From 42948d40edf54566c4c03e7d0dd70b768fec10cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillaume=20Mass=C3=A9?= Date: Sun, 11 Sep 2016 22:45:11 -0400 Subject: [PATCH 0001/2665] Widen Settings[_] to SettingsDefinition in CrossProject.[js, jvm]Settings() This change aligns with `Project.settings()` in sbt 0.13.8+. It allows to call `.settings(someSeqOfSettings)` in addition to `.settings(someSeqOfSettings: _*)`. --- .../scala/org/scalajs/sbtplugin/cross/CrossProject.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossProject.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossProject.scala index 35d6fbf5a5..d832abb117 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossProject.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossProject.scala @@ -225,11 +225,11 @@ final class CrossProject private ( copy(js = transformer(js)) /** Add settings specific to the underlying JVM project */ - def jvmSettings(ss: Def.Setting[_]*): CrossProject = + def jvmSettings(ss: Def.SettingsDefinition*): CrossProject = jvmConfigure(_.settings(ss: _*)) /** Add settings specific to the underlying JS project */ - def jsSettings(ss: Def.Setting[_]*): CrossProject = + def jsSettings(ss: Def.SettingsDefinition*): CrossProject = jsConfigure(_.settings(ss: _*)) // Concrete alteration members @@ -278,7 +278,7 @@ final class CrossProject private ( def settingSets(select: AddSettings*): CrossProject = copy(jvm.settingSets(select: _*), js.settingSets(select: _*)) - def settings(ss: Def.Setting[_]*): CrossProject = + def settings(ss: Def.SettingsDefinition*): CrossProject = copy(jvm.settings(ss: _*), js.settings(ss: _*)) override def toString(): String = s"CrossProject(jvm = $jvm, js = $js)" From 4665747e69bfe35d01b179a7e1fde0f00f55aaee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 13 Sep 2016 10:30:39 +0200 Subject: [PATCH 0002/2665] Use the right-biased API of Either from 2.12 instead of .right. Left and right projections of `Either` are deprecated in 2.12. They have been replaced by a right-biased API. We now use this API instead of `.right`, and we enable it in earlier versions of Scala through an implicit pimp. --- .../core/tools/linker/checker/IRChecker.scala | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 038012f8a6..bce76d7d1d 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -418,7 +418,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { receiver.tpe match { case ClassType(clazz) => for { - c <- tryLookupClass(clazz).right + c <- tryLookupClass(clazz) f <- c.lookupField(name) if !f.mutable } reportError(s"Assignment to immutable field $name.") @@ -643,7 +643,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { if (!kind.isClass) { reportError(s"Cannot select $item of non-class $cls") } else { - maybeClass.right foreach { + maybeClass.foreach { _.lookupField(item).fold[Unit] { reportError(s"Class $cls does not have a field $item") } { fieldDef => @@ -1149,4 +1149,14 @@ object IRChecker { private case class LocalDef(name: String, tpe: Type, mutable: Boolean)( val pos: Position) + + /** Enable the right-biased API of Either from 2.12 in earlier versions. */ + private implicit class RightBiasedEither[A, B](val self: Either[A, B]) + extends AnyVal { + + def foreach[U](f: B => U): Unit = self match { + case Left(_) => + case Right(r) => f(r) + } + } } From 730d7aba86f6227ea8c1d7a3b7eba56a36f4248f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 13 Sep 2016 10:32:42 +0200 Subject: [PATCH 0003/2665] Fix #2582: Upgrade to Scala 2.12.0-RC1. In the process, we get rid of scala-2.12-junit-mixin-plugin, since its functionality has been taken over by scalac itself. --- ci/checksizes.sh | 14 ++--- ci/matrix.xml | 18 +++---- .../partest/scalajs/2.12.0-M5/run/t5552.check | 2 - .../BlacklistedTests.txt | 10 +++- .../BuglistedTests.txt | 0 .../WhitelistedTests.txt | 53 +++++++++++++++++-- .../neg/t6446-additional.check | 12 ++--- .../neg/t6446-list.check | 0 .../neg/t6446-missing.check | 12 ++--- .../neg/t6446-show-phases.check | 14 ++--- .../neg/t7494-no-options.check | 12 ++--- .../run/Course-2002-01.check | 0 .../run/Course-2002-02.check | 0 .../run/Course-2002-04.check | 0 .../run/Course-2002-08.check | 0 .../run/Course-2002-09.check | 0 .../run/Course-2002-10.check | 0 .../{2.12.0-M5 => 2.12.0-RC1}/run/Meter.check | 0 .../run/MeterCaseClass.check | 0 .../{2.12.0-M5 => 2.12.0-RC1}/run/bugs.sem | 0 .../run/caseClassHash.check | 0 .../{2.12.0-M5 => 2.12.0-RC1}/run/deeps.check | 0 .../run/dynamic-anyval.check | 0 .../run/impconvtimes.check | 0 .../run/imports.check | 0 .../run/interpolation.check | 0 .../run/interpolationMultiline1.check | 0 .../run/issue192.sem | 0 .../run/macro-bundle-static.check | 0 .../run/macro-bundle-toplevel.check | 0 .../run/macro-bundle-whitebox-decl.check | 0 .../{2.12.0-M5 => 2.12.0-RC1}/run/misc.check | 16 +++--- .../run/promotion.check | 0 .../run/runtime.check | 0 .../run/spec-self.check | 0 .../run/structural.check | 0 .../run/t0421-new.check | 0 .../run/t0421-old.check | 0 .../{2.12.0-M5 => 2.12.0-RC1}/run/t1503.sem | 0 .../{2.12.0-M5 => 2.12.0-RC1}/run/t3702.check | 0 .../{2.12.0-M5 => 2.12.0-RC1}/run/t4148.sem | 0 .../{2.12.0-M5 => 2.12.0-RC1}/run/t4617.check | 0 .../{2.12.0-M5 => 2.12.0-RC1}/run/t5356.check | 0 .../scalajs/2.12.0-RC1/run/t5552.check | 6 +++ .../{2.12.0-M5 => 2.12.0-RC1}/run/t5568.check | 0 .../run/t5629b.check | 0 .../{2.12.0-M5 => 2.12.0-RC1}/run/t5680.check | 0 .../{2.12.0-M5 => 2.12.0-RC1}/run/t5866.check | 0 .../run/t6318_primitives.check | 0 .../{2.12.0-M5 => 2.12.0-RC1}/run/t6662.check | 0 .../{2.12.0-M5 => 2.12.0-RC1}/run/t7657.check | 0 .../{2.12.0-M5 => 2.12.0-RC1}/run/t7763.sem | 0 .../run/t8570a.check | 0 .../{2.12.0-M5 => 2.12.0-RC1}/run/t8764.check | 0 .../run/t9387b.check | 0 .../{2.12.0-M5 => 2.12.0-RC1}/run/t9656.check | 0 .../run/try-catch-unify.check | 0 .../run/virtpatmat_switch.check | 0 .../run/virtpatmat_typetag.check | 0 project/Build.scala | 32 ++--------- .../BlacklistedTests.txt | 1 + .../WhitelistedTests.txt | 1 + scripts/build-all-js.sh | 2 +- scripts/publish.sh | 4 +- 64 files changed, 120 insertions(+), 89 deletions(-) delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t5552.check rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/BlacklistedTests.txt (98%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/BuglistedTests.txt (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/WhitelistedTests.txt (97%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/neg/t6446-additional.check (79%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/neg/t6446-list.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/neg/t6446-missing.check (78%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/neg/t6446-show-phases.check (74%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/neg/t7494-no-options.check (79%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/Course-2002-01.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/Course-2002-02.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/Course-2002-04.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/Course-2002-08.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/Course-2002-09.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/Course-2002-10.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/Meter.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/MeterCaseClass.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/bugs.sem (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/caseClassHash.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/deeps.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/dynamic-anyval.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/impconvtimes.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/imports.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/interpolation.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/interpolationMultiline1.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/issue192.sem (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/macro-bundle-static.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/macro-bundle-toplevel.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/macro-bundle-whitebox-decl.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/misc.check (62%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/promotion.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/runtime.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/spec-self.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/structural.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/t0421-new.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/t0421-old.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/t1503.sem (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/t3702.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/t4148.sem (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/t4617.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/t5356.check (100%) create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5552.check rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/t5568.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/t5629b.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/t5680.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/t5866.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/t6318_primitives.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/t6662.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/t7657.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/t7763.sem (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/t8570a.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/t8764.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/t9387b.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/t9656.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/try-catch-unify.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/virtpatmat_switch.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-M5 => 2.12.0-RC1}/run/virtpatmat_typetag.check (100%) rename scala-test-suite/src/test/resources/{2.12.0-M5 => 2.12.0-RC1}/BlacklistedTests.txt (99%) rename scala-test-suite/src/test/resources/{2.12.0-M5 => 2.12.0-RC1}/WhitelistedTests.txt (97%) diff --git a/ci/checksizes.sh b/ci/checksizes.sh index e4a7f6daf7..2a73ae102d 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -11,8 +11,8 @@ case $FULLVER in 2.11.8) VER=2.11 ;; - 2.12.0-M5) - VER=2.12.0-M5 + 2.12.0-RC1) + VER=2.12.0-RC1 ;; 2.10.3|2.10.4|2.10.5|2.10.6|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7) echo "Ignoring checksizes for Scala $FULLVER" @@ -45,11 +45,11 @@ case $FULLVER in REVERSI_PREOPT_GZ_EXPECTEDSIZE=71000 REVERSI_OPT_GZ_EXPECTEDSIZE=32000 ;; - 2.12.0-M5) - REVERSI_PREOPT_EXPECTEDSIZE=528000 - REVERSI_OPT_EXPECTEDSIZE=124000 - REVERSI_PREOPT_GZ_EXPECTEDSIZE=67000 - REVERSI_OPT_GZ_EXPECTEDSIZE=30000 + 2.12.0-RC1) + REVERSI_PREOPT_EXPECTEDSIZE=595000 + REVERSI_OPT_EXPECTEDSIZE=149000 + REVERSI_PREOPT_GZ_EXPECTEDSIZE=78000 + REVERSI_OPT_GZ_EXPECTEDSIZE=36000 ;; esac diff --git a/ci/matrix.xml b/ci/matrix.xml index 536c3e6890..0ada1578e5 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -309,7 +309,7 @@ 1.8 - 2.12.0-M5 + 2.12.0-RC1 1.8 @@ -345,7 +345,7 @@ testSuite - 2.12.0-M5 + 2.12.0-RC1 1.8 testSuite @@ -367,7 +367,7 @@ scalaTestSuite - 2.12.0-M5 + 2.12.0-RC1 1.8 scalaTestSuite @@ -404,7 +404,7 @@ testSuite - 2.12.0-M5 + 2.12.0-RC1 1.8 testSuite @@ -426,7 +426,7 @@ scalaTestSuite - 2.12.0-M5 + 2.12.0-RC1 1.8 scalaTestSuite @@ -454,7 +454,7 @@ 1.8 - 2.12.0-M5 + 2.12.0-RC1 1.8 @@ -937,15 +937,15 @@ 1.7 - 2.12.0-M5 + 2.12.0-RC1 1.8 - 2.12.0-M5 + 2.12.0-RC1 1.8 - 2.12.0-M5 + 2.12.0-RC1 1.8 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t5552.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t5552.check deleted file mode 100644 index 4704611116..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t5552.check +++ /dev/null @@ -1,2 +0,0 @@ -(3,3) -(3,3) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/BlacklistedTests.txt similarity index 98% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/BlacklistedTests.txt rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/BlacklistedTests.txt index 4af018c5e0..fb68312e63 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/BlacklistedTests.txt @@ -129,6 +129,8 @@ run/t8188.scala run/t9375.scala run/t9365.scala run/inlineAddDeserializeLambda.scala +run/sammy_seriazable.scala +run/lambda-serialization-security.scala # Using System.getProperties @@ -470,6 +472,12 @@ run/t9102.scala run/t720.scala run/t9408.scala run/trait-default-specialize.scala +run/lazy-locals-2.scala +run/t5294.scala +run/trait_fields_final.scala +run/trait_fields_bytecode.scala +run/trait_fields_volatile.scala +run/junitForwarders run/reify_newimpl_29.scala run/reify_magicsymbols.scala @@ -776,6 +784,7 @@ run/repl-no-imports-no-predef.scala run/repl-paste-raw-b.scala run/repl-paste-raw-c.scala run/t9749-repl-dot.scala +run/trait_fields_repl.scala # Using Scala Script (partest.ScriptTest) @@ -853,7 +862,6 @@ run/dynamic-applyDynamicNamed.scala run/t4841-isolate-plugins run/large_code.scala run/macroPlugins-namerHooks.scala -run/t4287inferredMethodTypes.scala run/t4841-no-plugin.scala run/t4332.scala run/t8029.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/BuglistedTests.txt similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/BuglistedTests.txt rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/BuglistedTests.txt diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/WhitelistedTests.txt similarity index 97% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/WhitelistedTests.txt rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/WhitelistedTests.txt index 6dec84e05f..ecde31dc84 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/WhitelistedTests.txt @@ -217,7 +217,6 @@ pos/t3420.scala pos/t3440.scala pos/maxim1.scala pos/caseClassInMethod.scala -pos/t7239.scala pos/t3833.scala pos/t6675.scala pos/t4402 @@ -1536,7 +1535,6 @@ pos/compile1.scala pos/spec-t3497.scala pos/hkrange.scala pos/t287.scala -pos/t7294.scala pos/t6008.scala pos/t4432.scala pos/CustomGlobal.scala @@ -1628,7 +1626,6 @@ neg/t3776.scala neg/interop_classtags_arenot_manifests.scala neg/t4044.scala neg/macro-invalidusage-nontypeable -neg/t6375.scala neg/t500.scala neg/t4877.scala neg/t5357.scala @@ -3092,7 +3089,6 @@ pos/existental-slow-compile2.scala pos/existential-slow-compile1.scala pos/sammy_implicit.scala pos/t9178b.scala -pos/t9178.scala pos/t9449.scala pos/t3234.scala pos/t9542.scala @@ -3182,12 +3178,59 @@ neg/t9684b.scala neg/t9382.scala neg/trait-defaults-super.scala neg/t9684.scala -neg/nowarnDefaultJunitMethods run/hashCodeStatics.scala run/t9390d.scala run/trait-static-clash.scala run/t5568.scala run/t6318_primitives.scala +pos/fields_widen_trait_var.scala +pos/sammy_extends_function.scala +pos/infer_override_def_args.scala +pos/t482.scala +pos/t8079b.scala +pos/t6161b.scala +pos/t5294b.scala +pos/t5294c.scala +pos/overloaded_ho_fun.scala +pos/t4914.scala +pos/trait_fields_dependent_conflict.scala +pos/t2377b +pos/trait_fields_dependent_rebind.scala +pos/t9855b.scala +pos/trait_fields_inherit_double_def.scala +pos/t9855.scala +pos/t8873.scala +pos/trait_fields_nested_private_object.scala +pos/trait_fields_nested_public_object.scala +pos/trait_fields_private_this.scala +pos/trait_fields_var_override_deferred.scala +pos/trait_fields_static_fwd.scala +pos/trait_fields_owners.scala +pos/trait_fields_volatile.scala +pos/trait_lazy_accessboundary.scala +pos/trait_fields_lambdalift.scala +pos/typevar-in-prefix.scala +pos/val_infer.scala +pos/lub-from-hell.scala +neg/t8079a.scala +neg/sd128 +neg/t9849.scala +neg/trait_fields_var_override.scala +neg/val_infer.scala +neg/val_sig_infer_match.scala +neg/t7187.scala +neg/trait_fields_deprecated_overriding.scala +neg/t9847.scala +neg/val_sig_infer_struct.scala +neg/trait_fields_conflicts.scala +neg/lub-from-hell-2.scala +run/t2946 +run/lazy_local_labels.scala +run/sd167.scala +run/t9841.scala +run/trait-fields-override-lazy.scala +run/trait_fields_init.scala +run/trait_fields_three_layer_overrides.scala # Adapt checkfiles for (1.0).toString == "1" run/Course-2002-01.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/neg/t6446-additional.check similarity index 79% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/neg/t6446-additional.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/neg/t6446-additional.check index 8c45934fac..0819a9af4e 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/neg/t6446-additional.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/neg/t6446-additional.check @@ -12,12 +12,12 @@ superaccessors 8 add super accessors in traits and nested classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs + fields 13 synthesize accessors and fields, including bitmaps for la... + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes lambdalift 19 move nested functions to top level constructors 20 move field definitions into constructors flatten 21 eliminate inner classes diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/neg/t6446-list.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/neg/t6446-list.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/neg/t6446-list.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/neg/t6446-list.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/neg/t6446-missing.check similarity index 78% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/neg/t6446-missing.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/neg/t6446-missing.check index f1e16a5a40..1075466cf0 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/neg/t6446-missing.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/neg/t6446-missing.check @@ -13,12 +13,12 @@ superaccessors 8 add super accessors in traits and nested classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs + fields 13 synthesize accessors and fields, including bitmaps for la... + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes lambdalift 19 move nested functions to top level constructors 20 move field definitions into constructors flatten 21 eliminate inner classes diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/neg/t6446-show-phases.check similarity index 74% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/neg/t6446-show-phases.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/neg/t6446-show-phases.check index 8198acab2d..74635aab4b 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/neg/t6446-show-phases.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/neg/t6446-show-phases.check @@ -12,12 +12,12 @@ superaccessors 8 add super accessors in traits and nested classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs + fields 13 synthesize accessors and fields, including bitmaps for la... + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes lambdalift 19 move nested functions to top level constructors 20 move field definitions into constructors flatten 21 eliminate inner classes @@ -26,4 +26,4 @@ superaccessors 8 add super accessors in traits and nested classes cleanup 24 platform-specific cleanups, generate reflective calls delambdafy 25 remove lambdas jvm 26 generate JVM bytecode - terminal 27 the last phase during a compilation run \ No newline at end of file + terminal 27 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/neg/t7494-no-options.check similarity index 79% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/neg/t7494-no-options.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/neg/t7494-no-options.check index a0669e0a96..86e5cf88ba 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/neg/t7494-no-options.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/neg/t7494-no-options.check @@ -13,12 +13,12 @@ superaccessors 8 add super accessors in traits and nested classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs + fields 13 synthesize accessors and fields, including bitmaps for la... + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes lambdalift 19 move nested functions to top level constructors 20 move field definitions into constructors flatten 21 eliminate inner classes diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/Course-2002-01.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Course-2002-01.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/Course-2002-01.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Course-2002-01.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/Course-2002-02.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Course-2002-02.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/Course-2002-02.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Course-2002-02.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/Course-2002-04.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Course-2002-04.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/Course-2002-04.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Course-2002-04.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/Course-2002-08.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Course-2002-08.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/Course-2002-08.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Course-2002-08.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/Course-2002-09.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Course-2002-09.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/Course-2002-09.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Course-2002-09.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/Course-2002-10.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Course-2002-10.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/Course-2002-10.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Course-2002-10.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/Meter.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Meter.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/Meter.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Meter.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/MeterCaseClass.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/MeterCaseClass.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/MeterCaseClass.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/MeterCaseClass.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/bugs.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/bugs.sem similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/bugs.sem rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/bugs.sem diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/caseClassHash.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/caseClassHash.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/caseClassHash.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/caseClassHash.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/deeps.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/deeps.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/deeps.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/deeps.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/dynamic-anyval.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/dynamic-anyval.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/dynamic-anyval.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/dynamic-anyval.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/impconvtimes.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/impconvtimes.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/impconvtimes.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/impconvtimes.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/imports.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/imports.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/imports.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/imports.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/interpolation.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/interpolation.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/interpolation.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/interpolation.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/interpolationMultiline1.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/interpolationMultiline1.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/interpolationMultiline1.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/interpolationMultiline1.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/issue192.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/issue192.sem similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/issue192.sem rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/issue192.sem diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/macro-bundle-static.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/macro-bundle-static.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/macro-bundle-static.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/macro-bundle-static.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/macro-bundle-toplevel.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/macro-bundle-toplevel.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/macro-bundle-toplevel.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/macro-bundle-toplevel.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/macro-bundle-whitebox-decl.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/macro-bundle-whitebox-decl.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/macro-bundle-whitebox-decl.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/macro-bundle-whitebox-decl.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/misc.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/misc.check similarity index 62% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/misc.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/misc.check index 6043817dbc..85f37c51d7 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/misc.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/misc.check @@ -1,25 +1,25 @@ -misc.scala:46: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses +misc.scala:46: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses 42; ^ -misc.scala:47: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses +misc.scala:47: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses 42l; ^ -misc.scala:48: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses +misc.scala:48: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses 23.5f; ^ -misc.scala:49: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses +misc.scala:49: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses 23.5; ^ -misc.scala:50: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses +misc.scala:50: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses "Hello"; ^ -misc.scala:51: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses +misc.scala:51: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses 32 + 45; ^ -misc.scala:62: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses +misc.scala:62: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses x; ^ -misc.scala:74: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses +misc.scala:74: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses 1 < 2; ^ ### Hello diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/promotion.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/promotion.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/promotion.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/promotion.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/runtime.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/runtime.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/runtime.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/runtime.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/spec-self.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/spec-self.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/spec-self.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/spec-self.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/structural.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/structural.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/structural.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/structural.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t0421-new.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t0421-new.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t0421-new.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t0421-new.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t0421-old.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t0421-old.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t0421-old.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t0421-old.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t1503.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t1503.sem similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t1503.sem rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t1503.sem diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t3702.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t3702.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t3702.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t3702.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t4148.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t4148.sem similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t4148.sem rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t4148.sem diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t4617.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t4617.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t4617.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t4617.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t5356.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5356.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t5356.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5356.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5552.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5552.check new file mode 100644 index 0000000000..9e767b6d7b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5552.check @@ -0,0 +1,6 @@ +lazy: 3 +(3,3) +(3,3) +lazy: 3 +(3,3) +(3,3) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t5568.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5568.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t5568.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5568.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t5629b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5629b.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t5629b.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5629b.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t5680.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5680.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t5680.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5680.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t5866.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5866.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t5866.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5866.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t6318_primitives.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t6318_primitives.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t6318_primitives.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t6318_primitives.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t6662.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t6662.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t6662.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t6662.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t7657.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t7657.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t7657.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t7657.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t7763.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t7763.sem similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t7763.sem rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t7763.sem diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t8570a.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t8570a.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t8570a.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t8570a.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t8764.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t8764.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t8764.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t8764.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t9387b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t9387b.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t9387b.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t9387b.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t9656.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t9656.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/t9656.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t9656.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/try-catch-unify.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/try-catch-unify.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/try-catch-unify.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/try-catch-unify.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/virtpatmat_switch.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/virtpatmat_switch.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/virtpatmat_switch.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/virtpatmat_switch.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/virtpatmat_typetag.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/virtpatmat_typetag.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-M5/run/virtpatmat_typetag.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/virtpatmat_typetag.check diff --git a/project/Build.scala b/project/Build.scala index e1dc4472a8..5afe24bb63 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -64,7 +64,7 @@ object Build { CrossVersion.binaryMapped(v => s"sjs${previousSJSBinaryVersion}_$v") val scalaVersionsUsedForPublishing: Set[String] = - Set("2.10.6", "2.11.8", "2.12.0-M5") + Set("2.10.6", "2.11.8", "2.12.0-RC1") val newScalaBinaryVersionsInThisRelease: Set[String] = Set() @@ -375,32 +375,6 @@ object Build { Seq(s"-Xplugin:$jar") } } - ).withScalaJUnitMixinPlugin - } - - def withScalaJUnitMixinPlugin: Project = { - project.settings( - ivyConfigurations += config("test-plugin").hide, - scalacOptions in Test ++= { - val report = update.value - val jars = report.select(configurationFilter("test-plugin")) - for { - jar <- jars - jarPath = jar.getPath - if jarPath.contains("plugin") - } yield { - s"-Xplugin:$jarPath" - } - }, - libraryDependencies ++= { - if (scalaVersion.value.startsWith("2.10.") || - scalaVersion.value.startsWith("2.11.")) { - Seq.empty - } else { - Seq("org.scala-js" % "scala-junit-mixin-plugin" % "0.1.0" % - "test-plugin" cross CrossVersion.full) - } - } ) } @@ -450,7 +424,7 @@ object Build { "2.11.6", "2.11.7", "2.11.8", - "2.12.0-M5" + "2.12.0-RC1" ), // JDK version we are running with javaVersion in Global := { @@ -1441,7 +1415,7 @@ object Build { libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % "test" ) - ).withScalaJUnitMixinPlugin + ) lazy val noIrCheckTest: Project = Project( id = "noIrCheckTest", diff --git a/scala-test-suite/src/test/resources/2.12.0-M5/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.12.0-RC1/BlacklistedTests.txt similarity index 99% rename from scala-test-suite/src/test/resources/2.12.0-M5/BlacklistedTests.txt rename to scala-test-suite/src/test/resources/2.12.0-RC1/BlacklistedTests.txt index ddc59cd1a8..5c1d89e5e9 100644 --- a/scala-test-suite/src/test/resources/2.12.0-M5/BlacklistedTests.txt +++ b/scala-test-suite/src/test/resources/2.12.0-RC1/BlacklistedTests.txt @@ -71,6 +71,7 @@ scala/tools/testing/RunTesting.scala scala/PartialFunctionSerializationTest.scala scala/lang/stringinterpol/StringContextTest.scala scala/collection/IteratorTest.scala +scala/collection/NewBuilderTest.scala scala/collection/ParallelConsistencyTest.scala scala/collection/SeqViewTest.scala scala/collection/SetMapConsistencyTest.scala diff --git a/scala-test-suite/src/test/resources/2.12.0-M5/WhitelistedTests.txt b/scala-test-suite/src/test/resources/2.12.0-RC1/WhitelistedTests.txt similarity index 97% rename from scala-test-suite/src/test/resources/2.12.0-M5/WhitelistedTests.txt rename to scala-test-suite/src/test/resources/2.12.0-RC1/WhitelistedTests.txt index f87b481760..7be4fb6592 100644 --- a/scala-test-suite/src/test/resources/2.12.0-M5/WhitelistedTests.txt +++ b/scala-test-suite/src/test/resources/2.12.0-RC1/WhitelistedTests.txt @@ -2,6 +2,7 @@ scala/collection/IndexedSeqOptimizedTest.scala scala/collection/IterableViewLikeTest.scala scala/collection/ReusableBuildersTest.scala scala/collection/SearchingTest.scala +scala/collection/TraversableLikeTest.scala scala/collection/TraversableOnceTest.scala scala/collection/convert/NullSafetyToJavaTest.scala scala/collection/convert/NullSafetyToScalaTest.scala diff --git a/scripts/build-all-js.sh b/scripts/build-all-js.sh index fde5b4bba7..23a85b2946 100755 --- a/scripts/build-all-js.sh +++ b/scripts/build-all-js.sh @@ -3,7 +3,7 @@ tasks="fastOptJS fullOptJS" projects="helloworld/ reversi/ testingExample/test: testSuite/test:" -for v in 2.11.8 2.10.6 2.12.0-M5; do +for v in 2.11.8 2.10.6 2.12.0-RC1; do echo "++$v" echo "package" diff --git a/scripts/publish.sh b/scripts/publish.sh index b6555093f1..c7820d6323 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -8,8 +8,8 @@ else CMD="echo sbt" fi -FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.12.0-M5" -BIN_VERSIONS="2.10.6 2.11.8 2.12.0-M5" +FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.12.0-RC1" +BIN_VERSIONS="2.10.6 2.11.8 2.12.0-RC1" CLI_VERSIONS="2.10.6 2.11.8" SBT_VERSION="2.10.6" From 2d7176eae4737ca686ae60c3f3f2c549f67ee668 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 19 Aug 2016 18:06:15 +0200 Subject: [PATCH 0004/2665] Test ManifestFilters --- project/Build.scala | 2 + .../tools/jsdep/ManifestFiltersTest.scala | 47 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ManifestFiltersTest.scala diff --git a/project/Build.scala b/project/Build.scala index e1dc4472a8..c59377ebec 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -578,6 +578,8 @@ object Build { unmanagedSourceDirectories in Compile += baseDirectory.value.getParentFile / "shared/src/main/scala", + unmanagedSourceDirectories in Test += + baseDirectory.value.getParentFile / "shared/src/test/scala", sourceGenerators in Compile <+= Def.task { ScalaJSEnvGenerator.generateEnvHolder( diff --git a/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ManifestFiltersTest.scala b/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ManifestFiltersTest.scala new file mode 100644 index 0000000000..49189fd396 --- /dev/null +++ b/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ManifestFiltersTest.scala @@ -0,0 +1,47 @@ +package org.scalajs.core.tools.jsdep + +import org.junit.Test +import org.junit.Assert._ + +class ManifestFiltersTest { + import ManifestFilters._ + + private def mkManifest(module: String, deps: String*) = { + new JSDependencyManifest(new Origin(module, "compile"), + deps.map(new JSDependency(_)).toList, requiresDOM = false, + compliantSemantics = Nil) + } + + @Test + def reinterpretResourceNamesSimple(): Unit = { + val filter = reinterpretResourceNames("lib-b")( + "jquery.js" -> "2.1.3/jquery.js") + + val otherManifest = mkManifest("lib-a", "2.1.4/jquery.js", "bar.js") + val targetManifest = mkManifest("lib-b", "jquery.js", "foo.js") + + val result = filter(Seq(otherManifest, targetManifest)).toSet + val expected = Set(otherManifest, + mkManifest("lib-b", "2.1.3/jquery.js", "foo.js")) + + assertEquals(expected, result) + } + + @Test + def reinterpretResourceNamesFull(): Unit = { + val filter = reinterpretResourceNames( + origin => oldName => origin.moduleName + oldName) + + val manifests = for { + origin <- Seq("oa", "ob", "oc") + } yield { + val oldLibs = Seq("a.js", "b.js", "c.js") + val newLibs = oldLibs.map(origin + _) + (mkManifest(origin, oldLibs: _*), mkManifest(origin, newLibs: _*)) + } + + val (input, expected) = manifests.unzip + val result = filter(input) + assertEquals(expected, result) + } +} From e1be7b893ef019de35026ab9700c10c7c8620891 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 20 Aug 2016 10:53:21 +0200 Subject: [PATCH 0005/2665] Test ComplianceRequirement --- .../tools/jsdep/ComplianceRequirement.scala | 23 ++++++- .../jsdep/ComplianceRequirementTest.scala | 66 +++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ComplianceRequirementTest.scala diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ComplianceRequirement.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ComplianceRequirement.scala index d663a24dd3..bcbe0a392b 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ComplianceRequirement.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ComplianceRequirement.scala @@ -4,9 +4,30 @@ import org.scalajs.core.tools.sem.Semantics /** Expresses a requirement for a given semantic to be compliant */ final class ComplianceRequirement( - val semantics: String, val origins: List[Origin]) + val semantics: String, val origins: List[Origin]) { + override def toString(): String = + s"ComplianceRequirement($semantics, origins = [${origins.mkString(", ")}])" + + override def equals(that: Any): Boolean = that match { + case that: ComplianceRequirement => + this.semantics == that.semantics && + this.origins == that.origins + case _ => + false + } + + override def hashCode(): Int = { + import scala.util.hashing.MurmurHash3._ + var acc = ComplianceRequirement.HashSeed + acc = mix(acc, semantics.##) + acc = mixLast(acc, origins.##) + finalizeHash(acc, 2) + } +} object ComplianceRequirement { + // "org.scalajs.core.tools.jsdep.ComplianceRequirement".## + private final val HashSeed = -1738348249 /** Checks whether the given semantics are compliant with the given * requirements. diff --git a/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ComplianceRequirementTest.scala b/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ComplianceRequirementTest.scala new file mode 100644 index 0000000000..f359c062eb --- /dev/null +++ b/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ComplianceRequirementTest.scala @@ -0,0 +1,66 @@ +package org.scalajs.core.tools.jsdep + +import org.scalajs.core.tools.sem.Semantics + +import org.junit.Test +import org.junit.Assert._ + +class ComplianceRequirementTest { + private val origin = new Origin("test", "compile") + private val semantics = Set("asInstanceOfs", "moduleInit", "strictFloats") + + private def mkComplianceRequirement(semantics: String) = + new ComplianceRequirement(semantics, origin :: Nil) + + @Test + def checkComplianceSuccess: Unit = { + for (sems <- semantics.subsets) { + val origin = new Origin("test", "compile") + val requirements = sems.map(mkComplianceRequirement) + val semantics = Semantics.compliantTo(sems) + ComplianceRequirement.checkCompliance(requirements, semantics) + } + } + + @Test + def checkComplianceFail: Unit = { + for { + required <- semantics.subsets + missing <- required.subsets + if missing.nonEmpty + } { + val present = required -- missing + val requirements = required.map(mkComplianceRequirement) + val semantics = Semantics.compliantTo(present) + try { + ComplianceRequirement.checkCompliance(requirements, semantics) + fail("Expected a BadComplianceException be thrown") + } catch { + case e: BadComplianceException => + val expected = requirements.filterNot(r => present(r.semantics)) + assertEquals(expected, e.unmet.toSet) + } + } + } + + @Test + def mergeFromManifests: Unit = { + val origins = Array("a", "b", "c").map(new Origin(_, "compile")) + + def mkManifest(o: Int, semantics: String*) = + new JSDependencyManifest(origins(o), Nil, false, semantics.toList) + + val manifests = Seq( + mkManifest(0, "isInstanceOfs"), + mkManifest(1, "isInstanceOfs", "moduleInit"), + mkManifest(2)) + + val result = ComplianceRequirement.mergeFromManifests(manifests).toSet + val expected = Set( + new ComplianceRequirement("isInstanceOfs", List(0, 1).map(origins)), + new ComplianceRequirement("moduleInit", List(1).map(origins))) + + assertEquals(expected, result) + } + +} From d07f365fb16878ec736c605613e4cbdbde8a6bbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 14 Sep 2016 11:56:39 +0200 Subject: [PATCH 0006/2665] Fix #2592: Do shrink the result of Pattern.split() to an empty array. But not if the input string is the empty string itself. --- .../main/scala/java/util/regex/Pattern.scala | 72 ++++++++++--------- .../javalib/util/regex/RegexPatternTest.scala | 16 +++++ 2 files changed, 53 insertions(+), 35 deletions(-) diff --git a/javalib/src/main/scala/java/util/regex/Pattern.scala b/javalib/src/main/scala/java/util/regex/Pattern.scala index 7d853041ef..6ad79e8003 100644 --- a/javalib/src/main/scala/java/util/regex/Pattern.scala +++ b/javalib/src/main/scala/java/util/regex/Pattern.scala @@ -42,46 +42,48 @@ final class Pattern private (jsRegExp: js.RegExp, _pattern: String, _flags: Int) split(input, 0) def split(input: CharSequence, limit: Int): Array[String] = { - val lim = if (limit > 0) limit else Int.MaxValue - val inputStr = input.toString - val matcher = this.matcher(inputStr) - - // Actually split original string - val builder = Array.newBuilder[String] - var prevEnd = 0 - var size = 0 - while ((size < lim-1) && matcher.find()) { - if (matcher.end == 0) { - /* If there is a zero-width match at the beginning of the string, - * ignore it, i.e., omit the resulting empty string at the beginning of - * the array. - */ - } else { - builder += inputStr.substring(prevEnd, matcher.start) - size += 1 - } - prevEnd = matcher.end - } - builder += inputStr.substring(prevEnd) - val result = builder.result() - - /* With `limit == 0`, remove trailing empty strings (but do not reduce - * the array to be zero length). - */ - if (limit != 0) { - result + + // If the input string is empty, always return Array("") - #987, #2592 + if (inputStr == "") { + Array("") } else { - var actualLength = result.length - while (actualLength > 1 && result(actualLength - 1) == "") - actualLength -= 1 + // Actually split original string + val lim = if (limit > 0) limit else Int.MaxValue + val matcher = this.matcher(inputStr) + val builder = Array.newBuilder[String] + var prevEnd = 0 + var size = 0 + while ((size < lim-1) && matcher.find()) { + if (matcher.end == 0) { + /* If there is a zero-width match at the beginning of the string, + * ignore it, i.e., omit the resulting empty string at the beginning + * of the array. + */ + } else { + builder += inputStr.substring(prevEnd, matcher.start) + size += 1 + } + prevEnd = matcher.end + } + builder += inputStr.substring(prevEnd) + val result = builder.result() - if (actualLength == result.length) { + // With `limit == 0`, remove trailing empty strings. + if (limit != 0) { result } else { - val actualResult = new Array[String](actualLength) - System.arraycopy(result, 0, actualResult, 0, actualLength) - actualResult + var actualLength = result.length + while (actualLength != 0 && result(actualLength - 1) == "") + actualLength -= 1 + + if (actualLength == result.length) { + result + } else { + val actualResult = new Array[String](actualLength) + System.arraycopy(result, 0, actualResult, 0, actualLength) + actualResult + } } } } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexPatternTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexPatternTest.scala index 8062d8ac08..7a17b7f419 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexPatternTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexPatternTest.scala @@ -52,10 +52,17 @@ class RegexPatternTest { // Splitting the empty string must return 1 element - #987 split("", "a", Array("")) + split("", "a?", Array("")) split("", "\\*", Array("")) split("", "\n", Array("")) split("", "", Array("")) + /* Unless splitting the empty string, all trailing empty strings are + * removed, which can reduce it to an empty array. #2592 + */ + split("a", "a", Array()) + split("a", "a?", Array()) + /* Should remove leading empty match under some conditions - #1171, #2573 * The behavior changed in JDK 8 (at which point it became properly * documented). @@ -98,10 +105,19 @@ class RegexPatternTest { // Splitting the empty string must return 1 element - #987 splitWithLimit("", "a", 0, Array("")) + splitWithLimit("", "a?", 0, Array("")) splitWithLimit("", "\\*", 5, Array("")) splitWithLimit("", "\n", -2, Array("")) splitWithLimit("", "", 1, Array("")) + /* Unless splitting the empty string, if `limit` is 0, all trailing empty + * strings are removed, which can reduce it to an empty array. #2592 + */ + splitWithLimit("a", "a", 0, Array()) + splitWithLimit("a", "a?", 0, Array()) + splitWithLimit("a", "a", -1, Array("", "")) + splitWithLimit("a", "a?", -1, Array("", "", "")) + /* Should remove leading empty match under some conditions - #1171, #2573 * The behavior changed in JDK 8 (at which point it became properly * documented). From 16e40c3d06664eb3cb11c8c346dc38ec15c8756c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 15 Sep 2016 22:44:14 +0200 Subject: [PATCH 0007/2665] Give 1 KB more to the checksizes for 2.12.0-RC1. Apparently, the previous limit was a little bit too tight, and on some machines the file is a little bit bigger. --- ci/checksizes.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/checksizes.sh b/ci/checksizes.sh index 2a73ae102d..02d9d905da 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -47,7 +47,7 @@ case $FULLVER in ;; 2.12.0-RC1) REVERSI_PREOPT_EXPECTEDSIZE=595000 - REVERSI_OPT_EXPECTEDSIZE=149000 + REVERSI_OPT_EXPECTEDSIZE=150000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=78000 REVERSI_OPT_GZ_EXPECTEDSIZE=36000 ;; From f39fbf49d0b67bb0cddac5bfed51656af070c7f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 6 Sep 2016 16:19:40 +0200 Subject: [PATCH 0008/2665] Do not use Rhino by default (use Node.js or PhantomJS instead). The setting `scalaJSUseRhino` is now `false` by default, and is deprecated. The previous behavior can be restored with Seq(Compile, Test).flatMap( c => inConfig(c)(jsEnv := RhinoJSEnv().value)) --- ci/matrix.xml | 57 +++++++------------ .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 45 ++++++++++++++- .../sbtplugin/ScalaJSPluginInternal.scala | 17 ++---- 3 files changed, 67 insertions(+), 52 deletions(-) diff --git a/ci/matrix.xml b/ci/matrix.xml index 0ada1578e5..3424c6ea0f 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -15,11 +15,9 @@ @@ -257,14 +241,13 @@ sbt noDOM/run noDOM/testHtmlFastOpt noDOM/testHtmlFullOpt \ withDOM/run withDOM/testHtmlFastOpt withDOM/testHtmlFullOpt \ multiTestJS/test:run multiTestJS/testHtmlFastOpt multiTestJS/testHtmlFullOpt \ - test \ - 'set scalaJSUseRhino in Global := false' \ jetty9/run test \ jsDependenciesTest/packageJSDependencies \ jsDependenciesTest/packageMinifiedJSDependencies \ jsDependenciesTest/regressionTestForIssue2243 \ jsNoDependenciesTest/regressionTestForIssue2243 \ - multiTestJS/test:testScalaJSSourceMapAttribute + multiTestJS/test:testScalaJSSourceMapAttribute \ + 'set scalaJSUseRhino in Global := true' test ]]> inConfig(c)(jsEnv := RhinoJSEnv().value)) + * }}} + * + * The Rhino JS environment will support DOM through `env.js` if and only + * if `scalaJSRequestsDOM.value` evaluates to `true`. + * + * Note that the resulting [[sbt.Def.Setting Setting]] 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 RhinoJSEnv(): Def.Initialize[Task[RhinoJSEnv]] = Def.task { + /* We take the semantics from the linker, since they depend on the stage. + * This way we are sure we agree on the semantics with the linker. + */ + import ScalaJSPluginInternal.{scalaJSLinker, scalaJSRequestsDOM} + val semantics = scalaJSLinker.value.semantics + val withDOM = scalaJSRequestsDOM.value + new RhinoJSEnv(semantics, withDOM) + } + /** * Creates a [[sbt.Def.Initialize Def.Initialize]] for a NodeJSEnv. Use * this to explicitly specify in your build that you would like to run with Node.js: @@ -188,8 +217,18 @@ object ScalaJSPlugin extends AutoPlugin { val scalaJSConsole = TaskKey[JSConsole]("scalaJSConsole", "The JS console used by the Scala.js runner/tester", DTask) - val scalaJSUseRhino = SettingKey[Boolean]("scalaJSUseRhino", - "Whether Rhino should be used", APlusSetting) + /** Non-deprecated alias of `scalaJSUseRhino` for internal use. */ + private[sbtplugin] val scalaJSUseRhinoInternal = SettingKey[Boolean]( + "scalaJSUseRhino", "Whether Rhino should be used", KeyRanks.Invisible) + + @deprecated( + "Will be removed in 1.0.0. " + + "Note that Rhino is not used by default anymore, " + + "so setting `scalaJSUseRhino` to `false` is redundant. " + + "To enable Rhino anew, use " + + "`Seq(Compile, Test).flatMap(c => inConfig(c)(jsEnv := RhinoJSEnv().value))`.", + "0.6.13") + val scalaJSUseRhino = scalaJSUseRhinoInternal val jsEnv = TaskKey[JSEnv]("jsEnv", "A JVM-like environment where Scala.js files can be run and tested.", AMinusTask) @@ -280,7 +319,7 @@ object ScalaJSPlugin extends AutoPlugin { super.globalSettings ++ Seq( isScalaJSProject := false, scalaJSStage := Stage.FastOpt, - scalaJSUseRhino := true, + scalaJSUseRhinoInternal := false, scalaJSClearCacheStats := globalIRCache.clearStats() ) } diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 5956988404..0cd5910116 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -21,9 +21,7 @@ import org.scalajs.core.tools.linker.frontend.LinkerFrontend import org.scalajs.core.tools.linker.backend.{LinkerBackend, OutputMode} import org.scalajs.jsenv._ -import org.scalajs.jsenv.rhino.RhinoJSEnv -import org.scalajs.jsenv.nodejs.NodeJSEnv -import org.scalajs.jsenv.phantomjs.{PhantomJSEnv, PhantomJettyClassLoader} +import org.scalajs.jsenv.phantomjs.PhantomJettyClassLoader import org.scalajs.core.ir import org.scalajs.core.ir.Utils.escapeJS @@ -563,17 +561,12 @@ object ScalaJSPluginInternal { }, resolvedJSEnv := jsEnv.?.value.getOrElse { - if (scalaJSUseRhino.value) { - /* We take the semantics from the linker, since they depend on the - * stage. This way we are sure we agree on the semantics with the - * linker. - */ - val semantics = scalaJSLinker.value.semantics - new RhinoJSEnv(semantics, withDOM = scalaJSRequestsDOM.value) + if (scalaJSUseRhinoInternal.value) { + RhinoJSEnv().value } else if (scalaJSRequestsDOM.value) { - new PhantomJSEnv(jettyClassLoader = scalaJSPhantomJSClassLoader.value) + PhantomJSEnv().value } else { - new NodeJSEnv + NodeJSEnv().value } }, From 9df749efd1ab0fc4ed272d2fd63f3839e74fe292 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 8 Sep 2016 16:16:44 +0200 Subject: [PATCH 0009/2665] Always use Node.js in partest, instead of Rhino in noOpt. Historically, we used Rhino to execute the partest test suite in --noOpt. This hasn't been necessary for a while, but we had kept it that way to reduce the likelihood of breakage at the time. With the deprecation of the Rhino runner, it is time to forget that dark past, and always use Node.js to run partest, even in noOpt. --- .../scala/tools/nsc/MainGenericRunner.scala | 29 ++++++------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala index cd0c55d566..a95a35781f 100644 --- a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala +++ b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala @@ -13,7 +13,6 @@ import org.scalajs.core.tools.linker.Linker import org.scalajs.core.ir import org.scalajs.jsenv.JSConsole -import org.scalajs.jsenv.rhino.RhinoJSEnv import org.scalajs.jsenv.nodejs.NodeJSEnv import scala.tools.partest.scalajs.ScalaJSPartestOptions._ @@ -67,29 +66,19 @@ class MainGenericRunner { runnerIR(command.thingToRun, command.arguments) ) - val jsRunner = new MemVirtualJSFile("launcher.js") - .withContent(s"PartestLauncher().launch();") - val linker = Linker(semantics, withSourceMap = false, useClosureCompiler = optMode == FullOpt) - val libJSEnv = { - /* Historically, we used Rhino in NoOpt and NodeJS in FastOpt and FullOpt. - * This is not necessary anymore: Rhino can run in FastOpt. - * We keep this for now, mainly to not change too many things at once. - */ - if (optMode == NoOpt) { - val env = new RhinoJSEnv(semantics).withSourceMap(false) - val unit = linker.linkUnit(ir, env.symbolRequirements, logger) - env.loadLinkingUnit(unit) - } else { - val output = WritableMemVirtualJSFile("partest-fastOpt.js") - linker.link(ir, output, logger) - new NodeJSEnv().loadLibs(ResolvedJSDependency.minimal(output) :: Nil) - } + val sjsCode = { + val output = WritableMemVirtualJSFile("partest.js") + linker.link(ir, output, logger) + ResolvedJSDependency.minimal(output) :: Nil } - libJSEnv.jsRunner(jsRunner).run(logger, jsConsole) + val jsRunner = new MemVirtualJSFile("launcher.js") + .withContent(s"PartestLauncher().launch();") + + new NodeJSEnv().jsRunner(sjsCode, jsRunner).run(logger, jsConsole) true } @@ -107,7 +96,7 @@ class MainGenericRunner { import ir.Trees._ import ir.Types._ - val mainModuleClassName = ir.Definitions.encodeClassName(mainObj + "$") + val mainModuleClassName = ir.Definitions.encodeClassName(mainObj + "$") val className = "PartestLauncher$" val exportName = "PartestLauncher" val encodedClassName = ir.Definitions.encodeClassName(className) From 55f46885fa4bde51a0d26532b1f0520111a1be28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 6 Sep 2016 17:53:43 +0200 Subject: [PATCH 0010/2665] Deprecate RhinoJSEnv without replacement. It will be removed in Scala.js 1.0.0. --- .../jsenv/test/RetryingComJSEnvTest.scala | 4 +-- .../scalajs/jsenv/test/RhinoJSEnvTest.scala | 5 +++- .../org/scalajs/jsenv/rhino/RhinoJSEnv.scala | 15 +++++++++++ .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 26 ++++++++++++------- .../sbtplugin/ScalaJSPluginInternal.scala | 2 +- 5 files changed, 39 insertions(+), 13 deletions(-) diff --git a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/RetryingComJSEnvTest.scala b/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/RetryingComJSEnvTest.scala index 50b96d5f2c..4aeccda56c 100644 --- a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/RetryingComJSEnvTest.scala +++ b/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/RetryingComJSEnvTest.scala @@ -3,7 +3,7 @@ package org.scalajs.jsenv.test import org.scalajs.core.tools.io.VirtualJSFile import org.scalajs.core.tools.jsdep.ResolvedJSDependency import org.scalajs.core.tools.logging._ -import org.scalajs.jsenv.rhino.RhinoJSEnv +import org.scalajs.jsenv.nodejs.NodeJSEnv import org.scalajs.jsenv.{ComJSRunner, JSConsole, _} import scala.concurrent.Future @@ -19,7 +19,7 @@ class RetryingComJSEnvTest extends JSEnvTest with ComTests { } protected def newJSEnv: RetryingComJSEnv = - new RetryingComJSEnv(new FailingEnv(new RhinoJSEnv), maxFails) + new RetryingComJSEnv(new FailingEnv(new NodeJSEnv), maxFails) private final class FailingEnv(baseEnv: ComJSEnv) extends ComJSEnv { def name: String = s"FailingJSEnv of ${baseEnv.name}" diff --git a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/RhinoJSEnvTest.scala b/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/RhinoJSEnvTest.scala index 2934a73e8f..d69a07c53f 100644 --- a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/RhinoJSEnvTest.scala +++ b/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/RhinoJSEnvTest.scala @@ -1,7 +1,10 @@ package org.scalajs.jsenv.test +import org.scalajs.core.tools.sem.Semantics + import org.scalajs.jsenv.rhino._ class RhinoJSEnvTest extends TimeoutComTests { - protected def newJSEnv: RhinoJSEnv = new RhinoJSEnv + protected def newJSEnv: RhinoJSEnv = + new RhinoJSEnv(Semantics.Defaults, withDOM = false, internal = ()) } diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/RhinoJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/RhinoJSEnv.scala index e3e6142bec..202e87ef1e 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/RhinoJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/RhinoJSEnv.scala @@ -35,6 +35,11 @@ import scala.reflect.ClassTag import org.mozilla.javascript._ +/** A JS environment using a modified Rhino interpreter (deprecated). + * + * As of Scala.js 0.6.13, `RhinoJSEnv` is deprecated. It will be removed in + * Scala.js 1.0.0. + */ final class RhinoJSEnv private ( semantics: Semantics, withDOM: Boolean, @@ -43,9 +48,19 @@ final class RhinoJSEnv private ( import RhinoJSEnv._ + @deprecated( + "The Rhino JS environment is being phased out. " + + "It will be removed in Scala.js 1.0.0. ", + "0.6.13") def this(semantics: Semantics = Semantics.Defaults, withDOM: Boolean = false) = this(semantics, withDOM, sourceMap = true) + /** A non-deprecated constructor for internal use. */ + private[scalajs] def this(semantics: Semantics, withDOM: Boolean, + internal: Unit) = { + this(semantics, withDOM, sourceMap = true) + } + def withSourceMap(sourceMap: Boolean): RhinoJSEnv = new RhinoJSEnv(semantics, withDOM, sourceMap) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index d53a7acc4f..e4fc9ec612 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -62,6 +62,18 @@ object ScalaJSPlugin extends AutoPlugin { // Factory methods for JSEnvs + /** A non-deprecated version of `RhinoJSEnv` for internal use. */ + private[sbtplugin] + def RhinoJSEnvInternal(): Def.Initialize[Task[RhinoJSEnv]] = Def.task { + /* We take the semantics from the linker, since they depend on the stage. + * This way we are sure we agree on the semantics with the linker. + */ + import ScalaJSPluginInternal.{scalaJSLinker, scalaJSRequestsDOM} + val semantics = scalaJSLinker.value.semantics + val withDOM = scalaJSRequestsDOM.value + new RhinoJSEnv(semantics, withDOM, internal = ()) + } + /** Creates a [[sbt.Def.Initialize Def.Initialize]] for a [[RhinoJSEnv]]. * * Use this to explicitly specify in your build that you would like to run @@ -80,15 +92,11 @@ object ScalaJSPlugin extends AutoPlugin { * case) or scope it manually, using * [[sbt.ProjectExtra.inScope[* Project.inScope]]. */ - def RhinoJSEnv(): Def.Initialize[Task[RhinoJSEnv]] = Def.task { - /* We take the semantics from the linker, since they depend on the stage. - * This way we are sure we agree on the semantics with the linker. - */ - import ScalaJSPluginInternal.{scalaJSLinker, scalaJSRequestsDOM} - val semantics = scalaJSLinker.value.semantics - val withDOM = scalaJSRequestsDOM.value - new RhinoJSEnv(semantics, withDOM) - } + @deprecated( + "The Rhino JS environment is being phased out. " + + "It will be removed in Scala.js 1.0.0. ", + "0.6.13") + def RhinoJSEnv(): Def.Initialize[Task[RhinoJSEnv]] = RhinoJSEnvInternal() /** * Creates a [[sbt.Def.Initialize Def.Initialize]] for a NodeJSEnv. Use diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 0cd5910116..0ae225675d 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -562,7 +562,7 @@ object ScalaJSPluginInternal { resolvedJSEnv := jsEnv.?.value.getOrElse { if (scalaJSUseRhinoInternal.value) { - RhinoJSEnv().value + RhinoJSEnvInternal().value } else if (scalaJSRequestsDOM.value) { PhantomJSEnv().value } else { From 309b3f5abf996cc72ff1a3e36f6f724fe792b176 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 15 Sep 2016 15:43:31 +0200 Subject: [PATCH 0011/2665] Tone down the number of combinations in CI. Our resource consumption of CI has grown much too intense, to a point where it is slowing us down, as PR testing can be delayed by several hours. This commit "strategically" reduces the number of combinations that are tested on CI. Basically, we assume 2.10.2, 2.11.8 and 2.12.0-RC1 combined with JDK8 only as the "default", "base" combination. From that combination, we vary all the other parameters independently, but we do not combine several axes together. One exception is for sbt-plugin related things, whose "base" combination is 2.10.6 with all the JDKs. To make sure that the `testSuite` (which contains JDK7-only and JDK8-only parts) runs on JDK6 and 7 in `pr`, one `testSuite` run (in the default config, i.e., Node.js + fastOpt) is added to the `main` task. Partest fastOpt moves from `nightly` to `pr`. The tests in `pr` have become slow enough that two partest tasks (for 2.11.8 and 2.12.0-RC1) will not kill it. And this is the one thing from `nightly` that often breaks, so it is worth having in `pr`. --- ci/matrix.xml | 520 ++++---------------------------------------------- 1 file changed, 41 insertions(+), 479 deletions(-) diff --git a/ci/matrix.xml b/ci/matrix.xml index 3424c6ea0f..c232b409b8 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -58,7 +58,8 @@ 'set scalaJSOptimizerOptions in testingExample ~= (_.withDisableOptimizer(true))' \ ++$scala testingExample/test:run testingExample/test && sbtretry ++$scala testSuiteJVM/test testSuiteJVM/clean && - sbtretry ++$scala 'testSuite/test:runMain org.scalajs.testsuite.junit.JUnitBootstrapTest' testSuite/clean && + sbtretry ++$scala 'testSuite/test:runMain org.scalajs.testsuite.junit.JUnitBootstrapTest' && + sbtretry ++$scala testSuite/test && sbtretry ++$scala javalibExTestSuite/test && sbtretry 'set scalaJSStage in Global := FullOptStage' \ ++$scala javalibExTestSuite/test && @@ -266,7 +267,7 @@ ]]> - + 2.10.2 1.6 @@ -296,32 +297,12 @@ 1.8 - - - 2.10.2 - 1.6 - testSuite - - - 2.10.2 - 1.7 - testSuite - + 2.10.2 1.8 testSuite - - 2.11.8 - 1.6 - testSuite - - - 2.11.8 - 1.7 - testSuite - 2.11.8 1.8 @@ -333,17 +314,7 @@ testSuite - - - 2.11.8 - 1.6 - scalaTestSuite - - - 2.11.8 - 1.7 - scalaTestSuite - + 2.11.8 1.8 @@ -355,32 +326,12 @@ scalaTestSuite - - - 2.10.2 - 1.6 - testSuite - - - 2.10.2 - 1.7 - testSuite - + 2.10.2 1.8 testSuite - - 2.11.8 - 1.6 - testSuite - - - 2.11.8 - 1.7 - testSuite - 2.11.8 1.8 @@ -392,17 +343,7 @@ testSuite - - - 2.11.8 - 1.6 - scalaTestSuite - - - 2.11.8 - 1.7 - scalaTestSuite - + 2.11.8 1.8 @@ -414,24 +355,11 @@ scalaTestSuite - - - 2.10.2 - 1.6 - - - 2.10.2 - 1.7 - + 2.10.2 1.8 - - - 2.11.8 - 1.7 - 2.11.8 1.8 @@ -441,7 +369,7 @@ 1.8 - + 2.10.6 1.6 @@ -469,10 +397,16 @@ 2.11.0 1.7 - + + + 2.11.8 1.7 + + 2.12.0-RC1 + 1.8 + @@ -480,441 +414,101 @@ - + 2.10.3 - 1.7 + 1.8 2.10.4 - 1.7 - - - 2.10.5 - 1.6 - - - 2.10.5 - 1.7 + 1.8 2.10.5 1.8 - - 2.10.6 - 1.6 - - - 2.10.6 - 1.7 - 2.10.6 1.8 2.11.0 - 1.7 + 1.8 2.11.1 - 1.7 - - - 2.11.2 - 1.6 - - - 2.11.2 - 1.7 + 1.8 2.11.2 1.8 - - 2.11.4 - 1.6 - - - 2.11.4 - 1.7 - 2.11.4 1.8 - - 2.11.5 - 1.6 - - - 2.11.5 - 1.7 - 2.11.5 1.8 - - 2.11.6 - 1.6 - - - 2.11.6 - 1.7 - 2.11.6 1.8 - - 2.11.7 - 1.6 - - - 2.11.7 - 1.7 - 2.11.7 1.8 - - - 2.10.3 - 1.7 - testSuite - - - 2.10.4 - 1.7 - testSuite - - - 2.10.5 - 1.6 - testSuite - - - 2.10.5 - 1.7 - testSuite - - - 2.10.5 - 1.8 - testSuite - - - 2.10.6 - 1.6 - testSuite - - - 2.10.6 - 1.7 - testSuite - - - 2.10.6 - 1.8 - testSuite - + - 2.11.0 - 1.7 - testSuite - - - 2.11.1 - 1.7 - testSuite - - - 2.11.2 - 1.6 - testSuite - - - 2.11.2 - 1.7 - testSuite - - - 2.11.2 - 1.8 - testSuite - - - 2.11.4 - 1.6 - testSuite - - - 2.11.4 - 1.7 - testSuite - - - 2.11.4 - 1.8 - testSuite - - - 2.11.5 - 1.6 - testSuite - - - 2.11.5 - 1.7 - testSuite - - - 2.11.5 - 1.8 - testSuite - - - 2.11.6 + 2.10.2 1.6 testSuite - 2.11.6 + 2.10.2 1.7 testSuite - 2.11.6 - 1.8 - testSuite - - - 2.11.7 + 2.11.8 1.6 testSuite - 2.11.7 + 2.11.8 1.7 testSuite - - 2.11.7 - 1.8 - testSuite - - - - 2.10.3 - 1.7 - testSuite - - - 2.10.4 - 1.7 - testSuite - - - 2.10.5 - 1.6 - testSuite - - - 2.10.5 - 1.7 - testSuite - - - 2.10.5 - 1.8 - testSuite - - - 2.10.6 - 1.6 - testSuite - - - 2.10.6 - 1.7 - testSuite - - - 2.10.6 - 1.8 - testSuite - - - 2.11.0 - 1.7 - testSuite - - - 2.11.1 - 1.7 - testSuite - - - 2.11.2 - 1.6 - testSuite - - - 2.11.2 - 1.7 - testSuite - - - 2.11.2 - 1.8 - testSuite - - - 2.11.4 - 1.6 - testSuite - - - 2.11.4 - 1.7 - testSuite - - - 2.11.4 - 1.8 - testSuite - + - 2.11.5 - 1.6 - testSuite - - - 2.11.5 - 1.7 - testSuite - - - 2.11.5 - 1.8 - testSuite - - - 2.11.6 + 2.10.2 1.6 testSuite - 2.11.6 + 2.10.2 1.7 testSuite - 2.11.6 - 1.8 - testSuite - - - 2.11.7 + 2.11.8 1.6 testSuite - 2.11.7 + 2.11.8 1.7 testSuite - - 2.11.7 - 1.8 - testSuite - - - - - 2.10.3 - 1.7 - - - 2.10.4 - 1.7 - - - 2.10.5 - 1.6 - - - 2.10.5 - 1.7 - - - 2.10.5 - 1.8 - - - 2.10.6 - 1.6 - - - 2.10.6 - 1.7 - - - 2.10.6 - 1.8 - - - 2.11.0 - 1.7 - - - 2.11.1 - 1.7 - - - 2.11.2 - 1.7 - - - - 2.11.5 - 1.7 - - - 2.11.5 - 1.8 - - - 2.11.6 - 1.7 - - - 2.11.6 - 1.8 - - - 2.11.7 - 1.7 - - - 2.11.7 - 1.8 - + 2.11.8 1.7 - - 2.11.8 - 1.7 - 2.11.8 1.7 @@ -923,10 +517,6 @@ 2.12.0-RC1 1.8 - - 2.12.0-RC1 - 1.8 - 2.12.0-RC1 1.8 @@ -938,39 +528,27 @@ 2.11.0 - 1.7 + 1.8 2.11.0 - 1.7 + 1.8 2.11.0 - 1.7 + 1.8 2.11.1 - 1.7 + 1.8 2.11.1 - 1.7 + 1.8 2.11.1 - 1.7 - - - 2.11.2 - 1.7 - - - 2.11.2 - 1.7 - - - 2.11.2 - 1.7 + 1.8 2.11.2 @@ -985,18 +563,6 @@ 1.8 - - 2.11.5 - 1.7 - - - 2.11.5 - 1.7 - - - 2.11.5 - 1.7 - 2.11.5 1.8 @@ -1011,15 +577,15 @@ 2.11.6 - 1.7 + 1.8 2.11.6 - 1.7 + 1.8 2.11.6 - 1.7 + 1.8 2.11.6 @@ -1057,10 +623,6 @@ 2.11.8 1.8 - From 82972eb0703b0aeaf8c6b00f0393da2b3db7b621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 17 Sep 2016 15:02:24 +0200 Subject: [PATCH 0012/2665] Fix #2598: Do not swallow stderr from JS env in FrameworkDetector. --- project/BinaryIncompatibilities.scala | 3 +++ .../scala/org/scalajs/sbtplugin/FrameworkDetector.scala | 7 ++++--- .../org/scalajs/sbtplugin/ScalaJSPluginInternal.scala | 4 ++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index c77318b933..37fa41d5f9 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -15,6 +15,9 @@ object BinaryIncompatibilities { ) val SbtPlugin = Seq( + // private[sbtplugin], not an issue + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.sbtplugin.FrameworkDetector.detect") ) val TestAdapter = Seq( diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala index 4b57201bcb..1854d788c4 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala @@ -4,7 +4,7 @@ import sbt._ import org.scalajs.core.tools.io._ import org.scalajs.core.tools.json._ -import org.scalajs.core.tools.logging._ +import org.scalajs.core.tools.logging.Logger import org.scalajs.jsenv._ @@ -26,7 +26,8 @@ private[sbtplugin] final class FrameworkDetector(jsEnv: JSEnv) { * * Note: No JavaScript type tests are performed by this method */ - def detect(frameworks: Seq[TestFramework]): Map[TestFramework, String] = { + def detect(frameworks: Seq[TestFramework], + logger: Logger): Map[TestFramework, String] = { val data = frameworks.map(_.implClassNames.toList).toList.toJSON val code = s""" @@ -63,7 +64,7 @@ private[sbtplugin] final class FrameworkDetector(jsEnv: JSEnv) { val console = new StoreConsole val runner = jsEnv.jsRunner(vf) - runner.run(NullLogger, console) + runner.run(logger, console) // Filter jsDependencies unexpected output val results = console.buf collect { diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 0ae225675d..197cf08d6a 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -718,6 +718,7 @@ object ScalaJSPluginInternal { val console = scalaJSConsole.value val logger = streams.value.log + val toolsLogger = sbtLogger2ToolsLogger(logger) val frameworks = testFrameworks.value val jsEnv = loadedJSEnv.value match { @@ -729,8 +730,7 @@ object ScalaJSPluginInternal { val detector = new FrameworkDetector(jsEnv) - detector.detect(frameworks) map { case (tf, name) => - val toolsLogger = sbtLogger2ToolsLogger(logger) + detector.detect(frameworks, toolsLogger) map { case (tf, name) => (tf, new ScalaJSFramework(name, jsEnv, toolsLogger, console)) } }, From be01af325a88117edfb33e176b5a8b50a8a8670b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 17 Sep 2016 15:13:07 +0200 Subject: [PATCH 0013/2665] Fix #2583: Use JSDOMNodeJSEnv by default when requestsDOM is true. (instead of PhantomJS) --- ci/matrix.xml | 8 ++++---- .../org/scalajs/sbtplugin/ScalaJSPluginInternal.scala | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ci/matrix.xml b/ci/matrix.xml index 3424c6ea0f..ed6e9b2fb6 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -20,9 +20,9 @@ sbtretry 'set scalaJSStage in Global := FullOptStage' \ ++$scala helloworld/run \ helloworld/clean && - sbtretry 'set inScope(ThisScope in helloworld)(jsEnv := JSDOMNodeJSEnv().value)' \ + sbtretry 'set requiresDOM in helloworld := true' \ ++$scala helloworld/run && - sbtretry 'set inScope(ThisScope in helloworld)(jsEnv := JSDOMNodeJSEnv().value)' \ + sbtretry 'set requiresDOM in helloworld := true' \ 'set scalaJSStage in Global := FullOptStage' \ ++$scala helloworld/run \ helloworld/clean && @@ -81,9 +81,9 @@ sbtretry 'set scalaJSStage in Global := FullOptStage' \ ++$scala $testSuite/test \ $testSuite/clean && - sbtretry 'set inScope(ThisScope in $testSuite)(jsEnv := JSDOMNodeJSEnv().value)' \ + sbtretry 'set requiresDOM in $testSuite := true' \ ++$scala $testSuite/test && - sbtretry 'set inScope(ThisScope in $testSuite)(jsEnv := JSDOMNodeJSEnv().value)' \ + sbtretry 'set requiresDOM in $testSuite := true' \ 'set scalaJSStage in Global := FullOptStage' \ ++$scala $testSuite/test \ $testSuite/clean && diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 197cf08d6a..e4eb3123bd 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -564,7 +564,7 @@ object ScalaJSPluginInternal { if (scalaJSUseRhinoInternal.value) { RhinoJSEnvInternal().value } else if (scalaJSRequestsDOM.value) { - PhantomJSEnv().value + JSDOMNodeJSEnv().value } else { NodeJSEnv().value } From f60a074843676e1a823801216d750da7f65f4588 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Thu, 22 Sep 2016 21:06:04 +0200 Subject: [PATCH 0014/2665] Fix #2602: Linker gives bad error if used in invalid state --- .../scalajs/core/tools/linker/Linker.scala | 8 +-- .../core/tools/linker/LinkerTest.scala | 51 +++++++++++++++++++ 2 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala index 954e9a05bc..242a2d4c73 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala @@ -56,12 +56,12 @@ final class Linker(frontend: LinkerFrontend, backend: LinkerBackend) throw new IllegalStateException("Linker used concurrently") } - if (!_valid) { - throw new IllegalStateException( + try { + if (!_valid) { + throw new IllegalStateException( "Linker is invalid due to a previous exception in a component") - } + } - try { body } catch { case t: Throwable => diff --git a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala new file mode 100644 index 0000000000..233f0661e2 --- /dev/null +++ b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala @@ -0,0 +1,51 @@ +package org.scalajs.core.tools.linker + +import org.junit.Test +import org.junit.Assert._ + +import org.scalajs.core.tools.logging.NullLogger +import org.scalajs.core.tools.io._ + +class LinkerTest { + + /** This test exposes a problem where a linker in error state is called + * multiple times and ends up thinking it is being used concurrently. + */ + @Test + def clean_linking_state(): Unit = { + class DummyException extends Exception + + val badSeq = new IndexedSeq[VirtualScalaJSIRFile] { + def apply(x: Int): VirtualScalaJSIRFile = throw new DummyException() + def length: Int = throw new DummyException() + } + + val linker = Linker() + + def callLink(): Unit = + linker.link(badSeq, WritableMemVirtualJSFile("some_file"), NullLogger) + + // Call first time. Get exception from badSeq. + try { + callLink() + fail("Expected DummyException") + } catch { + case e: DummyException => // ok. + } + + def callInFailedState(): Unit = { + try { + callLink() + fail("Expected IllegalStateException") + } catch { + case e: IllegalStateException => + if (e.getMessage.contains("concurrent")) { + fail("Found bad message in exception: " + e.getMessage) + } + } + } + + for (_ <- 1 to 4) callInFailedState() + } + +} From 1d64ac5e8d0f11a0ba80627018ecd2e673fa4def Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Thu, 22 Sep 2016 21:17:32 +0200 Subject: [PATCH 0015/2665] DataInputStream: Remove TypedArray dependency. --- .../main/scala/java/io/DataInputStream.scala | 59 ++++++++----------- 1 file changed, 23 insertions(+), 36 deletions(-) diff --git a/javalib-ex/src/main/scala/java/io/DataInputStream.scala b/javalib-ex/src/main/scala/java/io/DataInputStream.scala index f3371dad28..1473a9f07e 100644 --- a/javalib-ex/src/main/scala/java/io/DataInputStream.scala +++ b/javalib-ex/src/main/scala/java/io/DataInputStream.scala @@ -2,19 +2,22 @@ package java.io import scala.scalajs.js.typedarray._ -/** ECMAScript 6 - * DataInputStream implementation using JavaScript typed arrays. - */ class DataInputStream(in: InputStream) extends FilterInputStream(in) with DataInput { + /* Due to the method readLine, we need to be able to push back a byte (if we + * read a \r and the following byte is NOT a \n). We implement this in the + * read() and the consumePos() method. + */ private var pushedBack: Int = -1 private var pushedBackMark: Int = -1 - // -- ArrayBufferInputStream mode helpers -- - // These variables are used to special case on ArrayBufferInputStreams - // They allow directly accessing the underlying ArrayBuffer rather than - // creating byte arrays first + /* ArrayBufferInputStream mode helpers + * + * These variables are used to special case on ArrayBufferInputStreams + * They allow directly accessing the underlying ArrayBuffer rather than + * creating byte arrays first. + */ private val inArrayBufferStream = in match { case in: ArrayBufferInputStream => in case _ => null @@ -24,7 +27,9 @@ class DataInputStream(in: InputStream) extends FilterInputStream(in) if (hasArrayBuffer) { val in = inArrayBufferStream new DataView(in.buffer, in.offset, in.length) - } else null + } else { + null + } } private def consumePos(n: Int) = { @@ -35,26 +40,6 @@ class DataInputStream(in: InputStream) extends FilterInputStream(in) resultPos } - // -- General InputStream mode helpers -- - // Due to the method readLine, we need to be able to push back a byte (if we - // read a \r and the following byte is NOT a \n). We implement this here. - // We also provide a method to create an ad-hoc data view of the next n bytes - private val convBufLen = 8 - private val convBuf = new ArrayBuffer(convBufLen) - private val convInView = new Int8Array(convBuf) - private val convOutView = new DataView(convBuf) - private def view(len: Int) = { - assert(len <= convBufLen) - var i = 0 - while (i < len) { - val byte = read() - if (byte == -1) eof() - convInView(i) = byte.toByte - i += 1 - } - convOutView - } - // General Helpers private def eof() = throw new EOFException() private def pushBack(v: Int) = { pushedBack = v } @@ -72,21 +57,21 @@ class DataInputStream(in: InputStream) extends FilterInputStream(in) if (hasArrayBuffer) bufDataView.getUint16(consumePos(2)).toChar else - view(2).getUint16(0).toChar + ((readByte() << 8) | readUnsignedByte()).toChar } def readDouble(): Double = { if (hasArrayBuffer) bufDataView.getFloat64(consumePos(8)) else - view(8).getFloat64(0) + java.lang.Double.longBitsToDouble(readLong()) } def readFloat(): Float = { if (hasArrayBuffer) bufDataView.getFloat32(consumePos(4)) else - view(4).getFloat32(0) + java.lang.Float.intBitsToFloat(readInt()) } def readFully(b: Array[Byte]): Unit = readFully(b, 0, b.length) @@ -106,10 +91,12 @@ class DataInputStream(in: InputStream) extends FilterInputStream(in) } def readInt(): Int = { - if (hasArrayBuffer) + if (hasArrayBuffer) { bufDataView.getInt32(consumePos(4)) - else - view(4).getInt32(0) + } else { + (readUnsignedByte() << 24) | (readUnsignedByte() << 16) | + (readUnsignedByte() << 8) | readUnsignedByte() + } } def readLine(): String = { @@ -140,7 +127,7 @@ class DataInputStream(in: InputStream) extends FilterInputStream(in) if (hasArrayBuffer) bufDataView.getInt16(consumePos(2)) else - view(2).getInt16(0) + ((readByte() << 8) | readUnsignedByte()).toShort } def readUnsignedByte(): Int = { @@ -153,7 +140,7 @@ class DataInputStream(in: InputStream) extends FilterInputStream(in) if (hasArrayBuffer) bufDataView.getUint16(consumePos(2)) else - view(2).getUint16(0) + (readUnsignedByte() << 8) | readUnsignedByte() } def readUTF(): String = { From b44757e50f0343522f8ad42e41e4642f03da6e9f Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Thu, 22 Sep 2016 21:58:39 +0200 Subject: [PATCH 0016/2665] Fix #2595: Move java.io.DataInputStream to javalib --- .../main/scala/java/io/DataInputStream.scala | 0 .../javalib/io/DataInputStreamJSTest.scala | 43 ++++++++++++++++++ .../javalib/io}/DataInputStreamTest.scala | 44 +++---------------- 3 files changed, 48 insertions(+), 39 deletions(-) rename {javalib-ex => javalib}/src/main/scala/java/io/DataInputStream.scala (100%) create mode 100644 test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/io/DataInputStreamJSTest.scala rename {javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/javalibex => test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io}/DataInputStreamTest.scala (89%) diff --git a/javalib-ex/src/main/scala/java/io/DataInputStream.scala b/javalib/src/main/scala/java/io/DataInputStream.scala similarity index 100% rename from javalib-ex/src/main/scala/java/io/DataInputStream.scala rename to javalib/src/main/scala/java/io/DataInputStream.scala diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/io/DataInputStreamJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/io/DataInputStreamJSTest.scala new file mode 100644 index 0000000000..3fbe4274c2 --- /dev/null +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/io/DataInputStreamJSTest.scala @@ -0,0 +1,43 @@ +package org.scalajs.testsuite.javalib.io + +import java.io.InputStream + +import org.scalajs.testsuite.utils.Platform._ + +import scala.scalajs.js.typedarray._ +import scala.scalajs.js.JSConverters._ + +import org.junit._ +import org.junit.Assume._ + +trait AssumeTypedArrays { + @BeforeClass def assumeTypedArrays(): Unit = { + assumeTrue("Assumed typed arrays", typedArrays) + } +} + +object DataInputStreamArrayBufferInputStreamTest extends AssumeTypedArrays + +class DataInputStreamArrayBufferInputStreamTest extends DataInputStreamTest { + protected def inFromBytes(bytes: Seq[Byte]): InputStream = + new ArrayBufferInputStream(new Int8Array(bytes.toJSArray).buffer) +} + +object DataInputStreamArrayPartiallyConsumedArrayBufferInputStreamTest + extends AssumeTypedArrays + +class DataInputStreamArrayPartiallyConsumedArrayBufferInputStreamTest + extends DataInputStreamTest { + + protected def inFromBytes(bytes: Seq[Byte]): InputStream = { + val addBytes = Seq[Byte](0, 0, 0, 0) + val allBytes = addBytes ++ bytes + val in = new ArrayBufferInputStream( + new Int8Array(allBytes.toJSArray).buffer) + + for (_ <- addBytes) + in.read() + + in + } +} diff --git a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/javalibex/DataInputStreamTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/DataInputStreamTest.scala similarity index 89% rename from javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/javalibex/DataInputStreamTest.scala rename to test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/DataInputStreamTest.scala index b53fbb5797..d068642b2e 100644 --- a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/javalibex/DataInputStreamTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/DataInputStreamTest.scala @@ -1,17 +1,14 @@ -package scala.scalajs.testsuite.javalibex +package org.scalajs.testsuite.javalib.io import java.io._ -import scala.scalajs.testsuite.utils.AssertThrows._ -import scala.scalajs.testsuite.utils.Platform._ +import org.scalajs.testsuite.utils.AssertThrows._ +import org.scalajs.testsuite.utils.Platform.executingInJVM import org.junit._ import org.junit.Assert._ import org.junit.Assume._ -import scala.scalajs.js.typedarray._ -import scala.scalajs.js.JSConverters._ - trait DataInputStreamTest { protected def inFromBytes(bytes: Seq[Byte]): InputStream @@ -300,6 +297,8 @@ trait DataInputStreamTest { } @Test def should_allow_marking_even_when_readLine_has_to_push_back(): Unit = { + assumeFalse("Not supported on JDK", executingInJVM) + val stream = newStream( "Hello World\nUNIX\nWindows\r\nMac (old)\rStuff".map(_.toInt): _*) @@ -321,40 +320,7 @@ trait DataInputStreamTest { range.toArray.map(_.asInstanceOf[Byte]) } -trait AssumeTypedArrays { - @BeforeClass def assumeTypedArrays(): Unit = { - assumeTrue("Assumed typed arrays", typedArrays) - } -} - -object DataInputStreamGenericTest extends AssumeTypedArrays - class DataInputStreamGenericTest extends DataInputStreamTest { protected def inFromBytes(bytes: Seq[Byte]): InputStream = new ByteArrayInputStream(bytes.toArray) } - -object DataInputStreamArrayBufferInputStreamTest extends AssumeTypedArrays - -class DataInputStreamArrayBufferInputStreamTest extends DataInputStreamTest { - protected def inFromBytes(bytes: Seq[Byte]): InputStream = - new ArrayBufferInputStream(new Int8Array(bytes.toJSArray).buffer) -} - -object DataInputStreamArrayPartiallyConsumedArrayBufferInputStreamTest - extends AssumeTypedArrays - -class DataInputStreamArrayPartiallyConsumedArrayBufferInputStreamTest - extends DataInputStreamTest { - - protected def inFromBytes(bytes: Seq[Byte]): InputStream = { - val addBytes = Seq[Byte](0, 0, 0, 0) - val allBytes = addBytes ++ bytes - val in = new ArrayBufferInputStream( - new Int8Array(allBytes.toJSArray).buffer) - - for (_ <- addBytes) in.read() - - in - } -} From 42c23e9e1fbfdcf4d0dfe35b2a235334929ee288 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 18 Sep 2016 12:06:45 +0200 Subject: [PATCH 0017/2665] Properly incrementalize the Emitter using knowledge queries. When a paper's terminology makes its way into a production codebase ... The `ScalaJSClassEmitter` and `JSDesugaring` do not have access to the `linkingUnit` anymore. All their requests for global knowledge go through a `GlobalKnowledge` interface, which contains the knowledge queries. The `Emitter` contains a subsystem `KnowledgeGuardian`, which, as its name implies, is responsible for guarding global knowledge. It tracks the dependencies between arbitrary `Invalidatable`s and the knowledge queries they perform. The `Invalidatable`s are `ClassCache` and `MethodCache`, which also implement `GlobalKnowledge` by delegating queries to the `KnowledgeGuardian`. This fixes some corner case bugs in the incremental behavior of the `Emitter`, the most significant one being changes in the `@JSName` of a native JS class or object. Previously, users of `LoadJSConstructor` (resp. `LoadJSModule`) would not be properly re-desugared when the `@JSName` of a target class (resp. module) was changed. The new architecture can now easily be extended with new kinds of global knowledge without fear of breaking incrementality. --- .../org/scalajs/jsenv/rhino/RhinoJSEnv.scala | 5 +- .../scalajs/jsenv/rhino/ScalaJSCoreLib.scala | 12 +- project/BinaryIncompatibilities.scala | 45 ++++ .../linker/backend/emitter/CoreJSLibs.scala | 6 +- .../linker/backend/emitter/Emitter.scala | 83 ++++-- .../backend/emitter/GlobalKnowledge.scala | 47 ++++ .../linker/backend/emitter/JSDesugaring.scala | 90 +++---- .../backend/emitter/KnowledgeGuardian.scala | 250 ++++++++++++++++++ .../backend/emitter/ScalaJSClassEmitter.scala | 121 ++++----- 9 files changed, 517 insertions(+), 142 deletions(-) create mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala create mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/RhinoJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/RhinoJSEnv.scala index 202e87ef1e..0bc0087840 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/RhinoJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/RhinoJSEnv.scala @@ -64,9 +64,8 @@ final class RhinoJSEnv private ( def withSourceMap(sourceMap: Boolean): RhinoJSEnv = new RhinoJSEnv(semantics, withDOM, sourceMap) - /* Although RhinoJSEnv does not use the Emitter directly, it uses - * ScalaJSCoreLib which uses the same underlying components - * (ScalaJSClassEmitter, JSDesugaring and CoreJSLibs). + /* Ask the Emitter, which we'll use in ScalaJSCoreLib to generate JS code, + * what are its requirements. */ val symbolRequirements = Emitter.symbolRequirements(semantics, ESLevel.ES5) diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala index 05222a8402..725d08c971 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala @@ -28,6 +28,10 @@ private[rhino] class ScalaJSCoreLib(linkingUnit: LinkingUnit) { require(linkingUnit.esLevel == ESLevel.ES5, "RhinoJSEnv only supports ES5") + private val emitter = new Emitter(linkingUnit.semantics, ECMAScript51Global) + + emitter.rhinoAPI.initialize(linkingUnit) + private val (providers, exportedSymbols) = { val providers = mutable.Map.empty[String, LinkedClass] val exportedSymbols = mutable.ListBuffer.empty[String] @@ -43,7 +47,7 @@ private[rhino] class ScalaJSCoreLib(linkingUnit: LinkingUnit) { def insertInto(context: Context, scope: Scriptable): Unit = { val semantics = linkingUnit.semantics - context.evaluateFile(scope, CoreJSLibs.lib(semantics, ECMAScript51Global)) + context.evaluateFile(scope, emitter.rhinoAPI.getHeaderFile()) lazifyScalaJSFields(scope) // Make sure exported symbols are loaded @@ -105,8 +109,7 @@ private[rhino] class ScalaJSCoreLib(linkingUnit: LinkingUnit) { private def getSourceMapper(fileName: String, untilLine: Int) = { val linked = providers(fileName.stripSuffix(PseudoFileSuffix)) val mapper = new Printers.ReverseSourceMapPrinter(untilLine) - val desugared = - new ScalaJSClassEmitter(ECMAScript51Global, linkingUnit).genClassDef(linked) + val desugared = emitter.rhinoAPI.genClassDef(linked) mapper.reverseSourceMap(desugared) mapper } @@ -160,8 +163,7 @@ private[rhino] class ScalaJSCoreLib(linkingUnit: LinkingUnit) { val linkedClass = providers.getOrElse(encodedName, throw new RhinoJSEnv.ClassNotFoundException(encodedName)) - val desugared = - new ScalaJSClassEmitter(ECMAScript51Global, linkingUnit).genClassDef(linkedClass) + val desugared = emitter.rhinoAPI.genClassDef(linkedClass) // Write tree val codeWriter = new java.io.StringWriter diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 37fa41d5f9..d83e730c18 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -6,6 +6,51 @@ object BinaryIncompatibilities { ) val Tools = Seq( + // private[emitter], not an issue + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring#JSDesugar.this"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.genRawJSClassConstructor"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.desugarTree"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.desugarToFunction"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.desugarToFunction"), + + // private[emitter], not an issue + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.this"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genDefaultMethods"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.isInterface"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genConstructor"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genDefaultMethod"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genClass"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genConstructorExportDef"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genTypeData"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genProperty"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genES6Class"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.linkedClassByName"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genMethod"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genClassDef"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genClassExports"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genExportedMembers"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genStaticMembers") ) val JSEnvs = Seq( diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala index a5710c05d0..34616cfe39 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala @@ -20,8 +20,10 @@ import org.scalajs.core.tools.linker.backend.OutputMode import scala.collection.immutable.Seq import scala.collection.mutable -// The only reason this is not private[backend] is that Rhino needs it -private[scalajs] object CoreJSLibs { +/* The only reason this is not private[emitter] is that Closure needs it. + * TODO We should try and get rid of this coupling. + */ +private[backend] object CoreJSLibs { private type Config = (Semantics, OutputMode) diff --git 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 index 7b5439d990..16498dc81e 100644 --- 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 @@ -33,7 +33,11 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, def this(semantics: Semantics, outputMode: OutputMode) = this(semantics, outputMode, InternalOptions()) - private var classEmitter: ScalaJSClassEmitter = _ + private val knowledgeGuardian = new KnowledgeGuardian + + private val classEmitter = + new ScalaJSClassEmitter(semantics, outputMode, internalOptions) + private val classCaches = mutable.Map.empty[List[String], ClassCache] private[this] var statsClassesReused: Int = 0 @@ -73,15 +77,13 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, } def emit(unit: LinkingUnit, builder: JSTreeBuilder, logger: Logger): Unit = { - classEmitter = new ScalaJSClassEmitter(outputMode, internalOptions, unit) - startRun() + startRun(unit) try { val orderedClasses = unit.classDefs.sortWith(compareClasses) for (classInfo <- orderedClasses) emitLinkedClass(classInfo, builder) } finally { endRun(logger) - classEmitter = null } } @@ -103,11 +105,16 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, else lhs.encodedName.compareTo(rhs.encodedName) < 0 } - private def startRun(): Unit = { + private def startRun(unit: LinkingUnit): Unit = { statsClassesReused = 0 statsClassesInvalidated = 0 statsMethodsReused = 0 statsMethodsInvalidated = 0 + + val invalidateAll = knowledgeGuardian.update(unit) + if (invalidateAll) + classCaches.clear() + classCaches.valuesIterator.foreach(_.startRun()) } @@ -136,24 +143,24 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, val methodCache = classCache.getStaticCache(m.info.encodedName) addTree(methodCache.getOrElseUpdate(m.version, - classEmitter.genMethod(className, m.tree))) + classEmitter.genMethod(className, m.tree)(methodCache))) } if (linkedClass.hasInstances && kind.isAnyScalaJSDefinedClass) { val ctor = classTreeCache.constructor.getOrElseUpdate( - classEmitter.genConstructor(linkedClass)) + classEmitter.genConstructor(linkedClass)(classCache)) // Normal methods val memberMethods = for (m <- linkedClass.memberMethods) yield { val methodCache = classCache.getMethodCache(m.info.encodedName) methodCache.getOrElseUpdate(m.version, - classEmitter.genMethod(className, m.tree)) + classEmitter.genMethod(className, m.tree)(methodCache)) } // Exported Members val exportedMembers = classTreeCache.exportedMembers.getOrElseUpdate( - classEmitter.genExportedMembers(linkedClass)) + classEmitter.genExportedMembers(linkedClass)(classCache)) outputMode match { case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => @@ -169,14 +176,14 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, case js.Skip() => Nil case oneMember => List(oneMember) } - addTree(classEmitter.genES6Class(linkedClass, allMembers)) + addTree(classEmitter.genES6Class(linkedClass, allMembers)(classCache)) } } else if (kind == ClassKind.Interface) { // Default methods for (m <- linkedClass.memberMethods) yield { val methodCache = classCache.getMethodCache(m.info.encodedName) addTree(methodCache.getOrElseUpdate(m.version, - classEmitter.genDefaultMethod(className, m.tree))) + classEmitter.genDefaultMethod(className, m.tree)(methodCache))) } } @@ -189,7 +196,7 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, if (linkedClass.hasRuntimeTypeInfo) { addTree(classTreeCache.typeData.getOrElseUpdate( - classEmitter.genTypeData(linkedClass))) + classEmitter.genTypeData(linkedClass)(classCache))) } if (linkedClass.hasInstances && kind.isClass && linkedClass.hasRuntimeTypeInfo) @@ -201,7 +208,7 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, classEmitter.genModuleAccessor(linkedClass))) addTree(classTreeCache.classExports.getOrElseUpdate( - classEmitter.genClassExports(linkedClass))) + classEmitter.genClassExports(linkedClass)(classCache))) } // Helpers @@ -226,9 +233,29 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, emitNextLine(0) } + // Private API for Rhino + + private[scalajs] object rhinoAPI { // scalastyle:ignore + /** A GlobalKnowledge that never tracks dependencies. This can be used in + * cases where we do not use any cache, which is what `genClassDef()` in + * this class does. + */ + private val globalKnowledge: GlobalKnowledge = + new knowledgeGuardian.KnowledgeAccessor {} + + def initialize(linkingUnit: LinkingUnit): Unit = + startRun(linkingUnit) + + def getHeaderFile(): org.scalajs.core.tools.io.VirtualJSFile = + CoreJSLibs.lib(semantics, outputMode) + + def genClassDef(linkedClass: LinkedClass): js.Tree = + classEmitter.genClassDef(linkedClass)(globalKnowledge) + } + // Caching - private final class ClassCache { + private final class ClassCache extends knowledgeGuardian.KnowledgeAccessor { private[this] var _cache: DesugaredClassCache = null private[this] var _lastVersion: Option[String] = None private[this] var _cacheUsed = false @@ -236,6 +263,15 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, private[this] val _staticCaches = mutable.Map.empty[String, MethodCache] private[this] val _methodCaches = mutable.Map.empty[String, MethodCache] + override def invalidate(): Unit = { + /* Do not invalidate contained methods, as they have their own + * invalidation logic. + */ + super.invalidate() + _cache = null + _lastVersion = None + } + def startRun(): Unit = { _cacheUsed = false _staticCaches.valuesIterator.foreach(_.startRun()) @@ -244,6 +280,7 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, def getCache(version: Option[String]): DesugaredClassCache = { if (_cache == null || _lastVersion.isEmpty || _lastVersion != version) { + invalidate() statsClassesInvalidated += 1 _lastVersion = version _cache = new DesugaredClassCache @@ -265,21 +302,28 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, _methodCaches.retain((_, c) => c.cleanAfterRun()) if (!_cacheUsed) - _cache = null + invalidate() _staticCaches.nonEmpty || _methodCaches.nonEmpty || _cacheUsed } } - private final class MethodCache { + private final class MethodCache extends knowledgeGuardian.KnowledgeAccessor { private[this] var _tree: js.Tree = null private[this] var _lastVersion: Option[String] = None private[this] var _cacheUsed = false + override def invalidate(): Unit = { + super.invalidate() + _tree = null + _lastVersion = None + } + def startRun(): Unit = _cacheUsed = false def getOrElseUpdate(version: Option[String], v: => js.Tree): js.Tree = { if (_tree == null || _lastVersion.isEmpty || _lastVersion != version) { + invalidate() statsMethodsInvalidated += 1 _tree = v _lastVersion = version @@ -290,7 +334,12 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, _tree } - def cleanAfterRun(): Boolean = _cacheUsed + def cleanAfterRun(): Boolean = { + if (!_cacheUsed) + invalidate() + + _cacheUsed + } } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala new file mode 100644 index 0000000000..16fcc1a21f --- /dev/null +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala @@ -0,0 +1,47 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package org.scalajs.core.tools.linker.backend.emitter + +import org.scalajs.core.ir.Trees.FieldDef + +private[emitter] trait GlobalKnowledge { + /** Tests whether the parent class data is accessed in the linking unit. */ + def isParentDataAccessed: Boolean + + // TODO Get rid of this when we break backward binary compatibility + /** Whether the standard library we're using has the new `RuntimeLong` + * implementation, with `lo` and `hi`. + */ + def hasNewRuntimeLong: Boolean + + /** Tests whether the specified class name refers to an `Interface`. */ + def isInterface(className: String): Boolean + + /** `None` for non-native JS classes; `Some(jsName)` for native JS classes. + * + * It is invalid to call this method with a class that is not a JS class + * (native or not). + */ + def getJSClassJSName(className: String): Option[String] + + /** The `encodedName` of the superclass of a (non-native) JS class. + * + * It is invalid to call this method with a class that is not a non-native + * JS class. + */ + def getSuperClassOfJSClass(className: String): String + + /** The `FieldDef`s of a non-native JS class. + * + * It is invalid to call this method with a class that is not a non-native + * JS class. + */ + def getJSClassFieldDefs(className: String): List[FieldDef] +} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala index 18c1228576..3ad44fe15a 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala @@ -204,7 +204,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { private[emitter] def desugarToFunction( classEmitter: ScalaJSClassEmitter, enclosingClassName: String, params: List[ParamDef], body: Tree, isStat: Boolean)( - implicit pos: Position): js.Function = { + implicit globalKnowledge: GlobalKnowledge, pos: Position): js.Function = { desugarToFunction(classEmitter, enclosingClassName, None, params, body, isStat) } @@ -215,7 +215,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { classEmitter: ScalaJSClassEmitter, enclosingClassName: String, thisIdent: Option[js.Ident], params: List[ParamDef], body: Tree, isStat: Boolean)( - implicit pos: Position): js.Function = { + implicit globalKnowledge: GlobalKnowledge, pos: Position): js.Function = { new JSDesugar(classEmitter, enclosingClassName, thisIdent).desugarToFunction(params, body, isStat) } @@ -223,7 +223,8 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { /** Desugars a statement or an expression. */ private[emitter] def desugarTree( classEmitter: ScalaJSClassEmitter, enclosingClassName: String, - tree: Tree, isStat: Boolean): js.Tree = { + tree: Tree, isStat: Boolean)( + implicit globalKnowledge: GlobalKnowledge): js.Tree = { val desugar = new JSDesugar(classEmitter, enclosingClassName, None) if (isStat) desugar.transformStat(tree, Set.empty)(Env.empty) @@ -239,19 +240,12 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { private class JSDesugar( classEmitter: ScalaJSClassEmitter, enclosingClassName: String, - thisIdent: Option[js.Ident]) { + thisIdent: Option[js.Ident])( + implicit globalKnowledge: GlobalKnowledge) { private val semantics = classEmitter.semantics private implicit val outputMode: OutputMode = classEmitter.outputMode - // TODO Get rid of this when we break backward binary compatibility - private lazy val hasNewRuntimeLong = { - val rtLongClass = classEmitter.linkedClassByName(LongImpl.RuntimeLongClass) - rtLongClass.memberMethods.exists { linkedMethod => - linkedMethod.tree.name.name == LongImpl.initFromParts - } - } - // Synthetic variables var syntheticVarCounter: Int = 0 @@ -437,8 +431,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { unnest(List(qualifier, item, rhs)) { case (List(newQualifier, newItem, newRhs), env0) => implicit val env = env0 - val linkedClass = classEmitter.linkedClassByName(cls.className) - val ctor = genRawJSClassConstructor(linkedClass) + val ctor = genRawJSClassConstructor(cls.className) genCallHelper("superSet", ctor DOT "prototype", transformExpr(newQualifier), transformExpr(item), transformExpr(rhs)) @@ -515,13 +508,11 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { unnestOrSpread(args) { (newArgs, env0) => implicit val env = env0 - val linkedClass = classEmitter.linkedClassByName(enclosingClassName) - val superCtorCall = { outputMode match { case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => val superCtor = genRawJSClassConstructor( - getSuperClassOfJSClass(linkedClass)) + globalKnowledge.getSuperClassOfJSClass(enclosingClassName)) if (containsAnySpread(newArgs)) { val argArray = spreadToArgArray(newArgs) @@ -539,8 +530,11 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { } } + val enclosingClassFieldDefs = + globalKnowledge.getJSClassFieldDefs(enclosingClassName) + val fieldDefs = for { - field @ FieldDef(name, ftpe, mutable) <- linkedClass.fields + field @ FieldDef(name, ftpe, mutable) <- enclosingClassFieldDefs } yield { implicit val pos = field.pos /* Here, a naive translation would emit something like this: @@ -950,11 +944,14 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { case LoadJSModule(_) => allowSideEffects - // LoadJSConstructor is pure only for Scala.js-defined JS classes + /* LoadJSConstructor is pure only for Scala.js-defined JS classes, + * which do not have a jsName. Note that this test makes sense per se, + * as the actual desugaring of `LoadJSConstructor` is based on the + * jsName of the class. + */ case LoadJSConstructor(cls) => allowUnpure || { - val linkedClass = classEmitter.linkedClassByName(cls.className) - linkedClass.kind == ClassKind.JSClass + globalKnowledge.getJSClassJSName(cls.className).isEmpty } // Non-expressions @@ -1413,10 +1410,8 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { } case JSSuperBracketCall(cls, receiver, method, args) => - val superClass = getSuperClassOfJSClass( - classEmitter.linkedClassByName(cls.className)) - val superCtor = - LoadJSConstructor(ClassType(superClass.encodedName)) + val superClass = globalKnowledge.getSuperClassOfJSClass(cls.className) + val superCtor = LoadJSConstructor(ClassType(superClass)) redo { JSBracketMethodApply( @@ -1667,7 +1662,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { val className = cls.className val transformedArgs = (receiver :: args) map transformExpr - if (classEmitter.isInterface(className)) { + if (globalKnowledge.isInterface(className)) { val Ident(methodName, origName) = method val fullName = className + "__" + methodName js.Apply(envField("f", fullName, origName), @@ -1930,14 +1925,12 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { transformExpr(method)), args map transformExpr) case JSSuperBracketSelect(cls, qualifier, item) => - val linkedClass = classEmitter.linkedClassByName(cls.className) - val ctor = genRawJSClassConstructor(linkedClass) + val ctor = genRawJSClassConstructor(cls.className) genCallHelper("superGet", ctor DOT "prototype", transformExpr(qualifier), transformExpr(item)) case LoadJSConstructor(cls) => - val linkedClass = classEmitter.linkedClassByName(cls.className) - genRawJSClassConstructor(linkedClass) + genRawJSClassConstructor(cls.className) case LoadJSModule(cls) => genLoadModule(cls.className) @@ -1979,7 +1972,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { case LongLiteral(0L) => genLongModuleApply(LongImpl.Zero) case LongLiteral(value) => - if (hasNewRuntimeLong) { + if (globalKnowledge.hasNewRuntimeLong) { val (lo, hi) = LongImpl.extractParts(value) genNewLong(LongImpl.initFromParts, js.IntLiteral(lo), js.IntLiteral(hi)) @@ -2086,13 +2079,6 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { } } - private def getSuperClassOfJSClass(linkedClass: LinkedClass)( - implicit pos: Position): LinkedClass = { - require(linkedClass.kind.isJSClass) - assert(linkedClass.superClass.isDefined, linkedClass.encodedName) - classEmitter.linkedClassByName(linkedClass.superClass.get.name) - } - private def genFround(arg: js.Tree)(implicit pos: Position): js.Tree = { genCallHelper("fround", arg) } @@ -2262,15 +2248,27 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { implicit outputMode: OutputMode, pos: Position): js.Tree = envField("c", className) - private[emitter] def genRawJSClassConstructor(linkedClass: LinkedClass)( + private[emitter] def genRawJSClassConstructor(className: String)( + implicit globalKnowledge: GlobalKnowledge, outputMode: OutputMode, + pos: Position): js.Tree = { + + genRawJSClassConstructor(className, + globalKnowledge.getJSClassJSName(className)) + } + + private[emitter] def genRawJSClassConstructor(className: String, + jsName: Option[String])( implicit outputMode: OutputMode, pos: Position): js.Tree = { - if (linkedClass.kind == ClassKind.JSClass) { - encodeClassVar(linkedClass.encodedName) - } else { - require(linkedClass.jsName.isDefined) - linkedClass.jsName.get.split("\\.").foldLeft(envField("g")) { - (prev, part) => genBracketSelect(prev, js.StringLiteral(part)) - } + jsName match { + case None => + // this is a Scala.js-defined JS class + encodeClassVar(className) + + case Some(jsName) => + // this is a native JS class + jsName.split("\\.").foldLeft(envField("g")) { + (prev, part) => genBracketSelect(prev, js.StringLiteral(part)) + } } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala new file mode 100644 index 0000000000..c316319221 --- /dev/null +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala @@ -0,0 +1,250 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package org.scalajs.core.tools.linker.backend.emitter + +import scala.collection.mutable + +import org.scalajs.core.ir.ClassKind +import org.scalajs.core.ir.Trees.FieldDef + +import org.scalajs.core.tools.linker._ + +private[emitter] final class KnowledgeGuardian { + import KnowledgeGuardian._ + + private var firstRun: Boolean = true + + private var hasNewRuntimeLong: Boolean = _ + private var isParentDataAccessed: Boolean = _ + + private val classes = mutable.Map.empty[String, Class] + + private def askHasNewRuntimeLong(invalidatable: Invalidatable): Boolean = + hasNewRuntimeLong + + private def askIsParentDataAccessed(invalidatable: Invalidatable): Boolean = + isParentDataAccessed + + /** Returns `true` if *all* caches should be invalidated. + * + * For global properties that are rarely changed and heavily used (such as + * isParentDataAccessed), we do not want to pay the price of the + * dependency graph, in terms of memory consumption and time spent + * maintaining it. It is a better trade-off to invalidate everything in + * the rare events where they do change. + */ + def update(linkingUnit: LinkingUnit): Boolean = { + val newIsParentDataAccessed = linkingUnit.globalInfo.isParentDataAccessed + var newHasNewRuntimeLong: Boolean = false + + // Update classes + for (linkedClass <- linkingUnit.classDefs) { + classes.get(linkedClass.encodedName).fold[Unit] { + // new class + classes.put(linkedClass.encodedName, new Class(linkedClass)) + } { existingCls => + existingCls.update(linkedClass) + } + + if (linkedClass.encodedName == LongImpl.RuntimeLongClass) { + newHasNewRuntimeLong = linkedClass.memberMethods.exists { linkedMethod => + linkedMethod.tree.name.name == LongImpl.initFromParts + } + } + } + + // Garbage collection + classes.retain((_, cls) => cls.testAndResetIsAlive()) + + val invalidateAll = !firstRun && { + newIsParentDataAccessed != isParentDataAccessed || + newHasNewRuntimeLong != hasNewRuntimeLong + } + firstRun = false + + isParentDataAccessed = newIsParentDataAccessed + hasNewRuntimeLong = newHasNewRuntimeLong + + if (invalidateAll) + classes.valuesIterator.foreach(_.unregisterAll()) + invalidateAll + } + + abstract class KnowledgeAccessor extends GlobalKnowledge with Invalidatable { + /* In theory, a KnowledgeAccessor should *contain* a GlobalKnowledge, not + * *be* a GlobalKnowledge. We organize it that way to reduce memory + * footprint and pointer indirections. + */ + + def hasNewRuntimeLong: Boolean = + askHasNewRuntimeLong(this) + + def isParentDataAccessed: Boolean = + askIsParentDataAccessed(this) + + def isInterface(className: String): Boolean = + classes(className).askIsInterface(this) + + def getJSClassJSName(className: String): Option[String] = + classes(className).askJSClassJSName(this) + + def getSuperClassOfJSClass(className: String): String = + classes(className).askJSSuperClass(this) + + def getJSClassFieldDefs(className: String): List[FieldDef] = + classes(className).askJSClassFieldDefs(this) + } +} + +private[emitter] object KnowledgeGuardian { + private[KnowledgeGuardian] trait Unregisterable { + def unregister(invalidatable: Invalidatable): Unit + } + + trait Invalidatable { + private val _registeredTo = mutable.Set.empty[Unregisterable] + + private[KnowledgeGuardian] def registeredTo( + unregisterable: Unregisterable): Unit = { + _registeredTo += unregisterable + } + + /** To be overridden to perform subclass-specific invalidation. + * + * All overrides should call the default implementation with `super` so + * that this `Invalidatable` is unregistered from the dependency graph. + */ + def invalidate(): Unit = { + _registeredTo.foreach(_.unregister(this)) + _registeredTo.clear() + } + } + + private class Class(initClass: LinkedClass) extends Unregisterable { + private var isAlive: Boolean = true + + private var isInterface = computeIsInterface(initClass) + private var jsName = computeJSName(initClass) + private var jsSuperClass = computeJSSuperClass(initClass) + private var jsClassFieldDefs = computeJSClassFieldDefs(initClass) + + private val isInterfaceAskers = mutable.Set.empty[Invalidatable] + private val jsNameAskers = mutable.Set.empty[Invalidatable] + private val jsSuperClassAskers = mutable.Set.empty[Invalidatable] + private val jsClassFieldDefsAskers = mutable.Set.empty[Invalidatable] + + def update(linkedClass: LinkedClass): Unit = { + isAlive = true + + val newIsInterface = computeIsInterface(linkedClass) + if (newIsInterface != isInterface) { + isInterface = newIsInterface + invalidateAskers(isInterfaceAskers) + } + + val newJSName = computeJSName(linkedClass) + if (newJSName != jsName) { + jsName = newJSName + invalidateAskers(jsNameAskers) + } + + val newJSSuperClass = computeJSSuperClass(linkedClass) + if (newJSSuperClass != jsSuperClass) { + jsSuperClass = newJSSuperClass + invalidateAskers(jsSuperClassAskers) + } + + val newJSClassFieldDefs = computeJSClassFieldDefs(linkedClass) + if (newJSClassFieldDefs != jsClassFieldDefs) { + jsClassFieldDefs = newJSClassFieldDefs + invalidateAskers(jsClassFieldDefsAskers) + } + } + + private def computeIsInterface(linkedClass: LinkedClass): Boolean = + linkedClass.kind == ClassKind.Interface + + private def computeJSName(linkedClass: LinkedClass): Option[String] = + linkedClass.jsName + + private def computeJSSuperClass(linkedClass: LinkedClass): String = { + linkedClass.kind match { + case ClassKind.JSClass | ClassKind.JSModuleClass => + linkedClass.superClass.get.name + case _ => + null + } + } + + private def computeJSClassFieldDefs( + linkedClass: LinkedClass): List[FieldDef] = { + if (linkedClass.kind == ClassKind.JSClass) + linkedClass.fields + else + Nil + } + + private def invalidateAskers(askers: mutable.Set[Invalidatable]): Unit = { + /* Calling `invalidateAndUnregisterFromAll()` will cause the + * `Invalidatable` to call `unregister()` in this class, which will + * mutate the `askers` set. Therefore, we cannot directly iterate over + * `askers`, and need to take a snapshot instead. + */ + val snapshot = askers.toSeq + askers.clear() + snapshot.foreach(_.invalidate()) + } + + def testAndResetIsAlive(): Boolean = { + val result = isAlive + isAlive = false + result + } + + def askIsInterface(invalidatable: Invalidatable): Boolean = { + invalidatable.registeredTo(this) + isInterfaceAskers += invalidatable + isInterface + } + + def askJSClassJSName(invalidatable: Invalidatable): Option[String] = { + invalidatable.registeredTo(this) + jsNameAskers += invalidatable + jsName + } + + def askJSSuperClass(invalidatable: Invalidatable): String = { + invalidatable.registeredTo(this) + jsSuperClassAskers += invalidatable + jsSuperClass + } + + def askJSClassFieldDefs(invalidatable: Invalidatable): List[FieldDef] = { + invalidatable.registeredTo(this) + jsClassFieldDefsAskers += invalidatable + jsClassFieldDefs + } + + def unregister(invalidatable: Invalidatable): Unit = { + isInterfaceAskers -= invalidatable + jsNameAskers -= invalidatable + jsSuperClassAskers -= invalidatable + jsClassFieldDefsAskers -= invalidatable + } + + /** Call this when we invalidate all caches. */ + def unregisterAll(): Unit = { + isInterfaceAskers.clear() + jsNameAskers.clear() + jsSuperClassAskers.clear() + jsClassFieldDefsAskers.clear() + } + } +} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala index 028d8bb253..d18e8e8b30 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala @@ -22,55 +22,19 @@ import org.scalajs.core.tools.javascript.{Trees => js} import org.scalajs.core.tools.linker.backend.OutputMode import org.scalajs.core.tools.linker.{LinkedClass, LinkingUnit} -/** Defines methods to emit Scala.js classes to JavaScript code. - * The results are completely desugared. - * - * The only reason this is not `private[emitter]` is because `RhinoJSEnv` - * needs it. - */ -private[scalajs] final class ScalaJSClassEmitter( +/** Emitter for the skeleton of classes. */ +private[emitter] final class ScalaJSClassEmitter( + private[emitter] val semantics: Semantics, private[emitter] val outputMode: OutputMode, - internalOptions: InternalOptions, - linkingUnit: LinkingUnit) { + internalOptions: InternalOptions) { private val jsDesugaring = new JSDesugaring(internalOptions) import ScalaJSClassEmitter._ import jsDesugaring._ - def this(outputMode: OutputMode, linkingUnit: LinkingUnit) = - this(outputMode, InternalOptions(), linkingUnit) - - private[emitter] lazy val linkedClassByName: Map[String, LinkedClass] = - linkingUnit.classDefs.map(c => c.encodedName -> c).toMap - - private[emitter] def isInterface(className: String): Boolean = { - /* TODO In theory, there is a flaw in the incremental behavior about this. - * - * This method is used to desugar ApplyStatically nodes. Depending on - * whether className is a class or an interface, the desugaring changes. - * This means that the result of desugaring an ApplyStatically depends on - * some global knowledge from the whole program (and not only of the method - * being desugared). If, from one run to the next, className switches from - * being a class to an interface or vice versa, there is nothing demanding - * that the IR of the call site change, yet the desugaring should change. - * In theory, this causes a flaw in the incremental behavior of the - * Emitter, which will not invalidate its cache for this. - * - * In practice, this should not happen, though. A method can only be called - * statically by subclasses and subtraits at the Scala *language* level. - * We also know that when a class/trait changes, all its subclasses and - * subtraits are recompiled by sbt's incremental compilation. This should - * mean that the input IR is always changed in that case anyway. - * - * It would be good to fix thoroughly if the Emitter/ScalaJSClassEmitter - * gets something for incremental whole-program updates, but for now, we - * live with the theoretical flaw. - */ - linkedClassByName(className).kind == ClassKind.Interface - } - - private[emitter] def semantics: Semantics = linkingUnit.semantics + def this(semantics: Semantics, outputMode: OutputMode) = + this(semantics, outputMode, InternalOptions()) private implicit def implicitOutputMode: OutputMode = outputMode @@ -93,7 +57,9 @@ private[scalajs] final class ScalaJSClassEmitter( * @param ancestors Encoded names of the ancestors of the class (not only * parents), including the class itself. */ - def genClassDef(tree: LinkedClass): js.Tree = { + def genClassDef(tree: LinkedClass)( + implicit globalKnowledge: GlobalKnowledge): js.Tree = { + implicit val pos = tree.pos val kind = tree.kind @@ -119,21 +85,25 @@ private[scalajs] final class ScalaJSClassEmitter( js.Block(reverseParts.reverse) } - def genStaticMembers(tree: LinkedClass): js.Tree = { + def genStaticMembers(tree: LinkedClass)( + implicit globalKnowledge: GlobalKnowledge): js.Tree = { val className = tree.name.name val staticMemberDefs = tree.staticMethods.map(m => genMethod(className, m.tree)) js.Block(staticMemberDefs)(tree.pos) } - def genDefaultMethods(tree: LinkedClass): js.Tree = { + def genDefaultMethods(tree: LinkedClass)( + implicit globalKnowledge: GlobalKnowledge): js.Tree = { val className = tree.name.name val defaultMethodDefs = tree.memberMethods.map(m => genDefaultMethod(className, m.tree)) js.Block(defaultMethodDefs)(tree.pos) } - def genClass(tree: LinkedClass): js.Tree = { + def genClass(tree: LinkedClass)( + implicit globalKnowledge: GlobalKnowledge): js.Tree = { + val className = tree.name.name val typeFunctionDef = genConstructor(tree) val memberDefs = @@ -159,7 +129,9 @@ private[scalajs] final class ScalaJSClassEmitter( } /** Generates an ECMAScript 6 class for a linked class. */ - def genES6Class(tree: LinkedClass, members: List[js.Tree]): js.Tree = { + def genES6Class(tree: LinkedClass, members: List[js.Tree])( + implicit globalKnowledge: GlobalKnowledge): js.Tree = { + require(outputMode == OutputMode.ECMAScript6) val className = tree.name.name @@ -171,14 +143,16 @@ private[scalajs] final class ScalaJSClassEmitter( if (!tree.kind.isJSClass) encodeClassVar(parentIdent.name) else - genRawJSClassConstructor(linkedClassByName(parentIdent.name)) + genRawJSClassConstructor(parentIdent.name) } js.ClassDef(Some(classIdent), parentVar, members)(tree.pos) } /** Generates the JS constructor for a class. */ - def genConstructor(tree: LinkedClass): js.Tree = { + def genConstructor(tree: LinkedClass)( + implicit globalKnowledge: GlobalKnowledge): js.Tree = { + assert(tree.kind.isAnyScalaJSDefinedClass) assert(tree.superClass.isDefined || tree.name.name == Definitions.ObjectClass, s"Class ${tree.name.name} is missing a parent class") @@ -193,7 +167,8 @@ private[scalajs] final class ScalaJSClassEmitter( } /** Generates the JS constructor for a class, ES5 style. */ - private def genES5Constructor(tree: LinkedClass): js.Tree = { + private def genES5Constructor(tree: LinkedClass)( + implicit globalKnowledge: GlobalKnowledge): js.Tree = { implicit val pos = tree.pos val className = tree.name.name @@ -231,8 +206,7 @@ private[scalajs] final class ScalaJSClassEmitter( val (inheritedCtorDef, inheritedCtorRef) = if (!isJSClass) { (js.Skip(), envField("h", parentIdent.name)) } else { - val superCtor = genRawJSClassConstructor( - linkedClassByName(parentIdent.name)) + val superCtor = genRawJSClassConstructor(parentIdent.name) (makeInheritableCtorDef(superCtor), envField("h", className)) } js.Block( @@ -250,7 +224,8 @@ private[scalajs] final class ScalaJSClassEmitter( } /** Generates the JS constructor for a class, ES6 style. */ - private def genES6Constructor(tree: LinkedClass): js.Tree = { + private def genES6Constructor(tree: LinkedClass)( + implicit globalKnowledge: GlobalKnowledge): js.Tree = { implicit val pos = tree.pos if (tree.kind.isJSClass) { @@ -272,7 +247,8 @@ private[scalajs] final class ScalaJSClassEmitter( } } - private def genConstructorFunForJSClass(tree: LinkedClass): js.Function = { + private def genConstructorFunForJSClass(tree: LinkedClass)( + implicit globalKnowledge: GlobalKnowledge): js.Function = { implicit val pos = tree.pos require(tree.kind.isJSClass) @@ -288,7 +264,8 @@ private[scalajs] final class ScalaJSClassEmitter( } /** Generates the creation of fields for a class. */ - private def genFieldDefs(tree: LinkedClass): List[js.Tree] = { + private def genFieldDefs(tree: LinkedClass)( + implicit globalKnowledge: GlobalKnowledge): List[js.Tree] = { val tpe = ClassType(tree.encodedName) for { field @ FieldDef(name, ftpe, mutable) <- tree.fields @@ -303,7 +280,8 @@ private[scalajs] final class ScalaJSClassEmitter( } /** Generates a method. */ - def genMethod(className: String, method: MethodDef): js.Tree = { + def genMethod(className: String, method: MethodDef)( + implicit globalKnowledge: GlobalKnowledge): js.Tree = { implicit val pos = method.pos val methodFun0 = desugarToFunction(this, className, @@ -339,7 +317,8 @@ private[scalajs] final class ScalaJSClassEmitter( } /** Generates a default method. */ - def genDefaultMethod(className: String, method: MethodDef): js.Tree = { + def genDefaultMethod(className: String, method: MethodDef)( + implicit globalKnowledge: GlobalKnowledge): js.Tree = { implicit val pos = method.pos /* TODO The identifier `$thiz` cannot be produced by 0.6.x compilers due to @@ -363,7 +342,8 @@ private[scalajs] final class ScalaJSClassEmitter( } /** Generates a property. */ - def genProperty(className: String, property: PropertyDef): js.Tree = { + def genProperty(className: String, property: PropertyDef)( + implicit globalKnowledge: GlobalKnowledge): js.Tree = { outputMode match { case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => genPropertyES5(className, property) @@ -372,8 +352,8 @@ private[scalajs] final class ScalaJSClassEmitter( } } - private def genPropertyES5(className: String, - property: PropertyDef): js.Tree = { + private def genPropertyES5(className: String, property: PropertyDef)( + implicit globalKnowledge: GlobalKnowledge): js.Tree = { implicit val pos = property.pos // defineProperty method @@ -422,8 +402,8 @@ private[scalajs] final class ScalaJSClassEmitter( js.Apply(defProp, proto :: name :: descriptor :: Nil) } - private def genPropertyES6(className: String, - property: PropertyDef): js.Tree = { + private def genPropertyES6(className: String, property: PropertyDef)( + implicit globalKnowledge: GlobalKnowledge): js.Tree = { implicit val pos = property.pos val propName = genPropertyName(property.name) @@ -654,7 +634,8 @@ private[scalajs] final class ScalaJSClassEmitter( ancestors DOT className } - def genTypeData(tree: LinkedClass): js.Tree = { + def genTypeData(tree: LinkedClass)( + implicit globalKnowledge: GlobalKnowledge): js.Tree = { import Definitions._ import TreeDSL._ @@ -677,7 +658,7 @@ private[scalajs] final class ScalaJSClassEmitter( if (isRawJSType) js.BooleanLiteral(true) else js.Undefined() - val parentData = if (linkingUnit.globalInfo.isParentDataAccessed) { + val parentData = if (globalKnowledge.isParentDataAccessed) { tree.superClass.fold[js.Tree] { if (isObjectClass) js.Null() else js.Undefined() @@ -714,7 +695,7 @@ private[scalajs] final class ScalaJSClassEmitter( if (tree.jsName.isEmpty && kind != ClassKind.JSClass) { (envField("noIsInstance"), js.Undefined()) } else { - val jsCtor = genRawJSClassConstructor(tree) + val jsCtor = genRawJSClassConstructor(className, tree.jsName) (js.Function(List(js.ParamDef(Ident("x"), rest = false)), js.Return { js.BinaryOp(JSBinaryOp.instanceof, js.VarRef(Ident("x")), jsCtor) }), js.Undefined()) @@ -819,7 +800,8 @@ private[scalajs] final class ScalaJSClassEmitter( js.Block(createModuleInstanceField, createAccessor) } - def genExportedMembers(tree: LinkedClass): js.Tree = { + def genExportedMembers(tree: LinkedClass)( + implicit globalKnowledge: GlobalKnowledge): js.Tree = { val exports = tree.exportedMembers map { member => member.tree match { case MethodDef(false, StringLiteral("constructor"), _, _, _) @@ -838,7 +820,8 @@ private[scalajs] final class ScalaJSClassEmitter( js.Block(exports)(tree.pos) } - def genClassExports(tree: LinkedClass): js.Tree = { + def genClassExports(tree: LinkedClass)( + implicit globalKnowledge: GlobalKnowledge): js.Tree = { val exports = tree.classExports collect { case e: ConstructorExportDef => genConstructorExportDef(tree, e) @@ -851,8 +834,8 @@ private[scalajs] final class ScalaJSClassEmitter( js.Block(exports)(tree.pos) } - def genConstructorExportDef(cd: LinkedClass, - tree: ConstructorExportDef): js.Tree = { + def genConstructorExportDef(cd: LinkedClass, tree: ConstructorExportDef)( + implicit globalKnowledge: GlobalKnowledge): js.Tree = { import TreeDSL._ implicit val pos = tree.pos From 9651550facf23797180865096ef18d72e05bfd47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 19 Sep 2016 18:41:47 +0200 Subject: [PATCH 0018/2665] Fix #2601: Propagate `version` from jar files to their entries. --- .../src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala index f82ac82eef..b0830efade 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala @@ -183,6 +183,7 @@ trait VirtualJarFile extends VirtualBinaryFile { findEntries(_.endsWith(".sjsir")) { (entry, stream) => val file = new JarEntryIRFile(path, entry.getName) file.content = IO.readInputStreamToByteArray(stream) + file.version = version file } } @@ -191,6 +192,7 @@ trait VirtualJarFile extends VirtualBinaryFile { findEntries(_.endsWith(".js")) { (entry, stream) => val file = new JarEntryJSFile(path, entry.getName) file.content = IO.readInputStreamToString(stream) + file.version = version file } } From 3440c2759df19f6fe4272c5eacee0831d4586b0f Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 25 Sep 2016 18:18:15 +0200 Subject: [PATCH 0019/2665] Fix #2603: Default values for non-exposed defs. --- .../org/scalajs/core/compiler/GenJSCode.scala | 20 ++++++++++- .../jsinterop/ScalaJSDefinedTest.scala | 34 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 9719feca58..dce8434bbd 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -1998,7 +1998,25 @@ abstract class GenJSCode extends plugins.PluginComponent isRawJSCtorDefaultParam(sym) } else { sym.hasFlag(reflect.internal.Flags.DEFAULTPARAM) && - isRawJSType(sym.owner.tpe) + isRawJSType(sym.owner.tpe) && { + /* If this is a default parameter accessor on a + * ScalaJSDefinedJSClass, we need to know if the method for which we + * are the default parameter is exposed or not. + * We do this by removing the $default suffix from the method name, + * and looking up a member with that name in the owner. + * Note that this does not work for local methods. But local methods + * are never exposed. + * Further note that overloads are easy, because either all or none + * of them are exposed. + */ + def isAttachedMethodExposed = { + val methodName = nme.defaultGetterToMethod(sym.name) + val ownerMethod = sym.owner.info.decl(methodName) + ownerMethod.filter(isExposed).exists + } + + !isScalaJSDefinedJSClass(sym.owner) || isAttachedMethodExposed + } } } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala index 67f6d8a417..e81764711c 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala @@ -1307,6 +1307,19 @@ class ScalaJSDefinedTest { assertEquals("hello3 4", dyn.foo("hello", 4)) } + @Test def overload_with_default_parameter(): Unit = { + @ScalaJSDefined + class OverloadDefaultParameter extends js.Object { + def foo(x: Int): Int = x + def foo(x: String = ""): String = x + } + + val foo = new OverloadDefaultParameter + assertEquals(5, foo.foo(5)) + assertEquals("", foo.foo()) + assertEquals("hello", foo.foo("hello")) + } + @Test def implement_a_simple_trait(): Unit = { @ScalaJSDefined class ImplementSimpleTrait extends js.Object with SimpleTrait { @@ -1431,6 +1444,27 @@ class ScalaJSDefinedTest { assertEquals(18, parent.methodWithDefault()) assertEquals(14, parent.methodWithDefault(7)) } + + // #2603 + @Test def default_values_in_non_exposed_methods(): Unit = { + @ScalaJSDefined + class DefaultParameterss(val default: Int) extends js.Object { + /* We don't use a constant default value to make sure it actually comes + * from the default parameter accessors. + */ + private def privateWithDefault(x: Int = default) = x + + def callPrivate(): Int = privateWithDefault() + def callNested(): Int = { + def nested(x: Int = default) = x + nested() + } + } + + val x = new DefaultParameterss(5) + assertEquals(5, x.callPrivate()) + assertEquals(5, x.callNested()) + } } object ScalaJSDefinedTest { From d2d8472ce4c86f1d69fa3ac52718d8a59986ceb0 Mon Sep 17 00:00:00 2001 From: Aleksandar Prokopec Date: Fri, 30 Sep 2016 09:58:54 +0200 Subject: [PATCH 0020/2665] Implement AtomicLongArray. --- .../concurrent/atomic/AtomicLongArray.scala | 66 +++++++++++++++++++ .../util/concurrent/atomic/AtomicTest.scala | 36 ++++++++++ 2 files changed, 102 insertions(+) create mode 100644 javalib/src/main/scala/java/util/concurrent/atomic/AtomicLongArray.scala diff --git a/javalib/src/main/scala/java/util/concurrent/atomic/AtomicLongArray.scala b/javalib/src/main/scala/java/util/concurrent/atomic/AtomicLongArray.scala new file mode 100644 index 0000000000..acb8ec4405 --- /dev/null +++ b/javalib/src/main/scala/java/util/concurrent/atomic/AtomicLongArray.scala @@ -0,0 +1,66 @@ +package java.util.concurrent.atomic + +class AtomicLongArray(length: Int) extends Serializable { + def this(array: Array[Long]) = { + this(array.size) + System.arraycopy(array, 0, inner, 0, length) + } + + private val inner: Array[Long] = new Array[Long](length) + + final def length(): Int = + inner.length + + final def get(i: Int): Long = + inner(i) + + final def set(i: Int, newValue: Long): Unit = + inner(i) = newValue + + final def lazySet(i: Int, newValue: Long): Unit = + set(i, newValue) + + final def getAndSet(i: Int, newValue: Long): Long = { + val ret = get(i) + set(i, newValue) + ret + } + + final def compareAndSet(i: Int, expect: Long, update: Long): Boolean = { + if (get(i) != expect) { + false + } else { + set(i, update) + true + } + } + + final def weakCompareAndSet(i: Int, expect: Long, update: Long): Boolean = + compareAndSet(i, expect, update) + + final def getAndIncrement(i: Int): Long = + getAndAdd(i, 1) + + final def getAndDecrement(i: Int): Long = + getAndAdd(i, -1) + + final def getAndAdd(i: Int, delta: Long): Long = { + val ret = get(i) + set(i, ret + delta) + ret + } + + final def incrementAndGet(i: Int): Long = + addAndGet(i, 1) + + final def decrementAndGet(i: Int): Long = + addAndGet(i, -1) + + final def addAndGet(i: Int, delta: Long): Long = { + set(i, get(i) + delta) + get(i) + } + + override def toString(): String = + inner.mkString("[", ", ", "]") +} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/atomic/AtomicTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/atomic/AtomicTest.scala index 886255df0d..52ba329adb 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/atomic/AtomicTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/atomic/AtomicTest.scala @@ -131,6 +131,42 @@ class AtomicTest { assertSame(thing1, atomic2.get(0)) assertSame(thing2, atomic2.get(1)) } + + @Test def atomicLongArrayTest(): Unit = { + val a = 7L + val b = 17L + val c = 177L + + val atomic = new java.util.concurrent.atomic.AtomicLongArray(2) + assertEquals(2, atomic.length) + assertEquals(0L, atomic.get(0)) + atomic.set(0, a) + assertEquals(a, atomic.get(0)) + atomic.set(1, b) + assertEquals(b, atomic.get(1)) + assertFalse(atomic.compareAndSet(0, b, a)) + assertEquals(a, atomic.get(0)) + assertTrue(atomic.compareAndSet(1, b, a)) + assertEquals(a, atomic.get(1)) + assertFalse(atomic.compareAndSet(1, c, b)) + assertEquals(a, atomic.getAndSet(1, b)) + assertEquals(b, atomic.get(1)) + assertEquals(b, atomic.getAndIncrement(1)) + assertEquals(b + 1, atomic.get(1)) + assertEquals(b + 2, atomic.incrementAndGet(1)) + assertEquals(b + 2, atomic.getAndDecrement(1)) + assertEquals(b, atomic.decrementAndGet(1)) + assertEquals(a, atomic.getAndAdd(0, 2)) + assertEquals(a + 2, atomic.get(0)) + assertEquals(a, atomic.addAndGet(0, -2)) + + val initArray = Array(a, b) + val atomic2 = new java.util.concurrent.atomic.AtomicLongArray(initArray) + assertEquals(a, atomic2.get(0)) + assertEquals(b, atomic2.get(1)) + initArray(0) = c + assertEquals(a, atomic2.get(0)) + } } case class Foo(i: Int) From d17addb1e50263fefc54c2c76000e561e655b7fe Mon Sep 17 00:00:00 2001 From: Aleksandar Prokopec Date: Sat, 1 Oct 2016 11:42:23 +0200 Subject: [PATCH 0021/2665] Implement java.util.Timer. --- javalib/src/main/scala/java/util/Timer.scala | 130 ++++++++++++ .../src/main/scala/java/util/TimerTask.scala | 51 +++++ .../testsuite/javalib/util/TimerTest.scala | 188 ++++++++++++++++++ 3 files changed, 369 insertions(+) create mode 100644 javalib/src/main/scala/java/util/Timer.scala create mode 100644 javalib/src/main/scala/java/util/TimerTask.scala create mode 100644 test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/util/TimerTest.scala diff --git a/javalib/src/main/scala/java/util/Timer.scala b/javalib/src/main/scala/java/util/Timer.scala new file mode 100644 index 0000000000..78f068cee7 --- /dev/null +++ b/javalib/src/main/scala/java/util/Timer.scala @@ -0,0 +1,130 @@ +package java.util + +import scala.collection._ +import scala.concurrent.duration._ + +class Timer() { + private[util] var canceled: Boolean = false + + def this(isDaemon: Boolean) = this() + + def this(name: String) = this() + + def this(name: String, isDaemon: Boolean) = this() + + private def acquire(task: TimerTask): Unit = { + if (canceled) + throw new IllegalStateException("Timer already cancelled.") + else if (task.owner != null || task.canceled) { + throw new IllegalStateException("TimerTask already scheduled or canceled.") + } + task.owner = this + } + + private def checkDelay(delay: Long): Unit = { + if (delay < 0 || (delay + System.currentTimeMillis) < 0) + throw new IllegalArgumentException("Negative delay.") + } + + private def checkTime(time: Date): Unit = { + if (time.getTime < 0) + throw new IllegalArgumentException(s"Negative time: $time.") + } + + private def checkPeriod(period: Long): Unit = { + if (period <= 0) + throw new IllegalArgumentException("Non-positive period.") + } + + private def scheduleOnce(task: TimerTask, delay: Long): Unit = { + acquire(task) + task.timeout(delay.millis) { + task.scheduledOnceAndStarted = true + task.doRun() + } + } + + private def getMillisUntil(time: Date): Long = + math.max(0L, time.getTime - System.currentTimeMillis()) + + def schedule(task: TimerTask, delay: Long): Unit = { + checkDelay(delay) + scheduleOnce(task, delay) + } + + def schedule(task: TimerTask, time: Date): Unit = { + checkTime(time) + val delay = getMillisUntil(time) + scheduleOnce(task, delay) + } + + private def schedulePeriodically( + task: TimerTask, delay: Long, period: Long): Unit = { + acquire(task) + task.timeout(delay.millis) { + def loop(): Unit = { + val startTime = System.nanoTime() + task.doRun() + val endTime = System.nanoTime() + val duration = (endTime - startTime) / 1000000 + task.timeout((period - duration).millis) { + loop() + } + } + loop() + } + } + + def schedule(task: TimerTask, delay: Long, period: Long): Unit = { + checkDelay(delay) + checkPeriod(period) + schedulePeriodically(task, delay, period) + } + + def schedule(task: TimerTask, firstTime: Date, period: Long): Unit = { + checkTime(firstTime) + checkPeriod(period) + val delay = getMillisUntil(firstTime) + schedulePeriodically(task, delay, period) + } + + private def scheduleFixed( + task: TimerTask, delay: Long, period: Long): Unit = { + acquire(task) + task.timeout(delay.millis) { + def loop(scheduledTime: Long): Unit = { + task.doRun() + val nextScheduledTime = scheduledTime + period + val nowTime = System.nanoTime / 1000000L + if (nowTime >= nextScheduledTime) { + // Re-run immediately. + loop(nextScheduledTime) + } else { + // Re-run after a timeout. + task.timeout((nextScheduledTime - nowTime).millis) { + loop(nextScheduledTime) + } + } + } + loop(System.nanoTime / 1000000L + period) + } + } + + def scheduleAtFixedRate(task: TimerTask, delay: Long, period: Long): Unit = { + checkDelay(delay) + checkPeriod(period) + scheduleFixed(task, delay, period) + } + + def scheduleAtFixedRate(task: TimerTask, firstTime: Date, period: Long): Unit = { + checkTime(firstTime) + checkPeriod(period) + val delay = getMillisUntil(firstTime) + scheduleFixed(task, delay, period) + } + + def cancel(): Unit = canceled = true + + def purge(): Int = 0 + +} diff --git a/javalib/src/main/scala/java/util/TimerTask.scala b/javalib/src/main/scala/java/util/TimerTask.scala new file mode 100644 index 0000000000..eadbd758e4 --- /dev/null +++ b/javalib/src/main/scala/java/util/TimerTask.scala @@ -0,0 +1,51 @@ +package java.util + +import scala.concurrent.duration.FiniteDuration +import scala.scalajs.js.timers._ +import scala.scalajs.js.timers.SetTimeoutHandle + +abstract class TimerTask { + private[util] var owner: Timer = null + private[util] var canceled: Boolean = false + private[util] var scheduledOnceAndStarted: Boolean = false + private[util] var lastScheduled: Long = 0L + private[util] var handle: SetTimeoutHandle = null + + def run(): Unit + + def cancel(): Boolean = { + if (handle != null) { + clearTimeout(handle) + handle = null + } + if (canceled || owner == null || scheduledOnceAndStarted) { + canceled = true + false + } else { + canceled = true + true + } + } + + def scheduledExecutionTime(): Long = lastScheduled + + private[util] def timeout(delay: FiniteDuration)(body: => Unit): Unit = { + if (!canceled) { + handle = setTimeout(delay)(body) + } + } + + private[util] def doRun(): Unit = { + if (!canceled && !owner.canceled) { + lastScheduled = System.currentTimeMillis() + try { + run() + } catch { + case t: Throwable => + canceled = true + throw t + } + } + } + +} diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/util/TimerTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/util/TimerTest.scala new file mode 100644 index 0000000000..17271c943b --- /dev/null +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/util/TimerTest.scala @@ -0,0 +1,188 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.javalib.util + +import org.junit.Assert._ +import org.junit.Test + +import org.scalajs.testsuite.jsinterop.TimeoutMock +import org.scalajs.testsuite.utils.AssertThrows._ + +import java.util.Timer +import java.util.TimerTask + +import scala.collection._ + +class TimerTest { + // Note that we are not currently testing `scheduleAtFixedRate`, because we + // cannot mock `System.nanoTime`. + + @Test def scheduleOnce(): Unit = { + TimeoutMock.withMockedTimeout { tick => + var completed = false + val timer = new Timer + val task = new TimerTask { + def run(): Unit = { + completed = true + } + } + timer.schedule(task, 1000) + tick(999) + assertFalse(completed) + tick(2) + assertTrue(completed) + assertFalse(task.cancel()) + + val secondTask = new TimerTask { + def run(): Unit = {} + } + assertThrows(classOf[IllegalArgumentException], timer.schedule(secondTask, -1)) + } + } + + @Test def scheduleOnceCancel(): Unit = { + TimeoutMock.withMockedTimeout { tick => + var completed = false + val timer = new Timer + val task = new TimerTask { + def run(): Unit = { + completed = true + } + } + timer.schedule(task, 1000) + tick(500) + assertTrue(task.cancel()) + tick(501) + assertFalse(completed) + } + } + + @Test def scheduleOnceAndCancelInRun(): Unit = { + TimeoutMock.withMockedTimeout { tick => + var cancelReturnValue = true + val timer = new Timer + val task = new TimerTask { + def run(): Unit = { + cancelReturnValue = this.cancel() + } + } + timer.schedule(task, 1000) + tick(1000) + assertFalse(cancelReturnValue) + } + } + + @Test def cancelBeforeSchedule(): Unit = { + TimeoutMock.withMockedTimeout { tick => + var completed = false + val timer = new Timer + val task = new TimerTask { + def run(): Unit = { + completed = true + } + } + assertFalse(task.cancel()) + assertThrows(classOf[IllegalStateException], timer.schedule(task, 1000)) + tick(2000) + assertFalse(completed) + } + } + + @Test def scheduleFixedDelay(): Unit = { + TimeoutMock.withMockedTimeout { tick => + var seen = mutable.Buffer[Int]() + val timer = new Timer + val task = new TimerTask { + var count = 0 + def run(): Unit = { + seen += count + count += 1 + } + } + timer.schedule(task, 1000, 100) + assertEquals(Seq(), seen) + tick(500) + assertEquals(Seq(), seen) + tick(500) + assertEquals(Seq(0), seen) + tick(100) + assertEquals(Seq(0, 1), seen) + tick(100) + assertEquals(Seq(0, 1, 2), seen) + tick(100) + assertEquals(Seq(0, 1, 2, 3), seen) + tick(250) + assertEquals(Seq(0, 1, 2, 3, 4, 5), seen) + assertTrue(task.cancel()) + tick(100) + assertEquals(Seq(0, 1, 2, 3, 4, 5), seen) + assertFalse(task.cancel()) + + val zeroPeriodTask = new TimerTask { + def run(): Unit = {} + } + assertThrows(classOf[IllegalArgumentException], + timer.schedule(zeroPeriodTask, 1000, 0)) + + val secondTask = new TimerTask { + var count = 6 + def run(): Unit = { + seen += count + count += 1 + } + } + timer.schedule(secondTask, 0, 100) + tick(100) + assertEquals(Seq(0, 1, 2, 3, 4, 5, 6, 7), seen) + timer.cancel() + tick(200) + assertEquals(Seq(0, 1, 2, 3, 4, 5, 6, 7), seen) + + val afterCancelTask = new TimerTask { + def run(): Unit = {} + } + assertThrows(classOf[IllegalStateException], + timer.schedule(afterCancelTask, 1000, 100)) + } + } + + @Test def scheduleFixedDelayCancel(): Unit = { + TimeoutMock.withMockedTimeout { tick => + var executed = false + val timer = new Timer + val task = new TimerTask { + def run(): Unit = { + executed = true + } + } + timer.schedule(task, 1000, 100) + tick(500) + assertTrue(task.cancel()) + assertFalse(task.cancel()) + tick(501) + assertFalse(executed) + } + } + + @Test def scheduleFixedDelayAndCancelInRun(): Unit = { + TimeoutMock.withMockedTimeout { tick => + var cancelReturnValue = false + val timer = new Timer + val task = new TimerTask { + def run(): Unit = { + cancelReturnValue = this.cancel() + } + } + timer.schedule(task, 1000, 100) + tick(999) + assertFalse(cancelReturnValue) + tick(2) + assertTrue(cancelReturnValue) + } + } +} From 020bc5f40ce085753b5954e7fac9e6430081a507 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 6 Oct 2016 16:12:28 +0200 Subject: [PATCH 0022/2665] Move Platform.scala in testSuite from test/ to main/. This seems to make Eclipse much happier. It used to complain about `Platform` not being defined in some of source files. Also, this makes sense on its own. --- .../scala/org/scalajs/testsuite/utils/Platform.scala | 0 .../scala/org/scalajs/testsuite/utils/Platform.scala | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename test-suite/js/src/{test => main}/scala/org/scalajs/testsuite/utils/Platform.scala (100%) rename test-suite/jvm/src/{test => main}/scala/org/scalajs/testsuite/utils/Platform.scala (100%) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/Platform.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala similarity index 100% rename from test-suite/js/src/test/scala/org/scalajs/testsuite/utils/Platform.scala rename to test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala diff --git a/test-suite/jvm/src/test/scala/org/scalajs/testsuite/utils/Platform.scala b/test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala similarity index 100% rename from test-suite/jvm/src/test/scala/org/scalajs/testsuite/utils/Platform.scala rename to test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala From eb6cd45946b2e38d86692a68e391a43ccb8324fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 21 Aug 2016 11:27:42 +0200 Subject: [PATCH 0023/2665] Bump the IR version number for the upcoming changes. --- ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index 630ee5b9f1..c733a60ffe 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -21,7 +21,7 @@ object ScalaJSVersions { * - a prior release version (i.e. "0.5.0", *not* "0.5.0-SNAPSHOT") * - `current` */ - val binaryEmitted: String = "0.6.8" + val binaryEmitted: String = current /** Versions whose binary files we can support (used by deserializer) */ val binarySupported: Set[String] = From 91474870d11fff0de73f10a361c92fc7345e3a8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 21 Aug 2016 11:52:46 +0200 Subject: [PATCH 0024/2665] Fix #2552: Store generalized "loading spec" for native things in IR. Previously, only native JS classes stored in the IR the means to load their constructor. This was stored as the `jsName` field, which was the fully qualified name of the class constructor, starting from the global object. This information was notably used by the `LoadJSConstructor` IR node, allowing that node to be valid both for native JS classes and Scala.js-defined JS classes. Native JS objects did not have a similar information, which caused `LoadJSModule` to be valid only for Scala.js-defined JS objects. Therefore, for native JS objects, the "desugaring" of `LoadJSModule` that would logically happen at link-time was done by the compiler. This meant that changing the `@JSName` of a native JS object was not a binary compatible change, as recorded in issue #2552. This commit fixes this issue, and in the process generalizes the stored information as "loading spec". Loading specs apply both to native JS classes and objects. They are a declarative specification of how a class constructor or an object should be loaded by `LoadJSConstructor` and `LoadJSModule`, respectively. Instead of storing the unstructured fully qualified name, a loading spec is an ADT with, currently, only one possible case, which is `Global(path: List[String])`. In the future, other loading spec kinds will be added, such as imports from ES6 modules (see #2175). Since now both classes and objects have a loading spec, we cannot use `jsName.isDefined` to identify native JS classes anymore (which is necessary for IR checks and when emitting the run-time `isInstance` reflective functions for raw JS types). To recover this distinction in the IR, we split `ClassKind.RawJSType` into three: `NativeJSClass`, `NativeJSModuleClass` and `AbstractJSType` (the latter being used for JS traits). With this information, we can check that `LoadJSConstructor` is valid for `NativeJSClass` and that `LoadJSModule` is valid for `NativeJSModuleClass`. We add a deserialization hack to turn `RawJSType` from the 0.6.8 format into `NativeJSClass` if there was a `jsName` (which we also turn into a loading spec). There is a hack on top of the hack, though. Since `jsName` is only visible in the tree, we cannot apply this hack to the `kind` stored in the infos. Therefore, the `kind` in the infos may be inconsistent with that in the tree. This is only a slight issue for the `Analyzer`, which therefore has another hack to tolerate an `AbstractJSType` where it expects a `NativeJSClass`. Note that native JS *objects* compiled with the 0.6.8 format will be deserialized as `AbstractJSType`, which means that `LoadJSModule` cannot be used on them. This means that even the new compiler must eagerly desugar `LoadJSModule` when loading native JS modules compiled by an older compiler, as it used to always do. Since there is no way to otherwise tell whether an object was compiled with a recent compiler or not, we add a marker annotation `@HasJSNativeLoadSpec` to native JS objects compiled with the 0.6.13 format or later. For those, we can issue a `LoadJSModule` node. In summary, this commit provides: - A fix for #2552 for objects compiled with 0.6.13 or later. - A generalized loading spec which can be extended to ES6 imports in the future. --- .../org/scalajs/core/compiler/GenJSCode.scala | 55 ++++++++-------- .../scalajs/core/compiler/JSDefinitions.scala | 1 + .../core/compiler/JSGlobalAddons.scala | 44 ++++++++++--- .../scalajs/core/compiler/PrepJSInterop.scala | 66 ++++++++++++------- .../scala/org/scalajs/core/ir/ClassKind.scala | 39 +++++++---- .../scala/org/scalajs/core/ir/Printers.scala | 25 +++---- .../org/scalajs/core/ir/Serializers.scala | 61 +++++++++++++++-- .../main/scala/org/scalajs/core/ir/Tags.scala | 5 ++ .../scala/org/scalajs/core/ir/Trees.scala | 35 +++++++++- .../org/scalajs/core/ir/PrintersTest.scala | 26 ++++++-- .../scalajs/js/annotation/JSFullName.scala | 4 ++ .../internal/HasJSNativeLoadSpec.scala | 20 ++++++ project/BinaryIncompatibilities.scala | 15 +++++ .../core/tools/linker/LinkedClass.scala | 10 +-- .../core/tools/linker/analyzer/Analyzer.scala | 40 ++++++++--- .../backend/emitter/GlobalKnowledge.scala | 9 +-- .../linker/backend/emitter/JSDesugaring.scala | 37 +++++++---- .../backend/emitter/KnowledgeGuardian.scala | 32 ++++----- .../backend/emitter/ScalaJSClassEmitter.scala | 22 ++++--- .../core/tools/linker/checker/IRChecker.scala | 41 ++++++++++-- .../tools/linker/checker/InfoChecker.scala | 15 ++++- .../tools/linker/frontend/BaseLinker.scala | 2 +- .../frontend/optimizer/GenIncOptimizer.scala | 4 +- 23 files changed, 445 insertions(+), 163 deletions(-) create mode 100644 library/src/main/scala/scala/scalajs/js/annotation/internal/HasJSNativeLoadSpec.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index dce8434bbd..e1186fd079 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -46,7 +46,7 @@ abstract class GenJSCode extends plugins.PluginComponent import rootMirror._ import definitions._ import jsDefinitions._ - import jsInterop.{jsNameOf, fullJSNameOf} + import jsInterop.{jsNameOf, compat068FullJSNameOf, jsNativeLoadSpecOf} import JSTreeExtractors._ import treeInfo.hasSynthCaseSymbol @@ -574,8 +574,8 @@ abstract class GenJSCode extends plugins.PluginComponent val newClassDef = { implicit val pos = origJsClass.pos val parent = js.Ident(ir.Definitions.ObjectClass) - js.ClassDef(origJsClass.name, ClassKind.RawJSType, - Some(parent), interfaces = Nil, jsName = None, + js.ClassDef(origJsClass.name, ClassKind.AbstractJSType, + Some(parent), interfaces = Nil, jsNativeLoadSpec = None, staticMembers.toList)(origJsClass.optimizerHints) } @@ -685,18 +685,20 @@ abstract class GenJSCode extends plugins.PluginComponent implicit val pos = sym.pos val classIdent = encodeClassFullNameIdent(sym) + val kind = { + if (sym.isTraitOrInterface) ClassKind.AbstractJSType + else if (sym.isModuleClass) ClassKind.NativeJSModuleClass + else ClassKind.NativeJSClass + } val superClass = if (sym.isTraitOrInterface) None else Some(encodeClassFullNameIdent(sym.superClass)) - val jsName = - if (sym.isTraitOrInterface || sym.isModuleClass) None - else Some(fullJSNameOf(sym)) + val jsNativeLoadSpec = + if (sym.isTraitOrInterface) None + else Some(jsNativeLoadSpecOf(sym)) - js.ClassDef(classIdent, ClassKind.RawJSType, - superClass, - genClassInterfaces(sym), - jsName, - Nil)( + js.ClassDef(classIdent, kind, superClass, genClassInterfaces(sym), + jsNativeLoadSpec, Nil)( OptimizerHints.empty) } @@ -4161,16 +4163,6 @@ abstract class GenJSCode extends plugins.PluginComponent js.LoadJSConstructor(jstpe.ClassType(encodeClassFullName(sym))) } - /** Gen JS code representing a JS module (var of the global scope) */ - private def genPrimitiveJSModule(sym: Symbol)( - implicit pos: Position): js.Tree = { - assert(sym.isModuleClass, - s"genPrimitiveJSModule called with non-module $sym") - fullJSNameOf(sym).split('.').foldLeft(genLoadGlobal()) { (memo, chunk) => - js.JSBracketSelect(memo, js.StringLiteral(chunk)) - } - } - /** Gen actual actual arguments to Scala method call. * Returns a list of the transformed arguments. * @@ -4931,12 +4923,21 @@ abstract class GenJSCode extends plugins.PluginComponent if (sym1 == StringModule) RuntimeStringModule.moduleClass else sym1 - val isGlobalScope = sym.tpe.typeSymbol isSubClass JSGlobalScopeClass - - if (isGlobalScope) { - genLoadGlobal() - } else if (isJSNativeClass(sym)) { - genPrimitiveJSModule(sym) + if (isJSNativeClass(sym) && + !sym.hasAnnotation(HasJSNativeLoadSpecAnnotation)) { + /* Compatibility for native JS modules compiled with Scala.js 0.6.12 + * and earlier. Since they did not store their loading spec in the IR, + * the js.LoadJSModule() IR node cannot be used to load them. We must + * "desugar" it early in the compiler. + */ + if (sym.isSubClass(JSGlobalScopeClass)) { + genLoadGlobal() + } else { + compat068FullJSNameOf(sym).split('.').foldLeft(genLoadGlobal()) { + (memo, chunk) => + js.JSBracketSelect(memo, js.StringLiteral(chunk)) + } + } } else { val moduleClassName = encodeClassFullName(sym) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 5db65aa513..30285b16e7 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -65,6 +65,7 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val JSExportNamedAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportNamed") lazy val ScalaJSDefinedAnnotation = getRequiredClass("scala.scalajs.js.annotation.ScalaJSDefined") lazy val SJSDefinedAnonymousClassAnnotation = getRequiredClass("scala.scalajs.js.annotation.SJSDefinedAnonymousClass") + lazy val HasJSNativeLoadSpecAnnotation = getRequiredClass("scala.scalajs.js.annotation.internal.HasJSNativeLoadSpec") lazy val JavaDefaultMethodAnnotation = getRequiredClass("scala.scalajs.js.annotation.JavaDefaultMethod") diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala index 733f1985c3..9a29853630 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala @@ -9,6 +9,8 @@ import scala.tools.nsc._ import scala.collection.mutable +import org.scalajs.core.ir.Trees.JSNativeLoadSpec + /** Additions to Global meaningful for the JavaScript backend * * @author Sébastien Doeraene @@ -37,6 +39,10 @@ trait JSGlobalAddons extends JSDefinitions private val exportedSymbols = mutable.Map.empty[Symbol, List[ExportInfo]] + /** JS native load specs of the symbols in the current compilation run. */ + private val jsNativeLoadSpecs = + mutable.Map.empty[Symbol, JSNativeLoadSpec] + private val exportPrefix = "$js$exported$" private val methodExportPrefix = exportPrefix + "meth$" private val propExportPrefix = exportPrefix + "prop$" @@ -47,14 +53,16 @@ trait JSGlobalAddons extends JSDefinitions val isNamed: Boolean } + def clearGlobalState(): Unit = { + exportedSymbols.clear() + jsNativeLoadSpecs.clear() + } + private def assertValidForRegistration(sym: Symbol): Unit = { assert(sym.isConstructor || sym.isClass, "Can only register constructors or classes for export") } - def clearRegisteredExports(): Unit = - exportedSymbols.clear() - def registerForExport(sym: Symbol, infos: List[ExportInfo]): Unit = { assert(!exportedSymbols.contains(sym), "Same symbol exported twice") assertValidForRegistration(sym) @@ -146,18 +154,36 @@ trait JSGlobalAddons extends JSDefinitions } } - /** Gets the fully qualified JS name of a static class of module Symbol. - * - * This is the JS name of the symbol qualified by the fully qualified JS - * name of its original owner if the latter is a native JS object. + /** Gets the fully qualified JS name of a static module Symbol compiled + * with the 0.6.8 binary format or earlier. */ - def fullJSNameOf(sym: Symbol): String = { - assert(sym.isClass, s"fullJSNameOf called for non-class symbol $sym") + def compat068FullJSNameOf(sym: Symbol): String = { + assert(sym.isModuleClass, + s"compat068FullJSNameOf called for non-module-class symbol $sym") sym.getAnnotation(JSFullNameAnnotation).flatMap(_.stringArg(0)) getOrElse { jsNameOf(sym) } } + /** Stores the JS native load spec of a symbol for the current compilation + * run. + */ + def storeJSNativeLoadSpec(sym: Symbol, spec: JSNativeLoadSpec): Unit = { + assert(sym.isClass, + s"storeJSNativeLoadSpec called for non-class symbol $sym") + + jsNativeLoadSpecs(sym) = spec + } + + /** Gets the JS native load spec of a symbol in the current compilation run. + */ + def jsNativeLoadSpecOf(sym: Symbol): JSNativeLoadSpec = { + assert(sym.isClass, + s"jsNativeLoadSpecOf called for non-class symbol $sym") + + jsNativeLoadSpecs(sym) + } + } } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 3dde03c9f1..d2d0a45c44 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -11,6 +11,8 @@ import nsc._ import scala.collection.immutable.ListMap import scala.collection.mutable +import org.scalajs.core.ir.Trees.JSNativeLoadSpec + /** Prepares classes extending js.Any for JavaScript interop * * This phase does: @@ -51,7 +53,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent override def description: String = PrepJSInterop.this.description override def run(): Unit = { jsPrimitives.initPrepJSPrimitives() - jsInterop.clearRegisteredExports() + jsInterop.clearGlobalState() super.run() } } @@ -533,33 +535,49 @@ abstract class PrepJSInterop extends plugins.PluginComponent } else if (enclosingOwner is OwnerKind.JSMod) { reporter.error(implDef.pos, "Scala.js-defined JS objects " + "may not have inner native JS classes or objects") - } else if (!sym.isTrait && (enclosingOwner is OwnerKind.JSNativeMod)) { - /* Store the fully qualified JS name in an explicit @JSFullName - * annotation, before `flatten` destroys the name and (in 2.10) the - * original owner chain. + } else if (!sym.isTrait) { + /* Compute the loading spec now, before `flatten` destroys the name + * and (in 2.10) the original owner chain. We store it in a global + * map. */ - val ownerFullJSName = jsInterop.fullJSNameOf(sym.owner) - val jsName = jsInterop.jsNameOf(sym) - val fullJSName = ownerFullJSName + "." + jsName - sym.addAnnotation(JSFullNameAnnotation, - typer.typed(Literal(Constant(fullJSName)))) - } else if (!sym.isTrait && !sym.hasAnnotation(JSNameAnnotation) && - !isJSGlobalScope(implDef)) { - if ((enclosingOwner is OwnerKind.ScalaMod) && - !sym.owner.isPackageObjectClass) { - if (sym.isModuleClass) { - reporter.error(implDef.pos, "Native JS objects inside " + - "non-native objects must have an @JSName annotation") + val loadSpec = { + if (enclosingOwner is OwnerKind.JSNativeMod) { + val ownerLoadSpec = jsInterop.jsNativeLoadSpecOf(sym.owner) + val jsName = jsInterop.jsNameOf(sym) + ownerLoadSpec match { + case JSNativeLoadSpec.Global(path) => + JSNativeLoadSpec.Global(path :+ jsName) + } + } else if (isJSGlobalScope(implDef)) { + JSNativeLoadSpec.Global(Nil) } else { - // This should be an error, but we erroneously allowed that before - reporter.warning(implDef.pos, "Native JS classes inside " + - "non-native objects should have an @JSName annotation. " + - "This will be enforced in 1.0.") + val needsExplicitJSName = { + (enclosingOwner is OwnerKind.ScalaMod) && + !sym.owner.isPackageObjectClass + } + + if (needsExplicitJSName && !sym.hasAnnotation(JSNameAnnotation)) { + if (sym.isModuleClass) { + reporter.error(implDef.pos, "Native JS objects inside " + + "non-native objects must have an @JSName annotation") + } else { + // This should be an error, but we erroneously allowed that before + reporter.warning(implDef.pos, "Native JS classes inside " + + "non-native objects should have an @JSName annotation. " + + "This will be enforced in 1.0.") + } + } + + val path = jsInterop.jsNameOf(sym).split('.').toList + JSNativeLoadSpec.Global(path) } - } else if (sym.owner.isPackageObjectClass) { - sym.addAnnotation(JSFullNameAnnotation, - typer.typed(Literal(Constant(jsInterop.jsNameOf(sym))))) } + + jsInterop.storeJSNativeLoadSpec(sym, loadSpec) + + // Mark module classes as having the new format + if (sym.isModuleClass) + sym.addAnnotation(HasJSNativeLoadSpecAnnotation) } } diff --git a/ir/src/main/scala/org/scalajs/core/ir/ClassKind.scala b/ir/src/main/scala/org/scalajs/core/ir/ClassKind.scala index f431cd6591..2e895212a0 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ClassKind.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ClassKind.scala @@ -24,6 +24,14 @@ sealed abstract class ClassKind { case _ => false } + def isJSType: Boolean = this match { + case AbstractJSType | JSClass | JSModuleClass | NativeJSClass | + NativeJSModuleClass => + true + case _ => + false + } + def hasModuleAccessor: Boolean = this match { case ModuleClass | JSModuleClass => true case _ => false @@ -35,9 +43,10 @@ sealed abstract class ClassKind { } def withoutModuleAccessor: ClassKind = this match { - case ModuleClass => Class - case JSModuleClass => JSClass - case _ => this + case ModuleClass => Class + case JSModuleClass => JSClass + case NativeJSModuleClass => AbstractJSType + case _ => this } } @@ -45,28 +54,34 @@ object ClassKind { case object Class extends ClassKind case object ModuleClass extends ClassKind case object Interface extends ClassKind - case object RawJSType extends ClassKind + case object AbstractJSType extends ClassKind case object HijackedClass extends ClassKind case object JSClass extends ClassKind case object JSModuleClass extends ClassKind + case object NativeJSClass extends ClassKind + case object NativeJSModuleClass extends ClassKind private[ir] def toByte(kind: ClassKind): Byte = kind match { - case ClassKind.Class => 1 - case ClassKind.ModuleClass => 2 - case ClassKind.Interface => 3 - case ClassKind.RawJSType => 4 - case ClassKind.HijackedClass => 5 - case ClassKind.JSClass => 6 - case ClassKind.JSModuleClass => 7 + case ClassKind.Class => 1 + case ClassKind.ModuleClass => 2 + case ClassKind.Interface => 3 + case ClassKind.AbstractJSType => 4 + case ClassKind.HijackedClass => 5 + case ClassKind.JSClass => 6 + case ClassKind.JSModuleClass => 7 + case ClassKind.NativeJSClass => 8 + case ClassKind.NativeJSModuleClass => 9 } private[ir] def fromByte(b: Byte): ClassKind = (b: @switch) match { case 1 => ClassKind.Class case 2 => ClassKind.ModuleClass case 3 => ClassKind.Interface - case 4 => ClassKind.RawJSType + case 4 => ClassKind.AbstractJSType case 5 => ClassKind.HijackedClass case 6 => ClassKind.JSClass case 7 => ClassKind.JSModuleClass + case 8 => ClassKind.NativeJSClass + case 9 => ClassKind.NativeJSModuleClass } } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index 4b9d9077b8..7b0756c714 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -754,16 +754,19 @@ object Printers { // Classes case tree: ClassDef => - val ClassDef(name, kind, superClass, interfaces, jsName, defs) = tree + val ClassDef(name, kind, superClass, interfaces, jsNativeLoadSpec, + defs) = tree print(tree.optimizerHints) kind match { - case ClassKind.Class => print("class ") - case ClassKind.ModuleClass => print("module class ") - case ClassKind.Interface => print("interface ") - case ClassKind.RawJSType => print("jstype ") - case ClassKind.HijackedClass => print("hijacked class ") - case ClassKind.JSClass => print("js class ") - case ClassKind.JSModuleClass => print("js module class ") + case ClassKind.Class => print("class ") + case ClassKind.ModuleClass => print("module class ") + case ClassKind.Interface => print("interface ") + case ClassKind.AbstractJSType => print("abstract js type ") + case ClassKind.HijackedClass => print("hijacked class ") + case ClassKind.JSClass => print("js class ") + case ClassKind.JSModuleClass => print("js module class ") + case ClassKind.NativeJSClass => print("native js class ") + case ClassKind.NativeJSModuleClass => print("native js module class ") } print(name) superClass.foreach { cls => @@ -780,9 +783,9 @@ object Printers { print(", ") } } - jsName.foreach { name => - print(" jsname ") - print(name) + jsNativeLoadSpec.foreach { spec => + print(" loadfrom ") + print(spec.toString) } print(" ") printColumn(defs, "{", "", "}") diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index 63a1ac7958..483826bd5d 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -391,13 +391,14 @@ object Serializers { writeTrees(captureValues) case tree: ClassDef => - val ClassDef(name, kind, superClass, parents, jsName, defs) = tree + val ClassDef(name, kind, superClass, parents, jsNativeLoadSpec, + defs) = tree writeByte(TagClassDef) writeIdent(name) writeByte(ClassKind.toByte(kind)) writeOptIdent(superClass) writeIdents(parents) - writeString(jsName.getOrElse("")) + writeJSNativeLoadSpec(jsNativeLoadSpec) writeTrees(defs) writeInt(tree.optimizerHints.bits) @@ -571,6 +572,20 @@ object Serializers { writeInt(PosDebugMagic) } + def writeJSNativeLoadSpec(jsNativeLoadSpec: Option[JSNativeLoadSpec]): Unit = { + import buffer._ + + jsNativeLoadSpec.fold { + writeByte(TagJSNativeLoadSpecNone) + } { spec => + spec match { + case JSNativeLoadSpec.Global(path) => + writeByte(TagJSNativeLoadSpecGlobal) + writeStrings(path) + } + } + } + def writeOptHash(optHash: Option[TreeHash]): Unit = { buffer.writeBoolean(optHash.isDefined) for (hash <- optHash) { @@ -581,6 +596,11 @@ object Serializers { def writeString(s: String): Unit = buffer.writeInt(stringToIndex(s)) + + def writeStrings(strings: List[String]): Unit = { + buffer.writeInt(strings.size) + strings.foreach(writeString) + } } private final class Deserializer(stream: InputStream, sourceVersion: String) { @@ -589,6 +609,8 @@ object Serializers { Set("0.6.0", "0.6.3", "0.6.4", "0.6.5").contains(sourceVersion) private[this] val useHacks066 = useHacks065 || sourceVersion == "0.6.6" + private[this] val useHacks068 = + useHacks066 || sourceVersion == "0.6.8" private[this] val input = new DataInputStream(stream) @@ -712,10 +734,10 @@ object Serializers { case TagClassDef => val name = readIdent() - val kind = ClassKind.fromByte(readByte()) + val kind0 = ClassKind.fromByte(readByte()) val superClass = readOptIdent() val parents = readIdents() - val jsName = Some(readString()).filter(_ != "") + val jsNativeLoadSpec = readJSNativeLoadSpec() val defs0 = readTrees() val defs = if (useHacks065) { defs0.filter { @@ -728,7 +750,18 @@ object Serializers { defs0 } val optimizerHints = new OptimizerHints(readInt()) - ClassDef(name, kind, superClass, parents, jsName, defs)(optimizerHints) + + val kind = { + if (useHacks068 && kind0 == ClassKind.AbstractJSType && + jsNativeLoadSpec.isDefined) { + ClassKind.NativeJSClass + } else { + kind0 + } + } + + ClassDef(name, kind, superClass, parents, jsNativeLoadSpec, defs)( + optimizerHints) case TagFieldDef => FieldDef(readIdent(), readType(), readBoolean()) @@ -898,6 +931,21 @@ object Serializers { result } + def readJSNativeLoadSpec(): Option[JSNativeLoadSpec] = { + if (useHacks068) { + Some(readString()).filter(_ != "").map { jsFullName => + JSNativeLoadSpec.Global(jsFullName.split("\\.").toList) + } + } else { + (input.readByte(): @switch) match { + case TagJSNativeLoadSpecNone => + None + case TagJSNativeLoadSpecGlobal => + Some(JSNativeLoadSpec.Global(readStrings())) + } + } + } + def readOptHash(): Option[TreeHash] = { if (input.readBoolean()) { val treeHash = new Array[Byte](20) @@ -911,6 +959,9 @@ object Serializers { def readString(): String = { strings(input.readInt()) } + + def readStrings(): List[String] = + List.fill(input.readInt())(readString()) } private class RewriteArgumentsTransformer extends Transformers.Transformer { diff --git a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala index 038e051054..4d719bcdc7 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala @@ -116,4 +116,9 @@ private[ir] object Tags { final val TagRecordType = TagArrayType + 1 final val TagNoType = TagRecordType + 1 + // Tags for JS native loading specs + + final val TagJSNativeLoadSpecNone = 0 + final val TagJSNativeLoadSpecGlobal = TagJSNativeLoadSpecNone + 1 + } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 335cc22099..450caa3582 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -770,7 +770,8 @@ object Trees { // Classes case class ClassDef(name: Ident, kind: ClassKind, superClass: Option[Ident], - interfaces: List[Ident], jsName: Option[String], defs: List[Tree])( + interfaces: List[Ident], jsNativeLoadSpec: Option[JSNativeLoadSpec], + defs: List[Tree])( val optimizerHints: OptimizerHints)( implicit val pos: Position) extends Tree { val tpe = NoType @@ -838,6 +839,38 @@ object Trees { new OptimizerHints(0) } + /** Loading specification for a native JS class or object. */ + sealed abstract class JSNativeLoadSpec + + object JSNativeLoadSpec { + + /** Load from the global scope. + * + * The `path` is a series of nested property names starting from the + * global object. + * + * The path can be empty, in which case this denotes the global object + * itself. + * + * Any element in the path is a property selection from there. A global + * scope loading spec with one path element is therefore a global variable. + * + * Examples: + * {{{ + * // + * Global(None, Nil) + * + * // .Date + * Global(None, List("Date")) + * + * // .cp.Vect + * Global(None, List("cp", "Vect")) + * }}} + */ + final case class Global(path: List[String]) extends JSNativeLoadSpec + + } + /** A hash of a tree (usually a MethodDef). Contains two SHA-1 hashes */ final class TreeHash(val treeHash: Array[Byte], val posHash: Array[Byte]) { assert(treeHash.length == 20) diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala index 1e3bb12838..d14c1a28ac 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala @@ -806,10 +806,10 @@ class PrintersTest { assertPrintEquals( """ - |jstype LTest extends O { + |abstract js type LTest extends O { |} """, - makeForKind(RawJSType)) + makeForKind(AbstractJSType)) assertPrintEquals( """ @@ -831,6 +831,20 @@ class PrintersTest { |} """, makeForKind(JSModuleClass)) + + assertPrintEquals( + """ + |native js class LTest extends O { + |} + """, + makeForKind(NativeJSClass)) + + assertPrintEquals( + """ + |native js module class LTest extends O { + |} + """, + makeForKind(NativeJSModuleClass)) } @Test def printClassDefParents(): Unit = { @@ -862,14 +876,14 @@ class PrintersTest { makeForParents(Some("sr_AbstractFunction0"), List("LIntf1", "LIntf2"))) } - @Test def printClassDefJSName(): Unit = { + @Test def printClassDefJSNativeLoadSpec(): Unit = { assertPrintEquals( """ - |jstype LTest extends O jsname Foo { + |native js class LTest extends O loadfrom Global(List(Foo)) { |} """, - ClassDef("LTest", ClassKind.RawJSType, Some(ObjectClass), Nil, - Some("Foo"), Nil)( + ClassDef("LTest", ClassKind.NativeJSClass, Some(ObjectClass), Nil, + Some(JSNativeLoadSpec.Global(List("Foo"))), Nil)( NoOptHints)) } diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSFullName.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSFullName.scala index 743cd4759f..8005276033 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSFullName.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSFullName.scala @@ -10,7 +10,11 @@ package scala.scalajs.js.annotation /** IMPLEMENTATION DETAIL: Saves the fully qualified JS name of a symbol. + * + * This annotation was used prior to Scala.js 0.6.13. It is only kept for + * backwards binary compatibility, and should not be used anymore. * * Do not use this annotation yourself. */ +@deprecated("Replaced by internal.JSNativeLoadSpec.", "0.6.13") class JSFullName(fullName: String) extends scala.annotation.StaticAnnotation diff --git a/library/src/main/scala/scala/scalajs/js/annotation/internal/HasJSNativeLoadSpec.scala b/library/src/main/scala/scala/scalajs/js/annotation/internal/HasJSNativeLoadSpec.scala new file mode 100644 index 0000000000..10d230b5e0 --- /dev/null +++ b/library/src/main/scala/scala/scalajs/js/annotation/internal/HasJSNativeLoadSpec.scala @@ -0,0 +1,20 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js API ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package scala.scalajs.js.annotation.internal + +/** IMPLEMENTATION DETAIL: Marks this JS native module class as having stored + * a loading spec in its IR. + * + * This is true iff the module class was compiled with Scala.js 0.6.13 or + * later. + * + * Do not use this annotation yourself. + */ +class HasJSNativeLoadSpec extends scala.annotation.StaticAnnotation diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index d83e730c18..2234c477b7 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -3,9 +3,24 @@ import com.typesafe.tools.mima.core.ProblemFilters._ object BinaryIncompatibilities { val IR = Seq( + // Breaking changes + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.ir.Trees#ClassDef.jsName") ) val Tools = Seq( + // Breaking changes + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.LinkedClass.jsName"), + + // private, not an issue + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.analyzer.Analyzer#ClassInfo.isAnyRawJSType"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.analyzer.Analyzer#ClassInfo.isStaticModule"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.checker.IRChecker#CheckedClass.jsName"), + // private[emitter], not an issue ProblemFilters.exclude[MissingMethodProblem]( "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring#JSDesugar.this"), diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala index ee613eeeaa..03c8cfe6d4 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala @@ -39,7 +39,7 @@ final class LinkedClass( val kind: ClassKind, val superClass: Option[Ident], val interfaces: List[Ident], - val jsName: Option[String], + val jsNativeLoadSpec: Option[JSNativeLoadSpec], val fields: List[FieldDef], val staticMethods: List[LinkedMember[MethodDef]], val memberMethods: List[LinkedMember[MethodDef]], @@ -88,7 +88,7 @@ final class LinkedClass( kind: ClassKind = this.kind, superClass: Option[Ident] = this.superClass, interfaces: List[Ident] = this.interfaces, - jsName: Option[String] = this.jsName, + jsNativeLoadSpec: Option[JSNativeLoadSpec] = this.jsNativeLoadSpec, fields: List[FieldDef] = this.fields, staticMethods: List[LinkedMember[MethodDef]] = this.staticMethods, memberMethods: List[LinkedMember[MethodDef]] = this.memberMethods, @@ -108,7 +108,7 @@ final class LinkedClass( kind, superClass, interfaces, - jsName, + jsNativeLoadSpec, fields, staticMethods, memberMethods, @@ -190,7 +190,7 @@ object LinkedClass { classDef.kind, classDef.superClass, classDef.interfaces, - classDef.jsName, + classDef.jsNativeLoadSpec, fields.toList, staticMethods.toList, memberMethods.toList, @@ -217,7 +217,7 @@ object LinkedClass { kind = ClassKind.Class, superClass = Some(Ident(Definitions.ObjectClass)), interfaces = Nil, - jsName = None, + jsNativeLoadSpec = None, fields = Nil, staticMethods = Nil, memberMethods = Nil, diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala index 47cb11d20b..16777f8d2c 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala @@ -181,11 +181,12 @@ private final class Analyzer(semantics: Semantics, val encodedName = data.encodedName val kind = data.kind - val isStaticModule = data.kind.hasModuleAccessor + val isAnyModuleClass = + data.kind.hasModuleAccessor || data.kind == ClassKind.NativeJSModuleClass val isInterface = data.kind == ClassKind.Interface val isScalaClass = data.kind.isClass || data.kind == ClassKind.HijackedClass val isJSClass = data.kind.isJSClass - val isAnyRawJSType = isJSClass || data.kind == ClassKind.RawJSType + val isJSType = data.kind.isJSType val isAnyClass = isScalaClass || isJSClass val isExported = data.isExported @@ -252,6 +253,7 @@ private final class Analyzer(semantics: Semantics, areInstanceTestsUsed || isDataAccessed || isAnySubclassInstantiated || + isModuleAccessed || isAnyStaticMethodReachable || isAnyDefaultMethodReachable @@ -556,7 +558,7 @@ private final class Analyzer(semantics: Semantics, // Myself if (isExported) { - if (isStaticModule) accessModule() + if (isAnyModuleClass) accessModule() else instantiated() } @@ -570,19 +572,37 @@ private final class Analyzer(semantics: Semantics, } def accessModule()(implicit from: From): Unit = { - if (!isStaticModule) { + if (!isAnyModuleClass) { _errors += NotAModule(this, from) } else if (!isModuleAccessed) { isModuleAccessed = true - instantiated() - if (isScalaClass) - callMethod("init___", statically = true) + + if (kind != ClassKind.NativeJSModuleClass) { + instantiated() + if (isScalaClass) + callMethod("init___", statically = true) + } } } def instantiated()(implicit from: From): Unit = { instantiatedFrom ::= from - if (!isInstantiated && (isScalaClass || isAnyRawJSType)) { + + /* TODO Get rid of this when we break binary compatibility. + * Due to the deserialization hacks for the 0.6.8 binary format, we + * might reach this point with `kind == ClassKind.AbstractJSType`, where + * in fact the ClassDef has `kind == ClassKind.NativeJSClass`. If an + * AbstractJSType is `instantiated()` here, we have to assume it is in + * fact a NativeJSClass. + */ + val isNativeJSClass = + kind == ClassKind.NativeJSClass || kind == ClassKind.AbstractJSType + + /* TODO? When the second line is false, shouldn't this be a linking error + * instead? + */ + if (!isInstantiated && + (isScalaClass || isJSClass || isNativeJSClass)) { isInstantiated = true if (isScalaClass) { @@ -592,7 +612,7 @@ private final class Analyzer(semantics: Semantics, for ((methodName, from) <- delayedCalls) delayedCallMethod(methodName)(from) } else { - assert(isAnyRawJSType) + assert(isJSClass || isNativeJSClass) subclassInstantiated() @@ -609,7 +629,7 @@ private final class Analyzer(semantics: Semantics, private def subclassInstantiated()(implicit from: From): Unit = { instantiatedFrom ::= from - if (!isAnySubclassInstantiated && (isScalaClass || isAnyRawJSType)) { + if (!isAnySubclassInstantiated && (isScalaClass || isJSType)) { isAnySubclassInstantiated = true } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala index 16fcc1a21f..036dcca7c8 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala @@ -9,7 +9,7 @@ package org.scalajs.core.tools.linker.backend.emitter -import org.scalajs.core.ir.Trees.FieldDef +import org.scalajs.core.ir.Trees.{FieldDef, JSNativeLoadSpec} private[emitter] trait GlobalKnowledge { /** Tests whether the parent class data is accessed in the linking unit. */ @@ -24,12 +24,13 @@ private[emitter] trait GlobalKnowledge { /** Tests whether the specified class name refers to an `Interface`. */ def isInterface(className: String): Boolean - /** `None` for non-native JS classes; `Some(jsName)` for native JS classes. + /** `None` for non-native JS classes/objects; `Some(spec)` for native JS + * classes/objects. * * It is invalid to call this method with a class that is not a JS class - * (native or not). + * or object (native or not). */ - def getJSClassJSName(className: String): Option[String] + def getJSNativeLoadSpec(className: String): Option[JSNativeLoadSpec] /** The `encodedName` of the superclass of a (non-native) JS class. * diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala index 3ad44fe15a..070321f803 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala @@ -945,13 +945,13 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { allowSideEffects /* LoadJSConstructor is pure only for Scala.js-defined JS classes, - * which do not have a jsName. Note that this test makes sense per se, - * as the actual desugaring of `LoadJSConstructor` is based on the - * jsName of the class. + * which do not have a native load spec. Note that this test makes + * sense per se, as the actual desugaring of `LoadJSConstructor` is + * based on the jsNativeLoadSpec of the class. */ case LoadJSConstructor(cls) => allowUnpure || { - globalKnowledge.getJSClassJSName(cls.className).isEmpty + globalKnowledge.getJSNativeLoadSpec(cls.className).isEmpty } // Non-expressions @@ -1933,7 +1933,15 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { genRawJSClassConstructor(cls.className) case LoadJSModule(cls) => - genLoadModule(cls.className) + val className = cls.className + globalKnowledge.getJSNativeLoadSpec(className) match { + case None => + // this is a Scala.js-defined JS module class + genLoadModule(className) + + case Some(spec) => + genLoadJSFromSpec(spec) + } case JSSpread(items) => assert(outputMode == OutputMode.ECMAScript6) @@ -2253,20 +2261,27 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { pos: Position): js.Tree = { genRawJSClassConstructor(className, - globalKnowledge.getJSClassJSName(className)) + globalKnowledge.getJSNativeLoadSpec(className)) } private[emitter] def genRawJSClassConstructor(className: String, - jsName: Option[String])( + spec: Option[JSNativeLoadSpec])( implicit outputMode: OutputMode, pos: Position): js.Tree = { - jsName match { + spec match { case None => // this is a Scala.js-defined JS class encodeClassVar(className) - case Some(jsName) => - // this is a native JS class - jsName.split("\\.").foldLeft(envField("g")) { + case Some(spec) => + genLoadJSFromSpec(spec) + } + } + + private[emitter] def genLoadJSFromSpec(spec: JSNativeLoadSpec)( + implicit outputMode: OutputMode, pos: Position): js.Tree = { + spec match { + case JSNativeLoadSpec.Global(path) => + path.foldLeft(envField("g")) { (prev, part) => genBracketSelect(prev, js.StringLiteral(part)) } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala index c316319221..34c85d3ab7 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala @@ -12,7 +12,7 @@ package org.scalajs.core.tools.linker.backend.emitter import scala.collection.mutable import org.scalajs.core.ir.ClassKind -import org.scalajs.core.ir.Trees.FieldDef +import org.scalajs.core.ir.Trees.{FieldDef, JSNativeLoadSpec} import org.scalajs.core.tools.linker._ @@ -92,8 +92,8 @@ private[emitter] final class KnowledgeGuardian { def isInterface(className: String): Boolean = classes(className).askIsInterface(this) - def getJSClassJSName(className: String): Option[String] = - classes(className).askJSClassJSName(this) + def getJSNativeLoadSpec(className: String): Option[JSNativeLoadSpec] = + classes(className).askJSNativeLoadSpec(this) def getSuperClassOfJSClass(className: String): String = classes(className).askJSSuperClass(this) @@ -131,12 +131,12 @@ private[emitter] object KnowledgeGuardian { private var isAlive: Boolean = true private var isInterface = computeIsInterface(initClass) - private var jsName = computeJSName(initClass) + private var jsNativeLoadSpec = computeJSNativeLoadSpec(initClass) private var jsSuperClass = computeJSSuperClass(initClass) private var jsClassFieldDefs = computeJSClassFieldDefs(initClass) private val isInterfaceAskers = mutable.Set.empty[Invalidatable] - private val jsNameAskers = mutable.Set.empty[Invalidatable] + private val jsNativeLoadSpecAskers = mutable.Set.empty[Invalidatable] private val jsSuperClassAskers = mutable.Set.empty[Invalidatable] private val jsClassFieldDefsAskers = mutable.Set.empty[Invalidatable] @@ -149,10 +149,10 @@ private[emitter] object KnowledgeGuardian { invalidateAskers(isInterfaceAskers) } - val newJSName = computeJSName(linkedClass) - if (newJSName != jsName) { - jsName = newJSName - invalidateAskers(jsNameAskers) + val newJSNativeLoadSpec = computeJSNativeLoadSpec(linkedClass) + if (newJSNativeLoadSpec != jsNativeLoadSpec) { + jsNativeLoadSpec = newJSNativeLoadSpec + invalidateAskers(jsNativeLoadSpecAskers) } val newJSSuperClass = computeJSSuperClass(linkedClass) @@ -171,8 +171,8 @@ private[emitter] object KnowledgeGuardian { private def computeIsInterface(linkedClass: LinkedClass): Boolean = linkedClass.kind == ClassKind.Interface - private def computeJSName(linkedClass: LinkedClass): Option[String] = - linkedClass.jsName + private def computeJSNativeLoadSpec(linkedClass: LinkedClass): Option[JSNativeLoadSpec] = + linkedClass.jsNativeLoadSpec private def computeJSSuperClass(linkedClass: LinkedClass): String = { linkedClass.kind match { @@ -214,10 +214,10 @@ private[emitter] object KnowledgeGuardian { isInterface } - def askJSClassJSName(invalidatable: Invalidatable): Option[String] = { + def askJSNativeLoadSpec(invalidatable: Invalidatable): Option[JSNativeLoadSpec] = { invalidatable.registeredTo(this) - jsNameAskers += invalidatable - jsName + jsNativeLoadSpecAskers += invalidatable + jsNativeLoadSpec } def askJSSuperClass(invalidatable: Invalidatable): String = { @@ -234,7 +234,7 @@ private[emitter] object KnowledgeGuardian { def unregister(invalidatable: Invalidatable): Unit = { isInterfaceAskers -= invalidatable - jsNameAskers -= invalidatable + jsNativeLoadSpecAskers -= invalidatable jsSuperClassAskers -= invalidatable jsClassFieldDefsAskers -= invalidatable } @@ -242,7 +242,7 @@ private[emitter] object KnowledgeGuardian { /** Call this when we invalidate all caches. */ def unregisterAll(): Unit = { isInterfaceAskers.clear() - jsNameAskers.clear() + jsNativeLoadSpecAskers.clear() jsSuperClassAskers.clear() jsClassFieldDefsAskers.clear() } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala index d18e8e8b30..e7fceb14fe 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala @@ -651,11 +651,11 @@ private[emitter] final class ScalaJSClassEmitter( HijackedBoxedClasses.contains(className) val isAncestorOfHijackedClass = AncestorsOfHijackedClasses.contains(className) - val isRawJSType = - kind == ClassKind.RawJSType || kind.isJSClass + val isJSType = + kind.isJSType val isRawJSTypeParam = - if (isRawJSType) js.BooleanLiteral(true) + if (isJSType) js.BooleanLiteral(true) else js.Undefined() val parentData = if (globalKnowledge.isParentDataAccessed) { @@ -686,16 +686,18 @@ private[emitter] final class ScalaJSClassEmitter( /* java.lang.String and ancestors of hijacked classes have a normal * ScalaJS.is.pack_Class test but with a non-standard behavior. */ (envField("is", className), js.Undefined()) - } else if (isRawJSType) { - /* Raw JS types have an instanceof operator-based isInstanceOf test - * dictated by their jsName. If there is no jsName, the test cannot - * be performed and must throw. - * JS classes have something similar, based on their constructor. + } else if (isJSType) { + /* Native JS classes have an instanceof operator-based isInstanceOf + * test dictated by their jsNativeLoadSpec. + * Non-native JS classes have something similar, based on their + * constructor. + * Other JS types do not have any instanceof operator, so the test + * cannot be performed and must throw. */ - if (tree.jsName.isEmpty && kind != ClassKind.JSClass) { + if (kind != ClassKind.JSClass && kind != ClassKind.NativeJSClass) { (envField("noIsInstance"), js.Undefined()) } else { - val jsCtor = genRawJSClassConstructor(className, tree.jsName) + val jsCtor = genRawJSClassConstructor(className, tree.jsNativeLoadSpec) (js.Function(List(js.ParamDef(Ident("x"), rest = false)), js.Return { js.BinaryOp(JSBinaryOp.instanceof, js.VarRef(Ident("x")), jsCtor) }), js.Undefined()) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index bce76d7d1d..3ae3572709 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -56,9 +56,11 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { def check(): Int = { for (classDef <- unit.classDefs) { implicit val ctx = ErrorContext(classDef) + checkJSNativeLoadSpec(classDef) checkStaticMembers(classDef) classDef.kind match { - case ClassKind.RawJSType => + case ClassKind.AbstractJSType | ClassKind.NativeJSClass | + ClassKind.NativeJSModuleClass => if (classDef.fields.nonEmpty || classDef.memberMethods.nonEmpty || classDef.abstractMethods.nonEmpty || @@ -74,6 +76,24 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { errorCount } + private def checkJSNativeLoadSpec(classDef: LinkedClass): Unit = { + implicit val ctx = ErrorContext(classDef) + + classDef.kind match { + case ClassKind.NativeJSClass | ClassKind.NativeJSModuleClass => + if (classDef.jsNativeLoadSpec.isEmpty) { + reportError( + s"Native JS type ${classDef.name} must have a jsNativeLoadSpec") + } + case _ => + if (classDef.jsNativeLoadSpec.isDefined) { + reportError( + s"Non-native JS type ${classDef.name} must not have a " + + "jsNativeLoadSpec") + } + } + } + private def checkStaticMembers(classDef: LinkedClass): Unit = { for (member <- classDef.staticMethods) { val methodDef = member.tree @@ -89,7 +109,9 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { } private def checkScalaClassDef(classDef: LinkedClass): Unit = { - assert(classDef.kind != ClassKind.RawJSType) + assert(classDef.kind != ClassKind.AbstractJSType && + classDef.kind != ClassKind.NativeJSClass && + classDef.kind != ClassKind.NativeJSModuleClass) // Is this a normal class? if (classDef.kind != ClassKind.HijackedClass && @@ -802,7 +824,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { val valid = clazz.kind match { case ClassKind.JSClass => true case ClassKind.JSModuleClass => true - case ClassKind.RawJSType => clazz.jsName.isDefined + case ClassKind.NativeJSClass => true case _ => false } if (!valid) @@ -810,7 +832,12 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { case LoadJSModule(cls) => val clazz = lookupClass(cls) - if (clazz.kind != ClassKind.JSModuleClass) + val valid = clazz.kind match { + case ClassKind.JSModuleClass => true + case ClassKind.NativeJSModuleClass => true + case _ => false + } + if (!valid) reportError(s"JS module class type expected but $cls found") case JSUnaryOp(op, lhs) => @@ -942,7 +969,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { NullType } else { val kind = tryLookupClass(encodedName).fold(_.kind, _.kind) - if (kind == ClassKind.RawJSType || kind.isJSClass) AnyType + if (kind.isJSType) AnyType else ClassType(encodedName) } } @@ -1064,7 +1091,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { val kind: ClassKind, val superClassName: Option[String], val ancestors: Set[String], - val jsName: Option[String], + val jsNativeLoadSpec: Option[JSNativeLoadSpec], _fields: TraversableOnce[CheckedField])( implicit ctx: ErrorContext) { @@ -1076,7 +1103,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { this(classDef.name.name, classDef.kind, classDef.superClass.map(_.name), classDef.ancestors.toSet, - classDef.jsName, + classDef.jsNativeLoadSpec, if (classDef.kind.isJSClass) Nil else classDef.fields.map(CheckedClass.checkedField)) } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/InfoChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/InfoChecker.scala index 999e266b59..18cfa7afb7 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/InfoChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/InfoChecker.scala @@ -43,9 +43,22 @@ private final class InfoChecker( private def checkClassInfo(info: ClassInfo, expectedInfo: ClassInfo): Unit = { val className = expectedInfo.encodedName + /* Due to the hack for AbstractJSType and NativeJSClass in the + * deserializer, it is possible to get info where `kind == AbstractJSType` + * but `expectedInfo == NativeJSClass`. We need to tolerate that here. + * TODO Get rid of this when we break binary compatibility. + */ + val patchedInfoKind = { + import ClassKind._ + if (info.kind == AbstractJSType && expectedInfo.kind == NativeJSClass) + NativeJSClass + else + info.kind + } + if (info.encodedName != expectedInfo.encodedName || info.isExported != expectedInfo.isExported || - info.kind != expectedInfo.kind || + patchedInfoKind != expectedInfo.kind || info.superClass != expectedInfo.superClass || info.interfaces.toSet != expectedInfo.interfaces.toSet) { errorCount += 1 diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index 629d77b435..1c105554f2 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -295,7 +295,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions kind, classDef.superClass, classDef.interfaces, - classDef.jsName, + classDef.jsNativeLoadSpec, fields.toList, staticMethods.toList, memberMethods.toList, diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala index 2a9f7d5885..eb2755d0cd 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala @@ -151,9 +151,7 @@ abstract class GenIncOptimizer private[optimizer] (semantics: Semantics, getInterface(linkedClass.encodedName).ancestors = linkedClass.ancestors if (linkedClass.hasInstances && - linkedClass.kind != ClassKind.RawJSType && - linkedClass.kind != ClassKind.Interface && - linkedClass.kind != ClassKind.JSClass) { + (linkedClass.kind.isClass || linkedClass.kind == ClassKind.HijackedClass)) { CollOps.put(neededClasses, linkedClass.encodedName, linkedClass) } From e6068253c8d80f4778f22e14ef3fd523b7e96309 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 27 Aug 2016 18:03:35 +0200 Subject: [PATCH 0025/2665] Always default to `persistLauncher in Test := false`. Even when `persistLauncher` is set to `true` for the Compile configuration, it should stay `false` in the `Test` configuration by default. --- .../main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index e4eb3123bd..86dc211d8a 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -834,6 +834,7 @@ object ScalaJSPluginInternal { relativeSourceMaps := false, persistLauncher := false, + persistLauncher in Test := false, emitSourceMaps := true, From ef482bc6f80c211ab730942638b9196c6c8f8fd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 28 Aug 2016 16:49:36 +0200 Subject: [PATCH 0026/2665] Honor `exportsNamespace` in the test interface and the test suite. The testing interface and the test suite had hard-coded that the exports namespace of Scala.js was always the global scope. This commit fixes this by looking up the actual exports namespace in the environment info. --- .../internal/FrameworkLoader.scala | 4 +- .../testinterface/internal/Master.scala | 3 +- .../testinterface/internal/Slave.scala | 3 +- .../compiler/InteroperabilityTest.scala | 15 ++-- .../testsuite/jsinterop/ExportsTest.scala | 71 ++++++++++--------- .../scalajs/testsuite/junit/JUnitUtil.scala | 4 +- .../org/scalajs/testsuite/utils/JSUtils.scala | 6 +- 7 files changed, 61 insertions(+), 45 deletions(-) diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkLoader.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkLoader.scala index 94ccc7c8bf..55c05a9a9b 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkLoader.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkLoader.scala @@ -7,8 +7,10 @@ import sbt.testing.Framework private[internal] object FrameworkLoader { def loadFramework(frameworkName: String): Framework = { + val exportsNamespace = + scala.scalajs.runtime.environmentInfo.exportsNamespace val parts = frameworkName.split('.') - val ctor = parts.foldLeft(js.Dynamic.global)(_.selectDynamic(_)) + val ctor = parts.foldLeft(exportsNamespace)(_.selectDynamic(_)) js.Dynamic.newInstance(ctor)().asInstanceOf[Framework] } diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Master.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/Master.scala index 29e455f2f1..bdf46bb42a 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Master.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/Master.scala @@ -36,7 +36,8 @@ final class Master(frameworkName: String) extends BridgeBase(frameworkName) { private def newRunner(data: js.Dynamic): Try[Unit] = { val args = data.args.asInstanceOf[js.Array[String]].toArray val remoteArgs = data.remoteArgs.asInstanceOf[js.Array[String]].toArray - val loader = new ScalaJSClassLoader(js.Dynamic.global) + val loader = new ScalaJSClassLoader( + scala.scalajs.runtime.environmentInfo.exportsNamespace) Try(runner = framework.runner(args, remoteArgs, loader)) } diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala index 2275181ebb..ee8e2feb05 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala @@ -75,7 +75,8 @@ final class Slave(frameworkName: String, args: js.Array[String], // Message handler methods private def newRunner(): Try[Unit] = { - val loader = new ScalaJSClassLoader(js.Dynamic.global) + val loader = new ScalaJSClassLoader( + scala.scalajs.runtime.environmentInfo.exportsNamespace) Try(runner = framework.slaveRunner(args.toArray, remoteArgs.toArray, loader, outboundRunnerMessage)) } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala index 0985951967..d3540bcc9d 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala @@ -17,6 +17,7 @@ import org.junit.Assert._ import org.junit.Assume._ import org.scalajs.testsuite.utils.AssertThrows._ +import org.scalajs.testsuite.utils.JSUtils import org.scalajs.testsuite.utils.Platform._ /* @@ -439,23 +440,23 @@ class InteroperabilityTest { @Test def should_unbox_Chars_received_from_calling_a_JS_interop_method(): Unit = { val obj = js.eval(""" var obj = { - get: function() { return JSUtils().stringToChar('e'); } + get: function(JSUtils) { return JSUtils.stringToChar('e'); } }; obj; """).asInstanceOf[InteroperabilityTestCharResult] - assertEquals('e'.toInt, obj.get().toInt) + assertEquals('e'.toInt, obj.get(JSUtils).toInt) } @Test def should_box_Chars_given_to_a_JS_interop_method(): Unit = { val obj = js.eval(""" var obj = { - twice: function(c) { c = JSUtils().charToString(c); return c+c; } + twice: function(JSUtils, c) { c = JSUtils.charToString(c); return c+c; } }; obj; """).asInstanceOf[InteroperabilityTestCharParam] - assertEquals("xx", obj.twice('x')) + assertEquals("xx", obj.twice(JSUtils, 'x')) } @Test def should_unbox_value_classes_received_from_calling_a_JS_interop_method(): Unit = { @@ -504,7 +505,7 @@ class InteroperabilityTest { testChar: function() { return 5; }, testInt: function() { return 6.4; }, testShort: function() { return 60000; }, - testDouble: function() { return JSUtils().stringToChar('e'); }, + testDouble: function() { return "hello"; }, testString: function() { return {}; }, testValueClass: function() { return "hello"; }, testNormalClass: function() { return 45; }, @@ -585,12 +586,12 @@ object InteroperabilityTest { @js.native trait InteroperabilityTestCharResult extends js.Object { - def get(): Char = js.native + def get(jsUtils: JSUtils.type): Char = js.native } @js.native trait InteroperabilityTestCharParam extends js.Object { - def twice(c: Char): String = js.native + def twice(jsUtils: JSUtils.type, c: Char): String = js.native } @js.native diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index 7cc71cf80c..c28fa579fe 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -20,10 +20,15 @@ import org.junit.Assert._ import org.junit.Assume._ import org.junit.Test +import org.scalajs.testsuite.utils.JSUtils + class ExportsTest { + /** The namespace in which top-level exports are stored. */ + val exportsNamespace = scala.scalajs.runtime.environmentInfo.exportsNamespace + /** This package in the JS (export) namespace */ - val jsPackage = js.Dynamic.global.org.scalajs.testsuite.jsinterop + val jsPackage = exportsNamespace.org.scalajs.testsuite.jsinterop // @JSExport @@ -604,7 +609,7 @@ class ExportsTest { } @Test def exports_for_objects_with_explicit_name(): Unit = { - val accessor = js.Dynamic.global.TheExportedObject + val accessor = exportsNamespace.TheExportedObject assertJSNotUndefined(accessor) assertEquals("function", js.typeOf(accessor)) val obj = accessor() @@ -614,7 +619,7 @@ class ExportsTest { } @Test def exports_for_Scala_js_defined_JS_objects_with_explicit_name(): Unit = { - val accessor = js.Dynamic.global.TheSJSDefinedExportedObject + val accessor = exportsNamespace.TheSJSDefinedExportedObject assertJSNotUndefined(accessor) assertEquals("function", js.typeOf(accessor)) val obj = accessor() @@ -624,7 +629,7 @@ class ExportsTest { } @Test def exports_for_objects_with_qualified_name(): Unit = { - val accessor = js.Dynamic.global.qualified.testobject.ExportedObject + val accessor = exportsNamespace.qualified.testobject.ExportedObject assertJSNotUndefined(accessor) assertEquals("function", js.typeOf(accessor)) val obj = accessor() @@ -634,7 +639,7 @@ class ExportsTest { } @Test def exports_for_objects_with_constant_folded_name(): Unit = { - val accessor = js.Dynamic.global.ConstantFoldedObjectExport + val accessor = exportsNamespace.ConstantFoldedObjectExport assertJSNotUndefined(accessor) assertEquals("function", js.typeOf(accessor)) val obj = accessor() @@ -671,7 +676,7 @@ class ExportsTest { } @Test def exports_for_classes_with_explicit_name(): Unit = { - val constr = js.Dynamic.global.TheExportedClass + val constr = exportsNamespace.TheExportedClass assertJSNotUndefined(constr) assertEquals("function", js.typeOf(constr)) val obj = js.Dynamic.newInstance(constr)(5) @@ -679,7 +684,7 @@ class ExportsTest { } @Test def exports_for_Scala_js_defined_JS_classes_with_explicit_name(): Unit = { - val constr = js.Dynamic.global.TheSJSDefinedExportedClass + val constr = exportsNamespace.TheSJSDefinedExportedClass assertJSNotUndefined(constr) assertEquals("function", js.typeOf(constr)) val obj = js.Dynamic.newInstance(constr)(5) @@ -688,7 +693,7 @@ class ExportsTest { } @Test def exports_for_classes_with_qualified_name_ExportedClass(): Unit = { - val constr = js.Dynamic.global.qualified.testclass.ExportedClass + val constr = exportsNamespace.qualified.testclass.ExportedClass assertJSNotUndefined(constr) assertEquals("function", js.typeOf(constr)) val obj = js.Dynamic.newInstance(constr)(5) @@ -696,7 +701,7 @@ class ExportsTest { } @Test def exports_for_classes_with_qualified_name_SJSDefinedExportedClass(): Unit = { - val constr = js.Dynamic.global.qualified.testclass.SJSDefinedExportedClass + val constr = exportsNamespace.qualified.testclass.SJSDefinedExportedClass assertJSNotUndefined(constr) assertEquals("function", js.typeOf(constr)) val obj = js.Dynamic.newInstance(constr)(5) @@ -705,7 +710,7 @@ class ExportsTest { } @Test def exports_for_classes_with_constant_folded_name(): Unit = { - val constr = js.Dynamic.global.ConstantFoldedClassExport + val constr = exportsNamespace.ConstantFoldedClassExport assertJSNotUndefined(constr) assertEquals("function", js.typeOf(constr)) val obj = js.Dynamic.newInstance(constr)(5) @@ -768,13 +773,13 @@ class ExportsTest { val funs = js.eval(""" var funs = { - testIsChar: function(foo) { return JSUtils().isChar(foo.bar(65)); }, - testCharValue: function(foo) { return JSUtils().charToString(foo.bar(65)); } + testIsChar: function(JSUtils, foo) { return JSUtils.isChar(foo.bar(65)); }, + testCharValue: function(JSUtils, foo) { return JSUtils.charToString(foo.bar(65)); } }; funs; """).asInstanceOf[js.Dynamic] - assertTrue(funs.testIsChar(foo).asInstanceOf[Boolean]) - assertEquals("A", funs.testCharValue(foo)) + assertTrue(funs.testIsChar(JSUtils, foo).asInstanceOf[Boolean]) + assertEquals("A", funs.testCharValue(JSUtils, foo)) } @Test def should_take_boxed_Chars_as_parameter(): Unit = { @@ -785,11 +790,11 @@ class ExportsTest { val foo = (new Foo).asInstanceOf[js.Dynamic] val f = js.eval(""" - var f = function(foo) { return foo.bar(JSUtils().stringToChar('e')); }; + var f = function(JSUtils, foo) { return foo.bar(JSUtils.stringToChar('e')); }; f; """).asInstanceOf[js.Dynamic] - assertEquals('e'.toInt, f(foo)) + assertEquals('e'.toInt, f(JSUtils, foo)) } @Test def should_be_able_to_disambiguate_an_Int_from_a_Char(): Unit = { @@ -803,12 +808,12 @@ class ExportsTest { val funs = js.eval(""" var funs = { - testChar: function(foo) { return foo.bar(JSUtils().stringToChar('S')); }, + testChar: function(JSUtils, foo) { return foo.bar(JSUtils.stringToChar('S')); }, testInt: function(foo) { return foo.bar(68); } }; funs; """).asInstanceOf[js.Dynamic] - assertEquals("char: S", funs.testChar(foo)) + assertEquals("char: S", funs.testChar(JSUtils, foo)) assertEquals("int: 68", funs.testInt(foo)) } @@ -935,7 +940,7 @@ class ExportsTest { } @Test def exporting_under_org_namespace_issue_364(): Unit = { - val accessor = js.Dynamic.global.org.ExportedUnderOrgObject + val accessor = exportsNamespace.org.ExportedUnderOrgObject assertEquals("function", js.typeOf(accessor)) val obj = accessor() assertSame(ExportedUnderOrgObject.asInstanceOf[js.Any], obj) @@ -1204,7 +1209,7 @@ class ExportsTest { @Test def auto_exports_for_objects_extending_a_trait(): Unit = { val accessor = - js.Dynamic.global.org.scalajs.testsuite.jsinterop.AutoExportedTraitObject + exportsNamespace.org.scalajs.testsuite.jsinterop.AutoExportedTraitObject assertJSNotUndefined(accessor) assertEquals("function", js.typeOf(accessor)) val obj = accessor() @@ -1214,7 +1219,7 @@ class ExportsTest { @Test def auto_exports_for_objects_extending_a_class(): Unit = { val accessor = - js.Dynamic.global.org.scalajs.testsuite.jsinterop.AutoExportedClassObject + exportsNamespace.org.scalajs.testsuite.jsinterop.AutoExportedClassObject assertJSNotUndefined(accessor) assertEquals("function", js.typeOf(accessor)) val obj = accessor() @@ -1224,7 +1229,7 @@ class ExportsTest { @Test def auto_exports_for_Scala_js_defined_JS_objects_extending_a_trait(): Unit = { val accessor = - js.Dynamic.global.org.scalajs.testsuite.jsinterop.SJSDefinedAutoExportedTraitObject + exportsNamespace.org.scalajs.testsuite.jsinterop.SJSDefinedAutoExportedTraitObject assertJSNotUndefined(accessor) assertEquals("function", js.typeOf(accessor)) val obj = accessor() @@ -1234,7 +1239,7 @@ class ExportsTest { @Test def auto_exports_for_Scala_js_defined_JS_objects_extending_a_class(): Unit = { val accessor = - js.Dynamic.global.org.scalajs.testsuite.jsinterop.SJSDefinedAutoExportedClassObject + exportsNamespace.org.scalajs.testsuite.jsinterop.SJSDefinedAutoExportedClassObject assertJSNotUndefined(accessor) assertEquals("function", js.typeOf(accessor)) val obj = accessor() @@ -1244,7 +1249,7 @@ class ExportsTest { @Test def auto_exports_for_objects_extending_a_trait_with_ignoreInvalidDescendants(): Unit = { val accessor = - js.Dynamic.global.org.scalajs.testsuite.jsinterop.AutoExportIgnoreTraitObject + exportsNamespace.org.scalajs.testsuite.jsinterop.AutoExportIgnoreTraitObject assertJSNotUndefined(accessor) assertEquals("function", js.typeOf(accessor)) val obj = accessor() @@ -1254,7 +1259,7 @@ class ExportsTest { @Test def auto_exports_for_objects_extending_a_class_with_ignoreInvalidDescendants(): Unit = { val accessor = - js.Dynamic.global.org.scalajs.testsuite.jsinterop.AutoExportIgnoreClassObject + exportsNamespace.org.scalajs.testsuite.jsinterop.AutoExportIgnoreClassObject assertJSNotUndefined(accessor) assertEquals("function", js.typeOf(accessor)) val obj = accessor() @@ -1264,7 +1269,7 @@ class ExportsTest { @Test def auto_exports_for_Scala_js_defined_JS_objects_extending_a_class_with_ignoreInvalidDescendants(): Unit = { val accessor = - js.Dynamic.global.org.scalajs.testsuite.jsinterop.SJSDefinedAutoExportedIgnoreClassObject + exportsNamespace.org.scalajs.testsuite.jsinterop.SJSDefinedAutoExportedIgnoreClassObject assertJSNotUndefined(accessor) assertEquals("function", js.typeOf(accessor)) val obj = accessor() @@ -1298,7 +1303,7 @@ class ExportsTest { @Test def auto_exports_for_classes_extending_a_trait(): Unit = { val ctor = - js.Dynamic.global.org.scalajs.testsuite.jsinterop.AutoExportedTraitClass + exportsNamespace.org.scalajs.testsuite.jsinterop.AutoExportedTraitClass assertJSNotUndefined(ctor) assertEquals("function", js.typeOf(ctor)) @@ -1313,7 +1318,7 @@ class ExportsTest { @Test def auto_exports_for_classes_extending_a_class(): Unit = { val ctor = - js.Dynamic.global.org.scalajs.testsuite.jsinterop.AutoExportedClassClass + exportsNamespace.org.scalajs.testsuite.jsinterop.AutoExportedClassClass assertJSNotUndefined(ctor) assertEquals("function", js.typeOf(ctor)) @@ -1328,7 +1333,7 @@ class ExportsTest { @Test def auto_exports_for_Scala_js_defined_JS_classes_extending_a_trait(): Unit = { val ctor = - js.Dynamic.global.org.scalajs.testsuite.jsinterop.SJSDefinedAutoExportedTraitClass + exportsNamespace.org.scalajs.testsuite.jsinterop.SJSDefinedAutoExportedTraitClass assertJSNotUndefined(ctor) assertEquals("function", js.typeOf(ctor)) @@ -1340,7 +1345,7 @@ class ExportsTest { @Test def auto_exports_for_Scala_js_defined_JS_classes_extending_a_class(): Unit = { val ctor = - js.Dynamic.global.org.scalajs.testsuite.jsinterop.SJSDefinedAutoExportedClassClass + exportsNamespace.org.scalajs.testsuite.jsinterop.SJSDefinedAutoExportedClassClass assertJSNotUndefined(ctor) assertEquals("function", js.typeOf(ctor)) @@ -1352,7 +1357,7 @@ class ExportsTest { @Test def auto_exports_for_classes_extending_a_trait_with_ignoreInvalidDescendants(): Unit = { val ctor = - js.Dynamic.global.org.scalajs.testsuite.jsinterop.AutoExportIgnoreTraitClass + exportsNamespace.org.scalajs.testsuite.jsinterop.AutoExportIgnoreTraitClass assertJSNotUndefined(ctor) assertEquals("function", js.typeOf(ctor)) @@ -1367,7 +1372,7 @@ class ExportsTest { @Test def auto_exports_for_classes_extending_a_class_with_ignoreInvalidDescendants(): Unit = { val ctor = - js.Dynamic.global.org.scalajs.testsuite.jsinterop.AutoExportIgnoreClassClass + exportsNamespace.org.scalajs.testsuite.jsinterop.AutoExportIgnoreClassClass assertJSNotUndefined(ctor) assertEquals("function", js.typeOf(ctor)) @@ -1382,7 +1387,7 @@ class ExportsTest { @Test def auto_exports_for_Scala_js_defined_JS_classes_extending_a_class_with_ignoreInvalidDescendants(): Unit = { val ctor = - js.Dynamic.global.org.scalajs.testsuite.jsinterop.SJSDefinedAutoExportedIgnoreClassClass + exportsNamespace.org.scalajs.testsuite.jsinterop.SJSDefinedAutoExportedIgnoreClassClass assertJSNotUndefined(ctor) assertEquals("function", js.typeOf(ctor)) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala index c08def3b87..6a6039e405 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala @@ -11,7 +11,9 @@ object JUnitUtil { def loadBootstrapper(classFullName: String): JUnitTestBootstrapper = { val fullName = s"$classFullName$BootstrapperSuffix" try { - fullName.split('.').foldLeft(js.Dynamic.global) { (obj, n) => + val exportsNamespace = + scala.scalajs.runtime.environmentInfo.exportsNamespace + fullName.split('.').foldLeft(exportsNamespace) { (obj, n) => obj.selectDynamic(n) }.apply().asInstanceOf[JUnitTestBootstrapper] } catch { diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/JSUtils.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/JSUtils.scala index 8dcae46733..7c6f95189f 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/JSUtils.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/JSUtils.scala @@ -1,9 +1,10 @@ package org.scalajs.testsuite.utils +import scala.language.implicitConversions + import scala.scalajs.js import js.annotation.JSExport -@JSExport("JSUtils") object JSUtils { /* We use java.lang.Character explicitly, because this class is used by * tests that check that Chars are actually boxed by the compiler. @@ -23,4 +24,7 @@ object JSUtils { @JSExport def charToString(c: Any): String = c.asInstanceOf[java.lang.Character].toString() + + implicit def asJSAny(jsUtils: JSUtils.type): js.Any = + jsUtils.asInstanceOf[js.Any] } From 27a05001ee5bdcd9845dd86a05409f939487bce4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 4 Oct 2016 12:27:52 +0200 Subject: [PATCH 0027/2665] Refactor Linker.apply() with a Config object. Instead of having a long list of parameters with default values, we now use a `Config` object for all optional parameters. This can be evolved in a binary compatible way in the future. --- .../scala/org/scalajs/cli/Scalajsld.scala | 13 ++- .../scala/tools/nsc/MainGenericRunner.scala | 10 ++- project/BinaryIncompatibilities.scala | 4 + .../sbtplugin/ScalaJSPluginInternal.scala | 12 ++- .../linker/LinkerPlatformExtensions.scala | 46 ++++++++-- .../core/tools/test/js/QuickLinker.scala | 6 +- .../linker/LinkerPlatformExtensions.scala | 61 +++++++++---- .../scalajs/core/tools/linker/Linker.scala | 86 ++++++++++++++++++- .../core/tools/linker/LinkerTest.scala | 5 +- 9 files changed, 204 insertions(+), 39 deletions(-) diff --git a/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala b/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala index f413566c82..f87edaa8ef 100644 --- a/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala +++ b/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala @@ -165,10 +165,15 @@ object Scalajsld { .withRelativizeSourceMapBase(options.relativizeSourceMap) .withPrettyPrint(options.prettyPrint) - val linker = Linker(semantics, options.outputMode, options.sourceMap, - disableOptimizer = options.noOpt, parallel = true, - useClosureCompiler = options.fullOpt, - frontendConfig, backendConfig) + val config = Linker.Config() + .withSourceMap(options.sourceMap) + .withOptimizer(!options.noOpt) + .withParallel(true) + .withClosureCompiler(options.fullOpt) + .withFrontendConfig(frontendConfig) + .withBackendConfig(backendConfig) + + val linker = Linker(semantics, options.outputMode, config) val logger = new ScalaConsoleLogger(options.logLevel) val outFile = WritableFileVirtualJSFile(options.output) diff --git a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala index a95a35781f..6cca7257b5 100644 --- a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala +++ b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala @@ -7,8 +7,8 @@ import org.scalajs.core.tools.logging._ import org.scalajs.core.tools.io._ import org.scalajs.core.tools.jsdep.ResolvedJSDependency import org.scalajs.core.tools.io.IRFileCache.IRContainer -import org.scalajs.core.tools.javascript.OutputMode import org.scalajs.core.tools.linker.Linker +import org.scalajs.core.tools.linker.backend.OutputMode import org.scalajs.core.ir @@ -66,8 +66,12 @@ class MainGenericRunner { runnerIR(command.thingToRun, command.arguments) ) - val linker = Linker(semantics, withSourceMap = false, - useClosureCompiler = optMode == FullOpt) + val linkerConfig = Linker.Config() + .withSourceMap(false) + .withClosureCompiler(optMode == FullOpt) + + val linker = Linker(semantics, OutputMode.ECMAScript51Isolated, + linkerConfig) val sjsCode = { val output = WritableMemVirtualJSFile("partest.js") diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 2234c477b7..f6813855af 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -21,6 +21,10 @@ object BinaryIncompatibilities { ProblemFilters.exclude[MissingMethodProblem]( "org.scalajs.core.tools.linker.checker.IRChecker#CheckedClass.jsName"), + // "sealed" trait, not an issue to add methods + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.LinkerPlatformExtensions.apply"), + // private[emitter], not an issue ProblemFilters.exclude[MissingMethodProblem]( "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring#JSDesugar.this"), diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 86dc211d8a..4edc008b57 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -189,10 +189,16 @@ object ScalaJSPluginInternal { .withCustomOutputWrapper(scalaJSOutputWrapper.value) .withPrettyPrint(opts.prettyPrintFullOptJS) + val config = Linker.Config() + .withSourceMap(withSourceMap) + .withOptimizer(!opts.disableOptimizer) + .withParallel(opts.parallel) + .withClosureCompiler(opts.useClosureCompiler) + .withFrontendConfig(frontendConfig) + .withBackendConfig(backendConfig) + val newLinker = { () => - Linker(semantics, outputMode, withSourceMap, opts.disableOptimizer, - opts.parallel, opts.useClosureCompiler, frontendConfig, - backendConfig) + Linker(semantics, outputMode, config) } new ClearableLinker(newLinker, opts.batchMode) diff --git a/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala b/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala index 1f58265d5d..fc5ea4eecf 100644 --- a/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala +++ b/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala @@ -16,6 +16,24 @@ import org.scalajs.core.tools.linker.frontend.optimizer.IncOptimizer import org.scalajs.core.tools.linker.backend._ trait LinkerPlatformExtensions { this: Linker.type => + def apply(semantics: Semantics, outputMode: OutputMode, + config: Config): Linker = { + + val optOptimizerFactory = { + if (!config.optimizer) None + else Some(IncOptimizer.factory) + } + + val frontend = new LinkerFrontend(semantics, outputMode.esLevel, + config.sourceMap, config.frontendConfig, optOptimizerFactory) + + val backend = new BasicLinkerBackend(semantics, outputMode, + config.sourceMap, config.backendConfig) + + new Linker(frontend, backend) + } + + @deprecated("Use the overload with a Config object.", "0.6.13") def apply( semantics: Semantics = Semantics.Defaults, outputMode: OutputMode = OutputMode.Default, @@ -23,14 +41,26 @@ trait LinkerPlatformExtensions { this: Linker.type => disableOptimizer: Boolean = false, frontendConfig: LinkerFrontend.Config = LinkerFrontend.Config(), backendConfig: LinkerBackend.Config = LinkerBackend.Config()): Linker = { - val optOptimizerFactory = - if (disableOptimizer) None - else Some(IncOptimizer.factory) - val frontend = new LinkerFrontend(semantics, outputMode.esLevel, - withSourceMap, frontendConfig, optOptimizerFactory) - val backend = new BasicLinkerBackend(semantics, outputMode, withSourceMap, - backendConfig) - new Linker(frontend, backend) + val config = Config() + .withSourceMap(withSourceMap) + .withOptimizer(!disableOptimizer) + .withFrontendConfig(frontendConfig) + .withBackendConfig(backendConfig) + + apply(semantics, outputMode, config) + } +} + +object LinkerPlatformExtensions { + import Linker.Config + + final class ConfigExt(val config: Config) extends AnyVal { + /** Whether to actually use the Google Closure Compiler pass. + * + * On the JavaScript platform, this always returns `false`, as GCC is not + * available. + */ + def closureCompiler: Boolean = false } } diff --git 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 index 72aea5507f..c950ec936c 100644 --- 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,7 +1,7 @@ package org.scalajs.core.tools.test.js import org.scalajs.core.tools.sem.Semantics -import org.scalajs.core.tools.javascript.OutputMode +import org.scalajs.core.tools.linker.backend.OutputMode import org.scalajs.core.tools.io._ import org.scalajs.core.tools.io.IRFileCache.IRContainer import org.scalajs.core.tools.logging._ @@ -33,7 +33,9 @@ object QuickLinker { def linkNodeInternal(semantics: Semantics, irFilesAndJars: Seq[String]): String = { val cache = (new IRFileCache).newCache - val linker = Linker(semantics) + + val linker = Linker(semantics, OutputMode.ECMAScript51Isolated, + Linker.Config()) val irContainers = irFilesAndJars.map { file => if (file.endsWith(".jar")) { diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala index dc5bd3fbf0..2d01e42ef3 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala @@ -17,37 +17,64 @@ import org.scalajs.core.tools.linker.backend._ import org.scalajs.core.tools.linker.backend.closure.ClosureLinkerBackend trait LinkerPlatformExtensions { this: Linker.type => - def apply( - semantics: Semantics = Semantics.Defaults, - outputMode: OutputMode = OutputMode.Default, - withSourceMap: Boolean = true, - disableOptimizer: Boolean = false, - parallel: Boolean = true, - useClosureCompiler: Boolean = false, - frontendConfig: LinkerFrontend.Config = LinkerFrontend.Config(), - backendConfig: LinkerBackend.Config = LinkerBackend.Config()): Linker = { + def apply(semantics: Semantics, outputMode: OutputMode, + config: Config): Linker = { val optOptimizerFactory = { - if (disableOptimizer) None - else if (parallel) Some(ParIncOptimizer.factory) + if (!config.optimizer) None + else if (config.parallel) Some(ParIncOptimizer.factory) else Some(IncOptimizer.factory) } val frontend = new LinkerFrontend(semantics, outputMode.esLevel, - withSourceMap, frontendConfig, optOptimizerFactory) + config.sourceMap, config.frontendConfig, optOptimizerFactory) val backend = { - if (useClosureCompiler) { + if (config.closureCompiler) { require(outputMode == OutputMode.ECMAScript51Isolated, s"Cannot use output mode $outputMode with the Closure Compiler") - new ClosureLinkerBackend(semantics, - withSourceMap, backendConfig) + new ClosureLinkerBackend(semantics, config.sourceMap, + config.backendConfig) } else { - new BasicLinkerBackend(semantics, outputMode, - withSourceMap, backendConfig) + new BasicLinkerBackend(semantics, outputMode, config.sourceMap, + config.backendConfig) } } new Linker(frontend, backend) } + + @deprecated("Use the overload with a Config object.", "0.6.13") + def apply( + semantics: Semantics = Semantics.Defaults, + outputMode: OutputMode = OutputMode.Default, + withSourceMap: Boolean = true, + disableOptimizer: Boolean = false, + parallel: Boolean = true, + useClosureCompiler: Boolean = false, + frontendConfig: LinkerFrontend.Config = LinkerFrontend.Config(), + backendConfig: LinkerBackend.Config = LinkerBackend.Config()): Linker = { + + val config = Config() + .withSourceMap(withSourceMap) + .withOptimizer(!disableOptimizer) + .withParallel(parallel) + .withClosureCompiler(useClosureCompiler) + .withFrontendConfig(frontendConfig) + .withBackendConfig(backendConfig) + + apply(semantics, outputMode, config) + } +} + +object LinkerPlatformExtensions { + import Linker.Config + + final class ConfigExt(val config: Config) extends AnyVal { + /** Whether to actually use the Google Closure Compiler pass. */ + def closureCompiler: Boolean = config.closureCompilerIfAvailable + + def withClosureCompiler(closureCompiler: Boolean): Config = + config.withClosureCompilerIfAvailable(closureCompiler) + } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala index 242a2d4c73..be5fb27648 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala @@ -9,6 +9,8 @@ package org.scalajs.core.tools.linker +import scala.language.implicitConversions + import java.util.concurrent.atomic.AtomicBoolean import org.scalajs.core.tools.logging.Logger @@ -73,4 +75,86 @@ final class Linker(frontend: LinkerFrontend, backend: LinkerBackend) } } -object Linker extends LinkerPlatformExtensions +object Linker extends LinkerPlatformExtensions { + /** Configuration to be passed to the `apply()` method. */ + final class Config private ( + /** Whether to generate source maps. */ + val sourceMap: Boolean, + /** Whether to use the Scala.js optimizer. */ + val optimizer: Boolean, + /** Whether things that can be parallelized should be parallelized. + * On the JavaScript platform, this does not have any effect. + */ + val parallel: Boolean, + /** Whether to use the Google Closure Compiler pass, if it is available. + * On the JavaScript platform, this does not have any effect. + */ + val closureCompilerIfAvailable: Boolean, + /** Additional configuration for the linker frontend. */ + val frontendConfig: LinkerFrontend.Config, + /** Additional configuration for the linker backend. */ + val backendConfig: LinkerBackend.Config + ) { + def withSourceMap(sourceMap: Boolean): Config = + copy(sourceMap = sourceMap) + + def withOptimizer(optimizer: Boolean): Config = + copy(optimizer = optimizer) + + def withParallel(parallel: Boolean): Config = + copy(parallel = parallel) + + def withClosureCompilerIfAvailable(closureCompilerIfAvailable: Boolean): Config = + copy(closureCompilerIfAvailable = closureCompilerIfAvailable) + + def withFrontendConfig(frontendConfig: LinkerFrontend.Config): Config = + copy(frontendConfig = frontendConfig) + + def withBackendConfig(backendConfig: LinkerBackend.Config): Config = + copy(backendConfig = backendConfig) + + private def copy( + sourceMap: Boolean = sourceMap, + optimizer: Boolean = optimizer, + parallel: Boolean = parallel, + closureCompilerIfAvailable: Boolean = closureCompilerIfAvailable, + frontendConfig: LinkerFrontend.Config = frontendConfig, + backendConfig: LinkerBackend.Config = backendConfig): Config = { + new Config( + sourceMap = sourceMap, + optimizer = optimizer, + parallel = parallel, + closureCompilerIfAvailable = closureCompilerIfAvailable, + frontendConfig = frontendConfig, + backendConfig = backendConfig) + } + } + + object Config { + import LinkerPlatformExtensions._ + + implicit def toPlatformExtensions(config: Config): ConfigExt = + new ConfigExt(config) + + /** Default configuration. + * + * - `sourceMap`: true + * - `optimizer`: true + * - `parallel`: true + * - `closureCompilerIfAvailable`: false + * - `frontendConfig`: default frontend configuration as returned by + * [[org.scalajs.core.tools.linker.frontend.LinkerFrontend.Config.apply]] + * - `backendConfig`: default backend configuration as returned by + * [[org.scalajs.core.tools.linker.backend.LinkerBackend.Config.apply]] + */ + def apply(): Config = { + new Config( + sourceMap = true, + optimizer = true, + parallel = true, + closureCompilerIfAvailable = false, + frontendConfig = LinkerFrontend.Config(), + backendConfig = LinkerBackend.Config()) + } + } +} diff --git a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala index 233f0661e2..967dcfce06 100644 --- a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala +++ b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala @@ -5,6 +5,8 @@ import org.junit.Assert._ import org.scalajs.core.tools.logging.NullLogger import org.scalajs.core.tools.io._ +import org.scalajs.core.tools.sem.Semantics +import org.scalajs.core.tools.linker.backend.OutputMode class LinkerTest { @@ -20,7 +22,8 @@ class LinkerTest { def length: Int = throw new DummyException() } - val linker = Linker() + val linker = Linker(Semantics.Defaults, OutputMode.ECMAScript51Isolated, + Linker.Config()) def callLink(): Unit = linker.link(badSeq, WritableMemVirtualJSFile("some_file"), NullLogger) From 2ac8233d77e7675538a79d224a44d632a108e487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 30 Sep 2016 22:03:54 +0200 Subject: [PATCH 0028/2665] Add `@JSImport` and the generation of CommonJS modules. This is the first and biggest step towards #2175. It contains all the semantic changes to the language and the IR. The only thing that is left is to actually emit ES2015 modules rather than CommonJS modules in the emitter. This commit contains two major changes, which are inherently linked: * An `@JSImport` annotation which can be used on top-level native JS classes and objects to signify that they should be imported from a JavaScript module. * A backend configuration `ModuleKind`, which instructs the emitter to generate a CommonJS module, rather than a script meant to be executed at the top-level of a JS engine. A codebase containing a reachable `@JSImport` cannot be successfully emitted to a top-level script, as there is no universal way of importing things. We could imagine emitting Node.js modules without `@JSImport` support at first, but it would be a bit nonsensical to have modules that cannot import from other modules. When emitting a module, top-level `@JSExport`s become the module exports, obviously. Semantically, `@JSImport` and `@JSExport` are ES2015 module imports and exports. They are therefore static, which means that a) things cannot be conditionally imported or exported and b) their "key" must be a compile-time string constant. The `ModuleKind` can be specified in sbt with the new key `scalaJSModuleKind`, which is scoped per project and per configuration, but not per stage. Indeed, they specify the interface with the outside JavaScript world, and that should not change in fastOpt versus fullOpt. Obviously, setting `scalaJSModuleKind` to `CommonJSModule` requires Node.js to be used for `run` and `test` tasks. The historical fact that the `scalaJSLauncher` is stage-independent unfortunately makes `packageJSLauncher` incompatible with a `scalaJSModuleKind` different from `NoModule`. This is because, with modules, the contents of the launcher must reference the module ID, which is different in fastOpt and fullOpt. In the future, we will extend `ModuleKind` with a new kind for actual ECMAScript 2015 modules. --- ci/matrix.xml | 16 +- .../scala/org/scalajs/cli/Scalajsld.scala | 17 +- .../scalajs/core/compiler/JSDefinitions.scala | 3 + .../scalajs/core/compiler/PrepJSInterop.scala | 94 ++++++++- .../core/compiler/test/JSInteropTest.scala | 188 +++++++++++++++++- .../org/scalajs/core/ir/Serializers.scala | 7 + .../main/scala/org/scalajs/core/ir/Tags.scala | 1 + .../scala/org/scalajs/core/ir/Trees.scala | 32 +++ .../org/scalajs/core/ir/PrintersTest.scala | 9 + .../scalajs/jsenv/rhino/ScalaJSCoreLib.scala | 4 +- .../scalajs/js/annotation/JSImport.scala | 60 ++++++ .../scala/tools/nsc/MainGenericRunner.scala | 4 +- project/BinaryIncompatibilities.scala | 17 +- project/Build.scala | 15 +- .../scalajs/sbtplugin/FrameworkDetector.scala | 59 +++--- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 8 +- .../sbtplugin/ScalaJSPluginInternal.scala | 143 ++++++++++--- .../sbttestadapter/ScalaJSFramework.scala | 28 ++- .../sbttestadapter/ScalaJSRunner.scala | 6 +- .../testsuite/jsinterop/ModulesTest.scala | 120 +++++++++++ .../linker/LinkerPlatformExtensions.scala | 6 +- .../core/tools/test/js/QuickLinker.scala | 4 +- .../linker/LinkerPlatformExtensions.scala | 12 +- .../closure/ClosureLinkerBackend.scala | 18 +- tools/scalajsenv.js | 10 + .../linker/backend/BasicLinkerBackend.scala | 13 +- .../tools/linker/backend/LinkerBackend.scala | 7 + .../tools/linker/backend/ModuleKind.scala | 43 ++++ .../linker/backend/emitter/CoreJSLibs.scala | 22 +- .../linker/backend/emitter/Emitter.scala | 84 ++++++-- .../linker/backend/emitter/JSDesugaring.scala | 64 +++++- .../core/tools/linker/LinkerTest.scala | 4 +- 32 files changed, 991 insertions(+), 127 deletions(-) create mode 100644 library/src/main/scala/scala/scalajs/js/annotation/JSImport.scala create mode 100644 test-suite/js/src/test/require-modules/org/scalajs/testsuite/jsinterop/ModulesTest.scala create mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/ModuleKind.scala diff --git a/ci/matrix.xml b/ci/matrix.xml index d9a3340485..ce19bf8658 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -130,6 +130,11 @@ sbtretry 'set scalacOptions in $testSuite += "-Xexperimental"' \ ++$scala $testSuite/test && sbtretry 'set scalacOptions in $testSuite += "-Xexperimental"' \ + 'set scalaJSStage in Global := FullOptStage' \ + ++$scala $testSuite/test && + sbtretry 'set scalaJSModuleKind in $testSuite := ModuleKind.CommonJSModule' \ + ++$scala $testSuite/test && + sbtretry 'set scalaJSModuleKind in $testSuite := ModuleKind.CommonJSModule' \ 'set scalaJSStage in Global := FullOptStage' \ ++$scala $testSuite/test ]]> @@ -170,7 +175,16 @@ 'set scalaJSStage in Global := FullOptStage' \ 'set scalaJSOptimizerOptions in $testSuite ~= (_.withDisableOptimizer(true))' \ ++$scala $testSuite/test \ - $testSuite/clean + $testSuite/clean && + sbtretry 'set scalaJSOutputMode in $testSuite := org.scalajs.core.tools.linker.backend.OutputMode.ECMAScript6' \ + 'set jsEnv in $testSuite := NodeJSEnv(args = ES6NodeArgs).value.withSourceMap(false)' \ + 'set scalaJSModuleKind in $testSuite := ModuleKind.CommonJSModule' \ + ++$scala $testSuite/test && + sbtretry 'set scalaJSOutputMode in $testSuite := org.scalajs.core.tools.linker.backend.OutputMode.ECMAScript6' \ + 'set jsEnv in $testSuite := NodeJSEnv(args = ES6NodeArgs).value.withSourceMap(false)' \ + 'set scalaJSModuleKind in $testSuite := ModuleKind.CommonJSModule' \ + 'set scalaJSStage in Global := FullOptStage' \ + ++$scala $testSuite/test ]]> + ModuleKind.All.find(_.toString() == s).getOrElse( + throw new IllegalArgumentException(s"$s is not a valid module kind")) + } + } + def main(args: Array[String]): Unit = { val parser = new scopt.OptionParser[Options]("scalajsld") { head("scalajsld", ScalaJSVersions.current) @@ -93,6 +102,9 @@ object Scalajsld { opt[OutputMode]('m', "outputMode") .action { (mode, c) => c.copy(outputMode = mode) } .text("Output mode " + OutputMode.All.mkString("(", ", ", ")")) + opt[ModuleKind]('k', "moduleKind") + .action { (kind, c) => c.copy(moduleKind = kind) } + .text("Module kind " + ModuleKind.All.mkString("(", ", ", ")")) opt[Unit]('b', "bypassLinkingErrors") .action { (_, c) => c.copy(bypassLinkingErrors = true) } .text("Only warn if there are linking errors (deprecated)") @@ -173,7 +185,8 @@ object Scalajsld { .withFrontendConfig(frontendConfig) .withBackendConfig(backendConfig) - val linker = Linker(semantics, options.outputMode, config) + val linker = Linker(semantics, options.outputMode, options.moduleKind, + config) val logger = new ScalaConsoleLogger(options.logLevel) val outFile = WritableFileVirtualJSFile(options.output) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 30285b16e7..436d620bee 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -63,12 +63,15 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val JSExportDescendentClassesAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportDescendentClasses") lazy val JSExportAllAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportAll") lazy val JSExportNamedAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportNamed") + lazy val JSImportAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSImport") lazy val ScalaJSDefinedAnnotation = getRequiredClass("scala.scalajs.js.annotation.ScalaJSDefined") lazy val SJSDefinedAnonymousClassAnnotation = getRequiredClass("scala.scalajs.js.annotation.SJSDefinedAnonymousClass") lazy val HasJSNativeLoadSpecAnnotation = getRequiredClass("scala.scalajs.js.annotation.internal.HasJSNativeLoadSpec") lazy val JavaDefaultMethodAnnotation = getRequiredClass("scala.scalajs.js.annotation.JavaDefaultMethod") + lazy val JSImportNamespaceObject = getRequiredModule("scala.scalajs.js.annotation.JSImport.Namespace") + lazy val JSAnyTpe = JSAnyClass.toTypeConstructor lazy val JSObjectTpe = JSObjectClass.toTypeConstructor diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index d2d0a45c44..353d776d35 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -183,6 +183,8 @@ abstract class PrepJSInterop extends plugins.PluginComponent if (sym.hasAnnotation(JSNativeAnnotation)) reportJSNativeOnNonJSAny(idef.pos, "Classes and objects") + else if (sym.hasAnnotation(JSImportAnnotation)) + reportJSImportOnNonJSNative(idef.pos) val kind = if (idef.isInstanceOf[ModuleDef]) OwnerKind.EnumMod @@ -195,6 +197,8 @@ abstract class PrepJSInterop extends plugins.PluginComponent if (sym.hasAnnotation(JSNativeAnnotation)) reportJSNativeOnNonJSAny(cldef.pos, "Traits and classes") + else if (sym.hasAnnotation(JSImportAnnotation)) + reportJSImportOnNonJSNative(cldef.pos) if (sym == UndefOrClass || sym == UnionClass) sym.addAnnotation(RawJSTypeAnnot) @@ -215,6 +219,8 @@ abstract class PrepJSInterop extends plugins.PluginComponent if (sym.hasAnnotation(JSNativeAnnotation)) reportJSNativeOnNonJSAny(modDef.pos, "Objects") + else if (sym.hasAnnotation(JSImportAnnotation)) + reportJSImportOnNonJSNative(modDef.pos) if (shouldPrepareExports) registerModuleExports(sym.moduleClass) @@ -521,6 +527,15 @@ abstract class PrepJSInterop extends plugins.PluginComponent s"A Scala.js-defined JS $strKind cannot directly extend a "+ "native JS trait.") } + + // Check that there is no @JSImport annotation + if (sym.hasAnnotation(JSImportAnnotation)) + reportJSImportOnNonJSNative(implDef.pos) + } + + if (shouldCheckLiterals) { + checkJSNameLiteral(sym) + checkJSImportLiteral(sym) } // Checks for native JS stuff, excluding JS anon functions @@ -547,9 +562,22 @@ abstract class PrepJSInterop extends plugins.PluginComponent ownerLoadSpec match { case JSNativeLoadSpec.Global(path) => JSNativeLoadSpec.Global(path :+ jsName) + case JSNativeLoadSpec.Import(module, path) => + JSNativeLoadSpec.Import(module, path :+ jsName) } } else if (isJSGlobalScope(implDef)) { JSNativeLoadSpec.Global(Nil) + } else if (sym.hasAnnotation(JSImportAnnotation)) { + val annot = sym.getAnnotation(JSImportAnnotation).get + val module = annot.stringArg(0).getOrElse { + "" // do not care because it does not compile anyway + } + annot.stringArg(1).fold { + JSNativeLoadSpec.Import(module, Nil) + } { pathName => + val path = pathName.split('.').toList + JSNativeLoadSpec.Import(module, path) + } } else { val needsExplicitJSName = { (enclosingOwner is OwnerKind.ScalaMod) && @@ -558,12 +586,14 @@ abstract class PrepJSInterop extends plugins.PluginComponent if (needsExplicitJSName && !sym.hasAnnotation(JSNameAnnotation)) { if (sym.isModuleClass) { - reporter.error(implDef.pos, "Native JS objects inside " + - "non-native objects must have an @JSName annotation") + reporter.error(implDef.pos, + "Native JS objects inside non-native objects must " + + "have an @JSName or @JSImport annotation") } else { // This should be an error, but we erroneously allowed that before - reporter.warning(implDef.pos, "Native JS classes inside " + - "non-native objects should have an @JSName annotation. " + + reporter.warning(implDef.pos, + "Native JS classes inside non-native objects should " + + "have an @JSName or @JSImport annotation. " + "This will be enforced in 1.0.") } } @@ -578,6 +608,12 @@ abstract class PrepJSInterop extends plugins.PluginComponent // Mark module classes as having the new format if (sym.isModuleClass) sym.addAnnotation(HasJSNativeLoadSpecAnnotation) + } else { + assert(sym.isTrait) // just tested in the previous `if` + if (sym.hasAnnotation(JSImportAnnotation)) { + reporter.error(implDef.pos, + "Traits may not have an @JSImport annotation") + } } } @@ -591,6 +627,10 @@ abstract class PrepJSInterop extends plugins.PluginComponent reporter.warning(implDef.pos, "Objects extending js.GlobalScope " + "should not have a @JSName annotation. This will be enforced " + "in 1.0.") + } else if (sym.hasAnnotation(JSImportAnnotation)) { + reporter.error(implDef.pos, + "Objects extending js.GlobalScope cannot have an @JSImport " + + "annotation.") } } @@ -620,9 +660,6 @@ abstract class PrepJSInterop extends plugins.PluginComponent } } - if (shouldCheckLiterals) - checkJSNameLiteral(sym) - // Check for overrides with different JS names - issue #1983 for (overridingPair <- new overridingPairs.Cursor(sym).iterator) { val low = overridingPair.low @@ -756,6 +793,11 @@ abstract class PrepJSInterop extends plugins.PluginComponent reporter.error(tree.pos, "Methods in a js.Any may not be @native") } + if (sym.hasAnnotation(JSImportAnnotation)) { + reporter.error(tree.pos, + "Methods and fields cannot be annotated with @JSImport.") + } + if (shouldCheckLiterals) checkJSNameLiteral(sym) @@ -918,6 +960,38 @@ abstract class PrepJSInterop extends plugins.PluginComponent } } + /** Checks that arguments to `@JSImport` on [[sym]] are literals. + * + * The second argument can also be the singleton `JSImport.Namespace` + * object. + * + * Reports an error on each annotation where this is not the case. + */ + private def checkJSImportLiteral(sym: Symbol): Unit = { + for { + annot <- sym.getAnnotation(JSImportAnnotation) + } { + assert(annot.args.size == 2, + s"@JSImport annotation $annot does not have exactly 2 arguments") + + val firstArgIsValid = annot.stringArg(0).isDefined + if (!firstArgIsValid) { + reporter.error(annot.args(0).pos, + "The first argument to @JSImport must be a literal string.") + } + + val secondArgIsValid = { + annot.stringArg(1).isDefined || + annot.args(1).symbol == JSImportNamespaceObject + } + if (!secondArgIsValid) { + reporter.error(annot.args(1).pos, + "The second argument to @JSImport must be literal string or the " + + "JSImport.Namespace object.") + } + } + } + private trait ScalaEnumFctExtractors { protected val methSym: Symbol @@ -1019,6 +1093,12 @@ abstract class PrepJSInterop extends plugins.PluginComponent "@js.native annotation") } + private def reportJSImportOnNonJSNative(pos: Position): Unit = { + reporter.error(pos, + s"Non JS-native classes, traits and objects may not have an " + + "@JSImport annotation") + } + private lazy val ScalaEnumClass = getRequiredClass("scala.Enumeration") private lazy val WasPublicBeforeTyperClass = getRequiredClass("scala.scalajs.js.annotation.WasPublicBeforeTyper") diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index 150ced2e6a..f3d0b6cbdd 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -67,6 +67,56 @@ class JSInteropTest extends DirectTest with TestHelpers { } + @Test + def noJSImportAnnotOnNonJSNative: Unit = { + + for { + obj <- Seq("class", "trait", "object") + } yield { + s""" + @ScalaJSDefined + @JSImport("foo", JSImport.Namespace) + $obj A extends js.Object + """ hasErrors + s""" + |newSource1.scala:7: error: Non JS-native classes, traits and objects may not have an @JSImport annotation + | $obj A extends js.Object + | ${" " * obj.length} ^ + """ + } + + for { + obj <- Seq("class", "trait", "object") + } yield { + s""" + @JSImport("foo", JSImport.Namespace) + $obj A + """ hasErrors + s""" + |newSource1.scala:6: error: Non JS-native classes, traits and objects may not have an @JSImport annotation + | $obj A + | ${" " * obj.length} ^ + """ + } + + } + + @Test + def noJSImportAnnotOnTrait: Unit = { + + s""" + @js.native + @JSImport("foo", JSImport.Namespace) + trait A extends js.Object + """ hasErrors + s""" + |newSource1.scala:7: error: Traits may not have an @JSImport annotation + | trait A extends js.Object + | ^ + """ + + } + @Test def noJSNativeAnnotWithoutJSAny: Unit = { @@ -437,6 +487,22 @@ class JSInteropTest extends DirectTest with TestHelpers { } + @Test + def noJSImportOnJSGlobalScope: Unit = { + + """ + @js.native + @JSImport("foo", JSImport.Namespace) + object Bar extends js.GlobalScope + """ hasErrors + """ + |newSource1.scala:7: error: Objects extending js.GlobalScope cannot have an @JSImport annotation. + | object Bar extends js.GlobalScope + | ^ + """ + + } + @Test def noLocalClass: Unit = { @@ -600,7 +666,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } """ hasWarns """ - |newSource1.scala:7: warning: Native JS classes inside non-native objects should have an @JSName annotation. This will be enforced in 1.0. + |newSource1.scala:7: warning: Native JS classes inside non-native objects should have an @JSName or @JSImport annotation. This will be enforced in 1.0. | class B extends js.Object | ^ """ @@ -612,7 +678,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Native JS objects inside non-native objects must have an @JSName annotation + |newSource1.scala:7: error: Native JS objects inside non-native objects must have an @JSName or @JSImport annotation | object B extends js.Object | ^ """ @@ -643,6 +709,17 @@ class JSInteropTest extends DirectTest with TestHelpers { } """.hasNoWarns + """ + object A { + @JSImport("InnerB", JSImport.Namespace) + @js.native + class B extends js.Object + @JSImport("InnerC", JSImport.Namespace) + @js.native + object C extends js.Object + } + """.hasNoWarns + """ object A { @js.native @@ -750,6 +827,113 @@ class JSInteropTest extends DirectTest with TestHelpers { } + @Test + def noJSImportOnMembers: Unit = { + + """ + @js.native + class Foo extends js.Object { + @JSImport("bar1", JSImport.Namespace) + val bar1: Int = js.native + @JSImport("bar2", JSImport.Namespace) + var bar2: Int = js.native + @JSImport("bar3", JSImport.Namespace) + def bar3: Int = js.native + + @js.native + @JSImport("Inner", JSImport.Namespace) + class Inner extends js.Object + + @js.native + @JSImport("Inner", JSImport.Namespace) + object Inner extends js.Object + } + """ hasErrors + """ + |newSource1.scala:8: error: Methods and fields cannot be annotated with @JSImport. + | val bar1: Int = js.native + | ^ + |newSource1.scala:10: error: Methods and fields cannot be annotated with @JSImport. + | var bar2: Int = js.native + | ^ + |newSource1.scala:12: error: Methods and fields cannot be annotated with @JSImport. + | def bar3: Int = js.native + | ^ + |newSource1.scala:16: error: Native JS traits and classes may not have inner traits, classes or objects + | class Inner extends js.Object + | ^ + |newSource1.scala:20: error: Native JS traits and classes may not have inner traits, classes or objects + | object Inner extends js.Object + | ^ + """ + + } + + @Test + def noNonLiteralJSImport: Unit = { + + """ + object A { + val a = "Hello" + } + + @JSImport(A.a, JSImport.Namespace) + @js.native + object B1 extends js.Object + + @JSImport(A.a, "B2") + @js.native + object B2 extends js.Object + + @JSImport("B3", A.a) + @js.native + object B3 extends js.Object + + @JSImport(A.a, JSImport.Namespace) + @js.native + object C1 extends js.Object + + @JSImport(A.a, "C2") + @js.native + object C2 extends js.Object + + @JSImport("C3", A.a) + @js.native + object C3 extends js.Object + + @JSImport(A.a, A.a) + @js.native + object D extends js.Object + """ hasErrors + """ + |newSource1.scala:9: error: The first argument to @JSImport must be a literal string. + | @JSImport(A.a, JSImport.Namespace) + | ^ + |newSource1.scala:13: error: The first argument to @JSImport must be a literal string. + | @JSImport(A.a, "B2") + | ^ + |newSource1.scala:17: error: The second argument to @JSImport must be literal string or the JSImport.Namespace object. + | @JSImport("B3", A.a) + | ^ + |newSource1.scala:21: error: The first argument to @JSImport must be a literal string. + | @JSImport(A.a, JSImport.Namespace) + | ^ + |newSource1.scala:25: error: The first argument to @JSImport must be a literal string. + | @JSImport(A.a, "C2") + | ^ + |newSource1.scala:29: error: The second argument to @JSImport must be literal string or the JSImport.Namespace object. + | @JSImport("C3", A.a) + | ^ + |newSource1.scala:33: error: The first argument to @JSImport must be a literal string. + | @JSImport(A.a, A.a) + | ^ + |newSource1.scala:33: error: The second argument to @JSImport must be literal string or the JSImport.Namespace object. + | @JSImport(A.a, A.a) + | ^ + """ + + } + @Test def noApplyProperty: Unit = { diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index 483826bd5d..52e4eddae8 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -582,6 +582,11 @@ object Serializers { case JSNativeLoadSpec.Global(path) => writeByte(TagJSNativeLoadSpecGlobal) writeStrings(path) + + case JSNativeLoadSpec.Import(module, path) => + writeByte(TagJSNativeLoadSpecImport) + writeString(module) + writeStrings(path) } } } @@ -942,6 +947,8 @@ object Serializers { None case TagJSNativeLoadSpecGlobal => Some(JSNativeLoadSpec.Global(readStrings())) + case TagJSNativeLoadSpecImport => + Some(JSNativeLoadSpec.Import(readString(), readStrings())) } } } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala index 4d719bcdc7..a75f626b50 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala @@ -120,5 +120,6 @@ private[ir] object Tags { final val TagJSNativeLoadSpecNone = 0 final val TagJSNativeLoadSpecGlobal = TagJSNativeLoadSpecNone + 1 + final val TagJSNativeLoadSpecImport = TagJSNativeLoadSpecGlobal + 1 } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 450caa3582..67e302fe3d 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -869,6 +869,38 @@ object Trees { */ final case class Global(path: List[String]) extends JSNativeLoadSpec + /** Load from a module import. + * + * The `module` is the ES module identifier. The `path` is a series of + * nested property names starting from the module object. + * + * The path can be empty, in which case the specification denotes the + * namespace import, i.e., import a special object whose fields are all + * the exports of the module. + * + * Any element in the path is a property selection from there. A module + * import info with one path element is importing that particular value + * from the module. + * + * Examples: + * {{{ + * // import { Bar as x } from 'foo' + * Import("foo", List("Bar")) + * + * // import { Bar as y } from 'foo' + * // y.Baz + * Import("foo", List("Bar", "Baz")) + * + * // import * as x from 'foo' (namespace import) + * Import("foo", Nil) + * + * // import x from 'foo' (default import) + * Import("foo", List("default")) + * }}} + */ + final case class Import(module: String, path: List[String]) + extends JSNativeLoadSpec + } /** A hash of a tree (usually a MethodDef). Contains two SHA-1 hashes */ diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala index d14c1a28ac..655242570f 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala @@ -885,6 +885,15 @@ class PrintersTest { ClassDef("LTest", ClassKind.NativeJSClass, Some(ObjectClass), Nil, Some(JSNativeLoadSpec.Global(List("Foo"))), Nil)( NoOptHints)) + + assertPrintEquals( + """ + |native js class LTest extends O loadfrom Import(foo,List(Bar)) { + |} + """, + ClassDef("LTest", ClassKind.NativeJSClass, Some(ObjectClass), Nil, + Some(JSNativeLoadSpec.Import("foo", List("Bar"))), Nil)( + NoOptHints)) } @Test def printClassDefOptimizerHints(): Unit = { diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala index 725d08c971..ac059af571 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala @@ -20,6 +20,7 @@ import org.scalajs.core.tools.linker.{LinkedClass, LinkingUnit} import org.scalajs.core.tools.javascript._ import org.scalajs.core.tools.io._ +import org.scalajs.core.tools.linker.backend.ModuleKind.NoModule import org.scalajs.core.tools.linker.backend.OutputMode.ECMAScript51Global import org.scalajs.core.tools.linker.backend.emitter._ @@ -28,7 +29,8 @@ private[rhino] class ScalaJSCoreLib(linkingUnit: LinkingUnit) { require(linkingUnit.esLevel == ESLevel.ES5, "RhinoJSEnv only supports ES5") - private val emitter = new Emitter(linkingUnit.semantics, ECMAScript51Global) + private val emitter = + new Emitter(linkingUnit.semantics, ECMAScript51Global, NoModule) emitter.rhinoAPI.initialize(linkingUnit) diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSImport.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSImport.scala new file mode 100644 index 0000000000..42d46a2c2d --- /dev/null +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSImport.scala @@ -0,0 +1,60 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js API ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package scala.scalajs.js.annotation + +/** Marks the annotated class or object as imported from another JS module. + * + * Intuitively, this corresponds to the following ECMAScript import + * directive: + * {{{ + * import { as AnnotatedClassOrObject } from + * }}} + * + * To import the default export of a module, use `JSImport.Default` as `name`. + * + * `@JSImport` is not compatible with the `jsDependencies` mechanism offered + * by the Scala.js sbt plugin. You are responsible for resolving and/or + * bundling the JavaScript modules that you are importing using other + * mechanisms. + */ +class JSImport(module: String, name: String) + extends scala.annotation.StaticAnnotation { + + /** Namespace import (import the module itself). + * + * The second parameter should be the singleton `JSImport.Namespace`. + * + * Intuitively, this corresponds to + * {{{ + * import * as AnnotatedObject from + * }}} + */ + def this(module: String, name: JSImport.Namespace.type) = + this(module, null: String) +} + +object JSImport { + /** Use as the `name` of a `JSImport` to use the default import. + * + * The actual value of this constant, the string `"default"`, is not + * arbitrary. It is the name under which a default export is registered in + * the ECMAScript 2015 specification. + */ + final val Default = "default" + + /** Use as the `name` of a `JSImport` to use a namespace import. + * + * Intuitively, it corresponds to `*` in an ECMAScript import: + * {{{ + * import * as AnnotatedObject from + * }}} + */ + object Namespace +} diff --git a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala index 6cca7257b5..2b06fe362f 100644 --- a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala +++ b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala @@ -8,7 +8,7 @@ import org.scalajs.core.tools.io._ import org.scalajs.core.tools.jsdep.ResolvedJSDependency import org.scalajs.core.tools.io.IRFileCache.IRContainer import org.scalajs.core.tools.linker.Linker -import org.scalajs.core.tools.linker.backend.OutputMode +import org.scalajs.core.tools.linker.backend.{OutputMode, ModuleKind} import org.scalajs.core.ir @@ -71,7 +71,7 @@ class MainGenericRunner { .withClosureCompiler(optMode == FullOpt) val linker = Linker(semantics, OutputMode.ECMAScript51Isolated, - linkerConfig) + ModuleKind.NoModule, linkerConfig) val sjsCode = { val output = WritableMemVirtualJSFile("partest.js") diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index f6813855af..0ee477b3a1 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -69,7 +69,11 @@ object BinaryIncompatibilities { ProblemFilters.exclude[MissingMethodProblem]( "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genExportedMembers"), ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genStaticMembers") + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genStaticMembers"), + + // private[emitter], not an issue + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.CoreJSLibs.lib") ) val JSEnvs = Seq( @@ -80,6 +84,8 @@ object BinaryIncompatibilities { val SbtPlugin = Seq( // private[sbtplugin], not an issue + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.sbtplugin.FrameworkDetector.this"), ProblemFilters.exclude[MissingMethodProblem]( "org.scalajs.sbtplugin.FrameworkDetector.detect") ) @@ -88,6 +94,15 @@ object BinaryIncompatibilities { ) val CLI = Seq( + // private, not an issue + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.cli.Scalajsld#Options.this"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.cli.Scalajsld#Options.copy"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.cli.Scalajsld#Options.apply"), + ProblemFilters.exclude[MissingTypesProblem]( + "org.scalajs.cli.Scalajsld$Options$") ) val Library = Seq( diff --git a/project/Build.scala b/project/Build.scala index 00daa36170..c0c4a22e1b 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -85,6 +85,10 @@ object Build { // set postLinkJSEnv in someProject := NodeJSEnv(args = ES6NodeArgs).value val ES6NodeArgs = Seq("--harmony-rest-parameters", "--harmony-spreadcalls") + private def includeIf(testDir: File, condition: Boolean): List[File] = + if (condition) List(testDir) + else Nil + val previousArtifactSetting: Setting[_] = { previousArtifact := { val scalaV = scalaVersion.value @@ -1280,10 +1284,6 @@ object Build { testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a", "-s"), unmanagedSourceDirectories in Test ++= { - def includeIf(testDir: File, condition: Boolean): List[File] = - if (condition) List(testDir) - else Nil - val testDir = (sourceDirectory in Test).value val sharedTestDir = testDir.getParentFile.getParentFile.getParentFile / "shared/src/test" @@ -1349,6 +1349,13 @@ object Build { testHtmlSettings(testHtmlFullOpt, FullOptStage) ++ Seq( name := "Scala.js test suite", + unmanagedSourceDirectories in Test ++= { + val testDir = (sourceDirectory in Test).value + + includeIf(testDir / "require-modules", + scalaJSModuleKind.value != ModuleKind.NoModule) + }, + jsDependencies += ProvidedJS / "ScalaJSDefinedTestNatives.js" % "test", skip in packageJSDependencies in Test := false, diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala index 1854d788c4..4f9d05b02c 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala @@ -5,12 +5,14 @@ import sbt._ import org.scalajs.core.tools.io._ import org.scalajs.core.tools.json._ import org.scalajs.core.tools.logging.Logger +import org.scalajs.core.tools.linker.backend.ModuleKind import org.scalajs.jsenv._ import scala.collection.mutable -private[sbtplugin] final class FrameworkDetector(jsEnv: JSEnv) { +private[sbtplugin] final class FrameworkDetector(jsEnv: JSEnv, + moduleKind: ModuleKind, moduleIdentifier: Option[String]) { import FrameworkDetector._ @@ -30,34 +32,41 @@ private[sbtplugin] final class FrameworkDetector(jsEnv: JSEnv) { logger: Logger): Map[TestFramework, String] = { val data = frameworks.map(_.implClassNames.toList).toList.toJSON + val exportsNamespaceExpr = + ScalaJSPluginInternal.makeExportsNamespaceExpr(moduleKind, moduleIdentifier) + val code = s""" - var data = ${jsonToString(data)}; - - function frameworkExists(name) { - var parts = name.split("."); - var obj = ${ScalaJSPluginInternal.jsGlobalExpr}; - for (var i = 0; i < parts.length; ++i) { - obj = obj[parts[i]]; - if (obj === void 0) - return false; - } - return true; - } - - for (var i = 0; i < data.length; ++i) { - var gotOne = false; - for (var j = 0; j < data[i].length; ++j) { - if (frameworkExists(data[i][j])) { - console.log("$ConsoleFrameworkPrefix" + data[i][j]); - gotOne = true; - break; + (function(exportsNamespace) { + "use strict"; + + var data = ${jsonToString(data)}; + + function frameworkExists(name) { + var parts = name.split("."); + var obj = exportsNamespace; + for (var i = 0; i < parts.length; ++i) { + obj = obj[parts[i]]; + if (obj === void 0) + return false; } + return true; } - if (!gotOne) { - // print an empty line with prefix to zip afterwards - console.log("$ConsoleFrameworkPrefix"); + + for (var i = 0; i < data.length; ++i) { + var gotOne = false; + for (var j = 0; j < data[i].length; ++j) { + if (frameworkExists(data[i][j])) { + console.log("$ConsoleFrameworkPrefix" + data[i][j]); + gotOne = true; + break; + } + } + if (!gotOne) { + // print an empty line with prefix to zip afterwards + console.log("$ConsoleFrameworkPrefix"); + } } - } + })($exportsNamespaceExpr); """ val vf = new MemVirtualJSFile("frameworkDetector.js").withContent(code) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index e4fc9ec612..a12d5f09ff 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -14,7 +14,7 @@ import sbt._ import org.scalajs.core.tools.sem.Semantics import org.scalajs.core.tools.io._ import org.scalajs.core.tools.linker.LinkingUnit -import org.scalajs.core.tools.linker.backend.OutputMode +import org.scalajs.core.tools.linker.backend.{ModuleKind, OutputMode} import org.scalajs.core.tools.jsdep.{JSDependencyManifest, ResolvedJSDependency} import org.scalajs.core.tools.jsdep.ManifestFilters.ManifestFilter import org.scalajs.core.tools.jsdep.DependencyResolver.DependencyFilter @@ -171,6 +171,9 @@ object ScalaJSPlugin extends AutoPlugin { new PhantomJSEnv(executable, args, env, autoExit, loader) } + // ModuleKind + val ModuleKind = org.scalajs.core.tools.linker.backend.ModuleKind + // All our public-facing keys val isScalaJSProject = SettingKey[Boolean]("isScalaJSProject", @@ -272,6 +275,9 @@ object ScalaJSPlugin extends AutoPlugin { val scalaJSOutputMode = SettingKey[OutputMode]("scalaJSOutputMode", "Output mode of Scala.js.", BPlusSetting) + val scalaJSModuleKind = SettingKey[ModuleKind]("scalaJSModuleKind", + "Kind of JavaScript modules emitted by Scala.js.", BPlusSetting) + val jsDependencyFilter = SettingKey[DependencyFilter]("jsDependencyFilter", "The filter applied to the raw JavaScript dependencies before execution", CSetting) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 4edc008b57..53f4164cdb 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -18,7 +18,7 @@ import org.scalajs.core.tools.jsdep._ import org.scalajs.core.tools.json._ import org.scalajs.core.tools.linker.{ClearableLinker, Linker} import org.scalajs.core.tools.linker.frontend.LinkerFrontend -import org.scalajs.core.tools.linker.backend.{LinkerBackend, OutputMode} +import org.scalajs.core.tools.linker.backend.{LinkerBackend, ModuleKind, OutputMode} import org.scalajs.jsenv._ import org.scalajs.jsenv.phantomjs.PhantomJettyClassLoader @@ -42,7 +42,7 @@ import java.net.URLClassLoader */ object ScalaJSPluginInternal { - import ScalaJSPlugin.autoImport._ + import ScalaJSPlugin.autoImport.{ModuleKind => _, _} /** The global Scala.js IR cache */ val globalIRCache: IRFileCache = new IRFileCache() @@ -86,6 +86,11 @@ object ScalaJSPluginInternal { "All .sjsir files on the fullClasspath, used by scalajsp", KeyRanks.Invisible) + val scalaJSModuleIdentifier = TaskKey[Option[String]]( + "scalaJSModuleIdentifier", + "An identifier for the module which contains the exports of Scala.js", + KeyRanks.Invisible) + val scalaJSSourceFiles = AttributeKey[Seq[File]]("scalaJSSourceFiles", "Files used to compute this value (can be used in FileFunctions later).", KeyRanks.Invisible) @@ -171,6 +176,7 @@ object ScalaJSPluginInternal { val semantics = (scalaJSSemantics in key).value val outputMode = (scalaJSOutputMode in key).value + val moduleKind = scalaJSModuleKind.value // intentionally not 'in key' val withSourceMap = (emitSourceMaps in key).value val relSourceMapBase = { @@ -198,7 +204,7 @@ object ScalaJSPluginInternal { .withBackendConfig(backendConfig) val newLinker = { () => - Linker(semantics, outputMode, config) + Linker(semantics, outputMode, moduleKind, config) } new ClearableLinker(newLinker, opts.batchMode) @@ -412,20 +418,37 @@ object ScalaJSPluginInternal { ((crossTarget in packageScalaJSLauncher).value / ((moduleName in packageScalaJSLauncher).value + "-launcher.js")), - skip in packageScalaJSLauncher := !persistLauncher.value, + skip in packageScalaJSLauncher := { + val value = !persistLauncher.value + if (!value && (scalaJSModuleKind.value != ModuleKind.NoModule)) { + throw new MessageOnlyException( + "persistLauncher := true is not compatible with emitting " + + "JavaScript modules") + } + 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") + 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 + assert(scalaJSModuleKind.value == ModuleKind.NoModule, + "Cannot produce a launcher file when scalaJSModuleKind " + + "is different from NoModule") + IO.write(file, + launcherContent(mainCl, ModuleKind.NoModule, None), + 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") + } } } }, @@ -609,7 +632,13 @@ object ScalaJSPluginInternal { val libs = resolvedJSDependencies.value.data ++ scalaJSConfigurationLibs.value resolvedJSEnv.value match { - case env: LinkingUnitJSEnv => + /* 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 @@ -627,6 +656,20 @@ object ScalaJSPluginInternal { env.loadLibs(libs :+ ResolvedJSDependency.minimal(file)) } } + }, + + scalaJSModuleIdentifier <<= Def.taskDyn { + scalaJSModuleKind.value match { + case ModuleKind.NoModule => + Def.task { + None + } + + case ModuleKind.CommonJSModule => + Def.task { + Some(scalaJSLinkedFile.value.path) + } + } } ) @@ -641,14 +684,34 @@ object ScalaJSPluginInternal { runner.run(sbtLogger2ToolsLogger(log), console) } - private def launcherContent(mainCl: String) = { + private def launcherContent(mainCl: String, moduleKind: ModuleKind, + moduleIdentifier: Option[String]): String = { + val exportsNamespaceExpr = + makeExportsNamespaceExpr(moduleKind, moduleIdentifier) val parts = mainCl.split('.').map(s => s"""["${escapeJS(s)}"]""").mkString - s"$jsGlobalExpr$parts().main();\n" + s"$exportsNamespaceExpr$parts().main();\n" + } + + private[sbtplugin] def makeExportsNamespaceExpr(moduleKind: ModuleKind, + moduleIdentifier: Option[String]): String = { + // !!! DUPLICATE code with ScalaJSFramework.optionalExportsNamespacePrefix + moduleKind match { + case ModuleKind.NoModule => + jsGlobalExpr + + case ModuleKind.CommonJSModule => + val moduleIdent = moduleIdentifier.getOrElse { + throw new IllegalArgumentException( + "The module identifier must be specified for CommonJS modules") + } + s"""require("${escapeJS(moduleIdent)}")""" + } } - private def memLauncher(mainCl: String) = { + private def memLauncher(mainCl: String, moduleKind: ModuleKind, + moduleIdentifier: Option[String]): VirtualJSFile = { new MemVirtualJSFile("Generated launcher file") - .withContent(launcherContent(mainCl)) + .withContent(launcherContent(mainCl, moduleKind, moduleIdentifier)) } def discoverJSApps(analysis: inc.Analysis): Seq[String] = { @@ -676,15 +739,22 @@ object ScalaJSPluginInternal { 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.") + if (persistLauncher.value) { + Def.task { + packageScalaJSLauncher.value.map(FileVirtualJSFile) + } + } else { + Def.task { + (mainClass in scalaJSLauncher).value.fold { + sys.error("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)) + } } } }, @@ -707,7 +777,10 @@ object ScalaJSPluginInternal { assert(scalaJSEnsureUnforked.value) val mainClass = runMainParser.parsed - jsRun(loadedJSEnv.value, mainClass, memLauncher(mainClass), + val moduleKind = scalaJSModuleKind.value + val moduleIdentifier = scalaJSModuleIdentifier.value + jsRun(loadedJSEnv.value, mainClass, + memLauncher(mainClass, moduleKind, moduleIdentifier), streams.value.log, scalaJSConsole.value) } ) @@ -734,10 +807,15 @@ object ScalaJSPluginInternal { sys.error(s"You need a ComJSEnv to test (found ${jsEnv.name})") } - val detector = new FrameworkDetector(jsEnv) + val moduleKind = scalaJSModuleKind.value + val moduleIdentifier = scalaJSModuleIdentifier.value + + val detector = + new FrameworkDetector(jsEnv, moduleKind, moduleIdentifier) detector.detect(frameworks, toolsLogger) map { case (tf, name) => - (tf, new ScalaJSFramework(name, jsEnv, toolsLogger, console)) + (tf, new ScalaJSFramework(name, jsEnv, moduleKind, moduleIdentifier, + toolsLogger, console)) } }, // Override default to avoid triggering a test:fastOptJS in a test:compile @@ -854,6 +932,7 @@ object ScalaJSPluginInternal { scalaJSSemantics := Semantics.Defaults, scalaJSOutputMode := OutputMode.ECMAScript51Isolated, + scalaJSModuleKind := ModuleKind.NoModule, checkScalaJSSemantics := true, scalaJSConsole := ConsoleJSConsole, diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala index f3b0bfb2b9..afc83db285 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala @@ -9,9 +9,12 @@ package org.scalajs.testadapter +import org.scalajs.core.ir.Utils.escapeJS + import org.scalajs.core.tools.io._ import org.scalajs.core.tools.json._ import org.scalajs.core.tools.logging._ +import org.scalajs.core.tools.linker.backend.ModuleKind import org.scalajs.jsenv._ @@ -20,10 +23,17 @@ import sbt.testing.{Logger => _, _} final class ScalaJSFramework( private[testadapter] val frameworkName: String, private[testadapter] val libEnv: ComJSEnv, + private[testadapter] val moduleKind: ModuleKind, + private[testadapter] val moduleIdentifier: Option[String], private[testadapter] val logger: Logger, private[testadapter] val jsConsole: JSConsole ) extends Framework { + def this(frameworkName: String, libEnv: ComJSEnv, logger: Logger, + jsConsole: JSConsole) = { + this(frameworkName, libEnv, ModuleKind.NoModule, None, logger, jsConsole) + } + private[this] val frameworkInfo = fetchFrameworkInfo() private[this] var _isRunning = false @@ -61,10 +71,26 @@ final class ScalaJSFramework( } private def frameworkInfoLauncher = { + val prefix = optionalExportsNamespacePrefix val name = jsonToString(frameworkName.toJSON) val code = s""" - new org.scalajs.testinterface.internal.InfoSender($name).initAndSend(); + new ${prefix}org.scalajs.testinterface.internal.InfoSender($name).initAndSend(); """ new MemVirtualJSFile(s"testFrameworkInfo.js").withContent(code) } + + private[testadapter] def optionalExportsNamespacePrefix: String = { + // !!! DUPLICATE code with ScalaJSPlugin.makeExportsNamespaceExpr + moduleKind match { + case ModuleKind.NoModule => + "" + + case ModuleKind.CommonJSModule => + val moduleIdent = moduleIdentifier.getOrElse { + throw new IllegalArgumentException( + "The module identifier must be specified for CommonJS modules") + } + s"""require("${escapeJS(moduleIdent)}").""" // note the final '.' + } + } } diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala index 0d398e06c9..aebce10ce2 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala @@ -190,20 +190,22 @@ final class ScalaJSRunner private[testadapter] ( // Helpers private def slaveLauncher = { + val prefix = framework.optionalExportsNamespacePrefix val frameworkJS = jsonToString(framework.frameworkName.toJSON) val argsJS = jsonToString(args.toList.toJSON) val remoteArgsJS = jsonToString(args.toList.toJSON) val code = s""" - new org.scalajs.testinterface.internal.Slave($frameworkJS, + new ${prefix}org.scalajs.testinterface.internal.Slave($frameworkJS, $argsJS, $remoteArgsJS).init(); """ new MemVirtualJSFile("testSlave.js").withContent(code) } private def masterLauncher = { + val prefix = framework.optionalExportsNamespacePrefix val name = jsonToString(framework.frameworkName.toJSON) val code = s""" - new org.scalajs.testinterface.internal.Master($name).init(); + new ${prefix}org.scalajs.testinterface.internal.Master($name).init(); """ new MemVirtualJSFile(s"testMaster.js").withContent(code) } diff --git a/test-suite/js/src/test/require-modules/org/scalajs/testsuite/jsinterop/ModulesTest.scala b/test-suite/js/src/test/require-modules/org/scalajs/testsuite/jsinterop/ModulesTest.scala new file mode 100644 index 0000000000..bc3d64bfd3 --- /dev/null +++ b/test-suite/js/src/test/require-modules/org/scalajs/testsuite/jsinterop/ModulesTest.scala @@ -0,0 +1,120 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.jsinterop + +import scala.scalajs.js +import scala.scalajs.js.annotation._ + +import org.junit.Assert._ +import org.junit.Test + +/* This is currently hard-coded for Node.js modules in particular. + * We are importing built-in Node.js modules, because we do not have any + * infrastructure to load non-built-in modules. In the future, we should use + * our own user-defined ES6 modules written in JavaScript. + */ +class ModulesTest { + import ModulesTest._ + + @Test def testImportModuleItself(): Unit = { + val qs = QueryString + assertTrue(qs.isInstanceOf[js.Object]) + + val dict = js.Dictionary("foo" -> "bar", "baz" -> "qux") + + assertEquals("foo=bar&baz=qux", qs.stringify(dict)) + assertEquals("foo:bar;baz:qux", qs.stringify(dict, ";", ":")) + + /* Potentially, this could be "optimized" by importing `stringify` as a + * global symbol if we are emitting ES2015 modules. + */ + assertEquals("foo=bar&baz=qux", QueryString.stringify(dict)) + assertEquals("foo:bar;baz:qux", QueryString.stringify(dict, ";", ":")) + } + + @Test def testImportLegacyModuleItselfAsDefault(): Unit = { + val qs = QueryStringAsDefault + assertTrue(qs.isInstanceOf[js.Object]) + + val dict = js.Dictionary("foo" -> "bar", "baz" -> "qux") + + assertEquals("foo=bar&baz=qux", qs.stringify(dict)) + assertEquals("foo:bar;baz:qux", qs.stringify(dict, ";", ":")) + + /* Potentially, this could be "optimized" by importing `stringify` as a + * global symbol if we are emitting ES2015 modules. + */ + assertEquals("foo=bar&baz=qux", QueryStringAsDefault.stringify(dict)) + assertEquals("foo:bar;baz:qux", QueryStringAsDefault.stringify(dict, ";", ":")) + } + + @Test def testImportObjectInModule(): Unit = { + assertTrue((Buffer: Any).isInstanceOf[js.Object]) + assertFalse(Buffer.isBuffer(5)) + } + + @Test def testImportClassInModule(): Unit = { + val b = new Buffer(5) + for (i <- 0 until 5) + b(i) = (i * i).toShort + + for (i <- 0 until 5) + assertEquals(i * i, b(i).toInt) + } + + @Test def testImportIntegrated(): Unit = { + val b = new Buffer(js.Array[Short](0xe3, 0x81, 0x93, 0xe3, 0x82, 0x93, 0xe3, + 0x81, 0xab, 0xe3, 0x81, 0xa1, 0xe3, 0x81, 0xaf)) + val decoder = new StringDecoder() + assertTrue(Buffer.isBuffer(b)) + assertFalse(Buffer.isBuffer(decoder)) + assertEquals("こんにちは", decoder.write(b)) + assertEquals("", decoder.end()) + } + +} + +object ModulesTest { + @js.native + @JSImport("querystring", JSImport.Namespace) + object QueryString extends js.Object { + def stringify(obj: js.Dictionary[String], sep: String = "&", + eq: String = "="): String = js.native + } + + @js.native + @JSImport("querystring", JSImport.Default) + object QueryStringAsDefault extends js.Object { + def stringify(obj: js.Dictionary[String], sep: String = "&", + eq: String = "="): String = js.native + } + + @js.native + @JSImport("string_decoder", "StringDecoder") + class StringDecoder(encoding: String = "utf8") extends js.Object { + def write(buffer: Buffer): String = js.native + def end(buffer: Buffer): String = js.native + def end(): String = js.native + } + + /* To stay compatible with Node.js 4.2.1, we describe and use deprecated + * APIs. + */ + @js.native + @JSImport("buffer", "Buffer") + class Buffer private () extends js.typedarray.Uint8Array(0) { + def this(size: Int) = this() + def this(array: js.Array[Short]) = this() + } + + @js.native + @JSImport("buffer", "Buffer") + object Buffer extends js.Object { + def isBuffer(x: Any): Boolean = js.native + } +} diff --git a/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala b/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala index fc5ea4eecf..cb96d12d90 100644 --- a/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala +++ b/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala @@ -17,7 +17,7 @@ import org.scalajs.core.tools.linker.backend._ trait LinkerPlatformExtensions { this: Linker.type => def apply(semantics: Semantics, outputMode: OutputMode, - config: Config): Linker = { + moduleKind: ModuleKind, config: Config): Linker = { val optOptimizerFactory = { if (!config.optimizer) None @@ -27,7 +27,7 @@ trait LinkerPlatformExtensions { this: Linker.type => val frontend = new LinkerFrontend(semantics, outputMode.esLevel, config.sourceMap, config.frontendConfig, optOptimizerFactory) - val backend = new BasicLinkerBackend(semantics, outputMode, + val backend = new BasicLinkerBackend(semantics, outputMode, moduleKind, config.sourceMap, config.backendConfig) new Linker(frontend, backend) @@ -48,7 +48,7 @@ trait LinkerPlatformExtensions { this: Linker.type => .withFrontendConfig(frontendConfig) .withBackendConfig(backendConfig) - apply(semantics, outputMode, config) + apply(semantics, outputMode, ModuleKind.NoModule, config) } } diff --git 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 index c950ec936c..9c57f7346e 100644 --- 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,7 +1,7 @@ package org.scalajs.core.tools.test.js import org.scalajs.core.tools.sem.Semantics -import org.scalajs.core.tools.linker.backend.OutputMode +import org.scalajs.core.tools.linker.backend.{OutputMode, ModuleKind} import org.scalajs.core.tools.io._ import org.scalajs.core.tools.io.IRFileCache.IRContainer import org.scalajs.core.tools.logging._ @@ -35,7 +35,7 @@ object QuickLinker { val cache = (new IRFileCache).newCache val linker = Linker(semantics, OutputMode.ECMAScript51Isolated, - Linker.Config()) + ModuleKind.NoModule, Linker.Config()) val irContainers = irFilesAndJars.map { file => if (file.endsWith(".jar")) { diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala index 2d01e42ef3..def532f099 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala @@ -18,7 +18,7 @@ import org.scalajs.core.tools.linker.backend.closure.ClosureLinkerBackend trait LinkerPlatformExtensions { this: Linker.type => def apply(semantics: Semantics, outputMode: OutputMode, - config: Config): Linker = { + moduleKind: ModuleKind, config: Config): Linker = { val optOptimizerFactory = { if (!config.optimizer) None @@ -33,11 +33,11 @@ trait LinkerPlatformExtensions { this: Linker.type => if (config.closureCompiler) { require(outputMode == OutputMode.ECMAScript51Isolated, s"Cannot use output mode $outputMode with the Closure Compiler") - new ClosureLinkerBackend(semantics, config.sourceMap, - config.backendConfig) + new ClosureLinkerBackend(semantics, moduleKind, + config.sourceMap, config.backendConfig) } else { - new BasicLinkerBackend(semantics, outputMode, config.sourceMap, - config.backendConfig) + new BasicLinkerBackend(semantics, outputMode, moduleKind, + config.sourceMap, config.backendConfig) } } @@ -63,7 +63,7 @@ trait LinkerPlatformExtensions { this: Linker.type => .withFrontendConfig(frontendConfig) .withBackendConfig(backendConfig) - apply(semantics, outputMode, config) + apply(semantics, outputMode, ModuleKind.NoModule, config) } } diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala index 29366ad615..24906c90f4 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala @@ -25,7 +25,7 @@ import org.scalajs.core.tools.sem.Semantics import org.scalajs.core.tools.linker.LinkingUnit import org.scalajs.core.tools.linker.analyzer.SymbolRequirement -import org.scalajs.core.tools.linker.backend.{OutputMode, LinkerBackend} +import org.scalajs.core.tools.linker.backend._ import org.scalajs.core.tools.linker.backend.emitter.{Emitter, CoreJSLibs} /** The Closure backend of the Scala.js linker. @@ -35,12 +35,20 @@ import org.scalajs.core.tools.linker.backend.emitter.{Emitter, CoreJSLibs} */ final class ClosureLinkerBackend( semantics: Semantics, + moduleKind: ModuleKind, withSourceMap: Boolean, config: LinkerBackend.Config -) extends LinkerBackend(semantics, ESLevel.ES5, withSourceMap, config) { +) extends LinkerBackend(semantics, ESLevel.ES5, moduleKind, withSourceMap, + config) { + + @deprecated("Use the overload with an explicit ModuleKind", "0.6.13") + def this(semantics: Semantics, withSourceMap: Boolean, + config: LinkerBackend.Config) { + this(semantics, ModuleKind.NoModule, withSourceMap, config) + } private[this] val emitter = { - new Emitter(semantics, OutputMode.ECMAScript51Isolated) + new Emitter(semantics, OutputMode.ECMAScript51Isolated, moduleKind) .withOptimizeBracketSelects(false) } @@ -69,7 +77,7 @@ final class ClosureLinkerBackend( val module = new JSModule("Scala.js") module.add(new CompilerInput(toClosureSource( - CoreJSLibs.lib(semantics, OutputMode.ECMAScript51Isolated)))) + CoreJSLibs.lib(semantics, OutputMode.ECMAScript51Isolated, moduleKind)))) val ast = builder.closureAST module.add(new CompilerInput(ast, ast.getInputId(), false)) @@ -190,7 +198,9 @@ private object ClosureLinkerBackend { Function.prototype.constructor = function() {}; Function.prototype.call = function() {}; Function.prototype.apply = function() {}; + function require() {} var global = {}; + var exports = {}; var __ScalaJSEnv = {}; var NaN = 0.0/0.0, Infinity = 1.0/0.0, undefined = void 0; """ diff --git a/tools/scalajsenv.js b/tools/scalajsenv.js index 88dd437369..921529fb08 100644 --- a/tools/scalajsenv.js +++ b/tools/scalajsenv.js @@ -22,9 +22,13 @@ ScalaJS.g = ScalaJS.env["global"] = ScalaJS.g; // Where to send exports +//!if moduleKind == CommonJSModule +ScalaJS.e = exports; +//!else ScalaJS.e = (typeof ScalaJS.env["exportsNamespace"] === "object" && ScalaJS.env["exportsNamespace"]) ? ScalaJS.env["exportsNamespace"] : ScalaJS.g; +//!endif ScalaJS.env["exportsNamespace"] = ScalaJS.e; // Freeze the environment info @@ -493,6 +497,12 @@ ScalaJS.superSet = function(initialProto, self, propName, value) { throw new ScalaJS.g["TypeError"]("super has no setter '" + propName + "'."); }; +//!if moduleKind == CommonJSModule +ScalaJS.moduleDefault = function(m) { + return (m && (typeof m === "object") && "default" in m) ? m["default"] : m; +}; +//!endif + ScalaJS.propertiesOf = function(obj) { const result = []; for (const prop in obj) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala index be3e6bf245..a0659a3600 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala @@ -24,11 +24,20 @@ import org.scalajs.core.tools.javascript.{JSFileBuilder, JSFileBuilderWithSource final class BasicLinkerBackend( semantics: Semantics, outputMode: OutputMode, + moduleKind: ModuleKind, withSourceMap: Boolean, config: LinkerBackend.Config -) extends LinkerBackend(semantics, outputMode.esLevel, withSourceMap, config) { +) extends LinkerBackend(semantics, outputMode.esLevel, moduleKind, + withSourceMap, config) { - private[this] val emitter = new Emitter(semantics, outputMode) + @deprecated("Use the overload with an explicit ModuleKind", "0.6.13") + def this(semantics: Semantics, outputMode: OutputMode, withSourceMap: Boolean, + config: LinkerBackend.Config) { + this(semantics, outputMode, ModuleKind.NoModule, withSourceMap, config) + } + + private[this] val emitter = + new Emitter(semantics, outputMode, moduleKind) val symbolRequirements: SymbolRequirement = emitter.symbolRequirements diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala index 1596160b12..b407b61b67 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala @@ -28,9 +28,16 @@ import org.scalajs.core.tools.linker.analyzer.SymbolRequirement abstract class LinkerBackend( val semantics: Semantics, val esLevel: ESLevel, + val moduleKind: ModuleKind, val withSourceMap: Boolean, protected val config: LinkerBackend.Config) { + @deprecated("Use the overload with an explicit ModuleKind", "0.6.13") + def this(semantics: Semantics, esLevel: ESLevel, withSourceMap: Boolean, + config: LinkerBackend.Config) { + this(semantics, esLevel, ModuleKind.NoModule, withSourceMap, config) + } + /** Symbols this backend needs to be present in the linking unit. */ val symbolRequirements: SymbolRequirement diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/ModuleKind.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/ModuleKind.scala new file mode 100644 index 0000000000..477a6d6b54 --- /dev/null +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/ModuleKind.scala @@ -0,0 +1,43 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package org.scalajs.core.tools.linker.backend + +/** Kind of module structure emitted for the Scala.js output. */ +sealed abstract class ModuleKind + +object ModuleKind { + + /** All the available module kinds. + * + * They are listed in decreasing order of "importance", as judged by + * whoever maintains the back-ends. + */ + val All: List[ModuleKind] = List( + NoModule, + CommonJSModule) + + /** No module structure. + * + * With this module kind, exports are stored on the global object by + * default, or to a separate object specified with + * `__ScalaJSEnv.exportsNamespace`. + * + * Imports are not supported. + */ + case object NoModule extends ModuleKind + + /** A CommonJS module (notably used by Node.js). + * + * Imported modules are fetched with `require`. Exports go to the `exports` + * module-global variable. + */ + case object CommonJSModule extends ModuleKind + +} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala index 34616cfe39..27a5d882bd 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala @@ -15,7 +15,7 @@ import org.scalajs.core.ir.ScalaJSVersions import org.scalajs.core.tools.io._ import org.scalajs.core.tools.sem._ -import org.scalajs.core.tools.linker.backend.OutputMode +import org.scalajs.core.tools.linker.backend.{ModuleKind, OutputMode} import scala.collection.immutable.Seq import scala.collection.mutable @@ -25,7 +25,7 @@ import scala.collection.mutable */ private[backend] object CoreJSLibs { - private type Config = (Semantics, OutputMode) + private type Config = (Semantics, OutputMode, ModuleKind) private val cachedLibByConfig = mutable.HashMap.empty[Config, VirtualJSFile] @@ -36,20 +36,22 @@ private[backend] object CoreJSLibs { private val gitHubBaseURI = new URI("https://raw.githubusercontent.com/scala-js/scala-js/") - def lib(semantics: Semantics, outputMode: OutputMode): VirtualJSFile = { + def lib(semantics: Semantics, outputMode: OutputMode, + moduleKind: ModuleKind): VirtualJSFile = { synchronized { cachedLibByConfig.getOrElseUpdate( - (semantics, outputMode), makeLib(semantics, outputMode)) + (semantics, outputMode, moduleKind), + makeLib(semantics, outputMode, moduleKind)) } } - private def makeLib(semantics: Semantics, - outputMode: OutputMode): VirtualJSFile = { - new ScalaJSEnvVirtualJSFile(makeContent(semantics, outputMode)) + private def makeLib(semantics: Semantics, outputMode: OutputMode, + moduleKind: ModuleKind): VirtualJSFile = { + new ScalaJSEnvVirtualJSFile(makeContent(semantics, outputMode, moduleKind)) } - private def makeContent(semantics: Semantics, - outputMode: OutputMode): String = { + private def makeContent(semantics: Semantics, outputMode: OutputMode, + moduleKind: ModuleKind): String = { // This is a basic sort-of-C-style preprocessor def getOption(name: String): String = name match { @@ -64,6 +66,8 @@ private[backend] object CoreJSLibs { semantics.productionMode.toString() case "outputMode" => outputMode.toString() + case "moduleKind" => + moduleKind.toString() } val originalLines = ScalaJSEnvLines diff --git 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 index 16498dc81e..08e1dd5afb 100644 --- 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 @@ -14,6 +14,7 @@ import scala.annotation.tailrec import scala.collection.mutable import org.scalajs.core.ir.{ClassKind, Position} +import org.scalajs.core.ir.Trees.JSNativeLoadSpec import org.scalajs.core.tools.sem._ import org.scalajs.core.tools.logging._ @@ -22,16 +23,28 @@ import org.scalajs.core.tools.javascript.{Trees => js, _} import org.scalajs.core.tools.linker._ import org.scalajs.core.tools.linker.analyzer.SymbolRequirement -import org.scalajs.core.tools.linker.backend.OutputMode +import org.scalajs.core.tools.linker.backend.{OutputMode, ModuleKind} /** Emits a desugared JS tree to a builder */ final class Emitter private (semantics: Semantics, outputMode: OutputMode, - internalOptions: InternalOptions) { + moduleKind: ModuleKind, internalOptions: InternalOptions) { import Emitter._ + require( + outputMode != OutputMode.ECMAScript51Global || moduleKind == ModuleKind.NoModule, + "The ECMAScript51Global output mode is not compatible with modules") + + def this(semantics: Semantics, outputMode: OutputMode, + moduleKind: ModuleKind) = { + this(semantics, outputMode, moduleKind, InternalOptions()) + } + + @deprecated("Use the overload with an explicit ModuleKind.", "0.6.13") def this(semantics: Semantics, outputMode: OutputMode) = - this(semantics, outputMode, InternalOptions()) + this(semantics, outputMode, ModuleKind.NoModule, InternalOptions()) + + private implicit def implicitOutputMode: OutputMode = outputMode private val knowledgeGuardian = new KnowledgeGuardian @@ -48,10 +61,25 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, val symbolRequirements: SymbolRequirement = Emitter.symbolRequirements(semantics, outputMode.esLevel) + private val needsIIFEWrapper = { + moduleKind match { + case ModuleKind.NoModule => + outputMode match { + case OutputMode.ECMAScript51Global => + false + case OutputMode.ECMAScript51Isolated | OutputMode.ECMAScript6 => + true + } + + case ModuleKind.CommonJSModule => + false + } + } + // Private API for the Closure backend (could be opened if necessary) private[backend] def withOptimizeBracketSelects( optimizeBracketSelects: Boolean): Emitter = { - new Emitter(semantics, outputMode, + new Emitter(semantics, outputMode, moduleKind, internalOptions.withOptimizeBracketSelects(optimizeBracketSelects)) } @@ -66,20 +94,20 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, emitLines(customHeader, builder) def emitPrelude(builder: JSFileBuilder, logger: Logger): Unit = { - outputMode match { - case OutputMode.ECMAScript51Global => - case OutputMode.ECMAScript51Isolated | OutputMode.ECMAScript6 => - builder.addLine("(function(){") - } + if (needsIIFEWrapper) + builder.addLine("(function(){") builder.addLine("'use strict';") - builder.addFile(CoreJSLibs.lib(semantics, outputMode)) + builder.addFile(CoreJSLibs.lib(semantics, outputMode, moduleKind)) } def emit(unit: LinkingUnit, builder: JSTreeBuilder, logger: Logger): Unit = { startRun(unit) try { val orderedClasses = unit.classDefs.sortWith(compareClasses) + + emitModuleImports(orderedClasses, builder) + for (classInfo <- orderedClasses) emitLinkedClass(classInfo, builder) } finally { @@ -87,14 +115,38 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, } } - def emitPostlude(builder: JSFileBuilder, logger: Logger): Unit = { - outputMode match { - case OutputMode.ECMAScript51Global => - case OutputMode.ECMAScript51Isolated | OutputMode.ECMAScript6 => - builder.addLine("}).call(this);") + private def emitModuleImports(orderedClasses: List[LinkedClass], + builder: JSTreeBuilder): Unit = { + moduleKind match { + case ModuleKind.NoModule => + + case ModuleKind.CommonJSModule => + val jsDesugaring = new JSDesugaring(internalOptions) + val encounteredModuleNames = mutable.Set.empty[String] + for (classDef <- orderedClasses) { + classDef.jsNativeLoadSpec match { + case None => + case Some(JSNativeLoadSpec.Global(_)) => + + case Some(JSNativeLoadSpec.Import(module, _)) => + if (encounteredModuleNames.add(module)) { + implicit val pos = classDef.pos + val rhs = js.Apply(js.VarRef(js.Ident("require")), + List(js.StringLiteral(module))) + val lhs = jsDesugaring.envModuleField(module) + val decl = jsDesugaring.genLet(lhs.ident, mutable = false, rhs) + builder.addJSTree(decl) + } + } + } } } + def emitPostlude(builder: JSFileBuilder, logger: Logger): Unit = { + if (needsIIFEWrapper) + builder.addLine("}).call(this);") + } + def emitCustomFooter(customFooter: String, builder: JSFileBuilder): Unit = emitLines(customFooter, builder) @@ -247,7 +299,7 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, startRun(linkingUnit) def getHeaderFile(): org.scalajs.core.tools.io.VirtualJSFile = - CoreJSLibs.lib(semantics, outputMode) + CoreJSLibs.lib(semantics, outputMode, moduleKind) def genClassDef(linkedClass: LinkedClass): js.Tree = classEmitter.genClassDef(linkedClass)(globalKnowledge) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala index 070321f803..96683e6a94 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala @@ -2279,14 +2279,74 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { private[emitter] def genLoadJSFromSpec(spec: JSNativeLoadSpec)( implicit outputMode: OutputMode, pos: Position): js.Tree = { + + def pathSelection(from: js.Tree, path: List[String]): js.Tree = { + path.foldLeft(from) { + (prev, part) => genBracketSelect(prev, js.StringLiteral(part)) + } + } + spec match { case JSNativeLoadSpec.Global(path) => - path.foldLeft(envField("g")) { - (prev, part) => genBracketSelect(prev, js.StringLiteral(part)) + pathSelection(envField("g"), path) + + case JSNativeLoadSpec.Import(module, path) => + val moduleValue = envModuleField(module) + path match { + case DefaultExportName :: rest => + val defaultField = genCallHelper("moduleDefault", moduleValue) + pathSelection(defaultField, rest) + case _ => + pathSelection(moduleValue, path) } } } + private final val DefaultExportName = "default" + + private[emitter] def envModuleField(module: String)( + implicit pos: Position): js.VarRef = { + + /* This is written so that the happy path, when `module` contains only + * valid characters, is fast. + */ + + def isValidChar(c: Char): Boolean = + (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') + + def containsOnlyValidChars(): Boolean = { + val len = module.length + var i = 0 + while (i != len) { + if (!isValidChar(module.charAt(i))) + return false + i += 1 + } + true + } + + def buildValidName(): String = { + val result = new java.lang.StringBuilder("$i_") + val len = module.length + var i = 0 + while (i != len) { + val c = module.charAt(i) + if (isValidChar(c)) + result.append(c) + else + result.append("$%04x".format(c.toInt)) + i += 1 + } + result.toString() + } + + val varName = + if (containsOnlyValidChars()) "$i_" + module + else buildValidName() + + js.VarRef(js.Ident(varName, Some(module))) + } + private[emitter] def envField(field: String, subField: String, origName: Option[String] = None)( implicit outputMode: OutputMode, pos: Position): js.Tree = { diff --git a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala index 967dcfce06..571bc9ffd1 100644 --- a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala +++ b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala @@ -6,7 +6,7 @@ import org.junit.Assert._ import org.scalajs.core.tools.logging.NullLogger import org.scalajs.core.tools.io._ import org.scalajs.core.tools.sem.Semantics -import org.scalajs.core.tools.linker.backend.OutputMode +import org.scalajs.core.tools.linker.backend.{OutputMode, ModuleKind} class LinkerTest { @@ -23,7 +23,7 @@ class LinkerTest { } val linker = Linker(Semantics.Defaults, OutputMode.ECMAScript51Isolated, - Linker.Config()) + ModuleKind.NoModule, Linker.Config()) def callLink(): Unit = linker.link(badSeq, WritableMemVirtualJSFile("some_file"), NullLogger) From c548a723121095ecb7208a5c7fbc0069f1fcc27b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 8 Oct 2016 13:03:29 +0200 Subject: [PATCH 0029/2665] Fix #2617: Emit a warning for @JSName on traits and non-JS-natives. This prompted a refactoring to keep things DRY, which in turn causes some error messages to change a bit with a less specific text. --- .../scalajs/core/compiler/PrepJSInterop.scala | 65 +++++++++-------- .../core/compiler/test/JSInteropTest.scala | 72 ++++++++++++++++--- 2 files changed, 98 insertions(+), 39 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 353d776d35..2b5036d785 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -167,12 +167,6 @@ abstract class PrepJSInterop extends plugins.PluginComponent "Scala traits, classes or objects (i.e., not extending js.Any)") super.transform(tree) - // @ScalaJSDefined is only valid on a js.Any - case idef: ImplDef if idef.symbol.hasAnnotation(ScalaJSDefinedAnnotation) => - reporter.error(idef.pos, - "@ScalaJSDefined is only allowed on classes extending js.Any") - super.transform(tree) - // Catch the definition of scala.Enumeration itself case cldef: ClassDef if cldef.symbol == ScalaEnumClass => enterOwner(OwnerKind.EnumImpl) { super.transform(cldef) } @@ -181,10 +175,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent case idef: ImplDef if isScalaEnum(idef) => val sym = idef.symbol - if (sym.hasAnnotation(JSNativeAnnotation)) - reportJSNativeOnNonJSAny(idef.pos, "Classes and objects") - else if (sym.hasAnnotation(JSImportAnnotation)) - reportJSImportOnNonJSNative(idef.pos) + checkJSAnySpecificAnnotsOnNonJSAny(idef.pos, sym) val kind = if (idef.isInstanceOf[ModuleDef]) OwnerKind.EnumMod @@ -195,10 +186,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent case cldef: ClassDef => val sym = cldef.symbol - if (sym.hasAnnotation(JSNativeAnnotation)) - reportJSNativeOnNonJSAny(cldef.pos, "Traits and classes") - else if (sym.hasAnnotation(JSImportAnnotation)) - reportJSImportOnNonJSNative(cldef.pos) + checkJSAnySpecificAnnotsOnNonJSAny(cldef.pos, sym) if (sym == UndefOrClass || sym == UnionClass) sym.addAnnotation(RawJSTypeAnnot) @@ -217,10 +205,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent case modDef: ModuleDef => val sym = modDef.symbol - if (sym.hasAnnotation(JSNativeAnnotation)) - reportJSNativeOnNonJSAny(modDef.pos, "Objects") - else if (sym.hasAnnotation(JSImportAnnotation)) - reportJSImportOnNonJSNative(modDef.pos) + checkJSAnySpecificAnnotsOnNonJSAny(modDef.pos, sym) if (shouldPrepareExports) registerModuleExports(sym.moduleClass) @@ -528,9 +513,8 @@ abstract class PrepJSInterop extends plugins.PluginComponent "native JS trait.") } - // Check that there is no @JSImport annotation - if (sym.hasAnnotation(JSImportAnnotation)) - reportJSImportOnNonJSNative(implDef.pos) + // Check that there is no JS-native-specific annotation + checkJSNativeSpecificAnnotsOnNonJSNative(sym) } if (shouldCheckLiterals) { @@ -610,6 +594,11 @@ abstract class PrepJSInterop extends plugins.PluginComponent sym.addAnnotation(HasJSNativeLoadSpecAnnotation) } else { assert(sym.isTrait) // just tested in the previous `if` + if (sym.hasAnnotation(JSNameAnnotation)) { + reporter.warning(implDef.pos, + "Traits should not have an @JSName annotation, as it does " + + "not have any effect. This will be enforced in 1.0.") + } if (sym.hasAnnotation(JSImportAnnotation)) { reporter.error(implDef.pos, "Traits may not have an @JSImport annotation") @@ -1088,15 +1077,35 @@ abstract class PrepJSInterop extends plugins.PluginComponent } } - private def reportJSNativeOnNonJSAny(pos: Position, reportOn: String): Unit = { - reporter.error(pos, reportOn + " not extending js.Any may not have a " + - "@js.native annotation") + private def checkJSAnySpecificAnnotsOnNonJSAny(pos: Position, + sym: Symbol): Unit = { + if (sym.hasAnnotation(ScalaJSDefinedAnnotation)) { + reporter.error(pos, + "@ScalaJSDefined is only allowed on classes extending js.Any") + } + + if (sym.hasAnnotation(JSNativeAnnotation)) { + reporter.error(pos, + "Classes, traits and objects not extending js.Any may not have an " + + "@js.native annotation") + } else { + checkJSNativeSpecificAnnotsOnNonJSNative(sym) + } } - private def reportJSImportOnNonJSNative(pos: Position): Unit = { - reporter.error(pos, - s"Non JS-native classes, traits and objects may not have an " + - "@JSImport annotation") + private def checkJSNativeSpecificAnnotsOnNonJSNative(sym: Symbol): Unit = { + for (annot <- sym.annotations) { + if (annot.symbol == JSNameAnnotation) { + reporter.warning(annot.pos, + "Non JS-native classes, traits and objects should not have an " + + "@JSName annotation, as it does not have any effect. " + + "This will be enforced in 1.0.") + } else if (annot.symbol == JSImportAnnotation) { + reporter.error(annot.pos, + "Non JS-native classes, traits and objects may not have an " + + "@JSImport annotation.") + } + } } private lazy val ScalaEnumClass = getRequiredClass("scala.Enumeration") diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index f3d0b6cbdd..6bf731b2ce 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -67,6 +67,40 @@ class JSInteropTest extends DirectTest with TestHelpers { } + @Test + def noJSNameAnnotOnNonJSNative: Unit = { + + for { + obj <- Seq("class", "trait", "object") + } yield { + s""" + @ScalaJSDefined + @JSName("foo") + $obj A extends js.Object + """ hasWarns + s""" + |newSource1.scala:6: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. + | @JSName("foo") + | ^ + """ + } + + for { + obj <- Seq("class", "trait", "object") + } yield { + s""" + @JSName("foo") + $obj A + """ hasWarns + s""" + |newSource1.scala:5: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. + | @JSName("foo") + | ^ + """ + } + + } + @Test def noJSImportAnnotOnNonJSNative: Unit = { @@ -79,9 +113,9 @@ class JSInteropTest extends DirectTest with TestHelpers { $obj A extends js.Object """ hasErrors s""" - |newSource1.scala:7: error: Non JS-native classes, traits and objects may not have an @JSImport annotation - | $obj A extends js.Object - | ${" " * obj.length} ^ + |newSource1.scala:6: error: Non JS-native classes, traits and objects may not have an @JSImport annotation. + | @JSImport("foo", JSImport.Namespace) + | ^ """ } @@ -93,14 +127,30 @@ class JSInteropTest extends DirectTest with TestHelpers { $obj A """ hasErrors s""" - |newSource1.scala:6: error: Non JS-native classes, traits and objects may not have an @JSImport annotation - | $obj A - | ${" " * obj.length} ^ + |newSource1.scala:5: error: Non JS-native classes, traits and objects may not have an @JSImport annotation. + | @JSImport("foo", JSImport.Namespace) + | ^ """ } } + @Test + def noJSNameAnnotOnTrait: Unit = { + + s""" + @js.native + @JSName("foo") + trait A extends js.Object + """ hasWarns + s""" + |newSource1.scala:7: warning: Traits should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. + | trait A extends js.Object + | ^ + """ + + } + @Test def noJSImportAnnotOnTrait: Unit = { @@ -125,7 +175,7 @@ class JSInteropTest extends DirectTest with TestHelpers { class A """ hasErrors """ - |newSource1.scala:6: error: Traits and classes not extending js.Any may not have a @js.native annotation + |newSource1.scala:6: error: Classes, traits and objects not extending js.Any may not have an @js.native annotation | class A | ^ """ @@ -135,7 +185,7 @@ class JSInteropTest extends DirectTest with TestHelpers { trait A """ hasErrors """ - |newSource1.scala:6: error: Traits and classes not extending js.Any may not have a @js.native annotation + |newSource1.scala:6: error: Classes, traits and objects not extending js.Any may not have an @js.native annotation | trait A | ^ """ @@ -145,7 +195,7 @@ class JSInteropTest extends DirectTest with TestHelpers { object A """ hasErrors """ - |newSource1.scala:6: error: Objects not extending js.Any may not have a @js.native annotation + |newSource1.scala:6: error: Classes, traits and objects not extending js.Any may not have an @js.native annotation | object A | ^ """ @@ -155,7 +205,7 @@ class JSInteropTest extends DirectTest with TestHelpers { class A extends Enumeration """ hasErrors """ - |newSource1.scala:6: error: Classes and objects not extending js.Any may not have a @js.native annotation + |newSource1.scala:6: error: Classes, traits and objects not extending js.Any may not have an @js.native annotation | class A extends Enumeration | ^ """ @@ -165,7 +215,7 @@ class JSInteropTest extends DirectTest with TestHelpers { object A extends Enumeration """ hasErrors """ - |newSource1.scala:6: error: Classes and objects not extending js.Any may not have a @js.native annotation + |newSource1.scala:6: error: Classes, traits and objects not extending js.Any may not have an @js.native annotation | object A extends Enumeration | ^ """ From 1dd280c52684ec8482697e12b949b47a4b18c45d Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 8 Oct 2016 17:14:35 +0200 Subject: [PATCH 0030/2665] Introduce Lhs in JSDesugaring to not use EmptyTree --- project/BinaryIncompatibilities.scala | 11 + .../linker/backend/emitter/JSDesugaring.scala | 193 ++++++++++-------- 2 files changed, 119 insertions(+), 85 deletions(-) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 0ee477b3a1..d2fbc309e5 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -37,6 +37,17 @@ object BinaryIncompatibilities { ProblemFilters.exclude[IncompatibleMethTypeProblem]( "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.desugarToFunction"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.Env"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring#Env.this"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring#Env.withLabeledExprLHS"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring#Env.lhsForLabeledExpr"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring#JSDesugar.pushLhsInto"), + // private[emitter], not an issue ProblemFilters.exclude[IncompatibleMethTypeProblem]( "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.this"), diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala index 96683e6a94..6cb48de5f5 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala @@ -54,7 +54,7 @@ import java.io.StringWriter * * Assign, i.e., `x =` * * VarDef, i.e., `val x =` or `var x =` * * Return, i.e., `return` - * * (EmptyTree is also used as a trick for code reuse) + * * Discard, i.e. just evaluate and discard * In fact, think that, in this context, LHS means: what to do with the * result of evaluating the RHS. * @@ -196,6 +196,7 @@ import java.io.StringWriter * @author Sébastien Doeraene */ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { + import JSDesugaring._ private final val ScalaJSEnvironmentName = "ScalaJS" @@ -380,7 +381,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { js.Skip() case VarDef(_, _, _, rhs) => - pushLhsInto(EmptyTree, rhs, tailPosLabels) + pushLhsInto(Lhs.Discard, rhs, tailPosLabels) // Statement-only language constructs @@ -388,7 +389,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { js.Skip() case Assign(RecordFieldVarRef(lhs), rhs) => - pushLhsInto(Assign(lhs, EmptyTree), rhs, tailPosLabels) + pushLhsInto(Lhs.Assign(lhs), rhs, tailPosLabels) case Assign(select @ Select(qualifier, item), rhs) => unnest(qualifier, rhs) { (newQualifier, newRhs, env0) => @@ -437,8 +438,8 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { transformExpr(rhs)) } - case Assign(_ : VarRef, rhs) => - pushLhsInto(tree, rhs, tailPosLabels) + case Assign(varRef: VarRef, rhs) => + pushLhsInto(Lhs.Assign(varRef), rhs, tailPosLabels) case Assign(_, _) => sys.error(s"Illegal Assign in transformStat: $tree") @@ -599,18 +600,18 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { // Treat 'return' as an LHS case Return(expr, label) => - pushLhsInto(tree, expr, tailPosLabels) + pushLhsInto(Lhs.Return(label), expr, tailPosLabels) - /* Anything else is an expression => pushLhsInto(EmptyTree, _) + /* Anything else is an expression => pushLhsInto(Lhs.Discard, _) * In order not to duplicate all the code of pushLhsInto() here, we - * use a trick: EmptyTree is a dummy LHS that says "do nothing + * use a trick: Lhs.Discard is a dummy LHS that says "do nothing * with the result of the rhs". * This is exactly what an expression statement is doing: it evaluates * the expression, but does nothing with its result. */ case _ => - pushLhsInto(EmptyTree, tree, tailPosLabels) + pushLhsInto(Lhs.Discard, tree, tailPosLabels) } } @@ -632,9 +633,10 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { @tailrec def transformLoop(trees: List[Tree], env: Env, acc: List[js.Tree]): (List[js.Tree], Env) = trees match { - case (tree @ VarDef(ident, tpe, mutable, rhs)) :: ts => + case VarDef(ident, tpe, mutable, rhs) :: ts => val newEnv = env.withDef(ident, tpe, mutable) - val newTree = pushLhsInto(tree, rhs, Set.empty)(env) + val lhs = Lhs.VarDef(ident, tpe, mutable) + val newTree = pushLhsInto(lhs, rhs, Set.empty)(env) transformLoop(ts, newEnv, newTree :: acc) case tree :: ts => @@ -795,7 +797,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { val newEnv = env.withDef(temp, arg.tpe, false) innerEnv = newEnv val computeTemp = pushLhsInto( - VarDef(temp, arg.tpe, mutable = false, EmptyTree), arg, + Lhs.VarDef(temp, arg.tpe, mutable = false), arg, Set.empty) computeTemp +=: extractedStatements VarRef(temp)(arg.tpe) @@ -1037,11 +1039,8 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { } } - /** Push an lhs into a (potentially complex) rhs - * lhs can be either a EmptyTree, a VarDef, a Assign or a - * Return - */ - def pushLhsInto(lhs: Tree, rhs: Tree, tailPosLabels: Set[String])( + /** Push an lhs into a (potentially complex) rhs */ + def pushLhsInto(lhs: Lhs, rhs: Tree, tailPosLabels: Set[String])( implicit env: Env): js.Tree = { implicit val pos = rhs.pos @@ -1053,16 +1052,16 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { * its scope. * This only matters in ECMAScript 6, because we emit Lets. */ - def extractLet(inner: Tree => js.Tree): js.Tree = { + def extractLet(inner: Lhs => js.Tree): js.Tree = { outputMode match { case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => inner(lhs) case OutputMode.ECMAScript6 => lhs match { - case VarDef(name, tpe, mutable, oldRhs) => + case Lhs.VarDef(name, tpe, mutable) => js.Block( doEmptyVarDef(name, tpe), - inner(Assign(VarRef(name)(tpe), oldRhs))) + inner(Lhs.Assign(VarRef(name)(tpe)))) case _ => inner(lhs) } @@ -1072,7 +1071,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { def doReturnToLabel(l: Ident): js.Tree = { val newLhs = env.lhsForLabeledExpr(l) val body = pushLhsInto(newLhs, rhs, Set.empty) - if (newLhs.tpe == NothingType) { + if (newLhs.hasNothingType) { /* A touch of peephole dead code elimination. * This is actually necessary to avoid dangling breaks to eliminated * labels, as in issue #2307. @@ -1088,14 +1087,14 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { } } - if (rhs.tpe == NothingType && lhs != EmptyTree) { + if (rhs.tpe == NothingType && lhs != Lhs.Discard) { /* A touch of peephole dead code elimination. * Actually necessary to handle pushing an lhs into an infinite loop, * for example. */ - val transformedRhs = pushLhsInto(EmptyTree, rhs, tailPosLabels) + val transformedRhs = pushLhsInto(Lhs.Discard, rhs, tailPosLabels) lhs match { - case VarDef(name, tpe, _, _) => + case Lhs.VarDef(name, tpe, _) => /* We still need to declare the var, in case it is used somewhere * else in the function, where we can't dce it. */ @@ -1115,32 +1114,34 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { // Base case, rhs is already a regular JS expression case _ if isExpression(rhs) => - (lhs: @unchecked) match { - case EmptyTree => + lhs match { + case Lhs.Discard => if (isSideEffectFreeExpression(rhs)) js.Skip() else transformExpr(rhs) - case VarDef(name, tpe, mutable, _) => + case Lhs.VarDef(name, tpe, mutable) => doVarDef(name, tpe, mutable, rhs) - case Assign(lhs, _) => + case Lhs.Assign(lhs) => doAssign(lhs, rhs) - case Return(_, None) => + case Lhs.Return(None) => js.Return(transformExpr(rhs)) - case Return(_, Some(l)) => + case Lhs.Return(Some(l)) => doReturnToLabel(l) } // Almost base case with RecordValue case RecordValue(recTpe, elems) => - (lhs: @unchecked) match { - case EmptyTree => + lhs match { + case Lhs.Discard => val (newStat, _) = transformBlockStats(elems) js.Block(newStat) - case VarDef(name, tpe, mutable, _) => + + case Lhs.VarDef(name, tpe, mutable) => unnest(elems) { (newElems, env) => doVarDef(name, tpe, mutable, RecordValue(recTpe, newElems))(env) } - case Assign(lhs, _) => + + case Lhs.Assign(lhs) => unnest(elems) { (newElems, env0) => implicit val env = env0 val temp = newSyntheticVar() @@ -1149,7 +1150,11 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { RecordValue(recTpe, newElems)), doAssign(lhs, VarRef(temp)(recTpe))) } - case Return(_, Some(l)) => + + case Lhs.Return(None) => + throw new AssertionError("Cannot return a record value.") + + case Lhs.Return(Some(l)) => doReturnToLabel(l) } @@ -1166,8 +1171,8 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { newBody } - case Return(expr, _) => - pushLhsInto(rhs, expr, tailPosLabels) + case Return(expr, label) => + pushLhsInto(Lhs.Return(label), expr, tailPosLabels) case Continue(label) => js.Continue(label.map(transformIdent)) @@ -1511,11 +1516,10 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { } case _ => - if (lhs == EmptyTree) { + if (lhs == Lhs.Discard) { /* Go "back" to transformStat() after having dived into - * expression statements. Remember that (lhs == EmptyTree) - * is a trick that we use to "add" all the code of pushLhsInto() - * to transformStat(). + * expression statements. Remember that Lhs.Discard is a trick that + * we use to "add" all the code of pushLhsInto() to transformStat(). */ rhs match { case _:Skip | _:VarDef | _:Assign | _:While | _:DoWhile | @@ -1592,7 +1596,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { val temp = newSyntheticVar() val newEnv = env.withDef(temp, expr.tpe, false) val computeTemp = pushLhsInto( - VarDef(temp, expr.tpe, mutable = false, EmptyTree), expr, + Lhs.VarDef(temp, expr.tpe, mutable = false), expr, Set.empty) js.Block(computeTemp, makeTree(VarRef(temp)(expr.tpe), newEnv)) } @@ -2138,49 +2142,6 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { } } - // Environment - - final class Env private ( - vars: Map[String, Boolean], - labeledExprLHSes: Map[String, Tree], - defaultBreakTargets: Set[String] - ) { - def isLocalMutable(ident: Ident): Boolean = vars(ident.name) - - def lhsForLabeledExpr(label: Ident): Tree = labeledExprLHSes(label.name) - - def isDefaultBreakTarget(label: String): Boolean = - defaultBreakTargets.contains(label) - - def withParams(params: List[ParamDef]): Env = { - params.foldLeft(this) { - case (env, ParamDef(name, tpe, mutable, _)) => - // ParamDefs may not contain record types - env.withDef(name, mutable) - } - } - - def withDef(ident: Ident, mutable: Boolean): Env = - copy(vars = vars + (ident.name -> mutable)) - - def withLabeledExprLHS(label: Ident, lhs: Tree): Env = - copy(labeledExprLHSes = labeledExprLHSes + (label.name -> lhs)) - - def withDefaultBreakTargets(targets: Set[String]): Env = - copy(defaultBreakTargets = targets) - - private def copy( - vars: Map[String, Boolean] = this.vars, - labeledExprLHSes: Map[String, Tree] = this.labeledExprLHSes, - defaultBreakTargets: Set[String] = this.defaultBreakTargets): Env = { - new Env(vars, labeledExprLHSes, defaultBreakTargets) - } - } - - object Env { - def empty: Env = new Env(Map.empty, Map.empty, Set.empty) - } - // Helpers private[emitter] def genLet(name: js.Ident, mutable: Boolean, rhs: js.Tree)( @@ -2454,3 +2415,65 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { "Exception while desugaring: " + writer.toString } } + +private object JSDesugaring { + /** A left hand side that can be pushed into a right hand side tree. */ + sealed abstract class Lhs { + def hasNothingType: Boolean = false + } + + object Lhs { + case class Assign(lhs: Tree) extends Lhs + case class VarDef(name: Ident, tpe: Type, mutable: Boolean) extends Lhs + + case class Return(label: Option[Ident]) extends Lhs { + override def hasNothingType: Boolean = true + } + + /** Discard the value of rhs (but retain side effects). */ + case object Discard extends Lhs + } + + // Environment + + final class Env private ( + vars: Map[String, Boolean], + labeledExprLHSes: Map[String, Lhs], + defaultBreakTargets: Set[String] + ) { + def isLocalMutable(ident: Ident): Boolean = vars(ident.name) + + def lhsForLabeledExpr(label: Ident): Lhs = labeledExprLHSes(label.name) + + def isDefaultBreakTarget(label: String): Boolean = + defaultBreakTargets.contains(label) + + def withParams(params: List[ParamDef]): Env = { + params.foldLeft(this) { + case (env, ParamDef(name, tpe, mutable, _)) => + // ParamDefs may not contain record types + env.withDef(name, mutable) + } + } + + def withDef(ident: Ident, mutable: Boolean): Env = + copy(vars = vars + (ident.name -> mutable)) + + def withLabeledExprLHS(label: Ident, lhs: Lhs): Env = + copy(labeledExprLHSes = labeledExprLHSes + (label.name -> lhs)) + + def withDefaultBreakTargets(targets: Set[String]): Env = + copy(defaultBreakTargets = targets) + + private def copy( + vars: Map[String, Boolean] = this.vars, + labeledExprLHSes: Map[String, Lhs] = this.labeledExprLHSes, + defaultBreakTargets: Set[String] = this.defaultBreakTargets): Env = { + new Env(vars, labeledExprLHSes, defaultBreakTargets) + } + } + + object Env { + def empty: Env = new Env(Map.empty, Map.empty, Set.empty) + } +} From 40b59fd9a694277b8b079bf5aa124b7a76890f24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 8 Oct 2016 21:20:22 +0200 Subject: [PATCH 0031/2665] Fix #2613: Replace `extends js.GlobalScope` by `@JSGlobalScope`. This prompted a lot of refactoring in `PrepJSInterop` to keep things DRY. In particular, all annotations related to the JS native load specs (i.e., `@JSName`, `@JSImport` and `@JSGlobalScope`) are now handled in (conceptually) the same way. Some discrepancies still exist to account for combinations that used not to be checked, as they need to warn instead of error out. --- .../org/scalajs/core/compiler/GenJSCode.scala | 4 + .../scalajs/core/compiler/JSDefinitions.scala | 1 + .../scalajs/core/compiler/PrepJSInterop.scala | 233 ++++++++++++------ .../core/compiler/test/JSInteropTest.scala | 85 +++++-- examples/helloworld/HelloWorld.scala | 5 +- .../scala/scala/scalajs/js/GlobalScope.scala | 1 + .../scala/scala/scalajs/js/URIUtils.scala | 5 +- .../scalajs/js/annotation/JSGlobalScope.scala | 20 ++ .../scala/scalajs/js/timers/RawTimers.scala | 4 +- project/BinaryIncompatibilities.scala | 11 + .../scalajs/testinterface/TestDetector.scala | 4 +- .../compiler/InteroperabilityTest.scala | 38 ++- 12 files changed, 313 insertions(+), 98 deletions(-) create mode 100644 library/src/main/scala/scala/scalajs/js/annotation/JSGlobalScope.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index e1186fd079..230852ff27 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -4929,6 +4929,10 @@ abstract class GenJSCode extends plugins.PluginComponent * and earlier. Since they did not store their loading spec in the IR, * the js.LoadJSModule() IR node cannot be used to load them. We must * "desugar" it early in the compiler. + * + * Moreover, before 0.6.13, these objects would not have the + * annotation @JSGlobalScope. Instead, they would inherit from the + * magical trait js.GlobalScope. */ if (sym.isSubClass(JSGlobalScopeClass)) { genLoadGlobal() diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 436d620bee..c0251fdd37 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -64,6 +64,7 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val JSExportAllAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportAll") lazy val JSExportNamedAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportNamed") lazy val JSImportAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSImport") + lazy val JSGlobalScopeAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSGlobalScope") lazy val ScalaJSDefinedAnnotation = getRequiredClass("scala.scalajs.js.annotation.ScalaJSDefined") lazy val SJSDefinedAnonymousClassAnnotation = getRequiredClass("scala.scalajs.js.annotation.SJSDefinedAnonymousClass") lazy val HasJSNativeLoadSpecAnnotation = getRequiredClass("scala.scalajs.js.annotation.internal.HasJSNativeLoadSpec") diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 2b5036d785..6e677501f4 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -454,6 +454,26 @@ abstract class PrepJSInterop extends plugins.PluginComponent sym.addAnnotation(SJSDefinedAnonymousClassAnnotation) } + /* Convert `extends js.GlobalScope` to `@JSGlobalScope`. + * No warning because `js.GlobalScope` already causes a deprecation + * warning. + * + * Note that due to an implementation detail of `addAnnotation()`, this + * will add `@JSGlobalScope` *before* all user-defined annotations. This + * is what we want here. The association `extends js.GlobalScope` + + * `@JSName` used not to be checked, in which case `js.GlobalScope` took + * precedence. The fact that `@JSGlobalScope` appears first in this case + * allows us to more easily preserve this behavior in + * `checkAndGetJSNativeLoadingSpecAnnotOf()`. + */ + if (sym.isSubClass(JSGlobalScopeClass) && sym != JSGlobalScopeClass) { + val annotInfo = { + AnnotationInfo(JSGlobalScopeAnnotation.tpe, Nil, Nil) + .setPos(implDef.pos) + } + sym.addAnnotation(annotInfo) + } + val isJSNative = !sym.hasAnnotation(ScalaJSDefinedAnnotation) if (sym.isPackageObjectClass) { @@ -539,54 +559,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent * and (in 2.10) the original owner chain. We store it in a global * map. */ - val loadSpec = { - if (enclosingOwner is OwnerKind.JSNativeMod) { - val ownerLoadSpec = jsInterop.jsNativeLoadSpecOf(sym.owner) - val jsName = jsInterop.jsNameOf(sym) - ownerLoadSpec match { - case JSNativeLoadSpec.Global(path) => - JSNativeLoadSpec.Global(path :+ jsName) - case JSNativeLoadSpec.Import(module, path) => - JSNativeLoadSpec.Import(module, path :+ jsName) - } - } else if (isJSGlobalScope(implDef)) { - JSNativeLoadSpec.Global(Nil) - } else if (sym.hasAnnotation(JSImportAnnotation)) { - val annot = sym.getAnnotation(JSImportAnnotation).get - val module = annot.stringArg(0).getOrElse { - "" // do not care because it does not compile anyway - } - annot.stringArg(1).fold { - JSNativeLoadSpec.Import(module, Nil) - } { pathName => - val path = pathName.split('.').toList - JSNativeLoadSpec.Import(module, path) - } - } else { - val needsExplicitJSName = { - (enclosingOwner is OwnerKind.ScalaMod) && - !sym.owner.isPackageObjectClass - } - - if (needsExplicitJSName && !sym.hasAnnotation(JSNameAnnotation)) { - if (sym.isModuleClass) { - reporter.error(implDef.pos, - "Native JS objects inside non-native objects must " + - "have an @JSName or @JSImport annotation") - } else { - // This should be an error, but we erroneously allowed that before - reporter.warning(implDef.pos, - "Native JS classes inside non-native objects should " + - "have an @JSName or @JSImport annotation. " + - "This will be enforced in 1.0.") - } - } - - val path = jsInterop.jsNameOf(sym).split('.').toList - JSNativeLoadSpec.Global(path) - } - } - + val loadSpec = checkAndComputeJSNativeLoadSpecOf(implDef.pos, sym) jsInterop.storeJSNativeLoadSpec(sym, loadSpec) // Mark module classes as having the new format @@ -594,35 +567,23 @@ abstract class PrepJSInterop extends plugins.PluginComponent sym.addAnnotation(HasJSNativeLoadSpecAnnotation) } else { assert(sym.isTrait) // just tested in the previous `if` - if (sym.hasAnnotation(JSNameAnnotation)) { - reporter.warning(implDef.pos, - "Traits should not have an @JSName annotation, as it does " + - "not have any effect. This will be enforced in 1.0.") - } - if (sym.hasAnnotation(JSImportAnnotation)) { - reporter.error(implDef.pos, - "Traits may not have an @JSImport annotation") + for { + annot <- sym.annotations + annotSym = annot.symbol + if JSNativeLoadingSpecAnnots.contains(annotSym) + } { + if (annotSym == JSNameAnnotation) { + reporter.warning(annot.pos, + "Traits should not have an @JSName annotation, as it does " + + "not have any effect. This will be enforced in 1.0.") + } else { + reporter.error(annot.pos, + s"Traits may not have an @${annotSym.nameString} annotation.") + } } } } - // Checks for things that extend js.GlobalScope - if (isJSGlobalScope(implDef) && implDef.symbol != JSGlobalScopeClass) { - // Only native objects may extend js.GlobalScope - if (!sym.isModuleClass || !isJSNative) { - reporter.error(implDef.pos, - "Only native objects may extend js.GlobalScope") - } else if (sym.hasAnnotation(JSNameAnnotation)) { - reporter.warning(implDef.pos, "Objects extending js.GlobalScope " + - "should not have a @JSName annotation. This will be enforced " + - "in 1.0.") - } else if (sym.hasAnnotation(JSImportAnnotation)) { - reporter.error(implDef.pos, - "Objects extending js.GlobalScope cannot have an @JSImport " + - "annotation.") - } - } - if (shouldPrepareExports) { if (sym.isTrait) { // Check that interface/trait is not exported @@ -688,6 +649,81 @@ abstract class PrepJSInterop extends plugins.PluginComponent enterOwner(kind) { super.transform(implDef) } } + private def checkAndComputeJSNativeLoadSpecOf(pos: Position, + sym: Symbol): JSNativeLoadSpec = { + if (enclosingOwner is OwnerKind.JSNativeMod) { + for { + annot <- sym.annotations + annotSym = annot.symbol + if annotSym != JSNameAnnotation && JSNativeLoadingSpecAnnots.contains(annotSym) + } { + reporter.error(annot.pos, + "Classes and objects nested in a JS native object cannot have " + + s"an ${annotSym.nameString} annotation.") + } + + val ownerLoadSpec = jsInterop.jsNativeLoadSpecOf(sym.owner) + val jsName = jsInterop.jsNameOf(sym) + ownerLoadSpec match { + case JSNativeLoadSpec.Global(path) => + JSNativeLoadSpec.Global(path :+ jsName) + case JSNativeLoadSpec.Import(module, path) => + JSNativeLoadSpec.Import(module, path :+ jsName) + } + } else { + def globalFromName = { + val path = jsInterop.jsNameOf(sym).split('.').toList + JSNativeLoadSpec.Global(path) + } + + checkAndGetJSNativeLoadingSpecAnnotOf(sym) match { + case Some(annot) if annot.symbol == JSGlobalScopeAnnotation => + if (!sym.isModuleClass) { + reporter.error(annot.pos, + "Only native JS objects can have an " + + "@JSGlobalScope annotation (or extend js.GlobalScope).") + } + JSNativeLoadSpec.Global(Nil) + + case Some(annot) if annot.symbol == JSImportAnnotation => + val module = annot.stringArg(0).getOrElse { + "" // do not care because it does not compile anyway + } + annot.stringArg(1).fold { + JSNativeLoadSpec.Import(module, Nil) + } { pathName => + val path = pathName.split('.').toList + JSNativeLoadSpec.Import(module, path) + } + + case Some(annot) if annot.symbol == JSNameAnnotation => + globalFromName + + case None => + val needsExplicitJSName = { + (enclosingOwner is OwnerKind.ScalaMod) && + !sym.owner.isPackageObjectClass + } + + if (needsExplicitJSName) { + if (sym.isModuleClass) { + reporter.error(pos, + "Native JS objects inside non-native objects must " + + "have an @JSName or @JSImport annotation") + } else { + // This should be an error, but we erroneously allowed that before + reporter.warning(pos, + "Native JS classes inside non-native objects should " + + "have an @JSName or @JSImport annotation. " + + "This will be enforced in 1.0.") + } + } + + globalFromName + } + } + } + /** Verify a ValOrDefDef inside a js.Any */ private def transformValOrDefDefInRawJSType(tree: ValOrDefDef) = { val sym = tree.symbol @@ -919,9 +955,6 @@ abstract class PrepJSInterop extends plugins.PluginComponent private def isJSAny(implDef: ImplDef): Boolean = isJSAny(implDef.symbol) - private def isJSGlobalScope(implDef: ImplDef) = - implDef.symbol.tpe.typeSymbol isSubClass JSGlobalScopeClass - private def isJSLambda(sym: Symbol) = sym.isAnonymousClass && AllJSFunctionClasses.exists(sym.tpe.typeSymbol isSubClass _) @@ -1104,10 +1137,58 @@ abstract class PrepJSInterop extends plugins.PluginComponent reporter.error(annot.pos, "Non JS-native classes, traits and objects may not have an " + "@JSImport annotation.") + } else if (annot.symbol == JSGlobalScopeAnnotation) { + reporter.error(annot.pos, + "Only native JS objects can have an @JSGlobalScope annotation " + + "(or extend js.GlobalScope).") } } } + private def checkAndGetJSNativeLoadingSpecAnnotOf( + sym: Symbol): Option[Annotation] = { + val annots = sym.annotations.filter { annot => + JSNativeLoadingSpecAnnots.contains(annot.symbol) + } + + annots match { + case Nil => + None + + case result :: duplicates => + for (annot <- duplicates) { + if (annot.symbol == JSNameAnnotation && + result.symbol == JSNameAnnotation) { + // This used not to be checked, so we can only warn + reporter.warning(annot.pos, + "A duplicate @JSName annotation is ignored, and should be " + + "removed. This will be enforced in 1.0.") + } else if (annot.symbol == JSNameAnnotation && + result.symbol == JSGlobalScopeAnnotation) { + /* This used not to be checked for `extends js.GlobalScope`, so we + * can only warn. See the comment where we deal with the legacy + * `extends js.GlobalScope` for the reason why we do not need to + * deal with the converse case (i.e., `@JSGlobalScope` always comes + * before `@JSName` in this case. + */ + reporter.warning(annot.pos, + "An @JSName annotation is ignored in the presence of " + + "@JSGlobalScope (or extends js.GlobalScope), and should be " + + "removed. This will be enforced in 1.0.") + } else { + reporter.error(annot.pos, + "Native JS classes and objects can only have one annotation " + + "among JSName, JSImport and JSGlobalScope (extending " + + "js.GlobalScope is treated as having @JSGlobalScope).") + } + } + Some(result) + } + } + + private lazy val JSNativeLoadingSpecAnnots: Set[Symbol] = + Set(JSNameAnnotation, JSImportAnnotation, JSGlobalScopeAnnotation) + private lazy val ScalaEnumClass = getRequiredClass("scala.Enumeration") private lazy val WasPublicBeforeTyperClass = getRequiredClass("scala.scalajs.js.annotation.WasPublicBeforeTyper") diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index 6bf731b2ce..0d6e8d2450 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -15,6 +15,12 @@ class JSInteropTest extends DirectTest with TestHelpers { import scala.scalajs.js.annotation._ """ + private val JSNativeLoadSpecAnnots = Seq( + "JSName" -> "@JSName(\"foo\")", + "JSImport" -> "@JSImport(\"foo\", \"bar\")", + "JSGlobalScope" -> "@JSGlobalScope" + ) + @Test def warnNoJSNativeAnnotation: Unit = { @@ -144,9 +150,9 @@ class JSInteropTest extends DirectTest with TestHelpers { trait A extends js.Object """ hasWarns s""" - |newSource1.scala:7: warning: Traits should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. - | trait A extends js.Object - | ^ + |newSource1.scala:6: warning: Traits should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. + | @JSName("foo") + | ^ """ } @@ -160,13 +166,62 @@ class JSInteropTest extends DirectTest with TestHelpers { trait A extends js.Object """ hasErrors s""" - |newSource1.scala:7: error: Traits may not have an @JSImport annotation - | trait A extends js.Object - | ^ + |newSource1.scala:6: error: Traits may not have an @JSImport annotation. + | @JSImport("foo", JSImport.Namespace) + | ^ """ } + @Test def noTwoJSNativeLoadSpecAnnots: Unit = { + for { + (firstAnnotName, firstAnnot) <- JSNativeLoadSpecAnnots + (secondAnnotName, secondAnnot) <- JSNativeLoadSpecAnnots + } { + val expectedMessageShort = { + if (firstAnnotName == "JSName" && secondAnnotName == firstAnnotName) + "warning: A duplicate @JSName annotation is ignored, and should be removed. This will be enforced in 1.0." + else if (firstAnnotName == "JSGlobalScope" && secondAnnotName == "JSName") + "warning: An @JSName annotation is ignored in the presence of @JSGlobalScope (or extends js.GlobalScope), and should be removed. This will be enforced in 1.0." + else + "error: Native JS classes and objects can only have one annotation among JSName, JSImport and JSGlobalScope (extending js.GlobalScope is treated as having @JSGlobalScope)." + } + + val onlyWarn = expectedMessageShort.startsWith("warning: ") + + val expectedMessage = { + s""" + |newSource1.scala:7: $expectedMessageShort + |$secondAnnot + | ^ + """ + } + + val kinds = { + if (firstAnnotName == "JSGlobalScope" || secondAnnotName == "JSGlobalScope") + Seq("object") + else + Seq("class", "object") + } + + for (kind <- kinds) { + val snippet = { + s""" + |@js.native + |$firstAnnot + |$secondAnnot + |$kind A extends js.Object + """.stripMargin + } + + if (onlyWarn) + snippet hasWarns expectedMessage + else + snippet hasErrors expectedMessage + } + } + } + @Test def noJSNativeAnnotWithoutJSAny: Unit = { @@ -474,7 +529,7 @@ class JSInteropTest extends DirectTest with TestHelpers { class A extends js.GlobalScope """ hasErrors """ - |newSource1.scala:6: error: Only native objects may extend js.GlobalScope + |newSource1.scala:6: error: Only native JS objects can have an @JSGlobalScope annotation (or extend js.GlobalScope). | class A extends js.GlobalScope | ^ """ @@ -484,7 +539,7 @@ class JSInteropTest extends DirectTest with TestHelpers { trait A extends js.GlobalScope """ hasErrors """ - |newSource1.scala:6: error: Only native objects may extend js.GlobalScope + |newSource1.scala:6: error: Traits may not have an @JSGlobalScope annotation. | trait A extends js.GlobalScope | ^ """ @@ -528,11 +583,11 @@ class JSInteropTest extends DirectTest with TestHelpers { @js.native @JSName("foo") object Bar extends js.GlobalScope - """ hasWarns + """ containsWarns """ - |newSource1.scala:7: warning: Objects extending js.GlobalScope should not have a @JSName annotation. This will be enforced in 1.0. - | object Bar extends js.GlobalScope - | ^ + |newSource1.scala:6: warning: An @JSName annotation is ignored in the presence of @JSGlobalScope (or extends js.GlobalScope), and should be removed. This will be enforced in 1.0. + | @JSName("foo") + | ^ """ } @@ -546,9 +601,9 @@ class JSInteropTest extends DirectTest with TestHelpers { object Bar extends js.GlobalScope """ hasErrors """ - |newSource1.scala:7: error: Objects extending js.GlobalScope cannot have an @JSImport annotation. - | object Bar extends js.GlobalScope - | ^ + |newSource1.scala:6: error: Native JS classes and objects can only have one annotation among JSName, JSImport and JSGlobalScope (extending js.GlobalScope is treated as having @JSGlobalScope). + | @JSImport("foo", JSImport.Namespace) + | ^ """ } diff --git a/examples/helloworld/HelloWorld.scala b/examples/helloworld/HelloWorld.scala index e3632781f1..54751982dd 100644 --- a/examples/helloworld/HelloWorld.scala +++ b/examples/helloworld/HelloWorld.scala @@ -6,7 +6,7 @@ package helloworld import scala.scalajs.js -import js.annotation.JSName +import js.annotation._ object HelloWorld extends js.JSApp { def main() { @@ -56,7 +56,8 @@ object HelloWorld extends js.JSApp { } @js.native -object window extends js.GlobalScope { +@JSGlobalScope +object window extends js.Object { val document: DOMDocument = js.native def alert(msg: String): Unit = js.native diff --git a/library/src/main/scala/scala/scalajs/js/GlobalScope.scala b/library/src/main/scala/scala/scalajs/js/GlobalScope.scala index 5173d09262..d077409d83 100644 --- a/library/src/main/scala/scala/scalajs/js/GlobalScope.scala +++ b/library/src/main/scala/scala/scalajs/js/GlobalScope.scala @@ -18,5 +18,6 @@ package scala.scalajs.js * * @see [[http://www.scala-js.org/doc/calling-javascript.html Calling JavaScript from Scala.js]] */ +@deprecated("Use the annotation @js.annotation.JSGlobalScope instead.", "0.6.13") @native trait GlobalScope extends Any diff --git a/library/src/main/scala/scala/scalajs/js/URIUtils.scala b/library/src/main/scala/scala/scalajs/js/URIUtils.scala index 0f5d419b82..ec102a3162 100644 --- a/library/src/main/scala/scala/scalajs/js/URIUtils.scala +++ b/library/src/main/scala/scala/scalajs/js/URIUtils.scala @@ -10,9 +10,12 @@ package scala.scalajs.js +import scala.scalajs.js.annotation.JSGlobalScope + /** Methods related to URIs, provided by ECMAScript 5.1. */ @native -object URIUtils extends GlobalScope { +@JSGlobalScope +object URIUtils extends Object { /** Decodes a Uniform Resource Identifier (URI). * @see [[encodeURI]] diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSGlobalScope.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSGlobalScope.scala new file mode 100644 index 0000000000..22eb8d4ec3 --- /dev/null +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSGlobalScope.scala @@ -0,0 +1,20 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js API ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package scala.scalajs.js.annotation + +/** Marks the annotated object as representing the JavaScript global scope. + * + * This is particularly useful to model top-level functions and fields that + * are in the JavaScript global scope. They can be declared inside an object + * annotated with `@JSGlobalScope`. + * + * @see [[http://www.scala-js.org/doc/calling-javascript.html Calling JavaScript from Scala.js]] + */ +class JSGlobalScope extends scala.annotation.StaticAnnotation diff --git a/library/src/main/scala/scala/scalajs/js/timers/RawTimers.scala b/library/src/main/scala/scala/scalajs/js/timers/RawTimers.scala index de70e4ff14..25c53fbfdd 100644 --- a/library/src/main/scala/scala/scalajs/js/timers/RawTimers.scala +++ b/library/src/main/scala/scala/scalajs/js/timers/RawTimers.scala @@ -10,6 +10,7 @@ package scala.scalajs.js.timers import scala.scalajs.js +import js.annotation.JSGlobalScope /** * Non-Standard @@ -20,7 +21,8 @@ import scala.scalajs.js * [[timers]] as they are more Scala-like. */ @js.native -object RawTimers extends js.GlobalScope { +@JSGlobalScope +object RawTimers extends js.Object { /** Schedule `handler` for execution in `interval` milliseconds. * diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 0ee477b3a1..160b0d609a 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -106,6 +106,17 @@ object BinaryIncompatibilities { ) val Library = Seq( + /* Technically breaking: remove `extends js.GlobalScope`. + * Even though not binary compatible at .class file level, this is binary + * compatible at the .sjsir level, because the parent js.GlobalScope is + * a JS type, so its IR type is `any` anyway. + * It is however not source compatible, but I'm willing to break the code + * of someone who would have declared a value of type js.GlobalScope. + */ + ProblemFilters.exclude[MissingTypesProblem]( + "scala.scalajs.js.URIUtils$"), + ProblemFilters.exclude[MissingTypesProblem]( + "scala.scalajs.js.timers.RawTimers$") ) val TestInterface = Seq( diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala b/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala index 52f6d10121..1fecfaddfd 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala @@ -1,6 +1,7 @@ package org.scalajs.testinterface import scala.scalajs.js +import js.annotation.JSGlobalScope import org.scalajs.testinterface.internal.TaskDefSerializer @@ -53,7 +54,8 @@ private[scalajs] object TestDetector { } @js.native - private object RawDefinitions extends js.GlobalScope { + @JSGlobalScope + private object RawDefinitions extends js.Object { val definedTests: js.Array[js.Dynamic] = js.native val testFrameworkNames: js.Array[js.Array[String]] = js.native } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala index d3540bcc9d..ed231c3de8 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala @@ -305,7 +305,7 @@ class InteroperabilityTest { assertArrayEquals(Array("plop", 42, 51), new C(elems: _*).args) } - @Test def should_acces_top_level_JS_objects_via_Scala_object_inheriting_from_js_GlobalScope(): Unit = { + @Test def should_acces_top_level_JS_objects_via_Scala_object_with_annot_JSGlobalScope(): Unit = { js.eval(""" var interoperabilityTestGlobalScopeValue = "7357"; var interoperabilityTestGlobalScopeValueAsInt = function() { @@ -323,6 +323,29 @@ class InteroperabilityTest { assertEquals(42, Global.interoperabilityTestGlobalScopeValueAsInt) } + @Test def should_acces_top_level_JS_objects_via_Scala_object_inheriting_from_js_GlobalScope(): Unit = { + js.eval(""" + var interoperabilityTestGlobalScopeDeprecatedValue = "7357"; + var interoperabilityTestGlobalScopeDeprecatedValueAsInt = function() { + return parseInt(interoperabilityTestGlobalScopeDeprecatedValue); + }; + """) + + // Use alias for convenience: see end of file for definition + val Global = InteroperabilityTestGlobalScopeDeprecated + + assertEquals("7357", Global.interoperabilityTestGlobalScopeDeprecatedValue) + assertEquals(7357, Global.interoperabilityTestGlobalScopeDeprecatedValueAsInt) + + Global.interoperabilityTestGlobalScopeDeprecatedValue = "42" + assertEquals(42, Global.interoperabilityTestGlobalScopeDeprecatedValueAsInt) + } + + @Test def extends_js_GlobalScope_takes_precedence_over_JSName(): Unit = { + assertSame(js.Dynamic.global, + InteroperabilityTestGlobalScopeDeprecatedWithJSName) + } + @Test def should_protect_receiver_of_raw_JS_apply_if_its_a_select_issue_804(): Unit = { val rawReceiver = js.eval(""" var interoperabilityTestRawReceiver = { @@ -731,11 +754,22 @@ class InteroperabilityTestVariadicCtor(inargs: Any*) extends js.Object { } @js.native -object InteroperabilityTestGlobalScope extends js.GlobalScope { +@JSGlobalScope +object InteroperabilityTestGlobalScope extends js.Object { var interoperabilityTestGlobalScopeValue: String = js.native def interoperabilityTestGlobalScopeValueAsInt(): Int = js.native } +@js.native +object InteroperabilityTestGlobalScopeDeprecated extends js.GlobalScope { + var interoperabilityTestGlobalScopeDeprecatedValue: String = js.native + def interoperabilityTestGlobalScopeDeprecatedValueAsInt(): Int = js.native +} + +@js.native +@JSName("ThisDoesNotExistButItIsIgnored") +object InteroperabilityTestGlobalScopeDeprecatedWithJSName extends js.GlobalScope + class SomeValueClass(val i: Int) extends AnyVal { override def toString(): String = s"SomeValueClass($i)" } From 5805448b778a7ef1f0a3bf9abd95682ac980134f Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 8 Oct 2016 19:45:54 +0200 Subject: [PATCH 0032/2665] Make allocation sites always optional --- project/BinaryIncompatibilities.scala | 18 ++++- .../frontend/optimizer/OptimizerCore.scala | 75 ++++++++++++------- 2 files changed, 63 insertions(+), 30 deletions(-) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index d2fbc309e5..0f46dfae18 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -84,7 +84,23 @@ object BinaryIncompatibilities { // private[emitter], not an issue ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.CoreJSLibs.lib") + "org.scalajs.core.tools.linker.backend.emitter.CoreJSLibs.lib"), + + // private, not an issue + ProblemFilters.exclude[AbstractClassProblem]( + "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore$AllocationSite"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#AllocationSite.this"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#RefinedType.apply"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#RefinedType.apply"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#RefinedType.copy"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#RefinedType.allocationSite"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#RefinedType.this") ) val JSEnvs = Seq( diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index 381b69f687..bb9bfbb6a8 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -814,7 +814,7 @@ private[optimizer] abstract class OptimizerCore( case New(cls, ctor, args) => pretransformExprs(args) { targs => - pretransformNew(tree, cls, ctor, targs)(cont) + pretransformNew(AllocationSite.Tree(tree), cls, ctor, targs)(cont) } case tree: Select => @@ -1073,17 +1073,15 @@ private[optimizer] abstract class OptimizerCore( } } - private def pretransformNew(tree: Tree, cls: ClassType, ctor: Ident, - targs: List[PreTransform])( - cont: PreTransCont)( + private def pretransformNew(allocationSite: AllocationSite, cls: ClassType, + ctor: Ident, targs: List[PreTransform])(cont: PreTransCont)( implicit scope: Scope, pos: Position): TailRec[Tree] = { tryNewInlineableClass(cls.className) match { case Some(initialValue) => tryOrRollback { cancelFun => - inlineClassConstructor( - new AllocationSite(tree), - cls, initialValue, ctor, targs, cancelFun)(cont) + inlineClassConstructor(allocationSite, cls, initialValue, + ctor, targs, cancelFun)(cont) } { () => cont(PreTransTree( New(cls, ctor, targs.map(finishTransformExpr)), @@ -1678,7 +1676,7 @@ private[optimizer] abstract class OptimizerCore( } } - private def inline(allocationSites: List[Option[AllocationSite]], + private def inline(allocationSites: List[AllocationSite], optReceiver: Option[PreTransform], args: List[PreTransform], target: MethodID, isStat: Boolean, usePreTransform: Boolean)( @@ -1971,8 +1969,9 @@ private[optimizer] abstract class OptimizerCore( private def boxChar(value: Tree)( cont: PreTransCont)( implicit scope: Scope, pos: Position): TailRec[Tree] = { - pretransformNew(value, ClassType(Definitions.BoxedCharacterClass), - Ident("init___C"), List(value.toPreTransform))(cont) + pretransformNew(AllocationSite.Tree(value), + ClassType(Definitions.BoxedCharacterClass), Ident("init___C"), + List(value.toPreTransform))(cont) } private def unboxChar(tvalue: PreTransform)( @@ -2014,7 +2013,7 @@ private[optimizer] abstract class OptimizerCore( cls, cls, ctor, args, cancelFun) { (finalFieldLocalDefs, cont2) => cont2(LocalDef( RefinedType(cls, isExact = true, isNullable = false, - allocationSite = Some(allocationSite)), + allocationSite = allocationSite), mutable = false, InlineClassInstanceReplacement(recordType, finalFieldLocalDefs, cancelFun)).toPreTransform) @@ -2033,7 +2032,7 @@ private[optimizer] abstract class OptimizerCore( implicit scope: Scope): TailRec[Tree] = tailcall { val target = staticCall(ctorClass.className, ctor.name).getOrElse(cancelFun()) - val targetID = (Some(allocationSite) :: args.map(_.tpe.allocationSite), target) + val targetID = (allocationSite :: args.map(_.tpe.allocationSite), target) if (scope.implsBeingInlined.contains(targetID)) cancelFun() @@ -2344,7 +2343,7 @@ private[optimizer] abstract class OptimizerCore( (op: @switch) match { case IntToLong => - pretransformNew(EmptyTree, rtLongClassType, + pretransformNew(AllocationSite.Anonymous, rtLongClassType, Ident(LongImpl.initFromInt), arg :: Nil)( cont) @@ -3609,7 +3608,7 @@ private[optimizer] abstract class OptimizerCore( val allLocalDefs = thisLocalDef ++: paramLocalDefs - val allocationSites = List.fill(allLocalDefs.size)(None) + val allocationSites = List.fill(allLocalDefs.size)(AllocationSite.Anonymous) val scope0 = optTarget.fold(Scope.Empty)( target => Scope.Empty.inlining((allocationSites, target))) val scope = scope0.withEnv(OptEnv.Empty.withLocalDefs(allLocalDefs)) @@ -4010,19 +4009,18 @@ private[optimizer] object OptimizerCore { private type PreTransCont = PreTransform => TailRec[Tree] private case class RefinedType private (base: Type, isExact: Boolean, - isNullable: Boolean)( - val allocationSite: Option[AllocationSite], dummy: Int = 0) { + isNullable: Boolean)(val allocationSite: AllocationSite, dummy: Int = 0) { def isNothingType: Boolean = base == NothingType } private object RefinedType { def apply(base: Type, isExact: Boolean, isNullable: Boolean, - allocationSite: Option[AllocationSite]): RefinedType = + allocationSite: AllocationSite): RefinedType = new RefinedType(base, isExact, isNullable)(allocationSite) def apply(base: Type, isExact: Boolean, isNullable: Boolean): RefinedType = - RefinedType(base, isExact, isNullable, None) + RefinedType(base, isExact, isNullable, AllocationSite.Anonymous) def apply(tpe: Type): RefinedType = tpe match { case IntType | FloatType | DoubleType => @@ -4040,17 +4038,37 @@ private[optimizer] object OptimizerCore { val Nothing = RefinedType(NothingType) } - private class AllocationSite(private val node: Tree) { - override def equals(that: Any): Boolean = that match { - case that: AllocationSite => this.node eq that.node - case _ => false + /** + * Global, lexical identity of an inlined object, given by the source + * location of its allocation. + * + * A crucial property of AllocationSite is that there is a finite amount of + * them, function of the program source. It is not permitted to create + * AllocationSites out of trees generated by the optimizer, as it would + * potentially grow the supply to an infinite amount. + */ + private sealed abstract class AllocationSite + + private object AllocationSite { + object Anonymous extends AllocationSite { + override def toString(): String = "AllocationSite()" } - override def hashCode(): Int = - System.identityHashCode(node) + def Tree(tree: Tree): AllocationSite = new TreeAllocationSite(tree) - override def toString(): String = - s"AllocationSite($node)" + private class TreeAllocationSite( + private val node: Tree) extends AllocationSite { + override def equals(that: Any): Boolean = that match { + case that: TreeAllocationSite => this.node eq that.node + case _ => false + } + + override def hashCode(): Int = + System.identityHashCode(node) + + override def toString(): String = + s"AllocationSite($node)" + } } private case class LocalDef( @@ -4187,12 +4205,11 @@ private[optimizer] object OptimizerCore { } private class Scope(val env: OptEnv, - val implsBeingInlined: Set[(List[Option[AllocationSite]], AbstractMethodID)]) { + val implsBeingInlined: Set[(List[AllocationSite], AbstractMethodID)]) { def withEnv(env: OptEnv): Scope = new Scope(env, implsBeingInlined) - def inlining(impl: (List[Option[AllocationSite]], - AbstractMethodID)): Scope = { + def inlining(impl: (List[AllocationSite], AbstractMethodID)): Scope = { assert(!implsBeingInlined(impl), s"Circular inlining of $impl") new Scope(env, implsBeingInlined + impl) } From 59cbf76c6f5dfce8d571c1b57c5ade62cded6e1f Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 8 Oct 2016 20:09:37 +0200 Subject: [PATCH 0033/2665] Do not rely on EmptyTree in patmat code --- .../org/scalajs/core/compiler/GenJSCode.scala | 65 ++++++++++--------- .../frontend/optimizer/OptimizerCore.scala | 62 ++++++++++-------- 2 files changed, 70 insertions(+), 57 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index e1186fd079..30b7385029 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -2585,14 +2585,13 @@ abstract class GenJSCode extends plugins.PluginComponent }.getOrElse(NoSymbol) var clauses: List[(List[js.Literal], js.Tree)] = Nil - var elseClause: js.Tree = js.EmptyTree - - var elseClauseLabel: Option[js.Ident] = None + var optElseClause: Option[js.Tree] = None + var optElseClauseLabel: Option[js.Ident] = None def genJumpToElseClause(implicit pos: ir.Position): js.Tree = { - if (elseClauseLabel.isEmpty) - elseClauseLabel = Some(freshLocalIdent("default")) - js.Return(js.Undefined(), elseClauseLabel) + if (optElseClauseLabel.isEmpty) + optElseClauseLabel = Some(freshLocalIdent("default")) + js.Return(js.Undefined(), optElseClauseLabel) } for (caze @ CaseDef(pat, guard, body) <- cases) { @@ -2643,12 +2642,12 @@ abstract class GenJSCode extends plugins.PluginComponent case lit: Literal => clauses = (List(genLiteral(lit)), genBody(body)) :: clauses case Ident(nme.WILDCARD) => - elseClause = body match { + optElseClause = Some(body match { case LabelDef(_, Nil, rhs) if hasSynthCaseSymbol(body) => genBody(rhs) case _ => genBody(body) - } + }) case Alternative(alts) => val genAlts = { alts map { @@ -2665,9 +2664,12 @@ abstract class GenJSCode extends plugins.PluginComponent } } - if (elseClauseLabel.isEmpty) { + val elseClause = optElseClause.getOrElse( + throw new AssertionError("No elseClause in pattern match")) + + optElseClauseLabel.fold[js.Tree] { js.Match(expr, clauses.reverse, elseClause)(resultType) - } else { + } { elseClauseLabel => val matchResultLabel = freshLocalIdent("matchResult") val patchedClauses = for ((alts, body) <- clauses) yield { implicit val pos = body.pos @@ -2678,7 +2680,7 @@ abstract class GenJSCode extends plugins.PluginComponent (alts, newBody) } js.Labeled(matchResultLabel, resultType, js.Block(List( - js.Labeled(elseClauseLabel.get, jstpe.NoType, { + js.Labeled(elseClauseLabel, jstpe.NoType, { js.Match(expr, patchedClauses.reverse, js.Skip())(jstpe.NoType) }), elseClause @@ -2837,45 +2839,48 @@ abstract class GenJSCode extends plugins.PluginComponent def genOptimizedLabeled(label: js.Ident, tpe: jstpe.Type, translatedCases: List[js.Tree], returnCount: Int)( implicit pos: Position): js.Tree = { - def default = + def default: js.Tree = js.Labeled(label, tpe, js.Block(translatedCases)) @tailrec def createRevAlts(xs: List[js.Tree], - acc: List[(js.Tree, js.Tree)]): List[(js.Tree, js.Tree)] = xs match { + acc: List[(js.Tree, js.Tree)]): (List[(js.Tree, js.Tree)], js.Tree) = xs match { case js.If(cond, body, js.Skip()) :: xr => createRevAlts(xr, (cond, body) :: acc) case remaining => - (js.EmptyTree, js.Block(remaining)(remaining.head.pos)) :: acc + (acc, js.Block(remaining)(remaining.head.pos)) } - val revAlts = createRevAlts(translatedCases, Nil) + val (revAlts, elsep) = createRevAlts(translatedCases, Nil) + + if (revAlts.size == returnCount - 1) { + def tryDropReturn(body: js.Tree): Option[js.Tree] = body match { + case jse.BlockOrAlone(prep, js.Return(result, Some(`label`))) => + Some(js.Block(prep :+ result)(body.pos)) + + case _ => + None + } - if (revAlts.size == returnCount) { @tailrec def constructOptimized(revAlts: List[(js.Tree, js.Tree)], elsep: js.Tree): js.Tree = { revAlts match { case (cond, body) :: revAltsRest => - body match { - case jse.BlockOrAlone(prep, - js.Return(result, Some(`label`))) => - val prepAndResult = js.Block(prep :+ result)(body.pos) - if (cond == js.EmptyTree) { - assert(elsep == js.EmptyTree) - constructOptimized(revAltsRest, prepAndResult) - } else { - assert(elsep != js.EmptyTree) - constructOptimized(revAltsRest, - js.If(cond, prepAndResult, elsep)(tpe)(cond.pos)) - } - case _ => + // cannot use flatMap due to tailrec + tryDropReturn(body) match { + case Some(newBody) => + constructOptimized(revAltsRest, + js.If(cond, newBody, elsep)(tpe)(cond.pos)) + + case None => default } case Nil => elsep } } - constructOptimized(revAlts, js.EmptyTree) + + tryDropReturn(elsep).fold(default)(constructOptimized(revAlts, _)) } else { default } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index bb9bfbb6a8..b6ebfad66c 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -3702,49 +3702,57 @@ private[optimizer] abstract class OptimizerCore( * GenJSCode.genOptimizedLabeled. */ def tryOptimizePatternMatch(oldLabelName: String, refinedType: Type, - returnCount: Int, newBody: Tree): Option[Tree] = { - if (!oldLabelName.startsWith("matchEnd")) None - else { - newBody match { + returnCount: Int, body: Tree): Option[Tree] = { + if (!oldLabelName.startsWith("matchEnd")) { + None + } else { + body match { case Block(stats) => @tailrec - def createRevAlts(xs: List[Tree], acc: List[(Tree, Tree)]): List[(Tree, Tree)] = xs match { + def createRevAlts(xs: List[Tree], + acc: List[(Tree, Tree)]): (List[(Tree, Tree)], Tree) = xs match { case If(cond, body, Skip()) :: xr => createRevAlts(xr, (cond, body) :: acc) case remaining => - (EmptyTree, Block(remaining)(remaining.head.pos)) :: acc + (acc, Block(remaining)(remaining.head.pos)) } - val revAlts = createRevAlts(stats, Nil) + val (revAlts, elsep) = createRevAlts(stats, Nil) + + if (revAlts.size == returnCount - 1) { + def tryDropReturn(body: Tree): Option[Tree] = body match { + case BlockOrAlone(prep, Return(result, Some(_))) => + val result1 = + if (refinedType == NoType) keepOnlySideEffects(result) + else result + Some(Block(prep :+ result1)(body.pos)) + + case _ => + None + } - if (revAlts.size == returnCount) { @tailrec - def constructOptimized(revAlts: List[(Tree, Tree)], elsep: Tree): Option[Tree] = { + def constructOptimized(revAlts: List[(Tree, Tree)], + elsep: Tree): Option[Tree] = { revAlts match { case (cond, body) :: revAltsRest => - body match { - case BlockOrAlone(prep, - Return(result, Some(Ident(newLabel, _)))) => - val result1 = - if (refinedType == NoType) keepOnlySideEffects(result) - else result - val prepAndResult = Block(prep :+ result1)(body.pos) - if (cond == EmptyTree) { - assert(elsep == EmptyTree) - constructOptimized(revAltsRest, prepAndResult) - } else { - assert(elsep != EmptyTree) - constructOptimized(revAltsRest, - foldIf(cond, prepAndResult, elsep)(refinedType)(cond.pos)) - } - case _ => + // cannot use flatMap due to tailrec + tryDropReturn(body) match { + case Some(newBody) => + constructOptimized(revAltsRest, + foldIf(cond, newBody, elsep)(refinedType)(cond.pos)) + + case None => None } case Nil => Some(elsep) } } - constructOptimized(revAlts, EmptyTree) - } else None + + tryDropReturn(elsep).flatMap(constructOptimized(revAlts, _)) + } else { + None + } case _ => None } From 19f411409649b01db6c68249e6f9cd26e16d2e7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 12 Oct 2016 16:30:19 +0200 Subject: [PATCH 0034/2665] Fix #2625: Fix clash of outer pointers in 2.12.0-RC2 onwards. The root cause of the bug #2625 which surfaces in 2.12.0 is actually #2382. We cannot fix #2382 without breaking backwards binary compatibility in general. However, we can fix it only for 2.12.0-RC2 onwards, as RCs of Scala (and the upcoming final) have separate binary ecosystems anyway. So this commit fixes #2382 but only for 2.12.0-RC2 onwards. The fix is trivial: name mangle all outer pointers in the same way as if they were private, i.e., with the number of class ancestors of its owner. --- .../scalajs/core/compiler/JSEncoding.scala | 27 +++- project/Build.scala | 25 +++ .../testsuite/compiler/OuterClassTest.scala | 146 ++++++++++++++++++ .../PatMatOuterPointerCheckTest.scala | 28 ++++ 4 files changed, 224 insertions(+), 2 deletions(-) create mode 100644 test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/OuterClassTest.scala create mode 100644 test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/PatMatOuterPointerCheckTest.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala index a35217f9ec..7698851015 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala @@ -86,6 +86,12 @@ trait JSEncoding extends SubComponent { self: GenJSCode => refClass.values ++ volatileRefClass.values) } + /** See comment in `encodeFieldSym()`. */ + private lazy val shouldMangleOuterPointerName = { + val v = scala.util.Properties.versionNumberString + !(v.startsWith("2.10.") || v.startsWith("2.11.") || v == "2.12.0-RC1") + } + def encodeFieldSym(sym: Symbol)(implicit pos: Position): js.Ident = { require(sym.owner.isClass && sym.isTerm && !sym.isMethod && !sym.isModule, "encodeFieldSym called with non-field symbol: " + sym) @@ -99,12 +105,29 @@ trait JSEncoding extends SubComponent { self: GenJSCode => * because they are emitted as private by our .scala source files, but * they are considered public at use site since their symbols come from * Java-emitted .class files. + * + * Starting with 2.12.0-RC2, we also special case outer fields. This + * essentially fixes #2382, which is caused by a class having various $outer + * pointers in its hierarchy that points to different outer instances. + * Without this fix, they all collapse to the same field in the IR. We + * cannot fix this for all Scala versions at the moment, because that would + * break backwards binary compatibility. We *do* fix it for 2.12.0-RC2 + * onwards because that also fixes #2625, which surfaced in 2.12 and is + * therefore a regression. We can do this because the 2.12 ecosystem is + * not binary compatible anyway (because of Scala) so we can break it on + * our side at the same time. */ - val idSuffix = - if (sym.isPrivate || allRefClasses.contains(sym.owner)) + val idSuffix: String = { + val usePerClassSuffix = { + sym.isPrivate || + allRefClasses.contains(sym.owner) || + (shouldMangleOuterPointerName && sym.isOuterField) + } + if (usePerClassSuffix) sym.owner.ancestors.count(!_.isTraitOrInterface).toString else "f" + } val encodedName = name + "$" + idSuffix js.Ident(mangleJSName(encodedName), Some(sym.unexpandedName.decoded)) diff --git a/project/Build.scala b/project/Build.scala index c0c4a22e1b..d433ac31d0 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1409,6 +1409,31 @@ object Build { IO.write(outFile, replaced.replace("@Test def workTest(): Unit = sys.error(\"stubs\")", unitTests)) Seq(outFile) + }, + + // Exclude tests based on version-dependent bugs + sources in Test := { + val sourceFiles = (sources in Test).value + val v = scalaVersion.value + + val hasBug2625 = v == "2.12.0-RC1" + val sourceFiles1 = { + if (hasBug2625) + sourceFiles.filterNot(_.getName == "PatMatOuterPointerCheckTest.scala") + else + sourceFiles + } + + val hasBug2382 = + v.startsWith("2.10.") || v.startsWith("2.11.") || v == "2.12.0-RC1" + val sourceFiles2 = { + if (hasBug2382) + sourceFiles1.filterNot(_.getName == "OuterClassTest.scala") + else + sourceFiles1 + } + + sourceFiles2 } ) ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/OuterClassTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/OuterClassTest.scala new file mode 100644 index 0000000000..2baed6a5ea --- /dev/null +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/OuterClassTest.scala @@ -0,0 +1,146 @@ +package org.scalajs.testsuite.compiler + +import org.junit.Test +import org.junit.Assert._ + +/* This test only works with 2.12.0-RC2 onwards. With previous versions of + * Scala, it suffers from #2382. + */ +class OuterClassTest { + + @Test def `Test code variant 1 from #2382`(): Unit = { + val b1 = new B1 {} + val y1 = new b1.Y1 + val z1 = new y1.Z1 + + assertEquals(1, b1.a) + assertEquals(1, z1.z1) + assertEquals(1, z1.z2) + assertEquals(2, y1.y) + } + + @Test def `Test code variant 2 from #2382`(): Unit = { + val b2 = new B2 {} + val y2 = new b2.Y2 + val z2 = new y2.Z2 + + assertEquals(1, b2.a) + assertEquals(1, z2.z1) + assertEquals(2, y2.y) + assertEquals(2, z2.z2) + } + + @Test def `Test code variant 3 from #2382`(): Unit = { + val a3 = new A3 {} + val y3 = new a3.Y3 + val z3 = new y3.Z3 + + assertEquals(1, a3.a) + assertEquals(1, z3.b) + } + + @Test def `Test code variant 4 from #2382`(): Unit = { + val a4 = new A4 {} + val y4 = new a4.Y4 + val z4 = new y4.Z4 + + assertEquals(1, a4.a) + assertEquals(1, z4.b) + } + + @Test def `Test code variant 5 from #2382`(): Unit = { + val a5 = new A5 {} + val y5 = new a5.Y5 + val z5 = new y5.Z5 + + assertEquals(1, a5.a) + assertEquals(1, z5.b) + assertEquals(2, z5.c) + assertEquals(2, z5.d) + assertEquals(3, z5.e) + assertEquals(3, z5.f) + } +} + +// Code from issue #2382 variant 1 + +trait A1 { + val a: Int = 1 + class X1 { + def x: Int = a + } +} + +trait B1 extends A1 { + class Y1 { + def y: Int = 2 + class Z1 extends X1 { + def z1: Int = a + def z2: Int = x + } + } +} + +// Code from issue #2382 variant 2 + +trait A2 { + val a: Int = 1 + class X2 +} + +trait B2 extends A2 { + class Y2 { + def y: Int = 2 + class Z2 extends X2 { + def z1: Int = a + def z2: Int = y + } + } +} + +// Code from issue #2382 variant 2 + +trait A3 { + val a: Int = 1 + class X3 + class Y3 { + class Z3 extends X3 { + def b: Int = a + } + } +} + +// Code from issue #2382 variant 4 + +class A4 { + val a: Int = 1 + class X4 + class Y4 { + class Z4 extends X4 { + def b: Int = a + } + } +} + +// Code from issue #2382 variant 5 + +class A5 { + val a: Int = 1 + trait B5 { + def c: Int = 2 + } + trait C5 extends B5 + trait D5 extends C5 + class X5 { + def e: Int = 3 + } + trait U5 extends X5 + trait S5 extends U5 + class Y5 extends S5 { + class Z5 extends X5 with D5 { + def b: Int = a + def d: Int = c + def f: Int = e + } + } +} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/PatMatOuterPointerCheckTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/PatMatOuterPointerCheckTest.scala new file mode 100644 index 0000000000..de20928b45 --- /dev/null +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/PatMatOuterPointerCheckTest.scala @@ -0,0 +1,28 @@ +package org.scalajs.testsuite.compiler + +import org.junit.Test +import org.junit.Assert._ + +class PatMatOuterPointerCheckTest { + import PatMatOuterPointerCheckTest._ + + @Test def testPatMatOuterPointerCheck(): Unit = { + assertEquals(1, (new A).call()) + } +} + +object PatMatOuterPointerCheckTest { + class A { + def call(): Int = f(Foo.B(1)) + + private def f(x: Foo): Int = x match { + case Foo.B(x) => x + } + + sealed abstract class Foo + + object Foo { + case class B(x: Int) extends Foo + } + } +} From 321f49b3ce57788b35c079b54934ff32594ce278 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 8 Oct 2016 01:15:52 +0200 Subject: [PATCH 0035/2665] Fix #2359: Remove EmptyTree --- .../org/scalajs/core/compiler/GenJSCode.scala | 209 +++++++++--------- .../scalajs/core/compiler/GenJSExports.scala | 27 ++- .../core/compiler/test/JSExportASTTest.scala | 2 +- .../scala/org/scalajs/core/ir/Hashers.scala | 14 +- .../scala/org/scalajs/core/ir/Infos.scala | 12 +- .../scala/org/scalajs/core/ir/Printers.scala | 57 +++-- .../org/scalajs/core/ir/Serializers.scala | 95 ++++++-- .../main/scala/org/scalajs/core/ir/Tags.scala | 6 + .../org/scalajs/core/ir/Transformers.scala | 22 +- .../org/scalajs/core/ir/Traversers.scala | 17 +- .../scala/org/scalajs/core/ir/Trees.scala | 18 +- .../org/scalajs/core/ir/PrintersTest.scala | 40 ++-- .../scala/tools/nsc/MainGenericRunner.scala | 16 +- project/BinaryIncompatibilities.scala | 27 ++- project/JavaLangObject.scala | 20 +- project/JavaLangString.scala | 16 +- .../closure/ClosureLinkerBackend.scala | 2 +- .../core/tools/linker/LinkedClass.scala | 6 +- .../linker/backend/emitter/JSDesugaring.scala | 51 ++--- .../backend/emitter/ScalaJSClassEmitter.scala | 73 +++--- .../core/tools/linker/checker/IRChecker.scala | 106 +++++---- .../tools/linker/frontend/BaseLinker.scala | 14 +- .../frontend/optimizer/GenIncOptimizer.scala | 8 +- .../frontend/optimizer/OptimizerCore.scala | 50 +++-- 24 files changed, 512 insertions(+), 396 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 30b7385029..9f8ab8c982 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -582,8 +582,8 @@ abstract class GenJSCode extends plugins.PluginComponent generatedClasses += ((sym, None, newClassDef)) // Construct inline class definition - val js.MethodDef(_, _, ctorParams, _, ctorBody) = constructor.getOrElse( - throw new AssertionError("No ctor found")); + val js.MethodDef(_, _, ctorParams, _, Some(ctorBody)) = + constructor.getOrElse(throw new AssertionError("No ctor found")) val selfName = freshLocalIdent("this")(pos) def selfRef(implicit pos: ir.Position) = @@ -606,7 +606,8 @@ abstract class GenJSCode extends plugins.PluginComponent case mdef: js.MethodDef => implicit val pos = mdef.pos val name = mdef.name.asInstanceOf[js.StringLiteral] - val impl = lambda(mdef.args, mdef.body) + val impl = lambda(mdef.args, mdef.body.getOrElse( + throw new AssertionError("Got anon SJS class with abstract method"))) js.Assign(js.JSBracketSelect(selfRef, name), impl) case pdef: js.PropertyDef => @@ -618,15 +619,21 @@ abstract class GenJSCode extends plugins.PluginComponent def field(name: String, value: js.Tree) = List(js.StringLiteral(name) -> value) - def accessor(tree: js.Tree, name: String)(genBody: js.Tree => js.Tree) = - if (tree == js.EmptyTree) Nil - else field(name, genBody(tree)) + val optGetter = pdef.getterBody map { body => + js.StringLiteral("get") -> lambda(params = Nil, body) + } + + val optSetter = pdef.setterArgAndBody map { case (arg, body) => + js.StringLiteral("set") -> lambda(params = arg :: Nil, body) + } val descriptor = js.JSObjectConstr( - accessor(pdef.getterBody, "get")(lambda(params = Nil, _)) ++ - accessor(pdef.setterBody, "set")(lambda(pdef.setterArg :: Nil, _)) ++ - field("configurable", js.BooleanLiteral(true)) ++ - field("enumerable", js.BooleanLiteral(true)) + optGetter.toList ++ + optSetter ++ + List( + js.StringLiteral("configurable") -> js.BooleanLiteral(true), + js.StringLiteral("enumerable") -> js.BooleanLiteral(true) + ) ) js.JSBracketMethodApply(jsObject, js.StringLiteral("defineProperty"), @@ -860,7 +867,7 @@ abstract class GenJSCode extends plugins.PluginComponent "Implementation restriction: constructors of " + "Scala.js-defined JS classes cannot have default parameters " + "if their companion module is JS native.") - js.EmptyTree + js.Skip() } else { withNewLocalNameScope { val ctors: List[js.MethodDef] = constructorTrees.flatMap { tree => @@ -870,7 +877,7 @@ abstract class GenJSCode extends plugins.PluginComponent val dispatch = genJSConstructorExport(constructorTrees.map(_.symbol)) val js.MethodDef(_, dispatchName, dispatchArgs, dispatchResultType, - dispatchResolution) = dispatch + Some(dispatchResolution)) = dispatch val jsConstructorBuilder = mkJSConstructorBuilder(ctors) @@ -898,7 +905,7 @@ abstract class GenJSCode extends plugins.PluginComponent primaryCtorBody :: postPrimaryCtorBody :: Nil) js.MethodDef(static = false, dispatchName, dispatchArgs, jstpe.NoType, - newBody)(dispatch.optimizerHints, None) + Some(newBody))(dispatch.optimizerHints, None) } } } @@ -933,7 +940,8 @@ abstract class GenJSCode extends plugins.PluginComponent private class JSConstructorBuilder(root: ConstructorTree) { - def primaryCtorBody: js.Tree = root.method.body + def primaryCtorBody: js.Tree = root.method.body.getOrElse( + throw new AssertionError("Found abstract constructor")) def hasSubConstructors: Boolean = root.subConstructors.nonEmpty @@ -979,7 +987,7 @@ abstract class GenJSCode extends plugins.PluginComponent mkSubPreCalls(constructorTree, overrideNumRef) val preSuperCall = { - constructorTree.method.body match { + constructorTree.method.body.get match { case js.Block(stats) => val beforeSuperCall = stats.takeWhile { case js.ApplyStatic(_, mtd, _) => !ir.Definitions.isConstructorName(mtd.name) @@ -1022,7 +1030,7 @@ abstract class GenJSCode extends plugins.PluginComponent private def mkPostPrimaryCtorBodyOnSndCtr(constructorTree: ConstructorTree, overrideNumRef: js.VarRef)(implicit pos: Position): js.Tree = { val postSuperCall = { - constructorTree.method.body match { + constructorTree.method.body.get match { case js.Block(stats) => stats.dropWhile { case js.ApplyStatic(_, mtd, _) => !ir.Definitions.isConstructorName(mtd.name) @@ -1165,7 +1173,7 @@ abstract class GenJSCode extends plugins.PluginComponent } val (primaryCtor :: Nil, secondaryCtors) = ctors.partition { - _.body match { + _.body.get match { case js.Block(stats) => stats.exists(_.isInstanceOf[js.JSSuperConstructorCall]) @@ -1175,7 +1183,7 @@ abstract class GenJSCode extends plugins.PluginComponent } val ctorToChildren = secondaryCtors.map { ctor => - findCtorForwarderCall(ctor.body) -> ctor + findCtorForwarderCall(ctor.body.get) -> ctor }.groupBy(_._1).mapValues(_.map(_._2)).withDefaultValue(Nil) var overrideNum = -1 @@ -1263,10 +1271,10 @@ abstract class GenJSCode extends plugins.PluginComponent sParam.tpe =:= symParam.tpe } } - genTraitImplApply(implMethodSym, - js.This()(currentClassType) :: jsParams.map(_.ref)) + Some(genTraitImplApply(implMethodSym, + js.This()(currentClassType) :: jsParams.map(_.ref))) } else { - js.EmptyTree + None } Some(js.MethodDef(static = false, methodName, jsParams, toIRType(sym.tpe.resultType), body)( @@ -1313,11 +1321,11 @@ abstract class GenJSCode extends plugins.PluginComponent if (!sym.isPrimaryConstructor) body0 else moveAllStatementsAfterSuperConstructorCall(body0) js.MethodDef(static = false, methodName, - jsParams, jstpe.NoType, body1)(optimizerHints, None) + jsParams, jstpe.NoType, Some(body1))(optimizerHints, None) } else if (sym.isClassConstructor) { js.MethodDef(static = false, methodName, jsParams, jstpe.NoType, - genStat(rhs))(optimizerHints, None) + Some(genStat(rhs)))(optimizerHints, None) } else { val resultIRType = toIRType(sym.tpe.resultType) genMethodDef(static = sym.owner.isImplClass, methodName, @@ -1398,8 +1406,8 @@ abstract class GenJSCode extends plugins.PluginComponent super.transform(tree, isStat) } } - val newBody = - transformer.transform(body, isStat = resultType == jstpe.NoType) + val newBody = body.map( + b => transformer.transform(b, isStat = resultType == jstpe.NoType)) js.MethodDef(static, methodName, newParams, resultType, newBody)(methodDef.optimizerHints, None)(methodDef.pos) } @@ -1507,8 +1515,8 @@ abstract class GenJSCode extends plugins.PluginComponent } if (!isScalaJSDefinedJSClass(currentClassSym)) { - js.MethodDef(static, methodName, jsParams, resultIRType, genBody())( - optimizerHints, None) + js.MethodDef(static, methodName, jsParams, resultIRType, + Some(genBody()))(optimizerHints, None) } else { assert(!static, tree.pos) @@ -1519,7 +1527,7 @@ abstract class GenJSCode extends plugins.PluginComponent jstpe.AnyType, mutable = false, rest = false) js.MethodDef(static = true, methodName, thisParamDef :: jsParams, - resultIRType, genBody())( + resultIRType, Some(genBody()))( optimizerHints, None) } } @@ -1899,89 +1907,86 @@ abstract class GenJSCode extends plugins.PluginComponent val Try(block, catches, finalizer) = tree val blockAST = genStatOrExpr(block, isStat) + val resultType = toIRType(tree.tpe) - val exceptIdent = freshLocalIdent("e") - val origExceptVar = js.VarRef(exceptIdent)(jstpe.AnyType) + val handled = + if (catches.isEmpty) blockAST + else genTryCatch(blockAST, catches, resultType, isStat) - val resultType = toIRType(tree.tpe) + genStat(finalizer) match { + case js.Skip() => handled + case ast => js.TryFinally(handled, ast) + } + } - val handlerAST = { - if (catches.isEmpty) { - js.EmptyTree - } else { - val mightCatchJavaScriptException = catches.exists { caseDef => - caseDef.pat match { - case Typed(Ident(nme.WILDCARD), tpt) => - isMaybeJavaScriptException(tpt.tpe) - case Ident(nme.WILDCARD) => - true - case pat @ Bind(_, _) => - isMaybeJavaScriptException(pat.symbol.tpe) - } - } + private def genTryCatch(body: js.Tree, catches: List[CaseDef], + resultType: jstpe.Type, + isStat: Boolean)(implicit pos: Position): js.Tree = { + val exceptIdent = freshLocalIdent("e") + val origExceptVar = js.VarRef(exceptIdent)(jstpe.AnyType) - val (exceptValDef, exceptVar) = if (mightCatchJavaScriptException) { - val valDef = js.VarDef(freshLocalIdent("e"), - encodeClassType(ThrowableClass), mutable = false, { - genApplyMethod( - genLoadModule(RuntimePackageModule), - Runtime_wrapJavaScriptException, - List(origExceptVar)) - }) - (valDef, valDef.ref) - } else { - (js.Skip(), origExceptVar) - } + val mightCatchJavaScriptException = catches.exists { caseDef => + caseDef.pat match { + case Typed(Ident(nme.WILDCARD), tpt) => + isMaybeJavaScriptException(tpt.tpe) + case Ident(nme.WILDCARD) => + true + case pat @ Bind(_, _) => + isMaybeJavaScriptException(pat.symbol.tpe) + } + } - val elseHandler: js.Tree = js.Throw(origExceptVar) + val (exceptValDef, exceptVar) = if (mightCatchJavaScriptException) { + val valDef = js.VarDef(freshLocalIdent("e"), + encodeClassType(ThrowableClass), mutable = false, { + genApplyMethod( + genLoadModule(RuntimePackageModule), + Runtime_wrapJavaScriptException, + List(origExceptVar)) + }) + (valDef, valDef.ref) + } else { + (js.Skip(), origExceptVar) + } - val handler0 = catches.foldRight(elseHandler) { (caseDef, elsep) => - implicit val pos = caseDef.pos - val CaseDef(pat, _, body) = caseDef + val elseHandler: js.Tree = js.Throw(origExceptVar) - // Extract exception type and variable - val (tpe, boundVar) = (pat match { - case Typed(Ident(nme.WILDCARD), tpt) => - (tpt.tpe, None) - case Ident(nme.WILDCARD) => - (ThrowableClass.tpe, None) - case Bind(_, _) => - (pat.symbol.tpe, Some(encodeLocalSym(pat.symbol))) - }) + val handler = catches.foldRight(elseHandler) { (caseDef, elsep) => + implicit val pos = caseDef.pos + val CaseDef(pat, _, body) = caseDef - // Generate the body that must be executed if the exception matches - val bodyWithBoundVar = (boundVar match { - case None => - genStatOrExpr(body, isStat) - case Some(bv) => - val castException = genAsInstanceOf(exceptVar, tpe) - js.Block( - js.VarDef(bv, toIRType(tpe), mutable = false, castException), - genStatOrExpr(body, isStat)) - }) + // Extract exception type and variable + val (tpe, boundVar) = (pat match { + case Typed(Ident(nme.WILDCARD), tpt) => + (tpt.tpe, None) + case Ident(nme.WILDCARD) => + (ThrowableClass.tpe, None) + case Bind(_, _) => + (pat.symbol.tpe, Some(encodeLocalSym(pat.symbol))) + }) - // Generate the test - if (tpe == ThrowableClass.tpe) { - bodyWithBoundVar - } else { - val cond = genIsInstanceOf(exceptVar, tpe) - js.If(cond, bodyWithBoundVar, elsep)(resultType) - } - } + // Generate the body that must be executed if the exception matches + val bodyWithBoundVar = (boundVar match { + case None => + genStatOrExpr(body, isStat) + case Some(bv) => + val castException = genAsInstanceOf(exceptVar, tpe) + js.Block( + js.VarDef(bv, toIRType(tpe), mutable = false, castException), + genStatOrExpr(body, isStat)) + }) - js.Block( - exceptValDef, - handler0) + // Generate the test + if (tpe == ThrowableClass.tpe) { + bodyWithBoundVar + } else { + val cond = genIsInstanceOf(exceptVar, tpe) + js.If(cond, bodyWithBoundVar, elsep)(resultType) } } - val finalizerAST = genStat(finalizer) match { - case js.Skip() => js.EmptyTree - case ast => ast - } - - if (handlerAST == js.EmptyTree && finalizerAST == js.EmptyTree) blockAST - else js.Try(blockAST, exceptIdent, handlerAST, finalizerAST)(resultType) + js.TryCatch(body, exceptIdent, + js.Block(exceptValDef, handler))(resultType) } /** Gen JS code for an Apply node (method call) @@ -4614,7 +4619,7 @@ abstract class GenJSCode extends plugins.PluginComponent val js.MethodDef(_, _, params, _, body) = applyMethod val (patchedParams, patchedBody) = - patchFunBodyWithBoxes(applyDef.symbol, params, body) + patchFunBodyWithBoxes(applyDef.symbol, params, body.get) // Fifth step: build the js.Closure @@ -4800,14 +4805,14 @@ abstract class GenJSCode extends plugins.PluginComponent mutable = false, rest = false) js.MethodDef(static = false, js.Ident("init___O"), List(fParamDef), jstpe.NoType, - js.Block(List( + Some(js.Block(List( js.Assign( js.Select(js.This()(classType), fFieldIdent)(jstpe.AnyType), fParamDef.ref), js.ApplyStatically(js.This()(classType), jstpe.ClassType(ir.Definitions.ObjectClass), js.Ident("init___"), - Nil)(jstpe.NoType))))( + Nil)(jstpe.NoType)))))( js.OptimizerHints.empty, None) } @@ -4833,7 +4838,7 @@ abstract class GenJSCode extends plugins.PluginComponent }) js.MethodDef(static = false, encodeMethodSym(sam), - jsParams, resultType, body)( + jsParams, resultType, Some(body))( js.OptimizerHints.empty, None) } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index 4b0f350bdd..697a4ab116 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -57,7 +57,6 @@ trait GenJSExports extends SubComponent { self: GenJSCode => dispatchMethodsNames: List[String]): List[js.Tree] = { dispatchMethodsNames .map(genJSClassDispatcher(classSym, _)) - .filter(_ != js.EmptyTree) } def genConstructorExports(classSym: Symbol): List[js.ConstructorExportDef] = { @@ -94,7 +93,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => val js.MethodDef(_, _, args, _, body) = withNewLocalNameScope(genExportMethod(ctors, jsName)) - js.ConstructorExportDef(jsName, args, body) + js.ConstructorExportDef(jsName, args, body.get) } exports.toList @@ -150,7 +149,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => Some(js.MethodDef(static = false, methodIdent, List(inArg), toIRType(sym.tpe.resultType), - genNamedExporterBody(trgSym, inArg.ref))( + Some(genNamedExporterBody(trgSym, inArg.ref)))( OptimizerHints.empty, None)) } } @@ -225,7 +224,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => if (isProp && methodSyms.nonEmpty) { reporter.error(alts.head.pos, s"Conflicting properties and methods for ${classSym.fullName}::$name.") - js.EmptyTree + js.Skip()(ir.Position.NoPosition) } else { genMemberExportOrDispatcher(classSym, name, isProp, alts) } @@ -256,15 +255,19 @@ trait GenJSExports extends SubComponent { self: GenJSCode => assert(getter.size <= 1, s"Found more than one getter to export for name ${jsName}.") - val getTree = - if (getter.isEmpty) js.EmptyTree - else genApplyForSym(0, false, getter.head) + val getterBody = getter.headOption.map(genApplyForSym(0, false, _)) - val setTree = - if (setters.isEmpty) js.EmptyTree - else genExportSameArgc(1, false, setters.map(ExportedSymbol), 0) // we only have 1 argument + val setterArgAndBody = { + if (setters.isEmpty) { + None + } else { + val arg = genFormalArg(1) + val body = genExportSameArgc(1, false, setters.map(ExportedSymbol), 0) + Some((arg, body)) + } + } - js.PropertyDef(js.StringLiteral(jsName), getTree, genFormalArg(1), setTree) + js.PropertyDef(js.StringLiteral(jsName), getterBody, setterArgAndBody) } /** generates the exporter function (i.e. exporter for non-properties) for @@ -389,7 +392,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } js.MethodDef(static = false, js.StringLiteral(jsName), - formalArgs, jstpe.AnyType, body)(OptimizerHints.empty, None) + formalArgs, jstpe.AnyType, Some(body))(OptimizerHints.empty, None) } /** diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportASTTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportASTTest.scala index 2a8e659aaf..8f5f85a1f8 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportASTTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportASTTest.scala @@ -24,7 +24,7 @@ class JSExportASTTest extends JSASTTest { override def foo = 2 } """.hasExactly(1, "definitions of property `foo`") { - case js.PropertyDef(js.StringLiteral("foo"), _, _, _) => + case js.PropertyDef(js.StringLiteral("foo"), _, _) => } } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala index 5c69d4867b..9436521b75 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala @@ -21,7 +21,7 @@ object Hashers { hasher.mixPropertyName(name) hasher.mixTrees(args) hasher.mixType(resultType) - hasher.mixTree(body) + body.foreach(hasher.mixTree) hasher.mixInt(methodDef.optimizerHints.bits) val hash = hasher.finalizeHash() @@ -89,9 +89,6 @@ object Hashers { def mixTree(tree: Tree): Unit = { mixPos(tree.pos) tree match { - case EmptyTree => - mixTag(TagEmptyTree) - case VarDef(ident, vtpe, mutable, rhs) => mixTag(TagVarDef) mixIdent(ident) @@ -154,11 +151,16 @@ object Hashers { mixTree(cond) mixOptIdent(label) - case Try(block, errVar, handler, finalizer) => - mixTag(TagTry) + case TryCatch(block, errVar, handler) => + mixTag(TagTryCatch) mixTree(block) mixIdent(errVar) mixTree(handler) + mixType(tree.tpe) + + case TryFinally(block, finalizer) => + mixTag(TagTryFinally) + mixTree(block) mixTree(finalizer) mixType(tree.tpe) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala index 07a3c3bbc6..751208f491 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala @@ -299,11 +299,10 @@ object Infos { builder .setEncodedName(methodDef.name.name) .setIsStatic(methodDef.static) - .setIsAbstract(methodDef.body == EmptyTree) + .setIsAbstract(methodDef.body.isEmpty) .setIsExported(methodDef.name.isInstanceOf[StringLiteral]) - // body can be EmptyTree, but that's fine - traverse(methodDef.body) + methodDef.body.foreach(traverse) builder.result() } @@ -313,9 +312,10 @@ object Infos { .setEncodedName(propertyDef.name.name) .setIsExported(true) - // Any of getterBody and setterBody can be EmptyTree, but that's fine - traverse(propertyDef.getterBody) - traverse(propertyDef.setterBody) + propertyDef.getterBody.foreach(traverse) + propertyDef.setterArgAndBody foreach { case (_, body) => + traverse(body) + } builder.result() } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index 7b0756c714..80b2a36c88 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -116,9 +116,6 @@ object Printers { def print(tree: Tree): Unit = { tree match { - case EmptyTree => - print("") - // Definitions case VarDef(ident, vtpe, mutable, rhs) => @@ -222,19 +219,29 @@ object Printers { print(cond) print(')') - case Try(block, errVar, handler, finalizer) => + case TryFinally(TryCatch(block, errVar, handler), finalizer) => print("try ") printBlock(block) - if (handler != EmptyTree) { - print(" catch (") - print(errVar) - print(") ") - printBlock(handler) - } - if (finalizer != EmptyTree) { - print(" finally ") - printBlock(finalizer) - } + print(" catch (") + print(errVar) + print(") ") + printBlock(handler) + print(" finally ") + printBlock(finalizer) + + case TryCatch(block, errVar, handler) => + print("try ") + printBlock(block) + print(" catch (") + print(errVar) + print(") ") + printBlock(handler) + + case TryFinally(block, finalizer) => + print("try ") + printBlock(block) + print(" finally ") + printBlock(finalizer) case Throw(expr) => print("throw ") @@ -807,27 +814,29 @@ object Printers { print("def ") print(name) printSig(args, resultType) - if (body == EmptyTree) + body.fold { print("") - else + } { body => printBlock(body) + } - case PropertyDef(name, getterBody, setterArg, setterBody) => - if (getterBody != EmptyTree) { + case PropertyDef(name, getterBody, setterArgAndBody) => + getterBody foreach { body => print("get ") print(name) printSig(Nil, AnyType) - printBlock(getterBody) + printBlock(body) + } - if (setterBody != EmptyTree) - println() + if (getterBody.isDefined && setterArgAndBody.isDefined) { + println() } - if (setterBody != EmptyTree) { + setterArgAndBody foreach { case (arg, body) => print("set ") print(name) - printSig(setterArg :: Nil, NoType) - printBlock(setterBody) + printSig(arg :: Nil, NoType) + printBlock(body) } case ConstructorExportDef(fullName, args, body) => diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index 52e4eddae8..61aedb11a7 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -111,9 +111,6 @@ object Serializers { import buffer._ writePosition(tree.pos) tree match { - case EmptyTree => - writeByte(TagEmptyTree) - case VarDef(ident, vtpe, mutable, rhs) => writeByte(TagVarDef) writeIdent(ident); writeType(vtpe); writeBoolean(mutable); writeTree(rhs) @@ -154,11 +151,15 @@ object Serializers { writeByte(TagDoWhile) writeTree(body); writeTree(cond); writeOptIdent(label) - case Try(block, errVar, handler, finalizer) => - writeByte(TagTry) - writeTree(block); writeIdent(errVar); writeTree(handler); writeTree(finalizer) + case TryCatch(block, errVar, handler) => + writeByte(TagTryCatch) + writeTree(block); writeIdent(errVar); writeTree(handler) writeType(tree.tpe) + case TryFinally(block, finalizer) => + writeByte(TagTryFinally) + writeTree(block); writeTree(finalizer) + case Throw(expr) => writeByte(TagThrow) writeTree(expr) @@ -428,7 +429,7 @@ object Serializers { // Write out method def writeBoolean(static); writePropertyName(name) - writeTrees(args); writeType(resultType); writeTree(body) + writeTrees(args); writeType(resultType); writeOptTree(body) writeInt(methodDef.optimizerHints.bits) // Jump back and write true length @@ -436,9 +437,14 @@ object Serializers { writeInt(length) bufferUnderlying.continue() - case PropertyDef(name, getter, arg, setter) => + case PropertyDef(name, getter, setterArgAndBody) => writeByte(TagPropertyDef) - writePropertyName(name); writeTree(getter); writeTree(arg); writeTree(setter) + writePropertyName(name) + writeOptTree(getter) + writeBoolean(setterArgAndBody.isDefined) + setterArgAndBody foreach { case (arg, body) => + writeTree(arg); writeTree(body) + } case ConstructorExportDef(fullName, args, body) => writeByte(TagConstructorExportDef) @@ -461,6 +467,15 @@ object Serializers { trees.foreach(writeTree) } + def writeOptTree(optTree: Option[Tree]): Unit = { + optTree.fold { + writePosition(Position.NoPosition) + buffer.writeByte(TagEmptyTree) + } { tree => + writeTree(tree) + } + } + def writeIdent(ident: Ident): Unit = { writePosition(ident.pos) writeString(ident.name); writeString(ident.originalName.getOrElse("")) @@ -634,11 +649,23 @@ object Serializers { } def readTree(): Tree = { + val pos = readPosition() + readTreeFromTag(input.readByte())(pos) + } + + def readOptTree(): Option[Tree] = { + // TODO switch tag and position when we can break binary compat. + val pos = readPosition() + val tag = input.readByte() + if (tag == TagEmptyTree) None + else Some(readTreeFromTag(tag)(pos)) + } + + private def readTreeFromTag(tag: Byte)(implicit pos: Position): Tree = { import input._ - implicit val pos = readPosition() - val tag = readByte() val result = (tag: @switch) match { - case TagEmptyTree => EmptyTree + case TagEmptyTree => + sys.error("Found invalid TagEmptyTree") case TagVarDef => VarDef(readIdent(), readType(), readBoolean(), readTree()) case TagParamDef => @@ -653,7 +680,29 @@ object Serializers { case TagIf => If(readTree(), readTree(), readTree())(readType()) case TagWhile => While(readTree(), readTree(), readOptIdent()) case TagDoWhile => DoWhile(readTree(), readTree(), readOptIdent()) - case TagTry => Try(readTree(), readIdent(), readTree(), readTree())(readType()) + + case TagTry => + if (!useHacks068) { + sys.error("Invalid tag TagTry") + } + + val block = readTree() + val errVar = readIdent() + val handler = readOptTree() + val finalizer = readOptTree() + val tpe = readType() + + val maybeCatch = handler.fold(block)( + handler => TryCatch(block, errVar, handler)(tpe)) + finalizer.fold(maybeCatch)( + finalizer => TryFinally(maybeCatch, finalizer)) + + case TagTryCatch => + TryCatch(readTree(), readIdent(), readTree())(readType()) + + case TagTryFinally => + TryFinally(readTree(), readTree()) + case TagThrow => Throw(readTree()) case TagContinue => Continue(readOptIdent()) case TagMatch => @@ -782,7 +831,7 @@ object Serializers { val len = readInt() assert(len >= 0) val result1 = MethodDef(readBoolean(), readPropertyName(), - readParamDefs(), readType(), readTree())( + readParamDefs(), readType(), readOptTree())( new OptimizerHints(readInt()), optHash) val result2 = if (foundArguments) { foundArguments = false @@ -799,8 +848,20 @@ object Serializers { result2 } case TagPropertyDef => - PropertyDef(readPropertyName(), readTree(), - readTree().asInstanceOf[ParamDef], readTree()) + val name = readPropertyName() + val getterBody = readOptTree() + val setterArgAndBody = if (useHacks068) { + val setterArg = readTree().asInstanceOf[ParamDef] + readOptTree().map(setterBody => (setterArg, setterBody)) + } else { + if (readBoolean()) + Some((readTree().asInstanceOf[ParamDef], readTree())) + else + None + } + + PropertyDef(name, getterBody, setterArgAndBody) + case TagConstructorExportDef => val result = ConstructorExportDef(readString(), readParamDefs(), readTree()) if (foundArguments) { @@ -985,7 +1046,7 @@ object Serializers { val MethodDef(static, name, args, resultType, body) = tree setupParamToIndex(args) MethodDef(static, name, List(argumentsParamDef(tree.pos)), - resultType, transform(body, isStat = resultType == NoType))( + resultType, body.map(transform(_, isStat = resultType == NoType)))( tree.optimizerHints, None)(tree.pos) } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala index a75f626b50..5ff4951bbb 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala @@ -14,6 +14,7 @@ private[ir] object Tags { // Tags for Trees + /** Use to denote optional trees. */ final val TagEmptyTree = 1 final val TagVarDef = TagEmptyTree + 1 @@ -27,7 +28,10 @@ private[ir] object Tags { final val TagIf = TagReturn + 1 final val TagWhile = TagIf + 1 final val TagDoWhile = TagWhile + 1 + + // TODO remove when we can break binary compat. final val TagTry = TagDoWhile + 1 + final val TagThrow = TagTry + 1 final val TagContinue = TagThrow + 1 final val TagMatch = TagContinue + 1 @@ -98,6 +102,8 @@ private[ir] object Tags { final val TagLoadJSConstructor = TagJSSuperConstructorCall + 1 final val TagLoadJSModule = TagLoadJSConstructor + 1 final val TagJSClassExportDef = TagLoadJSModule + 1 + final val TagTryCatch = TagJSClassExportDef + 1 + final val TagTryFinally = TagTryCatch + 1 // Tags for Types diff --git a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala index 184b4a9585..c3ec757dd0 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala @@ -53,9 +53,12 @@ object Transformers { case DoWhile(body, cond, label) => DoWhile(transformStat(body), transformExpr(cond), label) - case Try(block, errVar, handler, finalizer) => - Try(transform(block, isStat), errVar, transform(handler, isStat), - transformStat(finalizer))(tree.tpe) + case TryCatch(block, errVar, handler) => + TryCatch(transform(block, isStat), errVar, + transform(handler, isStat))(tree.tpe) + + case TryFinally(block, finalizer) => + TryFinally(transform(block, isStat), transformStat(finalizer)) case Throw(expr) => Throw(transformExpr(expr)) @@ -186,7 +189,7 @@ object Transformers { case _:Skip | _:Continue | _:Debugger | _:LoadModule | _:LoadJSConstructor | _:LoadJSModule | _:JSLinkingInfo | - _:Literal | _:UndefinedParam | _:VarRef | _:This | EmptyTree => + _:Literal | _:UndefinedParam | _:VarRef | _:This => tree case _ => @@ -211,15 +214,16 @@ object Transformers { case tree: MethodDef => val MethodDef(static, name, args, resultType, body) = tree - MethodDef(static, name, args, resultType, transformStat(body))( + MethodDef(static, name, args, resultType, body.map(transformStat))( tree.optimizerHints, None) - case PropertyDef(name, getterBody, setterArg, setterBody) => + case PropertyDef(name, getterBody, setterArgAndBody) => PropertyDef( name, - transformStat(getterBody), - setterArg, - transformStat(setterBody)) + getterBody.map(transformStat), + setterArgAndBody map { case (arg, body) => + (arg, transformStat(body)) + }) case ConstructorExportDef(fullName, args, body) => ConstructorExportDef(fullName, args, transformStat(body)) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala index 97d07460a0..f097514d1f 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala @@ -48,9 +48,12 @@ object Traversers { traverse(body) traverse(cond) - case Try(block, errVar, handler, finalizer) => + case TryCatch(block, errVar, handler) => traverse(block) traverse(handler) + + case TryFinally(block, finalizer) => + traverse(block) traverse(finalizer) case Throw(expr) => @@ -190,11 +193,13 @@ object Traversers { defs foreach traverse case MethodDef(static, name, args, resultType, body) => - traverse(body) + body.foreach(traverse) - case PropertyDef(name, getterBody, setterArg, setterBody) => - traverse(getterBody) - traverse(setterBody) + case PropertyDef(name, getterBody, setterArgAndBody) => + getterBody.foreach(traverse) + setterArgAndBody foreach { case (_, body) => + traverse(body) + } case ConstructorExportDef(fullName, args, body) => traverse(body) @@ -204,7 +209,7 @@ object Traversers { case _:Skip | _:Continue | _:Debugger | _:LoadModule | _:LoadJSConstructor | _:LoadJSModule | _:JSLinkingInfo | _:Literal | _:UndefinedParam | _:VarRef | _:This | _:FieldDef | - _:JSClassExportDef | _:ModuleExportDef | EmptyTree => + _:JSClassExportDef | _:ModuleExportDef => case _ => sys.error(s"Invalid tree in traverse() of class ${tree.getClass}") diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 67e302fe3d..5f37ff7296 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -28,11 +28,6 @@ object Trees { } } - case object EmptyTree extends Tree { - val pos = NoPosition - val tpe = NoType - } - // Identifiers and properties sealed trait PropertyName { @@ -170,9 +165,14 @@ object Trees { val tpe = NoType // cannot be in expression position } - case class Try(block: Tree, errVar: Ident, handler: Tree, finalizer: Tree)( + case class TryCatch(block: Tree, errVar: Ident, handler: Tree)( val tpe: Type)(implicit val pos: Position) extends Tree + case class TryFinally(block: Tree, finalizer: Tree)( + implicit val pos: Position) extends Tree { + val tpe = block.tpe + } + case class Throw(expr: Tree)(implicit val pos: Position) extends Tree { val tpe = NothingType } @@ -783,14 +783,14 @@ object Trees { } case class MethodDef(static: Boolean, name: PropertyName, - args: List[ParamDef], resultType: Type, body: Tree)( + args: List[ParamDef], resultType: Type, body: Option[Tree])( val optimizerHints: OptimizerHints, val hash: Option[TreeHash])( implicit val pos: Position) extends Tree { val tpe = NoType } - case class PropertyDef(name: PropertyName, getterBody: Tree, - setterArg: ParamDef, setterBody: Tree)( + case class PropertyDef(name: PropertyName, getterBody: Option[Tree], + setterArgAndBody: Option[(ParamDef, Tree)])( implicit val pos: Position) extends Tree { val tpe = NoType } diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala index 655242570f..8209318ddf 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala @@ -64,10 +64,6 @@ class PrintersTest { RecordType.Field("y", None, AnyType, mutable = true)))) } - @Test def printEmpty(): Unit = { - assertPrintEquals("", EmptyTree) - } - @Test def printVarDef(): Unit = { assertPrintEquals("val x: int = 5", VarDef("x", IntType, mutable = false, i(5))) @@ -221,7 +217,7 @@ class PrintersTest { | 6 |} """, - Try(i(5), "e", i(6), EmptyTree)(IntType)) + TryCatch(i(5), "e", i(6))(IntType)) assertPrintEquals( """ @@ -231,7 +227,7 @@ class PrintersTest { | 6 |} """, - Try(i(5), "e", EmptyTree, i(6))(IntType)) + TryFinally(i(5), i(6))) assertPrintEquals( """ @@ -243,7 +239,7 @@ class PrintersTest { | 7 |} """, - Try(i(5), "e", i(6), i(7))(IntType)) + TryFinally(TryCatch(i(5), "e", i(6))(IntType), i(7))) } @Test def printThrow(): Unit = { @@ -933,7 +929,7 @@ class PrintersTest { """, MethodDef(static = false, "m__I__I", List(ParamDef("x", IntType, mutable = false, rest = false)), - IntType, EmptyTree)(NoOptHints, None)) + IntType, None)(NoOptHints, None)) assertPrintEquals( """ @@ -943,7 +939,7 @@ class PrintersTest { """, MethodDef(static = false, "m__I__I", List(ParamDef("x", IntType, mutable = false, rest = false)), - IntType, i(5))(NoOptHints, None)) + IntType, Some(i(5)))(NoOptHints, None)) assertPrintEquals( """ @@ -953,7 +949,7 @@ class PrintersTest { """, MethodDef(static = false, "m__I__I", List(ParamDef("x", IntType, mutable = false, rest = false)), - IntType, i(5))(NoOptHints.withInline(true), None)) + IntType, Some(i(5)))(NoOptHints.withInline(true), None)) assertPrintEquals( """ @@ -963,7 +959,7 @@ class PrintersTest { """, MethodDef(static = false, "m__I__V", List(ParamDef("x", IntType, mutable = false, rest = false)), - NoType, i(5))(NoOptHints, None)) + NoType, Some(i(5)))(NoOptHints, None)) assertPrintEquals( """ @@ -973,7 +969,7 @@ class PrintersTest { """, MethodDef(static = false, StringLiteral("m"), List(ParamDef("x", AnyType, mutable = false, rest = false)), - AnyType, i(5))(NoOptHints, None)) + AnyType, Some(i(5)))(NoOptHints, None)) assertPrintEquals( """ @@ -983,7 +979,7 @@ class PrintersTest { """, MethodDef(static = false, StringLiteral("m"), List(ParamDef("x", AnyType, mutable = false, rest = true)), - AnyType, i(5))(NoOptHints, None)) + AnyType, Some(i(5)))(NoOptHints, None)) assertPrintEquals( """ @@ -993,7 +989,7 @@ class PrintersTest { """, MethodDef(static = true, "m__I__I", List(ParamDef("x", IntType, mutable = false, rest = false)), - IntType, i(5))(NoOptHints, None)) + IntType, Some(i(5)))(NoOptHints, None)) } @Test def printPropertyDef(): Unit = { @@ -1003,10 +999,7 @@ class PrintersTest { | 5 |} """, - PropertyDef(StringLiteral("prop"), - i(5), - ParamDef("x", AnyType, mutable = false, rest = false), - EmptyTree)) + PropertyDef(StringLiteral("prop"), Some(i(5)), None)) assertPrintEquals( """ @@ -1015,9 +1008,8 @@ class PrintersTest { |} """, PropertyDef(StringLiteral("prop"), - EmptyTree, - ParamDef("x", AnyType, mutable = false, rest = false), - i(7))) + None, + Some((ParamDef("x", AnyType, mutable = false, rest = false), i(7))))) assertPrintEquals( """ @@ -1029,9 +1021,9 @@ class PrintersTest { |} """, PropertyDef(StringLiteral("prop"), - i(5), - ParamDef("x", AnyType, mutable = false, rest = false), - i(7))) + Some(i(5)), + Some((ParamDef("x", AnyType, mutable = false, rest = false), + i(7))))) } @Test def printConstructorExportDef(): Unit = { diff --git a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala index 2b06fe362f..0720818122 100644 --- a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala +++ b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala @@ -119,12 +119,16 @@ class MainGenericRunner { StringLiteral("launch"), Nil, AnyType, - Block( - Apply(LoadModule(ClassType(mainModuleClassName)), - Ident("main__AT__V"), - List(ArrayValue(ArrayType("T", 1), args.map(StringLiteral(_)))) - )(NoType), - Undefined() + Some( + Block( + Apply(LoadModule(ClassType(mainModuleClassName)), + Ident("main__AT__V"), + List( + ArrayValue(ArrayType("T", 1), args.map(StringLiteral(_))) + ) + )(NoType), + Undefined() + ) ) )(OptimizerHints.empty, None), ModuleExportDef(exportName) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 0f46dfae18..e7bff962e3 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -5,7 +5,32 @@ object BinaryIncompatibilities { val IR = Seq( // Breaking changes ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.ir.Trees#ClassDef.jsName") + "org.scalajs.core.ir.Trees#ClassDef.jsName"), + + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.ir.Trees$Try"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.ir.Trees$Try$"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "org.scalajs.core.ir.Trees#MethodDef.apply"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.core.ir.Trees#MethodDef.body"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "org.scalajs.core.ir.Trees#MethodDef.copy"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "org.scalajs.core.ir.Trees#MethodDef.this"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.ir.Trees#PropertyDef.apply"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.ir.Trees#PropertyDef.copy"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.core.ir.Trees#PropertyDef.getterBody"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.ir.Trees#PropertyDef.setterArg"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.ir.Trees#PropertyDef.setterBody"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.ir.Trees#PropertyDef.this") ) val Tools = Seq( diff --git a/project/JavaLangObject.scala b/project/JavaLangObject.scala index 3bf88e7853..954cd4bb94 100644 --- a/project/JavaLangObject.scala +++ b/project/JavaLangObject.scala @@ -37,7 +37,7 @@ object JavaLangObject { Ident("init___", Some("")), Nil, NoType, - Skip())(OptimizerHints.empty, None), + Some(Skip()))(OptimizerHints.empty, None), /* def getClass(): java.lang.Class[_] = (this) */ MethodDef( @@ -45,7 +45,7 @@ object JavaLangObject { Ident("getClass__jl_Class", Some("getClass__jl_Class")), Nil, ClassType(ClassClass), - { + Some { GetClass(This()(ThisType)) })(OptimizerHints.empty.withInline(true), None), @@ -55,7 +55,7 @@ object JavaLangObject { Ident("hashCode__I", Some("hashCode__I")), Nil, IntType, - { + Some { Apply( LoadModule(ClassType("jl_System$")), Ident("identityHashCode__O__I", Some("identityHashCode")), @@ -69,7 +69,7 @@ object JavaLangObject { List(ParamDef(Ident("that", Some("that")), AnyType, mutable = false, rest = false)), BooleanType, - { + Some { BinaryOp(BinaryOp.===, This()(ThisType), VarRef(Ident("that", Some("that")))(AnyType)) @@ -84,7 +84,7 @@ object JavaLangObject { Ident("clone__O", Some("clone__O")), Nil, AnyType, - { + Some { If(IsInstanceOf(This()(ThisType), ClassType("jl_Cloneable")), { Apply(LoadModule(ClassType("sjsr_package$")), Ident("cloneObject__sjs_js_Object__sjs_js_Object", Some("cloneObject")), @@ -103,7 +103,7 @@ object JavaLangObject { Ident("toString__T", Some("toString__T")), Nil, ClassType(StringClass), - { + Some { BinaryOp(BinaryOp.String_+, BinaryOp(BinaryOp.String_+, Apply( Apply(This()(ThisType), @@ -130,7 +130,7 @@ object JavaLangObject { Ident("notify__V", Some("notify__V")), Nil, NoType, - Skip())(OptimizerHints.empty, None), + Some(Skip()))(OptimizerHints.empty, None), /* def notifyAll(): Unit = () */ MethodDef( @@ -138,7 +138,7 @@ object JavaLangObject { Ident("notifyAll__V", Some("notifyAll__V")), Nil, NoType, - Skip())(OptimizerHints.empty, None), + Some(Skip()))(OptimizerHints.empty, None), /* def finalize(): Unit = () */ MethodDef( @@ -146,7 +146,7 @@ object JavaLangObject { Ident("finalize__V", Some("finalize__V")), Nil, NoType, - Skip())(OptimizerHints.empty, None), + Some(Skip()))(OptimizerHints.empty, None), // Exports @@ -156,7 +156,7 @@ object JavaLangObject { StringLiteral("toString"), Nil, AnyType, - { + Some { Apply(This()(ThisType), Ident("toString__T", Some("toString__T")), Nil)(ClassType(StringClass)) diff --git a/project/JavaLangString.scala b/project/JavaLangString.scala index e5a186d675..b0509ec40a 100644 --- a/project/JavaLangString.scala +++ b/project/JavaLangString.scala @@ -40,7 +40,7 @@ object JavaLangString { List(ParamDef(Ident("that", Some("that")), AnyType, mutable = false, rest = false)), BooleanType, - { + Some { BinaryOp(BinaryOp.===, This()(ThisType), VarRef(Ident("that", Some("that")))(AnyType)) @@ -52,7 +52,7 @@ object JavaLangString { Ident("hashCode__I", Some("hashCode__I")), Nil, IntType, - { + Some { Apply( LoadModule(ClassType("sjsr_RuntimeString$")), Ident("hashCode__T__I", Some("hashCode__T__I")), @@ -66,7 +66,7 @@ object JavaLangString { List(ParamDef(Ident("that", Some("that")), ThisType, mutable = false, rest = false)), IntType, - { + Some { Apply( LoadModule(ClassType("sjsr_RuntimeString$")), Ident("compareTo__T__T__I", Some("compareTo__T__T__I")), @@ -82,7 +82,7 @@ object JavaLangString { List(ParamDef(Ident("that", Some("that")), AnyType, mutable = false, rest = false)), IntType, - { + Some { Apply( This()(ThisType), Ident("compareTo__T__I", Some("compareTo__T__I")), @@ -97,7 +97,7 @@ object JavaLangString { Ident("toString__T", Some("toString__T")), Nil, ClassType(StringClass), - { + Some { This()(ThisType) })(OptimizerHints.empty.withInline(true), None), @@ -108,7 +108,7 @@ object JavaLangString { List(ParamDef(Ident("i", Some("i")), IntType, mutable = false, rest = false)), IntType, - { + Some { Apply( LoadModule(ClassType("sjsr_RuntimeString$")), Ident("charAt__T__I__C", Some("charAt__T__I__C")), @@ -123,7 +123,7 @@ object JavaLangString { Ident("length__I", Some("length__I")), Nil, IntType, - { + Some { Apply( LoadModule(ClassType("sjsr_RuntimeString$")), Ident("length__T__I", Some("length__T__I")), @@ -144,7 +144,7 @@ object JavaLangString { mutable = false, rest = false) ), ClassType("jl_CharSequence"), - { + Some { Apply( LoadModule(ClassType("sjsr_RuntimeString$")), Ident("subSequence__T__I__I__jl_CharSequence", diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala index 24906c90f4..5c0ada193c 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala @@ -109,7 +109,7 @@ final class ClosureLinkerBackend( def exportName(tree: Tree): String = (tree: @unchecked) match { case MethodDef(_, StringLiteral(name), _, _, _) => name - case PropertyDef(StringLiteral(name), _, _, _) => name + case PropertyDef(StringLiteral(name), _, _) => name } val exportedPropertyNames = for { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala index 03c8cfe6d4..3018978af4 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala @@ -161,10 +161,10 @@ object LinkedClass { // Normal methods case m: MethodDef if m.name.isInstanceOf[Ident] => - if (m.body == EmptyTree) - abstractMethods += linkedMethod(m) - else + if (m.body.isDefined) memberMethods += linkedMethod(m) + else + abstractMethods += linkedMethod(m) case m: MethodDef if m.name.isInstanceOf[StringLiteral] => exportedMembers += linkedMethod(m) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala index 6cb48de5f5..00755f0539 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala @@ -377,9 +377,6 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { // VarDefs at the end of block. Normal VarDefs are handled in // transformBlockStats - case VarDef(_, _, _, EmptyTree) => - js.Skip() - case VarDef(_, _, _, rhs) => pushLhsInto(Lhs.Discard, rhs, tailPosLabels) @@ -1187,34 +1184,26 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { } } - case Try(block, errVar, handler, finalizer) => + /* The Google Closure Compiler used to wrongly eliminate finally blocks, + * if the catch block throws an exception. + * Issues: #563, google/closure-compiler#186 + * + * Therefore, we do not special case TryFinally(TryCatch(...)). + * We should do this now, since GCC seems to have fixed it (#2619). + */ + + case TryCatch(block, errVar, handler) => extractLet { newLhs => val newBlock = pushLhsInto(newLhs, block, tailPosLabels) - val newHandler = - if (handler == EmptyTree) js.EmptyTree - else pushLhsInto(newLhs, handler, tailPosLabels) - val newFinalizer = - if (finalizer == EmptyTree) js.EmptyTree - else transformStat(finalizer, tailPosLabels) - - if (newHandler != js.EmptyTree && newFinalizer != js.EmptyTree) { - /* The Google Closure Compiler wrongly eliminates finally blocks, if - * the catch block throws an exception. - * Issues: #563, google/closure-compiler#186 - * - * Therefore, we desugar - * - * try { ... } catch { ... } finally { ... } - * - * into - * - * try { try { ... } catch { ... } } finally { ... } - */ - js.Try(js.Try(newBlock, errVar, newHandler, js.EmptyTree), - errVar, js.EmptyTree, newFinalizer) - } else { - js.Try(newBlock, errVar, newHandler, newFinalizer) - } + val newHandler = pushLhsInto(newLhs, handler, tailPosLabels) + js.Try(newBlock, errVar, newHandler, js.EmptyTree) + } + + case TryFinally(block, finalizer) => + extractLet { newLhs => + val newBlock = pushLhsInto(newLhs, block, tailPosLabels) + val newFinalizer = transformStat(finalizer, tailPosLabels) + js.Try(newBlock, js.Ident("dummy"), js.EmptyTree, newFinalizer) } // TODO Treat throw as an LHS? @@ -1252,9 +1241,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { caze } } - val newDefault = - if (default == EmptyTree) js.EmptyTree - else pushLhsInto(newLhs, default, tailPosLabels) + val newDefault = pushLhsInto(newLhs, default, tailPosLabels) js.Switch(transformExpr(newSelector), newCases, newDefault) } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala index e7fceb14fe..e379ba6096 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala @@ -256,7 +256,7 @@ private[emitter] final class ScalaJSClassEmitter( tree.exportedMembers.map(_.tree) collectFirst { case MethodDef(false, StringLiteral("constructor"), params, _, body) => desugarToFunction(this, tree.encodedName, - params, body, isStat = true) + params, body.get, isStat = true) } getOrElse { throw new IllegalArgumentException( s"${tree.encodedName} does not have an exported constructor") @@ -282,10 +282,13 @@ private[emitter] final class ScalaJSClassEmitter( /** Generates a method. */ def genMethod(className: String, method: MethodDef)( implicit globalKnowledge: GlobalKnowledge): js.Tree = { + val methodBody = method.body.getOrElse( + throw new AssertionError("Cannot generate an abstract method")) + implicit val pos = method.pos val methodFun0 = desugarToFunction(this, className, - method.args, method.body, method.resultType == NoType) + method.args, methodBody, method.resultType == NoType) val methodFun = if (Definitions.isConstructorName(method.name.name)) { // init methods have to return `this` so that we can chain them to `new` @@ -328,7 +331,7 @@ private[emitter] final class ScalaJSClassEmitter( val thisIdent = js.Ident("$thiz", Some("this")) val methodFun0 = desugarToFunction(this, className, Some(thisIdent), - method.args, method.body, method.resultType == NoType) + method.args, method.body.get, method.resultType == NoType) val methodFun = js.Function( js.ParamDef(thisIdent, rest = false) :: methodFun0.args, @@ -374,31 +377,26 @@ private[emitter] final class ScalaJSClassEmitter( js.ObjectConstr(transformIdent(id) -> js.IntLiteral(0) :: Nil)) } - // Options passed to the defineProperty method - val descriptor = js.ObjectConstr { - // Basic config - val base = - js.StringLiteral("enumerable") -> js.BooleanLiteral(true) :: Nil - - // Optionally add getter - val wget = { - if (property.getterBody == EmptyTree) base - else { - val fun = desugarToFunction(this, className, - Nil, property.getterBody, isStat = false) - js.StringLiteral("get") -> fun :: base - } - } + // optional getter definition + val optGetter = property.getterBody map { body => + val fun = desugarToFunction(this, className, Nil, body, isStat = false) + js.StringLiteral("get") -> fun + } - // Optionally add setter - if (property.setterBody == EmptyTree) wget - else { - val fun = desugarToFunction(this, className, - property.setterArg :: Nil, property.setterBody, isStat = true) - js.StringLiteral("set") -> fun :: wget - } + // optional setter definition + val optSetter = property.setterArgAndBody map { case (arg, body) => + val fun = desugarToFunction(this, className, arg :: Nil, + body, isStat = true) + js.StringLiteral("set") -> fun } + // Options passed to the defineProperty method + val descriptor = js.ObjectConstr( + optGetter.toList ++ + optSetter ++ + List(js.StringLiteral("enumerable") -> js.BooleanLiteral(true)) + ) + js.Apply(defProp, proto :: name :: descriptor :: Nil) } @@ -408,22 +406,19 @@ private[emitter] final class ScalaJSClassEmitter( val propName = genPropertyName(property.name) - val getter = { - if (property.getterBody == EmptyTree) js.Skip() - else { - val fun = desugarToFunction(this, className, - Nil, property.getterBody, isStat = false) - js.GetterDef(static = false, propName, fun.body) - } + val getter = property.getterBody.fold[js.Tree] { + js.Skip() + } { body => + val fun = desugarToFunction(this, className, Nil, body, isStat = false) + js.GetterDef(static = false, propName, fun.body) } - val setter = { - if (property.setterBody == EmptyTree) js.Skip() - else { - val fun = desugarToFunction(this, className, - property.setterArg :: Nil, property.setterBody, isStat = true) - js.SetterDef(static = false, propName, fun.args.head, fun.body) - } + val setter = property.setterArgAndBody.fold[js.Tree] { + js.Skip() + } { case (arg, body) => + val fun = desugarToFunction(this, className, arg :: Nil, + body, isStat = true) + js.SetterDef(static = false, propName, fun.args.head, fun.body) } js.Block(getter, setter) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 3ae3572709..19580ad84a 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -239,13 +239,13 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { else ClassType(classDef.name.name) val bodyEnv = Env.fromSignature(thisType, params, resultType, isConstructor) - if (body == EmptyTree) { + body.fold { // Abstract if (static) reportError(s"Static method ${classDef.name.name}.$name cannot be abstract") else if (isConstructor) reportError(s"Constructor ${classDef.name.name}.$name cannot be abstract") - } else { + } { body => // Concrete if (resultType == NoType) typecheckStat(body, bodyEnv) @@ -297,8 +297,12 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { if (classDef.kind.isJSClass) AnyType else ClassType(classDef.name.name) - val bodyEnv = Env.fromSignature(thisType, params, resultType) - typecheckExpect(body, bodyEnv, resultType) + body.fold { + reportError("Exported method cannot be abstract") + } { body => + val bodyEnv = Env.fromSignature(thisType, params, resultType) + typecheckExpect(body, bodyEnv, resultType) + } } } @@ -312,41 +316,45 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { "but must be NoType") } - val bodyStats = body match { - case Block(stats) => stats - case _ => body :: Nil - } + body.fold { + reportError("JS class constructor cannot be abstract.") + } { body => + val bodyStats = body match { + case Block(stats) => stats + case _ => body :: Nil + } - val (prepStats, superCallAndRest) = - bodyStats.span(!_.isInstanceOf[JSSuperConstructorCall]) + val (prepStats, superCallAndRest) = + bodyStats.span(!_.isInstanceOf[JSSuperConstructorCall]) - val (superCall, restStats) = superCallAndRest match { - case (superCall: JSSuperConstructorCall) :: restStats => - (superCall, restStats) - case _ => - reportError( - "A JS class constructor must contain one super constructor call " + - "at the top-level") - (JSSuperConstructorCall(Nil)(methodDef.pos), Nil) - } + val (superCall, restStats) = superCallAndRest match { + case (superCall: JSSuperConstructorCall) :: restStats => + (superCall, restStats) + case _ => + reportError( + "A JS class constructor must contain one super constructor " + + "call at the top-level") + (JSSuperConstructorCall(Nil)(methodDef.pos), Nil) + } - val initialEnv = Env.fromSignature(NoType, params, NoType, - isConstructor = true) + val initialEnv = Env.fromSignature(NoType, params, NoType, + isConstructor = true) - val preparedEnv = (initialEnv /: prepStats) { (prevEnv, stat) => - typecheckStat(stat, prevEnv) - } + val preparedEnv = (initialEnv /: prepStats) { (prevEnv, stat) => + typecheckStat(stat, prevEnv) + } - for (arg <- superCall.args) - typecheckExprOrSpread(arg, preparedEnv) + for (arg <- superCall.args) + typecheckExprOrSpread(arg, preparedEnv) - val restEnv = preparedEnv.withThis(AnyType) - typecheckStat(Block(restStats)(methodDef.pos), restEnv) + val restEnv = preparedEnv.withThis(AnyType) + typecheckStat(Block(restStats)(methodDef.pos), restEnv) + } } private def checkExportedPropertyDef(propDef: PropertyDef, classDef: LinkedClass): Unit = withPerMethodState { - val PropertyDef(_, getterBody, setterArg, setterBody) = propDef + val PropertyDef(_, getterBody, setterArgAndBody) = propDef implicit val ctx = ErrorContext(propDef) if (!classDef.kind.isAnyScalaJSDefinedClass) { @@ -358,12 +366,12 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { if (classDef.kind.isJSClass) AnyType else ClassType(classDef.name.name) - if (getterBody != EmptyTree) { + getterBody.foreach { getterBody => val getterBodyEnv = Env.fromSignature(thisType, Nil, AnyType) typecheckExpect(getterBody, getterBodyEnv, AnyType) } - if (setterBody != EmptyTree) { + setterArgAndBody.foreach { case (setterArg, setterBody) => if (setterArg.ptpe != AnyType) reportError("Setter argument of exported property def has type "+ s"${setterArg.ptpe}, but must be Any") @@ -499,16 +507,16 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { typecheckExpect(cond, env, BooleanType) env - case Try(block, errVar, handler, finalizer) => + case TryCatch(block, errVar, handler) => typecheckStat(block, env) - if (handler != EmptyTree) { - val handlerEnv = - env.withLocal(LocalDef(errVar.name, AnyType, false)(errVar.pos)) - typecheckStat(handler, handlerEnv) - } - if (finalizer != EmptyTree) { - typecheckStat(finalizer, env) - } + val handlerEnv = + env.withLocal(LocalDef(errVar.name, AnyType, false)(errVar.pos)) + typecheckStat(handler, handlerEnv) + env + + case TryFinally(block, finalizer) => + typecheckStat(block, env) + typecheckStat(finalizer, env) env case Match(selector, cases, default) => @@ -612,17 +620,17 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { label.foreach(checkDeclareLabel) typecheckStat(body, env) - case Try(block, errVar, handler, finalizer) => + case TryCatch(block, errVar, handler) => val tpe = tree.tpe typecheckExpect(block, env, tpe) - if (handler != EmptyTree) { - val handlerEnv = - env.withLocal(LocalDef(errVar.name, AnyType, false)(errVar.pos)) - typecheckExpect(handler, handlerEnv, tpe) - } - if (finalizer != EmptyTree) { - typecheckStat(finalizer, env) - } + val handlerEnv = + env.withLocal(LocalDef(errVar.name, AnyType, false)(errVar.pos)) + typecheckExpect(handler, handlerEnv, tpe) + + case TryFinally(block, finalizer) => + val tpe = tree.tpe + typecheckExpect(block, env, tpe) + typecheckStat(finalizer, env) case Throw(expr) => typecheckExpr(expr, env) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index 1c105554f2..516eb6aee8 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -232,10 +232,10 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions if (analyzerInfo.methodInfos(m.name.name).isReachable) { if (m.name.isInstanceOf[StringLiteral]) exportedMembers += linkedMethod(m) - else if (m.body == EmptyTree) - abstractMethods += linkedMethod(m) - else + else if (m.body.isDefined) memberMethods += linkedMethod(m) + else + abstractMethods += linkedMethod(m) } case m: PropertyDef => @@ -328,8 +328,8 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions val superClassType = ClassType(classInfo.superClass.encodedName) MethodDef(static = false, ctorIdent, params, NoType, - ApplyStatically(This()(currentClassType), - superClassType, ctorIdent, params.map(_.ref))(NoType))( + Some(ApplyStatically(This()(currentClassType), + superClassType, ctorIdent, params.map(_.ref))(NoType)))( OptimizerHints.empty, inheritedMDef.hash) // over-approximation } @@ -364,7 +364,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions call } - MethodDef(static = false, proxyIdent, params, AnyType, body)( + MethodDef(static = false, proxyIdent, params, AnyType, Some(body))( OptimizerHints.empty, targetMDef.hash) } @@ -388,7 +388,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions This()(currentClassType), ClassType(targetInterface), targetIdent, params.map(_.ref))(targetMDef.resultType) - MethodDef(static = false, bridgeIdent, params, targetMDef.resultType, body)( + MethodDef(static = false, bridgeIdent, params, targetMDef.resultType, Some(body))( OptimizerHints.empty, targetMDef.hash) } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala index eb2755d0cd..175f4ba779 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala @@ -625,7 +625,7 @@ abstract class GenIncOptimizer private[optimizer] (semantics: Semantics, case Assign(Select(This(), _), rhs) => isTriviallySideEffectFree(rhs) case ApplyStatic(ClassType(cls), methodName, List(This())) => - statics(cls).methods(methodName.name).originalDef.body match { + statics(cls).methods(methodName.name).originalDef.body.exists { case Skip() => true case _ => false } @@ -641,7 +641,11 @@ abstract class GenIncOptimizer private[optimizer] (semantics: Semantics, case _ => isTriviallySideEffectFree(tree) } - isElidableStat(impl.originalDef.body) + impl.originalDef.body.fold { + throw new AssertionError("Module constructor cannot be abstract") + } { body => + isElidableStat(body) + } } /** All the methods of this class, including inherited ones. diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index b6ebfad66c..ab5ad27acb 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -126,7 +126,11 @@ private[optimizer] abstract class OptimizerCore( def optimize(thisType: Type, originalDef: MethodDef): LinkedMember[MethodDef] = { try { - val MethodDef(static, name, params, resultType, body) = originalDef + val MethodDef(static, name, params, resultType, optBody) = originalDef + val body = optBody getOrElse { + throw new AssertionError("Methods to optimize must be concrete") + } + val (newParams, newBody1) = try { transformIsolatedBody(Some(myself), thisType, params, resultType, body) } catch { @@ -141,7 +145,7 @@ private[optimizer] abstract class OptimizerCore( if (name.name == "init___") tryElimStoreModule(newBody1) else newBody1 val m = MethodDef(static, name, newParams, resultType, - newBody)(originalDef.optimizerHints, None)(originalDef.pos) + Some(newBody))(originalDef.optimizerHints, None)(originalDef.pos) val info = Infos.generateMethodInfo(m) new LinkedMember(info, m, None) @@ -438,12 +442,7 @@ private[optimizer] abstract class OptimizerCore( case _ => DoWhile(newBody, newCond, None) } - case Try(block, errVar, EmptyTree, finalizer) => - val newBlock = transform(block, isStat) - val newFinalizer = transformStat(finalizer) - Try(newBlock, errVar, EmptyTree, newFinalizer)(newBlock.tpe) - - case Try(block, errVar @ Ident(name, originalName), handler, finalizer) => + case TryCatch(block, errVar @ Ident(name, originalName), handler) => val newBlock = transform(block, isStat) val newName = freshLocalName(name, false) @@ -455,11 +454,14 @@ private[optimizer] abstract class OptimizerCore( transform(handler, isStat)(handlerScope) } - val newFinalizer = transformStat(finalizer) - val refinedType = constrainedLub(newBlock.tpe, newHandler.tpe, tree.tpe) - Try(newBlock, Ident(newName, newOriginalName)(errVar.pos), - newHandler, newFinalizer)(refinedType) + TryCatch(newBlock, Ident(newName, newOriginalName)(errVar.pos), + newHandler)(refinedType) + + case TryFinally(block, finalizer) => + val newBlock = transform(block, isStat) + val newFinalizer = transformStat(finalizer) + TryFinally(newBlock, newFinalizer) case Throw(expr) => Throw(transformExpr(expr)) @@ -669,8 +671,7 @@ private[optimizer] abstract class OptimizerCore( // Trees that need not be transformed case _:Skip | _:Debugger | _:LoadModule | _:LoadJSConstructor | - _:LoadJSModule | _:JSLinkingInfo | _:Literal | - EmptyTree => + _:LoadJSModule | _:JSLinkingInfo | _:Literal => tree case _ => @@ -1423,10 +1424,10 @@ private[optimizer] abstract class OptimizerCore( private def canMultiInline(impls: List[MethodID]): Boolean = { // TODO? Inline multiple non-forwarders with the exact same body? impls.forall(_.isForwarder) && - (getMethodBody(impls.head).body match { + (getMethodBody(impls.head).body.get match { // Trait impl forwarder case ApplyStatic(ClassType(staticCls), Ident(methodName, _), _) => - impls.tail.forall(getMethodBody(_).body match { + impls.tail.forall(getMethodBody(_).body.get match { case ApplyStatic(ClassType(`staticCls`), Ident(`methodName`, _), _) => true case _ => @@ -1435,7 +1436,7 @@ private[optimizer] abstract class OptimizerCore( // Shape of forwards to default methods case ApplyStatically(This(), cls, Ident(methodName, _), args) => - impls.tail.forall(getMethodBody(_).body match { + impls.tail.forall(getMethodBody(_).body.get match { case ApplyStatically(This(), `cls`, Ident(`methodName`, _), _) => true case _ => @@ -1444,7 +1445,7 @@ private[optimizer] abstract class OptimizerCore( // Bridge method case MaybeBox(Apply(This(), Ident(methodName, _), referenceArgs), boxID) => - impls.tail.forall(getMethodBody(_).body match { + impls.tail.forall(getMethodBody(_).body.get match { case MaybeBox(Apply(This(), Ident(`methodName`, _), implArgs), `boxID`) => referenceArgs.zip(implArgs) forall { case (MaybeUnbox(_, unboxID1), MaybeUnbox(_, unboxID2)) => @@ -1687,9 +1688,12 @@ private[optimizer] abstract class OptimizerCore( attemptedInlining += target - val MethodDef(static, _, formals, resultType, body) = getMethodBody(target) + val MethodDef(static, _, formals, resultType, optBody) = getMethodBody(target) assert(static == optReceiver.isEmpty, "There must be receiver if and only if the method is not static") + val body = optBody.getOrElse { + throw new AssertionError("A method to inline must be conrete") + } body match { case Skip() => @@ -2038,7 +2042,7 @@ private[optimizer] abstract class OptimizerCore( val targetMethodDef = getMethodBody(target) val formals = targetMethodDef.args - val stats = targetMethodDef.body match { + val stats = targetMethodDef.body.get match { case Block(stats) => stats case singleStat => List(singleStat) } @@ -4648,7 +4652,10 @@ private[optimizer] object OptimizerCore { var isForwarder: Boolean = false protected def updateInlineable(): Unit = { - val MethodDef(_, Ident(methodName, _), params, _, body) = originalDef + val MethodDef(_, Ident(methodName, _), params, _, optBody) = originalDef + val body = optBody getOrElse { + throw new AssertionError("Methods in optimizer must be concrete") + } isForwarder = body match { // Shape of forwarders to trait impls @@ -4686,7 +4693,6 @@ private[optimizer] object OptimizerCore { inlineable = !optimizerHints.noinline shouldInline = inlineable && { optimizerHints.inline || isForwarder || { - val MethodDef(_, _, params, _, body) = originalDef body match { case _:Skip | _:This | _:Literal => true From 1e6ac15eee1ad3f22ddb81b385a32d9d5efd313a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 13 Oct 2016 10:04:10 +0200 Subject: [PATCH 0036/2665] Version 0.6.13. --- .../scala/org/scalajs/core/ir/ScalaJSVersions.scala | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index c733a60ffe..81cf7560b9 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.13-SNAPSHOT" + val current: String = "0.6.13" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" @@ -21,11 +21,13 @@ object ScalaJSVersions { * - a prior release version (i.e. "0.5.0", *not* "0.5.0-SNAPSHOT") * - `current` */ - val binaryEmitted: String = current + val binaryEmitted: String = "0.6.13" /** Versions whose binary files we can support (used by deserializer) */ - val binarySupported: Set[String] = - Set("0.6.0", "0.6.3", "0.6.4", "0.6.5", "0.6.6", "0.6.8", binaryEmitted) + val binarySupported: Set[String] = { + Set("0.6.0", "0.6.3", "0.6.4", "0.6.5", "0.6.6", "0.6.8", "0.6.13", + binaryEmitted) + } // Just to be extra safe assert(binarySupported contains binaryEmitted) From 86153dfcb9ab0cf72d008a67c505b000abc53311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 14 Oct 2016 00:14:17 +0200 Subject: [PATCH 0037/2665] Towards 0.6.14. --- .../org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- project/BinaryIncompatibilities.scala | 145 ------------------ project/Build.scala | 2 +- 3 files changed, 2 insertions(+), 147 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index 81cf7560b9..7b4fecc955 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.13" + val current: String = "0.6.14-SNAPSHOT" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 22050e5ee0..c77318b933 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -3,129 +3,9 @@ import com.typesafe.tools.mima.core.ProblemFilters._ object BinaryIncompatibilities { val IR = Seq( - // Breaking changes - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.ir.Trees#ClassDef.jsName"), - - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.ir.Trees$Try"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.ir.Trees$Try$"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.ir.Trees#MethodDef.apply"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.core.ir.Trees#MethodDef.body"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.ir.Trees#MethodDef.copy"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.ir.Trees#MethodDef.this"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.ir.Trees#PropertyDef.apply"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.ir.Trees#PropertyDef.copy"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.core.ir.Trees#PropertyDef.getterBody"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.ir.Trees#PropertyDef.setterArg"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.ir.Trees#PropertyDef.setterBody"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.ir.Trees#PropertyDef.this") ) val Tools = Seq( - // Breaking changes - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.LinkedClass.jsName"), - - // private, not an issue - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.analyzer.Analyzer#ClassInfo.isAnyRawJSType"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.analyzer.Analyzer#ClassInfo.isStaticModule"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.checker.IRChecker#CheckedClass.jsName"), - - // "sealed" trait, not an issue to add methods - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.LinkerPlatformExtensions.apply"), - - // private[emitter], not an issue - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring#JSDesugar.this"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.genRawJSClassConstructor"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.desugarTree"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.desugarToFunction"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.desugarToFunction"), - - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.Env"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring#Env.this"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring#Env.withLabeledExprLHS"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring#Env.lhsForLabeledExpr"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring#JSDesugar.pushLhsInto"), - - // private[emitter], not an issue - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.this"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genDefaultMethods"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.isInterface"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genConstructor"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genDefaultMethod"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genClass"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genConstructorExportDef"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genTypeData"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genProperty"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genES6Class"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.linkedClassByName"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genMethod"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genClassDef"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genClassExports"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genExportedMembers"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genStaticMembers"), - - // private[emitter], not an issue - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.CoreJSLibs.lib"), - - // private, not an issue - ProblemFilters.exclude[AbstractClassProblem]( - "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore$AllocationSite"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#AllocationSite.this"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#RefinedType.apply"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#RefinedType.apply"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#RefinedType.copy"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#RefinedType.allocationSite"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#RefinedType.this") ) val JSEnvs = Seq( @@ -135,40 +15,15 @@ object BinaryIncompatibilities { ) val SbtPlugin = Seq( - // private[sbtplugin], not an issue - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.sbtplugin.FrameworkDetector.this"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.sbtplugin.FrameworkDetector.detect") ) val TestAdapter = Seq( ) val CLI = Seq( - // private, not an issue - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.cli.Scalajsld#Options.this"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.cli.Scalajsld#Options.copy"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.cli.Scalajsld#Options.apply"), - ProblemFilters.exclude[MissingTypesProblem]( - "org.scalajs.cli.Scalajsld$Options$") ) val Library = Seq( - /* Technically breaking: remove `extends js.GlobalScope`. - * Even though not binary compatible at .class file level, this is binary - * compatible at the .sjsir level, because the parent js.GlobalScope is - * a JS type, so its IR type is `any` anyway. - * It is however not source compatible, but I'm willing to break the code - * of someone who would have declared a value of type js.GlobalScope. - */ - ProblemFilters.exclude[MissingTypesProblem]( - "scala.scalajs.js.URIUtils$"), - ProblemFilters.exclude[MissingTypesProblem]( - "scala.scalajs.js.timers.RawTimers$") ) val TestInterface = Seq( diff --git a/project/Build.scala b/project/Build.scala index d433ac31d0..337fb30d65 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -57,7 +57,7 @@ object Build { val shouldPartest = settingKey[Boolean]( "Whether we should partest the current scala version (and fail if we can't)") - val previousVersion = "0.6.12" + val previousVersion = "0.6.13" val previousSJSBinaryVersion = ScalaJSCrossVersion.binaryScalaJSVersion(previousVersion) val previousBinaryCrossVersion = From dc3fa7331e6ba75e1266831cd920e4af91e8f158 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 25 Sep 2016 00:41:44 +0200 Subject: [PATCH 0038/2665] Fix #2129: Only request source jars for scalalib updateClassifiers requests source and javadoc jars for all dependencies. This fails for the Scala.js compiler. Instead, we explicitly specify the scala-library sources as a dependency and read them from the normal update. --- project/Build.scala | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 337fb30d65..beeaa37fa3 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -838,6 +838,9 @@ object Build { // Tell the plugin to hack-fix bad classOf trees scalacOptions += "-P:scalajs:fixClassOf", + libraryDependencies += + "org.scala-lang" % "scala-library" % scalaVersion.value classifier "sources", + artifactPath in fetchScalaSource := target.value / "scalaSources" / scalaVersion.value, @@ -847,11 +850,11 @@ object Build { val ver = scalaVersion.value val trgDir = (artifactPath in fetchScalaSource).value - val report = updateClassifiers.value + val report = update.value val scalaLibSourcesJar = report.select( configuration = Set("compile"), module = moduleFilter(name = "scala-library"), - artifact = artifactFilter(`type` = "src")).headOption.getOrElse { + artifact = artifactFilter(classifier = "sources")).headOption.getOrElse { sys.error(s"Could not fetch scala-library sources for version $ver") } From fc6fb5787d4af859838c37c1a33642d49dc5b359 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 29 Jul 2016 16:28:32 +0200 Subject: [PATCH 0039/2665] Remove unused methods. --- project/BinaryIncompatibilities.scala | 5 +++++ .../backend/emitter/ScalaJSClassEmitter.scala | 13 ------------- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index c77318b933..b2d5245efd 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -6,6 +6,11 @@ object BinaryIncompatibilities { ) val Tools = Seq( + // private[emitter], not an issue + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genDeclareModule"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genDeclareTypeData") ) val JSEnvs = Seq( diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala index e379ba6096..39357aaf67 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala @@ -38,19 +38,6 @@ private[emitter] final class ScalaJSClassEmitter( private implicit def implicitOutputMode: OutputMode = outputMode - def genDeclareTypeData(tree: LinkedClass): js.Tree = { - implicit val pos = tree.pos - envFieldDef("d", tree.encodedName, js.Null(), mutable = true) - } - - def genDeclareModule(tree: LinkedClass): js.Tree = { - implicit val pos = tree.pos - if (tree.kind.hasModuleAccessor) - envFieldDef("n", tree.encodedName, js.Undefined(), mutable = true) - else - js.Skip() - } - /** Desugar a Scala.js class into ECMAScript 5 constructs * * @param tree The IR tree to emit to raw JavaScript From 68634518a96bfdd98671f50f6c49910bfacbe30c Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 15 Oct 2016 15:50:40 +0200 Subject: [PATCH 0040/2665] Fix #2622: Remove js.EmtpyTree - In VarDef and Let, replace by Option[Tree] - Split Try into TryCatch and TryFinally - In Switch, replaced by Skip As a side effect, this fixes #2619. --- project/BinaryIncompatibilities.scala | 24 +++++++- .../closure/ClosureAstTransformer.scala | 36 +++++------- .../core/tools/javascript/Printers.scala | 55 +++++++++++-------- .../scalajs/core/tools/javascript/Trees.scala | 12 ++-- .../linker/backend/emitter/JSDesugaring.scala | 30 +++++----- 5 files changed, 92 insertions(+), 65 deletions(-) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index b2d5245efd..1e1772fdbe 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -10,7 +10,29 @@ object BinaryIncompatibilities { ProblemFilters.exclude[MissingMethodProblem]( "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genDeclareModule"), ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genDeclareTypeData") + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genDeclareTypeData"), + + // Breaking (remove js.EmptyTree) + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "org.scalajs.core.tools.javascript.Trees#Let.apply"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "org.scalajs.core.tools.javascript.Trees#Let.copy"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.core.tools.javascript.Trees#Let.rhs"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "org.scalajs.core.tools.javascript.Trees#Let.this"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.tools.javascript.Trees$Try"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.tools.javascript.Trees$Try$"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "org.scalajs.core.tools.javascript.Trees#VarDef.apply"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "org.scalajs.core.tools.javascript.Trees#VarDef.copy"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.core.tools.javascript.Trees#VarDef.rhs"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "org.scalajs.core.tools.javascript.Trees#VarDef.this") ) val JSEnvs = Seq( diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala index 8e1606ad38..9fea439c05 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala @@ -29,11 +29,9 @@ private[closure] class ClosureAstTransformer(relativizeBaseURI: Option[URI]) { implicit val pos = pos_in wrapTransform(tree) { - case VarDef(ident, EmptyTree) => - new Node(Token.VAR, transformName(ident)) - case VarDef(ident, rhs) => + case VarDef(ident, optRhs) => val node = transformName(ident) - node.addChildToFront(transformExpr(rhs)) + optRhs.foreach(rhs => node.addChildToFront(transformExpr(rhs))) new Node(Token.VAR, node) case Skip() => new Node(Token.EMPTY) @@ -41,8 +39,6 @@ private[closure] class ClosureAstTransformer(relativizeBaseURI: Option[URI]) { transformBlock(stats, pos) case Labeled(label, body) => new Node(Token.LABEL, transformLabel(label), transformBlock(body)) - case Return(EmptyTree) => - new Node(Token.RETURN) case Return(expr) => new Node(Token.RETURN, transformExpr(expr)) case If(cond, thenp, Skip()) => @@ -64,26 +60,26 @@ private[closure] class ClosureAstTransformer(relativizeBaseURI: Option[URI]) { new Node(Token.DO, transformBlock(body), transformExpr(cond)) new Node(Token.LABEL, transformLabel(label), setNodePosition(doNode, pos)) - case Try(block, errVar, handler, EmptyTree) => + case TryFinally(TryCatch(block, errVar, handler), finalizer) => val catchPos = handler.pos orElse pos val catchNode = new Node(Token.CATCH, transformName(errVar), transformBlock(handler)) val blockNode = new Node(Token.BLOCK, setNodePosition(catchNode, catchPos)) new Node(Token.TRY, transformBlock(block), - setNodePosition(blockNode, catchPos)) - case Try(block, _, EmptyTree, finalizer) => - val blockNode = setNodePosition(new Node(Token.BLOCK), pos) - new Node(Token.TRY, transformBlock(block), blockNode, - transformBlock(finalizer)) - case Try(block, errVar, handler, finalizer) => + setNodePosition(blockNode, catchPos), transformBlock(finalizer)) + case TryCatch(block, errVar, handler) => val catchPos = handler.pos orElse pos val catchNode = new Node(Token.CATCH, transformName(errVar), transformBlock(handler)) val blockNode = new Node(Token.BLOCK, setNodePosition(catchNode, catchPos)) new Node(Token.TRY, transformBlock(block), - setNodePosition(blockNode, catchPos), transformBlock(finalizer)) + setNodePosition(blockNode, catchPos)) + case TryFinally(block, finalizer) => + val blockNode = setNodePosition(new Node(Token.BLOCK), pos) + new Node(Token.TRY, transformBlock(block), blockNode, + transformBlock(finalizer)) case Throw(expr) => new Node(Token.THROW, transformExpr(expr)) case Break(None) => @@ -106,13 +102,11 @@ private[closure] class ClosureAstTransformer(relativizeBaseURI: Option[URI]) { setNodePosition(caseNode, expr.pos orElse pos)) } - if (default != EmptyTree) { - val bodyNode = transformBlock(default) - bodyNode.putBooleanProp(Node.SYNTHETIC_BLOCK_PROP, true) - val caseNode = new Node(Token.DEFAULT_CASE, bodyNode) - switchNode.addChildToBack( - setNodePosition(caseNode, default.pos orElse pos)) - } + val bodyNode = transformBlock(default) + bodyNode.putBooleanProp(Node.SYNTHETIC_BLOCK_PROP, true) + val caseNode = new Node(Token.DEFAULT_CASE, bodyNode) + switchNode.addChildToBack( + setNodePosition(caseNode, default.pos orElse pos)) switchNode diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala index 83b1e167fa..7dde4e5aa4 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala @@ -108,9 +108,6 @@ object Printers { def printTree(tree: Tree, isStat: Boolean): Unit = { tree match { - case EmptyTree => - print("") - // Comments case DocComment(text) => @@ -135,18 +132,18 @@ object Printers { // Definitions - case VarDef(ident, rhs) => + case VarDef(ident, optRhs) => print("var ") print(ident) - if (rhs ne EmptyTree) { + optRhs foreach { rhs => print(" = ") print(rhs) } - case Let(ident, mutable, rhs) => + case Let(ident, mutable, optRhs) => print(if (mutable) "let " else "const ") print(ident) - if (rhs ne EmptyTree) { + optRhs foreach { rhs => print(" = ") print(rhs) } @@ -227,19 +224,29 @@ object Printers { print(cond) print(')') - case Try(block, errVar, handler, finalizer) => + case TryFinally(TryCatch(block, errVar, handler), finalizer) => print("try ") printBlock(block) - if (handler ne EmptyTree) { - print(" catch (") - print(errVar) - print(") ") - printBlock(handler) - } - if (finalizer ne EmptyTree) { - print(" finally ") - printBlock(finalizer) - } + print(" catch (") + print(errVar) + print(") ") + printBlock(handler) + print(" finally ") + printBlock(finalizer) + + case TryCatch(block, errVar, handler) => + print("try ") + printBlock(block) + print(" catch (") + print(errVar) + print(") ") + printBlock(handler) + + case TryFinally(block, finalizer) => + print("try ") + printBlock(block) + print(" finally ") + printBlock(finalizer) case Throw(expr) => print("throw ") @@ -278,11 +285,15 @@ object Printers { printBlock(next._2) } } - if (default ne EmptyTree) { - println() - print("default: ") - printBlock(default) + + default match { + case Skip() => + case _ => + println() + print("default: ") + printBlock(default) } + undent() println() print('}') diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala index 540182e6d3..3772f96964 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala @@ -30,10 +30,6 @@ object Trees { } } - case object EmptyTree extends Tree { - val pos = NoPosition - } - // Comments case class DocComment(text: String)(implicit val pos: Position) extends Tree @@ -64,12 +60,12 @@ object Trees { def ref(implicit pos: Position): Tree = VarRef(name) } - case class VarDef(name: Ident, rhs: Tree)(implicit val pos: Position) extends LocalDef { + case class VarDef(name: Ident, rhs: Option[Tree])(implicit val pos: Position) extends LocalDef { def mutable: Boolean = true } /** ES6 let or const (depending on the mutable flag). */ - case class Let(name: Ident, mutable: Boolean, rhs: Tree)(implicit val pos: Position) extends LocalDef + case class Let(name: Ident, mutable: Boolean, rhs: Option[Tree])(implicit val pos: Position) extends LocalDef case class ParamDef(name: Ident, rest: Boolean)(implicit val pos: Position) extends LocalDef { def mutable: Boolean = true @@ -121,7 +117,9 @@ object Trees { case class DoWhile(body: Tree, cond: Tree, label: Option[Ident] = None)(implicit val pos: Position) extends Tree - case class Try(block: Tree, errVar: Ident, handler: Tree, finalizer: Tree)(implicit val pos: Position) extends Tree + case class TryCatch(block: Tree, errVar: Ident, handler: Tree)(implicit val pos: Position) extends Tree + + case class TryFinally(block: Tree, finalizer: Tree)(implicit val pos: Position) extends Tree case class Throw(expr: Tree)(implicit val pos: Position) extends Tree diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala index 00755f0539..7df65927cf 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala @@ -1010,7 +1010,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { }) case _ => - genLet(ident, mutable = true, js.EmptyTree) + genEmptyMutableLet(ident) } } @@ -1184,26 +1184,18 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { } } - /* The Google Closure Compiler used to wrongly eliminate finally blocks, - * if the catch block throws an exception. - * Issues: #563, google/closure-compiler#186 - * - * Therefore, we do not special case TryFinally(TryCatch(...)). - * We should do this now, since GCC seems to have fixed it (#2619). - */ - case TryCatch(block, errVar, handler) => extractLet { newLhs => val newBlock = pushLhsInto(newLhs, block, tailPosLabels) val newHandler = pushLhsInto(newLhs, handler, tailPosLabels) - js.Try(newBlock, errVar, newHandler, js.EmptyTree) + js.TryCatch(newBlock, errVar, newHandler) } case TryFinally(block, finalizer) => extractLet { newLhs => val newBlock = pushLhsInto(newLhs, block, tailPosLabels) val newFinalizer = transformStat(finalizer, tailPosLabels) - js.Try(newBlock, js.Ident("dummy"), js.EmptyTree, newFinalizer) + js.TryFinally(newBlock, newFinalizer) } // TODO Treat throw as an LHS? @@ -2135,9 +2127,19 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { implicit outputMode: OutputMode, pos: Position): js.LocalDef = { outputMode match { case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => - js.VarDef(name, rhs) + js.VarDef(name, Some(rhs)) + case OutputMode.ECMAScript6 => + js.Let(name, mutable, Some(rhs)) + } + } + + private[emitter] def genEmptyMutableLet(name: js.Ident)( + implicit outputMode: OutputMode, pos: Position): js.LocalDef = { + outputMode match { + case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => + js.VarDef(name, rhs = None) case OutputMode.ECMAScript6 => - js.Let(name, mutable, rhs) + js.Let(name, mutable = true, rhs = None) } } @@ -2356,7 +2358,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { // Make sure the function has a meaningful `name` property js.FunctionDef(globalVarIdent, args, body) case _ => - js.VarDef(globalVarIdent, value) + js.VarDef(globalVarIdent, Some(value)) } case OutputMode.ECMAScript6 => From 7242c7b711314f17f31234d36aa224f6669c2869 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 7 Nov 2016 15:10:01 +0100 Subject: [PATCH 0041/2665] Fix #2643: Do not replace `this` by `thisIdent` inside `Closure`s. `Closure`s reintroduce a new binding for `this`, which must not be replaced by `thisIdent`. --- project/BinaryIncompatibilities.scala | 6 +++++ .../jsinterop/ThisFunctionTest.scala | 27 +++++++++++++++++++ .../linker/backend/emitter/JSDesugaring.scala | 23 +++++++++------- 3 files changed, 46 insertions(+), 10 deletions(-) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 1e1772fdbe..a5987ce44d 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -12,6 +12,12 @@ object BinaryIncompatibilities { ProblemFilters.exclude[MissingMethodProblem]( "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genDeclareTypeData"), + // private, not an issue + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring#Env.this"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring#JSDesugar.this"), + // Breaking (remove js.EmptyTree) ProblemFilters.exclude[IncompatibleMethTypeProblem]( "org.scalajs.core.tools.javascript.Trees#Let.apply"), diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ThisFunctionTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ThisFunctionTest.scala index 1eb31a6a79..3a4c2be60a 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ThisFunctionTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ThisFunctionTest.scala @@ -71,4 +71,31 @@ class ThisFunctionTest { assertEquals("foo:42", f(obj, 42)) } + @Test def thisFunction_in_trait_issue2643(): Unit = { + trait TraitWithThisFunction { + def create = { + val f = { (passedThis: js.Dynamic) => + passedThis + } + js.Dynamic.literal( + "foo" -> ({ (passedThis: js.Dynamic) => { + passedThis + } }: js.ThisFunction0[js.Dynamic, js.Dynamic]), + "bar" -> js.ThisFunction.fromFunction1(f), + "foobar" -> (f: js.ThisFunction) + ) + } + } + + class TraitWithThisFunctionImpl extends TraitWithThisFunction + + val objFactory = new TraitWithThisFunctionImpl() + val obj = new TraitWithThisFunctionImpl().create + val thisValue = new js.Object + + assertSame(thisValue, obj.foo.call(thisValue)) + assertSame(thisValue, obj.bar.call(thisValue)) + assertSame(thisValue, obj.foobar.call(thisValue)) + } + } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala index 7df65927cf..aab779a6c3 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala @@ -217,8 +217,8 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { thisIdent: Option[js.Ident], params: List[ParamDef], body: Tree, isStat: Boolean)( implicit globalKnowledge: GlobalKnowledge, pos: Position): js.Function = { - new JSDesugar(classEmitter, enclosingClassName, - thisIdent).desugarToFunction(params, body, isStat) + new JSDesugar(classEmitter, enclosingClassName) + .desugarToFunction(params, body, isStat, Env.empty.withThisIdent(thisIdent)) } /** Desugars a statement or an expression. */ @@ -226,7 +226,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { classEmitter: ScalaJSClassEmitter, enclosingClassName: String, tree: Tree, isStat: Boolean)( implicit globalKnowledge: GlobalKnowledge): js.Tree = { - val desugar = new JSDesugar(classEmitter, enclosingClassName, None) + val desugar = new JSDesugar(classEmitter, enclosingClassName) if (isStat) desugar.transformStat(tree, Set.empty)(Env.empty) else @@ -240,8 +240,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { js.ParamDef(paramDef.name, paramDef.rest)(paramDef.pos) private class JSDesugar( - classEmitter: ScalaJSClassEmitter, enclosingClassName: String, - thisIdent: Option[js.Ident])( + classEmitter: ScalaJSClassEmitter, enclosingClassName: String)( implicit globalKnowledge: GlobalKnowledge) { private val semantics = classEmitter.semantics @@ -294,8 +293,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { /** Desugars parameters and body to a JS function. */ def desugarToFunction( - params: List[ParamDef], body: Tree, isStat: Boolean, - env0: Env = Env.empty)( + params: List[ParamDef], body: Tree, isStat: Boolean, env0: Env)( implicit pos: Position): js.Function = { val env = env0.withParams(params) @@ -1982,7 +1980,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { js.VarRef(name) case This() => - thisIdent.fold[js.Tree] { + env.thisIdent.fold[js.Tree] { js.This() } { ident => js.VarRef(ident) @@ -2426,6 +2424,7 @@ private object JSDesugaring { // Environment final class Env private ( + val thisIdent: Option[js.Ident], vars: Map[String, Boolean], labeledExprLHSes: Map[String, Lhs], defaultBreakTargets: Set[String] @@ -2437,6 +2436,9 @@ private object JSDesugaring { def isDefaultBreakTarget(label: String): Boolean = defaultBreakTargets.contains(label) + def withThisIdent(thisIdent: Option[js.Ident]): Env = + copy(thisIdent = thisIdent) + def withParams(params: List[ParamDef]): Env = { params.foldLeft(this) { case (env, ParamDef(name, tpe, mutable, _)) => @@ -2455,14 +2457,15 @@ private object JSDesugaring { copy(defaultBreakTargets = targets) private def copy( + thisIdent: Option[js.Ident] = this.thisIdent, vars: Map[String, Boolean] = this.vars, labeledExprLHSes: Map[String, Lhs] = this.labeledExprLHSes, defaultBreakTargets: Set[String] = this.defaultBreakTargets): Env = { - new Env(vars, labeledExprLHSes, defaultBreakTargets) + new Env(thisIdent, vars, labeledExprLHSes, defaultBreakTargets) } } object Env { - def empty: Env = new Env(Map.empty, Map.empty, Set.empty) + def empty: Env = new Env(None, Map.empty, Map.empty, Set.empty) } } From d94583cb065942a2178247687441ede4671942ac Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 29 Oct 2016 16:49:17 +0200 Subject: [PATCH 0042/2665] Fix #2626: Trivial module accessors not elided in 2.12 --- .../frontend/optimizer/GenIncOptimizer.scala | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala index 175f4ba779..60021928c6 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala @@ -620,15 +620,28 @@ abstract class GenIncOptimizer private[optimizer] (semantics: Semantics, case _ => false } def isElidableStat(tree: Tree): Boolean = tree match { - case Block(stats) => - stats.forall(isElidableStat) - case Assign(Select(This(), _), rhs) => - isTriviallySideEffectFree(rhs) + case Block(stats) => stats.forall(isElidableStat) + case Assign(Select(This(), _), rhs) => isTriviallySideEffectFree(rhs) + + // Mixin constructor, 2.10/2.11 case ApplyStatic(ClassType(cls), methodName, List(This())) => statics(cls).methods(methodName.name).originalDef.body.exists { case Skip() => true case _ => false } + + // Mixin constructor, 2.12 + case ApplyStatically(This(), ClassType(cls), methodName, Nil) + if !classes.contains(cls) => + // Since cls is not in classes, it must be a default method call. + defaults(cls).methods.get(methodName.name) exists { methodDef => + methodDef.originalDef.body exists { + case Skip() => true + case _ => false + } + } + + // Super class constructor. case ApplyStatically(This(), ClassType(cls), methodName, args) => Definitions.isConstructorName(methodName.name) && args.forall(isTriviallySideEffectFree) && @@ -636,10 +649,9 @@ abstract class GenIncOptimizer private[optimizer] (semantics: Semantics, superCls.encodedName == cls && superCls.lookupMethod(methodName.name).exists(isElidableModuleConstructor) } - case StoreModule(_, _) => - true - case _ => - isTriviallySideEffectFree(tree) + + case StoreModule(_, _) => true + case _ => isTriviallySideEffectFree(tree) } impl.originalDef.body.fold { throw new AssertionError("Module constructor cannot be abstract") From b031f0cf26d029ad88403c5b35e62d9e7122503c Mon Sep 17 00:00:00 2001 From: Carlos Quiroz Date: Tue, 8 Nov 2016 16:58:08 -0300 Subject: [PATCH 0043/2665] Definition of the java.util.NavigableMap interface --- .../main/scala/java/util/NavigableMap.scala | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 javalib/src/main/scala/java/util/NavigableMap.scala diff --git a/javalib/src/main/scala/java/util/NavigableMap.scala b/javalib/src/main/scala/java/util/NavigableMap.scala new file mode 100644 index 0000000000..e35bed106a --- /dev/null +++ b/javalib/src/main/scala/java/util/NavigableMap.scala @@ -0,0 +1,25 @@ +package java.util + +trait NavigableMap[K, V] extends SortedMap[K, V] { + def lowerEntry(key: K): Map.Entry[K, V] + def lowerKey(key: K): K + def floorEntry(key: K): Map.Entry[K, V] + def floorKey(key: K): K + def ceilingEntry(key: K): Map.Entry[K, V] + def ceilingKey(key: K): K + def higherEntry(key: K): Map.Entry[K, V] + def higherKey(key: K): K + def firstEntry(): Map.Entry[K, V] + def lastEntry(): Map.Entry[K, V] + def pollFirstEntry(): Map.Entry[K, V] + def pollLastEntry(): Map.Entry[K, V] + def descendingMap(): NavigableMap[K, V] + def navigableKeySet(): NavigableSet[K] + def descendingKeySet(): NavigableSet[K] + def subMap(fromKey: K, fromInclusive: Boolean, toKey: K, toInclusive: Boolean): NavigableMap[K, V] + def headMap(toKey: K, inclusive: Boolean): NavigableMap[K, V] + def tailMap(toKey: K, inclusive: Boolean): NavigableMap[K, V] + def subMap(fromKey: K, toKey: K): SortedMap[K, V] + def headMap(toKey: K): SortedMap[K, V] + def tailMap(fromKey: K): SortedMap[K, V] +} From 1e9be7153f1ba3d2b34e3f25a34ef8b12bcdd9d8 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Tue, 8 Nov 2016 19:38:40 +0100 Subject: [PATCH 0044/2665] Upgrade to Scala 2.12.0 --- ci/checksizes.sh | 14 ++++++------- ci/matrix.xml | 18 ++++++++-------- .../BlacklistedTests.txt | 3 +-- .../{2.12.0-RC1 => 2.12.0}/BuglistedTests.txt | 0 .../WhitelistedTests.txt | 19 ++++++++++++++++- .../neg/t6446-additional.check | 0 .../neg/t6446-list.check | 0 .../neg/t6446-missing.check | 0 .../neg/t6446-show-phases.check | 0 .../neg/t7494-no-options.check | 0 .../run/Course-2002-01.check | 0 .../run/Course-2002-02.check | 0 .../run/Course-2002-04.check | 0 .../run/Course-2002-08.check | 0 .../run/Course-2002-09.check | 0 .../run/Course-2002-10.check | 0 .../{2.12.0-RC1 => 2.12.0}/run/Meter.check | 0 .../run/MeterCaseClass.check | 0 .../{2.12.0-RC1 => 2.12.0}/run/bugs.sem | 0 .../run/caseClassHash.check | 0 .../{2.12.0-RC1 => 2.12.0}/run/deeps.check | 0 .../run/dynamic-anyval.check | 0 .../run/impconvtimes.check | 0 .../{2.12.0-RC1 => 2.12.0}/run/imports.check | 0 .../run/interpolation.check | 0 .../run/interpolationMultiline1.check | 0 .../{2.12.0-RC1 => 2.12.0}/run/issue192.sem | 0 .../run/macro-bundle-static.check | 0 .../run/macro-bundle-toplevel.check | 0 .../run/macro-bundle-whitebox-decl.check | 0 .../{2.12.0-RC1 => 2.12.0}/run/misc.check | 0 .../run/promotion.check | 0 .../{2.12.0-RC1 => 2.12.0}/run/runtime.check | 0 .../run/spec-self.check | 0 .../run/structural.check | 0 .../run/t0421-new.check | 0 .../run/t0421-old.check | 0 .../{2.12.0-RC1 => 2.12.0}/run/t1503.sem | 0 .../{2.12.0-RC1 => 2.12.0}/run/t3702.check | 0 .../{2.12.0-RC1 => 2.12.0}/run/t4148.sem | 0 .../{2.12.0-RC1 => 2.12.0}/run/t4617.check | 0 .../{2.12.0-RC1 => 2.12.0}/run/t5356.check | 0 .../{2.12.0-RC1 => 2.12.0}/run/t5552.check | 0 .../{2.12.0-RC1 => 2.12.0}/run/t5568.check | 0 .../{2.12.0-RC1 => 2.12.0}/run/t5629b.check | 0 .../{2.12.0-RC1 => 2.12.0}/run/t5680.check | 0 .../{2.12.0-RC1 => 2.12.0}/run/t5866.check | 0 .../run/t6318_primitives.check | 0 .../{2.12.0-RC1 => 2.12.0}/run/t6662.check | 0 .../{2.12.0-RC1 => 2.12.0}/run/t7657.check | 0 .../{2.12.0-RC1 => 2.12.0}/run/t7763.sem | 0 .../{2.12.0-RC1 => 2.12.0}/run/t8570a.check | 0 .../{2.12.0-RC1 => 2.12.0}/run/t8764.check | 0 .../{2.12.0-RC1 => 2.12.0}/run/t9387b.check | 0 .../{2.12.0-RC1 => 2.12.0}/run/t9656.check | 0 .../run/try-catch-unify.check | 0 .../run/virtpatmat_switch.check | 0 .../run/virtpatmat_typetag.check | 0 project/Build.scala | 21 ++++++------------- .../BlacklistedTests.txt | 0 .../WhitelistedTests.txt | 0 scripts/build-all-js.sh | 2 +- scripts/publish.sh | 4 ++-- 63 files changed, 44 insertions(+), 37 deletions(-) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/BlacklistedTests.txt (99%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/BuglistedTests.txt (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/WhitelistedTests.txt (99%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/neg/t6446-additional.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/neg/t6446-list.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/neg/t6446-missing.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/neg/t6446-show-phases.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/neg/t7494-no-options.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/Course-2002-01.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/Course-2002-02.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/Course-2002-04.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/Course-2002-08.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/Course-2002-09.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/Course-2002-10.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/Meter.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/MeterCaseClass.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/bugs.sem (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/caseClassHash.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/deeps.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/dynamic-anyval.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/impconvtimes.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/imports.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/interpolation.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/interpolationMultiline1.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/issue192.sem (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/macro-bundle-static.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/macro-bundle-toplevel.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/macro-bundle-whitebox-decl.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/misc.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/promotion.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/runtime.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/spec-self.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/structural.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/t0421-new.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/t0421-old.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/t1503.sem (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/t3702.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/t4148.sem (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/t4617.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/t5356.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/t5552.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/t5568.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/t5629b.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/t5680.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/t5866.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/t6318_primitives.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/t6662.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/t7657.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/t7763.sem (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/t8570a.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/t8764.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/t9387b.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/t9656.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/try-catch-unify.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/virtpatmat_switch.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.12.0-RC1 => 2.12.0}/run/virtpatmat_typetag.check (100%) rename scala-test-suite/src/test/resources/{2.12.0-RC1 => 2.12.0}/BlacklistedTests.txt (100%) rename scala-test-suite/src/test/resources/{2.12.0-RC1 => 2.12.0}/WhitelistedTests.txt (100%) diff --git a/ci/checksizes.sh b/ci/checksizes.sh index 02d9d905da..fdf000bcab 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -11,8 +11,8 @@ case $FULLVER in 2.11.8) VER=2.11 ;; - 2.12.0-RC1) - VER=2.12.0-RC1 + 2.12.0) + VER=2.12 ;; 2.10.3|2.10.4|2.10.5|2.10.6|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7) echo "Ignoring checksizes for Scala $FULLVER" @@ -45,11 +45,11 @@ case $FULLVER in REVERSI_PREOPT_GZ_EXPECTEDSIZE=71000 REVERSI_OPT_GZ_EXPECTEDSIZE=32000 ;; - 2.12.0-RC1) - REVERSI_PREOPT_EXPECTEDSIZE=595000 - REVERSI_OPT_EXPECTEDSIZE=150000 - REVERSI_PREOPT_GZ_EXPECTEDSIZE=78000 - REVERSI_OPT_GZ_EXPECTEDSIZE=36000 + 2.12.0) + REVERSI_PREOPT_EXPECTEDSIZE=555000 + REVERSI_OPT_EXPECTEDSIZE=140000 + REVERSI_PREOPT_GZ_EXPECTEDSIZE=75500 + REVERSI_OPT_GZ_EXPECTEDSIZE=35500 ;; esac diff --git a/ci/matrix.xml b/ci/matrix.xml index ce19bf8658..9bc71aecda 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -307,7 +307,7 @@ 1.8 - 2.12.0-RC1 + 2.12.0 1.8 @@ -323,7 +323,7 @@ testSuite - 2.12.0-RC1 + 2.12.0 1.8 testSuite @@ -335,7 +335,7 @@ scalaTestSuite - 2.12.0-RC1 + 2.12.0 1.8 scalaTestSuite @@ -352,7 +352,7 @@ testSuite - 2.12.0-RC1 + 2.12.0 1.8 testSuite @@ -364,7 +364,7 @@ scalaTestSuite - 2.12.0-RC1 + 2.12.0 1.8 scalaTestSuite @@ -379,7 +379,7 @@ 1.8 - 2.12.0-RC1 + 2.12.0 1.8 @@ -418,7 +418,7 @@ 1.7 - 2.12.0-RC1 + 2.12.0 1.8 @@ -528,11 +528,11 @@ 1.7 - 2.12.0-RC1 + 2.12.0 1.8 - 2.12.0-RC1 + 2.12.0 1.8 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt similarity index 99% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/BlacklistedTests.txt rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt index fb68312e63..ce1cf65299 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt @@ -49,8 +49,6 @@ run/t3895b.scala run/t5974.scala run/hashset.scala run/t5262.scala -run/t5293.scala -run/t5293-map.scala run/serialize-stream.scala run/sysprops.scala run/lambda-serialization-gc.scala @@ -605,6 +603,7 @@ run/t9437b run/t8756.scala run/inferred-type-constructors-hou.scala run/trait-static-forwarder +run/SD-235.scala # Uses refletction indirectly through # scala.runtime.ScalaRunTime.replStringOf diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BuglistedTests.txt similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/BuglistedTests.txt rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BuglistedTests.txt diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt similarity index 99% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/WhitelistedTests.txt rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt index ecde31dc84..405a6334c4 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt @@ -3150,7 +3150,6 @@ pos/t2712-4.scala pos/t2712-1.scala pos/t2712-3.scala pos/t2712-6.scala -pos/t5148.scala pos/t6895b.scala pos/t5683.scala pos/hkgadt.scala @@ -3256,6 +3255,24 @@ run/caseClassHash.scala run/interpolation.scala run/interpolationMultiline1.scala run/t9656.scala +pos/sd219.scala +pos/t9918 +pos/shapeless-regression.scala +pos/issue244.scala +pos/t9920.scala +pos/t9943.scala +neg/t5148.scala +run/sd242.scala +run/local_obj.scala +run/t9697.scala +run/t9920.scala +run/t9920c.scala +run/t9920d.scala +run/t9920b.scala +run/t9946a.scala +run/t9946c.scala +run/t9946b.scala +run/trait-super-calls.scala # Adapt checkfiles for ().toString == "undefined" run/t5680.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/neg/t6446-additional.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/neg/t6446-additional.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/neg/t6446-additional.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/neg/t6446-list.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/neg/t6446-list.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/neg/t6446-list.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/neg/t6446-list.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/neg/t6446-missing.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/neg/t6446-missing.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/neg/t6446-missing.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/neg/t6446-show-phases.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/neg/t6446-show-phases.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/neg/t6446-show-phases.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/neg/t7494-no-options.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/neg/t7494-no-options.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/neg/t7494-no-options.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Course-2002-01.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/Course-2002-01.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Course-2002-01.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/Course-2002-01.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Course-2002-02.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/Course-2002-02.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Course-2002-02.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/Course-2002-02.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Course-2002-04.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/Course-2002-04.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Course-2002-04.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/Course-2002-04.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Course-2002-08.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/Course-2002-08.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Course-2002-08.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/Course-2002-08.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Course-2002-09.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/Course-2002-09.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Course-2002-09.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/Course-2002-09.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Course-2002-10.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/Course-2002-10.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Course-2002-10.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/Course-2002-10.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Meter.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/Meter.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/Meter.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/Meter.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/MeterCaseClass.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/MeterCaseClass.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/MeterCaseClass.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/MeterCaseClass.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/bugs.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/bugs.sem similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/bugs.sem rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/bugs.sem diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/caseClassHash.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/caseClassHash.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/caseClassHash.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/caseClassHash.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/deeps.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/deeps.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/deeps.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/deeps.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/dynamic-anyval.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/dynamic-anyval.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/dynamic-anyval.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/dynamic-anyval.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/impconvtimes.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/impconvtimes.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/impconvtimes.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/impconvtimes.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/imports.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/imports.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/imports.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/imports.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/interpolation.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/interpolation.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/interpolation.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/interpolation.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/interpolationMultiline1.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/interpolationMultiline1.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/interpolationMultiline1.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/interpolationMultiline1.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/issue192.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/issue192.sem similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/issue192.sem rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/issue192.sem diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/macro-bundle-static.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/macro-bundle-static.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/macro-bundle-static.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/macro-bundle-static.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/macro-bundle-toplevel.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/macro-bundle-toplevel.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/macro-bundle-toplevel.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/macro-bundle-toplevel.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/macro-bundle-whitebox-decl.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/macro-bundle-whitebox-decl.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/macro-bundle-whitebox-decl.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/macro-bundle-whitebox-decl.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/misc.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/misc.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/misc.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/misc.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/promotion.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/promotion.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/promotion.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/promotion.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/runtime.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/runtime.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/runtime.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/runtime.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/spec-self.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/spec-self.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/spec-self.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/spec-self.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/structural.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/structural.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/structural.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/structural.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t0421-new.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t0421-new.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t0421-new.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t0421-new.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t0421-old.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t0421-old.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t0421-old.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t0421-old.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t1503.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t1503.sem similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t1503.sem rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t1503.sem diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t3702.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t3702.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t3702.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t3702.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t4148.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t4148.sem similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t4148.sem rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t4148.sem diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t4617.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t4617.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t4617.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t4617.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5356.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t5356.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5356.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t5356.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5552.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t5552.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5552.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t5552.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5568.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t5568.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5568.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t5568.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5629b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t5629b.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5629b.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t5629b.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5680.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t5680.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5680.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t5680.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5866.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t5866.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t5866.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t5866.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t6318_primitives.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t6318_primitives.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t6318_primitives.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t6318_primitives.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t6662.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t6662.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t6662.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t6662.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t7657.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t7657.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t7657.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t7657.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t7763.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t7763.sem similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t7763.sem rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t7763.sem diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t8570a.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t8570a.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t8570a.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t8570a.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t8764.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t8764.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t8764.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t8764.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t9387b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t9387b.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t9387b.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t9387b.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t9656.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t9656.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/t9656.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/t9656.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/try-catch-unify.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/try-catch-unify.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/try-catch-unify.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/try-catch-unify.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/virtpatmat_switch.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/virtpatmat_switch.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/virtpatmat_switch.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/virtpatmat_switch.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/virtpatmat_typetag.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/virtpatmat_typetag.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0-RC1/run/virtpatmat_typetag.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/run/virtpatmat_typetag.check diff --git a/project/Build.scala b/project/Build.scala index beeaa37fa3..ea8e11bef9 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -64,7 +64,7 @@ object Build { CrossVersion.binaryMapped(v => s"sjs${previousSJSBinaryVersion}_$v") val scalaVersionsUsedForPublishing: Set[String] = - Set("2.10.6", "2.11.8", "2.12.0-RC1") + Set("2.10.6", "2.11.8", "2.12.0") val newScalaBinaryVersionsInThisRelease: Set[String] = Set() @@ -428,7 +428,7 @@ object Build { "2.11.6", "2.11.7", "2.11.8", - "2.12.0-RC1" + "2.12.0" ), // JDK version we are running with javaVersion in Global := { @@ -1419,24 +1419,15 @@ object Build { val sourceFiles = (sources in Test).value val v = scalaVersion.value - val hasBug2625 = v == "2.12.0-RC1" + val hasBug2382 = v.startsWith("2.10.") || v.startsWith("2.11.") val sourceFiles1 = { - if (hasBug2625) - sourceFiles.filterNot(_.getName == "PatMatOuterPointerCheckTest.scala") - else - sourceFiles - } - - val hasBug2382 = - v.startsWith("2.10.") || v.startsWith("2.11.") || v == "2.12.0-RC1" - val sourceFiles2 = { if (hasBug2382) - sourceFiles1.filterNot(_.getName == "OuterClassTest.scala") + sourceFiles.filterNot(_.getName == "OuterClassTest.scala") else - sourceFiles1 + sourceFiles } - sourceFiles2 + sourceFiles1 } ) ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( diff --git a/scala-test-suite/src/test/resources/2.12.0-RC1/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.12.0/BlacklistedTests.txt similarity index 100% rename from scala-test-suite/src/test/resources/2.12.0-RC1/BlacklistedTests.txt rename to scala-test-suite/src/test/resources/2.12.0/BlacklistedTests.txt diff --git a/scala-test-suite/src/test/resources/2.12.0-RC1/WhitelistedTests.txt b/scala-test-suite/src/test/resources/2.12.0/WhitelistedTests.txt similarity index 100% rename from scala-test-suite/src/test/resources/2.12.0-RC1/WhitelistedTests.txt rename to scala-test-suite/src/test/resources/2.12.0/WhitelistedTests.txt diff --git a/scripts/build-all-js.sh b/scripts/build-all-js.sh index 23a85b2946..d34a0376fb 100755 --- a/scripts/build-all-js.sh +++ b/scripts/build-all-js.sh @@ -3,7 +3,7 @@ tasks="fastOptJS fullOptJS" projects="helloworld/ reversi/ testingExample/test: testSuite/test:" -for v in 2.11.8 2.10.6 2.12.0-RC1; do +for v in 2.11.8 2.10.6 2.12.0; do echo "++$v" echo "package" diff --git a/scripts/publish.sh b/scripts/publish.sh index c7820d6323..7e21707364 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -8,8 +8,8 @@ else CMD="echo sbt" fi -FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.12.0-RC1" -BIN_VERSIONS="2.10.6 2.11.8 2.12.0-RC1" +FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.12.0" +BIN_VERSIONS="2.10.6 2.11.8 2.12.0" CLI_VERSIONS="2.10.6 2.11.8" SBT_VERSION="2.10.6" From 7df2c63186e20cc74323f10a1c96f5e4dc91530c Mon Sep 17 00:00:00 2001 From: "justin.maat" Date: Thu, 10 Nov 2016 17:27:48 -0500 Subject: [PATCH 0045/2665] Fix #2640: Increase VMTermTimeout to 1 minute --- .../src/main/scala/org/scalajs/sbttestadapter/package.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/package.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/package.scala index f769f22346..bc32e810e5 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/package.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/package.scala @@ -12,5 +12,5 @@ package org.scalajs import scala.concurrent.duration._ package object testadapter { - private[testadapter] final val VMTermTimeout = 5.seconds + private[testadapter] final val VMTermTimeout = 1.minute } From 5f1d139081d972c522ac3ae4741657c9ed37cce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 17 Nov 2016 12:05:00 +0100 Subject: [PATCH 0046/2665] 25% faster Long.toString() for large Longs (>= 2^53). For large `Long` values, `toString()` divides once by 10^9, then converts the quotient and remainder to strings and concatenates the results. Previously, the quotient and remainder were returned in a tuple from `unsignedDivModHelper()`. Now, we let the latter perform the final step of conversion to string, which avoids the tuple allocation. According to micro-benchmarks, this optimization shaved off 25% of the run-time of `Long.toString()` for large `Long` values. --- .../scala/scalajs/runtime/RuntimeLong.scala | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala b/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala index 2c6eacd1f8..97cfb0f82e 100644 --- a/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala +++ b/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala @@ -427,7 +427,7 @@ object RuntimeLong { private final val AskQuotient = 0 private final val AskRemainder = 1 - private final val AskBoth = 2 + private final val AskToString = 2 /** The hi part of a (lo, hi) return value. */ private[this] var hiReturn: Int = _ @@ -472,20 +472,14 @@ object RuntimeLong { * The quotient must be <= ULong.MaxValue / 10^9, which is < 2^53, and * is therefore a valid double. It must also be non-zero, since * (lo, hi) >= 2^53 > 10^9. + * + * To avoid allocating a tuple with the quotient and remainder, we push + * the final conversion to string inside unsignedDivModHelper. According + * to micro-benchmarks, this optimization makes toString 25% faster in + * this branch. */ - val TenPow9Lo = 1000000000L.toInt - val TenPow9Hi = (1000000000L >>> 32).toInt - - val quotRem = unsignedDivModHelper(lo, hi, TenPow9Lo, TenPow9Hi, - AskBoth).asInstanceOf[js.Tuple4[Int, Int, Int, Int]] - val quotLo = quotRem._1 - val quotHi = quotRem._2 - val rem = quotRem._3 // remHi must be 0 by construction - - val quot = asUnsignedSafeDouble(quotLo, quotHi) - - val remStr = rem.toString - quot.toString + "000000000".jsSubstring(remStr.length) + remStr + unsignedDivModHelper(lo, hi, 1000000000, 0, + AskToString).asInstanceOf[String] } } @@ -783,8 +777,17 @@ object RuntimeLong { } } + /** Helper for `unsigned_/`, `unsigned_%` and `toUnsignedString()`. + * + * The value of `ask` may be one of: + * + * - `AskQuotient`: returns the quotient (with the hi part in `hiReturn`) + * - `AskRemainder`: returns the remainder (with the hi part in `hiReturn`) + * - `AskToString`: returns the conversion of `(alo, ahi)` to string. + * In this case, `blo` must be 10^9 and `bhi` must be 0. + */ private def unsignedDivModHelper(alo: Int, ahi: Int, blo: Int, bhi: Int, - ask: Int): Int | js.Tuple4[Int, Int, Int, Int] = { + ask: Int): Int | String = { var shift = inlineNumberOfLeadingZeros(blo, bhi) - inlineNumberOfLeadingZeros(alo, ahi) @@ -852,7 +855,10 @@ object RuntimeLong { hiReturn = remHi remLo } else { - js.Tuple4(quotLo, quotHi, remLo, remHi) + // AskToString (recall that b = 10^9 in this case) + val quot = asUnsignedSafeDouble(quotLo, quotHi) // != 0 + val remStr = remLo.toString // remHi is always 0 + quot.toString + "000000000".jsSubstring(remStr.length) + remStr } } From 3c498467660a6762598c950cd3a639b219a63e13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 12 Nov 2016 11:06:03 +0100 Subject: [PATCH 0047/2665] Add an arithmetic simplification in optimizer for >>>. (c1 & x) >>> c2 --> (c1 >>> c2) & (x >>> c2) And the same with `|` and `^`. Note that `c1 >>> c2` is still constant, so we are not actually creating more operations. Moreover, the value of `c1 >>> c2` is textually shorter-or-equal than `c1`, so at worst we keep the same character length, and sometimes slightly improve it. The benefit, though, happens if `c1 >>> c2` evaluates to the absorbing element of the bitwise operation, everything disappears. This happens notably for expressions like (0xffff & x) >>> 16 which will be produced by the improved `Long` multiplication of the following commit, in some cases. --- .../tools/linker/frontend/optimizer/OptimizerCore.scala | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index ab5ad27acb..7ab8f78cdc 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -2923,6 +2923,14 @@ private[optimizer] abstract class OptimizerCore( else PreTransBinaryOp(Int_>>>, x, PreTransLit(IntLiteral(dist))) + case (PreTransBinaryOp(op @ (Int_| | Int_& | Int_^), + PreTransLit(IntLiteral(x)), y), + z @ PreTransLit(IntLiteral(zValue))) => + foldBinaryOp( + op, + PreTransLit(IntLiteral(x >>> zValue)), + foldBinaryOp(Int_>>>, y, z)) + case (_, PreTransLit(IntLiteral(y))) => val dist = y & 31 if (dist == 0) From d08eed4a01c56a832c3021716875499c79cc56cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 12 Nov 2016 11:14:44 +0100 Subject: [PATCH 0048/2665] Shorter and faster `Long` multiplication. The key insight was that we do not need to compute the `hi` products by 16-bit components. The `hi` part is basically a.lo*b.hi + a.hi*b.hi + carry_from_lo_* so only the carry from multiplying `a.lo*b.lo` needs to be computed by 16-bit components. The resulting algorithm is significantly shorter, and we can afford to completely inline it. Subsequently, we can use the 16-bit products computed for the hi part to also compute the lo part, removing one multiplication. The fact that we can now inline the whole algorithm allows it to benefit from call-site optimizations on the underlying `Int` arithmetics. This mostly happens when one side is constant and/or the `hi` part of operands is 0. The whole thing collapses particularly well when `a` is a constant in the range `0 <= a <= 0xffff`, which happens for mundane things like `10 * x`. This improved implementation is significantly faster. A benchmark based on `BigInteger.multiply` exhibits > 2x improvement. --- .../scala/scalajs/runtime/RuntimeLong.scala | 246 ++++++++++++++++-- 1 file changed, 221 insertions(+), 25 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala b/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala index 97cfb0f82e..af4304147b 100644 --- a/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala +++ b/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala @@ -302,9 +302,229 @@ final class RuntimeLong(val lo: Int, val hi: Int) @inline def *(b: RuntimeLong): RuntimeLong = { + /* The following algorithm is based on the decomposition in 32-bit and then + * 16-bit subproducts of the unsigned interpretation of operands. + * + * Since everything is interpreted as unsigned, all values are Natural + * numbers and are >= 0, by construction. + * + * We are looking to compute + * a *[64] b = (a * b) % 2^64 + * + * We use the notation * and + for mathematical, non-overflowing + * operations, and *[64] and +[64] for overflowing operations. Eventually, + * we need to implement everything in terms of *[32] and +[32]. The symbol + * ^ is used for exponentiation (not bitwise xor). + * + * The decomposition in 32-bit components yields: + * + * a *[64] b + * = ( (2^32*ahi + alo) * (2^32*bhi + blo) ) % 2^64 + * = ( 2^64*ahi*bhi + 2^32*(ahi*blo + bhi*alo) + alo*blo ) % 2^64 + * + * With Natural numbers, congruence theory tells us that we can "distribute" + * `% n` on + and *, as long as we also keep the outer `% n`. To be more + * precise: + * (a + b) % n = (a%n + b) % n = (a + b%n) % n = (a%n + b%n) % n + * (a * b) % n = (a%n * b) % n = (a * b%n) % n = (a%n * b%n) % n + * + * From the latter, we derive a corollary that we'll implicitly use several + * times later: + * (n * x) % n = 0 for any n > 0 and any x + * + * We can use these equivalences to get rid of parts of our computation: + * + * ( 2^64*ahi*bhi + 2^32*(ahi*blo + bhi*alo) + alo*blo ) % 2^64 + * = ( (2^64*ahi*bhi % 2^64) + 2^32*(ahi*blo + bhi*alo) + alo*blo ) % 2^64 + * ------------------- + * = 0 + * = ( 2^32*(ahi*blo + bhi*alo) + alo*blo ) % 2^64 + * + * Observe that we can rewrite any quantity x as + * x = n*(x/n) + x%n + * where n is > 0 and / denotes the floor division. + * + * We can rewrite the product ahi*blo as + * + * ahi*blo + * = 2^32*(ahi*blo / 2^32) + (ahi*blo % 2^32) + * = 2^32*(ahi*blo / 2^32) + (ahi *[32] blo) + * + * Similarly, + * + * bhi*alo = 2^32*(alo*bhi / 2^32) + (alo *[32] bhi) + * + * Taking back our complete computation: + * + * a *[64] b + * = ( 2^32*(ahi*blo + bhi*alo) + alo*blo ) % 2^64 + * = ( 2^64*(ahi*blo / 2^32) + 2^32*(ahi *[32] blo) + * + 2^64*(alo*bhi / 2^32) + 2^32*(alo *[32] bhi) + * + alo*blo ) % 2^64 + * + * where distributing % 2^64 allows to get rid of the most awful parts: + * + * = ( 2^32*(ahi *[32] blo) + 2^32*(alo *[32] bhi) + alo*blo) % 2^64 + * + * Now we focus on the `alo*blo` part. We decompose it in 16-bit components. + * + * alo * blo + * = 2^32*a1*b1 + 2^16*a1*b0 + 2^16*a0*b1 + a0*b0 + * + * Because a1, a0, b1 and b0 are all <= 2^16-1, their pair-wise products + * are all <= (2^16-1)^2 = 2^32 - 2*2^16 + 1 = 0xfffe0001 < 2^32. This + * means that, for example, + * a1*b0 = (a1*b0) % 2^32 = a1 *[32] b0 + * with the same applying to other subproducts. + * + * Let + * a1b1 = a1 *[32] b1 + * a1b0 = a1 *[32] b0 + * a0b1 = a0 *[32] b1 + * a0b0 = a0 *[32] b0 + * + * Each of those is <= 0xfffe0001. + * + * We now have: + * + * alo * blo + * = 2^32*a1b1 + 2^16*a1b0 + 2^16*a0b1 + a0b0 + * + * We can decompose it using / and % as follows: + * alo * blo + * = 2^32*((alo * blo) / 2^32) + ((alo * blo) % 2^32) + * + * Let + * aloblo = (alo * blo) % 2^32 + * carry_from_lo_* = (alo * blo) / 2^32 + * + * Then + * alo * blo = 2^32 * carry_from_lo_* + aloblo + * + * aloblo = (alo * blo) % 2^32 + * = (2^32*a1b1 + 2^16*a1b0 + 2^16*a0b1 + a0b0) % 2^32 + * = (2^16*a1b0 + 2^16*a0b1 + a0b0) % 2^32 + * = (((2^16*a1b0 % 2^32 + 2^16*a0b1 % 2^32) % 2^32) + a0b0 % 2^32) % 2^32 + * = (2^16*a1b0 % 2^32) +[32] (2^16*a0b1 % 2^32) +[32] (a0b0 % 2^32) + * = (a1b0 <<[32] 16) +[32] (a0b1 <<[32] 16) +[32] a0b0 + * + * carry_from_lo_* is more difficult. + * + * carry_from_lo_* = (alo * blo) / 2^32 + * = (2^32*a1b1 + 2^16*a1b0 + 2^16*a0b1 + a0b0) / 2^32 + * = a1b1 + (2^16*a1b0 + 2^16*a0b1 + a0b0) / 2^32 + * = a1b1 + (2^16*a1b0 + 2^16*a0b1 + (2^16*(a0b0 / 2^16) + (a0b0 % 2^16))) / 2^32 + * = a1b1 + (2^16*(a1b0 + a0b1 + (a0b0 / 2^16)) + (a0 % 2^16)) / 2^32 + * ---------------------------------- + * multiple of 2^16 + * = a1b1 + ( (2^16*(a1b0 + a0b1 + (a0b0 / 2^16))) / 2^16 + (a0 % 2^16) / 2^16 ) / 2^16 + * --------- + * < 2^16 + * = a1b1 + (a1b0 + a0b1 + (a0b0 / 2^16)) / 2^16 + * = a1b1 + (a1b0 + (a0b1 + (a0b0 >>>[32] 16))) / 2^16 + * ---- --------------- + * <= 0xfffe0001 <= 0xffff + * ------------------------ + * <= 0xffff0000, hence the + does not overflow + * = a1b1 + (a1b0 + (a0b1 +[32] (a0b0 >>>[32] 16))) / 2^16 + * + * Let + * c1part = a0b1 +[32] (a0b0 >>>[32] 16) + * + * carry_from_lo_* + * = a1b1 + (a1b0 + c1part) / 2^16 + * = a1b1 + (a1b0 + (2^16*(c1part / 2^16) + (c1part % 2^16))) / 2^16 + * = a1b1 + (2^16*(c1part / 2^16) + (a1b0 + (c1part % 2^16))) / 2^16 + * = a1b1 + (2^16*(c1part / 2^16) + (a1b0 + (c1part &[32] 0xffff))) / 2^16 + * ---- ------------------- + * <= 0xfffe0001 <= 0xffff + * ---------------------------- + * <= 0xffff0000, hence the + does not overflow + * = a1b1 + (2^16*(c1part / 2^16) + (a1b0 +[32] (c1part &[32] 0xffff))) / 2^16 + * -------------------- + * multiple of 2^16 + * = a1b1 + ( 2^16*(c1part / 2^16) / 2^16 + (a1b0 +[32] (c1part &[32] 0xffff)) / 2^16 ) + * = a1b1 + (c1part / 2^16) + (a1b0 +[32] (c1part &[32] 0xffff)) / 2^16 + * ------ -------------------------------- + * < 2^32 < 2^32 + * = a1b1 + (c1part >>>[32] 16) + ((a1b0 +[32] (c1part &[32] 0xffff)) >>>[32] 16) + * + * Recap so far: + * + * a *[64] b + * = ( 2^32*(ahi *[32] blo) + 2^32*(alo *[32] bhi) + alo*blo ) % 2^64 + * alo*blo + * = 2^32*carry_from_lo_* + aloblo + * aloblo + * = (a1b0 <<[32] 16) +[32] (a0b1 <<[32] 16) +[32] a0b0 + * carry_from_lo_* + * = a1b1 + (c1part >>>[32] 16) + ((a1b0 +[32] (c1part &[32] 0xffff)) >>>[32] 16) + * + * Substituting, + * + * a *[64] b + * = ( 2^32*(ahi *[32] blo) + 2^32*(alo *[32] bhi) + 2^32*carry_from_lo_* + aloblo ) % 2^64 + * = ( 2^32*((ahi *[32] blo) + (alo *[32] bhi) + carry_from_lo_*) + aloblo ) % 2^64 + * = ( 2^32*((ahi *[32] blo) + (alo *[32] bhi) + carry_from_lo_*) % 2^64 + aloblo ) % 2^64 + * Using (n * x) % (n * m) = (n * (x % m)) with n = m = 2^32 (see proof below) + * = ( 2^32*(((ahi *[32] blo) + (alo *[32] bhi) + carry_from_lo_*) % 2^32) + aloblo ) % 2^64 + * = ( 2^32*((ahi *[32] blo) +[32] (alo *[32] bhi) +[32] (carry_from_lo_* % 2^32)) + aloblo ) % 2^64 + * + * Lemma: (n * x) % (n * m) = n * (x % m) + * (n * x) % (n * m) + * = (n * x) - ((n * x) / (n * m))*(n * m) using a % b = a - (a / b)*b + * = (n * x) - (x / m)*(n * m) + * = n * (x - (x / m)*m) + * = n * (x % m) using again a % b = a - (a / b)*b + * + * Since aloblo < 2^32 and the inner sum is also < 2^32: + * + * lo = aloblo + * = (a1b0 <<[32] 16) +[32] (a0b1 <<[32] 16) +[32] a0b0 + * = ((a1b0 +[32] a0a1) <<[32] 16) +[32] a0b0 + * + * hi = (ahi *[32] blo) +[32] (alo *[32] bhi) +[32] (carry_from_lo_* % 2^32) + * = (ahi *[32] blo) +[32] (alo *[32] bhi) +[32] + * (a1b1 + (c1part >>>[32] 16) + ((a1b0 +[32] (c1part &[32] 0xffff)) >>>[32] 16)) % 2^32 + * = (ahi *[32] blo) +[32] (alo *[32] bhi) +[32] + * a1b1 +[32] (c1part >>>[32] 16) +[32] ((a1b0 +[32] (c1part &[32] 0xffff)) >>>[32] 16) + */ + val alo = a.lo val blo = b.lo - new RuntimeLong(alo * blo, RuntimeLong.timesHi(alo, a.hi, blo, b.hi)) + + /* Note that the optimizer normalizes constants in * to be on the + * left-hand-side (when it cannot do constant-folding to begin with). + * Therefore, `b` is never constant in practice. + */ + + val a0 = alo & 0xffff + val a1 = alo >>> 16 + val b0 = blo & 0xffff + val b1 = blo >>> 16 + + val a0b0 = a0 * b0 + val a1b0 = a1 * b0 // collapses to 0 when a is constant and 0 <= a <= 0xffff + val a0b1 = a0 * b1 // (*) + + /* (*) Since b is never constant in practice, the only case where a0b1 + * would be constant 0 is if b's lo part is constant but not its hi part. + * That's not a likely scenario, though (not seen at all in our test suite). + */ + + /* lo = a.lo * b.lo, but we compute the above 3 subproducts for hi + * anyway, we reuse them to compute lo too, trading a * for 2 +'s and 1 <<. + */ + val lo = a0b0 + ((a1b0 + a0b1) << 16) + + // hi = a.lo*b.hi + a.hi*b.lo + carry_from_lo_* + val c1part = (a0b0 >>> 16) + a0b1 + val hi = { + alo*b.hi + a.hi*blo + a1 * b1 + (c1part >>> 16) + + (((c1part & 0xffff) + a1b0) >>> 16) // collapses to 0 when a1b0 = 0 + } + + new RuntimeLong(lo, hi) } @inline @@ -566,30 +786,6 @@ object RuntimeLong { } } - private def timesHi(alo: Int, ahi: Int, blo: Int, bhi: Int): Int = { - val a0 = alo & 0xffff - val a1 = alo >>> 16 - val a2 = ahi & 0xffff - val a3 = ahi >>> 16 - val b0 = blo & 0xffff - val b1 = blo >>> 16 - val b2 = bhi & 0xffff - val b3 = bhi >>> 16 - - val c1part = ((a0 * b0) >>> 16) + (a1 * b0) - var c2 = (c1part >>> 16) + (((c1part & 0xffff) + (a0 * b1)) >>> 16) - var c3 = c2 >>> 16 - c2 = (c2 & 0xffff) + a2 * b0 - c3 = c3 + (c2 >>> 16) - c2 = (c2 & 0xffff) + a1 * b1 - c3 = c3 + (c2 >>> 16) - c2 = (c2 & 0xffff) + a0 * b2 - c3 = c3 + (c2 >>> 16) - c3 = c3 + a3 * b0 + a2 * b1 + a1 * b2 + a0 * b3 - - (c2 & 0xffff) | (c3 << 16) - } - @inline def divide(a: RuntimeLong, b: RuntimeLong): RuntimeLong = { val lo = divideImpl(a.lo, a.hi, b.lo, b.hi) From 564f4bab97a2f0f0061cc545d08480c69c65a3a5 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Mon, 21 Nov 2016 15:39:51 -0800 Subject: [PATCH 0049/2665] Fix #1480: Mark js.Dictionary.empty @inline --- library/src/main/scala/scala/scalajs/js/Dictionary.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/src/main/scala/scala/scalajs/js/Dictionary.scala b/library/src/main/scala/scala/scalajs/js/Dictionary.scala index cf8997ab31..128c4c3dee 100644 --- a/library/src/main/scala/scala/scalajs/js/Dictionary.scala +++ b/library/src/main/scala/scala/scalajs/js/Dictionary.scala @@ -75,7 +75,8 @@ sealed trait Dictionary[A] extends Any { /** Factory for [[Dictionary]] instances. */ object Dictionary { /** Returns a new empty dictionary */ - def empty[A]: Dictionary[A] = (new Object).asInstanceOf[Dictionary[A]] + @inline def empty[A]: Dictionary[A] = + (new Object).asInstanceOf[Dictionary[A]] def apply[A](properties: (String, A)*): Dictionary[A] = { val result = empty[A] From 0f19c6c2e36da6b47085ebd8a7f230f95b8366d2 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Tue, 22 Nov 2016 13:55:56 -0800 Subject: [PATCH 0050/2665] Fix #1655: Allow export of classes inside objects This is a trivial extension to allow exports of static classes / modules. The only non-trivial issues is name choice, which we effectively circumvent by forcing the user to choose a name. --- .../scalajs/core/compiler/PrepJSExports.scala | 18 ++++++++- .../core/compiler/test/JSExportTest.scala | 36 ++++++++++++++---- .../testsuite/jsinterop/ExportsTest.scala | 38 +++++++++++++++++++ 3 files changed, 83 insertions(+), 9 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala index a260520cf6..b220f09782 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala @@ -75,7 +75,7 @@ trait PrepJSExports { this: PrepJSInterop => err("You may not export an abstract class") else if (clsSym.isLocalToBlock) err("You may not export a local class") - else if (clsSym.isNestedClass) + else if (!clsSym.isStatic) err(s"You may not export a nested class. $createFactoryInOuterClassHint") else { jsInterop.registerForExport(baseSym, exports) @@ -131,7 +131,7 @@ trait PrepJSExports { this: PrepJSInterop => } else if (sym.isLocalToBlock) { err("You may not export a local " + (if (isMod) "object" else "class")) - } else if (!sym.owner.hasPackageFlag) { + } else if (!sym.isStatic) { err("You may not export a nested " + (if (isMod) "object" else s"class. $createFactoryInOuterClassHint")) } else if (sym.isAbstractClass) { @@ -274,6 +274,20 @@ trait PrepJSExports { this: PrepJSInterop => "This will be enforced in 1.0.") } + // Don't allow nested class / module exports without explicit name. + def isStaticNested = { + /* For Scala.js defined JS classes, sym is the class itself. For normal + * classes, sym is the constructor that is to be exported. + */ + val clsSym = if (sym.isClass) sym else sym.owner + clsSym.isNestedClass && clsSym.isStatic && !clsSym.isLocalToBlock + } + + if (!isMember && !hasExplicitName && isStaticNested) { + reporter.error(annot.pos, + "You must set an explicit name for exports of nested classes.") + } + if (isNamedExport && jsInterop.isJSProperty(sym)) { reporter.error(annot.pos, "You may not export a getter or a setter as a named export") diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index 19b9c7b811..1d33b868a4 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -471,7 +471,10 @@ class JSExportTest extends DirectTest with TestHelpers { """ class A { @JSExport - class Nested + class Nested { + @JSExport + def this(x: Int) = this() + } @JSExport @ScalaJSDefined class Nested2 extends js.Object @@ -481,25 +484,39 @@ class JSExportTest extends DirectTest with TestHelpers { |newSource1.scala:4: error: You may not export a nested class. Create an exported factory method in the outer class to work around this limitation. | @JSExport | ^ - |newSource1.scala:7: error: You may not export a nested class. Create an exported factory method in the outer class to work around this limitation. + |newSource1.scala:6: error: You may not export a nested class. Create an exported factory method in the outer class to work around this limitation. + | @JSExport + | ^ + |newSource1.scala:10: error: You may not export a nested class. Create an exported factory method in the outer class to work around this limitation. | @JSExport | ^ """ + } + + @Test + def noImplicitNameNestedExportClass: Unit = { + """ object A { @JSExport - class Nested + class Nested { + @JSExport + def this(x: Int) = this + } @JSExport @ScalaJSDefined class Nested2 extends js.Object } """ hasErrors """ - |newSource1.scala:4: error: You may not export a nested class. Create an exported factory method in the outer class to work around this limitation. + |newSource1.scala:4: error: You must set an explicit name for exports of nested classes. | @JSExport | ^ - |newSource1.scala:7: error: You may not export a nested class. Create an exported factory method in the outer class to work around this limitation. + |newSource1.scala:6: error: You must set an explicit name for exports of nested classes. + | @JSExport + | ^ + |newSource1.scala:10: error: You must set an explicit name for exports of nested classes. | @JSExport | ^ """ @@ -527,6 +544,11 @@ class JSExportTest extends DirectTest with TestHelpers { | ^ """ + } + + @Test + def noImplicitNameNestedExportObject: Unit = { + """ object A { @JSExport @@ -537,10 +559,10 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:4: error: You may not export a nested object + |newSource1.scala:4: error: You must set an explicit name for exports of nested classes. | @JSExport | ^ - |newSource1.scala:7: error: You may not export a nested object + |newSource1.scala:7: error: You must set an explicit name for exports of nested classes. | @JSExport | ^ """ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index c28fa579fe..573f681a1b 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -638,6 +638,16 @@ class ExportsTest { assertEquals("witness", obj.witness) } + @Test def exports_for_nested_objects(): Unit = { + val accessor = exportsNamespace.qualified.nested.ExportedObject + assertJSNotUndefined(accessor) + assertEquals("function", js.typeOf(accessor)) + val obj = accessor() + assertJSNotUndefined(obj) + assertEquals("object", js.typeOf(obj)) + assertSame(obj, ExportHolder.ExportedObject) + } + @Test def exports_for_objects_with_constant_folded_name(): Unit = { val accessor = exportsNamespace.ConstantFoldedObjectExport assertJSNotUndefined(accessor) @@ -700,6 +710,14 @@ class ExportsTest { assertEquals(5, obj.x) } + @Test def exports_for_nested_classes(): Unit = { + val constr = exportsNamespace.qualified.nested.ExportedClass + assertJSNotUndefined(constr) + assertEquals("function", js.typeOf(constr)) + val obj = js.Dynamic.newInstance(constr)() + assertTrue((obj: Any).isInstanceOf[ExportHolder.ExportedClass]) + } + @Test def exports_for_classes_with_qualified_name_SJSDefinedExportedClass(): Unit = { val constr = exportsNamespace.qualified.testclass.SJSDefinedExportedClass assertJSNotUndefined(constr) @@ -709,6 +727,14 @@ class ExportsTest { assertEquals(5, obj.x) } + @Test def exports_for_nested_sjs_defined_classes(): Unit = { + val constr = exportsNamespace.qualified.nested.SJSDefinedExportedClass + assertJSNotUndefined(constr) + assertEquals("function", js.typeOf(constr)) + val obj = js.Dynamic.newInstance(constr)() + assertTrue((obj: Any).isInstanceOf[ExportHolder.SJSDefinedExportedClass]) + } + @Test def exports_for_classes_with_constant_folded_name(): Unit = { val constr = exportsNamespace.ConstantFoldedClassExport assertJSNotUndefined(constr) @@ -1603,3 +1629,15 @@ object ExportObjSetterNamed_= { // scalastyle:ignore @JSExport val x = 1 } + +object ExportHolder { + @JSExport("qualified.nested.ExportedClass") + class ExportedClass + + @JSExport("qualified.nested.ExportedObject") + object ExportedObject + + @JSExport("qualified.nested.SJSDefinedExportedClass") + @ScalaJSDefined + class SJSDefinedExportedClass extends js.Object +} From 3cf9e5c0bfbf2c4b3336bda904ac7aebcea4a7e4 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 4 Nov 2016 18:52:12 +0100 Subject: [PATCH 0051/2665] Fix #1381: Add top-level exports The new annotation @JSExportTopLevel allows modules to export their methods to the top-level of the export scope, so they can be called directly. For example: object MyApp { @JSExportTopLevel("main") def main(): Unit = ??? } Assuming that the export namespace is the `window` object, `MyApp.main` can now be invoked as follows in JavaScript: window.main() As opposed to (if one assumes `MyApp` and `main` to be exported): window.MyApp().main() Overloading is supported from within the same module. Exporting to the same name (irrespective of the export type) from different modules will cause a link time error. Current restrictions of top-level exports: - Properties (or fields) cannot be exported. - The fully qualified name of the export needs to be given. --- .../org/scalajs/core/compiler/GenJSCode.scala | 4 +- .../scalajs/core/compiler/GenJSExports.scala | 81 ++++++--- .../scalajs/core/compiler/JSDefinitions.scala | 1 + .../core/compiler/JSGlobalAddons.scala | 8 +- .../scalajs/core/compiler/PrepJSExports.scala | 64 +++++-- .../core/compiler/test/JSExportTest.scala | 156 ++++++++++++++++++ .../org/scalajs/core/ir/Definitions.scala | 11 +- .../scala/org/scalajs/core/ir/Infos.scala | 29 +++- .../scala/org/scalajs/core/ir/Printers.scala | 4 + .../org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- .../org/scalajs/core/ir/Serializers.scala | 12 +- .../main/scala/org/scalajs/core/ir/Tags.scala | 1 + .../org/scalajs/core/ir/Transformers.scala | 3 + .../org/scalajs/core/ir/Traversers.scala | 3 + .../scala/org/scalajs/core/ir/Trees.scala | 5 + .../org/scalajs/core/ir/PrintersTest.scala | 11 ++ .../js/annotation/JSExportTopLevel.scala | 20 +++ project/BinaryIncompatibilities.scala | 3 + .../js/annotation/ExportAnnotations.scala | 2 + .../testsuite/jsinterop/ExportsTest.scala | 62 +++++++ .../core/tools/linker/LinkedClass.scala | 6 +- .../backend/emitter/ScalaJSClassEmitter.scala | 28 +++- .../core/tools/linker/checker/IRChecker.scala | 32 +++- .../tools/linker/frontend/BaseLinker.scala | 6 +- 24 files changed, 483 insertions(+), 71 deletions(-) create mode 100644 library/src/main/scala/scala/scalajs/js/annotation/JSExportTopLevel.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index b567e3d33b..226a0eebab 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -405,7 +405,9 @@ abstract class GenJSCode extends plugins.PluginComponent if (isStaticModule(sym)) genModuleAccessorExports(sym) else genConstructorExports(sym) - memberExports ++ exportedConstructorsOrAccessors + val topLevelExports = genTopLevelExports(sym) + + memberExports ++ exportedConstructorsOrAccessors ++ topLevelExports } // Hashed definitions of the class diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index 697a4ab116..64e5ae22d2 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -120,6 +120,29 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } } + def genTopLevelExports(classSym: Symbol): List[js.TopLevelExportDef] = { + val allTopLevelExports = for { + methodSym <- classSym.info.members + if methodSym.isMethod && !methodSym.isConstructor + export <- jsInterop.registeredExportsOf(methodSym) + } yield { + assert(export.isTopLevel) + (export, methodSym) + } + + val result = for { + (jsName, tups) <- allTopLevelExports.groupBy(_._1.jsName) + } yield { + implicit val pos = tups.head._1.pos + + val alts = tups.map(t => ExportedSymbol(t._2)).toList + + js.TopLevelExportDef(genExportMethod(alts, jsName, static = true)) + } + + result.toList + } + /** Tests whether the given def a named exporter def that needs to be * generated with `genNamedExporterDef`. */ @@ -175,7 +198,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => // Generate JS code to prepare arguments (default getters and unboxes) val jsArgPrep = genPrepareArgs(jsArgRefs, trgSym) - val jsResult = genResult(trgSym, jsArgPrep.map(_.ref)) + val jsResult = genResult(trgSym, jsArgPrep.map(_.ref), static = false) js.Block(jsArgs ++ jsArgPrep :+ jsResult) } @@ -255,14 +278,17 @@ trait GenJSExports extends SubComponent { self: GenJSCode => assert(getter.size <= 1, s"Found more than one getter to export for name ${jsName}.") - val getterBody = getter.headOption.map(genApplyForSym(0, false, _)) + val getterBody = getter.headOption.map(genApplyForSym(minArgc = 0, + hasRestParam = false, _, static = false)) val setterArgAndBody = { if (setters.isEmpty) { None } else { val arg = genFormalArg(1) - val body = genExportSameArgc(1, false, setters.map(ExportedSymbol), 0) + val body = genExportSameArgc(minArgc = 1, hasRestParam = false, + alts = setters.map(ExportedSymbol), paramIndex = 0, + static = false) Some((arg, body)) } } @@ -272,7 +298,8 @@ trait GenJSExports extends SubComponent { self: GenJSCode => /** generates the exporter function (i.e. exporter for non-properties) for * a given name */ - private def genExportMethod(alts0: List[Exported], jsName: String) = { + private def genExportMethod(alts0: List[Exported], jsName: String, + static: Boolean = false) = { assert(alts0.nonEmpty, "need at least one alternative to generate exporter method") @@ -361,17 +388,19 @@ trait GenJSExports extends SubComponent { self: GenJSCode => // body of case to disambiguates methods with current count caseBody = genExportSameArgc(minArgc, needsRestParam, - methods.toList, 0, Some(argcs.min)) + methods.toList, paramIndex = 0, static, Some(argcs.min)) // argc in reverse order argcList = argcs.toList.sortBy(- _) } yield (argcList.map(argc => js.IntLiteral(argc - minArgc)), caseBody) def defaultCase = { - if (!hasVarArg) + if (!hasVarArg) { genThrowTypeError() - else - genExportSameArgc(minArgc, needsRestParam, varArgMeths, 0) + } else { + genExportSameArgc(minArgc, needsRestParam, varArgMeths, + paramIndex = 0, static = static) + } } val body = { @@ -391,7 +420,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } } - js.MethodDef(static = false, js.StringLiteral(jsName), + js.MethodDef(static, js.StringLiteral(jsName), formalArgs, jstpe.AnyType, Some(body))(OptimizerHints.empty, None) } @@ -404,13 +433,13 @@ trait GenJSExports extends SubComponent { self: GenJSCode => * @param maxArgc only use that many arguments */ private def genExportSameArgc(minArgc: Int, hasRestParam: Boolean, - alts: List[Exported], paramIndex: Int, + alts: List[Exported], paramIndex: Int, static: Boolean, maxArgc: Option[Int] = None): js.Tree = { implicit val pos = alts.head.pos if (alts.size == 1) - alts.head.genBody(minArgc, hasRestParam) + alts.head.genBody(minArgc, hasRestParam, static) else if (maxArgc.exists(_ <= paramIndex) || !alts.exists(_.params.size > paramIndex)) { // We reach here in three cases: @@ -434,7 +463,8 @@ trait GenJSExports extends SubComponent { self: GenJSCode => if (altsByTypeTest.size == 1) { // Testing this parameter is not doing any us good - genExportSameArgc(minArgc, hasRestParam, alts, paramIndex+1, maxArgc) + genExportSameArgc(minArgc, hasRestParam, alts, + paramIndex+1, static, maxArgc) } else { // Sort them so that, e.g., isInstanceOf[String] // comes before isInstanceOf[Object] @@ -449,7 +479,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => val paramRef = genFormalArgRef(paramIndex+1, minArgc) val genSubAlts = genExportSameArgc(minArgc, hasRestParam, - subAlts, paramIndex+1, maxArgc) + subAlts, paramIndex+1, static, maxArgc) def hasDefaultParam = subAlts.exists { case ExportedSymbol(p) => @@ -539,12 +569,13 @@ trait GenJSExports extends SubComponent { self: GenJSCode => * required. */ private def genApplyForSym(minArgc: Int, hasRestParam: Boolean, - sym: Symbol): js.Tree = { + sym: Symbol, static: Boolean): js.Tree = { if (isScalaJSDefinedJSClass(currentClassSym) && sym.owner != currentClassSym.get) { + assert(!static) genApplyForSymJSSuperCall(minArgc, hasRestParam, sym) } else { - genApplyForSymNonJSSuperCall(minArgc, sym) + genApplyForSymNonJSSuperCall(minArgc, sym, static) } } @@ -576,7 +607,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } private def genApplyForSymNonJSSuperCall(minArgc: Int, - sym: Symbol): js.Tree = { + sym: Symbol, static: Boolean): js.Tree = { implicit val pos = sym.pos // the (single) type of the repeated parameter if any @@ -604,7 +635,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => // Generate JS code to prepare arguments (default getters and unboxes) val jsArgPrep = genPrepareArgs(jsArgRefs, sym) ++ jsVarArgPrep - val jsResult = genResult(sym, jsArgPrep.map(_.ref)) + val jsResult = genResult(sym, jsArgPrep.map(_.ref), static) js.Block(jsArgPrep :+ jsResult) } @@ -700,12 +731,14 @@ trait GenJSExports extends SubComponent { self: GenJSCode => * Attention: This method casts the arguments to the right type. The IR * checker will not detect if you pass in a wrongly typed argument. */ - private def genResult(sym: Symbol, - args: List[js.Tree])(implicit pos: Position) = { + private def genResult(sym: Symbol, args: List[js.Tree], + static: Boolean)(implicit pos: Position) = { val thisType = if (sym.owner == ObjectClass) jstpe.ClassType(ir.Definitions.ObjectClass) else encodeClassType(sym.owner) - val receiver = js.This()(thisType) + val receiver = + if (static) genLoadModule(sym.owner) + else js.This()(thisType) val call = { if (isScalaJSDefinedJSClass(currentClassSym)) { assert(sym.owner == currentClassSym.get, sym.fullName) @@ -724,7 +757,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => private sealed abstract class Exported { def pos: Position def params: List[Type] - def genBody(minArgc: Int, hasRestParam: Boolean): js.Tree + def genBody(minArgc: Int, hasRestParam: Boolean, static: Boolean): js.Tree def name: String def typeInfo: String def hasRepeatedParam: Boolean @@ -733,8 +766,8 @@ trait GenJSExports extends SubComponent { self: GenJSCode => private case class ExportedSymbol(sym: Symbol) extends Exported { def pos: Position = sym.pos def params: List[Type] = sym.tpe.params.map(_.tpe) - def genBody(minArgc: Int, hasRestParam: Boolean): js.Tree = - genApplyForSym(minArgc, hasRestParam, sym) + def genBody(minArgc: Int, hasRestParam: Boolean, static: Boolean): js.Tree = + genApplyForSym(minArgc, hasRestParam, sym, static) def name: String = sym.name.toString def typeInfo: String = sym.tpe.toString def hasRepeatedParam: Boolean = GenJSExports.this.hasRepeatedParam(sym) @@ -742,7 +775,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => private case class ExportedBody(params: List[Type], body: js.Tree, name: String, pos: Position) extends Exported { - def genBody(minArgc: Int, hasRestParam: Boolean): js.Tree = body + def genBody(minArgc: Int, hasRestParam: Boolean, static: Boolean): js.Tree = body def typeInfo: String = params.mkString("(", ", ", ")") val hasRepeatedParam: Boolean = false } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index c0251fdd37..c500bc36a4 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -63,6 +63,7 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val JSExportDescendentClassesAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportDescendentClasses") lazy val JSExportAllAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportAll") lazy val JSExportNamedAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportNamed") + lazy val JSExportTopLevelAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportTopLevel") lazy val JSImportAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSImport") lazy val JSGlobalScopeAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSGlobalScope") lazy val ScalaJSDefinedAnnotation = getRequiredClass("scala.scalajs.js.annotation.ScalaJSDefined") diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala index 9a29853630..3057cf5c19 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala @@ -51,6 +51,7 @@ trait JSGlobalAddons extends JSDefinitions val jsName: String val pos: Position val isNamed: Boolean + val isTopLevel: Boolean } def clearGlobalState(): Unit = { @@ -58,19 +59,12 @@ trait JSGlobalAddons extends JSDefinitions jsNativeLoadSpecs.clear() } - private def assertValidForRegistration(sym: Symbol): Unit = { - assert(sym.isConstructor || sym.isClass, - "Can only register constructors or classes for export") - } - def registerForExport(sym: Symbol, infos: List[ExportInfo]): Unit = { assert(!exportedSymbols.contains(sym), "Same symbol exported twice") - assertValidForRegistration(sym) exportedSymbols.put(sym, infos) } def registeredExportsOf(sym: Symbol): List[ExportInfo] = { - assertValidForRegistration(sym) exportedSymbols.getOrElse(sym, Nil) } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala index b220f09782..86b385d5bc 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala @@ -25,8 +25,11 @@ trait PrepJSExports { this: PrepJSInterop => jsName: String, pos: Position, isNamed: Boolean, + isTopLevel: Boolean, ignoreInvalid: Boolean - ) extends jsInterop.ExportInfo + ) extends jsInterop.ExportInfo { + assert(!isNamed || !isTopLevel) + } /** Generate the exporter for the given DefDef * or ValDef (abstract val in class, val in trait or lazy val; @@ -87,8 +90,15 @@ trait PrepJSExports { this: PrepJSInterop => // Reset interface flag: Any trait will contain non-empty methods clsSym.resetFlag(Flags.INTERFACE) + val (topLevelExports, otherExports) = exports.partition(_.isTopLevel) + + /* We can handle top level exports entirely in the backend. So just + * register them here. + */ + jsInterop.registerForExport(baseSym, topLevelExports) + // Actually generate exporter methods - exports.flatMap { exp => + otherExports.flatMap { exp => if (exp.isNamed) genNamedExport(baseSym, exp.jsName, exp.pos) :: Nil else @@ -167,11 +177,13 @@ trait PrepJSExports { this: PrepJSInterop => def exportsOf(sym: Symbol): List[ExportInfo] = { val exports = directExportsOf(sym) ++ inheritedExportsOf(sym) - // Calculate the distinct exports for this symbol (eliminate double - // occurrences of (name, isNamed) pairs). - val grouped = exports.groupBy(exp => (exp.jsName, exp.isNamed)) + /* Calculate the distinct exports for this symbol (eliminate double + * occurrences of (name, isNamed, isTopLevel) tuples). + */ + val grouped = exports.groupBy( + exp => (exp.jsName, exp.isNamed, exp.isTopLevel)) - for (((jsName, isNamed), exps) <- grouped.toList) + for ((_, exps) <- grouped.toList) // Make sure that we are strict if necessary yield exps.find(!_.ignoreInvalid).getOrElse(exps.head) } @@ -192,11 +204,8 @@ trait PrepJSExports { this: PrepJSInterop => } // Annotations that are directly on the member - val directAnnots = for { - annot <- trgSym.annotations - if annot.symbol == JSExportAnnotation || - annot.symbol == JSExportNamedAnnotation - } yield annot + val directAnnots = trgSym.annotations.filter( + annot => isDirectMemberAnnot(annot.symbol)) // Is this a member export (i.e. not a class or module export)? val isMember = sym.isMethod && !sym.isConstructor @@ -214,6 +223,7 @@ trait PrepJSExports { this: PrepJSInterop => } yield { val isNamedExport = annot.symbol == JSExportNamedAnnotation val isExportAll = annot.symbol == JSExportAllAnnotation + val isTopLevelExport = annot.symbol == JSExportTopLevelAnnotation val hasExplicitName = annot.args.nonEmpty def explicitName = annot.stringArg(0).getOrElse { @@ -244,7 +254,7 @@ trait PrepJSExports { this: PrepJSInterop => // Make sure we do not override the default export of toString def isIllegalToString = { - isMember && !isNamedExport && + isMember && !isNamedExport && !isTopLevelExport && name == "toString" && sym.name != nme.toString_ && sym.tpe.params.isEmpty && !jsInterop.isJSGetter(sym) } @@ -255,7 +265,7 @@ trait PrepJSExports { this: PrepJSInterop => } def isIllegalApplyExport = { - isMember && !hasExplicitName && + isMember && !hasExplicitName && !isTopLevelExport && sym.name == nme.apply && !(isExportAll && directAnnots.exists(annot => annot.symbol == JSExportAnnotation && @@ -293,7 +303,23 @@ trait PrepJSExports { this: PrepJSInterop => "You may not export a getter or a setter as a named export") } - ExportInfo(name, annot.pos, isNamedExport, ignoreInvalid = false) + if (isTopLevelExport) { + if (jsInterop.isJSProperty(sym)) { + reporter.error(annot.pos, + "You may not export a getter or a setter to the top level") + } + + if (!isMember) { + reporter.error(annot.pos, "Use @JSExport on objects and " + + "constructors to export to the top level") + } else if (!sym.owner.isStatic || !sym.owner.isModuleClass) { + reporter.error(annot.pos, + "Only static objects may export their members to the top level") + } + } + + ExportInfo(name, annot.pos, isNamedExport, + isTopLevelExport, ignoreInvalid = false) } } @@ -348,7 +374,8 @@ trait PrepJSExports { this: PrepJSInterop => s"a @${trgAnnot.name} on $forcingSym") } - ExportInfo(name, sym.pos, false, ignoreInvalid) + ExportInfo(name, sym.pos, isNamed = false, isTopLevel = false, + ignoreInvalid) } optExport.toList @@ -526,4 +553,11 @@ trait PrepJSExports { this: PrepJSInterop => sym.paramss.flatten.reverse.dropWhile(isDefParam).exists(isDefParam) } + /** Whether a symbol is an annotation that goes directly on a member */ + private lazy val isDirectMemberAnnot = Set[Symbol]( + JSExportAnnotation, + JSExportNamedAnnotation, + JSExportTopLevelAnnotation + ) + } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index 1d33b868a4..553f1eef81 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -1095,4 +1095,160 @@ class JSExportTest extends DirectTest with TestHelpers { if (version.startsWith("2.10.") || version.startsWith("2.11.")) "" else s" (since $v)" } + + @Test + def noExportTopLevelModule: Unit = { + """ + @JSExportTopLevel("foo") + object A + """ hasErrors + """ + |newSource1.scala:3: error: Use @JSExport on objects and constructors to export to the top level + | @JSExportTopLevel("foo") + | ^ + """ + } + + @Test + def noExportTopLevelTrait: Unit = { + """ + @JSExportTopLevel("foo") + trait A + """ hasErrors + """ + |newSource1.scala:3: error: Use @JSExport on objects and constructors to export to the top level + | @JSExportTopLevel("foo") + | ^ + """ + } + + @Test + def noExportTopLevelClass: Unit = { + """ + @JSExportTopLevel("foo") + class A + """ hasErrors + """ + |newSource1.scala:3: error: Use @JSExport on objects and constructors to export to the top level + | @JSExportTopLevel("foo") + | ^ + """ + + """ + class A { + @JSExportTopLevel("foo") + def this(x: Int) = this() + } + """ hasErrors + """ + |newSource1.scala:4: error: Use @JSExport on objects and constructors to export to the top level + | @JSExportTopLevel("foo") + | ^ + """ + } + + @Test + def noExportTopLevelGetter: Unit = { + """ + object A { + @JSExportTopLevel("foo") + def a: Int = 1 + } + """ hasErrors + """ + |newSource1.scala:4: error: You may not export a getter or a setter to the top level + | @JSExportTopLevel("foo") + | ^ + """ + } + + @Test + def noExportTopLevelVal: Unit = { + """ + object A { + @JSExportTopLevel("foo") + val a: Int = 1 + } + """ hasErrors + """ + |newSource1.scala:4: error: You may not export a getter or a setter to the top level + | @JSExportTopLevel("foo") + | ^ + """ + } + + @Test + def noExportTopLevelVar: Unit = { + """ + object A { + @JSExportTopLevel("foo") + var a: Int = 1 + } + """ hasErrors + """ + |newSource1.scala:4: error: You may not export a getter or a setter to the top level + | @JSExportTopLevel("foo") + | ^ + """ + } + + @Test + def noExportTopLevelSetter: Unit = { + """ + object A { + @JSExportTopLevel("foo") + def a_=(x: Int): Unit = () + } + """ hasErrors + """ + |newSource1.scala:4: error: You may not export a getter or a setter to the top level + | @JSExportTopLevel("foo") + | ^ + """ + } + + @Test + def noExportTopLevelNonStatic: Unit = { + """ + class A { + @JSExportTopLevel("foo") + def a(): Unit = () + } + """ hasErrors + """ + |newSource1.scala:4: error: Only static objects may export their members to the top level + | @JSExportTopLevel("foo") + | ^ + """ + + """ + class A { + object B { + @JSExportTopLevel("foo") + def a(): Unit = () + } + } + """ hasErrors + """ + |newSource1.scala:5: error: Only static objects may export their members to the top level + | @JSExportTopLevel("foo") + | ^ + """ + } + + @Test + def noExportTopLevelJSModule: Unit = { + """ + @ScalaJSDefined + object A extends js.Object { + @JSExportTopLevel("foo") + def a(): Unit = () + } + """ hasErrors + """ + |newSource1.scala:5: error: You may not export a method of a subclass of js.Any + | @JSExportTopLevel("foo") + | ^ + """ + } } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala b/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala index 3e06739f85..7b7e9d37f9 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala @@ -66,7 +66,16 @@ object Definitions { val AncestorsOfPseudoArrayClass = Set( ObjectClass, SerializableClass, CloneableClass) - val ExportedConstructorsName = "__exportedInits" + /** Name used for infos of class exports + * + * These currently are exported constructors and top level exports) + * + * TODO give this a better name once we can break backwards compat. + */ + val ClassExportsName = "__exportedInits" + + @deprecated("Use ClassExportsName instead", "0.6.14") + def ExportedConstructorsName: String = "__exportedInits" /** Encodes a class name. */ def encodeClassName(fullName: String): String = { diff --git a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala index 751208f491..41ca84091f 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala @@ -258,6 +258,7 @@ object Infos { .addInterfaces(classDef.interfaces.map(_.name)) var exportedConstructors: List[ConstructorExportDef] = Nil + var topLevelExports: List[TopLevelExportDef] = Nil classDef.defs foreach { case methodDef: MethodDef => @@ -269,11 +270,16 @@ object Infos { exportedConstructors ::= constructorDef case _:JSClassExportDef | _:ModuleExportDef => builder.setIsExported(true) + case topLevelExport: TopLevelExportDef => + builder.setIsExported(true) + topLevelExports ::= topLevelExport case _ => } - if (exportedConstructors.nonEmpty) - builder.addMethod(generateExportedConstructorsInfo(exportedConstructors)) + if (exportedConstructors.nonEmpty || topLevelExports.nonEmpty) { + builder.addMethod( + generateClassExportsInfo(exportedConstructors, topLevelExports)) + } builder.result() } @@ -287,9 +293,17 @@ object Infos { new GenInfoTraverser().generatePropertyInfo(propertyDef) /** Generates the [[MethodInfo]] of a list of [[Trees.ConstructorExportDef]]s. */ + @deprecated("Use generateClassExportsInfo instead", "0.6.14") def generateExportedConstructorsInfo( constructorDefs: List[ConstructorExportDef]): MethodInfo = { - new GenInfoTraverser().generateExportedConstructorsInfo(constructorDefs) + generateClassExportsInfo(constructorDefs, Nil) + } + + /** Generates the [[MethodInfo]] for the class exports. */ + def generateClassExportsInfo(constructorDefs: List[ConstructorExportDef], + topLevelExports: List[TopLevelExportDef]): MethodInfo = { + new GenInfoTraverser().generateClassExportsInfo(constructorDefs, + topLevelExports) } private final class GenInfoTraverser extends Traversers.Traverser { @@ -320,15 +334,18 @@ object Infos { builder.result() } - def generateExportedConstructorsInfo( - constructorDefs: List[ConstructorExportDef]): MethodInfo = { + def generateClassExportsInfo(constructorDefs: List[ConstructorExportDef], + topLevelExports: List[TopLevelExportDef]): MethodInfo = { builder - .setEncodedName(ExportedConstructorsName) + .setEncodedName(ClassExportsName) .setIsExported(true) for (constructorDef <- constructorDefs) traverse(constructorDef.body) + for (topLevelExport <- topLevelExports) + traverse(topLevelExport.member) + builder.result() } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index 80b2a36c88..3f0d64f41a 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -856,6 +856,10 @@ object Printers { printEscapeJS(fullName, out) print('\"') + case TopLevelExportDef(member) => + print("export top ") + print(member) + case _ => print(s"") } diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index 7b4fecc955..a9b1d7d06c 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -21,7 +21,7 @@ object ScalaJSVersions { * - a prior release version (i.e. "0.5.0", *not* "0.5.0-SNAPSHOT") * - `current` */ - val binaryEmitted: String = "0.6.13" + val binaryEmitted: String = current /** Versions whose binary files we can support (used by deserializer) */ val binarySupported: Set[String] = { diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index 61aedb11a7..752a3c2a64 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -457,6 +457,10 @@ object Serializers { case ModuleExportDef(fullName) => writeByte(TagModuleExportDef) writeString(fullName) + + case TopLevelExportDef(member) => + writeByte(TagTopLevelExportDef) + writeTree(member) } if (UseDebugMagic) writeInt(DebugMagic) @@ -870,10 +874,10 @@ object Serializers { } else { result } - case TagJSClassExportDef => - JSClassExportDef(readString()) - case TagModuleExportDef => - ModuleExportDef(readString()) + + case TagJSClassExportDef => JSClassExportDef(readString()) + case TagModuleExportDef => ModuleExportDef(readString()) + case TagTopLevelExportDef => TopLevelExportDef(readTree()) } if (UseDebugMagic) { val magic = readInt() diff --git a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala index 5ff4951bbb..75839bdf03 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala @@ -104,6 +104,7 @@ private[ir] object Tags { final val TagJSClassExportDef = TagLoadJSModule + 1 final val TagTryCatch = TagJSClassExportDef + 1 final val TagTryFinally = TagTryCatch + 1 + final val TagTopLevelExportDef = TagTryFinally + 1 // Tags for Types diff --git a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala index c3ec757dd0..b35f8a1b34 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala @@ -231,6 +231,9 @@ object Transformers { case _:JSClassExportDef | _:ModuleExportDef => tree + case TopLevelExportDef(member) => + TopLevelExportDef(transformDef(member)) + case _ => sys.error(s"Invalid tree in transformDef() of class ${tree.getClass}") } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala index f097514d1f..aa1bed887d 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala @@ -204,6 +204,9 @@ object Traversers { case ConstructorExportDef(fullName, args, body) => traverse(body) + case TopLevelExportDef(member) => + traverse(member) + // Trees that need not be traversed case _:Skip | _:Continue | _:Debugger | _:LoadModule | diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 5f37ff7296..629770c04b 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -810,6 +810,11 @@ object Trees { val tpe = NoType } + case class TopLevelExportDef(member: Tree)( + implicit val pos: Position) extends Tree { + val tpe = NoType + } + final class OptimizerHints(val bits: Int) extends AnyVal { import OptimizerHints._ diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala index 8209318ddf..0447859ed8 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala @@ -1049,4 +1049,15 @@ class PrintersTest { """export module "pkg.Foo"""", ModuleExportDef("pkg.Foo")) } + + @Test def printTopLevelExportDef(): Unit = { + assertPrintEquals( + """ + |export top static def "pkg.foo"(x: any): any = { + | 5 + |}""", + TopLevelExportDef(MethodDef(static = true, StringLiteral("pkg.foo"), + List(ParamDef("x", AnyType, mutable = false, rest = false)), + AnyType, Some(i(5)))(NoOptHints, None))) + } } diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSExportTopLevel.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSExportTopLevel.scala new file mode 100644 index 0000000000..f6a04043e4 --- /dev/null +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSExportTopLevel.scala @@ -0,0 +1,20 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + + + +package scala.scalajs.js.annotation + +import scala.annotation.meta._ + +/** Specifies that the given member should be exported to the top level of the module. + * + * @see [[http://www.scala-js.org/doc/export-to-javascript.html Export Scala.js APIs to JavaScript]] + */ +@field @getter @setter +class JSExportTopLevel(name: String) extends scala.annotation.StaticAnnotation diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index a5987ce44d..4f32f871ed 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -3,6 +3,9 @@ import com.typesafe.tools.mima.core.ProblemFilters._ object BinaryIncompatibilities { val IR = Seq( + // private, not an issue + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.ir.Infos#GenInfoTraverser.generateExportedConstructorsInfo") ) val Tools = Seq( diff --git a/stubs/src/main/scala/scala/scalajs/js/annotation/ExportAnnotations.scala b/stubs/src/main/scala/scala/scalajs/js/annotation/ExportAnnotations.scala index c6bfd6f4c3..20281c4963 100644 --- a/stubs/src/main/scala/scala/scalajs/js/annotation/ExportAnnotations.scala +++ b/stubs/src/main/scala/scala/scalajs/js/annotation/ExportAnnotations.scala @@ -30,3 +30,5 @@ class JSExportNamed extends scala.annotation.Annotation { class JSExport extends scala.annotation.Annotation { def this(name: String) = this() } + +class JSExportTopLevel(name: String) extends scala.annotation.Annotation diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index 573f681a1b..40f95d1752 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -1231,6 +1231,35 @@ class ExportsTest { assertThrows(classOf[Throwable], obj2.z1) } + // @JSExportTopLevel + + @Test def basic_top_level_export(): Unit = { + assertEquals(1, jsPackage.toplevel.basic()) + } + + @Test def overloaded_top_level_export(): Unit = { + assertEquals("Hello World", jsPackage.toplevel.overload("World")) + assertEquals(2, jsPackage.toplevel.overload(2)) + assertEquals(9, jsPackage.toplevel.overload(2, 7)) + assertEquals(10, jsPackage.toplevel.overload(1, 2, 3, 4)) + } + + @Test def top_level_export_uses_unique_object(): Unit = { + jsPackage.toplevel.set(3) + assertEquals(3, TopLevelExports.myVar) + jsPackage.toplevel.set(7) + assertEquals(7, TopLevelExports.myVar) + } + + @Test def top_level_export_from_nested_object(): Unit = { + jsPackage.toplevel.setNested(28) + assertEquals(28, TopLevelExports.Nested.myVar) + } + + @Test def top_level_export_is_always_reachable(): Unit = { + assertEquals("Hello World", jsPackage.toplevel.reachability()) + } + // @JSExportDescendentObjects @Test def auto_exports_for_objects_extending_a_trait(): Unit = { @@ -1641,3 +1670,36 @@ object ExportHolder { @ScalaJSDefined class SJSDefinedExportedClass extends js.Object } + +object TopLevelExports { + @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.basic") + def basic(): Int = 1 + + @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.overload") + def overload(x: String): String = "Hello " + x + + @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.overload") + def overload(x: Int, y: Int*): Int = x + y.sum + + var myVar: Int = _ + + @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.set") + def setMyVar(x: Int): Unit = myVar = x + + object Nested { + var myVar: Int = _ + + @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.setNested") + def setMyVar(x: Int): Unit = myVar = x + } +} + +/* This object is only reachable via the top level export to make sure the + * analyzer behaves correctly. + */ +object TopLevelExportsReachability { + private val name = "World" + + @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.reachability") + def basic(): String = "Hello " + name +} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala index 3018978af4..3a787ee5cb 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala @@ -66,6 +66,9 @@ final class LinkedClass( case ConstructorExportDef(name, _, _) => name case ModuleExportDef(name) => name case JSClassExportDef(name) => name + + case TopLevelExportDef(MethodDef(_, StringLiteral(name), _, _, _)) => + name } def fullName: String = Definitions.decodeClassName(encodedName) @@ -182,8 +185,7 @@ object LinkedClass { sys.error(s"Illegal tree in ClassDef of class ${tree.getClass}") } - val classExportInfo = - memberInfoByName.get(Definitions.ExportedConstructorsName) + val classExportInfo = memberInfoByName.get(Definitions.ClassExportsName) new LinkedClass( classDef.name, diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala index 39357aaf67..2208c5e5b5 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala @@ -806,13 +806,18 @@ private[emitter] final class ScalaJSClassEmitter( def genClassExports(tree: LinkedClass)( implicit globalKnowledge: GlobalKnowledge): js.Tree = { - val exports = tree.classExports collect { + val exports = tree.classExports map { case e: ConstructorExportDef => genConstructorExportDef(tree, e) case e: JSClassExportDef => genJSClassExportDef(tree, e) case e: ModuleExportDef => genModuleExportDef(tree, e) + case e: TopLevelExportDef => + genTopLevelExportDef(tree, e) + case tree => + throw new AssertionError( + "Illegal class export " + tree.getClass.getName) } js.Block(exports)(tree.pos) @@ -880,6 +885,27 @@ private[emitter] final class ScalaJSClassEmitter( ) } + def genTopLevelExportDef(cd: LinkedClass, tree: TopLevelExportDef)( + implicit globalKnowledge: GlobalKnowledge): js.Tree = { + import TreeDSL._ + + val MethodDef(true, StringLiteral(fullName), args, resultType, Some(body)) = + tree.member + + implicit val pos = tree.pos + + val (createNamespace, expAccessorVar) = + genCreateNamespaceInExports(fullName) + + val methodDef = desugarToFunction(this, cd.encodedName, args, + body, isStat = resultType == NoType) + + js.Block( + createNamespace, + expAccessorVar := methodDef + ) + } + // Helpers /** Gen JS code for assigning an rhs to a qualified name in the exports scope. diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 19580ad84a..d1b70ce017 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -130,7 +130,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { case m: MethodDef => assert(m.name.isInstanceOf[StringLiteral], "Exported method must have StringLiteral as name") - checkExportedMethodDef(m, classDef) + checkExportedMethodDef(m, classDef, isTopLevel = false) case p: PropertyDef => assert(p.name.isInstanceOf[StringLiteral], "Exported property must have StringLiteral as name") @@ -149,10 +149,23 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { tree match { case member @ ConstructorExportDef(_, _, _) => checkConstructorExportDef(member, classDef) + case member @ JSClassExportDef(_) => checkJSClassExportDef(member, classDef) + case member @ ModuleExportDef(_) => checkModuleExportDef(member, classDef) + + case TopLevelExportDef(member) => + member match { + case methodDef: MethodDef => + checkExportedMethodDef(methodDef, classDef, isTopLevel = true) + + case _ => + reportError("Illegal top level export of type " + + member.getClass.getName) + } + // Anything else is illegal case _ => reportError("Illegal class export of type " + @@ -255,19 +268,22 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { } private def checkExportedMethodDef(methodDef: MethodDef, - classDef: LinkedClass): Unit = withPerMethodState { + classDef: LinkedClass, isTopLevel: Boolean): Unit = withPerMethodState { val MethodDef(static, StringLiteral(name), params, resultType, body) = methodDef implicit val ctx = ErrorContext(methodDef) - if (!classDef.kind.isAnyScalaJSDefinedClass) { + if (!isTopLevel && !classDef.kind.isAnyScalaJSDefinedClass) { reportError(s"Exported method def can only appear in a class") return } - if (static) + if (!isTopLevel && static) reportError("Exported method def cannot be static") - if (name.contains("__") && name != Definitions.ExportedConstructorsName) + if (isTopLevel && !static) + reportError("Top level export must be static") + + if (name.contains("__") && name != Definitions.ClassExportsName) reportError("Exported method def name cannot contain __") for (ParamDef(name, tpe, _, _) <- params) { @@ -293,9 +309,11 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { "but must be Any") } - val thisType = - if (classDef.kind.isJSClass) AnyType + val thisType = { + if (static) NoType + else if (classDef.kind.isJSClass) AnyType else ClassType(classDef.name.name) + } body.fold { reportError("Exported method cannot be abstract") diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index 516eb6aee8..b3638d74f2 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -251,6 +251,9 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions case e: ModuleExportDef => classExports += e + case e: TopLevelExportDef => + classExports += e + case tree => sys.error(s"Illegal tree in ClassDef of class ${tree.getClass}") } @@ -281,8 +284,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions } } - val classExportInfo = - memberInfoByName.get(Definitions.ExportedConstructorsName) + val classExportInfo = memberInfoByName.get(Definitions.ClassExportsName) val kind = if (analyzerInfo.isModuleAccessed) classDef.kind From 5f5f59c86c2b18bf2095416a2f8db6e3dbc4094d Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 2 Dec 2016 15:21:51 +0100 Subject: [PATCH 0052/2665] Fix #2668: Only allow 1 or 2 arg @JSBracketAccess --- .../scalajs/core/compiler/PrepJSInterop.scala | 6 +++++ .../core/compiler/test/JSInteropTest.scala | 24 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 6e677501f4..5c853f9aa6 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -794,6 +794,12 @@ abstract class PrepJSInterop extends plugins.PluginComponent if (enclosingOwner is OwnerKind.JSNonNative) { reporter.error(tree.pos, "@JSBracketAccess is not allowed in Scala.js-defined JS classes") + } else { + val paramCount = sym.paramss.map(_.size).sum + if (paramCount != 1 && paramCount != 2) { + reporter.error(tree.pos, + "@JSBracketAccess methods must have one or two parameters") + } } } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index 0d6e8d2450..da6100fbad 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -400,6 +400,30 @@ class JSInteropTest extends DirectTest with TestHelpers { } + @Test + def noBadBracketAccess: Unit = { + + """ + @js.native + class A extends js.Object { + @js.annotation.JSBracketAccess + def foo(): Int = js.native + + @js.annotation.JSBracketAccess + def bar(x: Int, y: Int, z: Int): Int = js.native + } + """ hasErrors + """ + |newSource1.scala:8: error: @JSBracketAccess methods must have one or two parameters + | def foo(): Int = js.native + | ^ + |newSource1.scala:11: error: @JSBracketAccess methods must have one or two parameters + | def bar(x: Int, y: Int, z: Int): Int = js.native + | ^ + """ + + } + @Test def noBadBracketCall: Unit = { From b30e4cf5f6160fd7f494c994f003abf401b7c849 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 2 Dec 2016 15:41:09 +0100 Subject: [PATCH 0053/2665] Fix #2658: Graceful error on bad @JSBracketAccess return type --- .../org/scalajs/core/compiler/PrepJSInterop.scala | 4 ++++ .../scalajs/core/compiler/test/JSInteropTest.scala | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 5c853f9aa6..fde196ab7e 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -799,6 +799,10 @@ abstract class PrepJSInterop extends plugins.PluginComponent if (paramCount != 1 && paramCount != 2) { reporter.error(tree.pos, "@JSBracketAccess methods must have one or two parameters") + } else if (paramCount == 2 && + sym.tpe.finalResultType.typeSymbol != UnitClass) { + reporter.error(tree.pos, + "@JSBracketAccess methods with two parameters must return Unit") } } } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index da6100fbad..73d16e0219 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -422,6 +422,19 @@ class JSInteropTest extends DirectTest with TestHelpers { | ^ """ + """ + @js.native + class A extends js.Object { + @js.annotation.JSBracketAccess + def foo(x: Int, y: Int): Int = js.native + } + """ hasErrors + """ + |newSource1.scala:8: error: @JSBracketAccess methods with two parameters must return Unit + | def foo(x: Int, y: Int): Int = js.native + | ^ + """ + } @Test From 892a09df018d7157a76570ae364ebfcdd327d3f0 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 2 Dec 2016 15:43:00 +0100 Subject: [PATCH 0054/2665] Disallow other bad @JSBracketAccess params Note that this is technically speaking a backwards compatibility breaking change. It was possible to define repeated or default arguments in @JSBracketAccess methods, as long as the invocation site had one or two parameters. However, all of the (working) use cases this breaks can be replaced by overloads in a fully source and binary compatible manner. --- .../scalajs/core/compiler/PrepJSInterop.scala | 10 +++++++ .../core/compiler/test/JSInteropTest.scala | 26 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index fde196ab7e..9cdd16e43a 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -804,6 +804,16 @@ abstract class PrepJSInterop extends plugins.PluginComponent reporter.error(tree.pos, "@JSBracketAccess methods with two parameters must return Unit") } + + for (param <- sym.paramss.flatten) { + if (isScalaRepeatedParamType(param.tpe)) { + reporter.error(param.pos, + "@JSBracketAccess methods may not have repeated parameters") + } else if (param.isParamWithDefault) { + reporter.error(param.pos, + "@JSBracketAccess methods may not have default parameters") + } + } } } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index 73d16e0219..7199a0b175 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -435,6 +435,32 @@ class JSInteropTest extends DirectTest with TestHelpers { | ^ """ + """ + @js.native + class A extends js.Object { + @js.annotation.JSBracketAccess + def bar(x: Int*): Int = js.native + } + """ hasErrors + """ + |newSource1.scala:8: error: @JSBracketAccess methods may not have repeated parameters + | def bar(x: Int*): Int = js.native + | ^ + """ + + """ + @js.native + class A extends js.Object { + @js.annotation.JSBracketAccess + def bar(x: Int = 1): Int = js.native + } + """ hasErrors + """ + |newSource1.scala:8: error: @JSBracketAccess methods may not have default parameters + | def bar(x: Int = 1): Int = js.native + | ^ + """ + } @Test From 1d41454318b59f3708bfe1528319bd2aabe2bf88 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 2 Dec 2016 16:13:23 +0100 Subject: [PATCH 0055/2665] Fix #2639: Refuse to import modules without module support --- .../linker/backend/emitter/Emitter.scala | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git 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 index 08e1dd5afb..0e6c1ef616 100644 --- 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 @@ -15,6 +15,7 @@ import scala.collection.mutable import org.scalajs.core.ir.{ClassKind, Position} import org.scalajs.core.ir.Trees.JSNativeLoadSpec +import org.scalajs.core.ir.Definitions.decodeClassName import org.scalajs.core.tools.sem._ import org.scalajs.core.tools.logging._ @@ -106,7 +107,7 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, try { val orderedClasses = unit.classDefs.sortWith(compareClasses) - emitModuleImports(orderedClasses, builder) + emitModuleImports(orderedClasses, builder, logger) for (classInfo <- orderedClasses) emitLinkedClass(classInfo, builder) @@ -116,9 +117,29 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, } private def emitModuleImports(orderedClasses: List[LinkedClass], - builder: JSTreeBuilder): Unit = { + builder: JSTreeBuilder, logger: Logger): Unit = { moduleKind match { case ModuleKind.NoModule => + var importsFound: Boolean = false + + for (classDef <- orderedClasses) { + classDef.jsNativeLoadSpec match { + case Some(JSNativeLoadSpec.Import(module, _)) => + val displayName = decodeClassName(classDef.encodedName) + logger.error(s"$displayName needs to be imported from module " + + s"'$module' but module support is disabled.") + importsFound = true + + case _ => + // ok + } + } + + if (importsFound) { + sys.error("There were module imports, but module support is " + + "disabled.\nTo enable module support, set scalaJSModuleKind := " + + "ModuleKind.CommonJSModule.") + } case ModuleKind.CommonJSModule => val jsDesugaring = new JSDesugaring(internalOptions) From 4f88d0095f352bef5fa1f0bfb223cd6df2b1277a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 4 Dec 2016 17:06:59 +0100 Subject: [PATCH 0056/2665] Fix #2649: Fall back to `updateClassifiers` on 2.10.5. Due to what appears to be a bug in sbt, `update` will not correctly fetch the `sources` artifact of the Scala library if `scalaVersion` happens to be the version of Scala used for sbt itself. We work around this bug by falling back to `updateClassifiers` in this specific case. --- project/Build.scala | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/project/Build.scala b/project/Build.scala index ea8e11bef9..25c0a00dc1 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -844,13 +844,26 @@ object Build { artifactPath in fetchScalaSource := target.value / "scalaSources" / scalaVersion.value, + /* Work around for #2649. We would like to always use `update`, but + * that fails if the scalaVersion we're looking for happens to be the + * version of Scala used by sbt itself. This is clearly a bug in sbt, + * which we work around here by using `updateClassifiers` instead in + * that case. + */ + update in fetchScalaSource := Def.taskDyn { + if (scalaVersion.value == scala.util.Properties.versionNumberString) + updateClassifiers + else + update + }.value, + fetchScalaSource := { val s = streams.value val cacheDir = s.cacheDirectory val ver = scalaVersion.value val trgDir = (artifactPath in fetchScalaSource).value - val report = update.value + val report = (update in fetchScalaSource).value val scalaLibSourcesJar = report.select( configuration = Set("compile"), module = moduleFilter(name = "scala-library"), From 2b4d68f25bf0a7361213ed90bde421162b7abd2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 4 Dec 2016 20:43:06 +0100 Subject: [PATCH 0057/2665] Fix #2587: Corner case in BigDecimal.multiply(). When multiplying two negative numbers for which the product should be `-2^63` (which is `-Long.MinValue`), the sum of the bit lengths is 63, but the result is still not representable. This is now detected as a special case. --- javalib/src/main/scala/java/math/BigDecimal.scala | 9 ++++++++- .../javalib/math/BigDecimalArithmeticTest.scala | 8 ++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/javalib/src/main/scala/java/math/BigDecimal.scala b/javalib/src/main/scala/java/math/BigDecimal.scala index 9b4165af06..eb6bca565f 100644 --- a/javalib/src/main/scala/java/math/BigDecimal.scala +++ b/javalib/src/main/scala/java/math/BigDecimal.scala @@ -675,7 +675,14 @@ class BigDecimal() extends Number with Comparable[BigDecimal] { if (this.isZero || multiplicand.isZero) { zeroScaledBy(newScale) } else if (this._bitLength + multiplicand._bitLength < 64) { - valueOf(this._smallValue * multiplicand._smallValue, safeLongToInt(newScale)) + val smallResult = this._smallValue * multiplicand._smallValue + if (smallResult == Long.MinValue && + this._smallValue < 0L && multiplicand._smallValue < 0L) { + // Corner case #2587: the result should be -Long.MinValue + new BigDecimal(BigInteger.getPowerOfTwo(63), safeLongToInt(newScale)) + } else { + valueOf(smallResult, safeLongToInt(newScale)) + } } else { val unscaled = this.getUnscaledValue.multiply(multiplicand.getUnscaledValue) new BigDecimal(unscaled, safeLongToInt(newScale)) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalArithmeticTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalArithmeticTest.scala index f8c8c3cb73..be3b7ddf37 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalArithmeticTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalArithmeticTest.scala @@ -1104,6 +1104,14 @@ class BigDecimalArithmeticTest { assertEquals(result.scale(), cScale) } + @Test def testMultiplySmallOverflow_issue2587(): Unit = { + val x = new BigDecimal(Int.MinValue) + val y = new BigDecimal(Int.MinValue.toLong * 2L) + val z = new BigDecimal("9223372036854775808") + assertEquals(z, x.multiply(y)) + assertEquals(z, y.multiply(x)) + } + @Test def testPow(): Unit = { val a = "123121247898748298842980" val aScale = 10 From f58ed8df31fb08e2ede163fb5a9a9e27c1ec20c8 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 3 Dec 2016 21:20:21 +0100 Subject: [PATCH 0058/2665] Fix #2631: Gracefully fail if UndefinedParam slips In Scala, default parameters are resolved at call site. Therefore, it is valid for a macro or a compiler plugin to move them around or even completely decouple from the function call they originated from. However, for Scala.js' facade types, this is not the case, mainly because in JavaScript, default parameters are resolved at definition site. Macros and compiler plugins must (to some extent) be aware of this restriction when running together with the Scala.js compiler plugin. With this commit, we gracefully report if we cannot compile a tree we received due to this restriction. Before this fix, the compiler emitted invalid IR. --- .../scalajs/core/compiler/GenJSFiles.scala | 14 +++ .../compiler/test/JSUndefinedParamTest.scala | 89 +++++++++++++++++++ .../core/compiler/test/util/DirectTest.scala | 14 ++- .../scala/org/scalajs/core/ir/Infos.scala | 8 ++ .../scalajs/core/ir/InvalidIRException.scala | 4 + project/Build.scala | 22 +++-- 6 files changed, 142 insertions(+), 9 deletions(-) create mode 100644 compiler/src/test/scala/org/scalajs/core/compiler/test/JSUndefinedParamTest.scala create mode 100644 ir/src/main/scala/org/scalajs/core/ir/InvalidIRException.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSFiles.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSFiles.scala index fe49926a26..8f1101d84e 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSFiles.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSFiles.scala @@ -29,6 +29,20 @@ trait GenJSFiles extends SubComponent { self: GenJSCode => try { ir.InfoSerializers.serialize(output, Infos.generateClassInfo(tree)) ir.Serializers.serialize(output, tree) + } catch { + case e: ir.InvalidIRException => + e.tree match { + case ir.Trees.UndefinedParam() => + reporter.error(sym.pos, "Found a dangling UndefinedParam at " + + s"${e.tree.pos}. This is likely due to a bad interaction " + + "between a macro or a compiler plugin and the Scala.js " + + "compiler plugin. If you hit this, please let us know.") + + case _ => + reporter.error(sym.pos, "The Scala.js compiler generated " + + "invalid IR for this class. Please report this as a bug. IR: " + + e.tree) + } } finally { output.close() } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSUndefinedParamTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSUndefinedParamTest.scala new file mode 100644 index 0000000000..4e96076583 --- /dev/null +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSUndefinedParamTest.scala @@ -0,0 +1,89 @@ +package org.scalajs.core.compiler.test + +import org.scalajs.core.compiler.test.util._ +import org.junit.Test + +// scalastyle:off line.size.limit + +/** This tests the UndefinedParam tracker in the compiler backend. + * + * In order to properly implement removal of trailing default parameters, the + * compiler backend may generate a UndefinedParam tree and catch it later. + * However, some macros and compiler plugins may generate trees the backend + * doesn't expect. As a result the backend used to generate invalid IR. + * Instead, we now track these helper trees and emit a more helpful error + * message if one of them sticks around. + * + * This test contains a macro that generates a tree we cannot handle and + * verifies that the compiler bails out. + */ +class JSUndefinedParamTest extends DirectTest with TestHelpers { + + /* We need a macro in the test. Therefore, we add scala-reflect and the + * compiler's output path itself to the classpath. + */ + override def classpath: List[String] = + super.classpath ++ List(scalaReflectPath, testOutputPath) + + @Test def noDanglingUndefinedParam: Unit = { + + // Define macro that extracts method parameter. + """ + import language.experimental.macros + + /** Dummy object to get the right shadowing for cross compilation */ + private object Compat210 { + object blackbox { // scalastyle:ignore + type Context = scala.reflect.macros.Context + } + } + + import Compat210._ + + object JSUndefinedParamTest { + import scala.reflect.macros._ // shadows blackbox from above + import blackbox.Context + + def extractArg(call: Any): Any = macro extractArg_impl + + def extractArg_impl(c: Context)(call: c.Expr[Any]): c.Expr[Any] = { + import c.universe._ + + call.tree match { + case Apply(fun, List(arg)) => c.Expr[Any](arg) + + case tree => + c.abort(tree.pos, "Bad tree. Need function call with single argument.") + } + } + } + """.succeeds() + + // Use the macro to trigger UndefinedParam catcher. + """ + import scala.scalajs.js + import scala.scalajs.js.annotation._ + + @js.native + trait MyTrait extends js.Any { + def foo(x: Int = js.native): Int = js.native + } + + object A { + val myTrait: MyTrait = ??? + + /* We assign the default parameter value for foo to b. + * This should fail. + */ + val b = JSUndefinedParamTest.extractArg(myTrait.foo()) + } + """ hasErrors + """ + |newSource1.scala:10: error: Found a dangling UndefinedParam at Position(virtualfile:newSource1.scala,15,54). This is likely due to a bad interaction between a macro or a compiler plugin and the Scala.js compiler plugin. If you hit this, please let us know. + | object A { + | ^ + """ + + } + +} diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala index f9891eea65..da04b730e3 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala @@ -8,6 +8,8 @@ import org.scalajs.core.compiler.ScalaJSPlugin import scala.collection.mutable +import java.io.File + /** This is heavily inspired by scala's partest suite's DirectTest */ abstract class DirectTest { @@ -26,7 +28,7 @@ abstract class DirectTest { List( "-d", testOutputPath, "-bootclasspath", scalaLibPath, - "-classpath", scalaJSLibPath) ++ + "-classpath", classpath.mkString(File.pathSeparator)) ++ extraArgs ++ args.toList) lazy val global: Global = new Global(settings, newReporter(settings)) { @@ -68,8 +70,16 @@ abstract class DirectTest { // Filed as #1443 def defaultGlobal: Global = newScalaJSCompiler() - def testOutputPath: String = sys.props("scala.scalajs.compiler.test.output") + def testOutputPath: String = { + val baseDir = sys.props("scala.scalajs.compiler.test.output") + val outDir = new File(baseDir, getClass.getName) + outDir.mkdirs() + outDir.getAbsolutePath + } + def scalaJSLibPath: String = sys.props("scala.scalajs.compiler.test.scalajslib") def scalaLibPath: String = sys.props("scala.scalajs.compiler.test.scalalib") + def scalaReflectPath: String = sys.props("scala.scalajs.compiler.test.scalareflect") + def classpath: List[String] = List(scalaJSLibPath) } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala index 41ca84091f..aab909bec7 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala @@ -382,6 +382,14 @@ object Infos { case LoadJSModule(ClassType(cls)) => builder.addAccessedModule(cls) + /* We explicitly catch UndefinedParam here to make sure, we do not + * emit it in the compiler. This does not entirely belong here, as it + * supports GenJSCode, but it is not wrong to throw an exception. + */ + case UndefinedParam() => + throw new InvalidIRException(tree, + "Found UndefinedParam while building infos") + case _ => } diff --git a/ir/src/main/scala/org/scalajs/core/ir/InvalidIRException.scala b/ir/src/main/scala/org/scalajs/core/ir/InvalidIRException.scala new file mode 100644 index 0000000000..9805565300 --- /dev/null +++ b/ir/src/main/scala/org/scalajs/core/ir/InvalidIRException.scala @@ -0,0 +1,4 @@ +package org.scalajs.core.ir + +class InvalidIRException(val tree: Trees.Tree, message: String) + extends Exception(message) diff --git a/project/Build.scala b/project/Build.scala index ea8e11bef9..24b3a72662 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -529,21 +529,29 @@ object Build { testOutDir.getAbsolutePath sys.props("scala.scalajs.compiler.test.scalajslib") = (packageBin in (library, Compile)).value.getAbsolutePath - sys.props("scala.scalajs.compiler.test.scalalib") = { - def isScalaLib(att: Attributed[File]) = { + def scalaArtifact(name: String): String = { + def isTarget(att: Attributed[File]) = { att.metadata.get(moduleID.key).exists { mId => mId.organization == "org.scala-lang" && - mId.name == "scala-library" && - mId.revision == scalaVersion.value + mId.name == name && + mId.revision == scalaVersion.value } } - val lib = (managedClasspath in Test).value.find(isScalaLib) - lib.map(_.data.getAbsolutePath).getOrElse { - streams.value.log.error("Couldn't find Scala library on the classpath. CP: " + (managedClasspath in Test).value); "" + (managedClasspath in Test).value.find(isTarget).fold { + streams.value.log.error(s"Couldn't find $name on the classpath") + "" + } { lib => + lib.data.getAbsolutePath } } + + sys.props("scala.scalajs.compiler.test.scalalib") = + scalaArtifact("scala-library") + + sys.props("scala.scalajs.compiler.test.scalareflect") = + scalaArtifact("scala-reflect") }, exportJars := true ) From 71ef9d2a4386f315a7641f802dd1fdf69e85fffb Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Mon, 5 Dec 2016 09:42:40 +0100 Subject: [PATCH 0059/2665] Add history API support to JSDOMNodeJSEnv --- .../jsenv/test/JSDOMNodeJSEnvTest.scala | 23 +++++++++++++++++++ .../scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala | 1 + 2 files changed, 24 insertions(+) create mode 100644 js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/JSDOMNodeJSEnvTest.scala diff --git a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/JSDOMNodeJSEnvTest.scala b/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/JSDOMNodeJSEnvTest.scala new file mode 100644 index 0000000000..88d8e19ff2 --- /dev/null +++ b/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/JSDOMNodeJSEnvTest.scala @@ -0,0 +1,23 @@ +package org.scalajs.jsenv.test + +import org.scalajs.jsenv.nodejs.JSDOMNodeJSEnv + +import org.junit.Test +import org.junit.Assert._ + +class JSDOMNodeJSEnvTest extends TimeoutComTests { + + protected def newJSEnv: JSDOMNodeJSEnv = new JSDOMNodeJSEnv() + + @Test + def historyAPI: Unit = { + """|console.log(window.location.href); + |window.history.pushState({}, "", "/foo"); + |console.log(window.location.href); + """.stripMargin hasOutput + """|http://localhost/ + |http://localhost/foo + |""".stripMargin + } + +} diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala index 3ba875f421..cc0d4cc530 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala @@ -77,6 +77,7 @@ class JSDOMNodeJSEnv( | }, | scripts: [${scriptsStringPath.mkString(", ")}], | onload: function (window) { + | jsdom.changeURL(window, "http://localhost"); | for (var k in window) { | if (windowKeys.indexOf(k) == -1) | global[k] = window[k]; From a7fdab74e09c7d9f94289837709cda2348efdaf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 28 Nov 2016 14:00:22 +0100 Subject: [PATCH 0060/2665] Allow concrete val/var/defs in JS traits with `= js.undefined`. Normally, term members in Scala.js-defined JS traits must be abstract. This commit relaxes the restriction to allow vals, vars and defs without parentheses to be concrete, if their right-hand- side is `js.undefined`. Such fields and methods are not actually created on Scala.js-defined JS classes and objects that extend those traits. Instead, they get a value of `undefined` by virtue of JavaScript using `undefined` for missing fields. In case of a `var`, the field can be created later by explicit assignment. For `val`s and `def`s, it can be created in subclasses with an `override val` or `override def`. This is particularly useful to model "configuration objects" as used in many JavaScript APIs. A Scala.js-defined JS trait with concrete `js.undefined` fields can define a typed API for the configuration object. It is then easy to create a configuration object with only a few fields set by defining `override val`s. Other fields and are not created on the resulting JavaScript object. --- .../org/scalajs/core/compiler/GenJSCode.scala | 36 ++- .../scalajs/core/compiler/JSDefinitions.scala | 2 + .../scalajs/core/compiler/PrepJSInterop.scala | 97 ++++-- .../test/InternalAnnotationsTest.scala | 28 +- .../core/compiler/test/JSOptionalTest.scala | 160 ++++++++++ .../compiler/test/ScalaJSDefinedTest.scala | 8 +- .../js/annotation/internal/JSOptional.scala | 22 ++ project/Build.scala | 7 +- .../jsinterop/JSOptionalTest212.scala | 245 ++++++++++++++ .../testsuite/jsinterop/JSOptionalTest.scala | 299 ++++++++++++++++++ 10 files changed, 865 insertions(+), 39 deletions(-) create mode 100644 compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala create mode 100644 library/src/main/scala/scala/scalajs/js/annotation/internal/JSOptional.scala create mode 100644 test-suite/js/src/test/require-2.12/org/scalajs/testsuite/jsinterop/JSOptionalTest212.scala create mode 100644 test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 226a0eebab..57d17d137d 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -281,12 +281,7 @@ abstract class GenJSCode extends plugins.PluginComponent val isPrimitive = isPrimitiveValueClass(sym) || (sym == ArrayClass) - /* Similarly, do not emit code for impl classes of raw JS traits. */ - val isRawJSImplClass = - sym.isImplClass && isRawJSType( - sym.owner.info.decl(sym.name.dropRight(nme.IMPL_CLASS_SUFFIX.length)).tpe) - - if (!isPrimitive && !isRawJSImplClass) { + if (!isPrimitive && !isRawJSImplClass(sym)) { withScopedVars( currentClassSym := sym, unexpectedMutatedFields := mutable.Set.empty, @@ -468,6 +463,8 @@ abstract class GenJSCode extends plugins.PluginComponent /* Exposed accessors must not be emitted, since the field they * access is enough. */ + } else if (sym.hasAnnotation(JSOptionalAnnotation)) { + // Optional methods must not be emitted } else { generatedMethods ++= genMethod(dd) @@ -811,6 +808,7 @@ abstract class GenJSCode extends plugins.PluginComponent (for { f <- classSym.info.decls if !f.isMethod && f.isTerm && !f.isModule + if !f.hasAnnotation(JSOptionalAnnotation) } yield { implicit val pos = f.pos @@ -2133,7 +2131,15 @@ abstract class GenJSCode extends plugins.PluginComponent val sym = fun.symbol if (isScalaJSDefinedJSClass(currentClassSym)) { - genJSSuperCall(tree, isStat) + if (sym.isMixinConstructor) { + /* Do not emit a call to the $init$ method of JS traits. + * This exception is necessary because @JSOptional fields cause the + * creation of a $init$ method, which we must not call. + */ + js.Skip() + } else { + genJSSuperCall(tree, isStat) + } } else { val superCall = genApplyMethodStatically( genThis()(sup.pos), sym, genActualArgs(sym, args)) @@ -2346,7 +2352,15 @@ abstract class GenJSCode extends plugins.PluginComponent def genTraitImplApply(method: Symbol, arguments: List[js.Tree])( implicit pos: Position): js.Tree = { - genApplyStatic(method, arguments) + if (method.isMixinConstructor && isRawJSImplClass(method.owner)) { + /* Do not emit a call to the $init$ method of JS traits. + * This exception is necessary because @JSOptional fields cause the + * creation of a $init$ method, which we must not call. + */ + js.Skip() + } else { + genApplyStatic(method, arguments) + } } def genApplyJSClassMethod(receiver: js.Tree, method: Symbol, @@ -5012,6 +5026,12 @@ abstract class GenJSCode extends plugins.PluginComponent private def isJSNativeClass(sym: Symbol): Boolean = isRawJSType(sym.tpe) && !isScalaJSDefinedJSClass(sym) + /** Tests whether the given class is the impl class of a raw JS trait. */ + private def isRawJSImplClass(sym: Symbol): Boolean = { + sym.isImplClass && isRawJSType( + sym.owner.info.decl(sym.name.dropRight(nme.IMPL_CLASS_SUFFIX.length)).tpe) + } + /** Tests whether the given member is exposed, i.e., whether it was * originally a public or protected member of a Scala.js-defined JS class. */ diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index c500bc36a4..e9282868c8 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -28,6 +28,7 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val JSPackage_constructorOf = getMemberMethod(ScalaJSJSPackage, newTermName("constructorOf")) lazy val JSPackage_debugger = getMemberMethod(ScalaJSJSPackage, newTermName("debugger")) lazy val JSPackage_native = getMemberMethod(ScalaJSJSPackage, newTermName("native")) + lazy val JSPackage_undefined = getMemberMethod(ScalaJSJSPackage, newTermName("undefined")) lazy val JSNativeAnnotation = getRequiredClass("scala.scalajs.js.native") @@ -69,6 +70,7 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val ScalaJSDefinedAnnotation = getRequiredClass("scala.scalajs.js.annotation.ScalaJSDefined") lazy val SJSDefinedAnonymousClassAnnotation = getRequiredClass("scala.scalajs.js.annotation.SJSDefinedAnonymousClass") lazy val HasJSNativeLoadSpecAnnotation = getRequiredClass("scala.scalajs.js.annotation.internal.HasJSNativeLoadSpec") + lazy val JSOptionalAnnotation = getRequiredClass("scala.scalajs.js.annotation.internal.JSOptional") lazy val JavaDefaultMethodAnnotation = getRequiredClass("scala.scalajs.js.annotation.JavaDefaultMethod") diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 9cdd16e43a..d7b4b619c4 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -610,30 +610,52 @@ abstract class PrepJSInterop extends plugins.PluginComponent } } - // Check for overrides with different JS names - issue #1983 + // Check for consistency of JS semantics across overriding for (overridingPair <- new overridingPairs.Cursor(sym).iterator) { val low = overridingPair.low val high = overridingPair.high - if (jsInterop.jsNameOf(low) != jsInterop.jsNameOf(high)) { - val pos = { - if (sym == low.owner) low.pos - else if (sym == high.owner) high.pos - else sym.pos - } + def errorPos = { + if (sym == low.owner) low.pos + else if (sym == high.owner) high.pos + else sym.pos + } + + def memberDefString(membSym: Symbol): String = + membSym.defStringSeenAs(sym.thisType.memberType(membSym)) + + // Check for overrides with different JS names - issue #1983 + if (jsInterop.jsNameOf(low) != jsInterop.jsNameOf(high)) { val msg = { - def memberDefString(membSym: Symbol) = { - membSym.defStringSeenAs(sym.thisType.memberType(membSym)) + + def memberDefStringWithJSName(membSym: Symbol) = { + memberDefString(membSym) + membSym.locationString + " with JSName '" + jsInterop.jsNameOf(membSym) + '\'' } "A member of a JS class is overriding another member with a different JS name.\n\n" + - memberDefString(low) + "\n" + + memberDefStringWithJSName(low) + "\n" + " is conflicting with\n" + - memberDefString(high) + "\n" + memberDefStringWithJSName(high) + "\n" } - reporter.warning(pos, msg) + reporter.warning(errorPos, msg) + } + + /* Cannot override a non-@JSOptional with an @JSOptional. Unfortunately + * at this point the symbols do not have @JSOptional yet, so we need + * to detect whether it would be applied. + */ + if (!isJSNative) { + def isJSOptional(sym: Symbol): Boolean = { + sym.owner.isTrait && !sym.isDeferred && !sym.isConstructor && + sym.owner.hasAnnotation(ScalaJSDefinedAnnotation) + } + + if (isJSOptional(low) && !(high.isDeferred || isJSOptional(high))) { + reporter.error(errorPos, + s"Cannot override concrete ${memberDefString(high)} from " + + s"${high.owner.fullName} in a Scala.js-defined JS trait.") + } } } @@ -865,14 +887,52 @@ abstract class PrepJSInterop extends plugins.PluginComponent "must be final") } - // Traits must be pure interfaces + // Traits must be pure interfaces, except for js.undefined members if (sym.owner.isTrait && sym.isTerm && !sym.isConstructor) { - if (!sym.isDeferred) { - reporter.error(tree.pos, - "A Scala.js-defined JS trait can only contain abstract members") - } else if (isPrivateMaybeWithin(sym)) { + if (sym.isMethod && isPrivateMaybeWithin(sym)) { reporter.error(tree.pos, "A Scala.js-defined JS trait cannot contain private members") + } else if (!sym.isDeferred) { + /* Tell the back-end not emit this thing. In fact, this only + * matters for mixed-in members created from this member. + */ + sym.addAnnotation(JSOptionalAnnotation) + + // For non-accessor methods, check that they do not have parens + if (sym.isMethod && !sym.isAccessor) { + sym.tpe match { + case _: NullaryMethodType => + // ok + case PolyType(_, _: NullaryMethodType) => + // ok + case _ => + reporter.error(tree.rhs.pos, + "In Scala.js-defined JS traits, defs with parentheses " + + "must be abstract.") + } + } + + /* Check that the right-hand-side is `js.undefined`. + * + * On 2.12+, fields are created later than this phase, and getters + * still hold the right-hand-side that we need to check (we + * identify this case with `sym.accessed == NoSymbol`). + * On 2.11 and before, however, the getter has already been + * rewritten to read the field, so we must not check it. + * In either case, setters must not be checked. + */ + if (!sym.isAccessor || (sym.isGetter && sym.accessed == NoSymbol)) { + // Check that the tree's body is `js.undefined` + tree.rhs match { + case sel: Select if sel.symbol == JSPackage_undefined => + // ok + case _ => + reporter.error(tree.rhs.pos, + "Members of Scala.js-defined JS traits must either be " + + "abstract, or their right-hand-side must be " + + "`js.undefined`.") + } + } } } } @@ -1255,7 +1315,8 @@ abstract class PrepJSInterop extends plugins.PluginComponent annotation.symbol == ExposedJSMemberAnnot || annotation.symbol == JSFullNameAnnotation || annotation.symbol == RawJSTypeAnnot || - annotation.symbol == SJSDefinedAnonymousClassAnnotation + annotation.symbol == SJSDefinedAnonymousClassAnnotation || + annotation.symbol == JSOptionalAnnotation } if (tree.isInstanceOf[MemberDef]) { diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/InternalAnnotationsTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/InternalAnnotationsTest.scala index 5a4377aab1..5e2c061ed7 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/InternalAnnotationsTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/InternalAnnotationsTest.scala @@ -9,7 +9,7 @@ import org.junit._ class InternalAnnotationsTest extends DirectTest with TestHelpers { override def preamble: String = - "import scala.scalajs.js, js.annotation._" + "import scala.scalajs.js, js.annotation._, js.annotation.internal._" @Test def exposedJSMember: Unit = { @@ -31,7 +31,15 @@ class InternalAnnotationsTest extends DirectTest with TestHelpers { test("SJSDefinedAnonymousClass") } - private def test(annotation: String): Unit = { + @Test + def jsOptional: Unit = { + test("JSOptional", "scala.scalajs.js.annotation.internal.JSOptional") + } + + private def test(annotation: String): Unit = + test(annotation, s"scala.scalajs.js.annotation.$annotation") + + private def test(annotation: String, annotFullName: String): Unit = { s""" @$annotation trait A @$annotation class B { @@ -44,28 +52,28 @@ class InternalAnnotationsTest extends DirectTest with TestHelpers { } """ hasErrors s""" - |newSource1.scala:2: error: scala.scalajs.js.annotation.$annotation is for compiler internal use only. Do not use it yourself. + |newSource1.scala:2: error: $annotFullName is for compiler internal use only. Do not use it yourself. | @$annotation trait A | ^ - |newSource1.scala:3: error: scala.scalajs.js.annotation.$annotation is for compiler internal use only. Do not use it yourself. + |newSource1.scala:3: error: $annotFullName is for compiler internal use only. Do not use it yourself. | @$annotation class B { | ^ - |newSource1.scala:4: error: scala.scalajs.js.annotation.$annotation is for compiler internal use only. Do not use it yourself. + |newSource1.scala:4: error: $annotFullName is for compiler internal use only. Do not use it yourself. | @$annotation val a = ??? | ^ - |newSource1.scala:5: error: scala.scalajs.js.annotation.$annotation is for compiler internal use only. Do not use it yourself. + |newSource1.scala:5: error: $annotFullName is for compiler internal use only. Do not use it yourself. | @$annotation var b = ??? | ^ - |newSource1.scala:6: error: scala.scalajs.js.annotation.$annotation is for compiler internal use only. Do not use it yourself. + |newSource1.scala:6: error: $annotFullName is for compiler internal use only. Do not use it yourself. | @$annotation def c = ??? | ^ - |newSource1.scala:7: error: scala.scalajs.js.annotation.$annotation is for compiler internal use only. Do not use it yourself. + |newSource1.scala:7: error: $annotFullName is for compiler internal use only. Do not use it yourself. | def d(@$annotation i: Int) = ??? | ^ - |newSource1.scala:8: error: scala.scalajs.js.annotation.$annotation is for compiler internal use only. Do not use it yourself. + |newSource1.scala:8: error: $annotFullName is for compiler internal use only. Do not use it yourself. | @$annotation class X | ^ - |newSource1.scala:9: error: scala.scalajs.js.annotation.$annotation is for compiler internal use only. Do not use it yourself. + |newSource1.scala:9: error: $annotFullName is for compiler internal use only. Do not use it yourself. | @$annotation trait Y | ^ """ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala new file mode 100644 index 0000000000..71ef7cd7a0 --- /dev/null +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala @@ -0,0 +1,160 @@ +package org.scalajs.core.compiler.test + +import org.scalajs.core.compiler.test.util._ + +import org.junit.Test +import org.junit.Ignore + +// scalastyle:off line.size.limit + +class JSOptionalTest extends DirectTest with TestHelpers { + + override def preamble: String = { + """ + import scala.scalajs.js + import scala.scalajs.js.annotation._ + """ + } + + @Test + def optionalRequiresUndefinedRHS: Unit = { + s""" + @ScalaJSDefined + trait A extends js.Object { + val a1: js.UndefOr[Int] = 5 + val a2: Int = 5 + + def b1: js.UndefOr[Int] = 5 + def b2: Int = 5 + + var c1: js.UndefOr[Int] = 5 + var c2: Int = 5 + } + """ hasErrors + s""" + |newSource1.scala:7: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. + | val a1: js.UndefOr[Int] = 5 + | ^ + |newSource1.scala:8: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. + | val a2: Int = 5 + | ^ + |newSource1.scala:10: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. + | def b1: js.UndefOr[Int] = 5 + | ^ + |newSource1.scala:11: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. + | def b2: Int = 5 + | ^ + |newSource1.scala:13: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. + | var c1: js.UndefOr[Int] = 5 + | ^ + |newSource1.scala:14: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. + | var c2: Int = 5 + | ^ + """ + } + + @Test + def noOverrideConcreteNonOptionalWithOptional: Unit = { + s""" + @ScalaJSDefined + abstract class A extends js.Object { + val a1: js.UndefOr[Int] = 5 + val a2: js.UndefOr[Int] + + def b1: js.UndefOr[Int] = 5 + def b2: js.UndefOr[Int] + } + + @ScalaJSDefined + trait B extends A { + override val a1: js.UndefOr[Int] = js.undefined + override val a2: js.UndefOr[Int] = js.undefined + + override def b1: js.UndefOr[Int] = js.undefined + override def b2: js.UndefOr[Int] = js.undefined + } + """ hasErrors + s""" + |newSource1.scala:16: error: Cannot override concrete val a1: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + | override val a1: js.UndefOr[Int] = js.undefined + | ^ + |newSource1.scala:19: error: Cannot override concrete def b1: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + | override def b1: js.UndefOr[Int] = js.undefined + | ^ + """ + + s""" + @js.native + class A extends js.Object { + val a: js.UndefOr[Int] = js.native + def b: js.UndefOr[Int] = js.native + } + + @ScalaJSDefined + trait B extends A { + override val a: js.UndefOr[Int] = js.undefined + override def b: js.UndefOr[Int] = js.undefined + } + """ hasErrors + s""" + |newSource1.scala:13: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + | override val a: js.UndefOr[Int] = js.undefined + | ^ + |newSource1.scala:14: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + | override def b: js.UndefOr[Int] = js.undefined + | ^ + """ + + s""" + @js.native + trait A extends js.Object { + val a: js.UndefOr[Int] = js.native + def b: js.UndefOr[Int] = js.native + } + + @js.native + class B extends A + + @ScalaJSDefined + trait C extends B { + override val a: js.UndefOr[Int] = js.undefined + override def b: js.UndefOr[Int] = js.undefined + } + """ hasErrors + s""" + |newSource1.scala:16: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + | override val a: js.UndefOr[Int] = js.undefined + | ^ + |newSource1.scala:17: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + | override def b: js.UndefOr[Int] = js.undefined + | ^ + """ + } + + @Test + def noOptionalDefWithParens: Unit = { + s""" + @ScalaJSDefined + trait A extends js.Object { + def a(): js.UndefOr[Int] = js.undefined + def b(x: Int): js.UndefOr[Int] = js.undefined + def c_=(v: Int): js.UndefOr[Int] = js.undefined + } + """ hasErrors + s""" + |newSource1.scala:7: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. + | def a(): js.UndefOr[Int] = js.undefined + | ^ + |newSource1.scala:8: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. + | def b(x: Int): js.UndefOr[Int] = js.undefined + | ^ + |newSource1.scala:9: error: Raw JS setters must return Unit + | def c_=(v: Int): js.UndefOr[Int] = js.undefined + | ^ + |newSource1.scala:9: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. + | def c_=(v: Int): js.UndefOr[Int] = js.undefined + | ^ + """ + } + +} diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala index 3106b22509..14242f48b7 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala @@ -596,12 +596,16 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { @ScalaJSDefined trait A extends js.Object { def foo(x: Int): Int = x + 1 + def bar[A](x: A): A = x } """ hasErrors """ - |newSource1.scala:7: error: A Scala.js-defined JS trait can only contain abstract members + |newSource1.scala:7: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. | def foo(x: Int): Int = x + 1 - | ^ + | ^ + |newSource1.scala:8: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. + | def bar[A](x: A): A = x + | ^ """ } diff --git a/library/src/main/scala/scala/scalajs/js/annotation/internal/JSOptional.scala b/library/src/main/scala/scala/scalajs/js/annotation/internal/JSOptional.scala new file mode 100644 index 0000000000..4d4ab3b3fa --- /dev/null +++ b/library/src/main/scala/scala/scalajs/js/annotation/internal/JSOptional.scala @@ -0,0 +1,22 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js API ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package scala.scalajs.js.annotation.internal + +import scala.annotation.meta._ + +/** IMPLEMENTATION DETAIL: Marks concrete members of Scala.js-defined JS + * traits, so that they can be identified by the back-end not to emit them. + * + * Internally, such members are known as "optional", in reference to their + * primary intended use case: optional fields in configuration objects. + * + * Do not use this annotation yourself. + */ +@field @getter @setter +class JSOptional extends scala.annotation.StaticAnnotation diff --git a/project/Build.scala b/project/Build.scala index b24da00b93..4101387f55 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1312,9 +1312,14 @@ object Build { val sharedTestDir = testDir.getParentFile.getParentFile.getParentFile / "shared/src/test" + val scalaV = scalaVersion.value + val isScalaAtLeast212 = + !scalaV.startsWith("2.10.") && !scalaV.startsWith("2.11.") + List(sharedTestDir / "scala") ++ includeIf(sharedTestDir / "require-jdk7", javaVersion.value >= 7) ++ - includeIf(sharedTestDir / "require-jdk8", javaVersion.value >= 8) + includeIf(sharedTestDir / "require-jdk8", javaVersion.value >= 8) ++ + includeIf(testDir / "require-2.12", isJSTest && isScalaAtLeast212) }, sources in Test ++= { diff --git a/test-suite/js/src/test/require-2.12/org/scalajs/testsuite/jsinterop/JSOptionalTest212.scala b/test-suite/js/src/test/require-2.12/org/scalajs/testsuite/jsinterop/JSOptionalTest212.scala new file mode 100644 index 0000000000..0ce5c9e978 --- /dev/null +++ b/test-suite/js/src/test/require-2.12/org/scalajs/testsuite/jsinterop/JSOptionalTest212.scala @@ -0,0 +1,245 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.jsinterop + +import scala.scalajs.js +import scala.scalajs.js.annotation._ + +import org.junit.Assert._ +import org.junit.Test + +import org.scalajs.testsuite.utils.JSAssert._ + +/** 2.12+ tests for `@JSOptional`. + * + * This class is basically a copy-paste of `JSOptionalTest`, where + * `override val/def`s do not have an explicit result type. Instead, they + * are inferred from the superclasses. + */ +class JSOptionalTest212 { + import JSOptionalTest212._ + + @Test def classImplementsTraitWithOptional(): Unit = { + val obj = new ClassImplementsTraitWithOptional + + assertEquals(js.undefined, obj.x) + assertFalse(obj.hasOwnProperty("x")) + + assertEquals(js.undefined, obj.y) + assertFalse(js.Object.hasProperty(obj, "y")) + + assertEquals(js.undefined, obj.y2) + assertFalse(js.Object.hasProperty(obj, "y2")) + + assertEquals(js.undefined, obj.z) + assertFalse(obj.hasOwnProperty("z")) + obj.z = Some(3) + assertEquals(Some(3), obj.z) + } + + @Test def anonClassImplementsTraitWithOptional(): Unit = { + val obj = new TraitWithOptional {} + + assertEquals(js.undefined, obj.x) + assertFalse(obj.hasOwnProperty("x")) + + assertEquals(js.undefined, obj.y) + assertFalse(js.Object.hasProperty(obj, "y")) + + assertEquals(js.undefined, obj.y2) + assertFalse(js.Object.hasProperty(obj, "y2")) + + assertEquals(js.undefined, obj.z) + assertFalse(obj.hasOwnProperty("z")) + obj.z = Some(3) + assertEquals(Some(3), obj.z) + } + + @Test def undefinedInClassIsNotOptional(): Unit = { + val obj = new UndefinedInClassIsNotOptional + + assertEquals(js.undefined, obj.x) + assertTrue(obj.hasOwnProperty("x")) + + assertEquals(js.undefined, obj.y) + assertTrue(js.Object.hasProperty(obj, "y")) + + assertEquals(js.undefined, obj.y2) + assertTrue(js.Object.hasProperty(obj, "y2")) + + assertEquals(js.undefined, obj.z) + assertTrue(obj.hasOwnProperty("z")) + obj.z = Some(3) + assertEquals(Some(3), obj.z) + } + + @Test def overrideWithUndefinedInClassIsNotOptional(): Unit = { + val obj = new OverrideWithUndefinedInClassIsNotOptional + + assertEquals(js.undefined, obj.x) + assertTrue(obj.hasOwnProperty("x")) + + assertEquals(js.undefined, obj.y) + assertTrue(js.Object.hasProperty(obj, "y")) + + assertEquals(js.undefined, obj.y2) + assertTrue(js.Object.hasProperty(obj, "y2")) + + assertEquals(js.undefined, obj.z) + assertTrue(obj.hasOwnProperty("z")) + obj.z = Some(3) + assertEquals(Some(3), obj.z) + } + + @Test def classOverrideOptionalWithConcrete(): Unit = { + val obj = new ClassImplementsTraitWithOptionalOverrideWithConcrete + + assertEquals(42, obj.x) + assertTrue(obj.hasOwnProperty("x")) + + assertEquals("hello", obj.y) + assertTrue(obj.hasOwnProperty("y")) + + assertEquals("world", obj.y2) + assertTrue(js.Object.hasProperty(obj, "y2")) + + assertEquals(Some(5), obj.z) + assertTrue(obj.hasOwnProperty("z")) + obj.z = Some(3) + assertEquals(Some(3), obj.z) + } + + @Test def anonClassOverrideOptionalWithConcrete(): Unit = { + val obj = new TraitWithOptional { + override val x = 42 + override val y = "hello" + override def y2 = "world" // scalastyle:ignore + z = Some(5) + } + + assertEquals(42, obj.x) + assertTrue(obj.hasOwnProperty("x")) + + assertEquals("hello", obj.y) + assertTrue(obj.hasOwnProperty("y")) + + assertEquals("world", obj.y2) + assertTrue(js.Object.hasProperty(obj, "y2")) + + assertEquals(Some(5), obj.z) + assertTrue(obj.hasOwnProperty("z")) + obj.z = Some(3) + assertEquals(Some(3), obj.z) + } + + @Test def overrideClassAbstractWithOptional(): Unit = { + @ScalaJSDefined + abstract class ClassWithAbstracts extends js.Object { + val x: js.UndefOr[Int] + def y: js.UndefOr[String] + def y2: js.UndefOr[String] + var z: js.UndefOr[Option[Int]] + } + + @ScalaJSDefined + trait OverrideClassAbstractWithOptional extends ClassWithAbstracts { + val x = js.undefined + def y = js.undefined + val y2 = js.undefined + var z: js.UndefOr[Option[Int]] = js.undefined + } + + val obj = new OverrideClassAbstractWithOptional {} + + assertEquals(js.undefined, obj.x) + assertFalse(obj.hasOwnProperty("x")) + + assertEquals(js.undefined, obj.y) + assertFalse(js.Object.hasProperty(obj, "y")) + + assertEquals(js.undefined, obj.y2) + assertFalse(js.Object.hasProperty(obj, "y2")) + + assertEquals(js.undefined, obj.z) + assertFalse(obj.hasOwnProperty("z")) + obj.z = Some(3) + assertEquals(Some(3), obj.z) + } + + @Test def overrideTraitAbstractWithOptional(): Unit = { + @ScalaJSDefined + trait TraitWithAbstracts extends js.Object { + val x: js.UndefOr[Int] + def y: js.UndefOr[String] + def y2: js.UndefOr[String] + var z: js.UndefOr[Option[Int]] + } + + @ScalaJSDefined + trait OverrideTraitAbstractWithOptional extends TraitWithAbstracts { + val x = js.undefined + def y = js.undefined + val y2 = js.undefined + var z: js.UndefOr[Option[Int]] = js.undefined + } + + val obj = new OverrideTraitAbstractWithOptional {} + + assertEquals(js.undefined, obj.x) + assertFalse(obj.hasOwnProperty("x")) + + assertEquals(js.undefined, obj.y) + assertFalse(js.Object.hasProperty(obj, "y")) + + assertEquals(js.undefined, obj.y2) + assertFalse(js.Object.hasProperty(obj, "y2")) + + assertEquals(js.undefined, obj.z) + assertFalse(obj.hasOwnProperty("z")) + obj.z = Some(3) + assertEquals(Some(3), obj.z) + } +} + +object JSOptionalTest212 { + @ScalaJSDefined + trait TraitWithOptional extends js.Object { + val x: js.UndefOr[Int] = js.undefined + def y: js.UndefOr[String] = js.undefined + def y2: js.UndefOr[String] = js.undefined + var z: js.UndefOr[Option[Int]] = js.undefined + } + + @ScalaJSDefined + class ClassImplementsTraitWithOptional extends TraitWithOptional + + @ScalaJSDefined + class UndefinedInClassIsNotOptional extends js.Object { + val x: js.UndefOr[Int] = js.undefined + def y: js.UndefOr[String] = js.undefined + def y2: js.UndefOr[String] = js.undefined + var z: js.UndefOr[Option[Int]] = js.undefined + } + + @ScalaJSDefined + class OverrideWithUndefinedInClassIsNotOptional extends TraitWithOptional { + override val x = js.undefined + override def y = js.undefined // scalastyle:ignore + override def y2 = js.undefined // scalastyle:ignore + z = js.undefined + } + + @ScalaJSDefined + class ClassImplementsTraitWithOptionalOverrideWithConcrete + extends TraitWithOptional { + override val x = 42 + override val y = "hello" + override def y2 = "world" // scalastyle:ignore + z = Some(5) + } +} diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala new file mode 100644 index 0000000000..00729e06f3 --- /dev/null +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala @@ -0,0 +1,299 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.jsinterop + +import scala.scalajs.js +import scala.scalajs.js.annotation._ + +import org.junit.Assert._ +import org.junit.Test + +import org.scalajs.testsuite.utils.JSAssert._ + +class JSOptionalTest { + import JSOptionalTest._ + + @Test def classImplementsTraitWithOptional(): Unit = { + val obj = new ClassImplementsTraitWithOptional + + assertEquals(js.undefined, obj.x) + assertFalse(obj.hasOwnProperty("x")) + + assertEquals(js.undefined, obj.y) + assertFalse(js.Object.hasProperty(obj, "y")) + + assertEquals(js.undefined, obj.y2) + assertFalse(js.Object.hasProperty(obj, "y2")) + + assertEquals(js.undefined, obj.z) + assertFalse(obj.hasOwnProperty("z")) + obj.z = Some(3) + assertEquals(Some(3), obj.z) + } + + @Test def anonClassImplementsTraitWithOptional(): Unit = { + val obj = new TraitWithOptional {} + + assertEquals(js.undefined, obj.x) + assertFalse(obj.hasOwnProperty("x")) + + assertEquals(js.undefined, obj.y) + assertFalse(js.Object.hasProperty(obj, "y")) + + assertEquals(js.undefined, obj.y2) + assertFalse(js.Object.hasProperty(obj, "y2")) + + assertEquals(js.undefined, obj.z) + assertFalse(obj.hasOwnProperty("z")) + obj.z = Some(3) + assertEquals(Some(3), obj.z) + } + + @Test def undefinedInClassIsNotOptional(): Unit = { + val obj = new UndefinedInClassIsNotOptional + + assertEquals(js.undefined, obj.x) + assertTrue(obj.hasOwnProperty("x")) + + assertEquals(js.undefined, obj.y) + assertTrue(js.Object.hasProperty(obj, "y")) + + assertEquals(js.undefined, obj.y2) + assertTrue(js.Object.hasProperty(obj, "y2")) + + assertEquals(js.undefined, obj.z) + assertTrue(obj.hasOwnProperty("z")) + obj.z = Some(3) + assertEquals(Some(3), obj.z) + } + + @Test def overrideWithUndefinedInClassIsNotOptional(): Unit = { + val obj = new OverrideWithUndefinedInClassIsNotOptional + + assertEquals(js.undefined, obj.x) + assertTrue(obj.hasOwnProperty("x")) + + assertEquals(js.undefined, obj.y) + assertTrue(js.Object.hasProperty(obj, "y")) + + assertEquals(js.undefined, obj.y2) + assertTrue(js.Object.hasProperty(obj, "y2")) + + assertEquals(js.undefined, obj.z) + assertTrue(obj.hasOwnProperty("z")) + obj.z = Some(3) + assertEquals(Some(3), obj.z) + } + + @Test def classOverrideOptionalWithConcrete(): Unit = { + val obj = new ClassImplementsTraitWithOptionalOverrideWithConcrete + + assertEquals(42, obj.x) + assertTrue(obj.hasOwnProperty("x")) + + assertEquals("hello", obj.y) + assertTrue(obj.hasOwnProperty("y")) + + assertEquals("world", obj.y2) + assertTrue(js.Object.hasProperty(obj, "y2")) + + assertEquals(Some(5), obj.z) + assertTrue(obj.hasOwnProperty("z")) + obj.z = Some(3) + assertEquals(Some(3), obj.z) + } + + @Test def anonClassOverrideOptionalWithConcrete(): Unit = { + val obj = new TraitWithOptional { + override val x: js.UndefOr[Int] = 42 + override val y: js.UndefOr[String] = "hello" + override def y2: js.UndefOr[String] = "world" + z = Some(5) + } + + assertEquals(42, obj.x) + assertTrue(obj.hasOwnProperty("x")) + + assertEquals("hello", obj.y) + assertTrue(obj.hasOwnProperty("y")) + + assertEquals("world", obj.y2) + assertTrue(js.Object.hasProperty(obj, "y2")) + + assertEquals(Some(5), obj.z) + assertTrue(obj.hasOwnProperty("z")) + obj.z = Some(3) + assertEquals(Some(3), obj.z) + } + + @Test def overrideOptionalWithOptional(): Unit = { + val obj = new OverrideOptionalWithOptional {} + + assertEquals(js.undefined, obj.x) + assertFalse(obj.hasOwnProperty("x")) + + assertEquals(js.undefined, obj.y) + assertFalse(js.Object.hasProperty(obj, "y")) + + assertEquals(js.undefined, obj.y2) + assertFalse(js.Object.hasProperty(obj, "y2")) + } + + @Test def overrideOptionalWithOptionalImplicitType(): Unit = { + val obj = new OverrideOptionalWithOptionalImplicitType {} + + assertEquals(js.undefined, obj.x) + assertFalse(obj.hasOwnProperty("x")) + + assertEquals(js.undefined, obj.y) + assertFalse(js.Object.hasProperty(obj, "y")) + + assertEquals(js.undefined, obj.y2) + assertFalse(js.Object.hasProperty(obj, "y2")) + } + + @Test def overrideClassAbstractWithOptional(): Unit = { + @ScalaJSDefined + abstract class ClassWithAbstracts extends js.Object { + val x: js.UndefOr[Int] + def y: js.UndefOr[String] + def y2: js.UndefOr[String] + var z: js.UndefOr[Option[Int]] + } + + @ScalaJSDefined + trait OverrideClassAbstractWithOptional extends ClassWithAbstracts { + val x: js.UndefOr[Int] = js.undefined + def y: js.UndefOr[String] = js.undefined + val y2: js.UndefOr[String] = js.undefined + var z: js.UndefOr[Option[Int]] = js.undefined + } + + val obj = new OverrideClassAbstractWithOptional {} + + assertEquals(js.undefined, obj.x) + assertFalse(obj.hasOwnProperty("x")) + + assertEquals(js.undefined, obj.y) + assertFalse(js.Object.hasProperty(obj, "y")) + + assertEquals(js.undefined, obj.y2) + assertFalse(js.Object.hasProperty(obj, "y2")) + + assertEquals(js.undefined, obj.z) + assertFalse(obj.hasOwnProperty("z")) + obj.z = Some(3) + assertEquals(Some(3), obj.z) + } + + @Test def overrideTraitAbstractWithOptional(): Unit = { + @ScalaJSDefined + trait TraitWithAbstracts extends js.Object { + val x: js.UndefOr[Int] + def y: js.UndefOr[String] + def y2: js.UndefOr[String] + var z: js.UndefOr[Option[Int]] + } + + @ScalaJSDefined + trait OverrideTraitAbstractWithOptional extends TraitWithAbstracts { + val x: js.UndefOr[Int] = js.undefined + def y: js.UndefOr[String] = js.undefined + val y2: js.UndefOr[String] = js.undefined + var z: js.UndefOr[Option[Int]] = js.undefined + } + + val obj = new OverrideTraitAbstractWithOptional {} + + assertEquals(js.undefined, obj.x) + assertFalse(obj.hasOwnProperty("x")) + + assertEquals(js.undefined, obj.y) + assertFalse(js.Object.hasProperty(obj, "y")) + + assertEquals(js.undefined, obj.y2) + assertFalse(js.Object.hasProperty(obj, "y2")) + + assertEquals(js.undefined, obj.z) + assertFalse(obj.hasOwnProperty("z")) + obj.z = Some(3) + assertEquals(Some(3), obj.z) + } + + def polyOptionalMethod(): Unit = { + @ScalaJSDefined + trait TraitWithPolyOptionalMethod extends js.Object { + def foo[A]: js.UndefOr[A] = js.undefined + } + + val obj = new TraitWithPolyOptionalMethod {} + + assertEquals(js.undefined, obj.foo[Int]) + assertFalse(js.Object.hasProperty(obj, "foo")) + } +} + +object JSOptionalTest { + @ScalaJSDefined + trait TraitWithOptional extends js.Object { + val x: js.UndefOr[Int] = js.undefined + def y: js.UndefOr[String] = js.undefined + def y2: js.UndefOr[String] = js.undefined + var z: js.UndefOr[Option[Int]] = js.undefined + } + + @ScalaJSDefined + class ClassImplementsTraitWithOptional extends TraitWithOptional + + @ScalaJSDefined + class UndefinedInClassIsNotOptional extends js.Object { + val x: js.UndefOr[Int] = js.undefined + def y: js.UndefOr[String] = js.undefined + def y2: js.UndefOr[String] = js.undefined + var z: js.UndefOr[Option[Int]] = js.undefined + } + + @ScalaJSDefined + class OverrideWithUndefinedInClassIsNotOptional extends TraitWithOptional { + override val x: js.UndefOr[Int] = js.undefined + override def y: js.UndefOr[String] = js.undefined + override def y2: js.UndefOr[String] = js.undefined + z = js.undefined + } + + @ScalaJSDefined + class ClassImplementsTraitWithOptionalOverrideWithConcrete + extends TraitWithOptional { + override val x: js.UndefOr[Int] = 42 + override val y: js.UndefOr[String] = "hello" + override def y2: js.UndefOr[String] = "world" + z = Some(5) + } + + @ScalaJSDefined + trait OverrideOptionalWithOptional extends TraitWithOptional { + override val x: js.UndefOr[Int] = js.undefined + override val y: js.UndefOr[String] = js.undefined + override def y2: js.UndefOr[String] = js.undefined + } + + @ScalaJSDefined + trait OverrideOptionalWithOptionalImplicitType extends TraitWithOptional { + /* Unlike cases where the rhs is an Int, String, etc., this compiles even + * in 2.10 and 2.11, because the inferred type is `js.UndefOr[Nothing]` + * (the type of `js.undefined`) which is truly a subtype of the inherited + * member's type `js.UndefOr[Int/String]`. Note that in this case, it + * would be impossible to re-override these fields with a + * `js.UndefOr[Int/String]` in a subclass, which means this is pretty + * useless in practice. + */ + override val x = js.undefined + override val y = js.undefined + override def y2 = js.undefined // scalastyle:ignore + } +} From 68bc904a3434db7ead045a3a6c1570ec2ef8e1ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 12 Dec 2016 15:12:55 +0100 Subject: [PATCH 0061/2665] Do not rely on `import` being relative to the `scala` package. Because Eclipse sometimes does not like it, and it's ugly anyway. --- .../scala/org/scalajs/testsuite/junit/JUnitBootstrapTest.scala | 2 +- .../src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitBootstrapTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitBootstrapTest.scala index c28caf4e8c..ff4e92d318 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitBootstrapTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitBootstrapTest.scala @@ -1,6 +1,6 @@ package org.scalajs.testsuite.junit -import scalajs.js +import scala.scalajs.js import org.junit.Test import org.junit.Assert.assertTrue diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala index 6a6039e405..45af7b965c 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala @@ -3,8 +3,6 @@ package org.scalajs.testsuite.junit import org.scalajs.junit.JUnitTestBootstrapper import org.junit.Assert.fail -import scalajs.js - object JUnitUtil { private final val BootstrapperSuffix = "$scalajs$junit$bootstrapper" From daeec34cdb1e265379fbe6e9b65f29a186fe668c Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Mon, 12 Dec 2016 16:33:24 -0800 Subject: [PATCH 0062/2665] fix a couple out-of-date comments --- .../src/main/scala/org/scalajs/core/compiler/GenJSCode.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 226a0eebab..cb2c1303ba 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -1223,7 +1223,7 @@ abstract class GenJSCode extends plugins.PluginComponent * Interface methods with the {{{@JavaDefaultMethod}}} annotation produce * default methods forwarding to the trait impl class method. * - * Other (normal) methods are emitted with `genMethodBody()`. + * Other (normal) methods are emitted with `genMethodDef()`. */ def genMethodWithCurrentLocalNameScope(dd: DefDef): Option[js.MethodDef] = { implicit val pos = dd.pos @@ -1579,7 +1579,7 @@ abstract class GenJSCode extends plugins.PluginComponent /** Local val or var declaration */ case ValDef(_, name, _, rhs) => /* Must have been eliminated by the tail call transform performed - * by genMethodBody(). */ + * by genMethodDef(). */ assert(name != nme.THIS, s"ValDef(_, nme.THIS, _, _) found at ${tree.pos}") From 6f0e5011c62025ff450fb7ac6cd80931881bfb25 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 2 Dec 2016 13:54:39 +0100 Subject: [PATCH 0063/2665] Fix #2655: NumericRange.{min|max} for Doubles As a side-effect, this fixes min/max for arbitrary integral types (which is currently broken in Scala JVM). This copies the upstream fix for SI-10086 (scala/scala@738ac6d7d3902767cc4cd5820fe83632e558f049). --- .../collection/immutable/NumericRange.scala | 9 +++- .../collection/immutable/NumericRange.scala | 9 +++- .../collection/immutable/NumericRange.scala | 9 +++- .../testsuite/scalalib/RangesTest.scala | 46 +++++++++++++++++++ 4 files changed, 67 insertions(+), 6 deletions(-) diff --git a/scalalib/overrides-2.10/scala/collection/immutable/NumericRange.scala b/scalalib/overrides-2.10/scala/collection/immutable/NumericRange.scala index d3971ee89e..95abce3fae 100644 --- a/scalalib/overrides-2.10/scala/collection/immutable/NumericRange.scala +++ b/scalalib/overrides-2.10/scala/collection/immutable/NumericRange.scala @@ -128,13 +128,18 @@ extends AbstractSeq[T] with IndexedSeq[T] with Serializable { import NumericRange.defaultOrdering override def min[T1 >: T](implicit ord: Ordering[T1]): T = - if (ord eq defaultOrdering(num)) { + // We can take the fast path: + // - If the Integral of this NumericRange is also the requested Ordering + // (Integral <: Ordering). This can happen for custom Integral types. + // - The Ordering is the default Ordering of a well-known Integral type. + if ((ord eq num) || defaultOrdering.get(num).exists(ord eq _)) { if (num.signum(step) > 0) start else last } else super.min(ord) override def max[T1 >: T](implicit ord: Ordering[T1]): T = - if (ord eq defaultOrdering(num)) { + // See comment for fast path in min(). + if ((ord eq num) || defaultOrdering.get(num).exists(ord eq _)) { if (num.signum(step) > 0) last else start } else super.max(ord) diff --git a/scalalib/overrides-2.11/scala/collection/immutable/NumericRange.scala b/scalalib/overrides-2.11/scala/collection/immutable/NumericRange.scala index a4a0a6016a..c3fcbd9f46 100644 --- a/scalalib/overrides-2.11/scala/collection/immutable/NumericRange.scala +++ b/scalalib/overrides-2.11/scala/collection/immutable/NumericRange.scala @@ -114,13 +114,18 @@ extends AbstractSeq[T] with IndexedSeq[T] with Serializable { import NumericRange.defaultOrdering override def min[T1 >: T](implicit ord: Ordering[T1]): T = - if (ord eq defaultOrdering(num)) { + // We can take the fast path: + // - If the Integral of this NumericRange is also the requested Ordering + // (Integral <: Ordering). This can happen for custom Integral types. + // - The Ordering is the default Ordering of a well-known Integral type. + if ((ord eq num) || defaultOrdering.get(num).exists(ord eq _)) { if (num.signum(step) > 0) start else last } else super.min(ord) override def max[T1 >: T](implicit ord: Ordering[T1]): T = - if (ord eq defaultOrdering(num)) { + // See comment for fast path in min(). + if ((ord eq num) || defaultOrdering.get(num).exists(ord eq _)) { if (num.signum(step) > 0) last else start } else super.max(ord) diff --git a/scalalib/overrides-2.12/scala/collection/immutable/NumericRange.scala b/scalalib/overrides-2.12/scala/collection/immutable/NumericRange.scala index 527b77482c..65e703829c 100644 --- a/scalalib/overrides-2.12/scala/collection/immutable/NumericRange.scala +++ b/scalalib/overrides-2.12/scala/collection/immutable/NumericRange.scala @@ -114,13 +114,18 @@ extends AbstractSeq[T] with IndexedSeq[T] with Serializable { import NumericRange.defaultOrdering override def min[T1 >: T](implicit ord: Ordering[T1]): T = - if (ord eq defaultOrdering(num)) { + // We can take the fast path: + // - If the Integral of this NumericRange is also the requested Ordering + // (Integral <: Ordering). This can happen for custom Integral types. + // - The Ordering is the default Ordering of a well-known Integral type. + if ((ord eq num) || defaultOrdering.get(num).exists(ord eq _)) { if (num.signum(step) > 0) start else last } else super.min(ord) override def max[T1 >: T](implicit ord: Ordering[T1]): T = - if (ord eq defaultOrdering(num)) { + // See comment for fast path in min(). + if ((ord eq num) || defaultOrdering.get(num).exists(ord eq _)) { if (num.signum(step) > 0) last else start } else super.max(ord) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/RangesTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/RangesTest.scala index b81501183a..cabd946a1e 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/RangesTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/RangesTest.scala @@ -93,4 +93,50 @@ class RangesTest { Range.Double(0.1, 1.0, 0.1).toString) } } + + @Test def NumericRange_min_issue_2655(): Unit = { + val y = 1.0 to 10.0 by 1.0 + assertEquals(1.0, y.min, 0.0) + } + + @Test def NumericRange_max_issue_2655(): Unit = { + val y = 1.0 to 10.0 by 1.0 + assertEquals(10.0, y.max, 0.0) + } + + @Test def NumericRange_with_arbitrary_integral(): Unit = { + // This is broken in Scala JVM up to (including) 2.11.8, 2.12.1 (SI-10086). + assumeFalse("Assumed not on JVM for 2.10.X", + executingInJVM && scalaVersion.startsWith("2.10.")) + assumeFalse("Assumed not on JVM for 2.11.{0-8}", + executingInJVM && (0 to 8).map("2.11." + _).contains(scalaVersion)) + assumeFalse("Assumed not on JVM for 2.12.{0-1}", + executingInJVM && (0 to 1).map("2.12." + _).contains(scalaVersion)) + + // Our custom integral type. + case class A(v: Int) + + implicit object aIsIntegral extends scala.math.Integral[A] { + def compare(x: A, y: A): Int = x.v.compare(y.v) + def fromInt(x: Int): A = A(x) + def minus(x: A, y: A): A = A(x.v - y.v) + def negate(x: A): A = A(-x.v) + def plus(x: A, y: A): A = A(x.v + y.v) + def times(x: A, y: A): A = A(x.v * y.v) + def quot(x: A, y: A): A = A(x.v / y.v) + def rem(x: A, y: A): A = A(x.v % y.v) + def toDouble(x: A): Double = x.v.toDouble + def toFloat(x: A): Float = x.v.toFloat + def toInt(x: A): Int = x.v + def toLong(x: A): Long = x.v.toLong + } + + val r = NumericRange(A(1), A(10), A(1)) + assertEquals(A(1), r.min) + assertEquals(A(9), r.max) + + // Also test with custom ordering. + assertEquals(A(9), r.min(aIsIntegral.reverse)) + assertEquals(A(1), r.max(aIsIntegral.reverse)) + } } From 5a62aebcd5a9201cf6db92b5c76109f5efddf2a2 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 15 Oct 2016 16:15:13 +0200 Subject: [PATCH 0064/2665] Fix #2624: PropertyDefs should be configurable --- .../jsinterop/ScalaJSDefinedTest.scala | 26 +++++++++++++++++++ .../backend/emitter/ScalaJSClassEmitter.scala | 5 +++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala index e81764711c..dee9d3eb29 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala @@ -565,6 +565,32 @@ class ScalaJSDefinedTest { assertEquals(100, dyn.foo()) } + @Test def properties_are_configurable(): Unit = { + // Named classes + @ScalaJSDefined + class Foo extends js.Object { + def myProp: Int = 1 + } + + // Delete property from prototype. + val prototype = js.constructorOf[Foo].prototype + prototype.asInstanceOf[js.Dictionary[js.Any]].delete("myProp") + + // Check it is actually gone. + assertTrue(js.isUndefined((new Foo()).asInstanceOf[js.Dynamic].myProp)) + + // Anonymous classes + val y = new js.Object { + def myProp: Int = 1 + } + + // The property should be on the instance itself. + assertTrue(y.hasOwnProperty("myProp")) + y.asInstanceOf[js.Dictionary[js.Any]].delete("myProp") + assertTrue(js.isUndefined(y.asInstanceOf[js.Dynamic].myProp)) + assertFalse(y.hasOwnProperty("myProp")) + } + @Test def properties_with_explicit_name(): Unit = { @ScalaJSDefined class PropertiesWithExplicitName extends js.Object { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala index 2208c5e5b5..305ca708ee 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala @@ -381,7 +381,10 @@ private[emitter] final class ScalaJSClassEmitter( val descriptor = js.ObjectConstr( optGetter.toList ++ optSetter ++ - List(js.StringLiteral("enumerable") -> js.BooleanLiteral(true)) + List( + js.StringLiteral("configurable") -> js.BooleanLiteral(true), + js.StringLiteral("enumerable") -> js.BooleanLiteral(true) + ) ) js.Apply(defProp, proto :: name :: descriptor :: Nil) From 1f942864ddf6f6b8b0bb13b6da18649ad0f7defd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 17 Dec 2016 18:27:19 +0100 Subject: [PATCH 0065/2665] Fix #2689: Do not propagate tailPosLabels inside finally block. Inside a `finally` block, we lose the property that we are in tail position of any label. This is because the code of the `finally` block is implicitly followed by some test to re-`throw` a caught exception or further `return` a returned value. --- .../testsuite/compiler/OptimizerTest.scala | 33 +++++++++++++++++++ .../linker/backend/emitter/JSDesugaring.scala | 2 +- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala index e245fcdbd4..cf5c1541fb 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala @@ -117,6 +117,39 @@ class OptimizerTest { assertEquals("BitSet(5, 6, 7)", b0.toString) } + @Test def must_not_eliminate_break_to_label_within_finally_block_issue2689(): Unit = { + // scalastyle:off return + val logs = js.Array[String]() + + @noinline def log(s: String): Unit = + logs += s + + def a1(): Unit = log("a1") + + def i1: Int = { log("i1"); 1 } + def i2: Int = { log("i2"); 2 } + + def e1: Int = { log("e1"); throw new Exception("Boom! #2689") } + + def t4(i: => Int): Int = { + log("t4") + try { + return i + } finally { + return i2 + } + } + + assertEquals(2, t4(i1)) + assertArrayEquals(Array[AnyRef]("t4", "i1", "i2"), logs.toArray[AnyRef]) + logs.clear() + + assertEquals(2, t4(e1)) + assertArrayEquals(Array[AnyRef]("t4", "e1", "i2"), logs.toArray[AnyRef]) + logs.clear() + // scalastyle:on return + } + // +[string] constant folding @Test def must_not_break_when_folding_two_constant_strings(): Unit = { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala index aab779a6c3..46593dfab6 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala @@ -1192,7 +1192,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { case TryFinally(block, finalizer) => extractLet { newLhs => val newBlock = pushLhsInto(newLhs, block, tailPosLabels) - val newFinalizer = transformStat(finalizer, tailPosLabels) + val newFinalizer = transformStat(finalizer, Set.empty) js.TryFinally(newBlock, newFinalizer) } From a435e884b41f59f524260aae107fdb0d18fc323e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 18 Dec 2016 01:15:44 +0100 Subject: [PATCH 0066/2665] Fix #2687: Be compatible with Scala 2.13. Overrides in the scalalib are literally copied from the overrides for 2.12. `RangesTest` is slightly adapted so that tests under 2.13 use the same code path as under 2.12. --- scalalib/overrides-2.13/scala/Console.scala | 222 ++++++ .../collection/immutable/NumericRange.scala | 375 +++++++++ .../scala/collection/immutable/Range.scala | 533 +++++++++++++ .../collection/mutable/ArrayBuilder.scala | 735 ++++++++++++++++++ .../scala/collection/mutable/Buffer.scala | 51 ++ .../scala/compat/Platform.scala | 132 ++++ .../scala/concurrent/ExecutionContext.scala | 183 +++++ scalalib/overrides-2.13/scala/package.scala | 133 ++++ .../scala/reflect/ClassTag.scala | 159 ++++ .../scala/reflect/Manifest.scala | 300 +++++++ .../scala/reflect/NameTransformer.scala | 161 ++++ .../testsuite/scalalib/RangesTest.scala | 24 +- 12 files changed, 2996 insertions(+), 12 deletions(-) create mode 100644 scalalib/overrides-2.13/scala/Console.scala create mode 100644 scalalib/overrides-2.13/scala/collection/immutable/NumericRange.scala create mode 100644 scalalib/overrides-2.13/scala/collection/immutable/Range.scala create mode 100644 scalalib/overrides-2.13/scala/collection/mutable/ArrayBuilder.scala create mode 100644 scalalib/overrides-2.13/scala/collection/mutable/Buffer.scala create mode 100644 scalalib/overrides-2.13/scala/compat/Platform.scala create mode 100644 scalalib/overrides-2.13/scala/concurrent/ExecutionContext.scala create mode 100644 scalalib/overrides-2.13/scala/package.scala create mode 100644 scalalib/overrides-2.13/scala/reflect/ClassTag.scala create mode 100644 scalalib/overrides-2.13/scala/reflect/Manifest.scala create mode 100644 scalalib/overrides-2.13/scala/reflect/NameTransformer.scala diff --git a/scalalib/overrides-2.13/scala/Console.scala b/scalalib/overrides-2.13/scala/Console.scala new file mode 100644 index 0000000000..b85f8dc3d0 --- /dev/null +++ b/scalalib/overrides-2.13/scala/Console.scala @@ -0,0 +1,222 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala + +import java.io.{ BufferedReader, InputStream, InputStreamReader, OutputStream, PrintStream, Reader } +import scala.io.{ AnsiColor, StdIn } +import scala.util.DynamicVariable + +/** Implements functionality for + * printing Scala values on the terminal as well as reading specific values. + * Also defines constants for marking up text on ANSI terminals. + * + * @author Matthias Zenger + * @version 1.0, 03/09/2003 + */ +object Console extends DeprecatedConsole with AnsiColor { + private val outVar = new DynamicVariable[PrintStream](java.lang.System.out) + private val errVar = new DynamicVariable[PrintStream](java.lang.System.err) + private val inVar = new DynamicVariable[BufferedReader](null) + //new BufferedReader(new InputStreamReader(java.lang.System.in))) + + protected def setOutDirect(out: PrintStream): Unit = outVar.value = out + protected def setErrDirect(err: PrintStream): Unit = errVar.value = err + protected def setInDirect(in: BufferedReader): Unit = inVar.value = in + + /** The default output, can be overridden by `setOut` */ + def out = outVar.value + /** The default error, can be overridden by `setErr` */ + def err = errVar.value + /** The default input, can be overridden by `setIn` */ + def in = inVar.value + + /** Sets the default output stream for the duration + * of execution of one thunk. + * + * @example {{{ + * withOut(Console.err) { println("This goes to default _error_") } + * }}} + * + * @param out the new output stream. + * @param thunk the code to execute with + * the new output stream active + * @return the results of `thunk` + * @see `withOut[T](out:OutputStream)(thunk: => T)` + */ + def withOut[T](out: PrintStream)(thunk: =>T): T = + outVar.withValue(out)(thunk) + + /** Sets the default output stream for the duration + * of execution of one thunk. + * + * @param out the new output stream. + * @param thunk the code to execute with + * the new output stream active + * @return the results of `thunk` + * @see `withOut[T](out:PrintStream)(thunk: => T)` + */ + def withOut[T](out: OutputStream)(thunk: =>T): T = + withOut(new PrintStream(out))(thunk) + + /** Set the default error stream for the duration + * of execution of one thunk. + * @example {{{ + * withErr(Console.out) { println("This goes to default _out_") } + * }}} + * + * @param err the new error stream. + * @param thunk the code to execute with + * the new error stream active + * @return the results of `thunk` + * @see `withErr[T](err:OutputStream)(thunk: =>T)` + */ + def withErr[T](err: PrintStream)(thunk: =>T): T = + errVar.withValue(err)(thunk) + + /** Sets the default error stream for the duration + * of execution of one thunk. + * + * @param err the new error stream. + * @param thunk the code to execute with + * the new error stream active + * @return the results of `thunk` + * @see `withErr[T](err:PrintStream)(thunk: =>T)` + */ + def withErr[T](err: OutputStream)(thunk: =>T): T = + withErr(new PrintStream(err))(thunk) + + /** Sets the default input stream for the duration + * of execution of one thunk. + * + * @example {{{ + * val someFile:Reader = openFile("file.txt") + * withIn(someFile) { + * // Reads a line from file.txt instead of default input + * println(readLine) + * } + * }}} + * + * @param thunk the code to execute with + * the new input stream active + * + * @return the results of `thunk` + * @see `withIn[T](in:InputStream)(thunk: =>T)` + */ + def withIn[T](reader: Reader)(thunk: =>T): T = + inVar.withValue(new BufferedReader(reader))(thunk) + + /** Sets the default input stream for the duration + * of execution of one thunk. + * + * @param in the new input stream. + * @param thunk the code to execute with + * the new input stream active + * @return the results of `thunk` + * @see `withIn[T](reader:Reader)(thunk: =>T)` + */ + def withIn[T](in: InputStream)(thunk: =>T): T = + withIn(new InputStreamReader(in))(thunk) + + /** Prints an object to `out` using its `toString` method. + * + * @param obj the object to print; may be null. + */ + def print(obj: Any) { + out.print(if (null == obj) "null" else obj.toString()) + } + + /** Flushes the output stream. This function is required when partial + * output (i.e. output not terminated by a newline character) has + * to be made visible on the terminal. + */ + def flush() { out.flush() } + + /** Prints a newline character on the default output. + */ + def println() { out.println() } + + /** Prints out an object to the default output, followed by a newline character. + * + * @param x the object to print. + */ + def println(x: Any) { out.println(x) } + + /** Prints its arguments as a formatted string to the default output, + * based on a string pattern (in a fashion similar to printf in C). + * + * The interpretation of the formatting patterns is described in + * + * `java.util.Formatter`. + * + * @param text the pattern for formatting the arguments. + * @param args the arguments used to instantiating the pattern. + * @throws java.lang.IllegalArgumentException if there was a problem with the format string or arguments + */ + def printf(text: String, args: Any*) { out.print(text format (args : _*)) } +} + +private[scala] abstract class DeprecatedConsole { + self: Console.type => + + /** Internal usage only. */ + protected def setOutDirect(out: PrintStream): Unit + protected def setErrDirect(err: PrintStream): Unit + protected def setInDirect(in: BufferedReader): Unit + + @deprecated("Use the method in scala.io.StdIn", "2.11.0") def readBoolean(): Boolean = StdIn.readBoolean() + @deprecated("Use the method in scala.io.StdIn", "2.11.0") def readByte(): Byte = StdIn.readByte() + @deprecated("Use the method in scala.io.StdIn", "2.11.0") def readChar(): Char = StdIn.readChar() + @deprecated("Use the method in scala.io.StdIn", "2.11.0") def readDouble(): Double = StdIn.readDouble() + @deprecated("Use the method in scala.io.StdIn", "2.11.0") def readFloat(): Float = StdIn.readFloat() + @deprecated("Use the method in scala.io.StdIn", "2.11.0") def readInt(): Int = StdIn.readInt() + @deprecated("Use the method in scala.io.StdIn", "2.11.0") def readLine(): String = StdIn.readLine() + @deprecated("Use the method in scala.io.StdIn", "2.11.0") def readLine(text: String, args: Any*): String = StdIn.readLine(text, args: _*) + @deprecated("Use the method in scala.io.StdIn", "2.11.0") def readLong(): Long = StdIn.readLong() + @deprecated("Use the method in scala.io.StdIn", "2.11.0") def readShort(): Short = StdIn.readShort() + @deprecated("Use the method in scala.io.StdIn", "2.11.0") def readf(format: String): List[Any] = StdIn.readf(format) + @deprecated("Use the method in scala.io.StdIn", "2.11.0") def readf1(format: String): Any = StdIn.readf1(format) + @deprecated("Use the method in scala.io.StdIn", "2.11.0") def readf2(format: String): (Any, Any) = StdIn.readf2(format) + @deprecated("Use the method in scala.io.StdIn", "2.11.0") def readf3(format: String): (Any, Any, Any) = StdIn.readf3(format) + + /** Sets the default output stream. + * + * @param out the new output stream. + */ + @deprecated("Use withOut", "2.11.0") def setOut(out: PrintStream): Unit = setOutDirect(out) + + /** Sets the default output stream. + * + * @param out the new output stream. + */ + @deprecated("Use withOut", "2.11.0") def setOut(out: OutputStream): Unit = setOutDirect(new PrintStream(out)) + + /** Sets the default error stream. + * + * @param err the new error stream. + */ + @deprecated("Use withErr", "2.11.0") def setErr(err: PrintStream): Unit = setErrDirect(err) + + /** Sets the default error stream. + * + * @param err the new error stream. + */ + @deprecated("Use withErr", "2.11.0") def setErr(err: OutputStream): Unit = setErrDirect(new PrintStream(err)) + + /** Sets the default input stream. + * + * @param reader specifies the new input stream. + */ + @deprecated("Use withIn", "2.11.0") def setIn(reader: Reader): Unit = setInDirect(new BufferedReader(reader)) + + /** Sets the default input stream. + * + * @param in the new input stream. + */ + @deprecated("Use withIn", "2.11.0") def setIn(in: InputStream): Unit = setInDirect(new BufferedReader(new InputStreamReader(in))) +} diff --git a/scalalib/overrides-2.13/scala/collection/immutable/NumericRange.scala b/scalalib/overrides-2.13/scala/collection/immutable/NumericRange.scala new file mode 100644 index 0000000000..65e703829c --- /dev/null +++ b/scalalib/overrides-2.13/scala/collection/immutable/NumericRange.scala @@ -0,0 +1,375 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2006-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala +package collection +package immutable + +// TODO: Now the specialization exists there is no clear reason to have +// separate classes for Range/NumericRange. Investigate and consolidate. + +/** `NumericRange` is a more generic version of the + * `Range` class which works with arbitrary types. + * It must be supplied with an `Integral` implementation of the + * range type. + * + * Factories for likely types include `Range.BigInt`, `Range.Long`, + * and `Range.BigDecimal`. `Range.Int` exists for completeness, but + * the `Int`-based `scala.Range` should be more performant. + * + * {{{ + * val r1 = new Range(0, 100, 1) + * val veryBig = Int.MaxValue.toLong + 1 + * val r2 = Range.Long(veryBig, veryBig + 100, 1) + * assert(r1 sameElements r2.map(_ - veryBig)) + * }}} + * + * @author Paul Phillips + * @version 2.8 + * @define Coll `NumericRange` + * @define coll numeric range + * @define mayNotTerminateInf + * @define willNotTerminateInf + */ +abstract class NumericRange[T] + (val start: T, val end: T, val step: T, val isInclusive: Boolean) + (implicit num: Integral[T]) +extends AbstractSeq[T] with IndexedSeq[T] with Serializable { + /** Note that NumericRange must be invariant so that constructs + * such as "1L to 10 by 5" do not infer the range type as AnyVal. + */ + import num._ + + // See comment in Range for why this must be lazy. + private lazy val numRangeElements: Int = + NumericRange.count(start, end, step, isInclusive) + + override def length = numRangeElements + override def isEmpty = length == 0 + override lazy val last: T = + if (length == 0) Nil.last + else locationAfterN(length - 1) + + /** Create a new range with the start and end values of this range and + * a new `step`. + */ + def by(newStep: T): NumericRange[T] = copy(start, end, newStep) + + /** Create a copy of this range. + */ + def copy(start: T, end: T, step: T): NumericRange[T] + + override def foreach[U](f: T => U) { + var count = 0 + var current = start + while (count < length) { + f(current) + current += step + count += 1 + } + } + + // TODO: these private methods are straight copies from Range, duplicated + // to guard against any (most likely illusory) performance drop. They should + // be eliminated one way or another. + + // Tests whether a number is within the endpoints, without testing + // whether it is a member of the sequence (i.e. when step > 1.) + private def isWithinBoundaries(elem: T) = !isEmpty && ( + (step > zero && start <= elem && elem <= last ) || + (step < zero && last <= elem && elem <= start) + ) + // Methods like apply throw exceptions on invalid n, but methods like take/drop + // are forgiving: therefore the checks are with the methods. + private def locationAfterN(n: Int): T = start + (step * fromInt(n)) + + // When one drops everything. Can't ever have unchecked operations + // like "end + 1" or "end - 1" because ranges involving Int.{ MinValue, MaxValue } + // will overflow. This creates an exclusive range where start == end + // based on the given value. + private def newEmptyRange(value: T) = NumericRange(value, value, step) + + final override def take(n: Int): NumericRange[T] = ( + if (n <= 0 || length == 0) newEmptyRange(start) + else if (n >= length) this + else new NumericRange.Inclusive(start, locationAfterN(n - 1), step) + ) + + final override def drop(n: Int): NumericRange[T] = ( + if (n <= 0 || length == 0) this + else if (n >= length) newEmptyRange(end) + else copy(locationAfterN(n), end, step) + ) + + def apply(idx: Int): T = { + if (idx < 0 || idx >= length) throw new IndexOutOfBoundsException(idx.toString) + else locationAfterN(idx) + } + + import NumericRange.defaultOrdering + + override def min[T1 >: T](implicit ord: Ordering[T1]): T = + // We can take the fast path: + // - If the Integral of this NumericRange is also the requested Ordering + // (Integral <: Ordering). This can happen for custom Integral types. + // - The Ordering is the default Ordering of a well-known Integral type. + if ((ord eq num) || defaultOrdering.get(num).exists(ord eq _)) { + if (num.signum(step) > 0) start + else last + } else super.min(ord) + + override def max[T1 >: T](implicit ord: Ordering[T1]): T = + // See comment for fast path in min(). + if ((ord eq num) || defaultOrdering.get(num).exists(ord eq _)) { + if (num.signum(step) > 0) last + else start + } else super.max(ord) + + // Motivated by the desire for Double ranges with BigDecimal precision, + // we need some way to map a Range and get another Range. This can't be + // done in any fully general way because Ranges are not arbitrary + // sequences but step-valued, so we have a custom method only we can call + // which we promise to use responsibly. + // + // The point of it all is that + // + // 0.0 to 1.0 by 0.1 + // + // should result in + // + // NumericRange[Double](0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0) + // + // and not + // + // NumericRange[Double](0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9) + // + // or perhaps more importantly, + // + // (0.1 to 0.3 by 0.1 contains 0.3) == true + // + private[immutable] def mapRange[A](fm: T => A)(implicit unum: Integral[A]): NumericRange[A] = { + val self = this + + // XXX This may be incomplete. + new NumericRange[A](fm(start), fm(end), fm(step), isInclusive) { + def copy(start: A, end: A, step: A): NumericRange[A] = + if (isInclusive) NumericRange.inclusive(start, end, step) + else NumericRange(start, end, step) + + private lazy val underlyingRange: NumericRange[T] = self + override def foreach[U](f: A => U) { underlyingRange foreach (x => f(fm(x))) } + override def isEmpty = underlyingRange.isEmpty + override def apply(idx: Int): A = fm(underlyingRange(idx)) + override def containsTyped(el: A) = underlyingRange exists (x => fm(x) == el) + + override def toString = { + def simpleOf(x: Any): String = x.getClass.getName.split("\\.").last + val stepped = simpleOf(underlyingRange.step) + s"${super.toString} (using $underlyingRange of $stepped)" + } + } + } + + // a well-typed contains method. + def containsTyped(x: T): Boolean = + isWithinBoundaries(x) && (((x - start) % step) == zero) + + override def contains[A1 >: T](x: A1): Boolean = + try containsTyped(x.asInstanceOf[T]) + catch { case _: ClassCastException => false } + + final override def sum[B >: T](implicit num: Numeric[B]): B = { + if (isEmpty) num.zero + else if (numRangeElements == 1) head + else { + // If there is no overflow, use arithmetic series formula + // a + ... (n terms total) ... + b = n*(a+b)/2 + if ((num eq scala.math.Numeric.IntIsIntegral)|| + (num eq scala.math.Numeric.ShortIsIntegral)|| + (num eq scala.math.Numeric.ByteIsIntegral)|| + (num eq scala.math.Numeric.CharIsIntegral)) { + // We can do math with no overflow in a Long--easy + val exact = (numRangeElements * ((num toLong head) + (num toInt last))) / 2 + num fromInt exact.toInt + } + else if (num eq scala.math.Numeric.LongIsIntegral) { + // Uh-oh, might be overflow, so we have to divide before we overflow. + // Either numRangeElements or (head + last) must be even, so divide the even one before multiplying + val a = head.toLong + val b = last.toLong + val ans = + if ((numRangeElements & 1) == 0) (numRangeElements / 2) * (a + b) + else numRangeElements * { + // Sum is even, but we might overflow it, so divide in pieces and add back remainder + val ha = a/2 + val hb = b/2 + ha + hb + ((a - 2*ha) + (b - 2*hb)) / 2 + } + ans.asInstanceOf[B] + } + else { + // User provided custom Numeric, so we cannot rely on arithmetic series formula (e.g. won't work on something like Z_6) + if (isEmpty) num.zero + else { + var acc = num.zero + var i = head + var idx = 0 + while(idx < length) { + acc = num.plus(acc, i) + i = i + step + idx = idx + 1 + } + acc + } + } + } + } + + override lazy val hashCode = super.hashCode() + override def equals(other: Any) = other match { + case x: NumericRange[_] => + (x canEqual this) && (length == x.length) && ( + (length == 0) || // all empty sequences are equal + (start == x.start && last == x.last) // same length and same endpoints implies equality + ) + case _ => + super.equals(other) + } + + override def toString = { + val empty = if (isEmpty) "empty " else "" + val preposition = if (isInclusive) "to" else "until" + val stepped = if (step == 1) "" else s" by $step" + s"${empty}NumericRange $start $preposition $end$stepped" + } +} + +/** A companion object for numeric ranges. + */ +object NumericRange { + + /** Calculates the number of elements in a range given start, end, step, and + * whether or not it is inclusive. Throws an exception if step == 0 or + * the number of elements exceeds the maximum Int. + */ + def count[T](start: T, end: T, step: T, isInclusive: Boolean)(implicit num: Integral[T]): Int = { + val zero = num.zero + val upward = num.lt(start, end) + val posStep = num.gt(step, zero) + + if (step == zero) throw new IllegalArgumentException("step cannot be 0.") + else if (start == end) if (isInclusive) 1 else 0 + else if (upward != posStep) 0 + else { + /* We have to be frightfully paranoid about running out of range. + * We also can't assume that the numbers will fit in a Long. + * We will assume that if a > 0, -a can be represented, and if + * a < 0, -a+1 can be represented. We also assume that if we + * can't fit in Int, we can represent 2*Int.MaxValue+3 (at least). + * And we assume that numbers wrap rather than cap when they overflow. + */ + // Check whether we can short-circuit by deferring to Int range. + val startint = num.toInt(start) + if (start == num.fromInt(startint)) { + val endint = num.toInt(end) + if (end == num.fromInt(endint)) { + val stepint = num.toInt(step) + if (step == num.fromInt(stepint)) { + return { + if (isInclusive) Range.inclusive(startint, endint, stepint).length + else Range (startint, endint, stepint).length + } + } + } + } + // If we reach this point, deferring to Int failed. + // Numbers may be big. + val one = num.one + val limit = num.fromInt(Int.MaxValue) + def check(t: T): T = + if (num.gt(t, limit)) throw new IllegalArgumentException("More than Int.MaxValue elements.") + else t + // If the range crosses zero, it might overflow when subtracted + val startside = num.signum(start) + val endside = num.signum(end) + num.toInt{ + if (startside*endside >= 0) { + // We're sure we can subtract these numbers. + // Note that we do not use .rem because of different conventions for Long and BigInt + val diff = num.minus(end, start) + val quotient = check(num.quot(diff, step)) + val remainder = num.minus(diff, num.times(quotient, step)) + if (!isInclusive && zero == remainder) quotient else check(num.plus(quotient, one)) + } + else { + // We might not even be able to subtract these numbers. + // Jump in three pieces: + // * start to -1 or 1, whichever is closer (waypointA) + // * one step, which will take us at least to 0 (ends at waypointB) + // * there to the end + val negone = num.fromInt(-1) + val startlim = if (posStep) negone else one + val startdiff = num.minus(startlim, start) + val startq = check(num.quot(startdiff, step)) + val waypointA = if (startq == zero) start else num.plus(start, num.times(startq, step)) + val waypointB = num.plus(waypointA, step) + check { + if (num.lt(waypointB, end) != upward) { + // No last piece + if (isInclusive && waypointB == end) num.plus(startq, num.fromInt(2)) + else num.plus(startq, one) + } + else { + // There is a last piece + val enddiff = num.minus(end,waypointB) + val endq = check(num.quot(enddiff, step)) + val last = if (endq == zero) waypointB else num.plus(waypointB, num.times(endq, step)) + // Now we have to tally up all the pieces + // 1 for the initial value + // startq steps to waypointA + // 1 step to waypointB + // endq steps to the end (one less if !isInclusive and last==end) + num.plus(startq, num.plus(endq, if (!isInclusive && last==end) one else num.fromInt(2))) + } + } + } + } + } + } + + class Inclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]) + extends NumericRange(start, end, step, true) { + def copy(start: T, end: T, step: T): Inclusive[T] = + NumericRange.inclusive(start, end, step) + + def exclusive: Exclusive[T] = NumericRange(start, end, step) + } + + class Exclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]) + extends NumericRange(start, end, step, false) { + def copy(start: T, end: T, step: T): Exclusive[T] = + NumericRange(start, end, step) + + def inclusive: Inclusive[T] = NumericRange.inclusive(start, end, step) + } + + def apply[T](start: T, end: T, step: T)(implicit num: Integral[T]): Exclusive[T] = + new Exclusive(start, end, step) + def inclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]): Inclusive[T] = + new Inclusive(start, end, step) + + private[collection] val defaultOrdering = Map[Numeric[_], Ordering[_]]( + Numeric.IntIsIntegral -> Ordering.Int, + Numeric.ShortIsIntegral -> Ordering.Short, + Numeric.ByteIsIntegral -> Ordering.Byte, + Numeric.CharIsIntegral -> Ordering.Char, + Numeric.LongIsIntegral -> Ordering.Long + ) + +} + diff --git a/scalalib/overrides-2.13/scala/collection/immutable/Range.scala b/scalalib/overrides-2.13/scala/collection/immutable/Range.scala new file mode 100644 index 0000000000..e5f4287a76 --- /dev/null +++ b/scalalib/overrides-2.13/scala/collection/immutable/Range.scala @@ -0,0 +1,533 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2006-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + + +package scala +package collection.immutable + +import scala.collection.parallel.immutable.ParRange + +/** The `Range` class represents integer values in range + * ''[start;end)'' with non-zero step value `step`. + * It's a special case of an indexed sequence. + * For example: + * + * {{{ + * val r1 = 0 until 10 + * val r2 = r1.start until r1.end by r1.step + 1 + * println(r2.length) // = 5 + * }}} + * + * Ranges that contain more than `Int.MaxValue` elements can be created, but + * these overfull ranges have only limited capabilities. Any method that + * could require a collection of over `Int.MaxValue` length to be created, or + * could be asked to index beyond `Int.MaxValue` elements will throw an + * exception. Overfull ranges can safely be reduced in size by changing + * the step size (e.g. `by 3`) or taking/dropping elements. `contains`, + * `equals`, and access to the ends of the range (`head`, `last`, `tail`, + * `init`) are also permitted on overfull ranges. + * + * @param start the start of this range. + * @param end the end of the range. For exclusive ranges, e.g. + * `Range(0,3)` or `(0 until 3)`, this is one + * step past the last one in the range. For inclusive + * ranges, e.g. `Range.inclusive(0,3)` or `(0 to 3)`, + * it may be in the range if it is not skipped by the step size. + * To find the last element inside a non-empty range, + use `last` instead. + * @param step the step for the range. + * + * @author Martin Odersky + * @author Paul Phillips + * @version 2.8 + * @since 2.5 + * @see [[http://docs.scala-lang.org/overviews/collections/concrete-immutable-collection-classes.html#ranges "Scala's Collection Library overview"]] + * section on `Ranges` for more information. + * + * @define coll range + * @define mayNotTerminateInf + * @define willNotTerminateInf + * @define doesNotUseBuilders + * '''Note:''' this method does not use builders to construct a new range, + * and its complexity is O(1). + */ +@SerialVersionUID(7618862778670199309L) +@inline +@deprecatedInheritance("The implementation details of Range makes inheriting from it unwise.", "2.11.0") +class Range(val start: Int, val end: Int, val step: Int) +extends scala.collection.AbstractSeq[Int] + with IndexedSeq[Int] + with scala.collection.CustomParallelizable[Int, ParRange] + with Serializable +{ + override def par = new ParRange(this) + + private def gap = end.toLong - start.toLong + private def isExact = gap % step == 0 + private def hasStub = isInclusive || !isExact + private def longLength = gap / step + ( if (hasStub) 1 else 0 ) + + // Check cannot be evaluated eagerly because we have a pattern where + // ranges are constructed like: "x to y by z" The "x to y" piece + // should not trigger an exception. So the calculation is delayed, + // which means it will not fail fast for those cases where failing was + // correct. + override final val isEmpty = ( + (start > end && step > 0) + || (start < end && step < 0) + || (start == end && !isInclusive) + ) + + private val numRangeElements: Int = { + if (step == 0) throw new IllegalArgumentException("step cannot be 0.") + else if (isEmpty) 0 + else { + val len = longLength + if (len > scala.Int.MaxValue) -1 + else len.toInt + } + } + + // This field has a sensible value only for non-empty ranges + private val lastElement = step match { + case 1 => if (isInclusive) end else end-1 + case -1 => if (isInclusive) end else end+1 + case _ => + val remainder = (gap % step).toInt + if (remainder != 0) end - remainder + else if (isInclusive) end + else end - step + } + + /** The last element of this range. This method will return the correct value + * even if there are too many elements to iterate over. + */ + override def last = if (isEmpty) Nil.last else lastElement + override def head = if (isEmpty) Nil.head else start + + override def min[A1 >: Int](implicit ord: Ordering[A1]): Int = + if (ord eq Ordering.Int) { + if (step > 0) head + else last + } else super.min(ord) + + override def max[A1 >: Int](implicit ord: Ordering[A1]): Int = + if (ord eq Ordering.Int) { + if (step > 0) last + else head + } else super.max(ord) + + protected def copy(start: Int, end: Int, step: Int): Range = new Range(start, end, step) + + /** Create a new range with the `start` and `end` values of this range and + * a new `step`. + * + * @return a new range with a different step + */ + def by(step: Int): Range = copy(start, end, step) + + def isInclusive = false + + override def size = length + override def length = if (numRangeElements < 0) fail() else numRangeElements + + private def fail() = Range.fail(start, end, step, isInclusive) + private def validateMaxLength() { + if (numRangeElements < 0) + fail() + } + + final def apply(idx: Int): Int = { + validateMaxLength() + if (idx < 0 || idx >= numRangeElements) throw new IndexOutOfBoundsException(idx.toString) + else start + (step * idx) + } + + @inline final override def foreach[@specialized(Unit) U](f: Int => U) { + // Implementation chosen on the basis of favorable microbenchmarks + // Note--initialization catches step == 0 so we don't need to here + if (!isEmpty) { + var i = start + while (true) { + f(i) + if (i == lastElement) return + i += step + } + } + } + + /** Creates a new range containing the first `n` elements of this range. + * + * $doesNotUseBuilders + * + * @param n the number of elements to take. + * @return a new range consisting of `n` first elements. + */ + final override def take(n: Int): Range = ( + if (n <= 0 || isEmpty) newEmptyRange(start) + else if (n >= numRangeElements && numRangeElements >= 0) this + else { + // May have more than Int.MaxValue elements in range (numRangeElements < 0) + // but the logic is the same either way: take the first n + new Range.Inclusive(start, locationAfterN(n - 1), step) + } + ) + + /** Creates a new range containing all the elements of this range except the first `n` elements. + * + * $doesNotUseBuilders + * + * @param n the number of elements to drop. + * @return a new range consisting of all the elements of this range except `n` first elements. + */ + final override def drop(n: Int): Range = ( + if (n <= 0 || isEmpty) this + else if (n >= numRangeElements && numRangeElements >= 0) newEmptyRange(end) + else { + // May have more than Int.MaxValue elements (numRangeElements < 0) + // but the logic is the same either way: go forwards n steps, keep the rest + copy(locationAfterN(n), end, step) + } + ) + + /** Creates a new range containing the elements starting at `from` up to but not including `until`. + * + * $doesNotUseBuilders + * + * @param from the element at which to start + * @param until the element at which to end (not included in the range) + * @return a new range consisting of a contiguous interval of values in the old range + */ + override def slice(from: Int, until: Int): Range = + if (from <= 0) take(until) + else if (until >= numRangeElements && numRangeElements >= 0) drop(from) + else { + val fromValue = locationAfterN(from) + if (from >= until) newEmptyRange(fromValue) + else new Range.Inclusive(fromValue, locationAfterN(until-1), step) + } + + /** Creates a new range containing all the elements of this range except the last one. + * + * $doesNotUseBuilders + * + * @return a new range consisting of all the elements of this range except the last one. + */ + final override def init: Range = { + if (isEmpty) + Nil.init + + dropRight(1) + } + + /** Creates a new range containing all the elements of this range except the first one. + * + * $doesNotUseBuilders + * + * @return a new range consisting of all the elements of this range except the first one. + */ + final override def tail: Range = { + if (isEmpty) + Nil.tail + + drop(1) + } + + // Advance from the start while we meet the given test + private def argTakeWhile(p: Int => Boolean): Long = { + if (isEmpty) start + else { + var current = start + val stop = last + while (current != stop && p(current)) current += step + if (current != stop || !p(current)) current + else current.toLong + step + } + } + // Methods like apply throw exceptions on invalid n, but methods like take/drop + // are forgiving: therefore the checks are with the methods. + private def locationAfterN(n: Int) = start + (step * n) + + // When one drops everything. Can't ever have unchecked operations + // like "end + 1" or "end - 1" because ranges involving Int.{ MinValue, MaxValue } + // will overflow. This creates an exclusive range where start == end + // based on the given value. + private def newEmptyRange(value: Int) = new Range(value, value, step) + + final override def takeWhile(p: Int => Boolean): Range = { + val stop = argTakeWhile(p) + if (stop==start) newEmptyRange(start) + else { + val x = (stop - step).toInt + if (x == last) this + else new Range.Inclusive(start, x, step) + } + } + final override def dropWhile(p: Int => Boolean): Range = { + val stop = argTakeWhile(p) + if (stop == start) this + else { + val x = (stop - step).toInt + if (x == last) newEmptyRange(last) + else new Range.Inclusive(x + step, last, step) + } + } + final override def span(p: Int => Boolean): (Range, Range) = { + val border = argTakeWhile(p) + if (border == start) (newEmptyRange(start), this) + else { + val x = (border - step).toInt + if (x == last) (this, newEmptyRange(last)) + else (new Range.Inclusive(start, x, step), new Range.Inclusive(x+step, last, step)) + } + } + + /** Creates a pair of new ranges, first consisting of elements before `n`, and the second + * of elements after `n`. + * + * $doesNotUseBuilders + */ + final override def splitAt(n: Int) = (take(n), drop(n)) + + /** Creates a new range consisting of the last `n` elements of the range. + * + * $doesNotUseBuilders + */ + final override def takeRight(n: Int): Range = { + if (n <= 0) newEmptyRange(start) + else if (numRangeElements >= 0) drop(numRangeElements - n) + else { + // Need to handle over-full range separately + val y = last + val x = y - step.toLong*(n-1) + if ((step > 0 && x < start) || (step < 0 && x > start)) this + else new Range.Inclusive(x.toInt, y, step) + } + } + + /** Creates a new range consisting of the initial `length - n` elements of the range. + * + * $doesNotUseBuilders + */ + final override def dropRight(n: Int): Range = { + if (n <= 0) this + else if (numRangeElements >= 0) take(numRangeElements - n) + else { + // Need to handle over-full range separately + val y = last - step.toInt*n + if ((step > 0 && y < start) || (step < 0 && y > start)) newEmptyRange(start) + else new Range.Inclusive(start, y.toInt, step) + } + } + + /** Returns the reverse of this range. + * + * $doesNotUseBuilders + */ + final override def reverse: Range = + if (isEmpty) this + else new Range.Inclusive(last, start, -step) + + /** Make range inclusive. + */ + def inclusive = + if (isInclusive) this + else new Range.Inclusive(start, end, step) + + final def contains(x: Int) = { + if (x==end && !isInclusive) false + else if (step > 0) { + if (x < start || x > end) false + else (step == 1) || (((x - start) % step) == 0) + } + else { + if (x < end || x > start) false + else (step == -1) || (((x - start) % step) == 0) + } + } + + final override def sum[B >: Int](implicit num: Numeric[B]): Int = { + if (num eq scala.math.Numeric.IntIsIntegral) { + // this is normal integer range with usual addition. arithmetic series formula can be used + if (isEmpty) 0 + else if (numRangeElements == 1) head + else ((numRangeElements * (head.toLong + last)) / 2).toInt + } else { + // user provided custom Numeric, we cannot rely on arithmetic series formula + if (isEmpty) num.toInt(num.zero) + else { + var acc = num.zero + var i = head + while (true) { + acc = num.plus(acc, i) + if (i == lastElement) return num.toInt(acc) + i = i + step + } + 0 // Never hit this--just to satisfy compiler since it doesn't know while(true) has type Nothing + } + } + } + + override def toIterable = this + + override def toSeq = this + + override def equals(other: Any) = other match { + case x: Range => + // Note: this must succeed for overfull ranges (length > Int.MaxValue) + (x canEqual this) && { + if (isEmpty) x.isEmpty // empty sequences are equal + else // this is non-empty... + x.nonEmpty && start == x.start && { // ...so other must contain something and have same start + val l0 = last + (l0 == x.last && ( // And same end + start == l0 || step == x.step // And either the same step, or not take any steps + )) + } + } + case _ => + super.equals(other) + } + + /* Note: hashCode can't be overridden without breaking Seq's equals contract. */ + + override def toString = { + val preposition = if (isInclusive) "to" else "until" + val stepped = if (step == 1) "" else s" by $step" + val prefix = if (isEmpty) "empty " else if (!isExact) "inexact " else "" + s"${prefix}Range $start $preposition $end$stepped" + } +} + +/** A companion object for the `Range` class. + */ +object Range { + private[immutable] val MAX_PRINT = 512 // some arbitrary value + + private def description(start: Int, end: Int, step: Int, isInclusive: Boolean) = + start + (if (isInclusive) " to " else " until ") + end + " by " + step + + private def fail(start: Int, end: Int, step: Int, isInclusive: Boolean) = + throw new IllegalArgumentException(description(start, end, step, isInclusive) + + ": seqs cannot contain more than Int.MaxValue elements.") + + /** Counts the number of range elements. + * @pre step != 0 + * If the size of the range exceeds Int.MaxValue, the + * result will be negative. + */ + def count(start: Int, end: Int, step: Int, isInclusive: Boolean): Int = { + if (step == 0) + throw new IllegalArgumentException("step cannot be 0.") + + val isEmpty = ( + if (start == end) !isInclusive + else if (start < end) step < 0 + else step > 0 + ) + if (isEmpty) 0 + else { + // Counts with Longs so we can recognize too-large ranges. + val gap: Long = end.toLong - start.toLong + val jumps: Long = gap / step + // Whether the size of this range is one larger than the + // number of full-sized jumps. + val hasStub = isInclusive || (gap % step != 0) + val result: Long = jumps + ( if (hasStub) 1 else 0 ) + + if (result > scala.Int.MaxValue) -1 + else result.toInt + } + } + def count(start: Int, end: Int, step: Int): Int = + count(start, end, step, isInclusive = false) + + @inline + class Inclusive(start: Int, end: Int, step: Int) extends Range(start, end, step) { +// override def par = new ParRange(this) + override def isInclusive = true + override protected def copy(start: Int, end: Int, step: Int): Range = new Inclusive(start, end, step) + } + + /** Make a range from `start` until `end` (exclusive) with given step value. + * @note step != 0 + */ + def apply(start: Int, end: Int, step: Int): Range = new Range(start, end, step) + + /** Make a range from `start` until `end` (exclusive) with step value 1. + */ + def apply(start: Int, end: Int): Range = new Range(start, end, 1) + + /** Make an inclusive range from `start` to `end` with given step value. + * @note step != 0 + */ + def inclusive(start: Int, end: Int, step: Int): Range.Inclusive = new Inclusive(start, end, step) + + /** Make an inclusive range from `start` to `end` with step value 1. + */ + def inclusive(start: Int, end: Int): Range.Inclusive = new Inclusive(start, end, 1) + + // BigInt and Long are straightforward generic ranges. + object BigInt { + def apply(start: BigInt, end: BigInt, step: BigInt) = NumericRange(start, end, step) + def inclusive(start: BigInt, end: BigInt, step: BigInt) = NumericRange.inclusive(start, end, step) + } + + object Long { + def apply(start: Long, end: Long, step: Long) = NumericRange(start, end, step) + def inclusive(start: Long, end: Long, step: Long) = NumericRange.inclusive(start, end, step) + } + + // BigDecimal uses an alternative implementation of Numeric in which + // it pretends to be Integral[T] instead of Fractional[T]. See Numeric for + // details. The intention is for it to throw an exception anytime + // imprecision or surprises might result from anything, although this may + // not yet be fully implemented. + object BigDecimal { + implicit val bigDecAsIntegral = scala.math.Numeric.BigDecimalAsIfIntegral + + def apply(start: BigDecimal, end: BigDecimal, step: BigDecimal) = + NumericRange(start, end, step) + def inclusive(start: BigDecimal, end: BigDecimal, step: BigDecimal) = + NumericRange.inclusive(start, end, step) + } + + // Double works by using a BigDecimal under the hood for precise + // stepping, but mapping the sequence values back to doubles with + // .doubleValue. This constructs the BigDecimals by way of the + // String constructor (valueOf) instead of the Double one, which + // is necessary to keep 0.3d at 0.3 as opposed to + // 0.299999999999999988897769753748434595763683319091796875 or so. + object Double { + implicit val bigDecAsIntegral = scala.math.Numeric.BigDecimalAsIfIntegral + implicit val doubleAsIntegral = scala.math.Numeric.DoubleAsIfIntegral + def toBD(x: Double): BigDecimal = scala.math.BigDecimal valueOf x + + def apply(start: Double, end: Double, step: Double) = + BigDecimal(toBD(start), toBD(end), toBD(step)) mapRange (_.doubleValue) + + def inclusive(start: Double, end: Double, step: Double) = + BigDecimal.inclusive(toBD(start), toBD(end), toBD(step)) mapRange (_.doubleValue) + } + + // As there is no appealing default step size for not-really-integral ranges, + // we offer a partially constructed object. + class Partial[T, U](private val f: T => U) extends AnyVal { + def by(x: T): U = f(x) + override def toString = "Range requires step" + } + + // Illustrating genericity with Int Range, which should have the same behavior + // as the original Range class. However we leave the original Range + // indefinitely, for performance and because the compiler seems to bootstrap + // off it and won't do so with our parameterized version without modifications. + object Int { + def apply(start: Int, end: Int, step: Int) = NumericRange(start, end, step) + def inclusive(start: Int, end: Int, step: Int) = NumericRange.inclusive(start, end, step) + } +} diff --git a/scalalib/overrides-2.13/scala/collection/mutable/ArrayBuilder.scala b/scalalib/overrides-2.13/scala/collection/mutable/ArrayBuilder.scala new file mode 100644 index 0000000000..ce3a7d5a03 --- /dev/null +++ b/scalalib/overrides-2.13/scala/collection/mutable/ArrayBuilder.scala @@ -0,0 +1,735 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala +package collection +package mutable + +import scala.reflect.ClassTag +import scala.runtime.BoxedUnit + +import scala.scalajs.js + +/** A builder class for arrays. + * + * @since 2.8 + * + * @tparam T the type of the elements for the builder. + */ +abstract class ArrayBuilder[T] extends ReusableBuilder[T, Array[T]] with Serializable + +/** A companion object for array builders. + * + * @since 2.8 + */ +object ArrayBuilder { + + /** Creates a new arraybuilder of type `T`. + * + * @tparam T type of the elements for the array builder, with a `ClassTag` context bound. + * @return a new empty array builder. + */ + @inline + def make[T: ClassTag](): ArrayBuilder[T] = + new ArrayBuilder.generic[T](implicitly[ClassTag[T]].runtimeClass) + + /** A generic ArrayBuilder optimized for Scala.js. + * + * @tparam T type of elements for the array builder. + * @param elementClass runtime class of the elements in the array. + */ + @inline + private final class generic[T](elementClass: Class[_]) extends ArrayBuilder[T] { + + private val isCharArrayBuilder = classOf[Char] == elementClass + private var elems: js.Array[Any] = js.Array() + + def +=(elem: T): this.type = { + val unboxedElem = + if (isCharArrayBuilder) elem.asInstanceOf[Char].toInt + else if (elem == null) zeroOf(elementClass) + else elem + elems.push(unboxedElem) + this + } + + def clear(): Unit = + elems = js.Array() + + def result(): Array[T] = { + val elemRuntimeClass = + if (classOf[Unit] == elementClass) classOf[BoxedUnit] + else if (classOf[Null] == elementClass || classOf[Nothing] == elementClass) classOf[Object] + else elementClass + genericArrayBuilderResult(elemRuntimeClass, elems) + } + + override def toString(): String = "ArrayBuilder.generic" + } + + // Intrinsic + private def zeroOf(runtimeClass: Class[_]): Any = runtimeClass match { + case java.lang.Byte.TYPE => 0.toByte + case java.lang.Short.TYPE => 0.toShort + case java.lang.Character.TYPE => 0 // yes, as an Int + case java.lang.Integer.TYPE => 0 + case java.lang.Long.TYPE => 0L + case java.lang.Float.TYPE => 0.0f + case java.lang.Double.TYPE => 0.0 + case java.lang.Boolean.TYPE => false + case java.lang.Void.TYPE => () + case _ => null + } + + // Intrinsic + private def genericArrayBuilderResult[T](runtimeClass: Class[_], + a: js.Array[Any]): Array[T] = { + val len = a.length + + if (classOf[Char] == runtimeClass) { + val result = new Array[Char](len) + var i = 0 + while (i != len) { + result(i) = a(i).asInstanceOf[Int].toChar + i += 1 + } + result.asInstanceOf[Array[T]] + } else { + val result: Array[T] = java.lang.reflect.Array.newInstance( + runtimeClass, len).asInstanceOf[Array[T]] + var i = 0 + while (i != len) { + result(i) = a(i).asInstanceOf[T] + i += 1 + } + result + } + } + + /** A class for array builders for arrays of reference types. + * + * This builder can be reused. + * + * @tparam T type of elements for the array builder, subtype of `AnyRef` with a `ClassTag` context bound. + */ + final class ofRef[T <: AnyRef : ClassTag] extends ArrayBuilder[T] { + + private var elems: Array[T] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[T] = { + val newelems = new Array[T](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: T): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[T]): this.type = (xs.asInstanceOf[AnyRef]) match { + case xs: WrappedArray.ofRef[_] => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { size = 0 } + + def result() = { + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofRef[_] => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofRef" + } + + /** A class for array builders for arrays of `byte`s. It can be reused. */ + final class ofByte extends ArrayBuilder[Byte] { + + private var elems: Array[Byte] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[Byte] = { + val newelems = new Array[Byte](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Byte): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Byte]): this.type = xs match { + case xs: WrappedArray.ofByte => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { size = 0 } + + def result() = { + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofByte => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofByte" + } + + /** A class for array builders for arrays of `short`s. It can be reused. */ + final class ofShort extends ArrayBuilder[Short] { + + private var elems: Array[Short] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[Short] = { + val newelems = new Array[Short](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Short): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Short]): this.type = xs match { + case xs: WrappedArray.ofShort => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { size = 0 } + + def result() = { + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofShort => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofShort" + } + + /** A class for array builders for arrays of `char`s. It can be reused. */ + final class ofChar extends ArrayBuilder[Char] { + + private var elems: Array[Char] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[Char] = { + val newelems = new Array[Char](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Char): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Char]): this.type = xs match { + case xs: WrappedArray.ofChar => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { size = 0 } + + def result() = { + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofChar => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofChar" + } + + /** A class for array builders for arrays of `int`s. It can be reused. */ + final class ofInt extends ArrayBuilder[Int] { + + private var elems: Array[Int] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[Int] = { + val newelems = new Array[Int](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Int): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Int]): this.type = xs match { + case xs: WrappedArray.ofInt => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { size = 0 } + + def result() = { + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofInt => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofInt" + } + + /** A class for array builders for arrays of `long`s. It can be reused. */ + final class ofLong extends ArrayBuilder[Long] { + + private var elems: Array[Long] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[Long] = { + val newelems = new Array[Long](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Long): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Long]): this.type = xs match { + case xs: WrappedArray.ofLong => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { size = 0 } + + def result() = { + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofLong => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofLong" + } + + /** A class for array builders for arrays of `float`s. It can be reused. */ + final class ofFloat extends ArrayBuilder[Float] { + + private var elems: Array[Float] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[Float] = { + val newelems = new Array[Float](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Float): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Float]): this.type = xs match { + case xs: WrappedArray.ofFloat => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { size = 0 } + + def result() = { + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofFloat => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofFloat" + } + + /** A class for array builders for arrays of `double`s. It can be reused. */ + final class ofDouble extends ArrayBuilder[Double] { + + private var elems: Array[Double] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[Double] = { + val newelems = new Array[Double](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Double): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Double]): this.type = xs match { + case xs: WrappedArray.ofDouble => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { size = 0 } + + def result() = { + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofDouble => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofDouble" + } + + /** A class for array builders for arrays of `boolean`s. It can be reused. */ + class ofBoolean extends ArrayBuilder[Boolean] { + + private var elems: Array[Boolean] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[Boolean] = { + val newelems = new Array[Boolean](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Boolean): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Boolean]): this.type = xs match { + case xs: WrappedArray.ofBoolean => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { size = 0 } + + def result() = { + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofBoolean => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofBoolean" + } + + /** A class for array builders for arrays of `Unit` type. It can be reused. */ + final class ofUnit extends ArrayBuilder[Unit] { + + private var size: Int = 0 + + def +=(elem: Unit): this.type = { + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Unit]): this.type = { + size += xs.size + this + } + + def clear() { size = 0 } + + def result() = { + val ans = new Array[Unit](size) + var i = 0 + while (i < size) { ans(i) = (); i += 1 } + ans + } + + override def equals(other: Any): Boolean = other match { + case x: ofUnit => (size == x.size) + case _ => false + } + + override def toString = "ArrayBuilder.ofUnit" + } +} diff --git a/scalalib/overrides-2.13/scala/collection/mutable/Buffer.scala b/scalalib/overrides-2.13/scala/collection/mutable/Buffer.scala new file mode 100644 index 0000000000..2171cb9dea --- /dev/null +++ b/scalalib/overrides-2.13/scala/collection/mutable/Buffer.scala @@ -0,0 +1,51 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + + + +package scala +package collection +package mutable + +import generic._ + +import scala.scalajs.js + +/** Buffers are used to create sequences of elements incrementally by + * appending, prepending, or inserting new elements. It is also + * possible to access and modify elements in a random access fashion + * via the index of the element in the current sequence. + * + * @author Matthias Zenger + * @author Martin Odersky + * @version 2.8 + * @since 1 + * + * @tparam A type of the elements contained in this buffer. + * + * @define Coll `Buffer` + * @define coll buffer + */ +trait Buffer[A] extends Seq[A] + with GenericTraversableTemplate[A, Buffer] + with BufferLike[A, Buffer[A]] + with scala.Cloneable { + override def companion: GenericCompanion[Buffer] = Buffer +} + +/** $factoryInfo + * @define coll buffer + * @define Coll `Buffer` + */ +object Buffer extends SeqFactory[Buffer] { + implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Buffer[A]] = ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]] + def newBuilder[A]: Builder[A, Buffer[A]] = new js.WrappedArray +} + +/** Explicit instantiation of the `Buffer` trait to reduce class file size in subclasses. */ +abstract class AbstractBuffer[A] extends AbstractSeq[A] with Buffer[A] diff --git a/scalalib/overrides-2.13/scala/compat/Platform.scala b/scalalib/overrides-2.13/scala/compat/Platform.scala new file mode 100644 index 0000000000..624ee370bd --- /dev/null +++ b/scalalib/overrides-2.13/scala/compat/Platform.scala @@ -0,0 +1,132 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala +package compat + +import java.lang.System + +object Platform { + + /** Thrown when a stack overflow occurs because a method or function recurses too deeply. + * + * On the JVM, this is a type alias for `java.lang.StackOverflowError`, which itself extends `java.lang.Error`. + * The same rules apply to catching a `java.lang.Error` as for Java, that it indicates a serious problem that a reasonable application should not try and catch. + */ + type StackOverflowError = java.lang.StackOverflowError + + /** This is a type alias for `java.util.ConcurrentModificationException`, + * which may be thrown by methods that detect an invalid modification of an object. + * For example, many common collection types do not allow modifying a collection + * while it is being iterated over. + */ + type ConcurrentModificationException = java.util.ConcurrentModificationException + + /** Copies `length` elements of array `src` starting at position `srcPos` to the + * array `dest` starting at position `destPos`. If `src`==`dest`, the copying will + * behave as if the elements copied from `src` were first copied to a temporary + * array before being copied back into the array at the destination positions. + * + * @param src A non-null array as source for the copy. + * @param srcPos The starting index in the source array. + * @param dest A non-null array as destination for the copy. + * @param destPos The starting index in the destination array. + * @param length The number of elements to be copied. + * @throws java.lang.NullPointerException If either `src` or `dest` are `null`. + * @throws java.lang.ArrayStoreException If either `src` or `dest` are not of type + * [java.lang.Array]; or if the element type of `src` is not + * compatible with that of `dest`. + * @throws java.lang.IndexOutOfBoundsException If either srcPos` or `destPos` are + * outside of the bounds of their respective arrays; or if `length` + * is negative; or if there are less than `length` elements available + * after `srcPos` or `destPos` in `src` and `dest` respectively. + */ + @inline + def arraycopy(src: AnyRef, srcPos: Int, dest: AnyRef, destPos: Int, length: Int) { + System.arraycopy(src, srcPos, dest, destPos, length) + } + + /** Creates a new array of the specified type and given length. + * + * Note that if `elemClass` is a subclass of [[scala.AnyVal]] then the returned value is an Array of the corresponding java primitive type. + * For example, the following code `scala.compat.Platform.createArray(classOf[Int], 4)` returns an array of the java primitive type `int`. + * + * For a [[scala.AnyVal]] array, the values of the array are set to 0 for ''numeric value types'' ([[scala.Double]], [[scala.Float]], [[scala.Long]], [[scala.Int]], [[scala.Char]], + * [[scala.Short]], and [[scala.Byte]]), and `false` for [[scala.Boolean]]. Creation of an array of type [[scala.Unit]] is not possible. + * + * For subclasses of [[scala.AnyRef]], the values of the array are set to `null`. + * + * The caller must cast the returned value to the correct type. + * + * @example {{{ + * val a = scala.compat.Platform.createArray(classOf[Int], 4).asInstanceOf[Array[Int]] // returns Array[Int](0, 0, 0, 0) + * }}} + * + * @param elemClass the `Class` object of the component type of the array + * @param length the length of the new array. + * @return an array of the given component type as an `AnyRef`. + * @throws java.lang.NullPointerException If `elemClass` is `null`. + * @throws java.lang.IllegalArgumentException if componentType is [[scala.Unit]] or `java.lang.Void.TYPE` + * @throws java.lang.NegativeArraySizeException if the specified length is negative + */ + @inline + def createArray(elemClass: Class[_], length: Int): AnyRef = + java.lang.reflect.Array.newInstance(elemClass, length) + + /** Assigns the value of 0 to each element in the array. + * @param arr A non-null Array[Int]. + * @throws java.lang.NullPointerException If `arr` is `null`. + */ + @inline + def arrayclear(arr: Array[Int]) { java.util.Arrays.fill(arr, 0) } + + /** Returns the `Class` object associated with the class or interface with the given string name using the current `ClassLoader`. + * On the JVM, invoking this method is equivalent to: `java.lang.Class.forName(name)` + * + * For more information, please see the Java documentation for [[java.lang.Class]]. + * + * @param name the fully qualified name of the desired class. + * @return the `Class` object for the class with the specified name. + * @throws java.lang.LinkageError if the linkage fails + * @throws java.lang.ExceptionInInitializerError if the initialization provoked by this method fails + * @throws java.lang.ClassNotFoundException if the class cannot be located + * @example {{{ + * val a = scala.compat.Platform.getClassForName("java.lang.Integer") // returns the Class[_] for java.lang.Integer + * }}} + */ + @inline + def getClassForName(name: String): Class[_] = java.lang.Class.forName(name) + + /** The default line separator. + * + * On the JavaScript backend, this is always "\n". + */ + val EOL = "\n" + + /** The current time in milliseconds. The time is counted since 1 January 1970 + * UTC. + * + * Note that the operating system timer used to obtain this value may be less + * precise than a millisecond. + */ + @inline + def currentTime: Long = System.currentTimeMillis() + + /** Runs the garbage collector. + * + * This is a request that the underlying JVM runs the garbage collector. + * The results of this call depends heavily on the JVM used. + * The underlying JVM is free to ignore this request. + */ + @inline + def collectGarbage(): Unit = System.gc() + + /** The name of the default character set encoding as a string */ + @inline + def defaultCharsetName: String = java.nio.charset.Charset.defaultCharset.name +} diff --git a/scalalib/overrides-2.13/scala/concurrent/ExecutionContext.scala b/scalalib/overrides-2.13/scala/concurrent/ExecutionContext.scala new file mode 100644 index 0000000000..fbe26f4de9 --- /dev/null +++ b/scalalib/overrides-2.13/scala/concurrent/ExecutionContext.scala @@ -0,0 +1,183 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala.concurrent + + +import java.util.concurrent.{ ExecutorService, Executor } +import scala.annotation.implicitNotFound +import scala.util.Try + +/** + * An `ExecutionContext` can execute program logic asynchronously, + * typically but not necessarily on a thread pool. + * + * A general purpose `ExecutionContext` must be asynchronous in executing + * any `Runnable` that is passed into its `execute`-method. A special purpose + * `ExecutionContext` may be synchronous but must only be passed to code that + * is explicitly safe to be run using a synchronously executing `ExecutionContext`. + * + * APIs such as `Future.onComplete` require you to provide a callback + * and an implicit `ExecutionContext`. The implicit `ExecutionContext` + * will be used to execute the callback. + * + * It is possible to simply import + * `scala.concurrent.ExecutionContext.Implicits.global` to obtain an + * implicit `ExecutionContext`. This global context is a reasonable + * default thread pool. + * + * However, application developers should carefully consider where they + * want to set policy; ideally, one place per application (or per + * logically-related section of code) will make a decision about + * which `ExecutionContext` to use. That is, you might want to avoid + * hardcoding `scala.concurrent.ExecutionContext.Implicits.global` all + * over the place in your code. + * One approach is to add `(implicit ec: ExecutionContext)` + * to methods which need an `ExecutionContext`. Then import a specific + * context in one place for the entire application or module, + * passing it implicitly to individual methods. + * + * A custom `ExecutionContext` may be appropriate to execute code + * which blocks on IO or performs long-running computations. + * `ExecutionContext.fromExecutorService` and `ExecutionContext.fromExecutor` + * are good ways to create a custom `ExecutionContext`. + * + * The intent of `ExecutionContext` is to lexically scope code execution. + * That is, each method, class, file, package, or application determines + * how to run its own code. This avoids issues such as running + * application callbacks on a thread pool belonging to a networking library. + * The size of a networking library's thread pool can be safely configured, + * knowing that only that library's network operations will be affected. + * Application callback execution can be configured separately. + */ +@implicitNotFound("""Cannot find an implicit ExecutionContext. You might pass +an (implicit ec: ExecutionContext) parameter to your method +or import scala.concurrent.ExecutionContext.Implicits.global.""") +trait ExecutionContext { + + /** Runs a block of code on this execution context. + * + * @param runnable the task to execute + */ + def execute(runnable: Runnable): Unit + + /** Reports that an asynchronous computation failed. + * + * @param cause the cause of the failure + */ + def reportFailure(@deprecatedName('t) cause: Throwable): Unit + + /** Prepares for the execution of a task. Returns the prepared + * execution context. The recommended implementation of + * `prepare` is to return `this`. + * + * This method should no longer be overridden or called. It was + * originally expected that `prepare` would be called by + * all libraries that consume ExecutionContexts, in order to + * capture thread local context. However, this usage has proven + * difficult to implement in practice and instead it is + * now better to avoid using `prepare` entirely. + * + * Instead, if an `ExecutionContext` needs to capture thread + * local context, it should capture that context when it is + * constructed, so that it doesn't need any additional + * preparation later. + */ + @deprecated("Preparation of ExecutionContexts will be removed.", "2.12") + def prepare(): ExecutionContext = this +} + +/** + * An [[ExecutionContext]] that is also a + * Java [[http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executor.html Executor]]. + */ +trait ExecutionContextExecutor extends ExecutionContext with Executor + +/** + * An [[ExecutionContext]] that is also a + * Java [[http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html ExecutorService]]. + */ +trait ExecutionContextExecutorService extends ExecutionContextExecutor with ExecutorService + + +/** Contains factory methods for creating execution contexts. + */ +object ExecutionContext { + /** + * The explicit global `ExecutionContext`. Invoke `global` when you want to provide the global + * `ExecutionContext` explicitly. + * + * The default `ExecutionContext` implementation is backed by a work-stealing thread pool. By default, + * the thread pool uses a target number of worker threads equal to the number of + * [[https://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#availableProcessors-- available processors]]. + * + * @return the global `ExecutionContext` + */ + def global: ExecutionContextExecutor = Implicits.global.asInstanceOf[ExecutionContextExecutor] + + object Implicits { + /** + * The implicit global `ExecutionContext`. Import `global` when you want to provide the global + * `ExecutionContext` implicitly. + * + * The default `ExecutionContext` implementation is backed by a work-stealing thread pool. By default, + * the thread pool uses a target number of worker threads equal to the number of + * [[https://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#availableProcessors-- available processors]]. + */ + implicit lazy val global: ExecutionContext = + scala.scalajs.concurrent.JSExecutionContext.queue + } + + /** Creates an `ExecutionContext` from the given `ExecutorService`. + * + * @param e the `ExecutorService` to use. If `null`, a new `ExecutorService` is created with [[http://www.scala-lang.org/api/current/index.html#scala.concurrent.ExecutionContext$@global:scala.concurrent.ExecutionContextExecutor default configuration]]. + * @param reporter a function for error reporting + * @return the `ExecutionContext` using the given `ExecutorService` + */ + def fromExecutorService(e: ExecutorService, reporter: Throwable => Unit): ExecutionContextExecutorService = + impl.ExecutionContextImpl.fromExecutorService(e, reporter) + + /** Creates an `ExecutionContext` from the given `ExecutorService` with the [[scala.concurrent.ExecutionContext$.defaultReporter default reporter]]. + * + * If it is guaranteed that none of the executed tasks are blocking, a single-threaded `ExecutorService` + * can be used to create an `ExecutionContext` as follows: + * + * {{{ + * import java.util.concurrent.Executors + * val ec = ExecutionContext.fromExecutorService(Executors.newSingleThreadExecutor()) + * }}} + * + * @param e the `ExecutorService` to use. If `null`, a new `ExecutorService` is created with [[http://www.scala-lang.org/api/current/index.html#scala.concurrent.ExecutionContext$@global:scala.concurrent.ExecutionContextExecutor default configuration]]. + * @return the `ExecutionContext` using the given `ExecutorService` + */ + def fromExecutorService(e: ExecutorService): ExecutionContextExecutorService = fromExecutorService(e, defaultReporter) + + /** Creates an `ExecutionContext` from the given `Executor`. + * + * @param e the `Executor` to use. If `null`, a new `Executor` is created with [[http://www.scala-lang.org/api/current/index.html#scala.concurrent.ExecutionContext$@global:scala.concurrent.ExecutionContextExecutor default configuration]]. + * @param reporter a function for error reporting + * @return the `ExecutionContext` using the given `Executor` + */ + def fromExecutor(e: Executor, reporter: Throwable => Unit): ExecutionContextExecutor = + impl.ExecutionContextImpl.fromExecutor(e, reporter) + + /** Creates an `ExecutionContext` from the given `Executor` with the [[scala.concurrent.ExecutionContext$.defaultReporter default reporter]]. + * + * @param e the `Executor` to use. If `null`, a new `Executor` is created with [[http://www.scala-lang.org/api/current/index.html#scala.concurrent.ExecutionContext$@global:scala.concurrent.ExecutionContextExecutor default configuration]]. + * @return the `ExecutionContext` using the given `Executor` + */ + def fromExecutor(e: Executor): ExecutionContextExecutor = fromExecutor(e, defaultReporter) + + /** The default reporter simply prints the stack trace of the `Throwable` to [[http://docs.oracle.com/javase/8/docs/api/java/lang/System.html#err System.err]]. + * + * @return the function for error reporting + */ + def defaultReporter: Throwable => Unit = _.printStackTrace() +} + + diff --git a/scalalib/overrides-2.13/scala/package.scala b/scalalib/overrides-2.13/scala/package.scala new file mode 100644 index 0000000000..21051d473f --- /dev/null +++ b/scalalib/overrides-2.13/scala/package.scala @@ -0,0 +1,133 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + + +/** + * Core Scala types. They are always available without an explicit import. + * @contentDiagram hideNodes "scala.Serializable" + */ +package object scala { + type Throwable = java.lang.Throwable + type Exception = java.lang.Exception + type Error = java.lang.Error + + type RuntimeException = java.lang.RuntimeException + type NullPointerException = java.lang.NullPointerException + type ClassCastException = java.lang.ClassCastException + type IndexOutOfBoundsException = java.lang.IndexOutOfBoundsException + type ArrayIndexOutOfBoundsException = java.lang.ArrayIndexOutOfBoundsException + type StringIndexOutOfBoundsException = java.lang.StringIndexOutOfBoundsException + type UnsupportedOperationException = java.lang.UnsupportedOperationException + type IllegalArgumentException = java.lang.IllegalArgumentException + type NoSuchElementException = java.util.NoSuchElementException + type NumberFormatException = java.lang.NumberFormatException + type AbstractMethodError = java.lang.AbstractMethodError + type InterruptedException = java.lang.InterruptedException + + // A dummy used by the specialization annotation. + val AnyRef = new Specializable { + override def toString = "object AnyRef" + } + + type TraversableOnce[+A] = scala.collection.TraversableOnce[A] + + type Traversable[+A] = scala.collection.Traversable[A] + val Traversable = scala.collection.Traversable + + type Iterable[+A] = scala.collection.Iterable[A] + val Iterable = scala.collection.Iterable + + type Seq[+A] = scala.collection.Seq[A] + val Seq = scala.collection.Seq + + type IndexedSeq[+A] = scala.collection.IndexedSeq[A] + val IndexedSeq = scala.collection.IndexedSeq + + type Iterator[+A] = scala.collection.Iterator[A] + val Iterator = scala.collection.Iterator + + type BufferedIterator[+A] = scala.collection.BufferedIterator[A] + + type List[+A] = scala.collection.immutable.List[A] + val List = scala.collection.immutable.List + + val Nil = scala.collection.immutable.Nil + + type ::[A] = scala.collection.immutable.::[A] + val :: = scala.collection.immutable.:: + + val +: = scala.collection.+: + val :+ = scala.collection.:+ + + type Stream[+A] = scala.collection.immutable.Stream[A] + val Stream = scala.collection.immutable.Stream + val #:: = scala.collection.immutable.Stream.#:: + + type Vector[+A] = scala.collection.immutable.Vector[A] + val Vector = scala.collection.immutable.Vector + + type StringBuilder = scala.collection.mutable.StringBuilder + val StringBuilder = scala.collection.mutable.StringBuilder + + type Range = scala.collection.immutable.Range + val Range = scala.collection.immutable.Range + + // Numeric types which were moved into scala.math.* + + type BigDecimal = scala.math.BigDecimal + lazy val BigDecimal = scala.math.BigDecimal + + type BigInt = scala.math.BigInt + lazy val BigInt = scala.math.BigInt + + type Equiv[T] = scala.math.Equiv[T] + val Equiv = scala.math.Equiv + + type Fractional[T] = scala.math.Fractional[T] + val Fractional = scala.math.Fractional + + type Integral[T] = scala.math.Integral[T] + val Integral = scala.math.Integral + + type Numeric[T] = scala.math.Numeric[T] + val Numeric = scala.math.Numeric + + type Ordered[T] = scala.math.Ordered[T] + val Ordered = scala.math.Ordered + + type Ordering[T] = scala.math.Ordering[T] + val Ordering = scala.math.Ordering + + type PartialOrdering[T] = scala.math.PartialOrdering[T] + type PartiallyOrdered[T] = scala.math.PartiallyOrdered[T] + + type Either[+A, +B] = scala.util.Either[A, B] + val Either = scala.util.Either + + type Left[+A, +B] = scala.util.Left[A, B] + val Left = scala.util.Left + + type Right[+A, +B] = scala.util.Right[A, B] + val Right = scala.util.Right + + // Annotations which we might move to annotation.* +/* + type SerialVersionUID = annotation.SerialVersionUID + type deprecated = annotation.deprecated + type deprecatedName = annotation.deprecatedName + type inline = annotation.inline + type native = annotation.native + type noinline = annotation.noinline + type remote = annotation.remote + type specialized = annotation.specialized + type transient = annotation.transient + type throws = annotation.throws + type unchecked = annotation.unchecked.unchecked + type volatile = annotation.volatile + */ +} diff --git a/scalalib/overrides-2.13/scala/reflect/ClassTag.scala b/scalalib/overrides-2.13/scala/reflect/ClassTag.scala new file mode 100644 index 0000000000..05312cebe0 --- /dev/null +++ b/scalalib/overrides-2.13/scala/reflect/ClassTag.scala @@ -0,0 +1,159 @@ +package scala +package reflect + +import java.lang.{ Class => jClass } + +/** + * + * A `ClassTag[T]` stores the erased class of a given type `T`, accessible via the `runtimeClass` + * field. This is particularly useful for instantiating `Array`s whose element types are unknown + * at compile time. + * + * `ClassTag`s are a weaker special case of [[scala.reflect.api.TypeTags#TypeTag]]s, in that they + * wrap only the runtime class of a given type, whereas a `TypeTag` contains all static type + * information. That is, `ClassTag`s are constructed from knowing only the top-level class of a + * type, without necessarily knowing all of its argument types. This runtime information is enough + * for runtime `Array` creation. + * + * For example: + * {{{ + * scala> def mkArray[T : ClassTag](elems: T*) = Array[T](elems: _*) + * mkArray: [T](elems: T*)(implicit evidence$1: scala.reflect.ClassTag[T])Array[T] + * + * scala> mkArray(42, 13) + * res0: Array[Int] = Array(42, 13) + * + * scala> mkArray("Japan","Brazil","Germany") + * res1: Array[String] = Array(Japan, Brazil, Germany) + * }}} + * + * See [[scala.reflect.api.TypeTags]] for more examples, or the + * [[http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html Reflection Guide: TypeTags]] + * for more details. + * + */ +@scala.annotation.implicitNotFound(msg = "No ClassTag available for ${T}") +trait ClassTag[T] extends ClassManifestDeprecatedApis[T] with Equals with Serializable { + // please, don't add any APIs here, like it was with `newWrappedArray` and `newArrayBuilder` + // class tags, and all tags in general, should be as minimalistic as possible + + /** A class representing the type `U` to which `T` would be erased. + * Note that there is no subtyping relationship between `T` and `U`. + */ + def runtimeClass: jClass[_] + + /** Produces a `ClassTag` that knows how to instantiate an `Array[Array[T]]` */ + def wrap: ClassTag[Array[T]] = ClassTag[Array[T]](arrayClass(runtimeClass)) + + /** Produces a new array with element type `T` and length `len` */ + override def newArray(len: Int): Array[T] = + runtimeClass match { + case java.lang.Byte.TYPE => new Array[Byte](len).asInstanceOf[Array[T]] + case java.lang.Short.TYPE => new Array[Short](len).asInstanceOf[Array[T]] + case java.lang.Character.TYPE => new Array[Char](len).asInstanceOf[Array[T]] + case java.lang.Integer.TYPE => new Array[Int](len).asInstanceOf[Array[T]] + case java.lang.Long.TYPE => new Array[Long](len).asInstanceOf[Array[T]] + case java.lang.Float.TYPE => new Array[Float](len).asInstanceOf[Array[T]] + case java.lang.Double.TYPE => new Array[Double](len).asInstanceOf[Array[T]] + case java.lang.Boolean.TYPE => new Array[Boolean](len).asInstanceOf[Array[T]] + case java.lang.Void.TYPE => new Array[Unit](len).asInstanceOf[Array[T]] + case _ => java.lang.reflect.Array.newInstance(runtimeClass, len).asInstanceOf[Array[T]] + } + + /** A ClassTag[T] can serve as an extractor that matches only objects of type T. + * + * The compiler tries to turn unchecked type tests in pattern matches into checked ones + * by wrapping a `(_: T)` type pattern as `ct(_: T)`, where `ct` is the `ClassTag[T]` instance. + * Type tests necessary before calling other extractors are treated similarly. + * `SomeExtractor(...)` is turned into `ct(SomeExtractor(...))` if `T` in `SomeExtractor.unapply(x: T)` + * is uncheckable, but we have an instance of `ClassTag[T]`. + */ + def unapply(x: Any): Option[T] = + if (null != x && ( + (runtimeClass.isInstance(x)) + || (x.isInstanceOf[Byte] && runtimeClass.isAssignableFrom(classOf[Byte])) + || (x.isInstanceOf[Short] && runtimeClass.isAssignableFrom(classOf[Short])) + || (x.isInstanceOf[Char] && runtimeClass.isAssignableFrom(classOf[Char])) + || (x.isInstanceOf[Int] && runtimeClass.isAssignableFrom(classOf[Int])) + || (x.isInstanceOf[Long] && runtimeClass.isAssignableFrom(classOf[Long])) + || (x.isInstanceOf[Float] && runtimeClass.isAssignableFrom(classOf[Float])) + || (x.isInstanceOf[Double] && runtimeClass.isAssignableFrom(classOf[Double])) + || (x.isInstanceOf[Boolean] && runtimeClass.isAssignableFrom(classOf[Boolean])) + || (x.isInstanceOf[Unit] && runtimeClass.isAssignableFrom(classOf[Unit]))) + ) Some(x.asInstanceOf[T]) + else None + + // TODO: deprecate overloads in 2.12.0, remove in 2.13.0 + def unapply(x: Byte) : Option[T] = unapplyImpl(x, classOf[Byte]) + def unapply(x: Short) : Option[T] = unapplyImpl(x, classOf[Short]) + def unapply(x: Char) : Option[T] = unapplyImpl(x, classOf[Char]) + def unapply(x: Int) : Option[T] = unapplyImpl(x, classOf[Int]) + def unapply(x: Long) : Option[T] = unapplyImpl(x, classOf[Long]) + def unapply(x: Float) : Option[T] = unapplyImpl(x, classOf[Float]) + def unapply(x: Double) : Option[T] = unapplyImpl(x, classOf[Double]) + def unapply(x: Boolean) : Option[T] = unapplyImpl(x, classOf[Boolean]) + def unapply(x: Unit) : Option[T] = unapplyImpl(x, classOf[Unit]) + + private[this] def unapplyImpl(x: Any, primitiveCls: java.lang.Class[_]): Option[T] = + if (runtimeClass.isInstance(x) || runtimeClass.isAssignableFrom(primitiveCls)) Some(x.asInstanceOf[T]) + else None + + // case class accessories + override def canEqual(x: Any) = x.isInstanceOf[ClassTag[_]] + override def equals(x: Any) = x.isInstanceOf[ClassTag[_]] && this.runtimeClass == x.asInstanceOf[ClassTag[_]].runtimeClass + override def hashCode = runtimeClass.## + override def toString = { + def prettyprint(clazz: jClass[_]): String = + if (clazz.isArray) s"Array[${prettyprint(clazz.getComponentType)}]" else + clazz.getName + prettyprint(runtimeClass) + } +} + +/** + * Class tags corresponding to primitive types and constructor/extractor for ClassTags. + */ +object ClassTag { + def Byte : ClassTag[scala.Byte] = ManifestFactory.Byte + def Short : ClassTag[scala.Short] = ManifestFactory.Short + def Char : ClassTag[scala.Char] = ManifestFactory.Char + def Int : ClassTag[scala.Int] = ManifestFactory.Int + def Long : ClassTag[scala.Long] = ManifestFactory.Long + def Float : ClassTag[scala.Float] = ManifestFactory.Float + def Double : ClassTag[scala.Double] = ManifestFactory.Double + def Boolean : ClassTag[scala.Boolean] = ManifestFactory.Boolean + def Unit : ClassTag[scala.Unit] = ManifestFactory.Unit + def Any : ClassTag[scala.Any] = ManifestFactory.Any + def Object : ClassTag[java.lang.Object] = ManifestFactory.Object + def AnyVal : ClassTag[scala.AnyVal] = ManifestFactory.AnyVal + def AnyRef : ClassTag[scala.AnyRef] = ManifestFactory.AnyRef + def Nothing : ClassTag[scala.Nothing] = ManifestFactory.Nothing + def Null : ClassTag[scala.Null] = ManifestFactory.Null + + @inline + private class GenericClassTag[T](val runtimeClass: jClass[_]) extends ClassTag[T] + + def apply[T](runtimeClass1: jClass[_]): ClassTag[T] = + runtimeClass1 match { + case java.lang.Byte.TYPE => ClassTag.Byte.asInstanceOf[ClassTag[T]] + case java.lang.Short.TYPE => ClassTag.Short.asInstanceOf[ClassTag[T]] + case java.lang.Character.TYPE => ClassTag.Char.asInstanceOf[ClassTag[T]] + case java.lang.Integer.TYPE => ClassTag.Int.asInstanceOf[ClassTag[T]] + case java.lang.Long.TYPE => ClassTag.Long.asInstanceOf[ClassTag[T]] + case java.lang.Float.TYPE => ClassTag.Float.asInstanceOf[ClassTag[T]] + case java.lang.Double.TYPE => ClassTag.Double.asInstanceOf[ClassTag[T]] + case java.lang.Boolean.TYPE => ClassTag.Boolean.asInstanceOf[ClassTag[T]] + case java.lang.Void.TYPE => ClassTag.Unit.asInstanceOf[ClassTag[T]] + case _ => + if (classOf[java.lang.Object] == runtimeClass1) + ClassTag.Object.asInstanceOf[ClassTag[T]] + else if (classOf[scala.runtime.Nothing$] == runtimeClass1) + ClassTag.Nothing.asInstanceOf[ClassTag[T]] + else if (classOf[scala.runtime.Null$] == runtimeClass1) + ClassTag.Null.asInstanceOf[ClassTag[T]] + else + new GenericClassTag[T](runtimeClass1) + } + + def unapply[T](ctag: ClassTag[T]): Option[Class[_]] = Some(ctag.runtimeClass) +} diff --git a/scalalib/overrides-2.13/scala/reflect/Manifest.scala b/scalalib/overrides-2.13/scala/reflect/Manifest.scala new file mode 100644 index 0000000000..f38ce59e4d --- /dev/null +++ b/scalalib/overrides-2.13/scala/reflect/Manifest.scala @@ -0,0 +1,300 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2007-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala +package reflect + +import scala.collection.mutable.{ArrayBuilder, WrappedArray} + +/** A `Manifest[T]` is an opaque descriptor for type T. Its supported use + * is to give access to the erasure of the type as a `Class` instance, as + * is necessary for the creation of native `Arrays` if the class is not + * known at compile time. + * + * The type-relation operators `<:<` and `=:=` should be considered + * approximations only, as there are numerous aspects of type conformance + * which are not yet adequately represented in manifests. + * + * Example usages: + * {{{ + * def arr[T] = new Array[T](0) // does not compile + * def arr[T](implicit m: Manifest[T]) = new Array[T](0) // compiles + * def arr[T: Manifest] = new Array[T](0) // shorthand for the preceding + * + * // Methods manifest, classManifest, and optManifest are in [[scala.Predef]]. + * def isApproxSubType[T: Manifest, U: Manifest] = manifest[T] <:< manifest[U] + * isApproxSubType[List[String], List[AnyRef]] // true + * isApproxSubType[List[String], List[Int]] // false + * + * def methods[T: ClassManifest] = classManifest[T].erasure.getMethods + * def retType[T: ClassManifest](name: String) = + * methods[T] find (_.getName == name) map (_.getGenericReturnType) + * + * retType[Map[_, _]]("values") // Some(scala.collection.Iterable) + * }}} + */ +@scala.annotation.implicitNotFound(msg = "No Manifest available for ${T}.") +// TODO undeprecated until Scala reflection becomes non-experimental +// @deprecated("use scala.reflect.ClassTag (to capture erasures) or scala.reflect.runtime.universe.TypeTag (to capture types) or both instead", "2.10.0") +trait Manifest[T] extends ClassManifest[T] with Equals { + override def typeArguments: List[Manifest[_]] = Nil + + override def arrayManifest: Manifest[Array[T]] = + Manifest.classType[Array[T]](arrayClass[T](runtimeClass), this) + + override def canEqual(that: Any): Boolean = that match { + case _: Manifest[_] => true + case _ => false + } + /** Note: testing for erasure here is important, as it is many times + * faster than <:< and rules out most comparisons. + */ + override def equals(that: Any): Boolean = that match { + case m: Manifest[_] => (m canEqual this) && (this.runtimeClass == m.runtimeClass) && (this <:< m) && (m <:< this) + case _ => false + } + override def hashCode = this.runtimeClass.## +} + +// TODO undeprecated until Scala reflection becomes non-experimental +// @deprecated("use type tags and manually check the corresponding class or type instead", "2.10.0") +@SerialVersionUID(1L) +abstract class AnyValManifest[T <: AnyVal](override val toString: String) extends Manifest[T] with Equals { + override def <:<(that: ClassManifest[_]): Boolean = + (that eq this) || (that eq Manifest.Any) || (that eq Manifest.AnyVal) + override def canEqual(other: Any) = other match { + case _: AnyValManifest[_] => true + case _ => false + } + override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef] + override def hashCode = System.identityHashCode(this) +} + +/** `ManifestFactory` defines factory methods for manifests. + * It is intended for use by the compiler and should not be used in client code. + * + * Unlike `Manifest`, this factory isn't annotated with a deprecation warning. + * This is done to prevent avalanches of deprecation warnings in the code that calls methods with manifests. + * Why so complicated? Read up the comments for `ClassManifestFactory`. + */ +object ManifestFactory { + def valueManifests: List[AnyValManifest[_]] = + List(Byte, Short, Char, Int, Long, Float, Double, Boolean, Unit) + + private object ByteManifest extends AnyValManifest[scala.Byte]("Byte") { + def runtimeClass = java.lang.Byte.TYPE + override def newArray(len: Int): Array[Byte] = new Array[Byte](len) + override def newWrappedArray(len: Int): WrappedArray[Byte] = new WrappedArray.ofByte(new Array[Byte](len)) + override def newArrayBuilder(): ArrayBuilder[Byte] = new ArrayBuilder.ofByte() + private def readResolve(): Any = Manifest.Byte + } + def Byte: AnyValManifest[Byte] = ByteManifest + + private object ShortManifest extends AnyValManifest[scala.Short]("Short") { + def runtimeClass = java.lang.Short.TYPE + override def newArray(len: Int): Array[Short] = new Array[Short](len) + override def newWrappedArray(len: Int): WrappedArray[Short] = new WrappedArray.ofShort(new Array[Short](len)) + override def newArrayBuilder(): ArrayBuilder[Short] = new ArrayBuilder.ofShort() + private def readResolve(): Any = Manifest.Short + } + def Short: AnyValManifest[Short] = ShortManifest + + private object CharManifest extends AnyValManifest[scala.Char]("Char") { + def runtimeClass = java.lang.Character.TYPE + override def newArray(len: Int): Array[Char] = new Array[Char](len) + override def newWrappedArray(len: Int): WrappedArray[Char] = new WrappedArray.ofChar(new Array[Char](len)) + override def newArrayBuilder(): ArrayBuilder[Char] = new ArrayBuilder.ofChar() + private def readResolve(): Any = Manifest.Char + } + def Char: AnyValManifest[Char] = CharManifest + + private object IntManifest extends AnyValManifest[scala.Int]("Int") { + def runtimeClass = java.lang.Integer.TYPE + override def newArray(len: Int): Array[Int] = new Array[Int](len) + override def newWrappedArray(len: Int): WrappedArray[Int] = new WrappedArray.ofInt(new Array[Int](len)) + override def newArrayBuilder(): ArrayBuilder[Int] = new ArrayBuilder.ofInt() + private def readResolve(): Any = Manifest.Int + } + def Int: AnyValManifest[Int] = IntManifest + + private object LongManifest extends AnyValManifest[scala.Long]("Long") { + def runtimeClass = java.lang.Long.TYPE + override def newArray(len: Int): Array[Long] = new Array[Long](len) + override def newWrappedArray(len: Int): WrappedArray[Long] = new WrappedArray.ofLong(new Array[Long](len)) + override def newArrayBuilder(): ArrayBuilder[Long] = new ArrayBuilder.ofLong() + private def readResolve(): Any = Manifest.Long + } + def Long: AnyValManifest[Long] = LongManifest + + private object FloatManifest extends AnyValManifest[scala.Float]("Float") { + def runtimeClass = java.lang.Float.TYPE + override def newArray(len: Int): Array[Float] = new Array[Float](len) + override def newWrappedArray(len: Int): WrappedArray[Float] = new WrappedArray.ofFloat(new Array[Float](len)) + override def newArrayBuilder(): ArrayBuilder[Float] = new ArrayBuilder.ofFloat() + private def readResolve(): Any = Manifest.Float + } + def Float: AnyValManifest[Float] = FloatManifest + + private object DoubleManifest extends AnyValManifest[scala.Double]("Double") { + def runtimeClass = java.lang.Double.TYPE + override def newArray(len: Int): Array[Double] = new Array[Double](len) + override def newWrappedArray(len: Int): WrappedArray[Double] = new WrappedArray.ofDouble(new Array[Double](len)) + override def newArrayBuilder(): ArrayBuilder[Double] = new ArrayBuilder.ofDouble() + private def readResolve(): Any = Manifest.Double + } + def Double: AnyValManifest[Double] = DoubleManifest + + private object BooleanManifest extends AnyValManifest[scala.Boolean]("Boolean") { + def runtimeClass = java.lang.Boolean.TYPE + override def newArray(len: Int): Array[Boolean] = new Array[Boolean](len) + override def newWrappedArray(len: Int): WrappedArray[Boolean] = new WrappedArray.ofBoolean(new Array[Boolean](len)) + override def newArrayBuilder(): ArrayBuilder[Boolean] = new ArrayBuilder.ofBoolean() + private def readResolve(): Any = Manifest.Boolean + } + def Boolean: AnyValManifest[Boolean] = BooleanManifest + + private object UnitManifest extends AnyValManifest[scala.Unit]("Unit") { + def runtimeClass = java.lang.Void.TYPE + override def newArray(len: Int): Array[Unit] = new Array[Unit](len) + override def newWrappedArray(len: Int): WrappedArray[Unit] = new WrappedArray.ofUnit(new Array[Unit](len)) + override def newArrayBuilder(): ArrayBuilder[Unit] = new ArrayBuilder.ofUnit() + override protected def arrayClass[T](tp: Class[_]): Class[Array[T]] = + if (tp eq runtimeClass) classOf[Array[scala.runtime.BoxedUnit]].asInstanceOf[Class[Array[T]]] + else super.arrayClass(tp) + private def readResolve(): Any = Manifest.Unit + } + def Unit: AnyValManifest[Unit] = UnitManifest + + private object AnyManifest extends PhantomManifest[scala.Any](classOf[java.lang.Object], "Any") { + override def runtimeClass = classOf[java.lang.Object] + override def newArray(len: Int) = new Array[scala.Any](len) + override def <:<(that: ClassManifest[_]): Boolean = (that eq this) + private def readResolve(): Any = Manifest.Any + } + def Any: Manifest[scala.Any] = AnyManifest + + private object ObjectManifest extends PhantomManifest[java.lang.Object](classOf[java.lang.Object], "Object") { + override def runtimeClass = classOf[java.lang.Object] + override def newArray(len: Int) = new Array[java.lang.Object](len) + override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any) + private def readResolve(): Any = Manifest.Object + } + def Object: Manifest[java.lang.Object] = ObjectManifest + + def AnyRef: Manifest[scala.AnyRef] = Object.asInstanceOf[Manifest[scala.AnyRef]] + + private object AnyValManifest extends PhantomManifest[scala.AnyVal](classOf[java.lang.Object], "AnyVal") { + override def runtimeClass = classOf[java.lang.Object] + override def newArray(len: Int) = new Array[scala.AnyVal](len) + override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any) + private def readResolve(): Any = Manifest.AnyVal + } + def AnyVal: Manifest[scala.AnyVal] = AnyValManifest + + private object NullManifest extends PhantomManifest[scala.Null](classOf[scala.runtime.Null$], "Null") { + override def runtimeClass = classOf[scala.runtime.Null$] + override def newArray(len: Int) = new Array[scala.Null](len) + override def <:<(that: ClassManifest[_]): Boolean = + (that ne null) && (that ne Nothing) && !(that <:< AnyVal) + private def readResolve(): Any = Manifest.Null + } + def Null: Manifest[scala.Null] = NullManifest + + private object NothingManifest extends PhantomManifest[scala.Nothing](classOf[scala.runtime.Nothing$], "Nothing") { + override def runtimeClass = classOf[scala.runtime.Nothing$] + override def newArray(len: Int) = new Array[scala.Nothing](len) + override def <:<(that: ClassManifest[_]): Boolean = (that ne null) + private def readResolve(): Any = Manifest.Nothing + } + def Nothing: Manifest[scala.Nothing] = NothingManifest + + private class SingletonTypeManifest[T <: AnyRef](value: AnyRef) extends Manifest[T] { + lazy val runtimeClass = value.getClass + override lazy val toString = value.toString + ".type" + } + + /** Manifest for the singleton type `value.type`. */ + def singleType[T <: AnyRef](value: AnyRef): Manifest[T] = + new SingletonTypeManifest[T](value) + + /** Manifest for the class type `clazz[args]`, where `clazz` is + * a top-level or static class. + * @note This no-prefix, no-arguments case is separate because we + * it's called from ScalaRunTime.boxArray itself. If we + * pass varargs as arrays into this, we get an infinitely recursive call + * to boxArray. (Besides, having a separate case is more efficient) + */ + def classType[T](clazz: Predef.Class[_]): Manifest[T] = + new ClassTypeManifest[T](None, clazz, Nil) + + /** Manifest for the class type `clazz`, where `clazz` is + * a top-level or static class and args are its type arguments. */ + def classType[T](clazz: Predef.Class[T], arg1: Manifest[_], args: Manifest[_]*): Manifest[T] = + new ClassTypeManifest[T](None, clazz, arg1 :: args.toList) + + /** Manifest for the class type `clazz[args]`, where `clazz` is + * a class with non-package prefix type `prefix` and type arguments `args`. + */ + def classType[T](prefix: Manifest[_], clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] = + new ClassTypeManifest[T](Some(prefix), clazz, args.toList) + + private abstract class PhantomManifest[T](_runtimeClass: Predef.Class[_], + override val toString: String) extends ClassTypeManifest[T](None, _runtimeClass, Nil) { + override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef] + override def hashCode = System.identityHashCode(this) + } + + /** Manifest for the class type `clazz[args]`, where `clazz` is + * a top-level or static class. */ + private class ClassTypeManifest[T](prefix: Option[Manifest[_]], + runtimeClass1: Predef.Class[_], + override val typeArguments: List[Manifest[_]]) extends Manifest[T] { + def runtimeClass: Predef.Class[_] = runtimeClass1 + override def toString = + (if (prefix.isEmpty) "" else prefix.get.toString+"#") + + (if (runtimeClass.isArray) "Array" else runtimeClass.getName) + + argString + } + + def arrayType[T](arg: Manifest[_]): Manifest[Array[T]] = + arg.asInstanceOf[Manifest[T]].arrayManifest + + private class AbstractTypeManifest[T](prefix: Manifest[_], name: String, upperBound: Predef.Class[_], args: Seq[Manifest[_]]) extends Manifest[T] { + def runtimeClass = upperBound + override val typeArguments = args.toList + override def toString = prefix.toString+"#"+name+argString + } + + /** Manifest for the abstract type `prefix # name`. `upperBound` is not + * strictly necessary as it could be obtained by reflection. It was + * added so that erasure can be calculated without reflection. */ + def abstractType[T](prefix: Manifest[_], name: String, upperBound: Predef.Class[_], args: Manifest[_]*): Manifest[T] = + new AbstractTypeManifest[T](prefix, name, upperBound, args) + + private class WildcardManifest[T](lowerBound: Manifest[_], upperBound: Manifest[_]) extends Manifest[T] { + def runtimeClass = upperBound.runtimeClass + override def toString = + "_" + + (if (lowerBound eq Nothing) "" else " >: "+lowerBound) + + (if (upperBound eq Nothing) "" else " <: "+upperBound) + } + + /** Manifest for the unknown type `_ >: L <: U` in an existential. + */ + def wildcardType[T](lowerBound: Manifest[_], upperBound: Manifest[_]): Manifest[T] = + new WildcardManifest[T](lowerBound, upperBound) + + private class IntersectionTypeManifest[T](parents: Seq[Manifest[_]]) extends Manifest[T] { + def runtimeClass = parents.head.runtimeClass + override def toString = parents.mkString(" with ") + } + + /** Manifest for the intersection type `parents_0 with ... with parents_n`. */ + def intersectionType[T](parents: Manifest[_]*): Manifest[T] = + new IntersectionTypeManifest[T](parents) +} diff --git a/scalalib/overrides-2.13/scala/reflect/NameTransformer.scala b/scalalib/overrides-2.13/scala/reflect/NameTransformer.scala new file mode 100644 index 0000000000..fcb8bdd1b8 --- /dev/null +++ b/scalalib/overrides-2.13/scala/reflect/NameTransformer.scala @@ -0,0 +1,161 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala +package reflect + +/** Provides functions to encode and decode Scala symbolic names. + * Also provides some constants. + */ +object NameTransformer { + // XXX Short term: providing a way to alter these without having to recompile + // the compiler before recompiling the compiler. + val MODULE_SUFFIX_STRING = "$" + val NAME_JOIN_STRING = "$" + val MODULE_INSTANCE_NAME = "MODULE$" + val LOCAL_SUFFIX_STRING = " " + val SETTER_SUFFIX_STRING = "_$eq" + val TRAIT_SETTER_SEPARATOR_STRING = "$_setter_$" + + private val nops = 128 + private val ncodes = 26 * 26 + + private class OpCodes(val op: Char, val code: String, val next: OpCodes) + + private val op2code = new Array[String](nops) + private val code2op = new Array[OpCodes](ncodes) + private def enterOp(op: Char, code: String) = { + op2code(op.toInt) = code + val c = (code.charAt(1) - 'a') * 26 + code.charAt(2) - 'a' + code2op(c.toInt) = new OpCodes(op, code, code2op(c)) + } + + /* Note: decoding assumes opcodes are only ever lowercase. */ + enterOp('~', "$tilde") + enterOp('=', "$eq") + enterOp('<', "$less") + enterOp('>', "$greater") + enterOp('!', "$bang") + enterOp('#', "$hash") + enterOp('%', "$percent") + enterOp('^', "$up") + enterOp('&', "$amp") + enterOp('|', "$bar") + enterOp('*', "$times") + enterOp('/', "$div") + enterOp('+', "$plus") + enterOp('-', "$minus") + enterOp(':', "$colon") + enterOp('\\', "$bslash") + enterOp('?', "$qmark") + enterOp('@', "$at") + + /** Replace operator symbols by corresponding `\$opname`. + * + * @param name the string to encode + * @return the string with all recognized opchars replaced with their encoding + */ + def encode(name: String): String = { + var buf: StringBuilder = null + val len = name.length() + var i = 0 + while (i < len) { + val c = name charAt i + if (c < nops && (op2code(c.toInt) ne null)) { + if (buf eq null) { + buf = new StringBuilder() + buf.append(name.substring(0, i)) + } + buf.append(op2code(c.toInt)) + /* Handle glyphs that are not valid Java/JVM identifiers */ + } + else if (!Character.isJavaIdentifierPart(c)) { + if (buf eq null) { + buf = new StringBuilder() + buf.append(name.substring(0, i)) + } + buf.append("$u%04X".format(c.toInt)) + } + else if (buf ne null) { + buf.append(c) + } + i += 1 + } + if (buf eq null) name else buf.toString() + } + + /** Replace `\$opname` by corresponding operator symbol. + * + * @param name0 the string to decode + * @return the string with all recognized operator symbol encodings replaced with their name + */ + def decode(name0: String): String = { + //System.out.println("decode: " + name);//DEBUG + val name = if (name0.endsWith("")) name0.stripSuffix("") + "this" + else name0 + var buf: StringBuilder = null + val len = name.length() + var i = 0 + while (i < len) { + var ops: OpCodes = null + var unicode = false + val c = name charAt i + if (c == '$' && i + 2 < len) { + val ch1 = name.charAt(i+1) + if ('a' <= ch1 && ch1 <= 'z') { + val ch2 = name.charAt(i+2) + if ('a' <= ch2 && ch2 <= 'z') { + ops = code2op((ch1 - 'a') * 26 + ch2 - 'a') + while ((ops ne null) && !name.startsWith(ops.code, i)) ops = ops.next + if (ops ne null) { + if (buf eq null) { + buf = new StringBuilder() + buf.append(name.substring(0, i)) + } + buf.append(ops.op) + i += ops.code.length() + } + /* Handle the decoding of Unicode glyphs that are + * not valid Java/JVM identifiers */ + } else if ((len - i) >= 6 && // Check that there are enough characters left + ch1 == 'u' && + ((Character.isDigit(ch2)) || + ('A' <= ch2 && ch2 <= 'F'))) { + /* Skip past "$u", next four should be hexadecimal */ + val hex = name.substring(i+2, i+6) + try { + val str = Integer.parseInt(hex, 16).toChar + if (buf eq null) { + buf = new StringBuilder() + buf.append(name.substring(0, i)) + } + buf.append(str) + /* 2 for "$u", 4 for hexadecimal number */ + i += 6 + unicode = true + } catch { + case _:NumberFormatException => + /* `hex` did not decode to a hexadecimal number, so + * do nothing. */ + } + } + } + } + /* If we didn't see an opcode or encoded Unicode glyph, and the + buffer is non-empty, write the current character and advance + one */ + if ((ops eq null) && !unicode) { + if (buf ne null) + buf.append(c) + i += 1 + } + } + //System.out.println("= " + (if (buf == null) name else buf.toString()));//DEBUG + if (buf eq null) name else buf.toString() + } +} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/RangesTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/RangesTest.scala index cabd946a1e..7acb5d146b 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/RangesTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/RangesTest.scala @@ -64,32 +64,32 @@ class RangesTest { } @Test def Range_toString_issue_2412(): Unit = { - if (scalaVersion.startsWith("2.12.")) { - assertEquals("inexact Range 1 to 10 by 2", (1 to 10 by 2).toString) - assertEquals("empty Range 1 until 1 by 2", (1 until 1 by 2).toString) - assertEquals("Range requires step", (0.0 to 1.0).toString) - assertEquals("Range 0 to 1", (0 to 1).toString) - } else { + if (scalaVersion.startsWith("2.10.") || scalaVersion.startsWith("2.11.")) { assertEquals("Range(1, 3, 5, 7, 9)", (1 to 10 by 2).toString) assertEquals("Range()", (1 until 1 by 2).toString) assertTrue((0.0 to 1.0).toString.startsWith("scala.collection.immutable.Range$Partial")) assertEquals("Range(0, 1)", (0 to 1).toString) + } else { + assertEquals("inexact Range 1 to 10 by 2", (1 to 10 by 2).toString) + assertEquals("empty Range 1 until 1 by 2", (1 until 1 by 2).toString) + assertEquals("Range requires step", (0.0 to 1.0).toString) + assertEquals("Range 0 to 1", (0 to 1).toString) } } @Test def NumericRange_toString_issue_2412(): Unit = { - if (scalaVersion.startsWith("2.12.")) { - assertEquals(s"NumericRange 0.1 to ${1.0} by 0.1", + if (scalaVersion.startsWith("2.10.") || scalaVersion.startsWith("2.11.")) { + assertEquals("NumericRange(0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6, 0.7, " + + "0.7999999999999999, 0.8999999999999999, 0.9999999999999999)", (0.1 to 1.0 by 0.1).toString()) assertEquals( - s"NumericRange 0.1 until ${1.0} by 0.1 (using NumericRange 0.1 until ${1.0} by 0.1 of BigDecimal)", + "NumericRange(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9)", Range.Double(0.1, 1.0, 0.1).toString) } else { - assertEquals("NumericRange(0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6, 0.7, " + - "0.7999999999999999, 0.8999999999999999, 0.9999999999999999)", + assertEquals(s"NumericRange 0.1 to ${1.0} by 0.1", (0.1 to 1.0 by 0.1).toString()) assertEquals( - "NumericRange(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9)", + s"NumericRange 0.1 until ${1.0} by 0.1 (using NumericRange 0.1 until ${1.0} by 0.1 of BigDecimal)", Range.Double(0.1, 1.0, 0.1).toString) } } From 0cedea3387a94dbd7096ff172bc56f51b857d414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 17 Dec 2016 14:56:50 +0100 Subject: [PATCH 0067/2665] Move run/t9516.scala from buglist to whitelist. It passes. We forgot to move it when we fixed #2502 in 3b065d8fd548d79368aa372c059597a509111ef9. --- .../scala/tools/partest/scalajs/2.12.0/BuglistedTests.txt | 3 --- .../scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BuglistedTests.txt index 99aa63e275..42c6146a09 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BuglistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BuglistedTests.txt @@ -2,6 +2,3 @@ # use scala.tools.partest.scalajs.testunknownonly to only run tests # which are neither in BuglistedTests.txt, WhitelistedTests.txt or # BlacklistedTests.txt - -# Bug with BoxedUnit/void -run/t9516.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt index 405a6334c4..199f0598ba 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt @@ -3230,6 +3230,7 @@ run/t9841.scala run/trait-fields-override-lazy.scala run/trait_fields_init.scala run/trait_fields_three_layer_overrides.scala +run/t9516.scala # Adapt checkfiles for (1.0).toString == "1" run/Course-2002-01.scala From dde7dfe3fcaa0fa5eeb9ec90ad8944603d80dfc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 17 Dec 2016 19:00:44 +0100 Subject: [PATCH 0068/2665] Fix `scalaTestSuite/test` on Windows. Previously, it could not be run on Windows because the white- and blacklists use `/` but file names have `\`. --- project/Build.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Build.scala b/project/Build.scala index 4101387f55..ccca541d6b 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1669,7 +1669,7 @@ object Build { val scalaScalaJUnitSources = { (jUnitTestsPath ** "*.scala").get.flatMap { file => file.relativeTo(jUnitTestsPath) match { - case Some(rel) => List((rel.toString, file)) + case Some(rel) => List((rel.toString.replace('\\', '/'), file)) case None => Nil } } From fc145fc9870a31cbd20c2d4102a670a29ead5032 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 17 Dec 2016 13:42:56 +0100 Subject: [PATCH 0069/2665] Fix #2688: Upgrade to Scala 2.12.1. This also fixes #2591, since the new standard library includes the fix from https://github.com/scala/scala/pull/5400. --- ci/checksizes.sh | 14 +- ci/matrix.xml | 34 +- .../scalajs/2.12.1/BlacklistedTests.txt | 994 +++++ .../partest/scalajs/2.12.1/BuglistedTests.txt | 4 + .../scalajs/2.12.1/WhitelistedTests.txt | 3317 +++++++++++++++++ .../scalajs/2.12.1/neg/t6446-additional.check | 30 + .../scalajs/2.12.1/neg/t6446-list.check | 2 + .../scalajs/2.12.1/neg/t6446-missing.check | 30 + .../2.12.1/neg/t6446-show-phases.check | 29 + .../scalajs/2.12.1/neg/t7494-no-options.check | 31 + .../scalajs/2.12.1/run/Course-2002-01.check | 37 + .../scalajs/2.12.1/run/Course-2002-02.check | 187 + .../scalajs/2.12.1/run/Course-2002-04.check | 64 + .../scalajs/2.12.1/run/Course-2002-08.check | 171 + .../scalajs/2.12.1/run/Course-2002-09.check | 50 + .../scalajs/2.12.1/run/Course-2002-10.check | 46 + .../partest/scalajs/2.12.1/run/Meter.check | 16 + .../scalajs/2.12.1/run/MeterCaseClass.check | 16 + .../tools/partest/scalajs/2.12.1/run/bugs.sem | 1 + .../scalajs/2.12.1/run/caseClassHash.check | 9 + .../partest/scalajs/2.12.1/run/deeps.check | 87 + .../scalajs/2.12.1/run/dynamic-anyval.check | 4 + .../scalajs/2.12.1/run/impconvtimes.check | 1 + .../partest/scalajs/2.12.1/run/imports.check | 21 + .../scalajs/2.12.1/run/interpolation.check | 32 + .../2.12.1/run/interpolationMultiline1.check | 26 + .../partest/scalajs/2.12.1/run/issue192.sem | 1 + .../2.12.1/run/macro-bundle-static.check | 6 + .../2.12.1/run/macro-bundle-toplevel.check | 6 + .../run/macro-bundle-whitebox-decl.check | 6 + .../partest/scalajs/2.12.1/run/misc.check | 62 + .../scalajs/2.12.1/run/promotion.check | 4 + .../partest/scalajs/2.12.1/run/runtime.check | 70 + .../scalajs/2.12.1/run/spec-self.check | 2 + .../scalajs/2.12.1/run/structural.check | 37 + .../scalajs/2.12.1/run/t0421-new.check | 3 + .../scalajs/2.12.1/run/t0421-old.check | 3 + .../partest/scalajs/2.12.1/run/t1503.sem | 1 + .../partest/scalajs/2.12.1/run/t3702.check | 2 + .../partest/scalajs/2.12.1/run/t4148.sem | 1 + .../partest/scalajs/2.12.1/run/t4617.check | 1 + .../partest/scalajs/2.12.1/run/t5356.check | 6 + .../partest/scalajs/2.12.1/run/t5552.check | 6 + .../partest/scalajs/2.12.1/run/t5568.check | 9 + .../partest/scalajs/2.12.1/run/t5629b.check | 10 + .../partest/scalajs/2.12.1/run/t5680.check | 3 + .../partest/scalajs/2.12.1/run/t5866.check | 2 + .../scalajs/2.12.1/run/t6318_primitives.check | 54 + .../partest/scalajs/2.12.1/run/t6662.check | 1 + .../partest/scalajs/2.12.1/run/t7657.check | 3 + .../partest/scalajs/2.12.1/run/t7763.sem | 1 + .../partest/scalajs/2.12.1/run/t8570a.check | 1 + .../partest/scalajs/2.12.1/run/t8764.check | 5 + .../partest/scalajs/2.12.1/run/t9387b.check | 1 + .../partest/scalajs/2.12.1/run/t9656.check | 14 + .../scalajs/2.12.1/run/try-catch-unify.check | 4 + .../2.12.1/run/virtpatmat_switch.check | 7 + .../2.12.1/run/virtpatmat_typetag.check | 10 + project/Build.scala | 5 +- .../resources/2.12.1/BlacklistedTests.txt | 121 + .../resources/2.12.1/WhitelistedTests.txt | 35 + scripts/build-all-js.sh | 2 +- scripts/publish.sh | 4 +- 63 files changed, 5741 insertions(+), 21 deletions(-) create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BuglistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-additional.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-list.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-missing.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-show-phases.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t7494-no-options.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Course-2002-01.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Course-2002-02.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Course-2002-04.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Course-2002-08.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Course-2002-09.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Course-2002-10.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Meter.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/MeterCaseClass.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/bugs.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/caseClassHash.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/deeps.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/dynamic-anyval.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/impconvtimes.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/imports.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/interpolation.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/interpolationMultiline1.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/issue192.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/macro-bundle-static.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/macro-bundle-toplevel.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/macro-bundle-whitebox-decl.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/misc.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/promotion.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/runtime.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/spec-self.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/structural.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t0421-new.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t0421-old.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t1503.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t3702.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t4148.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t4617.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t5356.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t5552.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t5568.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t5629b.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t5680.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t5866.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t6318_primitives.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t6662.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t7657.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t7763.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t8570a.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t8764.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t9387b.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t9656.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/try-catch-unify.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/virtpatmat_switch.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/virtpatmat_typetag.check create mode 100644 scala-test-suite/src/test/resources/2.12.1/BlacklistedTests.txt create mode 100644 scala-test-suite/src/test/resources/2.12.1/WhitelistedTests.txt diff --git a/ci/checksizes.sh b/ci/checksizes.sh index fdf000bcab..1cde0a5d9c 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -11,10 +11,10 @@ case $FULLVER in 2.11.8) VER=2.11 ;; - 2.12.0) + 2.12.1) VER=2.12 ;; - 2.10.3|2.10.4|2.10.5|2.10.6|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7) + 2.10.3|2.10.4|2.10.5|2.10.6|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7|2.12.0) echo "Ignoring checksizes for Scala $FULLVER" exit 0 ;; @@ -45,11 +45,11 @@ case $FULLVER in REVERSI_PREOPT_GZ_EXPECTEDSIZE=71000 REVERSI_OPT_GZ_EXPECTEDSIZE=32000 ;; - 2.12.0) - REVERSI_PREOPT_EXPECTEDSIZE=555000 - REVERSI_OPT_EXPECTEDSIZE=140000 - REVERSI_PREOPT_GZ_EXPECTEDSIZE=75500 - REVERSI_OPT_GZ_EXPECTEDSIZE=35500 + 2.12.1) + REVERSI_PREOPT_EXPECTEDSIZE=490000 + REVERSI_OPT_EXPECTEDSIZE=114000 + REVERSI_PREOPT_GZ_EXPECTEDSIZE=66000 + REVERSI_OPT_GZ_EXPECTEDSIZE=29000 ;; esac diff --git a/ci/matrix.xml b/ci/matrix.xml index 9bc71aecda..b4909c9126 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -307,7 +307,7 @@ 1.8 - 2.12.0 + 2.12.1 1.8 @@ -323,7 +323,7 @@ testSuite - 2.12.0 + 2.12.1 1.8 testSuite @@ -335,7 +335,7 @@ scalaTestSuite - 2.12.0 + 2.12.1 1.8 scalaTestSuite @@ -352,7 +352,7 @@ testSuite - 2.12.0 + 2.12.1 1.8 testSuite @@ -364,7 +364,7 @@ scalaTestSuite - 2.12.0 + 2.12.1 1.8 scalaTestSuite @@ -379,7 +379,7 @@ 1.8 - 2.12.0 + 2.12.1 1.8 @@ -418,7 +418,7 @@ 1.7 - 2.12.0 + 2.12.1 1.8 @@ -473,6 +473,10 @@ 2.11.7 1.8 + + 2.12.0 + 1.8 + @@ -528,11 +532,11 @@ 1.7 - 2.12.0 + 2.12.1 1.8 - 2.12.0 + 2.12.1 1.8 @@ -637,6 +641,18 @@ 2.11.8 1.8 + + 2.12.0 + 1.8 + + + 2.12.0 + 1.8 + + + 2.12.0 + 1.8 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt new file mode 100644 index 0000000000..e605c60168 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt @@ -0,0 +1,994 @@ +# +# POS +# + +# Using Jsoup, what's that? +pos/cycle-jsoup.scala + +# +# NEG +# + +# Screws up, but not really our problem (error: None.get instead of +# phase ordering error) +neg/t7494-multi-right-after +neg/t7494-right-after-before +neg/t7622-multi-followers +neg/t7622-cyclic-dependency + +# Uses some strange macro cross compile mechanism. +neg/macro-incompatible-macro-engine-c.scala + +# Uses .java files +run/t9200 +run/noInlineUnknownIndy +# +# RUN +# + +# Relies on the exact toString() representation of Floats/Doubles +run/t2378.scala + +# Uses ClassTags on existentials which are broken in Scala (see #251) +run/valueclasses-classtag-existential.scala + +# Relies on a particular execution speed +run/t5857.scala + +# Using parts of the javalib we don't plan to support + +run/t5018.scala +run/t2417.scala +run/t4813.scala +run/lazy-concurrent.scala +run/t3667.scala +run/t3038d.scala +run/shutdownhooks.scala +run/t5590.scala +run/t3895b.scala +run/t5974.scala +run/hashset.scala +run/t5262.scala +run/serialize-stream.scala +run/sysprops.scala +run/lambda-serialization-gc.scala +run/t9390.scala +run/t9390b.scala +run/t9390c.scala + +run/t2849.scala +run/t1360.scala +run/t3199b.scala +run/t8690.scala + +run/various-flat-classpath-types.scala + +# Uses java.util.Collections +run/t2250.scala + +# Uses java.math.BigDecimal / BigInteger : but failures not due to them +run/hashhash.scala +run/is-valid-num.scala + +# Documented semantic difference on String.split(x: Array[Char]) +run/t0325.scala + +# Using Threads +run/t6969.scala +run/inner-obj-auto.scala +run/predef-cycle.scala +run/synchronized.scala + +# Uses java.security +run/t2318.scala + +# Tries to catch java.lang.StackOverflowError +run/t6154.scala + +# Tries to catch java.lang.OutOfMemoryError +run/t7880.scala + +# Taking too much time, because JavaScript is not as fast as the JVM + +run/collections.scala +run/t3989.scala +run/adding-growing-set.scala +run/t3242.scala +run/hashCodeDistribution.scala +run/t408.scala +run/t6584.scala +run/t6853.scala +run/UnrolledBuffer.scala +run/t6253a.scala +run/t6253b.scala +run/t6253c.scala +run/numbereq.scala +run/t4658.scala + +# Crashes Rhino + +run/bridges.scala +run/patmat-exprs.scala + +# Using partest properties + +run/tailcalls.scala +run/t4294.scala +run/t6331b.scala + +# Using IO + +run/t6488.scala +run/t6988.scala + +# Object{Output|Input}Streams +run/t6935.scala +run/t8188.scala +run/t9375.scala +run/t9365.scala +run/inlineAddDeserializeLambda.scala +run/sammy_seriazable.scala +run/lambda-serialization-security.scala + +# Using System.getProperties + +run/t4426.scala + +# Using Await + +run/t7336.scala +run/t7775.scala +run/future-flatmap-exec-count.scala + +# Using detailed stack trace + +run/t6308.scala + +# Using reflection + +run/t6063 + +run/mixin-bridge-methods.scala +run/t5125.scala +run/outertest.scala +run/t6223.scala +run/t5652b +run/elidable-opt.scala +run/nullable-lazyvals.scala +run/t4794.scala +run/t5652 +run/t5652c +run/getClassTest-old.scala +run/t8960.scala +run/t7965.scala +run/t8087.scala +run/t8931.scala +run/t8445.scala +run/lambda-serialization.scala + +run/reflection-repl-classes.scala +run/t5256e.scala +run/typetags_core.scala +run/reflection-constructormirror-toplevel-badpath.scala +run/t5276_1b.scala +run/reflection-sorted-decls.scala +run/toolbox_typecheck_implicitsdisabled.scala +run/t5418b.scala +run/toolbox_typecheck_macrosdisabled2.scala +run/abstypetags_serialize.scala +run/all-overridden.scala +run/showraw_tree_kinds.scala +run/showraw_tree_types_ids.scala +run/showraw_tree_types_typed.scala +run/showraw_tree_ids.scala +run/showraw_tree_ultimate.scala +run/t5266_2.scala +run/t5274_1.scala +run/t5224.scala +run/reflection-sanitychecks.scala +run/t6086-vanilla.scala +run/t5277_2.scala +run/reflection-methodsymbol-params.scala +run/reflection-valueclasses-standard.scala +run/t5274_2.scala +run/t5423.scala +run/reflection-modulemirror-toplevel-good.scala +run/t5419.scala +run/t5271_3.scala +run/reflection-enclosed-nested-basic.scala +run/reflection-enclosed-nested-nested-basic.scala +run/fail-non-value-types.scala +run/exprs_serialize.scala +run/t5258a.scala +run/typetags_without_scala_reflect_manifest_lookup.scala +run/t4110-new.scala +run/t5273_2b_newpatmat.scala +run/t6277.scala +run/t5335.scala +run/toolbox_typecheck_macrosdisabled.scala +run/reflection-modulemirror-inner-good.scala +run/t5229_2.scala +run/typetags_multi.scala +run/typetags_without_scala_reflect_typetag_manifest_interop.scala +run/reflection-constructormirror-toplevel-good.scala +run/reflection-magicsymbols-invoke.scala +run/t6392b.scala +run/t5229_1.scala +run/reflection-magicsymbols-vanilla.scala +run/t5225_2.scala +run/runtimeEval1.scala +run/reflection-enclosed-nested-inner-basic.scala +run/reflection-fieldmirror-ctorparam.scala +run/t6181.scala +run/reflection-magicsymbols-repl.scala +run/t5272_2_newpatmat.scala +run/t5270.scala +run/t5418a.scala +run/t5276_2b.scala +run/t5256f.scala +run/reflection-enclosed-basic.scala +run/reflection-constructormirror-inner-badpath.scala +run/interop_typetags_are_manifests.scala +run/newTags.scala +run/t5273_1_newpatmat.scala +run/reflection-constructormirror-nested-good.scala +run/t2236-new.scala +run/existentials3-new.scala +run/t6323b.scala +run/t5943a1.scala +run/reflection-fieldmirror-getsetval.scala +run/t5272_1_oldpatmat.scala +run/t5256h.scala +run/t1195-new.scala +run/t5840.scala +run/reflection-methodsymbol-returntype.scala +run/reflection-fieldmirror-accessorsareokay.scala +run/reflection-sorted-members.scala +run/reflection-allmirrors-tostring.scala +run/valueclasses-typetag-existential.scala +run/toolbox_console_reporter.scala +run/reflection-enclosed-inner-inner-basic.scala +run/t5256b.scala +run/bytecodecs.scala +run/elidable.scala +run/freetypes_false_alarm1.scala +run/freetypes_false_alarm2.scala +run/getClassTest-new.scala +run/idempotency-extractors.scala +run/idempotency-case-classes.scala +run/idempotency-this.scala +run/idempotency-labels.scala +run/idempotency-lazy-vals.scala +run/interop_manifests_are_abstypetags.scala +run/interop_manifests_are_typetags.scala +run/abstypetags_core.scala +run/macro-reify-abstypetag-notypeparams +run/macro-reify-abstypetag-typeparams-tags +run/macro-reify-abstypetag-typeparams-notags +run/macro-reify-abstypetag-usetypetag +run/macro-reify-freevars +run/macro-reify-splice-outside-reify +run/macro-reify-tagless-a +run/macro-reify-type +run/macro-reify-typetag-typeparams-tags +run/macro-reify-typetag-notypeparams +run/macro-undetparams-implicitval +run/manifests-new.scala +run/manifests-old.scala +run/no-pickle-skolems +run/position-val-def.scala +run/reflect-priv-ctor.scala +run/primitive-sigs-2-new.scala +run/primitive-sigs-2-old.scala +run/reflection-enclosed-inner-basic.scala +run/reflection-enclosed-inner-nested-basic.scala +run/reflection-constructormirror-inner-good.scala +run/reflection-constructormirror-nested-badpath.scala +run/reflection-fancy-java-classes +run/reflection-fieldsymbol-navigation.scala +run/reflection-fieldmirror-nmelocalsuffixstring.scala +run/reflection-fieldmirror-getsetvar.scala +run/reflection-fieldmirror-privatethis.scala +run/reflection-implicit.scala +run/reflection-mem-glbs.scala +run/reflection-mem-tags.scala +run/reflection-java-annotations +run/reflection-java-crtp +run/reflection-methodsymbol-typeparams.scala +run/reflection-modulemirror-nested-badpath.scala +run/reflection-modulemirror-inner-badpath.scala +run/reflection-modulemirror-nested-good.scala +run/reflection-modulemirror-toplevel-badpath.scala +run/reflection-sync-subtypes.scala +run/reflinit.scala +run/reflection-valueclasses-derived.scala +run/reflection-valueclasses-magic.scala +run/resetattrs-this.scala +run/runtimeEval2.scala +run/showraw_aliases.scala +run/showraw_mods.scala +run/shortClass.scala +run/showraw_nosymbol.scala +run/showraw_tree.scala +run/showraw_tree_types_untyped.scala +run/t1167.scala +run/t2577.scala +run/t2873.scala +run/t2886.scala +run/t2251b.scala +run/t3346j.scala +run/t3507-new.scala +run/t3569.scala +run/t5125b.scala +run/t5225_1.scala +run/t3425b +run/t5256a.scala +run/t5230.scala +run/t5256c.scala +run/t5256g.scala +run/t5266_1.scala +run/t5269.scala +run/t5271_1.scala +run/t5271_2.scala +run/t5271_4.scala +run/t5272_1_newpatmat.scala +run/t5272_2_oldpatmat.scala +run/t5273_1_oldpatmat.scala +run/t5273_2a_newpatmat.scala +run/t5273_2a_oldpatmat.scala +run/t5275.scala +run/t5276_1a.scala +run/t5276_2a.scala +run/t5277_1.scala +run/t5279.scala +run/t5334_1.scala +run/t5334_2.scala +run/t5415.scala +run/t5418.scala +run/t5676.scala +run/t5704.scala +run/t5710-1.scala +run/t5710-2.scala +run/t5770.scala +run/t5894.scala +run/t5816.scala +run/t5824.scala +run/t5912.scala +run/t5942.scala +run/t5943a2.scala +run/t6023.scala +run/t6113.scala +run/t6175.scala +run/t6178.scala +run/t6199-mirror.scala +run/t6199-toolbox.scala +run/t6240-universe-code-gen.scala +run/t6221 +run/t6260b.scala +run/t6259.scala +run/t6287.scala +run/t6344.scala +run/t6392a.scala +run/t6591_1.scala +run/t6591_2.scala +run/t6591_3.scala +run/t6591_5.scala +run/t6591_6.scala +run/t6591_7.scala +run/t6608.scala +run/t6677.scala +run/t6687.scala +run/t6715.scala +run/t6719.scala +run/t6793.scala +run/t6860.scala +run/t6793b.scala +run/t6793c.scala +run/t7045.scala +run/t7046.scala +run/t7008-scala-defined +run/t7120b.scala +run/t7151.scala +run/t7214.scala +run/t7235.scala +run/t7331a.scala +run/t7331b.scala +run/t7331c.scala +run/t7558.scala +run/t7556 +run/t7779.scala +run/t7868b.scala +run/toolbox_current_run_compiles.scala +run/toolbox_default_reporter_is_silent.scala +run/toolbox_parse_package.scala +run/toolbox_silent_reporter.scala +run/toolbox_typecheck_inferimplicitvalue.scala +run/typetags_serialize.scala +run/valueclasses-typetag-basic.scala +run/WeakHashSetTest.scala +run/valueclasses-typetag-generic.scala +run/t4023.scala +run/t4024.scala +run/t6380.scala +run/t5273_2b_oldpatmat.scala +run/t8104 +run/t8047.scala +run/t6992 +run/var-arity-class-symbol.scala +run/typetags_symbolof_x.scala +run/typecheck +run/t8190.scala +run/t8192 +run/t8177f.scala +run/t8199.scala +run/t7932.scala +run/t7700.scala +run/t7570c.scala +run/t7570b.scala +run/t7533.scala +run/t7570a.scala +run/t7044 +run/t7328.scala +run/t6733.scala +run/t6554.scala +run/t6732.scala +run/t6379 +run/t6411b.scala +run/t6411a.scala +run/t6260c.scala +run/t6260-delambdafy.scala +run/showdecl +run/reflection-sync-potpourri.scala +run/reflection-tags.scala +run/reflection-companiontype.scala +run/reflection-scala-annotations.scala +run/reflection-idtc.scala +run/macro-reify-nested-b2 +run/mixin-signatures.scala +run/reflection-companion.scala +run/macro-reify-nested-b1 +run/macro-reify-nested-a2 +run/macro-reify-nested-a1 +run/macro-reify-chained2 +run/macro-reify-chained1 +run/inferred-type-constructors.scala +run/mirror_symbolof_x.scala +run/t8196.scala +run/t8549b.scala +run/t8574.scala +run/t8549.scala +run/t8637.scala +run/t8253.scala +run/t9027.scala +run/t6622.scala +run/toolbox_expand_macro.scala +run/toolbox-varargs +run/t9252.scala +run/t9182.scala +run/t9102.scala +run/t720.scala +run/t9408.scala +run/trait-default-specialize.scala +run/lazy-locals-2.scala +run/t5294.scala +run/trait_fields_final.scala +run/trait_fields_bytecode.scala +run/trait_fields_volatile.scala +run/junitForwarders + +run/reify_newimpl_29.scala +run/reify_magicsymbols.scala +run/reify_inheritance.scala +run/reify_newimpl_12.scala +run/reify_typerefs_2b.scala +run/reify_csv.scala +run/reify_inner2.scala +run/reify_maps_oldpatmat.scala +run/reify_newimpl_43.scala +run/reify_nested_inner_refers_to_local.scala +run/reify_closure7.scala +run/reify_closure8b.scala +run/reify_typerefs_3b.scala +run/reify_newimpl_44.scala +run/reify_newimpl_06.scala +run/reify_newimpl_05.scala +run/reify_newimpl_20.scala +run/reify_newimpl_23.scala +run/reify_metalevel_breach_-1_refers_to_1.scala +run/reify_newimpl_41.scala +run/reify-repl-fail-gracefully.scala +run/reify_fors_oldpatmat.scala +run/reify_inner3.scala +run/reify_closure8a.scala +run/reify_closures10.scala +run/reify_ann2a.scala +run/reify_newimpl_51.scala +run/reify_newimpl_47.scala +run/reify_extendbuiltins.scala +run/reify_newimpl_30.scala +run/reify_newimpl_38.scala +run/reify_closure2a.scala +run/reify_newimpl_45.scala +run/reify_closure1.scala +run/reify_generic2.scala +run/reify_printf.scala +run/reify_closure6.scala +run/reify_newimpl_37.scala +run/reify_newimpl_35.scala +run/reify_typerefs_3a.scala +run/reify_newimpl_25.scala +run/reify_ann4.scala +run/reify_typerefs_1b.scala +run/reify_newimpl_22.scala +run/reify_this.scala +run/reify_typerefs_2a.scala +run/reify_newimpl_03.scala +run/reify_newimpl_48.scala +run/reify_varargs.scala +run/reify_newimpl_42.scala +run/reify_newimpl_15.scala +run/reify_nested_inner_refers_to_global.scala +run/reify_newimpl_02.scala +run/reify_newimpl_01.scala +run/reify_fors_newpatmat.scala +run/reify_classfileann_a.scala +run/reify_nested_outer_refers_to_local.scala +run/reify_newimpl_13.scala +run/reify_closure5a.scala +run/reify_inner4.scala +run/reify_sort.scala +run/reify_ann1a.scala +run/reify_classfileann_b.scala +run/reify_closure4a.scala +run/reify_newimpl_33.scala +run/reify_sort1.scala +run/reify_properties.scala +run/reify_generic.scala +run/reify_newimpl_27.scala +run/reify-aliases.scala +run/reify_ann3.scala +run/reify-staticXXX.scala +run/reify_ann1b.scala +run/reify_ann5.scala +run/reify_anonymous.scala +run/reify-each-node-type.scala +run/reify_copypaste2.scala +run/reify_closure3a.scala +run/reify_copypaste1.scala +run/reify_complex.scala +run/reify_for1.scala +run/reify_getter.scala +run/reify_implicits-new.scala +run/reify_inner1.scala +run/reify_implicits-old.scala +run/reify_lazyunit.scala +run/reify_lazyevaluation.scala +run/reify_maps_newpatmat.scala +run/reify_metalevel_breach_+0_refers_to_1.scala +run/reify_metalevel_breach_-1_refers_to_0_a.scala +run/reify_metalevel_breach_-1_refers_to_0_b.scala +run/reify_nested_outer_refers_to_global.scala +run/reify_newimpl_04.scala +run/reify_newimpl_14.scala +run/reify_newimpl_11.scala +run/reify_newimpl_18.scala +run/reify_newimpl_19.scala +run/reify_newimpl_31.scala +run/reify_newimpl_21.scala +run/reify_newimpl_36.scala +run/reify_newimpl_39.scala +run/reify_newimpl_40.scala +run/reify_newimpl_49.scala +run/reify_newimpl_50.scala +run/reify_newimpl_52.scala +run/reify_renamed_term_basic.scala +run/reify_renamed_term_local_to_reifee.scala +run/reify_renamed_term_overloaded_method.scala +run/reify_renamed_type_basic.scala +run/reify_renamed_type_local_to_reifee.scala +run/reify_renamed_type_spliceable.scala +run/reify_typerefs_1a.scala +run/reify_timeofday.scala +run/reify_renamed_term_t5841.scala + +run/t7521b.scala +run/t8575b.scala +run/t8575c.scala +run/t8944c.scala +run/t9535.scala +run/t9437a +run/t9437b +run/t9814.scala +run/t10009.scala +run/t10075.scala +run/t10075b + +run/t8756.scala +run/inferred-type-constructors-hou.scala +run/trait-static-forwarder +run/SD-235.scala + +# Uses refletction indirectly through +# scala.runtime.ScalaRunTime.replStringOf +run/t6634.scala + +# Using reflection to invoke macros. These tests actually don't require +# or test reflection, but use it to separate compilation units nicely. +# It's a pity we cannot use them + +run/macro-abort-fresh +run/macro-expand-varargs-explicit-over-nonvarargs-bad +run/macro-invalidret-doesnt-conform-to-def-rettype +run/macro-invalidret-nontypeable +run/macro-invalidusage-badret +run/macro-invalidusage-partialapplication +run/macro-invalidusage-partialapplication-with-tparams +run/macro-reflective-ma-normal-mdmi +run/macro-reflective-mamd-normal-mi + +# Using macros, but indirectly creating calls to reflection +run/macro-reify-unreify + +# Using Enumeration in a way we cannot fix + +run/enums.scala +run/t3719.scala +run/t8611b.scala + +# Exceptions that become JavaScriptException + +run/pf-catch.scala +run/exceptions-2.scala +run/exceptions-nest.scala +run/t8601c.scala +run/t8601b.scala +run/inlineHandlers.scala + +# Expecting unsupported exceptions (e.g. ArrayIndexOutOfBounds) +run/optimizer-array-load.scala +run/t6827.scala +run/t8601.scala + +# Playing with classfile format + +run/classfile-format-51.scala +run/classfile-format-52.scala + +# Concurrent collections (TrieMap) +# has too much stuff implemented in *.java, so no support +run/triemap-hash.scala + +# Using parallel collections + +run/t5375.scala +run/t4894.scala +run/ctries-new +run/collection-conversions.scala +run/concurrent-map-conversions.scala +run/t4761.scala +run/t7498.scala +run/t6448.scala +run/ctries-old +run/map_java_conversions.scala +run/parmap-ops.scala +run/pc-conversions.scala +run/t4459.scala +run/t4608.scala +run/t4723.scala +run/t4895.scala +run/t6052.scala +run/t6410.scala +run/t6467.scala +run/t6908.scala +run/t8955.scala + +# Using scala.xml + +run/t4124.scala + +# Using Swing + +run/t3613.scala + +# Using the REPL + +run/t4285.scala +run/constant-type.scala +run/repl-bare-expr.scala +run/repl-parens.scala +run/repl-assign.scala +run/t5583.scala +run/treePrint.scala +run/constrained-types.scala +run/repl-power.scala +run/t4710.scala +run/repl-paste.scala +run/repl-reset.scala +run/repl-paste-3.scala +run/t6329_repl.scala +run/t6273.scala +run/repl-paste-2.scala +run/t5655.scala +run/t5072.scala +run/repl-colon-type.scala +run/kind-repl-command.scala +run/repl-trim-stack-trace.scala +run/t4594-repl-settings.scala +run/repl-save.scala +run/repl-paste-raw.scala +run/repl-paste-4.scala +run/t7801.scala +run/repl-backticks.scala +run/t6633.scala +run/repl-inline.scala + +# Using the Repl (scala.tools.partest.ReplTest) +run/class-symbol-contravariant.scala +run/lub-visibility.scala +run/macro-bundle-repl.scala +run/macro-repl-basic.scala +run/macro-repl-dontexpand.scala +run/macro-system-properties.scala +run/reflection-equality.scala +run/reflection-repl-elementary.scala +run/reify_newimpl_26.scala +run/repl-out-dir.scala +run/repl-term-macros.scala +run/repl-transcript.scala +run/repl-type-verbose.scala +run/t3376.scala +run/t4025.scala +run/t4172.scala +run/t4216.scala +run/t4542.scala +run/t4671.scala +run/t5256d.scala +run/t5535.scala +run/t5537.scala +run/t5789.scala +run/t6086-repl.scala +run/t6146b.scala +run/t6187.scala +run/t6320.scala +run/t6381.scala +run/t6434.scala +run/t6439.scala +run/t6507.scala +run/t6549.scala +run/t6937.scala +run/t7185.scala +run/t7319.scala +run/t7482a.scala +run/t7634.scala +run/t7747-repl.scala +run/t7805-repl-i.scala +run/tpeCache-tyconCache.scala +run/repl-empty-package +run/repl-javap-def.scala +run/repl-javap-mem.scala +run/repl-javap-outdir +run/repl-javap.scala +run/t6329_repl_bug.scala +run/t4950.scala +run/xMigration.scala +run/t6541-option.scala +run/repl-serialization.scala +run/t9174.scala +run/repl-paste-5.scala +run/repl-no-uescape.scala +run/repl-no-imports-no-predef-classbased.scala +run/repl-implicits-nopredef.scala +run/repl-classbased.scala +run/repl-no-imports-no-predef-power.scala +run/repl-paste-b.scala +run/repl-paste-6.scala +run/repl-implicits.scala +run/repl-no-imports-no-predef.scala +run/repl-paste-raw-b.scala +run/repl-paste-raw-c.scala +run/t9749-repl-dot.scala +run/trait_fields_repl.scala +run/t7139 +run/t9689 + +# Using Scala Script (partest.ScriptTest) + +run/t7711-script-args.scala +run/t4625.scala +run/t4625c.scala +run/t4625b.scala + +# Using the compiler API + +run/t2512.scala +run/analyzerPlugins.scala +run/compiler-asSeenFrom.scala +run/t5603.scala +run/t6440.scala +run/t5545.scala +run/existentials-in-compiler.scala +run/global-showdef.scala +run/stream_length.scala +run/annotatedRetyping.scala +run/imain.scala +run/existential-rangepos.scala +run/delambdafy_uncurry_byname_inline.scala +run/delambdafy_uncurry_byname_method.scala +run/delambdafy_uncurry_inline.scala +run/delambdafy_t6555.scala +run/delambdafy_uncurry_method.scala +run/delambdafy_t6028.scala +run/memberpos.scala +run/programmatic-main.scala +run/reflection-names.scala +run/settings-parse.scala +run/sm-interpolator.scala +run/t1501.scala +run/t1500.scala +run/sammy_java8.scala +run/t1618.scala +run/t2464 +run/t4072.scala +run/t5064.scala +run/t5385.scala +run/t5699.scala +run/t5717.scala +run/t5940.scala +run/t6028.scala +run/t6194.scala +run/t6669.scala +run/t6745-2.scala +run/t7096.scala +run/t7271.scala +run/t7337.scala +run/t7398.scala +run/t7569.scala +run/t7852.scala +run/t7817-tree-gen.scala +run/t7825.scala + +# partest.ParserTest +run/t3368.scala +run/t3368-b.scala +run/t3368-c.scala +run/t3368-d.scala +run/t9944.scala + +# partest.DirectTest +run/t6288.scala +run/t6331.scala +run/t6440b.scala +run/t6555.scala +run/t7876.scala +run/typetags_without_scala_reflect_typetag_lookup.scala +run/dynamic-updateDynamic.scala +run/dynamic-selectDynamic.scala +run/dynamic-applyDynamic.scala +run/dynamic-applyDynamicNamed.scala +run/t4841-isolate-plugins +run/large_code.scala +run/macroPlugins-namerHooks.scala +run/t4841-no-plugin.scala +run/t4332.scala +run/t8029.scala +run/t8046 +run/t5905-features.scala +run/t5905b-features.scala +run/large_class.scala +run/t8708_b +run/icode-reader-dead-code.scala +run/t5938.scala +run/t8502.scala +run/t6502.scala +run/t8907.scala +run/t9097.scala +run/macroPlugins-enterStats.scala +run/sbt-icode-interface.scala +run/t8502b.scala +run/t9437c +run/repl-paste-parse.scala +run/t5463.scala +run/t8433.scala +run/sd275.scala +run/sd275-java + +# partest.CompilerTest +run/t8852a.scala + +# partest.ASMConverters +run/t9403 + +# partest.BytecodeTest +run/t7106 +run/t7974 +run/t8601-closure-elim.scala +run/t4788 +run/t4788-separate-compilation + +# partest.SessionTest +run/t8843-repl-xlat.scala +run/t9206.scala +run/t9170.scala +run/t8918-unary-ids.scala +run/t1931.scala + +# partest.JavapTest +run/t8608-no-format.scala + +# Using .java source files + +run/t4317 +run/t4238 +run/t2296c +run/t4119 +run/t4283 +run/t4891 +run/t6168 +run/t6168b +run/t6240a +run/t6240b +run/t6548 +run/t6989 +run/t7008 +run/t7246 +run/t7246b +run/t7359 +run/t7439 +run/t7455 +run/t7510 +run/t7582-private-within +run/t7582 +run/t7582b +run/t3897 +run/t7374 +run/t3452e +run/t3452g +run/t3452d +run/t3452b +run/t3452a +run/t8442 +run/t8601e +run/t9298 +run/t9298b +run/t9359 +run/t7741a +run/t7741b +run/bcodeInlinerMixed +run/t9268 +run/t9489 +run/t9915 +run/t10059 + +# Using scala-script +run/t7791-script-linenums.scala + +# Suffers from bug in Node.js (https://github.com/joyent/node/issues/7528) +run/range-unit.scala + +# Using scalap +run/scalapInvokedynamic.scala + +# Using Manifests (which use Class.getInterfaces) +run/valueclasses-manifest-existential.scala +run/existentials3-old.scala +run/t2236-old.scala +run/interop_manifests_are_classtags.scala +run/valueclasses-manifest-generic.scala +run/valueclasses-manifest-basic.scala +run/t1195-old.scala +run/t3758-old.scala +run/t4110-old.scala +run/t6246.scala + +# Using ScalaRunTime.stringOf +run/value-class-extractor-seq.scala +run/t3493.scala + +# Custom invoke dynamic node +run/indy-via-macro +run/indy-via-macro-with-dynamic-args + +### Incorrect partests ### +# Badly uses constract of Console.print (no flush) +run/t429.scala +run/t6102.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BuglistedTests.txt new file mode 100644 index 0000000000..42c6146a09 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BuglistedTests.txt @@ -0,0 +1,4 @@ +# The tests in this file should pass but have never passed so far +# use scala.tools.partest.scalajs.testunknownonly to only run tests +# which are neither in BuglistedTests.txt, WhitelistedTests.txt or +# BlacklistedTests.txt diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt new file mode 100644 index 0000000000..e45b1fdc7f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt @@ -0,0 +1,3317 @@ +pos/spec-super.scala +pos/t1035.scala +pos/t5897.scala +pos/irrefutable.scala +pos/spec-partialmap.scala +pos/tcpoly_seq.scala +pos/partialfun.scala +pos/t2795-new.scala +pos/clsrefine.scala +pos/t0774 +pos/t1070.scala +pos/t5957 +pos/looping-jsig.scala +pos/t3274.scala +pos/spec-fields-old.scala +pos/t262.scala +pos/t7486.scala +pos/t2261.scala +pos/t6600.scala +pos/t4786.scala +pos/t5406.scala +pos/tcpoly_late_method_params.scala +pos/t2726 +pos/pos-bug1210.scala +pos/t3312.scala +pos/manifest1-old.scala +pos/gadt-gilles.scala +pos/t4842.scala +pos/ted.scala +pos/NoCyclicReference.scala +pos/t3568.scala +pos/t0030.scala +pos/t2635.scala +pos/t7232b +pos/t0017.scala +pos/t812.scala +pos/t2179.scala +pos/t651.scala +pos/spurious-overload.scala +pos/t758.scala +pos/t4760.scala +pos/t1672.scala +pos/mixins.scala +pos/patterns.scala +pos/t1260.scala +pos/t6551.scala +pos/t2060.scala +pos/t6575a.scala +pos/t1318.scala +pos/t4266.scala +pos/t0695 +pos/protected-static +pos/t5738.scala +pos/t1226.scala +pos/t5013 +pos/t6215.scala +pos/t5692b +pos/traits.scala +pos/t2994a.scala +pos/t3371.scala +pos/t613.scala +pos/t6499.scala +pos/xlint1.scala +pos/t1150 +pos/test4a.scala +pos/t2664.scala +pos/t3528.scala +pos/t3174.scala +pos/t6994.scala +pos/t4812.scala +pos/t5777.scala +pos/t5223.scala +pos/t439.scala +pos/t3079.scala +pos/t5829.scala +pos/t0036.scala +pos/scoping2.scala +pos/t4717.scala +pos/t4257.scala +pos/t1210a.scala +pos/getClassType.scala +pos/t5330.scala +pos/t4524.scala +pos/t2945.scala +pos/t6562.scala +pos/t0273.scala +pos/override-object-yes.scala +pos/t7426.scala +pos/t6601 +pos/t3076 +pos/seq-ordering.scala +pos/spec-groups.scala +pos/t296.scala +pos/t5545 +pos/spec-multiplectors.scala +pos/t1789.scala +pos/t2569 +pos/ksbug1.scala +pos/t0599.scala +pos/local-objects.scala +pos/t0081.scala +pos/t5756.scala +pos/t7126.scala +pos/t7716.scala +pos/t2797.scala +pos/t5399.scala +pos/t1101 +pos/t767.scala +pos/contrib467.scala +pos/t7532b +pos/self-type-override.scala +pos/t4853.scala +pos/t839.scala +pos/t5644 +pos/t5853.scala +pos/t5178.scala +pos/unapplyNeedsMemberType.scala +pos/t5390.scala +pos/t6575b.scala +pos/t151.scala +pos/t2665.scala +pos/t5120.scala +pos/erasure-nsquared.scala +pos/arrays3.scala +pos/t3136.scala +pos/inline-access-levels +pos/t3972.scala +pos/t2591.scala +pos/t3486 +pos/variances-flip.scala +pos/annotated-original +pos/typesafecons.scala +pos/stable.scala +pos/t1996.scala +pos/t3037.scala +pos/t1711 +pos/t3374.scala +pos/t0029.scala +pos/t3278.scala +pos/matthias3.scala +pos/t5546.scala +pos/t4020.scala +pos/matthias4.scala +pos/value-class-override-spec.scala +pos/arrays2.scala +pos/t5119.scala +pos/t2613.scala +pos/t4070b.scala +pos/virtpatmat_exist_uncurry.scala +pos/modules1.scala +pos/spec-constr-new.scala +pos/t6335.scala +pos/t675.scala +pos/t0644.scala +pos/t5892.scala +pos/t360.scala +pos/override.scala +pos/t1798.scala +pos/strip-tvars-for-lubbasetypes.scala +pos/hk-infer.scala +pos/t2119.scala +pos/t0231.scala +pos/t1459 +pos/t1381-new.scala +pos/t2610.scala +pos/t2708.scala +pos/t5604b +pos/t3951 +pos/t361.scala +pos/t319.scala +pos/largecasetest.scala +pos/switchUnbox.scala +pos/typetags.scala +pos/java-access-pos +pos/t803.scala +pos/t3898.scala +pos/t5692a +pos/t2421.scala +pos/t1102 +pos/t0654.scala +pos/exhaust_alternatives.scala +pos/t807.scala +pos/t5702-pos-infix-star.scala +pos/t1186 +pos/t1439.scala +pos/t7427.scala +pos/virtpatmat_binding_opt.scala +pos/t247.scala +pos/abstract.scala +pos/gen-traversable-methods.scala +pos/t2795-old.scala +pos/t5639 +pos/t2667.scala +pos/t2405.scala +pos/t1438.scala +pos/SI-7100.scala +pos/t1659.scala +pos/unchecked-a.scala +pos/t3636.scala +pos/t6745.scala +pos/t2809.scala +pos/t7022.scala +pos/t6447.scala +pos/t6367.scala +pos/t5846.scala +pos/lubs.scala +pos/t1987a.scala +pos/spec-arrays.scala +pos/virtpatmat_anonfun_for.scala +pos/listpattern.scala +pos/t5742.scala +pos/test5refine.scala +pos/t5604 +pos/return_thistype.scala +pos/t348plus.scala +pos/t3420.scala +pos/t3440.scala +pos/maxim1.scala +pos/caseClassInMethod.scala +pos/t3833.scala +pos/t6675.scala +pos/t4402 +pos/t5953.scala +pos/t1152 +pos/t0591.scala +pos/t210.scala +pos/t7035.scala +pos/t5769.scala +pos/pmbug.scala +pos/t2331.scala +pos/t5240.scala +pos/t304.scala +pos/annotated-treecopy +pos/t2081.scala +pos/t0904.scala +pos/t7649.scala +pos/t3498-new.scala +pos/contrib701.scala +pos/t6624.scala +pos/t3924.scala +pos/t374.scala +pos/t1642 +pos/t1591_pos.scala +pos/depmet_implicit_oopsla_session_2.scala +pos/t5899.scala +pos/thistype.scala +pos/t4176b.scala +pos/elidable-tparams.scala +pos/lambdalift.scala +pos/nothing_manifest_disambig-old.scala +pos/t372.scala +pos/t5399a.scala +pos/t2782.scala +pos/patmat-extract-tparam.scala +pos/t4114.scala +pos/unapplyVal.scala +pos/t2486.scala +pos/t5877b.scala +pos/t0625.scala +pos/t6358_2.scala +pos/viewtest1.scala +pos/t1237.scala +pos/scala-singleton.scala +pos/t1254 +pos/t5504 +pos/bounds.scala +pos/t3631.scala +pos/t3177.scala +pos/unapplyContexts2.scala +pos/t0438.scala +pos/t1642b.scala +pos/inferbroadtype.scala +pos/t1858.scala +pos/t3731.scala +pos/t6963c.scala +pos/classtag-pos.scala +pos/t6221.scala +pos/t3343.scala +pos/spec-asseenfrom.scala +pos/t604.scala +pos/spec-example1.scala +pos/t0786.scala +pos/annot-inner.scala +pos/t5886.scala +pos/t1056.scala +pos/t294 +pos/spec-Function1.scala +pos/t1836 +pos/spec-private.scala +pos/depmet_implicit_tpbetareduce.scala +pos/exhaust_2.scala +pos/t7532 +pos/t5175.scala +pos/t802.scala +pos/t5809.scala +pos/tcpoly_typesub.scala +pos/t6029.scala +pos/contextbounds-implicits-new.scala +pos/t3480.scala +pos/patterns3.scala +pos/caseaccs.scala +pos/spec-sparsearray-old.scala +pos/patterns1213.scala +pos/spec-traits.scala +pos/t0020.scala +pos/cycle +pos/t5968.scala +pos/typealiases.scala +pos/init.scala +pos/t697.scala +pos/t2693.scala +pos/t2377 +pos/unapplyGeneric.scala +pos/t1385.scala +pos/t3363-old.scala +pos/t1236.scala +pos/t0068.scala +pos/t4052.scala +pos/lambdalift1.scala +pos/z1730.scala +pos/variances-local.scala +pos/virtpatmat_gadt_array.scala +pos/t2421_delitedsl.scala +pos/t5626.scala +pos/t690.scala +pos/t711.scala +pos/t1937 +pos/t3999 +pos/t2305.scala +pos/t2168.scala +pos/t2660.scala +pos/t1693.scala +pos/t2799.scala +pos/t6966.scala +pos/t1001.scala +pos/S5.scala +pos/t0301.scala +pos/t1048.scala +pos/t415.scala +pos/t6386.scala +pos/t2187.scala +pos/hashhash-overloads.scala +pos/t6921.scala +pos/t0227.scala +pos/t6556.scala +pos/t3946 +pos/t1053.scala +pos/t1000.scala +pos/t0586.scala +pos/t7011.scala +pos/t7329.scala +pos/t4975.scala +pos/t1131.scala +pos/t1027.scala +pos/t2913.scala +pos/t3494.scala +pos/t5606.scala +pos/t4716.scala +pos/tcpoly_gm.scala +pos/t4859.scala +pos/t514.scala +pos/lexical.scala +pos/t2624.scala +pos/t4036.scala +pos/t2741 +pos/t703.scala +pos/five-dot-f.scala +pos/t805.scala +pos/strings.scala +pos/t2433 +pos/t6925.scala +pos/t1085.scala +pos/t7461 +pos/t1942 +pos/spec-lists.scala +pos/t3349 +pos/tcpoly_infer_ticket474.scala +pos/t1614 +pos/virtpatmat_reach_const.scala +pos/t2194.scala +pos/t6976 +pos/t1560.scala +pos/t6891.scala +pos/t3883.scala +pos/infersingle.scala +pos/gui.scala +pos/t1164.scala +pos/t3175-pos.scala +pos/t4336.scala +pos/annotations2.scala +pos/proj-rec-test.scala +pos/t2973.scala +pos/t1123.scala +pos/t6205.scala +pos/t5727.scala +pos/t6537.scala +pos/t6712.scala +pos/t3866.scala +pos/t4831.scala +pos/selftails.scala +pos/t397.scala +pos/spec-vector.scala +pos/t7233b.scala +pos/t1391.scala +pos/spec.scala +pos/t3106.scala +pos/contextbounds-implicits-old.scala +pos/packageobjs.scala +pos/michel3.scala +pos/t628.scala +pos/collections.scala +pos/tcpoly_boundedmonad.scala +pos/t7668.scala +pos/t0032.scala +pos/t0069.scala +pos/t4345.scala +pos/t3521 +pos/t3071.scala +pos/tcpoly_infer_easy.scala +pos/t289.scala +pos/t4365 +pos/rangepos-anonapply.scala +pos/t5033.scala +pos/lambda.scala +pos/S8.scala +pos/t6014.scala +pos/t1785.scala +pos/t6034.scala +pos/t7433.scala +pos/imp2-pos.scala +pos/t0504.scala +pos/t1272.scala +pos/t0612 +pos/value-class-override-no-spec.scala +pos/overloaded-unapply.scala +pos/t5859.scala +pos/chang +pos/localmodules.scala +pos/t4237.scala +pos/rangepos-patmat.scala +pos/t1974.scala +pos/t0054.scala +pos/michel2.scala +pos/t0770.scala +pos/t1146.scala +pos/t2441pos.scala +pos/t5099.scala +pos/tcpoly_seq_typealias.scala +pos/t946.scala +pos/tcpoly_infer_ticket1864.scala +pos/t4737 +pos/t7377b.scala +pos/t616.scala +pos/t201.scala +pos/t6355pos.scala +pos/escapes2.scala +pos/t1675.scala +pos/t3890.scala +pos/t6040.scala +pos/spec-tailcall.scala +pos/existentials.scala +pos/t5317.scala +pos/t7782b.scala +pos/t4758.scala +pos/t7296.scala +pos/t6896.scala +pos/cls1.scala +pos/t402.scala +pos/gosh.scala +pos/t2619.scala +pos/javaConversions-2.10-regression.scala +pos/t759.scala +pos/t5259.scala +pos/t5130.scala +pos/t5156.scala +pos/t0905.scala +pos/package-implicit +pos/t2669.scala +pos/trait-parents.scala +pos/virtpatmat_exhaust.scala +pos/patterns1.scala +pos/t1231 +pos/t1751 +pos/t7233.scala +pos/t6022.scala +pos/tcpoly_checkkinds_mix.scala +pos/depmet_implicit_norm_ret.scala +pos/package-case.scala +pos/philippe4.scala +pos/michel6.scala +pos/t4188.scala +pos/t3936 +pos/t1280.scala +pos/t6722.scala +pos/t796.scala +pos/t5542.scala +pos/t3927.scala +pos/t2293.scala +pos/t3800.scala +pos/t7285a.scala +pos/t927.scala +pos/t4494.scala +pos/t3864 +pos/ilya2 +pos/t2940 +pos/S1.scala +pos/tcpoly_wildcards.scala +pos/tryexpr.scala +pos/t6089b.scala +pos/depmet_implicit_oopsla_zipwith.scala +pos/t245.scala +pos/t6146.scala +pos/t1782 +pos/t851.scala +pos/spec-thistype.scala +pos/tcpoly_poly.scala +pos/t6815_import.scala +pos/t4649.scala +pos/t0453.scala +pos/t5020.scala +pos/ilya +pos/t2435.scala +pos/t1279a.scala +pos/t1957.scala +pos/gadts2.scala +pos/t3567 +pos/Z.scala +pos/t1203b +pos/nested2.scala +pos/t1896 +pos/viewtest2.scala +pos/t5541.scala +pos/existentials-harmful.scala +pos/t4063.scala +pos/t6485a +pos/t1208.scala +pos/t5041.scala +pos/unapplyComplex.scala +pos/t3384.scala +pos/t4112.scala +pos/t788.scala +pos/hklub0.scala +pos/t757.scala +pos/t1197 +pos/t359.scala +pos/t5667.scala +pos/t1107a.scala +pos/virtpatmat_castbinder.scala +pos/t267.scala +pos/t3419 +pos/t3861.scala +pos/t6797.scala +pos/spec-localdefs.scala +pos/t3404 +pos/t4457_1.scala +pos/matthias5.scala +pos/spec-polymeth.scala +pos/kinds.scala +pos/t2310.scala +pos/t6552.scala +pos/valdefs.scala +pos/hkarray.scala +pos/homonym.scala +pos/t1235 +pos/t3429 +pos/t0053.scala +pos/depmet_implicit_chaining_zw.scala +pos/virtpatmat_partialfun_nsdnho.scala +pos/t6664.scala +pos/ticket2251.scala +pos/t3495.scala +pos/super +pos/t121.scala +pos/javaConversions-2.10-ambiguity.scala +pos/t1803.scala +pos/t5877.scala +pos/t0085.scala +pos/t3582.scala +pos/t2939.scala +pos/t1422_pos.scala +pos/manifest1-new.scala +pos/t7505.scala +pos/t5720-ownerous.scala +pos/misc-unapply_pos.scala +pos/tcpoly_variance_pos.scala +pos/t5127.scala +pos/t6123-explaintypes-implicits.scala +pos/t2764 +pos/presuperContext.scala +pos/spec-simple.scala +pos/t3120 +pos/tcpoly_infer_ticket716.scala +pos/tcpoly_bounds1.scala +pos/t7369.scala +pos/imports-pos.scala +pos/t5654.scala +pos/t0123.scala +pos/raw-map +pos/t5330b.scala +pos/t6485b +pos/t6072.scala +pos/t5692c.scala +pos/tcpoly_param_scoping.scala +pos/t6204-b.scala +pos/attachments-typed-another-ident +pos/t5359.scala +pos/ticket2197.scala +pos/t720.scala +pos/t2130-2.scala +pos/t2260.scala +pos/t0304.scala +pos/t464.scala +pos/spec-maps.scala +pos/annotDepMethType.scala +pos/t6117.scala +pos/t911.scala +pos/t757a.scala +pos/t2504.scala +pos/t1381-old.scala +pos/t1232 +pos/needstypeearly.scala +pos/moduletrans.scala +pos/t4957.scala +pos/kinzer.scala +pos/t318.scala +pos/widen-existential.scala +pos/t0095.scala +pos/t566.scala +pos/tcpoly_overloaded.scala +pos/t7516 +pos/t7232 +pos/t698.scala +pos/t0002.scala +pos/t0288 +pos/t2994b.scala +pos/cls.scala +pos/t3622 +pos/t3671.scala +pos/tcpoly_subst.scala +pos/t5703 +pos/depmet_implicit_oopsla_session_simpler.scala +pos/t5022.scala +pos/builders.scala +pos/spec-foo.scala +pos/t756.scala +pos/t1569.scala +pos/implicit-unwrap-tc.scala +pos/t3688.scala +pos/t5198.scala +pos/t432.scala +pos/t6022b.scala +pos/channels.scala +pos/t1075.scala +pos/null.scala +pos/t1840 +pos/t6479.scala +pos/t6311.scala +pos/t0039.scala +pos/t1119.scala +pos/t573.scala +pos/t1136.scala +pos/t3938 +pos/spec-sealed.scala +pos/tcpoly_return_overriding.scala +pos/t3582b.scala +pos/t229.scala +pos/t3498-old.scala +pos/t531.scala +pos/t4545.scala +pos/t6651.scala +pos/t2133.scala +pos/tinondefcons.scala +pos/t6358.scala +pos/t7690.scala +pos/t5779-numeq-warn.scala +pos/list-extractor.scala +pos/t892.scala +pos/t2127.scala +pos/t7180.scala +pos/nullary_poly.scala +pos/virtpatmat_exist3.scala +pos/t1176 +pos/spec-funs.scala +pos/specialize10.scala +pos/t6514.scala +pos/exhaustive_heuristics.scala +pos/t0066.scala +pos/t460.scala +pos/t2130-1.scala +pos/t124.scala +pos/annotations.scala +pos/pat_gilles.scala +pos/array-interfaces.scala +pos/t6210.scala +pos/t3792.scala +pos/implicits-old.scala +pos/t389.scala +pos/t115.scala +pos/virtpatmat_exhaust_unchecked.scala +pos/scoping3.scala +pos/t6033.scala +pos/depmet_implicit_oopsla_session.scala +pos/t602.scala +pos/test5.scala +pos/t611.scala +pos/t5932.scala +pos/t4910.scala +pos/unapplySeq.scala +pos/t344.scala +pos/t3363-new.scala +pos/t4018.scala +pos/t4553.scala +pos/t5082.scala +pos/t3869.scala +pos/t3836.scala +pos/tcpoly_typeapp.scala +pos/t1409 +pos/nonlocal-unchecked.scala +pos/t0082.scala +pos/z1720.scala +pos/t7232c +pos/t2018.scala +pos/t3943 +pos/t2187-2.scala +pos/unicode-decode.scala +pos/t4757 +pos/t0710.scala +pos/t0305.scala +pos/t160.scala +pos/t7591 +pos/simplelists.scala +pos/List1.scala +pos/t516.scala +pos/t6648.scala +pos/t5165 +pos/t0055.scala +pos/t4744 +pos/t7377 +pos/t5726.scala +pos/t0091.scala +pos/t6595.scala +pos/compile.scala +pos/depmet_1_pos.scala +pos/t7364 +pos/philippe3.scala +pos/spec-doubledef-old.scala +pos/t4651.scala +pos/tcpoly_infer_implicit_tuple_wrapper.scala +pos/t6274.scala +pos/tcpoly_infer_explicit_tuple_wrapper.scala +pos/ticket2201.scala +pos/spec-fields-new.scala +pos/optmatch.scala +pos/t7517.scala +pos/t3560.scala +pos/t0165.scala +pos/t0872.scala +pos/t522.scala +pos/t2234.scala +pos/t5031_2.scala +pos/tcpoly_method.scala +pos/t6482.scala +pos/pos-bug1241.scala +pos/implicits-new.scala +pos/t2484.scala +pos/t2425.scala +pos/t1049.scala +pos/michel4.scala +pos/t5958.scala +pos/virtpatmat_instof_valuetype.scala +pos/spec-t6286.scala +pos/t873.scala +pos/t3137.scala +pos/Transactions.scala +pos/t0064.scala +pos/t7486-named.scala +pos/t5444.scala +pos/simple-exceptions.scala +pos/t1006.scala +pos/t7200b.scala +pos/t3777.scala +pos/t4840.scala +pos/t211.scala +pos/nullary.scala +pos/michel1.scala +pos/t5031_3 +pos/typealias_dubious.scala +pos/spec-doubledef-new.scala +pos/philippe1.scala +pos/thistypes.scala +pos/t3570.scala +pos/t6516.scala +pos/context.scala +pos/t3808.scala +pos/philippe2.scala +pos/constfold.scala +pos/t1292.scala +pos/t1147.scala +pos/t404.scala +pos/t4430.scala +pos/A.scala +pos/spec-partially.scala +pos/t5796.scala +pos/t2409 +pos/t284-pos.scala +pos/t5313.scala +pos/t2464 +pos/t1591b.scala +pos/hk-match +pos/t595.scala +pos/t6846.scala +pos/t6162-inheritance.scala +pos/relax_implicit_divergence.scala +pos/patterns2.scala +pos/t4692.scala +pos/t3837.scala +pos/t661.scala +pos/t2810.scala +pos/depexists.scala +pos/virtpatmat_exist4.scala +pos/t5245.scala +pos/t7190.scala +pos/isApplicableSafe.scala +pos/t6204-a.scala +pos/t0076.scala +pos/t1756.scala +pos/t1745 +pos/t6091.scala +pos/t0154.scala +pos/t530.scala +pos/t2094.scala +pos/t1034.scala +pos/t6084.scala +pos/t2454.scala +pos/t2956 +pos/tcpoly_ticket2096.scala +pos/attachments-typed-ident +pos/polymorphic-case-class.scala +pos/t252.scala +pos/spec-constr-old.scala +pos/t2421c.scala +pos/t122.scala +pos/t6574.scala +pos/t3859.scala +pos/spec-params-old.scala +pos/t1196 +pos/t4593.scala +pos/t596.scala +pos/t615.scala +pos/t7689.scala +pos/t3960.scala +pos/t3986.scala +pos/exbound.scala +pos/t2545.scala +pos/t1722 +pos/t159.scala +pos/t3272.scala +pos/t6301.scala +pos/t2794.scala +pos/t3048.scala +pos/t4970.scala +pos/t607.scala +pos/FPTest.scala +pos/test1.scala +pos/t4176.scala +pos/t112606A.scala +pos/t2183.scala +pos/t430-feb09.scala +pos/t6275.scala +pos/t1832.scala +pos/t8965.scala +pos/t7596b +pos/t8900.scala +pos/t9008.scala +pos/t7704.scala +pos/t7459c.scala +pos/sammy_override.scala +pos/t8828.scala +pos/t8868c +pos/t7459d.scala +pos/t8267.scala +pos/t8844.scala +pos/t8868a +pos/t8894.scala +pos/t7459a.scala +pos/t7596c +pos/t8498.scala +pos/t8868b +pos/t5413.scala +pos/t8781 +pos/t8934a +pos/t8310.scala +pos/t3439.scala +pos/t6582_exhaust_big.scala +pos/t8954 +pos/t5217.scala +pos/t7459b.scala +pos/t9018.scala +pos/sammy_exist.scala +pos/t8893.scala +pos/t7596 +pos/t8793.scala +pos/sammy_overload.scala +pos/t6051.scala +pos/t7683-stop-after-parser +pos/t7750.scala +pos/t5454.scala +pos/t8962.scala +pos/t8947 +pos/t8719 +pos/t8410.scala +pos/patmat-suppress.scala +pos/t8999.scala +pos/t8743.scala +pos/t9157.scala +pos/t8801.scala +pos/t9086.scala +pos/t9050.scala +pos/t9135.scala +pos/t9116.scala +pos/t5154.scala +pos/t3368.scala +pos/t9321.scala +pos/t9285.scala +pos/t8861.scala +pos/t9020.scala +pos/jesper.scala +pos/t9356 +pos/virtpatmat_exhaust_big.scala +pos/t9239 +pos/t9111-inliner-workaround +pos/t9181.scala + +neg/volatile_no_override.scala +neg/t800.scala +neg/t5426.scala +neg/t2462a.scala +neg/t2641.scala +neg/classtags_dont_use_typetags.scala +neg/t5031 +neg/t2275b.scala +neg/macro-qmarkqmarkqmark.scala +neg/t4879.scala +neg/t5956.scala +neg/t4196.scala +neg/reify_ann2b.scala +neg/t6666b.scala +neg/warn-unused-privates.scala +neg/t6928.scala +neg/t6337.scala +neg/sealed-java-enums.scala +neg/t563.scala +neg/t900.scala +neg/deadline-inf-illegal.scala +neg/t766.scala +neg/t5429.scala +neg/overloaded-implicit.scala +neg/t875.scala +neg/abstract-class-error +neg/unchecked2.scala +neg/predef-masking.scala +neg/viewtest.scala +neg/macro-noexpand +neg/varargs.scala +neg/t963b.scala +neg/t909.scala +neg/sensitive2.scala +neg/t5390b.scala +neg/abstraction-from-volatile-type-error.scala +neg/macro-exception +neg/t4431.scala +neg/t5689.scala +neg/valueclasses.scala +neg/overload.scala +neg/t0204.scala +neg/t908.scala +neg/t750 +neg/patmatexhaust.scala +neg/macro-invalidusage-badtargs +neg/t1168.scala +neg/t5761.scala +neg/t0503.scala +neg/t7235.scala +neg/t1215.scala +neg/primitive-sigs-1 +neg/t5578.scala +neg/names-defaults-neg-warn.scala +neg/t6436b.scala +neg/t3098 +neg/t910.scala +neg/parstar.scala +neg/t4568.scala +neg/newpat_unreachable.scala +neg/t1181.scala +neg/t5903c +neg/t7294.scala +neg/t4091.scala +neg/t5452-old.scala +neg/t5696.scala +neg/t0209.scala +neg/t2910.scala +neg/t7388.scala +neg/noMember2.scala +neg/no-predef.scala +neg/t6952.scala +neg/t1909b.scala +neg/abstract-report2.scala +neg/t5318.scala +neg/t6074.scala +neg/t7171.scala +neg/abstract-vars.scala +neg/unchecked-impossible.scala +neg/variances-refinement.scala +neg/t3453.scala +neg/t5189.scala +neg/t4302.scala +neg/xmltruncated7.scala +neg/t8217-local-alias-requires-rhs.scala +neg/t7602.scala +neg/t8869.scala +neg/t9008.scala +neg/sammy_error_exist_no_crash.scala +neg/t2866.scala +neg/t8597b.scala +neg/t5691.scala +neg/t8534b.scala +neg/t5091.scala +neg/literals.scala +neg/t8534.scala +neg/t8890.scala +neg/t9008b.scala +neg/t8731.scala +neg/t8291.scala +neg/t8597.scala +neg/t5639b +neg/t6582_exhaust_big.scala +neg/t8841.scala +neg/t9041.scala +neg/t9093.scala +neg/t7623.scala +neg/t9231.scala +neg/t9286b.scala +neg/t9273.scala +neg/t9127.scala +neg/t9286c.scala +neg/t9286a.scala +neg/virtpatmat_exhaust_big.scala +neg/inlineMaxSize.scala +neg/patmatexhaust-huge.scala + +run/t7249.scala +run/t3563.scala +run/t6111.scala +run/classtags_multi.scala +run/t5201.scala +run/checked.scala +run/valueclasses-classtag-basic.scala +run/t7171.scala +run/t5053.scala +run/t4535.scala +run/t5923d +run/t7291.scala +run/partialfun.scala +run/macro-term-declared-in-package-object +run/mapValues.scala +run/gadts.scala +run/t2386-new.scala +run/virtpatmat_stringinterp.scala +run/t657.scala +run/t0017.scala +run/t5713 +run/t576.scala +run/t3580.scala +run/virtpatmat_partial.scala +run/t6646.scala +run/mixins.scala +run/t1672.scala +run/macro-expand-implicit-macro-has-implicit +run/tuple-match.scala +run/t7039.scala +run/virtpatmat_opt_sharing.scala +run/virtpatmat_casting.scala +run/t2176.scala +run/eta-expand-star2.scala +run/macro-impl-relaxed +run/intmap.scala +run/t751.scala +run/t1591.scala +run/macro-typecheck-implicitsdisabled +run/t6911.scala +run/t5604.scala +run/macro-term-declared-in-default-param +run/collection-stacks.scala +run/multi-array.scala +run/t4560b.scala +run/buffer-slice.scala +run/t5629.scala +run/t6690.scala +run/matchonstream.scala +run/t3603.scala +run/lazy-exprs.scala +run/macro-quasiquotes +run/Course-2002-13.scala +run/t6337a.scala +run/exoticnames.scala +run/t0936.scala +run/runtime-richChar.scala +run/t6272.scala +run/t7215.scala +run/t1939.scala +run/ReverseSeqView.scala +run/lazy-leaks.scala +run/t0048.scala +run/t3994.scala +run/t2241.scala +run/t627.scala +run/t5966.scala +run/getClassTest-valueClass.scala +run/t3619.scala +run/t1300.scala +run/t2177.scala +run/t3760.scala +run/t1829.scala +run/macro-expand-implicit-macro-is-view +run/t889.scala +run/QueueTest.scala +run/t4537 +run/t3699.scala +run/t1192.scala +run/macro-expand-tparams-bounds +run/macro-expand-nullary-generic +run/t1434.scala +run/t6443-varargs.scala +run/macro-term-declared-in-trait +run/t4080.scala +run/matcharraytail.scala +run/infiniteloop.scala +run/t5733.scala +run/virtpatmat_nested_lists.scala +run/t5158.scala +run/t6695.scala +run/t6070.scala +run/t4558.scala +run/exc2.scala +run/patmat-behavior-2.scala +run/overloads.scala +run/t6957.scala +run/transform.scala +run/t5500.scala +run/t6663.scala +run/castsingleton.scala +run/t4147.scala +run/virtpatmat_staging.scala +run/t4565_1.scala +run/t5588.scala +run/run-bug4840.scala +run/t3496.scala +run/t5867.scala +run/search.scala +run/t3112.scala +run/hashsetremove.scala +run/t6443.scala +run/macro-expand-tparams-prefix +run/contrib674.scala +run/t3508.scala +run/t4300.scala +run/virtpatmat_typed.scala +run/macro-term-declared-in-class-object +run/map_test.scala +run/t5040.scala +run/t4827b.scala +run/lift-and-unlift.scala +run/t6574b.scala +run/t7240 +run/t3984.scala +run/virtpatmat_tailcalls_verifyerror.scala +run/macro-term-declared-in-class-class +run/emptypf.scala +run/t6104.scala +run/t2818.scala +run/t3761-overload-byname.scala +run/t2526.scala +run/phantomValueClass.scala +run/t3126.scala +run/arybufgrow.scala +run/t3980.scala +run/t7375b +run/t6077_patmat_cse_irrefutable.scala +run/classmanifests_new_core.scala +run/t3395.scala +run/name-based-patmat.scala +run/inliner-infer.scala +run/t5171.scala +run/t3726.scala +run/null-hash.scala +run/t4027.scala +run/t2544.scala +run/patmatnew.scala +run/t5923b +run/t7242.scala +run/classtags_core.scala +run/streamWithFilter.scala +run/t3038b.scala +run/macro-expand-varargs-explicit-over-nonvarargs-good +run/macro-divergence-spurious +run/macro-duplicate +run/t2958.scala +run/patch-boundary.scala +run/t2333.scala +run/lazy-override-run.scala +run/macro-quasiinvalidbody-c +run/t5037.scala +run/takeAndDrop.scala +run/t6126.scala +run/t0883.scala +run/t7617a +run/t4171.scala +run/empty-array.scala +run/t7198.scala +run/t493.scala +run/genericValueClass.scala +run/t0677-old.scala +run/t1373.scala +run/t4461.scala +run/t6011b.scala +run/t7584.scala +run/t3935.scala +run/t6928-run.scala +run/t744.scala +run/t3241.scala +run/blame_eye_triple_eee-double.scala +run/t3829.scala +run/t5577.scala +run/t5914.scala +run/t601.scala +run/t5610.scala +run/macro-basic-mamd-mi +run/t6150.scala +run/stringbuilder.scala +run/t7290.scala +run/t6888.scala +run/t6327.scala +run/virtpatmat_unapplyseq.scala +run/t4656.scala +run/macro-term-declared-in-method +run/macro-expand-implicit-macro-is-implicit +run/blame_eye_triple_eee-float.scala +run/t4482.scala +run/t5488.scala +run/matchemptyarray.scala +run/t3714.scala +run/richWrapperEquals.scala +run/t5328.scala +run/stream_flatmap_odds.scala +run/implicitclasses.scala +run/t6394b +run/complicatedmatch.scala +run/valueclasses-classmanifest-basic.scala +run/unreachable.scala +run/caseclasses.scala +run/withIndex.scala +run/exc1.scala +run/amp.scala +run/t1423.scala +run/t594.scala +run/t6353.scala +run/byname.scala +run/vector1.scala +run/t5879.scala +run/t1048.scala +run/t5080.scala +run/t4190.scala +run/caseClassEquality.scala +run/macro-enclosures +run/collections-toSelf.scala +run/implicits.scala +run/finalvar.scala +run/lazy-locals.scala +run/t7231.scala +run/t0508.scala +run/t6628.scala +run/t6406-regextract.scala +run/t0911.scala +run/t4013c.scala +run/t3502.scala +run/t5648.scala +run/retclosure.scala +run/t2857.scala +run/t4859.scala +run/t5162.scala +run/t3038.scala +run/classof.scala +run/t4062.scala +run/unapplyArray.scala +run/t4297.scala +run/t5923a +run/t1537.scala +run/boolexprs.scala +run/valueclasses-classtag-generic.scala +run/macro-term-declared-in-anonymous +run/tcpoly_monads.scala +run/t5407.scala +run/scan.scala +run/forvaleq.scala +run/null-and-intersect.scala +run/t7047 +run/t0607.scala +run/sequenceComparisons.scala +run/t4396.scala +run/macro-undetparams-consfromsls +run/t2029.scala +run/t1220.scala +run/option-fold.scala +run/t5284c.scala +run/macro-auto-duplicate +run/t3529.scala +run/t4697.scala +run/t2251.scala +run/t5300.scala +run/virtpatmat_valdef.scala +run/t2147.scala +run/virtpatmat_extends_product.scala +run/list_map.scala +run/t1333.scala +run/matchbytes.scala +run/valueclasses-classmanifest-existential.scala +run/records.scala +run/t3088.scala +run/macro-def-path-dependent +run/t6443-by-name.scala +run/t1044.scala +run/delay-good.scala +run/case-class-23.scala +run/weakconform.scala +run/patmat-bind-typed.scala +run/t4835.scala +run/t3097.scala +run/t405.scala +run/existentials.scala +run/t2876.scala +run/t4809.scala +run/t1427.scala +run/t6135.scala +run/t3575.scala +run/t5688.scala +run/t6900.scala +run/macro-expand-unapply-a +run/t6677b.scala +run/t7375a.scala +run/t7300.scala +run/typed-annotated +run/elidable-noflags.scala +run/t0042.scala +run/t3050.scala +run/t4536.scala +run/NestedClasses.scala +run/t3877.scala +run/seqlike-kmp.scala +run/t5907.scala +run/t266.scala +run/missingparams.scala +run/t2255.scala +run/t3488.scala +run/t3950.scala +run/typealias_overriding.scala +run/constant-optimization.scala +run/t7507.scala +run/t6090.scala +run/t4582.scala +run/macro-term-declared-in-class +run/macro-typecheck-macrosdisabled2 +run/t3425.scala +run/t4935.scala +run/t3326.scala +run/boolord.scala +run/t1141.scala +run/virtpatmat_unapply.scala +run/t5971.scala +run/t3651.scala +run/macro-sip19-revised +run/pure-args-byname-noinline.scala +run/preinits.scala +run/t5532.scala +run/concat-two-strings.scala +run/t3269.scala +run/macro-impl-default-params +run/t2162.scala +run/matchonseq.scala +run/t5428.scala +run/macro-expand-overload +run/t4660.scala +run/enrich-gentraversable.scala +run/macro-expand-override +run/t4054.scala +run/t4753.scala +run/macro-typecheck-macrosdisabled +run/t2308a.scala +run/duplicate-meth.scala +run/interop_classtags_are_classmanifests.scala +run/t3232.scala +run/t2075.scala +run/virtpatmat_partial_backquoted.scala +run/try-2.scala +run/macro-openmacros +run/macro-undetparams-macroitself +run/t6318_derived.scala +run/deprecate-early-type-defs.scala +run/dead-code-elimination.scala +run/t4827.scala +run/Course-2002-07.scala +run/slice-strings.scala +run/t6292.scala +run/t6206.scala +run/t1042.scala +run/t1718.scala +run/t2074_2.scala +run/arraycopy.scala +run/indexedSeq.scala +run/macro-term-declared-in-implicit-class +run/t3511.scala +run/t6290.scala +run/distinct.scala +run/virtpatmat_alts.scala +run/valueclasses-pavlov.scala +run/exceptions.scala +run/t1368.scala +run/t5856.scala +run/t6968.scala +run/names-defaults.scala +run/macro-expand-tparams-implicit +run/t5881.scala +run/t3540.scala +run/virtpatmat_try.scala +run/t7181.scala +run/value-class-extractor.scala +run/value-class-extractor-2.scala +run/t3150.scala +run/exc.scala +run/delay-bad.scala +run/infix.scala +run/t1309.scala +run/t6370.scala +run/t6725-2.scala +run/macro-impl-tparam-typetag-is-optional +run/macro-term-declared-in-block +run/matchnull.scala +run/t2127.scala +run/t7325.scala +run/groupby.scala +run/t3932.scala +run/t4871.scala +run/longmap.scala +run/t1524.scala +run/t6187b.scala +run/kmpSliceSearch.scala +run/t7088.scala +run/t5804.scala +run/stringbuilder-drop.scala +run/t5753_1 +run/t9223.scala +run/function-null-unbox.scala +run/t9223b.scala +run/disable-assertions.scala +run/valueClassSelfType.scala +run/indylambda-boxing +run/t9219.scala + +pos/cyclics-pos.scala +pos/cfcrash.scala +pos/tcpoly_higherorder_bound_method.scala +pos/t5084.scala +pos/macro-qmarkqmarkqmark.scala +pos/t7785.scala +pos/nested.scala +pos/t3152.scala +pos/t5031 +pos/t6925b.scala +pos/t1107b +pos/t5012.scala +pos/virtpatmat_obj_in_case.scala +pos/t4938.scala +pos/t3856.scala +pos/spec-cyclic.scala +pos/aliases.scala +pos/typerep_pos.scala +pos/t119.scala +pos/t1050.scala +pos/t3670.scala +pos/t6145.scala +pos/t7315.scala +pos/t5930.scala +pos/t789.scala +pos/t5071.scala +pos/t4731.scala +pos/t4547.scala +pos/t2038.scala +pos/testCoercionThis.scala +pos/t2444.scala +pos/t5744 +pos/t780.scala +pos/t1722-A.scala +pos/virtpatmat_exist1.scala +pos/t6225.scala +pos/t762.scala +pos/t0204.scala +pos/rebind.scala +pos/spec-short.scala +pos/comp-rec-test.scala +pos/lub-dealias-widen.scala +pos/t1168.scala +pos/modules.scala +pos/t4220.scala +pos/t4070.scala +pos/t175.scala +pos/t2500.scala +pos/t5029.scala +pos/itay.scala +pos/t4202.scala +pos/t1987b +pos/t3534.scala +pos/infer2-pos.scala +pos/spec-sparsearray-new.scala +pos/t7091.scala +pos/ticket0137.scala +pos/collectGenericCC.scala +pos/t640.scala +pos/t4305.scala +pos/extractor-types.scala +pos/t3880.scala +pos/spec-annotations.scala +pos/t3577.scala +pos/compile1.scala +pos/spec-t3497.scala +pos/hkrange.scala +pos/t287.scala +pos/t6008.scala +pos/t4432.scala +pos/CustomGlobal.scala +pos/patmat.scala +pos/t2413 +pos/t2910.scala +pos/t592.scala +pos/t6245 +pos/infer.scala +pos/t7228.scala +pos/compound.scala +pos/attributes.scala +pos/t6771.scala +pos/t1090.scala +pos/t684.scala +pos/t577.scala +pos/t4273.scala +pos/t6278-synth-def.scala +pos/t6184.scala +neg/t0214.scala +neg/t4842.scala +neg/t6214.scala +neg/reify_nested_inner_refers_to_local.scala +neg/t576.scala +neg/t5969.scala +neg/tcpoly_variance.scala +neg/t7509.scala +neg/mixins.scala +neg/parent-inherited-twice-error.scala +neg/macro-abort +neg/constructor-init-order.scala +neg/t6042.scala +neg/t0590.scala +neg/eta-expand-star-deprecation.scala +neg/t4221.scala +neg/t6263.scala +neg/t783.scala +neg/t5554.scala +neg/macro-invalidsig-params-badtype +neg/multi-array.scala +neg/raw-types-stubs +neg/spec-overrides.scala +neg/t836.scala +neg/t7289_status_quo.scala +neg/t5675.scala +neg/macro-quasiquotes +neg/t6667.scala +neg/t6597.scala +neg/t6264.scala +neg/t0345.scala +neg/t7294b.scala +neg/t5340.scala +neg/t2144.scala +neg/t1010.scala +neg/t1838.scala +neg/t5189b.scala +neg/reify_metalevel_breach_-1_refers_to_1.scala +neg/t6601 +neg/wellkinded_wrongarity.scala +neg/t3909.scala +neg/t876.scala +neg/t5390.scala +neg/unit2anyref.scala +neg/t0351.scala +neg/t5120.scala +neg/t1038.scala +neg/t5878.scala +neg/qualifying-class-error-2.scala +neg/t3816.scala +neg/tailrec.scala +neg/volatile.scala +neg/t944.scala +neg/t1705.scala +neg/t3977.scala +neg/t5553_2.scala +neg/t5318c.scala +neg/overload-msg.scala +neg/t5440.scala +neg/t6335.scala +neg/compile-time-only-b.scala +neg/t501.scala +neg/override.scala +neg/t663.scala +neg/t5892.scala +neg/t1980.scala +neg/macro-false-deprecation-warning +neg/t585.scala +neg/t3776.scala +neg/interop_classtags_arenot_manifests.scala +neg/t4044.scala +neg/macro-invalidusage-nontypeable +neg/t500.scala +neg/t4877.scala +neg/t5357.scala +neg/interop_abstypetags_arenot_manifests.scala +neg/t4460a.scala +neg/t5318b.scala +neg/t4440.scala +neg/t6663.scala +neg/t6357.scala +neg/gadts1.scala +neg/cyclics.scala +neg/t5060.scala +neg/scopes.scala +run/t4013.scala +run/macro-expand-tparams-explicit +run/tuples.scala +run/t5753_2 +run/t0528.scala +run/t5105.scala +run/t7341.scala +run/t3670.scala +run/t2594_tcpoly.scala +run/t3895.scala +run/t0668.scala +run/slices.scala +run/t6666a.scala +run/valueclasses-classmanifest-generic.scala +run/t2316_run.scala +run/t3004.scala +run/viewtest.scala +run/t6481.scala +run/t0005.scala +run/t4766.scala +run/t5500b.scala +run/t7407b.scala +run/backreferences.scala +run/arrayview.scala +run/t629.scala +run/t5903c +run/unittest_collection.scala +run/spec-nlreturn.scala +run/macro-term-declared-in-object-object +run/triple-quoted-expr.scala +run/t5937.scala +run/t6011c.scala +run/macro-expand-implicit-argument +run/try.scala +run/t1987b +run/t6089.scala +run/macro-range +run/t2524.scala +run/t4770.scala +run/virtpatmat_unapplyprod.scala +run/t1535.scala +run/ctor-order.scala +pos/t5210.scala +pos/t5384.scala +pos/rangepos.scala +pos/t443.scala +pos/t1480.scala +pos/t116.scala +pos/seqtest2.scala +pos/scoping1.scala +pos/t4269.scala +pos/lookupswitch.scala +pos/t3642 +pos/t5706.scala +pos/SI-5788.scala +pos/t7264 +pos/t0031.scala +pos/macro-deprecate-dont-touch-backquotedidents.scala +pos/t6815.scala +pos/test4refine.scala +pos/michel5.scala +pos/t0851.scala +pos/t1185.scala +pos/sudoku.scala +pos/t7520.scala +pos/t6208.scala +pos/t3411.scala +pos/t295.scala +pos/S3.scala +pos/t0674.scala +pos/t6664b.scala +pos/variances_pos.scala +pos/liftcode_polymorphic.scala +pos/t3174b.scala +pos/t7232d +pos/t578.scala +pos/implicit-infix-ops.scala +pos/t4363.scala +pos/t532.scala +pos/exponential-spec.scala +pos/t599.scala +pos/t5862.scala +pos/t4603 +pos/t3676.scala +pos/t1357.scala +pos/native-warning.scala +pos/t1230 +pos/t6028 +pos/t4275.scala +pos/overloaded_extractor_and_regular_def.scala +pos/t4205 +pos/matthias1.scala +pos/testcast.scala +pos/generic-sigs.scala +pos/t0093.scala +pos/specializes-sym-crash.scala +pos/t0061.scala +pos/t2429.scala +pos/t694.scala +pos/javaReadsSigs +pos/t2023.scala +pos/t704.scala +pos/t2208_pos.scala +pos/t5137.scala +pos/t2683.scala +pos/t0049.scala +pos/t1029 +pos/t4243.scala +pos/typerep-stephane.scala +pos/t177.scala +pos/t5967.scala +pos/t430.scala +pos/virtpatmat_infer_single_1.scala +pos/pat_iuli.scala +pos/t1071.scala +pos/t7226.scala +pos/t1843.scala +pos/t419.scala +pos/t7364b +pos/t1159.scala +pos/t5305.scala +pos/t7694.scala +pos/t6047.scala +pos/t3578.scala +pos/t2082.scala +pos/setter-not-implicit.scala +pos/t1133.scala +pos/t3862.scala +pos/t942 +pos/nothing_manifest_disambig-new.scala +pos/iterator-traversable-mix.scala +pos/eta.scala +pos/test4.scala +pos/t2691.scala +pos/t4502.scala +pos/t7183.scala +pos/protected-t1010.scala +pos/X.scala +pos/virtpatmat_exist2.scala +pos/t4911.scala +pos/t3477.scala +pos/t4173.scala +pos/t7782.scala +pos/t2399.scala +pos/virtpatmat_alts_subst.scala +pos/propagate.scala +pos/t2421b_pos.scala +pos/t183.scala +pos/t7033.scala +pos/t3612.scala +pos/t5330c.scala +pos/t3020.scala +pos/t4869.scala +pos/t3373.scala +pos/spec-params-new.scala +pos/t3672.scala +pos/t4501.scala +pos/t1565.scala +pos/t3774.scala +pos/t6942 +pos/t845.scala +pos/t3240.scala + +neg/t3275.scala +neg/t421.scala +neg/t5702-neg-bad-brace.scala +neg/t3663 +neg/badtok-1.scala +neg/t677.scala +neg/t7756b.scala +neg/t6534.scala +neg/t6276.scala +neg/t5762.scala +neg/abstract.scala +neg/t2405.scala +neg/t0418.scala +neg/t5390c.scala +neg/lazyvals.scala +neg/lubs.scala +neg/abstract-report.scala +neg/t4163.scala +neg/t5702-neg-bad-and-wild.scala +neg/macro-invalidret +neg/t6728.scala +neg/t5152.scala +neg/t1432.scala +neg/abstract-inaccessible.scala +neg/import-precedence.scala +neg/t2462b.scala +neg/macro-invalidusage-presuper +neg/specification-scopes +neg/t6048.scala +neg/t4079 +neg/macro-basic-mamdmi +neg/t7020.scala +neg/t3015.scala +neg/t0207.scala +neg/t2296b +neg/t0673 +neg/t3761-overload-byname.scala +neg/t6675.scala +neg/t5529.scala +neg/sensitive.scala +neg/t742.scala +neg/t5067.scala +neg/t6162-overriding.scala +neg/variances.scala +neg/t5728.scala +neg/t6323a.scala +neg/compile-time-only-a.scala +neg/t6795.scala +neg/t2494.scala +neg/t3649.scala +neg/macro-invalidsig +neg/t2796.scala +neg/t112706A.scala +neg/t0764.scala +neg/t3757 +neg/t1431.scala +neg/exhausting.scala +neg/t1523.scala +neg/t779.scala +neg/xmltruncated1.scala +neg/t2208.scala +neg/t2078.scala +neg/t521.scala +neg/null-unsoundness.scala +neg/stmt-expr-discard.scala +neg/t0513.scala +neg/unchecked-abstract.scala +neg/t4460c.scala +neg/divergent-implicit.scala +neg/t5078.scala +neg/t1701.scala +neg/t0816.scala +neg/t1672b.scala +neg/macro-invalidusage-badbounds +neg/tailrec-2.scala +neg/t4064.scala +neg/t5510.scala +neg/t3873.scala +neg/tailrec-3.scala +neg/t0226.scala +neg/t2031.scala +neg/t633.scala +neg/constrs.scala +neg/anyval-anyref-parent.scala +neg/t7290.scala +neg/t1041.scala +neg/patternalts.scala +neg/error_tooManyArgsPattern.scala +neg/checksensibleUnit.scala +neg/t6539 +neg/t4417.scala +neg/wellkinded_app.scala +neg/for-comprehension-old.scala +neg/t2779.scala +neg/object-not-a-value.scala +neg/t2968b.scala +neg/t6483.scala +neg/t6902.scala +neg/t6963a.scala +neg/t3399.scala +neg/t0015.scala +neg/t3995.scala +neg/t276.scala +neg/t6758.scala +neg/t2441.scala +neg/cycle-bounds.scala +neg/t1241.scala +neg/t4137.scala +neg/unicode-unterminated-quote.scala +neg/t4762.scala +neg/typeerror.scala +neg/implicits.scala +neg/t961.scala +neg/ambiguous-float-dots2.scala +neg/t2416.scala +neg/t5799.scala +neg/t7285.scala +neg/implicit-shadow.scala +neg/t2388.scala +neg/java-access-neg +neg/found-req-variance.scala +neg/hk-bad-bounds.scala +neg/t3224.scala +neg/t1033.scala +neg/t7385.scala +neg/t5882.scala +neg/t4541.scala +neg/t2973.scala +neg/t6406-regextract.scala +neg/t6666.scala +neg/t4831.scala +neg/t425.scala +neg/t1845.scala +neg/t3683b.scala +neg/t2801.scala +neg/t6083.scala +neg/t0528neg.scala +neg/stringinterpolation_macro-neg.scala +neg/t668.scala +neg/t5666.scala +neg/t4271.scala +neg/interop_typetags_arenot_classmanifests.scala +neg/t1355.scala +neg/t715.scala +neg/t7238.scala +neg/t7473.scala +neg/t7292-removal.scala +neg/tcpoly_infer_ticket1162.scala +neg/t4098.scala +neg/t6013 +neg/t6227.scala +neg/t464-neg.scala +neg/badtok-3.scala +neg/t6082.scala +neg/anytrait.scala +neg/valueclasses-doubledefs.scala +neg/t7519.scala +neg/overloaded-unapply.scala +neg/t1163.scala +neg/wellkinded_bounds.scala +neg/t7292-deprecation.scala +neg/t5044.scala +neg/t0842.scala +neg/t6436.scala +neg/interop_typetags_arenot_classtags.scala +neg/t3653.scala +neg/higherkind_novalue.scala +neg/t935.scala +neg/t6040.scala +neg/annot-nonconst.scala +neg/macro-deprecate-idents.scala +neg/illegal-stmt-start.scala +neg/t565.scala +neg/case-collision.scala +neg/t3209.scala +neg/t5821.scala +neg/abstract-class-2.scala +neg/t846.scala +neg/quasiquotes-syntax-error-position.scala +neg/t3987.scala +neg/t877.scala +neg/t0117.scala +neg/t692.scala +neg/t5702-neg-ugly-xbrace.scala +neg/t7752.scala +neg/case-collision2.scala +neg/t6526.scala +neg/t2213.scala +neg/t7756a.scala +neg/macro-override-macro-overrides-abstract-method-a +neg/tcpoly_ticket2101.scala +neg/delayed-init-ref.scala +neg/caseinherit.scala +neg/t3189.scala +neg/unchecked-suppress.scala +neg/t2180.scala +neg/t1371.scala +neg/macro-cyclic +neg/t6123-explaintypes-macros +neg/t4134.scala +neg/t691.scala +neg/t2421b.scala +neg/t4691_exhaust_extractor.scala +neg/t4419.scala +neg/t5801.scala +neg/t650.scala +neg/t5735.scala +neg/t696.scala +neg/t882.scala +neg/t2968.scala +neg/t7507.scala +neg/macro-invalidusage-badargs +neg/macro-reify-typetag-typeparams-notags +neg/wellkinded_app2.scala +neg/t4425b.scala +neg/t2296a +neg/t1878.scala +neg/t649.scala +neg/override-object-no.scala +neg/t4174.scala +neg/t2070.scala +neg/sabin2.scala +neg/t5903e +neg/t6566a.scala +neg/finitary-error.scala +neg/t4818.scala +neg/t3614.scala +neg/t6666c.scala +neg/ticket513.scala +neg/suggest-similar.scala +neg/t4457_1.scala +neg/t6666e.scala +neg/tcpoly_bounds.scala +neg/t4727.scala +neg/t4425.scala +neg/macro-invalidusage-methodvaluesyntax +neg/t3854.scala +neg/t3006.scala +neg/t5580b.scala +neg/t5378.scala +neg/t639.scala +neg/wrong-args-for-none.scala +neg/t7171b.scala +neg/t5361.scala +neg/unreachablechar.scala +neg/t5572.scala +neg/t7757a.scala +neg/macro-invalidimpl +neg/t2773.scala +neg/t6359.scala +neg/saito.scala +neg/xmltruncated2.scala +neg/t667.scala +neg/t3934.scala +neg/t6771b.scala +neg/t4584.scala +neg/wellkinded_wrongarity2.scala +neg/t7369.scala +neg/t1477.scala +neg/t5617.scala +neg/t7299.scala +neg/faculty.scala +neg/virtpatmat_reach_null.scala +neg/macro-reify-typetag-hktypeparams-notags +neg/t1224.scala +neg/xmltruncated3.scala +neg/t1872.scala +neg/t558.scala +neg/t7110.scala +neg/any-vs-anyref.scala +neg/t6340.scala +neg/t4166.scala +neg/t2918.scala +neg/t5856.scala +neg/t4989.scala +neg/t0003.scala +neg/t1183.scala +neg/t963.scala +neg/t4515.scala +neg/valueclasses-pavlov.scala +neg/t608.scala +neg/choices.scala +neg/patmat-type-check.scala +neg/valueclasses-impl-restrictions.scala +neg/imp2.scala +neg/protected-constructors.scala +neg/t6788.scala +neg/nullary-override.scala +neg/t200.scala +neg/t343.scala +neg/names-defaults-neg-ref.scala +neg/tcpoly_typealias.scala +neg/classtags_contextbound_b.scala +neg/t729.scala +neg/t5683.scala +neg/t4928.scala +neg/t700.scala +neg/t7669.scala +neg/macro-invalidshape +neg/t6011.scala +neg/t7325.scala +neg/check-dead.scala +neg/t550.scala +neg/t5663-badwarneq.scala +neg/t0699 +neg/nopredefs.scala +neg/t3507-old.scala +neg/t5352.scala +neg/t6336.scala +neg/interop_classmanifests_arenot_typetags.scala +neg/sealed-final-neg.scala +neg/t2102.scala +neg/t7636.scala +neg/t5031b +neg/t798.scala +neg/t5702-neg-bad-xbrace.scala +neg/t0899.scala +neg/cyclics-import.scala +neg/badtok-2.scala +neg/t473.scala +neg/t3160ambiguous.scala +neg/t5106.scala +neg/t1286 +neg/macro-override-macro-overrides-abstract-method-b +neg/t0259.scala +neg/t510.scala +neg/t3836.scala +neg/t5830.scala +neg/t1548 +neg/t5580a.scala +neg/forward.scala +neg/t591.scala +neg/t6558b.scala +neg/t556.scala +neg/xmltruncated4.scala +neg/t5497.scala +neg/t409.scala +neg/t6283.scala +neg/override-object-flag.scala +neg/constructor-prefix-error.scala +neg/eta-expand-star.scala +neg/t3392.scala +neg/t1275.scala +neg/nested-fn-print.scala +neg/t7330.scala +neg/t2275a.scala +neg/t630.scala +neg/t4270.scala +neg/t2775.scala +neg/pat_unreachable.scala +neg/t4158.scala +neg/unit-returns-value.scala +neg/t1422.scala +neg/reify_metalevel_breach_-1_refers_to_0_b.scala +neg/reassignment.scala +neg/t3683a.scala +neg/noMember1.scala +neg/macro-without-xmacros-b +neg/t1106.scala +neg/t5182.scala +neg/t6889.scala +neg/t4217.scala +neg/t7501 +neg/t5063.scala +neg/t1009.scala +neg/t997.scala +neg/unchecked.scala +neg/classtags_contextbound_c.scala +neg/applydynamic_sip.scala +neg/t7715.scala +neg/t588.scala +neg/t6667b.scala +neg/t7757b.scala +neg/t4069.scala +neg/t515.scala +neg/variances2.scala +neg/t1049.scala +neg/t7289.scala +neg/t1623.scala +neg/permanent-blindness.scala +neg/t5803.scala +neg/super-cast-or-test.scala +neg/nonlocal-warning.scala +neg/t5687.scala +neg/t5903a +neg/t6566b.scala +neg/unchecked-knowable.scala +neg/t5093.scala +neg/protected-static-fail +neg/type-diagnostics.scala +neg/forgot-interpolator.scala +neg/interop_abstypetags_arenot_classmanifests.scala +neg/t5376.scala +neg/t545.scala +neg/xmlcorner.scala +neg/switch.scala +neg/depmet_1.scala +neg/abstract-concrete-methods.scala +neg/t4987.scala +neg/t5452-new.scala +neg/t750b +neg/unchecked-refinement.scala +neg/t418.scala +neg/t5354.scala +neg/t3736.scala +neg/t631.scala +neg/t6829.scala +neg/t0218.scala +neg/volatile-intersection.scala +neg/t412.scala +neg/t693.scala +neg/t4882.scala +neg/t1960.scala +neg/macro-divergence-controlled +neg/t712.scala +neg/t5544 +neg/t3222.scala +neg/t3604.scala +neg/t1112.scala +neg/t7157 +neg/accesses.scala +neg/t452.scala +neg/t6162-inheritance +neg/t2442 +neg/t6567.scala +neg/lazy-override.scala +neg/abstract-explaintypes.scala +neg/nested-annotation.scala +neg/t5753 +neg/t4283b +neg/t3691.scala +neg/infix-op-positions.scala +neg/t3403.scala +neg/t4851 +neg/structural.scala +neg/error_dependentMethodTpeConversionToFunction.scala +neg/t5839.scala +neg/t5553_1.scala +neg/reify_metalevel_breach_+0_refers_to_1.scala +neg/t752.scala +neg/t6574.scala +neg/t3714-neg.scala +neg/t4457_2.scala +neg/t2148.scala +neg/t1364.scala +neg/saferJavaConversions.scala +neg/t414.scala +neg/t5493.scala +neg/classtags_contextbound_a.scala +neg/reify_metalevel_breach_-1_refers_to_0_a.scala +neg/t3118.scala +neg/t512.scala +neg/t2336.scala +neg/t856.scala +neg/xmltruncated6.scala +neg/t2206.scala +neg/virtpatmat_unreach_select.scala +neg/t6258.scala +neg/t6815.scala +neg/not-possible-cause.scala +neg/dbldef.scala +neg/qualifying-class-error-1.scala +neg/t835.scala +neg/t5455.scala +neg/t6558.scala +neg/t708.scala +neg/macro-nontypeablebody +neg/t0565.scala +neg/xmltruncated5.scala +neg/t5390d.scala +neg/t520.scala +neg/t6138.scala +neg/macro-without-xmacros-a +neg/t7214neg.scala +neg/t2870.scala +neg/t593.scala +neg/t4541b.scala +neg/t4460b.scala +neg/t284.scala +neg/t2488.scala +neg/macro-override-method-overrides-macro +neg/interop_abstypetags_arenot_classtags.scala +neg/t3769.scala +neg/warn-inferred-any.scala +neg/t664.scala +neg/t5903d +neg/t562.scala +neg/t2316.scala +neg/t0152.scala +neg/migration28.scala +neg/t6443c.scala +neg/tcpoly_override.scala +neg/t7324.scala +neg/t987.scala +neg/t5903b +neg/t3481.scala +neg/t6912.scala +neg/tcpoly_variance_enforce.scala +neg/t3913.scala +neg/names-defaults-neg.scala +neg/t765.scala +neg/t5358.scala +neg/t391.scala +neg/serialversionuid-not-const.scala +neg/t771.scala +neg/t0903.scala +neg/catch-all.scala +neg/classmanifests_new_deprecations.scala +neg/t0606.scala +neg/t5189_inferred.scala +neg/macro-reify-typetag-useabstypetag +neg/t5543.scala +neg/logImplicits.scala +neg/interop_typetags_without_classtags_arenot_manifests.scala +neg/t6535.scala +neg/t7259.scala +neg/t2139.scala +neg/t278.scala +neg/t5564.scala +neg/unchecked3.scala +neg/virtpatmat_reach_sealed_unsealed.scala +neg/checksensible.scala +neg/t7721.scala +run/t3798.scala +run/macro-expand-varargs-explicit-over-varargs +run/t3888.scala +run/t0677-new.scala +run/t3273.scala +run/t3763.scala +run/t2755.scala +run/t920.scala +run/t5610a.scala +run/literals.scala +run/proxy.scala +run/unapply.scala +run/t5830.scala +run/array-addition.scala +run/macro-expand-nullary-nongeneric +run/macro-basic-ma-mdmi +run/valueclasses-constr.scala +run/t1247.scala +run/t3487.scala +run/rawstrings.scala +run/patmat-seqs.scala +run/eta-expand-star.scala +run/t7436.scala +run/t3996.scala +run/constructors.scala +run/t498.scala +run/t3835.scala +run/t298.scala +run/t2867.scala +run/t7120 +run/virtpatmat_literal.scala +run/t2175.scala +run/t2503.scala +run/t3026.scala +run/t603.scala +run/t0091.scala +run/t6394a +run/macro-expand-varargs-implicit-over-varargs +run/t7407.scala +run/t2552.scala +run/virtpatmat_npe.scala +run/macro-sip19 +run/t6644.scala +run/t6614.scala +run/t2005.scala +run/t4680.scala +run/t5903a +run/classtags_contextbound.scala +run/Course-2002-05.scala +run/applydynamic_sip.scala +run/t1766.scala +run/retsynch.scala +run/t7715.scala +run/t102.scala +run/nonlocalreturn.scala +run/macro-reify-staticXXX +run/Course-2002-06.scala +run/t6863.scala +run/t6500.scala +run/macro-impl-rename-context +run/t4351.scala +run/t5009.scala +run/macro-term-declared-in-annotation +run/t6271.scala +run/array-existential-bound.scala +run/t6443b.scala +run/t1987.scala +run/MutableListTest.scala +run/t7571.scala +run/t5488-fn.scala +run/macro-bodyexpandstoimpl +run/macro-reify-ref-to-packageless +run/t2212.scala +run/macro-expand-varargs-implicit-over-nonvarargs +run/t0807.scala +run/patmat-behavior.scala +run/t2446.scala +run/breakout.scala +run/t4122.scala +run/macro-settings +run/t7157 +run/t1323.scala +run/t4013b.scala +run/t6309.scala +run/t4047.scala +run/t5544 +run/t978.scala +run/t3361.scala +run/t6611.scala +run/t5387.scala +run/t5656.scala +run/t4897.scala +run/numeric-range.scala +run/t4777.scala +run/Course-2002-03.scala +run/string-extractor.scala +run/view-headoption.scala +run/patmat_unapp_abstype-new.scala +run/stream-stack-overflow-filter-map.scala +run/macro-impl-tparam-only-in-impl +run/t6559.scala +run/macro-reify-tagful-a +run/macro-expand-multiple-arglists +run/t4709.scala +run/t3509.scala +run/t5284b.scala +run/t7617b +run/t3923.scala +run/virtpatmat_apply.scala +run/t363.scala +run/manifests-undeprecated-in-2.10.0.scala +run/matchintasany.scala +run/t3970.scala +run/t4996.scala +run/t5530.scala +run/macro-term-declared-in-object-class +run/t3242b.scala +run/indexedSeq-apply.scala +run/t107.scala +run/t2337.scala +run/t2754.scala +run/flat-flat-flat.scala +run/t6673.scala +run/interpolationMultiline2.scala +run/t0631.scala +run/t2800.scala +run/t6506.scala +run/t6260.scala +run/t2418.scala +run/t4415.scala +run/classmanifests_new_alias.scala +run/t5380.scala +run/tcpoly_parseridioms.scala +run/t1747.scala +run/t5903d +run/t3530.scala +run/t216.scala +run/macro-term-declared-in-refinement +run/t4592.scala +run/t2488.scala +run/t3327.scala +run/t5614.scala +run/t5903b +run/iterables.scala +run/t3964.scala +run/t6329_vanilla.scala +run/t3038c +run/t1697.scala +run/t2030.scala +run/t3397.scala +run/t1005.scala +run/t3353.scala +run/t1466.scala +run/t3186.scala +run/tcpoly_overriding.scala +run/t5394.scala +run/t5284.scala +run/unboxingBug.scala +run/t7200.scala +run/macro-reify-basic +run/t153.scala +run/iterator3444.scala +run/macro-expand-implicit-macro-is-val +run/macro-basic-ma-md-mi +run/interpolationArgs.scala +run/t4954.scala +run/t3645.scala +run/transpose.scala +run/t3887.scala +run/t4288.scala +run/unittest_iterator.scala +run/t5543.scala +run/macro-term-declared-in-object +run/iq.scala +run/t2788.scala +run/t2027.scala +run/macro-expand-recursive +run/t949.scala +run/t1909b.scala +run/delambdafy-nested-by-name.scala +run/delambdafy-two-lambdas.scala +run/macro-blackbox-materialization +run/lists-run.scala +run/macro-parse-position +run/macro-parse-position-malformed +run/macro-whitebox-dynamic-materialization +run/macro-whitebox-extractor +run/macro-vampire-false-warning +run/macro-whitebox-fundep-materialization +run/macro-whitebox-structural +run/mutable-treeset.scala +run/static-module-method.scala +run/sort.scala +run/t1909.scala +run/t1909c.scala +run/t3346a.scala +run/t3346d.scala +run/t3346f.scala +run/t3346h.scala +run/t3346g.scala +run/t3832.scala +run/t4742.scala +run/t5377.scala +run/t5923c.scala +run/t6188.scala +run/t6333.scala +run/t6385.scala +run/t7899.scala +run/t7899-regression.scala +run/t7584b.scala +run/t7223.scala +run/t7859 +run/t7868.scala +run/t7871 +run/arrayclone-new.scala +run/arrayclone-old.scala +run/bitsets.scala +run/comparable-comparator.scala +run/colltest1.scala +run/t2106.scala +run/t5986.scala +run/view-iterator-stream.scala +run/array-charSeq.scala +pos/signatures +pos/t1263 +pos/t3249 +neg/t4749.scala +neg/main1.scala +neg/t7251 +neg/t7494-after-terminal +neg/t7494-before-parser +neg/t7494-right-after-terminal +run/lazy-traits.scala +run/OrderingTest.scala +run/ReplacementMatching.scala +run/patmat-finally.scala +run/t3158.scala +run/t3346e.scala +run/t4398.scala +run/t4930.scala +run/t6534.scala +pos/sammy_scope.scala +pos/delambdafy-patterns.scala +pos/private-types-after-typer.scala +pos/delambdafy-lambdalift.scala +pos/sammy_poly.scala +pos/sammy_single.scala +pos/SI-4012-b.scala +pos/sammy_twice.scala +pos/t3160.scala +pos/t1014.scala +pos/t4970b.scala +pos/t2698.scala +pos/t5845.scala +pos/t6201.scala +pos/t6260a.scala +pos/t7688.scala +pos/t7818.scala +pos/t1203a.scala +pos/t7834.scala +pos/t7853.scala +pos/t7815.scala +pos/t7853-partial-function.scala +pos/t7864.scala +pos/t7928.scala +pos/t7902.scala +pos/t7944.scala +pos/t7847 +neg/accesses2.scala +neg/bad-advice.scala +neg/gadts2.scala +neg/gadts2-strict.scala +neg/macro-bundle-abstract.scala +neg/macro-bundle-object.scala +neg/macro-bundle-trait.scala +neg/macro-blackbox-dynamic-materialization +neg/macro-blackbox-extractor +neg/run-gadts-strict.scala +neg/macro-blackbox-structural +neg/sammy_restrictions.scala +neg/sammy_wrong_arity.scala +neg/t2462c.scala +neg/t3346b.scala +neg/t1909-object.scala +neg/macro-blackbox-fundep-materialization +neg/t3346c.scala +neg/t3871.scala +neg/t3871b.scala +neg/t3971.scala +neg/t3346i.scala +neg/t6120.scala +neg/t6260c.scala +neg/t6680a.scala +neg/t7239.scala +neg/t7007.scala +neg/t7605-deprecation.scala +neg/t7622-missing-required.scala +neg/t7629-view-bounds-deprecation.scala +neg/t7834neg.scala +neg/t7783.scala +neg/t7848-interp-warn.scala +neg/t7519-b +neg/t7622-missing-dependency +neg/t7870.scala +neg/t7877.scala +neg/t7895.scala +neg/t7895b.scala +neg/t7899.scala +neg/t7895c.scala +neg/t7859 +run/t4752.scala +run/t2087-and-2400.scala +run/t3855.scala +run/t6637.scala +run/t6731.scala +pos/t3999b.scala +run/t0432.scala +run/t2514.scala +run/t7817.scala +run/t874.scala +run/type-currying.scala +run/t3616.scala +run/t3687.scala +run/t4570.scala +run/t5612.scala +run/t1110.scala +run/t2636.scala +run/verify-ctor.scala +run/t3647.scala +run/t4560.scala +run/t6632.scala +run/richs.scala +run/t6725-1.scala +pos/t7776.scala +run/fors.scala +run/t6706.scala +run/t3175.scala +run/delambdafy-dependent-on-param-subst.scala +run/t4332b.scala +run/t8048a +run/t8017 +run/t7985b.scala +run/t8100.scala +run/patmat-mix-case-extractor.scala +run/t4750.scala +run/t7912.scala +run/delambdafy-dependent-on-param-subst-2.scala +run/t8048b +run/t8091.scala +run/macroPlugins-macroRuntime +run/macro-default-params +run/t6355.scala +run/t7777 +run/t8002.scala +run/t8015-ffc.scala +run/macro-subpatterns +run/t7985.scala +run/macroPlugins-macroArgs +run/t7326.scala +run/t5045.scala +run/value-class-partial-func-depmet.scala +run/t6329_vanilla_bug.scala +run/macroPlugins-macroExpand +run/t8010.scala +run/macroPlugins-typedMacroBody +run/t7406.scala +pos/t8146a.scala +pos/t8046c.scala +pos/t8002-nested-scope.scala +pos/t8132.scala +pos/t8045.scala +pos/overzealous-assert-genbcode.scala +pos/t8128.scala +pos/t8013 +pos/t8064b +pos/t6780.scala +pos/t7987 +pos/bcode_throw_null +pos/t8064 +pos/t8046.scala +pos/t6231.scala +pos/t7983.scala +pos/t5508.scala +pos/t5508-min.scala +pos/t8023b.scala +pos/t6231b.scala +pos/debug-reset-local-attrs.scala +pos/t8054.scala +pos/t2066.scala +pos/dotless-targs.scala +pos/t8120.scala +pos/t5508-min-okay.scala +pos/t8060.scala +pos/t8001 +pos/t8138.scala +pos/t8111.scala +pos/t8011.scala +pos/t8146b.scala +pos/t8046b.scala +pos/t8023.scala +pos/t5508-min-okay2.scala +pos/macro-implicit-invalidate-on-error.scala +neg/t6563.scala +neg/missing-param-type-tuple.scala +neg/not-a-legal-formal-parameter-tuple.scala +neg/t7897.scala +neg/t8015-ffa.scala +neg/quasiquotes-unliftable-not-found.scala +neg/t2066b.scala +neg/dotless-targs.scala +neg/patmat-classtag-compound.scala +neg/t2066.scala +neg/t8035-deprecated.scala +neg/t6675b.scala +neg/t8104 +neg/t7872.scala +neg/t7850.scala +neg/t7967.scala +neg/macro-bundle-overloaded.scala +neg/t6355a.scala +neg/class-of-double-targs.scala +neg/t6355b.scala +neg/macro-reify-splice-splice +neg/macro-bundle-noncontext.scala +neg/t8015-ffb.scala +neg/t8035-removed.scala +neg/t7984.scala +neg/t8024.scala +neg/t8024b.scala +neg/t8157.scala +neg/t8146-non-finitary-2.scala +neg/t8006.scala +neg/t7872c.scala +neg/t8146-non-finitary.scala +neg/t7872b.scala +neg/t6920.scala +run/t6200.scala +run/t6196.scala +run/macro-bundle-context-refinement +run/macro-enclosingowner-detectvar +run/macro-enclosingowner-sbt +run/macro-bundle-context-alias +run/macro-bundle-whitebox-use-refined +run/macro-bundle-whitebox-use-raw +neg/name-lookup-stable.scala +neg/t0764b.scala +neg/no-implicit-to-anyref-any-val.scala +neg/t1503.scala +neg/t4728.scala +neg/t6455.scala +neg/t6260-named.scala +neg/t6844.scala +neg/t7475c.scala +neg/t7475e.scala +neg/t7475f.scala +neg/macro-bundle-whitebox-use-raw +neg/macro-bundle-whitebox-use-refined +neg/macro-incompatible-macro-engine-b +neg/t7980.scala +neg/macro-incompatible-macro-engine-a +neg/t8143a.scala +neg/t8072.scala +neg/t8207.scala +neg/t8182.scala +neg/t8219-any-any-ref-equals.scala +neg/t8177a.scala +neg/t8228.scala +neg/t8229.scala +neg/t8237-default.scala +neg/t8244b.scala +neg/t8244e +neg/t8244c.scala +neg/t8265.scala +neg/t8266-invalid-interp.scala +neg/t6931 +neg/t8376 +neg/t8372.scala +neg/t8300-overloading.scala +neg/t8244 +neg/t8158 +neg/t8431.scala +pos/implicit-anyval-2.10.scala +pos/delambdafy_t6260_method.scala +pos/macro-bundle-disambiguate-bundle.scala +pos/macro-bundle-disambiguate-nonbundle.scala +pos/package-ob-case +pos/t1786-counter.scala +pos/reflection-compat-api-universe.scala +pos/existential-java-case-class +pos/t1786-cycle.scala +pos/reflection-compat-c.scala +pos/t3452f.scala +pos/reflection-compat-ru.scala +pos/t2066-2.10-compat.scala +pos/reflection-compat-macro-universe.scala +pos/t5900a.scala +pos/t5760-pkgobj-warn +pos/t5954a +pos/t5954b +pos/t5954d +pos/t6260.scala +pos/t5165b +pos/t5954c +pos/t6260b.scala +pos/t7475b.scala +pos/t7475a.scala +pos/t7753.scala +pos/t7322.scala +pos/t6948.scala +pos/t7475d.scala +pos/t7475e.scala +pos/t6169 +pos/t7788.scala +pos/t7919.scala +pos/t8177a.scala +pos/t8177.scala +pos/t8170.scala +pos/t8170b.scala +pos/t8177d.scala +pos/t8177b.scala +pos/t8177e.scala +pos/t8134 +pos/t8177h.scala +pos/t8177g.scala +pos/t8207.scala +pos/t8187.scala +pos/t8219.scala +pos/t8219b.scala +pos/t8224.scala +pos/t8237.scala +pos/t8223.scala +pos/t8237b.scala +pos/t8300-conversions-a.scala +pos/t8300-conversions-b.scala +pos/t8209a +pos/t8209b +pos/t8244d +pos/t8300-overloading.scala +pos/t8300-patmat-a.scala +pos/t8300-patmat-b.scala +pos/t8301.scala +pos/t8324.scala +pos/t8301b.scala +pos/t8363.scala +pos/t8367.scala +pos/t8369a.scala +pos/t8369b.scala +pos/t8403.scala +pos/t8364.scala +pos/t8352 +pos/t8376 +neg/macro-bundle-nonpublic-c.scala +neg/literate_existentials.scala +neg/macro-bundle-nonpublic-impl.scala +neg/macro-bundle-ambiguous.scala +neg/macro-bundle-priority-bundle.scala +neg/macro-bundle-need-qualifier.scala +neg/macro-bundle-nonstatic.scala +neg/macro-bundle-polymorphic.scala +neg/macro-bundle-priority-nonbundle.scala +neg/macro-bundle-wrongcontext-a.scala +neg/macro-bundle-wrongcontext-b.scala +run/t8425 +run/t8245.scala +run/t8266-octal-interp.scala +run/t8280.scala +run/t8395.scala +run/t8321 +run/t8153.scala +run/t8197.scala +run/t8197b.scala +run/t8233.scala +run/t8133 +run/t8133b +run/t7475b.scala +run/t6814 +run/t4577.scala +run/t5134.scala +run/t3452f.scala +run/t3452h.scala +run/t3452c.scala +run/t3452.scala +run/t261.scala +run/t3235-minimal.scala +run/t1503_future.scala +run/t5565.scala +pos/t8411 +pos/t8460.scala +run/t8428.scala +run/t8437 +run/absoverride.scala +run/arrays.scala +run/duration-coarsest.scala +run/iterator-from.scala +run/SymbolsTest.scala +run/t1074.scala +run/t1505.scala +run/streams.scala +run/t2111.scala +run/t4601.scala +pos/SI-4012-a.scala +pos/SI-7638.scala +neg/t3692-new.scala +run/t7015.scala +run/t7992b.scala +run/t7992.scala +run/t8570.scala +pos/t8157-2.10.scala +pos/t8325.scala +pos/t8523.scala +pos/t8578.scala +pos/t8329.scala +pos/t8497 +pos/t8546.scala +pos/t8531 +neg/t8325-c.scala +neg/t8325-b.scala +neg/t8325.scala +neg/t6988.scala +neg/t8463.scala +neg/t8450.scala +neg/t8430.scala +run/finally.scala +neg/t8630.scala +neg/t8035-no-adapted-args.scala +neg/t8675b.scala +neg/t8610-arg.scala +neg/t8736-c.scala +neg/tailrec-4.scala +neg/double-def-top-level +neg/t8610.scala +neg/aladdin1055 +neg/virtpatmat_exhaust_compound.scala +neg/t8675.scala +neg/t8525.scala +pos/t8736.scala +pos/t8625.scala +pos/t8596.scala +pos/t8617.scala +pos/t8736-b.scala +pos/t8708 +pos/macro-attachments +run/t8611a.scala +run/t8738.scala +run/macro-rangepos-args +run/t8610.scala +run/macro-rangepos-subpatterns +run/t8611c.scala +run/macroPlugins-isBlackbox +run/t8601d.scala +run/t8607.scala +run/bugs.scala +run/t1503.scala +run/t4148.scala +run/t7763.scala +run/issue192.scala +run/t8893b.scala +run/t8845.scala +run/t8933 +run/t7459c.scala +run/t9003.scala +run/t7459f.scala +run/t8933c.scala +run/t1994.scala +run/t2866.scala +run/t5665.scala +run/t7459d.scala +run/t8933b +run/t8888.scala +run/t7459b-optimize.scala +run/t7459a.scala +run/t7019.scala +run/t8893.scala +run/t8803.scala +run/t7459b.scala +run/t8823.scala +run/t6541.scala +run/nothingTypeDce.scala +run/t8680.scala +run/t8925.scala +run/nothingTypeNoOpt.scala +run/t9030.scala +run/bigDecimalTest.scala +run/bigDecimalCache.scala +run/range.scala +run/t6064.scala +run/t7521 +run/t8710.scala +run/t8575.scala +run/t8944 +run/t8944b.scala +run/t9387.scala +run/t9387b.scala +pos/t7784.scala +pos/t8862a.scala +pos/t9074.scala +pos/t8462.scala +pos/t8862b.scala +pos/alladin763.scala +pos/t6778.scala +pos/t9074b.scala +pos/t9326a.scala +pos/t9131.scala +pos/t9393 +pos/t9392 +neg/missing-arg-list.scala +neg/deprecated-target.scala +neg/t6895.scala +neg/beanInfoDeprecation.scala +neg/t8777.scala +neg/t6895b.scala +neg/t8892.scala +neg/t8849.scala +neg/inlineIndyLambdaPrivate +run/t9029.scala +run/t7850c.scala +run/t7850d.scala +run/t8334.scala +run/t9029c.scala +run/t9029b.scala +run/t9422.scala +run/t9425.scala +pos/t9475.scala +pos/t9498.scala +pos/t9479.scala +pos/t9479b.scala +pos/t9442.scala +pos/t9369.scala +pos/t6666d.scala +pos/t9370 +neg/t6810.scala +neg/t8127a.scala +neg/t8989.scala +neg/t9401.scala +neg/implicit-ambiguous.scala +neg/implicit-ambiguous-2.scala +neg/implicit-ambiguous-invalid.scala +neg/warn-unused-imports +run/t7269.scala +run/equality.scala +run/number-parsing.scala +run/t6220.scala +run/mapConserve.scala +run/colltest.scala +run/t0412.scala +run/t6261.scala +run/Predef.readLine.scala +run/java-erasure.scala +run/t5880.scala +run/t6197.scala +run/t4201.scala +run/t5608.scala +run/t3518.scala +run/t6198.scala +run/t2813.2.scala +pos/java-type-annotations +pos/sammy_infer_argtype_subtypes.scala +pos/sammy_ctor_arg.scala +pos/fun_undo_eta.scala +pos/sammy_inferargs.scala +pos/existental-slow-compile2.scala +pos/existential-slow-compile1.scala +pos/sammy_implicit.scala +pos/t9178b.scala +pos/t9449.scala +pos/t3234.scala +pos/t9542.scala +pos/t8429.scala +pos/t9658.scala +pos/t9630 +pos/t9399.scala +pos/t9411a.scala +pos/t9411b.scala +neg/partestInvalidFlag.scala +neg/sammy_error.scala +neg/sammy_disabled.scala +neg/sammy_overload.scala +neg/sammy_expected.scala +neg/t8700a +neg/t9527b.scala +neg/t9527a.scala +neg/t9572.scala +neg/t9535.scala +neg/t9629.scala +neg/optimiseDeprecated.scala +neg/t9398 +neg/outer-ref-checks.scala +neg/t8685.scala +neg/t8700b +run/t9349 +run/t9178a.scala +run/t9110.scala +run/sammy_cbn.scala +run/sammy_erasure_cce.scala +run/sammy_after_implicit_view.scala +run/sammy_restrictions_LMF.scala +run/sammy_vararg_cbn.scala +run/t7807.scala +run/sammy_return.scala +run/t9546.scala +run/t9546b.scala +run/lisp.scala +run/t9546c.scala +run/t9546d.scala +run/t9546e.scala +run/t9567.scala +run/t9567b.scala +run/trait-clonable.scala +run/t9567c.scala +run/trait-defaults-modules.scala +run/trait-defaults-modules3.scala +run/trait-defaults-modules2 +pos/functions.scala +pos/MailBox.scala +neg/t6289 +run/t4729 +run/t6114.scala +run/t1430 +pos/constant-warning.scala +pos/t2712-5.scala +pos/t2712-2.scala +pos/t2712-4.scala +pos/t2712-1.scala +pos/t2712-3.scala +pos/t2712-6.scala +pos/t6895b.scala +pos/t5683.scala +pos/hkgadt.scala +pos/t2712-7.scala +pos/t9245.scala +pos/t7088.scala +pos/trait-defaults-super.scala +pos/t8044.scala +pos/t9665.scala +pos/t9397.scala +pos/t5183.scala +pos/t8449 +neg/t8044-b.scala +neg/t8044.scala +neg/t2712-3.scala +neg/t2712-2.scala +neg/t2712-1.scala +neg/t9045.scala +neg/t8667.scala +neg/t9361.scala +neg/t9781.scala +neg/trait-no-native.scala +neg/hkgadt.scala +neg/t9684b.scala +neg/t9382.scala +neg/trait-defaults-super.scala +neg/t9684.scala +run/hashCodeStatics.scala +run/t9390d.scala +run/trait-static-clash.scala +run/t5568.scala +run/t6318_primitives.scala +pos/fields_widen_trait_var.scala +pos/sammy_extends_function.scala +pos/infer_override_def_args.scala +pos/t482.scala +pos/t8079b.scala +pos/t6161b.scala +pos/t5294b.scala +pos/t5294c.scala +pos/overloaded_ho_fun.scala +pos/t4914.scala +pos/trait_fields_dependent_conflict.scala +pos/t2377b +pos/trait_fields_dependent_rebind.scala +pos/t9855b.scala +pos/trait_fields_inherit_double_def.scala +pos/t9855.scala +pos/t8873.scala +pos/trait_fields_nested_private_object.scala +pos/trait_fields_nested_public_object.scala +pos/trait_fields_private_this.scala +pos/trait_fields_var_override_deferred.scala +pos/trait_fields_static_fwd.scala +pos/trait_fields_owners.scala +pos/trait_fields_volatile.scala +pos/trait_lazy_accessboundary.scala +pos/trait_fields_lambdalift.scala +pos/typevar-in-prefix.scala +pos/val_infer.scala +pos/lub-from-hell.scala +neg/t8079a.scala +neg/sd128 +neg/t9849.scala +neg/trait_fields_var_override.scala +neg/val_infer.scala +neg/val_sig_infer_match.scala +neg/t7187.scala +neg/trait_fields_deprecated_overriding.scala +neg/t9847.scala +neg/val_sig_infer_struct.scala +neg/trait_fields_conflicts.scala +neg/lub-from-hell-2.scala +run/t2946 +run/lazy_local_labels.scala +run/sd167.scala +run/t9841.scala +run/trait-fields-override-lazy.scala +run/trait_fields_init.scala +run/trait_fields_three_layer_overrides.scala +run/t9516.scala +run/t10032.scala + +# Adapt checkfiles for (1.0).toString == "1" +run/Course-2002-01.scala +run/t0421-new.scala +run/runtime.scala +run/t0421-old.scala +run/spec-self.scala +run/t5552.scala +run/Course-2002-02.scala +run/Course-2002-04.scala +run/promotion.scala +run/t4617.scala +run/Course-2002-09.scala +run/t5866.scala +run/try-catch-unify.scala +run/impconvtimes.scala +run/Course-2002-10.scala +run/Course-2002-08.scala +run/MeterCaseClass.scala +run/Meter.scala +run/deeps.scala +run/caseClassHash.scala +run/interpolation.scala +run/interpolationMultiline1.scala +run/t9656.scala +pos/sd219.scala +pos/t9918 +pos/shapeless-regression.scala +pos/issue244.scala +pos/t9920.scala +pos/t9943.scala +neg/t5148.scala +run/sd242.scala +run/local_obj.scala +run/t9697.scala +run/t9920.scala +run/t9920c.scala +run/t9920d.scala +run/t9920b.scala +run/t9946a.scala +run/t9946c.scala +run/t9946b.scala +run/trait-super-calls.scala +pos/sd268.scala +pos/sd248 +pos/t6734.scala +pos/t10009.scala +pos/t7551 +pos/t6978 +pos/t7046-2 +neg/t9953.scala +neg/t7014 +neg/t7046-2 +neg/t7046 +run/t7046-1 +run/t7046-2 + +# Adapt checkfiles for ().toString == "undefined" +run/t5680.scala +run/dynamic-anyval.scala +run/macro-bundle-toplevel +run/macro-bundle-whitebox-decl +run/t6662 +run/t8570a.scala +run/t3702.scala +run/t7657 +run/macro-bundle-static +run/structural.scala + +# Adapt checkfiles for print & flush (which we cannot 100% emulate) +run/imports.scala +run/misc.scala + +# Adapt checkfiles for compiler phase list +neg/t7494-no-options +neg/t6446-list +neg/t6446-missing +neg/t6446-show-phases.scala +neg/t6446-additional + +# Adapt checkfiles for different behavior with boxed types +run/virtpatmat_typetag.scala +run/virtpatmat_switch.scala +run/t5629b.scala +run/t5356.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-additional.check new file mode 100644 index 0000000000..b7ce23da2f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-additional.check @@ -0,0 +1,30 @@ + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + ploogin 27 A sample phase that does so many things it's kind of hard... + terminal 28 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-list.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-list.check new file mode 100644 index 0000000000..95883c8c81 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-list.check @@ -0,0 +1,2 @@ +ploogin - A sample plugin for testing. +scalajs - Compile to JavaScript diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-missing.check new file mode 100644 index 0000000000..56b74a3128 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-missing.check @@ -0,0 +1,30 @@ +Error: unable to load class: t6446.Ploogin + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + terminal 27 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-show-phases.check new file mode 100644 index 0000000000..cde255e3b1 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-show-phases.check @@ -0,0 +1,29 @@ + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + terminal 27 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t7494-no-options.check new file mode 100644 index 0000000000..d8be421e5e --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t7494-no-options.check @@ -0,0 +1,31 @@ +error: Error: ploogin takes no options + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + ploogin 27 A sample phase that does so many things it's kind of hard... + terminal 28 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Course-2002-01.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Course-2002-01.check new file mode 100644 index 0000000000..fcda9433de --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Course-2002-01.check @@ -0,0 +1,37 @@ +Course-2002-01.scala:41: warning: method loop in object M0 does nothing other than call itself recursively + def loop: Int = loop; + ^ +232 +667 +11 +10 +62.8318 +62.8318 +62.8318 +4 +81 +256 +25 +1 +737 +1 +0 +1 +76 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +sqrt(2) = 1.4142135623746899 +sqrt(2) = 1.4142135623746899 +cbrt(2) = 1.2599210500177698 +1 +1 1 +1 2 1 +1 3 3 1 +1 4 6 4 1 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Course-2002-02.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Course-2002-02.check new file mode 100644 index 0000000000..ab75cfdb61 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Course-2002-02.check @@ -0,0 +1,187 @@ +7 +120 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +pi = 3.181104885577714 +pi = 3.181104885577714 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 +pi = 3.181104885577714 +pi = 3.181104885577714 + +1.5 +1.4166666666666665 +1.4142156862745097 +1.4142135623746899 +sqrt(2) = 1.4142135623746899 + +1.5 +1.4166666666666665 +1.4142156862745097 +1.4142135623746899 +sqrt(2) = 1.4142135623746899 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +power(0,0) = 1 +power(0,1) = 0 +power(0,2) = 0 +power(0,3) = 0 +power(0,4) = 0 +power(0,5) = 0 +power(0,6) = 0 +power(0,7) = 0 +power(0,8) = 0 + +power(1,0) = 1 +power(1,1) = 1 +power(1,2) = 1 +power(1,3) = 1 +power(1,4) = 1 +power(1,5) = 1 +power(1,6) = 1 +power(1,7) = 1 +power(1,8) = 1 + +power(2,0) = 1 +power(2,1) = 2 +power(2,2) = 4 +power(2,3) = 8 +power(2,4) = 16 +power(2,5) = 32 +power(2,6) = 64 +power(2,7) = 128 +power(2,8) = 256 + +power(3,0) = 1 +power(3,1) = 3 +power(3,2) = 9 +power(3,3) = 27 +power(3,4) = 81 +power(3,5) = 243 +power(3,6) = 729 +power(3,7) = 2187 +power(3,8) = 6561 + +power(4,0) = 1 +power(4,1) = 4 +power(4,2) = 16 +power(4,3) = 64 +power(4,4) = 256 +power(4,5) = 1024 +power(4,6) = 4096 +power(4,7) = 16384 +power(4,8) = 65536 + +power(5,0) = 1 +power(5,1) = 5 +power(5,2) = 25 +power(5,3) = 125 +power(5,4) = 625 +power(5,5) = 3125 +power(5,6) = 15625 +power(5,7) = 78125 +power(5,8) = 390625 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Course-2002-04.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Course-2002-04.check new file mode 100644 index 0000000000..fc6ad96eed --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Course-2002-04.check @@ -0,0 +1,64 @@ +list0 = List(6, 3, 1, 8, 7, 1, 2, 5, 8, 4, 3, 4, 8) +list1 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list2 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list3 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list4 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list5 = List(8, 8, 8, 7, 6, 5, 4, 4, 3, 3, 2, 1, 1) +list6 = List(8, 8, 8, 7, 6, 5, 4, 4, 3, 3, 2, 1, 1) + +list0: List() -> List() +list1: List(0) -> List(0) +list2: List(0, 1) -> List(0, 1) +list3: List(1, 0) -> List(0, 1) +list4: List(0, 1, 2) -> List(0, 1, 2) +list5: List(1, 0, 2) -> List(0, 1, 2) +list6: List(0, 1, 2) -> List(0, 1, 2) +list7: List(1, 0, 2) -> List(0, 1, 2) +list8: List(2, 0, 1) -> List(0, 1, 2) +list9: List(2, 1, 0) -> List(0, 1, 2) +listA: List(6, 3, 1, 8, 7, 1, 2, 5, 8, 4) -> List(1, 1, 2, 3, 4, 5, 6, 7, 8, 8) + +f(x) = 5x^3+7x^2+5x+9 +f(0) = 9 +f(1) = 26 +f(2) = 87 +f(3) = 222 + +v1 = List(2, 3, 4) +v2 = List(6, 7, 8) + +id = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +m1 = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m2 = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) + +v1 * v1 = 29 +v1 * v2 = 65 +v2 * v1 = 65 +v1 * v2 = 65 + +id * v1 = List(2, 3, 4) +m1 * v1 = List(4, 6, 8) +m2 * v1 = List(20, 47, 74) + +trn(id) = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +trn(m1) = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +trn(m2) = List(List(1, 4, 7), List(2, 5, 8), List(3, 6, 9)) + +List(v1) * id = List(List(2, 3, 4)) +List(v1) * m1 = List(List(4, 6, 8)) +List(v1) * m2 = List(List(42, 51, 60)) + +id * List(v1) = List(List(2, 3, 4), List(0, 0, 0), List(0, 0, 0)) +m1 * List(v1) = List(List(4, 6, 8), List(0, 0, 0), List(0, 0, 0)) +m2 * List(v1) = List(List(2, 3, 4), List(8, 12, 16), List(14, 21, 28)) + +id * id = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +id * m1 = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m1 * id = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m1 * m1 = List(List(4, 0, 0), List(0, 4, 0), List(0, 0, 4)) +id * m2 = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) +m2 * id = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) +m1 * m2 = List(List(2, 4, 6), List(8, 10, 12), List(14, 16, 18)) +m2 * m1 = List(List(2, 4, 6), List(8, 10, 12), List(14, 16, 18)) +m2 * m2 = List(List(30, 36, 42), List(66, 81, 96), List(102, 126, 150)) + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Course-2002-08.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Course-2002-08.check new file mode 100644 index 0000000000..0585d5b44f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Course-2002-08.check @@ -0,0 +1,171 @@ +x = abc +count = 111 +x = hello +count = 112 + +account deposit 50 -> undefined +account withdraw 20 -> 30 +account withdraw 20 -> 10 +account withdraw 15 -> + +x deposit 30 -> undefined +y withdraw 20 -> + +x deposit 30 -> undefined +x withdraw 20 -> 10 + +x deposit 30 -> undefined +y withdraw 20 -> 10 + +2^0 = 1 +2^1 = 2 +2^2 = 4 +2^3 = 8 + +2^0 = 1 +2^1 = 2 +2^2 = 4 +2^3 = 8 + +1 2 3 +List(1, 2, 3) + +out 0 new-value = false +*** simulation started *** +out 1 new-value = true +!0 = 1 + +*** simulation started *** +out 2 new-value = false +!1 = 0 + +out 2 new-value = false + +*** simulation started *** +0 & 0 = 0 + +*** simulation started *** +0 & 1 = 0 + +*** simulation started *** +out 11 new-value = true +out 11 new-value = false +1 & 0 = 0 + +*** simulation started *** +out 14 new-value = true +1 & 1 = 1 + +out 14 new-value = false + +*** simulation started *** +0 | 0 = 0 + +*** simulation started *** +out 24 new-value = true +0 | 1 = 1 + +*** simulation started *** +1 | 0 = 1 + +*** simulation started *** +1 | 1 = 1 + +sum 34 new-value = false +carry 34 new-value = false + +*** simulation started *** +0 + 0 = 0 + +*** simulation started *** +sum 47 new-value = true +0 + 1 = 1 + +*** simulation started *** +carry 50 new-value = true +carry 50 new-value = false +sum 54 new-value = false +sum 54 new-value = true +1 + 0 = 1 + +*** simulation started *** +carry 57 new-value = true +sum 61 new-value = false +1 + 1 = 2 + +sum 61 new-value = false +carry 61 new-value = false + +*** simulation started *** +0 + 0 + 0 = 0 + +*** simulation started *** +sum 82 new-value = true +0 + 0 + 1 = 1 + +*** simulation started *** +sum 89 new-value = false +carry 90 new-value = true +sum 97 new-value = true +carry 98 new-value = false +0 + 1 + 0 = 1 + +*** simulation started *** +sum 113 new-value = false +carry 114 new-value = true +0 + 1 + 1 = 2 + +*** simulation started *** +sum 121 new-value = true +carry 122 new-value = false +sum 129 new-value = false +sum 129 new-value = true +1 + 0 + 0 = 1 + +*** simulation started *** +carry 137 new-value = true +sum 144 new-value = false +1 + 0 + 1 = 2 + +*** simulation started *** +carry 152 new-value = false +sum 152 new-value = true +sum 158 new-value = false +carry 159 new-value = true +1 + 1 + 0 = 2 + +*** simulation started *** +sum 173 new-value = true +1 + 1 + 1 = 3 + +in 0 new-value = false +ctrl0 0 new-value = false +ctrl1 0 new-value = false +ctrl2 0 new-value = false +out0 0 new-value = false +out1 0 new-value = false +out2 0 new-value = false +out3 0 new-value = false +out4 0 new-value = false +out5 0 new-value = false +out6 0 new-value = false +out7 0 new-value = false +in 0 new-value = true +*** simulation started *** +out0 10 new-value = true +ctrl0 10 new-value = true +*** simulation started *** +out1 13 new-value = true +out0 14 new-value = false +ctrl1 14 new-value = true +*** simulation started *** +out3 20 new-value = true +out1 21 new-value = false +ctrl2 21 new-value = true +*** simulation started *** +out7 30 new-value = true +out3 31 new-value = false +ctrl0 31 new-value = false +*** simulation started *** +out7 34 new-value = false +out6 35 new-value = true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Course-2002-09.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Course-2002-09.check new file mode 100644 index 0000000000..c921361db7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Course-2002-09.check @@ -0,0 +1,50 @@ +Probe: f = 32 +Probe: c = 0 +Probe: f = ? +Probe: c = ? + +Probe: f = 212 +Probe: c = 100 +Probe: f = ? +Probe: c = ? + +Probe: c = 0 +Probe: f = 32 +Probe: c = ? +Probe: f = ? + +Probe: c = 100 +Probe: f = 212 +Probe: c = ? +Probe: f = ? + +0 Celsius -> 32 Fahrenheits +100 Celsius -> 212 Fahrenheits +32 Fahrenheits -> 0 Celsius +212 Fahrenheits -> 100 Celsius + +a = ?, b = ?, c = ? => ? * ? = ? +a = 2, b = ?, c = ? => 2 * ? = ? +a = ?, b = 3, c = ? => ? * 3 = ? +a = ?, b = ?, c = 6 => ? * ? = 6 +a = 2, b = 3, c = ? => 2 * 3 = 6 +a = 2, b = ?, c = 6 => 2 * 3 = 6 +a = ?, b = 3, c = 6 => 2 * 3 = 6 +a = 2, b = 3, c = 6 => 2 * 3 = 6 + +a = 0, b = ?, c = ? => 0 * ? = 0 +a = ?, b = 0, c = ? => ? * 0 = 0 +a = ?, b = ?, c = 0 => ? * ? = 0 +a = 0, b = 7, c = ? => 0 * 7 = 0 +a = 7, b = 0, c = ? => 7 * 0 = 0 +a = 0, b = 0, c = ? => 0 * 0 = 0 +a = 0, b = ?, c = 0 => 0 * ? = 0 +a = ?, b = 0, c = 0 => ? * 0 = 0 +a = 0, b = 7, c = 0 => 0 * 7 = 0 +a = 7, b = 0, c = 0 => 7 * 0 = 0 +a = 0, b = 0, c = 0 => 0 * 0 = 0 + +a = 3, b = 4 => c = 5 +a = 3, c = 5 => b = 4 +b = 4, c = 5 => a = 3 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Course-2002-10.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Course-2002-10.check new file mode 100644 index 0000000000..847f0fa703 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Course-2002-10.check @@ -0,0 +1,46 @@ +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +fib(10) = 55 +fib(11) = 89 +fib(12) = 144 +fib(13) = 233 +fib(14) = 377 +fib(15) = 610 +fib(16) = 987 +fib(17) = 1597 +fib(18) = 2584 +fib(19) = 4181 + +pi(0) = 4 , 3.166666666666667 , 4 +pi(1) = 2.666666666666667 , 3.1333333333333337, 3.166666666666667 +pi(2) = 3.466666666666667 , 3.1452380952380956, 3.142105263157895 +pi(3) = 2.8952380952380956, 3.1396825396825396, 3.1415993573190044 +pi(4) = 3.33968253968254 , 3.142712842712843 , 3.141592714033778 +pi(5) = 2.976046176046176 , 3.140881340881341 , 3.1415926539752923 +pi(6) = 3.283738483738484 , 3.142071817071817 , 3.141592653591176 +pi(7) = 3.017071817071817 , 3.1412548236077646, 3.141592653589777 +pi(8) = 3.252365934718876 , 3.1418396189294024, 3.141592653589794 +pi(9) = 3.0418396189294024, 3.141406718496502 , 3.1415926535897936 +pi = 3.141592653589793 , 3.141592653589793 , 3.141592653589793 + +ln(0) = 1 , 0.7 , 1 +ln(1) = 0.5 , 0.6904761904761905, 0.7 +ln(2) = 0.8333333333333333, 0.6944444444444444, 0.6932773109243697 +ln(3) = 0.5833333333333333, 0.6924242424242424, 0.6931488693329254 +ln(4) = 0.7833333333333333, 0.6935897435897436, 0.6931471960735491 +ln(5) = 0.6166666666666667, 0.6928571428571428, 0.6931471806635636 +ln(6) = 0.7595238095238095, 0.6933473389355742, 0.6931471805604038 +ln(7) = 0.6345238095238095, 0.6930033416875522, 0.6931471805599444 +ln(8) = 0.7456349206349207, 0.6932539682539682, 0.6931471805599426 +ln(9) = 0.6456349206349206, 0.6930657506744463, 0.6931471805599453 +ln = 0.6931471805599453, 0.6931471805599453, 0.6931471805599453 + +prime numbers: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Meter.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Meter.check new file mode 100644 index 0000000000..f46fd557c8 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/Meter.check @@ -0,0 +1,16 @@ +Meter.scala:72: warning: a.Meter and Int are unrelated: they will never compare equal + println("x == 1: "+(x == 1)) + ^ +2 +4m +false +x.isInstanceOf[Meter]: true +x.hashCode: 1 +x == 1: false +x == y: true +a == b: true +testing native arrays +Array(1m, 2m) +1m +>>>1m<<< 1m +>>>2m<<< 2m diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/MeterCaseClass.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/MeterCaseClass.check new file mode 100644 index 0000000000..ac538d240f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/MeterCaseClass.check @@ -0,0 +1,16 @@ +MeterCaseClass.scala:69: warning: comparing values of types a.Meter and Int using `==' will always yield false + println("x == 1: "+(x == 1)) + ^ +2 +Meter(4) +false +x.isInstanceOf[Meter]: true +x.hashCode: 1 +x == 1: false +x == y: true +a == b: true +testing native arrays +Array(Meter(1), Meter(2)) +Meter(1) +>>>Meter(1)<<< Meter(1) +>>>Meter(2)<<< Meter(2) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/bugs.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/bugs.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/bugs.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/caseClassHash.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/caseClassHash.check new file mode 100644 index 0000000000..f975151e9c --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/caseClassHash.check @@ -0,0 +1,9 @@ +Foo(true,-1,-1,d,-5,-10,500,500,List(),5) +Foo(true,-1,-1,d,-5,-10,500,500,List(),5) +1383698062 +1383698062 +true +## method 1: 1383698062 +## method 2: 1383698062 + Murmur 1: 1383698062 + Murmur 2: 1383698062 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/deeps.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/deeps.check new file mode 100644 index 0000000000..e533b87dc5 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/deeps.check @@ -0,0 +1,87 @@ +testEquals1 +false +false +true + +testEquals2 +false +false +true + +testEquals3 +x=Array(1) +y=Array(1) +false +false +true + +x=Array(Array(1), Array(1)) +y=Array(Array(1), Array(1)) +false +false +true + +x=Array(Array(Array(1), Array(1)), Array(Array(1), Array(1))) +y=Array(Array(Array(1), Array(1)), Array(Array(1), Array(1))) +false +false +true + +testEquals4 +false +false +true +false +false +true +Array(true, false) +Array(true, false) +[true;false] +true;false + +Array(Array(true, false), Array(true, false)) +Array(Array(true, false), Array(true, false)) +[Array(true, false);Array(true, false)] +Array(true, false);Array(true, false) + +Array(Array(Array(true, false), Array(true, false)), Array(Array(true, false), Array(true, false))) +Array(Array(Array(true, false), Array(true, false)), Array(Array(true, false), Array(true, false))) +[Array(Array(true, false), Array(true, false));Array(Array(true, false), Array(true, false))] +Array(Array(true, false), Array(true, false));Array(Array(true, false), Array(true, false)) + +Array(1, 0) +Array(1, 0) +[1;0] +1;0 + +Array(Array(1, 0), Array(1, 0)) +Array(Array(1, 0), Array(1, 0)) +[Array(1, 0);Array(1, 0)] +Array(1, 0);Array(1, 0) + +Array(Array(Array(1, 0), Array(1, 0)), Array(Array(1, 0), Array(1, 0))) +Array(Array(Array(1, 0), Array(1, 0)), Array(Array(1, 0), Array(1, 0))) +[Array(Array(1, 0), Array(1, 0));Array(Array(1, 0), Array(1, 0))] +Array(Array(1, 0), Array(1, 0));Array(Array(1, 0), Array(1, 0)) + +Array(a, b) +Array(a, b) +[a;b] +a;b + +Array(Array(a, b), Array(a, b)) +Array(Array(a, b), Array(a, b)) +[Array(a, b);Array(a, b)] +Array(a, b);Array(a, b) + +Array(Array(Array(a, b), Array(a, b)), Array(Array(a, b), Array(a, b))) +Array(Array(Array(a, b), Array(a, b)), Array(Array(a, b), Array(a, b))) +[Array(Array(a, b), Array(a, b));Array(Array(a, b), Array(a, b))] +Array(Array(a, b), Array(a, b));Array(Array(a, b), Array(a, b)) + +[Array(true, false); Array(false)] +[Array(1, 2); Array(3)] +[Array(1, 2); Array(3)] + +Array(boo, and, foo) +Array(a) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/dynamic-anyval.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/dynamic-anyval.check new file mode 100644 index 0000000000..c125372c9a --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/dynamic-anyval.check @@ -0,0 +1,4 @@ +undefined.dingo(bippy, 5) +List(1, 2, 3).dingo(bippy, 5) +undefined.dingo(bippy, 5) +List(1, 2, 3).dingo(bippy, 5) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/impconvtimes.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/impconvtimes.check new file mode 100644 index 0000000000..082377e474 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/impconvtimes.check @@ -0,0 +1 @@ +3.0 * Hour = Measure(3,Hour) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/imports.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/imports.check new file mode 100644 index 0000000000..1aad598062 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/imports.check @@ -0,0 +1,21 @@ +In C_ico, v_ico .toString() returns ↩ +↪C_ico -> ok +In C_ico, field .toString() returns ↩ +↪C_ico -> ok +In C_ico, method.toString() returns ↩ +↪C_ico -> ok + +In C_ioc, v_ioc .toString() returns ↩ +↪C_ioc -> ok +In C_ioc, field .toString() returns ↩ +↪C_ioc -> ok +In C_ioc, method.toString() returns ↩ +↪C_ioc -> ok + +In C_oic, v_oic .toString() returns ↩ +↪C_oic -> ok +In C_oic, field .toString() returns ↩ +↪C_oic -> ok +In C_oic, method.toString() returns ↩ +↪C_oic -> ok + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/interpolation.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/interpolation.check new file mode 100644 index 0000000000..9c4a77715b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/interpolation.check @@ -0,0 +1,32 @@ +Bob is 1 years old +Bob is 1 years old +Bob will be 2 years old +Bob will be 2 years old +1+1 = 2 +1+1 = 2 +Bob is 12 years old +Bob is 12 years old +Bob will be 13 years old +Bob will be 13 years old +12+1 = 13 +12+1 = 13 +Bob is 123 years old +Bob is 123 years old +Bob will be 124 years old +Bob will be 124 years old +123+1 = 124 +123+1 = 124 +Best price: 10 +Best price: 10.00 +10% discount included +10.00% discount included +Best price: 13.345000267028809 +Best price: 13.35 +13.345000267028809% discount included +13.35% discount included + +0 +00 + +0 +00 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/interpolationMultiline1.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/interpolationMultiline1.check new file mode 100644 index 0000000000..1b6e140c13 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/interpolationMultiline1.check @@ -0,0 +1,26 @@ +Bob is 1 years old +Bob is 1 years old +Bob will be 2 years old +Bob will be 2 years old +1+1 = 2 +1+1 = 2 +Bob is 12 years old +Bob is 12 years old +Bob will be 13 years old +Bob will be 13 years old +12+1 = 13 +12+1 = 13 +Bob is 123 years old +Bob is 123 years old +Bob will be 124 years old +Bob will be 124 years old +123+1 = 124 +123+1 = 124 +Best price: 10 +Best price: 10.00 +10% discount included +10.00% discount included +Best price: 13.345000267028809 +Best price: 13.35 +13.345000267028809% discount included +13.35% discount included diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/issue192.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/issue192.sem new file mode 100644 index 0000000000..10abbf7f3b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/issue192.sem @@ -0,0 +1 @@ +strictFloats diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/macro-bundle-static.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/macro-bundle-static.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/macro-bundle-static.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/macro-bundle-toplevel.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/macro-bundle-toplevel.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/macro-bundle-toplevel.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/macro-bundle-whitebox-decl.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/macro-bundle-whitebox-decl.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/macro-bundle-whitebox-decl.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/misc.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/misc.check new file mode 100644 index 0000000000..85f37c51d7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/misc.check @@ -0,0 +1,62 @@ +misc.scala:46: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 42; + ^ +misc.scala:47: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 42l; + ^ +misc.scala:48: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 23.5f; + ^ +misc.scala:49: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 23.5; + ^ +misc.scala:50: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + "Hello"; + ^ +misc.scala:51: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 32 + 45; + ^ +misc.scala:62: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + x; + ^ +misc.scala:74: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 1 < 2; + ^ +### Hello +### 17 +### Bye + +### fib(0) = ↩ +↪1 +### fib(1) = ↩ +↪1 +### fib(2) = ↩ +↪2 +### fib(3) = ↩ +↪3 +### fib(4) = ↩ +↪5 +=== MyClass::toString === +=== MySubclass::toString === +=== MyClass::test === + +identity + +A.a = 1 +B.a = 5 +B.b = 2 + +X.a = 4 +Y.a = 11 +Y.b = 5 +Y.b = 5 + +X::foo + +Y::foo +X::foo + +3 +3 + +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/promotion.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/promotion.check new file mode 100644 index 0000000000..41e36c369d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/promotion.check @@ -0,0 +1,4 @@ +2 +6 +20 +30 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/runtime.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/runtime.check new file mode 100644 index 0000000000..0450b9498a --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/runtime.check @@ -0,0 +1,70 @@ +runtime.scala:141: warning: comparing values of types Null and Null using `eq' will always yield true + check(true , null eq null, null ne null); + ^ +runtime.scala:141: warning: comparing values of types Null and Null using `ne' will always yield false + check(true , null eq null, null ne null); + ^ +<<< Test0 +[false,true] +[0,1,2] +[3,4,5] +[a,b,c] +[6,7,8] +[9,10,11] +[12,13] +[14,15] +[string] +>>> Test0 + +<<< Test1 +10 +14 +15 +16 +20 +23 +24 +25 +26 +>>> Test1 + +<<< Test2 +A +M0 +N0 + +A +N0 +M0 + +A +M0 +M1 +N0 + +A +N0 +N1 +M0 + +>>> Test2 + +<<< Test3 +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +>>> Test3 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/spec-self.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/spec-self.check new file mode 100644 index 0000000000..fd3c81a4d7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/spec-self.check @@ -0,0 +1,2 @@ +5 +5 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/structural.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/structural.check new file mode 100644 index 0000000000..2fec112a87 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/structural.check @@ -0,0 +1,37 @@ + 1. hey + 2. 11 + 3. dee + 4. iei + 5. 6 + 6. 51 + 7. 2 + 8. 11 +10. 12 +11. eitch +12. 1 +13. ohone +14. 1 +15. undefined +16. one +17. tieone +18. 2 +19. true +20. 1 +21. undefined +22. one +23. oy +24. 1 +25. null +26. iei +31. 4 +32. undefined +33. iei +33. tieone +1 +2 +3 +4 +5 +caught +3 +2 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t0421-new.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t0421-new.check new file mode 100644 index 0000000000..00d29b7e5b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t0421-new.check @@ -0,0 +1,3 @@ +[Array(0, 1),Array(2, 3),Array(4, 5)] +[Array(31)] +[Array(24, 32)] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t0421-old.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t0421-old.check new file mode 100644 index 0000000000..00d29b7e5b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t0421-old.check @@ -0,0 +1,3 @@ +[Array(0, 1),Array(2, 3),Array(4, 5)] +[Array(31)] +[Array(24, 32)] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t1503.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t1503.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t1503.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t3702.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t3702.check new file mode 100644 index 0000000000..3fce98715c --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t3702.check @@ -0,0 +1,2 @@ +undefined +6 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t4148.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t4148.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t4148.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t4617.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t4617.check new file mode 100644 index 0000000000..a6790f16f7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t4617.check @@ -0,0 +1 @@ +Str 8 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t5356.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t5356.check new file mode 100644 index 0000000000..870c901131 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t5356.check @@ -0,0 +1,6 @@ +1 java.lang.Byte +1 java.lang.Byte +1 scala.math.BigInt +1 java.lang.Byte +1 java.lang.Byte +1 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t5552.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t5552.check new file mode 100644 index 0000000000..9e767b6d7b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t5552.check @@ -0,0 +1,6 @@ +lazy: 3 +(3,3) +(3,3) +lazy: 3 +(3,3) +(3,3) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t5568.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t5568.check new file mode 100644 index 0000000000..6f30cc5070 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t5568.check @@ -0,0 +1,9 @@ +void +int +class scala.runtime.BoxedUnit +class scala.runtime.BoxedUnit +class java.lang.Byte +class java.lang.Byte +5 +5 +5 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t5629b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t5629b.check new file mode 100644 index 0000000000..c65298a6ce --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t5629b.check @@ -0,0 +1,10 @@ +=== pf(1): +MySmartPF.apply entered... +newPF.applyOrElse entered... +default +scala.MatchError: 1 (of class java.lang.Byte) +=== pf(42): +MySmartPF.apply entered... +newPF.applyOrElse entered... +ok +=== done diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t5680.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t5680.check new file mode 100644 index 0000000000..a3b8b64a43 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t5680.check @@ -0,0 +1,3 @@ +[Lscala.runtime.BoxedUnit +undefined +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t5866.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t5866.check new file mode 100644 index 0000000000..64df1cec7f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t5866.check @@ -0,0 +1,2 @@ +0 +Foo(0) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t6318_primitives.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t6318_primitives.check new file mode 100644 index 0000000000..654ef1beec --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t6318_primitives.check @@ -0,0 +1,54 @@ +Checking if byte matches byte +Some(1) +Checking if byte matches short +Some(1) +Checking if class java.lang.Byte matches byte +Some(1) +Checking if short matches short +Some(1) +Checking if short matches char +None +Checking if class java.lang.Byte matches short +Some(1) +Checking if char matches char +Some() +Checking if char matches int +None +Checking if class java.lang.Character matches char +Some() +Checking if int matches int +Some(1) +Checking if int matches long +None +Checking if class java.lang.Byte matches int +Some(1) +Checking if long matches long +Some(1) +Checking if long matches float +None +Checking if class java.lang.Long matches long +Some(1) +Checking if float matches float +Some(1) +Checking if float matches double +Some(1) +Checking if class java.lang.Byte matches float +Some(1) +Checking if double matches double +Some(1) +Checking if double matches boolean +None +Checking if class java.lang.Byte matches double +Some(1) +Checking if boolean matches boolean +Some(true) +Checking if boolean matches void +None +Checking if class java.lang.Boolean matches boolean +Some(true) +Checking if void matches void +Some(undefined) +Checking if void matches byte +None +Checking if class scala.runtime.BoxedUnit matches void +Some(undefined) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t6662.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t6662.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t6662.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t7657.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t7657.check new file mode 100644 index 0000000000..1a87c1e866 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t7657.check @@ -0,0 +1,3 @@ +undefined +undefined +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t7763.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t7763.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t7763.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t8570a.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t8570a.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t8570a.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t8764.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t8764.check new file mode 100644 index 0000000000..121120217e --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t8764.check @@ -0,0 +1,5 @@ +IntOnly: should return an unboxed int +Int: int +IntAndDouble: should just box and return Anyval +Double: class java.lang.Byte +Int: class java.lang.Byte diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t9387b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t9387b.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t9387b.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t9656.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t9656.check new file mode 100644 index 0000000000..a16c04eaad --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/t9656.check @@ -0,0 +1,14 @@ +Range 1 to 10 +Range 1 to 10 +inexact Range 1 to 10 by 2 +Range 1 to 10 by 3 +inexact Range 1 until 10 by 2 +Range 100 to 100 +empty Range 100 until 100 +NumericRange 1 to 10 +NumericRange 1 to 10 by 2 +NumericRange 0.1 until 1 by 0.1 +NumericRange 0.1 until 1.0 by 0.1 +NumericRange 0.1 until 1 by 0.1 (using NumericRange 0.1 until 1 by 0.1 of BigDecimal) +NumericRange 0 days until 10 seconds by 1 second +empty NumericRange 0 days until 0 days by 1 second diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/try-catch-unify.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/try-catch-unify.check new file mode 100644 index 0000000000..813f01166d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/try-catch-unify.check @@ -0,0 +1,4 @@ +Failure(java.lang.NumberFormatException: For input string: "Hi") +Success(5) +O NOES +Failure(java.lang.NumberFormatException: For input string: "Hi") diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/virtpatmat_switch.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/virtpatmat_switch.check new file mode 100644 index 0000000000..0900a9ca32 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/virtpatmat_switch.check @@ -0,0 +1,7 @@ +zero +one +many +got a +got b +got some letter +scala.MatchError: 5 (of class java.lang.Byte) \ No newline at end of file diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/virtpatmat_typetag.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/virtpatmat_typetag.check new file mode 100644 index 0000000000..048c3aeed0 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/run/virtpatmat_typetag.check @@ -0,0 +1,10 @@ +1 is a Int +1 is a java.lang.Integer +1 is not a java.lang.String; it's a class java.lang.Byte +true is a Any +woele is a java.lang.String +1 is a Int +1 is a java.lang.Integer +1 is not a java.lang.String; it's a class java.lang.Byte +true is a Any +woele is a java.lang.String diff --git a/project/Build.scala b/project/Build.scala index ccca541d6b..24874a703f 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -64,7 +64,7 @@ object Build { CrossVersion.binaryMapped(v => s"sjs${previousSJSBinaryVersion}_$v") val scalaVersionsUsedForPublishing: Set[String] = - Set("2.10.6", "2.11.8", "2.12.0") + Set("2.10.6", "2.11.8", "2.12.1") val newScalaBinaryVersionsInThisRelease: Set[String] = Set() @@ -428,7 +428,8 @@ object Build { "2.11.6", "2.11.7", "2.11.8", - "2.12.0" + "2.12.0", + "2.12.1" ), // JDK version we are running with javaVersion in Global := { diff --git a/scala-test-suite/src/test/resources/2.12.1/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.12.1/BlacklistedTests.txt new file mode 100644 index 0000000000..c7b1f08622 --- /dev/null +++ b/scala-test-suite/src/test/resources/2.12.1/BlacklistedTests.txt @@ -0,0 +1,121 @@ +## Do not compile +scala/lang/annotations/BytecodeTest.scala +scala/lang/annotations/RunTest.scala +scala/lang/traits/BytecodeTest.scala +scala/lang/traits/RunTest.scala +scala/lang/primitives/NaNTest.scala +scala/lang/primitives/BoxUnboxTest.scala +scala/reflect/ClassOfTest.scala +scala/reflect/QTest.scala +scala/reflect/io/ZipArchiveTest.scala +scala/reflect/internal/util/AbstractFileClassLoaderTest.scala +scala/reflect/internal/util/SourceFileTest.scala +scala/reflect/internal/util/StringOpsTest.scala +scala/reflect/internal/PrintersTest.scala +scala/reflect/internal/ScopeTest.scala +scala/reflect/internal/TreeGenTest.scala +scala/reflect/internal/TypesTest.scala +scala/reflect/internal/util/WeakHashSetTest.scala +scala/reflect/internal/MirrorsTest.scala +scala/reflect/internal/NamesTest.scala +scala/tools/nsc/backend/jvm/BTypesTest.scala +scala/tools/nsc/backend/jvm/BytecodeTest.scala +scala/tools/nsc/backend/jvm/DefaultMethodTest.scala +scala/tools/nsc/backend/jvm/DirectCompileTest.scala +scala/tools/nsc/backend/jvm/IndyLambdaTest.scala +scala/tools/nsc/backend/jvm/IndySammyTest.scala +scala/tools/nsc/backend/jvm/OptimizedBytecodeTest.scala +scala/tools/nsc/backend/jvm/StringConcatTest.scala +scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala +scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala +scala/tools/nsc/backend/jvm/opt/AnalyzerTest.scala +scala/tools/nsc/backend/jvm/opt/BTypesFromClassfileTest.scala +scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala +scala/tools/nsc/backend/jvm/opt/ClosureOptimizerTest.scala +scala/tools/nsc/backend/jvm/opt/CompactLocalVariablesTest.scala +scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala +scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala +scala/tools/nsc/backend/jvm/opt/InlineInfoTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerIllegalAccessTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerTest.scala +scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala +scala/tools/nsc/backend/jvm/opt/MethodLevelOptsTest.scala +scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala +scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala +scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala +scala/tools/nsc/backend/jvm/opt/UnusedLocalVariablesTest.scala +scala/tools/nsc/ScriptRunnerTest.scala +scala/tools/nsc/classpath/AggregateClassPathTest.scala +scala/tools/nsc/classpath/PathResolverBaseTest.scala +scala/tools/nsc/classpath/VirtualDirectoryClassPathTest.scala +scala/tools/nsc/doc/html/HtmlDocletTest.scala +scala/tools/nsc/interpreter/CompletionTest.scala +scala/tools/nsc/interpreter/ScriptedTest.scala +scala/tools/nsc/interpreter/TabulatorTest.scala +scala/tools/nsc/settings/ScalaVersionTest.scala +scala/tools/nsc/settings/SettingsTest.scala +scala/tools/nsc/symtab/CannotHaveAttrsTest.scala +scala/tools/nsc/symtab/FlagsTest.scala +scala/tools/nsc/symtab/FreshNameExtractorTest.scala +scala/tools/nsc/symtab/StdNamesTest.scala +scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala +scala/tools/nsc/symtab/SymbolTableTest.scala +scala/tools/nsc/transform/delambdafy/DelambdafyTest.scala +scala/tools/nsc/transform/patmat/SolvingTest.scala +scala/tools/nsc/transform/patmat/PatmatBytecodeTest.scala +scala/tools/nsc/util/StackTraceTest.scala +scala/tools/testing/BytecodeTesting.scala +scala/tools/testing/RunTesting.scala + +## Do not link +scala/PartialFunctionSerializationTest.scala +scala/lang/stringinterpol/StringContextTest.scala +scala/collection/IteratorTest.scala +scala/collection/NewBuilderTest.scala +scala/collection/ParallelConsistencyTest.scala +scala/collection/SeqViewTest.scala +scala/collection/SetMapConsistencyTest.scala +scala/collection/convert/WrapperSerializationTest.scala +scala/collection/immutable/ListTest.scala +scala/collection/immutable/StreamTest.scala +scala/collection/immutable/StringLikeTest.scala +scala/collection/mutable/ArrayBufferTest.scala +scala/collection/mutable/MutableListTest.scala +scala/collection/mutable/OpenHashMapTest.scala +scala/collection/mutable/PriorityQueueTest.scala +scala/collection/parallel/immutable/ParRangeTest.scala +scala/concurrent/duration/SerializationTest.scala +scala/concurrent/impl/DefaultPromiseTest.scala +scala/io/SourceTest.scala +scala/runtime/ScalaRunTimeTest.scala +scala/sys/process/PipedProcessTest.scala +scala/sys/process/ProcessTest.scala +scala/tools/testing/AssertUtilTest.scala +scala/tools/testing/AssertThrowsTest.scala +scala/util/SpecVersionTest.scala +scala/util/SystemPropertiesTest.scala + +## Tests fail + +# Reflection +scala/reflect/ClassTagTest.scala + +# Regex +scala/util/matching/CharRegexTest.scala +scala/util/matching/RegexTest.scala + +# Require strict-floats +scala/math/BigDecimalTest.scala + +# Test fails only some times with +# 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' +# and' 'set scalaJSUseRhino in Global := false' +scala/collection/immutable/PagedSeqTest.scala + +# Bugs +scala/collection/convert/MapWrapperTest.scala + +# Tests passed but are too slow (timeouts) +scala/collection/immutable/ListSetTest.scala +scala/util/SortingTest.scala diff --git a/scala-test-suite/src/test/resources/2.12.1/WhitelistedTests.txt b/scala-test-suite/src/test/resources/2.12.1/WhitelistedTests.txt new file mode 100644 index 0000000000..59a038a21f --- /dev/null +++ b/scala-test-suite/src/test/resources/2.12.1/WhitelistedTests.txt @@ -0,0 +1,35 @@ +scala/collection/IndexedSeqOptimizedTest.scala +scala/collection/IterableViewLikeTest.scala +scala/collection/ReusableBuildersTest.scala +scala/collection/SearchingTest.scala +scala/collection/SeqLikeTest.scala +scala/collection/TraversableLikeTest.scala +scala/collection/TraversableOnceTest.scala +scala/collection/convert/NullSafetyToJavaTest.scala +scala/collection/convert/NullSafetyToScalaTest.scala +scala/collection/immutable/HashMapTest.scala +scala/collection/immutable/ListMapTest.scala +scala/collection/immutable/QueueTest.scala +scala/collection/immutable/RangeConsistencyTest.scala +scala/collection/immutable/SetTest.scala +scala/collection/immutable/TreeMapTest.scala +scala/collection/immutable/TreeSetTest.scala +scala/collection/immutable/VectorTest.scala +scala/collection/mutable/ArraySortingTest.scala +scala/collection/mutable/BitSetTest.scala +scala/collection/mutable/LinkedHashMapTest.scala +scala/collection/mutable/LinkedHashSetTest.scala +scala/collection/mutable/SetLikeTest.scala +scala/collection/mutable/UnrolledBufferTest.scala +scala/collection/mutable/VectorTest.scala +scala/lang/primitives/PredefAutoboxingTest.scala +scala/math/BigIntTest.scala +scala/math/NumericTest.scala +scala/math/OrderingTest.scala +scala/runtime/ZippedTest.scala +scala/tools/nsc/SampleTest.scala +scala/tools/testing/AssertUtil.scala +scala/tools/testing/TempDir.scala +scala/util/RandomTest.scala +scala/util/TryTest.scala +scala/util/control/ExceptionTest.scala diff --git a/scripts/build-all-js.sh b/scripts/build-all-js.sh index d34a0376fb..71aa7a6706 100755 --- a/scripts/build-all-js.sh +++ b/scripts/build-all-js.sh @@ -3,7 +3,7 @@ tasks="fastOptJS fullOptJS" projects="helloworld/ reversi/ testingExample/test: testSuite/test:" -for v in 2.11.8 2.10.6 2.12.0; do +for v in 2.11.8 2.10.6 2.12.1; do echo "++$v" echo "package" diff --git a/scripts/publish.sh b/scripts/publish.sh index 7e21707364..32a9e26484 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -8,8 +8,8 @@ else CMD="echo sbt" fi -FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.12.0" -BIN_VERSIONS="2.10.6 2.11.8 2.12.0" +FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.12.0 2.12.1" +BIN_VERSIONS="2.10.6 2.11.8 2.12.1" CLI_VERSIONS="2.10.6 2.11.8" SBT_VERSION="2.10.6" From 4d9d8b727271e4574657a8e0f51d4f906931e3ae Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 22 Oct 2016 23:39:00 +0200 Subject: [PATCH 0070/2665] Fix #2636: PropertyDefs should not be enumerable --- .../org/scalajs/core/compiler/GenJSCode.scala | 5 +---- .../testsuite/jsinterop/ExportsTest.scala | 10 ++++++++++ .../jsinterop/ScalaJSDefinedTest.scala | 18 ++++++++++++++++++ .../backend/emitter/ScalaJSClassEmitter.scala | 5 +---- 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 11159003b3..bcae89fddb 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -629,10 +629,7 @@ abstract class GenJSCode extends plugins.PluginComponent val descriptor = js.JSObjectConstr( optGetter.toList ++ optSetter ++ - List( - js.StringLiteral("configurable") -> js.BooleanLiteral(true), - js.StringLiteral("enumerable") -> js.BooleanLiteral(true) - ) + List(js.StringLiteral("configurable") -> js.BooleanLiteral(true)) ) js.JSBracketMethodApply(jsObject, js.StringLiteral("defineProperty"), diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index 40f95d1752..e7bd9986ac 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -198,6 +198,16 @@ class ExportsTest { assertEquals(7, bar.y) } + @Test def properties_are_not_enumerable(): Unit = { + class Foo { + @JSExport + def myProp: Int = 1 + } + + val x: js.Any = (new Foo()).asInstanceOf[js.Any] + assertFalse(js.Object.properties(x).contains("myProp")) + } + @Test def overloaded_exports_for_methods(): Unit = { class Foo { @JSExport("foobar") diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala index dee9d3eb29..35e787e103 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala @@ -565,6 +565,24 @@ class ScalaJSDefinedTest { assertEquals(100, dyn.foo()) } + @Test def properties_are_not_enumerable(): Unit = { + // Named classes + @ScalaJSDefined + class Foo extends js.Object { + def myProp: Int = 1 + } + + val x: js.Any = (new Foo()).asInstanceOf[js.Any] + assertFalse(js.Object.properties(x).contains("myProp")) + + // Anonymous classes + val y = new js.Object { + def myProp: Int = 1 + } + + assertFalse(js.Object.properties(y).contains("myProp")) + } + @Test def properties_are_configurable(): Unit = { // Named classes @ScalaJSDefined diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala index 305ca708ee..6442809000 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala @@ -381,10 +381,7 @@ private[emitter] final class ScalaJSClassEmitter( val descriptor = js.ObjectConstr( optGetter.toList ++ optSetter ++ - List( - js.StringLiteral("configurable") -> js.BooleanLiteral(true), - js.StringLiteral("enumerable") -> js.BooleanLiteral(true) - ) + List(js.StringLiteral("configurable") -> js.BooleanLiteral(true)) ) js.Apply(defProp, proto :: name :: descriptor :: Nil) From c9a01dc6eb97d84d9ca1af97daa34cbddcb4baa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 18 Dec 2016 15:18:00 +0100 Subject: [PATCH 0071/2665] Add a missing `@Test` in a JUnit test method. Because of that omission, the test was not run before. --- .../scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala index 00729e06f3..f8e05d2a78 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala @@ -225,7 +225,7 @@ class JSOptionalTest { assertEquals(Some(3), obj.z) } - def polyOptionalMethod(): Unit = { + @Test def polyOptionalMethod(): Unit = { @ScalaJSDefined trait TraitWithPolyOptionalMethod extends js.Object { def foo[A]: js.UndefOr[A] = js.undefined From b276afc4f48ebef15befbcd9a5bec2afb8416525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 18 Dec 2016 15:18:54 +0100 Subject: [PATCH 0072/2665] Add a helper `js.defined(x)` to drive type inference in some cases. When the expected type of an expression `x` is of the form `js.UndefOr[A]`, but an implicit conversion or a SAM conversion is required to type `x` as an `A`, the normal implicit conversion to `js.UndefOr[A]` does not work. We can use the helper `js.defined(x)` to drive Scala's type inference to apply the implicit conversion or the SAM conversion. This is particularly relevant for SAM conversion, for which even def any2undefOrA[A, B](a: A)(implicit ev: A => B): UndefOr[B] would not be enough to allow parameter type inference anyway. This is particularly important for configuration objects with function fields. --- .../scala/scala/scalajs/js/Thenable.scala | 5 +-- .../main/scala/scala/scalajs/js/defined.scala | 31 +++++++++++++++++++ .../jsinterop/JSOptionalTest212.scala | 14 +++++++++ .../testsuite/jsinterop/JSOptionalTest.scala | 15 +++++++++ .../testsuite/jsinterop/UndefOrTest.scala | 10 ++++++ 5 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 library/src/main/scala/scala/scalajs/js/defined.scala diff --git a/library/src/main/scala/scala/scalajs/js/Thenable.scala b/library/src/main/scala/scala/scalajs/js/Thenable.scala index cd34ce2eaf..2131ea9b23 100644 --- a/library/src/main/scala/scala/scalajs/js/Thenable.scala +++ b/library/src/main/scala/scala/scalajs/js/Thenable.scala @@ -47,16 +47,13 @@ object Thenable { * operations on it will be well-typed in turn. */ def toFuture: Future[A] = { - // Help for inference - def defined[A](x: A): js.UndefOr[A] = x - val p2 = scala.concurrent.Promise[A]() p.`then`[Unit]( { (v: A) => p2.success(v) (): Unit | Thenable[Unit] }, - defined { (e: scala.Any) => + js.defined { (e: scala.Any) => p2.failure(e match { case th: Throwable => th case _ => JavaScriptException(e) diff --git a/library/src/main/scala/scala/scalajs/js/defined.scala b/library/src/main/scala/scala/scalajs/js/defined.scala new file mode 100644 index 0000000000..7fc7249e2e --- /dev/null +++ b/library/src/main/scala/scala/scalajs/js/defined.scala @@ -0,0 +1,31 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js API ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package scala.scalajs.js + +import scala.scalajs.js + +object defined { // scalastyle:ignore + /** Explicitly upcasts an `A` to a `js.UndefOr[A]`. + * + * This method is useful in some cases to drive Scala's type inference. + * For example, when calling a method expecting a `js.UndefOr[js.FunctionN]` + * as shown below: + * + * {{{ + * def foo(f: js.UndefOr[js.Function1[Int, Int]] = js.undefined): Int = ??? + * + * foo((x: Int) => x + 1) // compile error (requires 2 chained implicits) + * foo(js.defined((x: Int) => x + 1)) // compiles + * + * // 2.12+ only: + * foo(js.defined(x => x + 1)) // compiles as well + * }}} + */ + def apply[A](a: A): js.UndefOr[A] = a +} diff --git a/test-suite/js/src/test/require-2.12/org/scalajs/testsuite/jsinterop/JSOptionalTest212.scala b/test-suite/js/src/test/require-2.12/org/scalajs/testsuite/jsinterop/JSOptionalTest212.scala index 0ce5c9e978..cd27c67489 100644 --- a/test-suite/js/src/test/require-2.12/org/scalajs/testsuite/jsinterop/JSOptionalTest212.scala +++ b/test-suite/js/src/test/require-2.12/org/scalajs/testsuite/jsinterop/JSOptionalTest212.scala @@ -204,6 +204,15 @@ class JSOptionalTest212 { obj.z = Some(3) assertEquals(Some(3), obj.z) } + + @Test def traitWithOptionalFunction(): Unit = { + val obj = new TraitWithOptionalFunction { + override val f = js.defined(x => x + 1) + } + + assertEquals("function", js.typeOf(obj.f)) + assertEquals(6, obj.f.get(5)) + } } object JSOptionalTest212 { @@ -242,4 +251,9 @@ object JSOptionalTest212 { override def y2 = "world" // scalastyle:ignore z = Some(5) } + + @ScalaJSDefined + trait TraitWithOptionalFunction extends js.Object { + val f: js.UndefOr[js.Function1[Int, Int]] = js.undefined + } } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala index f8e05d2a78..f56f4af49a 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala @@ -236,6 +236,16 @@ class JSOptionalTest { assertEquals(js.undefined, obj.foo[Int]) assertFalse(js.Object.hasProperty(obj, "foo")) } + + @Test def traitWithOptionalFunction(): Unit = { + val obj = new TraitWithOptionalFunction { + override val f: js.UndefOr[js.Function1[Int, Int]] = + js.defined((x: Int) => x + 1) + } + + assertEquals("function", js.typeOf(obj.f)) + assertEquals(6, obj.f.get(5)) + } } object JSOptionalTest { @@ -296,4 +306,9 @@ object JSOptionalTest { override val y = js.undefined override def y2 = js.undefined // scalastyle:ignore } + + @ScalaJSDefined + trait TraitWithOptionalFunction extends js.Object { + val f: js.UndefOr[js.Function1[Int, Int]] = js.undefined + } } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTest.scala index cab013e1cd..608204e46f 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTest.scala @@ -38,6 +38,16 @@ class UndefOrTest { assertThrows(classOf[NoSuchElementException], x.get) } + @Test def explicitly_convert_A_to_js_UndefOr_A(): Unit = { + val x: js.UndefOr[Int] = js.defined(42) + assertFalse(x.isEmpty) + assertEquals(42, x.get) + + val f: js.UndefOr[js.Function1[Int, Int]] = js.defined((x: Int) => x + 1) + assertFalse(f.isEmpty) + assertEquals(6, f.get(5)) + } + @Test def `convert_to_js_Any_when_A_<%_js_Any`(): Unit = { val x: js.UndefOr[Int] = 42 assertEquals(42, x) From 030f2bfc1aa7b0f61e05851267d263e07e5d4ceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 19 Dec 2016 10:53:52 +0100 Subject: [PATCH 0073/2665] Version 0.6.14. --- ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index a9b1d7d06c..3778e22a02 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.14-SNAPSHOT" + val current: String = "0.6.14" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" @@ -21,12 +21,12 @@ object ScalaJSVersions { * - a prior release version (i.e. "0.5.0", *not* "0.5.0-SNAPSHOT") * - `current` */ - val binaryEmitted: String = current + val binaryEmitted: String = "0.6.14" /** Versions whose binary files we can support (used by deserializer) */ val binarySupported: Set[String] = { Set("0.6.0", "0.6.3", "0.6.4", "0.6.5", "0.6.6", "0.6.8", "0.6.13", - binaryEmitted) + "0.6.14", binaryEmitted) } // Just to be extra safe From 7251bb8abd9a83fb8094ad3c0b1002f808cb50a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 20 Dec 2016 22:45:48 +0100 Subject: [PATCH 0074/2665] Towards 0.6.15. --- .../org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- project/BinaryIncompatibilities.scala | 36 ------------------- project/Build.scala | 2 +- 3 files changed, 2 insertions(+), 38 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index 3778e22a02..cb9f932c3d 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.14" + val current: String = "0.6.15-SNAPSHOT" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 4f32f871ed..c77318b933 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -3,45 +3,9 @@ import com.typesafe.tools.mima.core.ProblemFilters._ object BinaryIncompatibilities { val IR = Seq( - // private, not an issue - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.ir.Infos#GenInfoTraverser.generateExportedConstructorsInfo") ) val Tools = Seq( - // private[emitter], not an issue - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genDeclareModule"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genDeclareTypeData"), - - // private, not an issue - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring#Env.this"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring#JSDesugar.this"), - - // Breaking (remove js.EmptyTree) - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.tools.javascript.Trees#Let.apply"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.tools.javascript.Trees#Let.copy"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.core.tools.javascript.Trees#Let.rhs"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.tools.javascript.Trees#Let.this"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.tools.javascript.Trees$Try"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.tools.javascript.Trees$Try$"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.tools.javascript.Trees#VarDef.apply"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.tools.javascript.Trees#VarDef.copy"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.core.tools.javascript.Trees#VarDef.rhs"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.tools.javascript.Trees#VarDef.this") ) val JSEnvs = Seq( diff --git a/project/Build.scala b/project/Build.scala index 24874a703f..116bfb2b21 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -57,7 +57,7 @@ object Build { val shouldPartest = settingKey[Boolean]( "Whether we should partest the current scala version (and fail if we can't)") - val previousVersion = "0.6.13" + val previousVersion = "0.6.14" val previousSJSBinaryVersion = ScalaJSCrossVersion.binaryScalaJSVersion(previousVersion) val previousBinaryCrossVersion = From 3ce12cccb80da925023db6aec0e68b795822d20c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 22 Dec 2016 15:59:11 +0100 Subject: [PATCH 0075/2665] Fix #2694: Blacklist partest pos/t9181.scala. It's an artificially giant `if/else if/.../else` chain, which causes nesting of `If` nodes in our IR. This kills our IR serializer with a `StackOverflowException`. Blacklisting as won't fix, until and unless a Scala.js user hits that limitation in real life. --- .../scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt | 3 +++ .../scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt | 3 +++ .../scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt | 3 +++ .../scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt | 3 +++ .../scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt | 1 - 8 files changed, 12 insertions(+), 4 deletions(-) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt index fd6505a7ef..0dc70a2a0f 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt @@ -10,6 +10,9 @@ pos/t533.scala pos/functions.scala pos/MailBox.scala +# Kills our IR serializer, it's an artificially super-deep if/else if +pos/t9181.scala + # # NEG # diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt index b8951c8684..b737210a0c 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt @@ -943,7 +943,6 @@ pos/t9356 pos/virtpatmat_exhaust_big.scala pos/t9239 pos/t9111-inliner-workaround -pos/t9181.scala neg/volatile_no_override.scala neg/t800.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt index 9ebf87fdbf..007bc3af55 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt @@ -10,6 +10,9 @@ pos/t533.scala pos/functions.scala pos/MailBox.scala +# Kills our IR serializer, it's an artificially super-deep if/else if +pos/t9181.scala + # # NEG # diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt index 7d8dcb463b..4d2946257f 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt @@ -943,7 +943,6 @@ pos/t9356 pos/virtpatmat_exhaust_big.scala pos/t9239 pos/t9111-inliner-workaround -pos/t9181.scala neg/volatile_no_override.scala neg/t800.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt index ce1cf65299..52594133a7 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt @@ -5,6 +5,9 @@ # Using Jsoup, what's that? pos/cycle-jsoup.scala +# Kills our IR serializer, it's an artificially super-deep if/else if +pos/t9181.scala + # # NEG # diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt index 199f0598ba..9a02f81e9a 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt @@ -931,7 +931,6 @@ pos/t9356 pos/virtpatmat_exhaust_big.scala pos/t9239 pos/t9111-inliner-workaround -pos/t9181.scala neg/volatile_no_override.scala neg/t800.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt index e605c60168..7aee11c040 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt @@ -5,6 +5,9 @@ # Using Jsoup, what's that? pos/cycle-jsoup.scala +# Kills our IR serializer, it's an artificially super-deep if/else if +pos/t9181.scala + # # NEG # diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt index e45b1fdc7f..c2153da8ba 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt @@ -929,7 +929,6 @@ pos/t9356 pos/virtpatmat_exhaust_big.scala pos/t9239 pos/t9111-inliner-workaround -pos/t9181.scala neg/volatile_no_override.scala neg/t800.scala From 480334e2f2f855252a82f29aa37111c523c83409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 22 Dec 2016 17:21:34 +0100 Subject: [PATCH 0076/2665] Fix #2519: Test the behavior of setting readonly properties. * Exports of `val`s and `def`s without parentheses * `def`s without parentheses in Scala.js-defined JS classes --- .../testsuite/jsinterop/ExportsTest.scala | 25 +++++++++++++++- .../jsinterop/ScalaJSDefinedTest.scala | 29 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index e7bd9986ac..4258a29fba 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -20,7 +20,8 @@ import org.junit.Assert._ import org.junit.Assume._ import org.junit.Test -import org.scalajs.testsuite.utils.JSUtils +import org.scalajs.testsuite.utils.{JSUtils, Platform} +import org.scalajs.testsuite.utils.AssertThrows.assertThrows class ExportsTest { @@ -198,6 +199,28 @@ class ExportsTest { assertEquals(7, bar.y) } + @Test def readonly_properties(): Unit = { + assumeFalse( + "Assuming strict mode semantics, which are not honored by Rhino", + Platform.executingInRhino) + + class Foo { + @JSExport + val foo: Int = 1 + @JSExport + def bar: Int = 1 + } + + val x: js.Dynamic = (new Foo()).asInstanceOf[js.Dynamic] + + assertThrows(classOf[js.JavaScriptException], { + x.foo = 2 + }) + assertThrows(classOf[js.JavaScriptException], { + x.bar = 2 + }) + } + @Test def properties_are_not_enumerable(): Unit = { class Foo { @JSExport diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala index 35e787e103..5fe6569921 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala @@ -11,9 +11,12 @@ import scala.scalajs.js import scala.scalajs.js.annotation._ import org.junit.Assert._ +import org.junit.Assume._ import org.junit.Test import org.scalajs.testsuite.utils.JSAssert._ +import org.scalajs.testsuite.utils.Platform +import org.scalajs.testsuite.utils.AssertThrows.assertThrows class ScalaJSDefinedTest { import org.scalajs.testsuite.jsinterop.{ScalaJSDefinedTestSeparateRun => SepRun} @@ -565,6 +568,32 @@ class ScalaJSDefinedTest { assertEquals(100, dyn.foo()) } + @Test def readonly_properties(): Unit = { + assumeFalse( + "Assuming strict mode semantics, which are not honored by Rhino", + Platform.executingInRhino) + + // Named classes + @ScalaJSDefined + class Foo extends js.Object { + def bar: Int = 1 + } + + val x: js.Dynamic = (new Foo()).asInstanceOf[js.Dynamic] + assertThrows(classOf[js.JavaScriptException], { + x.bar = 2 + }) + + // Anonymous classes + val y = new js.Object { + def bar: Int = 1 + }.asInstanceOf[js.Dynamic] + + assertThrows(classOf[js.JavaScriptException], { + y.bar = 2 + }) + } + @Test def properties_are_not_enumerable(): Unit = { // Named classes @ScalaJSDefined From 813d2e3876ec2ce81a63b32e592096a25dde86b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 22 Dec 2016 18:17:13 +0100 Subject: [PATCH 0077/2665] Upgrade to sbt 0.13.13. Since sbt 0.13.13 deprecates all the so-called fishbone operators, we have to replace them by `.value`s and `.taskValue`s even where this is (arguably) less readable. --- project/Build.scala | 24 +++--- project/ExternalCompile.scala | 2 +- project/build.properties | 2 +- project/build.sbt | 4 +- .../sbtplugin/ScalaJSPluginInternal.scala | 73 ++++++++++--------- 5 files changed, 55 insertions(+), 50 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 116bfb2b21..a96391733c 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -568,11 +568,11 @@ object Build { unmanagedSourceDirectories in Test += baseDirectory.value.getParentFile / "shared/src/test/scala", - sourceGenerators in Compile <+= Def.task { + sourceGenerators in Compile += Def.task { ScalaJSEnvGenerator.generateEnvHolder( baseDirectory.value.getParentFile, (sourceManaged in Compile).value) - }, + }.taskValue, previousArtifactSetting, binaryIssueFilters ++= BinaryIncompatibilities.Tools, @@ -596,7 +596,7 @@ object Build { base = file("tools/js"), settings = myScalaJSSettings ++ commonToolsSettings ++ Seq( crossVersion := ScalaJSCrossVersion.binary, - resourceGenerators in Test <+= Def.task { + resourceGenerators in Test += Def.task { val base = (resourceManaged in Compile).value IO.createDirectory(base) val outFile = base / "js-test-definitions.js" @@ -609,7 +609,7 @@ object Build { IO.write(outFile, testDefinitions) Seq(outFile) - }, + }.taskValue, jsDependencies += ProvidedJS / "js-test-definitions.js" % "test" ) ++ inConfig(Test) { // Redefine test to run Node.js and link HelloWorld @@ -793,13 +793,13 @@ object Build { delambdafySetting, noClassFilesSettings, - resourceGenerators in Compile <+= Def.task { + resourceGenerators in Compile += Def.task { val base = (resourceManaged in Compile).value Seq( serializeHardcodedIR(base, JavaLangObject.InfoAndTree), serializeHardcodedIR(base, JavaLangString.InfoAndTree) ) - } + }.taskValue ) ++ ( scalaJSExternalCompileSettings ) @@ -1361,13 +1361,13 @@ object Build { }, // Fail if we are not in the right stage. - testHtmlKey in Test <<= (testHtmlKey in Test) dependsOn Def.task { + testHtmlKey in Test := (testHtmlKey in Test).dependsOn(Def.task { if (scalaJSStage.value != targetStage) { sys.error("In the Scala.js test-suite, the testHtml* tasks need " + "scalaJSStage to be set to their respecitve stage. Stage is: " + scalaJSStage.value) } - } + }).value ) lazy val testSuite: Project = Project( @@ -1406,7 +1406,7 @@ object Build { * * see test-suite/src/test/resources/SourceMapTestTemplate.scala */ - sourceGenerators in Test <+= Def.task { + sourceGenerators in Test += Def.task { val dir = (sourceManaged in Test).value IO.createDirectory(dir) @@ -1439,7 +1439,7 @@ object Build { IO.write(outFile, replaced.replace("@Test def workTest(): Unit = sys.error(\"stubs\")", unitTests)) Seq(outFile) - }, + }.taskValue, // Exclude tests based on version-dependent bugs sources in Test := { @@ -1613,7 +1613,7 @@ object Build { else Seq() }, - definedTests in Test <++= Def.taskDyn[Seq[sbt.TestDefinition]] { + definedTests in Test ++= Def.taskDyn[Seq[sbt.TestDefinition]] { if (shouldPartest.value) Def.task { val _ = (fetchScalaSource in partest).value Seq(new sbt.TestDefinition( @@ -1630,7 +1630,7 @@ object Build { } else { Def.task(Seq()) } - } + }.value ) ).dependsOn(partest % "test", library) diff --git a/project/ExternalCompile.scala b/project/ExternalCompile.scala index 05487fffc5..d99a5d8ce0 100644 --- a/project/ExternalCompile.scala +++ b/project/ExternalCompile.scala @@ -105,7 +105,7 @@ object ExternalCompile { // Make sure jsDependencyManifest runs after compile, otherwise compile // might remove the entire directory afterwards. - jsDependencyManifest <<= jsDependencyManifest.dependsOn(compile) + jsDependencyManifest := jsDependencyManifest.dependsOn(compile).value ) val scalaJSExternalCompileSettings = ( diff --git a/project/build.properties b/project/build.properties index 817bc38df8..27e88aa115 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.9 +sbt.version=0.13.13 diff --git a/project/build.sbt b/project/build.sbt index 91c65051e9..e6dc1f09f9 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -42,11 +42,11 @@ unmanagedSourceDirectories in Compile ++= { sources in Compile += baseDirectory.value / "project" / "ScalaJSEnvGenerator.scala" -sourceGenerators in Compile <+= Def.task { +sourceGenerators in Compile += Def.task { ScalaJSEnvGenerator.generateEnvHolder( baseDirectory.value.getParentFile / "tools", (sourceManaged in Compile).value) -} +}.taskValue unmanagedResourceDirectories in Compile += { val root = baseDirectory.value.getParentFile diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 53f4164cdb..9375c56b3e 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -141,7 +141,7 @@ object ScalaJSPluginInternal { private def packageJSDependenciesSetting(taskKey: TaskKey[File], cacheName: String, getLib: ResolvedJSDependency => VirtualJSFile): Setting[Task[File]] = { - taskKey <<= Def.taskDyn { + taskKey := Def.taskDyn { if ((skip in taskKey).value) Def.task((artifactPath in taskKey).value) else Def.task { @@ -165,7 +165,7 @@ object ScalaJSPluginInternal { output } - } + }.value } /** Settings for the production key (e.g. fastOptJS) of a given stage */ @@ -226,7 +226,7 @@ object ScalaJSPluginInternal { concurrentRestrictions in Global += Tags.limit((usesScalaJSLinkerTag in key).value, 1), - key <<= Def.taskDyn { + key := Def.taskDyn { val s = (streams in key).value val log = s.log val irInfo = (scalaJSIR in key).value @@ -258,25 +258,25 @@ object ScalaJSPluginInternal { val sourceMapFile = FileVirtualJSFile(output).sourceMapFile Attributed.blank(output).put(scalaJSSourceMap, sourceMapFile) } tag((usesScalaJSLinkerTag in key).value) - }, + }.value, - key <<= key.dependsOn(packageJSDependencies, packageScalaJSLauncher), + key := key.dependsOn(packageJSDependencies, packageScalaJSLauncher).value, scalaJSLinkedFile in key := new FileVirtualJSFile(key.value.data) ) private def dispatchSettingKeySettings[T](key: SettingKey[T]) = Seq( - key <<= Def.settingDyn { + key := Def.settingDyn { val stageKey = stageKeys(scalaJSStage.value) Def.setting { (key in stageKey).value } - } + }.value ) private def dispatchTaskKeySettings[T](key: TaskKey[T]) = Seq( - key <<= Def.taskDyn { + key := Def.taskDyn { val stageKey = stageKeys(scalaJSStage.value) Def.task { (key in stageKey).value } - } + }.value ) private def scalajspSettings: Seq[Setting[_]] = { @@ -306,9 +306,9 @@ object ScalaJSPluginInternal { } Seq( - sjsirFilesOnClasspath <<= Def.task { + sjsirFilesOnClasspath := Def.task { scalaJSIR.value.data.map(_.relativePath).toSeq - } storeAs(sjsirFilesOnClasspath) triggeredBy(scalaJSIR), + }.storeAs(sjsirFilesOnClasspath).triggeredBy(scalaJSIR).value, scalajsp := { val (options, relPath) = parser.parsed @@ -381,8 +381,9 @@ object ScalaJSPluginInternal { * Also note that it doesn't get cleared by the sbt's clean task. */ scalaJSIRCacheHolder := globalIRCache.newCache, - scalaJSIRCache <<= - Def.task(scalaJSIRCacheHolder.value).dependsOn(scalaJSClearCacheStats), + scalaJSIRCache := Def.task { + scalaJSIRCacheHolder.value + }.dependsOn(scalaJSClearCacheStats).value, scalaJSIR := { import IRFileCache.IRContainer @@ -412,7 +413,7 @@ object ScalaJSPluginInternal { prev.withUseClosureCompiler(outputMode == OutputMode.ECMAScript51Isolated) }, - fullOptJS <<= fullOptJS.dependsOn(packageMinifiedJSDependencies), + fullOptJS := fullOptJS.dependsOn(packageMinifiedJSDependencies).value, artifactPath in packageScalaJSLauncher := ((crossTarget in packageScalaJSLauncher).value / @@ -428,7 +429,7 @@ object ScalaJSPluginInternal { value }, - packageScalaJSLauncher <<= Def.taskDyn { + packageScalaJSLauncher := Def.taskDyn { if ((skip in packageScalaJSLauncher).value) { Def.task { Attributed.blank((artifactPath in packageScalaJSLauncher).value) @@ -451,7 +452,7 @@ object ScalaJSPluginInternal { } } } - }, + }.value, artifactPath in packageJSDependencies := ((crossTarget in packageJSDependencies).value / @@ -512,12 +513,12 @@ object ScalaJSPluginInternal { file }, - products <<= products.dependsOn(jsDependencyManifest), + products := products.dependsOn(jsDependencyManifest).value, - 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.") - )), + 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.") + }).value, scalaJSNativeLibraries := { collectFromClasspath(fullClasspath.value, @@ -627,7 +628,7 @@ object ScalaJSPluginInternal { } }, - loadedJSEnv <<= Def.taskDyn { + loadedJSEnv := Def.taskDyn { val log = streams.value.log val libs = resolvedJSDependencies.value.data ++ scalaJSConfigurationLibs.value @@ -656,9 +657,9 @@ object ScalaJSPluginInternal { env.loadLibs(libs :+ ResolvedJSDependency.minimal(file)) } } - }, + }.value, - scalaJSModuleIdentifier <<= Def.taskDyn { + scalaJSModuleIdentifier := Def.taskDyn[Option[String]] { scalaJSModuleKind.value match { case ModuleKind.NoModule => Def.task { @@ -670,7 +671,7 @@ object ScalaJSPluginInternal { Some(scalaJSLinkedFile.value.path) } } - } + }.value ) /** Run a class in a given environment using a given launcher */ @@ -738,7 +739,7 @@ object ScalaJSPluginInternal { // These settings will be filtered by the stage dummy tasks val scalaJSRunSettings = Seq( mainClass in scalaJSLauncher := (mainClass in run).value, - scalaJSLauncher <<= Def.taskDyn { + scalaJSLauncher := Def.taskDyn[Attributed[VirtualJSFile]] { if (persistLauncher.value) { Def.task { packageScalaJSLauncher.value.map(FileVirtualJSFile) @@ -757,12 +758,12 @@ object ScalaJSPluginInternal { } } } - }, + }.value, - discoveredMainClasses <<= compile.map(discoverJSApps). - storeAs(discoveredMainClasses).triggeredBy(compile), + discoveredMainClasses := compile.map(discoverJSApps). + storeAs(discoveredMainClasses).triggeredBy(compile).value, - run <<= Def.inputTask { + run := { // use assert to prevent warning about pure expr in stat pos assert(scalaJSEnsureUnforked.value) @@ -820,8 +821,10 @@ object ScalaJSPluginInternal { }, // Override default to avoid triggering a test:fastOptJS in a test:compile // without loosing autocompletion. - definedTestNames <<= definedTests map (_.map(_.name).distinct) - storeAs definedTestNames triggeredBy loadedJSEnv + definedTestNames := { + definedTests.map(_.map(_.name).distinct) + .storeAs(definedTestNames).triggeredBy(loadedJSEnv).value + } ) val scalaJSTestBuildSettings = ( @@ -937,13 +940,15 @@ object ScalaJSPluginInternal { scalaJSConsole := ConsoleJSConsole, - clean <<= clean.dependsOn(Def.task { + clean := { // have clean reset incremental linker state + val _ = clean.value (scalaJSLinker in (Compile, fastOptJS)).value.clear() (scalaJSLinker in (Test, fastOptJS)).value.clear() (scalaJSLinker in (Compile, fullOptJS)).value.clear() (scalaJSLinker in (Test, fullOptJS)).value.clear() - }), + () + }, /* Depend on jetty artifacts in dummy configuration to be able to inject * them into the PhantomJS runner if necessary. From 0e21974d93f59b68b760e8f6e250ae82ccd84eae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 22 Dec 2016 19:09:16 +0100 Subject: [PATCH 0078/2665] Address two deprecation warnings in our build. --- project/Build.scala | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index a96391733c..3afb678ec3 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -7,7 +7,7 @@ import bintray.Plugin.bintrayPublishSettings import bintray.Keys.{repository, bintrayOrganization, bintray} import com.typesafe.tools.mima.plugin.MimaPlugin.mimaDefaultSettings -import com.typesafe.tools.mima.plugin.MimaKeys.{previousArtifact, binaryIssueFilters} +import com.typesafe.tools.mima.plugin.MimaKeys.{previousArtifacts, binaryIssueFilters} import java.io.{ BufferedOutputStream, @@ -90,15 +90,15 @@ object Build { else Nil val previousArtifactSetting: Setting[_] = { - previousArtifact := { + previousArtifacts ++= { val scalaV = scalaVersion.value val scalaBinaryV = scalaBinaryVersion.value if (!scalaVersionsUsedForPublishing.contains(scalaV)) { // This artifact will not be published. Binary compatibility is irrelevant. - None + Set.empty } else if (newScalaBinaryVersionsInThisRelease.contains(scalaBinaryV)) { // New in this release, no binary compatibility to comply to - None + Set.empty } else { val thisProjectID = projectID.value val previousCrossVersion = thisProjectID.crossVersion match { @@ -114,7 +114,7 @@ object Build { (thisProjectID.organization % thisProjectID.name % previousVersion) .cross(previousCrossVersion) .extra(prevExtraAttributes.toSeq: _*) - Some(CrossVersion(scalaV, scalaBinaryV)(prevProjectID).cross(CrossVersion.Disabled)) + Set(CrossVersion(scalaV, scalaBinaryV)(prevProjectID).cross(CrossVersion.Disabled)) } } } @@ -616,7 +616,7 @@ object Build { test := { val jsEnv = resolvedJSEnv.value if (!jsEnv.isInstanceOf[NodeJSEnv]) - error("toolsJS/test must be run with Node.js") + sys.error("toolsJS/test must be run with Node.js") /* Collect IR relevant files from the classpath * We assume here that the classpath is valid. This is checked by the From f0099a9a3c82d7b192c4c8cda60a4c891271f5d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 22 Dec 2016 19:18:50 +0100 Subject: [PATCH 0079/2665] Upgrade to sbt-mima-plugin 0.1.13. This fixes #2270. --- project/Build.scala | 25 ++++++++++++------------- project/build.sbt | 2 +- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 3afb678ec3..107c851795 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -6,8 +6,7 @@ import scala.annotation.tailrec import bintray.Plugin.bintrayPublishSettings import bintray.Keys.{repository, bintrayOrganization, bintray} -import com.typesafe.tools.mima.plugin.MimaPlugin.mimaDefaultSettings -import com.typesafe.tools.mima.plugin.MimaKeys.{previousArtifacts, binaryIssueFilters} +import com.typesafe.tools.mima.plugin.MimaPlugin.autoImport._ import java.io.{ BufferedOutputStream, @@ -90,7 +89,7 @@ object Build { else Nil val previousArtifactSetting: Setting[_] = { - previousArtifacts ++= { + mimaPreviousArtifacts ++= { val scalaV = scalaVersion.value val scalaBinaryV = scalaBinaryVersion.value if (!scalaVersionsUsedForPublishing.contains(scalaV)) { @@ -248,7 +247,7 @@ object Build { if (errorsSeen.size > 0) sys.error("ScalaDoc patching had errors") else outDir } - ) ++ mimaDefaultSettings + ) val noClassFilesSettings: Setting[_] = ( scalacOptions in (Compile, compile) ++= { @@ -482,7 +481,7 @@ object Build { ) ++ Seq( name := "Scala.js IR", previousArtifactSetting, - binaryIssueFilters ++= BinaryIncompatibilities.IR, + mimaBinaryIssueFilters ++= BinaryIncompatibilities.IR, exportJars := true, // required so ScalaDoc linking works testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a", "-s") @@ -575,7 +574,7 @@ object Build { }.taskValue, previousArtifactSetting, - binaryIssueFilters ++= BinaryIncompatibilities.Tools, + mimaBinaryIssueFilters ++= BinaryIncompatibilities.Tools, exportJars := true // required so ScalaDoc linking works ) @@ -680,7 +679,7 @@ object Build { "org.webjars" % "envjs" % "1.2" ) ++ ScalaJSPluginInternal.phantomJSJettyModules.map(_ % "provided"), previousArtifactSetting, - binaryIssueFilters ++= BinaryIncompatibilities.JSEnvs + mimaBinaryIssueFilters ++= BinaryIncompatibilities.JSEnvs ) ).dependsOn(tools) @@ -694,7 +693,7 @@ object Build { libraryDependencies += "junit" % "junit" % "4.8.2", previousArtifactSetting, - binaryIssueFilters ++= BinaryIncompatibilities.JSEnvsTestKit + mimaBinaryIssueFilters ++= BinaryIncompatibilities.JSEnvsTestKit ) ).dependsOn(tools, jsEnvs) @@ -720,7 +719,7 @@ object Build { name := "Scala.js sbt test adapter", libraryDependencies += "org.scala-sbt" % "test-interface" % "1.0", previousArtifactSetting, - binaryIssueFilters ++= BinaryIncompatibilities.TestAdapter + mimaBinaryIssueFilters ++= BinaryIncompatibilities.TestAdapter ) ).dependsOn(jsEnvs) @@ -737,7 +736,7 @@ object Build { scalaBinaryVersion := CrossVersion.binaryScalaVersion(scalaVersion.value), previousArtifactSetting, - binaryIssueFilters ++= BinaryIncompatibilities.SbtPlugin, + mimaBinaryIssueFilters ++= BinaryIncompatibilities.SbtPlugin, // Add API mappings for sbt (seems they don't export their API URL) apiMappings ++= { @@ -1000,7 +999,7 @@ object Build { scalacOptions in (Compile, doc) ++= Seq("-implicits", "-groups"), exportJars := !isGeneratingEclipse, previousArtifactSetting, - binaryIssueFilters ++= BinaryIncompatibilities.Library, + mimaBinaryIssueFilters ++= BinaryIncompatibilities.Library, libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value % "provided" ) ++ ( @@ -1079,7 +1078,7 @@ object Build { ), previousArtifactSetting, - binaryIssueFilters ++= BinaryIncompatibilities.CLI, + mimaBinaryIssueFilters ++= BinaryIncompatibilities.CLI, // assembly options mainClass in assembly := None, // don't want an executable JAR @@ -1099,7 +1098,7 @@ object Build { name := "Scala.js test interface", delambdafySetting, previousArtifactSetting, - binaryIssueFilters ++= BinaryIncompatibilities.TestInterface + mimaBinaryIssueFilters ++= BinaryIncompatibilities.TestInterface ) ).withScalaJSCompiler.dependsOn(library) diff --git a/project/build.sbt b/project/build.sbt index e6dc1f09f9..e75b118b55 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -7,7 +7,7 @@ addSbtPlugin("me.lessis" % "bintray-sbt" % "0.1.2") addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.1") -addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.8") +addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.13") addSbtPlugin("org.scalastyle" % "scalastyle-sbt-plugin" % "0.8.0") From 24f8f1fd72a8e3b50d6fc91524729fd7f569309c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 22 Dec 2016 20:31:40 +0100 Subject: [PATCH 0080/2665] Upgrade to sbt-assembly 0.14.3. --- project/build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.sbt b/project/build.sbt index e75b118b55..bf5d5aa160 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -5,7 +5,7 @@ resolvers += Resolver.url( addSbtPlugin("me.lessis" % "bintray-sbt" % "0.1.2") -addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.1") +addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.3") addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.13") From b3aae21da7261e5ddfbb91ba1ab0c4cdaafb89ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 22 Dec 2016 20:36:49 +0100 Subject: [PATCH 0081/2665] Fix #2677: Build and publish CLI for 2.12. This requires upgrading scopt to 3.5.0, which is the first version supporting 2.12. --- ci/matrix.xml | 4 ++++ project/Build.scala | 12 +++++++++++- scripts/assemble-cli.sh | 4 ++++ scripts/publish.sh | 2 +- 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/ci/matrix.xml b/ci/matrix.xml index b4909c9126..221139ec89 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -405,6 +405,10 @@ 2.11.8 1.8 + + 2.12.1 + 1.8 + diff --git a/project/Build.scala b/project/Build.scala index 107c851795..877531070c 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1074,12 +1074,22 @@ object Build { ) ++ Seq( name := "Scala.js CLI", libraryDependencies ++= Seq( - "com.github.scopt" %% "scopt" % "3.2.0" + "com.github.scopt" %% "scopt" % "3.5.0" ), previousArtifactSetting, mimaBinaryIssueFilters ++= BinaryIncompatibilities.CLI, + // TODO Remove this when going towards 0.6.16 + // Ignore bin compat of cli for 2.12 because it's new in 0.6.15. + mimaPreviousArtifacts := { + val scalaV = scalaVersion.value + if (scalaV.startsWith("2.10.") || scalaV.startsWith("2.11.")) + mimaPreviousArtifacts.value + else + Set.empty + }, + // assembly options mainClass in assembly := None, // don't want an executable JAR assemblyOption in assembly ~= { _.copy(includeScala = false) }, diff --git a/scripts/assemble-cli.sh b/scripts/assemble-cli.sh index 8dd3182b8f..684a690dc1 100755 --- a/scripts/assemble-cli.sh +++ b/scripts/assemble-cli.sh @@ -19,6 +19,10 @@ case $BINVER in FULLVERS="2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8" BASEVER="2.11.8" ;; + 2.12) + FULLVERS="2.12.0 2.12.1" + BASEVER="2.12.1" + ;; *) echo "Invalid Scala version $BINVER" >&2 exit 2 diff --git a/scripts/publish.sh b/scripts/publish.sh index 32a9e26484..55e36cf58c 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -10,7 +10,7 @@ fi FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.12.0 2.12.1" BIN_VERSIONS="2.10.6 2.11.8 2.12.1" -CLI_VERSIONS="2.10.6 2.11.8" +CLI_VERSIONS="2.10.6 2.11.8 2.12.1" SBT_VERSION="2.10.6" COMPILER="compiler jUnitPlugin" From 2e271d7bd178a42dad4e2a4799e92f3f5acd9c33 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Thu, 29 Dec 2016 16:58:06 +0100 Subject: [PATCH 0082/2665] Fix #2695: Add top-level directory to CLI packages --- scripts/assemble-cli.sh | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/scripts/assemble-cli.sh b/scripts/assemble-cli.sh index 684a690dc1..90fba6f168 100755 --- a/scripts/assemble-cli.sh +++ b/scripts/assemble-cli.sh @@ -54,12 +54,18 @@ if [ "$2" != "nobuild" ]; then ) | sbt || exit $? fi -# Copy stuff to right location +# Base Scala.js project directory. BASE="$(dirname $0)/.." +# Determine Scala.js version. +SCALAJS_VER=$(ls $BASE/cli/target/scala-$BINVER/scalajs-cli-assembly_$BINVER-*.jar | grep -oE '[0-9]+\.[0-9]+\.[0-9]+(-SNAPSHOT|-RC[0-9]+|-M[0-9]+)?') + +# Aritfact name (no extension). +NAME=scalajs_$BINVER-$SCALAJS_VER + # Target directories TRG_BASE="$BASE/cli/pack" -TRG_VER="$TRG_BASE/$BINVER" +TRG_VER="$TRG_BASE/$NAME" TRG_LIB="$TRG_VER/lib" TRG_BIN="$TRG_VER/bin" @@ -67,8 +73,7 @@ rm -rf $TRG_VER mkdir -p $TRG_LIB mkdir -p $TRG_BIN -SCALAJS_VER=$(ls $BASE/cli/target/scala-$BINVER/scalajs-cli-assembly_$BINVER-*.jar | grep -oE '[0-9]+\.[0-9]+\.[0-9]+(-SNAPSHOT|-RC[0-9]+|-M[0-9]+)?') - +# Copy buils artifacts. cp $BASE/cli/target/scala-$BINVER/scalajs-cli-assembly_$BINVER-$SCALAJS_VER.jar $TRG_LIB cp $BASE/library/target/scala-$BINVER/scalajs-library_$BINVER-$SCALAJS_VER.jar $TRG_LIB @@ -76,6 +81,7 @@ for i in $FULLVERS; do cp $BASE/compiler/target/scala-$BINVER/scalajs-compiler_$i-$SCALAJS_VER.jar $TRG_LIB done +# Build and copy launcher scripts. PAT="s/@SCALA_BIN_VER@/$BINVER/; s/@SCALAJS_VER@/$SCALAJS_VER/" PREF=$BASE/cli/src/main/resources/ for i in $PREF*; do @@ -90,11 +96,10 @@ for i in $PREF*; do done # Tar and zip the whole thing up -OUT=scalajs_$BINVER-$SCALAJS_VER - -tar cfz $TRG_BASE/$OUT.tgz --exclude '*~' -C $TRG_VER lib bin ( - if [ -f $OUT.zip ]; then rm $OUT.zip; fi - cd $TRG_VER - zip -r ../$OUT.zip -r lib bin -x '*~' + cd $TRG_BASE + tar cfz $NAME.tgz --exclude '*~' $NAME + + if [ -f $NAME.zip ]; then rm $NAME.zip; fi + zip -r $NAME.zip -r $NAME -x '*~' ) From 234c7ba0c3bbb17dfd650e796d95b7edddf6fd36 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 1 Jan 2017 16:11:58 +0100 Subject: [PATCH 0083/2665] Fix #2703: Hide private and boilerplate docs The idea of how to do this is stolen from the scala/scala build. --- .../scala/scalajs/js/Function.nodoc.scala | 114 +++ .../scala/scala/scalajs/js/Function.scala | 104 --- .../scala/scalajs/js/ThisFunction.nodoc.scala | 110 +++ .../scala/scala/scalajs/js/ThisFunction.scala | 99 --- .../scala/scala/scalajs/js/Tuple.nodoc.scala | 702 ++++++++++++++++++ .../main/scala/scala/scalajs/js/Tuple.scala | 690 ----------------- project/Build.scala | 27 +- 7 files changed, 952 insertions(+), 894 deletions(-) create mode 100644 library/src/main/scala/scala/scalajs/js/Function.nodoc.scala create mode 100644 library/src/main/scala/scala/scalajs/js/ThisFunction.nodoc.scala create mode 100644 library/src/main/scala/scala/scalajs/js/Tuple.nodoc.scala diff --git a/library/src/main/scala/scala/scalajs/js/Function.nodoc.scala b/library/src/main/scala/scala/scalajs/js/Function.nodoc.scala new file mode 100644 index 0000000000..577d5ee300 --- /dev/null +++ b/library/src/main/scala/scala/scalajs/js/Function.nodoc.scala @@ -0,0 +1,114 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js API ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +/* Definitions for js.Function3 to js.Function22 that do not show in doc */ +package scala.scalajs.js + +// scalastyle:off line.size.limit + +@native +trait Function3[-T1, -T2, -T3, +R] extends Function { + def apply(arg1: T1, arg2: T2, arg3: T3): R +} + +@native +trait Function4[-T1, -T2, -T3, -T4, +R] extends Function { + def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4): R +} + +@native +trait Function5[-T1, -T2, -T3, -T4, -T5, +R] extends Function { + def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5): R +} + +@native +trait Function6[-T1, -T2, -T3, -T4, -T5, -T6, +R] extends Function { + def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6): R +} + +@native +trait Function7[-T1, -T2, -T3, -T4, -T5, -T6, -T7, +R] extends Function { + def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7): R +} + +@native +trait Function8[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, +R] extends Function { + def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8): R +} + +@native +trait Function9[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, +R] extends Function { + def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9): R +} + +@native +trait Function10[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, +R] extends Function { + def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10): R +} + +@native +trait Function11[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, +R] extends Function { + def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11): R +} + +@native +trait Function12[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, +R] extends Function { + def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12): R +} + +@native +trait Function13[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, +R] extends Function { + def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13): R +} + +@native +trait Function14[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, +R] extends Function { + def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14): R +} + +@native +trait Function15[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, +R] extends Function { + def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15): R +} + +@native +trait Function16[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, +R] extends Function { + def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16): R +} + +@native +trait Function17[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, +R] extends Function { + def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17): R +} + +@native +trait Function18[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, +R] extends Function { + def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18): R +} + +@native +trait Function19[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, +R] extends Function { + def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19): R +} + +@native +trait Function20[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, +R] extends Function { + def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19, arg20: T20): R +} + +@native +trait Function21[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, +R] extends Function { + def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19, arg20: T20, arg21: T21): R +} + +@native +trait Function22[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, -T22, +R] extends Function { + def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19, arg20: T20, arg21: T21, arg22: T22): R +} + +// scalastyle:on line.size.limit diff --git a/library/src/main/scala/scala/scalajs/js/Function.scala b/library/src/main/scala/scala/scalajs/js/Function.scala index 6b1aaf1380..97fb598218 100644 --- a/library/src/main/scala/scala/scalajs/js/Function.scala +++ b/library/src/main/scala/scala/scalajs/js/Function.scala @@ -103,8 +103,6 @@ object Function extends Object { def apply(args: String*): Function = native } -// scalastyle:off line.size.limit - @native trait Function0[+R] extends Function { def apply(): R @@ -119,105 +117,3 @@ trait Function1[-T1, +R] extends Function { trait Function2[-T1, -T2, +R] extends Function { def apply(arg1: T1, arg2: T2): R } - -@native -trait Function3[-T1, -T2, -T3, +R] extends Function { - def apply(arg1: T1, arg2: T2, arg3: T3): R -} - -@native -trait Function4[-T1, -T2, -T3, -T4, +R] extends Function { - def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4): R -} - -@native -trait Function5[-T1, -T2, -T3, -T4, -T5, +R] extends Function { - def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5): R -} - -@native -trait Function6[-T1, -T2, -T3, -T4, -T5, -T6, +R] extends Function { - def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6): R -} - -@native -trait Function7[-T1, -T2, -T3, -T4, -T5, -T6, -T7, +R] extends Function { - def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7): R -} - -@native -trait Function8[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, +R] extends Function { - def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8): R -} - -@native -trait Function9[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, +R] extends Function { - def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9): R -} - -@native -trait Function10[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, +R] extends Function { - def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10): R -} - -@native -trait Function11[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, +R] extends Function { - def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11): R -} - -@native -trait Function12[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, +R] extends Function { - def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12): R -} - -@native -trait Function13[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, +R] extends Function { - def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13): R -} - -@native -trait Function14[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, +R] extends Function { - def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14): R -} - -@native -trait Function15[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, +R] extends Function { - def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15): R -} - -@native -trait Function16[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, +R] extends Function { - def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16): R -} - -@native -trait Function17[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, +R] extends Function { - def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17): R -} - -@native -trait Function18[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, +R] extends Function { - def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18): R -} - -@native -trait Function19[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, +R] extends Function { - def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19): R -} - -@native -trait Function20[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, +R] extends Function { - def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19, arg20: T20): R -} - -@native -trait Function21[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, +R] extends Function { - def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19, arg20: T20, arg21: T21): R -} - -@native -trait Function22[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, -T22, +R] extends Function { - def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19, arg20: T20, arg21: T21, arg22: T22): R -} - -// scalastyle:on line.size.limit diff --git a/library/src/main/scala/scala/scalajs/js/ThisFunction.nodoc.scala b/library/src/main/scala/scala/scalajs/js/ThisFunction.nodoc.scala new file mode 100644 index 0000000000..2dbc8d2941 --- /dev/null +++ b/library/src/main/scala/scala/scalajs/js/ThisFunction.nodoc.scala @@ -0,0 +1,110 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js API ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +/* Definitions for js.ThisFunction3 to js.ThisFunction22 that do not show in doc */ +package scala.scalajs.js + +// scalastyle:off line.size.limit + +@native +trait ThisFunction3[-T0, -T1, -T2, -T3, +R] extends ThisFunction { + def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3): R +} + +@native +trait ThisFunction4[-T0, -T1, -T2, -T3, -T4, +R] extends ThisFunction { + def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4): R +} + +@native +trait ThisFunction5[-T0, -T1, -T2, -T3, -T4, -T5, +R] extends ThisFunction { + def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5): R +} + +@native +trait ThisFunction6[-T0, -T1, -T2, -T3, -T4, -T5, -T6, +R] extends ThisFunction { + def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6): R +} + +@native +trait ThisFunction7[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, +R] extends ThisFunction { + def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7): R +} + +@native +trait ThisFunction8[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, +R] extends ThisFunction { + def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8): R +} + +@native +trait ThisFunction9[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, +R] extends ThisFunction { + def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9): R +} + +@native +trait ThisFunction10[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, +R] extends ThisFunction { + def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10): R +} + +@native +trait ThisFunction11[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, +R] extends ThisFunction { + def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11): R +} + +@native +trait ThisFunction12[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, +R] extends ThisFunction { + def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12): R +} + +@native +trait ThisFunction13[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, +R] extends ThisFunction { + def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13): R +} + +@native +trait ThisFunction14[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, +R] extends ThisFunction { + def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14): R +} + +@native +trait ThisFunction15[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, +R] extends ThisFunction { + def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15): R +} + +@native +trait ThisFunction16[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, +R] extends ThisFunction { + def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16): R +} + +@native +trait ThisFunction17[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, +R] extends ThisFunction { + def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17): R +} + +@native +trait ThisFunction18[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, +R] extends ThisFunction { + def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18): R +} + +@native +trait ThisFunction19[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, +R] extends ThisFunction { + def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19): R +} + +@native +trait ThisFunction20[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, +R] extends ThisFunction { + def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19, arg20: T20): R +} + +@native +trait ThisFunction21[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, +R] extends ThisFunction { + def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19, arg20: T20, arg21: T21): R +} + +// scalastyle:on line.size.limit diff --git a/library/src/main/scala/scala/scalajs/js/ThisFunction.scala b/library/src/main/scala/scala/scalajs/js/ThisFunction.scala index 8b0844449c..ad7532a29f 100644 --- a/library/src/main/scala/scala/scalajs/js/ThisFunction.scala +++ b/library/src/main/scala/scala/scalajs/js/ThisFunction.scala @@ -77,8 +77,6 @@ object ThisFunction { // scalastyle:on line.size.limit } -// scalastyle:off line.size.limit - @native trait ThisFunction0[-T0, +R] extends ThisFunction { def apply(thisArg: T0): R @@ -93,100 +91,3 @@ trait ThisFunction1[-T0, -T1, +R] extends ThisFunction { trait ThisFunction2[-T0, -T1, -T2, +R] extends ThisFunction { def apply(thisArg: T0, arg1: T1, arg2: T2): R } - -@native -trait ThisFunction3[-T0, -T1, -T2, -T3, +R] extends ThisFunction { - def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3): R -} - -@native -trait ThisFunction4[-T0, -T1, -T2, -T3, -T4, +R] extends ThisFunction { - def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4): R -} - -@native -trait ThisFunction5[-T0, -T1, -T2, -T3, -T4, -T5, +R] extends ThisFunction { - def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5): R -} - -@native -trait ThisFunction6[-T0, -T1, -T2, -T3, -T4, -T5, -T6, +R] extends ThisFunction { - def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6): R -} - -@native -trait ThisFunction7[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, +R] extends ThisFunction { - def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7): R -} - -@native -trait ThisFunction8[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, +R] extends ThisFunction { - def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8): R -} - -@native -trait ThisFunction9[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, +R] extends ThisFunction { - def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9): R -} - -@native -trait ThisFunction10[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, +R] extends ThisFunction { - def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10): R -} - -@native -trait ThisFunction11[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, +R] extends ThisFunction { - def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11): R -} - -@native -trait ThisFunction12[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, +R] extends ThisFunction { - def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12): R -} - -@native -trait ThisFunction13[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, +R] extends ThisFunction { - def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13): R -} - -@native -trait ThisFunction14[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, +R] extends ThisFunction { - def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14): R -} - -@native -trait ThisFunction15[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, +R] extends ThisFunction { - def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15): R -} - -@native -trait ThisFunction16[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, +R] extends ThisFunction { - def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16): R -} - -@native -trait ThisFunction17[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, +R] extends ThisFunction { - def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17): R -} - -@native -trait ThisFunction18[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, +R] extends ThisFunction { - def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18): R -} - -@native -trait ThisFunction19[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, +R] extends ThisFunction { - def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19): R -} - -@native -trait ThisFunction20[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, +R] extends ThisFunction { - def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19, arg20: T20): R -} - -@native -trait ThisFunction21[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, +R] extends ThisFunction { - def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19, arg20: T20, arg21: T21): R -} - -// scalastyle:on line.size.limit diff --git a/library/src/main/scala/scala/scalajs/js/Tuple.nodoc.scala b/library/src/main/scala/scala/scalajs/js/Tuple.nodoc.scala new file mode 100644 index 0000000000..89a79da575 --- /dev/null +++ b/library/src/main/scala/scala/scalajs/js/Tuple.nodoc.scala @@ -0,0 +1,702 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js API ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +/* Definitions for js.Tuple4 to js.Tuple22 that do not show in doc */ +package scala.scalajs.js + +import scala.scalajs.js.annotation.JSName +import scala.language.implicitConversions + +// scalastyle:off line.size.limit + +/** + * A tuple "view" of 4 elements of a JavaScript [[Array]]. + * + * @see [[Tuple2]] + */ +@native +sealed trait Tuple4[+T1, +T2, +T3, +T4] extends Object { + @JSName("0") val _1: T1 = native + @JSName("1") val _2: T2 = native + @JSName("2") val _3: T3 = native + @JSName("3") val _4: T4 = native +} + +object Tuple4 { + @inline def apply[T1, T2, T3, T4](_1: T1, _2: T2, _3: T3, _4: T4): Tuple4[T1, T2, T3, T4] = + Array(_1, _2, _3, _4).asInstanceOf[Tuple4[T1, T2, T3, T4]] + + @inline def unapply[T1, T2, T3, T4](t: Tuple4[T1, T2, T3, T4]): Option[(T1, T2, T3, T4)] = + Some(t) + + @inline implicit def fromScalaTuple4[T1, T2, T3, T4](t: (T1, T2, T3, T4)): Tuple4[T1, T2, T3, T4] = + apply(t._1, t._2, t._3, t._4) + + @inline implicit def toScalaTuple4[T1, T2, T3, T4](t: Tuple4[T1, T2, T3, T4]): (T1, T2, T3, T4) = + (t._1, t._2, t._3, t._4) +} + + +/** + * A tuple "view" of 5 elements of a JavaScript [[Array]]. + * + * @see [[Tuple2]] + */ +@native +sealed trait Tuple5[+T1, +T2, +T3, +T4, +T5] extends Object { + @JSName("0") val _1: T1 = native + @JSName("1") val _2: T2 = native + @JSName("2") val _3: T3 = native + @JSName("3") val _4: T4 = native + @JSName("4") val _5: T5 = native +} + +object Tuple5 { + @inline def apply[T1, T2, T3, T4, T5](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5): Tuple5[T1, T2, T3, T4, T5] = + Array(_1, _2, _3, _4, _5).asInstanceOf[Tuple5[T1, T2, T3, T4, T5]] + + @inline def unapply[T1, T2, T3, T4, T5](t: Tuple5[T1, T2, T3, T4, T5]): Option[(T1, T2, T3, T4, T5)] = + Some(t) + + @inline implicit def fromScalaTuple5[T1, T2, T3, T4, T5](t: (T1, T2, T3, T4, T5)): Tuple5[T1, T2, T3, T4, T5] = + apply(t._1, t._2, t._3, t._4, t._5) + + @inline implicit def toScalaTuple5[T1, T2, T3, T4, T5](t: Tuple5[T1, T2, T3, T4, T5]): (T1, T2, T3, T4, T5) = + (t._1, t._2, t._3, t._4, t._5) +} + +/** + * A tuple "view" of 6 elements of a JavaScript [[Array]]. + * + * @see [[Tuple2]] + */ +@native +sealed trait Tuple6[+T1, +T2, +T3, +T4, +T5, +T6] extends Object { + @JSName("0") val _1: T1 = native + @JSName("1") val _2: T2 = native + @JSName("2") val _3: T3 = native + @JSName("3") val _4: T4 = native + @JSName("4") val _5: T5 = native + @JSName("5") val _6: T6 = native +} + +object Tuple6 { + @inline def apply[T1, T2, T3, T4, T5, T6](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6): Tuple6[T1, T2, T3, T4, T5, T6] = + Array(_1, _2, _3, _4, _5, _6).asInstanceOf[Tuple6[T1, T2, T3, T4, T5, T6]] + + @inline def unapply[T1, T2, T3, T4, T5, T6](t: Tuple6[T1, T2, T3, T4, T5, T6]): Option[(T1, T2, T3, T4, T5, T6)] = + Some(t) + + @inline implicit def fromScalaTuple6[T1, T2, T3, T4, T5, T6](t: (T1, T2, T3, T4, T5, T6)): Tuple6[T1, T2, T3, T4, T5, T6] = + apply(t._1, t._2, t._3, t._4, t._5, t._6) + + @inline implicit def toScalaTuple6[T1, T2, T3, T4, T5, T6](t: Tuple6[T1, T2, T3, T4, T5, T6]): (T1, T2, T3, T4, T5, T6) = + (t._1, t._2, t._3, t._4, t._5, t._6) +} + +/** + * A tuple "view" of 7 elements of a JavaScript [[Array]]. + * + * @see [[Tuple2]] + */ +@native +sealed trait Tuple7[+T1, +T2, +T3, +T4, +T5, +T6, +T7] extends Object { + @JSName("0") val _1: T1 = native + @JSName("1") val _2: T2 = native + @JSName("2") val _3: T3 = native + @JSName("3") val _4: T4 = native + @JSName("4") val _5: T5 = native + @JSName("5") val _6: T6 = native + @JSName("6") val _7: T7 = native +} + +object Tuple7 { + @inline def apply[T1, T2, T3, T4, T5, T6, T7](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7): Tuple7[T1, T2, T3, T4, T5, T6, T7] = + Array(_1, _2, _3, _4, _5, _6, _7).asInstanceOf[Tuple7[T1, T2, T3, T4, T5, T6, T7]] + + @inline def unapply[T1, T2, T3, T4, T5, T6, T7](t: Tuple7[T1, T2, T3, T4, T5, T6, T7]): Option[(T1, T2, T3, T4, T5, T6, T7)] = + Some(t) + + @inline implicit def fromScalaTuple7[T1, T2, T3, T4, T5, T6, T7](t: (T1, T2, T3, T4, T5, T6, T7)): Tuple7[T1, T2, T3, T4, T5, T6, T7] = + apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7) + + @inline implicit def toScalaTuple7[T1, T2, T3, T4, T5, T6, T7](t: Tuple7[T1, T2, T3, T4, T5, T6, T7]): (T1, T2, T3, T4, T5, T6, T7) = + (t._1, t._2, t._3, t._4, t._5, t._6, t._7) +} + +/** + * A tuple "view" of 8 elements of a JavaScript [[Array]]. + * + * @see [[Tuple2]] + */ +@native +sealed trait Tuple8[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8] extends Object { + @JSName("0") val _1: T1 = native + @JSName("1") val _2: T2 = native + @JSName("2") val _3: T3 = native + @JSName("3") val _4: T4 = native + @JSName("4") val _5: T5 = native + @JSName("5") val _6: T6 = native + @JSName("6") val _7: T7 = native + @JSName("7") val _8: T8 = native +} + +object Tuple8 { + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8): Tuple8[T1, T2, T3, T4, T5, T6, T7, T8] = + Array(_1, _2, _3, _4, _5, _6, _7, _8).asInstanceOf[Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]] + + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8](t: Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]): Option[(T1, T2, T3, T4, T5, T6, T7, T8)] = + Some(t) + + @inline implicit def fromScalaTuple8[T1, T2, T3, T4, T5, T6, T7, T8](t: (T1, T2, T3, T4, T5, T6, T7, T8)): Tuple8[T1, T2, T3, T4, T5, T6, T7, T8] = + apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8) + + @inline implicit def toScalaTuple8[T1, T2, T3, T4, T5, T6, T7, T8](t: Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]): (T1, T2, T3, T4, T5, T6, T7, T8) = + (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8) +} + +/** + * A tuple "view" of 9 elements of a JavaScript [[Array]]. + * + * @see [[Tuple2]] + */ +@native +sealed trait Tuple9[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9] extends Object { + @JSName("0") val _1: T1 = native + @JSName("1") val _2: T2 = native + @JSName("2") val _3: T3 = native + @JSName("3") val _4: T4 = native + @JSName("4") val _5: T5 = native + @JSName("5") val _6: T6 = native + @JSName("6") val _7: T7 = native + @JSName("7") val _8: T8 = native + @JSName("8") val _9: T9 = native +} + +object Tuple9 { + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9): Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9] = + Array(_1, _2, _3, _4, _5, _6, _7, _8, _9).asInstanceOf[Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]] + + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9](t: Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9)] = + Some(t) + + @inline implicit def fromScalaTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9)): Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9] = + apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9) + + @inline implicit def toScalaTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9](t: Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]): (T1, T2, T3, T4, T5, T6, T7, T8, T9) = + (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9) +} + +/** + * A tuple "view" of 10 elements of a JavaScript [[Array]]. + * + * @see [[Tuple2]] + */ +@native +sealed trait Tuple10[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10] extends Object { + @JSName("0") val _1: T1 = native + @JSName("1") val _2: T2 = native + @JSName("2") val _3: T3 = native + @JSName("3") val _4: T4 = native + @JSName("4") val _5: T5 = native + @JSName("5") val _6: T6 = native + @JSName("6") val _7: T7 = native + @JSName("7") val _8: T8 = native + @JSName("8") val _9: T9 = native + @JSName("9") val _10: T10 = native +} + +object Tuple10 { + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10): Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10] = + Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10).asInstanceOf[Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]] + + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10](t: Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)] = + Some(t) + + @inline implicit def fromScalaTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)): Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10] = + apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10) + + @inline implicit def toScalaTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10](t: Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) = + (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10) +} + +/** + * A tuple "view" of 11 elements of a JavaScript [[Array]]. + * + * @see [[Tuple2]] + */ +@native +sealed trait Tuple11[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11] extends Object { + @JSName("0") val _1: T1 = native + @JSName("1") val _2: T2 = native + @JSName("2") val _3: T3 = native + @JSName("3") val _4: T4 = native + @JSName("4") val _5: T5 = native + @JSName("5") val _6: T6 = native + @JSName("6") val _7: T7 = native + @JSName("7") val _8: T8 = native + @JSName("8") val _9: T9 = native + @JSName("9") val _10: T10 = native + @JSName("10") val _11: T11 = native +} + +object Tuple11 { + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11): Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11] = + Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11).asInstanceOf[Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]] + + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11](t: Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)] = + Some(t) + + @inline implicit def fromScalaTuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)): Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11] = + apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11) + + @inline implicit def toScalaTuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11](t: Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) = + (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11) +} + +/** + * A tuple "view" of 12 elements of a JavaScript [[Array]]. + * + * @see [[Tuple2]] + */ +@native +sealed trait Tuple12[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12] extends Object { + @JSName("0") val _1: T1 = native + @JSName("1") val _2: T2 = native + @JSName("2") val _3: T3 = native + @JSName("3") val _4: T4 = native + @JSName("4") val _5: T5 = native + @JSName("5") val _6: T6 = native + @JSName("6") val _7: T7 = native + @JSName("7") val _8: T8 = native + @JSName("8") val _9: T9 = native + @JSName("9") val _10: T10 = native + @JSName("10") val _11: T11 = native + @JSName("11") val _12: T12 = native +} + +object Tuple12 { + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12): Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12] = + Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12).asInstanceOf[Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]] + + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12](t: Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)] = + Some(t) + + @inline implicit def fromScalaTuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)): Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12] = + apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12) + + @inline implicit def toScalaTuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12](t: Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) = + (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12) +} + +/** + * A tuple "view" of 13 elements of a JavaScript [[Array]]. + * + * @see [[Tuple2]] + */ +@native +sealed trait Tuple13[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13] extends Object { + @JSName("0") val _1: T1 = native + @JSName("1") val _2: T2 = native + @JSName("2") val _3: T3 = native + @JSName("3") val _4: T4 = native + @JSName("4") val _5: T5 = native + @JSName("5") val _6: T6 = native + @JSName("6") val _7: T7 = native + @JSName("7") val _8: T8 = native + @JSName("8") val _9: T9 = native + @JSName("9") val _10: T10 = native + @JSName("10") val _11: T11 = native + @JSName("11") val _12: T12 = native + @JSName("12") val _13: T13 = native +} + +object Tuple13 { + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13): Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13] = + Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13).asInstanceOf[Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]] + + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13](t: Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)] = + Some(t) + + @inline implicit def fromScalaTuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)): Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13] = + apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13) + + @inline implicit def toScalaTuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13](t: Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) = + (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13) +} + +/** + * A tuple "view" of 14 elements of a JavaScript [[Array]]. + * + * @see [[Tuple2]] + */ +@native +sealed trait Tuple14[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14] extends Object { + @JSName("0") val _1: T1 = native + @JSName("1") val _2: T2 = native + @JSName("2") val _3: T3 = native + @JSName("3") val _4: T4 = native + @JSName("4") val _5: T5 = native + @JSName("5") val _6: T6 = native + @JSName("6") val _7: T7 = native + @JSName("7") val _8: T8 = native + @JSName("8") val _9: T9 = native + @JSName("9") val _10: T10 = native + @JSName("10") val _11: T11 = native + @JSName("11") val _12: T12 = native + @JSName("12") val _13: T13 = native + @JSName("13") val _14: T14 = native +} + +object Tuple14 { + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14): Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14] = + Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14).asInstanceOf[Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]] + + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14](t: Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)] = + Some(t) + + @inline implicit def fromScalaTuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)): Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14] = + apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14) + + @inline implicit def toScalaTuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14](t: Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) = + (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14) +} + +/** + * A tuple "view" of 15 elements of a JavaScript [[Array]]. + * + * @see [[Tuple2]] + */ +@native +sealed trait Tuple15[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15] extends Object { + @JSName("0") val _1: T1 = native + @JSName("1") val _2: T2 = native + @JSName("2") val _3: T3 = native + @JSName("3") val _4: T4 = native + @JSName("4") val _5: T5 = native + @JSName("5") val _6: T6 = native + @JSName("6") val _7: T7 = native + @JSName("7") val _8: T8 = native + @JSName("8") val _9: T9 = native + @JSName("9") val _10: T10 = native + @JSName("10") val _11: T11 = native + @JSName("11") val _12: T12 = native + @JSName("12") val _13: T13 = native + @JSName("13") val _14: T14 = native + @JSName("14") val _15: T15 = native +} + +object Tuple15 { + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15): Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15] = + Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15).asInstanceOf[Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]] + + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15](t: Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)] = + Some(t) + + @inline implicit def fromScalaTuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)): Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15] = + apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15) + + @inline implicit def toScalaTuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15](t: Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) = + (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15) +} + +/** + * A tuple "view" of 16 elements of a JavaScript [[Array]]. + * + * @see [[Tuple16]] + */ +@native +sealed trait Tuple16[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16] extends Object { + @JSName("0") val _1: T1 = native + @JSName("1") val _2: T2 = native + @JSName("2") val _3: T3 = native + @JSName("3") val _4: T4 = native + @JSName("4") val _5: T5 = native + @JSName("5") val _6: T6 = native + @JSName("6") val _7: T7 = native + @JSName("7") val _8: T8 = native + @JSName("8") val _9: T9 = native + @JSName("9") val _10: T10 = native + @JSName("10") val _11: T11 = native + @JSName("11") val _12: T12 = native + @JSName("12") val _13: T13 = native + @JSName("13") val _14: T14 = native + @JSName("14") val _15: T15 = native + @JSName("15") val _16: T16 = native +} + +object Tuple16 { + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16): Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16] = + Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16).asInstanceOf[Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]] + + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16](t: Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16)] = + Some(t) + + @inline implicit def fromScalaTuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16)): Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16] = + apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16) + + @inline implicit def toScalaTuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16](t: Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) = + (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16) +} + +/** + * A tuple "view" of 17 elements of a JavaScript [[Array]]. + * + * @see [[Tuple2]] + */ +@native +sealed trait Tuple17[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17] extends Object { + @JSName("0") val _1: T1 = native + @JSName("1") val _2: T2 = native + @JSName("2") val _3: T3 = native + @JSName("3") val _4: T4 = native + @JSName("4") val _5: T5 = native + @JSName("5") val _6: T6 = native + @JSName("6") val _7: T7 = native + @JSName("7") val _8: T8 = native + @JSName("8") val _9: T9 = native + @JSName("9") val _10: T10 = native + @JSName("10") val _11: T11 = native + @JSName("11") val _12: T12 = native + @JSName("12") val _13: T13 = native + @JSName("13") val _14: T14 = native + @JSName("14") val _15: T15 = native + @JSName("15") val _16: T16 = native + @JSName("16") val _17: T17 = native +} + +object Tuple17 { + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17): Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17] = + Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17).asInstanceOf[Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]] + + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17](t: Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17)] = + Some(t) + + @inline implicit def fromScalaTuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17)): Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17] = + apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17) + + @inline implicit def toScalaTuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17](t: Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) = + (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17) +} + +/** + * A tuple "view" of 18 elements of a JavaScript [[Array]]. + * + * @see [[Tuple2]] + */ +@native +sealed trait Tuple18[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18] extends Object { + @JSName("0") val _1: T1 = native + @JSName("1") val _2: T2 = native + @JSName("2") val _3: T3 = native + @JSName("3") val _4: T4 = native + @JSName("4") val _5: T5 = native + @JSName("5") val _6: T6 = native + @JSName("6") val _7: T7 = native + @JSName("7") val _8: T8 = native + @JSName("8") val _9: T9 = native + @JSName("9") val _10: T10 = native + @JSName("10") val _11: T11 = native + @JSName("11") val _12: T12 = native + @JSName("12") val _13: T13 = native + @JSName("13") val _14: T14 = native + @JSName("14") val _15: T15 = native + @JSName("15") val _16: T16 = native + @JSName("16") val _17: T17 = native + @JSName("17") val _18: T18 = native +} + +object Tuple18 { + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18): Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18] = + Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18).asInstanceOf[Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]] + + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18](t: Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18)] = + Some(t) + + @inline implicit def fromScalaTuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18)): Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18] = + apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18) + + @inline implicit def toScalaTuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18](t: Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) = + (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18) +} + +/** + * A tuple "view" of 19 elements of a JavaScript [[Array]]. + * + * @see [[Tuple2]] + */ +@native +sealed trait Tuple19[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19] extends Object { + @JSName("0") val _1: T1 = native + @JSName("1") val _2: T2 = native + @JSName("2") val _3: T3 = native + @JSName("3") val _4: T4 = native + @JSName("4") val _5: T5 = native + @JSName("5") val _6: T6 = native + @JSName("6") val _7: T7 = native + @JSName("7") val _8: T8 = native + @JSName("8") val _9: T9 = native + @JSName("9") val _10: T10 = native + @JSName("10") val _11: T11 = native + @JSName("11") val _12: T12 = native + @JSName("12") val _13: T13 = native + @JSName("13") val _14: T14 = native + @JSName("14") val _15: T15 = native + @JSName("15") val _16: T16 = native + @JSName("16") val _17: T17 = native + @JSName("17") val _18: T18 = native + @JSName("18") val _19: T19 = native +} + +object Tuple19 { + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18, _19: T19): Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19] = + Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19).asInstanceOf[Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]] + + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19](t: Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19)] = + Some(t) + + @inline implicit def fromScalaTuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19)): Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19] = + apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18, t._19) + + @inline implicit def toScalaTuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19](t: Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) = + (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18, t._19) +} + +/** + * A tuple "view" of 20 elements of a JavaScript [[Array]]. + * + * @see [[Tuple2]] + */ +@native +sealed trait Tuple20[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20] extends Object { + @JSName("0") val _1: T1 = native + @JSName("1") val _2: T2 = native + @JSName("2") val _3: T3 = native + @JSName("3") val _4: T4 = native + @JSName("4") val _5: T5 = native + @JSName("5") val _6: T6 = native + @JSName("6") val _7: T7 = native + @JSName("7") val _8: T8 = native + @JSName("8") val _9: T9 = native + @JSName("9") val _10: T10 = native + @JSName("10") val _11: T11 = native + @JSName("11") val _12: T12 = native + @JSName("12") val _13: T13 = native + @JSName("13") val _14: T14 = native + @JSName("14") val _15: T15 = native + @JSName("15") val _16: T16 = native + @JSName("16") val _17: T17 = native + @JSName("17") val _18: T18 = native + @JSName("18") val _19: T19 = native + @JSName("19") val _20: T20 = native +} + +object Tuple20 { + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18, _19: T19, _20: T20): Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20] = + Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20).asInstanceOf[Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]] + + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20](t: Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20)] = + Some(t) + + @inline implicit def fromScalaTuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20)): Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20] = + apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18, t._19, t._20) + + @inline implicit def toScalaTuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20](t: Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) = + (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18, t._19, t._20) +} + +/** + * A tuple "view" of 21 elements of a JavaScript [[Array]]. + * + * @see [[Tuple2]] + */ +@native +sealed trait Tuple21[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20, +T21] extends Object { + @JSName("0") val _1: T1 = native + @JSName("1") val _2: T2 = native + @JSName("2") val _3: T3 = native + @JSName("3") val _4: T4 = native + @JSName("4") val _5: T5 = native + @JSName("5") val _6: T6 = native + @JSName("6") val _7: T7 = native + @JSName("7") val _8: T8 = native + @JSName("8") val _9: T9 = native + @JSName("9") val _10: T10 = native + @JSName("10") val _11: T11 = native + @JSName("11") val _12: T12 = native + @JSName("12") val _13: T13 = native + @JSName("13") val _14: T14 = native + @JSName("14") val _15: T15 = native + @JSName("15") val _16: T16 = native + @JSName("16") val _17: T17 = native + @JSName("17") val _18: T18 = native + @JSName("18") val _19: T19 = native + @JSName("19") val _20: T20 = native + @JSName("20") val _21: T21 = native +} + +object Tuple21 { + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18, _19: T19, _20: T20, _21: T21): Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21] = + Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21).asInstanceOf[Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]] + + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21](t: Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21)] = + Some(t) + + @inline implicit def fromScalaTuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21)): Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21] = + apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18, t._19, t._20, t._21) + + @inline implicit def toScalaTuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21](t: Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) = + (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18, t._19, t._20, t._21) +} + +/** + * A tuple "view" of 22 elements of a JavaScript [[Array]]. + * + * @see [[Tuple2]] + */ +@native +sealed trait Tuple22[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20, +T21, +T22] extends Object { + @JSName("0") val _1: T1 = native + @JSName("1") val _2: T2 = native + @JSName("2") val _3: T3 = native + @JSName("3") val _4: T4 = native + @JSName("4") val _5: T5 = native + @JSName("5") val _6: T6 = native + @JSName("6") val _7: T7 = native + @JSName("7") val _8: T8 = native + @JSName("8") val _9: T9 = native + @JSName("9") val _10: T10 = native + @JSName("10") val _11: T11 = native + @JSName("11") val _12: T12 = native + @JSName("12") val _13: T13 = native + @JSName("13") val _14: T14 = native + @JSName("14") val _15: T15 = native + @JSName("15") val _16: T16 = native + @JSName("16") val _17: T17 = native + @JSName("17") val _18: T18 = native + @JSName("18") val _19: T19 = native + @JSName("19") val _20: T20 = native + @JSName("20") val _21: T21 = native + @JSName("21") val _22: T22 = native +} + +object Tuple22 { + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18, _19: T19, _20: T20, _21: T21, _22: T22): Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22] = + Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22).asInstanceOf[Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]] + + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22](t: Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22)] = + Some(t) + + @inline implicit def fromScalaTuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22)): Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22] = + apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18, t._19, t._20, t._21, t._22) + + @inline implicit def toScalaTuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22](t: Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) = + (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18, t._19, t._20, t._21, t._22) +} + +// scalastyle:on line.size.limit diff --git a/library/src/main/scala/scala/scalajs/js/Tuple.scala b/library/src/main/scala/scala/scalajs/js/Tuple.scala index d7ab2cb19e..255c294eea 100644 --- a/library/src/main/scala/scala/scalajs/js/Tuple.scala +++ b/library/src/main/scala/scala/scalajs/js/Tuple.scala @@ -17,9 +17,6 @@ package scala.scalajs.js import scala.scalajs.js.annotation.JSName import scala.language.implicitConversions - -// scalastyle:off line.size.limit - /** * A tuple "view" of 2 elements of a JavaScript [[Array]]. * Combines @@ -88,690 +85,3 @@ object Tuple3 { @inline implicit def toScalaTuple3[T1, T2, T3](t: Tuple3[T1, T2, T3]): (T1, T2, T3) = (t._1, t._2, t._3) } - -/** - * A tuple "view" of 4 elements of a JavaScript [[Array]]. - * - * @see [[Tuple2]] - */ -@native -sealed trait Tuple4[+T1, +T2, +T3, +T4] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native -} - -object Tuple4 { - @inline def apply[T1, T2, T3, T4](_1: T1, _2: T2, _3: T3, _4: T4): Tuple4[T1, T2, T3, T4] = - Array(_1, _2, _3, _4).asInstanceOf[Tuple4[T1, T2, T3, T4]] - - @inline def unapply[T1, T2, T3, T4](t: Tuple4[T1, T2, T3, T4]): Option[(T1, T2, T3, T4)] = - Some(t) - - @inline implicit def fromScalaTuple4[T1, T2, T3, T4](t: (T1, T2, T3, T4)): Tuple4[T1, T2, T3, T4] = - apply(t._1, t._2, t._3, t._4) - - @inline implicit def toScalaTuple4[T1, T2, T3, T4](t: Tuple4[T1, T2, T3, T4]): (T1, T2, T3, T4) = - (t._1, t._2, t._3, t._4) -} - - -/** - * A tuple "view" of 5 elements of a JavaScript [[Array]]. - * - * @see [[Tuple2]] - */ -@native -sealed trait Tuple5[+T1, +T2, +T3, +T4, +T5] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native -} - -object Tuple5 { - @inline def apply[T1, T2, T3, T4, T5](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5): Tuple5[T1, T2, T3, T4, T5] = - Array(_1, _2, _3, _4, _5).asInstanceOf[Tuple5[T1, T2, T3, T4, T5]] - - @inline def unapply[T1, T2, T3, T4, T5](t: Tuple5[T1, T2, T3, T4, T5]): Option[(T1, T2, T3, T4, T5)] = - Some(t) - - @inline implicit def fromScalaTuple5[T1, T2, T3, T4, T5](t: (T1, T2, T3, T4, T5)): Tuple5[T1, T2, T3, T4, T5] = - apply(t._1, t._2, t._3, t._4, t._5) - - @inline implicit def toScalaTuple5[T1, T2, T3, T4, T5](t: Tuple5[T1, T2, T3, T4, T5]): (T1, T2, T3, T4, T5) = - (t._1, t._2, t._3, t._4, t._5) -} - -/** - * A tuple "view" of 6 elements of a JavaScript [[Array]]. - * - * @see [[Tuple2]] - */ -@native -sealed trait Tuple6[+T1, +T2, +T3, +T4, +T5, +T6] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native -} - -object Tuple6 { - @inline def apply[T1, T2, T3, T4, T5, T6](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6): Tuple6[T1, T2, T3, T4, T5, T6] = - Array(_1, _2, _3, _4, _5, _6).asInstanceOf[Tuple6[T1, T2, T3, T4, T5, T6]] - - @inline def unapply[T1, T2, T3, T4, T5, T6](t: Tuple6[T1, T2, T3, T4, T5, T6]): Option[(T1, T2, T3, T4, T5, T6)] = - Some(t) - - @inline implicit def fromScalaTuple6[T1, T2, T3, T4, T5, T6](t: (T1, T2, T3, T4, T5, T6)): Tuple6[T1, T2, T3, T4, T5, T6] = - apply(t._1, t._2, t._3, t._4, t._5, t._6) - - @inline implicit def toScalaTuple6[T1, T2, T3, T4, T5, T6](t: Tuple6[T1, T2, T3, T4, T5, T6]): (T1, T2, T3, T4, T5, T6) = - (t._1, t._2, t._3, t._4, t._5, t._6) -} - -/** - * A tuple "view" of 7 elements of a JavaScript [[Array]]. - * - * @see [[Tuple2]] - */ -@native -sealed trait Tuple7[+T1, +T2, +T3, +T4, +T5, +T6, +T7] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native -} - -object Tuple7 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7): Tuple7[T1, T2, T3, T4, T5, T6, T7] = - Array(_1, _2, _3, _4, _5, _6, _7).asInstanceOf[Tuple7[T1, T2, T3, T4, T5, T6, T7]] - - @inline def unapply[T1, T2, T3, T4, T5, T6, T7](t: Tuple7[T1, T2, T3, T4, T5, T6, T7]): Option[(T1, T2, T3, T4, T5, T6, T7)] = - Some(t) - - @inline implicit def fromScalaTuple7[T1, T2, T3, T4, T5, T6, T7](t: (T1, T2, T3, T4, T5, T6, T7)): Tuple7[T1, T2, T3, T4, T5, T6, T7] = - apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7) - - @inline implicit def toScalaTuple7[T1, T2, T3, T4, T5, T6, T7](t: Tuple7[T1, T2, T3, T4, T5, T6, T7]): (T1, T2, T3, T4, T5, T6, T7) = - (t._1, t._2, t._3, t._4, t._5, t._6, t._7) -} - -/** - * A tuple "view" of 8 elements of a JavaScript [[Array]]. - * - * @see [[Tuple2]] - */ -@native -sealed trait Tuple8[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native -} - -object Tuple8 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8): Tuple8[T1, T2, T3, T4, T5, T6, T7, T8] = - Array(_1, _2, _3, _4, _5, _6, _7, _8).asInstanceOf[Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]] - - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8](t: Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]): Option[(T1, T2, T3, T4, T5, T6, T7, T8)] = - Some(t) - - @inline implicit def fromScalaTuple8[T1, T2, T3, T4, T5, T6, T7, T8](t: (T1, T2, T3, T4, T5, T6, T7, T8)): Tuple8[T1, T2, T3, T4, T5, T6, T7, T8] = - apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8) - - @inline implicit def toScalaTuple8[T1, T2, T3, T4, T5, T6, T7, T8](t: Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]): (T1, T2, T3, T4, T5, T6, T7, T8) = - (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8) -} - -/** - * A tuple "view" of 9 elements of a JavaScript [[Array]]. - * - * @see [[Tuple2]] - */ -@native -sealed trait Tuple9[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native -} - -object Tuple9 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9): Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9).asInstanceOf[Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]] - - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9](t: Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9)] = - Some(t) - - @inline implicit def fromScalaTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9)): Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9] = - apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9) - - @inline implicit def toScalaTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9](t: Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]): (T1, T2, T3, T4, T5, T6, T7, T8, T9) = - (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9) -} - -/** - * A tuple "view" of 10 elements of a JavaScript [[Array]]. - * - * @see [[Tuple2]] - */ -@native -sealed trait Tuple10[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native -} - -object Tuple10 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10): Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10).asInstanceOf[Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]] - - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10](t: Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)] = - Some(t) - - @inline implicit def fromScalaTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)): Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10] = - apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10) - - @inline implicit def toScalaTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10](t: Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) = - (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10) -} - -/** - * A tuple "view" of 11 elements of a JavaScript [[Array]]. - * - * @see [[Tuple2]] - */ -@native -sealed trait Tuple11[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native - @JSName("10") val _11: T11 = native -} - -object Tuple11 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11): Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11).asInstanceOf[Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]] - - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11](t: Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)] = - Some(t) - - @inline implicit def fromScalaTuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)): Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11] = - apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11) - - @inline implicit def toScalaTuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11](t: Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) = - (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11) -} - -/** - * A tuple "view" of 12 elements of a JavaScript [[Array]]. - * - * @see [[Tuple2]] - */ -@native -sealed trait Tuple12[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native - @JSName("10") val _11: T11 = native - @JSName("11") val _12: T12 = native -} - -object Tuple12 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12): Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12).asInstanceOf[Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]] - - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12](t: Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)] = - Some(t) - - @inline implicit def fromScalaTuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)): Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12] = - apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12) - - @inline implicit def toScalaTuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12](t: Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) = - (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12) -} - -/** - * A tuple "view" of 13 elements of a JavaScript [[Array]]. - * - * @see [[Tuple2]] - */ -@native -sealed trait Tuple13[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native - @JSName("10") val _11: T11 = native - @JSName("11") val _12: T12 = native - @JSName("12") val _13: T13 = native -} - -object Tuple13 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13): Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13).asInstanceOf[Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]] - - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13](t: Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)] = - Some(t) - - @inline implicit def fromScalaTuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)): Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13] = - apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13) - - @inline implicit def toScalaTuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13](t: Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) = - (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13) -} - -/** - * A tuple "view" of 14 elements of a JavaScript [[Array]]. - * - * @see [[Tuple2]] - */ -@native -sealed trait Tuple14[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native - @JSName("10") val _11: T11 = native - @JSName("11") val _12: T12 = native - @JSName("12") val _13: T13 = native - @JSName("13") val _14: T14 = native -} - -object Tuple14 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14): Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14).asInstanceOf[Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]] - - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14](t: Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)] = - Some(t) - - @inline implicit def fromScalaTuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)): Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14] = - apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14) - - @inline implicit def toScalaTuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14](t: Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) = - (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14) -} - -/** - * A tuple "view" of 15 elements of a JavaScript [[Array]]. - * - * @see [[Tuple2]] - */ -@native -sealed trait Tuple15[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native - @JSName("10") val _11: T11 = native - @JSName("11") val _12: T12 = native - @JSName("12") val _13: T13 = native - @JSName("13") val _14: T14 = native - @JSName("14") val _15: T15 = native -} - -object Tuple15 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15): Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15).asInstanceOf[Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]] - - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15](t: Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)] = - Some(t) - - @inline implicit def fromScalaTuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)): Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15] = - apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15) - - @inline implicit def toScalaTuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15](t: Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) = - (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15) -} - -/** - * A tuple "view" of 16 elements of a JavaScript [[Array]]. - * - * @see [[Tuple16]] - */ -@native -sealed trait Tuple16[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native - @JSName("10") val _11: T11 = native - @JSName("11") val _12: T12 = native - @JSName("12") val _13: T13 = native - @JSName("13") val _14: T14 = native - @JSName("14") val _15: T15 = native - @JSName("15") val _16: T16 = native -} - -object Tuple16 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16): Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16).asInstanceOf[Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]] - - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16](t: Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16)] = - Some(t) - - @inline implicit def fromScalaTuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16)): Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16] = - apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16) - - @inline implicit def toScalaTuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16](t: Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) = - (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16) -} - -/** - * A tuple "view" of 17 elements of a JavaScript [[Array]]. - * - * @see [[Tuple2]] - */ -@native -sealed trait Tuple17[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native - @JSName("10") val _11: T11 = native - @JSName("11") val _12: T12 = native - @JSName("12") val _13: T13 = native - @JSName("13") val _14: T14 = native - @JSName("14") val _15: T15 = native - @JSName("15") val _16: T16 = native - @JSName("16") val _17: T17 = native -} - -object Tuple17 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17): Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17).asInstanceOf[Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]] - - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17](t: Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17)] = - Some(t) - - @inline implicit def fromScalaTuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17)): Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17] = - apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17) - - @inline implicit def toScalaTuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17](t: Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) = - (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17) -} - -/** - * A tuple "view" of 18 elements of a JavaScript [[Array]]. - * - * @see [[Tuple2]] - */ -@native -sealed trait Tuple18[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native - @JSName("10") val _11: T11 = native - @JSName("11") val _12: T12 = native - @JSName("12") val _13: T13 = native - @JSName("13") val _14: T14 = native - @JSName("14") val _15: T15 = native - @JSName("15") val _16: T16 = native - @JSName("16") val _17: T17 = native - @JSName("17") val _18: T18 = native -} - -object Tuple18 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18): Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18).asInstanceOf[Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]] - - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18](t: Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18)] = - Some(t) - - @inline implicit def fromScalaTuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18)): Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18] = - apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18) - - @inline implicit def toScalaTuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18](t: Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) = - (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18) -} - -/** - * A tuple "view" of 19 elements of a JavaScript [[Array]]. - * - * @see [[Tuple2]] - */ -@native -sealed trait Tuple19[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native - @JSName("10") val _11: T11 = native - @JSName("11") val _12: T12 = native - @JSName("12") val _13: T13 = native - @JSName("13") val _14: T14 = native - @JSName("14") val _15: T15 = native - @JSName("15") val _16: T16 = native - @JSName("16") val _17: T17 = native - @JSName("17") val _18: T18 = native - @JSName("18") val _19: T19 = native -} - -object Tuple19 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18, _19: T19): Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19).asInstanceOf[Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]] - - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19](t: Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19)] = - Some(t) - - @inline implicit def fromScalaTuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19)): Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19] = - apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18, t._19) - - @inline implicit def toScalaTuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19](t: Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) = - (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18, t._19) -} - -/** - * A tuple "view" of 20 elements of a JavaScript [[Array]]. - * - * @see [[Tuple2]] - */ -@native -sealed trait Tuple20[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native - @JSName("10") val _11: T11 = native - @JSName("11") val _12: T12 = native - @JSName("12") val _13: T13 = native - @JSName("13") val _14: T14 = native - @JSName("14") val _15: T15 = native - @JSName("15") val _16: T16 = native - @JSName("16") val _17: T17 = native - @JSName("17") val _18: T18 = native - @JSName("18") val _19: T19 = native - @JSName("19") val _20: T20 = native -} - -object Tuple20 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18, _19: T19, _20: T20): Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20).asInstanceOf[Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]] - - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20](t: Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20)] = - Some(t) - - @inline implicit def fromScalaTuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20)): Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20] = - apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18, t._19, t._20) - - @inline implicit def toScalaTuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20](t: Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) = - (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18, t._19, t._20) -} - -/** - * A tuple "view" of 21 elements of a JavaScript [[Array]]. - * - * @see [[Tuple2]] - */ -@native -sealed trait Tuple21[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20, +T21] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native - @JSName("10") val _11: T11 = native - @JSName("11") val _12: T12 = native - @JSName("12") val _13: T13 = native - @JSName("13") val _14: T14 = native - @JSName("14") val _15: T15 = native - @JSName("15") val _16: T16 = native - @JSName("16") val _17: T17 = native - @JSName("17") val _18: T18 = native - @JSName("18") val _19: T19 = native - @JSName("19") val _20: T20 = native - @JSName("20") val _21: T21 = native -} - -object Tuple21 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18, _19: T19, _20: T20, _21: T21): Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21).asInstanceOf[Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]] - - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21](t: Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21)] = - Some(t) - - @inline implicit def fromScalaTuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21)): Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21] = - apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18, t._19, t._20, t._21) - - @inline implicit def toScalaTuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21](t: Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) = - (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18, t._19, t._20, t._21) -} - -/** - * A tuple "view" of 22 elements of a JavaScript [[Array]]. - * - * @see [[Tuple2]] - */ -@native -sealed trait Tuple22[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20, +T21, +T22] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native - @JSName("10") val _11: T11 = native - @JSName("11") val _12: T12 = native - @JSName("12") val _13: T13 = native - @JSName("13") val _14: T14 = native - @JSName("14") val _15: T15 = native - @JSName("15") val _16: T16 = native - @JSName("16") val _17: T17 = native - @JSName("17") val _18: T18 = native - @JSName("18") val _19: T19 = native - @JSName("19") val _20: T20 = native - @JSName("20") val _21: T21 = native - @JSName("21") val _22: T22 = native -} - -object Tuple22 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18, _19: T19, _20: T20, _21: T21, _22: T22): Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22).asInstanceOf[Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]] - - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22](t: Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22)] = - Some(t) - - @inline implicit def fromScalaTuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22)): Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22] = - apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18, t._19, t._20, t._21, t._22) - - @inline implicit def toScalaTuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22](t: Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) = - (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18, t._19, t._20, t._21, t._22) -} - -// scalastyle:on line.size.limit diff --git a/project/Build.scala b/project/Build.scala index 877531070c..ffe083141a 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -996,7 +996,6 @@ object Build { ) ++ Seq( name := "Scala.js library", delambdafySetting, - scalacOptions in (Compile, doc) ++= Seq("-implicits", "-groups"), exportJars := !isGeneratingEclipse, previousArtifactSetting, mimaBinaryIssueFilters ++= BinaryIncompatibilities.Library, @@ -1005,6 +1004,32 @@ object Build { ) ++ ( scalaJSExternalCompileSettings ) ++ inConfig(Compile)(Seq( + scalacOptions in doc ++= Seq("-implicits", "-groups"), + + // Filter doc sources to remove implementation details from doc. + sources in doc := { + def containsFileFilter(s: String): FileFilter = new FileFilter { + override def accept(f: File): Boolean = { + val path = f.getAbsolutePath.replace('\\', '/') + path.contains(s) + } + } + + val filter: FileFilter = ( + AllPassFilter + -- containsFileFilter("/scala/scalajs/runtime/") + -- containsFileFilter("/scala/scalajs/js/annotation/internal/") + -- "*.nodoc.scala" + ) + + (sources in doc).value.filter(filter.accept) + }, + + /* Add compiled .class files to doc dependencyClasspath, so we can + * still compile even with only part of the files being present. + */ + dependencyClasspath in doc ++= exportedProducts.value, + /* Add the .sjsir files from other lib projects * (but not .class files) */ From ed3d3b6596e891433e6696f9a6270d609f5c087e Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Sat, 7 Jan 2017 23:08:31 +0100 Subject: [PATCH 0084/2665] Add ScalaRunTime overrides --- .../scala/runtime/ScalaRunTime.scala | 356 +++++++++++++++++ .../scala/runtime/ScalaRunTime.scala | 363 ++++++++++++++++++ .../scala/runtime/ScalaRunTime.scala | 268 +++++++++++++ 3 files changed, 987 insertions(+) create mode 100644 scalalib/overrides-2.10/scala/runtime/ScalaRunTime.scala create mode 100644 scalalib/overrides-2.11/scala/runtime/ScalaRunTime.scala create mode 100644 scalalib/overrides/scala/runtime/ScalaRunTime.scala diff --git a/scalalib/overrides-2.10/scala/runtime/ScalaRunTime.scala b/scalalib/overrides-2.10/scala/runtime/ScalaRunTime.scala new file mode 100644 index 0000000000..dcd323961e --- /dev/null +++ b/scalalib/overrides-2.10/scala/runtime/ScalaRunTime.scala @@ -0,0 +1,356 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala +package runtime + +import scala.collection.{ Seq, IndexedSeq, TraversableView, AbstractIterator } +import scala.collection.mutable.WrappedArray +import scala.collection.immutable.{ StringLike, NumericRange, List, Stream, Nil, :: } +import scala.collection.generic.{ Sorted } +import scala.reflect.{ ClassTag, classTag } +import scala.util.control.ControlThrowable +import scala.xml.{ Node, MetaData } +import java.lang.{ Class => jClass } + +import java.lang.Double.doubleToLongBits +import java.lang.reflect.{ Modifier, Method => JMethod } + +/** The object ScalaRunTime provides support methods required by + * the scala runtime. All these methods should be considered + * outside the API and subject to change or removal without notice. + */ +object ScalaRunTime { + def isArray(x: AnyRef): Boolean = isArray(x, 1) + def isArray(x: Any, atLevel: Int): Boolean = + x != null && isArrayClass(x.getClass, atLevel) + + private def isArrayClass(clazz: jClass[_], atLevel: Int): Boolean = + clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) + + def isValueClass(clazz: jClass[_]) = clazz.isPrimitive() + + // includes specialized subclasses and future proofed against hypothetical TupleN (for N > 22) + def isTuple(x: Any) = x != null && x.getClass.getName.startsWith("scala.Tuple") + def isAnyVal(x: Any) = x match { + case _: Byte | _: Short | _: Char | _: Int | _: Long | _: Float | _: Double | _: Boolean | _: Unit => true + case _ => false + } + + /** Return the class object representing an array with element class `clazz`. + */ + def arrayClass(clazz: jClass[_]): jClass[_] = { + // newInstance throws an exception if the erasure is Void.TYPE. see SI-5680 + if (clazz == java.lang.Void.TYPE) classOf[Array[Unit]] + else java.lang.reflect.Array.newInstance(clazz, 0).getClass + } + + /** Return the class object representing elements in arrays described by a given schematic. + */ + def arrayElementClass(schematic: Any): jClass[_] = schematic match { + case cls: jClass[_] => cls.getComponentType + case tag: ClassTag[_] => tag.runtimeClass + case _ => + throw new UnsupportedOperationException(s"unsupported schematic $schematic (${schematic.getClass})") + } + + /** Return the class object representing an unboxed value type, + * e.g. classOf[int], not classOf[java.lang.Integer]. The compiler + * rewrites expressions like 5.getClass to come here. + */ + def anyValClass[T <: AnyVal : ClassTag](value: T): jClass[T] = + classTag[T].runtimeClass.asInstanceOf[jClass[T]] + + /** Retrieve generic array element */ + def array_apply(xs: AnyRef, idx: Int): Any = { + xs match { + case x: Array[AnyRef] => x(idx).asInstanceOf[Any] + case x: Array[Int] => x(idx).asInstanceOf[Any] + case x: Array[Double] => x(idx).asInstanceOf[Any] + case x: Array[Long] => x(idx).asInstanceOf[Any] + case x: Array[Float] => x(idx).asInstanceOf[Any] + case x: Array[Char] => x(idx).asInstanceOf[Any] + case x: Array[Byte] => x(idx).asInstanceOf[Any] + case x: Array[Short] => x(idx).asInstanceOf[Any] + case x: Array[Boolean] => x(idx).asInstanceOf[Any] + case x: Array[Unit] => x(idx).asInstanceOf[Any] + case null => throw new NullPointerException + } + } + + /** update generic array element */ + def array_update(xs: AnyRef, idx: Int, value: Any): Unit = { + xs match { + case x: Array[AnyRef] => x(idx) = value.asInstanceOf[AnyRef] + case x: Array[Int] => x(idx) = value.asInstanceOf[Int] + case x: Array[Double] => x(idx) = value.asInstanceOf[Double] + case x: Array[Long] => x(idx) = value.asInstanceOf[Long] + case x: Array[Float] => x(idx) = value.asInstanceOf[Float] + case x: Array[Char] => x(idx) = value.asInstanceOf[Char] + case x: Array[Byte] => x(idx) = value.asInstanceOf[Byte] + case x: Array[Short] => x(idx) = value.asInstanceOf[Short] + case x: Array[Boolean] => x(idx) = value.asInstanceOf[Boolean] + case x: Array[Unit] => x(idx) = value.asInstanceOf[Unit] + case null => throw new NullPointerException + } + } + + /** Get generic array length */ + def array_length(xs: AnyRef): Int = xs match { + case x: Array[AnyRef] => x.length + case x: Array[Int] => x.length + case x: Array[Double] => x.length + case x: Array[Long] => x.length + case x: Array[Float] => x.length + case x: Array[Char] => x.length + case x: Array[Byte] => x.length + case x: Array[Short] => x.length + case x: Array[Boolean] => x.length + case x: Array[Unit] => x.length + case null => throw new NullPointerException + } + + def array_clone(xs: AnyRef): AnyRef = xs match { + case x: Array[AnyRef] => ArrayRuntime.cloneArray(x) + case x: Array[Int] => ArrayRuntime.cloneArray(x) + case x: Array[Double] => ArrayRuntime.cloneArray(x) + case x: Array[Long] => ArrayRuntime.cloneArray(x) + case x: Array[Float] => ArrayRuntime.cloneArray(x) + case x: Array[Char] => ArrayRuntime.cloneArray(x) + case x: Array[Byte] => ArrayRuntime.cloneArray(x) + case x: Array[Short] => ArrayRuntime.cloneArray(x) + case x: Array[Boolean] => ArrayRuntime.cloneArray(x) + case x: Array[Unit] => x + case null => throw new NullPointerException + } + + /** Convert an array to an object array. + * Needed to deal with vararg arguments of primitive types that are passed + * to a generic Java vararg parameter T ... + */ + def toObjectArray(src: AnyRef): Array[Object] = src match { + case x: Array[AnyRef] => x + case _ => + val length = array_length(src) + val dest = new Array[Object](length) + for (i <- 0 until length) + array_update(dest, i, array_apply(src, i)) + dest + } + + def toArray[T](xs: scala.collection.Seq[T]) = { + val arr = new Array[AnyRef](xs.length) + var i = 0 + for (x <- xs) { + arr(i) = x.asInstanceOf[AnyRef] + i += 1 + } + arr + } + + // Java bug: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4071957 + // More background at ticket #2318. + def ensureAccessible(m: JMethod): JMethod = { + if (!m.isAccessible) { + try m setAccessible true + catch { case _: SecurityException => () } + } + m + } + + def checkInitialized[T <: AnyRef](x: T): T = + if (x == null) throw new UninitializedError else x + + def _toString(x: Product): String = + x.productIterator.mkString(x.productPrefix + "(", ",", ")") + + def _hashCode(x: Product): Int = scala.util.hashing.MurmurHash3.productHash(x) + + /** A helper for case classes. */ + def typedProductIterator[T](x: Product): Iterator[T] = { + new AbstractIterator[T] { + private var c: Int = 0 + private val cmax = x.productArity + def hasNext = c < cmax + def next() = { + val result = x.productElement(c) + c += 1 + result.asInstanceOf[T] + } + } + } + + /** Fast path equality method for inlining; used when -optimise is set. + */ + @inline def inlinedEquals(x: Object, y: Object): Boolean = + if (x eq y) true + else if (x eq null) false + else if (x.isInstanceOf[java.lang.Number]) BoxesRunTime.equalsNumObject(x.asInstanceOf[java.lang.Number], y) + else if (x.isInstanceOf[java.lang.Character]) BoxesRunTime.equalsCharObject(x.asInstanceOf[java.lang.Character], y) + else x.equals(y) + + def _equals(x: Product, y: Any): Boolean = y match { + case y: Product if x.productArity == y.productArity => x.productIterator sameElements y.productIterator + case _ => false + } + + // hashcode ----------------------------------------------------------- + // + // Note that these are the implementations called by ##, so they + // must not call ## themselves. + + def hash(x: Any): Int = + if (x == null) 0 + else if (x.isInstanceOf[java.lang.Number]) BoxesRunTime.hashFromNumber(x.asInstanceOf[java.lang.Number]) + else x.hashCode + + def hash(dv: Double): Int = { + val iv = dv.toInt + if (iv == dv) return iv + + val lv = dv.toLong + if (lv == dv) return lv.hashCode + + val fv = dv.toFloat + if (fv == dv) fv.hashCode else dv.hashCode + } + def hash(fv: Float): Int = { + val iv = fv.toInt + if (iv == fv) return iv + + val lv = fv.toLong + if (lv == fv) return hash(lv) + else fv.hashCode + } + def hash(lv: Long): Int = { + val low = lv.toInt + val lowSign = low >>> 31 + val high = (lv >>> 32).toInt + low ^ (high + lowSign) + } + def hash(x: Number): Int = runtime.BoxesRunTime.hashFromNumber(x) + + // The remaining overloads are here for completeness, but the compiler + // inlines these definitions directly so they're not generally used. + def hash(x: Int): Int = x + def hash(x: Short): Int = x.toInt + def hash(x: Byte): Int = x.toInt + def hash(x: Char): Int = x.toInt + def hash(x: Boolean): Int = if (x) true.hashCode else false.hashCode + def hash(x: Unit): Int = 0 + + /** A helper method for constructing case class equality methods, + * because existential types get in the way of a clean outcome and + * it's performing a series of Any/Any equals comparisons anyway. + * See ticket #2867 for specifics. + */ + def sameElements(xs1: scala.collection.Seq[Any], xs2: scala.collection.Seq[Any]) = xs1 sameElements xs2 + + /** Given any Scala value, convert it to a String. + * + * The primary motivation for this method is to provide a means for + * correctly obtaining a String representation of a value, while + * avoiding the pitfalls of naïvely calling toString on said value. + * In particular, it addresses the fact that (a) toString cannot be + * called on null and (b) depending on the apparent type of an + * array, toString may or may not print it in a human-readable form. + * + * @param arg the value to stringify + * @return a string representation of arg. + */ + def stringOf(arg: Any): String = stringOf(arg, scala.Int.MaxValue) + def stringOf(arg: Any, maxElements: Int): String = { + def packageOf(x: AnyRef) = x.getClass.getPackage match { + case null => "" + case p => p.getName + } + def isScalaClass(x: AnyRef) = packageOf(x) startsWith "scala." + def isScalaCompilerClass(x: AnyRef) = packageOf(x) startsWith "scala.tools.nsc." + + // When doing our own iteration is dangerous + def useOwnToString(x: Any) = x match { + // Node extends NodeSeq extends Seq[Node] and MetaData extends Iterable[MetaData] + case _: Node | _: MetaData => true + // Range/NumericRange have a custom toString to avoid walking a gazillion elements + case _: Range | _: NumericRange[_] => true + // Sorted collections to the wrong thing (for us) on iteration - ticket #3493 + case _: Sorted[_, _] => true + // StringBuilder(a, b, c) and similar not so attractive + case _: StringLike[_] => true + // Don't want to evaluate any elements in a view + case _: TraversableView[_, _] => true + // Don't want to a) traverse infinity or b) be overly helpful with peoples' custom + // collections which may have useful toString methods - ticket #3710 + // or c) print AbstractFiles which are somehow also Iterable[AbstractFile]s. + case x: Traversable[_] => !x.hasDefiniteSize || !isScalaClass(x) || isScalaCompilerClass(x) + // Otherwise, nothing could possibly go wrong + case _ => false + } + + // A variation on inner for maps so they print -> instead of bare tuples + def mapInner(arg: Any): String = arg match { + case (k, v) => inner(k) + " -> " + inner(v) + case _ => inner(arg) + } + + // Special casing Unit arrays, the value class which uses a reference array type. + def arrayToString(x: AnyRef) = { + if (x.getClass.getComponentType == classOf[BoxedUnit]) + 0 until (array_length(x) min maxElements) map (_ => "()") mkString ("Array(", ", ", ")") + else + WrappedArray make x take maxElements map inner mkString ("Array(", ", ", ")") + } + + // The recursively applied attempt to prettify Array printing. + // Note that iterator is used if possible and foreach is used as a + // last resort, because the parallel collections "foreach" in a + // random order even on sequences. + def inner(arg: Any): String = arg match { + case null => "null" + case "" => "\"\"" + case x: String => if (x.head.isWhitespace || x.last.isWhitespace) "\"" + x + "\"" else x + case x if useOwnToString(x) => x.toString + case x: AnyRef if isArray(x) => arrayToString(x) + case x: scala.collection.Map[_, _] => x.iterator take maxElements map mapInner mkString (x.stringPrefix + "(", ", ", ")") + case x: Iterable[_] => x.iterator take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")") + case x: Traversable[_] => x take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")") + case x: Product1[_] if isTuple(x) => "(" + inner(x._1) + ",)" // that special trailing comma + case x: Product if isTuple(x) => x.productIterator map inner mkString ("(", ",", ")") + case x => x.toString + } + + // The try/catch is defense against iterables which aren't actually designed + // to be iterated, such as some scala.tools.nsc.io.AbstractFile derived classes. + try inner(arg) + catch { + case _: StackOverflowError | _: UnsupportedOperationException | _: AssertionError => "" + arg + } + } + + /** stringOf formatted for use in a repl result. */ + def replStringOf(arg: Any, maxElements: Int): String = { + val s = stringOf(arg, maxElements) + val nl = if (s contains "\n") "\n" else "" + + nl + s + "\n" + } + private[scala] def checkZip(what: String, coll1: TraversableOnce[_], coll2: TraversableOnce[_]) { + if (sys.props contains "scala.debug.zip") { + val xs = coll1.toIndexedSeq + val ys = coll2.toIndexedSeq + if (xs.length != ys.length) { + Console.err.println( + "Mismatched zip in " + what + ":\n" + + " this: " + xs.mkString(", ") + "\n" + + " that: " + ys.mkString(", ") + ) + (new Exception).getStackTrace.drop(2).take(10).foreach(println) + } + } + } +} diff --git a/scalalib/overrides-2.11/scala/runtime/ScalaRunTime.scala b/scalalib/overrides-2.11/scala/runtime/ScalaRunTime.scala new file mode 100644 index 0000000000..026d5edd29 --- /dev/null +++ b/scalalib/overrides-2.11/scala/runtime/ScalaRunTime.scala @@ -0,0 +1,363 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala +package runtime + +import scala.collection.{ Seq, IndexedSeq, TraversableView, AbstractIterator, GenIterable } +import scala.collection.mutable.WrappedArray +import scala.collection.immutable.{ StringLike, NumericRange, List, Stream, Nil, :: } +import scala.collection.generic.{ Sorted, IsTraversableLike } +import scala.reflect.{ ClassTag, classTag } +import scala.util.control.ControlThrowable +import java.lang.{ Class => jClass } + +import java.lang.Double.doubleToLongBits +import java.lang.reflect.{ Modifier, Method => JMethod } + +/** The object ScalaRunTime provides support methods required by + * the scala runtime. All these methods should be considered + * outside the API and subject to change or removal without notice. + */ +object ScalaRunTime { + def isArray(x: Any, atLevel: Int = 1): Boolean = + x != null && isArrayClass(x.getClass, atLevel) + + private def isArrayClass(clazz: jClass[_], atLevel: Int): Boolean = + clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) + + def isValueClass(clazz: jClass[_]) = clazz.isPrimitive() + + // includes specialized subclasses and future proofed against hypothetical TupleN (for N > 22) + def isTuple(x: Any) = x != null && x.getClass.getName.startsWith("scala.Tuple") + def isAnyVal(x: Any) = x match { + case _: Byte | _: Short | _: Char | _: Int | _: Long | _: Float | _: Double | _: Boolean | _: Unit => true + case _ => false + } + + // A helper method to make my life in the pattern matcher a lot easier. + def drop[Repr](coll: Repr, num: Int)(implicit traversable: IsTraversableLike[Repr]): Repr = + traversable conversion coll drop num + + /** Return the class object representing an array with element class `clazz`. + */ + def arrayClass(clazz: jClass[_]): jClass[_] = { + // newInstance throws an exception if the erasure is Void.TYPE. see SI-5680 + if (clazz == java.lang.Void.TYPE) classOf[Array[Unit]] + else java.lang.reflect.Array.newInstance(clazz, 0).getClass + } + + /** Return the class object representing elements in arrays described by a given schematic. + */ + def arrayElementClass(schematic: Any): jClass[_] = schematic match { + case cls: jClass[_] => cls.getComponentType + case tag: ClassTag[_] => tag.runtimeClass + case _ => + throw new UnsupportedOperationException(s"unsupported schematic $schematic (${schematic.getClass})") + } + + /** Return the class object representing an unboxed value type, + * e.g., classOf[int], not classOf[java.lang.Integer]. The compiler + * rewrites expressions like 5.getClass to come here. + */ + def anyValClass[T <: AnyVal : ClassTag](value: T): jClass[T] = + classTag[T].runtimeClass.asInstanceOf[jClass[T]] + + /** Retrieve generic array element */ + def array_apply(xs: AnyRef, idx: Int): Any = { + xs match { + case x: Array[AnyRef] => x(idx).asInstanceOf[Any] + case x: Array[Int] => x(idx).asInstanceOf[Any] + case x: Array[Double] => x(idx).asInstanceOf[Any] + case x: Array[Long] => x(idx).asInstanceOf[Any] + case x: Array[Float] => x(idx).asInstanceOf[Any] + case x: Array[Char] => x(idx).asInstanceOf[Any] + case x: Array[Byte] => x(idx).asInstanceOf[Any] + case x: Array[Short] => x(idx).asInstanceOf[Any] + case x: Array[Boolean] => x(idx).asInstanceOf[Any] + case x: Array[Unit] => x(idx).asInstanceOf[Any] + case null => throw new NullPointerException + } + } + + /** update generic array element */ + def array_update(xs: AnyRef, idx: Int, value: Any): Unit = { + xs match { + case x: Array[AnyRef] => x(idx) = value.asInstanceOf[AnyRef] + case x: Array[Int] => x(idx) = value.asInstanceOf[Int] + case x: Array[Double] => x(idx) = value.asInstanceOf[Double] + case x: Array[Long] => x(idx) = value.asInstanceOf[Long] + case x: Array[Float] => x(idx) = value.asInstanceOf[Float] + case x: Array[Char] => x(idx) = value.asInstanceOf[Char] + case x: Array[Byte] => x(idx) = value.asInstanceOf[Byte] + case x: Array[Short] => x(idx) = value.asInstanceOf[Short] + case x: Array[Boolean] => x(idx) = value.asInstanceOf[Boolean] + case x: Array[Unit] => x(idx) = value.asInstanceOf[Unit] + case null => throw new NullPointerException + } + } + + /** Get generic array length */ + def array_length(xs: AnyRef): Int = xs match { + case x: Array[AnyRef] => x.length + case x: Array[Int] => x.length + case x: Array[Double] => x.length + case x: Array[Long] => x.length + case x: Array[Float] => x.length + case x: Array[Char] => x.length + case x: Array[Byte] => x.length + case x: Array[Short] => x.length + case x: Array[Boolean] => x.length + case x: Array[Unit] => x.length + case null => throw new NullPointerException + } + + def array_clone(xs: AnyRef): AnyRef = xs match { + case x: Array[AnyRef] => ArrayRuntime.cloneArray(x) + case x: Array[Int] => ArrayRuntime.cloneArray(x) + case x: Array[Double] => ArrayRuntime.cloneArray(x) + case x: Array[Long] => ArrayRuntime.cloneArray(x) + case x: Array[Float] => ArrayRuntime.cloneArray(x) + case x: Array[Char] => ArrayRuntime.cloneArray(x) + case x: Array[Byte] => ArrayRuntime.cloneArray(x) + case x: Array[Short] => ArrayRuntime.cloneArray(x) + case x: Array[Boolean] => ArrayRuntime.cloneArray(x) + case x: Array[Unit] => x + case null => throw new NullPointerException + } + + /** Convert an array to an object array. + * Needed to deal with vararg arguments of primitive types that are passed + * to a generic Java vararg parameter T ... + */ + def toObjectArray(src: AnyRef): Array[Object] = src match { + case x: Array[AnyRef] => x + case _ => + val length = array_length(src) + val dest = new Array[Object](length) + for (i <- 0 until length) + array_update(dest, i, array_apply(src, i)) + dest + } + + def toArray[T](xs: scala.collection.Seq[T]) = { + val arr = new Array[AnyRef](xs.length) + var i = 0 + for (x <- xs) { + arr(i) = x.asInstanceOf[AnyRef] + i += 1 + } + arr + } + + // Java bug: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4071957 + // More background at ticket #2318. + def ensureAccessible(m: JMethod): JMethod = scala.reflect.ensureAccessible(m) + + def checkInitialized[T <: AnyRef](x: T): T = + if (x == null) throw new UninitializedError else x + + def _toString(x: Product): String = + x.productIterator.mkString(x.productPrefix + "(", ",", ")") + + def _hashCode(x: Product): Int = scala.util.hashing.MurmurHash3.productHash(x) + + /** A helper for case classes. */ + def typedProductIterator[T](x: Product): Iterator[T] = { + new AbstractIterator[T] { + private var c: Int = 0 + private val cmax = x.productArity + def hasNext = c < cmax + def next() = { + val result = x.productElement(c) + c += 1 + result.asInstanceOf[T] + } + } + } + + /** Fast path equality method for inlining; used when -optimise is set. + */ + @inline def inlinedEquals(x: Object, y: Object): Boolean = + if (x eq y) true + else if (x eq null) false + else if (x.isInstanceOf[java.lang.Number]) BoxesRunTime.equalsNumObject(x.asInstanceOf[java.lang.Number], y) + else if (x.isInstanceOf[java.lang.Character]) BoxesRunTime.equalsCharObject(x.asInstanceOf[java.lang.Character], y) + else x.equals(y) + + def _equals(x: Product, y: Any): Boolean = y match { + case y: Product if x.productArity == y.productArity => x.productIterator sameElements y.productIterator + case _ => false + } + + // hashcode ----------------------------------------------------------- + // + // Note that these are the implementations called by ##, so they + // must not call ## themselves. + + def hash(x: Any): Int = + if (x == null) 0 + else if (x.isInstanceOf[java.lang.Number]) BoxesRunTime.hashFromNumber(x.asInstanceOf[java.lang.Number]) + else x.hashCode + + def hash(dv: Double): Int = { + val iv = dv.toInt + if (iv == dv) return iv + + val lv = dv.toLong + if (lv == dv) return lv.hashCode + + val fv = dv.toFloat + if (fv == dv) fv.hashCode else dv.hashCode + } + def hash(fv: Float): Int = { + val iv = fv.toInt + if (iv == fv) return iv + + val lv = fv.toLong + if (lv == fv) hash(lv) + else fv.hashCode + } + def hash(lv: Long): Int = { + val low = lv.toInt + val lowSign = low >>> 31 + val high = (lv >>> 32).toInt + low ^ (high + lowSign) + } + def hash(x: Number): Int = runtime.BoxesRunTime.hashFromNumber(x) + + // The remaining overloads are here for completeness, but the compiler + // inlines these definitions directly so they're not generally used. + def hash(x: Int): Int = x + def hash(x: Short): Int = x.toInt + def hash(x: Byte): Int = x.toInt + def hash(x: Char): Int = x.toInt + def hash(x: Boolean): Int = if (x) true.hashCode else false.hashCode + def hash(x: Unit): Int = 0 + + /** A helper method for constructing case class equality methods, + * because existential types get in the way of a clean outcome and + * it's performing a series of Any/Any equals comparisons anyway. + * See ticket #2867 for specifics. + */ + def sameElements(xs1: scala.collection.Seq[Any], xs2: scala.collection.Seq[Any]) = xs1 sameElements xs2 + + /** Given any Scala value, convert it to a String. + * + * The primary motivation for this method is to provide a means for + * correctly obtaining a String representation of a value, while + * avoiding the pitfalls of naively calling toString on said value. + * In particular, it addresses the fact that (a) toString cannot be + * called on null and (b) depending on the apparent type of an + * array, toString may or may not print it in a human-readable form. + * + * @param arg the value to stringify + * @return a string representation of arg. + */ + def stringOf(arg: Any): String = stringOf(arg, scala.Int.MaxValue) + def stringOf(arg: Any, maxElements: Int): String = { + def packageOf(x: AnyRef) = x.getClass.getPackage match { + case null => "" + case p => p.getName + } + def isScalaClass(x: AnyRef) = packageOf(x) startsWith "scala." + def isScalaCompilerClass(x: AnyRef) = packageOf(x) startsWith "scala.tools.nsc." + + // We use reflection because the scala.xml package might not be available + def isSubClassOf(potentialSubClass: Class[_], ofClass: String) = + try { + val classLoader = potentialSubClass.getClassLoader + val clazz = Class.forName(ofClass, /*initialize =*/ false, classLoader) + clazz.isAssignableFrom(potentialSubClass) + } catch { + case cnfe: ClassNotFoundException => false + } + def isXmlNode(potentialSubClass: Class[_]) = isSubClassOf(potentialSubClass, "scala.xml.Node") + def isXmlMetaData(potentialSubClass: Class[_]) = isSubClassOf(potentialSubClass, "scala.xml.MetaData") + + // When doing our own iteration is dangerous + def useOwnToString(x: Any) = x match { + // Range/NumericRange have a custom toString to avoid walking a gazillion elements + case _: Range | _: NumericRange[_] => true + // Sorted collections to the wrong thing (for us) on iteration - ticket #3493 + case _: Sorted[_, _] => true + // StringBuilder(a, b, c) and similar not so attractive + case _: StringLike[_] => true + // Don't want to evaluate any elements in a view + case _: TraversableView[_, _] => true + // Node extends NodeSeq extends Seq[Node] and MetaData extends Iterable[MetaData] + // -> catch those by isXmlNode and isXmlMetaData. + // Don't want to a) traverse infinity or b) be overly helpful with peoples' custom + // collections which may have useful toString methods - ticket #3710 + // or c) print AbstractFiles which are somehow also Iterable[AbstractFile]s. + case x: Traversable[_] => !x.hasDefiniteSize || !isScalaClass(x) || isScalaCompilerClass(x) || isXmlNode(x.getClass) || isXmlMetaData(x.getClass) + // Otherwise, nothing could possibly go wrong + case _ => false + } + + // A variation on inner for maps so they print -> instead of bare tuples + def mapInner(arg: Any): String = arg match { + case (k, v) => inner(k) + " -> " + inner(v) + case _ => inner(arg) + } + + // Special casing Unit arrays, the value class which uses a reference array type. + def arrayToString(x: AnyRef) = { + if (x.getClass.getComponentType == classOf[BoxedUnit]) + 0 until (array_length(x) min maxElements) map (_ => "()") mkString ("Array(", ", ", ")") + else + WrappedArray make x take maxElements map inner mkString ("Array(", ", ", ")") + } + + // The recursively applied attempt to prettify Array printing. + // Note that iterator is used if possible and foreach is used as a + // last resort, because the parallel collections "foreach" in a + // random order even on sequences. + def inner(arg: Any): String = arg match { + case null => "null" + case "" => "\"\"" + case x: String => if (x.head.isWhitespace || x.last.isWhitespace) "\"" + x + "\"" else x + case x if useOwnToString(x) => x.toString + case x: AnyRef if isArray(x) => arrayToString(x) + case x: scala.collection.Map[_, _] => x.iterator take maxElements map mapInner mkString (x.stringPrefix + "(", ", ", ")") + case x: GenIterable[_] => x.iterator take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")") + case x: Traversable[_] => x take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")") + case x: Product1[_] if isTuple(x) => "(" + inner(x._1) + ",)" // that special trailing comma + case x: Product if isTuple(x) => x.productIterator map inner mkString ("(", ",", ")") + case x => x.toString + } + + // The try/catch is defense against iterables which aren't actually designed + // to be iterated, such as some scala.tools.nsc.io.AbstractFile derived classes. + try inner(arg) + catch { + case _: UnsupportedOperationException | _: AssertionError => "" + arg + } + } + + /** stringOf formatted for use in a repl result. */ + def replStringOf(arg: Any, maxElements: Int): String = { + val s = stringOf(arg, maxElements) + val nl = if (s contains "\n") "\n" else "" + + nl + s + "\n" + } + + def box[T](clazz: jClass[T]): jClass[_] = clazz match { + case java.lang.Byte.TYPE => classOf[java.lang.Byte] + case java.lang.Short.TYPE => classOf[java.lang.Short] + case java.lang.Character.TYPE => classOf[java.lang.Character] + case java.lang.Integer.TYPE => classOf[java.lang.Integer] + case java.lang.Long.TYPE => classOf[java.lang.Long] + case java.lang.Float.TYPE => classOf[java.lang.Float] + case java.lang.Double.TYPE => classOf[java.lang.Double] + case java.lang.Void.TYPE => classOf[scala.runtime.BoxedUnit] + case java.lang.Boolean.TYPE => classOf[java.lang.Boolean] + case _ => clazz + } +} diff --git a/scalalib/overrides/scala/runtime/ScalaRunTime.scala b/scalalib/overrides/scala/runtime/ScalaRunTime.scala new file mode 100644 index 0000000000..b31a94576a --- /dev/null +++ b/scalalib/overrides/scala/runtime/ScalaRunTime.scala @@ -0,0 +1,268 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala +package runtime + +import scala.collection.{ TraversableView, AbstractIterator, GenIterable } +import scala.collection.mutable.WrappedArray +import scala.collection.immutable.{ StringLike, NumericRange } +import scala.collection.generic.{ Sorted, IsTraversableLike } +import scala.reflect.{ ClassTag, classTag } +import java.lang.{ Class => jClass } + +import java.lang.reflect.{ Method => JMethod } + +/** The object ScalaRunTime provides support methods required by + * the scala runtime. All these methods should be considered + * outside the API and subject to change or removal without notice. + */ +object ScalaRunTime { + def isArray(x: Any, atLevel: Int = 1): Boolean = + x != null && isArrayClass(x.getClass, atLevel) + + private def isArrayClass(clazz: jClass[_], atLevel: Int): Boolean = + clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) + + // A helper method to make my life in the pattern matcher a lot easier. + def drop[Repr](coll: Repr, num: Int)(implicit traversable: IsTraversableLike[Repr]): Repr = + traversable conversion coll drop num + + /** Return the class object representing an array with element class `clazz`. + */ + def arrayClass(clazz: jClass[_]): jClass[_] = { + // newInstance throws an exception if the erasure is Void.TYPE. see SI-5680 + if (clazz == java.lang.Void.TYPE) classOf[Array[Unit]] + else java.lang.reflect.Array.newInstance(clazz, 0).getClass + } + + /** Return the class object representing an unboxed value type, + * e.g., classOf[int], not classOf[java.lang.Integer]. The compiler + * rewrites expressions like 5.getClass to come here. + */ + def anyValClass[T <: AnyVal : ClassTag](value: T): jClass[T] = + classTag[T].runtimeClass.asInstanceOf[jClass[T]] + + /** Retrieve generic array element */ + def array_apply(xs: AnyRef, idx: Int): Any = { + xs match { + case x: Array[AnyRef] => x(idx).asInstanceOf[Any] + case x: Array[Int] => x(idx).asInstanceOf[Any] + case x: Array[Double] => x(idx).asInstanceOf[Any] + case x: Array[Long] => x(idx).asInstanceOf[Any] + case x: Array[Float] => x(idx).asInstanceOf[Any] + case x: Array[Char] => x(idx).asInstanceOf[Any] + case x: Array[Byte] => x(idx).asInstanceOf[Any] + case x: Array[Short] => x(idx).asInstanceOf[Any] + case x: Array[Boolean] => x(idx).asInstanceOf[Any] + case x: Array[Unit] => x(idx).asInstanceOf[Any] + case null => throw new NullPointerException + } + } + + /** update generic array element */ + def array_update(xs: AnyRef, idx: Int, value: Any): Unit = { + xs match { + case x: Array[AnyRef] => x(idx) = value.asInstanceOf[AnyRef] + case x: Array[Int] => x(idx) = value.asInstanceOf[Int] + case x: Array[Double] => x(idx) = value.asInstanceOf[Double] + case x: Array[Long] => x(idx) = value.asInstanceOf[Long] + case x: Array[Float] => x(idx) = value.asInstanceOf[Float] + case x: Array[Char] => x(idx) = value.asInstanceOf[Char] + case x: Array[Byte] => x(idx) = value.asInstanceOf[Byte] + case x: Array[Short] => x(idx) = value.asInstanceOf[Short] + case x: Array[Boolean] => x(idx) = value.asInstanceOf[Boolean] + case x: Array[Unit] => x(idx) = value.asInstanceOf[Unit] + case null => throw new NullPointerException + } + } + + /** Get generic array length */ + def array_length(xs: AnyRef): Int = xs match { + case x: Array[AnyRef] => x.length + case x: Array[Int] => x.length + case x: Array[Double] => x.length + case x: Array[Long] => x.length + case x: Array[Float] => x.length + case x: Array[Char] => x.length + case x: Array[Byte] => x.length + case x: Array[Short] => x.length + case x: Array[Boolean] => x.length + case x: Array[Unit] => x.length + case null => throw new NullPointerException + } + + def array_clone(xs: AnyRef): AnyRef = xs match { + case x: Array[AnyRef] => x.clone() + case x: Array[Int] => x.clone() + case x: Array[Double] => x.clone() + case x: Array[Long] => x.clone() + case x: Array[Float] => x.clone() + case x: Array[Char] => x.clone() + case x: Array[Byte] => x.clone() + case x: Array[Short] => x.clone() + case x: Array[Boolean] => x.clone() + case x: Array[Unit] => x + case null => throw new NullPointerException + } + + /** Convert an array to an object array. + * Needed to deal with vararg arguments of primitive types that are passed + * to a generic Java vararg parameter T ... + */ + def toObjectArray(src: AnyRef): Array[Object] = src match { + case x: Array[AnyRef] => x + case _ => + val length = array_length(src) + val dest = new Array[Object](length) + for (i <- 0 until length) + array_update(dest, i, array_apply(src, i)) + dest + } + + def toArray[T](xs: scala.collection.Seq[T]) = { + val arr = new Array[AnyRef](xs.length) + var i = 0 + for (x <- xs) { + arr(i) = x.asInstanceOf[AnyRef] + i += 1 + } + arr + } + + // Java bug: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4071957 + // More background at ticket #2318. + def ensureAccessible(m: JMethod): JMethod = scala.reflect.ensureAccessible(m) + + def _toString(x: Product): String = + x.productIterator.mkString(x.productPrefix + "(", ",", ")") + + def _hashCode(x: Product): Int = scala.util.hashing.MurmurHash3.productHash(x) + + /** A helper for case classes. */ + def typedProductIterator[T](x: Product): Iterator[T] = { + new AbstractIterator[T] { + private var c: Int = 0 + private val cmax = x.productArity + def hasNext = c < cmax + def next() = { + val result = x.productElement(c) + c += 1 + result.asInstanceOf[T] + } + } + } + + /** Old implementation of `##`. */ + @deprecated("Use scala.runtime.Statics.anyHash instead.", "2.12.0") + def hash(x: Any): Int = Statics.anyHash(x.asInstanceOf[Object]) + + /** Given any Scala value, convert it to a String. + * + * The primary motivation for this method is to provide a means for + * correctly obtaining a String representation of a value, while + * avoiding the pitfalls of naively calling toString on said value. + * In particular, it addresses the fact that (a) toString cannot be + * called on null and (b) depending on the apparent type of an + * array, toString may or may not print it in a human-readable form. + * + * @param arg the value to stringify + * @return a string representation of arg. + */ + def stringOf(arg: Any): String = stringOf(arg, scala.Int.MaxValue) + def stringOf(arg: Any, maxElements: Int): String = { + def packageOf(x: AnyRef) = x.getClass.getPackage match { + case null => "" + case p => p.getName + } + def isScalaClass(x: AnyRef) = packageOf(x) startsWith "scala." + def isScalaCompilerClass(x: AnyRef) = packageOf(x) startsWith "scala.tools.nsc." + + // includes specialized subclasses and future proofed against hypothetical TupleN (for N > 22) + def isTuple(x: Any) = x != null && x.getClass.getName.startsWith("scala.Tuple") + + // We use reflection because the scala.xml package might not be available + def isSubClassOf(potentialSubClass: Class[_], ofClass: String) = + try { + val classLoader = potentialSubClass.getClassLoader + val clazz = Class.forName(ofClass, /*initialize =*/ false, classLoader) + clazz.isAssignableFrom(potentialSubClass) + } catch { + case cnfe: ClassNotFoundException => false + } + def isXmlNode(potentialSubClass: Class[_]) = isSubClassOf(potentialSubClass, "scala.xml.Node") + def isXmlMetaData(potentialSubClass: Class[_]) = isSubClassOf(potentialSubClass, "scala.xml.MetaData") + + // When doing our own iteration is dangerous + def useOwnToString(x: Any) = x match { + // Range/NumericRange have a custom toString to avoid walking a gazillion elements + case _: Range | _: NumericRange[_] => true + // Sorted collections to the wrong thing (for us) on iteration - ticket #3493 + case _: Sorted[_, _] => true + // StringBuilder(a, b, c) and similar not so attractive + case _: StringLike[_] => true + // Don't want to evaluate any elements in a view + case _: TraversableView[_, _] => true + // Node extends NodeSeq extends Seq[Node] and MetaData extends Iterable[MetaData] + // -> catch those by isXmlNode and isXmlMetaData. + // Don't want to a) traverse infinity or b) be overly helpful with peoples' custom + // collections which may have useful toString methods - ticket #3710 + // or c) print AbstractFiles which are somehow also Iterable[AbstractFile]s. + case x: Traversable[_] => !x.hasDefiniteSize || !isScalaClass(x) || isScalaCompilerClass(x) || isXmlNode(x.getClass) || isXmlMetaData(x.getClass) + // Otherwise, nothing could possibly go wrong + case _ => false + } + + // A variation on inner for maps so they print -> instead of bare tuples + def mapInner(arg: Any): String = arg match { + case (k, v) => inner(k) + " -> " + inner(v) + case _ => inner(arg) + } + + // Special casing Unit arrays, the value class which uses a reference array type. + def arrayToString(x: AnyRef) = { + if (x.getClass.getComponentType == classOf[BoxedUnit]) + 0 until (array_length(x) min maxElements) map (_ => "()") mkString ("Array(", ", ", ")") + else + WrappedArray make x take maxElements map inner mkString ("Array(", ", ", ")") + } + + // The recursively applied attempt to prettify Array printing. + // Note that iterator is used if possible and foreach is used as a + // last resort, because the parallel collections "foreach" in a + // random order even on sequences. + def inner(arg: Any): String = arg match { + case null => "null" + case "" => "\"\"" + case x: String => if (x.head.isWhitespace || x.last.isWhitespace) "\"" + x + "\"" else x + case x if useOwnToString(x) => x.toString + case x: AnyRef if isArray(x) => arrayToString(x) + case x: scala.collection.Map[_, _] => x.iterator take maxElements map mapInner mkString (x.stringPrefix + "(", ", ", ")") + case x: GenIterable[_] => x.iterator take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")") + case x: Traversable[_] => x take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")") + case x: Product1[_] if isTuple(x) => "(" + inner(x._1) + ",)" // that special trailing comma + case x: Product if isTuple(x) => x.productIterator map inner mkString ("(", ",", ")") + case x => x.toString + } + + // The try/catch is defense against iterables which aren't actually designed + // to be iterated, such as some scala.tools.nsc.io.AbstractFile derived classes. + try inner(arg) + catch { + case _: UnsupportedOperationException | _: AssertionError => "" + arg + } + } + + /** stringOf formatted for use in a repl result. */ + def replStringOf(arg: Any, maxElements: Int): String = { + val s = stringOf(arg, maxElements) + val nl = if (s contains "\n") "\n" else "" + + nl + s + "\n" + } +} From 7ab8bf089fc5c92aea4b081ed40eb2b8ef807d93 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Sun, 8 Jan 2017 11:42:36 +0100 Subject: [PATCH 0085/2665] Fix #2712: Fix null safety issue in ScalaRunTime.isArray implementation --- .../scala/runtime/ScalaRunTime.scala | 2 +- .../scala/runtime/ScalaRunTime.scala | 2 +- .../scala/runtime/ScalaRunTime.scala | 2 +- .../scalalib/ScalaRunTimeJSTest.scala | 24 +++++++++++++++++++ .../testsuite/scalalib/ScalaRunTimeTest.scala | 23 ++++++++++++++++++ 5 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 test-suite/js/src/test/scala/org/scalajs/testsuite/scalalib/ScalaRunTimeJSTest.scala create mode 100644 test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ScalaRunTimeTest.scala diff --git a/scalalib/overrides-2.10/scala/runtime/ScalaRunTime.scala b/scalalib/overrides-2.10/scala/runtime/ScalaRunTime.scala index dcd323961e..c1562ceeaf 100644 --- a/scalalib/overrides-2.10/scala/runtime/ScalaRunTime.scala +++ b/scalalib/overrides-2.10/scala/runtime/ScalaRunTime.scala @@ -31,7 +31,7 @@ object ScalaRunTime { x != null && isArrayClass(x.getClass, atLevel) private def isArrayClass(clazz: jClass[_], atLevel: Int): Boolean = - clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) + clazz != null && clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) def isValueClass(clazz: jClass[_]) = clazz.isPrimitive() diff --git a/scalalib/overrides-2.11/scala/runtime/ScalaRunTime.scala b/scalalib/overrides-2.11/scala/runtime/ScalaRunTime.scala index 026d5edd29..b7ac02d5b5 100644 --- a/scalalib/overrides-2.11/scala/runtime/ScalaRunTime.scala +++ b/scalalib/overrides-2.11/scala/runtime/ScalaRunTime.scala @@ -29,7 +29,7 @@ object ScalaRunTime { x != null && isArrayClass(x.getClass, atLevel) private def isArrayClass(clazz: jClass[_], atLevel: Int): Boolean = - clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) + clazz != null && clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) def isValueClass(clazz: jClass[_]) = clazz.isPrimitive() diff --git a/scalalib/overrides/scala/runtime/ScalaRunTime.scala b/scalalib/overrides/scala/runtime/ScalaRunTime.scala index b31a94576a..a536bd5fd6 100644 --- a/scalalib/overrides/scala/runtime/ScalaRunTime.scala +++ b/scalalib/overrides/scala/runtime/ScalaRunTime.scala @@ -27,7 +27,7 @@ object ScalaRunTime { x != null && isArrayClass(x.getClass, atLevel) private def isArrayClass(clazz: jClass[_], atLevel: Int): Boolean = - clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) + clazz != null && clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) // A helper method to make my life in the pattern matcher a lot easier. def drop[Repr](coll: Repr, num: Int)(implicit traversable: IsTraversableLike[Repr]): Repr = diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/scalalib/ScalaRunTimeJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/scalalib/ScalaRunTimeJSTest.scala new file mode 100644 index 0000000000..c14089d84a --- /dev/null +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/scalalib/ScalaRunTimeJSTest.scala @@ -0,0 +1,24 @@ +package org.scalajs.testsuite.scalalib + +import org.junit.Test +import org.junit.Assert.assertFalse + +import scala.scalajs.js + +class ScalaRunTimeJSTest { + + @Test def ScalaRunTime_isArray_should_not_fail_with_JS_objects(): Unit = { + def isScalaArray(x: Any): Boolean = { + x match { + case _: Array[_] => true + case _ => false + } + } + + assertFalse(isScalaArray(js.Array(1, 2, 3))) + assertFalse(isScalaArray(new js.RegExp("abc"))) + assertFalse(isScalaArray(js.Dynamic.literal())) + assertFalse(isScalaArray(((x: Int) => x + 1): js.Function1[Int, Int])) + } + +} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ScalaRunTimeTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ScalaRunTimeTest.scala new file mode 100644 index 0000000000..67362d672e --- /dev/null +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ScalaRunTimeTest.scala @@ -0,0 +1,23 @@ +package org.scalajs.testsuite.scalalib + +import org.junit.Test +import org.junit.Assert.{assertFalse, assertTrue} + +import scala.concurrent.Future + +class ScalaRunTimeTest { + + @Test def ScalaRunTime_isArray(): Unit = { + def isScalaArray(x: Any): Boolean = { + x match { + case _: Array[_] => true + case _ => false + } + } + + assertTrue(isScalaArray(Array(1, 2, 3))) + assertFalse(isScalaArray(42)) + assertFalse(isScalaArray(Future.successful(42))) + } + +} From 8ea5a656fd92e61d502671a6acec2ae61ba3e75a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 9 Jan 2017 16:31:52 +0100 Subject: [PATCH 0086/2665] Fix #2715: Emit object literals for new anonymous JS class. When instantiating an anonymous JS class, we actually instantiate the parent class. If that parent class happens to be `js.Object`, and there is no formal argument to the constructor, we can use an empty object literal `{}` instead. This makes the compiler behavior consistent with a direct `new js.Object()`, for which we already applied this optimization. This allows Closure to fuse it with subsequent field assignments, eventually producing a direct object literal with fields. --- .../org/scalajs/core/compiler/GenJSCode.scala | 14 +++-- .../core/compiler/test/OptimizationTest.scala | 51 +++++++++++++++++++ 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index bcae89fddb..bfbafd8665 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -646,10 +646,16 @@ abstract class GenJSCode extends plugins.PluginComponent case js.JSSuperConstructorCall(args) => implicit val pos = tree.pos - val ident = - origJsClass.superClass.getOrElse(sys.error("No superclass")) - val superTpe = jstpe.ClassType(ident.name) - val newTree = js.JSNew(js.LoadJSConstructor(superTpe), args) + val newTree = { + val ident = + origJsClass.superClass.getOrElse(sys.error("No superclass")) + if (args.isEmpty && ident.name == "sjs_js_Object") { + js.JSObjectConstr(Nil) + } else { + val superTpe = jstpe.ClassType(ident.name) + js.JSNew(js.LoadJSConstructor(superTpe), args) + } + } js.Block( js.VarDef(selfName, jstpe.AnyType, mutable = false, newTree) :: diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala index f93c890846..d5ee4b9e48 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala @@ -172,4 +172,55 @@ class OptimizationTest extends JSASTTest { } } + @Test + def newSJSDefinedTraitProducesObjectConstr: Unit = { + """ + import scala.scalajs.js + import scala.scalajs.js.annotation._ + + @ScalaJSDefined + trait Point extends js.Object { + val x: Double + val y: Double + } + + class Test { + def newSJSDefinedTraitProducesObjectConstr(): Any = { + new Point { + val x = 5.0 + val y = 6.5 + } + } + } + """.hasNot("`new Object`") { + case js.JSNew(_, _) => + }.has("object literal") { + case js.JSObjectConstr(Nil) => + } + + """ + import scala.scalajs.js + import scala.scalajs.js.annotation._ + + @ScalaJSDefined + trait Point extends js.Object { + var x: js.UndefOr[Double] = js.undefined + var y: js.UndefOr[Double] = js.undefined + } + + class Test { + def newSJSDefinedTraitProducesObjectConstr(): Any = { + new Point { + x = 5.0 + y = 6.5 + } + } + } + """.hasNot("`new Object`") { + case js.JSNew(_, _) => + }.has("object literal") { + case js.JSObjectConstr(Nil) => + } + } + } From d537c803b63df20362736529386bcbb29a7642ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 30 Dec 2016 23:24:12 +0100 Subject: [PATCH 0087/2665] Allow to export module methods as static in their companion class. This implements the first part of the proposal #2702, i.e., exporting methods as static. This commit introduces a new annotation `@JSExportStatic`. It can be used on (non-accessor) methods in Scala objects whose companion class is a Scala.js-defined JS class. The annotation causes the method to exported as a static method of the companion class. The mechanism is conceptually (and technically) quite close to `@JSExportTopLevel`, where the export is nested in a static class namespace instead of being at the top-level. --- .../org/scalajs/core/compiler/GenJSCode.scala | 37 ++- .../scalajs/core/compiler/GenJSExports.scala | 26 +- .../scalajs/core/compiler/JSDefinitions.scala | 1 + .../core/compiler/JSGlobalAddons.scala | 17 +- .../scalajs/core/compiler/PrepJSExports.scala | 221 ++++++++++----- .../core/compiler/test/JSExportTest.scala | 268 ++++++++++++++++++ .../js/annotation/JSExportStatic.scala | 28 ++ .../jsinterop/JSExportStaticTest.scala | 201 +++++++++++++ .../core/tools/linker/analyzer/Analyzer.scala | 4 + .../backend/emitter/ScalaJSClassEmitter.scala | 43 ++- .../core/tools/linker/checker/IRChecker.scala | 10 +- .../tools/linker/frontend/BaseLinker.scala | 18 +- 12 files changed, 765 insertions(+), 109 deletions(-) create mode 100644 library/src/main/scala/scala/scalajs/js/annotation/JSExportStatic.scala create mode 100644 test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index bcae89fddb..d680a5ccf4 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -183,6 +183,14 @@ abstract class GenJSCode extends plugins.PluginComponent // Global class generation state ------------------------------------------- + /** Map a class from this compilation unit to its companion module class. + * This should be accessible through `sym.linkedClassOfClass`, but is + * broken for nested classes. The reverse link is not broken, though, + * which allows us to build this map in [[apply]] for the whole + * compilation unit before processing it. + */ + private var companionModuleClasses: Map[Symbol, Symbol] = Map.empty + private val lazilyGeneratedAnonClasses = mutable.Map.empty[Symbol, ClassDef] private val generatedClasses = ListBuffer.empty[(Symbol, Option[String], js.ClassDef)] @@ -249,6 +257,15 @@ abstract class GenJSCode extends plugins.PluginComponent } val allClassDefs = collectClassDefs(cunit.body) + // Build up companionModuleClasses + companionModuleClasses = (for { + classDef <- allClassDefs + sym = classDef.symbol + if sym.isModuleClass + } yield { + patchedLinkedClassOfClass(sym) -> sym + }).toMap + /* There are three types of anonymous classes we want to generate * only once we need them so we can inline them at construction site: * @@ -316,6 +333,7 @@ abstract class GenJSCode extends plugins.PluginComponent } finally { lazilyGeneratedAnonClasses.clear() generatedClasses.clear() + companionModuleClasses = Map.empty pos2irPosCache.clear() } } @@ -483,8 +501,22 @@ abstract class GenJSCode extends plugins.PluginComponent gen(cd.impl) + // Static members (exported from the companion object) + val staticMembers = { + /* This should be `sym.linkedClassOfClass`, but it does not work for + * classes and objects nested inside objects. + */ + companionModuleClasses.get(sym).fold[List[js.Tree]] { + Nil + } { companionModuleClass => + withScopedVars(currentClassSym := companionModuleClass) { + genStaticExports(companionModuleClass) + } + } + } + // Generate class-level exporters - val exports = + val classExports = if (isStaticModule(sym)) genModuleAccessorExports(sym) else genJSClassExports(sym) @@ -494,7 +526,8 @@ abstract class GenJSCode extends plugins.PluginComponent genJSClassConstructor(sym, constructorTrees.toList) :: genJSClassDispatchers(sym, dispatchMethodNames.result().distinct) ::: generatedMethods.toList ::: - exports + staticMembers ::: + classExports } // Hashed definitions of the class diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index 64e5ae22d2..01ec5363ed 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -121,26 +121,36 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } def genTopLevelExports(classSym: Symbol): List[js.TopLevelExportDef] = { - val allTopLevelExports = for { + for (m <- genTopLevelOrStaticExports(classSym, ExportDestination.TopLevel)) + yield js.TopLevelExportDef(m)(m.pos) + } + + def genStaticExports(classSym: Symbol): List[js.MethodDef] = + genTopLevelOrStaticExports(classSym, ExportDestination.Static) + + private def genTopLevelOrStaticExports(classSym: Symbol, + destination: ExportDestination): List[js.MethodDef] = { + require( + destination == ExportDestination.TopLevel || + destination == ExportDestination.Static) + + val allRelevantExports = for { methodSym <- classSym.info.members if methodSym.isMethod && !methodSym.isConstructor export <- jsInterop.registeredExportsOf(methodSym) + if export.destination == destination } yield { - assert(export.isTopLevel) (export, methodSym) } - val result = for { - (jsName, tups) <- allTopLevelExports.groupBy(_._1.jsName) + for { + (jsName, tups) <- allRelevantExports.groupBy(_._1.jsName).toList } yield { implicit val pos = tups.head._1.pos val alts = tups.map(t => ExportedSymbol(t._2)).toList - - js.TopLevelExportDef(genExportMethod(alts, jsName, static = true)) + genExportMethod(alts, jsName, static = true) } - - result.toList } /** Tests whether the given def a named exporter def that needs to be diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index e9282868c8..1d8c0e87a6 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -64,6 +64,7 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val JSExportDescendentClassesAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportDescendentClasses") lazy val JSExportAllAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportAll") lazy val JSExportNamedAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportNamed") + lazy val JSExportStaticAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportStatic") lazy val JSExportTopLevelAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportTopLevel") lazy val JSImportAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSImport") lazy val JSGlobalScopeAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSGlobalScope") diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala index 3057cf5c19..1b9413f863 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala @@ -30,6 +30,21 @@ trait JSGlobalAddons extends JSDefinitions JSGlobalAddons.this.asInstanceOf[ThisJSGlobalAddons] } + sealed abstract class ExportDestination + + object ExportDestination { + /** Export in the "normal" way: as an instance member, or at the top-level + * for naturally top-level things (classes and modules). + */ + case object Normal extends ExportDestination + + /** Export at the top-level. */ + case object TopLevel extends ExportDestination + + /** Export as a static member of the companion class. */ + case object Static extends ExportDestination + } + /** global javascript interop related helpers */ object jsInterop { // scalastyle:ignore import scala.reflect.NameTransformer @@ -51,7 +66,7 @@ trait JSGlobalAddons extends JSDefinitions val jsName: String val pos: Position val isNamed: Boolean - val isTopLevel: Boolean + val destination: ExportDestination } def clearGlobalState(): Unit = { diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala index 86b385d5bc..8e71744c61 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala @@ -25,10 +25,10 @@ trait PrepJSExports { this: PrepJSInterop => jsName: String, pos: Position, isNamed: Boolean, - isTopLevel: Boolean, + destination: ExportDestination, ignoreInvalid: Boolean ) extends jsInterop.ExportInfo { - assert(!isNamed || !isTopLevel) + assert(!isNamed || destination == ExportDestination.Normal) } /** Generate the exporter for the given DefDef @@ -90,15 +90,16 @@ trait PrepJSExports { this: PrepJSInterop => // Reset interface flag: Any trait will contain non-empty methods clsSym.resetFlag(Flags.INTERFACE) - val (topLevelExports, otherExports) = exports.partition(_.isTopLevel) + val (normalExports, topLevelAndStaticExports) = + exports.partition(_.destination == ExportDestination.Normal) - /* We can handle top level exports entirely in the backend. So just - * register them here. + /* We can handle top level exports and static exports entirely in the + * backend. So just register them here. */ - jsInterop.registerForExport(baseSym, topLevelExports) + jsInterop.registerForExport(baseSym, topLevelAndStaticExports) // Actually generate exporter methods - otherExports.flatMap { exp => + normalExports.flatMap { exp => if (exp.isNamed) genNamedExport(baseSym, exp.jsName, exp.pos) :: Nil else @@ -178,14 +179,15 @@ trait PrepJSExports { this: PrepJSInterop => val exports = directExportsOf(sym) ++ inheritedExportsOf(sym) /* Calculate the distinct exports for this symbol (eliminate double - * occurrences of (name, isNamed, isTopLevel) tuples). + * occurrences of (name, isNamed, isTopLevel, isStatic) tuples). */ val grouped = exports.groupBy( - exp => (exp.jsName, exp.isNamed, exp.isTopLevel)) + exp => (exp.jsName, exp.isNamed, exp.destination)) - for ((_, exps) <- grouped.toList) + for ((_, exps) <- grouped.toList) yield { // Make sure that we are strict if necessary - yield exps.find(!_.ignoreInvalid).getOrElse(exps.head) + exps.find(!_.ignoreInvalid).getOrElse(exps.head) + } } private def directExportsOf(sym: Symbol): List[ExportInfo] = { @@ -224,8 +226,12 @@ trait PrepJSExports { this: PrepJSInterop => val isNamedExport = annot.symbol == JSExportNamedAnnotation val isExportAll = annot.symbol == JSExportAllAnnotation val isTopLevelExport = annot.symbol == JSExportTopLevelAnnotation + val isStaticExport = annot.symbol == JSExportStaticAnnotation val hasExplicitName = annot.args.nonEmpty + assert(!isTopLevelExport || hasExplicitName, + "Found a top-level export without an explicit name at " + annot.pos) + def explicitName = annot.stringArg(0).getOrElse { reporter.error(annot.pos, s"The argument to ${annot.symbol.name} must be a literal string") @@ -239,6 +245,12 @@ trait PrepJSExports { this: PrepJSInterop => else sym.unexpandedName.decoded.stripSuffix("_=") } + val destination = { + if (isTopLevelExport) ExportDestination.TopLevel + else if (isStaticExport) ExportDestination.Static + else ExportDestination.Normal + } + // Enforce proper setter signature if (jsInterop.isJSSetter(sym)) checkSetterSignature(sym, annot.pos, exported = true) @@ -252,74 +264,128 @@ trait PrepJSExports { this: PrepJSInterop => "An exported name may not contain a double underscore (`__`)") } - // Make sure we do not override the default export of toString - def isIllegalToString = { - isMember && !isNamedExport && !isTopLevelExport && - name == "toString" && sym.name != nme.toString_ && - sym.tpe.params.isEmpty && !jsInterop.isJSGetter(sym) - } - - if (isIllegalToString) { - reporter.error(annot.pos, "You may not export a zero-argument " + - "method named other than 'toString' under the name 'toString'") - } - - def isIllegalApplyExport = { - isMember && !hasExplicitName && !isTopLevelExport && - sym.name == nme.apply && - !(isExportAll && directAnnots.exists(annot => - annot.symbol == JSExportAnnotation && - annot.args.nonEmpty && - annot.stringArg(0) == Some("apply"))) - } - - // Don't allow apply without explicit name - if (isIllegalApplyExport) { - // Get position for error message - val pos = if (isExportAll) trgSym.pos else annot.pos - - reporter.warning(pos, "Member cannot be exported to function " + - "application. It is available under the name apply instead. " + - "Add @JSExport(\"apply\") to silence this warning. " + - "This will be enforced in 1.0.") - } - - // Don't allow nested class / module exports without explicit name. - def isStaticNested = { - /* For Scala.js defined JS classes, sym is the class itself. For normal - * classes, sym is the constructor that is to be exported. - */ - val clsSym = if (sym.isClass) sym else sym.owner - clsSym.isNestedClass && clsSym.isStatic && !clsSym.isLocalToBlock - } - - if (!isMember && !hasExplicitName && isStaticNested) { - reporter.error(annot.pos, - "You must set an explicit name for exports of nested classes.") - } - - if (isNamedExport && jsInterop.isJSProperty(sym)) { - reporter.error(annot.pos, - "You may not export a getter or a setter as a named export") - } - - if (isTopLevelExport) { - if (jsInterop.isJSProperty(sym)) { - reporter.error(annot.pos, - "You may not export a getter or a setter to the top level") + /* Illegal function application exports, i.e., method named 'apply' + * without an explicit export name. + */ + if (isMember && !hasExplicitName && sym.name == nme.apply) { + destination match { + case ExportDestination.Normal => + def shouldBeTolerated = { + isExportAll && directAnnots.exists { annot => + annot.symbol == JSExportAnnotation && + annot.args.nonEmpty && + annot.stringArg(0) == Some("apply") + } + } + + // Don't allow apply without explicit name + if (!shouldBeTolerated) { + // Get position for error message + val pos = if (isExportAll) trgSym.pos else annot.pos + + reporter.warning(pos, "Member cannot be exported to function " + + "application. It is available under the name apply " + + "instead. Add @JSExport(\"apply\") to silence this " + + "warning. This will be enforced in 1.0.") + } + + case ExportDestination.TopLevel => + throw new AssertionError( + "Found a top-level export without an explicit name at " + + annot.pos) + + case ExportDestination.Static => + reporter.error(annot.pos, + "A member cannot be exported to function application as " + + "static. Use @JSExportStatic(\"apply\") to export it under " + + "the name 'apply'.") } + } - if (!isMember) { - reporter.error(annot.pos, "Use @JSExport on objects and " + - "constructors to export to the top level") - } else if (!sym.owner.isStatic || !sym.owner.isModuleClass) { - reporter.error(annot.pos, - "Only static objects may export their members to the top level") - } + // Destination-specific restrictions + destination match { + case ExportDestination.Normal => + // Make sure we do not override the default export of toString + def isIllegalToString = { + isMember && !isNamedExport && + name == "toString" && sym.name != nme.toString_ && + sym.tpe.params.isEmpty && !jsInterop.isJSGetter(sym) + } + if (isIllegalToString) { + reporter.error(annot.pos, "You may not export a zero-argument " + + "method named other than 'toString' under the name 'toString'") + } + + if (isNamedExport && jsInterop.isJSProperty(sym)) { + reporter.error(annot.pos, + "You may not export a getter or a setter as a named export") + } + + // Don't allow nested class / module exports without explicit name. + def isStaticNested = { + /* For Scala.js defined JS classes, sym is the class itself. For + * normal classes, sym is the constructor that is to be exported. + */ + val clsSym = if (sym.isClass) sym else sym.owner + clsSym.isNestedClass && clsSym.isStatic && !clsSym.isLocalToBlock + } + if (!isMember && !hasExplicitName && isStaticNested) { + reporter.error(annot.pos, + "You must set an explicit name for exports of nested classes.") + } + + case ExportDestination.TopLevel => + if (jsInterop.isJSProperty(sym)) { + reporter.error(annot.pos, + "You may not export a getter or a setter to the top level") + } + + if (!isMember) { + reporter.error(annot.pos, "Use @JSExport on objects and " + + "constructors to export to the top level") + } else if (!sym.owner.isStatic || !sym.owner.isModuleClass) { + reporter.error(annot.pos, + "Only static objects may export their members to the top level") + } + + case ExportDestination.Static => + val symOwner = + if (sym.isClassConstructor) sym.owner.owner + else sym.owner + + def companionIsScalaJSDefinedJSClass: Boolean = { + val companion = symOwner.companionClass + companion != NoSymbol && + !companion.isTrait && + isJSAny(companion) && + companion.hasAnnotation(ScalaJSDefinedAnnotation) + } + + if (!symOwner.isStatic || !symOwner.isModuleClass || + !companionIsScalaJSDefinedJSClass) { + reporter.error(annot.pos, + "Only a static object whose companion class is a " + + "Scala.js-defined JS class may export its members as static.") + } + + if (!isMember) { + if (sym.isTrait) { + reporter.error(annot.pos, + "You may not export a trait as static.") + } else { + reporter.error(annot.pos, + "Implementation restriction: cannot export a class or " + + "object as static") + } + } else if (jsInterop.isJSProperty(sym)) { + reporter.error(annot.pos, + "Implementation restriction: cannot export a getter or a " + + "setter as static") + } } - ExportInfo(name, annot.pos, isNamedExport, - isTopLevelExport, ignoreInvalid = false) + ExportInfo(name, annot.pos, isNamedExport, destination, + ignoreInvalid = false) } } @@ -374,7 +440,7 @@ trait PrepJSExports { this: PrepJSInterop => s"a @${trgAnnot.name} on $forcingSym") } - ExportInfo(name, sym.pos, isNamed = false, isTopLevel = false, + ExportInfo(name, sym.pos, isNamed = false, ExportDestination.Normal, ignoreInvalid) } @@ -557,7 +623,8 @@ trait PrepJSExports { this: PrepJSInterop => private lazy val isDirectMemberAnnot = Set[Symbol]( JSExportAnnotation, JSExportNamedAnnotation, - JSExportTopLevelAnnotation + JSExportTopLevelAnnotation, + JSExportStaticAnnotation ) } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index 553f1eef81..6b2b35073d 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -1251,4 +1251,272 @@ class JSExportTest extends DirectTest with TestHelpers { | ^ """ } + + @Test + def noExportStaticModule: Unit = { + """ + @ScalaJSDefined + class StaticContainer extends js.Object + + object StaticContainer { + @JSExportStatic + object A + } + """ hasErrors + """ + |newSource1.scala:7: error: Implementation restriction: cannot export a class or object as static + | @JSExportStatic + | ^ + """ + } + + @Test + def noExportStaticTrait: Unit = { + """ + @ScalaJSDefined + class StaticContainer extends js.Object + + object StaticContainer { + @JSExportStatic + trait A + } + """ hasErrors + """ + |newSource1.scala:7: error: You may not export a trait as static. + | @JSExportStatic + | ^ + """ + } + + @Test + def noExportStaticClass: Unit = { + """ + @ScalaJSDefined + class StaticContainer extends js.Object + + object StaticContainer { + @JSExportStatic + class A + } + """ hasErrors + """ + |newSource1.scala:7: error: Implementation restriction: cannot export a class or object as static + | @JSExportStatic + | ^ + """ + + """ + @ScalaJSDefined + class StaticContainer extends js.Object + + object StaticContainer { + class A { + @JSExportStatic + def this(x: Int) = this() + } + } + """ hasErrors + """ + |newSource1.scala:8: error: Implementation restriction: cannot export a class or object as static + | @JSExportStatic + | ^ + """ + } + + @Test + def noExportStaticVal: Unit = { + """ + @ScalaJSDefined + class StaticContainer extends js.Object + + object StaticContainer { + @JSExportStatic + val a: Int = 1 + } + """ hasErrors + """ + |newSource1.scala:7: error: Implementation restriction: cannot export a getter or a setter as static + | @JSExportStatic + | ^ + """ + } + + @Test + def noExportStaticVar: Unit = { + """ + @ScalaJSDefined + class StaticContainer extends js.Object + + object StaticContainer { + @JSExportStatic + var a: Int = 1 + } + """ hasErrors + """ + |newSource1.scala:7: error: Implementation restriction: cannot export a getter or a setter as static + | @JSExportStatic + | ^ + """ + } + + @Test + def noExportStaticGetter: Unit = { + """ + @ScalaJSDefined + class StaticContainer extends js.Object + + object StaticContainer { + @JSExportStatic + def a: Int = 1 + } + """ hasErrors + """ + |newSource1.scala:7: error: Implementation restriction: cannot export a getter or a setter as static + | @JSExportStatic + | ^ + """ + } + + @Test + def noExportStaticSetter: Unit = { + """ + @ScalaJSDefined + class StaticContainer extends js.Object + + object StaticContainer { + @JSExportStatic + def a_=(x: Int): Unit = () + } + """ hasErrors + """ + |newSource1.scala:7: error: Implementation restriction: cannot export a getter or a setter as static + | @JSExportStatic + | ^ + """ + } + + @Test + def noExportStaticCollapsingMethods: Unit = { + """ + @ScalaJSDefined + class StaticContainer extends js.Object + + object StaticContainer { + @JSExportStatic + def foo(x: Int): Int = x + + @JSExportStatic("foo") + def bar(x: Int): Int = x + 1 + } + """ hasErrors + """ + |newSource1.scala:11: error: Cannot disambiguate overloads for exported method bar with types + | (x: Int)Int + | (x: Int)Int + | def bar(x: Int): Int = x + 1 + | ^ + """ + } + + @Test + def noExportStaticNonStatic: Unit = { + """ + class A { + @ScalaJSDefined + class StaticContainer extends js.Object + + object StaticContainer { + @JSExportStatic + def a(): Unit = () + } + } + """ hasErrors + """ + |newSource1.scala:8: error: Only a static object whose companion class is a Scala.js-defined JS class may export its members as static. + | @JSExportStatic + | ^ + """ + } + + @Test + def noExportStaticInJSModule: Unit = { + """ + @ScalaJSDefined + class StaticContainer extends js.Object + + @ScalaJSDefined + object StaticContainer extends js.Object { + @JSExportStatic + def a(): Unit = () + } + """ hasErrors + """ + |newSource1.scala:8: error: You may not export a method of a subclass of js.Any + | @JSExportStatic + | ^ + """ + + """ + @ScalaJSDefined + class StaticContainer extends js.Object + + @js.native + object StaticContainer extends js.Object { + @JSExportStatic + def a(): Unit = js.native + } + """ hasErrors + """ + |newSource1.scala:8: error: You may not export a method of a subclass of js.Any + | @JSExportStatic + | ^ + """ + } + + @Test + def noExportStaticIfWrongCompanionType: Unit = { + """ + class StaticContainer + + object StaticContainer { + @JSExportStatic + def a(): Unit = () + } + """ hasErrors + """ + |newSource1.scala:6: error: Only a static object whose companion class is a Scala.js-defined JS class may export its members as static. + | @JSExportStatic + | ^ + """ + + """ + @ScalaJSDefined + trait StaticContainer extends js.Object + + object StaticContainer { + @JSExportStatic + def a(): Unit = () + } + """ hasErrors + """ + |newSource1.scala:7: error: Only a static object whose companion class is a Scala.js-defined JS class may export its members as static. + | @JSExportStatic + | ^ + """ + + """ + @js.native + class StaticContainer extends js.Object + + object StaticContainer { + @JSExportStatic + def a(): Unit = () + } + """ hasErrors + """ + |newSource1.scala:7: error: Only a static object whose companion class is a Scala.js-defined JS class may export its members as static. + | @JSExportStatic + | ^ + """ + } } diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSExportStatic.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSExportStatic.scala new file mode 100644 index 0000000000..8af0820b4a --- /dev/null +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSExportStatic.scala @@ -0,0 +1,28 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js API ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package scala.scalajs.js.annotation + +import scala.annotation.meta._ + +// scalastyle:off line.size.limit + +/** Specifies that the annotated member should be exported as a JavaScript + * static member of the companion class. + * + * This annotation may only be used on members of a Scala `object` whose + * companion class is a Scala.js-defined JavaScript class. The annotated + * member will be available as a static member of the companion class. + * + * @see [[https://www.scala-js.org/doc/export-to-javascript.html Export Scala.js APIs to JavaScript]] + * + * @see [[https://www.scala-js.org/doc/interoperability/sjs-defined-js-classes.html Write JavaScript classes in Scala.js]] + */ +class JSExportStatic extends scala.annotation.StaticAnnotation { + def this(name: String) = this() +} diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala new file mode 100644 index 0000000000..5cd7f5eff4 --- /dev/null +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala @@ -0,0 +1,201 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.jsinterop + +import scala.scalajs.js +import js.annotation._ + +import org.scalajs.testsuite.utils.AssertThrows._ +import org.scalajs.testsuite.utils.Platform._ + +import org.junit.Assert._ +import org.junit.Assume._ +import org.junit.Test + +class JSExportStaticTest { + @Test def toplevel_basic_static_method_export(): Unit = { + val statics = js.constructorOf[TopLevelStaticExportMethods] + + assertEquals(1, statics.basic()) + } + + @Test def toplevel_overloaded_static_method_export(): Unit = { + val statics = js.constructorOf[TopLevelStaticExportMethods] + + assertEquals("Hello World", statics.overload("World")) + assertEquals(2, statics.overload(2)) + assertEquals(9, statics.overload(2, 7)) + assertEquals(10, statics.overload(1, 2, 3, 4)) + } + + @Test def toplevel_renamed_static_method_export(): Unit = { + val statics = js.constructorOf[TopLevelStaticExportMethods] + + assertEquals(11, statics.renamed(8)) + } + + @Test def toplevel_renamed_overloaded_static_method_export(): Unit = { + val statics = js.constructorOf[TopLevelStaticExportMethods] + + assertEquals("Hello World", statics.renamedOverload("World")) + assertEquals(2, statics.renamedOverload(2)) + assertEquals(9, statics.renamedOverload(2, 7)) + assertEquals(10, statics.renamedOverload(1, 2, 3, 4)) + } + + @Test def toplevel_static_method_export_constructor(): Unit = { + val statics = js.constructorOf[TopLevelStaticExportMethods] + + assertEquals(24, statics.constructor(12)) + } + + @Test def toplevel_static_method_export_uses_unique_object(): Unit = { + val statics = js.constructorOf[TopLevelStaticExportMethods] + + statics.setMyVar(3) + assertEquals(3, TopLevelStaticExportMethods.myVar) + statics.setMyVar(7) + assertEquals(7, TopLevelStaticExportMethods.myVar) + } + + @Test def toplevel_static_method_export_also_exists_in_member(): Unit = { + val statics = js.constructorOf[TopLevelStaticExportMethods] + assertEquals(15, statics.alsoExistsAsMember(3)) + + val obj = new TopLevelStaticExportMethods + assertEquals(6, obj.alsoExistsAsMember(3)) + } + + @Test def nested_basic_static_method_export(): Unit = { + val statics = js.constructorOf[JSExportStaticTest.StaticExportMethods] + + assertEquals(1, statics.basic()) + } + + @Test def nested_overloaded_static_method_export(): Unit = { + val statics = js.constructorOf[JSExportStaticTest.StaticExportMethods] + + assertEquals("Hello World", statics.overload("World")) + assertEquals(2, statics.overload(2)) + assertEquals(9, statics.overload(2, 7)) + assertEquals(10, statics.overload(1, 2, 3, 4)) + } + + @Test def nested_renamed_static_method_export(): Unit = { + val statics = js.constructorOf[JSExportStaticTest.StaticExportMethods] + + assertEquals(11, statics.renamed(8)) + } + + @Test def nested_renamed_overloaded_static_method_export(): Unit = { + val statics = js.constructorOf[JSExportStaticTest.StaticExportMethods] + + assertEquals("Hello World", statics.renamedOverload("World")) + assertEquals(2, statics.renamedOverload(2)) + assertEquals(9, statics.renamedOverload(2, 7)) + assertEquals(10, statics.renamedOverload(1, 2, 3, 4)) + } + + @Test def nested_static_method_export_constructor(): Unit = { + val statics = js.constructorOf[JSExportStaticTest.StaticExportMethods] + + assertEquals(24, statics.constructor(12)) + } + + @Test def nested_static_method_export_uses_unique_object(): Unit = { + val statics = js.constructorOf[JSExportStaticTest.StaticExportMethods] + + statics.setMyVar(3) + assertEquals(3, JSExportStaticTest.StaticExportMethods.myVar) + statics.setMyVar(7) + assertEquals(7, JSExportStaticTest.StaticExportMethods.myVar) + } + + @Test def nested_static_method_export_also_exists_in_member(): Unit = { + val statics = js.constructorOf[JSExportStaticTest.StaticExportMethods] + assertEquals(15, statics.alsoExistsAsMember(3)) + + val obj = new JSExportStaticTest.StaticExportMethods + assertEquals(6, obj.alsoExistsAsMember(3)) + } + +} + +@ScalaJSDefined +class TopLevelStaticExportMethods extends js.Object { + def alsoExistsAsMember(x: Int): Int = x * 2 +} + +object TopLevelStaticExportMethods { + @JSExportStatic + def basic(): Int = 1 + + @JSExportStatic + def overload(x: String): String = "Hello " + x + + @JSExportStatic + def overload(x: Int, y: Int*): Int = x + y.sum + + @JSExportStatic("renamed") + def renamedMethod(x: Int): Int = x + 3 + + @JSExportStatic + def renamedOverload(x: String): String = "Hello " + x + + @JSExportStatic("renamedOverload") + def renamedOverloadedMethod(x: Int, y: Int*): Int = x + y.sum + + @JSExportStatic + def constructor(x: Int): Int = 2 * x + + var myVar: Int = _ + + @JSExportStatic + def setMyVar(x: Int): Unit = myVar = x + + @JSExportStatic + def alsoExistsAsMember(x: Int): Int = x * 5 +} + +object JSExportStaticTest { + @ScalaJSDefined + class StaticExportMethods extends js.Object { + def alsoExistsAsMember(x: Int): Int = x * 2 + } + + object StaticExportMethods { + @JSExportStatic + def basic(): Int = 1 + + @JSExportStatic + def overload(x: String): String = "Hello " + x + + @JSExportStatic + def overload(x: Int, y: Int*): Int = x + y.sum + + @JSExportStatic("renamed") + def renamedMethod(x: Int): Int = x + 3 + + @JSExportStatic + def renamedOverload(x: String): String = "Hello " + x + + @JSExportStatic("renamedOverload") + def renamedOverloadedMethod(x: Int, y: Int*): Int = x + y.sum + + @JSExportStatic + def constructor(x: Int): Int = 2 * x + + var myVar: Int = _ + + @JSExportStatic + def setMyVar(x: Int): Unit = myVar = x + + @JSExportStatic + def alsoExistsAsMember(x: Int): Int = x * 5 + } +} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala index 16777f8d2c..d2e3ce7562 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala @@ -619,6 +619,10 @@ private final class Analyzer(semantics: Semantics, if (isJSClass) superClass.instantiated() + for (methodInfo <- staticMethodInfos.values) { + if (methodInfo.isExported) + methodInfo.reachStatic()(FromExports) + } for (methodInfo <- methodInfos.values) { if (methodInfo.isExported) methodInfo.reach(this)(FromExports) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala index 6442809000..37829a2522 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala @@ -290,10 +290,22 @@ private[emitter] final class ScalaJSClassEmitter( } if (method.static) { - val Ident(methodName, origName) = method.name - envFieldDef( - "s", className + "__" + methodName, origName, - methodFun) + method.name match { + case Ident(methodName, origName) => + envFieldDef( + "s", className + "__" + methodName, origName, + methodFun) + + case methodName: StringLiteral => + outputMode match { + case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => + genAddToObject(encodeClassVar(className), methodName, methodFun) + + case OutputMode.ECMAScript6 => + js.MethodDef(static = true, genPropertyName(methodName), + methodFun.args, methodFun.body) + } + } } else { outputMode match { case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => @@ -414,12 +426,7 @@ private[emitter] final class ScalaJSClassEmitter( /** Generate `classVar.prototype.name = value` */ def genAddToPrototype(className: String, name: js.PropertyName, value: js.Tree)(implicit pos: Position): js.Tree = { - val proto = encodeClassVar(className).prototype - val select = name match { - case name: js.Ident => js.DotSelect(proto, name) - case name: js.StringLiteral => genBracketSelect(proto, name) - } - js.Assign(select, value) + genAddToObject(encodeClassVar(className).prototype, name, value) } /** Generate `classVar.prototype.name = value` */ @@ -428,6 +435,22 @@ private[emitter] final class ScalaJSClassEmitter( genAddToPrototype(className, genPropertyName(name), value) } + /** Generate `obj.name = value` */ + def genAddToObject(obj: js.Tree, name: js.PropertyName, + value: js.Tree)(implicit pos: Position): js.Tree = { + val select = name match { + case name: js.Ident => js.DotSelect(obj, name) + case name: js.StringLiteral => genBracketSelect(obj, name) + } + js.Assign(select, value) + } + + /** Generate `obj.name = value` */ + def genAddToObject(obj: js.Tree, name: PropertyName, + value: js.Tree)(implicit pos: Position): js.Tree = { + genAddToObject(obj, genPropertyName(name), value) + } + def genPropertyName(name: PropertyName): js.PropertyName = name match { case ident: Ident => transformIdent(ident) case StringLiteral(value) => js.StringLiteral(value)(name.pos) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index d1b70ce017..683c355344 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -129,11 +129,11 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { member.tree match { case m: MethodDef => assert(m.name.isInstanceOf[StringLiteral], - "Exported method must have StringLiteral as name") + "Exported method must have StringLiteral as name") checkExportedMethodDef(m, classDef, isTopLevel = false) case p: PropertyDef => assert(p.name.isInstanceOf[StringLiteral], - "Exported property must have StringLiteral as name") + "Exported property must have StringLiteral as name") checkExportedPropertyDef(p, classDef) // Anything else is illegal case _ => @@ -277,8 +277,8 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { return } - if (!isTopLevel && static) - reportError("Exported method def cannot be static") + if (!isTopLevel && static && classDef.kind != ClassKind.JSClass) + reportError("Exported method def in non-JS class cannot be static") if (isTopLevel && !static) reportError("Top level export must be static") @@ -301,7 +301,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { } } - if (classDef.kind.isJSClass && name == "constructor") { + if (classDef.kind.isJSClass && name == "constructor" && !static) { checkJSClassConstructor(methodDef, classDef) } else { if (resultType != AnyType) { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index b3638d74f2..a87c5bdbe1 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -190,7 +190,8 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions getTree: TreeProvider, analysis: Analysis) = { import ir.Trees._ - val memberInfoByName = Map(info.methods.map(m => m.encodedName -> m): _*) + val memberInfoByStaticAndName = + Map(info.methods.map(m => (m.isStatic, m.encodedName) -> m): _*) val fields = mutable.Buffer.empty[FieldDef] val staticMethods = mutable.Buffer.empty[LinkedMember[MethodDef]] @@ -200,13 +201,13 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions val classExports = mutable.Buffer.empty[Tree] def linkedMethod(m: MethodDef) = { - val info = memberInfoByName(m.name.name) + val info = memberInfoByStaticAndName((m.static, m.name.name)) val version = m.hash.map(Hashers.hashAsVersion(_, considerPositions)) new LinkedMember(info, m, version) } def linkedProperty(p: PropertyDef) = { - val info = memberInfoByName(p.name.name) + val info = memberInfoByStaticAndName((false, p.name.name)) new LinkedMember(info, p, None) } @@ -219,8 +220,12 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions classDef.defs.foreach { // Static methods case m: MethodDef if m.static => - if (analyzerInfo.staticMethodInfos(m.name.name).isReachable) - staticMethods += linkedMethod(m) + if (analyzerInfo.staticMethodInfos(m.name.name).isReachable) { + if (m.name.isInstanceOf[StringLiteral]) + exportedMembers += linkedMethod(m) + else + staticMethods += linkedMethod(m) + } // Fields case field @ FieldDef(_, _, _) => @@ -284,7 +289,8 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions } } - val classExportInfo = memberInfoByName.get(Definitions.ClassExportsName) + val classExportInfo = + memberInfoByStaticAndName.get((false, Definitions.ClassExportsName)) val kind = if (analyzerInfo.isModuleAccessed) classDef.kind From 1f574854a8c440d4bbf7f67cdc3782207313116d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 13 Dec 2016 14:47:03 +0100 Subject: [PATCH 0088/2665] Create Scala.js-defined JS class values lazily. This will be necessary to implement features which require user-defined code to be executed at class-definition-time. Since such code can have arbitrary cyclic dependencies on anything else, it is absolutely necessary that everything else is defined or lazily loaded. The two features that will need that are: * `@JSSymbol` (#1997) * Static fields, with their static initializers (#1902) --- .../scalajs/jsenv/rhino/ScalaJSCoreLib.scala | 2 + project/BinaryIncompatibilities.scala | 5 ++ .../closure/ClosureAstTransformer.scala | 2 + tools/scalajsenv.js | 2 + .../core/tools/javascript/Printers.scala | 4 + .../linker/backend/emitter/Emitter.scala | 51 +++++++----- .../linker/backend/emitter/JSDesugaring.scala | 18 ++++- .../backend/emitter/ScalaJSClassEmitter.scala | 79 ++++++++++++++----- 8 files changed, 121 insertions(+), 42 deletions(-) diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala index ac059af571..03dd4b26fc 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala @@ -133,6 +133,8 @@ private[rhino] class ScalaJSCoreLib(linkingUnit: LinkingUnit) { private val scalaJSLazyFields = Seq( Info("d"), + Info("a"), + Info("b"), Info("c"), Info("h"), Info("s", isStatics = true), diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index c77318b933..9f18e0bd1e 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -6,6 +6,11 @@ object BinaryIncompatibilities { ) val Tools = Seq( + // private[emitter], not an issue + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genClass"), + ProblemFilters.exclude[MissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genClassDef") ) val JSEnvs = Seq( diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala index 9fea439c05..b59e932b46 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala @@ -204,6 +204,8 @@ private[closure] class ClosureAstTransformer(relativizeBaseURI: Option[URI]) { case Function(args, body) => genFunction("", args, body) + case FunctionDef(name, args, body) => + genFunction(name.name, args, body) case _ => throw new TransformException(s"Unknown tree of class ${tree.getClass()}") diff --git a/tools/scalajsenv.js b/tools/scalajsenv.js index 921529fb08..e7257e6a00 100644 --- a/tools/scalajsenv.js +++ b/tools/scalajsenv.js @@ -125,6 +125,8 @@ ScalaJS.clz32 = ScalaJS.g["Math"]["clz32"] || (function(i) { // Other fields //!if outputMode == ECMAScript51Global ScalaJS.d = {}; // Data for types +ScalaJS.a = {}; // Scala.js-defined JS class value accessors +ScalaJS.b = {}; // Scala.js-defined JS class value fields ScalaJS.c = {}; // Scala.js constructors ScalaJS.h = {}; // Inheritable constructors (without initialization code) ScalaJS.s = {}; // Static methods diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala index 7dde4e5aa4..30451e3539 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala @@ -491,10 +491,14 @@ object Printers { // Named function definition case FunctionDef(name, args, body) => + if (!isStat) + print('(') print("function ") print(name) printSig(args) printBlock(body) + if (!isStat) + print(')') // ECMAScript 6 classes diff --git 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 index 0e6c1ef616..886625fae6 100644 --- 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 @@ -109,8 +109,11 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, emitModuleImports(orderedClasses, builder, logger) - for (classInfo <- orderedClasses) - emitLinkedClass(classInfo, builder) + for (linkedClass <- orderedClasses) + emitLinkedClass(linkedClass, builder) + + for (linkedClass <- orderedClasses) + emitLinkedClassClassExports(linkedClass, builder) } finally { endRun(logger) } @@ -235,22 +238,8 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, val exportedMembers = classTreeCache.exportedMembers.getOrElseUpdate( classEmitter.genExportedMembers(linkedClass)(classCache)) - outputMode match { - case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => - addTree(ctor) - memberMethods.foreach(addTree) - addTree(exportedMembers) - - case OutputMode.ECMAScript6 => - val allMembersBlock = js.Block( - ctor :: memberMethods ::: exportedMembers :: Nil)(Position.NoPosition) - val allMembers = allMembersBlock match { - case js.Block(members) => members - case js.Skip() => Nil - case oneMember => List(oneMember) - } - addTree(classEmitter.genES6Class(linkedClass, allMembers)(classCache)) - } + addTree(classEmitter.buildClass(linkedClass, ctor, memberMethods, + exportedMembers)(classCache)) } else if (kind == ClassKind.Interface) { // Default methods for (m <- linkedClass.memberMethods) yield { @@ -279,9 +268,29 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, if (linkedClass.kind.hasModuleAccessor) addTree(classTreeCache.moduleAccessor.getOrElseUpdate( classEmitter.genModuleAccessor(linkedClass))) + } + + /** Emits the class exports of a linked class. + * + * This is done after everything else has been emitted for all the classes + * in the program. That is necessary because class exports can call class + * value accessors, which may have unknown circular references. + */ + private def emitLinkedClassClassExports( + linkedClass: LinkedClass, builder: JSTreeBuilder): Unit = { - addTree(classTreeCache.classExports.getOrElseUpdate( - classEmitter.genClassExports(linkedClass)(classCache))) + def addTree(tree: js.Tree): Unit = builder.addJSTree(tree) + + /* `if` to avoid looking up the caches for nothing. Probably worth doing + * because only few classes have class exports. + */ + if (linkedClass.classExports.nonEmpty) { + val classCache = getClassCache(linkedClass.ancestors) + val classTreeCache = classCache.getCache(linkedClass.version) + + addTree(classTreeCache.classExports.getOrElseUpdate( + classEmitter.genClassExports(linkedClass)(classCache))) + } } // Helpers @@ -323,7 +332,7 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, CoreJSLibs.lib(semantics, outputMode, moduleKind) def genClassDef(linkedClass: LinkedClass): js.Tree = - classEmitter.genClassDef(linkedClass)(globalKnowledge) + classEmitter.genClassDefForRhino(linkedClass)(globalKnowledge) } // Caching diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala index 46593dfab6..2479d5878b 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala @@ -2217,8 +2217,8 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { implicit outputMode: OutputMode, pos: Position): js.Tree = { spec match { case None => - // this is a Scala.js-defined JS class - encodeClassVar(className) + // This is a Scala.js-defined JS class, call its class value accessor + js.Apply(envField("a", className), Nil) case Some(spec) => genLoadJSFromSpec(spec) @@ -2343,6 +2343,14 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { private[emitter] def envFieldDef(field: String, subField: String, origName: Option[String], value: js.Tree, mutable: Boolean)( implicit outputMode: OutputMode, pos: Position): js.Tree = { + envFieldDef(field, subField, origName, value, mutable, + keepFunctionExpression = false) + } + + private[emitter] def envFieldDef(field: String, subField: String, + origName: Option[String], value: js.Tree, mutable: Boolean, + keepFunctionExpression: Boolean)( + implicit outputMode: OutputMode, pos: Position): js.Tree = { val globalVar = envField(field, subField, origName) def globalVarIdent = globalVar.asInstanceOf[js.VarRef].ident @@ -2354,7 +2362,11 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { value match { case js.Function(args, body) => // Make sure the function has a meaningful `name` property - js.FunctionDef(globalVarIdent, args, body) + val functionExpr = js.FunctionDef(globalVarIdent, args, body) + if (keepFunctionExpression) + js.VarDef(globalVarIdent, Some(functionExpr)) + else + functionExpr case _ => js.VarDef(globalVarIdent, Some(value)) } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala index 37829a2522..e40cf7b1f1 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala @@ -38,13 +38,11 @@ private[emitter] final class ScalaJSClassEmitter( private implicit def implicitOutputMode: OutputMode = outputMode - /** Desugar a Scala.js class into ECMAScript 5 constructs + /** Desugars a Scala.js class specifically for use by the Rhino interpreter. * * @param tree The IR tree to emit to raw JavaScript - * @param ancestors Encoded names of the ancestors of the class (not only - * parents), including the class itself. */ - def genClassDef(tree: LinkedClass)( + def genClassDefForRhino(tree: LinkedClass)( implicit globalKnowledge: GlobalKnowledge): js.Tree = { implicit val pos = tree.pos @@ -56,7 +54,7 @@ private[emitter] final class ScalaJSClassEmitter( if (kind == ClassKind.Interface) reverseParts ::= genDefaultMethods(tree) if (kind.isAnyScalaJSDefinedClass && tree.hasInstances) - reverseParts ::= genClass(tree) + reverseParts ::= genClassForRhino(tree) if (needInstanceTests(tree)) { reverseParts ::= genInstanceTests(tree) reverseParts ::= genArrayInstanceTests(tree) @@ -88,20 +86,26 @@ private[emitter] final class ScalaJSClassEmitter( js.Block(defaultMethodDefs)(tree.pos) } - def genClass(tree: LinkedClass)( + private def genClassForRhino(tree: LinkedClass)( implicit globalKnowledge: GlobalKnowledge): js.Tree = { val className = tree.name.name - val typeFunctionDef = genConstructor(tree) + val ctor = genConstructor(tree) val memberDefs = tree.memberMethods.map(m => genMethod(className, m.tree)) - val exportedDefs = genExportedMembers(tree) + buildClass(tree, ctor, memberDefs, exportedDefs) + } + + def buildClass(tree: LinkedClass, ctor: js.Tree, memberDefs: List[js.Tree], + exportedDefs: js.Tree)( + implicit globalKnowledge: GlobalKnowledge): js.Tree = { + val className = tree.name.name val allDefsBlock = - js.Block(typeFunctionDef +: memberDefs :+ exportedDefs)(tree.pos) + js.Block(ctor +: memberDefs :+ exportedDefs)(tree.pos) - outputMode match { + val entireClassDef = outputMode match { case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => allDefsBlock @@ -113,6 +117,37 @@ private[emitter] final class ScalaJSClassEmitter( } genES6Class(tree, allDefs) } + + if (!tree.kind.isJSClass) { + entireClassDef + } else { + // Wrap the entire class def in an accessor function + import TreeDSL._ + implicit val pos = tree.pos + + val createClassValueVar = + envFieldDef("b", className, js.Undefined(), mutable = true) + + val createAccessor = { + val classValueVar = envField("b", className) + + val body = js.Block( + js.If(!classValueVar, { + js.Block( + entireClassDef, + classValueVar := envField("c", className) + ) + }, { + js.Skip() + }), + js.Return(classValueVar) + ) + + envFieldDef("a", className, js.Function(Nil, body)) + } + + js.Block(createClassValueVar, createAccessor) + } } /** Generates an ECMAScript 6 class for a linked class. */ @@ -164,7 +199,8 @@ private[emitter] final class ScalaJSClassEmitter( def makeInheritableCtorDef(ctorToMimic: js.Tree) = { js.Block( js.DocComment("@constructor"), - envFieldDef("h", className, js.Function(Nil, js.Skip())), + envFieldDef("h", className, None, js.Function(Nil, js.Skip()), + mutable = false, keepFunctionExpression = isJSClass), js.Assign(envField("h", className).prototype, ctorToMimic.prototype) ) } @@ -185,7 +221,8 @@ private[emitter] final class ScalaJSClassEmitter( val typeVar = encodeClassVar(className) val docComment = js.DocComment("@constructor") - val ctorDef = envFieldDef("c", className, ctorFun) + val ctorDef = envFieldDef("c", className, None, ctorFun, mutable = false, + keepFunctionExpression = isJSClass) val chainProto = tree.superClass.fold[js.Tree] { js.Skip() @@ -763,11 +800,17 @@ private[emitter] final class ScalaJSClassEmitter( val moduleInstanceVar = envField("n", className) val assignModule = { - val jsNew = js.New(encodeClassVar(className), Nil) - val instantiateModule = - if (tree.kind == ClassKind.JSModuleClass) jsNew - else js.Apply(jsNew DOT js.Ident("init___"), Nil) - moduleInstanceVar := instantiateModule + moduleInstanceVar := { + if (tree.kind == ClassKind.JSModuleClass) { + js.New( + genRawJSClassConstructor(className, None), + Nil) + } else { + js.Apply( + js.New(encodeClassVar(className), Nil) DOT js.Ident("init___"), + Nil) + } + } } val initBlock = semantics.moduleInit match { @@ -883,7 +926,7 @@ private[emitter] final class ScalaJSClassEmitter( implicit val pos = tree.pos - val classVar = envField("c", cd.name.name) + val classVar = genRawJSClassConstructor(cd.name.name, None) genClassOrModuleExportDef(cd, tree.fullName, classVar) } From adc7e15a8f69e5928d36e0c34bf2064a02faebfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 5 Jan 2017 16:22:20 +0100 Subject: [PATCH 0089/2665] Fix #1902: Export module fields as static in their companion class. This commit implements the second part of the proposal #2702, i.e., exporting fields as static. The `@JSExportStatic` annotation can now be used on `val`s and `var`s in addition to methods. This causes the specified field to be exported (and in fact stored) as a static field in the companion class of the enclosing module. Since this affects the storage location of the field, it cannot be used twice (with different export names) on the same field, as that would require the field to be stored in two different locations. --- .../org/scalajs/core/compiler/GenJSCode.scala | 120 ++++++++++++------ .../scalajs/core/compiler/GenJSExports.scala | 50 +++++++- .../core/compiler/JSGlobalAddons.scala | 15 ++- .../scalajs/core/compiler/PrepJSExports.scala | 35 ++++- .../core/compiler/test/JSExportTest.scala | 74 ++++++++++- .../org/scalajs/core/ir/Definitions.scala | 12 +- .../scala/org/scalajs/core/ir/Printers.scala | 4 +- .../org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- .../org/scalajs/core/ir/Serializers.scala | 17 ++- .../org/scalajs/core/ir/Transformers.scala | 2 +- .../scala/org/scalajs/core/ir/Trees.scala | 3 +- .../org/scalajs/core/ir/PrintersTest.scala | 20 ++- project/BinaryIncompatibilities.scala | 13 ++ .../jsinterop/JSExportStaticTest.scala | 118 +++++++++++++++++ .../core/tools/linker/LinkedClass.scala | 2 +- .../core/tools/linker/analyzer/Analyzer.scala | 6 +- .../linker/backend/emitter/JSDesugaring.scala | 62 ++++++--- .../backend/emitter/ScalaJSClassEmitter.scala | 34 ++++- .../core/tools/linker/checker/IRChecker.scala | 8 +- .../tools/linker/frontend/BaseLinker.scala | 2 +- .../frontend/optimizer/GenIncOptimizer.scala | 2 +- 21 files changed, 510 insertions(+), 91 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index d680a5ccf4..6361dc8c35 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -509,9 +509,21 @@ abstract class GenJSCode extends plugins.PluginComponent companionModuleClasses.get(sym).fold[List[js.Tree]] { Nil } { companionModuleClass => - withScopedVars(currentClassSym := companionModuleClass) { + val exports = withScopedVars(currentClassSym := companionModuleClass) { genStaticExports(companionModuleClass) } + if (exports.exists(_.isInstanceOf[js.FieldDef])) { + val staticInitializer = js.MethodDef( + static = true, + js.Ident(ir.Definitions.StaticInitializerName), + Nil, + jstpe.NoType, + Some(genLoadModule(companionModuleClass)))( + OptimizerHints.empty, None) + exports :+ staticInitializer + } else { + exports + } } } @@ -839,6 +851,7 @@ abstract class GenJSCode extends plugins.PluginComponent f <- classSym.info.decls if !f.isMethod && f.isTerm && !f.isModule if !f.hasAnnotation(JSOptionalAnnotation) + if !jsInterop.isFieldStatic(f) } yield { implicit val pos = f.pos @@ -848,42 +861,44 @@ abstract class GenJSCode extends plugins.PluginComponent if (isExposed(f)) js.StringLiteral(jsNameOf(f)) else encodeFieldSym(f) - val irTpe = if (!isScalaJSDefinedJSClass(classSym)) { - toIRType(f.tpe) - } else { - val tpeEnteringPosterasure = - enteringPhase(currentRun.posterasurePhase)(f.tpe) - tpeEnteringPosterasure match { - case tpe: ErasedValueType => - /* Here, we must store the field as the boxed representation of - * the value class. The default value of that field, as - * initialized at the time the instance is created, will - * therefore be null. This will not match the behavior we would - * get in a Scala class. To match the behavior, we would need to - * initialized to an instance of the boxed representation, with - * an underlying value set to the zero of its type. However we - * cannot implement that, so we live with the discrepancy. - * Anyway, scalac also has problems with uninitialized value - * class values, if they come from a generic context. - */ - jstpe.ClassType(encodeClassFullName(tpe.valueClazz)) + val irTpe = + if (!isScalaJSDefinedJSClass(classSym)) toIRType(f.tpe) + else genExposedFieldIRType(f) - case _ if f.tpe.typeSymbol == CharClass => - /* Will be initialized to null, which will unbox to '\0' when - * read. - */ - jstpe.ClassType(ir.Definitions.BoxedCharacterClass) + js.FieldDef(static = false, name, irTpe, mutable) + }).toList + } - case _ => - /* Other types are not boxed, so we can initialized them to - * their true zero. - */ - toIRType(f.tpe) - } - } + def genExposedFieldIRType(f: Symbol): jstpe.Type = { + val tpeEnteringPosterasure = + enteringPhase(currentRun.posterasurePhase)(f.tpe) + tpeEnteringPosterasure match { + case tpe: ErasedValueType => + /* Here, we must store the field as the boxed representation of + * the value class. The default value of that field, as + * initialized at the time the instance is created, will + * therefore be null. This will not match the behavior we would + * get in a Scala class. To match the behavior, we would need to + * initialized to an instance of the boxed representation, with + * an underlying value set to the zero of its type. However we + * cannot implement that, so we live with the discrepancy. + * Anyway, scalac also has problems with uninitialized value + * class values, if they come from a generic context. + */ + jstpe.ClassType(encodeClassFullName(tpe.valueClazz)) - js.FieldDef(name, irTpe, mutable) - }).toList + case _ if f.tpe.typeSymbol == CharClass => + /* Will be initialized to null, which will unbox to '\0' when + * read. + */ + jstpe.ClassType(ir.Definitions.BoxedCharacterClass) + + case _ => + /* Other types are not boxed, so we can initialize them to + * their true zero. + */ + toIRType(f.tpe) + } } // Constructor of a Scala.js-defined JS class ------------------------------ @@ -1676,6 +1691,12 @@ abstract class GenJSCode extends plugins.PluginComponent case Select(qualifier, selector) => val sym = tree.symbol + + def unboxFieldValue(boxed: js.Tree): js.Tree = { + fromAny(boxed, + enteringPhase(currentRun.posterasurePhase)(sym.tpe)) + } + if (sym.isModule) { assert(!sym.isPackageClass, "Cannot use package as value: " + tree) genLoadModule(sym) @@ -1689,8 +1710,14 @@ abstract class GenJSCode extends plugins.PluginComponent js.JSBracketSelect(genQual, js.StringLiteral(jsNameOf(sym))) else js.JSDotSelect(genQual, encodeFieldSym(sym)) - fromAny(boxed, - enteringPhase(currentRun.posterasurePhase)(sym.tpe)) + unboxFieldValue(boxed) + } else if (jsInterop.isFieldStatic(sym)) { + val exportInfo = jsInterop.staticFieldInfoOf(sym) + assert(exportInfo.destination == ExportDestination.Static) + val companionClass = patchedLinkedClassOfClass(sym.owner) + val boxed = js.JSBracketSelect(genPrimitiveJSClass(companionClass), + js.StringLiteral(exportInfo.jsName)) + unboxFieldValue(boxed) } else { js.Select(genExpr(qualifier), encodeFieldSym(sym))(toIRType(sym.tpe)) @@ -1763,15 +1790,25 @@ abstract class GenJSCode extends plugins.PluginComponent val genQual = genExpr(qualifier) + def genBoxedRhs: js.Tree = { + ensureBoxed(genRhs, + enteringPhase(currentRun.posterasurePhase)(rhs.tpe)) + } + if (isScalaJSDefinedJSClass(sym.owner)) { val genLhs = if (isExposed(sym)) js.JSBracketSelect(genQual, js.StringLiteral(jsNameOf(sym))) else js.JSDotSelect(genQual, encodeFieldSym(sym)) - val boxedRhs = - ensureBoxed(genRhs, - enteringPhase(currentRun.posterasurePhase)(rhs.tpe)) - js.Assign(genLhs, boxedRhs) + js.Assign(genLhs, genBoxedRhs) + } else if (jsInterop.isFieldStatic(sym)) { + val exportInfo = jsInterop.staticFieldInfoOf(sym) + assert(exportInfo.destination == ExportDestination.Static) + val companionClass = patchedLinkedClassOfClass(sym.owner) + val select = js.JSBracketSelect( + genPrimitiveJSClass(companionClass), + js.StringLiteral(exportInfo.jsName)) + js.Assign(select, genBoxedRhs) } else { js.Assign( js.Select(genQual, encodeFieldSym(sym))(toIRType(sym.tpe)), @@ -4843,7 +4880,8 @@ abstract class GenJSCode extends plugins.PluginComponent // val f$1: Any val fFieldIdent = js.Ident("f$1", Some("f")) - val fFieldDef = js.FieldDef(fFieldIdent, jstpe.AnyType, mutable = false) + val fFieldDef = js.FieldDef(static = false, fFieldIdent, jstpe.AnyType, + mutable = false) // def this(f: Any) = { this.f$1 = f; super() } val ctorDef = { diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index 01ec5363ed..c837e492c0 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -125,15 +125,59 @@ trait GenJSExports extends SubComponent { self: GenJSCode => yield js.TopLevelExportDef(m)(m.pos) } - def genStaticExports(classSym: Symbol): List[js.MethodDef] = + def genStaticExports(classSym: Symbol): List[js.Tree] = genTopLevelOrStaticExports(classSym, ExportDestination.Static) private def genTopLevelOrStaticExports(classSym: Symbol, - destination: ExportDestination): List[js.MethodDef] = { + destination: ExportDestination): List[js.Tree] = { require( destination == ExportDestination.TopLevel || destination == ExportDestination.Static) + val exportsNamesAndPositions = { + genTopLevelOrStaticFieldExports(classSym, destination) ++ + genTopLevelOrStaticMethodExports(classSym, destination) + } + + for { + exportsWithSameName <- exportsNamesAndPositions.groupBy(_._2).values + duplicate <- exportsWithSameName.tail + } { + val strKind = + if (destination == ExportDestination.TopLevel) "top-level" + else "static" + reporter.error(duplicate._3, + s"Duplicate $strKind export with name '${duplicate._2}': " + + "a field may not share its exported name with another field or " + + "method") + } + + exportsNamesAndPositions.map(_._1) + } + + private def genTopLevelOrStaticFieldExports(classSym: Symbol, + destination: ExportDestination): List[(js.FieldDef, String, Position)] = { + (for { + fieldSym <- classSym.info.members + if !fieldSym.isMethod && fieldSym.isTerm && !fieldSym.isModule + export <- jsInterop.registeredExportsOf(fieldSym) + if export.destination == destination + } yield { + // in fact, top-level field exports do not exist yet + assert(export.destination == ExportDestination.Static) + + implicit val pos = fieldSym.pos + + val mutable = true // static fields must always be mutable + val name = js.StringLiteral(export.jsName) + val irTpe = genExposedFieldIRType(fieldSym) + + (js.FieldDef(static = true, name, irTpe, mutable), export.jsName, pos) + }).toList + } + + private def genTopLevelOrStaticMethodExports(classSym: Symbol, + destination: ExportDestination): List[(js.MethodDef, String, Position)] = { val allRelevantExports = for { methodSym <- classSym.info.members if methodSym.isMethod && !methodSym.isConstructor @@ -149,7 +193,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => implicit val pos = tups.head._1.pos val alts = tups.map(t => ExportedSymbol(t._2)).toList - genExportMethod(alts, jsName, static = true) + (genExportMethod(alts, jsName, static = true), jsName, pos) } } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala index 1b9413f863..1cfa878d33 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala @@ -75,7 +75,8 @@ trait JSGlobalAddons extends JSDefinitions } def registerForExport(sym: Symbol, infos: List[ExportInfo]): Unit = { - assert(!exportedSymbols.contains(sym), "Same symbol exported twice") + assert(!exportedSymbols.contains(sym), + "Same symbol exported twice: " + sym) exportedSymbols.put(sym, infos) } @@ -142,6 +143,18 @@ trait JSGlobalAddons extends JSDefinitions def isJSSetter(sym: Symbol): Boolean = nme.isSetterName(sym.name) && sym.isMethod && !sym.isConstructor + /** Is this field symbol a static field at the IR level? */ + def isFieldStatic(sym: Symbol): Boolean = { + sym.owner.isModuleClass && // usually false, avoids a lookup in the map + registeredExportsOf(sym).nonEmpty + } + + /** The only export info of a static field. + * Requires `isFieldStatic(sym)`. + */ + def staticFieldInfoOf(sym: Symbol): ExportInfo = + registeredExportsOf(sym).head + /** has this symbol to be translated into a JS bracket access (JS to Scala) */ def isJSBracketAccess(sym: Symbol): Boolean = sym.hasAnnotation(JSBracketAccessAnnotation) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala index 8e71744c61..87b675de90 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala @@ -220,7 +220,7 @@ trait PrepJSExports { this: PrepJSInterop => Nil } - for { + val allExportInfos = for { annot <- directAnnots ++ unitAnnots } yield { val isNamedExport = annot.symbol == JSExportNamedAnnotation @@ -377,7 +377,7 @@ trait PrepJSExports { this: PrepJSInterop => "Implementation restriction: cannot export a class or " + "object as static") } - } else if (jsInterop.isJSProperty(sym)) { + } else if (!sym.isAccessor && jsInterop.isJSProperty(sym)) { reporter.error(annot.pos, "Implementation restriction: cannot export a getter or a " + "setter as static") @@ -387,6 +387,37 @@ trait PrepJSExports { this: PrepJSInterop => ExportInfo(name, annot.pos, isNamedExport, destination, ignoreInvalid = false) } + + /* Filter out static exports of accessors (as they are not actually + * exported, their fields are). The above is only used to uniformly perform + * checks. + */ + if (!sym.isAccessor || sym.accessed == NoSymbol) { + allExportInfos + } else { + /* For accessors, we need to apply some special logic to static exports. + * When tested on accessors, they actually apply on *fields*, not on the + * accessors. We use the same code paths hereabove to uniformly perform + * relevant checks, but at the end of the day, we have to throw away the + * ExportInfo. + * However, we must make sure that no field is exported *twice* as static. + */ + val (staticExportInfos, actualExportInfos) = + allExportInfos.partition(_.destination == ExportDestination.Static) + + if (sym.isGetter) { + val duplicates = staticExportInfos.drop(1) // no-op if isEmpty + for (duplicate <- duplicates) { + reporter.error(duplicate.pos, + "Fields (val or var) cannot be exported as static more than " + + "once") + } + + jsInterop.registerForExport(sym.accessed, staticExportInfos) + } + + actualExportInfos + } } private def inheritedExportsOf(sym: Symbol): List[ExportInfo] = { diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index 6b2b35073d..4a881adfc3 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -1324,37 +1324,39 @@ class JSExportTest extends DirectTest with TestHelpers { } @Test - def noExportStaticVal: Unit = { + def noExportStaticValTwice: Unit = { """ @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @JSExportStatic + @JSExportStatic("b") val a: Int = 1 } """ hasErrors """ - |newSource1.scala:7: error: Implementation restriction: cannot export a getter or a setter as static - | @JSExportStatic + |newSource1.scala:8: error: Fields (val or var) cannot be exported as static more than once + | @JSExportStatic("b") | ^ """ } @Test - def noExportStaticVar: Unit = { + def noExportStaticVarTwice: Unit = { """ @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @JSExportStatic + @JSExportStatic("b") var a: Int = 1 } """ hasErrors """ - |newSource1.scala:7: error: Implementation restriction: cannot export a getter or a setter as static - | @JSExportStatic + |newSource1.scala:8: error: Fields (val or var) cannot be exported as static more than once + | @JSExportStatic("b") | ^ """ } @@ -1418,6 +1420,66 @@ class JSExportTest extends DirectTest with TestHelpers { """ } + @Test + def noExportStaticFieldsWithSameName: Unit = { + """ + @ScalaJSDefined + class StaticContainer extends js.Object + + object StaticContainer { + @JSExportStatic + val a: Int = 1 + + @JSExportStatic("a") + var b: Int = 1 + } + """ hasErrors + """ + |newSource1.scala:8: error: Duplicate static export with name 'a': a field may not share its exported name with another field or method + | val a: Int = 1 + | ^ + """ + } + + @Test + def noExportStaticFieldsAndMethodsWithSameName: Unit = { + """ + @ScalaJSDefined + class StaticContainer extends js.Object + + object StaticContainer { + @JSExportStatic + val a: Int = 1 + + @JSExportStatic("a") + def b(x: Int): Int = x + 1 + } + """ hasErrors + """ + |newSource1.scala:10: error: Duplicate static export with name 'a': a field may not share its exported name with another field or method + | @JSExportStatic("a") + | ^ + """ + + """ + @ScalaJSDefined + class StaticContainer extends js.Object + + object StaticContainer { + @JSExportStatic + def a(x: Int): Int = x + 1 + + @JSExportStatic("a") + val b: Int = 1 + } + """ hasErrors + """ + |newSource1.scala:7: error: Duplicate static export with name 'a': a field may not share its exported name with another field or method + | @JSExportStatic + | ^ + """ + } + @Test def noExportStaticNonStatic: Unit = { """ diff --git a/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala b/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala index 7b7e9d37f9..617bb7b5fc 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala @@ -66,6 +66,9 @@ object Definitions { val AncestorsOfPseudoArrayClass = Set( ObjectClass, SerializableClass, CloneableClass) + /** Name of the static initializer method. */ + final val StaticInitializerName = "clinit___" + /** Name used for infos of class exports * * These currently are exported constructors and top level exports) @@ -166,6 +169,8 @@ object Definitions { if (encodedName == "init___") "" else encodedName.stripPrefix("init___") + "__" ("", privateAndSigString) + } else if (encodedName == StaticInitializerName) { + ("", "") } else { val pos = encodedName.indexOf("__") val pos2 = @@ -205,7 +210,10 @@ object Definitions { def isConstructorName(name: String): Boolean = name.startsWith("init___") - def isReflProxyName(name: String): Boolean = - name.endsWith("__") && !isConstructorName(name) + def isReflProxyName(name: String): Boolean = { + name.endsWith("__") && + !isConstructorName(name) && + name != StaticInitializerName + } } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index 3f0d64f41a..693115de3e 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -797,7 +797,9 @@ object Printers { print(" ") printColumn(defs, "{", "", "}") - case FieldDef(name, vtpe, mutable) => + case FieldDef(static, name, vtpe, mutable) => + if (static) + print("static ") if (mutable) print("var ") else diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index cb9f932c3d..b94a38cfa3 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -21,7 +21,7 @@ object ScalaJSVersions { * - a prior release version (i.e. "0.5.0", *not* "0.5.0-SNAPSHOT") * - `current` */ - val binaryEmitted: String = "0.6.14" + val binaryEmitted: String = current /** Versions whose binary files we can support (used by deserializer) */ val binarySupported: Set[String] = { diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index 752a3c2a64..c1007759ec 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -403,16 +403,18 @@ object Serializers { writeTrees(defs) writeInt(tree.optimizerHints.bits) - case FieldDef(name, ftpe, mutable) => + case FieldDef(static, name, ftpe, mutable) => /* TODO Simply use `writePropertyName` when we can break binary * compatibility. */ name match { case name: Ident => writeByte(TagFieldDef) + writeBoolean(static) writeIdent(name) case name: StringLiteral => writeByte(TagStringLitFieldDef) + writeBoolean(static) writeTree(name) } writeType(ftpe); writeBoolean(mutable) @@ -635,6 +637,8 @@ object Serializers { useHacks065 || sourceVersion == "0.6.6" private[this] val useHacks068 = useHacks066 || sourceVersion == "0.6.8" + private[this] val useHacks0614 = + useHacks068 || Set("0.6.13", "0.6.14").contains(sourceVersion) private[this] val input = new DataInputStream(stream) @@ -822,12 +826,19 @@ object Serializers { optimizerHints) case TagFieldDef => - FieldDef(readIdent(), readType(), readBoolean()) + val static = + if (useHacks0614) false + else readBoolean() + FieldDef(static, readIdent(), readType(), readBoolean()) case TagStringLitFieldDef => /* TODO Merge this into TagFieldDef and use readPropertyName() * when we can break binary compatibility. */ - FieldDef(readTree().asInstanceOf[StringLiteral], readType(), readBoolean()) + val static = + if (useHacks0614) false + else readBoolean() + FieldDef(static, readTree().asInstanceOf[StringLiteral], readType(), + readBoolean()) case TagMethodDef => val optHash = readOptHash() diff --git a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala index b35f8a1b34..731fa96f5a 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala @@ -209,7 +209,7 @@ object Transformers { implicit val pos = tree.pos tree match { - case FieldDef(_, _, _) => + case FieldDef(_, _, _, _) => tree case tree: MethodDef => diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 629770c04b..40cb719dcc 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -777,7 +777,8 @@ object Trees { val tpe = NoType } - case class FieldDef(name: PropertyName, ftpe: Type, mutable: Boolean)( + case class FieldDef(static: Boolean, name: PropertyName, ftpe: Type, + mutable: Boolean)( implicit val pos: Position) extends Tree { val tpe = NoType } diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala index 0447859ed8..d0df1eb29b 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala @@ -912,14 +912,26 @@ class PrintersTest { """, ClassDef("LTest", ClassKind.Class, Some(ObjectClass), Nil, None, List( - FieldDef("x$1", IntType, mutable = false), - FieldDef("y$1", IntType, mutable = true)))( + FieldDef(static = false, "x$1", IntType, mutable = false), + FieldDef(static = false, "y$1", IntType, mutable = true)))( NoOptHints)) } @Test def printFieldDef(): Unit = { - assertPrintEquals("val x$1: int", FieldDef("x$1", IntType, mutable = false)) - assertPrintEquals("var y$1: any", FieldDef("y$1", AnyType, mutable = true)) + assertPrintEquals("val x$1: int", + FieldDef(static = false, "x$1", IntType, mutable = false)) + assertPrintEquals("var y$1: any", + FieldDef(static = false, "y$1", AnyType, mutable = true)) + + assertPrintEquals("""val "x": int""", + FieldDef(static = false, StringLiteral("x"), IntType, mutable = false)) + assertPrintEquals("""var "y": any""", + FieldDef(static = false, StringLiteral("y"), AnyType, mutable = true)) + + assertPrintEquals("""static val "x": int""", + FieldDef(static = true, StringLiteral("x"), IntType, mutable = false)) + assertPrintEquals("""static var "y": any""", + FieldDef(static = true, StringLiteral("y"), AnyType, mutable = true)) } @Test def printMethodDef(): Unit = { diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 9f18e0bd1e..6b03f3323c 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -3,6 +3,19 @@ import com.typesafe.tools.mima.core.ProblemFilters._ object BinaryIncompatibilities { val IR = Seq( + // Breaking: FieldDef has new field `static` + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.ir.Trees#FieldDef.this"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.ir.Trees#FieldDef.apply"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.ir.Trees#FieldDef.copy"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.core.ir.Trees#FieldDef.copy$default$1"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.core.ir.Trees#FieldDef.copy$default$2"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.core.ir.Trees#FieldDef.copy$default$3") ) val Tools = Seq( diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala index 5cd7f5eff4..1389c5190f 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala @@ -18,6 +18,8 @@ import org.junit.Assume._ import org.junit.Test class JSExportStaticTest { + // Methods + @Test def toplevel_basic_static_method_export(): Unit = { val statics = js.constructorOf[TopLevelStaticExportMethods] @@ -124,6 +126,91 @@ class JSExportStaticTest { assertEquals(6, obj.alsoExistsAsMember(3)) } + // Fields + + @Test def basic_field(): Unit = { + val statics = js.constructorOf[JSExportStaticTest.StaticExportFields] + + // Initialization + assertEquals(5, statics.basicVal) + assertEquals("hello", statics.basicVar) + + // JS modifies var + statics.basicVar = "hello world" + assertEquals("hello world", statics.basicVar) + assertEquals("hello world", JSExportStaticTest.StaticExportFields.basicVar) + + // Scala modifies var + JSExportStaticTest.StaticExportFields.basicVar = "modified once more" + assertEquals("modified once more", + JSExportStaticTest.StaticExportFields.basicVar) + assertEquals("modified once more", statics.basicVar) + + // Reset var + JSExportStaticTest.StaticExportFields.basicVar = "hello" + } + + @Test def read_tampered_var_causes_class_cast_exception(): Unit = { + assumeTrue("assuming compliant asInstanceOfs", hasCompliantAsInstanceOfs) + + val statics = js.constructorOf[JSExportStaticTest.StaticExportFields] + + // JS modifies var with an incorrect type + statics.basicVar = 42 + assertThrows(classOf[ClassCastException], { + assertEquals(42, JSExportStaticTest.StaticExportFields.basicVar) + }) + + // Reset var + JSExportStaticTest.StaticExportFields.basicVar = "hello" + } + + @Test def renamed_field(): Unit = { + val statics = js.constructorOf[JSExportStaticTest.StaticExportFields] + + // Initialization + assertEquals(6, statics.renamedVal) + assertEquals("world", statics.renamedVar) + + // JS modifies var + statics.renamedVar = "hello world" + assertEquals("hello world", statics.renamedVar) + assertEquals("hello world", + JSExportStaticTest.StaticExportFields.renamedBasicVar) + + // Scala modifies var + JSExportStaticTest.StaticExportFields.renamedBasicVar = "modified once more" + assertEquals("modified once more", + JSExportStaticTest.StaticExportFields.renamedBasicVar) + assertEquals("modified once more", statics.renamedVar) + + // Reset var + JSExportStaticTest.StaticExportFields.renamedBasicVar = "world" + } + + @Test def uninitialized_fields(): Unit = { + val statics = js.constructorOf[JSExportStaticTest.StaticExportFields] + + assertEquals(0, JSExportStaticTest.StaticExportFields.uninitializedVarInt) + assertEquals(0, statics.uninitializedVarInt) + + assertEquals(null, + JSExportStaticTest.StaticExportFields.uninitializedVarString) + assertEquals(null, statics.uninitializedVarString) + + assertEquals('\0', + JSExportStaticTest.StaticExportFields.uninitializedVarChar) + assertEquals(null, statics.uninitializedVarChar) + } + + @Test def field_also_exists_in_member(): Unit = { + val statics = js.constructorOf[JSExportStaticTest.StaticExportFields] + assertEquals("hello", statics.alsoExistsAsMember) + + val obj = new JSExportStaticTest.StaticExportFields + assertEquals(5, obj.alsoExistsAsMember) + } + } @ScalaJSDefined @@ -198,4 +285,35 @@ object JSExportStaticTest { @JSExportStatic def alsoExistsAsMember(x: Int): Int = x * 5 } + + @ScalaJSDefined + class StaticExportFields extends js.Object { + val alsoExistsAsMember: Int = 5 + } + + object StaticExportFields { + @JSExportStatic + val basicVal: Int = 5 + + @JSExportStatic + var basicVar: String = "hello" + + @JSExportStatic("renamedVal") + val renamedBasicVal: Int = 6 + + @JSExportStatic("renamedVar") + var renamedBasicVar: String = "world" + + @JSExportStatic + var uninitializedVarInt: Int = _ + + @JSExportStatic + var uninitializedVarString: String = _ + + @JSExportStatic + var uninitializedVarChar: Char = _ + + @JSExportStatic + val alsoExistsAsMember: String = "hello" + } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala index 3a787ee5cb..5ca4821a50 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala @@ -159,7 +159,7 @@ object LinkedClass { staticMethods += linkedMethod(m) // Fields - case field @ FieldDef(_, _, _) => + case field @ FieldDef(_, _, _, _) => fields += field // Normal methods diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala index d2e3ce7562..ac62734d78 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala @@ -616,8 +616,12 @@ private final class Analyzer(semantics: Semantics, subclassInstantiated() - if (isJSClass) + if (isJSClass) { superClass.instantiated() + tryLookupStaticMethod(Definitions.StaticInitializerName).foreach { + staticInit => staticInit.reachStatic() + } + } for (methodInfo <- staticMethodInfos.values) { if (methodInfo.isExported) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala index 2479d5878b..5231d81662 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala @@ -530,7 +530,8 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { globalKnowledge.getJSClassFieldDefs(enclosingClassName) val fieldDefs = for { - field @ FieldDef(name, ftpe, mutable) <- enclosingClassFieldDefs + field @ FieldDef(false, name, ftpe, mutable) <- + enclosingClassFieldDefs } yield { implicit val pos = field.pos /* Here, a naive translation would emit something like this: @@ -569,7 +570,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { js.StringLiteral("configurable") -> js.BooleanLiteral(true), js.StringLiteral("enumerable") -> js.BooleanLiteral(true), js.StringLiteral("writable") -> js.BooleanLiteral(true), - js.StringLiteral("value") -> transformExpr(zeroOf(ftpe)) + js.StringLiteral("value") -> genZeroOf(ftpe) )) val descriptors = js.ObjectConstr(List( transformedName -> descriptor)) @@ -1959,7 +1960,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { case StringLiteral(value) => js.StringLiteral(value) case LongLiteral(0L) => - genLongModuleApply(LongImpl.Zero) + genLongZero() case LongLiteral(value) => if (globalKnowledge.hasNewRuntimeLong) { val (lo, hi) = LongImpl.extractParts(value) @@ -2086,20 +2087,6 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { js.Apply(receiver DOT methodName, args.toList) } - private def genLongModuleApply(methodName: String, args: js.Tree*)( - implicit pos: Position): js.Tree = { - import TreeDSL._ - js.Apply( - genLoadModule(LongImpl.RuntimeLongModuleClass) DOT methodName, - args.toList) - } - - private def genLoadModule(moduleClass: String)( - implicit pos: Position): js.Tree = { - import TreeDSL._ - js.Apply(envField("m", moduleClass), Nil) - } - private implicit class RecordAwareEnv(env: Env) { def withDef(ident: Ident, tpe: Type, mutable: Boolean): Env = tpe match { case RecordType(fields) => @@ -2121,6 +2108,33 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { // Helpers + private[emitter] def genZeroOf(tpe: Type)( + implicit outputMode: OutputMode, pos: Position): js.Tree = { + tpe match { + case BooleanType => js.BooleanLiteral(false) + case IntType => js.IntLiteral(0) + case LongType => genLongZero() + case FloatType => js.DoubleLiteral(0.0) + case DoubleType => js.DoubleLiteral(0.0) + case StringType => js.StringLiteral("") + case UndefType => js.Undefined() + case _ => js.Null() + } + } + + private def genLongZero()( + implicit outputMode: OutputMode, pos: Position): js.Tree = { + genLongModuleApply(LongImpl.Zero) + } + + private def genLongModuleApply(methodName: String, args: js.Tree*)( + implicit outputMode: OutputMode, pos: Position): js.Tree = { + import TreeDSL._ + js.Apply( + genLoadModule(LongImpl.RuntimeLongModuleClass) DOT methodName, + args.toList) + } + private[emitter] def genLet(name: js.Ident, mutable: Boolean, rhs: js.Tree)( implicit outputMode: OutputMode, pos: Position): js.LocalDef = { outputMode match { @@ -2204,6 +2218,12 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { implicit outputMode: OutputMode, pos: Position): js.Tree = envField("c", className) + private[emitter] def genLoadModule(moduleClass: String)( + implicit outputMode: OutputMode, pos: Position): js.Tree = { + import TreeDSL._ + js.Apply(envField("m", moduleClass), Nil) + } + private[emitter] def genRawJSClassConstructor(className: String)( implicit globalKnowledge: GlobalKnowledge, outputMode: OutputMode, pos: Position): js.Tree = { @@ -2376,6 +2396,14 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { } } + private[emitter] def genPropSelect(qual: js.Tree, item: js.PropertyName)( + implicit pos: Position): js.Tree = { + item match { + case item: js.Ident => js.DotSelect(qual, item) + case item: js.StringLiteral => genBracketSelect(qual, item) + } + } + private[emitter] def genBracketSelect(qual: js.Tree, item: js.Tree)( implicit pos: Position): js.Tree = { item match { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala index e40cf7b1f1..b775f46890 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala @@ -135,7 +135,9 @@ private[emitter] final class ScalaJSClassEmitter( js.If(!classValueVar, { js.Block( entireClassDef, - classValueVar := envField("c", className) + genCreateStaticFieldsOfJSClass(tree), + classValueVar := envField("c", className), + genStaticInitializationOfJSClass(tree) ) }, { js.Skip() @@ -292,7 +294,7 @@ private[emitter] final class ScalaJSClassEmitter( implicit globalKnowledge: GlobalKnowledge): List[js.Tree] = { val tpe = ClassType(tree.encodedName) for { - field @ FieldDef(name, ftpe, mutable) <- tree.fields + field @ FieldDef(false, name, ftpe, mutable) <- tree.fields } yield { implicit val pos = field.pos val selectField = (name: @unchecked) match { @@ -303,6 +305,34 @@ private[emitter] final class ScalaJSClassEmitter( } } + /** Generates the creation of the static fields for a JavaScript class. */ + private def genCreateStaticFieldsOfJSClass(tree: LinkedClass)( + implicit globalKnowledge: GlobalKnowledge): js.Tree = { + val className = tree.encodedName + val stats = for { + field @ FieldDef(true, name, ftpe, mutable) <- tree.fields + } yield { + implicit val pos = field.pos + val classVar = envField("c", className) + val select = genPropSelect(classVar, genPropertyName(name)) + js.Assign(select, genZeroOf(ftpe)) + } + js.Block(stats)(tree.pos) + } + + /** Generates the static initializer invocation of a JavaScript class. */ + private def genStaticInitializationOfJSClass(tree: LinkedClass)( + implicit globalKnowledge: GlobalKnowledge): js.Tree = { + import Definitions.StaticInitializerName + implicit val pos = tree.pos + if (tree.staticMethods.exists(_.tree.name.name == StaticInitializerName)) { + val fullName = tree.encodedName + "__" + StaticInitializerName + js.Apply(envField("s", fullName, Some("")), Nil) + } else { + js.Skip() + } + } + /** Generates a method. */ def genMethod(className: String, method: MethodDef)( implicit globalKnowledge: GlobalKnowledge): js.Tree = { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 683c355344..5ee8bbb084 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -200,9 +200,12 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { } private def checkFieldDef(fieldDef: FieldDef, classDef: LinkedClass): Unit = { - val FieldDef(name, tpe, mutable) = fieldDef + val FieldDef(static, name, tpe, mutable) = fieldDef implicit val ctx = ErrorContext(fieldDef) + if (static && !classDef.kind.isJSClass) + reportError(s"FieldDef '$name' cannot be static") + name match { case _: Ident => // ok @@ -960,6 +963,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { val resultType = resultRefType.fold[Type] { if (isConstructorName(encodedName)) NoType + else if (encodedName == StaticInitializerName) NoType else AnyType // reflective proxy } { refType => refTypeToType(refType) @@ -1143,7 +1147,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { private object CheckedClass { private def checkedField(fieldDef: FieldDef) = { - val FieldDef(Ident(name, _), tpe, mutable) = fieldDef + val FieldDef(false, Ident(name, _), tpe, mutable) = fieldDef new CheckedField(name, tpe, mutable) } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index a87c5bdbe1..d89ed5b785 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -228,7 +228,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions } // Fields - case field @ FieldDef(_, _, _) => + case field @ FieldDef(_, _, _, _) => if (analyzerInfo.isAnySubclassInstantiated) fields += field diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala index 60021928c6..f61ed14de7 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala @@ -560,7 +560,7 @@ abstract class GenIncOptimizer private[optimizer] (semantics: Semantics, } else { val allFields = reverseParentChain.flatMap(_.fields) val (fieldValues, fieldTypes) = (for { - f @ FieldDef(Ident(name, originalName), tpe, mutable) <- allFields + f @ FieldDef(false, Ident(name, originalName), tpe, mutable) <- allFields } yield { (zeroOf(tpe)(f.pos), RecordType.Field(name, originalName, tpe, mutable)) From d28845a866bca1968658de1556577564cf9b74b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 11 Jan 2017 14:53:01 +0100 Subject: [PATCH 0090/2665] Fix #2708: Remove a years-old workaround for a Closure bug. In the original implementation of a custom exports namespace, 6680f72e8167af954d58797d26e943cf3326c4af, we introduced a workaround for an apparent bug of Closure: we forced some unelidable read of `ScalaJS.e` so that Closure would not get rid of it, and all our exports alongside it. The workaround was refined later in 8793d47c9f88def176e927a2296fb82db893859a to fix #518. It appears this workaround is not needed anymore. It might be because of the update of Closure, or because we have another read of `ScalaJS.e` at the beginning of the file, or anything else really. In any case, I cannot reproduce the bug anymore without the workaround. Since that line was causing #2708, removing it fixes that issue. --- tools/scalajsenv.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tools/scalajsenv.js b/tools/scalajsenv.js index e7257e6a00..a59f84752f 100644 --- a/tools/scalajsenv.js +++ b/tools/scalajsenv.js @@ -709,12 +709,6 @@ ScalaJS.typedArray2DoubleArray = function(value) { return new arrayClassData.constr(new ScalaJS.g["Float64Array"](value)); }; -/* We have to force a non-elidable *read* of ScalaJS.e, otherwise Closure will - * eliminate it altogether, along with all the exports, which is ... er ... - * plain wrong. - */ -this["__ScalaJSExportsNamespace"] = ScalaJS.e; - // TypeData class //!if outputMode != ECMAScript6 From 8d39212f9d1a8207c969480c453f25123caf4bcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 11 Jan 2017 14:21:38 +0100 Subject: [PATCH 0091/2665] Fix #2709: Support reflective call of eq, ne, synchronized on AnyVal. To implement this, we drop support for reflective call of those methods on AnyRef instances, though. This is bug-compatible with the JVM. --- .../org/scalajs/core/compiler/GenJSCode.scala | 100 ++++++++--------- .../compiler/ReflectiveCallTest.scala | 101 ++++++++++++++---- 2 files changed, 135 insertions(+), 66 deletions(-) rename test-suite/{js => shared}/src/test/scala/org/scalajs/testsuite/compiler/ReflectiveCallTest.scala (77%) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 0c6e2a0ef2..ce35b312e1 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -3465,14 +3465,23 @@ abstract class GenJSCode extends plugins.PluginComponent implicit val pos = tree.pos val sym = tree.symbol + val name = sym.name val params = sym.tpe.params - /** check if the method we are invoking is eq or ne. they cannot be - * overridden since they are final. If this is true, we only emit a - * `===` or `!==`. + /* Is this a primitive method introduced in AnyRef? + * The concerned methods are `eq`, `ne` and `synchronized`. + * + * If it is, it can be defined in a custom value class. Calling it + * reflectively works on the JVM in that case. However, it does not work + * if the reflective call should in fact resolve to the method in + * `AnyRef` (it causes a `NoSuchMethodError`). We maintain bug + * compatibility for these methods: they work if redefined in a custom + * AnyVal, and fail at run-time (with a `TypeError`) otherwise. */ - val isEqOrNeq = (sym.name == nme.eq || sym.name == nme.ne) && + val isAnyRefPrimitive = { + (name == nme.eq || name == nme.ne || name == nme.synchronized_) && params.size == 1 && params.head.tpe.typeSymbol == ObjectClass + } /** check if the method we are invoking conforms to a method on * scala.Array. If this is the case, we check that case specially at @@ -3483,15 +3492,17 @@ abstract class GenJSCode extends plugins.PluginComponent * Note that we cannot check if the expected return type is correct, * since this type information is already erased. */ - def isArrayLikeOp = { - sym.name == nme.update && - params.size == 2 && params.head.tpe.typeSymbol == IntClass || - sym.name == nme.apply && - params.size == 1 && params.head.tpe.typeSymbol == IntClass || - sym.name == nme.length && - params.size == 0 || - sym.name == nme.clone_ && + def isArrayLikeOp = name match { + case nme.update => + params.size == 2 && params.head.tpe.typeSymbol == IntClass + case nme.apply => + params.size == 1 && params.head.tpe.typeSymbol == IntClass + case nme.length => + params.size == 0 + case nme.clone_ => params.size == 0 + case _ => + false } /** @@ -3500,7 +3511,7 @@ abstract class GenJSCode extends plugins.PluginComponent * (result != NoSymbol), we generate a runtime instance check if we are * dealing with the appropriate primitive type. */ - def matchingSymIn(clazz: Symbol) = clazz.tpe.member(sym.name).suchThat { s => + def matchingSymIn(clazz: Symbol) = clazz.tpe.member(name).suchThat { s => val sParams = s.tpe.params !s.isBridge && params.size == sParams.size && @@ -3511,40 +3522,33 @@ abstract class GenJSCode extends plugins.PluginComponent val ApplyDynamic(receiver, args) = tree - if (isEqOrNeq) { - // Just emit a boxed equality check - val jsThis = genExpr(receiver) - val jsThat = genExpr(args.head) - val op = if (sym.name == nme.eq) js.BinaryOp.=== else js.BinaryOp.!== - ensureBoxed(js.BinaryOp(op, jsThis, jsThat), BooleanClass.tpe) - } else { - // Create a fully-fledged reflective call - val receiverType = toIRType(receiver.tpe) - val callTrgIdent = freshLocalIdent() - val callTrgVarDef = - js.VarDef(callTrgIdent, receiverType, mutable = false, genExpr(receiver)) - val callTrg = js.VarRef(callTrgIdent)(receiverType) - - val arguments = args zip sym.tpe.params map { case (arg, param) => - /* No need for enteringPosterasure, because value classes are not - * supported as parameters of methods in structural types. - * We could do it for safety and future-proofing anyway, except that - * I am weary of calling enteringPosterasure for a reflective method - * symbol. - * - * Note also that this will typically unbox a primitive value that - * has just been boxed, or will .asInstanceOf[T] an expression which - * is already of type T. But the optimizer will get rid of that, and - * reflective calls are not numerous, so we don't complicate the - * compiler to eliminate them early. - */ - fromAny(genExpr(arg), param.tpe) - } + val receiverType = toIRType(receiver.tpe) + val callTrgIdent = freshLocalIdent() + val callTrgVarDef = + js.VarDef(callTrgIdent, receiverType, mutable = false, genExpr(receiver)) + val callTrg = js.VarRef(callTrgIdent)(receiverType) + + val arguments = args zip sym.tpe.params map { case (arg, param) => + /* No need for enteringPosterasure, because value classes are not + * supported as parameters of methods in structural types. + * We could do it for safety and future-proofing anyway, except that + * I am weary of calling enteringPosterasure for a reflective method + * symbol. + * + * Note also that this will typically unbox a primitive value that + * has just been boxed, or will .asInstanceOf[T] an expression which + * is already of type T. But the optimizer will get rid of that, and + * reflective calls are not numerous, so we don't complicate the + * compiler to eliminate them early. + */ + fromAny(genExpr(arg), param.tpe) + } - val proxyIdent = encodeMethodSym(sym, reflProxy = true) - var callStatement: js.Tree = - genApplyMethod(callTrg, proxyIdent, arguments, jstpe.AnyType) + val proxyIdent = encodeMethodSym(sym, reflProxy = true) + var callStatement: js.Tree = + genApplyMethod(callTrg, proxyIdent, arguments, jstpe.AnyType) + if (!isAnyRefPrimitive) { if (isArrayLikeOp) { def genRTCall(method: Symbol, args: js.Tree*) = genApplyMethod(genLoadModule(ScalaRunTimeModule), @@ -3552,7 +3556,7 @@ abstract class GenJSCode extends plugins.PluginComponent val isArrayTree = genRTCall(ScalaRunTime_isArray, callTrg, js.IntLiteral(1)) callStatement = js.If(isArrayTree, { - sym.name match { + name match { case nme.update => js.Block( genRTCall(currentRun.runDefinitions.arrayUpdateMethod, @@ -3632,9 +3636,9 @@ abstract class GenJSCode extends plugins.PluginComponent callStatement })(jstpe.AnyType) } - - js.Block(callTrgVarDef, callStatement) } + + js.Block(callTrgVarDef, callStatement) } /** Ensures that the value of the given tree is boxed. diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectiveCallTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ReflectiveCallTest.scala similarity index 77% rename from test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectiveCallTest.scala rename to test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ReflectiveCallTest.scala index 20aaa1e21b..580a19c54d 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectiveCallTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ReflectiveCallTest.scala @@ -7,16 +7,19 @@ \* */ package org.scalajs.testsuite.compiler -import scala.scalajs.js +import language.reflectiveCalls import org.junit.Test import org.junit.Assert._ +import org.junit.Assume._ -import language.reflectiveCalls +import org.scalajs.testsuite.utils.Platform +import org.scalajs.testsuite.utils.AssertThrows._ import java.lang.{Float => JFloat, Double => JDouble} class ReflectiveCallTest { + import ReflectiveCallTest._ @Test def should_allow_subtyping_in_return_types(): Unit = { class A { def x: Int = 1 } @@ -68,10 +71,10 @@ class ReflectiveCallTest { assertEquals(-1L, fLong(1L)) def fFloat(x: Any { def unary_- : Float}): Float = -x - assertEquals(-1.5f, fFloat(1.5f)) + assertEquals(-1.5f, fFloat(1.5f), 1e-5f) def fDouble(x: Any { def unary_- : Double }): Double = -x - assertEquals(-1.5, fDouble(1.5)) + assertEquals(-1.5, fDouble(1.5), 1e-5d) def fBoolean(x: Any { def unary_! : Boolean }): Boolean = !x assertTrue(fBoolean(false)) @@ -100,10 +103,10 @@ class ReflectiveCallTest { assertEquals(-34, fShort(-40)) def fFloat(x: Any { def %(x: Float): Float}): Float = x % 3.4f - assertEquals(2.1f, fFloat(5.5f)) + assertEquals(2.1f, fFloat(5.5f), 1e-5f) def fDouble(x: Any { def /(x: Double): Double }): Double = x / 1.4 - assertEquals(-1.0714285714285714, fDouble(-1.5)) + assertEquals(-1.0714285714285714, fDouble(-1.5), 1e-5d) def fBoolean(x: Any { def &&(x: Boolean): Boolean }): Boolean = x && true // scalastyle:ignore assertFalse(fBoolean(false)) @@ -111,6 +114,9 @@ class ReflectiveCallTest { } @Test def should_work_with_equality_operators_on_primitive_types(): Unit = { + assumeFalse("Reflective call to == and != is broken on the JVM", + Platform.executingInJVM) + def fNum(obj: Any { def ==(x: Int): Boolean }): Boolean = obj == 5 assertTrue(fNum(5.toByte)) assertFalse(fNum(6.toByte)) @@ -126,6 +132,7 @@ class ReflectiveCallTest { assertFalse(fNum(5.6f)) assertTrue(fNum(5.0)) assertFalse(fNum(7.9)) + def fBool(obj: Any { def ==(x: Boolean): Boolean }): Boolean = obj == false // scalastyle:ignore assertFalse(fBool(true)) assertTrue(fBool(false)) @@ -145,10 +152,10 @@ class ReflectiveCallTest { assertTrue(fNumN(5.6f)) assertFalse(fNumN(5.0)) assertTrue(fNumN(7.9)) + def fBoolN(obj: Any { def !=(x: Boolean): Boolean }): Boolean = obj != false // scalastyle:ignore assertTrue(fBoolN(true)) assertFalse(fBoolN(false)) - } @Test def should_work_with_Arrays(): Unit = { @@ -234,10 +241,10 @@ class ReflectiveCallTest { val sub = new Sub val x: { def foo(x: Option[Int]): Any } = sub - assertEquals(1, x.foo(Some(1)).asInstanceOf[js.Any]) // here is the "bug" + assertEquals(1, x.foo(Some(1))) // here is the "bug" val y: { def foo(x: Option[String]): Any } = sub - assertEquals(1, y.foo(Some("hello")).asInstanceOf[js.Any]) + assertEquals(1, y.foo(Some("hello"))) } @Test def should_work_on_java_lang_Object_notify_notifyAll_issue_303(): Unit = { @@ -253,7 +260,10 @@ class ReflectiveCallTest { class A - assertEquals(1, objNotifyTest(new A())) + val a = new A() + a.synchronized { + assertEquals(1, objNotifyTest(a)) + } } @Test def should_work_on_java_lang_Object_clone_issue_303(): Unit = { @@ -271,24 +281,71 @@ class ReflectiveCallTest { assertEquals(1, bClone.x) } - @Test def should_work_on_scala_AnyRef_eq_ne_issue_303(): Unit = { - type ObjEqLike = Any { + @Test def should_not_work_on_scala_AnyRef_eq_ne_synchronized_issue_2709(): Unit = { + // Bug compatible with Scala/JVM + + assumeFalse( + "GCC is a bit too eager in its optimizations in this error case", + Platform.isInFullOpt) + + type ObjWithAnyRefPrimitives = Any { def eq(that: AnyRef): Boolean def ne(that: AnyRef): Boolean + def synchronized[T](f: T): Any + } + + def objEqTest(obj: ObjWithAnyRefPrimitives, that: AnyRef): Boolean = + obj eq that + def objNeTest(obj: ObjWithAnyRefPrimitives, that: AnyRef): Boolean = + obj ne that + def objSynchronizedTest(obj: ObjWithAnyRefPrimitives, f: String): Any = + obj.synchronized(f) + + /* The name of the expected exception class. We cannot use + * classOf[js.JavaScriptException] as that would not compile on the JVM. + */ + val expectedClassName = + if (Platform.executingInJVM) "java.lang.NoSuchMethodException" + else "scala.scalajs.js.JavaScriptException" + + def testWith(body: => Unit): Unit = { + val exception = expectThrows(classOf[Throwable], body) + assertEquals(expectedClassName, exception.getClass.getName) } - def objEqTest(obj: ObjEqLike, that: AnyRef): Boolean = obj eq that - def objNeTest(obj: ObjEqLike, that: AnyRef): Boolean = obj ne that class A val a1 = new A val a2 = new A - assertFalse(objEqTest(a1,a2)) - assertTrue(objEqTest(a1,a1)) + testWith(objEqTest(a1, a2)) + testWith(objNeTest(a1, a2)) + testWith(objSynchronizedTest(a1, "hello")) + } + + @Test def should_work_on_AnyVal_eq_ne_synchronized_issue_2709(): Unit = { + type ObjWithAnyRefPrimitives = Any { + def eq(that: AnyRef): Boolean + def ne(that: AnyRef): Boolean + def synchronized[T](f: T): Any + } + + def objEqTest(obj: ObjWithAnyRefPrimitives, that: AnyRef): Boolean = + obj eq that + def objNeTest(obj: ObjWithAnyRefPrimitives, that: AnyRef): Boolean = + obj ne that + def objSynchronizedTest(obj: ObjWithAnyRefPrimitives, f: String): Any = + obj.synchronized(f) - assertTrue(objNeTest(a1,a2)) - assertFalse(objNeTest(a1,a1)) + val a = new AnyValWithAnyRefPrimitiveMethods(5) + + assertFalse(objEqTest(a, 5: Integer)) + assertTrue(objEqTest(a, 6: Integer)) + + assertTrue(objNeTest(a, 5: Integer)) + assertFalse(objNeTest(a, 6: Integer)) + + assertEquals("hellothere", objSynchronizedTest(a, "hello")) } @Test def should_work_on_java_lang_Float_Double_isNaN_isInfinite(): Unit = { @@ -349,3 +406,11 @@ class ReflectiveCallTest { test(new Foo) } } + +object ReflectiveCallTest { + class AnyValWithAnyRefPrimitiveMethods(val x: Int) extends AnyVal { + def eq(that: AnyRef): Boolean = (x + 1) == that + def ne(that: AnyRef): Boolean = (x + 1) != that + def synchronized[T](f: T): Any = f + "there" + } +} From dfd2799d710c5ddd0221aaca54af1041c044775f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 9 Jan 2017 13:11:09 +0100 Subject: [PATCH 0092/2665] Export fields at the top-level with `@JSExportTopLevel`. This commit implements the third part of the proposal #2702, i.e., exporting fields at the top-level. The `@JSExportTopLevel` annotation can now be used on `val`s and `var`s in addition to methods. This causes the specified field to be stored as a static field in the IR (which becomes a top-level var in JS) and exported at the top-level. Field exports are read-only views, as is the case in ECMAScript 2015 modules, so JS code cannot modify exported vars, but can observe changes to it done by Scala code. --- .../org/scalajs/core/compiler/GenJSCode.scala | 84 +++++--- .../scalajs/core/compiler/GenJSExports.scala | 30 +-- .../core/compiler/JSGlobalAddons.scala | 11 +- .../scalajs/core/compiler/PrepJSExports.scala | 34 +++- .../core/compiler/test/JSExportTest.scala | 79 +++++++- .../scala/org/scalajs/core/ir/Hashers.scala | 6 + .../org/scalajs/core/ir/InfoSerializers.scala | 39 ++-- .../scala/org/scalajs/core/ir/Infos.scala | 179 +++++++++++++----- .../scala/org/scalajs/core/ir/Printers.scala | 12 ++ .../org/scalajs/core/ir/Serializers.scala | 17 +- .../main/scala/org/scalajs/core/ir/Tags.scala | 2 + .../org/scalajs/core/ir/Transformers.scala | 4 +- .../org/scalajs/core/ir/Traversers.scala | 4 +- .../scala/org/scalajs/core/ir/Trees.scala | 10 +- .../org/scalajs/core/ir/PrintersTest.scala | 13 ++ .../scalajs/jsenv/rhino/ScalaJSCoreLib.scala | 1 + project/BinaryIncompatibilities.scala | 18 +- .../testsuite/jsinterop/ExportsTest.scala | 102 ++++++++++ tools/scalajsenv.js | 1 + .../core/tools/linker/LinkedClass.scala | 2 + .../core/tools/linker/analyzer/Analyzer.scala | 71 ++++++- .../linker/backend/emitter/Emitter.scala | 54 +++++- .../linker/backend/emitter/JSDesugaring.scala | 16 +- .../backend/emitter/ScalaJSClassEmitter.scala | 91 ++++++++- .../core/tools/linker/checker/IRChecker.scala | 61 +++++- .../tools/linker/frontend/BaseLinker.scala | 3 + .../frontend/optimizer/OptimizerCore.scala | 11 +- 27 files changed, 787 insertions(+), 168 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index ce35b312e1..b7dc48102a 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -420,7 +420,14 @@ abstract class GenJSCode extends plugins.PluginComponent val topLevelExports = genTopLevelExports(sym) - memberExports ++ exportedConstructorsOrAccessors ++ topLevelExports + val needsStaticInitializer = + topLevelExports.exists(_.isInstanceOf[js.TopLevelFieldExportDef]) + val optStaticInitializer = + if (!needsStaticInitializer) Nil + else genStaticInitializerLoadingModule(sym) :: Nil + + (memberExports ++ exportedConstructorsOrAccessors ++ topLevelExports ++ + optStaticInitializer) } // Hashed definitions of the class @@ -513,13 +520,8 @@ abstract class GenJSCode extends plugins.PluginComponent genStaticExports(companionModuleClass) } if (exports.exists(_.isInstanceOf[js.FieldDef])) { - val staticInitializer = js.MethodDef( - static = true, - js.Ident(ir.Definitions.StaticInitializerName), - Nil, - jstpe.NoType, - Some(genLoadModule(companionModuleClass)))( - OptimizerHints.empty, None) + val staticInitializer = + genStaticInitializerLoadingModule(companionModuleClass) exports :+ staticInitializer } else { exports @@ -852,26 +854,35 @@ abstract class GenJSCode extends plugins.PluginComponent assert(currentClassSym.get == classSym, "genClassFields called with a ClassDef other than the current one") + def isStaticBecauseOfTopLevelExport(f: Symbol): Boolean = + jsInterop.registeredExportsOf(f).head.destination == ExportDestination.TopLevel + // Non-method term members are fields, except for module members. (for { f <- classSym.info.decls if !f.isMethod && f.isTerm && !f.isModule if !f.hasAnnotation(JSOptionalAnnotation) - if !jsInterop.isFieldStatic(f) + static = jsInterop.isFieldStatic(f) + if !static || isStaticBecauseOfTopLevelExport(f) } yield { implicit val pos = f.pos - val mutable = + val mutable = { + static || // static fields must always be mutable suspectFieldMutable(f) || unexpectedMutatedFields.contains(f) + } + val name = if (isExposed(f)) js.StringLiteral(jsNameOf(f)) else encodeFieldSym(f) - val irTpe = - if (!isScalaJSDefinedJSClass(classSym)) toIRType(f.tpe) - else genExposedFieldIRType(f) + val irTpe = { + if (isScalaJSDefinedJSClass(classSym)) genExposedFieldIRType(f) + else if (static) jstpe.AnyType + else toIRType(f.tpe) + } - js.FieldDef(static = false, name, irTpe, mutable) + js.FieldDef(static, name, irTpe, mutable) }).toList } @@ -907,6 +918,19 @@ abstract class GenJSCode extends plugins.PluginComponent } } + // Static initializers ----------------------------------------------------- + + private def genStaticInitializerLoadingModule(sym: Symbol)( + implicit pos: Position): js.MethodDef = { + js.MethodDef( + static = true, + js.Ident(ir.Definitions.StaticInitializerName), + Nil, + jstpe.NoType, + Some(genLoadModule(sym)))( + OptimizerHints.empty, None) + } + // Constructor of a Scala.js-defined JS class ------------------------------ def genJSClassConstructor(classSym: Symbol, @@ -1718,12 +1742,7 @@ abstract class GenJSCode extends plugins.PluginComponent js.JSDotSelect(genQual, encodeFieldSym(sym)) unboxFieldValue(boxed) } else if (jsInterop.isFieldStatic(sym)) { - val exportInfo = jsInterop.staticFieldInfoOf(sym) - assert(exportInfo.destination == ExportDestination.Static) - val companionClass = patchedLinkedClassOfClass(sym.owner) - val boxed = js.JSBracketSelect(genPrimitiveJSClass(companionClass), - js.StringLiteral(exportInfo.jsName)) - unboxFieldValue(boxed) + unboxFieldValue(genSelectStaticFieldAsBoxed(sym)) } else { js.Select(genExpr(qualifier), encodeFieldSym(sym))(toIRType(sym.tpe)) @@ -1808,13 +1827,7 @@ abstract class GenJSCode extends plugins.PluginComponent js.JSDotSelect(genQual, encodeFieldSym(sym)) js.Assign(genLhs, genBoxedRhs) } else if (jsInterop.isFieldStatic(sym)) { - val exportInfo = jsInterop.staticFieldInfoOf(sym) - assert(exportInfo.destination == ExportDestination.Static) - val companionClass = patchedLinkedClassOfClass(sym.owner) - val select = js.JSBracketSelect( - genPrimitiveJSClass(companionClass), - js.StringLiteral(exportInfo.jsName)) - js.Assign(select, genBoxedRhs) + js.Assign(genSelectStaticFieldAsBoxed(sym), genBoxedRhs) } else { js.Assign( js.Select(genQual, encodeFieldSym(sym))(toIRType(sym.tpe)), @@ -1865,6 +1878,23 @@ abstract class GenJSCode extends plugins.PluginComponent } } + private def genSelectStaticFieldAsBoxed(sym: Symbol)( + implicit pos: Position): js.Tree = { + val exportInfos = jsInterop.staticFieldInfoOf(sym) + (exportInfos.head.destination: @unchecked) match { + case ExportDestination.TopLevel => + val cls = jstpe.ClassType(encodeClassFullName(sym.owner)) + js.SelectStatic(cls, encodeFieldSym(sym))(jstpe.AnyType) + + case ExportDestination.Static => + val exportInfo = exportInfos.head + val companionClass = patchedLinkedClassOfClass(sym.owner) + js.JSBracketSelect( + genPrimitiveJSClass(companionClass), + js.StringLiteral(exportInfo.jsName)) + } + } + /** Gen JS code for LabelDef * The only LabelDefs that can reach here are the desugaring of * while and do..while loops. All other LabelDefs (for tail calls or diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index c837e492c0..82aa1ff7a8 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -120,9 +120,15 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } } - def genTopLevelExports(classSym: Symbol): List[js.TopLevelExportDef] = { - for (m <- genTopLevelOrStaticExports(classSym, ExportDestination.TopLevel)) - yield js.TopLevelExportDef(m)(m.pos) + def genTopLevelExports(classSym: Symbol): List[js.Tree] = { + for { + m <- genTopLevelOrStaticExports(classSym, ExportDestination.TopLevel) + } yield { + m match { + case m: js.TopLevelFieldExportDef => m + case _ => js.TopLevelExportDef(m)(m.pos) + } + } } def genStaticExports(classSym: Symbol): List[js.Tree] = @@ -156,23 +162,25 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } private def genTopLevelOrStaticFieldExports(classSym: Symbol, - destination: ExportDestination): List[(js.FieldDef, String, Position)] = { + destination: ExportDestination): List[(js.Tree, String, Position)] = { (for { fieldSym <- classSym.info.members if !fieldSym.isMethod && fieldSym.isTerm && !fieldSym.isModule export <- jsInterop.registeredExportsOf(fieldSym) if export.destination == destination } yield { - // in fact, top-level field exports do not exist yet - assert(export.destination == ExportDestination.Static) - implicit val pos = fieldSym.pos - val mutable = true // static fields must always be mutable - val name = js.StringLiteral(export.jsName) - val irTpe = genExposedFieldIRType(fieldSym) + val tree = if (destination == ExportDestination.Static) { + val mutable = true // static fields must always be mutable + val name = js.StringLiteral(export.jsName) + val irTpe = genExposedFieldIRType(fieldSym) + js.FieldDef(static = true, name, irTpe, mutable) + } else { + js.TopLevelFieldExportDef(export.jsName, encodeFieldSym(fieldSym)) + } - (js.FieldDef(static = true, name, irTpe, mutable), export.jsName, pos) + (tree, export.jsName, pos) }).toList } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala index 1cfa878d33..993c4ad85c 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala @@ -149,11 +149,16 @@ trait JSGlobalAddons extends JSDefinitions registeredExportsOf(sym).nonEmpty } - /** The only export info of a static field. + /** The export info of a static field. + * * Requires `isFieldStatic(sym)`. + * + * The result is non-empty. If it contains an `ExportInfo` with + * `isStatic = true`, then it is the only element in the list. Otherwise, + * all elements have `isTopLevel = true`. */ - def staticFieldInfoOf(sym: Symbol): ExportInfo = - registeredExportsOf(sym).head + def staticFieldInfoOf(sym: Symbol): List[ExportInfo] = + registeredExportsOf(sym) /** has this symbol to be translated into a JS bracket access (JS to Scala) */ def isJSBracketAccess(sym: Symbol): Boolean = diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala index 87b675de90..9de0c1d4f4 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala @@ -335,7 +335,7 @@ trait PrepJSExports { this: PrepJSInterop => } case ExportDestination.TopLevel => - if (jsInterop.isJSProperty(sym)) { + if (!sym.isAccessor && jsInterop.isJSProperty(sym)) { reporter.error(annot.pos, "You may not export a getter or a setter to the top level") } @@ -400,20 +400,34 @@ trait PrepJSExports { this: PrepJSInterop => * accessors. We use the same code paths hereabove to uniformly perform * relevant checks, but at the end of the day, we have to throw away the * ExportInfo. - * However, we must make sure that no field is exported *twice* as static. + * However, we must make sure that no field is exported *twice* as static, + * nor both as static and as top-level (it is possible to export a field + * several times as top-level, though). */ - val (staticExportInfos, actualExportInfos) = - allExportInfos.partition(_.destination == ExportDestination.Static) + val (topLevelAndStaticExportInfos, actualExportInfos) = + allExportInfos.partition(_.destination != ExportDestination.Normal) if (sym.isGetter) { - val duplicates = staticExportInfos.drop(1) // no-op if isEmpty - for (duplicate <- duplicates) { - reporter.error(duplicate.pos, - "Fields (val or var) cannot be exported as static more than " + - "once") + topLevelAndStaticExportInfos.find { + _.destination == ExportDestination.Static + }.foreach { firstStatic => + for { + duplicate <- topLevelAndStaticExportInfos + if duplicate ne firstStatic + } { + if (duplicate.destination == ExportDestination.Static) { + reporter.error(duplicate.pos, + "Fields (val or var) cannot be exported as static more " + + "than once") + } else { + reporter.error(duplicate.pos, + "Fields (val or var) cannot be exported both as static " + + "and at the top-level") + } + } } - jsInterop.registerForExport(sym.accessed, staticExportInfos) + jsInterop.registerForExport(sym.accessed, topLevelAndStaticExportInfos) } actualExportInfos diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index 4a881adfc3..6cf34a9b6e 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -1163,11 +1163,11 @@ class JSExportTest extends DirectTest with TestHelpers { } @Test - def noExportTopLevelVal: Unit = { + def noExportTopLevelSetter: Unit = { """ object A { @JSExportTopLevel("foo") - val a: Int = 1 + def a_=(x: Int): Unit = () } """ hasErrors """ @@ -1178,30 +1178,51 @@ class JSExportTest extends DirectTest with TestHelpers { } @Test - def noExportTopLevelVar: Unit = { + def noExportTopLevelFieldsWithSameName: Unit = { """ object A { @JSExportTopLevel("foo") - var a: Int = 1 + val a: Int = 1 + + @JSExportTopLevel("foo") + var b: Int = 1 } """ hasErrors """ - |newSource1.scala:4: error: You may not export a getter or a setter to the top level - | @JSExportTopLevel("foo") - | ^ + |newSource1.scala:5: error: Duplicate top-level export with name 'foo': a field may not share its exported name with another field or method + | val a: Int = 1 + | ^ """ } @Test - def noExportTopLevelSetter: Unit = { + def noExportTopLevelFieldsAndMethodsWithSameName: Unit = { """ object A { @JSExportTopLevel("foo") - def a_=(x: Int): Unit = () + val a: Int = 1 + + @JSExportTopLevel("foo") + def b(x: Int): Int = x + 1 } """ hasErrors """ - |newSource1.scala:4: error: You may not export a getter or a setter to the top level + |newSource1.scala:7: error: Duplicate top-level export with name 'foo': a field may not share its exported name with another field or method + | @JSExportTopLevel("foo") + | ^ + """ + + """ + object A { + @JSExportTopLevel("foo") + def a(x: Int): Int = x + 1 + + @JSExportTopLevel("foo") + val b: Int = 1 + } + """ hasErrors + """ + |newSource1.scala:4: error: Duplicate top-level export with name 'foo': a field may not share its exported name with another field or method | @JSExportTopLevel("foo") | ^ """ @@ -1361,6 +1382,44 @@ class JSExportTest extends DirectTest with TestHelpers { """ } + @Test + def noExportValAsStaticAndTopLevel: Unit = { + """ + @ScalaJSDefined + class StaticContainer extends js.Object + + object StaticContainer { + @JSExportStatic + @JSExportTopLevel("foo") + val a: Int = 1 + } + """ hasErrors + """ + |newSource1.scala:8: error: Fields (val or var) cannot be exported both as static and at the top-level + | @JSExportTopLevel("foo") + | ^ + """ + } + + @Test + def noExportVarAsStaticAndTopLevel: Unit = { + """ + @ScalaJSDefined + class StaticContainer extends js.Object + + object StaticContainer { + @JSExportStatic + @JSExportTopLevel("foo") + var a: Int = 1 + } + """ hasErrors + """ + |newSource1.scala:8: error: Fields (val or var) cannot be exported both as static and at the top-level + | @JSExportTopLevel("foo") + | ^ + """ + } + @Test def noExportStaticGetter: Unit = { """ diff --git a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala index 9436521b75..8090db885e 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala @@ -206,6 +206,12 @@ object Hashers { mixIdent(item) mixType(tree.tpe) + case SelectStatic(cls, item) => + mixTag(TagSelectStatic) + mixType(cls) + mixIdent(item) + mixType(tree.tpe) + case Apply(receiver, method, args) => mixTag(TagApply) mixTree(receiver) diff --git a/ir/src/main/scala/org/scalajs/core/ir/InfoSerializers.scala b/ir/src/main/scala/org/scalajs/core/ir/InfoSerializers.scala index 6f007e9049..9d1d7a752d 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/InfoSerializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/InfoSerializers.scala @@ -62,19 +62,22 @@ object InfoSerializers { def writeMethodInfo(methodInfo: MethodInfo): Unit = { import methodInfo._ + + def writePerClassStrings(m: Map[String, List[String]]): Unit = { + writeSeq(m.toSeq) { + case (cls, items) => s.writeUTF(cls); writeStrings(items) + } + } + s.writeUTF(encodedName) s.writeBoolean(isStatic) s.writeBoolean(isAbstract) s.writeBoolean(isExported) - writeSeq(methodsCalled.toSeq) { - case (cls, callees) => s.writeUTF(cls); writeStrings(callees) - } - writeSeq(methodsCalledStatically.toSeq) { - case (cls, callees) => s.writeUTF(cls); writeStrings(callees) - } - writeSeq(staticMethodsCalled.toSeq) { - case (cls, callees) => s.writeUTF(cls); writeStrings(callees) - } + writePerClassStrings(staticFieldsRead) + writePerClassStrings(staticFieldsWritten) + writePerClassStrings(methodsCalled) + writePerClassStrings(methodsCalledStatically) + writePerClassStrings(staticMethodsCalled) writeStrings(instantiatedClasses) writeStrings(accessedModules) writeStrings(usedInstanceTests) @@ -103,6 +106,8 @@ object InfoSerializers { val useHacks065 = Set("0.6.0", "0.6.3", "0.6.4", "0.6.5").contains(version) + val useHacks0614 = + useHacks065 || Set("0.6.6", "0.6.8", "0.6.13", "0.6.14").contains(version) val encodedName = readUTF() val isExported = readBoolean() @@ -112,18 +117,28 @@ object InfoSerializers { val interfaces = readList(readUTF()) def readMethod(): MethodInfo = { + def readPerClassStrings(): Map[String, List[String]] = + readList(readUTF() -> readStrings()).toMap + val encodedName = readUTF() val isStatic = readBoolean() val isAbstract = readBoolean() val isExported = readBoolean() - val methodsCalled = readList(readUTF() -> readStrings()).toMap - val methodsCalledStatically = readList(readUTF() -> readStrings()).toMap - val staticMethodsCalled = readList(readUTF() -> readStrings()).toMap + val staticFieldsRead = + if (useHacks0614) Map.empty[String, List[String]] + else readPerClassStrings() + val staticFieldsWritten = + if (useHacks0614) Map.empty[String, List[String]] + else readPerClassStrings() + val methodsCalled = readPerClassStrings() + val methodsCalledStatically = readPerClassStrings() + val staticMethodsCalled = readPerClassStrings() val instantiatedClasses = readStrings() val accessedModules = readStrings() val usedInstanceTests = readStrings() val accessedClassData = readStrings() MethodInfo(encodedName, isStatic, isAbstract, isExported, + staticFieldsRead, staticFieldsWritten, methodsCalled, methodsCalledStatically, staticMethodsCalled, instantiatedClasses, accessedModules, usedInstanceTests, accessedClassData) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala index aab909bec7..4c76ed38d7 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala @@ -44,6 +44,8 @@ object Infos { val isStatic: Boolean, val isAbstract: Boolean, val isExported: Boolean, + val staticFieldsRead: Map[String, List[String]], + val staticFieldsWritten: Map[String, List[String]], val methodsCalled: Map[String, List[String]], val methodsCalledStatically: Map[String, List[String]], val staticMethodsCalled: Map[String, List[String]], @@ -57,6 +59,8 @@ object Infos { ) object MethodInfo { + @deprecated("Use the overload with all the fields and no defaults", + "0.6.15") def apply( encodedName: String, isStatic: Boolean = false, @@ -69,7 +73,29 @@ object Infos { accessedModules: List[String] = Nil, usedInstanceTests: List[String] = Nil, accessedClassData: List[String] = Nil): MethodInfo = { + apply(encodedName, isStatic, isAbstract, isExported, + staticFieldsRead = Map.empty, staticFieldsWritten = Map.empty, + methodsCalled, methodsCalledStatically, staticMethodsCalled, + instantiatedClasses, accessedModules, usedInstanceTests, + accessedClassData) + } + + def apply( + encodedName: String, + isStatic: Boolean, + isAbstract: Boolean, + isExported: Boolean, + staticFieldsRead: Map[String, List[String]], + staticFieldsWritten: Map[String, List[String]], + methodsCalled: Map[String, List[String]], + methodsCalledStatically: Map[String, List[String]], + staticMethodsCalled: Map[String, List[String]], + instantiatedClasses: List[String], + accessedModules: List[String], + usedInstanceTests: List[String], + accessedClassData: List[String]): MethodInfo = { new MethodInfo(encodedName, isStatic, isAbstract, isExported, + staticFieldsRead, staticFieldsWritten, methodsCalled, methodsCalledStatically, staticMethodsCalled, instantiatedClasses, accessedModules, usedInstanceTests, accessedClassData) @@ -131,6 +157,8 @@ object Infos { private var isAbstract: Boolean = false private var isExported: Boolean = false + private val staticFieldsRead = mutable.Map.empty[String, mutable.Set[String]] + private val staticFieldsWritten = mutable.Map.empty[String, mutable.Set[String]] private val methodsCalled = mutable.Map.empty[String, mutable.Set[String]] private val methodsCalledStatically = mutable.Map.empty[String, mutable.Set[String]] private val staticMethodsCalled = mutable.Map.empty[String, mutable.Set[String]] @@ -159,6 +187,16 @@ object Infos { this } + def addStaticFieldRead(cls: String, field: String): this.type = { + staticFieldsRead.getOrElseUpdate(cls, mutable.Set.empty) += field + this + } + + def addStaticFieldWritten(cls: String, field: String): this.type = { + staticFieldsWritten.getOrElseUpdate(cls, mutable.Set.empty) += field + this + } + def addMethodCalled(receiverTpe: Type, method: String): this.type = { receiverTpe match { case ClassType(cls) => addMethodCalled(cls, method) @@ -233,14 +271,21 @@ object Infos { } def result(): MethodInfo = { + def toMapOfLists( + m: mutable.Map[String, mutable.Set[String]]): Map[String, List[String]] = { + m.mapValues(_.toList).toMap + } + MethodInfo( encodedName = encodedName, isStatic = isStatic, isAbstract = isAbstract, isExported = isExported, - methodsCalled = methodsCalled.toMap.mapValues(_.toList), - methodsCalledStatically = methodsCalledStatically.toMap.mapValues(_.toList), - staticMethodsCalled = staticMethodsCalled.toMap.mapValues(_.toList), + staticFieldsRead = toMapOfLists(staticFieldsRead), + staticFieldsWritten = toMapOfLists(staticFieldsWritten), + methodsCalled = toMapOfLists(methodsCalled), + methodsCalledStatically = toMapOfLists(methodsCalledStatically), + staticMethodsCalled = toMapOfLists(staticMethodsCalled), instantiatedClasses = instantiatedClasses.toList, accessedModules = accessedModules.toList, usedInstanceTests = usedInstanceTests.toList, @@ -259,6 +304,7 @@ object Infos { var exportedConstructors: List[ConstructorExportDef] = Nil var topLevelExports: List[TopLevelExportDef] = Nil + var topLevelFieldExports: List[TopLevelFieldExportDef] = Nil classDef.defs foreach { case methodDef: MethodDef => @@ -273,12 +319,15 @@ object Infos { case topLevelExport: TopLevelExportDef => builder.setIsExported(true) topLevelExports ::= topLevelExport + case topLevelFieldExport: TopLevelFieldExportDef => + builder.setIsExported(true) + topLevelFieldExports ::= topLevelFieldExport case _ => } if (exportedConstructors.nonEmpty || topLevelExports.nonEmpty) { - builder.addMethod( - generateClassExportsInfo(exportedConstructors, topLevelExports)) + builder.addMethod(generateClassExportsInfo(classDef.name.name, + exportedConstructors, topLevelExports, topLevelFieldExports)) } builder.result() @@ -300,10 +349,22 @@ object Infos { } /** Generates the [[MethodInfo]] for the class exports. */ + @deprecated( + "Use the overload with an enclosingClass and topLevelFieldExports.", + "0.6.15") def generateClassExportsInfo(constructorDefs: List[ConstructorExportDef], topLevelExports: List[TopLevelExportDef]): MethodInfo = { - new GenInfoTraverser().generateClassExportsInfo(constructorDefs, - topLevelExports) + // enclosingClass won't be used when topLevelFieldExports is empty + generateClassExportsInfo("", constructorDefs, topLevelExports, Nil) + } + + /** Generates the [[MethodInfo]] for the class exports. */ + def generateClassExportsInfo(enclosingClass: String, + constructorDefs: List[ConstructorExportDef], + topLevelExports: List[TopLevelExportDef], + topLevelFieldExports: List[TopLevelFieldExportDef]): MethodInfo = { + new GenInfoTraverser().generateClassExportsInfo(enclosingClass, + constructorDefs, topLevelExports, topLevelFieldExports) } private final class GenInfoTraverser extends Traversers.Traverser { @@ -334,8 +395,10 @@ object Infos { builder.result() } - def generateClassExportsInfo(constructorDefs: List[ConstructorExportDef], - topLevelExports: List[TopLevelExportDef]): MethodInfo = { + def generateClassExportsInfo(enclosingClass: String, + constructorDefs: List[ConstructorExportDef], + topLevelExports: List[TopLevelExportDef], + topLevelFieldExports: List[TopLevelFieldExportDef]): MethodInfo = { builder .setEncodedName(ClassExportsName) .setIsExported(true) @@ -346,54 +409,74 @@ object Infos { for (topLevelExport <- topLevelExports) traverse(topLevelExport.member) + for (topLevelFieldExport <- topLevelFieldExports) { + val field = topLevelFieldExport.field.name + builder.addStaticFieldRead(enclosingClass, field) + builder.addStaticFieldWritten(enclosingClass, field) + } + builder.result() } override def traverse(tree: Tree): Unit = { tree match { - case New(ClassType(cls), ctor, _) => - builder.addInstantiatedClass(cls, ctor.name) - - case Apply(receiver, Ident(method, _), _) => - builder.addMethodCalled(receiver.tpe, method) - case ApplyStatically(_, ClassType(cls), method, _) => - builder.addMethodCalledStatically(cls, method.name) - case ApplyStatic(ClassType(cls), method, _) => - builder.addStaticMethodCalled(cls, method.name) - - case LoadModule(ClassType(cls)) => - builder.addAccessedModule(cls) - - case IsInstanceOf(_, tpe) => - builder.addUsedInstanceTest(tpe) - case AsInstanceOf(_, tpe) => - builder.addUsedInstanceTest(tpe) - - case NewArray(tpe, _) => - builder.addAccessedClassData(tpe) - case ArrayValue(tpe, _) => - builder.addAccessedClassData(tpe) - case ClassOf(cls) => - builder.addAccessedClassData(cls) - - case LoadJSConstructor(cls) => - builder.addInstantiatedClass(cls.className) - - case LoadJSModule(ClassType(cls)) => - builder.addAccessedModule(cls) - - /* We explicitly catch UndefinedParam here to make sure, we do not - * emit it in the compiler. This does not entirely belong here, as it - * supports GenJSCode, but it is not wrong to throw an exception. + /* Do not call super.traverse() so that the field is not also marked as + * read. */ - case UndefinedParam() => - throw new InvalidIRException(tree, - "Found UndefinedParam while building infos") + case Assign(SelectStatic(ClassType(cls), Ident(field, _)), rhs) => + builder.addStaticFieldWritten(cls, field) + traverse(rhs) + // In all other cases, we'll have to call super.traverse() case _ => + tree match { + case New(ClassType(cls), ctor, _) => + builder.addInstantiatedClass(cls, ctor.name) + + case SelectStatic(ClassType(cls), Ident(field, _)) => + builder.addStaticFieldRead(cls, field) + + case Apply(receiver, Ident(method, _), _) => + builder.addMethodCalled(receiver.tpe, method) + case ApplyStatically(_, ClassType(cls), method, _) => + builder.addMethodCalledStatically(cls, method.name) + case ApplyStatic(ClassType(cls), method, _) => + builder.addStaticMethodCalled(cls, method.name) + + case LoadModule(ClassType(cls)) => + builder.addAccessedModule(cls) + + case IsInstanceOf(_, tpe) => + builder.addUsedInstanceTest(tpe) + case AsInstanceOf(_, tpe) => + builder.addUsedInstanceTest(tpe) + + case NewArray(tpe, _) => + builder.addAccessedClassData(tpe) + case ArrayValue(tpe, _) => + builder.addAccessedClassData(tpe) + case ClassOf(cls) => + builder.addAccessedClassData(cls) + + case LoadJSConstructor(cls) => + builder.addInstantiatedClass(cls.className) + + case LoadJSModule(ClassType(cls)) => + builder.addAccessedModule(cls) + + /* We explicitly catch UndefinedParam here to make sure, we do not + * emit it in the compiler. This does not entirely belong here, as + * it supports GenJSCode, but it is not wrong to throw an exception. + */ + case UndefinedParam() => + throw new InvalidIRException(tree, + "Found UndefinedParam while building infos") + + case _ => + } + + super.traverse(tree) } - - super.traverse(tree) } } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index 693115de3e..b8ab1f4298 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -299,6 +299,11 @@ object Printers { print('.') print(item) + case SelectStatic(cls, item) => + print(cls) + print('.') + print(item) + case Apply(receiver, method, args) => print(receiver) print(".") @@ -862,6 +867,13 @@ object Printers { print("export top ") print(member) + case TopLevelFieldExportDef(fullName, field) => + print("export top static field ") + print(field) + print(" as \"") + printEscapeJS(fullName, out) + print('\"') + case _ => print(s"") } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index c1007759ec..a1a69c1a97 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -198,6 +198,11 @@ object Serializers { writeTree(qualifier); writeIdent(item) writeType(tree.tpe) + case SelectStatic(cls, item) => + writeByte(TagSelectStatic) + writeClassType(cls); writeIdent(item) + writeType(tree.tpe) + case Apply(receiver, method, args) => writeByte(TagApply) writeTree(receiver); writeIdent(method); writeTrees(args) @@ -463,6 +468,10 @@ object Serializers { case TopLevelExportDef(member) => writeByte(TagTopLevelExportDef) writeTree(member) + + case TopLevelFieldExportDef(fullName, field) => + writeByte(TagTopLevelFieldExportDef) + writeString(fullName); writeIdent(field) } if (UseDebugMagic) writeInt(DebugMagic) @@ -723,6 +732,7 @@ object Serializers { case TagLoadModule => LoadModule(readClassType()) case TagStoreModule => StoreModule(readClassType(), readTree()) case TagSelect => Select(readTree(), readIdent())(readType()) + case TagSelectStatic => SelectStatic(readClassType(), readIdent())(readType()) case TagApply => Apply(readTree(), readIdent(), readTrees())(readType()) case TagApplyStatically => val result1 = @@ -886,9 +896,10 @@ object Serializers { result } - case TagJSClassExportDef => JSClassExportDef(readString()) - case TagModuleExportDef => ModuleExportDef(readString()) - case TagTopLevelExportDef => TopLevelExportDef(readTree()) + case TagJSClassExportDef => JSClassExportDef(readString()) + case TagModuleExportDef => ModuleExportDef(readString()) + case TagTopLevelExportDef => TopLevelExportDef(readTree()) + case TagTopLevelFieldExportDef => TopLevelFieldExportDef(readString(), readIdent()) } if (UseDebugMagic) { val magic = readInt() diff --git a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala index 75839bdf03..251775f0f9 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala @@ -105,6 +105,8 @@ private[ir] object Tags { final val TagTryCatch = TagJSClassExportDef + 1 final val TagTryFinally = TagTryCatch + 1 final val TagTopLevelExportDef = TagTryFinally + 1 + final val TagSelectStatic = TagTopLevelExportDef + 1 + final val TagTopLevelFieldExportDef = TagSelectStatic + 1 // Tags for Types diff --git a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala index 731fa96f5a..4cc49fd2c3 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala @@ -187,7 +187,7 @@ object Transformers { // Trees that need not be transformed - case _:Skip | _:Continue | _:Debugger | _:LoadModule | + case _:Skip | _:Continue | _:Debugger | _:LoadModule | _:SelectStatic | _:LoadJSConstructor | _:LoadJSModule | _:JSLinkingInfo | _:Literal | _:UndefinedParam | _:VarRef | _:This => tree @@ -228,7 +228,7 @@ object Transformers { case ConstructorExportDef(fullName, args, body) => ConstructorExportDef(fullName, args, transformStat(body)) - case _:JSClassExportDef | _:ModuleExportDef => + case _:JSClassExportDef | _:ModuleExportDef | _:TopLevelFieldExportDef => tree case TopLevelExportDef(member) => diff --git a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala index aa1bed887d..e93ea7b021 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala @@ -209,10 +209,10 @@ object Traversers { // Trees that need not be traversed - case _:Skip | _:Continue | _:Debugger | _:LoadModule | + case _:Skip | _:Continue | _:Debugger | _:LoadModule | _:SelectStatic | _:LoadJSConstructor | _:LoadJSModule | _:JSLinkingInfo | _:Literal | _:UndefinedParam | _:VarRef | _:This | _:FieldDef | - _:JSClassExportDef | _:ModuleExportDef => + _:JSClassExportDef | _:ModuleExportDef | _:TopLevelFieldExportDef => case _ => sys.error(s"Invalid tree in traverse() of class ${tree.getClass}") diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 40cb719dcc..52dd9742f1 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -135,7 +135,7 @@ object Trees { case class Assign(lhs: Tree, rhs: Tree)( implicit val pos: Position) extends Tree { require(lhs match { - case _:VarRef | _:Select | _:ArraySelect | + case _:VarRef | _:Select | _:SelectStatic | _:ArraySelect | _:JSDotSelect | _:JSBracketSelect | _:JSSuperBracketSelect => true case _ => false }, s"Invalid lhs for Assign: $lhs") @@ -216,6 +216,9 @@ object Trees { case class Select(qualifier: Tree, item: Ident)(val tpe: Type)( implicit val pos: Position) extends Tree + case class SelectStatic(cls: ClassType, item: Ident)(val tpe: Type)( + implicit val pos: Position) extends Tree + /** Apply an instance method with dynamic dispatch (the default). */ case class Apply(receiver: Tree, method: Ident, args: List[Tree])( val tpe: Type)(implicit val pos: Position) extends Tree @@ -816,6 +819,11 @@ object Trees { val tpe = NoType } + case class TopLevelFieldExportDef(fullName: String, field: Ident)( + implicit val pos: Position) extends Tree { + val tpe = NoType + } + final class OptimizerHints(val bits: Int) extends AnyVal { import OptimizerHints._ diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala index d0df1eb29b..fbf08e4f9c 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala @@ -296,6 +296,11 @@ class PrintersTest { assertPrintEquals("x.f$1", Select(ref("x", "Ltest_Test"), "f$1")(IntType)) } + @Test def printSelectStatic(): Unit = { + assertPrintEquals("Ltest_Test.f$1", + SelectStatic("Ltest_Test", "f$1")(IntType)) + } + @Test def printApply(): Unit = { assertPrintEquals("x.m__V()", Apply(ref("x", "Ltest_Test"), "m__V", Nil)(NoType)) @@ -1072,4 +1077,12 @@ class PrintersTest { List(ParamDef("x", AnyType, mutable = false, rest = false)), AnyType, Some(i(5)))(NoOptHints, None))) } + + @Test def printTopLevelFieldExportDef(): Unit = { + assertPrintEquals( + """ + |export top static field x$1 as "x" + """, + TopLevelFieldExportDef("x", "x$1")) + } } diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala index 03dd4b26fc..07b44ae163 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala @@ -138,6 +138,7 @@ private[rhino] class ScalaJSCoreLib(linkingUnit: LinkingUnit) { Info("c"), Info("h"), Info("s", isStatics = true), + Info("t", isStatics = true), Info("f", isStatics = true), Info("n"), Info("m"), diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 6b03f3323c..f45f4df452 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -15,10 +15,26 @@ object BinaryIncompatibilities { ProblemFilters.exclude[IncompatibleResultTypeProblem]( "org.scalajs.core.ir.Trees#FieldDef.copy$default$2"), ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.core.ir.Trees#FieldDef.copy$default$3") + "org.scalajs.core.ir.Trees#FieldDef.copy$default$3"), + + // private, not an issue + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.ir.Infos#MethodInfo.this"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.ir.Infos#GenInfoTraverser.generateClassExportsInfo") ) val Tools = Seq( + // private, not an issue + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.checker.IRChecker#CheckedField.this"), + + // private, not an issue + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.analyzer.Analyzer.org$scalajs$core$tools$linker$analyzer$Analyzer$$createMissingMethodInfo$default$2"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.analyzer.Analyzer.org$scalajs$core$tools$linker$analyzer$Analyzer$$createMissingMethodInfo$default$3"), + // private[emitter], not an issue ProblemFilters.exclude[MissingMethodProblem]( "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genClass"), diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index 4258a29fba..e5e790bd93 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -1293,6 +1293,69 @@ class ExportsTest { assertEquals("Hello World", jsPackage.toplevel.reachability()) } + // @JSExportTopLevel fields + + @Test def top_level_export_basic_field(): Unit = { + // Initialization + assertEquals(5, jsPackage.toplevel.basicVal) + assertEquals("hello", jsPackage.toplevel.basicVar) + + // Scala modifies var + TopLevelFieldExports.basicVar = "modified" + assertEquals("modified", TopLevelFieldExports.basicVar) + assertEquals("modified", jsPackage.toplevel.basicVar) + + // Reset var + TopLevelFieldExports.basicVar = "hello" + } + + @Test def top_level_export_field_twice(): Unit = { + // Initialization + assertEquals(5, jsPackage.toplevel.valExportedTwice1) + assertEquals("hello", jsPackage.toplevel.varExportedTwice1) + assertEquals("hello", jsPackage.toplevel.varExportedTwice2) + + // Scala modifies var + TopLevelFieldExports.varExportedTwice = "modified" + assertEquals("modified", TopLevelFieldExports.varExportedTwice) + assertEquals("modified", jsPackage.toplevel.varExportedTwice1) + assertEquals("modified", jsPackage.toplevel.varExportedTwice2) + + // Reset var + TopLevelFieldExports.varExportedTwice = "hello" + } + + @Test def top_level_export_write_val_var_causes_typeerror(): Unit = { + assumeFalse("Assuming strict mode, not supported by Rhino", + Platform.executingInRhino) + + assertThrows(classOf[js.JavaScriptException], { + jsPackage.toplevel.basicVal = 54 + }) + + assertThrows(classOf[js.JavaScriptException], { + jsPackage.toplevel.basicVar = 54 + }) + } + + @Test def top_level_export_uninitialized_fields(): Unit = { + assertEquals(0, TopLevelFieldExports.uninitializedVarInt) + assertEquals(null, jsPackage.toplevel.uninitializedVarInt) + + assertEquals(0L, TopLevelFieldExports.uninitializedVarLong) + assertEquals(null, jsPackage.toplevel.uninitializedVarLong) + + assertEquals(null, TopLevelFieldExports.uninitializedVarString) + assertEquals(null, jsPackage.toplevel.uninitializedVarString) + + assertEquals('\0', TopLevelFieldExports.uninitializedVarChar) + assertEquals(null, jsPackage.toplevel.uninitializedVarChar) + } + + @Test def top_level_export_field_is_always_reachable_and_initialized(): Unit = { + assertEquals("Hello World", jsPackage.toplevel.fieldreachability) + } + // @JSExportDescendentObjects @Test def auto_exports_for_objects_extending_a_trait(): Unit = { @@ -1736,3 +1799,42 @@ object TopLevelExportsReachability { @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.reachability") def basic(): String = "Hello " + name } + +object TopLevelFieldExports { + @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.basicVal") + val basicVal: Int = 5 + + @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.basicVar") + var basicVar: String = "hello" + + @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.valExportedTwice1") + @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.valExportedTwice2") + val valExportedTwice: Int = 5 + + @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.varExportedTwice1") + @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.varExportedTwice2") + var varExportedTwice: String = "hello" + + @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.uninitializedVarInt") + var uninitializedVarInt: Int = _ + + @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.uninitializedVarLong") + var uninitializedVarLong: Long = _ + + @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.uninitializedVarString") + var uninitializedVarString: String = _ + + @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.uninitializedVarChar") + var uninitializedVarChar: Char = _ +} + +/* This object and its static initializer are only reachable via the top-level + * export of its field, to make sure the analyzer and the static initiliazer + * behave correctly. + */ +object TopLevelFieldExportsReachability { + private val name = "World" + + @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.fieldreachability") + val greeting = "Hello " + name +} diff --git a/tools/scalajsenv.js b/tools/scalajsenv.js index a59f84752f..2baf06e16a 100644 --- a/tools/scalajsenv.js +++ b/tools/scalajsenv.js @@ -130,6 +130,7 @@ ScalaJS.b = {}; // Scala.js-defined JS class value fields ScalaJS.c = {}; // Scala.js constructors ScalaJS.h = {}; // Inheritable constructors (without initialization code) ScalaJS.s = {}; // Static methods +ScalaJS.t = {}; // Static fields ScalaJS.f = {}; // Default methods ScalaJS.n = {}; // Module instances ScalaJS.m = {}; // Module accessors diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala index 5ca4821a50..7060e798b0 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala @@ -69,6 +69,8 @@ final class LinkedClass( case TopLevelExportDef(MethodDef(_, StringLiteral(name), _, _, _)) => name + + case TopLevelFieldExportDef(name, _) => name } def fullName: String = Definitions.decodeClassName(encodedName) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala index ac62734d78..74a084498e 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala @@ -244,6 +244,7 @@ private final class Analyzer(semantics: Semantics, var isModuleAccessed: Boolean = false var areInstanceTestsUsed: Boolean = false var isDataAccessed: Boolean = false + var isAnyStaticFieldReachable: Boolean = false var instantiatedFrom: List[From] = Nil @@ -254,6 +255,7 @@ private final class Analyzer(semantics: Semantics, isDataAccessed || isAnySubclassInstantiated || isModuleAccessed || + isAnyStaticFieldReachable || isAnyStaticMethodReachable || isAnyDefaultMethodReachable @@ -287,7 +289,7 @@ private final class Analyzer(semantics: Semantics, assert(inherited.nonExistent) inherited } else { - val syntheticInfo = Infos.MethodInfo( + val syntheticInfo = makeSyntheticMethodInfo( encodedName = ctorName, methodsCalledStatically = Map( superClass.encodedName -> List(ctorName))) @@ -403,7 +405,7 @@ private final class Analyzer(semantics: Semantics, val methodName = target.encodedName val targetOwner = target.owner - val syntheticInfo = Infos.MethodInfo( + val syntheticInfo = makeSyntheticMethodInfo( encodedName = methodName, methodsCalledStatically = Map( targetOwner.encodedName -> List(methodName))) @@ -521,7 +523,7 @@ private final class Analyzer(semantics: Semantics, s"Cannot create reflective proxy in non-Scala class $this") val returnsChar = targetName.endsWith("__C") - val syntheticInfo = Infos.MethodInfo( + val syntheticInfo = makeSyntheticMethodInfo( encodedName = proxyName, methodsCalled = Map( this.encodedName -> List(targetName)), @@ -539,7 +541,7 @@ private final class Analyzer(semantics: Semantics, def lookupStaticMethod(methodName: String): MethodInfo = { tryLookupStaticMethod(methodName).getOrElse { - val syntheticData = createMissingMethodInfo(methodName, isStatic = true) + val syntheticData = createMissingStaticMethodInfo(methodName) val m = new MethodInfo(this, syntheticData) m.nonExistent = true staticMethodInfos += methodName -> m @@ -569,6 +571,15 @@ private final class Analyzer(semantics: Semantics, callMethod(methodInfo.encodedName) } } + + /* My static initializer. + * Not technically an export, but also reachable out of thin air. + */ + if (!isJSType) { + staticMethodInfos.get(StaticInitializerName).foreach { + _.reachStatic()(fromAnalyzer) + } + } } def accessModule()(implicit from: From): Unit = { @@ -788,8 +799,23 @@ private final class Analyzer(semantics: Semantics, } /* `for` loops on maps are written with `while` loops to help the JIT - * compiler to inline and stack allocate tupples created by the iterators + * compiler to inline and stack allocate tuples created by the iterators */ + + val staticFieldsReadIterator = data.staticFieldsRead.iterator + while (staticFieldsReadIterator.hasNext) { + val (className, fields) = staticFieldsReadIterator.next() + if (fields.nonEmpty) + lookupClass(className).isAnyStaticFieldReachable = true + } + + val staticFieldsWrittenIterator = data.staticFieldsRead.iterator + while (staticFieldsWrittenIterator.hasNext) { + val (className, fields) = staticFieldsWrittenIterator.next() + if (fields.nonEmpty) + lookupClass(className).isAnyStaticFieldReachable = true + } + val methodsCalledIterator = data.methodsCalled.iterator while (methodsCalledIterator.hasNext) { val (className, methods) = methodsCalledIterator.next() @@ -846,11 +872,38 @@ private final class Analyzer(semantics: Semantics, ) } - private def createMissingMethodInfo(encodedName: String, + private def createMissingMethodInfo( + encodedName: String): Infos.MethodInfo = { + makeSyntheticMethodInfo(encodedName = encodedName) + } + + private def createMissingStaticMethodInfo( + encodedName: String): Infos.MethodInfo = { + makeSyntheticMethodInfo(encodedName = encodedName, isStatic = true) + } + + private def makeSyntheticMethodInfo( + encodedName: String, isStatic: Boolean = false, - isAbstract: Boolean = false): Infos.MethodInfo = { - Infos.MethodInfo(encodedName = encodedName, - isStatic = isStatic, isAbstract = isAbstract) + methodsCalled: Map[String, List[String]] = Map.empty, + methodsCalledStatically: Map[String, List[String]] = Map.empty, + instantiatedClasses: List[String] = Nil + ): Infos.MethodInfo = { + Infos.MethodInfo( + encodedName, + isStatic, + isAbstract = false, + isExported = false, + staticFieldsRead = Map.empty, + staticFieldsWritten = Map.empty, + methodsCalled = methodsCalled, + methodsCalledStatically = methodsCalledStatically, + staticMethodsCalled = Map.empty, + instantiatedClasses = instantiatedClasses, + accessedModules = Nil, + usedInstanceTests = Nil, + accessedClassData = Nil + ) } } diff --git 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 index 886625fae6..71bcbe217f 100644 --- 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 @@ -109,9 +109,29 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, emitModuleImports(orderedClasses, builder, logger) + /* Emit all the classes, in the appropriate order: + * + * - First, all class definitions, which depend on nothing but their + * superclasses. + * - Second, all static field definitions, which depend on nothing, + * except those of type Long which need to instantiate RuntimeLong. + * - Third, all static initializers, which in the worst case can observe + * some "zero" state of other static field definitions, but must not + * observe a *non-initialized* (undefined) state. + * - Finally, all the exports, during which some JS class creation can + * happen, causing JS static initializers to run. Those also must not + * observe a non-initialized state of other static fields. + */ + for (linkedClass <- orderedClasses) emitLinkedClass(linkedClass, builder) + for (linkedClass <- orderedClasses) + emitLinkedClassStaticFields(linkedClass, builder) + + for (linkedClass <- orderedClasses) + emitLinkedClassStaticInitializer(linkedClass, builder) + for (linkedClass <- orderedClasses) emitLinkedClassClassExports(linkedClass, builder) } finally { @@ -270,16 +290,39 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, classEmitter.genModuleAccessor(linkedClass))) } + /** Emits the static fields of a linked class. + * + * They are initialized with the zero of their type at this point. It is + * the job of static initializers to properly initialize them. + */ + private def emitLinkedClassStaticFields(linkedClass: LinkedClass, + builder: JSTreeBuilder): Unit = { + + if (!linkedClass.kind.isJSType) { + val classCache = getClassCache(linkedClass.ancestors) + val classTreeCache = classCache.getCache(linkedClass.version) + + builder.addJSTree(classTreeCache.staticFields.getOrElseUpdate( + classEmitter.genCreateStaticFieldsOfScalaClass(linkedClass)(classCache))) + } + } + + /** Emits the static initializer of a linked class, if any. */ + private def emitLinkedClassStaticInitializer(linkedClass: LinkedClass, + builder: JSTreeBuilder): Unit = { + + if (!linkedClass.kind.isJSType) + builder.addJSTree(classEmitter.genStaticInitialization(linkedClass)) + } + /** Emits the class exports of a linked class. * * This is done after everything else has been emitted for all the classes * in the program. That is necessary because class exports can call class * value accessors, which may have unknown circular references. */ - private def emitLinkedClassClassExports( - linkedClass: LinkedClass, builder: JSTreeBuilder): Unit = { - - def addTree(tree: js.Tree): Unit = builder.addJSTree(tree) + private def emitLinkedClassClassExports(linkedClass: LinkedClass, + builder: JSTreeBuilder): Unit = { /* `if` to avoid looking up the caches for nothing. Probably worth doing * because only few classes have class exports. @@ -288,7 +331,7 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, val classCache = getClassCache(linkedClass.ancestors) val classTreeCache = classCache.getCache(linkedClass.version) - addTree(classTreeCache.classExports.getOrElseUpdate( + builder.addJSTree(classTreeCache.classExports.getOrElseUpdate( classEmitter.genClassExports(linkedClass)(classCache))) } } @@ -434,6 +477,7 @@ private[scalajs] object Emitter { val typeData = new OneTimeCache[js.Tree] val setTypeData = new OneTimeCache[js.Tree] val moduleAccessor = new OneTimeCache[js.Tree] + val staticFields = new OneTimeCache[js.Tree] val classExports = new OneTimeCache[js.Tree] } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala index 5231d81662..5bc9259f19 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala @@ -433,8 +433,8 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { transformExpr(rhs)) } - case Assign(varRef: VarRef, rhs) => - pushLhsInto(Lhs.Assign(varRef), rhs, tailPosLabels) + case Assign(lhs @ (_:VarRef | _:SelectStatic), rhs) => + pushLhsInto(Lhs.Assign(lhs), rhs, tailPosLabels) case Assign(_, _) => sys.error(s"Illegal Assign in transformStat: $tree") @@ -868,6 +868,10 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { case Select(qualifier, item) => allowSideEffects && test(qualifier) + // Static fields are side-effect free + case SelectStatic(_, _) => + allowUnpure + // Expressions preserving pureness case Block(trees) => trees forall test case If(cond, thenp, elsep) => test(cond) && test(thenp) && test(elsep) @@ -1622,6 +1626,9 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { case Select(qualifier, item) => transformExpr(qualifier) DOT item + case SelectStatic(cls, item) => + genSelectStatic(cls.className, item) + case Apply(receiver, method, args) => val newReceiver = transformExpr(receiver) val newArgs = args map transformExpr @@ -2155,6 +2162,11 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { } } + private[emitter] def genSelectStatic(className: String, item: Ident)( + implicit outputMode: OutputMode, pos: Position): js.Tree = { + envField("t", className + "__" + item.name) + } + private[emitter] def genIsInstanceOf(expr: js.Tree, cls: ReferenceType)( implicit outputMode: OutputMode, pos: Position): js.Tree = genIsAsInstanceOf(expr, cls, test = true) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala index b775f46890..17e0fccae9 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala @@ -65,6 +65,10 @@ private[emitter] final class ScalaJSClassEmitter( reverseParts ::= genSetTypeData(tree) if (kind.hasModuleAccessor) reverseParts ::= genModuleAccessor(tree) + if (!kind.isJSType) { + reverseParts ::= genCreateStaticFieldsOfScalaClass(tree) + reverseParts ::= genStaticInitialization(tree) + } reverseParts ::= genClassExports(tree) js.Block(reverseParts.reverse) @@ -137,7 +141,7 @@ private[emitter] final class ScalaJSClassEmitter( entireClassDef, genCreateStaticFieldsOfJSClass(tree), classValueVar := envField("c", className), - genStaticInitializationOfJSClass(tree) + genStaticInitialization(tree) ) }, { js.Skip() @@ -305,6 +309,20 @@ private[emitter] final class ScalaJSClassEmitter( } } + /** Generates the creation of the static fields for a Scala class. */ + def genCreateStaticFieldsOfScalaClass(tree: LinkedClass)( + implicit globalKnowledge: GlobalKnowledge): js.Tree = { + val className = tree.encodedName + val stats = for { + field @ FieldDef(true, Ident(name, origName), ftpe, mutable) <- tree.fields + } yield { + implicit val pos = field.pos + val fullName = className + "__" + name + envFieldDef("t", fullName, origName, genZeroOf(ftpe), mutable) + } + js.Block(stats)(tree.pos) + } + /** Generates the creation of the static fields for a JavaScript class. */ private def genCreateStaticFieldsOfJSClass(tree: LinkedClass)( implicit globalKnowledge: GlobalKnowledge): js.Tree = { @@ -321,8 +339,7 @@ private[emitter] final class ScalaJSClassEmitter( } /** Generates the static initializer invocation of a JavaScript class. */ - private def genStaticInitializationOfJSClass(tree: LinkedClass)( - implicit globalKnowledge: GlobalKnowledge): js.Tree = { + def genStaticInitialization(tree: LinkedClass): js.Tree = { import Definitions.StaticInitializerName implicit val pos = tree.pos if (tree.staticMethods.exists(_.tree.name.name == StaticInitializerName)) { @@ -911,6 +928,8 @@ private[emitter] final class ScalaJSClassEmitter( genModuleExportDef(tree, e) case e: TopLevelExportDef => genTopLevelExportDef(tree, e) + case e: TopLevelFieldExportDef => + genTopLevelFieldExportDef(tree, e) case tree => throw new AssertionError( "Illegal class export " + tree.getClass.getName) @@ -1002,18 +1021,73 @@ private[emitter] final class ScalaJSClassEmitter( ) } + private def genTopLevelFieldExportDef(cd: LinkedClass, + tree: TopLevelFieldExportDef)( + implicit globalKnowledge: GlobalKnowledge): js.Tree = { + import TreeDSL._ + + val TopLevelFieldExportDef(fullName, field) = tree + + implicit val pos = tree.pos + + val (createNamespace, namespace, fieldName) = + genCreateNamespaceInExportsAndGetNamespace(fullName) + + // defineProperty method + val defProp = + genIdentBracketSelect(js.VarRef(js.Ident("Object")), "defineProperty") + + // optional getter definition + val getterDef = { + js.StringLiteral("get") -> js.Function(Nil, { + js.Return(genSelectStatic(cd.encodedName, field)) + }) + } + + // Options passed to the defineProperty method + val descriptor = js.ObjectConstr( + getterDef :: + (js.StringLiteral("configurable") -> js.BooleanLiteral(true)) :: + Nil + ) + + val callDefineProp = + js.Apply(defProp, namespace :: fieldName :: descriptor :: Nil) + + js.Block(createNamespace, callDefineProp) + } + // Helpers /** Gen JS code for assigning an rhs to a qualified name in the exports scope. - * For example, given the qualified name "foo.bar.Something", generates: + * For example, given the qualified name `"foo.bar.Something"`, generates: * - * ScalaJS.e["foo"] = ScalaJS.e["foo"] || {}; - * ScalaJS.e["foo"]["bar"] = ScalaJS.e["foo"]["bar"] || {}; + * {{{ + * $e["foo"] = $e["foo"] || {}; + * $e["foo"]["bar"] = $e["foo"]["bar"] || {}; + * }}} * - * Returns (statements, ScalaJS.e["foo"]["bar"]["Something"]) + * Returns `(statements, $e["foo"]["bar"]["Something"])` */ private def genCreateNamespaceInExports(qualName: String)( implicit pos: Position): (js.Tree, js.Tree) = { + val (createNamespace, namespace, lastPart) = + genCreateNamespaceInExportsAndGetNamespace(qualName) + (createNamespace, genBracketSelect(namespace, lastPart)) + } + + /** Gen JS code for assigning an rhs to a qualified name in the exports scope. + * For example, given the qualified name `"foo.bar.Something"`, generates: + * + * {{{ + * $e["foo"] = $e["foo"] || {}; + * $e["foo"]["bar"] = $e["foo"]["bar"] || {}; + * }}} + * + * Returns `(statements, $e["foo"]["bar"], "Something")` + */ + private def genCreateNamespaceInExportsAndGetNamespace(qualName: String)( + implicit pos: Position): (js.Tree, js.Tree, js.StringLiteral) = { val parts = qualName.split("\\.") val statements = List.newBuilder[js.Tree] var namespace = envField("e") @@ -1023,8 +1097,7 @@ private[emitter] final class ScalaJSClassEmitter( js.Assign(namespace, js.BinaryOp(JSBinaryOp.||, namespace, js.ObjectConstr(Nil))) } - val lhs = genBracketSelect(namespace, js.StringLiteral(parts.last)) - (js.Block(statements.result()), lhs) + (js.Block(statements.result()), namespace, js.StringLiteral(parts.last)) } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 5ee8bbb084..d8983f48eb 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -122,6 +122,19 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { checkFieldDef(field, classDef) } + /* Check for static field collisions. + * TODO #2627 We currently cannot check instance field collisions because + * of #2382. + */ + val staticFieldDefs = classDef.fields.filter(_.static) + for { + fieldsWithSameName <- staticFieldDefs.groupBy(_.name.name).values + duplicate <- fieldsWithSameName.tail + } { + implicit val ctx = ErrorContext(duplicate) + reportError(s"Duplicate static field with name '${duplicate.name}'") + } + // Check exported members for (member <- classDef.exportedMembers) { implicit val ctx = ErrorContext(member.tree) @@ -166,6 +179,15 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { member.getClass.getName) } + case TopLevelFieldExportDef(fullName, field) => + lookupClass(classDef.name.name).lookupStaticField(field.name).fold { + reportError(s"Cannot export non-existent static field '$field'") + } { checkedField => + val tpe = checkedField.tpe + if (tpe != AnyType) + reportError(s"Cannot export field '$field' of type $tpe") + } + // Anything else is illegal case _ => reportError("Illegal class export of type " + @@ -203,9 +225,6 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { val FieldDef(static, name, tpe, mutable) = fieldDef implicit val ctx = ErrorContext(fieldDef) - if (static && !classDef.kind.isJSClass) - reportError(s"FieldDef '$name' cannot be static") - name match { case _: Ident => // ok @@ -475,6 +494,14 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { } reportError(s"Assignment to immutable field $name.") case _ => } + case SelectStatic(ClassType(cls), Ident(name, _)) => + for { + c <- tryLookupClass(cls) + f <- c.lookupStaticField(name) + if !f.mutable + } { + reportError(s"Assignment to immutable static field $name.") + } case VarRef(Ident(name, _)) if !env.locals(name).mutable => reportError(s"Assignment to immutable variable $name.") case _ => @@ -710,6 +737,20 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { reportError(s"Cannot select $item of non-class type $qualType") } + case SelectStatic(ClassType(cls), Ident(item, _)) => + val checkedClass = lookupClass(cls) + if (checkedClass.kind.isJSType) { + reportError(s"Cannot select static $item of JS type $cls") + } else { + checkedClass.lookupStaticField(item).fold[Unit] { + reportError(s"Class $cls does not have a static field $item") + } { fieldDef => + if (fieldDef.tpe != tree.tpe) + reportError(s"SelectStatic $cls.$item of type "+ + s"${fieldDef.tpe} typed as ${tree.tpe}") + } + } + case Apply(receiver, Ident(method, _), args) => val receiverType = typecheckExpr(receiver, env) checkApplyGeneric(method, s"$receiverType.$method", args, tree.tpe, @@ -1125,7 +1166,8 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { _fields: TraversableOnce[CheckedField])( implicit ctx: ErrorContext) { - val fields = _fields.map(f => f.name -> f).toMap + val fields = _fields.filter(!_.static).map(f => f.name -> f).toMap + val staticFields = _fields.filter(_.static).map(f => f.name -> f).toMap lazy val superClass = superClassName.map(classes) @@ -1143,17 +1185,20 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { def lookupField(name: String): Option[CheckedField] = fields.get(name).orElse(superClass.flatMap(_.lookupField(name))) + + def lookupStaticField(name: String): Option[CheckedField] = + staticFields.get(name) } private object CheckedClass { private def checkedField(fieldDef: FieldDef) = { - val FieldDef(false, Ident(name, _), tpe, mutable) = fieldDef - new CheckedField(name, tpe, mutable) + val FieldDef(static, Ident(name, _), tpe, mutable) = fieldDef + new CheckedField(static, name, tpe, mutable) } } - private class CheckedField(val name: String, val tpe: Type, - val mutable: Boolean) + private class CheckedField(val static: Boolean, val name: String, + val tpe: Type, val mutable: Boolean) } object IRChecker { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index d89ed5b785..b9cf3cdfa1 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -259,6 +259,9 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions case e: TopLevelExportDef => classExports += e + case e: TopLevelFieldExportDef => + classExports += e + case tree => sys.error(s"Illegal tree in ClassDef of class ${tree.getClass}") } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index 7ab8f78cdc..9fcb95c222 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -173,8 +173,9 @@ private[optimizer] abstract class OptimizerCore( } else { val after = from.tail val afterIsTrivial = after.forall { - case Assign(Select(This(), Ident(_, _)), - _:Literal | _:VarRef) => + case Assign(Select(This(), _), _:Literal | _:VarRef) => + true + case Assign(SelectStatic(_, _), _:Literal | _:VarRef) => true case _ => false @@ -670,8 +671,8 @@ private[optimizer] abstract class OptimizerCore( // Trees that need not be transformed - case _:Skip | _:Debugger | _:LoadModule | _:LoadJSConstructor | - _:LoadJSModule | _:JSLinkingInfo | _:Literal => + case _:Skip | _:Debugger | _:LoadModule | _:SelectStatic | + _:LoadJSConstructor | _:LoadJSModule | _:JSLinkingInfo | _:Literal => tree case _ => @@ -1313,7 +1314,7 @@ private[optimizer] abstract class OptimizerCore( /** Keeps only the side effects of a Tree (overapproximation). */ private def keepOnlySideEffects(stat: Tree): Tree = stat match { - case _:VarRef | _:This | _:Literal => + case _:VarRef | _:This | _:Literal | _:SelectStatic => Skip()(stat.pos) case VarDef(_, _, _, rhs) => keepOnlySideEffects(rhs) From 3a5690da65d2feb394bbc038f94b07a2ada1ce9e Mon Sep 17 00:00:00 2001 From: Faiz Halde Date: Thu, 12 Jan 2017 22:40:42 +0530 Subject: [PATCH 0093/2665] Consistent condition checking in nextInt and nextLong The change is just to keep the code of `nextInt` and `nextLong` consistent. There is no change in the functionality --- .../src/main/scala/java/util/concurrent/ThreadLocalRandom.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javalib/src/main/scala/java/util/concurrent/ThreadLocalRandom.scala b/javalib/src/main/scala/java/util/concurrent/ThreadLocalRandom.scala index f159b223a4..ce6ab96c6e 100644 --- a/javalib/src/main/scala/java/util/concurrent/ThreadLocalRandom.scala +++ b/javalib/src/main/scala/java/util/concurrent/ThreadLocalRandom.scala @@ -78,7 +78,7 @@ class ThreadLocalRandom extends Random { throw new IllegalArgumentException() val difference = bound - least - if (difference >= 0) { + if (difference > 0) { nextLong(difference) + least } else { /* The interval size here is greater than Long.MaxValue, From 1bbef5fdef445d18b5a32faee88793fe8d4419c6 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 8 Jan 2017 19:50:45 +0100 Subject: [PATCH 0094/2665] Decouple JSDesugar from ScalaJSClassEmitter --- project/BinaryIncompatibilities.scala | 34 +++++++++- .../linker/backend/emitter/Emitter.scala | 2 +- .../linker/backend/emitter/JSDesugaring.scala | 68 +++++++++---------- .../backend/emitter/ScalaJSClassEmitter.scala | 38 +++++------ 4 files changed, 82 insertions(+), 60 deletions(-) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index f45f4df452..7b26b1db8c 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -39,7 +39,39 @@ object BinaryIncompatibilities { ProblemFilters.exclude[MissingMethodProblem]( "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genClass"), ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genClassDef") + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genClassDef"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.outputMode"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.semantics"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.genCallHelper"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.genLet"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.genRawJSClassConstructor"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.genEmptyMutableLet"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.desugarTree"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.genLoadJSFromSpec"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.encodeClassVar"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.desugarToFunction"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.desugarToFunction"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.envField"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.envFieldDef"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.genIsInstanceOf"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.this"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring#JSDesugar.this") ) val JSEnvs = Seq( diff --git 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 index 71bcbe217f..8edfab8288 100644 --- 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 @@ -165,7 +165,7 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, } case ModuleKind.CommonJSModule => - val jsDesugaring = new JSDesugaring(internalOptions) + val jsDesugaring = new JSDesugaring(semantics, outputMode, internalOptions) val encounteredModuleNames = mutable.Set.empty[String] for (classDef <- orderedClasses) { classDef.jsNativeLoadSpec match { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala index 5bc9259f19..9d80ca79da 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala @@ -195,7 +195,8 @@ import java.io.StringWriter * * @author Sébastien Doeraene */ -private[emitter] class JSDesugaring(internalOptions: InternalOptions) { +private[emitter] class JSDesugaring(semantics: Semantics, + outputMode: OutputMode, internalOptions: InternalOptions) { import JSDesugaring._ private final val ScalaJSEnvironmentName = "ScalaJS" @@ -203,30 +204,30 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { /** Desugars parameters and body to a JS function. */ private[emitter] def desugarToFunction( - classEmitter: ScalaJSClassEmitter, enclosingClassName: String, + enclosingClassName: String, params: List[ParamDef], body: Tree, isStat: Boolean)( implicit globalKnowledge: GlobalKnowledge, pos: Position): js.Function = { - desugarToFunction(classEmitter, enclosingClassName, + desugarToFunction(enclosingClassName, None, params, body, isStat) } /** Desugars parameters and body to a JS function. */ private[emitter] def desugarToFunction( - classEmitter: ScalaJSClassEmitter, enclosingClassName: String, + enclosingClassName: String, thisIdent: Option[js.Ident], params: List[ParamDef], body: Tree, isStat: Boolean)( implicit globalKnowledge: GlobalKnowledge, pos: Position): js.Function = { - new JSDesugar(classEmitter, enclosingClassName) + new JSDesugar(enclosingClassName) .desugarToFunction(params, body, isStat, Env.empty.withThisIdent(thisIdent)) } /** Desugars a statement or an expression. */ private[emitter] def desugarTree( - classEmitter: ScalaJSClassEmitter, enclosingClassName: String, + enclosingClassName: String, tree: Tree, isStat: Boolean)( implicit globalKnowledge: GlobalKnowledge): js.Tree = { - val desugar = new JSDesugar(classEmitter, enclosingClassName) + val desugar = new JSDesugar(enclosingClassName) if (isStat) desugar.transformStat(tree, Set.empty)(Env.empty) else @@ -239,13 +240,9 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { private[emitter] def transformParamDef(paramDef: ParamDef): js.ParamDef = js.ParamDef(paramDef.name, paramDef.rest)(paramDef.pos) - private class JSDesugar( - classEmitter: ScalaJSClassEmitter, enclosingClassName: String)( + private class JSDesugar(enclosingClassName: String)( implicit globalKnowledge: GlobalKnowledge) { - private val semantics = classEmitter.semantics - private implicit val outputMode: OutputMode = classEmitter.outputMode - // Synthetic variables var syntheticVarCounter: Int = 0 @@ -2115,8 +2112,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { // Helpers - private[emitter] def genZeroOf(tpe: Type)( - implicit outputMode: OutputMode, pos: Position): js.Tree = { + private[emitter] def genZeroOf(tpe: Type)(implicit pos: Position): js.Tree = { tpe match { case BooleanType => js.BooleanLiteral(false) case IntType => js.IntLiteral(0) @@ -2129,13 +2125,12 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { } } - private def genLongZero()( - implicit outputMode: OutputMode, pos: Position): js.Tree = { + private def genLongZero()(implicit pos: Position): js.Tree = { genLongModuleApply(LongImpl.Zero) } private def genLongModuleApply(methodName: String, args: js.Tree*)( - implicit outputMode: OutputMode, pos: Position): js.Tree = { + implicit pos: Position): js.Tree = { import TreeDSL._ js.Apply( genLoadModule(LongImpl.RuntimeLongModuleClass) DOT methodName, @@ -2143,7 +2138,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { } private[emitter] def genLet(name: js.Ident, mutable: Boolean, rhs: js.Tree)( - implicit outputMode: OutputMode, pos: Position): js.LocalDef = { + implicit pos: Position): js.LocalDef = { outputMode match { case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => js.VarDef(name, Some(rhs)) @@ -2153,7 +2148,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { } private[emitter] def genEmptyMutableLet(name: js.Ident)( - implicit outputMode: OutputMode, pos: Position): js.LocalDef = { + implicit pos: Position): js.LocalDef = { outputMode match { case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => js.VarDef(name, rhs = None) @@ -2163,20 +2158,20 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { } private[emitter] def genSelectStatic(className: String, item: Ident)( - implicit outputMode: OutputMode, pos: Position): js.Tree = { + implicit pos: Position): js.Tree = { envField("t", className + "__" + item.name) } private[emitter] def genIsInstanceOf(expr: js.Tree, cls: ReferenceType)( - implicit outputMode: OutputMode, pos: Position): js.Tree = + implicit pos: Position): js.Tree = genIsAsInstanceOf(expr, cls, test = true) private def genAsInstanceOf(expr: js.Tree, cls: ReferenceType)( - implicit outputMode: OutputMode, pos: Position): js.Tree = + implicit pos: Position): js.Tree = genIsAsInstanceOf(expr, cls, test = false) private def genIsAsInstanceOf(expr: js.Tree, cls: ReferenceType, test: Boolean)( - implicit outputMode: OutputMode, pos: Position): js.Tree = { + implicit pos: Position): js.Tree = { import Definitions._ import TreeDSL._ @@ -2222,23 +2217,22 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { } private[emitter] def genCallHelper(helperName: String, args: js.Tree*)( - implicit outputMode: OutputMode, pos: Position): js.Tree = { + implicit pos: Position): js.Tree = { js.Apply(envField(helperName), args.toList) } private[emitter] def encodeClassVar(className: String)( - implicit outputMode: OutputMode, pos: Position): js.Tree = + implicit pos: Position): js.Tree = envField("c", className) private[emitter] def genLoadModule(moduleClass: String)( - implicit outputMode: OutputMode, pos: Position): js.Tree = { + implicit pos: Position): js.Tree = { import TreeDSL._ js.Apply(envField("m", moduleClass), Nil) } private[emitter] def genRawJSClassConstructor(className: String)( - implicit globalKnowledge: GlobalKnowledge, outputMode: OutputMode, - pos: Position): js.Tree = { + implicit globalKnowledge: GlobalKnowledge, pos: Position): js.Tree = { genRawJSClassConstructor(className, globalKnowledge.getJSNativeLoadSpec(className)) @@ -2246,7 +2240,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { private[emitter] def genRawJSClassConstructor(className: String, spec: Option[JSNativeLoadSpec])( - implicit outputMode: OutputMode, pos: Position): js.Tree = { + implicit pos: Position): js.Tree = { spec match { case None => // This is a Scala.js-defined JS class, call its class value accessor @@ -2258,7 +2252,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { } private[emitter] def genLoadJSFromSpec(spec: JSNativeLoadSpec)( - implicit outputMode: OutputMode, pos: Position): js.Tree = { + implicit pos: Position): js.Tree = { def pathSelection(from: js.Tree, path: List[String]): js.Tree = { path.foldLeft(from) { @@ -2329,7 +2323,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { private[emitter] def envField(field: String, subField: String, origName: Option[String] = None)( - implicit outputMode: OutputMode, pos: Position): js.Tree = { + implicit pos: Position): js.Tree = { import TreeDSL._ outputMode match { @@ -2342,7 +2336,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { } private[emitter] def envField(field: String)( - implicit outputMode: OutputMode, pos: Position): js.Tree = { + implicit pos: Position): js.Tree = { import TreeDSL._ outputMode match { @@ -2356,25 +2350,25 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { private[emitter] def envFieldDef(field: String, subField: String, value: js.Tree)( - implicit outputMode: OutputMode, pos: Position): js.Tree = { + implicit pos: Position): js.Tree = { envFieldDef(field, subField, value, mutable = false) } private[emitter] def envFieldDef(field: String, subField: String, value: js.Tree, mutable: Boolean)( - implicit outputMode: OutputMode, pos: Position): js.Tree = { + implicit pos: Position): js.Tree = { envFieldDef(field, subField, origName = None, value, mutable) } private[emitter] def envFieldDef(field: String, subField: String, origName: Option[String], value: js.Tree)( - implicit outputMode: OutputMode, pos: Position): js.Tree = { + implicit pos: Position): js.Tree = { envFieldDef(field, subField, origName, value, mutable = false) } private[emitter] def envFieldDef(field: String, subField: String, origName: Option[String], value: js.Tree, mutable: Boolean)( - implicit outputMode: OutputMode, pos: Position): js.Tree = { + implicit pos: Position): js.Tree = { envFieldDef(field, subField, origName, value, mutable, keepFunctionExpression = false) } @@ -2382,7 +2376,7 @@ private[emitter] class JSDesugaring(internalOptions: InternalOptions) { private[emitter] def envFieldDef(field: String, subField: String, origName: Option[String], value: js.Tree, mutable: Boolean, keepFunctionExpression: Boolean)( - implicit outputMode: OutputMode, pos: Position): js.Tree = { + implicit pos: Position): js.Tree = { val globalVar = envField(field, subField, origName) def globalVarIdent = globalVar.asInstanceOf[js.VarRef].ident diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala index 17e0fccae9..eb4a811be0 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala @@ -23,12 +23,11 @@ import org.scalajs.core.tools.linker.backend.OutputMode import org.scalajs.core.tools.linker.{LinkedClass, LinkingUnit} /** Emitter for the skeleton of classes. */ -private[emitter] final class ScalaJSClassEmitter( - private[emitter] val semantics: Semantics, - private[emitter] val outputMode: OutputMode, - internalOptions: InternalOptions) { +private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, + outputMode: OutputMode, internalOptions: InternalOptions) { - private val jsDesugaring = new JSDesugaring(internalOptions) + private val jsDesugaring = + new JSDesugaring(semantics, outputMode, internalOptions) import ScalaJSClassEmitter._ import jsDesugaring._ @@ -163,8 +162,8 @@ private[emitter] final class ScalaJSClassEmitter( require(outputMode == OutputMode.ECMAScript6) val className = tree.name.name - val classIdent = encodeClassVar(className)( - outputMode, tree.name.pos).asInstanceOf[js.VarRef].ident + val classIdent = + encodeClassVar(className)(tree.name.pos).asInstanceOf[js.VarRef].ident val parentVar = for (parentIdent <- tree.superClass) yield { implicit val pos = parentIdent.pos @@ -285,8 +284,7 @@ private[emitter] final class ScalaJSClassEmitter( tree.exportedMembers.map(_.tree) collectFirst { case MethodDef(false, StringLiteral("constructor"), params, _, body) => - desugarToFunction(this, tree.encodedName, - params, body.get, isStat = true) + desugarToFunction(tree.encodedName, params, body.get, isStat = true) } getOrElse { throw new IllegalArgumentException( s"${tree.encodedName} does not have an exported constructor") @@ -304,7 +302,7 @@ private[emitter] final class ScalaJSClassEmitter( val selectField = (name: @unchecked) match { case name: Ident => Select(This()(tpe), name)(ftpe) } - desugarTree(this, tree.encodedName, + desugarTree(tree.encodedName, Assign(selectField, zeroOf(ftpe)), isStat = true) } } @@ -358,7 +356,7 @@ private[emitter] final class ScalaJSClassEmitter( implicit val pos = method.pos - val methodFun0 = desugarToFunction(this, className, + val methodFun0 = desugarToFunction(className, method.args, methodBody, method.resultType == NoType) val methodFun = if (Definitions.isConstructorName(method.name.name)) { @@ -413,7 +411,7 @@ private[emitter] final class ScalaJSClassEmitter( */ val thisIdent = js.Ident("$thiz", Some("this")) - val methodFun0 = desugarToFunction(this, className, Some(thisIdent), + val methodFun0 = desugarToFunction(className, Some(thisIdent), method.args, method.body.get, method.resultType == NoType) val methodFun = js.Function( @@ -462,14 +460,13 @@ private[emitter] final class ScalaJSClassEmitter( // optional getter definition val optGetter = property.getterBody map { body => - val fun = desugarToFunction(this, className, Nil, body, isStat = false) + val fun = desugarToFunction(className, Nil, body, isStat = false) js.StringLiteral("get") -> fun } // optional setter definition val optSetter = property.setterArgAndBody map { case (arg, body) => - val fun = desugarToFunction(this, className, arg :: Nil, - body, isStat = true) + val fun = desugarToFunction(className, arg :: Nil, body, isStat = true) js.StringLiteral("set") -> fun } @@ -492,15 +489,14 @@ private[emitter] final class ScalaJSClassEmitter( val getter = property.getterBody.fold[js.Tree] { js.Skip() } { body => - val fun = desugarToFunction(this, className, Nil, body, isStat = false) + val fun = desugarToFunction(className, Nil, body, isStat = false) js.GetterDef(static = false, propName, fun.body) } val setter = property.setterArgAndBody.fold[js.Tree] { js.Skip() } { case (arg, body) => - val fun = desugarToFunction(this, className, arg :: Nil, - body, isStat = true) + val fun = desugarToFunction(className, arg :: Nil, body, isStat = true) js.SetterDef(static = false, propName, fun.args.head, fun.body) } @@ -951,7 +947,7 @@ private[emitter] final class ScalaJSClassEmitter( val thisIdent = js.Ident("$thiz") val js.Function(ctorParams, ctorBody) = - desugarToFunction(this, cd.encodedName, + desugarToFunction(cd.encodedName, Some(thisIdent), args, body, isStat = true) val exportedCtor = js.Function(ctorParams, js.Block( @@ -1012,8 +1008,8 @@ private[emitter] final class ScalaJSClassEmitter( val (createNamespace, expAccessorVar) = genCreateNamespaceInExports(fullName) - val methodDef = desugarToFunction(this, cd.encodedName, args, - body, isStat = resultType == NoType) + val methodDef = desugarToFunction(cd.encodedName, args, body, + isStat = resultType == NoType) js.Block( createNamespace, From 213422a54d873b8c3e82ccc3886cc916e2392f71 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 8 Jan 2017 20:00:02 +0100 Subject: [PATCH 0095/2665] Put enclosingClassName in the Env and make it optional --- project/BinaryIncompatibilities.scala | 6 +++- .../linker/backend/emitter/JSDesugaring.scala | 33 +++++++++++++------ .../backend/emitter/ScalaJSClassEmitter.scala | 2 +- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 7b26b1db8c..8d9669d0c7 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -71,7 +71,11 @@ object BinaryIncompatibilities { ProblemFilters.exclude[DirectMissingMethodProblem]( "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.this"), ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring#JSDesugar.this") + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring#JSDesugar.this"), + + // private, not an issue. + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring#Env.this") ) val JSEnvs = Seq( diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala index 9d80ca79da..e077e6d9fc 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala @@ -218,20 +218,24 @@ private[emitter] class JSDesugaring(semantics: Semantics, thisIdent: Option[js.Ident], params: List[ParamDef], body: Tree, isStat: Boolean)( implicit globalKnowledge: GlobalKnowledge, pos: Position): js.Function = { - new JSDesugar(enclosingClassName) - .desugarToFunction(params, body, isStat, Env.empty.withThisIdent(thisIdent)) + val env = Env.empty + .withThisIdent(thisIdent) + .withEnclosingClassName(Some(enclosingClassName)) + + new JSDesugar().desugarToFunction(params, body, isStat, env) } /** Desugars a statement or an expression. */ private[emitter] def desugarTree( - enclosingClassName: String, + enclosingClassName: Option[String], tree: Tree, isStat: Boolean)( implicit globalKnowledge: GlobalKnowledge): js.Tree = { - val desugar = new JSDesugar(enclosingClassName) + val env = Env.empty.withEnclosingClassName(enclosingClassName) + val desugar = new JSDesugar() if (isStat) - desugar.transformStat(tree, Set.empty)(Env.empty) + desugar.transformStat(tree, Set.empty)(env) else - desugar.transformExpr(tree)(Env.empty) + desugar.transformExpr(tree)(env) } private[emitter] implicit def transformIdent(ident: Ident): js.Ident = @@ -240,8 +244,7 @@ private[emitter] class JSDesugaring(semantics: Semantics, private[emitter] def transformParamDef(paramDef: ParamDef): js.ParamDef = js.ParamDef(paramDef.name, paramDef.rest)(paramDef.pos) - private class JSDesugar(enclosingClassName: String)( - implicit globalKnowledge: GlobalKnowledge) { + private class JSDesugar()(implicit globalKnowledge: GlobalKnowledge) { // Synthetic variables @@ -501,6 +504,10 @@ private[emitter] class JSDesugaring(semantics: Semantics, unnestOrSpread(args) { (newArgs, env0) => implicit val env = env0 + val enclosingClassName = env.enclosingClassName.getOrElse { + sys.error("Need enclosing class for super constructor call.") + } + val superCtorCall = { outputMode match { case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => @@ -2471,6 +2478,7 @@ private object JSDesugaring { final class Env private ( val thisIdent: Option[js.Ident], + val enclosingClassName: Option[String], vars: Map[String, Boolean], labeledExprLHSes: Map[String, Lhs], defaultBreakTargets: Set[String] @@ -2482,6 +2490,9 @@ private object JSDesugaring { def isDefaultBreakTarget(label: String): Boolean = defaultBreakTargets.contains(label) + def withEnclosingClassName(enclosingClassName: Option[String]): Env = + copy(enclosingClassName = enclosingClassName) + def withThisIdent(thisIdent: Option[js.Ident]): Env = copy(thisIdent = thisIdent) @@ -2504,14 +2515,16 @@ private object JSDesugaring { private def copy( thisIdent: Option[js.Ident] = this.thisIdent, + enclosingClassName: Option[String] = this.enclosingClassName, vars: Map[String, Boolean] = this.vars, labeledExprLHSes: Map[String, Lhs] = this.labeledExprLHSes, defaultBreakTargets: Set[String] = this.defaultBreakTargets): Env = { - new Env(thisIdent, vars, labeledExprLHSes, defaultBreakTargets) + new Env(thisIdent, enclosingClassName, vars, labeledExprLHSes, + defaultBreakTargets) } } object Env { - def empty: Env = new Env(None, Map.empty, Map.empty, Set.empty) + def empty: Env = new Env(None, None, Map.empty, Map.empty, Set.empty) } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala index eb4a811be0..5244a826ef 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala @@ -302,7 +302,7 @@ private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, val selectField = (name: @unchecked) match { case name: Ident => Select(This()(tpe), name)(ftpe) } - desugarTree(tree.encodedName, + desugarTree(Some(tree.encodedName), Assign(selectField, zeroOf(ftpe)), isStat = true) } } From 61ddae5f74571bca29458ffeed3d5168aa056a8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 12 Jan 2017 17:46:29 +0100 Subject: [PATCH 0096/2665] Fix #2725: Rename TopLevelExportDef to TopLevelMethodExportDef. --- .../scalajs/core/compiler/GenJSExports.scala | 21 +++++++--------- .../scala/org/scalajs/core/ir/Infos.scala | 24 +++++++++---------- .../scala/org/scalajs/core/ir/Printers.scala | 4 ++-- .../org/scalajs/core/ir/Serializers.scala | 14 +++++------ .../main/scala/org/scalajs/core/ir/Tags.scala | 4 ++-- .../org/scalajs/core/ir/Transformers.scala | 5 ++-- .../org/scalajs/core/ir/Traversers.scala | 4 ++-- .../scala/org/scalajs/core/ir/Trees.scala | 2 +- .../org/scalajs/core/ir/PrintersTest.scala | 5 ++-- project/BinaryIncompatibilities.scala | 10 ++++++++ .../core/tools/linker/LinkedClass.scala | 2 +- .../backend/emitter/ScalaJSClassEmitter.scala | 9 +++---- .../core/tools/linker/checker/IRChecker.scala | 11 ++------- .../tools/linker/frontend/BaseLinker.scala | 2 +- 14 files changed, 60 insertions(+), 57 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index 82aa1ff7a8..00e10820a5 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -120,16 +120,8 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } } - def genTopLevelExports(classSym: Symbol): List[js.Tree] = { - for { - m <- genTopLevelOrStaticExports(classSym, ExportDestination.TopLevel) - } yield { - m match { - case m: js.TopLevelFieldExportDef => m - case _ => js.TopLevelExportDef(m)(m.pos) - } - } - } + def genTopLevelExports(classSym: Symbol): List[js.Tree] = + genTopLevelOrStaticExports(classSym, ExportDestination.TopLevel) def genStaticExports(classSym: Symbol): List[js.Tree] = genTopLevelOrStaticExports(classSym, ExportDestination.Static) @@ -185,7 +177,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } private def genTopLevelOrStaticMethodExports(classSym: Symbol, - destination: ExportDestination): List[(js.MethodDef, String, Position)] = { + destination: ExportDestination): List[(js.Tree, String, Position)] = { val allRelevantExports = for { methodSym <- classSym.info.members if methodSym.isMethod && !methodSym.isConstructor @@ -201,7 +193,12 @@ trait GenJSExports extends SubComponent { self: GenJSCode => implicit val pos = tups.head._1.pos val alts = tups.map(t => ExportedSymbol(t._2)).toList - (genExportMethod(alts, jsName, static = true), jsName, pos) + val methodDef = genExportMethod(alts, jsName, static = true) + val exportDef = + if (destination == ExportDestination.Static) methodDef + else js.TopLevelMethodExportDef(methodDef) + + (exportDef, jsName, pos) } } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala index 4c76ed38d7..b244fe4f4e 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala @@ -303,7 +303,7 @@ object Infos { .addInterfaces(classDef.interfaces.map(_.name)) var exportedConstructors: List[ConstructorExportDef] = Nil - var topLevelExports: List[TopLevelExportDef] = Nil + var topLevelMethodExports: List[TopLevelMethodExportDef] = Nil var topLevelFieldExports: List[TopLevelFieldExportDef] = Nil classDef.defs foreach { @@ -316,18 +316,18 @@ object Infos { exportedConstructors ::= constructorDef case _:JSClassExportDef | _:ModuleExportDef => builder.setIsExported(true) - case topLevelExport: TopLevelExportDef => + case topLevelMethodExport: TopLevelMethodExportDef => builder.setIsExported(true) - topLevelExports ::= topLevelExport + topLevelMethodExports ::= topLevelMethodExport case topLevelFieldExport: TopLevelFieldExportDef => builder.setIsExported(true) topLevelFieldExports ::= topLevelFieldExport case _ => } - if (exportedConstructors.nonEmpty || topLevelExports.nonEmpty) { + if (exportedConstructors.nonEmpty || topLevelMethodExports.nonEmpty) { builder.addMethod(generateClassExportsInfo(classDef.name.name, - exportedConstructors, topLevelExports, topLevelFieldExports)) + exportedConstructors, topLevelMethodExports, topLevelFieldExports)) } builder.result() @@ -353,18 +353,18 @@ object Infos { "Use the overload with an enclosingClass and topLevelFieldExports.", "0.6.15") def generateClassExportsInfo(constructorDefs: List[ConstructorExportDef], - topLevelExports: List[TopLevelExportDef]): MethodInfo = { + topLevelMethodExports: List[TopLevelMethodExportDef]): MethodInfo = { // enclosingClass won't be used when topLevelFieldExports is empty - generateClassExportsInfo("", constructorDefs, topLevelExports, Nil) + generateClassExportsInfo("", constructorDefs, topLevelMethodExports, Nil) } /** Generates the [[MethodInfo]] for the class exports. */ def generateClassExportsInfo(enclosingClass: String, constructorDefs: List[ConstructorExportDef], - topLevelExports: List[TopLevelExportDef], + topLevelMethodExports: List[TopLevelMethodExportDef], topLevelFieldExports: List[TopLevelFieldExportDef]): MethodInfo = { new GenInfoTraverser().generateClassExportsInfo(enclosingClass, - constructorDefs, topLevelExports, topLevelFieldExports) + constructorDefs, topLevelMethodExports, topLevelFieldExports) } private final class GenInfoTraverser extends Traversers.Traverser { @@ -397,7 +397,7 @@ object Infos { def generateClassExportsInfo(enclosingClass: String, constructorDefs: List[ConstructorExportDef], - topLevelExports: List[TopLevelExportDef], + topLevelMethodExports: List[TopLevelMethodExportDef], topLevelFieldExports: List[TopLevelFieldExportDef]): MethodInfo = { builder .setEncodedName(ClassExportsName) @@ -406,8 +406,8 @@ object Infos { for (constructorDef <- constructorDefs) traverse(constructorDef.body) - for (topLevelExport <- topLevelExports) - traverse(topLevelExport.member) + for (topLevelMethodExport <- topLevelMethodExports) + traverse(topLevelMethodExport.methodDef) for (topLevelFieldExport <- topLevelFieldExports) { val field = topLevelFieldExport.field.name diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index b8ab1f4298..3820e47017 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -863,9 +863,9 @@ object Printers { printEscapeJS(fullName, out) print('\"') - case TopLevelExportDef(member) => + case TopLevelMethodExportDef(methodDef) => print("export top ") - print(member) + print(methodDef) case TopLevelFieldExportDef(fullName, field) => print("export top static field ") diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index a1a69c1a97..0d5389be99 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -465,9 +465,9 @@ object Serializers { writeByte(TagModuleExportDef) writeString(fullName) - case TopLevelExportDef(member) => - writeByte(TagTopLevelExportDef) - writeTree(member) + case TopLevelMethodExportDef(methodDef) => + writeByte(TagTopLevelMethodExportDef) + writeTree(methodDef) case TopLevelFieldExportDef(fullName, field) => writeByte(TagTopLevelFieldExportDef) @@ -896,10 +896,10 @@ object Serializers { result } - case TagJSClassExportDef => JSClassExportDef(readString()) - case TagModuleExportDef => ModuleExportDef(readString()) - case TagTopLevelExportDef => TopLevelExportDef(readTree()) - case TagTopLevelFieldExportDef => TopLevelFieldExportDef(readString(), readIdent()) + case TagJSClassExportDef => JSClassExportDef(readString()) + case TagModuleExportDef => ModuleExportDef(readString()) + case TagTopLevelMethodExportDef => TopLevelMethodExportDef(readTree().asInstanceOf[MethodDef]) + case TagTopLevelFieldExportDef => TopLevelFieldExportDef(readString(), readIdent()) } if (UseDebugMagic) { val magic = readInt() diff --git a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala index 251775f0f9..0db0206f6e 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala @@ -104,8 +104,8 @@ private[ir] object Tags { final val TagJSClassExportDef = TagLoadJSModule + 1 final val TagTryCatch = TagJSClassExportDef + 1 final val TagTryFinally = TagTryCatch + 1 - final val TagTopLevelExportDef = TagTryFinally + 1 - final val TagSelectStatic = TagTopLevelExportDef + 1 + final val TagTopLevelMethodExportDef = TagTryFinally + 1 + final val TagSelectStatic = TagTopLevelMethodExportDef + 1 final val TagTopLevelFieldExportDef = TagSelectStatic + 1 // Tags for Types diff --git a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala index 4cc49fd2c3..5818a91abd 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala @@ -231,8 +231,9 @@ object Transformers { case _:JSClassExportDef | _:ModuleExportDef | _:TopLevelFieldExportDef => tree - case TopLevelExportDef(member) => - TopLevelExportDef(transformDef(member)) + case TopLevelMethodExportDef(methodDef) => + TopLevelMethodExportDef( + transformDef(methodDef).asInstanceOf[MethodDef]) case _ => sys.error(s"Invalid tree in transformDef() of class ${tree.getClass}") diff --git a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala index e93ea7b021..4e9849df78 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala @@ -204,8 +204,8 @@ object Traversers { case ConstructorExportDef(fullName, args, body) => traverse(body) - case TopLevelExportDef(member) => - traverse(member) + case TopLevelMethodExportDef(methodDef) => + traverse(methodDef) // Trees that need not be traversed diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 52dd9742f1..7c70a1c6de 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -814,7 +814,7 @@ object Trees { val tpe = NoType } - case class TopLevelExportDef(member: Tree)( + case class TopLevelMethodExportDef(methodDef: MethodDef)( implicit val pos: Position) extends Tree { val tpe = NoType } diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala index fbf08e4f9c..23cb79a617 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala @@ -1067,13 +1067,14 @@ class PrintersTest { ModuleExportDef("pkg.Foo")) } - @Test def printTopLevelExportDef(): Unit = { + @Test def printTopLevelMethodExportDef(): Unit = { assertPrintEquals( """ |export top static def "pkg.foo"(x: any): any = { | 5 |}""", - TopLevelExportDef(MethodDef(static = true, StringLiteral("pkg.foo"), + TopLevelMethodExportDef(MethodDef(static = true, + StringLiteral("pkg.foo"), List(ParamDef("x", AnyType, mutable = false, rest = false)), AnyType, Some(i(5)))(NoOptHints, None))) } diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 8d9669d0c7..d966946eb5 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -17,6 +17,14 @@ object BinaryIncompatibilities { ProblemFilters.exclude[IncompatibleResultTypeProblem]( "org.scalajs.core.ir.Trees#FieldDef.copy$default$3"), + // Breaking: TopLevelExportDef has been renamed to TopLevelMethodExportDef + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.ir.Trees$TopLevelExportDef"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.ir.Trees$TopLevelExportDef$"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.ir.Tags.TagTopLevelExportDef"), + // private, not an issue ProblemFilters.exclude[DirectMissingMethodProblem]( "org.scalajs.core.ir.Infos#MethodInfo.this"), @@ -40,6 +48,8 @@ object BinaryIncompatibilities { "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genClass"), ProblemFilters.exclude[MissingMethodProblem]( "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genClassDef"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genTopLevelExportDef"), ProblemFilters.exclude[DirectMissingMethodProblem]( "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.outputMode"), ProblemFilters.exclude[DirectMissingMethodProblem]( diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala index 7060e798b0..b92dbdbedf 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala @@ -67,7 +67,7 @@ final class LinkedClass( case ModuleExportDef(name) => name case JSClassExportDef(name) => name - case TopLevelExportDef(MethodDef(_, StringLiteral(name), _, _, _)) => + case TopLevelMethodExportDef(MethodDef(_, StringLiteral(name), _, _, _)) => name case TopLevelFieldExportDef(name, _) => name diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala index 5244a826ef..5d635c900f 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala @@ -922,8 +922,8 @@ private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, genJSClassExportDef(tree, e) case e: ModuleExportDef => genModuleExportDef(tree, e) - case e: TopLevelExportDef => - genTopLevelExportDef(tree, e) + case e: TopLevelMethodExportDef => + genTopLevelMethodExportDef(tree, e) case e: TopLevelFieldExportDef => genTopLevelFieldExportDef(tree, e) case tree => @@ -996,12 +996,13 @@ private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, ) } - def genTopLevelExportDef(cd: LinkedClass, tree: TopLevelExportDef)( + private def genTopLevelMethodExportDef(cd: LinkedClass, + tree: TopLevelMethodExportDef)( implicit globalKnowledge: GlobalKnowledge): js.Tree = { import TreeDSL._ val MethodDef(true, StringLiteral(fullName), args, resultType, Some(body)) = - tree.member + tree.methodDef implicit val pos = tree.pos diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index d8983f48eb..effd9096fa 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -169,15 +169,8 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { case member @ ModuleExportDef(_) => checkModuleExportDef(member, classDef) - case TopLevelExportDef(member) => - member match { - case methodDef: MethodDef => - checkExportedMethodDef(methodDef, classDef, isTopLevel = true) - - case _ => - reportError("Illegal top level export of type " + - member.getClass.getName) - } + case TopLevelMethodExportDef(methodDef) => + checkExportedMethodDef(methodDef, classDef, isTopLevel = true) case TopLevelFieldExportDef(fullName, field) => lookupClass(classDef.name.name).lookupStaticField(field.name).fold { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index b9cf3cdfa1..be5b4fbd84 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -256,7 +256,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions case e: ModuleExportDef => classExports += e - case e: TopLevelExportDef => + case e: TopLevelMethodExportDef => classExports += e case e: TopLevelFieldExportDef => From 4af6831d11f3b9d0c527b5ad2784403093f25bab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 13 Jan 2017 11:06:28 +0100 Subject: [PATCH 0097/2665] Fix missing __exportedInits info for top-level field exports. In practice, it wasn't an issue, because a) a top-level field export would always be accompanied by a static initializer, ensuring the class would be kept, and b) fields are never dce'ed away at the moment. It would have become an issue in the future, though, if/when the analyzer gets smarter about fields. --- ir/src/main/scala/org/scalajs/core/ir/Infos.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala index b244fe4f4e..7ed0e4adcb 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala @@ -325,7 +325,8 @@ object Infos { case _ => } - if (exportedConstructors.nonEmpty || topLevelMethodExports.nonEmpty) { + if (exportedConstructors.nonEmpty || topLevelMethodExports.nonEmpty || + topLevelFieldExports.nonEmpty) { builder.addMethod(generateClassExportsInfo(classDef.name.name, exportedConstructors, topLevelMethodExports, topLevelFieldExports)) } From a8c1e9a029a3966a354a954f5a4e370e43a822b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 13 Jan 2017 11:22:51 +0100 Subject: [PATCH 0098/2665] Fix #2719: Throw StringIndexOOBE in String{Buffer,Builder}. --- .../src/main/scala/java/lang/StringBuffer.scala | 12 ++++++++---- .../src/main/scala/java/lang/StringBuilder.scala | 12 ++++++++---- .../javalib/lang/StringBufferTest.scala | 16 ++++++++++------ 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/javalanglib/src/main/scala/java/lang/StringBuffer.scala b/javalanglib/src/main/scala/java/lang/StringBuffer.scala index 65e72be698..16db542b86 100644 --- a/javalanglib/src/main/scala/java/lang/StringBuffer.scala +++ b/javalanglib/src/main/scala/java/lang/StringBuffer.scala @@ -104,14 +104,18 @@ class StringBuffer(private var content: String) extends CharSequence } def setCharAt(index: Int, ch: scala.Char): Unit = { - if (index < 0 || index >= content.length) - throw new IndexOutOfBoundsException("String index out of range: " + index) + if (index < 0 || index >= content.length) { + throw new StringIndexOutOfBoundsException( + "String index out of range: " + index) + } content = content.substring(0, index) + ch + content.substring(index + 1) } def setLength(newLength: Int): Unit = { - if (newLength < 0) - throw new IndexOutOfBoundsException("String index out of range: " + newLength) + if (newLength < 0) { + throw new StringIndexOutOfBoundsException( + "String index out of range: " + newLength) + } val len = length() if (len == newLength) { diff --git a/javalanglib/src/main/scala/java/lang/StringBuilder.scala b/javalanglib/src/main/scala/java/lang/StringBuilder.scala index 093927cf78..28af223d0a 100644 --- a/javalanglib/src/main/scala/java/lang/StringBuilder.scala +++ b/javalanglib/src/main/scala/java/lang/StringBuilder.scala @@ -123,14 +123,18 @@ class StringBuilder(private var content: String) extends CharSequence } def setCharAt(index: Int, ch: scala.Char): Unit = { - if (index < 0 || index >= content.length) - throw new IndexOutOfBoundsException("String index out of range: " + index) + if (index < 0 || index >= content.length) { + throw new StringIndexOutOfBoundsException( + "String index out of range: " + index) + } content = content.substring(0, index) + ch + content.substring(index + 1) } def setLength(newLength: Int): Unit = { - if (newLength < 0) - throw new IndexOutOfBoundsException("String index out of range: " + newLength) + if (newLength < 0) { + throw new StringIndexOutOfBoundsException( + "String index out of range: " + newLength) + } val len = length() if (len == newLength) { diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringBufferTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringBufferTest.scala index df0af2a164..8d9f302a63 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringBufferTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringBufferTest.scala @@ -98,8 +98,10 @@ class StringBufferTest { buf.setCharAt(5, 'h') assertEquals("foxbah", buf.toString) - expectThrows(classOf[IndexOutOfBoundsException], buf.setCharAt(-1, 'h')) - expectThrows(classOf[IndexOutOfBoundsException], buf.setCharAt(6, 'h')) + expectThrows(classOf[StringIndexOutOfBoundsException], + buf.setCharAt(-1, 'h')) + expectThrows(classOf[StringIndexOutOfBoundsException], + buf.setCharAt(6, 'h')) } @Test def ensureCapacity(): Unit = { @@ -111,7 +113,7 @@ class StringBufferTest { val buf = newBuf buf.append("foobar") - expectThrows(classOf[IndexOutOfBoundsException], buf.setLength(-3)) + expectThrows(classOf[StringIndexOutOfBoundsException], buf.setLength(-3)) assertEquals("foo", { buf.setLength(3); buf.toString }) assertEquals("foo\u0000\u0000\u0000", { buf.setLength(6); buf.toString }) @@ -218,8 +220,10 @@ class StringBuilderTest { b.setCharAt(5, 'h') assertEquals("foxbah", b.toString) - expectThrows(classOf[IndexOutOfBoundsException], b.setCharAt(-1, 'h')) - expectThrows(classOf[IndexOutOfBoundsException], b.setCharAt(6, 'h')) + expectThrows(classOf[StringIndexOutOfBoundsException], + b.setCharAt(-1, 'h')) + expectThrows(classOf[StringIndexOutOfBoundsException], + b.setCharAt(6, 'h')) } @Test def ensureCapacity(): Unit = { @@ -231,7 +235,7 @@ class StringBuilderTest { val b = newBuilder b.append("foobar") - expectThrows(classOf[IndexOutOfBoundsException], b.setLength(-3)) + expectThrows(classOf[StringIndexOutOfBoundsException], b.setLength(-3)) assertEquals("foo", { b.setLength(3); b.toString }) assertEquals("foo\u0000\u0000\u0000", { b.setLength(6); b.toString }) From e8f1e95f45132da65f27428271e458395a36012f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 13 Jan 2017 17:10:03 +0100 Subject: [PATCH 0099/2665] Export module getters and setters as static in their companion class. This commit implements `@JSExportStatic` support for getters and setters, from the proposal #2702. The annotation `@JSExportStatic` can now be used on getters and setters, i.e., `def`s without parentheses and `def`s whose name ends with `_=`. The annotation causes the export of a static property in the companion class. --- .../scalajs/core/compiler/GenJSExports.scala | 69 ++++++--- .../scalajs/core/compiler/PrepJSExports.scala | 4 - .../core/compiler/test/JSExportASTTest.scala | 2 +- .../core/compiler/test/JSExportTest.scala | 134 ++++++++++++++++-- .../scala/org/scalajs/core/ir/Infos.scala | 1 + .../scala/org/scalajs/core/ir/Printers.scala | 6 +- .../org/scalajs/core/ir/Serializers.scala | 10 +- .../org/scalajs/core/ir/Transformers.scala | 3 +- .../org/scalajs/core/ir/Traversers.scala | 2 +- .../scala/org/scalajs/core/ir/Trees.scala | 4 +- .../org/scalajs/core/ir/PrintersTest.scala | 68 +++++---- project/BinaryIncompatibilities.scala | 12 ++ .../jsinterop/JSExportStaticTest.scala | 106 ++++++++++++++ .../closure/ClosureLinkerBackend.scala | 2 +- .../backend/emitter/ScalaJSClassEmitter.scala | 12 +- .../core/tools/linker/checker/IRChecker.scala | 5 +- .../tools/linker/frontend/BaseLinker.scala | 2 +- 17 files changed, 356 insertions(+), 86 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index 00e10820a5..aec2913cb1 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -91,7 +91,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => implicit val pos = ctors.head.pos val js.MethodDef(_, _, args, _, body) = - withNewLocalNameScope(genExportMethod(ctors, jsName)) + withNewLocalNameScope(genExportMethod(ctors, jsName, static = false)) js.ConstructorExportDef(jsName, args, body.get) } @@ -192,11 +192,29 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } yield { implicit val pos = tups.head._1.pos - val alts = tups.map(t => ExportedSymbol(t._2)).toList - val methodDef = genExportMethod(alts, jsName, static = true) + val alts = tups.map(_._2).toList + val firstAlt = alts.head + val isProp = jsInterop.isJSProperty(firstAlt) + + // Check for conflict between method vs property + + for { + conflicting <- alts.tail + if jsInterop.isJSProperty(conflicting) != isProp + } { + val kindStr = if (isProp) "method" else "property" + reporter.error(conflicting.pos, + s"Exported $kindStr $jsName conflicts with ${firstAlt.nameString}") + } + + // Generate the export + + val exportedMember = genMemberExportOrDispatcher(classSym, jsName, + isProp, alts, static = true) + val exportDef = - if (destination == ExportDestination.Static) methodDef - else js.TopLevelMethodExportDef(methodDef) + if (destination == ExportDestination.Static) exportedMember + else js.TopLevelMethodExportDef(exportedMember.asInstanceOf[js.MethodDef]) (exportDef, jsName, pos) } @@ -283,7 +301,8 @@ trait GenJSExports extends SubComponent { self: GenJSCode => s"Exported $kind $jsName conflicts with ${alts.head.fullName}") } - genMemberExportOrDispatcher(classSym, jsName, isProp, alts) + genMemberExportOrDispatcher(classSym, jsName, isProp, alts, + static = false) } private def genJSClassDispatcher(classSym: Symbol, name: String): js.Tree = { @@ -308,24 +327,26 @@ trait GenJSExports extends SubComponent { self: GenJSCode => s"Conflicting properties and methods for ${classSym.fullName}::$name.") js.Skip()(ir.Position.NoPosition) } else { - genMemberExportOrDispatcher(classSym, name, isProp, alts) + genMemberExportOrDispatcher(classSym, name, isProp, alts, + static = false) } } def genMemberExportOrDispatcher(classSym: Symbol, jsName: String, - isProp: Boolean, alts: List[Symbol]): js.Tree = { + isProp: Boolean, alts: List[Symbol], static: Boolean): js.Tree = { withNewLocalNameScope { if (isProp) - genExportProperty(alts, jsName) + genExportProperty(alts, jsName, static) else - genExportMethod(alts.map(ExportedSymbol), jsName) + genExportMethod(alts.map(ExportedSymbol), jsName, static) } } def genJSConstructorExport(alts: List[Symbol]): js.MethodDef = - genExportMethod(alts.map(ExportedSymbol), "constructor") + genExportMethod(alts.map(ExportedSymbol), "constructor", static = false) - private def genExportProperty(alts: List[Symbol], jsName: String) = { + private def genExportProperty(alts: List[Symbol], jsName: String, + static: Boolean): js.PropertyDef = { assert(!alts.isEmpty) implicit val pos = alts.head.pos @@ -333,12 +354,21 @@ trait GenJSExports extends SubComponent { self: GenJSCode => // we just check the parameter list length. val (getter, setters) = alts.partition(_.tpe.params.isEmpty) - // if we have more than one getter, something went horribly wrong - assert(getter.size <= 1, - s"Found more than one getter to export for name ${jsName}.") + // We can have at most one getter + if (getter.size > 1) { + /* Member export of properties should be caught earlier, so if we get + * here with a non-static export, something went horribly wrong. + */ + assert(static, + s"Found more than one instance getter to export for name $jsName.") + for (duplicate <- getter.tail) { + reporter.error(duplicate.pos, + s"Duplicate static getter export with name '$jsName'") + } + } val getterBody = getter.headOption.map(genApplyForSym(minArgc = 0, - hasRestParam = false, _, static = false)) + hasRestParam = false, _, static)) val setterArgAndBody = { if (setters.isEmpty) { @@ -347,18 +377,19 @@ trait GenJSExports extends SubComponent { self: GenJSCode => val arg = genFormalArg(1) val body = genExportSameArgc(minArgc = 1, hasRestParam = false, alts = setters.map(ExportedSymbol), paramIndex = 0, - static = false) + static = static) Some((arg, body)) } } - js.PropertyDef(js.StringLiteral(jsName), getterBody, setterArgAndBody) + js.PropertyDef(static, js.StringLiteral(jsName), getterBody, + setterArgAndBody) } /** generates the exporter function (i.e. exporter for non-properties) for * a given name */ private def genExportMethod(alts0: List[Exported], jsName: String, - static: Boolean = false) = { + static: Boolean): js.MethodDef = { assert(alts0.nonEmpty, "need at least one alternative to generate exporter method") diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala index 9de0c1d4f4..6d5ef1fc8b 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala @@ -377,10 +377,6 @@ trait PrepJSExports { this: PrepJSInterop => "Implementation restriction: cannot export a class or " + "object as static") } - } else if (!sym.isAccessor && jsInterop.isJSProperty(sym)) { - reporter.error(annot.pos, - "Implementation restriction: cannot export a getter or a " + - "setter as static") } } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportASTTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportASTTest.scala index 8f5f85a1f8..102eaa03a4 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportASTTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportASTTest.scala @@ -24,7 +24,7 @@ class JSExportASTTest extends JSASTTest { override def foo = 2 } """.hasExactly(1, "definitions of property `foo`") { - case js.PropertyDef(js.StringLiteral("foo"), _, _) => + case js.PropertyDef(_, js.StringLiteral("foo"), _, _) => } } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index 6cf34a9b6e..7388db3806 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -1421,60 +1421,86 @@ class JSExportTest extends DirectTest with TestHelpers { } @Test - def noExportStaticGetter: Unit = { + def noExportSetterWithBadSetterType: Unit = { """ @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @JSExportStatic - def a: Int = 1 + def a_=(x: Int, y: Int): Unit = () } """ hasErrors """ - |newSource1.scala:7: error: Implementation restriction: cannot export a getter or a setter as static + |newSource1.scala:7: error: Exported setters must have exactly one argument | @JSExportStatic | ^ """ } @Test - def noExportStaticSetter: Unit = { + def noExportStaticCollapsingMethods: Unit = { """ @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @JSExportStatic - def a_=(x: Int): Unit = () + def foo(x: Int): Int = x + + @JSExportStatic("foo") + def bar(x: Int): Int = x + 1 } """ hasErrors """ - |newSource1.scala:7: error: Implementation restriction: cannot export a getter or a setter as static - | @JSExportStatic - | ^ + |newSource1.scala:11: error: Cannot disambiguate overloads for exported method bar with types + | (x: Int)Int + | (x: Int)Int + | def bar(x: Int): Int = x + 1 + | ^ """ } @Test - def noExportStaticCollapsingMethods: Unit = { + def noExportStaticCollapsingGetters: Unit = { """ @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @JSExportStatic - def foo(x: Int): Int = x + def foo: Int = 1 @JSExportStatic("foo") - def bar(x: Int): Int = x + 1 + def bar: Int = 2 } """ hasErrors """ - |newSource1.scala:11: error: Cannot disambiguate overloads for exported method bar with types - | (x: Int)Int - | (x: Int)Int - | def bar(x: Int): Int = x + 1 + |newSource1.scala:8: error: Duplicate static getter export with name 'foo' + | def foo: Int = 1 + | ^ + """ + } + + @Test + def noExportStaticCollapsingSetters: Unit = { + """ + @ScalaJSDefined + class StaticContainer extends js.Object + + object StaticContainer { + @JSExportStatic + def foo_=(v: Int): Unit = () + + @JSExportStatic("foo") + def bar_=(v: Int): Unit = () + } + """ hasErrors + """ + |newSource1.scala:11: error: Cannot disambiguate overloads for exported method bar_$eq with types + | (v: Int)Unit + | (v: Int)Unit + | def bar_=(v: Int): Unit = () | ^ """ } @@ -1539,6 +1565,84 @@ class JSExportTest extends DirectTest with TestHelpers { """ } + @Test + def noExportStaticFieldsAndPropertiesWithSameName: Unit = { + """ + @ScalaJSDefined + class StaticContainer extends js.Object + + object StaticContainer { + @JSExportStatic + val a: Int = 1 + + @JSExportStatic("a") + def b: Int = 2 + } + """ hasErrors + """ + |newSource1.scala:10: error: Duplicate static export with name 'a': a field may not share its exported name with another field or method + | @JSExportStatic("a") + | ^ + """ + + """ + @ScalaJSDefined + class StaticContainer extends js.Object + + object StaticContainer { + @JSExportStatic + def a: Int = 1 + + @JSExportStatic("a") + val b: Int = 2 + } + """ hasErrors + """ + |newSource1.scala:7: error: Duplicate static export with name 'a': a field may not share its exported name with another field or method + | @JSExportStatic + | ^ + """ + } + + @Test + def noExportStaticPropertiesAndMethodsWithSameName: Unit = { + """ + @ScalaJSDefined + class StaticContainer extends js.Object + + object StaticContainer { + @JSExportStatic + def a: Int = 1 + + @JSExportStatic("a") + def b(x: Int): Int = x + 1 + } + """ hasErrors + """ + |newSource1.scala:8: error: Exported property a conflicts with b + | def a: Int = 1 + | ^ + """ + + """ + @ScalaJSDefined + class StaticContainer extends js.Object + + object StaticContainer { + @JSExportStatic + def a(x: Int): Int = x + 1 + + @JSExportStatic("a") + def b: Int = 1 + } + """ hasErrors + """ + |newSource1.scala:8: error: Exported method a conflicts with b + | def a(x: Int): Int = x + 1 + | ^ + """ + } + @Test def noExportStaticNonStatic: Unit = { """ diff --git a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala index 7ed0e4adcb..02615ae4f7 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala @@ -386,6 +386,7 @@ object Infos { def generatePropertyInfo(propertyDef: PropertyDef): MethodInfo = { builder .setEncodedName(propertyDef.name.name) + .setIsStatic(propertyDef.static) .setIsExported(true) propertyDef.getterBody.foreach(traverse) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index 3820e47017..b9c18442e5 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -827,8 +827,10 @@ object Printers { printBlock(body) } - case PropertyDef(name, getterBody, setterArgAndBody) => + case PropertyDef(static, name, getterBody, setterArgAndBody) => getterBody foreach { body => + if (static) + print("static ") print("get ") print(name) printSig(Nil, AnyType) @@ -840,6 +842,8 @@ object Printers { } setterArgAndBody foreach { case (arg, body) => + if (static) + print("static ") print("set ") print(name) printSig(arg :: Nil, NoType) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index 0d5389be99..7103101798 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -444,8 +444,9 @@ object Serializers { writeInt(length) bufferUnderlying.continue() - case PropertyDef(name, getter, setterArgAndBody) => + case PropertyDef(static, name, getter, setterArgAndBody) => writeByte(TagPropertyDef) + writeBoolean(static) writePropertyName(name) writeOptTree(getter) writeBoolean(setterArgAndBody.isDefined) @@ -872,7 +873,11 @@ object Serializers { } else { result2 } + case TagPropertyDef => + val static = + if (useHacks0614) false + else readBoolean() val name = readPropertyName() val getterBody = readOptTree() val setterArgAndBody = if (useHacks068) { @@ -884,8 +889,7 @@ object Serializers { else None } - - PropertyDef(name, getterBody, setterArgAndBody) + PropertyDef(static, name, getterBody, setterArgAndBody) case TagConstructorExportDef => val result = ConstructorExportDef(readString(), readParamDefs(), readTree()) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala index 5818a91abd..0ea5b816f9 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala @@ -217,8 +217,9 @@ object Transformers { MethodDef(static, name, args, resultType, body.map(transformStat))( tree.optimizerHints, None) - case PropertyDef(name, getterBody, setterArgAndBody) => + case PropertyDef(static, name, getterBody, setterArgAndBody) => PropertyDef( + static, name, getterBody.map(transformStat), setterArgAndBody map { case (arg, body) => diff --git a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala index 4e9849df78..9c62ad5f86 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala @@ -195,7 +195,7 @@ object Traversers { case MethodDef(static, name, args, resultType, body) => body.foreach(traverse) - case PropertyDef(name, getterBody, setterArgAndBody) => + case PropertyDef(static, name, getterBody, setterArgAndBody) => getterBody.foreach(traverse) setterArgAndBody foreach { case (_, body) => traverse(body) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 7c70a1c6de..15302c2096 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -793,8 +793,8 @@ object Trees { val tpe = NoType } - case class PropertyDef(name: PropertyName, getterBody: Option[Tree], - setterArgAndBody: Option[(ParamDef, Tree)])( + case class PropertyDef(static: Boolean, name: PropertyName, + getterBody: Option[Tree], setterArgAndBody: Option[(ParamDef, Tree)])( implicit val pos: Position) extends Tree { val tpe = NoType } diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala index 23cb79a617..57e6416a2e 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala @@ -1010,37 +1010,43 @@ class PrintersTest { } @Test def printPropertyDef(): Unit = { - assertPrintEquals( - """ - |get "prop"(): any = { - | 5 - |} - """, - PropertyDef(StringLiteral("prop"), Some(i(5)), None)) - - assertPrintEquals( - """ - |set "prop"(x: any) { - | 7 - |} - """, - PropertyDef(StringLiteral("prop"), - None, - Some((ParamDef("x", AnyType, mutable = false, rest = false), i(7))))) - - assertPrintEquals( - """ - |get "prop"(): any = { - | 5 - |} - |set "prop"(x: any) { - | 7 - |} - """, - PropertyDef(StringLiteral("prop"), - Some(i(5)), - Some((ParamDef("x", AnyType, mutable = false, rest = false), - i(7))))) + for (static <- Seq(false, true)) { + val staticStr = + if (static) "static " + else "" + + assertPrintEquals( + s""" + |${staticStr}get "prop"(): any = { + | 5 + |} + """, + PropertyDef(static, StringLiteral("prop"), Some(i(5)), None)) + + assertPrintEquals( + s""" + |${staticStr}set "prop"(x: any) { + | 7 + |} + """, + PropertyDef(static, StringLiteral("prop"), + None, + Some((ParamDef("x", AnyType, mutable = false, rest = false), i(7))))) + + assertPrintEquals( + s""" + |${staticStr}get "prop"(): any = { + | 5 + |} + |${staticStr}set "prop"(x: any) { + | 7 + |} + """, + PropertyDef(static, StringLiteral("prop"), + Some(i(5)), + Some((ParamDef("x", AnyType, mutable = false, rest = false), + i(7))))) + } } @Test def printConstructorExportDef(): Unit = { diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index d966946eb5..4f7393444c 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -17,6 +17,18 @@ object BinaryIncompatibilities { ProblemFilters.exclude[IncompatibleResultTypeProblem]( "org.scalajs.core.ir.Trees#FieldDef.copy$default$3"), + // Breaking: PropertyDef has new field `static` + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.ir.Trees#PropertyDef.this"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.ir.Trees#PropertyDef.apply"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.ir.Trees#PropertyDef.copy"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.core.ir.Trees#PropertyDef.copy$default$1"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.core.ir.Trees#PropertyDef.copy$default$2"), + // Breaking: TopLevelExportDef has been renamed to TopLevelMethodExportDef ProblemFilters.exclude[MissingClassProblem]( "org.scalajs.core.ir.Trees$TopLevelExportDef"), diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala index 1389c5190f..2e3767836f 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala @@ -126,6 +126,66 @@ class JSExportStaticTest { assertEquals(6, obj.alsoExistsAsMember(3)) } + // Properties + + @Test def basic_static_prop_readonly(): Unit = { + val statics = js.constructorOf[JSExportStaticTest.StaticExportProperties] + + assertEquals(1, statics.basicReadOnly) + } + + @Test def basic_static_prop_readwrite(): Unit = { + val statics = js.constructorOf[JSExportStaticTest.StaticExportProperties] + + assertEquals(5, statics.basicReadWrite) + statics.basicReadWrite = 10 + assertEquals(15, statics.basicReadWrite) + } + + @Test def static_prop_set_wrong_type_throws_classcastexception(): Unit = { + assumeTrue("assuming compliant asInstanceOfs", hasCompliantAsInstanceOfs) + + val statics = js.constructorOf[JSExportStaticTest.StaticExportProperties] + + assertThrows(classOf[ClassCastException], { + statics.basicReadWrite = "wrong type" + }) + } + + @Test def overloaded_static_prop_setter(): Unit = { + val statics = js.constructorOf[JSExportStaticTest.StaticExportProperties] + + assertEquals("got: ", statics.overloadedSetter) + statics.overloadedSetter = "foo" + assertEquals("got: foo", statics.overloadedSetter) + statics.overloadedSetter = 5 + assertEquals("got: foo10", statics.overloadedSetter) + } + + @Test def overloaded_static_prop_renamed(): Unit = { + val statics = js.constructorOf[JSExportStaticTest.StaticExportProperties] + + assertEquals(5, statics.renamed) + statics.renamed = 10 + assertEquals(15, statics.renamed) + statics.renamed = "foobar" + assertEquals(21, statics.renamed) + } + + @Test def static_prop_constructor(): Unit = { + val statics = js.constructorOf[JSExportStaticTest.StaticExportProperties] + + assertEquals(102, statics.constructor) + } + + @Test def static_prop_also_exists_in_member(): Unit = { + val statics = js.constructorOf[JSExportStaticTest.StaticExportProperties] + assertEquals("also a member", statics.alsoExistsAsMember) + + val obj = new JSExportStaticTest.StaticExportProperties + assertEquals(54, obj.alsoExistsAsMember) + } + // Fields @Test def basic_field(): Unit = { @@ -286,6 +346,52 @@ object JSExportStaticTest { def alsoExistsAsMember(x: Int): Int = x * 5 } + @ScalaJSDefined + class StaticExportProperties extends js.Object { + def alsoExistsAsMember: Int = 54 + } + + object StaticExportProperties { + @JSExportStatic + def basicReadOnly: Int = 1 + + private var basicVar: Int = 5 + + @JSExportStatic + def basicReadWrite: Int = basicVar + + @JSExportStatic + def basicReadWrite_=(v: Int): Unit = basicVar += v + + private var overloadedSetterVar: String = "" + + @JSExportStatic + def overloadedSetter: String = "got: " + overloadedSetterVar + + @JSExportStatic + def overloadedSetter_=(x: String): Unit = overloadedSetterVar += x + + @JSExportStatic + def overloadedSetter_=(x: Int): Unit = overloadedSetterVar += 2 * x + + private var renamedPropVar: Int = 5 + + @JSExportStatic("renamed") + def renamedProp: Int = renamedPropVar + + @JSExportStatic("renamed") + def renamedProp_=(v: Int): Unit = renamedPropVar += v + + @JSExportStatic("renamed") + def renamedOverload_=(x: String): Unit = renamedPropVar += x.length + + @JSExportStatic + def constructor: Int = 102 + + @JSExportStatic + def alsoExistsAsMember: String = "also a member" + } + @ScalaJSDefined class StaticExportFields extends js.Object { val alsoExistsAsMember: Int = 5 diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala index 5c0ada193c..c74b7f085b 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala @@ -109,7 +109,7 @@ final class ClosureLinkerBackend( def exportName(tree: Tree): String = (tree: @unchecked) match { case MethodDef(_, StringLiteral(name), _, _, _) => name - case PropertyDef(StringLiteral(name), _, _) => name + case PropertyDef(_, StringLiteral(name), _, _) => name } val exportedPropertyNames = for { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala index 5d635c900f..daed4086d4 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala @@ -445,7 +445,10 @@ private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, genIdentBracketSelect(js.VarRef(js.Ident("Object")), "defineProperty") // class prototype - val proto = encodeClassVar(className).prototype + val classVar = encodeClassVar(className) + val targetObject = + if (property.static) classVar + else classVar.prototype // property name val name = property.name match { @@ -477,27 +480,28 @@ private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, List(js.StringLiteral("configurable") -> js.BooleanLiteral(true)) ) - js.Apply(defProp, proto :: name :: descriptor :: Nil) + js.Apply(defProp, targetObject :: name :: descriptor :: Nil) } private def genPropertyES6(className: String, property: PropertyDef)( implicit globalKnowledge: GlobalKnowledge): js.Tree = { implicit val pos = property.pos + val static = property.static val propName = genPropertyName(property.name) val getter = property.getterBody.fold[js.Tree] { js.Skip() } { body => val fun = desugarToFunction(className, Nil, body, isStat = false) - js.GetterDef(static = false, propName, fun.body) + js.GetterDef(static, propName, fun.body) } val setter = property.setterArgAndBody.fold[js.Tree] { js.Skip() } { case (arg, body) => val fun = desugarToFunction(className, arg :: Nil, body, isStat = true) - js.SetterDef(static = false, propName, fun.args.head, fun.body) + js.SetterDef(static, propName, fun.args.head, fun.body) } js.Block(getter, setter) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index effd9096fa..7a1b20cb43 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -387,7 +387,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { private def checkExportedPropertyDef(propDef: PropertyDef, classDef: LinkedClass): Unit = withPerMethodState { - val PropertyDef(_, getterBody, setterArgAndBody) = propDef + val PropertyDef(static, _, getterBody, setterArgAndBody) = propDef implicit val ctx = ErrorContext(propDef) if (!classDef.kind.isAnyScalaJSDefinedClass) { @@ -396,7 +396,8 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { } val thisType = - if (classDef.kind.isJSClass) AnyType + if (static) NoType + else if (classDef.kind.isJSClass) AnyType else ClassType(classDef.name.name) getterBody.foreach { getterBody => diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index be5b4fbd84..096fafc98d 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -207,7 +207,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions } def linkedProperty(p: PropertyDef) = { - val info = memberInfoByStaticAndName((false, p.name.name)) + val info = memberInfoByStaticAndName((p.static, p.name.name)) new LinkedMember(info, p, None) } From 12018f0285ca3b339bfd49d74b86cca619b91c71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 13 Jan 2017 18:47:11 +0100 Subject: [PATCH 0100/2665] Fix #2721: Better error message in testHtml{Fast,Full}Opt. --- .../scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 9375c56b3e..1a0813c9a3 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -841,7 +841,8 @@ object ScalaJSPluginInternal { jsdepsKey: TaskKey[File]) = { testHtmlKey := { if ((skip in jsdepsKey).value) { - sys.error(s"(skip in $jsdepsKey) must be false for $testHtmlKey.") + throw new MessageOnlyException( + s"(skip in ${jsdepsKey.key}) must be false for ${testHtmlKey.key}.") } val log = streams.value.log From 730dc2d86b55147d0897a995b1be4c98a5564b7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 16 Jan 2017 17:52:05 +0100 Subject: [PATCH 0101/2665] Add some missing constants in boxed number and character classes. This is only for completeness of the source code, because these constants are never actually used by the compiler: it constant-folds values from the classfiles instead. --- javalanglib/src/main/scala/java/lang/Byte.scala | 1 + javalanglib/src/main/scala/java/lang/Character.scala | 1 + javalanglib/src/main/scala/java/lang/Double.scala | 2 ++ javalanglib/src/main/scala/java/lang/Float.scala | 2 ++ javalanglib/src/main/scala/java/lang/Short.scala | 1 + 5 files changed, 7 insertions(+) diff --git a/javalanglib/src/main/scala/java/lang/Byte.scala b/javalanglib/src/main/scala/java/lang/Byte.scala index dc0c82fc0b..ad902cd479 100644 --- a/javalanglib/src/main/scala/java/lang/Byte.scala +++ b/javalanglib/src/main/scala/java/lang/Byte.scala @@ -35,6 +35,7 @@ final class Byte private () extends Number with Comparable[Byte] { object Byte { final val TYPE = classOf[scala.Byte] final val SIZE = 8 + final val BYTES = 1 /* MIN_VALUE and MAX_VALUE should be 'final val's. But it is impossible to * write a proper Byte literal in Scala, that would both considered a Byte diff --git a/javalanglib/src/main/scala/java/lang/Character.scala b/javalanglib/src/main/scala/java/lang/Character.scala index 7b68e6d2a4..6d8bf062e4 100644 --- a/javalanglib/src/main/scala/java/lang/Character.scala +++ b/javalanglib/src/main/scala/java/lang/Character.scala @@ -164,6 +164,7 @@ object Character { final val MIN_VALUE = '\u0000' final val MAX_VALUE = '\uffff' final val SIZE = 16 + final val BYTES = 2 def valueOf(charValue: scala.Char): Character = new Character(charValue) diff --git a/javalanglib/src/main/scala/java/lang/Double.scala b/javalanglib/src/main/scala/java/lang/Double.scala index 5a35383d0f..b7e561e4f0 100644 --- a/javalanglib/src/main/scala/java/lang/Double.scala +++ b/javalanglib/src/main/scala/java/lang/Double.scala @@ -51,10 +51,12 @@ object Double { final val NEGATIVE_INFINITY = 1.0 / -0.0 final val NaN = 0.0 / 0.0 final val MAX_VALUE = scala.Double.MaxValue + final val MIN_NORMAL = 2.2250738585072014e-308 final val MIN_VALUE = scala.Double.MinPositiveValue final val MAX_EXPONENT = 1023 final val MIN_EXPONENT = -1022 final val SIZE = 64 + final val BYTES = 8 @inline def valueOf(doubleValue: scala.Double): Double = new Double(doubleValue) diff --git a/javalanglib/src/main/scala/java/lang/Float.scala b/javalanglib/src/main/scala/java/lang/Float.scala index f89ef34aa3..1108c0cb26 100644 --- a/javalanglib/src/main/scala/java/lang/Float.scala +++ b/javalanglib/src/main/scala/java/lang/Float.scala @@ -50,10 +50,12 @@ object Float { final val NEGATIVE_INFINITY = 1.0f / -0.0f final val NaN = 0.0f / 0.0f final val MAX_VALUE = scala.Float.MaxValue + final val MIN_NORMAL = 1.17549435e-38f final val MIN_VALUE = scala.Float.MinPositiveValue final val MAX_EXPONENT = 127 final val MIN_EXPONENT = -126 final val SIZE = 32 + final val BYTES = 4 @inline def valueOf(floatValue: scala.Float): Float = new Float(floatValue) diff --git a/javalanglib/src/main/scala/java/lang/Short.scala b/javalanglib/src/main/scala/java/lang/Short.scala index 135fe12793..f7a6e98362 100644 --- a/javalanglib/src/main/scala/java/lang/Short.scala +++ b/javalanglib/src/main/scala/java/lang/Short.scala @@ -34,6 +34,7 @@ final class Short private () extends Number with Comparable[Short] { object Short { final val TYPE = classOf[scala.Short] final val SIZE = 16 + final val BYTES = 2 /* MIN_VALUE and MAX_VALUE should be 'final val's. But it is impossible to * write a proper Short literal in Scala, that would both considered a Short From c8447584d599da6b4d47ebefab3f3b5d8783861a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 16 Jan 2017 17:53:26 +0100 Subject: [PATCH 0102/2665] Fix #2738: Implement Float and Double methods from JDK8. * `hashCode` * `isFinite` * `max` * `min` * `sum` * and `toHexString` (actually this one is from JDK5) --- .../src/main/scala/java/lang/Double.scala | 72 ++++++++++++++++++- .../src/main/scala/java/lang/Float.scala | 69 ++++++++++++++++-- .../javalib/lang/DoubleTestJDK8.scala | 72 +++++++++++++++++++ .../javalib/lang/FloatTestJDK8.scala | 71 ++++++++++++++++++ .../testsuite/javalib/lang/DoubleTest.scala | 22 ++++++ .../testsuite/javalib/lang/FloatTest.scala | 22 ++++++ 6 files changed, 322 insertions(+), 6 deletions(-) create mode 100644 test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/DoubleTestJDK8.scala create mode 100644 test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/FloatTestJDK8.scala diff --git a/javalanglib/src/main/scala/java/lang/Double.scala b/javalanglib/src/main/scala/java/lang/Double.scala index b7e561e4f0..31a444c66a 100644 --- a/javalanglib/src/main/scala/java/lang/Double.scala +++ b/javalanglib/src/main/scala/java/lang/Double.scala @@ -29,7 +29,7 @@ final class Double private () extends Number with Comparable[Double] { } @inline override def hashCode(): Int = - scala.scalajs.runtime.Bits.numberHashCode(doubleValue) + Double.hashCode(doubleValue) @inline override def compareTo(that: Double): Int = Double.compare(doubleValue, that.doubleValue) @@ -84,6 +84,61 @@ object Double { @inline def toString(d: scala.Double): String = "" + d + def toHexString(d: scala.Double): String = { + val ebits = 11 // exponent size + val mbits = 52 // mantissa size + val bias = (1 << (ebits - 1)) - 1 + + val bits = doubleToLongBits(d) + val s = bits < 0 + val m = bits & ((1L << mbits) - 1L) + val e = (bits >>> mbits).toInt & ((1 << ebits) - 1) // biased + + val posResult = if (e > 0) { + if (e == (1 << ebits) - 1) { + // Special + if (m != 0L) "NaN" + else "Infinity" + } else { + // Normalized + "0x1." + mantissaToHexString(m) + "p" + (e - bias) + } + } else { + if (m != 0L) { + // Subnormal + "0x0." + mantissaToHexString(m) + "p-1022" + } else { + // Zero + "0x0.0p0" + } + } + + if (bits < 0) "-" + posResult else posResult + } + + @inline + private def mantissaToHexString(m: scala.Long): String = + mantissaToHexStringLoHi(m.toInt, (m >>> 32).toInt) + + private def mantissaToHexStringLoHi(lo: Int, hi: Int): String = { + @inline def padHex5(i: Int): String = { + val s = Integer.toHexString(i) + "00000".substring(s.length) + s // 5 zeros + } + + @inline def padHex8(i: Int): String = { + val s = Integer.toHexString(i) + "00000000".substring(s.length) + s // 8 zeros + } + + val padded = padHex5(hi) + padHex8(lo) + + var len = padded.length + while (len > 1 && padded.charAt(len - 1) == '0') + len -= 1 + padded.substring(0, len) + } + def compare(a: scala.Double, b: scala.Double): scala.Int = { // NaN must equal itself, and be greater than anything else if (isNaN(a)) { @@ -115,9 +170,24 @@ object Double { @inline def isInfinite(v: scala.Double): scala.Boolean = v == POSITIVE_INFINITY || v == NEGATIVE_INFINITY + @inline def isFinite(d: scala.Double): scala.Boolean = + !isNaN(d) && !isInfinite(d) + + @inline def hashCode(value: scala.Double): Int = + scala.scalajs.runtime.Bits.numberHashCode(value) + @inline def longBitsToDouble(bits: scala.Long): scala.Double = scala.scalajs.runtime.Bits.longBitsToDouble(bits) @inline def doubleToLongBits(value: scala.Double): scala.Long = scala.scalajs.runtime.Bits.doubleToLongBits(value) + + @inline def sum(a: scala.Double, b: scala.Double): scala.Double = + a + b + + @inline def max(a: scala.Double, b: scala.Double): scala.Double = + Math.max(a, b) + + @inline def min(a: scala.Double, b: scala.Double): scala.Double = + Math.min(a, b) } diff --git a/javalanglib/src/main/scala/java/lang/Float.scala b/javalanglib/src/main/scala/java/lang/Float.scala index 1108c0cb26..791ed35089 100644 --- a/javalanglib/src/main/scala/java/lang/Float.scala +++ b/javalanglib/src/main/scala/java/lang/Float.scala @@ -26,9 +26,8 @@ final class Float private () extends Number with Comparable[Float] { false } - // Uses the hashCode of Doubles. See Bits.numberHashCode for the rationale. @inline override def hashCode(): Int = - scala.scalajs.runtime.Bits.numberHashCode(doubleValue) + Float.hashCode(floatValue) @inline override def compareTo(that: Float): Int = Float.compare(floatValue, that.floatValue) @@ -67,21 +66,81 @@ object Float { @inline def toString(f: scala.Float): String = "" + f + def toHexString(f: scala.Float): String = { + val ebits = 8 // exponent size + val mbits = 23 // mantissa size + val bias = (1 << (ebits - 1)) - 1 + + val bits = floatToIntBits(f) + val s = bits < 0 + val m = bits & ((1 << mbits) - 1) + val e = (bits >>> mbits).toInt & ((1 << ebits) - 1) // biased + + val posResult = if (e > 0) { + if (e == (1 << ebits) - 1) { + // Special + if (m != 0) "NaN" + else "Infinity" + } else { + // Normalized + "0x1." + mantissaToHexString(m) + "p" + (e - bias) + } + } else { + if (m != 0) { + // Subnormal + "0x0." + mantissaToHexString(m) + "p-126" + } else { + // Zero + "0x0.0p0" + } + } + + if (bits < 0) "-" + posResult else posResult + } + + @inline + private def mantissaToHexString(m: Int): String = { + @inline def padHex6(i: Int): String = { + val s = Integer.toHexString(i) + "000000".substring(s.length) + s // 6 zeros + } + + // The << 1 turns `m` from a 23-bit int into a 24-bit int (multiple of 4) + val padded = padHex6(m << 1) + var len = padded.length + while (len > 1 && padded.charAt(len - 1) == '0') + len -= 1 + padded.substring(0, len) + } + @inline def compare(a: scala.Float, b: scala.Float): scala.Int = Double.compare(a, b) - @inline protected def equals(a: scala.Float, b: scala.Float): scala.Boolean = - a == b || (isNaN(a) && isNaN(b)) - @inline def isNaN(v: scala.Float): scala.Boolean = v != v @inline def isInfinite(v: scala.Float): scala.Boolean = v == POSITIVE_INFINITY || v == NEGATIVE_INFINITY + @inline def isFinite(f: scala.Float): scala.Boolean = + !isNaN(f) && !isInfinite(f) + + // Uses the hashCode of Doubles. See Bits.numberHashCode for the rationale. + @inline def hashCode(value: scala.Float): Int = + scala.scalajs.runtime.Bits.numberHashCode(value) + @inline def intBitsToFloat(bits: scala.Int): scala.Float = scala.scalajs.runtime.Bits.intBitsToFloat(bits) @inline def floatToIntBits(value: scala.Float): scala.Int = scala.scalajs.runtime.Bits.floatToIntBits(value) + + @inline def sum(a: scala.Float, b: scala.Float): scala.Float = + a + b + + @inline def max(a: scala.Float, b: scala.Float): scala.Float = + Math.max(a, b) + + @inline def min(a: scala.Float, b: scala.Float): scala.Float = + Math.min(a, b) } diff --git a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/DoubleTestJDK8.scala b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/DoubleTestJDK8.scala new file mode 100644 index 0000000000..cfb996ebd0 --- /dev/null +++ b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/DoubleTestJDK8.scala @@ -0,0 +1,72 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package scalajs.testsuite.javalib.lang + +import org.junit.Test +import org.junit.Assert._ +import org.junit.Assume._ + +import org.scalajs.testsuite.utils.Platform.executingInJVM + +import java.lang.{Double => JDouble} + +class DoubleTestJDK8 { + + @Test def isFinite(): Unit = { + assertFalse(JDouble.isFinite(Double.PositiveInfinity)) + assertFalse(JDouble.isFinite(Double.NegativeInfinity)) + assertFalse(JDouble.isFinite(Double.NaN)) + assertFalse(JDouble.isFinite(1d/0)) + assertFalse(JDouble.isFinite(-1d/0)) + + assertTrue(JDouble.isFinite(0d)) + assertTrue(JDouble.isFinite(1d)) + assertTrue(JDouble.isFinite(123456d)) + assertTrue(JDouble.isFinite(Double.MinValue)) + assertTrue(JDouble.isFinite(Double.MaxValue)) + assertTrue(JDouble.isFinite(Double.MinPositiveValue)) + } + + @Test def staticHashCodeTest(): Unit = { + assumeFalse("Hash codes for doubles are different in JS than on the JVM", + executingInJVM) + + def test(x: Double, expected: Int): Unit = + assertEquals(expected, JDouble.hashCode(x)) + + test(0.0, 0) + test(-0.0, -2147483648) + test(1234.0, 1234) + test(1.5, 1073217536) + test(Math.PI, 340593891) + test(-54.0, -54) + + test(Double.MinPositiveValue, 1) + test(Double.MinValue, 1048576) + test(Double.MaxValue, -2146435072) + + test(Double.NaN, 2146959360) + test(Double.PositiveInfinity, 2146435072) + test(Double.NegativeInfinity, -1048576) + } + + // The following tests are only to make sure that things link + + @Test def sum(): Unit = { + assertEquals(12d, JDouble.sum(5d, 7d), 0d) + } + + @Test def max(): Unit = { + assertEquals(7d, JDouble.max(5d, 7d), 0d) + } + + @Test def min(): Unit = { + assertEquals(5d, JDouble.min(5d, 7d), 0d) + } + +} diff --git a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/FloatTestJDK8.scala b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/FloatTestJDK8.scala new file mode 100644 index 0000000000..c6307b8da2 --- /dev/null +++ b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/FloatTestJDK8.scala @@ -0,0 +1,71 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package scalajs.testsuite.javalib.lang + +import org.junit.Test +import org.junit.Assert._ +import org.junit.Assume._ + +import org.scalajs.testsuite.utils.Platform.executingInJVM + +import java.lang.{Float => JFloat} + +class FloatTestJDK8 { + + @Test def isFinite(): Unit = { + assertFalse(JFloat.isFinite(Float.PositiveInfinity)) + assertFalse(JFloat.isFinite(Float.NegativeInfinity)) + assertFalse(JFloat.isFinite(Float.NaN)) + assertFalse(JFloat.isFinite(1f/0)) + assertFalse(JFloat.isFinite(-1f/0)) + + assertTrue(JFloat.isFinite(0f)) + assertTrue(JFloat.isFinite(1f)) + assertTrue(JFloat.isFinite(123456f)) + assertTrue(JFloat.isFinite(Float.MinValue)) + assertTrue(JFloat.isFinite(Float.MaxValue)) + assertTrue(JFloat.isFinite(Float.MinPositiveValue)) + } + + @Test def staticHashCodeTest(): Unit = { + assumeFalse("Hash codes for doubles are different in JS than on the JVM", + executingInJVM) + + def test(x: Float, expected: Int): Unit = + assertEquals(expected, JFloat.hashCode(x)) + + test(0.0f, 0) + test(-0.0f, -2147483648) + test(1234.0f, 1234) + test(1.5f, 1073217536) + test(-54.0f, -54) + + test(Float.MinPositiveValue, 916455424) + test(Float.MinValue, 670040063) + test(Float.MaxValue, -1477443585) + + test(Float.NaN, 2146959360) + test(Float.PositiveInfinity, 2146435072) + test(Float.NegativeInfinity, -1048576) + } + + // The following tests are only to make sure that things link + + @Test def sum(): Unit = { + assertEquals(12f, JFloat.sum(5f, 7f), 0f) + } + + @Test def max(): Unit = { + assertEquals(7f, JFloat.max(5f, 7f), 0f) + } + + @Test def min(): Unit = { + assertEquals(5f, JFloat.min(5f, 7f), 0f) + } + +} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/DoubleTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/DoubleTest.scala index 2669527f65..12bf4da068 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/DoubleTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/DoubleTest.scala @@ -76,6 +76,28 @@ class DoubleTest { assertEquals("1.2", 1.2.toString) } + @Test def toHexStringTest(): Unit = { + import java.lang.Double.toHexString + + assertEquals("0x0.0p0", toHexString(0.0)) + assertEquals("-0x0.0p0", toHexString(-0.0)) + assertEquals("NaN", toHexString(Double.NaN)) + assertEquals("Infinity", toHexString(Double.PositiveInfinity)) + assertEquals("-Infinity", toHexString(Double.NegativeInfinity)) + assertEquals("0x1.0p0", toHexString(1.0)) + assertEquals("-0x1.0p0", toHexString(-1.0)) + assertEquals("0x1.0p1", toHexString(2.0)) + assertEquals("0x1.8p1", toHexString(3.0)) + assertEquals("0x1.0p-1", toHexString(0.5)) + assertEquals("0x1.0p-2", toHexString(0.25)) + assertEquals("0x1.00204p3", toHexString(8.003936767578125)) + assertEquals("0x0.00204p-1022", toHexString(1.094949828138e-311)) + assertEquals("0x1.fffffffffffffp1023", toHexString(Double.MaxValue)) + assertEquals("0x1.0p-1022", toHexString(java.lang.Double.MIN_NORMAL)) + assertEquals("0x0.fffffffffffffp-1022", toHexString(2.225073858507201E-308)) + assertEquals("0x0.0000000000001p-1022", toHexString(Double.MinPositiveValue)) + } + @Test def should_parse_strings(): Unit = { assertEquals(0.0, "0.0".toDouble, 0.0) assertTrue("NaN".toDouble.isNaN) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/FloatTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/FloatTest.scala index 032eaa1529..f4a3a359d9 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/FloatTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/FloatTest.scala @@ -79,6 +79,28 @@ class FloatTest { assertEquals("1.2", 1.2f.toString.substring(0,3)) } + @Test def toHexStringTest(): Unit = { + import java.lang.Float.toHexString + + assertEquals("NaN", toHexString(Float.NaN)) + assertEquals("Infinity", toHexString(Float.PositiveInfinity)) + assertEquals("-Infinity", toHexString(Float.NegativeInfinity)) + assertEquals("0x0.0p0", toHexString(0.0f)) + assertEquals("-0x0.0p0", toHexString(-0.0f)) + assertEquals("0x1.0p0", toHexString(1.0f)) + assertEquals("-0x1.0p0", toHexString(-1.0f)) + assertEquals("0x1.0p1", toHexString(2.0f)) + assertEquals("0x1.8p1", toHexString(3.0f)) + assertEquals("0x1.0p-1", toHexString(0.5f)) + assertEquals("0x1.0p-2", toHexString(0.25f)) + assertEquals("0x1.00204p3", toHexString(8.003937f)) + assertEquals("0x0.00204p-126", toHexString(5.785e-42f)) + assertEquals("0x1.fffffep127", toHexString(Float.MaxValue)) + assertEquals("0x1.0p-126", toHexString(java.lang.Float.MIN_NORMAL)) + assertEquals("0x0.fffffep-126", toHexString(1.1754942E-38f)) + assertEquals("0x0.000002p-126", toHexString(Float.MinPositiveValue)) + } + @Test def should_parse_strings(): Unit = { assertEquals(0.0f, "0.0".toFloat, 0.0f) assertTrue("NaN".toFloat.isNaN) From 9e7112fc1afcaa374cdd9497da6eddbcada7538b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 17 Jan 2017 19:29:17 +0100 Subject: [PATCH 0103/2665] Make Rhino run static initializers of otherwise unused classes. Previously, Rhino would only run static initializers of classes that were needed for some other reason. Notably, if they contain field exports, which is so far the only way a Scala class can have a static initializer anyway. This was not causing any issue so far, but the following commit will start emitting static initializers in Scala classes that do not have any export. --- .../scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala index 07b44ae163..73349a7a09 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala @@ -39,8 +39,14 @@ private[rhino] class ScalaJSCoreLib(linkingUnit: LinkingUnit) { val exportedSymbols = mutable.ListBuffer.empty[String] for (linkedClass <- linkingUnit.classDefs) { + def hasStaticInitializer = { + linkedClass.staticMethods.exists { + _.tree.name.name == ir.Definitions.StaticInitializerName + } + } + providers += linkedClass.encodedName -> linkedClass - if (linkedClass.isExported) + if (linkedClass.isExported || hasStaticInitializer) exportedSymbols += linkedClass.encodedName } From a8e1977fd5ad09a0123a7564dcbcb78bbdda0d26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 17 Jan 2017 14:01:45 +0100 Subject: [PATCH 0104/2665] Fix #2733: Implement on-demand reflective instantiation. This commit implements the variant of Proposal #2733 that supports all public constructors. We introduce a new API in `scala.scalajs.reflect` which allows to do some amount of run-time reflection, namely, instantiate classes and load module instances given their fully qualified names. Not all classes are eligible. Only objects and classes that have an ancestor annotated with `@EnableReflectiveInstantiation` can be found and instantiated that way. Moreover, traits, abstract classes, and classes without any public constructors cannot be found either. --- .../org/scalajs/core/compiler/GenJSCode.scala | 129 +++++++- .../scalajs/core/compiler/JSDefinitions.scala | 6 + .../scalajs/core/compiler/PrepJSInterop.scala | 8 + .../core/compiler/test/ReflectTest.scala | 64 ++++ .../scala/scala/scalajs/reflect/Reflect.scala | 102 ++++++ .../EnableReflectiveInstantiation.scala | 16 + .../annotation/ReflectAnnotations.scala | 10 + .../testsuite/library/ReflectTest.scala | 310 ++++++++++++++++++ 8 files changed, 634 insertions(+), 11 deletions(-) create mode 100644 compiler/src/test/scala/org/scalajs/core/compiler/test/ReflectTest.scala create mode 100644 library/src/main/scala/scala/scalajs/reflect/Reflect.scala create mode 100644 library/src/main/scala/scala/scalajs/reflect/annotation/EnableReflectiveInstantiation.scala create mode 100644 stubs/src/main/scala/scala/scalajs/reflect/annotation/ReflectAnnotations.scala create mode 100644 test-suite/js/src/test/scala/org/scalajs/testsuite/library/ReflectTest.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index b7dc48102a..a048ec1707 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -420,19 +420,42 @@ abstract class GenJSCode extends plugins.PluginComponent val topLevelExports = genTopLevelExports(sym) - val needsStaticInitializer = - topLevelExports.exists(_.isInstanceOf[js.TopLevelFieldExportDef]) - val optStaticInitializer = - if (!needsStaticInitializer) Nil - else genStaticInitializerLoadingModule(sym) :: Nil + memberExports ++ exportedConstructorsOrAccessors ++ topLevelExports + } - (memberExports ++ exportedConstructorsOrAccessors ++ topLevelExports ++ - optStaticInitializer) + // Static initializer + val optStaticInitializer = { + // Initialization of reflection data, if required + val reflectInit = { + val enableReflectiveInstantiation = { + (sym :: sym.ancestors).exists { ancestor => + ancestor.hasAnnotation(EnableReflectiveInstantiationAnnotation) + } + } + if (enableReflectiveInstantiation) + genRegisterReflectiveInstantiation(sym) + else + None + } + + // Initialization of the module because of field exports + val needsStaticModuleInit = + exports.exists(_.isInstanceOf[js.TopLevelFieldExportDef]) + val staticModuleInit = + if (!needsStaticModuleInit) None + else Some(genLoadModule(sym)) + + val staticInitializerStats = + reflectInit.toList ::: staticModuleInit.toList + if (staticInitializerStats.nonEmpty) + Some(genStaticInitializerWithStats(js.Block(staticInitializerStats))) + else + None } // Hashed definitions of the class val hashedDefs = - Hashers.hashDefs(generatedMembers ++ exports) + Hashers.hashDefs(generatedMembers ++ exports ++ optStaticInitializer) // The complete class definition val kind = @@ -521,7 +544,7 @@ abstract class GenJSCode extends plugins.PluginComponent } if (exports.exists(_.isInstanceOf[js.FieldDef])) { val staticInitializer = - genStaticInitializerLoadingModule(companionModuleClass) + genStaticInitializerWithStats(genLoadModule(companionModuleClass)) exports :+ staticInitializer } else { exports @@ -920,17 +943,101 @@ abstract class GenJSCode extends plugins.PluginComponent // Static initializers ----------------------------------------------------- - private def genStaticInitializerLoadingModule(sym: Symbol)( + private def genStaticInitializerWithStats(stats: js.Tree)( implicit pos: Position): js.MethodDef = { js.MethodDef( static = true, js.Ident(ir.Definitions.StaticInitializerName), Nil, jstpe.NoType, - Some(genLoadModule(sym)))( + Some(stats))( OptimizerHints.empty, None) } + private def genRegisterReflectiveInstantiation(sym: Symbol)( + implicit pos: Position): Option[js.Tree] = { + if (sym.isModuleClass) + genRegisterReflectiveInstantiationForModuleClass(sym) + else + genRegisterReflectiveInstantiationForNormalClass(sym) + } + + private def genRegisterReflectiveInstantiationForModuleClass(sym: Symbol)( + implicit pos: Position): Option[js.Tree] = { + val fqcnArg = js.StringLiteral(sym.fullName + "$") + val runtimeClassArg = js.ClassOf(toReferenceType(sym.info)) + val loadModuleFunArg = js.Closure(Nil, Nil, genLoadModule(sym), Nil) + + val stat = genApplyMethod( + genLoadModule(ReflectModule), + Reflect_registerLoadableModuleClass, + List(fqcnArg, runtimeClassArg, loadModuleFunArg)) + + Some(stat) + } + + private def genRegisterReflectiveInstantiationForNormalClass(sym: Symbol)( + implicit pos: Position): Option[js.Tree] = { + val ctors = + if (sym.isAbstractClass) Nil + else sym.info.member(nme.CONSTRUCTOR).alternatives.filter(_.isPublic) + + if (ctors.isEmpty) { + None + } else { + val constructorsInfos = for { + ctor <- ctors + } yield { + withNewLocalNameScope { + val (parameterTypes, formalParams, actualParams) = (for { + param <- ctor.tpe.params + } yield { + /* Note that we do *not* use `param.tpe` entering posterasure + * (neither to compute `paramType` nor to give to `fromAny`). + * Logic would tell us that we should do so, but we intentionally + * do not to preserve the behavior on the JVM regarding value + * classes. If a constructor takes a value class as parameter, as + * in: + * + * class ValueClass(val underlying: Int) extends AnyVal + * class Foo(val vc: ValueClass) + * + * then, from a reflection point of view, on the JVM, the + * constructor of `Foo` takes an `Int`, not a `ValueClas`. It + * must therefore be identified as the constructor whose + * parameter types is `List(classOf[Int])`, and when invoked + * reflectively, it must be given an `Int` (or `Integer`). + */ + val paramType = js.ClassOf(toReferenceType(param.tpe)) + val paramDef = js.ParamDef(encodeLocalSym(param), jstpe.AnyType, + mutable = false, rest = false) + val actualParam = fromAny(paramDef.ref, param.tpe) + (paramType, paramDef, actualParam) + }).unzip3 + + val paramTypesArray = js.JSArrayConstr(parameterTypes) + + val newInstanceFun = js.Closure(Nil, formalParams, { + genNew(sym, ctor, actualParams) + }, Nil) + + js.JSArrayConstr(List(paramTypesArray, newInstanceFun)) + } + } + + val fqcnArg = js.StringLiteral(sym.fullName) + val runtimeClassArg = js.ClassOf(toReferenceType(sym.info)) + val ctorsInfosArg = js.JSArrayConstr(constructorsInfos) + + val stat = genApplyMethod( + genLoadModule(ReflectModule), + Reflect_registerInstantiatableClass, + List(fqcnArg, runtimeClassArg, ctorsInfosArg)) + + Some(stat) + } + } + // Constructor of a Scala.js-defined JS class ------------------------------ def genJSClassConstructor(classSym: Symbol, diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 1d8c0e87a6..8b76752b22 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -137,6 +137,12 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val BoxesRunTime_boxToCharacter = getMemberMethod(BoxesRunTimeModule, newTermName("boxToCharacter")) lazy val BoxesRunTime_unboxToChar = getMemberMethod(BoxesRunTimeModule, newTermName("unboxToChar")) + lazy val ReflectModule = getRequiredModule("scala.scalajs.reflect.Reflect") + lazy val Reflect_registerLoadableModuleClass = getMemberMethod(ReflectModule, newTermName("registerLoadableModuleClass")) + lazy val Reflect_registerInstantiatableClass = getMemberMethod(ReflectModule, newTermName("registerInstantiatableClass")) + + lazy val EnableReflectiveInstantiationAnnotation = getRequiredClass("scala.scalajs.reflect.annotation.EnableReflectiveInstantiation") + } // scalastyle:on line.size.limit diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index d7b4b619c4..230e3de89f 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -476,6 +476,14 @@ abstract class PrepJSInterop extends plugins.PluginComponent val isJSNative = !sym.hasAnnotation(ScalaJSDefinedAnnotation) + // Forbid @EnableReflectiveInstantiation on JS types + sym.getAnnotation(EnableReflectiveInstantiationAnnotation).foreach { + annot => + reporter.error(annot.pos, + "@EnableReflectiveInstantiation cannot be used on types " + + "extending js.Any.") + } + if (sym.isPackageObjectClass) { reporter.warning(implDef.pos, "Package objects inheriting from js.Any are deprecated. " + diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/ReflectTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/ReflectTest.scala new file mode 100644 index 0000000000..8301efa2b0 --- /dev/null +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/ReflectTest.scala @@ -0,0 +1,64 @@ +package org.scalajs.core.compiler.test + +import org.scalajs.core.compiler.test.util._ +import org.junit.Test + +// scalastyle:off line.size.limit + +class ReflectTest extends DirectTest with TestHelpers { + + override def preamble: String = + """import scala.scalajs.js, js.annotation._ + import scala.scalajs.reflect.annotation._ + """ + + @Test + def noEnableReflectiveInstantiationOnJSType: Unit = { + """ + @EnableReflectiveInstantiation + @ScalaJSDefined + class A extends js.Object + + @EnableReflectiveInstantiation + @ScalaJSDefined + trait B extends js.Object + + @EnableReflectiveInstantiation + @ScalaJSDefined + object C extends js.Object + + @EnableReflectiveInstantiation + @js.native + class D extends js.Object + + @EnableReflectiveInstantiation + @js.native + trait E extends js.Object + + @EnableReflectiveInstantiation + @js.native + object F extends js.Object + """ hasErrors + """ + |newSource1.scala:4: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. + | @EnableReflectiveInstantiation + | ^ + |newSource1.scala:8: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. + | @EnableReflectiveInstantiation + | ^ + |newSource1.scala:12: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. + | @EnableReflectiveInstantiation + | ^ + |newSource1.scala:16: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. + | @EnableReflectiveInstantiation + | ^ + |newSource1.scala:20: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. + | @EnableReflectiveInstantiation + | ^ + |newSource1.scala:24: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. + | @EnableReflectiveInstantiation + | ^ + """ + } + +} diff --git a/library/src/main/scala/scala/scalajs/reflect/Reflect.scala b/library/src/main/scala/scala/scalajs/reflect/Reflect.scala new file mode 100644 index 0000000000..7dcb217262 --- /dev/null +++ b/library/src/main/scala/scala/scalajs/reflect/Reflect.scala @@ -0,0 +1,102 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js API ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package scala.scalajs.reflect + +import scala.collection.mutable + +import scala.scalajs.js + +final class LoadableModuleClass private[reflect] ( + val runtimeClass: Class[_], + loadModuleFun: js.Function0[Any] +) { + /** Loads the module instance and returns it. */ + def loadModule(): Any = loadModuleFun() +} + +final class InstantiatableClass private[reflect] ( + val runtimeClass: Class[_], + val declaredConstructors: List[InvokableConstructor] +) { + /** Instantiates a new instance of this class using the zero-argument + * constructor. + * + * @throws java.lang.InstantiationException (caused by a + * `NoSuchMethodException`) + * If this class does not have a public zero-argument constructor. + */ + def newInstance(): Any = { + getConstructor().fold[Any] { + throw new InstantiationException(runtimeClass.getName).initCause( + new NoSuchMethodException(runtimeClass.getName + ".()")) + } { ctor => + ctor.newInstance() + } + } + + /** Looks up a public constructor identified by the types of its formal + * parameters. + * + * If no such public constructor exists, returns `None`. + */ + def getConstructor(parameterTypes: Class[_]*): Option[InvokableConstructor] = + declaredConstructors.find(_.parameterTypes.sameElements(parameterTypes)) +} + +final class InvokableConstructor private[reflect] ( + val parameterTypes: List[Class[_]], + newInstanceFun: js.Function +) { + def newInstance(args: Any*): Any = { + /* Check the number of actual arguments. We let the casts and unbox + * operations inside `newInstanceFun` take care of the rest. + */ + require(args.size == parameterTypes.size) + newInstanceFun.asInstanceOf[js.Dynamic].apply( + args.asInstanceOf[Seq[js.Any]]: _*) + } +} + +object Reflect { + /* I would like those val's to be `js.Dictionary`'es instead of full-blown + * Scala Maps. But if I do that, GCC "dead-code"-eliminates away statements + * that fill `loadableModuleClasses`! We fool it into not making a fool of + * itself by using more complicated data structures that it does not + * understand -_-'. + */ + + private val loadableModuleClasses = + mutable.Map.empty[String, LoadableModuleClass] + + private val instantiatableClasses = + mutable.Map.empty[String, InstantiatableClass] + + // `protected[reflect]` makes it public in the IR + protected[reflect] def registerLoadableModuleClass[T]( + fqcn: String, runtimeClass: Class[T], + loadModuleFun: js.Function0[T]): Unit = { + loadableModuleClasses(fqcn) = + new LoadableModuleClass(runtimeClass, loadModuleFun) + } + + protected[reflect] def registerInstantiatableClass[T]( + fqcn: String, runtimeClass: Class[T], + constructors: js.Array[js.Tuple2[js.Array[Class[_]], js.Function]]): Unit = { + val invokableConstructors = constructors.map { c => + new InvokableConstructor(c._1.toList, c._2) + } + instantiatableClasses(fqcn) = + new InstantiatableClass(runtimeClass, invokableConstructors.toList) + } + + def lookupLoadableModuleClass(fqcn: String): Option[LoadableModuleClass] = + loadableModuleClasses.get(fqcn) + + def lookupInstantiatableClass(fqcn: String): Option[InstantiatableClass] = + instantiatableClasses.get(fqcn) +} diff --git a/library/src/main/scala/scala/scalajs/reflect/annotation/EnableReflectiveInstantiation.scala b/library/src/main/scala/scala/scalajs/reflect/annotation/EnableReflectiveInstantiation.scala new file mode 100644 index 0000000000..adb8a4e157 --- /dev/null +++ b/library/src/main/scala/scala/scalajs/reflect/annotation/EnableReflectiveInstantiation.scala @@ -0,0 +1,16 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js API ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package scala.scalajs.reflect.annotation + +/** Enables reflective instantiation for the annotated class, trait or object, + * and all its descendants. + * + * Affected classes can be identified at run-time through methods of + * [[scala.scalajs.reflect.Reflect]]. + */ +class EnableReflectiveInstantiation extends scala.annotation.StaticAnnotation diff --git a/stubs/src/main/scala/scala/scalajs/reflect/annotation/ReflectAnnotations.scala b/stubs/src/main/scala/scala/scalajs/reflect/annotation/ReflectAnnotations.scala new file mode 100644 index 0000000000..56a2a004bc --- /dev/null +++ b/stubs/src/main/scala/scala/scalajs/reflect/annotation/ReflectAnnotations.scala @@ -0,0 +1,10 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js API ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package scala.scalajs.reflect.annotation + +class EnableReflectiveInstantiation extends scala.annotation.Annotation diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ReflectTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ReflectTest.scala new file mode 100644 index 0000000000..f0d83d403a --- /dev/null +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ReflectTest.scala @@ -0,0 +1,310 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.library + +import org.junit.Assert._ +import org.junit.Assume._ +import org.junit.Test + +import org.scalajs.testsuite.utils.AssertThrows._ +import org.scalajs.testsuite.utils.Platform._ + +import scala.scalajs.reflect._ +import scala.scalajs.reflect.annotation._ + +class ReflectTest { + import ReflectTest.{Accessors, VC} + + private final val Prefix = "org.scalajs.testsuite.library.ReflectTest$" + + private final val NameClassEnableDirect = + Prefix + "ClassEnableDirect" + private final val NameClassEnableDirectNoZeroArgCtor = + Prefix + "ClassEnableDirectNoZeroArgCtor" + private final val NameObjectEnableDirect = + Prefix + "ObjectEnableDirect$" + private final val NameTraitEnableDirect = + Prefix + "TraitEnableDirect" + private final val NameAbstractClassEnableDirect = + Prefix + "AbstractClassEnableDirect" + private final val NameClassNoPublicConstructorEnableDirect = + Prefix + "ClassNoPublicConstructorEnableDirect" + + private final val NameClassEnableIndirect = + Prefix + "ClassEnableIndirect" + private final val NameClassEnableIndirectNoZeroArgCtor = + Prefix + "ClassEnableIndirectNoZeroArgCtor" + private final val NameObjectEnableIndirect = + Prefix + "ObjectEnableIndirect$" + private final val NameTraitEnableIndirect = + Prefix + "TraitEnableIndirect" + private final val NameAbstractClassEnableIndirect = + Prefix + "AbstractClassEnableIndirect" + private final val NameClassNoPublicConstructorEnableIndirect = + Prefix + "ClassNoPublicConstructorEnableIndirect" + + private final val NameClassDisable = + Prefix + "ClassDisable" + private final val NameObjectDisable = + Prefix + "ObjectDisable$" + private final val NameTraitDisable = + Prefix + "TraitDisable" + + @Test def testClassRuntimeClass(): Unit = { + for { + name <- Seq(NameClassEnableDirect, NameClassEnableDirectNoZeroArgCtor, + NameClassEnableIndirect, NameClassEnableIndirectNoZeroArgCtor) + } { + val optClassData = Reflect.lookupInstantiatableClass(name) + assertTrue(optClassData.isDefined) + val classData = optClassData.get + + val runtimeClass = optClassData.get.runtimeClass + assertEquals(name, runtimeClass.getName) + } + } + + @Test def testObjectRuntimeClass(): Unit = { + for { + name <- Seq(NameObjectEnableDirect, NameObjectEnableIndirect) + } { + val optClassData = Reflect.lookupLoadableModuleClass(name) + assertTrue(optClassData.isDefined) + val classData = optClassData.get + + val runtimeClass = optClassData.get.runtimeClass + assertEquals(name, runtimeClass.getName) + } + } + + @Test def testClassCannotBeFound(): Unit = { + for { + name <- Seq(NameObjectEnableDirect, NameTraitEnableDirect, + NameAbstractClassEnableDirect, + NameClassNoPublicConstructorEnableDirect, NameObjectEnableIndirect, + NameTraitEnableIndirect, NameAbstractClassEnableIndirect, + NameClassNoPublicConstructorEnableIndirect, NameClassDisable, + NameObjectDisable, NameTraitDisable) + } { + assertFalse(s"$name should not be found", + Reflect.lookupInstantiatableClass(name).isDefined) + } + } + + @Test def testObjectCannotBeFound(): Unit = { + for { + name <- Seq(NameClassEnableDirect, NameClassEnableDirectNoZeroArgCtor, + NameTraitEnableDirect, NameAbstractClassEnableDirect, + NameClassNoPublicConstructorEnableDirect, NameClassEnableIndirect, + NameTraitEnableIndirect, NameAbstractClassEnableIndirect, + NameClassNoPublicConstructorEnableIndirect, NameClassDisable, + NameObjectDisable, NameTraitDisable) + } { + assertFalse(s"$name should not be found", + Reflect.lookupLoadableModuleClass(name).isDefined) + } + } + + @Test def testClassNoArgCtor(): Unit = { + for (name <- Seq(NameClassEnableDirect, NameClassEnableIndirect)) { + val optClassData = Reflect.lookupInstantiatableClass(name) + assertTrue(optClassData.isDefined) + val classData = optClassData.get + + val instance = classData.newInstance().asInstanceOf[Accessors] + assertEquals(-1, instance.x) + assertEquals(name.stripPrefix(Prefix), instance.y) + } + } + + @Test def testClassNoArgCtorErrorCase(): Unit = { + for (name <- Seq(NameClassEnableDirectNoZeroArgCtor, + NameClassEnableIndirectNoZeroArgCtor)) { + val optClassData = Reflect.lookupInstantiatableClass(name) + assertTrue(optClassData.isDefined) + val classData = optClassData.get + + assertThrows(classOf[InstantiationException], { + classData.newInstance() + }) + } + } + + @Test def testClassCtorWithArgs(): Unit = { + for (name <- Seq(NameClassEnableDirect, NameClassEnableDirectNoZeroArgCtor, + NameClassEnableIndirect, NameClassEnableIndirectNoZeroArgCtor)) { + val optClassData = Reflect.lookupInstantiatableClass(name) + assertTrue(optClassData.isDefined) + val classData = optClassData.get + + val optCtorIntString = + classData.getConstructor(classOf[Int], classOf[String]) + assertTrue(optCtorIntString.isDefined) + val instanceIntString = + optCtorIntString.get.newInstance(543, "foobar").asInstanceOf[Accessors] + assertEquals(543, instanceIntString.x) + assertEquals("foobar", instanceIntString.y) + + val optCtorInt = classData.getConstructor(classOf[Int]) + assertTrue(optCtorInt.isDefined) + val instanceInt = + optCtorInt.get.newInstance(123).asInstanceOf[Accessors] + assertEquals(123, instanceInt.x) + assertEquals(name.stripPrefix(Prefix), instanceInt.y) + + // Value class is seen as its underlying + val optCtorShort = classData.getConstructor(classOf[Short]) + assertTrue(optCtorShort.isDefined) + val instanceShort = + optCtorShort.get.newInstance(21).asInstanceOf[Accessors] + assertEquals(42, instanceShort.x) + assertEquals(name.stripPrefix(Prefix), instanceShort.y) + + // Non-existent + assertFalse(classData.getConstructor(classOf[Boolean]).isDefined) + assertFalse(classData.getConstructor(classOf[VC]).isDefined) + + // Non-public + assertFalse(classData.getConstructor(classOf[String]).isDefined) + assertFalse(classData.getConstructor(classOf[Double]).isDefined) + } + } + + @Test def testObjectLoad(): Unit = { + for (name <- Seq(NameObjectEnableDirect, NameObjectEnableIndirect)) { + val optClassData = Reflect.lookupLoadableModuleClass(name) + assertTrue(optClassData.isDefined) + val classData = optClassData.get + + val instance = classData.loadModule().asInstanceOf[Accessors] + assertEquals(101, instance.x) + assertEquals(name.stripPrefix(Prefix), instance.y) + } + } + +} + +object ReflectTest { + trait Accessors { + val x: Int + val y: String + } + + final class VC(val self: Short) extends AnyVal + + // Entities with directly enabled reflection + + @EnableReflectiveInstantiation + class ClassEnableDirect(val x: Int, val y: String) extends Accessors { + def this(x: Int) = this(x, "ClassEnableDirect") + def this() = this(-1) + def this(vc: VC) = this(vc.self.toInt * 2) + + protected def this(y: String) = this(-5, y) + private def this(d: Double) = this(d.toInt) + } + + @EnableReflectiveInstantiation + class ClassEnableDirectNoZeroArgCtor(val x: Int, val y: String) + extends Accessors { + def this(x: Int) = this(x, "ClassEnableDirectNoZeroArgCtor") + def this(vc: VC) = this(vc.self.toInt * 2) + + protected def this(y: String) = this(-5, y) + private def this(d: Double) = this(d.toInt) + } + + @EnableReflectiveInstantiation + object ObjectEnableDirect extends Accessors { + val x = 101 + val y = "ObjectEnableDirect$" + } + + @EnableReflectiveInstantiation + trait TraitEnableDirect extends Accessors + + @EnableReflectiveInstantiation + abstract class AbstractClassEnableDirect(val x: Int, val y: String) + extends Accessors { + + def this(x: Int) = this(x, "AbstractClassEnableDirect") + def this() = this(-1) + def this(vc: VC) = this(vc.self.toInt * 2) + + protected def this(y: String) = this(-5, y) + private def this(d: Double) = this(d.toInt) + } + + @EnableReflectiveInstantiation + class ClassNoPublicConstructorEnableDirect private (val x: Int, val y: String) + extends Accessors { + + protected def this(y: String) = this(-5, y) + } + + // Entities with reflection enabled by inheritance + + @EnableReflectiveInstantiation + trait EnablingTrait + + class ClassEnableIndirect(val x: Int, val y: String) + extends EnablingTrait with Accessors { + + def this(x: Int) = this(x, "ClassEnableIndirect") + def this() = this(-1) + def this(vc: VC) = this(vc.self.toInt * 2) + + protected def this(y: String) = this(-5, y) + private def this(d: Double) = this(d.toInt) + } + + class ClassEnableIndirectNoZeroArgCtor(val x: Int, val y: String) + extends EnablingTrait with Accessors { + def this(x: Int) = this(x, "ClassEnableIndirectNoZeroArgCtor") + def this(vc: VC) = this(vc.self.toInt * 2) + + protected def this(y: String) = this(-5, y) + private def this(d: Double) = this(d.toInt) + } + + object ObjectEnableIndirect extends EnablingTrait with Accessors { + val x = 101 + val y = "ObjectEnableIndirect$" + } + + trait TraitEnableIndirect extends EnablingTrait with Accessors + + abstract class AbstractClassEnableIndirect(val x: Int, val y: String) + extends EnablingTrait with Accessors { + + def this(x: Int) = this(x, "AbstractClassEnableIndirect") + def this() = this(-1) + def this(vc: VC) = this(vc.self.toInt * 2) + + protected def this(y: String) = this(-5, y) + private def this(d: Double) = this(d.toInt) + } + + class ClassNoPublicConstructorEnableIndirect private ( + val x: Int, val y: String) + extends EnablingTrait with Accessors { + + protected def this(y: String) = this(-5, y) + } + + // Entities with reflection disabled + + class ClassDisable(val x: Int, val y: String) extends Accessors + + object ObjectDisable extends Accessors { + val x = 101 + val y = "ObjectDisable$" + } + + trait TraitDisable extends Accessors +} From f46050f245bed6c318e2f2855a811ea6afb5d0cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 17 Jan 2017 18:23:33 +0100 Subject: [PATCH 0105/2665] Prepare the testing interface to transition to reflective instantiation. This commit makes all the necessary changes to the testing interface so that it will be able to cope with reflective instantiation-based test loading. This means using `@EnableReflectiveInstantiation` instead of `@JSExportDescendantClasses`/`Objects` on both `sbt.testing.Framework` and test classes. This commit does *not*, however, already change the annotations. This ensures that the changes are "binary-compatible", in the sense that a new sbt plugin and (possibly) a new testing interface are able to run testing frameworks designed with the old export-based system. --- .../scala/sbttest/framework/DummyTask.scala | 2 +- .../scalajs/sbtplugin/FrameworkDetector.scala | 29 +------ .../org/scalajs/testinterface/TestUtils.scala | 16 ++++ .../scalajs/testinterface/TestDetector.scala | 26 ++++-- .../org/scalajs/testinterface/TestUtils.scala | 86 +++++++++++++++++-- .../internal/FrameworkDetector.scala | 39 +++++++++ .../internal/FrameworkLoader.scala | 15 ++-- .../scalajs/testsuite/junit/JUnitUtil.scala | 10 +-- 8 files changed, 173 insertions(+), 50 deletions(-) create mode 100644 test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkDetector.scala diff --git a/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/DummyTask.scala b/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/DummyTask.scala index 03c597a769..2ea89b7f50 100644 --- a/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/DummyTask.scala +++ b/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/DummyTask.scala @@ -15,7 +15,7 @@ final class DummyTask( try { // Just create a new instance. val inst = TestUtils.newInstance(taskDef.fullyQualifiedName, - runner.testClassLoader)(Seq()) + runner.testClassLoader, Seq())(Seq()) eventHandler.handle(new DummyEvent(taskDef, None)) loggers.foreach(_.info(s"Success: ${taskDef.fullyQualifiedName}")) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala index 4f9d05b02c..0667630585 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala @@ -40,31 +40,10 @@ private[sbtplugin] final class FrameworkDetector(jsEnv: JSEnv, "use strict"; var data = ${jsonToString(data)}; - - function frameworkExists(name) { - var parts = name.split("."); - var obj = exportsNamespace; - for (var i = 0; i < parts.length; ++i) { - obj = obj[parts[i]]; - if (obj === void 0) - return false; - } - return true; - } - - for (var i = 0; i < data.length; ++i) { - var gotOne = false; - for (var j = 0; j < data[i].length; ++j) { - if (frameworkExists(data[i][j])) { - console.log("$ConsoleFrameworkPrefix" + data[i][j]); - gotOne = true; - break; - } - } - if (!gotOne) { - // print an empty line with prefix to zip afterwards - console.log("$ConsoleFrameworkPrefix"); - } + var results = + exportsNamespace.org.scalajs.testinterface.internal.detectFrameworks(data); + for (var i = 0; i < results.length; ++i) { + console.log("$ConsoleFrameworkPrefix" + (results[i] || "")); } })($exportsNamespaceExpr); """ diff --git a/stubs/src/main/scala/org/scalajs/testinterface/TestUtils.scala b/stubs/src/main/scala/org/scalajs/testinterface/TestUtils.scala index 1a622fca0d..f7a4b8e6a7 100644 --- a/stubs/src/main/scala/org/scalajs/testinterface/TestUtils.scala +++ b/stubs/src/main/scala/org/scalajs/testinterface/TestUtils.scala @@ -15,9 +15,16 @@ object TestUtils { import scala.reflect.macros._ // shadows blackbox from above import blackbox.Context + @deprecated( + "Use the overload with explicit formal constructor parameter types.", + "0.6.15") def newInstance(name: String, loader: ClassLoader)(args: Seq[AnyRef]): AnyRef = macro newInstance_impl + def newInstance(name: String, loader: ClassLoader, paramTypes: Seq[Class[_]])( + args: Seq[AnyRef]): AnyRef = + macro newInstance_impl2 + def newInstance_impl(c: Context)(name: c.Expr[String], loader: c.Expr[ClassLoader])( args: c.Expr[Seq[AnyRef]]): c.Expr[AnyRef] = c.universe.reify { @@ -34,6 +41,15 @@ object TestUtils { ctor.newInstance(args.splice: _*).asInstanceOf[AnyRef] } + def newInstance_impl2(c: Context)(name: c.Expr[String], + loader: c.Expr[ClassLoader], paramTypes: c.Expr[Seq[Class[_]]])( + args: c.Expr[Seq[AnyRef]]): c.Expr[AnyRef] = c.universe.reify { + + val clazz = loader.splice.loadClass(name.splice) + val ctor = clazz.getConstructor(paramTypes.splice.toArray[Class[_]]: _*) + ctor.newInstance(args.splice: _*).asInstanceOf[AnyRef] + } + def loadModule(name: String, loader: ClassLoader): AnyRef = macro loadModule_impl diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala b/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala index 1fecfaddfd..9f3101bc27 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala @@ -1,7 +1,8 @@ package org.scalajs.testinterface import scala.scalajs.js -import js.annotation.JSGlobalScope +import scala.scalajs.js.annotation.JSGlobalScope +import scala.scalajs.reflect.Reflect import org.scalajs.testinterface.internal.TaskDefSerializer @@ -26,18 +27,31 @@ private[scalajs] object TestDetector { } private def tryLoadFramework(names: js.Array[String]): Option[Framework] = { - def tryLoadName(name: String) = { - val parts = name.split('.') + def tryLoadFromReflect(name: String): Option[Framework] = { + Reflect.lookupInstantiatableClass(name).collect { + case clazz if classOf[Framework].isAssignableFrom(clazz.runtimeClass) => + clazz.newInstance().asInstanceOf[Framework] + } + } - val ctor = parts.foldLeft[js.UndefOr[js.Dynamic]](js.Dynamic.global)( - (parent, name) => parent.map(_.selectDynamic(name))) + def tryLoadFromExportsNamespace(name: String): Option[Framework] = { + val exportsNamespace = + scala.scalajs.runtime.linkingInfo.envInfo.exportsNamespace + + val parts = name.split('.') + val ctor = parts.foldLeft[js.UndefOr[js.Dynamic]](exportsNamespace) { + (parent, name) => parent.map(_.selectDynamic(name)) + } ctor.map(js.Dynamic.newInstance(_)()).collect { case framework: Framework => framework }.toOption } - names.toStream.map(tryLoadName).flatten.headOption + def tryLoad(name: String): Option[Framework] = + tryLoadFromReflect(name).orElse(tryLoadFromExportsNamespace(name)) + + names.toStream.map(tryLoad).flatten.headOption } // Copied from sbt.TestFramework diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/TestUtils.scala b/test-interface/src/main/scala/org/scalajs/testinterface/TestUtils.scala index bd9eb5c2a4..27a5b62937 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/TestUtils.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/TestUtils.scala @@ -1,24 +1,94 @@ package org.scalajs.testinterface import scala.scalajs.js +import scala.scalajs.reflect._ object TestUtils { - def newInstance(name: String, loader: ClassLoader)(args: Seq[AnyRef]): AnyRef = { - val ctor = deepSelect(namespace(loader), name) - js.Dynamic.newInstance(ctor)(args.asInstanceOf[Seq[js.Any]]: _*) + /** Instantiates the class given by its fully qualified name. + * + * The target class must be exported under its fully qualified name. + * + * This overload of `newInstance` cannot instantiate classes with an + * ancestor annotated with + * [[scala.scalajs.reflect.annotation.EnableReflectiveInstantiation]]. + * + * Prefer using the other overload of `newInstance` for new code, which + * supports reflective instantiation in addition to exports-based + * instantiation. + */ + @deprecated( + "Use the overload with explicit formal constructor parameter types.", + "0.6.15") + def newInstance(name: String, loader: ClassLoader)( + args: Seq[AnyRef]): AnyRef = { + Reflect.lookupInstantiatableClass(name).fold[AnyRef] { + val ctor = deepSelect(namespace(loader), name) + js.Dynamic.newInstance(ctor)(args.asInstanceOf[Seq[js.Any]]: _*) + } { clazz => + throw new InstantiationException( + s"The class '$name' should be loaded through reflective " + + "instantiation, but the overload of TestUtils.newIntance() that " + + "was used does not support it. You can fix it by calling the other " + + "overload of TestUtils.newInstance().") + } + } + + /** Instantiates the class given by its fully qualified name. + * + * The target class must either + * + * - extend a class or trait annotated with + * [[scala.scalajs.reflect.annotation.EnableReflectiveInstantiation]], or + * - be exported under its fully qualified name. + * + * In the former case, the overload is selected based on `paramTypes`. In + * the latter case, the overload is selected by the usual export overload + * resolution mechanism. + */ + def newInstance(name: String, loader: ClassLoader, paramTypes: Seq[Class[_]])( + args: Seq[Any]): AnyRef = { + require(args.size == paramTypes.size, "argument count mismatch") + + Reflect.lookupInstantiatableClass(name).fold[AnyRef] { + val ctor = deepSelect(namespace(loader), name) + js.Dynamic.newInstance(ctor)(args.asInstanceOf[Seq[js.Any]]: _*) + } { clazz => + val ctor = clazz.declaredConstructors.find { + _.parameterTypes == paramTypes + }.getOrElse { + throw new InstantiationError(name) + } + ctor.newInstance(args: _*).asInstanceOf[AnyRef] + } } + /** Loads the module given by its fully qualified name. + * + * The target object must either + * + * - extend a class or trait annotated with + * [[scala.scalajs.reflect.annotation.EnableReflectiveInstantiation]], or + * - be exported under its fully qualified name. + * + * The name *must not* include the trailing `$` that is part of the module + * name, as added by the Scala compiler. + */ def loadModule(name: String, loader: ClassLoader): AnyRef = { - val accessor = deepSelect(namespace(loader), name) - accessor() + Reflect.lookupLoadableModuleClass(name + "$").fold[AnyRef] { + val accessor = deepSelect(namespace(loader), name) + accessor() + } { loadableModule => + loadableModule.loadModule().asInstanceOf[AnyRef] + } } private def namespace(loader: ClassLoader): js.Dynamic = { loader match { - case loader: ScalaJSClassLoader => loader.namespace - case _ => throw new IllegalArgumentException( - "Need a ScalaJSClassLoader.") + case loader: ScalaJSClassLoader => + loader.namespace + case _ => + throw new IllegalArgumentException("Need a ScalaJSClassLoader.") } } diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkDetector.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkDetector.scala new file mode 100644 index 0000000000..f9dfe0c3ec --- /dev/null +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkDetector.scala @@ -0,0 +1,39 @@ +package org.scalajs.testinterface.internal + +import scala.scalajs.js +import scala.scalajs.js.annotation._ +import scala.scalajs.js.JSConverters._ +import scala.scalajs.reflect.Reflect + +private[internal] object FrameworkDetector { + @JSExportTopLevel("org.scalajs.testinterface.internal.detectFrameworks") + def detectFrameworks( + frameworksData: js.Array[js.Array[String]]): js.Array[js.UndefOr[String]] = { + + def frameworkExistsInReflect(name: String): Boolean = { + Reflect.lookupInstantiatableClass(name).exists { clazz => + classOf[sbt.testing.Framework].isAssignableFrom(clazz.runtimeClass) + } + } + + def frameworkExistsInExportsNamespace(name: String): Boolean = { + /* This happens for testing frameworks developed before 0.6.15 that have + * not yet updated to using reflective instantiation, and are still + * using exports. + * Note that here, we have to assume that whatever we find is indeed a + * proper class export for a class extending sbt.testing.Framework. + */ + val exportsNamespace = + scala.scalajs.runtime.environmentInfo.exportsNamespace + name.split('.').foldLeft[js.UndefOr[js.Dynamic]](exportsNamespace) { + (prev, part) => prev.map(_.selectDynamic(part)) + }.isDefined + } + + def frameworkExists(name: String): Boolean = + frameworkExistsInReflect(name) || frameworkExistsInExportsNamespace(name) + + for (frameworkNames <- frameworksData) + yield frameworkNames.find(frameworkExists(_)).orUndefined + } +} diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkLoader.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkLoader.scala index 55c05a9a9b..3ca64d85fb 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkLoader.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkLoader.scala @@ -1,17 +1,22 @@ package org.scalajs.testinterface.internal import scala.scalajs.js +import scala.scalajs.reflect.Reflect import sbt.testing.Framework private[internal] object FrameworkLoader { def loadFramework(frameworkName: String): Framework = { - val exportsNamespace = - scala.scalajs.runtime.environmentInfo.exportsNamespace - val parts = frameworkName.split('.') - val ctor = parts.foldLeft(exportsNamespace)(_.selectDynamic(_)) - js.Dynamic.newInstance(ctor)().asInstanceOf[Framework] + Reflect.lookupInstantiatableClass(frameworkName).fold[Framework] { + val exportsNamespace = + scala.scalajs.runtime.environmentInfo.exportsNamespace + val parts = frameworkName.split('.') + val ctor = parts.foldLeft(exportsNamespace)(_.selectDynamic(_)) + js.Dynamic.newInstance(ctor)().asInstanceOf[Framework] + } { clazz => + clazz.newInstance().asInstanceOf[Framework] + } } } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala index 45af7b965c..dfdc3295c5 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala @@ -3,17 +3,17 @@ package org.scalajs.testsuite.junit import org.scalajs.junit.JUnitTestBootstrapper import org.junit.Assert.fail +import org.scalajs.testinterface._ + object JUnitUtil { private final val BootstrapperSuffix = "$scalajs$junit$bootstrapper" def loadBootstrapper(classFullName: String): JUnitTestBootstrapper = { val fullName = s"$classFullName$BootstrapperSuffix" try { - val exportsNamespace = - scala.scalajs.runtime.environmentInfo.exportsNamespace - fullName.split('.').foldLeft(exportsNamespace) { (obj, n) => - obj.selectDynamic(n) - }.apply().asInstanceOf[JUnitTestBootstrapper] + val loader = new ScalaJSClassLoader( + scala.scalajs.runtime.environmentInfo.exportsNamespace) + TestUtils.loadModule(fullName, loader).asInstanceOf[JUnitTestBootstrapper] } catch { case ex: Throwable => throw new AssertionError(s"could not load $fullName: ${ex.getMessage}") From 365ce061fe2fc3c28164403bd49c72e05df0b5c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 17 Jan 2017 18:24:18 +0100 Subject: [PATCH 0106/2665] Use reflective instantiation for `Framework`s instead of exports. Testing frameworks compiled with older versions of the testing interface will still be exported instead of available via reflection. Therefore there are fallback mechanisms to still support this. Newer testing frameworks (or recompiled) will use the new reflective instantiation support. --- test-interface/src/main/scala/sbt/testing/Framework.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test-interface/src/main/scala/sbt/testing/Framework.scala b/test-interface/src/main/scala/sbt/testing/Framework.scala index 01c8c22db2..15f1133ce2 100644 --- a/test-interface/src/main/scala/sbt/testing/Framework.scala +++ b/test-interface/src/main/scala/sbt/testing/Framework.scala @@ -1,9 +1,9 @@ package sbt.testing -import scala.scalajs.js.annotation._ +import scala.scalajs.reflect.annotation._ /** Interface implemented by test frameworks. */ -@JSExportDescendentClasses +@EnableReflectiveInstantiation trait Framework { /** A human-friendly name of the test framework that this object represents. From f7e4cf733d3a723437afd848d628ff81d4b98671 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 17 Jan 2017 18:26:33 +0100 Subject: [PATCH 0107/2665] Use reflective instantiation for JUnit bootstrapper objects. This commit updates the JUnit runtime to use the new reflective instantiation-based mechanism to load its bootstrapper objects. --- .../scala/org/scalajs/junit/JUnitTestBootstrapper.scala | 4 ++-- .../js/src/test/scala/sbttest/multitest/JUnitUtil.scala | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTestBootstrapper.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTestBootstrapper.scala index c53a855930..092e4d15b9 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTestBootstrapper.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTestBootstrapper.scala @@ -4,9 +4,9 @@ import java.lang.annotation.Annotation import org.junit.FixMethodOrder -import scala.scalajs.js.annotation.JSExportDescendentObjects +import scala.scalajs.reflect.annotation._ -@JSExportDescendentObjects +@EnableReflectiveInstantiation trait JUnitTestBootstrapper { def metadata(): JUnitClassMetadata def newInstance(): AnyRef diff --git a/sbt-plugin-test/multiTest/js/src/test/scala/sbttest/multitest/JUnitUtil.scala b/sbt-plugin-test/multiTest/js/src/test/scala/sbttest/multitest/JUnitUtil.scala index e2e891d531..8369ca4c87 100644 --- a/sbt-plugin-test/multiTest/js/src/test/scala/sbttest/multitest/JUnitUtil.scala +++ b/sbt-plugin-test/multiTest/js/src/test/scala/sbttest/multitest/JUnitUtil.scala @@ -3,7 +3,7 @@ package sbttest.multitest import org.scalajs.junit.JUnitTestBootstrapper import org.junit.Assert.fail -import scalajs.js +import scala.scalajs.reflect.Reflect object JUnitUtil { private final val bootstrapperSuffix = "$scalajs$junit$bootstrapper" @@ -11,9 +11,8 @@ object JUnitUtil { def loadBootstrapper(classFullName: String): JUnitTestBootstrapper = { val fullName = s"$classFullName$bootstrapperSuffix" try { - fullName.split('.').foldLeft(js.Dynamic.global) { (obj, n) => - obj.selectDynamic(n) - }.apply().asInstanceOf[JUnitTestBootstrapper] + val modClass = Reflect.lookupLoadableModuleClass(fullName + "$").get + modClass.loadModule().asInstanceOf[JUnitTestBootstrapper] } catch { case ex: Throwable => throw new AssertionError(s"could not load $fullName: ${ex.getMessage}") From 62c05d9515f8f1a43d99c05a4cc1a5e141f10a9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 18 Jan 2017 13:28:43 +0100 Subject: [PATCH 0108/2665] Use reflective instantiation in the DummyFramework of sbt-plugin-test. This commit updates the dummy testing framework in sbt-plugin-test to use the new reflective instantiation-based mechanism to load its test classes. --- .../testFramework/src/main/scala/sbttest/framework/Test.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/Test.scala b/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/Test.scala index 646ed2e6af..3834b6da03 100644 --- a/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/Test.scala +++ b/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/Test.scala @@ -1,6 +1,6 @@ package sbttest.framework -import scala.scalajs.js.annotation.JSExportDescendentClasses +import scala.scalajs.reflect.annotation.EnableReflectiveInstantiation -@JSExportDescendentClasses +@EnableReflectiveInstantiation class Test From 20f3e9a54a530aedff55815a1198fbd71c559bac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 21 Jan 2017 13:43:35 +0100 Subject: [PATCH 0109/2665] Make compiler AST tests fail if the snippet does not compile. This was a glaring omission. A `hasNot` test could pass simply because its source code snippet did not compile at all. No current test was passing because of this issue, though --- .../org/scalajs/core/compiler/test/util/JSASTTest.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/JSASTTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/util/JSASTTest.scala index f8eb49c806..f324f2bc2a 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/JSASTTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/util/JSASTTest.scala @@ -97,13 +97,15 @@ abstract class JSASTTest extends DirectTest { def stringAST(code: String): JSAST = stringAST(defaultGlobal)(code) def stringAST(global: Global)(code: String): JSAST = { - compileString(global)(code) + if (!compileString(global)(code)) + throw new IllegalArgumentException("snippet did not compile") lastAST } def sourceAST(source: SourceFile): JSAST = sourceAST(defaultGlobal)(source) def sourceAST(global: Global)(source: SourceFile): JSAST = { - compileSources(global)(source) + if (!compileSources(global)(source)) + throw new IllegalArgumentException("snippet did not compile") lastAST } From 80081269bde0bfb5fbb17eb62439de2ff0fe8388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 21 Jan 2017 23:14:03 +0100 Subject: [PATCH 0110/2665] Fix #2532: Emit "private" field access for Java-defined fields. Java-defined fields are now always accessed as if they were private. This is necessary because they are defined as private by our .scala source files, but they are considered `!isPrivate` at use site, since their symbols come from Java-emitted .class files. Fortunately, we can easily detect those as `isJavaDefined`. This includes fields of Ref types (IntRef, ObjectRef, etc.) which were previously special-cased at use-site. This commit generalizes the idea to all fields that are Java-defined (as per the .class files). Caveat: because of this, changing the length of the superclass chain of a Java-defined class is a binary incompatible change. This also fixes #2737, which was directly caused by #2532. --- .../scalajs/core/compiler/JSEncoding.scala | 25 +++++++------ .../io/ByteArrayOutputStreamTest.scala | 37 +++++++++++++++++++ .../javalib/util/EventObjectTest.scala | 2 - 3 files changed, 51 insertions(+), 13 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala index 7698851015..5270fcc2e5 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala @@ -80,12 +80,6 @@ trait JSEncoding extends SubComponent { self: GenJSCode => js.Ident(localSymbolName(sym), Some(sym.unexpandedName.decoded)) } - private lazy val allRefClasses: Set[Symbol] = { - import definitions._ - (Set(ObjectRefClass, VolatileObjectRefClass) ++ - refClass.values ++ volatileRefClass.values) - } - /** See comment in `encodeFieldSym()`. */ private lazy val shouldMangleOuterPointerName = { val v = scala.util.Properties.versionNumberString @@ -101,10 +95,15 @@ trait JSEncoding extends SubComponent { self: GenJSCode => if (name0.charAt(name0.length()-1) != ' ') name0 else name0.substring(0, name0.length()-1) - /* We have to special-case fields of Ref types (IntRef, ObjectRef, etc.) - * because they are emitted as private by our .scala source files, but - * they are considered public at use site since their symbols come from - * Java-emitted .class files. + /* Java-defined fields are always accessed as if they were private. This + * is necessary because they are defined as private by our .scala source + * files, but they are considered `!isPrivate` at use site, since their + * symbols come from Java-emitted .class files. Fortunately, we can + * easily detect those as `isJavaDefined`. This includes fields of Ref + * types (IntRef, ObjectRef, etc.) which were special-cased at use-site + * in Scala.js < 0.6.15. + * Caveat: because of this, changing the length of the superclass chain of + * a Java-defined class is a binary incompatible change. * * Starting with 2.12.0-RC2, we also special case outer fields. This * essentially fixes #2382, which is caused by a class having various $outer @@ -116,11 +115,15 @@ trait JSEncoding extends SubComponent { self: GenJSCode => * therefore a regression. We can do this because the 2.12 ecosystem is * not binary compatible anyway (because of Scala) so we can break it on * our side at the same time. + * + * TODO We should probably consider emitting *all* fields with an ancestor + * count. We cannot do that in a binary compatible way, though. This is + * filed as #2629. */ val idSuffix: String = { val usePerClassSuffix = { sym.isPrivate || - allRefClasses.contains(sym.owner) || + sym.isJavaDefined || (shouldMangleOuterPointerName && sym.isOuterField) } if (usePerClassSuffix) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/ByteArrayOutputStreamTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/ByteArrayOutputStreamTest.scala index c8499aaa6b..e0d191c48a 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/ByteArrayOutputStreamTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/ByteArrayOutputStreamTest.scala @@ -67,4 +67,41 @@ class ByteArrayOutputStreamTest { assertArrayEquals(Array[Byte](0, 1, 2, 3, 4, 5, 6, 7, 8, 9), out.toByteArray) } + @Test def buf_field(): Unit = { + class ByteArrayOutputStreamWithBufAccess extends ByteArrayOutputStream { + def getBuf(): Array[Byte] = buf + def setBuf(b: Array[Byte]): Unit = buf = b + } + + val os = new ByteArrayOutputStreamWithBufAccess + os.write(5.toInt) + os.flush() + assertEquals(5.toByte, os.getBuf()(0)) + + val newBuf = Array(10.toByte) + os.setBuf(newBuf) + assertSame(newBuf, os.getBuf()) + val output = os.toByteArray() + assertArrayEquals(newBuf, output) + assertNotSame(newBuf, output) + } + + @Test def count_field(): Unit = { + class ByteArrayOutputStreamWithCountAccess extends ByteArrayOutputStream { + def getCount(): Int = count + def setCount(c: Int): Unit = count = c + } + + val os = new ByteArrayOutputStreamWithCountAccess + os.write(Array[Byte](5, 7, 10, 15, 25, -4)) + os.flush() + assertEquals(6, os.getCount()) + assertArrayEquals(Array[Byte](5, 7, 10, 15, 25, -4), os.toByteArray()) + + os.setCount(3) + assertEquals(3, os.getCount()) + assertEquals(3, os.size()) + assertArrayEquals(Array[Byte](5, 7, 10), os.toByteArray()) + } + } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/EventObjectTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/EventObjectTest.scala index 5a5604b81c..c7edca936c 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/EventObjectTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/EventObjectTest.scala @@ -19,7 +19,6 @@ class EventObjectTest { assertSame(src, e.getSource) } - /* #2532 This does not link, because we cannot declare a Java field @Test def sourceField(): Unit = { class E(s: AnyRef) extends EventObject(s) { def setSource(s: AnyRef): Unit = source = s @@ -35,7 +34,6 @@ class EventObjectTest { assertSame(src2, e.otherGetSource) assertSame(src2, e.getSource) } - */ @Test def testToString(): Unit = { /* There is not much we can test about toString, but it should not be the From f73d8c894554702ff36d82022d0b1c34d72acf2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 21 Jan 2017 13:50:51 +0100 Subject: [PATCH 0111/2665] Fix #2265 and #2741: Look for repeated args in all parameter lists. Usually, in the compiler back-end, we use `methodTpe.params` to read the list of all parameters. This works because multiple parameter lists are flattened. The code that optimizes varargs as `new js.WrappedArray(js.Array(...))` was reading parameters right after `typer` in the type history. It has to use `.paramss.flatten` in that case, because `.params` represents only the first parameter list. --- .../org/scalajs/core/compiler/GenJSCode.scala | 8 +++- .../core/compiler/test/OptimizationTest.scala | 40 ++++++++++++++++++- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index b7dc48102a..fb4a08cd33 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -4305,7 +4305,11 @@ abstract class GenJSCode extends plugins.PluginComponent private def genActualArgs(sym: Symbol, args: List[Tree])( implicit pos: Position): List[js.Tree] = { val wereRepeated = exitingPhase(currentRun.typerPhase) { - sym.tpe.params.map(p => isScalaRepeatedParamType(p.tpe)) + /* Do NOT use `params` instead of `paramss.flatten` here! Exiting + * typer, `params` only contains the *first* parameter list. + * This was causing #2265 and #2741. + */ + sym.tpe.paramss.flatten.map(p => isScalaRepeatedParamType(p.tpe)) } if (wereRepeated.size > args.size) { @@ -4313,7 +4317,7 @@ abstract class GenJSCode extends plugins.PluginComponent args.map(genExpr) } else { /* Arguments that are in excess compared to the type signature after - * erasure are lambda-lifted arguments. They cannot be repeated, hence + * typer are lambda-lifted arguments. They cannot be repeated, hence * the extension to `false`. */ for ((arg, wasRepeated) <- args.zipAll(wereRepeated, EmptyTree, false)) yield { diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala index d5ee4b9e48..0188aa3096 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala @@ -10,7 +10,6 @@ class OptimizationTest extends JSASTTest { @Test def unwrapScalaFunWrapper: Unit = { - // Make sure we do not wrap and unwrap right away """ import scala.scalajs.js @@ -35,7 +34,10 @@ class OptimizationTest extends JSASTTest { has("runtime.AnonFunction ctor") { case js.New(jstpe.ClassType("sjsr_AnonFunction1"), _, _) => } + } + @Test + def testJSArrayApplyOptimization: Unit = { /* Make sure js.Array(...) is optimized away completely for several kinds * of data types. */ @@ -56,7 +58,10 @@ class OptimizationTest extends JSASTTest { case js.Apply(_, js.Ident(name, _), _) if name.startsWith("wrap") && name.endsWith("__scm_WrappedArray") => } + } + @Test + def testVarArgsOptimization: Unit = { /* Make sure varargs are optimized to use js.WrappedArray instead of * scm.WrappedArray, for various data types. */ @@ -78,6 +83,35 @@ class OptimizationTest extends JSASTTest { if name.startsWith("wrap") && name.endsWith("__scm_WrappedArray") => } + /* #2265 and #2741: + * Make sure varargs are optimized to use js.WrappedArray instead of + * scm.WrappedArray, for different species of target method (single arg + * list, multiple arg list, in value class). + */ + """ + import scala.scalajs.js + + class VC(val x: Int) extends AnyVal { + def singleInVC(ys: Int*): Int = x + ys.size + } + + class A { + def test(): Int = { + val a = single(5, 7, 9, -3) + val b = multiple(5)(7, 9, -3) + val c = new VC(5).singleInVC(7, 9, -3) + a + b + c + } + + def single(x: Int, ys: Int*): Int = x + ys.size + def multiple(x: Int)(ys: Int*): Int = x + ys.size + } + """. + hasNot("any of the wrapArray methods") { + case js.Apply(_, js.Ident(name, _), _) + if name.startsWith("wrap") && name.endsWith("__scm_WrappedArray") => + } + // Make sure our wrapper matcher has the right name """ import scala.scalajs.js @@ -90,7 +124,10 @@ class OptimizationTest extends JSASTTest { case js.Apply(_, js.Ident(name, _), _) if name.startsWith("wrap") && name.endsWith("__scm_WrappedArray") => } + } + @Test + def testNewJSObjectAndJSArray: Unit = { // Verify the optimized emitted code for 'new js.Object' and 'new js.Array' """ import scala.scalajs.js @@ -103,7 +140,6 @@ class OptimizationTest extends JSASTTest { hasNot("any reference to the global scope") { case js.JSLinkingInfo() => } - } @Test From e8e6e2cf40db9c79d6fc60a8129eeffc5bb97416 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 24 Jan 2017 18:34:12 +0100 Subject: [PATCH 0112/2665] Add s.c.i.RedBlackTree to overrides. The versions come from 2.10.6 and 2.11.8. In 2.11.x, 2.12.x and 2.13.x, the file has not changed since 2.11.8. --- .../collection/immutable/RedBlackTree.scala | 496 ++++++++++++++++ .../collection/immutable/RedBlackTree.scala | 562 ++++++++++++++++++ 2 files changed, 1058 insertions(+) create mode 100644 scalalib/overrides-2.10/scala/collection/immutable/RedBlackTree.scala create mode 100644 scalalib/overrides/scala/collection/immutable/RedBlackTree.scala diff --git a/scalalib/overrides-2.10/scala/collection/immutable/RedBlackTree.scala b/scalalib/overrides-2.10/scala/collection/immutable/RedBlackTree.scala new file mode 100644 index 0000000000..0254e9ca3a --- /dev/null +++ b/scalalib/overrides-2.10/scala/collection/immutable/RedBlackTree.scala @@ -0,0 +1,496 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + + + +package scala +package collection +package immutable + +import scala.annotation.tailrec +import scala.annotation.meta.getter + +/** An object containing the RedBlack tree implementation used by for `TreeMaps` and `TreeSets`. + * + * Implementation note: since efficiency is important for data structures this implementation + * uses null to represent empty trees. This also means pattern matching cannot + * easily be used. The API represented by the RedBlackTree object tries to hide these + * optimizations behind a reasonably clean API. + * + * @since 2.10 + */ +private[immutable] +object RedBlackTree { + + def isEmpty(tree: Tree[_, _]): Boolean = tree eq null + + def contains[A](tree: Tree[A, _], x: A)(implicit ordering: Ordering[A]): Boolean = lookup(tree, x) ne null + def get[A, B](tree: Tree[A, B], x: A)(implicit ordering: Ordering[A]): Option[B] = lookup(tree, x) match { + case null => None + case tree => Some(tree.value) + } + + @tailrec + def lookup[A, B](tree: Tree[A, B], x: A)(implicit ordering: Ordering[A]): Tree[A, B] = if (tree eq null) null else { + val cmp = ordering.compare(x, tree.key) + if (cmp < 0) lookup(tree.left, x) + else if (cmp > 0) lookup(tree.right, x) + else tree + } + + def count(tree: Tree[_, _]) = if (tree eq null) 0 else tree.count + def update[A, B, B1 >: B](tree: Tree[A, B], k: A, v: B1, overwrite: Boolean)(implicit ordering: Ordering[A]): Tree[A, B1] = blacken(upd(tree, k, v, overwrite)) + def delete[A, B](tree: Tree[A, B], k: A)(implicit ordering: Ordering[A]): Tree[A, B] = blacken(del(tree, k)) + def rangeImpl[A: Ordering, B](tree: Tree[A, B], from: Option[A], until: Option[A]): Tree[A, B] = (from, until) match { + case (Some(from), Some(until)) => this.range(tree, from, until) + case (Some(from), None) => this.from(tree, from) + case (None, Some(until)) => this.until(tree, until) + case (None, None) => tree + } + def range[A: Ordering, B](tree: Tree[A, B], from: A, until: A): Tree[A, B] = blacken(doRange(tree, from, until)) + def from[A: Ordering, B](tree: Tree[A, B], from: A): Tree[A, B] = blacken(doFrom(tree, from)) + def to[A: Ordering, B](tree: Tree[A, B], to: A): Tree[A, B] = blacken(doTo(tree, to)) + def until[A: Ordering, B](tree: Tree[A, B], key: A): Tree[A, B] = blacken(doUntil(tree, key)) + + def drop[A: Ordering, B](tree: Tree[A, B], n: Int): Tree[A, B] = blacken(doDrop(tree, n)) + def take[A: Ordering, B](tree: Tree[A, B], n: Int): Tree[A, B] = blacken(doTake(tree, n)) + def slice[A: Ordering, B](tree: Tree[A, B], from: Int, until: Int): Tree[A, B] = blacken(doSlice(tree, from, until)) + + def smallest[A, B](tree: Tree[A, B]): Tree[A, B] = { + if (tree eq null) throw new NoSuchElementException("empty map") + var result = tree + while (result.left ne null) result = result.left + result + } + def greatest[A, B](tree: Tree[A, B]): Tree[A, B] = { + if (tree eq null) throw new NoSuchElementException("empty map") + var result = tree + while (result.right ne null) result = result.right + result + } + + def foreach[A, B, U](tree: Tree[A, B], f: ((A, B)) => U): Unit = if (tree ne null) { + if (tree.left ne null) foreach(tree.left, f) + f((tree.key, tree.value)) + if (tree.right ne null) foreach(tree.right, f) + } + def foreachKey[A, U](tree: Tree[A, _], f: A => U): Unit = if (tree ne null) { + if (tree.left ne null) foreachKey(tree.left, f) + f(tree.key) + if (tree.right ne null) foreachKey(tree.right, f) + } + + def iterator[A, B](tree: Tree[A, B]): Iterator[(A, B)] = new EntriesIterator(tree) + def keysIterator[A, _](tree: Tree[A, _]): Iterator[A] = new KeysIterator(tree) + def valuesIterator[_, B](tree: Tree[_, B]): Iterator[B] = new ValuesIterator(tree) + + @tailrec + def nth[A, B](tree: Tree[A, B], n: Int): Tree[A, B] = { + val count = this.count(tree.left) + if (n < count) nth(tree.left, n) + else if (n > count) nth(tree.right, n - count - 1) + else tree + } + + def isBlack(tree: Tree[_, _]) = (tree eq null) || isBlackTree(tree) + + private[this] def isRedTree(tree: Tree[_, _]) = tree.isInstanceOf[RedTree[_, _]] + private[this] def isBlackTree(tree: Tree[_, _]) = tree.isInstanceOf[BlackTree[_, _]] + + private[this] def blacken[A, B](t: Tree[A, B]): Tree[A, B] = if (t eq null) null else t.black + + private[this] def mkTree[A, B](isBlack: Boolean, k: A, v: B, l: Tree[A, B], r: Tree[A, B]) = + if (isBlack) BlackTree(k, v, l, r) else RedTree(k, v, l, r) + + private[this] def balanceLeft[A, B, B1 >: B](isBlack: Boolean, z: A, zv: B, l: Tree[A, B1], d: Tree[A, B1]): Tree[A, B1] = { + if (isRedTree(l) && isRedTree(l.left)) + RedTree(l.key, l.value, BlackTree(l.left.key, l.left.value, l.left.left, l.left.right), BlackTree(z, zv, l.right, d)) + else if (isRedTree(l) && isRedTree(l.right)) + RedTree(l.right.key, l.right.value, BlackTree(l.key, l.value, l.left, l.right.left), BlackTree(z, zv, l.right.right, d)) + else + mkTree(isBlack, z, zv, l, d) + } + private[this] def balanceRight[A, B, B1 >: B](isBlack: Boolean, x: A, xv: B, a: Tree[A, B1], r: Tree[A, B1]): Tree[A, B1] = { + if (isRedTree(r) && isRedTree(r.left)) + RedTree(r.left.key, r.left.value, BlackTree(x, xv, a, r.left.left), BlackTree(r.key, r.value, r.left.right, r.right)) + else if (isRedTree(r) && isRedTree(r.right)) + RedTree(r.key, r.value, BlackTree(x, xv, a, r.left), BlackTree(r.right.key, r.right.value, r.right.left, r.right.right)) + else + mkTree(isBlack, x, xv, a, r) + } + private[this] def upd[A, B, B1 >: B](tree: Tree[A, B], k: A, v: B1, overwrite: Boolean)(implicit ordering: Ordering[A]): Tree[A, B1] = if (tree eq null) { + RedTree(k, v, null, null) + } else { + val cmp = ordering.compare(k, tree.key) + if (cmp < 0) balanceLeft(isBlackTree(tree), tree.key, tree.value, upd(tree.left, k, v, overwrite), tree.right) + else if (cmp > 0) balanceRight(isBlackTree(tree), tree.key, tree.value, tree.left, upd(tree.right, k, v, overwrite)) + else if (overwrite || k != tree.key) mkTree(isBlackTree(tree), k, v, tree.left, tree.right) + else tree + } + private[this] def updNth[A, B, B1 >: B](tree: Tree[A, B], idx: Int, k: A, v: B1, overwrite: Boolean): Tree[A, B1] = if (tree eq null) { + RedTree(k, v, null, null) + } else { + val rank = count(tree.left) + 1 + if (idx < rank) balanceLeft(isBlackTree(tree), tree.key, tree.value, updNth(tree.left, idx, k, v, overwrite), tree.right) + else if (idx > rank) balanceRight(isBlackTree(tree), tree.key, tree.value, tree.left, updNth(tree.right, idx - rank, k, v, overwrite)) + else if (overwrite) mkTree(isBlackTree(tree), k, v, tree.left, tree.right) + else tree + } + + /* Based on Stefan Kahrs' Haskell version of Okasaki's Red&Black Trees + * http://www.cse.unsw.edu.au/~dons/data/RedBlackTree.html */ + private[this] def del[A, B](tree: Tree[A, B], k: A)(implicit ordering: Ordering[A]): Tree[A, B] = if (tree eq null) null else { + def balance(x: A, xv: B, tl: Tree[A, B], tr: Tree[A, B]) = if (isRedTree(tl)) { + if (isRedTree(tr)) { + RedTree(x, xv, tl.black, tr.black) + } else if (isRedTree(tl.left)) { + RedTree(tl.key, tl.value, tl.left.black, BlackTree(x, xv, tl.right, tr)) + } else if (isRedTree(tl.right)) { + RedTree(tl.right.key, tl.right.value, BlackTree(tl.key, tl.value, tl.left, tl.right.left), BlackTree(x, xv, tl.right.right, tr)) + } else { + BlackTree(x, xv, tl, tr) + } + } else if (isRedTree(tr)) { + if (isRedTree(tr.right)) { + RedTree(tr.key, tr.value, BlackTree(x, xv, tl, tr.left), tr.right.black) + } else if (isRedTree(tr.left)) { + RedTree(tr.left.key, tr.left.value, BlackTree(x, xv, tl, tr.left.left), BlackTree(tr.key, tr.value, tr.left.right, tr.right)) + } else { + BlackTree(x, xv, tl, tr) + } + } else { + BlackTree(x, xv, tl, tr) + } + def subl(t: Tree[A, B]) = + if (t.isInstanceOf[BlackTree[_, _]]) t.red + else sys.error("Defect: invariance violation; expected black, got "+t) + + def balLeft(x: A, xv: B, tl: Tree[A, B], tr: Tree[A, B]) = if (isRedTree(tl)) { + RedTree(x, xv, tl.black, tr) + } else if (isBlackTree(tr)) { + balance(x, xv, tl, tr.red) + } else if (isRedTree(tr) && isBlackTree(tr.left)) { + RedTree(tr.left.key, tr.left.value, BlackTree(x, xv, tl, tr.left.left), balance(tr.key, tr.value, tr.left.right, subl(tr.right))) + } else { + sys.error("Defect: invariance violation") + } + def balRight(x: A, xv: B, tl: Tree[A, B], tr: Tree[A, B]) = if (isRedTree(tr)) { + RedTree(x, xv, tl, tr.black) + } else if (isBlackTree(tl)) { + balance(x, xv, tl.red, tr) + } else if (isRedTree(tl) && isBlackTree(tl.right)) { + RedTree(tl.right.key, tl.right.value, balance(tl.key, tl.value, subl(tl.left), tl.right.left), BlackTree(x, xv, tl.right.right, tr)) + } else { + sys.error("Defect: invariance violation") + } + def delLeft = if (isBlackTree(tree.left)) balLeft(tree.key, tree.value, del(tree.left, k), tree.right) else RedTree(tree.key, tree.value, del(tree.left, k), tree.right) + def delRight = if (isBlackTree(tree.right)) balRight(tree.key, tree.value, tree.left, del(tree.right, k)) else RedTree(tree.key, tree.value, tree.left, del(tree.right, k)) + def append(tl: Tree[A, B], tr: Tree[A, B]): Tree[A, B] = if (tl eq null) { + tr + } else if (tr eq null) { + tl + } else if (isRedTree(tl) && isRedTree(tr)) { + val bc = append(tl.right, tr.left) + if (isRedTree(bc)) { + RedTree(bc.key, bc.value, RedTree(tl.key, tl.value, tl.left, bc.left), RedTree(tr.key, tr.value, bc.right, tr.right)) + } else { + RedTree(tl.key, tl.value, tl.left, RedTree(tr.key, tr.value, bc, tr.right)) + } + } else if (isBlackTree(tl) && isBlackTree(tr)) { + val bc = append(tl.right, tr.left) + if (isRedTree(bc)) { + RedTree(bc.key, bc.value, BlackTree(tl.key, tl.value, tl.left, bc.left), BlackTree(tr.key, tr.value, bc.right, tr.right)) + } else { + balLeft(tl.key, tl.value, tl.left, BlackTree(tr.key, tr.value, bc, tr.right)) + } + } else if (isRedTree(tr)) { + RedTree(tr.key, tr.value, append(tl, tr.left), tr.right) + } else if (isRedTree(tl)) { + RedTree(tl.key, tl.value, tl.left, append(tl.right, tr)) + } else { + sys.error("unmatched tree on append: " + tl + ", " + tr) + } + + val cmp = ordering.compare(k, tree.key) + if (cmp < 0) delLeft + else if (cmp > 0) delRight + else append(tree.left, tree.right) + } + + private[this] def doFrom[A, B](tree: Tree[A, B], from: A)(implicit ordering: Ordering[A]): Tree[A, B] = { + if (tree eq null) return null + if (ordering.lt(tree.key, from)) return doFrom(tree.right, from) + val newLeft = doFrom(tree.left, from) + if (newLeft eq tree.left) tree + else if (newLeft eq null) upd(tree.right, tree.key, tree.value, false) + else rebalance(tree, newLeft, tree.right) + } + private[this] def doTo[A, B](tree: Tree[A, B], to: A)(implicit ordering: Ordering[A]): Tree[A, B] = { + if (tree eq null) return null + if (ordering.lt(to, tree.key)) return doTo(tree.left, to) + val newRight = doTo(tree.right, to) + if (newRight eq tree.right) tree + else if (newRight eq null) upd(tree.left, tree.key, tree.value, false) + else rebalance(tree, tree.left, newRight) + } + private[this] def doUntil[A, B](tree: Tree[A, B], until: A)(implicit ordering: Ordering[A]): Tree[A, B] = { + if (tree eq null) return null + if (ordering.lteq(until, tree.key)) return doUntil(tree.left, until) + val newRight = doUntil(tree.right, until) + if (newRight eq tree.right) tree + else if (newRight eq null) upd(tree.left, tree.key, tree.value, false) + else rebalance(tree, tree.left, newRight) + } + private[this] def doRange[A, B](tree: Tree[A, B], from: A, until: A)(implicit ordering: Ordering[A]): Tree[A, B] = { + if (tree eq null) return null + if (ordering.lt(tree.key, from)) return doRange(tree.right, from, until); + if (ordering.lteq(until, tree.key)) return doRange(tree.left, from, until); + val newLeft = doFrom(tree.left, from) + val newRight = doUntil(tree.right, until) + if ((newLeft eq tree.left) && (newRight eq tree.right)) tree + else if (newLeft eq null) upd(newRight, tree.key, tree.value, false); + else if (newRight eq null) upd(newLeft, tree.key, tree.value, false); + else rebalance(tree, newLeft, newRight) + } + + private[this] def doDrop[A, B](tree: Tree[A, B], n: Int): Tree[A, B] = { + if (n <= 0) return tree + if (n >= this.count(tree)) return null + val count = this.count(tree.left) + if (n > count) return doDrop(tree.right, n - count - 1) + val newLeft = doDrop(tree.left, n) + if (newLeft eq tree.left) tree + else if (newLeft eq null) updNth(tree.right, n - count - 1, tree.key, tree.value, false) + else rebalance(tree, newLeft, tree.right) + } + private[this] def doTake[A, B](tree: Tree[A, B], n: Int): Tree[A, B] = { + if (n <= 0) return null + if (n >= this.count(tree)) return tree + val count = this.count(tree.left) + if (n <= count) return doTake(tree.left, n) + val newRight = doTake(tree.right, n - count - 1) + if (newRight eq tree.right) tree + else if (newRight eq null) updNth(tree.left, n, tree.key, tree.value, false) + else rebalance(tree, tree.left, newRight) + } + private[this] def doSlice[A, B](tree: Tree[A, B], from: Int, until: Int): Tree[A, B] = { + if (tree eq null) return null + val count = this.count(tree.left) + if (from > count) return doSlice(tree.right, from - count - 1, until - count - 1) + if (until <= count) return doSlice(tree.left, from, until) + val newLeft = doDrop(tree.left, from) + val newRight = doTake(tree.right, until - count - 1) + if ((newLeft eq tree.left) && (newRight eq tree.right)) tree + else if (newLeft eq null) updNth(newRight, from - count - 1, tree.key, tree.value, false) + else if (newRight eq null) updNth(newLeft, until, tree.key, tree.value, false) + else rebalance(tree, newLeft, newRight) + } + + // The zipper returned might have been traversed left-most (always the left child) + // or right-most (always the right child). Left trees are traversed right-most, + // and right trees are traversed leftmost. + + // Returns the zipper for the side with deepest black nodes depth, a flag + // indicating whether the trees were unbalanced at all, and a flag indicating + // whether the zipper was traversed left-most or right-most. + + // If the trees were balanced, returns an empty zipper + private[this] def compareDepth[A, B](left: Tree[A, B], right: Tree[A, B]): (List[Tree[A, B]], Boolean, Boolean, Int) = { + // Once a side is found to be deeper, unzip it to the bottom + def unzip(zipper: List[Tree[A, B]], leftMost: Boolean): List[Tree[A, B]] = { + val next = if (leftMost) zipper.head.left else zipper.head.right + next match { + case null => zipper + case node => unzip(node :: zipper, leftMost) + } + } + + // Unzip left tree on the rightmost side and right tree on the leftmost side until one is + // found to be deeper, or the bottom is reached + def unzipBoth(left: Tree[A, B], + right: Tree[A, B], + leftZipper: List[Tree[A, B]], + rightZipper: List[Tree[A, B]], + smallerDepth: Int): (List[Tree[A, B]], Boolean, Boolean, Int) = { + if (isBlackTree(left) && isBlackTree(right)) { + unzipBoth(left.right, right.left, left :: leftZipper, right :: rightZipper, smallerDepth + 1) + } else if (isRedTree(left) && isRedTree(right)) { + unzipBoth(left.right, right.left, left :: leftZipper, right :: rightZipper, smallerDepth) + } else if (isRedTree(right)) { + unzipBoth(left, right.left, leftZipper, right :: rightZipper, smallerDepth) + } else if (isRedTree(left)) { + unzipBoth(left.right, right, left :: leftZipper, rightZipper, smallerDepth) + } else if ((left eq null) && (right eq null)) { + (Nil, true, false, smallerDepth) + } else if ((left eq null) && isBlackTree(right)) { + val leftMost = true + (unzip(right :: rightZipper, leftMost), false, leftMost, smallerDepth) + } else if (isBlackTree(left) && (right eq null)) { + val leftMost = false + (unzip(left :: leftZipper, leftMost), false, leftMost, smallerDepth) + } else { + sys.error("unmatched trees in unzip: " + left + ", " + right) + } + } + unzipBoth(left, right, Nil, Nil, 0) + } + + private[this] def rebalance[A, B](tree: Tree[A, B], newLeft: Tree[A, B], newRight: Tree[A, B]) = { + // This is like drop(n-1), but only counting black nodes + def findDepth(zipper: List[Tree[A, B]], depth: Int): List[Tree[A, B]] = zipper match { + case head :: tail if isBlackTree(head) => + if (depth == 1) zipper else findDepth(tail, depth - 1) + case _ :: tail => findDepth(tail, depth) + case Nil => sys.error("Defect: unexpected empty zipper while computing range") + } + + // Blackening the smaller tree avoids balancing problems on union; + // this can't be done later, though, or it would change the result of compareDepth + val blkNewLeft = blacken(newLeft) + val blkNewRight = blacken(newRight) + val (zipper, levelled, leftMost, smallerDepth) = compareDepth(blkNewLeft, blkNewRight) + + if (levelled) { + BlackTree(tree.key, tree.value, blkNewLeft, blkNewRight) + } else { + val zipFrom = findDepth(zipper, smallerDepth) + val union = if (leftMost) { + RedTree(tree.key, tree.value, blkNewLeft, zipFrom.head) + } else { + RedTree(tree.key, tree.value, zipFrom.head, blkNewRight) + } + val zippedTree = zipFrom.tail.foldLeft(union: Tree[A, B]) { (tree, node) => + if (leftMost) + balanceLeft(isBlackTree(node), node.key, node.value, tree, node.right) + else + balanceRight(isBlackTree(node), node.key, node.value, node.left, tree) + } + zippedTree + } + } + + /* + * Forcing direct fields access using the @inline annotation helps speed up + * various operations (especially smallest/greatest and update/delete). + * + * Unfortunately the direct field access is not guaranteed to work (but + * works on the current implementation of the Scala compiler). + * + * An alternative is to implement the these classes using plain old Java code... + */ + sealed abstract class Tree[A, +B]( + @(inline @getter) final val key: A, + @(inline @getter) final val value: B, + @(inline @getter) final val left: Tree[A, B], + @(inline @getter) final val right: Tree[A, B]) + extends Serializable { + @(inline @getter) final val count: Int = 1 + RedBlackTree.count(left) + RedBlackTree.count(right) + def black: Tree[A, B] + def red: Tree[A, B] + } + final class RedTree[A, +B](key: A, + value: B, + left: Tree[A, B], + right: Tree[A, B]) extends Tree[A, B](key, value, left, right) { + override def black: Tree[A, B] = BlackTree(key, value, left, right) + override def red: Tree[A, B] = this + override def toString: String = "RedTree(" + key + ", " + value + ", " + left + ", " + right + ")" + } + final class BlackTree[A, +B](key: A, + value: B, + left: Tree[A, B], + right: Tree[A, B]) extends Tree[A, B](key, value, left, right) { + override def black: Tree[A, B] = this + override def red: Tree[A, B] = RedTree(key, value, left, right) + override def toString: String = "BlackTree(" + key + ", " + value + ", " + left + ", " + right + ")" + } + + object RedTree { + @inline def apply[A, B](key: A, value: B, left: Tree[A, B], right: Tree[A, B]) = new RedTree(key, value, left, right) + def unapply[A, B](t: RedTree[A, B]) = Some((t.key, t.value, t.left, t.right)) + } + object BlackTree { + @inline def apply[A, B](key: A, value: B, left: Tree[A, B], right: Tree[A, B]) = new BlackTree(key, value, left, right) + def unapply[A, B](t: BlackTree[A, B]) = Some((t.key, t.value, t.left, t.right)) + } + + private[this] abstract class TreeIterator[A, B, R](tree: Tree[A, B]) extends Iterator[R] { + protected[this] def nextResult(tree: Tree[A, B]): R + + override def hasNext: Boolean = next ne null + + override def next: R = next match { + case null => + throw new NoSuchElementException("next on empty iterator") + case tree => + next = findNext(tree.right) + nextResult(tree) + } + + @tailrec + private[this] def findNext(tree: Tree[A, B]): Tree[A, B] = { + if (tree eq null) popPath() + else if (tree.left eq null) tree + else { + pushPath(tree) + findNext(tree.left) + } + } + + private[this] def pushPath(tree: Tree[A, B]) { + try { + path(index) = tree + index += 1 + } catch { + case _: ArrayIndexOutOfBoundsException => + /* + * Either the tree became unbalanced or we calculated the maximum height incorrectly. + * To avoid crashing the iterator we expand the path array. Obviously this should never + * happen... + * + * An exception handler is used instead of an if-condition to optimize the normal path. + * This makes a large difference in iteration speed! + */ + assert(index >= path.length) + path :+= null + pushPath(tree) + } + } + private[this] def popPath(): Tree[A, B] = if (index == 0) null else { + index -= 1 + path(index) + } + + private[this] var path = if (tree eq null) null else { + /* + * According to "Ralf Hinze. Constructing red-black trees" [http://www.cs.ox.ac.uk/ralf.hinze/publications/#P5] + * the maximum height of a red-black tree is 2*log_2(n + 2) - 2. + * + * According to {@see Integer#numberOfLeadingZeros} ceil(log_2(n)) = (32 - Integer.numberOfLeadingZeros(n - 1)) + * + * We also don't store the deepest nodes in the path so the maximum path length is further reduced by one. + */ + val maximumHeight = 2 * (32 - Integer.numberOfLeadingZeros(tree.count + 2 - 1)) - 2 - 1 + new Array[Tree[A, B]](maximumHeight) + } + private[this] var index = 0 + private[this] var next: Tree[A, B] = findNext(tree) + } + + private[this] class EntriesIterator[A, B](tree: Tree[A, B]) extends TreeIterator[A, B, (A, B)](tree) { + override def nextResult(tree: Tree[A, B]) = (tree.key, tree.value) + } + + private[this] class KeysIterator[A, B](tree: Tree[A, B]) extends TreeIterator[A, B, A](tree) { + override def nextResult(tree: Tree[A, B]) = tree.key + } + + private[this] class ValuesIterator[A, B](tree: Tree[A, B]) extends TreeIterator[A, B, B](tree) { + override def nextResult(tree: Tree[A, B]) = tree.value + } +} diff --git a/scalalib/overrides/scala/collection/immutable/RedBlackTree.scala b/scalalib/overrides/scala/collection/immutable/RedBlackTree.scala new file mode 100644 index 0000000000..afb4c9c552 --- /dev/null +++ b/scalalib/overrides/scala/collection/immutable/RedBlackTree.scala @@ -0,0 +1,562 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + + + +package scala +package collection +package immutable + +import scala.annotation.tailrec +import scala.annotation.meta.getter + +/** An object containing the RedBlack tree implementation used by for `TreeMaps` and `TreeSets`. + * + * Implementation note: since efficiency is important for data structures this implementation + * uses `null` to represent empty trees. This also means pattern matching cannot + * easily be used. The API represented by the RedBlackTree object tries to hide these + * optimizations behind a reasonably clean API. + * + * @since 2.10 + */ +private[collection] +object RedBlackTree { + + def isEmpty(tree: Tree[_, _]): Boolean = tree eq null + + def contains[A: Ordering](tree: Tree[A, _], x: A): Boolean = lookup(tree, x) ne null + def get[A: Ordering, B](tree: Tree[A, B], x: A): Option[B] = lookup(tree, x) match { + case null => None + case tree => Some(tree.value) + } + + @tailrec + def lookup[A, B](tree: Tree[A, B], x: A)(implicit ordering: Ordering[A]): Tree[A, B] = if (tree eq null) null else { + val cmp = ordering.compare(x, tree.key) + if (cmp < 0) lookup(tree.left, x) + else if (cmp > 0) lookup(tree.right, x) + else tree + } + + def count(tree: Tree[_, _]) = if (tree eq null) 0 else tree.count + /** + * Count all the nodes with keys greater than or equal to the lower bound and less than the upper bound. + * The two bounds are optional. + */ + def countInRange[A](tree: Tree[A, _], from: Option[A], to:Option[A])(implicit ordering: Ordering[A]) : Int = + if (tree eq null) 0 else + (from, to) match { + // with no bounds use this node's count + case (None, None) => tree.count + // if node is less than the lower bound, try the tree on the right, it might be in range + case (Some(lb), _) if ordering.lt(tree.key, lb) => countInRange(tree.right, from, to) + // if node is greater than or equal to the upper bound, try the tree on the left, it might be in range + case (_, Some(ub)) if ordering.gteq(tree.key, ub) => countInRange(tree.left, from, to) + // node is in range so the tree on the left will all be less than the upper bound and the tree on the + // right will all be greater than or equal to the lower bound. So 1 for this node plus + // count the subtrees by stripping off the bounds that we don't need any more + case _ => 1 + countInRange(tree.left, from, None) + countInRange(tree.right, None, to) + + } + def update[A: Ordering, B, B1 >: B](tree: Tree[A, B], k: A, v: B1, overwrite: Boolean): Tree[A, B1] = blacken(upd(tree, k, v, overwrite)) + def delete[A: Ordering, B](tree: Tree[A, B], k: A): Tree[A, B] = blacken(del(tree, k)) + def rangeImpl[A: Ordering, B](tree: Tree[A, B], from: Option[A], until: Option[A]): Tree[A, B] = (from, until) match { + case (Some(from), Some(until)) => this.range(tree, from, until) + case (Some(from), None) => this.from(tree, from) + case (None, Some(until)) => this.until(tree, until) + case (None, None) => tree + } + def range[A: Ordering, B](tree: Tree[A, B], from: A, until: A): Tree[A, B] = blacken(doRange(tree, from, until)) + def from[A: Ordering, B](tree: Tree[A, B], from: A): Tree[A, B] = blacken(doFrom(tree, from)) + def to[A: Ordering, B](tree: Tree[A, B], to: A): Tree[A, B] = blacken(doTo(tree, to)) + def until[A: Ordering, B](tree: Tree[A, B], key: A): Tree[A, B] = blacken(doUntil(tree, key)) + + def drop[A: Ordering, B](tree: Tree[A, B], n: Int): Tree[A, B] = blacken(doDrop(tree, n)) + def take[A: Ordering, B](tree: Tree[A, B], n: Int): Tree[A, B] = blacken(doTake(tree, n)) + def slice[A: Ordering, B](tree: Tree[A, B], from: Int, until: Int): Tree[A, B] = blacken(doSlice(tree, from, until)) + + def smallest[A, B](tree: Tree[A, B]): Tree[A, B] = { + if (tree eq null) throw new NoSuchElementException("empty map") + var result = tree + while (result.left ne null) result = result.left + result + } + def greatest[A, B](tree: Tree[A, B]): Tree[A, B] = { + if (tree eq null) throw new NoSuchElementException("empty map") + var result = tree + while (result.right ne null) result = result.right + result + } + + + def foreach[A,B,U](tree:Tree[A,B], f:((A,B)) => U):Unit = if (tree ne null) _foreach(tree,f) + + private[this] def _foreach[A, B, U](tree: Tree[A, B], f: ((A, B)) => U) { + if (tree.left ne null) _foreach(tree.left, f) + f((tree.key, tree.value)) + if (tree.right ne null) _foreach(tree.right, f) + } + + def foreachKey[A, U](tree:Tree[A,_], f: A => U):Unit = if (tree ne null) _foreachKey(tree,f) + + private[this] def _foreachKey[A, U](tree: Tree[A, _], f: A => U) { + if (tree.left ne null) _foreachKey(tree.left, f) + f((tree.key)) + if (tree.right ne null) _foreachKey(tree.right, f) + } + + def iterator[A: Ordering, B](tree: Tree[A, B], start: Option[A] = None): Iterator[(A, B)] = new EntriesIterator(tree, start) + def keysIterator[A: Ordering](tree: Tree[A, _], start: Option[A] = None): Iterator[A] = new KeysIterator(tree, start) + def valuesIterator[A: Ordering, B](tree: Tree[A, B], start: Option[A] = None): Iterator[B] = new ValuesIterator(tree, start) + + @tailrec + def nth[A, B](tree: Tree[A, B], n: Int): Tree[A, B] = { + val count = this.count(tree.left) + if (n < count) nth(tree.left, n) + else if (n > count) nth(tree.right, n - count - 1) + else tree + } + + def isBlack(tree: Tree[_, _]) = (tree eq null) || isBlackTree(tree) + + private[this] def isRedTree(tree: Tree[_, _]) = tree.isInstanceOf[RedTree[_, _]] + private[this] def isBlackTree(tree: Tree[_, _]) = tree.isInstanceOf[BlackTree[_, _]] + + private[this] def blacken[A, B](t: Tree[A, B]): Tree[A, B] = if (t eq null) null else t.black + + private[this] def mkTree[A, B](isBlack: Boolean, k: A, v: B, l: Tree[A, B], r: Tree[A, B]) = + if (isBlack) BlackTree(k, v, l, r) else RedTree(k, v, l, r) + + private[this] def balanceLeft[A, B, B1 >: B](isBlack: Boolean, z: A, zv: B, l: Tree[A, B1], d: Tree[A, B1]): Tree[A, B1] = { + if (isRedTree(l) && isRedTree(l.left)) + RedTree(l.key, l.value, BlackTree(l.left.key, l.left.value, l.left.left, l.left.right), BlackTree(z, zv, l.right, d)) + else if (isRedTree(l) && isRedTree(l.right)) + RedTree(l.right.key, l.right.value, BlackTree(l.key, l.value, l.left, l.right.left), BlackTree(z, zv, l.right.right, d)) + else + mkTree(isBlack, z, zv, l, d) + } + private[this] def balanceRight[A, B, B1 >: B](isBlack: Boolean, x: A, xv: B, a: Tree[A, B1], r: Tree[A, B1]): Tree[A, B1] = { + if (isRedTree(r) && isRedTree(r.left)) + RedTree(r.left.key, r.left.value, BlackTree(x, xv, a, r.left.left), BlackTree(r.key, r.value, r.left.right, r.right)) + else if (isRedTree(r) && isRedTree(r.right)) + RedTree(r.key, r.value, BlackTree(x, xv, a, r.left), BlackTree(r.right.key, r.right.value, r.right.left, r.right.right)) + else + mkTree(isBlack, x, xv, a, r) + } + private[this] def upd[A, B, B1 >: B](tree: Tree[A, B], k: A, v: B1, overwrite: Boolean)(implicit ordering: Ordering[A]): Tree[A, B1] = if (tree eq null) { + RedTree(k, v, null, null) + } else { + val cmp = ordering.compare(k, tree.key) + if (cmp < 0) balanceLeft(isBlackTree(tree), tree.key, tree.value, upd(tree.left, k, v, overwrite), tree.right) + else if (cmp > 0) balanceRight(isBlackTree(tree), tree.key, tree.value, tree.left, upd(tree.right, k, v, overwrite)) + else if (overwrite || k != tree.key) mkTree(isBlackTree(tree), k, v, tree.left, tree.right) + else tree + } + private[this] def updNth[A, B, B1 >: B](tree: Tree[A, B], idx: Int, k: A, v: B1, overwrite: Boolean): Tree[A, B1] = if (tree eq null) { + RedTree(k, v, null, null) + } else { + val rank = count(tree.left) + 1 + if (idx < rank) balanceLeft(isBlackTree(tree), tree.key, tree.value, updNth(tree.left, idx, k, v, overwrite), tree.right) + else if (idx > rank) balanceRight(isBlackTree(tree), tree.key, tree.value, tree.left, updNth(tree.right, idx - rank, k, v, overwrite)) + else if (overwrite) mkTree(isBlackTree(tree), k, v, tree.left, tree.right) + else tree + } + + /* Based on Stefan Kahrs' Haskell version of Okasaki's Red&Black Trees + * Constructing Red-Black Trees, Ralf Hinze: http://www.cs.ox.ac.uk/ralf.hinze/publications/WAAAPL99b.ps.gz + * Red-Black Trees in a Functional Setting, Chris Okasaki: https://wiki.rice.edu/confluence/download/attachments/2761212/Okasaki-Red-Black.pdf */ + private[this] def del[A, B](tree: Tree[A, B], k: A)(implicit ordering: Ordering[A]): Tree[A, B] = if (tree eq null) null else { + def balance(x: A, xv: B, tl: Tree[A, B], tr: Tree[A, B]) = if (isRedTree(tl)) { + if (isRedTree(tr)) { + RedTree(x, xv, tl.black, tr.black) + } else if (isRedTree(tl.left)) { + RedTree(tl.key, tl.value, tl.left.black, BlackTree(x, xv, tl.right, tr)) + } else if (isRedTree(tl.right)) { + RedTree(tl.right.key, tl.right.value, BlackTree(tl.key, tl.value, tl.left, tl.right.left), BlackTree(x, xv, tl.right.right, tr)) + } else { + BlackTree(x, xv, tl, tr) + } + } else if (isRedTree(tr)) { + if (isRedTree(tr.right)) { + RedTree(tr.key, tr.value, BlackTree(x, xv, tl, tr.left), tr.right.black) + } else if (isRedTree(tr.left)) { + RedTree(tr.left.key, tr.left.value, BlackTree(x, xv, tl, tr.left.left), BlackTree(tr.key, tr.value, tr.left.right, tr.right)) + } else { + BlackTree(x, xv, tl, tr) + } + } else { + BlackTree(x, xv, tl, tr) + } + def subl(t: Tree[A, B]) = + if (t.isInstanceOf[BlackTree[_, _]]) t.red + else sys.error("Defect: invariance violation; expected black, got "+t) + + def balLeft(x: A, xv: B, tl: Tree[A, B], tr: Tree[A, B]) = if (isRedTree(tl)) { + RedTree(x, xv, tl.black, tr) + } else if (isBlackTree(tr)) { + balance(x, xv, tl, tr.red) + } else if (isRedTree(tr) && isBlackTree(tr.left)) { + RedTree(tr.left.key, tr.left.value, BlackTree(x, xv, tl, tr.left.left), balance(tr.key, tr.value, tr.left.right, subl(tr.right))) + } else { + sys.error("Defect: invariance violation") + } + def balRight(x: A, xv: B, tl: Tree[A, B], tr: Tree[A, B]) = if (isRedTree(tr)) { + RedTree(x, xv, tl, tr.black) + } else if (isBlackTree(tl)) { + balance(x, xv, tl.red, tr) + } else if (isRedTree(tl) && isBlackTree(tl.right)) { + RedTree(tl.right.key, tl.right.value, balance(tl.key, tl.value, subl(tl.left), tl.right.left), BlackTree(x, xv, tl.right.right, tr)) + } else { + sys.error("Defect: invariance violation") + } + def delLeft = if (isBlackTree(tree.left)) balLeft(tree.key, tree.value, del(tree.left, k), tree.right) else RedTree(tree.key, tree.value, del(tree.left, k), tree.right) + def delRight = if (isBlackTree(tree.right)) balRight(tree.key, tree.value, tree.left, del(tree.right, k)) else RedTree(tree.key, tree.value, tree.left, del(tree.right, k)) + def append(tl: Tree[A, B], tr: Tree[A, B]): Tree[A, B] = if (tl eq null) { + tr + } else if (tr eq null) { + tl + } else if (isRedTree(tl) && isRedTree(tr)) { + val bc = append(tl.right, tr.left) + if (isRedTree(bc)) { + RedTree(bc.key, bc.value, RedTree(tl.key, tl.value, tl.left, bc.left), RedTree(tr.key, tr.value, bc.right, tr.right)) + } else { + RedTree(tl.key, tl.value, tl.left, RedTree(tr.key, tr.value, bc, tr.right)) + } + } else if (isBlackTree(tl) && isBlackTree(tr)) { + val bc = append(tl.right, tr.left) + if (isRedTree(bc)) { + RedTree(bc.key, bc.value, BlackTree(tl.key, tl.value, tl.left, bc.left), BlackTree(tr.key, tr.value, bc.right, tr.right)) + } else { + balLeft(tl.key, tl.value, tl.left, BlackTree(tr.key, tr.value, bc, tr.right)) + } + } else if (isRedTree(tr)) { + RedTree(tr.key, tr.value, append(tl, tr.left), tr.right) + } else if (isRedTree(tl)) { + RedTree(tl.key, tl.value, tl.left, append(tl.right, tr)) + } else { + sys.error("unmatched tree on append: " + tl + ", " + tr) + } + + val cmp = ordering.compare(k, tree.key) + if (cmp < 0) delLeft + else if (cmp > 0) delRight + else append(tree.left, tree.right) + } + + private[this] def doFrom[A, B](tree: Tree[A, B], from: A)(implicit ordering: Ordering[A]): Tree[A, B] = { + if (tree eq null) return null + if (ordering.lt(tree.key, from)) return doFrom(tree.right, from) + val newLeft = doFrom(tree.left, from) + if (newLeft eq tree.left) tree + else if (newLeft eq null) upd(tree.right, tree.key, tree.value, overwrite = false) + else rebalance(tree, newLeft, tree.right) + } + private[this] def doTo[A, B](tree: Tree[A, B], to: A)(implicit ordering: Ordering[A]): Tree[A, B] = { + if (tree eq null) return null + if (ordering.lt(to, tree.key)) return doTo(tree.left, to) + val newRight = doTo(tree.right, to) + if (newRight eq tree.right) tree + else if (newRight eq null) upd(tree.left, tree.key, tree.value, overwrite = false) + else rebalance(tree, tree.left, newRight) + } + private[this] def doUntil[A, B](tree: Tree[A, B], until: A)(implicit ordering: Ordering[A]): Tree[A, B] = { + if (tree eq null) return null + if (ordering.lteq(until, tree.key)) return doUntil(tree.left, until) + val newRight = doUntil(tree.right, until) + if (newRight eq tree.right) tree + else if (newRight eq null) upd(tree.left, tree.key, tree.value, overwrite = false) + else rebalance(tree, tree.left, newRight) + } + private[this] def doRange[A, B](tree: Tree[A, B], from: A, until: A)(implicit ordering: Ordering[A]): Tree[A, B] = { + if (tree eq null) return null + if (ordering.lt(tree.key, from)) return doRange(tree.right, from, until) + if (ordering.lteq(until, tree.key)) return doRange(tree.left, from, until) + val newLeft = doFrom(tree.left, from) + val newRight = doUntil(tree.right, until) + if ((newLeft eq tree.left) && (newRight eq tree.right)) tree + else if (newLeft eq null) upd(newRight, tree.key, tree.value, overwrite = false) + else if (newRight eq null) upd(newLeft, tree.key, tree.value, overwrite = false) + else rebalance(tree, newLeft, newRight) + } + + private[this] def doDrop[A, B](tree: Tree[A, B], n: Int): Tree[A, B] = { + if (n <= 0) return tree + if (n >= this.count(tree)) return null + val count = this.count(tree.left) + if (n > count) return doDrop(tree.right, n - count - 1) + val newLeft = doDrop(tree.left, n) + if (newLeft eq tree.left) tree + else if (newLeft eq null) updNth(tree.right, n - count - 1, tree.key, tree.value, overwrite = false) + else rebalance(tree, newLeft, tree.right) + } + private[this] def doTake[A, B](tree: Tree[A, B], n: Int): Tree[A, B] = { + if (n <= 0) return null + if (n >= this.count(tree)) return tree + val count = this.count(tree.left) + if (n <= count) return doTake(tree.left, n) + val newRight = doTake(tree.right, n - count - 1) + if (newRight eq tree.right) tree + else if (newRight eq null) updNth(tree.left, n, tree.key, tree.value, overwrite = false) + else rebalance(tree, tree.left, newRight) + } + private[this] def doSlice[A, B](tree: Tree[A, B], from: Int, until: Int): Tree[A, B] = { + if (tree eq null) return null + val count = this.count(tree.left) + if (from > count) return doSlice(tree.right, from - count - 1, until - count - 1) + if (until <= count) return doSlice(tree.left, from, until) + val newLeft = doDrop(tree.left, from) + val newRight = doTake(tree.right, until - count - 1) + if ((newLeft eq tree.left) && (newRight eq tree.right)) tree + else if (newLeft eq null) updNth(newRight, from - count - 1, tree.key, tree.value, overwrite = false) + else if (newRight eq null) updNth(newLeft, until, tree.key, tree.value, overwrite = false) + else rebalance(tree, newLeft, newRight) + } + + // The zipper returned might have been traversed left-most (always the left child) + // or right-most (always the right child). Left trees are traversed right-most, + // and right trees are traversed leftmost. + + // Returns the zipper for the side with deepest black nodes depth, a flag + // indicating whether the trees were unbalanced at all, and a flag indicating + // whether the zipper was traversed left-most or right-most. + + // If the trees were balanced, returns an empty zipper + private[this] def compareDepth[A, B](left: Tree[A, B], right: Tree[A, B]): (NList[Tree[A, B]], Boolean, Boolean, Int) = { + import NList.cons + // Once a side is found to be deeper, unzip it to the bottom + def unzip(zipper: NList[Tree[A, B]], leftMost: Boolean): NList[Tree[A, B]] = { + val next = if (leftMost) zipper.head.left else zipper.head.right + if (next eq null) zipper + else unzip(cons(next, zipper), leftMost) + } + + // Unzip left tree on the rightmost side and right tree on the leftmost side until one is + // found to be deeper, or the bottom is reached + def unzipBoth(left: Tree[A, B], + right: Tree[A, B], + leftZipper: NList[Tree[A, B]], + rightZipper: NList[Tree[A, B]], + smallerDepth: Int): (NList[Tree[A, B]], Boolean, Boolean, Int) = { + if (isBlackTree(left) && isBlackTree(right)) { + unzipBoth(left.right, right.left, cons(left, leftZipper), cons(right, rightZipper), smallerDepth + 1) + } else if (isRedTree(left) && isRedTree(right)) { + unzipBoth(left.right, right.left, cons(left, leftZipper), cons(right, rightZipper), smallerDepth) + } else if (isRedTree(right)) { + unzipBoth(left, right.left, leftZipper, cons(right, rightZipper), smallerDepth) + } else if (isRedTree(left)) { + unzipBoth(left.right, right, cons(left, leftZipper), rightZipper, smallerDepth) + } else if ((left eq null) && (right eq null)) { + (null, true, false, smallerDepth) + } else if ((left eq null) && isBlackTree(right)) { + val leftMost = true + (unzip(cons(right, rightZipper), leftMost), false, leftMost, smallerDepth) + } else if (isBlackTree(left) && (right eq null)) { + val leftMost = false + (unzip(cons(left, leftZipper), leftMost), false, leftMost, smallerDepth) + } else { + sys.error("unmatched trees in unzip: " + left + ", " + right) + } + } + unzipBoth(left, right, null, null, 0) + } + + private[this] def rebalance[A, B](tree: Tree[A, B], newLeft: Tree[A, B], newRight: Tree[A, B]) = { + // This is like drop(n-1), but only counting black nodes + @tailrec + def findDepth(zipper: NList[Tree[A, B]], depth: Int): NList[Tree[A, B]] = + if (zipper eq null) { + sys.error("Defect: unexpected empty zipper while computing range") + } else if (isBlackTree(zipper.head)) { + if (depth == 1) zipper else findDepth(zipper.tail, depth - 1) + } else { + findDepth(zipper.tail, depth) + } + + // Blackening the smaller tree avoids balancing problems on union; + // this can't be done later, though, or it would change the result of compareDepth + val blkNewLeft = blacken(newLeft) + val blkNewRight = blacken(newRight) + val (zipper, levelled, leftMost, smallerDepth) = compareDepth(blkNewLeft, blkNewRight) + + if (levelled) { + BlackTree(tree.key, tree.value, blkNewLeft, blkNewRight) + } else { + val zipFrom = findDepth(zipper, smallerDepth) + val union = if (leftMost) { + RedTree(tree.key, tree.value, blkNewLeft, zipFrom.head) + } else { + RedTree(tree.key, tree.value, zipFrom.head, blkNewRight) + } + val zippedTree = NList.foldLeft(zipFrom.tail, union: Tree[A, B]) { (tree, node) => + if (leftMost) + balanceLeft(isBlackTree(node), node.key, node.value, tree, node.right) + else + balanceRight(isBlackTree(node), node.key, node.value, node.left, tree) + } + zippedTree + } + } + + // Null optimized list implementation for tree rebalancing. null presents Nil. + private[this] final class NList[A](val head: A, val tail: NList[A]) + + private[this] final object NList { + + def cons[B](x: B, xs: NList[B]): NList[B] = new NList(x, xs) + + def foldLeft[A, B](xs: NList[A], z: B)(op: (B, A) => B): B = { + var acc = z + var these = xs + while (these ne null) { + acc = op(acc, these.head) + these = these.tail + } + acc + } + + } + + /* + * Forcing direct fields access using the @inline annotation helps speed up + * various operations (especially smallest/greatest and update/delete). + * + * Unfortunately the direct field access is not guaranteed to work (but + * works on the current implementation of the Scala compiler). + * + * An alternative is to implement the these classes using plain old Java code... + */ + sealed abstract class Tree[A, +B]( + @(inline @getter) final val key: A, + @(inline @getter) final val value: B, + @(inline @getter) final val left: Tree[A, B], + @(inline @getter) final val right: Tree[A, B]) + extends Serializable { + @(inline @getter) final val count: Int = 1 + RedBlackTree.count(left) + RedBlackTree.count(right) + def black: Tree[A, B] + def red: Tree[A, B] + } + final class RedTree[A, +B](key: A, + value: B, + left: Tree[A, B], + right: Tree[A, B]) extends Tree[A, B](key, value, left, right) { + override def black: Tree[A, B] = BlackTree(key, value, left, right) + override def red: Tree[A, B] = this + override def toString: String = "RedTree(" + key + ", " + value + ", " + left + ", " + right + ")" + } + final class BlackTree[A, +B](key: A, + value: B, + left: Tree[A, B], + right: Tree[A, B]) extends Tree[A, B](key, value, left, right) { + override def black: Tree[A, B] = this + override def red: Tree[A, B] = RedTree(key, value, left, right) + override def toString: String = "BlackTree(" + key + ", " + value + ", " + left + ", " + right + ")" + } + + object RedTree { + @inline def apply[A, B](key: A, value: B, left: Tree[A, B], right: Tree[A, B]) = new RedTree(key, value, left, right) + def unapply[A, B](t: RedTree[A, B]) = Some((t.key, t.value, t.left, t.right)) + } + object BlackTree { + @inline def apply[A, B](key: A, value: B, left: Tree[A, B], right: Tree[A, B]) = new BlackTree(key, value, left, right) + def unapply[A, B](t: BlackTree[A, B]) = Some((t.key, t.value, t.left, t.right)) + } + + private[this] abstract class TreeIterator[A, B, R](root: Tree[A, B], start: Option[A])(implicit ordering: Ordering[A]) extends Iterator[R] { + protected[this] def nextResult(tree: Tree[A, B]): R + + override def hasNext: Boolean = lookahead ne null + + override def next: R = lookahead match { + case null => + throw new NoSuchElementException("next on empty iterator") + case tree => + lookahead = findLeftMostOrPopOnEmpty(goRight(tree)) + nextResult(tree) + } + + @tailrec + private[this] def findLeftMostOrPopOnEmpty(tree: Tree[A, B]): Tree[A, B] = + if (tree eq null) popNext() + else if (tree.left eq null) tree + else findLeftMostOrPopOnEmpty(goLeft(tree)) + + private[this] def pushNext(tree: Tree[A, B]) { + try { + stackOfNexts(index) = tree + index += 1 + } catch { + case _: ArrayIndexOutOfBoundsException => + /* + * Either the tree became unbalanced or we calculated the maximum height incorrectly. + * To avoid crashing the iterator we expand the path array. Obviously this should never + * happen... + * + * An exception handler is used instead of an if-condition to optimize the normal path. + * This makes a large difference in iteration speed! + */ + assert(index >= stackOfNexts.length) + stackOfNexts :+= null + pushNext(tree) + } + } + private[this] def popNext(): Tree[A, B] = if (index == 0) null else { + index -= 1 + stackOfNexts(index) + } + + private[this] var stackOfNexts = if (root eq null) null else { + /* + * According to "Ralf Hinze. Constructing red-black trees" [http://www.cs.ox.ac.uk/ralf.hinze/publications/#P5] + * the maximum height of a red-black tree is 2*log_2(n + 2) - 2. + * + * According to {@see Integer#numberOfLeadingZeros} ceil(log_2(n)) = (32 - Integer.numberOfLeadingZeros(n - 1)) + * + * We also don't store the deepest nodes in the path so the maximum path length is further reduced by one. + */ + val maximumHeight = 2 * (32 - Integer.numberOfLeadingZeros(root.count + 2 - 1)) - 2 - 1 + new Array[Tree[A, B]](maximumHeight) + } + private[this] var index = 0 + private[this] var lookahead: Tree[A, B] = start map startFrom getOrElse findLeftMostOrPopOnEmpty(root) + + /** + * Find the leftmost subtree whose key is equal to the given key, or if no such thing, + * the leftmost subtree with the key that would be "next" after it according + * to the ordering. Along the way build up the iterator's path stack so that "next" + * functionality works. + */ + private[this] def startFrom(key: A) : Tree[A,B] = if (root eq null) null else { + @tailrec def find(tree: Tree[A, B]): Tree[A, B] = + if (tree eq null) popNext() + else find( + if (ordering.lteq(key, tree.key)) goLeft(tree) + else goRight(tree) + ) + find(root) + } + + private[this] def goLeft(tree: Tree[A, B]) = { + pushNext(tree) + tree.left + } + + private[this] def goRight(tree: Tree[A, B]) = tree.right + } + + private[this] class EntriesIterator[A: Ordering, B](tree: Tree[A, B], focus: Option[A]) extends TreeIterator[A, B, (A, B)](tree, focus) { + override def nextResult(tree: Tree[A, B]) = (tree.key, tree.value) + } + + private[this] class KeysIterator[A: Ordering, B](tree: Tree[A, B], focus: Option[A]) extends TreeIterator[A, B, A](tree, focus) { + override def nextResult(tree: Tree[A, B]) = tree.key + } + + private[this] class ValuesIterator[A: Ordering, B](tree: Tree[A, B], focus: Option[A]) extends TreeIterator[A, B, B](tree, focus) { + override def nextResult(tree: Tree[A, B]) = tree.value + } +} From 3ccca0d60dc306a8cceeca5145ee5b9b7ecf7aef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 24 Jan 2017 18:36:40 +0100 Subject: [PATCH 0113/2665] Fix the size of the stack used by RedBlackTree.iteratorFrom. This is a backport to Scala.js of the change introduced in PR https://github.com/scala/scala/pull/5645. It is important to Scala.js because the previous code relies on undefined behavior of `ArrayIndexOutOfBoundsException`. --- .../scala/collection/immutable/RedBlackTree.scala | 2 +- .../overrides/scala/collection/immutable/RedBlackTree.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scalalib/overrides-2.10/scala/collection/immutable/RedBlackTree.scala b/scalalib/overrides-2.10/scala/collection/immutable/RedBlackTree.scala index 0254e9ca3a..4aa4b4f63a 100644 --- a/scalalib/overrides-2.10/scala/collection/immutable/RedBlackTree.scala +++ b/scalalib/overrides-2.10/scala/collection/immutable/RedBlackTree.scala @@ -475,7 +475,7 @@ object RedBlackTree { * * We also don't store the deepest nodes in the path so the maximum path length is further reduced by one. */ - val maximumHeight = 2 * (32 - Integer.numberOfLeadingZeros(tree.count + 2 - 1)) - 2 - 1 + val maximumHeight = 2 * (32 - Integer.numberOfLeadingZeros(tree.count + 2 - 1)) - 2 new Array[Tree[A, B]](maximumHeight) } private[this] var index = 0 diff --git a/scalalib/overrides/scala/collection/immutable/RedBlackTree.scala b/scalalib/overrides/scala/collection/immutable/RedBlackTree.scala index afb4c9c552..31e59642d9 100644 --- a/scalalib/overrides/scala/collection/immutable/RedBlackTree.scala +++ b/scalalib/overrides/scala/collection/immutable/RedBlackTree.scala @@ -518,7 +518,7 @@ object RedBlackTree { * * We also don't store the deepest nodes in the path so the maximum path length is further reduced by one. */ - val maximumHeight = 2 * (32 - Integer.numberOfLeadingZeros(root.count + 2 - 1)) - 2 - 1 + val maximumHeight = 2 * (32 - Integer.numberOfLeadingZeros(root.count + 2 - 1)) - 2 new Array[Tree[A, B]](maximumHeight) } private[this] var index = 0 From c9339c24096b352f4226e7c78425fa88a12721f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 15 Jan 2017 16:22:36 +0100 Subject: [PATCH 0114/2665] Implement checked behavior of ArrayIndexOutOfBoundsExceptions. This brings support for `ArrayIndexOutOfBoundsExceptions` on par with `ClassCastException`s, i.e., they are controlled by a `CheckedBehavior` setting in `scalaJSSemantics`. The checked behavior is Fatal by default in fastOpt and Unchecked in fullOpt, as `asInstanceOfs`. --- ci/checksizes.sh | 4 +- .../src/main/scala/java/lang/System.scala | 15 ++-- javalib/src/main/scala/java/util/Arrays.scala | 15 ++-- .../scala/scalajs/runtime/LinkingInfo.scala | 3 + .../scalajs/runtime/SemanticsUtils.scala | 13 ++++ project/BinaryIncompatibilities.scala | 9 +++ project/Build.scala | 6 ++ .../scalajs/testsuite/utils/Platform.scala | 4 + .../scalajs/testsuite/utils/Platform.scala | 1 + .../testsuite/compiler/ArrayTest.scala | 43 +++++++++++ .../testsuite/javalib/lang/SystemTest.scala | 42 +++++++++- .../testsuite/javalib/util/ArraysTest.scala | 60 ++++++++------- tools/scalajsenv.js | 66 ++++++++++++++-- .../linker/backend/emitter/CoreJSLibs.scala | 2 + .../linker/backend/emitter/Emitter.scala | 6 +- .../linker/backend/emitter/JSDesugaring.scala | 29 +++++-- .../frontend/optimizer/OptimizerCore.scala | 2 + .../scalajs/core/tools/sem/Semantics.scala | 76 +++++++++++-------- 18 files changed, 308 insertions(+), 88 deletions(-) create mode 100644 test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ArrayTest.scala diff --git a/ci/checksizes.sh b/ci/checksizes.sh index 1cde0a5d9c..02ca9c3f08 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -40,13 +40,13 @@ case $FULLVER in REVERSI_OPT_GZ_EXPECTEDSIZE=31000 ;; 2.11.8) - REVERSI_PREOPT_EXPECTEDSIZE=526000 + REVERSI_PREOPT_EXPECTEDSIZE=527000 REVERSI_OPT_EXPECTEDSIZE=121000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=71000 REVERSI_OPT_GZ_EXPECTEDSIZE=32000 ;; 2.12.1) - REVERSI_PREOPT_EXPECTEDSIZE=490000 + REVERSI_PREOPT_EXPECTEDSIZE=492000 REVERSI_OPT_EXPECTEDSIZE=114000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=66000 REVERSI_OPT_GZ_EXPECTEDSIZE=29000 diff --git a/javalanglib/src/main/scala/java/lang/System.scala b/javalanglib/src/main/scala/java/lang/System.scala index 725224d249..905fe17260 100644 --- a/javalanglib/src/main/scala/java/lang/System.scala +++ b/javalanglib/src/main/scala/java/lang/System.scala @@ -3,12 +3,11 @@ package java.lang import java.io._ import scala.scalajs.js -import js.Dynamic.global +import scala.scalajs.js.Dynamic.global import scala.scalajs.LinkingInfo.assumingES6 -import scala.scalajs.runtime.linkingInfo +import scala.scalajs.runtime.{environmentInfo, linkingInfo, SemanticsUtils} import java.{util => ju} -import scalajs.runtime.environmentInfo object System { var out: PrintStream = new JSConsoleBasedPrintStream(isErr = false) @@ -54,9 +53,13 @@ object System { import scala.{Boolean, Char, Byte, Short, Int, Long, Float, Double} @inline def checkIndices(srcLen: Int, destLen: Int): Unit = { - if (srcPos < 0 || destPos < 0 || length < 0 || - srcPos + length > srcLen || destPos + length > destLen) - throw new ArrayIndexOutOfBoundsException("Array index out of bounds") + SemanticsUtils.arrayIndexOutOfBoundsCheck({ + srcPos < 0 || destPos < 0 || length < 0 || + srcPos > srcLen - length || + destPos > destLen - length + }, { + new ArrayIndexOutOfBoundsException() + }) } def mismatch(): Nothing = diff --git a/javalib/src/main/scala/java/util/Arrays.scala b/javalib/src/main/scala/java/util/Arrays.scala index 30cfe60c1a..24c74f7e02 100644 --- a/javalib/src/main/scala/java/util/Arrays.scala +++ b/javalib/src/main/scala/java/util/Arrays.scala @@ -1,6 +1,7 @@ package java.util -import scalajs.js +import scala.scalajs.js +import scala.scalajs.runtime.SemanticsUtils import scala.annotation.tailrec @@ -583,8 +584,8 @@ object Arrays { len: Int, start: Int, end: Int): Unit = { if (start > end) throw new IllegalArgumentException(start + " > " + end) - if (start < 0 || start > len) - throw new ArrayIndexOutOfBoundsException + SemanticsUtils.arrayIndexOutOfBoundsCheck(start < 0 || start > len, + new ArrayIndexOutOfBoundsException) } @noinline def asList[T <: AnyRef](a: Array[T]): List[T] = { @@ -726,10 +727,10 @@ object Arrays { private def checkRangeIndices(length: Int, start: Int, end: Int): Unit = { if (start > end) throw new IllegalArgumentException("fromIndex(" + start + ") > toIndex(" + end + ")") - if (start < 0) - throw new ArrayIndexOutOfBoundsException("Array index out of range: " + start) - if (end > length) - throw new ArrayIndexOutOfBoundsException("Array index out of range: " + end) + SemanticsUtils.arrayIndexOutOfBoundsCheck(start < 0, + new ArrayIndexOutOfBoundsException("Array index out of range: " + start)) + SemanticsUtils.arrayIndexOutOfBoundsCheck(end > length, + new ArrayIndexOutOfBoundsException("Array index out of range: " + end)) } @inline diff --git a/library/src/main/scala/scala/scalajs/runtime/LinkingInfo.scala b/library/src/main/scala/scala/scalajs/runtime/LinkingInfo.scala index bedde0a74e..3d372b8d77 100644 --- a/library/src/main/scala/scala/scalajs/runtime/LinkingInfo.scala +++ b/library/src/main/scala/scala/scalajs/runtime/LinkingInfo.scala @@ -25,6 +25,9 @@ object LinkingInfo { /** Compliance level of asInstanceOfs. */ val asInstanceOfs: Int = js.native + /** Compliance level of arrayIndexOutOfBounds. */ + val arrayIndexOutOfBounds: Int = js.native + /** Compliance level of moduleInit. */ val moduleInit: Int = js.native diff --git a/library/src/main/scala/scala/scalajs/runtime/SemanticsUtils.scala b/library/src/main/scala/scala/scalajs/runtime/SemanticsUtils.scala index 91af95f077..6d365f26b2 100644 --- a/library/src/main/scala/scala/scalajs/runtime/SemanticsUtils.scala +++ b/library/src/main/scala/scala/scalajs/runtime/SemanticsUtils.scala @@ -22,6 +22,19 @@ object SemanticsUtils { genericCheck(asInstanceOfs, shouldThrow, exception) } + @inline + private def arrayIndexOutOfBounds: Int = + linkingInfo.semantics.arrayIndexOutOfBounds + + /** Tests for an erroneous condition governed by the `arrayIndexOutOfBounds` + * semantics. + */ + @inline + def arrayIndexOutOfBoundsCheck(shouldThrow: => Boolean, + exception: => Throwable): Unit = { + genericCheck(arrayIndexOutOfBounds, shouldThrow, exception) + } + @inline private def genericCheck(complianceLevel: Int, shouldThrow: => Boolean, exception: => Throwable): Unit = { diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 4f7393444c..c5c10ad148 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -45,6 +45,10 @@ object BinaryIncompatibilities { ) val Tools = Seq( + // private, not an issue + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.sem.Semantics.this"), + // private, not an issue ProblemFilters.exclude[DirectMissingMethodProblem]( "org.scalajs.core.tools.linker.checker.IRChecker#CheckedField.this"), @@ -116,6 +120,11 @@ object BinaryIncompatibilities { ) val Library = Seq( + // New members of an @js.native trait in `runtime`, not an issue + ProblemFilters.exclude[ReversedMissingMethodProblem]( + "scala.scalajs.runtime.LinkingInfo#Semantics.arrayIndexOutOfBounds"), + ProblemFilters.exclude[ReversedMissingMethodProblem]( + "scala.scalajs.runtime.LinkingInfo#Semantics.scala$scalajs$runtime$LinkingInfo$Semantics$_setter_$arrayIndexOutOfBounds_=") ) val TestInterface = Seq( diff --git a/project/Build.scala b/project/Build.scala index ffe083141a..4075ec1050 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -77,6 +77,7 @@ object Build { val makeCompliant: Semantics => Semantics = { semantics => semantics .withAsInstanceOfs(CheckedBehavior.Compliant) + .withArrayIndexOutOfBounds(CheckedBehavior.Compliant) .withModuleInit(CheckedBehavior.Compliant) .withStrictFloats(true) } @@ -1296,6 +1297,11 @@ object Build { Seq("compliant-asinstanceofs") else Seq() + ) ++ ( + if (sems.arrayIndexOutOfBounds == CheckedBehavior.Compliant) + Seq("compliant-arrayindexoutofbounds") + else + Seq() ) ++ ( if (sems.moduleInit == CheckedBehavior.Compliant) Seq("compliant-moduleinit") diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala index b4957c5b8d..5797fa2173 100644 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala +++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala @@ -43,6 +43,10 @@ object Platform { def isInDevelopmentMode: Boolean = sysProp("development-mode") def hasCompliantAsInstanceOfs: Boolean = sysProp("compliant-asinstanceofs") + + def hasCompliantArrayIndexOutOfBounds: Boolean = + sysProp("compliant-arrayindexoutofbounds") + def hasCompliantModule: Boolean = sysProp("compliant-moduleinit") def hasStrictFloats: Boolean = sysProp("strict-floats") diff --git a/test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala b/test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala index 05af9429d8..2382bd18ab 100644 --- a/test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala +++ b/test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala @@ -33,6 +33,7 @@ object Platform { def isInDevelopmentMode: Boolean = true def hasCompliantAsInstanceOfs: Boolean = true + def hasCompliantArrayIndexOutOfBounds: Boolean = true def hasCompliantModule: Boolean = true def hasStrictFloats: Boolean = true } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ArrayTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ArrayTest.scala new file mode 100644 index 0000000000..52d7e0a343 --- /dev/null +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ArrayTest.scala @@ -0,0 +1,43 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.compiler + +import org.junit.Test +import org.junit.Assert._ +import org.junit.Assume._ + +import org.scalajs.testsuite.utils.AssertThrows._ +import org.scalajs.testsuite.utils.Platform.hasCompliantArrayIndexOutOfBounds + +class ArrayTest { + + @Test + def getArrayIndexOutOfBounds(): Unit = { + assumeTrue("Assuming compliant ArrayIndexOutOfBounds", + hasCompliantArrayIndexOutOfBounds) + + val a = new Array[Int](5) + assertThrows(classOf[ArrayIndexOutOfBoundsException], a(-1)) + assertThrows(classOf[ArrayIndexOutOfBoundsException], a(5)) + assertThrows(classOf[ArrayIndexOutOfBoundsException], a(Int.MinValue)) + assertThrows(classOf[ArrayIndexOutOfBoundsException], a(Int.MaxValue)) + } + + @Test + def setArrayIndexOutOfBounds(): Unit = { + assumeTrue("Assuming compliant ArrayIndexOutOfBounds", + hasCompliantArrayIndexOutOfBounds) + + val a = new Array[Int](5) + assertThrows(classOf[ArrayIndexOutOfBoundsException], a(-1) = 1) + assertThrows(classOf[ArrayIndexOutOfBoundsException], a(5) = 1) + assertThrows(classOf[ArrayIndexOutOfBoundsException], a(Int.MinValue) = 1) + assertThrows(classOf[ArrayIndexOutOfBoundsException], a(Int.MaxValue) = 1) + } + +} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemTest.scala index 52bc856aba..abf468af4c 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemTest.scala @@ -11,9 +11,10 @@ import language.implicitConversions import org.junit.Test import org.junit.Assert._ +import org.junit.Assume._ -import org.scalajs.testsuite.utils.AssertThrows.expectThrows -import org.scalajs.testsuite.utils.Platform.executingInJVM +import org.scalajs.testsuite.utils.AssertThrows._ +import org.scalajs.testsuite.utils.Platform._ class SystemTest { @@ -107,6 +108,43 @@ class SystemTest { assertArrayEquals(Array(0, 1, 2, 0, 1, 1, 0, 2, 1, 0), array) } + @Test def arraycopyIndexOutOfBounds(): Unit = { + assumeTrue("Assuming compliant ArrayIndexOutOfBounds", + hasCompliantArrayIndexOutOfBounds) + + val src = Array(0, 1, 2, 3, 4, 5, 6, 0, 0, 0) + val dest = Array(11, 12, 13, 15, 15, 16) + val original = Array(11, 12, 13, 15, 15, 16) + + assertThrows(classOf[ArrayIndexOutOfBoundsException], + System.arraycopy(src, -1, dest, 3, 4)) + assertArrayEquals(original, dest) + + assertThrows(classOf[ArrayIndexOutOfBoundsException], + System.arraycopy(src, 8, dest, 3, 4)) + assertArrayEquals(original, dest) + + assertThrows(classOf[ArrayIndexOutOfBoundsException], + System.arraycopy(src, 1, dest, -1, 4)) + assertArrayEquals(original, dest) + + assertThrows(classOf[ArrayIndexOutOfBoundsException], + System.arraycopy(src, 1, dest, 4, 4)) + assertArrayEquals(original, dest) + + assertThrows(classOf[ArrayIndexOutOfBoundsException], + System.arraycopy(src, 11, dest, 3, 4)) + assertArrayEquals(original, dest) + + assertThrows(classOf[ArrayIndexOutOfBoundsException], + System.arraycopy(src, 1, dest, 13, 4)) + assertArrayEquals(original, dest) + + assertThrows(classOf[ArrayIndexOutOfBoundsException], + System.arraycopy(src, 1, dest, 3, Int.MaxValue)) + assertArrayEquals(original, dest) + } + @Test def identityHashCode(): Unit = { class HasIDHashCode diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ArraysTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ArraysTest.scala index 5654804506..5f9c29cec1 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ArraysTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ArraysTest.scala @@ -13,6 +13,7 @@ import org.junit.Assert._ import org.junit.Assume._ import org.junit.Test +import org.scalajs.testsuite.utils.AssertThrows._ import org.scalajs.testsuite.utils.Platform._ import java.util.{ Arrays, Comparator } @@ -475,40 +476,32 @@ class ArraysTest { assertEquals(-7, ret) } - @Test def should_check_ranges_of_input_to_binarySearch(): Unit = { - def expectException(block: => Unit)(expected: PartialFunction[Throwable, Unit]): Unit = { - val catchAll: PartialFunction[Throwable, Unit] = { - case e: Throwable => assertEquals("not thrown", e.getClass.getName) - } - - try { - block - assertEquals("thrown", "exception") - } catch expected orElse catchAll - } - + @Test def binarySearchIllegalArgumentException(): Unit = { val array = Array(0, 1, 3, 4) - expectException({ Arrays.binarySearch(array, 3, 2, 2) }) { - case exception: IllegalArgumentException => - assertEquals("fromIndex(3) > toIndex(2)", exception.getMessage) - } + val e1 = expectThrows(classOf[IllegalArgumentException], + Arrays.binarySearch(array, 3, 2, 2)) + assertEquals("fromIndex(3) > toIndex(2)", e1.getMessage) // start/end comparison is made before index ranges checks - expectException({ Arrays.binarySearch(array, 7, 5, 2) }) { - case exception: IllegalArgumentException => - assertEquals("fromIndex(7) > toIndex(5)", exception.getMessage) - } + val e2 = expectThrows(classOf[IllegalArgumentException], + Arrays.binarySearch(array, 7, 5, 2)) + assertEquals("fromIndex(7) > toIndex(5)", e2.getMessage) + } - expectException({ Arrays.binarySearch(array, -1, 4, 2) }) { - case exception: ArrayIndexOutOfBoundsException => - assertEquals("Array index out of range: -1", exception.getMessage) - } + @Test def binarySearchArrayIndexOutOfBoundsException(): Unit = { + assumeTrue("Assuming compliant ArrayIndexOutOfBounds", + hasCompliantArrayIndexOutOfBounds) - expectException({ Arrays.binarySearch(array, 0, 5, 2) }) { - case exception: ArrayIndexOutOfBoundsException => - assertEquals("Array index out of range: 5", exception.getMessage) - } + val array = Array(0, 1, 3, 4) + + val e1 = expectThrows(classOf[ArrayIndexOutOfBoundsException], + Arrays.binarySearch(array, -1, 4, 2)) + assertEquals("Array index out of range: -1", e1.getMessage) + + val e2 = expectThrows(classOf[ArrayIndexOutOfBoundsException], + Arrays.binarySearch(array, 0, 5, 2)) + assertEquals("Array index out of range: 5", e2.getMessage) } @Test def copyOf_Int(): Unit = { @@ -602,6 +595,17 @@ class ArraysTest { assertArrayEquals(Array[A](B(3), B(4)), bscopyAsA) } + @Test def copyOfRange_AnyRef_ArrayIndexOutOfBoundsException(): Unit = { + assumeTrue("Assuming compliant ArrayIndexOutOfBounds", + hasCompliantArrayIndexOutOfBounds) + + val anyrefs: Array[AnyRef] = Array("a", "b", "c", "d", "e") + assertThrows(classOf[ArrayIndexOutOfBoundsException], + Arrays.copyOfRange(anyrefs, -1, 4)) + assertThrows(classOf[ArrayIndexOutOfBoundsException], + Arrays.copyOfRange(anyrefs, 6, 8)) + } + @Test def asList(): Unit = { val list = Arrays.asList(1, 2, 3) assertEquals(list.size(), 3) diff --git a/tools/scalajsenv.js b/tools/scalajsenv.js index 2baf06e16a..5345ba8e68 100644 --- a/tools/scalajsenv.js +++ b/tools/scalajsenv.js @@ -47,6 +47,15 @@ ScalaJS.linkingInfo = { "asInstanceOfs": 2, //!endif //!endif +//!if arrayIndexOutOfBounds == Compliant + "arrayIndexOutOfBounds": 0, +//!else +//!if arrayIndexOutOfBounds == Fatal + "arrayIndexOutOfBounds": 1, +//!else + "arrayIndexOutOfBounds": 2, +//!endif +//!endif //!if moduleInit == Compliant "moduleInit": 0, //!else @@ -211,6 +220,18 @@ ScalaJS.throwArrayCastException = function(instance, classArrayEncodedName, dept }; //!endif +//!if arrayIndexOutOfBounds != Unchecked +ScalaJS.throwArrayIndexOutOfBoundsException = function(i) { + const msg = (i === null) ? null : ("" + i); +//!if arrayIndexOutOfBounds == Compliant + throw new ScalaJS.c.jl_ArrayIndexOutOfBoundsException().init___T(msg); +//!else + throw new ScalaJS.c.sjsr_UndefinedBehaviorError().init___jl_Throwable( + new ScalaJS.c.jl_ArrayIndexOutOfBoundsException().init___T(msg)); +//!endif +}; +//!endif + ScalaJS.noIsInstance = function(instance) { throw new ScalaJS.g["TypeError"]( "Cannot call isInstance() on a Class representing a raw JS trait/object"); @@ -516,12 +537,21 @@ ScalaJS.propertiesOf = function(obj) { ScalaJS.systemArraycopy = function(src, srcPos, dest, destPos, length) { const srcu = src.u; const destu = dest.u; - if (srcu !== destu || destPos < srcPos || srcPos + length < destPos) { - for (let i = 0; i < length; i++) - destu[destPos+i] = srcu[srcPos+i]; + +//!if arrayIndexOutOfBounds != Unchecked + if (srcPos < 0 || destPos < 0 || length < 0 || + (srcPos > ((srcu.length - length) | 0)) || + (destPos > ((destu.length - length) | 0))) { + ScalaJS.throwArrayIndexOutOfBoundsException(null); + } +//!endif + + if (srcu !== destu || destPos < srcPos || (((srcPos + length) | 0) < destPos)) { + for (let i = 0; i < length; i = (i + 1) | 0) + destu[(destPos + i) | 0] = srcu[(srcPos + i) | 0]; } else { - for (let i = length-1; i >= 0; i--) - destu[destPos+i] = srcu[srcPos+i]; + for (let i = (length - 1) | 0; i >= 0; i = (i - 1) | 0) + destu[(destPos + i) | 0] = srcu[(srcPos + i) | 0]; } }; @@ -828,6 +858,19 @@ initArray( ArrayClass.prototype = new ScalaJS.h.O; ArrayClass.prototype.constructor = ArrayClass; +//!if arrayIndexOutOfBounds != Unchecked + ArrayClass.prototype.get = function(i) { + if (i < 0 || i >= this.u.length) + ScalaJS.throwArrayIndexOutOfBoundsException(i); + return this.u[i]; + }; + ArrayClass.prototype.set = function(i, v) { + if (i < 0 || i >= this.u.length) + ScalaJS.throwArrayIndexOutOfBoundsException(i); + this.u[i] = v; + }; +//!endif + ArrayClass.prototype.clone__O = function() { if (this.u instanceof Array) return new ArrayClass(this.u["slice"](0)); @@ -850,6 +893,19 @@ initArray( } }; +//!if arrayIndexOutOfBounds != Unchecked + get(i) { + if (i < 0 || i >= this.u.length) + ScalaJS.throwArrayIndexOutOfBoundsException(i); + return this.u[i]; + }; + set(i, v) { + if (i < 0 || i >= this.u.length) + ScalaJS.throwArrayIndexOutOfBoundsException(i); + this.u[i] = v; + }; +//!endif + clone__O() { if (this.u instanceof Array) return new ArrayClass(this.u["slice"](0)); diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala index 27a5d882bd..f86dcfe8c0 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala @@ -57,6 +57,8 @@ private[backend] object CoreJSLibs { def getOption(name: String): String = name match { case "asInstanceOfs" => semantics.asInstanceOfs.toString() + case "arrayIndexOutOfBounds" => + semantics.arrayIndexOutOfBounds.toString() case "moduleInit" => semantics.moduleInit.toString() case "floats" => diff --git 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 index 8edfab8288..46c3e4a8ea 100644 --- 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 @@ -512,7 +512,11 @@ private[scalajs] object Emitter { instantiateClass("jl_ClassCastException", "init___T") }, - cond(asInstanceOfs == Fatal) { + cond(arrayIndexOutOfBounds != Unchecked) { + instantiateClass("jl_ArrayIndexOutOfBoundsException", "init___T") + }, + + cond(asInstanceOfs == Fatal || arrayIndexOutOfBounds == Fatal) { instantiateClass("sjsr_UndefinedBehaviorError", "init___jl_Throwable") }, diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala index e077e6d9fc..45c6ad2cb8 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala @@ -398,11 +398,20 @@ private[emitter] class JSDesugaring(semantics: Semantics, unnest(List(array, index, rhs)) { case (List(newArray, newIndex, newRhs), env0) => implicit val env = env0 - js.Assign( - js.BracketSelect(js.DotSelect(transformExpr(newArray), - js.Ident("u"))(select.pos), - transformExpr(newIndex))(select.pos), - transformExpr(newRhs)) + val genArray = transformExpr(newArray) + val genIndex = transformExpr(newIndex) + val genRhs = transformExpr(newRhs) + semantics.arrayIndexOutOfBounds match { + case CheckedBehavior.Compliant | CheckedBehavior.Fatal => + js.Apply(js.DotSelect(genArray, js.Ident("set")), + List(genIndex, genRhs)) + case CheckedBehavior.Unchecked => + js.Assign( + js.BracketSelect( + js.DotSelect(genArray, js.Ident("u"))(select.pos), + genIndex)(select.pos), + genRhs) + } } case Assign(select @ JSDotSelect(qualifier, item), rhs) => @@ -1812,8 +1821,14 @@ private[emitter] class JSDesugaring(semantics: Semantics, Ident("u")), "length") case ArraySelect(array, index) => - js.BracketSelect(js.DotSelect(transformExpr(array), - Ident("u")), transformExpr(index)) + val newArray = transformExpr(array) + val newIndex = transformExpr(index) + semantics.arrayIndexOutOfBounds match { + case CheckedBehavior.Compliant | CheckedBehavior.Fatal => + js.Apply(js.DotSelect(newArray, js.Ident("get")), List(newIndex)) + case CheckedBehavior.Unchecked => + js.BracketSelect(js.DotSelect(newArray, js.Ident("u")), newIndex) + } case IsInstanceOf(expr, cls) => genIsInstanceOf(transformExpr(expr), cls) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index 9fcb95c222..a2fcb65aab 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -3572,6 +3572,8 @@ private[optimizer] abstract class OptimizerCore( semanticsStr match { case "asInstanceOfs" => behavior2IntLiteral(semantics.asInstanceOfs) + case "arrayIndexOutOfBounds" => + behavior2IntLiteral(semantics.arrayIndexOutOfBounds) case "moduleInit" => behavior2IntLiteral(semantics.moduleInit) case "strictFloats" => diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/sem/Semantics.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/sem/Semantics.scala index f6055d14c1..75de64ff84 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/sem/Semantics.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/sem/Semantics.scala @@ -13,8 +13,11 @@ import scala.collection.immutable.Traversable import org.scalajs.core.tools.linker.LinkedClass +import CheckedBehavior._ + final class Semantics private ( val asInstanceOfs: CheckedBehavior, + val arrayIndexOutOfBounds: CheckedBehavior, val moduleInit: CheckedBehavior, val strictFloats: Boolean, val productionMode: Boolean, @@ -25,6 +28,9 @@ final class Semantics private ( def withAsInstanceOfs(behavior: CheckedBehavior): Semantics = copy(asInstanceOfs = behavior) + def withArrayIndexOutOfBounds(behavior: CheckedBehavior): Semantics = + copy(arrayIndexOutOfBounds = behavior) + def withModuleInit(moduleInit: CheckedBehavior): Semantics = copy(moduleInit = moduleInit) @@ -39,15 +45,17 @@ final class Semantics private ( def optimized: Semantics = { copy(asInstanceOfs = this.asInstanceOfs.optimized, + arrayIndexOutOfBounds = this.arrayIndexOutOfBounds.optimized, moduleInit = this.moduleInit.optimized, productionMode = true) } override def equals(that: Any): Boolean = that match { case that: Semantics => - this.asInstanceOfs == that.asInstanceOfs && - this.moduleInit == that.moduleInit && - this.strictFloats == that.strictFloats && + this.asInstanceOfs == that.asInstanceOfs && + this.arrayIndexOutOfBounds == that.arrayIndexOutOfBounds && + this.moduleInit == that.moduleInit && + this.strictFloats == that.strictFloats && this.productionMode == that.productionMode case _ => false @@ -56,50 +64,56 @@ final class Semantics private ( override def hashCode(): Int = { import scala.util.hashing.MurmurHash3._ var acc = HashSeed - acc = mix(acc, asInstanceOfs.hashCode) - acc = mix(acc, moduleInit.hashCode) + acc = mix(acc, asInstanceOfs.##) + acc = mix(acc, arrayIndexOutOfBounds.##) + acc = mix(acc, moduleInit.##) acc = mix(acc, strictFloats.##) acc = mixLast(acc, productionMode.##) - finalizeHash(acc, 4) + finalizeHash(acc, 5) } override def toString(): String = { s"""Semantics( - | asInstanceOfs = $asInstanceOfs, - | moduleInit = $moduleInit, - | strictFloats = $strictFloats, - | productionMode = $productionMode + | asInstanceOfs = $asInstanceOfs, + | arrayIndexOutOfBounds = $arrayIndexOutOfBounds, + | moduleInit = $moduleInit, + | strictFloats = $strictFloats, + | productionMode = $productionMode |)""".stripMargin } /** Checks whether the given semantics setting is Java compliant */ def isCompliant(name: String): Boolean = name match { - case "asInstanceOfs" => asInstanceOfs == CheckedBehavior.Compliant - case "moduleInit" => moduleInit == CheckedBehavior.Compliant - case "strictFloats" => strictFloats - case _ => false + case "asInstanceOfs" => asInstanceOfs == Compliant + case "arrayIndexOutOfBounds" => arrayIndexOutOfBounds == Compliant + case "moduleInit" => moduleInit == Compliant + case "strictFloats" => strictFloats + case _ => false } /** Retrieve a list of semantics which are set to compliant */ def compliants: List[String] = { def cl(name: String, cond: Boolean) = if (cond) List(name) else Nil - cl("asInstanceOfs", asInstanceOfs == CheckedBehavior.Compliant) ++ - cl("moduleInit", moduleInit == CheckedBehavior.Compliant) ++ - cl("strictFloats", strictFloats) + cl("asInstanceOfs", asInstanceOfs == Compliant) ++ + cl("arrayIndexOutOfBounds", arrayIndexOutOfBounds == Compliant) ++ + cl("moduleInit", moduleInit == Compliant) ++ + cl("strictFloats", strictFloats) } private def copy( asInstanceOfs: CheckedBehavior = this.asInstanceOfs, + arrayIndexOutOfBounds: CheckedBehavior = this.arrayIndexOutOfBounds, moduleInit: CheckedBehavior = this.moduleInit, strictFloats: Boolean = this.strictFloats, productionMode: Boolean = this.productionMode, runtimeClassName: RuntimeClassNameFunction = this.runtimeClassName): Semantics = { new Semantics( - asInstanceOfs = asInstanceOfs, - moduleInit = moduleInit, - strictFloats = strictFloats, - productionMode = productionMode, + asInstanceOfs = asInstanceOfs, + arrayIndexOutOfBounds = arrayIndexOutOfBounds, + moduleInit = moduleInit, + strictFloats = strictFloats, + productionMode = productionMode, runtimeClassName = runtimeClassName) } } @@ -111,15 +125,15 @@ object Semantics { type RuntimeClassNameFunction = LinkedClass => String val Defaults: Semantics = new Semantics( - asInstanceOfs = CheckedBehavior.Fatal, - moduleInit = CheckedBehavior.Unchecked, - strictFloats = false, - productionMode = false, + asInstanceOfs = Fatal, + arrayIndexOutOfBounds = Fatal, + moduleInit = Unchecked, + strictFloats = false, + productionMode = false, runtimeClassName = _.fullName) def compliantTo(semantics: Traversable[String]): Semantics = { import Defaults._ - import CheckedBehavior._ val semsSet = semantics.toSet @@ -127,10 +141,12 @@ object Semantics { if (semsSet.contains(name)) compliant else default new Semantics( - asInstanceOfs = sw("asInstanceOfs", Compliant, asInstanceOfs), - moduleInit = sw("moduleInit", Compliant, moduleInit), - strictFloats = sw("strictFloats", true, strictFloats), - productionMode = false, + asInstanceOfs = sw("asInstanceOfs", Compliant, asInstanceOfs), + arrayIndexOutOfBounds = + sw("arrayIndexOutOfBounds", Compliant, arrayIndexOutOfBounds), + moduleInit = sw("moduleInit", Compliant, moduleInit), + strictFloats = sw("strictFloats", true, strictFloats), + productionMode = false, runtimeClassName = Defaults.runtimeClassName) } } From 4fba8af0e58c9e504f9401046dbce8d2c08f3082 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 25 Jan 2017 20:34:54 +0100 Subject: [PATCH 0115/2665] Fix #2752: Survive in `test` if there is no testing framework. The `test` task should trivially succeed if there is no testing framework on the classpath. However, f46050f245bed6c318e2f2855a811ea6afb5d0cd broke this scenario, by requiring an export from the testing interface to be present. This commit fixes the scenario to tolerate the absence of that export. In that case, no candidate testing framework is reported to be available. We add `library/test` to the CI matrix as a test for this scenario, as the `library` project does not and will not contain any tests. --- ci/matrix.xml | 1 + .../scalajs/sbtplugin/FrameworkDetector.scala | 20 +++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/ci/matrix.xml b/ci/matrix.xml index 221139ec89..5f70e5cd5b 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -57,6 +57,7 @@ sbtretry 'set inScope(ThisScope in testingExample)(jsEnv := new org.scalajs.jsenv.RetryingComJSEnv(PhantomJSEnv().value))' \ 'set scalaJSOptimizerOptions in testingExample ~= (_.withDisableOptimizer(true))' \ ++$scala testingExample/test:run testingExample/test && + sbtretry ++$scala library/test && sbtretry ++$scala testSuiteJVM/test testSuiteJVM/clean && sbtretry ++$scala 'testSuite/test:runMain org.scalajs.testsuite.junit.JUnitBootstrapTest' && sbtretry ++$scala testSuite/test && diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala index 0667630585..e88764e396 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala @@ -39,9 +39,25 @@ private[sbtplugin] final class FrameworkDetector(jsEnv: JSEnv, (function(exportsNamespace) { "use strict"; + /* #2752: if there is no testing framework at all on the classpath, + * the testing interface will not be there, and therefore the + * `detectFrameworks` function will not exist. We must therefore be + * careful when selecting it. + */ + var namespace = exportsNamespace; + namespace = namespace.org || {}; + namespace = namespace.scalajs || {}; + namespace = namespace.testinterface || {}; + namespace = namespace.internal || {}; + var detectFrameworksFun = namespace.detectFrameworks || (function(data) { + var results = []; + for (var i = 0; i < data.length; ++i) + results.push(void 0); + return results; + }); + var data = ${jsonToString(data)}; - var results = - exportsNamespace.org.scalajs.testinterface.internal.detectFrameworks(data); + var results = detectFrameworksFun(data); for (var i = 0; i < results.length; ++i) { console.log("$ConsoleFrameworkPrefix" + (results[i] || "")); } From 312949061a72d42d30a6fc00267804888472b8fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 5 Feb 2017 12:42:58 +0100 Subject: [PATCH 0116/2665] Fix #2762: Remove obsolete Node.js flags for rest and spread. Node.js 6.x, which is now installed in the CI servers, does not support the `--harmony-rest-parameters` and `--harmony-spreadcalls` flags anymore. Instead, it supports those features by default. This commit removes those flags when running with Node.js. This fixes the issue if a recent Node.js is used. Caveat: this fix will *break* runs in ES6 mode with an older Node.js. I do not see an easy way to correctly run on both old and new versions. Since this is an internal issue anyway, I don't think it's worth complicating the build with logic to detect the version of Node.js or whatnot. --- ci/matrix.xml | 18 +++++++++--------- project/Build.scala | 4 ---- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/ci/matrix.xml b/ci/matrix.xml index 5f70e5cd5b..4c978aa227 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -143,46 +143,46 @@ Date: Wed, 18 Jan 2017 20:15:57 +0100 Subject: [PATCH 0117/2665] Fix #2734: Allow @JSExportTopLevel on classes and objects. This commit implements the Proposal #2734. The annotation `@JSExportTopLevel` can now be used on static classes and objects (both Scala classes/objects and Scala.js-defined JS classes/objects) to export them at the top-level. For objects, the difference wrt. `@JSExport` is that the module instance itself is exported, rather than the module accessor. For classes, this is equivalent to exporting them via `@JSExport`. We include the possibility to be consistent with objects, and with the prospect of deprecating and removing `@JSExport` on classes and objects altogether. --- .../scalajs/core/compiler/GenJSExports.scala | 22 ++++- .../scalajs/core/compiler/PrepJSExports.scala | 8 +- .../core/compiler/test/JSExportTest.scala | 96 ++++++++++++------ .../scala/org/scalajs/core/ir/Infos.scala | 2 +- .../scala/org/scalajs/core/ir/Printers.scala | 5 + .../org/scalajs/core/ir/Serializers.scala | 5 + .../main/scala/org/scalajs/core/ir/Tags.scala | 1 + .../org/scalajs/core/ir/Transformers.scala | 3 +- .../org/scalajs/core/ir/Traversers.scala | 3 +- .../scala/org/scalajs/core/ir/Trees.scala | 18 ++++ .../org/scalajs/core/ir/PrintersTest.scala | 6 ++ .../testsuite/jsinterop/ExportsTest.scala | 99 +++++++++++++++++++ .../backend/emitter/ScalaJSClassEmitter.scala | 26 +++++ .../core/tools/linker/checker/IRChecker.scala | 26 +++-- .../tools/linker/frontend/BaseLinker.scala | 3 + 15 files changed, 278 insertions(+), 45 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index aec2913cb1..aceb98b063 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -106,17 +106,33 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } yield { implicit val pos = exp.pos assert(!exp.isNamed, "Class cannot be exported named") - js.JSClassExportDef(exp.jsName) + + exp.destination match { + case ExportDestination.Normal | ExportDestination.TopLevel => + js.JSClassExportDef(exp.jsName) + case ExportDestination.Static => + throw new AssertionError( + "Found a class export static for " + classSym.fullName) + } } } - def genModuleAccessorExports(classSym: Symbol): List[js.ModuleExportDef] = { + def genModuleAccessorExports(classSym: Symbol): List[js.Tree] = { for { exp <- jsInterop.registeredExportsOf(classSym) } yield { implicit val pos = exp.pos assert(!exp.isNamed, "Module cannot be exported named") - js.ModuleExportDef(exp.jsName) + + exp.destination match { + case ExportDestination.Normal => + js.ModuleExportDef(exp.jsName) + case ExportDestination.TopLevel => + js.TopLevelModuleExportDef(exp.jsName) + case ExportDestination.Static => + throw new AssertionError( + "Found a module export static for " + classSym.fullName) + } } } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala index 6d5ef1fc8b..6cd7438cfa 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala @@ -340,10 +340,10 @@ trait PrepJSExports { this: PrepJSInterop => "You may not export a getter or a setter to the top level") } - if (!isMember) { - reporter.error(annot.pos, "Use @JSExport on objects and " + - "constructors to export to the top level") - } else if (!sym.owner.isStatic || !sym.owner.isModuleClass) { + val symOwner = + if (sym.isConstructor) sym.owner.owner + else sym.owner + if (!symOwner.isStatic || !symOwner.isModuleClass) { reporter.error(annot.pos, "Only static objects may export their members to the top level") } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index 7388db3806..93b886d7e1 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -1096,54 +1096,42 @@ class JSExportTest extends DirectTest with TestHelpers { else s" (since $v)" } - @Test - def noExportTopLevelModule: Unit = { - """ - @JSExportTopLevel("foo") - object A - """ hasErrors - """ - |newSource1.scala:3: error: Use @JSExport on objects and constructors to export to the top level - | @JSExportTopLevel("foo") - | ^ - """ - } - @Test def noExportTopLevelTrait: Unit = { """ @JSExportTopLevel("foo") trait A - """ hasErrors - """ - |newSource1.scala:3: error: Use @JSExport on objects and constructors to export to the top level - | @JSExportTopLevel("foo") - | ^ - """ - } - @Test - def noExportTopLevelClass: Unit = { - """ - @JSExportTopLevel("foo") - class A + @JSExportTopLevel("bar") + @ScalaJSDefined + trait B extends js.Object """ hasErrors """ - |newSource1.scala:3: error: Use @JSExport on objects and constructors to export to the top level + |newSource1.scala:3: error: You may not export a trait | @JSExportTopLevel("foo") | ^ + |newSource1.scala:6: error: You may not export a trait + | @JSExportTopLevel("bar") + | ^ """ """ - class A { + object Container { @JSExportTopLevel("foo") - def this(x: Int) = this() + trait A + + @JSExportTopLevel("bar") + @ScalaJSDefined + trait B extends js.Object } """ hasErrors """ - |newSource1.scala:4: error: Use @JSExport on objects and constructors to export to the top level + |newSource1.scala:4: error: You may not export a trait | @JSExportTopLevel("foo") | ^ + |newSource1.scala:7: error: You may not export a trait + | @JSExportTopLevel("bar") + | ^ """ } @@ -1255,6 +1243,56 @@ class JSExportTest extends DirectTest with TestHelpers { | @JSExportTopLevel("foo") | ^ """ + + """ + class A { + @JSExportTopLevel("Foo") + object B + } + """ hasErrors + """ + |newSource1.scala:4: error: Only static objects may export their members to the top level + | @JSExportTopLevel("Foo") + | ^ + """ + + """ + class A { + @JSExportTopLevel("Foo") + @ScalaJSDefined + object B extends js.Object + } + """ hasErrors + """ + |newSource1.scala:4: error: Only static objects may export their members to the top level + | @JSExportTopLevel("Foo") + | ^ + """ + + """ + class A { + @JSExportTopLevel("Foo") + @ScalaJSDefined + class B extends js.Object + } + """ hasErrors + """ + |newSource1.scala:4: error: Only static objects may export their members to the top level + | @JSExportTopLevel("Foo") + | ^ + """ + + """ + class A { + @JSExportTopLevel("Foo") + class B + } + """ hasErrors + """ + |newSource1.scala:4: error: Only static objects may export their members to the top level + | @JSExportTopLevel("Foo") + | ^ + """ } @Test diff --git a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala index 02615ae4f7..4bcba6170d 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala @@ -314,7 +314,7 @@ object Infos { case constructorDef: ConstructorExportDef => builder.setIsExported(true) exportedConstructors ::= constructorDef - case _:JSClassExportDef | _:ModuleExportDef => + case _:JSClassExportDef | _:ModuleExportDef | _:TopLevelModuleExportDef => builder.setIsExported(true) case topLevelMethodExport: TopLevelMethodExportDef => builder.setIsExported(true) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index b9c18442e5..80cbeaebe9 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -867,6 +867,11 @@ object Printers { printEscapeJS(fullName, out) print('\"') + case TopLevelModuleExportDef(fullName) => + print("export top module \"") + printEscapeJS(fullName, out) + print('\"') + case TopLevelMethodExportDef(methodDef) => print("export top ") print(methodDef) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index 7103101798..05f3de7e35 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -466,6 +466,10 @@ object Serializers { writeByte(TagModuleExportDef) writeString(fullName) + case TopLevelModuleExportDef(fullName) => + writeByte(TagTopLevelModuleExportDef) + writeString(fullName) + case TopLevelMethodExportDef(methodDef) => writeByte(TagTopLevelMethodExportDef) writeTree(methodDef) @@ -902,6 +906,7 @@ object Serializers { case TagJSClassExportDef => JSClassExportDef(readString()) case TagModuleExportDef => ModuleExportDef(readString()) + case TagTopLevelModuleExportDef => TopLevelModuleExportDef(readString()) case TagTopLevelMethodExportDef => TopLevelMethodExportDef(readTree().asInstanceOf[MethodDef]) case TagTopLevelFieldExportDef => TopLevelFieldExportDef(readString(), readIdent()) } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala index 0db0206f6e..bdf373d2da 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala @@ -107,6 +107,7 @@ private[ir] object Tags { final val TagTopLevelMethodExportDef = TagTryFinally + 1 final val TagSelectStatic = TagTopLevelMethodExportDef + 1 final val TagTopLevelFieldExportDef = TagSelectStatic + 1 + final val TagTopLevelModuleExportDef = TagTopLevelFieldExportDef + 1 // Tags for Types diff --git a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala index 0ea5b816f9..dc9af73415 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala @@ -229,7 +229,8 @@ object Transformers { case ConstructorExportDef(fullName, args, body) => ConstructorExportDef(fullName, args, transformStat(body)) - case _:JSClassExportDef | _:ModuleExportDef | _:TopLevelFieldExportDef => + case _:JSClassExportDef | _:ModuleExportDef | + _:TopLevelModuleExportDef | _:TopLevelFieldExportDef => tree case TopLevelMethodExportDef(methodDef) => diff --git a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala index 9c62ad5f86..fe9783d4d9 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala @@ -212,7 +212,8 @@ object Traversers { case _:Skip | _:Continue | _:Debugger | _:LoadModule | _:SelectStatic | _:LoadJSConstructor | _:LoadJSModule | _:JSLinkingInfo | _:Literal | _:UndefinedParam | _:VarRef | _:This | _:FieldDef | - _:JSClassExportDef | _:ModuleExportDef | _:TopLevelFieldExportDef => + _:JSClassExportDef | _:ModuleExportDef | _:TopLevelModuleExportDef | + _:TopLevelFieldExportDef => case _ => sys.error(s"Invalid tree in traverse() of class ${tree.getClass}") diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 15302c2096..655fb9611c 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -809,11 +809,29 @@ object Trees { val tpe = NoType } + /** Traditional `@JSExport` for top-level objects, as a 0-arg function. + * + * This exports a module as a 0-arg function that returns the module + * instance. It is initialized lazily in that case. + * + * This alternative should eventually disappear. + */ case class ModuleExportDef(fullName: String)( implicit val pos: Position) extends Tree { val tpe = NoType } + /** New-style `@JSExportTopLevel` for top-level objects, directly as the + * object. + * + * This exports a module directly as a variable holding the module instance. + * The instance is initialized during ES module instantiation. + */ + case class TopLevelModuleExportDef(fullName: String)( + implicit val pos: Position) extends Tree { + val tpe = NoType + } + case class TopLevelMethodExportDef(methodDef: MethodDef)( implicit val pos: Position) extends Tree { val tpe = NoType diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala index 57e6416a2e..cc43de729a 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala @@ -1073,6 +1073,12 @@ class PrintersTest { ModuleExportDef("pkg.Foo")) } + @Test def printTopLevelModuleExportDef(): Unit = { + assertPrintEquals( + """export top module "pkg.Foo"""", + TopLevelModuleExportDef("pkg.Foo")) + } + @Test def printTopLevelMethodExportDef(): Unit = { assertPrintEquals( """ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index e5e790bd93..ecc6422550 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -651,6 +651,13 @@ class ExportsTest { assertEquals("witness", obj.witness) } + @Test def toplevel_exports_for_objects(): Unit = { + val obj = exportsNamespace.TopLevelExportedObject + assertJSNotUndefined(obj) + assertEquals("object", js.typeOf(obj)) + assertEquals("witness", obj.witness) + } + @Test def exports_for_Scala_js_defined_JS_objects_with_explicit_name(): Unit = { val accessor = exportsNamespace.TheSJSDefinedExportedObject assertJSNotUndefined(accessor) @@ -661,6 +668,16 @@ class ExportsTest { assertEquals("witness", obj.witness) } + @Test def toplevel_exports_for_Scala_js_defined_JS_objects(): Unit = { + val obj1 = exportsNamespace.SJSDefinedTopLevelExportedObject + assertJSNotUndefined(obj1) + assertEquals("object", js.typeOf(obj1)) + assertEquals("witness", obj1.witness) + + val obj2 = exportsNamespace.TheSJSDefinedTopLevelExportedObject + assertSame(obj1, obj2) + } + @Test def exports_for_objects_with_qualified_name(): Unit = { val accessor = exportsNamespace.qualified.testobject.ExportedObject assertJSNotUndefined(accessor) @@ -671,6 +688,13 @@ class ExportsTest { assertEquals("witness", obj.witness) } + @Test def toplevel_exports_for_objects_with_qualified_name(): Unit = { + val obj = exportsNamespace.qualified.testobject.TopLevelExportedObject + assertJSNotUndefined(obj) + assertEquals("object", js.typeOf(obj)) + assertEquals("witness", obj.witness) + } + @Test def exports_for_nested_objects(): Unit = { val accessor = exportsNamespace.qualified.nested.ExportedObject assertJSNotUndefined(accessor) @@ -681,6 +705,13 @@ class ExportsTest { assertSame(obj, ExportHolder.ExportedObject) } + @Test def toplevel_exports_for_nested_objects(): Unit = { + val obj = exportsNamespace.qualified.nested.TopLevelExportedObject + assertJSNotUndefined(obj) + assertEquals("object", js.typeOf(obj)) + assertSame(obj, ExportHolder.TopLevelExportedObject) + } + @Test def exports_for_objects_with_constant_folded_name(): Unit = { val accessor = exportsNamespace.ConstantFoldedObjectExport assertJSNotUndefined(accessor) @@ -726,6 +757,14 @@ class ExportsTest { assertEquals(5, obj.x) } + @Test def toplevel_exports_for_classes(): Unit = { + val constr = exportsNamespace.TopLevelExportedClass + assertJSNotUndefined(constr) + assertEquals("function", js.typeOf(constr)) + val obj = js.Dynamic.newInstance(constr)(5) + assertEquals(5, obj.x) + } + @Test def exports_for_Scala_js_defined_JS_classes_with_explicit_name(): Unit = { val constr = exportsNamespace.TheSJSDefinedExportedClass assertJSNotUndefined(constr) @@ -735,6 +774,18 @@ class ExportsTest { assertEquals(5, obj.x) } + @Test def toplevel_exports_for_Scala_js_defined_JS_classes(): Unit = { + val constr = exportsNamespace.SJSDefinedTopLevelExportedClass + assertJSNotUndefined(constr) + assertEquals("function", js.typeOf(constr)) + val obj = js.Dynamic.newInstance(constr)(5) + assertTrue((obj: Any).isInstanceOf[SJSDefinedTopLevelExportedClass]) + assertEquals(5, obj.x) + + val constr2 = exportsNamespace.TheSJSDefinedTopLevelExportedClass + assertSame(constr, constr2) + } + @Test def exports_for_classes_with_qualified_name_ExportedClass(): Unit = { val constr = exportsNamespace.qualified.testclass.ExportedClass assertJSNotUndefined(constr) @@ -743,6 +794,14 @@ class ExportsTest { assertEquals(5, obj.x) } + @Test def toplevel_exports_for_classes_with_qualified_name(): Unit = { + val constr = exportsNamespace.qualified.testclass.TopLevelExportedClass + assertJSNotUndefined(constr) + assertEquals("function", js.typeOf(constr)) + val obj = js.Dynamic.newInstance(constr)(5) + assertEquals(5, obj.x) + } + @Test def exports_for_nested_classes(): Unit = { val constr = exportsNamespace.qualified.nested.ExportedClass assertJSNotUndefined(constr) @@ -751,6 +810,14 @@ class ExportsTest { assertTrue((obj: Any).isInstanceOf[ExportHolder.ExportedClass]) } + @Test def toplevel_exports_for_nested_classes(): Unit = { + val constr = exportsNamespace.qualified.nested.TopLevelExportedClass + assertJSNotUndefined(constr) + assertEquals("function", js.typeOf(constr)) + val obj = js.Dynamic.newInstance(constr)() + assertTrue((obj: Any).isInstanceOf[ExportHolder.TopLevelExportedClass]) + } + @Test def exports_for_classes_with_qualified_name_SJSDefinedExportedClass(): Unit = { val constr = exportsNamespace.qualified.testclass.SJSDefinedExportedClass assertJSNotUndefined(constr) @@ -1597,6 +1664,13 @@ object ExportedObject { def witness: String = "witness" } +@JSExportTopLevel("TopLevelExportedObject") +@JSExportTopLevel("qualified.testobject.TopLevelExportedObject") +object TopLevelExportedObject { + @JSExport + val witness: String = "witness" +} + @JSExport @JSExport("TheSJSDefinedExportedObject") @ScalaJSDefined @@ -1604,6 +1678,13 @@ object SJSDefinedExportedObject extends js.Object { def witness: String = "witness" } +@JSExportTopLevel("SJSDefinedTopLevelExportedObject") +@JSExportTopLevel("TheSJSDefinedTopLevelExportedObject") +@ScalaJSDefined +object SJSDefinedTopLevelExportedObject extends js.Object { + val witness: String = "witness" +} + @JSExport protected object ProtectedExportedObject { @JSExport @@ -1619,12 +1700,24 @@ class ExportedClass(_x: Int) { val x = _x } +@JSExportTopLevel("TopLevelExportedClass") +@JSExportTopLevel("qualified.testclass.TopLevelExportedClass") +class TopLevelExportedClass(_x: Int) { + @JSExport + val x = _x +} + @JSExport @JSExport("TheSJSDefinedExportedClass") @JSExport("qualified.testclass.SJSDefinedExportedClass") @ScalaJSDefined class SJSDefinedExportedClass(val x: Int) extends js.Object +@JSExportTopLevel("SJSDefinedTopLevelExportedClass") +@JSExportTopLevel("TheSJSDefinedTopLevelExportedClass") +@ScalaJSDefined +class SJSDefinedTopLevelExportedClass(val x: Int) extends js.Object + @JSExport protected class ProtectedExportedClass(_x: Int) { @JSExport @@ -1759,9 +1852,15 @@ object ExportHolder { @JSExport("qualified.nested.ExportedClass") class ExportedClass + @JSExportTopLevel("qualified.nested.TopLevelExportedClass") + class TopLevelExportedClass + @JSExport("qualified.nested.ExportedObject") object ExportedObject + @JSExportTopLevel("qualified.nested.TopLevelExportedObject") + object TopLevelExportedObject + @JSExport("qualified.nested.SJSDefinedExportedClass") @ScalaJSDefined class SJSDefinedExportedClass extends js.Object diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala index daed4086d4..97dbcf87f0 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala @@ -926,6 +926,8 @@ private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, genJSClassExportDef(tree, e) case e: ModuleExportDef => genModuleExportDef(tree, e) + case e: TopLevelModuleExportDef => + genTopLevelModuleExportDef(tree, e) case e: TopLevelMethodExportDef => genTopLevelMethodExportDef(tree, e) case e: TopLevelFieldExportDef => @@ -979,6 +981,13 @@ private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, genClassOrModuleExportDef(cd, tree.fullName, classVar) } + /** Generates an exporter for a module as a 0-arg function. + * + * This corresponds to the old-style `@JSExport` of modules. Basically this + * exports the module accessor. The object will be initialized lazily on + * the first call of the accessor, exactly like the accesses to objects from + * Scala code. + */ def genModuleExportDef(cd: LinkedClass, tree: ModuleExportDef): js.Tree = { import TreeDSL._ @@ -988,6 +997,23 @@ private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, genClassOrModuleExportDef(cd, tree.fullName, baseAccessor) } + /** Generates an exporter for a module at the "top-level", which is directly + * as a variable holding the module instance. + * + * This corresponds the the new-style `@JSExportTopLevel` of modules. In + * this case, the module instance is initialized during ES moduleµ + * instantiation. + */ + def genTopLevelModuleExportDef(cd: LinkedClass, + tree: TopLevelModuleExportDef): js.Tree = { + import TreeDSL._ + + implicit val pos = tree.pos + + val moduleVar = genLoadModule(cd.name.name) + genClassOrModuleExportDef(cd, tree.fullName, moduleVar) + } + private def genClassOrModuleExportDef(cd: LinkedClass, exportFullName: String, exportedValue: js.Tree)(implicit pos: Position): js.Tree = { import TreeDSL._ diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 7a1b20cb43..7e7b103cb8 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -160,14 +160,17 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { implicit val ctx = ErrorContext(tree) tree match { - case member @ ConstructorExportDef(_, _, _) => - checkConstructorExportDef(member, classDef) + case tree: ConstructorExportDef => + checkConstructorExportDef(tree, classDef) - case member @ JSClassExportDef(_) => - checkJSClassExportDef(member, classDef) + case tree: JSClassExportDef => + checkJSClassExportDef(tree, classDef) - case member @ ModuleExportDef(_) => - checkModuleExportDef(member, classDef) + case tree: ModuleExportDef => + checkModuleExportDef(tree, classDef) + + case tree: TopLevelModuleExportDef => + checkTopLevelModuleExportDef(tree, classDef) case TopLevelMethodExportDef(methodDef) => checkExportedMethodDef(methodDef, classDef, isTopLevel = true) @@ -463,6 +466,17 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { reportError(s"Exported module def can only appear in a module class") } + private def checkTopLevelModuleExportDef( + topLevelModuleDef: TopLevelModuleExportDef, + classDef: LinkedClass): Unit = { + implicit val ctx = ErrorContext(topLevelModuleDef) + + if (!classDef.kind.hasModuleAccessor) { + reportError( + "Top-level module export def can only appear in a module class") + } + } + private def typecheckStat(tree: Tree, env: Env): Env = { implicit val ctx = ErrorContext(tree) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index 096fafc98d..9c386e7e53 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -256,6 +256,9 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions case e: ModuleExportDef => classExports += e + case e: TopLevelModuleExportDef => + classExports += e + case e: TopLevelMethodExportDef => classExports += e From 44294f3ccfb114b8f8c99c45c13d56790eebcbc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 5 Feb 2017 23:35:32 +0100 Subject: [PATCH 0118/2665] Fix #2761: Implement java.io.DataOutputStream. --- .../src/main/scala/java/io/DataOutput.scala | 20 ++ .../main/scala/java/io/DataOutputStream.scala | 94 ++++++ .../javalib/io/DataOutputStreamTest.scala | 277 ++++++++++++++++++ 3 files changed, 391 insertions(+) create mode 100644 javalib/src/main/scala/java/io/DataOutput.scala create mode 100644 javalib/src/main/scala/java/io/DataOutputStream.scala create mode 100644 test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/DataOutputStreamTest.scala diff --git a/javalib/src/main/scala/java/io/DataOutput.scala b/javalib/src/main/scala/java/io/DataOutput.scala new file mode 100644 index 0000000000..3794f0eb23 --- /dev/null +++ b/javalib/src/main/scala/java/io/DataOutput.scala @@ -0,0 +1,20 @@ +package java.io + +trait DataOutput { + def write(b: Int): Unit + def write(b: Array[Byte]): Unit + def write(b: Array[Byte], off: Int, len: Int): Unit + + def writeBoolean(v: Boolean): Unit + def writeByte(v: Int): Unit + def writeShort(v: Int): Unit + def writeChar(v: Int): Unit + def writeInt(v: Int): Unit + def writeLong(v: Long): Unit + def writeFloat(v: Float): Unit + def writeDouble(v: Double): Unit + + def writeBytes(s: String): Unit + def writeChars(s: String): Unit + def writeUTF(s: String): Unit +} diff --git a/javalib/src/main/scala/java/io/DataOutputStream.scala b/javalib/src/main/scala/java/io/DataOutputStream.scala new file mode 100644 index 0000000000..70b49d060c --- /dev/null +++ b/javalib/src/main/scala/java/io/DataOutputStream.scala @@ -0,0 +1,94 @@ +package java.io + +class DataOutputStream(out: OutputStream) + extends FilterOutputStream(out) with DataOutput { + + protected var written: Int = 0 + + override def write(b: Int): Unit = { + super.write(b) + written += 1 + } + + override def write(b: Array[Byte], off: Int, len: Int): Unit = { + out.write(b, off, len) + written += len + } + + override def flush(): Unit = + super.flush() + + final def writeBoolean(v: Boolean): Unit = + write(if (v) 1 else 0) + + final def writeByte(v: Int): Unit = + write(v) + + final def writeShort(v: Int): Unit = { + write(v >> 8) + write(v) + } + + final def writeChar(v: Int): Unit = { + write(v >> 8) + write(v) + } + + final def writeInt(v: Int): Unit = { + write(v >> 24) + write(v >> 16) + write(v >> 8) + write(v) + } + + @inline + final def writeLong(v: Long): Unit = { + writeInt((v >>> 32).toInt) + writeInt(v.toInt) + } + + final def writeFloat(v: Float): Unit = + writeInt(java.lang.Float.floatToIntBits(v)) + + final def writeDouble(v: Double): Unit = + writeLong(java.lang.Double.doubleToLongBits(v)) + + final def writeBytes(s: String): Unit = { + for (c <- s) + write(c.toInt) + } + + final def writeChars(s: String): Unit = { + for (c <- s) + writeChar(c) + } + + final def writeUTF(s: String): Unit = { + val buffer = new Array[Byte](2 + 3*s.length) + + var idx = 2 + for (c <- s) { + if (c <= 0x7f && c >= 0x01) { + buffer(idx) = c.toByte + idx += 1 + } else if (c < 0x0800) { + buffer(idx) = ((c >> 6) | 0xc0).toByte + buffer(idx + 1) = ((c & 0x3f) | 0x80).toByte + idx += 2 + } else { + buffer(idx) = ((c >> 12) | 0xe0).toByte + buffer(idx + 1) = (((c >> 6) & 0x3f) | 0x80).toByte + buffer(idx + 2) = ((c & 0x3f) | 0x80).toByte + idx += 3 + } + } + + val len = idx - 2 + buffer(0) = (len >> 8).toByte + buffer(1) = len.toByte + + write(buffer, 0, idx) + } + + final def size(): Int = written +} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/DataOutputStreamTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/DataOutputStreamTest.scala new file mode 100644 index 0000000000..0a32fcfa72 --- /dev/null +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/DataOutputStreamTest.scala @@ -0,0 +1,277 @@ +package org.scalajs.testsuite.javalib.io + +import java.io._ + +import org.junit._ +import org.junit.Assert._ + +object DataOutputStreamTest { + class DataOutputStreamWrittenAccess(out: OutputStream) + extends DataOutputStream(out) { + def getWritten(): Int = written + def setWritten(v: Int): Unit = written = v + } + + class CheckerOutputStream extends ByteArrayOutputStream { + val dataOutputStream = new DataOutputStreamWrittenAccess(this) + + assertEquals(0, dataOutputStream.getWritten()) + + /* Artificially skew `written` to make sure `size()` uses `written` as + * its implementation. + */ + dataOutputStream.setWritten(100) + + def check(expectedBytes: Int*): Unit = { + val expectedWritten = 100 + expectedBytes.size + assertEquals(expectedWritten, dataOutputStream.getWritten()) + assertEquals(expectedWritten, dataOutputStream.size()) + assertArrayEquals(expectedBytes.map(_.toByte).toArray, toByteArray()) + } + } +} + +class DataOutputStreamTest { + import DataOutputStreamTest._ + + private def newStream(): (DataOutputStream, CheckerOutputStream) = { + val checker = new CheckerOutputStream + (checker.dataOutputStream, checker) + } + + @Test def construct(): Unit = { + val (stream, checker) = newStream() + checker.check() + } + + @Test def writePrimitiveByte(): Unit = { + val (stream, checker) = newStream() + stream.write(42) + checker.check(42) + } + + @Test def writePrimitiveBytes(): Unit = { + val (stream, checker) = newStream() + stream.write(Array[Byte](5, 3, 1, 43, 6, 12, 2), 1, 4) + checker.check(3, 1, 43, 6) + } + + @Test def writeBoolean(): Unit = { + val (stream, checker) = newStream() + + stream.writeBoolean(true) + stream.writeBoolean(true) + stream.writeBoolean(false) + + checker.check(1, 1, 0) + } + + @Test def writeByte(): Unit = { + val (stream, checker) = newStream() + + stream.writeByte(0) + stream.writeByte(1) + stream.writeByte(-15) + stream.writeByte(125) + stream.writeByte(53) + + checker.check(0, 1, -15, 125, 53) + } + + @Test def writeShort(): Unit = { + val (stream, checker) = newStream() + + stream.writeShort(453) + stream.writeShort(-43) + stream.writeShort(Short.MaxValue) + stream.writeShort(6320) + stream.writeShort(0) + stream.writeShort(Short.MinValue) + stream.writeShort(-346) + stream.writeShort(34) + + checker.check( + 0x01, 0xc5, + 0xff, 0xd5, + 0x7f, 0xff, + 0x18, 0xb0, + 0x00, 0x00, + 0x80, 0x00, + 0xfe, 0xa6, + 0x00, 0x22 + ) + } + + @Test def writeChar(): Unit = { + val (stream, checker) = newStream() + + for (c <- "Höllö Wărȴđ") + stream.writeChar(c) + + checker.check( + 0x00, 0x48, // H + 0x00, 0xF6, // ö + 0x00, 0x6C, // l + 0x00, 0x6C, // l + 0x00, 0xF6, // ö + 0x00, 0x20, // [space] + 0x00, 0x57, // W + 0x01, 0x03, // ă + 0x00, 0x72, // r + 0x02, 0x34, // ȴ + 0x01, 0x11 // đ + ) + } + + @Test def writeInt(): Unit = { + val (stream, checker) = newStream() + + stream.writeInt(0) + stream.writeInt(Int.MaxValue) + stream.writeInt(-4) + stream.writeInt(83) + stream.writeInt(35234) + stream.writeInt(-97539) + stream.writeInt(Int.MinValue) + stream.writeInt(1) + + checker.check( + 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfc, + 0x00, 0x00, 0x00, 0x53, + 0x00, 0x00, 0x89, 0xa2, + 0xff, 0xfe, 0x82, 0xfd, + 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01 + ) + } + + @Test def writeLong(): Unit = { + val (stream, checker) = newStream() + + stream.writeLong(546372873646234L) + stream.writeLong(-32451234L) + stream.writeLong(Long.MaxValue) + stream.writeLong(0L) + stream.writeLong(-1L) + stream.writeLong(Long.MinValue) + stream.writeLong(-34524L) + stream.writeLong(47L) + + checker.check( + 0x00, 0x01, 0xf0, 0xec, 0x59, 0x0c, 0x70, 0x9a, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x10, 0xd5, 0x5e, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x79, 0x24, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f + ) + } + + @Test def writeFloat(): Unit = { + val (stream, checker) = newStream() + + stream.writeFloat(-1.0f) + stream.writeFloat(4563.564f) + stream.writeFloat(-0.0f) + stream.writeFloat(0.0f) + stream.writeFloat(Float.NaN) + stream.writeFloat(Float.PositiveInfinity) + stream.writeFloat(-0.002f) + stream.writeFloat(Float.NegativeInfinity) + + checker.check( + 0xbf, 0x80, 0x00, 0x00, + 0x45, 0x8e, 0x9c, 0x83, + 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xc0, 0x00, 0x00, + 0x7f, 0x80, 0x00, 0x00, + 0xbb, 0x03, 0x12, 0x6f, + 0xff, 0x80, 0x00, 0x00 + ) + } + + @Test def writeDouble(): Unit = { + val (stream, checker) = newStream() + + stream.writeDouble(0.7) + stream.writeDouble(345672.067923) + stream.writeDouble(-3472.0673) + stream.writeDouble(Double.NaN) + stream.writeDouble(Double.PositiveInfinity) + stream.writeDouble(-7.0134674) + stream.writeDouble(Double.NegativeInfinity) + stream.writeDouble(0.0) + + checker.check( + 0x3f, 0xe6, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x41, 0x15, 0x19, 0x20, 0x45, 0x8d, 0x9b, 0x5f, + 0xc0, 0xab, 0x20, 0x22, 0x75, 0x25, 0x46, 0x0b, + 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x1c, 0x0d, 0xca, 0x65, 0xea, 0x3f, 0xa4, + 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + ) + } + + @Test def writeBytesOfString(): Unit = { + val (stream, checker) = newStream() + + stream.writeBytes("Höllö Wărȴđ") + + checker.check( + 0x48, // H + 0xF6, // ö + 0x6C, // l + 0x6C, // l + 0xF6, // ö + 0x20, // [space] + 0x57, // W + 0x03, // ă + 0x72, // r + 0x34, // ȴ + 0x11 // đ + ) + } + + @Test def writeCharsOfString(): Unit = { + val (stream, checker) = newStream() + + stream.writeChars("Höllö Wărȴđ") + + checker.check( + 0x00, 0x48, // H + 0x00, 0xF6, // ö + 0x00, 0x6C, // l + 0x00, 0x6C, // l + 0x00, 0xF6, // ö + 0x00, 0x20, // [space] + 0x00, 0x57, // W + 0x01, 0x03, // ă + 0x00, 0x72, // r + 0x02, 0x34, // ȴ + 0x01, 0x11 // đ + ) + } + + @Test def writeUTF(): Unit = { + val (stream, checker) = newStream() + + stream.writeUTF("Höllö Wărȴđ") + stream.writeUTF("poo -> 💩") + stream.writeUTF("愛") + + checker.check( + 0x00, 0x10, 0x48, 0xc3, 0xb6, 0x6c, 0x6c, 0xc3, + 0xb6, 0x20, 0x57, 0xc4, 0x83, 0x72, 0xc8, 0xb4, + 0xc4, 0x91, 0x00, 0x0d, 0x70, 0x6f, 0x6f, 0x20, + 0x2d, 0x3e, 0x20, 0xed, 0xa0, 0xbd, 0xed, 0xb2, + 0xa9, 0x00, 0x03, 0xe6, 0x84, 0x9b + ) + } +} From fabd390344a36db711decbcd778ccacaf2de130d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 6 Feb 2017 10:37:17 +0100 Subject: [PATCH 0119/2665] Fix #2758: Add `UndefOr.contains` to mimic `Option.contains`. `Option.contains` was added in Scala 2.11.0. This commit adds an equivalent method to `UndefOr`. --- .../src/main/scala/scala/scalajs/js/UndefOr.scala | 12 ++++++++++++ .../scalajs/testsuite/jsinterop/UndefOrTest.scala | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/library/src/main/scala/scala/scalajs/js/UndefOr.scala b/library/src/main/scala/scala/scalajs/js/UndefOr.scala index c7a22ebc06..65f5d13d4d 100644 --- a/library/src/main/scala/scala/scalajs/js/UndefOr.scala +++ b/library/src/main/scala/scala/scalajs/js/UndefOr.scala @@ -158,6 +158,18 @@ final class UndefOrOps[A](val self: UndefOr[A]) extends AnyVal { @inline final def withFilter(p: A => Boolean): WithFilter[A] = new WithFilter(self, p) + /** Tests whether the $option contains a given value as an element. + * + * `x.contains(y)` differs from `x == y` only in the fact that it will + * return `false` when `x` and `y` are both `undefined`. + * + * @param elem the element to test. + * @return `true` if the $option has an element that is equal (as + * determined by `==`) to `elem`, `false` otherwise. + */ + @inline final def contains[A1 >: A](elem: A1): Boolean = + !isEmpty && elem == this.forceGet + /** Returns true if this option is nonempty '''and''' the predicate * `p` returns true when applied to this $option's value. * Otherwise, returns false. diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTest.scala index 608204e46f..12c8b2d1d9 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTest.scala @@ -111,6 +111,14 @@ class UndefOrTest { assertFalse(none[Int].filterNot(_ > 0).isDefined) } + @Test def contains(): Unit = { + assertTrue(some(7).contains(7)) + assertFalse(some(7).contains(8)) + assertFalse(none[Int].contains(7)) + + assertFalse(some(()).contains(())) + } + @Test def exists(): Unit = { assertTrue(some(7).exists(_ > 0)) assertFalse(some(7).exists(_ < 0)) From 8931e805eb77549347966a6ade794008f5799bad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 6 Feb 2017 13:30:26 +0100 Subject: [PATCH 0120/2665] Fix #2755: Fix array out of bounds in BigDecimal.divide(scale). There were computations based on `LongTenPows` that would access indices before testing whether they are valid or not. The fix is to delay those accesses after we've made sure that indices are valid. In the process, I have rearranged the computation of `diffScale` to convert it to an `Int` earlier, avoid some useless `Long` operations. --- .../src/main/scala/java/math/BigDecimal.scala | 42 ++++++++++--------- .../math/BigDecimalArithmeticTest.scala | 8 ++++ 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/javalib/src/main/scala/java/math/BigDecimal.scala b/javalib/src/main/scala/java/math/BigDecimal.scala index eb6bca565f..e82430a9fe 100644 --- a/javalib/src/main/scala/java/math/BigDecimal.scala +++ b/javalib/src/main/scala/java/math/BigDecimal.scala @@ -704,52 +704,56 @@ class BigDecimal() extends Number with Comparable[BigDecimal] { else if (divisor.isZero) throw new ArithmeticException("Division by zero") - val diffScale: Long = (this._scale.toLong - divisor._scale) - scale + val diffScale = { + val diffScaleLong = (this._scale.toLong - divisor._scale) - scale + val diffScale = diffScaleLong.toInt - // Check whether the diffScale will fit into an int. - if (bitLength(diffScale) > 32) { - val msg = s"Unable to scale as difference is too big ($diffScale)" - throw new ArithmeticException(msg) + // Check whether the diffScale will fit into an Int + if (diffScale.toLong != diffScaleLong) { + throw new ArithmeticException( + s"Unable to scale as difference is too big ($diffScaleLong)") + } + + diffScale } - @inline def default(): BigDecimal = { val scaledDividend0 = this.getUnscaledValue val scaledDivisor0 = divisor.getUnscaledValue val (scaledDividend, scaledDivisor) = if (diffScale > 0) - (scaledDividend0, multiplyByTenPow(scaledDivisor0, diffScale.toInt)) + (scaledDividend0, multiplyByTenPow(scaledDivisor0, diffScale)) else if (diffScale < 0) - (multiplyByTenPow(scaledDividend0, -diffScale.toInt), scaledDivisor0) + (multiplyByTenPow(scaledDividend0, -diffScale), scaledDivisor0) else - (scaledDividend0,scaledDivisor0) + (scaledDividend0, scaledDivisor0) divideBigIntegers(scaledDividend, scaledDivisor, scale, roundingMode) } if (this._bitLength < 64 && divisor._bitLength < 64) { - val lpt = LongTenPows(diffScale.toInt) val lptLen = LongTenPows.length - val lptbLen = LongTenPowsBitLength(diffScale.toInt) - val lptMinus = LongTenPows(-diffScale.toInt) - val lptbMinusLen = LongTenPowsBitLength(-diffScale.toInt) if (diffScale == 0) { val div = divisor._smallValue dividePrimitiveLongs(_smallValue, div, scale, roundingMode) } else if (diffScale > 0) { - if (diffScale < lptLen && divisor._bitLength + lptbLen < 64) { - val div = divisor._smallValue * lpt + if (diffScale < lptLen && + divisor._bitLength + LongTenPowsBitLength(diffScale) < 64) { + val div = divisor._smallValue * LongTenPows(diffScale) dividePrimitiveLongs(_smallValue, div, scale, roundingMode) } else { default() } - } else if (-diffScale < lptLen && this._bitLength + lptbMinusLen < 64) { - val div = _smallValue * lptMinus - dividePrimitiveLongs(div, divisor._smallValue, scale, roundingMode) } else { - default() + if (diffScale > -lptLen && // `-diffScale < lptLen` without overflow + this._bitLength + LongTenPowsBitLength(-diffScale) < 64) { + val div = _smallValue * LongTenPows(-diffScale) + dividePrimitiveLongs(div, divisor._smallValue, scale, roundingMode) + } else { + default() + } } } else { default() diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalArithmeticTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalArithmeticTest.scala index be3b7ddf37..27b16a32bb 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalArithmeticTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalArithmeticTest.scala @@ -497,6 +497,14 @@ class BigDecimalArithmeticTest { assertEquals(result.scale(), newScale) } + @Test def testDivideBigDecimalScale_issue2755(): Unit = { + val a = new BigDecimal(2L) + val b = new BigDecimal(1L) + val r = a.divide(b, 1, RoundingMode.UNNECESSARY) + assertEquals(1, r.scale()) + assertEquals(2L, r.longValueExact()) + } + @Test def testDivideByZero(): Unit = { val a = "1231212478987482988429808779810457634781384756794987" val aScale = 15 From 891a5f2068ffe6ccc07ad06ee1c0f245b277f7e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 6 Feb 2017 17:37:11 +0100 Subject: [PATCH 0121/2665] Make the union type understand variance for 1-arg type constructors. The subtyping rules of the union type, materialized by implicit `Evidence`s, are enhanced with support for variance in type constructors of 1 argument. Concretely, this means that `List[Int]` can now be assigned to a `List[Int | String]`, and that a `Consumer[Int | String]` can be assigned to a `Consumer[Int]` (for some `Consumer[-A]`). --- .../main/scala/scala/scalajs/js/Union.scala | 23 +++++++++- .../testsuite/library/UnionTypeTest.scala | 45 ++++++++++++++++++- 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/js/Union.scala b/library/src/main/scala/scala/scalajs/js/Union.scala index 5d1cf77815..ad8479105b 100644 --- a/library/src/main/scala/scala/scalajs/js/Union.scala +++ b/library/src/main/scala/scala/scalajs/js/Union.scala @@ -10,6 +10,7 @@ package scala.scalajs.js import scala.language.implicitConversions +import scala.language.higherKinds /** Value of type A or B (union type). * @@ -20,7 +21,7 @@ import scala.language.implicitConversions sealed trait |[A, B] // scalastyle:ignore object | { // scalastyle:ignore - /** Evidence that `A <: B`, taking top-level `|`-types into account. */ + /** Evidence that `A <: B`, taking `|`-types into account. */ sealed trait Evidence[-A, +B] /** A unique (and typically dead-code-eliminated away) instance of @@ -32,6 +33,18 @@ object | { // scalastyle:ignore /** If `A <: B2`, then `A <: B1 | B2`. */ implicit def right[A, B1, B2](implicit ev: Evidence[A, B2]): Evidence[A, B1 | B2] = ReusableEvidence.asInstanceOf[Evidence[A, B1 | B2]] + + /** Given a covariant type constructor `F[+_]`, if `A <: B`, then + * `F[A] <: F[B]`. + */ + implicit def covariant[F[+_], A, B](implicit ev: Evidence[A, B]): Evidence[F[A], F[B]] = + ReusableEvidence.asInstanceOf[Evidence[F[A], F[B]]] + + /** Given a contravariant type constructor `F[-_]`, if `B <: A`, then + * `F[A] <: F[B]`. + */ + implicit def contravariant[F[-_], A, B](implicit ev: Evidence[B, A]): Evidence[F[A], F[B]] = + ReusableEvidence.asInstanceOf[Evidence[F[A], F[B]]] } abstract sealed class EvidenceLowPrioImplicits extends EvidenceLowestPrioImplicits { @@ -66,6 +79,14 @@ object | { // scalastyle:ignore implicit def from[A, B1, B2](a: A)(implicit ev: Evidence[A, B1 | B2]): B1 | B2 = a.asInstanceOf[B1 | B2] + /** Upcast `F[A]` to `F[B]`. + * + * This needs evidence that `F[A] <: F[B]`. + */ + implicit def fromTypeConstructor[F[_], A, B](a: F[A])( + implicit ev: Evidence[F[A], F[B]]): F[B] = + a.asInstanceOf[F[B]] + /** Operations on union types. */ implicit class UnionOps[A <: _ | _](val self: A) extends AnyVal { /** Explicitly merge a union type to a supertype (which might not be a diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UnionTypeTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UnionTypeTest.scala index 0dd4363ed5..45db7507c6 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UnionTypeTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UnionTypeTest.scala @@ -19,9 +19,12 @@ import org.scalajs.testsuite.Typechecking._ import org.junit.Assert._ import org.junit.Test -class UnionTypeTest { +object UnionTypeTest { + class Consumer[-A] +} - private implicit def unionAsJSAny(x: _ | _): js.Any = x.asInstanceOf[js.Any] +class UnionTypeTest { + import UnionTypeTest._ // js.| (postive) @@ -176,6 +179,29 @@ class UnionTypeTest { assertEquals(a, a: js.UndefOr[js.UndefOr[Object] | Object | String]) } + @Test def covariant_type_constructor(): Unit = { + val a: List[Int] = List(5) + + assertSame(a, a: List[Int | String]) + assertSame(a, a: List[String | AnyVal]) + + val b: Int | List[Int] = a + + assertSame(a, b: AnyVal | List[Int | String]) + } + + @Test def contravariant_type_constructor(): Unit = { + val a: Consumer[CharSequence | Int] = new Consumer + + assertSame(a, a: Consumer[Int]) + assertSame(a, a: Consumer[String]) + assertSame(a, a: Consumer[Int | String]) + + val b: Int | Consumer[CharSequence | Int] = a + + assertSame(a, b: Consumer[Int | String] | AnyVal) + } + // js.| (negative) /* Error messages vary a lot depending on the version of Scala, so we do @@ -213,4 +239,19 @@ class UnionTypeTest { typeError( "(List(1, 2): List[Int] | Set[Int]).merge: Seq[Int]") } + + @Test def invariant_type_constructor(): Unit = { + typeError( + "(Array[Int]()): Array[Int | String]") + } + + @Test def covariant_type_constructor_in_contravariant_pos(): Unit = { + typeError( + "(Nil: List[Int | String]): List[Int]") + } + + @Test def contravariant_type_constructor_in_covariant_pos(): Unit = { + typeError( + "(new Consumer[Int]): Consumer[Int | String]") + } } From 1c3e27dc7ee26270a891e2bfaa32f9412e49c69c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 7 Feb 2017 10:37:21 +0100 Subject: [PATCH 0122/2665] Implement System.lineSeparator(). This is a JDK7 API. In Scala.js, it trivially returns `"\n"`. --- .../src/main/scala/java/lang/System.scala | 2 ++ .../javalib/lang/SystemTestOnJDK7.scala | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/lang/SystemTestOnJDK7.scala diff --git a/javalanglib/src/main/scala/java/lang/System.scala b/javalanglib/src/main/scala/java/lang/System.scala index 905fe17260..de07c62c68 100644 --- a/javalanglib/src/main/scala/java/lang/System.scala +++ b/javalanglib/src/main/scala/java/lang/System.scala @@ -245,6 +245,8 @@ object System { def getProperties(): ju.Properties = SystemProperties.value + def lineSeparator(): String = "\n" + def setProperties(properties: ju.Properties): Unit = { SystemProperties.value = if (properties != null) properties diff --git a/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/lang/SystemTestOnJDK7.scala b/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/lang/SystemTestOnJDK7.scala new file mode 100644 index 0000000000..3a6c4332af --- /dev/null +++ b/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/lang/SystemTestOnJDK7.scala @@ -0,0 +1,24 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.javalib.lang + +import org.scalajs.testsuite.utils.Platform._ + +import org.junit.Test +import org.junit.Assert._ + +class SystemTestOnJDK7 { + @Test def lineSeparator(): Unit = { + val lineSep = System.lineSeparator() + + if (!executingInJVM) + assertEquals("\n", lineSep) + else + assertTrue(Set("\n", "\r", "\r\n").contains(lineSep)) + } +} From b55b935b2f19f41875590db589f6b105e93af2a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 14 Feb 2017 20:19:51 +0100 Subject: [PATCH 0123/2665] Add a test ensuring we preserve evaluation order in object literals. --- .../testsuite/jsinterop/DynamicTest.scala | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DynamicTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DynamicTest.scala index 51b836ba4a..b9feb9047e 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DynamicTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DynamicTest.scala @@ -177,6 +177,50 @@ class DynamicTest { assertEquals(1, count) } + @Test def should_preserve_evaluation_order_of_keys_and_values(): Unit = { + import js.Dynamic.{ literal => obj } + + val orderCheck = Array.newBuilder[Int] + val x = obj( + { orderCheck += 1; "foo" } -> { orderCheck += 2; 3 }, + { orderCheck += 3; "bar" } -> { orderCheck += 4; "foobar" }) + val x_foo = x.foo + assertEquals(3, x_foo) + val x_bar = x.bar + assertEquals("foobar", x_bar) + val x_unknown = x.unknown + assertJSUndefined(x_unknown) + assertArrayEquals(Array(1, 2, 3, 4), orderCheck.result()) + + val orderCheck2 = Array.newBuilder[Int] + + def tup1 = ({ orderCheck2 += 1; "hello1" }, { orderCheck2 += 2; 3: js.Any }) + def tup2 = ({ orderCheck2 += 3; "hello2" }, { orderCheck2 += 4; 10: js.Any }) + + val y = obj(tup1, tup2) + val y_hello1 = y.hello1 + assertEquals(3, y_hello1) + val y_hello2 = y.hello2 + assertEquals(10, y_hello2) + assertArrayEquals(Array(1, 2, 3, 4), orderCheck2.result()) + + @noinline def block[A](a: A): A = a + + val orderCheck3 = Array.newBuilder[Int] + val z = obj( + { val a = block("foo"); orderCheck3 += 1; a } -> + { val a = block(3); orderCheck3 += 2; a }, + { val a = block("bar"); orderCheck3 += 3; a } -> + { val a = block("foobar"); orderCheck3 += 4; a }) + val z_foo = z.foo + assertEquals(3, z_foo) + val z_bar = z.bar + assertEquals("foobar", z_bar) + val z_unknown = z.unknown + assertJSUndefined(z_unknown) + assertArrayEquals(Array(1, 2, 3, 4), orderCheck3.result()) + } + @Test def should_allow_to_create_an_empty_object_with_the_literal_syntax(): Unit = { import js.Dynamic.{ literal => obj } val x = obj() From c3ec9ed5b92ea1271704e594bbd0bc64b8100a60 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Thu, 5 Jan 2017 22:20:48 +0100 Subject: [PATCH 0124/2665] Remove javascript.Tree.PropertyName.name. --- project/BinaryIncompatibilities.scala | 10 ++++++++++ .../backend/closure/ClosureAstTransformer.scala | 15 ++++++++++----- .../org/scalajs/core/tools/javascript/Trees.scala | 5 +---- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index c5c10ad148..c7355354a3 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -45,6 +45,12 @@ object BinaryIncompatibilities { ) val Tools = Seq( + // Breaking. Remove PropertyName.name + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.javascript.Trees#PropertyName.name"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.javascript.Trees#StringLiteral.name"), + // private, not an issue ProblemFilters.exclude[DirectMissingMethodProblem]( "org.scalajs.core.tools.sem.Semantics.this"), @@ -59,6 +65,10 @@ object BinaryIncompatibilities { ProblemFilters.exclude[DirectMissingMethodProblem]( "org.scalajs.core.tools.linker.analyzer.Analyzer.org$scalajs$core$tools$linker$analyzer$Analyzer$$createMissingMethodInfo$default$3"), + // private[closure], not an issue + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "org.scalajs.core.tools.linker.backend.closure.ClosureAstTransformer.transformString"), + // private[emitter], not an issue ProblemFilters.exclude[MissingMethodProblem]( "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genClass"), diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala index b59e932b46..21501289b6 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala @@ -233,15 +233,20 @@ private[closure] class ClosureAstTransformer(relativizeBaseURI: Option[URI]) { setNodePosition(Node.newString(Token.LABEL_NAME, ident.name), ident.pos orElse parentPos) - def transformString(pName: PropertyName)(implicit parentPos: Position): Node = - setNodePosition(Node.newString(pName.name), pName.pos orElse parentPos) + def transformString(ident: Ident)(implicit parentPos: Position): Node = + setNodePosition(Node.newString(ident.name), ident.pos orElse parentPos) def transformStringKey(pName: PropertyName)( implicit parentPos: Position): Node = { - val node = Node.newString(Token.STRING_KEY, pName.name) + val node = pName match { + case Ident(name, _) => + Node.newString(Token.STRING_KEY, name) - if (pName.isInstanceOf[StringLiteral]) - node.setQuotedString() + case StringLiteral(name) => + val node = Node.newString(Token.STRING_KEY, name) + node.setQuotedString() + node + } setNodePosition(node, pName.pos orElse parentPos) } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala index 3772f96964..5ab5cd5e09 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala @@ -37,7 +37,6 @@ object Trees { // Identifiers and properties sealed trait PropertyName { - def name: String def pos: Position } @@ -205,9 +204,7 @@ object Trees { case class DoubleLiteral(value: Double)(implicit val pos: Position) extends Literal case class StringLiteral(value: String)( - implicit val pos: Position) extends Literal with PropertyName { - override def name = value - } + implicit val pos: Position) extends Literal with PropertyName // Atomic expressions From e0eeb70d79753a8d9c621ba34abb496d7406783d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 6 Feb 2017 16:52:42 +0100 Subject: [PATCH 0125/2665] Opt: Virtualize JSArrayConstr's in the optimizer. This commit introduces a new kind of virtualized value (a new `LocalDefReplacement`) for JavaScript arrays created as a `JSArrayConstr` IR node. They can stay virtualized as long as the only operations performed on them are: * Reading the `length` property (replaced by a constant) * Reading an indexed property (replaced by the `LocalDef` at the appropriate index in the virtualized array, or `undefined` if the index is out of bounds) * Using the array in a `JSSpread` (the spread is expanded and replaced by a fixed number of arguments) This is particularly effective in two scenarios: * When writing Scala wrappers taking varargs that forward them as to a JS method taking varargs: if inlined, at call site the optimizer can expand the arguments as fixed arguments to the JS method. * When manipulating js.Tuples, which now have the same stack allocation capabilities as Scala tuples. --- .../testsuite/compiler/OptimizerTest.scala | 82 ++++++++ .../frontend/optimizer/OptimizerCore.scala | 185 ++++++++++++++++-- 2 files changed, 247 insertions(+), 20 deletions(-) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala index cf5c1541fb..adb17d4215 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala @@ -8,6 +8,7 @@ package org.scalajs.testsuite.compiler import scala.scalajs.js +import scala.scalajs.js.annotation._ import org.junit.Test import org.junit.Assert._ @@ -355,6 +356,87 @@ class OptimizerTest { assertEquals("Scala.js", 'S' + "cala.js") assertEquals("Scala.js", "Scala.j" + 's') } + + // Virtualization of JSArrayConstr + + @Test def must_not_break_virtualized_jsarrayconstr(): Unit = { + @noinline def b = 42 + + val a = js.Array[Any]("hello", b) + + assertEquals(2, a.length) + assertEquals("hello", a(0)) + assertEquals(42, a(1)) + assertEquals(js.undefined, a(-1)) + assertEquals(js.undefined, a(2)) + } + + @Test def must_not_break_escaped_jsarrayconstr(): Unit = { + @noinline def escape[A](a: A): A = a + + val a = js.Array[Any]("hello", 42) + + assertEquals(2, a.length) + assertEquals("hello", a(0)) + assertEquals(42, a(1)) + assertEquals(js.undefined, a(-1)) + assertEquals(js.undefined, a(2)) + + assertEquals(2, escape(a).length) + } + + @Test def must_not_break_modified_jsarrayconstr(): Unit = { + @noinline def escape[A](a: A): A = a + + val a = js.Array[Any]("hello", 42) + + assertEquals(2, a.length) + assertEquals("hello", a(0)) + assertEquals(42, a(1)) + assertEquals(js.undefined, a(-1)) + assertEquals(js.undefined, a(2)) + + a(0) = "bar" + + assertEquals("bar", a(0)) + } + + @Test def must_not_break_virtualized_jsarrayconstr_in_spread(): Unit = { + @ScalaJSDefined + class Foo extends js.Object { + def check(a: Int, b: String, rest: Any*): Unit = { + assertEquals(5, a) + assertEquals("foobar", b) + assertEquals(2, rest.length) + assertEquals("hello", rest(0)) + assertEquals(42, rest(1)) + } + } + + val a = js.Array[Any]("hello", 42) + val foo = new Foo + foo.check(5, "foobar", a: _*) + } + + @Test def must_not_break_virtualized_tuple(): Unit = { + @noinline def b = 42 + + val a = js.Tuple2("hello", b) + + assertEquals("hello", a._1) + assertEquals(42, a._2) + } + + @Test def must_not_break_escaped_tuple(): Unit = { + @noinline def escape[A](a: A): A = a + + val a = js.Tuple2("hello", 42) + + assertEquals("hello", a._1) + assertEquals(42, a._2) + + assertEquals("hello", escape(a)._1) + } } object OptimizerTest { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index a2fcb65aab..ea7b07bdf9 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -287,16 +287,6 @@ private[optimizer] abstract class OptimizerCore( private def transformExpr(tree: Tree)(implicit scope: Scope): Tree = transform(tree, isStat = false) - /** Transforms an expression or a JSSpread. */ - private def transformExprOrSpread(tree: Tree)(implicit scope: Scope): Tree = { - tree match { - case JSSpread(items) => - JSSpread(transformExpr(items))(tree.pos) - case _ => - transformExpr(tree) - } - } - /** Transforms a tree. */ private def transform(tree: Tree, isStat: Boolean)( implicit scope: Scope): Tree = { @@ -366,6 +356,8 @@ private[optimizer] abstract class OptimizerCore( lhs match { case lhs: Select => pretransformSelectCommon(lhs, isLhsOfAssign = true)(cont) + case lhs: JSBracketSelect => + pretransformJSBracketSelect(lhs, isLhsOfAssign = true)(cont) case _ => pretransformExpr(lhs)(cont) } @@ -606,13 +598,16 @@ private[optimizer] abstract class OptimizerCore( // JavaScript expressions case JSNew(ctor, args) => - JSNew(transformExpr(ctor), args map transformExprOrSpread) + JSNew(transformExpr(ctor), transformExprsOrSpreads(args)) case JSDotSelect(qualifier, item) => JSDotSelect(transformExpr(qualifier), item) - case JSBracketSelect(qualifier, item) => - foldJSBracketSelect(transformExpr(qualifier), transformExpr(item)) + case tree: JSBracketSelect => + trampoline { + pretransformJSBracketSelect(tree, isLhsOfAssign = false)( + finishTransform(isStat)) + } case tree: JSFunctionApply => trampoline { @@ -622,21 +617,21 @@ private[optimizer] abstract class OptimizerCore( case JSDotMethodApply(receiver, method, args) => JSDotMethodApply(transformExpr(receiver), method, - args map transformExprOrSpread) + transformExprsOrSpreads(args)) case JSBracketMethodApply(receiver, method, args) => JSBracketMethodApply(transformExpr(receiver), transformExpr(method), - args map transformExprOrSpread) + transformExprsOrSpreads(args)) case JSSuperBracketSelect(cls, qualifier, item) => JSSuperBracketSelect(cls, transformExpr(qualifier), transformExpr(item)) case JSSuperBracketCall(cls, receiver, method, args) => JSSuperBracketCall(cls, transformExpr(receiver), transformExpr(method), - args map transformExprOrSpread) + transformExprsOrSpreads(args)) case JSSuperConstructorCall(args) => - JSSuperConstructorCall(args map transformExprOrSpread) + JSSuperConstructorCall(transformExprsOrSpreads(args)) case JSDelete(JSDotSelect(obj, prop)) => JSDelete(JSDotSelect(transformExpr(obj), prop)) @@ -651,7 +646,7 @@ private[optimizer] abstract class OptimizerCore( JSBinaryOp(op, transformExpr(lhs), transformExpr(rhs)) case JSArrayConstr(items) => - JSArrayConstr(items map transformExprOrSpread) + JSArrayConstr(transformExprsOrSpreads(items)) case JSObjectConstr(fields) => JSObjectConstr(fields map { @@ -840,10 +835,44 @@ private[optimizer] abstract class OptimizerCore( case tree: BinaryOp => pretransformBinaryOp(tree)(cont) + case tree: JSBracketSelect => + pretransformJSBracketSelect(tree, isLhsOfAssign = false)(cont) + case tree: JSFunctionApply => pretransformJSFunctionApply(tree, isStat = false, usePreTransform = true)(cont) + case JSArrayConstr(items) => + if (items.exists(_.isInstanceOf[JSSpread])) { + /* TODO This means spread in array constr does not compose under + * this optimization. We could improve this with a + * pretransformExprsOrSpreads() or something like that. + */ + cont(JSArrayConstr(transformExprsOrSpreads(items)).toPreTransform) + } else { + pretransformExprs(items) { titems => + tryOrRollback { cancelFun => + val itemBindings = for { + (titem, index) <- titems.zipWithIndex + } yield { + Binding("x" + index, None, AnyType, mutable = false, titem) + } + withNewLocalDefs(itemBindings) { (itemLocalDefs, cont1) => + val replacement = InlineJSArrayReplacement( + itemLocalDefs.toVector, cancelFun) + val localDef = LocalDef( + RefinedType(AnyType, isExact = false, isNullable = false), + mutable = false, + replacement) + cont1(localDef.toPreTransform) + } (cont) + } { () => + cont(PreTransTree(JSArrayConstr(titems.map(finishTransformExpr)), + RefinedType(AnyType, isExact = false, isNullable = false))) + } + } + } + case AsInstanceOf(expr, tpe) => pretransformExpr(expr) { texpr => tpe match { @@ -1572,16 +1601,85 @@ private[optimizer] abstract class OptimizerCore( } } + private def pretransformJSBracketSelect(tree: JSBracketSelect, + isLhsOfAssign: Boolean)( + cont: PreTransCont)( + implicit scope: Scope): TailRec[Tree] = { + + val JSBracketSelect(qual, item) = tree + implicit val pos = tree.pos + + pretransformExprs(qual, item) { (tqual, titem0) => + val titem = optimizeJSBracketSelectItem(titem0) + + def default: TailRec[Tree] = { + cont(PreTransTree(foldJSBracketSelect(finishTransformExpr(tqual), + finishTransformExpr(titem)))) + } + + titem match { + case _ if isLhsOfAssign => + default + + case PreTransLit(itemLit) => + itemLit match { + case IntLiteral(itemInt) => + tqual match { + case PreTransLocalDef(LocalDef(_, false, + InlineJSArrayReplacement(itemLocalDefs, _))) => + if (itemInt >= 0 && itemInt < itemLocalDefs.size) + cont(itemLocalDefs(itemInt).toPreTransform) + else + cont(PreTransLit(Undefined())) + + case _ => + default + } + + case StringLiteral("length") => + tqual match { + case PreTransLocalDef(LocalDef(_, false, + InlineJSArrayReplacement(itemLocalDefs, _))) => + cont(PreTransLit(IntLiteral(itemLocalDefs.size))) + + case _ => + default + } + + case _ => + default + } + + case _ => + default + } + } + } + + private def optimizeJSBracketSelectItem(item: PreTransform): PreTransform = { + item match { + case PreTransLit(StringLiteral(s)) => + scala.util.Try(s.toInt).toOption match { + case Some(intValue) if intValue.toString == s => + PreTransLit(IntLiteral(intValue)(item.pos)) + case _ => + item + } + case _ => + item + } + } + private def pretransformJSFunctionApply(tree: JSFunctionApply, isStat: Boolean, usePreTransform: Boolean)( cont: PreTransCont)( - implicit scope: Scope, pos: Position): TailRec[Tree] = { + implicit scope: Scope): TailRec[Tree] = { val JSFunctionApply(fun, args) = tree implicit val pos = tree.pos if (args.exists(_.isInstanceOf[JSSpread])) { cont(JSFunctionApply(transformExpr(fun), - args.map(transformExprOrSpread)).toPreTransform) + transformExprsOrSpreads(args)).toPreTransform) } else { pretransformExpr(fun) { tfun => tfun match { @@ -1606,6 +1704,44 @@ private[optimizer] abstract class OptimizerCore( } } + private def transformExprsOrSpreads(trees: List[Tree])( + implicit scope: Scope): List[Tree] = { + + trees match { + case (spread: JSSpread) :: rest => + implicit val pos = spread.pos + + val newSpreadItems = trampoline { + pretransformExpr(spread.items) { tspreadItems => + TailCalls.done { + tspreadItems match { + case PreTransLocalDef(LocalDef(_, false, + InlineJSArrayReplacement(itemLocalDefs, _))) => + JSArrayConstr( + itemLocalDefs.toList.map(_.newReplacement(spread.pos))) + + case _ => + finishTransformExpr(tspreadItems) + } + } + } + } + + val newRest = transformExprsOrSpreads(rest) + + newSpreadItems match { + case JSArrayConstr(newFirsts) => newFirsts ::: newRest + case _ => JSSpread(newSpreadItems) :: newRest + } + + case first :: rest => + transformExpr(first) :: transformExprsOrSpreads(rest) + + case Nil => + Nil + } + } + private val ClassNamesThatShouldBeInlined = Set( "s_Predef$$less$colon$less", "s_Predef$$eq$colon$eq", @@ -4148,6 +4284,9 @@ private[optimizer] object OptimizerCore { case InlineClassInstanceReplacement(_, _, cancelFun) => cancelFun() + + case InlineJSArrayReplacement(_, cancelFun) => + cancelFun() } def contains(that: LocalDef): Boolean = { @@ -4156,6 +4295,8 @@ private[optimizer] object OptimizerCore { captureLocalDefs.exists(_.contains(that)) case InlineClassInstanceReplacement(_, fieldLocalDefs, _) => fieldLocalDefs.valuesIterator.exists(_.contains(that)) + case InlineJSArrayReplacement(elemLocalDefs, _) => + elemLocalDefs.exists(_.contains(that)) case _ => false }) @@ -4195,6 +4336,10 @@ private[optimizer] object OptimizerCore { fieldLocalDefs: Map[String, LocalDef], cancelFun: CancelFun) extends LocalDefReplacement + private final case class InlineJSArrayReplacement( + elemLocalDefs: Vector[LocalDef], + cancelFun: CancelFun) extends LocalDefReplacement + private final class LabelInfo( val newName: String, val acceptRecords: Boolean, From 049cda9deee3e88b610708b9d8dbbfa0c1606b27 Mon Sep 17 00:00:00 2001 From: n4to4 Date: Fri, 17 Feb 2017 17:56:15 +0900 Subject: [PATCH 0126/2665] Update sbt-assembly to 0.14.4 --- project/build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.sbt b/project/build.sbt index bf5d5aa160..ba4d3524d3 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -5,7 +5,7 @@ resolvers += Resolver.url( addSbtPlugin("me.lessis" % "bintray-sbt" % "0.1.2") -addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.3") +addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.4") addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.13") From c7d77589915d64bfa699c844465f815ff399ca8a Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 7 Jan 2017 16:10:42 +0100 Subject: [PATCH 0127/2665] Rename ir.PropertyName.name to encodedName. The encodedName is an identity we can use internally to track methods. However, it does not coincide with any real name, as we will see with the introduction of ComputedNames. --- .../scala/org/scalajs/core/compiler/GenJSCode.scala | 4 ++-- ir/src/main/scala/org/scalajs/core/ir/Infos.scala | 4 ++-- .../main/scala/org/scalajs/core/ir/Serializers.scala | 2 +- ir/src/main/scala/org/scalajs/core/ir/Trees.scala | 6 ++++-- .../scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala | 2 +- project/BinaryIncompatibilities.scala | 8 ++++++++ .../org/scalajs/core/tools/linker/LinkedClass.scala | 4 ++-- .../tools/linker/backend/emitter/JSDesugaring.scala | 4 ++-- .../linker/backend/emitter/KnowledgeGuardian.scala | 2 +- .../linker/backend/emitter/ScalaJSClassEmitter.scala | 4 ++-- .../scalajs/core/tools/linker/checker/IRChecker.scala | 2 +- .../core/tools/linker/frontend/BaseLinker.scala | 10 +++++----- .../linker/frontend/optimizer/OptimizerCore.scala | 2 +- 13 files changed, 32 insertions(+), 22 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index cab6480e6c..0070e697df 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -1100,7 +1100,7 @@ abstract class GenJSCode extends plugins.PluginComponent else (subConstructors.head.overrideNumBounds._1, overrideNum) def get(methodName: String): Option[ConstructorTree] = { - if (methodName == this.method.name.name) { + if (methodName == this.method.name.encodedName) { Some(this) } else { subConstructors.iterator.map(_.get(methodName)).collectFirst { @@ -1370,7 +1370,7 @@ abstract class GenJSCode extends plugins.PluginComponent var overrideNum = -1 def mkConstructorTree(method: js.MethodDef): ConstructorTree = { - val methodName = method.name.name + val methodName = method.name.encodedName val subCtrTrees = ctorToChildren(methodName).map(mkConstructorTree) overrideNum += 1 new ConstructorTree(overrideNum, method, subCtrTrees) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala index 4bcba6170d..cc443e9029 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala @@ -373,7 +373,7 @@ object Infos { def generateMethodInfo(methodDef: MethodDef): MethodInfo = { builder - .setEncodedName(methodDef.name.name) + .setEncodedName(methodDef.name.encodedName) .setIsStatic(methodDef.static) .setIsAbstract(methodDef.body.isEmpty) .setIsExported(methodDef.name.isInstanceOf[StringLiteral]) @@ -385,7 +385,7 @@ object Infos { def generatePropertyInfo(propertyDef: PropertyDef): MethodInfo = { builder - .setEncodedName(propertyDef.name.name) + .setEncodedName(propertyDef.name.encodedName) .setIsStatic(propertyDef.static) .setIsExported(true) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index 05f3de7e35..06ac5090ae 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -870,7 +870,7 @@ object Serializers { result1 } if (useHacks065 && result2.resultType != NoType && - isConstructorName(result2.name.name)) { + isConstructorName(result2.name.encodedName)) { result2.copy(resultType = NoType, body = result2.body)( result2.optimizerHints, result2.hash)( result2.pos) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 655fb9611c..d68d4cbe11 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -31,13 +31,15 @@ object Trees { // Identifiers and properties sealed trait PropertyName { - def name: String + /** Encoded name of this PropertyName within its owner's scope. */ + def encodedName: String def pos: Position } case class Ident(name: String, originalName: Option[String])( implicit val pos: Position) extends PropertyName { requireValidIdent(name) + def encodedName: String = name } object Ident { @@ -741,7 +743,7 @@ object Trees { case class StringLiteral(value: String)( implicit val pos: Position) extends Literal with PropertyName { val tpe = StringType - override def name: String = value + override def encodedName: String = value } case class ClassOf(cls: ReferenceType)( diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala index 73349a7a09..0fbae38b61 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala @@ -41,7 +41,7 @@ private[rhino] class ScalaJSCoreLib(linkingUnit: LinkingUnit) { for (linkedClass <- linkingUnit.classDefs) { def hasStaticInitializer = { linkedClass.staticMethods.exists { - _.tree.name.name == ir.Definitions.StaticInitializerName + _.tree.name.encodedName == ir.Definitions.StaticInitializerName } } diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index c7355354a3..c581e1b71d 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -37,6 +37,14 @@ object BinaryIncompatibilities { ProblemFilters.exclude[DirectMissingMethodProblem]( "org.scalajs.core.ir.Tags.TagTopLevelExportDef"), + // Breaking: PropertyName.{name -> encodedName} + ProblemFilters.exclude[ReversedMissingMethodProblem]( + "org.scalajs.core.ir.Trees#PropertyName.encodedName"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.ir.Trees#StringLiteral.name"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.ir.Trees#PropertyName.name"), + // private, not an issue ProblemFilters.exclude[DirectMissingMethodProblem]( "org.scalajs.core.ir.Infos#MethodInfo.this"), diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala index b92dbdbedf..5075a5df87 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala @@ -146,12 +146,12 @@ object LinkedClass { val classExports = mutable.Buffer.empty[Tree] def linkedMethod(m: MethodDef) = { - val info = memberInfoByName(m.name.name) + val info = memberInfoByName(m.name.encodedName) new LinkedMember(info, m, None) } def linkedProperty(p: PropertyDef) = { - val info = memberInfoByName(p.name.name) + val info = memberInfoByName(p.name.encodedName) new LinkedMember(info, p, None) } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala index 45c6ad2cb8..5a9ce69554 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala @@ -1478,7 +1478,7 @@ private[emitter] class JSDesugaring(semantics: Semantics, val assignFields = fields.foldRight((Set.empty[String], List.empty[Tree])) { case ((prop, value), (namesSeen, statsAcc)) => implicit val pos = value.pos - val name = prop.name + val name = prop.encodedName val stat = prop match { case _ if namesSeen.contains(name) => /* Important: do not emit the assignment, otherwise @@ -1574,7 +1574,7 @@ private[emitter] class JSDesugaring(semantics: Semantics, /** Tests whether a [[JSObjectConstr]] must be desugared. */ private def doesObjectConstrRequireDesugaring( tree: JSObjectConstr): Boolean = { - val names = tree.fields.map(_._1.name) + val names = tree.fields.map(_._1.encodedName) names.toSet.size != names.size // i.e., there is at least one duplicate } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala index 34c85d3ab7..a3111eada0 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala @@ -55,7 +55,7 @@ private[emitter] final class KnowledgeGuardian { if (linkedClass.encodedName == LongImpl.RuntimeLongClass) { newHasNewRuntimeLong = linkedClass.memberMethods.exists { linkedMethod => - linkedMethod.tree.name.name == LongImpl.initFromParts + linkedMethod.tree.name.encodedName == LongImpl.initFromParts } } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala index 97dbcf87f0..9f6af003ea 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala @@ -340,7 +340,7 @@ private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, def genStaticInitialization(tree: LinkedClass): js.Tree = { import Definitions.StaticInitializerName implicit val pos = tree.pos - if (tree.staticMethods.exists(_.tree.name.name == StaticInitializerName)) { + if (tree.staticMethods.exists(_.tree.name.encodedName == StaticInitializerName)) { val fullName = tree.encodedName + "__" + StaticInitializerName js.Apply(envField("s", fullName, Some("")), Nil) } else { @@ -359,7 +359,7 @@ private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, val methodFun0 = desugarToFunction(className, method.args, methodBody, method.resultType == NoType) - val methodFun = if (Definitions.isConstructorName(method.name.name)) { + val methodFun = if (Definitions.isConstructorName(method.name.encodedName)) { // init methods have to return `this` so that we can chain them to `new` js.Function(methodFun0.args, { implicit val pos = methodFun0.body.pos diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 7e7b103cb8..5a8ab77987 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -128,7 +128,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { */ val staticFieldDefs = classDef.fields.filter(_.static) for { - fieldsWithSameName <- staticFieldDefs.groupBy(_.name.name).values + fieldsWithSameName <- staticFieldDefs.groupBy(_.name.encodedName).values duplicate <- fieldsWithSameName.tail } { implicit val ctx = ErrorContext(duplicate) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index 9c386e7e53..348880172a 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -201,13 +201,13 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions val classExports = mutable.Buffer.empty[Tree] def linkedMethod(m: MethodDef) = { - val info = memberInfoByStaticAndName((m.static, m.name.name)) + val info = memberInfoByStaticAndName((m.static, m.name.encodedName)) val version = m.hash.map(Hashers.hashAsVersion(_, considerPositions)) new LinkedMember(info, m, version) } def linkedProperty(p: PropertyDef) = { - val info = memberInfoByStaticAndName((p.static, p.name.name)) + val info = memberInfoByStaticAndName((p.static, p.name.encodedName)) new LinkedMember(info, p, None) } @@ -220,7 +220,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions classDef.defs.foreach { // Static methods case m: MethodDef if m.static => - if (analyzerInfo.staticMethodInfos(m.name.name).isReachable) { + if (analyzerInfo.staticMethodInfos(m.name.encodedName).isReachable) { if (m.name.isInstanceOf[StringLiteral]) exportedMembers += linkedMethod(m) else @@ -234,7 +234,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions // Normal methods case m: MethodDef => - if (analyzerInfo.methodInfos(m.name.name).isReachable) { + if (analyzerInfo.methodInfos(m.name.encodedName).isReachable) { if (m.name.isInstanceOf[StringLiteral]) exportedMembers += linkedMethod(m) else if (m.body.isDefined) @@ -445,7 +445,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions val (classDef, _) = getTree(classInfo.encodedName) classDef.defs.collectFirst { case mDef: MethodDef - if !mDef.static && mDef.name.name == methodName => mDef + if !mDef.static && mDef.name.encodedName == methodName => mDef }.getOrElse { throw new AssertionError( s"Cannot find $methodName in ${classInfo.encodedName}") diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index a2fcb65aab..ca0c109546 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -142,7 +142,7 @@ private[optimizer] abstract class OptimizerCore( transformIsolatedBody(Some(myself), thisType, params, resultType, body) } val newBody = - if (name.name == "init___") tryElimStoreModule(newBody1) + if (name.encodedName == "init___") tryElimStoreModule(newBody1) else newBody1 val m = MethodDef(static, name, newParams, resultType, Some(newBody))(originalDef.optimizerHints, None)(originalDef.pos) From b75217575aa0e882a5477d41f906cff28315b4b9 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 20 Nov 2016 18:51:04 -0800 Subject: [PATCH 0128/2665] Add the API of JavaScript symbols to the library. --- .../main/scala/scala/scalajs/js/Symbol.scala | 131 ++++++++++++++++++ .../scalajs/testsuite/utils/Platform.scala | 4 + .../testsuite/jsinterop/SymbolTest.scala | 61 ++++++++ 3 files changed, 196 insertions(+) create mode 100644 library/src/main/scala/scala/scalajs/js/Symbol.scala create mode 100644 test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SymbolTest.scala diff --git a/library/src/main/scala/scala/scalajs/js/Symbol.scala b/library/src/main/scala/scala/scalajs/js/Symbol.scala new file mode 100644 index 0000000000..eaa3b7cc48 --- /dev/null +++ b/library/src/main/scala/scala/scalajs/js/Symbol.scala @@ -0,0 +1,131 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js API ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package scala.scalajs.js + +import scala.scalajs.js +import scala.scalajs.js.annotation._ + +/** ECMAScript 6 + * JavaScript Symbol. + */ +@js.native +sealed trait Symbol extends js.Any + +/** ECMAScript 6 + * Factory for [[Symbol js.Symbol]]s and well-known symbols. + * + * @groupname factories Factories for unique symbols + * @groupprio 10 + * + * @groupname registry Global symbol registry + * @groupprio 20 + * + * @groupname wellknownsyms Well-known symbols + * @groupprio 30 + */ +@js.native +object Symbol extends js.Object { + /** Creates a new unique symbol without description. + * + * @group factories + */ + def apply(): Symbol = js.native + + /** Creates a new unique symbol with the specified description. + * + * @group factories + */ + def apply(description: String): Symbol = js.native + + /** Retrieves the symbol with the specified key in the global symbol registry. + * + * The returned symbol's description is also the key. + * + * Asking twice `forKey` with the same key returns the same symbol, + * globally. + * + * @group registry + */ + @JSName("for") + def forKey(key: String): Symbol = js.native + + /** Retrieves the key under which the specified symbol is registered in the + * global symbol registry, or `undefined` if it is not registered. + * + * @group registry + */ + def keyFor(sym: Symbol): js.UndefOr[String] = js.native + + /** The well-known symbol `@@hasInstance`. + * + * @group wellknownsyms + */ + val hasInstance: Symbol = js.native + + /** The well-known symbol `@@isConcatSpreadable`. + * + * @group wellknownsyms + */ + val isConcatSpreadable: Symbol = js.native + + /** The well-known symbol `@@iterator`. + * + * @group wellknownsyms + */ + val iterator: Symbol = js.native + + /** The well-known symbol `@@match`. + * + * @group wellknownsyms + */ + val `match`: Symbol = js.native + + /** The well-known symbol `@@replace`. + * + * @group wellknownsyms + */ + val replace: Symbol = js.native + + /** The well-known symbol `@@search`. + * + * @group wellknownsyms + */ + val search: Symbol = js.native + + /** The well-known symbol `@@species`. + * + * @group wellknownsyms + */ + val species: Symbol = js.native + + /** The well-known symbol `@@split`. + * + * @group wellknownsyms + */ + val split: Symbol = js.native + + /** The well-known symbol `@@toPrimitive`. + * + * @group wellknownsyms + */ + val toPrimitive: Symbol = js.native + + /** The well-known symbol `@@toStringTag`. + * + * @group wellknownsyms + */ + val toStringTag: Symbol = js.native + + /** The well-known symbol `@@unscopables`. + * + * @group wellknownsyms + */ + val unscopables: Symbol = js.native +} diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala index 5797fa2173..7947fb6d1d 100644 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala +++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala @@ -7,6 +7,7 @@ \* */ package org.scalajs.testsuite.utils +import scala.scalajs.js import scala.scalajs.runtime object Platform { @@ -29,6 +30,9 @@ object Platform { def areTypedArraysSupported: Boolean = runtime.Bits.areTypedArraysSupported + def areJSSymbolsSupported: Boolean = + !js.isUndefined(js.Dynamic.global.Symbol) + def executingInRhino: Boolean = sysProp("rhino") def executingInNodeJS: Boolean = sysProp("nodejs") def executingInNodeJSOnJSDOM: Boolean = sysProp("nodejs.jsdom") diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SymbolTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SymbolTest.scala new file mode 100644 index 0000000000..7501e5ac7c --- /dev/null +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SymbolTest.scala @@ -0,0 +1,61 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.jsinterop + +import scala.scalajs.js + +import org.junit.Assert._ +import org.junit.Assume._ +import org.junit.{BeforeClass, Test} + +object SymbolTest { + @BeforeClass def assumeSymbolsAreSupported(): Unit = { + assumeTrue("Assuming JavaScript symbols are supported", + org.scalajs.testsuite.utils.Platform.areJSSymbolsSupported) + } +} + +class SymbolTest { + + val namedSymbol = js.Symbol.forKey("namedsym") + val opaqueSymbolWithDesc = js.Symbol("opaqueSymbolWithDesc") + val opaqueSymbolWithoutDesc = js.Symbol() + + @Test def typeOf(): Unit = { + assertEquals("symbol", js.typeOf(namedSymbol)) + assertEquals("symbol", js.typeOf(opaqueSymbolWithDesc)) + assertEquals("symbol", js.typeOf(opaqueSymbolWithoutDesc)) + } + + @Test def keyFor(): Unit = { + assertEquals("namedsym", js.Symbol.keyFor(namedSymbol)) + assertEquals(js.undefined, js.Symbol.keyFor(opaqueSymbolWithDesc)) + assertEquals(js.undefined, js.Symbol.keyFor(opaqueSymbolWithoutDesc)) + } + + @Test def identity(): Unit = { + assertSame(namedSymbol, js.Symbol.forKey("namedsym")) + assertNotSame(namedSymbol, js.Symbol("namedsym")) + assertNotSame(opaqueSymbolWithDesc, js.Symbol("opaqueSymbolWithDesc")) + assertNotSame(opaqueSymbolWithoutDesc, js.Symbol()) + } + + @Test def testToString(): Unit = { + assertEquals("Symbol(namedsym)", namedSymbol.toString()) + assertEquals("Symbol(opaqueSymbolWithDesc)", opaqueSymbolWithDesc.toString()) + assertEquals("Symbol()", opaqueSymbolWithoutDesc.toString()) + } + + @Test def wellKnownSymbolIterator(): Unit = { + val sym = js.Symbol.iterator + assertEquals("symbol", js.typeOf(sym)) + assertEquals(js.undefined, js.Symbol.keyFor(sym)) + assertEquals("Symbol(Symbol.iterator)", sym.toString()) + } + +} From e9174fe1a994e5e94a01d0705c2c1847727a0df3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 17 Feb 2017 15:52:26 +0100 Subject: [PATCH 0129/2665] Nicer pretty-printing of JS native load specs in the IR printer. --- .../scala/org/scalajs/core/ir/Printers.scala | 29 ++++++++++++++++++- .../org/scalajs/core/ir/PrintersTest.scala | 4 +-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index 80cbeaebe9..24c30be6bc 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -797,7 +797,7 @@ object Printers { } jsNativeLoadSpec.foreach { spec => print(" loadfrom ") - print(spec.toString) + print(spec) } print(" ") printColumn(defs, "{", "", "}") @@ -935,6 +935,33 @@ object Printers { case ident: Ident => print(ident) } + private def print(spec: JSNativeLoadSpec): Unit = { + def printPath(path: List[String]): Unit = { + for (propName <- path) { + if (isValidIdentifier(propName)) { + print('.') + print(propName) + } else { + print('[') + print(propName) + print(']') + } + } + } + + spec match { + case JSNativeLoadSpec.Global(path) => + print("") + printPath(path) + + case JSNativeLoadSpec.Import(module, path) => + print("import(") + print(module) + print(')') + printPath(path) + } + } + protected def print(s: String): Unit = out.write(s) diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala index cc43de729a..f17099f07c 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala @@ -880,7 +880,7 @@ class PrintersTest { @Test def printClassDefJSNativeLoadSpec(): Unit = { assertPrintEquals( """ - |native js class LTest extends O loadfrom Global(List(Foo)) { + |native js class LTest extends O loadfrom .Foo { |} """, ClassDef("LTest", ClassKind.NativeJSClass, Some(ObjectClass), Nil, @@ -889,7 +889,7 @@ class PrintersTest { assertPrintEquals( """ - |native js class LTest extends O loadfrom Import(foo,List(Bar)) { + |native js class LTest extends O loadfrom import(foo).Bar { |} """, ClassDef("LTest", ClassKind.NativeJSClass, Some(ObjectClass), Nil, From 360ea48df14f2251d5c7dedb408be8cf8566d15c Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Wed, 11 Jan 2017 13:15:10 +0100 Subject: [PATCH 0130/2665] Fix #1997: Add support for js.Symbols in @JSName annotations. The `@JSName` annotation could previously be used to specify the JavaScript *string* name of a property/method, independently of its Scala name. This can be used both in native JS classes as well as Scala.js-defined JS classes. This commit extends the capability of `@JSName` to admit a (static, stable) reference to a `js.Symbol`. This applies to both native and Scala.js-defined JS types. At call site, the semantics and compilation scheme are straightforward: it is a `JSBracketSelect` whose `item` part is a call to the symbol accessor. Since it is static by construction, we can call it from anywhere. At definition site for native JS types, there is nothing to do (besides validity checks). At definition site for Scala.js-defined JS classes, things get tricky. We can now have "exported" class members whose name is not a constant string anymore. This requires to extend the IR with `ComputedName`s (a concept that exists in ECMAScript 2015). A computed name is an arbitrary expression `Tree` that is evaluated to obtain the dynamic name of a property. This complicates the Emitter somewhat, but not that much because Scala.js-defined JS classes are created lazily, so we can execute arbitrary user-defined code at class-definition time. For overloading resolution, `ComputedName`s have a `logicalName`, derived from the fully qualified name of the symbol accessors. All `ComputedName`'d properties/methods with the same logical name (i.e., referencing the same static stable `js.Symbol`) are considered to be overloaded. This has an unavoidable caveat: if two `ComputedName`s in the same class have a different logical name, but actually evaluate to the same symbol, things will go wrong at run-time. `JSObjectConstr` is enhanced to support `ComputedName`s as well, for consistency. It is also consistent with Object Initializers in ECMAScript 2015. This actually complicates their treatment, mostly because of evaluation order concerns. Exports (in Scala classes and at the top-level) cannot use symbolic names. This is not expected to change in the future. There is one implementation restriction: `@JSName` with a symbol is not supported on native JS classes and objects that are nested within a native JS object. There is no language reason to disallow this, but the implementation is surprisingly difficult, due to the way scalac flattens such entities. --- .../org/scalajs/core/compiler/GenJSCode.scala | 64 +- .../scalajs/core/compiler/GenJSExports.scala | 42 +- .../scalajs/core/compiler/JSEncoding.scala | 5 + .../core/compiler/JSGlobalAddons.scala | 36 +- .../scalajs/core/compiler/PrepJSInterop.scala | 83 ++- .../core/compiler/test/JSInteropTest.scala | 620 +++++++++++++++++- .../compiler/test/ScalaJSDefinedTest.scala | 8 +- .../scala/org/scalajs/core/ir/Hashers.scala | 14 +- .../scala/org/scalajs/core/ir/Infos.scala | 14 +- .../scala/org/scalajs/core/ir/Printers.scala | 7 + .../org/scalajs/core/ir/Serializers.scala | 75 ++- .../main/scala/org/scalajs/core/ir/Tags.scala | 6 + .../org/scalajs/core/ir/Transformers.scala | 9 +- .../org/scalajs/core/ir/Traversers.scala | 9 +- .../scala/org/scalajs/core/ir/Trees.scala | 13 +- .../scala/scalajs/js/annotation/JSName.scala | 5 +- project/BinaryIncompatibilities.scala | 4 + .../testsuite/jsinterop/JSSymbolTest.scala | 531 +++++++++++++++ .../closure/ClosureAstTransformer.scala | 6 + .../closure/ClosureLinkerBackend.scala | 9 +- .../core/tools/javascript/Printers.scala | 5 + .../scalajs/core/tools/javascript/Trees.scala | 4 + .../linker/backend/emitter/JSDesugaring.scala | 196 +++++- .../backend/emitter/ScalaJSClassEmitter.scala | 56 +- .../core/tools/linker/checker/IRChecker.scala | 46 +- .../tools/linker/frontend/BaseLinker.scala | 18 +- .../frontend/optimizer/OptimizerCore.scala | 18 +- 27 files changed, 1721 insertions(+), 182 deletions(-) create mode 100644 test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 0070e697df..b44275e1a8 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -46,7 +46,7 @@ abstract class GenJSCode extends plugins.PluginComponent import rootMirror._ import definitions._ import jsDefinitions._ - import jsInterop.{jsNameOf, compat068FullJSNameOf, jsNativeLoadSpecOf} + import jsInterop.{jsNameOf, compat068FullJSNameOf, jsNativeLoadSpecOf, JSName} import JSTreeExtractors._ import treeInfo.hasSynthCaseSymbol @@ -491,7 +491,7 @@ abstract class GenJSCode extends plugins.PluginComponent val constructorTrees = new ListBuffer[DefDef] val generatedMethods = new ListBuffer[js.MethodDef] - val dispatchMethodNames = new ListBuffer[String] + val dispatchMethodNames = new ListBuffer[JSName] def gen(tree: Tree): Unit = { tree match { @@ -621,15 +621,14 @@ abstract class GenJSCode extends plugins.PluginComponent assert(mdef.static, "Non-static method in SJS defined JS class") staticMembers += mdef - case js.StringLiteral(name) => + case js.StringLiteral("constructor") => assert(!mdef.static, "Exported static method") + assert(constructor.isEmpty, "two ctors in class") + constructor = Some(mdef) - if (name == "constructor") { - assert(constructor.isEmpty, "two ctors in class") - constructor = Some(mdef) - } else { - classMembers += mdef - } + case _ => + assert(!mdef.static, "Exported static method") + classMembers += mdef } case property: js.PropertyDef => @@ -667,8 +666,9 @@ abstract class GenJSCode extends plugins.PluginComponent case fdef: js.FieldDef => implicit val pos = fdef.pos val select = fdef.name match { - case lit: js.StringLiteral => js.JSBracketSelect(selfRef, lit) - case ident: js.Ident => js.JSDotSelect(selfRef, ident) + case ident: js.Ident => js.JSDotSelect(selfRef, ident) + case lit: js.StringLiteral => js.JSBracketSelect(selfRef, lit) + case js.ComputedName(tree, _) => js.JSBracketSelect(selfRef, tree) } js.Assign(select, jstpe.zeroOf(fdef.tpe)) @@ -896,7 +896,7 @@ abstract class GenJSCode extends plugins.PluginComponent } val name = - if (isExposed(f)) js.StringLiteral(jsNameOf(f)) + if (isExposed(f)) genPropertyName(jsNameOf(f)) else encodeFieldSym(f) val irTpe = { @@ -1844,7 +1844,7 @@ abstract class GenJSCode extends plugins.PluginComponent } else if (isScalaJSDefinedJSClass(sym.owner)) { val genQual = genExpr(qualifier) val boxed = if (isExposed(sym)) - js.JSBracketSelect(genQual, js.StringLiteral(jsNameOf(sym))) + js.JSBracketSelect(genQual, genExpr(jsNameOf(sym))) else js.JSDotSelect(genQual, encodeFieldSym(sym)) unboxFieldValue(boxed) @@ -1929,7 +1929,7 @@ abstract class GenJSCode extends plugins.PluginComponent if (isScalaJSDefinedJSClass(sym.owner)) { val genLhs = if (isExposed(sym)) - js.JSBracketSelect(genQual, js.StringLiteral(jsNameOf(sym))) + js.JSBracketSelect(genQual, genExpr(jsNameOf(sym))) else js.JSDotSelect(genQual, encodeFieldSym(sym)) js.Assign(genLhs, genBoxedRhs) @@ -4199,7 +4199,7 @@ abstract class GenJSCode extends plugins.PluginComponent js.JSFunctionApply(receiver, args) case _ => - def jsFunName = js.StringLiteral(jsNameOf(sym)) + def jsFunName: js.Tree = genExpr(jsNameOf(sym)) def genSuperReference(propName: js.Tree): js.Tree = { superIn.fold[js.Tree] { @@ -5144,6 +5144,40 @@ abstract class GenJSCode extends plugins.PluginComponent (patchedParams, patchedBody) } + // Methods to deal with JSName --------------------------------------------- + + def genPropertyName(name: JSName)(implicit pos: Position): js.PropertyName = { + name match { + case JSName.Literal(name) => js.StringLiteral(name) + + case JSName.Computed(sym) => + js.ComputedName(genComputedJSName(sym), encodeComputedNameIdentity(sym)) + } + } + + def genExpr(name: JSName)(implicit pos: Position): js.Tree = name match { + case JSName.Literal(name) => js.StringLiteral(name) + case JSName.Computed(sym) => genComputedJSName(sym) + } + + private def genComputedJSName(sym: Symbol)(implicit pos: Position): js.Tree = { + /* By construction (i.e. restriction in PrepJSInterop), we know that sym + * must be a static method. + * Therefore, at this point, we can invoke it by loading its owner and + * calling it. + */ + val module = genLoadModule(sym.owner) + + if (isRawJSType(sym.owner.tpe)) { + if (!isScalaJSDefinedJSClass(sym.owner) || isExposed(sym)) + genJSCallGeneric(sym, module, args = Nil, isStat = false) + else + genApplyJSClassMethod(module, sym, arguments = Nil) + } else { + genApplyMethod(module, sym, arguments = Nil) + } + } + // Utilities --------------------------------------------------------------- /** Generate a literal "zero" for the requested type */ diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index aceb98b063..667b77df53 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -27,7 +27,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => import jsAddons._ import definitions._ import jsDefinitions._ - import jsInterop.jsNameOf + import jsInterop.{jsNameOf, JSName} trait JSExportsPhase { this: JSCodePhase => @@ -54,7 +54,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } def genJSClassDispatchers(classSym: Symbol, - dispatchMethodsNames: List[String]): List[js.Tree] = { + dispatchMethodsNames: List[JSName]): List[js.Tree] = { dispatchMethodsNames .map(genJSClassDispatcher(classSym, _)) } @@ -91,7 +91,8 @@ trait GenJSExports extends SubComponent { self: GenJSCode => implicit val pos = ctors.head.pos val js.MethodDef(_, _, args, _, body) = - withNewLocalNameScope(genExportMethod(ctors, jsName, static = false)) + withNewLocalNameScope(genExportMethod(ctors, JSName.Literal(jsName), + static = false)) js.ConstructorExportDef(jsName, args, body.get) } @@ -225,8 +226,8 @@ trait GenJSExports extends SubComponent { self: GenJSCode => // Generate the export - val exportedMember = genMemberExportOrDispatcher(classSym, jsName, - isProp, alts, static = true) + val exportedMember = genMemberExportOrDispatcher(classSym, + JSName.Literal(jsName), isProp, alts, static = true) val exportDef = if (destination == ExportDestination.Static) exportedMember @@ -317,11 +318,11 @@ trait GenJSExports extends SubComponent { self: GenJSCode => s"Exported $kind $jsName conflicts with ${alts.head.fullName}") } - genMemberExportOrDispatcher(classSym, jsName, isProp, alts, - static = false) + genMemberExportOrDispatcher(classSym, JSName.Literal(jsName), isProp, + alts, static = false) } - private def genJSClassDispatcher(classSym: Symbol, name: String): js.Tree = { + private def genJSClassDispatcher(classSym: Symbol, name: JSName): js.Tree = { var alts: List[Symbol] = Nil for { sym <- classSym.info.members @@ -348,7 +349,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } } - def genMemberExportOrDispatcher(classSym: Symbol, jsName: String, + def genMemberExportOrDispatcher(classSym: Symbol, jsName: JSName, isProp: Boolean, alts: List[Symbol], static: Boolean): js.Tree = { withNewLocalNameScope { if (isProp) @@ -358,10 +359,12 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } } - def genJSConstructorExport(alts: List[Symbol]): js.MethodDef = - genExportMethod(alts.map(ExportedSymbol), "constructor", static = false) + def genJSConstructorExport(alts: List[Symbol]): js.MethodDef = { + genExportMethod(alts.map(ExportedSymbol), JSName.Literal("constructor"), + static = false) + } - private def genExportProperty(alts: List[Symbol], jsName: String, + private def genExportProperty(alts: List[Symbol], jsName: JSName, static: Boolean): js.PropertyDef = { assert(!alts.isEmpty) implicit val pos = alts.head.pos @@ -379,7 +382,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => s"Found more than one instance getter to export for name $jsName.") for (duplicate <- getter.tail) { reporter.error(duplicate.pos, - s"Duplicate static getter export with name '$jsName'") + s"Duplicate static getter export with name '${jsName.displayName}'") } } @@ -398,13 +401,13 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } } - js.PropertyDef(static, js.StringLiteral(jsName), getterBody, + js.PropertyDef(static, genPropertyName(jsName), getterBody, setterArgAndBody) } /** generates the exporter function (i.e. exporter for non-properties) for * a given name */ - private def genExportMethod(alts0: List[Exported], jsName: String, + private def genExportMethod(alts0: List[Exported], jsName: JSName, static: Boolean): js.MethodDef = { assert(alts0.nonEmpty, "need at least one alternative to generate exporter method") @@ -414,7 +417,10 @@ trait GenJSExports extends SubComponent { self: GenJSCode => val alts = { // toString() is always exported. We might need to add it here // to get correct overloading. - if (jsName == "toString" && alts0.forall(_.params.nonEmpty)) + val needsToString = + jsName == JSName.Literal("toString") && alts0.forall(_.params.nonEmpty) + + if (needsToString) ExportedSymbol(Object_toString) :: alts0 else alts0 @@ -526,7 +532,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } } - js.MethodDef(static, js.StringLiteral(jsName), + js.MethodDef(static, genPropertyName(jsName), formalArgs, jstpe.AnyType, Some(body))(OptimizerHints.empty, None) } @@ -698,7 +704,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => val cls = jstpe.ClassType(encodeClassFullName(currentClassSym)) val receiver = js.This()(jstpe.AnyType) - val nameString = js.StringLiteral(jsNameOf(sym)) + val nameString = genExpr(jsNameOf(sym)) if (jsInterop.isJSGetter(sym)) { assert(allArgs.isEmpty) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala index 5270fcc2e5..0c2936c0d7 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala @@ -239,6 +239,11 @@ trait JSEncoding extends SubComponent { self: GenJSCode => def needsModuleClassSuffix(sym: Symbol): Boolean = sym.isModuleClass && !foreignIsImplClass(sym) + def encodeComputedNameIdentity(sym: Symbol): String = { + assert(sym.owner.isModuleClass) + encodeClassFullName(sym.owner) + "__" + encodeMemberNameInternal(sym) + } + private def encodeMemberNameInternal(sym: Symbol): String = sym.name.toString.replace("_", "$und") diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala index 993c4ad85c..3362f3348d 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala @@ -69,6 +69,22 @@ trait JSGlobalAddons extends JSDefinitions val destination: ExportDestination } + sealed abstract class JSName { + def displayName: String + } + + object JSName { + // Not final because it causes annoying compile warnings + case class Literal(name: String) extends JSName { + def displayName: String = name + } + + // Not final because it causes annoying compile warnings + case class Computed(sym: Symbol) extends JSName { + def displayName: String = sym.fullName + } + } + def clearGlobalState(): Unit = { exportedSymbols.clear() jsNativeLoadSpecs.clear() @@ -173,11 +189,18 @@ trait JSGlobalAddons extends JSDefinitions * If it is not explicitly specified with an `@JSName` annotation, the * JS name is inferred from the Scala name. */ - def jsNameOf(sym: Symbol): String = { - sym.getAnnotation(JSNameAnnotation).flatMap(_.stringArg(0)) getOrElse { + def jsNameOf(sym: Symbol): JSName = { + sym.getAnnotation(JSNameAnnotation).fold[JSName] { val base = sym.unexpandedName.decoded.stripSuffix("_=") - if (!sym.isMethod) base.stripSuffix(" ") - else base + val name = + if (!sym.isMethod) base.stripSuffix(" ") + else base + JSName.Literal(name) + } { annotation => + annotation.args.head match { + case Literal(Constant(name: String)) => JSName.Literal(name) + case tree => JSName.Computed(tree.symbol) + } } } @@ -188,7 +211,10 @@ trait JSGlobalAddons extends JSDefinitions assert(sym.isModuleClass, s"compat068FullJSNameOf called for non-module-class symbol $sym") sym.getAnnotation(JSFullNameAnnotation).flatMap(_.stringArg(0)) getOrElse { - jsNameOf(sym) + /* In 0.6.8, computed names did not exist, so we are necessarily + * reading a Literal here. + */ + jsNameOf(sym).asInstanceOf[JSName.Literal].name } } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 230e3de89f..0d58391c6a 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -42,6 +42,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent import definitions._ import rootMirror._ import jsDefinitions._ + import jsInterop.JSName val phaseName: String = "jsinterop" override def description: String = "prepare ASTs for JavaScript interop" @@ -546,7 +547,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent } if (shouldCheckLiterals) { - checkJSNameLiteral(sym) + checkJSNameArgument(sym) checkJSImportLiteral(sym) } @@ -638,7 +639,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent def memberDefStringWithJSName(membSym: Symbol) = { memberDefString(membSym) + membSym.locationString + " with JSName '" + - jsInterop.jsNameOf(membSym) + '\'' + jsInterop.jsNameOf(membSym).displayName + '\'' } "A member of a JS class is overriding another member with a different JS name.\n\n" + memberDefStringWithJSName(low) + "\n" + @@ -685,15 +686,25 @@ abstract class PrepJSInterop extends plugins.PluginComponent for { annot <- sym.annotations annotSym = annot.symbol - if annotSym != JSNameAnnotation && JSNativeLoadingSpecAnnots.contains(annotSym) + if JSNativeLoadingSpecAnnots.contains(annotSym) } { - reporter.error(annot.pos, - "Classes and objects nested in a JS native object cannot have " + - s"an ${annotSym.nameString} annotation.") + if (annotSym != JSNameAnnotation) { + reporter.error(annot.pos, + "Classes and objects nested in a JS native object cannot " + + s"have an ${annotSym.nameString} annotation.") + } else if (annot.args.head.tpe.typeSymbol != StringClass) { + reporter.error(annot.pos, + "Implementation restriction: @JSName with a js.Symbol is not " + + "supported on nested native classes and objects") + } + } + + val jsName = jsInterop.jsNameOf(sym) match { + case JSName.Literal(jsName) => jsName + case JSName.Computed(_) => "" // compile error above } val ownerLoadSpec = jsInterop.jsNativeLoadSpecOf(sym.owner) - val jsName = jsInterop.jsNameOf(sym) ownerLoadSpec match { case JSNativeLoadSpec.Global(path) => JSNativeLoadSpec.Global(path :+ jsName) @@ -702,7 +713,13 @@ abstract class PrepJSInterop extends plugins.PluginComponent } } else { def globalFromName = { - val path = jsInterop.jsNameOf(sym).split('.').toList + val path = jsInterop.jsNameOf(sym) match { + case JSName.Literal(name) => + name.split('.').toList + case JSName.Computed(_) => + // this happens in erroneous cases that report a compile error + List("") + } JSNativeLoadSpec.Global(path) } @@ -874,7 +891,17 @@ abstract class PrepJSInterop extends plugins.PluginComponent } if (shouldCheckLiterals) - checkJSNameLiteral(sym) + checkJSNameArgument(sym) + + /* Check that there is at most one @JSName annotation. We used not to + * check this, so we can only warn. + */ + val allJSNameAnnots = sym.annotations.filter(_.symbol == JSNameAnnotation) + for (duplicate <- allJSNameAnnots.drop(1)) { // does not throw if empty + reporter.warning(duplicate.pos, + "A duplicate @JSName annotation is ignored. " + + "This will become an error in 1.0.0.") + } if (enclosingOwner is OwnerKind.JSNonNative) { // Private methods cannot be overloaded @@ -1060,13 +1087,23 @@ abstract class PrepJSInterop extends plugins.PluginComponent /** Checks that argument to @JSName on [[sym]] is a literal. * Reports an error on each annotation where this is not the case. */ - private def checkJSNameLiteral(sym: Symbol): Unit = { - for { - annot <- sym.getAnnotation(JSNameAnnotation) - if annot.stringArg(0).isEmpty - } { - reporter.error(annot.pos, - "The argument to JSName must be a literal string") + private def checkJSNameArgument(sym: Symbol): Unit = { + for (annot <- sym.getAnnotation(JSNameAnnotation)) { + val argTree = annot.args.head + if (argTree.tpe.typeSymbol == StringClass) { + if (!argTree.isInstanceOf[Literal]) { + reporter.error(argTree.pos, + "A string argument to JSName must be a literal string") + } + } else { + // We have a js.Symbol + val sym = argTree.symbol + if (!sym.isStatic || !sym.isStable) { + reporter.error(argTree.pos, + "A js.Symbol argument to JSName must be a static, stable identifier") + } + } + } } @@ -1244,6 +1281,17 @@ abstract class PrepJSInterop extends plugins.PluginComponent None case result :: duplicates => + val actualResult = { + if (result.args.headOption.forall(_.tpe.typeSymbol == StringClass)) { + Some(result) + } else { + reporter.error(result.pos, + "@JSName with a js.Symbol can only be used on members of " + + "JavaScript types") + None + } + } + for (annot <- duplicates) { if (annot.symbol == JSNameAnnotation && result.symbol == JSNameAnnotation) { @@ -1270,7 +1318,8 @@ abstract class PrepJSInterop extends plugins.PluginComponent "js.GlobalScope is treated as having @JSGlobalScope).") } } - Some(result) + + actualResult } } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index 7199a0b175..78059021f1 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -83,11 +83,22 @@ class JSInteropTest extends DirectTest with TestHelpers { @ScalaJSDefined @JSName("foo") $obj A extends js.Object + + object Sym { + val sym = js.Symbol() + } + + @ScalaJSDefined + @JSName(Sym.sym) + $obj B extends js.Object """ hasWarns s""" |newSource1.scala:6: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. | @JSName("foo") | ^ + |newSource1.scala:14: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. + | @JSName(Sym.sym) + | ^ """ } @@ -97,11 +108,21 @@ class JSInteropTest extends DirectTest with TestHelpers { s""" @JSName("foo") $obj A + + object Sym { + val sym = js.Symbol() + } + + @JSName(Sym.sym) + $obj B """ hasWarns s""" |newSource1.scala:5: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. | @JSName("foo") | ^ + |newSource1.scala:12: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. + | @JSName(Sym.sym) + | ^ """ } @@ -148,11 +169,22 @@ class JSInteropTest extends DirectTest with TestHelpers { @js.native @JSName("foo") trait A extends js.Object + + object Sym { + val sym = js.Symbol() + } + + @js.native + @JSName(Sym.sym) + trait B extends js.Object """ hasWarns s""" |newSource1.scala:6: warning: Traits should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. | @JSName("foo") | ^ + |newSource1.scala:14: warning: Traits should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. + | @JSName(Sym.sym) + | ^ """ } @@ -963,9 +995,9 @@ class JSInteropTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:14: error: The argument to JSName must be a literal string + |newSource1.scala:14: error: A string argument to JSName must be a literal string | @JSName(A.a) - | ^ + | ^ """ // #1664 @@ -985,12 +1017,55 @@ class JSInteropTest extends DirectTest with TestHelpers { class C extends js.Object """ hasErrors """ - |newSource1.scala:11: error: The argument to JSName must be a literal string + |newSource1.scala:11: error: A string argument to JSName must be a literal string | @JSName(A.a) - | ^ - |newSource1.scala:15: error: The argument to JSName must be a literal string + | ^ + |newSource1.scala:15: error: A string argument to JSName must be a literal string | @JSName(A.a) - | ^ + | ^ + """ + + } + + @Test + def noNonStaticStableJSNameSymbol: Unit = { + + """ + import js.annotation.JSName + + class A { + val a = js.Symbol("foo") + } + + @js.native + class B extends js.Object { + @JSName(js.Symbol()) + def foo: Int = js.native + @JSName(new A().a) + def bar: Int = js.native + } + + @ScalaJSDefined + class C extends js.Object { + @JSName(js.Symbol()) + def foo: Int = js.native + @JSName(new A().a) + def bar: Int = js.native + } + """ hasErrors + """ + |newSource1.scala:13: error: A js.Symbol argument to JSName must be a static, stable identifier + | @JSName(js.Symbol()) + | ^ + |newSource1.scala:15: error: A js.Symbol argument to JSName must be a static, stable identifier + | @JSName(new A().a) + | ^ + |newSource1.scala:21: error: A js.Symbol argument to JSName must be a static, stable identifier + | @JSName(js.Symbol()) + | ^ + |newSource1.scala:23: error: A js.Symbol argument to JSName must be a static, stable identifier + | @JSName(new A().a) + | ^ """ } @@ -1179,6 +1254,78 @@ class JSInteropTest extends DirectTest with TestHelpers { } + @Test + def noJSSymbolNameOnTopLevelClassesAndObjects: Unit = { + for { + kind <- Seq("class", "object") + } { + s""" + object Sym { + val sym = js.Symbol() + } + + @JSName(Sym.sym) + @js.native + $kind A extends js.Object + """ hasErrors + """ + |newSource1.scala:9: error: @JSName with a js.Symbol can only be used on members of JavaScript types + | @JSName(Sym.sym) + | ^ + """ + } + } + + @Test + def noJSSymbolNameOnNestedNativeClassesAndObjects: Unit = { + for { + kind <- Seq("class", "object") + } { + s""" + object Sym { + val sym = js.Symbol() + } + + @js.native + object Enclosing extends js.Object { + @JSName(Sym.sym) + @js.native + $kind A extends js.Object + } + """ hasErrors + """ + |newSource1.scala:11: error: Implementation restriction: @JSName with a js.Symbol is not supported on nested native classes and objects + | @JSName(Sym.sym) + | ^ + """ + } + } + + @Test + def warnOnDuplicateJSNameAnnotOnMember: Unit = { + for { + kind <- Seq("class", "object", "trait") + } { + """ + object A { + val a = js.Symbol() + } + + @js.native + class A extends js.Object { + @JSName(A.a) + @JSName("foo") + def a: Int = js.native + } + """ hasWarns + """ + |newSource1.scala:12: warning: A duplicate @JSName annotation is ignored. This will become an error in 1.0.0. + | @JSName("foo") + | ^ + """ + } + } + @Test def scalaJSDefinedJSNameOverrideWarnings: Unit = { """ @@ -1540,6 +1687,467 @@ class JSInteropTest extends DirectTest with TestHelpers { """ } + @Test + def scalaJSDefinedJSNameWithSymbolOverrideWarnings: Unit = { + """ + object Syms { + val sym1 = js.Symbol() + } + + @ScalaJSDefined + trait A extends js.Object { + @JSName(Syms.sym1) + def bar(): Int + } + @ScalaJSDefined + class B extends A { + @JSName(Syms.sym1) + override def bar() = 1 + } + """.hasNoWarns + + """ + object Syms { + val sym1 = js.Symbol() + } + + @ScalaJSDefined + abstract class A extends js.Object { + @JSName(Syms.sym1) + def bar(): Int + } + @ScalaJSDefined + class B extends A { + @JSName(Syms.sym1) + override def bar() = 1 + } + """.hasNoWarns + + """ + object Syms { + val sym1 = js.Symbol() + val sym2 = js.Symbol() + } + + @ScalaJSDefined + abstract class A extends js.Object { + @JSName(Syms.sym1) + def bar(): Int + } + @ScalaJSDefined + class B extends A { + @JSName(Syms.sym2) + override def bar() = 1 + } + """ hasWarns + """ + |newSource1.scala:18: warning: A member of a JS class is overriding another member with a different JS name. + | + |override def bar(): Int in class B with JSName 'Syms.sym2' + | is conflicting with + |def bar(): Int in class A with JSName 'Syms.sym1' + | + | override def bar() = 1 + | ^ + """ + + """ + object Syms { + val sym1 = js.Symbol() + } + + @ScalaJSDefined + abstract class A extends js.Object { + @JSName(Syms.sym1) + def bar(): Int + } + @ScalaJSDefined + class B extends A { + @JSName("baz") + override def bar() = 1 + } + """ hasWarns + """ + |newSource1.scala:17: warning: A member of a JS class is overriding another member with a different JS name. + | + |override def bar(): Int in class B with JSName 'baz' + | is conflicting with + |def bar(): Int in class A with JSName 'Syms.sym1' + | + | override def bar() = 1 + | ^ + """ + + """ + object Syms { + val sym1 = js.Symbol() + } + + @ScalaJSDefined + abstract class A extends js.Object { + @JSName("foo") + def bar(): Int + } + @ScalaJSDefined + class B extends A { + @JSName(Syms.sym1) + override def bar() = 1 + } + """ hasWarns + """ + |newSource1.scala:17: warning: A member of a JS class is overriding another member with a different JS name. + | + |override def bar(): Int in class B with JSName 'Syms.sym1' + | is conflicting with + |def bar(): Int in class A with JSName 'foo' + | + | override def bar() = 1 + | ^ + """ + + """ + object Syms { + val sym1 = js.Symbol() + } + + @ScalaJSDefined + abstract class A extends js.Object { + @JSName(Syms.sym1) + def bar(): Int + } + @ScalaJSDefined + class B extends A { + override def bar() = 1 + } + """ hasWarns + """ + |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + | + |override def bar(): Int in class B with JSName 'bar' + | is conflicting with + |def bar(): Int in class A with JSName 'Syms.sym1' + | + | override def bar() = 1 + | ^ + """ + + """ + object Syms { + val sym1 = js.Symbol() + } + + @ScalaJSDefined + abstract class A extends js.Object { + @JSName(Syms.sym1) + def bar(): Object + } + @ScalaJSDefined + abstract class B extends A { + override def bar(): String + } + @ScalaJSDefined + class C extends B { + override def bar() = "1" + } + """ hasWarns + """ + |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + | + |override def bar(): String in class B with JSName 'bar' + | is conflicting with + |def bar(): Object in class A with JSName 'Syms.sym1' + | + | override def bar(): String + | ^ + |newSource1.scala:20: warning: A member of a JS class is overriding another member with a different JS name. + | + |override def bar(): String in class C with JSName 'bar' + | is conflicting with + |def bar(): Object in class A with JSName 'Syms.sym1' + | + | override def bar() = "1" + | ^ + """ + + """ + object Syms { + val sym1 = js.Symbol() + } + + @ScalaJSDefined + abstract class A extends js.Object { + def bar(): Object + } + @ScalaJSDefined + abstract class B extends A { + @JSName(Syms.sym1) + override def bar(): String + } + @ScalaJSDefined + class C extends B { + override def bar() = "1" + } + """ hasWarns + """ + |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + | + |override def bar(): String in class B with JSName 'Syms.sym1' + | is conflicting with + |def bar(): Object in class A with JSName 'bar' + | + | override def bar(): String + | ^ + |newSource1.scala:20: warning: A member of a JS class is overriding another member with a different JS name. + | + |override def bar(): String in class C with JSName 'bar' + | is conflicting with + |override def bar(): String in class B with JSName 'Syms.sym1' + | + | override def bar() = "1" + | ^ + """ + + """ + object Syms { + val sym1 = js.Symbol() + } + + @ScalaJSDefined + class A extends js.Object { + def foo: Int = 5 + } + @ScalaJSDefined + trait B extends A { + @JSName(Syms.sym1) + def foo: Int + } + @ScalaJSDefined + class C extends B + """ hasWarns + """ + |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + | + |def foo: Int in class A with JSName 'foo' + | is conflicting with + |def foo: Int in trait B with JSName 'Syms.sym1' + | + | def foo: Int + | ^ + """ + + """ + object Syms { + val sym1 = js.Symbol() + } + + @ScalaJSDefined + class A extends js.Object { + @JSName(Syms.sym1) + def foo: Int = 5 + } + @ScalaJSDefined + trait B extends A { + def foo: Int + } + @ScalaJSDefined + class C extends B + """ hasWarns + """ + |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + | + |def foo: Int in class A with JSName 'Syms.sym1' + | is conflicting with + |def foo: Int in trait B with JSName 'foo' + | + | def foo: Int + | ^ + """ + + """ + object Syms { + val sym1 = js.Symbol() + } + + @ScalaJSDefined + class A[T] extends js.Object { + @JSName(Syms.sym1) + def foo(x: T): T = x + } + @ScalaJSDefined + class B extends A[Int] { + override def foo(x: Int): Int = x + } + """ hasWarns + """ + |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + | + |override def foo(x: Int): Int in class B with JSName 'foo' + | is conflicting with + |def foo(x: Int): Int in class A with JSName 'Syms.sym1' + | + | override def foo(x: Int): Int = x + | ^ + """ + + """ + object Syms { + val sym1 = js.Symbol() + } + + @ScalaJSDefined + trait A[T] extends js.Object { + @JSName(Syms.sym1) + def foo(x: T): T + } + @ScalaJSDefined + class B extends A[Int] { + override def foo(x: Int): Int = x + } + """ hasWarns + """ + |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + | + |override def foo(x: Int): Int in class B with JSName 'foo' + | is conflicting with + |def foo(x: Int): Int in trait A with JSName 'Syms.sym1' + | + | override def foo(x: Int): Int = x + | ^ + """ + + """ + object Syms { + val sym1 = js.Symbol() + } + + @ScalaJSDefined + class A[T] extends js.Object { + @JSName(Syms.sym1) + def foo(x: T): T = x + } + @ScalaJSDefined + trait B extends A[Int] { + def foo(x: Int): Int + } + @ScalaJSDefined + class C extends B { + override def foo(x: Int): Int = x + } + """ hasWarns + """ + |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + | + |def foo(x: Int): Int in class A with JSName 'Syms.sym1' + | is conflicting with + |def foo(x: Int): Int in trait B with JSName 'foo' + | + | def foo(x: Int): Int + | ^ + |newSource1.scala:20: warning: A member of a JS class is overriding another member with a different JS name. + | + |override def foo(x: Int): Int in class C with JSName 'foo' + | is conflicting with + |def foo(x: Int): Int in class A with JSName 'Syms.sym1' + | + | override def foo(x: Int): Int = x + | ^ + """ + + """ + object Syms { + val sym1 = js.Symbol() + } + + @ScalaJSDefined + class A[T] extends js.Object { + def foo(x: T): T = x + } + @ScalaJSDefined + trait B extends A[Int] { + @JSName(Syms.sym1) + def foo(x: Int): Int + } + @ScalaJSDefined + class C extends B { + override def foo(x: Int): Int = x + } + """ hasWarns + """ + |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + | + |def foo(x: Int): Int in class A with JSName 'foo' + | is conflicting with + |def foo(x: Int): Int in trait B with JSName 'Syms.sym1' + | + | def foo(x: Int): Int + | ^ + |newSource1.scala:20: warning: A member of a JS class is overriding another member with a different JS name. + | + |override def foo(x: Int): Int in class C with JSName 'foo' + | is conflicting with + |def foo(x: Int): Int in trait B with JSName 'Syms.sym1' + | + | override def foo(x: Int): Int = x + | ^ + """ + + """ + object Syms { + val sym1 = js.Symbol() + } + + @ScalaJSDefined + trait A extends js.Object { + def foo: Int + } + @ScalaJSDefined + trait B extends js.Object { + @JSName(Syms.sym1) + def foo: Int + } + @ScalaJSDefined + trait C extends A with B + """ hasWarns + """ + |newSource1.scala:19: warning: A member of a JS class is overriding another member with a different JS name. + | + |def foo: Int in trait B with JSName 'Syms.sym1' + | is conflicting with + |def foo: Int in trait A with JSName 'foo' + | + | trait C extends A with B + | ^ + """ + + """ + object Syms { + val sym1 = js.Symbol() + } + + @ScalaJSDefined + trait A extends js.Object { + def foo: Int + } + @ScalaJSDefined + trait B extends js.Object { + @JSName(Syms.sym1) + def foo: Int + } + @ScalaJSDefined + abstract class C extends A with B + """ hasWarns + """ + |newSource1.scala:19: warning: A member of a JS class is overriding another member with a different JS name. + | + |def foo: Int in trait B with JSName 'Syms.sym1' + | is conflicting with + |def foo: Int in trait A with JSName 'foo' + | + | abstract class C extends A with B + | ^ + """ + } + @Test def noDefaultConstructorArgsIfModuleIsJSNative: Unit = { """ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala index 14242f48b7..00de69e8e1 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala @@ -457,9 +457,9 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:12: error: The argument to JSName must be a literal string + |newSource1.scala:12: error: A string argument to JSName must be a literal string | @JSName(A.a) - | ^ + | ^ """ """ @@ -477,9 +477,9 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:12: error: The argument to JSName must be a literal string + |newSource1.scala:12: error: A string argument to JSName must be a literal string | @JSName(A.a) - | ^ + | ^ """ } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala index 8090db885e..ee52ad8e6f 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala @@ -492,8 +492,18 @@ object Hashers { def mixOptIdent(optIdent: Option[Ident]): Unit = optIdent.foreach(mixIdent) def mixPropertyName(name: PropertyName): Unit = name match { - case name: Ident => mixIdent(name) - case name: StringLiteral => mixTree(name) + case name: Ident => + mixTag(TagPropertyNameIdent) + mixIdent(name) + + case name: StringLiteral => + mixTag(TagPropertyNameStringLiteral) + mixTree(name) + + case ComputedName(tree, logicalName) => + mixTag(TagPropertyNameComputedName) + mixTree(tree) + mixString(logicalName) } def mixPos(pos: Position): Unit = { diff --git a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala index cc443e9029..2b8689b961 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala @@ -376,7 +376,13 @@ object Infos { .setEncodedName(methodDef.name.encodedName) .setIsStatic(methodDef.static) .setIsAbstract(methodDef.body.isEmpty) - .setIsExported(methodDef.name.isInstanceOf[StringLiteral]) + .setIsExported(!methodDef.name.isInstanceOf[Ident]) + + methodDef.name match { + case ComputedName(tree, _) => + traverse(tree) + case _ => + } methodDef.body.foreach(traverse) @@ -389,6 +395,12 @@ object Infos { .setIsStatic(propertyDef.static) .setIsExported(true) + propertyDef.name match { + case ComputedName(tree, _) => + traverse(tree) + case _ => + } + propertyDef.getterBody.foreach(traverse) propertyDef.setterArgAndBody foreach { case (_, body) => traverse(body) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index 24c30be6bc..1c9ce7fe76 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -933,6 +933,13 @@ object Printers { private final def print(propName: PropertyName): Unit = propName match { case lit: StringLiteral => print(lit: Tree) case ident: Ident => print(ident) + + case ComputedName(tree, index) => + print("[") + print(tree) + print("](") + print(index) + print(")") } private def print(spec: JSNativeLoadSpec): Unit = { diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index 06ac5090ae..52b37fd691 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -409,20 +409,11 @@ object Serializers { writeInt(tree.optimizerHints.bits) case FieldDef(static, name, ftpe, mutable) => - /* TODO Simply use `writePropertyName` when we can break binary - * compatibility. - */ - name match { - case name: Ident => - writeByte(TagFieldDef) - writeBoolean(static) - writeIdent(name) - case name: StringLiteral => - writeByte(TagStringLitFieldDef) - writeBoolean(static) - writeTree(name) - } - writeType(ftpe); writeBoolean(mutable) + writeByte(TagFieldDef) + writeBoolean(static) + writePropertyName(name) + writeType(ftpe) + writeBoolean(mutable) case methodDef: MethodDef => val MethodDef(static, name, args, resultType, body) = methodDef @@ -556,11 +547,19 @@ object Serializers { def writeReferenceType(tpe: ReferenceType): Unit = writeType(tpe.asInstanceOf[Type]) - def writePropertyName(name: PropertyName): Unit = { - name match { - case name: Ident => buffer.writeBoolean(true); writeIdent(name) - case name: StringLiteral => buffer.writeBoolean(false); writeTree(name) - } + def writePropertyName(name: PropertyName): Unit = name match { + case name: Ident => + buffer.writeByte(TagPropertyNameIdent) + writeIdent(name) + + case name: StringLiteral => + buffer.writeByte(TagPropertyNameStringLiteral) + writeTree(name) + + case ComputedName(tree, index) => + buffer.writeByte(TagPropertyNameComputedName) + writeTree(tree) + writeString(index) } def writePosition(pos: Position): Unit = { @@ -841,19 +840,14 @@ object Serializers { optimizerHints) case TagFieldDef => - val static = - if (useHacks0614) false - else readBoolean() - FieldDef(static, readIdent(), readType(), readBoolean()) - case TagStringLitFieldDef => - /* TODO Merge this into TagFieldDef and use readPropertyName() - * when we can break binary compatibility. - */ - val static = - if (useHacks0614) false - else readBoolean() - FieldDef(static, readTree().asInstanceOf[StringLiteral], readType(), - readBoolean()) + if (useHacks0614) + FieldDef(static = false, readIdent(), readType(), readBoolean()) + else + FieldDef(readBoolean(), readPropertyName(), readType(), readBoolean()) + + case TagStringLitFieldDef if useHacks0614 => + FieldDef(static = false, readTree().asInstanceOf[StringLiteral], + readType(), readBoolean()) case TagMethodDef => val optHash = readOptHash() @@ -980,8 +974,21 @@ object Serializers { readType().asInstanceOf[ReferenceType] def readPropertyName(): PropertyName = { - if (input.readBoolean()) readIdent() - else readTree().asInstanceOf[StringLiteral] + if (useHacks0614) { + if (input.readBoolean()) readIdent() + else readTree().asInstanceOf[StringLiteral] + } else { + input.readByte() match { + case TagPropertyNameIdent => + readIdent() + + case TagPropertyNameStringLiteral => + readTree().asInstanceOf[StringLiteral] + + case TagPropertyNameComputedName => + ComputedName(readTree(), readString()) + } + } } def readPosition(): Position = { diff --git a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala index bdf373d2da..f627595124 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala @@ -126,6 +126,12 @@ private[ir] object Tags { final val TagRecordType = TagArrayType + 1 final val TagNoType = TagRecordType + 1 + // Tags for PropertyNames + + final val TagPropertyNameIdent = 1 + final val TagPropertyNameStringLiteral = TagPropertyNameIdent + 1 + final val TagPropertyNameComputedName = TagPropertyNameStringLiteral + 1 + // Tags for JS native loading specs final val TagJSNativeLoadSpecNone = 0 diff --git a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala index dc9af73415..fc3896745e 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala @@ -176,7 +176,14 @@ object Transformers { case JSObjectConstr(fields) => JSObjectConstr(fields map { - case (name, value) => (name, transformExpr(value)) + case (name, value) => + val newName = name match { + case ComputedName(tree, logicalName) => + ComputedName(transformExpr(tree), logicalName) + case _ => + name + } + (newName, transformExpr(value)) }) // Atomic expressions diff --git a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala index fe9783d4d9..e8c8009894 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala @@ -179,7 +179,14 @@ object Traversers { items foreach traverse case JSObjectConstr(fields) => - fields foreach { f => traverse(f._2) } + for ((key, value) <- fields) { + key match { + case ComputedName(tree, _) => + traverse(tree) + case _ => + } + traverse(value) + } // Atomic expressions diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index d68d4cbe11..771e82bd00 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -31,8 +31,13 @@ object Trees { // Identifiers and properties sealed trait PropertyName { - /** Encoded name of this PropertyName within its owner's scope. */ + /** Encoded name of this PropertyName within its owner's scope. + * + * For [[ComputedName]]s, the value of `encodedName` cannot be relied on + * beyond equality tests, and the fact that it starts with `"__computed_"`. + */ def encodedName: String + def pos: Position } @@ -81,6 +86,12 @@ object Trees { "transient", "volatile" ) + case class ComputedName(tree: Tree, logicalName: String) extends PropertyName { + requireValidIdent(logicalName) + def pos: Position = tree.pos + override def encodedName: String = "__computed_" + logicalName + } + // Definitions case class VarDef(name: Ident, vtpe: Type, mutable: Boolean, rhs: Tree)( diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSName.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSName.scala index 627cef0307..925c522a05 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSName.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSName.scala @@ -17,4 +17,7 @@ import scala.annotation.meta._ * @see [[http://www.scala-js.org/doc/calling-javascript.html Calling JavaScript from Scala.js]] */ @field @getter @setter -class JSName(name: String) extends scala.annotation.StaticAnnotation +class JSName private () extends scala.annotation.StaticAnnotation { + def this(name: String) = this() + def this(symbol: scala.scalajs.js.Symbol) = this() +} diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index c581e1b71d..3e8bd89116 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -78,10 +78,14 @@ object BinaryIncompatibilities { "org.scalajs.core.tools.linker.backend.closure.ClosureAstTransformer.transformString"), // private[emitter], not an issue + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genAddToPrototype"), ProblemFilters.exclude[MissingMethodProblem]( "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genClass"), ProblemFilters.exclude[MissingMethodProblem]( "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genClassDef"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genPropertyName"), ProblemFilters.exclude[DirectMissingMethodProblem]( "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genTopLevelExportDef"), ProblemFilters.exclude[DirectMissingMethodProblem]( diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala new file mode 100644 index 0000000000..ac8ed052e8 --- /dev/null +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala @@ -0,0 +1,531 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.jsinterop + +import scala.scalajs.js +import scala.scalajs.js.annotation._ + +import org.junit.Assert._ +import org.junit.Assume._ +import org.junit.{Test, BeforeClass} + +class JSSymbolTest { + import JSSymbolTest._ + import SJSDefinedWithSyms._ + + @Test def native_with_defs_that_are_properties(): Unit = { + val obj = mkObject(sym1 -> 1) + + assertEquals(1, obj.asInstanceOf[PropDefClass].internalDef) + assertEquals(1, obj.asInstanceOf[PropDefTrait].internalDef) + assertEquals(1, selectSymbol(obj, sym1)) + } + + @Test def sjsdefined_with_defs_that_are_properties(): Unit = { + val obj = new SJSDefinedPropDef + assertEquals(456, obj.internalDef) + + val asTrait: PropDefTrait = obj + assertEquals(456, asTrait.internalDef) + + assertEquals(456, selectSymbol(obj, sym1)) + } + + @Test def native_with_vals(): Unit = { + val obj = mkObject(sym1 -> "hi") + + assertEquals("hi", obj.asInstanceOf[PropValClass].internalVal) + assertEquals("hi", obj.asInstanceOf[PropValTrait].internalVal) + assertEquals("hi", selectSymbol(obj, sym1)) + } + + @Test def sjsdefined_with_vals(): Unit = { + val obj = new SJSDefinedPropVal + assertEquals("hello", obj.internalVal) + + val asTrait: PropValTrait = obj + assertEquals("hello", asTrait.internalVal) + + assertEquals("hello", selectSymbol(obj, sym1)) + } + + @Test def native_with_vars(): Unit = { + val obj0 = mkObject(sym1 -> 0.1).asInstanceOf[PropVarClass] + assertEquals(0.1, obj0.internalVar) + obj0.internalVar = 0.2 + assertEquals(0.2, obj0.internalVar) + + val obj1 = mkObject(sym1 -> 8.0).asInstanceOf[PropVarTrait] + assertEquals(8.0, obj1.internalVar) + obj1.internalVar = 8.2 + assertEquals(8.2, obj1.internalVar) + + val obj2 = mkObject(sym1 -> 8.0) + assertEquals(8.0, selectSymbol(obj2, sym1)) + updateSymbol(obj2, sym1, 8.2) + assertEquals(8.2, selectSymbol(obj2, sym1)) + } + + @Test def sjsdefined_with_vars(): Unit = { + val obj0 = new SJSDefinedPropVar + assertEquals(1511.1989, obj0.internalVar) + obj0.internalVar = 0.2 + assertEquals(0.2, obj0.internalVar) + + val obj1: PropVarTrait = new SJSDefinedPropVar + assertEquals(1511.1989, obj1.internalVar) + obj1.internalVar = 8.2 + assertEquals(8.2, obj1.internalVar) + + val obj2 = new SJSDefinedPropVar + assertEquals(1511.1989, selectSymbol(obj2, sym1)) + updateSymbol(obj2, sym1, 8.2) + assertEquals(8.2, selectSymbol(obj2, sym1)) + } + + @Test def sjsdefined_with_inner_object(): Unit = { + val obj0 = new SJSDefinedInnerObject + assertEquals("object", js.typeOf(obj0.innerObject.asInstanceOf[js.Any])) + assertEquals("SJSDefinedInnerObject.innerObject", obj0.innerObject.toString()) + + val obj1: InnerObjectTrait = new SJSDefinedInnerObject + assertEquals("object", js.typeOf(obj1.innerObject.asInstanceOf[js.Any])) + assertEquals("SJSDefinedInnerObject.innerObject", obj1.innerObject.toString()) + + assertEquals("object", + js.typeOf(selectSymbol(obj1, sym1).asInstanceOf[js.Any])) + assertEquals("SJSDefinedInnerObject.innerObject", + selectSymbol(obj1, sym1).toString()) + } + + @Test def native_with_methods(): Unit = { + val obj = mkObject( + sym1 -> ((x: Int) => x + 2), + sym2 -> ((x: String) => "Hello " + x) + ) + + assertEquals(4, obj.asInstanceOf[MethodClass].foo(2)) + assertEquals("Hello World", obj.asInstanceOf[MethodClass].bar("World")) + + assertEquals(6, obj.asInstanceOf[MethodTrait].foo(4)) + assertEquals("Hello Moon", obj.asInstanceOf[MethodTrait].bar("Moon")) + + assertEquals(6, callSymbol(obj, sym1)(4)) + assertEquals("Hello Moon", callSymbol(obj, sym2)("Moon")) + } + + @Test def sjsdefined_with_methods(): Unit = { + val obj = new SJSDefinedMethod + assertEquals(4, obj.foo(2)) + assertEquals("Hello World", obj.bar("World")) + + val asTrait: MethodTrait = obj + assertEquals(6, asTrait.foo(4)) + assertEquals("Hello Moon", asTrait.bar("Moon")) + + assertEquals(6, callSymbol(obj, sym1)(4)) + assertEquals("Hello Moon", callSymbol(obj, sym2)("Moon")) + } + + @Test def native_with_overloaded_methods(): Unit = { + val obj = mkObject( + sym1 -> ((x: Int) => x + 3), + sym2 -> ((x: String) => "Hello " + x) + ) + + assertEquals(5, obj.asInstanceOf[OverloadedMethodClass].foo(2)) + assertEquals("Hello World", obj.asInstanceOf[OverloadedMethodClass].foo("World")) + + assertEquals(6, obj.asInstanceOf[OverloadedMethodTrait].foo(3)) + assertEquals("Hello Moon", obj.asInstanceOf[OverloadedMethodTrait].foo("Moon")) + + assertEquals(6, callSymbol(obj, sym1)(3)) + assertEquals("Hello Moon", callSymbol(obj, sym2)("Moon")) + } + + @Test def sjsdefined_with_overloaded_methods(): Unit = { + val obj = new SJSDefinedOverloadedMethod + assertEquals(5, obj.foo(2)) + assertEquals("Hello World", obj.foo("World")) + + val asTrait: OverloadedMethodTrait = obj + assertEquals(6, asTrait.foo(3)) + assertEquals("Hello Moon", asTrait.foo("Moon")) + + assertEquals(6, callSymbol(obj, sym1)(3)) + assertEquals("Hello Moon", callSymbol(obj, sym2)("Moon")) + } + + @Test def native_with_overloaded_runtime_dispatch_methods(): Unit = { + val obj = mkObject( + sym1 -> { (x: Any) => + x match { + case x: Int => x + 3 + case x: String => "Hello " + x + } + } + ) + + assertEquals(5, + obj.asInstanceOf[OverloadedRuntimeDispatchMethodClass].foo(2)) + assertEquals("Hello World", + obj.asInstanceOf[OverloadedRuntimeDispatchMethodClass].foo("World")) + + assertEquals(6, + obj.asInstanceOf[OverloadedRuntimeDispatchMethodTrait].foo(3)) + assertEquals("Hello Moon", + obj.asInstanceOf[OverloadedRuntimeDispatchMethodTrait].foo("Moon")) + + assertEquals(6, callSymbol(obj, sym1)(3)) + assertEquals("Hello Moon", callSymbol(obj, sym1)("Moon")) + } + + @Test def sjsdefined_with_overloaded_runtime_dispatch_methods(): Unit = { + val obj = new SJSDefinedOverloadedRuntimeDispatchMethod + assertEquals(5, obj.foo(2)) + assertEquals("Hello World", obj.foo("World")) + + val asTrait: OverloadedRuntimeDispatchMethodTrait = obj + assertEquals(6, asTrait.foo(3)) + assertEquals("Hello Moon", asTrait.foo("Moon")) + + assertEquals(6, callSymbol(obj, sym1)(3)) + assertEquals("Hello Moon", callSymbol(obj, sym1)("Moon")) + } + + @Test def native_with_symbols_in_sjsdefined_object(): Unit = { + val obj = mkObject( + sym3 -> ((x: Int) => x + 2) + ) + + assertEquals(65, + obj.asInstanceOf[ClassWithSymsInSJSDefinedObject].symInSJSDefinedObject(63)) + assertEquals(65, + obj.asInstanceOf[TraitWithSymsInSJSDefinedObject].symInSJSDefinedObject(63)) + + assertEquals(65, callSymbol(obj, sym3)(63)) + } + + @Test def sjsdefined_with_symbols_in_sjsdefined_object(): Unit = { + val obj = new SJSDefinedWithSymsInSJSDefinedObject + assertEquals(65, obj.symInSJSDefinedObject(63)) + + val asTrait: TraitWithSymsInSJSDefinedObject = obj + assertEquals(65, asTrait.symInSJSDefinedObject(63)) + + assertEquals(65, callSymbol(obj, sym3)(63)) + } + + @Test def native_iterable(): Unit = { + val obj = mkObject( + js.Symbol.iterator -> (() => singletonIterator(653)) + ) + + assertArrayEquals(Array(653), + iterableToArray(obj.asInstanceOf[ClassJSIterable[Int]]).toArray) + assertArrayEquals(Array(653), + iterableToArray(obj.asInstanceOf[JSIterable[Int]]).toArray) + + val content = Array.newBuilder[Int] + iterateIterable(obj.asInstanceOf[JSIterable[Int]])(content += _) + assertArrayEquals(Array(653), content.result()) + } + + @Test def sjsdefined_iterable(): Unit = { + val obj = new SJSDefinedIterable + + assertArrayEquals(Array(532), iterableToArray(obj).toArray) + + val content = Array.newBuilder[Int] + iterateIterable(obj)(content += _) + assertArrayEquals(Array(532), content.result()) + } +} + +object JSSymbolTest { + + @BeforeClass + def beforeClass(): Unit = { + assumeTrue("Assuming JavaScript symbols are supported", + org.scalajs.testsuite.utils.Platform.areJSSymbolsSupported) + } + + /* These need to be lazy vals, so that they do not blow up if there is no + * symbol support at all. + */ + lazy val sym1 = js.Symbol() + lazy val sym2 = js.Symbol() + + @ScalaJSDefined + object SJSDefinedWithSyms extends js.Object { + val sym3 = js.Symbol() + } + + import SJSDefinedWithSyms._ + + def mkObject(members: (js.Symbol, js.Any)*): js.Object = { + val obj = (new js.Object).asInstanceOf[ObjectCreator] + for ((sym, member) <- members) { + obj(sym) = member + } + obj + } + + private def selectSymbol(obj: js.Any, sym: js.Symbol): Any = + obj.asInstanceOf[SymDynamic].selectSymbol(sym) + + private def updateSymbol(obj: js.Any, sym: js.Symbol, value: Any): Unit = + obj.asInstanceOf[SymDynamic].updateSymbol(sym, value) + + private def callSymbol(obj: js.Any, sym: js.Symbol)(args: js.Any*): Any = + obj.asInstanceOf[SymDynamic].callSymbol(sym)(args: _*) + + @js.native + private trait SymDynamic extends js.Any { + @JSBracketAccess + def selectSymbol(sym: js.Symbol): Any = js.native + + @JSBracketAccess + def updateSymbol(sym: js.Symbol, value: Any): Unit = js.native + + @JSBracketCall + def callSymbol(sym: js.Symbol)(args: js.Any*): Any = js.native + } + + def singletonIterator(singleton: Any): js.Dynamic = { + var first = true + js.Dynamic.literal( + next = { () => + if (first) { + first = false + js.Dynamic.literal(value = singleton.asInstanceOf[js.Any], + done = false) + } else { + js.Dynamic.literal(value = (), done = true) + } + } + ) + } + + def iterableToArray[A](iterable: JSIterable[A]): js.Array[A] = + js.constructorOf[js.Array[_]].from(iterable).asInstanceOf[js.Array[A]] + + def iterateIterable[A](iterable: JSIterable[A])(f: A => Any): Unit = { + val iterator = iterable.iterator() + def loop(): Unit = { + val entry = iterator.next() + // 2.10 didn't like the use of DynamicImplicits on the following line + if (!entry.done.asInstanceOf[Boolean]) { + f(entry.value.asInstanceOf[A]) + loop() + } + } + loop() + } + + @js.native + private trait ObjectCreator extends js.Object { + @JSBracketAccess + def update(s: js.Symbol, v: js.Any): Unit = js.native + } + + @ScalaJSDefined + trait PropDefTrait extends js.Any { + @JSName(sym1) + def internalDef: Int + } + + @js.native + @JSName("dummy") + class PropDefClass extends js.Any { + @JSName(sym1) + def internalDef: Int = js.native + } + + @ScalaJSDefined + class SJSDefinedPropDef extends js.Object with PropDefTrait { + @JSName(sym1) + def internalDef: Int = 456 + } + + @ScalaJSDefined + trait PropValTrait extends js.Any { + @JSName(sym1) + val internalVal: String + } + + @js.native + @JSName("dummy") + class PropValClass extends js.Any { + @JSName(sym1) + val internalVal: String = js.native + } + + @ScalaJSDefined + class SJSDefinedPropVal extends js.Object with PropValTrait { + @JSName(sym1) + val internalVal: String = "hello" + } + + @ScalaJSDefined + trait PropVarTrait extends js.Any { + @JSName(sym1) + var internalVar: Double + } + + @js.native + @JSName("dummy") + class PropVarClass extends js.Any { + @JSName(sym1) + var internalVar: Double = js.native + } + + @ScalaJSDefined + class SJSDefinedPropVar extends js.Object with PropVarTrait { + @JSName(sym1) + var internalVar: Double = 1511.1989 + } + + @ScalaJSDefined + trait InnerObjectTrait extends js.Any { + @JSName(sym1) + val innerObject: AnyRef + } + + @ScalaJSDefined + class SJSDefinedInnerObject extends js.Object with InnerObjectTrait { + @JSName(sym1) + object innerObject { // scalastyle:ignore + override def toString(): String = "SJSDefinedInnerObject.innerObject" + } + } + + @ScalaJSDefined + trait MethodTrait extends js.Any { + @JSName(sym1) + def foo(x: Int): Int + + @JSName(sym2) + def bar(x: String): String + } + + @js.native + @JSName("dummy") + class MethodClass extends js.Any { + @JSName(sym1) + def foo(x: Int): Int = js.native + + @JSName(sym2) + def bar(x: String): String = js.native + } + + @ScalaJSDefined + class SJSDefinedMethod extends js.Object with MethodTrait { + @JSName(sym1) + def foo(x: Int): Int = x + 2 + + @JSName(sym2) + def bar(x: String): String = "Hello " + x + } + + @ScalaJSDefined + trait OverloadedMethodTrait extends js.Any { + @JSName(sym1) + def foo(x: Int): Int + + @JSName(sym2) + def foo(x: String): String + } + + @js.native + @JSName("dummy") + class OverloadedMethodClass extends js.Any { + @JSName(sym1) + def foo(x: Int): Int = js.native + + @JSName(sym2) + def foo(x: String): String = js.native + } + + @ScalaJSDefined + class SJSDefinedOverloadedMethod extends js.Object with OverloadedMethodTrait { + @JSName(sym1) + def foo(x: Int): Int = x + 3 + + @JSName(sym2) + def foo(x: String): String = "Hello " + x + } + + @ScalaJSDefined + trait OverloadedRuntimeDispatchMethodTrait extends js.Any { + @JSName(sym1) + def foo(x: Int): Int + + @JSName(sym1) + def foo(x: String): String + } + + @js.native + @JSName("dummy") + class OverloadedRuntimeDispatchMethodClass extends js.Any { + @JSName(sym1) + def foo(x: Int): Int = js.native + + @JSName(sym1) + def foo(x: String): String = js.native + } + + @ScalaJSDefined + class SJSDefinedOverloadedRuntimeDispatchMethod + extends js.Object with OverloadedRuntimeDispatchMethodTrait { + @JSName(sym1) + def foo(x: Int): Int = x + 3 + + @JSName(sym1) + def foo(x: String): String = "Hello " + x + } + + @ScalaJSDefined + trait TraitWithSymsInSJSDefinedObject extends js.Object { + @JSName(sym3) + def symInSJSDefinedObject(x: Int): Int + } + + @js.native + @JSName("dummy") + class ClassWithSymsInSJSDefinedObject extends js.Object { + @JSName(sym3) + def symInSJSDefinedObject(x: Int): Int = js.native + } + + @ScalaJSDefined + class SJSDefinedWithSymsInSJSDefinedObject + extends TraitWithSymsInSJSDefinedObject { + @JSName(sym3) + def symInSJSDefinedObject(x: Int): Int = x + 2 + } + + @ScalaJSDefined + trait JSIterable[+A] extends js.Object { + @JSName(js.Symbol.iterator) + def iterator(): js.Dynamic + } + + @js.native + @JSName("dummy") + class ClassJSIterable[+A] extends JSIterable[A] { + @JSName(js.Symbol.iterator) + def iterator(): js.Dynamic = js.native + } + + @ScalaJSDefined + class SJSDefinedIterable extends JSIterable[Int] { + @JSName(js.Symbol.iterator) + def iterator(): js.Dynamic = singletonIterator(532) + } +} diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala index 21501289b6..e3e44ea032 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala @@ -246,6 +246,12 @@ private[closure] class ClosureAstTransformer(relativizeBaseURI: Option[URI]) { val node = Node.newString(Token.STRING_KEY, name) node.setQuotedString() node + + case ComputedName(tree) => + throw new AssertionError( + "The Closure AST compiler received a ComputedName, which it " + + "cannot translate because it always emits ES 5.1 code. " + + "Position: " + parentPos) } setNodePosition(node, pName.pos orElse parentPos) diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala index c74b7f085b..b9f97b2b4f 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala @@ -107,15 +107,16 @@ final class ClosureLinkerBackend( private def makeExternsForExports(linkingUnit: LinkingUnit): VirtualJSFile = { import org.scalajs.core.ir.Trees._ - def exportName(tree: Tree): String = (tree: @unchecked) match { - case MethodDef(_, StringLiteral(name), _, _, _) => name - case PropertyDef(_, StringLiteral(name), _, _) => name + def exportName(tree: Tree): Option[String] = (tree: @unchecked) match { + case MethodDef(_, StringLiteral(name), _, _, _) => Some(name) + case PropertyDef(_, StringLiteral(name), _, _) => Some(name) + case _ => None } val exportedPropertyNames = for { classDef <- linkingUnit.classDefs member <- classDef.exportedMembers - name = exportName(member.tree) + name <- exportName(member.tree) if isValidIdentifier(name) } yield { name diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala index 30451e3539..9aa744982e 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala @@ -561,6 +561,11 @@ object Printers { private final def print(propName: PropertyName): Unit = propName match { case lit: StringLiteral => print(lit: Tree) case ident: Ident => print(ident) + + case ComputedName(tree) => + print("[") + print(tree) + print("]") } protected def print(s: String): Unit = diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala index 5ab5cd5e09..6451d79ab1 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala @@ -50,6 +50,10 @@ object Trees { new Ident(name, Some(name)) } + case class ComputedName(tree: Tree) extends PropertyName { + def pos = tree.pos + } + // Definitions sealed trait LocalDef extends Tree { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala index 5a9ce69554..d483f702ea 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala @@ -225,6 +225,15 @@ private[emitter] class JSDesugaring(semantics: Semantics, new JSDesugar().desugarToFunction(params, body, isStat, env) } + /** Desugars parameters and body to a JS function. + */ + private[emitter] def desugarToFunction( + params: List[ParamDef], + body: Tree, isStat: Boolean)( + implicit globalKnowledge: GlobalKnowledge, pos: Position): js.Function = { + new JSDesugar().desugarToFunction(params, body, isStat, Env.empty) + } + /** Desugars a statement or an expression. */ private[emitter] def desugarTree( enclosingClassName: Option[String], @@ -557,37 +566,68 @@ private[emitter] class JSDesugaring(semantics: Semantics, * setter. * Instead, we must force the creation of a field on the object, * irrespective of the presence of a getter/setter in the - * prototype chain. This is why we use `defineProperties`: + * prototype chain. This is why we use `defineProperty`: * - * Object.defineProperties(this, { "field": { + * Object.defineProperty(this, "field", { * "configurable": true, * "enumerable": true, * "writable": true, * "value": 0 - * } }); + * }); * * which has all the same semantics as the assignment, except * it disregards the prototype chain. + * + * If the field is an identifier, we cannot directly translate + * it to a string for use in `defineProperty`, because Closure + * would fail to rename it. In that case, we use + * `defineProperties` instead, as follows: + * + * Object.defineProperties(this, { + * field: { + * "configurable": true, + * "enumerable": true, + * "writable": true, + * "value": 0 + * } + * }); */ - val defineProperties = { - genIdentBracketSelect(genIdentBracketSelect( - envField("g"), - "Object"), - "defineProperties") - } - val transformedName = name match { - case name: Ident => transformIdent(name) - case StringLiteral(s) => js.StringLiteral(s) + + def makeObjectMethodApply(methodName: String, + args: List[js.Tree]): js.Tree = { + js.Apply( + genIdentBracketSelect(genIdentBracketSelect( + envField("g"), + "Object"), + methodName), + args) } + val descriptor = js.ObjectConstr(List( js.StringLiteral("configurable") -> js.BooleanLiteral(true), js.StringLiteral("enumerable") -> js.BooleanLiteral(true), js.StringLiteral("writable") -> js.BooleanLiteral(true), js.StringLiteral("value") -> genZeroOf(ftpe) )) - val descriptors = js.ObjectConstr(List( - transformedName -> descriptor)) - js.Apply(defineProperties, List(js.This(), descriptors)) + + unnestPropertyName(name) { (newName, env0) => + implicit val env = env0 + newName match { + case newName: Ident => + val descriptors = js.ObjectConstr(List( + transformIdent(newName) -> descriptor)) + makeObjectMethodApply("defineProperties", + List(js.This(), descriptors)) + + case newName: StringLiteral => + makeObjectMethodApply("defineProperty", + List(js.This(), transformExpr(newName), descriptor)) + + case ComputedName(nameTree, _) => + makeObjectMethodApply("defineProperty", + List(js.This(), transformExpr(nameTree), descriptor)) + } + } } js.Block(superCtorCall :: fieldDefs) @@ -770,10 +810,23 @@ private[emitter] class JSDesugaring(semantics: Semantics, ArrayValue(tpe, recs(elems)) case JSArrayConstr(items) if !containsAnySpread(items) => JSArrayConstr(recs(items)) + case arg @ JSObjectConstr(items) if !doesObjectConstrRequireDesugaring(arg) => - val newValues = recs(items.map(_._2)) - JSObjectConstr(items.map(_._1) zip newValues) + // We need to properly interleave keys and values here + val newItems = items.foldRight[List[(PropertyName, Tree)]](Nil) { + case ((key, value), acc) => + val newValue = rec(value) // value first! + val newKey = key match { + case _:Ident | _:StringLiteral => + key + case ComputedName(keyExpr, logicalName) => + ComputedName(rec(keyExpr), logicalName) + } + (newKey, newValue) :: acc + } + JSObjectConstr(newItems) + case Closure(captureParams, params, body, captureValues) => Closure(captureParams, params, body, recs(captureValues)) @@ -857,6 +910,53 @@ private[emitter] class JSDesugaring(semantics: Semantics, } } + /** Unnest for the fields of a `JSObjectConstr`. */ + def unnestJSObjectConstrFields(fields: List[(PropertyName, Tree)])( + makeStat: (List[(PropertyName, Tree)], Env) => js.Tree)( + implicit env: Env): js.Tree = { + + // Collect all the trees that need unnesting, in evaluation order + val trees = fields.flatMap { + case (ComputedName(tree, _), value) => List(tree, value) + case (_, value) => List(value) + } + + unnest(trees) { (newTrees, env) => + val newTreesIterator = newTrees.iterator + + val newFields = fields.map { + case (propName, value) => + val newPropName = propName match { + case ComputedName(_, logicalName) => + val newTree = newTreesIterator.next() + ComputedName(newTree, logicalName) + case _:StringLiteral | _:Ident => + propName + } + val newValue = newTreesIterator.next() + (newPropName, newValue) + } + + assert(!newTreesIterator.hasNext) + makeStat(newFields, env) + } + } + + /** Unnest for a `PropertyName`. */ + def unnestPropertyName(arg: PropertyName)( + makeStat: (PropertyName, Env) => js.Tree)( + implicit env: Env): js.Tree = { + + arg match { + case _:StringLiteral | _:Ident => + makeStat(arg, env) + case ComputedName(tree, logicalName) => + unnest(tree) { (newTree, env) => + makeStat(ComputedName(newTree, logicalName), env) + } + } + } + /** Common implementation for the functions below. * A pure expression can be moved around or executed twice, because it * will always produce the same result and never have side-effects. @@ -905,8 +1005,14 @@ private[emitter] class JSDesugaring(semantics: Semantics, case JSArrayConstr(items) => allowUnpure && (items forall test) case tree @ JSObjectConstr(items) => - allowUnpure && (items forall (item => test(item._2))) && - !doesObjectConstrRequireDesugaring(tree) + allowUnpure && + !doesObjectConstrRequireDesugaring(tree) && + items.forall { item => + test(item._2) && (item._1 match { + case ComputedName(tree, _) => test(tree) + case _ => true + }) + } case Closure(captureParams, params, body, captureValues) => allowUnpure && (captureValues forall test) @@ -1478,9 +1584,12 @@ private[emitter] class JSDesugaring(semantics: Semantics, val assignFields = fields.foldRight((Set.empty[String], List.empty[Tree])) { case ((prop, value), (namesSeen, statsAcc)) => implicit val pos = value.pos - val name = prop.encodedName + val nameForDupes = prop match { + case _:StringLiteral | _:Ident => Some(prop.encodedName) + case _: ComputedName => None + } val stat = prop match { - case _ if namesSeen.contains(name) => + case _ if nameForDupes.exists(namesSeen) => /* Important: do not emit the assignment, otherwise * Closure recreates a literal with the duplicate field! */ @@ -1489,17 +1598,17 @@ private[emitter] class JSDesugaring(semantics: Semantics, Assign(JSDotSelect(objVarDef.ref, prop), value) case prop: StringLiteral => Assign(JSBracketSelect(objVarDef.ref, prop), value) + case ComputedName(tree, _) => + Assign(JSBracketSelect(objVarDef.ref, tree), value) } - (namesSeen + name, stat :: statsAcc) + (namesSeen ++ nameForDupes, stat :: statsAcc) }._2 redo { Block(objVarDef :: assignFields ::: objVarDef.ref :: Nil) } } else { - val names = fields map (_._1) - val items = fields map (_._2) - unnest(items) { (newItems, env) => - redo(JSObjectConstr(names.zip(newItems)))(env) + unnestJSObjectConstrFields(fields) { (newFields, env) => + redo(JSObjectConstr(newFields))(env) } } @@ -1574,8 +1683,21 @@ private[emitter] class JSDesugaring(semantics: Semantics, /** Tests whether a [[JSObjectConstr]] must be desugared. */ private def doesObjectConstrRequireDesugaring( tree: JSObjectConstr): Boolean = { - val names = tree.fields.map(_._1.encodedName) - names.toSet.size != names.size // i.e., there is at least one duplicate + def computedNamesAllowed: Boolean = + outputMode == OutputMode.ECMAScript6 + + def hasComputedName: Boolean = + tree.fields.exists(_._1.isInstanceOf[ComputedName]) + + def hasDuplicateNonComputedProp: Boolean = { + val names = tree.fields.collect { + case (StringLiteral(name), _) => name + case (Ident(name, _), _) => name + } + names.toSet.size != names.size + } + + (!computedNamesAllowed && hasComputedName) || hasDuplicateNonComputedProp } /** Evaluates `expr` and stores the result in a temp, then evaluates the @@ -1965,11 +2087,8 @@ private[emitter] class JSDesugaring(semantics: Semantics, js.ArrayConstr(items map transformExpr) case JSObjectConstr(fields) => - js.ObjectConstr(fields map { - case (name: Ident, value) => - (transformIdent(name), transformExpr(value)) - case (StringLiteral(name), value) => - (js.StringLiteral(name), transformExpr(value)) + js.ObjectConstr(fields map { case (name, value) => + (transformPropertyName(name), transformExpr(value)) }) case JSLinkingInfo() => @@ -2084,6 +2203,16 @@ private[emitter] class JSDesugaring(semantics: Semantics, "isInfinite__Z" -> "isInfinite" ) + def transformPropertyName(pName: PropertyName)( + implicit env: Env): js.PropertyName = { + implicit val pos = pName.pos + pName match { + case name: Ident => transformIdent(name) + case StringLiteral(s) => js.StringLiteral(s) + case ComputedName(tree, _) => js.ComputedName(transformExpr(tree)) + } + } + def genClassDataOf(cls: ReferenceType)(implicit pos: Position): js.Tree = { cls match { case ClassType(className) => @@ -2429,6 +2558,7 @@ private[emitter] class JSDesugaring(semantics: Semantics, item match { case item: js.Ident => js.DotSelect(qual, item) case item: js.StringLiteral => genBracketSelect(qual, item) + case js.ComputedName(tree) => genBracketSelect(qual, tree) } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala index 9f6af003ea..bfb1b4c874 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala @@ -378,10 +378,11 @@ private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, "s", className + "__" + methodName, origName, methodFun) - case methodName: StringLiteral => + case methodName => outputMode match { case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => - genAddToObject(encodeClassVar(className), methodName, methodFun) + genAddToObject(className, encodeClassVar(className), methodName, + methodFun) case OutputMode.ECMAScript6 => js.MethodDef(static = true, genPropertyName(methodName), @@ -451,14 +452,15 @@ private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, else classVar.prototype // property name - val name = property.name match { - case StringLiteral(value) => - js.StringLiteral(value) - case id: Ident => + val name = genPropertyName(property.name) match { + case value: js.StringLiteral => value + case js.ComputedName(tree) => tree + + case id: js.Ident => // We need to work around the closure compiler. Call propertyName to // get a string representation of the optimized name genCallHelper("propertyName", - js.ObjectConstr(transformIdent(id) -> js.IntLiteral(0) :: Nil)) + js.ObjectConstr(id -> js.IntLiteral(0) :: Nil)) } // optional getter definition @@ -508,36 +510,48 @@ private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, } /** Generate `classVar.prototype.name = value` */ - def genAddToPrototype(className: String, name: js.PropertyName, - value: js.Tree)(implicit pos: Position): js.Tree = { + def genAddToPrototype(className: String, name: js.PropertyName, value: js.Tree)( + implicit globalKnowledge: GlobalKnowledge, pos: Position): js.Tree = { genAddToObject(encodeClassVar(className).prototype, name, value) } /** Generate `classVar.prototype.name = value` */ - def genAddToPrototype(className: String, name: PropertyName, - value: js.Tree)(implicit pos: Position): js.Tree = { + def genAddToPrototype(className: String, name: PropertyName, value: js.Tree)( + implicit globalKnowledge: GlobalKnowledge, pos: Position): js.Tree = { genAddToPrototype(className, genPropertyName(name), value) } /** Generate `obj.name = value` */ def genAddToObject(obj: js.Tree, name: js.PropertyName, value: js.Tree)(implicit pos: Position): js.Tree = { - val select = name match { - case name: js.Ident => js.DotSelect(obj, name) - case name: js.StringLiteral => genBracketSelect(obj, name) - } - js.Assign(select, value) + js.Assign(genPropSelect(obj, name), value) } /** Generate `obj.name = value` */ - def genAddToObject(obj: js.Tree, name: PropertyName, - value: js.Tree)(implicit pos: Position): js.Tree = { + def genAddToObject(className: String, obj: js.Tree, name: PropertyName, + value: js.Tree)( + implicit globalKnowledge: GlobalKnowledge, pos: Position): js.Tree = { genAddToObject(obj, genPropertyName(name), value) } - def genPropertyName(name: PropertyName): js.PropertyName = name match { - case ident: Ident => transformIdent(ident) - case StringLiteral(value) => js.StringLiteral(value)(name.pos) + def genPropertyName(name: PropertyName)( + implicit globalKnowledge: GlobalKnowledge): js.PropertyName = { + name match { + case ident: Ident => transformIdent(ident) + case StringLiteral(value) => js.StringLiteral(value)(name.pos) + + case ComputedName(tree, _) => + implicit val pos = name.pos + val fun = desugarToFunction(params = Nil, body = tree, isStat = false) + val nameTree = fun match { + case js.Function(Nil, js.Return(expr)) => + // no need for an IIFE, we can just use `expr` directly + expr + case _ => + js.Apply(fun, Nil) + } + js.ComputedName(nameTree) + } } private[tools] def needInstanceTests(tree: LinkedClass): Boolean = { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 5a8ab77987..6c1fd53297 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -141,13 +141,11 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { member.tree match { case m: MethodDef => - assert(m.name.isInstanceOf[StringLiteral], - "Exported method must have StringLiteral as name") checkExportedMethodDef(m, classDef, isTopLevel = false) + case p: PropertyDef => - assert(p.name.isInstanceOf[StringLiteral], - "Exported property must have StringLiteral as name") checkExportedPropertyDef(p, classDef) + // Anything else is illegal case _ => reportError("Illegal exported class member of type " + @@ -227,6 +225,10 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { case _: StringLiteral => if (!classDef.kind.isJSClass) reportError(s"FieldDef '$name' cannot have a string literal name") + case ComputedName(tree, _) => + if (!classDef.kind.isJSClass) + reportError(s"FieldDef '$name' cannot have a computed name") + typecheckExpect(tree, Env.empty, AnyType) } if (tpe == NoType) @@ -287,7 +289,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { private def checkExportedMethodDef(methodDef: MethodDef, classDef: LinkedClass, isTopLevel: Boolean): Unit = withPerMethodState { - val MethodDef(static, StringLiteral(name), params, resultType, body) = methodDef + val MethodDef(static, pName, params, resultType, body) = methodDef implicit val ctx = ErrorContext(methodDef) if (!isTopLevel && !classDef.kind.isAnyScalaJSDefinedClass) { @@ -301,8 +303,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { if (isTopLevel && !static) reportError("Top level export must be static") - if (name.contains("__") && name != Definitions.ClassExportsName) - reportError("Exported method def name cannot contain __") + checkExportedPropertyName(pName, classDef, isTopLevel) for (ParamDef(name, tpe, _, _) <- params) { if (tpe == NoType) @@ -319,7 +320,14 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { } } - if (classDef.kind.isJSClass && name == "constructor" && !static) { + def isJSConstructor = { + !static && (pName match { + case StringLiteral("constructor") => true + case _ => false + }) + } + + if (classDef.kind.isJSClass && isJSConstructor) { checkJSClassConstructor(methodDef, classDef) } else { if (resultType != AnyType) { @@ -390,7 +398,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { private def checkExportedPropertyDef(propDef: PropertyDef, classDef: LinkedClass): Unit = withPerMethodState { - val PropertyDef(static, _, getterBody, setterArgAndBody) = propDef + val PropertyDef(static, pName, getterBody, setterArgAndBody) = propDef implicit val ctx = ErrorContext(propDef) if (!classDef.kind.isAnyScalaJSDefinedClass) { @@ -398,6 +406,8 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { return } + checkExportedPropertyName(pName, classDef, isTopLevel = false) + val thisType = if (static) NoType else if (classDef.kind.isJSClass) AnyType @@ -420,6 +430,24 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { } } + private def checkExportedPropertyName(pName: PropertyName, + classDef: LinkedClass, isTopLevel: Boolean)( + implicit ctx: ErrorContext): Unit = { + pName match { + case _: Ident => + throw new AssertionError("Exported method may not have Ident as name") + + case StringLiteral(name) => + if (name.contains("__") && name != Definitions.ClassExportsName) + reportError("Exported method def name cannot contain __") + + case ComputedName(tree, _) => + if (isTopLevel || !classDef.kind.isJSClass) + reportError("Only JS classes may contain members with computed names") + typecheckExpect(tree, Env.empty, AnyType) + } + } + private def checkConstructorExportDef(ctorDef: ConstructorExportDef, classDef: LinkedClass): Unit = withPerMethodState { val ConstructorExportDef(_, params, body) = ctorDef diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index 348880172a..6f1c894aff 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -221,10 +221,10 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions // Static methods case m: MethodDef if m.static => if (analyzerInfo.staticMethodInfos(m.name.encodedName).isReachable) { - if (m.name.isInstanceOf[StringLiteral]) - exportedMembers += linkedMethod(m) - else + if (m.name.isInstanceOf[Ident]) staticMethods += linkedMethod(m) + else + exportedMembers += linkedMethod(m) } // Fields @@ -235,12 +235,14 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions // Normal methods case m: MethodDef => if (analyzerInfo.methodInfos(m.name.encodedName).isReachable) { - if (m.name.isInstanceOf[StringLiteral]) + if (m.name.isInstanceOf[Ident]) { + if (m.body.isDefined) + memberMethods += linkedMethod(m) + else + abstractMethods += linkedMethod(m) + } else { exportedMembers += linkedMethod(m) - else if (m.body.isDefined) - memberMethods += linkedMethod(m) - else - abstractMethods += linkedMethod(m) + } } case m: PropertyDef => diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index ca0c109546..bb1f570e56 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -655,7 +655,23 @@ private[optimizer] abstract class OptimizerCore( case JSObjectConstr(fields) => JSObjectConstr(fields map { - case (name, value) => (name, transformExpr(value)) + case (name, value) => + /* #2773 - The ascription `: PropertyName` side-steps the issue by + * pushing down an appropriate expected type. + * TODO We need to minimize and fix the root cause. + */ + val newName: PropertyName = name match { + case _:StringLiteral | _:Ident => + name + case ComputedName(nameExpr, logicalName) => + transformExpr(nameExpr) match { + case newName: StringLiteral => + newName + case newName => + ComputedName(newName, logicalName) + } + } + (newName, transformExpr(value)) }) // Atomic expressions From 470f6cfec083ff904073fe10267f14439267cfb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 14 Feb 2017 20:21:51 +0100 Subject: [PATCH 0131/2665] Use `JSObjectConstr` more often for `js.Dynamic.literal`. Now that `JSObjectConstr` admits `ComputedName`s for keys, there are more patterns of calls of `js.Dynamic.literal` that can be emitted as `JSObjectConstr`. This commit leverages that. --- .../org/scalajs/core/compiler/GenJSCode.scala | 62 ++++++++++--------- .../core/compiler/JSTreeExtractors.scala | 55 +++++++--------- 2 files changed, 57 insertions(+), 60 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index b44275e1a8..11303ae5de 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -3908,9 +3908,10 @@ abstract class GenJSCode extends plugins.PluginComponent * {name1: arg1, name2: arg2, ... } */ - def warnIfDuplicatedKey(pairs: List[(js.StringLiteral, js.Tree)]): Unit = { - val allKeys = pairs.collect { case (js.StringLiteral(keyName), _) => keyName } - val keyCounts = allKeys.distinct.map(key => key -> allKeys.count(_ == key)) + def warnIfDuplicatedKey(keys: List[js.StringLiteral]): Unit = { + val keyNames = keys.map(_.value) + val keyCounts = + keyNames.distinct.map(key => key -> keyNames.count(_ == key)) val duplicateKeyCounts = keyCounts.filter(1 < _._2) if (duplicateKeyCounts.nonEmpty) { reporter.warning(pos, @@ -3923,12 +3924,21 @@ abstract class GenJSCode extends plugins.PluginComponent } } + def keyToPropName(key: js.Tree, index: Int): js.PropertyName = key match { + case key: js.StringLiteral => key + case _ => js.ComputedName(key, "local" + index) + } + // Extract first arg to future proof against varargs extractFirstArg(genArgs) match { - // case js.Dynamic.literal("name1" -> ..., "name2" -> ...) - case (js.StringLiteral("apply"), jse.LitNamed(pairs)) => - warnIfDuplicatedKey(pairs) - js.JSObjectConstr(pairs) + // case js.Dynamic.literal("name1" -> ..., nameExpr2 -> ...) + case (js.StringLiteral("apply"), jse.Tuple2List(pairs)) => + warnIfDuplicatedKey(pairs.collect { + case (key: js.StringLiteral, _) => key + }) + js.JSObjectConstr(pairs.zipWithIndex.map { + case ((key, value), index) => (keyToPropName(key, index), value) + }) /* case js.Dynamic.literal(x: _*) * Even though scalac does not support this notation, it is still @@ -3950,31 +3960,27 @@ abstract class GenJSCode extends plugins.PluginComponent // case js.Dynamic.literal(x, y) case (js.StringLiteral("apply"), tups) => // Check for duplicated explicit keys - val pairs = jse.LitNamedExtractor.extractFrom(tups) - warnIfDuplicatedKey(pairs) - - // Create tmp variable - val resIdent = freshLocalIdent("obj") - val resVarDef = js.VarDef(resIdent, jstpe.AnyType, mutable = false, - js.JSObjectConstr(Nil)) - val res = resVarDef.ref + warnIfDuplicatedKey(jse.extractLiteralKeysFrom(tups)) - // Assign fields + // Evaluate all tuples first val tuple2Type = encodeClassType(TupleClass(2)) - val assigns = tups flatMap { - // special case for literals - case jse.Tuple2(name, value) => - js.Assign(js.JSBracketSelect(res, name), value) :: Nil - case tupExpr => - val tupIdent = freshLocalIdent("tup") - val tup = js.VarRef(tupIdent)(tuple2Type) - js.VarDef(tupIdent, tuple2Type, mutable = false, tupExpr) :: - js.Assign(js.JSBracketSelect(res, - genApplyMethod(tup, js.Ident("$$und1__O"), Nil, jstpe.AnyType)), - genApplyMethod(tup, js.Ident("$$und2__O"), Nil, jstpe.AnyType)) :: Nil + val evalTuples = tups.map { tup => + js.VarDef(freshLocalIdent("tup"), tuple2Type, mutable = false, + tup)(tup.pos) } - js.Block(resVarDef +: assigns :+ res: _*) + // Build the resulting object + val result = js.JSObjectConstr(evalTuples.zipWithIndex.map { + case (evalTuple, index) => + val tupRef = evalTuple.ref + val key = genApplyMethod(tupRef, js.Ident("$$und1__O"), Nil, + jstpe.AnyType) + val value = genApplyMethod(tupRef, js.Ident("$$und2__O"), Nil, + jstpe.AnyType) + keyToPropName(key, index) -> value + }) + + js.Block(evalTuples :+ result) // case where another method is called case (js.StringLiteral(name), _) if name != "apply" => diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSTreeExtractors.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSTreeExtractors.scala index cd84ba2382..4e70ff5ce0 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSTreeExtractors.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSTreeExtractors.scala @@ -22,45 +22,36 @@ object JSTreeExtractors { }) } - /** - * A partially literally named sequence (like in a call to applyDynamicNamed) - * Where some parameters are expected to be literally named. + /** Extracts the literal strings in "key" position of a sequence of Tuple2. * - * Example (Scala): method(("name1", x), (a, y), z) + * Non-Tuple2 constructors are silently ignored, as well as non-literal + * keys. */ - object LitNamedExtractor { - def extractFrom(exprs: List[Tree]): List[(StringLiteral, Tree)] = { - // Note that with 'failIfNonLit = false' - // genNameLitExtract will never return None - genNamedLitExtract(exprs, Nil, false).getOrElse(Nil) - } - - @tailrec - private[jse] final def genNamedLitExtract( - exprs: List[Tree], - acc: List[(StringLiteral, Tree)], - failIfNonLit: Boolean - ): Option[List[(StringLiteral, Tree)]] = exprs match { - case Tuple2(name: StringLiteral, value) :: xs => - genNamedLitExtract(xs, (name, value) :: acc, failIfNonLit) - case _ :: xs => - if (failIfNonLit) - None - else - genNamedLitExtract(xs, acc, failIfNonLit) - case Nil => Some(acc.reverse) + def extractLiteralKeysFrom(exprs: List[Tree]): List[StringLiteral] = { + exprs.collect { + case Tuple2(key: StringLiteral, _) => key } } - /** - * A literally named sequence (like in a call to applyDynamicNamed) - * Where all parameters are expected to be literally named. + /** A list of Tuple2, for example used as a list of key/value pairs + * (like in a call to applyDynamicNamed). * - * Example (Scala): method(("name1", x), ("name2", y)) + * Examples (Scala): + * {{{ + * method(("name1", x), ("name2", y)) + * method("name1" -> x, "name2" -> y) + * method(nameExpr1 -> x, (nameExpr2, y)) + * }}} */ - object LitNamed { - def unapply(exprs: List[Tree]): Option[List[(StringLiteral, Tree)]] = { - LitNamedExtractor.genNamedLitExtract(exprs, Nil, true) + object Tuple2List { + def unapply(exprs: List[Tree]): Option[List[(Tree, Tree)]] = { + val tuples = exprs.collect { + case Tuple2(key, value) => (key, value) + } + if (tuples.size == exprs.size) + Some(tuples) + else + None } } From 6f234d2da85c73819d1fc6a6bba5664830fa26c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 20 Feb 2017 16:56:13 +0100 Subject: [PATCH 0132/2665] Deprecate top-level @JSExport, and @JSExportDescendent{Classes,Objects}. Top-level `@JSExport`s (on classes and objects) should be replaced by `@JSExportTopLevel`. For objects, this is a change of semantics, as the object itself is exported, rather than a 0-arg function returning the object. It is still possible to achieve the same behavior as before by explicitly exporting a 0-arg method returning the object with `@JSExportTopLevel`, so we do not lose any expressiveness. `@JSExportDescendentClasses` and `@JSExportDescendentObjects` should not have any use cases left, now that reflective instantiation and module loading is properly supported through `@EnableReflectiveInstantiation` and `scala.scalajs.reflect.Reflect`. --- .../scalajs/core/compiler/PrepJSExports.scala | 55 +++++++++ .../scalajs/core/compiler/PrepJSInterop.scala | 3 + .../core/compiler/ScalaJSOptions.scala | 3 + .../scalajs/core/compiler/ScalaJSPlugin.scala | 22 +++- .../test/JSExportDeprecationsTest.scala | 105 ++++++++++++++++++ .../core/compiler/test/JSExportTest.scala | 2 +- .../compiler/test/ScalaJSDefinedTest.scala | 3 + .../core/compiler/test/util/DirectTest.scala | 19 +++- examples/reversi/Reversi.scala | 4 +- project/Build.scala | 14 ++- .../testinterface/internal/InfoSender.scala | 4 +- .../testinterface/internal/Master.scala | 4 +- .../testinterface/internal/Slave.scala | 4 +- .../core/tools/test/js/QuickLinker.scala | 4 +- .../core/tools/test/js/TestRunner.scala | 4 +- 15 files changed, 227 insertions(+), 23 deletions(-) create mode 100644 compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportDeprecationsTest.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala index 6cd7438cfa..543a951a20 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala @@ -31,6 +31,11 @@ trait PrepJSExports { this: PrepJSInterop => assert(!isNamed || destination == ExportDestination.Normal) } + private final val SuppressExportDeprecationsMsg = { + "\n (you can suppress this warning in 0.6.x by passing the option " + + "`-P:scalajs:suppressExportDeprecations` to scalac)" + } + /** Generate the exporter for the given DefDef * or ValDef (abstract val in class, val in trait or lazy val; * these don't get DefDefs until the fields phase) @@ -165,6 +170,37 @@ trait PrepJSExports { this: PrepJSInterop => } } + /** Deprecate `@JSExportDescendentClasses` and `@JSExportDescendentObjects`. + * + * We do this only on the annotated symbol (not in descendants), which is + * why this test is a bit separate from everything else. + * Ideally we would simply `@deprecate` the annotations, but that would not + * allow us to suppress the deprecations. + */ + def checkDeprecationOfJSExportDescendentClassesObjects(sym: Symbol): Unit = { + if (!scalaJSOpts.suppressExportDeprecations) { + for (annot <- sym.annotations) { + if (annot.symbol == JSExportDescendentClassesAnnotation) { + reporter.warning(annot.pos, + "@JSExportDescendentClasses is deprecated and will be removed " + + "in 1.0.0. For use cases where you want to simulate "+ + "\"reflective\" instantiation, use @EnableReflectiveInstantion " + + "and scala.scalajs.reflect.Reflect.lookupInstantiatableClass " + + "instead." + + SuppressExportDeprecationsMsg) + } else if (annot.symbol == JSExportDescendentObjectsAnnotation) { + reporter.warning(annot.pos, + "@JSExportDescendentObjects is deprecated and will be removed " + + "in 1.0.0. For use cases where you want to simulate " + + "\"reflective\" loading, use @EnableReflectiveInstantion and " + + "scala.scalajs.reflect.Reflect.lookupLoadableModuleClass " + + "instead." + + SuppressExportDeprecationsMsg) + } + } + } + } + private def createFactoryInOuterClassHint = { "Create an exported factory method in the outer class to work " + "around this limitation." @@ -334,6 +370,25 @@ trait PrepJSExports { this: PrepJSInterop => "You must set an explicit name for exports of nested classes.") } + // Deprecate @JSExport on classes and objects + if (!isMember && !scalaJSOpts.suppressExportDeprecations) { + if (sym.isModuleClass) { + reporter.warning(annot.pos, + "@JSExport on objects is deprecated and will be removed " + + "in 1.0.0. Use @JSExportTopLevel instead. Note that it " + + "exports the object itself (rather than a 0-arg function " + + "returning the object), so the calling JavaScript code " + + "must be adapted." + + SuppressExportDeprecationsMsg) + } else { + reporter.warning(annot.pos, + "@JSExport on classes is deprecated and will be removed " + + "in 1.0.0. Use @JSExportTopLevel instead (which does " + + "exactly the same thing on classes)." + + SuppressExportDeprecationsMsg) + } + } + case ExportDestination.TopLevel => if (!sym.isAccessor && jsInterop.isJSProperty(sym)) { reporter.error(annot.pos, diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 0d58391c6a..585e016dc9 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -353,6 +353,9 @@ abstract class PrepJSInterop extends plugins.PluginComponent case _ => super.transform(tree) } + if (tree.isInstanceOf[ImplDef]) + checkDeprecationOfJSExportDescendentClassesObjects(tree.symbol) + postTransform(preTransformedTree) } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala index aa7f91a245..b56305fb97 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala @@ -19,6 +19,9 @@ trait ScalaJSOptions { * If false, bad calls to classOf will cause an error. */ def fixClassOf: Boolean + /** Should we suppress deprecations of exports coming from 0.6.15? */ + def suppressExportDeprecations: Boolean + /** which source locations in source maps should be relativized (or where * should they be mapped to)? */ def sourceURIMaps: List[URIMap] diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala index e111f2655b..57b39e4045 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala @@ -44,6 +44,7 @@ class ScalaJSPlugin(val global: Global) extends NscPlugin { object scalaJSOpts extends ScalaJSOptions { // scalastyle:ignore import ScalaJSOptions.URIMap var fixClassOf: Boolean = false + var suppressExportDeprecations: Boolean = false lazy val sourceURIMaps: List[URIMap] = { if (_sourceURIMaps.nonEmpty) _sourceURIMaps.reverse @@ -97,7 +98,6 @@ class ScalaJSPlugin(val global: Global) extends NscPlugin { for (option <- options) { if (option == "fixClassOf") { fixClassOf = true - } else if (option.startsWith("mapSourceURI:")) { val uris = option.stripPrefix("mapSourceURI:").split("->") @@ -113,7 +113,8 @@ class ScalaJSPlugin(val global: Global) extends NscPlugin { error(s"${e.getInput} is not a valid URI") } } - + } else if (option == "suppressExportDeprecations") { + suppressExportDeprecations = true // The following options are deprecated (how do we show this to the user?) } else if (option.startsWith("relSourceMap:")) { val uriStr = option.stripPrefix("relSourceMap:") @@ -145,15 +146,24 @@ class ScalaJSPlugin(val global: Global) extends NscPlugin { 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 + | 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 + | -P:$name:suppressExportDeprecations + | Silence deprecations of top-level @JSExport, + | @JSExportDescendentClasses and @JSExportDescendentObjects. + | This can be used as a transition path in the 0.6.x cycle, + | to avoid too many deprecation warnings that are not trivial + | to address. + | -P:$name:fixClassOf + | Repair calls to Predef.classOf that reach Scala.js. | WARNING: This is a tremendous hack! Expect ugly errors if you use this option. |Deprecated options - | -P:$name:relSourceMap: relativize emitted source maps with - | -P:$name:absSourceMap: absolutize emitted source maps with + | -P:$name:relSourceMap: + | Relativize emitted source maps with + | -P:$name:absSourceMap: + | Absolutize emitted source maps with | This option requires the use of relSourceMap """.stripMargin) diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportDeprecationsTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportDeprecationsTest.scala new file mode 100644 index 0000000000..5489d88b47 --- /dev/null +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportDeprecationsTest.scala @@ -0,0 +1,105 @@ +package org.scalajs.core.compiler.test + +import org.scalajs.core.compiler.test.util._ +import org.junit.Test + +// scalastyle:off line.size.limit + +class JSExportDeprecationsTest extends DirectTest with TestHelpers { + + override def extraArgs: List[String] = + super.extraArgs :+ "-deprecation" + + override def preamble: String = + """import scala.scalajs.js, js.annotation._ + """ + + @Test + def warnJSExportClass: Unit = { + """ + @JSExport + class A + + @JSExport("Foo") + class B + """ hasWarns + """ + |newSource1.scala:3: warning: @JSExport on classes is deprecated and will be removed in 1.0.0. Use @JSExportTopLevel instead (which does exactly the same thing on classes). + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressExportDeprecations` to scalac) + | @JSExport + | ^ + |newSource1.scala:6: warning: @JSExport on classes is deprecated and will be removed in 1.0.0. Use @JSExportTopLevel instead (which does exactly the same thing on classes). + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressExportDeprecations` to scalac) + | @JSExport("Foo") + | ^ + """ + } + + @Test + def warnJSExportObject: Unit = { + """ + @JSExport + object A + + @JSExport("Foo") + object B + """ hasWarns + """ + |newSource1.scala:3: warning: @JSExport on objects is deprecated and will be removed in 1.0.0. Use @JSExportTopLevel instead. Note that it exports the object itself (rather than a 0-arg function returning the object), so the calling JavaScript code must be adapted. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressExportDeprecations` to scalac) + | @JSExport + | ^ + |newSource1.scala:6: warning: @JSExport on objects is deprecated and will be removed in 1.0.0. Use @JSExportTopLevel instead. Note that it exports the object itself (rather than a 0-arg function returning the object), so the calling JavaScript code must be adapted. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressExportDeprecations` to scalac) + | @JSExport("Foo") + | ^ + """ + } + + @Test + def warnJSExportDescendentClasses: Unit = { + for (kind <- Seq("class", "trait", "object")) { + s""" + @JSExportDescendentClasses + $kind A + + @JSExportDescendentClasses(ignoreInvalidDescendants = true) + $kind B + """ hasWarns + """ + |newSource1.scala:3: warning: @JSExportDescendentClasses is deprecated and will be removed in 1.0.0. For use cases where you want to simulate "reflective" instantiation, use @EnableReflectiveInstantion and scala.scalajs.reflect.Reflect.lookupInstantiatableClass instead. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressExportDeprecations` to scalac) + | @JSExportDescendentClasses + | ^ + |newSource1.scala:6: warning: @JSExportDescendentClasses is deprecated and will be removed in 1.0.0. For use cases where you want to simulate "reflective" instantiation, use @EnableReflectiveInstantion and scala.scalajs.reflect.Reflect.lookupInstantiatableClass instead. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressExportDeprecations` to scalac) + | @JSExportDescendentClasses(ignoreInvalidDescendants = true) + | ^ + """ + } + } + + @Test + def warnJSExportDescendentObjects: Unit = { + for (kind <- Seq("class", "trait", "object")) { + s""" + @JSExportDescendentObjects + $kind A + + @JSExportDescendentObjects(ignoreInvalidDescendants = true) + $kind B + """ hasWarns + """ + |newSource1.scala:3: warning: @JSExportDescendentObjects is deprecated and will be removed in 1.0.0. For use cases where you want to simulate "reflective" loading, use @EnableReflectiveInstantion and scala.scalajs.reflect.Reflect.lookupLoadableModuleClass instead. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressExportDeprecations` to scalac) + | @JSExportDescendentObjects + | ^ + |newSource1.scala:6: warning: @JSExportDescendentObjects is deprecated and will be removed in 1.0.0. For use cases where you want to simulate "reflective" loading, use @EnableReflectiveInstantion and scala.scalajs.reflect.Reflect.lookupLoadableModuleClass instead. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressExportDeprecations` to scalac) + | @JSExportDescendentObjects(ignoreInvalidDescendants = true) + | ^ + """ + } + } + +} diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index 93b886d7e1..907cec0a1c 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -8,7 +8,7 @@ import org.junit.Test class JSExportTest extends DirectTest with TestHelpers { override def extraArgs: List[String] = - super.extraArgs :+ "-deprecation" + super.extraArgs ::: List("-deprecation", "-P:scalajs:suppressExportDeprecations") override def preamble: String = """import scala.scalajs.js, js.annotation._ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala index 00de69e8e1..20d73829fb 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala @@ -9,6 +9,9 @@ import org.junit.Ignore class ScalaJSDefinedTest extends DirectTest with TestHelpers { + override def extraArgs: List[String] = + super.extraArgs :+ "-P:scalajs:suppressExportDeprecations" + override def preamble: String = """ import scala.scalajs.js diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala index da04b730e3..1a58d8d5a4 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala @@ -1,6 +1,7 @@ package org.scalajs.core.compiler.test.util import scala.tools.nsc._ +import scala.tools.nsc.plugins.Plugin import reporters.{Reporter, ConsoleReporter} import scala.reflect.internal.util.{ SourceFile, BatchSourceFile } @@ -32,7 +33,23 @@ abstract class DirectTest { extraArgs ++ args.toList) lazy val global: Global = new Global(settings, newReporter(settings)) { - override lazy val plugins = newScalaJSPlugin(global) :: Nil + private implicit class PluginCompat(val plugin: Plugin) { + def options: List[String] = { + val prefix = plugin.name + ":" + for { + option <- settings.pluginOptions.value + if option.startsWith(prefix) + } yield { + option.stripPrefix(prefix) + } + } + } + + override lazy val plugins = { + val scalaJSPlugin = newScalaJSPlugin(global) + scalaJSPlugin.processOptions(scalaJSPlugin.options, sys.error(_)) + scalaJSPlugin :: Nil + } } global diff --git a/examples/reversi/Reversi.scala b/examples/reversi/Reversi.scala index b4a34a46de..77b1e08f5a 100644 --- a/examples/reversi/Reversi.scala +++ b/examples/reversi/Reversi.scala @@ -7,7 +7,7 @@ package reversi import scala.annotation.tailrec import scala.scalajs.js -import scala.scalajs.js.annotation.JSExport +import scala.scalajs.js.annotation._ sealed abstract class OptPlayer @@ -25,7 +25,7 @@ case object Black extends Player { val opponent = White } -@JSExport("Reversi") +@JSExportTopLevel("Reversi") class Reversi(jQuery: JQueryStatic, playground: JQuery) { // The Model ----------------------------------------------------------------- diff --git a/project/Build.scala b/project/Build.scala index 7572cbf2d2..ba07868545 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -639,14 +639,14 @@ object Build { val code = { s""" - var linker = scalajs.QuickLinker(); + var linker = scalajs.QuickLinker; var lib = linker.linkTestSuiteNode(${irPaths.mkString(", ")}); var __ScalaJSEnv = $scalaJSEnv; eval("(function() { 'use strict'; " + lib + ";" + - "scalajs.TestRunner().runTests();" + + "scalajs.TestRunner.runTests();" + "}).call(this);"); """ } @@ -997,7 +997,10 @@ object Build { previousArtifactSetting, mimaBinaryIssueFilters ++= BinaryIncompatibilities.Library, libraryDependencies += - "org.scala-lang" % "scala-reflect" % scalaVersion.value % "provided" + "org.scala-lang" % "scala-reflect" % scalaVersion.value % "provided", + + // js.JSApp is annotated with @JSExportDescendentObjects + scalacOptions += "-P:scalajs:suppressExportDeprecations" ) ++ ( scalaJSExternalCompileSettings ) ++ inConfig(Compile)(Seq( @@ -1415,6 +1418,11 @@ object Build { testHtmlSettings(testHtmlFullOpt, FullOptStage) ++ Seq( name := "Scala.js test suite", + /* We still have zillions of run test for top-level @JSExport. Don't + * drown the test:compile output under useless warnings. + */ + scalacOptions in Test += "-P:scalajs:suppressExportDeprecations", + unmanagedSourceDirectories in Test ++= { val testDir = (sourceDirectory in Test).value diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/InfoSender.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/InfoSender.scala index 5c5294b7fb..6928842c70 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/InfoSender.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/InfoSender.scala @@ -3,9 +3,9 @@ package org.scalajs.testinterface.internal import scala.scalajs.js import js.Dynamic.{literal => lit} import js.JSConverters._ -import js.annotation.JSExport +import js.annotation._ -@JSExport +@JSExportTopLevel("org.scalajs.testinterface.internal.InfoSender") final class InfoSender(frameworkName: String) { @JSExport diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Master.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/Master.scala index bdf46bb42a..f4646b92a0 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Master.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/Master.scala @@ -2,7 +2,7 @@ package org.scalajs.testinterface.internal import scala.scalajs.js import js.Dynamic.{literal => lit} -import js.annotation.JSExport +import js.annotation._ import sbt.testing._ @@ -10,7 +10,7 @@ import scala.util.Try import org.scalajs.testinterface.ScalaJSClassLoader -@JSExport +@JSExportTopLevel("org.scalajs.testinterface.internal.Master") final class Master(frameworkName: String) extends BridgeBase(frameworkName) { private[this] var runner: Runner = _ diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala index ee8e2feb05..0317380c1a 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala @@ -1,7 +1,7 @@ package org.scalajs.testinterface.internal import scala.scalajs.js -import js.annotation.JSExport +import js.annotation._ import sbt.testing._ @@ -12,7 +12,7 @@ import scala.util.{Try, Success, Failure} import org.scalajs.testinterface.ScalaJSClassLoader -@JSExport +@JSExportTopLevel("org.scalajs.testinterface.internal.Slave") final class Slave(frameworkName: String, args: js.Array[String], remoteArgs: js.Array[String]) extends BridgeBase(frameworkName) { diff --git 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 index 9c57f7346e..1f0391ec76 100644 --- 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 @@ -7,9 +7,9 @@ import org.scalajs.core.tools.io.IRFileCache.IRContainer import org.scalajs.core.tools.logging._ import org.scalajs.core.tools.linker.Linker -import scala.scalajs.js.annotation.JSExport +import scala.scalajs.js.annotation._ -@JSExport("scalajs.QuickLinker") +@JSExportTopLevel("scalajs.QuickLinker") object QuickLinker { /** Link a Scala.js application on Node.js */ diff --git a/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala b/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala index 24210020ea..eac39b462d 100644 --- a/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala +++ b/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala @@ -1,13 +1,13 @@ package org.scalajs.core.tools.test.js import scala.scalajs.js -import js.annotation.JSExport +import scala.scalajs.js.annotation._ import org.scalajs.testinterface.{ScalaJSClassLoader, TestDetector} import sbt.testing._ -@JSExport("scalajs.TestRunner") +@JSExportTopLevel("scalajs.TestRunner") object TestRunner { @JSExport From 07d23721b6b0c8249453d74137370c7cb36def67 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 25 Feb 2017 17:38:53 +0100 Subject: [PATCH 0133/2665] Fix #2782: Utils.relativize with files as baseURI --- .../scala/org/scalajs/core/ir/Utils.scala | 7 +++- .../scala/org/scalajs/core/ir/UtilsTest.scala | 37 +++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 ir/src/test/scala/org/scalajs/core/ir/UtilsTest.scala diff --git a/ir/src/main/scala/org/scalajs/core/ir/Utils.scala b/ir/src/main/scala/org/scalajs/core/ir/Utils.scala index 5adbd3933b..9546d9a040 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Utils.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Utils.scala @@ -29,8 +29,11 @@ object Utils { base.getRawAuthority != trgt.getRawAuthority) trgt else { - val trgtCmps = trgt.getRawPath.split('/') - val baseCmps = base.getRawPath.split('/') + val trgtCmps = trgt.getRawPath.split("/", -1) + + // Disregard the last element, since it is the filename + // (or empty string for a directory). + val baseCmps = base.getRawPath.split("/", -1).init val prefixLen = (trgtCmps zip baseCmps).takeWhile(t => t._1 == t._2).size diff --git a/ir/src/test/scala/org/scalajs/core/ir/UtilsTest.scala b/ir/src/test/scala/org/scalajs/core/ir/UtilsTest.scala new file mode 100644 index 0000000000..2f0bf59888 --- /dev/null +++ b/ir/src/test/scala/org/scalajs/core/ir/UtilsTest.scala @@ -0,0 +1,37 @@ +package org.scalajs.core.ir + +import java.net.URI + +import org.junit.Test +import org.junit.Assert._ + +class UtilsTest { + + @Test def relativizeURI(): Unit = { + def test(base: String, trgt: String, rel: String) = { + val baseURI = new URI(base) + val trgtURI = new URI(trgt) + val relURI = Utils.relativize(baseURI, trgtURI) + assertEquals(rel, relURI.toString) + assertEquals(trgtURI, baseURI.resolve(relURI)) + } + + test("file:///foo/bar/", "file:///foo/bar/baz", "baz") + test("file:///foo/bar/boo", "file:///foo/bar/baz", "baz") + + test("file:///foo/bar/", "file:///foo/bar/baz/", "baz/") + test("file:///foo/bar/boo", "file:///foo/bar/baz/", "baz/") + + test("file:///foo/bar/", "file:///foo/baz", "../baz") + test("file:///foo/bar/boo", "file:///foo/baz", "../baz") + + test("file:///foo/bar/", "file:///foo/baz/", "../baz/") + test("file:///foo/bar/boo", "file:///foo/baz/", "../baz/") + + test("file:///bar/foo/", "file:///foo/bar/baz", "../../foo/bar/baz") + + test("file:///foo", "http://bar.com/foo", "http://bar.com/foo") + test("http://bob.com/foo", "http://bar.com/foo", "http://bar.com/foo") + } + +} From 408f29142a96bc25cd9bd67dad604ac5c0d8e247 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 25 Feb 2017 16:52:55 +0100 Subject: [PATCH 0134/2665] Fix #2750: Make test HTML include paths relative --- project/BinaryIncompatibilities.scala | 3 +++ .../sbtplugin/HTMLRunnerTemplate.scala | 20 +++++++++---------- .../sbtplugin/ScalaJSPluginInternal.scala | 7 ++++--- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 3e8bd89116..19bed91a9c 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -133,6 +133,9 @@ object BinaryIncompatibilities { ) val SbtPlugin = Seq( + // private[scalajs], not an issue. + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.sbtplugin.HTMLRunnerTemplate.render") ) val TestAdapter = Seq( diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/HTMLRunnerTemplate.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/HTMLRunnerTemplate.scala index 7f9d7e20d3..010e41b23b 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/HTMLRunnerTemplate.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/HTMLRunnerTemplate.scala @@ -9,38 +9,38 @@ package org.scalajs.sbtplugin -import java.io.File -import java.io.Writer +import java.net.URI import sbt.testing.{Framework, TaskDef} +import org.scalajs.core.ir.Utils import org.scalajs.core.tools.json._ import org.scalajs.testadapter.TaskDefSerializers._ /** Template for the HTML runner. */ private[scalajs] object HTMLRunnerTemplate { - def render(title: String, sjsFile: File, jsdepsFile: File, css: File, - loadedFrameworks: Map[sbt.TestFramework, Framework], + def render(baseURI: URI, title: String, sjsFile: URI, jsdepsFile: URI, + css: URI, loadedFrameworks: Map[sbt.TestFramework, Framework], definedTests: Seq[sbt.TestDefinition], sysProps: Map[String, String]): String = { + def relURI(uri: URI) = + htmlEscaped(Utils.relativize(baseURI, uri).toASCIIString) + s""" ${htmlEscaped(title)} - + - - + + diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 1a0813c9a3..ff08a7a412 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -860,9 +860,10 @@ object ScalaJSPluginInternal { } } - IO.write(output, HTMLRunnerTemplate.render(name.value + " - tests", - (sjsKey in testHtmlKey).value.data, (jsdepsKey in testHtmlKey).value, - css, (loadedTestFrameworks in testHtmlKey).value, + IO.write(output, HTMLRunnerTemplate.render(output.toURI, + name.value + " - tests", (sjsKey in testHtmlKey).value.data.toURI, + (jsdepsKey in testHtmlKey).value.toURI, css.toURI, + (loadedTestFrameworks in testHtmlKey).value, (definedTests in testHtmlKey).value, (scalaJSJavaSystemProperties in testHtmlKey).value)) From c90af21db0d766cde2f45bab54e32b2200bc633f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 25 Feb 2017 17:54:36 +0100 Subject: [PATCH 0135/2665] Add facades for ES6 Iterator and Iterable Also add conversions to and from relevant Scala types. Note that these facades do not take return values into account (which are needed for full generator typing). --- .../src/main/scala/scala/scalajs/js/Any.scala | 7 +- .../main/scala/scala/scalajs/js/Array.scala | 8 +- .../scala/scala/scalajs/js/Iterable.scala | 23 ++++ .../scala/scala/scalajs/js/IterableOps.scala | 17 +++ .../scala/scala/scalajs/js/Iterator.scala | 54 +++++++++ .../scala/scala/scalajs/js/JSConverters.scala | 37 ++++++ .../main/scala/scala/scalajs/js/Promise.scala | 6 +- .../main/scala/scala/scalajs/js/UndefOr.scala | 2 +- .../scala/scalajs/js/WrappedDictionary.scala | 6 +- project/BinaryIncompatibilities.scala | 12 ++ .../testsuite/jsinterop/IterableTest.scala | 114 ++++++++++++++++++ 11 files changed, 276 insertions(+), 10 deletions(-) create mode 100644 library/src/main/scala/scala/scalajs/js/Iterable.scala create mode 100644 library/src/main/scala/scala/scalajs/js/IterableOps.scala create mode 100644 library/src/main/scala/scala/scalajs/js/Iterator.scala create mode 100644 test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/IterableTest.scala diff --git a/library/src/main/scala/scala/scalajs/js/Any.scala b/library/src/main/scala/scala/scalajs/js/Any.scala index ecc87673d3..623b853814 100644 --- a/library/src/main/scala/scala/scalajs/js/Any.scala +++ b/library/src/main/scala/scala/scalajs/js/Any.scala @@ -176,9 +176,14 @@ object Any extends LowPrioAnyImplicits { value.asInstanceOf[Any] } -trait LowPrioAnyImplicits { +trait LowPrioAnyImplicits extends LowestPrioAnyImplicits { implicit def wrapArray[A](array: Array[A]): WrappedArray[A] = new WrappedArray(array) implicit def wrapDictionary[A](dict: Dictionary[A]): WrappedDictionary[A] = new WrappedDictionary(dict) } + +sealed trait LowestPrioAnyImplicits { + implicit def iterableOps[A](iterable: Iterable[A]): IterableOps[A] = + new IterableOps(iterable) +} diff --git a/library/src/main/scala/scala/scalajs/js/Array.scala b/library/src/main/scala/scala/scalajs/js/Array.scala index 3d44587fbe..0383b13f5c 100644 --- a/library/src/main/scala/scala/scalajs/js/Array.scala +++ b/library/src/main/scala/scala/scalajs/js/Array.scala @@ -37,7 +37,7 @@ import annotation._ * @constructor Creates a new array of length 0. */ @native -class Array[A] extends Object { +class Array[A] extends Object with Iterable[A] { /** Creates a new array with the given length. * @param arrayLength Initial length of the array. */ @@ -73,6 +73,12 @@ class Array[A] extends Object { */ def concat[B >: A](items: Array[_ <: B]*): Array[B] = native + /** ECMAScript 6 + * JavaScript Iterator for this Array. + */ + @JSName(Symbol.iterator) + def jsIterator(): Iterator[A] = native + /** * The join() method joins all elements of an array into a string. * diff --git a/library/src/main/scala/scala/scalajs/js/Iterable.scala b/library/src/main/scala/scala/scalajs/js/Iterable.scala new file mode 100644 index 0000000000..477e5b7f39 --- /dev/null +++ b/library/src/main/scala/scala/scalajs/js/Iterable.scala @@ -0,0 +1,23 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js API ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package scala.scalajs.js + +import scala.scalajs.js +import js.annotation._ + +/** ECMAScript 6 + * JavaScript Iterable. + */ +@ScalaJSDefined +trait Iterable[+A] extends js.Object { + /** JavaScript Iterator for this Iterable. */ + @JSName(Symbol.iterator) + def jsIterator(): Iterator[A] +} diff --git a/library/src/main/scala/scala/scalajs/js/IterableOps.scala b/library/src/main/scala/scala/scalajs/js/IterableOps.scala new file mode 100644 index 0000000000..37b9a79fb0 --- /dev/null +++ b/library/src/main/scala/scala/scalajs/js/IterableOps.scala @@ -0,0 +1,17 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js API ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package scala.scalajs.js + +/** Adapts a JavaScript Iterable to a Scala Iterable */ +@inline +final class IterableOps[+A](self: Iterable[A]) + extends scala.collection.Iterable[A] { + @inline + def iterator: scala.collection.Iterator[A] = self.jsIterator().toIterator +} diff --git a/library/src/main/scala/scala/scalajs/js/Iterator.scala b/library/src/main/scala/scala/scalajs/js/Iterator.scala new file mode 100644 index 0000000000..9b4fbbb48b --- /dev/null +++ b/library/src/main/scala/scala/scalajs/js/Iterator.scala @@ -0,0 +1,54 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js API ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package scala.scalajs.js + +import scala.scalajs.js +import js.annotation._ + +/** ECMAScript 6 + * JavaScript Iterator. + */ +@ScalaJSDefined +trait Iterator[+A] extends js.Object { + def next(): Iterator.Entry[A] +} + +object Iterator { + /** Return value of [[Iterator.next]]. */ + @ScalaJSDefined + trait Entry[+A] extends js.Object { + /** Whether the iterator has completed. */ + def done: Boolean + + /** The current value. Reading this value is only valid if done is false. */ + def value: A + } + + @inline + private final class WrappedIterator[+A](self: Iterator[A]) + extends scala.collection.Iterator[A] { + private[this] var lastEntry = self.next() + + @inline + def hasNext: Boolean = !lastEntry.done + + @inline + def next(): A = { + val value = lastEntry.value + lastEntry = self.next() + value + } + } + + final implicit class IteratorOps[A](val __self: Iterator[A]) extends AnyVal { + @inline + def toIterator: scala.collection.Iterator[A] = new WrappedIterator(__self) + } +} diff --git a/library/src/main/scala/scala/scalajs/js/JSConverters.scala b/library/src/main/scala/scala/scalajs/js/JSConverters.scala index cb0cf8c08e..14eac7fb58 100644 --- a/library/src/main/scala/scala/scalajs/js/JSConverters.scala +++ b/library/src/main/scala/scala/scalajs/js/JSConverters.scala @@ -12,6 +12,7 @@ package scala.scalajs.js import scala.language.implicitConversions import scala.scalajs.js +import scala.scalajs.js.annotation.{JSName, ScalaJSDefined} import scala.collection._ import scala.concurrent.{ExecutionContext, Future} @@ -41,6 +42,42 @@ object JSConverters extends JSConvertersLowPrioImplicits { @inline final def toJSArray: Array[T] = genTraversableOnce2jsArray(col) } + implicit class JSRichGenIterable[T]( + val __self: GenIterable[T]) extends AnyVal { + @inline final def toJSIterable: Iterable[T] = new IterableAdapter(__self) + } + + implicit class JSRichIterator[T]( + val __self: scala.collection.Iterator[T]) extends AnyVal { + @inline final def toJSIterator: Iterator[T] = new IteratorAdapter(__self) + } + + @ScalaJSDefined + private class IterableAdapter[+T](col: GenIterable[T]) extends Iterable[T] { + @JSName(Symbol.iterator) + final def jsIterator(): Iterator[T] = col.iterator.toJSIterator + } + + @ScalaJSDefined + private class IteratorAdapter[+T]( + it: scala.collection.Iterator[T]) extends Iterator[T] { + final def next(): Iterator.Entry[T] = { + if (it.hasNext) { + new Iterator.Entry[T] { + val done: Boolean = false + val value: T = it.next() + } + } else { + new Iterator.Entry[T] { + val done: Boolean = true + // Evil cast to work around typing. By specification, reading `value` + // is undefined behavior, so this is ok. + val value: T = js.undefined.asInstanceOf[T] + } + } + } + } + implicit class JSRichGenMap[T](val map: GenMap[String, T]) extends AnyVal { @inline final def toJSDictionary: Dictionary[T] = { val result = Dictionary.empty[T] diff --git a/library/src/main/scala/scala/scalajs/js/Promise.scala b/library/src/main/scala/scala/scalajs/js/Promise.scala index 2f823ed117..9e64bfa934 100644 --- a/library/src/main/scala/scala/scalajs/js/Promise.scala +++ b/library/src/main/scala/scala/scalajs/js/Promise.scala @@ -61,9 +61,7 @@ object Promise extends js.Object { /** Returns a new [[Promise]] failed with the specified `reason`. */ def reject(reason: scala.Any): Promise[Nothing] = js.native - // TODO Use js.Iterable - def all[A](promises: js.Array[_ <: Promise[A]]): Promise[js.Array[A]] = js.native + def all[A](promises: js.Iterable[Promise[A]]): Promise[js.Array[A]] = js.native - // TODO Use js.Iterable - def race[A](promises: js.Array[_ <: Promise[A]]): Promise[A] = js.native + def race[A](promises: js.Iterable[Promise[A]]): Promise[A] = js.native } diff --git a/library/src/main/scala/scala/scalajs/js/UndefOr.scala b/library/src/main/scala/scala/scalajs/js/UndefOr.scala index 65f5d13d4d..fcf421bcf4 100644 --- a/library/src/main/scala/scala/scalajs/js/UndefOr.scala +++ b/library/src/main/scala/scala/scalajs/js/UndefOr.scala @@ -220,7 +220,7 @@ final class UndefOrOps[A](val self: UndefOr[A]) extends AnyVal { /** Returns a singleton iterator returning the $option's value * if it is nonempty, or an empty iterator if the option is empty. */ - def iterator: Iterator[A] = + def iterator: scala.collection.Iterator[A] = if (isEmpty) scala.collection.Iterator.empty else scala.collection.Iterator.single(this.forceGet) diff --git a/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala b/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala index 3a56800390..90bce3e8eb 100644 --- a/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala +++ b/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala @@ -57,11 +57,11 @@ class WrappedDictionary[A](val dict: Dictionary[A]) this } - def iterator: Iterator[(String, A)] = + def iterator: scala.collection.Iterator[(String, A)] = new DictionaryIterator(dict) @inline - override def keys: Iterable[String] = + override def keys: scala.collection.Iterable[String] = Object.keys(dict.asInstanceOf[Object]) override def empty: WrappedDictionary[A] = @@ -84,7 +84,7 @@ object WrappedDictionary { Cache.safeHasOwnProperty(dict, key) private final class DictionaryIterator[+A]( - dict: Dictionary[A]) extends Iterator[(String, A)] { + dict: Dictionary[A]) extends scala.collection.Iterator[(String, A)] { private[this] val keys = Object.keys(dict.asInstanceOf[Object]) private[this] var index: Int = 0 def hasNext(): Boolean = index < keys.length diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 3e8bd89116..6a905e1fad 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -142,6 +142,18 @@ object BinaryIncompatibilities { ) val Library = Seq( + // Relaxed typing (js.Iterable instead of js.Array) in js.Promise. + // Not a compatibility issue (due to JS land). + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "scala.scalajs.js.Promise.race"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "scala.scalajs.js.Promise.all"), + + // New member in non-sealed trait (for low prio implicits). + // Theoretically breaking. + ProblemFilters.exclude[InheritedNewAbstractMethodProblem]( + "scala.scalajs.js.LowestPrioAnyImplicits.iterableOps"), + // New members of an @js.native trait in `runtime`, not an issue ProblemFilters.exclude[ReversedMissingMethodProblem]( "scala.scalajs.runtime.LinkingInfo#Semantics.arrayIndexOutOfBounds"), diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/IterableTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/IterableTest.scala new file mode 100644 index 0000000000..e2fc8df2f3 --- /dev/null +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/IterableTest.scala @@ -0,0 +1,114 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.jsinterop + +import scala.scalajs.js +import scala.scalajs.js.annotation.{JSName, ScalaJSDefined} + +import org.junit.Assert._ +import org.junit.Assume._ +import org.junit.{BeforeClass, Test} + +object IterableTest { + @BeforeClass def assumeSymbolsAreSupported(): Unit = { + assumeTrue("Assuming JavaScript symbols are supported", + org.scalajs.testsuite.utils.Platform.areJSSymbolsSupported) + } + + @ScalaJSDefined + private class CounterIterable(val max: Int) extends js.Iterable[Int] { + @JSName(js.Symbol.iterator) + def jsIterator(): js.Iterator[Int] = new CounterIterator(max) + } + + @ScalaJSDefined + private class CounterIterator(val max: Int) extends js.Iterator[Int] { + private[this] var nextNum = 0 + + def next(): js.Iterator.Entry[Int] = { + if (nextNum < max) { + val res = new js.Iterator.Entry[Int] { + val done: Boolean = false + val value: Int = nextNum + } + + nextNum +=1 + + res + } else { + new js.Iterator.Entry[Int] { + val done: Boolean = true + val value: Int = 0 + } + } + } + } +} + +class IterableTest { + import IterableTest._ + + def assertValue[T](expected: T, entry: js.Iterator.Entry[T]): Unit = { + assertFalse(entry.done) + assertEquals(expected, entry.value) + } + + @Test def jsArrayIsIterable(): Unit = { + val iterable: js.Iterable[Int] = js.Array(1, 2, 3) + val it = iterable.jsIterator() + + assertValue(1, it.next()) + assertValue(2, it.next()) + assertValue(3, it.next()) + assertTrue(it.next().done) + assertTrue(it.next().done) + } + + @Test def iterableToScala(): Unit = { + val jsIterable: js.Iterable[Int] = new CounterIterable(5) + val iterable: Iterable[Int] = jsIterable + assertEquals(List(0, 1, 2, 3, 4), iterable.toList) + } + + @Test def iteratorToScala(): Unit = { + val jsIterator: js.Iterator[Int] = new CounterIterator(5) + val iterator: Iterator[Int] = jsIterator.toIterator + assertEquals(List(0, 1, 2, 3, 4), iterator.toList) + } + + @Test def jsArrayToScalaViaIterable(): Unit = { + val jsIterable: js.Iterable[Int] = js.Array(1, 2, 3) + assertEquals(List(1, 2, 3), jsIterable.toList) + } + + @Test def scalaToIterable(): Unit = { + import js.JSConverters._ + + val jsIterable: js.Iterable[String] = Iterable("a", "b", "c").toJSIterable + val it = jsIterable.jsIterator() + + assertValue("a", it.next()) + assertValue("b", it.next()) + assertValue("c", it.next()) + assertTrue(it.next().done) + assertTrue(it.next().done) + } + + @Test def scalaToIterator(): Unit = { + import js.JSConverters._ + + val it = Iterator("a", "b", "c").toJSIterator + + assertValue("a", it.next()) + assertValue("b", it.next()) + assertValue("c", it.next()) + assertTrue(it.next().done) + assertTrue(it.next().done) + } + +} From 3ab659aaa2bdad655d437f7435e3cd2f517af3e1 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 3 Mar 2017 20:05:49 +0100 Subject: [PATCH 0136/2665] Fix #2772: Allow @JSName on objects inside SJS defined JS class --- .../scalajs/core/compiler/PrepJSInterop.scala | 88 ++++++++++--------- .../core/compiler/test/JSInteropTest.scala | 37 ++++++++ .../jsinterop/ScalaJSDefinedTest.scala | 29 ++++++ 3 files changed, 113 insertions(+), 41 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 585e016dc9..c5eb02d350 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -414,12 +414,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent // Expose objects (modules) members of Scala.js-defined JS classes if (sym.isModule && (enclosingOwner is OwnerKind.JSNonNative)) { - def shouldBeExposed: Boolean = { - !sym.isLocalToBlock && - !sym.isSynthetic && - !isPrivateMaybeWithin(sym) - } - if (shouldBeExposed) + if (shouldModuleBeExposed(sym)) sym.addAnnotation(ExposedJSMemberAnnot) } @@ -1034,6 +1029,47 @@ abstract class PrepJSInterop extends plugins.PluginComponent super.transform(tree) } + private def checkJSAnySpecificAnnotsOnNonJSAny(pos: Position, + sym: Symbol): Unit = { + if (sym.hasAnnotation(ScalaJSDefinedAnnotation)) { + reporter.error(pos, + "@ScalaJSDefined is only allowed on classes extending js.Any") + } + + if (sym.hasAnnotation(JSNativeAnnotation)) { + reporter.error(pos, + "Classes, traits and objects not extending js.Any may not have an " + + "@js.native annotation") + } else { + checkJSNativeSpecificAnnotsOnNonJSNative(sym) + } + } + + private def checkJSNativeSpecificAnnotsOnNonJSNative(sym: Symbol): Unit = { + val allowJSName = { + sym.isModuleOrModuleClass && + (enclosingOwner is OwnerKind.JSNonNative) && + shouldModuleBeExposed(sym) + } + + for (annot <- sym.annotations) { + if (annot.symbol == JSNameAnnotation && !allowJSName) { + reporter.warning(annot.pos, + "Non JS-native classes, traits and objects should not have an " + + "@JSName annotation, as it does not have any effect. " + + "This will be enforced in 1.0.") + } else if (annot.symbol == JSImportAnnotation) { + reporter.error(annot.pos, + "Non JS-native classes, traits and objects may not have an " + + "@JSImport annotation.") + } else if (annot.symbol == JSGlobalScopeAnnotation) { + reporter.error(annot.pos, + "Only native JS objects can have an @JSGlobalScope annotation " + + "(or extend js.GlobalScope).") + } + } + } + } def isJSAny(sym: Symbol): Boolean = @@ -1238,41 +1274,6 @@ abstract class PrepJSInterop extends plugins.PluginComponent } } - private def checkJSAnySpecificAnnotsOnNonJSAny(pos: Position, - sym: Symbol): Unit = { - if (sym.hasAnnotation(ScalaJSDefinedAnnotation)) { - reporter.error(pos, - "@ScalaJSDefined is only allowed on classes extending js.Any") - } - - if (sym.hasAnnotation(JSNativeAnnotation)) { - reporter.error(pos, - "Classes, traits and objects not extending js.Any may not have an " + - "@js.native annotation") - } else { - checkJSNativeSpecificAnnotsOnNonJSNative(sym) - } - } - - private def checkJSNativeSpecificAnnotsOnNonJSNative(sym: Symbol): Unit = { - for (annot <- sym.annotations) { - if (annot.symbol == JSNameAnnotation) { - reporter.warning(annot.pos, - "Non JS-native classes, traits and objects should not have an " + - "@JSName annotation, as it does not have any effect. " + - "This will be enforced in 1.0.") - } else if (annot.symbol == JSImportAnnotation) { - reporter.error(annot.pos, - "Non JS-native classes, traits and objects may not have an " + - "@JSImport annotation.") - } else if (annot.symbol == JSGlobalScopeAnnotation) { - reporter.error(annot.pos, - "Only native JS objects can have an @JSGlobalScope annotation " + - "(or extend js.GlobalScope).") - } - } - } - private def checkAndGetJSNativeLoadingSpecAnnotOf( sym: Symbol): Option[Annotation] = { val annots = sym.annotations.filter { annot => @@ -1347,6 +1348,11 @@ abstract class PrepJSInterop extends plugins.PluginComponent case ctor: MethodSymbol if ctor.isPrimaryConstructor => ctor } + private def shouldModuleBeExposed(sym: Symbol) = { + assert(sym.isModuleOrModuleClass) + !sym.isLocalToBlock && !sym.isSynthetic && !isPrivateMaybeWithin(sym) + } + private def wasPublicBeforeTyper(sym: Symbol): Boolean = sym.hasAnnotation(WasPublicBeforeTyperClass) diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index 78059021f1..0db1c17176 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -128,6 +128,43 @@ class JSInteropTest extends DirectTest with TestHelpers { } + @Test + def okJSNameOnNestedObjects: Unit = { + + """ + @ScalaJSDefined + class A extends js.Object { + @JSName("foo") + object toto + + @JSName("bar") + @ScalaJSDefined + object tata extends js.Object + } + """.hasNoWarns + + """ + @ScalaJSDefined + class A extends js.Object { + @JSName("foo") + private object toto + + @JSName("bar") + @ScalaJSDefined + private object tata extends js.Object + } + """ hasWarns + """ + |newSource1.scala:7: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. + | @JSName("foo") + | ^ + |newSource1.scala:10: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. + | @JSName("bar") + | ^ + """ + + } + @Test def noJSImportAnnotOnNonJSNative: Unit = { diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala index 5fe6569921..066e69a192 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala @@ -296,6 +296,35 @@ class ScalaJSDefinedTest { assertFalse((inner2: AnyRef) eq inner1) } + // #2772 + @Test def Scala_object_nested_inside_a_Scala_js_defined_JS_class_JSName(): Unit = { + @ScalaJSDefined + class Foo extends js.Object { + var innerInitCount: Int = _ + + @JSName("innerName") + object Inner { + innerInitCount += 1 + } + } + + val foo = new Foo + assertEquals(0, foo.innerInitCount) + val inner1 = foo.Inner + assertEquals(1, foo.innerInitCount) + assertTrue((foo.Inner: AnyRef) eq inner1) + assertEquals(1, foo.innerInitCount) + + val dyn = (new Foo).asInstanceOf[js.Dynamic] + assertEquals(0, dyn.innerInitCount) + val inner2 = dyn.innerName + assertEquals(1, dyn.innerInitCount) + assertTrue((dyn.innerName: AnyRef) eq inner2) + assertEquals(1, dyn.innerInitCount) + + assertFalse((inner2: AnyRef) eq inner1) + } + @Test def anonymous_class_with_captures(): Unit = { val x = (() => 5)() val obj = new js.Object { From b4edde60b240e370b0877d7e3878095b31e3d836 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 5 Mar 2017 18:47:38 +0100 Subject: [PATCH 0137/2665] Take ImplDef, not Symbol for annotation checks This is cleaner, as it only allows the caller to verify annotations on the currently transformed class. The methods that verify the annotations make this assumption (since they use enclosingOwner). --- .../scalajs/core/compiler/PrepJSInterop.scala | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index c5eb02d350..c801a353c1 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -176,7 +176,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent case idef: ImplDef if isScalaEnum(idef) => val sym = idef.symbol - checkJSAnySpecificAnnotsOnNonJSAny(idef.pos, sym) + checkJSAnySpecificAnnotsOnNonJSAny(idef) val kind = if (idef.isInstanceOf[ModuleDef]) OwnerKind.EnumMod @@ -187,7 +187,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent case cldef: ClassDef => val sym = cldef.symbol - checkJSAnySpecificAnnotsOnNonJSAny(cldef.pos, sym) + checkJSAnySpecificAnnotsOnNonJSAny(cldef) if (sym == UndefOrClass || sym == UnionClass) sym.addAnnotation(RawJSTypeAnnot) @@ -206,7 +206,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent case modDef: ModuleDef => val sym = modDef.symbol - checkJSAnySpecificAnnotsOnNonJSAny(modDef.pos, sym) + checkJSAnySpecificAnnotsOnNonJSAny(modDef) if (shouldPrepareExports) registerModuleExports(sym.moduleClass) @@ -541,7 +541,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent } // Check that there is no JS-native-specific annotation - checkJSNativeSpecificAnnotsOnNonJSNative(sym) + checkJSNativeSpecificAnnotsOnNonJSNative(implDef) } if (shouldCheckLiterals) { @@ -1029,23 +1029,27 @@ abstract class PrepJSInterop extends plugins.PluginComponent super.transform(tree) } - private def checkJSAnySpecificAnnotsOnNonJSAny(pos: Position, - sym: Symbol): Unit = { + private def checkJSAnySpecificAnnotsOnNonJSAny(implDef: ImplDef): Unit = { + val sym = implDef.symbol + if (sym.hasAnnotation(ScalaJSDefinedAnnotation)) { - reporter.error(pos, + reporter.error(implDef.pos, "@ScalaJSDefined is only allowed on classes extending js.Any") } if (sym.hasAnnotation(JSNativeAnnotation)) { - reporter.error(pos, + reporter.error(implDef.pos, "Classes, traits and objects not extending js.Any may not have an " + "@js.native annotation") } else { - checkJSNativeSpecificAnnotsOnNonJSNative(sym) + checkJSNativeSpecificAnnotsOnNonJSNative(implDef) } } - private def checkJSNativeSpecificAnnotsOnNonJSNative(sym: Symbol): Unit = { + private def checkJSNativeSpecificAnnotsOnNonJSNative( + implDef: ImplDef): Unit = { + val sym = implDef.symbol + val allowJSName = { sym.isModuleOrModuleClass && (enclosingOwner is OwnerKind.JSNonNative) && From 4e5d6a76d4de62233ec2f01d628bc9c26727b2f1 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 3 Mar 2017 16:56:44 +0100 Subject: [PATCH 0138/2665] Fix #2778: Warn on self-referencing @JSName --- .../scalajs/core/compiler/PrepJSInterop.scala | 55 ++++++++++--------- .../core/compiler/test/JSInteropTest.scala | 31 +++++++++++ 2 files changed, 61 insertions(+), 25 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index c801a353c1..64f8e64719 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -545,7 +545,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent } if (shouldCheckLiterals) { - checkJSNameArgument(sym) + checkJSNameArgument(implDef) checkJSImportLiteral(sym) } @@ -889,7 +889,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent } if (shouldCheckLiterals) - checkJSNameArgument(sym) + checkJSNameArgument(tree) /* Check that there is at most one @JSName annotation. We used not to * check this, so we can only warn. @@ -1074,6 +1074,34 @@ abstract class PrepJSInterop extends plugins.PluginComponent } } + /** Checks that argument to @JSName on [[member]] is a literal. + * Reports an error on each annotation where this is not the case. + */ + private def checkJSNameArgument(member: MemberDef): Unit = { + for (annot <- member.symbol.getAnnotation(JSNameAnnotation)) { + val argTree = annot.args.head + if (argTree.tpe.typeSymbol == StringClass) { + if (!argTree.isInstanceOf[Literal]) { + reporter.error(argTree.pos, + "A string argument to JSName must be a literal string") + } + } else { + // We have a js.Symbol + val sym = argTree.symbol + if (!sym.isStatic || !sym.isStable) { + reporter.error(argTree.pos, + "A js.Symbol argument to JSName must be a static, stable identifier") + } else if ((enclosingOwner is OwnerKind.JSNonNative) && + sym.owner == member.symbol.owner) { + reporter.warning(argTree.pos, + "This symbol is defined in the same object as the annotation's " + + "target. This will cause a stackoverflow at runtime") + } + } + + } + } + } def isJSAny(sym: Symbol): Boolean = @@ -1127,29 +1155,6 @@ abstract class PrepJSInterop extends plugins.PluginComponent def isPrivateMaybeWithin(sym: Symbol): Boolean = sym.isPrivate || (sym.hasAccessBoundary && !sym.isProtected) - /** Checks that argument to @JSName on [[sym]] is a literal. - * Reports an error on each annotation where this is not the case. - */ - private def checkJSNameArgument(sym: Symbol): Unit = { - for (annot <- sym.getAnnotation(JSNameAnnotation)) { - val argTree = annot.args.head - if (argTree.tpe.typeSymbol == StringClass) { - if (!argTree.isInstanceOf[Literal]) { - reporter.error(argTree.pos, - "A string argument to JSName must be a literal string") - } - } else { - // We have a js.Symbol - val sym = argTree.symbol - if (!sym.isStatic || !sym.isStable) { - reporter.error(argTree.pos, - "A js.Symbol argument to JSName must be a static, stable identifier") - } - } - - } - } - /** Checks that arguments to `@JSImport` on [[sym]] are literals. * * The second argument can also be the singleton `JSImport.Namespace` diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index 0db1c17176..29586a461f 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -1107,6 +1107,37 @@ class JSInteropTest extends DirectTest with TestHelpers { } + @Test + def noSelfReferenceJSNameSymbol: Unit = { + + """ + @ScalaJSDefined + object A extends js.Object { + val a = js.Symbol("foo") + + @JSName(a) + def foo: Int = 1 + } + """ hasWarns + """ + |newSource1.scala:9: warning: This symbol is defined in the same object as the annotation's target. This will cause a stackoverflow at runtime + | @JSName(a) + | ^ + """ + + // Native objects are OK, since we do not control definition order. + """ + @js.native + object A extends js.Object { + val a: js.Symbol = js.native + + @JSName(a) + def foo: Int = js.native + } + """.succeeds + + } + @Test def noJSImportOnMembers: Unit = { From 14a9d7633234139aa6d8444959f62447b58daa6c Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 5 Mar 2017 19:56:51 +0100 Subject: [PATCH 0139/2665] TypedArrays are js.Iterable --- .../scalajs/js/typedarray/Float32Array.scala | 2 +- .../scalajs/js/typedarray/Float64Array.scala | 2 +- .../scalajs/js/typedarray/Int16Array.scala | 2 +- .../scalajs/js/typedarray/Int32Array.scala | 2 +- .../scalajs/js/typedarray/Int8Array.scala | 2 +- .../scalajs/js/typedarray/TypedArray.scala | 11 +-- .../scalajs/js/typedarray/Uint16Array.scala | 2 +- .../scalajs/js/typedarray/Uint32Array.scala | 2 +- .../scalajs/js/typedarray/Uint8Array.scala | 2 +- .../js/typedarray/Uint8ClampedArray.scala | 2 +- project/BinaryIncompatibilities.scala | 49 +++++++++++++ .../testsuite/typedarray/TypedArrayTest.scala | 72 +++++++++++++------ 12 files changed, 116 insertions(+), 34 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Float32Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Float32Array.scala index 452b79c6a1..11db18d2ea 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Float32Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Float32Array.scala @@ -18,7 +18,7 @@ class Float32Array private extends TypedArray[Float, Float32Array] { def this(typedArray: TypedArray[_, _]) = this() /** Creates a new Float32Array with the elements in the given array */ - def this(array: js.Array[_]) = this() + def this(array: js.Iterable[_]) = this() /** Creates a Float32Array view on the given ArrayBuffer */ def this(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = ???) = this() diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Float64Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Float64Array.scala index c40bed3004..b31a3c92eb 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Float64Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Float64Array.scala @@ -18,7 +18,7 @@ class Float64Array private extends TypedArray[Double, Float64Array] { def this(typedArray: TypedArray[_, _]) = this() /** Creates a new Float64Array with the elements in the given array */ - def this(array: js.Array[_]) = this() + def this(array: js.Iterable[_]) = this() /** Creates a Float64Array view on the given ArrayBuffer */ def this(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = ???) = this() diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Int16Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Int16Array.scala index 517709bfd0..13bec62e63 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Int16Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Int16Array.scala @@ -18,7 +18,7 @@ class Int16Array private extends TypedArray[Short, Int16Array] { def this(typedArray: TypedArray[_, _]) = this() /** Creates a new Int16Array with the elements in the given array */ - def this(array: js.Array[_]) = this() + def this(array: js.Iterable[_]) = this() /** Creates a Int16Array view on the given ArrayBuffer */ def this(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = ???) = this() diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Int32Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Int32Array.scala index 5ff091ff53..3b175c60aa 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Int32Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Int32Array.scala @@ -18,7 +18,7 @@ class Int32Array private extends TypedArray[Int, Int32Array] { def this(typedArray: TypedArray[_, _]) = this() /** Creates a new Int32Array with the elements in the given array */ - def this(array: js.Array[_]) = this() + def this(array: js.Iterable[_]) = this() /** Creates a Int32Array view on the given ArrayBuffer */ def this(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = ???) = this() diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Int8Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Int8Array.scala index 96e3ed7d54..0c3bdc1c73 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Int8Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Int8Array.scala @@ -18,7 +18,7 @@ class Int8Array private extends TypedArray[Byte, Int8Array] { def this(typedArray: TypedArray[_, _]) = this() /** Creates a new Int8Array with the elements in the given array */ - def this(array: js.Array[_]) = this() + def this(array: js.Iterable[_]) = this() /** Creates a Int8Array view on the given ArrayBuffer */ def this(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = ???) = this() diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/TypedArray.scala b/library/src/main/scala/scala/scalajs/js/typedarray/TypedArray.scala index ce78a872d0..5adc3d4376 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/TypedArray.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/TypedArray.scala @@ -1,14 +1,14 @@ package scala.scalajs.js.typedarray import scala.scalajs.js -import scala.scalajs.js.annotation.JSBracketAccess +import scala.scalajs.js.annotation.{JSBracketAccess, JSName} /** ECMAScript 6 * A TypedArray allows to view an [[ArrayBuffer]] as an array of values of a * particular numeric type. */ @js.native -trait TypedArray[T, Repr] extends ArrayBufferView { +trait TypedArray[T, Repr] extends ArrayBufferView with js.Iterable[T] { /** The number of elements in this TypedArray */ val length: Int = js.native @@ -25,6 +25,9 @@ trait TypedArray[T, Repr] extends ArrayBufferView { @JSBracketAccess def get(index: Int): T = js.native + @JSName(js.Symbol.iterator) + def jsIterator(): js.Iterator[T] = js.native + /** Set element at index */ @JSBracketAccess def set(index: Int, value: T): Unit = js.native @@ -36,10 +39,10 @@ trait TypedArray[T, Repr] extends ArrayBufferView { def set(typedArray: TypedArray[_, _], offset: Int): Unit = js.native /** Set the values from array in this TypedArray */ - def set(array: js.Array[_]): Unit = js.native + def set(array: js.Iterable[_]): Unit = js.native /** Set the values from array in this TypedArray at given offset */ - def set(array: js.Array[_], offset: Int): Unit = js.native + def set(array: js.Iterable[_], offset: Int): Unit = js.native /** Create a new TypedArray view of this TypedArray at given location */ def subarray(begin: Int, end: Int = ???): Repr = js.native diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Uint16Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Uint16Array.scala index d770b135eb..db25b5a20c 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Uint16Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Uint16Array.scala @@ -18,7 +18,7 @@ class Uint16Array private extends TypedArray[Int, Uint16Array] { def this(typedArray: TypedArray[_, _]) = this() /** Creates a new Uint16Array with the elements in the given array */ - def this(array: js.Array[_]) = this() + def this(array: js.Iterable[_]) = this() /** Creates a Uint16Array view on the given ArrayBuffer */ def this(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = ???) = this() diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Uint32Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Uint32Array.scala index 220de3aaa8..ffc57ee108 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Uint32Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Uint32Array.scala @@ -18,7 +18,7 @@ class Uint32Array private extends TypedArray[Double, Uint32Array] { def this(typedArray: TypedArray[_, _]) = this() /** Creates a new Uint32Array with the elements in the given array */ - def this(array: js.Array[_]) = this() + def this(array: js.Iterable[_]) = this() /** Creates a Uint32Array view on the given ArrayBuffer */ def this(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = ???) = this() diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Uint8Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Uint8Array.scala index 591a734ada..30aa866f50 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Uint8Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Uint8Array.scala @@ -18,7 +18,7 @@ class Uint8Array private extends TypedArray[Short, Uint8Array] { def this(typedArray: TypedArray[_, _]) = this() /** Creates a new Uint8Array with the elements in the given array */ - def this(array: js.Array[_]) = this() + def this(array: js.Iterable[_]) = this() /** Creates a Uint8Array view on the given ArrayBuffer */ def this(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = ???) = this() diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Uint8ClampedArray.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Uint8ClampedArray.scala index c949fe0fd2..04cf613343 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Uint8ClampedArray.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Uint8ClampedArray.scala @@ -19,7 +19,7 @@ class Uint8ClampedArray private extends TypedArray[Int, Uint8ClampedArray] { def this(typedArray: TypedArray[_, _]) = this() /** Creates a new Uint8ClampedArray with the elements in the given array */ - def this(array: js.Array[_]) = this() + def this(array: js.Iterable[_]) = this() /** Creates a Uint8ClampedArray view on the given ArrayBuffer */ def this(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = ???) = this() diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 1958d7c8c5..e1d7f79dbd 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -152,6 +152,55 @@ object BinaryIncompatibilities { ProblemFilters.exclude[IncompatibleMethTypeProblem]( "scala.scalajs.js.Promise.all"), + // js.Iterable support in TypedArray. + // Not a compatibility issue (due to JS land). + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "scala.scalajs.js.typedarray.Int8Array.set"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "scala.scalajs.js.typedarray.Int8Array.this"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "scala.scalajs.js.typedarray.Uint8ClampedArray.set"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "scala.scalajs.js.typedarray.Uint8ClampedArray.this"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "scala.scalajs.js.typedarray.Uint16Array.set"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "scala.scalajs.js.typedarray.Uint16Array.this"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "scala.scalajs.js.typedarray.Uint8Array.set"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "scala.scalajs.js.typedarray.Uint8Array.this"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "scala.scalajs.js.typedarray.TypedArray.set"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "scala.scalajs.js.typedarray.TypedArray.set"), + ProblemFilters.exclude[ReversedMissingMethodProblem]( + "scala.scalajs.js.typedarray.TypedArray.set"), + ProblemFilters.exclude[ReversedMissingMethodProblem]( + "scala.scalajs.js.typedarray.TypedArray.jsIterator"), + ProblemFilters.exclude[InheritedNewAbstractMethodProblem]( + "scala.scalajs.js.Iterable.jsIterator"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "scala.scalajs.js.typedarray.Int32Array.set"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "scala.scalajs.js.typedarray.Int32Array.this"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "scala.scalajs.js.typedarray.Float32Array.set"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "scala.scalajs.js.typedarray.Float32Array.this"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "scala.scalajs.js.typedarray.Float64Array.set"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "scala.scalajs.js.typedarray.Float64Array.this"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "scala.scalajs.js.typedarray.Int16Array.set"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "scala.scalajs.js.typedarray.Int16Array.this"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "scala.scalajs.js.typedarray.Uint32Array.set"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "scala.scalajs.js.typedarray.Uint32Array.this"), + // New member in non-sealed trait (for low prio implicits). // Theoretically breaking. ProblemFilters.exclude[InheritedNewAbstractMethodProblem]( diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/TypedArrayTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/TypedArrayTest.scala index d0a5dd0695..e829026896 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/TypedArrayTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/TypedArrayTest.scala @@ -8,6 +8,7 @@ package org.scalajs.testsuite.typedarray import org.junit.Assert._ +import org.junit.Assume._ import org.junit.Test import org.scalajs.testsuite.utils.Requires @@ -23,7 +24,7 @@ trait TypedArrayTest[V, T <: TypedArray[V, T]] { def bytesPerElement: Int def lenCtor(len: Int): T def tarrCtor(tarr: TypedArray[_, _]): T - def arrCtor(arr: js.Array[_]): T + def itCtor(arr: js.Iterable[_]): T def bufCtor1(buf: ArrayBuffer): T def bufCtor2(buf: ArrayBuffer, start: Int): T def bufCtor3(buf: ArrayBuffer, start: Int, end: Int): T @@ -46,7 +47,7 @@ trait TypedArrayTest[V, T <: TypedArray[V, T]] { } @Test def should_allow_constructing_a_new_name_from_a_js_Array(): Unit = { - val x = arrCtor(js.Array(5,6,7)) + val x = itCtor(js.Array(5,6,7)) assertTrue(hasType(x)) assertEquals(3, x.length) @@ -56,7 +57,7 @@ trait TypedArrayTest[V, T <: TypedArray[V, T]] { } @Test def should_allow_constructing_a_new_name_from_an_ArrayBuffer_1_arg(): Unit = { - val buf = arrCtor(js.Array(5, 6, 7, 8)).buffer + val buf = itCtor(js.Array(5, 6, 7, 8)).buffer val x = bufCtor1(buf) assertTrue(hasType(x)) assertEquals(4, x.length) @@ -68,7 +69,7 @@ trait TypedArrayTest[V, T <: TypedArray[V, T]] { } @Test def should_allow_constructing_a_new_name_from_an_ArrayBuffer_2_args(): Unit = { - val buf = arrCtor(js.Array(5, 6, 7, 8)).buffer + val buf = itCtor(js.Array(5, 6, 7, 8)).buffer val x = bufCtor2(buf, bytesPerElement) assertTrue(hasType(x)) assertEquals(3, x.length) @@ -79,7 +80,7 @@ trait TypedArrayTest[V, T <: TypedArray[V, T]] { } @Test def should_allow_constructing_a_new_name_from_an_ArrayBuffer_3_args(): Unit = { - val buf = arrCtor(js.Array(5, 6, 7, 8)).buffer + val buf = itCtor(js.Array(5, 6, 7, 8)).buffer val x = bufCtor3(buf, bytesPerElement, 2) assertTrue(hasType(x)) assertEquals(2, x.length) @@ -94,7 +95,7 @@ trait TypedArrayTest[V, T <: TypedArray[V, T]] { } @Test def should_allow_retrieving_an_should_allow_retrieving_an(): Unit = { - val x = arrCtor(js.Array(5)) + val x = itCtor(js.Array(5)) assertEquals(5, x(0)) } @@ -109,7 +110,7 @@ trait TypedArrayTest[V, T <: TypedArray[V, T]] { } @Test def should_provide_should_provide(): Unit = { - val x = arrCtor(js.Array(10)) + val x = itCtor(js.Array(10)) assertEquals(10, x.get(0)) } @@ -168,7 +169,7 @@ trait TypedArrayTest[V, T <: TypedArray[V, T]] { } @Test def subarray_with_one_argument(): Unit = { - val x = arrCtor(js.Array(1,2,3,4,5,6,7,8,9)) + val x = itCtor(js.Array(1,2,3,4,5,6,7,8,9)) val y = x.subarray(2) assertEquals(7, y.length) @@ -180,7 +181,7 @@ trait TypedArrayTest[V, T <: TypedArray[V, T]] { } @Test def subarray_with_two_arguments(): Unit = { - val x = arrCtor(js.Array(1,2,3,4,5,6,7,8,9)) + val x = itCtor(js.Array(1,2,3,4,5,6,7,8,9)) val y = x.subarray(2, 4) assertEquals(2, y.length) @@ -192,25 +193,54 @@ trait TypedArrayTest[V, T <: TypedArray[V, T]] { } @Test def buffer(): Unit = { - val x = arrCtor(js.Array(1,2,3,4,5,6,7,8,9)) + val x = itCtor(js.Array(1,2,3,4,5,6,7,8,9)) val y = bufCtor3(x.buffer, 0, 2) assertSame(x.buffer, y.buffer) } @Test def byteLength(): Unit = { - val x = arrCtor(js.Array(0 until bytesPerElement * 4: _*)) + val x = itCtor(js.Array(0 until bytesPerElement * 4: _*)) val y = bufCtor3(x.buffer, bytesPerElement, 3) assertEquals(3 * bytesPerElement, y.byteLength) } @Test def byteOffset(): Unit = { - val x = arrCtor(js.Array(0 until bytesPerElement * 4: _*)) + val x = itCtor(js.Array(0 until bytesPerElement * 4: _*)) val y = bufCtor3(x.buffer, bytesPerElement, 3) assertEquals(bytesPerElement, y.byteOffset) } + + @Test def is_iterable(): Unit = { + assumeTrue("Assuming JavaScript symbols are supported", + org.scalajs.testsuite.utils.Platform.areJSSymbolsSupported) + + import js.JSConverters._ + + val testData: List[Int] = (1 to 10).toList + val typedArray: T = itCtor(testData.toJSArray) + val jsIterable: js.Iterable[V] = typedArray + val iterable: Iterable[V] = jsIterable + + assertEquals(iterable.toList, testData.map(intToV)) + } + + @Test def from_iterable(): Unit = { + assumeTrue("Assuming JavaScript symbols are supported", + org.scalajs.testsuite.utils.Platform.areJSSymbolsSupported) + + import js.JSConverters._ + + val x = itCtor(Iterable(1, 2, 3, 4).toJSIterable) + + assertEquals(4, x.length) + assertEquals(1, x(0)) + assertEquals(2, x(1)) + assertEquals(3, x(2)) + assertEquals(4, x(3)) + } } object Int8ArrayTest extends Requires.TypedArray @@ -219,7 +249,7 @@ class Int8ArrayTest extends TypedArrayTest[Byte, Int8Array] { def bytesPerElement: Int = Int8Array.BYTES_PER_ELEMENT def lenCtor(len: Int): Int8Array = new Int8Array(len) def tarrCtor(tarr: TypedArray[_, _]): Int8Array = new Int8Array(tarr) - def arrCtor(arr: js.Array[_]): Int8Array = new Int8Array(arr) + def itCtor(arr: js.Iterable[_]): Int8Array = new Int8Array(arr) def bufCtor1(buf: ArrayBuffer): Int8Array = new Int8Array(buf) def bufCtor2(buf: ArrayBuffer, start: Int): Int8Array = new Int8Array(buf, start) def bufCtor3(buf: ArrayBuffer, start: Int, end: Int): Int8Array = new Int8Array(buf, start, end) @@ -233,7 +263,7 @@ class Uint8ArrayTest extends TypedArrayTest[Short, Uint8Array] { def bytesPerElement: Int = Uint8Array.BYTES_PER_ELEMENT def lenCtor(len: Int): Uint8Array = new Uint8Array(len) def tarrCtor(tarr: TypedArray[_, _]): Uint8Array = new Uint8Array(tarr) - def arrCtor(arr: js.Array[_]): Uint8Array = new Uint8Array(arr) + def itCtor(arr: js.Iterable[_]): Uint8Array = new Uint8Array(arr) def bufCtor1(buf: ArrayBuffer): Uint8Array = new Uint8Array(buf) def bufCtor2(buf: ArrayBuffer, start: Int): Uint8Array = new Uint8Array(buf, start) def bufCtor3(buf: ArrayBuffer, start: Int, end: Int): Uint8Array = new Uint8Array(buf, start, end) @@ -247,7 +277,7 @@ class Uint8ClampedArrayTest extends TypedArrayTest[Int, Uint8ClampedArray] { def bytesPerElement: Int = Uint8ClampedArray.BYTES_PER_ELEMENT def lenCtor(len: Int): Uint8ClampedArray = new Uint8ClampedArray(len) def tarrCtor(tarr: TypedArray[_, _]): Uint8ClampedArray = new Uint8ClampedArray(tarr) - def arrCtor(arr: js.Array[_]): Uint8ClampedArray = new Uint8ClampedArray(arr) + def itCtor(arr: js.Iterable[_]): Uint8ClampedArray = new Uint8ClampedArray(arr) def bufCtor1(buf: ArrayBuffer): Uint8ClampedArray = new Uint8ClampedArray(buf) def bufCtor2(buf: ArrayBuffer, start: Int): Uint8ClampedArray = new Uint8ClampedArray(buf, start) def bufCtor3(buf: ArrayBuffer, start: Int, end: Int): Uint8ClampedArray = new Uint8ClampedArray(buf, start, end) @@ -261,7 +291,7 @@ class Int16ArrayTest extends TypedArrayTest[Short, Int16Array] { def bytesPerElement: Int = Int16Array.BYTES_PER_ELEMENT def lenCtor(len: Int): Int16Array = new Int16Array(len) def tarrCtor(tarr: TypedArray[_, _]): Int16Array = new Int16Array(tarr) - def arrCtor(arr: js.Array[_]): Int16Array = new Int16Array(arr) + def itCtor(arr: js.Iterable[_]): Int16Array = new Int16Array(arr) def bufCtor1(buf: ArrayBuffer): Int16Array = new Int16Array(buf) def bufCtor2(buf: ArrayBuffer, start: Int): Int16Array = new Int16Array(buf, start) def bufCtor3(buf: ArrayBuffer, start: Int, end: Int): Int16Array = new Int16Array(buf, start, end) @@ -275,7 +305,7 @@ class Uint16ArrayTest extends TypedArrayTest[Int, Uint16Array] { def bytesPerElement: Int = Uint16Array.BYTES_PER_ELEMENT def lenCtor(len: Int): Uint16Array = new Uint16Array(len) def tarrCtor(tarr: TypedArray[_, _]): Uint16Array = new Uint16Array(tarr) - def arrCtor(arr: js.Array[_]): Uint16Array = new Uint16Array(arr) + def itCtor(arr: js.Iterable[_]): Uint16Array = new Uint16Array(arr) def bufCtor1(buf: ArrayBuffer): Uint16Array = new Uint16Array(buf) def bufCtor2(buf: ArrayBuffer, start: Int): Uint16Array = new Uint16Array(buf, start) def bufCtor3(buf: ArrayBuffer, start: Int, end: Int): Uint16Array = new Uint16Array(buf, start, end) @@ -289,7 +319,7 @@ class Int32ArrayTest extends TypedArrayTest[Int, Int32Array] { def bytesPerElement: Int = Int32Array.BYTES_PER_ELEMENT def lenCtor(len: Int): Int32Array = new Int32Array(len) def tarrCtor(tarr: TypedArray[_, _]): Int32Array = new Int32Array(tarr) - def arrCtor(arr: js.Array[_]): Int32Array = new Int32Array(arr) + def itCtor(arr: js.Iterable[_]): Int32Array = new Int32Array(arr) def bufCtor1(buf: ArrayBuffer): Int32Array = new Int32Array(buf) def bufCtor2(buf: ArrayBuffer, start: Int): Int32Array = new Int32Array(buf, start) def bufCtor3(buf: ArrayBuffer, start: Int, end: Int): Int32Array = new Int32Array(buf, start, end) @@ -303,7 +333,7 @@ class Uint32ArrayTest extends TypedArrayTest[Double, Uint32Array] { def bytesPerElement: Int = Uint32Array.BYTES_PER_ELEMENT def lenCtor(len: Int): Uint32Array = new Uint32Array(len) def tarrCtor(tarr: TypedArray[_, _]): Uint32Array = new Uint32Array(tarr) - def arrCtor(arr: js.Array[_]): Uint32Array = new Uint32Array(arr) + def itCtor(arr: js.Iterable[_]): Uint32Array = new Uint32Array(arr) def bufCtor1(buf: ArrayBuffer): Uint32Array = new Uint32Array(buf) def bufCtor2(buf: ArrayBuffer, start: Int): Uint32Array = new Uint32Array(buf, start) def bufCtor3(buf: ArrayBuffer, start: Int, end: Int): Uint32Array = new Uint32Array(buf, start, end) @@ -317,7 +347,7 @@ class Float32ArrayTest extends TypedArrayTest[Float, Float32Array] { def bytesPerElement: Int = Float32Array.BYTES_PER_ELEMENT def lenCtor(len: Int): Float32Array = new Float32Array(len) def tarrCtor(tarr: TypedArray[_, _]): Float32Array = new Float32Array(tarr) - def arrCtor(arr: js.Array[_]): Float32Array = new Float32Array(arr) + def itCtor(arr: js.Iterable[_]): Float32Array = new Float32Array(arr) def bufCtor1(buf: ArrayBuffer): Float32Array = new Float32Array(buf) def bufCtor2(buf: ArrayBuffer, start: Int): Float32Array = new Float32Array(buf, start) def bufCtor3(buf: ArrayBuffer, start: Int, end: Int): Float32Array = new Float32Array(buf, start, end) @@ -331,7 +361,7 @@ class Float64ArrayTest extends TypedArrayTest[Double, Float64Array] { def bytesPerElement: Int = Float64Array.BYTES_PER_ELEMENT def lenCtor(len: Int): Float64Array = new Float64Array(len) def tarrCtor(tarr: TypedArray[_, _]): Float64Array = new Float64Array(tarr) - def arrCtor(arr: js.Array[_]): Float64Array = new Float64Array(arr) + def itCtor(arr: js.Iterable[_]): Float64Array = new Float64Array(arr) def bufCtor1(buf: ArrayBuffer): Float64Array = new Float64Array(buf) def bufCtor2(buf: ArrayBuffer, start: Int): Float64Array = new Float64Array(buf, start) def bufCtor3(buf: ArrayBuffer, start: Int, end: Int): Float64Array = new Float64Array(buf, start, end) From b3afca69437123aec500f7f1ba5d689563fbf15f Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 5 Mar 2017 21:14:09 +0100 Subject: [PATCH 0140/2665] Move envFieldDef to ClassEmitter They are not (and should not) be used elsewhere. --- project/BinaryIncompatibilities.scala | 2 + .../linker/backend/emitter/JSDesugaring.scala | 54 ------------------- .../backend/emitter/ScalaJSClassEmitter.scala | 45 ++++++++++++---- 3 files changed, 37 insertions(+), 64 deletions(-) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 1958d7c8c5..e9d20d67e8 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -112,6 +112,8 @@ object BinaryIncompatibilities { "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.desugarToFunction"), ProblemFilters.exclude[DirectMissingMethodProblem]( "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.envField"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.envFieldDef"), ProblemFilters.exclude[IncompatibleMethTypeProblem]( "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.envFieldDef"), ProblemFilters.exclude[DirectMissingMethodProblem]( diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala index d483f702ea..92a7fb2db5 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala @@ -2499,60 +2499,6 @@ private[emitter] class JSDesugaring(semantics: Semantics, } } - private[emitter] def envFieldDef(field: String, subField: String, - value: js.Tree)( - implicit pos: Position): js.Tree = { - envFieldDef(field, subField, value, mutable = false) - } - - private[emitter] def envFieldDef(field: String, subField: String, - value: js.Tree, mutable: Boolean)( - implicit pos: Position): js.Tree = { - envFieldDef(field, subField, origName = None, value, mutable) - } - - private[emitter] def envFieldDef(field: String, subField: String, - origName: Option[String], value: js.Tree)( - implicit pos: Position): js.Tree = { - envFieldDef(field, subField, origName, value, mutable = false) - } - - private[emitter] def envFieldDef(field: String, subField: String, - origName: Option[String], value: js.Tree, mutable: Boolean)( - implicit pos: Position): js.Tree = { - envFieldDef(field, subField, origName, value, mutable, - keepFunctionExpression = false) - } - - private[emitter] def envFieldDef(field: String, subField: String, - origName: Option[String], value: js.Tree, mutable: Boolean, - keepFunctionExpression: Boolean)( - implicit pos: Position): js.Tree = { - val globalVar = envField(field, subField, origName) - def globalVarIdent = globalVar.asInstanceOf[js.VarRef].ident - - outputMode match { - case OutputMode.ECMAScript51Global => - js.Assign(globalVar, value) - - case OutputMode.ECMAScript51Isolated => - value match { - case js.Function(args, body) => - // Make sure the function has a meaningful `name` property - val functionExpr = js.FunctionDef(globalVarIdent, args, body) - if (keepFunctionExpression) - js.VarDef(globalVarIdent, Some(functionExpr)) - else - functionExpr - case _ => - js.VarDef(globalVarIdent, Some(value)) - } - - case OutputMode.ECMAScript6 => - genLet(globalVarIdent, mutable, value) - } - } - private[emitter] def genPropSelect(qual: js.Tree, item: js.PropertyName)( implicit pos: Position): js.Tree = { item match { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala index bfb1b4c874..b14807eee5 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala @@ -204,8 +204,8 @@ private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, def makeInheritableCtorDef(ctorToMimic: js.Tree) = { js.Block( js.DocComment("@constructor"), - envFieldDef("h", className, None, js.Function(Nil, js.Skip()), - mutable = false, keepFunctionExpression = isJSClass), + envFieldDef("h", className, js.Function(Nil, js.Skip()), + keepFunctionExpression = isJSClass), js.Assign(envField("h", className).prototype, ctorToMimic.prototype) ) } @@ -226,7 +226,7 @@ private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, val typeVar = encodeClassVar(className) val docComment = js.DocComment("@constructor") - val ctorDef = envFieldDef("c", className, None, ctorFun, mutable = false, + val ctorDef = envFieldDef("c", className, ctorFun, keepFunctionExpression = isJSClass) val chainProto = tree.superClass.fold[js.Tree] { @@ -316,7 +316,7 @@ private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, } yield { implicit val pos = field.pos val fullName = className + "__" + name - envFieldDef("t", fullName, origName, genZeroOf(ftpe), mutable) + envFieldDef("t", fullName, genZeroOf(ftpe), origName, mutable) } js.Block(stats)(tree.pos) } @@ -374,9 +374,7 @@ private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, if (method.static) { method.name match { case Ident(methodName, origName) => - envFieldDef( - "s", className + "__" + methodName, origName, - methodFun) + envFieldDef("s", className + "__" + methodName, methodFun, origName) case methodName => outputMode match { @@ -421,9 +419,7 @@ private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, val Ident(methodName, origName) = method.name - envFieldDef( - "f", className + "__" + methodName, origName, - methodFun) + envFieldDef("f", className + "__" + methodName, methodFun, origName) } /** Generates a property. */ @@ -1100,6 +1096,35 @@ private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, // Helpers + private def envFieldDef(field: String, subField: String, value: js.Tree, + origName: Option[String] = None, mutable: Boolean = false, + keepFunctionExpression: Boolean = false)( + implicit pos: Position): js.Tree = { + val globalVar = envField(field, subField, origName) + def globalVarIdent = globalVar.asInstanceOf[js.VarRef].ident + + outputMode match { + case OutputMode.ECMAScript51Global => + js.Assign(globalVar, value) + + case OutputMode.ECMAScript51Isolated => + value match { + case js.Function(args, body) => + // Make sure the function has a meaningful `name` property + val functionExpr = js.FunctionDef(globalVarIdent, args, body) + if (keepFunctionExpression) + js.VarDef(globalVarIdent, Some(functionExpr)) + else + functionExpr + case _ => + js.VarDef(globalVarIdent, Some(value)) + } + + case OutputMode.ECMAScript6 => + genLet(globalVarIdent, mutable, value) + } + } + /** Gen JS code for assigning an rhs to a qualified name in the exports scope. * For example, given the qualified name `"foo.bar.Something"`, generates: * From 08589e5fd5f6312cff192005fb1644f8b0dd0510 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 6 Mar 2017 16:06:12 +0100 Subject: [PATCH 0141/2665] Demand `@JSGlobal` for non-`@JSImport` JS native classes and objects. Previously, a top-level `@js.native` class/object was loaded from the global scope by default, either with an explicit name through `@JSName` or with an implicit name derived from its Scala name. With this commit, such a native class/object should be declared with an `@JSGlobal` annotation instead (either with or without an explicit name). For example, @js.native class Foo extends js.Object @js.native @JSName("Foobaz") object Bar extends js.Object would now be written as @js.native @JSGlobal class Foo extends js.Object @js.native @JSGlobal("Foobaz") object Bar extends js.Object There are two main reasons for such a change. First, it brings loading from the global scope syntactically on par with importing from a module. As the JS eco-system moves towards modules, the syntactic bias towards globally scoped things is not relevant anymore. Second, it removes the overloaded meaning of `@JSName`. Indeed, this annotation has significantly different meanings whether it is attached to a top-level native class/object versus a member of a JS type. For example, a `.` has a special meaning for top-level native class/object, but not for a member of a JS type. The changes in this commit close #2615 by leaving only the meaning where `.` is not special, and therefore need not be forbidden. Since this is a fairly disruptive change, the deprecation warnings can be suppressed with the option `-P:scalajs:suppressMissingJSGlobalDeprecations` during the 0.6.x cycle, to ease migration. --- .../scalajs/core/compiler/JSDefinitions.scala | 1 + .../core/compiler/JSGlobalAddons.scala | 12 +- .../scalajs/core/compiler/PrepJSInterop.scala | 108 +++- .../core/compiler/ScalaJSOptions.scala | 3 + .../scalajs/core/compiler/ScalaJSPlugin.scala | 3 + .../compiler/test/DiverseErrorsTest.scala | 14 +- .../core/compiler/test/JSExportTest.scala | 13 +- .../core/compiler/test/JSInteropTest.scala | 588 +++++++++++++++--- .../core/compiler/test/JSOptionalTest.scala | 10 +- ...ngJSGlobalDeprecationsSuppressedTest.scala | 88 +++ .../MissingJSGlobalDeprecationsTest.scala | 132 ++++ .../core/compiler/test/ReflectTest.scala | 6 +- examples/helloworld/HelloWorld.scala | 2 +- .../main/scala/scala/scalajs/js/Array.scala | 2 + .../main/scala/scala/scalajs/js/Date.scala | 4 + .../main/scala/scala/scalajs/js/Error.scala | 16 + .../scala/scala/scalajs/js/Function.scala | 4 + .../main/scala/scala/scalajs/js/JSON.scala | 3 + .../main/scala/scala/scalajs/js/Math.scala | 3 + .../main/scala/scala/scalajs/js/Object.scala | 4 + .../main/scala/scala/scalajs/js/Promise.scala | 3 + .../main/scala/scala/scalajs/js/RegExp.scala | 4 + .../main/scala/scala/scalajs/js/Symbol.scala | 1 + .../scalajs/js/annotation/JSGlobal.scala | 46 ++ .../scalajs/js/typedarray/ArrayBuffer.scala | 2 + .../scalajs/js/typedarray/DataView.scala | 2 + .../scalajs/js/typedarray/Float32Array.scala | 3 + .../scalajs/js/typedarray/Float64Array.scala | 3 + .../scalajs/js/typedarray/Int16Array.scala | 3 + .../scalajs/js/typedarray/Int32Array.scala | 3 + .../scalajs/js/typedarray/Int8Array.scala | 3 + .../scalajs/js/typedarray/Uint16Array.scala | 3 + .../scalajs/js/typedarray/Uint32Array.scala | 3 + .../scalajs/js/typedarray/Uint8Array.scala | 3 + .../js/typedarray/Uint8ClampedArray.scala | 3 + .../scala/scalajs/runtime/RuntimeString.scala | 3 +- project/Build.scala | 6 +- .../scalajs/testinterface/HTMLRunner.scala | 4 +- .../scalajs/testinterface/internal/Com.scala | 4 +- .../resources/ScalaJSDefinedTestNatives.js | 2 + .../compiler/InteroperabilityTest.scala | 137 +++- .../testsuite/compiler/ReflectionTest.scala | 4 +- .../testsuite/compiler/RuntimeTypesTest.scala | 4 +- .../testsuite/jsinterop/ExportsTest.scala | 4 +- .../jsinterop/JSNativeInPackage.scala | 73 ++- .../testsuite/jsinterop/JSSymbolTest.scala | 16 +- .../testsuite/jsinterop/MiscInteropTest.scala | 2 +- .../jsinterop/ScalaJSDefinedTest.scala | 16 +- 48 files changed, 1212 insertions(+), 164 deletions(-) create mode 100644 compiler/src/test/scala/org/scalajs/core/compiler/test/MissingJSGlobalDeprecationsSuppressedTest.scala create mode 100644 compiler/src/test/scala/org/scalajs/core/compiler/test/MissingJSGlobalDeprecationsTest.scala create mode 100644 library/src/main/scala/scala/scalajs/js/annotation/JSGlobal.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 8b76752b22..2421beeabe 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -67,6 +67,7 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val JSExportStaticAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportStatic") lazy val JSExportTopLevelAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportTopLevel") lazy val JSImportAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSImport") + lazy val JSGlobalAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSGlobal") lazy val JSGlobalScopeAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSGlobalScope") lazy val ScalaJSDefinedAnnotation = getRequiredClass("scala.scalajs.js.annotation.ScalaJSDefined") lazy val SJSDefinedAnonymousClassAnnotation = getRequiredClass("scala.scalajs.js.annotation.SJSDefinedAnonymousClass") diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala index 3362f3348d..b3cf7936fd 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala @@ -191,11 +191,7 @@ trait JSGlobalAddons extends JSDefinitions */ def jsNameOf(sym: Symbol): JSName = { sym.getAnnotation(JSNameAnnotation).fold[JSName] { - val base = sym.unexpandedName.decoded.stripSuffix("_=") - val name = - if (!sym.isMethod) base.stripSuffix(" ") - else base - JSName.Literal(name) + JSName.Literal(defaultJSNameOf(sym)) } { annotation => annotation.args.head match { case Literal(Constant(name: String)) => JSName.Literal(name) @@ -204,6 +200,12 @@ trait JSGlobalAddons extends JSDefinitions } } + def defaultJSNameOf(sym: Symbol): String = { + val base = sym.unexpandedName.decoded.stripSuffix("_=") + if (!sym.isMethod) base.stripSuffix(" ") + else base + } + /** Gets the fully qualified JS name of a static module Symbol compiled * with the 0.6.8 binary format or earlier. */ diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 64f8e64719..ee7a8ec579 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -75,6 +75,11 @@ abstract class PrepJSInterop extends plugins.PluginComponent val scala_ = newTypeName("scala") // not defined in 2.10's tpnme } + private final val SuppressMissingJSGlobalDeprecationsMsg = { + "\n (you can suppress this warning in 0.6.x by passing the option " + + "`-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac)" + } + class JSInteropTransformer(unit: CompilationUnit) extends Transformer { // Force evaluation of JSDynamicLiteral: Strangely, we are unable to find @@ -546,6 +551,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent if (shouldCheckLiterals) { checkJSNameArgument(implDef) + checkJSGlobalLiteral(sym) checkJSImportLiteral(sym) } @@ -689,7 +695,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent if (annotSym != JSNameAnnotation) { reporter.error(annot.pos, "Classes and objects nested in a JS native object cannot " + - s"have an ${annotSym.nameString} annotation.") + s"have an @${annotSym.nameString} annotation.") } else if (annot.args.head.tpe.typeSymbol != StringClass) { reporter.error(annot.pos, "Implementation restriction: @JSName with a js.Symbol is not " + @@ -710,10 +716,18 @@ abstract class PrepJSInterop extends plugins.PluginComponent JSNativeLoadSpec.Import(module, path :+ jsName) } } else { + def parsePath(pathName: String): List[String] = + pathName.split('.').toList + + def needsExplicitJSName = { + (enclosingOwner is OwnerKind.ScalaMod) && + !sym.owner.isPackageObjectClass + } + def globalFromName = { val path = jsInterop.jsNameOf(sym) match { - case JSName.Literal(name) => - name.split('.').toList + case JSName.Literal(pathName) => + parsePath(pathName) case JSName.Computed(_) => // this happens in erroneous cases that report a compile error List("") @@ -730,38 +744,60 @@ abstract class PrepJSInterop extends plugins.PluginComponent } JSNativeLoadSpec.Global(Nil) + case Some(annot) if annot.symbol == JSGlobalAnnotation => + val pathName = annot.stringArg(0).getOrElse { + if (needsExplicitJSName) { + reporter.error(annot.pos, + "Native JS classes and objects inside non-native objects " + + "must have an explicit name in @JSGlobal") + } + jsInterop.defaultJSNameOf(sym) + } + JSNativeLoadSpec.Global(parsePath(pathName)) + case Some(annot) if annot.symbol == JSImportAnnotation => val module = annot.stringArg(0).getOrElse { "" // do not care because it does not compile anyway } - annot.stringArg(1).fold { - JSNativeLoadSpec.Import(module, Nil) - } { pathName => - val path = pathName.split('.').toList - JSNativeLoadSpec.Import(module, path) - } + val path = annot.stringArg(1).fold[List[String]](Nil)(parsePath) + JSNativeLoadSpec.Import(module, path) case Some(annot) if annot.symbol == JSNameAnnotation => + if (!scalaJSOpts.suppressMissingJSGlobalDeprecations) { + reporter.warning(annot.pos, + "@JSName on top-level native JS classes and objects " + + "(or native JS classes and objects inside Scala objects) " + + "is deprecated, and should be replaced by @JSGlobal (with " + + "the same meaning). This will be enforced in 1.0." + + SuppressMissingJSGlobalDeprecationsMsg) + } + globalFromName case None => - val needsExplicitJSName = { - (enclosingOwner is OwnerKind.ScalaMod) && - !sym.owner.isPackageObjectClass - } - if (needsExplicitJSName) { if (sym.isModuleClass) { reporter.error(pos, "Native JS objects inside non-native objects must " + - "have an @JSName or @JSImport annotation") + "have an @JSGlobal or @JSImport annotation") } else { // This should be an error, but we erroneously allowed that before reporter.warning(pos, "Native JS classes inside non-native objects should " + - "have an @JSName or @JSImport annotation. " + + "have an @JSGlobal or @JSImport annotation. " + "This will be enforced in 1.0.") } + } else { + if (!scalaJSOpts.suppressMissingJSGlobalDeprecations && + !sym.isPackageObjectClass) { + reporter.warning(pos, + "Top-level native JS classes and objects should have an " + + "@JSGlobal or @JSImport annotation. This will be " + + "enforced in 1.0.\n" + + " If migrating from 0.6.14 or earlier, the equivalent " + + "behavior is an @JSGlobal without parameter." + + SuppressMissingJSGlobalDeprecationsMsg) + } } globalFromName @@ -883,7 +919,10 @@ abstract class PrepJSInterop extends plugins.PluginComponent reporter.error(tree.pos, "Methods in a js.Any may not be @native") } - if (sym.hasAnnotation(JSImportAnnotation)) { + if (sym.hasAnnotation(JSGlobalAnnotation)) { + reporter.error(tree.pos, + "Methods and fields cannot be annotated with @JSGlobal.") + } else if (sym.hasAnnotation(JSImportAnnotation)) { reporter.error(tree.pos, "Methods and fields cannot be annotated with @JSImport.") } @@ -1062,6 +1101,10 @@ abstract class PrepJSInterop extends plugins.PluginComponent "Non JS-native classes, traits and objects should not have an " + "@JSName annotation, as it does not have any effect. " + "This will be enforced in 1.0.") + } else if (annot.symbol == JSGlobalAnnotation) { + reporter.error(annot.pos, + "Non JS-native classes, traits and objects may not have an " + + "@JSGlobal annotation.") } else if (annot.symbol == JSImportAnnotation) { reporter.error(annot.pos, "Non JS-native classes, traits and objects may not have an " + @@ -1155,6 +1198,26 @@ abstract class PrepJSInterop extends plugins.PluginComponent def isPrivateMaybeWithin(sym: Symbol): Boolean = sym.isPrivate || (sym.hasAccessBoundary && !sym.isProtected) + /** Checks that the optional argument to `@JSGlobal` on [[sym]] is a literal. + * + * Reports an error on each annotation where this is not the case. + */ + private def checkJSGlobalLiteral(sym: Symbol): Unit = { + for { + annot <- sym.getAnnotation(JSGlobalAnnotation) + if annot.args.nonEmpty + } { + assert(annot.args.size == 1, + s"@JSGlobal annotation $annot has more than 1 argument") + + val argIsValid = annot.stringArg(0).isDefined + if (!argIsValid) { + reporter.error(annot.args(0).pos, + "The argument to @JSGlobal must be a literal string.") + } + } + } + /** Checks that arguments to `@JSImport` on [[sym]] are literals. * * The second argument can also be the singleton `JSImport.Namespace` @@ -1327,8 +1390,9 @@ abstract class PrepJSInterop extends plugins.PluginComponent } else { reporter.error(annot.pos, "Native JS classes and objects can only have one annotation " + - "among JSName, JSImport and JSGlobalScope (extending " + - "js.GlobalScope is treated as having @JSGlobalScope).") + "among JSName, JSGlobal, JSImport and JSGlobalScope " + + "(extending js.GlobalScope is treated as having " + + "@JSGlobalScope).") } } @@ -1336,8 +1400,10 @@ abstract class PrepJSInterop extends plugins.PluginComponent } } - private lazy val JSNativeLoadingSpecAnnots: Set[Symbol] = - Set(JSNameAnnotation, JSImportAnnotation, JSGlobalScopeAnnotation) + private lazy val JSNativeLoadingSpecAnnots: Set[Symbol] = { + Set(JSNameAnnotation, JSGlobalAnnotation, JSImportAnnotation, + JSGlobalScopeAnnotation) + } private lazy val ScalaEnumClass = getRequiredClass("scala.Enumeration") private lazy val WasPublicBeforeTyperClass = diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala index b56305fb97..2008d5f26b 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala @@ -22,6 +22,9 @@ trait ScalaJSOptions { /** Should we suppress deprecations of exports coming from 0.6.15? */ def suppressExportDeprecations: Boolean + /** Should we suppress deprecations related to missing `@JSGlobal`? */ + def suppressMissingJSGlobalDeprecations: Boolean + /** which source locations in source maps should be relativized (or where * should they be mapped to)? */ def sourceURIMaps: List[URIMap] diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala index 57b39e4045..d49db4c23d 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala @@ -45,6 +45,7 @@ class ScalaJSPlugin(val global: Global) extends NscPlugin { import ScalaJSOptions.URIMap var fixClassOf: Boolean = false var suppressExportDeprecations: Boolean = false + var suppressMissingJSGlobalDeprecations: Boolean = false lazy val sourceURIMaps: List[URIMap] = { if (_sourceURIMaps.nonEmpty) _sourceURIMaps.reverse @@ -115,6 +116,8 @@ class ScalaJSPlugin(val global: Global) extends NscPlugin { } } else if (option == "suppressExportDeprecations") { suppressExportDeprecations = true + } else if (option == "suppressMissingJSGlobalDeprecations") { + suppressMissingJSGlobalDeprecations = true // The following options are deprecated (how do we show this to the user?) } else if (option.startsWith("relSourceMap:")) { val uriStr = option.stripPrefix("relSourceMap:") diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/DiverseErrorsTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/DiverseErrorsTest.scala index 0cbe3f91e8..88cd50b182 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/DiverseErrorsTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/DiverseErrorsTest.scala @@ -58,9 +58,9 @@ class DiverseErrorsTest extends DirectTest with TestHelpers { """ """ - @js.native class NativeJSClass extends js.Object + @js.native @JSGlobal class NativeJSClass extends js.Object @js.native trait NativeJSTrait extends js.Object - @js.native object NativeJSObject extends js.Object + @js.native @JSGlobal object NativeJSObject extends js.Object @ScalaJSDefined class JSClass extends js.Object @ScalaJSDefined trait JSTrait extends js.Object @@ -145,9 +145,9 @@ class DiverseErrorsTest extends DirectTest with TestHelpers { """ """ - @js.native class NativeJSClass extends js.Object + @js.native @JSGlobal class NativeJSClass extends js.Object @js.native trait NativeJSTrait extends js.Object - @js.native object NativeJSObject extends js.Object + @js.native @JSGlobal object NativeJSObject extends js.Object @ScalaJSDefined class JSClass extends js.Object @ScalaJSDefined trait JSTrait extends js.Object @@ -212,7 +212,7 @@ class DiverseErrorsTest extends DirectTest with TestHelpers { import scala.scalajs.runtime object ScalaObject - @js.native object NativeJSObject extends js.Object + @js.native @JSGlobal object NativeJSObject extends js.Object @ScalaJSDefined object JSObject extends js.Object object A { @@ -239,9 +239,9 @@ class DiverseErrorsTest extends DirectTest with TestHelpers { class ScalaClass trait ScalaTrait - @js.native class NativeJSClass extends js.Object + @js.native @JSGlobal class NativeJSClass extends js.Object @js.native trait NativeJSTrait extends js.Object - @js.native object NativeJSObject extends js.Object + @js.native @JSGlobal object NativeJSObject extends js.Object @ScalaJSDefined class JSClass extends js.Object @ScalaJSDefined trait JSTrait extends js.Object diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index 907cec0a1c..60508bce30 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -577,6 +577,7 @@ class JSExportTest extends DirectTest with TestHelpers { @JSExport @js.native + @JSGlobal("Dummy") object A extends js.Object """ hasErrors """ @@ -603,6 +604,7 @@ class JSExportTest extends DirectTest with TestHelpers { @JSExport @js.native + @JSGlobal("Dummy") class A extends js.Object { @JSExport def this(x: Int) = this() @@ -612,7 +614,7 @@ class JSExportTest extends DirectTest with TestHelpers { |newSource1.scala:5: error: You may not export a native JS class or object | @JSExport | ^ - |newSource1.scala:8: error: You may not export a constructor of a subclass of js.Any + |newSource1.scala:9: error: You may not export a constructor of a subclass of js.Any | @JSExport | ^ """ @@ -626,13 +628,14 @@ class JSExportTest extends DirectTest with TestHelpers { import scala.scalajs.js @js.native + @JSGlobal("Dummy") class A extends js.Object { @JSExport def foo: Int = js.native } """ hasErrors """ - |newSource1.scala:7: error: You may not export a method of a subclass of js.Any + |newSource1.scala:8: error: You may not export a method of a subclass of js.Any | @JSExport | ^ """ @@ -1724,13 +1727,14 @@ class JSExportTest extends DirectTest with TestHelpers { class StaticContainer extends js.Object @js.native + @JSGlobal("Dummy") object StaticContainer extends js.Object { @JSExportStatic def a(): Unit = js.native } """ hasErrors """ - |newSource1.scala:8: error: You may not export a method of a subclass of js.Any + |newSource1.scala:9: error: You may not export a method of a subclass of js.Any | @JSExportStatic | ^ """ @@ -1769,6 +1773,7 @@ class JSExportTest extends DirectTest with TestHelpers { """ @js.native + @JSGlobal("Dummy") class StaticContainer extends js.Object object StaticContainer { @@ -1777,7 +1782,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Only a static object whose companion class is a Scala.js-defined JS class may export its members as static. + |newSource1.scala:8: error: Only a static object whose companion class is a Scala.js-defined JS class may export its members as static. | @JSExportStatic | ^ """ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index 29586a461f..24fd795e06 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -17,6 +17,8 @@ class JSInteropTest extends DirectTest with TestHelpers { private val JSNativeLoadSpecAnnots = Seq( "JSName" -> "@JSName(\"foo\")", + "JSGlobal" -> "@JSGlobal", + "JSGlobal" -> "@JSGlobal(\"foo\")", "JSImport" -> "@JSImport(\"foo\", \"bar\")", "JSGlobalScope" -> "@JSGlobalScope" ) @@ -24,18 +26,32 @@ class JSInteropTest extends DirectTest with TestHelpers { @Test def warnNoJSNativeAnnotation: Unit = { - for { - obj <- Seq("class", "trait", "object") - } yield { - s""" - $obj A extends js.Object - """ hasWarns - s""" - |newSource1.scala:5: warning: Classes, traits and objects inheriting from js.Any should be annotated with @js.native, unless they have @ScalaJSDefined. The default will switch to Scala.js-defined in the next major version of Scala.js. - | $obj A extends js.Object - | ${" " * obj.length} ^ - """ - } + """ + class A extends js.Object + """ containsWarns + """ + |newSource1.scala:5: warning: Classes, traits and objects inheriting from js.Any should be annotated with @js.native, unless they have @ScalaJSDefined. The default will switch to Scala.js-defined in the next major version of Scala.js. + | class A extends js.Object + | ^ + """ + + """ + object A extends js.Object + """ containsWarns + """ + |newSource1.scala:5: warning: Classes, traits and objects inheriting from js.Any should be annotated with @js.native, unless they have @ScalaJSDefined. The default will switch to Scala.js-defined in the next major version of Scala.js. + | object A extends js.Object + | ^ + """ + + """ + trait A extends js.Object + """ hasWarns + """ + |newSource1.scala:5: warning: Classes, traits and objects inheriting from js.Any should be annotated with @js.native, unless they have @ScalaJSDefined. The default will switch to Scala.js-defined in the next major version of Scala.js. + | trait A extends js.Object + | ^ + """ } @@ -165,6 +181,53 @@ class JSInteropTest extends DirectTest with TestHelpers { } + @Test + def noJSGlobalAnnotOnNonJSNative: Unit = { + + for { + obj <- Seq("class", "trait", "object") + } yield { + s""" + @ScalaJSDefined + @JSGlobal + $obj A extends js.Object + + @ScalaJSDefined + @JSGlobal("Foo") + $obj B extends js.Object + """ hasErrors + s""" + |newSource1.scala:6: error: Non JS-native classes, traits and objects may not have an @JSGlobal annotation. + | @JSGlobal + | ^ + |newSource1.scala:10: error: Non JS-native classes, traits and objects may not have an @JSGlobal annotation. + | @JSGlobal("Foo") + | ^ + """ + } + + for { + obj <- Seq("class", "trait", "object") + } yield { + s""" + @JSGlobal + $obj A + + @JSGlobal("Foo") + $obj B + """ hasErrors + s""" + |newSource1.scala:5: error: Non JS-native classes, traits and objects may not have an @JSGlobal annotation. + | @JSGlobal + | ^ + |newSource1.scala:8: error: Non JS-native classes, traits and objects may not have an @JSGlobal annotation. + | @JSGlobal("Foo") + | ^ + """ + } + + } + @Test def noJSImportAnnotOnNonJSNative: Unit = { @@ -226,6 +289,33 @@ class JSInteropTest extends DirectTest with TestHelpers { } + @Test + def noJSGlobalAnnotOnTrait: Unit = { + + s""" + @js.native + @JSGlobal + trait A extends js.Object + """ hasErrors + s""" + |newSource1.scala:6: error: Traits may not have an @JSGlobal annotation. + | @JSGlobal + | ^ + """ + + s""" + @js.native + @JSGlobal("Foo") + trait A extends js.Object + """ hasErrors + s""" + |newSource1.scala:6: error: Traits may not have an @JSGlobal annotation. + | @JSGlobal("Foo") + | ^ + """ + + } + @Test def noJSImportAnnotOnTrait: Unit = { @@ -253,7 +343,7 @@ class JSInteropTest extends DirectTest with TestHelpers { else if (firstAnnotName == "JSGlobalScope" && secondAnnotName == "JSName") "warning: An @JSName annotation is ignored in the presence of @JSGlobalScope (or extends js.GlobalScope), and should be removed. This will be enforced in 1.0." else - "error: Native JS classes and objects can only have one annotation among JSName, JSImport and JSGlobalScope (extending js.GlobalScope is treated as having @JSGlobalScope)." + "error: Native JS classes and objects can only have one annotation among JSName, JSGlobal, JSImport and JSGlobalScope (extending js.GlobalScope is treated as having @JSGlobalScope)." } val onlyWarn = expectedMessageShort.startsWith("warning: ") @@ -266,6 +356,19 @@ class JSInteropTest extends DirectTest with TestHelpers { """ } + val jsNameWarning = if (firstAnnotName == "JSName") { + s""" + |newSource1.scala:6: warning: @JSName on top-level native JS classes and objects (or native JS classes and objects inside Scala objects) is deprecated, and should be replaced by @JSGlobal (with the same meaning). This will be enforced in 1.0. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) + |$firstAnnot + | ^ + """.trim + } else { + "" + } + + val fullExpectedMessage = expectedMessage + jsNameWarning + val kinds = { if (firstAnnotName == "JSGlobalScope" || secondAnnotName == "JSGlobalScope") Seq("object") @@ -284,9 +387,9 @@ class JSInteropTest extends DirectTest with TestHelpers { } if (onlyWarn) - snippet hasWarns expectedMessage + snippet hasWarns fullExpectedMessage else - snippet hasErrors expectedMessage + snippet hasErrors fullExpectedMessage } } } @@ -354,11 +457,14 @@ class JSInteropTest extends DirectTest with TestHelpers { inner <- Seq("class", "trait", "object") innerSJSDefined <- Seq(false, true) } yield { + val jsGlobalAnnot = + if (outer == "trait") "" + else "@JSGlobal" val innerLine = if (innerSJSDefined) s"@ScalaJSDefined $inner A extends js.Object" else s"$inner A" s""" - @js.native + @js.native $jsGlobalAnnot $outer A extends js.Object { $innerLine } @@ -380,12 +486,13 @@ class JSInteropTest extends DirectTest with TestHelpers { } yield { s""" @js.native + @JSGlobal object A extends js.Object { $inner A } """ hasErrors s""" - |newSource1.scala:7: error: Native JS objects cannot contain inner Scala traits, classes or objects (i.e., not extending js.Any) + |newSource1.scala:8: error: Native JS objects cannot contain inner Scala traits, classes or objects (i.e., not extending js.Any) | $inner A | ${" " * inner.length} ^ """ @@ -397,10 +504,10 @@ class JSInteropTest extends DirectTest with TestHelpers { def noNonSyntheticCompanionInsideNativeJSObject: Unit = { // See #1891: The default parameter generates a synthetic companion object - // The synthetic companion should be allowed, but it may not be expliclit + // The synthetic companion should be allowed, but it may not be explicit """ - @js.native object A extends js.Object { + @js.native @JSGlobal object A extends js.Object { @js.native class B(x: Int = ???) extends js.Object object B } @@ -412,7 +519,7 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @js.native object A extends js.Object { + @js.native @JSGlobal object A extends js.Object { @js.native class B(x: Int = ???) extends js.Object } """.succeeds @@ -427,12 +534,13 @@ class JSInteropTest extends DirectTest with TestHelpers { } yield { s""" @js.native + @JSGlobal object A extends js.Object { @ScalaJSDefined $inner A extends js.Object } """ hasErrors s""" - |newSource1.scala:7: error: Native JS objects cannot contain inner Scala.js-defined JS classes or objects + |newSource1.scala:8: error: Native JS objects cannot contain inner Scala.js-defined JS classes or objects | @ScalaJSDefined $inner A extends js.Object | ${" " * inner.length} ^ """ @@ -445,6 +553,7 @@ class JSInteropTest extends DirectTest with TestHelpers { """ @js.native + @JSGlobal class A extends js.Object { def foo_=(x: Int): Int = js.native def bar_=(x: Int, y: Int): Unit = js.native @@ -453,16 +562,16 @@ class JSInteropTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Raw JS setters must return Unit + |newSource1.scala:8: error: Raw JS setters must return Unit | def foo_=(x: Int): Int = js.native | ^ - |newSource1.scala:8: error: Raw JS setters must have exactly one argument + |newSource1.scala:9: error: Raw JS setters must have exactly one argument | def bar_=(x: Int, y: Int): Unit = js.native | ^ - |newSource1.scala:9: error: Raw JS setters may not have repeated params + |newSource1.scala:10: error: Raw JS setters may not have repeated params | def goo_=(x: Int*): Unit = js.native | ^ - |newSource1.scala:10: error: Raw JS setters may not have default params + |newSource1.scala:11: error: Raw JS setters may not have default params | def hoo_=(x: Int = 1): Unit = js.native | ^ """ @@ -474,6 +583,7 @@ class JSInteropTest extends DirectTest with TestHelpers { """ @js.native + @JSGlobal class A extends js.Object { @js.annotation.JSBracketAccess def foo(): Int = js.native @@ -483,49 +593,52 @@ class JSInteropTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: @JSBracketAccess methods must have one or two parameters + |newSource1.scala:9: error: @JSBracketAccess methods must have one or two parameters | def foo(): Int = js.native | ^ - |newSource1.scala:11: error: @JSBracketAccess methods must have one or two parameters + |newSource1.scala:12: error: @JSBracketAccess methods must have one or two parameters | def bar(x: Int, y: Int, z: Int): Int = js.native | ^ """ """ @js.native + @JSGlobal class A extends js.Object { @js.annotation.JSBracketAccess def foo(x: Int, y: Int): Int = js.native } """ hasErrors """ - |newSource1.scala:8: error: @JSBracketAccess methods with two parameters must return Unit + |newSource1.scala:9: error: @JSBracketAccess methods with two parameters must return Unit | def foo(x: Int, y: Int): Int = js.native | ^ """ """ @js.native + @JSGlobal class A extends js.Object { @js.annotation.JSBracketAccess def bar(x: Int*): Int = js.native } """ hasErrors """ - |newSource1.scala:8: error: @JSBracketAccess methods may not have repeated parameters + |newSource1.scala:9: error: @JSBracketAccess methods may not have repeated parameters | def bar(x: Int*): Int = js.native | ^ """ """ @js.native + @JSGlobal class A extends js.Object { @js.annotation.JSBracketAccess def bar(x: Int = 1): Int = js.native } """ hasErrors """ - |newSource1.scala:8: error: @JSBracketAccess methods may not have default parameters + |newSource1.scala:9: error: @JSBracketAccess methods may not have default parameters | def bar(x: Int = 1): Int = js.native | ^ """ @@ -537,13 +650,14 @@ class JSInteropTest extends DirectTest with TestHelpers { """ @js.native + @JSGlobal class A extends js.Object { @js.annotation.JSBracketCall def foo(): Int = js.native } """ hasErrors """ - |newSource1.scala:8: error: @JSBracketCall methods must have at least one non-repeated parameter + |newSource1.scala:9: error: @JSBracketCall methods must have at least one non-repeated parameter | def foo(): Int = js.native | ^ """ @@ -555,21 +669,24 @@ class JSInteropTest extends DirectTest with TestHelpers { """ trait A + @js.native + @JSGlobal class B extends js.Object with A """ hasErrors """ - |newSource1.scala:7: error: B extends A which does not extend js.Any. + |newSource1.scala:9: error: B extends A which does not extend js.Any. | class B extends js.Object with A | ^ """ """ @js.native + @JSGlobal class B extends js.Object with Serializable """ hasErrors """ - |newSource1.scala:6: error: B extends scala.Serializable which does not extend js.Any. + |newSource1.scala:7: error: B extends scala.Serializable which does not extend js.Any. | class B extends js.Object with Serializable | ^ """ @@ -581,20 +698,22 @@ class JSInteropTest extends DirectTest with TestHelpers { """ @js.native + @JSGlobal case class A(x: Int) extends js.Object """ hasErrors """ - |newSource1.scala:6: error: Classes and objects extending js.Any may not have a case modifier + |newSource1.scala:7: error: Classes and objects extending js.Any may not have a case modifier | case class A(x: Int) extends js.Object | ^ """ """ @js.native + @JSGlobal case object B extends js.Object """ hasErrors """ - |newSource1.scala:6: error: Classes and objects extending js.Any may not have a case modifier + |newSource1.scala:7: error: Classes and objects extending js.Any may not have a case modifier | case object B extends js.Object | ^ """ @@ -636,11 +755,15 @@ class JSInteropTest extends DirectTest with TestHelpers { if (outerSJSDefined) s"@ScalaJSDefined $outer A extends js.Object" else s"$outer A" + val jsGlobalAnnot = + if (inner == "trait") "" + else "@JSGlobal" + val errTrg = if (inner == "object") "objects" else "classes" s""" $outerLine { - @js.native + @js.native $jsGlobalAnnot $inner Inner extends js.Object } """ hasErrors @@ -724,6 +847,22 @@ class JSInteropTest extends DirectTest with TestHelpers { } + @Test + def noJSGlobalOnJSGlobalScope: Unit = { + + """ + @js.native + @JSGlobal + object Bar extends js.GlobalScope + """ hasErrors + """ + |newSource1.scala:6: error: Native JS classes and objects can only have one annotation among JSName, JSGlobal, JSImport and JSGlobalScope (extending js.GlobalScope is treated as having @JSGlobalScope). + | @JSGlobal + | ^ + """ + + } + @Test def noJSImportOnJSGlobalScope: Unit = { @@ -733,7 +872,7 @@ class JSInteropTest extends DirectTest with TestHelpers { object Bar extends js.GlobalScope """ hasErrors """ - |newSource1.scala:6: error: Native JS classes and objects can only have one annotation among JSName, JSImport and JSGlobalScope (extending js.GlobalScope is treated as having @JSGlobalScope). + |newSource1.scala:6: error: Native JS classes and objects can only have one annotation among JSName, JSGlobal, JSImport and JSGlobalScope (extending js.GlobalScope is treated as having @JSGlobalScope). | @JSImport("foo", JSImport.Namespace) | ^ """ @@ -747,12 +886,13 @@ class JSInteropTest extends DirectTest with TestHelpers { object A { def a = { @js.native + @JSGlobal class B extends js.Object } } """ hasErrors """ - |newSource1.scala:8: error: Local native JS classes and objects are not allowed + |newSource1.scala:9: error: Local native JS classes and objects are not allowed | class B extends js.Object | ^ """ @@ -766,12 +906,13 @@ class JSInteropTest extends DirectTest with TestHelpers { object A { def a = { @js.native + @JSGlobal object B extends js.Object } } """ hasErrors """ - |newSource1.scala:8: error: Local native JS classes and objects are not allowed + |newSource1.scala:9: error: Local native JS classes and objects are not allowed | object B extends js.Object | ^ """ @@ -783,13 +924,14 @@ class JSInteropTest extends DirectTest with TestHelpers { """ @js.native + @JSGlobal class A extends js.Object { @native def value: Int = js.native } """ hasErrors """ - |newSource1.scala:8: error: Methods in a js.Any may not be @native + |newSource1.scala:9: error: Methods in a js.Any may not be @native | def value: Int = js.native | ^ """ @@ -801,16 +943,17 @@ class JSInteropTest extends DirectTest with TestHelpers { """ @js.native + @JSGlobal class A extends js.Object { def value: Int = ??? val x: Int = ??? } """ hasWarns """ - |newSource1.scala:7: warning: Members of traits, classes and objects extending js.Any may only contain members that call js.native. This will be enforced in 1.0. + |newSource1.scala:8: warning: Members of traits, classes and objects extending js.Any may only contain members that call js.native. This will be enforced in 1.0. | def value: Int = ??? | ^ - |newSource1.scala:8: warning: Members of traits, classes and objects extending js.Any may only contain members that call js.native. This will be enforced in 1.0. + |newSource1.scala:9: warning: Members of traits, classes and objects extending js.Any may only contain members that call js.native. This will be enforced in 1.0. | val x: Int = ??? | ^ """ @@ -822,6 +965,7 @@ class JSInteropTest extends DirectTest with TestHelpers { """ @js.native + @JSGlobal abstract class A extends js.Object { def value: Int val x: Int @@ -843,13 +987,14 @@ class JSInteropTest extends DirectTest with TestHelpers { """ @js.native + @JSGlobal class A(x: Int, y: Int) extends js.Object { def this(x: Int) = this(x, 5) def this() = this(7) } """ hasErrors """ - |newSource1.scala:8: error: A secondary constructor of a class extending js.Any may only call the primary constructor + |newSource1.scala:9: error: A secondary constructor of a class extending js.Any may only call the primary constructor | def this() = this(7) | ^ """ @@ -877,16 +1022,17 @@ class JSInteropTest extends DirectTest with TestHelpers { """ @js.native + @JSGlobal class A extends js.Object { def foo = js.native val bar = js.native } """ hasWarns """ - |newSource1.scala:7: warning: The type of foo got inferred as Nothing. To suppress this warning, explicitly ascribe the type. + |newSource1.scala:8: warning: The type of foo got inferred as Nothing. To suppress this warning, explicitly ascribe the type. | def foo = js.native | ^ - |newSource1.scala:8: warning: The type of bar got inferred as Nothing. To suppress this warning, explicitly ascribe the type. + |newSource1.scala:9: warning: The type of bar got inferred as Nothing. To suppress this warning, explicitly ascribe the type. | val bar = js.native | ^ """ @@ -894,7 +1040,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } @Test - def noNativeClassObjectWithoutJSNameInsideScalaObject: Unit = { + def noNativeClassObjectWithoutExplicitNameInsideScalaObject: Unit = { """ object A { @@ -903,7 +1049,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } """ hasWarns """ - |newSource1.scala:7: warning: Native JS classes inside non-native objects should have an @JSName or @JSImport annotation. This will be enforced in 1.0. + |newSource1.scala:7: warning: Native JS classes inside non-native objects should have an @JSGlobal or @JSImport annotation. This will be enforced in 1.0. | class B extends js.Object | ^ """ @@ -915,35 +1061,106 @@ class JSInteropTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Native JS objects inside non-native objects must have an @JSName or @JSImport annotation + |newSource1.scala:7: error: Native JS objects inside non-native objects must have an @JSGlobal or @JSImport annotation | object B extends js.Object | ^ """ + """ + object A { + @js.native + @JSGlobal + class B extends js.Object + } + """ hasErrors + """ + |newSource1.scala:7: error: Native JS classes and objects inside non-native objects must have an explicit name in @JSGlobal + | @JSGlobal + | ^ + """ + + """ + object A { + @js.native + @JSGlobal + object B extends js.Object + } + """ hasErrors + """ + |newSource1.scala:7: error: Native JS classes and objects inside non-native objects must have an explicit name in @JSGlobal + | @JSGlobal + | ^ + """ + // From issue #2401 """ package object A { @js.native object B extends js.Object + + @js.native + @JSGlobal + object C extends js.Object } - """.hasNoWarns + """ hasWarns + """ + |newSource1.scala:7: warning: Top-level native JS classes and objects should have an @JSGlobal or @JSImport annotation. This will be enforced in 1.0. + | If migrating from 0.6.14 or earlier, the equivalent behavior is an @JSGlobal without parameter. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) + | object B extends js.Object + | ^ + """ """ package object A { @js.native class B extends js.Object + + @js.native + @JSGlobal + class C extends js.Object } - """.hasNoWarns + """ hasWarns + """ + |newSource1.scala:7: warning: Top-level native JS classes and objects should have an @JSGlobal or @JSImport annotation. This will be enforced in 1.0. + | If migrating from 0.6.14 or earlier, the equivalent behavior is an @JSGlobal without parameter. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) + | class B extends js.Object + | ^ + """ """ object A { @JSName("InnerB") @js.native class B extends js.Object + @JSName("InnerC") @js.native object C extends js.Object } + """ hasWarns + """ + |newSource1.scala:6: warning: @JSName on top-level native JS classes and objects (or native JS classes and objects inside Scala objects) is deprecated, and should be replaced by @JSGlobal (with the same meaning). This will be enforced in 1.0. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) + | @JSName("InnerB") + | ^ + |newSource1.scala:10: warning: @JSName on top-level native JS classes and objects (or native JS classes and objects inside Scala objects) is deprecated, and should be replaced by @JSGlobal (with the same meaning). This will be enforced in 1.0. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) + | @JSName("InnerC") + | ^ + """ + + """ + object A { + @JSGlobal("InnerB") + @js.native + class B extends js.Object + + @JSGlobal("InnerC") + @js.native + object C extends js.Object + } """.hasNoWarns """ @@ -951,6 +1168,7 @@ class JSInteropTest extends DirectTest with TestHelpers { @JSImport("InnerB", JSImport.Namespace) @js.native class B extends js.Object + @JSImport("InnerC", JSImport.Namespace) @js.native object C extends js.Object @@ -966,11 +1184,14 @@ class JSInteropTest extends DirectTest with TestHelpers { """ @js.native + @JSGlobal object A extends js.Object { @js.native class B extends js.Object + @js.native trait C extends js.Object + @js.native object D extends js.Object } @@ -979,7 +1200,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } @Test - def nestedJSGlobalScopeWithoutJSName: Unit = { + def nestedJSGlobalScopeWithoutExplicitName: Unit = { // #2319 """ object Outer { @@ -1000,11 +1221,12 @@ class JSInteropTest extends DirectTest with TestHelpers { @ScalaJSDefined object A extends js.Object { @js.native + @JSGlobal $inner B extends js.Object } """ hasErrors s""" - |newSource1.scala:8: error: Scala.js-defined JS objects may not have inner native JS classes or objects + |newSource1.scala:9: error: Scala.js-defined JS objects may not have inner native JS classes or objects | $inner B extends js.Object | ${" " * inner.length} ^ """ @@ -1024,6 +1246,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } @js.native + @JSGlobal class B extends js.Object { @JSName(A.a) def foo: Int = js.native @@ -1032,7 +1255,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:14: error: A string argument to JSName must be a literal string + |newSource1.scala:15: error: A string argument to JSName must be a literal string | @JSName(A.a) | ^ """ @@ -1057,9 +1280,17 @@ class JSInteropTest extends DirectTest with TestHelpers { |newSource1.scala:11: error: A string argument to JSName must be a literal string | @JSName(A.a) | ^ + |newSource1.scala:11: warning: @JSName on top-level native JS classes and objects (or native JS classes and objects inside Scala objects) is deprecated, and should be replaced by @JSGlobal (with the same meaning). This will be enforced in 1.0. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) + | @JSName(A.a) + | ^ |newSource1.scala:15: error: A string argument to JSName must be a literal string | @JSName(A.a) | ^ + |newSource1.scala:15: warning: @JSName on top-level native JS classes and objects (or native JS classes and objects inside Scala objects) is deprecated, and should be replaced by @JSGlobal (with the same meaning). This will be enforced in 1.0. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) + | @JSName(A.a) + | ^ """ } @@ -1075,6 +1306,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } @js.native + @JSGlobal class B extends js.Object { @JSName(js.Symbol()) def foo: Int = js.native @@ -1091,16 +1323,16 @@ class JSInteropTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:13: error: A js.Symbol argument to JSName must be a static, stable identifier + |newSource1.scala:14: error: A js.Symbol argument to JSName must be a static, stable identifier | @JSName(js.Symbol()) | ^ - |newSource1.scala:15: error: A js.Symbol argument to JSName must be a static, stable identifier + |newSource1.scala:16: error: A js.Symbol argument to JSName must be a static, stable identifier | @JSName(new A().a) | ^ - |newSource1.scala:21: error: A js.Symbol argument to JSName must be a static, stable identifier + |newSource1.scala:22: error: A js.Symbol argument to JSName must be a static, stable identifier | @JSName(js.Symbol()) | ^ - |newSource1.scala:23: error: A js.Symbol argument to JSName must be a static, stable identifier + |newSource1.scala:24: error: A js.Symbol argument to JSName must be a static, stable identifier | @JSName(new A().a) | ^ """ @@ -1139,11 +1371,169 @@ class JSInteropTest extends DirectTest with TestHelpers { } @Test - def noJSImportOnMembers: Unit = { + def noJSGlobalOnMembersOfClassesAndTraits: Unit = { + + for (outer <- Seq("class", "trait")) { + s""" + @js.native ${if (outer == "trait") "" else "@JSGlobal"} + $outer Foo extends js.Object { + @JSGlobal("bar1") + val bar1: Int = js.native + @JSGlobal("bar2") + var bar2: Int = js.native + @JSGlobal("bar3") + def bar3: Int = js.native + + @js.native + @JSGlobal("Inner") + class Inner extends js.Object + + @js.native + @JSGlobal("Inner") + object Inner extends js.Object + + @js.native + @JSGlobal + class InnerImplied extends js.Object + + @js.native + @JSGlobal + object InnerImplied extends js.Object + } + """ hasErrors + """ + |newSource1.scala:8: error: Methods and fields cannot be annotated with @JSGlobal. + | val bar1: Int = js.native + | ^ + |newSource1.scala:10: error: Methods and fields cannot be annotated with @JSGlobal. + | var bar2: Int = js.native + | ^ + |newSource1.scala:12: error: Methods and fields cannot be annotated with @JSGlobal. + | def bar3: Int = js.native + | ^ + |newSource1.scala:16: error: Native JS traits and classes may not have inner traits, classes or objects + | class Inner extends js.Object + | ^ + |newSource1.scala:20: error: Native JS traits and classes may not have inner traits, classes or objects + | object Inner extends js.Object + | ^ + |newSource1.scala:24: error: Native JS traits and classes may not have inner traits, classes or objects + | class InnerImplied extends js.Object + | ^ + |newSource1.scala:28: error: Native JS traits and classes may not have inner traits, classes or objects + | object InnerImplied extends js.Object + | ^ + """ + } + + } + + @Test + def noJSGlobalOnMembersOfObjects: Unit = { + + s""" + @js.native @JSGlobal + object Foo extends js.Object { + @JSGlobal("bar1") + val bar1: Int = js.native + @JSGlobal("bar2") + var bar2: Int = js.native + @JSGlobal("bar3") + def bar3: Int = js.native + + @js.native + @JSGlobal("Inner") + class Inner extends js.Object + + @js.native + @JSGlobal("Inner") + object Inner extends js.Object + + @js.native + @JSGlobal + class InnerImplied extends js.Object + @js.native + @JSGlobal + object InnerImplied extends js.Object + } + """ hasErrors """ - @js.native - class Foo extends js.Object { + |newSource1.scala:8: error: Methods and fields cannot be annotated with @JSGlobal. + | val bar1: Int = js.native + | ^ + |newSource1.scala:10: error: Methods and fields cannot be annotated with @JSGlobal. + | var bar2: Int = js.native + | ^ + |newSource1.scala:12: error: Methods and fields cannot be annotated with @JSGlobal. + | def bar3: Int = js.native + | ^ + |newSource1.scala:15: error: Classes and objects nested in a JS native object cannot have an @JSGlobal annotation. + | @JSGlobal("Inner") + | ^ + |newSource1.scala:19: error: Classes and objects nested in a JS native object cannot have an @JSGlobal annotation. + | @JSGlobal("Inner") + | ^ + |newSource1.scala:23: error: Classes and objects nested in a JS native object cannot have an @JSGlobal annotation. + | @JSGlobal + | ^ + |newSource1.scala:27: error: Classes and objects nested in a JS native object cannot have an @JSGlobal annotation. + | @JSGlobal + | ^ + """ + + } + + @Test + def noJSImportOnMembersOfClassesAndTraits: Unit = { + + for (outer <- Seq("class", "trait")) { + s""" + @js.native ${if (outer == "trait") "" else "@JSGlobal"} + $outer Foo extends js.Object { + @JSImport("bar1", JSImport.Namespace) + val bar1: Int = js.native + @JSImport("bar2", JSImport.Namespace) + var bar2: Int = js.native + @JSImport("bar3", JSImport.Namespace) + def bar3: Int = js.native + + @js.native + @JSImport("Inner", JSImport.Namespace) + class Inner extends js.Object + + @js.native + @JSImport("Inner", JSImport.Namespace) + object Inner extends js.Object + } + """ hasErrors + """ + |newSource1.scala:8: error: Methods and fields cannot be annotated with @JSImport. + | val bar1: Int = js.native + | ^ + |newSource1.scala:10: error: Methods and fields cannot be annotated with @JSImport. + | var bar2: Int = js.native + | ^ + |newSource1.scala:12: error: Methods and fields cannot be annotated with @JSImport. + | def bar3: Int = js.native + | ^ + |newSource1.scala:16: error: Native JS traits and classes may not have inner traits, classes or objects + | class Inner extends js.Object + | ^ + |newSource1.scala:20: error: Native JS traits and classes may not have inner traits, classes or objects + | object Inner extends js.Object + | ^ + """ + } + + } + + @Test + def noJSImportOnMembersOfObjects: Unit = { + + """ + @js.native @JSGlobal + object Foo extends js.Object { @JSImport("bar1", JSImport.Namespace) val bar1: Int = js.native @JSImport("bar2", JSImport.Namespace) @@ -1170,12 +1560,39 @@ class JSInteropTest extends DirectTest with TestHelpers { |newSource1.scala:12: error: Methods and fields cannot be annotated with @JSImport. | def bar3: Int = js.native | ^ - |newSource1.scala:16: error: Native JS traits and classes may not have inner traits, classes or objects - | class Inner extends js.Object - | ^ - |newSource1.scala:20: error: Native JS traits and classes may not have inner traits, classes or objects - | object Inner extends js.Object - | ^ + |newSource1.scala:15: error: Classes and objects nested in a JS native object cannot have an @JSImport annotation. + | @JSImport("Inner", JSImport.Namespace) + | ^ + |newSource1.scala:19: error: Classes and objects nested in a JS native object cannot have an @JSImport annotation. + | @JSImport("Inner", JSImport.Namespace) + | ^ + """ + + } + + @Test + def noNonLiteralJSGlobal: Unit = { + + """ + object A { + val a = "Hello" + } + + @JSGlobal(A.a) + @js.native + object B extends js.Object + + @JSGlobal(A.a) + @js.native + class C extends js.Object + """ hasErrors + """ + |newSource1.scala:9: error: The argument to @JSGlobal must be a literal string. + | @JSGlobal(A.a) + | ^ + |newSource1.scala:13: error: The argument to @JSGlobal must be a literal string. + | @JSGlobal(A.a) + | ^ """ } @@ -1336,10 +1753,15 @@ class JSInteropTest extends DirectTest with TestHelpers { @js.native $kind A extends js.Object """ hasErrors - """ + s""" |newSource1.scala:9: error: @JSName with a js.Symbol can only be used on members of JavaScript types | @JSName(Sym.sym) | ^ + |newSource1.scala:11: warning: Top-level native JS classes and objects should have an @JSGlobal or @JSImport annotation. This will be enforced in 1.0. + | If migrating from 0.6.14 or earlier, the equivalent behavior is an @JSGlobal without parameter. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) + | $kind A extends js.Object + | ${" " * kind.length} ^ """ } } @@ -1355,6 +1777,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } @js.native + @JSGlobal object Enclosing extends js.Object { @JSName(Sym.sym) @js.native @@ -1362,7 +1785,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:11: error: Implementation restriction: @JSName with a js.Symbol is not supported on nested native classes and objects + |newSource1.scala:12: error: Implementation restriction: @JSName with a js.Symbol is not supported on nested native classes and objects | @JSName(Sym.sym) | ^ """ @@ -1380,6 +1803,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } @js.native + @JSGlobal class A extends js.Object { @JSName(A.a) @JSName("foo") @@ -1387,7 +1811,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } """ hasWarns """ - |newSource1.scala:12: warning: A duplicate @JSName annotation is ignored. This will become an error in 1.0.0. + |newSource1.scala:13: warning: A duplicate @JSName annotation is ignored. This will become an error in 1.0.0. | @JSName("foo") | ^ """ @@ -2221,7 +2645,9 @@ class JSInteropTest extends DirectTest with TestHelpers { """ @ScalaJSDefined class A(x: Int = 1) extends js.Object + @js.native + @JSGlobal object A extends js.Object """ hasErrors """ @@ -2232,7 +2658,9 @@ class JSInteropTest extends DirectTest with TestHelpers { """ class A(x: Int = 1) + @js.native + @JSGlobal object A extends js.Object """ hasErrors """ @@ -2246,38 +2674,40 @@ class JSInteropTest extends DirectTest with TestHelpers { def noDefaultOverrideCrash: Unit = { """ @js.native + @JSGlobal class NativeBase extends js.Object { - def add(option: js.Any = js.native): js.Any = js.native + def add(option: js.Any = js.native): js.Any = js.native } @ScalaJSDefined class Derived extends NativeBase { - override def add(option: js.Any): js.Any = super.add(option) + override def add(option: js.Any): js.Any = super.add(option) } """ hasErrors """ - |newSource1.scala:11: error: When overriding a native method with default arguments, the overriding method must explicitly repeat the default arguments. - | override def add(option: js.Any): js.Any = super.add(option) - | ^ + |newSource1.scala:12: error: When overriding a native method with default arguments, the overriding method must explicitly repeat the default arguments. + | override def add(option: js.Any): js.Any = super.add(option) + | ^ """ """ @js.native trait NativeTrait extends js.Object { - def add(option: js.Any = js.native): js.Any = js.native + def add(option: js.Any = js.native): js.Any = js.native } @js.native + @JSGlobal class NativeBase extends NativeTrait @ScalaJSDefined class Derived extends NativeBase { - override def add(option: js.Any): js.Any = super.add(option) + override def add(option: js.Any): js.Any = super.add(option) } """ hasErrors """ - |newSource1.scala:15: error: When overriding a native method with default arguments, the overriding method must explicitly repeat the default arguments. - | override def add(option: js.Any): js.Any = super.add(option) - | ^ + |newSource1.scala:16: error: When overriding a native method with default arguments, the overriding method must explicitly repeat the default arguments. + | override def add(option: js.Any): js.Any = super.add(option) + | ^ """ } } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala index 71ef7cd7a0..3de7da1cfc 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala @@ -85,6 +85,7 @@ class JSOptionalTest extends DirectTest with TestHelpers { s""" @js.native + @JSGlobal class A extends js.Object { val a: js.UndefOr[Int] = js.native def b: js.UndefOr[Int] = js.native @@ -97,10 +98,10 @@ class JSOptionalTest extends DirectTest with TestHelpers { } """ hasErrors s""" - |newSource1.scala:13: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + |newSource1.scala:14: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. | override val a: js.UndefOr[Int] = js.undefined | ^ - |newSource1.scala:14: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + |newSource1.scala:15: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. | override def b: js.UndefOr[Int] = js.undefined | ^ """ @@ -113,6 +114,7 @@ class JSOptionalTest extends DirectTest with TestHelpers { } @js.native + @JSGlobal class B extends A @ScalaJSDefined @@ -122,10 +124,10 @@ class JSOptionalTest extends DirectTest with TestHelpers { } """ hasErrors s""" - |newSource1.scala:16: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + |newSource1.scala:17: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. | override val a: js.UndefOr[Int] = js.undefined | ^ - |newSource1.scala:17: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + |newSource1.scala:18: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. | override def b: js.UndefOr[Int] = js.undefined | ^ """ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/MissingJSGlobalDeprecationsSuppressedTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/MissingJSGlobalDeprecationsSuppressedTest.scala new file mode 100644 index 0000000000..1835be4059 --- /dev/null +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/MissingJSGlobalDeprecationsSuppressedTest.scala @@ -0,0 +1,88 @@ +package org.scalajs.core.compiler.test + +import org.scalajs.core.compiler.test.util._ +import org.junit.Test + +// scalastyle:off line.size.limit + +/* This is a copy of MissingJSGlobalDeprecationsTest, but with all the + * relevant deprecations suppressed. This tests the suppression mechanism. + */ +class MissingJSGlobalDeprecationsSuppressedTest + extends DirectTest with TestHelpers { + + override def extraArgs: List[String] = + super.extraArgs :+ "-P:scalajs:suppressMissingJSGlobalDeprecations" + + override def preamble: String = + """import scala.scalajs.js, js.annotation._ + """ + + @Test + def noWarnNoAnnotClass: Unit = { + """ + @js.native + class A extends js.Object + + @js.native + abstract class B extends js.Object + """.hasNoWarns + } + + @Test + def noWarnNoAnnotObject: Unit = { + """ + @js.native + object A extends js.Object + """.hasNoWarns + } + + @Test + def noWarnJSNameClass: Unit = { + """ + @js.native + @JSName("Foo") + class A extends js.Object + + @js.native + @JSName("Foo") + abstract class B extends js.Object + """.hasNoWarns + } + + @Test + def noWarnJSNameObject: Unit = { + """ + @js.native + @JSName("Foo") + object A extends js.Object + """.hasNoWarns + } + + @Test + def noWarnJSNameNestedClass: Unit = { + """ + object Enclosing { + @js.native + @JSName("Foo") + class A extends js.Object + + @js.native + @JSName("Foo") + abstract class B extends js.Object + } + """.hasNoWarns + } + + @Test + def noWarnJSNameNestObject: Unit = { + """ + object Enclosing { + @js.native + @JSName("Foo") + object A extends js.Object + } + """.hasNoWarns + } + +} diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/MissingJSGlobalDeprecationsTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/MissingJSGlobalDeprecationsTest.scala new file mode 100644 index 0000000000..c42f4d6401 --- /dev/null +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/MissingJSGlobalDeprecationsTest.scala @@ -0,0 +1,132 @@ +package org.scalajs.core.compiler.test + +import org.scalajs.core.compiler.test.util._ +import org.junit.Test + +// scalastyle:off line.size.limit + +class MissingJSGlobalDeprecationsTest extends DirectTest with TestHelpers { + + override def preamble: String = + """import scala.scalajs.js, js.annotation._ + """ + + @Test + def warnNoAnnotClass: Unit = { + """ + @js.native + class A extends js.Object + + @js.native + abstract class B extends js.Object + """ hasWarns + """ + |newSource1.scala:4: warning: Top-level native JS classes and objects should have an @JSGlobal or @JSImport annotation. This will be enforced in 1.0. + | If migrating from 0.6.14 or earlier, the equivalent behavior is an @JSGlobal without parameter. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) + | class A extends js.Object + | ^ + |newSource1.scala:7: warning: Top-level native JS classes and objects should have an @JSGlobal or @JSImport annotation. This will be enforced in 1.0. + | If migrating from 0.6.14 or earlier, the equivalent behavior is an @JSGlobal without parameter. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) + | abstract class B extends js.Object + | ^ + """ + } + + @Test + def warnNoAnnotObject: Unit = { + """ + @js.native + object A extends js.Object + """ hasWarns + """ + |newSource1.scala:4: warning: Top-level native JS classes and objects should have an @JSGlobal or @JSImport annotation. This will be enforced in 1.0. + | If migrating from 0.6.14 or earlier, the equivalent behavior is an @JSGlobal without parameter. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) + | object A extends js.Object + | ^ + """ + } + + @Test + def warnJSNameClass: Unit = { + """ + @js.native + @JSName("Foo") + class A extends js.Object + + @js.native + @JSName("Foo") + abstract class B extends js.Object + """ hasWarns + """ + |newSource1.scala:4: warning: @JSName on top-level native JS classes and objects (or native JS classes and objects inside Scala objects) is deprecated, and should be replaced by @JSGlobal (with the same meaning). This will be enforced in 1.0. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) + | @JSName("Foo") + | ^ + |newSource1.scala:8: warning: @JSName on top-level native JS classes and objects (or native JS classes and objects inside Scala objects) is deprecated, and should be replaced by @JSGlobal (with the same meaning). This will be enforced in 1.0. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) + | @JSName("Foo") + | ^ + """ + } + + @Test + def warnJSNameObject: Unit = { + """ + @js.native + @JSName("Foo") + object A extends js.Object + """ hasWarns + """ + |newSource1.scala:4: warning: @JSName on top-level native JS classes and objects (or native JS classes and objects inside Scala objects) is deprecated, and should be replaced by @JSGlobal (with the same meaning). This will be enforced in 1.0. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) + | @JSName("Foo") + | ^ + """ + } + + @Test + def warnJSNameNestedClass: Unit = { + """ + object Enclosing { + @js.native + @JSName("Foo") + class A extends js.Object + + @js.native + @JSName("Foo") + abstract class B extends js.Object + } + """ hasWarns + """ + |newSource1.scala:5: warning: @JSName on top-level native JS classes and objects (or native JS classes and objects inside Scala objects) is deprecated, and should be replaced by @JSGlobal (with the same meaning). This will be enforced in 1.0. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) + | @JSName("Foo") + | ^ + |newSource1.scala:9: warning: @JSName on top-level native JS classes and objects (or native JS classes and objects inside Scala objects) is deprecated, and should be replaced by @JSGlobal (with the same meaning). This will be enforced in 1.0. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) + | @JSName("Foo") + | ^ + """ + } + + @Test + def warnJSNameNestObject: Unit = { + """ + object Enclosing { + @js.native + @JSName("Foo") + object A extends js.Object + } + """ hasWarns + """ + |newSource1.scala:5: warning: @JSName on top-level native JS classes and objects (or native JS classes and objects inside Scala objects) is deprecated, and should be replaced by @JSGlobal (with the same meaning). This will be enforced in 1.0. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) + | @JSName("Foo") + | ^ + """ + } + +} diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/ReflectTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/ReflectTest.scala index 8301efa2b0..5f985f77bc 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/ReflectTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/ReflectTest.scala @@ -29,6 +29,7 @@ class ReflectTest extends DirectTest with TestHelpers { @EnableReflectiveInstantiation @js.native + @JSGlobal class D extends js.Object @EnableReflectiveInstantiation @@ -37,6 +38,7 @@ class ReflectTest extends DirectTest with TestHelpers { @EnableReflectiveInstantiation @js.native + @JSGlobal object F extends js.Object """ hasErrors """ @@ -52,10 +54,10 @@ class ReflectTest extends DirectTest with TestHelpers { |newSource1.scala:16: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. | @EnableReflectiveInstantiation | ^ - |newSource1.scala:20: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. + |newSource1.scala:21: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. | @EnableReflectiveInstantiation | ^ - |newSource1.scala:24: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. + |newSource1.scala:25: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. | @EnableReflectiveInstantiation | ^ """ diff --git a/examples/helloworld/HelloWorld.scala b/examples/helloworld/HelloWorld.scala index 54751982dd..2fbf2c4f6f 100644 --- a/examples/helloworld/HelloWorld.scala +++ b/examples/helloworld/HelloWorld.scala @@ -77,7 +77,7 @@ trait DOMElement extends js.Object { } @js.native -@JSName("jQuery") +@JSGlobal("jQuery") object JQuery extends js.Object { def apply(selector: String): JQuery = js.native } diff --git a/library/src/main/scala/scala/scalajs/js/Array.scala b/library/src/main/scala/scala/scalajs/js/Array.scala index 0383b13f5c..f6bb75118a 100644 --- a/library/src/main/scala/scala/scalajs/js/Array.scala +++ b/library/src/main/scala/scala/scalajs/js/Array.scala @@ -37,6 +37,7 @@ import annotation._ * @constructor Creates a new array of length 0. */ @native +@JSGlobal class Array[A] extends Object with Iterable[A] { /** Creates a new array with the given length. * @param arrayLength Initial length of the array. @@ -169,6 +170,7 @@ class Array[A] extends Object with Iterable[A] { /** Factory for [[js.Array]] objects. */ @native +@JSGlobal object Array extends Object { // Do not expose this one - use new Array(len) instead // def apply[A](arrayLength: Int): Array[A] = native diff --git a/library/src/main/scala/scala/scalajs/js/Date.scala b/library/src/main/scala/scala/scalajs/js/Date.scala index 4c5f78c85a..fbd7c09b70 100644 --- a/library/src/main/scala/scala/scalajs/js/Date.scala +++ b/library/src/main/scala/scala/scalajs/js/Date.scala @@ -14,6 +14,8 @@ */ package scala.scalajs.js +import scala.scalajs.js.annotation._ + /** * Creates a JavaScript Date instance that represents a single moment in time. * Date objects are based on a time value that is the number of milliseconds @@ -22,6 +24,7 @@ package scala.scalajs.js * MDN */ @native +@JSGlobal class Date extends Object { def this(value: Double) = this() @@ -188,6 +191,7 @@ class Date extends Object { /** Factory for [[js.Date]] objects. */ @native +@JSGlobal object Date extends Object { def apply(): String = native diff --git a/library/src/main/scala/scala/scalajs/js/Error.scala b/library/src/main/scala/scala/scalajs/js/Error.scala index 4bc1c200c8..f3f6e09c94 100644 --- a/library/src/main/scala/scala/scalajs/js/Error.scala +++ b/library/src/main/scala/scala/scalajs/js/Error.scala @@ -14,7 +14,10 @@ */ package scala.scalajs.js +import scala.scalajs.js.annotation._ + @native +@JSGlobal class Error(message0: String = "") extends Object { val name: String = native /** @@ -26,6 +29,7 @@ class Error(message0: String = "") extends Object { } @native +@JSGlobal object Error extends Object { def apply(message: String = ""): Error = native } @@ -37,9 +41,11 @@ object Error extends Object { * MDN */ @native +@JSGlobal class EvalError(message: String = "") extends Error @native +@JSGlobal object EvalError extends Object { def apply(message: String = ""): EvalError = native } @@ -57,9 +63,11 @@ object EvalError extends Object { * MDN */ @native +@JSGlobal class RangeError(message: String = "") extends Error @native +@JSGlobal object RangeError extends Object { def apply(message: String = ""): RangeError = native } @@ -73,9 +81,11 @@ object RangeError extends Object { * MDN */ @native +@JSGlobal class ReferenceError(message: String = "") extends Error @native +@JSGlobal object ReferenceError extends Object { def apply(message: String = ""): ReferenceError = native } @@ -89,9 +99,11 @@ object ReferenceError extends Object { * MDN */ @native +@JSGlobal class SyntaxError(message: String = "") extends Error @native +@JSGlobal object SyntaxError extends Object { def apply(message: String = ""): SyntaxError = native } @@ -105,9 +117,11 @@ object SyntaxError extends Object { * MDN */ @native +@JSGlobal class TypeError(message: String = "") extends Error @native +@JSGlobal object TypeError extends Object { def apply(message: String = ""): TypeError = native } @@ -120,9 +134,11 @@ object TypeError extends Object { * MDN */ @native +@JSGlobal class URIError(message: String = "") extends Error @native +@JSGlobal object URIError extends Object { def apply(message: String = ""): URIError = native } diff --git a/library/src/main/scala/scala/scalajs/js/Function.scala b/library/src/main/scala/scala/scalajs/js/Function.scala index 97fb598218..3d6e4fec56 100644 --- a/library/src/main/scala/scala/scalajs/js/Function.scala +++ b/library/src/main/scala/scala/scalajs/js/Function.scala @@ -14,6 +14,8 @@ */ package scala.scalajs.js +import scala.scalajs.js.annotation._ + /** * The Function constructor creates a new Function object. In JavaScript every * function is actually a Function object. @@ -40,6 +42,7 @@ package scala.scalajs.js * MDN */ @native +@JSGlobal class Function(args: String*) extends Object { /** * length is a property of a function object, and indicates how many arguments @@ -99,6 +102,7 @@ class Function(args: String*) extends Object { } @native +@JSGlobal object Function extends Object { def apply(args: String*): Function = native } diff --git a/library/src/main/scala/scala/scalajs/js/JSON.scala b/library/src/main/scala/scala/scalajs/js/JSON.scala index 649e51c60a..2578b84609 100644 --- a/library/src/main/scala/scala/scalajs/js/JSON.scala +++ b/library/src/main/scala/scala/scalajs/js/JSON.scala @@ -14,6 +14,8 @@ */ package scala.scalajs.js +import scala.scalajs.js.annotation._ + /** * The JSON object contains methods for converting values to JavaScript Object * Notation (JSON) and for converting JSON to values. @@ -21,6 +23,7 @@ package scala.scalajs.js * MDN */ @native +@JSGlobal object JSON extends Object { /** * Parse a string as JSON, optionally transforming the value produced by parsing. diff --git a/library/src/main/scala/scala/scalajs/js/Math.scala b/library/src/main/scala/scala/scalajs/js/Math.scala index f854b3284e..c9f07a331b 100644 --- a/library/src/main/scala/scala/scalajs/js/Math.scala +++ b/library/src/main/scala/scala/scalajs/js/Math.scala @@ -14,6 +14,8 @@ */ package scala.scalajs.js +import scala.scalajs.js.annotation._ + /** * Math is a built-in object that has properties and methods for mathematical * constants and functions. Not a function object. @@ -21,6 +23,7 @@ package scala.scalajs.js * MDN */ @native +@JSGlobal object Math extends Object { /** * Euler's constant and the base of natural logarithms, approximately 2.718. diff --git a/library/src/main/scala/scala/scalajs/js/Object.scala b/library/src/main/scala/scala/scalajs/js/Object.scala index cf37d2d351..de292e2753 100644 --- a/library/src/main/scala/scala/scalajs/js/Object.scala +++ b/library/src/main/scala/scala/scalajs/js/Object.scala @@ -14,8 +14,11 @@ */ package scala.scalajs.js +import scala.scalajs.js.annotation._ + /** Base class of all JavaScript objects. */ @native +@JSGlobal class Object extends Any { def this(value: Any) = this() @@ -46,6 +49,7 @@ class Object extends Any { /** The top-level `Object` JavaScript object. */ @native +@JSGlobal object Object extends Object { def apply(): Object = native def apply(value: Any): Object = native diff --git a/library/src/main/scala/scala/scalajs/js/Promise.scala b/library/src/main/scala/scala/scalajs/js/Promise.scala index 9e64bfa934..e016e35a14 100644 --- a/library/src/main/scala/scala/scalajs/js/Promise.scala +++ b/library/src/main/scala/scala/scalajs/js/Promise.scala @@ -12,6 +12,7 @@ package scala.scalajs.js import scala.language.implicitConversions import scala.scalajs.js +import scala.scalajs.js.annotation._ import scala.concurrent.Future @@ -37,6 +38,7 @@ import scala.concurrent.Future * directly use the methods of `Future` on `Promise`s. */ @js.native +@JSGlobal class Promise[+A]( executor: js.Function2[js.Function1[A | Thenable[A], _], js.Function1[scala.Any, _], _]) extends js.Object with js.Thenable[A] { @@ -54,6 +56,7 @@ class Promise[+A]( } @js.native +@JSGlobal object Promise extends js.Object { /** Returns a new [[Promise]] completed with the specified `value`. */ def resolve[A](value: A | Thenable[A]): Promise[A] = js.native diff --git a/library/src/main/scala/scala/scalajs/js/RegExp.scala b/library/src/main/scala/scala/scalajs/js/RegExp.scala index 56dc2c3ebe..3a9281465a 100644 --- a/library/src/main/scala/scala/scalajs/js/RegExp.scala +++ b/library/src/main/scala/scala/scalajs/js/RegExp.scala @@ -14,6 +14,8 @@ */ package scala.scalajs.js +import scala.scalajs.js.annotation._ + /** * The RegExp constructor creates a regular expression object for matching * text with a pattern. @@ -21,6 +23,7 @@ package scala.scalajs.js * MDN */ @native +@JSGlobal class RegExp(pattern: String, flags: String = "") extends Object { /** Creates a new RegExp with the same pattern and flags as the given one. */ def this(pattern: RegExp) = this("", "") @@ -103,6 +106,7 @@ class RegExp(pattern: String, flags: String = "") extends Object { } @native +@JSGlobal object RegExp extends Object { def apply(pattern: String, flags: String = ""): RegExp = native diff --git a/library/src/main/scala/scala/scalajs/js/Symbol.scala b/library/src/main/scala/scala/scalajs/js/Symbol.scala index eaa3b7cc48..c6a8a8bd9f 100644 --- a/library/src/main/scala/scala/scalajs/js/Symbol.scala +++ b/library/src/main/scala/scala/scalajs/js/Symbol.scala @@ -31,6 +31,7 @@ sealed trait Symbol extends js.Any * @groupprio 30 */ @js.native +@JSGlobal object Symbol extends js.Object { /** Creates a new unique symbol without description. * diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSGlobal.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSGlobal.scala new file mode 100644 index 0000000000..7ed693109c --- /dev/null +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSGlobal.scala @@ -0,0 +1,46 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js API ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package scala.scalajs.js.annotation + +/** Marks the annotated class or object as being a member of the JavaScript + * global scope. + * + * The annotated class/object must also be annotated with `@js.native`, and + * therefore extend [[scala.scalajs.js.Any js.Any]]. + * + * Given: + * {{{ + * @js.native + * @JSGlobal + * class Foo extends js.Object + * + * @js.native + * @JSGlobal("Foobar") + * object Bar extends js.Object + * + * @js.native + * @JSGlobal("Lib.Babar") + * class Babar extends js.Object + * }}} + * + * The following mappings apply (`global` denotes the global scope): + * + * {{{ + * Scala.js | JavaScript + * ------------------------+------------------ + * new Foo() | new global.Foo() + * Bar | global.Foobar + * js.constructorOf[Babar] | global.Lib.Babar + * }}} + * + * @see [[http://www.scala-js.org/doc/calling-javascript.html Calling JavaScript from Scala.js]] + */ +class JSGlobal extends scala.annotation.StaticAnnotation { + def this(name: String) = this() +} diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBuffer.scala b/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBuffer.scala index 7d9501da2b..4bffa83839 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBuffer.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBuffer.scala @@ -1,11 +1,13 @@ package scala.scalajs.js.typedarray import scala.scalajs.js +import scala.scalajs.js.annotation._ /** ECMAScript 6 * An ArrayBuffer is a block of contiguous, non-resizable memory. */ @js.native +@JSGlobal class ArrayBuffer(length: Int) extends js.Object { /** Length of this buffer in bytes */ diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/DataView.scala b/library/src/main/scala/scala/scalajs/js/typedarray/DataView.scala index 1ae540a1e6..82a718f97f 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/DataView.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/DataView.scala @@ -1,12 +1,14 @@ package scala.scalajs.js.typedarray import scala.scalajs.js +import scala.scalajs.js.annotation._ /** ECMAScript 6 * A DataView allows for extraction of particular data types at specific * offsets. */ @js.native +@JSGlobal class DataView(buffer: ArrayBuffer, byteOffset: Int = 0, byteLength: Int = ???) extends ArrayBufferView { diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Float32Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Float32Array.scala index 11db18d2ea..069af01e2e 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Float32Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Float32Array.scala @@ -1,11 +1,13 @@ package scala.scalajs.js.typedarray import scala.scalajs.js +import scala.scalajs.js.annotation._ /** ECMAScript 6 * A [[TypedArray]] of single precision floats */ @js.native +@JSGlobal class Float32Array private extends TypedArray[Float, Float32Array] { /** Constructs a Float32Array with the given length. Initialized to all 0 */ @@ -29,4 +31,5 @@ class Float32Array private extends TypedArray[Float, Float32Array] { * [[Float32Array]] companion */ @js.native +@JSGlobal object Float32Array extends TypedArrayStatic diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Float64Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Float64Array.scala index b31a3c92eb..f47d56e250 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Float64Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Float64Array.scala @@ -1,11 +1,13 @@ package scala.scalajs.js.typedarray import scala.scalajs.js +import scala.scalajs.js.annotation._ /** ECMAScript 6 * A [[TypedArray]] of double precision floats */ @js.native +@JSGlobal class Float64Array private extends TypedArray[Double, Float64Array] { /** Constructs a Float64Array with the given length. Initialized to all 0 */ @@ -29,4 +31,5 @@ class Float64Array private extends TypedArray[Double, Float64Array] { * [[Float64Array]] companion */ @js.native +@JSGlobal object Float64Array extends TypedArrayStatic diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Int16Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Int16Array.scala index 13bec62e63..4384dd0d41 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Int16Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Int16Array.scala @@ -1,11 +1,13 @@ package scala.scalajs.js.typedarray import scala.scalajs.js +import scala.scalajs.js.annotation._ /** ECMAScript 6 * A [[TypedArray]] of signed 16-bit integers */ @js.native +@JSGlobal class Int16Array private extends TypedArray[Short, Int16Array] { /** Constructs a Int16Array with the given length. Initialized to all 0 */ @@ -29,4 +31,5 @@ class Int16Array private extends TypedArray[Short, Int16Array] { * [[Int16Array]] companion */ @js.native +@JSGlobal object Int16Array extends TypedArrayStatic diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Int32Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Int32Array.scala index 3b175c60aa..d311d97e5b 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Int32Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Int32Array.scala @@ -1,11 +1,13 @@ package scala.scalajs.js.typedarray import scala.scalajs.js +import scala.scalajs.js.annotation._ /** ECMAScript 6 * A [[TypedArray]] of signed 32-bit integers */ @js.native +@JSGlobal class Int32Array private extends TypedArray[Int, Int32Array] { /** Constructs a Int32Array with the given length. Initialized to all 0 */ @@ -29,4 +31,5 @@ class Int32Array private extends TypedArray[Int, Int32Array] { * [[Int32Array]] companion */ @js.native +@JSGlobal object Int32Array extends TypedArrayStatic diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Int8Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Int8Array.scala index 0c3bdc1c73..12cc0419ff 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Int8Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Int8Array.scala @@ -1,11 +1,13 @@ package scala.scalajs.js.typedarray import scala.scalajs.js +import scala.scalajs.js.annotation._ /** ECMAScript 6 * A [[TypedArray]] of signed 8-bit integers */ @js.native +@JSGlobal class Int8Array private extends TypedArray[Byte, Int8Array] { /** Constructs a Int8Array with the given length. Initialized to all 0 */ @@ -29,4 +31,5 @@ class Int8Array private extends TypedArray[Byte, Int8Array] { * [[Int8Array]] companion */ @js.native +@JSGlobal object Int8Array extends TypedArrayStatic diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Uint16Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Uint16Array.scala index db25b5a20c..29335c8dca 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Uint16Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Uint16Array.scala @@ -1,11 +1,13 @@ package scala.scalajs.js.typedarray import scala.scalajs.js +import scala.scalajs.js.annotation._ /** ECMAScript 6 * A [[TypedArray]] of unsigned 16-bit integers */ @js.native +@JSGlobal class Uint16Array private extends TypedArray[Int, Uint16Array] { /** Constructs a Uint16Array with the given length. Initialized to all 0 */ @@ -29,4 +31,5 @@ class Uint16Array private extends TypedArray[Int, Uint16Array] { * [[Uint16Array]] companion */ @js.native +@JSGlobal object Uint16Array extends TypedArrayStatic diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Uint32Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Uint32Array.scala index ffc57ee108..ba0dc415dc 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Uint32Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Uint32Array.scala @@ -1,11 +1,13 @@ package scala.scalajs.js.typedarray import scala.scalajs.js +import scala.scalajs.js.annotation._ /** ECMAScript 6 * A [[TypedArray]] of unsigned 32-bit integers */ @js.native +@JSGlobal class Uint32Array private extends TypedArray[Double, Uint32Array] { /** Constructs a Uint32Array with the given length. Initialized to all 0 */ @@ -29,4 +31,5 @@ class Uint32Array private extends TypedArray[Double, Uint32Array] { * [[Uint32Array]] companion */ @js.native +@JSGlobal object Uint32Array extends TypedArrayStatic diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Uint8Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Uint8Array.scala index 30aa866f50..6d664d8bce 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Uint8Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Uint8Array.scala @@ -1,11 +1,13 @@ package scala.scalajs.js.typedarray import scala.scalajs.js +import scala.scalajs.js.annotation._ /** ECMAScript 6 * A [[TypedArray]] of unsigned 8-bit integers */ @js.native +@JSGlobal class Uint8Array private extends TypedArray[Short, Uint8Array] { /** Constructs a Uint8Array with the given length. Initialized to all 0 */ @@ -29,4 +31,5 @@ class Uint8Array private extends TypedArray[Short, Uint8Array] { * [[Uint8Array]] companion */ @js.native +@JSGlobal object Uint8Array extends TypedArrayStatic diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Uint8ClampedArray.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Uint8ClampedArray.scala index 04cf613343..bcee4c4691 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Uint8ClampedArray.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Uint8ClampedArray.scala @@ -1,12 +1,14 @@ package scala.scalajs.js.typedarray import scala.scalajs.js +import scala.scalajs.js.annotation._ /** ECMAScript 6 * A [[TypedArray]] of unsigned 8-bit integers whose values are clamped to * their max/min rather than wrapped around if they overflow. */ @js.native +@JSGlobal class Uint8ClampedArray private extends TypedArray[Int, Uint8ClampedArray] { /** Constructs a Uint8ClampedArray with the given length. Initialized to all 0 */ @@ -30,4 +32,5 @@ class Uint8ClampedArray private extends TypedArray[Int, Uint8ClampedArray] { * [[Uint8ClampedArray]] companion */ @js.native +@JSGlobal object Uint8ClampedArray extends TypedArrayStatic diff --git a/library/src/main/scala/scala/scalajs/runtime/RuntimeString.scala b/library/src/main/scala/scala/scalajs/runtime/RuntimeString.scala index 6e5fd18b63..354553c278 100644 --- a/library/src/main/scala/scala/scalajs/runtime/RuntimeString.scala +++ b/library/src/main/scala/scala/scalajs/runtime/RuntimeString.scala @@ -3,6 +3,7 @@ package scala.scalajs.runtime import java.util.Comparator import scala.scalajs.js +import scala.scalajs.js.annotation._ import js.JSStringOps._ import java.nio.ByteBuffer @@ -399,7 +400,7 @@ private[runtime] object RuntimeString { } @js.native - @js.annotation.JSName("String") + @JSGlobal("String") private object NativeJSString extends js.Object { def fromCharCode(charCodes: Int*): String = js.native } diff --git a/project/Build.scala b/project/Build.scala index ba07868545..43ccb2480a 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1418,10 +1418,12 @@ object Build { testHtmlSettings(testHtmlFullOpt, FullOptStage) ++ Seq( name := "Scala.js test suite", - /* We still have zillions of run test for top-level @JSExport. Don't - * drown the test:compile output under useless warnings. + /* We still have zillions of run test for top-level @JSExport and for + * @JSName/missing @JSGlobal. Don't drown the test:compile output under + * useless warnings. */ scalacOptions in Test += "-P:scalajs:suppressExportDeprecations", + scalacOptions in Test += "-P:scalajs:suppressMissingJSGlobalDeprecations", unmanagedSourceDirectories in Test ++= { val testDir = (sourceDirectory in Test).value diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala b/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala index abd69a3205..3c1708bc35 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala @@ -9,7 +9,7 @@ package org.scalajs.testinterface import scala.scalajs.js import scala.scalajs.concurrent.QueueExecutionContext -import scala.scalajs.js.annotation.JSName +import scala.scalajs.js.annotation._ import js.URIUtils.{decodeURIComponent, encodeURIComponent} import scala.collection.mutable @@ -432,7 +432,7 @@ protected[testinterface] object HTMLRunner extends js.JSApp { // Mini dom facade. private object dom { // scalastyle:ignore - @JSName("document") + @JSGlobal("document") @js.native object document extends js.Object { // scalastyle:ignore def body: Element = js.native diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Com.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/Com.scala index 42485e2d81..c0ed78c634 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Com.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/Com.scala @@ -1,10 +1,10 @@ package org.scalajs.testinterface.internal import scala.scalajs.js -import js.annotation.JSName +import scala.scalajs.js.annotation._ @js.native -@JSName("scalajsCom") +@JSGlobal("scalajsCom") object Com extends js.Object { def init(onReceive: js.Function1[String, Unit]): Unit = js.native def send(msg: String): Unit = js.native diff --git a/test-suite/js/src/test/resources/ScalaJSDefinedTestNatives.js b/test-suite/js/src/test/resources/ScalaJSDefinedTestNatives.js index 50abe1e28e..54e4cb44a6 100644 --- a/test-suite/js/src/test/resources/ScalaJSDefinedTestNatives.js +++ b/test-suite/js/src/test/resources/ScalaJSDefinedTestNatives.js @@ -55,6 +55,7 @@ $g.ConstructorDefaultParam = ConstructorDefaultParam; $g.JSNativeObjectInPackageFoo = {}; + $g.JSNativeObjectInPackageFooJSNameOmitted = $g.JSNativeObjectInPackageFoo; $g.JSNativeObjectInPackageBar = {}; var JSNativeClassInPackageFoo = function() { $g.Object.call(this); @@ -63,6 +64,7 @@ return "foo"; }; $g.JSNativeClassInPackageFoo = JSNativeClassInPackageFoo; + $g.JSNativeClassInPackageFooJSNameOmitted = $g.JSNativeClassInPackageFoo; var JSNativeClassInPackageBar = function() { $g.Object.call(this); }; diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala index ed231c3de8..2648724b70 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala @@ -118,6 +118,12 @@ class InteroperabilityTest { assertEquals(42, obj.field) assertEquals("42", obj.method) assertEquals("Scala.js", obj.getConstructorParam) + + // With @JSName (old-style) + val objOld = new InteroperabilityTestPatternJSName("Scala.js") + assertEquals(42, objOld.field) + assertEquals("42", objOld.method) + assertEquals("Scala.js", objOld.getConstructorParam) } @Test def should_acces_top_level_JS_objects_via_Scala_objects_inheriting_from_js_Object(): Unit = { @@ -134,10 +140,16 @@ class InteroperabilityTest { // Use alias for convenience: see end of file for definition val TopLevel = InteroperabilityTestTopLevel - val obj = TopLevel("7357") assertEquals("7357", obj.value) assertEquals(7357, obj.valueAsInt) + + // With @JSName (old-style) + val TopLevelOld = InteroperabilityTestTopLevelJSName + assertSame(TopLevel, TopLevelOld) + val objOld = TopLevelOld("7357") + assertEquals("7357", objOld.value) + assertEquals(7357, objOld.valueAsInt) } @Test def should_access_native_JS_classes_and_objects_nested_in_JS_objects(): Unit = { @@ -159,6 +171,8 @@ class InteroperabilityTest { this.x = x || 42; } }; + var InteroperabilityTestContainerObjectJSNameOmitted = + InteroperabilityTestContainerObject; """) // Use alias for convenience: see end of file for definition @@ -181,6 +195,28 @@ class InteroperabilityTest { val obj6 = new TopLevel.ContainedClassWithDefaultParam(10) assertEquals(10, obj6.x) + + // With an omitted @JSName (old-style) + val TopLevelOld = InteroperabilityTestContainerObjectJSNameOmitted + assertSame(TopLevel, TopLevelOld) + + val obj1Old = new TopLevelOld.ContainedClass(34) + assertEquals(34, obj1Old.x) + + val obj2Old = TopLevelOld.ContainedObject + assertEquals(42, obj2Old.x) + + val obj3Old = new TopLevelOld.ContainedClassWithJSName(65) + assertEquals(130, obj3Old.x) + + val obj4Old = TopLevelOld.ContainedObjectWithJSName + assertEquals(4242, obj4Old.x) + + val obj5Old = new TopLevelOld.ContainedClassWithDefaultParam() + assertEquals(42, obj5Old.x) + + val obj6Old = new TopLevelOld.ContainedClassWithDefaultParam(10) + assertEquals(10, obj6Old.x) } @Test def should_access_native_JS_classes_and_objects_nested_in_atJSNamed_JS_objects(): Unit = { @@ -202,7 +238,7 @@ class InteroperabilityTest { """) // Use alias for convenience: see end of file for definition - val TopLevel = InteroperabilityTestContainerObjectWithJSName + val TopLevel = InteroperabilityTestContainerObjectExplicitName val obj1 = new TopLevel.ContainedClass(34) assertEquals(34, obj1.x) @@ -215,6 +251,22 @@ class InteroperabilityTest { val obj4 = TopLevel.ContainedObjectWithJSName assertEquals(4242, obj4.x) + + // With @JSName (old-style) + val TopLevelOld = InteroperabilityTestContainerObjectExplicitNameJSName + assertSame(TopLevel, TopLevelOld) + + val obj1Old = new TopLevelOld.ContainedClass(34) + assertEquals(34, obj1Old.x) + + val obj2Old = TopLevelOld.ContainedObject + assertEquals(42, obj2Old.x) + + val obj3Old = new TopLevelOld.ContainedClassWithJSName(65) + assertEquals(130, obj3Old.x) + + val obj4Old = TopLevelOld.ContainedObjectWithJSName + assertEquals(4242, obj4Old.x) } @Test def should_allow_to_call_JS_methods_with_variadic_parameters(): Unit = { @@ -651,7 +703,7 @@ object InteroperabilityTest { * their tests. */ -@JSName("InteroperabilityTestInherit.Pattern") +@JSGlobal("InteroperabilityTestInherit.Pattern") @js.native class InteroperabilityTestPattern protected () extends js.Object { def this(pattern: String) = this() @@ -660,19 +712,35 @@ class InteroperabilityTestPattern protected () extends js.Object { def getConstructorParam(): String = js.native } +@JSName("InteroperabilityTestInherit.Pattern") +@js.native +class InteroperabilityTestPatternJSName protected () extends js.Object { + def this(pattern: String) = this() + val field: Int = js.native + def method(): String = js.native + def getConstructorParam(): String = js.native +} + @js.native trait InteroperabilityTestTopLevel extends js.Object { val value: String = js.native def valueAsInt(): Int = js.native } -@JSName("InteroperabilityTestTopLevelObject") +@JSGlobal("InteroperabilityTestTopLevelObject") @js.native object InteroperabilityTestTopLevel extends js.Object { def apply(value: String): InteroperabilityTestTopLevel = js.native } +@JSName("InteroperabilityTestTopLevelObject") @js.native +object InteroperabilityTestTopLevelJSName extends js.Object { + def apply(value: String): InteroperabilityTestTopLevel = js.native +} + +@js.native +@JSGlobal object InteroperabilityTestContainerObject extends js.Object { @js.native class ContainedClass(_x: Int) extends js.Object { @@ -702,9 +770,65 @@ object InteroperabilityTestContainerObject extends js.Object { } } +@js.native +object InteroperabilityTestContainerObjectJSNameOmitted extends js.Object { + @js.native + class ContainedClass(_x: Int) extends js.Object { + val x: Int = js.native + } + + @js.native + object ContainedObject extends js.Object { + val x: Int = js.native + } + + @JSName("ContainedClassRenamed") + @js.native + class ContainedClassWithJSName(_x: Int) extends js.Object { + val x: Int = js.native + } + + @JSName("ContainedObjectRenamed") + @js.native + object ContainedObjectWithJSName extends js.Object { + val x: Int = js.native + } + + @js.native + class ContainedClassWithDefaultParam(_x: Int = ???) extends js.Object { + val x: Int = js.native + } +} + +@JSGlobal("InteroperabilityTestContainerObjectRenamed") +@js.native +object InteroperabilityTestContainerObjectExplicitName extends js.Object { + @js.native + class ContainedClass(_x: Int) extends js.Object { + val x: Int = js.native + } + + @js.native + object ContainedObject extends js.Object { + val x: Int = js.native + } + + @JSName("ContainedClassRenamed") + @js.native + class ContainedClassWithJSName(_x: Int) extends js.Object { + val x: Int = js.native + } + + @JSName("ContainedObjectRenamed") + @js.native + object ContainedObjectWithJSName extends js.Object { + val x: Int = js.native + } +} + @JSName("InteroperabilityTestContainerObjectRenamed") @js.native -object InteroperabilityTestContainerObjectWithJSName extends js.Object { +object InteroperabilityTestContainerObjectExplicitNameJSName extends js.Object { @js.native class ContainedClass(_x: Int) extends js.Object { val x: Int = js.native @@ -749,6 +873,7 @@ trait InteroperabilityTestPolyClassPolyNullaryMethod[+T] extends js.Object { } @js.native +@JSGlobal class InteroperabilityTestVariadicCtor(inargs: Any*) extends js.Object { val args: js.Array[Any] = js.native } @@ -775,9 +900,11 @@ class SomeValueClass(val i: Int) extends AnyVal { } @js.native +@JSGlobal class InteroperabilityTestCtor(x: Int = 5, y: Int = ???) extends js.Object { def values: js.Array[Int] = js.native } @js.native +@JSGlobal class InteroparabilityCtorInlineValue(val x: Int, var y: Int) extends js.Object diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectionTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectionTest.scala index eb1f0836c0..f85cbee1a2 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectionTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectionTest.scala @@ -15,7 +15,7 @@ import java.io.Serializable import scala.reflect.{classTag, ClassTag} import scala.scalajs.js -import js.annotation.JSName +import js.annotation.JSGlobal import org.junit.Test import org.junit.Assert._ @@ -161,7 +161,7 @@ object ReflectionTest { class RenamedTestClass - @JSName("ReflectionTestRawJSClass") + @JSGlobal("ReflectionTestRawJSClass") @js.native class ReflectionTestRawJSClass extends js.Object diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RuntimeTypesTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RuntimeTypesTest.scala index bdd6f7fa87..de0fd2523c 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RuntimeTypesTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RuntimeTypesTest.scala @@ -11,7 +11,7 @@ import java.lang.Cloneable import java.io.Serializable import scala.scalajs.js -import scala.scalajs.js.annotation.JSName +import scala.scalajs.js.annotation.JSGlobal import org.junit.Test import org.junit.Assert._ @@ -148,7 +148,7 @@ object RuntimeTypesTest { @js.native trait SomeJSInterface extends ParentJSType - @JSName("SomeJSClass") + @JSGlobal("SomeJSClass") @js.native class SomeJSClass extends ParentJSType diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index ecc6422550..4177e0d6a8 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -1821,9 +1821,9 @@ object SJSDefinedAutoExportedIgnoreClassObject extends SJSDefinedAutoExportIgnor @ScalaJSDefined class SJSDefinedAutoExportedIgnoreClassClass(val x: Int) extends SJSDefinedAutoExportIgnoreClass -@js.native +@js.native @JSGlobal object NativeInvalidExportObject extends SJSDefinedAutoExportIgnoreClass -@js.native +@js.native @JSGlobal class NativeInvalidExportClass extends SJSDefinedAutoExportIgnoreClass @ScalaJSDefined class SJSDefinedInvalidExportClass private () extends SJSDefinedAutoExportIgnoreClass diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNativeInPackage.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNativeInPackage.scala index 86b9838bc5..52ede549c4 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNativeInPackage.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNativeInPackage.scala @@ -4,39 +4,66 @@ import org.junit.Test import org.junit.Assert._ import scala.scalajs.js -import scala.scalajs.js.annotation.JSName +import scala.scalajs.js.annotation._ package object packageobjectwithnatives { @js.native + @JSGlobal object JSNativeObjectInPackageFoo extends js.Object @js.native - @JSName("JSNativeObjectInPackageBar") + object JSNativeObjectInPackageFooJSNameOmitted extends js.Object + + @js.native + @JSGlobal("JSNativeObjectInPackageBar") object JSNativeObjectInPackageBaz extends js.Object @js.native + @JSName("JSNativeObjectInPackageBar") + object JSNativeObjectInPackageBazJSName extends js.Object + + @js.native + @JSGlobal class JSNativeClassInPackageFoo extends js.Object { def foo(): String = js.native } + @js.native + class JSNativeClassInPackageFooJSNameOmitted extends js.Object { + def foo(): String = js.native + } + @js.native @JSName("JSNativeClassInPackageBar") class JSNativeClassInPackageBaz extends js.Object { def baz(): String = js.native } + + @js.native + @JSGlobal("JSNativeClassInPackageBar") + class JSNativeClassInPackageBazJSName extends js.Object { + def baz(): String = js.native + } } class JSNativeInPackage { import packageobjectwithnatives._ import js.Dynamic.global - @Test def testOvjectDefaultJSName(): Unit = { + @Test def testObjectDefaultJSGlobal(): Unit = { val gJSNativeObjectInPackageFoo = global.JSNativeObjectInPackageFoo assertFalse(js.isUndefined(gJSNativeObjectInPackageFoo)) assertSame(JSNativeObjectInPackageFoo, gJSNativeObjectInPackageFoo) } - @Test def testObjectJSName(): Unit = { + @Test def testObjectDefaultJSName(): Unit = { + val gJSNativeObjectInPackageFoo = global.JSNativeObjectInPackageFoo + assertFalse(js.isUndefined(gJSNativeObjectInPackageFoo)) + assertSame(JSNativeObjectInPackageFooJSNameOmitted, + gJSNativeObjectInPackageFoo) + } + + @Test def testObjectJSGlobal(): Unit = { val gJSNativeObjectInPackageBar = global.JSNativeObjectInPackageBar val gJSNativeObjectInPackageBaz = global.JSNativeObjectInPackageBaz assertFalse(js.isUndefined(gJSNativeObjectInPackageBar)) @@ -44,7 +71,15 @@ class JSNativeInPackage { assertSame(JSNativeObjectInPackageBaz, gJSNativeObjectInPackageBar) } - @Test def testClassDefaultJSName(): Unit = { + @Test def testObjectJSName(): Unit = { + val gJSNativeObjectInPackageBar = global.JSNativeObjectInPackageBar + val gJSNativeObjectInPackageBaz = global.JSNativeObjectInPackageBaz + assertFalse(js.isUndefined(gJSNativeObjectInPackageBar)) + assertTrue(js.isUndefined(gJSNativeObjectInPackageBaz)) + assertSame(JSNativeObjectInPackageBazJSName, gJSNativeObjectInPackageBar) + } + + @Test def testClassDefaultJSGlobal(): Unit = { val gJSNativeClassInPackageFooCtr = global.JSNativeClassInPackageFoo assertFalse(js.isUndefined(gJSNativeClassInPackageFooCtr)) assertEquals(js.constructorOf[JSNativeClassInPackageFoo], @@ -56,7 +91,19 @@ class JSNativeInPackage { assertEquals("foo", new JSNativeClassInPackageFoo().foo()) } - @Test def testClassJSName(): Unit = { + @Test def testClassDefaultJSName(): Unit = { + val gJSNativeClassInPackageFooCtr = global.JSNativeClassInPackageFoo + assertFalse(js.isUndefined(gJSNativeClassInPackageFooCtr)) + assertEquals(js.constructorOf[JSNativeClassInPackageFooJSNameOmitted], + gJSNativeClassInPackageFooCtr) + + val gJSNativeClassInPackageFoo = + js.Dynamic.newInstance(gJSNativeClassInPackageFooCtr)() + assertEquals("foo", gJSNativeClassInPackageFoo.foo()) + assertEquals("foo", new JSNativeClassInPackageFooJSNameOmitted().foo()) + } + + @Test def testClassJSGlobal(): Unit = { val gJSNativeClassInPackageBarCtr = global.JSNativeClassInPackageBar val gJSNativeClassInPackageBazCtr = global.JSNativeClassInPackageBaz assertFalse(js.isUndefined(gJSNativeClassInPackageBarCtr)) @@ -69,4 +116,18 @@ class JSNativeInPackage { assertEquals("baz", gJSNativeClassInPackageBar.baz()) assertEquals("baz", new JSNativeClassInPackageBaz().baz()) } + + @Test def testClassJSName(): Unit = { + val gJSNativeClassInPackageBarCtr = global.JSNativeClassInPackageBar + val gJSNativeClassInPackageBazCtr = global.JSNativeClassInPackageBaz + assertFalse(js.isUndefined(gJSNativeClassInPackageBarCtr)) + assertSame(js.constructorOf[JSNativeClassInPackageBazJSName], + gJSNativeClassInPackageBarCtr) + assertTrue(js.isUndefined(gJSNativeClassInPackageBazCtr)) + + val gJSNativeClassInPackageBar = + js.Dynamic.newInstance(gJSNativeClassInPackageBarCtr)() + assertEquals("baz", gJSNativeClassInPackageBar.baz()) + assertEquals("baz", new JSNativeClassInPackageBazJSName().baz()) + } } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala index ac8ed052e8..9608e28652 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala @@ -341,7 +341,7 @@ object JSSymbolTest { } @js.native - @JSName("dummy") + @JSGlobal("dummy") class PropDefClass extends js.Any { @JSName(sym1) def internalDef: Int = js.native @@ -360,7 +360,7 @@ object JSSymbolTest { } @js.native - @JSName("dummy") + @JSGlobal("dummy") class PropValClass extends js.Any { @JSName(sym1) val internalVal: String = js.native @@ -379,7 +379,7 @@ object JSSymbolTest { } @js.native - @JSName("dummy") + @JSGlobal("dummy") class PropVarClass extends js.Any { @JSName(sym1) var internalVar: Double = js.native @@ -415,7 +415,7 @@ object JSSymbolTest { } @js.native - @JSName("dummy") + @JSGlobal("dummy") class MethodClass extends js.Any { @JSName(sym1) def foo(x: Int): Int = js.native @@ -443,7 +443,7 @@ object JSSymbolTest { } @js.native - @JSName("dummy") + @JSGlobal("dummy") class OverloadedMethodClass extends js.Any { @JSName(sym1) def foo(x: Int): Int = js.native @@ -471,7 +471,7 @@ object JSSymbolTest { } @js.native - @JSName("dummy") + @JSGlobal("dummy") class OverloadedRuntimeDispatchMethodClass extends js.Any { @JSName(sym1) def foo(x: Int): Int = js.native @@ -497,7 +497,7 @@ object JSSymbolTest { } @js.native - @JSName("dummy") + @JSGlobal("dummy") class ClassWithSymsInSJSDefinedObject extends js.Object { @JSName(sym3) def symInSJSDefinedObject(x: Int): Int = js.native @@ -517,7 +517,7 @@ object JSSymbolTest { } @js.native - @JSName("dummy") + @JSGlobal("dummy") class ClassJSIterable[+A] extends JSIterable[A] { @JSName(js.Symbol.iterator) def iterator(): js.Dynamic = js.native diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala index 0af099c7f2..0a3657d086 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala @@ -215,7 +215,7 @@ object MiscInteropTest { def foo(x: Int): Int = js.native } - @JSName("DirectSubclassOfJSAny") + @JSGlobal("DirectSubclassOfJSAny") @js.native class DirectSubclassOfJSAny extends js.Any { def bar(x: Int): Int = js.native diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala index 066e69a192..c6d9c69d60 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala @@ -1572,7 +1572,7 @@ class ScalaJSDefinedTest { object ScalaJSDefinedTest { // Defined in test-suite/src/test/resources/ScalaJSDefinedTestNatives.js - @JSName("ScalaJSDefinedTestNativeParentClass") + @JSGlobal("ScalaJSDefinedTestNativeParentClass") @js.native class NativeParentClass(val x: Int) extends js.Object { def foo(s: String): String = js.native @@ -1595,7 +1595,7 @@ object ScalaJSDefinedTest { } // Defined in test-suite/src/test/resources/ScalaJSDefinedTestNatives.js - @JSName("ScalaJSDefinedTestNativeParentClassWithDeferred") + @JSGlobal("ScalaJSDefinedTestNativeParentClassWithDeferred") @js.native abstract class NativeParentClassWithDeferred extends NativeTraitWithDeferred { def foo(y: Int): Int = js.native // = bar(y + 4) + x @@ -1604,7 +1604,7 @@ object ScalaJSDefinedTest { } // Defined in test-suite/src/test/resources/ScalaJSDefinedTestNatives.js - @JSName("ScalaJSDefinedTestNativeParentClassWithVarargs") + @JSGlobal("ScalaJSDefinedTestNativeParentClassWithVarargs") @js.native class NativeParentClassWithVarargs( _x: Int, _args: Int*) extends js.Object { @@ -1689,25 +1689,25 @@ object ScalaJSDefinedTest { object ConstructorDefaultParamScalaJSNonNative extends js.Object @js.native - @JSName("ConstructorDefaultParam") + @JSGlobal("ConstructorDefaultParam") class ConstructorDefaultParamJSNativeNone(val foo: Int = -1) extends js.Object @js.native - @JSName("ConstructorDefaultParam") + @JSGlobal("ConstructorDefaultParam") class ConstructorDefaultParamJSNativeScala(val foo: Int = -1) extends js.Object object ConstructorDefaultParamJSNativeScala @js.native - @JSName("ConstructorDefaultParam") + @JSGlobal("ConstructorDefaultParam") class ConstructorDefaultParamJSNativeJSNonNative(val foo: Int = -1) extends js.Object @ScalaJSDefined object ConstructorDefaultParamJSNativeJSNonNative extends js.Object @js.native - @JSName("ConstructorDefaultParam") + @JSGlobal("ConstructorDefaultParam") class ConstructorDefaultParamJSNativeJSNative(val foo: Int = -1) extends js.Object @js.native - @JSName("ConstructorDefaultParam") + @JSGlobal("ConstructorDefaultParam") object ConstructorDefaultParamJSNativeJSNative extends js.Object // sanity check From 7ad687615f2ac802607317b1f60a18d7d89b5d36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 13 Mar 2017 15:55:03 +0100 Subject: [PATCH 0142/2665] Cross-compile most of tests in testsuite.compiler.RegressionTest. `should_support_class_literals_for_existential_value_types_issue_218` should pass, which is why it is in the shared part, but it doesn't due to not being bug-compatible with the JVM. This is filed as --- .../testsuite/compiler/RegressionJSTest.scala | 76 +++++++++++++++++++ .../testsuite/compiler/RegressionTest.scala | 75 +++--------------- 2 files changed, 86 insertions(+), 65 deletions(-) create mode 100644 test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala rename test-suite/{js => shared}/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala (88%) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala new file mode 100644 index 0000000000..7fd9ff5b60 --- /dev/null +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala @@ -0,0 +1,76 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.compiler + +import scala.scalajs.js +import scala.scalajs.js.annotation._ + +import org.junit.Test +import org.junit.Assert._ + +class RegressionJSTest { + + @Test def should_not_swallow_Unit_expressions_when_converting_to_js_Any_issue_83(): Unit = { + var effectHappened = false + def doEffect(): Unit = effectHappened = true + def f(): js.Any = doEffect() + f() + assertTrue(effectHappened) + } + + @Test def should_resolve_overloads_on_scala_Function_apply_when_converting_to_js_Function_issue_125(): Unit = { + class Fct extends Function1[Int, Any] { + def apply(n: Int): Int = n + } + + val scalaFunction = new Fct + val jsFunction: js.Any = scalaFunction + val thisFunction: js.ThisFunction = scalaFunction + } + + @Test def should_not_put_bad_flags_on_caseaccessor_export_forwarders_issue_1191(): Unit = { + // This test used to choke patmat + + @JSExportAll + case class T(one: Int, two: Int) + + val T(a, b) = T(1, 2) + + assertEquals(1, a) + assertEquals(2, b) + } + + @Test def should_support_debugger_statements_through_the_whole_pipeline_issue_1402(): Unit = { + /* A function that hopefully persuades the optimizer not to optimize + * we need a debugger statement that is unreachable, but not eliminated. + */ + @noinline + class A(var z: Int = 4) { + var x: Int = _ + var y: Int = _ + + @noinline + def plus(x0: Int, y0: Int): Int = { + x = x0 + y = y0 + var res = 0 + while (x > 0 || y > 0 || z > 0) { + if (x > 0) x -= 1 + else if (y > 0) y -= 1 + else z -= 1 + res += 1 + } + res + } + } + + if (new A().plus(5, 10) < 3) + js.debugger() + } + +} diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala similarity index 88% rename from test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala rename to test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala index 8688deb8a6..e3d27a4ade 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala @@ -9,10 +9,9 @@ package org.scalajs.testsuite.compiler import scala.annotation.tailrec -import scala.scalajs.js - import org.junit.Test import org.junit.Assert._ +import org.junit.Assume._ import org.scalajs.testsuite.utils.AssertThrows._ @@ -23,11 +22,11 @@ class RegressionTest { @Test def `Wrong_division_conversion_(7_/_2.0)_issue_18`(): Unit = { val div = 7 / 2.0 - assertEquals(3.5, div) + assertEquals(3.5, div, 0.0) assertEquals("double", div.getClass.getName) val mod = 7 % 2.0 - assertEquals(1.0, mod) + assertEquals(1.0, mod, 0.0) assertEquals("double", mod.getClass.getName) } @@ -62,14 +61,6 @@ class RegressionTest { new Bug66B("", "") } - @Test def should_not_swallow_Unit_expressions_when_converting_to_js_Any_issue_83(): Unit = { - var effectHappened = false - def doEffect(): Unit = effectHappened = true - def f(): js.Any = doEffect() - f() - assertTrue(effectHappened) - } - @Test def should_correctly_call_subSequence_on_non_string_CharSequences_issue_55(): Unit = { val arr: CharSequence = Array('a','b','c','d') val ss = arr.subSequence(2,3) @@ -82,16 +73,6 @@ class RegressionTest { assertEquals("afoo", 'a' + "foo") } - @Test def should_resolve_overloads_on_scala_Function_apply_when_converting_to_js_Function_issue_125(): Unit = { - class Fct extends Function1[Int, Any] { - def apply(n: Int): Int = n - } - - val scalaFunction = new Fct - val jsFunction: js.Any = scalaFunction - val thisFunction: js.ThisFunction = scalaFunction - } - @Test def should_correctly_dispatch_calls_on_private_functions_issue_165(): Unit = { class A { private def x: Int = 1 @@ -165,6 +146,9 @@ class RegressionTest { } @Test def should_support_class_literals_for_existential_value_types_issue_218(): Unit = { + assumeFalse("Not bug-compatible with the JVM, issue #2801", + Platform.executingInJVM) + assertEquals("org.scalajs.testsuite.compiler.RegressionTest$Bug218Foo", scala.reflect.classTag[Bug218Foo[_]].toString) } @@ -231,11 +215,11 @@ class RegressionTest { val float = zero[Float] assertTrue((float: Any).isInstanceOf[Float]) - assertEquals(0.0f, float) + assertEquals(0.0f, float, 0.0f) val double = zero[Double] assertTrue((double: Any).isInstanceOf[Double]) - assertEquals(0.0, double) + assertEquals(0.0, double, 0.0) val ref = zero[AnyRef] assertEquals(null, ref) @@ -274,18 +258,6 @@ class RegressionTest { assertThrows(classOf[Exception], (giveMeANothing(): scala.runtime.IntRef).elem) } - @Test def should_not_put_bad_flags_on_caseaccessor_export_forwarders_issue_1191(): Unit = { - // This test used to choke patmat - - @scala.scalajs.js.annotation.JSExportAll - case class T(one: Int, two: Int) - - val T(a, b) = T(1, 2) - - assertEquals(1, a) - assertEquals(2, b) - } - @Test def should_properly_order_ctor_statements_when_inlining_issue_1369(): Unit = { trait Bar { def x: Int @@ -355,33 +327,6 @@ class RegressionTest { assertEquals("15", new Test().fct(1)) } - @Test def should_support_debugger_statements_through_the_whole_pipeline_issue_1402(): Unit = { - // A function that hopfully persuades the optimizer not to optimize - // we need a debugger statement that is unreachable, but not eliminated - @noinline - class A(var z: Int = 4) { - var x: Int = _ - var y: Int = _ - - @noinline - def plus(x0: Int, y0: Int): Int = { - x = x0 - y = y0 - var res = 0 - while (x > 0 || y > 0 || z > 0) { - if (x > 0) x -= 1 - else if (y > 0) y -= 1 - else z -= 1 - res += 1 - } - res - } - } - - if (new A().plus(5, 10) < 3) - js.debugger() - } - @Test def should_not_cause_Closure_to_crash_with_Unexpected_variable_NaN_issue_1469(): Unit = { /* Basically we want to make sure that a specialized bridge of Function1 * taking and returning Double is emitted (and not dce'ed) for this @@ -401,7 +346,7 @@ class RegressionTest { */ class F extends Function1[Any, Unit] { def apply(x: Any): Unit = - assertEquals(5, x.asInstanceOf[js.Any]) + assertEquals(5, x) } // Make sure the specialized Function1.apply(Double)Double is reachable. @@ -410,7 +355,7 @@ class RegressionTest { ((x: Double) => x * z): (Double => Double) } val someDoubleFun = makeFun(2.0) - assertEquals(147.0, someDoubleFun(42.0)) + assertEquals(147.0, someDoubleFun(42.0), 0.0) // Make sure F itself is reachable and not completely inlineable @noinline def makeF: Any => Any = (() => new F)() From b7f3e23a832accbc78c98dbebf97b36b588bf23c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 13 Mar 2017 16:12:49 +0100 Subject: [PATCH 0143/2665] Fix #2799: Don't use `equals` for comparing java.lang.Double/Float. This is essentially a port of the fix for scala-dev#329, which was implemented in https://github.com/scala/scala/pull/5761. To remain bug-compatible with the JVM, we explicitly look at the version of the Scala compiler that we run on to determine whether or not the fix should be applied. --- .../org/scalajs/core/compiler/GenJSCode.scala | 37 ++++++- .../testsuite/compiler/RegressionTest.scala | 100 ++++++++++++++++++ 2 files changed, 133 insertions(+), 4 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 11303ae5de..195056deab 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -3359,6 +3359,18 @@ abstract class GenJSCode extends plugins.PluginComponent } } + /** See comment in `genEqEqPrimitive()` about `mustUseAnyComparator`. */ + private lazy val shouldPreserveEqEqBugWithJLFloatDouble = { + val v = scala.util.Properties.versionNumberString + + { + v.startsWith("2.10.") || + v.startsWith("2.11.") || + v == "2.12.0" || + v == "2.12.1" + } + } + /** Gen JS code for a call to Any.== */ def genEqEqPrimitive(ltpe: Type, rtpe: Type, lsrc: js.Tree, rsrc: js.Tree)( implicit pos: Position): js.Tree = { @@ -3368,13 +3380,30 @@ abstract class GenJSCode extends plugins.PluginComponent * This is the case when either side of the comparison might have a * run-time type subtype of java.lang.Number or java.lang.Character, * **which includes when either is a raw JS type**. + * * When it is statically known that both sides are equal and subtypes of * Number or Character, not using the rich equality is possible (their - * own equals method will do ok.) + * own equals method will do ok), except for java.lang.Float and + * java.lang.Double: their `equals` have different behavior around `NaN` + * and `-0.0`, see Javadoc (scala-dev#329, #2799). + * + * The latter case is only avoided in 2.12.2+, to remain bug-compatible + * with the Scala/JVM compiler. */ - val mustUseAnyComparator: Boolean = isRawJSType(ltpe) || isRawJSType(rtpe) || { - val areSameFinals = ltpe.isFinalType && rtpe.isFinalType && (ltpe =:= rtpe) - !areSameFinals && isMaybeBoxed(ltpe.typeSymbol) && isMaybeBoxed(rtpe.typeSymbol) + val mustUseAnyComparator: Boolean = { + isRawJSType(ltpe) || isRawJSType(rtpe) || { + isMaybeBoxed(ltpe.typeSymbol) && isMaybeBoxed(rtpe.typeSymbol) && { + val areSameFinals = + ltpe.isFinalType && rtpe.isFinalType && (ltpe =:= rtpe) + !areSameFinals || { + val sym = ltpe.typeSymbol + (sym == BoxedFloatClass || sym == BoxedDoubleClass) && { + // Bug-compatibility for Scala < 2.12.2 + !shouldPreserveEqEqBugWithJLFloatDouble + } + } + } + } } if (mustUseAnyComparator) { diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala index e3d27a4ade..e8ece13e2b 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala @@ -435,6 +435,106 @@ class RegressionTest { assertEquals((Nil, 10), result) } + private val hasEqEqJLFloatDoubleBug: Boolean = { + val v = Platform.scalaVersion + + { + v.startsWith("2.10.") || + v.startsWith("2.11.") || + v == "2.12.0" || + v == "2.12.1" + } + } + + def assertTrueUnlessEqEqJLFloatDoubleBug(actual: Boolean): Unit = { + if (hasEqEqJLFloatDoubleBug) + assertFalse(actual) + else + assertTrue(actual) + } + + @Test def eqEqJLDouble(): Unit = { + // Taken from run/sd329.scala in scala/scala + + def d1: Double = 0.0 + def d2: Double = -0.0 + def d3: Double = Double.NaN + def d4: Double = Double.NaN + assertTrue(d1 == d2) + assertTrue(d3 != d4) + + def d1B: java.lang.Double = d1 + def d2B: java.lang.Double = d2 + def d3B: java.lang.Double = d3 + def d4B: java.lang.Double = d4 + assertTrueUnlessEqEqJLFloatDoubleBug(d1B == d2B) + assertTrue(d1 == d1B) + assertTrue(d1B == d1) + assertTrueUnlessEqEqJLFloatDoubleBug(d3B != d4B) + assertTrue(d3 != d4B) + assertTrue(d3B != d4) + + assertFalse(d1B.equals(d2B)) // ! see javadoc + assertTrue(d3B.equals(d4B)) // ! see javadoc + + def d1A: Any = d1 + def d2A: Any = d2 + def d3A: Any = d3 + def d4A: Any = d4 + assertTrue(d1A == d2A) + assertTrue(d1 == d1A) + assertTrue(d1A == d1) + assertTrue(d1B == d1A) + assertTrue(d1A == d1B) + + assertTrue(d3A != d4A) + assertTrue(d3 != d4A) + assertTrue(d3A != d4) + assertTrue(d3B != d4A) + assertTrue(d3A != d4B) + } + + @Test def eqEqJLFloat(): Unit = { + // Taken from run/sd329.scala in scala/scala + + def f1: Float = 0.0f + def f2: Float = -0.0f + def f3: Float = Float.NaN + def f4: Float = Float.NaN + assertTrue(f1 == f2) + assertTrue(f3 != f4) + + def f1B: java.lang.Float = f1 + def f2B: java.lang.Float = f2 + def f3B: java.lang.Float = f3 + def f4B: java.lang.Float = f4 + assertTrueUnlessEqEqJLFloatDoubleBug(f1B == f2B) + assertTrue(f1 == f1B) + assertTrue(f1B == f1) + assertTrueUnlessEqEqJLFloatDoubleBug(f3B != f4B) + assertTrue(f3 != f4B) + assertTrue(f3B != f4) + + assertFalse(f1B.equals(f2B)) // ! see javadoc + assertTrue(f3B.equals(f4B)) // ! see javadoc + + def f1A: Any = f1 + def f2A: Any = f2 + def f3A: Any = f3 + def f4A: Any = f4 + assertTrue(f1A == f2A) + assertTrue(f1 == f1A) + assertTrue(f1A == f1) + assertTrue(f1B == f1A) + assertTrue(f1A == f1B) + + assertTrue(f3A != f4A) + assertTrue(f3 != f4A) + assertTrue(f3A != f4) + assertTrue(f3B != f4A) + assertTrue(f3A != f4B) + } + } object RegressionTest { From 01d2bd85a64eaa47e02a89dc0ee84283584a9cec Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 5 Mar 2017 21:21:09 +0100 Subject: [PATCH 0144/2665] Move .prototype to TreeDSL No point having two DSLs laying around. --- project/BinaryIncompatibilities.scala | 4 ++++ .../core/tools/linker/backend/emitter/JSDesugaring.scala | 5 ----- .../linker/backend/emitter/ScalaJSClassEmitter.scala | 9 +++++++-- .../core/tools/linker/backend/emitter/TreeDSL.scala | 2 ++ 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index e9d20d67e8..8e25bcc292 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -92,6 +92,10 @@ object BinaryIncompatibilities { "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.outputMode"), ProblemFilters.exclude[DirectMissingMethodProblem]( "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.semantics"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.MyTreeOps"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$MyTreeOps"), ProblemFilters.exclude[DirectMissingMethodProblem]( "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.genCallHelper"), ProblemFilters.exclude[DirectMissingMethodProblem]( diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala index 92a7fb2db5..6733dd7ddb 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala @@ -2531,11 +2531,6 @@ private[emitter] class JSDesugaring(semantics: Semantics, js.BracketSelect(qual, js.StringLiteral(item)) } - private[emitter] implicit class MyTreeOps(val self: js.Tree) { - def prototype(implicit pos: Position): js.Tree = - js.DotSelect(self, js.Ident("prototype")) - } - class DesugarException(tree: Tree, cause: Throwable) extends Exception(exceptionMsg(tree), cause) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala index b14807eee5..aed1f2326b 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala @@ -196,6 +196,7 @@ private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, /** Generates the JS constructor for a class, ES5 style. */ private def genES5Constructor(tree: LinkedClass)( implicit globalKnowledge: GlobalKnowledge): js.Tree = { + import TreeDSL._ implicit val pos = tree.pos val className = tree.name.name @@ -206,7 +207,7 @@ private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, js.DocComment("@constructor"), envFieldDef("h", className, js.Function(Nil, js.Skip()), keepFunctionExpression = isJSClass), - js.Assign(envField("h", className).prototype, ctorToMimic.prototype) + envField("h", className).prototype := ctorToMimic.prototype ) } @@ -238,9 +239,10 @@ private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, val superCtor = genRawJSClassConstructor(parentIdent.name) (makeInheritableCtorDef(superCtor), envField("h", className)) } + js.Block( inheritedCtorDef, - js.Assign(typeVar.prototype, js.New(inheritedCtorRef, Nil)), + typeVar.prototype := js.New(inheritedCtorRef, Nil), genAddToPrototype(className, js.StringLiteral("constructor"), typeVar) ) } @@ -435,6 +437,7 @@ private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, private def genPropertyES5(className: String, property: PropertyDef)( implicit globalKnowledge: GlobalKnowledge): js.Tree = { + import TreeDSL._ implicit val pos = property.pos // defineProperty method @@ -508,6 +511,8 @@ private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, /** Generate `classVar.prototype.name = value` */ def genAddToPrototype(className: String, name: js.PropertyName, value: js.Tree)( implicit globalKnowledge: GlobalKnowledge, pos: Position): js.Tree = { + import TreeDSL._ + genAddToObject(encodeClassVar(className).prototype, name, value) } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/TreeDSL.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/TreeDSL.scala index 34e45f5dc4..a90ea68abf 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/TreeDSL.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/TreeDSL.scala @@ -47,6 +47,8 @@ private[emitter] object TreeDSL { def :=(that: Tree)(implicit pos: Position): Tree = Assign(self, that) + + def prototype(implicit pos: Position): Tree = self DOT "prototype" } def typeof(expr: Tree)(implicit pos: Position): Tree = From 9599879a61daf5a137586a44ef2cd2f0eb093bd3 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 5 Mar 2017 21:40:09 +0100 Subject: [PATCH 0145/2665] Remove unused stuff. --- project/BinaryIncompatibilities.scala | 4 ++++ .../core/tools/linker/backend/emitter/Emitter.scala | 2 -- .../tools/linker/backend/emitter/JSDesugaring.scala | 10 ---------- .../linker/backend/emitter/ScalaJSClassEmitter.scala | 5 ----- 4 files changed, 4 insertions(+), 17 deletions(-) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 8e25bcc292..09453aebe8 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -92,10 +92,14 @@ object BinaryIncompatibilities { "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.outputMode"), ProblemFilters.exclude[DirectMissingMethodProblem]( "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.semantics"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.this"), ProblemFilters.exclude[DirectMissingMethodProblem]( "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.MyTreeOps"), ProblemFilters.exclude[MissingClassProblem]( "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$MyTreeOps"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$DesugarException"), ProblemFilters.exclude[DirectMissingMethodProblem]( "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.genCallHelper"), ProblemFilters.exclude[DirectMissingMethodProblem]( diff --git 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 index 46c3e4a8ea..4204430932 100644 --- 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 @@ -45,8 +45,6 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, def this(semantics: Semantics, outputMode: OutputMode) = this(semantics, outputMode, ModuleKind.NoModule, InternalOptions()) - private implicit def implicitOutputMode: OutputMode = outputMode - private val knowledgeGuardian = new KnowledgeGuardian private val classEmitter = diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala index 6733dd7ddb..309147006d 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala @@ -2530,16 +2530,6 @@ private[emitter] class JSDesugaring(semantics: Semantics, else js.BracketSelect(qual, js.StringLiteral(item)) } - - class DesugarException(tree: Tree, - cause: Throwable) extends Exception(exceptionMsg(tree), cause) - - private def exceptionMsg(tree: Tree): String = { - val writer = new StringWriter - val printer = new ir.Printers.IRTreePrinter(writer) - printer.printTopLevelTree(tree) - "Exception while desugaring: " + writer.toString - } } private object JSDesugaring { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala index aed1f2326b..45d40af057 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala @@ -32,11 +32,6 @@ private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, import ScalaJSClassEmitter._ import jsDesugaring._ - def this(semantics: Semantics, outputMode: OutputMode) = - this(semantics, outputMode, InternalOptions()) - - private implicit def implicitOutputMode: OutputMode = outputMode - /** Desugars a Scala.js class specifically for use by the Rhino interpreter. * * @param tree The IR tree to emit to raw JavaScript From e5f16cd4b6e3deb6121a8b4d7b28f14c55b967aa Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 5 Mar 2017 22:01:06 +0100 Subject: [PATCH 0146/2665] Factor JS tree generation into new JSGen --- project/BinaryIncompatibilities.scala | 14 + .../linker/backend/emitter/Emitter.scala | 9 +- .../linker/backend/emitter/JSDesugaring.scala | 291 +---------------- .../tools/linker/backend/emitter/JSGen.scala | 297 ++++++++++++++++++ .../backend/emitter/ScalaJSClassEmitter.scala | 7 +- 5 files changed, 325 insertions(+), 293 deletions(-) create mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 09453aebe8..82057a21a7 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -130,6 +130,20 @@ object BinaryIncompatibilities { "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.this"), ProblemFilters.exclude[DirectMissingMethodProblem]( "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring#JSDesugar.this"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.envField$default$3"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.genBracketSelect"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.envModuleField"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.genIdentBracketSelect"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.transformParamDef"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.transformIdent"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.this"), // private, not an issue. ProblemFilters.exclude[DirectMissingMethodProblem]( diff --git 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 index 4204430932..bf0b9bc4e9 100644 --- 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 @@ -47,8 +47,8 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, private val knowledgeGuardian = new KnowledgeGuardian - private val classEmitter = - new ScalaJSClassEmitter(semantics, outputMode, internalOptions) + private val jsGen = new JSGen(semantics, outputMode, internalOptions) + private val classEmitter = new ScalaJSClassEmitter(jsGen) private val classCaches = mutable.Map.empty[List[String], ClassCache] @@ -163,7 +163,6 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, } case ModuleKind.CommonJSModule => - val jsDesugaring = new JSDesugaring(semantics, outputMode, internalOptions) val encounteredModuleNames = mutable.Set.empty[String] for (classDef <- orderedClasses) { classDef.jsNativeLoadSpec match { @@ -175,8 +174,8 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, implicit val pos = classDef.pos val rhs = js.Apply(js.VarRef(js.Ident("require")), List(js.StringLiteral(module))) - val lhs = jsDesugaring.envModuleField(module) - val decl = jsDesugaring.genLet(lhs.ident, mutable = false, rhs) + val lhs = jsGen.envModuleField(module) + val decl = jsGen.genLet(lhs.ident, mutable = false, rhs) builder.addJSTree(decl) } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala index 309147006d..e8a31d15cf 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala @@ -9,8 +9,6 @@ package org.scalajs.core.tools.linker.backend.emitter -import scala.language.implicitConversions - import scala.annotation.{switch, tailrec} import scala.collection.mutable @@ -195,15 +193,13 @@ import java.io.StringWriter * * @author Sébastien Doeraene */ -private[emitter] class JSDesugaring(semantics: Semantics, - outputMode: OutputMode, internalOptions: InternalOptions) { +private[emitter] class JSDesugaring(jsGen: JSGen) { import JSDesugaring._ - - private final val ScalaJSEnvironmentName = "ScalaJS" + import jsGen._ /** Desugars parameters and body to a JS function. */ - private[emitter] def desugarToFunction( + def desugarToFunction( enclosingClassName: String, params: List[ParamDef], body: Tree, isStat: Boolean)( implicit globalKnowledge: GlobalKnowledge, pos: Position): js.Function = { @@ -213,7 +209,7 @@ private[emitter] class JSDesugaring(semantics: Semantics, /** Desugars parameters and body to a JS function. */ - private[emitter] def desugarToFunction( + def desugarToFunction( enclosingClassName: String, thisIdent: Option[js.Ident], params: List[ParamDef], body: Tree, isStat: Boolean)( @@ -227,7 +223,7 @@ private[emitter] class JSDesugaring(semantics: Semantics, /** Desugars parameters and body to a JS function. */ - private[emitter] def desugarToFunction( + def desugarToFunction( params: List[ParamDef], body: Tree, isStat: Boolean)( implicit globalKnowledge: GlobalKnowledge, pos: Position): js.Function = { @@ -235,7 +231,7 @@ private[emitter] class JSDesugaring(semantics: Semantics, } /** Desugars a statement or an expression. */ - private[emitter] def desugarTree( + def desugarTree( enclosingClassName: Option[String], tree: Tree, isStat: Boolean)( implicit globalKnowledge: GlobalKnowledge): js.Tree = { @@ -247,10 +243,7 @@ private[emitter] class JSDesugaring(semantics: Semantics, desugar.transformExpr(tree)(env) } - private[emitter] implicit def transformIdent(ident: Ident): js.Ident = - js.Ident(ident.name, ident.originalName)(ident.pos) - - private[emitter] def transformParamDef(paramDef: ParamDef): js.ParamDef = + private def transformParamDef(paramDef: ParamDef): js.ParamDef = js.ParamDef(paramDef.name, paramDef.rest)(paramDef.pos) private class JSDesugar()(implicit globalKnowledge: GlobalKnowledge) { @@ -2260,276 +2253,6 @@ private[emitter] class JSDesugaring(semantics: Semantics, } } } - - // Helpers - - private[emitter] def genZeroOf(tpe: Type)(implicit pos: Position): js.Tree = { - tpe match { - case BooleanType => js.BooleanLiteral(false) - case IntType => js.IntLiteral(0) - case LongType => genLongZero() - case FloatType => js.DoubleLiteral(0.0) - case DoubleType => js.DoubleLiteral(0.0) - case StringType => js.StringLiteral("") - case UndefType => js.Undefined() - case _ => js.Null() - } - } - - private def genLongZero()(implicit pos: Position): js.Tree = { - genLongModuleApply(LongImpl.Zero) - } - - private def genLongModuleApply(methodName: String, args: js.Tree*)( - implicit pos: Position): js.Tree = { - import TreeDSL._ - js.Apply( - genLoadModule(LongImpl.RuntimeLongModuleClass) DOT methodName, - args.toList) - } - - private[emitter] def genLet(name: js.Ident, mutable: Boolean, rhs: js.Tree)( - implicit pos: Position): js.LocalDef = { - outputMode match { - case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => - js.VarDef(name, Some(rhs)) - case OutputMode.ECMAScript6 => - js.Let(name, mutable, Some(rhs)) - } - } - - private[emitter] def genEmptyMutableLet(name: js.Ident)( - implicit pos: Position): js.LocalDef = { - outputMode match { - case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => - js.VarDef(name, rhs = None) - case OutputMode.ECMAScript6 => - js.Let(name, mutable = true, rhs = None) - } - } - - private[emitter] def genSelectStatic(className: String, item: Ident)( - implicit pos: Position): js.Tree = { - envField("t", className + "__" + item.name) - } - - private[emitter] def genIsInstanceOf(expr: js.Tree, cls: ReferenceType)( - implicit pos: Position): js.Tree = - genIsAsInstanceOf(expr, cls, test = true) - - private def genAsInstanceOf(expr: js.Tree, cls: ReferenceType)( - implicit pos: Position): js.Tree = - genIsAsInstanceOf(expr, cls, test = false) - - private def genIsAsInstanceOf(expr: js.Tree, cls: ReferenceType, test: Boolean)( - implicit pos: Position): js.Tree = { - import Definitions._ - import TreeDSL._ - - cls match { - case ClassType(className0) => - val className = - if (className0 == BoxedLongClass) LongImpl.RuntimeLongClass - else className0 - - if (HijackedBoxedClasses.contains(className)) { - if (test) { - className match { - case BoxedUnitClass => expr === js.Undefined() - case BoxedBooleanClass => typeof(expr) === "boolean" - case BoxedByteClass => genCallHelper("isByte", expr) - case BoxedShortClass => genCallHelper("isShort", expr) - case BoxedIntegerClass => genCallHelper("isInt", expr) - case BoxedFloatClass => genCallHelper("isFloat", expr) - case BoxedDoubleClass => typeof(expr) === "number" - } - } else { - className match { - case BoxedUnitClass => genCallHelper("asUnit", expr) - case BoxedBooleanClass => genCallHelper("asBoolean", expr) - case BoxedByteClass => genCallHelper("asByte", expr) - case BoxedShortClass => genCallHelper("asShort", expr) - case BoxedIntegerClass => genCallHelper("asInt", expr) - case BoxedFloatClass => genCallHelper("asFloat", expr) - case BoxedDoubleClass => genCallHelper("asDouble", expr) - } - } - } else { - js.Apply( - envField(if (test) "is" else "as", className), - List(expr)) - } - - case ArrayType(base, depth) => - js.Apply( - envField(if (test) "isArrayOf" else "asArrayOf", base), - List(expr, js.IntLiteral(depth))) - } - } - - private[emitter] def genCallHelper(helperName: String, args: js.Tree*)( - implicit pos: Position): js.Tree = { - js.Apply(envField(helperName), args.toList) - } - - private[emitter] def encodeClassVar(className: String)( - implicit pos: Position): js.Tree = - envField("c", className) - - private[emitter] def genLoadModule(moduleClass: String)( - implicit pos: Position): js.Tree = { - import TreeDSL._ - js.Apply(envField("m", moduleClass), Nil) - } - - private[emitter] def genRawJSClassConstructor(className: String)( - implicit globalKnowledge: GlobalKnowledge, pos: Position): js.Tree = { - - genRawJSClassConstructor(className, - globalKnowledge.getJSNativeLoadSpec(className)) - } - - private[emitter] def genRawJSClassConstructor(className: String, - spec: Option[JSNativeLoadSpec])( - implicit pos: Position): js.Tree = { - spec match { - case None => - // This is a Scala.js-defined JS class, call its class value accessor - js.Apply(envField("a", className), Nil) - - case Some(spec) => - genLoadJSFromSpec(spec) - } - } - - private[emitter] def genLoadJSFromSpec(spec: JSNativeLoadSpec)( - implicit pos: Position): js.Tree = { - - def pathSelection(from: js.Tree, path: List[String]): js.Tree = { - path.foldLeft(from) { - (prev, part) => genBracketSelect(prev, js.StringLiteral(part)) - } - } - - spec match { - case JSNativeLoadSpec.Global(path) => - pathSelection(envField("g"), path) - - case JSNativeLoadSpec.Import(module, path) => - val moduleValue = envModuleField(module) - path match { - case DefaultExportName :: rest => - val defaultField = genCallHelper("moduleDefault", moduleValue) - pathSelection(defaultField, rest) - case _ => - pathSelection(moduleValue, path) - } - } - } - - private final val DefaultExportName = "default" - - private[emitter] def envModuleField(module: String)( - implicit pos: Position): js.VarRef = { - - /* This is written so that the happy path, when `module` contains only - * valid characters, is fast. - */ - - def isValidChar(c: Char): Boolean = - (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') - - def containsOnlyValidChars(): Boolean = { - val len = module.length - var i = 0 - while (i != len) { - if (!isValidChar(module.charAt(i))) - return false - i += 1 - } - true - } - - def buildValidName(): String = { - val result = new java.lang.StringBuilder("$i_") - val len = module.length - var i = 0 - while (i != len) { - val c = module.charAt(i) - if (isValidChar(c)) - result.append(c) - else - result.append("$%04x".format(c.toInt)) - i += 1 - } - result.toString() - } - - val varName = - if (containsOnlyValidChars()) "$i_" + module - else buildValidName() - - js.VarRef(js.Ident(varName, Some(module))) - } - - private[emitter] def envField(field: String, subField: String, - origName: Option[String] = None)( - implicit pos: Position): js.Tree = { - import TreeDSL._ - - outputMode match { - case OutputMode.ECMAScript51Global => - envField(field) DOT js.Ident(subField, origName) - - case OutputMode.ECMAScript51Isolated | OutputMode.ECMAScript6 => - js.VarRef(js.Ident("$" + field + "_" + subField, origName)) - } - } - - private[emitter] def envField(field: String)( - implicit pos: Position): js.Tree = { - import TreeDSL._ - - outputMode match { - case OutputMode.ECMAScript51Global => - js.VarRef(js.Ident(ScalaJSEnvironmentName)) DOT field - - case OutputMode.ECMAScript51Isolated | OutputMode.ECMAScript6 => - js.VarRef(js.Ident("$" + field)) - } - } - - private[emitter] def genPropSelect(qual: js.Tree, item: js.PropertyName)( - implicit pos: Position): js.Tree = { - item match { - case item: js.Ident => js.DotSelect(qual, item) - case item: js.StringLiteral => genBracketSelect(qual, item) - case js.ComputedName(tree) => genBracketSelect(qual, tree) - } - } - - private[emitter] def genBracketSelect(qual: js.Tree, item: js.Tree)( - implicit pos: Position): js.Tree = { - item match { - case js.StringLiteral(name) if internalOptions.optimizeBracketSelects && - isValidIdentifier(name) && name != "eval" => - /* We exclude "eval" because Rhino does not respect the strict mode - * specificities of eval(). - */ - js.DotSelect(qual, js.Ident(name)) - case _ => - js.BracketSelect(qual, item) - } - } - - private[emitter] def genIdentBracketSelect(qual: js.Tree, item: String)( - implicit pos: Position): js.Tree = { - require(item != "eval") - if (internalOptions.optimizeBracketSelects) - js.DotSelect(qual, js.Ident(item)) - else - js.BracketSelect(qual, js.StringLiteral(item)) - } } private object JSDesugaring { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala new file mode 100644 index 0000000000..8ae3e3487b --- /dev/null +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala @@ -0,0 +1,297 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package org.scalajs.core.tools.linker.backend.emitter + +import scala.language.implicitConversions + +import org.scalajs.core.ir +import ir._ +import ir.Types._ +import ir.{Trees => irt} + +import org.scalajs.core.tools.sem._ +import org.scalajs.core.tools.linker.backend.OutputMode +import org.scalajs.core.tools.javascript.Trees._ + +/** Collection of tree generators that are used accross the board. + * This class is fully stateless. + * + * Also carries around config (semantics and outputMode). + */ +private[emitter] final class JSGen(val semantics: Semantics, + val outputMode: OutputMode, internalOptions: InternalOptions) { + import JSGen._ + + implicit def transformIdent(ident: irt.Ident): Ident = + Ident(ident.name, ident.originalName)(ident.pos) + + def genZeroOf(tpe: Type)(implicit pos: Position): Tree = { + tpe match { + case BooleanType => BooleanLiteral(false) + case IntType => IntLiteral(0) + case LongType => genLongZero() + case FloatType => DoubleLiteral(0.0) + case DoubleType => DoubleLiteral(0.0) + case StringType => StringLiteral("") + case UndefType => Undefined() + case _ => Null() + } + } + + def genLongZero()(implicit pos: Position): Tree = { + genLongModuleApply(LongImpl.Zero) + } + + def genLongModuleApply(methodName: String, args: Tree*)( + implicit pos: Position): Tree = { + import TreeDSL._ + Apply( + genLoadModule(LongImpl.RuntimeLongModuleClass) DOT methodName, + args.toList) + } + + def genLet(name: Ident, mutable: Boolean, rhs: Tree)( + implicit pos: Position): LocalDef = { + outputMode match { + case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => + VarDef(name, Some(rhs)) + case OutputMode.ECMAScript6 => + Let(name, mutable, Some(rhs)) + } + } + + def genEmptyMutableLet(name: Ident)(implicit pos: Position): LocalDef = { + outputMode match { + case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => + VarDef(name, rhs = None) + case OutputMode.ECMAScript6 => + Let(name, mutable = true, rhs = None) + } + } + + def genSelectStatic(className: String, item: irt.Ident)( + implicit pos: Position): Tree = { + envField("t", className + "__" + item.name) + } + + def genIsInstanceOf(expr: Tree, cls: ReferenceType)( + implicit pos: Position): Tree = + genIsAsInstanceOf(expr, cls, test = true) + + def genAsInstanceOf(expr: Tree, cls: ReferenceType)( + implicit pos: Position): Tree = + genIsAsInstanceOf(expr, cls, test = false) + + private def genIsAsInstanceOf(expr: Tree, cls: ReferenceType, test: Boolean)( + implicit pos: Position): Tree = { + import Definitions._ + import TreeDSL._ + + cls match { + case ClassType(className0) => + val className = + if (className0 == BoxedLongClass) LongImpl.RuntimeLongClass + else className0 + + if (HijackedBoxedClasses.contains(className)) { + if (test) { + className match { + case BoxedUnitClass => expr === Undefined() + case BoxedBooleanClass => typeof(expr) === "boolean" + case BoxedByteClass => genCallHelper("isByte", expr) + case BoxedShortClass => genCallHelper("isShort", expr) + case BoxedIntegerClass => genCallHelper("isInt", expr) + case BoxedFloatClass => genCallHelper("isFloat", expr) + case BoxedDoubleClass => typeof(expr) === "number" + } + } else { + className match { + case BoxedUnitClass => genCallHelper("asUnit", expr) + case BoxedBooleanClass => genCallHelper("asBoolean", expr) + case BoxedByteClass => genCallHelper("asByte", expr) + case BoxedShortClass => genCallHelper("asShort", expr) + case BoxedIntegerClass => genCallHelper("asInt", expr) + case BoxedFloatClass => genCallHelper("asFloat", expr) + case BoxedDoubleClass => genCallHelper("asDouble", expr) + } + } + } else { + Apply( + envField(if (test) "is" else "as", className), + List(expr)) + } + + case ArrayType(base, depth) => + Apply( + envField(if (test) "isArrayOf" else "asArrayOf", base), + List(expr, IntLiteral(depth))) + } + } + + def genCallHelper(helperName: String, args: Tree*)( + implicit pos: Position): Tree = { + Apply(envField(helperName), args.toList) + } + + def encodeClassVar(className: String)(implicit pos: Position): Tree = + envField("c", className) + + def genLoadModule(moduleClass: String)(implicit pos: Position): Tree = { + import TreeDSL._ + Apply(envField("m", moduleClass), Nil) + } + + def genRawJSClassConstructor(className: String)( + implicit globalKnowledge: GlobalKnowledge, pos: Position): Tree = { + + genRawJSClassConstructor(className, + globalKnowledge.getJSNativeLoadSpec(className)) + } + + def genRawJSClassConstructor(className: String, + spec: Option[irt.JSNativeLoadSpec])( + implicit pos: Position): Tree = { + spec match { + case None => + // This is a Scala.js-defined JS class, call its class value accessor + Apply(envField("a", className), Nil) + + case Some(spec) => + genLoadJSFromSpec(spec) + } + } + + def genLoadJSFromSpec(spec: irt.JSNativeLoadSpec)( + implicit pos: Position): Tree = { + + def pathSelection(from: Tree, path: List[String]): Tree = { + path.foldLeft(from) { + (prev, part) => genBracketSelect(prev, StringLiteral(part)) + } + } + + spec match { + case irt.JSNativeLoadSpec.Global(path) => + pathSelection(envField("g"), path) + + case irt.JSNativeLoadSpec.Import(module, path) => + val moduleValue = envModuleField(module) + path match { + case DefaultExportName :: rest => + val defaultField = genCallHelper("moduleDefault", moduleValue) + pathSelection(defaultField, rest) + case _ => + pathSelection(moduleValue, path) + } + } + } + + def envModuleField(module: String)(implicit pos: Position): VarRef = { + /* This is written so that the happy path, when `module` contains only + * valid characters, is fast. + */ + + def isValidChar(c: Char): Boolean = + (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') + + def containsOnlyValidChars(): Boolean = { + val len = module.length + var i = 0 + while (i != len) { + if (!isValidChar(module.charAt(i))) + return false + i += 1 + } + true + } + + def buildValidName(): String = { + val result = new java.lang.StringBuilder("$i_") + val len = module.length + var i = 0 + while (i != len) { + val c = module.charAt(i) + if (isValidChar(c)) + result.append(c) + else + result.append("$%04x".format(c.toInt)) + i += 1 + } + result.toString() + } + + val varName = + if (containsOnlyValidChars()) "$i_" + module + else buildValidName() + + VarRef(Ident(varName, Some(module))) + } + + def envField(field: String, subField: String, origName: Option[String] = None)( + implicit pos: Position): Tree = { + import TreeDSL._ + + outputMode match { + case OutputMode.ECMAScript51Global => + envField(field) DOT Ident(subField, origName) + + case OutputMode.ECMAScript51Isolated | OutputMode.ECMAScript6 => + VarRef(Ident("$" + field + "_" + subField, origName)) + } + } + + def envField(field: String)(implicit pos: Position): Tree = { + import TreeDSL._ + + outputMode match { + case OutputMode.ECMAScript51Global => + VarRef(Ident(ScalaJSEnvironmentName)) DOT field + + case OutputMode.ECMAScript51Isolated | OutputMode.ECMAScript6 => + VarRef(Ident("$" + field)) + } + } + + def genPropSelect(qual: Tree, item: PropertyName)( + implicit pos: Position): Tree = { + item match { + case item: Ident => DotSelect(qual, item) + case item: StringLiteral => genBracketSelect(qual, item) + case ComputedName(tree) => genBracketSelect(qual, tree) + } + } + + def genBracketSelect(qual: Tree, item: Tree)(implicit pos: Position): Tree = { + item match { + case StringLiteral(name) if internalOptions.optimizeBracketSelects && + irt.isValidIdentifier(name) && name != "eval" => + /* We exclude "eval" because Rhino does not respect the strict mode + * specificities of eval(). + */ + DotSelect(qual, Ident(name)) + case _ => + BracketSelect(qual, item) + } + } + + def genIdentBracketSelect(qual: Tree, item: String)( + implicit pos: Position): Tree = { + require(item != "eval") + if (internalOptions.optimizeBracketSelects) + DotSelect(qual, Ident(item)) + else + BracketSelect(qual, StringLiteral(item)) + } +} + +private object JSGen { + private final val ScalaJSEnvironmentName = "ScalaJS" + private final val DefaultExportName = "default" +} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala index 45d40af057..54248b6b26 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala @@ -23,14 +23,13 @@ import org.scalajs.core.tools.linker.backend.OutputMode import org.scalajs.core.tools.linker.{LinkedClass, LinkingUnit} /** Emitter for the skeleton of classes. */ -private[emitter] final class ScalaJSClassEmitter(semantics: Semantics, - outputMode: OutputMode, internalOptions: InternalOptions) { +private[emitter] final class ScalaJSClassEmitter(jsGen: JSGen) { - private val jsDesugaring = - new JSDesugaring(semantics, outputMode, internalOptions) + private val jsDesugaring = new JSDesugaring(jsGen) import ScalaJSClassEmitter._ import jsDesugaring._ + import jsGen._ /** Desugars a Scala.js class specifically for use by the Rhino interpreter. * From 87a93a0ed9ad2ee0a8869d601955b3390ea039a7 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 5 Mar 2017 22:02:50 +0100 Subject: [PATCH 0147/2665] Rename internals. ScalaJSClassEmitter -> ClassEmitter JSDesugaring -> FunctionEmitter --- project/BinaryIncompatibilities.scala | 106 +++++++----------- ...SClassEmitter.scala => ClassEmitter.scala} | 10 +- .../linker/backend/emitter/Emitter.scala | 2 +- ...Desugaring.scala => FunctionEmitter.scala} | 12 +- 4 files changed, 52 insertions(+), 78 deletions(-) rename tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/{ScalaJSClassEmitter.scala => ClassEmitter.scala} (99%) rename tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/{JSDesugaring.scala => FunctionEmitter.scala} (99%) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 82057a21a7..4df1cdc81e 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -78,76 +78,50 @@ object BinaryIncompatibilities { "org.scalajs.core.tools.linker.backend.closure.ClosureAstTransformer.transformString"), // private[emitter], not an issue - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genAddToPrototype"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genClass"), - ProblemFilters.exclude[MissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genClassDef"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genPropertyName"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.genTopLevelExportDef"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.outputMode"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.semantics"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter.this"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.MyTreeOps"), ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$MyTreeOps"), + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter$"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring"), ProblemFilters.exclude[MissingClassProblem]( "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$DesugarException"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.genCallHelper"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.genLet"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.genRawJSClassConstructor"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.genEmptyMutableLet"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.desugarTree"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.genLoadJSFromSpec"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.encodeClassVar"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.desugarToFunction"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.desugarToFunction"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.envField"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.envFieldDef"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.envFieldDef"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.genIsInstanceOf"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.this"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring#JSDesugar.this"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.envField$default$3"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.genBracketSelect"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.envModuleField"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.genIdentBracketSelect"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.transformParamDef"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.transformIdent"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring.this"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$MyTreeOps"), - // private, not an issue. - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring#Env.this") + // private, not an issue + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$JSDesugar"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$JSDesugar$RecordFieldVarRef$"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$JSDesugar$RecordVarRef$"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$JSDesugar$RecordAwareEnv"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$Lhs"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$Lhs$"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$Lhs$Assign"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$Lhs$Assign$"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$Lhs$Return"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$Lhs$Return$"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$Lhs$Discard$"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$Lhs$VarDef$"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$Lhs$VarDef"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$Env"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$Env$") ) val JSEnvs = Seq( diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala similarity index 99% rename from tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala rename to tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index 54248b6b26..b4f4bb42da 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ScalaJSClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -23,12 +23,12 @@ import org.scalajs.core.tools.linker.backend.OutputMode import org.scalajs.core.tools.linker.{LinkedClass, LinkingUnit} /** Emitter for the skeleton of classes. */ -private[emitter] final class ScalaJSClassEmitter(jsGen: JSGen) { +private[emitter] final class ClassEmitter(jsGen: JSGen) { - private val jsDesugaring = new JSDesugaring(jsGen) + private val functionEmitter = new FunctionEmitter(jsGen) - import ScalaJSClassEmitter._ - import jsDesugaring._ + import ClassEmitter._ + import functionEmitter._ import jsGen._ /** Desugars a Scala.js class specifically for use by the Rhino interpreter. @@ -1167,7 +1167,7 @@ private[emitter] final class ScalaJSClassEmitter(jsGen: JSGen) { } -private object ScalaJSClassEmitter { +private object ClassEmitter { private val ClassesWhoseDataReferToTheirInstanceTests = { Definitions.AncestorsOfHijackedClasses + Definitions.ObjectClass + Definitions.StringClass diff --git 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 index bf0b9bc4e9..b800dd46cf 100644 --- 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 @@ -48,7 +48,7 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, private val knowledgeGuardian = new KnowledgeGuardian private val jsGen = new JSGen(semantics, outputMode, internalOptions) - private val classEmitter = new ScalaJSClassEmitter(jsGen) + private val classEmitter = new ClassEmitter(jsGen) private val classCaches = mutable.Map.empty[List[String], ClassCache] diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/FunctionEmitter.scala similarity index 99% rename from tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala rename to tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/FunctionEmitter.scala index e8a31d15cf..854c460241 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSDesugaring.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/FunctionEmitter.scala @@ -29,7 +29,7 @@ import org.scalajs.core.tools.javascript.{Trees => js} import java.io.StringWriter -/** Desugaring of the IR to JavaScript. +/** Desugaring of the IR to JavaScript functions. * * The general shape and compliance to standards is chosen with an * [[OutputMode]]. @@ -95,14 +95,14 @@ import java.io.StringWriter * * -------------------------------------------------------------------------- * - * JSDesugaring does all this in a single pass, but it helps to think that: + * FunctionEmitter does all this in a single pass, but it helps to think that: * * Rule 1) is implemented by unnest(), and used most notably in * * transformStat() for statement-only constructs * * pushLhsInto() for statement-or-expression constructs * * Rule 2) is implemented by pushLhsInto() * * Emitting the class structure is delegated to [[ScalaJSClassEmitter]]. * - * There are a few other things that JSDesugaring takes care of: + * There are a few other things that FunctionEmitter takes care of: * * Transform Scala expressions into their JS equivalent, taking the * Scala.js class encoding into account. * * And tiny details. @@ -193,8 +193,8 @@ import java.io.StringWriter * * @author Sébastien Doeraene */ -private[emitter] class JSDesugaring(jsGen: JSGen) { - import JSDesugaring._ +private[emitter] class FunctionEmitter(jsGen: JSGen) { + import FunctionEmitter._ import jsGen._ /** Desugars parameters and body to a JS function. @@ -2255,7 +2255,7 @@ private[emitter] class JSDesugaring(jsGen: JSGen) { } } -private object JSDesugaring { +private object FunctionEmitter { /** A left hand side that can be pushed into a right hand side tree. */ sealed abstract class Lhs { def hasNothingType: Boolean = false From 4437be8dabbf915cee05c2783be421af8ddf779b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 15 Mar 2017 11:28:29 +0100 Subject: [PATCH 0148/2665] Fix #2744: Restrict @JSExportStatic fields to be defined first. More precisely, they must be defined before non-static fields, as well as before any constructor statement. This makes sure that there is no initialization code that can run before their own. This makes `@JSExportStatic` consistent with the `@static` SIP (SIP-25). --- .../scalajs/core/compiler/PrepJSInterop.scala | 22 ++++++ .../core/compiler/test/JSExportTest.scala | 74 +++++++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index ee7a8ec579..1b3454e6e2 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -401,6 +401,28 @@ abstract class PrepJSInterop extends plugins.PluginComponent case Template(parents, self, body) => val clsSym = tree.symbol.owner + + // Check that @JSExportStatic fields come first + if (clsSym.isModuleClass) { // quick check to avoid useless work + var foundStatOrNonStaticVal: Boolean = false + for (tree <- body) { + tree match { + case vd: ValDef if vd.symbol.hasAnnotation(JSExportStaticAnnotation) => + if (foundStatOrNonStaticVal) { + reporter.error(vd.pos, + "@JSExportStatic vals and vars must be defined before " + + "any other val/var, and before any constructor " + + "statement.") + } + case vd: ValDef if !vd.symbol.isLazy => + foundStatOrNonStaticVal = true + case _: MemberDef => + case _ => + foundStatOrNonStaticVal = true + } + } + } + val exports = exporters.get(clsSym).toIterable.flatten // Add exports to the template treeCopy.Template(tree, parents, self, body ++ exports) diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index 60508bce30..c06b73c4fe 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -1787,4 +1787,78 @@ class JSExportTest extends DirectTest with TestHelpers { | ^ """ } + + @Test + def noExportStaticFieldAfterStatOrNonStaticField: Unit = { + for { + offendingDecl <- Seq( + "val a: Int = 1", + "var a: Int = 1", + """println("foo")""" + ) + } + s""" + @ScalaJSDefined + class StaticContainer extends js.Object + + object StaticContainer { + $offendingDecl + + @JSExportStatic + val b: Int = 1 + + @JSExportStatic + var c: Int = 1 + + @JSExportStatic + def d: Int = 1 + + @JSExportStatic + def d_=(v: Int): Unit = () + + @JSExportStatic + def e(): Int = 1 + } + """ hasErrors + """ + |newSource1.scala:10: error: @JSExportStatic vals and vars must be defined before any other val/var, and before any constructor statement. + | val b: Int = 1 + | ^ + |newSource1.scala:13: error: @JSExportStatic vals and vars must be defined before any other val/var, and before any constructor statement. + | var c: Int = 1 + | ^ + """ + + for { + validDecl <- Seq( + "@JSExportStatic val a: Int = 1", + "@JSExportStatic var a: Int = 1", + "lazy val a: Int = 1", + "def a: Int = 1", + "def a_=(v: Int): Unit = ()", + "def a(): Int = 1", + "@JSExportStatic def a: Int = 1", + "@JSExportStatic def a_=(v: Int): Unit = ()", + "@JSExportStatic def a(): Int = 1", + "class A", + "object A", + "trait A", + "type A = Int" + ) + } + s""" + @ScalaJSDefined + class StaticContainer extends js.Object + + object StaticContainer { + $validDecl + + @JSExportStatic + val b: Int = 1 + + @JSExportStatic + var c: Int = 1 + } + """.succeeds + } } From b3900f655f99343c8e294407c90342eaa07bc13d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 16 Mar 2017 21:00:05 +0100 Subject: [PATCH 0149/2665] Disallow exports of lazy vals to the top-level. Exporting a lazy val to the top level does not make sense, because they must be evaluated at module loading time. In fact, the generated code was buggy. --- .../org/scalajs/core/compiler/PrepJSExports.scala | 5 ++++- .../scalajs/core/compiler/test/JSExportTest.scala | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala index 543a951a20..53cb3e66e7 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala @@ -390,7 +390,10 @@ trait PrepJSExports { this: PrepJSInterop => } case ExportDestination.TopLevel => - if (!sym.isAccessor && jsInterop.isJSProperty(sym)) { + if (sym.isLazy) { + reporter.error(annot.pos, + "You may not export a lazy val to the top level") + } else if (!sym.isAccessor && jsInterop.isJSProperty(sym)) { reporter.error(annot.pos, "You may not export a getter or a setter to the top level") } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index c06b73c4fe..94b2237376 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -1138,6 +1138,21 @@ class JSExportTest extends DirectTest with TestHelpers { """ } + @Test + def noExportTopLevelLazyVal: Unit = { + """ + object A { + @JSExportTopLevel("foo") + lazy val a: Int = 1 + } + """ hasErrors + """ + |newSource1.scala:4: error: You may not export a lazy val to the top level + | @JSExportTopLevel("foo") + | ^ + """ + } + @Test def noExportTopLevelGetter: Unit = { """ From ce65967592c9c3e411b538432639d609d19c850a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 16 Mar 2017 21:00:39 +0100 Subject: [PATCH 0150/2665] Disallow exports of lazy vals as static. Exporting a lazy val as static probably makes sense, but as SIP-25 on `@static` considers static lazy vals as an open question, it is safer to disallow them for now. This can be reconsidered in the future. --- .../scalajs/core/compiler/PrepJSExports.scala | 7 ++++++- .../core/compiler/test/JSExportTest.scala | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala index 53cb3e66e7..9c4f9f93e6 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala @@ -426,7 +426,12 @@ trait PrepJSExports { this: PrepJSInterop => "Scala.js-defined JS class may export its members as static.") } - if (!isMember) { + if (isMember) { + if (sym.isLazy) { + reporter.error(annot.pos, + "You may not export a lazy val as static") + } + } else { if (sym.isTrait) { reporter.error(annot.pos, "You may not export a trait as static.") diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index 94b2237376..cb272d9457 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -1438,6 +1438,24 @@ class JSExportTest extends DirectTest with TestHelpers { """ } + @Test + def noExportStaticLazyVal: Unit = { + """ + @ScalaJSDefined + class StaticContainer extends js.Object + + object StaticContainer { + @JSExportStatic + lazy val a: Int = 1 + } + """ hasErrors + """ + |newSource1.scala:7: error: You may not export a lazy val as static + | @JSExportStatic + | ^ + """ + } + @Test def noExportValAsStaticAndTopLevel: Unit = { """ From a5eeeb9f222215eacc399611e9d85afe8fbcb29a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 8 Mar 2017 13:07:49 +0100 Subject: [PATCH 0151/2665] Deprecate private members of native JS classes/traits/objects. Historically, our compiler has tolerated `private`, `private[this]` and `private[Scope]` members in native JS classes, traits, and objects. Once compiled, it would consider that they are in fact public, with non-mangled names. This is at odds with how private members of Scala.js-defined JS types are handled at use site, which means there are different semantics at use site between native versus Scala.js-defined types, which is bad. This commit deprecates definitions of private members in native JS types. We still accept `private[this]` constructors, because they are sometimes necessary to have a primary constructor that other constructors delegate to. `private[this]` constructors are fine, because they cannot be called from anywhere but the secondary constructors. Note that even a `private` constructor can be called from the companion object, which can be non-native, so this is not allowed. --- .../core/compiler/Compat210Component.scala | 2 + .../scalajs/core/compiler/PrepJSInterop.scala | 29 +++++++ .../core/compiler/test/JSInteropTest.scala | 83 +++++++++++++++++++ .../scala/scala/scalajs/js/Dictionary.scala | 7 -- .../scala/scalajs/js/WrappedDictionary.scala | 21 ++++- .../scalajs/js/typedarray/Float32Array.scala | 2 +- .../scalajs/js/typedarray/Float64Array.scala | 2 +- .../scalajs/js/typedarray/Int16Array.scala | 2 +- .../scalajs/js/typedarray/Int32Array.scala | 2 +- .../scalajs/js/typedarray/Int8Array.scala | 2 +- .../scalajs/js/typedarray/Uint16Array.scala | 2 +- .../scalajs/js/typedarray/Uint32Array.scala | 2 +- .../scalajs/js/typedarray/Uint8Array.scala | 2 +- .../js/typedarray/Uint8ClampedArray.scala | 3 +- project/BinaryIncompatibilities.scala | 4 + 15 files changed, 147 insertions(+), 18 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala b/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala index 9e5d9d0054..f574e06148 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala @@ -7,6 +7,7 @@ package org.scalajs.core.compiler import scala.collection.mutable +import scala.reflect.internal.Flags.{LOCAL, PRIVATE} import scala.tools.nsc._ /** Hacks to have our source code compatible with 2.10 and 2.11. @@ -26,6 +27,7 @@ trait Compat210Component { def unexpandedName: Name = self.originalName def originalName: Name = sys.error("infinite loop in Compat") + def isPrivateThis: Boolean = self.hasAllFlags(PRIVATE | LOCAL) def isLocalToBlock: Boolean = self.isLocal def implClass: Symbol = NoSymbol diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 1b3454e6e2..65be9f9625 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -962,6 +962,35 @@ abstract class PrepJSInterop extends plugins.PluginComponent "This will become an error in 1.0.0.") } + /* In native JS types, there should not be any private member, except + * private[this] constructors. + */ + if ((enclosingOwner is OwnerKind.JSNative) && isPrivateMaybeWithin(sym)) { + // Necessary for `private[this] val/var + def isFieldPrivateThis: Boolean = { + sym.isPrivateThis && + !sym.isParamAccessor && + !sym.owner.info.decls.exists(s => s.isGetter && s.accessed == sym) + } + + if (sym.isClassConstructor) { + if (!sym.isPrivateThis) { + reporter.warning(tree.pos, + "Declaring private constructors in native JS classes is " + + "deprecated, because they do not behave the same way as in " + + "Scala.js-defined JS classes. Use `private[this]` instead. " + + "This will become an error in 1.0.0.") + } + } else if (sym.isMethod || isFieldPrivateThis) { + reporter.warning(tree.pos, + "Declaring private members in native JS classes is " + + "deprecated, because they do not behave the same way as in " + + "Scala.js-defined JS classes. Use a public member in a " + + "private facade instead. " + + "This will become an error in 1.0.0.") + } + } + if (enclosingOwner is OwnerKind.JSNonNative) { // Private methods cannot be overloaded if (sym.isMethod && isPrivateMaybeWithin(sym)) { diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index 24fd795e06..9cebad4c14 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -1001,6 +1001,89 @@ class JSInteropTest extends DirectTest with TestHelpers { } + @Test + def warnPrivateMemberInNative: Unit = { + + """ + @js.native + @JSGlobal + class A extends js.Object { + private[this] val a: Int = js.native + private val b: Int = js.native + private[A] val c: Int = js.native + + private[this] var d: Int = js.native + private var e: Int = js.native + private[A] var f: Int = js.native + + private[this] def g(): Int = js.native + private def h(): Int = js.native + private[A] def i(): Int = js.native + } + """ hasWarns + """ + |newSource1.scala:8: warning: Declaring private members in native JS classes is deprecated, because they do not behave the same way as in Scala.js-defined JS classes. Use a public member in a private facade instead. This will become an error in 1.0.0. + | private[this] val a: Int = js.native + | ^ + |newSource1.scala:9: warning: Declaring private members in native JS classes is deprecated, because they do not behave the same way as in Scala.js-defined JS classes. Use a public member in a private facade instead. This will become an error in 1.0.0. + | private val b: Int = js.native + | ^ + |newSource1.scala:10: warning: Declaring private members in native JS classes is deprecated, because they do not behave the same way as in Scala.js-defined JS classes. Use a public member in a private facade instead. This will become an error in 1.0.0. + | private[A] val c: Int = js.native + | ^ + |newSource1.scala:12: warning: Declaring private members in native JS classes is deprecated, because they do not behave the same way as in Scala.js-defined JS classes. Use a public member in a private facade instead. This will become an error in 1.0.0. + | private[this] var d: Int = js.native + | ^ + |newSource1.scala:13: warning: Declaring private members in native JS classes is deprecated, because they do not behave the same way as in Scala.js-defined JS classes. Use a public member in a private facade instead. This will become an error in 1.0.0. + | private var e: Int = js.native + | ^ + |newSource1.scala:14: warning: Declaring private members in native JS classes is deprecated, because they do not behave the same way as in Scala.js-defined JS classes. Use a public member in a private facade instead. This will become an error in 1.0.0. + | private[A] var f: Int = js.native + | ^ + |newSource1.scala:16: warning: Declaring private members in native JS classes is deprecated, because they do not behave the same way as in Scala.js-defined JS classes. Use a public member in a private facade instead. This will become an error in 1.0.0. + | private[this] def g(): Int = js.native + | ^ + |newSource1.scala:17: warning: Declaring private members in native JS classes is deprecated, because they do not behave the same way as in Scala.js-defined JS classes. Use a public member in a private facade instead. This will become an error in 1.0.0. + | private def h(): Int = js.native + | ^ + |newSource1.scala:18: warning: Declaring private members in native JS classes is deprecated, because they do not behave the same way as in Scala.js-defined JS classes. Use a public member in a private facade instead. This will become an error in 1.0.0. + | private[A] def i(): Int = js.native + | ^ + """ + + } + + @Test + def warnPrivateConstructorInNative: Unit = { + + """ + @js.native + @JSGlobal + class A private () extends js.Object + """ containsWarns + """ + |newSource1.scala:7: warning: Declaring private constructors in native JS classes is deprecated, because they do not behave the same way as in Scala.js-defined JS classes. Use `private[this]` instead. This will become an error in 1.0.0. + | class A private () extends js.Object + """ + + """ + @js.native + @JSGlobal + class A private[A] () extends js.Object + """ containsWarns + """ + |newSource1.scala:7: warning: Declaring private constructors in native JS classes is deprecated, because they do not behave the same way as in Scala.js-defined JS classes. Use `private[this]` instead. This will become an error in 1.0.0. + | class A private[A] () extends js.Object + """ + + """ + @js.native + @JSGlobal + class A private[this] () extends js.Object + """.hasNoWarns + + } + @Test def noUseJsNative: Unit = { diff --git a/library/src/main/scala/scala/scalajs/js/Dictionary.scala b/library/src/main/scala/scala/scalajs/js/Dictionary.scala index 128c4c3dee..dff2feaee3 100644 --- a/library/src/main/scala/scala/scalajs/js/Dictionary.scala +++ b/library/src/main/scala/scala/scalajs/js/Dictionary.scala @@ -50,13 +50,6 @@ import annotation.JSBracketAccess */ @native sealed trait Dictionary[A] extends Any { - /** Reads a field of this object by its name. - * - * This must not be called if the dictionary does not contain the key. - */ - @JSBracketAccess - private[js] def rawApply(key: String): A = native - /** Writes a field of this object by its name. */ @JSBracketAccess def update(key: String, value: A): Unit = native diff --git a/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala b/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala index 90bce3e8eb..f425fd0495 100644 --- a/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala +++ b/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala @@ -8,6 +8,9 @@ package scala.scalajs.js +import scala.scalajs.js +import scala.scalajs.js.annotation._ + import scala.collection.mutable import mutable.Builder @@ -24,18 +27,22 @@ class WrappedDictionary[A](val dict: Dictionary[A]) def get(key: String): Option[A] = { if (contains(key)) - Some(dict.rawApply(key)) + Some(rawApply(key)) else None } override def apply(key: String): A = { if (contains(key)) - dict.rawApply(key) + rawApply(key) else throw new NoSuchElementException("key not found: " + key) } + @inline + private def rawApply(key: String): A = + dict.asInstanceOf[DictionaryRawApply[A]].rawApply(key) + override def contains(key: String): Boolean = { /* We have to use a safe version of hasOwnProperty, because * "hasOwnProperty" could be a key of this dictionary. @@ -83,6 +90,16 @@ object WrappedDictionary { private def safeHasOwnProperty(dict: Dictionary[_], key: String): Boolean = Cache.safeHasOwnProperty(dict, key) + @js.native + private trait DictionaryRawApply[A] extends js.Object { + /** Reads a field of this object by its name. + * + * This must not be called if the dictionary does not contain the key. + */ + @JSBracketAccess + def rawApply(key: String): A = native + } + private final class DictionaryIterator[+A]( dict: Dictionary[A]) extends scala.collection.Iterator[(String, A)] { private[this] val keys = Object.keys(dict.asInstanceOf[Object]) diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Float32Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Float32Array.scala index 069af01e2e..4be02de554 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Float32Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Float32Array.scala @@ -8,7 +8,7 @@ import scala.scalajs.js.annotation._ */ @js.native @JSGlobal -class Float32Array private extends TypedArray[Float, Float32Array] { +class Float32Array private[this] () extends TypedArray[Float, Float32Array] { /** Constructs a Float32Array with the given length. Initialized to all 0 */ def this(length: Int) = this() diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Float64Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Float64Array.scala index f47d56e250..b84559a9ac 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Float64Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Float64Array.scala @@ -8,7 +8,7 @@ import scala.scalajs.js.annotation._ */ @js.native @JSGlobal -class Float64Array private extends TypedArray[Double, Float64Array] { +class Float64Array private[this] () extends TypedArray[Double, Float64Array] { /** Constructs a Float64Array with the given length. Initialized to all 0 */ def this(length: Int) = this() diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Int16Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Int16Array.scala index 4384dd0d41..70e924d73b 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Int16Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Int16Array.scala @@ -8,7 +8,7 @@ import scala.scalajs.js.annotation._ */ @js.native @JSGlobal -class Int16Array private extends TypedArray[Short, Int16Array] { +class Int16Array private[this] () extends TypedArray[Short, Int16Array] { /** Constructs a Int16Array with the given length. Initialized to all 0 */ def this(length: Int) = this() diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Int32Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Int32Array.scala index d311d97e5b..4174c231ca 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Int32Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Int32Array.scala @@ -8,7 +8,7 @@ import scala.scalajs.js.annotation._ */ @js.native @JSGlobal -class Int32Array private extends TypedArray[Int, Int32Array] { +class Int32Array private[this] () extends TypedArray[Int, Int32Array] { /** Constructs a Int32Array with the given length. Initialized to all 0 */ def this(length: Int) = this() diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Int8Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Int8Array.scala index 12cc0419ff..9d238e9814 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Int8Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Int8Array.scala @@ -8,7 +8,7 @@ import scala.scalajs.js.annotation._ */ @js.native @JSGlobal -class Int8Array private extends TypedArray[Byte, Int8Array] { +class Int8Array private[this] () extends TypedArray[Byte, Int8Array] { /** Constructs a Int8Array with the given length. Initialized to all 0 */ def this(length: Int) = this() diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Uint16Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Uint16Array.scala index 29335c8dca..7a0635eb5c 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Uint16Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Uint16Array.scala @@ -8,7 +8,7 @@ import scala.scalajs.js.annotation._ */ @js.native @JSGlobal -class Uint16Array private extends TypedArray[Int, Uint16Array] { +class Uint16Array private[this] () extends TypedArray[Int, Uint16Array] { /** Constructs a Uint16Array with the given length. Initialized to all 0 */ def this(length: Int) = this() diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Uint32Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Uint32Array.scala index ba0dc415dc..20f60a36ff 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Uint32Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Uint32Array.scala @@ -8,7 +8,7 @@ import scala.scalajs.js.annotation._ */ @js.native @JSGlobal -class Uint32Array private extends TypedArray[Double, Uint32Array] { +class Uint32Array private[this] () extends TypedArray[Double, Uint32Array] { /** Constructs a Uint32Array with the given length. Initialized to all 0 */ def this(length: Int) = this() diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Uint8Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Uint8Array.scala index 6d664d8bce..4965aa72ef 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Uint8Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Uint8Array.scala @@ -8,7 +8,7 @@ import scala.scalajs.js.annotation._ */ @js.native @JSGlobal -class Uint8Array private extends TypedArray[Short, Uint8Array] { +class Uint8Array private[this] () extends TypedArray[Short, Uint8Array] { /** Constructs a Uint8Array with the given length. Initialized to all 0 */ def this(length: Int) = this() diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Uint8ClampedArray.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Uint8ClampedArray.scala index bcee4c4691..63e30aeee7 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Uint8ClampedArray.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Uint8ClampedArray.scala @@ -9,7 +9,8 @@ import scala.scalajs.js.annotation._ */ @js.native @JSGlobal -class Uint8ClampedArray private extends TypedArray[Int, Uint8ClampedArray] { +class Uint8ClampedArray private[this] () + extends TypedArray[Int, Uint8ClampedArray] { /** Constructs a Uint8ClampedArray with the given length. Initialized to all 0 */ def this(length: Int) = this() diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 7088822170..a4df1df02c 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -199,6 +199,10 @@ object BinaryIncompatibilities { ProblemFilters.exclude[IncompatibleMethTypeProblem]( "scala.scalajs.js.typedarray.Uint32Array.this"), + // private[js], not an issue + ProblemFilters.exclude[DirectMissingMethodProblem]( + "scala.scalajs.js.Dictionary.rawApply"), + // New member in non-sealed trait (for low prio implicits). // Theoretically breaking. ProblemFilters.exclude[InheritedNewAbstractMethodProblem]( From 083e3d51652e6bf056e6c7e97eccaf9b34ff819c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 16 Feb 2017 11:51:47 +0100 Subject: [PATCH 0152/2665] Deprecate the internals of LinkingUnit. There were a bunch of things in LinkingUnit that should not be used outside of the linker itself. --- .../core/tools/linker/LinkingUnit.scala | 57 ++++++++++++++++--- .../backend/emitter/KnowledgeGuardian.scala | 17 ++++-- .../core/tools/linker/checker/IRChecker.scala | 2 +- .../tools/linker/frontend/BaseLinker.scala | 2 +- .../core/tools/linker/frontend/Refiner.scala | 4 +- .../frontend/optimizer/GenIncOptimizer.scala | 2 +- 6 files changed, 66 insertions(+), 18 deletions(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala index 8e92397a6b..afe7750028 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala @@ -6,17 +6,46 @@ import org.scalajs.core.tools.javascript.ESLevel import org.scalajs.core.ir import ir.{Definitions, Infos} -final class LinkingUnit( +final class LinkingUnit private[linker] ( val semantics: Semantics, val esLevel: ESLevel, val classDefs: List[LinkedClass], - val infos: Map[String, Infos.ClassInfo], - val isComplete: Boolean + private[linker] val infosInternal: Map[String, Infos.ClassInfo], + val isComplete: Boolean, + dummyInternal: Unit ) { import LinkingUnit._ - lazy val globalInfo: GlobalInfo = { + /** Creates a `LinkingUnit` without any entry point. */ + @deprecated( + "The LinkingUnit constructor was not intended to be exposed to user " + + "code. It will be removed in 1.0.0.", + "0.6.15") + def this(semantics: Semantics, esLevel: ESLevel, classDefs: List[LinkedClass], + infos: Map[String, Infos.ClassInfo], isComplete: Boolean) = { + this(semantics, esLevel, classDefs, infos, isComplete, dummyInternal = ()) + } + + @deprecated( + "LinkingUnit.infos was not intended to be exposed to user code. " + + "It will be removed in 1.0.0. " + + "Use linkingUnit.classDefs.map(_.toInfo) instead.", + "0.6.15") + val infos: Map[String, Infos.ClassInfo] = infosInternal + + /* This used to be a `lazy val`, but that causes scalac to complain about + * uses of GlobalInfo inside globalInfo. The issue also appears with a `val` + * but not with a `def`. + * A `def` is binary compatible with a `lazy val`, although not source + * compatible (a `lazy val` is *stable*, so can be imported from). + */ + @deprecated( + "LinkingUnit.globalInfo was not intended to be exposed to user code. " + + "It will be removed in 1.0.0. " + + "Inspect the relevant data in linkingUnit.classDefs instead.", + "0.6.15") + def globalInfo: GlobalInfo = { classDefs.find(_.encodedName == Definitions.ClassClass).fold { GlobalInfo( isParentDataAccessed = false) @@ -27,14 +56,27 @@ final class LinkingUnit( } } - def updated(classDefs: List[LinkedClass], isComplete: Boolean): LinkingUnit = { - val newInfos = infos ++ classDefs.map(cd => cd.encodedName -> cd.toInfo) - new LinkingUnit(semantics, esLevel, classDefs, newInfos, isComplete) + @deprecated( + "LinkingUnit.updated was not intended to be exposed to user code. " + + "It will be removed in 1.0.0.", + "0.6.15") + def updated(classDefs: List[LinkedClass], isComplete: Boolean): LinkingUnit = + updatedInternal(classDefs, isComplete) + + /** Non-deprecated version of `updated` for internal use. */ + private[linker] def updatedInternal(classDefs: List[LinkedClass], + isComplete: Boolean): LinkingUnit = { + val newInfos = + infosInternal ++ classDefs.map(cd => cd.encodedName -> cd.toInfo) + new LinkingUnit(semantics, esLevel, classDefs, newInfos, isComplete, + dummyInternal = ()) } } +@deprecated("This object only contains deprecated members.", "0.6.15") object LinkingUnit { + @deprecated("See LinkingInfo.globalInfo.", "0.6.15") final class GlobalInfo private ( /** Whether the parent data of class data is accessed. * This is true iff the java.lang.Class.getSuperclass() method exists, @@ -43,6 +85,7 @@ object LinkingUnit { val isParentDataAccessed: Boolean ) + @deprecated("See LinkingInfo.globalInfo.", "0.6.15") object GlobalInfo { private[LinkingUnit] def apply( isParentDataAccessed: Boolean diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala index a3111eada0..34f76a37f2 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala @@ -11,7 +11,7 @@ package org.scalajs.core.tools.linker.backend.emitter import scala.collection.mutable -import org.scalajs.core.ir.ClassKind +import org.scalajs.core.ir.{ClassKind, Definitions} import org.scalajs.core.ir.Trees.{FieldDef, JSNativeLoadSpec} import org.scalajs.core.tools.linker._ @@ -41,7 +41,7 @@ private[emitter] final class KnowledgeGuardian { * the rare events where they do change. */ def update(linkingUnit: LinkingUnit): Boolean = { - val newIsParentDataAccessed = linkingUnit.globalInfo.isParentDataAccessed + var newIsParentDataAccessed = false var newHasNewRuntimeLong: Boolean = false // Update classes @@ -53,10 +53,15 @@ private[emitter] final class KnowledgeGuardian { existingCls.update(linkedClass) } - if (linkedClass.encodedName == LongImpl.RuntimeLongClass) { - newHasNewRuntimeLong = linkedClass.memberMethods.exists { linkedMethod => - linkedMethod.tree.name.encodedName == LongImpl.initFromParts - } + def methodExists(encodedName: String): Boolean = + linkedClass.memberMethods.exists(_.tree.name.encodedName == encodedName) + + linkedClass.encodedName match { + case Definitions.ClassClass => + newIsParentDataAccessed = methodExists("getSuperclass__jl_Class") + case LongImpl.RuntimeLongClass => + newHasNewRuntimeLong = methodExists(LongImpl.initFromParts) + case _ => } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 6c1fd53297..285fdc0e56 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -1094,7 +1094,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { private def lookupInfo(className: String)( implicit ctx: ErrorContext): Infos.ClassInfo = { - unit.infos.getOrElse(className, { + unit.infosInternal.getOrElse(className, { reportError(s"Cannot find info for class $className") Infos.ClassInfo(className) }) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index 6f1c894aff..9344d879e1 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -180,7 +180,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions } yield linkedClassDef new LinkingUnit(semantics, esLevel, linkedClassDefs.toList, infoByName, - analysis.allAvailable) + analysis.allAvailable, dummyInternal = ()) } /** Takes a Infos, a ClassDef and DCE infos to construct a stripped down diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala index 32330e6ead..e4471e357f 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala @@ -24,7 +24,7 @@ final class Refiner { logger: Logger): LinkingUnit = { val analysis = logger.time("Refiner: Compute reachability") { Analyzer.computeReachability(unit.semantics, symbolRequirements, - unit.infos.values.toList, allowAddingSyntheticMethods = false) + unit.infosInternal.values.toList, allowAddingSyntheticMethods = false) } /* There really should not be linking errors at this point. If there are, @@ -57,7 +57,7 @@ final class Refiner { linkedClassDef <- optClassDef(classInfo) } yield linkedClassDef - unit.updated(classDefs = linkedClassDefs.toList, + unit.updatedInternal(classDefs = linkedClassDefs.toList, isComplete = analysis.allAvailable) } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala index f61ed14de7..35f29309e7 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala @@ -135,7 +135,7 @@ abstract class GenIncOptimizer private[optimizer] (semantics: Semantics, memberMethods = defs(memberNamespace)) } - unit.updated(classDefs = newLinkedClasses, isComplete = true) + unit.updatedInternal(classDefs = newLinkedClasses, isComplete = true) } } From 8166c6c782a13ea117c01b9d0761418671b69c9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 21 Feb 2017 12:06:41 +0100 Subject: [PATCH 0153/2665] Do not include java.math tests when using PhantomJS. This reduces the pressure on PhantomJS in terms of mass of code in the test suite. It seems we reached the limits of what PhantomJS can handle in terms of code mass. Since PhantomJS support is due to be moved to a separate repository in 1.0.0, the easiest way to fix this is to reduce the pressure on PhantomJS. We therefore remove the tests of java.math (BigInteger and BigDecimal) when running with PhantomJS. These tests are well isolated, and the less likely to have environmental differences. --- project/Build.scala | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/project/Build.scala b/project/Build.scala index 43ccb2480a..9b9c993d5d 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1501,6 +1501,37 @@ object Build { } sourceFiles1 + }, + + /* Reduce the amount of tests on PhantomJS to avoid a crash. + * It seems we reached the limits of what PhantomJS can handle in terms + * of code mass. Since PhantomJS support is due to be moved to a + * separate repository in 1.0.0, the easiest way to fix this is to + * reduce the pressure on PhantomJS. We therefore remove the tests of + * java.math (BigInteger and BigDecimal) when running with PhantomJS. + * These tests are well isolated, and the less likely to have + * environmental differences. + * + * Note that `jsEnv` is never set from this Build, but it is set via + * the command-line in the CI matrix. + */ + sources in Test := { + def isPhantomJS(env: JSEnv): Boolean = env match { + case _: PhantomJSEnv => true + case env: RetryingComJSEnv => isPhantomJS(env.baseEnv) + case _ => false + } + + val sourceFiles = (sources in Test).value + if ((jsEnv in Test).?.value.exists(isPhantomJS)) { + sourceFiles.filter { f => + !f.getAbsolutePath + .replace('\\', '/') + .contains("/org/scalajs/testsuite/javalib/math/") + } + } else { + sourceFiles + } } ) ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( From 518a9cd346f95a3ef659f6c1cbe5d832f62d0de1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 16 Feb 2017 12:46:29 +0100 Subject: [PATCH 0154/2665] Add user-defined module initializers to the linker. A module initializer is a piece of code that is executed when the module produced for a linked Scala.js application is loaded. This commit adds an sbt task of type `Seq[ModuleInitializer]`, which allows the user to define custom entry points to their module. Example: scalaJSModuleInitializers += { org.scalajs.core.tools.linker.ModuleInitializer.mainMethod( "fully.qualified.ObjectName", "main") } Module initializers can be specified `in Compile`, in which case they are not executed during tests. This fills a gap in our interoperability criterium, as previously there was no way that user-defined code could be executed at module load time (without hacking around it by using an exported static field that is not actually used). This is also intended to provide a basis for a better replacement to launcher files, but such work is not done in this commit. --- .../scala/org/scalajs/cli/Scalajsld.scala | 24 +++++- .../scalajs/jsenv/rhino/ScalaJSCoreLib.scala | 12 ++- .../scala/tools/nsc/MainGenericRunner.scala | 48 ++++++----- project/BinaryIncompatibilities.scala | 79 +++++++++++++++++++ project/Build.scala | 48 ++++++++++- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 6 +- .../sbtplugin/ScalaJSPluginInternal.scala | 15 +++- .../compiler/ModuleInitializersTest.scala | 61 ++++++++++++++ .../core/tools/test/js/QuickLinker.scala | 28 +++++-- .../core/tools/linker/ClearableLinker.scala | 6 +- .../scalajs/core/tools/linker/GenLinker.scala | 16 +++- .../scalajs/core/tools/linker/Linker.scala | 7 +- .../core/tools/linker/LinkingUnit.scala | 11 +-- .../core/tools/linker/ModuleInitializer.scala | 62 +++++++++++++++ .../linker/backend/emitter/ClassEmitter.scala | 14 +++- .../linker/backend/emitter/Emitter.scala | 20 +++++ .../tools/linker/frontend/BaseLinker.scala | 49 +++++++++--- .../linker/frontend/LinkerFrontend.scala | 14 +++- .../core/tools/linker/frontend/Refiner.scala | 6 +- .../core/tools/linker/LinkerTest.scala | 2 +- 20 files changed, 459 insertions(+), 69 deletions(-) create mode 100644 test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ModuleInitializersTest.scala create mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/linker/ModuleInitializer.scala diff --git a/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala b/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala index 9bf0b26855..f1c0374882 100644 --- a/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala +++ b/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala @@ -17,7 +17,7 @@ import org.scalajs.core.tools.logging._ import CheckedBehavior.Compliant -import org.scalajs.core.tools.linker.Linker +import org.scalajs.core.tools.linker.{ModuleInitializer, Linker} import org.scalajs.core.tools.linker.frontend.LinkerFrontend import org.scalajs.core.tools.linker.backend.{LinkerBackend, OutputMode, ModuleKind} @@ -30,6 +30,7 @@ object Scalajsld { private case class Options( cp: Seq[File] = Seq.empty, + moduleInitializers: Seq[ModuleInitializer] = Seq.empty, output: File = null, jsoutput: Boolean = false, semantics: Semantics = Semantics.Defaults, @@ -45,6 +46,17 @@ object Scalajsld { stdLib: Option[File] = None, logLevel: Level = Level.Info) + private implicit object MainMethodRead extends scopt.Read[ModuleInitializer] { + val arity = 1 + val reads = { (s: String) => + val lastDot = s.lastIndexOf('.') + if (lastDot < 0) + throw new IllegalArgumentException(s"$s is not a valid main method") + ModuleInitializer.mainMethod(s.substring(0, lastDot), + s.substring(lastDot + 1)) + } + } + private implicit object OutputModeRead extends scopt.Read[OutputMode] { val arity = 1 val reads = { (s: String) => @@ -68,6 +80,12 @@ object Scalajsld { .unbounded() .action { (x, c) => c.copy(cp = c.cp :+ x) } .text("Entries of Scala.js classpath to link") + opt[ModuleInitializer]("mainMethod") + .valueName("") + .abbr("mm") + .unbounded() + .action { (x, c) => c.copy(moduleInitializers = c.moduleInitializers :+ x) } + .text("Execute the specified main method on startup") opt[File]('o', "output") .valueName("") .required() @@ -148,6 +166,7 @@ object Scalajsld { for (options <- parser.parse(args, Options())) { val classpath = options.stdLib.toList ++ options.cp val irContainers = IRFileCache.IRContainer.fromClasspath(classpath) + val moduleInitializers = options.moduleInitializers // Warn if writing JS dependencies was requested. if (options.jsoutput) { @@ -192,7 +211,8 @@ object Scalajsld { val outFile = WritableFileVirtualJSFile(options.output) val cache = (new IRFileCache).newCache - linker.link(cache.cached(irContainers), outFile, logger) + linker.link(cache.cached(irContainers), moduleInitializers, outFile, + logger) } } } diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala index 0fbae38b61..8da714762c 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala @@ -63,6 +63,10 @@ private[rhino] class ScalaJSCoreLib(linkingUnit: LinkingUnit) { val c = Context.toObject(ScalaJS.get("c", ScalaJS), scope) for (encodedName <- exportedSymbols) c.get(encodedName, c) + + // Execute the module initializers + evaluateJSTree(scope, emitter.rhinoAPI.genModuleInitializers(linkingUnit), + "ScalaJSEntryPoints.js") } /** Source maps the given stack trace (where possible) */ @@ -175,14 +179,16 @@ private[rhino] class ScalaJSCoreLib(linkingUnit: LinkingUnit) { throw new RhinoJSEnv.ClassNotFoundException(encodedName)) val desugared = emitter.rhinoAPI.genClassDef(linkedClass) + evaluateJSTree(scope, desugared, encodedName + PseudoFileSuffix) + } - // Write tree + private def evaluateJSTree(scope: Scriptable, tree: Trees.Tree, + fakeFileName: String): Unit = { val codeWriter = new java.io.StringWriter val printer = new Printers.JSTreePrinter(codeWriter) - printer.printTopLevelTree(desugared) + printer.printTopLevelTree(tree) printer.complete() val ctx = Context.getCurrentContext() - val fakeFileName = encodedName + PseudoFileSuffix ctx.evaluateString(scope, codeWriter.toString(), fakeFileName, 1, null) } diff --git a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala index 0720818122..7c85fa27be 100644 --- a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala +++ b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala @@ -7,7 +7,7 @@ import org.scalajs.core.tools.logging._ import org.scalajs.core.tools.io._ import org.scalajs.core.tools.jsdep.ResolvedJSDependency import org.scalajs.core.tools.io.IRFileCache.IRContainer -import org.scalajs.core.tools.linker.Linker +import org.scalajs.core.tools.linker.{Linker, ModuleInitializer} import org.scalajs.core.tools.linker.backend.{OutputMode, ModuleKind} import org.scalajs.core.ir @@ -66,6 +66,9 @@ class MainGenericRunner { runnerIR(command.thingToRun, command.arguments) ) + val moduleInitializers = + Seq(ModuleInitializer.mainMethod("PartestLauncher", "main")) + val linkerConfig = Linker.Config() .withSourceMap(false) .withClosureCompiler(optMode == FullOpt) @@ -75,14 +78,11 @@ class MainGenericRunner { val sjsCode = { val output = WritableMemVirtualJSFile("partest.js") - linker.link(ir, output, logger) - ResolvedJSDependency.minimal(output) :: Nil + linker.link(ir, moduleInitializers, output, logger) + output } - val jsRunner = new MemVirtualJSFile("launcher.js") - .withContent(s"PartestLauncher().launch();") - - new NodeJSEnv().jsRunner(sjsCode, jsRunner).run(logger, jsConsole) + new NodeJSEnv().jsRunner(sjsCode).run(logger, jsConsole) true } @@ -102,7 +102,6 @@ class MainGenericRunner { val mainModuleClassName = ir.Definitions.encodeClassName(mainObj + "$") val className = "PartestLauncher$" - val exportName = "PartestLauncher" val encodedClassName = ir.Definitions.encodeClassName(className) val definition = { @@ -116,22 +115,31 @@ class MainGenericRunner { List( MethodDef( static = false, - StringLiteral("launch"), + Ident("init___", Some("")), Nil, - AnyType, + NoType, Some( - Block( - Apply(LoadModule(ClassType(mainModuleClassName)), - Ident("main__AT__V"), - List( - ArrayValue(ArrayType("T", 1), args.map(StringLiteral(_))) - ) - )(NoType), - Undefined() - ) + ApplyStatically(This()(ClassType(encodedClassName)), + ClassType(ir.Definitions.ObjectClass), + Ident("init___"), + Nil + )(NoType) ) )(OptimizerHints.empty, None), - ModuleExportDef(exportName) + MethodDef( + static = false, + Ident("main__V", Some("main")), + Nil, + NoType, + Some( + Apply(LoadModule(ClassType(mainModuleClassName)), + Ident("main__AT__V"), + List( + ArrayValue(ArrayType("T", 1), args.map(StringLiteral(_))) + ) + )(NoType) + ) + )(OptimizerHints.empty, None) ) )(OptimizerHints.empty) } diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 7088822170..e7d2814548 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -53,6 +53,12 @@ object BinaryIncompatibilities { ) val Tools = Seq( + // Breaking: add 2 methods to the GenLinker trait + ProblemFilters.exclude[ReversedMissingMethodProblem]( + "org.scalajs.core.tools.linker.GenLinker.link"), + ProblemFilters.exclude[ReversedMissingMethodProblem]( + "org.scalajs.core.tools.linker.GenLinker.linkUnit"), + // Breaking. Remove PropertyName.name ProblemFilters.exclude[DirectMissingMethodProblem]( "org.scalajs.core.tools.javascript.Trees#PropertyName.name"), @@ -73,6 +79,10 @@ object BinaryIncompatibilities { ProblemFilters.exclude[DirectMissingMethodProblem]( "org.scalajs.core.tools.linker.analyzer.Analyzer.org$scalajs$core$tools$linker$analyzer$Analyzer$$createMissingMethodInfo$default$3"), + // private[frontend], not an issue + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.frontend.BaseLinker.linkInternal"), + // private[closure], not an issue ProblemFilters.exclude[IncompatibleMethTypeProblem]( "org.scalajs.core.tools.linker.backend.closure.ClosureAstTransformer.transformString"), @@ -140,6 +150,75 @@ object BinaryIncompatibilities { ) val CLI = Seq( + // private, not an issue + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.cli.Scalajsld#Options.this"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.$default$2"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.$default$3"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.$default$4"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.$default$5"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.$default$6"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.$default$7"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.$default$11"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.$default$12"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.$default$14"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.$default$15"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.cli.Scalajsld#Options.copy"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.copy$default$2"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.copy$default$3"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.copy$default$4"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.copy$default$5"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.copy$default$6"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.copy$default$7"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.copy$default$11"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.copy$default$12"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.copy$default$14"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.copy$default$15"), + ProblemFilters.exclude[MissingTypesProblem]( + "org.scalajs.cli.Scalajsld$Options$"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.cli.Scalajsld#Options.apply"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.apply$default$2"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.apply$default$3"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.apply$default$4"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.apply$default$5"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.apply$default$6"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.apply$default$7"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.apply$default$11"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.apply$default$12"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.apply$default$14"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.cli.Scalajsld#Options.apply$default$15") ) val Library = Seq( diff --git a/project/Build.scala b/project/Build.scala index 9b9c993d5d..94fbde4829 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -32,6 +32,7 @@ import org.scalajs.core.tools.io.MemVirtualJSFile import org.scalajs.core.tools.sem._ import org.scalajs.core.tools.jsdep.ResolvedJSDependency import org.scalajs.core.tools.json._ +import org.scalajs.core.tools.linker.ModuleInitializer import org.scalajs.core.tools.linker.backend.OutputMode import sbtassembly.AssemblyPlugin.autoImport._ @@ -624,9 +625,26 @@ object Build { val (jars, dirs) = cp.filter(_.exists).partition(_.isFile) val irFiles = dirs.flatMap(dir => (dir ** "*.sjsir").get) - val irPaths = { - for (f <- jars ++ irFiles) - yield s""""${escapeJS(f.getAbsolutePath)}"""" + def seqOfStringsToJSArrayCode(strings: Seq[String]): String = + strings.map(s => "\"" + escapeJS(s) + "\"").mkString("[", ", ", "]") + + val irPaths = { + val absolutePaths = (jars ++ irFiles).map(_.getAbsolutePath) + seqOfStringsToJSArrayCode(absolutePaths) + } + + val mainMethods = { + /* Ideally we would read `scalaJSModuleInitializers in (testSuite, Test)`, + * but we cannot convert the ModuleInitializers to strings to be + * passed to the QuickLinker (because ModuleInitializer is a + * write-only data structure). So we have some duplication. + */ + val unescapedMainMethods = List( + "org.scalajs.testsuite.compiler.ModuleInitializerInNoConfiguration.main", + "org.scalajs.testsuite.compiler.ModuleInitializerInTestConfiguration.main2", + "org.scalajs.testsuite.compiler.ModuleInitializerInTestConfiguration.main1" + ) + seqOfStringsToJSArrayCode(unescapedMainMethods) } val scalaJSEnv = { @@ -640,7 +658,7 @@ object Build { val code = { s""" var linker = scalajs.QuickLinker; - var lib = linker.linkTestSuiteNode(${irPaths.mkString(", ")}); + var lib = linker.linkTestSuiteNode($irPaths, $mainMethods); var __ScalaJSEnv = $scalaJSEnv; @@ -1532,6 +1550,28 @@ object Build { } else { sourceFiles } + }, + + // Module initializers. Duplicated in toolsJS/test + scalaJSModuleInitializers += { + ModuleInitializer.mainMethod( + "org.scalajs.testsuite.compiler.ModuleInitializerInNoConfiguration", + "main") + }, + scalaJSModuleInitializers in Compile += { + ModuleInitializer.mainMethod( + "org.scalajs.testsuite.compiler.ModuleInitializerInCompileConfiguration", + "main") + }, + scalaJSModuleInitializers in Test += { + ModuleInitializer.mainMethod( + "org.scalajs.testsuite.compiler.ModuleInitializerInTestConfiguration", + "main2") + }, + scalaJSModuleInitializers in Test += { + ModuleInitializer.mainMethod( + "org.scalajs.testsuite.compiler.ModuleInitializerInTestConfiguration", + "main1") } ) ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index a12d5f09ff..0402656ac8 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -13,7 +13,7 @@ import sbt._ import org.scalajs.core.tools.sem.Semantics import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.linker.LinkingUnit +import org.scalajs.core.tools.linker.{ModuleInitializer, LinkingUnit} import org.scalajs.core.tools.linker.backend.{ModuleKind, OutputMode} import org.scalajs.core.tools.jsdep.{JSDependencyManifest, ResolvedJSDependency} import org.scalajs.core.tools.jsdep.ManifestFilters.ManifestFilter @@ -196,6 +196,10 @@ object ScalaJSPlugin extends AutoPlugin { val scalaJSIR = TaskKey[Attributed[Seq[VirtualScalaJSIRFile with RelativeVirtualFile]]]( "scalaJSIR", "All the *.sjsir files on the classpath", CTask) + val scalaJSModuleInitializers = TaskKey[Seq[ModuleInitializer]]("scalaJSModuleInitializers", + "Module initializers of the Scala.js application, to be called when it starts.", + AMinusTask) + val scalaJSNativeLibraries = TaskKey[Attributed[Seq[VirtualJSFile with RelativeVirtualFile]]]( "scalaJSNativeLibraries", "All the *.js files on the classpath", CTask) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index ff08a7a412..9caa0d995e 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -232,6 +232,7 @@ object ScalaJSPluginInternal { val irInfo = (scalaJSIR in key).value val realFiles = irInfo.get(scalaJSSourceFiles).get val ir = irInfo.data + val moduleInitializers = scalaJSModuleInitializers.value val output = (artifactPath in key).value Def.task { @@ -248,7 +249,9 @@ object ScalaJSPluginInternal { IO.createDirectory(output.getParentFile) val linker = (scalaJSLinker in key).value - linker.link(ir, AtomicWritableFileVirtualJSFile(output), sbtLogger2ToolsLogger(log)) + linker.link(ir, moduleInitializers, + AtomicWritableFileVirtualJSFile(output), + sbtLogger2ToolsLogger(log)) logIRCacheStats(log) @@ -644,8 +647,9 @@ object ScalaJSPluginInternal { Def.task { val linker = scalaJSLinker.value val ir = scalaJSIR.value.data - val unit = linker.linkUnit(ir, env.symbolRequirements, - sbtLogger2ToolsLogger(log)) + 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) @@ -940,6 +944,11 @@ object ScalaJSPluginInternal { scalaJSModuleKind := ModuleKind.NoModule, checkScalaJSSemantics := true, + scalaJSModuleInitializers := Seq(), + scalaJSModuleInitializers in Compile := scalaJSModuleInitializers.value, + // Do not inherit scalaJSModuleInitializers in Test from Compile + scalaJSModuleInitializers in Test := scalaJSModuleInitializers.value, + scalaJSConsole := ConsoleJSConsole, clean := { diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ModuleInitializersTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ModuleInitializersTest.scala new file mode 100644 index 0000000000..1ef295c39e --- /dev/null +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ModuleInitializersTest.scala @@ -0,0 +1,61 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.compiler + +import org.junit.Test +import org.junit.Assert._ + +class ModuleInitializersTest { + import ModuleInitializersTest._ + + @Test def correctInitializers(): Unit = { + assertArrayEquals( + Array[AnyRef](NoConfigMain, TestConfigMain2, TestConfigMain1), + moduleInitializersEffects.toArray[AnyRef]) + } + +} + +object ModuleInitializersTest { + final val NoConfigMain = "ModuleInitializerInNoConfiguration.main" + final val CompileConfigMain = "ModuleInitializerInCompileConfiguration.main" + final val TestConfigMain1 = "ModuleInitializerInTestConfiguration.main1" + final val TestConfigMain2 = "ModuleInitializerInTestConfiguration.main2" + + val moduleInitializersEffects = + new scala.collection.mutable.ListBuffer[String] +} + +object ModuleInitializerInNoConfiguration { + import ModuleInitializersTest._ + + def main(): Unit = { + moduleInitializersEffects += NoConfigMain + } +} + +object ModuleInitializerInCompileConfiguration { + import ModuleInitializersTest._ + + def main(): Unit = { + // This is not going to be actually run + moduleInitializersEffects += CompileConfigMain + } +} + +object ModuleInitializerInTestConfiguration { + import ModuleInitializersTest._ + + def main1(): Unit = { + moduleInitializersEffects += TestConfigMain1 + } + + def main2(): Unit = { + moduleInitializersEffects += TestConfigMain2 + } +} diff --git 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 index 1f0391ec76..5e3449b39a 100644 --- 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,12 +1,13 @@ package org.scalajs.core.tools.test.js import org.scalajs.core.tools.sem.Semantics -import org.scalajs.core.tools.linker.backend.{OutputMode, ModuleKind} import org.scalajs.core.tools.io._ import org.scalajs.core.tools.io.IRFileCache.IRContainer +import org.scalajs.core.tools.linker.{ModuleInitializer, Linker} +import org.scalajs.core.tools.linker.backend.{OutputMode, ModuleKind} import org.scalajs.core.tools.logging._ -import org.scalajs.core.tools.linker.Linker +import scala.scalajs.js import scala.scalajs.js.annotation._ @JSExportTopLevel("scalajs.QuickLinker") @@ -14,24 +15,27 @@ object QuickLinker { /** Link a Scala.js application on Node.js */ @JSExport - def linkNode(irFilesAndJars: String*): String = - linkNodeInternal(Semantics.Defaults, irFilesAndJars) + def linkNode(irFilesAndJars: js.Array[String], + mainMethods: js.Array[String]): String = { + linkNodeInternal(Semantics.Defaults, irFilesAndJars, mainMethods) + } /** Link the Scala.js test suite on Node.js */ @JSExport - def linkTestSuiteNode(irFilesAndJars: String*): String = { + def linkTestSuiteNode(irFilesAndJars: js.Array[String], + mainMethods: js.Array[String]): String = { val semantics = Semantics.Defaults.withRuntimeClassName(_.fullName match { case "org.scalajs.testsuite.compiler.ReflectionTest$RenamedTestClass" => "renamed.test.Class" case fullName => fullName }) - linkNodeInternal(semantics, irFilesAndJars) + linkNodeInternal(semantics, irFilesAndJars, mainMethods) } /** Link a Scala.js application on Node.js */ def linkNodeInternal(semantics: Semantics, - irFilesAndJars: Seq[String]): String = { + irFilesAndJars: Seq[String], mainMethods: Seq[String]): String = { val cache = (new IRFileCache).newCache val linker = Linker(semantics, OutputMode.ECMAScript51Isolated, @@ -54,8 +58,16 @@ object QuickLinker { val ir = cache.cached(irContainers) + val moduleInitializers = mainMethods.map { mainMethod => + val lastDot = mainMethod.lastIndexOf('.') + if (lastDot < 0) + throw new IllegalArgumentException(s"$mainMethod is not a valid main method") + ModuleInitializer.mainMethod(mainMethod.substring(0, lastDot), + mainMethod.substring(lastDot + 1)) + } + val out = WritableMemVirtualJSFile("out.js") - linker.link(ir, out, new ScalaConsoleLogger) + linker.link(ir, moduleInitializers, out, new ScalaConsoleLogger) out.content } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ClearableLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ClearableLinker.scala index 13a638fb21..9fb20ce618 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ClearableLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ClearableLinker.scala @@ -42,13 +42,15 @@ final class ClearableLinker(newLinker: () => GenLinker, batchMode: Boolean) } def linkUnit(irFiles: Seq[VirtualScalaJSIRFile], + moduleInitializers: Seq[ModuleInitializer], symbolRequirements: SymbolRequirement, logger: Logger): LinkingUnit = { - linkerOp(_.linkUnit(irFiles, symbolRequirements, logger)) + linkerOp(_.linkUnit(irFiles, moduleInitializers, symbolRequirements, logger)) } def link(irFiles: Seq[VirtualScalaJSIRFile], + moduleInitializers: Seq[ModuleInitializer], output: WritableVirtualJSFile, logger: Logger): Unit = { - linkerOp(_.link(irFiles, output, logger)) + linkerOp(_.link(irFiles, moduleInitializers, output, logger)) } def clear(): Unit = diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala index 1a46e562bf..f9c0aa651c 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala @@ -18,15 +18,29 @@ import org.scalajs.core.tools.linker.analyzer.SymbolRequirement /** Common supertrait of [[Linker]] and [[ClearableLinker]]. * - * Essentially anything that has the [[link]] and [[linkUnit]] methods. + * Essentially anything that has the `link` and `linkUnit` methods. */ trait GenLinker { def semantics: Semantics def esLevel: ESLevel + @deprecated("Use the overload with explicit module initializers.", "0.6.15") def linkUnit(irFiles: Seq[VirtualScalaJSIRFile], + symbolRequirements: SymbolRequirement, logger: Logger): LinkingUnit = { + linkUnit(irFiles, Nil, symbolRequirements, logger) + } + + def linkUnit(irFiles: Seq[VirtualScalaJSIRFile], + moduleInitializers: Seq[ModuleInitializer], symbolRequirements: SymbolRequirement, logger: Logger): LinkingUnit + @deprecated("Use the overload with explicit module initializers.", "0.6.15") + def link(irFiles: Seq[VirtualScalaJSIRFile], + output: WritableVirtualJSFile, logger: Logger): Unit = { + link(irFiles, Nil, output, logger) + } + def link(irFiles: Seq[VirtualScalaJSIRFile], + moduleInitializers: Seq[ModuleInitializer], output: WritableVirtualJSFile, logger: Logger): Unit } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala index be5fb27648..b4d8f33873 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala @@ -41,13 +41,16 @@ final class Linker(frontend: LinkerFrontend, backend: LinkerBackend) private[this] val _linking = new AtomicBoolean(false) def linkUnit(irFiles: Seq[VirtualScalaJSIRFile], + moduleInitializers: Seq[ModuleInitializer], symbolRequirements: SymbolRequirement, logger: Logger): LinkingUnit = - guard(frontend.link(irFiles, symbolRequirements, logger)) + guard(frontend.link(irFiles, moduleInitializers, symbolRequirements, logger)) def link(irFiles: Seq[VirtualScalaJSIRFile], + moduleInitializers: Seq[ModuleInitializer], output: WritableVirtualJSFile, logger: Logger): Unit = { guard { - val unit = frontend.link(irFiles, backend.symbolRequirements, logger) + val unit = frontend.link(irFiles, moduleInitializers, + backend.symbolRequirements, logger) backend.emit(unit, output, logger) } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala index afe7750028..6b8150b197 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala @@ -11,8 +11,8 @@ final class LinkingUnit private[linker] ( val esLevel: ESLevel, val classDefs: List[LinkedClass], private[linker] val infosInternal: Map[String, Infos.ClassInfo], - val isComplete: Boolean, - dummyInternal: Unit + val moduleInitializers: List[ModuleInitializer], + val isComplete: Boolean ) { import LinkingUnit._ @@ -24,7 +24,8 @@ final class LinkingUnit private[linker] ( "0.6.15") def this(semantics: Semantics, esLevel: ESLevel, classDefs: List[LinkedClass], infos: Map[String, Infos.ClassInfo], isComplete: Boolean) = { - this(semantics, esLevel, classDefs, infos, isComplete, dummyInternal = ()) + this(semantics, esLevel, classDefs, infos, moduleInitializers = Nil, + isComplete) } @deprecated( @@ -68,8 +69,8 @@ final class LinkingUnit private[linker] ( isComplete: Boolean): LinkingUnit = { val newInfos = infosInternal ++ classDefs.map(cd => cd.encodedName -> cd.toInfo) - new LinkingUnit(semantics, esLevel, classDefs, newInfos, isComplete, - dummyInternal = ()) + new LinkingUnit(semantics, esLevel, classDefs, newInfos, moduleInitializers, + isComplete) } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ModuleInitializer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ModuleInitializer.scala new file mode 100644 index 0000000000..cdefb0f912 --- /dev/null +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ModuleInitializer.scala @@ -0,0 +1,62 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.core.tools.linker + +import org.scalajs.core.ir.Definitions._ +import org.scalajs.core.ir.Types.ClassType + +import org.scalajs.core.tools.linker.analyzer.SymbolRequirement + +/** A module initializer for a Scala.js application. + * + * When linking a Scala.js application, a sequence of `ModuleInitializer`s can + * be given. Those module initializers will be executed at the startup of the + * application. More specifically, the top-level code of the ECMAScript 2015 + * module emitted for the application will invoke the specified module + * initializers in the specified order, after having initialized everything + * else (notably static initializers). + * + * Instances of `ModuleInitializer` can be created with methods of + * [[ModuleInitializer$ the ModuleInitializer companion object]]. + */ +sealed abstract class ModuleInitializer + +/** Factory for [[ModuleInitializer]]s. */ +object ModuleInitializer { + private[linker] final case class VoidMainMethod(moduleClassName: String, + encodedMainMethodName: String) + extends ModuleInitializer + + /** Makes an [[ModuleInitializer]] that calls a zero-argument method returning + * `Unit` in a top-level `object`. + * + * @param moduleClassName + * The fully-qualified name of the module class, e.g., `"foo.bar.Babar"`. + * Note that it does not end with `$`. + * @param mainMethodName + * The name of the main method to invoke, e.g., `"main"`. + */ + def mainMethod(moduleClassName: String, + mainMethodName: String): ModuleInitializer = { + VoidMainMethod(encodeClassName(moduleClassName + "$"), + mainMethodName + "__V") + } + + def toSymbolRequirement( + entryPoints: Seq[ModuleInitializer]): SymbolRequirement = { + val factory = SymbolRequirement.factory("module initializers") + val requirements = for (entryPoint <- entryPoints) yield { + entryPoint match { + case VoidMainMethod(moduleClassName, mainMethodName) => + factory.callOnModule(moduleClassName, mainMethodName) + } + } + factory.multiple(requirements: _*) + } +} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index b4f4bb42da..47c870d258 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -19,8 +19,8 @@ import org.scalajs.core.tools.sem._ import CheckedBehavior.Unchecked import org.scalajs.core.tools.javascript.{Trees => js} +import org.scalajs.core.tools.linker._ import org.scalajs.core.tools.linker.backend.OutputMode -import org.scalajs.core.tools.linker.{LinkedClass, LinkingUnit} /** Emitter for the skeleton of classes. */ private[emitter] final class ClassEmitter(jsGen: JSGen) { @@ -1165,6 +1165,18 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { (js.Block(statements.result()), namespace, js.StringLiteral(parts.last)) } + /** Gen JS code for an [[ModuleInitializer]]. */ + def genModuleInitializer(moduleInitializer: ModuleInitializer): js.Tree = { + import TreeDSL._ + + implicit val pos = Position.NoPosition + + moduleInitializer match { + case ModuleInitializer.VoidMainMethod(moduleClassName, mainMethodName) => + js.Apply(genLoadModule(moduleClassName) DOT mainMethodName, Nil) + } + } + } private object ClassEmitter { diff --git 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 index b800dd46cf..ac6c4286a5 100644 --- 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 @@ -132,6 +132,11 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, for (linkedClass <- orderedClasses) emitLinkedClassClassExports(linkedClass, builder) + + // Emit the module initializers + + for (moduleInitializer <- unit.moduleInitializers) + emitModuleInitializer(moduleInitializer, builder) } finally { endRun(logger) } @@ -333,6 +338,15 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, } } + /** Emits an [[EntryPoint]]. + * + * This is done at the very end of the emitted module/script. + */ + private def emitModuleInitializer(moduleInitializer: ModuleInitializer, + builder: JSTreeBuilder): Unit = { + builder.addJSTree(classEmitter.genModuleInitializer(moduleInitializer)) + } + // Helpers private def getClassTreeCache(linkedClass: LinkedClass): DesugaredClassCache = @@ -373,6 +387,12 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, def genClassDef(linkedClass: LinkedClass): js.Tree = classEmitter.genClassDefForRhino(linkedClass)(globalKnowledge) + + def genModuleInitializers(linkingUnit: LinkingUnit): js.Tree = { + val genModuleInitializers = + linkingUnit.moduleInitializers.map(classEmitter.genModuleInitializer(_)) + js.Block(genModuleInitializers)(Position.NoPosition) + } } // Caching diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index 9344d879e1..62949e3d68 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -37,13 +37,21 @@ import Analysis._ /** Links the information from [[io.VirtualScalaJSIRFile]]s into * [[LinkedClass]]es. Does a dead code elimination pass. */ -final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions: Boolean) { +final class BaseLinker(semantics: Semantics, esLevel: ESLevel, + considerPositions: Boolean) { private type TreeProvider = String => (ClassDef, Option[String]) + @deprecated("Use the overload with explicit module initializers.", "0.6.15") def link(irInput: Seq[VirtualScalaJSIRFile], logger: Logger, symbolRequirements: SymbolRequirement, checkIR: Boolean): LinkingUnit = { - linkInternal(irInput, logger, symbolRequirements, + link(irInput, Nil, logger, symbolRequirements, checkIR) + } + + def link(irInput: Seq[VirtualScalaJSIRFile], + moduleInitializers: Seq[ModuleInitializer], logger: Logger, + symbolRequirements: SymbolRequirement, checkIR: Boolean): LinkingUnit = { + linkInternal(irInput, moduleInitializers, logger, symbolRequirements, bypassLinkingErrors = false, checkIR = checkIR) } @@ -54,12 +62,25 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions def link(irInput: Seq[VirtualScalaJSIRFile], logger: Logger, symbolRequirements: SymbolRequirement, bypassLinkingErrors: Boolean, checkIR: Boolean): LinkingUnit = { - linkInternal(irInput, logger, symbolRequirements, + linkInternal(irInput, Nil, logger, symbolRequirements, + bypassLinkingErrors, checkIR) + } + + @deprecated( + "Bypassing linking errors will not be possible in the next major version. " + + "Use the overload without the bypassLinkingError parameter instead.", + "0.6.6") + def link(irInput: Seq[VirtualScalaJSIRFile], + moduleInitializers: Seq[ModuleInitializer], logger: Logger, + symbolRequirements: SymbolRequirement, bypassLinkingErrors: Boolean, + checkIR: Boolean): LinkingUnit = { + linkInternal(irInput, moduleInitializers, logger, symbolRequirements, bypassLinkingErrors, checkIR) } // Non-deprecated version to be called from `LinkerFrontend` - private[frontend] def linkInternal(irInput: Seq[VirtualScalaJSIRFile], logger: Logger, + private[frontend] def linkInternal(irInput: Seq[VirtualScalaJSIRFile], + moduleInitializers: Seq[ModuleInitializer], logger: Logger, symbolRequirements: SymbolRequirement, bypassLinkingErrors: Boolean, checkIR: Boolean): LinkingUnit = { @@ -83,13 +104,13 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions (pf.tree, pf.version) } - linkInternal(infos, getTree, logger, symbolRequirements, + linkInternal(infos, getTree, moduleInitializers, logger, symbolRequirements, bypassLinkingErrors, checkIR) } private def linkInternal(infoInput: List[Infos.ClassInfo], - getTree: TreeProvider, logger: Logger, - symbolRequirements: SymbolRequirement, + getTree: TreeProvider, moduleInitializers: Seq[ModuleInitializer], + logger: Logger, symbolRequirements: SymbolRequirement, bypassLinkingErrors: Boolean, checkIR: Boolean): LinkingUnit = { if (checkIR) { @@ -103,7 +124,11 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions } val analysis = logger.time("Linker: Compute reachability") { - Analyzer.computeReachability(semantics, symbolRequirements, infoInput, + val allSymbolRequirements = { + symbolRequirements ++ + ModuleInitializer.toSymbolRequirement(moduleInitializers) + } + Analyzer.computeReachability(semantics, allSymbolRequirements, infoInput, allowAddingSyntheticMethods = true) } @@ -134,7 +159,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions } val linkResult = logger.time("Linker: Assemble LinkedClasses") { - assemble(infoInput, getTree, analysis) + assemble(infoInput, getTree, moduleInitializers, analysis) } // Make sure we don't export to the same name twice. @@ -155,8 +180,8 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions linkResult } - private def assemble(infoInput: List[Infos.ClassInfo], - getTree: TreeProvider, analysis: Analysis) = { + private def assemble(infoInput: List[Infos.ClassInfo], getTree: TreeProvider, + moduleInitializers: Seq[ModuleInitializer], analysis: Analysis) = { val infoByName = Map(infoInput.map(c => c.encodedName -> c): _*) def optClassDef(analyzerInfo: Analysis.ClassInfo) = { @@ -180,7 +205,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, considerPositions } yield linkedClassDef new LinkingUnit(semantics, esLevel, linkedClassDefs.toList, infoByName, - analysis.allAvailable, dummyInternal = ()) + moduleInitializers.toList, analysis.allAvailable) } /** Takes a Infos, a ClassDef and DCE infos to construct a stripped down diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala index d5c58b039c..013201462a 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala @@ -15,7 +15,7 @@ import org.scalajs.core.tools.io.VirtualScalaJSIRFile import org.scalajs.core.tools.sem.Semantics import org.scalajs.core.tools.javascript.ESLevel -import org.scalajs.core.tools.linker.LinkingUnit +import org.scalajs.core.tools.linker._ import org.scalajs.core.tools.linker.analyzer.SymbolRequirement import org.scalajs.core.tools.linker.frontend.optimizer.{GenIncOptimizer, IncOptimizer} @@ -43,16 +43,24 @@ final class LinkerFrontend( private[this] val refiner: Refiner = new Refiner /** Link and optionally optimize the given IR to a [[LinkingUnit]]. */ + @deprecated("Use the overload with explicit module initializers.", "0.6.15") def link(irFiles: Seq[VirtualScalaJSIRFile], symbolRequirements: SymbolRequirement, logger: Logger): LinkingUnit = { + link(irFiles, Nil, symbolRequirements, logger) + } + + /** Link and optionally optimize the given IR to a [[LinkingUnit]]. */ + def link(irFiles: Seq[VirtualScalaJSIRFile], + moduleInitializers: Seq[ModuleInitializer], + symbolRequirements: SymbolRequirement, logger: Logger): LinkingUnit = { val preOptimizerRequirements = optOptimizer.fold(symbolRequirements) { optimizer => symbolRequirements ++ optimizer.symbolRequirements } val linkResult = logger.time("Basic Linking") { - linker.linkInternal(irFiles, logger, preOptimizerRequirements, - config.bypassLinkingErrors, config.checkIR) + linker.linkInternal(irFiles, moduleInitializers, logger, + preOptimizerRequirements, config.bypassLinkingErrors, config.checkIR) } optOptimizer.fold(linkResult) { optimizer => diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala index e4471e357f..28a5e3cdf1 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala @@ -23,7 +23,11 @@ final class Refiner { def refine(unit: LinkingUnit, symbolRequirements: SymbolRequirement, logger: Logger): LinkingUnit = { val analysis = logger.time("Refiner: Compute reachability") { - Analyzer.computeReachability(unit.semantics, symbolRequirements, + val allSymbolRequirements = { + symbolRequirements ++ + ModuleInitializer.toSymbolRequirement(unit.moduleInitializers) + } + Analyzer.computeReachability(unit.semantics, allSymbolRequirements, unit.infosInternal.values.toList, allowAddingSyntheticMethods = false) } diff --git a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala index 571bc9ffd1..8d9575d62a 100644 --- a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala +++ b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala @@ -26,7 +26,7 @@ class LinkerTest { ModuleKind.NoModule, Linker.Config()) def callLink(): Unit = - linker.link(badSeq, WritableMemVirtualJSFile("some_file"), NullLogger) + linker.link(badSeq, Nil, WritableMemVirtualJSFile("some_file"), NullLogger) // Call first time. Get exception from badSeq. try { From aff7dcf2440da9f9134f6d85060cfba2fe322553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 17 Feb 2017 22:20:31 +0100 Subject: [PATCH 0155/2665] Add scalaJSUseMainModuleInitializer, to use an initializer for the mainClass. When the setting `scalaJSUseMainModuleInitializer` is set to true, a module initializer will be derived from `mainClass` (which is itself derived from discovered `js.JSApp`s in the program). This causes a call to the main method of a main class to be built in the fastOptJS/fullOptJS output. Consequently, `run` is adapted to know about `scalaJSUseMainModuleInitializer`, so that it doesn't execute the main method twice. The setting is mutually exclusive with `persistLauncher`, as it does not make sense to write a launcher file when the main .js file already executes the main method. In fact, `scalaJSUseMainModuleInitializer` is intended to supersede launcher files and `persistLauncher`. This also fixes #2199. --- ci/matrix.xml | 15 ++++- .../helloworld/helloworld-2.10-fastopt.html | 2 - examples/helloworld/helloworld-2.10.html | 2 - .../helloworld/helloworld-2.11-fastopt.html | 2 - examples/helloworld/helloworld-2.11.html | 2 - project/Build.scala | 2 +- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 10 ++++ .../sbtplugin/ScalaJSPluginInternal.scala | 59 +++++++++++++++++-- 8 files changed, 79 insertions(+), 15 deletions(-) diff --git a/ci/matrix.xml b/ci/matrix.xml index 4c978aa227..728e18b5b4 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -39,7 +39,20 @@ ++$scala helloworld/run && sbtretry 'set inScope(ThisScope in helloworld)(jsEnv := new org.scalajs.jsenv.RetryingComJSEnv(PhantomJSEnv().value))' \ 'set scalaJSStage in Global := FullOptStage' \ - ++$scala helloworld/run && + ++$scala helloworld/run \ + helloworld/clean && + sbtretry ++$scala \ + 'set scalaJSModuleKind in helloworld := ModuleKind.CommonJSModule' \ + helloworld/run \ + helloworld/clean && + sbtretry ++$scala \ + 'set Seq(scalaJSUseMainModuleInitializer in helloworld := false, persistLauncher in helloworld := true)' \ + 'set scalaJSUseRhino in Global := true' \ + helloworld/run && + sbtretry ++$scala \ + 'set Seq(scalaJSUseMainModuleInitializer in helloworld := false, persistLauncher in helloworld := true)' \ + helloworld/run \ + helloworld/clean && sbtretry 'set scalaJSUseRhino in Global := true' \ ++$scala testingExample/test:run testingExample/test && sbtretry ++$scala testingExample/test:run testingExample/test && diff --git a/examples/helloworld/helloworld-2.10-fastopt.html b/examples/helloworld/helloworld-2.10-fastopt.html index 98b2705643..b8b413f796 100644 --- a/examples/helloworld/helloworld-2.10-fastopt.html +++ b/examples/helloworld/helloworld-2.10-fastopt.html @@ -13,7 +13,5 @@ - - diff --git a/examples/helloworld/helloworld-2.10.html b/examples/helloworld/helloworld-2.10.html index 80b00b9e42..ae117a00f6 100644 --- a/examples/helloworld/helloworld-2.10.html +++ b/examples/helloworld/helloworld-2.10.html @@ -13,7 +13,5 @@ - - diff --git a/examples/helloworld/helloworld-2.11-fastopt.html b/examples/helloworld/helloworld-2.11-fastopt.html index dbf5598f00..7b30469669 100644 --- a/examples/helloworld/helloworld-2.11-fastopt.html +++ b/examples/helloworld/helloworld-2.11-fastopt.html @@ -13,7 +13,5 @@ - - diff --git a/examples/helloworld/helloworld-2.11.html b/examples/helloworld/helloworld-2.11.html index 9c9a3a18dd..eb9d7cfd40 100644 --- a/examples/helloworld/helloworld-2.11.html +++ b/examples/helloworld/helloworld-2.11.html @@ -13,7 +13,5 @@ - - diff --git a/project/Build.scala b/project/Build.scala index 94fbde4829..b2cbba0bf3 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1225,7 +1225,7 @@ object Build { settings = exampleSettings ++ Seq( name := "Hello World - Scala.js example", moduleName := "helloworld", - persistLauncher := true + scalaJSUseMainModuleInitializer := true ) ).withScalaJSCompiler.dependsOn(library) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 0402656ac8..b8307a80a7 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -200,6 +200,16 @@ object ScalaJSPlugin extends AutoPlugin { "Module initializers of the Scala.js application, to be called when it starts.", AMinusTask) + val scalaJSUseMainModuleInitializer = SettingKey[Boolean]("scalaJSUseMainModuleInitializer", + "If true, adds the `mainClass` as a module initializer of the Scala.js module", + APlusSetting) + + val scalaJSMainModuleInitializer = TaskKey[Option[ModuleInitializer]]( + "scalaJSMainModuleInitializer", + "The main module initializer, used if " + + "`scalaJSUseMainModuleInitializer` is true", + CTask) + val scalaJSNativeLibraries = TaskKey[Attributed[Seq[VirtualJSFile with RelativeVirtualFile]]]( "scalaJSNativeLibraries", "All the *.js files on the classpath", CTask) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 9caa0d995e..602156a406 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -16,7 +16,7 @@ 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.linker.{ClearableLinker, Linker} +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} @@ -424,10 +424,18 @@ object ScalaJSPluginInternal { skip in packageScalaJSLauncher := { val value = !persistLauncher.value - if (!value && (scalaJSModuleKind.value != ModuleKind.NoModule)) { - throw new MessageOnlyException( - "persistLauncher := true is not compatible with emitting " + - "JavaScript modules") + if (!value) { + if (scalaJSUseMainModuleInitializer.value) { + throw new MessageOnlyException( + "persistLauncher := true is not compatible with using a main " + + "module initializer (scalaJSUseMainModuleInitializer := " + + "true), nor is it necessary, since fastOptJS/fullOptJS " + + "includes the call to the main method") + } else if (scalaJSModuleKind.value != ModuleKind.NoModule) { + throw new MessageOnlyException( + "persistLauncher := true is not compatible with emitting " + + "JavaScript modules") + } } value }, @@ -742,12 +750,42 @@ object ScalaJSPluginInternal { // These settings will be filtered by the stage dummy tasks val scalaJSRunSettings = Seq( + scalaJSMainModuleInitializer := { + mainClass.value.map(ModuleInitializer.mainMethod(_, "main")) + }, + + scalaJSModuleInitializers ++= { + if (scalaJSUseMainModuleInitializer.value) { + Seq(scalaJSMainModuleInitializer.value.getOrElse { + throw new MessageOnlyException( + "No main module initializer was specified (possibly because " + + "no or multiple main classes were found), but " + + "scalaJSUseMainModuleInitializer was set to true. " + + "You can explicitly specify it either with " + + "`mainClass := Some(...)` or with " + + "`scalaJSMainModuleInitializer := Some(...)`") + }) + } else { + Seq.empty + } + }, + mainClass in scalaJSLauncher := (mainClass in run).value, scalaJSLauncher := Def.taskDyn[Attributed[VirtualJSFile]] { if (persistLauncher.value) { Def.task { packageScalaJSLauncher.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 scalaJSLauncher).value.fold { @@ -782,6 +820,14 @@ object ScalaJSPluginInternal { assert(scalaJSEnsureUnforked.value) val mainClass = runMainParser.parsed + + if (scalaJSUseMainModuleInitializer.value) { + throw new MessageOnlyException( + "`runMain` is not supported when using a main module " + + "initializer (scalaJSUseMainModuleInitializer := true) since " + + "the (unique) entry point is burned in the fastOptJS/fullOptJS.") + } + val moduleKind = scalaJSModuleKind.value val moduleIdentifier = scalaJSModuleIdentifier.value jsRun(loadedJSEnv.value, mainClass, @@ -949,6 +995,9 @@ object ScalaJSPluginInternal { // Do not inherit scalaJSModuleInitializers in Test from Compile scalaJSModuleInitializers in Test := scalaJSModuleInitializers.value, + scalaJSUseMainModuleInitializer := false, + scalaJSUseMainModuleInitializer in Test := false, + scalaJSConsole := ConsoleJSConsole, clean := { From e46949ee6c0000db9083527797aa7a361025a8f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 17 Feb 2017 23:54:12 +0100 Subject: [PATCH 0156/2665] Deprecate `persistLauncher` and `packageScalaJSLauncher`. The functionality offered by `persistLauncher` and `packageScalaJSLauncher` has been superseded by `scalaJSUseMainModuleInitializer`. This commit deprecates settings and tasks related to the generation of a launcher file, and recommends to use `scalaJSUseMainModuleInitializer` instead. --- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 38 +++++++++++++++++-- .../sbtplugin/ScalaJSPluginInternal.scala | 38 +++++++++---------- 2 files changed, 53 insertions(+), 23 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index b8307a80a7..ec05e6fa38 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -216,8 +216,19 @@ object ScalaJSPlugin extends AutoPlugin { val scalaJSStage = SettingKey[Stage]("scalaJSStage", "The optimization stage at which run and test are executed", APlusSetting) - val packageScalaJSLauncher = TaskKey[Attributed[File]]("packageScalaJSLauncher", - "Writes the persistent launcher file. Fails if the mainClass is ambigous", CTask) + /** Non-deprecated alias of `packageScalaJSLauncher` for internal use. */ + private[sbtplugin] val packageScalaJSLauncherInternal = TaskKey[Attributed[File]]( + "packageScalaJSLauncher", + "Writes the persistent launcher file. Fails if the mainClass is ambigous", + CTask) + + @deprecated( + "The functionality of `packageScalaJSLauncher` has been superseded " + + "by `scalaJSUseMainModuleInitializer`. Set the latter to `true` to " + + "include what was previously the launcher directly inside the main " + + ".js file generated by fastOptJS/fullOptJS.", + "0.6.15") + val packageScalaJSLauncher = packageScalaJSLauncherInternal val packageJSDependencies = TaskKey[File]("packageJSDependencies", "Packages all dependencies of the preLink classpath in a single file.", AMinusTask) @@ -236,9 +247,19 @@ object ScalaJSPlugin extends AutoPlugin { "Linked Scala.js file. This is the result of fastOptJS or fullOptJS, " + "depending on the stage.", DTask) - val scalaJSLauncher = TaskKey[Attributed[VirtualJSFile]]("scalaJSLauncher", + /** Non-deprecated alias of `scalaJSUseRhino` for internal use. */ + private[sbtplugin] val scalaJSLauncherInternal = TaskKey[Attributed[VirtualJSFile]]( + "scalaJSLauncher", "Code used to run. (Attributed with used class name)", DTask) + @deprecated( + "The functionality of `scalaJSLauncher` has been superseded by " + + "`scalaJSUseMainModuleInitializer`. Set the latter to `true` to " + + "include what was previously the launcher directly inside the main " + + ".js file generated by fastOptJS/fullOptJS.", + "0.6.15") + val scalaJSLauncher = scalaJSLauncherInternal + val scalaJSConsole = TaskKey[JSConsole]("scalaJSConsole", "The JS console used by the Scala.js runner/tester", DTask) @@ -305,10 +326,19 @@ object ScalaJSPlugin extends AutoPlugin { "Whether to check that the current semantics meet compliance " + "requirements of dependencies.", CSetting) - val persistLauncher = SettingKey[Boolean]("persistLauncher", + /** Non-deprecated alias of `persistLauncher` for internal use. */ + private[sbtplugin] val persistLauncherInternal = SettingKey[Boolean]("persistLauncher", "Tell optimize/package tasks to write the laucher file to disk. " + "If this is set, your project may only have a single mainClass or you must explicitly set it", AMinusSetting) + @deprecated( + "The functionality of `persistLauncher` has been superseded by " + + "`scalaJSUseMainModuleInitializer`. Set the latter to `true` to " + + "include what was previously the launcher directly inside the main " + + ".js file generated by fastOptJS/fullOptJS.", + "0.6.15") + val persistLauncher = persistLauncherInternal + val scalaJSOptimizerOptions = SettingKey[OptimizerOptions]("scalaJSOptimizerOptions", "All kinds of options for the Scala.js optimizer stages", DSetting) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 602156a406..47251f62b5 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -263,7 +263,7 @@ object ScalaJSPluginInternal { } tag((usesScalaJSLinkerTag in key).value) }.value, - key := key.dependsOn(packageJSDependencies, packageScalaJSLauncher).value, + key := key.dependsOn(packageJSDependencies, packageScalaJSLauncherInternal).value, scalaJSLinkedFile in key := new FileVirtualJSFile(key.value.data) ) @@ -418,12 +418,12 @@ object ScalaJSPluginInternal { fullOptJS := fullOptJS.dependsOn(packageMinifiedJSDependencies).value, - artifactPath in packageScalaJSLauncher := - ((crossTarget in packageScalaJSLauncher).value / - ((moduleName in packageScalaJSLauncher).value + "-launcher.js")), + artifactPath in packageScalaJSLauncherInternal := + ((crossTarget in packageScalaJSLauncherInternal).value / + ((moduleName in packageScalaJSLauncherInternal).value + "-launcher.js")), - skip in packageScalaJSLauncher := { - val value = !persistLauncher.value + skip in packageScalaJSLauncherInternal := { + val value = !persistLauncherInternal.value if (!value) { if (scalaJSUseMainModuleInitializer.value) { throw new MessageOnlyException( @@ -440,15 +440,15 @@ object ScalaJSPluginInternal { value }, - packageScalaJSLauncher := Def.taskDyn { - if ((skip in packageScalaJSLauncher).value) { + packageScalaJSLauncherInternal := Def.taskDyn { + if ((skip in packageScalaJSLauncherInternal).value) { Def.task { - Attributed.blank((artifactPath in packageScalaJSLauncher).value) + Attributed.blank((artifactPath in packageScalaJSLauncherInternal).value) } } else { Def.task { mainClass.value map { mainCl => - val file = (artifactPath in packageScalaJSLauncher).value + val file = (artifactPath in packageScalaJSLauncherInternal).value assert(scalaJSModuleKind.value == ModuleKind.NoModule, "Cannot produce a launcher file when scalaJSModuleKind " + "is different from NoModule") @@ -770,11 +770,11 @@ object ScalaJSPluginInternal { } }, - mainClass in scalaJSLauncher := (mainClass in run).value, - scalaJSLauncher := Def.taskDyn[Attributed[VirtualJSFile]] { - if (persistLauncher.value) { + mainClass in scalaJSLauncherInternal := (mainClass in run).value, + scalaJSLauncherInternal := Def.taskDyn[Attributed[VirtualJSFile]] { + if (persistLauncherInternal.value) { Def.task { - packageScalaJSLauncher.value.map(FileVirtualJSFile) + packageScalaJSLauncherInternal.value.map(FileVirtualJSFile) } } else if (scalaJSUseMainModuleInitializer.value) { Def.task { @@ -788,7 +788,7 @@ object ScalaJSPluginInternal { } } else { Def.task { - (mainClass in scalaJSLauncher).value.fold { + (mainClass in scalaJSLauncherInternal).value.fold { sys.error("No main class detected.") } { mainClass => val moduleKind = scalaJSModuleKind.value @@ -809,7 +809,7 @@ object ScalaJSPluginInternal { // use assert to prevent warning about pure expr in stat pos assert(scalaJSEnsureUnforked.value) - val launch = scalaJSLauncher.value + val launch = scalaJSLauncherInternal.value val className = launch.get(name.key).getOrElse("") jsRun(loadedJSEnv.value, className, launch.data, streams.value.log, scalaJSConsole.value) @@ -880,7 +880,7 @@ object ScalaJSPluginInternal { val scalaJSTestBuildSettings = ( scalaJSConfigSettings ) ++ ( - Seq(fastOptJS, fullOptJS, packageScalaJSLauncher, + Seq(fastOptJS, fullOptJS, packageScalaJSLauncherInternal, packageJSDependencies) map { packageJSTask => moduleName in packageJSTask := moduleName.value + "-test" } @@ -972,8 +972,8 @@ object ScalaJSPluginInternal { isScalaJSProject := true, relativeSourceMaps := false, - persistLauncher := false, - persistLauncher in Test := false, + persistLauncherInternal := false, + persistLauncherInternal in Test := false, emitSourceMaps := true, From c8681b6b117f27947ced3802087817e0fafa9bee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 18 Feb 2017 00:32:42 +0100 Subject: [PATCH 0157/2665] Deprecate scalaJSOutputWrapper. `scalaJSOutputWrapper` was used in a variety of ways to work around limitations of Scala.js. All the use cases found in the wild now have better replacements: * Acquire the `require` function from the lexical scope and store it in `global`: emit CommonJS modules instead. * Set the `exportsNamespace` to `module.exports`: also emit CommonJS modules. * Execute a main method at startup of the .js file: use module initializers instead, in particular `scalaJSUseMainModuleInitializer`. * Export a top-level function or similar: use `@JSExportTopLevel` instead. Therefore, this commit deprecates `scalaJSOutputWrapper` and the corresponding option in `LinkerBackend.Config`. --- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 15 +++++++++++++-- .../scalajs/sbtplugin/ScalaJSPluginInternal.scala | 4 ++-- .../core/tools/linker/backend/LinkerBackend.scala | 11 +++++++++++ 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index ec05e6fa38..5e1826504d 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -298,8 +298,19 @@ object ScalaJSPlugin extends AutoPlugin { val emitSourceMaps = SettingKey[Boolean]("emitSourceMaps", "Whether package and optimize stages should emit source maps at all", BPlusSetting) - val scalaJSOutputWrapper = SettingKey[(String, String)]("scalaJSOutputWrapper", - "Custom wrapper for the generated .js files. Formatted as tuple (header, footer).", BPlusSetting) + /** Non-deprecated alias of `scalaJSOutputWrapper` for internal use. */ + private[sbtplugin] val scalaJSOutputWrapperInternal = SettingKey[(String, String)]( + "scalaJSOutputWrapper", + "Custom wrapper for the generated .js files. Formatted as tuple (header, footer).", + BPlusSetting) + + @deprecated( + "The functionality of `scalaJSOutputWrapper` has been superseded by " + + "a combination of more direct and more reliable features. Depending " + + "on your use case, use `scalaJSUseMainModuleInitializer`, " + + "`scalaJSModuleKind` and/or `@JSExportTopLevel` instead.", + "0.6.15") + val scalaJSOutputWrapper = scalaJSOutputWrapperInternal val jsDependencies = SettingKey[Seq[AbstractJSDep]]("jsDependencies", "JavaScript libraries this project depends upon. Also used to depend on the DOM.", APlusSetting) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 47251f62b5..7719b601b0 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -192,7 +192,7 @@ object ScalaJSPluginInternal { val backendConfig = LinkerBackend.Config() .withRelativizeSourceMapBase(relSourceMapBase) - .withCustomOutputWrapper(scalaJSOutputWrapper.value) + .withCustomOutputWrapperInternal(scalaJSOutputWrapperInternal.value) .withPrettyPrint(opts.prettyPrintFullOptJS) val config = Linker.Config() @@ -977,7 +977,7 @@ object ScalaJSPluginInternal { emitSourceMaps := true, - scalaJSOutputWrapper := ("", ""), + scalaJSOutputWrapperInternal := ("", ""), scalaJSOptimizerOptions := OptimizerOptions(), diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala index b407b61b67..53c984d31c 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala @@ -77,9 +77,20 @@ object LinkerBackend { def withRelativizeSourceMapBase(relativizeSourceMapBase: Option[URI]): Config = copy(relativizeSourceMapBase = relativizeSourceMapBase) + @deprecated( + "The functionality of custom output wrappers has been superseded " + + "by the support for CommonJS modules, module initializers, and " + + "top-level exports.", + "0.6.15") def withCustomOutputWrapper(customOutputWrapper: (String, String)): Config = copy(customOutputWrapper = customOutputWrapper) + // Non-deprecated version to call from the sbt plugin + private[scalajs] def withCustomOutputWrapperInternal( + customOutputWrapper: (String, String)): Config = { + copy(customOutputWrapper = customOutputWrapper) + } + def withPrettyPrint(prettyPrint: Boolean): Config = copy(prettyPrint = prettyPrint) From 43a7728c8211bc231ca7b8afe9aadd020c786c38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 19 Mar 2017 10:52:20 +0100 Subject: [PATCH 0158/2665] Fix #2816: Disable `noExportStaticLazyVal` on Scala 2.12.0. Because it is affected by SI-10075, which we have no control over and cannot workaround. --- .../scala/org/scalajs/core/compiler/test/JSExportTest.scala | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index cb272d9457..43bc326ef7 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -3,6 +3,8 @@ package org.scalajs.core.compiler.test import org.scalajs.core.compiler.test.util._ import org.junit.Test +import org.junit.Assume._ + // scalastyle:off line.size.limit class JSExportTest extends DirectTest with TestHelpers { @@ -1440,6 +1442,9 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticLazyVal: Unit = { + // Affected by Scala bug SI-10075 + assumeTrue(scala.util.Properties.versionNumberString != "2.12.0") + """ @ScalaJSDefined class StaticContainer extends js.Object From f41dfb3826d6efdf640de901c681859f8cae433c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 19 Mar 2017 10:53:36 +0100 Subject: [PATCH 0159/2665] Bug-list run/Predef.readLine.scala (filed as #2815). It is broken by GCC now that we use a module initializer instead of an export for the `PartestLauncher`. --- .../scala/tools/partest/scalajs/2.11.0/BuglistedTests.txt | 3 +++ .../scala/tools/partest/scalajs/2.11.0/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.11.1/BuglistedTests.txt | 3 +++ .../scala/tools/partest/scalajs/2.11.1/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.11.2/BuglistedTests.txt | 3 +++ .../scala/tools/partest/scalajs/2.11.2/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.11.5/BuglistedTests.txt | 3 +++ .../scala/tools/partest/scalajs/2.11.5/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.11.6/BuglistedTests.txt | 3 +++ .../scala/tools/partest/scalajs/2.11.6/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.11.7/BuglistedTests.txt | 3 +++ .../scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.11.8/BuglistedTests.txt | 3 +++ .../scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.12.0/BuglistedTests.txt | 3 +++ .../scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.12.1/BuglistedTests.txt | 3 +++ .../scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt | 1 - 18 files changed, 27 insertions(+), 9 deletions(-) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/BuglistedTests.txt index 42c6146a09..273cb2c2d4 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/BuglistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/BuglistedTests.txt @@ -2,3 +2,6 @@ # use scala.tools.partest.scalajs.testunknownonly to only run tests # which are neither in BuglistedTests.txt, WhitelistedTests.txt or # BlacklistedTests.txt + +# Broken by GCC, filed as #2815 +run/Predef.readLine.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/WhitelistedTests.txt index bdfb7c6c1e..576bf96b5f 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/WhitelistedTests.txt @@ -2879,7 +2879,6 @@ run/mapConserve.scala run/colltest.scala run/t0412.scala run/t6261.scala -run/Predef.readLine.scala run/java-erasure.scala run/t5880.scala run/t6197.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/BuglistedTests.txt index 42c6146a09..273cb2c2d4 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/BuglistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/BuglistedTests.txt @@ -2,3 +2,6 @@ # use scala.tools.partest.scalajs.testunknownonly to only run tests # which are neither in BuglistedTests.txt, WhitelistedTests.txt or # BlacklistedTests.txt + +# Broken by GCC, filed as #2815 +run/Predef.readLine.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/WhitelistedTests.txt index bb2ed7acce..fd45587491 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/WhitelistedTests.txt @@ -2897,7 +2897,6 @@ run/mapConserve.scala run/colltest.scala run/t0412.scala run/t6261.scala -run/Predef.readLine.scala run/java-erasure.scala run/t5880.scala run/t6197.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/BuglistedTests.txt index 42c6146a09..273cb2c2d4 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/BuglistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/BuglistedTests.txt @@ -2,3 +2,6 @@ # use scala.tools.partest.scalajs.testunknownonly to only run tests # which are neither in BuglistedTests.txt, WhitelistedTests.txt or # BlacklistedTests.txt + +# Broken by GCC, filed as #2815 +run/Predef.readLine.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/WhitelistedTests.txt index 3bb2dfc1c0..a2fdef5743 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/WhitelistedTests.txt @@ -2925,7 +2925,6 @@ run/mapConserve.scala run/colltest.scala run/t0412.scala run/t6261.scala -run/Predef.readLine.scala run/java-erasure.scala run/t5880.scala run/t6197.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/BuglistedTests.txt index 42c6146a09..273cb2c2d4 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/BuglistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/BuglistedTests.txt @@ -2,3 +2,6 @@ # use scala.tools.partest.scalajs.testunknownonly to only run tests # which are neither in BuglistedTests.txt, WhitelistedTests.txt or # BlacklistedTests.txt + +# Broken by GCC, filed as #2815 +run/Predef.readLine.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/WhitelistedTests.txt index 61c64e3deb..08a68a3d82 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/WhitelistedTests.txt @@ -3011,7 +3011,6 @@ run/mapConserve.scala run/colltest.scala run/t0412.scala run/t6261.scala -run/Predef.readLine.scala run/java-erasure.scala run/t5880.scala run/t6197.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/BuglistedTests.txt index 42c6146a09..273cb2c2d4 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/BuglistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/BuglistedTests.txt @@ -2,3 +2,6 @@ # use scala.tools.partest.scalajs.testunknownonly to only run tests # which are neither in BuglistedTests.txt, WhitelistedTests.txt or # BlacklistedTests.txt + +# Broken by GCC, filed as #2815 +run/Predef.readLine.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/WhitelistedTests.txt index 62cca972fa..62cac931f3 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/WhitelistedTests.txt @@ -3023,7 +3023,6 @@ run/mapConserve.scala run/colltest.scala run/t0412.scala run/t6261.scala -run/Predef.readLine.scala run/java-erasure.scala run/t5880.scala run/t6197.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BuglistedTests.txt index 42c6146a09..273cb2c2d4 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BuglistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BuglistedTests.txt @@ -2,3 +2,6 @@ # use scala.tools.partest.scalajs.testunknownonly to only run tests # which are neither in BuglistedTests.txt, WhitelistedTests.txt or # BlacklistedTests.txt + +# Broken by GCC, filed as #2815 +run/Predef.readLine.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt index b737210a0c..19e4217fc8 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt @@ -3050,7 +3050,6 @@ run/mapConserve.scala run/colltest.scala run/t0412.scala run/t6261.scala -run/Predef.readLine.scala run/java-erasure.scala run/t5880.scala run/t6197.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BuglistedTests.txt index 42c6146a09..273cb2c2d4 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BuglistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BuglistedTests.txt @@ -2,3 +2,6 @@ # use scala.tools.partest.scalajs.testunknownonly to only run tests # which are neither in BuglistedTests.txt, WhitelistedTests.txt or # BlacklistedTests.txt + +# Broken by GCC, filed as #2815 +run/Predef.readLine.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt index 4d2946257f..fa420a587b 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt @@ -3048,7 +3048,6 @@ run/mapConserve.scala run/colltest.scala run/t0412.scala run/t6261.scala -run/Predef.readLine.scala run/java-erasure.scala run/t5880.scala run/t6197.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BuglistedTests.txt index 42c6146a09..273cb2c2d4 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BuglistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BuglistedTests.txt @@ -2,3 +2,6 @@ # use scala.tools.partest.scalajs.testunknownonly to only run tests # which are neither in BuglistedTests.txt, WhitelistedTests.txt or # BlacklistedTests.txt + +# Broken by GCC, filed as #2815 +run/Predef.readLine.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt index 9a02f81e9a..0503e9c2c7 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt @@ -3070,7 +3070,6 @@ run/mapConserve.scala run/colltest.scala run/t0412.scala run/t6261.scala -run/Predef.readLine.scala run/java-erasure.scala run/t5880.scala run/t6197.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BuglistedTests.txt index 42c6146a09..273cb2c2d4 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BuglistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BuglistedTests.txt @@ -2,3 +2,6 @@ # use scala.tools.partest.scalajs.testunknownonly to only run tests # which are neither in BuglistedTests.txt, WhitelistedTests.txt or # BlacklistedTests.txt + +# Broken by GCC, filed as #2815 +run/Predef.readLine.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt index c2153da8ba..78ea8bd2e4 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt @@ -3068,7 +3068,6 @@ run/mapConserve.scala run/colltest.scala run/t0412.scala run/t6261.scala -run/Predef.readLine.scala run/java-erasure.scala run/t5880.scala run/t6197.scala From 649a518c696ff8bb044f1be70ffc8e1d286c2432 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 19 Mar 2017 16:50:46 +0100 Subject: [PATCH 0160/2665] Version 0.6.15. --- ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index b94a38cfa3..fed669d303 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.15-SNAPSHOT" + val current: String = "0.6.15" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" @@ -21,12 +21,12 @@ object ScalaJSVersions { * - a prior release version (i.e. "0.5.0", *not* "0.5.0-SNAPSHOT") * - `current` */ - val binaryEmitted: String = current + val binaryEmitted: String = "0.6.15" /** Versions whose binary files we can support (used by deserializer) */ val binarySupported: Set[String] = { Set("0.6.0", "0.6.3", "0.6.4", "0.6.5", "0.6.6", "0.6.8", "0.6.13", - "0.6.14", binaryEmitted) + "0.6.14", "0.6.15", binaryEmitted) } // Just to be extra safe From c97afcc137fb484da45bd588c3a9b1635554f324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 20 Mar 2017 13:08:00 +0100 Subject: [PATCH 0161/2665] Towards 0.6.16. --- .../org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- project/BinaryIncompatibilities.scala | 268 ------------------ project/Build.scala | 12 +- 3 files changed, 2 insertions(+), 280 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index fed669d303..012d1ead12 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.15" + val current: String = "0.6.16-SNAPSHOT" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index b90577ffae..c77318b933 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -3,135 +3,9 @@ import com.typesafe.tools.mima.core.ProblemFilters._ object BinaryIncompatibilities { val IR = Seq( - // Breaking: FieldDef has new field `static` - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.ir.Trees#FieldDef.this"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.ir.Trees#FieldDef.apply"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.ir.Trees#FieldDef.copy"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.core.ir.Trees#FieldDef.copy$default$1"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.core.ir.Trees#FieldDef.copy$default$2"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.core.ir.Trees#FieldDef.copy$default$3"), - - // Breaking: PropertyDef has new field `static` - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.ir.Trees#PropertyDef.this"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.ir.Trees#PropertyDef.apply"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.ir.Trees#PropertyDef.copy"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.core.ir.Trees#PropertyDef.copy$default$1"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.core.ir.Trees#PropertyDef.copy$default$2"), - - // Breaking: TopLevelExportDef has been renamed to TopLevelMethodExportDef - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.ir.Trees$TopLevelExportDef"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.ir.Trees$TopLevelExportDef$"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.ir.Tags.TagTopLevelExportDef"), - - // Breaking: PropertyName.{name -> encodedName} - ProblemFilters.exclude[ReversedMissingMethodProblem]( - "org.scalajs.core.ir.Trees#PropertyName.encodedName"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.ir.Trees#StringLiteral.name"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.ir.Trees#PropertyName.name"), - - // private, not an issue - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.ir.Infos#MethodInfo.this"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.ir.Infos#GenInfoTraverser.generateClassExportsInfo") ) val Tools = Seq( - // Breaking: add 2 methods to the GenLinker trait - ProblemFilters.exclude[ReversedMissingMethodProblem]( - "org.scalajs.core.tools.linker.GenLinker.link"), - ProblemFilters.exclude[ReversedMissingMethodProblem]( - "org.scalajs.core.tools.linker.GenLinker.linkUnit"), - - // Breaking. Remove PropertyName.name - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.javascript.Trees#PropertyName.name"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.javascript.Trees#StringLiteral.name"), - - // private, not an issue - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.sem.Semantics.this"), - - // private, not an issue - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.checker.IRChecker#CheckedField.this"), - - // private, not an issue - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.analyzer.Analyzer.org$scalajs$core$tools$linker$analyzer$Analyzer$$createMissingMethodInfo$default$2"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.analyzer.Analyzer.org$scalajs$core$tools$linker$analyzer$Analyzer$$createMissingMethodInfo$default$3"), - - // private[frontend], not an issue - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.frontend.BaseLinker.linkInternal"), - - // private[closure], not an issue - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.tools.linker.backend.closure.ClosureAstTransformer.transformString"), - - // private[emitter], not an issue - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.tools.linker.backend.emitter.ScalaJSClassEmitter"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$DesugarException"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$MyTreeOps"), - - // private, not an issue - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$JSDesugar"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$JSDesugar$RecordFieldVarRef$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$JSDesugar$RecordVarRef$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$JSDesugar$RecordAwareEnv"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$Lhs"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$Lhs$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$Lhs$Assign"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$Lhs$Assign$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$Lhs$Return"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$Lhs$Return$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$Lhs$Discard$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$Lhs$VarDef$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$Lhs$VarDef"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$Env"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSDesugaring$Env$") ) val JSEnvs = Seq( @@ -141,157 +15,15 @@ object BinaryIncompatibilities { ) val SbtPlugin = Seq( - // private[scalajs], not an issue. - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.sbtplugin.HTMLRunnerTemplate.render") ) val TestAdapter = Seq( ) val CLI = Seq( - // private, not an issue - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.cli.Scalajsld#Options.this"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.$default$2"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.$default$3"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.$default$4"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.$default$5"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.$default$6"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.$default$7"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.$default$11"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.$default$12"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.$default$14"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.$default$15"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.cli.Scalajsld#Options.copy"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.copy$default$2"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.copy$default$3"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.copy$default$4"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.copy$default$5"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.copy$default$6"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.copy$default$7"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.copy$default$11"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.copy$default$12"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.copy$default$14"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.copy$default$15"), - ProblemFilters.exclude[MissingTypesProblem]( - "org.scalajs.cli.Scalajsld$Options$"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.cli.Scalajsld#Options.apply"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.apply$default$2"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.apply$default$3"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.apply$default$4"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.apply$default$5"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.apply$default$6"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.apply$default$7"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.apply$default$11"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.apply$default$12"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.apply$default$14"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.cli.Scalajsld#Options.apply$default$15") ) val Library = Seq( - // Relaxed typing (js.Iterable instead of js.Array) in js.Promise. - // Not a compatibility issue (due to JS land). - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "scala.scalajs.js.Promise.race"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "scala.scalajs.js.Promise.all"), - - // js.Iterable support in TypedArray. - // Not a compatibility issue (due to JS land). - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "scala.scalajs.js.typedarray.Int8Array.set"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "scala.scalajs.js.typedarray.Int8Array.this"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "scala.scalajs.js.typedarray.Uint8ClampedArray.set"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "scala.scalajs.js.typedarray.Uint8ClampedArray.this"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "scala.scalajs.js.typedarray.Uint16Array.set"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "scala.scalajs.js.typedarray.Uint16Array.this"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "scala.scalajs.js.typedarray.Uint8Array.set"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "scala.scalajs.js.typedarray.Uint8Array.this"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "scala.scalajs.js.typedarray.TypedArray.set"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "scala.scalajs.js.typedarray.TypedArray.set"), - ProblemFilters.exclude[ReversedMissingMethodProblem]( - "scala.scalajs.js.typedarray.TypedArray.set"), - ProblemFilters.exclude[ReversedMissingMethodProblem]( - "scala.scalajs.js.typedarray.TypedArray.jsIterator"), - ProblemFilters.exclude[InheritedNewAbstractMethodProblem]( - "scala.scalajs.js.Iterable.jsIterator"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "scala.scalajs.js.typedarray.Int32Array.set"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "scala.scalajs.js.typedarray.Int32Array.this"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "scala.scalajs.js.typedarray.Float32Array.set"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "scala.scalajs.js.typedarray.Float32Array.this"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "scala.scalajs.js.typedarray.Float64Array.set"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "scala.scalajs.js.typedarray.Float64Array.this"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "scala.scalajs.js.typedarray.Int16Array.set"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "scala.scalajs.js.typedarray.Int16Array.this"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "scala.scalajs.js.typedarray.Uint32Array.set"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "scala.scalajs.js.typedarray.Uint32Array.this"), - - // private[js], not an issue - ProblemFilters.exclude[DirectMissingMethodProblem]( - "scala.scalajs.js.Dictionary.rawApply"), - - // New member in non-sealed trait (for low prio implicits). - // Theoretically breaking. - ProblemFilters.exclude[InheritedNewAbstractMethodProblem]( - "scala.scalajs.js.LowestPrioAnyImplicits.iterableOps"), - - // New members of an @js.native trait in `runtime`, not an issue - ProblemFilters.exclude[ReversedMissingMethodProblem]( - "scala.scalajs.runtime.LinkingInfo#Semantics.arrayIndexOutOfBounds"), - ProblemFilters.exclude[ReversedMissingMethodProblem]( - "scala.scalajs.runtime.LinkingInfo#Semantics.scala$scalajs$runtime$LinkingInfo$Semantics$_setter_$arrayIndexOutOfBounds_=") ) val TestInterface = Seq( diff --git a/project/Build.scala b/project/Build.scala index b2cbba0bf3..da66a3f7ac 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -56,7 +56,7 @@ object Build { val shouldPartest = settingKey[Boolean]( "Whether we should partest the current scala version (and fail if we can't)") - val previousVersion = "0.6.14" + val previousVersion = "0.6.15" val previousSJSBinaryVersion = ScalaJSCrossVersion.binaryScalaJSVersion(previousVersion) val previousBinaryCrossVersion = @@ -1123,16 +1123,6 @@ object Build { previousArtifactSetting, mimaBinaryIssueFilters ++= BinaryIncompatibilities.CLI, - // TODO Remove this when going towards 0.6.16 - // Ignore bin compat of cli for 2.12 because it's new in 0.6.15. - mimaPreviousArtifacts := { - val scalaV = scalaVersion.value - if (scalaV.startsWith("2.10.") || scalaV.startsWith("2.11.")) - mimaPreviousArtifacts.value - else - Set.empty - }, - // assembly options mainClass in assembly := None, // don't want an executable JAR assemblyOption in assembly ~= { _.copy(includeScala = false) }, From 079d7fbaa0d4cf4d374c0c0b2ffdb1651b6b63bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 21 Mar 2017 16:21:00 +0100 Subject: [PATCH 0162/2665] Towards 1.0.0. --- .../main/scala/org/scalajs/core/ir/ScalaJSVersions.scala | 7 +++---- project/Build.scala | 5 +++++ .../scala/org/scalajs/sbtplugin/ScalaJSCrossVersion.scala | 6 +++--- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index 012d1ead12..f7c6b68c58 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.16-SNAPSHOT" + val current: String = "1.0.0-SNAPSHOT" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" @@ -21,12 +21,11 @@ object ScalaJSVersions { * - a prior release version (i.e. "0.5.0", *not* "0.5.0-SNAPSHOT") * - `current` */ - val binaryEmitted: String = "0.6.15" + val binaryEmitted: String = current /** Versions whose binary files we can support (used by deserializer) */ val binarySupported: Set[String] = { - Set("0.6.0", "0.6.3", "0.6.4", "0.6.5", "0.6.6", "0.6.8", "0.6.13", - "0.6.14", "0.6.15", binaryEmitted) + Set(binaryEmitted) } // Just to be extra safe diff --git a/project/Build.scala b/project/Build.scala index da66a3f7ac..0be54c7aca 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -56,6 +56,7 @@ object Build { val shouldPartest = settingKey[Boolean]( "Whether we should partest the current scala version (and fail if we can't)") + /* MiMa configuration -- irrelevant while in 1.0.0-SNAPSHOT. val previousVersion = "0.6.15" val previousSJSBinaryVersion = ScalaJSCrossVersion.binaryScalaJSVersion(previousVersion) @@ -66,6 +67,7 @@ object Build { Set("2.10.6", "2.11.8", "2.12.1") val newScalaBinaryVersionsInThisRelease: Set[String] = Set() + */ val javaVersion = settingKey[Int]( "The major Java SDK version that should be assumed for compatibility. " + @@ -88,6 +90,7 @@ object Build { val previousArtifactSetting: Setting[_] = { mimaPreviousArtifacts ++= { + /* MiMa is completely disabled while we are in 1.0.0-SNAPSHOT. val scalaV = scalaVersion.value val scalaBinaryV = scalaBinaryVersion.value if (!scalaVersionsUsedForPublishing.contains(scalaV)) { @@ -113,6 +116,8 @@ object Build { .extra(prevExtraAttributes.toSeq: _*) Set(CrossVersion(scalaV, scalaBinaryV)(prevProjectID).cross(CrossVersion.Disabled)) } + */ + Set.empty } } diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSCrossVersion.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSCrossVersion.scala index 4e22ecce43..8aedecd2a7 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSCrossVersion.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSCrossVersion.scala @@ -28,9 +28,9 @@ object ScalaJSCrossVersion { val currentBinaryVersion = binaryScalaJSVersion(ScalaJSVersions.binaryEmitted) def binaryScalaJSVersion(full: String): String = full match { - case ReleaseVersion(major, minor, _) => s"$major.$minor" - case MinorSnapshotVersion(major, minor, _) => s"$major.$minor" - case _ => full + case ReleaseVersion(major, _, _) => major + case MinorSnapshotVersion(major, _, _) => major + case _ => full } def scalaJSMapped(cross: CrossVersion): CrossVersion = cross match { From f73ad1981428759a8baa5a04e05fb62beb8e27e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 23 Mar 2017 15:53:46 +0100 Subject: [PATCH 0163/2665] Remove an ancient relic `helloworld/startup.js`. This dates back from the era of Scala.js 0.3! I have no idea how it survived there so long. --- examples/helloworld/startup.js | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 examples/helloworld/startup.js diff --git a/examples/helloworld/startup.js b/examples/helloworld/startup.js deleted file mode 100644 index f45e4cbe39..0000000000 --- a/examples/helloworld/startup.js +++ /dev/null @@ -1,8 +0,0 @@ -/* Scala.js example code - * Public domain - * Author: Sébastien Doeraene - */ - -$(function() { - ScalaJS.modules.helloworld_HelloWorld().main(); -}); From 0723177ad0255acbc66a12534b64ec892fed3cde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 23 Mar 2017 15:55:51 +0100 Subject: [PATCH 0164/2665] Fix the directory of `org.scalajs.sbtplugin.Loggers`. For some reason it was erroneously in `scala/scalajs/...` rather than `org/scalajs/...`. --- .../src/main/scala/{scala => org}/scalajs/sbtplugin/Loggers.scala | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename sbt-plugin/src/main/scala/{scala => org}/scalajs/sbtplugin/Loggers.scala (100%) diff --git a/sbt-plugin/src/main/scala/scala/scalajs/sbtplugin/Loggers.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Loggers.scala similarity index 100% rename from sbt-plugin/src/main/scala/scala/scalajs/sbtplugin/Loggers.scala rename to sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Loggers.scala From b9128c09719d1e96737d632d58ca4f7c7d6d108e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 21 Mar 2017 23:57:33 +0100 Subject: [PATCH 0165/2665] Fix #2823: Remove support for Rhino. The main chunk of this commit is obviously the removal of `org.scalajs.jsenv.rhino`, but there are other consequences: * The removal of Rhino-specific hooks in the linker * The removal of sbt settings dedicated to supporting Rhino * The removal of Platform.executingInRhino, and all the assumptions in the test suite that depend on it * Whitelisting one more partest, which was blacklisted only because Rhino did not support it The following things are *not* removed: * Support for Rhino detection and stack trace parsing in `StackTrace.scala`, so that a hypothetical third-party JS env for Rhino or Nashorn would get decent stack traces * The `ECMAScript51Global` output mode, which was only useful for Rhino (its removal is a TODO for a subsequent commit) --- DEVELOPING.md | 14 +- ci/matrix.xml | 29 +- .../scalajs/testsuite/utils/Platform.scala | 1 - .../scalajs/jsenv/test/RhinoJSEnvTest.scala | 10 - .../jsenv/rhino/LazyScalaJSScope.scala | 111 ---- .../org/scalajs/jsenv/rhino/RhinoJSEnv.scala | 618 ------------------ .../scalajs/jsenv/rhino/ScalaJSCoreLib.scala | 201 ------ .../org/scalajs/jsenv/rhino/package.scala | 42 -- .../main/scala/scala/scalajs/js/package.scala | 2 +- .../scala/scalajs/js/timers/package.scala | 4 +- .../scala/scalajs/runtime/StackTrace.scala | 8 +- .../noircheck/RhinoLinkFailureTest.scala | 34 - .../scalajs/2.11.0/BlacklistedTests.txt | 4 - .../scalajs/2.11.0/WhitelistedTests.txt | 1 + .../scalajs/2.11.1/BlacklistedTests.txt | 4 - .../scalajs/2.11.1/WhitelistedTests.txt | 1 + .../scalajs/2.11.2/BlacklistedTests.txt | 4 - .../scalajs/2.11.2/WhitelistedTests.txt | 1 + .../scalajs/2.11.5/BlacklistedTests.txt | 4 - .../scalajs/2.11.5/WhitelistedTests.txt | 1 + .../scalajs/2.11.6/BlacklistedTests.txt | 4 - .../scalajs/2.11.6/WhitelistedTests.txt | 1 + .../scalajs/2.11.7/BlacklistedTests.txt | 4 - .../scalajs/2.11.7/WhitelistedTests.txt | 1 + .../scalajs/2.11.8/BlacklistedTests.txt | 4 - .../scalajs/2.11.8/WhitelistedTests.txt | 1 + .../scalajs/2.12.0/BlacklistedTests.txt | 5 +- .../scalajs/2.12.0/WhitelistedTests.txt | 1 + .../scalajs/2.12.1/BlacklistedTests.txt | 5 +- .../scalajs/2.12.1/WhitelistedTests.txt | 1 + project/Build.scala | 18 +- project/build.sbt | 4 - .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 53 +- .../sbtplugin/ScalaJSPluginInternal.scala | 4 +- .../resources/2.11.5/BlacklistedTests.txt | 1 - .../resources/2.11.6/BlacklistedTests.txt | 1 - .../resources/2.11.7/BlacklistedTests.txt | 1 - .../resources/2.11.8/BlacklistedTests.txt | 1 - .../resources/2.12.0/BlacklistedTests.txt | 1 - .../resources/2.12.1/BlacklistedTests.txt | 1 - .../scalajs/testsuite/utils/Platform.scala | 1 - .../testsuite/javalib/lang/SystemJSTest.scala | 13 +- .../testsuite/jsinterop/DictionaryTest.scala | 3 - .../testsuite/jsinterop/ExportsTest.scala | 7 - .../testsuite/jsinterop/MiscInteropTest.scala | 1 - .../jsinterop/ScalaJSDefinedTest.scala | 4 - .../scalajs/testsuite/utils/Platform.scala | 1 - .../testsuite/javalib/lang/MathTest.scala | 3 - .../tools/linker/backend/OutputMode.scala | 5 +- .../linker/backend/emitter/ClassEmitter.scala | 48 -- .../linker/backend/emitter/Emitter.scala | 32 +- .../tools/linker/backend/emitter/JSGen.scala | 5 +- 52 files changed, 46 insertions(+), 1283 deletions(-) delete mode 100644 js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/RhinoJSEnvTest.scala delete mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/rhino/LazyScalaJSScope.scala delete mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/rhino/RhinoJSEnv.scala delete mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala delete mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/rhino/package.scala delete mode 100644 no-ir-check-test/src/test/scala/org/scalajs/testsuite/noircheck/RhinoLinkFailureTest.scala diff --git a/DEVELOPING.md b/DEVELOPING.md index 1ae366db94..ef12072574 100644 --- a/DEVELOPING.md +++ b/DEVELOPING.md @@ -38,11 +38,7 @@ you typically need to > reload -To test with Node.js instead of Rhino, use the usual Scala.js setting: - - > set scalaJSUseRhino in Global := false - -and to run in fullOpt stage: +To test in fullOpt stage: > set scalaJSStage in Global := FullOptStage @@ -50,11 +46,11 @@ When running with Node.js, by default, the test suite requires the `source-map-support` package to be installed in `npm`. You can bypass the source map tests locally with this setting: - > set postLinkJSEnv in testSuite := NodeJSEnv().value.withSourceMap(false) + > set jsEnv in testSuite := NodeJSEnv().value.withSourceMap(false) To test with PhantomJS, use this setting: - > set inScope(ThisScope in testSuite)(Seq(postLinkJSEnv := PhantomJSEnv().value)) + > set inScope(ThisScope in testSuite)(Seq(jsEnv := PhantomJSEnv().value)) The tests for the javalibEx are in a separate testing project: @@ -115,7 +111,7 @@ of `library/package`. Note that the sbt plugin depends on the IR and the tools. -* `js-envs/` The JavaScript environments and runners (Rhino, Node.js and PhantomJS) +* `js-envs/` The JavaScript environments and runners (Node.js and PhantomJS) * `sbt-plugin/` The sbt plugin itself ### Testing projects @@ -128,7 +124,7 @@ Note that the sbt plugin depends on the IR and the tools. * `examples/helloworld/` A simple Hello World, typically used as sandbox for quick testing * `examples/reversi/` The historical Reversi demo - we use it to track the impact of changes on the emitted code size -* `examples/testing/` A simple project with tests using the DOM, mostly used to test the support for the DOM in Rhino +* `examples/testing/` A simple project with tests using the DOM, mostly used to test the support for the DOM with jsdom and PhantomJS These example projects also have HTML pages to run them in real browsers. diff --git a/ci/matrix.xml b/ci/matrix.xml index 728e18b5b4..733ed924a8 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -15,7 +15,6 @@ put(name, this, base.get(name, base)) - case index: Int => put(index, this, base.get(index, base)) - } - } - } - - private def load(name: String): Unit = - coreLib.load(globalScope, propNameToEncodedName(name)) - - private def propNameToEncodedName(name: String): String = { - if (isStatics) name.split("__")(0) - else name - } - - override def getClassName(): String = "LazyScalaJSScope" - - override def get(name: String, start: Scriptable): AnyRef = { - if (name == "__noSuchMethod__") { - /* Automatically called by Rhino when trying to call a method fails. - * We don't want to throw a ClassNotFoundException for this case, but - * rather return a proper NOT_FOUND sentinel. Otherwise, this exception - * would "shadow" the real one containing the class name that could not - * be found on the classpath. - */ - Scriptable.NOT_FOUND - } else { - fields.getOrElse(name, { - try { - load(name) - fields.getOrElse(name, Scriptable.NOT_FOUND) - } catch { - // We need to re-throw the exception if `load` fails, otherwise the - // JavaScript runtime will not catch it. - case t: RhinoJSEnv.ClassNotFoundException => - throw Context.throwAsScriptRuntimeEx(t) - } - }).asInstanceOf[AnyRef] - } - } - - override def get(index: Int, start: Scriptable): AnyRef = - get(index.toString, start) - - override def has(name: String, start: Scriptable): Boolean = - fields.contains(name) - override def has(index: Int, start: Scriptable): Boolean = - has(index.toString, start) - - override def put(name: String, start: Scriptable, value: Any): Unit = - fields(name) = value - override def put(index: Int, start: Scriptable, value: Any): Unit = - put(index.toString, start, value) - - override def delete(name: String): Unit = () - override def delete(index: Int): Unit = () - - override def getPrototype(): Scriptable = prototype - override def setPrototype(value: Scriptable): Unit = prototype = value - - override def getParentScope(): Scriptable = parentScope - override def setParentScope(value: Scriptable): Unit = parentScope = value - - override def getIds(): Array[AnyRef] = fields.keys.toArray - - override def getDefaultValue(hint: java.lang.Class[_]): AnyRef = { - base.getDefaultValue(hint) - } - - override def hasInstance(instance: Scriptable): Boolean = false -} diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/RhinoJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/RhinoJSEnv.scala deleted file mode 100644 index 0bc0087840..0000000000 --- a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/RhinoJSEnv.scala +++ /dev/null @@ -1,618 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.jsenv.rhino - -import org.scalajs.jsenv._ -import org.scalajs.jsenv.Utils.OptDeadline - -import org.scalajs.core.tools.sem.Semantics -import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.jsdep.ResolvedJSDependency -import org.scalajs.core.tools.logging._ - -import org.scalajs.core.tools.linker.LinkingUnit -import org.scalajs.core.tools.linker.backend.OutputMode -import org.scalajs.core.tools.linker.backend.emitter.Emitter -import org.scalajs.core.tools.javascript.ESLevel - -import scala.annotation.tailrec - -import scala.io.Source - -import scala.collection.mutable - -import scala.concurrent.{Future, Promise, Await, TimeoutException} -import scala.concurrent.duration._ - -import scala.reflect.ClassTag - -import org.mozilla.javascript._ - -/** A JS environment using a modified Rhino interpreter (deprecated). - * - * As of Scala.js 0.6.13, `RhinoJSEnv` is deprecated. It will be removed in - * Scala.js 1.0.0. - */ -final class RhinoJSEnv private ( - semantics: Semantics, - withDOM: Boolean, - val sourceMap: Boolean -) extends LinkingUnitComJSEnv { - - import RhinoJSEnv._ - - @deprecated( - "The Rhino JS environment is being phased out. " + - "It will be removed in Scala.js 1.0.0. ", - "0.6.13") - def this(semantics: Semantics = Semantics.Defaults, withDOM: Boolean = false) = - this(semantics, withDOM, sourceMap = true) - - /** A non-deprecated constructor for internal use. */ - private[scalajs] def this(semantics: Semantics, withDOM: Boolean, - internal: Unit) = { - this(semantics, withDOM, sourceMap = true) - } - - def withSourceMap(sourceMap: Boolean): RhinoJSEnv = - new RhinoJSEnv(semantics, withDOM, sourceMap) - - /* Ask the Emitter, which we'll use in ScalaJSCoreLib to generate JS code, - * what are its requirements. - */ - val symbolRequirements = Emitter.symbolRequirements(semantics, ESLevel.ES5) - - def name: String = "RhinoJSEnv" - - override def loadLinkingUnit(linkingUnit: LinkingUnit): ComJSEnv = { - verifyUnit(linkingUnit) - super.loadLinkingUnit(linkingUnit) - } - - /** Executes code in an environment where the Scala.js library is set up to - * load its classes lazily. - * - * Other .js scripts in the inputs are executed eagerly before the provided - * `code` is called. - */ - override def jsRunner(libs: Seq[ResolvedJSDependency], - code: VirtualJSFile): JSRunner = { - new Runner(libs, None, Nil, code) - } - - override def jsRunner(preLibs: Seq[ResolvedJSDependency], - linkingUnit: LinkingUnit, postLibs: Seq[ResolvedJSDependency], - code: VirtualJSFile): JSRunner = { - verifyUnit(linkingUnit) - new Runner(preLibs, Some(linkingUnit), postLibs, code) - } - - private class Runner(preLibs: Seq[ResolvedJSDependency], - optLinkingUnit: Option[LinkingUnit], postLibs: Seq[ResolvedJSDependency], - code: VirtualJSFile) extends JSRunner { - def run(logger: Logger, console: JSConsole): Unit = - internalRunJS(preLibs, optLinkingUnit, postLibs, - code, logger, console, None) - } - - override def asyncRunner(libs: Seq[ResolvedJSDependency], - code: VirtualJSFile): AsyncJSRunner = { - new AsyncRunner(libs, None, Nil, code) - } - - override def asyncRunner(preLibs: Seq[ResolvedJSDependency], - linkingUnit: LinkingUnit, postLibs: Seq[ResolvedJSDependency], - code: VirtualJSFile): AsyncJSRunner = { - verifyUnit(linkingUnit) - new AsyncRunner(preLibs, Some(linkingUnit), postLibs, code) - } - - private class AsyncRunner(preLibs: Seq[ResolvedJSDependency], - optLinkingUnit: Option[LinkingUnit], postLibs: Seq[ResolvedJSDependency], - code: VirtualJSFile) extends AsyncJSRunner { - - private[this] val promise = Promise[Unit] - private[this] var _thread: Thread = _ - - def future: Future[Unit] = promise.future - - def start(logger: Logger, console: JSConsole): Future[Unit] = { - _thread = new Thread { - override def run(): Unit = { - try { - internalRunJS(preLibs, optLinkingUnit, postLibs, - code, logger, console, optChannel) - promise.success(()) - } catch { - case t: Throwable => - promise.failure(t) - } - } - } - - _thread.start() - future - } - - def stop(): Unit = _thread.interrupt() - - protected def optChannel(): Option[Channel] = None - } - - override def comRunner(libs: Seq[ResolvedJSDependency], - code: VirtualJSFile): ComJSRunner = { - new ComRunner(libs, None, Nil, code) - } - - override def comRunner(preLibs: Seq[ResolvedJSDependency], - linkingUnit: LinkingUnit, postLibs: Seq[ResolvedJSDependency], - code: VirtualJSFile): ComJSRunner = { - verifyUnit(linkingUnit) - new ComRunner(preLibs, Some(linkingUnit), postLibs, code) - } - - private class ComRunner(preLibs: Seq[ResolvedJSDependency], - optLinkingUnit: Option[LinkingUnit], postLibs: Seq[ResolvedJSDependency], - code: VirtualJSFile) - extends AsyncRunner(preLibs, optLinkingUnit, postLibs, code) - with ComJSRunner { - - private[this] val channel = new Channel - - override protected def optChannel(): Option[Channel] = Some(channel) - - def send(msg: String): Unit = channel.sendToJS(msg) - - def receive(timeout: Duration): String = { - try { - channel.recvJVM(timeout) - } catch { - case _: ChannelClosedException => - throw new ComJSEnv.ComClosedException - } - } - - def close(): Unit = channel.closeJVM() - - } - - private def internalRunJS(preLibs: Seq[ResolvedJSDependency], - optLinkingUnit: Option[LinkingUnit], postLibs: Seq[ResolvedJSDependency], - code: VirtualJSFile, logger: Logger, console: JSConsole, - optChannel: Option[Channel]): Unit = { - - val context = Context.enter() - try { - val scope = context.initStandardObjects() - - // Rhino has trouble optimizing some big things, e.g., env.js or ScalaTest - context.setOptimizationLevel(-1) - - if (withDOM) - setupDOM(context, scope) - - disableLiveConnect(context, scope) - setupConsole(context, scope, console) - - val taskQ = setupSetTimeout(context, scope) - - // Optionally setup scalaJSCom - var recvCallback: Option[String => Unit] = None - for (channel <- optChannel) { - setupCom(context, scope, channel, - setCallback = cb => recvCallback = Some(cb), - clrCallback = () => recvCallback = None) - } - - try { - // Evaluate pre JS libs - preLibs.foreach(lib => context.evaluateFile(scope, lib.lib)) - - // Load LinkingUnit (if present) - optLinkingUnit.foreach(loadLinkingUnit(context, scope, _)) - - // Evaluate post JS libs - postLibs.foreach(lib => context.evaluateFile(scope, lib.lib)) - - // Actually run the code - context.evaluateFile(scope, code) - - // Start the event loop - - for (channel <- optChannel) { - comEventLoop(taskQ, channel, - () => recvCallback.get, () => recvCallback.isDefined) - } - - // Channel is closed. Fall back to basic event loop - basicEventLoop(taskQ) - - } catch { - case e: RhinoException => - // Trace here, since we want to be in the context to trace. - logger.trace(e) - sys.error(s"Exception while running JS code: ${e.getMessage}") - } - } finally { - // Ensure the channel is closed to release JVM side - optChannel.foreach(_.closeJS()) - - Context.exit() - } - } - - private def setupDOM(context: Context, scope: Scriptable): Unit = { - // Fetch env.rhino.js from webjar - val name = "env.rhino.js" - val path = "/META-INF/resources/webjars/envjs/1.2/" + name - val resource = getClass.getResource(path) - assert(resource != null, s"need $name as resource") - - // Don't print envjs header - scope.addFunction("print", args => ()) - - // Pipe file to Rhino - val reader = Source.fromURL(resource).bufferedReader - context.evaluateReader(scope, reader, name, 1, null); - - // No need to actually define print here: It is captured by envjs to - // implement console.log, which we'll override in the next statement - } - - /** Make sure Rhino does not do its magic for JVM top-level packages (#364) */ - private def disableLiveConnect(context: Context, scope: Scriptable): Unit = { - val PackagesObject = - ScriptableObject.getProperty(scope, "Packages").asInstanceOf[Scriptable] - val topLevelPackageIds = ScriptableObject.getPropertyIds(PackagesObject) - for (id <- topLevelPackageIds) (id: Any) match { - case name: String => ScriptableObject.deleteProperty(scope, name) - case index: Int => ScriptableObject.deleteProperty(scope, index) - case _ => // should not happen, I think, but with Rhino you never know - } - } - - private def setupConsole(context: Context, scope: Scriptable, - console: JSConsole): Unit = { - // Setup console.log - val jsconsole = context.newObject(scope) - jsconsole.addFunction("log", _.foreach(console.log _)) - ScriptableObject.putProperty(scope, "console", jsconsole) - } - - private def setupSetTimeout(context: Context, - scope: Scriptable): TaskQueue = { - - val ordering = Ordering.by[TimedTask, Deadline](_.deadline).reverse - val taskQ = mutable.PriorityQueue.empty(ordering) - - def ensure[T: ClassTag](v: AnyRef, errMsg: String) = v match { - case v: T => v - case _ => sys.error(errMsg) - } - - scope.addFunction("setTimeout", args => { - val cb = ensure[Function](args(0), - "First argument to setTimeout must be a function") - - val deadline = - args.lift(1).fold(0)(n => Context.toNumber(n).toInt).millis.fromNow - - val task = new TimeoutTask(deadline, () => - cb.call(context, scope, scope, args.slice(2, args.length))) - - taskQ += task - - task - }) - - scope.addFunction("setInterval", args => { - val cb = ensure[Function](args(0), - "First argument to setInterval must be a function") - - val interval = Context.toNumber(args(1)).toInt.millis - val firstDeadline = interval.fromNow - - val task = new IntervalTask(firstDeadline, interval, () => - cb.call(context, scope, scope, args.slice(2, args.length))) - - taskQ += task - - task - }) - - scope.addFunction("clearTimeout", args => { - val task = ensure[TimeoutTask](args(0), "First argument to " + - "clearTimeout must be a value returned by setTimeout") - task.cancel() - }) - - scope.addFunction("clearInterval", args => { - val task = ensure[IntervalTask](args(0), "First argument to " + - "clearInterval must be a value returned by setInterval") - task.cancel() - }) - - taskQ - } - - private def setupCom(context: Context, scope: Scriptable, channel: Channel, - setCallback: (String => Unit) => Unit, clrCallback: () => Unit): Unit = { - - val comObj = context.newObject(scope) - - comObj.addFunction("send", s => - channel.sendToJVM(Context.toString(s(0)))) - - comObj.addFunction("init", s => s(0) match { - case f: Function => - val cb: String => Unit = - msg => f.call(context, scope, scope, Array(msg)) - setCallback(cb) - case _ => - sys.error("First argument to init must be a function") - }) - - comObj.addFunction("close", _ => { - // Tell JVM side we won't send anything - channel.closeJS() - // Internally register that we're done - clrCallback() - }) - - ScriptableObject.putProperty(scope, "scalajsCom", comObj) - } - - /** Loads a [[LinkingUnit]] with lazy loading of classes and source mapping. */ - private def loadLinkingUnit(context: Context, scope: Scriptable, - linkingUnit: LinkingUnit): Unit = { - - val loader = new ScalaJSCoreLib(linkingUnit) - - // Setup sourceMapper - if (sourceMap) { - val oldScalaJSenv = ScriptableObject.getProperty(scope, "__ScalaJSEnv") - val scalaJSenv = oldScalaJSenv match { - case Scriptable.NOT_FOUND => - val newScalaJSenv = context.newObject(scope) - ScriptableObject.putProperty(scope, "__ScalaJSEnv", newScalaJSenv) - newScalaJSenv - - case oldScalaJSenv: Scriptable => - oldScalaJSenv - } - - scalaJSenv.addFunction("sourceMapper", args => { - val trace = Context.toObject(args(0), scope) - loader.mapStackTrace(trace, context, scope) - }) - } - - loader.insertInto(context, scope) - } - - private def basicEventLoop(taskQ: TaskQueue): Unit = - eventLoopImpl(taskQ, sleepWait, () => true) - - private def comEventLoop(taskQ: TaskQueue, channel: Channel, - callback: () => String => Unit, isOpen: () => Boolean): Unit = { - - if (!isOpen()) - // The channel has not been opened yet. Wait for opening. - eventLoopImpl(taskQ, sleepWait, () => !isOpen()) - - // Once we reach this point, we either: - // - Are done - // - The channel is open - - // Guard call to `callback` - if (isOpen()) { - val cb = callback() - try { - @tailrec - def loop(): Unit = { - val loopResult = eventLoopImpl(taskQ, channel.recvJS _, isOpen) - - loopResult match { - case Some(msg) => - cb(msg) - loop() - case None if isOpen() => - assert(taskQ.isEmpty) - cb(channel.recvJS()) - loop() - case None => - // No tasks left, channel closed - } - } - loop() - } catch { - case _: ChannelClosedException => - // the JVM side closed the connection - } - } - } - - /** Run an event loop on [[taskQ]] using [[waitFct]] to wait - * - * If [[waitFct]] returns a Some, this method returns this value immediately - * If [[waitFct]] returns a None, we assume a sufficient amount has been - * waited for the Deadline to pass. The event loop then runs the task. - * - * Each iteration, [[continue]] is queried, whether to continue the loop. - * - * @returns A Some returned by [[waitFct]] or None if [[continue]] has - * returned false, or there are no more tasks (i.e. [[taskQ]] is empty) - * @throws InterruptedException if the thread was interrupted - */ - private def eventLoopImpl[T](taskQ: TaskQueue, - waitFct: Deadline => Option[T], continue: () => Boolean): Option[T] = { - - @tailrec - def loop(): Option[T] = { - if (Thread.interrupted()) - throw new InterruptedException() - - if (taskQ.isEmpty || !continue()) None - else { - val task = taskQ.head - if (task.canceled) { - taskQ.dequeue() - loop() - } else { - waitFct(task.deadline) match { - case result @ Some(_) => result - - case None => - // The time has actually expired - val task = taskQ.dequeue() - - // Perform task - task.task() - - if (task.reschedule()) - taskQ += task - - loop() - } - } - } - } - - loop() - } - - private val sleepWait = { (deadline: Deadline) => - val timeLeft = deadline.timeLeft.toMillis - if (timeLeft > 0) - Thread.sleep(timeLeft) - None - } - - private def verifyUnit(linkingUnit: LinkingUnit) = { - require(linkingUnit.semantics == semantics, - "RhinoJSEnv and LinkingUnit must agree on semantics") - require(linkingUnit.esLevel == ESLevel.ES5, "RhinoJSEnv only supports ES5") - } - -} - -object RhinoJSEnv { - - final class ClassNotFoundException(className: String) extends Exception( - s"Rhino was unable to load Scala.js class: $className") - - /** Communication channel between the Rhino thread and the rest of the JVM */ - private class Channel { - private[this] var _closedJS = false - private[this] var _closedJVM = false - private[this] val js2jvm = mutable.Queue.empty[String] - private[this] val jvm2js = mutable.Queue.empty[String] - - def sendToJS(msg: String): Unit = synchronized { - ensureOpen(_closedJVM) - jvm2js.enqueue(msg) - notifyAll() - } - - def sendToJVM(msg: String): Unit = synchronized { - ensureOpen(_closedJS) - js2jvm.enqueue(msg) - notifyAll() - } - - def recvJVM(timeout: Duration): String = synchronized { - val deadline = OptDeadline(timeout) - - while (js2jvm.isEmpty && ensureOpen(_closedJS) && !deadline.isOverdue) - wait(deadline.millisLeft) - - if (js2jvm.isEmpty) - throw new TimeoutException("Timeout expired") - js2jvm.dequeue() - } - - def recvJS(): String = synchronized { - while (jvm2js.isEmpty && ensureOpen(_closedJVM)) - wait() - - jvm2js.dequeue() - } - - def recvJS(deadline: Deadline): Option[String] = synchronized { - var expired = false - while (jvm2js.isEmpty && !expired && ensureOpen(_closedJVM)) { - val timeLeft = deadline.timeLeft.toMillis - if (timeLeft > 0) - wait(timeLeft) - else - expired = true - } - - if (expired) None - else Some(jvm2js.dequeue()) - } - - def closeJS(): Unit = synchronized { - _closedJS = true - notifyAll() - } - - def closeJVM(): Unit = synchronized { - _closedJVM = true - notifyAll() - } - - /** Throws if the channel is closed and returns true */ - private def ensureOpen(closed: Boolean): Boolean = { - if (closed) - throw new ChannelClosedException - true - } - } - - private class ChannelClosedException extends Exception - - private abstract class TimedTask(val task: () => Unit) { - private[this] var _canceled: Boolean = false - - def deadline: Deadline - def reschedule(): Boolean - - def canceled: Boolean = _canceled - def cancel(): Unit = _canceled = true - } - - private final class TimeoutTask(val deadline: Deadline, - task: () => Unit) extends TimedTask(task) { - def reschedule(): Boolean = false - - override def toString(): String = - s"TimeoutTask($deadline, canceled = $canceled)" - } - - private final class IntervalTask(firstDeadline: Deadline, - interval: FiniteDuration, task: () => Unit) extends TimedTask(task) { - - private[this] var _deadline = firstDeadline - - def deadline: Deadline = _deadline - - def reschedule(): Boolean = { - _deadline += interval - !canceled - } - - override def toString(): String = - s"IntervalTask($deadline, interval = $interval, canceled = $canceled)" - } - - private type TaskQueue = mutable.PriorityQueue[TimedTask] - -} diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala deleted file mode 100644 index 8da714762c..0000000000 --- a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala +++ /dev/null @@ -1,201 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.jsenv.rhino - -import scala.collection.mutable - -import org.mozilla.javascript.{Context, Scriptable} - -import org.scalajs.core.ir - -import org.scalajs.core.tools.sem.Semantics -import org.scalajs.core.tools.linker.{LinkedClass, LinkingUnit} -import org.scalajs.core.tools.javascript._ -import org.scalajs.core.tools.io._ - -import org.scalajs.core.tools.linker.backend.ModuleKind.NoModule -import org.scalajs.core.tools.linker.backend.OutputMode.ECMAScript51Global -import org.scalajs.core.tools.linker.backend.emitter._ - -private[rhino] class ScalaJSCoreLib(linkingUnit: LinkingUnit) { - import ScalaJSCoreLib._ - - require(linkingUnit.esLevel == ESLevel.ES5, "RhinoJSEnv only supports ES5") - - private val emitter = - new Emitter(linkingUnit.semantics, ECMAScript51Global, NoModule) - - emitter.rhinoAPI.initialize(linkingUnit) - - private val (providers, exportedSymbols) = { - val providers = mutable.Map.empty[String, LinkedClass] - val exportedSymbols = mutable.ListBuffer.empty[String] - - for (linkedClass <- linkingUnit.classDefs) { - def hasStaticInitializer = { - linkedClass.staticMethods.exists { - _.tree.name.encodedName == ir.Definitions.StaticInitializerName - } - } - - providers += linkedClass.encodedName -> linkedClass - if (linkedClass.isExported || hasStaticInitializer) - exportedSymbols += linkedClass.encodedName - } - - (providers, exportedSymbols) - } - - def insertInto(context: Context, scope: Scriptable): Unit = { - val semantics = linkingUnit.semantics - context.evaluateFile(scope, emitter.rhinoAPI.getHeaderFile()) - lazifyScalaJSFields(scope) - - // Make sure exported symbols are loaded - val ScalaJS = Context.toObject(scope.get("ScalaJS", scope), scope) - val c = Context.toObject(ScalaJS.get("c", ScalaJS), scope) - for (encodedName <- exportedSymbols) - c.get(encodedName, c) - - // Execute the module initializers - evaluateJSTree(scope, emitter.rhinoAPI.genModuleInitializers(linkingUnit), - "ScalaJSEntryPoints.js") - } - - /** Source maps the given stack trace (where possible) */ - def mapStackTrace(stackTrace: Scriptable, - context: Context, scope: Scriptable): Scriptable = { - val count = Context.toNumber(stackTrace.get("length", stackTrace)).toInt - - // Maps file -> max line (0-based) - val neededMaps = mutable.Map.empty[String, Int] - - // Collect required line counts - for (i <- 0 until count) { - val elem = Context.toObject(stackTrace.get(i, stackTrace), scope) - val fileName = Context.toString(elem.get("fileName", elem)) - - if (fileName.endsWith(PseudoFileSuffix) && - providers.contains(fileName.stripSuffix(PseudoFileSuffix))) { - - val curMaxLine = neededMaps.getOrElse(fileName, -1) - val reqLine = Context.toNumber(elem.get("lineNumber", elem)).toInt - 1 - - if (reqLine > curMaxLine) - neededMaps.put(fileName, reqLine) - } - } - - // Map required files - val maps = - for ((fileName, maxLine) <- neededMaps) - yield (fileName, getSourceMapper(fileName, maxLine)) - - // Create new stack trace to return - val res = context.newArray(scope, count) - - for (i <- 0 until count) { - val elem = Context.toObject(stackTrace.get(i, stackTrace), scope) - val fileName = Context.toString(elem.get("fileName", elem)) - val line = Context.toNumber(elem.get("lineNumber", elem)).toInt - 1 - - val pos = maps.get(fileName).fold(ir.Position.NoPosition)(_(line)) - - val newElem = - if (pos.isDefined) newPosElem(scope, context, elem, pos) - else elem - - res.put(i, res, newElem) - } - - res - } - - private def getSourceMapper(fileName: String, untilLine: Int) = { - val linked = providers(fileName.stripSuffix(PseudoFileSuffix)) - val mapper = new Printers.ReverseSourceMapPrinter(untilLine) - val desugared = emitter.rhinoAPI.genClassDef(linked) - mapper.reverseSourceMap(desugared) - mapper - } - - private def newPosElem(scope: Scriptable, context: Context, - origElem: Scriptable, pos: ir.Position): Scriptable = { - assert(pos.isDefined) - - val elem = context.newObject(scope) - - elem.put("declaringClass", elem, origElem.get("declaringClass", origElem)) - elem.put("methodName", elem, origElem.get("methodName", origElem)) - elem.put("fileName", elem, pos.source.toString) - elem.put("lineNumber", elem, pos.line + 1) - elem.put("columnNumber", elem, pos.column + 1) - - elem - } - - private val scalaJSLazyFields = Seq( - Info("d"), - Info("a"), - Info("b"), - Info("c"), - Info("h"), - Info("s", isStatics = true), - Info("t", isStatics = true), - Info("f", isStatics = true), - Info("n"), - Info("m"), - Info("is"), - Info("as"), - Info("isArrayOf"), - Info("asArrayOf")) - - private def lazifyScalaJSFields(scope: Scriptable) = { - val ScalaJS = Context.toObject(scope.get("ScalaJS", scope), scope) - - def makeLazyScalaJSScope(base: Scriptable, isStatics: Boolean) = - new LazyScalaJSScope(this, scope, base, isStatics) - - for (Info(name, isStatics) <- scalaJSLazyFields) { - val base = ScalaJS.get(name, ScalaJS) - // Depending on the Semantics, some fields could be entirely absent - if (base != Scriptable.NOT_FOUND) { - val lazified = makeLazyScalaJSScope( - base.asInstanceOf[Scriptable], isStatics) - ScalaJS.put(name, ScalaJS, lazified) - } - } - } - - private[rhino] def load(scope: Scriptable, encodedName: String): Unit = { - val linkedClass = providers.getOrElse(encodedName, - throw new RhinoJSEnv.ClassNotFoundException(encodedName)) - - val desugared = emitter.rhinoAPI.genClassDef(linkedClass) - evaluateJSTree(scope, desugared, encodedName + PseudoFileSuffix) - } - - private def evaluateJSTree(scope: Scriptable, tree: Trees.Tree, - fakeFileName: String): Unit = { - val codeWriter = new java.io.StringWriter - val printer = new Printers.JSTreePrinter(codeWriter) - printer.printTopLevelTree(tree) - printer.complete() - val ctx = Context.getCurrentContext() - ctx.evaluateString(scope, codeWriter.toString(), - fakeFileName, 1, null) - } -} - -private[rhino] object ScalaJSCoreLib { - private case class Info(name: String, isStatics: Boolean = false) - - private final val PseudoFileSuffix = ".sjsir" -} diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/package.scala b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/package.scala deleted file mode 100644 index 3f67cbd34d..0000000000 --- a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/package.scala +++ /dev/null @@ -1,42 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.jsenv - -import org.mozilla.javascript._ - -import org.scalajs.core.tools.io._ - -package object rhino { - - private[rhino] implicit class ContextOps(val self: Context) extends AnyVal { - def evaluateFile(scope: Scriptable, file: VirtualJSFile, - securityDomain: AnyRef = null): Any = { - self.evaluateString(scope, file.content, file.path, 1, securityDomain) - } - } - - private[rhino] implicit class ScriptableObjectOps(val self: Scriptable) { - def addFunction(name: String, function: Array[AnyRef] => Any): Unit = { - val rhinoFunction = - new BaseFunction { - ScriptRuntime.setFunctionProtoAndParent(this, self) - override def call(context: Context, scope: Scriptable, - thisObj: Scriptable, args: Array[AnyRef]): AnyRef = { - function(args) match { - case () => Undefined.instance - case r => r.asInstanceOf[AnyRef] - } - } - } - - ScriptableObject.putProperty(self, name, rhinoFunction) - } - } -} diff --git a/library/src/main/scala/scala/scalajs/js/package.scala b/library/src/main/scala/scala/scalajs/js/package.scala index 67e25a8510..5ad71af18a 100644 --- a/library/src/main/scala/scala/scalajs/js/package.scala +++ b/library/src/main/scala/scala/scalajs/js/package.scala @@ -92,7 +92,7 @@ package object js { * MDN * * Browser support: - * - Has no effect in Rhino nor, apparently, in Firefox + * - Has no effect in Firefox, apparently * - In Chrome, it has no effect unless the developer tools are opened * beforehand. */ diff --git a/library/src/main/scala/scala/scalajs/js/timers/package.scala b/library/src/main/scala/scala/scalajs/js/timers/package.scala index fe1a38fc2c..e1d704e6e0 100644 --- a/library/src/main/scala/scala/scalajs/js/timers/package.scala +++ b/library/src/main/scala/scala/scalajs/js/timers/package.scala @@ -14,10 +14,10 @@ import scala.concurrent.duration.FiniteDuration /** * Non-Standard * Non-standard, but in general well supported methods to schedule asynchronous - * exeuction. + * execution. * * The methods in this package work in all JavaScript virtual machines - * supported by Scala.js (currently Rhino, Node.js and PhantomJS). + * supporting `setTimeout` and `setInterval`. */ package object timers { diff --git a/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala b/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala index 02e0be8c08..750961b95a 100644 --- a/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala +++ b/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala @@ -62,7 +62,13 @@ object StackTrace { @inline def captureState(throwable: Throwable, e: Any): Unit = throwable.asInstanceOf[js.Dynamic].stackdata = e.asInstanceOf[js.Any] - /** Tests whether we're running under Rhino. */ + /** Tests whether we're running under Rhino (or Nashorn). + * + * Even though we do not support Rhino nor Nashorn in the core repository, + * we can always hope that someone will eventually pull off a third-party JS + * env that manages to use either without surgery in the Scala.js linker. + * So we keep support of stack trace detection for those engines. + */ private lazy val isRhino: Boolean = { try { js.Dynamic.global.Packages.org.mozilla.javascript.JavaScriptException diff --git a/no-ir-check-test/src/test/scala/org/scalajs/testsuite/noircheck/RhinoLinkFailureTest.scala b/no-ir-check-test/src/test/scala/org/scalajs/testsuite/noircheck/RhinoLinkFailureTest.scala deleted file mode 100644 index 6aecea3d84..0000000000 --- a/no-ir-check-test/src/test/scala/org/scalajs/testsuite/noircheck/RhinoLinkFailureTest.scala +++ /dev/null @@ -1,34 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ -package org.scalajs.testsuite.noircheck - -import org.junit.Test -import org.junit.Assert._ -import org.junit.Assume._ - -import scala.scalajs.js - -class RhinoLinkFailureTest { - - @Test def Rhino_linking_should_throw_an_exception_if_it_fails_loading_a_class(): Unit = { - val executingInRhino = System.getProperty("scalajs.rhino", "false") == "true" - assumeTrue("Assumed executing in Rhino", executingInRhino) - - // scala.collection.parallel.Splitter$ is not defined - try { - val pool = scala.collection.parallel.Splitter.empty - sys.error("Should not reach here") - } catch { - case js.JavaScriptException(e) => - // Make sure offending class is reported - assertTrue(e.toString.contains("sc_parallel_Splitter$")) - } - - } - -} diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/BlacklistedTests.txt index cfd6fc4af6..4cf53e21b1 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/BlacklistedTests.txt @@ -107,11 +107,7 @@ run/t6253b.scala run/t6253c.scala run/numbereq.scala run/t4658.scala - -# Crashes Rhino - run/bridges.scala -run/patmat-exprs.scala # Using partest properties diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/WhitelistedTests.txt index 576bf96b5f..cbbb456dac 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/WhitelistedTests.txt @@ -2887,6 +2887,7 @@ run/t5608.scala run/t3518.scala run/t6198.scala run/t2813.2.scala +run/patmat-exprs.scala # Adapt checkfiles for (1.0).toString == "1" run/Course-2002-01.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/BlacklistedTests.txt index 01c1d8b0f4..9106349ca6 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/BlacklistedTests.txt @@ -107,11 +107,7 @@ run/t6253b.scala run/t6253c.scala run/numbereq.scala run/t4658.scala - -# Crashes Rhino - run/bridges.scala -run/patmat-exprs.scala # Using partest properties diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/WhitelistedTests.txt index fd45587491..2e27016dec 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/WhitelistedTests.txt @@ -2905,6 +2905,7 @@ run/t5608.scala run/t3518.scala run/t6198.scala run/t2813.2.scala +run/patmat-exprs.scala # Adapt checkfiles for (1.0).toString == "1" run/Course-2002-01.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/BlacklistedTests.txt index dbc5e1f732..1a47a4999f 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/BlacklistedTests.txt @@ -108,11 +108,7 @@ run/t6253b.scala run/t6253c.scala run/numbereq.scala run/t4658.scala - -# Crashes Rhino - run/bridges.scala -run/patmat-exprs.scala # Using partest properties diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/WhitelistedTests.txt index a2fdef5743..560db6620f 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/WhitelistedTests.txt @@ -2934,6 +2934,7 @@ run/t3518.scala run/t8346.scala run/t6198.scala run/t2813.2.scala +run/patmat-exprs.scala # Adapt checkfiles for (1.0).toString == "1" run/Course-2002-01.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/BlacklistedTests.txt index 387b5a622d..64ed501be5 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/BlacklistedTests.txt @@ -110,11 +110,7 @@ run/t6253b.scala run/t6253c.scala run/numbereq.scala run/t4658.scala - -# Crashes Rhino - run/bridges.scala -run/patmat-exprs.scala # Using partest properties diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/WhitelistedTests.txt index 08a68a3d82..64d3004876 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/WhitelistedTests.txt @@ -3020,6 +3020,7 @@ run/t3518.scala run/t8346.scala run/t6198.scala run/t2813.2.scala +run/patmat-exprs.scala # Adapt checkfiles for (1.0).toString == "1" run/Course-2002-01.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/BlacklistedTests.txt index cfa245fc6e..ffa1d262be 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/BlacklistedTests.txt @@ -110,11 +110,7 @@ run/t6253b.scala run/t6253c.scala run/numbereq.scala run/t4658.scala - -# Crashes Rhino - run/bridges.scala -run/patmat-exprs.scala # Using partest properties diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/WhitelistedTests.txt index 62cac931f3..bda5bd7f1f 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/WhitelistedTests.txt @@ -3032,6 +3032,7 @@ run/t3518.scala run/t8346.scala run/t6198.scala run/t2813.2.scala +run/patmat-exprs.scala # Adapt checkfiles for (1.0).toString == "1" run/Course-2002-01.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt index 0dc70a2a0f..66f4f16858 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt @@ -114,11 +114,7 @@ run/t6253b.scala run/t6253c.scala run/numbereq.scala run/t4658.scala - -# Crashes Rhino - run/bridges.scala -run/patmat-exprs.scala # Using partest properties diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt index 19e4217fc8..7e4ec802b9 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt @@ -3059,6 +3059,7 @@ run/t3518.scala run/t8346.scala run/t6198.scala run/t2813.2.scala +run/patmat-exprs.scala # Adapt checkfiles for (1.0).toString == "1" run/Course-2002-01.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt index 007bc3af55..ff8af5f9d3 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt @@ -118,11 +118,7 @@ run/t6253b.scala run/t6253c.scala run/numbereq.scala run/t4658.scala - -# Crashes Rhino - run/bridges.scala -run/patmat-exprs.scala # Using partest properties diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt index fa420a587b..5f523d7609 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt @@ -3093,6 +3093,7 @@ neg/t9401.scala neg/t9572.scala neg/warn-unused-imports neg/partestInvalidFlag.scala +run/patmat-exprs.scala # Adapt checkfiles for (1.0).toString == "1" run/Course-2002-01.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt index 52594133a7..cf3808febe 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt @@ -25,6 +25,7 @@ neg/macro-incompatible-macro-engine-c.scala # Uses .java files run/t9200 run/noInlineUnknownIndy + # # RUN # @@ -107,11 +108,7 @@ run/t6253b.scala run/t6253c.scala run/numbereq.scala run/t4658.scala - -# Crashes Rhino - run/bridges.scala -run/patmat-exprs.scala # Using partest properties diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt index 0503e9c2c7..ecffa5252b 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt @@ -3229,6 +3229,7 @@ run/trait-fields-override-lazy.scala run/trait_fields_init.scala run/trait_fields_three_layer_overrides.scala run/t9516.scala +run/patmat-exprs.scala # Adapt checkfiles for (1.0).toString == "1" run/Course-2002-01.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt index 7aee11c040..71e7dfb7fa 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt @@ -25,6 +25,7 @@ neg/macro-incompatible-macro-engine-c.scala # Uses .java files run/t9200 run/noInlineUnknownIndy + # # RUN # @@ -107,11 +108,7 @@ run/t6253b.scala run/t6253c.scala run/numbereq.scala run/t4658.scala - -# Crashes Rhino - run/bridges.scala -run/patmat-exprs.scala # Using partest properties diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt index 78ea8bd2e4..1591a9bbcb 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt @@ -3228,6 +3228,7 @@ run/trait_fields_init.scala run/trait_fields_three_layer_overrides.scala run/t9516.scala run/t10032.scala +run/patmat-exprs.scala # Adapt checkfiles for (1.0).toString == "1" run/Course-2002-01.scala diff --git a/project/Build.scala b/project/Build.scala index 0be54c7aca..76e7b3d4d7 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -21,7 +21,6 @@ import org.scalajs.core.ir.Utils.escapeJS import org.scalajs.sbtplugin._ import org.scalajs.jsenv.{JSEnv, RetryingComJSEnv} -import org.scalajs.jsenv.rhino.RhinoJSEnv import org.scalajs.jsenv.nodejs.{NodeJSEnv, JSDOMNodeJSEnv} import org.scalajs.jsenv.phantomjs.PhantomJSEnv import ScalaJSPlugin.autoImport._ @@ -694,10 +693,8 @@ object Build { commonSettings ++ publishSettings ++ fatalWarningsSettings ) ++ Seq( name := "Scala.js JS Envs", - libraryDependencies ++= Seq( - "io.apigee" % "rhino" % "1.7R5pre4", - "org.webjars" % "envjs" % "1.2" - ) ++ ScalaJSPluginInternal.phantomJSJettyModules.map(_ % "provided"), + libraryDependencies ++= + ScalaJSPluginInternal.phantomJSJettyModules.map(_ % "provided"), previousArtifactSetting, mimaBinaryIssueFilters ++= BinaryIncompatibilities.JSEnvs ) @@ -1260,11 +1257,6 @@ object Build { testOptionTags := { @tailrec def envTagsFor(env: JSEnv): Seq[String] = env match { - case env: RhinoJSEnv => - val baseArgs = Seq("rhino") - if (env.sourceMap) baseArgs :+ "source-maps" - else baseArgs - case env: NodeJSEnv => val baseArgs = Seq("nodejs", "typedarray") if (env.sourceMap) { @@ -1404,7 +1396,7 @@ object Build { // We need to patch the system properties. scalaJSJavaSystemProperties in Test in testHtmlKey ~= { base => val unsupported = - Seq("rhino", "nodejs", "nodejs.jsdom", "phantomjs", "source-maps") + Seq("nodejs", "nodejs.jsdom", "phantomjs", "source-maps") val supported = Seq("typedarray", "browser") @@ -1666,7 +1658,6 @@ object Build { "org.scala-lang.modules" %% "scala-partest" % "1.0.17" }, "org.scala-js" % "closure-compiler-java-6" % "v20160517", - "io.apigee" % "rhino" % "1.7R5pre4", "com.googlecode.json-simple" % "json-simple" % "1.1.1" exclude("junit", "junit") ) else Seq() @@ -1695,8 +1686,7 @@ object Build { val scalaFilter: FileFilter = "*.scala" val files = ( (jsenvBase * scalaFilter) +++ - (jsenvBase / "nodejs" ** scalaFilter) +++ - (jsenvBase / "rhino" ** scalaFilter)) + (jsenvBase / "nodejs" ** scalaFilter)) files.get } diff --git a/project/build.sbt b/project/build.sbt index ba4d3524d3..28543e18f5 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -13,10 +13,6 @@ addSbtPlugin("org.scalastyle" % "scalastyle-sbt-plugin" % "0.8.0") libraryDependencies += "org.scala-js" % "closure-compiler-java-6" % "v20160517" -libraryDependencies += "io.apigee" % "rhino" % "1.7R5pre4" - -libraryDependencies += "org.webjars" % "envjs" % "1.2" - libraryDependencies += "org.eclipse.jgit" % "org.eclipse.jgit.pgm" % "3.2.0.201312181205-r" libraryDependencies += "com.googlecode.json-simple" % "json-simple" % "1.1.1" exclude("junit", "junit") diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 5e1826504d..de7d798473 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -22,7 +22,6 @@ import org.scalajs.core.tools.jsdep.DependencyResolver.DependencyFilter import org.scalajs.core.ir.ScalaJSVersions import org.scalajs.jsenv.{JSEnv, JSConsole} -import org.scalajs.jsenv.rhino.RhinoJSEnv import org.scalajs.jsenv.nodejs.{NodeJSEnv, JSDOMNodeJSEnv} import org.scalajs.jsenv.phantomjs.PhantomJSEnv @@ -62,42 +61,6 @@ object ScalaJSPlugin extends AutoPlugin { // Factory methods for JSEnvs - /** A non-deprecated version of `RhinoJSEnv` for internal use. */ - private[sbtplugin] - def RhinoJSEnvInternal(): Def.Initialize[Task[RhinoJSEnv]] = Def.task { - /* We take the semantics from the linker, since they depend on the stage. - * This way we are sure we agree on the semantics with the linker. - */ - import ScalaJSPluginInternal.{scalaJSLinker, scalaJSRequestsDOM} - val semantics = scalaJSLinker.value.semantics - val withDOM = scalaJSRequestsDOM.value - new RhinoJSEnv(semantics, withDOM, internal = ()) - } - - /** Creates a [[sbt.Def.Initialize Def.Initialize]] for a [[RhinoJSEnv]]. - * - * Use this to explicitly specify in your build that you would like to run - * with Rhino: - * - * {{{ - * Seq(Compile, Test).flatMap(c => inConfig(c)(jsEnv := RhinoJSEnv().value)) - * }}} - * - * The Rhino JS environment will support DOM through `env.js` if and only - * if `scalaJSRequestsDOM.value` evaluates to `true`. - * - * Note that the resulting [[sbt.Def.Setting Setting]] 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]]. - */ - @deprecated( - "The Rhino JS environment is being phased out. " + - "It will be removed in Scala.js 1.0.0. ", - "0.6.13") - def RhinoJSEnv(): Def.Initialize[Task[RhinoJSEnv]] = RhinoJSEnvInternal() - /** * Creates a [[sbt.Def.Initialize Def.Initialize]] for a NodeJSEnv. Use * this to explicitly specify in your build that you would like to run with Node.js: @@ -247,7 +210,7 @@ object ScalaJSPlugin extends AutoPlugin { "Linked Scala.js file. This is the result of fastOptJS or fullOptJS, " + "depending on the stage.", DTask) - /** Non-deprecated alias of `scalaJSUseRhino` for internal use. */ + /** Non-deprecated alias of `scalaJSLauncher` for internal use. */ private[sbtplugin] val scalaJSLauncherInternal = TaskKey[Attributed[VirtualJSFile]]( "scalaJSLauncher", "Code used to run. (Attributed with used class name)", DTask) @@ -263,19 +226,6 @@ object ScalaJSPlugin extends AutoPlugin { val scalaJSConsole = TaskKey[JSConsole]("scalaJSConsole", "The JS console used by the Scala.js runner/tester", DTask) - /** Non-deprecated alias of `scalaJSUseRhino` for internal use. */ - private[sbtplugin] val scalaJSUseRhinoInternal = SettingKey[Boolean]( - "scalaJSUseRhino", "Whether Rhino should be used", KeyRanks.Invisible) - - @deprecated( - "Will be removed in 1.0.0. " + - "Note that Rhino is not used by default anymore, " + - "so setting `scalaJSUseRhino` to `false` is redundant. " + - "To enable Rhino anew, use " + - "`Seq(Compile, Test).flatMap(c => inConfig(c)(jsEnv := RhinoJSEnv().value))`.", - "0.6.13") - val scalaJSUseRhino = scalaJSUseRhinoInternal - val jsEnv = TaskKey[JSEnv]("jsEnv", "A JVM-like environment where Scala.js files can be run and tested.", AMinusTask) @@ -388,7 +338,6 @@ object ScalaJSPlugin extends AutoPlugin { super.globalSettings ++ Seq( isScalaJSProject := false, scalaJSStage := Stage.FastOpt, - scalaJSUseRhinoInternal := false, scalaJSClearCacheStats := globalIRCache.clearStats() ) } diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 7719b601b0..139fb458e8 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -602,9 +602,7 @@ object ScalaJSPluginInternal { }, resolvedJSEnv := jsEnv.?.value.getOrElse { - if (scalaJSUseRhinoInternal.value) { - RhinoJSEnvInternal().value - } else if (scalaJSRequestsDOM.value) { + if (scalaJSRequestsDOM.value) { JSDOMNodeJSEnv().value } else { NodeJSEnv().value diff --git a/scala-test-suite/src/test/resources/2.11.5/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.11.5/BlacklistedTests.txt index bbcfe3e538..4cb46ffb0a 100644 --- a/scala-test-suite/src/test/resources/2.11.5/BlacklistedTests.txt +++ b/scala-test-suite/src/test/resources/2.11.5/BlacklistedTests.txt @@ -64,5 +64,4 @@ scala/collection/convert/MapWrapperTest.scala # Test fails only some times with # 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' -# and' 'set scalaJSUseRhino in Global := false' scala/collection/immutable/PagedSeqTest.scala diff --git a/scala-test-suite/src/test/resources/2.11.6/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.11.6/BlacklistedTests.txt index 72492f83b2..01f38969e4 100644 --- a/scala-test-suite/src/test/resources/2.11.6/BlacklistedTests.txt +++ b/scala-test-suite/src/test/resources/2.11.6/BlacklistedTests.txt @@ -72,5 +72,4 @@ scala/collection/convert/MapWrapperTest.scala # Test fails only some times with # 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' -# and' 'set scalaJSUseRhino in Global := false' scala/collection/immutable/PagedSeqTest.scala diff --git a/scala-test-suite/src/test/resources/2.11.7/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.11.7/BlacklistedTests.txt index 21fbc4a1d2..f47d1ebe6e 100644 --- a/scala-test-suite/src/test/resources/2.11.7/BlacklistedTests.txt +++ b/scala-test-suite/src/test/resources/2.11.7/BlacklistedTests.txt @@ -83,5 +83,4 @@ scala/collection/convert/MapWrapperTest.scala # Test fails only some times with # 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' -# and' 'set scalaJSUseRhino in Global := false' scala/collection/immutable/PagedSeqTest.scala \ No newline at end of file diff --git a/scala-test-suite/src/test/resources/2.11.8/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.11.8/BlacklistedTests.txt index 8c539ab5a4..9dda810713 100644 --- a/scala-test-suite/src/test/resources/2.11.8/BlacklistedTests.txt +++ b/scala-test-suite/src/test/resources/2.11.8/BlacklistedTests.txt @@ -88,5 +88,4 @@ scala/collection/convert/MapWrapperTest.scala # Test fails only some times with # 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' -# and' 'set scalaJSUseRhino in Global := false' scala/collection/immutable/PagedSeqTest.scala \ No newline at end of file diff --git a/scala-test-suite/src/test/resources/2.12.0/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.12.0/BlacklistedTests.txt index 5c1d89e5e9..d68c4fb325 100644 --- a/scala-test-suite/src/test/resources/2.12.0/BlacklistedTests.txt +++ b/scala-test-suite/src/test/resources/2.12.0/BlacklistedTests.txt @@ -106,7 +106,6 @@ scala/math/BigDecimalTest.scala # Test fails only some times with # 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' -# and' 'set scalaJSUseRhino in Global := false' scala/collection/immutable/PagedSeqTest.scala # Bugs diff --git a/scala-test-suite/src/test/resources/2.12.1/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.12.1/BlacklistedTests.txt index c7b1f08622..5140f481d5 100644 --- a/scala-test-suite/src/test/resources/2.12.1/BlacklistedTests.txt +++ b/scala-test-suite/src/test/resources/2.12.1/BlacklistedTests.txt @@ -110,7 +110,6 @@ scala/math/BigDecimalTest.scala # Test fails only some times with # 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' -# and' 'set scalaJSUseRhino in Global := false' scala/collection/immutable/PagedSeqTest.scala # Bugs diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala index 7947fb6d1d..28c4c5ce08 100644 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala +++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala @@ -33,7 +33,6 @@ object Platform { def areJSSymbolsSupported: Boolean = !js.isUndefined(js.Dynamic.global.Symbol) - def executingInRhino: Boolean = sysProp("rhino") def executingInNodeJS: Boolean = sysProp("nodejs") def executingInNodeJSOnJSDOM: Boolean = sysProp("nodejs.jsdom") def executingInPhantomJS: Boolean = sysProp("phantomjs") diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala index 15fe8dccfc..6e825b7c63 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala @@ -107,24 +107,20 @@ class SystemJSTest { val inNode = get("scalajs.nodejs") == "true" val inNodeWithJSDOM = get("scalajs.nodejs.jsdom") == "true" val inPhantomJS = get("scalajs.phantomjs") == "true" - val inRhino = get("scalajs.rhino") == "true" if (inBrowser) { assertFalse(js.isUndefined(js.Dynamic.global.window)) - assertFalse(inNode || inNodeWithJSDOM || inPhantomJS || inRhino) + assertFalse(inNode || inNodeWithJSDOM || inPhantomJS) } else if (inNode) { val process = js.Dynamic.global.process assertFalse(js.isUndefined(process)) - assertFalse(inBrowser || inNodeWithJSDOM || inPhantomJS || inRhino) + assertFalse(inBrowser || inNodeWithJSDOM || inPhantomJS) } else if (inNodeWithJSDOM) { val window = js.Dynamic.global.window assertFalse(js.isUndefined(window)) - assertFalse(inBrowser || inNode || inPhantomJS || inRhino) + assertFalse(inBrowser || inNode || inPhantomJS) } else if (inPhantomJS) { assertFalse(js.isUndefined(js.Dynamic.global.callPhantom)) - assertFalse(inBrowser || inNode || inNodeWithJSDOM || inRhino) - } else if (inRhino) { - assertFalse(js.isUndefined(js.Dynamic.global.Packages)) - assertFalse(inBrowser || inNode || inNodeWithJSDOM || inPhantomJS) + assertFalse(inBrowser || inNode || inNodeWithJSDOM) } else { fail("No known platform tag found.") } @@ -132,7 +128,6 @@ class SystemJSTest { assertEquals(inNode, Platform.executingInNodeJS) assertEquals(inNodeWithJSDOM, Platform.executingInNodeJSOnJSDOM) assertEquals(inPhantomJS, Platform.executingInPhantomJS) - assertEquals(inRhino, Platform.executingInRhino) val typedArrays = get("scalajs.typedarray") == "true" assertEquals(typedArrays, Platform.typedArrays) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DictionaryTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DictionaryTest.scala index 2f0eb28ff8..61cafaaa7f 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DictionaryTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DictionaryTest.scala @@ -34,10 +34,7 @@ class DictionaryTest { assertEquals("foobar", obj("bar")) } - // This doesn't work on Rhino due to lack of full strict mode support - #679 - @Test def should_behave_as_specified_when_deleting_a_non_configurable_property_issue_461_issue_679(): Unit = { - assumeFalse("Assumed not executing in Rhino", executingInRhino) val obj = js.Dictionary.empty[js.Any] js.Object.defineProperty(obj.asInstanceOf[js.Object], "nonconfig", js.Dynamic.literal(value = 4, writable = false).asInstanceOf[js.PropertyDescriptor]) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index 4177e0d6a8..a243f5b420 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -200,10 +200,6 @@ class ExportsTest { } @Test def readonly_properties(): Unit = { - assumeFalse( - "Assuming strict mode semantics, which are not honored by Rhino", - Platform.executingInRhino) - class Foo { @JSExport val foo: Int = 1 @@ -1393,9 +1389,6 @@ class ExportsTest { } @Test def top_level_export_write_val_var_causes_typeerror(): Unit = { - assumeFalse("Assuming strict mode, not supported by Rhino", - Platform.executingInRhino) - assertThrows(classOf[js.JavaScriptException], { jsPackage.toplevel.basicVal = 54 }) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala index 0a3657d086..a84787fe06 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala @@ -184,7 +184,6 @@ class MiscInteropTest { // Emitted classes @Test def should_have_a_meaningful_name_property(): Unit = { - assumeFalse("Assumed not executing in Rhino", executingInRhino) assumeFalse("Assumed not executing in FullOpt", isInFullOpt) def nameOf(obj: Any): js.Any = diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala index c6d9c69d60..87a0822411 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala @@ -598,10 +598,6 @@ class ScalaJSDefinedTest { } @Test def readonly_properties(): Unit = { - assumeFalse( - "Assuming strict mode semantics, which are not honored by Rhino", - Platform.executingInRhino) - // Named classes @ScalaJSDefined class Foo extends js.Object { diff --git a/test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala b/test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala index 2382bd18ab..8df9397ae8 100644 --- a/test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala +++ b/test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala @@ -20,7 +20,6 @@ object Platform { else throw new Exception("Unknown java.version format") } - def executingInRhino: Boolean = false def executingInNodeJS: Boolean = false def executingInNodeJSOnJSDOM: Boolean = false def executingInPhantomJS: Boolean = false diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/MathTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/MathTest.scala index 08b4763c79..0b3b2b735e 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/MathTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/MathTest.scala @@ -191,9 +191,6 @@ class MathTest { } @Test def rint_for_Double(): Unit = { - // js.Math.round() is buggy on Rhino - assumeFalse("Assumed not executing in Rhino", executingInRhino) - import Math.rint def isPosZero(x: Double): Boolean = diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala index aa849a4e70..d14a7792e4 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala @@ -29,8 +29,11 @@ object OutputMode { /** The default output mode. This is always the first element of [[All]] */ val Default = All.head + // TODO Remove this now that the support for Rhino is dead /** Legacy output mode where everything is stored in a global ScalaJS variable. - * This is suited to the special Rhino interpreter. + * This used to be necessary for the special Rhino interpreter. Since it + * has been removed, this output mode is completely useless, and will be + * removed as well. */ case object ECMAScript51Global extends OutputMode { val esLevel: ESLevel = ESLevel.ES5 diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index 47c870d258..bf2f8dbd8d 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -31,42 +31,6 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { import functionEmitter._ import jsGen._ - /** Desugars a Scala.js class specifically for use by the Rhino interpreter. - * - * @param tree The IR tree to emit to raw JavaScript - */ - def genClassDefForRhino(tree: LinkedClass)( - implicit globalKnowledge: GlobalKnowledge): js.Tree = { - - implicit val pos = tree.pos - val kind = tree.kind - - var reverseParts: List[js.Tree] = Nil - - reverseParts ::= genStaticMembers(tree) - if (kind == ClassKind.Interface) - reverseParts ::= genDefaultMethods(tree) - if (kind.isAnyScalaJSDefinedClass && tree.hasInstances) - reverseParts ::= genClassForRhino(tree) - if (needInstanceTests(tree)) { - reverseParts ::= genInstanceTests(tree) - reverseParts ::= genArrayInstanceTests(tree) - } - if (tree.hasRuntimeTypeInfo) - reverseParts ::= genTypeData(tree) - if (kind.isClass && tree.hasInstances && tree.hasRuntimeTypeInfo) - reverseParts ::= genSetTypeData(tree) - if (kind.hasModuleAccessor) - reverseParts ::= genModuleAccessor(tree) - if (!kind.isJSType) { - reverseParts ::= genCreateStaticFieldsOfScalaClass(tree) - reverseParts ::= genStaticInitialization(tree) - } - reverseParts ::= genClassExports(tree) - - js.Block(reverseParts.reverse) - } - def genStaticMembers(tree: LinkedClass)( implicit globalKnowledge: GlobalKnowledge): js.Tree = { val className = tree.name.name @@ -83,18 +47,6 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { js.Block(defaultMethodDefs)(tree.pos) } - private def genClassForRhino(tree: LinkedClass)( - implicit globalKnowledge: GlobalKnowledge): js.Tree = { - - val className = tree.name.name - val ctor = genConstructor(tree) - val memberDefs = - tree.memberMethods.map(m => genMethod(className, m.tree)) - val exportedDefs = genExportedMembers(tree) - - buildClass(tree, ctor, memberDefs, exportedDefs) - } - def buildClass(tree: LinkedClass, ctor: js.Tree, memberDefs: List[js.Tree], exportedDefs: js.Tree)( implicit globalKnowledge: GlobalKnowledge): js.Tree = { diff --git 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 index ac6c4286a5..e79d28d669 100644 --- 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 @@ -369,32 +369,6 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, emitNextLine(0) } - // Private API for Rhino - - private[scalajs] object rhinoAPI { // scalastyle:ignore - /** A GlobalKnowledge that never tracks dependencies. This can be used in - * cases where we do not use any cache, which is what `genClassDef()` in - * this class does. - */ - private val globalKnowledge: GlobalKnowledge = - new knowledgeGuardian.KnowledgeAccessor {} - - def initialize(linkingUnit: LinkingUnit): Unit = - startRun(linkingUnit) - - def getHeaderFile(): org.scalajs.core.tools.io.VirtualJSFile = - CoreJSLibs.lib(semantics, outputMode, moduleKind) - - def genClassDef(linkedClass: LinkedClass): js.Tree = - classEmitter.genClassDefForRhino(linkedClass)(globalKnowledge) - - def genModuleInitializers(linkingUnit: LinkingUnit): js.Tree = { - val genModuleInitializers = - linkingUnit.moduleInitializers.map(classEmitter.genModuleInitializer(_)) - js.Block(genModuleInitializers)(Position.NoPosition) - } - } - // Caching private final class ClassCache extends knowledgeGuardian.KnowledgeAccessor { @@ -485,8 +459,7 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, } } -// The only reason this is not private is that Rhino needs it -private[scalajs] object Emitter { +private object Emitter { private final class DesugaredClassCache { val constructor = new OneTimeCache[js.Tree] val exportedMembers = new OneTimeCache[js.Tree] @@ -507,8 +480,7 @@ private[scalajs] object Emitter { } } - // The only reason this is not private is that Rhino needs it - private[scalajs] def symbolRequirements(semantics: Semantics, + private def symbolRequirements(semantics: Semantics, esLevel: ESLevel): SymbolRequirement = { import semantics._ import CheckedBehavior._ diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala index 8ae3e3487b..ec9695e0ae 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala @@ -272,8 +272,9 @@ private[emitter] final class JSGen(val semantics: Semantics, item match { case StringLiteral(name) if internalOptions.optimizeBracketSelects && irt.isValidIdentifier(name) && name != "eval" => - /* We exclude "eval" because Rhino does not respect the strict mode - * specificities of eval(). + /* We exclude "eval" because we do not want to rely too much on the + * strict mode peculiarities of eval(), so that we can keep running + * on VMs that do not support strict mode. */ DotSelect(qual, Ident(name)) case _ => From 3c21f4831d4f44383b8d75dbb1a34962dd935c90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 22 Mar 2017 15:06:30 +0100 Subject: [PATCH 0166/2665] Remove javascript.Printers.ReverseSourceMapPrinter. Although it is a public API, it was only ever used by the Rhino JS env. --- .../core/tools/javascript/Printers.scala | 57 ------------------- 1 file changed, 57 deletions(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala index 9aa744982e..bc9b4bc9d2 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala @@ -628,61 +628,4 @@ object Printers { } } - /** Prints a tree to find original locations based on line numbers. - * @param untilLine last 0-based line the positions should be recorded for - */ - class ReverseSourceMapPrinter(untilLine: Int) - extends JSTreePrinter(ReverseSourceMapPrinter.NullWriter) { - - private val positions = Array.fill(untilLine+1)(NoPosition) - private var curLine = 0 - - private val doneBreak = new Breaks - - def apply(x: Int): Position = positions(x) - - def reverseSourceMap(tree: Tree): Unit = doneBreak.breakable { - printTopLevelTree(tree) - } - - override def printTree(tree: Tree, isStat: Boolean): Unit = { - if (positions(curLine).isEmpty) - positions(curLine) = tree.pos - - super.printTree(tree, isStat) - } - - override protected def print(ident: Ident): Unit = { - if (positions(curLine).isEmpty) - positions(curLine) = ident.pos - - super.print(ident) - } - - override def println(): Unit = { - super.println() - curLine += 1 - if (curLine > untilLine) - doneBreak.break() - } - - override protected def print(s: String): Unit = { - // assume no EOL char in s, and assume s only has ASCII characters - // therefore, we fully ignore the string - } - - override protected def print(c: Int): Unit = { - // assume c is not EOL, and assume c is an ASCII characters - // therefore, we fully ignore the char - } - } - - private object ReverseSourceMapPrinter { - private object NullWriter extends Writer { - def close(): Unit = () - def flush(): Unit = () - def write(buf: Array[Char], off: Int, len: Int): Unit = () - } - } - } From 0d5eadb9e32cae6ee3a8fe270c6fc51f002e0eb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 22 Mar 2017 15:26:43 +0100 Subject: [PATCH 0167/2665] Remove the ECMAScript51Global output mode. This output mode was some obscure legacy, underperforming and leaking output mode, whose only purpose was to support the Rhino JS env. This commit also fixes #2686, by (de-)construction. --- .../scala/scalajs/runtime/StackTrace.scala | 14 +++------ tools/scalajsenv.js | 27 +---------------- .../tools/linker/backend/OutputMode.scala | 13 +-------- .../linker/backend/emitter/ClassEmitter.scala | 21 ++++++-------- .../linker/backend/emitter/CoreJSLibs.scala | 5 +--- .../linker/backend/emitter/Emitter.scala | 16 ++-------- .../backend/emitter/FunctionEmitter.scala | 8 ++--- .../tools/linker/backend/emitter/JSGen.scala | 29 ++++--------------- 8 files changed, 28 insertions(+), 105 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala b/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala index 750961b95a..a5b684f466 100644 --- a/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala +++ b/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala @@ -163,15 +163,9 @@ object StackTrace { * \$c_.prototype. * \$c_. * \$s___ + * \$f___ * \$m_ * }}} - * and their ECMAScript51Global equivalents: - * {{{ - * ScalaJS.c..prototype. - * ScalaJS.c.. - * ScalaJS.s.__ - * ScalaJS.m. - * }}} * all of them optionally prefixed by `Object.` or `[object Object].`. * * When the function name is none of those, the pair @@ -180,9 +174,9 @@ object StackTrace { * display the function name. */ private def extractClassMethod(functionName: String): (String, String) = { - val PatC = """^(?:Object\.|\[object Object\]\.)?(?:ScalaJS\.c\.|\$c_)([^\.]+)(?:\.prototype)?\.([^\.]+)$""".re - val PatS = """^(?:Object\.|\[object Object\]\.)?(?:ScalaJS\.(?:s|f)\.|\$(?:s|f)_)((?:_[^_]|[^_])+)__([^\.]+)$""".re - val PatM = """^(?:Object\.|\[object Object\]\.)?(?:ScalaJS\.m\.|\$m_)([^\.]+)$""".re + val PatC = """^(?:Object\.|\[object Object\]\.)?\$c_([^\.]+)(?:\.prototype)?\.([^\.]+)$""".re + val PatS = """^(?:Object\.|\[object Object\]\.)?\$[sf]_((?:_[^_]|[^_])+)__([^\.]+)$""".re + val PatM = """^(?:Object\.|\[object Object\]\.)?\$m_([^\.]+)$""".re var isModule = false var mtch = PatC.exec(functionName) diff --git a/tools/scalajsenv.js b/tools/scalajsenv.js index 5345ba8e68..9599647ac8 100644 --- a/tools/scalajsenv.js +++ b/tools/scalajsenv.js @@ -7,10 +7,6 @@ * The top-level Scala.js environment * * ---------------------------------- */ -//!if outputMode == ECMAScript51Global -var ScalaJS = {}; -//!endif - // Get the environment info ScalaJS.env = (typeof __ScalaJSEnv === "object" && __ScalaJSEnv) ? __ScalaJSEnv : {}; @@ -131,34 +127,13 @@ ScalaJS.clz32 = ScalaJS.g["Math"]["clz32"] || (function(i) { }); //!endif -// Other fields -//!if outputMode == ECMAScript51Global -ScalaJS.d = {}; // Data for types -ScalaJS.a = {}; // Scala.js-defined JS class value accessors -ScalaJS.b = {}; // Scala.js-defined JS class value fields -ScalaJS.c = {}; // Scala.js constructors -ScalaJS.h = {}; // Inheritable constructors (without initialization code) -ScalaJS.s = {}; // Static methods -ScalaJS.t = {}; // Static fields -ScalaJS.f = {}; // Default methods -ScalaJS.n = {}; // Module instances -ScalaJS.m = {}; // Module accessors -ScalaJS.is = {}; // isInstanceOf methods -ScalaJS.isArrayOf = {}; // isInstanceOfArrayOf methods -//!if asInstanceOfs != Unchecked -ScalaJS.as = {}; // asInstanceOf methods -ScalaJS.asArrayOf = {}; // asInstanceOfArrayOf methods -//!endif -ScalaJS.lastIDHash = 0; // last value attributed to an id hash code -ScalaJS.idHashCodeMap = ScalaJS.g["WeakMap"] ? new ScalaJS.g["WeakMap"]() : null; -//!else +// identityHashCode support let $lastIDHash = 0; // last value attributed to an id hash code //!if outputMode == ECMAScript6 const $idHashCodeMap = new ScalaJS.g["WeakMap"](); //!else const $idHashCodeMap = ScalaJS.g["WeakMap"] ? new ScalaJS.g["WeakMap"]() : null; //!endif -//!endif // Core mechanism diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala index d14a7792e4..8f9f7acd5f 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala @@ -23,22 +23,11 @@ object OutputMode { */ val All = List( ECMAScript51Isolated, - ECMAScript6, - ECMAScript51Global) + ECMAScript6) /** The default output mode. This is always the first element of [[All]] */ val Default = All.head - // TODO Remove this now that the support for Rhino is dead - /** Legacy output mode where everything is stored in a global ScalaJS variable. - * This used to be necessary for the special Rhino interpreter. Since it - * has been removed, this output mode is completely useless, and will be - * removed as well. - */ - case object ECMAScript51Global extends OutputMode { - val esLevel: ESLevel = ESLevel.ES5 - } - /** Modern output mode compliant with ECMAScript 5.1 in a function scope. * This is the default output mode used by fastOpt and fullOpt. * The output must be enclosed in an anonymous function isolating the code diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index bf2f8dbd8d..989c27c359 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -55,7 +55,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { js.Block(ctor +: memberDefs :+ exportedDefs)(tree.pos) val entireClassDef = outputMode match { - case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => + case OutputMode.ECMAScript51Isolated => allDefsBlock case OutputMode.ECMAScript6 => @@ -131,7 +131,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { s"Class ${tree.name.name} is missing a parent class") outputMode match { - case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => + case OutputMode.ECMAScript51Isolated => genES5Constructor(tree) case OutputMode.ECMAScript6 => @@ -326,7 +326,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { case methodName => outputMode match { - case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => + case OutputMode.ECMAScript51Isolated => genAddToObject(className, encodeClassVar(className), methodName, methodFun) @@ -337,7 +337,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { } } else { outputMode match { - case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => + case OutputMode.ECMAScript51Isolated => genAddToPrototype(className, method.name, methodFun) case OutputMode.ECMAScript6 => @@ -374,7 +374,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { def genProperty(className: String, property: PropertyDef)( implicit globalKnowledge: GlobalKnowledge): js.Tree = { outputMode match { - case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => + case OutputMode.ECMAScript51Isolated => genPropertyES5(className, property) case OutputMode.ECMAScript6 => genPropertyES6(className, property) @@ -724,7 +724,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val (isInstanceFun, isArrayOfFun) = { if (isObjectClass) { - /* Object has special ScalaJS.is.O *and* ScalaJS.isArrayOf.O. */ + /* Object has special $is_O *and* $isArrayOf_O. */ (envField("is", className), envField("isArrayOf", className)) } else if (isHijackedBoxedClass) { /* Hijacked boxed classes have a special isInstanceOf test. */ @@ -734,7 +734,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { }), js.Undefined()) } else if (isAncestorOfHijackedClass || className == StringClass) { /* java.lang.String and ancestors of hijacked classes have a normal - * ScalaJS.is.pack_Class test but with a non-standard behavior. */ + * $is_pack_Class test but with a non-standard behavior. */ (envField("is", className), js.Undefined()) } else if (isJSType) { /* Native JS classes have an instanceof operator-based isInstanceOf @@ -1052,12 +1052,9 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { keepFunctionExpression: Boolean = false)( implicit pos: Position): js.Tree = { val globalVar = envField(field, subField, origName) - def globalVarIdent = globalVar.asInstanceOf[js.VarRef].ident + val globalVarIdent = globalVar.ident outputMode match { - case OutputMode.ECMAScript51Global => - js.Assign(globalVar, value) - case OutputMode.ECMAScript51Isolated => value match { case js.Function(args, body) => @@ -1107,7 +1104,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { implicit pos: Position): (js.Tree, js.Tree, js.StringLiteral) = { val parts = qualName.split("\\.") val statements = List.newBuilder[js.Tree] - var namespace = envField("e") + var namespace: js.Tree = envField("e") for (i <- 0 until parts.length-1) { namespace = genBracketSelect(namespace, js.StringLiteral(parts(i))) statements += diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala index f86dcfe8c0..0af4db160d 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala @@ -123,9 +123,6 @@ private[backend] object CoreJSLibs { "{{LINKER_VERSION}}", ScalaJSVersions.current) val content1 = outputMode match { - case OutputMode.ECMAScript51Global => - content - case OutputMode.ECMAScript51Isolated | OutputMode.ECMAScript6 => content .replaceAll("ScalaJS\\.d\\.", "\\$d_") @@ -143,7 +140,7 @@ private[backend] object CoreJSLibs { } outputMode match { - case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => + case OutputMode.ECMAScript51Isolated => content1 .replaceAll(raw"\b(let|const)\b", "var") diff --git 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 index e79d28d669..39fed9c51c 100644 --- 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 @@ -32,10 +32,6 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, import Emitter._ - require( - outputMode != OutputMode.ECMAScript51Global || moduleKind == ModuleKind.NoModule, - "The ECMAScript51Global output mode is not compatible with modules") - def this(semantics: Semantics, outputMode: OutputMode, moduleKind: ModuleKind) = { this(semantics, outputMode, moduleKind, InternalOptions()) @@ -62,16 +58,8 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, private val needsIIFEWrapper = { moduleKind match { - case ModuleKind.NoModule => - outputMode match { - case OutputMode.ECMAScript51Global => - false - case OutputMode.ECMAScript51Isolated | OutputMode.ECMAScript6 => - true - } - - case ModuleKind.CommonJSModule => - false + case ModuleKind.NoModule => true + case ModuleKind.CommonJSModule => false } } diff --git 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 index 854c460241..06b729cf2f 100644 --- 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 @@ -305,7 +305,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { else Return(body) val translateRestParam = outputMode match { - case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => + case OutputMode.ECMAScript51Isolated => params.nonEmpty && params.last.rest case _ => false @@ -521,7 +521,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { val superCtorCall = { outputMode match { - case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => + case OutputMode.ECMAScript51Isolated => val superCtor = genRawJSClassConstructor( globalKnowledge.getSuperClassOfJSClass(enclosingClassName)) @@ -1166,7 +1166,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { */ def extractLet(inner: Lhs => js.Tree): js.Tree = { outputMode match { - case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => + case OutputMode.ECMAScript51Isolated => inner(lhs) case OutputMode.ECMAScript6 => lhs match { @@ -2211,7 +2211,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case ClassType(className) => envField("d", className) case ArrayType(base, dims) => - (1 to dims).foldLeft(envField("d", base)) { (prev, _) => + (1 to dims).foldLeft[js.Tree](envField("d", base)) { (prev, _) => js.Apply(js.DotSelect(prev, js.Ident("getArrayOf")), Nil) } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala index ec9695e0ae..b9aab6f417 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala @@ -60,7 +60,7 @@ private[emitter] final class JSGen(val semantics: Semantics, def genLet(name: Ident, mutable: Boolean, rhs: Tree)( implicit pos: Position): LocalDef = { outputMode match { - case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => + case OutputMode.ECMAScript51Isolated => VarDef(name, Some(rhs)) case OutputMode.ECMAScript6 => Let(name, mutable, Some(rhs)) @@ -69,7 +69,7 @@ private[emitter] final class JSGen(val semantics: Semantics, def genEmptyMutableLet(name: Ident)(implicit pos: Position): LocalDef = { outputMode match { - case OutputMode.ECMAScript51Global | OutputMode.ECMAScript51Isolated => + case OutputMode.ECMAScript51Isolated => VarDef(name, rhs = None) case OutputMode.ECMAScript6 => Let(name, mutable = true, rhs = None) @@ -235,29 +235,12 @@ private[emitter] final class JSGen(val semantics: Semantics, } def envField(field: String, subField: String, origName: Option[String] = None)( - implicit pos: Position): Tree = { - import TreeDSL._ - - outputMode match { - case OutputMode.ECMAScript51Global => - envField(field) DOT Ident(subField, origName) - - case OutputMode.ECMAScript51Isolated | OutputMode.ECMAScript6 => - VarRef(Ident("$" + field + "_" + subField, origName)) - } + implicit pos: Position): VarRef = { + VarRef(Ident("$" + field + "_" + subField, origName)) } - def envField(field: String)(implicit pos: Position): Tree = { - import TreeDSL._ - - outputMode match { - case OutputMode.ECMAScript51Global => - VarRef(Ident(ScalaJSEnvironmentName)) DOT field - - case OutputMode.ECMAScript51Isolated | OutputMode.ECMAScript6 => - VarRef(Ident("$" + field)) - } - } + def envField(field: String)(implicit pos: Position): VarRef = + VarRef(Ident("$" + field)) def genPropSelect(qual: Tree, item: PropertyName)( implicit pos: Position): Tree = { From 6e361886b8e877178c3b488bddc2abb1665f16bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 22 Mar 2017 16:07:09 +0100 Subject: [PATCH 0168/2665] Rewrite scalajsenv.js to use $-vars instead of `ScalaJS.xyz`. The `ScalaJS.xyz` scheme was necessary for the `ECMAScript51Global` output mode, which was removed. We can now write `scalajsenv.js` directly with `$`-prefixed "top-level" variables and functions, in the style of the two remaining output modes. --- tools/scalajsenv.js | 520 +++++++++--------- .../linker/backend/emitter/CoreJSLibs.scala | 21 +- 2 files changed, 262 insertions(+), 279 deletions(-) diff --git a/tools/scalajsenv.js b/tools/scalajsenv.js index 9599647ac8..d99d43b847 100644 --- a/tools/scalajsenv.js +++ b/tools/scalajsenv.js @@ -8,31 +8,31 @@ * ---------------------------------- */ // Get the environment info -ScalaJS.env = (typeof __ScalaJSEnv === "object" && __ScalaJSEnv) ? __ScalaJSEnv : {}; +const $env = (typeof __ScalaJSEnv === "object" && __ScalaJSEnv) ? __ScalaJSEnv : {}; // Global scope -ScalaJS.g = - (typeof ScalaJS.env["global"] === "object" && ScalaJS.env["global"]) - ? ScalaJS.env["global"] +const $g = + (typeof $env["global"] === "object" && $env["global"]) + ? $env["global"] : ((typeof global === "object" && global && global["Object"] === Object) ? global : this); -ScalaJS.env["global"] = ScalaJS.g; +$env["global"] = $g; // Where to send exports //!if moduleKind == CommonJSModule -ScalaJS.e = exports; +const $e = exports; //!else -ScalaJS.e = - (typeof ScalaJS.env["exportsNamespace"] === "object" && ScalaJS.env["exportsNamespace"]) - ? ScalaJS.env["exportsNamespace"] : ScalaJS.g; +const $e = + (typeof $env["exportsNamespace"] === "object" && $env["exportsNamespace"]) + ? $env["exportsNamespace"] : $g; //!endif -ScalaJS.env["exportsNamespace"] = ScalaJS.e; +$env["exportsNamespace"] = $e; // Freeze the environment info -ScalaJS.g["Object"]["freeze"](ScalaJS.env); +$g["Object"]["freeze"]($env); // Linking info - must be in sync with scala.scalajs.runtime.LinkingInfo -ScalaJS.linkingInfo = { - "envInfo": ScalaJS.env, +const $linkingInfo = { + "envInfo": $env, "semantics": { //!if asInstanceOfs == Compliant "asInstanceOfs": 0, @@ -79,17 +79,17 @@ ScalaJS.linkingInfo = { //!endif "linkerVersion": "{{LINKER_VERSION}}" }; -ScalaJS.g["Object"]["freeze"](ScalaJS.linkingInfo); -ScalaJS.g["Object"]["freeze"](ScalaJS.linkingInfo["semantics"]); +$g["Object"]["freeze"]($linkingInfo); +$g["Object"]["freeze"]($linkingInfo["semantics"]); // Snapshots of builtins and polyfills //!if outputMode == ECMAScript6 -ScalaJS.imul = ScalaJS.g["Math"]["imul"]; -ScalaJS.fround = ScalaJS.g["Math"]["fround"]; -ScalaJS.clz32 = ScalaJS.g["Math"]["clz32"]; +const $imul = $g["Math"]["imul"]; +const $fround = $g["Math"]["fround"]; +const $clz32 = $g["Math"]["clz32"]; //!else -ScalaJS.imul = ScalaJS.g["Math"]["imul"] || (function(a, b) { +const $imul = $g["Math"]["imul"] || (function(a, b) { // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul const ah = (a >>> 16) & 0xffff; const al = a & 0xffff; @@ -100,14 +100,14 @@ ScalaJS.imul = ScalaJS.g["Math"]["imul"] || (function(a, b) { return ((al * bl) + (((ah * bl + al * bh) << 16) >>> 0) | 0); }); -ScalaJS.fround = ScalaJS.g["Math"]["fround"] || +const $fround = $g["Math"]["fround"] || //!if floats == Strict - (ScalaJS.g["Float32Array"] ? (function(v) { - const array = new ScalaJS.g["Float32Array"](1); + ($g["Float32Array"] ? (function(v) { + const array = new $g["Float32Array"](1); array[0] = v; return array[0]; }) : (function(v) { - return ScalaJS.m.sjsr_package$().froundPolyfill__D__D(+v); + return $m_sjsr_package$().froundPolyfill__D__D(+v); })); //!else (function(v) { @@ -115,7 +115,7 @@ ScalaJS.fround = ScalaJS.g["Math"]["fround"] || }); //!endif -ScalaJS.clz32 = ScalaJS.g["Math"]["clz32"] || (function(i) { +const $clz32 = $g["Math"]["clz32"] || (function(i) { // See Hacker's Delight, Section 5-3 if (i === 0) return 32; let r = 1; @@ -130,14 +130,14 @@ ScalaJS.clz32 = ScalaJS.g["Math"]["clz32"] || (function(i) { // identityHashCode support let $lastIDHash = 0; // last value attributed to an id hash code //!if outputMode == ECMAScript6 -const $idHashCodeMap = new ScalaJS.g["WeakMap"](); +const $idHashCodeMap = new $g["WeakMap"](); //!else -const $idHashCodeMap = ScalaJS.g["WeakMap"] ? new ScalaJS.g["WeakMap"]() : null; +const $idHashCodeMap = $g["WeakMap"] ? new $g["WeakMap"]() : null; //!endif // Core mechanism -ScalaJS.makeIsArrayOfPrimitive = function(primitiveData) { +function $makeIsArrayOfPrimitive(primitiveData) { return function(obj, depth) { return !!(obj && obj.$classData && (obj.$classData.arrayDepth === depth) && @@ -146,12 +146,12 @@ ScalaJS.makeIsArrayOfPrimitive = function(primitiveData) { }; //!if asInstanceOfs != Unchecked -ScalaJS.makeAsArrayOfPrimitive = function(isInstanceOfFunction, arrayEncodedName) { +function $makeAsArrayOfPrimitive(isInstanceOfFunction, arrayEncodedName) { return function(obj, depth) { if (isInstanceOfFunction(obj, depth) || (obj === null)) return obj; else - ScalaJS.throwArrayCastException(obj, arrayEncodedName, depth); + $throwArrayCastException(obj, arrayEncodedName, depth); } }; //!endif @@ -165,62 +165,62 @@ ScalaJS.makeAsArrayOfPrimitive = function(isInstanceOfFunction, arrayEncodedName * but we must still get hold of a string of that name for runtime * reflection. */ -ScalaJS.propertyName = function(obj) { +function $propertyName(obj) { for (const prop in obj) return prop; }; // Runtime functions -ScalaJS.isScalaJSObject = function(obj) { +function $isScalaJSObject(obj) { return !!(obj && obj.$classData); }; //!if asInstanceOfs != Unchecked -ScalaJS.throwClassCastException = function(instance, classFullName) { +function $throwClassCastException(instance, classFullName) { //!if asInstanceOfs == Compliant - throw new ScalaJS.c.jl_ClassCastException().init___T( + throw new $c_jl_ClassCastException().init___T( instance + " is not an instance of " + classFullName); //!else - throw new ScalaJS.c.sjsr_UndefinedBehaviorError().init___jl_Throwable( - new ScalaJS.c.jl_ClassCastException().init___T( + throw new $c_sjsr_UndefinedBehaviorError().init___jl_Throwable( + new $c_jl_ClassCastException().init___T( instance + " is not an instance of " + classFullName)); //!endif }; -ScalaJS.throwArrayCastException = function(instance, classArrayEncodedName, depth) { +function $throwArrayCastException(instance, classArrayEncodedName, depth) { for (; depth; --depth) classArrayEncodedName = "[" + classArrayEncodedName; - ScalaJS.throwClassCastException(instance, classArrayEncodedName); + $throwClassCastException(instance, classArrayEncodedName); }; //!endif //!if arrayIndexOutOfBounds != Unchecked -ScalaJS.throwArrayIndexOutOfBoundsException = function(i) { +function $throwArrayIndexOutOfBoundsException(i) { const msg = (i === null) ? null : ("" + i); //!if arrayIndexOutOfBounds == Compliant - throw new ScalaJS.c.jl_ArrayIndexOutOfBoundsException().init___T(msg); + throw new $c_jl_ArrayIndexOutOfBoundsException().init___T(msg); //!else - throw new ScalaJS.c.sjsr_UndefinedBehaviorError().init___jl_Throwable( - new ScalaJS.c.jl_ArrayIndexOutOfBoundsException().init___T(msg)); + throw new $c_sjsr_UndefinedBehaviorError().init___jl_Throwable( + new $c_jl_ArrayIndexOutOfBoundsException().init___T(msg)); //!endif }; //!endif -ScalaJS.noIsInstance = function(instance) { - throw new ScalaJS.g["TypeError"]( +function $noIsInstance(instance) { + throw new $g["TypeError"]( "Cannot call isInstance() on a Class representing a raw JS trait/object"); }; -ScalaJS.makeNativeArrayWrapper = function(arrayClassData, nativeArray) { +function $makeNativeArrayWrapper(arrayClassData, nativeArray) { return new arrayClassData.constr(nativeArray); }; -ScalaJS.newArrayObject = function(arrayClassData, lengths) { - return ScalaJS.newArrayObjectInternal(arrayClassData, lengths, 0); +function $newArrayObject(arrayClassData, lengths) { + return $newArrayObjectInternal(arrayClassData, lengths, 0); }; -ScalaJS.newArrayObjectInternal = function(arrayClassData, lengths, lengthIndex) { +function $newArrayObjectInternal(arrayClassData, lengths, lengthIndex) { const result = new arrayClassData.constr(lengths[lengthIndex]); if (lengthIndex < lengths.length-1) { @@ -228,7 +228,7 @@ ScalaJS.newArrayObjectInternal = function(arrayClassData, lengths, lengthIndex) const subLengthIndex = lengthIndex+1; const underlying = result.u; for (let i = 0; i < underlying.length; i++) { - underlying[i] = ScalaJS.newArrayObjectInternal( + underlying[i] = $newArrayObjectInternal( subArrayClassData, lengths, subLengthIndex); } } @@ -236,84 +236,84 @@ ScalaJS.newArrayObjectInternal = function(arrayClassData, lengths, lengthIndex) return result; }; -ScalaJS.objectToString = function(instance) { +function $objectToString(instance) { if (instance === void 0) return "undefined"; else return instance.toString(); }; -ScalaJS.objectGetClass = function(instance) { +function $objectGetClass(instance) { switch (typeof instance) { case "string": - return ScalaJS.d.T.getClassOf(); + return $d_T.getClassOf(); case "number": { const v = instance | 0; if (v === instance) { // is the value integral? - if (ScalaJS.isByte(v)) - return ScalaJS.d.jl_Byte.getClassOf(); - else if (ScalaJS.isShort(v)) - return ScalaJS.d.jl_Short.getClassOf(); + if ($isByte(v)) + return $d_jl_Byte.getClassOf(); + else if ($isShort(v)) + return $d_jl_Short.getClassOf(); else - return ScalaJS.d.jl_Integer.getClassOf(); + return $d_jl_Integer.getClassOf(); } else { - if (ScalaJS.isFloat(instance)) - return ScalaJS.d.jl_Float.getClassOf(); + if ($isFloat(instance)) + return $d_jl_Float.getClassOf(); else - return ScalaJS.d.jl_Double.getClassOf(); + return $d_jl_Double.getClassOf(); } } case "boolean": - return ScalaJS.d.jl_Boolean.getClassOf(); + return $d_jl_Boolean.getClassOf(); case "undefined": - return ScalaJS.d.sr_BoxedUnit.getClassOf(); + return $d_sr_BoxedUnit.getClassOf(); default: if (instance === null) return instance.getClass__jl_Class(); - else if (ScalaJS.is.sjsr_RuntimeLong(instance)) - return ScalaJS.d.jl_Long.getClassOf(); - else if (ScalaJS.isScalaJSObject(instance)) + else if ($is_sjsr_RuntimeLong(instance)) + return $d_jl_Long.getClassOf(); + else if ($isScalaJSObject(instance)) return instance.$classData.getClassOf(); else return null; // Exception? } }; -ScalaJS.objectClone = function(instance) { - if (ScalaJS.isScalaJSObject(instance) || (instance === null)) +function $objectClone(instance) { + if ($isScalaJSObject(instance) || (instance === null)) return instance.clone__O(); else - throw new ScalaJS.c.jl_CloneNotSupportedException().init___(); + throw new $c_jl_CloneNotSupportedException().init___(); }; -ScalaJS.objectNotify = function(instance) { +function $objectNotify(instance) { // final and no-op in java.lang.Object if (instance === null) instance.notify__V(); }; -ScalaJS.objectNotifyAll = function(instance) { +function $objectNotifyAll(instance) { // final and no-op in java.lang.Object if (instance === null) instance.notifyAll__V(); }; -ScalaJS.objectFinalize = function(instance) { - if (ScalaJS.isScalaJSObject(instance) || (instance === null)) +function $objectFinalize(instance) { + if ($isScalaJSObject(instance) || (instance === null)) instance.finalize__V(); // else no-op }; -ScalaJS.objectEquals = function(instance, rhs) { - if (ScalaJS.isScalaJSObject(instance) || (instance === null)) +function $objectEquals(instance, rhs) { + if ($isScalaJSObject(instance) || (instance === null)) return instance.equals__O__Z(rhs); else if (typeof instance === "number") - return typeof rhs === "number" && ScalaJS.numberEquals(instance, rhs); + return typeof rhs === "number" && $numberEquals(instance, rhs); else return instance === rhs; }; -ScalaJS.numberEquals = function(lhs, rhs) { +function $numberEquals(lhs, rhs) { return (lhs === rhs) ? ( // 0.0.equals(-0.0) must be false lhs !== 0 || 1/lhs === 1/rhs @@ -323,43 +323,43 @@ ScalaJS.numberEquals = function(lhs, rhs) { ); }; -ScalaJS.objectHashCode = function(instance) { +function $objectHashCode(instance) { switch (typeof instance) { case "string": - return ScalaJS.m.sjsr_RuntimeString$().hashCode__T__I(instance); + return $m_sjsr_RuntimeString$().hashCode__T__I(instance); case "number": - return ScalaJS.m.sjsr_Bits$().numberHashCode__D__I(instance); + return $m_sjsr_Bits$().numberHashCode__D__I(instance); case "boolean": return instance ? 1231 : 1237; case "undefined": return 0; default: - if (ScalaJS.isScalaJSObject(instance) || instance === null) + if ($isScalaJSObject(instance) || instance === null) return instance.hashCode__I(); //!if outputMode != ECMAScript6 - else if (ScalaJS.idHashCodeMap === null) + else if ($idHashCodeMap === null) return 42; //!endif else - return ScalaJS.systemIdentityHashCode(instance); + return $systemIdentityHashCode(instance); } }; -ScalaJS.comparableCompareTo = function(instance, rhs) { +function $comparableCompareTo(instance, rhs) { switch (typeof instance) { case "string": //!if asInstanceOfs != Unchecked - ScalaJS.as.T(rhs); + $as_T(rhs); //!endif return instance === rhs ? 0 : (instance < rhs ? -1 : 1); case "number": //!if asInstanceOfs != Unchecked - ScalaJS.as.jl_Number(rhs); + $as_jl_Number(rhs); //!endif - return ScalaJS.m.jl_Double$().compare__D__D__I(instance, rhs); + return $m_jl_Double$().compare__D__D__I(instance, rhs); case "boolean": //!if asInstanceOfs != Unchecked - ScalaJS.asBoolean(rhs); + $asBoolean(rhs); //!endif return instance - rhs; // yes, this gives the right result default: @@ -367,10 +367,10 @@ ScalaJS.comparableCompareTo = function(instance, rhs) { } }; -ScalaJS.charSequenceLength = function(instance) { +function $charSequenceLength(instance) { if (typeof(instance) === "string") //!if asInstanceOfs != Unchecked - return ScalaJS.uI(instance["length"]); + return $uI(instance["length"]); //!else return instance["length"] | 0; //!endif @@ -378,10 +378,10 @@ ScalaJS.charSequenceLength = function(instance) { return instance.length__I(); }; -ScalaJS.charSequenceCharAt = function(instance, index) { +function $charSequenceCharAt(instance, index) { if (typeof(instance) === "string") //!if asInstanceOfs != Unchecked - return ScalaJS.uI(instance["charCodeAt"](index)) & 0xffff; + return $uI(instance["charCodeAt"](index)) & 0xffff; //!else return instance["charCodeAt"](index) & 0xffff; //!endif @@ -389,10 +389,10 @@ ScalaJS.charSequenceCharAt = function(instance, index) { return instance.charAt__I__C(index); }; -ScalaJS.charSequenceSubSequence = function(instance, start, end) { +function $charSequenceSubSequence(instance, start, end) { if (typeof(instance) === "string") //!if asInstanceOfs != Unchecked - return ScalaJS.as.T(instance["substring"](start, end)); + return $as_T(instance["substring"](start, end)); //!else return instance["substring"](start, end); //!endif @@ -400,54 +400,54 @@ ScalaJS.charSequenceSubSequence = function(instance, start, end) { return instance.subSequence__I__I__jl_CharSequence(start, end); }; -ScalaJS.booleanBooleanValue = function(instance) { +function $booleanBooleanValue(instance) { if (typeof instance === "boolean") return instance; else return instance.booleanValue__Z(); }; -ScalaJS.numberByteValue = function(instance) { +function $numberByteValue(instance) { if (typeof instance === "number") return (instance << 24) >> 24; else return instance.byteValue__B(); }; -ScalaJS.numberShortValue = function(instance) { +function $numberShortValue(instance) { if (typeof instance === "number") return (instance << 16) >> 16; else return instance.shortValue__S(); }; -ScalaJS.numberIntValue = function(instance) { +function $numberIntValue(instance) { if (typeof instance === "number") return instance | 0; else return instance.intValue__I(); }; -ScalaJS.numberLongValue = function(instance) { +function $numberLongValue(instance) { if (typeof instance === "number") - return ScalaJS.m.sjsr_RuntimeLong$().fromDouble__D__sjsr_RuntimeLong(instance); + return $m_sjsr_RuntimeLong$().fromDouble__D__sjsr_RuntimeLong(instance); else return instance.longValue__J(); }; -ScalaJS.numberFloatValue = function(instance) { - if (typeof instance === "number") return ScalaJS.fround(instance); +function $numberFloatValue(instance) { + if (typeof instance === "number") return $fround(instance); else return instance.floatValue__F(); }; -ScalaJS.numberDoubleValue = function(instance) { +function $numberDoubleValue(instance) { if (typeof instance === "number") return instance; else return instance.doubleValue__D(); }; -ScalaJS.isNaN = function(instance) { +function $isNaN(instance) { return instance !== instance; }; -ScalaJS.isInfinite = function(instance) { - return !ScalaJS.g["isFinite"](instance) && !ScalaJS.isNaN(instance); +function $isInfinite(instance) { + return !$g["isFinite"](instance) && !$isNaN(instance); }; -ScalaJS.doubleToInt = function(x) { +function $doubleToInt(x) { return (x > 2147483647) ? (2147483647) : ((x < -2147483648) ? -2147483648 : (x | 0)); }; /** Instantiates a JS object with variadic arguments to the constructor. */ -ScalaJS.newJSObjectWithVarargs = function(ctor, args) { +function $newJSObjectWithVarargs(ctor, args) { // This basically emulates the ECMAScript specification for 'new'. - const instance = ScalaJS.g["Object"]["create"](ctor.prototype); + const instance = $g["Object"]["create"](ctor.prototype); const result = ctor["apply"](instance, args); switch (typeof result) { case "string": case "number": case "boolean": case "undefined": case "symbol": @@ -457,9 +457,9 @@ ScalaJS.newJSObjectWithVarargs = function(ctor, args) { } }; -ScalaJS.resolveSuperRef = function(initialProto, propName) { - const getPrototypeOf = ScalaJS.g["Object"]["getPrototypeOf"]; - const getOwnPropertyDescriptor = ScalaJS.g["Object"]["getOwnPropertyDescriptor"]; +function $resolveSuperRef(initialProto, propName) { + const getPrototypeOf = $g["Object"]["getPrototypeOf"]; + const getOwnPropertyDescriptor = $g["Object"]["getOwnPropertyDescriptor"]; let superProto = getPrototypeOf(initialProto); while (superProto !== null) { @@ -472,8 +472,8 @@ ScalaJS.resolveSuperRef = function(initialProto, propName) { return void 0; }; -ScalaJS.superGet = function(initialProto, self, propName) { - const desc = ScalaJS.resolveSuperRef(initialProto, propName); +function $superGet(initialProto, self, propName) { + const desc = $resolveSuperRef(initialProto, propName); if (desc !== void 0) { const getter = desc["get"]; if (getter !== void 0) @@ -484,8 +484,8 @@ ScalaJS.superGet = function(initialProto, self, propName) { return void 0; }; -ScalaJS.superSet = function(initialProto, self, propName, value) { - const desc = ScalaJS.resolveSuperRef(initialProto, propName); +function $superSet(initialProto, self, propName, value) { + const desc = $resolveSuperRef(initialProto, propName); if (desc !== void 0) { const setter = desc["set"]; if (setter !== void 0) { @@ -493,23 +493,23 @@ ScalaJS.superSet = function(initialProto, self, propName, value) { return void 0; } } - throw new ScalaJS.g["TypeError"]("super has no setter '" + propName + "'."); + throw new $g["TypeError"]("super has no setter '" + propName + "'."); }; //!if moduleKind == CommonJSModule -ScalaJS.moduleDefault = function(m) { +function $moduleDefault(m) { return (m && (typeof m === "object") && "default" in m) ? m["default"] : m; }; //!endif -ScalaJS.propertiesOf = function(obj) { +function $propertiesOf(obj) { const result = []; for (const prop in obj) result["push"](prop); return result; }; -ScalaJS.systemArraycopy = function(src, srcPos, dest, destPos, length) { +function $systemArraycopy(src, srcPos, dest, destPos, length) { const srcu = src.u; const destu = dest.u; @@ -517,7 +517,7 @@ ScalaJS.systemArraycopy = function(src, srcPos, dest, destPos, length) { if (srcPos < 0 || destPos < 0 || length < 0 || (srcPos > ((srcu.length - length) | 0)) || (destPos > ((destu.length - length) | 0))) { - ScalaJS.throwArrayIndexOutOfBoundsException(null); + $throwArrayIndexOutOfBoundsException(null); } //!endif @@ -530,23 +530,23 @@ ScalaJS.systemArraycopy = function(src, srcPos, dest, destPos, length) { } }; -ScalaJS.systemIdentityHashCode = +const $systemIdentityHashCode = //!if outputMode != ECMAScript6 - (ScalaJS.idHashCodeMap !== null) ? + ($idHashCodeMap !== null) ? //!endif (function(obj) { switch (typeof obj) { case "string": case "number": case "boolean": case "undefined": - return ScalaJS.objectHashCode(obj); + return $objectHashCode(obj); default: if (obj === null) { return 0; } else { - let hash = ScalaJS.idHashCodeMap["get"](obj); + let hash = $idHashCodeMap["get"](obj); if (hash === void 0) { - hash = (ScalaJS.lastIDHash + 1) | 0; - ScalaJS.lastIDHash = hash; - ScalaJS.idHashCodeMap["set"](obj, hash); + hash = ($lastIDHash + 1) | 0; + $lastIDHash = hash; + $idHashCodeMap["set"](obj, hash); } return hash; } @@ -554,13 +554,13 @@ ScalaJS.systemIdentityHashCode = //!if outputMode != ECMAScript6 }) : (function(obj) { - if (ScalaJS.isScalaJSObject(obj)) { + if ($isScalaJSObject(obj)) { let hash = obj["$idHashCode$0"]; if (hash !== void 0) { return hash; - } else if (!ScalaJS.g["Object"]["isSealed"](obj)) { - hash = (ScalaJS.lastIDHash + 1) | 0; - ScalaJS.lastIDHash = hash; + } else if (!$g["Object"]["isSealed"](obj)) { + hash = ($lastIDHash + 1) | 0; + $lastIDHash = hash; obj["$idHashCode$0"] = hash; return hash; } else { @@ -569,157 +569,157 @@ ScalaJS.systemIdentityHashCode = } else if (obj === null) { return 0; } else { - return ScalaJS.objectHashCode(obj); + return $objectHashCode(obj); } //!endif }); // is/as for hijacked boxed classes (the non-trivial ones) -ScalaJS.isByte = function(v) { +function $isByte(v) { return (v << 24 >> 24) === v && 1/v !== 1/-0; }; -ScalaJS.isShort = function(v) { +function $isShort(v) { return (v << 16 >> 16) === v && 1/v !== 1/-0; }; -ScalaJS.isInt = function(v) { +function $isInt(v) { return (v | 0) === v && 1/v !== 1/-0; }; -ScalaJS.isFloat = function(v) { +function $isFloat(v) { //!if floats == Strict - return v !== v || ScalaJS.fround(v) === v; + return v !== v || $fround(v) === v; //!else return typeof v === "number"; //!endif }; //!if asInstanceOfs != Unchecked -ScalaJS.asUnit = function(v) { +function $asUnit(v) { if (v === void 0 || v === null) return v; else - ScalaJS.throwClassCastException(v, "scala.runtime.BoxedUnit"); + $throwClassCastException(v, "scala.runtime.BoxedUnit"); }; -ScalaJS.asBoolean = function(v) { +function $asBoolean(v) { if (typeof v === "boolean" || v === null) return v; else - ScalaJS.throwClassCastException(v, "java.lang.Boolean"); + $throwClassCastException(v, "java.lang.Boolean"); }; -ScalaJS.asByte = function(v) { - if (ScalaJS.isByte(v) || v === null) +function $asByte(v) { + if ($isByte(v) || v === null) return v; else - ScalaJS.throwClassCastException(v, "java.lang.Byte"); + $throwClassCastException(v, "java.lang.Byte"); }; -ScalaJS.asShort = function(v) { - if (ScalaJS.isShort(v) || v === null) +function $asShort(v) { + if ($isShort(v) || v === null) return v; else - ScalaJS.throwClassCastException(v, "java.lang.Short"); + $throwClassCastException(v, "java.lang.Short"); }; -ScalaJS.asInt = function(v) { - if (ScalaJS.isInt(v) || v === null) +function $asInt(v) { + if ($isInt(v) || v === null) return v; else - ScalaJS.throwClassCastException(v, "java.lang.Integer"); + $throwClassCastException(v, "java.lang.Integer"); }; -ScalaJS.asFloat = function(v) { - if (ScalaJS.isFloat(v) || v === null) +function $asFloat(v) { + if ($isFloat(v) || v === null) return v; else - ScalaJS.throwClassCastException(v, "java.lang.Float"); + $throwClassCastException(v, "java.lang.Float"); }; -ScalaJS.asDouble = function(v) { +function $asDouble(v) { if (typeof v === "number" || v === null) return v; else - ScalaJS.throwClassCastException(v, "java.lang.Double"); + $throwClassCastException(v, "java.lang.Double"); }; //!endif // Unboxes //!if asInstanceOfs != Unchecked -ScalaJS.uZ = function(value) { - return !!ScalaJS.asBoolean(value); +function $uZ(value) { + return !!$asBoolean(value); }; -ScalaJS.uB = function(value) { - return ScalaJS.asByte(value) | 0; +function $uB(value) { + return $asByte(value) | 0; }; -ScalaJS.uS = function(value) { - return ScalaJS.asShort(value) | 0; +function $uS(value) { + return $asShort(value) | 0; }; -ScalaJS.uI = function(value) { - return ScalaJS.asInt(value) | 0; +function $uI(value) { + return $asInt(value) | 0; }; -ScalaJS.uJ = function(value) { - return null === value ? ScalaJS.m.sjsr_RuntimeLong$().Zero$1 - : ScalaJS.as.sjsr_RuntimeLong(value); +function $uJ(value) { + return null === value ? $m_sjsr_RuntimeLong$().Zero$1 + : $as_sjsr_RuntimeLong(value); }; -ScalaJS.uF = function(value) { +function $uF(value) { /* Here, it is fine to use + instead of fround, because asFloat already * ensures that the result is either null or a float. */ - return +ScalaJS.asFloat(value); + return +$asFloat(value); }; -ScalaJS.uD = function(value) { - return +ScalaJS.asDouble(value); +function $uD(value) { + return +$asDouble(value); }; //!else -ScalaJS.uJ = function(value) { - return null === value ? ScalaJS.m.sjsr_RuntimeLong$().Zero$1 : value; +function $uJ(value) { + return null === value ? $m_sjsr_RuntimeLong$().Zero$1 : value; }; //!endif // TypeArray conversions -ScalaJS.byteArray2TypedArray = function(value) { return new ScalaJS.g["Int8Array"](value.u); }; -ScalaJS.shortArray2TypedArray = function(value) { return new ScalaJS.g["Int16Array"](value.u); }; -ScalaJS.charArray2TypedArray = function(value) { return new ScalaJS.g["Uint16Array"](value.u); }; -ScalaJS.intArray2TypedArray = function(value) { return new ScalaJS.g["Int32Array"](value.u); }; -ScalaJS.floatArray2TypedArray = function(value) { return new ScalaJS.g["Float32Array"](value.u); }; -ScalaJS.doubleArray2TypedArray = function(value) { return new ScalaJS.g["Float64Array"](value.u); }; +function $byteArray2TypedArray(value) { return new $g["Int8Array"](value.u); }; +function $shortArray2TypedArray(value) { return new $g["Int16Array"](value.u); }; +function $charArray2TypedArray(value) { return new $g["Uint16Array"](value.u); }; +function $intArray2TypedArray(value) { return new $g["Int32Array"](value.u); }; +function $floatArray2TypedArray(value) { return new $g["Float32Array"](value.u); }; +function $doubleArray2TypedArray(value) { return new $g["Float64Array"](value.u); }; -ScalaJS.typedArray2ByteArray = function(value) { - const arrayClassData = ScalaJS.d.B.getArrayOf(); - return new arrayClassData.constr(new ScalaJS.g["Int8Array"](value)); +function $typedArray2ByteArray(value) { + const arrayClassData = $d_B.getArrayOf(); + return new arrayClassData.constr(new $g["Int8Array"](value)); }; -ScalaJS.typedArray2ShortArray = function(value) { - const arrayClassData = ScalaJS.d.S.getArrayOf(); - return new arrayClassData.constr(new ScalaJS.g["Int16Array"](value)); +function $typedArray2ShortArray(value) { + const arrayClassData = $d_S.getArrayOf(); + return new arrayClassData.constr(new $g["Int16Array"](value)); }; -ScalaJS.typedArray2CharArray = function(value) { - const arrayClassData = ScalaJS.d.C.getArrayOf(); - return new arrayClassData.constr(new ScalaJS.g["Uint16Array"](value)); +function $typedArray2CharArray(value) { + const arrayClassData = $d_C.getArrayOf(); + return new arrayClassData.constr(new $g["Uint16Array"](value)); }; -ScalaJS.typedArray2IntArray = function(value) { - const arrayClassData = ScalaJS.d.I.getArrayOf(); - return new arrayClassData.constr(new ScalaJS.g["Int32Array"](value)); +function $typedArray2IntArray(value) { + const arrayClassData = $d_I.getArrayOf(); + return new arrayClassData.constr(new $g["Int32Array"](value)); }; -ScalaJS.typedArray2FloatArray = function(value) { - const arrayClassData = ScalaJS.d.F.getArrayOf(); - return new arrayClassData.constr(new ScalaJS.g["Float32Array"](value)); +function $typedArray2FloatArray(value) { + const arrayClassData = $d_F.getArrayOf(); + return new arrayClassData.constr(new $g["Float32Array"](value)); }; -ScalaJS.typedArray2DoubleArray = function(value) { - const arrayClassData = ScalaJS.d.D.getArrayOf(); - return new arrayClassData.constr(new ScalaJS.g["Float64Array"](value)); +function $typedArray2DoubleArray(value) { + const arrayClassData = $d_D.getArrayOf(); + return new arrayClassData.constr(new $g["Float64Array"](value)); }; // TypeData class //!if outputMode != ECMAScript6 /** @constructor */ -ScalaJS.TypeData = function() { +function $TypeData() { //!else class $TypeData { constructor() { @@ -747,7 +747,7 @@ constructor() { }; //!if outputMode != ECMAScript6 -ScalaJS.TypeData.prototype.initPrim = function( +$TypeData.prototype.initPrim = function( //!else initPrim( //!endif @@ -768,13 +768,13 @@ initPrim( }; //!if outputMode != ECMAScript6 -ScalaJS.TypeData.prototype.initClass = function( +$TypeData.prototype.initClass = function( //!else initClass( //!endif internalNameObj, isInterface, fullName, ancestors, isRawJSType, parentData, isInstance, isArrayOf) { - const internalName = ScalaJS.propertyName(internalNameObj); + const internalName = $propertyName(internalNameObj); isInstance = isInstance || function(obj) { return !!(obj && obj.$classData && obj.$classData.ancestors[internalName]); @@ -801,7 +801,7 @@ initClass( }; //!if outputMode != ECMAScript6 -ScalaJS.TypeData.prototype.initArray = function( +$TypeData.prototype.initArray = function( //!else initArray( //!endif @@ -814,7 +814,7 @@ initArray( // is a special case here, since the class has not // been defined yet, when this file is read const componentZero = (componentZero0 == "longZero") - ? ScalaJS.m.sjsr_RuntimeLong$().Zero$1 + ? $m_sjsr_RuntimeLong$().Zero$1 : componentZero0; //!if outputMode != ECMAScript6 @@ -830,18 +830,18 @@ initArray( this.u = arg; } } - ArrayClass.prototype = new ScalaJS.h.O; + ArrayClass.prototype = new $h_O; ArrayClass.prototype.constructor = ArrayClass; //!if arrayIndexOutOfBounds != Unchecked ArrayClass.prototype.get = function(i) { if (i < 0 || i >= this.u.length) - ScalaJS.throwArrayIndexOutOfBoundsException(i); + $throwArrayIndexOutOfBoundsException(i); return this.u[i]; }; ArrayClass.prototype.set = function(i, v) { if (i < 0 || i >= this.u.length) - ScalaJS.throwArrayIndexOutOfBoundsException(i); + $throwArrayIndexOutOfBoundsException(i); this.u[i] = v; }; //!endif @@ -854,7 +854,7 @@ initArray( return new ArrayClass(new this.u.constructor(this.u)); }; //!else - class ArrayClass extends ScalaJS.c.O { + class ArrayClass extends $c_O { constructor(arg) { super(); if (typeof(arg) === "number") { @@ -871,12 +871,12 @@ initArray( //!if arrayIndexOutOfBounds != Unchecked get(i) { if (i < 0 || i >= this.u.length) - ScalaJS.throwArrayIndexOutOfBoundsException(i); + $throwArrayIndexOutOfBoundsException(i); return this.u[i]; }; set(i, v) { if (i < 0 || i >= this.u.length) - ScalaJS.throwArrayIndexOutOfBoundsException(i); + $throwArrayIndexOutOfBoundsException(i); this.u[i] = v; }; //!endif @@ -908,7 +908,7 @@ initArray( // Runtime support this.constr = ArrayClass; - this.parentData = ScalaJS.d.O; + this.parentData = $d_O; this.ancestors = {O: 1, jl_Cloneable: 1, Ljava_io_Serializable: 1}; this.componentData = componentData; this.arrayBase = componentBase; @@ -930,52 +930,52 @@ initArray( }; //!if outputMode != ECMAScript6 -ScalaJS.TypeData.prototype.getClassOf = function() { +$TypeData.prototype.getClassOf = function() { //!else getClassOf() { //!endif if (!this._classOf) - this._classOf = new ScalaJS.c.jl_Class().init___jl_ScalaJSClassData(this); + this._classOf = new $c_jl_Class().init___jl_ScalaJSClassData(this); return this._classOf; }; //!if outputMode != ECMAScript6 -ScalaJS.TypeData.prototype.getArrayOf = function() { +$TypeData.prototype.getArrayOf = function() { //!else getArrayOf() { //!endif if (!this._arrayOf) - this._arrayOf = new ScalaJS.TypeData().initArray(this); + this._arrayOf = new $TypeData().initArray(this); return this._arrayOf; }; // java.lang.Class support //!if outputMode != ECMAScript6 -ScalaJS.TypeData.prototype["getFakeInstance"] = function() { +$TypeData.prototype["getFakeInstance"] = function() { //!else "getFakeInstance"() { //!endif - if (this === ScalaJS.d.T) + if (this === $d_T) return "some string"; - else if (this === ScalaJS.d.jl_Boolean) + else if (this === $d_jl_Boolean) return false; - else if (this === ScalaJS.d.jl_Byte || - this === ScalaJS.d.jl_Short || - this === ScalaJS.d.jl_Integer || - this === ScalaJS.d.jl_Float || - this === ScalaJS.d.jl_Double) + else if (this === $d_jl_Byte || + this === $d_jl_Short || + this === $d_jl_Integer || + this === $d_jl_Float || + this === $d_jl_Double) return 0; - else if (this === ScalaJS.d.jl_Long) - return ScalaJS.m.sjsr_RuntimeLong$().Zero$1; - else if (this === ScalaJS.d.sr_BoxedUnit) + else if (this === $d_jl_Long) + return $m_sjsr_RuntimeLong$().Zero$1; + else if (this === $d_sr_BoxedUnit) return void 0; else return {$classData: this}; }; //!if outputMode != ECMAScript6 -ScalaJS.TypeData.prototype["getSuperclass"] = function() { +$TypeData.prototype["getSuperclass"] = function() { //!else "getSuperclass"() { //!endif @@ -983,7 +983,7 @@ ScalaJS.TypeData.prototype["getSuperclass"] = function() { }; //!if outputMode != ECMAScript6 -ScalaJS.TypeData.prototype["getComponentType"] = function() { +$TypeData.prototype["getComponentType"] = function() { //!else "getComponentType"() { //!endif @@ -991,14 +991,14 @@ ScalaJS.TypeData.prototype["getComponentType"] = function() { }; //!if outputMode != ECMAScript6 -ScalaJS.TypeData.prototype["newArrayOfThisClass"] = function(lengths) { +$TypeData.prototype["newArrayOfThisClass"] = function(lengths) { //!else "newArrayOfThisClass"(lengths) { //!endif let arrayClassData = this; for (let i = 0; i < lengths.length; i++) arrayClassData = arrayClassData.getArrayOf(); - return ScalaJS.newArrayObject(arrayClassData, lengths); + return $newArrayObject(arrayClassData, lengths); }; //!if outputMode == ECMAScript6 }; @@ -1006,50 +1006,50 @@ ScalaJS.TypeData.prototype["newArrayOfThisClass"] = function(lengths) { // Create primitive types -ScalaJS.d.V = new ScalaJS.TypeData().initPrim(undefined, "V", "void"); -ScalaJS.d.Z = new ScalaJS.TypeData().initPrim(false, "Z", "boolean"); -ScalaJS.d.C = new ScalaJS.TypeData().initPrim(0, "C", "char"); -ScalaJS.d.B = new ScalaJS.TypeData().initPrim(0, "B", "byte"); -ScalaJS.d.S = new ScalaJS.TypeData().initPrim(0, "S", "short"); -ScalaJS.d.I = new ScalaJS.TypeData().initPrim(0, "I", "int"); -ScalaJS.d.J = new ScalaJS.TypeData().initPrim("longZero", "J", "long"); -ScalaJS.d.F = new ScalaJS.TypeData().initPrim(0.0, "F", "float"); -ScalaJS.d.D = new ScalaJS.TypeData().initPrim(0.0, "D", "double"); +const $d_V = new $TypeData().initPrim(undefined, "V", "void"); +const $d_Z = new $TypeData().initPrim(false, "Z", "boolean"); +const $d_C = new $TypeData().initPrim(0, "C", "char"); +const $d_B = new $TypeData().initPrim(0, "B", "byte"); +const $d_S = new $TypeData().initPrim(0, "S", "short"); +const $d_I = new $TypeData().initPrim(0, "I", "int"); +const $d_J = new $TypeData().initPrim("longZero", "J", "long"); +const $d_F = new $TypeData().initPrim(0.0, "F", "float"); +const $d_D = new $TypeData().initPrim(0.0, "D", "double"); // Instance tests for array of primitives -ScalaJS.isArrayOf.Z = ScalaJS.makeIsArrayOfPrimitive(ScalaJS.d.Z); -ScalaJS.d.Z.isArrayOf = ScalaJS.isArrayOf.Z; +const $isArrayOf_Z = $makeIsArrayOfPrimitive($d_Z); +$d_Z.isArrayOf = $isArrayOf_Z; -ScalaJS.isArrayOf.C = ScalaJS.makeIsArrayOfPrimitive(ScalaJS.d.C); -ScalaJS.d.C.isArrayOf = ScalaJS.isArrayOf.C; +const $isArrayOf_C = $makeIsArrayOfPrimitive($d_C); +$d_C.isArrayOf = $isArrayOf_C; -ScalaJS.isArrayOf.B = ScalaJS.makeIsArrayOfPrimitive(ScalaJS.d.B); -ScalaJS.d.B.isArrayOf = ScalaJS.isArrayOf.B; +const $isArrayOf_B = $makeIsArrayOfPrimitive($d_B); +$d_B.isArrayOf = $isArrayOf_B; -ScalaJS.isArrayOf.S = ScalaJS.makeIsArrayOfPrimitive(ScalaJS.d.S); -ScalaJS.d.S.isArrayOf = ScalaJS.isArrayOf.S; +const $isArrayOf_S = $makeIsArrayOfPrimitive($d_S); +$d_S.isArrayOf = $isArrayOf_S; -ScalaJS.isArrayOf.I = ScalaJS.makeIsArrayOfPrimitive(ScalaJS.d.I); -ScalaJS.d.I.isArrayOf = ScalaJS.isArrayOf.I; +const $isArrayOf_I = $makeIsArrayOfPrimitive($d_I); +$d_I.isArrayOf = $isArrayOf_I; -ScalaJS.isArrayOf.J = ScalaJS.makeIsArrayOfPrimitive(ScalaJS.d.J); -ScalaJS.d.J.isArrayOf = ScalaJS.isArrayOf.J; +const $isArrayOf_J = $makeIsArrayOfPrimitive($d_J); +$d_J.isArrayOf = $isArrayOf_J; -ScalaJS.isArrayOf.F = ScalaJS.makeIsArrayOfPrimitive(ScalaJS.d.F); -ScalaJS.d.F.isArrayOf = ScalaJS.isArrayOf.F; +const $isArrayOf_F = $makeIsArrayOfPrimitive($d_F); +$d_F.isArrayOf = $isArrayOf_F; -ScalaJS.isArrayOf.D = ScalaJS.makeIsArrayOfPrimitive(ScalaJS.d.D); -ScalaJS.d.D.isArrayOf = ScalaJS.isArrayOf.D; +const $isArrayOf_D = $makeIsArrayOfPrimitive($d_D); +$d_D.isArrayOf = $isArrayOf_D; //!if asInstanceOfs != Unchecked // asInstanceOfs for array of primitives -ScalaJS.asArrayOf.Z = ScalaJS.makeAsArrayOfPrimitive(ScalaJS.isArrayOf.Z, "Z"); -ScalaJS.asArrayOf.C = ScalaJS.makeAsArrayOfPrimitive(ScalaJS.isArrayOf.C, "C"); -ScalaJS.asArrayOf.B = ScalaJS.makeAsArrayOfPrimitive(ScalaJS.isArrayOf.B, "B"); -ScalaJS.asArrayOf.S = ScalaJS.makeAsArrayOfPrimitive(ScalaJS.isArrayOf.S, "S"); -ScalaJS.asArrayOf.I = ScalaJS.makeAsArrayOfPrimitive(ScalaJS.isArrayOf.I, "I"); -ScalaJS.asArrayOf.J = ScalaJS.makeAsArrayOfPrimitive(ScalaJS.isArrayOf.J, "J"); -ScalaJS.asArrayOf.F = ScalaJS.makeAsArrayOfPrimitive(ScalaJS.isArrayOf.F, "F"); -ScalaJS.asArrayOf.D = ScalaJS.makeAsArrayOfPrimitive(ScalaJS.isArrayOf.D, "D"); +const $asArrayOf_Z = $makeAsArrayOfPrimitive($isArrayOf_Z, "Z"); +const $asArrayOf_C = $makeAsArrayOfPrimitive($isArrayOf_C, "C"); +const $asArrayOf_B = $makeAsArrayOfPrimitive($isArrayOf_B, "B"); +const $asArrayOf_S = $makeAsArrayOfPrimitive($isArrayOf_S, "S"); +const $asArrayOf_I = $makeAsArrayOfPrimitive($isArrayOf_I, "I"); +const $asArrayOf_J = $makeAsArrayOfPrimitive($isArrayOf_J, "J"); +const $asArrayOf_F = $makeAsArrayOfPrimitive($isArrayOf_F, "F"); +const $asArrayOf_D = $makeAsArrayOfPrimitive($isArrayOf_D, "D"); //!endif diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala index 0af4db160d..a2aacfb19a 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala @@ -122,30 +122,13 @@ private[backend] object CoreJSLibs { val content = lines.mkString("", "\n", "\n").replace( "{{LINKER_VERSION}}", ScalaJSVersions.current) - val content1 = outputMode match { - case OutputMode.ECMAScript51Isolated | OutputMode.ECMAScript6 => - content - .replaceAll("ScalaJS\\.d\\.", "\\$d_") - .replaceAll("ScalaJS\\.c\\.", "\\$c_") - .replaceAll("ScalaJS\\.h\\.", "\\$h_") - .replaceAll("ScalaJS\\.s\\.", "\\$s_") - .replaceAll("ScalaJS\\.n\\.", "\\$n_") - .replaceAll("ScalaJS\\.m\\.", "\\$m_") - .replaceAll("ScalaJS\\.is\\.", "\\$is_") - .replaceAll("ScalaJS\\.as\\.", "\\$as_") - .replaceAll("ScalaJS\\.isArrayOf\\.", "\\$isArrayOf_") - .replaceAll("ScalaJS\\.asArrayOf\\.", "\\$asArrayOf_") - .replaceAll("ScalaJS\\.", "\\$") - .replaceAll("\n(\\$[A-Za-z0-9_]+) =", "\nconst $1 =") - } - outputMode match { case OutputMode.ECMAScript51Isolated => - content1 + content .replaceAll(raw"\b(let|const)\b", "var") case OutputMode.ECMAScript6 => - content1 + content } } From 268d000de4ec7e803496eb026631262bbcce6aaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 25 Mar 2017 00:20:05 +0100 Subject: [PATCH 0169/2665] Remove LinkingUnitJSEnv. This API was only useful for Rhino's lazy loading. --- .../scalajs/jsenv/LinkingUnitAsyncJSEnv.scala | 42 ----------- .../scalajs/jsenv/LinkingUnitComJSEnv.scala | 43 ----------- .../org/scalajs/jsenv/LinkingUnitJSEnv.scala | 72 ------------------- .../sbtplugin/ScalaJSPluginInternal.scala | 34 ++------- 4 files changed, 6 insertions(+), 185 deletions(-) delete mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/LinkingUnitAsyncJSEnv.scala delete mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/LinkingUnitComJSEnv.scala delete mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/LinkingUnitJSEnv.scala diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/LinkingUnitAsyncJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/LinkingUnitAsyncJSEnv.scala deleted file mode 100644 index dc2219252f..0000000000 --- a/js-envs/src/main/scala/org/scalajs/jsenv/LinkingUnitAsyncJSEnv.scala +++ /dev/null @@ -1,42 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.jsenv - -import org.scalajs.core.tools.io.VirtualJSFile -import org.scalajs.core.tools.jsdep.ResolvedJSDependency -import org.scalajs.core.tools.linker.LinkingUnit - -trait LinkingUnitAsyncJSEnv extends LinkingUnitJSEnv with AsyncJSEnv { - def asyncRunner(preLibs: Seq[ResolvedJSDependency], linkingUnit: LinkingUnit, - postLibs: Seq[ResolvedJSDependency], code: VirtualJSFile): AsyncJSRunner - - override def loadLibs(libs: Seq[ResolvedJSDependency]): LinkingUnitAsyncJSEnv = - new LinkingUnitAsyncLoadedLibs { val loadedLibs = libs } - - override def loadLinkingUnit(linkingUnit: LinkingUnit): AsyncJSEnv = - new AsyncLoadedUnit { val loadedUnit = linkingUnit } - - private[jsenv] trait LinkingUnitAsyncLoadedLibs extends LinkingUnitLoadedLibs - with AsyncLoadedLibs with LinkingUnitAsyncJSEnv { - def asyncRunner(preLibs: Seq[ResolvedJSDependency], linkingUnit: LinkingUnit, - postLibs: Seq[ResolvedJSDependency], - code: VirtualJSFile): AsyncJSRunner = { - LinkingUnitAsyncJSEnv.this.asyncRunner(loadedLibs ++ preLibs, linkingUnit, - postLibs, code) - } - } - - private[jsenv] trait AsyncLoadedUnit extends LoadedUnit with AsyncJSEnv { - def asyncRunner(libs: Seq[ResolvedJSDependency], - code: VirtualJSFile): AsyncJSRunner = { - LinkingUnitAsyncJSEnv.this.asyncRunner(Nil, loadedUnit, libs, code) - } - } -} diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/LinkingUnitComJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/LinkingUnitComJSEnv.scala deleted file mode 100644 index dc39bbcb73..0000000000 --- a/js-envs/src/main/scala/org/scalajs/jsenv/LinkingUnitComJSEnv.scala +++ /dev/null @@ -1,43 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.jsenv - -import org.scalajs.core.tools.io.VirtualJSFile -import org.scalajs.core.tools.jsdep.ResolvedJSDependency -import org.scalajs.core.tools.linker.LinkingUnit - -trait LinkingUnitComJSEnv extends LinkingUnitAsyncJSEnv with ComJSEnv { - def comRunner(preLibs: Seq[ResolvedJSDependency], linkingUnit: LinkingUnit, - postLibs: Seq[ResolvedJSDependency], code: VirtualJSFile): ComJSRunner - - override def loadLibs(libs: Seq[ResolvedJSDependency]): LinkingUnitComJSEnv = - new LinkingUnitComLoadedLibs { val loadedLibs = libs } - - override def loadLinkingUnit(linkingUnit: LinkingUnit): ComJSEnv = - new ComLoadedUnit { val loadedUnit = linkingUnit } - - private[jsenv] trait LinkingUnitComLoadedLibs - extends LinkingUnitAsyncLoadedLibs with ComLoadedLibs - with LinkingUnitComJSEnv { - def comRunner(preLibs: Seq[ResolvedJSDependency], linkingUnit: LinkingUnit, - postLibs: Seq[ResolvedJSDependency], - code: VirtualJSFile): ComJSRunner = { - LinkingUnitComJSEnv.this.comRunner(loadedLibs ++ preLibs, linkingUnit, - postLibs, code) - } - } - - private[jsenv] trait ComLoadedUnit extends AsyncLoadedUnit with ComJSEnv { - def comRunner(libs: Seq[ResolvedJSDependency], - code: VirtualJSFile): ComJSRunner = { - LinkingUnitComJSEnv.this.comRunner(Nil, loadedUnit, libs, code) - } - } -} diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/LinkingUnitJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/LinkingUnitJSEnv.scala deleted file mode 100644 index 6ba33e6697..0000000000 --- a/js-envs/src/main/scala/org/scalajs/jsenv/LinkingUnitJSEnv.scala +++ /dev/null @@ -1,72 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.jsenv - -import org.scalajs.core.tools.io.VirtualJSFile -import org.scalajs.core.tools.jsdep.ResolvedJSDependency -import org.scalajs.core.tools.linker.LinkingUnit -import org.scalajs.core.tools.linker.analyzer.SymbolRequirement - -trait LinkingUnitJSEnv extends JSEnv { - /** Symbols this [[LinkingUnitJSEnv]] needs present in the - * [[org.scalajs.core.tools.linker.LinkingUnit LinkingUnit]] it receives. - */ - val symbolRequirements: SymbolRequirement - - /** Prepare a runner for the code in the virtual file. */ - def jsRunner(preLibs: Seq[ResolvedJSDependency], linkingUnit: LinkingUnit, - postLibs: Seq[ResolvedJSDependency], code: VirtualJSFile): JSRunner - - override def loadLibs(libs: Seq[ResolvedJSDependency]): LinkingUnitJSEnv = - new LinkingUnitLoadedLibs { val loadedLibs = libs } - - /** Returns a [[JSEnv]] with the given - * [[org.scalajs.core.tools.linker.LinkingUnit LinkingUnit]] already loaded. - * - * Note that any subsequent libraries will be inserted after the - * [[org.scalajs.core.tools.linker.LinkingUnit LinkingUnit]]. - * - * Hence, the following are equivalent: - * {{{ - * jsEnv.loadUnit(a).jsRunner(b, c) - * jsEnv.jsRunner(Nil, a, b, c) - * }}} - * - * If you need to load libraries before, you can use the [[loadLibs]] method: - * {{{ - * jsEnv.loadLibs(a).loadUnit(b).jsRunner(c, d) - * // equivalent to - * jsEnv.jsRunner(a, b, c, d) - * }}} - */ - def loadLinkingUnit(linkingUnit: LinkingUnit): JSEnv = - new LoadedUnit { val loadedUnit = linkingUnit } - - private[jsenv] trait LinkingUnitLoadedLibs - extends LoadedLibs with LinkingUnitJSEnv { - val symbolRequirements: SymbolRequirement = - LinkingUnitJSEnv.this.symbolRequirements - - def jsRunner(preLibs: Seq[ResolvedJSDependency], linkingUnit: LinkingUnit, - postLibs: Seq[ResolvedJSDependency], code: VirtualJSFile): JSRunner = { - LinkingUnitJSEnv.this.jsRunner(loadedLibs ++ preLibs, - linkingUnit, postLibs, code) - } - } - - private[jsenv] trait LoadedUnit extends JSEnv { - val loadedUnit: LinkingUnit - - def name: String = LinkingUnitJSEnv.this.name - - def jsRunner(libs: Seq[ResolvedJSDependency], code: VirtualJSFile): JSRunner = - LinkingUnitJSEnv.this.jsRunner(Nil, loadedUnit, libs, code) - } -} diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 139fb458e8..7516e79cfa 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -637,37 +637,15 @@ object ScalaJSPluginInternal { } }, - loadedJSEnv := Def.taskDyn { + loadedJSEnv := { val log = streams.value.log + val env = resolvedJSEnv.value 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, + val file = scalaJSLinkedFile.value + log.debug(s"Loading JSEnv with linked file ${file.path}") + env.loadLibs(libs :+ ResolvedJSDependency.minimal(file)) + }, scalaJSModuleIdentifier := Def.taskDyn[Option[String]] { scalaJSModuleKind.value match { From 7c05cef59d334db16916ff0bb9d47d3967bb33c3 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Wed, 22 Mar 2017 21:18:22 +0100 Subject: [PATCH 0170/2665] Fix #2829: Make Scala.js defined default --- .../org/scalajs/core/compiler/GenJSCode.scala | 7 +- .../scalajs/core/compiler/JSDefinitions.scala | 1 - .../scalajs/core/compiler/PrepJSExports.scala | 4 +- .../scalajs/core/compiler/PrepJSInterop.scala | 25 +- .../compiler/test/DiverseErrorsTest.scala | 20 +- .../core/compiler/test/JSExportTest.scala | 139 ++++----- .../core/compiler/test/JSInteropTest.scala | 266 ++++-------------- .../core/compiler/test/JSOptionalTest.scala | 38 ++- .../core/compiler/test/OptimizationTest.scala | 2 - .../core/compiler/test/ReflectTest.scala | 13 +- .../compiler/test/ScalaJSDefinedTest.scala | 147 +++------- .../scala/org/scalajs/core/ir/Trees.scala | 9 +- .../jsinterop/ScalaJSDefinedTestEx.scala | 2 - .../src/main/scala/scala/scalajs/js/Any.scala | 1 - .../scala/scala/scalajs/js/Iterable.scala | 1 - .../scala/scala/scalajs/js/Iterator.scala | 2 - .../scala/scala/scalajs/js/JSConverters.scala | 2 - .../scala/scala/scalajs/js/Thenable.scala | 1 - .../scalajs/js/annotation/JSExportNamed.scala | 1 - .../js/annotation/ScalaJSDefined.scala | 2 + .../ScalaJSDefinedTestSeparateRun.scala | 3 - .../jsinterop/JSOptionalTest212.scala | 10 - .../compiler/InteroperabilityTest.scala | 1 - .../testsuite/compiler/OptimizerTest.scala | 1 - .../testsuite/jsinterop/ExportsTest.scala | 21 -- .../testsuite/jsinterop/IterableTest.scala | 2 - .../jsinterop/JSExportStaticTest.scala | 4 - .../testsuite/jsinterop/JSNameTest.scala | 3 - .../testsuite/jsinterop/JSOptionalTest.scala | 13 - .../testsuite/jsinterop/JSSymbolTest.scala | 19 -- .../testsuite/jsinterop/MiscInteropTest.scala | 5 - .../testsuite/jsinterop/PromiseMock.scala | 1 - .../jsinterop/ScalaJSDefinedTest.scala | 93 ------ 33 files changed, 203 insertions(+), 656 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 195056deab..0a8b61140b 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -1696,7 +1696,8 @@ abstract class GenJSCode extends plugins.PluginComponent else genExpr(tree) } - if (!isScalaJSDefinedJSClass(currentClassSym)) { + if (!isScalaJSDefinedJSClass(currentClassSym) || + isRawJSFunctionDef(currentClassSym)) { js.MethodDef(static, methodName, jsParams, resultIRType, Some(genBody()))(optimizerHints, None) } else { @@ -5305,14 +5306,14 @@ abstract class GenJSCode extends plugins.PluginComponent /** Tests whether the given class is a Scala.js-defined JS class. */ def isScalaJSDefinedJSClass(sym: Symbol): Boolean = - !sym.isTrait && sym.hasAnnotation(ScalaJSDefinedAnnotation) + !sym.isTrait && isRawJSType(sym.tpe) && !sym.hasAnnotation(JSNativeAnnotation) def isScalaJSDefinedAnonJSClass(sym: Symbol): Boolean = sym.hasAnnotation(SJSDefinedAnonymousClassAnnotation) /** Tests whether the given class is a JS native class. */ private def isJSNativeClass(sym: Symbol): Boolean = - isRawJSType(sym.tpe) && !isScalaJSDefinedJSClass(sym) + sym.hasAnnotation(JSNativeAnnotation) /** Tests whether the given class is the impl class of a raw JS trait. */ private def isRawJSImplClass(sym: Symbol): Boolean = { diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 2421beeabe..ce00d06cc6 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -69,7 +69,6 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val JSImportAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSImport") lazy val JSGlobalAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSGlobal") lazy val JSGlobalScopeAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSGlobalScope") - lazy val ScalaJSDefinedAnnotation = getRequiredClass("scala.scalajs.js.annotation.ScalaJSDefined") lazy val SJSDefinedAnonymousClassAnnotation = getRequiredClass("scala.scalajs.js.annotation.SJSDefinedAnonymousClass") lazy val HasJSNativeLoadSpecAnnotation = getRequiredClass("scala.scalajs.js.annotation.internal.HasJSNativeLoadSpec") lazy val JSOptionalAnnotation = getRequiredClass("scala.scalajs.js.annotation.internal.JSOptional") diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala index 9c4f9f93e6..1c678cf307 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala @@ -121,7 +121,7 @@ trait PrepJSExports { this: PrepJSInterop => /** Checks and registers class exports on the symbol. */ def registerClassExports(sym: Symbol): Unit = { - assert(!sym.isModuleClass && sym.hasAnnotation(ScalaJSDefinedAnnotation), + assert(!sym.isModuleClass && !sym.hasAnnotation(JSNativeAnnotation), "Expected a Scala.js-defined JS class") registerClassOrModuleExportsInternal(sym) } @@ -416,7 +416,7 @@ trait PrepJSExports { this: PrepJSInterop => companion != NoSymbol && !companion.isTrait && isJSAny(companion) && - companion.hasAnnotation(ScalaJSDefinedAnnotation) + !companion.hasAnnotation(JSNativeAnnotation) } if (!symOwner.isStatic || !symOwner.isModuleClass || diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 65be9f9625..430f28a530 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -469,14 +469,13 @@ abstract class PrepJSInterop extends plugins.PluginComponent def isNativeJSTraitType(tpe: Type): Boolean = { val sym = tpe.typeSymbol - sym.isTrait && !sym.hasAnnotation(ScalaJSDefinedAnnotation) + sym.isTrait && sym.hasAnnotation(JSNativeAnnotation) } val isJSAnonFun = isJSLambda(sym) sym.addAnnotation(RawJSTypeAnnot) if (sym.isAnonymousClass && !isJSAnonFun) { - sym.addAnnotation(ScalaJSDefinedAnnotation) sym.addAnnotation(SJSDefinedAnonymousClassAnnotation) } @@ -500,7 +499,10 @@ abstract class PrepJSInterop extends plugins.PluginComponent sym.addAnnotation(annotInfo) } - val isJSNative = !sym.hasAnnotation(ScalaJSDefinedAnnotation) + /* Anonymous functions are considered native, since they are handled + * specially in the backend. + */ + val isJSNative = sym.hasAnnotation(JSNativeAnnotation) || isJSAnonFun // Forbid @EnableReflectiveInstantiation on JS types sym.getAnnotation(EnableReflectiveInstantiationAnnotation).foreach { @@ -514,16 +516,6 @@ abstract class PrepJSInterop extends plugins.PluginComponent reporter.warning(implDef.pos, "Package objects inheriting from js.Any are deprecated. " + "Use a normal object instead.") - } else if (isJSNative && !isJSAnonFun && - !sym.hasAnnotation(JSNativeAnnotation)) { - reporter.warning(implDef.pos, - "Classes, traits and objects inheriting from js.Any should be " + - "annotated with @js.native, unless they have @ScalaJSDefined. " + - "The default will switch to Scala.js-defined in the next major " + - "version of Scala.js.") - } else if (!isJSNative && sym.hasAnnotation(JSNativeAnnotation)) { - reporter.error(implDef.pos, - "@ScalaJSDefined and @js.native cannot be used together") } def strKind = @@ -683,7 +675,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent if (!isJSNative) { def isJSOptional(sym: Symbol): Boolean = { sym.owner.isTrait && !sym.isDeferred && !sym.isConstructor && - sym.owner.hasAnnotation(ScalaJSDefinedAnnotation) + !sym.owner.hasAnnotation(JSNativeAnnotation) } if (isJSOptional(low) && !(high.isDeferred || isJSOptional(high))) { @@ -1122,11 +1114,6 @@ abstract class PrepJSInterop extends plugins.PluginComponent private def checkJSAnySpecificAnnotsOnNonJSAny(implDef: ImplDef): Unit = { val sym = implDef.symbol - if (sym.hasAnnotation(ScalaJSDefinedAnnotation)) { - reporter.error(implDef.pos, - "@ScalaJSDefined is only allowed on classes extending js.Any") - } - if (sym.hasAnnotation(JSNativeAnnotation)) { reporter.error(implDef.pos, "Classes, traits and objects not extending js.Any may not have an " + diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/DiverseErrorsTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/DiverseErrorsTest.scala index 88cd50b182..b71e6aedb6 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/DiverseErrorsTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/DiverseErrorsTest.scala @@ -62,9 +62,9 @@ class DiverseErrorsTest extends DirectTest with TestHelpers { @js.native trait NativeJSTrait extends js.Object @js.native @JSGlobal object NativeJSObject extends js.Object - @ScalaJSDefined class JSClass extends js.Object - @ScalaJSDefined trait JSTrait extends js.Object - @ScalaJSDefined object JSObject extends js.Object + class JSClass extends js.Object + trait JSTrait extends js.Object + object JSObject extends js.Object object A { val a = js.constructorOf[NativeJSTrait] @@ -149,9 +149,9 @@ class DiverseErrorsTest extends DirectTest with TestHelpers { @js.native trait NativeJSTrait extends js.Object @js.native @JSGlobal object NativeJSObject extends js.Object - @ScalaJSDefined class JSClass extends js.Object - @ScalaJSDefined trait JSTrait extends js.Object - @ScalaJSDefined object JSObject extends js.Object + class JSClass extends js.Object + trait JSTrait extends js.Object + object JSObject extends js.Object object A { val a = js.constructorTag[NativeJSTrait] @@ -213,7 +213,7 @@ class DiverseErrorsTest extends DirectTest with TestHelpers { object ScalaObject @js.native @JSGlobal object NativeJSObject extends js.Object - @ScalaJSDefined object JSObject extends js.Object + object JSObject extends js.Object object A { val a = runtime.constructorOf(classOf[ScalaObject.type].asInstanceOf[Class[_ <: js.Any]]) @@ -243,9 +243,9 @@ class DiverseErrorsTest extends DirectTest with TestHelpers { @js.native trait NativeJSTrait extends js.Object @js.native @JSGlobal object NativeJSObject extends js.Object - @ScalaJSDefined class JSClass extends js.Object - @ScalaJSDefined trait JSTrait extends js.Object - @ScalaJSDefined object JSObject extends js.Object + class JSClass extends js.Object + trait JSTrait extends js.Object + object JSObject extends js.Object object A { val a = runtime.constructorOf(classOf[ScalaClass].asInstanceOf[Class[_ <: js.Any]]) diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index 43bc326ef7..320231a47f 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -32,7 +32,7 @@ class JSExportTest extends DirectTest with TestHelpers { class B__ @JSExport - @ScalaJSDefined class C__ extends js.Object + class C__ extends js.Object """ hasErrors """ |newSource1.scala:4: error: An exported name may not contain a double underscore (`__`) @@ -45,8 +45,8 @@ class JSExportTest extends DirectTest with TestHelpers { | class B__ | ^ |newSource1.scala:15: error: An exported name may not contain a double underscore (`__`) - | @ScalaJSDefined class C__ extends js.Object - | ^ + | class C__ extends js.Object + | ^ """ // Inherited exports (objects) @@ -66,16 +66,16 @@ class JSExportTest extends DirectTest with TestHelpers { """ @JSExportDescendentObjects - @ScalaJSDefined trait A extends js.Object + trait A extends js.Object package fo__o { - @ScalaJSDefined object B extends A + object B extends A } """ hasErrors """ |newSource1.scala:7: error: B may not have a double underscore (`__`) in its fully qualified name, since it is forced to be exported by a @JSExportDescendentObjects on trait A - | @ScalaJSDefined object B extends A - | ^ + | object B extends A + | ^ """ // Inherited exports (classes) @@ -101,16 +101,16 @@ class JSExportTest extends DirectTest with TestHelpers { """ @JSExportDescendentClasses - @ScalaJSDefined trait A extends js.Object + trait A extends js.Object package fo__o { - @ScalaJSDefined class B(x: Int) extends A + class B(x: Int) extends A } """ hasErrors """ |newSource1.scala:7: error: B may not have a double underscore (`__`) in its fully qualified name, since it is forced to be exported by a @JSExportDescendentClasses on trait A - | @ScalaJSDefined class B(x: Int) extends A - | ^ + | class B(x: Int) extends A + | ^ """ } @@ -211,7 +211,7 @@ class JSExportTest extends DirectTest with TestHelpers { class A @JSExport - @ScalaJSDefined class B extends js.Object + class B extends js.Object } } """ hasErrors @@ -232,7 +232,7 @@ class JSExportTest extends DirectTest with TestHelpers { object A @JSExport - @ScalaJSDefined object B extends js.Object + object B extends js.Object } } """ hasErrors @@ -339,7 +339,7 @@ class JSExportTest extends DirectTest with TestHelpers { } @JSExport - @ScalaJSDefined abstract class C extends js.Object + abstract class C extends js.Object """ hasErrors """ |newSource1.scala:3: error: You may not export an abstract class @@ -363,7 +363,7 @@ class JSExportTest extends DirectTest with TestHelpers { trait Test @JSExport - @ScalaJSDefined trait Test2 extends js.Object + trait Test2 extends js.Object @JSExport @js.native @@ -394,10 +394,10 @@ class JSExportTest extends DirectTest with TestHelpers { protected[this] class B @JSExport - @ScalaJSDefined private class C extends js.Object + private class C extends js.Object @JSExport - @ScalaJSDefined protected[this] class D extends js.Object + protected[this] class D extends js.Object """ hasErrors """ |newSource1.scala:3: error: You may only export public and protected classes @@ -422,10 +422,10 @@ class JSExportTest extends DirectTest with TestHelpers { protected[this] object B @JSExport - @ScalaJSDefined private object C extends js.Object + private object C extends js.Object @JSExport - @ScalaJSDefined protected[this] object D extends js.Object + protected[this] object D extends js.Object """ hasErrors """ |newSource1.scala:3: error: You may only export public and protected objects @@ -479,7 +479,7 @@ class JSExportTest extends DirectTest with TestHelpers { } @JSExport - @ScalaJSDefined class Nested2 extends js.Object + class Nested2 extends js.Object } """ hasErrors """ @@ -508,7 +508,7 @@ class JSExportTest extends DirectTest with TestHelpers { } @JSExport - @ScalaJSDefined class Nested2 extends js.Object + class Nested2 extends js.Object } """ hasErrors """ @@ -534,7 +534,7 @@ class JSExportTest extends DirectTest with TestHelpers { object Nested @JSExport - @ScalaJSDefined object Nested2 extends js.Object + object Nested2 extends js.Object } """ hasErrors """ @@ -557,7 +557,7 @@ class JSExportTest extends DirectTest with TestHelpers { object Nested @JSExport - @ScalaJSDefined object Nested2 extends js.Object + object Nested2 extends js.Object } """ hasErrors """ @@ -645,14 +645,13 @@ class JSExportTest extends DirectTest with TestHelpers { """ import scala.scalajs.js - @ScalaJSDefined class A extends js.Object { @JSExport def foo: Int = js.native } """ hasErrors """ - |newSource1.scala:7: error: You may not export a method of a subclass of js.Any + |newSource1.scala:6: error: You may not export a method of a subclass of js.Any | @JSExport | ^ """ @@ -889,7 +888,7 @@ class JSExportTest extends DirectTest with TestHelpers { object A @JSExportNamed - @ScalaJSDefined object B extends js.Object + object B extends js.Object """ hasErrors """ |newSource1.scala:3: error: You may not use @JSNamedExport on an object @@ -907,7 +906,7 @@ class JSExportTest extends DirectTest with TestHelpers { """ @JSExportNamed - @ScalaJSDefined class A extends js.Object + class A extends js.Object """ hasErrors """ |newSource1.scala:3: error: You may not use @JSNamedExport on a Scala.js-defined JS class @@ -1108,7 +1107,6 @@ class JSExportTest extends DirectTest with TestHelpers { trait A @JSExportTopLevel("bar") - @ScalaJSDefined trait B extends js.Object """ hasErrors """ @@ -1126,7 +1124,6 @@ class JSExportTest extends DirectTest with TestHelpers { trait A @JSExportTopLevel("bar") - @ScalaJSDefined trait B extends js.Object } """ hasErrors @@ -1279,7 +1276,6 @@ class JSExportTest extends DirectTest with TestHelpers { """ class A { @JSExportTopLevel("Foo") - @ScalaJSDefined object B extends js.Object } """ hasErrors @@ -1292,7 +1288,6 @@ class JSExportTest extends DirectTest with TestHelpers { """ class A { @JSExportTopLevel("Foo") - @ScalaJSDefined class B extends js.Object } """ hasErrors @@ -1318,14 +1313,13 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportTopLevelJSModule: Unit = { """ - @ScalaJSDefined object A extends js.Object { @JSExportTopLevel("foo") def a(): Unit = () } """ hasErrors """ - |newSource1.scala:5: error: You may not export a method of a subclass of js.Any + |newSource1.scala:4: error: You may not export a method of a subclass of js.Any | @JSExportTopLevel("foo") | ^ """ @@ -1334,7 +1328,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticModule: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1343,7 +1336,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Implementation restriction: cannot export a class or object as static + |newSource1.scala:6: error: Implementation restriction: cannot export a class or object as static | @JSExportStatic | ^ """ @@ -1352,7 +1345,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticTrait: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1361,7 +1353,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: You may not export a trait as static. + |newSource1.scala:6: error: You may not export a trait as static. | @JSExportStatic | ^ """ @@ -1370,7 +1362,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticClass: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1379,13 +1370,12 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Implementation restriction: cannot export a class or object as static + |newSource1.scala:6: error: Implementation restriction: cannot export a class or object as static | @JSExportStatic | ^ """ """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1396,7 +1386,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Implementation restriction: cannot export a class or object as static + |newSource1.scala:7: error: Implementation restriction: cannot export a class or object as static | @JSExportStatic | ^ """ @@ -1405,7 +1395,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticValTwice: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1415,7 +1404,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Fields (val or var) cannot be exported as static more than once + |newSource1.scala:7: error: Fields (val or var) cannot be exported as static more than once | @JSExportStatic("b") | ^ """ @@ -1424,7 +1413,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticVarTwice: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1434,7 +1422,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Fields (val or var) cannot be exported as static more than once + |newSource1.scala:7: error: Fields (val or var) cannot be exported as static more than once | @JSExportStatic("b") | ^ """ @@ -1446,7 +1434,6 @@ class JSExportTest extends DirectTest with TestHelpers { assumeTrue(scala.util.Properties.versionNumberString != "2.12.0") """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1455,7 +1442,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: You may not export a lazy val as static + |newSource1.scala:6: error: You may not export a lazy val as static | @JSExportStatic | ^ """ @@ -1464,7 +1451,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportValAsStaticAndTopLevel: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1474,7 +1460,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Fields (val or var) cannot be exported both as static and at the top-level + |newSource1.scala:7: error: Fields (val or var) cannot be exported both as static and at the top-level | @JSExportTopLevel("foo") | ^ """ @@ -1483,7 +1469,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportVarAsStaticAndTopLevel: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1493,7 +1478,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Fields (val or var) cannot be exported both as static and at the top-level + |newSource1.scala:7: error: Fields (val or var) cannot be exported both as static and at the top-level | @JSExportTopLevel("foo") | ^ """ @@ -1502,7 +1487,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportSetterWithBadSetterType: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1511,7 +1495,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Exported setters must have exactly one argument + |newSource1.scala:6: error: Exported setters must have exactly one argument | @JSExportStatic | ^ """ @@ -1520,7 +1504,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticCollapsingMethods: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1532,7 +1515,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:11: error: Cannot disambiguate overloads for exported method bar with types + |newSource1.scala:10: error: Cannot disambiguate overloads for exported method bar with types | (x: Int)Int | (x: Int)Int | def bar(x: Int): Int = x + 1 @@ -1543,7 +1526,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticCollapsingGetters: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1555,7 +1537,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Duplicate static getter export with name 'foo' + |newSource1.scala:7: error: Duplicate static getter export with name 'foo' | def foo: Int = 1 | ^ """ @@ -1564,7 +1546,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticCollapsingSetters: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1576,7 +1557,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:11: error: Cannot disambiguate overloads for exported method bar_$eq with types + |newSource1.scala:10: error: Cannot disambiguate overloads for exported method bar_$eq with types | (v: Int)Unit | (v: Int)Unit | def bar_=(v: Int): Unit = () @@ -1587,7 +1568,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticFieldsWithSameName: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1599,7 +1579,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Duplicate static export with name 'a': a field may not share its exported name with another field or method + |newSource1.scala:7: error: Duplicate static export with name 'a': a field may not share its exported name with another field or method | val a: Int = 1 | ^ """ @@ -1608,7 +1588,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticFieldsAndMethodsWithSameName: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1620,13 +1599,12 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:10: error: Duplicate static export with name 'a': a field may not share its exported name with another field or method + |newSource1.scala:9: error: Duplicate static export with name 'a': a field may not share its exported name with another field or method | @JSExportStatic("a") | ^ """ """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1638,7 +1616,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Duplicate static export with name 'a': a field may not share its exported name with another field or method + |newSource1.scala:6: error: Duplicate static export with name 'a': a field may not share its exported name with another field or method | @JSExportStatic | ^ """ @@ -1647,7 +1625,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticFieldsAndPropertiesWithSameName: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1659,13 +1636,12 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:10: error: Duplicate static export with name 'a': a field may not share its exported name with another field or method + |newSource1.scala:9: error: Duplicate static export with name 'a': a field may not share its exported name with another field or method | @JSExportStatic("a") | ^ """ """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1677,7 +1653,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Duplicate static export with name 'a': a field may not share its exported name with another field or method + |newSource1.scala:6: error: Duplicate static export with name 'a': a field may not share its exported name with another field or method | @JSExportStatic | ^ """ @@ -1686,7 +1662,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticPropertiesAndMethodsWithSameName: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1698,13 +1673,12 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Exported property a conflicts with b + |newSource1.scala:7: error: Exported property a conflicts with b | def a: Int = 1 | ^ """ """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1716,7 +1690,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Exported method a conflicts with b + |newSource1.scala:7: error: Exported method a conflicts with b | def a(x: Int): Int = x + 1 | ^ """ @@ -1726,7 +1700,6 @@ class JSExportTest extends DirectTest with TestHelpers { def noExportStaticNonStatic: Unit = { """ class A { - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1736,7 +1709,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Only a static object whose companion class is a Scala.js-defined JS class may export its members as static. + |newSource1.scala:7: error: Only a static object whose companion class is a Scala.js-defined JS class may export its members as static. | @JSExportStatic | ^ """ @@ -1745,23 +1718,20 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticInJSModule: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object - @ScalaJSDefined object StaticContainer extends js.Object { @JSExportStatic def a(): Unit = () } """ hasErrors """ - |newSource1.scala:8: error: You may not export a method of a subclass of js.Any + |newSource1.scala:6: error: You may not export a method of a subclass of js.Any | @JSExportStatic | ^ """ """ - @ScalaJSDefined class StaticContainer extends js.Object @js.native @@ -1772,7 +1742,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:9: error: You may not export a method of a subclass of js.Any + |newSource1.scala:8: error: You may not export a method of a subclass of js.Any | @JSExportStatic | ^ """ @@ -1795,7 +1765,6 @@ class JSExportTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined trait StaticContainer extends js.Object object StaticContainer { @@ -1804,7 +1773,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Only a static object whose companion class is a Scala.js-defined JS class may export its members as static. + |newSource1.scala:6: error: Only a static object whose companion class is a Scala.js-defined JS class may export its members as static. | @JSExportStatic | ^ """ @@ -1836,7 +1805,6 @@ class JSExportTest extends DirectTest with TestHelpers { ) } s""" - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1859,10 +1827,10 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:10: error: @JSExportStatic vals and vars must be defined before any other val/var, and before any constructor statement. + |newSource1.scala:9: error: @JSExportStatic vals and vars must be defined before any other val/var, and before any constructor statement. | val b: Int = 1 | ^ - |newSource1.scala:13: error: @JSExportStatic vals and vars must be defined before any other val/var, and before any constructor statement. + |newSource1.scala:12: error: @JSExportStatic vals and vars must be defined before any other val/var, and before any constructor statement. | var c: Int = 1 | ^ """ @@ -1885,7 +1853,6 @@ class JSExportTest extends DirectTest with TestHelpers { ) } s""" - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index 9cebad4c14..0de4d7ca31 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -23,38 +23,6 @@ class JSInteropTest extends DirectTest with TestHelpers { "JSGlobalScope" -> "@JSGlobalScope" ) - @Test - def warnNoJSNativeAnnotation: Unit = { - - """ - class A extends js.Object - """ containsWarns - """ - |newSource1.scala:5: warning: Classes, traits and objects inheriting from js.Any should be annotated with @js.native, unless they have @ScalaJSDefined. The default will switch to Scala.js-defined in the next major version of Scala.js. - | class A extends js.Object - | ^ - """ - - """ - object A extends js.Object - """ containsWarns - """ - |newSource1.scala:5: warning: Classes, traits and objects inheriting from js.Any should be annotated with @js.native, unless they have @ScalaJSDefined. The default will switch to Scala.js-defined in the next major version of Scala.js. - | object A extends js.Object - | ^ - """ - - """ - trait A extends js.Object - """ hasWarns - """ - |newSource1.scala:5: warning: Classes, traits and objects inheriting from js.Any should be annotated with @js.native, unless they have @ScalaJSDefined. The default will switch to Scala.js-defined in the next major version of Scala.js. - | trait A extends js.Object - | ^ - """ - - } - @Test def warnJSPackageObjectDeprecated: Unit = { @@ -69,26 +37,6 @@ class JSInteropTest extends DirectTest with TestHelpers { } - @Test - def noJSNativeAnnotWithSJSDefinedAnnot: Unit = { - - for { - obj <- Seq("class", "trait", "object") - } yield { - s""" - @ScalaJSDefined - @js.native - $obj A extends js.Object - """ hasErrors - s""" - |newSource1.scala:7: error: @ScalaJSDefined and @js.native cannot be used together - | $obj A extends js.Object - | ${" " * obj.length} ^ - """ - } - - } - @Test def noJSNameAnnotOnNonJSNative: Unit = { @@ -96,7 +44,6 @@ class JSInteropTest extends DirectTest with TestHelpers { obj <- Seq("class", "trait", "object") } yield { s""" - @ScalaJSDefined @JSName("foo") $obj A extends js.Object @@ -104,15 +51,14 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym = js.Symbol() } - @ScalaJSDefined @JSName(Sym.sym) $obj B extends js.Object """ hasWarns s""" - |newSource1.scala:6: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. + |newSource1.scala:5: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. | @JSName("foo") | ^ - |newSource1.scala:14: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. + |newSource1.scala:12: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. | @JSName(Sym.sym) | ^ """ @@ -148,33 +94,29 @@ class JSInteropTest extends DirectTest with TestHelpers { def okJSNameOnNestedObjects: Unit = { """ - @ScalaJSDefined class A extends js.Object { @JSName("foo") object toto @JSName("bar") - @ScalaJSDefined object tata extends js.Object } """.hasNoWarns """ - @ScalaJSDefined class A extends js.Object { @JSName("foo") private object toto @JSName("bar") - @ScalaJSDefined private object tata extends js.Object } """ hasWarns """ - |newSource1.scala:7: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. + |newSource1.scala:6: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. | @JSName("foo") | ^ - |newSource1.scala:10: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. + |newSource1.scala:9: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. | @JSName("bar") | ^ """ @@ -188,19 +130,17 @@ class JSInteropTest extends DirectTest with TestHelpers { obj <- Seq("class", "trait", "object") } yield { s""" - @ScalaJSDefined @JSGlobal $obj A extends js.Object - @ScalaJSDefined @JSGlobal("Foo") $obj B extends js.Object """ hasErrors s""" - |newSource1.scala:6: error: Non JS-native classes, traits and objects may not have an @JSGlobal annotation. + |newSource1.scala:5: error: Non JS-native classes, traits and objects may not have an @JSGlobal annotation. | @JSGlobal | ^ - |newSource1.scala:10: error: Non JS-native classes, traits and objects may not have an @JSGlobal annotation. + |newSource1.scala:8: error: Non JS-native classes, traits and objects may not have an @JSGlobal annotation. | @JSGlobal("Foo") | ^ """ @@ -235,12 +175,11 @@ class JSInteropTest extends DirectTest with TestHelpers { obj <- Seq("class", "trait", "object") } yield { s""" - @ScalaJSDefined @JSImport("foo", JSImport.Namespace) $obj A extends js.Object """ hasErrors s""" - |newSource1.scala:6: error: Non JS-native classes, traits and objects may not have an @JSImport annotation. + |newSource1.scala:5: error: Non JS-native classes, traits and objects may not have an @JSImport annotation. | @JSImport("foo", JSImport.Namespace) | ^ """ @@ -461,7 +400,7 @@ class JSInteropTest extends DirectTest with TestHelpers { if (outer == "trait") "" else "@JSGlobal" val innerLine = - if (innerSJSDefined) s"@ScalaJSDefined $inner A extends js.Object" + if (innerSJSDefined) s"$inner A extends js.Object" else s"$inner A" s""" @js.native $jsGlobalAnnot @@ -536,13 +475,13 @@ class JSInteropTest extends DirectTest with TestHelpers { @js.native @JSGlobal object A extends js.Object { - @ScalaJSDefined $inner A extends js.Object + $inner A extends js.Object } """ hasErrors s""" |newSource1.scala:8: error: Native JS objects cannot contain inner Scala.js-defined JS classes or objects - | @ScalaJSDefined $inner A extends js.Object - | ${" " * inner.length} ^ + | $inner A extends js.Object + | ${" " * inner.length} ^ """ } @@ -719,21 +658,19 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined case class A(x: Int) extends js.Object """ hasErrors """ - |newSource1.scala:6: error: Classes and objects extending js.Any may not have a case modifier + |newSource1.scala:5: error: Classes and objects extending js.Any may not have a case modifier | case class A(x: Int) extends js.Object | ^ """ """ - @ScalaJSDefined case object B extends js.Object """ hasErrors """ - |newSource1.scala:6: error: Classes and objects extending js.Any may not have a case modifier + |newSource1.scala:5: error: Classes and objects extending js.Any may not have a case modifier | case object B extends js.Object | ^ """ @@ -752,7 +689,7 @@ class JSInteropTest extends DirectTest with TestHelpers { outerSJSDefined <- Seq(false, true) } yield { val outerLine = - if (outerSJSDefined) s"@ScalaJSDefined $outer A extends js.Object" + if (outerSJSDefined) s"$outer A extends js.Object" else s"$outer A" val jsGlobalAnnot = @@ -800,31 +737,28 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined class A extends js.Object with js.GlobalScope """ hasErrors """ - |newSource1.scala:6: error: A Scala.js-defined JS class cannot directly extend a native JS trait. + |newSource1.scala:5: error: A Scala.js-defined JS class cannot directly extend a native JS trait. | class A extends js.Object with js.GlobalScope | ^ """ """ - @ScalaJSDefined trait A extends js.Object with js.GlobalScope """ hasErrors """ - |newSource1.scala:6: error: A Scala.js-defined JS trait cannot directly extend a native JS trait. + |newSource1.scala:5: error: A Scala.js-defined JS trait cannot directly extend a native JS trait. | trait A extends js.Object with js.GlobalScope | ^ """ """ - @ScalaJSDefined object A extends js.Object with js.GlobalScope """ hasErrors """ - |newSource1.scala:6: error: A Scala.js-defined JS object cannot directly extend a native JS trait. + |newSource1.scala:5: error: A Scala.js-defined JS object cannot directly extend a native JS trait. | object A extends js.Object with js.GlobalScope | ^ """ @@ -1301,7 +1235,6 @@ class JSInteropTest extends DirectTest with TestHelpers { inner <- Seq("class", "object") } { s""" - @ScalaJSDefined object A extends js.Object { @js.native @JSGlobal @@ -1309,7 +1242,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } """ hasErrors s""" - |newSource1.scala:9: error: Scala.js-defined JS objects may not have inner native JS classes or objects + |newSource1.scala:8: error: Scala.js-defined JS objects may not have inner native JS classes or objects | $inner B extends js.Object | ${" " * inner.length} ^ """ @@ -1397,7 +1330,6 @@ class JSInteropTest extends DirectTest with TestHelpers { def bar: Int = js.native } - @ScalaJSDefined class C extends js.Object { @JSName(js.Symbol()) def foo: Int = js.native @@ -1412,10 +1344,10 @@ class JSInteropTest extends DirectTest with TestHelpers { |newSource1.scala:16: error: A js.Symbol argument to JSName must be a static, stable identifier | @JSName(new A().a) | ^ - |newSource1.scala:22: error: A js.Symbol argument to JSName must be a static, stable identifier + |newSource1.scala:21: error: A js.Symbol argument to JSName must be a static, stable identifier | @JSName(js.Symbol()) | ^ - |newSource1.scala:24: error: A js.Symbol argument to JSName must be a static, stable identifier + |newSource1.scala:23: error: A js.Symbol argument to JSName must be a static, stable identifier | @JSName(new A().a) | ^ """ @@ -1426,7 +1358,6 @@ class JSInteropTest extends DirectTest with TestHelpers { def noSelfReferenceJSNameSymbol: Unit = { """ - @ScalaJSDefined object A extends js.Object { val a = js.Symbol("foo") @@ -1435,7 +1366,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } """ hasWarns """ - |newSource1.scala:9: warning: This symbol is defined in the same object as the annotation's target. This will cause a stackoverflow at runtime + |newSource1.scala:8: warning: This symbol is defined in the same object as the annotation's target. This will cause a stackoverflow at runtime | @JSName(a) | ^ """ @@ -1904,23 +1835,19 @@ class JSInteropTest extends DirectTest with TestHelpers { @Test def scalaJSDefinedJSNameOverrideWarnings: Unit = { """ - @ScalaJSDefined abstract class A extends js.Object { def bar(): Int } - @ScalaJSDefined class B extends A { override def bar() = 1 } """.hasNoWarns """ - @ScalaJSDefined trait A extends js.Object { @JSName("foo") def bar(): Int } - @ScalaJSDefined class B extends A { @JSName("foo") override def bar() = 1 @@ -1928,12 +1855,10 @@ class JSInteropTest extends DirectTest with TestHelpers { """.hasNoWarns """ - @ScalaJSDefined abstract class A extends js.Object { @JSName("foo") def bar(): Int } - @ScalaJSDefined class B extends A { @JSName("foo") override def bar() = 1 @@ -1941,19 +1866,17 @@ class JSInteropTest extends DirectTest with TestHelpers { """.hasNoWarns """ - @ScalaJSDefined abstract class A extends js.Object { @JSName("foo") def bar(): Int } - @ScalaJSDefined class B extends A { @JSName("baz") override def bar() = 1 } """ hasWarns """ - |newSource1.scala:13: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:11: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): Int in class B with JSName 'baz' | is conflicting with @@ -1964,18 +1887,16 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined abstract class A extends js.Object { @JSName("foo") def bar(): Int } - @ScalaJSDefined class B extends A { override def bar() = 1 } """ hasWarns """ - |newSource1.scala:12: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): Int in class B with JSName 'bar' | is conflicting with @@ -1986,22 +1907,19 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined abstract class A extends js.Object { @JSName("foo") def bar(): Object } - @ScalaJSDefined abstract class B extends A { override def bar(): String } - @ScalaJSDefined class C extends B { override def bar() = "1" } """ hasWarns """ - |newSource1.scala:12: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): String in class B with JSName 'bar' | is conflicting with @@ -2009,7 +1927,7 @@ class JSInteropTest extends DirectTest with TestHelpers { | | override def bar(): String | ^ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:13: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): String in class C with JSName 'bar' | is conflicting with @@ -2020,22 +1938,19 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined abstract class A extends js.Object { def bar(): Object } - @ScalaJSDefined abstract class B extends A { @JSName("foo") override def bar(): String } - @ScalaJSDefined class C extends B { override def bar() = "1" } """ hasWarns """ - |newSource1.scala:12: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): String in class B with JSName 'foo' | is conflicting with @@ -2043,7 +1958,7 @@ class JSInteropTest extends DirectTest with TestHelpers { | | override def bar(): String | ^ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:13: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): String in class C with JSName 'bar' | is conflicting with @@ -2054,20 +1969,17 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined class A extends js.Object { def foo: Int = 5 } - @ScalaJSDefined trait B extends A { @JSName("bar") def foo: Int } - @ScalaJSDefined class C extends B """ hasWarns """ - |newSource1.scala:12: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. | |def foo: Int in class A with JSName 'foo' | is conflicting with @@ -2078,20 +1990,17 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined class A extends js.Object { @JSName("bar") def foo: Int = 5 } - @ScalaJSDefined trait B extends A { def foo: Int } - @ScalaJSDefined class C extends B """ hasWarns """ - |newSource1.scala:12: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. | |def foo: Int in class A with JSName 'bar' | is conflicting with @@ -2102,18 +2011,16 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined class A[T] extends js.Object { @JSName("bar") def foo(x: T): T = x } - @ScalaJSDefined class B extends A[Int] { override def foo(x: Int): Int = x } """ hasWarns """ - |newSource1.scala:12: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. | |override def foo(x: Int): Int in class B with JSName 'foo' | is conflicting with @@ -2124,18 +2031,16 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined trait A[T] extends js.Object { @JSName("bar") def foo(x: T): T } - @ScalaJSDefined class B extends A[Int] { override def foo(x: Int): Int = x } """ hasWarns """ - |newSource1.scala:12: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. | |override def foo(x: Int): Int in class B with JSName 'foo' | is conflicting with @@ -2146,22 +2051,19 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined class A[T] extends js.Object { @JSName("bar") def foo(x: T): T = x } - @ScalaJSDefined trait B extends A[Int] { def foo(x: Int): Int } - @ScalaJSDefined class C extends B { override def foo(x: Int): Int = x } """ hasWarns """ - |newSource1.scala:12: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. | |def foo(x: Int): Int in class A with JSName 'bar' | is conflicting with @@ -2169,7 +2071,7 @@ class JSInteropTest extends DirectTest with TestHelpers { | | def foo(x: Int): Int | ^ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:13: warning: A member of a JS class is overriding another member with a different JS name. | |override def foo(x: Int): Int in class C with JSName 'foo' | is conflicting with @@ -2180,22 +2082,19 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined class A[T] extends js.Object { def foo(x: T): T = x } - @ScalaJSDefined trait B extends A[Int] { @JSName("bar") def foo(x: Int): Int } - @ScalaJSDefined class C extends B { override def foo(x: Int): Int = x } """ hasWarns """ - |newSource1.scala:12: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. | |def foo(x: Int): Int in class A with JSName 'foo' | is conflicting with @@ -2203,7 +2102,7 @@ class JSInteropTest extends DirectTest with TestHelpers { | | def foo(x: Int): Int | ^ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:13: warning: A member of a JS class is overriding another member with a different JS name. | |override def foo(x: Int): Int in class C with JSName 'foo' | is conflicting with @@ -2214,20 +2113,17 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined trait A extends js.Object { def foo: Int } - @ScalaJSDefined trait B extends js.Object { @JSName("bar") def foo: Int } - @ScalaJSDefined trait C extends A with B """ hasWarns """ - |newSource1.scala:15: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:12: warning: A member of a JS class is overriding another member with a different JS name. | |def foo: Int in trait B with JSName 'bar' | is conflicting with @@ -2238,20 +2134,17 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined trait A extends js.Object { def foo: Int } - @ScalaJSDefined trait B extends js.Object { @JSName("bar") def foo: Int } - @ScalaJSDefined abstract class C extends A with B """ hasWarns """ - |newSource1.scala:15: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:12: warning: A member of a JS class is overriding another member with a different JS name. | |def foo: Int in trait B with JSName 'bar' | is conflicting with @@ -2269,12 +2162,10 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined trait A extends js.Object { @JSName(Syms.sym1) def bar(): Int } - @ScalaJSDefined class B extends A { @JSName(Syms.sym1) override def bar() = 1 @@ -2286,12 +2177,10 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined abstract class A extends js.Object { @JSName(Syms.sym1) def bar(): Int } - @ScalaJSDefined class B extends A { @JSName(Syms.sym1) override def bar() = 1 @@ -2304,19 +2193,17 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym2 = js.Symbol() } - @ScalaJSDefined abstract class A extends js.Object { @JSName(Syms.sym1) def bar(): Int } - @ScalaJSDefined class B extends A { @JSName(Syms.sym2) override def bar() = 1 } """ hasWarns """ - |newSource1.scala:18: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): Int in class B with JSName 'Syms.sym2' | is conflicting with @@ -2331,19 +2218,17 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined abstract class A extends js.Object { @JSName(Syms.sym1) def bar(): Int } - @ScalaJSDefined class B extends A { @JSName("baz") override def bar() = 1 } """ hasWarns """ - |newSource1.scala:17: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:15: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): Int in class B with JSName 'baz' | is conflicting with @@ -2358,19 +2243,17 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined abstract class A extends js.Object { @JSName("foo") def bar(): Int } - @ScalaJSDefined class B extends A { @JSName(Syms.sym1) override def bar() = 1 } """ hasWarns """ - |newSource1.scala:17: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:15: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): Int in class B with JSName 'Syms.sym1' | is conflicting with @@ -2385,18 +2268,16 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined abstract class A extends js.Object { @JSName(Syms.sym1) def bar(): Int } - @ScalaJSDefined class B extends A { override def bar() = 1 } """ hasWarns """ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): Int in class B with JSName 'bar' | is conflicting with @@ -2411,22 +2292,19 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined abstract class A extends js.Object { @JSName(Syms.sym1) def bar(): Object } - @ScalaJSDefined abstract class B extends A { override def bar(): String } - @ScalaJSDefined class C extends B { override def bar() = "1" } """ hasWarns """ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): String in class B with JSName 'bar' | is conflicting with @@ -2434,7 +2312,7 @@ class JSInteropTest extends DirectTest with TestHelpers { | | override def bar(): String | ^ - |newSource1.scala:20: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:17: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): String in class C with JSName 'bar' | is conflicting with @@ -2449,22 +2327,19 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined abstract class A extends js.Object { def bar(): Object } - @ScalaJSDefined abstract class B extends A { @JSName(Syms.sym1) override def bar(): String } - @ScalaJSDefined class C extends B { override def bar() = "1" } """ hasWarns """ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): String in class B with JSName 'Syms.sym1' | is conflicting with @@ -2472,7 +2347,7 @@ class JSInteropTest extends DirectTest with TestHelpers { | | override def bar(): String | ^ - |newSource1.scala:20: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:17: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): String in class C with JSName 'bar' | is conflicting with @@ -2487,20 +2362,17 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined class A extends js.Object { def foo: Int = 5 } - @ScalaJSDefined trait B extends A { @JSName(Syms.sym1) def foo: Int } - @ScalaJSDefined class C extends B """ hasWarns """ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. | |def foo: Int in class A with JSName 'foo' | is conflicting with @@ -2515,20 +2387,17 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined class A extends js.Object { @JSName(Syms.sym1) def foo: Int = 5 } - @ScalaJSDefined trait B extends A { def foo: Int } - @ScalaJSDefined class C extends B """ hasWarns """ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. | |def foo: Int in class A with JSName 'Syms.sym1' | is conflicting with @@ -2543,18 +2412,16 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined class A[T] extends js.Object { @JSName(Syms.sym1) def foo(x: T): T = x } - @ScalaJSDefined class B extends A[Int] { override def foo(x: Int): Int = x } """ hasWarns """ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. | |override def foo(x: Int): Int in class B with JSName 'foo' | is conflicting with @@ -2569,18 +2436,16 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined trait A[T] extends js.Object { @JSName(Syms.sym1) def foo(x: T): T } - @ScalaJSDefined class B extends A[Int] { override def foo(x: Int): Int = x } """ hasWarns """ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. | |override def foo(x: Int): Int in class B with JSName 'foo' | is conflicting with @@ -2595,22 +2460,19 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined class A[T] extends js.Object { @JSName(Syms.sym1) def foo(x: T): T = x } - @ScalaJSDefined trait B extends A[Int] { def foo(x: Int): Int } - @ScalaJSDefined class C extends B { override def foo(x: Int): Int = x } """ hasWarns """ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. | |def foo(x: Int): Int in class A with JSName 'Syms.sym1' | is conflicting with @@ -2618,7 +2480,7 @@ class JSInteropTest extends DirectTest with TestHelpers { | | def foo(x: Int): Int | ^ - |newSource1.scala:20: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:17: warning: A member of a JS class is overriding another member with a different JS name. | |override def foo(x: Int): Int in class C with JSName 'foo' | is conflicting with @@ -2633,22 +2495,19 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined class A[T] extends js.Object { def foo(x: T): T = x } - @ScalaJSDefined trait B extends A[Int] { @JSName(Syms.sym1) def foo(x: Int): Int } - @ScalaJSDefined class C extends B { override def foo(x: Int): Int = x } """ hasWarns """ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. | |def foo(x: Int): Int in class A with JSName 'foo' | is conflicting with @@ -2656,7 +2515,7 @@ class JSInteropTest extends DirectTest with TestHelpers { | | def foo(x: Int): Int | ^ - |newSource1.scala:20: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:17: warning: A member of a JS class is overriding another member with a different JS name. | |override def foo(x: Int): Int in class C with JSName 'foo' | is conflicting with @@ -2671,20 +2530,17 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined trait A extends js.Object { def foo: Int } - @ScalaJSDefined trait B extends js.Object { @JSName(Syms.sym1) def foo: Int } - @ScalaJSDefined trait C extends A with B """ hasWarns """ - |newSource1.scala:19: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. | |def foo: Int in trait B with JSName 'Syms.sym1' | is conflicting with @@ -2699,20 +2555,17 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined trait A extends js.Object { def foo: Int } - @ScalaJSDefined trait B extends js.Object { @JSName(Syms.sym1) def foo: Int } - @ScalaJSDefined abstract class C extends A with B """ hasWarns """ - |newSource1.scala:19: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. | |def foo: Int in trait B with JSName 'Syms.sym1' | is conflicting with @@ -2726,7 +2579,6 @@ class JSInteropTest extends DirectTest with TestHelpers { @Test def noDefaultConstructorArgsIfModuleIsJSNative: Unit = { """ - @ScalaJSDefined class A(x: Int = 1) extends js.Object @js.native @@ -2734,7 +2586,7 @@ class JSInteropTest extends DirectTest with TestHelpers { object A extends js.Object """ hasErrors """ - |newSource1.scala:6: error: Implementation restriction: constructors of Scala.js-defined JS classes cannot have default parameters if their companion module is JS native. + |newSource1.scala:5: error: Implementation restriction: constructors of Scala.js-defined JS classes cannot have default parameters if their companion module is JS native. | class A(x: Int = 1) extends js.Object | ^ """ @@ -2761,13 +2613,12 @@ class JSInteropTest extends DirectTest with TestHelpers { class NativeBase extends js.Object { def add(option: js.Any = js.native): js.Any = js.native } - @ScalaJSDefined class Derived extends NativeBase { override def add(option: js.Any): js.Any = super.add(option) } """ hasErrors """ - |newSource1.scala:12: error: When overriding a native method with default arguments, the overriding method must explicitly repeat the default arguments. + |newSource1.scala:11: error: When overriding a native method with default arguments, the overriding method must explicitly repeat the default arguments. | override def add(option: js.Any): js.Any = super.add(option) | ^ """ @@ -2782,13 +2633,12 @@ class JSInteropTest extends DirectTest with TestHelpers { @JSGlobal class NativeBase extends NativeTrait - @ScalaJSDefined class Derived extends NativeBase { override def add(option: js.Any): js.Any = super.add(option) } """ hasErrors """ - |newSource1.scala:16: error: When overriding a native method with default arguments, the overriding method must explicitly repeat the default arguments. + |newSource1.scala:15: error: When overriding a native method with default arguments, the overriding method must explicitly repeat the default arguments. | override def add(option: js.Any): js.Any = super.add(option) | ^ """ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala index 3de7da1cfc..4b320c3d7e 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala @@ -19,7 +19,6 @@ class JSOptionalTest extends DirectTest with TestHelpers { @Test def optionalRequiresUndefinedRHS: Unit = { s""" - @ScalaJSDefined trait A extends js.Object { val a1: js.UndefOr[Int] = 5 val a2: Int = 5 @@ -32,22 +31,22 @@ class JSOptionalTest extends DirectTest with TestHelpers { } """ hasErrors s""" - |newSource1.scala:7: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. + |newSource1.scala:6: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. | val a1: js.UndefOr[Int] = 5 | ^ - |newSource1.scala:8: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. + |newSource1.scala:7: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. | val a2: Int = 5 | ^ - |newSource1.scala:10: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. + |newSource1.scala:9: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. | def b1: js.UndefOr[Int] = 5 | ^ - |newSource1.scala:11: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. + |newSource1.scala:10: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. | def b2: Int = 5 | ^ - |newSource1.scala:13: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. + |newSource1.scala:12: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. | var c1: js.UndefOr[Int] = 5 | ^ - |newSource1.scala:14: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. + |newSource1.scala:13: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. | var c2: Int = 5 | ^ """ @@ -56,7 +55,6 @@ class JSOptionalTest extends DirectTest with TestHelpers { @Test def noOverrideConcreteNonOptionalWithOptional: Unit = { s""" - @ScalaJSDefined abstract class A extends js.Object { val a1: js.UndefOr[Int] = 5 val a2: js.UndefOr[Int] @@ -65,7 +63,6 @@ class JSOptionalTest extends DirectTest with TestHelpers { def b2: js.UndefOr[Int] } - @ScalaJSDefined trait B extends A { override val a1: js.UndefOr[Int] = js.undefined override val a2: js.UndefOr[Int] = js.undefined @@ -75,10 +72,10 @@ class JSOptionalTest extends DirectTest with TestHelpers { } """ hasErrors s""" - |newSource1.scala:16: error: Cannot override concrete val a1: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + |newSource1.scala:14: error: Cannot override concrete val a1: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. | override val a1: js.UndefOr[Int] = js.undefined | ^ - |newSource1.scala:19: error: Cannot override concrete def b1: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + |newSource1.scala:17: error: Cannot override concrete def b1: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. | override def b1: js.UndefOr[Int] = js.undefined | ^ """ @@ -91,17 +88,16 @@ class JSOptionalTest extends DirectTest with TestHelpers { def b: js.UndefOr[Int] = js.native } - @ScalaJSDefined trait B extends A { override val a: js.UndefOr[Int] = js.undefined override def b: js.UndefOr[Int] = js.undefined } """ hasErrors s""" - |newSource1.scala:14: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + |newSource1.scala:13: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. | override val a: js.UndefOr[Int] = js.undefined | ^ - |newSource1.scala:15: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + |newSource1.scala:14: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. | override def b: js.UndefOr[Int] = js.undefined | ^ """ @@ -117,17 +113,16 @@ class JSOptionalTest extends DirectTest with TestHelpers { @JSGlobal class B extends A - @ScalaJSDefined trait C extends B { override val a: js.UndefOr[Int] = js.undefined override def b: js.UndefOr[Int] = js.undefined } """ hasErrors s""" - |newSource1.scala:17: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + |newSource1.scala:16: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. | override val a: js.UndefOr[Int] = js.undefined | ^ - |newSource1.scala:18: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + |newSource1.scala:17: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. | override def b: js.UndefOr[Int] = js.undefined | ^ """ @@ -136,7 +131,6 @@ class JSOptionalTest extends DirectTest with TestHelpers { @Test def noOptionalDefWithParens: Unit = { s""" - @ScalaJSDefined trait A extends js.Object { def a(): js.UndefOr[Int] = js.undefined def b(x: Int): js.UndefOr[Int] = js.undefined @@ -144,16 +138,16 @@ class JSOptionalTest extends DirectTest with TestHelpers { } """ hasErrors s""" - |newSource1.scala:7: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. + |newSource1.scala:6: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. | def a(): js.UndefOr[Int] = js.undefined | ^ - |newSource1.scala:8: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. + |newSource1.scala:7: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. | def b(x: Int): js.UndefOr[Int] = js.undefined | ^ - |newSource1.scala:9: error: Raw JS setters must return Unit + |newSource1.scala:8: error: Raw JS setters must return Unit | def c_=(v: Int): js.UndefOr[Int] = js.undefined | ^ - |newSource1.scala:9: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. + |newSource1.scala:8: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. | def c_=(v: Int): js.UndefOr[Int] = js.undefined | ^ """ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala index 0188aa3096..1acdadd6cc 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala @@ -214,7 +214,6 @@ class OptimizationTest extends JSASTTest { import scala.scalajs.js import scala.scalajs.js.annotation._ - @ScalaJSDefined trait Point extends js.Object { val x: Double val y: Double @@ -238,7 +237,6 @@ class OptimizationTest extends JSASTTest { import scala.scalajs.js import scala.scalajs.js.annotation._ - @ScalaJSDefined trait Point extends js.Object { var x: js.UndefOr[Double] = js.undefined var y: js.UndefOr[Double] = js.undefined diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/ReflectTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/ReflectTest.scala index 5f985f77bc..93859def11 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/ReflectTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/ReflectTest.scala @@ -16,15 +16,12 @@ class ReflectTest extends DirectTest with TestHelpers { def noEnableReflectiveInstantiationOnJSType: Unit = { """ @EnableReflectiveInstantiation - @ScalaJSDefined class A extends js.Object @EnableReflectiveInstantiation - @ScalaJSDefined trait B extends js.Object @EnableReflectiveInstantiation - @ScalaJSDefined object C extends js.Object @EnableReflectiveInstantiation @@ -45,19 +42,19 @@ class ReflectTest extends DirectTest with TestHelpers { |newSource1.scala:4: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. | @EnableReflectiveInstantiation | ^ - |newSource1.scala:8: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. + |newSource1.scala:7: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. | @EnableReflectiveInstantiation | ^ - |newSource1.scala:12: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. + |newSource1.scala:10: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. | @EnableReflectiveInstantiation | ^ - |newSource1.scala:16: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. + |newSource1.scala:13: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. | @EnableReflectiveInstantiation | ^ - |newSource1.scala:21: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. + |newSource1.scala:18: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. | @EnableReflectiveInstantiation | ^ - |newSource1.scala:25: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. + |newSource1.scala:22: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. | @EnableReflectiveInstantiation | ^ """ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala index 20d73829fb..e34781ad1a 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala @@ -18,43 +18,22 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { import scala.scalajs.js.annotation._ """ - @Test - def noSJSDefinedOnScalaEntity: Unit = { - val objs = List("class", "trait", "object") - - for { - obj <- objs - } { - s""" - @ScalaJSDefined - $obj A - """ hasErrors - s""" - |newSource1.scala:6: error: @ScalaJSDefined is only allowed on classes extending js.Any - | $obj A - | ${" " * obj.length}^ - """ - } - } - @Test def noExtendAnyRef: Unit = { """ - @ScalaJSDefined class A extends js.Any """ hasErrors """ - |newSource1.scala:6: error: A Scala.js-defined JS class cannot directly extend AnyRef. It must extend a JS class (native or not). + |newSource1.scala:5: error: A Scala.js-defined JS class cannot directly extend AnyRef. It must extend a JS class (native or not). | class A extends js.Any | ^ """ """ - @ScalaJSDefined object A extends js.Any """ hasErrors """ - |newSource1.scala:6: error: A Scala.js-defined JS object cannot directly extend AnyRef. It must extend a JS class (native or not). + |newSource1.scala:5: error: A Scala.js-defined JS object cannot directly extend AnyRef. It must extend a JS class (native or not). | object A extends js.Any | ^ """ @@ -66,13 +45,10 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { @js.native trait NativeTrait extends js.Object - @ScalaJSDefined class A extends NativeTrait - @ScalaJSDefined trait B extends NativeTrait - @ScalaJSDefined object C extends NativeTrait object Container { @@ -80,16 +56,16 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:9: error: A Scala.js-defined JS class cannot directly extend a native JS trait. + |newSource1.scala:8: error: A Scala.js-defined JS class cannot directly extend a native JS trait. | class A extends NativeTrait | ^ - |newSource1.scala:12: error: A Scala.js-defined JS trait cannot directly extend a native JS trait. + |newSource1.scala:10: error: A Scala.js-defined JS trait cannot directly extend a native JS trait. | trait B extends NativeTrait | ^ - |newSource1.scala:15: error: A Scala.js-defined JS object cannot directly extend a native JS trait. + |newSource1.scala:12: error: A Scala.js-defined JS object cannot directly extend a native JS trait. | object C extends NativeTrait | ^ - |newSource1.scala:18: error: A Scala.js-defined JS class cannot directly extend a native JS trait. + |newSource1.scala:15: error: A Scala.js-defined JS class cannot directly extend a native JS trait. | val x = new NativeTrait {} | ^ """ @@ -98,13 +74,12 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { @Test def noApplyMethod: Unit = { """ - @ScalaJSDefined class A extends js.Object { def apply(arg: Int): Int = arg } """ hasErrors """ - |newSource1.scala:7: error: A Scala.js-defined JavaScript class cannot declare a method named `apply` without `@JSName` + |newSource1.scala:6: error: A Scala.js-defined JavaScript class cannot declare a method named `apply` without `@JSName` | def apply(arg: Int): Int = arg | ^ """ @@ -113,14 +88,13 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { @Test def noBracketAccess: Unit = { """ - @ScalaJSDefined class A extends js.Object { @JSBracketAccess def foo(index: Int, arg: Int): Int = arg } """ hasErrors """ - |newSource1.scala:8: error: @JSBracketAccess is not allowed in Scala.js-defined JS classes + |newSource1.scala:7: error: @JSBracketAccess is not allowed in Scala.js-defined JS classes | def foo(index: Int, arg: Int): Int = arg | ^ """ @@ -129,14 +103,13 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { @Test def noBracketCall: Unit = { """ - @ScalaJSDefined class A extends js.Object { @JSBracketCall def foo(m: String, arg: Int): Int = arg } """ hasErrors """ - |newSource1.scala:8: error: @JSBracketCall is not allowed in Scala.js-defined JS classes + |newSource1.scala:7: error: @JSBracketCall is not allowed in Scala.js-defined JS classes | def foo(m: String, arg: Int): Int = arg | ^ """ @@ -145,40 +118,37 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { @Test def noOverloadedPrivate: Unit = { """ - @ScalaJSDefined class A extends js.Object { private def foo(i: Int): Int = i private def foo(s: String): String = s } """ hasErrors """ - |newSource1.scala:7: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. + |newSource1.scala:6: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. | private def foo(i: Int): Int = i | ^ - |newSource1.scala:8: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. + |newSource1.scala:7: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. | private def foo(s: String): String = s | ^ """ """ - @ScalaJSDefined object A extends js.Object { private def foo(i: Int): Int = i private def foo(s: String): String = s } """ hasErrors """ - |newSource1.scala:7: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. + |newSource1.scala:6: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. | private def foo(i: Int): Int = i | ^ - |newSource1.scala:8: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. + |newSource1.scala:7: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. | private def foo(s: String): String = s | ^ """ """ object Enclosing { - @ScalaJSDefined class A extends js.Object { private[Enclosing] def foo(i: Int): Int = i private def foo(s: String): String = s @@ -186,30 +156,28 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. + |newSource1.scala:7: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. | private[Enclosing] def foo(i: Int): Int = i | ^ - |newSource1.scala:9: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. + |newSource1.scala:8: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. | private def foo(s: String): String = s | ^ """ """ - @ScalaJSDefined class A extends js.Object { private def foo(i: Int): Int = i def foo(s: String): String = s } """ hasErrors """ - |newSource1.scala:7: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. + |newSource1.scala:6: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. | private def foo(i: Int): Int = i | ^ """ """ object Enclosing { - @ScalaJSDefined class A extends js.Object { private[Enclosing] def foo(i: Int): Int = i def foo(s: String): String = s @@ -217,7 +185,7 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. + |newSource1.scala:7: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. | private[Enclosing] def foo(i: Int): Int = i | ^ """ @@ -227,34 +195,31 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { def noVirtualQualifiedPrivate: Unit = { """ object Enclosing { - @ScalaJSDefined class A extends js.Object { private[Enclosing] def foo(i: Int): Int = i private[Enclosing] val x: Int = 3 private[Enclosing] var y: Int = 5 } - @ScalaJSDefined class B extends A { override private[Enclosing] final def foo(i: Int): Int = i + 1 } } """ hasErrors """ - |newSource1.scala:8: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:7: error: Qualified private members in Scala.js-defined JS classes must be final | private[Enclosing] def foo(i: Int): Int = i | ^ - |newSource1.scala:9: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:8: error: Qualified private members in Scala.js-defined JS classes must be final | private[Enclosing] val x: Int = 3 | ^ - |newSource1.scala:10: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:9: error: Qualified private members in Scala.js-defined JS classes must be final | private[Enclosing] var y: Int = 5 | ^ """ """ object Enclosing { - @ScalaJSDefined object A extends js.Object { private[Enclosing] def foo(i: Int): Int = i private[Enclosing] val x: Int = 3 @@ -263,47 +228,44 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:7: error: Qualified private members in Scala.js-defined JS classes must be final | private[Enclosing] def foo(i: Int): Int = i | ^ - |newSource1.scala:9: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:8: error: Qualified private members in Scala.js-defined JS classes must be final | private[Enclosing] val x: Int = 3 | ^ - |newSource1.scala:10: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:9: error: Qualified private members in Scala.js-defined JS classes must be final | private[Enclosing] var y: Int = 5 | ^ """ """ object Enclosing { - @ScalaJSDefined abstract class A extends js.Object { private[Enclosing] def foo(i: Int): Int private[Enclosing] val x: Int private[Enclosing] var y: Int } - @ScalaJSDefined class B extends A { override private[Enclosing] final def foo(i: Int): Int = i + 1 } } """ hasErrors """ - |newSource1.scala:8: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:7: error: Qualified private members in Scala.js-defined JS classes must be final | private[Enclosing] def foo(i: Int): Int | ^ - |newSource1.scala:9: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:8: error: Qualified private members in Scala.js-defined JS classes must be final | private[Enclosing] val x: Int | ^ - |newSource1.scala:10: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:9: error: Qualified private members in Scala.js-defined JS classes must be final | private[Enclosing] var y: Int | ^ """ """ object Enclosing { - @ScalaJSDefined trait A extends js.Object { private[Enclosing] def foo(i: Int): Int private[Enclosing] val x: Int @@ -312,33 +274,29 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:7: error: Qualified private members in Scala.js-defined JS classes must be final | private[Enclosing] def foo(i: Int): Int | ^ - |newSource1.scala:9: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:8: error: Qualified private members in Scala.js-defined JS classes must be final | private[Enclosing] val x: Int | ^ - |newSource1.scala:10: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:9: error: Qualified private members in Scala.js-defined JS classes must be final | private[Enclosing] var y: Int | ^ """ """ object Enclosing { - @ScalaJSDefined class A private () extends js.Object - @ScalaJSDefined class B private[this] () extends js.Object - @ScalaJSDefined class C private[Enclosing] () extends js.Object } """.succeeds """ object Enclosing { - @ScalaJSDefined class A extends js.Object { final private[Enclosing] def foo(i: Int): Int = i } @@ -347,7 +305,6 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { """ object Enclosing { - @ScalaJSDefined class A extends js.Object { private def foo(i: Int): Int = i private[this] def bar(i: Int): Int = i + 1 @@ -357,7 +314,6 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { """ object Enclosing { - @ScalaJSDefined object A extends js.Object { final private[Enclosing] def foo(i: Int): Int = i } @@ -366,7 +322,6 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { """ object Enclosing { - @ScalaJSDefined object A extends js.Object { private def foo(i: Int): Int = i private[this] def bar(i: Int): Int = i + 1 @@ -376,28 +331,26 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { """ object Enclosing { - @ScalaJSDefined abstract class A extends js.Object { final private[Enclosing] def foo(i: Int): Int } } """ hasErrors """ - |newSource1.scala:8: error: abstract member may not have final modifier + |newSource1.scala:7: error: abstract member may not have final modifier | final private[Enclosing] def foo(i: Int): Int | ^ """ """ object Enclosing { - @ScalaJSDefined trait A extends js.Object { final private[Enclosing] def foo(i: Int): Int } } """ hasErrors """ - |newSource1.scala:8: error: abstract member may not have final modifier + |newSource1.scala:7: error: abstract member may not have final modifier | final private[Enclosing] def foo(i: Int): Int | ^ """ @@ -406,25 +359,23 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { @Test def noUseJsNative: Unit = { """ - @ScalaJSDefined class A extends js.Object { def foo = js.native } """ hasErrors """ - |newSource1.scala:7: error: js.native may only be used as stub implementation in facade types + |newSource1.scala:6: error: js.native may only be used as stub implementation in facade types | def foo = js.native | ^ """ """ - @ScalaJSDefined object A extends js.Object { def foo = js.native } """ hasErrors """ - |newSource1.scala:7: error: js.native may only be used as stub implementation in facade types + |newSource1.scala:6: error: js.native may only be used as stub implementation in facade types | def foo = js.native | ^ """ @@ -451,7 +402,6 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { final val b = "World" } - @ScalaJSDefined class B extends js.Object { @JSName(A.a) def foo: Int = 5 @@ -460,7 +410,7 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:12: error: A string argument to JSName must be a literal string + |newSource1.scala:11: error: A string argument to JSName must be a literal string | @JSName(A.a) | ^ """ @@ -471,7 +421,6 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { final val b = "World" } - @ScalaJSDefined object B extends js.Object { @JSName(A.a) def foo: Int = 5 @@ -480,7 +429,7 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:12: error: A string argument to JSName must be a literal string + |newSource1.scala:11: error: A string argument to JSName must be a literal string | @JSName(A.a) | ^ """ @@ -491,19 +440,17 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { // def apply """ - @ScalaJSDefined class A extends js.Object { def apply: Int = 42 } """ hasErrors """ - |newSource1.scala:7: error: A member named apply represents function application in JavaScript. A parameterless member should be exported as a property. You must add @JSName("apply") + |newSource1.scala:6: error: A member named apply represents function application in JavaScript. A parameterless member should be exported as a property. You must add @JSName("apply") | def apply: Int = 42 | ^ """ """ - @ScalaJSDefined class A extends js.Object { @JSName("apply") def apply: Int = 42 @@ -513,19 +460,17 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { // val apply """ - @ScalaJSDefined class A extends js.Object { val apply: Int = 42 } """ hasErrors """ - |newSource1.scala:7: error: A member named apply represents function application in JavaScript. A parameterless member should be exported as a property. You must add @JSName("apply") + |newSource1.scala:6: error: A member named apply represents function application in JavaScript. A parameterless member should be exported as a property. You must add @JSName("apply") | val apply: Int = 42 | ^ """ """ - @ScalaJSDefined class A extends js.Object { @JSName("apply") val apply: Int = 42 @@ -535,19 +480,17 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { // var apply """ - @ScalaJSDefined class A extends js.Object { var apply: Int = 42 } """ hasErrors """ - |newSource1.scala:7: error: A member named apply represents function application in JavaScript. A parameterless member should be exported as a property. You must add @JSName("apply") + |newSource1.scala:6: error: A member named apply represents function application in JavaScript. A parameterless member should be exported as a property. You must add @JSName("apply") | var apply: Int = 42 | ^ """ """ - @ScalaJSDefined class A extends js.Object { @JSName("apply") var apply: Int = 42 @@ -558,36 +501,33 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { @Test def noExportClassWithOnlyPrivateCtors: Unit = { """ - @ScalaJSDefined @JSExport class A private () extends js.Object """ hasErrors """ - |newSource1.scala:6: error: You may not export a class that has only private constructors + |newSource1.scala:5: error: You may not export a class that has only private constructors | @JSExport | ^ """ """ - @ScalaJSDefined @JSExport class A private[this] () extends js.Object """ hasErrors """ - |newSource1.scala:6: error: You may not export a class that has only private constructors + |newSource1.scala:5: error: You may not export a class that has only private constructors | @JSExport | ^ """ """ - @ScalaJSDefined @JSExport class A private[A] () extends js.Object object A """ hasErrors """ - |newSource1.scala:6: error: You may not export a class that has only private constructors + |newSource1.scala:5: error: You may not export a class that has only private constructors | @JSExport | ^ """ @@ -596,17 +536,16 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { @Test def noConcreteMemberInTrait: Unit = { """ - @ScalaJSDefined trait A extends js.Object { def foo(x: Int): Int = x + 1 def bar[A](x: A): A = x } """ hasErrors """ - |newSource1.scala:7: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. + |newSource1.scala:6: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. | def foo(x: Int): Int = x + 1 | ^ - |newSource1.scala:8: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. + |newSource1.scala:7: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. | def bar[A](x: A): A = x | ^ """ diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 771e82bd00..2303977b1d 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -460,10 +460,10 @@ object Trees { * * `cls` must be a Scala.js-defined JS class. * - * Given the Scala.js-defined JS class + * Given the Scala.js-defined JS classes * * {{{ - * @ScalaJSDefined + * class Bar extends js.Object * class Foo extends Bar * }}} * @@ -497,10 +497,10 @@ object Trees { * * `cls` must be a Scala.js-defined JS class. * - * Given the Scala.js-defined JS class + * Given the Scala.js-defined JS classes * * {{{ - * @ScalaJSDefined + * class Bar extends js.Object * class Foo extends Bar * }}} * @@ -585,7 +585,6 @@ object Trees { * if it is a Scala.js-defined JS class. Given the class * * {{{ - * @ScalaJSDefined * class Foo(x: Int) extends js.Object * }}} * diff --git a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ScalaJSDefinedTestEx.scala b/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ScalaJSDefinedTestEx.scala index 784a8e8963..ada3db13b6 100644 --- a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ScalaJSDefinedTestEx.scala +++ b/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ScalaJSDefinedTestEx.scala @@ -22,10 +22,8 @@ import scala.scalajs.js.annotation._ class ScalaJSDefinedTestEx { @Test def constructor_property_on_the_prototype_issue_1963(): Unit = { - @ScalaJSDefined class ParentClass extends js.Object - @ScalaJSDefined class ChildClass extends ParentClass val child = new ChildClass().asInstanceOf[js.Dynamic] diff --git a/library/src/main/scala/scala/scalajs/js/Any.scala b/library/src/main/scala/scala/scalajs/js/Any.scala index 623b853814..d6ca0f567d 100644 --- a/library/src/main/scala/scala/scalajs/js/Any.scala +++ b/library/src/main/scala/scala/scalajs/js/Any.scala @@ -52,7 +52,6 @@ import annotation.ScalaJSDefined * See the [[http://www.scala-js.org/doc/js-interoperability.html JavaScript * interoperability guide]] of Scala.js for more details. */ -@ScalaJSDefined trait Any extends scala.AnyRef /** Provides implicit conversions from Scala values to JavaScript values. */ diff --git a/library/src/main/scala/scala/scalajs/js/Iterable.scala b/library/src/main/scala/scala/scalajs/js/Iterable.scala index 477e5b7f39..97a898cda0 100644 --- a/library/src/main/scala/scala/scalajs/js/Iterable.scala +++ b/library/src/main/scala/scala/scalajs/js/Iterable.scala @@ -15,7 +15,6 @@ import js.annotation._ /** ECMAScript 6 * JavaScript Iterable. */ -@ScalaJSDefined trait Iterable[+A] extends js.Object { /** JavaScript Iterator for this Iterable. */ @JSName(Symbol.iterator) diff --git a/library/src/main/scala/scala/scalajs/js/Iterator.scala b/library/src/main/scala/scala/scalajs/js/Iterator.scala index 9b4fbbb48b..086202fcdb 100644 --- a/library/src/main/scala/scala/scalajs/js/Iterator.scala +++ b/library/src/main/scala/scala/scalajs/js/Iterator.scala @@ -15,14 +15,12 @@ import js.annotation._ /** ECMAScript 6 * JavaScript Iterator. */ -@ScalaJSDefined trait Iterator[+A] extends js.Object { def next(): Iterator.Entry[A] } object Iterator { /** Return value of [[Iterator.next]]. */ - @ScalaJSDefined trait Entry[+A] extends js.Object { /** Whether the iterator has completed. */ def done: Boolean diff --git a/library/src/main/scala/scala/scalajs/js/JSConverters.scala b/library/src/main/scala/scala/scalajs/js/JSConverters.scala index 14eac7fb58..34ce5c52ba 100644 --- a/library/src/main/scala/scala/scalajs/js/JSConverters.scala +++ b/library/src/main/scala/scala/scalajs/js/JSConverters.scala @@ -52,13 +52,11 @@ object JSConverters extends JSConvertersLowPrioImplicits { @inline final def toJSIterator: Iterator[T] = new IteratorAdapter(__self) } - @ScalaJSDefined private class IterableAdapter[+T](col: GenIterable[T]) extends Iterable[T] { @JSName(Symbol.iterator) final def jsIterator(): Iterator[T] = col.iterator.toJSIterator } - @ScalaJSDefined private class IteratorAdapter[+T]( it: scala.collection.Iterator[T]) extends Iterator[T] { final def next(): Iterator.Entry[T] = { diff --git a/library/src/main/scala/scala/scalajs/js/Thenable.scala b/library/src/main/scala/scala/scalajs/js/Thenable.scala index 2131ea9b23..8736ecfd17 100644 --- a/library/src/main/scala/scala/scalajs/js/Thenable.scala +++ b/library/src/main/scala/scala/scalajs/js/Thenable.scala @@ -27,7 +27,6 @@ import scala.concurrent.Future * The signature of the `then` method is only valid provided that the * values of `B` do not have a `then` method. */ -@ScalaJSDefined trait Thenable[+A] extends js.Object { def `then`[B]( onFulfilled: js.Function1[A, B | Thenable[B]], diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSExportNamed.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSExportNamed.scala index ad229b2043..bb91787f62 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSExportNamed.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSExportNamed.scala @@ -46,7 +46,6 @@ package scala.scalajs.js.annotation * }}} * you should write: * {{{ - * @ScalaJSDefined * trait FooOptions extends js.Object { * val a: Int * val b: String diff --git a/library/src/main/scala/scala/scalajs/js/annotation/ScalaJSDefined.scala b/library/src/main/scala/scala/scalajs/js/annotation/ScalaJSDefined.scala index 9387b90d92..878253c4da 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/ScalaJSDefined.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/ScalaJSDefined.scala @@ -14,4 +14,6 @@ package scala.scalajs.js.annotation * This annotation may only be used on a class extending * [[scala.scalajs.js.Any js.Any]]. */ +@deprecated("Scala.js defined is now the default. This annotation has no " + + "effect and can be safely removed.", "1.0.0") class ScalaJSDefined extends scala.annotation.StaticAnnotation diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTestSeparateRun.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTestSeparateRun.scala index f92f514b96..431bcf3325 100644 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTestSeparateRun.scala +++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTestSeparateRun.scala @@ -15,17 +15,14 @@ import scala.scalajs.js.annotation._ */ object ScalaJSDefinedTestSeparateRun { - @ScalaJSDefined class SimpleParentClass extends js.Object { def foo(x: Int): Int = x + 1 } - @ScalaJSDefined class SimpleChildClass extends SimpleParentClass { override def foo(x: Int): Int = x + 3 } - @ScalaJSDefined trait SimpleTrait extends js.Any { def foo(x: Int): Int } diff --git a/test-suite/js/src/test/require-2.12/org/scalajs/testsuite/jsinterop/JSOptionalTest212.scala b/test-suite/js/src/test/require-2.12/org/scalajs/testsuite/jsinterop/JSOptionalTest212.scala index cd27c67489..08caa4ee40 100644 --- a/test-suite/js/src/test/require-2.12/org/scalajs/testsuite/jsinterop/JSOptionalTest212.scala +++ b/test-suite/js/src/test/require-2.12/org/scalajs/testsuite/jsinterop/JSOptionalTest212.scala @@ -138,7 +138,6 @@ class JSOptionalTest212 { } @Test def overrideClassAbstractWithOptional(): Unit = { - @ScalaJSDefined abstract class ClassWithAbstracts extends js.Object { val x: js.UndefOr[Int] def y: js.UndefOr[String] @@ -146,7 +145,6 @@ class JSOptionalTest212 { var z: js.UndefOr[Option[Int]] } - @ScalaJSDefined trait OverrideClassAbstractWithOptional extends ClassWithAbstracts { val x = js.undefined def y = js.undefined @@ -172,7 +170,6 @@ class JSOptionalTest212 { } @Test def overrideTraitAbstractWithOptional(): Unit = { - @ScalaJSDefined trait TraitWithAbstracts extends js.Object { val x: js.UndefOr[Int] def y: js.UndefOr[String] @@ -180,7 +177,6 @@ class JSOptionalTest212 { var z: js.UndefOr[Option[Int]] } - @ScalaJSDefined trait OverrideTraitAbstractWithOptional extends TraitWithAbstracts { val x = js.undefined def y = js.undefined @@ -216,7 +212,6 @@ class JSOptionalTest212 { } object JSOptionalTest212 { - @ScalaJSDefined trait TraitWithOptional extends js.Object { val x: js.UndefOr[Int] = js.undefined def y: js.UndefOr[String] = js.undefined @@ -224,10 +219,8 @@ object JSOptionalTest212 { var z: js.UndefOr[Option[Int]] = js.undefined } - @ScalaJSDefined class ClassImplementsTraitWithOptional extends TraitWithOptional - @ScalaJSDefined class UndefinedInClassIsNotOptional extends js.Object { val x: js.UndefOr[Int] = js.undefined def y: js.UndefOr[String] = js.undefined @@ -235,7 +228,6 @@ object JSOptionalTest212 { var z: js.UndefOr[Option[Int]] = js.undefined } - @ScalaJSDefined class OverrideWithUndefinedInClassIsNotOptional extends TraitWithOptional { override val x = js.undefined override def y = js.undefined // scalastyle:ignore @@ -243,7 +235,6 @@ object JSOptionalTest212 { z = js.undefined } - @ScalaJSDefined class ClassImplementsTraitWithOptionalOverrideWithConcrete extends TraitWithOptional { override val x = 42 @@ -252,7 +243,6 @@ object JSOptionalTest212 { z = Some(5) } - @ScalaJSDefined trait TraitWithOptionalFunction extends js.Object { val f: js.UndefOr[js.Function1[Int, Int]] = js.undefined } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala index 2648724b70..de41a44ed5 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala @@ -862,7 +862,6 @@ trait InteroperabilityTestPolyTypeNullaryMethodNative extends js.Object { def emptyArray[T]: js.Array[T] = js.native } -@ScalaJSDefined trait InteroperabilityTestPolyTypeNullaryMethodNonNative extends js.Object { def emptyArray[T]: js.Array[T] } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala index adb17d4215..082274c274 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala @@ -402,7 +402,6 @@ class OptimizerTest { } @Test def must_not_break_virtualized_jsarrayconstr_in_spread(): Unit = { - @ScalaJSDefined class Foo extends js.Object { def check(a: Int, b: String, rest: Any*): Unit = { assertEquals(5, a) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index a243f5b420..f02fcf82d5 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -1244,7 +1244,6 @@ class ExportsTest { def checkOriginalY3() = y3 } - @ScalaJSDefined class JSClass extends js.Object def getJSObj2(): js.Object = new JSClass { @@ -1262,7 +1261,6 @@ class ExportsTest { def checkOriginalY3() = y3 } - @ScalaJSDefined abstract class JSAbstractClass extends js.Object def getJSObj3(): js.Object = new JSAbstractClass { @@ -1280,7 +1278,6 @@ class ExportsTest { def checkOriginalY3() = y3 } - @ScalaJSDefined abstract class JSTrait extends js.Object def getJSObj4(): js.Object = new JSTrait { @@ -1493,7 +1490,6 @@ class ExportsTest { object A extends AutoExportIgnoreTrait { var x = 1 } object B extends AutoExportIgnoreClass { var x = 2 } - @ScalaJSDefined object C extends SJSDefinedAutoExportIgnoreClass { var x = 3 } // Check that the objects are usable @@ -1611,14 +1607,12 @@ class ExportsTest { @Test def should_ignore_invalid_descendants2(): Unit = { trait HasBar { def bar: Int } - @ScalaJSDefined trait SJSDefinedHasBar extends js.Any { def bar: Int } // This is just to check that everything here compiles class A extends AutoExportIgnoreTrait { def foo: Int = 1 } class B extends AutoExportIgnoreClass { def foo: Int = 2 } - @ScalaJSDefined class C extends SJSDefinedAutoExportIgnoreClass { def foo: Int = 3 } val a = new A { override def foo: Int = 3 } @@ -1666,14 +1660,12 @@ object TopLevelExportedObject { @JSExport @JSExport("TheSJSDefinedExportedObject") -@ScalaJSDefined object SJSDefinedExportedObject extends js.Object { def witness: String = "witness" } @JSExportTopLevel("SJSDefinedTopLevelExportedObject") @JSExportTopLevel("TheSJSDefinedTopLevelExportedObject") -@ScalaJSDefined object SJSDefinedTopLevelExportedObject extends js.Object { val witness: String = "witness" } @@ -1703,12 +1695,10 @@ class TopLevelExportedClass(_x: Int) { @JSExport @JSExport("TheSJSDefinedExportedClass") @JSExport("qualified.testclass.SJSDefinedExportedClass") -@ScalaJSDefined class SJSDefinedExportedClass(val x: Int) extends js.Object @JSExportTopLevel("SJSDefinedTopLevelExportedClass") @JSExportTopLevel("TheSJSDefinedTopLevelExportedClass") -@ScalaJSDefined class SJSDefinedTopLevelExportedClass(val x: Int) extends js.Object @JSExport @@ -1764,22 +1754,16 @@ class AutoExportedClassClass(_x: Int) extends AutoExportTrait { @JSExportDescendentClasses @JSExportDescendentObjects -@ScalaJSDefined trait SJSDefinedAutoExportTrait extends js.Object -@ScalaJSDefined object SJSDefinedAutoExportedTraitObject extends SJSDefinedAutoExportTrait -@ScalaJSDefined class SJSDefinedAutoExportedTraitClass(val x: Int) extends SJSDefinedAutoExportTrait @JSExportDescendentClasses @JSExportDescendentObjects -@ScalaJSDefined class SJSDefinedAutoExportClass extends js.Object -@ScalaJSDefined object SJSDefinedAutoExportedClassObject extends SJSDefinedAutoExportClass -@ScalaJSDefined class SJSDefinedAutoExportedClassClass(val x: Int) extends SJSDefinedAutoExportClass @JSExportDescendentClasses(ignoreInvalidDescendants = true) @@ -1806,19 +1790,15 @@ class AutoExportIgnoreClassClass(_x: Int) extends AutoExportIgnoreTrait { @JSExportDescendentClasses(ignoreInvalidDescendants = true) @JSExportDescendentObjects(ignoreInvalidDescendants = true) -@ScalaJSDefined class SJSDefinedAutoExportIgnoreClass extends js.Object -@ScalaJSDefined object SJSDefinedAutoExportedIgnoreClassObject extends SJSDefinedAutoExportIgnoreClass -@ScalaJSDefined class SJSDefinedAutoExportedIgnoreClassClass(val x: Int) extends SJSDefinedAutoExportIgnoreClass @js.native @JSGlobal object NativeInvalidExportObject extends SJSDefinedAutoExportIgnoreClass @js.native @JSGlobal class NativeInvalidExportClass extends SJSDefinedAutoExportIgnoreClass -@ScalaJSDefined class SJSDefinedInvalidExportClass private () extends SJSDefinedAutoExportIgnoreClass class SomeValueClass(val i: Int) extends AnyVal @@ -1855,7 +1835,6 @@ object ExportHolder { object TopLevelExportedObject @JSExport("qualified.nested.SJSDefinedExportedClass") - @ScalaJSDefined class SJSDefinedExportedClass extends js.Object } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/IterableTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/IterableTest.scala index e2fc8df2f3..ec7a95027a 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/IterableTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/IterableTest.scala @@ -20,13 +20,11 @@ object IterableTest { org.scalajs.testsuite.utils.Platform.areJSSymbolsSupported) } - @ScalaJSDefined private class CounterIterable(val max: Int) extends js.Iterable[Int] { @JSName(js.Symbol.iterator) def jsIterator(): js.Iterator[Int] = new CounterIterator(max) } - @ScalaJSDefined private class CounterIterator(val max: Int) extends js.Iterator[Int] { private[this] var nextNum = 0 diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala index 2e3767836f..1ac2abb4ba 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala @@ -273,7 +273,6 @@ class JSExportStaticTest { } -@ScalaJSDefined class TopLevelStaticExportMethods extends js.Object { def alsoExistsAsMember(x: Int): Int = x * 2 } @@ -310,7 +309,6 @@ object TopLevelStaticExportMethods { } object JSExportStaticTest { - @ScalaJSDefined class StaticExportMethods extends js.Object { def alsoExistsAsMember(x: Int): Int = x * 2 } @@ -346,7 +344,6 @@ object JSExportStaticTest { def alsoExistsAsMember(x: Int): Int = x * 5 } - @ScalaJSDefined class StaticExportProperties extends js.Object { def alsoExistsAsMember: Int = 54 } @@ -392,7 +389,6 @@ object JSExportStaticTest { def alsoExistsAsMember: String = "also a member" } - @ScalaJSDefined class StaticExportFields extends js.Object { val alsoExistsAsMember: Int = 5 } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNameTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNameTest.scala index b410d04b6f..e0451eceb2 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNameTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNameTest.scala @@ -81,19 +81,16 @@ object JSNameTest { var internalVar: Double = js.native } - @ScalaJSDefined trait PropDefSJSDefined extends js.Any { @JSName("jsDef") def internalDef: Int } - @ScalaJSDefined trait PropValSJSDefined extends js.Any { @JSName("jsVal") val internalVal: String } - @ScalaJSDefined trait PropVarSJSDefined extends js.Any { @JSName("jsVar") var internalVar: Double diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala index f56f4af49a..e7948a68fc 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala @@ -158,7 +158,6 @@ class JSOptionalTest { } @Test def overrideClassAbstractWithOptional(): Unit = { - @ScalaJSDefined abstract class ClassWithAbstracts extends js.Object { val x: js.UndefOr[Int] def y: js.UndefOr[String] @@ -166,7 +165,6 @@ class JSOptionalTest { var z: js.UndefOr[Option[Int]] } - @ScalaJSDefined trait OverrideClassAbstractWithOptional extends ClassWithAbstracts { val x: js.UndefOr[Int] = js.undefined def y: js.UndefOr[String] = js.undefined @@ -192,7 +190,6 @@ class JSOptionalTest { } @Test def overrideTraitAbstractWithOptional(): Unit = { - @ScalaJSDefined trait TraitWithAbstracts extends js.Object { val x: js.UndefOr[Int] def y: js.UndefOr[String] @@ -200,7 +197,6 @@ class JSOptionalTest { var z: js.UndefOr[Option[Int]] } - @ScalaJSDefined trait OverrideTraitAbstractWithOptional extends TraitWithAbstracts { val x: js.UndefOr[Int] = js.undefined def y: js.UndefOr[String] = js.undefined @@ -226,7 +222,6 @@ class JSOptionalTest { } @Test def polyOptionalMethod(): Unit = { - @ScalaJSDefined trait TraitWithPolyOptionalMethod extends js.Object { def foo[A]: js.UndefOr[A] = js.undefined } @@ -249,7 +244,6 @@ class JSOptionalTest { } object JSOptionalTest { - @ScalaJSDefined trait TraitWithOptional extends js.Object { val x: js.UndefOr[Int] = js.undefined def y: js.UndefOr[String] = js.undefined @@ -257,10 +251,8 @@ object JSOptionalTest { var z: js.UndefOr[Option[Int]] = js.undefined } - @ScalaJSDefined class ClassImplementsTraitWithOptional extends TraitWithOptional - @ScalaJSDefined class UndefinedInClassIsNotOptional extends js.Object { val x: js.UndefOr[Int] = js.undefined def y: js.UndefOr[String] = js.undefined @@ -268,7 +260,6 @@ object JSOptionalTest { var z: js.UndefOr[Option[Int]] = js.undefined } - @ScalaJSDefined class OverrideWithUndefinedInClassIsNotOptional extends TraitWithOptional { override val x: js.UndefOr[Int] = js.undefined override def y: js.UndefOr[String] = js.undefined @@ -276,7 +267,6 @@ object JSOptionalTest { z = js.undefined } - @ScalaJSDefined class ClassImplementsTraitWithOptionalOverrideWithConcrete extends TraitWithOptional { override val x: js.UndefOr[Int] = 42 @@ -285,14 +275,12 @@ object JSOptionalTest { z = Some(5) } - @ScalaJSDefined trait OverrideOptionalWithOptional extends TraitWithOptional { override val x: js.UndefOr[Int] = js.undefined override val y: js.UndefOr[String] = js.undefined override def y2: js.UndefOr[String] = js.undefined } - @ScalaJSDefined trait OverrideOptionalWithOptionalImplicitType extends TraitWithOptional { /* Unlike cases where the rhs is an Int, String, etc., this compiles even * in 2.10 and 2.11, because the inferred type is `js.UndefOr[Nothing]` @@ -307,7 +295,6 @@ object JSOptionalTest { override def y2 = js.undefined // scalastyle:ignore } - @ScalaJSDefined trait TraitWithOptionalFunction extends js.Object { val f: js.UndefOr[js.Function1[Int, Int]] = js.undefined } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala index 9608e28652..37fa585928 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala @@ -261,7 +261,6 @@ object JSSymbolTest { lazy val sym1 = js.Symbol() lazy val sym2 = js.Symbol() - @ScalaJSDefined object SJSDefinedWithSyms extends js.Object { val sym3 = js.Symbol() } @@ -334,7 +333,6 @@ object JSSymbolTest { def update(s: js.Symbol, v: js.Any): Unit = js.native } - @ScalaJSDefined trait PropDefTrait extends js.Any { @JSName(sym1) def internalDef: Int @@ -347,13 +345,11 @@ object JSSymbolTest { def internalDef: Int = js.native } - @ScalaJSDefined class SJSDefinedPropDef extends js.Object with PropDefTrait { @JSName(sym1) def internalDef: Int = 456 } - @ScalaJSDefined trait PropValTrait extends js.Any { @JSName(sym1) val internalVal: String @@ -366,13 +362,11 @@ object JSSymbolTest { val internalVal: String = js.native } - @ScalaJSDefined class SJSDefinedPropVal extends js.Object with PropValTrait { @JSName(sym1) val internalVal: String = "hello" } - @ScalaJSDefined trait PropVarTrait extends js.Any { @JSName(sym1) var internalVar: Double @@ -385,19 +379,16 @@ object JSSymbolTest { var internalVar: Double = js.native } - @ScalaJSDefined class SJSDefinedPropVar extends js.Object with PropVarTrait { @JSName(sym1) var internalVar: Double = 1511.1989 } - @ScalaJSDefined trait InnerObjectTrait extends js.Any { @JSName(sym1) val innerObject: AnyRef } - @ScalaJSDefined class SJSDefinedInnerObject extends js.Object with InnerObjectTrait { @JSName(sym1) object innerObject { // scalastyle:ignore @@ -405,7 +396,6 @@ object JSSymbolTest { } } - @ScalaJSDefined trait MethodTrait extends js.Any { @JSName(sym1) def foo(x: Int): Int @@ -424,7 +414,6 @@ object JSSymbolTest { def bar(x: String): String = js.native } - @ScalaJSDefined class SJSDefinedMethod extends js.Object with MethodTrait { @JSName(sym1) def foo(x: Int): Int = x + 2 @@ -433,7 +422,6 @@ object JSSymbolTest { def bar(x: String): String = "Hello " + x } - @ScalaJSDefined trait OverloadedMethodTrait extends js.Any { @JSName(sym1) def foo(x: Int): Int @@ -452,7 +440,6 @@ object JSSymbolTest { def foo(x: String): String = js.native } - @ScalaJSDefined class SJSDefinedOverloadedMethod extends js.Object with OverloadedMethodTrait { @JSName(sym1) def foo(x: Int): Int = x + 3 @@ -461,7 +448,6 @@ object JSSymbolTest { def foo(x: String): String = "Hello " + x } - @ScalaJSDefined trait OverloadedRuntimeDispatchMethodTrait extends js.Any { @JSName(sym1) def foo(x: Int): Int @@ -480,7 +466,6 @@ object JSSymbolTest { def foo(x: String): String = js.native } - @ScalaJSDefined class SJSDefinedOverloadedRuntimeDispatchMethod extends js.Object with OverloadedRuntimeDispatchMethodTrait { @JSName(sym1) @@ -490,7 +475,6 @@ object JSSymbolTest { def foo(x: String): String = "Hello " + x } - @ScalaJSDefined trait TraitWithSymsInSJSDefinedObject extends js.Object { @JSName(sym3) def symInSJSDefinedObject(x: Int): Int @@ -503,14 +487,12 @@ object JSSymbolTest { def symInSJSDefinedObject(x: Int): Int = js.native } - @ScalaJSDefined class SJSDefinedWithSymsInSJSDefinedObject extends TraitWithSymsInSJSDefinedObject { @JSName(sym3) def symInSJSDefinedObject(x: Int): Int = x + 2 } - @ScalaJSDefined trait JSIterable[+A] extends js.Object { @JSName(js.Symbol.iterator) def iterator(): js.Dynamic @@ -523,7 +505,6 @@ object JSSymbolTest { def iterator(): js.Dynamic = js.native } - @ScalaJSDefined class SJSDefinedIterable extends JSIterable[Int] { @JSName(js.Symbol.iterator) def iterator(): js.Dynamic = singletonIterator(532) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala index a84787fe06..2098f325e7 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala @@ -197,16 +197,12 @@ class MiscInteropTest { object MiscInteropTest { - @ScalaJSDefined abstract class AbstractJSClass extends js.Object - @ScalaJSDefined class ConcreteJSClass extends AbstractJSClass - @ScalaJSDefined class OtherwiseUnreferencedJSClass(val x: Int) extends js.Object - @ScalaJSDefined class OtherwiseUnreferencedJSClassForTag(val x: Int) extends js.Object @js.native @@ -222,7 +218,6 @@ object MiscInteropTest { class SomeScalaClass - @ScalaJSDefined class SomeJSClass extends js.Object } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PromiseMock.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PromiseMock.scala index 7d0ea67482..d39d48d783 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PromiseMock.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PromiseMock.scala @@ -115,7 +115,6 @@ object PromiseMock { } } - @ScalaJSDefined private class MockPromise[+A]( executor: js.Function2[js.Function1[A | Thenable[A], _], js.Function1[scala.Any, _], _]) extends js.Object with js.Thenable[A] { diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala index 87a0822411..40b4beae85 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala @@ -216,7 +216,6 @@ class ScalaJSDefinedTest { } @Test def lambda_inside_a_method_issue_2220(): Unit = { - @ScalaJSDefined class LambdaInsideMethod extends js.Object { def foo(): Int = { List(1, 2, 3).map(_ * 2).sum @@ -228,7 +227,6 @@ class ScalaJSDefinedTest { @Test def nested_inside_a_Scala_class(): Unit = { class OuterScalaClass(val x: Int) { - @ScalaJSDefined class InnerJSClass(val y: Int) extends js.Object { def sum(z: Int): Int = x + y + z } @@ -241,9 +239,7 @@ class ScalaJSDefinedTest { } @Test def nested_inside_a_Scala_js_defined_JS_class(): Unit = { - @ScalaJSDefined class OuterJSClass(val x: Int) extends js.Object { - @ScalaJSDefined class InnerJSClass(val y: Int) extends js.Object { def sum(z: Int): Int = x + y + z } @@ -256,7 +252,6 @@ class ScalaJSDefinedTest { } @Test def Scala_class_nested_inside_a_Scala_js_defined_JS_class(): Unit = { - @ScalaJSDefined class OuterJSClass(val x: Int) extends js.Object { class InnerScalaClass(val y: Int) { def sum(z: Int): Int = x + y + z @@ -270,7 +265,6 @@ class ScalaJSDefinedTest { } @Test def Scala_object_nested_inside_a_Scala_js_defined_JS_class(): Unit = { - @ScalaJSDefined class Foo extends js.Object { var innerInitCount: Int = _ @@ -298,7 +292,6 @@ class ScalaJSDefinedTest { // #2772 @Test def Scala_object_nested_inside_a_Scala_js_defined_JS_class_JSName(): Unit = { - @ScalaJSDefined class Foo extends js.Object { var innerInitCount: Int = _ @@ -348,7 +341,6 @@ class ScalaJSDefinedTest { } @Test def local_class_has_own_prototype(): Unit = { - @ScalaJSDefined class Local extends js.Object { val x = 1 } @@ -446,7 +438,6 @@ class ScalaJSDefinedTest { @Test def local_object_is_lazy(): Unit = { var initCount: Int = 0 - @ScalaJSDefined object Obj extends js.Object { initCount += 1 } @@ -463,7 +454,6 @@ class ScalaJSDefinedTest { @Test def local_object_with_captures(): Unit = { val x = (() => 5)() - @ScalaJSDefined object Obj extends js.Object { val y = 10 def sum(z: Int): Int = x + y + z @@ -478,11 +468,9 @@ class ScalaJSDefinedTest { } @Test def object_in_Scala_js_defined_JS_class(): Unit = { - @ScalaJSDefined class Foo extends js.Object { var innerInitCount: Int = _ - @ScalaJSDefined object Inner extends js.Object { innerInitCount += 1 } @@ -506,7 +494,6 @@ class ScalaJSDefinedTest { } @Test def local_defs_must_not_be_exposed(): Unit = { - @ScalaJSDefined class LocalDefsMustNotBeExposed extends js.Object { def foo(): String = { def bar(): String = "hello" @@ -519,7 +506,6 @@ class ScalaJSDefinedTest { } @Test def local_objects_must_not_be_exposed(): Unit = { - @ScalaJSDefined class LocalObjectsMustNotBeExposed extends js.Object { def foo(): String = { object Bar @@ -532,7 +518,6 @@ class ScalaJSDefinedTest { } @Test def local_defs_with_captures_issue_1975(): Unit = { - @ScalaJSDefined class LocalDefsWithCaptures extends js.Object { def foo(suffix: String): String = { def bar(): String = "hello " + suffix @@ -545,7 +530,6 @@ class ScalaJSDefinedTest { } @Test def methods_with_explicit_name(): Unit = { - @ScalaJSDefined class MethodsWithExplicitName extends js.Object { @JSName("theAnswer") def bar(): Int = 42 @@ -565,7 +549,6 @@ class ScalaJSDefinedTest { } @Test def methods_with_constant_folded_name(): Unit = { - @ScalaJSDefined class MethodsWithConstantFoldedName extends js.Object { @JSName(JSNameHolder.MethodName) def bar(): Int = 42 @@ -580,7 +563,6 @@ class ScalaJSDefinedTest { } @Test def protected_methods(): Unit = { - @ScalaJSDefined class ProtectedMethods extends js.Object { protected def bar(): Int = 42 @@ -599,7 +581,6 @@ class ScalaJSDefinedTest { @Test def readonly_properties(): Unit = { // Named classes - @ScalaJSDefined class Foo extends js.Object { def bar: Int = 1 } @@ -621,7 +602,6 @@ class ScalaJSDefinedTest { @Test def properties_are_not_enumerable(): Unit = { // Named classes - @ScalaJSDefined class Foo extends js.Object { def myProp: Int = 1 } @@ -639,7 +619,6 @@ class ScalaJSDefinedTest { @Test def properties_are_configurable(): Unit = { // Named classes - @ScalaJSDefined class Foo extends js.Object { def myProp: Int = 1 } @@ -664,7 +643,6 @@ class ScalaJSDefinedTest { } @Test def properties_with_explicit_name(): Unit = { - @ScalaJSDefined class PropertiesWithExplicitName extends js.Object { private[this] var myY: String = "hello" @JSName("answer") @@ -705,7 +683,6 @@ class ScalaJSDefinedTest { } @Test def protected_properties(): Unit = { - @ScalaJSDefined class ProtectedProperties extends js.Object { protected val x: Int = 42 protected[testsuite] val y: Int = 43 @@ -720,7 +697,6 @@ class ScalaJSDefinedTest { } @Test def simple_overloaded_methods(): Unit = { - @ScalaJSDefined class SimpleOverloadedMethods extends js.Object { def foo(): Int = 42 def foo(x: Int): Int = x*2 @@ -737,7 +713,6 @@ class ScalaJSDefinedTest { } @Test def renamed_overloaded_methods(): Unit = { - @ScalaJSDefined class RenamedOverloadedMethods extends js.Object { @JSName("foobar") def foo(): Int = 42 @@ -766,13 +741,11 @@ class ScalaJSDefinedTest { } @Test def overloaded_constructors_with_captured_parameters(): Unit = { - @ScalaJSDefined class OverloadedConstructorWithOuterContextOnly(val x: Int) extends js.Object { def this(y: String) = this(y.length) } val z = (() => 5)() - @ScalaJSDefined class OverloadedConstructorWithValCapture(val x: Int) extends js.Object { def this(y: String) = this(z) } @@ -785,11 +758,9 @@ class ScalaJSDefinedTest { } @Test def overloaded_constructors_with_super_class(): Unit = { - @ScalaJSDefined class OverloadedConstructorSup(val x: Int) extends js.Object { def this(y: String) = this(y.length) } - @ScalaJSDefined class OverloadedConstructorSub(x: Int) extends OverloadedConstructorSup(3 * x) { def this(y: String) = this(2 * y.length) @@ -802,7 +773,6 @@ class ScalaJSDefinedTest { } @Test def overloaded_constructors_with_repeated_parameters(): Unit = { - @ScalaJSDefined class OverloadedConstructorWithRepeatedParameters(xs: Int*) extends js.Object { def this(y: String, ys: String*) = this(y.length +: ys.map(_.length): _*) @@ -866,7 +836,6 @@ class ScalaJSDefinedTest { } @Test def polytype_nullary_method_issue_2445(): Unit = { - @ScalaJSDefined class PolyTypeNullaryMethod extends js.Object { def emptyArray[T]: js.Array[T] = js.Array() } @@ -883,7 +852,6 @@ class ScalaJSDefinedTest { } @Test def default_parameters(): Unit = { - @ScalaJSDefined class DefaultParameters extends js.Object { def bar(x: Int, y: Int = 1): Int = x + y def dependent(x: Int)(y: Int = x + 1): Int = x + y @@ -891,7 +859,6 @@ class ScalaJSDefinedTest { def foobar(x: Int): Int = bar(x) } - @ScalaJSDefined object DefaultParametersMod extends js.Object { def bar(x: Int, y: Int = 1): Int = x + y def dependent(x: Int)(y: Int = x + 1): Int = x + y @@ -924,7 +891,6 @@ class ScalaJSDefinedTest { } @Test def override_default_parameters(): Unit = { - @ScalaJSDefined class OverrideDefaultParametersParent extends js.Object { def bar(x: Int, y: Int = 1): Int = x + y def dependent(x: Int)(y: Int = x + 1): Int = x + y @@ -932,7 +898,6 @@ class ScalaJSDefinedTest { def foobar(x: Int): Int = bar(x) } - @ScalaJSDefined class OverrideDefaultParametersChild extends OverrideDefaultParametersParent { override def bar(x: Int, y: Int = 10): Int = super.bar(x, y) @@ -962,7 +927,6 @@ class ScalaJSDefinedTest { } @Test def override_method_with_default_parameters_without_new_default(): Unit = { - @ScalaJSDefined class OverrideDefaultParametersWithoutDefaultParent extends js.Object { def bar(x: Int, y: Int = 1): Int = x + y def dependent(x: Int)(y: Int = x + 1): Int = x + y @@ -970,7 +934,6 @@ class ScalaJSDefinedTest { def foobar(x: Int): Int = bar(x) } - @ScalaJSDefined class OverrideDefaultParametersWithoutDefaultChild extends OverrideDefaultParametersWithoutDefaultParent { override def bar(x: Int, y: Int): Int = x - y @@ -1060,7 +1023,6 @@ class ScalaJSDefinedTest { } @Test def `call_super_constructor_with_:__*`(): Unit = { - @ScalaJSDefined class CallSuperCtorWithSpread(x: Int, y: Int, z: Int) extends NativeParentClassWithVarargs(x, Seq(y, z): _*) @@ -1075,7 +1037,6 @@ class ScalaJSDefinedTest { } @Test def override_native_method(): Unit = { - @ScalaJSDefined class OverrideNativeMethod extends NativeParentClass(3) { override def foo(s: String): String = s + s + x } @@ -1094,7 +1055,6 @@ class ScalaJSDefinedTest { } @Test def override_non_native_method(): Unit = { - @ScalaJSDefined class OverrideNonNativeMethod extends NonNativeParentClass(3) { override def foo(s: String): String = s + s + x } @@ -1124,7 +1084,6 @@ class ScalaJSDefinedTest { } @Test def override_native_method_and_call_super(): Unit = { - @ScalaJSDefined class OverrideNativeMethodSuperCall extends NativeParentClass(3) { override def foo(s: String): String = super.foo("bar") + s } @@ -1143,7 +1102,6 @@ class ScalaJSDefinedTest { } @Test def override_non_native_method_and_call_super(): Unit = { - @ScalaJSDefined class OverrideNonNativeMethodSuperCall extends NonNativeParentClass(3) { override def foo(s: String): String = super.foo("bar") + s } @@ -1162,7 +1120,6 @@ class ScalaJSDefinedTest { } @Test def override_native_val(): Unit = { - @ScalaJSDefined class OverrideNativeVal extends NativeParentClass(3) { override val x: Int = 42 } @@ -1184,7 +1141,6 @@ class ScalaJSDefinedTest { } @Test def override_non_native_val(): Unit = { - @ScalaJSDefined class OverrideNonNativeVal extends NonNativeParentClass(3) { override val x: Int = 42 } @@ -1206,7 +1162,6 @@ class ScalaJSDefinedTest { } @Test def override_native_getter(): Unit = { - @ScalaJSDefined class OverrideNativeGetter extends NativeParentClass(3) { override def bar: Int = x * 3 } @@ -1225,7 +1180,6 @@ class ScalaJSDefinedTest { } @Test def override_non_native_getter(): Unit = { - @ScalaJSDefined class OverrideNonNativeGetter extends NonNativeParentClass(3) { override def bar: Int = x * 3 } @@ -1244,7 +1198,6 @@ class ScalaJSDefinedTest { } @Test def override_native_getter_with_val(): Unit = { - @ScalaJSDefined class OverrideNativeGetterWithVal extends NativeParentClass(3) { override val bar: Int = 1 } @@ -1263,7 +1216,6 @@ class ScalaJSDefinedTest { } @Test def override_non_native_getter_with_val(): Unit = { - @ScalaJSDefined class OverrideNonNativeGetterWithVal extends NonNativeParentClass(3) { override val bar: Int = 1 } @@ -1282,11 +1234,9 @@ class ScalaJSDefinedTest { } @Test def override_getter_with_super(): Unit = { - @ScalaJSDefined class OverrideGetterSuperParent extends js.Object { def bar: Int = 43 } - @ScalaJSDefined class OverrideGetterSuperChild extends OverrideGetterSuperParent { override def bar: Int = super.bar * 3 } @@ -1302,12 +1252,10 @@ class ScalaJSDefinedTest { } @Test def override_setter_with_super(): Unit = { - @ScalaJSDefined class OverrideSetterSuperParent extends js.Object { var x: Int = 43 def bar_=(v: Int): Unit = x = v } - @ScalaJSDefined class OverrideSetterSuperChild extends OverrideSetterSuperParent { override def bar_=(v: Int): Unit = super.bar_=(v * 3) } @@ -1326,12 +1274,10 @@ class ScalaJSDefinedTest { } @Test def add_setter_in_subclass(): Unit = { - @ScalaJSDefined class AddSetterInSubclassParent extends js.Object { var x: Int = 43 def bar: Int = x } - @ScalaJSDefined class AddSetterInSubclassChild extends AddSetterInSubclassParent { def bar_=(v: Int): Unit = x = v } @@ -1348,12 +1294,10 @@ class ScalaJSDefinedTest { } @Test def add_getter_in_subclass(): Unit = { - @ScalaJSDefined class AddGetterInSubclassParent extends js.Object { var x: Int = 43 def bar_=(v: Int): Unit = x = v } - @ScalaJSDefined class AddGetterInSubclassChild extends AddGetterInSubclassParent { def bar: Int = x } @@ -1370,7 +1314,6 @@ class ScalaJSDefinedTest { } @Test def overload_native_method(): Unit = { - @ScalaJSDefined class OverloadNativeMethod extends NativeParentClass(3) { def foo(s: String, y: Int): String = foo(s) + " " + y } @@ -1388,7 +1331,6 @@ class ScalaJSDefinedTest { } @Test def overload_non_native_method(): Unit = { - @ScalaJSDefined class OverloadNonNativeMethod extends NonNativeParentClass(3) { def foo(s: String, y: Int): String = foo(s) + " " + y } @@ -1406,7 +1348,6 @@ class ScalaJSDefinedTest { } @Test def overload_with_default_parameter(): Unit = { - @ScalaJSDefined class OverloadDefaultParameter extends js.Object { def foo(x: Int): Int = x def foo(x: String = ""): String = x @@ -1419,7 +1360,6 @@ class ScalaJSDefinedTest { } @Test def implement_a_simple_trait(): Unit = { - @ScalaJSDefined class ImplementSimpleTrait extends js.Object with SimpleTrait { def foo(x: Int): Int = x + 1 } @@ -1432,7 +1372,6 @@ class ScalaJSDefinedTest { } @Test def implement_a_simple_trait_under_separate_compilation(): Unit = { - @ScalaJSDefined class ImplementSimpleTraitSepRun extends js.Object with SepRun.SimpleTrait { def foo(x: Int): Int = x + 1 } @@ -1445,12 +1384,10 @@ class ScalaJSDefinedTest { } @Test def implement_a_trait_with_a_val(): Unit = { - @ScalaJSDefined trait TraitWithVal extends js.Object { val x: Int } - @ScalaJSDefined class ImplWithVal extends TraitWithVal { val x: Int = 3 } @@ -1463,12 +1400,10 @@ class ScalaJSDefinedTest { } @Test def implement_a_trait_with_a_var(): Unit = { - @ScalaJSDefined trait TraitWithVar extends js.Object { var x: Int } - @ScalaJSDefined class ImplWithVar extends TraitWithVar { var x: Int = 3 } @@ -1486,12 +1421,10 @@ class ScalaJSDefinedTest { } @Test def implement_a_trait_extending_a_native_JS_class(): Unit = { - @ScalaJSDefined trait TraitExtendsJSClass extends NativeParentClass { def foobar(x: Int): Int } - @ScalaJSDefined class ImplExtendsJSClassAndTrait extends NativeParentClass(5) with TraitExtendsJSClass { def foobar(x: Int): Int = x * 3 @@ -1502,7 +1435,6 @@ class ScalaJSDefinedTest { } @Test def implement_abstract_members_coming_from_a_native_JS_class(): Unit = { - @ScalaJSDefined class ImplDeferredMembersFromJSParent extends NativeParentClassWithDeferred { val x: Int = 43 @@ -1529,7 +1461,6 @@ class ScalaJSDefinedTest { } @Test def override_a_method_with_default_values_from_a_native_JS_class(): Unit = { - @ScalaJSDefined class OverrideDefault extends NativeParentClass(7) { override def methodWithDefault(x: Int = 9): Int = x * 2 } @@ -1545,7 +1476,6 @@ class ScalaJSDefinedTest { // #2603 @Test def default_values_in_non_exposed_methods(): Unit = { - @ScalaJSDefined class DefaultParameterss(val default: Int) extends js.Object { /* We don't use a constant default value to make sure it actually comes * from the default parameter accessors. @@ -1578,7 +1508,6 @@ object ScalaJSDefinedTest { def methodWithDefault(x: Int = 5): Int = js.native } - @ScalaJSDefined class NonNativeParentClass(val x: Int) extends js.Object { def foo(s: String): String = s + x @@ -1608,34 +1537,28 @@ object ScalaJSDefinedTest { val args: js.Array[Int] = js.native } - @ScalaJSDefined trait SimpleTrait extends js.Any { def foo(x: Int): Int } - @ScalaJSDefined class Minimal extends js.Object private var staticNonNativeObjectInitCount: Int = _ - @ScalaJSDefined object StaticNonNativeObject extends js.Object { staticNonNativeObjectInitCount += 1 } - @ScalaJSDefined class SimpleMethod extends js.Object { def foo(x: Int): Int = x + 3 def bar(s: String, i: Int): String = s + i } - @ScalaJSDefined object StaticObjectSimpleMethod extends js.Object { def foo(x: Int): Int = x + 3 def bar(s: String, i: Int): String = s + i } - @ScalaJSDefined class SimpleField extends js.Object { val x = 5 var y = 10 @@ -1643,7 +1566,6 @@ object ScalaJSDefinedTest { def sum(): Int = x + y } - @ScalaJSDefined object StaticObjectSimpleField extends js.Object { val x = 5 var y = 10 @@ -1651,7 +1573,6 @@ object ScalaJSDefinedTest { def sum(): Int = x + y } - @ScalaJSDefined class SimpleAccessors extends js.Object { var x = 1 def readPlus1: Int = x + 1 @@ -1660,7 +1581,6 @@ object ScalaJSDefinedTest { def neg_=(v: Int): Unit = x = -v } - @ScalaJSDefined class SimpleConstructor(_x: Int, _y: Int) extends js.Object { val x = _x var y = _y @@ -1668,20 +1588,15 @@ object ScalaJSDefinedTest { def sum(): Int = x + y } - @ScalaJSDefined class ConstructorDefaultParamJSNonNativeNone(val foo: Int = -1) extends js.Object - @ScalaJSDefined class ConstructorDefaultParamJSNonNativeJSNonNative(val foo: Int = -1) extends js.Object - @ScalaJSDefined object ConstructorDefaultParamJSNonNativeJSNonNative extends js.Object - @ScalaJSDefined class ConstructorDefaultParamJSNonNativeScala(val foo: Int = -1) extends js.Object object ConstructorDefaultParamJSNonNativeScala class ConstructorDefaultParamScalaJSNonNative(val foo: Int = -1) - @ScalaJSDefined object ConstructorDefaultParamScalaJSNonNative extends js.Object @js.native @@ -1696,7 +1611,6 @@ object ScalaJSDefinedTest { @js.native @JSGlobal("ConstructorDefaultParam") class ConstructorDefaultParamJSNativeJSNonNative(val foo: Int = -1) extends js.Object - @ScalaJSDefined object ConstructorDefaultParamJSNativeJSNonNative extends js.Object @js.native @@ -1713,19 +1627,16 @@ object ScalaJSDefinedTest { // sanity check class ConstructorDefaultParamScalaNone(val foo: Int = -1) - @ScalaJSDefined class OverloadedConstructorParamNumber(val foo: Int) extends js.Object { def this(x: Int, y: Int) = this(x + y) def this(x: Int, y: Int, z: Int) = this(x + y, z) } - @ScalaJSDefined class OverloadedConstructorParamType(val foo: Int) extends js.Object { def this(x: String) = this(x.length) def this(x: Option[String]) = this(x.get) } - @ScalaJSDefined class OverloadedConstructorComplex(val foo: Int, var bar: Int) extends js.Object { def this() = this(5, 6) def this(x: Int) = this(x, x) @@ -1744,17 +1655,14 @@ object ScalaJSDefinedTest { this((a + b).length, (x + y).length) } - @ScalaJSDefined class SimpleConstructorAutoFields(val x: Int, var y: Int) extends js.Object { def sum(): Int = x + y } - @ScalaJSDefined class SimpleConstructorParamAccessors(x: Int, y: Int) extends js.Object { def sum(): Int = x + y } - @ScalaJSDefined class DefaultFieldValues extends js.Object { var int: Int = _ var bool: Boolean = _ @@ -1764,7 +1672,6 @@ object ScalaJSDefinedTest { var valueClass: SomeValueClass = _ } - @ScalaJSDefined class SimpleInheritedFromNative( x: Int, val y: Int) extends NativeParentClass(x) From 7ca50a524e0de9da90b8235e2d54c4b86fc17a8d Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 18 Mar 2017 11:30:10 +0100 Subject: [PATCH 0171/2665] Drop parallel collections in scalalib in 2.13 This backports scala/scala@d205a63cd1ea812c262df0d8304123265ccc35d1 on Range.scala. --- .../overrides-2.13/scala/collection/immutable/Range.scala | 6 ------ 1 file changed, 6 deletions(-) diff --git a/scalalib/overrides-2.13/scala/collection/immutable/Range.scala b/scalalib/overrides-2.13/scala/collection/immutable/Range.scala index e5f4287a76..fb2c34c064 100644 --- a/scalalib/overrides-2.13/scala/collection/immutable/Range.scala +++ b/scalalib/overrides-2.13/scala/collection/immutable/Range.scala @@ -10,8 +10,6 @@ package scala package collection.immutable -import scala.collection.parallel.immutable.ParRange - /** The `Range` class represents integer values in range * ''[start;end)'' with non-zero step value `step`. * It's a special case of an indexed sequence. @@ -62,11 +60,8 @@ import scala.collection.parallel.immutable.ParRange class Range(val start: Int, val end: Int, val step: Int) extends scala.collection.AbstractSeq[Int] with IndexedSeq[Int] - with scala.collection.CustomParallelizable[Int, ParRange] with Serializable { - override def par = new ParRange(this) - private def gap = end.toLong - start.toLong private def isExact = gap % step == 0 private def hasStub = isInclusive || !isExact @@ -449,7 +444,6 @@ object Range { @inline class Inclusive(start: Int, end: Int, step: Int) extends Range(start, end, step) { -// override def par = new ParRange(this) override def isInclusive = true override protected def copy(start: Int, end: Int, step: Int): Range = new Inclusive(start, end, step) } From 602828200d639ab42292daba26e7fd6eb5383569 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 25 Mar 2017 08:43:50 +0100 Subject: [PATCH 0172/2665] Fix #2834: Remove js.GlobalScope As a side effect, this: - Removes binary compatibility for classes without loading spec. - Makes loading spec checks strict (part of #1111). - Adds a missing test. --- .../org/scalajs/core/compiler/GenJSCode.scala | 31 +--- .../scalajs/core/compiler/JSDefinitions.scala | 4 - .../core/compiler/JSGlobalAddons.scala | 14 -- .../scalajs/core/compiler/PrepJSInterop.scala | 54 +----- .../core/compiler/test/JSInteropTest.scala | 155 +++--------------- .../scala/scala/scalajs/js/GlobalScope.scala | 23 --- .../compiler/InteroperabilityTest.scala | 33 ---- 7 files changed, 37 insertions(+), 277 deletions(-) delete mode 100644 library/src/main/scala/scala/scalajs/js/GlobalScope.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 0a8b61140b..b3967a9b00 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -46,7 +46,7 @@ abstract class GenJSCode extends plugins.PluginComponent import rootMirror._ import definitions._ import jsDefinitions._ - import jsInterop.{jsNameOf, compat068FullJSNameOf, jsNativeLoadSpecOf, JSName} + import jsInterop.{jsNameOf, jsNativeLoadSpecOf, JSName} import JSTreeExtractors._ import treeInfo.hasSynthCaseSymbol @@ -5238,32 +5238,11 @@ abstract class GenJSCode extends plugins.PluginComponent if (sym1 == StringModule) RuntimeStringModule.moduleClass else sym1 - if (isJSNativeClass(sym) && - !sym.hasAnnotation(HasJSNativeLoadSpecAnnotation)) { - /* Compatibility for native JS modules compiled with Scala.js 0.6.12 - * and earlier. Since they did not store their loading spec in the IR, - * the js.LoadJSModule() IR node cannot be used to load them. We must - * "desugar" it early in the compiler. - * - * Moreover, before 0.6.13, these objects would not have the - * annotation @JSGlobalScope. Instead, they would inherit from the - * magical trait js.GlobalScope. - */ - if (sym.isSubClass(JSGlobalScopeClass)) { - genLoadGlobal() - } else { - compat068FullJSNameOf(sym).split('.').foldLeft(genLoadGlobal()) { - (memo, chunk) => - js.JSBracketSelect(memo, js.StringLiteral(chunk)) - } - } - } else { - val moduleClassName = encodeClassFullName(sym) + val moduleClassName = encodeClassFullName(sym) - val cls = jstpe.ClassType(moduleClassName) - if (isRawJSType(sym.tpe)) js.LoadJSModule(cls) - else js.LoadModule(cls) - } + val cls = jstpe.ClassType(moduleClassName) + if (isRawJSType(sym.tpe)) js.LoadJSModule(cls) + else js.LoadModule(cls) } /** Gen JS code to load the global scope. */ diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index ce00d06cc6..399ea65214 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -39,8 +39,6 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val JSObjectClass = getRequiredClass("scala.scalajs.js.Object") lazy val JSThisFunctionClass = getRequiredClass("scala.scalajs.js.ThisFunction") - lazy val JSGlobalScopeClass = getRequiredClass("scala.scalajs.js.GlobalScope") - lazy val UndefOrClass = getRequiredClass("scala.scalajs.js.UndefOr") lazy val UnionClass = getRequiredClass("scala.scalajs.js.$bar") @@ -80,8 +78,6 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val JSAnyTpe = JSAnyClass.toTypeConstructor lazy val JSObjectTpe = JSObjectClass.toTypeConstructor - lazy val JSGlobalScopeTpe = JSGlobalScopeClass.toTypeConstructor - lazy val JSFunctionTpes = JSFunctionClasses.map(_.toTypeConstructor) lazy val JSAnyModule = JSAnyClass.companionModule diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala index b3cf7936fd..af57a417bd 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala @@ -206,20 +206,6 @@ trait JSGlobalAddons extends JSDefinitions else base } - /** Gets the fully qualified JS name of a static module Symbol compiled - * with the 0.6.8 binary format or earlier. - */ - def compat068FullJSNameOf(sym: Symbol): String = { - assert(sym.isModuleClass, - s"compat068FullJSNameOf called for non-module-class symbol $sym") - sym.getAnnotation(JSFullNameAnnotation).flatMap(_.stringArg(0)) getOrElse { - /* In 0.6.8, computed names did not exist, so we are necessarily - * reading a Literal here. - */ - jsNameOf(sym).asInstanceOf[JSName.Literal].name - } - } - /** Stores the JS native load spec of a symbol for the current compilation * run. */ diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 430f28a530..d11b64e688 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -479,26 +479,6 @@ abstract class PrepJSInterop extends plugins.PluginComponent sym.addAnnotation(SJSDefinedAnonymousClassAnnotation) } - /* Convert `extends js.GlobalScope` to `@JSGlobalScope`. - * No warning because `js.GlobalScope` already causes a deprecation - * warning. - * - * Note that due to an implementation detail of `addAnnotation()`, this - * will add `@JSGlobalScope` *before* all user-defined annotations. This - * is what we want here. The association `extends js.GlobalScope` + - * `@JSName` used not to be checked, in which case `js.GlobalScope` took - * precedence. The fact that `@JSGlobalScope` appears first in this case - * allows us to more easily preserve this behavior in - * `checkAndGetJSNativeLoadingSpecAnnotOf()`. - */ - if (sym.isSubClass(JSGlobalScopeClass) && sym != JSGlobalScopeClass) { - val annotInfo = { - AnnotationInfo(JSGlobalScopeAnnotation.tpe, Nil, Nil) - .setPos(implDef.pos) - } - sym.addAnnotation(annotInfo) - } - /* Anonymous functions are considered native, since they are handled * specially in the backend. */ @@ -753,8 +733,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent case Some(annot) if annot.symbol == JSGlobalScopeAnnotation => if (!sym.isModuleClass) { reporter.error(annot.pos, - "Only native JS objects can have an " + - "@JSGlobalScope annotation (or extend js.GlobalScope).") + "Only native JS objects can have an @JSGlobalScope annotation.") } JSNativeLoadSpec.Global(Nil) @@ -1149,8 +1128,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent "@JSImport annotation.") } else if (annot.symbol == JSGlobalScopeAnnotation) { reporter.error(annot.pos, - "Only native JS objects can have an @JSGlobalScope annotation " + - "(or extend js.GlobalScope).") + "Only native JS objects can have an @JSGlobalScope annotation.") } } } @@ -1407,31 +1385,9 @@ abstract class PrepJSInterop extends plugins.PluginComponent } for (annot <- duplicates) { - if (annot.symbol == JSNameAnnotation && - result.symbol == JSNameAnnotation) { - // This used not to be checked, so we can only warn - reporter.warning(annot.pos, - "A duplicate @JSName annotation is ignored, and should be " + - "removed. This will be enforced in 1.0.") - } else if (annot.symbol == JSNameAnnotation && - result.symbol == JSGlobalScopeAnnotation) { - /* This used not to be checked for `extends js.GlobalScope`, so we - * can only warn. See the comment where we deal with the legacy - * `extends js.GlobalScope` for the reason why we do not need to - * deal with the converse case (i.e., `@JSGlobalScope` always comes - * before `@JSName` in this case. - */ - reporter.warning(annot.pos, - "An @JSName annotation is ignored in the presence of " + - "@JSGlobalScope (or extends js.GlobalScope), and should be " + - "removed. This will be enforced in 1.0.") - } else { - reporter.error(annot.pos, - "Native JS classes and objects can only have one annotation " + - "among JSName, JSGlobal, JSImport and JSGlobalScope " + - "(extending js.GlobalScope is treated as having " + - "@JSGlobalScope).") - } + reporter.error(annot.pos, + "Native JS classes and objects can only have one annotation " + + "among JSName, JSGlobal, JSImport and JSGlobalScope.") } actualResult diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index 0de4d7ca31..315754f2e0 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -201,6 +201,31 @@ class JSInteropTest extends DirectTest with TestHelpers { } + @Test + def noJSGlobalScopeAnnotOnNonJSNative: Unit = { + + """ + @JSGlobalScope + object A extends js.Object + """ hasErrors + """ + |newSource1.scala:5: error: Only native JS objects can have an @JSGlobalScope annotation. + | @JSGlobalScope + | ^ + """ + + """ + @JSGlobalScope + object A + """ hasErrors + """ + |newSource1.scala:5: error: Only native JS objects can have an @JSGlobalScope annotation. + | @JSGlobalScope + | ^ + """ + + } + @Test def noJSNameAnnotOnTrait: Unit = { @@ -276,20 +301,9 @@ class JSInteropTest extends DirectTest with TestHelpers { (firstAnnotName, firstAnnot) <- JSNativeLoadSpecAnnots (secondAnnotName, secondAnnot) <- JSNativeLoadSpecAnnots } { - val expectedMessageShort = { - if (firstAnnotName == "JSName" && secondAnnotName == firstAnnotName) - "warning: A duplicate @JSName annotation is ignored, and should be removed. This will be enforced in 1.0." - else if (firstAnnotName == "JSGlobalScope" && secondAnnotName == "JSName") - "warning: An @JSName annotation is ignored in the presence of @JSGlobalScope (or extends js.GlobalScope), and should be removed. This will be enforced in 1.0." - else - "error: Native JS classes and objects can only have one annotation among JSName, JSGlobal, JSImport and JSGlobalScope (extending js.GlobalScope is treated as having @JSGlobalScope)." - } - - val onlyWarn = expectedMessageShort.startsWith("warning: ") - val expectedMessage = { s""" - |newSource1.scala:7: $expectedMessageShort + |newSource1.scala:7: error: Native JS classes and objects can only have one annotation among JSName, JSGlobal, JSImport and JSGlobalScope. |$secondAnnot | ^ """ @@ -325,10 +339,7 @@ class JSInteropTest extends DirectTest with TestHelpers { """.stripMargin } - if (onlyWarn) - snippet hasWarns fullExpectedMessage - else - snippet hasErrors fullExpectedMessage + snippet hasErrors fullExpectedMessage } } } @@ -713,106 +724,6 @@ class JSInteropTest extends DirectTest with TestHelpers { } - @Test - def noGlobalScopeClass: Unit = { - - """ - @js.native - class A extends js.GlobalScope - """ hasErrors - """ - |newSource1.scala:6: error: Only native JS objects can have an @JSGlobalScope annotation (or extend js.GlobalScope). - | class A extends js.GlobalScope - | ^ - """ - - """ - @js.native - trait A extends js.GlobalScope - """ hasErrors - """ - |newSource1.scala:6: error: Traits may not have an @JSGlobalScope annotation. - | trait A extends js.GlobalScope - | ^ - """ - - """ - class A extends js.Object with js.GlobalScope - """ hasErrors - """ - |newSource1.scala:5: error: A Scala.js-defined JS class cannot directly extend a native JS trait. - | class A extends js.Object with js.GlobalScope - | ^ - """ - - """ - trait A extends js.Object with js.GlobalScope - """ hasErrors - """ - |newSource1.scala:5: error: A Scala.js-defined JS trait cannot directly extend a native JS trait. - | trait A extends js.Object with js.GlobalScope - | ^ - """ - - """ - object A extends js.Object with js.GlobalScope - """ hasErrors - """ - |newSource1.scala:5: error: A Scala.js-defined JS object cannot directly extend a native JS trait. - | object A extends js.Object with js.GlobalScope - | ^ - """ - - } - - @Test - def noJSNameOnJSGlobalScope: Unit = { - // #2320 - """ - @js.native - @JSName("foo") - object Bar extends js.GlobalScope - """ containsWarns - """ - |newSource1.scala:6: warning: An @JSName annotation is ignored in the presence of @JSGlobalScope (or extends js.GlobalScope), and should be removed. This will be enforced in 1.0. - | @JSName("foo") - | ^ - """ - - } - - @Test - def noJSGlobalOnJSGlobalScope: Unit = { - - """ - @js.native - @JSGlobal - object Bar extends js.GlobalScope - """ hasErrors - """ - |newSource1.scala:6: error: Native JS classes and objects can only have one annotation among JSName, JSGlobal, JSImport and JSGlobalScope (extending js.GlobalScope is treated as having @JSGlobalScope). - | @JSGlobal - | ^ - """ - - } - - @Test - def noJSImportOnJSGlobalScope: Unit = { - - """ - @js.native - @JSImport("foo", JSImport.Namespace) - object Bar extends js.GlobalScope - """ hasErrors - """ - |newSource1.scala:6: error: Native JS classes and objects can only have one annotation among JSName, JSGlobal, JSImport and JSGlobalScope (extending js.GlobalScope is treated as having @JSGlobalScope). - | @JSImport("foo", JSImport.Namespace) - | ^ - """ - - } - @Test def noLocalClass: Unit = { @@ -1216,18 +1127,6 @@ class JSInteropTest extends DirectTest with TestHelpers { } - @Test - def nestedJSGlobalScopeWithoutExplicitName: Unit = { - // #2319 - """ - object Outer { - @js.native - object Foo extends js.GlobalScope - } - """.succeeds - - } - @Test def noNativeClassObjectInsideScalaJSDefinedObject: Unit = { diff --git a/library/src/main/scala/scala/scalajs/js/GlobalScope.scala b/library/src/main/scala/scala/scalajs/js/GlobalScope.scala deleted file mode 100644 index d077409d83..0000000000 --- a/library/src/main/scala/scala/scalajs/js/GlobalScope.scala +++ /dev/null @@ -1,23 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - - -package scala.scalajs.js - -/** Marker trait for top-level objects representing the JS global scope. - * - * When calling method on a top-level object or package object that is a - * subtype of GlobalScope, the receiver is dropped, and the JavaScript global - * scope is used instead. - * - * @see [[http://www.scala-js.org/doc/calling-javascript.html Calling JavaScript from Scala.js]] - */ -@deprecated("Use the annotation @js.annotation.JSGlobalScope instead.", "0.6.13") -@native -trait GlobalScope extends Any diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala index de41a44ed5..c6a98914e3 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala @@ -375,29 +375,6 @@ class InteroperabilityTest { assertEquals(42, Global.interoperabilityTestGlobalScopeValueAsInt) } - @Test def should_acces_top_level_JS_objects_via_Scala_object_inheriting_from_js_GlobalScope(): Unit = { - js.eval(""" - var interoperabilityTestGlobalScopeDeprecatedValue = "7357"; - var interoperabilityTestGlobalScopeDeprecatedValueAsInt = function() { - return parseInt(interoperabilityTestGlobalScopeDeprecatedValue); - }; - """) - - // Use alias for convenience: see end of file for definition - val Global = InteroperabilityTestGlobalScopeDeprecated - - assertEquals("7357", Global.interoperabilityTestGlobalScopeDeprecatedValue) - assertEquals(7357, Global.interoperabilityTestGlobalScopeDeprecatedValueAsInt) - - Global.interoperabilityTestGlobalScopeDeprecatedValue = "42" - assertEquals(42, Global.interoperabilityTestGlobalScopeDeprecatedValueAsInt) - } - - @Test def extends_js_GlobalScope_takes_precedence_over_JSName(): Unit = { - assertSame(js.Dynamic.global, - InteroperabilityTestGlobalScopeDeprecatedWithJSName) - } - @Test def should_protect_receiver_of_raw_JS_apply_if_its_a_select_issue_804(): Unit = { val rawReceiver = js.eval(""" var interoperabilityTestRawReceiver = { @@ -884,16 +861,6 @@ object InteroperabilityTestGlobalScope extends js.Object { def interoperabilityTestGlobalScopeValueAsInt(): Int = js.native } -@js.native -object InteroperabilityTestGlobalScopeDeprecated extends js.GlobalScope { - var interoperabilityTestGlobalScopeDeprecatedValue: String = js.native - def interoperabilityTestGlobalScopeDeprecatedValueAsInt(): Int = js.native -} - -@js.native -@JSName("ThisDoesNotExistButItIsIgnored") -object InteroperabilityTestGlobalScopeDeprecatedWithJSName extends js.GlobalScope - class SomeValueClass(val i: Int) extends AnyVal { override def toString(): String = s"SomeValueClass($i)" } From ec3c3bd685ff32f9fbbe4e19db085cb651babf8c Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 25 Mar 2017 16:08:17 +0100 Subject: [PATCH 0173/2665] Scala 2.13 parallel collection support for linker This changes the inner type of the AtomicAcc from List to ParVector. The change was inspired by simplicity, but also reduces allocations, since the elements need not be copied any more to move to a ParArray. --- project/BinaryIncompatibilities.scala | 13 +++++++++++++ project/Build.scala | 7 +++++++ .../frontend/optimizer/ConcurrencyUtils.scala | 15 ++++++++------- .../frontend/optimizer/ParIncOptimizer.scala | 17 +++++++++-------- 4 files changed, 37 insertions(+), 15 deletions(-) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index c77318b933..dafb831e1d 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -6,6 +6,19 @@ object BinaryIncompatibilities { ) val Tools = Seq( + // private[optimizer], not an issue + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "org.scalajs.core.tools.linker.frontend.optimizer.ConcurrencyUtils#AtomicAcc.apply"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.core.tools.linker.frontend.optimizer.ConcurrencyUtils#AtomicAccOps.removeAll$extension"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.core.tools.linker.frontend.optimizer.ConcurrencyUtils#AtomicAccOps.removeAll"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "org.scalajs.core.tools.linker.frontend.optimizer.ParIncOptimizer#CollOps.prepAdd"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.core.tools.linker.frontend.optimizer.ParIncOptimizer#CollOps.finishAdd"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.core.tools.linker.frontend.optimizer.ParIncOptimizer#CollOps.emptyParIterable") ) val JSEnvs = Seq( diff --git a/project/Build.scala b/project/Build.scala index da66a3f7ac..c30d40b6a1 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -584,6 +584,13 @@ object Build { "org.scala-js" % "closure-compiler-java-6" % "v20160517", "com.googlecode.json-simple" % "json-simple" % "1.1.1" exclude("junit", "junit"), "com.novocode" % "junit-interface" % "0.9" % "test" + ) ++ ( + CrossVersion.partialVersion(scalaVersion.value) match { + case Some((2, n)) if n >= 13 => + Seq("org.scala-lang.modules" %% "scala-parallel-collections" % "0.1.1") + + case _ => Nil + } ) ) ).dependsOn(irProject) diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ConcurrencyUtils.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ConcurrencyUtils.scala index c76941e04f..145f1e9143 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ConcurrencyUtils.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ConcurrencyUtils.scala @@ -12,6 +12,7 @@ package org.scalajs.core.tools.linker.frontend.optimizer import scala.annotation.tailrec import scala.collection.concurrent.TrieMap +import scala.collection.parallel.immutable.ParVector import java.util.concurrent.atomic._ @@ -19,12 +20,12 @@ private[optimizer] object ConcurrencyUtils { /** An atomic accumulator supports adding single elements and retrieving and * deleting all contained elements */ - type AtomicAcc[T] = AtomicReference[List[T]] + type AtomicAcc[T] = AtomicReference[ParVector[T]] object AtomicAcc { @inline final def empty[T]: AtomicAcc[T] = - new AtomicReference[List[T]](Nil) - @inline final def apply[T](l: List[T]): AtomicAcc[T] = + new AtomicReference(ParVector.empty[T]) + @inline final def apply[T](l: ParVector[T]): AtomicAcc[T] = new AtomicReference(l) } @@ -35,7 +36,7 @@ private[optimizer] object ConcurrencyUtils { final def +=(x: T): Unit = AtomicAccOps.append(acc, x) @inline - final def removeAll(): List[T] = AtomicAccOps.removeAll(acc) + final def removeAll(): ParVector[T] = AtomicAccOps.removeAll(acc) } object AtomicAccOps { @@ -43,13 +44,13 @@ private[optimizer] object ConcurrencyUtils { @tailrec private final def append[T](acc: AtomicAcc[T], x: T): Boolean = { val oldV = acc.get - val newV = x :: oldV + val newV = oldV :+ x acc.compareAndSet(oldV, newV) || append(acc, x) } @inline - private final def removeAll[T](acc: AtomicAcc[T]): List[T] = - acc.getAndSet(Nil) + private final def removeAll[T](acc: AtomicAcc[T]): ParVector[T] = + acc.getAndSet(ParVector.empty) } type TrieSet[T] = TrieMap[T, Null] diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ParIncOptimizer.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ParIncOptimizer.scala index 9ef7cb14f3..ef8205c8fc 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ParIncOptimizer.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ParIncOptimizer.scala @@ -11,7 +11,8 @@ package org.scalajs.core.tools.linker.frontend.optimizer import scala.collection.{GenTraversableOnce, GenIterable} import scala.collection.concurrent.TrieMap -import scala.collection.parallel.mutable.{ParTrieMap, ParArray} +import scala.collection.parallel.mutable.ParTrieMap +import scala.collection.parallel.immutable.ParVector import java.util.concurrent.atomic._ @@ -28,13 +29,13 @@ final class ParIncOptimizer(semantics: Semantics, esLevel: ESLevel, type Map[K, V] = TrieMap[K, V] type ParMap[K, V] = ParTrieMap[K, V] type AccMap[K, V] = TrieMap[K, AtomicAcc[V]] - type ParIterable[V] = ParArray[V] + type ParIterable[V] = ParVector[V] type Addable[V] = AtomicAcc[V] def emptyAccMap[K, V]: AccMap[K, V] = TrieMap.empty def emptyMap[K, V]: Map[K, V] = TrieMap.empty def emptyParMap[K, V]: ParMap[K, V] = ParTrieMap.empty - def emptyParIterable[V]: ParIterable[V] = ParArray.empty + def emptyParIterable[V]: ParIterable[V] = ParVector.empty // Operations on ParMap def put[K, V](map: ParMap[K, V], k: K, v: V): Unit = map.put(k, v) @@ -52,21 +53,21 @@ final class ParIncOptimizer(semantics: Semantics, esLevel: ESLevel, map.getOrPut(k, AtomicAcc.empty) += v def getAcc[K, V](map: AccMap[K, V], k: K): GenIterable[V] = - map.get(k).fold[Iterable[V]](Nil)(_.removeAll()).toParArray + map.get(k).fold[ParVector[V]](ParVector.empty)(_.removeAll()) def parFlatMapKeys[A, B](map: AccMap[A, _])( f: A => GenTraversableOnce[B]): GenIterable[B] = - map.keys.flatMap(f).toParArray + new ParVector(map.keys.flatMap(f).toVector) // Operations on ParIterable def prepAdd[V](it: ParIterable[V]): Addable[V] = - AtomicAcc(it.toList) + AtomicAcc(it) def add[V](addable: Addable[V], v: V): Unit = addable += v def finishAdd[V](addable: Addable[V]): ParIterable[V] = - addable.removeAll().toParArray + addable.removeAll() } private val _interfaces = TrieMap.empty[String, InterfaceType] @@ -81,7 +82,7 @@ final class ParIncOptimizer(semantics: Semantics, esLevel: ESLevel, encodedName: String): MethodImpl = new ParMethodImpl(owner, encodedName) private[optimizer] def processAllTaggedMethods(): Unit = { - val methods = methodsToProcess.removeAll().toParArray + val methods = methodsToProcess.removeAll() logProcessingMethods(methods.count(!_.deleted)) for (method <- methods) method.process() From 8899bd0f1c609964a922434171e0fc18d45eff48 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 25 Mar 2017 20:56:15 +0100 Subject: [PATCH 0174/2665] Remove RhinoLinkFailureTest. It doesn't test what we intended. See #2848. --- .../noircheck/RhinoLinkFailureTest.scala | 34 ------------------- 1 file changed, 34 deletions(-) delete mode 100644 no-ir-check-test/src/test/scala/org/scalajs/testsuite/noircheck/RhinoLinkFailureTest.scala diff --git a/no-ir-check-test/src/test/scala/org/scalajs/testsuite/noircheck/RhinoLinkFailureTest.scala b/no-ir-check-test/src/test/scala/org/scalajs/testsuite/noircheck/RhinoLinkFailureTest.scala deleted file mode 100644 index 6aecea3d84..0000000000 --- a/no-ir-check-test/src/test/scala/org/scalajs/testsuite/noircheck/RhinoLinkFailureTest.scala +++ /dev/null @@ -1,34 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ -package org.scalajs.testsuite.noircheck - -import org.junit.Test -import org.junit.Assert._ -import org.junit.Assume._ - -import scala.scalajs.js - -class RhinoLinkFailureTest { - - @Test def Rhino_linking_should_throw_an_exception_if_it_fails_loading_a_class(): Unit = { - val executingInRhino = System.getProperty("scalajs.rhino", "false") == "true" - assumeTrue("Assumed executing in Rhino", executingInRhino) - - // scala.collection.parallel.Splitter$ is not defined - try { - val pool = scala.collection.parallel.Splitter.empty - sys.error("Should not reach here") - } catch { - case js.JavaScriptException(e) => - // Make sure offending class is reported - assertTrue(e.toString.contains("sc_parallel_Splitter$")) - } - - } - -} From ac476e4e298323f62a9d990abe5cbb7538e5ccfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 27 Mar 2017 23:33:01 +0200 Subject: [PATCH 0175/2665] Separate all PhantomJS-related things in distinct projects. This is part of #2839. * `PhantomJSEnv` and `RetryingComJSEnv` are sent to their own `phantomJSEnv` sbt project. * The settings and tasks used to construct the `ClassLoader` that loads jetty8 are extracted into a separate `AutoPlugin`, named `PhantomJSEnvPlugin`, in the sbt project `phantomJSEnvPlugin`. * The tests in `sbt-plugin-test` do not mix PhantomJS-related tests with other tests anymore (in particular `jsDependencies`). --- build.sbt | 2 + ci/matrix.xml | 17 +-- .../jsenv/phantomjs/WebsocketListener.scala | 10 -- .../jsenv/phantomjs/WebsocketManager.scala | 10 -- .../phantomjs/JettyWebsocketManager.scala | 8 ++ .../jsenv/phantomjs/PhantomJSEnv.scala | 15 ++- .../phantomjs/PhantomJettyClassLoader.scala | 8 ++ .../jsenv/phantomjs}/RetryingComJSEnv.scala | 23 ++-- .../jsenv/phantomjs/WebsocketListener.scala | 18 ++++ .../jsenv/phantomjs/WebsocketManager.scala | 18 ++++ .../jsenv/phantomjs}/PhantomJSTest.scala | 4 +- .../PhantomJSWithCustomInitFilesTest.scala | 4 +- .../phantomjs}/RetryingComJSEnvTest.scala | 4 +- .../sbtplugin/PhantomJSEnvPlugin.scala | 102 ++++++++++++++++++ project/Build.scala | 60 +++++++++-- project/build.sbt | 4 +- sbt-plugin-test/build.sbt | 33 +++--- sbt-plugin-test/project/Jetty9Test.scala | 20 ++-- sbt-plugin-test/project/build.sbt | 3 + .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 33 ------ .../sbtplugin/ScalaJSPluginInternal.scala | 22 ---- 21 files changed, 282 insertions(+), 136 deletions(-) delete mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketListener.scala delete mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketManager.scala rename {js-envs => phantomjs-env}/src/main/scala/org/scalajs/jsenv/phantomjs/JettyWebsocketManager.scala (88%) rename {js-envs => phantomjs-env}/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala (98%) rename {js-envs => phantomjs-env}/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJettyClassLoader.scala (81%) rename {js-envs/src/main/scala/org/scalajs/jsenv => phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs}/RetryingComJSEnv.scala (90%) create mode 100644 phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketListener.scala create mode 100644 phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketManager.scala rename {js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test => phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs}/PhantomJSTest.scala (59%) rename {js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test => phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs}/PhantomJSWithCustomInitFilesTest.scala (71%) rename {js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test => phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs}/RetryingComJSEnvTest.scala (97%) create mode 100644 phantomjs-sbt-plugin/src/main/scala/org/scalajs/jsenv/phantomjs/sbtplugin/PhantomJSEnvPlugin.scala diff --git a/build.sbt b/build.sbt index 85e48571c7..b47aa80d38 100644 --- a/build.sbt +++ b/build.sbt @@ -22,6 +22,8 @@ val jUnitRuntime = Build.jUnitRuntime val jUnitTestOutputsJS = Build.jUnitTestOutputsJS val jUnitTestOutputsJVM = Build.jUnitTestOutputsJVM val jUnitPlugin = Build.jUnitPlugin +val phantomJSEnv = Build.phantomJSEnv +val phantomJSEnvPlugin = Build.phantomJSEnvPlugin val examples = Build.examples val helloworld = Build.helloworld val reversi = Build.reversi diff --git a/ci/matrix.xml b/ci/matrix.xml index 733ed924a8..6061674764 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -31,9 +31,9 @@ sbtretry 'set scalaJSSemantics in helloworld ~= (_.withAsInstanceOfs(org.scalajs.core.tools.sem.CheckedBehavior.Unchecked))' \ ++$scala helloworld/run \ helloworld/clean && - sbtretry 'set inScope(ThisScope in helloworld)(jsEnv := new org.scalajs.jsenv.RetryingComJSEnv(PhantomJSEnv().value))' \ + sbtretry 'set inScope(ThisScope in helloworld)(jsEnv := new org.scalajs.jsenv.phantomjs.RetryingComJSEnv(PhantomJSEnv().value))' \ ++$scala helloworld/run && - sbtretry 'set inScope(ThisScope in helloworld)(jsEnv := new org.scalajs.jsenv.RetryingComJSEnv(PhantomJSEnv().value))' \ + sbtretry 'set inScope(ThisScope in helloworld)(jsEnv := new org.scalajs.jsenv.phantomjs.RetryingComJSEnv(PhantomJSEnv().value))' \ 'set scalaJSStage in Global := FullOptStage' \ ++$scala helloworld/run \ helloworld/clean && @@ -49,15 +49,15 @@ sbtretry 'set scalaJSStage in Global := FullOptStage' \ ++$scala testingExample/test:run testingExample/test \ testingExample/clean && - sbtretry 'set inScope(ThisScope in testingExample)(jsEnv := new org.scalajs.jsenv.RetryingComJSEnv(PhantomJSEnv().value))' \ + sbtretry 'set inScope(ThisScope in testingExample)(jsEnv := new org.scalajs.jsenv.phantomjs.RetryingComJSEnv(PhantomJSEnv().value))' \ ++$scala testingExample/test:run testingExample/test && - sbtretry 'set inScope(ThisScope in testingExample)(jsEnv := new org.scalajs.jsenv.RetryingComJSEnv(PhantomJSEnv().value))' \ + sbtretry 'set inScope(ThisScope in testingExample)(jsEnv := new org.scalajs.jsenv.phantomjs.RetryingComJSEnv(PhantomJSEnv().value))' \ 'set scalaJSStage in Global := FullOptStage' \ ++$scala testingExample/test:run testingExample/test \ testingExample/clean && sbtretry 'set scalaJSOptimizerOptions in testingExample ~= (_.withDisableOptimizer(true))' \ ++$scala testingExample/test:run testingExample/test && - sbtretry 'set inScope(ThisScope in testingExample)(jsEnv := new org.scalajs.jsenv.RetryingComJSEnv(PhantomJSEnv().value))' \ + sbtretry 'set inScope(ThisScope in testingExample)(jsEnv := new org.scalajs.jsenv.phantomjs.RetryingComJSEnv(PhantomJSEnv().value))' \ 'set scalaJSOptimizerOptions in testingExample ~= (_.withDisableOptimizer(true))' \ ++$scala testingExample/test:run testingExample/test && sbtretry ++$scala library/test && @@ -107,10 +107,10 @@ 'set scalaJSOptimizerOptions in $testSuite ~= (_.withDisableOptimizer(true))' \ ++$scala $testSuite/test \ $testSuite/clean && - sbtretry 'set inScope(ThisScope in $testSuite)(jsEnv := new org.scalajs.jsenv.RetryingComJSEnv(PhantomJSEnv().value))' \ + sbtretry 'set inScope(ThisScope in $testSuite)(jsEnv := new org.scalajs.jsenv.phantomjs.RetryingComJSEnv(PhantomJSEnv().value))' \ 'set parallelExecution in ($testSuite, Test) := false' \ ++$scala $testSuite/test && - sbtretry 'set inScope(ThisScope in $testSuite)(jsEnv := new org.scalajs.jsenv.RetryingComJSEnv(PhantomJSEnv().value))' \ + sbtretry 'set inScope(ThisScope in $testSuite)(jsEnv := new org.scalajs.jsenv.phantomjs.RetryingComJSEnv(PhantomJSEnv().value))' \ 'set parallelExecution in ($testSuite, Test) := false' \ 'set scalaJSStage in Global := FullOptStage' \ ++$scala $testSuite/test \ @@ -239,7 +239,8 @@ testInterface/publishLocal stubs/publishLocal \ jUnitPlugin/publishLocal jUnitRuntime/publishLocal && sbt ++2.10.6 ir/publishLocal tools/publishLocal jsEnvs/publishLocal \ - testAdapter/publishLocal sbtPlugin/publishLocal && + testAdapter/publishLocal sbtPlugin/publishLocal \ + phantomJSEnv/publishLocal phantomJSEnvPlugin/publishLocal && cd sbt-plugin-test && sbt noDOM/run noDOM/testHtmlFastOpt noDOM/testHtmlFullOpt \ withDOM/run withDOM/testHtmlFastOpt withDOM/testHtmlFullOpt \ diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketListener.scala b/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketListener.scala deleted file mode 100644 index b26dc1dcf9..0000000000 --- a/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketListener.scala +++ /dev/null @@ -1,10 +0,0 @@ -package org.scalajs.jsenv.phantomjs - -private[phantomjs] trait WebsocketListener { - def onRunning(): Unit - def onOpen(): Unit - def onClose(): Unit - def onMessage(msg: String): Unit - - def log(msg: String): Unit -} diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketManager.scala b/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketManager.scala deleted file mode 100644 index 875393c070..0000000000 --- a/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketManager.scala +++ /dev/null @@ -1,10 +0,0 @@ -package org.scalajs.jsenv.phantomjs - -private[phantomjs] trait WebsocketManager { - def start(): Unit - def stop(): Unit - def sendMessage(msg: String): Unit - def localPort: Int - def isConnected: Boolean - def isClosed: Boolean -} diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/JettyWebsocketManager.scala b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/JettyWebsocketManager.scala similarity index 88% rename from js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/JettyWebsocketManager.scala rename to phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/JettyWebsocketManager.scala index 0d5019fca6..97a9b8c303 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/JettyWebsocketManager.scala +++ b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/JettyWebsocketManager.scala @@ -1,3 +1,11 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ PhantomJS support for Scala.js ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ https://www.scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + package org.scalajs.jsenv.phantomjs import javax.servlet.http.HttpServletRequest diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala similarity index 98% rename from js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala rename to phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala index 4aaf1a2866..e9a54895d6 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala +++ b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala @@ -1,11 +1,10 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* __ *\ +** ________ ___ / / ___ __ ____ PhantomJS support for Scala.js ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ https://www.scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ package org.scalajs.jsenv.phantomjs diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJettyClassLoader.scala b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJettyClassLoader.scala similarity index 81% rename from js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJettyClassLoader.scala rename to phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJettyClassLoader.scala index 428279e4c7..6b9ab89628 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJettyClassLoader.scala +++ b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJettyClassLoader.scala @@ -1,3 +1,11 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ PhantomJS support for Scala.js ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ https://www.scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + package org.scalajs.jsenv.phantomjs import org.scalajs.core.tools.io.IO diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/RetryingComJSEnv.scala b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnv.scala similarity index 90% rename from js-envs/src/main/scala/org/scalajs/jsenv/RetryingComJSEnv.scala rename to phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnv.scala index 9c879332d4..850b535120 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/RetryingComJSEnv.scala +++ b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnv.scala @@ -1,18 +1,19 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* __ *\ +** ________ ___ / / ___ __ ____ PhantomJS support for Scala.js ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ https://www.scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ - -package org.scalajs.jsenv +package org.scalajs.jsenv.phantomjs import org.scalajs.core.tools.io._ import org.scalajs.core.tools.logging.Logger import org.scalajs.core.tools.jsdep.ResolvedJSDependency +import org.scalajs.jsenv._ + import scala.concurrent.{Future, Promise, ExecutionContext} import scala.concurrent.duration.Duration import scala.collection.mutable @@ -30,6 +31,10 @@ import scala.util.{Try, Failure, Success} * property. * * No retrying is performed for synchronous, or normal asynchronous runs. + * + * Although `RetryingComJSEnv` is agnostic of the underlying JS env, and is + * therefore not tied to PhantomJS, it is most often used to compensate for + * flakiness effects of PhantomJS. */ final class RetryingComJSEnv(val baseEnv: ComJSEnv, val maxRetries: Int) extends ComJSEnv { diff --git a/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketListener.scala b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketListener.scala new file mode 100644 index 0000000000..a05f76407d --- /dev/null +++ b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketListener.scala @@ -0,0 +1,18 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ PhantomJS support for Scala.js ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ https://www.scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.jsenv.phantomjs + +private[phantomjs] trait WebsocketListener { + def onRunning(): Unit + def onOpen(): Unit + def onClose(): Unit + def onMessage(msg: String): Unit + + def log(msg: String): Unit +} diff --git a/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketManager.scala b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketManager.scala new file mode 100644 index 0000000000..489c4b4201 --- /dev/null +++ b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketManager.scala @@ -0,0 +1,18 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ PhantomJS support for Scala.js ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ https://www.scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.jsenv.phantomjs + +private[phantomjs] trait WebsocketManager { + def start(): Unit + def stop(): Unit + def sendMessage(msg: String): Unit + def localPort: Int + def isConnected: Boolean + def isClosed: Boolean +} diff --git a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/PhantomJSTest.scala b/phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/PhantomJSTest.scala similarity index 59% rename from js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/PhantomJSTest.scala rename to phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/PhantomJSTest.scala index b4fd37df0f..c3894e1025 100644 --- a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/PhantomJSTest.scala +++ b/phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/PhantomJSTest.scala @@ -1,6 +1,6 @@ -package org.scalajs.jsenv.test +package org.scalajs.jsenv.phantomjs -import org.scalajs.jsenv.phantomjs.PhantomJSEnv +import org.scalajs.jsenv.test._ class PhantomJSTest extends JSEnvTest with ComTests { protected def newJSEnv: PhantomJSEnv = new PhantomJSEnv diff --git a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/PhantomJSWithCustomInitFilesTest.scala b/phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/PhantomJSWithCustomInitFilesTest.scala similarity index 71% rename from js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/PhantomJSWithCustomInitFilesTest.scala rename to phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/PhantomJSWithCustomInitFilesTest.scala index 8c31699b45..17716457a3 100644 --- a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/PhantomJSWithCustomInitFilesTest.scala +++ b/phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/PhantomJSWithCustomInitFilesTest.scala @@ -1,6 +1,6 @@ -package org.scalajs.jsenv.test +package org.scalajs.jsenv.phantomjs -import org.scalajs.jsenv.phantomjs.PhantomJSEnv +import org.scalajs.jsenv.test._ class PhantomJSWithCustomInitFilesTest extends CustomInitFilesTest { protected def newJSEnv: PhantomJSEnv = new PhantomJSEnv { diff --git a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/RetryingComJSEnvTest.scala b/phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnvTest.scala similarity index 97% rename from js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/RetryingComJSEnvTest.scala rename to phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnvTest.scala index 4aeccda56c..484fb4d3bf 100644 --- a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/RetryingComJSEnvTest.scala +++ b/phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnvTest.scala @@ -1,10 +1,12 @@ -package org.scalajs.jsenv.test +package org.scalajs.jsenv.phantomjs import org.scalajs.core.tools.io.VirtualJSFile import org.scalajs.core.tools.jsdep.ResolvedJSDependency import org.scalajs.core.tools.logging._ + import org.scalajs.jsenv.nodejs.NodeJSEnv import org.scalajs.jsenv.{ComJSRunner, JSConsole, _} +import org.scalajs.jsenv.test._ import scala.concurrent.Future import scala.concurrent.duration.Duration diff --git a/phantomjs-sbt-plugin/src/main/scala/org/scalajs/jsenv/phantomjs/sbtplugin/PhantomJSEnvPlugin.scala b/phantomjs-sbt-plugin/src/main/scala/org/scalajs/jsenv/phantomjs/sbtplugin/PhantomJSEnvPlugin.scala new file mode 100644 index 0000000000..363aab6d09 --- /dev/null +++ b/phantomjs-sbt-plugin/src/main/scala/org/scalajs/jsenv/phantomjs/sbtplugin/PhantomJSEnvPlugin.scala @@ -0,0 +1,102 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ PhantomJS support for Scala.js ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ https://www.scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.jsenv.phantomjs.sbtplugin + +import sbt._ +import sbt.Keys._ + +import java.net.URLClassLoader + +import org.scalajs.sbtplugin.ScalaJSPlugin +import org.scalajs.sbtplugin.ScalaJSPlugin.autoImport._ + +import org.scalajs.jsenv._ +import org.scalajs.jsenv.phantomjs._ + +/** An sbt plugin that simplifies the setup of [[PhantomJSEnv]]s. + * + * There is no need to use `enablePlugins(PhantomJSEnvPlugin)`, as this plugin + * is automatically triggered by Scala.js projects. + * + * Usually, one only needs to use the + * [[PhantomJSEnvPlugin.autoImport.PhantomJSEnv]] method. + */ +object PhantomJSEnvPlugin extends AutoPlugin { + override def requires: Plugins = ScalaJSPlugin + override def trigger: PluginTrigger = allRequirements + + object autoImport { + /** Class loader for PhantomJSEnv, used to load jetty8. + * + * Usually, you should not need to use `scalaJSPhantomJSClassLoader` + * directly. Instead, use the `PhantomJSEnv()` function. + */ + val scalaJSPhantomJSClassLoader: TaskKey[ClassLoader] = { + TaskKey[ClassLoader]( + "scalaJSPhantomJSClassLoader", + "Private class loader to load jetty8 without polluting the " + + "classpath. Only use this as the `jettyClassLoader` argument of " + + "a PhantomJSEnv.", + KeyRanks.Invisible) + } + + /** An [[sbt.Def.Initialize Def.Initialize]] for a [[PhantomJSEnv]]. + * + * Use this to specify in your build that you would like to run and/or + * test a project 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(executable, args, env, autoExit, loader) + } + } + + import autoImport._ + + val phantomJSJettyModules: Seq[ModuleID] = Seq( + "org.eclipse.jetty" % "jetty-websocket" % "8.1.16.v20140903", + "org.eclipse.jetty" % "jetty-server" % "8.1.16.v20140903" + ) + + override def projectSettings: Seq[Setting[_]] = Seq( + /* Depend on jetty artifacts in a 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) + } + ) + +} diff --git a/project/Build.scala b/project/Build.scala index 2215989130..9f18b6d354 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -20,9 +20,12 @@ import org.scalajs.core.ir import org.scalajs.core.ir.Utils.escapeJS import org.scalajs.sbtplugin._ -import org.scalajs.jsenv.{JSEnv, RetryingComJSEnv} +import org.scalajs.jsenv.JSEnv import org.scalajs.jsenv.nodejs.{NodeJSEnv, JSDOMNodeJSEnv} -import org.scalajs.jsenv.phantomjs.PhantomJSEnv + +import org.scalajs.jsenv.phantomjs.sbtplugin.PhantomJSEnvPlugin +import org.scalajs.jsenv.phantomjs.{PhantomJSEnv, RetryingComJSEnv} + import ScalaJSPlugin.autoImport._ import ExternalCompile.scalaJSExternalCompileSettings import Loggers._ @@ -347,7 +350,10 @@ object Build { publishMavenStyle := false ) - val myScalaJSSettings = ScalaJSPluginInternal.scalaJSAbstractSettings ++ Seq( + val myScalaJSSettings = ( + ScalaJSPluginInternal.scalaJSAbstractSettings ++ + PhantomJSEnvPlugin.projectSettings + ) ++ Seq( autoCompilerPlugins := true, scalaJSOptimizerOptions ~= (_.withCheckScalaJSIR(true)), @@ -700,8 +706,6 @@ object Build { commonSettings ++ publishSettings ++ fatalWarningsSettings ) ++ Seq( name := "Scala.js JS Envs", - libraryDependencies ++= - ScalaJSPluginInternal.phantomJSJettyModules.map(_ % "provided"), previousArtifactSetting, mimaBinaryIssueFilters ++= BinaryIncompatibilities.JSEnvs ) @@ -728,9 +732,8 @@ object Build { commonSettings ++ fatalWarningsSettings ) ++ Seq( name := "Scala.js JS Envs Test Suite", - libraryDependencies ++= Seq( - "com.novocode" % "junit-interface" % "0.9" % "test" - ) ++ ScalaJSPluginInternal.phantomJSJettyModules.map(_ % "provided") + libraryDependencies += + "com.novocode" % "junit-interface" % "0.9" % "test" ) ).dependsOn(tools, jsEnvs, jsEnvsTestKit % "test") @@ -1206,6 +1209,47 @@ object Build { ) ) + // PhantomJS support - to be moved out of the core repository + + lazy val phantomJSEnv: Project = Project( + id = "phantomJSEnv", + base = file("phantomjs-env"), + settings = ( + commonSettings ++ publishSettings ++ fatalWarningsSettings + ) ++ Seq( + name := "scalajs-env-phantomjs", + libraryDependencies ++= + PhantomJSEnvPlugin.phantomJSJettyModules.map(_ % "provided"), + libraryDependencies += + "com.novocode" % "junit-interface" % "0.9" % "test" + ) + ).dependsOn(jsEnvs, jsEnvsTestKit % "test") + + lazy val phantomJSEnvPlugin: Project = Project( + id = "phantomJSEnvPlugin", + base = file("phantomjs-sbt-plugin"), + settings = ( + commonSettings ++ publishIvySettings ++ fatalWarningsSettings + ) ++ Seq( + name := "sbt-scalajs-env-phantomjs", + sbtPlugin := true, + scalaBinaryVersion := + CrossVersion.binaryScalaVersion(scalaVersion.value), + + // Add API mappings for sbt (seems they don't export their API URL) + apiMappings ++= { + val deps = (externalDependencyClasspath in Compile).value + val sbtJars = deps filter { attributed => + val p = attributed.data.getPath + p.contains("/org.scala-sbt/") && p.endsWith(".jar") + } + val docUrl = + url(s"http://www.scala-sbt.org/${sbtVersion.value}/api/") + sbtJars.map(_.data -> docUrl).toMap + } + ) + ).dependsOn(plugin, phantomJSEnv) + // Examples lazy val examples: Project = Project( diff --git a/project/build.sbt b/project/build.sbt index 28543e18f5..2ff758b90d 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -30,7 +30,9 @@ unmanagedSourceDirectories in Compile ++= { root / "tools/jvm/src/main/scala", root / "js-envs/src/main/scala", root / "test-adapter/src/main/scala", - root / "sbt-plugin/src/main/scala" + root / "sbt-plugin/src/main/scala", + root / "phantomjs-env/src/main/scala", + root / "phantomjs-sbt-plugin/src/main/scala" ) } diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index dd51eb23d3..cbd595b88e 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -73,15 +73,8 @@ lazy val jetty9 = project.settings(baseSettings: _*). enablePlugins(ScalaJSPlugin). settings( name := "Scala.js sbt test with jetty9 on classpath", - // This project also tests packageJSDependencies, although we don't use it - jsDependencies ++= Seq( - RuntimeDOM, - // The jsDependenciesTest relies on this jQuery dependency - // If you change it, make sure we still test properly - "org.webjars" % "jquery" % "1.10.2" / "jquery.js" - ), // Use PhantomJS, allow cross domain requests - postLinkJSEnv := PhantomJSEnv(args = Seq("--web-security=no")).value, + jsEnv := PhantomJSEnv(args = Seq("--web-security=no")).value, Jetty9Test.runSetting ) @@ -163,6 +156,19 @@ lazy val multiTest = crossProject. lazy val multiTestJS = multiTest.js lazy val multiTestJVM = multiTest.jvm +lazy val jsDependenciesTestDependee = project. + settings(versionSettings: _*). + enablePlugins(ScalaJSPlugin). + settings( + // This project contains some jsDependencies to test in jsDependenciesTest + jsDependencies ++= Seq( + RuntimeDOM, + // The jsDependenciesTest relies on this jQuery dependency + // If you change it, make sure we still test properly + "org.webjars" % "jquery" % "1.10.2" / "jquery.js" + ) + ) + lazy val jsDependenciesTest = withRegretionTestForIssue2243( project.settings(versionSettings: _*). enablePlugins(ScalaJSPlugin). @@ -179,14 +185,17 @@ lazy val jsDependenciesTest = withRegretionTestForIssue2243( "org.webjars" % "mustachejs" % "0.8.2" / "mustache.js" commonJSName "Mustache", "org.webjars" % "mustachejs" % "0.8.2" / "0.8.2/mustache.js" commonJSName "Mustache", - // cause an ambiguity with jQuery dependency from jetty9 project (if we don't filter) + // cause an ambiguity with the jQuery dependency from the + // jsDependenciesTestDependee project (if we don't filter) ProvidedJS / "js/customJQuery/jquery.js" dependsOn "1.10.2/jquery.js", // Test minified dependencies "org.webjars" % "immutable" % "3.4.0" / "immutable.js" minified "immutable.min.js" ), - jsManifestFilter := ManifestFilters.reinterpretResourceNames("jetty9")( - "jquery.js" -> "1.10.2/jquery.js") + jsManifestFilter := { + ManifestFilters.reinterpretResourceNames("jsDependenciesTestDependee")( + "jquery.js" -> "1.10.2/jquery.js") + } ). settings(inConfig(Compile)(Seq( packageJSDependencies <<= packageJSDependencies.dependsOn(Def.task { @@ -227,7 +236,7 @@ lazy val jsDependenciesTest = withRegretionTestForIssue2243( streams.value.log.info("jsDependencies resolution test passed") }) )): _*). - dependsOn(jetty9) // depends on jQuery + dependsOn(jsDependenciesTestDependee) // depends on jQuery ) lazy val jsNoDependenciesTest = withRegretionTestForIssue2243( diff --git a/sbt-plugin-test/project/Jetty9Test.scala b/sbt-plugin-test/project/Jetty9Test.scala index 809b1bd94e..e988c27543 100644 --- a/sbt-plugin-test/project/Jetty9Test.scala +++ b/sbt-plugin-test/project/Jetty9Test.scala @@ -27,17 +27,17 @@ object Jetty9Test { val code = new MemVirtualJSFile("runner.js").withContent( """ scalajsCom.init(function(msg) { - jQuery.ajax({ - url: msg, - success: function(dat) { - scalajsCom.send(dat.trim()); - scalajsCom.close(); - }, - error: function() { - scalajsCom.send("failed!"); - scalajsCom.close(); - } + var xhr = new XMLHttpRequest(); + xhr.open("GET", msg); + xhr.onload = (function() { + scalajsCom.send(xhr.responseText.trim()); + scalajsCom.close(); }); + xhr.onerror = (function() { + scalajsCom.send("failed!"); + scalajsCom.close(); + }); + xhr.send(); }); """ ) diff --git a/sbt-plugin-test/project/build.sbt b/sbt-plugin-test/project/build.sbt index fd8d93a70f..79c666d229 100644 --- a/sbt-plugin-test/project/build.sbt +++ b/sbt-plugin-test/project/build.sbt @@ -1,4 +1,7 @@ addSbtPlugin("org.scala-js" % "sbt-scalajs" % org.scalajs.core.ir.ScalaJSVersions.current) +addSbtPlugin("org.scala-js" % "sbt-scalajs-env-phantomjs" % + org.scalajs.core.ir.ScalaJSVersions.current) + libraryDependencies += "org.eclipse.jetty" % "jetty-server" % "9.2.3.v20140905" diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index de7d798473..1073168e86 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -23,7 +23,6 @@ import org.scalajs.core.ir.ScalaJSVersions import org.scalajs.jsenv.{JSEnv, JSConsole} import org.scalajs.jsenv.nodejs.{NodeJSEnv, JSDOMNodeJSEnv} -import org.scalajs.jsenv.phantomjs.PhantomJSEnv object ScalaJSPlugin extends AutoPlugin { override def requires: Plugins = plugins.JvmPlugin @@ -108,32 +107,6 @@ object ScalaJSPlugin extends AutoPlugin { new JSDOMNodeJSEnv(executable, args, 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(executable, args, env, autoExit, loader) - } - // ModuleKind val ModuleKind = org.scalajs.core.tools.linker.backend.ModuleKind @@ -306,12 +279,6 @@ object ScalaJSPlugin extends AutoPlugin { val loadedJSEnv = TaskKey[JSEnv]("loadedJSEnv", "A JSEnv already loaded up with library and Scala.js code. Ready to run.", DTask) - /** Class loader for PhantomJSEnv. Used to load jetty8. */ - val scalaJSPhantomJSClassLoader = TaskKey[ClassLoader]("scalaJSPhantomJSClassLoader", - "Private class loader to load jetty8 without polluting classpath. Only use this " + - "as the `jettyClassLoader` argument of the PhantomJSEnv", - KeyRanks.Invisible) - /** Prints the content of a .sjsir file in human readable form. */ val scalajsp = InputKey[Unit]("scalajsp", "Prints the content of a .sjsir file in human readable form.", diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 7516e79cfa..7c062ff11d 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -21,7 +21,6 @@ import org.scalajs.core.tools.linker.frontend.LinkerFrontend import org.scalajs.core.tools.linker.backend.{LinkerBackend, ModuleKind, OutputMode} import org.scalajs.jsenv._ -import org.scalajs.jsenv.phantomjs.PhantomJettyClassLoader import org.scalajs.core.ir import org.scalajs.core.ir.Utils.escapeJS @@ -35,7 +34,6 @@ import scala.collection.mutable import java.io.FileNotFoundException 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. @@ -939,11 +937,6 @@ object ScalaJSPluginInternal { 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( isScalaJSProject := true, @@ -986,21 +979,6 @@ object ScalaJSPluginInternal { () }, - /* 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) - }, scalaJSJavaSystemProperties := Map.empty, scalaJSConfigurationLibs := Nil ) From b2db990943ab4aedc9b008a113111287d0ee429c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 28 Mar 2017 16:18:02 +0200 Subject: [PATCH 0176/2665] Directly use loadedJSEnv in toolsJS/test. Previously, we were depending on `resolvedJSEnv`, and basically reimplementing the work done in the `loadedJSEnv` task. --- project/Build.scala | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 9f18b6d354..fa67995b72 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -628,8 +628,7 @@ object Build { ) ++ inConfig(Test) { // Redefine test to run Node.js and link HelloWorld test := { - val jsEnv = resolvedJSEnv.value - if (!jsEnv.isInstanceOf[NodeJSEnv]) + if (!resolvedJSEnv.value.isInstanceOf[NodeJSEnv]) sys.error("toolsJS/test must be run with Node.js") /* Collect IR relevant files from the classpath @@ -689,10 +688,7 @@ object Build { val launcher = new MemVirtualJSFile("Generated launcher file") .withContent(code) - val linked = scalaJSLinkedFile.value - val libs = resolvedJSDependencies.value.data :+ - ResolvedJSDependency.minimal(linked) - val runner = jsEnv.jsRunner(libs, launcher) + val runner = loadedJSEnv.value.jsRunner(launcher) runner.run(sbtLogger2ToolsLogger(streams.value.log), scalaJSConsole.value) } From b5784f623b8d65a599d7a98724f98b49614c8c7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 28 Mar 2017 16:23:13 +0200 Subject: [PATCH 0177/2665] Move the implemention of commonJSName to the sbt plugin. It was previously done inside `NodeJSEnv`, which was good from an Object-Oriented point of view. However, this required that the API of `JSEnv` knows the notion of `commonJSName`, which is going to be a serious issue when we isolate `jsDependencies` out of the core. This commit moves the implementation of the `commonJSName` behavior in the sbt plugin, whence it can be extracted to the `jsDependencies` plugin in the future. This has the disadvantage that we burn `NodeJSEnv` as the only `JSEnv` for which `commonJSName` is a thing. We can compensate for that by a user-overridable predicate in the future `jsDependencies` plugin if necessary. --- .../org/scalajs/jsenv/nodejs/NodeJSEnv.scala | 20 ------------- .../sbtplugin/ScalaJSPluginInternal.scala | 29 +++++++++++++++++-- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala index 5f01785ea7..37cb682d01 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala @@ -11,8 +11,6 @@ package org.scalajs.jsenv.nodejs import org.scalajs.jsenv._ -import org.scalajs.core.ir.Utils.escapeJS - import org.scalajs.core.tools.io._ import org.scalajs.core.tools.jsdep.ResolvedJSDependency import org.scalajs.core.tools.logging._ @@ -66,24 +64,6 @@ class NodeJSEnv private ( protected trait AbstractBasicNodeRunner extends AbstractNodeRunner { - /** Libraries are loaded via require in Node.js */ - override protected def getLibJSFiles(): Seq[VirtualJSFile] = { - initFiles() ++ - customInitFiles() ++ - libs.map(requireLibrary) - } - - /** Rewrites a library virtual file to a require statement if possible */ - protected def requireLibrary(dep: ResolvedJSDependency): VirtualJSFile = { - dep.info.commonJSName.fold(dep.lib) { varname => - val fname = dep.lib.name - libCache.materialize(dep.lib) - new MemVirtualJSFile(s"require-$fname").withContent( - s"""$varname = require("${escapeJS(fname)}");""" - ) - } - } - // Send code to Stdin override protected def sendVMStdin(out: OutputStream): Unit = { /* Do not factor this method out into AbstractNodeRunner or when mixin in diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 7c062ff11d..5cce364f43 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -638,11 +638,36 @@ object ScalaJSPluginInternal { loadedJSEnv := { val log = streams.value.log val env = resolvedJSEnv.value - val libs = + val deps = resolvedJSDependencies.value.data ++ scalaJSConfigurationLibs.value + + /* Implement the behavior of commonJSName without having to burn it + * inside NodeJSEnv, and hence in the JSEnv API. + * Since this matches against NodeJSEnv specifically, it obviously + * breaks the OO approach, but oh well ... + */ + val libs = env match { + case _: org.scalajs.jsenv.nodejs.NodeJSEnv => + val libCache = new VirtualFileMaterializer(false) + + for (dep <- deps) yield { + dep.info.commonJSName.fold { + dep.lib + } { commonJSName => + val fname = libCache.materialize(dep.lib).getAbsolutePath + new MemVirtualJSFile(s"require-$fname").withContent( + s"""$commonJSName = require("${escapeJS(fname)}");""" + ) + } + } + + case _ => + deps.map(_.lib) + } + val file = scalaJSLinkedFile.value log.debug(s"Loading JSEnv with linked file ${file.path}") - env.loadLibs(libs :+ ResolvedJSDependency.minimal(file)) + env.loadLibs((libs :+ file).map(ResolvedJSDependency.minimal(_))) }, scalaJSModuleIdentifier := Def.taskDyn[Option[String]] { From 2a17ca5ea8090ab55429c1278f534ba3c9a4694d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 28 Mar 2017 16:51:41 +0200 Subject: [PATCH 0178/2665] Use VirtualJSFiles instead of ResolvedJSDependency in the JSEnv API. This removes the annoying dependency (sic!) of the `JSEnv` API on `ResolvedJSDependency`. This was the only part of `tools.jsdep` that was used in the `JSEnv` API, so it decouples those. This will be very important as we separate `jsDependencies` in a separate plugin, as the `tools.jsdep` package should go with that, out of the core. --- .../scala/org/scalajs/jsenv/AsyncJSEnv.scala | 7 +++---- .../main/scala/org/scalajs/jsenv/ComJSEnv.scala | 7 +++---- .../scala/org/scalajs/jsenv/ExternalJSEnv.scala | 9 ++++----- .../main/scala/org/scalajs/jsenv/JSEnv.scala | 9 ++++----- .../scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala | 17 ++++++++--------- .../org/scalajs/jsenv/nodejs/NodeJSEnv.scala | 13 ++++++------- .../scalajs/jsenv/phantomjs/PhantomJSEnv.scala | 13 ++++++------- .../jsenv/phantomjs/RetryingComJSEnv.scala | 15 ++++----------- .../jsenv/phantomjs/RetryingComJSEnvTest.scala | 7 +++---- .../sbtplugin/ScalaJSPluginInternal.scala | 2 +- 10 files changed, 42 insertions(+), 57 deletions(-) diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSEnv.scala index c0ba9aa93a..9b6c8dfcfe 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSEnv.scala @@ -10,19 +10,18 @@ package org.scalajs.jsenv import org.scalajs.core.tools.io.VirtualJSFile -import org.scalajs.core.tools.jsdep.ResolvedJSDependency trait AsyncJSEnv extends JSEnv { - def asyncRunner(libs: Seq[ResolvedJSDependency], code: VirtualJSFile): AsyncJSRunner + def asyncRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): AsyncJSRunner final def asyncRunner(code: VirtualJSFile): AsyncJSRunner = asyncRunner(Nil, code) - override def loadLibs(libs: Seq[ResolvedJSDependency]): AsyncJSEnv = + override def loadLibs(libs: Seq[VirtualJSFile]): AsyncJSEnv = new AsyncLoadedLibs { val loadedLibs = libs } private[jsenv] trait AsyncLoadedLibs extends LoadedLibs with AsyncJSEnv { - def asyncRunner(libs: Seq[ResolvedJSDependency], + def asyncRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): AsyncJSRunner = { AsyncJSEnv.this.asyncRunner(loadedLibs ++ libs, code) } diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/ComJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/ComJSEnv.scala index 52c6dcfaa2..b20faad7f7 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/ComJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/ComJSEnv.scala @@ -10,7 +10,6 @@ package org.scalajs.jsenv import org.scalajs.core.tools.io.VirtualJSFile -import org.scalajs.core.tools.jsdep.ResolvedJSDependency /** An [[AsyncJSEnv]] that provides communication to and from the JS VM. * @@ -28,15 +27,15 @@ import org.scalajs.core.tools.jsdep.ResolvedJSDependency * }}} */ trait ComJSEnv extends AsyncJSEnv { - def comRunner(libs: Seq[ResolvedJSDependency], code: VirtualJSFile): ComJSRunner + def comRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): ComJSRunner final def comRunner(code: VirtualJSFile): ComJSRunner = comRunner(Nil, code) - override def loadLibs(libs: Seq[ResolvedJSDependency]): ComJSEnv = + override def loadLibs(libs: Seq[VirtualJSFile]): ComJSEnv = new ComLoadedLibs { val loadedLibs = libs } private[jsenv] trait ComLoadedLibs extends AsyncLoadedLibs with ComJSEnv { - def comRunner(libs: Seq[ResolvedJSDependency], + def comRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): ComJSRunner = { ComJSEnv.this.comRunner(loadedLibs ++ libs, code) } diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala index a19ed6e3e4..fe7ead4c83 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala @@ -2,7 +2,6 @@ package org.scalajs.jsenv import org.scalajs.core.tools.io._ import org.scalajs.core.tools.logging.Logger -import org.scalajs.core.tools.jsdep.ResolvedJSDependency import java.io.{ Console => _, _ } import scala.io.Source @@ -28,7 +27,7 @@ abstract class ExternalJSEnv( protected def customInitFiles(): Seq[VirtualJSFile] = Nil protected class AbstractExtRunner( - protected val libs: Seq[ResolvedJSDependency], + protected val libs: Seq[VirtualJSFile], protected val code: VirtualJSFile) extends JSInitFiles { private[this] var _logger: Logger = _ @@ -64,7 +63,7 @@ abstract class ExternalJSEnv( /** Get files that are a library (i.e. that do not run anything) */ protected def getLibJSFiles(): Seq[VirtualJSFile] = - initFiles() ++ customInitFiles() ++ libs.map(_.lib) + initFiles() ++ customInitFiles() ++ libs /** Get all files that are passed to VM (libraries and code) */ protected def getJSFiles(): Seq[VirtualJSFile] = @@ -144,7 +143,7 @@ abstract class ExternalJSEnv( } - protected class ExtRunner(libs: Seq[ResolvedJSDependency], code: VirtualJSFile) + protected class ExtRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile) extends AbstractExtRunner(libs, code) with JSRunner { def run(logger: Logger, console: JSConsole): Unit = { @@ -157,7 +156,7 @@ abstract class ExternalJSEnv( } } - protected class AsyncExtRunner(libs: Seq[ResolvedJSDependency], code: VirtualJSFile) + protected class AsyncExtRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile) extends AbstractExtRunner(libs, code) with AsyncJSRunner { private[this] var vmInst: Process = null diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala index aa6c7a5ba9..202a7ffcda 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala @@ -10,14 +10,13 @@ package org.scalajs.jsenv import org.scalajs.core.tools.io.VirtualJSFile -import org.scalajs.core.tools.jsdep.ResolvedJSDependency trait JSEnv { /** Human-readable name for this [[JSEnv]] */ def name: String /** Prepare a runner for the code in the virtual file. */ - def jsRunner(libs: Seq[ResolvedJSDependency], code: VirtualJSFile): JSRunner + def jsRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): JSRunner /** Prepare a runner without any libraries. * @@ -36,15 +35,15 @@ trait JSEnv { * jsEnv.jsRunner(a ++ b, c) * }}} */ - def loadLibs(libs: Seq[ResolvedJSDependency]): JSEnv = + def loadLibs(libs: Seq[VirtualJSFile]): JSEnv = new LoadedLibs { val loadedLibs = libs } private[jsenv] trait LoadedLibs extends JSEnv { - val loadedLibs: Seq[ResolvedJSDependency] + val loadedLibs: Seq[VirtualJSFile] def name: String = JSEnv.this.name - def jsRunner(libs: Seq[ResolvedJSDependency], code: VirtualJSFile): JSRunner = + def jsRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): JSRunner = JSEnv.this.jsRunner(loadedLibs ++ libs, code) } } diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala index cc0d4cc530..6027d502c0 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala @@ -12,7 +12,6 @@ package org.scalajs.jsenv.nodejs import java.io.{Console => _, _} import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.jsdep.ResolvedJSDependency import org.scalajs.jsenv._ import org.scalajs.core.ir.Utils.escapeJS @@ -25,28 +24,28 @@ class JSDOMNodeJSEnv( protected def vmName: String = "Node.js with JSDOM" - override def jsRunner(libs: Seq[ResolvedJSDependency], + override def jsRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): JSRunner = { new DOMNodeRunner(libs, code) } - override def asyncRunner(libs: Seq[ResolvedJSDependency], + override def asyncRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): AsyncJSRunner = { new AsyncDOMNodeRunner(libs, code) } - override def comRunner(libs: Seq[ResolvedJSDependency], + override def comRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): ComJSRunner = { new ComDOMNodeRunner(libs, code) } - protected class DOMNodeRunner(libs: Seq[ResolvedJSDependency], code: VirtualJSFile) + protected class DOMNodeRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile) extends ExtRunner(libs, code) with AbstractDOMNodeRunner - protected class AsyncDOMNodeRunner(libs: Seq[ResolvedJSDependency], code: VirtualJSFile) + protected class AsyncDOMNodeRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile) extends AsyncExtRunner(libs, code) with AbstractDOMNodeRunner - protected class ComDOMNodeRunner(libs: Seq[ResolvedJSDependency], code: VirtualJSFile) + protected class ComDOMNodeRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile) extends AsyncDOMNodeRunner(libs, code) with NodeComJSRunner protected trait AbstractDOMNodeRunner extends AbstractNodeRunner { @@ -95,9 +94,9 @@ class JSDOMNodeJSEnv( override protected def getJSFiles(): Seq[VirtualJSFile] = initFiles() ++ customInitFiles() ++ codeWithJSDOMContext() - /** Libraries are loaded via scripts in Node.js */ + /** Libraries are loaded via scripts in the jsdom environment. */ override protected def getLibJSFiles(): Seq[VirtualJSFile] = - libs.map(_.lib) + libs // Send code to Stdin override protected def sendVMStdin(out: OutputStream): Unit = { diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala index 37cb682d01..675cc5600f 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala @@ -12,7 +12,6 @@ package org.scalajs.jsenv.nodejs import org.scalajs.jsenv._ import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.jsdep.ResolvedJSDependency import org.scalajs.core.tools.logging._ import java.io.{ Console => _, _ } @@ -38,28 +37,28 @@ class NodeJSEnv private ( // For binary compatibility, now `executable` is defined in AbstractNodeJSEnv override protected def executable: String = super.executable - override def jsRunner(libs: Seq[ResolvedJSDependency], + override def jsRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): JSRunner = { new NodeRunner(libs, code) } - override def asyncRunner(libs: Seq[ResolvedJSDependency], + override def asyncRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): AsyncJSRunner = { new AsyncNodeRunner(libs, code) } - override def comRunner(libs: Seq[ResolvedJSDependency], + override def comRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): ComJSRunner = { new ComNodeRunner(libs, code) } - protected class NodeRunner(libs: Seq[ResolvedJSDependency], code: VirtualJSFile) + protected class NodeRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile) extends ExtRunner(libs, code) with AbstractBasicNodeRunner - protected class AsyncNodeRunner(libs: Seq[ResolvedJSDependency], code: VirtualJSFile) + protected class AsyncNodeRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile) extends AsyncExtRunner(libs, code) with AbstractBasicNodeRunner - protected class ComNodeRunner(libs: Seq[ResolvedJSDependency], code: VirtualJSFile) + protected class ComNodeRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile) extends AsyncNodeRunner(libs, code) with NodeComJSRunner protected trait AbstractBasicNodeRunner extends AbstractNodeRunner { diff --git a/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala index e9a54895d6..0001dcfe85 100644 --- a/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala +++ b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala @@ -14,7 +14,6 @@ import org.scalajs.jsenv.Utils.OptDeadline import org.scalajs.core.ir.Utils.{escapeJS, fixFileURI} import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.jsdep.ResolvedJSDependency import org.scalajs.core.tools.logging._ import java.io.{ Console => _, _ } @@ -40,30 +39,30 @@ class PhantomJSEnv( protected def vmName: String = "PhantomJS" protected def executable: String = phantomjsPath - override def jsRunner(libs: Seq[ResolvedJSDependency], + override def jsRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): JSRunner = { new PhantomRunner(libs, code) } - override def asyncRunner(libs: Seq[ResolvedJSDependency], + override def asyncRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): AsyncJSRunner = { new AsyncPhantomRunner(libs, code) } - override def comRunner(libs: Seq[ResolvedJSDependency], + override def comRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): ComJSRunner = { new ComPhantomRunner(libs, code) } - protected class PhantomRunner(libs: Seq[ResolvedJSDependency], + protected class PhantomRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile) extends ExtRunner(libs, code) with AbstractPhantomRunner - protected class AsyncPhantomRunner(libs: Seq[ResolvedJSDependency], + protected class AsyncPhantomRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile) extends AsyncExtRunner(libs, code) with AbstractPhantomRunner - protected class ComPhantomRunner(libs: Seq[ResolvedJSDependency], + protected class ComPhantomRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile) extends AsyncPhantomRunner(libs, code) with ComJSRunner { diff --git a/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnv.scala b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnv.scala index 850b535120..8aa373637b 100644 --- a/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnv.scala +++ b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnv.scala @@ -10,7 +10,6 @@ package org.scalajs.jsenv.phantomjs import org.scalajs.core.tools.io._ import org.scalajs.core.tools.logging.Logger -import org.scalajs.core.tools.jsdep.ResolvedJSDependency import org.scalajs.jsenv._ @@ -43,27 +42,21 @@ final class RetryingComJSEnv(val baseEnv: ComJSEnv, def name: String = s"Retrying ${baseEnv.name}" - def jsRunner(libs: Seq[ResolvedJSDependency], - code: VirtualJSFile): JSRunner = { + def jsRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): JSRunner = baseEnv.jsRunner(libs, code) - } - def asyncRunner(libs: Seq[ResolvedJSDependency], - code: VirtualJSFile): AsyncJSRunner = { + def asyncRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): AsyncJSRunner = baseEnv.asyncRunner(libs, code) - } - def comRunner(libs: Seq[ResolvedJSDependency], - code: VirtualJSFile): ComJSRunner = { + def comRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): ComJSRunner = new RetryingComJSRunner(libs, code) - } /** Hack to work around abstract override in ComJSRunner */ private trait DummyJSRunner { def stop(): Unit = () } - private class RetryingComJSRunner(libs: Seq[ResolvedJSDependency], + private class RetryingComJSRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile) extends DummyJSRunner with ComJSRunner { private[this] val promise = Promise[Unit] diff --git a/phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnvTest.scala b/phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnvTest.scala index 484fb4d3bf..0223510a7c 100644 --- a/phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnvTest.scala +++ b/phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnvTest.scala @@ -1,7 +1,6 @@ package org.scalajs.jsenv.phantomjs import org.scalajs.core.tools.io.VirtualJSFile -import org.scalajs.core.tools.jsdep.ResolvedJSDependency import org.scalajs.core.tools.logging._ import org.scalajs.jsenv.nodejs.NodeJSEnv @@ -29,17 +28,17 @@ class RetryingComJSEnvTest extends JSEnvTest with ComTests { private[this] var fails = 0 private[this] var failedReceive = false - def jsRunner(libs: Seq[ResolvedJSDependency], + def jsRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): JSRunner = { baseEnv.jsRunner(libs, code) } - def asyncRunner(libs: Seq[ResolvedJSDependency], + def asyncRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): AsyncJSRunner = { baseEnv.asyncRunner(libs, code) } - def comRunner(libs: Seq[ResolvedJSDependency], + def comRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): ComJSRunner = { new FailingComJSRunner(baseEnv.comRunner(libs, code)) } diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 5cce364f43..1b7feabaf9 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -667,7 +667,7 @@ object ScalaJSPluginInternal { val file = scalaJSLinkedFile.value log.debug(s"Loading JSEnv with linked file ${file.path}") - env.loadLibs((libs :+ file).map(ResolvedJSDependency.minimal(_))) + env.loadLibs(libs :+ file) }, scalaJSModuleIdentifier := Def.taskDyn[Option[String]] { From c55f33fac8f168607a9ac9a47ea463b5b1d5b531 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 25 Mar 2017 08:57:03 +0100 Subject: [PATCH 0179/2665] Disallow package objects extending js.Any --- .../scala/org/scalajs/core/compiler/PrepJSInterop.scala | 7 ++----- .../org/scalajs/core/compiler/test/JSInteropTest.scala | 4 ++-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index d11b64e688..5be42bef41 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -492,11 +492,8 @@ abstract class PrepJSInterop extends plugins.PluginComponent "extending js.Any.") } - if (sym.isPackageObjectClass) { - reporter.warning(implDef.pos, - "Package objects inheriting from js.Any are deprecated. " + - "Use a normal object instead.") - } + if (sym.isPackageObjectClass) + reporter.error(implDef.pos, "Package objects may not extend js.Any.") def strKind = if (sym.isTrait) "trait" diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index 315754f2e0..8c650d021a 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -28,9 +28,9 @@ class JSInteropTest extends DirectTest with TestHelpers { s""" package object jspackage extends js.Object - """ hasWarns + """ hasErrors s""" - |newSource1.scala:5: warning: Package objects inheriting from js.Any are deprecated. Use a normal object instead. + |newSource1.scala:5: error: Package objects may not extend js.Any. | package object jspackage extends js.Object | ^ """ From 9ccff12cc580791f7c3643f5bddfcbfa497dd711 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 25 Mar 2017 09:27:57 +0100 Subject: [PATCH 0180/2665] Disallow @JSName on traits. --- .../org/scalajs/core/compiler/PrepJSInterop.scala | 10 ++-------- .../org/scalajs/core/compiler/test/JSInteropTest.scala | 6 +++--- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 5be42bef41..49b41333f1 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -576,14 +576,8 @@ abstract class PrepJSInterop extends plugins.PluginComponent annotSym = annot.symbol if JSNativeLoadingSpecAnnots.contains(annotSym) } { - if (annotSym == JSNameAnnotation) { - reporter.warning(annot.pos, - "Traits should not have an @JSName annotation, as it does " + - "not have any effect. This will be enforced in 1.0.") - } else { - reporter.error(annot.pos, - s"Traits may not have an @${annotSym.nameString} annotation.") - } + reporter.error(annot.pos, + s"Traits may not have an @${annotSym.nameString} annotation.") } } } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index 8c650d021a..941b0d9a49 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -241,12 +241,12 @@ class JSInteropTest extends DirectTest with TestHelpers { @js.native @JSName(Sym.sym) trait B extends js.Object - """ hasWarns + """ hasErrors s""" - |newSource1.scala:6: warning: Traits should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. + |newSource1.scala:6: error: Traits may not have an @JSName annotation. | @JSName("foo") | ^ - |newSource1.scala:14: warning: Traits should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. + |newSource1.scala:14: error: Traits may not have an @JSName annotation. | @JSName(Sym.sym) | ^ """ From 5772672af3cfa6c4e489b93f7e6848bebb631809 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 25 Mar 2017 17:04:37 +0100 Subject: [PATCH 0181/2665] Disallow duplicate @JSName --- .../scala/org/scalajs/core/compiler/PrepJSInterop.scala | 9 +++------ .../org/scalajs/core/compiler/test/JSInteropTest.scala | 6 +++--- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 49b41333f1..c52afd98e9 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -914,14 +914,11 @@ abstract class PrepJSInterop extends plugins.PluginComponent if (shouldCheckLiterals) checkJSNameArgument(tree) - /* Check that there is at most one @JSName annotation. We used not to - * check this, so we can only warn. - */ + // Check that there is at most one @JSName annotation. val allJSNameAnnots = sym.annotations.filter(_.symbol == JSNameAnnotation) for (duplicate <- allJSNameAnnots.drop(1)) { // does not throw if empty - reporter.warning(duplicate.pos, - "A duplicate @JSName annotation is ignored. " + - "This will become an error in 1.0.0.") + reporter.error(duplicate.pos, + "A member can only have a single @JSName annotation.") } /* In native JS types, there should not be any private member, except diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index 941b0d9a49..55df3b7934 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -1706,7 +1706,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } @Test - def warnOnDuplicateJSNameAnnotOnMember: Unit = { + def noDuplicateJSNameAnnotOnMember: Unit = { for { kind <- Seq("class", "object", "trait") } { @@ -1722,9 +1722,9 @@ class JSInteropTest extends DirectTest with TestHelpers { @JSName("foo") def a: Int = js.native } - """ hasWarns + """ hasErrors """ - |newSource1.scala:13: warning: A duplicate @JSName annotation is ignored. This will become an error in 1.0.0. + |newSource1.scala:13: error: A member can only have a single @JSName annotation. | @JSName("foo") | ^ """ From 410b456a1dfde44eb41663ea36a8b30a5b89ba23 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 25 Mar 2017 17:31:13 +0100 Subject: [PATCH 0182/2665] Disallow private members on JS native types --- .../scalajs/core/compiler/PrepJSInterop.scala | 17 ++++------ .../core/compiler/test/JSInteropTest.scala | 34 ++++++++++--------- .../testsuite/jsinterop/ModulesTest.scala | 2 +- 3 files changed, 25 insertions(+), 28 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index c52afd98e9..bcdb50c290 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -934,19 +934,14 @@ abstract class PrepJSInterop extends plugins.PluginComponent if (sym.isClassConstructor) { if (!sym.isPrivateThis) { - reporter.warning(tree.pos, - "Declaring private constructors in native JS classes is " + - "deprecated, because they do not behave the same way as in " + - "Scala.js-defined JS classes. Use `private[this]` instead. " + - "This will become an error in 1.0.0.") + reporter.error(sym.pos, + "Native JS classes may not have private constructors. " + + "Use `private[this]` to declare an internal constructor.") } } else if (sym.isMethod || isFieldPrivateThis) { - reporter.warning(tree.pos, - "Declaring private members in native JS classes is " + - "deprecated, because they do not behave the same way as in " + - "Scala.js-defined JS classes. Use a public member in a " + - "private facade instead. " + - "This will become an error in 1.0.0.") + reporter.error(tree.pos, + "Native JS classes may not have private members. " + + "Use a public member in a private facade instead.") } } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index 55df3b7934..2c5b7edbd0 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -847,7 +847,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } @Test - def warnPrivateMemberInNative: Unit = { + def noPrivateMemberInNative: Unit = { """ @js.native @@ -865,33 +865,33 @@ class JSInteropTest extends DirectTest with TestHelpers { private def h(): Int = js.native private[A] def i(): Int = js.native } - """ hasWarns + """ hasErrors """ - |newSource1.scala:8: warning: Declaring private members in native JS classes is deprecated, because they do not behave the same way as in Scala.js-defined JS classes. Use a public member in a private facade instead. This will become an error in 1.0.0. + |newSource1.scala:8: error: Native JS classes may not have private members. Use a public member in a private facade instead. | private[this] val a: Int = js.native | ^ - |newSource1.scala:9: warning: Declaring private members in native JS classes is deprecated, because they do not behave the same way as in Scala.js-defined JS classes. Use a public member in a private facade instead. This will become an error in 1.0.0. + |newSource1.scala:9: error: Native JS classes may not have private members. Use a public member in a private facade instead. | private val b: Int = js.native | ^ - |newSource1.scala:10: warning: Declaring private members in native JS classes is deprecated, because they do not behave the same way as in Scala.js-defined JS classes. Use a public member in a private facade instead. This will become an error in 1.0.0. + |newSource1.scala:10: error: Native JS classes may not have private members. Use a public member in a private facade instead. | private[A] val c: Int = js.native | ^ - |newSource1.scala:12: warning: Declaring private members in native JS classes is deprecated, because they do not behave the same way as in Scala.js-defined JS classes. Use a public member in a private facade instead. This will become an error in 1.0.0. + |newSource1.scala:12: error: Native JS classes may not have private members. Use a public member in a private facade instead. | private[this] var d: Int = js.native | ^ - |newSource1.scala:13: warning: Declaring private members in native JS classes is deprecated, because they do not behave the same way as in Scala.js-defined JS classes. Use a public member in a private facade instead. This will become an error in 1.0.0. + |newSource1.scala:13: error: Native JS classes may not have private members. Use a public member in a private facade instead. | private var e: Int = js.native | ^ - |newSource1.scala:14: warning: Declaring private members in native JS classes is deprecated, because they do not behave the same way as in Scala.js-defined JS classes. Use a public member in a private facade instead. This will become an error in 1.0.0. + |newSource1.scala:14: error: Native JS classes may not have private members. Use a public member in a private facade instead. | private[A] var f: Int = js.native | ^ - |newSource1.scala:16: warning: Declaring private members in native JS classes is deprecated, because they do not behave the same way as in Scala.js-defined JS classes. Use a public member in a private facade instead. This will become an error in 1.0.0. + |newSource1.scala:16: error: Native JS classes may not have private members. Use a public member in a private facade instead. | private[this] def g(): Int = js.native | ^ - |newSource1.scala:17: warning: Declaring private members in native JS classes is deprecated, because they do not behave the same way as in Scala.js-defined JS classes. Use a public member in a private facade instead. This will become an error in 1.0.0. + |newSource1.scala:17: error: Native JS classes may not have private members. Use a public member in a private facade instead. | private def h(): Int = js.native | ^ - |newSource1.scala:18: warning: Declaring private members in native JS classes is deprecated, because they do not behave the same way as in Scala.js-defined JS classes. Use a public member in a private facade instead. This will become an error in 1.0.0. + |newSource1.scala:18: error: Native JS classes may not have private members. Use a public member in a private facade instead. | private[A] def i(): Int = js.native | ^ """ @@ -899,26 +899,28 @@ class JSInteropTest extends DirectTest with TestHelpers { } @Test - def warnPrivateConstructorInNative: Unit = { + def noPrivateConstructorInNative: Unit = { """ @js.native @JSGlobal class A private () extends js.Object - """ containsWarns + """ hasErrors """ - |newSource1.scala:7: warning: Declaring private constructors in native JS classes is deprecated, because they do not behave the same way as in Scala.js-defined JS classes. Use `private[this]` instead. This will become an error in 1.0.0. + |newSource1.scala:7: error: Native JS classes may not have private constructors. Use `private[this]` to declare an internal constructor. | class A private () extends js.Object + | ^ """ """ @js.native @JSGlobal class A private[A] () extends js.Object - """ containsWarns + """ hasErrors """ - |newSource1.scala:7: warning: Declaring private constructors in native JS classes is deprecated, because they do not behave the same way as in Scala.js-defined JS classes. Use `private[this]` instead. This will become an error in 1.0.0. + |newSource1.scala:7: error: Native JS classes may not have private constructors. Use `private[this]` to declare an internal constructor. | class A private[A] () extends js.Object + | ^ """ """ diff --git a/test-suite/js/src/test/require-modules/org/scalajs/testsuite/jsinterop/ModulesTest.scala b/test-suite/js/src/test/require-modules/org/scalajs/testsuite/jsinterop/ModulesTest.scala index bc3d64bfd3..a54491103d 100644 --- a/test-suite/js/src/test/require-modules/org/scalajs/testsuite/jsinterop/ModulesTest.scala +++ b/test-suite/js/src/test/require-modules/org/scalajs/testsuite/jsinterop/ModulesTest.scala @@ -107,7 +107,7 @@ object ModulesTest { */ @js.native @JSImport("buffer", "Buffer") - class Buffer private () extends js.typedarray.Uint8Array(0) { + class Buffer private[this] () extends js.typedarray.Uint8Array(0) { def this(size: Int) = this() def this(array: js.Array[Short]) = this() } From 83adf8c675a06337eba6d46ebb567068de209004 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 25 Mar 2017 17:36:53 +0100 Subject: [PATCH 0183/2665] Enforce native implementations to be js.native --- .../scala/org/scalajs/core/compiler/PrepJSInterop.scala | 5 ++--- .../org/scalajs/core/compiler/test/JSInteropTest.scala | 8 ++++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index bcdb50c290..3a431f3a4d 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -1055,9 +1055,8 @@ abstract class PrepJSInterop extends plugins.PluginComponent case sel: Select if sel.symbol == JSPackage_native => case _ => val pos = if (tree.rhs != EmptyTree) tree.rhs.pos else tree.pos - reporter.warning(pos, "Members of traits, classes and objects " + - "extending js.Any may only contain members that call js.native. " + - "This will be enforced in 1.0.") + reporter.error(pos, + "Concrete members of JS native types may only call js.native.") } if (sym.tpe.resultType.typeSymbol == NothingClass && diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index 2c5b7edbd0..285e5a768d 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -784,7 +784,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } @Test - def warnJSAnyBody: Unit = { + def checkJSAnyBody: Unit = { """ @js.native @@ -793,12 +793,12 @@ class JSInteropTest extends DirectTest with TestHelpers { def value: Int = ??? val x: Int = ??? } - """ hasWarns + """ hasErrors """ - |newSource1.scala:8: warning: Members of traits, classes and objects extending js.Any may only contain members that call js.native. This will be enforced in 1.0. + |newSource1.scala:8: error: Concrete members of JS native types may only call js.native. | def value: Int = ??? | ^ - |newSource1.scala:9: warning: Members of traits, classes and objects extending js.Any may only contain members that call js.native. This will be enforced in 1.0. + |newSource1.scala:9: error: Concrete members of JS native types may only call js.native. | val x: Int = ??? | ^ """ From 63e108dee802fb138d28d855e7f056c0827e30c5 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 25 Mar 2017 17:44:16 +0100 Subject: [PATCH 0184/2665] Disallow default params on exported setters --- .../scala/org/scalajs/core/compiler/PrepJSInterop.scala | 9 ++------- .../org/scalajs/core/compiler/test/JSExportTest.scala | 4 ++-- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 3a431f3a4d..fa4cfc0ebc 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -1167,13 +1167,8 @@ abstract class PrepJSInterop extends plugins.PluginComponent if (isScalaRepeatedParamType(arg.tpe)) reporter.error(pos, s"$typeStr setters may not have repeated params") - if (arg.hasFlag(reflect.internal.Flags.DEFAULTPARAM)) { - val msg = s"$typeStr setters may not have default params" - if (exported) - reporter.warning(pos, msg + ". This will be enforced in 1.0.") - else - reporter.error(pos, msg) - } + if (arg.hasFlag(reflect.internal.Flags.DEFAULTPARAM)) + reporter.error(pos, s"$typeStr setters may not have default params") case _ => reporter.error(pos, s"$typeStr setters must have exactly one argument") diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index 320231a47f..625145b63c 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -706,9 +706,9 @@ class JSExportTest extends DirectTest with TestHelpers { @JSExport def foo_=(x: Int = 1) = () } - """ hasWarns + """ hasErrors """ - |newSource1.scala:4: warning: Exported setters may not have default params. This will be enforced in 1.0. + |newSource1.scala:4: error: Exported setters may not have default params | @JSExport | ^ """ From e1637ff6310ce201882792563b8f6375414adcd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 29 Mar 2017 15:46:57 +0200 Subject: [PATCH 0185/2665] Abstract VirtualJarFile into VirtualFileContainer. The API of `VirtualJarFile` is abstracted one level up in the hierarchy, in a new trait `VirtualFileContainer`. `VirtualJarFile` implements the zip binary format details, reading with `ZipInputStream`. This will allow to give platform-specific implementations of `VirtualFileContainer` that do not rely on `ZipInputStream`. --- .../scalajs/core/tools/io/IRFileCache.scala | 2 +- .../scalajs/core/tools/io/VirtualFiles.scala | 80 ++++++++++++++----- 2 files changed, 61 insertions(+), 21 deletions(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala index 6f2c52c8cc..618d8171fa 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala @@ -312,7 +312,7 @@ object IRFileCache { override def toURI: URI = ir.toURI } - final case class Jar(jar: VirtualJarFile) extends IRContainer { + final case class Jar(jar: VirtualFileContainer) extends IRContainer { override def path: String = jar.path override def name: String = jar.name override def version: Option[String] = jar.version diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala index b0830efade..4f3a8bee8e 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala @@ -173,56 +173,96 @@ trait VirtualSerializedScalaJSIRFile extends VirtualBinaryFile with VirtualScala } } -trait VirtualJarFile extends VirtualBinaryFile { - /** All the `*.sjsir` files in this Jar +/** A virtual file container. + * + * This is a generic virtual container for embedded virtual files, especially + * one found on a classpath such as a jar, and containing `.sjsir` files. + */ +trait VirtualFileContainer extends VirtualFile { + import VirtualFileContainer._ + + /** Lists the entries of this container that satisfy a given predicate. + * + * @param p + * Predicate on the relative path of files to select. + * @param makeResult + * Function building an element of the result list for an entry, given + * its relative path an `InputStream` of the content. `makeResult` may + * `close()` the input stream, but it is not mandatory. In any case, the + * input stream cannot be used after `makeResult` returns. + */ + def listEntries[T](p: String => Boolean)( + makeResult: (String, InputStream) => T): List[T] + + /** All the `*.sjsir` files in this container. * * It is up to the implementation whether these files are read lazily or not. * The default implementation reads them into memory. + * + * Depending on the implementation, calling `sjsirFiles` might be more + * efficient than using `listEntries` with a predicate + * `_.endsWith(".sjsir")`. */ - def sjsirFiles: Seq[VirtualScalaJSIRFile with RelativeVirtualFile] = { - findEntries(_.endsWith(".sjsir")) { (entry, stream) => - val file = new JarEntryIRFile(path, entry.getName) + def sjsirFiles: List[VirtualScalaJSIRFile with RelativeVirtualFile] = { + listEntries(_.endsWith(".sjsir")) { (relPath, stream) => + val file = new EntryIRFile(path, relPath) file.content = IO.readInputStreamToByteArray(stream) file.version = version file } } - def jsFiles: Seq[VirtualJSFile with RelativeVirtualFile] = { - findEntries(_.endsWith(".js")) { (entry, stream) => - val file = new JarEntryJSFile(path, entry.getName) + def jsFiles: List[VirtualJSFile with RelativeVirtualFile] = { + listEntries(_.endsWith(".js")) { (relPath, stream) => + val file = new EntryJSFile(path, relPath) file.content = IO.readInputStreamToString(stream) file.version = version file } } - def jsDependencyManifests: Seq[JSDependencyManifest] = { - findEntries(_ == JSDependencyManifest.ManifestFileName) { (_, stream) => + def jsDependencyManifests: List[JSDependencyManifest] = { + listEntries(_ == JSDependencyManifest.ManifestFileName) { (_, stream) => val json = readJSON(new InputStreamReader(stream, "UTF-8")) fromJSON[JSDependencyManifest](json) } } +} - private def findEntries[T](cond: String => Boolean)( - mkResult: (ZipEntry, InputStream) => T): Seq[T] = { +private object VirtualFileContainer { + private class EntryIRFile(outerPath: String, val relativePath: String) + extends MemVirtualSerializedScalaJSIRFile(s"$outerPath:$relativePath") + with RelativeVirtualFile + + private class EntryJSFile(outerPath: String, val relativePath: String) + extends MemVirtualJSFile(s"$outerPath:$relativePath") + with RelativeVirtualFile +} + +/** A virtual jar file. */ +trait VirtualJarFile extends VirtualFileContainer with VirtualBinaryFile { + import VirtualJarFile._ + + def listEntries[T](p: String => Boolean)( + makeResult: (String, InputStream) => T): List[T] = { val stream = new ZipInputStream(inputStream) try { + val streamIgnoreClose = new IgnoreCloseFilterInputStream(stream) Iterator.continually(stream.getNextEntry()) .takeWhile(_ != null) - .filter(entry => cond(entry.getName)) - .map(entry => mkResult(entry, stream)) + .filter(entry => p(entry.getName)) + .map(entry => makeResult(entry.getName, streamIgnoreClose)) .toList } finally { stream.close() } } +} - private class JarEntryIRFile(outerPath: String, val relativePath: String) - extends MemVirtualSerializedScalaJSIRFile(s"$outerPath:$relativePath") - with RelativeVirtualFile +private object VirtualJarFile { + private final class IgnoreCloseFilterInputStream(in: InputStream) + extends FilterInputStream(in) { - private class JarEntryJSFile(outerPath: String, val relativePath: String) - extends MemVirtualJSFile(s"$outerPath:$relativePath") - with RelativeVirtualFile + override def close(): Unit = () + } } From b856c575589f9bb3f3b070897d96cb4240ffd82d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 31 Mar 2017 16:55:08 +0200 Subject: [PATCH 0186/2665] Remove the dependency of toolsJS/test on javalibEx. Instead of using the regular `VirtualJarFile`, which uses `ZipInputStream`, we define a custom `NodeVirtualJarFile` directly in `QuickLinker.scala`. That implementation is a direct wrapper over JSZip, without going through `ZipInputStream`. This allows to drop the dependency on javalibEx from the bootstrap test. --- project/Build.scala | 11 +++- .../core/tools/test/js/QuickLinker.scala | 60 ++++++++++++++++++- 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index fa67995b72..e77999f6d6 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -515,7 +515,7 @@ object Build { (scalaSource in Test in irProject).value ) ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( - javalibEx, jUnitRuntime % "test" + library, jUnitRuntime % "test" ) lazy val compiler: Project = Project( @@ -624,7 +624,10 @@ object Build { IO.write(outFile, testDefinitions) Seq(outFile) }.taskValue, - jsDependencies += ProvidedJS / "js-test-definitions.js" % "test" + + jsDependencies += ProvidedJS / "js-test-definitions.js" % "test", + jsDependencies += + "org.webjars" % "jszip" % "2.4.0" % "test" / "jszip.min.js" commonJSName "JSZip" ) ++ inConfig(Test) { // Redefine test to run Node.js and link HelloWorld test := { @@ -693,7 +696,9 @@ object Build { runner.run(sbtLogger2ToolsLogger(streams.value.log), scalaJSConsole.value) } } - ).withScalaJSCompiler.dependsOn(javalibEx, testSuite % "test->test", irProjectJS) + ).withScalaJSCompiler.dependsOn( + library, irProjectJS, testSuite % "test->test" + ) lazy val jsEnvs: Project = Project( id = "jsEnvs", diff --git 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 index 5e3449b39a..907ccbad31 100644 --- 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,5 +1,7 @@ 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.io.IRFileCache.IRContainer @@ -9,6 +11,7 @@ import org.scalajs.core.tools.logging._ import scala.scalajs.js import scala.scalajs.js.annotation._ +import scala.scalajs.js.typedarray._ @JSExportTopLevel("scalajs.QuickLinker") object QuickLinker { @@ -43,7 +46,7 @@ object QuickLinker { val irContainers = irFilesAndJars.map { file => if (file.endsWith(".jar")) { - val vf = new NodeVirtualBinaryFile(file) with VirtualJarFile + val vf = new NodeVirtualJarFile(file) IRContainer.Jar(vf) } else if (file.endsWith(".sjsir")) { val vf = new NodeVirtualScalaJSIRFile(file) with RelativeVirtualFile { @@ -72,4 +75,59 @@ object QuickLinker { out.content } + 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 + @JSGlobal("JSZip") + private class JSZip(data: Uint8Array) extends js.Object { + def files: js.Dictionary[JSZipEntry] = js.native + } + + private trait JSZipEntry extends js.Object { + def asArrayBuffer(): ArrayBuffer + } + } From 7ff851a9d5f73f8566588aad855c85c7400eb978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 31 Mar 2017 20:02:15 +0200 Subject: [PATCH 0187/2665] Rename javalibExTestSuite to testSuiteEx. Indeed, that test suite was not only testing things in javalibEx, but also some random tests that cannot be part of the standard test suite for various reasons. In the process, this commit fixes the package structure from `scala.scalajs.testsuite` to `org.scalajs.testsuite`. --- DEVELOPING.md | 4 ++-- build.sbt | 2 +- ci/matrix.xml | 6 +++--- project/Build.scala | 20 ++++++++++++++----- .../testsuite/javalib/lang/ObjectTestEx.scala | 5 +++-- .../javalibex/ZipInputStreamTest.scala | 4 ++-- .../jsinterop/ScalaJSDefinedTestEx.scala | 2 +- .../testsuite/utils/AssertThrows.scala | 2 +- .../scalajs/testsuite/utils/Platform.scala | 2 +- 9 files changed, 29 insertions(+), 18 deletions(-) rename {javalib-ex-test-suite/src/test/scala/scala => test-suite-ex/src/test/scala/org}/scalajs/testsuite/javalib/lang/ObjectTestEx.scala (96%) rename {javalib-ex-test-suite/src/test/scala/scala => test-suite-ex/src/test/scala/org}/scalajs/testsuite/javalibex/ZipInputStreamTest.scala (98%) rename {javalib-ex-test-suite/src/test/scala/scala => test-suite-ex/src/test/scala/org}/scalajs/testsuite/jsinterop/ScalaJSDefinedTestEx.scala (96%) rename {javalib-ex-test-suite/src/test/scala/scala => test-suite-ex/src/test/scala/org}/scalajs/testsuite/utils/AssertThrows.scala (98%) rename {javalib-ex-test-suite/src/test/scala/scala => test-suite-ex/src/test/scala/org}/scalajs/testsuite/utils/Platform.scala (95%) diff --git a/DEVELOPING.md b/DEVELOPING.md index ef12072574..ab6a266c3c 100644 --- a/DEVELOPING.md +++ b/DEVELOPING.md @@ -52,9 +52,9 @@ To test with PhantomJS, use this setting: > set inScope(ThisScope in testSuite)(Seq(jsEnv := PhantomJSEnv().value)) -The tests for the javalibEx are in a separate testing project: +There are also a few additional tests in a separate testing project: - > javalibExTestSuite/test + > testSuiteEx/test The compiler tests (mostly verifying expected compile error messages) can be run with diff --git a/build.sbt b/build.sbt index b47aa80d38..fd1a5d140e 100644 --- a/build.sbt +++ b/build.sbt @@ -31,7 +31,7 @@ val testingExample = Build.testingExample val testSuite = Build.testSuite val testSuiteJVM = Build.testSuiteJVM val noIrCheckTest = Build.noIrCheckTest -val javalibExTestSuite = Build.javalibExTestSuite +val testSuiteEx = Build.testSuiteEx val partest = Build.partest val partestSuite = Build.partestSuite val scalaTestSuite = Build.scalaTestSuite diff --git a/ci/matrix.xml b/ci/matrix.xml index 6061674764..e86261d9fa 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -64,9 +64,9 @@ sbtretry ++$scala testSuiteJVM/test testSuiteJVM/clean && sbtretry ++$scala 'testSuite/test:runMain org.scalajs.testsuite.junit.JUnitBootstrapTest' && sbtretry ++$scala testSuite/test && - sbtretry ++$scala javalibExTestSuite/test && + sbtretry ++$scala testSuiteEx/test && sbtretry 'set scalaJSStage in Global := FullOptStage' \ - ++$scala javalibExTestSuite/test && + ++$scala testSuiteEx/test && sbtretry ++$scala testSuite/test:doc compiler/test reversi/fastOptJS reversi/fullOptJS && sbtretry ++$scala compiler/compile:doc library/compile:doc javalibEx/compile:doc \ testInterface/compile:doc && @@ -216,7 +216,7 @@ sbtPlugin/scalastyle testInterface/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 --git a/project/Build.scala b/project/Build.scala index e77999f6d6..f97b69fa81 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -475,7 +475,7 @@ object Build { clean in examples, clean in helloworld, clean in reversi, clean in testingExample, clean in testSuite, clean in testSuiteJVM, clean in noIrCheckTest, - clean in javalibExTestSuite, + clean in testSuiteEx, clean in partest, clean in partestSuite, clean in scalaTestSuite).value, @@ -1642,13 +1642,23 @@ object Build { ) ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn(library, jUnitRuntime) - lazy val javalibExTestSuite: Project = Project( - id = "javalibExTestSuite", - base = file("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( + id = "testSuiteEx", + base = file("test-suite-ex"), settings = ( commonSettings ++ myScalaJSSettings ++ testTagSettings ) ++ Seq( - name := "JavaLib Ex Test Suite", + name := "Scala.js test suite ex", publishArtifact in Compile := false, testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a", "-s"), scalacOptions in Test ~= (_.filter(_ != "-deprecation")) diff --git a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/javalib/lang/ObjectTestEx.scala b/test-suite-ex/src/test/scala/org/scalajs/testsuite/javalib/lang/ObjectTestEx.scala similarity index 96% rename from javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/javalib/lang/ObjectTestEx.scala rename to test-suite-ex/src/test/scala/org/scalajs/testsuite/javalib/lang/ObjectTestEx.scala index fcdadd3b27..9936fe200a 100644 --- a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/javalib/lang/ObjectTestEx.scala +++ b/test-suite-ex/src/test/scala/org/scalajs/testsuite/javalib/lang/ObjectTestEx.scala @@ -7,11 +7,12 @@ \* */ package org.scalajs.testsuite.javalib.lang +import scala.scalajs.js + import org.junit.Test import org.junit.Assert._ -import scala.scalajs.js -import scala.scalajs.testsuite.utils.AssertThrows._ +import org.scalajs.testsuite.utils.AssertThrows._ /** Additional tests for java.lang.Object that have to be in a separate * codebase than testSuite to be meaningful. diff --git a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/javalibex/ZipInputStreamTest.scala b/test-suite-ex/src/test/scala/org/scalajs/testsuite/javalibex/ZipInputStreamTest.scala similarity index 98% rename from javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/javalibex/ZipInputStreamTest.scala rename to test-suite-ex/src/test/scala/org/scalajs/testsuite/javalibex/ZipInputStreamTest.scala index 39a89f2dd5..408a1e908e 100644 --- a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/javalibex/ZipInputStreamTest.scala +++ b/test-suite-ex/src/test/scala/org/scalajs/testsuite/javalibex/ZipInputStreamTest.scala @@ -1,10 +1,10 @@ -package scala.scalajs.testsuite.javalibex +package org.scalajs.testsuite.javalibex import org.junit.Test import org.junit.Assert._ import org.junit.Assume._ -import scala.scalajs.testsuite.utils.Platform._ +import org.scalajs.testsuite.utils.Platform._ import java.io._ import java.util.zip._ diff --git a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ScalaJSDefinedTestEx.scala b/test-suite-ex/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTestEx.scala similarity index 96% rename from javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ScalaJSDefinedTestEx.scala rename to test-suite-ex/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTestEx.scala index ada3db13b6..d2e31f07ae 100644 --- a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ScalaJSDefinedTestEx.scala +++ b/test-suite-ex/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTestEx.scala @@ -5,7 +5,7 @@ ** /____/\___/_/ |_/____/_/ | |__/ /____/ ** ** |/____/ ** \* */ -package scala.scalajs.testsuite.jsinterop +package org.scalajs.testsuite.jsinterop import org.junit.Test import org.junit.Assert._ diff --git a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/utils/AssertThrows.scala b/test-suite-ex/src/test/scala/org/scalajs/testsuite/utils/AssertThrows.scala similarity index 98% rename from javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/utils/AssertThrows.scala rename to test-suite-ex/src/test/scala/org/scalajs/testsuite/utils/AssertThrows.scala index b9f8540c32..2fc772e263 100644 --- a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/utils/AssertThrows.scala +++ b/test-suite-ex/src/test/scala/org/scalajs/testsuite/utils/AssertThrows.scala @@ -1,4 +1,4 @@ -package scala.scalajs.testsuite.utils +package org.scalajs.testsuite.utils /** This is a copy of the implementation in the testSuite */ object AssertThrows { diff --git a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/utils/Platform.scala b/test-suite-ex/src/test/scala/org/scalajs/testsuite/utils/Platform.scala similarity index 95% rename from javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/utils/Platform.scala rename to test-suite-ex/src/test/scala/org/scalajs/testsuite/utils/Platform.scala index 3faca1efb3..a7a047ecd4 100644 --- a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/utils/Platform.scala +++ b/test-suite-ex/src/test/scala/org/scalajs/testsuite/utils/Platform.scala @@ -5,7 +5,7 @@ ** /____/\___/_/ |_/____/_/ | |__/ /____/ ** ** |/____/ ** \* */ -package scala.scalajs.testsuite.utils +package org.scalajs.testsuite.utils /** This is a partial copy of the implementation in the testSuite */ object Platform { From 4a99cd125788784db1f075231294171faed8458c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 31 Mar 2017 20:09:56 +0200 Subject: [PATCH 0188/2665] Fix #2840: Remove the javalib-ex. --- DEVELOPING.md | 2 +- build.sbt | 1 - ci/matrix.xml | 6 +- .../java/util/zip/InflaterInputStream.scala | 19 --- .../main/scala/java/util/zip/ZipEntry.scala | 70 --------- .../scala/java/util/zip/ZipInputStream.scala | 93 ------------ project/Build.scala | 21 +-- scripts/publish.sh | 2 +- .../javalibex/ZipInputStreamTest.scala | 137 ------------------ 9 files changed, 7 insertions(+), 344 deletions(-) delete mode 100644 javalib-ex/src/main/scala/java/util/zip/InflaterInputStream.scala delete mode 100644 javalib-ex/src/main/scala/java/util/zip/ZipEntry.scala delete mode 100644 javalib-ex/src/main/scala/java/util/zip/ZipInputStream.scala delete mode 100644 test-suite-ex/src/test/scala/org/scalajs/testsuite/javalibex/ZipInputStreamTest.scala diff --git a/DEVELOPING.md b/DEVELOPING.md index ab6a266c3c..d9798cf676 100644 --- a/DEVELOPING.md +++ b/DEVELOPING.md @@ -142,6 +142,6 @@ following incantations. `SCALA_VERSION` refers to the Scala version used by the separate project. > ++SCALA_VERSION - > ;compiler/publishLocal;library/publishLocal;javalibEx/publishLocal;testInterface/publishLocal;stubs/publishLocal;jUnitRuntime/publishLocal;jUnitPlugin/publishLocal + > ;compiler/publishLocal;library/publishLocal;testInterface/publishLocal;stubs/publishLocal;jUnitRuntime/publishLocal;jUnitPlugin/publishLocal > ++2.10.6 > ;ir/publishLocal;tools/publishLocal;jsEnvs/publishLocal;jsEnvsTestKit/publishLocal;testAdapter/publishLocal;sbtPlugin/publishLocal diff --git a/build.sbt b/build.sbt index fd1a5d140e..e2f6adc44e 100644 --- a/build.sbt +++ b/build.sbt @@ -14,7 +14,6 @@ val javalib = Build.javalib val scalalib = Build.scalalib val libraryAux = Build.libraryAux val library = Build.library -val javalibEx = Build.javalibEx val stubs = Build.stubs val cli = Build.cli val testInterface = Build.testInterface diff --git a/ci/matrix.xml b/ci/matrix.xml index e86261d9fa..6c14406db2 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -68,7 +68,7 @@ sbtretry 'set scalaJSStage in Global := FullOptStage' \ ++$scala testSuiteEx/test && sbtretry ++$scala testSuite/test:doc compiler/test reversi/fastOptJS reversi/fullOptJS && - sbtretry ++$scala compiler/compile:doc library/compile:doc javalibEx/compile:doc \ + sbtretry ++$scala compiler/compile:doc library/compile:doc \ testInterface/compile:doc && sbtretry ++$scala partest/fetchScalaSource && sbtretry ++$scala library/mimaReportBinaryIssues testInterface/mimaReportBinaryIssues && @@ -209,7 +209,7 @@ sbtPlugin/mimaReportBinaryIssues \ irJS/mimaReportBinaryIssues toolsJS/mimaReportBinaryIssues && sbt ++$scala library/scalastyle javalanglib/scalastyle javalib/scalastyle \ - javalibEx/scalastyle ir/scalastyle compiler/scalastyle \ + ir/scalastyle compiler/scalastyle \ compiler/test:scalastyle tools/scalastyle tools/test:scalastyle \ jsEnvs/scalastyle jsEnvsTestKit/scalastyle \ jsEnvsTestSuite/test:scalastyle testAdapter/scalastyle \ @@ -235,7 +235,7 @@ - * External: JSZip - * ZipInputStream implementation using - * JSZip - */ -class ZipInputStream(in: InputStream) extends InflaterInputStream(in) { - - // Not implemented - // - All static constant fields (zip internals) - // - protected def createZipEntry(name: String): ZipEntry - - private[this] val entryIter = { - import js.Dynamic.{global => g} - - val data = in match { - case in: ArrayBufferInputStream => - // Simulate reading all the data - while (in.skip(in.available()) > 0) {} - new Uint8Array(in.buffer, in.offset, in.length) - case _ => - val arr = new js.Array[Int] - var x = in.read() - while (x != -1) { - arr.push(x) - x = in.read() - } - new Uint8Array(arr) - } - - val zip = js.Dynamic.newInstance(g.JSZip)(data) - val entries = zip.files.asInstanceOf[js.Dictionary[js.Dynamic]] - - entries.iterator - } - - private[this] var inner: ArrayBufferInputStream = null - - override def close(): Unit = { - closeEntry() - super.close() - } - - override def available(): Int = { - if (inner == null || inner.available() <= 0) 0 - else 1 - } - - def closeEntry(): Unit = { - if (inner != null) - inner.close() - inner = null - } - - def getNextEntry(): ZipEntry = { - closeEntry() - if (entryIter.hasNext) { - val (name, jsEntry) = entryIter.next() - val res = new ZipEntry(name) - res.setTime(jsEntry.date.asInstanceOf[js.Date].getTime().toLong) - res.setComment(jsEntry.comment.asInstanceOf[String]) - - inner = new ArrayBufferInputStream( - jsEntry.asArrayBuffer().asInstanceOf[ArrayBuffer]) - - res - } else null - } - - override def read(): Int = { - if (inner == null) -1 - else inner.read() - } - - override def read(buf: Array[Byte], off: Int, len: Int): Int = { - if (len == 0) 0 - else if (inner == null) -1 - else inner.read(buf, off, len) - } - - override def skip(n: Long): Long = { - if (inner == null) 0 - else inner.skip(n) - } - -} diff --git a/project/Build.scala b/project/Build.scala index f97b69fa81..f87307bc4d 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -467,7 +467,7 @@ object Build { clean in jsEnvs, clean in jsEnvsTestKit, clean in jsEnvsTestSuite, clean in testAdapter, clean in plugin, clean in javalanglib, clean in javalib, clean in scalalib, - clean in libraryAux, clean in library, clean in javalibEx, + clean in libraryAux, clean in library, clean in stubs, clean in cli, clean in testInterface, clean in jUnitRuntime, clean in jUnitPlugin, @@ -1094,23 +1094,6 @@ object Build { )) ).withScalaJSCompiler - lazy val javalibEx: Project = Project( - id = "javalibEx", - base = file("javalib-ex"), - settings = ( - commonSettings ++ publishSettings ++ myScalaJSSettings ++ fatalWarningsSettings - ) ++ Seq( - name := "Scala.js JavaLib Ex", - delambdafySetting, - noClassFilesSettings, - exportJars := true, - jsDependencies += - "org.webjars" % "jszip" % "2.4.0" / "jszip.min.js" commonJSName "JSZip" - ) ++ ( - scalaJSExternalCompileSettings - ) - ).withScalaJSCompiler.dependsOn(library) - lazy val stubs: Project = Project( id = "stubs", base = file("stubs"), @@ -1663,7 +1646,7 @@ object Build { testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a", "-s"), scalacOptions in Test ~= (_.filter(_ != "-deprecation")) ) - ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn(javalibEx, jUnitRuntime) + ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn(library, jUnitRuntime) lazy val partest: Project = Project( id = "partest", diff --git a/scripts/publish.sh b/scripts/publish.sh index 55e36cf58c..383258c59f 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -14,7 +14,7 @@ CLI_VERSIONS="2.10.6 2.11.8 2.12.1" SBT_VERSION="2.10.6" COMPILER="compiler jUnitPlugin" -LIBS="library javalibEx ir irJS tools toolsJS jsEnvs jsEnvsTestKit testAdapter stubs testInterface jUnitRuntime" +LIBS="library ir irJS tools toolsJS jsEnvs jsEnvsTestKit testAdapter stubs testInterface jUnitRuntime" # Publish compiler for v in $FULL_VERSIONS; do diff --git a/test-suite-ex/src/test/scala/org/scalajs/testsuite/javalibex/ZipInputStreamTest.scala b/test-suite-ex/src/test/scala/org/scalajs/testsuite/javalibex/ZipInputStreamTest.scala deleted file mode 100644 index 408a1e908e..0000000000 --- a/test-suite-ex/src/test/scala/org/scalajs/testsuite/javalibex/ZipInputStreamTest.scala +++ /dev/null @@ -1,137 +0,0 @@ -package org.scalajs.testsuite.javalibex - -import org.junit.Test -import org.junit.Assert._ -import org.junit.Assume._ - -import org.scalajs.testsuite.utils.Platform._ - -import java.io._ -import java.util.zip._ - -class ZipInputStreamTest { - - @Test def should_read_zip_archives(): Unit = { - assumeTrue("Assumed typed arrays", typedArrays) - - val in = new ZipInputStream(new ByteArrayInputStream(binZip)) - - def expectBinEntry(name: String, data: Seq[Int]): Unit = { - val e = in.getNextEntry() - assertEquals(name, e.getName()) - - for (d <- data) - assertEquals(d, in.read()) - - assertEquals(-1, in.read()) - } - - def expectStrEntry(name: String, content: String): Unit = { - val e = in.getNextEntry() - assertEquals(name, e.getName()) - - val r = new InputStreamReader(in) - - for (c <- content) - assertEquals(c, r.read().toChar) - - assertEquals(-1, r.read()) - } - - expectBinEntry("greetings/", Seq()) - expectStrEntry("greetings/en.txt", "Hello World, how are you doing?\n") - expectStrEntry("greetings/es.txt", "¿Hola mundo, cómo estás?\n") - expectStrEntry("greetings/fr.txt", "Bonjour, comment ça va?\n") - expectStrEntry("greetings/ja.txt", "こんにちは、お元気ですか。\n") - expectBinEntry("binary/", Seq()) - expectBinEntry("binary/bytes_0_to_50.bin", 0 to 50) - - assertTrue(in.getNextEntry() == null) - in.close() - } - - /** A zip archive for testing: - * - * $ zipinfo test.zip - * Archive: test.zip 1304 bytes 7 files - * drwxr-xr-x 3.0 unx 0 bx stor 13-Aug-14 07:42 greetings/ - * -rw-r--r-- 3.0 unx 32 tx stor 13-Aug-14 07:40 greetings/en.txt - * -rw-r--r-- 3.0 unx 28 tx stor 13-Aug-14 07:42 greetings/es.txt - * -rw-r--r-- 3.0 unx 25 tx stor 13-Aug-14 07:41 greetings/fr.txt - * -rw-r--r-- 3.0 unx 40 tx stor 13-Aug-14 07:40 greetings/ja.txt - * drwxr-xr-x 3.0 unx 0 bx stor 13-Aug-14 07:48 binary/ - * -rw-r--r-- 3.0 unx 51 bx stor 13-Aug-14 07:48 binary/bytes_0_to_50.bin - * 7 files, 176 bytes uncompressed, 176 bytes compressed: 0.0% - */ - val binZip = Array[Byte](80, 75, 3, 4, 10, 0, 0, 0, 0, 0, 89, 61, 13, 69, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 28, 0, 103, 114, 101, 101, 116, - 105, 110, 103, 115, 47, 85, 84, 9, 0, 3, -39, -6, -22, 83, -44, -4, -22, - 83, 117, 120, 11, 0, 1, 4, -4, 1, 0, 0, 4, 0, 0, 0, 0, 80, 75, 3, 4, 10, - 0, 2, 0, 0, 0, 13, 61, 13, 69, -125, -110, -96, -74, 32, 0, 0, 0, 32, 0, - 0, 0, 16, 0, 28, 0, 103, 114, 101, 101, 116, 105, 110, 103, 115, 47, 101, - 110, 46, 116, 120, 116, 85, 84, 9, 0, 3, 73, -6, -22, 83, -108, -4, -22, - 83, 117, 120, 11, 0, 1, 4, -4, 1, 0, 0, 4, 0, 0, 0, 0, 72, 101, 108, 108, - 111, 32, 87, 111, 114, 108, 100, 44, 32, 104, 111, 119, 32, 97, 114, 101, - 32, 121, 111, 117, 32, 100, 111, 105, 110, 103, 63, 10, 80, 75, 3, 4, 10, - 0, 2, 0, 0, 0, 89, 61, 13, 69, -27, 99, -56, -20, 28, 0, 0, 0, 28, 0, 0, - 0, 16, 0, 28, 0, 103, 114, 101, 101, 116, 105, 110, 103, 115, 47, 101, - 115, 46, 116, 120, 116, 85, 84, 9, 0, 3, -39, -6, -22, 83, -108, -4, -22, - 83, 117, 120, 11, 0, 1, 4, -4, 1, 0, 0, 4, 0, 0, 0, 0, -62, -65, 72, 111, - 108, 97, 32, 109, 117, 110, 100, 111, 44, 32, 99, -61, -77, 109, 111, 32, - 101, 115, 116, -61, -95, 115, 63, 10, 80, 75, 3, 4, 10, 0, 2, 0, 0, 0, 42, - 61, 13, 69, -2, -58, -42, 30, 25, 0, 0, 0, 25, 0, 0, 0, 16, 0, 28, 0, 103, - 114, 101, 101, 116, 105, 110, 103, 115, 47, 102, 114, 46, 116, 120, 116, - 85, 84, 9, 0, 3, -128, -6, -22, 83, -108, -4, -22, 83, 117, 120, 11, 0, 1, - 4, -4, 1, 0, 0, 4, 0, 0, 0, 0, 66, 111, 110, 106, 111, 117, 114, 44, 32, - 99, 111, 109, 109, 101, 110, 116, 32, -61, -89, 97, 32, 118, 97, 63, 10, - 80, 75, 3, 4, 10, 0, 2, 0, 0, 0, 24, 61, 13, 69, -26, -5, 76, 91, 40, 0, - 0, 0, 40, 0, 0, 0, 16, 0, 28, 0, 103, 114, 101, 101, 116, 105, 110, 103, - 115, 47, 106, 97, 46, 116, 120, 116, 85, 84, 9, 0, 3, 96, -6, -22, 83, - -108, -4, -22, 83, 117, 120, 11, 0, 1, 4, -4, 1, 0, 0, 4, 0, 0, 0, 0, - -29, -127, -109, -29, -126, -109, -29, -127, -85, -29, -127, -95, -29, - -127, -81, -29, -128, -127, -29, -127, -118, -27, -123, -125, -26, -80, - -105, -29, -127, -89, -29, -127, -103, -29, -127, -117, -29, -128, -126, - 10, 80, 75, 3, 4, 10, 0, 0, 0, 0, 0, 6, 62, 13, 69, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 7, 0, 28, 0, 98, 105, 110, 97, 114, 121, 47, 85, 84, 9, 0, - 3, 28, -4, -22, 83, -44, -4, -22, 83, 117, 120, 11, 0, 1, 4, -4, 1, 0, 0, - 4, 0, 0, 0, 0, 80, 75, 3, 4, 10, 0, 2, 0, 0, 0, 3, 62, 13, 69, -7, 93, 98, - 55, 51, 0, 0, 0, 51, 0, 0, 0, 24, 0, 28, 0, 98, 105, 110, 97, 114, 121, - 47, 98, 121, 116, 101, 115, 95, 48, 95, 116, 111, 95, 53, 48, 46, 98, 105, - 110, 85, 84, 9, 0, 3, 22, -4, -22, 83, -108, -4, -22, 83, 117, 120, 11, 0, - 1, 4, -4, 1, 0, 0, 4, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 80, 75, 1, 2, 30, 3, 10, 0, 0, 0, 0, 0, 89, 61, 13, 69, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 24, 0, 0, 0, 0, 0, 0, 0, 16, 0, -19, - 65, 0, 0, 0, 0, 103, 114, 101, 101, 116, 105, 110, 103, 115, 47, 85, 84, - 5, 0, 3, -39, -6, -22, 83, 117, 120, 11, 0, 1, 4, -4, 1, 0, 0, 4, 0, 0, 0, - 0, 80, 75, 1, 2, 30, 3, 10, 0, 2, 0, 0, 0, 13, 61, 13, 69, -125, -110, - -96, -74, 32, 0, 0, 0, 32, 0, 0, 0, 16, 0, 24, 0, 0, 0, 0, 0, 1, 0, 0, 0, - -92, -127, 68, 0, 0, 0, 103, 114, 101, 101, 116, 105, 110, 103, 115, 47, - 101, 110, 46, 116, 120, 116, 85, 84, 5, 0, 3, 73, -6, -22, 83, 117, 120, - 11, 0, 1, 4, -4, 1, 0, 0, 4, 0, 0, 0, 0, 80, 75, 1, 2, 30, 3, 10, 0, 2, 0, - 0, 0, 89, 61, 13, 69, -27, 99, -56, -20, 28, 0, 0, 0, 28, 0, 0, 0, 16, 0, - 24, 0, 0, 0, 0, 0, 1, 0, 0, 0, -92, -127, -82, 0, 0, 0, 103, 114, 101, - 101, 116, 105, 110, 103, 115, 47, 101, 115, 46, 116, 120, 116, 85, 84, 5, - 0, 3, -39, -6, -22, 83, 117, 120, 11, 0, 1, 4, -4, 1, 0, 0, 4, 0, 0, 0, 0, - 80, 75, 1, 2, 30, 3, 10, 0, 2, 0, 0, 0, 42, 61, 13, 69, -2, -58, -42, 30, - 25, 0, 0, 0, 25, 0, 0, 0, 16, 0, 24, 0, 0, 0, 0, 0, 1, 0, 0, 0, -92, -127, - 20, 1, 0, 0, 103, 114, 101, 101, 116, 105, 110, 103, 115, 47, 102, 114, - 46, 116, 120, 116, 85, 84, 5, 0, 3, -128, -6, -22, 83, 117, 120, 11, 0, 1, - 4, -4, 1, 0, 0, 4, 0, 0, 0, 0, 80, 75, 1, 2, 30, 3, 10, 0, 2, 0, 0, 0, 24, - 61, 13, 69, -26, -5, 76, 91, 40, 0, 0, 0, 40, 0, 0, 0, 16, 0, 24, 0, 0, 0, - 0, 0, 1, 0, 0, 0, -92, -127, 119, 1, 0, 0, 103, 114, 101, 101, 116, 105, - 110, 103, 115, 47, 106, 97, 46, 116, 120, 116, 85, 84, 5, 0, 3, 96, -6, - -22, 83, 117, 120, 11, 0, 1, 4, -4, 1, 0, 0, 4, 0, 0, 0, 0, 80, 75, 1, 2, - 30, 3, 10, 0, 0, 0, 0, 0, 6, 62, 13, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 7, 0, 24, 0, 0, 0, 0, 0, 0, 0, 16, 0, -19, 65, -23, 1, 0, 0, 98, 105, - 110, 97, 114, 121, 47, 85, 84, 5, 0, 3, 28, -4, -22, 83, 117, 120, 11, 0, - 1, 4, -4, 1, 0, 0, 4, 0, 0, 0, 0, 80, 75, 1, 2, 30, 3, 10, 0, 2, 0, 0, 0, - 3, 62, 13, 69, -7, 93, 98, 55, 51, 0, 0, 0, 51, 0, 0, 0, 24, 0, 24, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -92, -127, 42, 2, 0, 0, 98, 105, 110, 97, 114, 121, - 47, 98, 121, 116, 101, 115, 95, 48, 95, 116, 111, 95, 53, 48, 46, 98, 105, - 110, 85, 84, 5, 0, 3, 22, -4, -22, 83, 117, 120, 11, 0, 1, 4, -4, 1, 0, 0, - 4, 0, 0, 0, 0, 80, 75, 5, 6, 0, 0, 0, 0, 7, 0, 7, 0, 83, 2, 0, 0, -81, 2, - 0, 0, 0, 0) - -} From 25500163f7217c25e5c78f2f8e694b150435ead1 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Mon, 3 Apr 2017 14:21:05 +0100 Subject: [PATCH 0189/2665] Use LocalProject to solve cyclical deps in the build --- project/Build.scala | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index f87307bc4d..8c67014e08 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -142,7 +142,7 @@ object Build { shouldPartest := { val testListDir = ( - (resourceDirectory in (partestSuite, Test)).value / "scala" + (resourceDirectory in (LocalProject("partestSuite"), Test)).value / "scala" / "tools" / "partest" / "scalajs" / scalaVersion.value ) testListDir.exists @@ -536,7 +536,7 @@ object Build { sys.props("scala.scalajs.compiler.test.output") = testOutDir.getAbsolutePath sys.props("scala.scalajs.compiler.test.scalajslib") = - (packageBin in (library, Compile)).value.getAbsolutePath + (packageBin in (LocalProject("library"), Compile)).value.getAbsolutePath def scalaArtifact(name: String): String = { def isTarget(att: Attributed[File]) = { @@ -1076,16 +1076,16 @@ object Build { val filter = ("*.sjsir": NameFilter) - val javalibProducts = (products in javalib).value + val javalibProducts = (products in LocalProject("javalib")).value val javalibMappings = javalibProducts.flatMap(base => Path.selectSubpaths(base, filter)) val javalibFilteredMappings = javalibMappings.filter( _._2.replace('\\', '/') != "java/lang/MathJDK8Bridge$.sjsir") val otherProducts = ( - (products in javalanglib).value ++ - (products in scalalib).value ++ - (products in libraryAux).value) + (products in LocalProject("javalanglib")).value ++ + (products in LocalProject("scalalib")).value ++ + (products in LocalProject("libraryAux")).value) val otherMappings = otherProducts.flatMap(base => Path.selectSubpaths(base, filter)) From a65d1d3301db512cd167bbfc0429a5a678aaa955 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 30 Mar 2017 14:14:58 +0100 Subject: [PATCH 0190/2665] Switch to Project#settings in the build .. and miscellaneous other build tweaks. --- project/Build.scala | 1679 ++++++++++++++++++++----------------------- 1 file changed, 794 insertions(+), 885 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 8c67014e08..7d0e5cc182 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -334,26 +334,23 @@ object Build { } ) - private def publishToBintraySettings = ( - bintrayPublishSettings - ) ++ Seq( + private def publishToBintraySettings = Def.settings( + bintrayPublishSettings, repository in bintray := "scala-js-releases", bintrayOrganization in bintray := Some("scala-js") ) - val publishIvySettings = ( + val publishIvySettings = Def.settings( if (Properties.envOrNone("PUBLISH_TO_BINTRAY") == Some("true")) publishToBintraySettings else - publishToScalaJSRepoSettings - ) ++ Seq( + publishToScalaJSRepoSettings, publishMavenStyle := false ) - val myScalaJSSettings = ( - ScalaJSPluginInternal.scalaJSAbstractSettings ++ - PhantomJSEnvPlugin.projectSettings - ) ++ Seq( + val myScalaJSSettings = Def.settings( + ScalaJSPluginInternal.scalaJSAbstractSettings, + PhantomJSEnvPlugin.projectSettings, autoCompilerPlugins := true, scalaJSOptimizerOptions ~= (_.withCheckScalaJSIR(true)), @@ -378,14 +375,14 @@ object Build { def withScalaJSJUnitPlugin: Project = { project.settings( - scalacOptions in Test ++= { - if (isGeneratingEclipse) { - Seq.empty - } else { - val jar = (packageBin in (jUnitPlugin, Compile)).value - Seq(s"-Xplugin:$jar") + scalacOptions in Test ++= { + if (isGeneratingEclipse) { + Seq.empty + } else { + val jar = (packageBin in (jUnitPlugin, Compile)).value + Seq(s"-Xplugin:$jar") + } } - } ) } @@ -417,9 +414,8 @@ object Build { } } - val thisBuildSettings = ( - inScope(Global)(ScalaJSPlugin.globalSettings) - ) ++ Seq( + val thisBuildSettings = Def.settings( + inScope(Global)(ScalaJSPlugin.globalSettings), // Most of the projects cross-compile crossScalaVersions := Seq( "2.10.2", @@ -453,40 +449,38 @@ object Build { } ) - lazy val root: Project = Project( - id = "scalajs", - base = file("."), - settings = commonSettings ++ Seq( - name := "Scala.js", - publishArtifact in Compile := false, - - clean := clean.dependsOn( - clean in compiler, - clean in irProject, clean in irProjectJS, - clean in tools, clean in toolsJS, - clean in jsEnvs, clean in jsEnvsTestKit, clean in jsEnvsTestSuite, - clean in testAdapter, clean in plugin, - clean in javalanglib, clean in javalib, clean in scalalib, - clean in libraryAux, clean in library, - clean in stubs, clean in cli, - clean in testInterface, - clean in jUnitRuntime, clean in jUnitPlugin, - clean in jUnitTestOutputsJS, clean in jUnitTestOutputsJVM, - clean in examples, clean in helloworld, - clean in reversi, clean in testingExample, - clean in testSuite, clean in testSuiteJVM, clean in noIrCheckTest, - clean in testSuiteEx, - clean in partest, clean in partestSuite, - clean in scalaTestSuite).value, - - publish := {}, - publishLocal := {} - ) + lazy val root: Project = Project(id = "scalajs", base = file(".")).settings( + commonSettings, + name := "Scala.js", + publishArtifact in Compile := false, + + clean := clean.dependsOn( + clean in compiler, + clean in irProject, clean in irProjectJS, + clean in tools, clean in toolsJS, + clean in jsEnvs, clean in jsEnvsTestKit, clean in jsEnvsTestSuite, + clean in testAdapter, clean in plugin, + clean in javalanglib, clean in javalib, clean in scalalib, + clean in libraryAux, clean in library, + clean in stubs, clean in cli, + clean in testInterface, + clean in jUnitRuntime, clean in jUnitPlugin, + clean in jUnitTestOutputsJS, clean in jUnitTestOutputsJVM, + clean in examples, clean in helloworld, + clean in reversi, clean in testingExample, + clean in testSuite, clean in testSuiteJVM, clean in noIrCheckTest, + clean in testSuiteEx, + clean in partest, clean in partestSuite, + clean in scalaTestSuite).value, + + publish := {}, + publishLocal := {} ) - val commonIrProjectSettings = ( - commonSettings ++ publishSettings ++ fatalWarningsSettings - ) ++ Seq( + val commonIrProjectSettings = Def.settings( + commonSettings, + publishSettings, + fatalWarningsSettings, name := "Scala.js IR", previousArtifactSetting, mimaBinaryIssueFilters ++= BinaryIncompatibilities.IR, @@ -495,79 +489,73 @@ object Build { testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a", "-s") ) - lazy val irProject: Project = Project( - id = "ir", - base = file("ir"), - settings = commonIrProjectSettings ++ Seq( - libraryDependencies += - "com.novocode" % "junit-interface" % "0.9" % "test" - ) + lazy val irProject: Project = Project(id = "ir", base = file("ir")).settings( + commonIrProjectSettings, + libraryDependencies += + "com.novocode" % "junit-interface" % "0.9" % "test" ) - lazy val irProjectJS: Project = Project( - id = "irJS", - base = file("ir/.js"), - settings = commonIrProjectSettings ++ myScalaJSSettings ++ Seq( - crossVersion := ScalaJSCrossVersion.binary, - unmanagedSourceDirectories in Compile += - (scalaSource in Compile in irProject).value, - unmanagedSourceDirectories in Test += - (scalaSource in Test in irProject).value - ) + lazy val irProjectJS: Project = Project(id = "irJS", base = file("ir/.js")).settings( + commonIrProjectSettings, + myScalaJSSettings, + crossVersion := ScalaJSCrossVersion.binary, + unmanagedSourceDirectories in Compile += + (scalaSource in Compile in irProject).value, + unmanagedSourceDirectories in Test += + (scalaSource in Test in irProject).value ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( library, jUnitRuntime % "test" ) - lazy val compiler: Project = Project( - id = "compiler", - base = file("compiler"), - settings = commonSettings ++ publishSettings ++ Seq( - name := "Scala.js compiler", - crossVersion := CrossVersion.full, // because compiler api is not binary compatible - libraryDependencies ++= Seq( - "org.scala-lang" % "scala-compiler" % scalaVersion.value, - "org.scala-lang" % "scala-reflect" % scalaVersion.value, - "com.novocode" % "junit-interface" % "0.9" % "test" - ), - testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a"), - testOptions += Tests.Setup { () => - val testOutDir = (streams.value.cacheDirectory / "scalajs-compiler-test") - IO.createDirectory(testOutDir) - sys.props("scala.scalajs.compiler.test.output") = - testOutDir.getAbsolutePath - sys.props("scala.scalajs.compiler.test.scalajslib") = - (packageBin in (LocalProject("library"), Compile)).value.getAbsolutePath - - def scalaArtifact(name: String): String = { - def isTarget(att: Attributed[File]) = { - att.metadata.get(moduleID.key).exists { mId => - mId.organization == "org.scala-lang" && - mId.name == name && - mId.revision == scalaVersion.value - } - } - - (managedClasspath in Test).value.find(isTarget).fold { - streams.value.log.error(s"Couldn't find $name on the classpath") - "" - } { lib => - lib.data.getAbsolutePath - } + lazy val compiler: Project = project.settings( + commonSettings, + publishSettings, + name := "Scala.js compiler", + crossVersion := CrossVersion.full, // because compiler api is not binary compatible + libraryDependencies ++= Seq( + "org.scala-lang" % "scala-compiler" % scalaVersion.value, + "org.scala-lang" % "scala-reflect" % scalaVersion.value, + "com.novocode" % "junit-interface" % "0.9" % "test" + ), + testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a"), + testOptions += Tests.Setup { () => + val testOutDir = (streams.value.cacheDirectory / "scalajs-compiler-test") + IO.createDirectory(testOutDir) + sys.props("scala.scalajs.compiler.test.output") = + testOutDir.getAbsolutePath + sys.props("scala.scalajs.compiler.test.scalajslib") = + (packageBin in (LocalProject("library"), Compile)).value.getAbsolutePath + + def scalaArtifact(name: String): String = { + def isTarget(att: Attributed[File]) = { + att.metadata.get(moduleID.key).exists { mId => + mId.organization == "org.scala-lang" && + mId.name == name && + mId.revision == scalaVersion.value } + } - sys.props("scala.scalajs.compiler.test.scalalib") = - scalaArtifact("scala-library") + (managedClasspath in Test).value.find(isTarget).fold { + streams.value.log.error(s"Couldn't find $name on the classpath") + "" + } { lib => + lib.data.getAbsolutePath + } + } - sys.props("scala.scalajs.compiler.test.scalareflect") = - scalaArtifact("scala-reflect") - }, - exportJars := true - ) + sys.props("scala.scalajs.compiler.test.scalalib") = + scalaArtifact("scala-library") + + sys.props("scala.scalajs.compiler.test.scalareflect") = + scalaArtifact("scala-reflect") + }, + exportJars := true ).dependsOnSource(irProject) - val commonToolsSettings = ( - commonSettings ++ publishSettings ++ fatalWarningsSettings - ) ++ Seq( + val commonToolsSettings = Def.settings( + commonSettings, + publishSettings, + fatalWarningsSettings, name := "Scala.js tools", unmanagedSourceDirectories in Compile += @@ -586,49 +574,46 @@ object Build { exportJars := true // required so ScalaDoc linking works ) - lazy val tools: Project = Project( - id = "tools", - base = file("tools/jvm"), - settings = commonToolsSettings ++ Seq( - libraryDependencies ++= Seq( - "org.scala-js" % "closure-compiler-java-6" % "v20160517", - "com.googlecode.json-simple" % "json-simple" % "1.1.1" exclude("junit", "junit"), - "com.novocode" % "junit-interface" % "0.9" % "test" - ) ++ ( - CrossVersion.partialVersion(scalaVersion.value) match { - case Some((2, n)) if n >= 13 => - Seq("org.scala-lang.modules" %% "scala-parallel-collections" % "0.1.1") - - case _ => Nil - } - ) + lazy val tools: Project = (project in file("tools/jvm")).settings( + commonToolsSettings, + libraryDependencies ++= Seq( + "org.scala-js" % "closure-compiler-java-6" % "v20160517", + "com.googlecode.json-simple" % "json-simple" % "1.1.1" exclude("junit", "junit"), + "com.novocode" % "junit-interface" % "0.9" % "test" + ) ++ ( + CrossVersion.partialVersion(scalaVersion.value) match { + case Some((2, n)) if n >= 13 => + Seq("org.scala-lang.modules" %% "scala-parallel-collections" % "0.1.1") + + case _ => Nil + } ) ).dependsOn(irProject) - lazy val toolsJS: Project = Project( - id = "toolsJS", - base = file("tools/js"), - settings = myScalaJSSettings ++ commonToolsSettings ++ Seq( - crossVersion := ScalaJSCrossVersion.binary, - resourceGenerators in Test += Def.task { - val base = (resourceManaged in Compile).value - IO.createDirectory(base) - val outFile = base / "js-test-definitions.js" - - val testDefinitions = { - org.scalajs.build.HTMLRunnerTemplateAccess.renderTestDefinitions( - (loadedTestFrameworks in testSuite in Test).value, - (definedTests in testSuite in Test).value) - } + lazy val toolsJS: Project = (project in file("tools/js")).settings( + myScalaJSSettings, + 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" + + 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, + }.taskValue, - jsDependencies += ProvidedJS / "js-test-definitions.js" % "test", - jsDependencies += - "org.webjars" % "jszip" % "2.4.0" % "test" / "jszip.min.js" commonJSName "JSZip" - ) ++ inConfig(Test) { + jsDependencies += ProvidedJS / "js-test-definitions.js" % "test", + jsDependencies += + "org.webjars" % "jszip" % "2.4.0" % "test" / "jszip.min.js" commonJSName "JSZip", + + inConfig(Test) { // Redefine test to run Node.js and link HelloWorld test := { if (!resolvedJSEnv.value.isInstanceOf[NodeJSEnv]) @@ -700,87 +685,71 @@ object Build { library, irProjectJS, testSuite % "test->test" ) - lazy val jsEnvs: Project = Project( - id = "jsEnvs", - base = file("js-envs"), - settings = ( - commonSettings ++ publishSettings ++ fatalWarningsSettings - ) ++ Seq( - name := "Scala.js JS Envs", - previousArtifactSetting, - mimaBinaryIssueFilters ++= BinaryIncompatibilities.JSEnvs - ) + lazy val jsEnvs: Project = (project in file("js-envs")).settings( + commonSettings, + publishSettings, + fatalWarningsSettings, + name := "Scala.js JS Envs", + previousArtifactSetting, + mimaBinaryIssueFilters ++= BinaryIncompatibilities.JSEnvs ).dependsOn(tools) - lazy val jsEnvsTestKit: Project = Project( - id = "jsEnvsTestKit", - base = file("js-envs-test-kit"), - settings = ( - commonSettings ++ publishSettings ++ fatalWarningsSettings - ) ++ Seq( - name := "Scala.js JS Envs Test Kit", - libraryDependencies += - "junit" % "junit" % "4.8.2", - previousArtifactSetting, - mimaBinaryIssueFilters ++= BinaryIncompatibilities.JSEnvsTestKit - ) + 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", + previousArtifactSetting, + mimaBinaryIssueFilters ++= BinaryIncompatibilities.JSEnvsTestKit ).dependsOn(tools, jsEnvs) - lazy val jsEnvsTestSuite: Project = Project( - id = "jsEnvsTestSuite", - base = file("js-envs-test-suite"), - settings = ( - commonSettings ++ fatalWarningsSettings - ) ++ Seq( - name := "Scala.js JS Envs Test Suite", - libraryDependencies += - "com.novocode" % "junit-interface" % "0.9" % "test" - ) + lazy val jsEnvsTestSuite: Project = (project in file("js-envs-test-suite")).settings( + commonSettings, + fatalWarningsSettings, + name := "Scala.js JS Envs Test Suite", + libraryDependencies += + "com.novocode" % "junit-interface" % "0.9" % "test" ).dependsOn(tools, jsEnvs, jsEnvsTestKit % "test") - lazy val testAdapter = Project( - id = "testAdapter", - base = file("test-adapter"), - settings = ( - commonSettings ++ publishSettings ++ fatalWarningsSettings - ) ++ Seq( - name := "Scala.js sbt test adapter", - libraryDependencies += "org.scala-sbt" % "test-interface" % "1.0", - previousArtifactSetting, - mimaBinaryIssueFilters ++= BinaryIncompatibilities.TestAdapter - ) + lazy val testAdapter = (project in file("test-adapter")).settings( + commonSettings, + publishSettings, + fatalWarningsSettings, + name := "Scala.js sbt test adapter", + libraryDependencies += "org.scala-sbt" % "test-interface" % "1.0", + previousArtifactSetting, + mimaBinaryIssueFilters ++= BinaryIncompatibilities.TestAdapter ).dependsOn(jsEnvs) - lazy val plugin: Project = Project( - id = "sbtPlugin", - base = file("sbt-plugin"), - settings = ( - commonSettings ++ publishIvySettings ++ fatalWarningsSettings - ) ++ Seq( - name := "Scala.js sbt plugin", - normalizedName := "sbt-scalajs", - name in bintray := "sbt-scalajs-plugin", // "sbt-scalajs" was taken - sbtPlugin := true, - scalaBinaryVersion := - CrossVersion.binaryScalaVersion(scalaVersion.value), - previousArtifactSetting, - mimaBinaryIssueFilters ++= BinaryIncompatibilities.SbtPlugin, - - // Add API mappings for sbt (seems they don't export their API URL) - apiMappings ++= { - val deps = (externalDependencyClasspath in Compile).value - - val sbtJars = deps filter { attributed => - val p = attributed.data.getPath - p.contains("/org.scala-sbt/") && p.endsWith(".jar") - } + lazy val plugin: Project = Project(id = "sbtPlugin", base = file("sbt-plugin")).settings( + commonSettings, + publishIvySettings, + fatalWarningsSettings, + name := "Scala.js sbt plugin", + normalizedName := "sbt-scalajs", + name in bintray := "sbt-scalajs-plugin", // "sbt-scalajs" was taken + sbtPlugin := true, + scalaBinaryVersion := + CrossVersion.binaryScalaVersion(scalaVersion.value), + previousArtifactSetting, + mimaBinaryIssueFilters ++= BinaryIncompatibilities.SbtPlugin, - val docUrl = - url(s"http://www.scala-sbt.org/${sbtVersion.value}/api/") + // Add API mappings for sbt (seems they don't export their API URL) + apiMappings ++= { + val deps = (externalDependencyClasspath in Compile).value - sbtJars.map(_.data -> docUrl).toMap - } - ) + val sbtJars = deps filter { attributed => + val p = attributed.data.getPath + p.contains("/org.scala-sbt/") && p.endsWith(".jar") + } + + val docUrl = + url(s"http://www.scala-sbt.org/${sbtVersion.value}/api/") + + sbtJars.map(_.data -> docUrl).toMap + } ).dependsOn(tools, jsEnvs, testAdapter) lazy val delambdafySetting = { @@ -809,232 +778,214 @@ object Build { output } - lazy val javalanglib: Project = Project( - id = "javalanglib", - base = file("javalanglib"), - settings = ( - commonSettings ++ myScalaJSSettings ++ fatalWarningsSettings - ) ++ Seq( - name := "java.lang library for Scala.js", - publishArtifact in Compile := false, - delambdafySetting, - noClassFilesSettings, - - resourceGenerators in Compile += Def.task { - val base = (resourceManaged in Compile).value - Seq( - serializeHardcodedIR(base, JavaLangObject.InfoAndTree), - serializeHardcodedIR(base, JavaLangString.InfoAndTree) - ) - }.taskValue - ) ++ ( - scalaJSExternalCompileSettings - ) + lazy val javalanglib: Project = project.settings( + commonSettings, + myScalaJSSettings, + fatalWarningsSettings, + name := "java.lang library for Scala.js", + publishArtifact in Compile := false, + delambdafySetting, + noClassFilesSettings, + + resourceGenerators in Compile += Def.task { + val base = (resourceManaged in Compile).value + Seq( + serializeHardcodedIR(base, JavaLangObject.InfoAndTree), + serializeHardcodedIR(base, JavaLangString.InfoAndTree) + ) + }.taskValue, + scalaJSExternalCompileSettings ).withScalaJSCompiler.dependsOnLibraryNoJar - lazy val javalib: Project = Project( - id = "javalib", - base = file("javalib"), - settings = ( - commonSettings ++ myScalaJSSettings ++ fatalWarningsSettings - ) ++ Seq( - name := "Java library for Scala.js", - publishArtifact in Compile := false, - delambdafySetting, - noClassFilesSettings - ) ++ ( - scalaJSExternalCompileSettings - ) + lazy val javalib: Project = project.settings( + commonSettings, + myScalaJSSettings, + fatalWarningsSettings, + name := "Java library for Scala.js", + publishArtifact in Compile := false, + delambdafySetting, + noClassFilesSettings, + scalaJSExternalCompileSettings ).withScalaJSCompiler.dependsOnLibraryNoJar - lazy val scalalib: Project = Project( - id = "scalalib", - base = file("scalalib"), - settings = commonSettings ++ Seq( - /* Link source maps to the GitHub sources of the original scalalib - * #2195 This must come *before* the option added by myScalaJSSettings - * because mapSourceURI works on a first-match basis. - */ - scalacOptions += { - "-P:scalajs:mapSourceURI:" + - (artifactPath in fetchScalaSource).value.toURI + - "->https://raw.githubusercontent.com/scala/scala/v" + - scalaVersion.value + "/src/library/" - } - ) ++ myScalaJSSettings ++ Seq( - name := "Scala library for Scala.js", - publishArtifact in Compile := false, - delambdafySetting, - noClassFilesSettings, - - // The Scala lib is full of warnings we don't want to see - scalacOptions ~= (_.filterNot( - Set("-deprecation", "-unchecked", "-feature") contains _)), - - // Tell the plugin to hack-fix bad classOf trees - scalacOptions += "-P:scalajs:fixClassOf", - - libraryDependencies += - "org.scala-lang" % "scala-library" % scalaVersion.value classifier "sources", - - artifactPath in fetchScalaSource := - target.value / "scalaSources" / scalaVersion.value, - - /* Work around for #2649. We would like to always use `update`, but - * that fails if the scalaVersion we're looking for happens to be the - * version of Scala used by sbt itself. This is clearly a bug in sbt, - * which we work around here by using `updateClassifiers` instead in - * that case. - */ - update in fetchScalaSource := Def.taskDyn { - if (scalaVersion.value == scala.util.Properties.versionNumberString) - updateClassifiers - else - update - }.value, - - fetchScalaSource := { - val s = streams.value - val cacheDir = s.cacheDirectory - val ver = scalaVersion.value - val trgDir = (artifactPath in fetchScalaSource).value - - val report = (update in fetchScalaSource).value - val scalaLibSourcesJar = report.select( - configuration = Set("compile"), - module = moduleFilter(name = "scala-library"), - artifact = artifactFilter(classifier = "sources")).headOption.getOrElse { - sys.error(s"Could not fetch scala-library sources for version $ver") - } + lazy val scalalib: Project = project.settings( + commonSettings, + /* Link source maps to the GitHub sources of the original scalalib + * #2195 This must come *before* the option added by myScalaJSSettings + * because mapSourceURI works on a first-match basis. + */ + scalacOptions += { + "-P:scalajs:mapSourceURI:" + + (artifactPath in fetchScalaSource).value.toURI + + "->https://raw.githubusercontent.com/scala/scala/v" + + scalaVersion.value + "/src/library/" + }, + myScalaJSSettings, + name := "Scala library for Scala.js", + publishArtifact in Compile := false, + delambdafySetting, + noClassFilesSettings, - FileFunction.cached(cacheDir / s"fetchScalaSource-$ver", - FilesInfo.lastModified, FilesInfo.exists) { dependencies => - s.log.info(s"Unpacking Scala library sources to $trgDir...") + // The Scala lib is full of warnings we don't want to see + scalacOptions ~= (_.filterNot( + Set("-deprecation", "-unchecked", "-feature") contains _)), - if (trgDir.exists) - IO.delete(trgDir) - IO.createDirectory(trgDir) - IO.unzip(scalaLibSourcesJar, trgDir) - } (Set(scalaLibSourcesJar)) + // Tell the plugin to hack-fix bad classOf trees + scalacOptions += "-P:scalajs:fixClassOf", - trgDir - }, + libraryDependencies += + "org.scala-lang" % "scala-library" % scalaVersion.value classifier "sources", - unmanagedSourceDirectories in Compile := { - // Calculates all prefixes of the current Scala version - // (including the empty prefix) to construct override - // directories like the following: - // - override-2.10.2-RC1 - // - override-2.10.2 - // - override-2.10 - // - override-2 - // - override - val ver = scalaVersion.value - val base = baseDirectory.value - val parts = ver.split(Array('.','-')) - val verList = parts.inits.map { ps => - val len = ps.mkString(".").length - // re-read version, since we lost '.' and '-' - ver.substring(0, len) - } - def dirStr(v: String) = - if (v.isEmpty) "overrides" else s"overrides-$v" - val dirs = verList.map(base / dirStr(_)).filter(_.exists) - dirs.toSeq // most specific shadow less specific - }, + artifactPath in fetchScalaSource := + target.value / "scalaSources" / scalaVersion.value, - // Compute sources - // Files in earlier src dirs shadow files in later dirs - sources in Compile := { - // Sources coming from the sources of Scala - val scalaSrcDir = fetchScalaSource.value - - // All source directories (overrides shadow scalaSrcDir) - val sourceDirectories = - (unmanagedSourceDirectories in Compile).value :+ scalaSrcDir - - // Filter sources with overrides - def normPath(f: File): String = - f.getPath.replace(java.io.File.separator, "/") - - val sources = mutable.ListBuffer.empty[File] - val paths = mutable.Set.empty[String] - - for { - srcDir <- sourceDirectories - normSrcDir = normPath(srcDir) - src <- (srcDir ** "*.scala").get - } { - val normSrc = normPath(src) - val path = normSrc.substring(normSrcDir.length) - val useless = - path.contains("/scala/collection/parallel/") || - path.contains("/scala/util/parsing/") - if (!useless) { - if (paths.add(path)) - sources += src - else - streams.value.log.debug(s"not including $src") - } - } + /* Work around for #2649. We would like to always use `update`, but + * that fails if the scalaVersion we're looking for happens to be the + * version of Scala used by sbt itself. This is clearly a bug in sbt, + * which we work around here by using `updateClassifiers` instead in + * that case. + */ + update in fetchScalaSource := Def.taskDyn { + if (scalaVersion.value == scala.util.Properties.versionNumberString) + updateClassifiers + else + update + }.value, + + fetchScalaSource := { + val s = streams.value + val cacheDir = s.cacheDirectory + val ver = scalaVersion.value + val trgDir = (artifactPath in fetchScalaSource).value + + val report = (update in fetchScalaSource).value + val scalaLibSourcesJar = report.select( + configuration = Set("compile"), + module = moduleFilter(name = "scala-library"), + artifact = artifactFilter(classifier = "sources")).headOption.getOrElse { + sys.error(s"Could not fetch scala-library sources for version $ver") + } - sources.result() - }, + FileFunction.cached(cacheDir / s"fetchScalaSource-$ver", + FilesInfo.lastModified, FilesInfo.exists) { dependencies => + s.log.info(s"Unpacking Scala library sources to $trgDir...") - // Continuation plugin (when using 2.10.x) - autoCompilerPlugins := true, - libraryDependencies ++= { - val ver = scalaVersion.value - if (ver.startsWith("2.10.")) - Seq(compilerPlugin("org.scala-lang.plugins" % "continuations" % ver)) - else - Nil - }, - scalacOptions ++= { - if (scalaVersion.value.startsWith("2.10.")) - Seq("-P:continuations:enable") + if (trgDir.exists) + IO.delete(trgDir) + IO.createDirectory(trgDir) + IO.unzip(scalaLibSourcesJar, trgDir) + } (Set(scalaLibSourcesJar)) + + trgDir + }, + + unmanagedSourceDirectories in Compile := { + // Calculates all prefixes of the current Scala version + // (including the empty prefix) to construct override + // directories like the following: + // - override-2.10.2-RC1 + // - override-2.10.2 + // - override-2.10 + // - override-2 + // - override + val ver = scalaVersion.value + val base = baseDirectory.value + val parts = ver.split(Array('.','-')) + val verList = parts.inits.map { ps => + val len = ps.mkString(".").length + // re-read version, since we lost '.' and '-' + ver.substring(0, len) + } + def dirStr(v: String) = + if (v.isEmpty) "overrides" else s"overrides-$v" + val dirs = verList.map(base / dirStr(_)).filter(_.exists) + dirs.toSeq // most specific shadow less specific + }, + + // Compute sources + // Files in earlier src dirs shadow files in later dirs + sources in Compile := { + // Sources coming from the sources of Scala + val scalaSrcDir = fetchScalaSource.value + + // All source directories (overrides shadow scalaSrcDir) + val sourceDirectories = + (unmanagedSourceDirectories in Compile).value :+ scalaSrcDir + + // Filter sources with overrides + def normPath(f: File): String = + f.getPath.replace(java.io.File.separator, "/") + + val sources = mutable.ListBuffer.empty[File] + val paths = mutable.Set.empty[String] + + for { + srcDir <- sourceDirectories + normSrcDir = normPath(srcDir) + src <- (srcDir ** "*.scala").get + } { + val normSrc = normPath(src) + val path = normSrc.substring(normSrcDir.length) + val useless = + path.contains("/scala/collection/parallel/") || + path.contains("/scala/util/parsing/") + if (!useless) { + if (paths.add(path)) + sources += src else - Nil + streams.value.log.debug(s"not including $src") } - ) ++ ( - scalaJSExternalCompileSettings - ) + } + + sources.result() + }, + + // Continuation plugin (when using 2.10.x) + autoCompilerPlugins := true, + libraryDependencies ++= { + val ver = scalaVersion.value + if (ver.startsWith("2.10.")) + Seq(compilerPlugin("org.scala-lang.plugins" % "continuations" % ver)) + else + Nil + }, + scalacOptions ++= { + if (scalaVersion.value.startsWith("2.10.")) + Seq("-P:continuations:enable") + else + Nil + }, + scalaJSExternalCompileSettings ).withScalaJSCompiler.dependsOnLibraryNoJar - lazy val libraryAux: Project = Project( - id = "libraryAux", - base = file("library-aux"), - settings = ( - commonSettings ++ myScalaJSSettings ++ fatalWarningsSettings - ) ++ Seq( - name := "Scala.js aux library", - publishArtifact in Compile := false, - delambdafySetting, - noClassFilesSettings - ) ++ ( - scalaJSExternalCompileSettings - ) + lazy val libraryAux: Project = (project in file("library-aux")).settings( + commonSettings, + myScalaJSSettings, + fatalWarningsSettings, + name := "Scala.js aux library", + publishArtifact in Compile := false, + delambdafySetting, + noClassFilesSettings, + scalaJSExternalCompileSettings ).withScalaJSCompiler.dependsOnLibraryNoJar - lazy val library: Project = Project( - id = "library", - base = file("library"), - settings = ( - commonSettings ++ publishSettings ++ myScalaJSSettings ++ fatalWarningsSettings - ) ++ Seq( - name := "Scala.js library", - delambdafySetting, - exportJars := !isGeneratingEclipse, - previousArtifactSetting, - mimaBinaryIssueFilters ++= BinaryIncompatibilities.Library, - libraryDependencies += - "org.scala-lang" % "scala-reflect" % scalaVersion.value % "provided", - - // js.JSApp is annotated with @JSExportDescendentObjects - scalacOptions += "-P:scalajs:suppressExportDeprecations" - ) ++ ( - scalaJSExternalCompileSettings - ) ++ inConfig(Compile)(Seq( + lazy val library: Project = project.settings( + commonSettings, + publishSettings, + myScalaJSSettings, + fatalWarningsSettings, + name := "Scala.js library", + delambdafySetting, + exportJars := !isGeneratingEclipse, + previousArtifactSetting, + mimaBinaryIssueFilters ++= BinaryIncompatibilities.Library, + libraryDependencies += + "org.scala-lang" % "scala-reflect" % scalaVersion.value % "provided", + + // js.JSApp is annotated with @JSExportDescendentObjects + scalacOptions += "-P:scalajs:suppressExportDeprecations", + scalaJSExternalCompileSettings, + inConfig(Compile)(Seq( scalacOptions in doc ++= Seq("-implicits", "-groups"), // Filter doc sources to remove implementation details from doc. @@ -1094,61 +1045,57 @@ object Build { )) ).withScalaJSCompiler - lazy val stubs: Project = Project( - id = "stubs", - base = file("stubs"), - settings = commonSettings ++ publishSettings ++ Seq( - name := "Scala.js Stubs", - libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value, - previousArtifactSetting - ) + lazy val stubs: Project = project.settings( + commonSettings, + publishSettings, + name := "Scala.js Stubs", + libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value, + previousArtifactSetting ) // Scala.js command line interface - lazy val cli: Project = Project( - id = "cli", - base = file("cli"), - settings = ( - commonSettings ++ publishSettings ++ fatalWarningsSettings - ) ++ Seq( - name := "Scala.js CLI", - libraryDependencies ++= Seq( - "com.github.scopt" %% "scopt" % "3.5.0" - ), - - previousArtifactSetting, - mimaBinaryIssueFilters ++= BinaryIncompatibilities.CLI, - - // assembly options - mainClass in assembly := None, // don't want an executable JAR - assemblyOption in assembly ~= { _.copy(includeScala = false) }, - assemblyJarName in assembly := - s"${normalizedName.value}-assembly_${scalaBinaryVersion.value}-${version.value}.jar" - ) + lazy val cli: Project = project.settings( + commonSettings, + publishSettings, + fatalWarningsSettings, + name := "Scala.js CLI", + libraryDependencies ++= Seq( + "com.github.scopt" %% "scopt" % "3.5.0" + ), + + previousArtifactSetting, + mimaBinaryIssueFilters ++= BinaryIncompatibilities.CLI, + + // assembly options + mainClass in assembly := None, // don't want an executable JAR + assemblyOption in assembly ~= { _.copy(includeScala = false) }, + assemblyJarName in assembly := + s"${normalizedName.value}-assembly_${scalaBinaryVersion.value}-${version.value}.jar" ).dependsOn(tools) // Test framework - lazy val testInterface = Project( - id = "testInterface", - base = file("test-interface"), - settings = ( - commonSettings ++ publishSettings ++ myScalaJSSettings ++ fatalWarningsSettings - ) ++ Seq( - name := "Scala.js test interface", - delambdafySetting, - previousArtifactSetting, - mimaBinaryIssueFilters ++= BinaryIncompatibilities.TestInterface - ) + lazy val testInterface = (project in file("test-interface")).settings( + commonSettings, + publishSettings, + myScalaJSSettings, + fatalWarningsSettings, + name := "Scala.js test interface", + delambdafySetting, + previousArtifactSetting, + mimaBinaryIssueFilters ++= BinaryIncompatibilities.TestInterface ).withScalaJSCompiler.dependsOn(library) - lazy val jUnitRuntime = Project( - id = "jUnitRuntime", - base = file("junit-runtime"), - settings = commonSettings ++ publishSettings ++ myScalaJSSettings ++ - fatalWarningsSettings ++ Seq(name := "Scala.js JUnit test runtime") + lazy val jUnitRuntime = (project in file("junit-runtime")).settings( + commonSettings, + publishSettings, + myScalaJSSettings, + fatalWarningsSettings, + name := "Scala.js JUnit test runtime" ).withScalaJSCompiler.dependsOn(testInterface) - val commonJUnitTestOutputsSettings = commonSettings ++ fatalWarningsSettings ++ Seq( + val commonJUnitTestOutputsSettings = Def.settings( + commonSettings, + fatalWarningsSettings, publishArtifact in Compile := false, parallelExecution in Test := false, unmanagedSourceDirectories in Test += @@ -1159,123 +1106,99 @@ object Build { ) ) - lazy val jUnitTestOutputsJS = Project( - id = "jUnitTestOutputsJS", - base = file("junit-test/output-js"), - settings = commonJUnitTestOutputsSettings ++ myScalaJSSettings ++ Seq( - name := "Tests for Scala.js JUnit output in JS." - ) + lazy val jUnitTestOutputsJS = (project in file("junit-test/output-js")).settings( + commonJUnitTestOutputsSettings, + myScalaJSSettings, + name := "Tests for Scala.js JUnit output in JS." ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( jUnitRuntime % "test", testInterface % "test" ) - lazy val jUnitTestOutputsJVM = Project( - id = "jUnitTestOutputsJVM", - base = file("junit-test/output-jvm"), - settings = commonJUnitTestOutputsSettings ++ Seq( - 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" - ) + 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" ) ) - 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, exportJars := true - ) ) // PhantomJS support - to be moved out of the core repository - lazy val phantomJSEnv: Project = Project( - id = "phantomJSEnv", - base = file("phantomjs-env"), - settings = ( - commonSettings ++ publishSettings ++ fatalWarningsSettings - ) ++ Seq( - name := "scalajs-env-phantomjs", - libraryDependencies ++= - PhantomJSEnvPlugin.phantomJSJettyModules.map(_ % "provided"), - libraryDependencies += - "com.novocode" % "junit-interface" % "0.9" % "test" - ) + lazy val phantomJSEnv: Project = (project in file("phantomjs-env")).settings( + commonSettings, + publishSettings, + fatalWarningsSettings, + name := "scalajs-env-phantomjs", + libraryDependencies ++= + PhantomJSEnvPlugin.phantomJSJettyModules.map(_ % "provided"), + libraryDependencies += + "com.novocode" % "junit-interface" % "0.9" % "test" ).dependsOn(jsEnvs, jsEnvsTestKit % "test") - lazy val phantomJSEnvPlugin: Project = Project( - id = "phantomJSEnvPlugin", - base = file("phantomjs-sbt-plugin"), - settings = ( - commonSettings ++ publishIvySettings ++ fatalWarningsSettings - ) ++ Seq( - name := "sbt-scalajs-env-phantomjs", - sbtPlugin := true, - scalaBinaryVersion := - CrossVersion.binaryScalaVersion(scalaVersion.value), - - // Add API mappings for sbt (seems they don't export their API URL) - apiMappings ++= { - val deps = (externalDependencyClasspath in Compile).value - val sbtJars = deps filter { attributed => - val p = attributed.data.getPath - p.contains("/org.scala-sbt/") && p.endsWith(".jar") - } - val docUrl = - url(s"http://www.scala-sbt.org/${sbtVersion.value}/api/") - sbtJars.map(_.data -> docUrl).toMap - } - ) + lazy val phantomJSEnvPlugin: Project = (project in file("phantomjs-sbt-plugin")).settings( + commonSettings, + publishIvySettings, + fatalWarningsSettings, + name := "sbt-scalajs-env-phantomjs", + sbtPlugin := true, + scalaBinaryVersion := + CrossVersion.binaryScalaVersion(scalaVersion.value), + + // Add API mappings for sbt (seems they don't export their API URL) + apiMappings ++= { + val deps = (externalDependencyClasspath in Compile).value + val sbtJars = deps filter { attributed => + val p = attributed.data.getPath + p.contains("/org.scala-sbt/") && p.endsWith(".jar") + } + val docUrl = + url(s"http://www.scala-sbt.org/${sbtVersion.value}/api/") + sbtJars.map(_.data -> docUrl).toMap + } ).dependsOn(plugin, phantomJSEnv) // Examples - lazy val examples: Project = Project( - id = "examples", - base = file("examples"), - settings = commonSettings ++ Seq( - name := "Scala.js examples" - ) + lazy val examples: Project = project.settings( + commonSettings, + name := "Scala.js examples" ).aggregate(helloworld, reversi, testingExample) lazy val exampleSettings = commonSettings ++ myScalaJSSettings ++ fatalWarningsSettings - lazy val helloworld: Project = Project( - id = "helloworld", - base = file("examples") / "helloworld", - settings = exampleSettings ++ Seq( - name := "Hello World - Scala.js example", - moduleName := "helloworld", - scalaJSUseMainModuleInitializer := true - ) + lazy val helloworld: Project = (project in (file("examples") / "helloworld")).settings( + exampleSettings, + name := "Hello World - Scala.js example", + moduleName := "helloworld", + scalaJSUseMainModuleInitializer := true ).withScalaJSCompiler.dependsOn(library) - lazy val reversi = Project( - id = "reversi", - base = file("examples") / "reversi", - settings = exampleSettings ++ Seq( - name := "Reversi - Scala.js example", - moduleName := "reversi" - ) + lazy val reversi = (project in (file("examples") / "reversi")).settings( + exampleSettings, + name := "Reversi - Scala.js example", + moduleName := "reversi" ).withScalaJSCompiler.dependsOn(library) - lazy val testingExample = Project( - id = "testingExample", - base = file("examples") / "testing", - settings = exampleSettings ++ Seq( - name := "Testing - Scala.js example", - moduleName := "testing", + lazy val testingExample = (project in (file("examples") / "testing")).settings( + exampleSettings, + name := "Testing - Scala.js example", + moduleName := "testing", - jsDependencies ++= Seq( - RuntimeDOM % "test", - "org.webjars" % "jquery" % "1.10.2" / "jquery.js" % "test" - ) + jsDependencies ++= Seq( + RuntimeDOM % "test", + "org.webjars" % "jquery" % "1.10.2" / "jquery.js" % "test" ) ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( library, jUnitRuntime % "test" @@ -1378,53 +1301,53 @@ object Build { } def testSuiteCommonSettings(isJSTest: Boolean): Seq[Setting[_]] = Seq( - publishArtifact in Compile := false, - scalacOptions ~= (_.filter(_ != "-deprecation")), - - // Need reflect for typechecking macros - libraryDependencies += - "org.scala-lang" % "scala-reflect" % scalaVersion.value % "provided", - - testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a", "-s"), + publishArtifact in Compile := false, + scalacOptions ~= (_.filter(_ != "-deprecation")), - unmanagedSourceDirectories in Test ++= { - val testDir = (sourceDirectory in Test).value - val sharedTestDir = - testDir.getParentFile.getParentFile.getParentFile / "shared/src/test" + // Need reflect for typechecking macros + libraryDependencies += + "org.scala-lang" % "scala-reflect" % scalaVersion.value % "provided", - val scalaV = scalaVersion.value - val isScalaAtLeast212 = - !scalaV.startsWith("2.10.") && !scalaV.startsWith("2.11.") - - List(sharedTestDir / "scala") ++ - includeIf(sharedTestDir / "require-jdk7", javaVersion.value >= 7) ++ - includeIf(sharedTestDir / "require-jdk8", javaVersion.value >= 8) ++ - includeIf(testDir / "require-2.12", isJSTest && isScalaAtLeast212) - }, - - sources in Test ++= { - val supportsSAM = scalaBinaryVersion.value match { - case "2.10" => false - case "2.11" => scalacOptions.value.contains("-Xexperimental") - case _ => true - } + testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a", "-s"), - /* Can't add require-sam as unmanagedSourceDirectories because of the use - * of scalacOptions. Hence sources are added individually. - * Note that a testSuite/test will not trigger a compile when sources are - * modified in require-sam - */ - if (supportsSAM) { + unmanagedSourceDirectories in Test ++= { val testDir = (sourceDirectory in Test).value val sharedTestDir = testDir.getParentFile.getParentFile.getParentFile / "shared/src/test" - ((sharedTestDir / "require-sam") ** "*.scala").get ++ - (if (isJSTest) ((testDir / "require-sam") ** "*.scala").get else Nil) - } else { - Nil + val scalaV = scalaVersion.value + val isScalaAtLeast212 = + !scalaV.startsWith("2.10.") && !scalaV.startsWith("2.11.") + + List(sharedTestDir / "scala") ++ + includeIf(sharedTestDir / "require-jdk7", javaVersion.value >= 7) ++ + includeIf(sharedTestDir / "require-jdk8", javaVersion.value >= 8) ++ + includeIf(testDir / "require-2.12", isJSTest && isScalaAtLeast212) + }, + + sources in Test ++= { + val supportsSAM = scalaBinaryVersion.value match { + case "2.10" => false + case "2.11" => scalacOptions.value.contains("-Xexperimental") + case _ => true + } + + /* Can't add require-sam as unmanagedSourceDirectories because of the + * use of scalacOptions. Hence sources are added individually. + * Note that a testSuite/test will not trigger a compile when sources + * are modified in require-sam + */ + if (supportsSAM) { + val testDir = (sourceDirectory in Test).value + val sharedTestDir = + testDir.getParentFile.getParentFile.getParentFile / "shared/src/test" + + ((sharedTestDir / "require-sam") ** "*.scala").get ++ + (if (isJSTest) ((testDir / "require-sam") ** "*.scala").get else Nil) + } else { + Nil + } } - } ) def testHtmlSettings[T](testHtmlKey: TaskKey[T], targetStage: Stage) = Seq( @@ -1449,180 +1372,176 @@ object Build { }).value ) - lazy val testSuite: Project = Project( - id = "testSuite", - base = file("test-suite/js"), - settings = commonSettings ++ myScalaJSSettings ++ testTagSettings ++ - testSuiteCommonSettings(isJSTest = true) ++ - testHtmlSettings(testHtmlFastOpt, FastOptStage) ++ - testHtmlSettings(testHtmlFullOpt, FullOptStage) ++ Seq( - name := "Scala.js test suite", - - /* We still have zillions of run test for top-level @JSExport and for - * @JSName/missing @JSGlobal. Don't drown the test:compile output under - * useless warnings. - */ - scalacOptions in Test += "-P:scalajs:suppressExportDeprecations", - scalacOptions in Test += "-P:scalajs:suppressMissingJSGlobalDeprecations", + lazy val testSuite: Project = (project in file("test-suite/js")).settings( + commonSettings, + myScalaJSSettings, + testTagSettings, + testSuiteCommonSettings(isJSTest = true), + testHtmlSettings(testHtmlFastOpt, FastOptStage), + testHtmlSettings(testHtmlFullOpt, FullOptStage), + name := "Scala.js test suite", + + /* We still have zillions of run test for top-level @JSExport and for + * @JSName/missing @JSGlobal. Don't drown the test:compile output under + * useless warnings. + */ + scalacOptions in Test += "-P:scalajs:suppressExportDeprecations", + scalacOptions in Test += "-P:scalajs:suppressMissingJSGlobalDeprecations", - unmanagedSourceDirectories in Test ++= { - val testDir = (sourceDirectory in Test).value + unmanagedSourceDirectories in Test ++= { + val testDir = (sourceDirectory in Test).value - includeIf(testDir / "require-modules", - scalaJSModuleKind.value != ModuleKind.NoModule) - }, - - jsDependencies += ProvidedJS / "ScalaJSDefinedTestNatives.js" % "test", - skip in packageJSDependencies in Test := false, - - scalaJSSemantics ~= (_.withRuntimeClassName(_.fullName match { - case "org.scalajs.testsuite.compiler.ReflectionTest$RenamedTestClass" => - "renamed.test.Class" - case fullName => - fullName - })), - - javaOptions in Test += "-Dscalajs.scalaVersion=" + scalaVersion.value, - - /* Generate a scala source file that throws exceptions in - * various places (while attaching the source line to the - * exception). When we catch the exception, we can then - * compare the attached source line and the source line - * calculated via the source maps. - * - * see test-suite/src/test/resources/SourceMapTestTemplate.scala - */ - sourceGenerators in Test += Def.task { - val dir = (sourceManaged in Test).value - IO.createDirectory(dir) - - val template = IO.read((resourceDirectory in Test).value / - "SourceMapTestTemplate.scala") - - def lineNo(cs: CharSequence) = - (0 until cs.length).count(i => cs.charAt(i) == '\n') + 1 - - var i = 0 - val pat = "/\\*{2,3}/".r - val replaced = pat.replaceAllIn(template, { mat => - val lNo = lineNo(mat.before) - val res = - if (mat.end - mat.start == 5) - // matching a /***/ - s"if (TC.is($i)) { throw new TestException($lNo) } else " - else - // matching a /**/ - s"; if (TC.is($i)) { throw new TestException($lNo) } ;" - - i += 1 - - res - }) - - val outFile = dir / "SourceMapTest.scala" - val unitTests = - (0 until i).map(i => s"@Test def workTest$i(): Unit = test($i)").mkString("; ") - IO.write(outFile, - replaced.replace("@Test def workTest(): Unit = sys.error(\"stubs\")", unitTests)) - Seq(outFile) - }.taskValue, - - // Exclude tests based on version-dependent bugs - sources in Test := { - val sourceFiles = (sources in Test).value - val v = scalaVersion.value - - val hasBug2382 = v.startsWith("2.10.") || v.startsWith("2.11.") - val sourceFiles1 = { - if (hasBug2382) - sourceFiles.filterNot(_.getName == "OuterClassTest.scala") + includeIf(testDir / "require-modules", + scalaJSModuleKind.value != ModuleKind.NoModule) + }, + + jsDependencies += ProvidedJS / "ScalaJSDefinedTestNatives.js" % "test", + skip in packageJSDependencies in Test := false, + + scalaJSSemantics ~= (_.withRuntimeClassName(_.fullName match { + case "org.scalajs.testsuite.compiler.ReflectionTest$RenamedTestClass" => + "renamed.test.Class" + case fullName => + fullName + })), + + javaOptions in Test += "-Dscalajs.scalaVersion=" + scalaVersion.value, + + /* Generate a scala source file that throws exceptions in + * various places (while attaching the source line to the + * exception). When we catch the exception, we can then + * compare the attached source line and the source line + * calculated via the source maps. + * + * see test-suite/src/test/resources/SourceMapTestTemplate.scala + */ + sourceGenerators in Test += Def.task { + val dir = (sourceManaged in Test).value + IO.createDirectory(dir) + + val template = IO.read((resourceDirectory in Test).value / + "SourceMapTestTemplate.scala") + + def lineNo(cs: CharSequence) = + (0 until cs.length).count(i => cs.charAt(i) == '\n') + 1 + + var i = 0 + val pat = "/\\*{2,3}/".r + val replaced = pat.replaceAllIn(template, { mat => + val lNo = lineNo(mat.before) + val res = + if (mat.end - mat.start == 5) + // matching a /***/ + s"if (TC.is($i)) { throw new TestException($lNo) } else " else - sourceFiles - } + // matching a /**/ + s"; if (TC.is($i)) { throw new TestException($lNo) } ;" - sourceFiles1 - }, - - /* Reduce the amount of tests on PhantomJS to avoid a crash. - * It seems we reached the limits of what PhantomJS can handle in terms - * of code mass. Since PhantomJS support is due to be moved to a - * separate repository in 1.0.0, the easiest way to fix this is to - * reduce the pressure on PhantomJS. We therefore remove the tests of - * java.math (BigInteger and BigDecimal) when running with PhantomJS. - * These tests are well isolated, and the less likely to have - * environmental differences. - * - * Note that `jsEnv` is never set from this Build, but it is set via - * the command-line in the CI matrix. - */ - sources in Test := { - def isPhantomJS(env: JSEnv): Boolean = env match { - case _: PhantomJSEnv => true - case env: RetryingComJSEnv => isPhantomJS(env.baseEnv) - case _ => false - } + i += 1 - val sourceFiles = (sources in Test).value - if ((jsEnv in Test).?.value.exists(isPhantomJS)) { - sourceFiles.filter { f => - !f.getAbsolutePath - .replace('\\', '/') - .contains("/org/scalajs/testsuite/javalib/math/") - } - } else { + res + }) + + val outFile = dir / "SourceMapTest.scala" + val unitTests = + (0 until i).map(i => s"@Test def workTest$i(): Unit = test($i)").mkString("; ") + IO.write(outFile, + replaced.replace("@Test def workTest(): Unit = sys.error(\"stubs\")", unitTests)) + Seq(outFile) + }.taskValue, + + // Exclude tests based on version-dependent bugs + sources in Test := { + val sourceFiles = (sources in Test).value + val v = scalaVersion.value + + val hasBug2382 = v.startsWith("2.10.") || v.startsWith("2.11.") + val sourceFiles1 = { + if (hasBug2382) + sourceFiles.filterNot(_.getName == "OuterClassTest.scala") + else sourceFiles + } + + sourceFiles1 + }, + + /* Reduce the amount of tests on PhantomJS to avoid a crash. + * It seems we reached the limits of what PhantomJS can handle in terms + * of code mass. Since PhantomJS support is due to be moved to a + * separate repository in 1.0.0, the easiest way to fix this is to + * reduce the pressure on PhantomJS. We therefore remove the tests of + * java.math (BigInteger and BigDecimal) when running with PhantomJS. + * These tests are well isolated, and the less likely to have + * environmental differences. + * + * Note that `jsEnv` is never set from this Build, but it is set via + * the command-line in the CI matrix. + */ + sources in Test := { + def isPhantomJS(env: JSEnv): Boolean = env match { + case _: PhantomJSEnv => true + case env: RetryingComJSEnv => isPhantomJS(env.baseEnv) + case _ => false + } + + val sourceFiles = (sources in Test).value + if ((jsEnv in Test).?.value.exists(isPhantomJS)) { + sourceFiles.filter { f => + !f.getAbsolutePath + .replace('\\', '/') + .contains("/org/scalajs/testsuite/javalib/math/") } - }, - - // Module initializers. Duplicated in toolsJS/test - scalaJSModuleInitializers += { - ModuleInitializer.mainMethod( - "org.scalajs.testsuite.compiler.ModuleInitializerInNoConfiguration", - "main") - }, - scalaJSModuleInitializers in Compile += { - ModuleInitializer.mainMethod( - "org.scalajs.testsuite.compiler.ModuleInitializerInCompileConfiguration", - "main") - }, - scalaJSModuleInitializers in Test += { - ModuleInitializer.mainMethod( - "org.scalajs.testsuite.compiler.ModuleInitializerInTestConfiguration", - "main2") - }, - scalaJSModuleInitializers in Test += { - ModuleInitializer.mainMethod( - "org.scalajs.testsuite.compiler.ModuleInitializerInTestConfiguration", - "main1") + } else { + sourceFiles } - ) + }, + + // Module initializers. Duplicated in toolsJS/test + scalaJSModuleInitializers += { + ModuleInitializer.mainMethod( + "org.scalajs.testsuite.compiler.ModuleInitializerInNoConfiguration", + "main") + }, + scalaJSModuleInitializers in Compile += { + ModuleInitializer.mainMethod( + "org.scalajs.testsuite.compiler.ModuleInitializerInCompileConfiguration", + "main") + }, + scalaJSModuleInitializers in Test += { + ModuleInitializer.mainMethod( + "org.scalajs.testsuite.compiler.ModuleInitializerInTestConfiguration", + "main2") + }, + scalaJSModuleInitializers in Test += { + ModuleInitializer.mainMethod( + "org.scalajs.testsuite.compiler.ModuleInitializerInTestConfiguration", + "main1") + } ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( - library, jUnitRuntime + library, jUnitRuntime ) - 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" - ) ) - 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 - ) + lazy val noIrCheckTest: Project = (project in file("no-ir-check-test")).settings( + commonSettings, + myScalaJSSettings, + testTagSettings, + 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) /* Additional test suite, for tests that should not be part of the normal @@ -1635,156 +1554,147 @@ object Build { * test each file in this test suite, so that we're sure that do not * interfere with other. */ - lazy val testSuiteEx: Project = Project( - id = "testSuiteEx", - base = file("test-suite-ex"), - settings = ( - commonSettings ++ myScalaJSSettings ++ testTagSettings - ) ++ Seq( - name := "Scala.js test suite ex", - publishArtifact in Compile := false, - testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a", "-s"), - scalacOptions in Test ~= (_.filter(_ != "-deprecation")) - ) + lazy val testSuiteEx: Project = (project in file("test-suite-ex")).settings( + commonSettings, + myScalaJSSettings, + testTagSettings, + name := "Scala.js test suite ex", + publishArtifact in Compile := false, + testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a", "-s"), + scalacOptions in Test ~= (_.filter(_ != "-deprecation")) ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn(library, jUnitRuntime) - lazy val partest: Project = Project( - id = "partest", - base = file("partest"), - settings = commonSettings ++ fatalWarningsSettings ++ Seq( - name := "Partest for Scala.js", - moduleName := "scalajs-partest", + lazy val partest: Project = project.settings( + commonSettings, + fatalWarningsSettings, + name := "Partest for Scala.js", + moduleName := "scalajs-partest", - resolvers += Resolver.typesafeIvyRepo("releases"), + resolvers += Resolver.typesafeIvyRepo("releases"), - artifactPath in fetchScalaSource := - baseDirectory.value / "fetchedSources" / scalaVersion.value, + artifactPath in fetchScalaSource := + baseDirectory.value / "fetchedSources" / scalaVersion.value, - fetchScalaSource := { - import org.eclipse.jgit.api._ + fetchScalaSource := { + import org.eclipse.jgit.api._ - val s = streams.value - val ver = scalaVersion.value - val trgDir = (artifactPath in fetchScalaSource).value + val s = streams.value + val ver = scalaVersion.value + val trgDir = (artifactPath in fetchScalaSource).value - if (!trgDir.exists) { - s.log.info(s"Fetching Scala source version $ver") + if (!trgDir.exists) { + s.log.info(s"Fetching Scala source version $ver") - // Make parent dirs and stuff - IO.createDirectory(trgDir) + // Make parent dirs and stuff + IO.createDirectory(trgDir) - // Clone scala source code - new CloneCommand() - .setDirectory(trgDir) - .setURI("https://github.com/scala/scala.git") - .call() - } + // Clone scala source code + new CloneCommand() + .setDirectory(trgDir) + .setURI("https://github.com/scala/scala.git") + .call() + } - // Checkout proper ref. We do this anyway so we fail if - // something is wrong - val git = Git.open(trgDir) - s.log.info(s"Checking out Scala source version $ver") - git.checkout().setName(s"v$ver").call() + // Checkout proper ref. We do this anyway so we fail if + // something is wrong + val git = Git.open(trgDir) + s.log.info(s"Checking out Scala source version $ver") + git.checkout().setName(s"v$ver").call() - trgDir - }, + trgDir + }, - libraryDependencies ++= { - if (shouldPartest.value) - Seq( - "org.scala-sbt" % "sbt" % sbtVersion.value, - { - val v = scalaVersion.value - if (v == "2.11.0" || v == "2.11.1" || v == "2.11.2") - "org.scala-lang.modules" %% "scala-partest" % "1.0.13" - else if (v.startsWith("2.11.")) - "org.scala-lang.modules" %% "scala-partest" % "1.0.16" - else - "org.scala-lang.modules" %% "scala-partest" % "1.0.17" - }, - "org.scala-js" % "closure-compiler-java-6" % "v20160517", - "com.googlecode.json-simple" % "json-simple" % "1.1.1" exclude("junit", "junit") - ) - else Seq() - }, + libraryDependencies ++= { + if (shouldPartest.value) + Seq( + "org.scala-sbt" % "sbt" % sbtVersion.value, + { + val v = scalaVersion.value + if (v == "2.11.0" || v == "2.11.1" || v == "2.11.2") + "org.scala-lang.modules" %% "scala-partest" % "1.0.13" + else if (v.startsWith("2.11.")) + "org.scala-lang.modules" %% "scala-partest" % "1.0.16" + else + "org.scala-lang.modules" %% "scala-partest" % "1.0.17" + }, + "org.scala-js" % "closure-compiler-java-6" % "v20160517", + "com.googlecode.json-simple" % "json-simple" % "1.1.1" exclude("junit", "junit") + ) + else Seq() + }, - unmanagedSourceDirectories in Compile += { - val sourceRoot = (sourceDirectory in Compile).value.getParentFile - val v = scalaVersion.value - if (v == "2.11.0" || v == "2.11.1" || v == "2.11.2") - sourceRoot / "main-partest-1.0.13" - else - sourceRoot / "main-partest-1.0.16" - }, + unmanagedSourceDirectories in Compile += { + val sourceRoot = (sourceDirectory in Compile).value.getParentFile + val v = scalaVersion.value + if (v == "2.11.0" || v == "2.11.1" || v == "2.11.2") + sourceRoot / "main-partest-1.0.13" + else + sourceRoot / "main-partest-1.0.16" + }, - sources in Compile := { - if (shouldPartest.value) { - // Partest sources and some sources of sbtplugin (see above) - val baseSrcs = (sources in Compile).value - // Sources for tools (and hence IR) - val toolSrcs = (sources in (tools, Compile)).value - // Sources for js-envs - val jsenvSrcs = { - val jsenvBase = ((scalaSource in (jsEnvs, Compile)).value / - "org/scalajs/jsenv") - - val scalaFilter: FileFilter = "*.scala" - val files = ( - (jsenvBase * scalaFilter) +++ - (jsenvBase / "nodejs" ** scalaFilter)) - - files.get - } - toolSrcs ++ baseSrcs ++ jsenvSrcs - } else Seq() + sources in Compile := { + if (shouldPartest.value) { + // Partest sources and some sources of sbtplugin (see above) + val baseSrcs = (sources in Compile).value + // Sources for tools (and hence IR) + val toolSrcs = (sources in (tools, Compile)).value + // Sources for js-envs + val jsenvSrcs = { + val jsenvBase = ((scalaSource in (jsEnvs, Compile)).value / + "org/scalajs/jsenv") + + val scalaFilter: FileFilter = "*.scala" + val files = ( + (jsenvBase * scalaFilter) +++ + (jsenvBase / "nodejs" ** scalaFilter)) + + files.get } - - ) + toolSrcs ++ baseSrcs ++ jsenvSrcs + } else Seq() + } ).dependsOn(compiler) - lazy val partestSuite: Project = Project( - id = "partestSuite", - base = file("partest-suite"), - settings = commonSettings ++ fatalWarningsSettings ++ Seq( - name := "Scala.js partest suite", + lazy val partestSuite: Project = (project in file("partest-suite")).settings( + commonSettings, + fatalWarningsSettings, + name := "Scala.js partest suite", - fork in Test := true, - javaOptions in Test += "-Xmx1G", + fork in Test := true, + javaOptions in Test += "-Xmx1G", - // Override the dependency of partest - see #1889 - dependencyOverrides += "org.scala-lang" % "scala-library" % scalaVersion.value % "test", + // Override the dependency of partest - see #1889 + dependencyOverrides += "org.scala-lang" % "scala-library" % scalaVersion.value % "test", - testFrameworks ++= { - if (shouldPartest.value) - Seq(new TestFramework("scala.tools.partest.scalajs.Framework")) - else Seq() - }, + testFrameworks ++= { + if (shouldPartest.value) + Seq(new TestFramework("scala.tools.partest.scalajs.Framework")) + else Seq() + }, - definedTests in Test ++= Def.taskDyn[Seq[sbt.TestDefinition]] { - if (shouldPartest.value) Def.task { - val _ = (fetchScalaSource in partest).value - Seq(new sbt.TestDefinition( - s"partest-${scalaVersion.value}", - // marker fingerprint since there are no test classes - // to be discovered by sbt: - new sbt.testing.AnnotatedFingerprint { - def isModule = true - def annotationName = "partest" - }, - true, - Array() - )) - } else { - Def.task(Seq()) - } - }.value - ) + definedTests in Test ++= Def.taskDyn[Seq[sbt.TestDefinition]] { + if (shouldPartest.value) Def.task { + val _ = (fetchScalaSource in partest).value + Seq(new sbt.TestDefinition( + s"partest-${scalaVersion.value}", + // marker fingerprint since there are no test classes + // to be discovered by sbt: + new sbt.testing.AnnotatedFingerprint { + def isModule = true + def annotationName = "partest" + }, + true, + Array() + )) + } else { + Def.task(Seq()) + } + }.value ).dependsOn(partest % "test", library) - lazy val scalaTestSuite: Project = Project( - id = "scalaTestSuite", - base = file("scala-test-suite"), - settings = commonSettings ++ myScalaJSSettings ++ Seq( + lazy val scalaTestSuite: Project = (project in file("scala-test-suite")).settings( + commonSettings, + myScalaJSSettings, publishArtifact in Compile := false, testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a", "-s"), @@ -1856,7 +1766,6 @@ object Build { case fTup if whitelist(fTup._1) => fTup._2 } } - ) ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn(jUnitRuntime) } From 146232abc4ee32142510e5e81a79a51ebba08399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 5 Apr 2017 13:30:23 +0200 Subject: [PATCH 0191/2665] Do not use jsDependencies (nor jQuery) in testingExample. This turns testingExample into a test for DOM support only, independent of `jsDependencies`. --- examples/testing/src/main/scala/ElementCreator.scala | 8 +++++--- .../testing/src/test/scala/DOMExistanceTest.scala | 12 ------------ .../testing/src/test/scala/ElementCreatorTest.scala | 10 +++------- project/Build.scala | 6 +----- 4 files changed, 9 insertions(+), 27 deletions(-) diff --git a/examples/testing/src/main/scala/ElementCreator.scala b/examples/testing/src/main/scala/ElementCreator.scala index 9d0d58d833..22cf43c752 100644 --- a/examples/testing/src/main/scala/ElementCreator.scala +++ b/examples/testing/src/main/scala/ElementCreator.scala @@ -2,7 +2,9 @@ import scala.scalajs.js import js.Dynamic.global object ElementCreator { - val jQ = global.jQuery - - def create(): js.Dynamic = jQ("body").append(jQ("

Test

")) + def create(): Unit = { + val h1 = global.document.createElement("h1") + h1.innerHTML = "Test" + global.document.body.appendChild(h1) + } } diff --git a/examples/testing/src/test/scala/DOMExistanceTest.scala b/examples/testing/src/test/scala/DOMExistanceTest.scala index 531fd5850d..b77381b341 100644 --- a/examples/testing/src/test/scala/DOMExistanceTest.scala +++ b/examples/testing/src/test/scala/DOMExistanceTest.scala @@ -21,16 +21,4 @@ class DOMExistenceTest { def should_initialize_windod(): Unit = { assertFalse(js.isUndefined(global.window)) } - - @Test - def should_initialize_jQuery(): Unit = { - assertFalse(js.isUndefined(global.jQuery)) - assertFalse(js.isUndefined(global.window.jQuery)) - } - - @Test - def should_initialize_dollar(): Unit = { - assertFalse(js.isUndefined(global.$)) - assertFalse(js.isUndefined(global.window.$)) - } } diff --git a/examples/testing/src/test/scala/ElementCreatorTest.scala b/examples/testing/src/test/scala/ElementCreatorTest.scala index 4adda4b7d5..2033b18d85 100644 --- a/examples/testing/src/test/scala/ElementCreatorTest.scala +++ b/examples/testing/src/test/scala/ElementCreatorTest.scala @@ -8,15 +8,11 @@ class ElementCreatorTest { @Test def element_creator_create_an_element_in_body(): Unit = { - // create the element + // Create the element ElementCreator.create() - // jquery would make this easier, but I wanted to - // only use pure html in the test itself - val body = global.document.getElementsByTagName("body") - .asInstanceOf[js.Array[js.Dynamic]].head - - // the Scala.js DOM API would make this easier + // Test that it was correctly created + val body = global.document.body assertEquals("H1", body.lastChild.tagName.toString) assertEquals("Test", body.lastChild.innerHTML.toString) } diff --git a/project/Build.scala b/project/Build.scala index 7d0e5cc182..ad11e30c79 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1195,11 +1195,7 @@ object Build { exampleSettings, name := "Testing - Scala.js example", moduleName := "testing", - - jsDependencies ++= Seq( - RuntimeDOM % "test", - "org.webjars" % "jquery" % "1.10.2" / "jquery.js" % "test" - ) + jsEnv := new JSDOMNodeJSEnv() ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( library, jUnitRuntime % "test" ) From 5971239b845bd64062addb8c0f36fa59009f1d71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 5 Apr 2017 14:54:05 +0200 Subject: [PATCH 0192/2665] Do not use jsDependencies (nor jQuery) in sbt-plugin-test/withDOM. This turns withDOM into a test for DOM support only, independent of `jsDependencies`. --- sbt-plugin-test/build.sbt | 5 ++--- .../withDOM/src/main/scala/sbttest/withDOM/Lib.scala | 11 +---------- .../src/main/scala/sbttest/withDOM/TestApp.scala | 2 +- .../src/test/scala/sbttest/withDOM/LibTest.scala | 7 ++----- 4 files changed, 6 insertions(+), 19 deletions(-) diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index cbd595b88e..837e665ebe 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -1,4 +1,5 @@ import org.scalajs.core.tools.jsdep.ManifestFilters +import org.scalajs.jsenv.nodejs.JSDOMNodeJSEnv name := "Scala.js sbt test" @@ -61,9 +62,7 @@ lazy val withDOM = project.settings(baseSettings: _*). enablePlugins(ScalaJSJUnitPlugin). settings( name := "Scala.js sbt test w/ DOM", - jsDependencies ++= Seq( - RuntimeDOM, - "org.webjars" % "jquery" % "1.10.2" / "jquery.js"), + jsEnv := new JSDOMNodeJSEnv(), scalaJSOutputWrapper := ( "// Scala.js - withDOM sbt test\n//\n// Compiled with Scala.js\n", "// End of Scala.js generated script") diff --git a/sbt-plugin-test/withDOM/src/main/scala/sbttest/withDOM/Lib.scala b/sbt-plugin-test/withDOM/src/main/scala/sbttest/withDOM/Lib.scala index e43155721b..4c22036338 100644 --- a/sbt-plugin-test/withDOM/src/main/scala/sbttest/withDOM/Lib.scala +++ b/sbt-plugin-test/withDOM/src/main/scala/sbttest/withDOM/Lib.scala @@ -5,24 +5,15 @@ import scala.scalajs.js object Lib { val document: js.Dynamic = js.Dynamic.global.document - val jQuery: js.Dynamic = js.Dynamic.global.jQuery def getElementsByTagName(name: String): js.Array[js.Dynamic] = document.getElementsByTagName(name).asInstanceOf[js.Array[js.Dynamic]] /** appends a

with the message to the document */ def appendDocument(msg: String): Unit = { - val trg = { - val bodies = getElementsByTagName("body") - if (bodies.length > 0) - bodies(0) - else - document - } - val elem = document.createElement("p") elem.appendChild(document.createTextNode(msg)) - trg.appendChild(elem) + document.body.appendChild(elem) } } diff --git a/sbt-plugin-test/withDOM/src/main/scala/sbttest/withDOM/TestApp.scala b/sbt-plugin-test/withDOM/src/main/scala/sbttest/withDOM/TestApp.scala index e61ed20a17..f614bc6f60 100644 --- a/sbt-plugin-test/withDOM/src/main/scala/sbttest/withDOM/TestApp.scala +++ b/sbt-plugin-test/withDOM/src/main/scala/sbttest/withDOM/TestApp.scala @@ -8,7 +8,7 @@ object TestApp extends js.JSApp { Lib.appendDocument("Hello World") Lib.appendDocument("Still Here!") - println(Lib.jQuery("p").text()) + println(Lib.getElementsByTagName("p").head.innerHTML) } } diff --git a/sbt-plugin-test/withDOM/src/test/scala/sbttest/withDOM/LibTest.scala b/sbt-plugin-test/withDOM/src/test/scala/sbttest/withDOM/LibTest.scala index d8b11d0939..174ec87af2 100644 --- a/sbt-plugin-test/withDOM/src/test/scala/sbttest/withDOM/LibTest.scala +++ b/sbt-plugin-test/withDOM/src/test/scala/sbttest/withDOM/LibTest.scala @@ -6,12 +6,9 @@ import org.junit.Test import org.junit.Assert._ class LibTest { - @Test def dummy_library_should_provide_jQuery(): Unit = { - assertFalse(js.isUndefined(Lib.jQuery)) - } - @Test def dummy_library_should_append_an_element(): Unit = { - def count = Lib.jQuery("p").length.asInstanceOf[Int] + def count = Lib.getElementsByTagName("p").length + val oldCount = count Lib.appendDocument("foo") assertEquals(1, count - oldCount) From 45203508e4406ba7d8d8aa9871536e2413027b5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 5 Apr 2017 15:09:06 +0200 Subject: [PATCH 0193/2665] Do not automatically select JSDOMNodeJSEnv if requiresDOM is true. This removes the interaction between `jsDependencies` on the one hand, and `JSDOMNodeJSEnv` on the other hand. This will be required so that we can move those two segments of the sbt plugin in separate repositories and sbt plugins (#2841, #2842). Note that this makes `requiresDOM`, and therefore `jsDependencies += RuntimeDOM`, completely useless; they do not have any effect anymore. They should probably be deprecated/stubbed out in the `jsDependencies` plugin. --- ci/matrix.xml | 8 ++++---- .../org/scalajs/sbtplugin/ScalaJSPluginInternal.scala | 9 ++------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/ci/matrix.xml b/ci/matrix.xml index 6c14406db2..d51e6c8e77 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -19,9 +19,9 @@ sbtretry 'set scalaJSStage in Global := FullOptStage' \ ++$scala helloworld/run \ helloworld/clean && - sbtretry 'set requiresDOM in helloworld := true' \ + sbtretry 'set jsEnv in helloworld := new org.scalajs.jsenv.nodejs.NodeJSEnv' \ ++$scala helloworld/run && - sbtretry 'set requiresDOM in helloworld := true' \ + sbtretry 'set jsEnv in helloworld := new org.scalajs.jsenv.nodejs.NodeJSEnv' \ 'set scalaJSStage in Global := FullOptStage' \ ++$scala helloworld/run \ helloworld/clean && @@ -84,9 +84,9 @@ sbtretry 'set scalaJSStage in Global := FullOptStage' \ ++$scala $testSuite/test \ $testSuite/clean && - sbtretry 'set requiresDOM in $testSuite := true' \ + sbtretry 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv' \ ++$scala $testSuite/test && - sbtretry 'set requiresDOM in $testSuite := true' \ + sbtretry 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv' \ 'set scalaJSStage in Global := FullOptStage' \ ++$scala $testSuite/test \ $testSuite/clean && diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 1b7feabaf9..5019d43a11 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -21,6 +21,7 @@ import org.scalajs.core.tools.linker.frontend.LinkerFrontend import org.scalajs.core.tools.linker.backend.{LinkerBackend, ModuleKind, OutputMode} import org.scalajs.jsenv._ +import org.scalajs.jsenv.nodejs.NodeJSEnv import org.scalajs.core.ir import org.scalajs.core.ir.Utils.escapeJS @@ -599,13 +600,7 @@ object ScalaJSPluginInternal { jsDependencyManifests.value.data.exists(_.requiresDOM)) }, - resolvedJSEnv := jsEnv.?.value.getOrElse { - if (scalaJSRequestsDOM.value) { - JSDOMNodeJSEnv().value - } else { - NodeJSEnv().value - } - }, + resolvedJSEnv := jsEnv.?.value.getOrElse(new NodeJSEnv()), scalaJSJavaSystemProperties ++= { val javaSysPropsPattern = "-D([^=]*)=(.*)".r From e193f5df8e9b75cd5db931eafe4ba5ea3c4e6734 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Thu, 6 Apr 2017 20:15:36 +0200 Subject: [PATCH 0194/2665] Fix #2864: Optimizer performance regression. This essentially reverts commit ec3c3bd685ff32f9fbbe4e19db085cb651babf8c modulo: - The build file changes to include the par-collections. - An additional import to get `.toParArray` back. Performance on testSuite/test:fastOptJS on MacBook Air, 2.2 GHz Intel Core i7, 8 GB 1600 MHz DDR3 tl;dr: optimizer is 10x faster after the revert. Before: Linker: Check Infos: 5253899 us Linker: Compute reachability: 2527607 us Linker: Assemble LinkedClasses: 429050 us Linker: Check IR: 2320856 us Basic Linking: 10591499 us Inc. optimizer: Batch mode: true Inc. optimizer: Incremental part: 39471999 us Inc. optimizer: Optimizing 35061 methods. Inc. optimizer: Optimizer part: 348688137 us Inc. optimizer: 388289830 us Refiner: Compute reachability: 382626 us Refiner: Assemble LinkedClasses: 82460 us Refiner: 476345 us Emitter: Class tree cache stats: reused: 2785 -- invalidated: 2975 Emitter: Method tree cache stats: resued: 0 -- invalidated: 24570 Emitter (write output): 6734101 us Global IR cache stats: reused: 159 -- invalidated: 2187 -- trees read: 5747 After: Linker: Check Infos: 5480910 us Linker: Compute reachability: 3199914 us Linker: Assemble LinkedClasses: 529704 us Linker: Check IR: 2257044 us Basic Linking: 11544069 us Inc. optimizer: Batch mode: true Inc. optimizer: Incremental part: 746521 us Inc. optimizer: Optimizing 35061 methods. Inc. optimizer: Optimizer part: 37023884 us Inc. optimizer: 37889433 us Refiner: Compute reachability: 380839 us Refiner: Assemble LinkedClasses: 68282 us Refiner: 463019 us Emitter: Class tree cache stats: reused: 2785 -- invalidated: 2975 Emitter: Method tree cache stats: resued: 0 -- invalidated: 24570 Emitter (write output): 11078321 us Global IR cache stats: reused: 0 -- invalidated: 2346 -- trees read: 5747 --- project/BinaryIncompatibilities.scala | 13 ------------- .../frontend/optimizer/ConcurrencyUtils.scala | 15 +++++++-------- .../frontend/optimizer/ParIncOptimizer.scala | 18 +++++++++--------- 3 files changed, 16 insertions(+), 30 deletions(-) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index dafb831e1d..c77318b933 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -6,19 +6,6 @@ object BinaryIncompatibilities { ) val Tools = Seq( - // private[optimizer], not an issue - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.tools.linker.frontend.optimizer.ConcurrencyUtils#AtomicAcc.apply"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.core.tools.linker.frontend.optimizer.ConcurrencyUtils#AtomicAccOps.removeAll$extension"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.core.tools.linker.frontend.optimizer.ConcurrencyUtils#AtomicAccOps.removeAll"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.tools.linker.frontend.optimizer.ParIncOptimizer#CollOps.prepAdd"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.core.tools.linker.frontend.optimizer.ParIncOptimizer#CollOps.finishAdd"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.core.tools.linker.frontend.optimizer.ParIncOptimizer#CollOps.emptyParIterable") ) val JSEnvs = Seq( diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ConcurrencyUtils.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ConcurrencyUtils.scala index 145f1e9143..c76941e04f 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ConcurrencyUtils.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ConcurrencyUtils.scala @@ -12,7 +12,6 @@ package org.scalajs.core.tools.linker.frontend.optimizer import scala.annotation.tailrec import scala.collection.concurrent.TrieMap -import scala.collection.parallel.immutable.ParVector import java.util.concurrent.atomic._ @@ -20,12 +19,12 @@ private[optimizer] object ConcurrencyUtils { /** An atomic accumulator supports adding single elements and retrieving and * deleting all contained elements */ - type AtomicAcc[T] = AtomicReference[ParVector[T]] + type AtomicAcc[T] = AtomicReference[List[T]] object AtomicAcc { @inline final def empty[T]: AtomicAcc[T] = - new AtomicReference(ParVector.empty[T]) - @inline final def apply[T](l: ParVector[T]): AtomicAcc[T] = + new AtomicReference[List[T]](Nil) + @inline final def apply[T](l: List[T]): AtomicAcc[T] = new AtomicReference(l) } @@ -36,7 +35,7 @@ private[optimizer] object ConcurrencyUtils { final def +=(x: T): Unit = AtomicAccOps.append(acc, x) @inline - final def removeAll(): ParVector[T] = AtomicAccOps.removeAll(acc) + final def removeAll(): List[T] = AtomicAccOps.removeAll(acc) } object AtomicAccOps { @@ -44,13 +43,13 @@ private[optimizer] object ConcurrencyUtils { @tailrec private final def append[T](acc: AtomicAcc[T], x: T): Boolean = { val oldV = acc.get - val newV = oldV :+ x + val newV = x :: oldV acc.compareAndSet(oldV, newV) || append(acc, x) } @inline - private final def removeAll[T](acc: AtomicAcc[T]): ParVector[T] = - acc.getAndSet(ParVector.empty) + private final def removeAll[T](acc: AtomicAcc[T]): List[T] = + acc.getAndSet(Nil) } type TrieSet[T] = TrieMap[T, Null] diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ParIncOptimizer.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ParIncOptimizer.scala index ef8205c8fc..89ed78b597 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ParIncOptimizer.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ParIncOptimizer.scala @@ -11,8 +11,8 @@ package org.scalajs.core.tools.linker.frontend.optimizer import scala.collection.{GenTraversableOnce, GenIterable} import scala.collection.concurrent.TrieMap -import scala.collection.parallel.mutable.ParTrieMap -import scala.collection.parallel.immutable.ParVector +import scala.collection.parallel.mutable.{ParTrieMap, ParArray} +import scala.collection.parallel._ import java.util.concurrent.atomic._ @@ -29,13 +29,13 @@ final class ParIncOptimizer(semantics: Semantics, esLevel: ESLevel, type Map[K, V] = TrieMap[K, V] type ParMap[K, V] = ParTrieMap[K, V] type AccMap[K, V] = TrieMap[K, AtomicAcc[V]] - type ParIterable[V] = ParVector[V] + type ParIterable[V] = ParArray[V] type Addable[V] = AtomicAcc[V] def emptyAccMap[K, V]: AccMap[K, V] = TrieMap.empty def emptyMap[K, V]: Map[K, V] = TrieMap.empty def emptyParMap[K, V]: ParMap[K, V] = ParTrieMap.empty - def emptyParIterable[V]: ParIterable[V] = ParVector.empty + def emptyParIterable[V]: ParIterable[V] = ParArray.empty // Operations on ParMap def put[K, V](map: ParMap[K, V], k: K, v: V): Unit = map.put(k, v) @@ -53,21 +53,21 @@ final class ParIncOptimizer(semantics: Semantics, esLevel: ESLevel, map.getOrPut(k, AtomicAcc.empty) += v def getAcc[K, V](map: AccMap[K, V], k: K): GenIterable[V] = - map.get(k).fold[ParVector[V]](ParVector.empty)(_.removeAll()) + map.get(k).fold[Iterable[V]](Nil)(_.removeAll()).toParArray def parFlatMapKeys[A, B](map: AccMap[A, _])( f: A => GenTraversableOnce[B]): GenIterable[B] = - new ParVector(map.keys.flatMap(f).toVector) + map.keys.flatMap(f).toParArray // Operations on ParIterable def prepAdd[V](it: ParIterable[V]): Addable[V] = - AtomicAcc(it) + AtomicAcc(it.toList) def add[V](addable: Addable[V], v: V): Unit = addable += v def finishAdd[V](addable: Addable[V]): ParIterable[V] = - addable.removeAll() + addable.removeAll().toParArray } private val _interfaces = TrieMap.empty[String, InterfaceType] @@ -82,7 +82,7 @@ final class ParIncOptimizer(semantics: Semantics, esLevel: ESLevel, encodedName: String): MethodImpl = new ParMethodImpl(owner, encodedName) private[optimizer] def processAllTaggedMethods(): Unit = { - val methods = methodsToProcess.removeAll() + val methods = methodsToProcess.removeAll().toParArray logProcessingMethods(methods.count(!_.deleted)) for (method <- methods) method.process() From 2ceb620ae9b5132b82de20462b3ec2dc3ddd897e Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 2 Apr 2017 19:48:34 +0200 Subject: [PATCH 0195/2665] Fix #2836: Disallow @JSName as loading spec. As a side effect, this enforces having a loading spec for JS native classes. --- .../scalajs/core/compiler/PrepJSInterop.scala | 125 +++-------- .../core/compiler/ScalaJSOptions.scala | 3 - .../scalajs/core/compiler/ScalaJSPlugin.scala | 3 - .../core/compiler/test/JSInteropTest.scala | 208 +++++++++--------- ...ngJSGlobalDeprecationsSuppressedTest.scala | 88 -------- .../MissingJSGlobalDeprecationsTest.scala | 132 ----------- project/Build.scala | 1 - .../compiler/InteroperabilityTest.scala | 124 ----------- .../jsinterop/JSNativeInPackage.scala | 61 +---- 9 files changed, 145 insertions(+), 600 deletions(-) delete mode 100644 compiler/src/test/scala/org/scalajs/core/compiler/test/MissingJSGlobalDeprecationsSuppressedTest.scala delete mode 100644 compiler/src/test/scala/org/scalajs/core/compiler/test/MissingJSGlobalDeprecationsTest.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index fa4cfc0ebc..d85d13c327 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -571,13 +571,13 @@ abstract class PrepJSInterop extends plugins.PluginComponent sym.addAnnotation(HasJSNativeLoadSpecAnnotation) } else { assert(sym.isTrait) // just tested in the previous `if` - for { - annot <- sym.annotations - annotSym = annot.symbol - if JSNativeLoadingSpecAnnots.contains(annotSym) - } { - reporter.error(annot.pos, - s"Traits may not have an @${annotSym.nameString} annotation.") + for (annot <- sym.annotations) { + val annotSym = annot.symbol + if (JSNativeLoadingSpecAnnots.contains(annotSym) || + annotSym == JSNameAnnotation) { + reporter.error(annot.pos, + s"Traits may not have an @${annotSym.nameString} annotation.") + } } } } @@ -672,16 +672,15 @@ abstract class PrepJSInterop extends plugins.PluginComponent private def checkAndComputeJSNativeLoadSpecOf(pos: Position, sym: Symbol): JSNativeLoadSpec = { if (enclosingOwner is OwnerKind.JSNativeMod) { - for { - annot <- sym.annotations - annotSym = annot.symbol - if JSNativeLoadingSpecAnnots.contains(annotSym) - } { - if (annotSym != JSNameAnnotation) { + for (annot <- sym.annotations) { + val annotSym = annot.symbol + + if (JSNativeLoadingSpecAnnots.contains(annotSym)) { reporter.error(annot.pos, "Classes and objects nested in a JS native object cannot " + s"have an @${annotSym.nameString} annotation.") - } else if (annot.args.head.tpe.typeSymbol != StringClass) { + } else if (annotSym == JSNameAnnotation && + annot.args.head.tpe.typeSymbol != StringClass) { reporter.error(annot.pos, "Implementation restriction: @JSName with a js.Symbol is not " + "supported on nested native classes and objects") @@ -704,23 +703,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent def parsePath(pathName: String): List[String] = pathName.split('.').toList - def needsExplicitJSName = { - (enclosingOwner is OwnerKind.ScalaMod) && - !sym.owner.isPackageObjectClass - } - - def globalFromName = { - val path = jsInterop.jsNameOf(sym) match { - case JSName.Literal(pathName) => - parsePath(pathName) - case JSName.Computed(_) => - // this happens in erroneous cases that report a compile error - List("") - } - JSNativeLoadSpec.Global(path) - } - - checkAndGetJSNativeLoadingSpecAnnotOf(sym) match { + checkAndGetJSNativeLoadingSpecAnnotOf(pos, sym) match { case Some(annot) if annot.symbol == JSGlobalScopeAnnotation => if (!sym.isModuleClass) { reporter.error(annot.pos, @@ -730,6 +713,11 @@ abstract class PrepJSInterop extends plugins.PluginComponent case Some(annot) if annot.symbol == JSGlobalAnnotation => val pathName = annot.stringArg(0).getOrElse { + val needsExplicitJSName = { + (enclosingOwner is OwnerKind.ScalaMod) && + !sym.owner.isPackageObjectClass + } + if (needsExplicitJSName) { reporter.error(annot.pos, "Native JS classes and objects inside non-native objects " + @@ -746,45 +734,9 @@ abstract class PrepJSInterop extends plugins.PluginComponent val path = annot.stringArg(1).fold[List[String]](Nil)(parsePath) JSNativeLoadSpec.Import(module, path) - case Some(annot) if annot.symbol == JSNameAnnotation => - if (!scalaJSOpts.suppressMissingJSGlobalDeprecations) { - reporter.warning(annot.pos, - "@JSName on top-level native JS classes and objects " + - "(or native JS classes and objects inside Scala objects) " + - "is deprecated, and should be replaced by @JSGlobal (with " + - "the same meaning). This will be enforced in 1.0." + - SuppressMissingJSGlobalDeprecationsMsg) - } - - globalFromName - case None => - if (needsExplicitJSName) { - if (sym.isModuleClass) { - reporter.error(pos, - "Native JS objects inside non-native objects must " + - "have an @JSGlobal or @JSImport annotation") - } else { - // This should be an error, but we erroneously allowed that before - reporter.warning(pos, - "Native JS classes inside non-native objects should " + - "have an @JSGlobal or @JSImport annotation. " + - "This will be enforced in 1.0.") - } - } else { - if (!scalaJSOpts.suppressMissingJSGlobalDeprecations && - !sym.isPackageObjectClass) { - reporter.warning(pos, - "Top-level native JS classes and objects should have an " + - "@JSGlobal or @JSImport annotation. This will be " + - "enforced in 1.0.\n" + - " If migrating from 0.6.14 or earlier, the equivalent " + - "behavior is an @JSGlobal without parameter." + - SuppressMissingJSGlobalDeprecationsMsg) - } - } - - globalFromName + // We already emitted an error. Just propagate something. + JSNativeLoadSpec.Global(Nil) } } } @@ -1340,40 +1292,35 @@ abstract class PrepJSInterop extends plugins.PluginComponent } private def checkAndGetJSNativeLoadingSpecAnnotOf( - sym: Symbol): Option[Annotation] = { + pos: Position, sym: Symbol): Option[Annotation] = { + for (annot <- sym.getAnnotation(JSNameAnnotation)) { + reporter.error(annot.pos, "@JSName annotations are not allowed on top " + + "level classes or objects (or classes and objects inside Scala objects).") + } + val annots = sym.annotations.filter { annot => JSNativeLoadingSpecAnnots.contains(annot.symbol) } + val badAnnotCountMsg = + "Native JS classes and objects must have exactly one " + + "annotation among @JSGlobal, @JSImport and @JSGlobalScope." + annots match { case Nil => + reporter.error(pos, badAnnotCountMsg) None case result :: duplicates => - val actualResult = { - if (result.args.headOption.forall(_.tpe.typeSymbol == StringClass)) { - Some(result) - } else { - reporter.error(result.pos, - "@JSName with a js.Symbol can only be used on members of " + - "JavaScript types") - None - } - } - - for (annot <- duplicates) { - reporter.error(annot.pos, - "Native JS classes and objects can only have one annotation " + - "among JSName, JSGlobal, JSImport and JSGlobalScope.") - } + for (annot <- duplicates) + reporter.error(annot.pos, badAnnotCountMsg) - actualResult + Some(result) } } private lazy val JSNativeLoadingSpecAnnots: Set[Symbol] = { - Set(JSNameAnnotation, JSGlobalAnnotation, JSImportAnnotation, - JSGlobalScopeAnnotation) + Set(JSGlobalAnnotation, JSImportAnnotation, JSGlobalScopeAnnotation) } private lazy val ScalaEnumClass = getRequiredClass("scala.Enumeration") diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala index 2008d5f26b..b56305fb97 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala @@ -22,9 +22,6 @@ trait ScalaJSOptions { /** Should we suppress deprecations of exports coming from 0.6.15? */ def suppressExportDeprecations: Boolean - /** Should we suppress deprecations related to missing `@JSGlobal`? */ - def suppressMissingJSGlobalDeprecations: Boolean - /** which source locations in source maps should be relativized (or where * should they be mapped to)? */ def sourceURIMaps: List[URIMap] diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala index d49db4c23d..57b39e4045 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala @@ -45,7 +45,6 @@ class ScalaJSPlugin(val global: Global) extends NscPlugin { import ScalaJSOptions.URIMap var fixClassOf: Boolean = false var suppressExportDeprecations: Boolean = false - var suppressMissingJSGlobalDeprecations: Boolean = false lazy val sourceURIMaps: List[URIMap] = { if (_sourceURIMaps.nonEmpty) _sourceURIMaps.reverse @@ -116,8 +115,6 @@ class ScalaJSPlugin(val global: Global) extends NscPlugin { } } else if (option == "suppressExportDeprecations") { suppressExportDeprecations = true - } else if (option == "suppressMissingJSGlobalDeprecations") { - suppressMissingJSGlobalDeprecations = true // The following options are deprecated (how do we show this to the user?) } else if (option.startsWith("relSourceMap:")) { val uriStr = option.stripPrefix("relSourceMap:") diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index 285e5a768d..9a0f98362e 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -16,7 +16,6 @@ class JSInteropTest extends DirectTest with TestHelpers { """ private val JSNativeLoadSpecAnnots = Seq( - "JSName" -> "@JSName(\"foo\")", "JSGlobal" -> "@JSGlobal", "JSGlobal" -> "@JSGlobal(\"foo\")", "JSImport" -> "@JSImport(\"foo\", \"bar\")", @@ -225,6 +224,49 @@ class JSInteropTest extends DirectTest with TestHelpers { """ } + @Test + def noJSNameAnnotOnClass: Unit = { + """ + @js.native + @JSName("Foo") + class A extends js.Object + + @js.native + @JSName("Foo") + abstract class B extends js.Object + """ hasErrors + """ + |newSource1.scala:6: error: @JSName annotations are not allowed on top level classes or objects (or classes and objects inside Scala objects). + | @JSName("Foo") + | ^ + |newSource1.scala:7: error: Native JS classes and objects must have exactly one annotation among @JSGlobal, @JSImport and @JSGlobalScope. + | class A extends js.Object + | ^ + |newSource1.scala:10: error: @JSName annotations are not allowed on top level classes or objects (or classes and objects inside Scala objects). + | @JSName("Foo") + | ^ + |newSource1.scala:11: error: Native JS classes and objects must have exactly one annotation among @JSGlobal, @JSImport and @JSGlobalScope. + | abstract class B extends js.Object + | ^ + """ + } + + @Test + def noJSNameAnnotOnObject: Unit = { + """ + @js.native + @JSName("Foo") + object A extends js.Object + """ hasErrors + """ + |newSource1.scala:6: error: @JSName annotations are not allowed on top level classes or objects (or classes and objects inside Scala objects). + | @JSName("Foo") + | ^ + |newSource1.scala:7: error: Native JS classes and objects must have exactly one annotation among @JSGlobal, @JSImport and @JSGlobalScope. + | object A extends js.Object + | ^ + """ + } @Test def noJSNameAnnotOnTrait: Unit = { @@ -301,27 +343,6 @@ class JSInteropTest extends DirectTest with TestHelpers { (firstAnnotName, firstAnnot) <- JSNativeLoadSpecAnnots (secondAnnotName, secondAnnot) <- JSNativeLoadSpecAnnots } { - val expectedMessage = { - s""" - |newSource1.scala:7: error: Native JS classes and objects can only have one annotation among JSName, JSGlobal, JSImport and JSGlobalScope. - |$secondAnnot - | ^ - """ - } - - val jsNameWarning = if (firstAnnotName == "JSName") { - s""" - |newSource1.scala:6: warning: @JSName on top-level native JS classes and objects (or native JS classes and objects inside Scala objects) is deprecated, and should be replaced by @JSGlobal (with the same meaning). This will be enforced in 1.0. - | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) - |$firstAnnot - | ^ - """.trim - } else { - "" - } - - val fullExpectedMessage = expectedMessage + jsNameWarning - val kinds = { if (firstAnnotName == "JSGlobalScope" || secondAnnotName == "JSGlobalScope") Seq("object") @@ -339,7 +360,11 @@ class JSInteropTest extends DirectTest with TestHelpers { """.stripMargin } - snippet hasErrors fullExpectedMessage + snippet hasErrors s""" + |newSource1.scala:7: error: Native JS classes and objects must have exactly one annotation among @JSGlobal, @JSImport and @JSGlobalScope. + |$secondAnnot + | ^ + """ } } } @@ -969,6 +994,38 @@ class JSInteropTest extends DirectTest with TestHelpers { } + @Test + def nativeClassMustHaveLoadingSpec: Unit = { + """ + @js.native + class A extends js.Object + + @js.native + abstract class B extends js.Object + """ hasErrors + """ + |newSource1.scala:6: error: Native JS classes and objects must have exactly one annotation among @JSGlobal, @JSImport and @JSGlobalScope. + | class A extends js.Object + | ^ + |newSource1.scala:9: error: Native JS classes and objects must have exactly one annotation among @JSGlobal, @JSImport and @JSGlobalScope. + | abstract class B extends js.Object + | ^ + """ + } + + @Test + def nativeObjectMustHaveLoadingSpec: Unit = { + """ + @js.native + object A extends js.Object + """ hasErrors + """ + |newSource1.scala:6: error: Native JS classes and objects must have exactly one annotation among @JSGlobal, @JSImport and @JSGlobalScope. + | object A extends js.Object + | ^ + """ + } + @Test def noNativeClassObjectWithoutExplicitNameInsideScalaObject: Unit = { @@ -977,9 +1034,9 @@ class JSInteropTest extends DirectTest with TestHelpers { @js.native class B extends js.Object } - """ hasWarns + """ hasErrors """ - |newSource1.scala:7: warning: Native JS classes inside non-native objects should have an @JSGlobal or @JSImport annotation. This will be enforced in 1.0. + |newSource1.scala:7: error: Native JS classes and objects must have exactly one annotation among @JSGlobal, @JSImport and @JSGlobalScope. | class B extends js.Object | ^ """ @@ -991,7 +1048,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Native JS objects inside non-native objects must have an @JSGlobal or @JSImport annotation + |newSource1.scala:7: error: Native JS classes and objects must have exactly one annotation among @JSGlobal, @JSImport and @JSGlobalScope. | object B extends js.Object | ^ """ @@ -1032,11 +1089,9 @@ class JSInteropTest extends DirectTest with TestHelpers { @JSGlobal object C extends js.Object } - """ hasWarns + """ hasErrors """ - |newSource1.scala:7: warning: Top-level native JS classes and objects should have an @JSGlobal or @JSImport annotation. This will be enforced in 1.0. - | If migrating from 0.6.14 or earlier, the equivalent behavior is an @JSGlobal without parameter. - | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) + |newSource1.scala:7: error: Native JS classes and objects must have exactly one annotation among @JSGlobal, @JSImport and @JSGlobalScope. | object B extends js.Object | ^ """ @@ -1050,11 +1105,9 @@ class JSInteropTest extends DirectTest with TestHelpers { @JSGlobal class C extends js.Object } - """ hasWarns + """ hasErrors """ - |newSource1.scala:7: warning: Top-level native JS classes and objects should have an @JSGlobal or @JSImport annotation. This will be enforced in 1.0. - | If migrating from 0.6.14 or earlier, the equivalent behavior is an @JSGlobal without parameter. - | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) + |newSource1.scala:7: error: Native JS classes and objects must have exactly one annotation among @JSGlobal, @JSImport and @JSGlobalScope. | class B extends js.Object | ^ """ @@ -1067,18 +1120,32 @@ class JSInteropTest extends DirectTest with TestHelpers { @JSName("InnerC") @js.native - object C extends js.Object + abstract class C extends js.Object + + @JSName("InnerD") + @js.native + object D extends js.Object } - """ hasWarns + """ hasErrors """ - |newSource1.scala:6: warning: @JSName on top-level native JS classes and objects (or native JS classes and objects inside Scala objects) is deprecated, and should be replaced by @JSGlobal (with the same meaning). This will be enforced in 1.0. - | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) + |newSource1.scala:6: error: @JSName annotations are not allowed on top level classes or objects (or classes and objects inside Scala objects). | @JSName("InnerB") | ^ - |newSource1.scala:10: warning: @JSName on top-level native JS classes and objects (or native JS classes and objects inside Scala objects) is deprecated, and should be replaced by @JSGlobal (with the same meaning). This will be enforced in 1.0. - | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) + |newSource1.scala:8: error: Native JS classes and objects must have exactly one annotation among @JSGlobal, @JSImport and @JSGlobalScope. + | class B extends js.Object + | ^ + |newSource1.scala:10: error: @JSName annotations are not allowed on top level classes or objects (or classes and objects inside Scala objects). | @JSName("InnerC") | ^ + |newSource1.scala:12: error: Native JS classes and objects must have exactly one annotation among @JSGlobal, @JSImport and @JSGlobalScope. + | abstract class C extends js.Object + | ^ + |newSource1.scala:14: error: @JSName annotations are not allowed on top level classes or objects (or classes and objects inside Scala objects). + | @JSName("InnerD") + | ^ + |newSource1.scala:16: error: Native JS classes and objects must have exactly one annotation among @JSGlobal, @JSImport and @JSGlobalScope. + | object D extends js.Object + | ^ """ """ @@ -1177,39 +1244,6 @@ class JSInteropTest extends DirectTest with TestHelpers { | ^ """ - // #1664 - """ - import js.annotation.JSName - - object A { - val a = "Hello" - } - - @JSName(A.a) - @js.native - object B extends js.Object - - @JSName(A.a) - @js.native - class C extends js.Object - """ hasErrors - """ - |newSource1.scala:11: error: A string argument to JSName must be a literal string - | @JSName(A.a) - | ^ - |newSource1.scala:11: warning: @JSName on top-level native JS classes and objects (or native JS classes and objects inside Scala objects) is deprecated, and should be replaced by @JSGlobal (with the same meaning). This will be enforced in 1.0. - | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) - | @JSName(A.a) - | ^ - |newSource1.scala:15: error: A string argument to JSName must be a literal string - | @JSName(A.a) - | ^ - |newSource1.scala:15: warning: @JSName on top-level native JS classes and objects (or native JS classes and objects inside Scala objects) is deprecated, and should be replaced by @JSGlobal (with the same meaning). This will be enforced in 1.0. - | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) - | @JSName(A.a) - | ^ - """ - } @Test @@ -1274,6 +1308,7 @@ class JSInteropTest extends DirectTest with TestHelpers { // Native objects are OK, since we do not control definition order. """ + @JSGlobal @js.native object A extends js.Object { val a: js.Symbol = js.native @@ -1654,33 +1689,6 @@ class JSInteropTest extends DirectTest with TestHelpers { } - @Test - def noJSSymbolNameOnTopLevelClassesAndObjects: Unit = { - for { - kind <- Seq("class", "object") - } { - s""" - object Sym { - val sym = js.Symbol() - } - - @JSName(Sym.sym) - @js.native - $kind A extends js.Object - """ hasErrors - s""" - |newSource1.scala:9: error: @JSName with a js.Symbol can only be used on members of JavaScript types - | @JSName(Sym.sym) - | ^ - |newSource1.scala:11: warning: Top-level native JS classes and objects should have an @JSGlobal or @JSImport annotation. This will be enforced in 1.0. - | If migrating from 0.6.14 or earlier, the equivalent behavior is an @JSGlobal without parameter. - | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) - | $kind A extends js.Object - | ${" " * kind.length} ^ - """ - } - } - @Test def noJSSymbolNameOnNestedNativeClassesAndObjects: Unit = { for { diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/MissingJSGlobalDeprecationsSuppressedTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/MissingJSGlobalDeprecationsSuppressedTest.scala deleted file mode 100644 index 1835be4059..0000000000 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/MissingJSGlobalDeprecationsSuppressedTest.scala +++ /dev/null @@ -1,88 +0,0 @@ -package org.scalajs.core.compiler.test - -import org.scalajs.core.compiler.test.util._ -import org.junit.Test - -// scalastyle:off line.size.limit - -/* This is a copy of MissingJSGlobalDeprecationsTest, but with all the - * relevant deprecations suppressed. This tests the suppression mechanism. - */ -class MissingJSGlobalDeprecationsSuppressedTest - extends DirectTest with TestHelpers { - - override def extraArgs: List[String] = - super.extraArgs :+ "-P:scalajs:suppressMissingJSGlobalDeprecations" - - override def preamble: String = - """import scala.scalajs.js, js.annotation._ - """ - - @Test - def noWarnNoAnnotClass: Unit = { - """ - @js.native - class A extends js.Object - - @js.native - abstract class B extends js.Object - """.hasNoWarns - } - - @Test - def noWarnNoAnnotObject: Unit = { - """ - @js.native - object A extends js.Object - """.hasNoWarns - } - - @Test - def noWarnJSNameClass: Unit = { - """ - @js.native - @JSName("Foo") - class A extends js.Object - - @js.native - @JSName("Foo") - abstract class B extends js.Object - """.hasNoWarns - } - - @Test - def noWarnJSNameObject: Unit = { - """ - @js.native - @JSName("Foo") - object A extends js.Object - """.hasNoWarns - } - - @Test - def noWarnJSNameNestedClass: Unit = { - """ - object Enclosing { - @js.native - @JSName("Foo") - class A extends js.Object - - @js.native - @JSName("Foo") - abstract class B extends js.Object - } - """.hasNoWarns - } - - @Test - def noWarnJSNameNestObject: Unit = { - """ - object Enclosing { - @js.native - @JSName("Foo") - object A extends js.Object - } - """.hasNoWarns - } - -} diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/MissingJSGlobalDeprecationsTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/MissingJSGlobalDeprecationsTest.scala deleted file mode 100644 index c42f4d6401..0000000000 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/MissingJSGlobalDeprecationsTest.scala +++ /dev/null @@ -1,132 +0,0 @@ -package org.scalajs.core.compiler.test - -import org.scalajs.core.compiler.test.util._ -import org.junit.Test - -// scalastyle:off line.size.limit - -class MissingJSGlobalDeprecationsTest extends DirectTest with TestHelpers { - - override def preamble: String = - """import scala.scalajs.js, js.annotation._ - """ - - @Test - def warnNoAnnotClass: Unit = { - """ - @js.native - class A extends js.Object - - @js.native - abstract class B extends js.Object - """ hasWarns - """ - |newSource1.scala:4: warning: Top-level native JS classes and objects should have an @JSGlobal or @JSImport annotation. This will be enforced in 1.0. - | If migrating from 0.6.14 or earlier, the equivalent behavior is an @JSGlobal without parameter. - | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) - | class A extends js.Object - | ^ - |newSource1.scala:7: warning: Top-level native JS classes and objects should have an @JSGlobal or @JSImport annotation. This will be enforced in 1.0. - | If migrating from 0.6.14 or earlier, the equivalent behavior is an @JSGlobal without parameter. - | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) - | abstract class B extends js.Object - | ^ - """ - } - - @Test - def warnNoAnnotObject: Unit = { - """ - @js.native - object A extends js.Object - """ hasWarns - """ - |newSource1.scala:4: warning: Top-level native JS classes and objects should have an @JSGlobal or @JSImport annotation. This will be enforced in 1.0. - | If migrating from 0.6.14 or earlier, the equivalent behavior is an @JSGlobal without parameter. - | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) - | object A extends js.Object - | ^ - """ - } - - @Test - def warnJSNameClass: Unit = { - """ - @js.native - @JSName("Foo") - class A extends js.Object - - @js.native - @JSName("Foo") - abstract class B extends js.Object - """ hasWarns - """ - |newSource1.scala:4: warning: @JSName on top-level native JS classes and objects (or native JS classes and objects inside Scala objects) is deprecated, and should be replaced by @JSGlobal (with the same meaning). This will be enforced in 1.0. - | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) - | @JSName("Foo") - | ^ - |newSource1.scala:8: warning: @JSName on top-level native JS classes and objects (or native JS classes and objects inside Scala objects) is deprecated, and should be replaced by @JSGlobal (with the same meaning). This will be enforced in 1.0. - | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) - | @JSName("Foo") - | ^ - """ - } - - @Test - def warnJSNameObject: Unit = { - """ - @js.native - @JSName("Foo") - object A extends js.Object - """ hasWarns - """ - |newSource1.scala:4: warning: @JSName on top-level native JS classes and objects (or native JS classes and objects inside Scala objects) is deprecated, and should be replaced by @JSGlobal (with the same meaning). This will be enforced in 1.0. - | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) - | @JSName("Foo") - | ^ - """ - } - - @Test - def warnJSNameNestedClass: Unit = { - """ - object Enclosing { - @js.native - @JSName("Foo") - class A extends js.Object - - @js.native - @JSName("Foo") - abstract class B extends js.Object - } - """ hasWarns - """ - |newSource1.scala:5: warning: @JSName on top-level native JS classes and objects (or native JS classes and objects inside Scala objects) is deprecated, and should be replaced by @JSGlobal (with the same meaning). This will be enforced in 1.0. - | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) - | @JSName("Foo") - | ^ - |newSource1.scala:9: warning: @JSName on top-level native JS classes and objects (or native JS classes and objects inside Scala objects) is deprecated, and should be replaced by @JSGlobal (with the same meaning). This will be enforced in 1.0. - | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) - | @JSName("Foo") - | ^ - """ - } - - @Test - def warnJSNameNestObject: Unit = { - """ - object Enclosing { - @js.native - @JSName("Foo") - object A extends js.Object - } - """ hasWarns - """ - |newSource1.scala:5: warning: @JSName on top-level native JS classes and objects (or native JS classes and objects inside Scala objects) is deprecated, and should be replaced by @JSGlobal (with the same meaning). This will be enforced in 1.0. - | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressMissingJSGlobalDeprecations` to scalac) - | @JSName("Foo") - | ^ - """ - } - -} diff --git a/project/Build.scala b/project/Build.scala index 7d0e5cc182..c812e2c68d 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1386,7 +1386,6 @@ object Build { * useless warnings. */ scalacOptions in Test += "-P:scalajs:suppressExportDeprecations", - scalacOptions in Test += "-P:scalajs:suppressMissingJSGlobalDeprecations", unmanagedSourceDirectories in Test ++= { val testDir = (sourceDirectory in Test).value diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala index c6a98914e3..dec7cb79c0 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala @@ -118,12 +118,6 @@ class InteroperabilityTest { assertEquals(42, obj.field) assertEquals("42", obj.method) assertEquals("Scala.js", obj.getConstructorParam) - - // With @JSName (old-style) - val objOld = new InteroperabilityTestPatternJSName("Scala.js") - assertEquals(42, objOld.field) - assertEquals("42", objOld.method) - assertEquals("Scala.js", objOld.getConstructorParam) } @Test def should_acces_top_level_JS_objects_via_Scala_objects_inheriting_from_js_Object(): Unit = { @@ -143,13 +137,6 @@ class InteroperabilityTest { val obj = TopLevel("7357") assertEquals("7357", obj.value) assertEquals(7357, obj.valueAsInt) - - // With @JSName (old-style) - val TopLevelOld = InteroperabilityTestTopLevelJSName - assertSame(TopLevel, TopLevelOld) - val objOld = TopLevelOld("7357") - assertEquals("7357", objOld.value) - assertEquals(7357, objOld.valueAsInt) } @Test def should_access_native_JS_classes_and_objects_nested_in_JS_objects(): Unit = { @@ -171,8 +158,6 @@ class InteroperabilityTest { this.x = x || 42; } }; - var InteroperabilityTestContainerObjectJSNameOmitted = - InteroperabilityTestContainerObject; """) // Use alias for convenience: see end of file for definition @@ -195,28 +180,6 @@ class InteroperabilityTest { val obj6 = new TopLevel.ContainedClassWithDefaultParam(10) assertEquals(10, obj6.x) - - // With an omitted @JSName (old-style) - val TopLevelOld = InteroperabilityTestContainerObjectJSNameOmitted - assertSame(TopLevel, TopLevelOld) - - val obj1Old = new TopLevelOld.ContainedClass(34) - assertEquals(34, obj1Old.x) - - val obj2Old = TopLevelOld.ContainedObject - assertEquals(42, obj2Old.x) - - val obj3Old = new TopLevelOld.ContainedClassWithJSName(65) - assertEquals(130, obj3Old.x) - - val obj4Old = TopLevelOld.ContainedObjectWithJSName - assertEquals(4242, obj4Old.x) - - val obj5Old = new TopLevelOld.ContainedClassWithDefaultParam() - assertEquals(42, obj5Old.x) - - val obj6Old = new TopLevelOld.ContainedClassWithDefaultParam(10) - assertEquals(10, obj6Old.x) } @Test def should_access_native_JS_classes_and_objects_nested_in_atJSNamed_JS_objects(): Unit = { @@ -251,22 +214,6 @@ class InteroperabilityTest { val obj4 = TopLevel.ContainedObjectWithJSName assertEquals(4242, obj4.x) - - // With @JSName (old-style) - val TopLevelOld = InteroperabilityTestContainerObjectExplicitNameJSName - assertSame(TopLevel, TopLevelOld) - - val obj1Old = new TopLevelOld.ContainedClass(34) - assertEquals(34, obj1Old.x) - - val obj2Old = TopLevelOld.ContainedObject - assertEquals(42, obj2Old.x) - - val obj3Old = new TopLevelOld.ContainedClassWithJSName(65) - assertEquals(130, obj3Old.x) - - val obj4Old = TopLevelOld.ContainedObjectWithJSName - assertEquals(4242, obj4Old.x) } @Test def should_allow_to_call_JS_methods_with_variadic_parameters(): Unit = { @@ -689,15 +636,6 @@ class InteroperabilityTestPattern protected () extends js.Object { def getConstructorParam(): String = js.native } -@JSName("InteroperabilityTestInherit.Pattern") -@js.native -class InteroperabilityTestPatternJSName protected () extends js.Object { - def this(pattern: String) = this() - val field: Int = js.native - def method(): String = js.native - def getConstructorParam(): String = js.native -} - @js.native trait InteroperabilityTestTopLevel extends js.Object { val value: String = js.native @@ -710,12 +648,6 @@ object InteroperabilityTestTopLevel extends js.Object { def apply(value: String): InteroperabilityTestTopLevel = js.native } -@JSName("InteroperabilityTestTopLevelObject") -@js.native -object InteroperabilityTestTopLevelJSName extends js.Object { - def apply(value: String): InteroperabilityTestTopLevel = js.native -} - @js.native @JSGlobal object InteroperabilityTestContainerObject extends js.Object { @@ -747,36 +679,6 @@ object InteroperabilityTestContainerObject extends js.Object { } } -@js.native -object InteroperabilityTestContainerObjectJSNameOmitted extends js.Object { - @js.native - class ContainedClass(_x: Int) extends js.Object { - val x: Int = js.native - } - - @js.native - object ContainedObject extends js.Object { - val x: Int = js.native - } - - @JSName("ContainedClassRenamed") - @js.native - class ContainedClassWithJSName(_x: Int) extends js.Object { - val x: Int = js.native - } - - @JSName("ContainedObjectRenamed") - @js.native - object ContainedObjectWithJSName extends js.Object { - val x: Int = js.native - } - - @js.native - class ContainedClassWithDefaultParam(_x: Int = ???) extends js.Object { - val x: Int = js.native - } -} - @JSGlobal("InteroperabilityTestContainerObjectRenamed") @js.native object InteroperabilityTestContainerObjectExplicitName extends js.Object { @@ -803,32 +705,6 @@ object InteroperabilityTestContainerObjectExplicitName extends js.Object { } } -@JSName("InteroperabilityTestContainerObjectRenamed") -@js.native -object InteroperabilityTestContainerObjectExplicitNameJSName extends js.Object { - @js.native - class ContainedClass(_x: Int) extends js.Object { - val x: Int = js.native - } - - @js.native - object ContainedObject extends js.Object { - val x: Int = js.native - } - - @JSName("ContainedClassRenamed") - @js.native - class ContainedClassWithJSName(_x: Int) extends js.Object { - val x: Int = js.native - } - - @JSName("ContainedObjectRenamed") - @js.native - object ContainedObjectWithJSName extends js.Object { - val x: Int = js.native - } -} - @js.native trait InteroperabilityTestVariadicMethod extends js.Object { def foo(args: Any*): js.Array[Any] = js.native diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNativeInPackage.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNativeInPackage.scala index 52ede549c4..6df36bfd45 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNativeInPackage.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNativeInPackage.scala @@ -11,37 +11,19 @@ package object packageobjectwithnatives { @JSGlobal object JSNativeObjectInPackageFoo extends js.Object - @js.native - object JSNativeObjectInPackageFooJSNameOmitted extends js.Object - @js.native @JSGlobal("JSNativeObjectInPackageBar") object JSNativeObjectInPackageBaz extends js.Object - @js.native - @JSName("JSNativeObjectInPackageBar") - object JSNativeObjectInPackageBazJSName extends js.Object - @js.native @JSGlobal class JSNativeClassInPackageFoo extends js.Object { def foo(): String = js.native } - @js.native - class JSNativeClassInPackageFooJSNameOmitted extends js.Object { - def foo(): String = js.native - } - - @js.native - @JSName("JSNativeClassInPackageBar") - class JSNativeClassInPackageBaz extends js.Object { - def baz(): String = js.native - } - @js.native @JSGlobal("JSNativeClassInPackageBar") - class JSNativeClassInPackageBazJSName extends js.Object { + class JSNativeClassInPackageBaz extends js.Object { def baz(): String = js.native } } @@ -56,13 +38,6 @@ class JSNativeInPackage { assertSame(JSNativeObjectInPackageFoo, gJSNativeObjectInPackageFoo) } - @Test def testObjectDefaultJSName(): Unit = { - val gJSNativeObjectInPackageFoo = global.JSNativeObjectInPackageFoo - assertFalse(js.isUndefined(gJSNativeObjectInPackageFoo)) - assertSame(JSNativeObjectInPackageFooJSNameOmitted, - gJSNativeObjectInPackageFoo) - } - @Test def testObjectJSGlobal(): Unit = { val gJSNativeObjectInPackageBar = global.JSNativeObjectInPackageBar val gJSNativeObjectInPackageBaz = global.JSNativeObjectInPackageBaz @@ -71,14 +46,6 @@ class JSNativeInPackage { assertSame(JSNativeObjectInPackageBaz, gJSNativeObjectInPackageBar) } - @Test def testObjectJSName(): Unit = { - val gJSNativeObjectInPackageBar = global.JSNativeObjectInPackageBar - val gJSNativeObjectInPackageBaz = global.JSNativeObjectInPackageBaz - assertFalse(js.isUndefined(gJSNativeObjectInPackageBar)) - assertTrue(js.isUndefined(gJSNativeObjectInPackageBaz)) - assertSame(JSNativeObjectInPackageBazJSName, gJSNativeObjectInPackageBar) - } - @Test def testClassDefaultJSGlobal(): Unit = { val gJSNativeClassInPackageFooCtr = global.JSNativeClassInPackageFoo assertFalse(js.isUndefined(gJSNativeClassInPackageFooCtr)) @@ -91,18 +58,6 @@ class JSNativeInPackage { assertEquals("foo", new JSNativeClassInPackageFoo().foo()) } - @Test def testClassDefaultJSName(): Unit = { - val gJSNativeClassInPackageFooCtr = global.JSNativeClassInPackageFoo - assertFalse(js.isUndefined(gJSNativeClassInPackageFooCtr)) - assertEquals(js.constructorOf[JSNativeClassInPackageFooJSNameOmitted], - gJSNativeClassInPackageFooCtr) - - val gJSNativeClassInPackageFoo = - js.Dynamic.newInstance(gJSNativeClassInPackageFooCtr)() - assertEquals("foo", gJSNativeClassInPackageFoo.foo()) - assertEquals("foo", new JSNativeClassInPackageFooJSNameOmitted().foo()) - } - @Test def testClassJSGlobal(): Unit = { val gJSNativeClassInPackageBarCtr = global.JSNativeClassInPackageBar val gJSNativeClassInPackageBazCtr = global.JSNativeClassInPackageBaz @@ -116,18 +71,4 @@ class JSNativeInPackage { assertEquals("baz", gJSNativeClassInPackageBar.baz()) assertEquals("baz", new JSNativeClassInPackageBaz().baz()) } - - @Test def testClassJSName(): Unit = { - val gJSNativeClassInPackageBarCtr = global.JSNativeClassInPackageBar - val gJSNativeClassInPackageBazCtr = global.JSNativeClassInPackageBaz - assertFalse(js.isUndefined(gJSNativeClassInPackageBarCtr)) - assertSame(js.constructorOf[JSNativeClassInPackageBazJSName], - gJSNativeClassInPackageBarCtr) - assertTrue(js.isUndefined(gJSNativeClassInPackageBazCtr)) - - val gJSNativeClassInPackageBar = - js.Dynamic.newInstance(gJSNativeClassInPackageBarCtr)() - assertEquals("baz", gJSNativeClassInPackageBar.baz()) - assertEquals("baz", new JSNativeClassInPackageBazJSName().baz()) - } } From 2bad0ac76a9b33ff1f4d7d39a8fbe6178ff216cd Mon Sep 17 00:00:00 2001 From: Martti von Hertzen Date: Wed, 1 Mar 2017 22:24:52 +0200 Subject: [PATCH 0196/2665] Implement java.util.Base64. --- javalib/src/main/scala/java/util/Base64.scala | 587 ++++++++++++++++ .../testsuite/javalib/util/Base64Test.scala | 645 ++++++++++++++++++ 2 files changed, 1232 insertions(+) create mode 100644 javalib/src/main/scala/java/util/Base64.scala create mode 100644 test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/Base64Test.scala diff --git a/javalib/src/main/scala/java/util/Base64.scala b/javalib/src/main/scala/java/util/Base64.scala new file mode 100644 index 0000000000..28b82d7dec --- /dev/null +++ b/javalib/src/main/scala/java/util/Base64.scala @@ -0,0 +1,587 @@ +package java.util + +import scala.annotation.tailrec + +import java.io._ +import java.nio.charset.StandardCharsets +import java.nio.ByteBuffer + +object Base64 { + + private val chars = ('A' to 'Z') ++ ('a' to 'z') ++ ('0' to '9') + + private val basicEncodeTable: Array[Byte] = + (chars ++ Seq('+', '/')).map(_.toByte).toArray + + private val urlSafeEncodeTable: Array[Byte] = + (chars ++ Seq('-', '_')).map(_.toByte).toArray + + private def decodeTable(encode: Array[Byte]): Array[Int] = { + val decode = Array.fill[Int](256)(-1) + for ((b, i) <- encode.zipWithIndex) + decode(b) = i + decode('=') = -2 + decode + } + + private val basicDecodeTable = decodeTable(basicEncodeTable) + private val urlSafeDecodeTable = decodeTable(urlSafeEncodeTable) + + private val mimeLineSeparators = Array[Byte]('\r', '\n') + private final val mimeLineLength = 76 + + private val basicEncoder = + new Encoder(basicEncodeTable) + + private val basicDecoder = + new Decoder(basicDecodeTable, ignoreInvalid = false) + + private val mimeEncoder = + new Encoder(basicEncodeTable, mimeLineLength, mimeLineSeparators) + + private val mimeDecoder = + new Decoder(basicDecodeTable, ignoreInvalid = true) + + private val urlSafeEncoder = + new Encoder(urlSafeEncodeTable) + + private val urlSafeDecoder = + new Decoder(urlSafeDecodeTable, ignoreInvalid = false) + + // -------------------------------------------------------------------------- + + def getEncoder(): Encoder = basicEncoder + + def getUrlEncoder(): Encoder = urlSafeEncoder + + def getMimeEncoder(): Encoder = mimeEncoder + + def getMimeEncoder(lineLength: Int, lineSeparator: Array[Byte]): Encoder = { + for (b <- lineSeparator) { + if (basicDecodeTable(b & 0xff) != -1) { + throw new IllegalArgumentException( + "Illegal base64 line separator character 0x" + (b & 0xff).toHexString) + } + } + new Encoder(basicEncodeTable, lineLength / 4 * 4, lineSeparator) + } + + def getDecoder(): Decoder = basicDecoder + + def getUrlDecoder(): Decoder = urlSafeDecoder + + def getMimeDecoder(): Decoder = mimeDecoder + + // -------------------------------------------------------------------------- + + class Decoder private[Base64] (table: Array[Int], ignoreInvalid: Boolean) { + + def decode(src: Array[Byte]): Array[Byte] = { + val dst = new Array[Byte](dstRequiredLength(src)) + doDecode(new Wrapper(src), new Wrapper(dst)) + dst + } + + def decode(src: String): Array[Byte] = + decode(src.getBytes(StandardCharsets.ISO_8859_1)) + + def decode(src: Array[Byte], dst: Array[Byte]): Int = { + if (dst.length < dstMaxLength(src.length) && // dst is possibly too small + dst.length < dstRequiredLength(src)) { // dst is actually too small + throw new IllegalArgumentException( + "Output byte array is too small for decoding all input bytes") + } + + doDecode(new Wrapper(src), new Wrapper(dst)) + } + + def decode(buffer: ByteBuffer): ByteBuffer = { + val start = buffer.position() + try { + val src = new Array[Byte](buffer.remaining()) + buffer.get(src) + val dst = new Array[Byte](dstRequiredLength(src)) + val written = doDecode(new Wrapper(src), new Wrapper(dst)) + ByteBuffer.wrap(dst, 0, written) + } catch { + case e: IllegalArgumentException => + buffer.position(start) + throw e + } + } + + def wrap(is: InputStream): InputStream = + new DecodingInputStream(is, table, ignoreInvalid) + + // ------------------------------------------------------------------------ + // PRIVATE + // ------------------------------------------------------------------------ + + private def doDecode(src: Wrapper, dst: Wrapper): Int = { + val srcBuffer = new Wrapper(new Array[Byte](4)) + + @inline + def inputData(): Unit = { + srcBuffer.position = 0 + var shift = 18 + var i = 0 + while (srcBuffer.hasRemaining) { + i |= ((srcBuffer.get() & 0xff) << shift) + shift -= 6 + } + + if (shift == 12) { + throw new IllegalArgumentException( + "Last unit does not have enough valid bits") + } + + if (shift <= 6) + dst.put((i >> 16).toByte) + if (shift <= 0) + dst.put((i >> 8).toByte) + if (shift <= -6) + dst.put(i.toByte) + srcBuffer.clear() + } + + @tailrec + def iterate(): Unit = { + if (src.hasRemaining) { + if (srcBuffer.hasRemaining) { + val int = src.get() & 0xff + table(int) match { + case -2 => + + case -1 => + if (!ignoreInvalid) { + throw new IllegalArgumentException( + "Illegal base64 character " + int.toHexString) + } + iterate() + + case i => + srcBuffer.put(i.toByte) + iterate() + } + } else { + inputData() + iterate() + } + } + } + + iterate() + + // end or padding + srcBuffer.flip() + inputData() + while (src.hasRemaining) { + val int = src.get() & 0xff + val value = table(int) + if (value != -2 && (!ignoreInvalid || value > 0)) { + throw new IllegalArgumentException( + s"Input byte array has incorrect ending byte at $int") + } + } + + dst.position + } + + private def dstRequiredLength(src: Array[Byte]): Int = { + var validBytes = 0 + + if (ignoreInvalid) { + for (i <- src.indices) { + if (table(src(i) & 0xff) >= 0) + validBytes += 1 + } + } else { + /* We check the end for padding and compute the length from there. + * This is ok, if the rest contains garbage we'll have written + * something before throwing but the spec says "If the input byte array + * is not in valid Base64 encoding scheme then some bytes may have been + * written to the output byte array before IllegalArgumentException is + * thrown." + */ + validBytes = src.length + if (src.length >= 1 && src.last == '=') { + validBytes -= 1 + if (src.length >= 2 && src(src.length - 2) == '=') + validBytes -= 1 + } + + if (src.length >= 1 && validBytes == 0) { + throw new IllegalArgumentException( + "Input byte array has wrong 4-byte ending unit") + } + } + + dstMaxLength(validBytes) + } + + /** Computes the destination length solely based on the source length, + * without knowing about padding. + */ + private def dstMaxLength(srcLength: Int): Int = + (srcLength + 3) / 4 * 3 - (if (srcLength % 4 == 0) 0 else 4 - (srcLength % 4)) + + } + + private object DecodingInputStream { + private final val DecodeState18 = 0 + private final val DecodeState12 = 1 + private final val DecodeState14 = 2 + private final val DecodeState16 = 3 + } + + private class DecodingInputStream(in: InputStream, table: Array[Int], + ignoreInvalid: Boolean) + extends FilterInputStream(in) { + + import DecodingInputStream._ + + private val oneBuf = new Array[Byte](1) + + private var closed = false + private var eof = false + private var out = 0 + private var shift = DecodeState18 + + override def read(): Int = + if (read(oneBuf, 0, 1) == -1) -1 + else oneBuf(0) & 0xff + + override def read(b: Array[Byte], off: Int, len: Int): Int = { + var written = 0 + + @inline + def writeValue(i: Int): Int = { + /* Max value means we're writing remaining bytes after EOF, no table + * lookup. + */ + if (i == Int.MaxValue) { + 0 + } else { + table(i) match { + case -1 => + if (!ignoreInvalid) { + throw new IOException( + "Illegal base64 character " + i.toHexString) + } + 0 + + case v => + shift match { + case DecodeState18 => + out |= v << 18 + shift = DecodeState12 + 0 + + case DecodeState12 => + out |= v << 12 + b(off + written) = (out >> 16).toByte + out <<= 8 + shift = DecodeState14 + 1 + + case DecodeState14 => + out |= v << 14 + b(off + written) = (out >> 16).toByte + out <<= 8 + shift = DecodeState16 + 1 + + case DecodeState16 => + out |= v << 16 + b(off + written) = (out >> 16).toByte + out = 0 + shift = DecodeState18 + 1 + } + } + } + } + + @inline + def endOfFile(): Int = { + eof = true + shift match { + case DecodeState18 => + 0 // nothing + case DecodeState12 => + throw new IOException( + "Base64 stream has one un-decoded dangling byte.") + case _ => + writeValue(Int.MaxValue) + } + } + + @inline + def padding(): Int = { + eof = true + val s = shift + if (s == DecodeState18 || s == DecodeState12 || + (s == DecodeState14 && in.read() != '=' && !ignoreInvalid)) { + throw new IOException ("Illegal base64 ending sequence") + } + writeValue(Int.MaxValue) + } + + @tailrec + def iterate(): Unit = { + if (written < len) { + in.read() match { + case -1 => + written += endOfFile() + + case '=' => + written += padding() + iterate() + + case int => + written += writeValue(int) + iterate() + } + } + } + + if (closed) + throw new IOException("Stream is closed") + + if (off < 0 || len < 0 || len > b.length - off) + throw new IndexOutOfBoundsException() + + if (eof) { + -1 + } else { + iterate() + written + } + } + + override def close(): Unit = if (!closed) { + closed = true + in.close() + } + } + + // -------------------------------------------------------------------------- + + class Encoder private[Base64] (table: Array[Byte], lineLength: Int = 0, + lineSeparator: Array[Byte] = Array.empty, withPadding: Boolean = true) { + + def encode(src: Array[Byte]): Array[Byte] = { + val dst = new Array[Byte](dstLength(src.length)) + doEncode(src, dst, dst.length) + dst + } + + def encode(src: Array[Byte], dst: Array[Byte]): Int = { + val dstLen = dstLength(src.length) + if (dst.length < dstLen) { + throw new IllegalArgumentException( + "Output byte array is too small for encoding all input bytes") + } + doEncode(src, dst, dstLen) + } + + def encodeToString(src: Array[Byte]): String = + new String(encode(src), StandardCharsets.ISO_8859_1) + + def encode(buffer: ByteBuffer): ByteBuffer = { + val result = new Array[Byte](dstLength(buffer.remaining())) + val src = new Array[Byte](buffer.remaining()) + buffer.get(src) + val written = doEncode(new Wrapper(src), new Wrapper(result)) + ByteBuffer.wrap(result, 0, written) + } + + def wrap(os: OutputStream): OutputStream = + new EncodingOutputStream(os, table, lineLength, lineSeparator, withPadding) + + def withoutPadding(): Encoder = + if (withPadding) new Encoder(table, lineLength, lineSeparator, false) + else this + + // ------------------------------------------------------------------------ + // PRIVATE + // ------------------------------------------------------------------------ + + private def doEncode(src: Array[Byte], dst: Array[Byte], + dstLength: Int): Int = { + doEncode(new Wrapper(src), new Wrapper(dst, 0, dstLength)) + } + + // dst position must always be 0 here + private def doEncode(src: Wrapper, dst: Wrapper): Int = { + val length = src.remaining + var currentLine = 0 + + @inline + def encode(a: Byte, b: Byte, c: Byte): Unit = { + val bits = (a & 0xff) << 16 | (b & 0xff) << 8 | (c & 0xff) + dst.put(table((bits >>> 18) & 0x3f)) + dst.put(table((bits >>> 12) & 0x3f)) + if (dst.hasRemaining) + dst.put(table((bits >>> 6) & 0x3f)) + if (dst.hasRemaining) + dst.put(table(bits & 0x3f)) + + currentLine += 4 + if (lineSeparator.length > 0 && lineLength > 0 && + currentLine == lineLength && dst.hasRemaining) { + lineSeparator.foreach(dst.put(_)) + currentLine = 0 + } + } + + while (src.remaining >= 3) + encode(src.get(), src.get(), src.get()) + + (length % 3) match { + case 0 => + case 1 => + encode(src.get(), 0, 0) + if (withPadding) { + dst.position = dst.position - 2 + dst.put('='.toByte) + dst.put('='.toByte) + } + case 2 => + encode(src.get(), src.get(), 0) + if (withPadding) { + dst.position = dst.position - 1 + dst.put('='.toByte) + } + } + + dst.position + } + + private def dstLength(srcLength: Int): Int = { + val withPad = ((srcLength + 2) / 3) * 4 + val toRemove = if (withPadding) 0 else (3 - (srcLength % 3)) % 3 + val withoutEndLines = withPad - toRemove + val endLines = + if (lineLength <= 0) 0 + else ((withoutEndLines - 1) / lineLength) * lineSeparator.length + withoutEndLines + endLines + } + } + + // -------------------------------------------------------------------------- + + private class EncodingOutputStream(out: OutputStream, table: Array[Byte], + lineLength: Int, lineSeparator: Array[Byte], withPadding: Boolean) + extends FilterOutputStream(out) { + + private val inputBuf = new Wrapper(new Array[Byte](3)) + private var currentLineLength = 0 + private var closed = false + + override def write(b: Int): Unit = + write(Array(b.toByte), 0, 1) + + @inline + private def addLineSeparators(): Unit = { + if (lineSeparator.length > 0 && lineLength > 0 && + currentLineLength == lineLength) { + out.write(lineSeparator) + currentLineLength = 0 + } + } + + @inline + private def writeBuffer(count: Int): Unit = { + inputBuf.clear() + val bits = { + ((inputBuf.get() & 0xff) << 16) | + ((inputBuf.get() & 0xff) << 8) | + (inputBuf.get() & 0xff) + } + var shift = 18 + for (_ <- 0 until count) { + out.write(table((bits >>> shift) & 0x3f)) + shift -= 6 + currentLineLength += 1 + } + inputBuf.clear() + } + + override def write(bytes: Array[Byte], off: Int, len: Int): Unit = { + if (closed) + throw new IOException("Stream is closed") + if (off < 0 || len < 0 || len > bytes.length - off) + throw new IndexOutOfBoundsException() + + if (len != 0) { + addLineSeparators() + for (i <- off until (off + len)) { + inputBuf.put(bytes(i)) + if (!inputBuf.hasRemaining) { + writeBuffer(4) + if (i < (off + len - 1)) + addLineSeparators() + } + } + } + } + + override def close(): Unit = { + @inline + def fillAndWrite(count: Int): Unit = { + addLineSeparators() + while (inputBuf.hasRemaining) + inputBuf.put(0.toByte) + writeBuffer(count) + if (withPadding) { + for (_ <- count until 4) + out.write('=') + } + } + + if (!closed) { + inputBuf.position match { + case 0 => + case 1 => fillAndWrite(2) + case 2 => fillAndWrite(3) + } + out.close() + closed = true + } + } + } + + /** An Array augmented with a position and a limit. + * + * This is modeled after `java.nio.ByteBuffer`, but is more lightweight. + */ + private class Wrapper(array: Array[Byte], var position: Int, var limit: Int) { + + def this(array: Array[Byte]) = this(array, 0, array.length) + + def hasRemaining: Boolean = position < limit + + def remaining: Int = limit - position + + def put(b: Byte): Unit = { + array(position) = b + position += 1 + } + + def get(): Byte = { + position += 1 + array(position-1) + } + + def clear(): Unit = { + position = 0 + limit = array.length + } + + def flip(): Unit = { + limit = position + position = 0 + } + } +} diff --git a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/Base64Test.scala b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/Base64Test.scala new file mode 100644 index 0000000000..f4cdf00943 --- /dev/null +++ b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/Base64Test.scala @@ -0,0 +1,645 @@ +package org.scalajs.testsuite.javalib.util + +import java.io.{ByteArrayInputStream, ByteArrayOutputStream, IOException} +import java.nio.ByteBuffer +import java.nio.charset.StandardCharsets.ISO_8859_1 +import java.util.Base64 +import java.util.Base64.Decoder + +import org.junit.Assert._ +import org.junit.Assume._ +import org.junit.Test + +import org.scalajs.testsuite.utils.AssertThrows._ +import org.scalajs.testsuite.utils.Platform + +class Base64Test { + import Base64Test._ + + // -------------------------------------------------------------------------- + // ENCODERS + // -------------------------------------------------------------------------- + + @Test def encodeToString(): Unit = { + val results = + for ((name, in, enc) <- encoders) yield (name -> enc.encodeToString(in)) + assertEquals("calculated count doesn't match computed count", + encodedResults.length, results.size) + for (((name, enc), exp) <- results.zip(encodedResults)) + assertEquals(s"encodeToString doesn't match for: $name", exp, enc) + } + + @Test def encodeOneArray(): Unit = { + val results = + for ((name, in, enc) <- encoders) yield (name -> enc.encode(in)) + assertEquals("calculated count doesn't match computed count", + encodedResults.length, results.size) + for (((name, enc), exp) <- results.zip(encodedResults)) { + assertEquals(s"encode array doesn't match for: $name", + exp, new String(enc, ISO_8859_1)) + } + } + + @Test def encodeTwoArrays(): Unit = { + for (((name, in, enc), exp) <- encoders.zip(encodedResults)) { + val dst = new Array[Byte](exp.length + 10) // array too big on purpose + val written = enc.encode(in, dst) + assertEquals(s"number of written bytes doesn't match for: $name", + exp.length, written) + val content = dst.slice(0, written) + val rlt = new String(content, ISO_8859_1) + assertEquals(s"encode array into array doesn't match for: $name", + exp, rlt) + } + } + + @Test def encodeTwoArraysThrowsWithTooSmallDestination(): Unit = { + val in = "Man" + val dst = new Array[Byte](3) // too small + assertThrows(classOf[IllegalArgumentException], { + Base64.getEncoder.encode(in.getBytes, dst) + }) + } + + @Test def encodeByteBuffer(): Unit = { + for (((name, in, enc), exp) <- encoders.zip(encodedResults)) { + val result1 = enc.encode(ByteBuffer.wrap(in)) + assertEquals(s"byte buffers don't match for: $name", + exp, new String(result1.array(), ISO_8859_1)) + + val bb = ByteBuffer.allocate(in.length + 2) + bb.position(2) + bb.mark() + bb.put(in) + bb.reset() + val result2 = enc.encode(bb) + assertEquals(s"byte buffers don't match for: $name", + exp, new String(result2.array(), ISO_8859_1)) + } + } + + @Test def encodeOutputStream(): Unit = { + for (((name, in, enc), exp) <- encoders.zip(encodedResults)) { + val baos = new ByteArrayOutputStream() + val out = enc.wrap(baos) + out.write(in(0)) + out.write(in, 1, in.length - 1) + out.close() + val result = new String(baos.toByteArray, ISO_8859_1) + assertEquals(s"output stream result doesn't match for: $name", + exp, result) + } + } + + @Test def encodeOutputStreamFailsOnJVM(): Unit = { + assumeFalse("JDK bug JDK-8176379", Platform.executingInJVM) + + // The `1` below will create a buggy encoder on the JVM + val encoder = Base64.getMimeEncoder(1, Array('@')) + val input = "Man" + val expected = "TWFu" + val ba = new ByteArrayOutputStream() + val out = encoder.wrap(ba) + out.write(input.getBytes) + out.close() + val result = new String(ba.toByteArray) + assertEquals("outputstream should be initialized correctly", + expected, result) + } + + @Test def encodeOutputStreamTooMuch(): Unit = { + val enc = Base64.getEncoder + val out = enc.wrap(new ByteArrayOutputStream()) + assertThrows(classOf[IndexOutOfBoundsException], { + out.write(Array.empty[Byte], 0, 5) + }) + } + + @Test def testIllegalLineSeparator(): Unit = { + assertThrows(classOf[IllegalArgumentException], { + Base64.getMimeEncoder(8, Array[Byte]('A')) + }) + } + + // -------------------------------------------------------------------------- + // DECODERS + // -------------------------------------------------------------------------- + + @Test def decodeFromString(): Unit = { + assertEquals("encoded data count doesn't match input count", + encoders.length, decodersAndInputs.length) + for ((encoded, (decoder, in)) <- encodedResults.zip(decodersAndInputs)) { + assertArrayEquals(s"decoded doesn't match expected $encoded", + in.getBytes(ISO_8859_1), decoder.decode(encoded)) + } + } + + @Test def decodeFromArray(): Unit = { + for ((encoded, (decoder, in)) <- encodedResults.zip(decodersAndInputs)) { + val encodedBytes = encoded.getBytes(ISO_8859_1) + val result = decoder.decode(encodedBytes) + assertEquals(s"decoded doesn't match expected for encoded $encoded", + in, new String(result, ISO_8859_1)) + } + } + + @Test def decodeFromArrayToDest(): Unit = { + for ((encoded, (decoder, in)) <- encodedResults.zip(decodersAndInputs)) { + val dst = new Array[Byte](in.length) + val encInBytes = encoded.getBytes(ISO_8859_1) + val dec = decoder.decode(encInBytes, dst) + assertEquals("decoded count doesn't match expected", in.length, dec) + assertArrayEquals("decoded array doesn't match expected", + in.getBytes(ISO_8859_1), dst) + } + } + + @Test def decodeFromByteBuffer(): Unit = { + for ((encoded, (decoder, in)) <- encodedResults.zip(decodersAndInputs)) { + val bb = ByteBuffer.wrap(encoded.getBytes(ISO_8859_1)) + val decoded = decoder.decode(bb) + val array = new Array[Byte](decoded.limit) + decoded.get(array) + assertArrayEquals("decoded byte buffer doesn't match expected", + in.getBytes(ISO_8859_1), array) + } + } + + @Test def decodeToArrayTooSmall(): Unit = { + val encoded = "TWFu" + val dst = new Array[Byte](2) // too small + assertThrows(classOf[IllegalArgumentException], { + Base64.getDecoder.decode(encoded.getBytes, dst) + }) + } + + @Test def decodeIllegalCharacter(): Unit = { + val encoded = "TWE*" + assertThrows(classOf[IllegalArgumentException], { + Base64.getDecoder.decode(encoded) + }) + assertThrows(classOf[IllegalArgumentException], { + Base64.getUrlDecoder.decode(encoded) + }) + + assertEquals("MIME encoder should allow illegals", + "Ma", new String(Base64.getMimeDecoder.decode(encoded), ISO_8859_1)) + } + + @Test def decodeIllegalLength(): Unit = { + val encoded = "TWFuu" + assertThrows(classOf[IllegalArgumentException], { + Base64.getDecoder.decode(encoded) + }) + assertThrows(classOf[IllegalArgumentException], { + Base64.getUrlDecoder.decode(encoded) + }) + assertThrows(classOf[IllegalArgumentException], { + Base64.getMimeDecoder.decode(encoded) + }) + } + + @Test def decodeIllegalPadding(): Unit = { + assumeFalse("JDK bug JDK-8176043", Platform.executingInJVM) + + val encoded = "TQ=*" + assertThrows(classOf[IllegalArgumentException], { + Base64.getDecoder.decode(encoded) + }) + assertThrows(classOf[IllegalArgumentException], { + Base64.getUrlDecoder.decode(encoded) + }) + + assertEquals("MIME encoder should allow illegal paddings", + "M", new String(Base64.getMimeDecoder.decode(encoded), ISO_8859_1)) + } + + @Test def decodeInputStream(): Unit = { + for ((encoded, (decoder, expected)) <- encodedResults.zip(decodersAndInputs)) { + val byteInstream = new ByteArrayInputStream(encoded.getBytes(ISO_8859_1)) + val instream = decoder.wrap(byteInstream) + val read = new Array[Byte](expected.length) + instream.read(read) + while (instream.read() != -1) {} // read padding + instream.close() + assertEquals("inputstream read value not as expected", + expected, new String(read, ISO_8859_1)) + } + } + + @Test def decodeIllegalsInputStream(): Unit = { + val encoded = "TQ=*" + assertThrows(classOf[IOException], { + decodeInputStream(basic, encoded) + }) + assertThrows(classOf[IOException], { + decodeInputStream(url, encoded) + }) + assertThrows(classOf[IOException], { + decodeInputStream(mime, "TWFu", Array('a')) + }) + assertThrows(classOf[IOException], { + decodeInputStream(basic, "TWFu", Array(0.toByte)) + }) + } + + @Test def decodeIllegalsInputStreamIllegalPadding(): Unit = { + assumeFalse("JDK bug JDK-8176043", Platform.executingInJVM) + + val encoded = "TQ=*" + assertEquals("mime encoder should allow illegal paddings", + "M", decodeInputStream(mime, encoded)) + } + + @Test def decodeBufferWithJustPaddingNonMime(): Unit = { + for (decoder <- Seq(Base64.getDecoder, Base64.getUrlDecoder)) { + // Should pass for empty and throw IllegalArgumentException for = and == + val bb = decoder.decode(ByteBuffer.allocate(0)) + assertEquals(0, bb.limit()) + for (input <- Seq("=", "==")) { + assertThrows(classOf[IllegalArgumentException], { + decoder.decode(ByteBuffer.wrap(input.getBytes)) + }) + } + } + } + + @Test def decodeBufferWithJustPaddingMime(): Unit = { + assumeFalse("JDK bug JDK-8176043", Platform.executingInJVM) + + for (input <- Seq("", "=", "==")) { + val bb = Base64.getMimeDecoder.decode(ByteBuffer.wrap(input.getBytes)) + assertEquals(0, bb.limit()) + } + } + + private def decodeInputStream(decoder: Decoder, input: String, + dangling: Array[Byte] = Array.empty): String = { + val bytes = input.getBytes ++ dangling + val stream = decoder.wrap(new ByteArrayInputStream(bytes)) + val tmp = new Array[Byte](bytes.length) + val read = stream.read(tmp) + new String(tmp, 0, read) + } + +} + +object Base64Test { + + private val input: Array[Byte] = { + val text = { + "Base64 is a group of similar binary-to-text encoding schemes that " + + "represent binary data in an ASCII string format by translating it " + + "into a radix-64 representation" + } + text.getBytes(ISO_8859_1) + } + + private val inputLengths = Seq(1, 2, 3, 4, 10, input.length) + private val lineDelimChars = "@$*" + private val lineLengths = Seq(-1, 0, 4, 5, 9) + + private val stdEncPadding = Seq( + "basic, padding" -> Base64.getEncoder, + "url, padding" -> Base64.getUrlEncoder, + "mime, padding" -> Base64.getMimeEncoder + ) + + private val stdEncNoPadding = { + for ((name, enc) <- stdEncPadding) + yield name.replace("padding", "no padding") -> enc.withoutPadding() + } + + private val lineDelimitersWithLineLengths: Seq[(String, Int)] = { + for { + i <- 0 to lineDelimChars.length + l <- lineLengths + } yield { + lineDelimChars.take(i) -> l + } + } + + private val customEncPadding = { + for ((delim, ll) <- lineDelimitersWithLineLengths) yield { + (s"mime, padding, line length: $ll delimiters: $delim" -> + Base64.getMimeEncoder(ll, delim.getBytes)) + } + } + + private val customEncNoPadding = { + for ((name, enc) <- customEncPadding) + yield name.replace("padding", "no padding") -> enc.withoutPadding() + } + + private val allEncoders = + stdEncPadding ++ stdEncNoPadding ++ customEncPadding ++ customEncNoPadding + + private val encoders = { + for { + (name, enc) <- allEncoders + length <- inputLengths + } yield { + (s"$name", input.take(length), enc) + } + } + + private lazy val decodersAndInputs = data.map(t => getDecoderAndInput(t._1)) + private lazy val encodedResults = data.map(_._2) + + private val basic = Base64.getDecoder + private val url = Base64.getUrlDecoder + + private val mime = Base64.getMimeDecoder + + def getDecoderAndInput(text: String): (Decoder, String) = { + val decoder = { + if (text.contains("basic")) basic + else if (text.contains("url")) url + else if (text.contains("mime")) mime + else throw new IllegalArgumentException(s"no decoder found in string $text") + } + val input = text.replaceAll(".*%(.*)%", "$1") + decoder -> input + } + + // scalastyle:off line.size.limit + lazy val data = Array( + "basic, padding %B%" -> "Qg==", + "basic, padding %Ba%" -> "QmE=", + "basic, padding %Bas%" -> "QmFz", + "basic, padding %Base%" -> "QmFzZQ==", + "basic, padding %Base64 is %" -> "QmFzZTY0IGlzIA==", + "basic, padding %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "url, padding %B%" -> "Qg==", + "url, padding %Ba%" -> "QmE=", + "url, padding %Bas%" -> "QmFz", + "url, padding %Base%" -> "QmFzZQ==", + "url, padding %Base64 is %" -> "QmFzZTY0IGlzIA==", + "url, padding %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "mime, padding %B%" -> "Qg==", + "mime, padding %Ba%" -> "QmE=", + "mime, padding %Bas%" -> "QmFz", + "mime, padding %Base%" -> "QmFzZQ==", + "mime, padding %Base64 is %" -> "QmFzZTY0IGlzIA==", + "mime, padding %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hl\r\nbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQg\r\nYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "basic, no padding %B%" -> "Qg", + "basic, no padding %Ba%" -> "QmE", + "basic, no padding %Bas%" -> "QmFz", + "basic, no padding %Base%" -> "QmFzZQ", + "basic, no padding %Base64 is %" -> "QmFzZTY0IGlzIA", + "basic, no padding %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "url, no padding %B%" -> "Qg", + "url, no padding %Ba%" -> "QmE", + "url, no padding %Bas%" -> "QmFz", + "url, no padding %Base%" -> "QmFzZQ", + "url, no padding %Base64 is %" -> "QmFzZTY0IGlzIA", + "url, no padding %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "mime, no padding %B%" -> "Qg", + "mime, no padding %Ba%" -> "QmE", + "mime, no padding %Bas%" -> "QmFz", + "mime, no padding %Base%" -> "QmFzZQ", + "mime, no padding %Base64 is %" -> "QmFzZTY0IGlzIA", + "mime, no padding %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hl\r\nbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQg\r\nYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "mime, padding, line length: -1 delimiters: %B%" -> "Qg==", + "mime, padding, line length: -1 delimiters: %Ba%" -> "QmE=", + "mime, padding, line length: -1 delimiters: %Bas%" -> "QmFz", + "mime, padding, line length: -1 delimiters: %Base%" -> "QmFzZQ==", + "mime, padding, line length: -1 delimiters: %Base64 is %" -> "QmFzZTY0IGlzIA==", + "mime, padding, line length: -1 delimiters: %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "mime, padding, line length: 0 delimiters: %B%" -> "Qg==", + "mime, padding, line length: 0 delimiters: %Ba%" -> "QmE=", + "mime, padding, line length: 0 delimiters: %Bas%" -> "QmFz", + "mime, padding, line length: 0 delimiters: %Base%" -> "QmFzZQ==", + "mime, padding, line length: 0 delimiters: %Base64 is %" -> "QmFzZTY0IGlzIA==", + "mime, padding, line length: 0 delimiters: %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "mime, padding, line length: 4 delimiters: %B%" -> "Qg==", + "mime, padding, line length: 4 delimiters: %Ba%" -> "QmE=", + "mime, padding, line length: 4 delimiters: %Bas%" -> "QmFz", + "mime, padding, line length: 4 delimiters: %Base%" -> "QmFzZQ==", + "mime, padding, line length: 4 delimiters: %Base64 is %" -> "QmFzZTY0IGlzIA==", + "mime, padding, line length: 4 delimiters: %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "mime, padding, line length: 5 delimiters: %B%" -> "Qg==", + "mime, padding, line length: 5 delimiters: %Ba%" -> "QmE=", + "mime, padding, line length: 5 delimiters: %Bas%" -> "QmFz", + "mime, padding, line length: 5 delimiters: %Base%" -> "QmFzZQ==", + "mime, padding, line length: 5 delimiters: %Base64 is %" -> "QmFzZTY0IGlzIA==", + "mime, padding, line length: 5 delimiters: %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "mime, padding, line length: 9 delimiters: %B%" -> "Qg==", + "mime, padding, line length: 9 delimiters: %Ba%" -> "QmE=", + "mime, padding, line length: 9 delimiters: %Bas%" -> "QmFz", + "mime, padding, line length: 9 delimiters: %Base%" -> "QmFzZQ==", + "mime, padding, line length: 9 delimiters: %Base64 is %" -> "QmFzZTY0IGlzIA==", + "mime, padding, line length: 9 delimiters: %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "mime, padding, line length: -1 delimiters: @ %B%" -> "Qg==", + "mime, padding, line length: -1 delimiters: @ %Ba%" -> "QmE=", + "mime, padding, line length: -1 delimiters: @ %Bas%" -> "QmFz", + "mime, padding, line length: -1 delimiters: @ %Base%" -> "QmFzZQ==", + "mime, padding, line length: -1 delimiters: @ %Base64 is %" -> "QmFzZTY0IGlzIA==", + "mime, padding, line length: -1 delimiters: @ %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "mime, padding, line length: 0 delimiters: @ %B%" -> "Qg==", + "mime, padding, line length: 0 delimiters: @ %Ba%" -> "QmE=", + "mime, padding, line length: 0 delimiters: @ %Bas%" -> "QmFz", + "mime, padding, line length: 0 delimiters: @ %Base%" -> "QmFzZQ==", + "mime, padding, line length: 0 delimiters: @ %Base64 is %" -> "QmFzZTY0IGlzIA==", + "mime, padding, line length: 0 delimiters: @ %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "mime, padding, line length: 4 delimiters: @ %B%" -> "Qg==", + "mime, padding, line length: 4 delimiters: @ %Ba%" -> "QmE=", + "mime, padding, line length: 4 delimiters: @ %Bas%" -> "QmFz", + "mime, padding, line length: 4 delimiters: @ %Base%" -> "QmFz@ZQ==", + "mime, padding, line length: 4 delimiters: @ %Base64 is %" -> "QmFz@ZTY0@IGlz@IA==", + "mime, padding, line length: 4 delimiters: @ %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFz@ZTY0@IGlz@IGEg@Z3Jv@dXAg@b2Yg@c2lt@aWxh@ciBi@aW5h@cnkt@dG8t@dGV4@dCBl@bmNv@ZGlu@ZyBz@Y2hl@bWVz@IHRo@YXQg@cmVw@cmVz@ZW50@IGJp@bmFy@eSBk@YXRh@IGlu@IGFu@IEFT@Q0lJ@IHN0@cmlu@ZyBm@b3Jt@YXQg@Ynkg@dHJh@bnNs@YXRp@bmcg@aXQg@aW50@byBh@IHJh@ZGl4@LTY0@IHJl@cHJl@c2Vu@dGF0@aW9u", + "mime, padding, line length: 5 delimiters: @ %B%" -> "Qg==", + "mime, padding, line length: 5 delimiters: @ %Ba%" -> "QmE=", + "mime, padding, line length: 5 delimiters: @ %Bas%" -> "QmFz", + "mime, padding, line length: 5 delimiters: @ %Base%" -> "QmFz@ZQ==", + "mime, padding, line length: 5 delimiters: @ %Base64 is %" -> "QmFz@ZTY0@IGlz@IA==", + "mime, padding, line length: 5 delimiters: @ %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFz@ZTY0@IGlz@IGEg@Z3Jv@dXAg@b2Yg@c2lt@aWxh@ciBi@aW5h@cnkt@dG8t@dGV4@dCBl@bmNv@ZGlu@ZyBz@Y2hl@bWVz@IHRo@YXQg@cmVw@cmVz@ZW50@IGJp@bmFy@eSBk@YXRh@IGlu@IGFu@IEFT@Q0lJ@IHN0@cmlu@ZyBm@b3Jt@YXQg@Ynkg@dHJh@bnNs@YXRp@bmcg@aXQg@aW50@byBh@IHJh@ZGl4@LTY0@IHJl@cHJl@c2Vu@dGF0@aW9u", + "mime, padding, line length: 9 delimiters: @ %B%" -> "Qg==", + "mime, padding, line length: 9 delimiters: @ %Ba%" -> "QmE=", + "mime, padding, line length: 9 delimiters: @ %Bas%" -> "QmFz", + "mime, padding, line length: 9 delimiters: @ %Base%" -> "QmFzZQ==", + "mime, padding, line length: 9 delimiters: @ %Base64 is %" -> "QmFzZTY0@IGlzIA==", + "mime, padding, line length: 9 delimiters: @ %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0@IGlzIGEg@Z3JvdXAg@b2Ygc2lt@aWxhciBi@aW5hcnkt@dG8tdGV4@dCBlbmNv@ZGluZyBz@Y2hlbWVz@IHRoYXQg@cmVwcmVz@ZW50IGJp@bmFyeSBk@YXRhIGlu@IGFuIEFT@Q0lJIHN0@cmluZyBm@b3JtYXQg@YnkgdHJh@bnNsYXRp@bmcgaXQg@aW50byBh@IHJhZGl4@LTY0IHJl@cHJlc2Vu@dGF0aW9u", + "mime, padding, line length: -1 delimiters: @$ %B%" -> "Qg==", + "mime, padding, line length: -1 delimiters: @$ %Ba%" -> "QmE=", + "mime, padding, line length: -1 delimiters: @$ %Bas%" -> "QmFz", + "mime, padding, line length: -1 delimiters: @$ %Base%" -> "QmFzZQ==", + "mime, padding, line length: -1 delimiters: @$ %Base64 is %" -> "QmFzZTY0IGlzIA==", + "mime, padding, line length: -1 delimiters: @$ %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "mime, padding, line length: 0 delimiters: @$ %B%" -> "Qg==", + "mime, padding, line length: 0 delimiters: @$ %Ba%" -> "QmE=", + "mime, padding, line length: 0 delimiters: @$ %Bas%" -> "QmFz", + "mime, padding, line length: 0 delimiters: @$ %Base%" -> "QmFzZQ==", + "mime, padding, line length: 0 delimiters: @$ %Base64 is %" -> "QmFzZTY0IGlzIA==", + "mime, padding, line length: 0 delimiters: @$ %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "mime, padding, line length: 4 delimiters: @$ %B%" -> "Qg==", + "mime, padding, line length: 4 delimiters: @$ %Ba%" -> "QmE=", + "mime, padding, line length: 4 delimiters: @$ %Bas%" -> "QmFz", + "mime, padding, line length: 4 delimiters: @$ %Base%" -> "QmFz@$ZQ==", + "mime, padding, line length: 4 delimiters: @$ %Base64 is %" -> "QmFz@$ZTY0@$IGlz@$IA==", + "mime, padding, line length: 4 delimiters: @$ %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFz@$ZTY0@$IGlz@$IGEg@$Z3Jv@$dXAg@$b2Yg@$c2lt@$aWxh@$ciBi@$aW5h@$cnkt@$dG8t@$dGV4@$dCBl@$bmNv@$ZGlu@$ZyBz@$Y2hl@$bWVz@$IHRo@$YXQg@$cmVw@$cmVz@$ZW50@$IGJp@$bmFy@$eSBk@$YXRh@$IGlu@$IGFu@$IEFT@$Q0lJ@$IHN0@$cmlu@$ZyBm@$b3Jt@$YXQg@$Ynkg@$dHJh@$bnNs@$YXRp@$bmcg@$aXQg@$aW50@$byBh@$IHJh@$ZGl4@$LTY0@$IHJl@$cHJl@$c2Vu@$dGF0@$aW9u", + "mime, padding, line length: 5 delimiters: @$ %B%" -> "Qg==", + "mime, padding, line length: 5 delimiters: @$ %Ba%" -> "QmE=", + "mime, padding, line length: 5 delimiters: @$ %Bas%" -> "QmFz", + "mime, padding, line length: 5 delimiters: @$ %Base%" -> "QmFz@$ZQ==", + "mime, padding, line length: 5 delimiters: @$ %Base64 is %" -> "QmFz@$ZTY0@$IGlz@$IA==", + "mime, padding, line length: 5 delimiters: @$ %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFz@$ZTY0@$IGlz@$IGEg@$Z3Jv@$dXAg@$b2Yg@$c2lt@$aWxh@$ciBi@$aW5h@$cnkt@$dG8t@$dGV4@$dCBl@$bmNv@$ZGlu@$ZyBz@$Y2hl@$bWVz@$IHRo@$YXQg@$cmVw@$cmVz@$ZW50@$IGJp@$bmFy@$eSBk@$YXRh@$IGlu@$IGFu@$IEFT@$Q0lJ@$IHN0@$cmlu@$ZyBm@$b3Jt@$YXQg@$Ynkg@$dHJh@$bnNs@$YXRp@$bmcg@$aXQg@$aW50@$byBh@$IHJh@$ZGl4@$LTY0@$IHJl@$cHJl@$c2Vu@$dGF0@$aW9u", + "mime, padding, line length: 9 delimiters: @$ %B%" -> "Qg==", + "mime, padding, line length: 9 delimiters: @$ %Ba%" -> "QmE=", + "mime, padding, line length: 9 delimiters: @$ %Bas%" -> "QmFz", + "mime, padding, line length: 9 delimiters: @$ %Base%" -> "QmFzZQ==", + "mime, padding, line length: 9 delimiters: @$ %Base64 is %" -> "QmFzZTY0@$IGlzIA==", + "mime, padding, line length: 9 delimiters: @$ %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0@$IGlzIGEg@$Z3JvdXAg@$b2Ygc2lt@$aWxhciBi@$aW5hcnkt@$dG8tdGV4@$dCBlbmNv@$ZGluZyBz@$Y2hlbWVz@$IHRoYXQg@$cmVwcmVz@$ZW50IGJp@$bmFyeSBk@$YXRhIGlu@$IGFuIEFT@$Q0lJIHN0@$cmluZyBm@$b3JtYXQg@$YnkgdHJh@$bnNsYXRp@$bmcgaXQg@$aW50byBh@$IHJhZGl4@$LTY0IHJl@$cHJlc2Vu@$dGF0aW9u", + "mime, padding, line length: -1 delimiters: @$* %B%" -> "Qg==", + "mime, padding, line length: -1 delimiters: @$* %Ba%" -> "QmE=", + "mime, padding, line length: -1 delimiters: @$* %Bas%" -> "QmFz", + "mime, padding, line length: -1 delimiters: @$* %Base%" -> "QmFzZQ==", + "mime, padding, line length: -1 delimiters: @$* %Base64 is %" -> "QmFzZTY0IGlzIA==", + "mime, padding, line length: -1 delimiters: @$* %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "mime, padding, line length: 0 delimiters: @$* %B%" -> "Qg==", + "mime, padding, line length: 0 delimiters: @$* %Ba%" -> "QmE=", + "mime, padding, line length: 0 delimiters: @$* %Bas%" -> "QmFz", + "mime, padding, line length: 0 delimiters: @$* %Base%" -> "QmFzZQ==", + "mime, padding, line length: 0 delimiters: @$* %Base64 is %" -> "QmFzZTY0IGlzIA==", + "mime, padding, line length: 0 delimiters: @$* %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "mime, padding, line length: 4 delimiters: @$* %B%" -> "Qg==", + "mime, padding, line length: 4 delimiters: @$* %Ba%" -> "QmE=", + "mime, padding, line length: 4 delimiters: @$* %Bas%" -> "QmFz", + "mime, padding, line length: 4 delimiters: @$* %Base%" -> "QmFz@$*ZQ==", + "mime, padding, line length: 4 delimiters: @$* %Base64 is %" -> "QmFz@$*ZTY0@$*IGlz@$*IA==", + "mime, padding, line length: 4 delimiters: @$* %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFz@$*ZTY0@$*IGlz@$*IGEg@$*Z3Jv@$*dXAg@$*b2Yg@$*c2lt@$*aWxh@$*ciBi@$*aW5h@$*cnkt@$*dG8t@$*dGV4@$*dCBl@$*bmNv@$*ZGlu@$*ZyBz@$*Y2hl@$*bWVz@$*IHRo@$*YXQg@$*cmVw@$*cmVz@$*ZW50@$*IGJp@$*bmFy@$*eSBk@$*YXRh@$*IGlu@$*IGFu@$*IEFT@$*Q0lJ@$*IHN0@$*cmlu@$*ZyBm@$*b3Jt@$*YXQg@$*Ynkg@$*dHJh@$*bnNs@$*YXRp@$*bmcg@$*aXQg@$*aW50@$*byBh@$*IHJh@$*ZGl4@$*LTY0@$*IHJl@$*cHJl@$*c2Vu@$*dGF0@$*aW9u", + "mime, padding, line length: 5 delimiters: @$* %B%" -> "Qg==", + "mime, padding, line length: 5 delimiters: @$* %Ba%" -> "QmE=", + "mime, padding, line length: 5 delimiters: @$* %Bas%" -> "QmFz", + "mime, padding, line length: 5 delimiters: @$* %Base%" -> "QmFz@$*ZQ==", + "mime, padding, line length: 5 delimiters: @$* %Base64 is %" -> "QmFz@$*ZTY0@$*IGlz@$*IA==", + "mime, padding, line length: 5 delimiters: @$* %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFz@$*ZTY0@$*IGlz@$*IGEg@$*Z3Jv@$*dXAg@$*b2Yg@$*c2lt@$*aWxh@$*ciBi@$*aW5h@$*cnkt@$*dG8t@$*dGV4@$*dCBl@$*bmNv@$*ZGlu@$*ZyBz@$*Y2hl@$*bWVz@$*IHRo@$*YXQg@$*cmVw@$*cmVz@$*ZW50@$*IGJp@$*bmFy@$*eSBk@$*YXRh@$*IGlu@$*IGFu@$*IEFT@$*Q0lJ@$*IHN0@$*cmlu@$*ZyBm@$*b3Jt@$*YXQg@$*Ynkg@$*dHJh@$*bnNs@$*YXRp@$*bmcg@$*aXQg@$*aW50@$*byBh@$*IHJh@$*ZGl4@$*LTY0@$*IHJl@$*cHJl@$*c2Vu@$*dGF0@$*aW9u", + "mime, padding, line length: 9 delimiters: @$* %B%" -> "Qg==", + "mime, padding, line length: 9 delimiters: @$* %Ba%" -> "QmE=", + "mime, padding, line length: 9 delimiters: @$* %Bas%" -> "QmFz", + "mime, padding, line length: 9 delimiters: @$* %Base%" -> "QmFzZQ==", + "mime, padding, line length: 9 delimiters: @$* %Base64 is %" -> "QmFzZTY0@$*IGlzIA==", + "mime, padding, line length: 9 delimiters: @$* %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0@$*IGlzIGEg@$*Z3JvdXAg@$*b2Ygc2lt@$*aWxhciBi@$*aW5hcnkt@$*dG8tdGV4@$*dCBlbmNv@$*ZGluZyBz@$*Y2hlbWVz@$*IHRoYXQg@$*cmVwcmVz@$*ZW50IGJp@$*bmFyeSBk@$*YXRhIGlu@$*IGFuIEFT@$*Q0lJIHN0@$*cmluZyBm@$*b3JtYXQg@$*YnkgdHJh@$*bnNsYXRp@$*bmcgaXQg@$*aW50byBh@$*IHJhZGl4@$*LTY0IHJl@$*cHJlc2Vu@$*dGF0aW9u", + "mime, no padding, line length: -1 delimiters: %B%" -> "Qg", + "mime, no padding, line length: -1 delimiters: %Ba%" -> "QmE", + "mime, no padding, line length: -1 delimiters: %Bas%" -> "QmFz", + "mime, no padding, line length: -1 delimiters: %Base%" -> "QmFzZQ", + "mime, no padding, line length: -1 delimiters: %Base64 is %" -> "QmFzZTY0IGlzIA", + "mime, no padding, line length: -1 delimiters: %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "mime, no padding, line length: 0 delimiters: %B%" -> "Qg", + "mime, no padding, line length: 0 delimiters: %Ba%" -> "QmE", + "mime, no padding, line length: 0 delimiters: %Bas%" -> "QmFz", + "mime, no padding, line length: 0 delimiters: %Base%" -> "QmFzZQ", + "mime, no padding, line length: 0 delimiters: %Base64 is %" -> "QmFzZTY0IGlzIA", + "mime, no padding, line length: 0 delimiters: %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "mime, no padding, line length: 4 delimiters: %B%" -> "Qg", + "mime, no padding, line length: 4 delimiters: %Ba%" -> "QmE", + "mime, no padding, line length: 4 delimiters: %Bas%" -> "QmFz", + "mime, no padding, line length: 4 delimiters: %Base%" -> "QmFzZQ", + "mime, no padding, line length: 4 delimiters: %Base64 is %" -> "QmFzZTY0IGlzIA", + "mime, no padding, line length: 4 delimiters: %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "mime, no padding, line length: 5 delimiters: %B%" -> "Qg", + "mime, no padding, line length: 5 delimiters: %Ba%" -> "QmE", + "mime, no padding, line length: 5 delimiters: %Bas%" -> "QmFz", + "mime, no padding, line length: 5 delimiters: %Base%" -> "QmFzZQ", + "mime, no padding, line length: 5 delimiters: %Base64 is %" -> "QmFzZTY0IGlzIA", + "mime, no padding, line length: 5 delimiters: %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "mime, no padding, line length: 9 delimiters: %B%" -> "Qg", + "mime, no padding, line length: 9 delimiters: %Ba%" -> "QmE", + "mime, no padding, line length: 9 delimiters: %Bas%" -> "QmFz", + "mime, no padding, line length: 9 delimiters: %Base%" -> "QmFzZQ", + "mime, no padding, line length: 9 delimiters: %Base64 is %" -> "QmFzZTY0IGlzIA", + "mime, no padding, line length: 9 delimiters: %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "mime, no padding, line length: -1 delimiters: @ %B%" -> "Qg", + "mime, no padding, line length: -1 delimiters: @ %Ba%" -> "QmE", + "mime, no padding, line length: -1 delimiters: @ %Bas%" -> "QmFz", + "mime, no padding, line length: -1 delimiters: @ %Base%" -> "QmFzZQ", + "mime, no padding, line length: -1 delimiters: @ %Base64 is %" -> "QmFzZTY0IGlzIA", + "mime, no padding, line length: -1 delimiters: @ %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "mime, no padding, line length: 0 delimiters: @ %B%" -> "Qg", + "mime, no padding, line length: 0 delimiters: @ %Ba%" -> "QmE", + "mime, no padding, line length: 0 delimiters: @ %Bas%" -> "QmFz", + "mime, no padding, line length: 0 delimiters: @ %Base%" -> "QmFzZQ", + "mime, no padding, line length: 0 delimiters: @ %Base64 is %" -> "QmFzZTY0IGlzIA", + "mime, no padding, line length: 0 delimiters: @ %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "mime, no padding, line length: 4 delimiters: @ %B%" -> "Qg", + "mime, no padding, line length: 4 delimiters: @ %Ba%" -> "QmE", + "mime, no padding, line length: 4 delimiters: @ %Bas%" -> "QmFz", + "mime, no padding, line length: 4 delimiters: @ %Base%" -> "QmFz@ZQ", + "mime, no padding, line length: 4 delimiters: @ %Base64 is %" -> "QmFz@ZTY0@IGlz@IA", + "mime, no padding, line length: 4 delimiters: @ %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFz@ZTY0@IGlz@IGEg@Z3Jv@dXAg@b2Yg@c2lt@aWxh@ciBi@aW5h@cnkt@dG8t@dGV4@dCBl@bmNv@ZGlu@ZyBz@Y2hl@bWVz@IHRo@YXQg@cmVw@cmVz@ZW50@IGJp@bmFy@eSBk@YXRh@IGlu@IGFu@IEFT@Q0lJ@IHN0@cmlu@ZyBm@b3Jt@YXQg@Ynkg@dHJh@bnNs@YXRp@bmcg@aXQg@aW50@byBh@IHJh@ZGl4@LTY0@IHJl@cHJl@c2Vu@dGF0@aW9u", + "mime, no padding, line length: 5 delimiters: @ %B%" -> "Qg", + "mime, no padding, line length: 5 delimiters: @ %Ba%" -> "QmE", + "mime, no padding, line length: 5 delimiters: @ %Bas%" -> "QmFz", + "mime, no padding, line length: 5 delimiters: @ %Base%" -> "QmFz@ZQ", + "mime, no padding, line length: 5 delimiters: @ %Base64 is %" -> "QmFz@ZTY0@IGlz@IA", + "mime, no padding, line length: 5 delimiters: @ %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFz@ZTY0@IGlz@IGEg@Z3Jv@dXAg@b2Yg@c2lt@aWxh@ciBi@aW5h@cnkt@dG8t@dGV4@dCBl@bmNv@ZGlu@ZyBz@Y2hl@bWVz@IHRo@YXQg@cmVw@cmVz@ZW50@IGJp@bmFy@eSBk@YXRh@IGlu@IGFu@IEFT@Q0lJ@IHN0@cmlu@ZyBm@b3Jt@YXQg@Ynkg@dHJh@bnNs@YXRp@bmcg@aXQg@aW50@byBh@IHJh@ZGl4@LTY0@IHJl@cHJl@c2Vu@dGF0@aW9u", + "mime, no padding, line length: 9 delimiters: @ %B%" -> "Qg", + "mime, no padding, line length: 9 delimiters: @ %Ba%" -> "QmE", + "mime, no padding, line length: 9 delimiters: @ %Bas%" -> "QmFz", + "mime, no padding, line length: 9 delimiters: @ %Base%" -> "QmFzZQ", + "mime, no padding, line length: 9 delimiters: @ %Base64 is %" -> "QmFzZTY0@IGlzIA", + "mime, no padding, line length: 9 delimiters: @ %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0@IGlzIGEg@Z3JvdXAg@b2Ygc2lt@aWxhciBi@aW5hcnkt@dG8tdGV4@dCBlbmNv@ZGluZyBz@Y2hlbWVz@IHRoYXQg@cmVwcmVz@ZW50IGJp@bmFyeSBk@YXRhIGlu@IGFuIEFT@Q0lJIHN0@cmluZyBm@b3JtYXQg@YnkgdHJh@bnNsYXRp@bmcgaXQg@aW50byBh@IHJhZGl4@LTY0IHJl@cHJlc2Vu@dGF0aW9u", + "mime, no padding, line length: -1 delimiters: @$ %B%" -> "Qg", + "mime, no padding, line length: -1 delimiters: @$ %Ba%" -> "QmE", + "mime, no padding, line length: -1 delimiters: @$ %Bas%" -> "QmFz", + "mime, no padding, line length: -1 delimiters: @$ %Base%" -> "QmFzZQ", + "mime, no padding, line length: -1 delimiters: @$ %Base64 is %" -> "QmFzZTY0IGlzIA", + "mime, no padding, line length: -1 delimiters: @$ %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "mime, no padding, line length: 0 delimiters: @$ %B%" -> "Qg", + "mime, no padding, line length: 0 delimiters: @$ %Ba%" -> "QmE", + "mime, no padding, line length: 0 delimiters: @$ %Bas%" -> "QmFz", + "mime, no padding, line length: 0 delimiters: @$ %Base%" -> "QmFzZQ", + "mime, no padding, line length: 0 delimiters: @$ %Base64 is %" -> "QmFzZTY0IGlzIA", + "mime, no padding, line length: 0 delimiters: @$ %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "mime, no padding, line length: 4 delimiters: @$ %B%" -> "Qg", + "mime, no padding, line length: 4 delimiters: @$ %Ba%" -> "QmE", + "mime, no padding, line length: 4 delimiters: @$ %Bas%" -> "QmFz", + "mime, no padding, line length: 4 delimiters: @$ %Base%" -> "QmFz@$ZQ", + "mime, no padding, line length: 4 delimiters: @$ %Base64 is %" -> "QmFz@$ZTY0@$IGlz@$IA", + "mime, no padding, line length: 4 delimiters: @$ %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFz@$ZTY0@$IGlz@$IGEg@$Z3Jv@$dXAg@$b2Yg@$c2lt@$aWxh@$ciBi@$aW5h@$cnkt@$dG8t@$dGV4@$dCBl@$bmNv@$ZGlu@$ZyBz@$Y2hl@$bWVz@$IHRo@$YXQg@$cmVw@$cmVz@$ZW50@$IGJp@$bmFy@$eSBk@$YXRh@$IGlu@$IGFu@$IEFT@$Q0lJ@$IHN0@$cmlu@$ZyBm@$b3Jt@$YXQg@$Ynkg@$dHJh@$bnNs@$YXRp@$bmcg@$aXQg@$aW50@$byBh@$IHJh@$ZGl4@$LTY0@$IHJl@$cHJl@$c2Vu@$dGF0@$aW9u", + "mime, no padding, line length: 5 delimiters: @$ %B%" -> "Qg", + "mime, no padding, line length: 5 delimiters: @$ %Ba%" -> "QmE", + "mime, no padding, line length: 5 delimiters: @$ %Bas%" -> "QmFz", + "mime, no padding, line length: 5 delimiters: @$ %Base%" -> "QmFz@$ZQ", + "mime, no padding, line length: 5 delimiters: @$ %Base64 is %" -> "QmFz@$ZTY0@$IGlz@$IA", + "mime, no padding, line length: 5 delimiters: @$ %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFz@$ZTY0@$IGlz@$IGEg@$Z3Jv@$dXAg@$b2Yg@$c2lt@$aWxh@$ciBi@$aW5h@$cnkt@$dG8t@$dGV4@$dCBl@$bmNv@$ZGlu@$ZyBz@$Y2hl@$bWVz@$IHRo@$YXQg@$cmVw@$cmVz@$ZW50@$IGJp@$bmFy@$eSBk@$YXRh@$IGlu@$IGFu@$IEFT@$Q0lJ@$IHN0@$cmlu@$ZyBm@$b3Jt@$YXQg@$Ynkg@$dHJh@$bnNs@$YXRp@$bmcg@$aXQg@$aW50@$byBh@$IHJh@$ZGl4@$LTY0@$IHJl@$cHJl@$c2Vu@$dGF0@$aW9u", + "mime, no padding, line length: 9 delimiters: @$ %B%" -> "Qg", + "mime, no padding, line length: 9 delimiters: @$ %Ba%" -> "QmE", + "mime, no padding, line length: 9 delimiters: @$ %Bas%" -> "QmFz", + "mime, no padding, line length: 9 delimiters: @$ %Base%" -> "QmFzZQ", + "mime, no padding, line length: 9 delimiters: @$ %Base64 is %" -> "QmFzZTY0@$IGlzIA", + "mime, no padding, line length: 9 delimiters: @$ %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0@$IGlzIGEg@$Z3JvdXAg@$b2Ygc2lt@$aWxhciBi@$aW5hcnkt@$dG8tdGV4@$dCBlbmNv@$ZGluZyBz@$Y2hlbWVz@$IHRoYXQg@$cmVwcmVz@$ZW50IGJp@$bmFyeSBk@$YXRhIGlu@$IGFuIEFT@$Q0lJIHN0@$cmluZyBm@$b3JtYXQg@$YnkgdHJh@$bnNsYXRp@$bmcgaXQg@$aW50byBh@$IHJhZGl4@$LTY0IHJl@$cHJlc2Vu@$dGF0aW9u", + "mime, no padding, line length: -1 delimiters: @$* %B%" -> "Qg", + "mime, no padding, line length: -1 delimiters: @$* %Ba%" -> "QmE", + "mime, no padding, line length: -1 delimiters: @$* %Bas%" -> "QmFz", + "mime, no padding, line length: -1 delimiters: @$* %Base%" -> "QmFzZQ", + "mime, no padding, line length: -1 delimiters: @$* %Base64 is %" -> "QmFzZTY0IGlzIA", + "mime, no padding, line length: -1 delimiters: @$* %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "mime, no padding, line length: 0 delimiters: @$* %B%" -> "Qg", + "mime, no padding, line length: 0 delimiters: @$* %Ba%" -> "QmE", + "mime, no padding, line length: 0 delimiters: @$* %Bas%" -> "QmFz", + "mime, no padding, line length: 0 delimiters: @$* %Base%" -> "QmFzZQ", + "mime, no padding, line length: 0 delimiters: @$* %Base64 is %" -> "QmFzZTY0IGlzIA", + "mime, no padding, line length: 0 delimiters: @$* %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0IGlzIGEgZ3JvdXAgb2Ygc2ltaWxhciBiaW5hcnktdG8tdGV4dCBlbmNvZGluZyBzY2hlbWVzIHRoYXQgcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGFuIEFTQ0lJIHN0cmluZyBmb3JtYXQgYnkgdHJhbnNsYXRpbmcgaXQgaW50byBhIHJhZGl4LTY0IHJlcHJlc2VudGF0aW9u", + "mime, no padding, line length: 4 delimiters: @$* %B%" -> "Qg", + "mime, no padding, line length: 4 delimiters: @$* %Ba%" -> "QmE", + "mime, no padding, line length: 4 delimiters: @$* %Bas%" -> "QmFz", + "mime, no padding, line length: 4 delimiters: @$* %Base%" -> "QmFz@$*ZQ", + "mime, no padding, line length: 4 delimiters: @$* %Base64 is %" -> "QmFz@$*ZTY0@$*IGlz@$*IA", + "mime, no padding, line length: 4 delimiters: @$* %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFz@$*ZTY0@$*IGlz@$*IGEg@$*Z3Jv@$*dXAg@$*b2Yg@$*c2lt@$*aWxh@$*ciBi@$*aW5h@$*cnkt@$*dG8t@$*dGV4@$*dCBl@$*bmNv@$*ZGlu@$*ZyBz@$*Y2hl@$*bWVz@$*IHRo@$*YXQg@$*cmVw@$*cmVz@$*ZW50@$*IGJp@$*bmFy@$*eSBk@$*YXRh@$*IGlu@$*IGFu@$*IEFT@$*Q0lJ@$*IHN0@$*cmlu@$*ZyBm@$*b3Jt@$*YXQg@$*Ynkg@$*dHJh@$*bnNs@$*YXRp@$*bmcg@$*aXQg@$*aW50@$*byBh@$*IHJh@$*ZGl4@$*LTY0@$*IHJl@$*cHJl@$*c2Vu@$*dGF0@$*aW9u", + "mime, no padding, line length: 5 delimiters: @$* %B%" -> "Qg", + "mime, no padding, line length: 5 delimiters: @$* %Ba%" -> "QmE", + "mime, no padding, line length: 5 delimiters: @$* %Bas%" -> "QmFz", + "mime, no padding, line length: 5 delimiters: @$* %Base%" -> "QmFz@$*ZQ", + "mime, no padding, line length: 5 delimiters: @$* %Base64 is %" -> "QmFz@$*ZTY0@$*IGlz@$*IA", + "mime, no padding, line length: 5 delimiters: @$* %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFz@$*ZTY0@$*IGlz@$*IGEg@$*Z3Jv@$*dXAg@$*b2Yg@$*c2lt@$*aWxh@$*ciBi@$*aW5h@$*cnkt@$*dG8t@$*dGV4@$*dCBl@$*bmNv@$*ZGlu@$*ZyBz@$*Y2hl@$*bWVz@$*IHRo@$*YXQg@$*cmVw@$*cmVz@$*ZW50@$*IGJp@$*bmFy@$*eSBk@$*YXRh@$*IGlu@$*IGFu@$*IEFT@$*Q0lJ@$*IHN0@$*cmlu@$*ZyBm@$*b3Jt@$*YXQg@$*Ynkg@$*dHJh@$*bnNs@$*YXRp@$*bmcg@$*aXQg@$*aW50@$*byBh@$*IHJh@$*ZGl4@$*LTY0@$*IHJl@$*cHJl@$*c2Vu@$*dGF0@$*aW9u", + "mime, no padding, line length: 9 delimiters: @$* %B%" -> "Qg", + "mime, no padding, line length: 9 delimiters: @$* %Ba%" -> "QmE", + "mime, no padding, line length: 9 delimiters: @$* %Bas%" -> "QmFz", + "mime, no padding, line length: 9 delimiters: @$* %Base%" -> "QmFzZQ", + "mime, no padding, line length: 9 delimiters: @$* %Base64 is %" -> "QmFzZTY0@$*IGlzIA", + "mime, no padding, line length: 9 delimiters: @$* %Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation%" -> "QmFzZTY0@$*IGlzIGEg@$*Z3JvdXAg@$*b2Ygc2lt@$*aWxhciBi@$*aW5hcnkt@$*dG8tdGV4@$*dCBlbmNv@$*ZGluZyBz@$*Y2hlbWVz@$*IHRoYXQg@$*cmVwcmVz@$*ZW50IGJp@$*bmFyeSBk@$*YXRhIGlu@$*IGFuIEFT@$*Q0lJIHN0@$*cmluZyBm@$*b3JtYXQg@$*YnkgdHJh@$*bnNsYXRp@$*bmcgaXQg@$*aW50byBh@$*IHJhZGl4@$*LTY0IHJl@$*cHJlc2Vu@$*dGF0aW9u" + ) + // scalastyle:on line.size.limit +} From 48984ddeb359ef70b68764c6ac57c7d35250c87e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 7 Apr 2017 15:44:22 +0200 Subject: [PATCH 0197/2665] Fix #2855: Deprecate CrossProject.settingSets. --- .../scala/org/scalajs/sbtplugin/cross/CrossProject.scala | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossProject.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossProject.scala index d832abb117..7017118195 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossProject.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossProject.scala @@ -275,6 +275,11 @@ final class CrossProject private ( * * Note: If you disable AutoPlugins here, Scala.js will not work */ + @deprecated( + "Project#settingSets will be removed from sbt 1.0, hence " + + "CrossProject#settingSets will be removed from Scala.js 1.0. " + + "As a temporary measure, use `.configureAll(_.settingSets(select))`.", + "0.6.16") def settingSets(select: AddSettings*): CrossProject = copy(jvm.settingSets(select: _*), js.settingSets(select: _*)) From e16ae09b8389b41621653eae95f107382b84507b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 7 Apr 2017 16:07:21 +0200 Subject: [PATCH 0198/2665] Fix #2808: Handle long strings in DataInputStream. By "long" strings we mean strings whose encoded byte length is greater than `Short.MaxValue`, for which the length must be read as an unsigned short. Also, make sure that DataOutputStream throws for strings whose encoded byte length is `>= 0x10000`. --- .../src/main/scala/java/io/DataInputStream.scala | 2 +- .../src/main/scala/java/io/DataOutputStream.scala | 4 ++++ .../javalib/io/DataInputStreamTest.scala | 15 +++++++++++++++ .../javalib/io/DataOutputStreamTest.scala | 14 ++++++++++++++ 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/javalib/src/main/scala/java/io/DataInputStream.scala b/javalib/src/main/scala/java/io/DataInputStream.scala index 1473a9f07e..6165d8e359 100644 --- a/javalib/src/main/scala/java/io/DataInputStream.scala +++ b/javalib/src/main/scala/java/io/DataInputStream.scala @@ -144,7 +144,7 @@ class DataInputStream(in: InputStream) extends FilterInputStream(in) } def readUTF(): String = { - val length = readShort() + val length = readUnsignedShort() var res = "" var i = 0 diff --git a/javalib/src/main/scala/java/io/DataOutputStream.scala b/javalib/src/main/scala/java/io/DataOutputStream.scala index 70b49d060c..b6acc5b561 100644 --- a/javalib/src/main/scala/java/io/DataOutputStream.scala +++ b/javalib/src/main/scala/java/io/DataOutputStream.scala @@ -84,6 +84,10 @@ class DataOutputStream(out: OutputStream) } val len = idx - 2 + + if (len >= 0x10000) + throw new UTFDataFormatException(s"encoded string too long: $len bytes") + buffer(0) = (len >> 8).toByte buffer(1) = len.toByte diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/DataInputStreamTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/DataInputStreamTest.scala index d068642b2e..22975c8532 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/DataInputStreamTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/DataInputStreamTest.scala @@ -284,6 +284,21 @@ trait DataInputStreamTest { assertThrows(classOf[UTFDataFormatException], badStream.readUTF) } + @Test def readUTF_with_very_long_string(): Unit = { + val length = 40000 + val inputBytes = new Array[Byte](2 + length) + inputBytes(0) = (length >> 8).toByte + inputBytes(1) = length.toByte + for (i <- 2 until (2 + length)) + inputBytes(i) = 'a'.toByte + + val stream = new DataInputStream(new ByteArrayInputStream(inputBytes)) + val result = stream.readUTF() + assertEquals(length, result.length) + assertTrue(result.forall(_ == 'a')) + assertEquals(-1, stream.read()) + } + @Test def should_provide_readLine(): Unit = { val stream = newStream( "Hello World\nUNIX\nWindows\r\nMac (old)\rStuff".map(_.toInt): _*) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/DataOutputStreamTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/DataOutputStreamTest.scala index 0a32fcfa72..e2a79b12c5 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/DataOutputStreamTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/DataOutputStreamTest.scala @@ -5,6 +5,8 @@ import java.io._ import org.junit._ import org.junit.Assert._ +import org.scalajs.testsuite.utils.AssertThrows._ + object DataOutputStreamTest { class DataOutputStreamWrittenAccess(out: OutputStream) extends DataOutputStream(out) { @@ -274,4 +276,16 @@ class DataOutputStreamTest { 0xa9, 0x00, 0x03, 0xe6, 0x84, 0x9b ) } + + @Test def writeUTFTooLong(): Unit = { + val (stream, checker) = newStream() + + var longString = "aaa" + while (longString.length < 0x10000) + longString = longString + longString + + assertThrows(classOf[UTFDataFormatException], { + stream.writeUTF(longString) + }) + } } From 808fb7c3d3f56b0c1ba97bab6610c9d13f53722a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 7 Apr 2017 16:35:46 +0200 Subject: [PATCH 0199/2665] Fix #2780: Reach all methods of j.l.Integer before the optimizer. This was already partially fixed in 10997e9b04eb1a82225f85975073a64c09982448, which was a fix for `compareTo(Short)` were affected. #2780 shows that all methods of `java.lang.Integer` are affected, in fact, so this commit extends the existing fix to all methods. Note that the methods still disappear after the refiner if they are not needed, and anyway they are all hijacked as helpers, so the quality of DCE is not affected by this fix. There is no additional test, because the warnings could already be observed before, but as warnings, they did not fail the build. --- .../frontend/optimizer/GenIncOptimizer.scala | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala index 35f29309e7..e5bfbd227f 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala @@ -52,8 +52,25 @@ abstract class GenIncOptimizer private[optimizer] (semantics: Semantics, callMethods(LongImpl.RuntimeLongClass, LongImpl.AllIntrinsicMethods) ++ optional(callMethods(LongImpl.RuntimeLongClass, LongImpl.OptionalIntrinsicMethods)) ++ - callMethods(Definitions.BoxedIntegerClass, - Seq("compareTo__jl_Byte__I", "compareTo__jl_Short__I")) ++ // #2184 + /* #2184 + #2780: we need to keep all methods of j.l.Integer, in case + * the corresponding methods are called on j.l.Byte or j.l.Short, and + * through optimizations become calls on j.l.Integer. + */ + callMethods(Definitions.BoxedIntegerClass, Seq( + "byteValue__B", + "shortValue__S", + "intValue__I", + "longValue__J", + "floatValue__F", + "doubleValue__D", + "equals__O__Z", + "hashCode__I", + "compareTo__jl_Integer__I", + "toString__T", + "compareTo__jl_Byte__I", + "compareTo__jl_Short__I", + "compareTo__O__I" + )) ++ instantiateClass("jl_NullPointerException", "init___") } From 24669a15d7d1d711ef1b95518e37eb435b901116 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 7 Apr 2017 19:54:16 +0200 Subject: [PATCH 0200/2665] Fix #2871: Restore testing of JSDOMNodeJSEnv. Tests were accidentally removed in 45203508e4406ba7d8d8aa9871536e2413027b5e. --- ci/matrix.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ci/matrix.xml b/ci/matrix.xml index d51e6c8e77..dafcd6ba29 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -19,9 +19,9 @@ sbtretry 'set scalaJSStage in Global := FullOptStage' \ ++$scala helloworld/run \ helloworld/clean && - sbtretry 'set jsEnv in helloworld := new org.scalajs.jsenv.nodejs.NodeJSEnv' \ + sbtretry 'set jsEnv in helloworld := new org.scalajs.jsenv.nodejs.JSDOMNodeJSEnv' \ ++$scala helloworld/run && - sbtretry 'set jsEnv in helloworld := new org.scalajs.jsenv.nodejs.NodeJSEnv' \ + sbtretry 'set jsEnv in helloworld := new org.scalajs.jsenv.nodejs.JSDOMNodeJSEnv' \ 'set scalaJSStage in Global := FullOptStage' \ ++$scala helloworld/run \ helloworld/clean && @@ -84,9 +84,9 @@ sbtretry 'set scalaJSStage in Global := FullOptStage' \ ++$scala $testSuite/test \ $testSuite/clean && - sbtretry 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv' \ + sbtretry 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.JSDOMNodeJSEnv' \ ++$scala $testSuite/test && - sbtretry 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv' \ + sbtretry 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.JSDOMNodeJSEnv' \ 'set scalaJSStage in Global := FullOptStage' \ ++$scala $testSuite/test \ $testSuite/clean && From 83797a145751437cf33ca87408a4f2417a07d0fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 8 Apr 2017 10:29:04 +0200 Subject: [PATCH 0201/2665] Unify the parameter names of external JS env constructors. They all standardize on `executable`, `args` en `env`, which are the names used by the `Initialize` constructors in `ScalaJSPlugin`. --- .../org/scalajs/jsenv/ExternalJSEnv.scala | 22 +++++++++---- .../jsenv/nodejs/AbstractNodeJSEnv.scala | 14 +++++--- .../scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala | 11 ++++--- .../org/scalajs/jsenv/nodejs/NodeJSEnv.scala | 32 +++++++++++-------- .../jsenv/phantomjs/PhantomJSEnv.scala | 12 ++++--- 5 files changed, 57 insertions(+), 34 deletions(-) diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala index a19ed6e3e4..d58bc6cfec 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala @@ -11,8 +11,11 @@ import scala.concurrent.{Future, Promise} import scala.util.Try abstract class ExternalJSEnv( - final protected val additionalArgs: Seq[String], - final protected val additionalEnv: Map[String, String]) extends AsyncJSEnv { + @deprecatedName('additionalArgs) + final protected val args: Seq[String], + @deprecatedName('additionalEnv) + final protected val env: Map[String, String]) + extends AsyncJSEnv { import ExternalJSEnv._ @@ -24,6 +27,12 @@ abstract class ExternalJSEnv( /** Command to execute (on shell) for this VM */ protected def executable: String + @deprecated("Use `args` instead.", "0.6.16") + final protected def additionalArgs: Seq[String] = args + + @deprecated("Use `env` instead.", "0.6.16") + final protected def additionalEnv: Map[String, String] = env + /** Custom initialization scripts. */ protected def customInitFiles(): Seq[VirtualJSFile] = Nil @@ -51,16 +60,17 @@ abstract class ExternalJSEnv( protected def sendVMStdin(out: OutputStream): Unit = {} /** VM arguments excluding executable. Override to adapt. - * Overrider is responsible to add additionalArgs. + * + * The default value in `ExternalJSEnv` is `args`. */ - protected def getVMArgs(): Seq[String] = additionalArgs + protected def getVMArgs(): Seq[String] = args /** VM environment. Override to adapt. * - * Default is `sys.env` and [[additionalEnv]] + * The default value in `ExternalJSEnv` is `sys.env ++ env`. */ protected def getVMEnv(): Map[String, String] = - sys.env ++ additionalEnv + sys.env ++ env /** Get files that are a library (i.e. that do not run anything) */ protected def getLibJSFiles(): Seq[VirtualJSFile] = diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala index d0047c5391..a5304b63e5 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala @@ -22,9 +22,15 @@ import org.scalajs.jsenv.Utils.OptDeadline import scala.concurrent.TimeoutException import scala.concurrent.duration._ -abstract class AbstractNodeJSEnv(nodejsPath: String, addArgs: Seq[String], - addEnv: Map[String, String], val sourceMap: Boolean) - extends ExternalJSEnv(addArgs, addEnv) with ComJSEnv { +abstract class AbstractNodeJSEnv( + @deprecatedName('nodejsPath) + protected val executable: String, + @deprecatedName('addArgs) + args: Seq[String], + @deprecatedName('addEnv) + env: Map[String, String], + val sourceMap: Boolean) + extends ExternalJSEnv(args, env) with ComJSEnv { /** True, if the installed node executable supports source mapping. * @@ -43,8 +49,6 @@ abstract class AbstractNodeJSEnv(nodejsPath: String, addArgs: Seq[String], } } - protected def executable: String = nodejsPath - /** Retry-timeout to wait for the JS VM to connect */ protected val acceptTimeout = 5000 diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala index cc0d4cc530..4da372ea41 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala @@ -18,10 +18,13 @@ import org.scalajs.jsenv._ import org.scalajs.core.ir.Utils.escapeJS class JSDOMNodeJSEnv( - nodejsPath: String = "node", - addArgs: Seq[String] = Seq.empty, - addEnv: Map[String, String] = Map.empty -) extends AbstractNodeJSEnv(nodejsPath, addArgs, addEnv, sourceMap = false) { + @deprecatedName('nodejsPath) + executable: String = "node", + @deprecatedName('addArgs) + args: Seq[String] = Seq.empty, + @deprecatedName('addEnv) + env: Map[String, String] = Map.empty) + extends AbstractNodeJSEnv(executable, args, env, sourceMap = false) { protected def vmName: String = "Node.js with JSDOM" diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala index 5f01785ea7..8bc26f49cd 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala @@ -19,27 +19,31 @@ import org.scalajs.core.tools.logging._ import java.io.{ Console => _, _ } - class NodeJSEnv private ( - nodejsPath: String, - addArgs: Seq[String], - addEnv: Map[String, String], - sourceMap: Boolean -) extends AbstractNodeJSEnv(nodejsPath, addArgs, addEnv, sourceMap) { - - def this(nodejsPath: String = "node", addArgs: Seq[String] = Seq.empty, - addEnv: Map[String, String] = Map.empty) = { - this(nodejsPath, addArgs, addEnv, sourceMap = true) + @deprecatedName('nodejsPath) + override protected val executable: String, // override val for bin compat + @deprecatedName('addArgs) + args: Seq[String], + @deprecatedName('addEnv) + env: Map[String, String], + sourceMap: Boolean) + extends AbstractNodeJSEnv(executable, args, env, sourceMap) { + + def this( + @deprecatedName('nodejsPath) + executable: String = "node", + @deprecatedName('addArgs) + args: Seq[String] = Seq.empty, + @deprecatedName('addEnv) + env: Map[String, String] = Map.empty) = { + this(executable, args, env, sourceMap = true) } def withSourceMap(sourceMap: Boolean): NodeJSEnv = - new NodeJSEnv(nodejsPath, addArgs, addEnv, sourceMap) + new NodeJSEnv(executable, args, env, sourceMap) protected def vmName: String = "Node.js" - // For binary compatibility, now `executable` is defined in AbstractNodeJSEnv - override protected def executable: String = super.executable - override def jsRunner(libs: Seq[ResolvedJSDependency], code: VirtualJSFile): JSRunner = { new NodeRunner(libs, code) diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala index 4aaf1a2866..239aa4b37d 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala @@ -29,17 +29,19 @@ import scala.concurrent.{ExecutionContext, TimeoutException, Future} import scala.concurrent.duration.Duration class PhantomJSEnv( - phantomjsPath: String = "phantomjs", - addArgs: Seq[String] = Seq.empty, - addEnv: Map[String, String] = Map.empty, + @deprecatedName('phantomjsPath) + protected val executable: String = "phantomjs", + @deprecatedName('addArgs) + args: Seq[String] = Seq.empty, + @deprecatedName('addEnv) + env: Map[String, String] = Map.empty, val autoExit: Boolean = true, jettyClassLoader: ClassLoader = null -) extends ExternalJSEnv(addArgs, addEnv) with ComJSEnv { +) extends ExternalJSEnv(args, env) with ComJSEnv { import PhantomJSEnv._ protected def vmName: String = "PhantomJS" - protected def executable: String = phantomjsPath override def jsRunner(libs: Seq[ResolvedJSDependency], code: VirtualJSFile): JSRunner = { From b79a605723644463f2f1e3488d2ab934694b3217 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 7 Apr 2017 19:40:56 +0200 Subject: [PATCH 0202/2665] Deprecate NodeJSEnv().value and JSDOMNodeJSEnv().value. The constructors `new NodeJSEnv()` and `new JSDOMNodeJSEnv()` should be used instead. Those `Initialize` constructors were added to be consistent with `RhinoJSEnv().value` (which needs `scalaJSLinker.value` and `scalaJSRequestsDOM.value`) and `PhantomJSEnv().value` (which needs `scalaJSPhantomJSClassLoader.value`). However, as Rhino is deprecated, and PhantomJS will move in its own repo, it doesn't make any sense to keep being consistent. Moreover, `JSDOMNodeJSEnv` will also move to its own repo, and won't even provide a companion sbt plugin (because there is no need to), so `JSDOMNodeJSEnv().value` would have nowhere to go, breaking the consistency anyway. --- ci/matrix.xml | 22 +++++++++---------- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 7 ++++++ .../sbtplugin/ScalaJSPluginInternal.scala | 4 ++-- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/ci/matrix.xml b/ci/matrix.xml index 728e18b5b4..9878d0421e 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -156,46 +156,46 @@ diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 5e1826504d..87d4b02f0e 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -113,6 +113,9 @@ object ScalaJSPlugin extends AutoPlugin { * case) or scope it manually, using * [[sbt.ProjectExtra.inScope[* Project.inScope]]. */ + @deprecated( + "Use `jsEnv := new org.scalajs.jsenv.nodejs.NodeJSEnv(...)` instead.", + "0.6.16") def NodeJSEnv( executable: String = "node", args: Seq[String] = Seq.empty, @@ -137,6 +140,10 @@ object ScalaJSPlugin extends AutoPlugin { * case) or scope it manually, using * [[sbt.ProjectExtra.inScope[* Project.inScope]]. */ + @deprecated( + "Use `jsEnv := new org.scalajs.jsenv.nodejs.JSDOMNodeJSEnv(...)` " + + "instead.", + "0.6.16") def JSDOMNodeJSEnv( executable: String = "node", args: Seq[String] = Seq.empty, diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 7719b601b0..9cd93942bd 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -605,9 +605,9 @@ object ScalaJSPluginInternal { if (scalaJSUseRhinoInternal.value) { RhinoJSEnvInternal().value } else if (scalaJSRequestsDOM.value) { - JSDOMNodeJSEnv().value + new org.scalajs.jsenv.nodejs.JSDOMNodeJSEnv() } else { - NodeJSEnv().value + new org.scalajs.jsenv.nodejs.NodeJSEnv() } }, From cc9b478cfa85e0984dc32b386d5b866482209fd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 9 Apr 2017 10:56:37 +0200 Subject: [PATCH 0203/2665] Fix #2880: Use our own definition of Sys_error. In https://github.com/scala/scala/pull/5830, the definition of `Sys_error` was removed from `Definitions.scala`. This commit reintroduces it in our own codebase, as a quickfix to #2880. This will need to be revisited as part of #2876 not use `sys.error` at all, but that is less urgent. --- .../main/scala/org/scalajs/core/compiler/JSDefinitions.scala | 4 ++++ .../main/scala/org/scalajs/core/compiler/PrepJSInterop.scala | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 2421beeabe..9483da5a7b 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -138,6 +138,10 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val BoxesRunTime_boxToCharacter = getMemberMethod(BoxesRunTimeModule, newTermName("boxToCharacter")) lazy val BoxesRunTime_unboxToChar = getMemberMethod(BoxesRunTimeModule, newTermName("unboxToChar")) + // Copy-pasted from `Definitions.scala`, because it was removed in 2.13. + lazy val SysPackage = getPackageObject("scala.sys") + def Sys_error: Symbol = getMemberMethod(SysPackage, nme.error) + lazy val ReflectModule = getRequiredModule("scala.scalajs.reflect.Reflect") lazy val Reflect_registerLoadableModuleClass = getMemberMethod(ReflectModule, newTermName("registerLoadableModuleClass")) lazy val Reflect_registerInstantiatableClass = getMemberMethod(ReflectModule, newTermName("registerInstantiatableClass")) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 65be9f9625..fd3ae4a23c 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -1078,7 +1078,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent if (sym != JSPackage_native) { tree.rhs match { case Apply(trg, Literal(Constant("stub")) :: Nil) - if trg.symbol == definitions.Sys_error => + if trg.symbol == jsDefinitions.Sys_error => case _ => reporter.error(tree.pos, "The body of a primitive must be `sys.error(\"stub\")`.") From d7fd8a22e4520380af41c87cbd3e6a676e1b4d03 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 9 Apr 2017 20:14:38 +0200 Subject: [PATCH 0204/2665] Remove JUnitBootstrapTest JUnit bootstrapping is tested through every test of the test suite and the JUnit test suite itself. We remove the test because it is hard to support with the upcoming removal of runMain support combined with the existence of other module initializers in the test suite. --- ci/matrix.xml | 3 +-- .../scala/sbttest/multitest/JUnitUtil.scala | 21 ------------------- .../multitest/ScalaJSJUnitBootstrapTest.scala | 20 ------------------ .../testsuite/junit/JUnitBootstrapTest.scala | 20 ------------------ 4 files changed, 1 insertion(+), 63 deletions(-) delete mode 100644 sbt-plugin-test/multiTest/js/src/test/scala/sbttest/multitest/JUnitUtil.scala delete mode 100644 sbt-plugin-test/multiTest/js/src/test/scala/sbttest/multitest/ScalaJSJUnitBootstrapTest.scala delete mode 100644 test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitBootstrapTest.scala diff --git a/ci/matrix.xml b/ci/matrix.xml index dafcd6ba29..7ad2a560ee 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -62,7 +62,6 @@ ++$scala testingExample/test:run testingExample/test && sbtretry ++$scala library/test && sbtretry ++$scala testSuiteJVM/test testSuiteJVM/clean && - sbtretry ++$scala 'testSuite/test:runMain org.scalajs.testsuite.junit.JUnitBootstrapTest' && sbtretry ++$scala testSuite/test && sbtretry ++$scala testSuiteEx/test && sbtretry 'set scalaJSStage in Global := FullOptStage' \ @@ -244,7 +243,7 @@ cd sbt-plugin-test && sbt noDOM/run noDOM/testHtmlFastOpt noDOM/testHtmlFullOpt \ withDOM/run withDOM/testHtmlFastOpt withDOM/testHtmlFullOpt \ - multiTestJS/test:run multiTestJS/testHtmlFastOpt multiTestJS/testHtmlFullOpt \ + multiTestJS/testHtmlFastOpt multiTestJS/testHtmlFullOpt \ jetty9/run test \ jsDependenciesTest/packageJSDependencies \ jsDependenciesTest/packageMinifiedJSDependencies \ diff --git a/sbt-plugin-test/multiTest/js/src/test/scala/sbttest/multitest/JUnitUtil.scala b/sbt-plugin-test/multiTest/js/src/test/scala/sbttest/multitest/JUnitUtil.scala deleted file mode 100644 index 8369ca4c87..0000000000 --- a/sbt-plugin-test/multiTest/js/src/test/scala/sbttest/multitest/JUnitUtil.scala +++ /dev/null @@ -1,21 +0,0 @@ -package sbttest.multitest - -import org.scalajs.junit.JUnitTestBootstrapper -import org.junit.Assert.fail - -import scala.scalajs.reflect.Reflect - -object JUnitUtil { - private final val bootstrapperSuffix = "$scalajs$junit$bootstrapper" - - def loadBootstrapper(classFullName: String): JUnitTestBootstrapper = { - val fullName = s"$classFullName$bootstrapperSuffix" - try { - val modClass = Reflect.lookupLoadableModuleClass(fullName + "$").get - modClass.loadModule().asInstanceOf[JUnitTestBootstrapper] - } catch { - case ex: Throwable => - throw new AssertionError(s"could not load $fullName: ${ex.getMessage}") - } - } -} diff --git a/sbt-plugin-test/multiTest/js/src/test/scala/sbttest/multitest/ScalaJSJUnitBootstrapTest.scala b/sbt-plugin-test/multiTest/js/src/test/scala/sbttest/multitest/ScalaJSJUnitBootstrapTest.scala deleted file mode 100644 index 855a39de60..0000000000 --- a/sbt-plugin-test/multiTest/js/src/test/scala/sbttest/multitest/ScalaJSJUnitBootstrapTest.scala +++ /dev/null @@ -1,20 +0,0 @@ -package sbttest.multitest - -import scala.scalajs.js - -import org.junit.Test -import org.junit.Assert.assertTrue - -class JUnitBootstrapTest { - @Test def testClassBootstrap(): Unit = { - // This tests that the Scala.js JUnit runtime is working - assertTrue(true) - } -} - -object JUnitBootstrapTest extends js.JSApp { - def main(): Unit = { - // This should not fail - JUnitUtil.loadBootstrapper("sbttest.multitest.JUnitBootstrapTest") - } -} diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitBootstrapTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitBootstrapTest.scala deleted file mode 100644 index ff4e92d318..0000000000 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitBootstrapTest.scala +++ /dev/null @@ -1,20 +0,0 @@ -package org.scalajs.testsuite.junit - -import scala.scalajs.js - -import org.junit.Test -import org.junit.Assert.assertTrue - -class JUnitBootstrapTest { - @Test def testClassBootstrap(): Unit = { - // This tests that the Scala.js JUnit runtime is working - assertTrue(true) - } -} - -object JUnitBootstrapTest extends js.JSApp { - def main(): Unit = { - // This should not fail - JUnitUtil.loadBootstrapper("org.scalajs.testsuite.junit.JUnitBootstrapTest") - } -} From fe075d77e0e07967a9e39711a22e240642c39aa3 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 9 Apr 2017 23:40:03 +0200 Subject: [PATCH 0205/2665] Remove testingExample TestMain We won't be able to support it once we drop non-module launchers. --- ci/matrix.xml | 12 ++++++------ examples/testing/src/test/scala/TestMain.scala | 8 -------- 2 files changed, 6 insertions(+), 14 deletions(-) delete mode 100644 examples/testing/src/test/scala/TestMain.scala diff --git a/ci/matrix.xml b/ci/matrix.xml index 7ad2a560ee..acad664a22 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -45,21 +45,21 @@ 'set Seq(scalaJSUseMainModuleInitializer in helloworld := false, persistLauncher in helloworld := true)' \ helloworld/run \ helloworld/clean && - sbtretry ++$scala testingExample/test:run testingExample/test && + sbtretry ++$scala testingExample/test && sbtretry 'set scalaJSStage in Global := FullOptStage' \ - ++$scala testingExample/test:run testingExample/test \ + ++$scala testingExample/test \ testingExample/clean && sbtretry 'set inScope(ThisScope in testingExample)(jsEnv := new org.scalajs.jsenv.phantomjs.RetryingComJSEnv(PhantomJSEnv().value))' \ - ++$scala testingExample/test:run testingExample/test && + ++$scala testingExample/test && sbtretry 'set inScope(ThisScope in testingExample)(jsEnv := new org.scalajs.jsenv.phantomjs.RetryingComJSEnv(PhantomJSEnv().value))' \ 'set scalaJSStage in Global := FullOptStage' \ - ++$scala testingExample/test:run testingExample/test \ + ++$scala testingExample/test \ testingExample/clean && sbtretry 'set scalaJSOptimizerOptions in testingExample ~= (_.withDisableOptimizer(true))' \ - ++$scala testingExample/test:run testingExample/test && + ++$scala testingExample/test && sbtretry 'set inScope(ThisScope in testingExample)(jsEnv := new org.scalajs.jsenv.phantomjs.RetryingComJSEnv(PhantomJSEnv().value))' \ 'set scalaJSOptimizerOptions in testingExample ~= (_.withDisableOptimizer(true))' \ - ++$scala testingExample/test:run testingExample/test && + ++$scala testingExample/test && sbtretry ++$scala library/test && sbtretry ++$scala testSuiteJVM/test testSuiteJVM/clean && sbtretry ++$scala testSuite/test && diff --git a/examples/testing/src/test/scala/TestMain.scala b/examples/testing/src/test/scala/TestMain.scala deleted file mode 100644 index 4d5b0d8246..0000000000 --- a/examples/testing/src/test/scala/TestMain.scala +++ /dev/null @@ -1,8 +0,0 @@ -import scala.scalajs.js - -object TestMain extends js.JSApp { - def main(): Unit = { - // Use JS console to make sure this doesn't work on the JVM - js.Dynamic.global.console.log("Test main") - } -} From 228d54cf05ac12f0efc6790fecb336f2fb630f2e Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 9 Apr 2017 19:27:26 +0200 Subject: [PATCH 0206/2665] Fix #2883: Remove packageJSLauncher --- ci/matrix.xml | 4 - sbt-plugin-test/build.sbt | 6 +- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 40 ----- .../sbtplugin/ScalaJSPluginInternal.scala | 146 ++---------------- 4 files changed, 21 insertions(+), 175 deletions(-) diff --git a/ci/matrix.xml b/ci/matrix.xml index acad664a22..0aa2c55c5d 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -41,10 +41,6 @@ 'set scalaJSModuleKind in helloworld := ModuleKind.CommonJSModule' \ helloworld/run \ helloworld/clean && - sbtretry ++$scala \ - 'set Seq(scalaJSUseMainModuleInitializer in helloworld := false, persistLauncher in helloworld := true)' \ - helloworld/run \ - helloworld/clean && sbtretry ++$scala testingExample/test && sbtretry 'set scalaJSStage in Global := FullOptStage' \ ++$scala testingExample/test \ diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index 837e665ebe..f3830fa3f5 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -50,7 +50,8 @@ lazy val noDOM = project.settings(baseSettings: _*). name := "Scala.js sbt test w/o DOM", scalaJSOutputWrapper := ( "// Scala.js - noDOM sbt test\n//\n// Compiled with Scala.js\n", - "// End of Scala.js generated script") + "// End of Scala.js generated script"), + scalaJSUseMainModuleInitializer := true ). /* This hopefully exposes concurrent uses of the linker. If it fails/gets * flaky, there is a bug somewhere - #2202 @@ -65,7 +66,8 @@ lazy val withDOM = project.settings(baseSettings: _*). jsEnv := new JSDOMNodeJSEnv(), scalaJSOutputWrapper := ( "// Scala.js - withDOM sbt test\n//\n// Compiled with Scala.js\n", - "// End of Scala.js generated script") + "// End of Scala.js generated script"), + scalaJSUseMainModuleInitializer := true ) lazy val jetty9 = project.settings(baseSettings: _*). diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 1073168e86..0efbdd59fd 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -152,20 +152,6 @@ object ScalaJSPlugin extends AutoPlugin { val scalaJSStage = SettingKey[Stage]("scalaJSStage", "The optimization stage at which run and test are executed", APlusSetting) - /** Non-deprecated alias of `packageScalaJSLauncher` for internal use. */ - private[sbtplugin] val packageScalaJSLauncherInternal = TaskKey[Attributed[File]]( - "packageScalaJSLauncher", - "Writes the persistent launcher file. Fails if the mainClass is ambigous", - CTask) - - @deprecated( - "The functionality of `packageScalaJSLauncher` has been superseded " + - "by `scalaJSUseMainModuleInitializer`. Set the latter to `true` to " + - "include what was previously the launcher directly inside the main " + - ".js file generated by fastOptJS/fullOptJS.", - "0.6.15") - val packageScalaJSLauncher = packageScalaJSLauncherInternal - val packageJSDependencies = TaskKey[File]("packageJSDependencies", "Packages all dependencies of the preLink classpath in a single file.", AMinusTask) @@ -183,19 +169,6 @@ object ScalaJSPlugin extends AutoPlugin { "Linked Scala.js file. This is the result of fastOptJS or fullOptJS, " + "depending on the stage.", DTask) - /** Non-deprecated alias of `scalaJSLauncher` for internal use. */ - private[sbtplugin] val scalaJSLauncherInternal = TaskKey[Attributed[VirtualJSFile]]( - "scalaJSLauncher", - "Code used to run. (Attributed with used class name)", DTask) - - @deprecated( - "The functionality of `scalaJSLauncher` has been superseded by " + - "`scalaJSUseMainModuleInitializer`. Set the latter to `true` to " + - "include what was previously the launcher directly inside the main " + - ".js file generated by fastOptJS/fullOptJS.", - "0.6.15") - val scalaJSLauncher = scalaJSLauncherInternal - val scalaJSConsole = TaskKey[JSConsole]("scalaJSConsole", "The JS console used by the Scala.js runner/tester", DTask) @@ -260,19 +233,6 @@ object ScalaJSPlugin extends AutoPlugin { "Whether to check that the current semantics meet compliance " + "requirements of dependencies.", CSetting) - /** Non-deprecated alias of `persistLauncher` for internal use. */ - private[sbtplugin] val persistLauncherInternal = SettingKey[Boolean]("persistLauncher", - "Tell optimize/package tasks to write the laucher file to disk. " + - "If this is set, your project may only have a single mainClass or you must explicitly set it", AMinusSetting) - - @deprecated( - "The functionality of `persistLauncher` has been superseded by " + - "`scalaJSUseMainModuleInitializer`. Set the latter to `true` to " + - "include what was previously the launcher directly inside the main " + - ".js file generated by fastOptJS/fullOptJS.", - "0.6.15") - val persistLauncher = persistLauncherInternal - val scalaJSOptimizerOptions = SettingKey[OptimizerOptions]("scalaJSOptimizerOptions", "All kinds of options for the Scala.js optimizer stages", DSetting) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 5019d43a11..6d427abdb7 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -262,7 +262,7 @@ object ScalaJSPluginInternal { } tag((usesScalaJSLinkerTag in key).value) }.value, - key := key.dependsOn(packageJSDependencies, packageScalaJSLauncherInternal).value, + key := key.dependsOn(packageJSDependencies).value, scalaJSLinkedFile in key := new FileVirtualJSFile(key.value.data) ) @@ -417,53 +417,6 @@ object ScalaJSPluginInternal { fullOptJS := fullOptJS.dependsOn(packageMinifiedJSDependencies).value, - artifactPath in packageScalaJSLauncherInternal := - ((crossTarget in packageScalaJSLauncherInternal).value / - ((moduleName in packageScalaJSLauncherInternal).value + "-launcher.js")), - - skip in packageScalaJSLauncherInternal := { - val value = !persistLauncherInternal.value - if (!value) { - if (scalaJSUseMainModuleInitializer.value) { - throw new MessageOnlyException( - "persistLauncher := true is not compatible with using a main " + - "module initializer (scalaJSUseMainModuleInitializer := " + - "true), nor is it necessary, since fastOptJS/fullOptJS " + - "includes the call to the main method") - } else if (scalaJSModuleKind.value != ModuleKind.NoModule) { - throw new MessageOnlyException( - "persistLauncher := true is not compatible with emitting " + - "JavaScript modules") - } - } - value - }, - - packageScalaJSLauncherInternal := Def.taskDyn { - if ((skip in packageScalaJSLauncherInternal).value) { - Def.task { - Attributed.blank((artifactPath in packageScalaJSLauncherInternal).value) - } - } else { - Def.task { - mainClass.value map { mainCl => - val file = (artifactPath in packageScalaJSLauncherInternal).value - assert(scalaJSModuleKind.value == ModuleKind.NoModule, - "Cannot produce a launcher file when scalaJSModuleKind " + - "is different from NoModule") - IO.write(file, - launcherContent(mainCl, ModuleKind.NoModule, None), - 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") - } - } - } - }.value, - artifactPath in packageJSDependencies := ((crossTarget in packageJSDependencies).value / ((moduleName in packageJSDependencies).value + "-jsdeps.js")), @@ -680,25 +633,6 @@ object ScalaJSPluginInternal { }.value ) - /** Run a class in a given environment using a given launcher */ - private def jsRun(jsEnv: JSEnv, mainCl: String, - launcher: VirtualJSFile, log: Logger, console: JSConsole) = { - - log.info("Running " + mainCl) - log.debug(s"with JSEnv ${jsEnv.name}") - - val runner = jsEnv.jsRunner(launcher) - runner.run(sbtLogger2ToolsLogger(log), console) - } - - private def launcherContent(mainCl: String, moduleKind: ModuleKind, - moduleIdentifier: Option[String]): String = { - val exportsNamespaceExpr = - makeExportsNamespaceExpr(moduleKind, moduleIdentifier) - val parts = mainCl.split('.').map(s => s"""["${escapeJS(s)}"]""").mkString - s"$exportsNamespaceExpr$parts().main();\n" - } - private[sbtplugin] def makeExportsNamespaceExpr(moduleKind: ModuleKind, moduleIdentifier: Option[String]): String = { // !!! DUPLICATE code with ScalaJSFramework.optionalExportsNamespacePrefix @@ -715,12 +649,6 @@ object ScalaJSPluginInternal { } } - private def memLauncher(mainCl: String, moduleKind: ModuleKind, - moduleIdentifier: Option[String]): VirtualJSFile = { - new MemVirtualJSFile("Generated launcher file") - .withContent(launcherContent(mainCl, moduleKind, moduleIdentifier)) - } - def discoverJSApps(analysis: inc.Analysis): Seq[String] = { import xsbt.api.{Discovered, Discovery} @@ -764,38 +692,6 @@ object ScalaJSPluginInternal { } }, - mainClass in scalaJSLauncherInternal := (mainClass in run).value, - scalaJSLauncherInternal := Def.taskDyn[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 { - sys.error("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, - discoveredMainClasses := compile.map(discoverJSApps). storeAs(discoveredMainClasses).triggeredBy(compile).value, @@ -803,30 +699,25 @@ object ScalaJSPluginInternal { // use assert to prevent warning about pure expr in stat pos assert(scalaJSEnsureUnforked.value) - val launch = scalaJSLauncherInternal.value - val className = launch.get(name.key).getOrElse("") - jsRun(loadedJSEnv.value, className, launch.data, - streams.value.log, scalaJSConsole.value) - }, + if (!scalaJSUseMainModuleInitializer.value) { + throw new MessageOnlyException("`run` is only supported with " + + "scalaJSUseMainModuleInitializer := true") + } - runMain := { - // use assert to prevent warning about pure expr in stat pos - assert(scalaJSEnsureUnforked.value) + val log = streams.value.log + val jsEnv = loadedJSEnv.value - val mainClass = runMainParser.parsed + log.info("Running " + mainClass.value.getOrElse("")) + log.debug(s"with JSEnv ${jsEnv.name}") - if (scalaJSUseMainModuleInitializer.value) { - throw new MessageOnlyException( - "`runMain` is not supported when using a main module " + - "initializer (scalaJSUseMainModuleInitializer := true) since " + - "the (unique) entry point is burned in the fastOptJS/fullOptJS.") - } + val dummyLauncher = new MemVirtualJSFile("No-op generated launcher file") - val moduleKind = scalaJSModuleKind.value - val moduleIdentifier = scalaJSModuleIdentifier.value - jsRun(loadedJSEnv.value, mainClass, - memLauncher(mainClass, moduleKind, moduleIdentifier), - streams.value.log, scalaJSConsole.value) + jsEnv.jsRunner(dummyLauncher).run( + sbtLogger2ToolsLogger(log), scalaJSConsole.value) + }, + + runMain := { + throw new MessageOnlyException("`runMain` is not supported in Scala.js") } ) @@ -874,8 +765,7 @@ object ScalaJSPluginInternal { val scalaJSTestBuildSettings = ( scalaJSConfigSettings ) ++ ( - Seq(fastOptJS, fullOptJS, packageScalaJSLauncherInternal, - packageJSDependencies) map { packageJSTask => + Seq(fastOptJS, fullOptJS, packageJSDependencies) map { packageJSTask => moduleName in packageJSTask := moduleName.value + "-test" } ) @@ -961,8 +851,6 @@ object ScalaJSPluginInternal { isScalaJSProject := true, relativeSourceMaps := false, - persistLauncherInternal := false, - persistLauncherInternal in Test := false, emitSourceMaps := true, From facca8515a55a0969c618dc59a71a885449897da Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Wed, 5 Apr 2017 19:22:44 +0200 Subject: [PATCH 0207/2665] Fix #2861: Remove @JSExportDescendent{Classes|Objects} --- .../scalajs/core/compiler/JSDefinitions.scala | 2 - .../scalajs/core/compiler/PrepJSExports.scala | 129 +------- .../scalajs/core/compiler/PrepJSInterop.scala | 31 +- .../test/JSExportDeprecationsTest.scala | 46 --- .../core/compiler/test/JSExportTest.scala | 86 ------ .../main/scala/scala/scalajs/js/JSApp.scala | 14 +- .../JSExportDescendentObjects.scala | 29 -- project/Build.scala | 2 - .../js/annotation/ExportAnnotations.scala | 10 - .../testsuite/jsinterop/ExportsTest.scala | 292 ------------------ 10 files changed, 18 insertions(+), 623 deletions(-) delete mode 100644 library/src/main/scala/scala/scalajs/js/annotation/JSExportDescendentObjects.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 248b251ae8..84d99c36e9 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -58,8 +58,6 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val JSBracketAccessAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSBracketAccess") lazy val JSBracketCallAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSBracketCall") lazy val JSExportAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExport") - lazy val JSExportDescendentObjectsAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportDescendentObjects") - lazy val JSExportDescendentClassesAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportDescendentClasses") lazy val JSExportAllAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportAll") lazy val JSExportNamedAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportNamed") lazy val JSExportStaticAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportStatic") diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala index 1c678cf307..63651c7223 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala @@ -21,13 +21,9 @@ trait PrepJSExports { this: PrepJSInterop => import scala.reflect.internal.Flags - case class ExportInfo( - jsName: String, - pos: Position, - isNamed: Boolean, - destination: ExportDestination, - ignoreInvalid: Boolean - ) extends jsInterop.ExportInfo { + case class ExportInfo(jsName: String, isNamed: Boolean, + destination: ExportDestination)(val pos: Position) + extends jsInterop.ExportInfo { assert(!isNamed || destination == ExportDestination.Normal) } @@ -47,12 +43,10 @@ trait PrepJSExports { this: PrepJSInterop => val clsSym = baseSym.owner val exports = exportsOf(baseSym) - val ignoreInvalid = exports.forall(_.ignoreInvalid) // Helper function for errors def err(msg: String) = { - if (!ignoreInvalid) - reporter.error(exports.head.pos, msg) + reporter.error(exports.head.pos, msg) Nil } @@ -130,12 +124,10 @@ trait PrepJSExports { this: PrepJSInterop => val isMod = sym.isModuleClass val exports = exportsOf(sym) - val ignoreInvalid = exports.forall(_.ignoreInvalid) if (exports.nonEmpty) { def err(msg: String) = { - if (!ignoreInvalid) - reporter.error(exports.head.pos, msg) + reporter.error(exports.head.pos, msg) } def hasAnyNonPrivateCtor: Boolean = @@ -159,7 +151,6 @@ trait PrepJSExports { this: PrepJSInterop => for { exp <- named - if !exp.ignoreInvalid } { reporter.error(exp.pos, "You may not use @JSNamedExport on " + (if (isMod) "an object" else "a Scala.js-defined JS class")) @@ -170,37 +161,6 @@ trait PrepJSExports { this: PrepJSInterop => } } - /** Deprecate `@JSExportDescendentClasses` and `@JSExportDescendentObjects`. - * - * We do this only on the annotated symbol (not in descendants), which is - * why this test is a bit separate from everything else. - * Ideally we would simply `@deprecate` the annotations, but that would not - * allow us to suppress the deprecations. - */ - def checkDeprecationOfJSExportDescendentClassesObjects(sym: Symbol): Unit = { - if (!scalaJSOpts.suppressExportDeprecations) { - for (annot <- sym.annotations) { - if (annot.symbol == JSExportDescendentClassesAnnotation) { - reporter.warning(annot.pos, - "@JSExportDescendentClasses is deprecated and will be removed " + - "in 1.0.0. For use cases where you want to simulate "+ - "\"reflective\" instantiation, use @EnableReflectiveInstantion " + - "and scala.scalajs.reflect.Reflect.lookupInstantiatableClass " + - "instead." + - SuppressExportDeprecationsMsg) - } else if (annot.symbol == JSExportDescendentObjectsAnnotation) { - reporter.warning(annot.pos, - "@JSExportDescendentObjects is deprecated and will be removed " + - "in 1.0.0. For use cases where you want to simulate " + - "\"reflective\" loading, use @EnableReflectiveInstantion and " + - "scala.scalajs.reflect.Reflect.lookupLoadableModuleClass " + - "instead." + - SuppressExportDeprecationsMsg) - } - } - } - } - private def createFactoryInOuterClassHint = { "Create an exported factory method in the outer class to work " + "around this limitation." @@ -212,21 +172,6 @@ trait PrepJSExports { this: PrepJSInterop => * are used, rather than the annotations of the accessor itself. */ def exportsOf(sym: Symbol): List[ExportInfo] = { - val exports = directExportsOf(sym) ++ inheritedExportsOf(sym) - - /* Calculate the distinct exports for this symbol (eliminate double - * occurrences of (name, isNamed, isTopLevel, isStatic) tuples). - */ - val grouped = exports.groupBy( - exp => (exp.jsName, exp.isNamed, exp.destination)) - - for ((_, exps) <- grouped.toList) yield { - // Make sure that we are strict if necessary - exps.find(!_.ignoreInvalid).getOrElse(exps.head) - } - } - - private def directExportsOf(sym: Symbol): List[ExportInfo] = { val trgSym = { def isOwnerScalaClass = !sym.owner.isModuleClass && !isJSAny(sym.owner) @@ -443,15 +388,14 @@ trait PrepJSExports { this: PrepJSInterop => } } - ExportInfo(name, annot.pos, isNamedExport, destination, - ignoreInvalid = false) + ExportInfo(name, isNamedExport, destination)(annot.pos) } /* Filter out static exports of accessors (as they are not actually * exported, their fields are). The above is only used to uniformly perform * checks. */ - if (!sym.isAccessor || sym.accessed == NoSymbol) { + val filteredExports = if (!sym.isAccessor || sym.accessed == NoSymbol) { allExportInfos } else { /* For accessors, we need to apply some special logic to static exports. @@ -491,65 +435,8 @@ trait PrepJSExports { this: PrepJSInterop => actualExportInfos } - } - - private def inheritedExportsOf(sym: Symbol): List[ExportInfo] = { - // The symbol from which we (potentially) inherit exports. It also - // gives the exports their name - val trgSym = { - if (sym.isModuleClass || (sym.isClass && isJSAny(sym))) { - sym - } else if (sym.isConstructor && sym.isPublic && !isJSAny(sym.owner) && - sym.owner.isConcreteClass && !sym.owner.isModuleClass) { - sym.owner - } else { - NoSymbol - } - } - if (trgSym == NoSymbol) { - Nil - } else { - val trgAnnot = - if (sym.isModuleClass) JSExportDescendentObjectsAnnotation - else JSExportDescendentClassesAnnotation - - val forcingSymInfos = for { - forcingSym <- trgSym.ancestors - annot <- forcingSym.annotations - if annot.symbol == trgAnnot - } yield { - val ignoreInvalid = annot.constantAtIndex(0).fold(false)(_.booleanValue) - (forcingSym, ignoreInvalid) - } - - // The dominating forcing symbol, is the first that does not ignore - // or the first otherwise - val forcingSymInfo = - forcingSymInfos.find(!_._2).orElse(forcingSymInfos.headOption) - - val name = decodedFullName(trgSym) - val nameValid = !name.contains("__") - - val optExport = for { - (forcingSym, ignoreInvalid) <- forcingSymInfo - if nameValid || !ignoreInvalid - } yield { - // Enfore no __ in name - if (!nameValid) { - // Get all annotation positions for error message - reporter.error(sym.pos, - s"${trgSym.name} may not have a double underscore (`__`) in " + - "its fully qualified name, since it is forced to be exported by " + - s"a @${trgAnnot.name} on $forcingSym") - } - - ExportInfo(name, sym.pos, isNamed = false, ExportDestination.Normal, - ignoreInvalid) - } - - optExport.toList - } + filteredExports.distinct } /** Just like sym.fullName, but does not encode components */ diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 67079be307..57322864cb 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -199,10 +199,8 @@ abstract class PrepJSInterop extends plugins.PluginComponent if (shouldPrepareExports && sym.isTrait) { // Check that interface/trait is not exported - for { - exp <- exportsOf(sym) - if !exp.ignoreInvalid - } reporter.error(exp.pos, "You may not export a trait") + for (exp <- exportsOf(sym)) + reporter.error(exp.pos, "You may not export a trait") } enterOwner(OwnerKind.NonEnumScalaClass) { super.transform(cldef) } @@ -358,9 +356,6 @@ abstract class PrepJSInterop extends plugins.PluginComponent case _ => super.transform(tree) } - if (tree.isInstanceOf[ImplDef]) - checkDeprecationOfJSExportDescendentClassesObjects(tree.symbol) - postTransform(preTransformedTree) } @@ -431,12 +426,8 @@ abstract class PrepJSInterop extends plugins.PluginComponent val sym = memDef.symbol if (sym.isLocalToBlock && !sym.owner.isCaseApplyOrUnapply) { // We exclude case class apply (and unapply) to work around SI-8826 - for { - exp <- exportsOf(sym) - if !exp.ignoreInvalid - } { + for (exp <- exportsOf(sym)) reporter.error(exp.pos, "You may not export a local definition") - } } // Expose objects (modules) members of Scala.js-defined JS classes @@ -585,18 +576,11 @@ abstract class PrepJSInterop extends plugins.PluginComponent if (shouldPrepareExports) { if (sym.isTrait) { // Check that interface/trait is not exported - for { - exp <- exportsOf(sym) - if !exp.ignoreInvalid - } { + for (exp <- exportsOf(sym)) reporter.error(exp.pos, "You may not export a trait") - } } else if (isJSNative) { // Check that a JS native type is not exported - for { - exp <- exportsOf(sym) - if !exp.ignoreInvalid - } { + for (exp <- exportsOf(sym)) { reporter.error(exp.pos, "You may not export a native JS class or object") } @@ -750,10 +734,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent if (shouldPrepareExports) { // Exports are never valid on members of JS types lazy val memType = if (sym.isConstructor) "constructor" else "method" - for { - exp <- exportsOf(sym) - if !exp.ignoreInvalid - } { + for (exp <- exportsOf(sym)) { reporter.error(exp.pos, s"You may not export a $memType of a subclass of js.Any") } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportDeprecationsTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportDeprecationsTest.scala index 5489d88b47..e972e88374 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportDeprecationsTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportDeprecationsTest.scala @@ -56,50 +56,4 @@ class JSExportDeprecationsTest extends DirectTest with TestHelpers { """ } - @Test - def warnJSExportDescendentClasses: Unit = { - for (kind <- Seq("class", "trait", "object")) { - s""" - @JSExportDescendentClasses - $kind A - - @JSExportDescendentClasses(ignoreInvalidDescendants = true) - $kind B - """ hasWarns - """ - |newSource1.scala:3: warning: @JSExportDescendentClasses is deprecated and will be removed in 1.0.0. For use cases where you want to simulate "reflective" instantiation, use @EnableReflectiveInstantion and scala.scalajs.reflect.Reflect.lookupInstantiatableClass instead. - | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressExportDeprecations` to scalac) - | @JSExportDescendentClasses - | ^ - |newSource1.scala:6: warning: @JSExportDescendentClasses is deprecated and will be removed in 1.0.0. For use cases where you want to simulate "reflective" instantiation, use @EnableReflectiveInstantion and scala.scalajs.reflect.Reflect.lookupInstantiatableClass instead. - | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressExportDeprecations` to scalac) - | @JSExportDescendentClasses(ignoreInvalidDescendants = true) - | ^ - """ - } - } - - @Test - def warnJSExportDescendentObjects: Unit = { - for (kind <- Seq("class", "trait", "object")) { - s""" - @JSExportDescendentObjects - $kind A - - @JSExportDescendentObjects(ignoreInvalidDescendants = true) - $kind B - """ hasWarns - """ - |newSource1.scala:3: warning: @JSExportDescendentObjects is deprecated and will be removed in 1.0.0. For use cases where you want to simulate "reflective" loading, use @EnableReflectiveInstantion and scala.scalajs.reflect.Reflect.lookupLoadableModuleClass instead. - | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressExportDeprecations` to scalac) - | @JSExportDescendentObjects - | ^ - |newSource1.scala:6: warning: @JSExportDescendentObjects is deprecated and will be removed in 1.0.0. For use cases where you want to simulate "reflective" loading, use @EnableReflectiveInstantion and scala.scalajs.reflect.Reflect.lookupLoadableModuleClass instead. - | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressExportDeprecations` to scalac) - | @JSExportDescendentObjects(ignoreInvalidDescendants = true) - | ^ - """ - } - } - } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index 625145b63c..08d52f9b27 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -48,70 +48,6 @@ class JSExportTest extends DirectTest with TestHelpers { | class C__ extends js.Object | ^ """ - - // Inherited exports (objects) - """ - @JSExportDescendentObjects - trait A - - package fo__o { - object B extends A - } - """ hasErrors - """ - |newSource1.scala:7: error: B may not have a double underscore (`__`) in its fully qualified name, since it is forced to be exported by a @JSExportDescendentObjects on trait A - | object B extends A - | ^ - """ - - """ - @JSExportDescendentObjects - trait A extends js.Object - - package fo__o { - object B extends A - } - """ hasErrors - """ - |newSource1.scala:7: error: B may not have a double underscore (`__`) in its fully qualified name, since it is forced to be exported by a @JSExportDescendentObjects on trait A - | object B extends A - | ^ - """ - - // Inherited exports (classes) - """ - @JSExportDescendentClasses - trait A - - package fo__o { - class B(x: Int) extends A { - def this() = this(1) - private def this(s: String) = this(1) - } - } - """ hasErrors - """ - |newSource1.scala:7: error: B may not have a double underscore (`__`) in its fully qualified name, since it is forced to be exported by a @JSExportDescendentClasses on trait A - | class B(x: Int) extends A { - | ^ - |newSource1.scala:8: error: B may not have a double underscore (`__`) in its fully qualified name, since it is forced to be exported by a @JSExportDescendentClasses on trait A - | def this() = this(1) - | ^ - """ - - """ - @JSExportDescendentClasses - trait A extends js.Object - - package fo__o { - class B(x: Int) extends A - } - """ hasErrors - """ - |newSource1.scala:7: error: B may not have a double underscore (`__`) in its fully qualified name, since it is forced to be exported by a @JSExportDescendentClasses on trait A - | class B(x: Int) extends A - | ^ - """ } @Test @@ -1010,28 +946,6 @@ class JSExportTest extends DirectTest with TestHelpers { } - @Test - def noInheritIgnoreInvalidDescendants: Unit = { - - """ - @JSExportDescendentClasses - trait A - - @JSExportDescendentClasses(ignoreInvalidDescendants = true) - trait B - - object A { - // Local class is not allowed - def foo = { new A with B } - } - """ hasErrors - """ - |newSource1.scala:11: error: You may not export a local class - | def foo = { new A with B } - | ^ - """ - } - @Test def noExportImplicitApply: Unit = { diff --git a/library/src/main/scala/scala/scalajs/js/JSApp.scala b/library/src/main/scala/scala/scalajs/js/JSApp.scala index fd12207afa..47fe4b0450 100644 --- a/library/src/main/scala/scala/scalajs/js/JSApp.scala +++ b/library/src/main/scala/scala/scalajs/js/JSApp.scala @@ -1,20 +1,14 @@ package scala.scalajs.js -import annotation.{JSExport, JSExportDescendentObjects} - /** Base class for top-level, entry point main objects. - * - * 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. */ -@JSExportDescendentObjects trait JSApp { - @JSExport def main(): Unit } diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSExportDescendentObjects.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSExportDescendentObjects.scala deleted file mode 100644 index 6932e5f433..0000000000 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSExportDescendentObjects.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - - -package scala.scalajs.js.annotation - -/** Specifies that all the objects extending the annotated class or trait - * should be exported for use in raw JS. - * Note that objects exported this way are exported under their fully - * qualified name. - * - * @param ignoreInvalidDescendants If true, descendants that cannot be exported - * are silently ignored. - * @see [[http://www.scala-js.org/doc/export-to-javascript.html Export Scala.js APIs to JavaScript]] - */ -class JSExportDescendentObjects(ignoreInvalidDescendants: Boolean) - extends scala.annotation.StaticAnnotation { - /** Constructor that makes invalid descendants fail. - * - * same as setting ingoreInvalidDescendants to false - */ - def this() = this(false) -} diff --git a/project/Build.scala b/project/Build.scala index 1dbb9d505f..3371253df0 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -982,8 +982,6 @@ object Build { libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value % "provided", - // js.JSApp is annotated with @JSExportDescendentObjects - scalacOptions += "-P:scalajs:suppressExportDeprecations", scalaJSExternalCompileSettings, inConfig(Compile)(Seq( scalacOptions in doc ++= Seq("-implicits", "-groups"), diff --git a/stubs/src/main/scala/scala/scalajs/js/annotation/ExportAnnotations.scala b/stubs/src/main/scala/scala/scalajs/js/annotation/ExportAnnotations.scala index 20281c4963..da307d0c26 100644 --- a/stubs/src/main/scala/scala/scalajs/js/annotation/ExportAnnotations.scala +++ b/stubs/src/main/scala/scala/scalajs/js/annotation/ExportAnnotations.scala @@ -13,16 +13,6 @@ import scala.annotation.Annotation class JSExportAll extends scala.annotation.Annotation -class JSExportDescendentObjects(ignoreInvalidDescendants: Boolean) - extends scala.annotation.Annotation { - def this() = this(false) -} - -class JSExportDescendentClasses(ignoreInvalidDescendants: Boolean) - extends scala.annotation.Annotation { - def this() = this(false) -} - class JSExportNamed extends scala.annotation.Annotation { def this(name: String) = this() } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index f02fcf82d5..028a3caa51 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -1413,227 +1413,6 @@ class ExportsTest { assertEquals("Hello World", jsPackage.toplevel.fieldreachability) } - // @JSExportDescendentObjects - - @Test def auto_exports_for_objects_extending_a_trait(): Unit = { - val accessor = - exportsNamespace.org.scalajs.testsuite.jsinterop.AutoExportedTraitObject - assertJSNotUndefined(accessor) - assertEquals("function", js.typeOf(accessor)) - val obj = accessor() - assertJSNotUndefined(obj) - assertSame(AutoExportedTraitObject.asInstanceOf[js.Any], obj) - } - - @Test def auto_exports_for_objects_extending_a_class(): Unit = { - val accessor = - exportsNamespace.org.scalajs.testsuite.jsinterop.AutoExportedClassObject - assertJSNotUndefined(accessor) - assertEquals("function", js.typeOf(accessor)) - val obj = accessor() - assertJSNotUndefined(obj) - assertSame(AutoExportedClassObject.asInstanceOf[js.Any], obj) - } - - @Test def auto_exports_for_Scala_js_defined_JS_objects_extending_a_trait(): Unit = { - val accessor = - exportsNamespace.org.scalajs.testsuite.jsinterop.SJSDefinedAutoExportedTraitObject - assertJSNotUndefined(accessor) - assertEquals("function", js.typeOf(accessor)) - val obj = accessor() - assertJSNotUndefined(obj) - assertSame(SJSDefinedAutoExportedTraitObject, obj) - } - - @Test def auto_exports_for_Scala_js_defined_JS_objects_extending_a_class(): Unit = { - val accessor = - exportsNamespace.org.scalajs.testsuite.jsinterop.SJSDefinedAutoExportedClassObject - assertJSNotUndefined(accessor) - assertEquals("function", js.typeOf(accessor)) - val obj = accessor() - assertJSNotUndefined(obj) - assertSame(SJSDefinedAutoExportedClassObject, obj) - } - - @Test def auto_exports_for_objects_extending_a_trait_with_ignoreInvalidDescendants(): Unit = { - val accessor = - exportsNamespace.org.scalajs.testsuite.jsinterop.AutoExportIgnoreTraitObject - assertJSNotUndefined(accessor) - assertEquals("function", js.typeOf(accessor)) - val obj = accessor() - assertJSNotUndefined(obj) - assertSame(AutoExportIgnoreTraitObject.asInstanceOf[js.Any], obj) - } - - @Test def auto_exports_for_objects_extending_a_class_with_ignoreInvalidDescendants(): Unit = { - val accessor = - exportsNamespace.org.scalajs.testsuite.jsinterop.AutoExportIgnoreClassObject - assertJSNotUndefined(accessor) - assertEquals("function", js.typeOf(accessor)) - val obj = accessor() - assertJSNotUndefined(obj) - assertSame(AutoExportIgnoreClassObject.asInstanceOf[js.Any], obj) - } - - @Test def auto_exports_for_Scala_js_defined_JS_objects_extending_a_class_with_ignoreInvalidDescendants(): Unit = { - val accessor = - exportsNamespace.org.scalajs.testsuite.jsinterop.SJSDefinedAutoExportedIgnoreClassObject - assertJSNotUndefined(accessor) - assertEquals("function", js.typeOf(accessor)) - val obj = accessor() - assertJSNotUndefined(obj) - assertSame(SJSDefinedAutoExportedIgnoreClassObject, obj) - } - - @Test def should_ignore_invalid_descendants(): Unit = { - // This is just to check that everything here compiles - object A extends AutoExportIgnoreTrait { var x = 1 } - object B extends AutoExportIgnoreClass { var x = 2 } - - object C extends SJSDefinedAutoExportIgnoreClass { var x = 3 } - - // Check that the objects are usable - assertEquals(1, A.x) - assertEquals(2, B.x) - assertEquals(3, C.x) - - A.x = 3 - B.x = 4 - C.x = 2 - - assertEquals(3, A.x) - assertEquals(4, B.x) - assertEquals(2, C.x) - } - - // @JSExportDescendentClasses - - @Test def auto_exports_for_classes_extending_a_trait(): Unit = { - val ctor = - exportsNamespace.org.scalajs.testsuite.jsinterop.AutoExportedTraitClass - assertJSNotUndefined(ctor) - assertEquals("function", js.typeOf(ctor)) - - val obj1 = js.Dynamic.newInstance(ctor)() - assertJSNotUndefined(obj1) - assertEquals(obj1.x, 5) - - val obj2 = js.Dynamic.newInstance(ctor)(100) - assertJSNotUndefined(obj2) - assertEquals(obj2.x, 100) - } - - @Test def auto_exports_for_classes_extending_a_class(): Unit = { - val ctor = - exportsNamespace.org.scalajs.testsuite.jsinterop.AutoExportedClassClass - assertJSNotUndefined(ctor) - assertEquals("function", js.typeOf(ctor)) - - val obj1 = js.Dynamic.newInstance(ctor)() - assertJSNotUndefined(obj1) - assertEquals(obj1.x, 5) - - val obj2 = js.Dynamic.newInstance(ctor)(100) - assertJSNotUndefined(obj2) - assertEquals(obj2.x, 100) - } - - @Test def auto_exports_for_Scala_js_defined_JS_classes_extending_a_trait(): Unit = { - val ctor = - exportsNamespace.org.scalajs.testsuite.jsinterop.SJSDefinedAutoExportedTraitClass - assertJSNotUndefined(ctor) - assertEquals("function", js.typeOf(ctor)) - - val obj = js.Dynamic.newInstance(ctor)(100) - assertTrue((obj: Any).isInstanceOf[SJSDefinedAutoExportedTraitClass]) - assertJSNotUndefined(obj) - assertEquals(obj.x, 100) - } - - @Test def auto_exports_for_Scala_js_defined_JS_classes_extending_a_class(): Unit = { - val ctor = - exportsNamespace.org.scalajs.testsuite.jsinterop.SJSDefinedAutoExportedClassClass - assertJSNotUndefined(ctor) - assertEquals("function", js.typeOf(ctor)) - - val obj = js.Dynamic.newInstance(ctor)(100) - assertTrue((obj: Any).isInstanceOf[SJSDefinedAutoExportedClassClass]) - assertJSNotUndefined(obj) - assertEquals(obj.x, 100) - } - - @Test def auto_exports_for_classes_extending_a_trait_with_ignoreInvalidDescendants(): Unit = { - val ctor = - exportsNamespace.org.scalajs.testsuite.jsinterop.AutoExportIgnoreTraitClass - assertJSNotUndefined(ctor) - assertEquals("function", js.typeOf(ctor)) - - val obj1 = js.Dynamic.newInstance(ctor)() - assertJSNotUndefined(obj1) - assertEquals(obj1.x, 5) - - val obj2 = js.Dynamic.newInstance(ctor)(100) - assertJSNotUndefined(obj2) - assertEquals(obj2.x, 100) - } - - @Test def auto_exports_for_classes_extending_a_class_with_ignoreInvalidDescendants(): Unit = { - val ctor = - exportsNamespace.org.scalajs.testsuite.jsinterop.AutoExportIgnoreClassClass - assertJSNotUndefined(ctor) - assertEquals("function", js.typeOf(ctor)) - - val obj1 = js.Dynamic.newInstance(ctor)() - assertJSNotUndefined(obj1) - assertEquals(obj1.x, 5) - - val obj2 = js.Dynamic.newInstance(ctor)(100) - assertJSNotUndefined(obj2) - assertEquals(obj2.x, 100) - } - - @Test def auto_exports_for_Scala_js_defined_JS_classes_extending_a_class_with_ignoreInvalidDescendants(): Unit = { - val ctor = - exportsNamespace.org.scalajs.testsuite.jsinterop.SJSDefinedAutoExportedIgnoreClassClass - assertJSNotUndefined(ctor) - assertEquals("function", js.typeOf(ctor)) - - val obj = js.Dynamic.newInstance(ctor)(100) - assertTrue((obj: Any).isInstanceOf[SJSDefinedAutoExportedIgnoreClassClass]) - assertJSNotUndefined(obj) - assertEquals(obj.x, 100) - } - - @Test def should_ignore_invalid_descendants2(): Unit = { - trait HasBar { def bar: Int } - - trait SJSDefinedHasBar extends js.Any { def bar: Int } - - // This is just to check that everything here compiles - class A extends AutoExportIgnoreTrait { def foo: Int = 1 } - class B extends AutoExportIgnoreClass { def foo: Int = 2 } - - class C extends SJSDefinedAutoExportIgnoreClass { def foo: Int = 3 } - - val a = new A { override def foo: Int = 3 } - val b = new B { override def foo: Int = 4 } - val c = new C { override def foo: Int = 5 } - val d = new AutoExportIgnoreClass with HasBar { def bar: Int = 1 } - val e = new AutoExportIgnoreTrait with HasBar { def bar: Int = 1 } - val f = new SJSDefinedAutoExportIgnoreClass with SJSDefinedHasBar { def bar: Int = 1 } - - // Check the classes are usable - assertEquals(1, (new A).foo) - assertEquals(2, (new B).foo) - assertEquals(3, (new C).foo) - assertEquals(3, a.foo) - assertEquals(4, b.foo) - assertEquals(5, c.foo) - assertEquals(1, d.bar) - assertEquals(1, e.bar) - assertEquals(1, f.bar) - } - } object ExportNameHolder { @@ -1730,77 +1509,6 @@ class ExportedDefaultArgClass(x: Int, y: Int, z: Int) { @JSExport("org.ExportedUnderOrgObject") object ExportedUnderOrgObject -@JSExportDescendentClasses -@JSExportDescendentObjects -trait AutoExportTrait - -object AutoExportedTraitObject extends AutoExportTrait -class AutoExportedTraitClass(_x: Int) extends AutoExportTrait { - def this() = this(5) - @JSExport - def x: Int = _x -} - -@JSExportDescendentClasses -@JSExportDescendentObjects -class AutoExportClass - -object AutoExportedClassObject extends AutoExportClass -class AutoExportedClassClass(_x: Int) extends AutoExportTrait { - def this() = this(5) - @JSExport - def x: Int = _x -} - -@JSExportDescendentClasses -@JSExportDescendentObjects -trait SJSDefinedAutoExportTrait extends js.Object - -object SJSDefinedAutoExportedTraitObject extends SJSDefinedAutoExportTrait -class SJSDefinedAutoExportedTraitClass(val x: Int) extends SJSDefinedAutoExportTrait - -@JSExportDescendentClasses -@JSExportDescendentObjects -class SJSDefinedAutoExportClass extends js.Object - -object SJSDefinedAutoExportedClassObject extends SJSDefinedAutoExportClass -class SJSDefinedAutoExportedClassClass(val x: Int) extends SJSDefinedAutoExportClass - -@JSExportDescendentClasses(ignoreInvalidDescendants = true) -@JSExportDescendentObjects(ignoreInvalidDescendants = true) -trait AutoExportIgnoreTrait - -object AutoExportIgnoreTraitObject extends AutoExportIgnoreTrait -class AutoExportIgnoreTraitClass(_x: Int) extends AutoExportIgnoreTrait { - def this() = this(5) - @JSExport - def x: Int = _x -} - -@JSExportDescendentClasses(ignoreInvalidDescendants = true) -@JSExportDescendentObjects(ignoreInvalidDescendants = true) -class AutoExportIgnoreClass - -object AutoExportIgnoreClassObject extends AutoExportIgnoreClass -class AutoExportIgnoreClassClass(_x: Int) extends AutoExportIgnoreTrait { - def this() = this(5) - @JSExport - def x: Int = _x -} - -@JSExportDescendentClasses(ignoreInvalidDescendants = true) -@JSExportDescendentObjects(ignoreInvalidDescendants = true) -class SJSDefinedAutoExportIgnoreClass extends js.Object - -object SJSDefinedAutoExportedIgnoreClassObject extends SJSDefinedAutoExportIgnoreClass -class SJSDefinedAutoExportedIgnoreClassClass(val x: Int) extends SJSDefinedAutoExportIgnoreClass - -@js.native @JSGlobal -object NativeInvalidExportObject extends SJSDefinedAutoExportIgnoreClass -@js.native @JSGlobal -class NativeInvalidExportClass extends SJSDefinedAutoExportIgnoreClass -class SJSDefinedInvalidExportClass private () extends SJSDefinedAutoExportIgnoreClass - class SomeValueClass(val i: Int) extends AnyVal @JSExportNamed From 4d4e4b7e99d5437d2f1953a87a9c32a6b0ed7500 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Wed, 5 Apr 2017 19:38:29 +0200 Subject: [PATCH 0208/2665] Fix #2859: Remove @JSExportNamed --- .../org/scalajs/core/compiler/GenJSCode.scala | 10 +- .../scalajs/core/compiler/GenJSExports.scala | 76 +------- .../scalajs/core/compiler/JSDefinitions.scala | 1 - .../core/compiler/JSGlobalAddons.scala | 1 - .../scalajs/core/compiler/PrepJSExports.scala | 74 +------- .../core/compiler/test/JSExportTest.scala | 179 +----------------- .../scalajs/js/annotation/JSExportNamed.scala | 74 -------- .../js/annotation/ExportAnnotations.scala | 4 - .../testsuite/jsinterop/ExportsTest.scala | 43 ----- 9 files changed, 11 insertions(+), 451 deletions(-) delete mode 100644 library/src/main/scala/scala/scalajs/js/annotation/JSExportNamed.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index b3967a9b00..a3b333e389 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -392,10 +392,7 @@ abstract class GenJSCode extends plugins.PluginComponent () // fields are added via genClassFields() case dd: DefDef => - if (isNamedExporterDef(dd)) - generatedMethods ++= genNamedExporterDef(dd) - else - generatedMethods ++= genMethod(dd) + generatedMethods ++= genMethod(dd) case _ => abort("Illegal tree in gen of genClass(): " + tree) } @@ -798,10 +795,7 @@ abstract class GenJSCode extends plugins.PluginComponent case Template(_, _, body) => body.flatMap(gen) case dd: DefDef => - if (isNamedExporterDef(dd)) - genNamedExporterDef(dd).toList - else - genMethod(dd).toList + genMethod(dd).toList case _ => abort("Illegal tree in gen of genInterface(): " + tree) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index 667b77df53..ccf50d5929 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -74,19 +74,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => val exports = for { (jsName, specs) <- ctorExports.groupBy(_._1.jsName) // group by exported name } yield { - val (namedExports, normalExports) = specs.partition(_._1.isNamed) - - val normalCtors = normalExports.map(s => ExportedSymbol(s._2)) - val namedCtors = for { - (exp, ctor) <- namedExports - } yield { - implicit val pos = exp.pos - ExportedBody(List(JSAnyTpe), - genNamedExporterBody(ctor, genFormalArg(1).ref), - nme.CONSTRUCTOR.toString, pos) - } - - val ctors = normalCtors ++ namedCtors + val ctors = specs.map(s => ExportedSymbol(s._2)) implicit val pos = ctors.head.pos @@ -106,7 +94,6 @@ trait GenJSExports extends SubComponent { self: GenJSCode => exp <- jsInterop.registeredExportsOf(classSym) } yield { implicit val pos = exp.pos - assert(!exp.isNamed, "Class cannot be exported named") exp.destination match { case ExportDestination.Normal | ExportDestination.TopLevel => @@ -123,7 +110,6 @@ trait GenJSExports extends SubComponent { self: GenJSCode => exp <- jsInterop.registeredExportsOf(classSym) } yield { implicit val pos = exp.pos - assert(!exp.isNamed, "Module cannot be exported named") exp.destination match { case ExportDestination.Normal => @@ -237,66 +223,6 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } } - /** Tests whether the given def a named exporter def that needs to be - * generated with `genNamedExporterDef`. - */ - def isNamedExporterDef(dd: DefDef): Boolean = { - jsInterop.isExport(dd.symbol) && - dd.symbol.annotations.exists(_.symbol == JSExportNamedAnnotation) - } - - /** Generate the exporter proxy for a named export */ - def genNamedExporterDef(dd: DefDef): Option[js.MethodDef] = { - implicit val pos = dd.pos - - if (isAbstractMethod(dd)) { - None - } else { - val sym = dd.symbol - - val Block(Apply(fun, _) :: Nil, _) = dd.rhs - val trgSym = fun.symbol - - val inArg = - js.ParamDef(js.Ident("namedParams"), jstpe.AnyType, - mutable = false, rest = false) - val inArgRef = inArg.ref - - val methodIdent = encodeMethodSym(sym) - - Some(js.MethodDef(static = false, methodIdent, - List(inArg), toIRType(sym.tpe.resultType), - Some(genNamedExporterBody(trgSym, inArg.ref)))( - OptimizerHints.empty, None)) - } - } - - private def genNamedExporterBody(trgSym: Symbol, inArg: js.Tree)( - implicit pos: Position) = { - - if (hasRepeatedParam(trgSym)) { - reporter.error(pos, - "You may not name-export a method with a *-parameter") - } - - val jsArgs = for { - (pSym, index) <- trgSym.info.params.zipWithIndex - } yield { - val rhs = js.JSBracketSelect(inArg, - js.StringLiteral(pSym.name.decoded)) - js.VarDef(js.Ident("namedArg$" + index), jstpe.AnyType, - mutable = false, rhs = rhs) - } - - val jsArgRefs = jsArgs.map(_.ref) - - // Generate JS code to prepare arguments (default getters and unboxes) - val jsArgPrep = genPrepareArgs(jsArgRefs, trgSym) - val jsResult = genResult(trgSym, jsArgPrep.map(_.ref), static = false) - - js.Block(jsArgs ++ jsArgPrep :+ jsResult) - } - private def genMemberExport(classSym: Symbol, name: TermName): js.Tree = { val alts = classSym.info.member(name).alternatives diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 84d99c36e9..52f63dfa8d 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -59,7 +59,6 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val JSBracketCallAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSBracketCall") lazy val JSExportAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExport") lazy val JSExportAllAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportAll") - lazy val JSExportNamedAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportNamed") lazy val JSExportStaticAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportStatic") lazy val JSExportTopLevelAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportTopLevel") lazy val JSImportAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSImport") diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala index af57a417bd..8bc88043e6 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala @@ -65,7 +65,6 @@ trait JSGlobalAddons extends JSDefinitions trait ExportInfo { val jsName: String val pos: Position - val isNamed: Boolean val destination: ExportDestination } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala index 63651c7223..c76c44abb8 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala @@ -21,11 +21,9 @@ trait PrepJSExports { this: PrepJSInterop => import scala.reflect.internal.Flags - case class ExportInfo(jsName: String, isNamed: Boolean, + case class ExportInfo(jsName: String, destination: ExportDestination)(val pos: Position) - extends jsInterop.ExportInfo { - assert(!isNamed || destination == ExportDestination.Normal) - } + extends jsInterop.ExportInfo private final val SuppressExportDeprecationsMsg = { "\n (you can suppress this warning in 0.6.x by passing the option " + @@ -98,12 +96,7 @@ trait PrepJSExports { this: PrepJSInterop => jsInterop.registerForExport(baseSym, topLevelAndStaticExports) // Actually generate exporter methods - normalExports.flatMap { exp => - if (exp.isNamed) - genNamedExport(baseSym, exp.jsName, exp.pos) :: Nil - else - genExportDefs(baseSym, exp.jsName, exp.pos) - } + normalExports.flatMap(exp => genExportDefs(baseSym, exp.jsName, exp.pos)) } } @@ -147,16 +140,7 @@ trait PrepJSExports { this: PrepJSInterop => } else if (!isMod && !hasAnyNonPrivateCtor) { err("You may not export a class that has only private constructors") } else { - val (named, normal) = exports.partition(_.isNamed) - - for { - exp <- named - } { - reporter.error(exp.pos, "You may not use @JSNamedExport on " + - (if (isMod) "an object" else "a Scala.js-defined JS class")) - } - - jsInterop.registerForExport(sym, normal) + jsInterop.registerForExport(sym, exports) } } } @@ -204,7 +188,6 @@ trait PrepJSExports { this: PrepJSInterop => val allExportInfos = for { annot <- directAnnots ++ unitAnnots } yield { - val isNamedExport = annot.symbol == JSExportNamedAnnotation val isExportAll = annot.symbol == JSExportAllAnnotation val isTopLevelExport = annot.symbol == JSExportTopLevelAnnotation val isStaticExport = annot.symbol == JSExportStaticAnnotation @@ -288,8 +271,7 @@ trait PrepJSExports { this: PrepJSInterop => case ExportDestination.Normal => // Make sure we do not override the default export of toString def isIllegalToString = { - isMember && !isNamedExport && - name == "toString" && sym.name != nme.toString_ && + isMember && name == "toString" && sym.name != nme.toString_ && sym.tpe.params.isEmpty && !jsInterop.isJSGetter(sym) } if (isIllegalToString) { @@ -297,11 +279,6 @@ trait PrepJSExports { this: PrepJSInterop => "method named other than 'toString' under the name 'toString'") } - if (isNamedExport && jsInterop.isJSProperty(sym)) { - reporter.error(annot.pos, - "You may not export a getter or a setter as a named export") - } - // Don't allow nested class / module exports without explicit name. def isStaticNested = { /* For Scala.js defined JS classes, sym is the class itself. For @@ -388,7 +365,7 @@ trait PrepJSExports { this: PrepJSInterop => } } - ExportInfo(name, isNamedExport, destination)(annot.pos) + ExportInfo(name, destination)(annot.pos) } /* Filter out static exports of accessors (as they are not actually @@ -483,7 +460,6 @@ trait PrepJSExports { this: PrepJSInterop => // Remove export annotations expSym.removeAnnotation(JSExportAnnotation) - expSym.removeAnnotation(JSExportNamedAnnotation) // Add symbol to class clsSym.info.decls.enter(expSym) @@ -500,43 +476,6 @@ trait PrepJSExports { this: PrepJSInterop => exporter :: defaultGetters } - /** Generate a dummy DefDef tree for a named export. This tree is captured - * by GenJSCode again to generate the required JavaScript logic. - */ - private def genNamedExport(defSym: Symbol, jsName: String, pos: Position) = { - val clsSym = defSym.owner - val scalaName = jsInterop.scalaExportName(jsName, false) - - // Create symbol for the new exporter method - val expSym = clsSym.newMethodSymbol(scalaName, pos, - Flags.SYNTHETIC | Flags.FINAL) - - // Mark the symbol to be a named export - expSym.addAnnotation(JSExportNamedAnnotation) - - // Create a single parameter of type Any - val param = expSym.newValueParameter(newTermName("namedArgs"), pos) - param.setInfo(AnyTpe) - - // Set method type - expSym.setInfo(MethodType(param :: Nil, AnyClass.tpe)) - - // Register method to parent - clsSym.info.decls.enter(expSym) - - // Placeholder tree - def ph = Ident(Predef_???) - - // Create a call to the forwarded method with ??? as args - val sel: Tree = Select(This(clsSym), defSym) - val call = (sel /: defSym.paramss) { - (fun, params) => Apply(fun, List.fill(params.size)(ph)) - } - - // rhs is a block to prevent boxing of result - typer.typedDefDef(DefDef(expSym, Block(call, ph))) - } - private def genExportDefaultGetter(clsSym: Symbol, trgMethod: Symbol, exporter: Symbol, paramPos: Int, pos: Position) = { @@ -613,7 +552,6 @@ trait PrepJSExports { this: PrepJSInterop => /** Whether a symbol is an annotation that goes directly on a member */ private lazy val isDirectMemberAnnot = Set[Symbol]( JSExportAnnotation, - JSExportNamedAnnotation, JSExportTopLevelAnnotation, JSExportStaticAnnotation ) diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index 08d52f9b27..dbb5bb4902 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -734,179 +734,6 @@ class JSExportTest extends DirectTest with TestHelpers { } - @Test - def namedExportIsDeprecated: Unit = { - - """ - class A { - @JSExportNamed - def foo(x: Int, y: Int) = 1 - } - """ hasWarns - s""" - |newSource1.scala:5: warning: class JSExportNamed in package annotation is deprecated${since("0.6.11")}: Use @JSExport with an explicit option bag instead. See the Scaladoc for more details. - | def foo(x: Int, y: Int) = 1 - | ^ - |newSource1.scala:4: warning: class JSExportNamed in package annotation is deprecated${since("0.6.11")}: Use @JSExport with an explicit option bag instead. See the Scaladoc for more details. - | @JSExportNamed - | ^ - """ - - } - - @Test - def noOverrideNamedExport: Unit = { - - """ - class A { - @JSExportNamed - def foo(x: Int, y: Int) = 1 - } - - class B extends A { - @JSExportNamed - override def foo(x: Int, y: Int) = 2 - } - """ hasErrors - s""" - |newSource1.scala:5: warning: class JSExportNamed in package annotation is deprecated${since("0.6.11")}: Use @JSExport with an explicit option bag instead. See the Scaladoc for more details. - | def foo(x: Int, y: Int) = 1 - | ^ - |newSource1.scala:4: warning: class JSExportNamed in package annotation is deprecated${since("0.6.11")}: Use @JSExport with an explicit option bag instead. See the Scaladoc for more details. - | @JSExportNamed - | ^ - |newSource1.scala:9: error: overriding method $$js$$exported$$meth$$foo in class A of type (namedArgs: Any)Any; - | method $$js$$exported$$meth$$foo cannot override final member - | @JSExportNamed - | ^ - |newSource1.scala:10: warning: class JSExportNamed in package annotation is deprecated${since("0.6.11")}: Use @JSExport with an explicit option bag instead. See the Scaladoc for more details. - | override def foo(x: Int, y: Int) = 2 - | ^ - """ - - } - - @Test - def noConflictNamedExport: Unit = { - - // Normal method - """ - class A { - @JSExportNamed - def foo(x: Int, y: Int) = 1 - - @JSExport - def foo(x: scala.scalajs.js.Any) = 2 - } - """ fails() // No error test, Scala version dependent error messages - - // Ctors - """ - class A { - @JSExportNamed - def this(x: Int) = this() - - @JSExport - def this(x: scala.scalajs.js.Any) = this - - @JSExportNamed - def this(x: Long) = this() - } - """ fails() // No error test, Scala version dependent error messages - - } - - @Test - def noNamedExportObject: Unit = { - - """ - @JSExportNamed - object A - - @JSExportNamed - object B extends js.Object - """ hasErrors - """ - |newSource1.scala:3: error: You may not use @JSNamedExport on an object - | @JSExportNamed - | ^ - |newSource1.scala:6: error: You may not use @JSNamedExport on an object - | @JSExportNamed - | ^ - """ - - } - - @Test - def noNamedExportSJSDefinedClass: Unit = { - - """ - @JSExportNamed - class A extends js.Object - """ hasErrors - """ - |newSource1.scala:3: error: You may not use @JSNamedExport on a Scala.js-defined JS class - | @JSExportNamed - | ^ - """ - - } - - @Test - def noNamedExportVarArg: Unit = { - - """ - class A { - @JSExportNamed - def foo(a: Int*) = 1 - } - """ hasErrors - s""" - |newSource1.scala:5: warning: class JSExportNamed in package annotation is deprecated${since("0.6.11")}: Use @JSExport with an explicit option bag instead. See the Scaladoc for more details. - | def foo(a: Int*) = 1 - | ^ - |newSource1.scala:4: warning: class JSExportNamed in package annotation is deprecated${since("0.6.11")}: Use @JSExport with an explicit option bag instead. See the Scaladoc for more details. - | @JSExportNamed - | ^ - |newSource1.scala:4: error: You may not name-export a method with a *-parameter - | @JSExportNamed - | ^ - """ - - } - - @Test - def noNamedExportProperty: Unit = { - - // Getter - """ - class A { - @JSExportNamed - def a = 1 - } - """ hasErrors - """ - |newSource1.scala:4: error: You may not export a getter or a setter as a named export - | @JSExportNamed - | ^ - """ - - - // Setter - """ - class A { - @JSExportNamed - def a_=(x: Int) = () - } - """ hasErrors - """ - |newSource1.scala:4: error: You may not export a getter or a setter as a named export - | @JSExportNamed - | ^ - """ - - } - @Test def gracefulDoubleDefaultFail: Unit = { // This used to blow up (i.e. not just fail), because PrepJSExports asked @@ -973,17 +800,15 @@ class JSExportTest extends DirectTest with TestHelpers { | ^ """ - // For this case, deprecation warnings are not exactly the same in 2.10.x """ @JSExportAll class A { - @JSExportNamed("apply") @JSExport("foo") def apply(): Int = 1 } - """ containsWarns + """ hasWarns """ - |newSource1.scala:7: warning: Member cannot be exported to function application. It is available under the name apply instead. Add @JSExport("apply") to silence this warning. This will be enforced in 1.0. + |newSource1.scala:6: warning: Member cannot be exported to function application. It is available under the name apply instead. Add @JSExport("apply") to silence this warning. This will be enforced in 1.0. | def apply(): Int = 1 | ^ """ diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSExportNamed.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSExportNamed.scala deleted file mode 100644 index bb91787f62..0000000000 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSExportNamed.scala +++ /dev/null @@ -1,74 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.scalajs.js.annotation - -/** Exports the given method to JavaScript with named parameters. - * - * It can then be called like this: - * {{{ - * obj.foo({ - * param1: value1 - * param2: value2 - * param7: value3 - * }); - * }}} - * - * Note that named exports don't support overloading. Therefore the - * following will fail: - * {{{ - * class A { - * @JSExportNamed - * def a(foo: Int) = foo + 1 - * @JSExportNamed - * def a(bar: String) = "Hello " + bar - * } - * }}} - * - * As of Scala.js 0.6.11, `@JSExportNamed` is deprecated without direct - * replacement (see [[https://github.com/scala-js/scala-js/issues/2442]]). - * You should take a single parameter of a JS type and decompose it yourself. - * For example, instead of - * {{{ - * class A { - * @JSExportNamed - * def foo(a: Int, b: String, c: Boolean = false): Unit = { - * // do something with a, b, c - * } - * } - * }}} - * you should write: - * {{{ - * trait FooOptions extends js.Object { - * val a: Int - * val b: String - * val c: js.UndefOr[Boolean] - * } - * - * class A { - * @JSExport - * def foo(options: FooOptions): Unit = { - * val a = options.a - * val b = options.b - * val c = options.c.getOrElse(false) - * // do something with a, b, c - * } - * } - * }}} - * - * @see [[http://www.scala-js.org/doc/export-to-javascript.html Export Scala.js APIs to JavaScript]] - */ -@deprecated( - "Use @JSExport with an explicit option bag instead. " + - "See the Scaladoc for more details.", - "0.6.11") -class JSExportNamed extends scala.annotation.StaticAnnotation { - def this(name: String) = this() -} diff --git a/stubs/src/main/scala/scala/scalajs/js/annotation/ExportAnnotations.scala b/stubs/src/main/scala/scala/scalajs/js/annotation/ExportAnnotations.scala index da307d0c26..b000bd268a 100644 --- a/stubs/src/main/scala/scala/scalajs/js/annotation/ExportAnnotations.scala +++ b/stubs/src/main/scala/scala/scalajs/js/annotation/ExportAnnotations.scala @@ -13,10 +13,6 @@ import scala.annotation.Annotation class JSExportAll extends scala.annotation.Annotation -class JSExportNamed extends scala.annotation.Annotation { - def this(name: String) = this() -} - class JSExport extends scala.annotation.Annotation { def this(name: String) = this() } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index 028a3caa51..7daa76d5f7 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -1024,43 +1024,6 @@ class ExportsTest { assertEquals(1, foo.b) } - @Test def named_exports(): Unit = { - import js.Dynamic.{literal => lit} - - class FooNamed { - @JSExportNamed("bar1") - def bar(x: Int, y: Int): Int = x + y - - @JSExportNamed("bar2") - @JSExport - def bar(x: Int = 1)(y: Int = x)(z: Int = y): Int = x + y + z - } - - val foo = (new FooNamed).asInstanceOf[js.Dynamic] - - assertEquals(3, foo.bar1(lit(x = 1, y = 2))) - if (hasCompliantAsInstanceOfs) - assertThrows(classOf[Exception], foo.bar1(lit(x = 1)))// missing arg - assertEquals(3, foo.bar2(lit())) - assertEquals(6, foo.bar2(lit(x = 2))) - assertEquals(5, foo.bar2(lit(y = 2))) - assertEquals(4, foo.bar2(lit(y = 2, z = 1))) - assertEquals(6, foo.bar(2)) - assertEquals(8, foo.bar(2,3)) - } - - @Test def named_constructor_exports(): Unit = { - import js.Dynamic.{literal => lit} - - val constr = jsPackage.ExportedNamedArgClass - val result1 = js.Dynamic.newInstance(constr)(lit(x = 2)).result - assertEquals("22true", result1) - val result2 = js.Dynamic.newInstance(constr)(lit(y = "foo")).result - assertEquals("1foofalse", result2) - val result3 = js.Dynamic.newInstance(constr)(lit(z = true, y = "foo")).result - assertEquals("1footrue", result3) - } - @Test def exporting_under_org_namespace_issue_364(): Unit = { val accessor = exportsNamespace.org.ExportedUnderOrgObject assertEquals("function", js.typeOf(accessor)) @@ -1511,12 +1474,6 @@ object ExportedUnderOrgObject class SomeValueClass(val i: Int) extends AnyVal -@JSExportNamed -class ExportedNamedArgClass(x: Int = 1)(y: String = x.toString)(z: Boolean = y != "foo") { - @JSExport - val result = x + y + z -} - @JSExport class ExportClassSetterNamed_= { // scalastyle:ignore @JSExport From 497e46351ae264e8b5ce8ee650515971733f9ec7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 10 Apr 2017 20:57:14 +0200 Subject: [PATCH 0209/2665] Blacklist two tests using .java source files in 2.12.{0,1}. They were already blacklisted in 2.11.x versions, because they use .java source files. Somehow they got whitelisted in 2.12.{0,1}, and survived because bypassing linking errors was tolerated. However, as we drop support for that, they need to be blacklisted. --- .../scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt | 2 ++ .../scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt | 2 -- .../scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt | 2 ++ .../scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt | 2 -- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt index cf3808febe..6efe1fcd2f 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt @@ -936,6 +936,8 @@ run/t3452g run/t3452d run/t3452b run/t3452a +run/t1430 +run/t4729 run/t8442 run/t8601e run/t9298 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt index ecffa5252b..966a720394 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt @@ -3138,9 +3138,7 @@ run/trait-defaults-modules2 pos/functions.scala pos/MailBox.scala neg/t6289 -run/t4729 run/t6114.scala -run/t1430 pos/constant-warning.scala pos/t2712-5.scala pos/t2712-2.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt index 71e7dfb7fa..7de2dbca19 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt @@ -946,6 +946,8 @@ run/t3452g run/t3452d run/t3452b run/t3452a +run/t1430 +run/t4729 run/t8442 run/t8601e run/t9298 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt index 1591a9bbcb..0f9ed70192 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt @@ -3136,9 +3136,7 @@ run/trait-defaults-modules2 pos/functions.scala pos/MailBox.scala neg/t6289 -run/t4729 run/t6114.scala -run/t1430 pos/constant-warning.scala pos/t2712-5.scala pos/t2712-2.scala From d8a9329fc24ee03caac023da17d596db7f98b358 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 10 Apr 2017 13:33:19 +0200 Subject: [PATCH 0210/2665] Remove support for bypassing linking errors. --- build.sbt | 1 - ci/matrix.xml | 8 -- .../scala/org/scalajs/cli/Scalajsld.scala | 12 --- .../noircheck/DummyParentsTest.scala | 31 ------ project/Build.scala | 15 +-- .../scalajs/sbtplugin/OptimizerOptions.scala | 16 +-- .../sbtplugin/ScalaJSPluginInternal.scala | 1 - .../core/tools/linker/LinkedClass.scala | 27 ----- .../core/tools/linker/LinkingUnit.scala | 28 +---- .../core/tools/linker/analyzer/Analysis.scala | 1 - .../core/tools/linker/analyzer/Analyzer.scala | 10 +- .../tools/linker/frontend/BaseLinker.scala | 102 ++++-------------- .../linker/frontend/LinkerFrontend.scala | 28 +---- .../core/tools/linker/frontend/Refiner.scala | 42 ++++---- .../frontend/optimizer/GenIncOptimizer.scala | 4 +- 15 files changed, 55 insertions(+), 271 deletions(-) delete mode 100644 no-ir-check-test/src/test/scala/org/scalajs/testsuite/noircheck/DummyParentsTest.scala diff --git a/build.sbt b/build.sbt index e2f6adc44e..69adf9832f 100644 --- a/build.sbt +++ b/build.sbt @@ -29,7 +29,6 @@ val reversi = Build.reversi val testingExample = Build.testingExample val testSuite = Build.testSuite val testSuiteJVM = Build.testSuiteJVM -val noIrCheckTest = Build.noIrCheckTest val testSuiteEx = Build.testSuiteEx val partest = Build.partest val partestSuite = Build.partestSuite diff --git a/ci/matrix.xml b/ci/matrix.xml index 78b53c7d93..323813d7f0 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -85,10 +85,6 @@ 'set scalaJSStage in Global := FullOptStage' \ ++$scala $testSuite/test \ $testSuite/clean && - sbtretry ++$scala noIrCheckTest/test && - sbtretry 'set scalaJSStage in Global := FullOptStage' \ - ++$scala noIrCheckTest/test \ - noIrCheckTest/clean && sbtretry 'set scalaJSOptimizerOptions in $testSuite ~= (_.withDisableOptimizer(true))' \ ++$scala $testSuite/test \ $testSuite/clean && @@ -128,10 +124,6 @@ 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv().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().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 scalaJSOptimizerOptions in $testSuite ~= (_.withDisableOptimizer(true))' \ diff --git a/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala b/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala index f1c0374882..40c3a679fe 100644 --- a/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala +++ b/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala @@ -41,7 +41,6 @@ object Scalajsld { prettyPrint: Boolean = false, sourceMap: Boolean = false, relativizeSourceMap: Option[URI] = None, - bypassLinkingErrors: Boolean = false, checkIR: Boolean = false, stdLib: Option[File] = None, logLevel: Level = Level.Info) @@ -123,9 +122,6 @@ object Scalajsld { opt[ModuleKind]('k', "moduleKind") .action { (kind, c) => c.copy(moduleKind = kind) } .text("Module kind " + ModuleKind.All.mkString("(", ", ", ")")) - opt[Unit]('b', "bypassLinkingErrors") - .action { (_, c) => c.copy(bypassLinkingErrors = true) } - .text("Only warn if there are linking errors (deprecated)") opt[Unit]('c', "checkIR") .action { (_, c) => c.copy(checkIR = true) } .text("Check IR before optimizing") @@ -177,19 +173,11 @@ object Scalajsld { "if you rely on this feature.") } - // Warn if bypassing linking errors was requested. - if (options.bypassLinkingErrors) { - Console.err.println( - "Support for bypassing linking errors with -b or " + - "--bypassLinkingErrors will be dropped in the next major version.") - } - val semantics = if (options.fullOpt) options.semantics.optimized else options.semantics val frontendConfig = LinkerFrontend.Config() - .withBypassLinkingErrorsInternal(options.bypassLinkingErrors) .withCheckIR(options.checkIR) val backendConfig = LinkerBackend.Config() diff --git a/no-ir-check-test/src/test/scala/org/scalajs/testsuite/noircheck/DummyParentsTest.scala b/no-ir-check-test/src/test/scala/org/scalajs/testsuite/noircheck/DummyParentsTest.scala deleted file mode 100644 index 588ad4752a..0000000000 --- a/no-ir-check-test/src/test/scala/org/scalajs/testsuite/noircheck/DummyParentsTest.scala +++ /dev/null @@ -1,31 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ -package org.scalajs.testsuite.noircheck - -import org.junit.Test - -class DummyParentsTest { - - @Test def linking_stages_should_provide_dummy_parents_if_required(): Unit = { - - import scala.concurrent.forkjoin._ - - // scala.concurrent.forkjoin.ForkJoinWorkerThread is not defined - class DummyFJWorkerThread extends ForkJoinWorkerThread(null) { - override def onStart(): Unit = { /* something */ } - } - - val x = "1".toInt - - if (x + x < 0) { - // Ensure DummyFuture is not DCEd, but never instantiated - new DummyFJWorkerThread() - } - - } -} diff --git a/project/Build.scala b/project/Build.scala index 3371253df0..aa6d095620 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -468,7 +468,7 @@ object Build { clean in jUnitTestOutputsJS, clean in jUnitTestOutputsJVM, clean in examples, clean in helloworld, clean in reversi, clean in testingExample, - clean in testSuite, clean in testSuiteJVM, clean in noIrCheckTest, + clean in testSuite, clean in testSuiteJVM, clean in testSuiteEx, clean in partest, clean in partestSuite, clean in scalaTestSuite).value, @@ -1524,19 +1524,6 @@ object Build { "com.novocode" % "junit-interface" % "0.11" % "test" ) - lazy val noIrCheckTest: Project = (project in file("no-ir-check-test")).settings( - commonSettings, - myScalaJSSettings, - testTagSettings, - 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) - /* 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 diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/OptimizerOptions.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/OptimizerOptions.scala index 5ed475f5ab..8cd1b5fbd7 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/OptimizerOptions.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/OptimizerOptions.scala @@ -20,8 +20,6 @@ import OptimizerOptions._ * instance. */ final class OptimizerOptions private ( - /** Whether to only warn if the linker has errors */ - val bypassLinkingErrors: Boolean = false, /** Whether to parallelize the optimizer (currently fastOptJS only) **/ val parallel: Boolean = true, /** Whether to run the optimizer in batch (i.e. non-incremental) mode */ @@ -36,12 +34,6 @@ final class OptimizerOptions private ( val useClosureCompiler: Boolean = false ) { - @deprecated( - "Bypassing linking errors will not be possible in the next major version.", - "0.6.6") - def withBypassLinkingErrors(bypassLinkingErrors: Boolean): OptimizerOptions = - copy(bypassLinkingErrors = bypassLinkingErrors) - def withParallel(parallel: Boolean): OptimizerOptions = copy(parallel = parallel) @@ -60,20 +52,18 @@ final class OptimizerOptions private ( def withUseClosureCompiler(useClosureCompiler: Boolean): OptimizerOptions = copy(useClosureCompiler = useClosureCompiler) - private def copy(bypassLinkingErrors: Boolean = bypassLinkingErrors, + private def copy( parallel: Boolean = parallel, batchMode: Boolean = batchMode, disableOptimizer: Boolean = disableOptimizer, prettyPrintFullOptJS: Boolean = prettyPrintFullOptJS, checkScalaJSIR: Boolean = checkScalaJSIR, useClosureCompiler: Boolean = useClosureCompiler) = { - new OptimizerOptions(bypassLinkingErrors, parallel, batchMode, - disableOptimizer, prettyPrintFullOptJS, checkScalaJSIR, - useClosureCompiler) + new OptimizerOptions(parallel, batchMode, disableOptimizer, + prettyPrintFullOptJS, checkScalaJSIR, useClosureCompiler) } override def toString: String = { s"""OptimizerOptions( - | bypassLinkingErrors = $bypassLinkingErrors | parallel = $parallel | batchMode = $batchMode | disableOptimizer = $disableOptimizer diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 6d427abdb7..3d32731dee 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -186,7 +186,6 @@ object ScalaJSPluginInternal { } val frontendConfig = LinkerFrontend.Config() - .withBypassLinkingErrorsInternal(opts.bypassLinkingErrors) .withCheckIR(opts.checkScalaJSIR) val backendConfig = LinkerBackend.Config() diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala index 5075a5df87..ab66eeda81 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala @@ -211,31 +211,4 @@ object LinkedClass { version = None) } - def dummyParent(encodedName: String, version: Option[String]): LinkedClass = { - import ir.Trees.{Ident, OptimizerHints} - - implicit val pos = Position.NoPosition - - new LinkedClass( - name = Ident(encodedName), - kind = ClassKind.Class, - superClass = Some(Ident(Definitions.ObjectClass)), - interfaces = Nil, - jsNativeLoadSpec = None, - fields = Nil, - staticMethods = Nil, - memberMethods = Nil, - abstractMethods = Nil, - exportedMembers = Nil, - classExports = Nil, - classExportInfo = None, - optimizerHints = OptimizerHints.empty, - pos = Position.NoPosition, - ancestors = List(Definitions.ObjectClass, encodedName), - hasInstances = true, - hasInstanceTests = true, - hasRuntimeTypeInfo = true, - version = version) - } - } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala index 6b8150b197..44cf25a40a 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala @@ -11,23 +11,11 @@ final class LinkingUnit private[linker] ( val esLevel: ESLevel, val classDefs: List[LinkedClass], private[linker] val infosInternal: Map[String, Infos.ClassInfo], - val moduleInitializers: List[ModuleInitializer], - val isComplete: Boolean + val moduleInitializers: List[ModuleInitializer] ) { import LinkingUnit._ - /** Creates a `LinkingUnit` without any entry point. */ - @deprecated( - "The LinkingUnit constructor was not intended to be exposed to user " + - "code. It will be removed in 1.0.0.", - "0.6.15") - def this(semantics: Semantics, esLevel: ESLevel, classDefs: List[LinkedClass], - infos: Map[String, Infos.ClassInfo], isComplete: Boolean) = { - this(semantics, esLevel, classDefs, infos, moduleInitializers = Nil, - isComplete) - } - @deprecated( "LinkingUnit.infos was not intended to be exposed to user code. " + "It will be removed in 1.0.0. " + @@ -57,20 +45,10 @@ final class LinkingUnit private[linker] ( } } - @deprecated( - "LinkingUnit.updated was not intended to be exposed to user code. " + - "It will be removed in 1.0.0.", - "0.6.15") - def updated(classDefs: List[LinkedClass], isComplete: Boolean): LinkingUnit = - updatedInternal(classDefs, isComplete) - - /** Non-deprecated version of `updated` for internal use. */ - private[linker] def updatedInternal(classDefs: List[LinkedClass], - isComplete: Boolean): LinkingUnit = { + private[linker] def updated(classDefs: List[LinkedClass]): LinkingUnit = { val newInfos = infosInternal ++ classDefs.map(cd => cd.encodedName -> cd.toInfo) - new LinkingUnit(semantics, esLevel, classDefs, newInfos, moduleInitializers, - isComplete) + new LinkingUnit(semantics, esLevel, classDefs, newInfos, moduleInitializers) } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala index 33475cbe33..18b209f638 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala @@ -29,7 +29,6 @@ import ir.Definitions.{decodeClassName, decodeMethodName} trait Analysis { import Analysis._ - def allAvailable: Boolean def classInfos: scala.collection.Map[String, ClassInfo] def errors: Seq[Error] } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala index 74a084498e..340a22b80f 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala @@ -25,13 +25,11 @@ private final class Analyzer(semantics: Semantics, import Analyzer._ import Analysis._ - private[this] var _allAvailable: Boolean = true private[this] val _classInfos = mutable.Map.empty[String, ClassInfo] private[this] val _errors = mutable.Buffer.empty[Error] private val fromAnalyzer = FromCore("analyzer") - def allAvailable: Boolean = _allAvailable def classInfos: scala.collection.Map[String, Analysis.ClassInfo] = _classInfos def errors: Seq[Error] = _errors @@ -668,10 +666,8 @@ private final class Analyzer(semantics: Semantics, } def checkExistent()(implicit from: From): Unit = { - if (nonExistent) { + if (nonExistent) _errors += MissingClass(this, from) - _allAvailable = false - } } def callMethod(methodName: String, statically: Boolean = false)( @@ -771,10 +767,8 @@ private final class Analyzer(semantics: Semantics, } private def checkExistent()(implicit from: From) = { - if (nonExistent) { + if (nonExistent) _errors += MissingMethod(this, from) - _allAvailable = false - } } private[this] def doReach(): Unit = { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index 62949e3d68..f04ed3f749 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -51,38 +51,6 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, def link(irInput: Seq[VirtualScalaJSIRFile], moduleInitializers: Seq[ModuleInitializer], logger: Logger, symbolRequirements: SymbolRequirement, checkIR: Boolean): LinkingUnit = { - linkInternal(irInput, moduleInitializers, logger, symbolRequirements, - bypassLinkingErrors = false, checkIR = checkIR) - } - - @deprecated( - "Bypassing linking errors will not be possible in the next major version. " + - "Use the overload without the bypassLinkingError parameter instead.", - "0.6.6") - def link(irInput: Seq[VirtualScalaJSIRFile], logger: Logger, - symbolRequirements: SymbolRequirement, bypassLinkingErrors: Boolean, - checkIR: Boolean): LinkingUnit = { - linkInternal(irInput, Nil, logger, symbolRequirements, - bypassLinkingErrors, checkIR) - } - - @deprecated( - "Bypassing linking errors will not be possible in the next major version. " + - "Use the overload without the bypassLinkingError parameter instead.", - "0.6.6") - def link(irInput: Seq[VirtualScalaJSIRFile], - moduleInitializers: Seq[ModuleInitializer], logger: Logger, - symbolRequirements: SymbolRequirement, bypassLinkingErrors: Boolean, - checkIR: Boolean): LinkingUnit = { - linkInternal(irInput, moduleInitializers, logger, symbolRequirements, - bypassLinkingErrors, checkIR) - } - - // Non-deprecated version to be called from `LinkerFrontend` - private[frontend] def linkInternal(irInput: Seq[VirtualScalaJSIRFile], - moduleInitializers: Seq[ModuleInitializer], logger: Logger, - symbolRequirements: SymbolRequirement, bypassLinkingErrors: Boolean, - checkIR: Boolean): LinkingUnit = { val infosBuilder = List.newBuilder[Infos.ClassInfo] val encodedNameToFile = mutable.Map.empty[String, VirtualScalaJSIRFile] @@ -105,13 +73,13 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, } linkInternal(infos, getTree, moduleInitializers, logger, symbolRequirements, - bypassLinkingErrors, checkIR) + checkIR) } private def linkInternal(infoInput: List[Infos.ClassInfo], getTree: TreeProvider, moduleInitializers: Seq[ModuleInitializer], logger: Logger, symbolRequirements: SymbolRequirement, - bypassLinkingErrors: Boolean, checkIR: Boolean): LinkingUnit = { + checkIR: Boolean): LinkingUnit = { if (checkIR) { logger.time("Linker: Check Infos") { @@ -133,14 +101,6 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, } if (analysis.errors.nonEmpty) { - // TODO Make it always fatal when we can get rid of bypassLinkingErrors - val fatal = !bypassLinkingErrors || analysis.errors.exists { - case _: Analysis.MissingJavaLangObjectClass => true - case _: Analysis.CycleInInheritanceChain => true - case _ => false - } - - val linkingErrLevel = if (fatal) Level.Error else Level.Warn val maxDisplayErrors = { val propName = "org.scalajs.core.tools.linker.maxlinkingerrors" Try(System.getProperty(propName, "20").toInt).getOrElse(20).max(1) @@ -148,14 +108,13 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, analysis.errors .take(maxDisplayErrors) - .foreach(logError(_, logger, linkingErrLevel)) + .foreach(logError(_, logger, Level.Error)) val skipped = analysis.errors.size - maxDisplayErrors if (skipped > 0) - logger.log(linkingErrLevel, s"Not showing $skipped more linking errors") + logger.log(Level.Error, s"Not showing $skipped more linking errors") - if (fatal) - sys.error("There were linking errors") + sys.error("There were linking errors") } val linkResult = logger.time("Linker: Assemble LinkedClasses") { @@ -163,17 +122,13 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, } // Make sure we don't export to the same name twice. - checkConflictingExports(linkResult, logger, bypassLinkingErrors) + checkConflictingExports(linkResult, logger) if (checkIR) { logger.time("Linker: Check IR") { - if (linkResult.isComplete) { - val errorCount = IRChecker.check(linkResult, logger) - if (errorCount != 0) - sys.error(s"There were $errorCount IR checking errors.") - } else { - sys.error("Could not check IR because there were linking errors.") - } + val errorCount = IRChecker.check(linkResult, logger) + if (errorCount != 0) + sys.error(s"There were $errorCount IR checking errors.") } } @@ -184,28 +139,18 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, moduleInitializers: Seq[ModuleInitializer], analysis: Analysis) = { val infoByName = Map(infoInput.map(c => c.encodedName -> c): _*) - def optClassDef(analyzerInfo: Analysis.ClassInfo) = { + val linkedClassDefs = for { + analyzerInfo <- analysis.classInfos.values + if analyzerInfo.isNeededAtAll + } yield { val encodedName = analyzerInfo.encodedName - - def optDummyParent = - if (!analyzerInfo.isAnySubclassInstantiated) None - else Some(LinkedClass.dummyParent(encodedName, Some("dummy"))) - - infoByName.get(encodedName).map { info => - val (tree, version) = getTree(encodedName) - val newVersion = version.map("real" + _) // avoid collision with dummy - linkedClassDef(info, tree, analyzerInfo, newVersion, getTree, analysis) - }.orElse(optDummyParent) + val (tree, version) = getTree(encodedName) + linkedClassDef(infoByName(encodedName), tree, analyzerInfo, version, + getTree, analysis) } - val linkedClassDefs = for { - classInfo <- analysis.classInfos.values - if classInfo.isNeededAtAll - linkedClassDef <- optClassDef(classInfo) - } yield linkedClassDef - new LinkingUnit(semantics, esLevel, linkedClassDefs.toList, infoByName, - moduleInitializers.toList, analysis.allAvailable) + moduleInitializers.toList) } /** Takes a Infos, a ClassDef and DCE infos to construct a stripped down @@ -479,8 +424,8 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, } } - private def checkConflictingExports(unit: LinkingUnit, logger: Logger, - bypassLinkingErrors: Boolean): Unit = { + private def checkConflictingExports(unit: LinkingUnit, + logger: Logger): Unit = { val namesAndClasses = for { classDef <- unit.classDefs name <- classDef.topLevelExportNames @@ -488,21 +433,20 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, name -> classDef } - val level = if (bypassLinkingErrors) Level.Warn else Level.Error val errors = for { (name, namesAndClasses) <- namesAndClasses.groupBy(_._1) if namesAndClasses.size > 1 } yield { - logger.log(level, s"Conflicting top-level exports to $name from the " + - "following classes:") + logger.log(Level.Error, + s"Conflicting top-level exports to $name from the following classes:") for ((_, linkedClass) <- namesAndClasses) { - logger.log(level, s"- ${linkedClass.fullName}") + logger.log(Level.Error, s"- ${linkedClass.fullName}") } () } - if (errors.nonEmpty && !bypassLinkingErrors) { + if (errors.nonEmpty) { sys.error("There were conflicting exports.") } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala index 013201462a..0ac8ee4144 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala @@ -59,17 +59,12 @@ final class LinkerFrontend( } val linkResult = logger.time("Basic Linking") { - linker.linkInternal(irFiles, moduleInitializers, logger, - preOptimizerRequirements, config.bypassLinkingErrors, config.checkIR) + linker.link(irFiles, moduleInitializers, logger, + preOptimizerRequirements, config.checkIR) } optOptimizer.fold(linkResult) { optimizer => - if (linkResult.isComplete) { - optimize(linkResult, symbolRequirements, optimizer, logger) - } else { - logger.warn("Not running the optimizer because there were linking errors.") - linkResult - } + optimize(linkResult, symbolRequirements, optimizer, logger) } } @@ -88,30 +83,15 @@ final class LinkerFrontend( object LinkerFrontend { /** Configurations relevant to the frontend */ final class Config private ( - /** Whether to only warn if the linker has errors. */ - val bypassLinkingErrors: Boolean = false, /** If true, performs expensive checks of the IR for the used parts. */ val checkIR: Boolean = false ) { - @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) private def copy( - bypassLinkingErrors: Boolean = bypassLinkingErrors, checkIR: Boolean = checkIR): Config = { - new Config(bypassLinkingErrors, checkIR) + new Config(checkIR) } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala index 28a5e3cdf1..d23de59d56 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala @@ -31,38 +31,32 @@ final class Refiner { unit.infosInternal.values.toList, allowAddingSyntheticMethods = false) } - /* There really should not be linking errors at this point. If there are, - * it is most likely a bug in the optimizer. We should crash here, but we - * used to silently ignore any errors before 0.6.6. So currently we only - * warn, not to break compatibility. - * TODO Issue errors when we can break backward compatibility. + /* There must not be linking errors at this point. If there are, it is a + * bug in the optimizer. */ - analysis.errors.foreach(Analysis.logError(_, logger, Level.Warn)) + if (analysis.errors.nonEmpty) { + analysis.errors.foreach(Analysis.logError(_, logger, Level.Error)) + throw new AssertionError( + "There were linking errors after the optimizer has run. " + + "This is a bug, please report it. " + + "You can work around the bug by disabling the optimizer. " + + "In the sbt plugin, this can be done with " + + "`scalaJSOptimizerOptions ~= { _.withDisableOptimizer(true) }`.") + } logger.time("Refiner: Assemble LinkedClasses") { val linkedClassesByName = Map(unit.classDefs.map(c => c.encodedName -> c): _*) - def optClassDef(analyzerInfo: Analysis.ClassInfo) = { - val encodedName = analyzerInfo.encodedName - - def optDummyParent = - if (!analyzerInfo.isAnySubclassInstantiated) None - else Some(LinkedClass.dummyParent(encodedName, Some("dummy"))) - - linkedClassesByName.get(encodedName).map { - refineClassDef(_, analyzerInfo) - }.orElse(optDummyParent) - } - val linkedClassDefs = for { - classInfo <- analysis.classInfos.values - if classInfo.isNeededAtAll - linkedClassDef <- optClassDef(classInfo) - } yield linkedClassDef + analyzerInfo <- analysis.classInfos.values + if analyzerInfo.isNeededAtAll + } yield { + refineClassDef(linkedClassesByName(analyzerInfo.encodedName), + analyzerInfo) + } - unit.updatedInternal(classDefs = linkedClassDefs.toList, - isComplete = analysis.allAvailable) + unit.updated(classDefs = linkedClassDefs.toList) } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala index e5bfbd227f..dabcfb9a37 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala @@ -120,8 +120,6 @@ abstract class GenIncOptimizer private[optimizer] (semantics: Semantics, /** Update the incremental analyzer with a new run. */ def update(unit: LinkingUnit, logger: Logger): LinkingUnit = { - require(unit.isComplete, "Cannot optimize incomplete LinkingUnits") - withLogger(logger) { batchMode = objectClass == null logger.debug(s"Inc. optimizer: Batch mode: $batchMode") @@ -152,7 +150,7 @@ abstract class GenIncOptimizer private[optimizer] (semantics: Semantics, memberMethods = defs(memberNamespace)) } - unit.updatedInternal(classDefs = newLinkedClasses, isComplete = true) + unit.updated(classDefs = newLinkedClasses) } } From 5e0b23ad5a09a35ed15f200bea63c0d11ead7c71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 10 Apr 2017 18:15:17 +0200 Subject: [PATCH 0211/2665] Fix #2874: Remove the distinction libs/code in the JSEnv API. `JSEnv#jsRunner` and friends `asyncRunner` and `comRunner` now only take a `Seq[VirtualJSFiles]`, containing all JS files to be given to the JS environment. The JS environments therefore make no distinction between "library" files and the "code" file. The disinction was arbitrary anyway, and unifying them makes sure that all the JS files are first-class. In particular, it forced to solve shortcomings in terms of error handling in `JSDOMNodeJSEnv`. --- .../org/scalajs/jsenv/test/AsyncTests.scala | 2 +- .../org/scalajs/jsenv/test/ComTests.scala | 2 +- .../org/scalajs/jsenv/test/JSEnvTest.scala | 4 +- .../scala/org/scalajs/jsenv/AsyncJSEnv.scala | 10 +-- .../scala/org/scalajs/jsenv/ComJSEnv.scala | 9 +- .../org/scalajs/jsenv/ExternalJSEnv.scala | 25 +++--- .../main/scala/org/scalajs/jsenv/JSEnv.scala | 21 ++--- .../jsenv/nodejs/AbstractNodeJSEnv.scala | 2 +- .../scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala | 90 +++++++++++-------- .../org/scalajs/jsenv/nodejs/NodeJSEnv.scala | 30 +++---- .../scala/tools/nsc/MainGenericRunner.scala | 2 +- .../jsenv/phantomjs/PhantomJSEnv.scala | 51 +++-------- .../jsenv/phantomjs/RetryingComJSEnv.scala | 20 ++--- .../phantomjs/RetryingComJSEnvTest.scala | 18 ++-- project/Build.scala | 2 +- sbt-plugin-test/project/Jetty9Test.scala | 2 +- .../scalajs/sbtplugin/FrameworkDetector.scala | 2 +- .../sbtplugin/ScalaJSPluginInternal.scala | 4 +- .../sbttestadapter/ScalaJSFramework.scala | 2 +- .../sbttestadapter/ScalaJSRunner.scala | 4 +- 20 files changed, 133 insertions(+), 169 deletions(-) diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/AsyncTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/AsyncTests.scala index acb3830f45..a571573d5b 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/AsyncTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/AsyncTests.scala @@ -20,7 +20,7 @@ trait AsyncTests extends BasicJSEnvTests { protected def asyncRunner(code: String): AsyncJSRunner = { val codeVF = new MemVirtualJSFile("testScript.js").withContent(code) - newJSEnv.asyncRunner(codeVF) + newJSEnv.asyncRunner(codeVF :: Nil) } protected def start(runner: AsyncJSRunner): Future[Unit] = { diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala index cb6415d482..5959156b76 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala @@ -16,7 +16,7 @@ trait ComTests extends AsyncTests { protected def comRunner(code: String): ComJSRunner = { val codeVF = new MemVirtualJSFile("testScript.js").withContent(code) - newJSEnv.comRunner(codeVF) + newJSEnv.comRunner(codeVF :: Nil) } private def assertThrowClosed(msg: String, body: => Unit): Unit = { diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvTest.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvTest.scala index e48859924d..7d6adb78fd 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvTest.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvTest.scala @@ -22,7 +22,7 @@ abstract class JSEnvTest { val console = new StoreJSConsole() val logger = new StoreLogger() - newJSEnv.jsRunner(code).run(logger, console) + newJSEnv.jsRunner(code :: Nil).run(logger, console) val log = logger.getLog val hasBadLog = log exists { @@ -38,7 +38,7 @@ abstract class JSEnvTest { def fails(): Unit = { try { - newJSEnv.jsRunner(code).run(NullLogger, NullJSConsole) + newJSEnv.jsRunner(code :: Nil).run(NullLogger, NullJSConsole) assertTrue("Code snipped should fail", false) } catch { case e: Exception => diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSEnv.scala index 9b6c8dfcfe..9bf05fc5f9 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSEnv.scala @@ -12,18 +12,14 @@ package org.scalajs.jsenv import org.scalajs.core.tools.io.VirtualJSFile trait AsyncJSEnv extends JSEnv { - def asyncRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): AsyncJSRunner - - final def asyncRunner(code: VirtualJSFile): AsyncJSRunner = - asyncRunner(Nil, code) + def asyncRunner(files: Seq[VirtualJSFile]): AsyncJSRunner override def loadLibs(libs: Seq[VirtualJSFile]): AsyncJSEnv = new AsyncLoadedLibs { val loadedLibs = libs } private[jsenv] trait AsyncLoadedLibs extends LoadedLibs with AsyncJSEnv { - def asyncRunner(libs: Seq[VirtualJSFile], - code: VirtualJSFile): AsyncJSRunner = { - AsyncJSEnv.this.asyncRunner(loadedLibs ++ libs, code) + def asyncRunner(files: Seq[VirtualJSFile]): AsyncJSRunner = { + AsyncJSEnv.this.asyncRunner(loadedLibs ++ files) } } } diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/ComJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/ComJSEnv.scala index b20faad7f7..f6a2345d31 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/ComJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/ComJSEnv.scala @@ -27,17 +27,14 @@ import org.scalajs.core.tools.io.VirtualJSFile * }}} */ trait ComJSEnv extends AsyncJSEnv { - def comRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): ComJSRunner - - final def comRunner(code: VirtualJSFile): ComJSRunner = comRunner(Nil, code) + def comRunner(files: Seq[VirtualJSFile]): ComJSRunner override def loadLibs(libs: Seq[VirtualJSFile]): ComJSEnv = new ComLoadedLibs { val loadedLibs = libs } private[jsenv] trait ComLoadedLibs extends AsyncLoadedLibs with ComJSEnv { - def comRunner(libs: Seq[VirtualJSFile], - code: VirtualJSFile): ComJSRunner = { - ComJSEnv.this.comRunner(loadedLibs ++ libs, code) + def comRunner(files: Seq[VirtualJSFile]): ComJSRunner = { + ComJSEnv.this.comRunner(loadedLibs ++ files) } } } diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala index 872e7a9a80..7608cfb93f 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala @@ -36,8 +36,7 @@ abstract class ExternalJSEnv( protected def customInitFiles(): Seq[VirtualJSFile] = Nil protected class AbstractExtRunner( - protected val libs: Seq[VirtualJSFile], - protected val code: VirtualJSFile) extends JSInitFiles { + protected val files: Seq[VirtualJSFile]) extends JSInitFiles { private[this] var _logger: Logger = _ private[this] var _console: JSConsole = _ @@ -71,13 +70,15 @@ abstract class ExternalJSEnv( protected def getVMEnv(): Map[String, String] = sys.env ++ env - /** Get files that are a library (i.e. that do not run anything) */ - protected def getLibJSFiles(): Seq[VirtualJSFile] = - initFiles() ++ customInitFiles() ++ libs - - /** Get all files that are passed to VM (libraries and code) */ + /** All the JS files that are passed to the VM. + * + * This method can overridden to provide custom behavior in subclasses. + * + * The default value in `ExternalJSEnv` is + * `initFiles() ++ customInitFiles() ++ files`. + */ protected def getJSFiles(): Seq[VirtualJSFile] = - getLibJSFiles() :+ code + initFiles() ++ customInitFiles() ++ files /** write a single JS file to a writer using an include fct if appropriate */ protected def writeJSFile(file: VirtualJSFile, writer: Writer): Unit = { @@ -153,8 +154,8 @@ abstract class ExternalJSEnv( } - protected class ExtRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile) - extends AbstractExtRunner(libs, code) with JSRunner { + protected class ExtRunner(files: Seq[VirtualJSFile]) + extends AbstractExtRunner(files) with JSRunner { def run(logger: Logger, console: JSConsole): Unit = { setupLoggerAndConsole(logger, console) @@ -166,8 +167,8 @@ abstract class ExternalJSEnv( } } - protected class AsyncExtRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile) - extends AbstractExtRunner(libs, code) with AsyncJSRunner { + protected class AsyncExtRunner(files: Seq[VirtualJSFile]) + extends AbstractExtRunner(files) with AsyncJSRunner { private[this] var vmInst: Process = null private[this] var ioThreadEx: Throwable = null diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala index 202a7ffcda..c4e48ebb7b 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala @@ -15,24 +15,15 @@ trait JSEnv { /** Human-readable name for this [[JSEnv]] */ def name: String - /** Prepare a runner for the code in the virtual file. */ - def jsRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): JSRunner - - /** Prepare a runner without any libraries. - * - * Strictly equivalent to: - * {{{ - * this.jsRunner(Nil, code) - * }}} - */ - final def jsRunner(code: VirtualJSFile): JSRunner = jsRunner(Nil, code) + /** Prepare a runner with the specified JavaScript files. */ + def jsRunner(files: Seq[VirtualJSFile]): JSRunner /** Return this [[JSEnv]] with the given libraries already loaded. * * The following two are equivalent: * {{{ - * jsEnv.loadLibs(a).jsRunner(b, c) - * jsEnv.jsRunner(a ++ b, c) + * jsEnv.loadLibs(a).jsRunner(b) + * jsEnv.jsRunner(a ++ b) * }}} */ def loadLibs(libs: Seq[VirtualJSFile]): JSEnv = @@ -43,7 +34,7 @@ trait JSEnv { def name: String = JSEnv.this.name - def jsRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): JSRunner = - JSEnv.this.jsRunner(loadedLibs ++ libs, code) + def jsRunner(files: Seq[VirtualJSFile]): JSRunner = + JSEnv.this.jsRunner(loadedLibs ++ files) } } diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala index a5304b63e5..aac11422a9 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala @@ -41,7 +41,7 @@ abstract class AbstractNodeJSEnv( .withContent("""require('source-map-support').install();""") try { - jsRunner(code).run(NullLogger, NullJSConsole) + jsRunner(Seq(code)).run(NullLogger, NullJSConsole) true } catch { case t: ExternalJSEnv.NonZeroExitException => diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala index a39910431c..2ab94a17da 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala @@ -27,66 +27,66 @@ class JSDOMNodeJSEnv( protected def vmName: String = "Node.js with JSDOM" - override def jsRunner(libs: Seq[VirtualJSFile], - code: VirtualJSFile): JSRunner = { - new DOMNodeRunner(libs, code) - } + override def jsRunner(files: Seq[VirtualJSFile]): JSRunner = + new DOMNodeRunner(files) - override def asyncRunner(libs: Seq[VirtualJSFile], - code: VirtualJSFile): AsyncJSRunner = { - new AsyncDOMNodeRunner(libs, code) - } + override def asyncRunner(files: Seq[VirtualJSFile]): AsyncJSRunner = + new AsyncDOMNodeRunner(files) - override def comRunner(libs: Seq[VirtualJSFile], - code: VirtualJSFile): ComJSRunner = { - new ComDOMNodeRunner(libs, code) - } + override def comRunner(files: Seq[VirtualJSFile]): ComJSRunner = + new ComDOMNodeRunner(files) - protected class DOMNodeRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile) - extends ExtRunner(libs, code) with AbstractDOMNodeRunner + protected class DOMNodeRunner(files: Seq[VirtualJSFile]) + extends ExtRunner(files) with AbstractDOMNodeRunner - protected class AsyncDOMNodeRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile) - extends AsyncExtRunner(libs, code) with AbstractDOMNodeRunner + protected class AsyncDOMNodeRunner(files: Seq[VirtualJSFile]) + extends AsyncExtRunner(files) with AbstractDOMNodeRunner - protected class ComDOMNodeRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile) - extends AsyncDOMNodeRunner(libs, code) with NodeComJSRunner + protected class ComDOMNodeRunner(files: Seq[VirtualJSFile]) + extends AsyncDOMNodeRunner(files) with NodeComJSRunner protected trait AbstractDOMNodeRunner extends AbstractNodeRunner { protected def codeWithJSDOMContext(): Seq[VirtualJSFile] = { - val scriptsJSPaths = getLibJSFiles().map { + val scriptsPaths = getScriptsJSFiles().map { case file: FileVirtualFile => file.path case file => libCache.materialize(file).getAbsolutePath } - val scriptsStringPath = scriptsJSPaths.map('"' + escapeJS(_) + '"') + val scriptsURIs = + scriptsPaths.map(path => new java.io.File(path).toURI.toASCIIString) + val scriptsURIsAsJSStrings = scriptsURIs.map('"' + escapeJS(_) + '"') val jsDOMCode = { s""" |(function () { | const jsdom = require("jsdom"); - | var windowKeys = []; + | + | var virtualConsole = jsdom.createVirtualConsole() + | .sendTo(console, { omitJsdomErrors: true }); + | virtualConsole.on("jsdomError", function (error) { + | /* This inelegant if + console.error is the only way I found + | * to make sure the stack trace of the original error is + | * printed out. + | */ + | if (error.detail && error.detail.stack) + | console.error(error.detail.stack); + | + | // Throw the error anew to make sure the whole execution fails + | throw error; + | }); | | jsdom.env({ | html: "", - | virtualConsole: jsdom.createVirtualConsole().sendTo(console), + | url: "http://localhost/", + | virtualConsole: virtualConsole, | created: function (error, window) { | if (error == null) { | window["__ScalaJSEnv"] = __ScalaJSEnv; | window["scalajsCom"] = global.scalajsCom; - | windowKeys = Object.keys(window); | } else { - | console.log(error); + | throw error; | } | }, - | scripts: [${scriptsStringPath.mkString(", ")}], - | onload: function (window) { - | jsdom.changeURL(window, "http://localhost"); - | for (var k in window) { - | if (windowKeys.indexOf(k) == -1) - | global[k] = window[k]; - | } - | - | ${code.content} - | } + | scripts: [${scriptsURIsAsJSStrings.mkString(", ")}] | }); |})(); |""".stripMargin @@ -94,12 +94,28 @@ class JSDOMNodeJSEnv( Seq(new MemVirtualJSFile("codeWithJSDOMContext.js").withContent(jsDOMCode)) } + /** All the JS files that are passed to the VM. + * + * This method can overridden to provide custom behavior in subclasses. + * + * This method is overridden in `JSDOMNodeJSEnv` so that user-provided + * JS files (excluding "init" files) are executed as *scripts* within the + * jsdom environment, rather than being directly executed by the VM. + * + * The value returned by this method in `JSDOMNodeJSEnv` is + * `initFiles() ++ customInitFiles() ++ codeWithJSDOMContext()`. + */ override protected def getJSFiles(): Seq[VirtualJSFile] = initFiles() ++ customInitFiles() ++ codeWithJSDOMContext() - /** Libraries are loaded via scripts in the jsdom environment. */ - override protected def getLibJSFiles(): Seq[VirtualJSFile] = - libs + /** JS files to be loaded via scripts in the jsdom environment. + * + * This method can be overridden to provide a different list of scripts. + * + * The default value in `JSDOMNodeJSEnv` is `files`. + */ + protected def getScriptsJSFiles(): Seq[VirtualJSFile] = + files // Send code to Stdin override protected def sendVMStdin(out: OutputStream): Unit = { diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala index 2845c84eb5..ba8dc93278 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala @@ -41,29 +41,23 @@ class NodeJSEnv private ( protected def vmName: String = "Node.js" - override def jsRunner(libs: Seq[VirtualJSFile], - code: VirtualJSFile): JSRunner = { - new NodeRunner(libs, code) - } + override def jsRunner(files: Seq[VirtualJSFile]): JSRunner = + new NodeRunner(files) - override def asyncRunner(libs: Seq[VirtualJSFile], - code: VirtualJSFile): AsyncJSRunner = { - new AsyncNodeRunner(libs, code) - } + override def asyncRunner(files: Seq[VirtualJSFile]): AsyncJSRunner = + new AsyncNodeRunner(files) - override def comRunner(libs: Seq[VirtualJSFile], - code: VirtualJSFile): ComJSRunner = { - new ComNodeRunner(libs, code) - } + override def comRunner(files: Seq[VirtualJSFile]): ComJSRunner = + new ComNodeRunner(files) - protected class NodeRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile) - extends ExtRunner(libs, code) with AbstractBasicNodeRunner + protected class NodeRunner(files: Seq[VirtualJSFile]) + extends ExtRunner(files) with AbstractBasicNodeRunner - protected class AsyncNodeRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile) - extends AsyncExtRunner(libs, code) with AbstractBasicNodeRunner + protected class AsyncNodeRunner(files: Seq[VirtualJSFile]) + extends AsyncExtRunner(files) with AbstractBasicNodeRunner - protected class ComNodeRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile) - extends AsyncNodeRunner(libs, code) with NodeComJSRunner + protected class ComNodeRunner(files: Seq[VirtualJSFile]) + extends AsyncNodeRunner(files) with NodeComJSRunner protected trait AbstractBasicNodeRunner extends AbstractNodeRunner { diff --git a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala index 7c85fa27be..6d3d788f18 100644 --- a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala +++ b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala @@ -82,7 +82,7 @@ class MainGenericRunner { output } - new NodeJSEnv().jsRunner(sjsCode).run(logger, jsConsole) + new NodeJSEnv().jsRunner(sjsCode :: Nil).run(logger, jsConsole) true } diff --git a/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala index 1b285a6b8c..b4edeecbf1 100644 --- a/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala +++ b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala @@ -41,32 +41,23 @@ class PhantomJSEnv( protected def vmName: String = "PhantomJS" - override def jsRunner(libs: Seq[VirtualJSFile], - code: VirtualJSFile): JSRunner = { - new PhantomRunner(libs, code) - } + override def jsRunner(files: Seq[VirtualJSFile]): JSRunner = + new PhantomRunner(files) - override def asyncRunner(libs: Seq[VirtualJSFile], - code: VirtualJSFile): AsyncJSRunner = { - new AsyncPhantomRunner(libs, code) - } + override def asyncRunner(files: Seq[VirtualJSFile]): AsyncJSRunner = + new AsyncPhantomRunner(files) - override def comRunner(libs: Seq[VirtualJSFile], - code: VirtualJSFile): ComJSRunner = { - new ComPhantomRunner(libs, code) - } + override def comRunner(files: Seq[VirtualJSFile]): ComJSRunner = + new ComPhantomRunner(files) - protected class PhantomRunner(libs: Seq[VirtualJSFile], - code: VirtualJSFile) extends ExtRunner(libs, code) - with AbstractPhantomRunner + protected class PhantomRunner(files: Seq[VirtualJSFile]) + extends ExtRunner(files) with AbstractPhantomRunner - protected class AsyncPhantomRunner(libs: Seq[VirtualJSFile], - code: VirtualJSFile) extends AsyncExtRunner(libs, code) - with AbstractPhantomRunner + protected class AsyncPhantomRunner(files: Seq[VirtualJSFile]) + extends AsyncExtRunner(files) with AbstractPhantomRunner - protected class ComPhantomRunner(libs: Seq[VirtualJSFile], - code: VirtualJSFile) extends AsyncPhantomRunner(libs, code) - with ComJSRunner { + protected class ComPhantomRunner(files: Seq[VirtualJSFile]) + extends AsyncPhantomRunner(files) with ComJSRunner { private var mgrIsRunning: Boolean = false @@ -403,9 +394,8 @@ class PhantomJSEnv( out.write(s""" Phantom.js Launcher """) - sendJS(getLibJSFiles(), out) - writeCodeLauncher(code, out) - out.write(s"\n\n\n") + sendJS(getJSFiles(), out) + out.write(s"\n\n\n") } protected def createTmpLauncherFile(): File = { @@ -486,17 +476,6 @@ class PhantomJSEnv( webTmpF } - - protected def writeCodeLauncher(code: VirtualJSFile, out: Writer): Unit = { - // Create a file with the launcher function. - val launcherFile = new MemVirtualJSFile("phantomjs-launcher.js") - launcherFile.content = s""" - // Phantom.js code launcher - // Origin: ${code.path} - function $launcherName() {${code.content}} - """ - writeJSFile(launcherFile, out) - } } protected def htmlEscape(str: String): String = str.flatMap { @@ -513,6 +492,4 @@ private object PhantomJSEnv { private final val MaxByteMessageSize = 32768 // 32 KB private final val MaxCharMessageSize = MaxByteMessageSize / 2 // 2B per char private final val MaxCharPayloadSize = MaxCharMessageSize - 1 // frag flag - - private final val launcherName = "scalaJSPhantomJSEnvLauncher" } diff --git a/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnv.scala b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnv.scala index 8aa373637b..8da4e3fd03 100644 --- a/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnv.scala +++ b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnv.scala @@ -42,26 +42,26 @@ final class RetryingComJSEnv(val baseEnv: ComJSEnv, def name: String = s"Retrying ${baseEnv.name}" - def jsRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): JSRunner = - baseEnv.jsRunner(libs, code) + def jsRunner(files: Seq[VirtualJSFile]): JSRunner = + baseEnv.jsRunner(files) - def asyncRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): AsyncJSRunner = - baseEnv.asyncRunner(libs, code) + def asyncRunner(files: Seq[VirtualJSFile]): AsyncJSRunner = + baseEnv.asyncRunner(files) - def comRunner(libs: Seq[VirtualJSFile], code: VirtualJSFile): ComJSRunner = - new RetryingComJSRunner(libs, code) + def comRunner(files: Seq[VirtualJSFile]): ComJSRunner = + new RetryingComJSRunner(files) /** Hack to work around abstract override in ComJSRunner */ private trait DummyJSRunner { def stop(): Unit = () } - private class RetryingComJSRunner(libs: Seq[VirtualJSFile], - code: VirtualJSFile) extends DummyJSRunner with ComJSRunner { + private class RetryingComJSRunner(files: Seq[VirtualJSFile]) + extends DummyJSRunner with ComJSRunner { private[this] val promise = Promise[Unit] - private[this] var curRunner = baseEnv.comRunner(libs, code) + private[this] var curRunner = baseEnv.comRunner(files) private[this] var hasReceived = false private[this] var retryCount = 0 @@ -135,7 +135,7 @@ final class RetryingComJSEnv(val baseEnv: ComJSEnv, val oldRunner = curRunner curRunner = try { - baseEnv.comRunner(libs, code) + baseEnv.comRunner(files) } catch { case NonFatal(t) => _logger.error("Could not retry: creating an new runner failed: " + diff --git a/phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnvTest.scala b/phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnvTest.scala index 0223510a7c..2161b6118c 100644 --- a/phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnvTest.scala +++ b/phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnvTest.scala @@ -28,20 +28,14 @@ class RetryingComJSEnvTest extends JSEnvTest with ComTests { private[this] var fails = 0 private[this] var failedReceive = false - def jsRunner(libs: Seq[VirtualJSFile], - code: VirtualJSFile): JSRunner = { - baseEnv.jsRunner(libs, code) - } + def jsRunner(files: Seq[VirtualJSFile]): JSRunner = + baseEnv.jsRunner(files) - def asyncRunner(libs: Seq[VirtualJSFile], - code: VirtualJSFile): AsyncJSRunner = { - baseEnv.asyncRunner(libs, code) - } + def asyncRunner(files: Seq[VirtualJSFile]): AsyncJSRunner = + baseEnv.asyncRunner(files) - def comRunner(libs: Seq[VirtualJSFile], - code: VirtualJSFile): ComJSRunner = { - new FailingComJSRunner(baseEnv.comRunner(libs, code)) - } + def comRunner(files: Seq[VirtualJSFile]): ComJSRunner = + new FailingComJSRunner(baseEnv.comRunner(files)) /** Hack to work around abstract override in ComJSRunner */ private trait DummyJSRunner { diff --git a/project/Build.scala b/project/Build.scala index 3371253df0..69c4489083 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -676,7 +676,7 @@ object Build { val launcher = new MemVirtualJSFile("Generated launcher file") .withContent(code) - val runner = loadedJSEnv.value.jsRunner(launcher) + val runner = loadedJSEnv.value.jsRunner(launcher :: Nil) runner.run(sbtLogger2ToolsLogger(streams.value.log), scalaJSConsole.value) } diff --git a/sbt-plugin-test/project/Jetty9Test.scala b/sbt-plugin-test/project/Jetty9Test.scala index e988c27543..5a7dbdd389 100644 --- a/sbt-plugin-test/project/Jetty9Test.scala +++ b/sbt-plugin-test/project/Jetty9Test.scala @@ -42,7 +42,7 @@ object Jetty9Test { """ ) - val runner = jsEnv.comRunner(code) + val runner = jsEnv.comRunner(code :: Nil) runner.start(streams.value.log, jsConsole) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala index e88764e396..fcc2c890af 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala @@ -67,7 +67,7 @@ private[sbtplugin] final class FrameworkDetector(jsEnv: JSEnv, val vf = new MemVirtualJSFile("frameworkDetector.js").withContent(code) val console = new StoreConsole - val runner = jsEnv.jsRunner(vf) + val runner = jsEnv.jsRunner(vf :: Nil) runner.run(logger, console) // Filter jsDependencies unexpected output diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 6d427abdb7..696cbe39ab 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -710,9 +710,7 @@ object ScalaJSPluginInternal { log.info("Running " + mainClass.value.getOrElse("")) log.debug(s"with JSEnv ${jsEnv.name}") - val dummyLauncher = new MemVirtualJSFile("No-op generated launcher file") - - jsEnv.jsRunner(dummyLauncher).run( + jsEnv.jsRunner(Nil).run( sbtLogger2ToolsLogger(log), scalaJSConsole.value) }, diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala index afc83db285..ef35c7383a 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala @@ -58,7 +58,7 @@ final class ScalaJSFramework( private[testadapter] def runDone(): Unit = synchronized(_isRunning = false) private def fetchFrameworkInfo() = { - val runner = libEnv.comRunner(frameworkInfoLauncher) + val runner = libEnv.comRunner(frameworkInfoLauncher :: Nil) runner.start(logger, jsConsole) try { diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala index aebce10ce2..9560abf787 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala @@ -177,7 +177,7 @@ final class ScalaJSRunner private[testadapter] ( ensureNotDone() // Launch the slave - val slave = framework.libEnv.comRunner(slaveLauncher) + val slave = framework.libEnv.comRunner(slaveLauncher :: Nil) slave.start(framework.logger, framework.jsConsole) // Create a runner on the slave @@ -218,7 +218,7 @@ final class ScalaJSRunner private[testadapter] ( private def createRemoteRunner(): Unit = { assert(master == null) - master = framework.libEnv.comRunner(masterLauncher) + master = framework.libEnv.comRunner(masterLauncher :: Nil) master.start(framework.logger, framework.jsConsole) val data = { From 9722c9488ed99e550a9e787250f7f0a0946eb849 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 9 Apr 2017 20:51:11 +0200 Subject: [PATCH 0212/2665] Cleanup exports error message handling. This notably hides exportsOf from PrepJSInterop. The separation between error message generation in- and outside of PrepJSInterop has gotten blurrier in the past. By simply hiding it, we remove this ill-defined interface and make changing the error messages easier in the future. --- .../scalajs/core/compiler/PrepJSExports.scala | 127 ++++++++++-------- .../scalajs/core/compiler/PrepJSInterop.scala | 47 ++----- .../scalajs/core/compiler/ScalaJSPlugin.scala | 2 +- .../core/compiler/test/JSExportTest.scala | 4 +- 4 files changed, 87 insertions(+), 93 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala index c76c44abb8..89ce316e9a 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala @@ -50,37 +50,37 @@ trait PrepJSExports { this: PrepJSInterop => def memType = if (baseSym.isConstructor) "constructor" else "method" - if (exports.isEmpty) + if (exports.isEmpty) { Nil - else if (!hasLegalExportVisibility(baseSym)) + } else if (!hasLegalExportVisibility(baseSym)) { err(s"You may only export public and protected ${memType}s") - else if (baseSym.isMacro) + } else if (baseSym.isMacro) { err("You may not export a macro") - else if (scalaPrimitives.isPrimitive(baseSym)) + } else if (isJSAny(clsSym)) { + err(s"You may not export a $memType of a subclass of js.Any") + } else if (scalaPrimitives.isPrimitive(baseSym)) { err("You may not export a primitive") - else if (hasIllegalRepeatedParam(baseSym)) + } else if (baseSym.isLocalToBlock) { + // We exclude case class apply (and unapply) to work around SI-8826 + if (clsSym.isCaseApplyOrUnapply) { + Nil + } else { + err("You may not export a local definition") + } + } else if (hasIllegalRepeatedParam(baseSym)) { err(s"In an exported $memType, a *-parameter must come last " + "(through all parameter lists)") - else if (hasIllegalDefaultParam(baseSym)) + } else if (hasIllegalDefaultParam(baseSym)) { err(s"In an exported $memType, all parameters with defaults " + "must be at the end") - else if (baseSym.isConstructor) { + } else if (baseSym.isConstructor) { // we can generate constructors entirely in the backend, since they // do not need inheritance and such. But we want to check their sanity // here by previous tests and the following ones. - - if (!hasLegalExportVisibility(clsSym)) - err("You may only export public and protected classes") - else if (clsSym.isAbstractClass) - err("You may not export an abstract class") - else if (clsSym.isLocalToBlock) - err("You may not export a local class") - else if (!clsSym.isStatic) - err(s"You may not export a nested class. $createFactoryInOuterClassHint") - else { + if (checkClassOrModuleExports(clsSym, exports.head.pos)) jsInterop.registerForExport(baseSym, exports) - Nil - } + + Nil } else { assert(!baseSym.isBridge) @@ -100,48 +100,63 @@ trait PrepJSExports { this: PrepJSInterop => } } - /** Checks and registers module exports on the symbol */ - def registerModuleExports(sym: Symbol): Unit = { - assert(sym.isModuleClass, "Expected module class") - registerClassOrModuleExportsInternal(sym) - } + /** Check and (potentially) register a class or module for export. + * + * Note that Scala classes are never registered for export, their + * constructors are. + */ + def registerClassOrModuleExports(sym: Symbol): Unit = { + val exports = exportsOf(sym) + def isScalaClass = !sym.isModuleClass && !isJSAny(sym) - /** Checks and registers class exports on the symbol. */ - def registerClassExports(sym: Symbol): Unit = { - assert(!sym.isModuleClass && !sym.hasAnnotation(JSNativeAnnotation), - "Expected a Scala.js-defined JS class") - registerClassOrModuleExportsInternal(sym) + if (exports.nonEmpty && checkClassOrModuleExports(sym, exports.head.pos) && + !isScalaClass) { + jsInterop.registerForExport(sym, exports) + } } - private def registerClassOrModuleExportsInternal(sym: Symbol): Unit = { + /** Check a class or module for export. + * + * There are 2 ways that this method can be reached: + * - via `registerClassOrModuleExports` + * - via `genExportMember` (constructor of Scala class) + */ + private def checkClassOrModuleExports(sym: Symbol, errPos: Position): Boolean = { val isMod = sym.isModuleClass - val exports = exportsOf(sym) - - if (exports.nonEmpty) { - def err(msg: String) = { - reporter.error(exports.head.pos, msg) - } + def err(msg: String) = { + reporter.error(errPos, msg) + false + } - def hasAnyNonPrivateCtor: Boolean = - sym.info.member(nme.CONSTRUCTOR).filter(!isPrivateMaybeWithin(_)).exists - - if (!hasLegalExportVisibility(sym)) { - err("You may only export public and protected " + - (if (isMod) "objects" else "classes")) - } else if (sym.isLocalToBlock) { - err("You may not export a local " + - (if (isMod) "object" else "class")) - } else if (!sym.isStatic) { - err("You may not export a nested " + - (if (isMod) "object" else s"class. $createFactoryInOuterClassHint")) - } else if (sym.isAbstractClass) { - err("You may not export an abstract class") - } else if (!isMod && !hasAnyNonPrivateCtor) { - err("You may not export a class that has only private constructors") - } else { - jsInterop.registerForExport(sym, exports) - } + def hasAnyNonPrivateCtor: Boolean = + sym.info.member(nme.CONSTRUCTOR).filter(!isPrivateMaybeWithin(_)).exists + + def isJSNative = sym.hasAnnotation(JSNativeAnnotation) + + if (sym.isTrait) { + err("You may not export a trait") + } else if (isJSNative) { + err("You may not export a native JS " + (if (isMod) "object" else "class")) + } else if (!hasLegalExportVisibility(sym)) { + err("You may only export public and protected " + + (if (isMod) "objects" else "classes")) + } else if (sym.isLocalToBlock) { + err("You may not export a local " + + (if (isMod) "object" else "class")) + } else if (!sym.isStatic) { + err("You may not export a nested " + + (if (isMod) "object" else s"class. $createFactoryInOuterClassHint")) + } else if (sym.isAbstractClass) { + err("You may not export an abstract class") + } else if (!isMod && !hasAnyNonPrivateCtor) { + /* This test is only relevant for JS classes but doesn't hurt for Scala + * classes as we could not reach it if there were only private + * constructors. + */ + err("You may not export a class that has only private constructors") + } else { + true } } @@ -155,7 +170,7 @@ trait PrepJSExports { this: PrepJSInterop => * Note that for accessor symbols, the annotations of the accessed symbol * are used, rather than the annotations of the accessor itself. */ - def exportsOf(sym: Symbol): List[ExportInfo] = { + private def exportsOf(sym: Symbol): List[ExportInfo] = { val trgSym = { def isOwnerScalaClass = !sym.owner.isModuleClass && !isJSAny(sym.owner) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 57322864cb..475bd137e2 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -197,11 +197,8 @@ abstract class PrepJSInterop extends plugins.PluginComponent if (sym == UndefOrClass || sym == UnionClass) sym.addAnnotation(RawJSTypeAnnot) - if (shouldPrepareExports && sym.isTrait) { - // Check that interface/trait is not exported - for (exp <- exportsOf(sym)) - reporter.error(exp.pos, "You may not export a trait") - } + if (shouldPrepareExports) + registerClassOrModuleExports(sym) enterOwner(OwnerKind.NonEnumScalaClass) { super.transform(cldef) } @@ -212,7 +209,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent checkJSAnySpecificAnnotsOnNonJSAny(modDef) if (shouldPrepareExports) - registerModuleExports(sym.moduleClass) + registerClassOrModuleExports(sym.moduleClass) enterOwner(OwnerKind.NonEnumScalaMod) { super.transform(modDef) } @@ -424,10 +421,10 @@ abstract class PrepJSInterop extends plugins.PluginComponent case memDef: MemberDef => val sym = memDef.symbol - if (sym.isLocalToBlock && !sym.owner.isCaseApplyOrUnapply) { - // We exclude case class apply (and unapply) to work around SI-8826 - for (exp <- exportsOf(sym)) - reporter.error(exp.pos, "You may not export a local definition") + if (shouldPrepareExports && sym.isLocalToBlock) { + // Exports are never valid on local definitions, but delegate complaining. + val exports = genExportMember(sym) + assert(exports.isEmpty, "Generated exports for local definition.") } // Expose objects (modules) members of Scala.js-defined JS classes @@ -573,24 +570,8 @@ abstract class PrepJSInterop extends plugins.PluginComponent } } - if (shouldPrepareExports) { - if (sym.isTrait) { - // Check that interface/trait is not exported - for (exp <- exportsOf(sym)) - reporter.error(exp.pos, "You may not export a trait") - } else if (isJSNative) { - // Check that a JS native type is not exported - for (exp <- exportsOf(sym)) { - reporter.error(exp.pos, - "You may not export a native JS class or object") - } - } else { - if (sym.isModuleClass) - registerModuleExports(sym) - else if (!sym.isTrait) - registerClassExports(sym) - } - } + if (shouldPrepareExports) + registerClassOrModuleExports(sym) // Check for consistency of JS semantics across overriding for (overridingPair <- new overridingPairs.Cursor(sym).iterator) { @@ -732,12 +713,10 @@ abstract class PrepJSInterop extends plugins.PluginComponent assert(!sym.isLocalToBlock, s"$tree at ${tree.pos}") if (shouldPrepareExports) { - // Exports are never valid on members of JS types - lazy val memType = if (sym.isConstructor) "constructor" else "method" - for (exp <- exportsOf(sym)) { - reporter.error(exp.pos, - s"You may not export a $memType of a subclass of js.Any") - } + // Exports are never valid on members of JS types, but delegate + // complaining. + val exports = genExportMember(sym) + assert(exports.isEmpty, "Generated exports for member JS type.") /* Add the @ExposedJSMember annotation to exposed symbols in * Scala.js-defined classes. diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala index 57b39e4045..82f8e6f601 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala @@ -63,7 +63,7 @@ class ScalaJSPlugin(val global: Global) extends NscPlugin { * `@JSExport` annotation to the module. */ def registerModuleExports(sym: Symbol): Unit = - PrepInteropComponent.registerModuleExports(sym) + PrepInteropComponent.registerClassOrModuleExports(sym) object PreTyperComponentComponent extends { val global: ScalaJSPlugin.this.global.type = ScalaJSPlugin.this.global diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index dbb5bb4902..cfb0dbe1ad 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -519,7 +519,7 @@ class JSExportTest extends DirectTest with TestHelpers { object A extends js.Object """ hasErrors """ - |newSource1.scala:5: error: You may not export a native JS class or object + |newSource1.scala:5: error: You may not export a native JS object | @JSExport | ^ """ @@ -549,7 +549,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:5: error: You may not export a native JS class or object + |newSource1.scala:5: error: You may not export a native JS class | @JSExport | ^ |newSource1.scala:9: error: You may not export a constructor of a subclass of js.Any From c07bd70cded46541c419bc80c53fe764fbfab062 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 7 Apr 2017 17:06:15 +0200 Subject: [PATCH 0213/2665] Fix #2862: Disallow @JSExport on non-members --- .../scalajs/core/compiler/PrepJSExports.scala | 57 ++--- .../core/compiler/ScalaJSOptions.scala | 3 - .../scalajs/core/compiler/ScalaJSPlugin.scala | 9 - .../test/JSExportDeprecationsTest.scala | 59 ----- .../core/compiler/test/JSExportTest.scala | 222 ++++++++++++------ .../compiler/test/ScalaJSDefinedTest.scala | 15 +- project/Build.scala | 6 - .../testsuite/jsinterop/ExportsTest.scala | 221 +++-------------- 8 files changed, 207 insertions(+), 385 deletions(-) delete mode 100644 compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportDeprecationsTest.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala index 89ce316e9a..8ae54874f5 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala @@ -25,11 +25,6 @@ trait PrepJSExports { this: PrepJSInterop => destination: ExportDestination)(val pos: Position) extends jsInterop.ExportInfo - private final val SuppressExportDeprecationsMsg = { - "\n (you can suppress this warning in 0.6.x by passing the option " + - "`-P:scalajs:suppressExportDeprecations` to scalac)" - } - /** Generate the exporter for the given DefDef * or ValDef (abstract val in class, val in trait or lazy val; * these don't get DefDefs until the fields phase) @@ -190,7 +185,7 @@ trait PrepJSExports { this: PrepJSInterop => annot => isDirectMemberAnnot(annot.symbol)) // Is this a member export (i.e. not a class or module export)? - val isMember = sym.isMethod && !sym.isConstructor + val isMember = !sym.isClass && !sym.isConstructor // Annotations for this member on the whole unit val unitAnnots = { @@ -281,6 +276,10 @@ trait PrepJSExports { this: PrepJSInterop => } } + val symOwner = + if (sym.isConstructor) sym.owner.owner + else sym.owner + // Destination-specific restrictions destination match { case ExportDestination.Normal => @@ -294,36 +293,11 @@ trait PrepJSExports { this: PrepJSInterop => "method named other than 'toString' under the name 'toString'") } - // Don't allow nested class / module exports without explicit name. - def isStaticNested = { - /* For Scala.js defined JS classes, sym is the class itself. For - * normal classes, sym is the constructor that is to be exported. - */ - val clsSym = if (sym.isClass) sym else sym.owner - clsSym.isNestedClass && clsSym.isStatic && !clsSym.isLocalToBlock - } - if (!isMember && !hasExplicitName && isStaticNested) { + // Disallow @JSExport on non-members. + if (!isMember && !sym.isTrait) { reporter.error(annot.pos, - "You must set an explicit name for exports of nested classes.") - } - - // Deprecate @JSExport on classes and objects - if (!isMember && !scalaJSOpts.suppressExportDeprecations) { - if (sym.isModuleClass) { - reporter.warning(annot.pos, - "@JSExport on objects is deprecated and will be removed " + - "in 1.0.0. Use @JSExportTopLevel instead. Note that it " + - "exports the object itself (rather than a 0-arg function " + - "returning the object), so the calling JavaScript code " + - "must be adapted." + - SuppressExportDeprecationsMsg) - } else { - reporter.warning(annot.pos, - "@JSExport on classes is deprecated and will be removed " + - "in 1.0.0. Use @JSExportTopLevel instead (which does " + - "exactly the same thing on classes)." + - SuppressExportDeprecationsMsg) - } + "@JSExport is forbidden on objects and classes. " + + "Use @JSExportTopLevel instead.") } case ExportDestination.TopLevel => @@ -335,19 +309,16 @@ trait PrepJSExports { this: PrepJSInterop => "You may not export a getter or a setter to the top level") } - val symOwner = - if (sym.isConstructor) sym.owner.owner - else sym.owner - if (!symOwner.isStatic || !symOwner.isModuleClass) { + /* Disallow non-static methods. + * Note: Non-static classes have more specific error messages in + * checkClassOrModuleExports + */ + if (sym.isMethod && (!symOwner.isStatic || !symOwner.isModuleClass)) { reporter.error(annot.pos, "Only static objects may export their members to the top level") } case ExportDestination.Static => - val symOwner = - if (sym.isClassConstructor) sym.owner.owner - else sym.owner - def companionIsScalaJSDefinedJSClass: Boolean = { val companion = symOwner.companionClass companion != NoSymbol && diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala index b56305fb97..aa7f91a245 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala @@ -19,9 +19,6 @@ trait ScalaJSOptions { * If false, bad calls to classOf will cause an error. */ def fixClassOf: Boolean - /** Should we suppress deprecations of exports coming from 0.6.15? */ - def suppressExportDeprecations: Boolean - /** which source locations in source maps should be relativized (or where * should they be mapped to)? */ def sourceURIMaps: List[URIMap] diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala index 82f8e6f601..d5ed93f82c 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala @@ -44,7 +44,6 @@ class ScalaJSPlugin(val global: Global) extends NscPlugin { object scalaJSOpts extends ScalaJSOptions { // scalastyle:ignore import ScalaJSOptions.URIMap var fixClassOf: Boolean = false - var suppressExportDeprecations: Boolean = false lazy val sourceURIMaps: List[URIMap] = { if (_sourceURIMaps.nonEmpty) _sourceURIMaps.reverse @@ -113,8 +112,6 @@ class ScalaJSPlugin(val global: Global) extends NscPlugin { error(s"${e.getInput} is not a valid URI") } } - } else if (option == "suppressExportDeprecations") { - suppressExportDeprecations = true // The following options are deprecated (how do we show this to the user?) } else if (option.startsWith("relSourceMap:")) { val uriStr = option.stripPrefix("relSourceMap:") @@ -150,12 +147,6 @@ class ScalaJSPlugin(val global: Global) extends NscPlugin { | - 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:suppressExportDeprecations - | Silence deprecations of top-level @JSExport, - | @JSExportDescendentClasses and @JSExportDescendentObjects. - | This can be used as a transition path in the 0.6.x cycle, - | to avoid too many deprecation warnings that are not trivial - | to address. | -P:$name:fixClassOf | Repair calls to Predef.classOf that reach Scala.js. | WARNING: This is a tremendous hack! Expect ugly errors if you use this option. diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportDeprecationsTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportDeprecationsTest.scala deleted file mode 100644 index e972e88374..0000000000 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportDeprecationsTest.scala +++ /dev/null @@ -1,59 +0,0 @@ -package org.scalajs.core.compiler.test - -import org.scalajs.core.compiler.test.util._ -import org.junit.Test - -// scalastyle:off line.size.limit - -class JSExportDeprecationsTest extends DirectTest with TestHelpers { - - override def extraArgs: List[String] = - super.extraArgs :+ "-deprecation" - - override def preamble: String = - """import scala.scalajs.js, js.annotation._ - """ - - @Test - def warnJSExportClass: Unit = { - """ - @JSExport - class A - - @JSExport("Foo") - class B - """ hasWarns - """ - |newSource1.scala:3: warning: @JSExport on classes is deprecated and will be removed in 1.0.0. Use @JSExportTopLevel instead (which does exactly the same thing on classes). - | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressExportDeprecations` to scalac) - | @JSExport - | ^ - |newSource1.scala:6: warning: @JSExport on classes is deprecated and will be removed in 1.0.0. Use @JSExportTopLevel instead (which does exactly the same thing on classes). - | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressExportDeprecations` to scalac) - | @JSExport("Foo") - | ^ - """ - } - - @Test - def warnJSExportObject: Unit = { - """ - @JSExport - object A - - @JSExport("Foo") - object B - """ hasWarns - """ - |newSource1.scala:3: warning: @JSExport on objects is deprecated and will be removed in 1.0.0. Use @JSExportTopLevel instead. Note that it exports the object itself (rather than a 0-arg function returning the object), so the calling JavaScript code must be adapted. - | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressExportDeprecations` to scalac) - | @JSExport - | ^ - |newSource1.scala:6: warning: @JSExport on objects is deprecated and will be removed in 1.0.0. Use @JSExportTopLevel instead. Note that it exports the object itself (rather than a 0-arg function returning the object), so the calling JavaScript code must be adapted. - | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressExportDeprecations` to scalac) - | @JSExport("Foo") - | ^ - """ - } - -} diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index cfb0dbe1ad..bf92a0fd8e 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -10,12 +10,50 @@ import org.junit.Assume._ class JSExportTest extends DirectTest with TestHelpers { override def extraArgs: List[String] = - super.extraArgs ::: List("-deprecation", "-P:scalajs:suppressExportDeprecations") + super.extraArgs ::: List("-deprecation") override def preamble: String = """import scala.scalajs.js, js.annotation._ """ + @Test + def noJSExportClass: Unit = { + """ + @JSExport + class A + + @JSExport("Foo") + class B + """ hasErrors + """ + |newSource1.scala:3: error: @JSExport is forbidden on objects and classes. Use @JSExportTopLevel instead. + | @JSExport + | ^ + |newSource1.scala:6: error: @JSExport is forbidden on objects and classes. Use @JSExportTopLevel instead. + | @JSExport("Foo") + | ^ + """ + } + + @Test + def noJSExportObject: Unit = { + """ + @JSExport + object A + + @JSExport("Foo") + object B + """ hasErrors + """ + |newSource1.scala:3: error: @JSExport is forbidden on objects and classes. Use @JSExportTopLevel instead. + | @JSExport + | ^ + |newSource1.scala:6: error: @JSExport is forbidden on objects and classes. Use @JSExportTopLevel instead. + | @JSExport("Foo") + | ^ + """ + } + @Test def noDoubleUnderscoreExport: Unit = { // Normal exports @@ -28,10 +66,10 @@ class JSExportTest extends DirectTest with TestHelpers { def bar__(x: Int) = x } - @JSExport + @JSExportTopLevel("B__") class B__ - @JSExport + @JSExportTopLevel("C__") class C__ extends js.Object """ hasErrors """ @@ -41,12 +79,12 @@ class JSExportTest extends DirectTest with TestHelpers { |newSource1.scala:8: error: An exported name may not contain a double underscore (`__`) | def bar__(x: Int) = x | ^ - |newSource1.scala:12: error: An exported name may not contain a double underscore (`__`) - | class B__ - | ^ - |newSource1.scala:15: error: An exported name may not contain a double underscore (`__`) - | class C__ extends js.Object - | ^ + |newSource1.scala:11: error: An exported name may not contain a double underscore (`__`) + | @JSExportTopLevel("B__") + | ^ + |newSource1.scala:14: error: An exported name may not contain a double underscore (`__`) + | @JSExportTopLevel("C__") + | ^ """ } @@ -152,10 +190,10 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:5: error: You may not export a local class + |newSource1.scala:5: error: @JSExport is forbidden on objects and classes. Use @JSExportTopLevel instead. | @JSExport | ^ - |newSource1.scala:8: error: You may not export a local class + |newSource1.scala:8: error: @JSExport is forbidden on objects and classes. Use @JSExportTopLevel instead. | @JSExport | ^ """ @@ -173,10 +211,10 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:5: error: You may not export a local object + |newSource1.scala:5: error: @JSExport is forbidden on objects and classes. Use @JSExportTopLevel instead. | @JSExport | ^ - |newSource1.scala:8: error: You may not export a local object + |newSource1.scala:8: error: @JSExport is forbidden on objects and classes. Use @JSExportTopLevel instead. | @JSExport | ^ """ @@ -266,33 +304,33 @@ class JSExportTest extends DirectTest with TestHelpers { def noExportAbstractClass: Unit = { """ - @JSExport + @JSExportTopLevel("A") abstract class A abstract class B(x: Int) { - @JSExport + @JSExportTopLevel("B") def this() = this(5) } - @JSExport + @JSExportTopLevel("C") abstract class C extends js.Object """ hasErrors """ |newSource1.scala:3: error: You may not export an abstract class - | @JSExport + | @JSExportTopLevel("A") | ^ |newSource1.scala:7: error: You may not export an abstract class - | @JSExport + | @JSExportTopLevel("B") | ^ |newSource1.scala:11: error: You may not export an abstract class - | @JSExport + | @JSExportTopLevel("C") | ^ """ } @Test - def noExportTrait: Unit = { + def noJSExportOnTrait: Unit = { """ @JSExport @@ -323,58 +361,58 @@ class JSExportTest extends DirectTest with TestHelpers { def noExportNonPublicClassOrObject: Unit = { """ - @JSExport + @JSExportTopLevel("A") private class A - @JSExport + @JSExportTopLevel("B") protected[this] class B - @JSExport + @JSExportTopLevel("C") private class C extends js.Object - @JSExport + @JSExportTopLevel("D") protected[this] class D extends js.Object """ hasErrors """ |newSource1.scala:3: error: You may only export public and protected classes - | @JSExport + | @JSExportTopLevel("A") | ^ |newSource1.scala:6: error: You may only export public and protected classes - | @JSExport + | @JSExportTopLevel("B") | ^ |newSource1.scala:9: error: You may only export public and protected classes - | @JSExport + | @JSExportTopLevel("C") | ^ |newSource1.scala:12: error: You may only export public and protected classes - | @JSExport + | @JSExportTopLevel("D") | ^ """ """ - @JSExport + @JSExportTopLevel("A") private object A - @JSExport + @JSExportTopLevel("B") protected[this] object B - @JSExport + @JSExportTopLevel("C") private object C extends js.Object - @JSExport + @JSExportTopLevel("D") protected[this] object D extends js.Object """ hasErrors """ |newSource1.scala:3: error: You may only export public and protected objects - | @JSExport + | @JSExportTopLevel("A") | ^ |newSource1.scala:6: error: You may only export public and protected objects - | @JSExport + | @JSExportTopLevel("B") | ^ |newSource1.scala:9: error: You may only export public and protected objects - | @JSExport + | @JSExportTopLevel("C") | ^ |newSource1.scala:12: error: You may only export public and protected objects - | @JSExport + | @JSExportTopLevel("D") | ^ """ @@ -419,13 +457,13 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:4: error: You may not export a nested class. Create an exported factory method in the outer class to work around this limitation. + |newSource1.scala:4: error: @JSExport is forbidden on objects and classes. Use @JSExportTopLevel instead. | @JSExport | ^ - |newSource1.scala:6: error: You may not export a nested class. Create an exported factory method in the outer class to work around this limitation. + |newSource1.scala:6: error: @JSExport is forbidden on objects and classes. Use @JSExportTopLevel instead. | @JSExport | ^ - |newSource1.scala:10: error: You may not export a nested class. Create an exported factory method in the outer class to work around this limitation. + |newSource1.scala:10: error: @JSExport is forbidden on objects and classes. Use @JSExportTopLevel instead. | @JSExport | ^ """ @@ -433,7 +471,7 @@ class JSExportTest extends DirectTest with TestHelpers { } @Test - def noImplicitNameNestedExportClass: Unit = { + def noNestedExportClass: Unit = { """ object A { @@ -448,13 +486,14 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:4: error: You must set an explicit name for exports of nested classes. + + |newSource1.scala:4: error: @JSExport is forbidden on objects and classes. Use @JSExportTopLevel instead. | @JSExport | ^ - |newSource1.scala:6: error: You must set an explicit name for exports of nested classes. + |newSource1.scala:6: error: @JSExport is forbidden on objects and classes. Use @JSExportTopLevel instead. | @JSExport | ^ - |newSource1.scala:10: error: You must set an explicit name for exports of nested classes. + |newSource1.scala:10: error: @JSExport is forbidden on objects and classes. Use @JSExportTopLevel instead. | @JSExport | ^ """ @@ -462,10 +501,10 @@ class JSExportTest extends DirectTest with TestHelpers { } @Test - def noExportNestedObject: Unit = { + def noNestedExportObject: Unit = { """ - class A { + object A { @JSExport object Nested @@ -474,10 +513,10 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:4: error: You may not export a nested object + |newSource1.scala:4: error: @JSExport is forbidden on objects and classes. Use @JSExportTopLevel instead. | @JSExport | ^ - |newSource1.scala:7: error: You may not export a nested object + |newSource1.scala:7: error: @JSExport is forbidden on objects and classes. Use @JSExportTopLevel instead. | @JSExport | ^ """ @@ -485,75 +524,75 @@ class JSExportTest extends DirectTest with TestHelpers { } @Test - def noImplicitNameNestedExportObject: Unit = { + def noExportTopLevelNestedObject: Unit = { """ - object A { - @JSExport + class A { + @JSExportTopLevel("Nested") object Nested - @JSExport + @JSExportTopLevel("Nested2") object Nested2 extends js.Object } """ hasErrors """ - |newSource1.scala:4: error: You must set an explicit name for exports of nested classes. - | @JSExport + |newSource1.scala:4: error: You may not export a nested object + | @JSExportTopLevel("Nested") | ^ - |newSource1.scala:7: error: You must set an explicit name for exports of nested classes. - | @JSExport + |newSource1.scala:7: error: You may not export a nested object + | @JSExportTopLevel("Nested2") | ^ """ } @Test - def noExportJSRaw: Unit = { + def noExportJSNative: Unit = { """ import scala.scalajs.js - @JSExport + @JSExportTopLevel("A") @js.native @JSGlobal("Dummy") object A extends js.Object """ hasErrors """ |newSource1.scala:5: error: You may not export a native JS object - | @JSExport + | @JSExportTopLevel("A") | ^ """ """ import scala.scalajs.js - @JSExport + @JSExportTopLevel("A") @js.native trait A extends js.Object """ hasErrors """ |newSource1.scala:5: error: You may not export a trait - | @JSExport + | @JSExportTopLevel("A") | ^ """ """ import scala.scalajs.js - @JSExport + @JSExportTopLevel("A") @js.native @JSGlobal("Dummy") class A extends js.Object { - @JSExport + @JSExportTopLevel("A") def this(x: Int) = this() } """ hasErrors """ |newSource1.scala:5: error: You may not export a native JS class - | @JSExport + | @JSExportTopLevel("A") | ^ |newSource1.scala:9: error: You may not export a constructor of a subclass of js.Any - | @JSExport + | @JSExportTopLevel("A") | ^ """ @@ -827,7 +866,7 @@ class JSExportTest extends DirectTest with TestHelpers { def exportObjectAsToString: Unit = { """ - @JSExport("toString") + @JSExportTopLevel("toString") object ExportAsToString """.succeeds @@ -1007,7 +1046,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:4: error: Only static objects may export their members to the top level + |newSource1.scala:4: error: You may not export a nested object | @JSExportTopLevel("Foo") | ^ """ @@ -1019,7 +1058,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:4: error: Only static objects may export their members to the top level + |newSource1.scala:4: error: You may not export a nested object | @JSExportTopLevel("Foo") | ^ """ @@ -1031,7 +1070,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:4: error: Only static objects may export their members to the top level + |newSource1.scala:4: error: You may not export a nested class. Create an exported factory method in the outer class to work around this limitation. | @JSExportTopLevel("Foo") | ^ """ @@ -1043,12 +1082,57 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:4: error: Only static objects may export their members to the top level + |newSource1.scala:4: error: You may not export a nested class. Create an exported factory method in the outer class to work around this limitation. | @JSExportTopLevel("Foo") | ^ """ } + @Test + def noExportTopLevelLocal: Unit = { + // Local class + """ + class A { + def method = { + @JSExportTopLevel("A") + class A + + @JSExportTopLevel("B") + class B extends js.Object + } + } + """ hasErrors + """ + |newSource1.scala:5: error: You may not export a local class + | @JSExportTopLevel("A") + | ^ + |newSource1.scala:8: error: You may not export a local class + | @JSExportTopLevel("B") + | ^ + """ + + // Local object + """ + class A { + def method = { + @JSExportTopLevel("A") + object A + + @JSExportTopLevel("B") + object B extends js.Object + } + } + """ hasErrors + """ + |newSource1.scala:5: error: You may not export a local object + | @JSExportTopLevel("A") + | ^ + |newSource1.scala:8: error: You may not export a local object + | @JSExportTopLevel("B") + | ^ + """ + } + @Test def noExportTopLevelJSModule: Unit = { """ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala index e34781ad1a..7d705b01fa 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala @@ -9,9 +9,6 @@ import org.junit.Ignore class ScalaJSDefinedTest extends DirectTest with TestHelpers { - override def extraArgs: List[String] = - super.extraArgs :+ "-P:scalajs:suppressExportDeprecations" - override def preamble: String = """ import scala.scalajs.js @@ -501,34 +498,34 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { @Test def noExportClassWithOnlyPrivateCtors: Unit = { """ - @JSExport + @JSExportTopLevel("A") class A private () extends js.Object """ hasErrors """ |newSource1.scala:5: error: You may not export a class that has only private constructors - | @JSExport + | @JSExportTopLevel("A") | ^ """ """ - @JSExport + @JSExportTopLevel("A") class A private[this] () extends js.Object """ hasErrors """ |newSource1.scala:5: error: You may not export a class that has only private constructors - | @JSExport + | @JSExportTopLevel("A") | ^ """ """ - @JSExport + @JSExportTopLevel("A") class A private[A] () extends js.Object object A """ hasErrors """ |newSource1.scala:5: error: You may not export a class that has only private constructors - | @JSExport + | @JSExportTopLevel("A") | ^ """ } diff --git a/project/Build.scala b/project/Build.scala index 3371253df0..a03034c365 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1375,12 +1375,6 @@ object Build { testHtmlSettings(testHtmlFullOpt, FullOptStage), name := "Scala.js test suite", - /* We still have zillions of run test for top-level @JSExport and for - * @JSName/missing @JSGlobal. Don't drown the test:compile output under - * useless warnings. - */ - scalacOptions in Test += "-P:scalajs:suppressExportDeprecations", - unmanagedSourceDirectories in Test ++= { val testDir = (sourceDirectory in Test).value diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index 7daa76d5f7..966ec36c7c 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -617,36 +617,6 @@ class ExportsTest { assertEquals(3, a.foo(vc1.asInstanceOf[js.Any], vc2.asInstanceOf[js.Any])) } - @Test def exports_for_objects_with_implicit_name(): Unit = { - val accessor = jsPackage.ExportedObject - assertJSNotUndefined(accessor) - assertEquals("function", js.typeOf(accessor)) - val obj = accessor() - assertJSNotUndefined(obj) - assertEquals("object", js.typeOf(obj)) - assertEquals("witness", obj.witness) - } - - @Test def exports_for_Scala_js_defined_JS_objects_with_implicit_name(): Unit = { - val accessor = jsPackage.SJSDefinedExportedObject - assertJSNotUndefined(accessor) - assertEquals("function", js.typeOf(accessor)) - val obj = accessor() - assertJSNotUndefined(obj) - assertEquals("object", js.typeOf(obj)) - assertEquals("witness", obj.witness) - } - - @Test def exports_for_objects_with_explicit_name(): Unit = { - val accessor = exportsNamespace.TheExportedObject - assertJSNotUndefined(accessor) - assertEquals("function", js.typeOf(accessor)) - val obj = accessor() - assertJSNotUndefined(obj) - assertEquals("object", js.typeOf(obj)) - assertEquals("witness", obj.witness) - } - @Test def toplevel_exports_for_objects(): Unit = { val obj = exportsNamespace.TopLevelExportedObject assertJSNotUndefined(obj) @@ -654,34 +624,13 @@ class ExportsTest { assertEquals("witness", obj.witness) } - @Test def exports_for_Scala_js_defined_JS_objects_with_explicit_name(): Unit = { - val accessor = exportsNamespace.TheSJSDefinedExportedObject - assertJSNotUndefined(accessor) - assertEquals("function", js.typeOf(accessor)) - val obj = accessor() - assertJSNotUndefined(obj) - assertEquals("object", js.typeOf(obj)) - assertEquals("witness", obj.witness) - } - @Test def toplevel_exports_for_Scala_js_defined_JS_objects(): Unit = { val obj1 = exportsNamespace.SJSDefinedTopLevelExportedObject assertJSNotUndefined(obj1) assertEquals("object", js.typeOf(obj1)) assertEquals("witness", obj1.witness) - val obj2 = exportsNamespace.TheSJSDefinedTopLevelExportedObject - assertSame(obj1, obj2) - } - - @Test def exports_for_objects_with_qualified_name(): Unit = { - val accessor = exportsNamespace.qualified.testobject.ExportedObject - assertJSNotUndefined(accessor) - assertEquals("function", js.typeOf(accessor)) - val obj = accessor() - assertJSNotUndefined(obj) - assertEquals("object", js.typeOf(obj)) - assertEquals("witness", obj.witness) + assertSame(obj1, SJSDefinedExportedObject) } @Test def toplevel_exports_for_objects_with_qualified_name(): Unit = { @@ -691,68 +640,27 @@ class ExportsTest { assertEquals("witness", obj.witness) } - @Test def exports_for_nested_objects(): Unit = { - val accessor = exportsNamespace.qualified.nested.ExportedObject - assertJSNotUndefined(accessor) - assertEquals("function", js.typeOf(accessor)) - val obj = accessor() - assertJSNotUndefined(obj) - assertEquals("object", js.typeOf(obj)) - assertSame(obj, ExportHolder.ExportedObject) - } - @Test def toplevel_exports_for_nested_objects(): Unit = { - val obj = exportsNamespace.qualified.nested.TopLevelExportedObject + val obj = exportsNamespace.qualified.nested.ExportedObject assertJSNotUndefined(obj) assertEquals("object", js.typeOf(obj)) - assertSame(obj, ExportHolder.TopLevelExportedObject) + assertSame(obj, ExportHolder.ExportedObject) } @Test def exports_for_objects_with_constant_folded_name(): Unit = { - val accessor = exportsNamespace.ConstantFoldedObjectExport - assertJSNotUndefined(accessor) - assertEquals("function", js.typeOf(accessor)) - val obj = accessor() + val obj = exportsNamespace.ConstantFoldedObjectExport assertJSNotUndefined(obj) assertEquals("object", js.typeOf(obj)) assertEquals("witness", obj.witness) } @Test def exports_for_protected_objects(): Unit = { - val accessor = jsPackage.ProtectedExportedObject - assertJSNotUndefined(accessor) - assertEquals("function", js.typeOf(accessor)) - val obj = accessor() + val obj = exportsNamespace.ProtectedExportedObject assertJSNotUndefined(obj) assertEquals("object", js.typeOf(obj)) assertEquals("witness", obj.witness) } - @Test def exports_for_classes_with_implicit_name(): Unit = { - val constr = jsPackage.ExportedClass - assertJSNotUndefined(constr) - assertEquals("function", js.typeOf(constr)) - val obj = js.Dynamic.newInstance(constr)(5) - assertEquals(5, obj.x) - } - - @Test def exports_for_Scala_js_defined_JS_classes_with_implicit_name(): Unit = { - val constr = jsPackage.SJSDefinedExportedClass - assertJSNotUndefined(constr) - assertEquals("function", js.typeOf(constr)) - val obj = js.Dynamic.newInstance(constr)(5) - assertTrue((obj: Any).isInstanceOf[SJSDefinedExportedClass]) - assertEquals(5, obj.x) - } - - @Test def exports_for_classes_with_explicit_name(): Unit = { - val constr = exportsNamespace.TheExportedClass - assertJSNotUndefined(constr) - assertEquals("function", js.typeOf(constr)) - val obj = js.Dynamic.newInstance(constr)(5) - assertEquals(5, obj.x) - } - @Test def toplevel_exports_for_classes(): Unit = { val constr = exportsNamespace.TopLevelExportedClass assertJSNotUndefined(constr) @@ -761,15 +669,6 @@ class ExportsTest { assertEquals(5, obj.x) } - @Test def exports_for_Scala_js_defined_JS_classes_with_explicit_name(): Unit = { - val constr = exportsNamespace.TheSJSDefinedExportedClass - assertJSNotUndefined(constr) - assertEquals("function", js.typeOf(constr)) - val obj = js.Dynamic.newInstance(constr)(5) - assertTrue((obj: Any).isInstanceOf[SJSDefinedExportedClass]) - assertEquals(5, obj.x) - } - @Test def toplevel_exports_for_Scala_js_defined_JS_classes(): Unit = { val constr = exportsNamespace.SJSDefinedTopLevelExportedClass assertJSNotUndefined(constr) @@ -778,16 +677,7 @@ class ExportsTest { assertTrue((obj: Any).isInstanceOf[SJSDefinedTopLevelExportedClass]) assertEquals(5, obj.x) - val constr2 = exportsNamespace.TheSJSDefinedTopLevelExportedClass - assertSame(constr, constr2) - } - - @Test def exports_for_classes_with_qualified_name_ExportedClass(): Unit = { - val constr = exportsNamespace.qualified.testclass.ExportedClass - assertJSNotUndefined(constr) - assertEquals("function", js.typeOf(constr)) - val obj = js.Dynamic.newInstance(constr)(5) - assertEquals(5, obj.x) + assertSame(constr, js.constructorOf[SJSDefinedTopLevelExportedClass]) } @Test def toplevel_exports_for_classes_with_qualified_name(): Unit = { @@ -798,7 +688,7 @@ class ExportsTest { assertEquals(5, obj.x) } - @Test def exports_for_nested_classes(): Unit = { + @Test def toplevel_exports_for_nested_classes(): Unit = { val constr = exportsNamespace.qualified.nested.ExportedClass assertJSNotUndefined(constr) assertEquals("function", js.typeOf(constr)) @@ -806,24 +696,16 @@ class ExportsTest { assertTrue((obj: Any).isInstanceOf[ExportHolder.ExportedClass]) } - @Test def toplevel_exports_for_nested_classes(): Unit = { - val constr = exportsNamespace.qualified.nested.TopLevelExportedClass - assertJSNotUndefined(constr) - assertEquals("function", js.typeOf(constr)) - val obj = js.Dynamic.newInstance(constr)() - assertTrue((obj: Any).isInstanceOf[ExportHolder.TopLevelExportedClass]) - } - - @Test def exports_for_classes_with_qualified_name_SJSDefinedExportedClass(): Unit = { - val constr = exportsNamespace.qualified.testclass.SJSDefinedExportedClass + @Test def toplevel_exports_for_classes_with_qualified_name_SJSDefinedExportedClass(): Unit = { + val constr = exportsNamespace.qualified.testclass.SJSDefinedTopLevelExportedClass assertJSNotUndefined(constr) assertEquals("function", js.typeOf(constr)) val obj = js.Dynamic.newInstance(constr)(5) - assertTrue((obj: Any).isInstanceOf[SJSDefinedExportedClass]) + assertTrue((obj: Any).isInstanceOf[SJSDefinedTopLevelExportedClass]) assertEquals(5, obj.x) } - @Test def exports_for_nested_sjs_defined_classes(): Unit = { + @Test def toplevel_exports_for_nested_sjs_defined_classes(): Unit = { val constr = exportsNamespace.qualified.nested.SJSDefinedExportedClass assertJSNotUndefined(constr) assertEquals("function", js.typeOf(constr)) @@ -840,7 +722,7 @@ class ExportsTest { } @Test def exports_for_protected_classes(): Unit = { - val constr = jsPackage.ProtectedExportedClass + val constr = exportsNamespace.ProtectedExportedClass assertJSNotUndefined(constr) assertEquals("function", js.typeOf(constr)) val obj = js.Dynamic.newInstance(constr)(5) @@ -848,7 +730,7 @@ class ExportsTest { } @Test def export_for_classes_with_repeated_parameters_in_ctor(): Unit = { - val constr = jsPackage.ExportedVarArgClass + val constr = exportsNamespace.ExportedVarArgClass assertEquals("", js.Dynamic.newInstance(constr)().result) assertEquals("a", js.Dynamic.newInstance(constr)("a").result) assertEquals("a|b", js.Dynamic.newInstance(constr)("a", "b").result) @@ -857,7 +739,7 @@ class ExportsTest { } @Test def export_for_classes_with_default_parameters_in_ctor(): Unit = { - val constr = jsPackage.ExportedDefaultArgClass + val constr = exportsNamespace.ExportedDefaultArgClass assertEquals(6, js.Dynamic.newInstance(constr)(1,2,3).result) assertEquals(106, js.Dynamic.newInstance(constr)(1).result) assertEquals(103, js.Dynamic.newInstance(constr)(1,2).result) @@ -1025,9 +907,7 @@ class ExportsTest { } @Test def exporting_under_org_namespace_issue_364(): Unit = { - val accessor = exportsNamespace.org.ExportedUnderOrgObject - assertEquals("function", js.typeOf(accessor)) - val obj = accessor() + val obj = exportsNamespace.org.ExportedUnderOrgObject assertSame(ExportedUnderOrgObject.asInstanceOf[js.Any], obj) } @@ -1145,13 +1025,13 @@ class ExportsTest { } @Test def `exports_for_classes_ending_in__=_issue_1090`(): Unit = { - val constr = jsPackage.ExportClassSetterNamed_= + val constr = exportsNamespace.ExportClassSetterNamed_= val obj = js.Dynamic.newInstance(constr)() assertEquals(obj.x, 1) } @Test def `exports_for_objects_ending_in__=_issue_1090`(): Unit = { - assertEquals(jsPackage.ExportObjSetterNamed_=().x, 1) + assertEquals(exportsNamespace.ExportObjSetterNamed_=.x, 1) } @Test def should_expose_public_members_of_new_js_Object_issue_1899(): Unit = { @@ -1384,122 +1264,89 @@ object ExportNameHolder { final val methodName = "myMethod" } -@JSExport -@JSExport("TheExportedObject") -@JSExport("qualified.testobject.ExportedObject") // purposefully halfway the same as ExportedClass -@JSExport(ExportNameHolder.objectName) -object ExportedObject { - @JSExport - def witness: String = "witness" -} - @JSExportTopLevel("TopLevelExportedObject") @JSExportTopLevel("qualified.testobject.TopLevelExportedObject") +@JSExportTopLevel(ExportNameHolder.objectName) object TopLevelExportedObject { @JSExport val witness: String = "witness" } -@JSExport -@JSExport("TheSJSDefinedExportedObject") -object SJSDefinedExportedObject extends js.Object { - def witness: String = "witness" -} - @JSExportTopLevel("SJSDefinedTopLevelExportedObject") -@JSExportTopLevel("TheSJSDefinedTopLevelExportedObject") -object SJSDefinedTopLevelExportedObject extends js.Object { +@JSExportTopLevel("qualified.testobject.SJSDefinedTopLevelExportedObject") +object SJSDefinedExportedObject extends js.Object { val witness: String = "witness" } -@JSExport +@JSExportTopLevel("ProtectedExportedObject") protected object ProtectedExportedObject { @JSExport def witness: String = "witness" } -@JSExport -@JSExport("TheExportedClass") -@JSExport("qualified.testclass.ExportedClass") // purposefully halfway the same as ExportedObject -@JSExport(ExportNameHolder.className) -class ExportedClass(_x: Int) { - @JSExport - val x = _x -} - @JSExportTopLevel("TopLevelExportedClass") @JSExportTopLevel("qualified.testclass.TopLevelExportedClass") +@JSExportTopLevel(ExportNameHolder.className) class TopLevelExportedClass(_x: Int) { @JSExport val x = _x } -@JSExport -@JSExport("TheSJSDefinedExportedClass") -@JSExport("qualified.testclass.SJSDefinedExportedClass") -class SJSDefinedExportedClass(val x: Int) extends js.Object - @JSExportTopLevel("SJSDefinedTopLevelExportedClass") -@JSExportTopLevel("TheSJSDefinedTopLevelExportedClass") +@JSExportTopLevel("qualified.testclass.SJSDefinedTopLevelExportedClass") class SJSDefinedTopLevelExportedClass(val x: Int) extends js.Object -@JSExport +@JSExportTopLevel("ProtectedExportedClass") protected class ProtectedExportedClass(_x: Int) { @JSExport val x = _x } -@JSExport +@JSExportTopLevel("ExportedVarArgClass") class ExportedVarArgClass(x: String*) { - @JSExport + @JSExportTopLevel("ExportedVarArgClass") def this(x: Int, y: String) = this(s"Number: <$x>", y) @JSExport def result: String = x.mkString("|") } -@JSExport +@JSExportTopLevel("ExportedDefaultArgClass") class ExportedDefaultArgClass(x: Int, y: Int, z: Int) { - @JSExport + @JSExportTopLevel("ExportedDefaultArgClass") def this(x: Int, y: Int = 5) = this(x, y, 100) @JSExport def result: Int = x + y + z } -@JSExport("org.ExportedUnderOrgObject") +@JSExportTopLevel("org.ExportedUnderOrgObject") object ExportedUnderOrgObject class SomeValueClass(val i: Int) extends AnyVal -@JSExport +@JSExportTopLevel("ExportClassSetterNamed_=") class ExportClassSetterNamed_= { // scalastyle:ignore @JSExport val x = 1 } -@JSExport +@JSExportTopLevel("ExportObjSetterNamed_=") object ExportObjSetterNamed_= { // scalastyle:ignore @JSExport val x = 1 } object ExportHolder { - @JSExport("qualified.nested.ExportedClass") + @JSExportTopLevel("qualified.nested.ExportedClass") class ExportedClass - @JSExportTopLevel("qualified.nested.TopLevelExportedClass") - class TopLevelExportedClass - - @JSExport("qualified.nested.ExportedObject") + @JSExportTopLevel("qualified.nested.ExportedObject") object ExportedObject - @JSExportTopLevel("qualified.nested.TopLevelExportedObject") - object TopLevelExportedObject - - @JSExport("qualified.nested.SJSDefinedExportedClass") + @JSExportTopLevel("qualified.nested.SJSDefinedExportedClass") class SJSDefinedExportedClass extends js.Object } From 3548a278dfcf677a807111441c904d82a6e5e8e4 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 9 Apr 2017 23:35:06 +0200 Subject: [PATCH 0214/2665] Fix #2879: Unify IRFileCache.IRContainer and VirtualFileContainer --- .../scala/org/scalajs/cli/Scalajsld.scala | 2 +- .../scala/tools/nsc/MainGenericRunner.scala | 3 +- .../sbtplugin/ScalaJSPluginInternal.scala | 10 ++-- .../io/IRContainerPlatformExtensions.scala | 14 ----- .../core/tools/test/js/QuickLinker.scala | 7 +-- .../core/tools/io/FileVirtualFiles.scala | 37 +++++++++++-- .../io/IRContainerPlatformExtensions.scala | 52 ------------------- .../scalajs/core/tools/io/IRFileCache.scala | 49 ++++------------- .../scalajs/core/tools/io/VirtualFiles.scala | 25 +++++++-- 9 files changed, 73 insertions(+), 126 deletions(-) delete mode 100644 tools/js/src/main/scala/org/scalajs/core/tools/io/IRContainerPlatformExtensions.scala delete mode 100644 tools/jvm/src/main/scala/org/scalajs/core/tools/io/IRContainerPlatformExtensions.scala diff --git a/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala b/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala index 40c3a679fe..03f38c8557 100644 --- a/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala +++ b/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala @@ -161,7 +161,7 @@ object Scalajsld { for (options <- parser.parse(args, Options())) { val classpath = options.stdLib.toList ++ options.cp - val irContainers = IRFileCache.IRContainer.fromClasspath(classpath) + val irContainers = FileScalaJSIRContainer.fromClasspath(classpath) val moduleInitializers = options.moduleInitializers // Warn if writing JS dependencies was requested. diff --git a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala index 6d3d788f18..8de5e690cf 100644 --- a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala +++ b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala @@ -6,7 +6,6 @@ import org.scalajs.core.tools.sem.Semantics import org.scalajs.core.tools.logging._ import org.scalajs.core.tools.io._ import org.scalajs.core.tools.jsdep.ResolvedJSDependency -import org.scalajs.core.tools.io.IRFileCache.IRContainer import org.scalajs.core.tools.linker.{Linker, ModuleInitializer} import org.scalajs.core.tools.linker.backend.{OutputMode, ModuleKind} @@ -89,7 +88,7 @@ class MainGenericRunner { private def loadIR(classpathURLs: Seq[URL]) = { val irContainers = - IRContainer.fromClasspath(classpathURLs.map(urlToFile)) + FileScalaJSIRContainer.fromClasspath(classpathURLs.map(urlToFile)) val cache = (new IRFileCache).newCache cache.cached(irContainers) } diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index c7eef1de02..e9d4a43126 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -387,13 +387,9 @@ object ScalaJSPluginInternal { }.dependsOn(scalaJSClearCacheStats).value, scalaJSIR := { - import IRFileCache.IRContainer - - val rawIR = collectFromClasspath(fullClasspath.value, - "*.sjsir", collectJar = jar => IRContainer.Jar(jar) :: Nil, - collectFile = { (file, relPath) => - IRContainer.File(FileVirtualScalaJSIRFile.relative(file, relPath)) - }) + val rawIR = collectFromClasspath(fullClasspath.value, "*.sjsir", + collectJar = Seq(_), + collectFile = FileVirtualScalaJSIRFile.relative) val cache = scalaJSIRCache.value rawIR.map(cache.cached) diff --git a/tools/js/src/main/scala/org/scalajs/core/tools/io/IRContainerPlatformExtensions.scala b/tools/js/src/main/scala/org/scalajs/core/tools/io/IRContainerPlatformExtensions.scala deleted file mode 100644 index 191aa37329..0000000000 --- a/tools/js/src/main/scala/org/scalajs/core/tools/io/IRContainerPlatformExtensions.scala +++ /dev/null @@ -1,14 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.core.tools.io - -import org.scalajs.core.tools.io.IRFileCache.IRContainer - -trait IRContainerPlatformExtensions { this: IRContainer.type => } diff --git 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 index 907ccbad31..8f7735b0df 100644 --- 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 @@ -4,7 +4,6 @@ import java.io.InputStream import org.scalajs.core.tools.sem.Semantics import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.io.IRFileCache.IRContainer import org.scalajs.core.tools.linker.{ModuleInitializer, Linker} import org.scalajs.core.tools.linker.backend.{OutputMode, ModuleKind} import org.scalajs.core.tools.logging._ @@ -46,14 +45,12 @@ object QuickLinker { val irContainers = irFilesAndJars.map { file => if (file.endsWith(".jar")) { - val vf = new NodeVirtualJarFile(file) - IRContainer.Jar(vf) + new NodeVirtualJarFile(file) } else if (file.endsWith(".sjsir")) { - val vf = new NodeVirtualScalaJSIRFile(file) with RelativeVirtualFile { + new NodeVirtualScalaJSIRFile(file) with VirtualRelativeScalaJSIRFile { // The compiler should not use this (only scalajsp does) def relativePath: String = s"" } - IRContainer.File(vf) } else { sys.error("Illegal IR file / Jar: " + file) } diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala index 2b8475b7f1..4cae5cefe0 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala @@ -168,9 +168,9 @@ object FileVirtualScalaJSIRFile extends (File => FileVirtualScalaJSIRFile) { def apply(f: File): FileVirtualScalaJSIRFile = new FileVirtualScalaJSIRFile(f) - def relative(f: File, - relPath: String): FileVirtualScalaJSIRFile with RelativeVirtualFile = { - new FileVirtualScalaJSIRFile(f) with RelativeVirtualFile { + def relative(f: File, relPath: String): FileVirtualScalaJSIRFile + with VirtualRelativeScalaJSIRFile = { + new FileVirtualScalaJSIRFile(f) with VirtualRelativeScalaJSIRFile { def relativePath: String = relPath } } @@ -178,3 +178,34 @@ object FileVirtualScalaJSIRFile extends (File => FileVirtualScalaJSIRFile) { def isScalaJSIRFile(file: File): Boolean = hasExtension(file, ".sjsir") } + +object FileScalaJSIRContainer { + def fromClasspath(classpath: Seq[File]): Seq[ScalaJSIRContainer] = { + classpath flatMap { entry => + if (!entry.exists) + Nil + else if (entry.isDirectory) + fromDirectory(entry) + else if (entry.getName.endsWith(".jar")) + List(new FileVirtualBinaryFile(entry) with VirtualJarFile) + else + throw new IllegalArgumentException("Illegal classpath entry " + entry) + } + } + + private def fromDirectory(dir: File): Seq[ScalaJSIRContainer] = { + require(dir.isDirectory) + + val baseDir = dir.getAbsoluteFile + + def walkForIR(dir: File): Seq[File] = { + val (subdirs, files) = dir.listFiles().partition(_.isDirectory) + subdirs.flatMap(walkForIR) ++ files.filter(_.getName.endsWith(".sjsir")) + } + + for (ir <- walkForIR(baseDir)) yield { + val relDir = ir.getPath.stripPrefix(baseDir.getPath) + FileVirtualScalaJSIRFile.relative(ir, relDir) + } + } +} diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/io/IRContainerPlatformExtensions.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/io/IRContainerPlatformExtensions.scala deleted file mode 100644 index d26ebd519d..0000000000 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/io/IRContainerPlatformExtensions.scala +++ /dev/null @@ -1,52 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.core.tools.io - -import java.io.{File => JFile} - -import org.scalajs.core.tools.io.IRFileCache.IRContainer - -trait IRContainerPlatformExtensions { this: IRContainer.type => - def fromClasspath(classpath: Seq[JFile]): Seq[IRContainer] = { - classpath flatMap { entry => - if (!entry.exists) - Nil - else if (entry.isDirectory) - fromDirectory(entry) - else if (entry.getName.endsWith(".jar")) - fromJar(entry) :: Nil - else - throw new IllegalArgumentException("Illegal classpath entry " + entry) - } - } - - def fromJar(jar: JFile): Jar = { - require(jar.isFile) - val vf = new FileVirtualBinaryFile(jar) with VirtualJarFile - Jar(vf) - } - - def fromDirectory(dir: JFile): Seq[File] = { - require(dir.isDirectory) - - val baseDir = dir.getAbsoluteFile - - def walkForIR(dir: JFile): Seq[JFile] = { - val (subdirs, files) = dir.listFiles().partition(_.isDirectory) - subdirs.flatMap(walkForIR) ++ files.filter(_.getName.endsWith(".sjsir")) - } - - for (ir <- walkForIR(baseDir)) yield { - val relDir = ir.getPath.stripPrefix(baseDir.getPath) - val vf = FileVirtualScalaJSIRFile.relative(ir, relDir) - File(vf) - } - } -} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala index 618d8171fa..f89d936c5d 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala @@ -30,8 +30,6 @@ final class IRFileCache { * that paying the cost for synchronization is lower than I/O. */ - import IRFileCache._ - /** Holds the cached IR */ private[this] val globalCache = new ConcurrentHashMap[String, PersistedFiles] @@ -71,15 +69,15 @@ final class IRFileCache { * [[free]]. * * @note Updating any of the underlying files in the container during the - * lifetime of a returned [[IRFileCache.VirtualRelativeIRFile]] yields + * lifetime of a returned [[VirtualRelativeScalaJSIRFile]] yields * unspecified behavior. */ - def cached(files: Seq[IRContainer]): Seq[VirtualRelativeIRFile] = { + def cached(files: Seq[ScalaJSIRContainer]): Seq[VirtualRelativeScalaJSIRFile] = { update(files) localCache.flatMap(_.files) } - private def update(files: Seq[IRContainer]): Unit = clearOnThrow { + private def update(files: Seq[ScalaJSIRContainer]): Unit = clearOnThrow { val result = Seq.newBuilder[PersistedFiles] for (file <- files) { @@ -145,9 +143,9 @@ final class IRFileCache { * May only be written under synchronization, except if this is a tombstone */ @volatile - private[this] var _files: Seq[VirtualRelativeIRFile] = null + private[this] var _files: Seq[VirtualRelativeScalaJSIRFile] = null - def files: Seq[VirtualRelativeIRFile] = _files + def files: Seq[VirtualRelativeScalaJSIRFile] = _files /** Try to reference this block of files. * @return true if referencing succeeded, false if this is a tombstone @@ -195,11 +193,11 @@ final class IRFileCache { _files = null } - /** Updates this file with the given [[IRContainer]]. + /** Updates this file with the given [[ScalaJSIRContainer]]. * * May only be called by a thread, if it holds a reference to this file. */ - def update(file: IRContainer): Unit = { + def update(file: ScalaJSIRContainer): Unit = { assert(_references.get > 0, "Updating an unreferenced file") assert(file.path == path, s"Path mismatch: $path, ${file.path}") @@ -218,22 +216,17 @@ final class IRFileCache { statsReused.incrementAndGet() } else { statsInvalidated.incrementAndGet() - _files = extractIRFiles(file).map(new PersistentIRFile(_)) + _files = file.sjsirFiles.map(new PersistentIRFile(_)) _version = file.version } } } } - - private def extractIRFiles(file: IRContainer) = file match { - case IRContainer.File(file) => file :: Nil - case IRContainer.Jar(jar) => jar.sjsirFiles - } } private final class PersistentIRFile( - private[this] var _irFile: VirtualRelativeIRFile) - extends VirtualScalaJSIRFile with RelativeVirtualFile { + private[this] var _irFile: VirtualRelativeScalaJSIRFile) + extends VirtualRelativeScalaJSIRFile { import ir.Trees._ import ir.Infos @@ -298,26 +291,4 @@ object IRFileCache { s"trees read: $treesRead" } } - - type VirtualRelativeIRFile = VirtualScalaJSIRFile with RelativeVirtualFile - - sealed trait IRContainer extends VirtualFile - - object IRContainer extends IRContainerPlatformExtensions { - final case class File(ir: VirtualRelativeIRFile) extends IRContainer { - override def path: String = ir.path - override def name: String = ir.name - override def version: Option[String] = ir.version - override def exists: Boolean = ir.exists - override def toURI: URI = ir.toURI - } - - final case class Jar(jar: VirtualFileContainer) extends IRContainer { - override def path: String = jar.path - override def name: String = jar.name - override def version: Option[String] = jar.version - override def exists: Boolean = jar.exists - override def toURI: URI = jar.toURI - } - } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala index 4f3a8bee8e..70487bc1e6 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala @@ -118,6 +118,20 @@ trait WritableVirtualJSFile extends WritableVirtualTextFile with VirtualJSFile { def sourceMapWriter: Writer } +/** A virtual file containing Scala.js IR. + * + * This can be a [[VirtualScalaJSIRFile]] (with [[RelativeVirtualFile]]) or a + * [[VirtualFileContainer]]. + * + * The main difference compared to using individual files + * (that are extracted beforehand) is that the fileset can be versioned at a + * higher level: the container needs to change its version when any of the + * files change. Therefore, the entire extraction process can be cached. + */ +trait ScalaJSIRContainer extends VirtualFile { + def sjsirFiles: List[VirtualRelativeScalaJSIRFile] +} + /** A virtual Scala.js IR file. * It contains the class info and the IR tree. */ @@ -134,6 +148,11 @@ trait VirtualScalaJSIRFile extends VirtualFile { def infoAndTree: (ir.Infos.ClassInfo, ir.Trees.ClassDef) } +trait VirtualRelativeScalaJSIRFile extends VirtualScalaJSIRFile + with RelativeVirtualFile with ScalaJSIRContainer { + def sjsirFiles: List[VirtualRelativeScalaJSIRFile] = this :: Nil +} + /** Base trait for virtual Scala.js IR files that are serialized as binary file. */ trait VirtualSerializedScalaJSIRFile extends VirtualBinaryFile with VirtualScalaJSIRFile { @@ -178,7 +197,7 @@ trait VirtualSerializedScalaJSIRFile extends VirtualBinaryFile with VirtualScala * This is a generic virtual container for embedded virtual files, especially * one found on a classpath such as a jar, and containing `.sjsir` files. */ -trait VirtualFileContainer extends VirtualFile { +trait VirtualFileContainer extends ScalaJSIRContainer { import VirtualFileContainer._ /** Lists the entries of this container that satisfy a given predicate. @@ -203,7 +222,7 @@ trait VirtualFileContainer extends VirtualFile { * efficient than using `listEntries` with a predicate * `_.endsWith(".sjsir")`. */ - def sjsirFiles: List[VirtualScalaJSIRFile with RelativeVirtualFile] = { + def sjsirFiles: List[VirtualRelativeScalaJSIRFile] = { listEntries(_.endsWith(".sjsir")) { (relPath, stream) => val file = new EntryIRFile(path, relPath) file.content = IO.readInputStreamToByteArray(stream) @@ -232,7 +251,7 @@ trait VirtualFileContainer extends VirtualFile { private object VirtualFileContainer { private class EntryIRFile(outerPath: String, val relativePath: String) extends MemVirtualSerializedScalaJSIRFile(s"$outerPath:$relativePath") - with RelativeVirtualFile + with VirtualRelativeScalaJSIRFile private class EntryJSFile(outerPath: String, val relativePath: String) extends MemVirtualJSFile(s"$outerPath:$relativePath") From 4d2bdb3ab29f2cff2b094dfcfb42a026e09fed99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 12 Apr 2017 12:05:35 +0200 Subject: [PATCH 0215/2665] Upgrade to sbt 0.13.15. Including the sbt-plugin-test, which we had left behind at 0.13.9. --- project/build.properties | 2 +- sbt-plugin-test/project/build.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/project/build.properties b/project/build.properties index 27e88aa115..64317fdae5 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.13 +sbt.version=0.13.15 diff --git a/sbt-plugin-test/project/build.properties b/sbt-plugin-test/project/build.properties index 817bc38df8..64317fdae5 100644 --- a/sbt-plugin-test/project/build.properties +++ b/sbt-plugin-test/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.9 +sbt.version=0.13.15 From 570e837aa3fa8a97d26c62f9f2eee6507e88ad6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 11 Apr 2017 22:46:48 +0200 Subject: [PATCH 0216/2665] Fix #2889: Explicitly export HTMLRunner.main(). We previously relied on the automatic *export* of `js.JSApp`s, but this feature was dropped in facca8515a55a0969c618dc59a71a885449897da with the decommissioning of `@JSExportDescendentObjects`. Instead of `HTMLRunner extends js.JSApp`, we now explicitly export its `main` method. --- .../main/scala/org/scalajs/sbtplugin/HTMLRunnerTemplate.scala | 2 +- .../src/main/scala/org/scalajs/testinterface/HTMLRunner.scala | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/HTMLRunnerTemplate.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/HTMLRunnerTemplate.scala index 010e41b23b..d88f60b562 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/HTMLRunnerTemplate.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/HTMLRunnerTemplate.scala @@ -45,7 +45,7 @@ private[scalajs] object HTMLRunnerTemplate { ${renderTestDefinitions(loadedFrameworks, definedTests)} - + """ } diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala b/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala index 3c1708bc35..d8c6780090 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala @@ -21,7 +21,7 @@ import scala.util.Try import sbt.testing._ -protected[testinterface] object HTMLRunner extends js.JSApp { +protected[testinterface] object HTMLRunner { private val classLoader = new ScalaJSClassLoader(js.Dynamic.global) private object EventCounter { @@ -42,6 +42,7 @@ protected[testinterface] object HTMLRunner extends js.JSApp { } } + @JSExportTopLevel("org.scalajs.testinterface.HTMLRunner.main") def main(): Unit = { /* Note: Test filtering is currently done based on the fully qualified name * of a test. While this is reasonable in most cases, there could be a test From 0afd2d9f5c278e6470873197f1ce4149829a35ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 10 Apr 2017 22:27:16 +0200 Subject: [PATCH 0217/2665] Actually use `enablePlugins(ScalaJSPlugin)` inside our own build. We previously avoided that not to have so-called "ecosystem" settings, e.g., library dependencies on our own artifacts. It is however equally easy to cancel out those settings we do not want in a custom `AutoPlugin` specific to the build. This allows us to use a genuine `enablePlugins`, which in turn will allow us to add more `enablePlugins` on plugins that depend on `ScalaJSPlugin` without breaking everything. For example, we do this with `PhantomJSEnvPlugin`. --- project/Build.scala | 159 ++++++++++++++++++++++++++++---------------- 1 file changed, 100 insertions(+), 59 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 90294fff15..2555495b4f 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -48,11 +48,47 @@ object ExposedValues extends AutoPlugin { } } -object Build { +object MyScalaJSPlugin extends AutoPlugin { + override def requires: Plugins = ScalaJSPlugin && PhantomJSEnvPlugin val isGeneratingEclipse = Properties.envOrElse("GENERATING_ECLIPSE", "false").toBoolean + override def projectSettings: Seq[Setting[_]] = Seq( + /* Remove libraryDependencies on ourselves; we use .dependsOn() instead + * inside this build. + */ + libraryDependencies ~= { libDeps => + val blacklist = + Set("scalajs-compiler", "scalajs-library", "scalajs-test-interface") + libDeps.filterNot(dep => blacklist.contains(dep.name)) + }, + + /* Most of our Scala.js libraries are not cross-compiled against the + * the Scala.js binary version number. + */ + crossVersion := CrossVersion.binary, + + scalaJSOptimizerOptions ~= (_.withCheckScalaJSIR(true)), + + // Link source maps + scalacOptions ++= { + val base = (baseDirectory in LocalProject("scalajs")).value + if (isGeneratingEclipse) Seq() + else if (scalaJSIsSnapshotVersion) Seq() + else Seq( + // Link source maps to github sources + "-P:scalajs:mapSourceURI:" + base.toURI + + "->https://raw.githubusercontent.com/scala-js/scala-js/v" + + scalaJSVersion + "/" + ) + } + ) +} + +object Build { + import MyScalaJSPlugin.isGeneratingEclipse + val fetchScalaSource = taskKey[File]( "Fetches the scala source for the current scala version") val shouldPartest = settingKey[Boolean]( @@ -348,25 +384,6 @@ object Build { publishMavenStyle := false ) - val myScalaJSSettings = Def.settings( - ScalaJSPluginInternal.scalaJSAbstractSettings, - PhantomJSEnvPlugin.projectSettings, - autoCompilerPlugins := true, - scalaJSOptimizerOptions ~= (_.withCheckScalaJSIR(true)), - - // Link source maps - scalacOptions ++= { - if (isGeneratingEclipse) Seq() - else if (scalaJSIsSnapshotVersion) Seq() - else Seq( - // Link source maps to github sources - "-P:scalajs:mapSourceURI:" + root.base.toURI + - "->https://raw.githubusercontent.com/scala-js/scala-js/v" + - scalaJSVersion + "/" - ) - } - ) - implicit class ProjectOps(val project: Project) extends AnyVal { /** Uses the Scala.js compiler plugin. */ def withScalaJSCompiler: Project = @@ -415,7 +432,6 @@ object Build { } val thisBuildSettings = Def.settings( - inScope(Global)(ScalaJSPlugin.globalSettings), // Most of the projects cross-compile crossScalaVersions := Seq( "2.10.2", @@ -495,9 +511,12 @@ object Build { "com.novocode" % "junit-interface" % "0.9" % "test" ) - lazy val irProjectJS: Project = Project(id = "irJS", base = file("ir/.js")).settings( + lazy val irProjectJS: Project = Project( + id = "irJS", base = file("ir/.js") + ).enablePlugins( + MyScalaJSPlugin + ).settings( commonIrProjectSettings, - myScalaJSSettings, crossVersion := ScalaJSCrossVersion.binary, unmanagedSourceDirectories in Compile += (scalaSource in Compile in irProject).value, @@ -590,8 +609,9 @@ object Build { ) ).dependsOn(irProject) - lazy val toolsJS: Project = (project in file("tools/js")).settings( - myScalaJSSettings, + lazy val toolsJS: Project = (project in file("tools/js")).enablePlugins( + MyScalaJSPlugin + ).settings( commonToolsSettings, crossVersion := ScalaJSCrossVersion.binary, resourceGenerators in Test += Def.task { @@ -605,8 +625,8 @@ object Build { (definedTests in testSuite in Test).value) } - IO.write(outFile, testDefinitions) - Seq(outFile) + IO.write(outFile, testDefinitions) + Seq(outFile) }.taskValue, jsDependencies += ProvidedJS / "js-test-definitions.js" % "test", @@ -778,9 +798,10 @@ object Build { output } - lazy val javalanglib: Project = project.settings( + lazy val javalanglib: Project = project.enablePlugins( + MyScalaJSPlugin + ).settings( commonSettings, - myScalaJSSettings, fatalWarningsSettings, name := "java.lang library for Scala.js", publishArtifact in Compile := false, @@ -797,9 +818,10 @@ object Build { scalaJSExternalCompileSettings ).withScalaJSCompiler.dependsOnLibraryNoJar - lazy val javalib: Project = project.settings( + lazy val javalib: Project = project.enablePlugins( + MyScalaJSPlugin + ).settings( commonSettings, - myScalaJSSettings, fatalWarningsSettings, name := "Java library for Scala.js", publishArtifact in Compile := false, @@ -808,19 +830,24 @@ object Build { scalaJSExternalCompileSettings ).withScalaJSCompiler.dependsOnLibraryNoJar - lazy val scalalib: Project = project.settings( + lazy val scalalib: Project = project.enablePlugins( + MyScalaJSPlugin + ).settings( commonSettings, /* Link source maps to the GitHub sources of the original scalalib - * #2195 This must come *before* the option added by myScalaJSSettings + * #2195 This must come *before* the option added by MyScalaJSPlugin * because mapSourceURI works on a first-match basis. */ - scalacOptions += { - "-P:scalajs:mapSourceURI:" + - (artifactPath in fetchScalaSource).value.toURI + - "->https://raw.githubusercontent.com/scala/scala/v" + - scalaVersion.value + "/src/library/" + scalacOptions := { + val previousScalacOptions = scalacOptions.value + val sourceMapOption = { + "-P:scalajs:mapSourceURI:" + + (artifactPath in fetchScalaSource).value.toURI + + "->https://raw.githubusercontent.com/scala/scala/v" + + scalaVersion.value + "/src/library/" + } + sourceMapOption +: previousScalacOptions }, - myScalaJSSettings, name := "Scala library for Scala.js", publishArtifact in Compile := false, delambdafySetting, @@ -958,9 +985,10 @@ object Build { scalaJSExternalCompileSettings ).withScalaJSCompiler.dependsOnLibraryNoJar - lazy val libraryAux: Project = (project in file("library-aux")).settings( + lazy val libraryAux: Project = (project in file("library-aux")).enablePlugins( + MyScalaJSPlugin + ).settings( commonSettings, - myScalaJSSettings, fatalWarningsSettings, name := "Scala.js aux library", publishArtifact in Compile := false, @@ -969,10 +997,11 @@ object Build { scalaJSExternalCompileSettings ).withScalaJSCompiler.dependsOnLibraryNoJar - lazy val library: Project = project.settings( + lazy val library: Project = project.enablePlugins( + MyScalaJSPlugin + ).settings( commonSettings, publishSettings, - myScalaJSSettings, fatalWarningsSettings, name := "Scala.js library", delambdafySetting, @@ -1072,10 +1101,11 @@ object Build { ).dependsOn(tools) // Test framework - lazy val testInterface = (project in file("test-interface")).settings( + lazy val testInterface = (project in file("test-interface")).enablePlugins( + MyScalaJSPlugin + ).settings( commonSettings, publishSettings, - myScalaJSSettings, fatalWarningsSettings, name := "Scala.js test interface", delambdafySetting, @@ -1083,10 +1113,11 @@ object Build { mimaBinaryIssueFilters ++= BinaryIncompatibilities.TestInterface ).withScalaJSCompiler.dependsOn(library) - lazy val jUnitRuntime = (project in file("junit-runtime")).settings( + lazy val jUnitRuntime = (project in file("junit-runtime")).enablePlugins( + MyScalaJSPlugin + ).settings( commonSettings, publishSettings, - myScalaJSSettings, fatalWarningsSettings, name := "Scala.js JUnit test runtime" ).withScalaJSCompiler.dependsOn(testInterface) @@ -1104,9 +1135,10 @@ object Build { ) ) - lazy val jUnitTestOutputsJS = (project in file("junit-test/output-js")).settings( + lazy val jUnitTestOutputsJS = (project in file("junit-test/output-js")).enablePlugins( + MyScalaJSPlugin + ).settings( commonJUnitTestOutputsSettings, - myScalaJSSettings, name := "Tests for Scala.js JUnit output in JS." ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( jUnitRuntime % "test", testInterface % "test" @@ -1174,22 +1206,28 @@ object Build { name := "Scala.js examples" ).aggregate(helloworld, reversi, testingExample) - lazy val exampleSettings = commonSettings ++ myScalaJSSettings ++ fatalWarningsSettings + lazy val exampleSettings = commonSettings ++ fatalWarningsSettings - lazy val helloworld: Project = (project in (file("examples") / "helloworld")).settings( + lazy val helloworld: Project = (project in (file("examples") / "helloworld")).enablePlugins( + MyScalaJSPlugin + ).settings( exampleSettings, name := "Hello World - Scala.js example", moduleName := "helloworld", scalaJSUseMainModuleInitializer := true ).withScalaJSCompiler.dependsOn(library) - lazy val reversi = (project in (file("examples") / "reversi")).settings( + lazy val reversi = (project in (file("examples") / "reversi")).enablePlugins( + MyScalaJSPlugin + ).settings( exampleSettings, name := "Reversi - Scala.js example", moduleName := "reversi" ).withScalaJSCompiler.dependsOn(library) - lazy val testingExample = (project in (file("examples") / "testing")).settings( + lazy val testingExample = (project in (file("examples") / "testing")).enablePlugins( + MyScalaJSPlugin + ).settings( exampleSettings, name := "Testing - Scala.js example", moduleName := "testing", @@ -1366,9 +1404,10 @@ object Build { }).value ) - lazy val testSuite: Project = (project in file("test-suite/js")).settings( + lazy val testSuite: Project = (project in file("test-suite/js")).enablePlugins( + MyScalaJSPlugin + ).settings( commonSettings, - myScalaJSSettings, testTagSettings, testSuiteCommonSettings(isJSTest = true), testHtmlSettings(testHtmlFastOpt, FastOptStage), @@ -1528,9 +1567,10 @@ object Build { * 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")).settings( + lazy val testSuiteEx: Project = (project in file("test-suite-ex")).enablePlugins( + MyScalaJSPlugin + ).settings( commonSettings, - myScalaJSSettings, testTagSettings, name := "Scala.js test suite ex", publishArtifact in Compile := false, @@ -1666,9 +1706,10 @@ object Build { }.value ).dependsOn(partest % "test", library) - lazy val scalaTestSuite: Project = (project in file("scala-test-suite")).settings( + lazy val scalaTestSuite: Project = (project in file("scala-test-suite")).enablePlugins( + MyScalaJSPlugin + ).settings( commonSettings, - myScalaJSSettings, publishArtifact in Compile := false, testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a", "-s"), From f2331213f126cb36203b4b929befa9cca357bd5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 10 Apr 2017 23:40:09 +0200 Subject: [PATCH 0218/2665] Add a new task jsExecutionFiles to list *all* JS files sent to JS envs. This currently includes: * The resolved JS dependencies (patched for `commonJSName` support) * The old `scalaJSConfigurationLibs`, which were only used to specify one virtual JS file defining the Java system properties * The linked Scala.js file Additional JS files can be added (typically at the *front* of the sequence) in user-space. This removes one of the last drops of coupling of `jsDependencies` to the rest of the sbt plugin, which will be needed to extract it in a separate sbt plugin. Additionally, it simplifies `loadedJSEnv` so much that there is a good chance we will be able to remove it completely in the future. --- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 7 +- .../sbtplugin/ScalaJSPluginInternal.scala | 79 ++++++++++--------- 2 files changed, 45 insertions(+), 41 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 6f12b70261..4f023f1f3e 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -251,9 +251,10 @@ object ScalaJSPlugin extends AutoPlugin { "Prints the content of a .sjsir file in human readable form.", CTask) - val scalaJSConfigurationLibs = TaskKey[Seq[ResolvedJSDependency]]( - "scalaJSConfigurationLibs", - "List of JS libraries used as project configuration.", CTask) + val jsExecutionFiles = TaskKey[Seq[VirtualJSFile]]( + "jsExecutionFiles", + "All the JS files given to JS environments on `run`, `test`, etc.", + BTask) val scalaJSJavaSystemProperties = TaskKey[Map[String, String]]( "scalaJSJavaSystemProperties", diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index e9d4a43126..a9afc9fc4a 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -535,6 +535,35 @@ object ScalaJSPluginInternal { .put(scalaJSSourceFiles, realFiles) }, + // Add the resolved JS dependencies to the list of JS files given to envs + jsExecutionFiles ++= { + val deps = resolvedJSDependencies.value.data + + /* Implement the behavior of commonJSName without having to burn it + * inside NodeJSEnv, and hence in the JSEnv API. + * Since this matches against NodeJSEnv specifically, it obviously + * breaks the OO approach, but oh well ... + */ + resolvedJSEnv.value match { + case _: org.scalajs.jsenv.nodejs.NodeJSEnv => + val libCache = new VirtualFileMaterializer(false) + + for (dep <- deps) yield { + dep.info.commonJSName.fold { + dep.lib + } { commonJSName => + val fname = libCache.materialize(dep.lib).getAbsolutePath + new MemVirtualJSFile(s"require-$fname").withContent( + s"""$commonJSName = require("${escapeJS(fname)}");""" + ) + } + } + + case _ => + deps.map(_.lib) + } + }, + // Give tasks ability to check we are not forking at build reading time scalaJSEnsureUnforked := { if (fork.value) @@ -560,7 +589,8 @@ object ScalaJSPluginInternal { }.toMap }, - scalaJSConfigurationLibs ++= { + // Optionally add a JS file defining Java system properties + jsExecutionFiles ++= { val javaSystemProperties = scalaJSJavaSystemProperties.value if (javaSystemProperties.isEmpty) { Nil @@ -573,45 +603,14 @@ object ScalaJSPluginInternal { "var __ScalaJSEnv = (typeof __ScalaJSEnv === \"object\" && __ScalaJSEnv) ? __ScalaJSEnv : {};\n" + "__ScalaJSEnv.javaSystemProperties = {" + formattedProps.mkString(", ") + "};\n" } - Seq(ResolvedJSDependency.minimal( - new MemVirtualJSFile("setJavaSystemProperties.js").withContent(code))) + Seq(new MemVirtualJSFile("setJavaSystemProperties.js").withContent(code)) } }, - loadedJSEnv := { - val log = streams.value.log - val env = resolvedJSEnv.value - val deps = - resolvedJSDependencies.value.data ++ scalaJSConfigurationLibs.value + // Crucially, add the Scala.js linked file to the JS files + jsExecutionFiles += scalaJSLinkedFile.value, - /* Implement the behavior of commonJSName without having to burn it - * inside NodeJSEnv, and hence in the JSEnv API. - * Since this matches against NodeJSEnv specifically, it obviously - * breaks the OO approach, but oh well ... - */ - val libs = env match { - case _: org.scalajs.jsenv.nodejs.NodeJSEnv => - val libCache = new VirtualFileMaterializer(false) - - for (dep <- deps) yield { - dep.info.commonJSName.fold { - dep.lib - } { commonJSName => - val fname = libCache.materialize(dep.lib).getAbsolutePath - new MemVirtualJSFile(s"require-$fname").withContent( - s"""$commonJSName = require("${escapeJS(fname)}");""" - ) - } - } - - case _ => - deps.map(_.lib) - } - - val file = scalaJSLinkedFile.value - log.debug(s"Loading JSEnv with linked file ${file.path}") - env.loadLibs(libs :+ file) - }, + loadedJSEnv := resolvedJSEnv.value.loadLibs(jsExecutionFiles.value), scalaJSModuleIdentifier := Def.taskDyn[Option[String]] { scalaJSModuleKind.value match { @@ -868,6 +867,11 @@ object ScalaJSPluginInternal { scalaJSUseMainModuleInitializer := false, scalaJSUseMainModuleInitializer in Test := false, + jsExecutionFiles := Nil, + jsExecutionFiles in Compile := jsExecutionFiles.value, + // Do not inherit jsExecutionFiles in Test from Compile + jsExecutionFiles in Test := jsExecutionFiles.value, + scalaJSConsole := ConsoleJSConsole, clean := { @@ -880,8 +884,7 @@ object ScalaJSPluginInternal { () }, - scalaJSJavaSystemProperties := Map.empty, - scalaJSConfigurationLibs := Nil + scalaJSJavaSystemProperties := Map.empty ) val scalaJSAbstractSettings: Seq[Setting[_]] = ( From b1ffe191ec25f245023876f3ebe68692b93c2a98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 11 Apr 2017 16:25:00 +0200 Subject: [PATCH 0219/2665] Use jsExecutionFiles in testHtml tasks, rather than -jsdeps.js. This is necessary to decouple `testHtmlFastOpt` and `testHtmlFullOpt` from the `jsDependencies` mechanism. To keep supporting the fact that `testHtmlFastOpt` loads `-fastopt.js` while `testHtmlFullOpt` loads `-opt.js`, we have to resort to some ugly manipulation of the files, but it all works out in the end. --- project/Build.scala | 25 ++++++ .../sbtplugin/HTMLRunnerTemplate.scala | 15 ++-- .../sbtplugin/ScalaJSPluginInternal.scala | 90 ++++++++++++------- 3 files changed, 86 insertions(+), 44 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 2555495b4f..f66fc81c96 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1394,6 +1394,31 @@ object Build { supported.map("scalajs." + _ -> "true") }, + // And we need to actually use those patched system properties. + jsExecutionFiles in (Test, testHtmlKey) := { + val previousFiles = (jsExecutionFiles in (Test, testHtmlKey)).value + + val patchedSystemProperties = + (scalaJSJavaSystemProperties in (Test, testHtmlKey)).value + + val code = s""" + var __ScalaJSEnv = { + javaSystemProperties: ${jsonToString(patchedSystemProperties.toJSON)} + }; + """ + + val patchedSystemPropertiesFile = + new MemVirtualJSFile("setJavaSystemProperties.js").withContent(code) + + // Replace the normal `setJavaSystemProperties.js` file with the patch + for (file <- previousFiles) yield { + if (file.path == "setJavaSystemProperties.js") + patchedSystemPropertiesFile + else + file + } + }, + // Fail if we are not in the right stage. testHtmlKey in Test := (testHtmlKey in Test).dependsOn(Def.task { if (scalaJSStage.value != targetStage) { diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/HTMLRunnerTemplate.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/HTMLRunnerTemplate.scala index d88f60b562..58acfdd60f 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/HTMLRunnerTemplate.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/HTMLRunnerTemplate.scala @@ -20,10 +20,9 @@ import org.scalajs.testadapter.TaskDefSerializers._ /** Template for the HTML runner. */ private[scalajs] object HTMLRunnerTemplate { - def render(baseURI: URI, title: String, sjsFile: URI, jsdepsFile: URI, + def render(baseURI: URI, title: String, jsFiles: Seq[URI], css: URI, loadedFrameworks: Map[sbt.TestFramework, Framework], - definedTests: Seq[sbt.TestDefinition], - sysProps: Map[String, String]): String = { + definedTests: Seq[sbt.TestDefinition]): String = { def relURI(uri: URI) = htmlEscaped(Utils.relativize(baseURI, uri).toASCIIString) @@ -34,13 +33,9 @@ private[scalajs] object HTMLRunnerTemplate { ${htmlEscaped(title)} - - - + ${(for (jsFile <- jsFiles) yield s""" + + """).mkString("")} diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index a9afc9fc4a..1eceb8cc26 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -763,40 +763,64 @@ object ScalaJSPluginInternal { ) private def scalaJSTestHtmlTaskSettings( - testHtmlKey: TaskKey[Attributed[File]], sjsKey: TaskKey[Attributed[File]], - jsdepsKey: TaskKey[File]) = { - testHtmlKey := { - if ((skip in jsdepsKey).value) { - throw new MessageOnlyException( - s"(skip in ${jsdepsKey.key}) must be false for ${testHtmlKey.key}.") - } + testHtmlKey: TaskKey[Attributed[File]], + sjsFileKey: TaskKey[Attributed[File]]) = { + Def.settings( + jsExecutionFiles in testHtmlKey := { + /* Forcefully choose the appropriate Scala.js-generated .js file + * (fastOptJS or fullOptJS). The way we do this is absolutely hacky. + * We find in `inherited` the `VirtualFile` that corresponds to + * `scalaJSLinkedFile.value` (which depends on `scalaJSStage`) and + * replace it with `sjsFileKey` (which does not). Since tasks are + * only evaluated once per command run, we know that + * `scalaJSLinkedFile.value` returns the exact same file (as in `eq`) + * which we will find in `inherited`, hence we can reliably recognize + * the proper and replace it. If we do not find it, we do not touch + * anything. + */ + val inherited = jsExecutionFiles.value + val stageDependentSJSFile = scalaJSLinkedFile.value + val replacementSJSFile = (scalaJSLinkedFile in sjsFileKey).value + for (file <- inherited) yield { + if (file eq stageDependentSJSFile) + replacementSJSFile + else + file + } + }, - val log = streams.value.log - val output = (artifactPath in testHtmlKey).value - - val css: java.io.File = { - val name = "test-runner.css" - val inputStream = getClass.getResourceAsStream(name) - try { - val outFile = (resourceManaged in testHtmlKey).value / name - IO.transfer(inputStream, outFile) - outFile - } finally { - inputStream.close() - } - } + testHtmlKey := { + val log = streams.value.log + val output = (artifactPath in testHtmlKey).value - IO.write(output, HTMLRunnerTemplate.render(output.toURI, - name.value + " - tests", (sjsKey in testHtmlKey).value.data.toURI, - (jsdepsKey in testHtmlKey).value.toURI, css.toURI, - (loadedTestFrameworks in testHtmlKey).value, - (definedTests in testHtmlKey).value, - (scalaJSJavaSystemProperties in testHtmlKey).value)) + val jsFileCache = new VirtualFileMaterializer(true) + val jsFileURIs = (jsExecutionFiles in testHtmlKey).value.map { + case file: FileVirtualFile => file.toURI + case file => jsFileCache.materialize(file).toURI + } - log.info(s"Wrote HTML test runner. Point your browser to ${output.toURI}") + val css: java.io.File = { + val name = "test-runner.css" + val inputStream = getClass.getResourceAsStream(name) + try { + val outFile = (resourceManaged in testHtmlKey).value / name + IO.transfer(inputStream, outFile) + outFile + } finally { + inputStream.close() + } + } - Attributed.blank(output) - } + IO.write(output, HTMLRunnerTemplate.render(output.toURI, + name.value + " - tests", jsFileURIs, css.toURI, + (loadedTestFrameworks in testHtmlKey).value, + (definedTests in testHtmlKey).value)) + + log.info(s"Wrote HTML test runner. Point your browser to ${output.toURI}") + + Attributed.blank(output) + } + ) } val scalaJSTestHtmlSettings = Seq( @@ -807,10 +831,8 @@ object ScalaJSPluginInternal { ((crossTarget in testHtmlFullOpt).value / ((moduleName in testHtmlFullOpt).value + "-opt-test.html")) ) ++ ( - scalaJSTestHtmlTaskSettings(testHtmlFastOpt, fastOptJS, - packageJSDependencies) ++ - scalaJSTestHtmlTaskSettings(testHtmlFullOpt, fullOptJS, - packageMinifiedJSDependencies) + scalaJSTestHtmlTaskSettings(testHtmlFastOpt, fastOptJS) ++ + scalaJSTestHtmlTaskSettings(testHtmlFullOpt, fullOptJS) ) val scalaJSTestSettings = ( From 11efcbd4e6e78b87baae9e909254353e64c8a9f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 13 Apr 2017 11:11:56 +0200 Subject: [PATCH 0220/2665] Restore the test for #2202 (concurrent use of the linker). The previous test had basically been inhibited when we switched the default environment from Rhino to Node.js. Indeed, this caused `loadedJSEnv` not to use the linker itself, but rather depend on the result of `fastOptJS`. The test was therefore not testing anything anymore. We restore this test in a more explicit and robust way, with a custom task to concurrently use the linker of `fullOptJS`, and a dedicated test task to directly depend on the former + `fullOptJS`. We use `fullOptJS` instead of `fastOptJS` because it takes more time, increasing the likelihood of concurrent execution. --- ci/matrix.xml | 1 + sbt-plugin-test/build.sbt | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/ci/matrix.xml b/ci/matrix.xml index 323813d7f0..bf1460b306 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -233,6 +233,7 @@ withDOM/run withDOM/testHtmlFastOpt withDOM/testHtmlFullOpt \ multiTestJS/testHtmlFastOpt multiTestJS/testHtmlFullOpt \ jetty9/run test \ + noDOM/clean noDOM/concurrentUseOfLinkerTest \ jsDependenciesTest/packageJSDependencies \ jsDependenciesTest/packageMinifiedJSDependencies \ jsDependenciesTest/regressionTestForIssue2243 \ diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index f3830fa3f5..ff83c8514a 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -1,5 +1,11 @@ +import org.scalajs.core.tools.io._ import org.scalajs.core.tools.jsdep.ManifestFilters import org.scalajs.jsenv.nodejs.JSDOMNodeJSEnv +import org.scalajs.sbtplugin.ScalaJSPluginInternal._ +import org.scalajs.sbtplugin.Loggers.sbtLogger2ToolsLogger + +lazy val concurrentFakeFullOptJS = taskKey[Any]("") +lazy val concurrentUseOfLinkerTest = taskKey[Any]("") name := "Scala.js sbt test" @@ -56,7 +62,32 @@ lazy val noDOM = project.settings(baseSettings: _*). /* This hopefully exposes concurrent uses of the linker. If it fails/gets * flaky, there is a bug somewhere - #2202 */ - settings(inConfig(Compile)(run <<= run.dependsOn(fastOptJS, loadedJSEnv)): _*) + settings(inConfig(Compile)(Seq( + // A fake fullOptJS that we will run concurrently with the true fullOptJS + concurrentFakeFullOptJS := Def.taskDyn { + val s = (streams in fullOptJS).value + val log = s.log + val ir = (scalaJSIR in fullOptJS).value.data + val moduleInitializers = scalaJSModuleInitializers.value + + Def.task { + log.info("Fake full optimizing") + val linker = (scalaJSLinker in fullOptJS).value + linker.link(ir, moduleInitializers, + WritableMemVirtualJSFile("fake-fastopt.js"), + sbtLogger2ToolsLogger(log)) + }.tag((usesScalaJSLinkerTag in fullOptJS).value) + }.value, + + /* Depend on both fullOptJS and concurrentFakeFullOptJS, so that they + * are hopefully executed in parallel (potentially, but they should be + * blocked from actually doing so by the concurrent restrictions on + * usesScalaJSLinkerTag). + */ + concurrentUseOfLinkerTest := { + (fullOptJS.value, concurrentFakeFullOptJS.value) + } + ))) lazy val withDOM = project.settings(baseSettings: _*). enablePlugins(ScalaJSPlugin). From 291d907264bcdf72ea53790e1eac710c7f095d76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 12 Apr 2017 22:27:03 +0200 Subject: [PATCH 0221/2665] Fix #2875: Remove JSEnv.loadLibs, resolvedJSEnv and loadedJSEnv. We remove `resolvedJSEnv` simply by initializing `jsEnv` by default in the project scope, and using `jsEnv` instead of `resolvedJSEnv`. We remove `loadedJSEnv` by using instead the pair `jsEnv` + `jsExecutionFiles` explicitly. Finally, we can remove `JSEnv.loadLibs`, as it was only useful for `loadedJSEnv`. --- .../scala/org/scalajs/jsenv/AsyncJSEnv.scala | 9 ----- .../scala/org/scalajs/jsenv/ComJSEnv.scala | 9 ----- .../main/scala/org/scalajs/jsenv/JSEnv.scala | 20 ----------- project/Build.scala | 6 ++-- sbt-plugin-test/project/Jetty9Test.scala | 5 +-- .../scalajs/sbtplugin/FrameworkDetector.scala | 5 +-- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 16 ++------- .../sbtplugin/ScalaJSPluginInternal.scala | 33 ++++++++++--------- .../sbttestadapter/ScalaJSFramework.scala | 15 ++++++--- .../sbttestadapter/ScalaJSRunner.scala | 4 +-- 10 files changed, 40 insertions(+), 82 deletions(-) diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSEnv.scala index 9bf05fc5f9..d3893851ea 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSEnv.scala @@ -13,13 +13,4 @@ import org.scalajs.core.tools.io.VirtualJSFile trait AsyncJSEnv extends JSEnv { def asyncRunner(files: Seq[VirtualJSFile]): AsyncJSRunner - - override def loadLibs(libs: Seq[VirtualJSFile]): AsyncJSEnv = - new AsyncLoadedLibs { val loadedLibs = libs } - - private[jsenv] trait AsyncLoadedLibs extends LoadedLibs with AsyncJSEnv { - def asyncRunner(files: Seq[VirtualJSFile]): AsyncJSRunner = { - AsyncJSEnv.this.asyncRunner(loadedLibs ++ files) - } - } } diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/ComJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/ComJSEnv.scala index f6a2345d31..b0fb295730 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/ComJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/ComJSEnv.scala @@ -28,15 +28,6 @@ import org.scalajs.core.tools.io.VirtualJSFile */ trait ComJSEnv extends AsyncJSEnv { def comRunner(files: Seq[VirtualJSFile]): ComJSRunner - - override def loadLibs(libs: Seq[VirtualJSFile]): ComJSEnv = - new ComLoadedLibs { val loadedLibs = libs } - - private[jsenv] trait ComLoadedLibs extends AsyncLoadedLibs with ComJSEnv { - def comRunner(files: Seq[VirtualJSFile]): ComJSRunner = { - ComJSEnv.this.comRunner(loadedLibs ++ files) - } - } } object ComJSEnv { diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala index c4e48ebb7b..9d86183fcf 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala @@ -17,24 +17,4 @@ trait JSEnv { /** Prepare a runner with the specified JavaScript files. */ def jsRunner(files: Seq[VirtualJSFile]): JSRunner - - /** Return this [[JSEnv]] with the given libraries already loaded. - * - * The following two are equivalent: - * {{{ - * jsEnv.loadLibs(a).jsRunner(b) - * jsEnv.jsRunner(a ++ b) - * }}} - */ - def loadLibs(libs: Seq[VirtualJSFile]): JSEnv = - new LoadedLibs { val loadedLibs = libs } - - private[jsenv] trait LoadedLibs extends JSEnv { - val loadedLibs: Seq[VirtualJSFile] - - def name: String = JSEnv.this.name - - def jsRunner(files: Seq[VirtualJSFile]): JSRunner = - JSEnv.this.jsRunner(loadedLibs ++ files) - } } diff --git a/project/Build.scala b/project/Build.scala index f66fc81c96..d2e133bca8 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -636,7 +636,7 @@ object Build { inConfig(Test) { // Redefine test to run Node.js and link HelloWorld test := { - if (!resolvedJSEnv.value.isInstanceOf[NodeJSEnv]) + if (!jsEnv.value.isInstanceOf[NodeJSEnv]) sys.error("toolsJS/test must be run with Node.js") /* Collect IR relevant files from the classpath @@ -696,7 +696,7 @@ object Build { val launcher = new MemVirtualJSFile("Generated launcher file") .withContent(code) - val runner = loadedJSEnv.value.jsRunner(launcher :: Nil) + val runner = jsEnv.value.jsRunner(jsExecutionFiles.value :+ launcher) runner.run(sbtLogger2ToolsLogger(streams.value.log), scalaJSConsole.value) } @@ -1277,7 +1277,7 @@ object Build { "don't know what tags to specify for the test suite") } - val envTags = envTagsFor((resolvedJSEnv in Test).value) + val envTags = envTagsFor((jsEnv in Test).value) val stage = (scalaJSStage in Test).value diff --git a/sbt-plugin-test/project/Jetty9Test.scala b/sbt-plugin-test/project/Jetty9Test.scala index 5a7dbdd389..031bda1546 100644 --- a/sbt-plugin-test/project/Jetty9Test.scala +++ b/sbt-plugin-test/project/Jetty9Test.scala @@ -21,7 +21,8 @@ object Jetty9Test { private val jettyPort = 23548 val runSetting = run <<= Def.inputTask { - val jsEnv = (loadedJSEnv in Compile).value.asInstanceOf[ComJSEnv] + val env = (jsEnv in Compile).value.asInstanceOf[ComJSEnv] + val files = (jsExecutionFiles in Compile).value val jsConsole = scalaJSConsole.value val code = new MemVirtualJSFile("runner.js").withContent( @@ -42,7 +43,7 @@ object Jetty9Test { """ ) - val runner = jsEnv.comRunner(code :: Nil) + val runner = env.comRunner(files :+ code) runner.start(streams.value.log, jsConsole) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala index fcc2c890af..db38db7de7 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala @@ -12,7 +12,8 @@ import org.scalajs.jsenv._ import scala.collection.mutable private[sbtplugin] final class FrameworkDetector(jsEnv: JSEnv, - moduleKind: ModuleKind, moduleIdentifier: Option[String]) { + jsFiles: Seq[VirtualJSFile], moduleKind: ModuleKind, + moduleIdentifier: Option[String]) { import FrameworkDetector._ @@ -67,7 +68,7 @@ private[sbtplugin] final class FrameworkDetector(jsEnv: JSEnv, val vf = new MemVirtualJSFile("frameworkDetector.js").withContent(code) val console = new StoreConsole - val runner = jsEnv.jsRunner(vf :: Nil) + val runner = jsEnv.jsRunner(jsFiles :+ vf) runner.run(logger, console) // Filter jsDependencies unexpected output diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 4f023f1f3e..b94f7d5b2c 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -180,17 +180,8 @@ object ScalaJSPlugin extends AutoPlugin { "The JS console used by the Scala.js runner/tester", DTask) val jsEnv = TaskKey[JSEnv]("jsEnv", - "A JVM-like environment where Scala.js files can be run and tested.", AMinusTask) - - val resolvedJSEnv = TaskKey[JSEnv]("resolvedJSEnv", - "The JSEnv used for execution. This equals the setting of jsEnv or a " + - "reasonable default value if jsEnv is not set.", DTask) - - @deprecated("Use jsEnv instead.", "0.6.6") - val preLinkJSEnv = jsEnv - - @deprecated("Use jsEnv instead.", "0.6.6") - val postLinkJSEnv = jsEnv + "The JavaScript environment in which to run and test Scala.js applications.", + AMinusTask) val requiresDOM = SettingKey[Boolean]("requiresDOM", "Whether this projects needs the DOM. Overrides anything inherited through dependencies.", AMinusSetting) @@ -243,9 +234,6 @@ object ScalaJSPlugin extends AutoPlugin { val scalaJSOptimizerOptions = SettingKey[OptimizerOptions]("scalaJSOptimizerOptions", "All kinds of options for the Scala.js optimizer stages", DSetting) - val loadedJSEnv = TaskKey[JSEnv]("loadedJSEnv", - "A JSEnv already loaded up with library and Scala.js code. Ready to run.", DTask) - /** Prints the content of a .sjsir file in human readable form. */ val scalajsp = InputKey[Unit]("scalajsp", "Prints the content of a .sjsir file in human readable form.", diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 1eceb8cc26..94ec64a65e 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -544,7 +544,7 @@ object ScalaJSPluginInternal { * Since this matches against NodeJSEnv specifically, it obviously * breaks the OO approach, but oh well ... */ - resolvedJSEnv.value match { + jsEnv.value match { case _: org.scalajs.jsenv.nodejs.NodeJSEnv => val libCache = new VirtualFileMaterializer(false) @@ -577,8 +577,6 @@ object ScalaJSPluginInternal { jsDependencyManifests.value.data.exists(_.requiresDOM)) }, - resolvedJSEnv := jsEnv.?.value.getOrElse(new NodeJSEnv()), - scalaJSJavaSystemProperties ++= { val javaSysPropsPattern = "-D([^=]*)=(.*)".r javaOptions.value.map { @@ -610,8 +608,6 @@ object ScalaJSPluginInternal { // Crucially, add the Scala.js linked file to the JS files jsExecutionFiles += scalaJSLinkedFile.value, - loadedJSEnv := resolvedJSEnv.value.loadLibs(jsExecutionFiles.value), - scalaJSModuleIdentifier := Def.taskDyn[Option[String]] { scalaJSModuleKind.value match { case ModuleKind.NoModule => @@ -699,12 +695,13 @@ object ScalaJSPluginInternal { } val log = streams.value.log - val jsEnv = loadedJSEnv.value + val env = jsEnv.value + val files = jsExecutionFiles.value log.info("Running " + mainClass.value.getOrElse("")) - log.debug(s"with JSEnv ${jsEnv.name}") + log.debug(s"with JSEnv ${env.name}") - jsEnv.jsRunner(Nil).run( + env.jsRunner(files).run( sbtLogger2ToolsLogger(log), scalaJSConsole.value) }, @@ -728,29 +725,31 @@ object ScalaJSPluginInternal { val toolsLogger = sbtLogger2ToolsLogger(logger) val frameworks = testFrameworks.value - val jsEnv = loadedJSEnv.value match { - case jsEnv: ComJSEnv => jsEnv + val env = jsEnv.value match { + case env: ComJSEnv => env - case jsEnv => - sys.error(s"You need a ComJSEnv to test (found ${jsEnv.name})") + case env => + sys.error(s"You need a ComJSEnv to test (found ${env.name})") } + val files = jsExecutionFiles.value + val moduleKind = scalaJSModuleKind.value val moduleIdentifier = scalaJSModuleIdentifier.value val detector = - new FrameworkDetector(jsEnv, moduleKind, moduleIdentifier) + new FrameworkDetector(env, files, moduleKind, moduleIdentifier) detector.detect(frameworks, toolsLogger) map { case (tf, name) => - (tf, new ScalaJSFramework(name, jsEnv, moduleKind, moduleIdentifier, - toolsLogger, console)) + (tf, new ScalaJSFramework(name, env, files, moduleKind, + moduleIdentifier, toolsLogger, console)) } }, // Override default to avoid triggering a test:fastOptJS in a test:compile // without loosing autocompletion. definedTestNames := { definedTests.map(_.map(_.name).distinct) - .storeAs(definedTestNames).triggeredBy(loadedJSEnv).value + .storeAs(definedTestNames).triggeredBy(loadedTestFrameworks).value } ) @@ -889,6 +888,8 @@ object ScalaJSPluginInternal { scalaJSUseMainModuleInitializer := false, scalaJSUseMainModuleInitializer in Test := false, + jsEnv := new NodeJSEnv(), + jsExecutionFiles := Nil, jsExecutionFiles in Compile := jsExecutionFiles.value, // Do not inherit jsExecutionFiles in Test from Compile diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala index ef35c7383a..77b9c30db1 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala @@ -22,16 +22,18 @@ import sbt.testing.{Logger => _, _} final class ScalaJSFramework( private[testadapter] val frameworkName: String, - private[testadapter] val libEnv: ComJSEnv, + private val jsEnv: ComJSEnv, + private val jsFiles: Seq[VirtualJSFile], private[testadapter] val moduleKind: ModuleKind, private[testadapter] val moduleIdentifier: Option[String], private[testadapter] val logger: Logger, private[testadapter] val jsConsole: JSConsole ) extends Framework { - def this(frameworkName: String, libEnv: ComJSEnv, logger: Logger, - jsConsole: JSConsole) = { - this(frameworkName, libEnv, ModuleKind.NoModule, None, logger, jsConsole) + def this(frameworkName: String, jsEnv: ComJSEnv, jsFiles: Seq[VirtualJSFile], + logger: Logger, jsConsole: JSConsole) = { + this(frameworkName, jsEnv, jsFiles, ModuleKind.NoModule, None, logger, + jsConsole) } private[this] val frameworkInfo = fetchFrameworkInfo() @@ -57,8 +59,11 @@ final class ScalaJSFramework( private[testadapter] def runDone(): Unit = synchronized(_isRunning = false) + private[testadapter] def newComRunner(files: Seq[VirtualJSFile]): ComJSRunner = + jsEnv.comRunner(jsFiles ++ files) + private def fetchFrameworkInfo() = { - val runner = libEnv.comRunner(frameworkInfoLauncher :: Nil) + val runner = newComRunner(frameworkInfoLauncher :: Nil) runner.start(logger, jsConsole) try { diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala index 9560abf787..8aab91a1cb 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala @@ -177,7 +177,7 @@ final class ScalaJSRunner private[testadapter] ( ensureNotDone() // Launch the slave - val slave = framework.libEnv.comRunner(slaveLauncher :: Nil) + val slave = framework.newComRunner(slaveLauncher :: Nil) slave.start(framework.logger, framework.jsConsole) // Create a runner on the slave @@ -218,7 +218,7 @@ final class ScalaJSRunner private[testadapter] ( private def createRemoteRunner(): Unit = { assert(master == null) - master = framework.libEnv.comRunner(masterLauncher :: Nil) + master = framework.newComRunner(masterLauncher :: Nil) master.start(framework.logger, framework.jsConsole) val data = { From 4ca09896f8e473a39fc5366cf3c8246f8c402b5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 24 Apr 2017 14:42:35 +0200 Subject: [PATCH 0222/2665] Fix some JUnit signatures to take Any instead of AnyRef. A Java method taking an `Object` is seen from Scala as taking an `Any`, not an `AnyRef`. --- .../src/main/scala/org/junit/Assert.scala | 30 +++++++++---------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/junit-runtime/src/main/scala/org/junit/Assert.scala b/junit-runtime/src/main/scala/org/junit/Assert.scala index 592f6587db..febda63d03 100644 --- a/junit-runtime/src/main/scala/org/junit/Assert.scala +++ b/junit-runtime/src/main/scala/org/junit/Assert.scala @@ -55,13 +55,12 @@ object Assert { def assertEquals(expected: Any, actual: Any): Unit = assertEquals(null, expected, actual) - def assertNotEquals(message: String, unexpected: AnyRef, - actual: AnyRef): Unit = { + def assertNotEquals(message: String, unexpected: Any, actual: Any): Unit = { if (equalsRegardingNull(unexpected, actual)) failEquals(message, actual) } - def assertNotEquals(unexpected: AnyRef, actual: AnyRef): Unit = + def assertNotEquals(unexpected: Any, actual: Any): Unit = assertNotEquals(null, unexpected, actual) private def failEquals(message: String, actual: Any): Unit = { @@ -213,39 +212,39 @@ object Assert { def assertEquals(expected: Float, actual: Float, delta: Float): Unit = assertEquals(null, expected, actual, delta) - def assertNotNull(message: String, obj: AnyRef): Unit = + def assertNotNull(message: String, obj: Any): Unit = assertTrue(message, obj != null) - def assertNotNull(obj: AnyRef): Unit = + def assertNotNull(obj: Any): Unit = assertNotNull(null, obj) - def assertNull(message: String, obj: AnyRef): Unit = { + def assertNull(message: String, obj: Any): Unit = { if (obj != null) failNotNull(message, obj) } - def assertNull(obj: AnyRef): Unit = + def assertNull(obj: Any): Unit = assertNull(null, obj) - private def failNotNull(message: String, actual: AnyRef): Unit = { + private def failNotNull(message: String, actual: Any): Unit = { val formatted = if (message != null) message + " " else "" fail(s"${formatted}expected null, but was:<$actual}>") } - def assertSame(message: String, expected: AnyRef, actual: AnyRef): Unit = { - if (expected ne actual) + def assertSame(message: String, expected: Any, actual: Any): Unit = { + if (expected.asInstanceOf[AnyRef] ne actual.asInstanceOf[AnyRef]) failNotSame(message, expected, actual) } - def assertSame(expected: AnyRef, actual: AnyRef): Unit = + def assertSame(expected: Any, actual: Any): Unit = assertSame(null, expected, actual) - def assertNotSame(message: String, unexpected: AnyRef, actual: AnyRef): Unit = { - if (unexpected eq actual) + def assertNotSame(message: String, unexpected: Any, actual: Any): Unit = { + if (unexpected.asInstanceOf[AnyRef] eq actual.asInstanceOf[AnyRef]) failSame(message) } - def assertNotSame(unexpected: AnyRef, actual: AnyRef): Unit = + def assertNotSame(unexpected: Any, actual: Any): Unit = assertNotSame(null, unexpected, actual) private def failSame(message: String): Unit = { @@ -255,8 +254,7 @@ object Assert { fail(s"$message expected not same") } - private def failNotSame(message: String, expected: AnyRef, - actual: AnyRef): Unit = { + private def failNotSame(message: String, expected: Any, actual: Any): Unit = { if (message == null) fail(s"expected same:<$expected> was not:<$actual>") else From 7efa985acfde0a87926d3b736279600403a65ed0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 24 Apr 2017 16:08:23 +0200 Subject: [PATCH 0223/2665] Upgrade to Scala 2.11.11. --- ci/checksizes.sh | 6 +- ci/matrix.xml | 56 +- .../scalajs/2.11.11/BlacklistedTests.txt | 990 +++++ .../scalajs/2.11.11/BuglistedTests.txt | 7 + .../scalajs/2.11.11/WhitelistedTests.txt | 3191 +++++++++++++++++ .../2.11.11/neg/t6446-additional.check | 31 + .../scalajs/2.11.11/neg/t6446-list.check | 2 + .../scalajs/2.11.11/neg/t6446-missing.check | 31 + .../2.11.11/neg/t6446-show-phases.check | 30 + .../2.11.11/neg/t7494-no-options.check | 32 + .../scalajs/2.11.11/run/Course-2002-01.check | 37 + .../scalajs/2.11.11/run/Course-2002-02.check | 187 + .../scalajs/2.11.11/run/Course-2002-04.check | 64 + .../scalajs/2.11.11/run/Course-2002-08.check | 171 + .../scalajs/2.11.11/run/Course-2002-09.check | 50 + .../scalajs/2.11.11/run/Course-2002-10.check | 46 + .../partest/scalajs/2.11.11/run/Meter.check | 16 + .../scalajs/2.11.11/run/MeterCaseClass.check | 16 + .../partest/scalajs/2.11.11/run/bugs.sem | 1 + .../scalajs/2.11.11/run/caseClassHash.check | 9 + .../partest/scalajs/2.11.11/run/deeps.check | 87 + .../2.11.11/run/delambdafy-specialized.check | 1 + .../scalajs/2.11.11/run/dynamic-anyval.check | 4 + .../scalajs/2.11.11/run/impconvtimes.check | 1 + .../partest/scalajs/2.11.11/run/imports.check | 21 + .../scalajs/2.11.11/run/interpolation.check | 32 + .../2.11.11/run/interpolationMultiline1.check | 26 + .../partest/scalajs/2.11.11/run/issue192.sem | 1 + .../2.11.11/run/macro-bundle-static.check | 6 + .../2.11.11/run/macro-bundle-toplevel.check | 6 + .../run/macro-bundle-whitebox-decl.check | 6 + .../partest/scalajs/2.11.11/run/misc.check | 62 + .../scalajs/2.11.11/run/promotion.check | 4 + .../partest/scalajs/2.11.11/run/runtime.check | 70 + .../scalajs/2.11.11/run/spec-self.check | 2 + .../scalajs/2.11.11/run/structural.check | 37 + .../scalajs/2.11.11/run/t0421-new.check | 3 + .../scalajs/2.11.11/run/t0421-old.check | 3 + .../partest/scalajs/2.11.11/run/t1503.sem | 1 + .../partest/scalajs/2.11.11/run/t3702.check | 2 + .../partest/scalajs/2.11.11/run/t4148.sem | 1 + .../partest/scalajs/2.11.11/run/t4617.check | 1 + .../partest/scalajs/2.11.11/run/t5356.check | 6 + .../partest/scalajs/2.11.11/run/t5552.check | 2 + .../partest/scalajs/2.11.11/run/t5568.check | 9 + .../partest/scalajs/2.11.11/run/t5629b.check | 10 + .../partest/scalajs/2.11.11/run/t5680.check | 3 + .../partest/scalajs/2.11.11/run/t5866.check | 2 + .../partest/scalajs/2.11.11/run/t6102.check | 28 + .../2.11.11/run/t6318_primitives.check | 54 + .../partest/scalajs/2.11.11/run/t6662.check | 1 + .../partest/scalajs/2.11.11/run/t7657.check | 3 + .../partest/scalajs/2.11.11/run/t7763.sem | 1 + .../partest/scalajs/2.11.11/run/t8570a.check | 1 + .../partest/scalajs/2.11.11/run/t8764.check | 5 + .../partest/scalajs/2.11.11/run/t9387b.check | 1 + .../scalajs/2.11.11/run/try-catch-unify.check | 4 + .../2.11.11/run/virtpatmat_switch.check | 7 + .../2.11.11/run/virtpatmat_typetag.check | 10 + project/Build.scala | 5 +- sbt-plugin-test/build.sbt | 2 +- .../resources/2.11.11/BlacklistedTests.txt | 96 + .../resources/2.11.11/WhitelistedTests.txt | 27 + .../concurrent/impl/AbstractPromise.scala | 11 + .../scala/reflect/ClassTag.scala | 163 + .../scala/reflect/Manifest.scala | 295 ++ scripts/assemble-cli.sh | 4 +- scripts/build-all-js.sh | 2 +- scripts/publish.sh | 6 +- 69 files changed, 6076 insertions(+), 32 deletions(-) create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/BlacklistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/BuglistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/WhitelistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-additional.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-list.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-missing.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-show-phases.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t7494-no-options.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Course-2002-01.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Course-2002-02.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Course-2002-04.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Course-2002-08.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Course-2002-09.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Course-2002-10.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Meter.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/MeterCaseClass.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/bugs.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/caseClassHash.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/deeps.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/delambdafy-specialized.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/dynamic-anyval.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/impconvtimes.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/imports.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/interpolation.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/interpolationMultiline1.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/issue192.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/macro-bundle-static.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/macro-bundle-toplevel.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/macro-bundle-whitebox-decl.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/misc.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/promotion.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/runtime.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/spec-self.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/structural.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t0421-new.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t0421-old.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t1503.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t3702.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t4148.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t4617.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t5356.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t5552.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t5568.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t5629b.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t5680.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t5866.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t6102.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t6318_primitives.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t6662.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t7657.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t7763.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t8570a.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t8764.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t9387b.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/try-catch-unify.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/virtpatmat_switch.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/virtpatmat_typetag.check create mode 100644 scala-test-suite/src/test/resources/2.11.11/BlacklistedTests.txt create mode 100644 scala-test-suite/src/test/resources/2.11.11/WhitelistedTests.txt create mode 100644 scalalib/overrides-2.11.11/scala/concurrent/impl/AbstractPromise.scala create mode 100644 scalalib/overrides-2.11.11/scala/reflect/ClassTag.scala create mode 100644 scalalib/overrides-2.11.11/scala/reflect/Manifest.scala diff --git a/ci/checksizes.sh b/ci/checksizes.sh index 02ca9c3f08..93b201868b 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -8,13 +8,13 @@ case $FULLVER in 2.10.2) VER=2.10 ;; - 2.11.8) + 2.11.11) VER=2.11 ;; 2.12.1) VER=2.12 ;; - 2.10.3|2.10.4|2.10.5|2.10.6|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7|2.12.0) + 2.10.3|2.10.4|2.10.5|2.10.6|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7|2.11.8|2.12.0) echo "Ignoring checksizes for Scala $FULLVER" exit 0 ;; @@ -39,7 +39,7 @@ case $FULLVER in REVERSI_PREOPT_GZ_EXPECTEDSIZE=71000 REVERSI_OPT_GZ_EXPECTEDSIZE=31000 ;; - 2.11.8) + 2.11.11) REVERSI_PREOPT_EXPECTEDSIZE=527000 REVERSI_OPT_EXPECTEDSIZE=121000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=71000 diff --git a/ci/matrix.xml b/ci/matrix.xml index 9878d0421e..ccea763fa3 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -261,9 +261,9 @@ 1.8 - 2.11.8 + 2.11.11 1.6 - 2.11.8 + 2.11.11 1.7 - 2.11.8 + 2.11.11 1.8 @@ -332,7 +332,7 @@ testSuite - 2.11.8 + 2.11.11 1.8 testSuite @@ -344,7 +344,7 @@ - 2.11.8 + 2.11.11 1.8 scalaTestSuite @@ -361,7 +361,7 @@ testSuite - 2.11.8 + 2.11.11 1.8 testSuite @@ -373,7 +373,7 @@ - 2.11.8 + 2.11.11 1.8 scalaTestSuite @@ -389,7 +389,7 @@ 1.8 - 2.11.8 + 2.11.11 1.8 @@ -412,11 +412,11 @@ - 2.11.8 + 2.11.11 1.7 - 2.11.8 + 2.11.11 1.8 @@ -432,7 +432,7 @@ - 2.11.8 + 2.11.11 1.7 @@ -491,6 +491,10 @@ 2.11.7 1.8 + + 2.11.8 + 1.8 + 2.12.0 1.8 @@ -508,12 +512,12 @@ testSuite - 2.11.8 + 2.11.11 1.6 testSuite - 2.11.8 + 2.11.11 1.7 testSuite @@ -530,23 +534,23 @@ testSuite - 2.11.8 + 2.11.11 1.6 testSuite - 2.11.8 + 2.11.11 1.7 testSuite - 2.11.8 + 2.11.11 1.7 - 2.11.8 + 2.11.11 1.7 @@ -659,6 +663,18 @@ 2.11.8 1.8 + + 2.11.11 + 1.8 + + + 2.11.11 + 1.8 + + + 2.11.11 + 1.8 + 2.12.0 1.8 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/BlacklistedTests.txt new file mode 100644 index 0000000000..83eb479975 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/BlacklistedTests.txt @@ -0,0 +1,990 @@ +# +# POS +# + +# Using Jsoup, what's that? +pos/cycle-jsoup.scala + +# Using scala.actors +pos/t533.scala +pos/functions.scala +pos/MailBox.scala + +# Kills our IR serializer, it's an artificially super-deep if/else if +pos/t9181.scala + +# +# NEG +# + +# Screws up, but not really our problem (error: None.get instead of +# phase ordering error) +neg/t7494-multi-right-after +neg/t7494-right-after-before +neg/t7622-multi-followers +neg/t7622-cyclic-dependency + +# Uses some strange macro cross compile mechanism. +neg/macro-incompatible-macro-engine-c.scala + +# Uses .java files +neg/t6289 + +# +# RUN +# + +# Relies on the exact toString() representation of Floats/Doubles +run/t2378.scala + +# Uses ClassTags on existentials which are broken in Scala (see #251) +run/valueclasses-classtag-existential.scala + +# Relies on a particular execution speed +run/t5857.scala + +# Using parts of the javalib we don't plan to support + +run/t5018.scala +run/t2417.scala +run/t4813.scala +run/lazy-concurrent.scala +run/t3667.scala +run/t3038d.scala +run/shutdownhooks.scala +run/t5590.scala +run/t3895b.scala +run/t5974.scala +run/hashset.scala +run/t5262.scala +run/t5293.scala +run/t5293-map.scala +run/serialize-stream.scala +run/sysprops.scala +run/lambda-serialization-gc.scala + +run/t2849.scala +run/t1360.scala +run/t6114.scala +run/t3199b.scala +run/t8690.scala + +run/various-flat-classpath-types.scala + +# Uses java.util.Collections +run/t2250.scala + +# Used java.io.ObjectInputStream +run/t9365.scala +run/t9375.scala + +# Uses java.math.BigDecimal / BigInteger : but failures not due to them +run/hashhash.scala +run/is-valid-num.scala +run/stringinterpolation_macro-run.scala + +# Documented semantic difference on String.split(x: Array[Char]) +run/t0325.scala + +# Using Threads +run/t6969.scala +run/inner-obj-auto.scala +run/predef-cycle.scala +run/synchronized.scala + +# Uses java.security +run/t2318.scala + +# Tries to catch java.lang.StackOverflowError +run/t6154.scala +run/t9841.scala + +# Tries to catch java.lang.OutOfMemoryError +run/t7880.scala + +# Taking too much time, because JavaScript is not as fast as the JVM + +run/t3822.scala +run/collections.scala +run/t3989.scala +run/adding-growing-set.scala +run/t3242.scala +run/hashCodeDistribution.scala +run/t408.scala +run/t6584.scala +run/t6853.scala +run/UnrolledBuffer.scala +run/t6253a.scala +run/t6253b.scala +run/t6253c.scala +run/numbereq.scala +run/t4658.scala + +# Crashes Rhino + +run/bridges.scala +run/patmat-exprs.scala + +# Using partest properties + +run/tailcalls.scala +run/t4294.scala +run/t6331b.scala + +# Using IO + +run/t6488.scala +run/t6988.scala + +# Object{Output|Input}Streams +run/t6935.scala +run/t8188.scala + +# Using System.getProperties + +run/t4426.scala + +# Using Await + +run/t7336.scala +run/t7775.scala +run/future-flatmap-exec-count.scala + +# Using detailed stack trace + +run/t6308.scala + +# Using reflection + +run/t720.scala +run/t6063 + +run/mixin-bridge-methods.scala +run/t5125.scala +run/outertest.scala +run/t6223.scala +run/t5652b +run/elidable-opt.scala +run/nullable-lazyvals.scala +run/t4794.scala +run/t5652 +run/t5652c +run/getClassTest-old.scala +run/t8960.scala +run/t7965.scala +run/t8087.scala +run/t8931.scala +run/delambdafyLambdaClassNames +run/t8445.scala +run/lambda-serialization.scala + +run/reflection-repl-classes.scala +run/t5256e.scala +run/typetags_core.scala +run/reflection-constructormirror-toplevel-badpath.scala +run/t5276_1b.scala +run/reflection-sorted-decls.scala +run/toolbox_typecheck_implicitsdisabled.scala +run/t5418b.scala +run/toolbox_typecheck_macrosdisabled2.scala +run/abstypetags_serialize.scala +run/all-overridden.scala +run/showraw_tree_kinds.scala +run/showraw_tree_types_ids.scala +run/showraw_tree_types_typed.scala +run/showraw_tree_ids.scala +run/showraw_tree_ultimate.scala +run/t5266_2.scala +run/t5274_1.scala +run/t5224.scala +run/reflection-sanitychecks.scala +run/t6086-vanilla.scala +run/t5277_2.scala +run/reflection-methodsymbol-params.scala +run/reflection-valueclasses-standard.scala +run/t5274_2.scala +run/t5423.scala +run/reflection-modulemirror-toplevel-good.scala +run/t5419.scala +run/t5271_3.scala +run/reflection-enclosed-nested-basic.scala +run/reflection-enclosed-nested-nested-basic.scala +run/fail-non-value-types.scala +run/exprs_serialize.scala +run/t5258a.scala +run/typetags_without_scala_reflect_manifest_lookup.scala +run/t4110-new.scala +run/t5273_2b_newpatmat.scala +run/t6277.scala +run/t5335.scala +run/toolbox_typecheck_macrosdisabled.scala +run/reflection-modulemirror-inner-good.scala +run/t5229_2.scala +run/typetags_multi.scala +run/typetags_without_scala_reflect_typetag_manifest_interop.scala +run/reflection-constructormirror-toplevel-good.scala +run/reflection-magicsymbols-invoke.scala +run/t6392b.scala +run/t5229_1.scala +run/reflection-magicsymbols-vanilla.scala +run/t5225_2.scala +run/origins.scala +run/runtimeEval1.scala +run/reflection-implClass.scala +run/reflection-enclosed-nested-inner-basic.scala +run/reflection-fieldmirror-ctorparam.scala +run/t6181.scala +run/reflection-magicsymbols-repl.scala +run/t5272_2_newpatmat.scala +run/t5270.scala +run/t5418a.scala +run/t5276_2b.scala +run/t5256f.scala +run/reflection-enclosed-basic.scala +run/reflection-constructormirror-inner-badpath.scala +run/interop_typetags_are_manifests.scala +run/newTags.scala +run/t5273_1_newpatmat.scala +run/reflection-constructormirror-nested-good.scala +run/t2236-new.scala +run/existentials3-new.scala +run/t6323b.scala +run/t5943a1.scala +run/reflection-fieldmirror-getsetval.scala +run/t5272_1_oldpatmat.scala +run/t5256h.scala +run/t1195-new.scala +run/t5840.scala +run/reflection-methodsymbol-returntype.scala +run/reflection-fieldmirror-accessorsareokay.scala +run/reflection-sorted-members.scala +run/reflection-allmirrors-tostring.scala +run/valueclasses-typetag-existential.scala +run/toolbox_console_reporter.scala +run/reflection-enclosed-inner-inner-basic.scala +run/t5256b.scala +run/bytecodecs.scala +run/elidable.scala +run/freetypes_false_alarm1.scala +run/freetypes_false_alarm2.scala +run/getClassTest-new.scala +run/idempotency-extractors.scala +run/idempotency-case-classes.scala +run/idempotency-this.scala +run/idempotency-labels.scala +run/idempotency-lazy-vals.scala +run/interop_manifests_are_abstypetags.scala +run/interop_manifests_are_typetags.scala +run/abstypetags_core.scala +run/macro-reify-abstypetag-notypeparams +run/macro-reify-abstypetag-typeparams-tags +run/macro-reify-abstypetag-typeparams-notags +run/macro-reify-abstypetag-usetypetag +run/macro-reify-freevars +run/macro-reify-splice-outside-reify +run/macro-reify-tagless-a +run/macro-reify-type +run/macro-reify-typetag-typeparams-tags +run/macro-reify-typetag-notypeparams +run/macro-undetparams-implicitval +run/manifests-new.scala +run/manifests-old.scala +run/no-pickle-skolems +run/position-val-def.scala +run/reflect-priv-ctor.scala +run/primitive-sigs-2-new.scala +run/primitive-sigs-2-old.scala +run/reflection-enclosed-inner-basic.scala +run/reflection-enclosed-inner-nested-basic.scala +run/reflection-constructormirror-inner-good.scala +run/reflection-constructormirror-nested-badpath.scala +run/reflection-fancy-java-classes +run/reflection-fieldsymbol-navigation.scala +run/reflection-fieldmirror-nmelocalsuffixstring.scala +run/reflection-fieldmirror-getsetvar.scala +run/reflection-fieldmirror-privatethis.scala +run/reflection-implicit.scala +run/reflection-mem-glbs.scala +run/reflection-mem-tags.scala +run/reflection-java-annotations +run/reflection-java-crtp +run/reflection-methodsymbol-typeparams.scala +run/reflection-modulemirror-nested-badpath.scala +run/reflection-modulemirror-inner-badpath.scala +run/reflection-modulemirror-nested-good.scala +run/reflection-modulemirror-toplevel-badpath.scala +run/reflection-sync-subtypes.scala +run/reflinit.scala +run/reflection-valueclasses-derived.scala +run/reflection-valueclasses-magic.scala +run/resetattrs-this.scala +run/runtimeEval2.scala +run/showraw_aliases.scala +run/showraw_mods.scala +run/shortClass.scala +run/showraw_nosymbol.scala +run/showraw_tree.scala +run/showraw_tree_types_untyped.scala +run/t1167.scala +run/t2577.scala +run/t2873.scala +run/t2886.scala +run/t2251b.scala +run/t3346j.scala +run/t3507-new.scala +run/t3569.scala +run/t5125b.scala +run/t5225_1.scala +run/t3425b +run/t5256a.scala +run/t5230.scala +run/t5256c.scala +run/t5256g.scala +run/t5266_1.scala +run/t5269.scala +run/t5271_1.scala +run/t5271_2.scala +run/t5271_4.scala +run/t5272_1_newpatmat.scala +run/t5272_2_oldpatmat.scala +run/t5273_1_oldpatmat.scala +run/t5273_2a_newpatmat.scala +run/t5273_2a_oldpatmat.scala +run/t5275.scala +run/t5276_1a.scala +run/t5276_2a.scala +run/t5277_1.scala +run/t5279.scala +run/t5334_1.scala +run/t5334_2.scala +run/t5415.scala +run/t5418.scala +run/t5676.scala +run/t5704.scala +run/t5710-1.scala +run/t5710-2.scala +run/t5770.scala +run/t5894.scala +run/t5816.scala +run/t5824.scala +run/t5912.scala +run/t5942.scala +run/t5943a2.scala +run/t6023.scala +run/t6113.scala +run/t6175.scala +run/t6178.scala +run/t6199-mirror.scala +run/t6199-toolbox.scala +run/t6240-universe-code-gen.scala +run/t6221 +run/t6260b.scala +run/t6259.scala +run/t6287.scala +run/t6344.scala +run/t6392a.scala +run/t6591_1.scala +run/t6591_2.scala +run/t6591_3.scala +run/t6591_5.scala +run/t6591_6.scala +run/t6591_7.scala +run/t6608.scala +run/t6677.scala +run/t6687.scala +run/t6715.scala +run/t6719.scala +run/t6793.scala +run/t6860.scala +run/t6793b.scala +run/t6793c.scala +run/t7045.scala +run/t7046.scala +run/t7008-scala-defined +run/t7120b.scala +run/t7151.scala +run/t7214.scala +run/t7235.scala +run/t7331a.scala +run/t7331b.scala +run/t7331c.scala +run/t7558.scala +run/t7556 +run/t7779.scala +run/t7868b.scala +run/toolbox_current_run_compiles.scala +run/toolbox_default_reporter_is_silent.scala +run/toolbox_expand_macro.scala +run/toolbox_parse_package.scala +run/toolbox_silent_reporter.scala +run/toolbox_typecheck_inferimplicitvalue.scala +run/trait-renaming +run/typetags_serialize.scala +run/valueclasses-typetag-basic.scala +run/WeakHashSetTest.scala +run/valueclasses-typetag-generic.scala +run/t4023.scala +run/t4024.scala +run/t6380.scala +run/t5273_2b_oldpatmat.scala +run/t8104 +run/t8047.scala +run/t6992 +run/var-arity-class-symbol.scala +run/typetags_symbolof_x.scala +run/typecheck +run/t8190.scala +run/t8192 +run/t8177f.scala +run/t8199.scala +run/t7932.scala +run/t7700.scala +run/t7570c.scala +run/t7570b.scala +run/t7533.scala +run/t7570a.scala +run/t7044 +run/t7328.scala +run/t6733.scala +run/t6554.scala +run/t6732.scala +run/t6379 +run/t6411b.scala +run/t6411a.scala +run/t6260c.scala +run/t6260-delambdafy.scala +run/showdecl +run/reflection-sync-potpourri.scala +run/reflection-tags.scala +run/reflection-companiontype.scala +run/reflection-scala-annotations.scala +run/reflection-idtc.scala +run/macro-reify-nested-b2 +run/mixin-signatures.scala +run/reflection-companion.scala +run/macro-reify-nested-b1 +run/macro-reify-nested-a2 +run/macro-reify-nested-a1 +run/macro-reify-chained2 +run/macro-reify-chained1 +run/inferred-type-constructors.scala +run/mirror_symbolof_x.scala +run/t8196.scala +run/t8549b.scala +run/t8574.scala +run/t8549.scala +run/t8637.scala +run/t8253.scala +run/t9027.scala +run/t6622.scala +run/toolbox-varargs +run/t9252.scala +run/t9182.scala +run/t9102.scala +run/t9388-bin-compat.scala + +run/reify_newimpl_29.scala +run/reify_magicsymbols.scala +run/reify_inheritance.scala +run/reify_newimpl_12.scala +run/reify_typerefs_2b.scala +run/reify_csv.scala +run/reify_inner2.scala +run/reify_maps_oldpatmat.scala +run/reify_newimpl_43.scala +run/reify_nested_inner_refers_to_local.scala +run/reify_closure7.scala +run/reify_closure8b.scala +run/reify_typerefs_3b.scala +run/reify_newimpl_44.scala +run/reify_newimpl_06.scala +run/reify_newimpl_05.scala +run/reify_newimpl_20.scala +run/reify_newimpl_23.scala +run/reify_metalevel_breach_-1_refers_to_1.scala +run/reify_newimpl_41.scala +run/reify-repl-fail-gracefully.scala +run/reify_fors_oldpatmat.scala +run/reify_inner3.scala +run/reify_closure8a.scala +run/reify_closures10.scala +run/reify_ann2a.scala +run/reify_newimpl_51.scala +run/reify_newimpl_47.scala +run/reify_extendbuiltins.scala +run/reify_newimpl_30.scala +run/reify_newimpl_38.scala +run/reify_closure2a.scala +run/reify_newimpl_45.scala +run/reify_closure1.scala +run/reify_generic2.scala +run/reify_printf.scala +run/reify_closure6.scala +run/reify_newimpl_37.scala +run/reify_newimpl_35.scala +run/reify_typerefs_3a.scala +run/reify_newimpl_25.scala +run/reify_ann4.scala +run/reify_typerefs_1b.scala +run/reify_newimpl_22.scala +run/reify_this.scala +run/reify_typerefs_2a.scala +run/reify_newimpl_03.scala +run/reify_newimpl_48.scala +run/reify_varargs.scala +run/reify_newimpl_42.scala +run/reify_newimpl_15.scala +run/reify_nested_inner_refers_to_global.scala +run/reify_newimpl_02.scala +run/reify_newimpl_01.scala +run/reify_fors_newpatmat.scala +run/reify_classfileann_a.scala +run/reify_nested_outer_refers_to_local.scala +run/reify_newimpl_13.scala +run/reify_closure5a.scala +run/reify_inner4.scala +run/reify_sort.scala +run/reify_ann1a.scala +run/reify_classfileann_b.scala +run/reify_closure4a.scala +run/reify_newimpl_33.scala +run/reify_sort1.scala +run/reify_properties.scala +run/reify_generic.scala +run/reify_newimpl_27.scala +run/reify-aliases.scala +run/reify_ann3.scala +run/reify-staticXXX.scala +run/reify_ann1b.scala +run/reify_ann5.scala +run/reify_anonymous.scala +run/reify-each-node-type.scala +run/reify_copypaste2.scala +run/reify_closure3a.scala +run/reify_copypaste1.scala +run/reify_complex.scala +run/reify_for1.scala +run/reify_getter.scala +run/reify_implicits-new.scala +run/reify_inner1.scala +run/reify_implicits-old.scala +run/reify_lazyunit.scala +run/reify_lazyevaluation.scala +run/reify_maps_newpatmat.scala +run/reify_metalevel_breach_+0_refers_to_1.scala +run/reify_metalevel_breach_-1_refers_to_0_a.scala +run/reify_metalevel_breach_-1_refers_to_0_b.scala +run/reify_nested_outer_refers_to_global.scala +run/reify_newimpl_04.scala +run/reify_newimpl_14.scala +run/reify_newimpl_11.scala +run/reify_newimpl_18.scala +run/reify_newimpl_19.scala +run/reify_newimpl_31.scala +run/reify_newimpl_21.scala +run/reify_newimpl_36.scala +run/reify_newimpl_39.scala +run/reify_newimpl_40.scala +run/reify_newimpl_49.scala +run/reify_newimpl_50.scala +run/reify_newimpl_52.scala +run/reify_renamed_term_basic.scala +run/reify_renamed_term_local_to_reifee.scala +run/reify_renamed_term_overloaded_method.scala +run/reify_renamed_type_basic.scala +run/reify_renamed_type_local_to_reifee.scala +run/reify_renamed_type_spliceable.scala +run/reify_typerefs_1a.scala +run/reify_timeofday.scala +run/reify_renamed_term_t5841.scala + +run/inferred-type-constructors-hou.scala + +# Uses refletction indirectly through +# scala.runtime.ScalaRunTime.replStringOf +run/t6634.scala + +# Using reflection to invoke macros. These tests actually don't require +# or test reflection, but use it to separate compilation units nicely. +# It's a pity we cannot use them + +run/macro-abort-fresh +run/macro-expand-varargs-explicit-over-nonvarargs-bad +run/macro-invalidret-doesnt-conform-to-def-rettype +run/macro-invalidret-nontypeable +run/macro-invalidusage-badret +run/macro-invalidusage-partialapplication +run/macro-invalidusage-partialapplication-with-tparams +run/macro-reflective-ma-normal-mdmi +run/macro-reflective-mamd-normal-mi + +# Using macros, but indirectly creating calls to reflection +run/macro-reify-unreify + +# Using Enumeration in a way we cannot fix + +run/enums.scala +run/t3719.scala +run/t8611b.scala + +# Exceptions that become JavaScriptException + +run/pf-catch.scala +run/exceptions-2.scala +run/exceptions-nest.scala +run/t8601c.scala +run/t8601b.scala + +# Expecting unsupported exceptions (e.g. ArrayIndexOutOfBounds) +run/optimizer-array-load.scala +run/t8601.scala + +# Playing with classfile format + +run/classfile-format-51.scala +run/classfile-format-52.scala + +# Concurrent collections (TrieMap) +# has too much stuff implemented in *.java, so no support +run/triemap-hash.scala + +# Using parallel collections + +run/t5375.scala +run/t4894.scala +run/ctries-new +run/collection-conversions.scala +run/concurrent-map-conversions.scala +run/t4761.scala +run/concurrent-stream.scala +run/t7498.scala +run/t6448.scala +run/ctries-old +run/map_java_conversions.scala +run/parmap-ops.scala +run/pc-conversions.scala +run/t4459.scala +run/t4608.scala +run/t4723.scala +run/t4895.scala +run/t6052.scala +run/t6410.scala +run/t6467.scala +run/t6908.scala + +# Using scala.xml + +run/t4124.scala + +# Using Swing + +run/t3613.scala + +# Using the REPL + +run/t4285.scala +run/constant-type.scala +run/repl-bare-expr.scala +run/repl-parens.scala +run/repl-assign.scala +run/t5583.scala +run/treePrint.scala +run/constrained-types.scala +run/repl-power.scala +run/t4710.scala +run/repl-paste.scala +run/repl-reset.scala +run/repl-paste-3.scala +run/t6329_repl.scala +run/t6273.scala +run/repl-paste-2.scala +run/t5655.scala +run/t5072.scala +run/repl-colon-type.scala +run/kind-repl-command.scala +run/repl-trim-stack-trace.scala +run/t4594-repl-settings.scala +run/repl-save.scala +run/repl-paste-raw.scala +run/repl-paste-4.scala +run/repl-paste-5.scala +run/t7801.scala +run/repl-backticks.scala +run/t6633.scala + +# Using the Repl (scala.tools.partest.ReplTest) +run/class-symbol-contravariant.scala +run/lub-visibility.scala +run/macro-bundle-repl.scala +run/macro-repl-basic.scala +run/macro-repl-dontexpand.scala +run/macro-system-properties.scala +run/reflection-equality.scala +run/reflection-repl-elementary.scala +run/reify_newimpl_26.scala +run/repl-javap-app.scala +run/repl-out-dir.scala +run/repl-term-macros.scala +run/repl-transcript.scala +run/repl-type-verbose.scala +run/t3376.scala +run/t4025.scala +run/t4172.scala +run/t4216.scala +run/t4542.scala +run/t4671.scala +run/t5256d.scala +run/t5535.scala +run/t5537.scala +run/t5789.scala +run/t6086-repl.scala +run/t6146b.scala +run/t6187.scala +run/t6320.scala +run/t6381.scala +run/t6434.scala +run/t6439.scala +run/t6507.scala +run/t6549.scala +run/t6937.scala +run/t7185.scala +run/t7319.scala +run/t7482a.scala +run/t7634.scala +run/t7747-repl.scala +run/t7805-repl-i.scala +run/tpeCache-tyconCache.scala +run/repl-empty-package +run/repl-javap-def.scala +run/repl-javap-fun.scala +run/repl-javap-mem.scala +run/repl-javap-memfun.scala +run/repl-javap-more-fun.scala +run/repl-javap-outdir +run/repl-javap.scala +run/repl-javap-outdir-funs +run/t6329_repl_bug.scala +run/t4950.scala +run/xMigration.scala +run/t6541-option.scala +run/repl-serialization.scala +run/repl-paste-6.scala +run/repl-no-uescape.scala +run/repl-classbased.scala +run/repl-paste-parse.scala + +# Using Scala Script (partest.ScriptTest) + +run/t7711-script-args.scala +run/t4625.scala +run/t4625b.scala +run/t4625c.scala + +# Using the compiler API + +run/t2512.scala +run/analyzerPlugins.scala +run/test-cpp.scala +run/compiler-asSeenFrom.scala +run/t5603.scala +run/t6440.scala +run/t5545.scala +run/existentials-in-compiler.scala +run/global-showdef.scala +run/inline-ex-handlers.scala +run/stream_length.scala +run/annotatedRetyping.scala +run/imain.scala +run/existential-rangepos.scala +run/delambdafy_uncurry_byname_inline.scala +run/delambdafy_uncurry_byname_method.scala +run/delambdafy_uncurry_inline.scala +run/delambdafy_t6555.scala +run/delambdafy_uncurry_method.scala +run/delambdafy_t6028.scala +run/memberpos.scala +run/programmatic-main.scala +run/reflection-names.scala +run/settings-parse.scala +run/sm-interpolator.scala +run/t1501.scala +run/t1500.scala +run/sammy_java8.scala +run/t1618.scala +run/t2464 +run/t4072.scala +run/t5064.scala +run/t5313.scala +run/t5385.scala +run/t5699.scala +run/t5717.scala +run/t5940.scala +run/t6028.scala +run/t6194.scala +run/t6288b-jump-position.scala +run/t6669.scala +run/t6745-2.scala +run/t6955.scala +run/t6956.scala +run/t7096.scala +run/t7271.scala +run/t7337.scala +run/t7398.scala +run/t7569.scala +run/t7852.scala +run/t7817-tree-gen.scala +run/t7825.scala + +# partest.ParserTest +run/t3368.scala +run/t3368-b.scala +run/t3368-c.scala +run/t3368-d.scala + +# partest.DirectTest +run/t6288.scala +run/t6331.scala +run/t6440b.scala +run/t6555.scala +run/t7876.scala +run/typetags_without_scala_reflect_typetag_lookup.scala +run/dynamic-updateDynamic.scala +run/dynamic-selectDynamic.scala +run/dynamic-applyDynamic.scala +run/dynamic-applyDynamicNamed.scala +run/t4841-isolate-plugins +run/large_code.scala +run/macroPlugins-namerHooks.scala +run/t4287inferredMethodTypes.scala +run/t4841-no-plugin.scala +run/t4332.scala +run/t8029.scala +run/t8046 +run/t5905-features.scala +run/t5905b-features.scala +run/large_class.scala +run/t8708_b +run/icode-reader-dead-code.scala +run/t5938.scala +run/t8502.scala +run/t6502.scala +run/t8907.scala +run/t9097.scala +run/macroPlugins-enterStats.scala +run/sbt-icode-interface.scala + +# Using partest.StoreReporterDirectTest +run/t8502b.scala + +# partest.StubErrorMessageTest +run/StubErrorBInheritsFromA.scala +run/StubErrorComplexInnerClass.scala +run/StubErrorHK.scala +run/StubErrorReturnTypeFunction.scala +run/StubErrorReturnTypeFunction2.scala +run/StubErrorReturnTypePolyFunction.scala +run/StubErrorSubclasses.scala +run/StubErrorTypeclass.scala +run/StubErrorTypeDef.scala + +# partest.CompilerTest +run/t8852a.scala + +# partest.BytecodeTest +run/t6546 +run/t7106 +run/t7974 +run/t8601-closure-elim.scala +run/t4788 +run/t4788-separate-compilation +run/t9403 + +# partest.SessionTest +run/t1931.scala +run/t8843-repl-xlat.scala +run/t9206.scala +run/t9170.scala + +# partest.JavapTest +run/t8608-no-format.scala +run/repl-javap-lambdas.scala + +# Using .java source files + +run/t4317 +run/t4238 +run/t2296c +run/t4119 +run/t4283 +run/t4891 +run/t6168 +run/t6168b +run/t6240a +run/t6240b +run/t6548 +run/t6989 +run/t7008 +run/t7246 +run/t7246b +run/t7359 +run/t7439 +run/t7455 +run/t7510 +run/t7582-private-within +run/t7582 +run/t7582b +run/t3897 +run/t7374 +run/t3452e +run/t3452g +run/t3452d +run/t3452b-bcode +run/t3452b +run/t3452a +run/t1430 +run/t4729 +run/t8442 +run/t8601e +run/t9298 +run/t9298b +run/t9359 +run/t7741a +run/t7741b +run/bcodeInlinerMixed +run/t9268 +run/t1459 +run/t1459generic +run/t3236 +run/t9013 + +# Using scalap +run/scalapInvokedynamic.scala + +# Using scala-script +run/t7791-script-linenums.scala + +# Suffers from bug in Node.js (https://github.com/joyent/node/issues/7528) +run/range-unit.scala + +# Using Manifests (which use Class.getInterfaces) +run/valueclasses-manifest-existential.scala +run/existentials3-old.scala +run/t2236-old.scala +run/interop_manifests_are_classtags.scala +run/valueclasses-manifest-generic.scala +run/valueclasses-manifest-basic.scala +run/t1195-old.scala +run/t3758-old.scala +run/t4110-old.scala +run/t6246.scala + +# Using ScalaRunTime.stringOf +run/value-class-extractor-seq.scala +run/t3493.scala + +# Using Class.forName +run/private-inline.scala + +### Incorrect partests ### +# Badly uses constract of Console.print (no flush) +run/t429.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/BuglistedTests.txt new file mode 100644 index 0000000000..273cb2c2d4 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/BuglistedTests.txt @@ -0,0 +1,7 @@ +# The tests in this file should pass but have never passed so far +# use scala.tools.partest.scalajs.testunknownonly to only run tests +# which are neither in BuglistedTests.txt, WhitelistedTests.txt or +# BlacklistedTests.txt + +# Broken by GCC, filed as #2815 +run/Predef.readLine.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/WhitelistedTests.txt new file mode 100644 index 0000000000..5a0c686987 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/WhitelistedTests.txt @@ -0,0 +1,3191 @@ +pos/spec-super.scala +pos/t1035.scala +pos/t5897.scala +pos/irrefutable.scala +pos/spec-partialmap.scala +pos/tcpoly_seq.scala +pos/partialfun.scala +pos/t2795-new.scala +pos/clsrefine.scala +pos/t0774 +pos/t1070.scala +pos/t5957 +pos/looping-jsig.scala +pos/t3274.scala +pos/spec-fields-old.scala +pos/t262.scala +pos/t7486.scala +pos/t2261.scala +pos/t6600.scala +pos/t4786.scala +pos/t5406.scala +pos/tcpoly_late_method_params.scala +pos/t2726 +pos/pos-bug1210.scala +pos/t3312.scala +pos/manifest1-old.scala +pos/gadt-gilles.scala +pos/t4842.scala +pos/ted.scala +pos/NoCyclicReference.scala +pos/t3568.scala +pos/t0030.scala +pos/t2635.scala +pos/t7232b +pos/t0017.scala +pos/t812.scala +pos/t2179.scala +pos/t651.scala +pos/spurious-overload.scala +pos/t758.scala +pos/t4760.scala +pos/t1672.scala +pos/mixins.scala +pos/patterns.scala +pos/t1260.scala +pos/t6551.scala +pos/t2060.scala +pos/t6575a.scala +pos/t1318.scala +pos/t4266.scala +pos/t0695 +pos/protected-static +pos/t5738.scala +pos/t1226.scala +pos/t5013 +pos/t6215.scala +pos/t5692b +pos/traits.scala +pos/t2994a.scala +pos/t3371.scala +pos/t613.scala +pos/t6499.scala +pos/xlint1.scala +pos/t1150 +pos/sealed-final.scala +pos/test4a.scala +pos/t2664.scala +pos/t3528.scala +pos/t3174.scala +pos/t6994.scala +pos/t4812.scala +pos/t5777.scala +pos/t5223.scala +pos/t439.scala +pos/t3079.scala +pos/t5829.scala +pos/t0036.scala +pos/scoping2.scala +pos/t4717.scala +pos/t4257.scala +pos/t1210a.scala +pos/getClassType.scala +pos/t5330.scala +pos/t4524.scala +pos/t2945.scala +pos/t6562.scala +pos/t0273.scala +pos/override-object-yes.scala +pos/t7426.scala +pos/t6601 +pos/t3076 +pos/seq-ordering.scala +pos/spec-groups.scala +pos/t296.scala +pos/t5545 +pos/spec-multiplectors.scala +pos/t1789.scala +pos/t2569 +pos/ksbug1.scala +pos/t0599.scala +pos/local-objects.scala +pos/t0081.scala +pos/t5756.scala +pos/t7126.scala +pos/t7716.scala +pos/t2797.scala +pos/t5399.scala +pos/t1101 +pos/t767.scala +pos/contrib467.scala +pos/t7532b +pos/self-type-override.scala +pos/t4853.scala +pos/t839.scala +pos/t5644 +pos/t5853.scala +pos/t5178.scala +pos/unapplyNeedsMemberType.scala +pos/t5390.scala +pos/t6575b.scala +pos/t151.scala +pos/t2665.scala +pos/t5120.scala +pos/erasure-nsquared.scala +pos/arrays3.scala +pos/t3136.scala +pos/inline-access-levels +pos/t3972.scala +pos/t2591.scala +pos/t3486 +pos/variances-flip.scala +pos/annotated-original +pos/typesafecons.scala +pos/stable.scala +pos/t1996.scala +pos/t3037.scala +pos/t1711 +pos/t3374.scala +pos/t0029.scala +pos/t3278.scala +pos/matthias3.scala +pos/t5546.scala +pos/t4020.scala +pos/matthias4.scala +pos/value-class-override-spec.scala +pos/arrays2.scala +pos/t5119.scala +pos/t2613.scala +pos/t4070b.scala +pos/virtpatmat_exist_uncurry.scala +pos/modules1.scala +pos/spec-constr-new.scala +pos/t6335.scala +pos/t675.scala +pos/t0644.scala +pos/t5892.scala +pos/t360.scala +pos/override.scala +pos/t1798.scala +pos/strip-tvars-for-lubbasetypes.scala +pos/hk-infer.scala +pos/t2119.scala +pos/t0231.scala +pos/t1459 +pos/t1381-new.scala +pos/t2610.scala +pos/t2708.scala +pos/t5604b +pos/t3951 +pos/t361.scala +pos/t319.scala +pos/largecasetest.scala +pos/switchUnbox.scala +pos/typetags.scala +pos/java-access-pos +pos/t803.scala +pos/t3898.scala +pos/t5692a +pos/t2421.scala +pos/t1102 +pos/t0654.scala +pos/exhaust_alternatives.scala +pos/t807.scala +pos/t5702-pos-infix-star.scala +pos/t1186 +pos/t1439.scala +pos/t7427.scala +pos/virtpatmat_binding_opt.scala +pos/t247.scala +pos/abstract.scala +pos/gen-traversable-methods.scala +pos/t2795-old.scala +pos/t5639 +pos/t2667.scala +pos/t2405.scala +pos/t1438.scala +pos/SI-7100.scala +pos/t1659.scala +pos/unchecked-a.scala +pos/t3636.scala +pos/t6745.scala +pos/t2809.scala +pos/t7022.scala +pos/t6447.scala +pos/t6367.scala +pos/t5846.scala +pos/lubs.scala +pos/t1987a.scala +pos/spec-arrays.scala +pos/virtpatmat_anonfun_for.scala +pos/listpattern.scala +pos/t5742.scala +pos/test5refine.scala +pos/t5604 +pos/return_thistype.scala +pos/t348plus.scala +pos/t3420.scala +pos/t3440.scala +pos/maxim1.scala +pos/caseClassInMethod.scala +pos/t7239.scala +pos/t3833.scala +pos/t6675.scala +pos/t4402 +pos/t5953.scala +pos/t1152 +pos/t0591.scala +pos/t210.scala +pos/t7035.scala +pos/t5769.scala +pos/pmbug.scala +pos/t2331.scala +pos/t5240.scala +pos/t304.scala +pos/annotated-treecopy +pos/t2081.scala +pos/t0904.scala +pos/t7649.scala +pos/t3498-new.scala +pos/contrib701.scala +pos/t6624.scala +pos/t3924.scala +pos/t374.scala +pos/t1642 +pos/t1591_pos.scala +pos/depmet_implicit_oopsla_session_2.scala +pos/t5899.scala +pos/thistype.scala +pos/t4176b.scala +pos/elidable-tparams.scala +pos/lambdalift.scala +pos/nothing_manifest_disambig-old.scala +pos/t372.scala +pos/t5399a.scala +pos/t2782.scala +pos/patmat-extract-tparam.scala +pos/t4114.scala +pos/unapplyVal.scala +pos/t2486.scala +pos/t5877b.scala +pos/t0625.scala +pos/t6358_2.scala +pos/viewtest1.scala +pos/t1237.scala +pos/scala-singleton.scala +pos/t1254 +pos/t5504 +pos/bounds.scala +pos/t3631.scala +pos/t3177.scala +pos/unapplyContexts2.scala +pos/t0438.scala +pos/t1642b.scala +pos/inferbroadtype.scala +pos/t1858.scala +pos/t3731.scala +pos/t6963c.scala +pos/classtag-pos.scala +pos/t6221.scala +pos/t3343.scala +pos/spec-asseenfrom.scala +pos/t604.scala +pos/spec-example1.scala +pos/t0786.scala +pos/annot-inner.scala +pos/t5886.scala +pos/t1056.scala +pos/t294 +pos/spec-Function1.scala +pos/t1836 +pos/spec-private.scala +pos/depmet_implicit_tpbetareduce.scala +pos/exhaust_2.scala +pos/t7532 +pos/t5175.scala +pos/t802.scala +pos/t5809.scala +pos/tcpoly_typesub.scala +pos/t6029.scala +pos/contextbounds-implicits-new.scala +pos/t3480.scala +pos/patterns3.scala +pos/caseaccs.scala +pos/spec-sparsearray-old.scala +pos/patterns1213.scala +pos/spec-traits.scala +pos/t0020.scala +pos/cycle +pos/t5968.scala +pos/typealiases.scala +pos/init.scala +pos/t697.scala +pos/t2693.scala +pos/t2377 +pos/unapplyGeneric.scala +pos/t1385.scala +pos/t3363-old.scala +pos/t1236.scala +pos/t0068.scala +pos/t4052.scala +pos/lambdalift1.scala +pos/z1730.scala +pos/variances-local.scala +pos/virtpatmat_gadt_array.scala +pos/t2421_delitedsl.scala +pos/t5626.scala +pos/t690.scala +pos/t711.scala +pos/t6547.scala +pos/t1937 +pos/t3999 +pos/SI-7060.scala +pos/t2305.scala +pos/t2168.scala +pos/t2660.scala +pos/t1693.scala +pos/inliner2.scala +pos/t2799.scala +pos/t6966.scala +pos/t1001.scala +pos/S5.scala +pos/t0301.scala +pos/t1048.scala +pos/t415.scala +pos/t6386.scala +pos/t2187.scala +pos/hashhash-overloads.scala +pos/t6921.scala +pos/t0227.scala +pos/t6556.scala +pos/t3946 +pos/t1053.scala +pos/t1000.scala +pos/t0586.scala +pos/t7011.scala +pos/t7329.scala +pos/t4975.scala +pos/t1131.scala +pos/t1027.scala +pos/t2913.scala +pos/t3494.scala +pos/t5606.scala +pos/t4716.scala +pos/tcpoly_gm.scala +pos/t4859.scala +pos/t514.scala +pos/lexical.scala +pos/t2624.scala +pos/t4036.scala +pos/t2741 +pos/t703.scala +pos/five-dot-f.scala +pos/t805.scala +pos/strings.scala +pos/t2433 +pos/t6925.scala +pos/t1085.scala +pos/t7461 +pos/t1942 +pos/spec-lists.scala +pos/t3349 +pos/tcpoly_infer_ticket474.scala +pos/t1614 +pos/virtpatmat_reach_const.scala +pos/t2194.scala +pos/t6976 +pos/t1560.scala +pos/t6891.scala +pos/t3883.scala +pos/infersingle.scala +pos/gui.scala +pos/t1164.scala +pos/t3175-pos.scala +pos/t4336.scala +pos/annotations2.scala +pos/proj-rec-test.scala +pos/t2973.scala +pos/t1123.scala +pos/t6205.scala +pos/t5727.scala +pos/t6537.scala +pos/t6712.scala +pos/t3866.scala +pos/t4831.scala +pos/selftails.scala +pos/t397.scala +pos/spec-vector.scala +pos/t7233b.scala +pos/t1391.scala +pos/spec.scala +pos/t3106.scala +pos/contextbounds-implicits-old.scala +pos/packageobjs.scala +pos/michel3.scala +pos/t628.scala +pos/collections.scala +pos/tcpoly_boundedmonad.scala +pos/t7668.scala +pos/t0032.scala +pos/t0069.scala +pos/t4345.scala +pos/t3521 +pos/t3071.scala +pos/tcpoly_infer_easy.scala +pos/t289.scala +pos/t4365 +pos/rangepos-anonapply.scala +pos/t5033.scala +pos/lambda.scala +pos/S8.scala +pos/t6014.scala +pos/t1785.scala +pos/t6034.scala +pos/t7433.scala +pos/imp2-pos.scala +pos/t0504.scala +pos/t1272.scala +pos/t0612 +pos/value-class-override-no-spec.scala +pos/overloaded-unapply.scala +pos/t5859.scala +pos/chang +pos/localmodules.scala +pos/t4237.scala +pos/rangepos-patmat.scala +pos/t1974.scala +pos/t0054.scala +pos/michel2.scala +pos/t0770.scala +pos/t1146.scala +pos/t2441pos.scala +pos/t5099.scala +pos/tcpoly_seq_typealias.scala +pos/t946.scala +pos/tcpoly_infer_ticket1864.scala +pos/t4579.scala +pos/t4737 +pos/t7377b.scala +pos/t616.scala +pos/t201.scala +pos/t6355pos.scala +pos/escapes2.scala +pos/t1675.scala +pos/t3890.scala +pos/t6040.scala +pos/spec-tailcall.scala +pos/existentials.scala +pos/t5317.scala +pos/t7782b.scala +pos/t4758.scala +pos/t7296.scala +pos/t6896.scala +pos/cls1.scala +pos/t402.scala +pos/gosh.scala +pos/t2619.scala +pos/javaConversions-2.10-regression.scala +pos/t759.scala +pos/t5259.scala +pos/t5130.scala +pos/t5156.scala +pos/t0905.scala +pos/package-implicit +pos/t2669.scala +pos/trait-parents.scala +pos/virtpatmat_exhaust.scala +pos/patterns1.scala +pos/t7014 +pos/t1231 +pos/t1751 +pos/t7233.scala +pos/t6022.scala +pos/tcpoly_checkkinds_mix.scala +pos/depmet_implicit_norm_ret.scala +pos/package-case.scala +pos/philippe4.scala +pos/michel6.scala +pos/t4188.scala +pos/t3936 +pos/t1280.scala +pos/t6722.scala +pos/t796.scala +pos/t5542.scala +pos/t3927.scala +pos/t2293.scala +pos/t3800.scala +pos/t7285a.scala +pos/t927.scala +pos/t4494.scala +pos/t3864 +pos/ilya2 +pos/t2940 +pos/S1.scala +pos/tcpoly_wildcards.scala +pos/tryexpr.scala +pos/t6089b.scala +pos/depmet_implicit_oopsla_zipwith.scala +pos/t245.scala +pos/t6146.scala +pos/t1782 +pos/t851.scala +pos/spec-thistype.scala +pos/tcpoly_poly.scala +pos/t6815_import.scala +pos/t4649.scala +pos/t0453.scala +pos/t5020.scala +pos/ilya +pos/t2435.scala +pos/t1279a.scala +pos/t2171.scala +pos/t1957.scala +pos/gadts2.scala +pos/t3567 +pos/Z.scala +pos/t1203b +pos/nested2.scala +pos/t1896 +pos/viewtest2.scala +pos/t5541.scala +pos/existentials-harmful.scala +pos/t4063.scala +pos/t6485a +pos/t1208.scala +pos/t5041.scala +pos/unapplyComplex.scala +pos/t3384.scala +pos/t4112.scala +pos/t788.scala +pos/hklub0.scala +pos/t757.scala +pos/t1197 +pos/t359.scala +pos/t5667.scala +pos/t1107a.scala +pos/virtpatmat_castbinder.scala +pos/t267.scala +pos/t3419 +pos/t3861.scala +pos/t6797.scala +pos/spec-localdefs.scala +pos/t3404 +pos/t4457_1.scala +pos/matthias5.scala +pos/spec-polymeth.scala +pos/kinds.scala +pos/t2310.scala +pos/t6552.scala +pos/valdefs.scala +pos/hkarray.scala +pos/homonym.scala +pos/t1235 +pos/t3429 +pos/t0053.scala +pos/depmet_implicit_chaining_zw.scala +pos/virtpatmat_partialfun_nsdnho.scala +pos/t6664.scala +pos/ticket2251.scala +pos/t3495.scala +pos/super +pos/t121.scala +pos/javaConversions-2.10-ambiguity.scala +pos/t1803.scala +pos/t5877.scala +pos/t0085.scala +pos/t3582.scala +pos/t2939.scala +pos/t1422_pos.scala +pos/manifest1-new.scala +pos/t7505.scala +pos/t5720-ownerous.scala +pos/misc-unapply_pos.scala +pos/tcpoly_variance_pos.scala +pos/t5127.scala +pos/t6123-explaintypes-implicits.scala +pos/t2764 +pos/presuperContext.scala +pos/spec-simple.scala +pos/t3120 +pos/t5729.scala +pos/tcpoly_infer_ticket716.scala +pos/tcpoly_bounds1.scala +pos/t7369.scala +pos/imports-pos.scala +pos/t5654.scala +pos/t0123.scala +pos/raw-map +pos/t5330b.scala +pos/t6485b +pos/t6072.scala +pos/t5692c.scala +pos/t3430.scala +pos/tcpoly_param_scoping.scala +pos/t6204-b.scala +pos/attachments-typed-another-ident +pos/t5359.scala +pos/ticket2197.scala +pos/t720.scala +pos/t2130-2.scala +pos/t2260.scala +pos/t0304.scala +pos/t464.scala +pos/spec-maps.scala +pos/annotDepMethType.scala +pos/t6117.scala +pos/t911.scala +pos/t757a.scala +pos/t2504.scala +pos/t1381-old.scala +pos/t1232 +pos/needstypeearly.scala +pos/moduletrans.scala +pos/t4957.scala +pos/kinzer.scala +pos/t318.scala +pos/widen-existential.scala +pos/t0095.scala +pos/t566.scala +pos/tcpoly_overloaded.scala +pos/t7516 +pos/t7232 +pos/t698.scala +pos/t0002.scala +pos/t0288 +pos/t2994b.scala +pos/cls.scala +pos/t3622 +pos/t3671.scala +pos/tcpoly_subst.scala +pos/t5703 +pos/depmet_implicit_oopsla_session_simpler.scala +pos/t5022.scala +pos/builders.scala +pos/spec-foo.scala +pos/t756.scala +pos/t1569.scala +pos/implicit-unwrap-tc.scala +pos/t3688.scala +pos/t5198.scala +pos/t432.scala +pos/t6022b.scala +pos/channels.scala +pos/t1075.scala +pos/null.scala +pos/t1840 +pos/t6479.scala +pos/t6311.scala +pos/t0039.scala +pos/t1119.scala +pos/t573.scala +pos/t1136.scala +pos/t3938 +pos/spec-sealed.scala +pos/tcpoly_return_overriding.scala +pos/t3582b.scala +pos/t229.scala +pos/t3498-old.scala +pos/t531.scala +pos/t4545.scala +pos/t6651.scala +pos/t2133.scala +pos/tinondefcons.scala +pos/t6157.scala +pos/t6358.scala +pos/t7690.scala +pos/t5779-numeq-warn.scala +pos/list-extractor.scala +pos/t892.scala +pos/t2127.scala +pos/t7180.scala +pos/nullary_poly.scala +pos/virtpatmat_exist3.scala +pos/t1176 +pos/spec-funs.scala +pos/specialize10.scala +pos/t6514.scala +pos/exhaustive_heuristics.scala +pos/t0066.scala +pos/t460.scala +pos/t2130-1.scala +pos/t124.scala +pos/annotations.scala +pos/pat_gilles.scala +pos/array-interfaces.scala +pos/t6210.scala +pos/t3792.scala +pos/implicits-old.scala +pos/t389.scala +pos/t115.scala +pos/virtpatmat_exhaust_unchecked.scala +pos/scoping3.scala +pos/t6033.scala +pos/depmet_implicit_oopsla_session.scala +pos/t602.scala +pos/test5.scala +pos/t611.scala +pos/t5932.scala +pos/t4910.scala +pos/unapplySeq.scala +pos/t344.scala +pos/t3363-new.scala +pos/t4018.scala +pos/t4553.scala +pos/t5082.scala +pos/t3869.scala +pos/t3836.scala +pos/tcpoly_typeapp.scala +pos/t1409 +pos/nonlocal-unchecked.scala +pos/t0082.scala +pos/z1720.scala +pos/t7232c +pos/t2018.scala +pos/t3943 +pos/t2187-2.scala +pos/unicode-decode.scala +pos/t4757 +pos/t0710.scala +pos/t0305.scala +pos/t160.scala +pos/t7591 +pos/simplelists.scala +pos/List1.scala +pos/t516.scala +pos/t6648.scala +pos/t5165 +pos/t0055.scala +pos/t4744 +pos/t7377 +pos/t5726.scala +pos/t0091.scala +pos/t6595.scala +pos/compile.scala +pos/depmet_1_pos.scala +pos/t7364 +pos/philippe3.scala +pos/spec-doubledef-old.scala +pos/t4651.scala +pos/tcpoly_infer_implicit_tuple_wrapper.scala +pos/t6274.scala +pos/tcpoly_infer_explicit_tuple_wrapper.scala +pos/ticket2201.scala +pos/spec-fields-new.scala +pos/optmatch.scala +pos/t7517.scala +pos/t3560.scala +pos/t0165.scala +pos/t0872.scala +pos/t522.scala +pos/t2234.scala +pos/t5031_2.scala +pos/tcpoly_method.scala +pos/t6482.scala +pos/pos-bug1241.scala +pos/implicits-new.scala +pos/t2484.scala +pos/t2425.scala +pos/t1049.scala +pos/michel4.scala +pos/t5958.scala +pos/virtpatmat_instof_valuetype.scala +pos/spec-t6286.scala +pos/t873.scala +pos/t3137.scala +pos/Transactions.scala +pos/t0064.scala +pos/t7486-named.scala +pos/t5444.scala +pos/simple-exceptions.scala +pos/t1006.scala +pos/t7200b.scala +pos/t3777.scala +pos/t4840.scala +pos/t211.scala +pos/nullary.scala +pos/michel1.scala +pos/t5031_3 +pos/typealias_dubious.scala +pos/spec-doubledef-new.scala +pos/philippe1.scala +pos/thistypes.scala +pos/t3570.scala +pos/t6516.scala +pos/context.scala +pos/t3808.scala +pos/philippe2.scala +pos/constfold.scala +pos/t1292.scala +pos/t1147.scala +pos/t404.scala +pos/t4430.scala +pos/A.scala +pos/spec-partially.scala +pos/t5796.scala +pos/t2409 +pos/t284-pos.scala +pos/t5313.scala +pos/t2464 +pos/t1591b.scala +pos/hk-match +pos/t595.scala +pos/t6846.scala +pos/t6162-inheritance.scala +pos/relax_implicit_divergence.scala +pos/patterns2.scala +pos/t4692.scala +pos/t3837.scala +pos/t661.scala +pos/t2810.scala +pos/depexists.scala +pos/virtpatmat_exist4.scala +pos/t5245.scala +pos/t7190.scala +pos/isApplicableSafe.scala +pos/t6204-a.scala +pos/t0076.scala +pos/t1756.scala +pos/t1745 +pos/t6091.scala +pos/t0154.scala +pos/t530.scala +pos/t2094.scala +pos/t1034.scala +pos/t6084.scala +pos/t2454.scala +pos/t2956 +pos/tcpoly_ticket2096.scala +pos/attachments-typed-ident +pos/polymorphic-case-class.scala +pos/t252.scala +pos/spec-constr-old.scala +pos/t2421c.scala +pos/t122.scala +pos/t6574.scala +pos/t3859.scala +pos/spec-params-old.scala +pos/t1196 +pos/t4593.scala +pos/t596.scala +pos/t615.scala +pos/t7689.scala +pos/t3960.scala +pos/t3986.scala +pos/exbound.scala +pos/t2545.scala +pos/t1722 +pos/t159.scala +pos/t3272.scala +pos/t6301.scala +pos/t2794.scala +pos/t3048.scala +pos/t4970.scala +pos/t607.scala +pos/FPTest.scala +pos/test1.scala +pos/t3252.scala +pos/t4176.scala +pos/t112606A.scala +pos/t2183.scala +pos/t430-feb09.scala +pos/t6275.scala +pos/t1832.scala +pos/t8965.scala +pos/t7596b +pos/t8900.scala +pos/t9008.scala +pos/t7704.scala +pos/t7459c.scala +pos/sammy_override.scala +pos/t8828.scala +pos/t8868c +pos/t7459d.scala +pos/t8267.scala +pos/t8844.scala +pos/t8868a +pos/t8894.scala +pos/t7459a.scala +pos/t7596c +pos/t8498.scala +pos/t8868b +pos/t5413.scala +pos/t8781 +pos/t8934a +pos/t8310.scala +pos/t3439.scala +pos/t6582_exhaust_big.scala +pos/t8954 +pos/t5217.scala +pos/t7459b.scala +pos/t9018.scala +pos/sammy_exist.scala +pos/t8893.scala +pos/t7596 +pos/t8793.scala +pos/sammy_overload.scala +pos/t6051.scala +pos/t7683-stop-after-parser +pos/t7750.scala +pos/t5454.scala +pos/t8962.scala +pos/t8947 +pos/t8719 +pos/t8410.scala +pos/patmat-suppress.scala +pos/t8999.scala +pos/t8743.scala +pos/t9157.scala +pos/t8801.scala +pos/t9086.scala +pos/t9050.scala +pos/t9135.scala +pos/t9116.scala +pos/t5154.scala +pos/t9123.scala +pos/t3368.scala +pos/t9321.scala +pos/t9285.scala +pos/t8861.scala +pos/t8359-closelim-crash.scala +pos/t9020.scala +pos/jesper.scala +pos/t9356 +pos/virtpatmat_exhaust_big.scala +pos/t9239 +pos/t9111-inliner-workaround + +neg/volatile_no_override.scala +neg/t800.scala +neg/t5426.scala +neg/t2462a.scala +neg/t2641.scala +neg/classtags_dont_use_typetags.scala +neg/t5031 +neg/t2275b.scala +neg/macro-qmarkqmarkqmark.scala +neg/t4879.scala +neg/t5956.scala +neg/t4196.scala +neg/reify_ann2b.scala +neg/t6666b.scala +neg/warn-unused-privates.scala +neg/t6928.scala +neg/t6337.scala +neg/sealed-java-enums.scala +neg/t563.scala +neg/t900.scala +neg/deadline-inf-illegal.scala +neg/t766.scala +neg/t5429.scala +neg/overloaded-implicit.scala +neg/t875.scala +neg/abstract-class-error +neg/unchecked2.scala +neg/predef-masking.scala +neg/viewtest.scala +neg/macro-noexpand +neg/varargs.scala +neg/t963b.scala +neg/t909.scala +neg/sensitive2.scala +neg/t5390b.scala +neg/abstraction-from-volatile-type-error.scala +neg/macro-exception +neg/t4431.scala +neg/t5689.scala +neg/valueclasses.scala +neg/overload.scala +neg/t0204.scala +neg/t908.scala +neg/t750 +neg/patmatexhaust.scala +neg/macro-invalidusage-badtargs +neg/t1168.scala +neg/t5761.scala +neg/t0503.scala +neg/t7235.scala +neg/t1215.scala +neg/primitive-sigs-1 +neg/t5578.scala +neg/names-defaults-neg-warn.scala +neg/t6436b.scala +neg/t3098 +neg/t910.scala +neg/parstar.scala +neg/t4568.scala +neg/newpat_unreachable.scala +neg/t1181.scala +neg/t5903c +neg/t7294.scala +neg/t4091.scala +neg/t5452-old.scala +neg/t5696.scala +neg/t0209.scala +neg/t2910.scala +neg/t7388.scala +neg/noMember2.scala +neg/no-predef.scala +neg/t6952.scala +neg/t1909b.scala +neg/abstract-report2.scala +neg/t5318.scala +neg/t6074.scala +neg/t7171.scala +neg/abstract-vars.scala +neg/unchecked-impossible.scala +neg/variances-refinement.scala +neg/t3453.scala +neg/t5189.scala +neg/t4302.scala +neg/xmltruncated7.scala +neg/t8217-local-alias-requires-rhs.scala +neg/t7602.scala +neg/t8869.scala +neg/t9008.scala +neg/sammy_error_exist_no_crash.scala +neg/t2866.scala +neg/t8597b.scala +neg/t5691.scala +neg/t8534b.scala +neg/t5091.scala +neg/literals.scala +neg/t8534.scala +neg/t8890.scala +neg/t8764.scala +neg/t9008b.scala +neg/t8731.scala +neg/t8291.scala +neg/t8597.scala +neg/t5639b +neg/t6582_exhaust_big.scala +neg/t8841.scala +neg/t9041.scala +neg/t9093.scala +neg/t7623.scala +neg/t9231.scala +neg/t9286b.scala +neg/t9273.scala +neg/t9127.scala +neg/t9286c.scala +neg/t9286a.scala +neg/virtpatmat_exhaust_big.scala +neg/inlineMaxSize.scala +neg/patmatexhaust-huge.scala + +run/t7249.scala +run/t3563.scala +run/t6111.scala +run/classtags_multi.scala +run/t5201.scala +run/checked.scala +run/valueclasses-classtag-basic.scala +run/t7171.scala +run/t5053.scala +run/t4535.scala +run/t5923d +run/t7291.scala +run/partialfun.scala +run/macro-term-declared-in-package-object +run/mapValues.scala +run/gadts.scala +run/t2386-new.scala +run/virtpatmat_stringinterp.scala +run/t657.scala +run/t0017.scala +run/t5713 +run/t576.scala +run/t3580.scala +run/virtpatmat_partial.scala +run/t6646.scala +run/mixins.scala +run/t1672.scala +run/macro-expand-implicit-macro-has-implicit +run/tuple-match.scala +run/t7039.scala +run/virtpatmat_opt_sharing.scala +run/virtpatmat_casting.scala +run/t2176.scala +run/eta-expand-star2.scala +run/macro-impl-relaxed +run/intmap.scala +run/t751.scala +run/t1591.scala +run/macro-typecheck-implicitsdisabled +run/t6911.scala +run/t5604.scala +run/macro-term-declared-in-default-param +run/collection-stacks.scala +run/multi-array.scala +run/t4560b.scala +run/buffer-slice.scala +run/t5629.scala +run/t6690.scala +run/matchonstream.scala +run/t3603.scala +run/lazy-exprs.scala +run/macro-quasiquotes +run/Course-2002-13.scala +run/t6337a.scala +run/exoticnames.scala +run/t0936.scala +run/runtime-richChar.scala +run/t6272.scala +run/t7215.scala +run/t1939.scala +run/ReverseSeqView.scala +run/lazy-leaks.scala +run/t0048.scala +run/t3994.scala +run/t2241.scala +run/t627.scala +run/t5966.scala +run/getClassTest-valueClass.scala +run/t3619.scala +run/t1300.scala +run/t2177.scala +run/t3760.scala +run/t1829.scala +run/macro-expand-implicit-macro-is-view +run/t889.scala +run/QueueTest.scala +run/t4537 +run/t3699.scala +run/t1192.scala +run/macro-expand-tparams-bounds +run/macro-expand-nullary-generic +run/t1434.scala +run/t6443-varargs.scala +run/macro-term-declared-in-trait +run/t4080.scala +run/matcharraytail.scala +run/infiniteloop.scala +run/t5733.scala +run/virtpatmat_nested_lists.scala +run/t5158.scala +run/t6695.scala +run/t6070.scala +run/t4558.scala +run/exc2.scala +run/patmat-behavior-2.scala +run/overloads.scala +run/t6957.scala +run/transform.scala +run/t5500.scala +run/t6663.scala +run/castsingleton.scala +run/t4147.scala +run/virtpatmat_staging.scala +run/t4565_1.scala +run/t5588.scala +run/run-bug4840.scala +run/t3496.scala +run/t5867.scala +run/search.scala +run/t3112.scala +run/hashsetremove.scala +run/t6443.scala +run/macro-expand-tparams-prefix +run/contrib674.scala +run/t3508.scala +run/t4300.scala +run/virtpatmat_typed.scala +run/macro-term-declared-in-class-object +run/map_test.scala +run/t5040.scala +run/t4827b.scala +run/lift-and-unlift.scala +run/t6574b.scala +run/t7240 +run/t3984.scala +run/virtpatmat_tailcalls_verifyerror.scala +run/macro-term-declared-in-class-class +run/emptypf.scala +run/t6104.scala +run/t2818.scala +run/t3761-overload-byname.scala +run/t2526.scala +run/phantomValueClass.scala +run/t3126.scala +run/arybufgrow.scala +run/t3980.scala +run/t7375b +run/t6077_patmat_cse_irrefutable.scala +run/classmanifests_new_core.scala +run/t3395.scala +run/name-based-patmat.scala +run/inliner-infer.scala +run/t5171.scala +run/t3726.scala +run/null-hash.scala +run/t4027.scala +run/t2544.scala +run/patmatnew.scala +run/t5923b +run/t7242.scala +run/classtags_core.scala +run/streamWithFilter.scala +run/t3038b.scala +run/macro-expand-varargs-explicit-over-nonvarargs-good +run/macro-divergence-spurious +run/macro-duplicate +run/t2958.scala +run/patch-boundary.scala +run/t2333.scala +run/lazy-override-run.scala +run/macro-quasiinvalidbody-c +run/t5037.scala +run/takeAndDrop.scala +run/t6126.scala +run/t0883.scala +run/t7617a +run/t4171.scala +run/empty-array.scala +run/t7198.scala +run/t493.scala +run/genericValueClass.scala +run/t0677-old.scala +run/t1373.scala +run/t4461.scala +run/t6011b.scala +run/t7584.scala +run/t3935.scala +run/t6928-run.scala +run/t744.scala +run/t3241.scala +run/blame_eye_triple_eee-double.scala +run/t3829.scala +run/t5577.scala +run/t5914.scala +run/t601.scala +run/t5610.scala +run/macro-basic-mamd-mi +run/t6150.scala +run/stringbuilder.scala +run/t7290.scala +run/t6888.scala +run/t6327.scala +run/virtpatmat_unapplyseq.scala +run/t4656.scala +run/macro-term-declared-in-method +run/macro-expand-implicit-macro-is-implicit +run/blame_eye_triple_eee-float.scala +run/t4482.scala +run/t5488.scala +run/matchemptyarray.scala +run/t3714.scala +run/richWrapperEquals.scala +run/t5328.scala +run/stream_flatmap_odds.scala +run/implicitclasses.scala +run/t6827.scala +run/t6394b +run/complicatedmatch.scala +run/valueclasses-classmanifest-basic.scala +run/unreachable.scala +run/caseclasses.scala +run/withIndex.scala +run/exc1.scala +run/amp.scala +run/t1423.scala +run/t594.scala +run/t6353.scala +run/byname.scala +run/vector1.scala +run/t5879.scala +run/t1048.scala +run/t5080.scala +run/t4190.scala +run/caseClassEquality.scala +run/macro-enclosures +run/collections-toSelf.scala +run/implicits.scala +run/finalvar.scala +run/lazy-locals.scala +run/t7231.scala +run/t0508.scala +run/t6628.scala +run/t6406-regextract.scala +run/t0911.scala +run/t4013c.scala +run/t3502.scala +run/t5648.scala +run/retclosure.scala +run/t2857.scala +run/t4859.scala +run/t5162.scala +run/t3038.scala +run/classof.scala +run/t4062.scala +run/unapplyArray.scala +run/t4297.scala +run/t5923a +run/t1537.scala +run/boolexprs.scala +run/valueclasses-classtag-generic.scala +run/macro-term-declared-in-anonymous +run/tcpoly_monads.scala +run/t5407.scala +run/scan.scala +run/forvaleq.scala +run/null-and-intersect.scala +run/t7047 +run/t0607.scala +run/sequenceComparisons.scala +run/t4396.scala +run/macro-undetparams-consfromsls +run/t2029.scala +run/t1220.scala +run/option-fold.scala +run/t5284c.scala +run/macro-auto-duplicate +run/t3529.scala +run/t4697.scala +run/t2251.scala +run/t5300.scala +run/virtpatmat_valdef.scala +run/t2147.scala +run/virtpatmat_extends_product.scala +run/list_map.scala +run/t1333.scala +run/matchbytes.scala +run/valueclasses-classmanifest-existential.scala +run/records.scala +run/t3088.scala +run/macro-def-path-dependent +run/t6443-by-name.scala +run/t1044.scala +run/delay-good.scala +run/case-class-23.scala +run/weakconform.scala +run/patmat-bind-typed.scala +run/t4835.scala +run/t3097.scala +run/t405.scala +run/existentials.scala +run/t2876.scala +run/t4809.scala +run/t1427.scala +run/t6135.scala +run/t3575.scala +run/t5688.scala +run/t6900.scala +run/macro-expand-unapply-a +run/t6677b.scala +run/t7375a.scala +run/t7300.scala +run/typed-annotated +run/elidable-noflags.scala +run/t0042.scala +run/t3050.scala +run/t4536.scala +run/NestedClasses.scala +run/t3877.scala +run/seqlike-kmp.scala +run/t5907.scala +run/t266.scala +run/missingparams.scala +run/t2255.scala +run/t3488.scala +run/t3950.scala +run/typealias_overriding.scala +run/constant-optimization.scala +run/t7507.scala +run/t6090.scala +run/t4582.scala +run/macro-term-declared-in-class +run/macro-typecheck-macrosdisabled2 +run/t3425.scala +run/t4935.scala +run/t3326.scala +run/boolord.scala +run/t1141.scala +run/virtpatmat_unapply.scala +run/t5971.scala +run/t3651.scala +run/macro-sip19-revised +run/pure-args-byname-noinline.scala +run/preinits.scala +run/t5532.scala +run/concat-two-strings.scala +run/t3269.scala +run/macro-impl-default-params +run/t2162.scala +run/matchonseq.scala +run/t5428.scala +run/macro-expand-overload +run/t4660.scala +run/enrich-gentraversable.scala +run/macro-expand-override +run/t4054.scala +run/t4753.scala +run/macro-typecheck-macrosdisabled +run/t2308a.scala +run/duplicate-meth.scala +run/interop_classtags_are_classmanifests.scala +run/t3232.scala +run/t2075.scala +run/virtpatmat_partial_backquoted.scala +run/try-2.scala +run/macro-openmacros +run/macro-undetparams-macroitself +run/t6318_derived.scala +run/deprecate-early-type-defs.scala +run/dead-code-elimination.scala +run/t4827.scala +run/Course-2002-07.scala +run/slice-strings.scala +run/t6292.scala +run/t6206.scala +run/t1042.scala +run/t1718.scala +run/t2074_2.scala +run/arraycopy.scala +run/indexedSeq.scala +run/macro-term-declared-in-implicit-class +run/t3511.scala +run/t6290.scala +run/distinct.scala +run/virtpatmat_alts.scala +run/valueclasses-pavlov.scala +run/exceptions.scala +run/t1368.scala +run/t5856.scala +run/t6968.scala +run/names-defaults.scala +run/macro-expand-tparams-implicit +run/t5881.scala +run/t3540.scala +run/virtpatmat_try.scala +run/t7181.scala +run/value-class-extractor.scala +run/value-class-extractor-2.scala +run/t3150.scala +run/exc.scala +run/delay-bad.scala +run/infix.scala +run/t1309.scala +run/t6370.scala +run/t6725-2.scala +run/macro-impl-tparam-typetag-is-optional +run/macro-term-declared-in-block +run/matchnull.scala +run/t2127.scala +run/t7325.scala +run/groupby.scala +run/t3932.scala +run/t4871.scala +run/longmap.scala +run/t1524.scala +run/t6187b.scala +run/kmpSliceSearch.scala +run/t7088.scala +run/t5804.scala +run/stringbuilder-drop.scala +run/t5753_1 +run/t9223.scala +run/function-null-unbox.scala +run/t9223b.scala +run/disable-assertions.scala +run/valueClassSelfType.scala +run/indylambda-boxing +run/t9219.scala + +pos/cyclics-pos.scala +pos/cfcrash.scala +pos/tcpoly_higherorder_bound_method.scala +pos/t5084.scala +pos/trait-force-info.scala +pos/macro-qmarkqmarkqmark.scala +pos/t7785.scala +pos/nested.scala +pos/t3152.scala +pos/t5031 +pos/t6925b.scala +pos/t1107b +pos/t5012.scala +pos/virtpatmat_obj_in_case.scala +pos/t4938.scala +pos/t3856.scala +pos/spec-cyclic.scala +pos/aliases.scala +pos/typerep_pos.scala +pos/t119.scala +pos/t1050.scala +pos/t3670.scala +pos/t6145.scala +pos/t7315.scala +pos/t5930.scala +pos/t789.scala +pos/t5071.scala +pos/t4731.scala +pos/t4547.scala +pos/t2038.scala +pos/testCoercionThis.scala +pos/t2444.scala +pos/t5744 +pos/t780.scala +pos/t1722-A.scala +pos/virtpatmat_exist1.scala +pos/t6225.scala +pos/t762.scala +pos/t0204.scala +pos/rebind.scala +pos/spec-short.scala +pos/comp-rec-test.scala +pos/lub-dealias-widen.scala +pos/t1168.scala +pos/modules.scala +pos/t4220.scala +pos/t4070.scala +pos/t175.scala +pos/t2500.scala +pos/t5029.scala +pos/itay.scala +pos/t4202.scala +pos/t1987b +pos/t3534.scala +pos/infer2-pos.scala +pos/spec-sparsearray-new.scala +pos/t7091.scala +pos/ticket0137.scala +pos/collectGenericCC.scala +pos/t640.scala +pos/t4305.scala +pos/extractor-types.scala +pos/t3880.scala +pos/spec-annotations.scala +pos/t3577.scala +pos/compile1.scala +pos/spec-t3497.scala +pos/hkrange.scala +pos/t287.scala +pos/t7294.scala +pos/t6008.scala +pos/t4432.scala +pos/CustomGlobal.scala +pos/patmat.scala +pos/t2413 +pos/t2910.scala +pos/t592.scala +pos/t6245 +pos/infer.scala +pos/t7228.scala +pos/compound.scala +pos/attributes.scala +pos/t6771.scala +pos/t1090.scala +pos/t684.scala +pos/t577.scala +pos/t4273.scala +pos/t6278-synth-def.scala +pos/t6184.scala +neg/t0214.scala +neg/t4842.scala +neg/t6214.scala +neg/reify_nested_inner_refers_to_local.scala +neg/t576.scala +neg/t5969.scala +neg/tcpoly_variance.scala +neg/t7509.scala +neg/mixins.scala +neg/parent-inherited-twice-error.scala +neg/macro-abort +neg/constructor-init-order.scala +neg/t6042.scala +neg/t0590.scala +neg/eta-expand-star-deprecation.scala +neg/t4221.scala +neg/t6263.scala +neg/t783.scala +neg/t5554.scala +neg/macro-invalidsig-params-badtype +neg/multi-array.scala +neg/raw-types-stubs +neg/spec-overrides.scala +neg/t836.scala +neg/t7289_status_quo.scala +neg/t5675.scala +neg/macro-quasiquotes +neg/t6667.scala +neg/t6597.scala +neg/t6264.scala +neg/t0345.scala +neg/t7294b.scala +neg/t5340.scala +neg/t2144.scala +neg/t1010.scala +neg/t1838.scala +neg/t5189b.scala +neg/reify_metalevel_breach_-1_refers_to_1.scala +neg/t6601 +neg/wellkinded_wrongarity.scala +neg/t3909.scala +neg/t876.scala +neg/t5390.scala +neg/unit2anyref.scala +neg/t0351.scala +neg/t5120.scala +neg/t1038.scala +neg/t5878.scala +neg/qualifying-class-error-2.scala +neg/t3816.scala +neg/tailrec.scala +neg/volatile.scala +neg/t944.scala +neg/t1705.scala +neg/t3977.scala +neg/t5553_2.scala +neg/t5318c.scala +neg/overload-msg.scala +neg/t5440.scala +neg/t6335.scala +neg/compile-time-only-b.scala +neg/t501.scala +neg/override.scala +neg/t663.scala +neg/t5892.scala +neg/t1980.scala +neg/macro-false-deprecation-warning +neg/t5148.scala +neg/t585.scala +neg/t3776.scala +neg/interop_classtags_arenot_manifests.scala +neg/t4044.scala +neg/macro-invalidusage-nontypeable +neg/t6375.scala +neg/t500.scala +neg/t4877.scala +neg/t5357.scala +neg/interop_abstypetags_arenot_manifests.scala +neg/t4460a.scala +neg/t5318b.scala +neg/t3234.scala +neg/t4440.scala +neg/t6663.scala +neg/t6357.scala +neg/gadts1.scala +neg/cyclics.scala +neg/t5060.scala +neg/scopes.scala +run/t4013.scala +run/macro-expand-tparams-explicit +run/tuples.scala +run/t5753_2 +run/t0528.scala +run/t5105.scala +run/t7341.scala +run/t3670.scala +run/t2594_tcpoly.scala +run/t3895.scala +run/t0668.scala +run/slices.scala +run/t6666a.scala +run/valueclasses-classmanifest-generic.scala +run/t2316_run.scala +run/t3004.scala +run/viewtest.scala +run/t6481.scala +run/t0005.scala +run/t4766.scala +run/t5500b.scala +run/t7407b.scala +run/backreferences.scala +run/arrayview.scala +run/t629.scala +run/t5903c +run/unittest_collection.scala +run/spec-nlreturn.scala +run/macro-term-declared-in-object-object +run/triple-quoted-expr.scala +run/t5937.scala +run/t6011c.scala +run/macro-expand-implicit-argument +run/try.scala +run/t1987b +run/t6089.scala +run/macro-range +run/t2524.scala +run/t4770.scala +run/virtpatmat_unapplyprod.scala +run/t1535.scala +run/ctor-order.scala +pos/t5210.scala +pos/t5384.scala +pos/rangepos.scala +pos/t443.scala +pos/t1480.scala +pos/t116.scala +pos/seqtest2.scala +pos/scoping1.scala +pos/t4269.scala +pos/lookupswitch.scala +pos/t3642 +pos/t5706.scala +pos/SI-5788.scala +pos/t7264 +pos/t0031.scala +pos/macro-deprecate-dont-touch-backquotedidents.scala +pos/t6815.scala +pos/test4refine.scala +pos/michel5.scala +pos/t0851.scala +pos/t1185.scala +pos/sudoku.scala +pos/t7520.scala +pos/t6208.scala +pos/t3411.scala +pos/t295.scala +pos/S3.scala +pos/t0674.scala +pos/t6664b.scala +pos/variances_pos.scala +pos/liftcode_polymorphic.scala +pos/t3174b.scala +pos/t7232d +pos/t578.scala +pos/implicit-infix-ops.scala +pos/t4363.scala +pos/t532.scala +pos/exponential-spec.scala +pos/t599.scala +pos/t5862.scala +pos/t4603 +pos/t3676.scala +pos/t1357.scala +pos/native-warning.scala +pos/t1230 +pos/t6028 +pos/t4275.scala +pos/overloaded_extractor_and_regular_def.scala +pos/t4205 +pos/matthias1.scala +pos/testcast.scala +pos/generic-sigs.scala +pos/t0093.scala +pos/specializes-sym-crash.scala +pos/t0061.scala +pos/t2429.scala +pos/t694.scala +pos/javaReadsSigs +pos/t2023.scala +pos/t704.scala +pos/t2208_pos.scala +pos/t5137.scala +pos/t2683.scala +pos/t0049.scala +pos/t1029 +pos/t4243.scala +pos/typerep-stephane.scala +pos/t177.scala +pos/t5967.scala +pos/t430.scala +pos/virtpatmat_infer_single_1.scala +pos/pat_iuli.scala +pos/t1071.scala +pos/t7226.scala +pos/t1843.scala +pos/t419.scala +pos/t7364b +pos/t1159.scala +pos/t5305.scala +pos/t7694.scala +pos/t6047.scala +pos/t3578.scala +pos/t2082.scala +pos/setter-not-implicit.scala +pos/t1133.scala +pos/t3862.scala +pos/t942 +pos/nothing_manifest_disambig-new.scala +pos/iterator-traversable-mix.scala +pos/eta.scala +pos/test4.scala +pos/t2691.scala +pos/t4502.scala +pos/t7183.scala +pos/protected-t1010.scala +pos/X.scala +pos/virtpatmat_exist2.scala +pos/t4911.scala +pos/t3477.scala +pos/t4173.scala +pos/t7782.scala +pos/t2399.scala +pos/virtpatmat_alts_subst.scala +pos/propagate.scala +pos/t2421b_pos.scala +pos/t183.scala +pos/t7033.scala +pos/t3612.scala +pos/t5330c.scala +pos/t3020.scala +pos/t4869.scala +pos/t3373.scala +pos/spec-params-new.scala +pos/t3672.scala +pos/t4501.scala +pos/t1565.scala +pos/t3774.scala +pos/t6942 +pos/t845.scala +pos/t3240.scala + +neg/t3275.scala +neg/t421.scala +neg/t5702-neg-bad-brace.scala +neg/t3663 +neg/badtok-1.scala +neg/t677.scala +neg/t7756b.scala +neg/t6534.scala +neg/t6276.scala +neg/t5762.scala +neg/abstract.scala +neg/t2405.scala +neg/t0418.scala +neg/t5390c.scala +neg/lazyvals.scala +neg/lubs.scala +neg/abstract-report.scala +neg/t4163.scala +neg/t5702-neg-bad-and-wild.scala +neg/macro-invalidret +neg/t6728.scala +neg/t5152.scala +neg/t1432.scala +neg/abstract-inaccessible.scala +neg/import-precedence.scala +neg/t2462b.scala +neg/macro-invalidusage-presuper +neg/specification-scopes +neg/t6048.scala +neg/t4079 +neg/macro-basic-mamdmi +neg/t7020.scala +neg/t3015.scala +neg/t0207.scala +neg/t2296b +neg/t0673 +neg/t3761-overload-byname.scala +neg/t6675.scala +neg/t5529.scala +neg/sensitive.scala +neg/t742.scala +neg/t5067.scala +neg/t6162-overriding.scala +neg/variances.scala +neg/t5728.scala +neg/t6323a.scala +neg/compile-time-only-a.scala +neg/t6795.scala +neg/t2494.scala +neg/t3649.scala +neg/macro-invalidsig +neg/t2796.scala +neg/t112706A.scala +neg/t0764.scala +neg/t3757 +neg/t1431.scala +neg/exhausting.scala +neg/t1523.scala +neg/t779.scala +neg/xmltruncated1.scala +neg/t2208.scala +neg/t2078.scala +neg/t521.scala +neg/null-unsoundness.scala +neg/stmt-expr-discard.scala +neg/t0513.scala +neg/unchecked-abstract.scala +neg/t4460c.scala +neg/divergent-implicit.scala +neg/t5078.scala +neg/t1701.scala +neg/t0816.scala +neg/t1672b.scala +neg/macro-invalidusage-badbounds +neg/tailrec-2.scala +neg/t4064.scala +neg/t5510.scala +neg/t3873.scala +neg/tailrec-3.scala +neg/t0226.scala +neg/t2031.scala +neg/t633.scala +neg/constrs.scala +neg/anyval-anyref-parent.scala +neg/t7290.scala +neg/t1041.scala +neg/patternalts.scala +neg/error_tooManyArgsPattern.scala +neg/checksensibleUnit.scala +neg/t6539 +neg/t4417.scala +neg/wellkinded_app.scala +neg/for-comprehension-old.scala +neg/t2779.scala +neg/object-not-a-value.scala +neg/t2968b.scala +neg/t6483.scala +neg/t6902.scala +neg/t6963a.scala +neg/t3399.scala +neg/t0015.scala +neg/t3995.scala +neg/t276.scala +neg/t6758.scala +neg/t2441.scala +neg/cycle-bounds.scala +neg/t1241.scala +neg/t4137.scala +neg/unicode-unterminated-quote.scala +neg/t4762.scala +neg/typeerror.scala +neg/implicits.scala +neg/t961.scala +neg/ambiguous-float-dots2.scala +neg/t2416.scala +neg/t5799.scala +neg/t7285.scala +neg/implicit-shadow.scala +neg/t2388.scala +neg/java-access-neg +neg/found-req-variance.scala +neg/hk-bad-bounds.scala +neg/t3224.scala +neg/t1033.scala +neg/t7385.scala +neg/t5882.scala +neg/t4541.scala +neg/t2973.scala +neg/t6406-regextract.scala +neg/t6666.scala +neg/t4831.scala +neg/t425.scala +neg/t1845.scala +neg/t3683b.scala +neg/t2801.scala +neg/t6083.scala +neg/t0528neg.scala +neg/stringinterpolation_macro-neg.scala +neg/t668.scala +neg/t5666.scala +neg/t4271.scala +neg/interop_typetags_arenot_classmanifests.scala +neg/t1355.scala +neg/t715.scala +neg/t7238.scala +neg/t7473.scala +neg/t7292-removal.scala +neg/tcpoly_infer_ticket1162.scala +neg/t4098.scala +neg/t6013 +neg/t6227.scala +neg/t464-neg.scala +neg/badtok-3.scala +neg/t6082.scala +neg/anytrait.scala +neg/valueclasses-doubledefs.scala +neg/t7519.scala +neg/overloaded-unapply.scala +neg/t1163.scala +neg/wellkinded_bounds.scala +neg/t7292-deprecation.scala +neg/t5044.scala +neg/t0842.scala +neg/t6436.scala +neg/interop_typetags_arenot_classtags.scala +neg/t3653.scala +neg/higherkind_novalue.scala +neg/t935.scala +neg/t6040.scala +neg/annot-nonconst.scala +neg/macro-deprecate-idents.scala +neg/illegal-stmt-start.scala +neg/t565.scala +neg/case-collision.scala +neg/t3209.scala +neg/t5821.scala +neg/abstract-class-2.scala +neg/t846.scala +neg/quasiquotes-syntax-error-position.scala +neg/t3987.scala +neg/t877.scala +neg/t0117.scala +neg/t692.scala +neg/t5702-neg-ugly-xbrace.scala +neg/t7752.scala +neg/case-collision2.scala +neg/t6526.scala +neg/t2213.scala +neg/t7756a.scala +neg/macro-override-macro-overrides-abstract-method-a +neg/tcpoly_ticket2101.scala +neg/delayed-init-ref.scala +neg/caseinherit.scala +neg/t3189.scala +neg/unchecked-suppress.scala +neg/t2180.scala +neg/t1371.scala +neg/macro-cyclic +neg/t6123-explaintypes-macros +neg/t4134.scala +neg/t691.scala +neg/t2421b.scala +neg/t4691_exhaust_extractor.scala +neg/t4419.scala +neg/t5801.scala +neg/t650.scala +neg/t5735.scala +neg/t696.scala +neg/t882.scala +neg/t2968.scala +neg/t7507.scala +neg/macro-invalidusage-badargs +neg/macro-reify-typetag-typeparams-notags +neg/wellkinded_app2.scala +neg/t4425b.scala +neg/t2296a +neg/t1878.scala +neg/t649.scala +neg/override-object-no.scala +neg/t4174.scala +neg/t2070.scala +neg/sabin2.scala +neg/t5903e +neg/t6566a.scala +neg/finitary-error.scala +neg/t4818.scala +neg/t3614.scala +neg/t6666c.scala +neg/ticket513.scala +neg/suggest-similar.scala +neg/t4457_1.scala +neg/t6666e.scala +neg/tcpoly_bounds.scala +neg/t4727.scala +neg/t4425.scala +neg/macro-invalidusage-methodvaluesyntax +neg/t3854.scala +neg/t3006.scala +neg/t5580b.scala +neg/t5378.scala +neg/t639.scala +neg/wrong-args-for-none.scala +neg/t7171b.scala +neg/t5361.scala +neg/unreachablechar.scala +neg/t5572.scala +neg/t7757a.scala +neg/macro-invalidimpl +neg/t2773.scala +neg/t6359.scala +neg/saito.scala +neg/xmltruncated2.scala +neg/t667.scala +neg/t3934.scala +neg/t6771b.scala +neg/t4584.scala +neg/wellkinded_wrongarity2.scala +neg/t7369.scala +neg/t1477.scala +neg/t5617.scala +neg/t7299.scala +neg/faculty.scala +neg/virtpatmat_reach_null.scala +neg/macro-reify-typetag-hktypeparams-notags +neg/t1224.scala +neg/xmltruncated3.scala +neg/t1872.scala +neg/t558.scala +neg/t7110.scala +neg/any-vs-anyref.scala +neg/t6340.scala +neg/t4166.scala +neg/t2918.scala +neg/t5856.scala +neg/t4989.scala +neg/t0003.scala +neg/t1183.scala +neg/t963.scala +neg/t4515.scala +neg/valueclasses-pavlov.scala +neg/t608.scala +neg/choices.scala +neg/patmat-type-check.scala +neg/valueclasses-impl-restrictions.scala +neg/imp2.scala +neg/protected-constructors.scala +neg/t6788.scala +neg/nullary-override.scala +neg/t200.scala +neg/t343.scala +neg/names-defaults-neg-ref.scala +neg/tcpoly_typealias.scala +neg/classtags_contextbound_b.scala +neg/t729.scala +neg/t5683.scala +neg/t4928.scala +neg/t700.scala +neg/t7669.scala +neg/macro-invalidshape +neg/t6011.scala +neg/t7325.scala +neg/check-dead.scala +neg/t550.scala +neg/t5663-badwarneq.scala +neg/t0699 +neg/nopredefs.scala +neg/t3507-old.scala +neg/t5352.scala +neg/t6336.scala +neg/interop_classmanifests_arenot_typetags.scala +neg/sealed-final-neg.scala +neg/t2102.scala +neg/t7636.scala +neg/t5031b +neg/t798.scala +neg/t5702-neg-bad-xbrace.scala +neg/t0899.scala +neg/cyclics-import.scala +neg/badtok-2.scala +neg/t473.scala +neg/t3160ambiguous.scala +neg/t5106.scala +neg/t1286 +neg/macro-override-macro-overrides-abstract-method-b +neg/t0259.scala +neg/t510.scala +neg/t3836.scala +neg/t5830.scala +neg/t1548 +neg/t5580a.scala +neg/forward.scala +neg/t591.scala +neg/t6558b.scala +neg/t556.scala +neg/xmltruncated4.scala +neg/t5497.scala +neg/t409.scala +neg/t6283.scala +neg/override-object-flag.scala +neg/constructor-prefix-error.scala +neg/eta-expand-star.scala +neg/t3392.scala +neg/t1275.scala +neg/nested-fn-print.scala +neg/t7330.scala +neg/t2275a.scala +neg/t630.scala +neg/t4270.scala +neg/t2775.scala +neg/pat_unreachable.scala +neg/t4158.scala +neg/unit-returns-value.scala +neg/t1422.scala +neg/reify_metalevel_breach_-1_refers_to_0_b.scala +neg/reassignment.scala +neg/t3683a.scala +neg/noMember1.scala +neg/macro-without-xmacros-b +neg/t1106.scala +neg/t5182.scala +neg/t6889.scala +neg/t4217.scala +neg/t7501 +neg/t5063.scala +neg/t1009.scala +neg/t997.scala +neg/unchecked.scala +neg/classtags_contextbound_c.scala +neg/applydynamic_sip.scala +neg/t7715.scala +neg/t588.scala +neg/t6667b.scala +neg/t7757b.scala +neg/t4069.scala +neg/t515.scala +neg/variances2.scala +neg/t1049.scala +neg/t7289.scala +neg/t1623.scala +neg/permanent-blindness.scala +neg/t5803.scala +neg/super-cast-or-test.scala +neg/nonlocal-warning.scala +neg/t5687.scala +neg/t5903a +neg/t6566b.scala +neg/unchecked-knowable.scala +neg/t5093.scala +neg/protected-static-fail +neg/type-diagnostics.scala +neg/forgot-interpolator.scala +neg/interop_abstypetags_arenot_classmanifests.scala +neg/t5376.scala +neg/t545.scala +neg/xmlcorner.scala +neg/switch.scala +neg/depmet_1.scala +neg/abstract-concrete-methods.scala +neg/t4987.scala +neg/t5452-new.scala +neg/t750b +neg/unchecked-refinement.scala +neg/t418.scala +neg/t5354.scala +neg/t3736.scala +neg/t631.scala +neg/t6829.scala +neg/t0218.scala +neg/volatile-intersection.scala +neg/t412.scala +neg/t693.scala +neg/t4882.scala +neg/t1960.scala +neg/macro-divergence-controlled +neg/t712.scala +neg/t5544 +neg/t3222.scala +neg/t3604.scala +neg/t1112.scala +neg/t7157 +neg/accesses.scala +neg/t452.scala +neg/t6162-inheritance +neg/t2442 +neg/t6567.scala +neg/lazy-override.scala +neg/abstract-explaintypes.scala +neg/nested-annotation.scala +neg/t5753 +neg/t4283b +neg/t3691.scala +neg/infix-op-positions.scala +neg/t3403.scala +neg/t4851 +neg/structural.scala +neg/error_dependentMethodTpeConversionToFunction.scala +neg/t5839.scala +neg/t5553_1.scala +neg/reify_metalevel_breach_+0_refers_to_1.scala +neg/t752.scala +neg/t6574.scala +neg/t3714-neg.scala +neg/t4457_2.scala +neg/t2148.scala +neg/t1364.scala +neg/saferJavaConversions.scala +neg/t414.scala +neg/t5493.scala +neg/classtags_contextbound_a.scala +neg/reify_metalevel_breach_-1_refers_to_0_a.scala +neg/t3118.scala +neg/t512.scala +neg/t2336.scala +neg/t856.scala +neg/xmltruncated6.scala +neg/t2206.scala +neg/virtpatmat_unreach_select.scala +neg/t6258.scala +neg/t6815.scala +neg/not-possible-cause.scala +neg/dbldef.scala +neg/qualifying-class-error-1.scala +neg/t835.scala +neg/t5455.scala +neg/t6558.scala +neg/t708.scala +neg/macro-nontypeablebody +neg/t0565.scala +neg/xmltruncated5.scala +neg/t5390d.scala +neg/t520.scala +neg/t6138.scala +neg/macro-without-xmacros-a +neg/t7214neg.scala +neg/t2870.scala +neg/t593.scala +neg/t4541b.scala +neg/t4460b.scala +neg/t284.scala +neg/t2488.scala +neg/macro-override-method-overrides-macro +neg/interop_abstypetags_arenot_classtags.scala +neg/t3769.scala +neg/warn-inferred-any.scala +neg/t664.scala +neg/t5903d +neg/t562.scala +neg/t2316.scala +neg/t0152.scala +neg/migration28.scala +neg/t6443c.scala +neg/tcpoly_override.scala +neg/t7324.scala +neg/t987.scala +neg/t5903b +neg/t3481.scala +neg/t6912.scala +neg/tcpoly_variance_enforce.scala +neg/t3913.scala +neg/names-defaults-neg.scala +neg/t765.scala +neg/t5358.scala +neg/t391.scala +neg/serialversionuid-not-const.scala +neg/t771.scala +neg/t0903.scala +neg/catch-all.scala +neg/classmanifests_new_deprecations.scala +neg/t0606.scala +neg/t5189_inferred.scala +neg/macro-reify-typetag-useabstypetag +neg/t5543.scala +neg/logImplicits.scala +neg/interop_typetags_without_classtags_arenot_manifests.scala +neg/t6535.scala +neg/t7259.scala +neg/t2139.scala +neg/t278.scala +neg/t5564.scala +neg/unchecked3.scala +neg/virtpatmat_reach_sealed_unsealed.scala +neg/checksensible.scala +neg/t7721.scala +run/t3798.scala +run/macro-expand-varargs-explicit-over-varargs +run/t3888.scala +run/t0677-new.scala +run/t3273.scala +run/t3763.scala +run/t2755.scala +run/t920.scala +run/t5610a.scala +run/literals.scala +run/proxy.scala +run/unapply.scala +run/t5830.scala +run/array-addition.scala +run/macro-expand-nullary-nongeneric +run/macro-basic-ma-mdmi +run/valueclasses-constr.scala +run/t1247.scala +run/t3487.scala +run/rawstrings.scala +run/patmat-seqs.scala +run/eta-expand-star.scala +run/t7436.scala +run/t3996.scala +run/constructors.scala +run/t498.scala +run/t3835.scala +run/t298.scala +run/t2867.scala +run/t7120 +run/virtpatmat_literal.scala +run/t2175.scala +run/t2503.scala +run/t3026.scala +run/t603.scala +run/t0091.scala +run/t6394a +run/macro-expand-varargs-implicit-over-varargs +run/t7407.scala +run/t2552.scala +run/virtpatmat_npe.scala +run/macro-sip19 +run/t6644.scala +run/t6614.scala +run/t2005.scala +run/t4680.scala +run/t5903a +run/classtags_contextbound.scala +run/Course-2002-05.scala +run/applydynamic_sip.scala +run/t1766.scala +run/retsynch.scala +run/t7715.scala +run/t102.scala +run/nonlocalreturn.scala +run/macro-reify-staticXXX +run/Course-2002-06.scala +run/t6863.scala +run/t6500.scala +run/macro-impl-rename-context +run/t4351.scala +run/t5009.scala +run/macro-term-declared-in-annotation +run/t6271.scala +run/array-existential-bound.scala +run/t6443b.scala +run/t1987.scala +run/MutableListTest.scala +run/t7571.scala +run/t5488-fn.scala +run/macro-bodyexpandstoimpl +run/macro-reify-ref-to-packageless +run/t2212.scala +run/macro-expand-varargs-implicit-over-nonvarargs +run/t0807.scala +run/patmat-behavior.scala +run/t2446.scala +run/tuple-zipped.scala +run/breakout.scala +run/t4122.scala +run/macro-settings +run/t7157 +run/t1323.scala +run/t4013b.scala +run/t6309.scala +run/t4047.scala +run/t5544 +run/t978.scala +run/t3361.scala +run/t6611.scala +run/t5387.scala +run/t5656.scala +run/t4897.scala +run/numeric-range.scala +run/t4777.scala +run/Course-2002-03.scala +run/string-extractor.scala +run/view-headoption.scala +run/patmat_unapp_abstype-new.scala +run/stream-stack-overflow-filter-map.scala +run/macro-impl-tparam-only-in-impl +run/t6559.scala +run/macro-reify-tagful-a +run/macro-expand-multiple-arglists +run/t4709.scala +run/t3509.scala +run/t5284b.scala +run/t7617b +run/t3923.scala +run/virtpatmat_apply.scala +run/t363.scala +run/manifests-undeprecated-in-2.10.0.scala +run/matchintasany.scala +run/t3970.scala +run/t4996.scala +run/t5530.scala +run/macro-term-declared-in-object-class +run/t3242b.scala +run/indexedSeq-apply.scala +run/t107.scala +run/t2337.scala +run/t2754.scala +run/flat-flat-flat.scala +run/t6673.scala +run/interpolationMultiline2.scala +run/t0631.scala +run/t2800.scala +run/t6506.scala +run/t6260.scala +run/t2418.scala +run/t4415.scala +run/classmanifests_new_alias.scala +run/t5380.scala +run/tcpoly_parseridioms.scala +run/t1747.scala +run/t5903d +run/t3530.scala +run/t216.scala +run/macro-term-declared-in-refinement +run/t4592.scala +run/t2488.scala +run/t3327.scala +run/t5614.scala +run/t5903b +run/iterables.scala +run/t3964.scala +run/t6329_vanilla.scala +run/t3038c +run/t1697.scala +run/t2030.scala +run/t3397.scala +run/t1005.scala +run/t3353.scala +run/t1466.scala +run/t3186.scala +run/tcpoly_overriding.scala +run/t5394.scala +run/t5284.scala +run/unboxingBug.scala +run/t7200.scala +run/macro-reify-basic +run/t153.scala +run/iterator3444.scala +run/macro-expand-implicit-macro-is-val +run/macro-basic-ma-md-mi +run/interpolationArgs.scala +run/t4954.scala +run/t3645.scala +run/transpose.scala +run/t3887.scala +run/t4288.scala +run/unittest_iterator.scala +run/t5543.scala +run/macro-term-declared-in-object +run/iq.scala +run/t2788.scala +run/t2027.scala +run/macro-expand-recursive +run/t949.scala +run/t1909b.scala +run/delambdafy-nested-by-name.scala +run/delambdafy-two-lambdas.scala +run/macro-blackbox-materialization +run/lists-run.scala +run/macro-parse-position +run/macro-parse-position-malformed +run/macro-whitebox-dynamic-materialization +run/macro-whitebox-extractor +run/macro-vampire-false-warning +run/macro-whitebox-fundep-materialization +run/macro-whitebox-structural +run/mutable-treeset.scala +run/static-module-method.scala +run/sort.scala +run/t1909.scala +run/t1909c.scala +run/t3346a.scala +run/t3346d.scala +run/t3346f.scala +run/t3346h.scala +run/t3346g.scala +run/t3832.scala +run/t4742.scala +run/t5377.scala +run/t5923c.scala +run/t6188.scala +run/t6333.scala +run/t6385.scala +run/t7899.scala +run/t7899-regression.scala +run/t7584b.scala +run/t7223.scala +run/t7859 +run/t7868.scala +run/t7871 +run/arrayclone-new.scala +run/arrayclone-old.scala +run/bitsets.scala +run/comparable-comparator.scala +run/colltest1.scala +run/t2106.scala +run/t5986.scala +run/view-iterator-stream.scala +run/array-charSeq.scala +pos/signatures +pos/t1263 +pos/t3249 +neg/t4749.scala +neg/main1.scala +neg/t7251 +neg/t7494-after-terminal +neg/t7494-before-parser +neg/t7494-right-after-terminal +run/lazy-traits.scala +run/OrderingTest.scala +run/ReplacementMatching.scala +run/patmat-finally.scala +run/t3158.scala +run/t3346e.scala +run/t4398.scala +run/t4930.scala +run/t6534.scala +pos/sammy_scope.scala +pos/delambdafy-patterns.scala +pos/private-types-after-typer.scala +pos/delambdafy-lambdalift.scala +pos/sammy_poly.scala +pos/sammy_single.scala +pos/SI-4012-b.scala +pos/sammy_twice.scala +pos/t3160.scala +pos/t1014.scala +pos/t4970b.scala +pos/t2698.scala +pos/t5845.scala +pos/t6201.scala +pos/t6260a.scala +pos/t7688.scala +pos/t7818.scala +pos/t1203a.scala +pos/t7834.scala +pos/t7853.scala +pos/t7815.scala +pos/t7853-partial-function.scala +pos/t7864.scala +pos/t7928.scala +pos/t7902.scala +pos/t7944.scala +pos/t7847 +neg/accesses2.scala +neg/bad-advice.scala +neg/gadts2.scala +neg/gadts2-strict.scala +neg/macro-bundle-abstract.scala +neg/macro-bundle-object.scala +neg/macro-bundle-trait.scala +neg/macro-blackbox-dynamic-materialization +neg/macro-blackbox-extractor +neg/run-gadts-strict.scala +neg/macro-blackbox-structural +neg/sammy_restrictions.scala +neg/sammy_wrong_arity.scala +neg/t2462c.scala +neg/t3346b.scala +neg/t1909-object.scala +neg/macro-blackbox-fundep-materialization +neg/t3346c.scala +neg/t3871.scala +neg/t3871b.scala +neg/t3971.scala +neg/t3346i.scala +neg/t6120.scala +neg/t6260c.scala +neg/t6680a.scala +neg/t7239.scala +neg/t7007.scala +neg/t7605-deprecation.scala +neg/t7622-missing-required.scala +neg/t7629-view-bounds-deprecation.scala +neg/t7834neg.scala +neg/t7783.scala +neg/t7848-interp-warn.scala +neg/t7519-b +neg/t7622-missing-dependency +neg/t7870.scala +neg/t7877.scala +neg/t7895.scala +neg/t7895b.scala +neg/t7899.scala +neg/t7895c.scala +neg/t7859 +run/t4752.scala +run/t2087-and-2400.scala +run/t3855.scala +run/t6637.scala +run/t6731.scala +pos/t3999b.scala +run/t0432.scala +run/t2514.scala +run/t7817.scala +run/t874.scala +run/type-currying.scala +run/t3616.scala +run/t3687.scala +run/t4570.scala +run/t5612.scala +run/t1110.scala +run/t2636.scala +run/verify-ctor.scala +run/t3647.scala +run/t4560.scala +run/t6632.scala +run/hashCodeBoxesRunTime.scala +run/richs.scala +run/t6725-1.scala +pos/t7776.scala +run/fors.scala +run/t6706.scala +run/t3175.scala +run/delambdafy-dependent-on-param-subst.scala +run/t4332b.scala +run/t8048a +run/t8017 +run/t7985b.scala +run/t8100.scala +run/patmat-mix-case-extractor.scala +run/t4750.scala +run/t7912.scala +run/delambdafy-dependent-on-param-subst-2.scala +run/t8048b +run/t8091.scala +run/macroPlugins-macroRuntime +run/macro-default-params +run/t6355.scala +run/t7777 +run/t8002.scala +run/t8015-ffc.scala +run/macro-subpatterns +run/t7985.scala +run/macroPlugins-macroArgs +run/t7326.scala +run/t5045.scala +run/value-class-partial-func-depmet.scala +run/t6329_vanilla_bug.scala +run/macroPlugins-macroExpand +run/t8010.scala +run/macroPlugins-typedMacroBody +run/t7406.scala +pos/t8146a.scala +pos/t8046c.scala +pos/t8002-nested-scope.scala +pos/t8132.scala +pos/t8045.scala +pos/overzealous-assert-genbcode.scala +pos/t8128.scala +pos/t8013 +pos/t8064b +pos/t6780.scala +pos/t7987 +pos/bcode_throw_null +pos/t8064 +pos/t8046.scala +pos/t6231.scala +pos/t7983.scala +pos/t5508.scala +pos/t5508-min.scala +pos/t8023b.scala +pos/t6231b.scala +pos/debug-reset-local-attrs.scala +pos/t8054.scala +pos/t2066.scala +pos/dotless-targs.scala +pos/t8120.scala +pos/t5508-min-okay.scala +pos/t8060.scala +pos/t8001 +pos/t8138.scala +pos/t8111.scala +pos/t8062 +pos/t8011.scala +pos/t8146b.scala +pos/t8046b.scala +pos/t8023.scala +pos/t5508-min-okay2.scala +pos/macro-implicit-invalidate-on-error.scala +neg/t6563.scala +neg/missing-param-type-tuple.scala +neg/not-a-legal-formal-parameter-tuple.scala +neg/t7897.scala +neg/t8015-ffa.scala +neg/quasiquotes-unliftable-not-found.scala +neg/t2066b.scala +neg/dotless-targs.scala +neg/patmat-classtag-compound.scala +neg/t2066.scala +neg/t8035-deprecated.scala +neg/t6675b.scala +neg/t8104 +neg/t7872.scala +neg/t7850.scala +neg/t7967.scala +neg/macro-bundle-overloaded.scala +neg/t6355a.scala +neg/class-of-double-targs.scala +neg/t6355b.scala +neg/macro-reify-splice-splice +neg/macro-bundle-noncontext.scala +neg/t8015-ffb.scala +neg/t8035-removed.scala +neg/t7984.scala +neg/t8024.scala +neg/t8024b.scala +neg/t8157.scala +neg/t8146-non-finitary-2.scala +neg/t8006.scala +neg/t7872c.scala +neg/t8146-non-finitary.scala +neg/t7872b.scala +neg/t6920.scala +run/t6200.scala +run/t6196.scala +run/macro-bundle-context-refinement +run/macro-enclosingowner-detectvar +run/macro-enclosingowner-sbt +run/macro-bundle-context-alias +run/macro-bundle-whitebox-use-refined +run/macro-bundle-whitebox-use-raw +neg/name-lookup-stable.scala +neg/t0764b.scala +neg/no-implicit-to-anyref-any-val.scala +neg/t1503.scala +neg/t4728.scala +neg/t6455.scala +neg/t6260-named.scala +neg/t6844.scala +neg/t7475c.scala +neg/t7475e.scala +neg/t7475f.scala +neg/macro-bundle-whitebox-use-raw +neg/macro-bundle-whitebox-use-refined +neg/macro-incompatible-macro-engine-b +neg/t7980.scala +neg/macro-incompatible-macro-engine-a +neg/t8143a.scala +neg/t8072.scala +neg/t8207.scala +neg/t8182.scala +neg/t8219-any-any-ref-equals.scala +neg/t8177a.scala +neg/t8228.scala +neg/t8229.scala +neg/t8237-default.scala +neg/t8244b.scala +neg/t8244e +neg/t8244c.scala +neg/t8265.scala +neg/t8266-invalid-interp.scala +neg/t6931 +neg/t8376 +neg/t8372.scala +neg/t8300-overloading.scala +neg/t8244 +neg/t8158 +neg/t8431.scala +pos/implicit-anyval-2.10.scala +pos/delambdafy_t6260_method.scala +pos/macro-bundle-disambiguate-bundle.scala +pos/macro-bundle-disambiguate-nonbundle.scala +pos/package-ob-case +pos/t1786-counter.scala +pos/reflection-compat-api-universe.scala +pos/list-optim-check.scala +pos/existential-java-case-class +pos/t1786-cycle.scala +pos/reflection-compat-c.scala +pos/t3452f.scala +pos/reflection-compat-ru.scala +pos/t2066-2.10-compat.scala +pos/reflection-compat-macro-universe.scala +pos/t5900a.scala +pos/t5760-pkgobj-warn +pos/t5954a +pos/t5954b +pos/t5954d +pos/t6260.scala +pos/t5165b +pos/t5954c +pos/t6260b.scala +pos/t7475b.scala +pos/t7475a.scala +pos/t7753.scala +pos/t7322.scala +pos/t6948.scala +pos/t7475d.scala +pos/t7475e.scala +pos/t6169 +pos/t7788.scala +pos/t7919.scala +pos/t8177a.scala +pos/t8177.scala +pos/t8170.scala +pos/t8170b.scala +pos/t8177d.scala +pos/t8177b.scala +pos/t8177e.scala +pos/t8134 +pos/t8177h.scala +pos/t8177g.scala +pos/t8207.scala +pos/t8187.scala +pos/t8219.scala +pos/t8219b.scala +pos/t8224.scala +pos/t8237.scala +pos/t8223.scala +pos/t8237b.scala +pos/t8300-conversions-a.scala +pos/t8300-conversions-b.scala +pos/t8209a +pos/t8209b +pos/t8244d +pos/t8300-overloading.scala +pos/t8300-patmat-a.scala +pos/t8300-patmat-b.scala +pos/t8315b.scala +pos/t8306.scala +pos/t8301.scala +pos/t8324.scala +pos/t8315.scala +pos/t8301b.scala +pos/t8363.scala +pos/t8367.scala +pos/t8369a.scala +pos/t8369b.scala +pos/t8403.scala +pos/t8364.scala +pos/t8352 +pos/t8376 +neg/macro-bundle-nonpublic-c.scala +neg/literate_existentials.scala +neg/macro-bundle-nonpublic-impl.scala +neg/macro-bundle-ambiguous.scala +neg/macro-bundle-priority-bundle.scala +neg/macro-bundle-need-qualifier.scala +neg/macro-bundle-nonstatic.scala +neg/macro-bundle-polymorphic.scala +neg/macro-bundle-priority-nonbundle.scala +neg/macro-bundle-wrongcontext-a.scala +neg/macro-bundle-wrongcontext-b.scala +run/t8425 +run/t8245.scala +run/t8266-octal-interp.scala +run/t8280.scala +run/t8395.scala +run/t8321 +run/t8153.scala +run/t8233-bcode.scala +run/t8197.scala +run/t8197b.scala +run/t8233.scala +run/t8133 +run/t8133b +run/t7475b.scala +run/t7445.scala +run/t6814 +run/t4577.scala +run/t5134.scala +run/t3452f.scala +run/t3452h.scala +run/t3452c.scala +run/t3452.scala +run/t261.scala +run/t3235-minimal.scala +run/t1503_future.scala +run/t5565.scala +pos/t8411 +pos/t8460.scala +run/t8428.scala +run/t8437 +run/absoverride.scala +run/arrays.scala +run/duration-coarsest.scala +run/iterator-from.scala +run/SymbolsTest.scala +run/t1074.scala +run/t1505.scala +run/streams.scala +run/t2111.scala +run/t4601.scala +pos/SI-4012-a.scala +pos/SI-7638.scala +neg/t3692-new.scala +run/t7015.scala +run/t7992b.scala +run/t7992.scala +run/t8570.scala +pos/t8157-2.10.scala +pos/t8325.scala +pos/t8523.scala +pos/t8578.scala +pos/t8329.scala +pos/t8497 +pos/t8546.scala +pos/t8531 +neg/t8325-c.scala +neg/t8325-b.scala +neg/t8325.scala +neg/t6988.scala +neg/t8463.scala +neg/t8450.scala +neg/t8430.scala +run/finally.scala +neg/t8630.scala +neg/t8035-no-adapted-args.scala +neg/t8675b.scala +neg/t8610-arg.scala +neg/t8736-c.scala +neg/tailrec-4.scala +neg/double-def-top-level +neg/t8610.scala +neg/aladdin1055 +neg/virtpatmat_exhaust_compound.scala +neg/t8675.scala +neg/t8525.scala +pos/t8736.scala +pos/t8625.scala +pos/t8596.scala +pos/t8617.scala +pos/t8736-b.scala +pos/t8708 +pos/macro-attachments +run/t8611a.scala +run/t8738.scala +run/macro-rangepos-args +run/t8610.scala +run/macro-rangepos-subpatterns +run/t8611c.scala +run/macroPlugins-isBlackbox +run/t8601d.scala +run/t8607.scala +run/bugs.scala +run/t1503.scala +run/t4148.scala +run/t7763.scala +run/issue192.scala +run/t8893b.scala +run/t8845.scala +run/t8933 +run/t7459c.scala +run/t9003.scala +run/t7459f.scala +run/t8933c.scala +run/t1994.scala +run/t2866.scala +run/t5665.scala +run/t7459d.scala +run/t8933b +run/t8888.scala +run/t7459b-optimize.scala +run/t7459a.scala +run/t7019.scala +run/t8893.scala +run/t8803.scala +run/t7459b.scala +run/nothingTypeNoFramesNoDce.scala +run/t8823.scala +run/sammy_repeated.scala +run/t6541.scala +run/nothingTypeDce.scala +run/t8680.scala +run/t8925.scala +run/nothingTypeNoOpt.scala +run/t9030.scala +run/bigDecimalTest.scala +run/bigDecimalCache.scala +run/range.scala +run/t6064.scala +run/t7269.scala +run/equality.scala +run/number-parsing.scala +run/t6220.scala +run/mapConserve.scala +run/colltest.scala +run/t0412.scala +run/t6261.scala +run/java-erasure.scala +run/t5880.scala +run/t6197.scala +run/t4201.scala +run/t5608.scala +run/t3518.scala +run/t6198.scala +run/t2813.2.scala +run/t9029b.scala +run/t9029c.scala +run/t7850c.scala +run/t7850d.scala +run/t9029.scala +run/t9387.scala +run/t9387b.scala +run/t9422.scala +run/t9425.scala +run/t9546.scala +run/t9546b.scala +run/t9546c.scala +run/t9546e.scala +run/t9546d.scala +run/t9567.scala +run/t9567b.scala +run/t9567c.scala +pos/t9442.scala +pos/t9369.scala +pos/existential-slow-compile1.scala +pos/t6666d.scala +pos/existental-slow-compile2.scala +pos/t9475.scala +pos/t9370 +pos/t9392 +pos/t9393 +neg/t8989.scala +neg/t8127a.scala +neg/t6895.scala +neg/t8892.scala +neg/missing-arg-list.scala +neg/t8777.scala +neg/t6895b.scala +neg/t9401.scala +neg/t9572.scala +neg/warn-unused-imports +neg/partestInvalidFlag.scala +pos/t2712-1.scala +pos/t2712-2.scala +pos/t2712-3.scala +pos/t2712-4.scala +pos/t2712-5.scala +pos/t2712-6.scala +pos/t2712-7.scala +pos/t10206.scala +pos/hkgadt.scala +pos/t9331.scala +pos/t6895b.scala +pos/t9245.scala +pos/t5683.scala +pos/t9630 +pos/userdefined_apply_poly_overload.scala +pos/t9399.scala +pos/t9411a.scala +pos/t8449 +pos/userdefined_apply.scala +pos/t9411b.scala +pos/t7046-2 +neg/t3236-neg +neg/t2712-1.scala +neg/t2712-2.scala +neg/t2712-3.scala +neg/t9834.scala +neg/t8763.scala +neg/userdefined_apply.scala +neg/t7046 +neg/t7046-2 +run/t10261 +run/t10037 +run/t7046-1 +run/t9806.scala +run/t9114.scala +run/t7046-2 + +# Adapt checkfiles for (1.0).toString == "1" +run/Course-2002-01.scala +run/t0421-new.scala +run/runtime.scala +run/t0421-old.scala +run/spec-self.scala +run/t5552.scala +run/Course-2002-02.scala +run/Course-2002-04.scala +run/promotion.scala +run/t4617.scala +run/Course-2002-09.scala +run/t5866.scala +run/try-catch-unify.scala +run/impconvtimes.scala +run/Course-2002-10.scala +run/Course-2002-08.scala +run/MeterCaseClass.scala +run/Meter.scala +run/deeps.scala +run/caseClassHash.scala +run/interpolation.scala +run/interpolationMultiline1.scala + +# Adapt checkfiles for ().toString == "undefined" +run/t5680.scala +run/dynamic-anyval.scala +run/macro-bundle-toplevel +run/macro-bundle-whitebox-decl +run/t6662 +run/t8570a.scala +run/t3702.scala +run/t7657 +run/macro-bundle-static +run/structural.scala + +# Adapt checkfiles for print & flush (which we cannot 100% emulate) +run/imports.scala +run/misc.scala + +# Adapt checkfiles for compiler phase list +run/t6102.scala +neg/t7494-no-options +neg/t6446-list +neg/t6446-missing +neg/t6446-show-phases.scala +neg/t6446-additional + +# Adapt checkfiles for different behavior with boxed types +run/t5568.scala +run/virtpatmat_typetag.scala +run/virtpatmat_switch.scala +run/t5629b.scala +run/t6318_primitives.scala +run/t8764.scala +run/t5356.scala + +# Difference in function specialization +run/delambdafy-specialized.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-additional.check new file mode 100644 index 0000000000..3c72fe21c0 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-additional.check @@ -0,0 +1,31 @@ + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + tailcalls 13 replace tail calls by jumps + specialize 14 @specialized-driven class and method specialization + explicitouter 15 this refs to outer pointers + erasure 16 erase types, add interfaces for traits + posterasure 17 clean up erased inline classes + lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + icode 26 generate portable intermediate code + jvm 27 generate JVM bytecode + ploogin 28 A sample phase that does so many things it's kind of hard... + terminal 29 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-list.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-list.check new file mode 100644 index 0000000000..95883c8c81 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-list.check @@ -0,0 +1,2 @@ +ploogin - A sample plugin for testing. +scalajs - Compile to JavaScript diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-missing.check new file mode 100644 index 0000000000..4761e1f032 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-missing.check @@ -0,0 +1,31 @@ +Error: unable to load class: t6446.Ploogin + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + tailcalls 13 replace tail calls by jumps + specialize 14 @specialized-driven class and method specialization + explicitouter 15 this refs to outer pointers + erasure 16 erase types, add interfaces for traits + posterasure 17 clean up erased inline classes + lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + icode 26 generate portable intermediate code + jvm 27 generate JVM bytecode + terminal 28 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-show-phases.check new file mode 100644 index 0000000000..28b57055a3 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-show-phases.check @@ -0,0 +1,30 @@ + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + tailcalls 13 replace tail calls by jumps + specialize 14 @specialized-driven class and method specialization + explicitouter 15 this refs to outer pointers + erasure 16 erase types, add interfaces for traits + posterasure 17 clean up erased inline classes + lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + icode 26 generate portable intermediate code + jvm 27 generate JVM bytecode + terminal 28 the last phase during a compilation run \ No newline at end of file diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t7494-no-options.check new file mode 100644 index 0000000000..fa3cdc9193 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t7494-no-options.check @@ -0,0 +1,32 @@ +error: Error: ploogin takes no options + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + tailcalls 13 replace tail calls by jumps + specialize 14 @specialized-driven class and method specialization + explicitouter 15 this refs to outer pointers + erasure 16 erase types, add interfaces for traits + posterasure 17 clean up erased inline classes + lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + icode 26 generate portable intermediate code + jvm 27 generate JVM bytecode + ploogin 28 A sample phase that does so many things it's kind of hard... + terminal 29 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Course-2002-01.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Course-2002-01.check new file mode 100644 index 0000000000..fcda9433de --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Course-2002-01.check @@ -0,0 +1,37 @@ +Course-2002-01.scala:41: warning: method loop in object M0 does nothing other than call itself recursively + def loop: Int = loop; + ^ +232 +667 +11 +10 +62.8318 +62.8318 +62.8318 +4 +81 +256 +25 +1 +737 +1 +0 +1 +76 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +sqrt(2) = 1.4142135623746899 +sqrt(2) = 1.4142135623746899 +cbrt(2) = 1.2599210500177698 +1 +1 1 +1 2 1 +1 3 3 1 +1 4 6 4 1 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Course-2002-02.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Course-2002-02.check new file mode 100644 index 0000000000..ab75cfdb61 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Course-2002-02.check @@ -0,0 +1,187 @@ +7 +120 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +pi = 3.181104885577714 +pi = 3.181104885577714 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 +pi = 3.181104885577714 +pi = 3.181104885577714 + +1.5 +1.4166666666666665 +1.4142156862745097 +1.4142135623746899 +sqrt(2) = 1.4142135623746899 + +1.5 +1.4166666666666665 +1.4142156862745097 +1.4142135623746899 +sqrt(2) = 1.4142135623746899 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +power(0,0) = 1 +power(0,1) = 0 +power(0,2) = 0 +power(0,3) = 0 +power(0,4) = 0 +power(0,5) = 0 +power(0,6) = 0 +power(0,7) = 0 +power(0,8) = 0 + +power(1,0) = 1 +power(1,1) = 1 +power(1,2) = 1 +power(1,3) = 1 +power(1,4) = 1 +power(1,5) = 1 +power(1,6) = 1 +power(1,7) = 1 +power(1,8) = 1 + +power(2,0) = 1 +power(2,1) = 2 +power(2,2) = 4 +power(2,3) = 8 +power(2,4) = 16 +power(2,5) = 32 +power(2,6) = 64 +power(2,7) = 128 +power(2,8) = 256 + +power(3,0) = 1 +power(3,1) = 3 +power(3,2) = 9 +power(3,3) = 27 +power(3,4) = 81 +power(3,5) = 243 +power(3,6) = 729 +power(3,7) = 2187 +power(3,8) = 6561 + +power(4,0) = 1 +power(4,1) = 4 +power(4,2) = 16 +power(4,3) = 64 +power(4,4) = 256 +power(4,5) = 1024 +power(4,6) = 4096 +power(4,7) = 16384 +power(4,8) = 65536 + +power(5,0) = 1 +power(5,1) = 5 +power(5,2) = 25 +power(5,3) = 125 +power(5,4) = 625 +power(5,5) = 3125 +power(5,6) = 15625 +power(5,7) = 78125 +power(5,8) = 390625 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Course-2002-04.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Course-2002-04.check new file mode 100644 index 0000000000..fc6ad96eed --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Course-2002-04.check @@ -0,0 +1,64 @@ +list0 = List(6, 3, 1, 8, 7, 1, 2, 5, 8, 4, 3, 4, 8) +list1 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list2 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list3 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list4 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list5 = List(8, 8, 8, 7, 6, 5, 4, 4, 3, 3, 2, 1, 1) +list6 = List(8, 8, 8, 7, 6, 5, 4, 4, 3, 3, 2, 1, 1) + +list0: List() -> List() +list1: List(0) -> List(0) +list2: List(0, 1) -> List(0, 1) +list3: List(1, 0) -> List(0, 1) +list4: List(0, 1, 2) -> List(0, 1, 2) +list5: List(1, 0, 2) -> List(0, 1, 2) +list6: List(0, 1, 2) -> List(0, 1, 2) +list7: List(1, 0, 2) -> List(0, 1, 2) +list8: List(2, 0, 1) -> List(0, 1, 2) +list9: List(2, 1, 0) -> List(0, 1, 2) +listA: List(6, 3, 1, 8, 7, 1, 2, 5, 8, 4) -> List(1, 1, 2, 3, 4, 5, 6, 7, 8, 8) + +f(x) = 5x^3+7x^2+5x+9 +f(0) = 9 +f(1) = 26 +f(2) = 87 +f(3) = 222 + +v1 = List(2, 3, 4) +v2 = List(6, 7, 8) + +id = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +m1 = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m2 = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) + +v1 * v1 = 29 +v1 * v2 = 65 +v2 * v1 = 65 +v1 * v2 = 65 + +id * v1 = List(2, 3, 4) +m1 * v1 = List(4, 6, 8) +m2 * v1 = List(20, 47, 74) + +trn(id) = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +trn(m1) = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +trn(m2) = List(List(1, 4, 7), List(2, 5, 8), List(3, 6, 9)) + +List(v1) * id = List(List(2, 3, 4)) +List(v1) * m1 = List(List(4, 6, 8)) +List(v1) * m2 = List(List(42, 51, 60)) + +id * List(v1) = List(List(2, 3, 4), List(0, 0, 0), List(0, 0, 0)) +m1 * List(v1) = List(List(4, 6, 8), List(0, 0, 0), List(0, 0, 0)) +m2 * List(v1) = List(List(2, 3, 4), List(8, 12, 16), List(14, 21, 28)) + +id * id = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +id * m1 = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m1 * id = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m1 * m1 = List(List(4, 0, 0), List(0, 4, 0), List(0, 0, 4)) +id * m2 = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) +m2 * id = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) +m1 * m2 = List(List(2, 4, 6), List(8, 10, 12), List(14, 16, 18)) +m2 * m1 = List(List(2, 4, 6), List(8, 10, 12), List(14, 16, 18)) +m2 * m2 = List(List(30, 36, 42), List(66, 81, 96), List(102, 126, 150)) + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Course-2002-08.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Course-2002-08.check new file mode 100644 index 0000000000..0585d5b44f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Course-2002-08.check @@ -0,0 +1,171 @@ +x = abc +count = 111 +x = hello +count = 112 + +account deposit 50 -> undefined +account withdraw 20 -> 30 +account withdraw 20 -> 10 +account withdraw 15 -> + +x deposit 30 -> undefined +y withdraw 20 -> + +x deposit 30 -> undefined +x withdraw 20 -> 10 + +x deposit 30 -> undefined +y withdraw 20 -> 10 + +2^0 = 1 +2^1 = 2 +2^2 = 4 +2^3 = 8 + +2^0 = 1 +2^1 = 2 +2^2 = 4 +2^3 = 8 + +1 2 3 +List(1, 2, 3) + +out 0 new-value = false +*** simulation started *** +out 1 new-value = true +!0 = 1 + +*** simulation started *** +out 2 new-value = false +!1 = 0 + +out 2 new-value = false + +*** simulation started *** +0 & 0 = 0 + +*** simulation started *** +0 & 1 = 0 + +*** simulation started *** +out 11 new-value = true +out 11 new-value = false +1 & 0 = 0 + +*** simulation started *** +out 14 new-value = true +1 & 1 = 1 + +out 14 new-value = false + +*** simulation started *** +0 | 0 = 0 + +*** simulation started *** +out 24 new-value = true +0 | 1 = 1 + +*** simulation started *** +1 | 0 = 1 + +*** simulation started *** +1 | 1 = 1 + +sum 34 new-value = false +carry 34 new-value = false + +*** simulation started *** +0 + 0 = 0 + +*** simulation started *** +sum 47 new-value = true +0 + 1 = 1 + +*** simulation started *** +carry 50 new-value = true +carry 50 new-value = false +sum 54 new-value = false +sum 54 new-value = true +1 + 0 = 1 + +*** simulation started *** +carry 57 new-value = true +sum 61 new-value = false +1 + 1 = 2 + +sum 61 new-value = false +carry 61 new-value = false + +*** simulation started *** +0 + 0 + 0 = 0 + +*** simulation started *** +sum 82 new-value = true +0 + 0 + 1 = 1 + +*** simulation started *** +sum 89 new-value = false +carry 90 new-value = true +sum 97 new-value = true +carry 98 new-value = false +0 + 1 + 0 = 1 + +*** simulation started *** +sum 113 new-value = false +carry 114 new-value = true +0 + 1 + 1 = 2 + +*** simulation started *** +sum 121 new-value = true +carry 122 new-value = false +sum 129 new-value = false +sum 129 new-value = true +1 + 0 + 0 = 1 + +*** simulation started *** +carry 137 new-value = true +sum 144 new-value = false +1 + 0 + 1 = 2 + +*** simulation started *** +carry 152 new-value = false +sum 152 new-value = true +sum 158 new-value = false +carry 159 new-value = true +1 + 1 + 0 = 2 + +*** simulation started *** +sum 173 new-value = true +1 + 1 + 1 = 3 + +in 0 new-value = false +ctrl0 0 new-value = false +ctrl1 0 new-value = false +ctrl2 0 new-value = false +out0 0 new-value = false +out1 0 new-value = false +out2 0 new-value = false +out3 0 new-value = false +out4 0 new-value = false +out5 0 new-value = false +out6 0 new-value = false +out7 0 new-value = false +in 0 new-value = true +*** simulation started *** +out0 10 new-value = true +ctrl0 10 new-value = true +*** simulation started *** +out1 13 new-value = true +out0 14 new-value = false +ctrl1 14 new-value = true +*** simulation started *** +out3 20 new-value = true +out1 21 new-value = false +ctrl2 21 new-value = true +*** simulation started *** +out7 30 new-value = true +out3 31 new-value = false +ctrl0 31 new-value = false +*** simulation started *** +out7 34 new-value = false +out6 35 new-value = true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Course-2002-09.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Course-2002-09.check new file mode 100644 index 0000000000..c921361db7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Course-2002-09.check @@ -0,0 +1,50 @@ +Probe: f = 32 +Probe: c = 0 +Probe: f = ? +Probe: c = ? + +Probe: f = 212 +Probe: c = 100 +Probe: f = ? +Probe: c = ? + +Probe: c = 0 +Probe: f = 32 +Probe: c = ? +Probe: f = ? + +Probe: c = 100 +Probe: f = 212 +Probe: c = ? +Probe: f = ? + +0 Celsius -> 32 Fahrenheits +100 Celsius -> 212 Fahrenheits +32 Fahrenheits -> 0 Celsius +212 Fahrenheits -> 100 Celsius + +a = ?, b = ?, c = ? => ? * ? = ? +a = 2, b = ?, c = ? => 2 * ? = ? +a = ?, b = 3, c = ? => ? * 3 = ? +a = ?, b = ?, c = 6 => ? * ? = 6 +a = 2, b = 3, c = ? => 2 * 3 = 6 +a = 2, b = ?, c = 6 => 2 * 3 = 6 +a = ?, b = 3, c = 6 => 2 * 3 = 6 +a = 2, b = 3, c = 6 => 2 * 3 = 6 + +a = 0, b = ?, c = ? => 0 * ? = 0 +a = ?, b = 0, c = ? => ? * 0 = 0 +a = ?, b = ?, c = 0 => ? * ? = 0 +a = 0, b = 7, c = ? => 0 * 7 = 0 +a = 7, b = 0, c = ? => 7 * 0 = 0 +a = 0, b = 0, c = ? => 0 * 0 = 0 +a = 0, b = ?, c = 0 => 0 * ? = 0 +a = ?, b = 0, c = 0 => ? * 0 = 0 +a = 0, b = 7, c = 0 => 0 * 7 = 0 +a = 7, b = 0, c = 0 => 7 * 0 = 0 +a = 0, b = 0, c = 0 => 0 * 0 = 0 + +a = 3, b = 4 => c = 5 +a = 3, c = 5 => b = 4 +b = 4, c = 5 => a = 3 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Course-2002-10.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Course-2002-10.check new file mode 100644 index 0000000000..847f0fa703 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Course-2002-10.check @@ -0,0 +1,46 @@ +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +fib(10) = 55 +fib(11) = 89 +fib(12) = 144 +fib(13) = 233 +fib(14) = 377 +fib(15) = 610 +fib(16) = 987 +fib(17) = 1597 +fib(18) = 2584 +fib(19) = 4181 + +pi(0) = 4 , 3.166666666666667 , 4 +pi(1) = 2.666666666666667 , 3.1333333333333337, 3.166666666666667 +pi(2) = 3.466666666666667 , 3.1452380952380956, 3.142105263157895 +pi(3) = 2.8952380952380956, 3.1396825396825396, 3.1415993573190044 +pi(4) = 3.33968253968254 , 3.142712842712843 , 3.141592714033778 +pi(5) = 2.976046176046176 , 3.140881340881341 , 3.1415926539752923 +pi(6) = 3.283738483738484 , 3.142071817071817 , 3.141592653591176 +pi(7) = 3.017071817071817 , 3.1412548236077646, 3.141592653589777 +pi(8) = 3.252365934718876 , 3.1418396189294024, 3.141592653589794 +pi(9) = 3.0418396189294024, 3.141406718496502 , 3.1415926535897936 +pi = 3.141592653589793 , 3.141592653589793 , 3.141592653589793 + +ln(0) = 1 , 0.7 , 1 +ln(1) = 0.5 , 0.6904761904761905, 0.7 +ln(2) = 0.8333333333333333, 0.6944444444444444, 0.6932773109243697 +ln(3) = 0.5833333333333333, 0.6924242424242424, 0.6931488693329254 +ln(4) = 0.7833333333333333, 0.6935897435897436, 0.6931471960735491 +ln(5) = 0.6166666666666667, 0.6928571428571428, 0.6931471806635636 +ln(6) = 0.7595238095238095, 0.6933473389355742, 0.6931471805604038 +ln(7) = 0.6345238095238095, 0.6930033416875522, 0.6931471805599444 +ln(8) = 0.7456349206349207, 0.6932539682539682, 0.6931471805599426 +ln(9) = 0.6456349206349206, 0.6930657506744463, 0.6931471805599453 +ln = 0.6931471805599453, 0.6931471805599453, 0.6931471805599453 + +prime numbers: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Meter.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Meter.check new file mode 100644 index 0000000000..f46fd557c8 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/Meter.check @@ -0,0 +1,16 @@ +Meter.scala:72: warning: a.Meter and Int are unrelated: they will never compare equal + println("x == 1: "+(x == 1)) + ^ +2 +4m +false +x.isInstanceOf[Meter]: true +x.hashCode: 1 +x == 1: false +x == y: true +a == b: true +testing native arrays +Array(1m, 2m) +1m +>>>1m<<< 1m +>>>2m<<< 2m diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/MeterCaseClass.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/MeterCaseClass.check new file mode 100644 index 0000000000..ac538d240f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/MeterCaseClass.check @@ -0,0 +1,16 @@ +MeterCaseClass.scala:69: warning: comparing values of types a.Meter and Int using `==' will always yield false + println("x == 1: "+(x == 1)) + ^ +2 +Meter(4) +false +x.isInstanceOf[Meter]: true +x.hashCode: 1 +x == 1: false +x == y: true +a == b: true +testing native arrays +Array(Meter(1), Meter(2)) +Meter(1) +>>>Meter(1)<<< Meter(1) +>>>Meter(2)<<< Meter(2) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/bugs.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/bugs.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/bugs.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/caseClassHash.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/caseClassHash.check new file mode 100644 index 0000000000..f975151e9c --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/caseClassHash.check @@ -0,0 +1,9 @@ +Foo(true,-1,-1,d,-5,-10,500,500,List(),5) +Foo(true,-1,-1,d,-5,-10,500,500,List(),5) +1383698062 +1383698062 +true +## method 1: 1383698062 +## method 2: 1383698062 + Murmur 1: 1383698062 + Murmur 2: 1383698062 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/deeps.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/deeps.check new file mode 100644 index 0000000000..e533b87dc5 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/deeps.check @@ -0,0 +1,87 @@ +testEquals1 +false +false +true + +testEquals2 +false +false +true + +testEquals3 +x=Array(1) +y=Array(1) +false +false +true + +x=Array(Array(1), Array(1)) +y=Array(Array(1), Array(1)) +false +false +true + +x=Array(Array(Array(1), Array(1)), Array(Array(1), Array(1))) +y=Array(Array(Array(1), Array(1)), Array(Array(1), Array(1))) +false +false +true + +testEquals4 +false +false +true +false +false +true +Array(true, false) +Array(true, false) +[true;false] +true;false + +Array(Array(true, false), Array(true, false)) +Array(Array(true, false), Array(true, false)) +[Array(true, false);Array(true, false)] +Array(true, false);Array(true, false) + +Array(Array(Array(true, false), Array(true, false)), Array(Array(true, false), Array(true, false))) +Array(Array(Array(true, false), Array(true, false)), Array(Array(true, false), Array(true, false))) +[Array(Array(true, false), Array(true, false));Array(Array(true, false), Array(true, false))] +Array(Array(true, false), Array(true, false));Array(Array(true, false), Array(true, false)) + +Array(1, 0) +Array(1, 0) +[1;0] +1;0 + +Array(Array(1, 0), Array(1, 0)) +Array(Array(1, 0), Array(1, 0)) +[Array(1, 0);Array(1, 0)] +Array(1, 0);Array(1, 0) + +Array(Array(Array(1, 0), Array(1, 0)), Array(Array(1, 0), Array(1, 0))) +Array(Array(Array(1, 0), Array(1, 0)), Array(Array(1, 0), Array(1, 0))) +[Array(Array(1, 0), Array(1, 0));Array(Array(1, 0), Array(1, 0))] +Array(Array(1, 0), Array(1, 0));Array(Array(1, 0), Array(1, 0)) + +Array(a, b) +Array(a, b) +[a;b] +a;b + +Array(Array(a, b), Array(a, b)) +Array(Array(a, b), Array(a, b)) +[Array(a, b);Array(a, b)] +Array(a, b);Array(a, b) + +Array(Array(Array(a, b), Array(a, b)), Array(Array(a, b), Array(a, b))) +Array(Array(Array(a, b), Array(a, b)), Array(Array(a, b), Array(a, b))) +[Array(Array(a, b), Array(a, b));Array(Array(a, b), Array(a, b))] +Array(Array(a, b), Array(a, b));Array(Array(a, b), Array(a, b)) + +[Array(true, false); Array(false)] +[Array(1, 2); Array(3)] +[Array(1, 2); Array(3)] + +Array(boo, and, foo) +Array(a) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/delambdafy-specialized.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/delambdafy-specialized.check new file mode 100644 index 0000000000..a20ad22303 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/delambdafy-specialized.check @@ -0,0 +1 @@ +scala.runtime.AbstractFunction1 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/dynamic-anyval.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/dynamic-anyval.check new file mode 100644 index 0000000000..c125372c9a --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/dynamic-anyval.check @@ -0,0 +1,4 @@ +undefined.dingo(bippy, 5) +List(1, 2, 3).dingo(bippy, 5) +undefined.dingo(bippy, 5) +List(1, 2, 3).dingo(bippy, 5) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/impconvtimes.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/impconvtimes.check new file mode 100644 index 0000000000..082377e474 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/impconvtimes.check @@ -0,0 +1 @@ +3.0 * Hour = Measure(3,Hour) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/imports.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/imports.check new file mode 100644 index 0000000000..1aad598062 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/imports.check @@ -0,0 +1,21 @@ +In C_ico, v_ico .toString() returns ↩ +↪C_ico -> ok +In C_ico, field .toString() returns ↩ +↪C_ico -> ok +In C_ico, method.toString() returns ↩ +↪C_ico -> ok + +In C_ioc, v_ioc .toString() returns ↩ +↪C_ioc -> ok +In C_ioc, field .toString() returns ↩ +↪C_ioc -> ok +In C_ioc, method.toString() returns ↩ +↪C_ioc -> ok + +In C_oic, v_oic .toString() returns ↩ +↪C_oic -> ok +In C_oic, field .toString() returns ↩ +↪C_oic -> ok +In C_oic, method.toString() returns ↩ +↪C_oic -> ok + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/interpolation.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/interpolation.check new file mode 100644 index 0000000000..9c4a77715b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/interpolation.check @@ -0,0 +1,32 @@ +Bob is 1 years old +Bob is 1 years old +Bob will be 2 years old +Bob will be 2 years old +1+1 = 2 +1+1 = 2 +Bob is 12 years old +Bob is 12 years old +Bob will be 13 years old +Bob will be 13 years old +12+1 = 13 +12+1 = 13 +Bob is 123 years old +Bob is 123 years old +Bob will be 124 years old +Bob will be 124 years old +123+1 = 124 +123+1 = 124 +Best price: 10 +Best price: 10.00 +10% discount included +10.00% discount included +Best price: 13.345000267028809 +Best price: 13.35 +13.345000267028809% discount included +13.35% discount included + +0 +00 + +0 +00 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/interpolationMultiline1.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/interpolationMultiline1.check new file mode 100644 index 0000000000..1b6e140c13 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/interpolationMultiline1.check @@ -0,0 +1,26 @@ +Bob is 1 years old +Bob is 1 years old +Bob will be 2 years old +Bob will be 2 years old +1+1 = 2 +1+1 = 2 +Bob is 12 years old +Bob is 12 years old +Bob will be 13 years old +Bob will be 13 years old +12+1 = 13 +12+1 = 13 +Bob is 123 years old +Bob is 123 years old +Bob will be 124 years old +Bob will be 124 years old +123+1 = 124 +123+1 = 124 +Best price: 10 +Best price: 10.00 +10% discount included +10.00% discount included +Best price: 13.345000267028809 +Best price: 13.35 +13.345000267028809% discount included +13.35% discount included diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/issue192.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/issue192.sem new file mode 100644 index 0000000000..10abbf7f3b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/issue192.sem @@ -0,0 +1 @@ +strictFloats diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/macro-bundle-static.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/macro-bundle-static.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/macro-bundle-static.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/macro-bundle-toplevel.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/macro-bundle-toplevel.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/macro-bundle-toplevel.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/macro-bundle-whitebox-decl.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/macro-bundle-whitebox-decl.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/macro-bundle-whitebox-decl.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/misc.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/misc.check new file mode 100644 index 0000000000..6043817dbc --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/misc.check @@ -0,0 +1,62 @@ +misc.scala:46: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses + 42; + ^ +misc.scala:47: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses + 42l; + ^ +misc.scala:48: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses + 23.5f; + ^ +misc.scala:49: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses + 23.5; + ^ +misc.scala:50: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses + "Hello"; + ^ +misc.scala:51: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses + 32 + 45; + ^ +misc.scala:62: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses + x; + ^ +misc.scala:74: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses + 1 < 2; + ^ +### Hello +### 17 +### Bye + +### fib(0) = ↩ +↪1 +### fib(1) = ↩ +↪1 +### fib(2) = ↩ +↪2 +### fib(3) = ↩ +↪3 +### fib(4) = ↩ +↪5 +=== MyClass::toString === +=== MySubclass::toString === +=== MyClass::test === + +identity + +A.a = 1 +B.a = 5 +B.b = 2 + +X.a = 4 +Y.a = 11 +Y.b = 5 +Y.b = 5 + +X::foo + +Y::foo +X::foo + +3 +3 + +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/promotion.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/promotion.check new file mode 100644 index 0000000000..41e36c369d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/promotion.check @@ -0,0 +1,4 @@ +2 +6 +20 +30 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/runtime.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/runtime.check new file mode 100644 index 0000000000..0450b9498a --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/runtime.check @@ -0,0 +1,70 @@ +runtime.scala:141: warning: comparing values of types Null and Null using `eq' will always yield true + check(true , null eq null, null ne null); + ^ +runtime.scala:141: warning: comparing values of types Null and Null using `ne' will always yield false + check(true , null eq null, null ne null); + ^ +<<< Test0 +[false,true] +[0,1,2] +[3,4,5] +[a,b,c] +[6,7,8] +[9,10,11] +[12,13] +[14,15] +[string] +>>> Test0 + +<<< Test1 +10 +14 +15 +16 +20 +23 +24 +25 +26 +>>> Test1 + +<<< Test2 +A +M0 +N0 + +A +N0 +M0 + +A +M0 +M1 +N0 + +A +N0 +N1 +M0 + +>>> Test2 + +<<< Test3 +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +>>> Test3 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/spec-self.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/spec-self.check new file mode 100644 index 0000000000..fd3c81a4d7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/spec-self.check @@ -0,0 +1,2 @@ +5 +5 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/structural.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/structural.check new file mode 100644 index 0000000000..2fec112a87 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/structural.check @@ -0,0 +1,37 @@ + 1. hey + 2. 11 + 3. dee + 4. iei + 5. 6 + 6. 51 + 7. 2 + 8. 11 +10. 12 +11. eitch +12. 1 +13. ohone +14. 1 +15. undefined +16. one +17. tieone +18. 2 +19. true +20. 1 +21. undefined +22. one +23. oy +24. 1 +25. null +26. iei +31. 4 +32. undefined +33. iei +33. tieone +1 +2 +3 +4 +5 +caught +3 +2 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t0421-new.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t0421-new.check new file mode 100644 index 0000000000..00d29b7e5b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t0421-new.check @@ -0,0 +1,3 @@ +[Array(0, 1),Array(2, 3),Array(4, 5)] +[Array(31)] +[Array(24, 32)] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t0421-old.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t0421-old.check new file mode 100644 index 0000000000..00d29b7e5b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t0421-old.check @@ -0,0 +1,3 @@ +[Array(0, 1),Array(2, 3),Array(4, 5)] +[Array(31)] +[Array(24, 32)] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t1503.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t1503.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t1503.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t3702.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t3702.check new file mode 100644 index 0000000000..3fce98715c --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t3702.check @@ -0,0 +1,2 @@ +undefined +6 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t4148.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t4148.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t4148.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t4617.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t4617.check new file mode 100644 index 0000000000..a6790f16f7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t4617.check @@ -0,0 +1 @@ +Str 8 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t5356.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t5356.check new file mode 100644 index 0000000000..870c901131 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t5356.check @@ -0,0 +1,6 @@ +1 java.lang.Byte +1 java.lang.Byte +1 scala.math.BigInt +1 java.lang.Byte +1 java.lang.Byte +1 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t5552.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t5552.check new file mode 100644 index 0000000000..4704611116 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t5552.check @@ -0,0 +1,2 @@ +(3,3) +(3,3) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t5568.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t5568.check new file mode 100644 index 0000000000..6f30cc5070 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t5568.check @@ -0,0 +1,9 @@ +void +int +class scala.runtime.BoxedUnit +class scala.runtime.BoxedUnit +class java.lang.Byte +class java.lang.Byte +5 +5 +5 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t5629b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t5629b.check new file mode 100644 index 0000000000..c65298a6ce --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t5629b.check @@ -0,0 +1,10 @@ +=== pf(1): +MySmartPF.apply entered... +newPF.applyOrElse entered... +default +scala.MatchError: 1 (of class java.lang.Byte) +=== pf(42): +MySmartPF.apply entered... +newPF.applyOrElse entered... +ok +=== done diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t5680.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t5680.check new file mode 100644 index 0000000000..a3b8b64a43 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t5680.check @@ -0,0 +1,3 @@ +[Lscala.runtime.BoxedUnit +undefined +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t5866.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t5866.check new file mode 100644 index 0000000000..64df1cec7f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t5866.check @@ -0,0 +1,2 @@ +0 +Foo(0) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t6102.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t6102.check new file mode 100644 index 0000000000..3082267832 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t6102.check @@ -0,0 +1,28 @@ +[running phase parser on t6102.scala] +[running phase jspretyper on t6102.scala] +[running phase namer on t6102.scala] +[running phase packageobjects on t6102.scala] +[running phase typer on t6102.scala] +[running phase jsinterop on t6102.scala] +[running phase patmat on t6102.scala] +[running phase superaccessors on t6102.scala] +[running phase extmethods on t6102.scala] +[running phase pickler on t6102.scala] +[running phase refchecks on t6102.scala] +[running phase uncurry on t6102.scala] +[running phase tailcalls on t6102.scala] +[running phase specialize on t6102.scala] +[running phase explicitouter on t6102.scala] +[running phase erasure on t6102.scala] +[running phase posterasure on t6102.scala] +[running phase lazyvals on t6102.scala] +[running phase lambdalift on t6102.scala] +[running phase constructors on t6102.scala] +[running phase flatten on t6102.scala] +[running phase mixin on t6102.scala] +[running phase jscode on t6102.scala] +[running phase cleanup on t6102.scala] +[running phase delambdafy on t6102.scala] +[running phase icode on t6102.scala] +[running phase dce on t6102.scala] +[running phase jvm on icode] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t6318_primitives.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t6318_primitives.check new file mode 100644 index 0000000000..654ef1beec --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t6318_primitives.check @@ -0,0 +1,54 @@ +Checking if byte matches byte +Some(1) +Checking if byte matches short +Some(1) +Checking if class java.lang.Byte matches byte +Some(1) +Checking if short matches short +Some(1) +Checking if short matches char +None +Checking if class java.lang.Byte matches short +Some(1) +Checking if char matches char +Some() +Checking if char matches int +None +Checking if class java.lang.Character matches char +Some() +Checking if int matches int +Some(1) +Checking if int matches long +None +Checking if class java.lang.Byte matches int +Some(1) +Checking if long matches long +Some(1) +Checking if long matches float +None +Checking if class java.lang.Long matches long +Some(1) +Checking if float matches float +Some(1) +Checking if float matches double +Some(1) +Checking if class java.lang.Byte matches float +Some(1) +Checking if double matches double +Some(1) +Checking if double matches boolean +None +Checking if class java.lang.Byte matches double +Some(1) +Checking if boolean matches boolean +Some(true) +Checking if boolean matches void +None +Checking if class java.lang.Boolean matches boolean +Some(true) +Checking if void matches void +Some(undefined) +Checking if void matches byte +None +Checking if class scala.runtime.BoxedUnit matches void +Some(undefined) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t6662.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t6662.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t6662.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t7657.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t7657.check new file mode 100644 index 0000000000..1a87c1e866 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t7657.check @@ -0,0 +1,3 @@ +undefined +undefined +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t7763.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t7763.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t7763.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t8570a.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t8570a.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t8570a.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t8764.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t8764.check new file mode 100644 index 0000000000..121120217e --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t8764.check @@ -0,0 +1,5 @@ +IntOnly: should return an unboxed int +Int: int +IntAndDouble: should just box and return Anyval +Double: class java.lang.Byte +Int: class java.lang.Byte diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t9387b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t9387b.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t9387b.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/try-catch-unify.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/try-catch-unify.check new file mode 100644 index 0000000000..813f01166d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/try-catch-unify.check @@ -0,0 +1,4 @@ +Failure(java.lang.NumberFormatException: For input string: "Hi") +Success(5) +O NOES +Failure(java.lang.NumberFormatException: For input string: "Hi") diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/virtpatmat_switch.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/virtpatmat_switch.check new file mode 100644 index 0000000000..0900a9ca32 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/virtpatmat_switch.check @@ -0,0 +1,7 @@ +zero +one +many +got a +got b +got some letter +scala.MatchError: 5 (of class java.lang.Byte) \ No newline at end of file diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/virtpatmat_typetag.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/virtpatmat_typetag.check new file mode 100644 index 0000000000..048c3aeed0 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/virtpatmat_typetag.check @@ -0,0 +1,10 @@ +1 is a Int +1 is a java.lang.Integer +1 is not a java.lang.String; it's a class java.lang.Byte +true is a Any +woele is a java.lang.String +1 is a Int +1 is a java.lang.Integer +1 is not a java.lang.String; it's a class java.lang.Byte +true is a Any +woele is a java.lang.String diff --git a/project/Build.scala b/project/Build.scala index c30d40b6a1..637cb78f07 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -63,7 +63,7 @@ object Build { CrossVersion.binaryMapped(v => s"sjs${previousSJSBinaryVersion}_$v") val scalaVersionsUsedForPublishing: Set[String] = - Set("2.10.6", "2.11.8", "2.12.1") + Set("2.10.6", "2.11.11", "2.12.1") val newScalaBinaryVersionsInThisRelease: Set[String] = Set() @@ -117,7 +117,7 @@ object Build { } val commonSettings = Seq( - scalaVersion := "2.11.8", + scalaVersion := "2.11.11", organization := "org.scala-js", version := scalaJSVersion, @@ -425,6 +425,7 @@ object Build { "2.11.6", "2.11.7", "2.11.8", + "2.11.11", "2.12.0", "2.12.1" ), diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index dd51eb23d3..ef8a62a4f5 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -6,7 +6,7 @@ version := scalaJSVersion val versionSettings = Seq( version := scalaJSVersion, - scalaVersion := "2.11.8" + scalaVersion := "2.11.11" ) val baseSettings = versionSettings ++ Seq( diff --git a/scala-test-suite/src/test/resources/2.11.11/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.11.11/BlacklistedTests.txt new file mode 100644 index 0000000000..cdd52e55b1 --- /dev/null +++ b/scala-test-suite/src/test/resources/2.11.11/BlacklistedTests.txt @@ -0,0 +1,96 @@ +# Do not compile +scala/issues/BytecodeTests.scala +scala/reflect/QTest.scala +scala/reflect/io/ZipArchiveTest.scala +scala/reflect/internal/util/AbstractFileClassLoaderTest.scala +scala/reflect/internal/util/SourceFileTest.scala +scala/reflect/internal/util/StringOpsTest.scala +scala/reflect/internal/PrintersTest.scala +scala/reflect/internal/ScopeTest.scala +scala/reflect/internal/TypesTest.scala +scala/reflect/internal/util/WeakHashSetTest.scala +scala/reflect/internal/MirrorsTest.scala +scala/reflect/internal/NamesTest.scala +scala/tools/nsc/ScriptRunnerTest.scala +scala/tools/nsc/backend/jvm/BTypesTest.scala +scala/tools/nsc/backend/jvm/CodeGenTools.scala +scala/tools/nsc/backend/jvm/DirectCompileTest.scala +scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala +scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala +scala/tools/nsc/backend/jvm/opt/BTypesFromClassfileTest.scala +scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala +scala/tools/nsc/backend/jvm/opt/CompactLocalVariablesTest.scala +scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala +scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala +scala/tools/nsc/backend/jvm/opt/InlineInfoTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerIllegalAccessTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerTest.scala +scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala +scala/tools/nsc/backend/jvm/opt/MethodLevelOpts.scala +scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala +scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala +scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala +scala/tools/nsc/backend/jvm/opt/UnusedLocalVariablesTest.scala +scala/tools/nsc/classpath/AggregateFlatClassPathTest.scala +scala/tools/nsc/classpath/FlatClassPathResolverTest.scala +scala/tools/nsc/doc/html/HtmlDocletTest.scala +scala/tools/nsc/interpreter/CompletionTest.scala +scala/tools/nsc/interpreter/TabulatorTest.scala +scala/tools/nsc/settings/ScalaVersionTest.scala +scala/tools/nsc/settings/SettingsTest.scala +scala/tools/nsc/symtab/CannotHaveAttrsTest.scala +scala/tools/nsc/symtab/FlagsTest.scala +scala/tools/nsc/symtab/FreshNameExtractorTest.scala +scala/tools/nsc/symtab/StdNamesTest.scala +scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala +scala/tools/nsc/symtab/SymbolTableTest.scala +scala/tools/nsc/transform/delambdafy/DelambdafyTest.scala +scala/tools/nsc/transform/patmat/SolvingTest.scala +scala/tools/nsc/util/ClassPathImplComparator.scala +scala/tools/nsc/util/StackTraceTest.scala + +## Do not link +scala/StringContextTest.scala +scala/collection/IteratorTest.scala +scala/collection/ParallelConsistencyTest.scala +scala/collection/immutable/ListTest.scala +scala/collection/immutable/StringLikeTest.scala +scala/collection/mutable/ArrayBufferTest.scala +scala/collection/mutable/MutableListTest.scala +scala/collection/mutable/OpenHashMapTest.scala +scala/collection/mutable/PriorityQueueTest.scala +scala/concurrent/duration/SerializationTest.scala +scala/concurrent/impl/DefaultPromiseTest.scala +scala/io/SourceTest.scala +scala/runtime/ScalaRunTimeTest.scala +scala/tools/testing/AssertUtilTest.scala + +## Tests fail + +# Reflection +scala/reflect/ClassTag.scala +scala/tools/testing/AssertThrowsTest.scala + +# Regex +scala/util/matching/CharRegexTest.scala +scala/util/matching/RegexTest.scala + +# Require strict-floats +scala/math/BigDecimalTest.scala + +# Tests passed but are too slow (timeouts) +scala/collection/immutable/RangeConsistencyTest.scala +scala/collection/SetMapConsistencyTest.scala +scala/util/SortingTest.scala + +# Bugs +scala/collection/convert/MapWrapperTest.scala + +# Bug #2717 (ArrayBuilder needs to be reusable) +scala/collection/mutable/ArrayBuilderTest.scala + +# Test fails only some times with +# 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' +# and' 'set scalaJSUseRhino in Global := false' +scala/collection/immutable/PagedSeqTest.scala \ No newline at end of file diff --git a/scala-test-suite/src/test/resources/2.11.11/WhitelistedTests.txt b/scala-test-suite/src/test/resources/2.11.11/WhitelistedTests.txt new file mode 100644 index 0000000000..b59d7b5f4c --- /dev/null +++ b/scala-test-suite/src/test/resources/2.11.11/WhitelistedTests.txt @@ -0,0 +1,27 @@ +scala/collection/IndexedSeqOptimizedTest.scala +scala/collection/IndexedSeqTest.scala +scala/collection/IterableViewLikeTest.scala +scala/collection/SearchingTest.scala +scala/collection/TraversableOnceTest.scala +scala/collection/immutable/HashMapTest.scala +scala/collection/immutable/QueueTest.scala +scala/collection/immutable/SetTests.scala +scala/collection/immutable/TreeMapTest.scala +scala/collection/immutable/TreeSetTest.scala +scala/collection/immutable/VectorTest.scala +scala/collection/mutable/ArraySortingTest.scala +scala/collection/mutable/BitSetTest.scala +scala/collection/mutable/LinkedHashMapTest.scala +scala/collection/mutable/LinkedHashSetTest.scala +scala/collection/mutable/SetLikeTest.scala +scala/collection/mutable/UnrolledBufferTest.scala +scala/collection/mutable/VectorTest.scala +scala/collection/mutable/WrappedArrayBuilderTest.scala +scala/math/NumericTest.scala +scala/math/OrderingTest.scala +scala/tools/nsc/SampleTest.scala +scala/tools/testing/AssertUtil.scala +scala/tools/testing/TempDir.scala +scala/util/RandomTest.scala +scala/util/SpecVersionTest.scala +scala/util/TryTest.scala diff --git a/scalalib/overrides-2.11.11/scala/concurrent/impl/AbstractPromise.scala b/scalalib/overrides-2.11.11/scala/concurrent/impl/AbstractPromise.scala new file mode 100644 index 0000000000..bb1ae1a670 --- /dev/null +++ b/scalalib/overrides-2.11.11/scala/concurrent/impl/AbstractPromise.scala @@ -0,0 +1,11 @@ +package scala.concurrent.impl + +import java.util.concurrent.atomic.AtomicReference + +@Deprecated // Since 2.11.8. Extend java.util.concurrent.atomic.AtomicReference instead. +abstract class AbstractPromise extends AtomicReference[AnyRef] { + protected final def updateState(oldState: AnyRef, newState: AnyRef): Boolean = + compareAndSet(oldState, newState) + + protected final def getState(): AnyRef = get() +} diff --git a/scalalib/overrides-2.11.11/scala/reflect/ClassTag.scala b/scalalib/overrides-2.11.11/scala/reflect/ClassTag.scala new file mode 100644 index 0000000000..3c354a98da --- /dev/null +++ b/scalalib/overrides-2.11.11/scala/reflect/ClassTag.scala @@ -0,0 +1,163 @@ +package scala +package reflect + +import java.lang.{ Class => jClass } +import scala.language.{implicitConversions, existentials} +import scala.runtime.ScalaRunTime.{ arrayClass, arrayElementClass } + +/** + * + * A `ClassTag[T]` stores the erased class of a given type `T`, accessible via the `runtimeClass` + * field. This is particularly useful for instantiating `Array`s whose element types are unknown + * at compile time. + * + * `ClassTag`s are a weaker special case of [[scala.reflect.api.TypeTags#TypeTag]]s, in that they + * wrap only the runtime class of a given type, whereas a `TypeTag` contains all static type + * information. That is, `ClassTag`s are constructed from knowing only the top-level class of a + * type, without necessarily knowing all of its argument types. This runtime information is enough + * for runtime `Array` creation. + * + * For example: + * {{{ + * scala> def mkArray[T : ClassTag](elems: T*) = Array[T](elems: _*) + * mkArray: [T](elems: T*)(implicit evidence$1: scala.reflect.ClassTag[T])Array[T] + * + * scala> mkArray(42, 13) + * res0: Array[Int] = Array(42, 13) + * + * scala> mkArray("Japan","Brazil","Germany") + * res1: Array[String] = Array(Japan, Brazil, Germany) + * }}} + * + * See [[scala.reflect.api.TypeTags]] for more examples, or the + * [[http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html Reflection Guide: TypeTags]] + * for more details. + * + */ +@scala.annotation.implicitNotFound(msg = "No ClassTag available for ${T}") +trait ClassTag[T] extends ClassManifestDeprecatedApis[T] with Equals with Serializable { + // please, don't add any APIs here, like it was with `newWrappedArray` and `newArrayBuilder` + // class tags, and all tags in general, should be as minimalistic as possible + + /** A class representing the type `U` to which `T` would be erased. + * Note that there is no subtyping relationship between `T` and `U`. + */ + def runtimeClass: jClass[_] + + /** Produces a `ClassTag` that knows how to instantiate an `Array[Array[T]]` */ + def wrap: ClassTag[Array[T]] = ClassTag[Array[T]](arrayClass(runtimeClass)) + + /** Produces a new array with element type `T` and length `len` */ + override def newArray(len: Int): Array[T] = + runtimeClass match { + case java.lang.Byte.TYPE => new Array[Byte](len).asInstanceOf[Array[T]] + case java.lang.Short.TYPE => new Array[Short](len).asInstanceOf[Array[T]] + case java.lang.Character.TYPE => new Array[Char](len).asInstanceOf[Array[T]] + case java.lang.Integer.TYPE => new Array[Int](len).asInstanceOf[Array[T]] + case java.lang.Long.TYPE => new Array[Long](len).asInstanceOf[Array[T]] + case java.lang.Float.TYPE => new Array[Float](len).asInstanceOf[Array[T]] + case java.lang.Double.TYPE => new Array[Double](len).asInstanceOf[Array[T]] + case java.lang.Boolean.TYPE => new Array[Boolean](len).asInstanceOf[Array[T]] + case java.lang.Void.TYPE => new Array[Unit](len).asInstanceOf[Array[T]] + case _ => java.lang.reflect.Array.newInstance(runtimeClass, len).asInstanceOf[Array[T]] + } + + /** A ClassTag[T] can serve as an extractor that matches only objects of type T. + * + * The compiler tries to turn unchecked type tests in pattern matches into checked ones + * by wrapping a `(_: T)` type pattern as `ct(_: T)`, where `ct` is the `ClassTag[T]` instance. + * Type tests necessary before calling other extractors are treated similarly. + * `SomeExtractor(...)` is turned into `ct(SomeExtractor(...))` if `T` in `SomeExtractor.unapply(x: T)` + * is uncheckable, but we have an instance of `ClassTag[T]`. + */ + def unapply(x: Any): Option[T] = x match { + case null => None + case b: Byte => unapply(b) + case s: Short => unapply(s) + case c: Char => unapply(c) + case i: Int => unapply(i) + case l: Long => unapply(l) + case f: Float => unapply(f) + case d: Double => unapply(d) + case b: Boolean => unapply(b) + case u: Unit => unapply(u) + case a: Any => unapplyImpl(a) + } + + // TODO: Inline the bodies of these into the Any-accepting unapply overload above and delete them. + // This cannot be done until at least 2.12.0 for reasons of binary compatibility + def unapply(x: Byte) : Option[T] = unapplyImpl(x, classOf[Byte]) + def unapply(x: Short) : Option[T] = unapplyImpl(x, classOf[Short]) + def unapply(x: Char) : Option[T] = unapplyImpl(x, classOf[Char]) + def unapply(x: Int) : Option[T] = unapplyImpl(x, classOf[Int]) + def unapply(x: Long) : Option[T] = unapplyImpl(x, classOf[Long]) + def unapply(x: Float) : Option[T] = unapplyImpl(x, classOf[Float]) + def unapply(x: Double) : Option[T] = unapplyImpl(x, classOf[Double]) + def unapply(x: Boolean) : Option[T] = unapplyImpl(x, classOf[Boolean]) + def unapply(x: Unit) : Option[T] = unapplyImpl(x, classOf[Unit]) + + private[this] def unapplyImpl(x: Any, alternative: jClass[_] = null): Option[T] = { + val conforms = runtimeClass.isInstance(x) || (alternative != null && runtimeClass.isAssignableFrom(alternative)) + if (conforms) Some(x.asInstanceOf[T]) else None + } + + // case class accessories + override def canEqual(x: Any) = x.isInstanceOf[ClassTag[_]] + override def equals(x: Any) = x.isInstanceOf[ClassTag[_]] && this.runtimeClass == x.asInstanceOf[ClassTag[_]].runtimeClass + override def hashCode = scala.runtime.ScalaRunTime.hash(runtimeClass) + override def toString = { + def prettyprint(clazz: jClass[_]): String = + if (clazz.isArray) s"Array[${prettyprint(arrayElementClass(clazz))}]" else + clazz.getName + prettyprint(runtimeClass) + } +} + +/** + * Class tags corresponding to primitive types and constructor/extractor for ClassTags. + */ +object ClassTag { + def Byte : ClassTag[scala.Byte] = ManifestFactory.Byte + def Short : ClassTag[scala.Short] = ManifestFactory.Short + def Char : ClassTag[scala.Char] = ManifestFactory.Char + def Int : ClassTag[scala.Int] = ManifestFactory.Int + def Long : ClassTag[scala.Long] = ManifestFactory.Long + def Float : ClassTag[scala.Float] = ManifestFactory.Float + def Double : ClassTag[scala.Double] = ManifestFactory.Double + def Boolean : ClassTag[scala.Boolean] = ManifestFactory.Boolean + def Unit : ClassTag[scala.Unit] = ManifestFactory.Unit + def Any : ClassTag[scala.Any] = ManifestFactory.Any + def Object : ClassTag[java.lang.Object] = ManifestFactory.Object + def AnyVal : ClassTag[scala.AnyVal] = ManifestFactory.AnyVal + def AnyRef : ClassTag[scala.AnyRef] = ManifestFactory.AnyRef + def Nothing : ClassTag[scala.Nothing] = ManifestFactory.Nothing + def Null : ClassTag[scala.Null] = ManifestFactory.Null + + def apply[T](runtimeClass1: jClass[_]): ClassTag[T] = + runtimeClass1 match { + case java.lang.Byte.TYPE => ClassTag.Byte.asInstanceOf[ClassTag[T]] + case java.lang.Short.TYPE => ClassTag.Short.asInstanceOf[ClassTag[T]] + case java.lang.Character.TYPE => ClassTag.Char.asInstanceOf[ClassTag[T]] + case java.lang.Integer.TYPE => ClassTag.Int.asInstanceOf[ClassTag[T]] + case java.lang.Long.TYPE => ClassTag.Long.asInstanceOf[ClassTag[T]] + case java.lang.Float.TYPE => ClassTag.Float.asInstanceOf[ClassTag[T]] + case java.lang.Double.TYPE => ClassTag.Double.asInstanceOf[ClassTag[T]] + case java.lang.Boolean.TYPE => ClassTag.Boolean.asInstanceOf[ClassTag[T]] + case java.lang.Void.TYPE => ClassTag.Unit.asInstanceOf[ClassTag[T]] + case _ => + if (classOf[java.lang.Object] == runtimeClass1) + ClassTag.Object.asInstanceOf[ClassTag[T]] + else if (classOf[scala.runtime.Nothing$] == runtimeClass1) + ClassTag.Nothing.asInstanceOf[ClassTag[T]] + else if (classOf[scala.runtime.Null$] == runtimeClass1) + ClassTag.Null.asInstanceOf[ClassTag[T]] + else + new ClassClassTag[T](runtimeClass1) + } + + @inline + private final class ClassClassTag[T]( + val runtimeClass: Class[_]) extends ClassTag[T] + + def unapply[T](ctag: ClassTag[T]): Option[Class[_]] = Some(ctag.runtimeClass) +} diff --git a/scalalib/overrides-2.11.11/scala/reflect/Manifest.scala b/scalalib/overrides-2.11.11/scala/reflect/Manifest.scala new file mode 100644 index 0000000000..1297148a0b --- /dev/null +++ b/scalalib/overrides-2.11.11/scala/reflect/Manifest.scala @@ -0,0 +1,295 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2007-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala +package reflect + +import scala.collection.mutable.{ ArrayBuilder, WrappedArray } + +/** A `Manifest[T]` is an opaque descriptor for type T. Its supported use + * is to give access to the erasure of the type as a `Class` instance, as + * is necessary for the creation of native `Arrays` if the class is not + * known at compile time. + * + * The type-relation operators `<:<` and `=:=` should be considered + * approximations only, as there are numerous aspects of type conformance + * which are not yet adequately represented in manifests. + * + * Example usages: +{{{ + def arr[T] = new Array[T](0) // does not compile + def arr[T](implicit m: Manifest[T]) = new Array[T](0) // compiles + def arr[T: Manifest] = new Array[T](0) // shorthand for the preceding + + // Methods manifest, classManifest, and optManifest are in [[scala.Predef]]. + def isApproxSubType[T: Manifest, U: Manifest] = manifest[T] <:< manifest[U] + isApproxSubType[List[String], List[AnyRef]] // true + isApproxSubType[List[String], List[Int]] // false + + def methods[T: ClassManifest] = classManifest[T].erasure.getMethods + def retType[T: ClassManifest](name: String) = + methods[T] find (_.getName == name) map (_.getGenericReturnType) + + retType[Map[_, _]]("values") // Some(scala.collection.Iterable) +}}} + * + */ +@scala.annotation.implicitNotFound(msg = "No Manifest available for ${T}.") +// TODO undeprecated until Scala reflection becomes non-experimental +// @deprecated("Use scala.reflect.ClassTag (to capture erasures) or scala.reflect.runtime.universe.TypeTag (to capture types) or both instead", "2.10.0") +trait Manifest[T] extends ClassManifest[T] with Equals { + override def typeArguments: List[Manifest[_]] = Nil + + override def arrayManifest: Manifest[Array[T]] = + Manifest.classType[Array[T]](arrayClass[T](runtimeClass), this) + + override def canEqual(that: Any): Boolean = that match { + case _: Manifest[_] => true + case _ => false + } + /** Note: testing for erasure here is important, as it is many times + * faster than <:< and rules out most comparisons. + */ + override def equals(that: Any): Boolean = that match { + case m: Manifest[_] => (m canEqual this) && (this.runtimeClass == m.runtimeClass) && (this <:< m) && (m <:< this) + case _ => false + } + override def hashCode = this.runtimeClass.## +} + +// TODO undeprecated until Scala reflection becomes non-experimental +// @deprecated("Use type tags and manually check the corresponding class or type instead", "2.10.0") +@SerialVersionUID(1L) +abstract class AnyValManifest[T <: AnyVal](override val toString: String) extends Manifest[T] with Equals { + override def <:<(that: ClassManifest[_]): Boolean = + (that eq this) || (that eq Manifest.Any) || (that eq Manifest.AnyVal) + override def canEqual(other: Any) = other match { + case _: AnyValManifest[_] => true + case _ => false + } + override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef] + override def hashCode = System.identityHashCode(this) +} + +/** `ManifestFactory` defines factory methods for manifests. + * It is intended for use by the compiler and should not be used in client code. + * + * Unlike `Manifest`, this factory isn't annotated with a deprecation warning. + * This is done to prevent avalanches of deprecation warnings in the code that calls methods with manifests. + * Why so complicated? Read up the comments for `ClassManifestFactory`. + */ +object ManifestFactory { + def valueManifests: List[AnyValManifest[_]] = + List(Byte, Short, Char, Int, Long, Float, Double, Boolean, Unit) + + def Byte: AnyValManifest[Byte] = ByteManifest + def Short: AnyValManifest[Short] = ShortManifest + def Char: AnyValManifest[Char] = CharManifest + def Int: AnyValManifest[Int] = IntManifest + def Long: AnyValManifest[Long] = LongManifest + def Float: AnyValManifest[Float] = FloatManifest + def Double: AnyValManifest[Double] = DoubleManifest + def Boolean: AnyValManifest[Boolean] = BooleanManifest + def Unit: AnyValManifest[Unit] = UnitManifest + def Any: Manifest[scala.Any] = AnyManifest + def Object: Manifest[java.lang.Object] = ObjectManifest + def AnyRef: Manifest[scala.AnyRef] = Object.asInstanceOf[Manifest[scala.AnyRef]] + def AnyVal: Manifest[scala.AnyVal] = AnyValManifest + def Null: Manifest[scala.Null] = NullManifest + def Nothing: Manifest[scala.Nothing] = NothingManifest + + private object ByteManifest extends AnyValManifest[scala.Byte]("Byte") { + def runtimeClass = java.lang.Byte.TYPE + override def newArray(len: Int): Array[Byte] = new Array[Byte](len) + override def newWrappedArray(len: Int): WrappedArray[Byte] = new WrappedArray.ofByte(new Array[Byte](len)) + override def newArrayBuilder(): ArrayBuilder[Byte] = new ArrayBuilder.ofByte() + private def readResolve(): Any = Manifest.Byte + } + + private object ShortManifest extends AnyValManifest[scala.Short]("Short") { + def runtimeClass = java.lang.Short.TYPE + override def newArray(len: Int): Array[Short] = new Array[Short](len) + override def newWrappedArray(len: Int): WrappedArray[Short] = new WrappedArray.ofShort(new Array[Short](len)) + override def newArrayBuilder(): ArrayBuilder[Short] = new ArrayBuilder.ofShort() + private def readResolve(): Any = Manifest.Short + } + + private object CharManifest extends AnyValManifest[scala.Char]("Char") { + def runtimeClass = java.lang.Character.TYPE + override def newArray(len: Int): Array[Char] = new Array[Char](len) + override def newWrappedArray(len: Int): WrappedArray[Char] = new WrappedArray.ofChar(new Array[Char](len)) + override def newArrayBuilder(): ArrayBuilder[Char] = new ArrayBuilder.ofChar() + private def readResolve(): Any = Manifest.Char + } + + private object IntManifest extends AnyValManifest[scala.Int]("Int") { + def runtimeClass = java.lang.Integer.TYPE + override def newArray(len: Int): Array[Int] = new Array[Int](len) + override def newWrappedArray(len: Int): WrappedArray[Int] = new WrappedArray.ofInt(new Array[Int](len)) + override def newArrayBuilder(): ArrayBuilder[Int] = new ArrayBuilder.ofInt() + private def readResolve(): Any = Manifest.Int + } + + private object LongManifest extends AnyValManifest[scala.Long]("Long") { + def runtimeClass = java.lang.Long.TYPE + override def newArray(len: Int): Array[Long] = new Array[Long](len) + override def newWrappedArray(len: Int): WrappedArray[Long] = new WrappedArray.ofLong(new Array[Long](len)) + override def newArrayBuilder(): ArrayBuilder[Long] = new ArrayBuilder.ofLong() + private def readResolve(): Any = Manifest.Long + } + + private object FloatManifest extends AnyValManifest[scala.Float]("Float") { + def runtimeClass = java.lang.Float.TYPE + override def newArray(len: Int): Array[Float] = new Array[Float](len) + override def newWrappedArray(len: Int): WrappedArray[Float] = new WrappedArray.ofFloat(new Array[Float](len)) + override def newArrayBuilder(): ArrayBuilder[Float] = new ArrayBuilder.ofFloat() + private def readResolve(): Any = Manifest.Float + } + + private object DoubleManifest extends AnyValManifest[scala.Double]("Double") { + def runtimeClass = java.lang.Double.TYPE + override def newArray(len: Int): Array[Double] = new Array[Double](len) + override def newWrappedArray(len: Int): WrappedArray[Double] = new WrappedArray.ofDouble(new Array[Double](len)) + override def newArrayBuilder(): ArrayBuilder[Double] = new ArrayBuilder.ofDouble() + private def readResolve(): Any = Manifest.Double + } + + private object BooleanManifest extends AnyValManifest[scala.Boolean]("Boolean") { + def runtimeClass = java.lang.Boolean.TYPE + override def newArray(len: Int): Array[Boolean] = new Array[Boolean](len) + override def newWrappedArray(len: Int): WrappedArray[Boolean] = new WrappedArray.ofBoolean(new Array[Boolean](len)) + override def newArrayBuilder(): ArrayBuilder[Boolean] = new ArrayBuilder.ofBoolean() + private def readResolve(): Any = Manifest.Boolean + } + + private object UnitManifest extends AnyValManifest[scala.Unit]("Unit") { + def runtimeClass = java.lang.Void.TYPE + override def newArray(len: Int): Array[Unit] = new Array[Unit](len) + override def newWrappedArray(len: Int): WrappedArray[Unit] = new WrappedArray.ofUnit(new Array[Unit](len)) + override def newArrayBuilder(): ArrayBuilder[Unit] = new ArrayBuilder.ofUnit() + override protected def arrayClass[T](tp: Class[_]): Class[Array[T]] = + if (tp eq runtimeClass) classOf[Array[scala.runtime.BoxedUnit]].asInstanceOf[Class[Array[T]]] + else super.arrayClass(tp) + private def readResolve(): Any = Manifest.Unit + } + + private object AnyManifest extends PhantomManifest[scala.Any](classOf[java.lang.Object], "Any") { + override def runtimeClass = classOf[java.lang.Object] + override def newArray(len: Int) = new Array[scala.Any](len) + override def <:<(that: ClassManifest[_]): Boolean = (that eq this) + private def readResolve(): Any = Manifest.Any + } + + private object ObjectManifest extends PhantomManifest[java.lang.Object](classOf[java.lang.Object], "Object") { + override def runtimeClass = classOf[java.lang.Object] + override def newArray(len: Int) = new Array[java.lang.Object](len) + override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any) + private def readResolve(): Any = Manifest.Object + } + + private object AnyValManifest extends PhantomManifest[scala.AnyVal](classOf[java.lang.Object], "AnyVal") { + override def runtimeClass = classOf[java.lang.Object] + override def newArray(len: Int) = new Array[scala.AnyVal](len) + override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any) + private def readResolve(): Any = Manifest.AnyVal + } + + private object NullManifest extends PhantomManifest[scala.Null](classOf[scala.runtime.Null$], "Null") { + override def runtimeClass = classOf[scala.runtime.Null$] + override def newArray(len: Int) = new Array[scala.Null](len) + override def <:<(that: ClassManifest[_]): Boolean = + (that ne null) && (that ne Nothing) && !(that <:< AnyVal) + private def readResolve(): Any = Manifest.Null + } + + private object NothingManifest extends PhantomManifest[scala.Nothing](classOf[scala.runtime.Nothing$], "Nothing") { + override def runtimeClass = classOf[scala.runtime.Nothing$] + override def newArray(len: Int) = new Array[scala.Nothing](len) + override def <:<(that: ClassManifest[_]): Boolean = (that ne null) + private def readResolve(): Any = Manifest.Nothing + } + + private class SingletonTypeManifest[T <: AnyRef](value: AnyRef) extends Manifest[T] { + lazy val runtimeClass = value.getClass + override lazy val toString = value.toString + ".type" + } + + /** Manifest for the singleton type `value.type`. */ + def singleType[T <: AnyRef](value: AnyRef): Manifest[T] = + new SingletonTypeManifest[T](value) + + /** Manifest for the class type `clazz[args]`, where `clazz` is + * a top-level or static class. + * @note This no-prefix, no-arguments case is separate because we + * it's called from ScalaRunTime.boxArray itself. If we + * pass varargs as arrays into this, we get an infinitely recursive call + * to boxArray. (Besides, having a separate case is more efficient) + */ + def classType[T](clazz: Predef.Class[_]): Manifest[T] = + new ClassTypeManifest[T](None, clazz, Nil) + + /** Manifest for the class type `clazz`, where `clazz` is + * a top-level or static class and args are its type arguments. */ + def classType[T](clazz: Predef.Class[T], arg1: Manifest[_], args: Manifest[_]*): Manifest[T] = + new ClassTypeManifest[T](None, clazz, arg1 :: args.toList) + + /** Manifest for the class type `clazz[args]`, where `clazz` is + * a class with non-package prefix type `prefix` and type arguments `args`. + */ + def classType[T](prefix: Manifest[_], clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] = + new ClassTypeManifest[T](Some(prefix), clazz, args.toList) + + private abstract class PhantomManifest[T](_runtimeClass: Predef.Class[_], + override val toString: String) extends ClassTypeManifest[T](None, _runtimeClass, Nil) { + override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef] + override def hashCode = System.identityHashCode(this) + } + + /** Manifest for the class type `clazz[args]`, where `clazz` is + * a top-level or static class. */ + private class ClassTypeManifest[T](prefix: Option[Manifest[_]], + runtimeClass1: Predef.Class[_], + override val typeArguments: List[Manifest[_]]) extends Manifest[T] { + def runtimeClass: Predef.Class[_] = runtimeClass1 + override def toString = + (if (prefix.isEmpty) "" else prefix.get.toString+"#") + + (if (runtimeClass.isArray) "Array" else runtimeClass.getName) + + argString + } + + def arrayType[T](arg: Manifest[_]): Manifest[Array[T]] = + arg.asInstanceOf[Manifest[T]].arrayManifest + + /** Manifest for the abstract type `prefix # name'. `upperBound` is not + * strictly necessary as it could be obtained by reflection. It was + * added so that erasure can be calculated without reflection. */ + def abstractType[T](prefix: Manifest[_], name: String, upperBound: Predef.Class[_], args: Manifest[_]*): Manifest[T] = + new Manifest[T] { + def runtimeClass = upperBound + override val typeArguments = args.toList + override def toString = prefix.toString+"#"+name+argString + } + + /** Manifest for the unknown type `_ >: L <: U` in an existential. + */ + def wildcardType[T](lowerBound: Manifest[_], upperBound: Manifest[_]): Manifest[T] = + new Manifest[T] { + def runtimeClass = upperBound.runtimeClass + override def toString = + "_" + + (if (lowerBound eq Nothing) "" else " >: "+lowerBound) + + (if (upperBound eq Nothing) "" else " <: "+upperBound) + } + + /** Manifest for the intersection type `parents_0 with ... with parents_n'. */ + def intersectionType[T](parents: Manifest[_]*): Manifest[T] = + new Manifest[T] { + def runtimeClass = parents.head.runtimeClass + override def toString = parents.mkString(" with ") + } +} diff --git a/scripts/assemble-cli.sh b/scripts/assemble-cli.sh index 90fba6f168..1f0c032800 100755 --- a/scripts/assemble-cli.sh +++ b/scripts/assemble-cli.sh @@ -16,8 +16,8 @@ case $BINVER in BASEVER="2.10.6" ;; 2.11) - FULLVERS="2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8" - BASEVER="2.11.8" + FULLVERS="2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11" + BASEVER="2.11.11" ;; 2.12) FULLVERS="2.12.0 2.12.1" diff --git a/scripts/build-all-js.sh b/scripts/build-all-js.sh index 71aa7a6706..2203b63231 100755 --- a/scripts/build-all-js.sh +++ b/scripts/build-all-js.sh @@ -3,7 +3,7 @@ tasks="fastOptJS fullOptJS" projects="helloworld/ reversi/ testingExample/test: testSuite/test:" -for v in 2.11.8 2.10.6 2.12.1; do +for v in 2.11.11 2.10.6 2.12.1; do echo "++$v" echo "package" diff --git a/scripts/publish.sh b/scripts/publish.sh index 55e36cf58c..83123038dd 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -8,9 +8,9 @@ else CMD="echo sbt" fi -FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.12.0 2.12.1" -BIN_VERSIONS="2.10.6 2.11.8 2.12.1" -CLI_VERSIONS="2.10.6 2.11.8 2.12.1" +FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.12.0 2.12.1" +BIN_VERSIONS="2.10.6 2.11.11 2.12.1" +CLI_VERSIONS="2.10.6 2.11.11 2.12.1" SBT_VERSION="2.10.6" COMPILER="compiler jUnitPlugin" From 92d30d8d06e88bd62a07ebc849a47bc0ef91229c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 24 Apr 2017 19:06:50 +0200 Subject: [PATCH 0224/2665] Upgrade to Scala 2.12.2. --- ci/checksizes.sh | 14 +- ci/matrix.xml | 36 +- .../scalajs/2.12.2/BlacklistedTests.txt | 1021 +++++ .../partest/scalajs/2.12.2/BuglistedTests.txt | 10 + .../scalajs/2.12.2/WhitelistedTests.txt | 3353 +++++++++++++++++ .../scalajs/2.12.2/neg/t6446-additional.check | 30 + .../scalajs/2.12.2/neg/t6446-list.check | 2 + .../scalajs/2.12.2/neg/t6446-missing.check | 30 + .../2.12.2/neg/t6446-show-phases.check | 29 + .../scalajs/2.12.2/neg/t7494-no-options.check | 31 + .../scalajs/2.12.2/run/Course-2002-01.check | 37 + .../scalajs/2.12.2/run/Course-2002-02.check | 187 + .../scalajs/2.12.2/run/Course-2002-04.check | 64 + .../scalajs/2.12.2/run/Course-2002-08.check | 171 + .../scalajs/2.12.2/run/Course-2002-09.check | 50 + .../scalajs/2.12.2/run/Course-2002-10.check | 46 + .../partest/scalajs/2.12.2/run/Meter.check | 16 + .../scalajs/2.12.2/run/MeterCaseClass.check | 16 + .../tools/partest/scalajs/2.12.2/run/bugs.sem | 1 + .../scalajs/2.12.2/run/caseClassHash.check | 9 + .../partest/scalajs/2.12.2/run/deeps.check | 87 + .../scalajs/2.12.2/run/dynamic-anyval.check | 4 + .../scalajs/2.12.2/run/impconvtimes.check | 1 + .../partest/scalajs/2.12.2/run/imports.check | 21 + .../scalajs/2.12.2/run/interpolation.check | 32 + .../2.12.2/run/interpolationMultiline1.check | 26 + .../partest/scalajs/2.12.2/run/issue192.sem | 1 + .../2.12.2/run/macro-bundle-static.check | 6 + .../2.12.2/run/macro-bundle-toplevel.check | 6 + .../run/macro-bundle-whitebox-decl.check | 6 + .../partest/scalajs/2.12.2/run/misc.check | 62 + .../scalajs/2.12.2/run/promotion.check | 4 + .../partest/scalajs/2.12.2/run/runtime.check | 70 + .../scalajs/2.12.2/run/spec-self.check | 2 + .../scalajs/2.12.2/run/structural.check | 37 + .../scalajs/2.12.2/run/t0421-new.check | 3 + .../scalajs/2.12.2/run/t0421-old.check | 3 + .../partest/scalajs/2.12.2/run/t1503.sem | 1 + .../partest/scalajs/2.12.2/run/t3702.check | 2 + .../partest/scalajs/2.12.2/run/t4148.sem | 1 + .../partest/scalajs/2.12.2/run/t4617.check | 1 + .../partest/scalajs/2.12.2/run/t5356.check | 6 + .../partest/scalajs/2.12.2/run/t5552.check | 6 + .../partest/scalajs/2.12.2/run/t5568.check | 9 + .../partest/scalajs/2.12.2/run/t5629b.check | 10 + .../partest/scalajs/2.12.2/run/t5680.check | 3 + .../partest/scalajs/2.12.2/run/t5866.check | 2 + .../scalajs/2.12.2/run/t6318_primitives.check | 54 + .../partest/scalajs/2.12.2/run/t6662.check | 1 + .../partest/scalajs/2.12.2/run/t7657.check | 3 + .../partest/scalajs/2.12.2/run/t7763.sem | 1 + .../partest/scalajs/2.12.2/run/t8570a.check | 1 + .../partest/scalajs/2.12.2/run/t8764.check | 5 + .../partest/scalajs/2.12.2/run/t9387b.check | 1 + .../partest/scalajs/2.12.2/run/t9656.check | 14 + .../scalajs/2.12.2/run/try-catch-unify.check | 4 + .../2.12.2/run/virtpatmat_switch.check | 7 + .../2.12.2/run/virtpatmat_typetag.check | 10 + project/Build.scala | 5 +- .../resources/2.12.2/BlacklistedTests.txt | 128 + .../resources/2.12.2/WhitelistedTests.txt | 40 + scripts/assemble-cli.sh | 4 +- scripts/build-all-js.sh | 2 +- scripts/publish.sh | 6 +- 64 files changed, 5826 insertions(+), 25 deletions(-) create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/BlacklistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/BuglistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/WhitelistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-additional.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-list.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-missing.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-show-phases.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t7494-no-options.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Course-2002-01.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Course-2002-02.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Course-2002-04.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Course-2002-08.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Course-2002-09.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Course-2002-10.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Meter.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/MeterCaseClass.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/bugs.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/caseClassHash.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/deeps.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/dynamic-anyval.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/impconvtimes.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/imports.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/interpolation.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/interpolationMultiline1.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/issue192.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/macro-bundle-static.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/macro-bundle-toplevel.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/macro-bundle-whitebox-decl.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/misc.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/promotion.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/runtime.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/spec-self.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/structural.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t0421-new.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t0421-old.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t1503.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t3702.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t4148.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t4617.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t5356.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t5552.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t5568.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t5629b.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t5680.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t5866.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t6318_primitives.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t6662.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t7657.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t7763.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t8570a.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t8764.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t9387b.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t9656.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/try-catch-unify.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/virtpatmat_switch.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/virtpatmat_typetag.check create mode 100644 scala-test-suite/src/test/resources/2.12.2/BlacklistedTests.txt create mode 100644 scala-test-suite/src/test/resources/2.12.2/WhitelistedTests.txt diff --git a/ci/checksizes.sh b/ci/checksizes.sh index 93b201868b..28dacf2400 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -11,10 +11,10 @@ case $FULLVER in 2.11.11) VER=2.11 ;; - 2.12.1) + 2.12.2) VER=2.12 ;; - 2.10.3|2.10.4|2.10.5|2.10.6|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7|2.11.8|2.12.0) + 2.10.3|2.10.4|2.10.5|2.10.6|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7|2.11.8|2.12.0|2.12.1) echo "Ignoring checksizes for Scala $FULLVER" exit 0 ;; @@ -45,11 +45,11 @@ case $FULLVER in REVERSI_PREOPT_GZ_EXPECTEDSIZE=71000 REVERSI_OPT_GZ_EXPECTEDSIZE=32000 ;; - 2.12.1) - REVERSI_PREOPT_EXPECTEDSIZE=492000 - REVERSI_OPT_EXPECTEDSIZE=114000 - REVERSI_PREOPT_GZ_EXPECTEDSIZE=66000 - REVERSI_OPT_GZ_EXPECTEDSIZE=29000 + 2.12.2) + REVERSI_PREOPT_EXPECTEDSIZE=629000 + REVERSI_OPT_EXPECTEDSIZE=144000 + REVERSI_PREOPT_GZ_EXPECTEDSIZE=76000 + REVERSI_OPT_GZ_EXPECTEDSIZE=33000 ;; esac diff --git a/ci/matrix.xml b/ci/matrix.xml index ccea763fa3..e6b2942d31 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -321,7 +321,7 @@ 1.8 - 2.12.1 + 2.12.2 1.8 @@ -337,7 +337,7 @@ testSuite - 2.12.1 + 2.12.2 1.8 testSuite @@ -349,7 +349,7 @@ scalaTestSuite - 2.12.1 + 2.12.2 1.8 scalaTestSuite @@ -366,7 +366,7 @@ testSuite - 2.12.1 + 2.12.2 1.8 testSuite @@ -378,7 +378,7 @@ scalaTestSuite - 2.12.1 + 2.12.2 1.8 scalaTestSuite @@ -393,7 +393,7 @@ 1.8 - 2.12.1 + 2.12.2 1.8 @@ -420,7 +420,7 @@ 1.8 - 2.12.1 + 2.12.2 1.8 @@ -436,7 +436,7 @@ 1.7 - 2.12.1 + 2.12.2 1.8 @@ -499,6 +499,10 @@ 2.12.0 1.8 + + 2.12.1 + 1.8 + @@ -554,11 +558,11 @@ 1.7 - 2.12.1 + 2.12.2 1.8 - 2.12.1 + 2.12.2 1.8 @@ -687,6 +691,18 @@ 2.12.0 1.8 + + 2.12.1 + 1.8 + + + 2.12.1 + 1.8 + + + 2.12.1 + 1.8 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/BlacklistedTests.txt new file mode 100644 index 0000000000..7982bdf902 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/BlacklistedTests.txt @@ -0,0 +1,1021 @@ +# +# POS +# + +# Using Jsoup, what's that? +pos/cycle-jsoup.scala + +# Kills our IR serializer, it's an artificially super-deep if/else if +pos/t9181.scala + +# +# NEG +# + +# Screws up, but not really our problem (error: None.get instead of +# phase ordering error) +neg/t7494-multi-right-after +neg/t7494-right-after-before +neg/t7622-multi-followers +neg/t7622-cyclic-dependency + +# Uses some strange macro cross compile mechanism. +neg/macro-incompatible-macro-engine-c.scala + +# Uses .java files +run/t9200 +run/noInlineUnknownIndy +# +# RUN +# + +# Relies on the exact toString() representation of Floats/Doubles +run/t2378.scala + +# Uses ClassTags on existentials which are broken in Scala (see #251) +run/valueclasses-classtag-existential.scala + +# Relies on a particular execution speed +run/t5857.scala + +# Using parts of the javalib we don't plan to support + +run/t5018.scala +run/t2417.scala +run/t4813.scala +run/lazy-concurrent.scala +run/t3667.scala +run/t3038d.scala +run/shutdownhooks.scala +run/t5590.scala +run/t3895b.scala +run/t5974.scala +run/hashset.scala +run/t5262.scala +run/serialize-stream.scala +run/sysprops.scala +run/lambda-serialization-gc.scala +run/t9390.scala +run/t9390b.scala +run/t9390c.scala + +run/t2849.scala +run/t1360.scala +run/t3199b.scala +run/t8690.scala + +run/various-flat-classpath-types.scala + +# Uses java.util.Collections +run/t2250.scala + +# Uses java.math.BigDecimal / BigInteger : but failures not due to them +run/hashhash.scala +run/is-valid-num.scala + +# Documented semantic difference on String.split(x: Array[Char]) +run/t0325.scala + +# Using Threads +run/t6969.scala +run/inner-obj-auto.scala +run/predef-cycle.scala +run/synchronized.scala + +# Uses java.security +run/t2318.scala + +# Tries to catch java.lang.StackOverflowError +run/t6154.scala + +# Tries to catch java.lang.OutOfMemoryError +run/t7880.scala + +# Taking too much time, because JavaScript is not as fast as the JVM + +run/collections.scala +run/t3989.scala +run/adding-growing-set.scala +run/t3242.scala +run/hashCodeDistribution.scala +run/t408.scala +run/t6584.scala +run/t6853.scala +run/UnrolledBuffer.scala +run/t6253a.scala +run/t6253b.scala +run/t6253c.scala +run/numbereq.scala +run/t4658.scala + +# Crashes Rhino + +run/bridges.scala +run/patmat-exprs.scala + +# Using partest properties + +run/tailcalls.scala +run/t4294.scala +run/t6331b.scala + +# Using IO + +run/t6488.scala +run/t6988.scala + +# Object{Output|Input}Streams +run/t6935.scala +run/t8188.scala +run/t9375.scala +run/t9365.scala +run/inlineAddDeserializeLambda.scala +run/sammy_seriazable.scala +run/lambda-serialization-security.scala + +# Using System.getProperties + +run/t4426.scala + +# Using Await + +run/t7336.scala +run/t7775.scala +run/future-flatmap-exec-count.scala + +# Using detailed stack trace + +run/t6308.scala + +# Using reflection + +run/t6063 + +run/mixin-bridge-methods.scala +run/t5125.scala +run/outertest.scala +run/t6223.scala +run/t5652b +run/elidable-opt.scala +run/nullable-lazyvals.scala +run/t4794.scala +run/t5652 +run/t5652c +run/getClassTest-old.scala +run/t8960.scala +run/t7965.scala +run/t8087.scala +run/t8931.scala +run/t8445.scala +run/lambda-serialization.scala + +run/reflection-repl-classes.scala +run/t5256e.scala +run/typetags_core.scala +run/reflection-constructormirror-toplevel-badpath.scala +run/t5276_1b.scala +run/reflection-sorted-decls.scala +run/toolbox_typecheck_implicitsdisabled.scala +run/t5418b.scala +run/toolbox_typecheck_macrosdisabled2.scala +run/abstypetags_serialize.scala +run/all-overridden.scala +run/showraw_tree_kinds.scala +run/showraw_tree_types_ids.scala +run/showraw_tree_types_typed.scala +run/showraw_tree_ids.scala +run/showraw_tree_ultimate.scala +run/t5266_2.scala +run/t5274_1.scala +run/t5224.scala +run/reflection-sanitychecks.scala +run/t6086-vanilla.scala +run/t5277_2.scala +run/reflection-methodsymbol-params.scala +run/reflection-valueclasses-standard.scala +run/t5274_2.scala +run/t5423.scala +run/reflection-modulemirror-toplevel-good.scala +run/t5419.scala +run/t5271_3.scala +run/reflection-enclosed-nested-basic.scala +run/reflection-enclosed-nested-nested-basic.scala +run/fail-non-value-types.scala +run/exprs_serialize.scala +run/t5258a.scala +run/typetags_without_scala_reflect_manifest_lookup.scala +run/t4110-new.scala +run/t5273_2b_newpatmat.scala +run/t6277.scala +run/t5335.scala +run/toolbox_typecheck_macrosdisabled.scala +run/reflection-modulemirror-inner-good.scala +run/t5229_2.scala +run/typetags_multi.scala +run/typetags_without_scala_reflect_typetag_manifest_interop.scala +run/reflection-constructormirror-toplevel-good.scala +run/reflection-magicsymbols-invoke.scala +run/t6392b.scala +run/t5229_1.scala +run/reflection-magicsymbols-vanilla.scala +run/t5225_2.scala +run/runtimeEval1.scala +run/reflection-enclosed-nested-inner-basic.scala +run/reflection-fieldmirror-ctorparam.scala +run/t6181.scala +run/reflection-magicsymbols-repl.scala +run/t5272_2_newpatmat.scala +run/t5270.scala +run/t5418a.scala +run/t5276_2b.scala +run/t5256f.scala +run/reflection-enclosed-basic.scala +run/reflection-constructormirror-inner-badpath.scala +run/interop_typetags_are_manifests.scala +run/newTags.scala +run/t5273_1_newpatmat.scala +run/reflection-constructormirror-nested-good.scala +run/t2236-new.scala +run/existentials3-new.scala +run/t6323b.scala +run/t5943a1.scala +run/reflection-fieldmirror-getsetval.scala +run/t5272_1_oldpatmat.scala +run/t5256h.scala +run/t1195-new.scala +run/t5840.scala +run/reflection-methodsymbol-returntype.scala +run/reflection-fieldmirror-accessorsareokay.scala +run/reflection-sorted-members.scala +run/reflection-allmirrors-tostring.scala +run/valueclasses-typetag-existential.scala +run/toolbox_console_reporter.scala +run/reflection-enclosed-inner-inner-basic.scala +run/t5256b.scala +run/bytecodecs.scala +run/elidable.scala +run/freetypes_false_alarm1.scala +run/freetypes_false_alarm2.scala +run/getClassTest-new.scala +run/idempotency-extractors.scala +run/idempotency-case-classes.scala +run/idempotency-this.scala +run/idempotency-labels.scala +run/idempotency-lazy-vals.scala +run/interop_manifests_are_abstypetags.scala +run/interop_manifests_are_typetags.scala +run/abstypetags_core.scala +run/macro-reify-abstypetag-notypeparams +run/macro-reify-abstypetag-typeparams-tags +run/macro-reify-abstypetag-typeparams-notags +run/macro-reify-abstypetag-usetypetag +run/macro-reify-freevars +run/macro-reify-splice-outside-reify +run/macro-reify-tagless-a +run/macro-reify-type +run/macro-reify-typetag-typeparams-tags +run/macro-reify-typetag-notypeparams +run/macro-undetparams-implicitval +run/manifests-new.scala +run/manifests-old.scala +run/no-pickle-skolems +run/position-val-def.scala +run/reflect-priv-ctor.scala +run/primitive-sigs-2-new.scala +run/primitive-sigs-2-old.scala +run/reflection-enclosed-inner-basic.scala +run/reflection-enclosed-inner-nested-basic.scala +run/reflection-constructormirror-inner-good.scala +run/reflection-constructormirror-nested-badpath.scala +run/reflection-fancy-java-classes +run/reflection-fieldsymbol-navigation.scala +run/reflection-fieldmirror-nmelocalsuffixstring.scala +run/reflection-fieldmirror-getsetvar.scala +run/reflection-fieldmirror-privatethis.scala +run/reflection-implicit.scala +run/reflection-mem-glbs.scala +run/reflection-mem-tags.scala +run/reflection-java-annotations +run/reflection-java-crtp +run/reflection-methodsymbol-typeparams.scala +run/reflection-modulemirror-nested-badpath.scala +run/reflection-modulemirror-inner-badpath.scala +run/reflection-modulemirror-nested-good.scala +run/reflection-modulemirror-toplevel-badpath.scala +run/reflection-sync-subtypes.scala +run/reflinit.scala +run/reflection-valueclasses-derived.scala +run/reflection-valueclasses-magic.scala +run/resetattrs-this.scala +run/runtimeEval2.scala +run/showraw_aliases.scala +run/showraw_mods.scala +run/shortClass.scala +run/showraw_nosymbol.scala +run/showraw_tree.scala +run/showraw_tree_types_untyped.scala +run/t1167.scala +run/t2577.scala +run/t2873.scala +run/t2886.scala +run/t2251b.scala +run/t3346j.scala +run/t3507-new.scala +run/t3569.scala +run/t5125b.scala +run/t5225_1.scala +run/t3425b +run/t5256a.scala +run/t5230.scala +run/t5256c.scala +run/t5256g.scala +run/t5266_1.scala +run/t5269.scala +run/t5271_1.scala +run/t5271_2.scala +run/t5271_4.scala +run/t5272_1_newpatmat.scala +run/t5272_2_oldpatmat.scala +run/t5273_1_oldpatmat.scala +run/t5273_2a_newpatmat.scala +run/t5273_2a_oldpatmat.scala +run/t5275.scala +run/t5276_1a.scala +run/t5276_2a.scala +run/t5277_1.scala +run/t5279.scala +run/t5334_1.scala +run/t5334_2.scala +run/t5415.scala +run/t5418.scala +run/t5676.scala +run/t5704.scala +run/t5710-1.scala +run/t5710-2.scala +run/t5770.scala +run/t5894.scala +run/t5816.scala +run/t5824.scala +run/t5912.scala +run/t5942.scala +run/t5943a2.scala +run/t6023.scala +run/t6113.scala +run/t6175.scala +run/t6178.scala +run/t6199-mirror.scala +run/t6199-toolbox.scala +run/t6240-universe-code-gen.scala +run/t6221 +run/t6260b.scala +run/t6259.scala +run/t6287.scala +run/t6344.scala +run/t6392a.scala +run/t6591_1.scala +run/t6591_2.scala +run/t6591_3.scala +run/t6591_5.scala +run/t6591_6.scala +run/t6591_7.scala +run/t6608.scala +run/t6677.scala +run/t6687.scala +run/t6715.scala +run/t6719.scala +run/t6793.scala +run/t6860.scala +run/t6793b.scala +run/t6793c.scala +run/t7045.scala +run/t7046.scala +run/t7008-scala-defined +run/t7120b.scala +run/t7151.scala +run/t7214.scala +run/t7235.scala +run/t7331a.scala +run/t7331b.scala +run/t7331c.scala +run/t7558.scala +run/t7556 +run/t7779.scala +run/t7868b.scala +run/toolbox_current_run_compiles.scala +run/toolbox_default_reporter_is_silent.scala +run/toolbox_parse_package.scala +run/toolbox_silent_reporter.scala +run/toolbox_typecheck_inferimplicitvalue.scala +run/typetags_serialize.scala +run/valueclasses-typetag-basic.scala +run/WeakHashSetTest.scala +run/valueclasses-typetag-generic.scala +run/t4023.scala +run/t4024.scala +run/t6380.scala +run/t5273_2b_oldpatmat.scala +run/t8104 +run/t8047.scala +run/t6992 +run/var-arity-class-symbol.scala +run/typetags_symbolof_x.scala +run/typecheck +run/t8190.scala +run/t8192 +run/t8177f.scala +run/t8199.scala +run/t7932.scala +run/t7700.scala +run/t7570c.scala +run/t7570b.scala +run/t7533.scala +run/t7570a.scala +run/t7044 +run/t7328.scala +run/t6733.scala +run/t6554.scala +run/t6732.scala +run/t6379 +run/t6411b.scala +run/t6411a.scala +run/t6260c.scala +run/t6260-delambdafy.scala +run/showdecl +run/reflection-sync-potpourri.scala +run/reflection-tags.scala +run/reflection-companiontype.scala +run/reflection-scala-annotations.scala +run/reflection-idtc.scala +run/macro-reify-nested-b2 +run/mixin-signatures.scala +run/reflection-companion.scala +run/macro-reify-nested-b1 +run/macro-reify-nested-a2 +run/macro-reify-nested-a1 +run/macro-reify-chained2 +run/macro-reify-chained1 +run/inferred-type-constructors.scala +run/mirror_symbolof_x.scala +run/t8196.scala +run/t8549b.scala +run/t8574.scala +run/t8549.scala +run/t8637.scala +run/t8253.scala +run/t9027.scala +run/t6622.scala +run/toolbox_expand_macro.scala +run/toolbox-varargs +run/t9252.scala +run/t9182.scala +run/t9102.scala +run/t720.scala +run/t9408.scala +run/trait-default-specialize.scala +run/lazy-locals-2.scala +run/t5294.scala +run/trait_fields_final.scala +run/trait_fields_bytecode.scala +run/trait_fields_volatile.scala +run/junitForwarders + +run/reify_newimpl_29.scala +run/reify_magicsymbols.scala +run/reify_inheritance.scala +run/reify_newimpl_12.scala +run/reify_typerefs_2b.scala +run/reify_csv.scala +run/reify_inner2.scala +run/reify_maps_oldpatmat.scala +run/reify_newimpl_43.scala +run/reify_nested_inner_refers_to_local.scala +run/reify_closure7.scala +run/reify_closure8b.scala +run/reify_typerefs_3b.scala +run/reify_newimpl_44.scala +run/reify_newimpl_06.scala +run/reify_newimpl_05.scala +run/reify_newimpl_20.scala +run/reify_newimpl_23.scala +run/reify_metalevel_breach_-1_refers_to_1.scala +run/reify_newimpl_41.scala +run/reify-repl-fail-gracefully.scala +run/reify_fors_oldpatmat.scala +run/reify_inner3.scala +run/reify_closure8a.scala +run/reify_closures10.scala +run/reify_ann2a.scala +run/reify_newimpl_51.scala +run/reify_newimpl_47.scala +run/reify_extendbuiltins.scala +run/reify_newimpl_30.scala +run/reify_newimpl_38.scala +run/reify_closure2a.scala +run/reify_newimpl_45.scala +run/reify_closure1.scala +run/reify_generic2.scala +run/reify_printf.scala +run/reify_closure6.scala +run/reify_newimpl_37.scala +run/reify_newimpl_35.scala +run/reify_typerefs_3a.scala +run/reify_newimpl_25.scala +run/reify_ann4.scala +run/reify_typerefs_1b.scala +run/reify_newimpl_22.scala +run/reify_this.scala +run/reify_typerefs_2a.scala +run/reify_newimpl_03.scala +run/reify_newimpl_48.scala +run/reify_varargs.scala +run/reify_newimpl_42.scala +run/reify_newimpl_15.scala +run/reify_nested_inner_refers_to_global.scala +run/reify_newimpl_02.scala +run/reify_newimpl_01.scala +run/reify_fors_newpatmat.scala +run/reify_classfileann_a.scala +run/reify_nested_outer_refers_to_local.scala +run/reify_newimpl_13.scala +run/reify_closure5a.scala +run/reify_inner4.scala +run/reify_sort.scala +run/reify_ann1a.scala +run/reify_classfileann_b.scala +run/reify_closure4a.scala +run/reify_newimpl_33.scala +run/reify_sort1.scala +run/reify_properties.scala +run/reify_generic.scala +run/reify_newimpl_27.scala +run/reify-aliases.scala +run/reify_ann3.scala +run/reify-staticXXX.scala +run/reify_ann1b.scala +run/reify_ann5.scala +run/reify_anonymous.scala +run/reify-each-node-type.scala +run/reify_copypaste2.scala +run/reify_closure3a.scala +run/reify_copypaste1.scala +run/reify_complex.scala +run/reify_for1.scala +run/reify_getter.scala +run/reify_implicits-new.scala +run/reify_inner1.scala +run/reify_implicits-old.scala +run/reify_lazyunit.scala +run/reify_lazyevaluation.scala +run/reify_maps_newpatmat.scala +run/reify_metalevel_breach_+0_refers_to_1.scala +run/reify_metalevel_breach_-1_refers_to_0_a.scala +run/reify_metalevel_breach_-1_refers_to_0_b.scala +run/reify_nested_outer_refers_to_global.scala +run/reify_newimpl_04.scala +run/reify_newimpl_14.scala +run/reify_newimpl_11.scala +run/reify_newimpl_18.scala +run/reify_newimpl_19.scala +run/reify_newimpl_31.scala +run/reify_newimpl_21.scala +run/reify_newimpl_36.scala +run/reify_newimpl_39.scala +run/reify_newimpl_40.scala +run/reify_newimpl_49.scala +run/reify_newimpl_50.scala +run/reify_newimpl_52.scala +run/reify_renamed_term_basic.scala +run/reify_renamed_term_local_to_reifee.scala +run/reify_renamed_term_overloaded_method.scala +run/reify_renamed_type_basic.scala +run/reify_renamed_type_local_to_reifee.scala +run/reify_renamed_type_spliceable.scala +run/reify_typerefs_1a.scala +run/reify_timeofday.scala +run/reify_renamed_term_t5841.scala + +run/t7521b.scala +run/t8575b.scala +run/t8575c.scala +run/t8944c.scala +run/t9535.scala +run/t9437a +run/t9437b +run/t9814.scala +run/t10009.scala +run/t10075.scala +run/t10075b + +run/t8756.scala +run/inferred-type-constructors-hou.scala +run/trait-static-forwarder +run/SD-235.scala +run/t10026.scala + +# Uses refletction indirectly through +# scala.runtime.ScalaRunTime.replStringOf +run/t6634.scala + +# Using reflection to invoke macros. These tests actually don't require +# or test reflection, but use it to separate compilation units nicely. +# It's a pity we cannot use them + +run/macro-abort-fresh +run/macro-expand-varargs-explicit-over-nonvarargs-bad +run/macro-invalidret-doesnt-conform-to-def-rettype +run/macro-invalidret-nontypeable +run/macro-invalidusage-badret +run/macro-invalidusage-partialapplication +run/macro-invalidusage-partialapplication-with-tparams +run/macro-reflective-ma-normal-mdmi +run/macro-reflective-mamd-normal-mi + +# Using macros, but indirectly creating calls to reflection +run/macro-reify-unreify + +# Using Enumeration in a way we cannot fix + +run/enums.scala +run/t3719.scala +run/t8611b.scala + +# Exceptions that become JavaScriptException + +run/pf-catch.scala +run/exceptions-2.scala +run/exceptions-nest.scala +run/t8601c.scala +run/t8601b.scala +run/inlineHandlers.scala + +# Expecting unsupported exceptions (e.g. ArrayIndexOutOfBounds) +run/optimizer-array-load.scala +run/t6827.scala +run/t8601.scala + +# Playing with classfile format + +run/classfile-format-51.scala +run/classfile-format-52.scala + +# Concurrent collections (TrieMap) +# has too much stuff implemented in *.java, so no support +run/triemap-hash.scala + +# Using parallel collections + +run/t5375.scala +run/t4894.scala +run/ctries-new +run/collection-conversions.scala +run/concurrent-map-conversions.scala +run/t4761.scala +run/t7498.scala +run/t6448.scala +run/ctries-old +run/map_java_conversions.scala +run/parmap-ops.scala +run/pc-conversions.scala +run/t4459.scala +run/t4608.scala +run/t4723.scala +run/t4895.scala +run/t6052.scala +run/t6410.scala +run/t6467.scala +run/t6908.scala +run/t8955.scala + +# Using scala.xml + +run/t4124.scala + +# Using Swing + +run/t3613.scala + +# Using the REPL + +run/t4285.scala +run/constant-type.scala +run/repl-bare-expr.scala +run/repl-parens.scala +run/repl-assign.scala +run/t5583.scala +run/treePrint.scala +run/constrained-types.scala +run/repl-power.scala +run/t4710.scala +run/repl-paste.scala +run/repl-reset.scala +run/repl-paste-3.scala +run/t6329_repl.scala +run/t6273.scala +run/repl-paste-2.scala +run/t5655.scala +run/t5072.scala +run/repl-colon-type.scala +run/kind-repl-command.scala +run/repl-trim-stack-trace.scala +run/t4594-repl-settings.scala +run/repl-save.scala +run/repl-paste-raw.scala +run/repl-paste-4.scala +run/t7801.scala +run/repl-backticks.scala +run/t6633.scala +run/repl-inline.scala + +# Using the Repl (scala.tools.partest.ReplTest) +run/class-symbol-contravariant.scala +run/lub-visibility.scala +run/macro-bundle-repl.scala +run/macro-repl-basic.scala +run/macro-repl-dontexpand.scala +run/macro-system-properties.scala +run/reflection-equality.scala +run/reflection-repl-elementary.scala +run/reify_newimpl_26.scala +run/repl-out-dir.scala +run/repl-term-macros.scala +run/repl-transcript.scala +run/repl-type-verbose.scala +run/t3376.scala +run/t4025.scala +run/t4172.scala +run/t4216.scala +run/t4542.scala +run/t4671.scala +run/t5256d.scala +run/t5535.scala +run/t5537.scala +run/t5789.scala +run/t6086-repl.scala +run/t6146b.scala +run/t6187.scala +run/t6320.scala +run/t6381.scala +run/t6434.scala +run/t6439.scala +run/t6507.scala +run/t6549.scala +run/t6937.scala +run/t7185.scala +run/t7319.scala +run/t7482a.scala +run/t7634.scala +run/t7747-repl.scala +run/t7805-repl-i.scala +run/tpeCache-tyconCache.scala +run/repl-empty-package +run/repl-javap-def.scala +run/repl-javap-mem.scala +run/repl-javap-outdir +run/repl-javap.scala +run/t6329_repl_bug.scala +run/t4950.scala +run/xMigration.scala +run/t6541-option.scala +run/repl-serialization.scala +run/t9174.scala +run/repl-paste-5.scala +run/repl-no-uescape.scala +run/repl-no-imports-no-predef-classbased.scala +run/repl-implicits-nopredef.scala +run/repl-classbased.scala +run/repl-no-imports-no-predef-power.scala +run/repl-paste-b.scala +run/repl-paste-6.scala +run/repl-implicits.scala +run/repl-no-imports-no-predef.scala +run/repl-paste-raw-b.scala +run/repl-paste-raw-c.scala +run/t9749-repl-dot.scala +run/trait_fields_repl.scala +run/t7139 +run/t9689 +run/trailing-commas.scala +run/t4700.scala +run/t9880-9881.scala + +# Using Scala Script (partest.ScriptTest) + +run/t7711-script-args.scala +run/t4625.scala +run/t4625c.scala +run/t4625b.scala + +# Using the compiler API + +run/t2512.scala +run/analyzerPlugins.scala +run/compiler-asSeenFrom.scala +run/t5603.scala +run/t6440.scala +run/t5545.scala +run/existentials-in-compiler.scala +run/global-showdef.scala +run/stream_length.scala +run/annotatedRetyping.scala +run/imain.scala +run/existential-rangepos.scala +run/delambdafy_uncurry_byname_inline.scala +run/delambdafy_uncurry_byname_method.scala +run/delambdafy_uncurry_inline.scala +run/delambdafy_t6555.scala +run/delambdafy_uncurry_method.scala +run/delambdafy_t6028.scala +run/memberpos.scala +run/programmatic-main.scala +run/reflection-names.scala +run/settings-parse.scala +run/sm-interpolator.scala +run/t1501.scala +run/t1500.scala +run/sammy_java8.scala +run/t1618.scala +run/t2464 +run/t4072.scala +run/t5064.scala +run/t5385.scala +run/t5699.scala +run/t5717.scala +run/t5940.scala +run/t6028.scala +run/t6194.scala +run/t6669.scala +run/t6745-2.scala +run/t7096.scala +run/t7271.scala +run/t7337.scala +run/t7398.scala +run/t7569.scala +run/t7852.scala +run/t7817-tree-gen.scala +run/t7825.scala + +# partest.ParserTest +run/t3368.scala +run/t3368-b.scala +run/t3368-c.scala +run/t3368-d.scala +run/t9944.scala + +# partest.DirectTest +run/t6288.scala +run/t6331.scala +run/t6440b.scala +run/t6555.scala +run/t7876.scala +run/typetags_without_scala_reflect_typetag_lookup.scala +run/dynamic-updateDynamic.scala +run/dynamic-selectDynamic.scala +run/dynamic-applyDynamic.scala +run/dynamic-applyDynamicNamed.scala +run/t4841-isolate-plugins +run/large_code.scala +run/macroPlugins-namerHooks.scala +run/t4841-no-plugin.scala +run/t4332.scala +run/t8029.scala +run/t8046 +run/t5905-features.scala +run/t5905b-features.scala +run/large_class.scala +run/t8708_b +run/icode-reader-dead-code.scala +run/t5938.scala +run/t8502.scala +run/t6502.scala +run/t8907.scala +run/t9097.scala +run/macroPlugins-enterStats.scala +run/sbt-icode-interface.scala +run/t8502b.scala +run/t9437c +run/repl-paste-parse.scala +run/t5463.scala +run/t8433.scala +run/sd275.scala +run/sd275-java + +# Using partest.StoreReporterDirectTest +run/t10171 + +# partest.StubErrorMessageTest +run/StubErrorBInheritsFromA.scala +run/StubErrorComplexInnerClass.scala +run/StubErrorHK.scala +run/StubErrorReturnTypeFunction.scala +run/StubErrorReturnTypeFunction2.scala +run/StubErrorReturnTypePolyFunction.scala +run/StubErrorSubclasses.scala +run/StubErrorTypeclass.scala +run/StubErrorTypeDef.scala + +# partest.CompilerTest +run/t8852a.scala + +# partest.ASMConverters +run/t9403 + +# partest.BytecodeTest +run/t7106 +run/t7974 +run/t8601-closure-elim.scala +run/t4788 +run/t4788-separate-compilation + +# partest.SessionTest +run/t8843-repl-xlat.scala +run/t9206.scala +run/t9170.scala +run/t8918-unary-ids.scala +run/t1931.scala + +# partest.JavapTest +run/t8608-no-format.scala + +# Using .java source files + +run/t4317 +run/t4238 +run/t2296c +run/t4119 +run/t4283 +run/t4891 +run/t6168 +run/t6168b +run/t6240a +run/t6240b +run/t6548 +run/t6989 +run/t7008 +run/t7246 +run/t7246b +run/t7359 +run/t7439 +run/t7455 +run/t7510 +run/t7582-private-within +run/t7582 +run/t7582b +run/t3897 +run/t7374 +run/t3452e +run/t3452g +run/t3452d +run/t3452b +run/t3452a +run/t8442 +run/t8601e +run/t9298 +run/t9298b +run/t9359 +run/t7741a +run/t7741b +run/bcodeInlinerMixed +run/t9268 +run/t9489 +run/t9915 +run/t10059 +run/t1459 +run/t1459generic +run/t3236 +run/t9013 +run/t10231 +run/t10067 + +# Using scala-script +run/t7791-script-linenums.scala + +# Suffers from bug in Node.js (https://github.com/joyent/node/issues/7528) +run/range-unit.scala + +# Using scalap +run/scalapInvokedynamic.scala + +# Using Manifests (which use Class.getInterfaces) +run/valueclasses-manifest-existential.scala +run/existentials3-old.scala +run/t2236-old.scala +run/interop_manifests_are_classtags.scala +run/valueclasses-manifest-generic.scala +run/valueclasses-manifest-basic.scala +run/t1195-old.scala +run/t3758-old.scala +run/t4110-old.scala +run/t6246.scala + +# Using ScalaRunTime.stringOf +run/value-class-extractor-seq.scala +run/t3493.scala + +# Custom invoke dynamic node +run/indy-via-macro +run/indy-via-macro-with-dynamic-args + +### Incorrect partests ### +# Badly uses constract of Console.print (no flush) +run/t429.scala +run/t6102.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/BuglistedTests.txt new file mode 100644 index 0000000000..b210d1091e --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/BuglistedTests.txt @@ -0,0 +1,10 @@ +# The tests in this file should pass but have never passed so far +# use scala.tools.partest.scalajs.testunknownonly to only run tests +# which are neither in BuglistedTests.txt, WhitelistedTests.txt or +# BlacklistedTests.txt + +# Broken by GCC, filed as #2815 +run/Predef.readLine.scala + +# `Int.box(???)` crashes the compiler, filed as #2901 +run/t10069b.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/WhitelistedTests.txt new file mode 100644 index 0000000000..d48243f28b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/WhitelistedTests.txt @@ -0,0 +1,3353 @@ +pos/spec-super.scala +pos/t1035.scala +pos/t5897.scala +pos/irrefutable.scala +pos/spec-partialmap.scala +pos/tcpoly_seq.scala +pos/partialfun.scala +pos/t2795-new.scala +pos/clsrefine.scala +pos/t0774 +pos/t1070.scala +pos/t5957 +pos/looping-jsig.scala +pos/t3274.scala +pos/spec-fields-old.scala +pos/t262.scala +pos/t7486.scala +pos/t2261.scala +pos/t6600.scala +pos/t4786.scala +pos/t5406.scala +pos/tcpoly_late_method_params.scala +pos/t2726 +pos/pos-bug1210.scala +pos/t3312.scala +pos/manifest1-old.scala +pos/gadt-gilles.scala +pos/t4842.scala +pos/ted.scala +pos/NoCyclicReference.scala +pos/t3568.scala +pos/t0030.scala +pos/t2635.scala +pos/t7232b +pos/t0017.scala +pos/t812.scala +pos/t2179.scala +pos/t651.scala +pos/spurious-overload.scala +pos/t758.scala +pos/t4760.scala +pos/t1672.scala +pos/mixins.scala +pos/patterns.scala +pos/t1260.scala +pos/t6551.scala +pos/t2060.scala +pos/t6575a.scala +pos/t1318.scala +pos/t4266.scala +pos/t0695 +pos/protected-static +pos/t5738.scala +pos/t1226.scala +pos/t5013 +pos/t6215.scala +pos/t5692b +pos/traits.scala +pos/t2994a.scala +pos/t3371.scala +pos/t613.scala +pos/t6499.scala +pos/xlint1.scala +pos/t1150 +pos/test4a.scala +pos/t2664.scala +pos/t3528.scala +pos/t3174.scala +pos/t6994.scala +pos/t4812.scala +pos/t5777.scala +pos/t5223.scala +pos/t439.scala +pos/t3079.scala +pos/t5829.scala +pos/t0036.scala +pos/scoping2.scala +pos/t4717.scala +pos/t4257.scala +pos/t1210a.scala +pos/getClassType.scala +pos/t5330.scala +pos/t4524.scala +pos/t2945.scala +pos/t6562.scala +pos/t0273.scala +pos/override-object-yes.scala +pos/t7426.scala +pos/t6601 +pos/t3076 +pos/seq-ordering.scala +pos/spec-groups.scala +pos/t296.scala +pos/t5545 +pos/spec-multiplectors.scala +pos/t1789.scala +pos/t2569 +pos/ksbug1.scala +pos/t0599.scala +pos/local-objects.scala +pos/t0081.scala +pos/t5756.scala +pos/t7126.scala +pos/t7716.scala +pos/t2797.scala +pos/t5399.scala +pos/t1101 +pos/t767.scala +pos/contrib467.scala +pos/t7532b +pos/self-type-override.scala +pos/t4853.scala +pos/t839.scala +pos/t5644 +pos/t5853.scala +pos/t5178.scala +pos/unapplyNeedsMemberType.scala +pos/t5390.scala +pos/t6575b.scala +pos/t151.scala +pos/t2665.scala +pos/t5120.scala +pos/erasure-nsquared.scala +pos/arrays3.scala +pos/t3136.scala +pos/inline-access-levels +pos/t3972.scala +pos/t2591.scala +pos/t3486 +pos/variances-flip.scala +pos/annotated-original +pos/typesafecons.scala +pos/stable.scala +pos/t1996.scala +pos/t3037.scala +pos/t1711 +pos/t3374.scala +pos/t0029.scala +pos/t3278.scala +pos/matthias3.scala +pos/t5546.scala +pos/t4020.scala +pos/matthias4.scala +pos/value-class-override-spec.scala +pos/arrays2.scala +pos/t5119.scala +pos/t2613.scala +pos/t4070b.scala +pos/virtpatmat_exist_uncurry.scala +pos/modules1.scala +pos/spec-constr-new.scala +pos/t6335.scala +pos/t675.scala +pos/t0644.scala +pos/t5892.scala +pos/t360.scala +pos/override.scala +pos/t1798.scala +pos/strip-tvars-for-lubbasetypes.scala +pos/hk-infer.scala +pos/t2119.scala +pos/t0231.scala +pos/t1459 +pos/t1381-new.scala +pos/t2610.scala +pos/t2708.scala +pos/t5604b +pos/t3951 +pos/t361.scala +pos/t319.scala +pos/largecasetest.scala +pos/switchUnbox.scala +pos/typetags.scala +pos/java-access-pos +pos/t803.scala +pos/t3898.scala +pos/t5692a +pos/t2421.scala +pos/t1102 +pos/t0654.scala +pos/exhaust_alternatives.scala +pos/t807.scala +pos/t5702-pos-infix-star.scala +pos/t1186 +pos/t1439.scala +pos/t7427.scala +pos/virtpatmat_binding_opt.scala +pos/t247.scala +pos/abstract.scala +pos/gen-traversable-methods.scala +pos/t2795-old.scala +pos/t5639 +pos/t2667.scala +pos/t2405.scala +pos/t1438.scala +pos/SI-7100.scala +pos/t1659.scala +pos/unchecked-a.scala +pos/t3636.scala +pos/t6745.scala +pos/t2809.scala +pos/t7022.scala +pos/t6447.scala +pos/t6367.scala +pos/t5846.scala +pos/lubs.scala +pos/t1987a.scala +pos/spec-arrays.scala +pos/virtpatmat_anonfun_for.scala +pos/listpattern.scala +pos/t5742.scala +pos/test5refine.scala +pos/t5604 +pos/return_thistype.scala +pos/t348plus.scala +pos/t3420.scala +pos/t3440.scala +pos/maxim1.scala +pos/caseClassInMethod.scala +pos/t3833.scala +pos/t6675.scala +pos/t4402 +pos/t5953.scala +pos/t1152 +pos/t0591.scala +pos/t210.scala +pos/t7035.scala +pos/t5769.scala +pos/pmbug.scala +pos/t2331.scala +pos/t5240.scala +pos/t304.scala +pos/annotated-treecopy +pos/t2081.scala +pos/t0904.scala +pos/t7649.scala +pos/t3498-new.scala +pos/contrib701.scala +pos/t6624.scala +pos/t3924.scala +pos/t374.scala +pos/t1642 +pos/t1591_pos.scala +pos/depmet_implicit_oopsla_session_2.scala +pos/t5899.scala +pos/thistype.scala +pos/t4176b.scala +pos/elidable-tparams.scala +pos/lambdalift.scala +pos/nothing_manifest_disambig-old.scala +pos/t372.scala +pos/t5399a.scala +pos/t2782.scala +pos/patmat-extract-tparam.scala +pos/t4114.scala +pos/unapplyVal.scala +pos/t2486.scala +pos/t5877b.scala +pos/t0625.scala +pos/t6358_2.scala +pos/viewtest1.scala +pos/t1237.scala +pos/scala-singleton.scala +pos/t1254 +pos/t5504 +pos/bounds.scala +pos/t3631.scala +pos/t3177.scala +pos/unapplyContexts2.scala +pos/t0438.scala +pos/t1642b.scala +pos/inferbroadtype.scala +pos/t1858.scala +pos/t3731.scala +pos/t6963c.scala +pos/classtag-pos.scala +pos/t6221.scala +pos/t3343.scala +pos/spec-asseenfrom.scala +pos/t604.scala +pos/spec-example1.scala +pos/t0786.scala +pos/annot-inner.scala +pos/t5886.scala +pos/t1056.scala +pos/t294 +pos/spec-Function1.scala +pos/t1836 +pos/spec-private.scala +pos/depmet_implicit_tpbetareduce.scala +pos/exhaust_2.scala +pos/t7532 +pos/t5175.scala +pos/t802.scala +pos/t5809.scala +pos/tcpoly_typesub.scala +pos/t6029.scala +pos/contextbounds-implicits-new.scala +pos/t3480.scala +pos/patterns3.scala +pos/caseaccs.scala +pos/spec-sparsearray-old.scala +pos/patterns1213.scala +pos/spec-traits.scala +pos/t0020.scala +pos/cycle +pos/t5968.scala +pos/typealiases.scala +pos/init.scala +pos/t697.scala +pos/t2693.scala +pos/t2377 +pos/unapplyGeneric.scala +pos/t1385.scala +pos/t3363-old.scala +pos/t1236.scala +pos/t0068.scala +pos/t4052.scala +pos/lambdalift1.scala +pos/z1730.scala +pos/variances-local.scala +pos/virtpatmat_gadt_array.scala +pos/t2421_delitedsl.scala +pos/t5626.scala +pos/t690.scala +pos/t711.scala +pos/t1937 +pos/t3999 +pos/t2305.scala +pos/t2168.scala +pos/t2660.scala +pos/t1693.scala +pos/t2799.scala +pos/t6966.scala +pos/t1001.scala +pos/S5.scala +pos/t0301.scala +pos/t1048.scala +pos/t415.scala +pos/t6386.scala +pos/t2187.scala +pos/hashhash-overloads.scala +pos/t6921.scala +pos/t0227.scala +pos/t6556.scala +pos/t3946 +pos/t1053.scala +pos/t1000.scala +pos/t0586.scala +pos/t7011.scala +pos/t7329.scala +pos/t4975.scala +pos/t1131.scala +pos/t1027.scala +pos/t2913.scala +pos/t3494.scala +pos/t5606.scala +pos/t4716.scala +pos/tcpoly_gm.scala +pos/t4859.scala +pos/t514.scala +pos/lexical.scala +pos/t2624.scala +pos/t4036.scala +pos/t2741 +pos/t703.scala +pos/five-dot-f.scala +pos/t805.scala +pos/strings.scala +pos/t2433 +pos/t6925.scala +pos/t1085.scala +pos/t7461 +pos/t1942 +pos/spec-lists.scala +pos/t3349 +pos/tcpoly_infer_ticket474.scala +pos/t1614 +pos/virtpatmat_reach_const.scala +pos/t2194.scala +pos/t6976 +pos/t1560.scala +pos/t6891.scala +pos/t3883.scala +pos/infersingle.scala +pos/gui.scala +pos/t1164.scala +pos/t3175-pos.scala +pos/t4336.scala +pos/annotations2.scala +pos/proj-rec-test.scala +pos/t2973.scala +pos/t1123.scala +pos/t6205.scala +pos/t5727.scala +pos/t6537.scala +pos/t6712.scala +pos/t3866.scala +pos/t4831.scala +pos/selftails.scala +pos/t397.scala +pos/spec-vector.scala +pos/t7233b.scala +pos/t1391.scala +pos/spec.scala +pos/t3106.scala +pos/contextbounds-implicits-old.scala +pos/packageobjs.scala +pos/michel3.scala +pos/t628.scala +pos/collections.scala +pos/tcpoly_boundedmonad.scala +pos/t7668.scala +pos/t0032.scala +pos/t0069.scala +pos/t4345.scala +pos/t3521 +pos/t3071.scala +pos/tcpoly_infer_easy.scala +pos/t289.scala +pos/t4365 +pos/rangepos-anonapply.scala +pos/t5033.scala +pos/lambda.scala +pos/S8.scala +pos/t6014.scala +pos/t1785.scala +pos/t6034.scala +pos/t7433.scala +pos/imp2-pos.scala +pos/t0504.scala +pos/t1272.scala +pos/t0612 +pos/value-class-override-no-spec.scala +pos/overloaded-unapply.scala +pos/t5859.scala +pos/chang +pos/localmodules.scala +pos/t4237.scala +pos/rangepos-patmat.scala +pos/t1974.scala +pos/t0054.scala +pos/michel2.scala +pos/t0770.scala +pos/t1146.scala +pos/t2441pos.scala +pos/t5099.scala +pos/tcpoly_seq_typealias.scala +pos/t946.scala +pos/tcpoly_infer_ticket1864.scala +pos/t4737 +pos/t7377b.scala +pos/t616.scala +pos/t201.scala +pos/t6355pos.scala +pos/escapes2.scala +pos/t1675.scala +pos/t3890.scala +pos/t6040.scala +pos/spec-tailcall.scala +pos/existentials.scala +pos/t5317.scala +pos/t7782b.scala +pos/t4758.scala +pos/t7296.scala +pos/t6896.scala +pos/cls1.scala +pos/t402.scala +pos/gosh.scala +pos/t2619.scala +pos/javaConversions-2.10-regression.scala +pos/t759.scala +pos/t5259.scala +pos/t5130.scala +pos/t5156.scala +pos/t0905.scala +pos/package-implicit +pos/t2669.scala +pos/trait-parents.scala +pos/virtpatmat_exhaust.scala +pos/patterns1.scala +pos/t1231 +pos/t1751 +pos/t7233.scala +pos/t6022.scala +pos/tcpoly_checkkinds_mix.scala +pos/depmet_implicit_norm_ret.scala +pos/package-case.scala +pos/philippe4.scala +pos/michel6.scala +pos/t4188.scala +pos/t3936 +pos/t1280.scala +pos/t6722.scala +pos/t796.scala +pos/t5542.scala +pos/t3927.scala +pos/t2293.scala +pos/t3800.scala +pos/t7285a.scala +pos/t927.scala +pos/t4494.scala +pos/t3864 +pos/ilya2 +pos/t2940 +pos/S1.scala +pos/tcpoly_wildcards.scala +pos/tryexpr.scala +pos/t6089b.scala +pos/depmet_implicit_oopsla_zipwith.scala +pos/t245.scala +pos/t6146.scala +pos/t1782 +pos/t851.scala +pos/spec-thistype.scala +pos/tcpoly_poly.scala +pos/t6815_import.scala +pos/t4649.scala +pos/t0453.scala +pos/t5020.scala +pos/ilya +pos/t2435.scala +pos/t1279a.scala +pos/t1957.scala +pos/gadts2.scala +pos/t3567 +pos/Z.scala +pos/t1203b +pos/nested2.scala +pos/t1896 +pos/viewtest2.scala +pos/t5541.scala +pos/existentials-harmful.scala +pos/t4063.scala +pos/t6485a +pos/t1208.scala +pos/t5041.scala +pos/unapplyComplex.scala +pos/t3384.scala +pos/t4112.scala +pos/t788.scala +pos/hklub0.scala +pos/t757.scala +pos/t1197 +pos/t359.scala +pos/t5667.scala +pos/t1107a.scala +pos/virtpatmat_castbinder.scala +pos/t267.scala +pos/t3419 +pos/t3861.scala +pos/t6797.scala +pos/spec-localdefs.scala +pos/t3404 +pos/t4457_1.scala +pos/matthias5.scala +pos/spec-polymeth.scala +pos/kinds.scala +pos/t2310.scala +pos/t6552.scala +pos/valdefs.scala +pos/hkarray.scala +pos/homonym.scala +pos/t1235 +pos/t3429 +pos/t0053.scala +pos/depmet_implicit_chaining_zw.scala +pos/virtpatmat_partialfun_nsdnho.scala +pos/t6664.scala +pos/ticket2251.scala +pos/t3495.scala +pos/super +pos/t121.scala +pos/javaConversions-2.10-ambiguity.scala +pos/t1803.scala +pos/t5877.scala +pos/t0085.scala +pos/t3582.scala +pos/t2939.scala +pos/t1422_pos.scala +pos/manifest1-new.scala +pos/t7505.scala +pos/t5720-ownerous.scala +pos/misc-unapply_pos.scala +pos/tcpoly_variance_pos.scala +pos/t5127.scala +pos/t6123-explaintypes-implicits.scala +pos/t2764 +pos/presuperContext.scala +pos/spec-simple.scala +pos/t3120 +pos/tcpoly_infer_ticket716.scala +pos/tcpoly_bounds1.scala +pos/t7369.scala +pos/imports-pos.scala +pos/t5654.scala +pos/t0123.scala +pos/raw-map +pos/t5330b.scala +pos/t6485b +pos/t6072.scala +pos/t5692c.scala +pos/tcpoly_param_scoping.scala +pos/t6204-b.scala +pos/attachments-typed-another-ident +pos/t5359.scala +pos/ticket2197.scala +pos/t720.scala +pos/t2130-2.scala +pos/t2260.scala +pos/t0304.scala +pos/t464.scala +pos/spec-maps.scala +pos/annotDepMethType.scala +pos/t6117.scala +pos/t911.scala +pos/t757a.scala +pos/t2504.scala +pos/t1381-old.scala +pos/t1232 +pos/needstypeearly.scala +pos/moduletrans.scala +pos/t4957.scala +pos/kinzer.scala +pos/t318.scala +pos/widen-existential.scala +pos/t0095.scala +pos/t566.scala +pos/tcpoly_overloaded.scala +pos/t7516 +pos/t7232 +pos/t698.scala +pos/t0002.scala +pos/t0288 +pos/t2994b.scala +pos/cls.scala +pos/t3622 +pos/t3671.scala +pos/tcpoly_subst.scala +pos/t5703 +pos/depmet_implicit_oopsla_session_simpler.scala +pos/t5022.scala +pos/builders.scala +pos/spec-foo.scala +pos/t756.scala +pos/t1569.scala +pos/implicit-unwrap-tc.scala +pos/t3688.scala +pos/t5198.scala +pos/t432.scala +pos/t6022b.scala +pos/channels.scala +pos/t1075.scala +pos/null.scala +pos/t1840 +pos/t6479.scala +pos/t6311.scala +pos/t0039.scala +pos/t1119.scala +pos/t573.scala +pos/t1136.scala +pos/t3938 +pos/spec-sealed.scala +pos/tcpoly_return_overriding.scala +pos/t3582b.scala +pos/t229.scala +pos/t3498-old.scala +pos/t531.scala +pos/t4545.scala +pos/t6651.scala +pos/t2133.scala +pos/tinondefcons.scala +pos/t6358.scala +pos/t7690.scala +pos/t5779-numeq-warn.scala +pos/list-extractor.scala +pos/t892.scala +pos/t2127.scala +pos/t7180.scala +pos/nullary_poly.scala +pos/virtpatmat_exist3.scala +pos/t1176 +pos/spec-funs.scala +pos/specialize10.scala +pos/t6514.scala +pos/exhaustive_heuristics.scala +pos/t0066.scala +pos/t460.scala +pos/t2130-1.scala +pos/t124.scala +pos/annotations.scala +pos/pat_gilles.scala +pos/array-interfaces.scala +pos/t6210.scala +pos/t3792.scala +pos/implicits-old.scala +pos/t389.scala +pos/t115.scala +pos/virtpatmat_exhaust_unchecked.scala +pos/scoping3.scala +pos/t6033.scala +pos/depmet_implicit_oopsla_session.scala +pos/t602.scala +pos/test5.scala +pos/t611.scala +pos/t5932.scala +pos/t4910.scala +pos/unapplySeq.scala +pos/t344.scala +pos/t3363-new.scala +pos/t4018.scala +pos/t4553.scala +pos/t5082.scala +pos/t3869.scala +pos/t3836.scala +pos/tcpoly_typeapp.scala +pos/t1409 +pos/nonlocal-unchecked.scala +pos/t0082.scala +pos/z1720.scala +pos/t7232c +pos/t2018.scala +pos/t3943 +pos/t2187-2.scala +pos/unicode-decode.scala +pos/t4757 +pos/t0710.scala +pos/t0305.scala +pos/t160.scala +pos/t7591 +pos/simplelists.scala +pos/List1.scala +pos/t516.scala +pos/t6648.scala +pos/t5165 +pos/t0055.scala +pos/t4744 +pos/t7377 +pos/t5726.scala +pos/t0091.scala +pos/t6595.scala +pos/compile.scala +pos/depmet_1_pos.scala +pos/t7364 +pos/philippe3.scala +pos/spec-doubledef-old.scala +pos/t4651.scala +pos/tcpoly_infer_implicit_tuple_wrapper.scala +pos/t6274.scala +pos/tcpoly_infer_explicit_tuple_wrapper.scala +pos/ticket2201.scala +pos/spec-fields-new.scala +pos/optmatch.scala +pos/t7517.scala +pos/t3560.scala +pos/t0165.scala +pos/t0872.scala +pos/t522.scala +pos/t2234.scala +pos/t5031_2.scala +pos/tcpoly_method.scala +pos/t6482.scala +pos/pos-bug1241.scala +pos/implicits-new.scala +pos/t2484.scala +pos/t2425.scala +pos/t1049.scala +pos/michel4.scala +pos/t5958.scala +pos/virtpatmat_instof_valuetype.scala +pos/spec-t6286.scala +pos/t873.scala +pos/t3137.scala +pos/Transactions.scala +pos/t0064.scala +pos/t7486-named.scala +pos/t5444.scala +pos/simple-exceptions.scala +pos/t1006.scala +pos/t7200b.scala +pos/t3777.scala +pos/t4840.scala +pos/t211.scala +pos/nullary.scala +pos/michel1.scala +pos/t5031_3 +pos/typealias_dubious.scala +pos/spec-doubledef-new.scala +pos/philippe1.scala +pos/thistypes.scala +pos/t3570.scala +pos/t6516.scala +pos/context.scala +pos/t3808.scala +pos/philippe2.scala +pos/constfold.scala +pos/t1292.scala +pos/t1147.scala +pos/t404.scala +pos/t4430.scala +pos/A.scala +pos/spec-partially.scala +pos/t5796.scala +pos/t2409 +pos/t284-pos.scala +pos/t5313.scala +pos/t2464 +pos/t1591b.scala +pos/hk-match +pos/t595.scala +pos/t6846.scala +pos/t6162-inheritance.scala +pos/relax_implicit_divergence.scala +pos/patterns2.scala +pos/t4692.scala +pos/t3837.scala +pos/t661.scala +pos/t2810.scala +pos/depexists.scala +pos/virtpatmat_exist4.scala +pos/t5245.scala +pos/t7190.scala +pos/isApplicableSafe.scala +pos/t6204-a.scala +pos/t0076.scala +pos/t1756.scala +pos/t1745 +pos/t6091.scala +pos/t0154.scala +pos/t530.scala +pos/t2094.scala +pos/t1034.scala +pos/t6084.scala +pos/t2454.scala +pos/t2956 +pos/tcpoly_ticket2096.scala +pos/attachments-typed-ident +pos/polymorphic-case-class.scala +pos/t252.scala +pos/spec-constr-old.scala +pos/t2421c.scala +pos/t122.scala +pos/t6574.scala +pos/t3859.scala +pos/spec-params-old.scala +pos/t1196 +pos/t4593.scala +pos/t596.scala +pos/t615.scala +pos/t7689.scala +pos/t3960.scala +pos/t3986.scala +pos/exbound.scala +pos/t2545.scala +pos/t1722 +pos/t159.scala +pos/t3272.scala +pos/t6301.scala +pos/t2794.scala +pos/t3048.scala +pos/t4970.scala +pos/t607.scala +pos/FPTest.scala +pos/test1.scala +pos/t4176.scala +pos/t112606A.scala +pos/t2183.scala +pos/t430-feb09.scala +pos/t6275.scala +pos/t1832.scala +pos/t8965.scala +pos/t7596b +pos/t8900.scala +pos/t9008.scala +pos/t7704.scala +pos/t7459c.scala +pos/sammy_override.scala +pos/t8828.scala +pos/t8868c +pos/t7459d.scala +pos/t8267.scala +pos/t8844.scala +pos/t8868a +pos/t8894.scala +pos/t7459a.scala +pos/t7596c +pos/t8498.scala +pos/t8868b +pos/t5413.scala +pos/t8781 +pos/t8934a +pos/t8310.scala +pos/t3439.scala +pos/t6582_exhaust_big.scala +pos/t8954 +pos/t5217.scala +pos/t7459b.scala +pos/t9018.scala +pos/sammy_exist.scala +pos/t8893.scala +pos/t7596 +pos/t8793.scala +pos/sammy_overload.scala +pos/t6051.scala +pos/t7683-stop-after-parser +pos/t7750.scala +pos/t5454.scala +pos/t8962.scala +pos/t8947 +pos/t8719 +pos/t8410.scala +pos/patmat-suppress.scala +pos/t8999.scala +pos/t8743.scala +pos/t9157.scala +pos/t8801.scala +pos/t9086.scala +pos/t9050.scala +pos/t9135.scala +pos/t9116.scala +pos/t5154.scala +pos/t3368.scala +pos/t9321.scala +pos/t9285.scala +pos/t8861.scala +pos/t9020.scala +pos/jesper.scala +pos/t9356 +pos/virtpatmat_exhaust_big.scala +pos/t9239 +pos/t9111-inliner-workaround + +neg/volatile_no_override.scala +neg/t800.scala +neg/t5426.scala +neg/t2462a.scala +neg/t2641.scala +neg/classtags_dont_use_typetags.scala +neg/t5031 +neg/t2275b.scala +neg/macro-qmarkqmarkqmark.scala +neg/t4879.scala +neg/t5956.scala +neg/t4196.scala +neg/reify_ann2b.scala +neg/t6666b.scala +neg/warn-unused-privates.scala +neg/t6928.scala +neg/t6337.scala +neg/sealed-java-enums.scala +neg/t563.scala +neg/t900.scala +neg/deadline-inf-illegal.scala +neg/t766.scala +neg/t5429.scala +neg/overloaded-implicit.scala +neg/t875.scala +neg/abstract-class-error +neg/unchecked2.scala +neg/predef-masking.scala +neg/viewtest.scala +neg/macro-noexpand +neg/varargs.scala +neg/t963b.scala +neg/t909.scala +neg/sensitive2.scala +neg/t5390b.scala +neg/abstraction-from-volatile-type-error.scala +neg/macro-exception +neg/t4431.scala +neg/t5689.scala +neg/valueclasses.scala +neg/overload.scala +neg/t0204.scala +neg/t908.scala +neg/t750 +neg/patmatexhaust.scala +neg/macro-invalidusage-badtargs +neg/t1168.scala +neg/t5761.scala +neg/t0503.scala +neg/t7235.scala +neg/t1215.scala +neg/primitive-sigs-1 +neg/t5578.scala +neg/names-defaults-neg-warn.scala +neg/t6436b.scala +neg/t3098 +neg/t910.scala +neg/parstar.scala +neg/t4568.scala +neg/newpat_unreachable.scala +neg/t1181.scala +neg/t5903c +neg/t7294.scala +neg/t4091.scala +neg/t5452-old.scala +neg/t5696.scala +neg/t0209.scala +neg/t2910.scala +neg/t7388.scala +neg/noMember2.scala +neg/no-predef.scala +neg/t6952.scala +neg/t1909b.scala +neg/abstract-report2.scala +neg/t5318.scala +neg/t6074.scala +neg/t7171.scala +neg/abstract-vars.scala +neg/unchecked-impossible.scala +neg/variances-refinement.scala +neg/t3453.scala +neg/t5189.scala +neg/t4302.scala +neg/xmltruncated7.scala +neg/t8217-local-alias-requires-rhs.scala +neg/t7602.scala +neg/t8869.scala +neg/t9008.scala +neg/sammy_error_exist_no_crash.scala +neg/t2866.scala +neg/t8597b.scala +neg/t5691.scala +neg/t8534b.scala +neg/t5091.scala +neg/literals.scala +neg/t8534.scala +neg/t8890.scala +neg/t9008b.scala +neg/t8731.scala +neg/t8291.scala +neg/t8597.scala +neg/t5639b +neg/t6582_exhaust_big.scala +neg/t8841.scala +neg/t9041.scala +neg/t9093.scala +neg/t7623.scala +neg/t9231.scala +neg/t9286b.scala +neg/t9273.scala +neg/t9127.scala +neg/t9286c.scala +neg/t9286a.scala +neg/virtpatmat_exhaust_big.scala +neg/inlineMaxSize.scala +neg/patmatexhaust-huge.scala + +run/t7249.scala +run/t3563.scala +run/t6111.scala +run/classtags_multi.scala +run/t5201.scala +run/checked.scala +run/valueclasses-classtag-basic.scala +run/t7171.scala +run/t5053.scala +run/t4535.scala +run/t5923d +run/t7291.scala +run/partialfun.scala +run/macro-term-declared-in-package-object +run/mapValues.scala +run/gadts.scala +run/t2386-new.scala +run/virtpatmat_stringinterp.scala +run/t657.scala +run/t0017.scala +run/t5713 +run/t576.scala +run/t3580.scala +run/virtpatmat_partial.scala +run/t6646.scala +run/mixins.scala +run/t1672.scala +run/macro-expand-implicit-macro-has-implicit +run/tuple-match.scala +run/t7039.scala +run/virtpatmat_opt_sharing.scala +run/virtpatmat_casting.scala +run/t2176.scala +run/macro-impl-relaxed +run/intmap.scala +run/t751.scala +run/t1591.scala +run/macro-typecheck-implicitsdisabled +run/t6911.scala +run/t5604.scala +run/macro-term-declared-in-default-param +run/collection-stacks.scala +run/multi-array.scala +run/t4560b.scala +run/buffer-slice.scala +run/t5629.scala +run/t6690.scala +run/matchonstream.scala +run/t3603.scala +run/lazy-exprs.scala +run/macro-quasiquotes +run/Course-2002-13.scala +run/t6337a.scala +run/exoticnames.scala +run/t0936.scala +run/runtime-richChar.scala +run/t6272.scala +run/t7215.scala +run/t1939.scala +run/ReverseSeqView.scala +run/lazy-leaks.scala +run/t0048.scala +run/t3994.scala +run/t2241.scala +run/t627.scala +run/t5966.scala +run/getClassTest-valueClass.scala +run/t3619.scala +run/t1300.scala +run/t2177.scala +run/t3760.scala +run/t1829.scala +run/macro-expand-implicit-macro-is-view +run/t889.scala +run/QueueTest.scala +run/t4537 +run/t3699.scala +run/t1192.scala +run/macro-expand-tparams-bounds +run/macro-expand-nullary-generic +run/t1434.scala +run/t6443-varargs.scala +run/macro-term-declared-in-trait +run/t4080.scala +run/matcharraytail.scala +run/infiniteloop.scala +run/t5733.scala +run/virtpatmat_nested_lists.scala +run/t5158.scala +run/t6695.scala +run/t6070.scala +run/t4558.scala +run/exc2.scala +run/patmat-behavior-2.scala +run/overloads.scala +run/t6957.scala +run/transform.scala +run/t5500.scala +run/t6663.scala +run/castsingleton.scala +run/t4147.scala +run/virtpatmat_staging.scala +run/t4565_1.scala +run/t5588.scala +run/run-bug4840.scala +run/t3496.scala +run/t5867.scala +run/search.scala +run/t3112.scala +run/hashsetremove.scala +run/t6443.scala +run/macro-expand-tparams-prefix +run/contrib674.scala +run/t3508.scala +run/t4300.scala +run/virtpatmat_typed.scala +run/macro-term-declared-in-class-object +run/map_test.scala +run/t5040.scala +run/t4827b.scala +run/lift-and-unlift.scala +run/t6574b.scala +run/t7240 +run/t3984.scala +run/virtpatmat_tailcalls_verifyerror.scala +run/macro-term-declared-in-class-class +run/emptypf.scala +run/t6104.scala +run/t2818.scala +run/t3761-overload-byname.scala +run/t2526.scala +run/phantomValueClass.scala +run/t3126.scala +run/arybufgrow.scala +run/t3980.scala +run/t7375b +run/t6077_patmat_cse_irrefutable.scala +run/classmanifests_new_core.scala +run/t3395.scala +run/name-based-patmat.scala +run/inliner-infer.scala +run/t5171.scala +run/t3726.scala +run/null-hash.scala +run/t4027.scala +run/t2544.scala +run/patmatnew.scala +run/t5923b +run/t7242.scala +run/classtags_core.scala +run/streamWithFilter.scala +run/t3038b.scala +run/macro-expand-varargs-explicit-over-nonvarargs-good +run/macro-divergence-spurious +run/macro-duplicate +run/t2958.scala +run/patch-boundary.scala +run/t2333.scala +run/lazy-override-run.scala +run/macro-quasiinvalidbody-c +run/t5037.scala +run/takeAndDrop.scala +run/t6126.scala +run/t0883.scala +run/t7617a +run/t4171.scala +run/empty-array.scala +run/t7198.scala +run/t493.scala +run/genericValueClass.scala +run/t0677-old.scala +run/t1373.scala +run/t4461.scala +run/t6011b.scala +run/t7584.scala +run/t3935.scala +run/t6928-run.scala +run/t744.scala +run/t3241.scala +run/blame_eye_triple_eee-double.scala +run/t3829.scala +run/t5577.scala +run/t5914.scala +run/t601.scala +run/t5610.scala +run/macro-basic-mamd-mi +run/t6150.scala +run/stringbuilder.scala +run/t7290.scala +run/t6888.scala +run/t6327.scala +run/virtpatmat_unapplyseq.scala +run/t4656.scala +run/macro-term-declared-in-method +run/macro-expand-implicit-macro-is-implicit +run/blame_eye_triple_eee-float.scala +run/t4482.scala +run/t5488.scala +run/matchemptyarray.scala +run/t3714.scala +run/richWrapperEquals.scala +run/t5328.scala +run/stream_flatmap_odds.scala +run/implicitclasses.scala +run/t6394b +run/complicatedmatch.scala +run/valueclasses-classmanifest-basic.scala +run/unreachable.scala +run/caseclasses.scala +run/withIndex.scala +run/exc1.scala +run/amp.scala +run/t1423.scala +run/t594.scala +run/t6353.scala +run/byname.scala +run/vector1.scala +run/t5879.scala +run/t1048.scala +run/t5080.scala +run/t4190.scala +run/caseClassEquality.scala +run/macro-enclosures +run/collections-toSelf.scala +run/implicits.scala +run/finalvar.scala +run/lazy-locals.scala +run/t7231.scala +run/t0508.scala +run/t6628.scala +run/t6406-regextract.scala +run/t0911.scala +run/t4013c.scala +run/t3502.scala +run/t5648.scala +run/retclosure.scala +run/t2857.scala +run/t4859.scala +run/t5162.scala +run/t3038.scala +run/classof.scala +run/t4062.scala +run/unapplyArray.scala +run/t4297.scala +run/t5923a +run/t1537.scala +run/boolexprs.scala +run/valueclasses-classtag-generic.scala +run/macro-term-declared-in-anonymous +run/tcpoly_monads.scala +run/t5407.scala +run/scan.scala +run/forvaleq.scala +run/null-and-intersect.scala +run/t7047 +run/t0607.scala +run/sequenceComparisons.scala +run/t4396.scala +run/macro-undetparams-consfromsls +run/t2029.scala +run/t1220.scala +run/option-fold.scala +run/t5284c.scala +run/macro-auto-duplicate +run/t3529.scala +run/t4697.scala +run/t2251.scala +run/t5300.scala +run/virtpatmat_valdef.scala +run/t2147.scala +run/virtpatmat_extends_product.scala +run/list_map.scala +run/t1333.scala +run/matchbytes.scala +run/valueclasses-classmanifest-existential.scala +run/records.scala +run/t3088.scala +run/macro-def-path-dependent +run/t6443-by-name.scala +run/t1044.scala +run/delay-good.scala +run/case-class-23.scala +run/weakconform.scala +run/patmat-bind-typed.scala +run/t4835.scala +run/t3097.scala +run/t405.scala +run/existentials.scala +run/t2876.scala +run/t4809.scala +run/t1427.scala +run/t6135.scala +run/t3575.scala +run/t5688.scala +run/t6900.scala +run/macro-expand-unapply-a +run/t6677b.scala +run/t7375a.scala +run/t7300.scala +run/typed-annotated +run/elidable-noflags.scala +run/t0042.scala +run/t3050.scala +run/t4536.scala +run/NestedClasses.scala +run/t3877.scala +run/seqlike-kmp.scala +run/t5907.scala +run/t266.scala +run/missingparams.scala +run/t2255.scala +run/t3488.scala +run/t3950.scala +run/typealias_overriding.scala +run/constant-optimization.scala +run/t7507.scala +run/t6090.scala +run/t4582.scala +run/macro-term-declared-in-class +run/macro-typecheck-macrosdisabled2 +run/t3425.scala +run/t4935.scala +run/t3326.scala +run/boolord.scala +run/t1141.scala +run/virtpatmat_unapply.scala +run/t5971.scala +run/t3651.scala +run/macro-sip19-revised +run/pure-args-byname-noinline.scala +run/preinits.scala +run/t5532.scala +run/concat-two-strings.scala +run/t3269.scala +run/macro-impl-default-params +run/t2162.scala +run/matchonseq.scala +run/t5428.scala +run/macro-expand-overload +run/t4660.scala +run/enrich-gentraversable.scala +run/macro-expand-override +run/t4054.scala +run/t4753.scala +run/macro-typecheck-macrosdisabled +run/t2308a.scala +run/duplicate-meth.scala +run/interop_classtags_are_classmanifests.scala +run/t3232.scala +run/t2075.scala +run/virtpatmat_partial_backquoted.scala +run/try-2.scala +run/macro-openmacros +run/macro-undetparams-macroitself +run/t6318_derived.scala +run/deprecate-early-type-defs.scala +run/dead-code-elimination.scala +run/t4827.scala +run/Course-2002-07.scala +run/slice-strings.scala +run/t6292.scala +run/t6206.scala +run/t1042.scala +run/t1718.scala +run/t2074_2.scala +run/arraycopy.scala +run/indexedSeq.scala +run/macro-term-declared-in-implicit-class +run/t3511.scala +run/t6290.scala +run/distinct.scala +run/virtpatmat_alts.scala +run/valueclasses-pavlov.scala +run/exceptions.scala +run/t1368.scala +run/t5856.scala +run/t6968.scala +run/names-defaults.scala +run/macro-expand-tparams-implicit +run/t5881.scala +run/t3540.scala +run/virtpatmat_try.scala +run/t7181.scala +run/value-class-extractor.scala +run/value-class-extractor-2.scala +run/t3150.scala +run/exc.scala +run/delay-bad.scala +run/infix.scala +run/t1309.scala +run/t6370.scala +run/t6725-2.scala +run/macro-impl-tparam-typetag-is-optional +run/macro-term-declared-in-block +run/matchnull.scala +run/t2127.scala +run/t7325.scala +run/groupby.scala +run/t3932.scala +run/t4871.scala +run/longmap.scala +run/t1524.scala +run/t6187b.scala +run/kmpSliceSearch.scala +run/t7088.scala +run/t5804.scala +run/stringbuilder-drop.scala +run/t5753_1 +run/t9223.scala +run/function-null-unbox.scala +run/t9223b.scala +run/disable-assertions.scala +run/valueClassSelfType.scala +run/indylambda-boxing +run/t9219.scala + +pos/cyclics-pos.scala +pos/cfcrash.scala +pos/tcpoly_higherorder_bound_method.scala +pos/t5084.scala +pos/macro-qmarkqmarkqmark.scala +pos/t7785.scala +pos/nested.scala +pos/t3152.scala +pos/t5031 +pos/t6925b.scala +pos/t1107b +pos/t5012.scala +pos/virtpatmat_obj_in_case.scala +pos/t4938.scala +pos/t3856.scala +pos/spec-cyclic.scala +pos/aliases.scala +pos/typerep_pos.scala +pos/t119.scala +pos/t1050.scala +pos/t3670.scala +pos/t6145.scala +pos/t7315.scala +pos/t5930.scala +pos/t789.scala +pos/t5071.scala +pos/t4731.scala +pos/t4547.scala +pos/t2038.scala +pos/testCoercionThis.scala +pos/t2444.scala +pos/t5744 +pos/t780.scala +pos/t1722-A.scala +pos/virtpatmat_exist1.scala +pos/t6225.scala +pos/t762.scala +pos/t0204.scala +pos/rebind.scala +pos/spec-short.scala +pos/comp-rec-test.scala +pos/lub-dealias-widen.scala +pos/t1168.scala +pos/modules.scala +pos/t4220.scala +pos/t4070.scala +pos/t175.scala +pos/t2500.scala +pos/t5029.scala +pos/itay.scala +pos/t4202.scala +pos/t1987b +pos/t3534.scala +pos/infer2-pos.scala +pos/spec-sparsearray-new.scala +pos/t7091.scala +pos/ticket0137.scala +pos/collectGenericCC.scala +pos/t640.scala +pos/t4305.scala +pos/extractor-types.scala +pos/t3880.scala +pos/spec-annotations.scala +pos/t3577.scala +pos/compile1.scala +pos/spec-t3497.scala +pos/hkrange.scala +pos/t287.scala +pos/t6008.scala +pos/t4432.scala +pos/CustomGlobal.scala +pos/patmat.scala +pos/t2413 +pos/t2910.scala +pos/t592.scala +pos/t6245 +pos/infer.scala +pos/t7228.scala +pos/compound.scala +pos/attributes.scala +pos/t6771.scala +pos/t1090.scala +pos/t684.scala +pos/t577.scala +pos/t4273.scala +pos/t6278-synth-def.scala +pos/t6184.scala +neg/t0214.scala +neg/t4842.scala +neg/t6214.scala +neg/reify_nested_inner_refers_to_local.scala +neg/t576.scala +neg/t5969.scala +neg/tcpoly_variance.scala +neg/t7509.scala +neg/mixins.scala +neg/parent-inherited-twice-error.scala +neg/macro-abort +neg/constructor-init-order.scala +neg/t6042.scala +neg/t0590.scala +neg/t4221.scala +neg/t6263.scala +neg/t783.scala +neg/t5554.scala +neg/macro-invalidsig-params-badtype +neg/multi-array.scala +neg/raw-types-stubs +neg/spec-overrides.scala +neg/t836.scala +neg/t7289_status_quo.scala +neg/t5675.scala +neg/macro-quasiquotes +neg/t6667.scala +neg/t6597.scala +neg/t6264.scala +neg/t0345.scala +neg/t7294b.scala +neg/t5340.scala +neg/t2144.scala +neg/t1010.scala +neg/t1838.scala +neg/t5189b.scala +neg/reify_metalevel_breach_-1_refers_to_1.scala +neg/t6601 +neg/wellkinded_wrongarity.scala +neg/t3909.scala +neg/t876.scala +neg/t5390.scala +neg/unit2anyref.scala +neg/t0351.scala +neg/t5120.scala +neg/t1038.scala +neg/t5878.scala +neg/qualifying-class-error-2.scala +neg/t3816.scala +neg/tailrec.scala +neg/volatile.scala +neg/t944.scala +neg/t1705.scala +neg/t3977.scala +neg/t5553_2.scala +neg/t5318c.scala +neg/overload-msg.scala +neg/t5440.scala +neg/t6335.scala +neg/compile-time-only-b.scala +neg/t501.scala +neg/override.scala +neg/t663.scala +neg/t5892.scala +neg/t1980.scala +neg/macro-false-deprecation-warning +neg/t585.scala +neg/t3776.scala +neg/interop_classtags_arenot_manifests.scala +neg/t4044.scala +neg/macro-invalidusage-nontypeable +neg/t500.scala +neg/t4877.scala +neg/t5357.scala +neg/interop_abstypetags_arenot_manifests.scala +neg/t4460a.scala +neg/t5318b.scala +neg/t4440.scala +neg/t6663.scala +neg/t6357.scala +neg/gadts1.scala +neg/cyclics.scala +neg/t5060.scala +neg/scopes.scala +run/t4013.scala +run/macro-expand-tparams-explicit +run/tuples.scala +run/t5753_2 +run/t0528.scala +run/t5105.scala +run/t7341.scala +run/t3670.scala +run/t2594_tcpoly.scala +run/t3895.scala +run/t0668.scala +run/slices.scala +run/t6666a.scala +run/valueclasses-classmanifest-generic.scala +run/t2316_run.scala +run/t3004.scala +run/viewtest.scala +run/t6481.scala +run/t0005.scala +run/t4766.scala +run/t5500b.scala +run/t7407b.scala +run/backreferences.scala +run/arrayview.scala +run/t629.scala +run/t5903c +run/unittest_collection.scala +run/spec-nlreturn.scala +run/macro-term-declared-in-object-object +run/triple-quoted-expr.scala +run/t5937.scala +run/t6011c.scala +run/macro-expand-implicit-argument +run/try.scala +run/t1987b +run/t6089.scala +run/macro-range +run/t2524.scala +run/t4770.scala +run/virtpatmat_unapplyprod.scala +run/t1535.scala +run/ctor-order.scala +pos/t5210.scala +pos/t5384.scala +pos/rangepos.scala +pos/t443.scala +pos/t1480.scala +pos/t116.scala +pos/seqtest2.scala +pos/scoping1.scala +pos/t4269.scala +pos/lookupswitch.scala +pos/t3642 +pos/t5706.scala +pos/SI-5788.scala +pos/t7264 +pos/t0031.scala +pos/macro-deprecate-dont-touch-backquotedidents.scala +pos/t6815.scala +pos/test4refine.scala +pos/michel5.scala +pos/t0851.scala +pos/t1185.scala +pos/sudoku.scala +pos/t7520.scala +pos/t6208.scala +pos/t3411.scala +pos/t295.scala +pos/S3.scala +pos/t0674.scala +pos/t6664b.scala +pos/variances_pos.scala +pos/liftcode_polymorphic.scala +pos/t3174b.scala +pos/t7232d +pos/t578.scala +pos/implicit-infix-ops.scala +pos/t4363.scala +pos/t532.scala +pos/exponential-spec.scala +pos/t599.scala +pos/t5862.scala +pos/t4603 +pos/t3676.scala +pos/t1357.scala +pos/native-warning.scala +pos/t1230 +pos/t6028 +pos/t4275.scala +pos/overloaded_extractor_and_regular_def.scala +pos/t4205 +pos/matthias1.scala +pos/testcast.scala +pos/generic-sigs.scala +pos/t0093.scala +pos/specializes-sym-crash.scala +pos/t0061.scala +pos/t2429.scala +pos/t694.scala +pos/javaReadsSigs +pos/t2023.scala +pos/t704.scala +pos/t2208_pos.scala +pos/t5137.scala +pos/t2683.scala +pos/t0049.scala +pos/t1029 +pos/t4243.scala +pos/typerep-stephane.scala +pos/t177.scala +pos/t5967.scala +pos/t430.scala +pos/virtpatmat_infer_single_1.scala +pos/pat_iuli.scala +pos/t1071.scala +pos/t7226.scala +pos/t1843.scala +pos/t419.scala +pos/t7364b +pos/t1159.scala +pos/t5305.scala +pos/t7694.scala +pos/t6047.scala +pos/t3578.scala +pos/t2082.scala +pos/setter-not-implicit.scala +pos/t1133.scala +pos/t3862.scala +pos/t942 +pos/nothing_manifest_disambig-new.scala +pos/iterator-traversable-mix.scala +pos/eta.scala +pos/test4.scala +pos/t2691.scala +pos/t4502.scala +pos/t7183.scala +pos/protected-t1010.scala +pos/X.scala +pos/virtpatmat_exist2.scala +pos/t4911.scala +pos/t3477.scala +pos/t4173.scala +pos/t7782.scala +pos/t2399.scala +pos/virtpatmat_alts_subst.scala +pos/propagate.scala +pos/t2421b_pos.scala +pos/t183.scala +pos/t7033.scala +pos/t3612.scala +pos/t5330c.scala +pos/t3020.scala +pos/t4869.scala +pos/t3373.scala +pos/spec-params-new.scala +pos/t3672.scala +pos/t4501.scala +pos/t1565.scala +pos/t3774.scala +pos/t6942 +pos/t845.scala +pos/t3240.scala + +neg/t3275.scala +neg/t421.scala +neg/t5702-neg-bad-brace.scala +neg/t3663 +neg/badtok-1.scala +neg/t677.scala +neg/t7756b.scala +neg/t6534.scala +neg/t6276.scala +neg/t5762.scala +neg/abstract.scala +neg/t2405.scala +neg/t0418.scala +neg/t5390c.scala +neg/lazyvals.scala +neg/lubs.scala +neg/abstract-report.scala +neg/t4163.scala +neg/t5702-neg-bad-and-wild.scala +neg/macro-invalidret +neg/t6728.scala +neg/t5152.scala +neg/t1432.scala +neg/abstract-inaccessible.scala +neg/import-precedence.scala +neg/t2462b.scala +neg/macro-invalidusage-presuper +neg/specification-scopes +neg/t6048.scala +neg/t4079 +neg/macro-basic-mamdmi +neg/t7020.scala +neg/t3015.scala +neg/t0207.scala +neg/t2296b +neg/t0673 +neg/t3761-overload-byname.scala +neg/t6675.scala +neg/t5529.scala +neg/sensitive.scala +neg/t742.scala +neg/t5067.scala +neg/t6162-overriding.scala +neg/variances.scala +neg/t5728.scala +neg/t6323a.scala +neg/compile-time-only-a.scala +neg/t6795.scala +neg/t2494.scala +neg/t3649.scala +neg/macro-invalidsig +neg/t2796.scala +neg/t112706A.scala +neg/t0764.scala +neg/t3757 +neg/t1431.scala +neg/exhausting.scala +neg/t1523.scala +neg/t779.scala +neg/xmltruncated1.scala +neg/t2208.scala +neg/t2078.scala +neg/t521.scala +neg/null-unsoundness.scala +neg/stmt-expr-discard.scala +neg/t0513.scala +neg/unchecked-abstract.scala +neg/t4460c.scala +neg/divergent-implicit.scala +neg/t5078.scala +neg/t1701.scala +neg/t0816.scala +neg/t1672b.scala +neg/macro-invalidusage-badbounds +neg/tailrec-2.scala +neg/t4064.scala +neg/t5510.scala +neg/t3873.scala +neg/tailrec-3.scala +neg/t0226.scala +neg/t2031.scala +neg/t633.scala +neg/constrs.scala +neg/anyval-anyref-parent.scala +neg/t7290.scala +neg/t1041.scala +neg/patternalts.scala +neg/error_tooManyArgsPattern.scala +neg/checksensibleUnit.scala +neg/t6539 +neg/t4417.scala +neg/wellkinded_app.scala +neg/for-comprehension-old.scala +neg/t2779.scala +neg/object-not-a-value.scala +neg/t2968b.scala +neg/t6483.scala +neg/t6902.scala +neg/t6963a.scala +neg/t3399.scala +neg/t0015.scala +neg/t3995.scala +neg/t276.scala +neg/t6758.scala +neg/t2441.scala +neg/cycle-bounds.scala +neg/t1241.scala +neg/t4137.scala +neg/unicode-unterminated-quote.scala +neg/t4762.scala +neg/typeerror.scala +neg/implicits.scala +neg/t961.scala +neg/ambiguous-float-dots2.scala +neg/t2416.scala +neg/t5799.scala +neg/t7285.scala +neg/implicit-shadow.scala +neg/t2388.scala +neg/java-access-neg +neg/found-req-variance.scala +neg/hk-bad-bounds.scala +neg/t3224.scala +neg/t1033.scala +neg/t7385.scala +neg/t5882.scala +neg/t4541.scala +neg/t2973.scala +neg/t6406-regextract.scala +neg/t6666.scala +neg/t4831.scala +neg/t425.scala +neg/t1845.scala +neg/t3683b.scala +neg/t2801.scala +neg/t6083.scala +neg/t0528neg.scala +neg/stringinterpolation_macro-neg.scala +neg/t668.scala +neg/t5666.scala +neg/t4271.scala +neg/interop_typetags_arenot_classmanifests.scala +neg/t1355.scala +neg/t715.scala +neg/t7238.scala +neg/t7473.scala +neg/t7292-removal.scala +neg/tcpoly_infer_ticket1162.scala +neg/t4098.scala +neg/t6013 +neg/t6227.scala +neg/t464-neg.scala +neg/badtok-3.scala +neg/t6082.scala +neg/anytrait.scala +neg/valueclasses-doubledefs.scala +neg/t7519.scala +neg/overloaded-unapply.scala +neg/t1163.scala +neg/wellkinded_bounds.scala +neg/t7292-deprecation.scala +neg/t5044.scala +neg/t0842.scala +neg/t6436.scala +neg/interop_typetags_arenot_classtags.scala +neg/t3653.scala +neg/higherkind_novalue.scala +neg/t935.scala +neg/t6040.scala +neg/annot-nonconst.scala +neg/macro-deprecate-idents.scala +neg/illegal-stmt-start.scala +neg/t565.scala +neg/case-collision.scala +neg/t3209.scala +neg/t5821.scala +neg/abstract-class-2.scala +neg/t846.scala +neg/quasiquotes-syntax-error-position.scala +neg/t3987.scala +neg/t877.scala +neg/t0117.scala +neg/t692.scala +neg/t5702-neg-ugly-xbrace.scala +neg/t7752.scala +neg/case-collision2.scala +neg/t6526.scala +neg/t2213.scala +neg/t7756a.scala +neg/macro-override-macro-overrides-abstract-method-a +neg/tcpoly_ticket2101.scala +neg/delayed-init-ref.scala +neg/caseinherit.scala +neg/t3189.scala +neg/unchecked-suppress.scala +neg/t2180.scala +neg/t1371.scala +neg/macro-cyclic +neg/t6123-explaintypes-macros +neg/t4134.scala +neg/t691.scala +neg/t2421b.scala +neg/t4691_exhaust_extractor.scala +neg/t4419.scala +neg/t5801.scala +neg/t650.scala +neg/t5735.scala +neg/t696.scala +neg/t882.scala +neg/t2968.scala +neg/t7507.scala +neg/macro-invalidusage-badargs +neg/macro-reify-typetag-typeparams-notags +neg/wellkinded_app2.scala +neg/t4425b.scala +neg/t2296a +neg/t1878.scala +neg/t649.scala +neg/override-object-no.scala +neg/t4174.scala +neg/t2070.scala +neg/sabin2.scala +neg/t5903e +neg/t6566a.scala +neg/finitary-error.scala +neg/t4818.scala +neg/t3614.scala +neg/t6666c.scala +neg/ticket513.scala +neg/suggest-similar.scala +neg/t4457_1.scala +neg/t6666e.scala +neg/tcpoly_bounds.scala +neg/t4727.scala +neg/t4425.scala +neg/macro-invalidusage-methodvaluesyntax +neg/t3854.scala +neg/t3006.scala +neg/t5580b.scala +neg/t5378.scala +neg/t639.scala +neg/wrong-args-for-none.scala +neg/t7171b.scala +neg/t5361.scala +neg/unreachablechar.scala +neg/t5572.scala +neg/t7757a.scala +neg/macro-invalidimpl +neg/t2773.scala +neg/t6359.scala +neg/saito.scala +neg/xmltruncated2.scala +neg/t667.scala +neg/t3934.scala +neg/t6771b.scala +neg/t4584.scala +neg/wellkinded_wrongarity2.scala +neg/t7369.scala +neg/t1477.scala +neg/t5617.scala +neg/t7299.scala +neg/faculty.scala +neg/virtpatmat_reach_null.scala +neg/macro-reify-typetag-hktypeparams-notags +neg/t1224.scala +neg/xmltruncated3.scala +neg/t1872.scala +neg/t558.scala +neg/t7110.scala +neg/any-vs-anyref.scala +neg/t6340.scala +neg/t4166.scala +neg/t2918.scala +neg/t5856.scala +neg/t4989.scala +neg/t0003.scala +neg/t1183.scala +neg/t963.scala +neg/t4515.scala +neg/valueclasses-pavlov.scala +neg/t608.scala +neg/choices.scala +neg/patmat-type-check.scala +neg/valueclasses-impl-restrictions.scala +neg/imp2.scala +neg/protected-constructors.scala +neg/t6788.scala +neg/nullary-override.scala +neg/t200.scala +neg/t343.scala +neg/names-defaults-neg-ref.scala +neg/tcpoly_typealias.scala +neg/classtags_contextbound_b.scala +neg/t729.scala +neg/t5683.scala +neg/t4928.scala +neg/t700.scala +neg/t7669.scala +neg/macro-invalidshape +neg/t6011.scala +neg/t7325.scala +neg/check-dead.scala +neg/t550.scala +neg/t5663-badwarneq.scala +neg/t0699 +neg/nopredefs.scala +neg/t3507-old.scala +neg/t5352.scala +neg/t6336.scala +neg/interop_classmanifests_arenot_typetags.scala +neg/sealed-final-neg.scala +neg/t2102.scala +neg/t7636.scala +neg/t5031b +neg/t798.scala +neg/t5702-neg-bad-xbrace.scala +neg/t0899.scala +neg/cyclics-import.scala +neg/badtok-2.scala +neg/t473.scala +neg/t3160ambiguous.scala +neg/t5106.scala +neg/t1286 +neg/macro-override-macro-overrides-abstract-method-b +neg/t0259.scala +neg/t510.scala +neg/t3836.scala +neg/t5830.scala +neg/t1548 +neg/t5580a.scala +neg/forward.scala +neg/t591.scala +neg/t6558b.scala +neg/t556.scala +neg/xmltruncated4.scala +neg/t5497.scala +neg/t409.scala +neg/t6283.scala +neg/override-object-flag.scala +neg/constructor-prefix-error.scala +neg/eta-expand-star.scala +neg/t3392.scala +neg/t1275.scala +neg/nested-fn-print.scala +neg/t7330.scala +neg/t2275a.scala +neg/t630.scala +neg/t4270.scala +neg/t2775.scala +neg/pat_unreachable.scala +neg/t4158.scala +neg/unit-returns-value.scala +neg/t1422.scala +neg/reify_metalevel_breach_-1_refers_to_0_b.scala +neg/reassignment.scala +neg/t3683a.scala +neg/noMember1.scala +neg/macro-without-xmacros-b +neg/t1106.scala +neg/t5182.scala +neg/t6889.scala +neg/t4217.scala +neg/t7501 +neg/t5063.scala +neg/t1009.scala +neg/t997.scala +neg/unchecked.scala +neg/classtags_contextbound_c.scala +neg/applydynamic_sip.scala +neg/t7715.scala +neg/t588.scala +neg/t6667b.scala +neg/t7757b.scala +neg/t4069.scala +neg/t515.scala +neg/variances2.scala +neg/t1049.scala +neg/t7289.scala +neg/t1623.scala +neg/permanent-blindness.scala +neg/t5803.scala +neg/super-cast-or-test.scala +neg/nonlocal-warning.scala +neg/t5687.scala +neg/t5903a +neg/t6566b.scala +neg/unchecked-knowable.scala +neg/t5093.scala +neg/protected-static-fail +neg/type-diagnostics.scala +neg/forgot-interpolator.scala +neg/interop_abstypetags_arenot_classmanifests.scala +neg/t5376.scala +neg/t545.scala +neg/xmlcorner.scala +neg/switch.scala +neg/depmet_1.scala +neg/abstract-concrete-methods.scala +neg/t4987.scala +neg/t5452-new.scala +neg/t750b +neg/unchecked-refinement.scala +neg/t418.scala +neg/t5354.scala +neg/t3736.scala +neg/t631.scala +neg/t6829.scala +neg/t0218.scala +neg/volatile-intersection.scala +neg/t412.scala +neg/t693.scala +neg/t4882.scala +neg/t1960.scala +neg/macro-divergence-controlled +neg/t712.scala +neg/t5544 +neg/t3222.scala +neg/t3604.scala +neg/t1112.scala +neg/t7157 +neg/accesses.scala +neg/t452.scala +neg/t6162-inheritance +neg/t2442 +neg/t6567.scala +neg/lazy-override.scala +neg/abstract-explaintypes.scala +neg/nested-annotation.scala +neg/t5753 +neg/t4283b +neg/t3691.scala +neg/infix-op-positions.scala +neg/t3403.scala +neg/t4851 +neg/structural.scala +neg/error_dependentMethodTpeConversionToFunction.scala +neg/t5839.scala +neg/t5553_1.scala +neg/reify_metalevel_breach_+0_refers_to_1.scala +neg/t752.scala +neg/t6574.scala +neg/t3714-neg.scala +neg/t4457_2.scala +neg/t2148.scala +neg/t1364.scala +neg/saferJavaConversions.scala +neg/t414.scala +neg/t5493.scala +neg/classtags_contextbound_a.scala +neg/reify_metalevel_breach_-1_refers_to_0_a.scala +neg/t3118.scala +neg/t512.scala +neg/t2336.scala +neg/t856.scala +neg/xmltruncated6.scala +neg/t2206.scala +neg/virtpatmat_unreach_select.scala +neg/t6258.scala +neg/t6815.scala +neg/not-possible-cause.scala +neg/dbldef.scala +neg/qualifying-class-error-1.scala +neg/t835.scala +neg/t5455.scala +neg/t6558.scala +neg/t708.scala +neg/macro-nontypeablebody +neg/t0565.scala +neg/xmltruncated5.scala +neg/t5390d.scala +neg/t520.scala +neg/t6138.scala +neg/macro-without-xmacros-a +neg/t7214neg.scala +neg/t2870.scala +neg/t593.scala +neg/t4541b.scala +neg/t4460b.scala +neg/t284.scala +neg/t2488.scala +neg/macro-override-method-overrides-macro +neg/interop_abstypetags_arenot_classtags.scala +neg/t3769.scala +neg/warn-inferred-any.scala +neg/t664.scala +neg/t5903d +neg/t562.scala +neg/t2316.scala +neg/t0152.scala +neg/migration28.scala +neg/t6443c.scala +neg/tcpoly_override.scala +neg/t7324.scala +neg/t987.scala +neg/t5903b +neg/t3481.scala +neg/t6912.scala +neg/tcpoly_variance_enforce.scala +neg/t3913.scala +neg/names-defaults-neg.scala +neg/t765.scala +neg/t5358.scala +neg/t391.scala +neg/serialversionuid-not-const.scala +neg/t771.scala +neg/t0903.scala +neg/catch-all.scala +neg/classmanifests_new_deprecations.scala +neg/t0606.scala +neg/t5189_inferred.scala +neg/macro-reify-typetag-useabstypetag +neg/t5543.scala +neg/logImplicits.scala +neg/interop_typetags_without_classtags_arenot_manifests.scala +neg/t6535.scala +neg/t7259.scala +neg/t2139.scala +neg/t278.scala +neg/t5564.scala +neg/unchecked3.scala +neg/virtpatmat_reach_sealed_unsealed.scala +neg/checksensible.scala +neg/t7721.scala +run/t3798.scala +run/macro-expand-varargs-explicit-over-varargs +run/t3888.scala +run/t0677-new.scala +run/t3273.scala +run/t3763.scala +run/t2755.scala +run/t920.scala +run/t5610a.scala +run/literals.scala +run/proxy.scala +run/unapply.scala +run/t5830.scala +run/array-addition.scala +run/macro-expand-nullary-nongeneric +run/macro-basic-ma-mdmi +run/valueclasses-constr.scala +run/t1247.scala +run/t3487.scala +run/rawstrings.scala +run/patmat-seqs.scala +run/eta-expand-star.scala +run/t7436.scala +run/t3996.scala +run/constructors.scala +run/t498.scala +run/t3835.scala +run/t298.scala +run/t2867.scala +run/t7120 +run/virtpatmat_literal.scala +run/t2175.scala +run/t2503.scala +run/t3026.scala +run/t603.scala +run/t0091.scala +run/t6394a +run/macro-expand-varargs-implicit-over-varargs +run/t7407.scala +run/t2552.scala +run/virtpatmat_npe.scala +run/macro-sip19 +run/t6644.scala +run/t6614.scala +run/t2005.scala +run/t4680.scala +run/t5903a +run/classtags_contextbound.scala +run/Course-2002-05.scala +run/applydynamic_sip.scala +run/t1766.scala +run/retsynch.scala +run/t7715.scala +run/t102.scala +run/nonlocalreturn.scala +run/macro-reify-staticXXX +run/Course-2002-06.scala +run/t6863.scala +run/t6500.scala +run/macro-impl-rename-context +run/t4351.scala +run/t5009.scala +run/macro-term-declared-in-annotation +run/t6271.scala +run/array-existential-bound.scala +run/t6443b.scala +run/t1987.scala +run/MutableListTest.scala +run/t7571.scala +run/t5488-fn.scala +run/macro-bodyexpandstoimpl +run/macro-reify-ref-to-packageless +run/t2212.scala +run/macro-expand-varargs-implicit-over-nonvarargs +run/t0807.scala +run/patmat-behavior.scala +run/t2446.scala +run/breakout.scala +run/t4122.scala +run/macro-settings +run/t7157 +run/t1323.scala +run/t4013b.scala +run/t6309.scala +run/t4047.scala +run/t5544 +run/t978.scala +run/t3361.scala +run/t6611.scala +run/t5387.scala +run/t5656.scala +run/t4897.scala +run/numeric-range.scala +run/t4777.scala +run/Course-2002-03.scala +run/string-extractor.scala +run/view-headoption.scala +run/patmat_unapp_abstype-new.scala +run/stream-stack-overflow-filter-map.scala +run/macro-impl-tparam-only-in-impl +run/t6559.scala +run/macro-reify-tagful-a +run/macro-expand-multiple-arglists +run/t4709.scala +run/t3509.scala +run/t5284b.scala +run/t7617b +run/t3923.scala +run/virtpatmat_apply.scala +run/t363.scala +run/manifests-undeprecated-in-2.10.0.scala +run/matchintasany.scala +run/t3970.scala +run/t4996.scala +run/t5530.scala +run/macro-term-declared-in-object-class +run/t3242b.scala +run/indexedSeq-apply.scala +run/t107.scala +run/t2337.scala +run/t2754.scala +run/flat-flat-flat.scala +run/t6673.scala +run/interpolationMultiline2.scala +run/t0631.scala +run/t2800.scala +run/t6506.scala +run/t6260.scala +run/t2418.scala +run/t4415.scala +run/classmanifests_new_alias.scala +run/t5380.scala +run/tcpoly_parseridioms.scala +run/t1747.scala +run/t5903d +run/t3530.scala +run/t216.scala +run/macro-term-declared-in-refinement +run/t4592.scala +run/t2488.scala +run/t3327.scala +run/t5614.scala +run/t5903b +run/iterables.scala +run/t3964.scala +run/t6329_vanilla.scala +run/t3038c +run/t1697.scala +run/t2030.scala +run/t3397.scala +run/t1005.scala +run/t3353.scala +run/t1466.scala +run/t3186.scala +run/tcpoly_overriding.scala +run/t5394.scala +run/t5284.scala +run/unboxingBug.scala +run/t7200.scala +run/macro-reify-basic +run/t153.scala +run/iterator3444.scala +run/macro-expand-implicit-macro-is-val +run/macro-basic-ma-md-mi +run/interpolationArgs.scala +run/t4954.scala +run/t3645.scala +run/transpose.scala +run/t3887.scala +run/t4288.scala +run/unittest_iterator.scala +run/t5543.scala +run/macro-term-declared-in-object +run/iq.scala +run/t2788.scala +run/t2027.scala +run/macro-expand-recursive +run/t949.scala +run/t1909b.scala +run/delambdafy-nested-by-name.scala +run/delambdafy-two-lambdas.scala +run/macro-blackbox-materialization +run/lists-run.scala +run/macro-parse-position +run/macro-parse-position-malformed +run/macro-whitebox-dynamic-materialization +run/macro-whitebox-extractor +run/macro-vampire-false-warning +run/macro-whitebox-fundep-materialization +run/macro-whitebox-structural +run/mutable-treeset.scala +run/static-module-method.scala +run/sort.scala +run/t1909.scala +run/t1909c.scala +run/t3346a.scala +run/t3346d.scala +run/t3346f.scala +run/t3346h.scala +run/t3346g.scala +run/t3832.scala +run/t4742.scala +run/t5377.scala +run/t5923c.scala +run/t6188.scala +run/t6333.scala +run/t6385.scala +run/t7899.scala +run/t7584b.scala +run/t7223.scala +run/t7859 +run/t7868.scala +run/t7871 +run/arrayclone-new.scala +run/arrayclone-old.scala +run/bitsets.scala +run/comparable-comparator.scala +run/colltest1.scala +run/t2106.scala +run/t5986.scala +run/view-iterator-stream.scala +run/array-charSeq.scala +pos/signatures +pos/t1263 +pos/t3249 +neg/t4749.scala +neg/main1.scala +neg/t7251 +neg/t7494-after-terminal +neg/t7494-before-parser +neg/t7494-right-after-terminal +run/lazy-traits.scala +run/OrderingTest.scala +run/ReplacementMatching.scala +run/patmat-finally.scala +run/t3158.scala +run/t3346e.scala +run/t4398.scala +run/t4930.scala +run/t6534.scala +pos/sammy_scope.scala +pos/delambdafy-patterns.scala +pos/private-types-after-typer.scala +pos/delambdafy-lambdalift.scala +pos/sammy_poly.scala +pos/sammy_single.scala +pos/SI-4012-b.scala +pos/sammy_twice.scala +pos/t3160.scala +pos/t1014.scala +pos/t4970b.scala +pos/t2698.scala +pos/t5845.scala +pos/t6201.scala +pos/t6260a.scala +pos/t7688.scala +pos/t7818.scala +pos/t1203a.scala +pos/t7834.scala +pos/t7853.scala +pos/t7815.scala +pos/t7853-partial-function.scala +pos/t7864.scala +pos/t7928.scala +pos/t7902.scala +pos/t7944.scala +pos/t7847 +neg/accesses2.scala +neg/bad-advice.scala +neg/gadts2.scala +neg/gadts2-strict.scala +neg/macro-bundle-abstract.scala +neg/macro-bundle-object.scala +neg/macro-bundle-trait.scala +neg/macro-blackbox-dynamic-materialization +neg/macro-blackbox-extractor +neg/run-gadts-strict.scala +neg/macro-blackbox-structural +neg/sammy_restrictions.scala +neg/sammy_wrong_arity.scala +neg/t2462c.scala +neg/t3346b.scala +neg/t1909-object.scala +neg/macro-blackbox-fundep-materialization +neg/t3346c.scala +neg/t3871.scala +neg/t3871b.scala +neg/t3971.scala +neg/t3346i.scala +neg/t6120.scala +neg/t6260c.scala +neg/t6680a.scala +neg/t7239.scala +neg/t7007.scala +neg/t7605-deprecation.scala +neg/t7622-missing-required.scala +neg/t7629-view-bounds-deprecation.scala +neg/t7834neg.scala +neg/t7783.scala +neg/t7848-interp-warn.scala +neg/t7519-b +neg/t7622-missing-dependency +neg/t7870.scala +neg/t7877.scala +neg/t7895.scala +neg/t7895b.scala +neg/t7899.scala +neg/t7895c.scala +neg/t7859 +run/t4752.scala +run/t2087-and-2400.scala +run/t3855.scala +run/t6637.scala +run/t6731.scala +pos/t3999b.scala +run/t0432.scala +run/t2514.scala +run/t7817.scala +run/t874.scala +run/type-currying.scala +run/t3616.scala +run/t3687.scala +run/t4570.scala +run/t5612.scala +run/t1110.scala +run/t2636.scala +run/verify-ctor.scala +run/t3647.scala +run/t4560.scala +run/t6632.scala +run/richs.scala +run/t6725-1.scala +pos/t7776.scala +run/fors.scala +run/t6706.scala +run/t3175.scala +run/delambdafy-dependent-on-param-subst.scala +run/t4332b.scala +run/t8048a +run/t8017 +run/t7985b.scala +run/t8100.scala +run/patmat-mix-case-extractor.scala +run/t4750.scala +run/t7912.scala +run/delambdafy-dependent-on-param-subst-2.scala +run/t8048b +run/t8091.scala +run/macroPlugins-macroRuntime +run/macro-default-params +run/t6355.scala +run/t7777 +run/t8002.scala +run/t8015-ffc.scala +run/macro-subpatterns +run/t7985.scala +run/macroPlugins-macroArgs +run/t7326.scala +run/t5045.scala +run/value-class-partial-func-depmet.scala +run/t6329_vanilla_bug.scala +run/macroPlugins-macroExpand +run/t8010.scala +run/macroPlugins-typedMacroBody +run/t7406.scala +pos/t8146a.scala +pos/t8046c.scala +pos/t8132.scala +pos/t8045.scala +pos/overzealous-assert-genbcode.scala +pos/t8128.scala +pos/t8013 +pos/t8064b +pos/t6780.scala +pos/t7987 +pos/bcode_throw_null +pos/t8064 +pos/t8046.scala +pos/t6231.scala +pos/t7983.scala +pos/t5508.scala +pos/t5508-min.scala +pos/t8023b.scala +pos/t6231b.scala +pos/debug-reset-local-attrs.scala +pos/t8054.scala +pos/t2066.scala +pos/dotless-targs.scala +pos/t8120.scala +pos/t5508-min-okay.scala +pos/t8060.scala +pos/t8001 +pos/t8138.scala +pos/t8111.scala +pos/t8011.scala +pos/t8146b.scala +pos/t8046b.scala +pos/t8023.scala +pos/t5508-min-okay2.scala +pos/macro-implicit-invalidate-on-error.scala +neg/t6563.scala +neg/missing-param-type-tuple.scala +neg/not-a-legal-formal-parameter-tuple.scala +neg/t7897.scala +neg/t8015-ffa.scala +neg/quasiquotes-unliftable-not-found.scala +neg/t2066b.scala +neg/dotless-targs.scala +neg/patmat-classtag-compound.scala +neg/t2066.scala +neg/t8035-deprecated.scala +neg/t6675b.scala +neg/t8104 +neg/t7872.scala +neg/t7850.scala +neg/t7967.scala +neg/macro-bundle-overloaded.scala +neg/t6355a.scala +neg/class-of-double-targs.scala +neg/t6355b.scala +neg/macro-reify-splice-splice +neg/macro-bundle-noncontext.scala +neg/t8015-ffb.scala +neg/t8035-removed.scala +neg/t7984.scala +neg/t8024.scala +neg/t8024b.scala +neg/t8157.scala +neg/t8146-non-finitary-2.scala +neg/t8006.scala +neg/t7872c.scala +neg/t8146-non-finitary.scala +neg/t7872b.scala +neg/t6920.scala +run/t6200.scala +run/t6196.scala +run/macro-bundle-context-refinement +run/macro-enclosingowner-detectvar +run/macro-enclosingowner-sbt +run/macro-bundle-context-alias +run/macro-bundle-whitebox-use-refined +run/macro-bundle-whitebox-use-raw +neg/name-lookup-stable.scala +neg/t0764b.scala +neg/no-implicit-to-anyref-any-val.scala +neg/t1503.scala +neg/t4728.scala +neg/t6455.scala +neg/t6260-named.scala +neg/t6844.scala +neg/t7475c.scala +neg/t7475e.scala +neg/t7475f.scala +neg/macro-bundle-whitebox-use-raw +neg/macro-bundle-whitebox-use-refined +neg/macro-incompatible-macro-engine-b +neg/t7980.scala +neg/macro-incompatible-macro-engine-a +neg/t8143a.scala +neg/t8072.scala +neg/t8207.scala +neg/t8182.scala +neg/t8219-any-any-ref-equals.scala +neg/t8177a.scala +neg/t8228.scala +neg/t8229.scala +neg/t8237-default.scala +neg/t8244b.scala +neg/t8244e +neg/t8244c.scala +neg/t8265.scala +neg/t8266-invalid-interp.scala +neg/t6931 +neg/t8376 +neg/t8372.scala +neg/t8300-overloading.scala +neg/t8244 +neg/t8158 +neg/t8431.scala +pos/implicit-anyval-2.10.scala +pos/delambdafy_t6260_method.scala +pos/macro-bundle-disambiguate-bundle.scala +pos/macro-bundle-disambiguate-nonbundle.scala +pos/package-ob-case +pos/t1786-counter.scala +pos/reflection-compat-api-universe.scala +pos/existential-java-case-class +pos/t1786-cycle.scala +pos/reflection-compat-c.scala +pos/t3452f.scala +pos/reflection-compat-ru.scala +pos/t2066-2.10-compat.scala +pos/reflection-compat-macro-universe.scala +pos/t5900a.scala +pos/t5760-pkgobj-warn +pos/t5954a +pos/t5954b +pos/t5954d +pos/t6260.scala +pos/t5165b +pos/t5954c +pos/t6260b.scala +pos/t7475b.scala +pos/t7475a.scala +pos/t7753.scala +pos/t7322.scala +pos/t6948.scala +pos/t7475d.scala +pos/t7475e.scala +pos/t6169 +pos/t7788.scala +pos/t7919.scala +pos/t8177a.scala +pos/t8177.scala +pos/t8170.scala +pos/t8170b.scala +pos/t8177d.scala +pos/t8177b.scala +pos/t8177e.scala +pos/t8134 +pos/t8177h.scala +pos/t8177g.scala +pos/t8207.scala +pos/t8187.scala +pos/t8219.scala +pos/t8219b.scala +pos/t8224.scala +pos/t8237.scala +pos/t8223.scala +pos/t8237b.scala +pos/t8300-conversions-a.scala +pos/t8300-conversions-b.scala +pos/t8209a +pos/t8209b +pos/t8244d +pos/t8300-overloading.scala +pos/t8300-patmat-a.scala +pos/t8300-patmat-b.scala +pos/t8301.scala +pos/t8324.scala +pos/t8301b.scala +pos/t8363.scala +pos/t8367.scala +pos/t8369a.scala +pos/t8369b.scala +pos/t8403.scala +pos/t8364.scala +pos/t8352 +pos/t8376 +neg/macro-bundle-nonpublic-c.scala +neg/literate_existentials.scala +neg/macro-bundle-nonpublic-impl.scala +neg/macro-bundle-ambiguous.scala +neg/macro-bundle-priority-bundle.scala +neg/macro-bundle-need-qualifier.scala +neg/macro-bundle-nonstatic.scala +neg/macro-bundle-polymorphic.scala +neg/macro-bundle-priority-nonbundle.scala +neg/macro-bundle-wrongcontext-a.scala +neg/macro-bundle-wrongcontext-b.scala +run/t8425 +run/t8245.scala +run/t8266-octal-interp.scala +run/t8280.scala +run/t8395.scala +run/t8321 +run/t8153.scala +run/t8197.scala +run/t8197b.scala +run/t8233.scala +run/t8133 +run/t8133b +run/t7475b.scala +run/t6814 +run/t4577.scala +run/t5134.scala +run/t3452f.scala +run/t3452h.scala +run/t3452c.scala +run/t3452.scala +run/t261.scala +run/t3235-minimal.scala +run/t1503_future.scala +run/t5565.scala +pos/t8411 +pos/t8460.scala +run/t8428.scala +run/t8437 +run/absoverride.scala +run/arrays.scala +run/duration-coarsest.scala +run/iterator-from.scala +run/SymbolsTest.scala +run/t1074.scala +run/t1505.scala +run/streams.scala +run/t2111.scala +run/t4601.scala +pos/SI-4012-a.scala +pos/SI-7638.scala +neg/t3692-new.scala +run/t7015.scala +run/t7992b.scala +run/t7992.scala +run/t8570.scala +pos/t8157-2.10.scala +pos/t8325.scala +pos/t8523.scala +pos/t8578.scala +pos/t8329.scala +pos/t8497 +pos/t8546.scala +pos/t8531 +neg/t8325-c.scala +neg/t8325-b.scala +neg/t8325.scala +neg/t6988.scala +neg/t8463.scala +neg/t8450.scala +neg/t8430.scala +run/finally.scala +neg/t8630.scala +neg/t8035-no-adapted-args.scala +neg/t8675b.scala +neg/t8610-arg.scala +neg/t8736-c.scala +neg/tailrec-4.scala +neg/double-def-top-level +neg/t8610.scala +neg/aladdin1055 +neg/virtpatmat_exhaust_compound.scala +neg/t8675.scala +neg/t8525.scala +pos/t8736.scala +pos/t8625.scala +pos/t8596.scala +pos/t8617.scala +pos/t8736-b.scala +pos/t8708 +pos/macro-attachments +run/t8611a.scala +run/t8738.scala +run/macro-rangepos-args +run/t8610.scala +run/macro-rangepos-subpatterns +run/t8611c.scala +run/macroPlugins-isBlackbox +run/t8601d.scala +run/t8607.scala +run/bugs.scala +run/t1503.scala +run/t4148.scala +run/t7763.scala +run/issue192.scala +run/t8893b.scala +run/t8845.scala +run/t8933 +run/t7459c.scala +run/t9003.scala +run/t7459f.scala +run/t8933c.scala +run/t1994.scala +run/t2866.scala +run/t5665.scala +run/t7459d.scala +run/t8933b +run/t8888.scala +run/t7459b-optimize.scala +run/t7459a.scala +run/t7019.scala +run/t8893.scala +run/t8803.scala +run/t7459b.scala +run/t8823.scala +run/t6541.scala +run/nothingTypeDce.scala +run/t8680.scala +run/t8925.scala +run/nothingTypeNoOpt.scala +run/t9030.scala +run/bigDecimalTest.scala +run/bigDecimalCache.scala +run/range.scala +run/t6064.scala +run/t7521 +run/t8710.scala +run/t8575.scala +run/t8944 +run/t8944b.scala +run/t9387.scala +run/t9387b.scala +pos/t7784.scala +pos/t8862a.scala +pos/t9074.scala +pos/t8462.scala +pos/t8862b.scala +pos/alladin763.scala +pos/t6778.scala +pos/t9074b.scala +pos/t9326a.scala +pos/t9131.scala +pos/t9393 +pos/t9392 +neg/missing-arg-list.scala +neg/deprecated-target.scala +neg/t6895.scala +neg/beanInfoDeprecation.scala +neg/t8777.scala +neg/t6895b.scala +neg/t8892.scala +neg/t8849.scala +neg/inlineIndyLambdaPrivate +run/t9029.scala +run/t7850c.scala +run/t7850d.scala +run/t8334.scala +run/t9029c.scala +run/t9029b.scala +run/t9422.scala +run/t9425.scala +pos/t9475.scala +pos/t9498.scala +pos/t9479.scala +pos/t9479b.scala +pos/t9442.scala +pos/t9369.scala +pos/t6666d.scala +pos/t9370 +neg/t6810.scala +neg/t8127a.scala +neg/t8989.scala +neg/t9401.scala +neg/implicit-ambiguous.scala +neg/implicit-ambiguous-2.scala +neg/implicit-ambiguous-invalid.scala +neg/warn-unused-imports +run/t7269.scala +run/equality.scala +run/number-parsing.scala +run/t6220.scala +run/mapConserve.scala +run/colltest.scala +run/t0412.scala +run/t6261.scala +run/java-erasure.scala +run/t5880.scala +run/t6197.scala +run/t4201.scala +run/t5608.scala +run/t3518.scala +run/t6198.scala +run/t2813.2.scala +pos/java-type-annotations +pos/sammy_infer_argtype_subtypes.scala +pos/sammy_ctor_arg.scala +pos/fun_undo_eta.scala +pos/sammy_inferargs.scala +pos/existental-slow-compile2.scala +pos/existential-slow-compile1.scala +pos/sammy_implicit.scala +pos/t9178b.scala +pos/t9449.scala +pos/t3234.scala +pos/t9542.scala +pos/t8429.scala +pos/t9658.scala +pos/t9630 +pos/t9399.scala +pos/t9411a.scala +pos/t9411b.scala +neg/partestInvalidFlag.scala +neg/sammy_error.scala +neg/sammy_disabled.scala +neg/sammy_overload.scala +neg/sammy_expected.scala +neg/t8700a +neg/t9527b.scala +neg/t9527a.scala +neg/t9572.scala +neg/t9535.scala +neg/t9629.scala +neg/optimiseDeprecated.scala +neg/t9398 +neg/outer-ref-checks.scala +neg/t8685.scala +neg/t8700b +run/t9349 +run/t9178a.scala +run/t9110.scala +run/sammy_cbn.scala +run/sammy_erasure_cce.scala +run/sammy_after_implicit_view.scala +run/sammy_restrictions_LMF.scala +run/sammy_vararg_cbn.scala +run/t7807.scala +run/sammy_return.scala +run/t9546.scala +run/t9546b.scala +run/lisp.scala +run/t9546c.scala +run/t9546d.scala +run/t9546e.scala +run/t9567.scala +run/t9567b.scala +run/trait-clonable.scala +run/t9567c.scala +run/trait-defaults-modules.scala +run/trait-defaults-modules3.scala +run/trait-defaults-modules2 +pos/functions.scala +pos/MailBox.scala +neg/t6289 +run/t4729 +run/t6114.scala +run/t1430 +pos/constant-warning.scala +pos/t2712-5.scala +pos/t2712-2.scala +pos/t2712-4.scala +pos/t2712-1.scala +pos/t2712-3.scala +pos/t2712-6.scala +pos/t6895b.scala +pos/t5683.scala +pos/hkgadt.scala +pos/t2712-7.scala +pos/t9245.scala +pos/t7088.scala +pos/trait-defaults-super.scala +pos/t8044.scala +pos/t9665.scala +pos/t9397.scala +pos/t5183.scala +pos/t8449 +neg/t8044-b.scala +neg/t8044.scala +neg/t2712-3.scala +neg/t2712-2.scala +neg/t2712-1.scala +neg/t9045.scala +neg/t8667.scala +neg/t9361.scala +neg/t9781.scala +neg/trait-no-native.scala +neg/hkgadt.scala +neg/t9684b.scala +neg/t9382.scala +neg/trait-defaults-super.scala +neg/t9684.scala +run/hashCodeStatics.scala +run/t9390d.scala +run/trait-static-clash.scala +run/t5568.scala +run/t6318_primitives.scala +pos/fields_widen_trait_var.scala +pos/sammy_extends_function.scala +pos/infer_override_def_args.scala +pos/t482.scala +pos/t8079b.scala +pos/t6161b.scala +pos/t5294b.scala +pos/t5294c.scala +pos/overloaded_ho_fun.scala +pos/t4914.scala +pos/trait_fields_dependent_conflict.scala +pos/t2377b +pos/trait_fields_dependent_rebind.scala +pos/t9855b.scala +pos/trait_fields_inherit_double_def.scala +pos/t9855.scala +pos/t8873.scala +pos/trait_fields_nested_private_object.scala +pos/trait_fields_nested_public_object.scala +pos/trait_fields_private_this.scala +pos/trait_fields_var_override_deferred.scala +pos/trait_fields_static_fwd.scala +pos/trait_fields_owners.scala +pos/trait_fields_volatile.scala +pos/trait_lazy_accessboundary.scala +pos/trait_fields_lambdalift.scala +pos/typevar-in-prefix.scala +pos/val_infer.scala +pos/lub-from-hell.scala +neg/t8079a.scala +neg/sd128 +neg/t9849.scala +neg/trait_fields_var_override.scala +neg/val_infer.scala +neg/val_sig_infer_match.scala +neg/t7187.scala +neg/trait_fields_deprecated_overriding.scala +neg/t9847.scala +neg/val_sig_infer_struct.scala +neg/trait_fields_conflicts.scala +neg/lub-from-hell-2.scala +run/t2946 +run/lazy_local_labels.scala +run/sd167.scala +run/t9841.scala +run/trait-fields-override-lazy.scala +run/trait_fields_init.scala +run/trait_fields_three_layer_overrides.scala +run/t9516.scala +run/t10032.scala +pos/sam_erasure_boundedwild.scala +pos/t10154.scala +pos/t10066.scala +pos/t10154b.scala +pos/t10093.scala +pos/t8040.scala +pos/t3772.scala +pos/t10206.scala +pos/t9331.scala +pos/userdefined_apply_poly_overload.scala +pos/userdefined_apply.scala +pos/trailing-commas.scala +neg/t10097.scala +neg/t10068.scala +neg/ambiguous-same.scala +neg/maxerrs.scala +neg/maxwarns.scala +neg/t10207.scala +neg/t10066.scala +neg/t3236-neg +neg/t3772.scala +neg/t8704.scala +neg/t8002-nested-scope.scala +neg/t10097b.scala +neg/trailing-commas.scala +neg/t9834.scala +neg/userdefined_apply.scala +neg/t8417.scala +neg/warn-unused-implicits.scala +neg/t7860.scala +neg/t8763.scala +neg/t9636.scala +neg/warn-unused-params.scala +neg/t9675.scala +neg/warn-unused-patvars.scala +run/t10069.scala +run/SD-290.scala +run/sd329.scala +run/t10097.scala +run/t10072.scala +run/t10261 +run/t9114.scala + +# Adapt checkfiles for (1.0).toString == "1" +run/Course-2002-01.scala +run/t0421-new.scala +run/runtime.scala +run/t0421-old.scala +run/spec-self.scala +run/t5552.scala +run/Course-2002-02.scala +run/Course-2002-04.scala +run/promotion.scala +run/t4617.scala +run/Course-2002-09.scala +run/t5866.scala +run/try-catch-unify.scala +run/impconvtimes.scala +run/Course-2002-10.scala +run/Course-2002-08.scala +run/MeterCaseClass.scala +run/Meter.scala +run/deeps.scala +run/caseClassHash.scala +run/interpolation.scala +run/interpolationMultiline1.scala +run/t9656.scala +pos/sd219.scala +pos/t9918 +pos/shapeless-regression.scala +pos/issue244.scala +pos/t9920.scala +pos/t9943.scala +neg/t5148.scala +run/sd242.scala +run/local_obj.scala +run/t9697.scala +run/t9920.scala +run/t9920c.scala +run/t9920d.scala +run/t9920b.scala +run/t9946a.scala +run/t9946c.scala +run/t9946b.scala +run/trait-super-calls.scala +pos/sd268.scala +pos/sd248 +pos/t6734.scala +pos/t10009.scala +pos/t7551 +pos/t6978 +pos/t7046-2 +neg/t9953.scala +neg/t7014 +neg/t7046-2 +neg/t7046 +run/t7046-1 +run/t7046-2 + +# Adapt checkfiles for ().toString == "undefined" +run/t5680.scala +run/dynamic-anyval.scala +run/macro-bundle-toplevel +run/macro-bundle-whitebox-decl +run/t6662 +run/t8570a.scala +run/t3702.scala +run/t7657 +run/macro-bundle-static +run/structural.scala + +# Adapt checkfiles for print & flush (which we cannot 100% emulate) +run/imports.scala +run/misc.scala + +# Adapt checkfiles for compiler phase list +neg/t7494-no-options +neg/t6446-list +neg/t6446-missing +neg/t6446-show-phases.scala +neg/t6446-additional + +# Adapt checkfiles for different behavior with boxed types +run/virtpatmat_typetag.scala +run/virtpatmat_switch.scala +run/t5629b.scala +run/t5356.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-additional.check new file mode 100644 index 0000000000..b7ce23da2f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-additional.check @@ -0,0 +1,30 @@ + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + ploogin 27 A sample phase that does so many things it's kind of hard... + terminal 28 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-list.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-list.check new file mode 100644 index 0000000000..95883c8c81 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-list.check @@ -0,0 +1,2 @@ +ploogin - A sample plugin for testing. +scalajs - Compile to JavaScript diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-missing.check new file mode 100644 index 0000000000..56b74a3128 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-missing.check @@ -0,0 +1,30 @@ +Error: unable to load class: t6446.Ploogin + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + terminal 27 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-show-phases.check new file mode 100644 index 0000000000..cde255e3b1 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-show-phases.check @@ -0,0 +1,29 @@ + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + terminal 27 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t7494-no-options.check new file mode 100644 index 0000000000..d8be421e5e --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t7494-no-options.check @@ -0,0 +1,31 @@ +error: Error: ploogin takes no options + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + ploogin 27 A sample phase that does so many things it's kind of hard... + terminal 28 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Course-2002-01.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Course-2002-01.check new file mode 100644 index 0000000000..fcda9433de --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Course-2002-01.check @@ -0,0 +1,37 @@ +Course-2002-01.scala:41: warning: method loop in object M0 does nothing other than call itself recursively + def loop: Int = loop; + ^ +232 +667 +11 +10 +62.8318 +62.8318 +62.8318 +4 +81 +256 +25 +1 +737 +1 +0 +1 +76 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +sqrt(2) = 1.4142135623746899 +sqrt(2) = 1.4142135623746899 +cbrt(2) = 1.2599210500177698 +1 +1 1 +1 2 1 +1 3 3 1 +1 4 6 4 1 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Course-2002-02.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Course-2002-02.check new file mode 100644 index 0000000000..ab75cfdb61 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Course-2002-02.check @@ -0,0 +1,187 @@ +7 +120 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +pi = 3.181104885577714 +pi = 3.181104885577714 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 +pi = 3.181104885577714 +pi = 3.181104885577714 + +1.5 +1.4166666666666665 +1.4142156862745097 +1.4142135623746899 +sqrt(2) = 1.4142135623746899 + +1.5 +1.4166666666666665 +1.4142156862745097 +1.4142135623746899 +sqrt(2) = 1.4142135623746899 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +power(0,0) = 1 +power(0,1) = 0 +power(0,2) = 0 +power(0,3) = 0 +power(0,4) = 0 +power(0,5) = 0 +power(0,6) = 0 +power(0,7) = 0 +power(0,8) = 0 + +power(1,0) = 1 +power(1,1) = 1 +power(1,2) = 1 +power(1,3) = 1 +power(1,4) = 1 +power(1,5) = 1 +power(1,6) = 1 +power(1,7) = 1 +power(1,8) = 1 + +power(2,0) = 1 +power(2,1) = 2 +power(2,2) = 4 +power(2,3) = 8 +power(2,4) = 16 +power(2,5) = 32 +power(2,6) = 64 +power(2,7) = 128 +power(2,8) = 256 + +power(3,0) = 1 +power(3,1) = 3 +power(3,2) = 9 +power(3,3) = 27 +power(3,4) = 81 +power(3,5) = 243 +power(3,6) = 729 +power(3,7) = 2187 +power(3,8) = 6561 + +power(4,0) = 1 +power(4,1) = 4 +power(4,2) = 16 +power(4,3) = 64 +power(4,4) = 256 +power(4,5) = 1024 +power(4,6) = 4096 +power(4,7) = 16384 +power(4,8) = 65536 + +power(5,0) = 1 +power(5,1) = 5 +power(5,2) = 25 +power(5,3) = 125 +power(5,4) = 625 +power(5,5) = 3125 +power(5,6) = 15625 +power(5,7) = 78125 +power(5,8) = 390625 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Course-2002-04.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Course-2002-04.check new file mode 100644 index 0000000000..fc6ad96eed --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Course-2002-04.check @@ -0,0 +1,64 @@ +list0 = List(6, 3, 1, 8, 7, 1, 2, 5, 8, 4, 3, 4, 8) +list1 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list2 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list3 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list4 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list5 = List(8, 8, 8, 7, 6, 5, 4, 4, 3, 3, 2, 1, 1) +list6 = List(8, 8, 8, 7, 6, 5, 4, 4, 3, 3, 2, 1, 1) + +list0: List() -> List() +list1: List(0) -> List(0) +list2: List(0, 1) -> List(0, 1) +list3: List(1, 0) -> List(0, 1) +list4: List(0, 1, 2) -> List(0, 1, 2) +list5: List(1, 0, 2) -> List(0, 1, 2) +list6: List(0, 1, 2) -> List(0, 1, 2) +list7: List(1, 0, 2) -> List(0, 1, 2) +list8: List(2, 0, 1) -> List(0, 1, 2) +list9: List(2, 1, 0) -> List(0, 1, 2) +listA: List(6, 3, 1, 8, 7, 1, 2, 5, 8, 4) -> List(1, 1, 2, 3, 4, 5, 6, 7, 8, 8) + +f(x) = 5x^3+7x^2+5x+9 +f(0) = 9 +f(1) = 26 +f(2) = 87 +f(3) = 222 + +v1 = List(2, 3, 4) +v2 = List(6, 7, 8) + +id = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +m1 = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m2 = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) + +v1 * v1 = 29 +v1 * v2 = 65 +v2 * v1 = 65 +v1 * v2 = 65 + +id * v1 = List(2, 3, 4) +m1 * v1 = List(4, 6, 8) +m2 * v1 = List(20, 47, 74) + +trn(id) = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +trn(m1) = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +trn(m2) = List(List(1, 4, 7), List(2, 5, 8), List(3, 6, 9)) + +List(v1) * id = List(List(2, 3, 4)) +List(v1) * m1 = List(List(4, 6, 8)) +List(v1) * m2 = List(List(42, 51, 60)) + +id * List(v1) = List(List(2, 3, 4), List(0, 0, 0), List(0, 0, 0)) +m1 * List(v1) = List(List(4, 6, 8), List(0, 0, 0), List(0, 0, 0)) +m2 * List(v1) = List(List(2, 3, 4), List(8, 12, 16), List(14, 21, 28)) + +id * id = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +id * m1 = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m1 * id = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m1 * m1 = List(List(4, 0, 0), List(0, 4, 0), List(0, 0, 4)) +id * m2 = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) +m2 * id = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) +m1 * m2 = List(List(2, 4, 6), List(8, 10, 12), List(14, 16, 18)) +m2 * m1 = List(List(2, 4, 6), List(8, 10, 12), List(14, 16, 18)) +m2 * m2 = List(List(30, 36, 42), List(66, 81, 96), List(102, 126, 150)) + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Course-2002-08.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Course-2002-08.check new file mode 100644 index 0000000000..0585d5b44f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Course-2002-08.check @@ -0,0 +1,171 @@ +x = abc +count = 111 +x = hello +count = 112 + +account deposit 50 -> undefined +account withdraw 20 -> 30 +account withdraw 20 -> 10 +account withdraw 15 -> + +x deposit 30 -> undefined +y withdraw 20 -> + +x deposit 30 -> undefined +x withdraw 20 -> 10 + +x deposit 30 -> undefined +y withdraw 20 -> 10 + +2^0 = 1 +2^1 = 2 +2^2 = 4 +2^3 = 8 + +2^0 = 1 +2^1 = 2 +2^2 = 4 +2^3 = 8 + +1 2 3 +List(1, 2, 3) + +out 0 new-value = false +*** simulation started *** +out 1 new-value = true +!0 = 1 + +*** simulation started *** +out 2 new-value = false +!1 = 0 + +out 2 new-value = false + +*** simulation started *** +0 & 0 = 0 + +*** simulation started *** +0 & 1 = 0 + +*** simulation started *** +out 11 new-value = true +out 11 new-value = false +1 & 0 = 0 + +*** simulation started *** +out 14 new-value = true +1 & 1 = 1 + +out 14 new-value = false + +*** simulation started *** +0 | 0 = 0 + +*** simulation started *** +out 24 new-value = true +0 | 1 = 1 + +*** simulation started *** +1 | 0 = 1 + +*** simulation started *** +1 | 1 = 1 + +sum 34 new-value = false +carry 34 new-value = false + +*** simulation started *** +0 + 0 = 0 + +*** simulation started *** +sum 47 new-value = true +0 + 1 = 1 + +*** simulation started *** +carry 50 new-value = true +carry 50 new-value = false +sum 54 new-value = false +sum 54 new-value = true +1 + 0 = 1 + +*** simulation started *** +carry 57 new-value = true +sum 61 new-value = false +1 + 1 = 2 + +sum 61 new-value = false +carry 61 new-value = false + +*** simulation started *** +0 + 0 + 0 = 0 + +*** simulation started *** +sum 82 new-value = true +0 + 0 + 1 = 1 + +*** simulation started *** +sum 89 new-value = false +carry 90 new-value = true +sum 97 new-value = true +carry 98 new-value = false +0 + 1 + 0 = 1 + +*** simulation started *** +sum 113 new-value = false +carry 114 new-value = true +0 + 1 + 1 = 2 + +*** simulation started *** +sum 121 new-value = true +carry 122 new-value = false +sum 129 new-value = false +sum 129 new-value = true +1 + 0 + 0 = 1 + +*** simulation started *** +carry 137 new-value = true +sum 144 new-value = false +1 + 0 + 1 = 2 + +*** simulation started *** +carry 152 new-value = false +sum 152 new-value = true +sum 158 new-value = false +carry 159 new-value = true +1 + 1 + 0 = 2 + +*** simulation started *** +sum 173 new-value = true +1 + 1 + 1 = 3 + +in 0 new-value = false +ctrl0 0 new-value = false +ctrl1 0 new-value = false +ctrl2 0 new-value = false +out0 0 new-value = false +out1 0 new-value = false +out2 0 new-value = false +out3 0 new-value = false +out4 0 new-value = false +out5 0 new-value = false +out6 0 new-value = false +out7 0 new-value = false +in 0 new-value = true +*** simulation started *** +out0 10 new-value = true +ctrl0 10 new-value = true +*** simulation started *** +out1 13 new-value = true +out0 14 new-value = false +ctrl1 14 new-value = true +*** simulation started *** +out3 20 new-value = true +out1 21 new-value = false +ctrl2 21 new-value = true +*** simulation started *** +out7 30 new-value = true +out3 31 new-value = false +ctrl0 31 new-value = false +*** simulation started *** +out7 34 new-value = false +out6 35 new-value = true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Course-2002-09.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Course-2002-09.check new file mode 100644 index 0000000000..c921361db7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Course-2002-09.check @@ -0,0 +1,50 @@ +Probe: f = 32 +Probe: c = 0 +Probe: f = ? +Probe: c = ? + +Probe: f = 212 +Probe: c = 100 +Probe: f = ? +Probe: c = ? + +Probe: c = 0 +Probe: f = 32 +Probe: c = ? +Probe: f = ? + +Probe: c = 100 +Probe: f = 212 +Probe: c = ? +Probe: f = ? + +0 Celsius -> 32 Fahrenheits +100 Celsius -> 212 Fahrenheits +32 Fahrenheits -> 0 Celsius +212 Fahrenheits -> 100 Celsius + +a = ?, b = ?, c = ? => ? * ? = ? +a = 2, b = ?, c = ? => 2 * ? = ? +a = ?, b = 3, c = ? => ? * 3 = ? +a = ?, b = ?, c = 6 => ? * ? = 6 +a = 2, b = 3, c = ? => 2 * 3 = 6 +a = 2, b = ?, c = 6 => 2 * 3 = 6 +a = ?, b = 3, c = 6 => 2 * 3 = 6 +a = 2, b = 3, c = 6 => 2 * 3 = 6 + +a = 0, b = ?, c = ? => 0 * ? = 0 +a = ?, b = 0, c = ? => ? * 0 = 0 +a = ?, b = ?, c = 0 => ? * ? = 0 +a = 0, b = 7, c = ? => 0 * 7 = 0 +a = 7, b = 0, c = ? => 7 * 0 = 0 +a = 0, b = 0, c = ? => 0 * 0 = 0 +a = 0, b = ?, c = 0 => 0 * ? = 0 +a = ?, b = 0, c = 0 => ? * 0 = 0 +a = 0, b = 7, c = 0 => 0 * 7 = 0 +a = 7, b = 0, c = 0 => 7 * 0 = 0 +a = 0, b = 0, c = 0 => 0 * 0 = 0 + +a = 3, b = 4 => c = 5 +a = 3, c = 5 => b = 4 +b = 4, c = 5 => a = 3 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Course-2002-10.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Course-2002-10.check new file mode 100644 index 0000000000..847f0fa703 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Course-2002-10.check @@ -0,0 +1,46 @@ +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +fib(10) = 55 +fib(11) = 89 +fib(12) = 144 +fib(13) = 233 +fib(14) = 377 +fib(15) = 610 +fib(16) = 987 +fib(17) = 1597 +fib(18) = 2584 +fib(19) = 4181 + +pi(0) = 4 , 3.166666666666667 , 4 +pi(1) = 2.666666666666667 , 3.1333333333333337, 3.166666666666667 +pi(2) = 3.466666666666667 , 3.1452380952380956, 3.142105263157895 +pi(3) = 2.8952380952380956, 3.1396825396825396, 3.1415993573190044 +pi(4) = 3.33968253968254 , 3.142712842712843 , 3.141592714033778 +pi(5) = 2.976046176046176 , 3.140881340881341 , 3.1415926539752923 +pi(6) = 3.283738483738484 , 3.142071817071817 , 3.141592653591176 +pi(7) = 3.017071817071817 , 3.1412548236077646, 3.141592653589777 +pi(8) = 3.252365934718876 , 3.1418396189294024, 3.141592653589794 +pi(9) = 3.0418396189294024, 3.141406718496502 , 3.1415926535897936 +pi = 3.141592653589793 , 3.141592653589793 , 3.141592653589793 + +ln(0) = 1 , 0.7 , 1 +ln(1) = 0.5 , 0.6904761904761905, 0.7 +ln(2) = 0.8333333333333333, 0.6944444444444444, 0.6932773109243697 +ln(3) = 0.5833333333333333, 0.6924242424242424, 0.6931488693329254 +ln(4) = 0.7833333333333333, 0.6935897435897436, 0.6931471960735491 +ln(5) = 0.6166666666666667, 0.6928571428571428, 0.6931471806635636 +ln(6) = 0.7595238095238095, 0.6933473389355742, 0.6931471805604038 +ln(7) = 0.6345238095238095, 0.6930033416875522, 0.6931471805599444 +ln(8) = 0.7456349206349207, 0.6932539682539682, 0.6931471805599426 +ln(9) = 0.6456349206349206, 0.6930657506744463, 0.6931471805599453 +ln = 0.6931471805599453, 0.6931471805599453, 0.6931471805599453 + +prime numbers: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Meter.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Meter.check new file mode 100644 index 0000000000..f46fd557c8 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/Meter.check @@ -0,0 +1,16 @@ +Meter.scala:72: warning: a.Meter and Int are unrelated: they will never compare equal + println("x == 1: "+(x == 1)) + ^ +2 +4m +false +x.isInstanceOf[Meter]: true +x.hashCode: 1 +x == 1: false +x == y: true +a == b: true +testing native arrays +Array(1m, 2m) +1m +>>>1m<<< 1m +>>>2m<<< 2m diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/MeterCaseClass.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/MeterCaseClass.check new file mode 100644 index 0000000000..ac538d240f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/MeterCaseClass.check @@ -0,0 +1,16 @@ +MeterCaseClass.scala:69: warning: comparing values of types a.Meter and Int using `==' will always yield false + println("x == 1: "+(x == 1)) + ^ +2 +Meter(4) +false +x.isInstanceOf[Meter]: true +x.hashCode: 1 +x == 1: false +x == y: true +a == b: true +testing native arrays +Array(Meter(1), Meter(2)) +Meter(1) +>>>Meter(1)<<< Meter(1) +>>>Meter(2)<<< Meter(2) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/bugs.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/bugs.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/bugs.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/caseClassHash.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/caseClassHash.check new file mode 100644 index 0000000000..f975151e9c --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/caseClassHash.check @@ -0,0 +1,9 @@ +Foo(true,-1,-1,d,-5,-10,500,500,List(),5) +Foo(true,-1,-1,d,-5,-10,500,500,List(),5) +1383698062 +1383698062 +true +## method 1: 1383698062 +## method 2: 1383698062 + Murmur 1: 1383698062 + Murmur 2: 1383698062 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/deeps.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/deeps.check new file mode 100644 index 0000000000..e533b87dc5 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/deeps.check @@ -0,0 +1,87 @@ +testEquals1 +false +false +true + +testEquals2 +false +false +true + +testEquals3 +x=Array(1) +y=Array(1) +false +false +true + +x=Array(Array(1), Array(1)) +y=Array(Array(1), Array(1)) +false +false +true + +x=Array(Array(Array(1), Array(1)), Array(Array(1), Array(1))) +y=Array(Array(Array(1), Array(1)), Array(Array(1), Array(1))) +false +false +true + +testEquals4 +false +false +true +false +false +true +Array(true, false) +Array(true, false) +[true;false] +true;false + +Array(Array(true, false), Array(true, false)) +Array(Array(true, false), Array(true, false)) +[Array(true, false);Array(true, false)] +Array(true, false);Array(true, false) + +Array(Array(Array(true, false), Array(true, false)), Array(Array(true, false), Array(true, false))) +Array(Array(Array(true, false), Array(true, false)), Array(Array(true, false), Array(true, false))) +[Array(Array(true, false), Array(true, false));Array(Array(true, false), Array(true, false))] +Array(Array(true, false), Array(true, false));Array(Array(true, false), Array(true, false)) + +Array(1, 0) +Array(1, 0) +[1;0] +1;0 + +Array(Array(1, 0), Array(1, 0)) +Array(Array(1, 0), Array(1, 0)) +[Array(1, 0);Array(1, 0)] +Array(1, 0);Array(1, 0) + +Array(Array(Array(1, 0), Array(1, 0)), Array(Array(1, 0), Array(1, 0))) +Array(Array(Array(1, 0), Array(1, 0)), Array(Array(1, 0), Array(1, 0))) +[Array(Array(1, 0), Array(1, 0));Array(Array(1, 0), Array(1, 0))] +Array(Array(1, 0), Array(1, 0));Array(Array(1, 0), Array(1, 0)) + +Array(a, b) +Array(a, b) +[a;b] +a;b + +Array(Array(a, b), Array(a, b)) +Array(Array(a, b), Array(a, b)) +[Array(a, b);Array(a, b)] +Array(a, b);Array(a, b) + +Array(Array(Array(a, b), Array(a, b)), Array(Array(a, b), Array(a, b))) +Array(Array(Array(a, b), Array(a, b)), Array(Array(a, b), Array(a, b))) +[Array(Array(a, b), Array(a, b));Array(Array(a, b), Array(a, b))] +Array(Array(a, b), Array(a, b));Array(Array(a, b), Array(a, b)) + +[Array(true, false); Array(false)] +[Array(1, 2); Array(3)] +[Array(1, 2); Array(3)] + +Array(boo, and, foo) +Array(a) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/dynamic-anyval.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/dynamic-anyval.check new file mode 100644 index 0000000000..c125372c9a --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/dynamic-anyval.check @@ -0,0 +1,4 @@ +undefined.dingo(bippy, 5) +List(1, 2, 3).dingo(bippy, 5) +undefined.dingo(bippy, 5) +List(1, 2, 3).dingo(bippy, 5) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/impconvtimes.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/impconvtimes.check new file mode 100644 index 0000000000..082377e474 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/impconvtimes.check @@ -0,0 +1 @@ +3.0 * Hour = Measure(3,Hour) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/imports.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/imports.check new file mode 100644 index 0000000000..1aad598062 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/imports.check @@ -0,0 +1,21 @@ +In C_ico, v_ico .toString() returns ↩ +↪C_ico -> ok +In C_ico, field .toString() returns ↩ +↪C_ico -> ok +In C_ico, method.toString() returns ↩ +↪C_ico -> ok + +In C_ioc, v_ioc .toString() returns ↩ +↪C_ioc -> ok +In C_ioc, field .toString() returns ↩ +↪C_ioc -> ok +In C_ioc, method.toString() returns ↩ +↪C_ioc -> ok + +In C_oic, v_oic .toString() returns ↩ +↪C_oic -> ok +In C_oic, field .toString() returns ↩ +↪C_oic -> ok +In C_oic, method.toString() returns ↩ +↪C_oic -> ok + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/interpolation.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/interpolation.check new file mode 100644 index 0000000000..9c4a77715b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/interpolation.check @@ -0,0 +1,32 @@ +Bob is 1 years old +Bob is 1 years old +Bob will be 2 years old +Bob will be 2 years old +1+1 = 2 +1+1 = 2 +Bob is 12 years old +Bob is 12 years old +Bob will be 13 years old +Bob will be 13 years old +12+1 = 13 +12+1 = 13 +Bob is 123 years old +Bob is 123 years old +Bob will be 124 years old +Bob will be 124 years old +123+1 = 124 +123+1 = 124 +Best price: 10 +Best price: 10.00 +10% discount included +10.00% discount included +Best price: 13.345000267028809 +Best price: 13.35 +13.345000267028809% discount included +13.35% discount included + +0 +00 + +0 +00 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/interpolationMultiline1.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/interpolationMultiline1.check new file mode 100644 index 0000000000..1b6e140c13 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/interpolationMultiline1.check @@ -0,0 +1,26 @@ +Bob is 1 years old +Bob is 1 years old +Bob will be 2 years old +Bob will be 2 years old +1+1 = 2 +1+1 = 2 +Bob is 12 years old +Bob is 12 years old +Bob will be 13 years old +Bob will be 13 years old +12+1 = 13 +12+1 = 13 +Bob is 123 years old +Bob is 123 years old +Bob will be 124 years old +Bob will be 124 years old +123+1 = 124 +123+1 = 124 +Best price: 10 +Best price: 10.00 +10% discount included +10.00% discount included +Best price: 13.345000267028809 +Best price: 13.35 +13.345000267028809% discount included +13.35% discount included diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/issue192.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/issue192.sem new file mode 100644 index 0000000000..10abbf7f3b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/issue192.sem @@ -0,0 +1 @@ +strictFloats diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/macro-bundle-static.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/macro-bundle-static.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/macro-bundle-static.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/macro-bundle-toplevel.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/macro-bundle-toplevel.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/macro-bundle-toplevel.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/macro-bundle-whitebox-decl.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/macro-bundle-whitebox-decl.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/macro-bundle-whitebox-decl.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/misc.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/misc.check new file mode 100644 index 0000000000..85f37c51d7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/misc.check @@ -0,0 +1,62 @@ +misc.scala:46: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 42; + ^ +misc.scala:47: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 42l; + ^ +misc.scala:48: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 23.5f; + ^ +misc.scala:49: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 23.5; + ^ +misc.scala:50: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + "Hello"; + ^ +misc.scala:51: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 32 + 45; + ^ +misc.scala:62: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + x; + ^ +misc.scala:74: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 1 < 2; + ^ +### Hello +### 17 +### Bye + +### fib(0) = ↩ +↪1 +### fib(1) = ↩ +↪1 +### fib(2) = ↩ +↪2 +### fib(3) = ↩ +↪3 +### fib(4) = ↩ +↪5 +=== MyClass::toString === +=== MySubclass::toString === +=== MyClass::test === + +identity + +A.a = 1 +B.a = 5 +B.b = 2 + +X.a = 4 +Y.a = 11 +Y.b = 5 +Y.b = 5 + +X::foo + +Y::foo +X::foo + +3 +3 + +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/promotion.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/promotion.check new file mode 100644 index 0000000000..41e36c369d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/promotion.check @@ -0,0 +1,4 @@ +2 +6 +20 +30 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/runtime.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/runtime.check new file mode 100644 index 0000000000..0450b9498a --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/runtime.check @@ -0,0 +1,70 @@ +runtime.scala:141: warning: comparing values of types Null and Null using `eq' will always yield true + check(true , null eq null, null ne null); + ^ +runtime.scala:141: warning: comparing values of types Null and Null using `ne' will always yield false + check(true , null eq null, null ne null); + ^ +<<< Test0 +[false,true] +[0,1,2] +[3,4,5] +[a,b,c] +[6,7,8] +[9,10,11] +[12,13] +[14,15] +[string] +>>> Test0 + +<<< Test1 +10 +14 +15 +16 +20 +23 +24 +25 +26 +>>> Test1 + +<<< Test2 +A +M0 +N0 + +A +N0 +M0 + +A +M0 +M1 +N0 + +A +N0 +N1 +M0 + +>>> Test2 + +<<< Test3 +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +>>> Test3 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/spec-self.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/spec-self.check new file mode 100644 index 0000000000..fd3c81a4d7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/spec-self.check @@ -0,0 +1,2 @@ +5 +5 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/structural.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/structural.check new file mode 100644 index 0000000000..2fec112a87 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/structural.check @@ -0,0 +1,37 @@ + 1. hey + 2. 11 + 3. dee + 4. iei + 5. 6 + 6. 51 + 7. 2 + 8. 11 +10. 12 +11. eitch +12. 1 +13. ohone +14. 1 +15. undefined +16. one +17. tieone +18. 2 +19. true +20. 1 +21. undefined +22. one +23. oy +24. 1 +25. null +26. iei +31. 4 +32. undefined +33. iei +33. tieone +1 +2 +3 +4 +5 +caught +3 +2 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t0421-new.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t0421-new.check new file mode 100644 index 0000000000..00d29b7e5b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t0421-new.check @@ -0,0 +1,3 @@ +[Array(0, 1),Array(2, 3),Array(4, 5)] +[Array(31)] +[Array(24, 32)] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t0421-old.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t0421-old.check new file mode 100644 index 0000000000..00d29b7e5b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t0421-old.check @@ -0,0 +1,3 @@ +[Array(0, 1),Array(2, 3),Array(4, 5)] +[Array(31)] +[Array(24, 32)] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t1503.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t1503.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t1503.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t3702.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t3702.check new file mode 100644 index 0000000000..3fce98715c --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t3702.check @@ -0,0 +1,2 @@ +undefined +6 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t4148.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t4148.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t4148.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t4617.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t4617.check new file mode 100644 index 0000000000..a6790f16f7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t4617.check @@ -0,0 +1 @@ +Str 8 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t5356.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t5356.check new file mode 100644 index 0000000000..870c901131 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t5356.check @@ -0,0 +1,6 @@ +1 java.lang.Byte +1 java.lang.Byte +1 scala.math.BigInt +1 java.lang.Byte +1 java.lang.Byte +1 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t5552.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t5552.check new file mode 100644 index 0000000000..9e767b6d7b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t5552.check @@ -0,0 +1,6 @@ +lazy: 3 +(3,3) +(3,3) +lazy: 3 +(3,3) +(3,3) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t5568.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t5568.check new file mode 100644 index 0000000000..6f30cc5070 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t5568.check @@ -0,0 +1,9 @@ +void +int +class scala.runtime.BoxedUnit +class scala.runtime.BoxedUnit +class java.lang.Byte +class java.lang.Byte +5 +5 +5 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t5629b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t5629b.check new file mode 100644 index 0000000000..c65298a6ce --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t5629b.check @@ -0,0 +1,10 @@ +=== pf(1): +MySmartPF.apply entered... +newPF.applyOrElse entered... +default +scala.MatchError: 1 (of class java.lang.Byte) +=== pf(42): +MySmartPF.apply entered... +newPF.applyOrElse entered... +ok +=== done diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t5680.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t5680.check new file mode 100644 index 0000000000..a3b8b64a43 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t5680.check @@ -0,0 +1,3 @@ +[Lscala.runtime.BoxedUnit +undefined +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t5866.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t5866.check new file mode 100644 index 0000000000..64df1cec7f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t5866.check @@ -0,0 +1,2 @@ +0 +Foo(0) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t6318_primitives.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t6318_primitives.check new file mode 100644 index 0000000000..654ef1beec --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t6318_primitives.check @@ -0,0 +1,54 @@ +Checking if byte matches byte +Some(1) +Checking if byte matches short +Some(1) +Checking if class java.lang.Byte matches byte +Some(1) +Checking if short matches short +Some(1) +Checking if short matches char +None +Checking if class java.lang.Byte matches short +Some(1) +Checking if char matches char +Some() +Checking if char matches int +None +Checking if class java.lang.Character matches char +Some() +Checking if int matches int +Some(1) +Checking if int matches long +None +Checking if class java.lang.Byte matches int +Some(1) +Checking if long matches long +Some(1) +Checking if long matches float +None +Checking if class java.lang.Long matches long +Some(1) +Checking if float matches float +Some(1) +Checking if float matches double +Some(1) +Checking if class java.lang.Byte matches float +Some(1) +Checking if double matches double +Some(1) +Checking if double matches boolean +None +Checking if class java.lang.Byte matches double +Some(1) +Checking if boolean matches boolean +Some(true) +Checking if boolean matches void +None +Checking if class java.lang.Boolean matches boolean +Some(true) +Checking if void matches void +Some(undefined) +Checking if void matches byte +None +Checking if class scala.runtime.BoxedUnit matches void +Some(undefined) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t6662.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t6662.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t6662.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t7657.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t7657.check new file mode 100644 index 0000000000..1a87c1e866 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t7657.check @@ -0,0 +1,3 @@ +undefined +undefined +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t7763.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t7763.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t7763.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t8570a.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t8570a.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t8570a.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t8764.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t8764.check new file mode 100644 index 0000000000..121120217e --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t8764.check @@ -0,0 +1,5 @@ +IntOnly: should return an unboxed int +Int: int +IntAndDouble: should just box and return Anyval +Double: class java.lang.Byte +Int: class java.lang.Byte diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t9387b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t9387b.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t9387b.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t9656.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t9656.check new file mode 100644 index 0000000000..a16c04eaad --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/t9656.check @@ -0,0 +1,14 @@ +Range 1 to 10 +Range 1 to 10 +inexact Range 1 to 10 by 2 +Range 1 to 10 by 3 +inexact Range 1 until 10 by 2 +Range 100 to 100 +empty Range 100 until 100 +NumericRange 1 to 10 +NumericRange 1 to 10 by 2 +NumericRange 0.1 until 1 by 0.1 +NumericRange 0.1 until 1.0 by 0.1 +NumericRange 0.1 until 1 by 0.1 (using NumericRange 0.1 until 1 by 0.1 of BigDecimal) +NumericRange 0 days until 10 seconds by 1 second +empty NumericRange 0 days until 0 days by 1 second diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/try-catch-unify.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/try-catch-unify.check new file mode 100644 index 0000000000..813f01166d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/try-catch-unify.check @@ -0,0 +1,4 @@ +Failure(java.lang.NumberFormatException: For input string: "Hi") +Success(5) +O NOES +Failure(java.lang.NumberFormatException: For input string: "Hi") diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/virtpatmat_switch.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/virtpatmat_switch.check new file mode 100644 index 0000000000..0900a9ca32 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/virtpatmat_switch.check @@ -0,0 +1,7 @@ +zero +one +many +got a +got b +got some letter +scala.MatchError: 5 (of class java.lang.Byte) \ No newline at end of file diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/virtpatmat_typetag.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/virtpatmat_typetag.check new file mode 100644 index 0000000000..048c3aeed0 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/run/virtpatmat_typetag.check @@ -0,0 +1,10 @@ +1 is a Int +1 is a java.lang.Integer +1 is not a java.lang.String; it's a class java.lang.Byte +true is a Any +woele is a java.lang.String +1 is a Int +1 is a java.lang.Integer +1 is not a java.lang.String; it's a class java.lang.Byte +true is a Any +woele is a java.lang.String diff --git a/project/Build.scala b/project/Build.scala index 637cb78f07..03c8181c6c 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -63,7 +63,7 @@ object Build { CrossVersion.binaryMapped(v => s"sjs${previousSJSBinaryVersion}_$v") val scalaVersionsUsedForPublishing: Set[String] = - Set("2.10.6", "2.11.11", "2.12.1") + Set("2.10.6", "2.11.11", "2.12.2") val newScalaBinaryVersionsInThisRelease: Set[String] = Set() @@ -427,7 +427,8 @@ object Build { "2.11.8", "2.11.11", "2.12.0", - "2.12.1" + "2.12.1", + "2.12.2" ), // JDK version we are running with javaVersion in Global := { diff --git a/scala-test-suite/src/test/resources/2.12.2/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.12.2/BlacklistedTests.txt new file mode 100644 index 0000000000..c3bad1906e --- /dev/null +++ b/scala-test-suite/src/test/resources/2.12.2/BlacklistedTests.txt @@ -0,0 +1,128 @@ +## Do not compile +scala/lang/annotations/BytecodeTest.scala +scala/lang/annotations/RunTest.scala +scala/lang/traits/BytecodeTest.scala +scala/lang/traits/RunTest.scala +scala/lang/primitives/NaNTest.scala +scala/lang/primitives/BoxUnboxTest.scala +scala/reflect/ClassOfTest.scala +scala/reflect/QTest.scala +scala/reflect/io/ZipArchiveTest.scala +scala/reflect/internal/util/AbstractFileClassLoaderTest.scala +scala/reflect/internal/util/SourceFileTest.scala +scala/reflect/internal/util/StringOpsTest.scala +scala/reflect/internal/PrintersTest.scala +scala/reflect/internal/ScopeTest.scala +scala/reflect/internal/TreeGenTest.scala +scala/reflect/internal/TypesTest.scala +scala/reflect/internal/util/WeakHashSetTest.scala +scala/reflect/internal/MirrorsTest.scala +scala/reflect/internal/NamesTest.scala +scala/tools/nsc/backend/jvm/BTypesTest.scala +scala/tools/nsc/backend/jvm/BytecodeTest.scala +scala/tools/nsc/backend/jvm/DefaultMethodTest.scala +scala/tools/nsc/backend/jvm/DirectCompileTest.scala +scala/tools/nsc/backend/jvm/IndyLambdaTest.scala +scala/tools/nsc/backend/jvm/IndySammyTest.scala +scala/tools/nsc/backend/jvm/OptimizedBytecodeTest.scala +scala/tools/nsc/backend/jvm/StringConcatTest.scala +scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala +scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala +scala/tools/nsc/backend/jvm/opt/AnalyzerTest.scala +scala/tools/nsc/backend/jvm/opt/BTypesFromClassfileTest.scala +scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala +scala/tools/nsc/backend/jvm/opt/ClosureOptimizerTest.scala +scala/tools/nsc/backend/jvm/opt/CompactLocalVariablesTest.scala +scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala +scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala +scala/tools/nsc/backend/jvm/opt/InlineInfoTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerIllegalAccessTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerTest.scala +scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala +scala/tools/nsc/backend/jvm/opt/MethodLevelOptsTest.scala +scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala +scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala +scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala +scala/tools/nsc/backend/jvm/opt/UnusedLocalVariablesTest.scala +scala/tools/nsc/ScriptRunnerTest.scala +scala/tools/nsc/classpath/AggregateClassPathTest.scala +scala/tools/nsc/classpath/JrtClassPathTest.scala +scala/tools/nsc/classpath/PathResolverBaseTest.scala +scala/tools/nsc/classpath/VirtualDirectoryClassPathTest.scala +scala/tools/nsc/doc/html/HtmlDocletTest.scala +scala/tools/nsc/interpreter/CompletionTest.scala +scala/tools/nsc/interpreter/ScriptedTest.scala +scala/tools/nsc/interpreter/TabulatorTest.scala +scala/tools/nsc/reporters/ConsoleReporterTest.scala +scala/tools/nsc/settings/ScalaVersionTest.scala +scala/tools/nsc/settings/SettingsTest.scala +scala/tools/nsc/symtab/CannotHaveAttrsTest.scala +scala/tools/nsc/symtab/FlagsTest.scala +scala/tools/nsc/symtab/FreshNameExtractorTest.scala +scala/tools/nsc/symtab/StdNamesTest.scala +scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala +scala/tools/nsc/symtab/SymbolTableTest.scala +scala/tools/nsc/transform/delambdafy/DelambdafyTest.scala +scala/tools/nsc/transform/patmat/SolvingTest.scala +scala/tools/nsc/transform/patmat/PatmatBytecodeTest.scala +scala/tools/nsc/typechecker/Implicits.scala +scala/tools/nsc/util/StackTraceTest.scala +scala/tools/testing/BytecodeTesting.scala +scala/tools/testing/RunTesting.scala + +## Do not link +scala/PartialFunctionSerializationTest.scala +scala/lang/stringinterpol/StringContextTest.scala +scala/collection/IteratorTest.scala +scala/collection/NewBuilderTest.scala +scala/collection/ParallelConsistencyTest.scala +scala/collection/SeqViewTest.scala +scala/collection/SetMapConsistencyTest.scala +scala/collection/concurrent/TrieMapTest.scala +scala/collection/convert/WrapperSerializationTest.scala +scala/collection/immutable/ListTest.scala +scala/collection/immutable/StreamTest.scala +scala/collection/immutable/StringLikeTest.scala +scala/collection/mutable/ArrayBufferTest.scala +scala/collection/mutable/MutableListTest.scala +scala/collection/mutable/OpenHashMapTest.scala +scala/collection/mutable/PriorityQueueTest.scala +scala/collection/parallel/immutable/ParRangeTest.scala +scala/concurrent/duration/SerializationTest.scala +scala/concurrent/impl/DefaultPromiseTest.scala +scala/io/SourceTest.scala +scala/runtime/ScalaRunTimeTest.scala +scala/sys/process/PipedProcessTest.scala +scala/sys/process/ProcessTest.scala +scala/tools/testing/AssertUtilTest.scala +scala/tools/testing/AssertThrowsTest.scala +scala/util/SpecVersionTest.scala +scala/util/SystemPropertiesTest.scala + +## Tests fail + +# Reflection +scala/reflect/ClassTagTest.scala + +# Regex +scala/util/matching/CharRegexTest.scala +scala/util/matching/RegexTest.scala + +# Require strict-floats +scala/math/BigDecimalTest.scala + +# Difference of getClass() on primitive values +scala/collection/immutable/RangeTest.scala + +# Test fails only some times with +# 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' +# and' 'set scalaJSUseRhino in Global := false' +scala/collection/immutable/PagedSeqTest.scala + +# Bugs +scala/collection/convert/MapWrapperTest.scala + +# Tests passed but are too slow (timeouts) +scala/collection/immutable/ListSetTest.scala +scala/util/SortingTest.scala diff --git a/scala-test-suite/src/test/resources/2.12.2/WhitelistedTests.txt b/scala-test-suite/src/test/resources/2.12.2/WhitelistedTests.txt new file mode 100644 index 0000000000..60f3a24edb --- /dev/null +++ b/scala-test-suite/src/test/resources/2.12.2/WhitelistedTests.txt @@ -0,0 +1,40 @@ +scala/collection/IndexedSeqOptimizedTest.scala +scala/collection/IndexedSeqTest.scala +scala/collection/IterableViewLikeTest.scala +scala/collection/LinearSeqOptimizedTest.scala +scala/collection/ReusableBuildersTest.scala +scala/collection/SearchingTest.scala +scala/collection/SeqLikeTest.scala +scala/collection/TraversableLikeTest.scala +scala/collection/TraversableOnceTest.scala +scala/collection/convert/NullSafetyToJavaTest.scala +scala/collection/convert/NullSafetyToScalaTest.scala +scala/collection/immutable/HashMapTest.scala +scala/collection/immutable/ListMapTest.scala +scala/collection/immutable/QueueTest.scala +scala/collection/immutable/RangeConsistencyTest.scala +scala/collection/immutable/SetTest.scala +scala/collection/immutable/TreeMapTest.scala +scala/collection/immutable/TreeSetTest.scala +scala/collection/immutable/VectorTest.scala +scala/collection/mutable/ArraySortingTest.scala +scala/collection/mutable/BitSetTest.scala +scala/collection/mutable/HashMapTest.scala +scala/collection/mutable/LinkedHashMapTest.scala +scala/collection/mutable/LinkedHashSetTest.scala +scala/collection/mutable/SetLikeTest.scala +scala/collection/mutable/TreeMapTest.scala +scala/collection/mutable/TreeSetTest.scala +scala/collection/mutable/UnrolledBufferTest.scala +scala/collection/mutable/VectorTest.scala +scala/lang/primitives/PredefAutoboxingTest.scala +scala/math/BigIntTest.scala +scala/math/NumericTest.scala +scala/math/OrderingTest.scala +scala/runtime/ZippedTest.scala +scala/tools/nsc/SampleTest.scala +scala/tools/testing/AssertUtil.scala +scala/tools/testing/TempDir.scala +scala/util/RandomTest.scala +scala/util/TryTest.scala +scala/util/control/ExceptionTest.scala diff --git a/scripts/assemble-cli.sh b/scripts/assemble-cli.sh index 1f0c032800..bc27fac4e9 100755 --- a/scripts/assemble-cli.sh +++ b/scripts/assemble-cli.sh @@ -20,8 +20,8 @@ case $BINVER in BASEVER="2.11.11" ;; 2.12) - FULLVERS="2.12.0 2.12.1" - BASEVER="2.12.1" + FULLVERS="2.12.0 2.12.1 2.12.2" + BASEVER="2.12.2" ;; *) echo "Invalid Scala version $BINVER" >&2 diff --git a/scripts/build-all-js.sh b/scripts/build-all-js.sh index 2203b63231..f0432062ea 100755 --- a/scripts/build-all-js.sh +++ b/scripts/build-all-js.sh @@ -3,7 +3,7 @@ tasks="fastOptJS fullOptJS" projects="helloworld/ reversi/ testingExample/test: testSuite/test:" -for v in 2.11.11 2.10.6 2.12.1; do +for v in 2.11.11 2.10.6 2.12.2; do echo "++$v" echo "package" diff --git a/scripts/publish.sh b/scripts/publish.sh index 83123038dd..dd6e797a29 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -8,9 +8,9 @@ else CMD="echo sbt" fi -FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.12.0 2.12.1" -BIN_VERSIONS="2.10.6 2.11.11 2.12.1" -CLI_VERSIONS="2.10.6 2.11.11 2.12.1" +FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.12.0 2.12.1 2.12.2" +BIN_VERSIONS="2.10.6 2.11.11 2.12.2" +CLI_VERSIONS="2.10.6 2.11.11 2.12.2" SBT_VERSION="2.10.6" COMPILER="compiler jUnitPlugin" From c99fd5576e6756f01c1c0d24b320ffd2e4778217 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 25 Apr 2017 13:31:42 +0200 Subject: [PATCH 0225/2665] Blacklist neg/patmatexhaust-huge.scala. It exhibits spurious failures, and anyway it's testing the pattern matcher exhaustivity checks, which does not concern Scala.js. --- .../scala/tools/partest/scalajs/2.11.11/BlacklistedTests.txt | 3 +++ .../scala/tools/partest/scalajs/2.11.11/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt | 3 +++ .../scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt | 3 +++ .../scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt | 3 +++ .../scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt | 3 +++ .../scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.12.2/BlacklistedTests.txt | 3 +++ .../scala/tools/partest/scalajs/2.12.2/WhitelistedTests.txt | 1 - 12 files changed, 18 insertions(+), 6 deletions(-) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/BlacklistedTests.txt index 83eb479975..b941f5e8fe 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/BlacklistedTests.txt @@ -27,6 +27,9 @@ neg/t7622-cyclic-dependency # Uses some strange macro cross compile mechanism. neg/macro-incompatible-macro-engine-c.scala +# Spurious failures +neg/patmatexhaust-huge.scala + # Uses .java files neg/t6289 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/WhitelistedTests.txt index 5a0c686987..7e25d4af5e 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/WhitelistedTests.txt @@ -1060,7 +1060,6 @@ neg/t9286c.scala neg/t9286a.scala neg/virtpatmat_exhaust_big.scala neg/inlineMaxSize.scala -neg/patmatexhaust-huge.scala run/t7249.scala run/t3563.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt index 0dc70a2a0f..a68e758890 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt @@ -27,6 +27,9 @@ neg/t7622-cyclic-dependency # Uses some strange macro cross compile mechanism. neg/macro-incompatible-macro-engine-c.scala +# Spurious failures +neg/patmatexhaust-huge.scala + # Uses .java files neg/t6289 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt index 19e4217fc8..633a87bcea 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt @@ -1061,7 +1061,6 @@ neg/t9286c.scala neg/t9286a.scala neg/virtpatmat_exhaust_big.scala neg/inlineMaxSize.scala -neg/patmatexhaust-huge.scala run/t7249.scala run/t3563.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt index 007bc3af55..070ed8ea6c 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt @@ -27,6 +27,9 @@ neg/t7622-cyclic-dependency # Uses some strange macro cross compile mechanism. neg/macro-incompatible-macro-engine-c.scala +# Spurious failures +neg/patmatexhaust-huge.scala + # Uses .java files neg/t6289 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt index fa420a587b..a8c54466bf 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt @@ -1060,7 +1060,6 @@ neg/t9286c.scala neg/t9286a.scala neg/virtpatmat_exhaust_big.scala neg/inlineMaxSize.scala -neg/patmatexhaust-huge.scala run/t7249.scala run/t3563.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt index 52594133a7..7c4d820a68 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt @@ -22,6 +22,9 @@ neg/t7622-cyclic-dependency # Uses some strange macro cross compile mechanism. neg/macro-incompatible-macro-engine-c.scala +# Spurious failures +neg/patmatexhaust-huge.scala + # Uses .java files run/t9200 run/noInlineUnknownIndy diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt index 0503e9c2c7..0b00e3852d 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt @@ -1047,7 +1047,6 @@ neg/t9286c.scala neg/t9286a.scala neg/virtpatmat_exhaust_big.scala neg/inlineMaxSize.scala -neg/patmatexhaust-huge.scala run/t7249.scala run/t3563.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt index 7aee11c040..f0081eb856 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt @@ -22,6 +22,9 @@ neg/t7622-cyclic-dependency # Uses some strange macro cross compile mechanism. neg/macro-incompatible-macro-engine-c.scala +# Spurious failures +neg/patmatexhaust-huge.scala + # Uses .java files run/t9200 run/noInlineUnknownIndy diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt index 78ea8bd2e4..f69bee00b7 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt @@ -1045,7 +1045,6 @@ neg/t9286c.scala neg/t9286a.scala neg/virtpatmat_exhaust_big.scala neg/inlineMaxSize.scala -neg/patmatexhaust-huge.scala run/t7249.scala run/t3563.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/BlacklistedTests.txt index 7982bdf902..e39a983628 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/BlacklistedTests.txt @@ -22,6 +22,9 @@ neg/t7622-cyclic-dependency # Uses some strange macro cross compile mechanism. neg/macro-incompatible-macro-engine-c.scala +# Spurious failures +neg/patmatexhaust-huge.scala + # Uses .java files run/t9200 run/noInlineUnknownIndy diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/WhitelistedTests.txt index d48243f28b..aad0b42d9f 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/WhitelistedTests.txt @@ -1045,7 +1045,6 @@ neg/t9286c.scala neg/t9286a.scala neg/virtpatmat_exhaust_big.scala neg/inlineMaxSize.scala -neg/patmatexhaust-huge.scala run/t7249.scala run/t3563.scala From d39a999607ae8f16d1bca3a2e2c18b793aaae9e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 25 Apr 2017 14:42:55 +0200 Subject: [PATCH 0226/2665] Add Scala 2.13.0-M1 to the build and CI. --- ci/checksizes.sh | 9 + ci/matrix.xml | 40 + .../scalajs/2.13.0-M1/BlacklistedTests.txt | 1003 +++++ .../scalajs/2.13.0-M1/BuglistedTests.txt | 10 + .../scalajs/2.13.0-M1/WhitelistedTests.txt | 3352 +++++++++++++++++ .../2.13.0-M1/neg/t6446-additional.check | 30 + .../scalajs/2.13.0-M1/neg/t6446-list.check | 2 + .../scalajs/2.13.0-M1/neg/t6446-missing.check | 30 + .../2.13.0-M1/neg/t6446-show-phases.check | 29 + .../2.13.0-M1/neg/t7494-no-options.check | 31 + .../2.13.0-M1/run/Course-2002-01.check | 37 + .../2.13.0-M1/run/Course-2002-02.check | 187 + .../2.13.0-M1/run/Course-2002-04.check | 64 + .../2.13.0-M1/run/Course-2002-08.check | 171 + .../2.13.0-M1/run/Course-2002-09.check | 50 + .../2.13.0-M1/run/Course-2002-10.check | 46 + .../partest/scalajs/2.13.0-M1/run/Meter.check | 16 + .../2.13.0-M1/run/MeterCaseClass.check | 16 + .../partest/scalajs/2.13.0-M1/run/bugs.sem | 1 + .../scalajs/2.13.0-M1/run/caseClassHash.check | 9 + .../partest/scalajs/2.13.0-M1/run/deeps.check | 87 + .../2.13.0-M1/run/dynamic-anyval.check | 4 + .../scalajs/2.13.0-M1/run/impconvtimes.check | 1 + .../scalajs/2.13.0-M1/run/imports.check | 21 + .../scalajs/2.13.0-M1/run/interpolation.check | 32 + .../run/interpolationMultiline1.check | 26 + .../scalajs/2.13.0-M1/run/issue192.sem | 1 + .../2.13.0-M1/run/macro-bundle-static.check | 6 + .../2.13.0-M1/run/macro-bundle-toplevel.check | 6 + .../run/macro-bundle-whitebox-decl.check | 6 + .../partest/scalajs/2.13.0-M1/run/misc.check | 62 + .../scalajs/2.13.0-M1/run/promotion.check | 4 + .../scalajs/2.13.0-M1/run/runtime.check | 70 + .../scalajs/2.13.0-M1/run/spec-self.check | 2 + .../scalajs/2.13.0-M1/run/structural.check | 37 + .../scalajs/2.13.0-M1/run/t0421-new.check | 3 + .../scalajs/2.13.0-M1/run/t0421-old.check | 3 + .../partest/scalajs/2.13.0-M1/run/t1503.sem | 1 + .../partest/scalajs/2.13.0-M1/run/t3702.check | 2 + .../partest/scalajs/2.13.0-M1/run/t4148.sem | 1 + .../partest/scalajs/2.13.0-M1/run/t4617.check | 1 + .../partest/scalajs/2.13.0-M1/run/t5356.check | 6 + .../partest/scalajs/2.13.0-M1/run/t5552.check | 6 + .../partest/scalajs/2.13.0-M1/run/t5568.check | 9 + .../scalajs/2.13.0-M1/run/t5629b.check | 10 + .../partest/scalajs/2.13.0-M1/run/t5680.check | 3 + .../partest/scalajs/2.13.0-M1/run/t5866.check | 2 + .../2.13.0-M1/run/t6318_primitives.check | 54 + .../partest/scalajs/2.13.0-M1/run/t6662.check | 1 + .../partest/scalajs/2.13.0-M1/run/t7657.check | 3 + .../partest/scalajs/2.13.0-M1/run/t7763.sem | 1 + .../scalajs/2.13.0-M1/run/t8570a.check | 1 + .../partest/scalajs/2.13.0-M1/run/t8764.check | 5 + .../scalajs/2.13.0-M1/run/t9387b.check | 1 + .../partest/scalajs/2.13.0-M1/run/t9656.check | 14 + .../2.13.0-M1/run/try-catch-unify.check | 4 + .../2.13.0-M1/run/virtpatmat_switch.check | 7 + .../2.13.0-M1/run/virtpatmat_typetag.check | 10 + .../partest/scalajs/PartestInterface.scala | 2 +- project/Build.scala | 58 +- .../resources/2.13.0-M1/BlacklistedTests.txt | 131 + .../resources/2.13.0-M1/WhitelistedTests.txt | 43 + scripts/build-all-js.sh | 2 +- scripts/publish.sh | 4 +- ...nstanceTestsHijackedBoxedClassesTest.scala | 4 +- 65 files changed, 5860 insertions(+), 30 deletions(-) create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/BlacklistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/BuglistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/WhitelistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t6446-additional.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t6446-list.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t6446-missing.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t6446-show-phases.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t7494-no-options.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-01.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-02.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-04.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-08.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-09.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-10.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Meter.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/MeterCaseClass.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/bugs.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/caseClassHash.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/deeps.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/dynamic-anyval.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/impconvtimes.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/imports.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/interpolation.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/interpolationMultiline1.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/issue192.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/macro-bundle-static.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/macro-bundle-toplevel.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/macro-bundle-whitebox-decl.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/misc.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/promotion.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/runtime.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/spec-self.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/structural.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t0421-new.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t0421-old.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t1503.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t3702.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t4148.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t4617.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5356.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5552.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5568.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5629b.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5680.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5866.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t6318_primitives.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t6662.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t7657.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t7763.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t8570a.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t8764.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t9387b.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t9656.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/try-catch-unify.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/virtpatmat_switch.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/virtpatmat_typetag.check create mode 100644 scala-test-suite/src/test/resources/2.13.0-M1/BlacklistedTests.txt create mode 100644 scala-test-suite/src/test/resources/2.13.0-M1/WhitelistedTests.txt diff --git a/ci/checksizes.sh b/ci/checksizes.sh index 28dacf2400..a4dd550104 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -14,6 +14,9 @@ case $FULLVER in 2.12.2) VER=2.12 ;; + 2.13.0-M1) + VER=2.13.0-M1 + ;; 2.10.3|2.10.4|2.10.5|2.10.6|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7|2.11.8|2.12.0|2.12.1) echo "Ignoring checksizes for Scala $FULLVER" exit 0 @@ -51,6 +54,12 @@ case $FULLVER in REVERSI_PREOPT_GZ_EXPECTEDSIZE=76000 REVERSI_OPT_GZ_EXPECTEDSIZE=33000 ;; + 2.13.0-M1) + REVERSI_PREOPT_EXPECTEDSIZE=627000 + REVERSI_OPT_EXPECTEDSIZE=144000 + REVERSI_PREOPT_GZ_EXPECTEDSIZE=76000 + REVERSI_OPT_GZ_EXPECTEDSIZE=33000 + ;; esac echo "Checksizes: Scala version: $FULLVER" diff --git a/ci/matrix.xml b/ci/matrix.xml index e6b2942d31..c881149c03 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -324,6 +324,10 @@ 2.12.2 1.8 + + 2.13.0-M1 + 1.8 + @@ -341,6 +345,11 @@ 1.8 testSuite + + 2.13.0-M1 + 1.8 + testSuite + @@ -353,6 +362,11 @@ 1.8 scalaTestSuite + + 2.13.0-M1 + 1.8 + scalaTestSuite + @@ -370,6 +384,11 @@ 1.8 testSuite + + 2.13.0-M1 + 1.8 + testSuite + @@ -382,6 +401,11 @@ 1.8 scalaTestSuite + + 2.13.0-M1 + 1.8 + scalaTestSuite + @@ -396,6 +420,10 @@ 2.12.2 1.8 + + 2.13.0-M1 + 1.8 + @@ -439,6 +467,10 @@ 2.12.2 1.8 + + 2.13.0-M1 + 1.8 + @@ -565,6 +597,14 @@ 2.12.2 1.8 + + 2.13.0-M1 + 1.8 + + + 2.13.0-M1 + 1.8 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/BlacklistedTests.txt new file mode 100644 index 0000000000..2040dfafd3 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/BlacklistedTests.txt @@ -0,0 +1,1003 @@ +# +# POS +# + +# Using Jsoup, what's that? +pos/cycle-jsoup.scala + +# Kills our IR serializer, it's an artificially super-deep if/else if +pos/t9181.scala + +# +# NEG +# + +# Screws up, but not really our problem (error: None.get instead of +# phase ordering error) +neg/t7494-multi-right-after +neg/t7494-right-after-before +neg/t7622-multi-followers +neg/t7622-cyclic-dependency + +# Uses some strange macro cross compile mechanism. +neg/macro-incompatible-macro-engine-c.scala + +# Spurious failures +neg/patmatexhaust-huge.scala + +# Uses .java files +run/t9200 +run/noInlineUnknownIndy +# +# RUN +# + +# Relies on the exact toString() representation of Floats/Doubles +run/t2378.scala + +# Uses ClassTags on existentials which are broken in Scala (see #251) +run/valueclasses-classtag-existential.scala + +# Relies on a particular execution speed +run/t5857.scala + +# Using parts of the javalib we don't plan to support + +run/t5018.scala +run/t2417.scala +run/t4813.scala +run/lazy-concurrent.scala +run/t3667.scala +run/t3038d.scala +run/shutdownhooks.scala +run/t5590.scala +run/t3895b.scala +run/t5974.scala +run/t5262.scala +run/serialize-stream.scala +run/sysprops.scala +run/lambda-serialization-gc.scala +run/t9390.scala +run/t9390b.scala +run/t9390c.scala + +run/t2849.scala +run/t1360.scala +run/t3199b.scala +run/t8690.scala + +run/various-flat-classpath-types.scala + +# Uses java.util.Collections +run/t2250.scala + +# Uses java.math.BigDecimal / BigInteger : but failures not due to them +run/hashhash.scala +run/is-valid-num.scala + +# Documented semantic difference on String.split(x: Array[Char]) +run/t0325.scala + +# Using Threads +run/t6969.scala +run/inner-obj-auto.scala +run/predef-cycle.scala +run/synchronized.scala + +# Uses java.security +run/t2318.scala + +# Tries to catch java.lang.StackOverflowError +run/t6154.scala + +# Tries to catch java.lang.OutOfMemoryError +run/t7880.scala + +# Taking too much time, because JavaScript is not as fast as the JVM + +run/collections.scala +run/t3989.scala +run/adding-growing-set.scala +run/t3242.scala +run/hashCodeDistribution.scala +run/t408.scala +run/t6584.scala +run/t6853.scala +run/UnrolledBuffer.scala +run/t6253a.scala +run/t6253b.scala +run/t6253c.scala +run/numbereq.scala +run/t4658.scala + +# Crashes Rhino + +run/bridges.scala +run/patmat-exprs.scala + +# Using partest properties + +run/tailcalls.scala +run/t4294.scala +run/t6331b.scala + +# Using IO + +run/t6488.scala +run/t6988.scala + +# Object{Output|Input}Streams +run/t6935.scala +run/t8188.scala +run/t9375.scala +run/t9365.scala +run/inlineAddDeserializeLambda.scala +run/sammy_seriazable.scala +run/lambda-serialization-security.scala + +# Using System.getProperties + +run/t4426.scala + +# Using Await + +run/t7336.scala +run/t7775.scala +run/future-flatmap-exec-count.scala + +# Using detailed stack trace + +run/t6308.scala + +# Using reflection + +run/t6063 + +run/mixin-bridge-methods.scala +run/t5125.scala +run/outertest.scala +run/t6223.scala +run/t5652b +run/elidable-opt.scala +run/nullable-lazyvals.scala +run/t4794.scala +run/t5652 +run/t5652c +run/getClassTest-old.scala +run/t8960.scala +run/t7965.scala +run/t8087.scala +run/t8931.scala +run/t8445.scala +run/lambda-serialization.scala + +run/reflection-repl-classes.scala +run/t5256e.scala +run/typetags_core.scala +run/reflection-constructormirror-toplevel-badpath.scala +run/t5276_1b.scala +run/reflection-sorted-decls.scala +run/toolbox_typecheck_implicitsdisabled.scala +run/t5418b.scala +run/toolbox_typecheck_macrosdisabled2.scala +run/abstypetags_serialize.scala +run/all-overridden.scala +run/showraw_tree_kinds.scala +run/showraw_tree_types_ids.scala +run/showraw_tree_types_typed.scala +run/showraw_tree_ids.scala +run/showraw_tree_ultimate.scala +run/t5266_2.scala +run/t5274_1.scala +run/t5224.scala +run/reflection-sanitychecks.scala +run/t6086-vanilla.scala +run/t5277_2.scala +run/reflection-methodsymbol-params.scala +run/reflection-valueclasses-standard.scala +run/t5274_2.scala +run/t5423.scala +run/reflection-modulemirror-toplevel-good.scala +run/t5419.scala +run/t5271_3.scala +run/reflection-enclosed-nested-basic.scala +run/reflection-enclosed-nested-nested-basic.scala +run/fail-non-value-types.scala +run/exprs_serialize.scala +run/t5258a.scala +run/typetags_without_scala_reflect_manifest_lookup.scala +run/t4110-new.scala +run/t5273_2b_newpatmat.scala +run/t6277.scala +run/t5335.scala +run/toolbox_typecheck_macrosdisabled.scala +run/reflection-modulemirror-inner-good.scala +run/t5229_2.scala +run/typetags_multi.scala +run/typetags_without_scala_reflect_typetag_manifest_interop.scala +run/reflection-constructormirror-toplevel-good.scala +run/reflection-magicsymbols-invoke.scala +run/t6392b.scala +run/t5229_1.scala +run/reflection-magicsymbols-vanilla.scala +run/t5225_2.scala +run/runtimeEval1.scala +run/reflection-enclosed-nested-inner-basic.scala +run/reflection-fieldmirror-ctorparam.scala +run/t6181.scala +run/reflection-magicsymbols-repl.scala +run/t5272_2_newpatmat.scala +run/t5270.scala +run/t5418a.scala +run/t5276_2b.scala +run/t5256f.scala +run/reflection-enclosed-basic.scala +run/reflection-constructormirror-inner-badpath.scala +run/interop_typetags_are_manifests.scala +run/newTags.scala +run/t5273_1_newpatmat.scala +run/reflection-constructormirror-nested-good.scala +run/t2236-new.scala +run/existentials3-new.scala +run/t6323b.scala +run/t5943a1.scala +run/reflection-fieldmirror-getsetval.scala +run/t5272_1_oldpatmat.scala +run/t5256h.scala +run/t1195-new.scala +run/t5840.scala +run/reflection-methodsymbol-returntype.scala +run/reflection-fieldmirror-accessorsareokay.scala +run/reflection-sorted-members.scala +run/reflection-allmirrors-tostring.scala +run/valueclasses-typetag-existential.scala +run/toolbox_console_reporter.scala +run/reflection-enclosed-inner-inner-basic.scala +run/t5256b.scala +run/bytecodecs.scala +run/elidable.scala +run/freetypes_false_alarm1.scala +run/freetypes_false_alarm2.scala +run/getClassTest-new.scala +run/idempotency-extractors.scala +run/idempotency-case-classes.scala +run/idempotency-this.scala +run/idempotency-labels.scala +run/idempotency-lazy-vals.scala +run/interop_manifests_are_abstypetags.scala +run/interop_manifests_are_typetags.scala +run/abstypetags_core.scala +run/macro-reify-abstypetag-notypeparams +run/macro-reify-abstypetag-typeparams-tags +run/macro-reify-abstypetag-typeparams-notags +run/macro-reify-abstypetag-usetypetag +run/macro-reify-freevars +run/macro-reify-splice-outside-reify +run/macro-reify-tagless-a +run/macro-reify-type +run/macro-reify-typetag-typeparams-tags +run/macro-reify-typetag-notypeparams +run/macro-undetparams-implicitval +run/manifests-new.scala +run/manifests-old.scala +run/no-pickle-skolems +run/position-val-def.scala +run/reflect-priv-ctor.scala +run/primitive-sigs-2-new.scala +run/primitive-sigs-2-old.scala +run/reflection-enclosed-inner-basic.scala +run/reflection-enclosed-inner-nested-basic.scala +run/reflection-constructormirror-inner-good.scala +run/reflection-constructormirror-nested-badpath.scala +run/reflection-fancy-java-classes +run/reflection-fieldsymbol-navigation.scala +run/reflection-fieldmirror-nmelocalsuffixstring.scala +run/reflection-fieldmirror-getsetvar.scala +run/reflection-fieldmirror-privatethis.scala +run/reflection-implicit.scala +run/reflection-mem-glbs.scala +run/reflection-mem-tags.scala +run/reflection-java-annotations +run/reflection-java-crtp +run/reflection-methodsymbol-typeparams.scala +run/reflection-modulemirror-nested-badpath.scala +run/reflection-modulemirror-inner-badpath.scala +run/reflection-modulemirror-nested-good.scala +run/reflection-modulemirror-toplevel-badpath.scala +run/reflection-sync-subtypes.scala +run/reflinit.scala +run/reflection-valueclasses-derived.scala +run/reflection-valueclasses-magic.scala +run/resetattrs-this.scala +run/runtimeEval2.scala +run/showraw_aliases.scala +run/showraw_mods.scala +run/shortClass.scala +run/showraw_nosymbol.scala +run/showraw_tree.scala +run/showraw_tree_types_untyped.scala +run/t1167.scala +run/t2577.scala +run/t2873.scala +run/t2886.scala +run/t2251b.scala +run/t3346j.scala +run/t3507-new.scala +run/t3569.scala +run/t5125b.scala +run/t5225_1.scala +run/t3425b +run/t5256a.scala +run/t5230.scala +run/t5256c.scala +run/t5256g.scala +run/t5266_1.scala +run/t5269.scala +run/t5271_1.scala +run/t5271_2.scala +run/t5271_4.scala +run/t5272_1_newpatmat.scala +run/t5272_2_oldpatmat.scala +run/t5273_1_oldpatmat.scala +run/t5273_2a_newpatmat.scala +run/t5273_2a_oldpatmat.scala +run/t5275.scala +run/t5276_1a.scala +run/t5276_2a.scala +run/t5277_1.scala +run/t5279.scala +run/t5334_1.scala +run/t5334_2.scala +run/t5415.scala +run/t5418.scala +run/t5676.scala +run/t5704.scala +run/t5710-1.scala +run/t5710-2.scala +run/t5770.scala +run/t5894.scala +run/t5816.scala +run/t5824.scala +run/t5912.scala +run/t5942.scala +run/t5943a2.scala +run/t6023.scala +run/t6113.scala +run/t6175.scala +run/t6178.scala +run/t6199-mirror.scala +run/t6199-toolbox.scala +run/t6240-universe-code-gen.scala +run/t6221 +run/t6260b.scala +run/t6259.scala +run/t6287.scala +run/t6344.scala +run/t6392a.scala +run/t6591_1.scala +run/t6591_2.scala +run/t6591_3.scala +run/t6591_5.scala +run/t6591_6.scala +run/t6591_7.scala +run/t6608.scala +run/t6677.scala +run/t6687.scala +run/t6715.scala +run/t6719.scala +run/t6793.scala +run/t6860.scala +run/t6793b.scala +run/t6793c.scala +run/t7045.scala +run/t7046.scala +run/t7008-scala-defined +run/t7120b.scala +run/t7151.scala +run/t7214.scala +run/t7235.scala +run/t7331a.scala +run/t7331b.scala +run/t7331c.scala +run/t7558.scala +run/t7556 +run/t7779.scala +run/t7868b.scala +run/toolbox_current_run_compiles.scala +run/toolbox_default_reporter_is_silent.scala +run/toolbox_parse_package.scala +run/toolbox_silent_reporter.scala +run/toolbox_typecheck_inferimplicitvalue.scala +run/typetags_serialize.scala +run/valueclasses-typetag-basic.scala +run/WeakHashSetTest.scala +run/valueclasses-typetag-generic.scala +run/t4023.scala +run/t4024.scala +run/t6380.scala +run/t5273_2b_oldpatmat.scala +run/t8104 +run/t8047.scala +run/t6992 +run/var-arity-class-symbol.scala +run/typetags_symbolof_x.scala +run/typecheck +run/t8190.scala +run/t8192 +run/t8177f.scala +run/t8199.scala +run/t7932.scala +run/t7700.scala +run/t7570c.scala +run/t7570b.scala +run/t7533.scala +run/t7570a.scala +run/t7044 +run/t7328.scala +run/t6733.scala +run/t6554.scala +run/t6732.scala +run/t6379 +run/t6411b.scala +run/t6411a.scala +run/t6260c.scala +run/t6260-delambdafy.scala +run/showdecl +run/reflection-sync-potpourri.scala +run/reflection-tags.scala +run/reflection-companiontype.scala +run/reflection-scala-annotations.scala +run/reflection-idtc.scala +run/macro-reify-nested-b2 +run/mixin-signatures.scala +run/reflection-companion.scala +run/macro-reify-nested-b1 +run/macro-reify-nested-a2 +run/macro-reify-nested-a1 +run/macro-reify-chained2 +run/macro-reify-chained1 +run/inferred-type-constructors.scala +run/mirror_symbolof_x.scala +run/t8196.scala +run/t8549b.scala +run/t8574.scala +run/t8637.scala +run/t8253.scala +run/t9027.scala +run/t6622.scala +run/toolbox_expand_macro.scala +run/toolbox-varargs +run/t9252.scala +run/t9182.scala +run/t9102.scala +run/t720.scala +run/t9408.scala +run/trait-default-specialize.scala +run/lazy-locals-2.scala +run/t5294.scala +run/trait_fields_final.scala +run/trait_fields_bytecode.scala +run/trait_fields_volatile.scala +run/junitForwarders + +run/reify_newimpl_29.scala +run/reify_magicsymbols.scala +run/reify_inheritance.scala +run/reify_newimpl_12.scala +run/reify_typerefs_2b.scala +run/reify_csv.scala +run/reify_inner2.scala +run/reify_maps_oldpatmat.scala +run/reify_newimpl_43.scala +run/reify_nested_inner_refers_to_local.scala +run/reify_closure7.scala +run/reify_closure8b.scala +run/reify_typerefs_3b.scala +run/reify_newimpl_44.scala +run/reify_newimpl_06.scala +run/reify_newimpl_05.scala +run/reify_newimpl_20.scala +run/reify_newimpl_23.scala +run/reify_metalevel_breach_-1_refers_to_1.scala +run/reify_newimpl_41.scala +run/reify-repl-fail-gracefully.scala +run/reify_fors_oldpatmat.scala +run/reify_inner3.scala +run/reify_closure8a.scala +run/reify_closures10.scala +run/reify_ann2a.scala +run/reify_newimpl_51.scala +run/reify_newimpl_47.scala +run/reify_extendbuiltins.scala +run/reify_newimpl_30.scala +run/reify_newimpl_38.scala +run/reify_closure2a.scala +run/reify_newimpl_45.scala +run/reify_closure1.scala +run/reify_generic2.scala +run/reify_printf.scala +run/reify_closure6.scala +run/reify_newimpl_37.scala +run/reify_newimpl_35.scala +run/reify_typerefs_3a.scala +run/reify_newimpl_25.scala +run/reify_ann4.scala +run/reify_typerefs_1b.scala +run/reify_newimpl_22.scala +run/reify_this.scala +run/reify_typerefs_2a.scala +run/reify_newimpl_03.scala +run/reify_newimpl_48.scala +run/reify_varargs.scala +run/reify_newimpl_42.scala +run/reify_newimpl_15.scala +run/reify_nested_inner_refers_to_global.scala +run/reify_newimpl_02.scala +run/reify_newimpl_01.scala +run/reify_fors_newpatmat.scala +run/reify_classfileann_a.scala +run/reify_nested_outer_refers_to_local.scala +run/reify_newimpl_13.scala +run/reify_closure5a.scala +run/reify_inner4.scala +run/reify_sort.scala +run/reify_ann1a.scala +run/reify_classfileann_b.scala +run/reify_closure4a.scala +run/reify_newimpl_33.scala +run/reify_sort1.scala +run/reify_properties.scala +run/reify_generic.scala +run/reify_newimpl_27.scala +run/reify-aliases.scala +run/reify_ann3.scala +run/reify-staticXXX.scala +run/reify_ann1b.scala +run/reify_ann5.scala +run/reify_anonymous.scala +run/reify-each-node-type.scala +run/reify_copypaste2.scala +run/reify_closure3a.scala +run/reify_copypaste1.scala +run/reify_complex.scala +run/reify_for1.scala +run/reify_getter.scala +run/reify_implicits-new.scala +run/reify_inner1.scala +run/reify_implicits-old.scala +run/reify_lazyunit.scala +run/reify_lazyevaluation.scala +run/reify_maps_newpatmat.scala +run/reify_metalevel_breach_+0_refers_to_1.scala +run/reify_metalevel_breach_-1_refers_to_0_a.scala +run/reify_metalevel_breach_-1_refers_to_0_b.scala +run/reify_nested_outer_refers_to_global.scala +run/reify_newimpl_04.scala +run/reify_newimpl_14.scala +run/reify_newimpl_11.scala +run/reify_newimpl_18.scala +run/reify_newimpl_19.scala +run/reify_newimpl_31.scala +run/reify_newimpl_21.scala +run/reify_newimpl_36.scala +run/reify_newimpl_39.scala +run/reify_newimpl_40.scala +run/reify_newimpl_49.scala +run/reify_newimpl_50.scala +run/reify_newimpl_52.scala +run/reify_renamed_term_basic.scala +run/reify_renamed_term_local_to_reifee.scala +run/reify_renamed_term_overloaded_method.scala +run/reify_renamed_type_basic.scala +run/reify_renamed_type_local_to_reifee.scala +run/reify_renamed_type_spliceable.scala +run/reify_typerefs_1a.scala +run/reify_timeofday.scala +run/reify_renamed_term_t5841.scala + +run/t7521b.scala +run/t8575b.scala +run/t8575c.scala +run/t8944c.scala +run/t9535.scala +run/t9437a +run/t9437b +run/t9814.scala +run/t10009.scala +run/t10075.scala +run/t10075b + +run/t8756.scala +run/inferred-type-constructors-hou.scala +run/trait-static-forwarder +run/SD-235.scala +run/t10026.scala + +# Uses refletction indirectly through +# scala.runtime.ScalaRunTime.replStringOf +run/t6634.scala + +# Using reflection to invoke macros. These tests actually don't require +# or test reflection, but use it to separate compilation units nicely. +# It's a pity we cannot use them + +run/macro-abort-fresh +run/macro-expand-varargs-explicit-over-nonvarargs-bad +run/macro-invalidret-doesnt-conform-to-def-rettype +run/macro-invalidret-nontypeable +run/macro-invalidusage-badret +run/macro-invalidusage-partialapplication +run/macro-invalidusage-partialapplication-with-tparams +run/macro-reflective-ma-normal-mdmi +run/macro-reflective-mamd-normal-mi + +# Using macros, but indirectly creating calls to reflection +run/macro-reify-unreify + +# Using Enumeration in a way we cannot fix + +run/enums.scala +run/t3719.scala +run/t8611b.scala + +# Exceptions that become JavaScriptException + +run/pf-catch.scala +run/exceptions-2.scala +run/exceptions-nest.scala +run/t8601c.scala +run/t8601b.scala +run/inlineHandlers.scala + +# Expecting unsupported exceptions (e.g. ArrayIndexOutOfBounds) +run/optimizer-array-load.scala +run/t6827.scala +run/t8601.scala + +# Playing with classfile format + +run/classfile-format-51.scala +run/classfile-format-52.scala + +# Concurrent collections (TrieMap) +# has too much stuff implemented in *.java, so no support +run/triemap-hash.scala + +# Using parallel collections + +run/concurrent-map-conversions.scala +run/map_java_conversions.scala + +# Using scala.xml + +run/t4124.scala + +# Using Swing + +run/t3613.scala + +# Using the REPL + +run/t4285.scala +run/constant-type.scala +run/repl-bare-expr.scala +run/repl-parens.scala +run/repl-assign.scala +run/t5583.scala +run/treePrint.scala +run/constrained-types.scala +run/repl-power.scala +run/t4710.scala +run/repl-paste.scala +run/repl-reset.scala +run/repl-paste-3.scala +run/t6329_repl.scala +run/t6273.scala +run/repl-paste-2.scala +run/t5655.scala +run/t5072.scala +run/repl-colon-type.scala +run/kind-repl-command.scala +run/repl-trim-stack-trace.scala +run/t4594-repl-settings.scala +run/repl-save.scala +run/repl-paste-raw.scala +run/repl-paste-4.scala +run/t7801.scala +run/repl-backticks.scala +run/t6633.scala +run/repl-inline.scala + +# Using the Repl (scala.tools.partest.ReplTest) +run/class-symbol-contravariant.scala +run/lub-visibility.scala +run/macro-bundle-repl.scala +run/macro-repl-basic.scala +run/macro-repl-dontexpand.scala +run/macro-system-properties.scala +run/reflection-equality.scala +run/reflection-repl-elementary.scala +run/reify_newimpl_26.scala +run/repl-out-dir.scala +run/repl-term-macros.scala +run/repl-transcript.scala +run/repl-type-verbose.scala +run/t3376.scala +run/t4025.scala +run/t4172.scala +run/t4216.scala +run/t4542.scala +run/t4671.scala +run/t5256d.scala +run/t5535.scala +run/t5537.scala +run/t5789.scala +run/t6086-repl.scala +run/t6146b.scala +run/t6187.scala +run/t6320.scala +run/t6381.scala +run/t6434.scala +run/t6439.scala +run/t6507.scala +run/t6549.scala +run/t6937.scala +run/t7185.scala +run/t7319.scala +run/t7482a.scala +run/t7634.scala +run/t7747-repl.scala +run/t7805-repl-i.scala +run/tpeCache-tyconCache.scala +run/repl-empty-package +run/repl-javap-def.scala +run/repl-javap-mem.scala +run/repl-javap-outdir +run/repl-javap.scala +run/t6329_repl_bug.scala +run/t4950.scala +run/xMigration.scala +run/t6541-option.scala +run/repl-serialization.scala +run/t9174.scala +run/repl-paste-5.scala +run/repl-no-uescape.scala +run/repl-no-imports-no-predef-classbased.scala +run/repl-implicits-nopredef.scala +run/repl-classbased.scala +run/repl-no-imports-no-predef-power.scala +run/repl-paste-b.scala +run/repl-paste-6.scala +run/repl-implicits.scala +run/repl-no-imports-no-predef.scala +run/repl-paste-raw-b.scala +run/repl-paste-raw-c.scala +run/t9749-repl-dot.scala +run/trait_fields_repl.scala +run/t7139 +run/t9689 +run/trailing-commas.scala +run/t4700.scala +run/t9880-9881.scala + +# Using Scala Script (partest.ScriptTest) + +run/t7711-script-args.scala +run/t4625.scala +run/t4625c.scala +run/t4625b.scala + +# Using the compiler API + +run/t2512.scala +run/analyzerPlugins.scala +run/compiler-asSeenFrom.scala +run/t5603.scala +run/t6440.scala +run/t5545.scala +run/existentials-in-compiler.scala +run/global-showdef.scala +run/stream_length.scala +run/annotatedRetyping.scala +run/imain.scala +run/existential-rangepos.scala +run/delambdafy_uncurry_byname_inline.scala +run/delambdafy_uncurry_byname_method.scala +run/delambdafy_uncurry_inline.scala +run/delambdafy_t6555.scala +run/delambdafy_uncurry_method.scala +run/delambdafy_t6028.scala +run/memberpos.scala +run/programmatic-main.scala +run/reflection-names.scala +run/settings-parse.scala +run/sm-interpolator.scala +run/t1501.scala +run/t1500.scala +run/sammy_java8.scala +run/t1618.scala +run/t2464 +run/t4072.scala +run/t5064.scala +run/t5385.scala +run/t5699.scala +run/t5717.scala +run/t5940.scala +run/t6028.scala +run/t6194.scala +run/t6669.scala +run/t6745-2.scala +run/t7096.scala +run/t7271.scala +run/t7337.scala +run/t7398.scala +run/t7569.scala +run/t7852.scala +run/t7817-tree-gen.scala +run/t7825.scala + +# partest.ParserTest +run/t3368.scala +run/t3368-b.scala +run/t3368-c.scala +run/t3368-d.scala +run/t9944.scala + +# partest.DirectTest +run/t6288.scala +run/t6331.scala +run/t6440b.scala +run/t6555.scala +run/t7876.scala +run/typetags_without_scala_reflect_typetag_lookup.scala +run/dynamic-updateDynamic.scala +run/dynamic-selectDynamic.scala +run/dynamic-applyDynamic.scala +run/dynamic-applyDynamicNamed.scala +run/t4841-isolate-plugins +run/large_code.scala +run/macroPlugins-namerHooks.scala +run/t4841-no-plugin.scala +run/t4332.scala +run/t8029.scala +run/t8046 +run/t5905-features.scala +run/t5905b-features.scala +run/large_class.scala +run/t8708_b +run/icode-reader-dead-code.scala +run/t5938.scala +run/t8502.scala +run/t6502.scala +run/t8907.scala +run/t9097.scala +run/macroPlugins-enterStats.scala +run/sbt-icode-interface.scala +run/t8502b.scala +run/t9437c +run/repl-paste-parse.scala +run/t5463.scala +run/t8433.scala +run/sd275.scala +run/sd275-java + +# Using partest.StoreReporterDirectTest +run/t10171 + +# partest.StubErrorMessageTest +run/StubErrorBInheritsFromA.scala +run/StubErrorComplexInnerClass.scala +run/StubErrorHK.scala +run/StubErrorReturnTypeFunction.scala +run/StubErrorReturnTypeFunction2.scala +run/StubErrorReturnTypePolyFunction.scala +run/StubErrorSubclasses.scala +run/StubErrorTypeclass.scala +run/StubErrorTypeDef.scala + +# partest.CompilerTest +run/t8852a.scala + +# partest.ASMConverters +run/t9403 + +# partest.BytecodeTest +run/t7106 +run/t7974 +run/t8601-closure-elim.scala +run/t4788 +run/t4788-separate-compilation + +# partest.SessionTest +run/t8843-repl-xlat.scala +run/t9206.scala +run/t9170.scala +run/t8918-unary-ids.scala +run/t1931.scala + +# partest.JavapTest +run/t8608-no-format.scala + +# Using .java source files + +run/t4317 +run/t4238 +run/t2296c +run/t4119 +run/t4283 +run/t4891 +run/t6168 +run/t6168b +run/t6240a +run/t6240b +run/t6548 +run/t6989 +run/t7008 +run/t7246 +run/t7246b +run/t7359 +run/t7439 +run/t7455 +run/t7510 +run/t7582-private-within +run/t7582 +run/t7582b +run/t3897 +run/t7374 +run/t3452e +run/t3452g +run/t3452d +run/t3452b +run/t3452a +run/t8442 +run/t8601e +run/t9298 +run/t9298b +run/t9359 +run/t7741a +run/t7741b +run/bcodeInlinerMixed +run/t9268 +run/t9489 +run/t9915 +run/t10059 +run/t1459 +run/t1459generic +run/t3236 +run/t9013 +run/t10231 +run/t10067 + +# Using scala-script +run/t7791-script-linenums.scala + +# Suffers from bug in Node.js (https://github.com/joyent/node/issues/7528) +run/range-unit.scala + +# Using scalap +run/scalapInvokedynamic.scala + +# Using Manifests (which use Class.getInterfaces) +run/valueclasses-manifest-existential.scala +run/existentials3-old.scala +run/t2236-old.scala +run/interop_manifests_are_classtags.scala +run/valueclasses-manifest-generic.scala +run/valueclasses-manifest-basic.scala +run/t1195-old.scala +run/t3758-old.scala +run/t4110-old.scala +run/t6246.scala + +# Using ScalaRunTime.stringOf +run/value-class-extractor-seq.scala +run/t3493.scala + +# Custom invoke dynamic node +run/indy-via-macro +run/indy-via-macro-with-dynamic-args + +### Incorrect partests ### +# Badly uses constract of Console.print (no flush) +run/t429.scala +run/t6102.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/BuglistedTests.txt new file mode 100644 index 0000000000..b210d1091e --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/BuglistedTests.txt @@ -0,0 +1,10 @@ +# The tests in this file should pass but have never passed so far +# use scala.tools.partest.scalajs.testunknownonly to only run tests +# which are neither in BuglistedTests.txt, WhitelistedTests.txt or +# BlacklistedTests.txt + +# Broken by GCC, filed as #2815 +run/Predef.readLine.scala + +# `Int.box(???)` crashes the compiler, filed as #2901 +run/t10069b.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/WhitelistedTests.txt new file mode 100644 index 0000000000..47f4c5b1e7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/WhitelistedTests.txt @@ -0,0 +1,3352 @@ +pos/spec-super.scala +pos/t1035.scala +pos/t5897.scala +pos/irrefutable.scala +pos/spec-partialmap.scala +pos/tcpoly_seq.scala +pos/partialfun.scala +pos/t2795-new.scala +pos/clsrefine.scala +pos/t0774 +pos/t1070.scala +pos/t5957 +pos/looping-jsig.scala +pos/t3274.scala +pos/spec-fields-old.scala +pos/t262.scala +pos/t7486.scala +pos/t2261.scala +pos/t6600.scala +pos/t4786.scala +pos/t5406.scala +pos/tcpoly_late_method_params.scala +pos/t2726 +pos/pos-bug1210.scala +pos/t3312.scala +pos/manifest1-old.scala +pos/gadt-gilles.scala +pos/t4842.scala +pos/ted.scala +pos/NoCyclicReference.scala +pos/t3568.scala +pos/t0030.scala +pos/t2635.scala +pos/t7232b +pos/t0017.scala +pos/t812.scala +pos/t2179.scala +pos/t651.scala +pos/spurious-overload.scala +pos/t758.scala +pos/t4760.scala +pos/t1672.scala +pos/mixins.scala +pos/patterns.scala +pos/t1260.scala +pos/t6551.scala +pos/t2060.scala +pos/t6575a.scala +pos/t1318.scala +pos/t4266.scala +pos/t0695 +pos/protected-static +pos/t5738.scala +pos/t1226.scala +pos/t5013 +pos/t6215.scala +pos/t5692b +pos/traits.scala +pos/t2994a.scala +pos/t3371.scala +pos/t613.scala +pos/t6499.scala +pos/xlint1.scala +pos/t1150 +pos/test4a.scala +pos/t2664.scala +pos/t3528.scala +pos/t3174.scala +pos/t6994.scala +pos/t4812.scala +pos/t5777.scala +pos/t5223.scala +pos/t439.scala +pos/t3079.scala +pos/t5829.scala +pos/t0036.scala +pos/scoping2.scala +pos/t4717.scala +pos/t4257.scala +pos/t1210a.scala +pos/getClassType.scala +pos/t5330.scala +pos/t4524.scala +pos/t2945.scala +pos/t6562.scala +pos/t0273.scala +pos/override-object-yes.scala +pos/t7426.scala +pos/t6601 +pos/t3076 +pos/seq-ordering.scala +pos/spec-groups.scala +pos/t296.scala +pos/t5545 +pos/spec-multiplectors.scala +pos/t1789.scala +pos/t2569 +pos/ksbug1.scala +pos/t0599.scala +pos/local-objects.scala +pos/t0081.scala +pos/t5756.scala +pos/t7126.scala +pos/t7716.scala +pos/t2797.scala +pos/t5399.scala +pos/t1101 +pos/t767.scala +pos/contrib467.scala +pos/t7532b +pos/self-type-override.scala +pos/t4853.scala +pos/t839.scala +pos/t5644 +pos/t5853.scala +pos/t5178.scala +pos/unapplyNeedsMemberType.scala +pos/t5390.scala +pos/t6575b.scala +pos/t151.scala +pos/t2665.scala +pos/t5120.scala +pos/erasure-nsquared.scala +pos/arrays3.scala +pos/t3136.scala +pos/inline-access-levels +pos/t3972.scala +pos/t2591.scala +pos/t3486 +pos/variances-flip.scala +pos/annotated-original +pos/typesafecons.scala +pos/stable.scala +pos/t1996.scala +pos/t3037.scala +pos/t1711 +pos/t3374.scala +pos/t0029.scala +pos/t3278.scala +pos/matthias3.scala +pos/t5546.scala +pos/t4020.scala +pos/matthias4.scala +pos/value-class-override-spec.scala +pos/arrays2.scala +pos/t5119.scala +pos/t2613.scala +pos/t4070b.scala +pos/virtpatmat_exist_uncurry.scala +pos/modules1.scala +pos/spec-constr-new.scala +pos/t6335.scala +pos/t675.scala +pos/t0644.scala +pos/t5892.scala +pos/t360.scala +pos/override.scala +pos/t1798.scala +pos/strip-tvars-for-lubbasetypes.scala +pos/hk-infer.scala +pos/t2119.scala +pos/t0231.scala +pos/t1459 +pos/t1381-new.scala +pos/t2610.scala +pos/t2708.scala +pos/t5604b +pos/t3951 +pos/t361.scala +pos/t319.scala +pos/largecasetest.scala +pos/switchUnbox.scala +pos/typetags.scala +pos/java-access-pos +pos/t803.scala +pos/t3898.scala +pos/t5692a +pos/t2421.scala +pos/t1102 +pos/t0654.scala +pos/exhaust_alternatives.scala +pos/t807.scala +pos/t5702-pos-infix-star.scala +pos/t1186 +pos/t1439.scala +pos/t7427.scala +pos/virtpatmat_binding_opt.scala +pos/t247.scala +pos/abstract.scala +pos/gen-traversable-methods.scala +pos/t2795-old.scala +pos/t5639 +pos/t2667.scala +pos/t2405.scala +pos/t1438.scala +pos/SI-7100.scala +pos/t1659.scala +pos/unchecked-a.scala +pos/t3636.scala +pos/t6745.scala +pos/t2809.scala +pos/t7022.scala +pos/t6447.scala +pos/t6367.scala +pos/t5846.scala +pos/lubs.scala +pos/t1987a.scala +pos/spec-arrays.scala +pos/virtpatmat_anonfun_for.scala +pos/listpattern.scala +pos/t5742.scala +pos/test5refine.scala +pos/t5604 +pos/return_thistype.scala +pos/t348plus.scala +pos/t3420.scala +pos/t3440.scala +pos/maxim1.scala +pos/caseClassInMethod.scala +pos/t3833.scala +pos/t6675.scala +pos/t4402 +pos/t5953.scala +pos/t1152 +pos/t0591.scala +pos/t210.scala +pos/t7035.scala +pos/t5769.scala +pos/pmbug.scala +pos/t2331.scala +pos/t5240.scala +pos/t304.scala +pos/annotated-treecopy +pos/t2081.scala +pos/t0904.scala +pos/t7649.scala +pos/t3498-new.scala +pos/contrib701.scala +pos/t6624.scala +pos/t3924.scala +pos/t374.scala +pos/t1642 +pos/t1591_pos.scala +pos/depmet_implicit_oopsla_session_2.scala +pos/t5899.scala +pos/thistype.scala +pos/t4176b.scala +pos/elidable-tparams.scala +pos/lambdalift.scala +pos/nothing_manifest_disambig-old.scala +pos/t372.scala +pos/t5399a.scala +pos/t2782.scala +pos/patmat-extract-tparam.scala +pos/t4114.scala +pos/unapplyVal.scala +pos/t2486.scala +pos/t5877b.scala +pos/t0625.scala +pos/t6358_2.scala +pos/viewtest1.scala +pos/t1237.scala +pos/scala-singleton.scala +pos/t1254 +pos/t5504 +pos/bounds.scala +pos/t3631.scala +pos/t3177.scala +pos/unapplyContexts2.scala +pos/t0438.scala +pos/t1642b.scala +pos/inferbroadtype.scala +pos/t1858.scala +pos/t3731.scala +pos/t6963c.scala +pos/classtag-pos.scala +pos/t6221.scala +pos/t3343.scala +pos/spec-asseenfrom.scala +pos/t604.scala +pos/spec-example1.scala +pos/t0786.scala +pos/annot-inner.scala +pos/t5886.scala +pos/t1056.scala +pos/t294 +pos/spec-Function1.scala +pos/t1836 +pos/spec-private.scala +pos/depmet_implicit_tpbetareduce.scala +pos/exhaust_2.scala +pos/t7532 +pos/t5175.scala +pos/t802.scala +pos/t5809.scala +pos/tcpoly_typesub.scala +pos/t6029.scala +pos/contextbounds-implicits-new.scala +pos/t3480.scala +pos/patterns3.scala +pos/caseaccs.scala +pos/spec-sparsearray-old.scala +pos/patterns1213.scala +pos/spec-traits.scala +pos/t0020.scala +pos/cycle +pos/t5968.scala +pos/typealiases.scala +pos/init.scala +pos/t697.scala +pos/t2693.scala +pos/t2377 +pos/unapplyGeneric.scala +pos/t1385.scala +pos/t3363-old.scala +pos/t1236.scala +pos/t0068.scala +pos/t4052.scala +pos/lambdalift1.scala +pos/z1730.scala +pos/variances-local.scala +pos/virtpatmat_gadt_array.scala +pos/t2421_delitedsl.scala +pos/t5626.scala +pos/t690.scala +pos/t711.scala +pos/t1937 +pos/t3999 +pos/t2305.scala +pos/t2168.scala +pos/t2660.scala +pos/t1693.scala +pos/t2799.scala +pos/t6966.scala +pos/t1001.scala +pos/S5.scala +pos/t0301.scala +pos/t1048.scala +pos/t415.scala +pos/t6386.scala +pos/t2187.scala +pos/hashhash-overloads.scala +pos/t6921.scala +pos/t0227.scala +pos/t6556.scala +pos/t3946 +pos/t1053.scala +pos/t1000.scala +pos/t0586.scala +pos/t7011.scala +pos/t7329.scala +pos/t4975.scala +pos/t1131.scala +pos/t1027.scala +pos/t2913.scala +pos/t3494.scala +pos/t5606.scala +pos/t4716.scala +pos/tcpoly_gm.scala +pos/t4859.scala +pos/t514.scala +pos/lexical.scala +pos/t2624.scala +pos/t4036.scala +pos/t2741 +pos/t703.scala +pos/five-dot-f.scala +pos/t805.scala +pos/strings.scala +pos/t2433 +pos/t6925.scala +pos/t1085.scala +pos/t7461 +pos/t1942 +pos/spec-lists.scala +pos/t3349 +pos/tcpoly_infer_ticket474.scala +pos/t1614 +pos/virtpatmat_reach_const.scala +pos/t2194.scala +pos/t6976 +pos/t1560.scala +pos/t6891.scala +pos/t3883.scala +pos/infersingle.scala +pos/gui.scala +pos/t1164.scala +pos/t3175-pos.scala +pos/t4336.scala +pos/annotations2.scala +pos/proj-rec-test.scala +pos/t2973.scala +pos/t1123.scala +pos/t6205.scala +pos/t5727.scala +pos/t6537.scala +pos/t6712.scala +pos/t3866.scala +pos/t4831.scala +pos/selftails.scala +pos/t397.scala +pos/spec-vector.scala +pos/t7233b.scala +pos/t1391.scala +pos/spec.scala +pos/t3106.scala +pos/contextbounds-implicits-old.scala +pos/packageobjs.scala +pos/michel3.scala +pos/t628.scala +pos/collections.scala +pos/tcpoly_boundedmonad.scala +pos/t7668.scala +pos/t0032.scala +pos/t0069.scala +pos/t4345.scala +pos/t3521 +pos/t3071.scala +pos/tcpoly_infer_easy.scala +pos/t289.scala +pos/t4365 +pos/rangepos-anonapply.scala +pos/t5033.scala +pos/lambda.scala +pos/S8.scala +pos/t6014.scala +pos/t1785.scala +pos/t6034.scala +pos/t7433.scala +pos/imp2-pos.scala +pos/t0504.scala +pos/t1272.scala +pos/t0612 +pos/value-class-override-no-spec.scala +pos/overloaded-unapply.scala +pos/t5859.scala +pos/chang +pos/localmodules.scala +pos/t4237.scala +pos/rangepos-patmat.scala +pos/t1974.scala +pos/t0054.scala +pos/michel2.scala +pos/t0770.scala +pos/t1146.scala +pos/t2441pos.scala +pos/t5099.scala +pos/tcpoly_seq_typealias.scala +pos/t946.scala +pos/tcpoly_infer_ticket1864.scala +pos/t4737 +pos/t7377b.scala +pos/t616.scala +pos/t201.scala +pos/t6355pos.scala +pos/escapes2.scala +pos/t1675.scala +pos/t3890.scala +pos/t6040.scala +pos/spec-tailcall.scala +pos/existentials.scala +pos/t5317.scala +pos/t7782b.scala +pos/t4758.scala +pos/t7296.scala +pos/t6896.scala +pos/cls1.scala +pos/t402.scala +pos/gosh.scala +pos/t2619.scala +pos/javaConversions-2.10-regression.scala +pos/t759.scala +pos/t5259.scala +pos/t5130.scala +pos/t5156.scala +pos/t0905.scala +pos/package-implicit +pos/t2669.scala +pos/trait-parents.scala +pos/virtpatmat_exhaust.scala +pos/patterns1.scala +pos/t1231 +pos/t1751 +pos/t7233.scala +pos/t6022.scala +pos/tcpoly_checkkinds_mix.scala +pos/depmet_implicit_norm_ret.scala +pos/package-case.scala +pos/philippe4.scala +pos/michel6.scala +pos/t4188.scala +pos/t3936 +pos/t1280.scala +pos/t6722.scala +pos/t796.scala +pos/t5542.scala +pos/t3927.scala +pos/t2293.scala +pos/t3800.scala +pos/t7285a.scala +pos/t927.scala +pos/t4494.scala +pos/t3864 +pos/ilya2 +pos/t2940 +pos/S1.scala +pos/tcpoly_wildcards.scala +pos/tryexpr.scala +pos/t6089b.scala +pos/depmet_implicit_oopsla_zipwith.scala +pos/t245.scala +pos/t6146.scala +pos/t1782 +pos/t851.scala +pos/spec-thistype.scala +pos/tcpoly_poly.scala +pos/t6815_import.scala +pos/t4649.scala +pos/t0453.scala +pos/t5020.scala +pos/ilya +pos/t2435.scala +pos/t1279a.scala +pos/t1957.scala +pos/gadts2.scala +pos/t3567 +pos/Z.scala +pos/t1203b +pos/nested2.scala +pos/t1896 +pos/viewtest2.scala +pos/t5541.scala +pos/existentials-harmful.scala +pos/t4063.scala +pos/t6485a +pos/t1208.scala +pos/t5041.scala +pos/unapplyComplex.scala +pos/t3384.scala +pos/t4112.scala +pos/t788.scala +pos/hklub0.scala +pos/t757.scala +pos/t1197 +pos/t359.scala +pos/t5667.scala +pos/t1107a.scala +pos/virtpatmat_castbinder.scala +pos/t267.scala +pos/t3419 +pos/t3861.scala +pos/t6797.scala +pos/spec-localdefs.scala +pos/t3404 +pos/t4457_1.scala +pos/matthias5.scala +pos/spec-polymeth.scala +pos/kinds.scala +pos/t2310.scala +pos/t6552.scala +pos/valdefs.scala +pos/hkarray.scala +pos/homonym.scala +pos/t1235 +pos/t3429 +pos/t0053.scala +pos/depmet_implicit_chaining_zw.scala +pos/virtpatmat_partialfun_nsdnho.scala +pos/t6664.scala +pos/ticket2251.scala +pos/t3495.scala +pos/super +pos/t121.scala +pos/javaConversions-2.10-ambiguity.scala +pos/t1803.scala +pos/t5877.scala +pos/t0085.scala +pos/t3582.scala +pos/t2939.scala +pos/t1422_pos.scala +pos/manifest1-new.scala +pos/t7505.scala +pos/t5720-ownerous.scala +pos/misc-unapply_pos.scala +pos/tcpoly_variance_pos.scala +pos/t5127.scala +pos/t6123-explaintypes-implicits.scala +pos/t2764 +pos/presuperContext.scala +pos/spec-simple.scala +pos/t3120 +pos/tcpoly_infer_ticket716.scala +pos/tcpoly_bounds1.scala +pos/t7369.scala +pos/imports-pos.scala +pos/t5654.scala +pos/t0123.scala +pos/raw-map +pos/t5330b.scala +pos/t6485b +pos/t6072.scala +pos/t5692c.scala +pos/tcpoly_param_scoping.scala +pos/t6204-b.scala +pos/attachments-typed-another-ident +pos/t5359.scala +pos/ticket2197.scala +pos/t720.scala +pos/t2130-2.scala +pos/t2260.scala +pos/t0304.scala +pos/t464.scala +pos/spec-maps.scala +pos/annotDepMethType.scala +pos/t6117.scala +pos/t911.scala +pos/t757a.scala +pos/t2504.scala +pos/t1381-old.scala +pos/t1232 +pos/needstypeearly.scala +pos/moduletrans.scala +pos/t4957.scala +pos/kinzer.scala +pos/t318.scala +pos/widen-existential.scala +pos/t0095.scala +pos/t566.scala +pos/tcpoly_overloaded.scala +pos/t7516 +pos/t7232 +pos/t698.scala +pos/t0002.scala +pos/t0288 +pos/t2994b.scala +pos/cls.scala +pos/t3622 +pos/t3671.scala +pos/tcpoly_subst.scala +pos/t5703 +pos/depmet_implicit_oopsla_session_simpler.scala +pos/t5022.scala +pos/builders.scala +pos/spec-foo.scala +pos/t756.scala +pos/t1569.scala +pos/implicit-unwrap-tc.scala +pos/t3688.scala +pos/t5198.scala +pos/t432.scala +pos/t6022b.scala +pos/channels.scala +pos/t1075.scala +pos/null.scala +pos/t1840 +pos/t6479.scala +pos/t6311.scala +pos/t0039.scala +pos/t1119.scala +pos/t573.scala +pos/t1136.scala +pos/t3938 +pos/spec-sealed.scala +pos/tcpoly_return_overriding.scala +pos/t3582b.scala +pos/t229.scala +pos/t3498-old.scala +pos/t531.scala +pos/t4545.scala +pos/t6651.scala +pos/t2133.scala +pos/tinondefcons.scala +pos/t6358.scala +pos/t7690.scala +pos/t5779-numeq-warn.scala +pos/list-extractor.scala +pos/t892.scala +pos/t2127.scala +pos/t7180.scala +pos/nullary_poly.scala +pos/virtpatmat_exist3.scala +pos/t1176 +pos/spec-funs.scala +pos/specialize10.scala +pos/t6514.scala +pos/exhaustive_heuristics.scala +pos/t0066.scala +pos/t460.scala +pos/t2130-1.scala +pos/t124.scala +pos/annotations.scala +pos/pat_gilles.scala +pos/array-interfaces.scala +pos/t6210.scala +pos/t3792.scala +pos/implicits-old.scala +pos/t389.scala +pos/t115.scala +pos/virtpatmat_exhaust_unchecked.scala +pos/scoping3.scala +pos/t6033.scala +pos/depmet_implicit_oopsla_session.scala +pos/t602.scala +pos/test5.scala +pos/t611.scala +pos/t5932.scala +pos/t4910.scala +pos/unapplySeq.scala +pos/t344.scala +pos/t3363-new.scala +pos/t4018.scala +pos/t4553.scala +pos/t5082.scala +pos/t3869.scala +pos/t3836.scala +pos/tcpoly_typeapp.scala +pos/t1409 +pos/nonlocal-unchecked.scala +pos/t0082.scala +pos/z1720.scala +pos/t7232c +pos/t2018.scala +pos/t3943 +pos/t2187-2.scala +pos/unicode-decode.scala +pos/t4757 +pos/t0710.scala +pos/t0305.scala +pos/t160.scala +pos/t7591 +pos/simplelists.scala +pos/List1.scala +pos/t516.scala +pos/t6648.scala +pos/t5165 +pos/t0055.scala +pos/t4744 +pos/t7377 +pos/t5726.scala +pos/t0091.scala +pos/t6595.scala +pos/compile.scala +pos/depmet_1_pos.scala +pos/t7364 +pos/philippe3.scala +pos/spec-doubledef-old.scala +pos/t4651.scala +pos/tcpoly_infer_implicit_tuple_wrapper.scala +pos/t6274.scala +pos/tcpoly_infer_explicit_tuple_wrapper.scala +pos/ticket2201.scala +pos/spec-fields-new.scala +pos/optmatch.scala +pos/t7517.scala +pos/t3560.scala +pos/t0165.scala +pos/t0872.scala +pos/t522.scala +pos/t2234.scala +pos/t5031_2.scala +pos/tcpoly_method.scala +pos/t6482.scala +pos/pos-bug1241.scala +pos/implicits-new.scala +pos/t2484.scala +pos/t2425.scala +pos/t1049.scala +pos/michel4.scala +pos/t5958.scala +pos/virtpatmat_instof_valuetype.scala +pos/spec-t6286.scala +pos/t873.scala +pos/t3137.scala +pos/Transactions.scala +pos/t0064.scala +pos/t7486-named.scala +pos/t5444.scala +pos/simple-exceptions.scala +pos/t1006.scala +pos/t7200b.scala +pos/t3777.scala +pos/t4840.scala +pos/t211.scala +pos/nullary.scala +pos/michel1.scala +pos/t5031_3 +pos/typealias_dubious.scala +pos/spec-doubledef-new.scala +pos/philippe1.scala +pos/thistypes.scala +pos/t3570.scala +pos/t6516.scala +pos/context.scala +pos/t3808.scala +pos/philippe2.scala +pos/constfold.scala +pos/t1292.scala +pos/t1147.scala +pos/t404.scala +pos/t4430.scala +pos/A.scala +pos/spec-partially.scala +pos/t5796.scala +pos/t2409 +pos/t284-pos.scala +pos/t5313.scala +pos/t2464 +pos/t1591b.scala +pos/hk-match +pos/t595.scala +pos/t6846.scala +pos/t6162-inheritance.scala +pos/relax_implicit_divergence.scala +pos/patterns2.scala +pos/t4692.scala +pos/t3837.scala +pos/t661.scala +pos/t2810.scala +pos/depexists.scala +pos/virtpatmat_exist4.scala +pos/t5245.scala +pos/t7190.scala +pos/isApplicableSafe.scala +pos/t6204-a.scala +pos/t0076.scala +pos/t1756.scala +pos/t1745 +pos/t6091.scala +pos/t0154.scala +pos/t530.scala +pos/t2094.scala +pos/t1034.scala +pos/t6084.scala +pos/t2454.scala +pos/t2956 +pos/tcpoly_ticket2096.scala +pos/attachments-typed-ident +pos/polymorphic-case-class.scala +pos/t252.scala +pos/spec-constr-old.scala +pos/t2421c.scala +pos/t122.scala +pos/t6574.scala +pos/t3859.scala +pos/spec-params-old.scala +pos/t1196 +pos/t4593.scala +pos/t596.scala +pos/t615.scala +pos/t7689.scala +pos/t3960.scala +pos/t3986.scala +pos/exbound.scala +pos/t2545.scala +pos/t1722 +pos/t159.scala +pos/t3272.scala +pos/t6301.scala +pos/t2794.scala +pos/t3048.scala +pos/t4970.scala +pos/t607.scala +pos/FPTest.scala +pos/test1.scala +pos/t4176.scala +pos/t112606A.scala +pos/t2183.scala +pos/t430-feb09.scala +pos/t6275.scala +pos/t1832.scala +pos/t8965.scala +pos/t7596b +pos/t8900.scala +pos/t9008.scala +pos/t7704.scala +pos/t7459c.scala +pos/sammy_override.scala +pos/t8828.scala +pos/t8868c +pos/t7459d.scala +pos/t8267.scala +pos/t8844.scala +pos/t8868a +pos/t8894.scala +pos/t7459a.scala +pos/t7596c +pos/t8498.scala +pos/t8868b +pos/t5413.scala +pos/t8781 +pos/t8934a +pos/t8310.scala +pos/t3439.scala +pos/t6582_exhaust_big.scala +pos/t8954 +pos/t5217.scala +pos/t7459b.scala +pos/t9018.scala +pos/sammy_exist.scala +pos/t8893.scala +pos/t7596 +pos/t8793.scala +pos/sammy_overload.scala +pos/t6051.scala +pos/t7683-stop-after-parser +pos/t7750.scala +pos/t5454.scala +pos/t8962.scala +pos/t8947 +pos/t8719 +pos/t8410.scala +pos/patmat-suppress.scala +pos/t8999.scala +pos/t8743.scala +pos/t9157.scala +pos/t8801.scala +pos/t9086.scala +pos/t9050.scala +pos/t9135.scala +pos/t9116.scala +pos/t5154.scala +pos/t3368.scala +pos/t9321.scala +pos/t9285.scala +pos/t8861.scala +pos/t9020.scala +pos/jesper.scala +pos/t9356 +pos/virtpatmat_exhaust_big.scala +pos/t9239 +pos/t9111-inliner-workaround + +neg/volatile_no_override.scala +neg/t800.scala +neg/t5426.scala +neg/t2462a.scala +neg/t2641.scala +neg/classtags_dont_use_typetags.scala +neg/t5031 +neg/t2275b.scala +neg/macro-qmarkqmarkqmark.scala +neg/t4879.scala +neg/t5956.scala +neg/t4196.scala +neg/reify_ann2b.scala +neg/t6666b.scala +neg/warn-unused-privates.scala +neg/t6928.scala +neg/t6337.scala +neg/sealed-java-enums.scala +neg/t563.scala +neg/t900.scala +neg/deadline-inf-illegal.scala +neg/t766.scala +neg/t5429.scala +neg/overloaded-implicit.scala +neg/t875.scala +neg/abstract-class-error +neg/unchecked2.scala +neg/predef-masking.scala +neg/viewtest.scala +neg/macro-noexpand +neg/varargs.scala +neg/t963b.scala +neg/t909.scala +neg/sensitive2.scala +neg/t5390b.scala +neg/abstraction-from-volatile-type-error.scala +neg/macro-exception +neg/t4431.scala +neg/t5689.scala +neg/valueclasses.scala +neg/overload.scala +neg/t0204.scala +neg/t908.scala +neg/t750 +neg/patmatexhaust.scala +neg/macro-invalidusage-badtargs +neg/t1168.scala +neg/t5761.scala +neg/t0503.scala +neg/t7235.scala +neg/t1215.scala +neg/primitive-sigs-1 +neg/t5578.scala +neg/names-defaults-neg-warn.scala +neg/t6436b.scala +neg/t3098 +neg/t910.scala +neg/parstar.scala +neg/t4568.scala +neg/newpat_unreachable.scala +neg/t1181.scala +neg/t5903c +neg/t7294.scala +neg/t4091.scala +neg/t5452-old.scala +neg/t5696.scala +neg/t0209.scala +neg/t2910.scala +neg/t7388.scala +neg/noMember2.scala +neg/no-predef.scala +neg/t6952.scala +neg/t1909b.scala +neg/abstract-report2.scala +neg/t5318.scala +neg/t6074.scala +neg/t7171.scala +neg/abstract-vars.scala +neg/unchecked-impossible.scala +neg/variances-refinement.scala +neg/t3453.scala +neg/t5189.scala +neg/t4302.scala +neg/xmltruncated7.scala +neg/t8217-local-alias-requires-rhs.scala +neg/t7602.scala +neg/t8869.scala +neg/t9008.scala +neg/sammy_error_exist_no_crash.scala +neg/t2866.scala +neg/t8597b.scala +neg/t5691.scala +neg/t8534b.scala +neg/t5091.scala +neg/literals.scala +neg/t8534.scala +neg/t8890.scala +neg/t9008b.scala +neg/t8731.scala +neg/t8291.scala +neg/t8597.scala +neg/t5639b +neg/t6582_exhaust_big.scala +neg/t8841.scala +neg/t9041.scala +neg/t9093.scala +neg/t7623.scala +neg/t9231.scala +neg/t9286b.scala +neg/t9273.scala +neg/t9127.scala +neg/t9286c.scala +neg/t9286a.scala +neg/virtpatmat_exhaust_big.scala +neg/inlineMaxSize.scala + +run/t7249.scala +run/t3563.scala +run/t6111.scala +run/classtags_multi.scala +run/t5201.scala +run/checked.scala +run/valueclasses-classtag-basic.scala +run/t7171.scala +run/t5053.scala +run/t4535.scala +run/t5923d +run/t7291.scala +run/partialfun.scala +run/macro-term-declared-in-package-object +run/mapValues.scala +run/gadts.scala +run/t2386-new.scala +run/virtpatmat_stringinterp.scala +run/t657.scala +run/t0017.scala +run/t5713 +run/t576.scala +run/t3580.scala +run/virtpatmat_partial.scala +run/t6646.scala +run/mixins.scala +run/t1672.scala +run/macro-expand-implicit-macro-has-implicit +run/tuple-match.scala +run/t7039.scala +run/virtpatmat_opt_sharing.scala +run/virtpatmat_casting.scala +run/t2176.scala +run/macro-impl-relaxed +run/intmap.scala +run/t751.scala +run/t1591.scala +run/macro-typecheck-implicitsdisabled +run/t6911.scala +run/t5604.scala +run/macro-term-declared-in-default-param +run/collection-stacks.scala +run/multi-array.scala +run/t4560b.scala +run/buffer-slice.scala +run/t5629.scala +run/t6690.scala +run/matchonstream.scala +run/t3603.scala +run/lazy-exprs.scala +run/macro-quasiquotes +run/Course-2002-13.scala +run/t6337a.scala +run/exoticnames.scala +run/t0936.scala +run/runtime-richChar.scala +run/t6272.scala +run/t7215.scala +run/t1939.scala +run/ReverseSeqView.scala +run/lazy-leaks.scala +run/t0048.scala +run/t3994.scala +run/t2241.scala +run/t627.scala +run/t5966.scala +run/getClassTest-valueClass.scala +run/t3619.scala +run/t1300.scala +run/t2177.scala +run/t3760.scala +run/t1829.scala +run/macro-expand-implicit-macro-is-view +run/t889.scala +run/QueueTest.scala +run/t4537 +run/t3699.scala +run/t1192.scala +run/macro-expand-tparams-bounds +run/macro-expand-nullary-generic +run/t1434.scala +run/t6443-varargs.scala +run/macro-term-declared-in-trait +run/t4080.scala +run/matcharraytail.scala +run/infiniteloop.scala +run/t5733.scala +run/virtpatmat_nested_lists.scala +run/t5158.scala +run/t6695.scala +run/t6070.scala +run/t4558.scala +run/exc2.scala +run/patmat-behavior-2.scala +run/overloads.scala +run/t6957.scala +run/transform.scala +run/t5500.scala +run/t6663.scala +run/castsingleton.scala +run/t4147.scala +run/virtpatmat_staging.scala +run/t4565_1.scala +run/t5588.scala +run/run-bug4840.scala +run/t3496.scala +run/t5867.scala +run/search.scala +run/t3112.scala +run/hashsetremove.scala +run/t6443.scala +run/macro-expand-tparams-prefix +run/contrib674.scala +run/t3508.scala +run/t4300.scala +run/virtpatmat_typed.scala +run/macro-term-declared-in-class-object +run/map_test.scala +run/t5040.scala +run/t4827b.scala +run/lift-and-unlift.scala +run/t6574b.scala +run/t7240 +run/t3984.scala +run/virtpatmat_tailcalls_verifyerror.scala +run/macro-term-declared-in-class-class +run/emptypf.scala +run/t6104.scala +run/t2818.scala +run/t3761-overload-byname.scala +run/t2526.scala +run/phantomValueClass.scala +run/t3126.scala +run/arybufgrow.scala +run/t3980.scala +run/t7375b +run/t6077_patmat_cse_irrefutable.scala +run/classmanifests_new_core.scala +run/t3395.scala +run/name-based-patmat.scala +run/inliner-infer.scala +run/t5171.scala +run/t3726.scala +run/null-hash.scala +run/t4027.scala +run/t2544.scala +run/patmatnew.scala +run/t5923b +run/t7242.scala +run/classtags_core.scala +run/streamWithFilter.scala +run/t3038b.scala +run/macro-expand-varargs-explicit-over-nonvarargs-good +run/macro-divergence-spurious +run/macro-duplicate +run/t2958.scala +run/patch-boundary.scala +run/t2333.scala +run/lazy-override-run.scala +run/macro-quasiinvalidbody-c +run/t5037.scala +run/takeAndDrop.scala +run/t6126.scala +run/t0883.scala +run/t7617a +run/t4171.scala +run/empty-array.scala +run/t7198.scala +run/t493.scala +run/genericValueClass.scala +run/t0677-old.scala +run/t1373.scala +run/t4461.scala +run/t6011b.scala +run/t7584.scala +run/t3935.scala +run/t6928-run.scala +run/t744.scala +run/t3241.scala +run/blame_eye_triple_eee-double.scala +run/t3829.scala +run/t5577.scala +run/t5914.scala +run/t601.scala +run/t5610.scala +run/macro-basic-mamd-mi +run/t6150.scala +run/stringbuilder.scala +run/t7290.scala +run/t6888.scala +run/t6327.scala +run/virtpatmat_unapplyseq.scala +run/t4656.scala +run/macro-term-declared-in-method +run/macro-expand-implicit-macro-is-implicit +run/blame_eye_triple_eee-float.scala +run/t4482.scala +run/t5488.scala +run/matchemptyarray.scala +run/t3714.scala +run/richWrapperEquals.scala +run/t5328.scala +run/stream_flatmap_odds.scala +run/implicitclasses.scala +run/t6394b +run/complicatedmatch.scala +run/valueclasses-classmanifest-basic.scala +run/unreachable.scala +run/caseclasses.scala +run/withIndex.scala +run/exc1.scala +run/amp.scala +run/t1423.scala +run/t594.scala +run/t6353.scala +run/byname.scala +run/vector1.scala +run/t5879.scala +run/t1048.scala +run/t5080.scala +run/t4190.scala +run/caseClassEquality.scala +run/macro-enclosures +run/collections-toSelf.scala +run/implicits.scala +run/finalvar.scala +run/lazy-locals.scala +run/t7231.scala +run/t0508.scala +run/t6628.scala +run/t6406-regextract.scala +run/t0911.scala +run/t4013c.scala +run/t3502.scala +run/t5648.scala +run/retclosure.scala +run/t2857.scala +run/t4859.scala +run/t5162.scala +run/t3038.scala +run/classof.scala +run/t4062.scala +run/unapplyArray.scala +run/t4297.scala +run/t5923a +run/t1537.scala +run/boolexprs.scala +run/valueclasses-classtag-generic.scala +run/macro-term-declared-in-anonymous +run/tcpoly_monads.scala +run/t5407.scala +run/scan.scala +run/forvaleq.scala +run/null-and-intersect.scala +run/t7047 +run/t0607.scala +run/sequenceComparisons.scala +run/t4396.scala +run/macro-undetparams-consfromsls +run/t2029.scala +run/t1220.scala +run/option-fold.scala +run/t5284c.scala +run/macro-auto-duplicate +run/t3529.scala +run/t4697.scala +run/t2251.scala +run/t5300.scala +run/virtpatmat_valdef.scala +run/t2147.scala +run/virtpatmat_extends_product.scala +run/list_map.scala +run/t1333.scala +run/matchbytes.scala +run/valueclasses-classmanifest-existential.scala +run/records.scala +run/t3088.scala +run/macro-def-path-dependent +run/t6443-by-name.scala +run/t1044.scala +run/delay-good.scala +run/case-class-23.scala +run/weakconform.scala +run/patmat-bind-typed.scala +run/t4835.scala +run/t3097.scala +run/t405.scala +run/existentials.scala +run/t2876.scala +run/t4809.scala +run/t1427.scala +run/t6135.scala +run/t3575.scala +run/t5688.scala +run/t6900.scala +run/macro-expand-unapply-a +run/t6677b.scala +run/t7375a.scala +run/t7300.scala +run/typed-annotated +run/elidable-noflags.scala +run/t0042.scala +run/t3050.scala +run/t4536.scala +run/NestedClasses.scala +run/t3877.scala +run/seqlike-kmp.scala +run/t5907.scala +run/t266.scala +run/missingparams.scala +run/t2255.scala +run/t3488.scala +run/t3950.scala +run/typealias_overriding.scala +run/constant-optimization.scala +run/t7507.scala +run/t6090.scala +run/t4582.scala +run/macro-term-declared-in-class +run/macro-typecheck-macrosdisabled2 +run/t3425.scala +run/t4935.scala +run/t3326.scala +run/boolord.scala +run/t1141.scala +run/virtpatmat_unapply.scala +run/t5971.scala +run/t3651.scala +run/macro-sip19-revised +run/pure-args-byname-noinline.scala +run/preinits.scala +run/t5532.scala +run/concat-two-strings.scala +run/t3269.scala +run/macro-impl-default-params +run/t2162.scala +run/matchonseq.scala +run/t5428.scala +run/macro-expand-overload +run/t4660.scala +run/enrich-gentraversable.scala +run/macro-expand-override +run/t4054.scala +run/t4753.scala +run/macro-typecheck-macrosdisabled +run/t2308a.scala +run/duplicate-meth.scala +run/interop_classtags_are_classmanifests.scala +run/t3232.scala +run/t2075.scala +run/virtpatmat_partial_backquoted.scala +run/try-2.scala +run/macro-openmacros +run/macro-undetparams-macroitself +run/t6318_derived.scala +run/deprecate-early-type-defs.scala +run/dead-code-elimination.scala +run/t4827.scala +run/Course-2002-07.scala +run/slice-strings.scala +run/t6292.scala +run/t6206.scala +run/t1042.scala +run/t1718.scala +run/t2074_2.scala +run/arraycopy.scala +run/indexedSeq.scala +run/macro-term-declared-in-implicit-class +run/t3511.scala +run/t6290.scala +run/distinct.scala +run/virtpatmat_alts.scala +run/valueclasses-pavlov.scala +run/exceptions.scala +run/t1368.scala +run/t5856.scala +run/t6968.scala +run/names-defaults.scala +run/macro-expand-tparams-implicit +run/t5881.scala +run/t3540.scala +run/virtpatmat_try.scala +run/t7181.scala +run/value-class-extractor.scala +run/value-class-extractor-2.scala +run/t3150.scala +run/exc.scala +run/delay-bad.scala +run/infix.scala +run/t1309.scala +run/t6370.scala +run/t6725-2.scala +run/macro-impl-tparam-typetag-is-optional +run/macro-term-declared-in-block +run/matchnull.scala +run/t2127.scala +run/t7325.scala +run/groupby.scala +run/t3932.scala +run/t4871.scala +run/longmap.scala +run/t1524.scala +run/t6187b.scala +run/kmpSliceSearch.scala +run/t7088.scala +run/t5804.scala +run/stringbuilder-drop.scala +run/t5753_1 +run/t9223.scala +run/function-null-unbox.scala +run/t9223b.scala +run/disable-assertions.scala +run/valueClassSelfType.scala +run/indylambda-boxing +run/t9219.scala + +pos/cyclics-pos.scala +pos/cfcrash.scala +pos/tcpoly_higherorder_bound_method.scala +pos/t5084.scala +pos/macro-qmarkqmarkqmark.scala +pos/t7785.scala +pos/nested.scala +pos/t3152.scala +pos/t5031 +pos/t6925b.scala +pos/t1107b +pos/t5012.scala +pos/virtpatmat_obj_in_case.scala +pos/t4938.scala +pos/t3856.scala +pos/spec-cyclic.scala +pos/aliases.scala +pos/typerep_pos.scala +pos/t119.scala +pos/t1050.scala +pos/t3670.scala +pos/t6145.scala +pos/t7315.scala +pos/t5930.scala +pos/t789.scala +pos/t5071.scala +pos/t4731.scala +pos/t4547.scala +pos/t2038.scala +pos/testCoercionThis.scala +pos/t2444.scala +pos/t5744 +pos/t780.scala +pos/t1722-A.scala +pos/virtpatmat_exist1.scala +pos/t6225.scala +pos/t762.scala +pos/t0204.scala +pos/rebind.scala +pos/spec-short.scala +pos/comp-rec-test.scala +pos/lub-dealias-widen.scala +pos/t1168.scala +pos/modules.scala +pos/t4220.scala +pos/t4070.scala +pos/t175.scala +pos/t2500.scala +pos/t5029.scala +pos/itay.scala +pos/t4202.scala +pos/t1987b +pos/t3534.scala +pos/infer2-pos.scala +pos/spec-sparsearray-new.scala +pos/t7091.scala +pos/ticket0137.scala +pos/collectGenericCC.scala +pos/t640.scala +pos/t4305.scala +pos/extractor-types.scala +pos/t3880.scala +pos/spec-annotations.scala +pos/t3577.scala +pos/compile1.scala +pos/spec-t3497.scala +pos/hkrange.scala +pos/t287.scala +pos/t6008.scala +pos/t4432.scala +pos/CustomGlobal.scala +pos/patmat.scala +pos/t2413 +pos/t2910.scala +pos/t592.scala +pos/t6245 +pos/infer.scala +pos/t7228.scala +pos/compound.scala +pos/attributes.scala +pos/t6771.scala +pos/t1090.scala +pos/t684.scala +pos/t577.scala +pos/t4273.scala +pos/t6278-synth-def.scala +pos/t6184.scala +neg/t0214.scala +neg/t4842.scala +neg/t6214.scala +neg/reify_nested_inner_refers_to_local.scala +neg/t576.scala +neg/t5969.scala +neg/tcpoly_variance.scala +neg/t7509.scala +neg/mixins.scala +neg/parent-inherited-twice-error.scala +neg/macro-abort +neg/constructor-init-order.scala +neg/t6042.scala +neg/t0590.scala +neg/t4221.scala +neg/t6263.scala +neg/t783.scala +neg/t5554.scala +neg/macro-invalidsig-params-badtype +neg/multi-array.scala +neg/raw-types-stubs +neg/spec-overrides.scala +neg/t836.scala +neg/t7289_status_quo.scala +neg/t5675.scala +neg/macro-quasiquotes +neg/t6667.scala +neg/t6597.scala +neg/t6264.scala +neg/t0345.scala +neg/t7294b.scala +neg/t5340.scala +neg/t2144.scala +neg/t1010.scala +neg/t1838.scala +neg/t5189b.scala +neg/reify_metalevel_breach_-1_refers_to_1.scala +neg/t6601 +neg/wellkinded_wrongarity.scala +neg/t3909.scala +neg/t876.scala +neg/t5390.scala +neg/unit2anyref.scala +neg/t0351.scala +neg/t5120.scala +neg/t1038.scala +neg/t5878.scala +neg/qualifying-class-error-2.scala +neg/t3816.scala +neg/tailrec.scala +neg/volatile.scala +neg/t944.scala +neg/t1705.scala +neg/t3977.scala +neg/t5553_2.scala +neg/t5318c.scala +neg/overload-msg.scala +neg/t5440.scala +neg/t6335.scala +neg/compile-time-only-b.scala +neg/t501.scala +neg/override.scala +neg/t663.scala +neg/t5892.scala +neg/t1980.scala +neg/macro-false-deprecation-warning +neg/t585.scala +neg/t3776.scala +neg/interop_classtags_arenot_manifests.scala +neg/t4044.scala +neg/macro-invalidusage-nontypeable +neg/t500.scala +neg/t4877.scala +neg/t5357.scala +neg/interop_abstypetags_arenot_manifests.scala +neg/t4460a.scala +neg/t5318b.scala +neg/t4440.scala +neg/t6663.scala +neg/t6357.scala +neg/gadts1.scala +neg/cyclics.scala +neg/t5060.scala +neg/scopes.scala +run/t4013.scala +run/macro-expand-tparams-explicit +run/tuples.scala +run/t5753_2 +run/t0528.scala +run/t5105.scala +run/t7341.scala +run/t3670.scala +run/t2594_tcpoly.scala +run/t3895.scala +run/t0668.scala +run/slices.scala +run/t6666a.scala +run/valueclasses-classmanifest-generic.scala +run/t2316_run.scala +run/t3004.scala +run/viewtest.scala +run/t6481.scala +run/t0005.scala +run/t4766.scala +run/t5500b.scala +run/t7407b.scala +run/backreferences.scala +run/arrayview.scala +run/t629.scala +run/t5903c +run/unittest_collection.scala +run/spec-nlreturn.scala +run/macro-term-declared-in-object-object +run/triple-quoted-expr.scala +run/t5937.scala +run/t6011c.scala +run/macro-expand-implicit-argument +run/try.scala +run/t1987b +run/t6089.scala +run/macro-range +run/t2524.scala +run/t4770.scala +run/virtpatmat_unapplyprod.scala +run/t1535.scala +run/ctor-order.scala +pos/t5210.scala +pos/t5384.scala +pos/rangepos.scala +pos/t443.scala +pos/t1480.scala +pos/t116.scala +pos/seqtest2.scala +pos/scoping1.scala +pos/t4269.scala +pos/lookupswitch.scala +pos/t3642 +pos/t5706.scala +pos/SI-5788.scala +pos/t7264 +pos/t0031.scala +pos/macro-deprecate-dont-touch-backquotedidents.scala +pos/t6815.scala +pos/test4refine.scala +pos/michel5.scala +pos/t0851.scala +pos/t1185.scala +pos/sudoku.scala +pos/t7520.scala +pos/t6208.scala +pos/t3411.scala +pos/t295.scala +pos/S3.scala +pos/t0674.scala +pos/t6664b.scala +pos/variances_pos.scala +pos/liftcode_polymorphic.scala +pos/t3174b.scala +pos/t7232d +pos/t578.scala +pos/implicit-infix-ops.scala +pos/t4363.scala +pos/t532.scala +pos/exponential-spec.scala +pos/t599.scala +pos/t5862.scala +pos/t4603 +pos/t3676.scala +pos/t1357.scala +pos/native-warning.scala +pos/t1230 +pos/t6028 +pos/t4275.scala +pos/overloaded_extractor_and_regular_def.scala +pos/t4205 +pos/matthias1.scala +pos/testcast.scala +pos/generic-sigs.scala +pos/t0093.scala +pos/specializes-sym-crash.scala +pos/t0061.scala +pos/t2429.scala +pos/t694.scala +pos/javaReadsSigs +pos/t2023.scala +pos/t704.scala +pos/t2208_pos.scala +pos/t5137.scala +pos/t2683.scala +pos/t0049.scala +pos/t1029 +pos/t4243.scala +pos/typerep-stephane.scala +pos/t177.scala +pos/t5967.scala +pos/t430.scala +pos/virtpatmat_infer_single_1.scala +pos/pat_iuli.scala +pos/t1071.scala +pos/t7226.scala +pos/t1843.scala +pos/t419.scala +pos/t7364b +pos/t1159.scala +pos/t5305.scala +pos/t7694.scala +pos/t6047.scala +pos/t3578.scala +pos/t2082.scala +pos/setter-not-implicit.scala +pos/t1133.scala +pos/t3862.scala +pos/t942 +pos/nothing_manifest_disambig-new.scala +pos/iterator-traversable-mix.scala +pos/eta.scala +pos/test4.scala +pos/t2691.scala +pos/t4502.scala +pos/t7183.scala +pos/protected-t1010.scala +pos/X.scala +pos/virtpatmat_exist2.scala +pos/t4911.scala +pos/t3477.scala +pos/t4173.scala +pos/t7782.scala +pos/t2399.scala +pos/virtpatmat_alts_subst.scala +pos/propagate.scala +pos/t2421b_pos.scala +pos/t183.scala +pos/t7033.scala +pos/t3612.scala +pos/t5330c.scala +pos/t3020.scala +pos/t4869.scala +pos/t3373.scala +pos/spec-params-new.scala +pos/t3672.scala +pos/t4501.scala +pos/t1565.scala +pos/t3774.scala +pos/t6942 +pos/t845.scala +pos/t3240.scala + +neg/t3275.scala +neg/t421.scala +neg/t5702-neg-bad-brace.scala +neg/t3663 +neg/badtok-1.scala +neg/t677.scala +neg/t7756b.scala +neg/t6534.scala +neg/t6276.scala +neg/t5762.scala +neg/abstract.scala +neg/t2405.scala +neg/t0418.scala +neg/t5390c.scala +neg/lazyvals.scala +neg/lubs.scala +neg/abstract-report.scala +neg/t4163.scala +neg/t5702-neg-bad-and-wild.scala +neg/macro-invalidret +neg/t6728.scala +neg/t5152.scala +neg/t1432.scala +neg/abstract-inaccessible.scala +neg/import-precedence.scala +neg/t2462b.scala +neg/macro-invalidusage-presuper +neg/specification-scopes +neg/t6048.scala +neg/t4079 +neg/macro-basic-mamdmi +neg/t7020.scala +neg/t3015.scala +neg/t0207.scala +neg/t2296b +neg/t0673 +neg/t3761-overload-byname.scala +neg/t6675.scala +neg/t5529.scala +neg/sensitive.scala +neg/t742.scala +neg/t5067.scala +neg/t6162-overriding.scala +neg/variances.scala +neg/t5728.scala +neg/t6323a.scala +neg/compile-time-only-a.scala +neg/t6795.scala +neg/t2494.scala +neg/t3649.scala +neg/macro-invalidsig +neg/t2796.scala +neg/t112706A.scala +neg/t0764.scala +neg/t3757 +neg/t1431.scala +neg/exhausting.scala +neg/t1523.scala +neg/t779.scala +neg/xmltruncated1.scala +neg/t2208.scala +neg/t2078.scala +neg/t521.scala +neg/null-unsoundness.scala +neg/stmt-expr-discard.scala +neg/t0513.scala +neg/unchecked-abstract.scala +neg/t4460c.scala +neg/divergent-implicit.scala +neg/t5078.scala +neg/t1701.scala +neg/t0816.scala +neg/t1672b.scala +neg/macro-invalidusage-badbounds +neg/tailrec-2.scala +neg/t4064.scala +neg/t5510.scala +neg/t3873.scala +neg/tailrec-3.scala +neg/t0226.scala +neg/t2031.scala +neg/t633.scala +neg/constrs.scala +neg/anyval-anyref-parent.scala +neg/t7290.scala +neg/t1041.scala +neg/patternalts.scala +neg/error_tooManyArgsPattern.scala +neg/checksensibleUnit.scala +neg/t6539 +neg/t4417.scala +neg/wellkinded_app.scala +neg/for-comprehension-old.scala +neg/t2779.scala +neg/object-not-a-value.scala +neg/t2968b.scala +neg/t6483.scala +neg/t6902.scala +neg/t6963a.scala +neg/t3399.scala +neg/t0015.scala +neg/t3995.scala +neg/t276.scala +neg/t6758.scala +neg/t2441.scala +neg/cycle-bounds.scala +neg/t1241.scala +neg/t4137.scala +neg/unicode-unterminated-quote.scala +neg/t4762.scala +neg/typeerror.scala +neg/implicits.scala +neg/t961.scala +neg/ambiguous-float-dots2.scala +neg/t2416.scala +neg/t5799.scala +neg/t7285.scala +neg/implicit-shadow.scala +neg/t2388.scala +neg/java-access-neg +neg/found-req-variance.scala +neg/hk-bad-bounds.scala +neg/t3224.scala +neg/t1033.scala +neg/t7385.scala +neg/t5882.scala +neg/t4541.scala +neg/t2973.scala +neg/t6406-regextract.scala +neg/t6666.scala +neg/t4831.scala +neg/t425.scala +neg/t1845.scala +neg/t3683b.scala +neg/t2801.scala +neg/t6083.scala +neg/t0528neg.scala +neg/stringinterpolation_macro-neg.scala +neg/t668.scala +neg/t5666.scala +neg/t4271.scala +neg/interop_typetags_arenot_classmanifests.scala +neg/t1355.scala +neg/t715.scala +neg/t7238.scala +neg/t7473.scala +neg/t7292-removal.scala +neg/tcpoly_infer_ticket1162.scala +neg/t4098.scala +neg/t6013 +neg/t6227.scala +neg/t464-neg.scala +neg/badtok-3.scala +neg/t6082.scala +neg/anytrait.scala +neg/valueclasses-doubledefs.scala +neg/t7519.scala +neg/overloaded-unapply.scala +neg/t1163.scala +neg/wellkinded_bounds.scala +neg/t7292-deprecation.scala +neg/t5044.scala +neg/t0842.scala +neg/t6436.scala +neg/interop_typetags_arenot_classtags.scala +neg/t3653.scala +neg/higherkind_novalue.scala +neg/t935.scala +neg/t6040.scala +neg/annot-nonconst.scala +neg/macro-deprecate-idents.scala +neg/illegal-stmt-start.scala +neg/t565.scala +neg/case-collision.scala +neg/t3209.scala +neg/t5821.scala +neg/abstract-class-2.scala +neg/t846.scala +neg/quasiquotes-syntax-error-position.scala +neg/t3987.scala +neg/t877.scala +neg/t0117.scala +neg/t692.scala +neg/t5702-neg-ugly-xbrace.scala +neg/t7752.scala +neg/case-collision2.scala +neg/t6526.scala +neg/t2213.scala +neg/t7756a.scala +neg/macro-override-macro-overrides-abstract-method-a +neg/tcpoly_ticket2101.scala +neg/delayed-init-ref.scala +neg/caseinherit.scala +neg/t3189.scala +neg/unchecked-suppress.scala +neg/t2180.scala +neg/t1371.scala +neg/macro-cyclic +neg/t6123-explaintypes-macros +neg/t4134.scala +neg/t691.scala +neg/t2421b.scala +neg/t4691_exhaust_extractor.scala +neg/t4419.scala +neg/t5801.scala +neg/t650.scala +neg/t5735.scala +neg/t696.scala +neg/t882.scala +neg/t2968.scala +neg/t7507.scala +neg/macro-invalidusage-badargs +neg/macro-reify-typetag-typeparams-notags +neg/wellkinded_app2.scala +neg/t4425b.scala +neg/t2296a +neg/t1878.scala +neg/t649.scala +neg/override-object-no.scala +neg/t4174.scala +neg/t2070.scala +neg/sabin2.scala +neg/t5903e +neg/t6566a.scala +neg/finitary-error.scala +neg/t4818.scala +neg/t3614.scala +neg/t6666c.scala +neg/ticket513.scala +neg/suggest-similar.scala +neg/t4457_1.scala +neg/t6666e.scala +neg/tcpoly_bounds.scala +neg/t4727.scala +neg/t4425.scala +neg/macro-invalidusage-methodvaluesyntax +neg/t3854.scala +neg/t3006.scala +neg/t5580b.scala +neg/t5378.scala +neg/t639.scala +neg/wrong-args-for-none.scala +neg/t7171b.scala +neg/t5361.scala +neg/unreachablechar.scala +neg/t5572.scala +neg/t7757a.scala +neg/macro-invalidimpl +neg/t2773.scala +neg/t6359.scala +neg/saito.scala +neg/xmltruncated2.scala +neg/t667.scala +neg/t3934.scala +neg/t6771b.scala +neg/t4584.scala +neg/wellkinded_wrongarity2.scala +neg/t7369.scala +neg/t1477.scala +neg/t5617.scala +neg/t7299.scala +neg/faculty.scala +neg/virtpatmat_reach_null.scala +neg/macro-reify-typetag-hktypeparams-notags +neg/t1224.scala +neg/xmltruncated3.scala +neg/t1872.scala +neg/t558.scala +neg/t7110.scala +neg/any-vs-anyref.scala +neg/t6340.scala +neg/t4166.scala +neg/t2918.scala +neg/t5856.scala +neg/t4989.scala +neg/t0003.scala +neg/t1183.scala +neg/t963.scala +neg/t4515.scala +neg/valueclasses-pavlov.scala +neg/t608.scala +neg/choices.scala +neg/patmat-type-check.scala +neg/valueclasses-impl-restrictions.scala +neg/imp2.scala +neg/protected-constructors.scala +neg/t6788.scala +neg/nullary-override.scala +neg/t200.scala +neg/t343.scala +neg/names-defaults-neg-ref.scala +neg/tcpoly_typealias.scala +neg/classtags_contextbound_b.scala +neg/t729.scala +neg/t5683.scala +neg/t4928.scala +neg/t700.scala +neg/t7669.scala +neg/macro-invalidshape +neg/t6011.scala +neg/t7325.scala +neg/check-dead.scala +neg/t550.scala +neg/t5663-badwarneq.scala +neg/t0699 +neg/nopredefs.scala +neg/t3507-old.scala +neg/t5352.scala +neg/t6336.scala +neg/interop_classmanifests_arenot_typetags.scala +neg/sealed-final-neg.scala +neg/t2102.scala +neg/t7636.scala +neg/t5031b +neg/t798.scala +neg/t5702-neg-bad-xbrace.scala +neg/t0899.scala +neg/cyclics-import.scala +neg/badtok-2.scala +neg/t473.scala +neg/t3160ambiguous.scala +neg/t5106.scala +neg/t1286 +neg/macro-override-macro-overrides-abstract-method-b +neg/t0259.scala +neg/t510.scala +neg/t3836.scala +neg/t5830.scala +neg/t1548 +neg/t5580a.scala +neg/forward.scala +neg/t591.scala +neg/t6558b.scala +neg/t556.scala +neg/xmltruncated4.scala +neg/t5497.scala +neg/t409.scala +neg/t6283.scala +neg/override-object-flag.scala +neg/constructor-prefix-error.scala +neg/eta-expand-star.scala +neg/t3392.scala +neg/t1275.scala +neg/nested-fn-print.scala +neg/t7330.scala +neg/t2275a.scala +neg/t630.scala +neg/t4270.scala +neg/t2775.scala +neg/pat_unreachable.scala +neg/t4158.scala +neg/unit-returns-value.scala +neg/t1422.scala +neg/reify_metalevel_breach_-1_refers_to_0_b.scala +neg/reassignment.scala +neg/t3683a.scala +neg/noMember1.scala +neg/macro-without-xmacros-b +neg/t1106.scala +neg/t5182.scala +neg/t6889.scala +neg/t4217.scala +neg/t7501 +neg/t5063.scala +neg/t1009.scala +neg/t997.scala +neg/unchecked.scala +neg/classtags_contextbound_c.scala +neg/applydynamic_sip.scala +neg/t7715.scala +neg/t588.scala +neg/t6667b.scala +neg/t7757b.scala +neg/t4069.scala +neg/t515.scala +neg/variances2.scala +neg/t1049.scala +neg/t7289.scala +neg/t1623.scala +neg/permanent-blindness.scala +neg/t5803.scala +neg/super-cast-or-test.scala +neg/nonlocal-warning.scala +neg/t5687.scala +neg/t5903a +neg/t6566b.scala +neg/unchecked-knowable.scala +neg/t5093.scala +neg/protected-static-fail +neg/type-diagnostics.scala +neg/forgot-interpolator.scala +neg/interop_abstypetags_arenot_classmanifests.scala +neg/t5376.scala +neg/t545.scala +neg/xmlcorner.scala +neg/switch.scala +neg/depmet_1.scala +neg/abstract-concrete-methods.scala +neg/t4987.scala +neg/t5452-new.scala +neg/t750b +neg/unchecked-refinement.scala +neg/t418.scala +neg/t5354.scala +neg/t3736.scala +neg/t631.scala +neg/t6829.scala +neg/t0218.scala +neg/volatile-intersection.scala +neg/t412.scala +neg/t693.scala +neg/t4882.scala +neg/t1960.scala +neg/macro-divergence-controlled +neg/t712.scala +neg/t5544 +neg/t3222.scala +neg/t3604.scala +neg/t1112.scala +neg/t7157 +neg/accesses.scala +neg/t452.scala +neg/t6162-inheritance +neg/t2442 +neg/t6567.scala +neg/lazy-override.scala +neg/abstract-explaintypes.scala +neg/nested-annotation.scala +neg/t5753 +neg/t4283b +neg/t3691.scala +neg/infix-op-positions.scala +neg/t3403.scala +neg/t4851 +neg/structural.scala +neg/error_dependentMethodTpeConversionToFunction.scala +neg/t5839.scala +neg/t5553_1.scala +neg/reify_metalevel_breach_+0_refers_to_1.scala +neg/t752.scala +neg/t6574.scala +neg/t3714-neg.scala +neg/t4457_2.scala +neg/t2148.scala +neg/t1364.scala +neg/saferJavaConversions.scala +neg/t414.scala +neg/t5493.scala +neg/classtags_contextbound_a.scala +neg/reify_metalevel_breach_-1_refers_to_0_a.scala +neg/t3118.scala +neg/t512.scala +neg/t2336.scala +neg/t856.scala +neg/xmltruncated6.scala +neg/t2206.scala +neg/virtpatmat_unreach_select.scala +neg/t6258.scala +neg/t6815.scala +neg/not-possible-cause.scala +neg/dbldef.scala +neg/qualifying-class-error-1.scala +neg/t835.scala +neg/t5455.scala +neg/t6558.scala +neg/t708.scala +neg/macro-nontypeablebody +neg/t0565.scala +neg/xmltruncated5.scala +neg/t5390d.scala +neg/t520.scala +neg/t6138.scala +neg/macro-without-xmacros-a +neg/t7214neg.scala +neg/t2870.scala +neg/t593.scala +neg/t4541b.scala +neg/t4460b.scala +neg/t284.scala +neg/t2488.scala +neg/macro-override-method-overrides-macro +neg/interop_abstypetags_arenot_classtags.scala +neg/t3769.scala +neg/warn-inferred-any.scala +neg/t664.scala +neg/t5903d +neg/t562.scala +neg/t2316.scala +neg/t0152.scala +neg/migration28.scala +neg/t6443c.scala +neg/tcpoly_override.scala +neg/t7324.scala +neg/t987.scala +neg/t5903b +neg/t3481.scala +neg/t6912.scala +neg/tcpoly_variance_enforce.scala +neg/t3913.scala +neg/names-defaults-neg.scala +neg/t765.scala +neg/t5358.scala +neg/t391.scala +neg/serialversionuid-not-const.scala +neg/t771.scala +neg/t0903.scala +neg/catch-all.scala +neg/classmanifests_new_deprecations.scala +neg/t0606.scala +neg/t5189_inferred.scala +neg/macro-reify-typetag-useabstypetag +neg/t5543.scala +neg/logImplicits.scala +neg/interop_typetags_without_classtags_arenot_manifests.scala +neg/t6535.scala +neg/t7259.scala +neg/t2139.scala +neg/t278.scala +neg/t5564.scala +neg/unchecked3.scala +neg/virtpatmat_reach_sealed_unsealed.scala +neg/checksensible.scala +neg/t7721.scala +run/t3798.scala +run/macro-expand-varargs-explicit-over-varargs +run/t3888.scala +run/t0677-new.scala +run/t3273.scala +run/t3763.scala +run/t2755.scala +run/t920.scala +run/t5610a.scala +run/literals.scala +run/proxy.scala +run/unapply.scala +run/t5830.scala +run/array-addition.scala +run/macro-expand-nullary-nongeneric +run/macro-basic-ma-mdmi +run/valueclasses-constr.scala +run/t1247.scala +run/t3487.scala +run/rawstrings.scala +run/patmat-seqs.scala +run/eta-expand-star.scala +run/t7436.scala +run/t3996.scala +run/constructors.scala +run/t498.scala +run/t3835.scala +run/t298.scala +run/t2867.scala +run/t7120 +run/virtpatmat_literal.scala +run/t2175.scala +run/t2503.scala +run/t3026.scala +run/t603.scala +run/t0091.scala +run/t6394a +run/macro-expand-varargs-implicit-over-varargs +run/t7407.scala +run/t2552.scala +run/virtpatmat_npe.scala +run/macro-sip19 +run/t6644.scala +run/t6614.scala +run/t2005.scala +run/t4680.scala +run/t5903a +run/classtags_contextbound.scala +run/Course-2002-05.scala +run/applydynamic_sip.scala +run/t1766.scala +run/retsynch.scala +run/t7715.scala +run/t102.scala +run/nonlocalreturn.scala +run/macro-reify-staticXXX +run/Course-2002-06.scala +run/t6863.scala +run/t6500.scala +run/macro-impl-rename-context +run/t4351.scala +run/t5009.scala +run/macro-term-declared-in-annotation +run/t6271.scala +run/array-existential-bound.scala +run/t6443b.scala +run/t1987.scala +run/MutableListTest.scala +run/t7571.scala +run/t5488-fn.scala +run/macro-bodyexpandstoimpl +run/macro-reify-ref-to-packageless +run/t2212.scala +run/macro-expand-varargs-implicit-over-nonvarargs +run/t0807.scala +run/patmat-behavior.scala +run/t2446.scala +run/breakout.scala +run/t4122.scala +run/macro-settings +run/t7157 +run/t1323.scala +run/t4013b.scala +run/t6309.scala +run/t4047.scala +run/t5544 +run/t978.scala +run/t3361.scala +run/t6611.scala +run/t5387.scala +run/t5656.scala +run/t4897.scala +run/numeric-range.scala +run/t4777.scala +run/Course-2002-03.scala +run/string-extractor.scala +run/view-headoption.scala +run/patmat_unapp_abstype-new.scala +run/stream-stack-overflow-filter-map.scala +run/macro-impl-tparam-only-in-impl +run/t6559.scala +run/macro-reify-tagful-a +run/macro-expand-multiple-arglists +run/t4709.scala +run/t3509.scala +run/t5284b.scala +run/t7617b +run/t3923.scala +run/virtpatmat_apply.scala +run/t363.scala +run/manifests-undeprecated-in-2.10.0.scala +run/matchintasany.scala +run/t3970.scala +run/t4996.scala +run/t5530.scala +run/macro-term-declared-in-object-class +run/t3242b.scala +run/indexedSeq-apply.scala +run/t107.scala +run/t2337.scala +run/t2754.scala +run/flat-flat-flat.scala +run/t6673.scala +run/interpolationMultiline2.scala +run/t0631.scala +run/t2800.scala +run/t6506.scala +run/t6260.scala +run/t2418.scala +run/t4415.scala +run/classmanifests_new_alias.scala +run/t5380.scala +run/tcpoly_parseridioms.scala +run/t1747.scala +run/t5903d +run/t3530.scala +run/t216.scala +run/macro-term-declared-in-refinement +run/t4592.scala +run/t2488.scala +run/t3327.scala +run/t5614.scala +run/t5903b +run/iterables.scala +run/t3964.scala +run/t6329_vanilla.scala +run/t3038c +run/t1697.scala +run/t2030.scala +run/t3397.scala +run/t1005.scala +run/t3353.scala +run/t1466.scala +run/t3186.scala +run/tcpoly_overriding.scala +run/t5394.scala +run/t5284.scala +run/unboxingBug.scala +run/t7200.scala +run/macro-reify-basic +run/t153.scala +run/iterator3444.scala +run/macro-expand-implicit-macro-is-val +run/macro-basic-ma-md-mi +run/interpolationArgs.scala +run/t4954.scala +run/t3645.scala +run/transpose.scala +run/t3887.scala +run/t4288.scala +run/unittest_iterator.scala +run/t5543.scala +run/macro-term-declared-in-object +run/iq.scala +run/t2788.scala +run/t2027.scala +run/macro-expand-recursive +run/t949.scala +run/t1909b.scala +run/delambdafy-nested-by-name.scala +run/delambdafy-two-lambdas.scala +run/macro-blackbox-materialization +run/lists-run.scala +run/macro-parse-position +run/macro-parse-position-malformed +run/macro-whitebox-dynamic-materialization +run/macro-whitebox-extractor +run/macro-vampire-false-warning +run/macro-whitebox-fundep-materialization +run/macro-whitebox-structural +run/mutable-treeset.scala +run/static-module-method.scala +run/sort.scala +run/t1909.scala +run/t1909c.scala +run/t3346a.scala +run/t3346d.scala +run/t3346f.scala +run/t3346h.scala +run/t3346g.scala +run/t3832.scala +run/t4742.scala +run/t5377.scala +run/t5923c.scala +run/t6188.scala +run/t6333.scala +run/t6385.scala +run/t7899.scala +run/t7584b.scala +run/t7223.scala +run/t7859 +run/t7868.scala +run/t7871 +run/arrayclone-new.scala +run/arrayclone-old.scala +run/bitsets.scala +run/comparable-comparator.scala +run/colltest1.scala +run/t2106.scala +run/t5986.scala +run/view-iterator-stream.scala +run/array-charSeq.scala +pos/signatures +pos/t1263 +pos/t3249 +neg/t4749.scala +neg/main1.scala +neg/t7251 +neg/t7494-after-terminal +neg/t7494-before-parser +neg/t7494-right-after-terminal +run/lazy-traits.scala +run/OrderingTest.scala +run/ReplacementMatching.scala +run/patmat-finally.scala +run/t3158.scala +run/t3346e.scala +run/t4398.scala +run/t4930.scala +run/t6534.scala +pos/sammy_scope.scala +pos/delambdafy-patterns.scala +pos/private-types-after-typer.scala +pos/delambdafy-lambdalift.scala +pos/sammy_poly.scala +pos/sammy_single.scala +pos/SI-4012-b.scala +pos/sammy_twice.scala +pos/t3160.scala +pos/t1014.scala +pos/t4970b.scala +pos/t2698.scala +pos/t5845.scala +pos/t6201.scala +pos/t6260a.scala +pos/t7688.scala +pos/t7818.scala +pos/t1203a.scala +pos/t7834.scala +pos/t7853.scala +pos/t7815.scala +pos/t7853-partial-function.scala +pos/t7864.scala +pos/t7928.scala +pos/t7902.scala +pos/t7944.scala +pos/t7847 +neg/accesses2.scala +neg/bad-advice.scala +neg/gadts2.scala +neg/gadts2-strict.scala +neg/macro-bundle-abstract.scala +neg/macro-bundle-object.scala +neg/macro-bundle-trait.scala +neg/macro-blackbox-dynamic-materialization +neg/macro-blackbox-extractor +neg/run-gadts-strict.scala +neg/macro-blackbox-structural +neg/sammy_restrictions.scala +neg/sammy_wrong_arity.scala +neg/t2462c.scala +neg/t3346b.scala +neg/t1909-object.scala +neg/macro-blackbox-fundep-materialization +neg/t3346c.scala +neg/t3871.scala +neg/t3871b.scala +neg/t3971.scala +neg/t3346i.scala +neg/t6120.scala +neg/t6260c.scala +neg/t6680a.scala +neg/t7239.scala +neg/t7007.scala +neg/t7605-deprecation.scala +neg/t7622-missing-required.scala +neg/t7629-view-bounds-deprecation.scala +neg/t7834neg.scala +neg/t7783.scala +neg/t7848-interp-warn.scala +neg/t7519-b +neg/t7622-missing-dependency +neg/t7870.scala +neg/t7877.scala +neg/t7895.scala +neg/t7895b.scala +neg/t7899.scala +neg/t7895c.scala +neg/t7859 +run/t4752.scala +run/t2087-and-2400.scala +run/t3855.scala +run/t6637.scala +run/t6731.scala +pos/t3999b.scala +run/t0432.scala +run/t2514.scala +run/t7817.scala +run/t874.scala +run/type-currying.scala +run/t3616.scala +run/t3687.scala +run/t4570.scala +run/t5612.scala +run/t1110.scala +run/t2636.scala +run/verify-ctor.scala +run/t3647.scala +run/t4560.scala +run/t6632.scala +run/richs.scala +run/t6725-1.scala +pos/t7776.scala +run/fors.scala +run/t6706.scala +run/t3175.scala +run/delambdafy-dependent-on-param-subst.scala +run/t4332b.scala +run/t8048a +run/t8017 +run/t7985b.scala +run/t8100.scala +run/patmat-mix-case-extractor.scala +run/t4750.scala +run/t7912.scala +run/delambdafy-dependent-on-param-subst-2.scala +run/t8048b +run/t8091.scala +run/macroPlugins-macroRuntime +run/macro-default-params +run/t6355.scala +run/t7777 +run/t8002.scala +run/t8015-ffc.scala +run/macro-subpatterns +run/t7985.scala +run/macroPlugins-macroArgs +run/t7326.scala +run/t5045.scala +run/value-class-partial-func-depmet.scala +run/t6329_vanilla_bug.scala +run/macroPlugins-macroExpand +run/t8010.scala +run/macroPlugins-typedMacroBody +run/t7406.scala +pos/t8146a.scala +pos/t8046c.scala +pos/t8132.scala +pos/t8045.scala +pos/overzealous-assert-genbcode.scala +pos/t8128.scala +pos/t8013 +pos/t8064b +pos/t6780.scala +pos/t7987 +pos/bcode_throw_null +pos/t8064 +pos/t8046.scala +pos/t6231.scala +pos/t7983.scala +pos/t5508.scala +pos/t5508-min.scala +pos/t8023b.scala +pos/t6231b.scala +pos/debug-reset-local-attrs.scala +pos/t8054.scala +pos/t2066.scala +pos/dotless-targs.scala +pos/t8120.scala +pos/t5508-min-okay.scala +pos/t8060.scala +pos/t8001 +pos/t8138.scala +pos/t8111.scala +pos/t8011.scala +pos/t8146b.scala +pos/t8046b.scala +pos/t8023.scala +pos/t5508-min-okay2.scala +pos/macro-implicit-invalidate-on-error.scala +neg/t6563.scala +neg/missing-param-type-tuple.scala +neg/not-a-legal-formal-parameter-tuple.scala +neg/t7897.scala +neg/t8015-ffa.scala +neg/quasiquotes-unliftable-not-found.scala +neg/t2066b.scala +neg/dotless-targs.scala +neg/patmat-classtag-compound.scala +neg/t2066.scala +neg/t8035-deprecated.scala +neg/t6675b.scala +neg/t8104 +neg/t7872.scala +neg/t7850.scala +neg/t7967.scala +neg/macro-bundle-overloaded.scala +neg/t6355a.scala +neg/class-of-double-targs.scala +neg/t6355b.scala +neg/macro-reify-splice-splice +neg/macro-bundle-noncontext.scala +neg/t8015-ffb.scala +neg/t8035-removed.scala +neg/t7984.scala +neg/t8024.scala +neg/t8024b.scala +neg/t8157.scala +neg/t8146-non-finitary-2.scala +neg/t8006.scala +neg/t7872c.scala +neg/t8146-non-finitary.scala +neg/t7872b.scala +neg/t6920.scala +run/t6200.scala +run/t6196.scala +run/macro-bundle-context-refinement +run/macro-enclosingowner-detectvar +run/macro-enclosingowner-sbt +run/macro-bundle-context-alias +run/macro-bundle-whitebox-use-refined +run/macro-bundle-whitebox-use-raw +neg/name-lookup-stable.scala +neg/t0764b.scala +neg/no-implicit-to-anyref-any-val.scala +neg/t1503.scala +neg/t4728.scala +neg/t6455.scala +neg/t6260-named.scala +neg/t6844.scala +neg/t7475c.scala +neg/t7475e.scala +neg/t7475f.scala +neg/macro-bundle-whitebox-use-raw +neg/macro-bundle-whitebox-use-refined +neg/macro-incompatible-macro-engine-b +neg/t7980.scala +neg/macro-incompatible-macro-engine-a +neg/t8143a.scala +neg/t8207.scala +neg/t8182.scala +neg/t8219-any-any-ref-equals.scala +neg/t8177a.scala +neg/t8228.scala +neg/t8229.scala +neg/t8237-default.scala +neg/t8244b.scala +neg/t8244e +neg/t8244c.scala +neg/t8265.scala +neg/t8266-invalid-interp.scala +neg/t6931 +neg/t8376 +neg/t8372.scala +neg/t8300-overloading.scala +neg/t8244 +neg/t8158 +neg/t8431.scala +pos/implicit-anyval-2.10.scala +pos/delambdafy_t6260_method.scala +pos/macro-bundle-disambiguate-bundle.scala +pos/macro-bundle-disambiguate-nonbundle.scala +pos/package-ob-case +pos/t1786-counter.scala +pos/reflection-compat-api-universe.scala +pos/existential-java-case-class +pos/t1786-cycle.scala +pos/reflection-compat-c.scala +pos/t3452f.scala +pos/reflection-compat-ru.scala +pos/t2066-2.10-compat.scala +pos/reflection-compat-macro-universe.scala +pos/t5900a.scala +pos/t5760-pkgobj-warn +pos/t5954a +pos/t5954b +pos/t5954d +pos/t6260.scala +pos/t5165b +pos/t5954c +pos/t6260b.scala +pos/t7475b.scala +pos/t7475a.scala +pos/t7753.scala +pos/t7322.scala +pos/t6948.scala +pos/t7475d.scala +pos/t7475e.scala +pos/t6169 +pos/t7788.scala +pos/t7919.scala +pos/t8177a.scala +pos/t8177.scala +pos/t8170.scala +pos/t8170b.scala +pos/t8177d.scala +pos/t8177b.scala +pos/t8177e.scala +pos/t8134 +pos/t8177h.scala +pos/t8177g.scala +pos/t8207.scala +pos/t8187.scala +pos/t8219.scala +pos/t8219b.scala +pos/t8224.scala +pos/t8237.scala +pos/t8223.scala +pos/t8237b.scala +pos/t8300-conversions-a.scala +pos/t8300-conversions-b.scala +pos/t8209a +pos/t8209b +pos/t8244d +pos/t8300-overloading.scala +pos/t8300-patmat-a.scala +pos/t8300-patmat-b.scala +pos/t8301.scala +pos/t8324.scala +pos/t8301b.scala +pos/t8363.scala +pos/t8367.scala +pos/t8369a.scala +pos/t8369b.scala +pos/t8403.scala +pos/t8364.scala +pos/t8352 +pos/t8376 +neg/macro-bundle-nonpublic-c.scala +neg/literate_existentials.scala +neg/macro-bundle-nonpublic-impl.scala +neg/macro-bundle-ambiguous.scala +neg/macro-bundle-priority-bundle.scala +neg/macro-bundle-need-qualifier.scala +neg/macro-bundle-nonstatic.scala +neg/macro-bundle-polymorphic.scala +neg/macro-bundle-priority-nonbundle.scala +neg/macro-bundle-wrongcontext-a.scala +neg/macro-bundle-wrongcontext-b.scala +run/t8425 +run/t8245.scala +run/t8266-octal-interp.scala +run/t8280.scala +run/t8395.scala +run/t8321 +run/t8153.scala +run/t8197.scala +run/t8197b.scala +run/t8233.scala +run/t8133 +run/t8133b +run/t7475b.scala +run/t6814 +run/t4577.scala +run/t5134.scala +run/t3452f.scala +run/t3452h.scala +run/t3452c.scala +run/t3452.scala +run/t261.scala +run/t3235-minimal.scala +run/t1503_future.scala +run/t5565.scala +pos/t8411 +pos/t8460.scala +run/t8428.scala +run/t8437 +run/absoverride.scala +run/arrays.scala +run/duration-coarsest.scala +run/iterator-from.scala +run/SymbolsTest.scala +run/t1074.scala +run/t1505.scala +run/streams.scala +run/t2111.scala +run/t4601.scala +pos/SI-4012-a.scala +pos/SI-7638.scala +neg/t3692-new.scala +run/t7015.scala +run/t7992b.scala +run/t7992.scala +run/t8570.scala +pos/t8157-2.10.scala +pos/t8325.scala +pos/t8523.scala +pos/t8578.scala +pos/t8329.scala +pos/t8497 +pos/t8546.scala +pos/t8531 +neg/t8325-c.scala +neg/t8325-b.scala +neg/t8325.scala +neg/t6988.scala +neg/t8463.scala +neg/t8450.scala +neg/t8430.scala +run/finally.scala +neg/t8630.scala +neg/t8035-no-adapted-args.scala +neg/t8675b.scala +neg/t8610-arg.scala +neg/t8736-c.scala +neg/tailrec-4.scala +neg/double-def-top-level +neg/t8610.scala +neg/aladdin1055 +neg/virtpatmat_exhaust_compound.scala +neg/t8675.scala +neg/t8525.scala +pos/t8736.scala +pos/t8625.scala +pos/t8596.scala +pos/t8617.scala +pos/t8736-b.scala +pos/t8708 +pos/macro-attachments +run/t8611a.scala +run/t8738.scala +run/macro-rangepos-args +run/t8610.scala +run/macro-rangepos-subpatterns +run/t8611c.scala +run/macroPlugins-isBlackbox +run/t8601d.scala +run/t8607.scala +run/bugs.scala +run/t1503.scala +run/t4148.scala +run/t7763.scala +run/issue192.scala +run/t8893b.scala +run/t8845.scala +run/t8933 +run/t7459c.scala +run/t9003.scala +run/t7459f.scala +run/t8933c.scala +run/t1994.scala +run/t2866.scala +run/t5665.scala +run/t7459d.scala +run/t8933b +run/t8888.scala +run/t7459b-optimize.scala +run/t7459a.scala +run/t7019.scala +run/t8893.scala +run/t8803.scala +run/t7459b.scala +run/t8823.scala +run/t6541.scala +run/nothingTypeDce.scala +run/t8680.scala +run/t8925.scala +run/nothingTypeNoOpt.scala +run/t9030.scala +run/bigDecimalTest.scala +run/bigDecimalCache.scala +run/range.scala +run/t6064.scala +run/t7521 +run/t8710.scala +run/t8575.scala +run/t8944 +run/t8944b.scala +run/t9387.scala +run/t9387b.scala +pos/t7784.scala +pos/t8862a.scala +pos/t9074.scala +pos/t8462.scala +pos/t8862b.scala +pos/alladin763.scala +pos/t6778.scala +pos/t9074b.scala +pos/t9326a.scala +pos/t9131.scala +pos/t9393 +pos/t9392 +neg/missing-arg-list.scala +neg/deprecated-target.scala +neg/t6895.scala +neg/beanInfoDeprecation.scala +neg/t8777.scala +neg/t6895b.scala +neg/t8892.scala +neg/t8849.scala +neg/inlineIndyLambdaPrivate +run/t9029.scala +run/t7850c.scala +run/t7850d.scala +run/t8334.scala +run/t9029c.scala +run/t9029b.scala +run/t9422.scala +run/t9425.scala +pos/t9475.scala +pos/t9498.scala +pos/t9479.scala +pos/t9479b.scala +pos/t9442.scala +pos/t9369.scala +pos/t6666d.scala +pos/t9370 +neg/t6810.scala +neg/t8127a.scala +neg/t8989.scala +neg/t9401.scala +neg/implicit-ambiguous.scala +neg/implicit-ambiguous-2.scala +neg/implicit-ambiguous-invalid.scala +neg/warn-unused-imports +run/t7269.scala +run/equality.scala +run/number-parsing.scala +run/t6220.scala +run/mapConserve.scala +run/colltest.scala +run/t0412.scala +run/t6261.scala +run/java-erasure.scala +run/t5880.scala +run/t6197.scala +run/t4201.scala +run/t5608.scala +run/t3518.scala +run/t6198.scala +run/t2813.2.scala +pos/java-type-annotations +pos/sammy_infer_argtype_subtypes.scala +pos/sammy_ctor_arg.scala +pos/fun_undo_eta.scala +pos/sammy_inferargs.scala +pos/existental-slow-compile2.scala +pos/existential-slow-compile1.scala +pos/sammy_implicit.scala +pos/t9178b.scala +pos/t9449.scala +pos/t3234.scala +pos/t9542.scala +pos/t8429.scala +pos/t9658.scala +pos/t9630 +pos/t9399.scala +pos/t9411a.scala +pos/t9411b.scala +neg/partestInvalidFlag.scala +neg/sammy_error.scala +neg/sammy_disabled.scala +neg/sammy_overload.scala +neg/sammy_expected.scala +neg/t8700a +neg/t9527b.scala +neg/t9527a.scala +neg/t9572.scala +neg/t9535.scala +neg/t9629.scala +neg/optimiseDeprecated.scala +neg/t9398 +neg/outer-ref-checks.scala +neg/t8685.scala +neg/t8700b +run/t9349 +run/t9178a.scala +run/t9110.scala +run/sammy_cbn.scala +run/sammy_erasure_cce.scala +run/sammy_after_implicit_view.scala +run/sammy_restrictions_LMF.scala +run/sammy_vararg_cbn.scala +run/t7807.scala +run/sammy_return.scala +run/t9546.scala +run/t9546b.scala +run/lisp.scala +run/t9546c.scala +run/t9546d.scala +run/t9546e.scala +run/t9567.scala +run/t9567b.scala +run/trait-clonable.scala +run/t9567c.scala +run/trait-defaults-modules.scala +run/trait-defaults-modules3.scala +run/trait-defaults-modules2 +pos/functions.scala +pos/MailBox.scala +neg/t6289 +run/t4729 +run/t6114.scala +run/t1430 +pos/constant-warning.scala +pos/t2712-5.scala +pos/t2712-2.scala +pos/t2712-4.scala +pos/t2712-1.scala +pos/t2712-3.scala +pos/t2712-6.scala +pos/t6895b.scala +pos/t5683.scala +pos/hkgadt.scala +pos/t2712-7.scala +pos/t9245.scala +pos/t7088.scala +pos/trait-defaults-super.scala +pos/t8044.scala +pos/t9665.scala +pos/t9397.scala +pos/t5183.scala +pos/t8449 +neg/t8044-b.scala +neg/t8044.scala +neg/t2712-3.scala +neg/t2712-2.scala +neg/t2712-1.scala +neg/t9045.scala +neg/t8667.scala +neg/t9361.scala +neg/t9781.scala +neg/trait-no-native.scala +neg/hkgadt.scala +neg/t9684b.scala +neg/t9382.scala +neg/trait-defaults-super.scala +neg/t9684.scala +run/hashCodeStatics.scala +run/t9390d.scala +run/trait-static-clash.scala +run/t5568.scala +run/t6318_primitives.scala +pos/fields_widen_trait_var.scala +pos/sammy_extends_function.scala +pos/infer_override_def_args.scala +pos/t482.scala +pos/t8079b.scala +pos/t6161b.scala +pos/t5294b.scala +pos/t5294c.scala +pos/overloaded_ho_fun.scala +pos/t4914.scala +pos/trait_fields_dependent_conflict.scala +pos/t2377b +pos/trait_fields_dependent_rebind.scala +pos/t9855b.scala +pos/trait_fields_inherit_double_def.scala +pos/t9855.scala +pos/t8873.scala +pos/trait_fields_nested_private_object.scala +pos/trait_fields_nested_public_object.scala +pos/trait_fields_private_this.scala +pos/trait_fields_var_override_deferred.scala +pos/trait_fields_static_fwd.scala +pos/trait_fields_owners.scala +pos/trait_fields_volatile.scala +pos/trait_lazy_accessboundary.scala +pos/trait_fields_lambdalift.scala +pos/typevar-in-prefix.scala +pos/val_infer.scala +pos/lub-from-hell.scala +neg/t8079a.scala +neg/sd128 +neg/t9849.scala +neg/trait_fields_var_override.scala +neg/val_infer.scala +neg/val_sig_infer_match.scala +neg/t7187.scala +neg/trait_fields_deprecated_overriding.scala +neg/t9847.scala +neg/val_sig_infer_struct.scala +neg/trait_fields_conflicts.scala +neg/lub-from-hell-2.scala +run/t2946 +run/lazy_local_labels.scala +run/sd167.scala +run/t9841.scala +run/trait-fields-override-lazy.scala +run/trait_fields_init.scala +run/trait_fields_three_layer_overrides.scala +run/t9516.scala +run/t10032.scala +pos/sam_erasure_boundedwild.scala +pos/t10154.scala +pos/t10066.scala +pos/t10154b.scala +pos/t10093.scala +pos/t8040.scala +pos/t3772.scala +pos/t10206.scala +pos/t9331.scala +pos/userdefined_apply_poly_overload.scala +pos/userdefined_apply.scala +pos/trailing-commas.scala +neg/t10097.scala +neg/t10068.scala +neg/ambiguous-same.scala +neg/maxerrs.scala +neg/maxwarns.scala +neg/t10207.scala +neg/t10066.scala +neg/t3236-neg +neg/t3772.scala +neg/t8704.scala +neg/t8002-nested-scope.scala +neg/t10097b.scala +neg/trailing-commas.scala +neg/t9834.scala +neg/userdefined_apply.scala +neg/t8417.scala +neg/warn-unused-implicits.scala +neg/t7860.scala +neg/t8763.scala +neg/t9636.scala +neg/warn-unused-params.scala +neg/t9675.scala +neg/warn-unused-patvars.scala +run/t10069.scala +run/SD-290.scala +run/sd329.scala +run/t10097.scala +run/t10072.scala +run/t10261 +run/t9114.scala +run/InferOverloadedPartialFunction.scala + +# Adapt checkfiles for (1.0).toString == "1" +run/Course-2002-01.scala +run/t0421-new.scala +run/runtime.scala +run/t0421-old.scala +run/spec-self.scala +run/t5552.scala +run/Course-2002-02.scala +run/Course-2002-04.scala +run/promotion.scala +run/t4617.scala +run/Course-2002-09.scala +run/t5866.scala +run/try-catch-unify.scala +run/impconvtimes.scala +run/Course-2002-10.scala +run/Course-2002-08.scala +run/MeterCaseClass.scala +run/Meter.scala +run/deeps.scala +run/caseClassHash.scala +run/interpolation.scala +run/interpolationMultiline1.scala +run/t9656.scala +pos/sd219.scala +pos/t9918 +pos/shapeless-regression.scala +pos/issue244.scala +pos/t9920.scala +pos/t9943.scala +neg/t5148.scala +run/sd242.scala +run/local_obj.scala +run/t9697.scala +run/t9920.scala +run/t9920c.scala +run/t9920d.scala +run/t9920b.scala +run/t9946a.scala +run/t9946c.scala +run/t9946b.scala +run/trait-super-calls.scala +pos/sd268.scala +pos/sd248 +pos/t6734.scala +pos/t10009.scala +pos/t7551 +pos/t6978 +pos/t7046-2 +neg/t9953.scala +neg/t7014 +neg/t7046-2 +neg/t7046 +run/t7046-1 +run/t7046-2 + +# Adapt checkfiles for ().toString == "undefined" +run/t5680.scala +run/dynamic-anyval.scala +run/macro-bundle-toplevel +run/macro-bundle-whitebox-decl +run/t6662 +run/t8570a.scala +run/t3702.scala +run/t7657 +run/macro-bundle-static +run/structural.scala + +# Adapt checkfiles for print & flush (which we cannot 100% emulate) +run/imports.scala +run/misc.scala + +# Adapt checkfiles for compiler phase list +neg/t7494-no-options +neg/t6446-list +neg/t6446-missing +neg/t6446-show-phases.scala +neg/t6446-additional + +# Adapt checkfiles for different behavior with boxed types +run/virtpatmat_typetag.scala +run/virtpatmat_switch.scala +run/t5629b.scala +run/t5356.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t6446-additional.check new file mode 100644 index 0000000000..b7ce23da2f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t6446-additional.check @@ -0,0 +1,30 @@ + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + ploogin 27 A sample phase that does so many things it's kind of hard... + terminal 28 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t6446-list.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t6446-list.check new file mode 100644 index 0000000000..95883c8c81 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t6446-list.check @@ -0,0 +1,2 @@ +ploogin - A sample plugin for testing. +scalajs - Compile to JavaScript diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t6446-missing.check new file mode 100644 index 0000000000..56b74a3128 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t6446-missing.check @@ -0,0 +1,30 @@ +Error: unable to load class: t6446.Ploogin + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + terminal 27 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t6446-show-phases.check new file mode 100644 index 0000000000..cde255e3b1 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t6446-show-phases.check @@ -0,0 +1,29 @@ + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + terminal 27 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t7494-no-options.check new file mode 100644 index 0000000000..d8be421e5e --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t7494-no-options.check @@ -0,0 +1,31 @@ +error: Error: ploogin takes no options + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + ploogin 27 A sample phase that does so many things it's kind of hard... + terminal 28 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-01.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-01.check new file mode 100644 index 0000000000..fcda9433de --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-01.check @@ -0,0 +1,37 @@ +Course-2002-01.scala:41: warning: method loop in object M0 does nothing other than call itself recursively + def loop: Int = loop; + ^ +232 +667 +11 +10 +62.8318 +62.8318 +62.8318 +4 +81 +256 +25 +1 +737 +1 +0 +1 +76 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +sqrt(2) = 1.4142135623746899 +sqrt(2) = 1.4142135623746899 +cbrt(2) = 1.2599210500177698 +1 +1 1 +1 2 1 +1 3 3 1 +1 4 6 4 1 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-02.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-02.check new file mode 100644 index 0000000000..ab75cfdb61 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-02.check @@ -0,0 +1,187 @@ +7 +120 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +pi = 3.181104885577714 +pi = 3.181104885577714 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 +pi = 3.181104885577714 +pi = 3.181104885577714 + +1.5 +1.4166666666666665 +1.4142156862745097 +1.4142135623746899 +sqrt(2) = 1.4142135623746899 + +1.5 +1.4166666666666665 +1.4142156862745097 +1.4142135623746899 +sqrt(2) = 1.4142135623746899 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +power(0,0) = 1 +power(0,1) = 0 +power(0,2) = 0 +power(0,3) = 0 +power(0,4) = 0 +power(0,5) = 0 +power(0,6) = 0 +power(0,7) = 0 +power(0,8) = 0 + +power(1,0) = 1 +power(1,1) = 1 +power(1,2) = 1 +power(1,3) = 1 +power(1,4) = 1 +power(1,5) = 1 +power(1,6) = 1 +power(1,7) = 1 +power(1,8) = 1 + +power(2,0) = 1 +power(2,1) = 2 +power(2,2) = 4 +power(2,3) = 8 +power(2,4) = 16 +power(2,5) = 32 +power(2,6) = 64 +power(2,7) = 128 +power(2,8) = 256 + +power(3,0) = 1 +power(3,1) = 3 +power(3,2) = 9 +power(3,3) = 27 +power(3,4) = 81 +power(3,5) = 243 +power(3,6) = 729 +power(3,7) = 2187 +power(3,8) = 6561 + +power(4,0) = 1 +power(4,1) = 4 +power(4,2) = 16 +power(4,3) = 64 +power(4,4) = 256 +power(4,5) = 1024 +power(4,6) = 4096 +power(4,7) = 16384 +power(4,8) = 65536 + +power(5,0) = 1 +power(5,1) = 5 +power(5,2) = 25 +power(5,3) = 125 +power(5,4) = 625 +power(5,5) = 3125 +power(5,6) = 15625 +power(5,7) = 78125 +power(5,8) = 390625 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-04.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-04.check new file mode 100644 index 0000000000..fc6ad96eed --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-04.check @@ -0,0 +1,64 @@ +list0 = List(6, 3, 1, 8, 7, 1, 2, 5, 8, 4, 3, 4, 8) +list1 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list2 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list3 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list4 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list5 = List(8, 8, 8, 7, 6, 5, 4, 4, 3, 3, 2, 1, 1) +list6 = List(8, 8, 8, 7, 6, 5, 4, 4, 3, 3, 2, 1, 1) + +list0: List() -> List() +list1: List(0) -> List(0) +list2: List(0, 1) -> List(0, 1) +list3: List(1, 0) -> List(0, 1) +list4: List(0, 1, 2) -> List(0, 1, 2) +list5: List(1, 0, 2) -> List(0, 1, 2) +list6: List(0, 1, 2) -> List(0, 1, 2) +list7: List(1, 0, 2) -> List(0, 1, 2) +list8: List(2, 0, 1) -> List(0, 1, 2) +list9: List(2, 1, 0) -> List(0, 1, 2) +listA: List(6, 3, 1, 8, 7, 1, 2, 5, 8, 4) -> List(1, 1, 2, 3, 4, 5, 6, 7, 8, 8) + +f(x) = 5x^3+7x^2+5x+9 +f(0) = 9 +f(1) = 26 +f(2) = 87 +f(3) = 222 + +v1 = List(2, 3, 4) +v2 = List(6, 7, 8) + +id = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +m1 = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m2 = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) + +v1 * v1 = 29 +v1 * v2 = 65 +v2 * v1 = 65 +v1 * v2 = 65 + +id * v1 = List(2, 3, 4) +m1 * v1 = List(4, 6, 8) +m2 * v1 = List(20, 47, 74) + +trn(id) = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +trn(m1) = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +trn(m2) = List(List(1, 4, 7), List(2, 5, 8), List(3, 6, 9)) + +List(v1) * id = List(List(2, 3, 4)) +List(v1) * m1 = List(List(4, 6, 8)) +List(v1) * m2 = List(List(42, 51, 60)) + +id * List(v1) = List(List(2, 3, 4), List(0, 0, 0), List(0, 0, 0)) +m1 * List(v1) = List(List(4, 6, 8), List(0, 0, 0), List(0, 0, 0)) +m2 * List(v1) = List(List(2, 3, 4), List(8, 12, 16), List(14, 21, 28)) + +id * id = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +id * m1 = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m1 * id = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m1 * m1 = List(List(4, 0, 0), List(0, 4, 0), List(0, 0, 4)) +id * m2 = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) +m2 * id = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) +m1 * m2 = List(List(2, 4, 6), List(8, 10, 12), List(14, 16, 18)) +m2 * m1 = List(List(2, 4, 6), List(8, 10, 12), List(14, 16, 18)) +m2 * m2 = List(List(30, 36, 42), List(66, 81, 96), List(102, 126, 150)) + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-08.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-08.check new file mode 100644 index 0000000000..0585d5b44f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-08.check @@ -0,0 +1,171 @@ +x = abc +count = 111 +x = hello +count = 112 + +account deposit 50 -> undefined +account withdraw 20 -> 30 +account withdraw 20 -> 10 +account withdraw 15 -> + +x deposit 30 -> undefined +y withdraw 20 -> + +x deposit 30 -> undefined +x withdraw 20 -> 10 + +x deposit 30 -> undefined +y withdraw 20 -> 10 + +2^0 = 1 +2^1 = 2 +2^2 = 4 +2^3 = 8 + +2^0 = 1 +2^1 = 2 +2^2 = 4 +2^3 = 8 + +1 2 3 +List(1, 2, 3) + +out 0 new-value = false +*** simulation started *** +out 1 new-value = true +!0 = 1 + +*** simulation started *** +out 2 new-value = false +!1 = 0 + +out 2 new-value = false + +*** simulation started *** +0 & 0 = 0 + +*** simulation started *** +0 & 1 = 0 + +*** simulation started *** +out 11 new-value = true +out 11 new-value = false +1 & 0 = 0 + +*** simulation started *** +out 14 new-value = true +1 & 1 = 1 + +out 14 new-value = false + +*** simulation started *** +0 | 0 = 0 + +*** simulation started *** +out 24 new-value = true +0 | 1 = 1 + +*** simulation started *** +1 | 0 = 1 + +*** simulation started *** +1 | 1 = 1 + +sum 34 new-value = false +carry 34 new-value = false + +*** simulation started *** +0 + 0 = 0 + +*** simulation started *** +sum 47 new-value = true +0 + 1 = 1 + +*** simulation started *** +carry 50 new-value = true +carry 50 new-value = false +sum 54 new-value = false +sum 54 new-value = true +1 + 0 = 1 + +*** simulation started *** +carry 57 new-value = true +sum 61 new-value = false +1 + 1 = 2 + +sum 61 new-value = false +carry 61 new-value = false + +*** simulation started *** +0 + 0 + 0 = 0 + +*** simulation started *** +sum 82 new-value = true +0 + 0 + 1 = 1 + +*** simulation started *** +sum 89 new-value = false +carry 90 new-value = true +sum 97 new-value = true +carry 98 new-value = false +0 + 1 + 0 = 1 + +*** simulation started *** +sum 113 new-value = false +carry 114 new-value = true +0 + 1 + 1 = 2 + +*** simulation started *** +sum 121 new-value = true +carry 122 new-value = false +sum 129 new-value = false +sum 129 new-value = true +1 + 0 + 0 = 1 + +*** simulation started *** +carry 137 new-value = true +sum 144 new-value = false +1 + 0 + 1 = 2 + +*** simulation started *** +carry 152 new-value = false +sum 152 new-value = true +sum 158 new-value = false +carry 159 new-value = true +1 + 1 + 0 = 2 + +*** simulation started *** +sum 173 new-value = true +1 + 1 + 1 = 3 + +in 0 new-value = false +ctrl0 0 new-value = false +ctrl1 0 new-value = false +ctrl2 0 new-value = false +out0 0 new-value = false +out1 0 new-value = false +out2 0 new-value = false +out3 0 new-value = false +out4 0 new-value = false +out5 0 new-value = false +out6 0 new-value = false +out7 0 new-value = false +in 0 new-value = true +*** simulation started *** +out0 10 new-value = true +ctrl0 10 new-value = true +*** simulation started *** +out1 13 new-value = true +out0 14 new-value = false +ctrl1 14 new-value = true +*** simulation started *** +out3 20 new-value = true +out1 21 new-value = false +ctrl2 21 new-value = true +*** simulation started *** +out7 30 new-value = true +out3 31 new-value = false +ctrl0 31 new-value = false +*** simulation started *** +out7 34 new-value = false +out6 35 new-value = true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-09.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-09.check new file mode 100644 index 0000000000..c921361db7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-09.check @@ -0,0 +1,50 @@ +Probe: f = 32 +Probe: c = 0 +Probe: f = ? +Probe: c = ? + +Probe: f = 212 +Probe: c = 100 +Probe: f = ? +Probe: c = ? + +Probe: c = 0 +Probe: f = 32 +Probe: c = ? +Probe: f = ? + +Probe: c = 100 +Probe: f = 212 +Probe: c = ? +Probe: f = ? + +0 Celsius -> 32 Fahrenheits +100 Celsius -> 212 Fahrenheits +32 Fahrenheits -> 0 Celsius +212 Fahrenheits -> 100 Celsius + +a = ?, b = ?, c = ? => ? * ? = ? +a = 2, b = ?, c = ? => 2 * ? = ? +a = ?, b = 3, c = ? => ? * 3 = ? +a = ?, b = ?, c = 6 => ? * ? = 6 +a = 2, b = 3, c = ? => 2 * 3 = 6 +a = 2, b = ?, c = 6 => 2 * 3 = 6 +a = ?, b = 3, c = 6 => 2 * 3 = 6 +a = 2, b = 3, c = 6 => 2 * 3 = 6 + +a = 0, b = ?, c = ? => 0 * ? = 0 +a = ?, b = 0, c = ? => ? * 0 = 0 +a = ?, b = ?, c = 0 => ? * ? = 0 +a = 0, b = 7, c = ? => 0 * 7 = 0 +a = 7, b = 0, c = ? => 7 * 0 = 0 +a = 0, b = 0, c = ? => 0 * 0 = 0 +a = 0, b = ?, c = 0 => 0 * ? = 0 +a = ?, b = 0, c = 0 => ? * 0 = 0 +a = 0, b = 7, c = 0 => 0 * 7 = 0 +a = 7, b = 0, c = 0 => 7 * 0 = 0 +a = 0, b = 0, c = 0 => 0 * 0 = 0 + +a = 3, b = 4 => c = 5 +a = 3, c = 5 => b = 4 +b = 4, c = 5 => a = 3 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-10.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-10.check new file mode 100644 index 0000000000..847f0fa703 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-10.check @@ -0,0 +1,46 @@ +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +fib(10) = 55 +fib(11) = 89 +fib(12) = 144 +fib(13) = 233 +fib(14) = 377 +fib(15) = 610 +fib(16) = 987 +fib(17) = 1597 +fib(18) = 2584 +fib(19) = 4181 + +pi(0) = 4 , 3.166666666666667 , 4 +pi(1) = 2.666666666666667 , 3.1333333333333337, 3.166666666666667 +pi(2) = 3.466666666666667 , 3.1452380952380956, 3.142105263157895 +pi(3) = 2.8952380952380956, 3.1396825396825396, 3.1415993573190044 +pi(4) = 3.33968253968254 , 3.142712842712843 , 3.141592714033778 +pi(5) = 2.976046176046176 , 3.140881340881341 , 3.1415926539752923 +pi(6) = 3.283738483738484 , 3.142071817071817 , 3.141592653591176 +pi(7) = 3.017071817071817 , 3.1412548236077646, 3.141592653589777 +pi(8) = 3.252365934718876 , 3.1418396189294024, 3.141592653589794 +pi(9) = 3.0418396189294024, 3.141406718496502 , 3.1415926535897936 +pi = 3.141592653589793 , 3.141592653589793 , 3.141592653589793 + +ln(0) = 1 , 0.7 , 1 +ln(1) = 0.5 , 0.6904761904761905, 0.7 +ln(2) = 0.8333333333333333, 0.6944444444444444, 0.6932773109243697 +ln(3) = 0.5833333333333333, 0.6924242424242424, 0.6931488693329254 +ln(4) = 0.7833333333333333, 0.6935897435897436, 0.6931471960735491 +ln(5) = 0.6166666666666667, 0.6928571428571428, 0.6931471806635636 +ln(6) = 0.7595238095238095, 0.6933473389355742, 0.6931471805604038 +ln(7) = 0.6345238095238095, 0.6930033416875522, 0.6931471805599444 +ln(8) = 0.7456349206349207, 0.6932539682539682, 0.6931471805599426 +ln(9) = 0.6456349206349206, 0.6930657506744463, 0.6931471805599453 +ln = 0.6931471805599453, 0.6931471805599453, 0.6931471805599453 + +prime numbers: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Meter.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Meter.check new file mode 100644 index 0000000000..f46fd557c8 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Meter.check @@ -0,0 +1,16 @@ +Meter.scala:72: warning: a.Meter and Int are unrelated: they will never compare equal + println("x == 1: "+(x == 1)) + ^ +2 +4m +false +x.isInstanceOf[Meter]: true +x.hashCode: 1 +x == 1: false +x == y: true +a == b: true +testing native arrays +Array(1m, 2m) +1m +>>>1m<<< 1m +>>>2m<<< 2m diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/MeterCaseClass.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/MeterCaseClass.check new file mode 100644 index 0000000000..ac538d240f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/MeterCaseClass.check @@ -0,0 +1,16 @@ +MeterCaseClass.scala:69: warning: comparing values of types a.Meter and Int using `==' will always yield false + println("x == 1: "+(x == 1)) + ^ +2 +Meter(4) +false +x.isInstanceOf[Meter]: true +x.hashCode: 1 +x == 1: false +x == y: true +a == b: true +testing native arrays +Array(Meter(1), Meter(2)) +Meter(1) +>>>Meter(1)<<< Meter(1) +>>>Meter(2)<<< Meter(2) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/bugs.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/bugs.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/bugs.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/caseClassHash.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/caseClassHash.check new file mode 100644 index 0000000000..f975151e9c --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/caseClassHash.check @@ -0,0 +1,9 @@ +Foo(true,-1,-1,d,-5,-10,500,500,List(),5) +Foo(true,-1,-1,d,-5,-10,500,500,List(),5) +1383698062 +1383698062 +true +## method 1: 1383698062 +## method 2: 1383698062 + Murmur 1: 1383698062 + Murmur 2: 1383698062 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/deeps.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/deeps.check new file mode 100644 index 0000000000..e533b87dc5 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/deeps.check @@ -0,0 +1,87 @@ +testEquals1 +false +false +true + +testEquals2 +false +false +true + +testEquals3 +x=Array(1) +y=Array(1) +false +false +true + +x=Array(Array(1), Array(1)) +y=Array(Array(1), Array(1)) +false +false +true + +x=Array(Array(Array(1), Array(1)), Array(Array(1), Array(1))) +y=Array(Array(Array(1), Array(1)), Array(Array(1), Array(1))) +false +false +true + +testEquals4 +false +false +true +false +false +true +Array(true, false) +Array(true, false) +[true;false] +true;false + +Array(Array(true, false), Array(true, false)) +Array(Array(true, false), Array(true, false)) +[Array(true, false);Array(true, false)] +Array(true, false);Array(true, false) + +Array(Array(Array(true, false), Array(true, false)), Array(Array(true, false), Array(true, false))) +Array(Array(Array(true, false), Array(true, false)), Array(Array(true, false), Array(true, false))) +[Array(Array(true, false), Array(true, false));Array(Array(true, false), Array(true, false))] +Array(Array(true, false), Array(true, false));Array(Array(true, false), Array(true, false)) + +Array(1, 0) +Array(1, 0) +[1;0] +1;0 + +Array(Array(1, 0), Array(1, 0)) +Array(Array(1, 0), Array(1, 0)) +[Array(1, 0);Array(1, 0)] +Array(1, 0);Array(1, 0) + +Array(Array(Array(1, 0), Array(1, 0)), Array(Array(1, 0), Array(1, 0))) +Array(Array(Array(1, 0), Array(1, 0)), Array(Array(1, 0), Array(1, 0))) +[Array(Array(1, 0), Array(1, 0));Array(Array(1, 0), Array(1, 0))] +Array(Array(1, 0), Array(1, 0));Array(Array(1, 0), Array(1, 0)) + +Array(a, b) +Array(a, b) +[a;b] +a;b + +Array(Array(a, b), Array(a, b)) +Array(Array(a, b), Array(a, b)) +[Array(a, b);Array(a, b)] +Array(a, b);Array(a, b) + +Array(Array(Array(a, b), Array(a, b)), Array(Array(a, b), Array(a, b))) +Array(Array(Array(a, b), Array(a, b)), Array(Array(a, b), Array(a, b))) +[Array(Array(a, b), Array(a, b));Array(Array(a, b), Array(a, b))] +Array(Array(a, b), Array(a, b));Array(Array(a, b), Array(a, b)) + +[Array(true, false); Array(false)] +[Array(1, 2); Array(3)] +[Array(1, 2); Array(3)] + +Array(boo, and, foo) +Array(a) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/dynamic-anyval.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/dynamic-anyval.check new file mode 100644 index 0000000000..c125372c9a --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/dynamic-anyval.check @@ -0,0 +1,4 @@ +undefined.dingo(bippy, 5) +List(1, 2, 3).dingo(bippy, 5) +undefined.dingo(bippy, 5) +List(1, 2, 3).dingo(bippy, 5) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/impconvtimes.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/impconvtimes.check new file mode 100644 index 0000000000..082377e474 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/impconvtimes.check @@ -0,0 +1 @@ +3.0 * Hour = Measure(3,Hour) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/imports.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/imports.check new file mode 100644 index 0000000000..1aad598062 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/imports.check @@ -0,0 +1,21 @@ +In C_ico, v_ico .toString() returns ↩ +↪C_ico -> ok +In C_ico, field .toString() returns ↩ +↪C_ico -> ok +In C_ico, method.toString() returns ↩ +↪C_ico -> ok + +In C_ioc, v_ioc .toString() returns ↩ +↪C_ioc -> ok +In C_ioc, field .toString() returns ↩ +↪C_ioc -> ok +In C_ioc, method.toString() returns ↩ +↪C_ioc -> ok + +In C_oic, v_oic .toString() returns ↩ +↪C_oic -> ok +In C_oic, field .toString() returns ↩ +↪C_oic -> ok +In C_oic, method.toString() returns ↩ +↪C_oic -> ok + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/interpolation.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/interpolation.check new file mode 100644 index 0000000000..9c4a77715b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/interpolation.check @@ -0,0 +1,32 @@ +Bob is 1 years old +Bob is 1 years old +Bob will be 2 years old +Bob will be 2 years old +1+1 = 2 +1+1 = 2 +Bob is 12 years old +Bob is 12 years old +Bob will be 13 years old +Bob will be 13 years old +12+1 = 13 +12+1 = 13 +Bob is 123 years old +Bob is 123 years old +Bob will be 124 years old +Bob will be 124 years old +123+1 = 124 +123+1 = 124 +Best price: 10 +Best price: 10.00 +10% discount included +10.00% discount included +Best price: 13.345000267028809 +Best price: 13.35 +13.345000267028809% discount included +13.35% discount included + +0 +00 + +0 +00 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/interpolationMultiline1.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/interpolationMultiline1.check new file mode 100644 index 0000000000..1b6e140c13 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/interpolationMultiline1.check @@ -0,0 +1,26 @@ +Bob is 1 years old +Bob is 1 years old +Bob will be 2 years old +Bob will be 2 years old +1+1 = 2 +1+1 = 2 +Bob is 12 years old +Bob is 12 years old +Bob will be 13 years old +Bob will be 13 years old +12+1 = 13 +12+1 = 13 +Bob is 123 years old +Bob is 123 years old +Bob will be 124 years old +Bob will be 124 years old +123+1 = 124 +123+1 = 124 +Best price: 10 +Best price: 10.00 +10% discount included +10.00% discount included +Best price: 13.345000267028809 +Best price: 13.35 +13.345000267028809% discount included +13.35% discount included diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/issue192.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/issue192.sem new file mode 100644 index 0000000000..10abbf7f3b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/issue192.sem @@ -0,0 +1 @@ +strictFloats diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/macro-bundle-static.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/macro-bundle-static.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/macro-bundle-static.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/macro-bundle-toplevel.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/macro-bundle-toplevel.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/macro-bundle-toplevel.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/macro-bundle-whitebox-decl.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/macro-bundle-whitebox-decl.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/macro-bundle-whitebox-decl.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/misc.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/misc.check new file mode 100644 index 0000000000..85f37c51d7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/misc.check @@ -0,0 +1,62 @@ +misc.scala:46: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 42; + ^ +misc.scala:47: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 42l; + ^ +misc.scala:48: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 23.5f; + ^ +misc.scala:49: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 23.5; + ^ +misc.scala:50: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + "Hello"; + ^ +misc.scala:51: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 32 + 45; + ^ +misc.scala:62: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + x; + ^ +misc.scala:74: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 1 < 2; + ^ +### Hello +### 17 +### Bye + +### fib(0) = ↩ +↪1 +### fib(1) = ↩ +↪1 +### fib(2) = ↩ +↪2 +### fib(3) = ↩ +↪3 +### fib(4) = ↩ +↪5 +=== MyClass::toString === +=== MySubclass::toString === +=== MyClass::test === + +identity + +A.a = 1 +B.a = 5 +B.b = 2 + +X.a = 4 +Y.a = 11 +Y.b = 5 +Y.b = 5 + +X::foo + +Y::foo +X::foo + +3 +3 + +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/promotion.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/promotion.check new file mode 100644 index 0000000000..41e36c369d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/promotion.check @@ -0,0 +1,4 @@ +2 +6 +20 +30 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/runtime.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/runtime.check new file mode 100644 index 0000000000..0450b9498a --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/runtime.check @@ -0,0 +1,70 @@ +runtime.scala:141: warning: comparing values of types Null and Null using `eq' will always yield true + check(true , null eq null, null ne null); + ^ +runtime.scala:141: warning: comparing values of types Null and Null using `ne' will always yield false + check(true , null eq null, null ne null); + ^ +<<< Test0 +[false,true] +[0,1,2] +[3,4,5] +[a,b,c] +[6,7,8] +[9,10,11] +[12,13] +[14,15] +[string] +>>> Test0 + +<<< Test1 +10 +14 +15 +16 +20 +23 +24 +25 +26 +>>> Test1 + +<<< Test2 +A +M0 +N0 + +A +N0 +M0 + +A +M0 +M1 +N0 + +A +N0 +N1 +M0 + +>>> Test2 + +<<< Test3 +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +>>> Test3 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/spec-self.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/spec-self.check new file mode 100644 index 0000000000..fd3c81a4d7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/spec-self.check @@ -0,0 +1,2 @@ +5 +5 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/structural.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/structural.check new file mode 100644 index 0000000000..2fec112a87 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/structural.check @@ -0,0 +1,37 @@ + 1. hey + 2. 11 + 3. dee + 4. iei + 5. 6 + 6. 51 + 7. 2 + 8. 11 +10. 12 +11. eitch +12. 1 +13. ohone +14. 1 +15. undefined +16. one +17. tieone +18. 2 +19. true +20. 1 +21. undefined +22. one +23. oy +24. 1 +25. null +26. iei +31. 4 +32. undefined +33. iei +33. tieone +1 +2 +3 +4 +5 +caught +3 +2 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t0421-new.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t0421-new.check new file mode 100644 index 0000000000..00d29b7e5b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t0421-new.check @@ -0,0 +1,3 @@ +[Array(0, 1),Array(2, 3),Array(4, 5)] +[Array(31)] +[Array(24, 32)] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t0421-old.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t0421-old.check new file mode 100644 index 0000000000..00d29b7e5b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t0421-old.check @@ -0,0 +1,3 @@ +[Array(0, 1),Array(2, 3),Array(4, 5)] +[Array(31)] +[Array(24, 32)] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t1503.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t1503.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t1503.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t3702.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t3702.check new file mode 100644 index 0000000000..3fce98715c --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t3702.check @@ -0,0 +1,2 @@ +undefined +6 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t4148.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t4148.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t4148.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t4617.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t4617.check new file mode 100644 index 0000000000..a6790f16f7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t4617.check @@ -0,0 +1 @@ +Str 8 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5356.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5356.check new file mode 100644 index 0000000000..870c901131 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5356.check @@ -0,0 +1,6 @@ +1 java.lang.Byte +1 java.lang.Byte +1 scala.math.BigInt +1 java.lang.Byte +1 java.lang.Byte +1 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5552.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5552.check new file mode 100644 index 0000000000..9e767b6d7b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5552.check @@ -0,0 +1,6 @@ +lazy: 3 +(3,3) +(3,3) +lazy: 3 +(3,3) +(3,3) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5568.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5568.check new file mode 100644 index 0000000000..6f30cc5070 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5568.check @@ -0,0 +1,9 @@ +void +int +class scala.runtime.BoxedUnit +class scala.runtime.BoxedUnit +class java.lang.Byte +class java.lang.Byte +5 +5 +5 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5629b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5629b.check new file mode 100644 index 0000000000..c65298a6ce --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5629b.check @@ -0,0 +1,10 @@ +=== pf(1): +MySmartPF.apply entered... +newPF.applyOrElse entered... +default +scala.MatchError: 1 (of class java.lang.Byte) +=== pf(42): +MySmartPF.apply entered... +newPF.applyOrElse entered... +ok +=== done diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5680.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5680.check new file mode 100644 index 0000000000..a3b8b64a43 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5680.check @@ -0,0 +1,3 @@ +[Lscala.runtime.BoxedUnit +undefined +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5866.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5866.check new file mode 100644 index 0000000000..64df1cec7f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5866.check @@ -0,0 +1,2 @@ +0 +Foo(0) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t6318_primitives.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t6318_primitives.check new file mode 100644 index 0000000000..654ef1beec --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t6318_primitives.check @@ -0,0 +1,54 @@ +Checking if byte matches byte +Some(1) +Checking if byte matches short +Some(1) +Checking if class java.lang.Byte matches byte +Some(1) +Checking if short matches short +Some(1) +Checking if short matches char +None +Checking if class java.lang.Byte matches short +Some(1) +Checking if char matches char +Some() +Checking if char matches int +None +Checking if class java.lang.Character matches char +Some() +Checking if int matches int +Some(1) +Checking if int matches long +None +Checking if class java.lang.Byte matches int +Some(1) +Checking if long matches long +Some(1) +Checking if long matches float +None +Checking if class java.lang.Long matches long +Some(1) +Checking if float matches float +Some(1) +Checking if float matches double +Some(1) +Checking if class java.lang.Byte matches float +Some(1) +Checking if double matches double +Some(1) +Checking if double matches boolean +None +Checking if class java.lang.Byte matches double +Some(1) +Checking if boolean matches boolean +Some(true) +Checking if boolean matches void +None +Checking if class java.lang.Boolean matches boolean +Some(true) +Checking if void matches void +Some(undefined) +Checking if void matches byte +None +Checking if class scala.runtime.BoxedUnit matches void +Some(undefined) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t6662.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t6662.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t6662.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t7657.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t7657.check new file mode 100644 index 0000000000..1a87c1e866 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t7657.check @@ -0,0 +1,3 @@ +undefined +undefined +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t7763.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t7763.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t7763.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t8570a.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t8570a.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t8570a.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t8764.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t8764.check new file mode 100644 index 0000000000..121120217e --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t8764.check @@ -0,0 +1,5 @@ +IntOnly: should return an unboxed int +Int: int +IntAndDouble: should just box and return Anyval +Double: class java.lang.Byte +Int: class java.lang.Byte diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t9387b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t9387b.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t9387b.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t9656.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t9656.check new file mode 100644 index 0000000000..a16c04eaad --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t9656.check @@ -0,0 +1,14 @@ +Range 1 to 10 +Range 1 to 10 +inexact Range 1 to 10 by 2 +Range 1 to 10 by 3 +inexact Range 1 until 10 by 2 +Range 100 to 100 +empty Range 100 until 100 +NumericRange 1 to 10 +NumericRange 1 to 10 by 2 +NumericRange 0.1 until 1 by 0.1 +NumericRange 0.1 until 1.0 by 0.1 +NumericRange 0.1 until 1 by 0.1 (using NumericRange 0.1 until 1 by 0.1 of BigDecimal) +NumericRange 0 days until 10 seconds by 1 second +empty NumericRange 0 days until 0 days by 1 second diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/try-catch-unify.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/try-catch-unify.check new file mode 100644 index 0000000000..813f01166d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/try-catch-unify.check @@ -0,0 +1,4 @@ +Failure(java.lang.NumberFormatException: For input string: "Hi") +Success(5) +O NOES +Failure(java.lang.NumberFormatException: For input string: "Hi") diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/virtpatmat_switch.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/virtpatmat_switch.check new file mode 100644 index 0000000000..0900a9ca32 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/virtpatmat_switch.check @@ -0,0 +1,7 @@ +zero +one +many +got a +got b +got some letter +scala.MatchError: 5 (of class java.lang.Byte) \ No newline at end of file diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/virtpatmat_typetag.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/virtpatmat_typetag.check new file mode 100644 index 0000000000..048c3aeed0 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/virtpatmat_typetag.check @@ -0,0 +1,10 @@ +1 is a Int +1 is a java.lang.Integer +1 is not a java.lang.String; it's a class java.lang.Byte +true is a Any +woele is a java.lang.String +1 is a Int +1 is a java.lang.Integer +1 is not a java.lang.String; it's a class java.lang.Byte +true is a Any +woele is a java.lang.String diff --git a/partest/src/main/scala/scala/tools/partest/scalajs/PartestInterface.scala b/partest/src/main/scala/scala/tools/partest/scalajs/PartestInterface.scala index dc638c2368..b0356e1622 100644 --- a/partest/src/main/scala/scala/tools/partest/scalajs/PartestInterface.scala +++ b/partest/src/main/scala/scala/tools/partest/scalajs/PartestInterface.scala @@ -21,7 +21,7 @@ object Framework { // definedTests in Test += new sbt.TestDefinition("partest", fingerprint, true, Array()) } class Framework extends _root_.sbt.testing.Framework { - def fingerprints: Array[Fingerprint] = Array(Framework.fingerprint) + def fingerprints: Array[Fingerprint] = Array[Fingerprint](Framework.fingerprint) def name: String = "partest" def runner(args: Array[String], remoteArgs: Array[String], testClassLoader: ClassLoader): _root_.sbt.testing.Runner = diff --git a/project/Build.scala b/project/Build.scala index 03c8181c6c..fe2ef6d662 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -63,9 +63,9 @@ object Build { CrossVersion.binaryMapped(v => s"sjs${previousSJSBinaryVersion}_$v") val scalaVersionsUsedForPublishing: Set[String] = - Set("2.10.6", "2.11.11", "2.12.2") + Set("2.10.6", "2.11.11", "2.12.2", "2.13.0-M1") val newScalaBinaryVersionsInThisRelease: Set[String] = - Set() + Set("2.13.0-M1") val javaVersion = settingKey[Int]( "The major Java SDK version that should be assumed for compatibility. " + @@ -360,6 +360,16 @@ object Build { } ) + private def parallelCollectionsDependencies( + scalaVersion: String): Seq[ModuleID] = { + CrossVersion.partialVersion(scalaVersion) match { + case Some((2, n)) if n >= 13 => + Seq("org.scala-lang.modules" %% "scala-parallel-collections" % "0.1.2") + + case _ => Nil + } + } + implicit class ProjectOps(val project: Project) extends AnyVal { /** Uses the Scala.js compiler plugin. */ def withScalaJSCompiler: Project = @@ -428,7 +438,8 @@ object Build { "2.11.11", "2.12.0", "2.12.1", - "2.12.2" + "2.12.2", + "2.13.0-M1" ), // JDK version we are running with javaVersion in Global := { @@ -587,12 +598,7 @@ object Build { "com.googlecode.json-simple" % "json-simple" % "1.1.1" exclude("junit", "junit"), "com.novocode" % "junit-interface" % "0.9" % "test" ) ++ ( - CrossVersion.partialVersion(scalaVersion.value) match { - case Some((2, n)) if n >= 13 => - Seq("org.scala-lang.modules" %% "scala-parallel-collections" % "0.1.1") - - case _ => Nil - } + parallelCollectionsDependencies(scalaVersion.value) ) ) ).dependsOn(irProject) @@ -1657,23 +1663,27 @@ object Build { }, libraryDependencies ++= { - if (shouldPartest.value) + if (shouldPartest.value) { Seq( - "org.scala-sbt" % "sbt" % sbtVersion.value, - { - val v = scalaVersion.value - if (v == "2.11.0" || v == "2.11.1" || v == "2.11.2") - "org.scala-lang.modules" %% "scala-partest" % "1.0.13" - else if (v.startsWith("2.11.")) - "org.scala-lang.modules" %% "scala-partest" % "1.0.16" - else - "org.scala-lang.modules" %% "scala-partest" % "1.0.17" - }, - "org.scala-js" % "closure-compiler-java-6" % "v20160517", - "io.apigee" % "rhino" % "1.7R5pre4", - "com.googlecode.json-simple" % "json-simple" % "1.1.1" exclude("junit", "junit") + "org.scala-sbt" % "sbt" % sbtVersion.value, + { + val v = scalaVersion.value + if (v == "2.11.0" || v == "2.11.1" || v == "2.11.2") + "org.scala-lang.modules" %% "scala-partest" % "1.0.13" + else if (v.startsWith("2.11.")) + "org.scala-lang.modules" %% "scala-partest" % "1.0.16" + else + "org.scala-lang.modules" %% "scala-partest" % "1.1.1" + }, + "org.scala-js" % "closure-compiler-java-6" % "v20160517", + "io.apigee" % "rhino" % "1.7R5pre4", + "com.googlecode.json-simple" % "json-simple" % "1.1.1" exclude("junit", "junit") + ) ++ ( + parallelCollectionsDependencies(scalaVersion.value) ) - else Seq() + } else { + Seq() + } }, unmanagedSourceDirectories in Compile += { diff --git a/scala-test-suite/src/test/resources/2.13.0-M1/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.13.0-M1/BlacklistedTests.txt new file mode 100644 index 0000000000..faa01b77f3 --- /dev/null +++ b/scala-test-suite/src/test/resources/2.13.0-M1/BlacklistedTests.txt @@ -0,0 +1,131 @@ +## Do not compile +scala/SerializationStabilityTest.scala +scala/lang/annotations/BytecodeTest.scala +scala/lang/annotations/RunTest.scala +scala/lang/traits/BytecodeTest.scala +scala/lang/traits/RunTest.scala +scala/lang/primitives/NaNTest.scala +scala/lang/primitives/BoxUnboxTest.scala +scala/reflect/ClassOfTest.scala +scala/reflect/QTest.scala +scala/reflect/io/ZipArchiveTest.scala +scala/reflect/internal/util/AbstractFileClassLoaderTest.scala +scala/reflect/internal/util/SourceFileTest.scala +scala/reflect/internal/util/StringOpsTest.scala +scala/reflect/internal/PrintersTest.scala +scala/reflect/internal/ScopeTest.scala +scala/reflect/internal/TreeGenTest.scala +scala/reflect/internal/TypesTest.scala +scala/reflect/internal/util/WeakHashSetTest.scala +scala/reflect/internal/MirrorsTest.scala +scala/reflect/internal/NamesTest.scala +scala/tools/nsc/backend/jvm/BTypesTest.scala +scala/tools/nsc/backend/jvm/BytecodeTest.scala +scala/tools/nsc/backend/jvm/DefaultMethodTest.scala +scala/tools/nsc/backend/jvm/DirectCompileTest.scala +scala/tools/nsc/backend/jvm/IndyLambdaTest.scala +scala/tools/nsc/backend/jvm/IndySammyTest.scala +scala/tools/nsc/backend/jvm/OptimizedBytecodeTest.scala +scala/tools/nsc/backend/jvm/StringConcatTest.scala +scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala +scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala +scala/tools/nsc/backend/jvm/opt/AnalyzerTest.scala +scala/tools/nsc/backend/jvm/opt/BTypesFromClassfileTest.scala +scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala +scala/tools/nsc/backend/jvm/opt/ClosureOptimizerTest.scala +scala/tools/nsc/backend/jvm/opt/CompactLocalVariablesTest.scala +scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala +scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala +scala/tools/nsc/backend/jvm/opt/InlineInfoTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerIllegalAccessTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerTest.scala +scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala +scala/tools/nsc/backend/jvm/opt/MethodLevelOptsTest.scala +scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala +scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala +scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala +scala/tools/nsc/backend/jvm/opt/UnusedLocalVariablesTest.scala +scala/tools/nsc/ScriptRunnerTest.scala +scala/tools/nsc/classpath/AggregateClassPathTest.scala +scala/tools/nsc/classpath/JrtClassPathTest.scala +scala/tools/nsc/classpath/PathResolverBaseTest.scala +scala/tools/nsc/classpath/VirtualDirectoryClassPathTest.scala +scala/tools/nsc/doc/html/HtmlDocletTest.scala +scala/tools/nsc/interpreter/CompletionTest.scala +scala/tools/nsc/interpreter/ScriptedTest.scala +scala/tools/nsc/interpreter/TabulatorTest.scala +scala/tools/nsc/reporters/ConsoleReporterTest.scala +scala/tools/nsc/settings/ScalaVersionTest.scala +scala/tools/nsc/settings/SettingsTest.scala +scala/tools/nsc/symtab/CannotHaveAttrsTest.scala +scala/tools/nsc/symtab/FlagsTest.scala +scala/tools/nsc/symtab/FreshNameExtractorTest.scala +scala/tools/nsc/symtab/StdNamesTest.scala +scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala +scala/tools/nsc/symtab/SymbolTableTest.scala +scala/tools/nsc/transform/delambdafy/DelambdafyTest.scala +scala/tools/nsc/transform/patmat/SolvingTest.scala +scala/tools/nsc/transform/patmat/PatmatBytecodeTest.scala +scala/tools/nsc/typechecker/Implicits.scala +scala/tools/nsc/util/StackTraceTest.scala +scala/tools/testing/BytecodeTesting.scala +scala/tools/testing/RunTesting.scala + +## Do not link +scala/CollectTest.scala +scala/PartialFunctionSerializationTest.scala +scala/lang/stringinterpol/StringContextTest.scala +scala/collection/IteratorTest.scala +scala/collection/NewBuilderTest.scala +scala/collection/SeqViewTest.scala +scala/collection/SetMapConsistencyTest.scala +scala/collection/concurrent/TrieMapTest.scala +scala/collection/convert/WrapperSerializationTest.scala +scala/collection/immutable/ListTest.scala +scala/collection/immutable/StreamTest.scala +scala/collection/immutable/StringLikeTest.scala +scala/collection/mutable/ArrayBufferTest.scala +scala/collection/mutable/MutableListTest.scala +scala/collection/mutable/OpenHashMapTest.scala +scala/collection/mutable/PriorityQueueTest.scala +scala/concurrent/duration/SerializationTest.scala +scala/concurrent/impl/DefaultPromiseTest.scala +scala/io/SourceTest.scala +scala/runtime/ScalaRunTimeTest.scala +scala/sys/process/PipedProcessTest.scala +scala/sys/process/ProcessTest.scala +scala/tools/testing/AssertUtilTest.scala +scala/tools/testing/AssertThrowsTest.scala +scala/util/SpecVersionTest.scala +scala/util/SystemPropertiesTest.scala + +# Doesn't link because of #2906 +scala/util/RandomUtilTest.scala + +## Tests fail + +# Reflection +scala/reflect/ClassTagTest.scala + +# Regex +scala/util/matching/CharRegexTest.scala +scala/util/matching/RegexTest.scala + +# Require strict-floats +scala/math/BigDecimalTest.scala + +# Difference of getClass() on primitive values +scala/collection/immutable/RangeTest.scala + +# Test fails only some times with +# 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' +# and' 'set scalaJSUseRhino in Global := false' +scala/collection/immutable/PagedSeqTest.scala + +# Bugs +scala/collection/convert/MapWrapperTest.scala + +# Tests passed but are too slow (timeouts) +scala/collection/immutable/ListSetTest.scala +scala/util/SortingTest.scala diff --git a/scala-test-suite/src/test/resources/2.13.0-M1/WhitelistedTests.txt b/scala-test-suite/src/test/resources/2.13.0-M1/WhitelistedTests.txt new file mode 100644 index 0000000000..70e77712c9 --- /dev/null +++ b/scala-test-suite/src/test/resources/2.13.0-M1/WhitelistedTests.txt @@ -0,0 +1,43 @@ +scala/CharSequenceImplicitsTests.scala +scala/collection/CollectionConversionsTest.scala +scala/collection/IndexedSeqOptimizedTest.scala +scala/collection/IndexedSeqTest.scala +scala/collection/IterableViewLikeTest.scala +scala/collection/LinearSeqOptimizedTest.scala +scala/collection/ReusableBuildersTest.scala +scala/collection/SearchingTest.scala +scala/collection/SeqLikeTest.scala +scala/collection/TraversableLikeTest.scala +scala/collection/TraversableOnceTest.scala +scala/collection/convert/NullSafetyToJavaTest.scala +scala/collection/convert/NullSafetyToScalaTest.scala +scala/collection/immutable/HashMapTest.scala +scala/collection/immutable/ListMapTest.scala +scala/collection/immutable/QueueTest.scala +scala/collection/immutable/RangeConsistencyTest.scala +scala/collection/immutable/SetTest.scala +scala/collection/immutable/TreeMapTest.scala +scala/collection/immutable/TreeSetTest.scala +scala/collection/immutable/VectorTest.scala +scala/collection/mutable/ArraySortingTest.scala +scala/collection/mutable/BitSetTest.scala +scala/collection/mutable/HashMapTest.scala +scala/collection/mutable/HashSetTest.scala +scala/collection/mutable/LinkedHashMapTest.scala +scala/collection/mutable/LinkedHashSetTest.scala +scala/collection/mutable/SetLikeTest.scala +scala/collection/mutable/TreeMapTest.scala +scala/collection/mutable/TreeSetTest.scala +scala/collection/mutable/UnrolledBufferTest.scala +scala/collection/mutable/VectorTest.scala +scala/lang/primitives/PredefAutoboxingTest.scala +scala/math/BigIntTest.scala +scala/math/NumericTest.scala +scala/math/OrderingTest.scala +scala/runtime/ZippedTest.scala +scala/tools/nsc/SampleTest.scala +scala/tools/testing/AssertUtil.scala +scala/tools/testing/TempDir.scala +scala/util/RandomTest.scala +scala/util/TryTest.scala +scala/util/control/ExceptionTest.scala diff --git a/scripts/build-all-js.sh b/scripts/build-all-js.sh index f0432062ea..6e23f098c8 100755 --- a/scripts/build-all-js.sh +++ b/scripts/build-all-js.sh @@ -3,7 +3,7 @@ tasks="fastOptJS fullOptJS" projects="helloworld/ reversi/ testingExample/test: testSuite/test:" -for v in 2.11.11 2.10.6 2.12.2; do +for v in 2.11.11 2.10.6 2.12.2 2.13.0-M1; do echo "++$v" echo "package" diff --git a/scripts/publish.sh b/scripts/publish.sh index dd6e797a29..27502988c1 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -8,8 +8,8 @@ else CMD="echo sbt" fi -FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.12.0 2.12.1 2.12.2" -BIN_VERSIONS="2.10.6 2.11.11 2.12.2" +FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.12.0 2.12.1 2.12.2 2.13.0-M1" +BIN_VERSIONS="2.10.6 2.11.11 2.12.2 2.13.0-M1" CLI_VERSIONS="2.10.6 2.11.11 2.12.2" SBT_VERSION="2.10.6" diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InstanceTestsHijackedBoxedClassesTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InstanceTestsHijackedBoxedClassesTest.scala index a0df0bedb7..71ec90d9ec 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InstanceTestsHijackedBoxedClassesTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InstanceTestsHijackedBoxedClassesTest.scala @@ -80,13 +80,13 @@ class InstanceTestsHijackedBoxedClassesTest { swallow((684321L: Any).asInstanceOf[Long]) swallow((3.14f: Any).asInstanceOf[Float]) swallow((3.14: Any).asInstanceOf[Double]) - if (scalaVersion.startsWith("2.12.")) + if (!scalaVersion.startsWith("2.10.") && !scalaVersion.startsWith("2.11.")) (12345: Any).asInstanceOf[Unit] } @Test def should_support_asInstanceOf_negative(): Unit = { assumeTrue("Assumed compliant asInstanceOf", hasCompliantAsInstanceOfs) - if (!scalaVersion.startsWith("2.12.")) + if (scalaVersion.startsWith("2.10.") || scalaVersion.startsWith("2.11.")) assertThrows(classOf[Exception], (12345: Any).asInstanceOf[Unit]) assertThrows(classOf[Exception], (12345: Any).asInstanceOf[Boolean]) assertThrows(classOf[Exception], (12345: Any).asInstanceOf[Char]) From 4881c97f6bdaafecf6d04f2f189b50ac84e7a874 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 26 Apr 2017 01:02:14 +0200 Subject: [PATCH 0227/2665] Fix #2901: Do not crash the compiler for `Int.box(???)`. This fixes the partest `run/t10069b.scala`. We do not add any test in our own test suite, because a relevant test would crash the JVM back-end in all Scala versions < 2.12.2. We rely on the partest to provide a regression test. --- .../src/main/scala/org/scalajs/core/compiler/GenJSCode.scala | 2 +- .../scala/tools/partest/scalajs/2.12.2/BuglistedTests.txt | 3 --- .../scala/tools/partest/scalajs/2.12.2/WhitelistedTests.txt | 1 + .../scala/tools/partest/scalajs/2.13.0-M1/BuglistedTests.txt | 3 --- .../scala/tools/partest/scalajs/2.13.0-M1/WhitelistedTests.txt | 1 + 5 files changed, 3 insertions(+), 7 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 195056deab..992302020c 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -2258,7 +2258,7 @@ abstract class GenJSCode extends plugins.PluginComponent } else if (currentRun.runDefinitions.isBox(sym)) { // Box a primitive value (cannot be Unit) val arg = args.head - makePrimitiveBox(genExpr(arg), arg.tpe) + makePrimitiveBox(genExpr(arg), sym.firstParam.tpe) } else if (currentRun.runDefinitions.isUnbox(sym)) { // Unbox a primitive value (cannot be Unit) val arg = args.head diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/BuglistedTests.txt index b210d1091e..273cb2c2d4 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/BuglistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/BuglistedTests.txt @@ -5,6 +5,3 @@ # Broken by GCC, filed as #2815 run/Predef.readLine.scala - -# `Int.box(???)` crashes the compiler, filed as #2901 -run/t10069b.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/WhitelistedTests.txt index aad0b42d9f..d388af436d 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/WhitelistedTests.txt @@ -3265,6 +3265,7 @@ run/t10097.scala run/t10072.scala run/t10261 run/t9114.scala +run/t10069b.scala # Adapt checkfiles for (1.0).toString == "1" run/Course-2002-01.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/BuglistedTests.txt index b210d1091e..273cb2c2d4 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/BuglistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/BuglistedTests.txt @@ -5,6 +5,3 @@ # Broken by GCC, filed as #2815 run/Predef.readLine.scala - -# `Int.box(???)` crashes the compiler, filed as #2901 -run/t10069b.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/WhitelistedTests.txt index 47f4c5b1e7..c7eb192cbd 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/WhitelistedTests.txt @@ -3265,6 +3265,7 @@ run/t10072.scala run/t10261 run/t9114.scala run/InferOverloadedPartialFunction.scala +run/t10069b.scala # Adapt checkfiles for (1.0).toString == "1" run/Course-2002-01.scala From 173ac928be1e0918224974edea08cd97a67e613e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 26 Apr 2017 01:49:31 +0200 Subject: [PATCH 0228/2665] Fix #2902: Adapt to jsdom v10. While still retaining compatibility with jsdom v9. --- .../scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala index 4da372ea41..df13d0d517 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala @@ -63,7 +63,13 @@ class JSDOMNodeJSEnv( val jsDOMCode = { s""" |(function () { - | const jsdom = require("jsdom"); + | var jsdom; + | try { + | jsdom = require("jsdom/lib/old-api.js"); // jsdom >= 10.x + | } catch (e) { + | jsdom = require("jsdom"); // jsdom <= 9.x + | } + | | var windowKeys = []; | | jsdom.env({ From a42903526a5b44e8bbee90561e65fe306f39d536 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 26 Apr 2017 11:08:28 +0200 Subject: [PATCH 0229/2665] Fix #2911: Fix doubleToLongBits for values close to a power of 2. --- .../main/scala/scala/scalajs/runtime/Bits.scala | 15 ++++++++++++++- .../testsuite/javalib/lang/DoubleTest.scala | 3 +++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/library/src/main/scala/scala/scalajs/runtime/Bits.scala b/library/src/main/scala/scala/scalajs/runtime/Bits.scala index 352df5f13b..a25e69c726 100644 --- a/library/src/main/scala/scala/scalajs/runtime/Bits.scala +++ b/library/src/main/scala/scala/scalajs/runtime/Bits.scala @@ -226,7 +226,20 @@ object Bits { val twoPowFbits = pow(2, fbits) var e = min(rawToInt(floor(log(av) / LN2)), 1023) - var f = roundToEven(av / pow(2, e) * twoPowFbits) + var twoPowE = pow(2, e) + + /* #2911: When av is very close under a power of 2 (e.g., + * 9007199254740991.0 == 2^53 - 1), `log(av) / LN2` will already round + * *up* to an `e` which is 1 too much. The `floor()` afterwards comes + * too late to fix that. + * We now decrement `e` if it ends up being too big. + */ + if (twoPowE > av) { + e -= 1 + twoPowE /= 2 + } + + var f = roundToEven(av / twoPowE * twoPowFbits) if (f / twoPowFbits >= 2) { e = e + 1 f = 1 diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/DoubleTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/DoubleTest.scala index 12bf4da068..ac79152660 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/DoubleTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/DoubleTest.scala @@ -249,6 +249,9 @@ class DoubleTest { assertEquals(0xffefffffffffffffL, f(-1.7976931348623157e308)) // largest neg normal form assertEquals(0xcd124568bc6584caL, f(-1.8790766677624813e63)) // an arbitrary neg normal form + // #2911 Normal form very close under a power of 2 + assertEquals(4845873199050653695L, f(9007199254740991.0)) + // Subnormal forms assertEquals(0x0000000000000001L, f(Double.MinPositiveValue)) // smallest pos subnormal form assertEquals(0x000fffffffffffffL, f(2.225073858507201e-308)) // largest pos subnormal form From ac19aaf95d28cf70963ddbc3db747df838ef87f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 25 Apr 2017 23:42:02 +0200 Subject: [PATCH 0230/2665] Better implementation of j.l.Math.nextUp(Double). The new implementation relies on the efficiency of `Double.doubleToLongBits` and `Double.longBitsToDouble`, which we do have on JS engines implementing typed arrays. --- .../src/main/scala/java/lang/Math.scala | 37 ++++--------------- .../testsuite/javalib/lang/MathTest.scala | 36 +++++++++++++----- 2 files changed, 33 insertions(+), 40 deletions(-) diff --git a/javalanglib/src/main/scala/java/lang/Math.scala b/javalanglib/src/main/scala/java/lang/Math.scala index 1f4b72ffb9..bb3e945840 100644 --- a/javalanglib/src/main/scala/java/lang/Math.scala +++ b/javalanglib/src/main/scala/java/lang/Math.scala @@ -97,37 +97,14 @@ object Math { } def nextUp(a: scala.Double): scala.Double = { - // js implementation of nextUp https://gist.github.com/Yaffle/4654250 - import scala.Double._ - if (a != a || a == PositiveInfinity) + if (a != a || a == scala.Double.PositiveInfinity) { a - else if (a == NegativeInfinity) - MinValue - else if (a == MaxValue) - PositiveInfinity - else if (a == 0) - MinPositiveValue - else { - def iter(x: scala.Double, xi: scala.Double, n: scala.Double): scala.Double = { - if (Math.abs(xi - x) >= 1E-16) { - val c0 = (xi + x) / 2 - val c = - if (c0 == NegativeInfinity || c0 == PositiveInfinity) - x + (xi - x) / 2 - else - c0 - if (n == c) xi - else if (a < c) iter(x = x, xi = c, n = c) - else iter(x = c, xi = xi, n = c) - } - else xi - } - val d = Math.max(Math.abs(a) * 2E-16, MinPositiveValue) - val ad = a + d - val xi0 = - if (ad == PositiveInfinity) MaxValue - else ad - iter(x = a, xi = xi0, n = a) + } else if (a == -0.0) { // also matches +0.0 but that's fine + scala.Double.MinPositiveValue + } else { + val abits = Double.doubleToLongBits(a) + val rbits = if (a > 0) abits + 1L else abits - 1L + Double.longBitsToDouble(rbits) } } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/MathTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/MathTest.scala index 08b4763c79..aca1e7cc61 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/MathTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/MathTest.scala @@ -17,6 +17,12 @@ import org.scalajs.testsuite.utils.Platform._ class MathTest { + /** Like `assertEquals` with `delta = 0.0`, but positive and negative zeros + * compare not equal. + */ + private def assertSameDouble(expected: Double, actual: Double): Unit = + assertTrue(s"expected: $expected but was: $actual", expected.equals(actual)) + @Test def abs(): Unit = { assertEquals(0, Math.abs(0)) assertEquals(42, Math.abs(42)) @@ -115,16 +121,26 @@ class MathTest { } @Test def nextUp_for_Double(): Unit = { - assertEquals(Double.PositiveInfinity, Math.nextUp(Double.PositiveInfinity), 0.0) - assertEquals(Double.MinValue, Math.nextUp(Double.NegativeInfinity), 0.0) - assertEquals(Double.PositiveInfinity, Math.nextUp(Double.MaxValue), 0.0) - assertEquals(-1.7976931348623155e+308, Math.nextUp(-Double.MaxValue), 0.0) - assertEquals(Double.PositiveInfinity, Math.nextUp(-Double.MinValue), 0.0) - assertEquals(Double.MinPositiveValue, Math.nextUp(0.0), 0.0) - assertEquals(Double.MinPositiveValue, Math.nextUp(-0.0), 0.0) - assertEquals(9007199254740992.0, Math.nextUp(9007199254740991.0), 0.0) - assertEquals(9007199254740994.0, Math.nextUp(9007199254740992.0), 0.0) - assertEquals(1 + 2.2204460492503130808472633361816E-16, Math.nextUp(1.0), 0.0) + // Specials + assertSameDouble(Double.MinPositiveValue, Math.nextUp(0.0)) + assertSameDouble(Double.MinPositiveValue, Math.nextUp(-0.0)) + assertSameDouble(Double.PositiveInfinity, Math.nextUp(Double.PositiveInfinity)) + assertSameDouble(Double.MinValue, Math.nextUp(Double.NegativeInfinity)) + assertSameDouble(Double.NaN, Math.nextUp(Double.NaN)) + + // Corner cases + val MinNormal = java.lang.Double.MIN_NORMAL + val MaxSubnormal = 2.225073858507201e-308 + assertSameDouble(Double.PositiveInfinity, Math.nextUp(Double.MaxValue)) + assertSameDouble(-1.7976931348623155e+308, Math.nextUp(Double.MinValue)) + assertSameDouble(-0.0, Math.nextUp(-Double.MinPositiveValue)) + assertSameDouble(MinNormal, Math.nextUp(MaxSubnormal)) + assertSameDouble(-MaxSubnormal, Math.nextUp(-MinNormal)) + + // Random values + assertSameDouble(9007199254740992.0, Math.nextUp(9007199254740991.0)) + assertSameDouble(9007199254740994.0, Math.nextUp(9007199254740992.0)) + assertSameDouble(1.0000000000000002, Math.nextUp(1.0)) } @Test def nextAfter_for_Double(): Unit = { From b1405ce872da37775fb13445a7947e11afe812c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 25 Apr 2017 23:55:54 +0200 Subject: [PATCH 0231/2665] Implement j.l.Math.nextDown(Double). This method was introduced in JDK 8. Its implementation is of course very similar to `nextUp`. --- .../src/main/scala/java/lang/Math.scala | 13 ++++++++- .../javalib/lang/MathTestOnJDK8.scala | 29 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/javalanglib/src/main/scala/java/lang/Math.scala b/javalanglib/src/main/scala/java/lang/Math.scala index bb3e945840..b7c86e7980 100644 --- a/javalanglib/src/main/scala/java/lang/Math.scala +++ b/javalanglib/src/main/scala/java/lang/Math.scala @@ -108,6 +108,18 @@ object Math { } } + def nextDown(a: scala.Double): scala.Double = { + if (a != a || a == scala.Double.NegativeInfinity) { + a + } else if (a == 0.0) { // also matches -0.0 but that's fine + -scala.Double.MinPositiveValue + } else { + val abits = Double.doubleToLongBits(a) + val rbits = if (a > 0) abits - 1L else abits + 1L + Double.longBitsToDouble(rbits) + } + } + def nextAfter(a: scala.Double, b: scala.Double): scala.Double = { if (b < a) -nextUp(-a) @@ -316,7 +328,6 @@ object Math { // def getExponent(a: scala.Double): scala.Int // def nextAfter(a: scala.Float, b: scala.Double): scala.Float // def nextUp(a: scala.Float): scala.Float - // def nextDown(a: scala.Double): scala.Double // def nextDown(a: scala.Float): scala.Float // def scalb(a: scala.Double, scalaFactor: scala.Int): scala.Double // def scalb(a: scala.Float, scalaFactor: scala.Int): scala.Float diff --git 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 index 31086a5d9a..4c162110b9 100644 --- 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 @@ -9,6 +9,12 @@ import org.scalajs.testsuite.utils.Platform._ class MathTestOnJDK8 { + /** Like `assertEquals` with `delta = 0.0`, but positive and negative zeros + * compare not equal. + */ + private def assertSameDouble(expected: Double, actual: Double): Unit = + assertTrue(s"expected: $expected but was: $actual", expected.equals(actual)) + @Test def addExact(): Unit = { assertEquals(0, Math.addExact(0, 0)) assertEquals(1, Math.addExact(0, 1)) @@ -285,4 +291,27 @@ class MathTestOnJDK8 { for (n <- Seq(0L, 1L, -1L, Long.MaxValue, Long.MinValue)) assertThrows(classOf[ArithmeticException], Math.floorMod(n, 0)) } + + @Test def nextDown_for_Double(): Unit = { + // Specials + assertSameDouble(-Double.MinPositiveValue, Math.nextDown(0.0)) + assertSameDouble(-Double.MinPositiveValue, Math.nextDown(-0.0)) + assertSameDouble(Double.MaxValue, Math.nextDown(Double.PositiveInfinity)) + assertSameDouble(Double.NegativeInfinity, Math.nextDown(Double.NegativeInfinity)) + assertSameDouble(Double.NaN, Math.nextDown(Double.NaN)) + + // Corner cases + val MinNormal = java.lang.Double.MIN_NORMAL + val MaxSubnormal = 2.225073858507201e-308 + assertSameDouble(1.7976931348623155e+308, Math.nextDown(Double.MaxValue)) + assertSameDouble(Double.NegativeInfinity, Math.nextDown(Double.MinValue)) + assertSameDouble(0.0, Math.nextDown(Double.MinPositiveValue)) + assertSameDouble(MaxSubnormal, Math.nextDown(MinNormal)) + assertSameDouble(-MinNormal, Math.nextDown(-MaxSubnormal)) + + // Random values + assertSameDouble(9007199254740991.0, Math.nextDown(9007199254740992.0)) + assertSameDouble(9007199254740992.0, Math.nextDown(9007199254740994.0)) + assertSameDouble(0.9999999999999999, Math.nextDown(1.0)) + } } From 66aa0885bdec69f3ae2234e3b6e7d0632c599a2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 26 Apr 2017 00:03:32 +0200 Subject: [PATCH 0232/2665] Better implementation of j.l.Math.nextAfter. Taking advantage of `nextDown` for the case `b < a`. --- .../src/main/scala/java/lang/Math.scala | 8 ++-- .../testsuite/javalib/lang/MathTest.scala | 43 +++++++++++++------ 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/javalanglib/src/main/scala/java/lang/Math.scala b/javalanglib/src/main/scala/java/lang/Math.scala index b7c86e7980..f3d9ffd494 100644 --- a/javalanglib/src/main/scala/java/lang/Math.scala +++ b/javalanglib/src/main/scala/java/lang/Math.scala @@ -121,11 +121,11 @@ object Math { } def nextAfter(a: scala.Double, b: scala.Double): scala.Double = { - if (b < a) - -nextUp(-a) - else if (a < b) + if (b > a) nextUp(a) - else if (a != a || b != b) + else if (b < a) + nextDown(a) + else if (a != a) scala.Double.NaN else b diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/MathTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/MathTest.scala index aca1e7cc61..b1a3697e7f 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/MathTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/MathTest.scala @@ -144,19 +144,36 @@ class MathTest { } @Test def nextAfter_for_Double(): Unit = { - assertTrue(Math.nextAfter(1.0, Double.NaN).isNaN) - assertTrue(Math.nextAfter(Double.NaN, 1.0).isNaN) - assertEquals(0.0, Math.nextAfter(0.0, 0.0), 0.0) - assertEquals(-0.0, Math.nextAfter(0.0, -0.0), 0.0) - assertEquals(0.0, Math.nextAfter(-0.0, 0.0), 0.0) - assertEquals(-0.0, Math.nextAfter(-0.0, -0.0), 0.0) - assertEquals(Double.NegativeInfinity, Math.nextAfter(Double.MinValue, Double.NegativeInfinity), 0.0) - assertEquals(Double.PositiveInfinity, Math.nextAfter(-Double.MinValue, Double.PositiveInfinity), 0.0) - assertEquals(Double.MaxValue, Math.nextAfter(Double.PositiveInfinity, Double.NegativeInfinity), 0.0) - assertEquals(Double.MinValue, Math.nextAfter(Double.NegativeInfinity, Double.PositiveInfinity), 0.0) - assertEquals(Double.PositiveInfinity, Math.nextAfter(Double.MaxValue, Double.PositiveInfinity), 0.0) - assertEquals(Double.NegativeInfinity, Math.nextAfter(-Double.MaxValue, Double.NegativeInfinity), 0.0) - assertEquals(1.0, Math.nextAfter(1.0, 1.0), 0.0) + assertSameDouble(Double.NaN, Math.nextAfter(Double.NaN, Double.NaN)) + assertSameDouble(Double.NaN, Math.nextAfter(1.0, Double.NaN)) + assertSameDouble(Double.NaN, Math.nextAfter(Double.NaN, 1.0)) + + assertSameDouble(0.0, Math.nextAfter(0.0, 0.0)) + assertSameDouble(-0.0, Math.nextAfter(0.0, -0.0)) + assertSameDouble(0.0, Math.nextAfter(-0.0, 0.0)) + assertSameDouble(-0.0, Math.nextAfter(-0.0, -0.0)) + + assertSameDouble(Double.PositiveInfinity, + Math.nextAfter(Double.PositiveInfinity, Double.PositiveInfinity)) + assertSameDouble(Double.NegativeInfinity, + Math.nextAfter(Double.NegativeInfinity, Double.NegativeInfinity)) + + assertSameDouble(Double.NegativeInfinity, + Math.nextAfter(Double.MinValue, Double.NegativeInfinity)) + assertSameDouble(Double.PositiveInfinity, + Math.nextAfter(-Double.MinValue, Double.PositiveInfinity)) + assertSameDouble(Double.MaxValue, + Math.nextAfter(Double.PositiveInfinity, Double.NegativeInfinity)) + assertSameDouble(Double.MinValue, + Math.nextAfter(Double.NegativeInfinity, Double.PositiveInfinity)) + assertSameDouble(Double.PositiveInfinity, + Math.nextAfter(Double.MaxValue, Double.PositiveInfinity)) + assertSameDouble(Double.NegativeInfinity, + Math.nextAfter(-Double.MaxValue, Double.NegativeInfinity)) + + assertSameDouble(1.0, Math.nextAfter(1.0, 1.0)) + assertSameDouble(1.0000000000000002, Math.nextAfter(1.0, 2.0)) + assertSameDouble(0.9999999999999999, Math.nextAfter(1.0, 0.5)) } @Test def ulp_for_Double(): Unit = { From bdbed84a913385c6de2465d10fffd7f21d3fbc41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 26 Apr 2017 00:29:01 +0200 Subject: [PATCH 0233/2665] Fix #2906: Implement j.l.Math.next{Up,Down,After} for Float. --- .../src/main/scala/java/lang/Math.scala | 38 +++++++++++- .../resources/2.13.0-M1/BlacklistedTests.txt | 3 - .../resources/2.13.0-M1/WhitelistedTests.txt | 1 + .../javalib/lang/MathTestOnJDK8.scala | 28 +++++++++ .../testsuite/javalib/lang/MathTest.scala | 61 +++++++++++++++++++ 5 files changed, 125 insertions(+), 6 deletions(-) diff --git a/javalanglib/src/main/scala/java/lang/Math.scala b/javalanglib/src/main/scala/java/lang/Math.scala index f3d9ffd494..4f2c0cf549 100644 --- a/javalanglib/src/main/scala/java/lang/Math.scala +++ b/javalanglib/src/main/scala/java/lang/Math.scala @@ -108,6 +108,18 @@ object Math { } } + def nextUp(a: scala.Float): scala.Float = { + if (a != a || a == scala.Float.PositiveInfinity) { + a + } else if (a == -0.0f) { // also matches +0.0f but that's fine + scala.Float.MinPositiveValue + } else { + val abits = Float.floatToIntBits(a) + val rbits = if (a > 0) abits + 1 else abits - 1 + Float.intBitsToFloat(rbits) + } + } + def nextDown(a: scala.Double): scala.Double = { if (a != a || a == scala.Double.NegativeInfinity) { a @@ -120,6 +132,18 @@ object Math { } } + def nextDown(a: scala.Float): scala.Float = { + if (a != a || a == scala.Float.NegativeInfinity) { + a + } else if (a == 0.0f) { // also matches -0.0f but that's fine + -scala.Float.MinPositiveValue + } else { + val abits = Float.floatToIntBits(a) + val rbits = if (a > 0) abits - 1 else abits + 1 + Float.intBitsToFloat(rbits) + } + } + def nextAfter(a: scala.Double, b: scala.Double): scala.Double = { if (b > a) nextUp(a) @@ -131,6 +155,17 @@ object Math { b } + def nextAfter(a: scala.Float, b: scala.Double): scala.Float = { + if (b > a) + nextUp(a) + else if (b < a) + nextDown(a) + else if (a != a) + scala.Float.NaN + else + b.toFloat + } + def ulp(a: scala.Double): scala.Double = { if (abs(a) == scala.Double.PositiveInfinity) scala.Double.PositiveInfinity @@ -326,9 +361,6 @@ object Math { // def copySign(magnitude: scala.Float, sign: scala.Float): scala.Float // def getExponent(a: scala.Float): scala.Int // def getExponent(a: scala.Double): scala.Int - // def nextAfter(a: scala.Float, b: scala.Double): scala.Float - // def nextUp(a: scala.Float): scala.Float - // def nextDown(a: scala.Float): scala.Float // def scalb(a: scala.Double, scalaFactor: scala.Int): scala.Double // def scalb(a: scala.Float, scalaFactor: scala.Int): scala.Float } diff --git a/scala-test-suite/src/test/resources/2.13.0-M1/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.13.0-M1/BlacklistedTests.txt index faa01b77f3..de9f1669f0 100644 --- a/scala-test-suite/src/test/resources/2.13.0-M1/BlacklistedTests.txt +++ b/scala-test-suite/src/test/resources/2.13.0-M1/BlacklistedTests.txt @@ -100,9 +100,6 @@ scala/tools/testing/AssertThrowsTest.scala scala/util/SpecVersionTest.scala scala/util/SystemPropertiesTest.scala -# Doesn't link because of #2906 -scala/util/RandomUtilTest.scala - ## Tests fail # Reflection diff --git a/scala-test-suite/src/test/resources/2.13.0-M1/WhitelistedTests.txt b/scala-test-suite/src/test/resources/2.13.0-M1/WhitelistedTests.txt index 70e77712c9..0a693b4054 100644 --- a/scala-test-suite/src/test/resources/2.13.0-M1/WhitelistedTests.txt +++ b/scala-test-suite/src/test/resources/2.13.0-M1/WhitelistedTests.txt @@ -39,5 +39,6 @@ scala/tools/nsc/SampleTest.scala scala/tools/testing/AssertUtil.scala scala/tools/testing/TempDir.scala scala/util/RandomTest.scala +scala/util/RandomUtilTest.scala scala/util/TryTest.scala scala/util/control/ExceptionTest.scala diff --git 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 index 4c162110b9..ea5d21c0bd 100644 --- 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 @@ -15,6 +15,12 @@ class MathTestOnJDK8 { private def assertSameDouble(expected: Double, actual: Double): Unit = assertTrue(s"expected: $expected but was: $actual", expected.equals(actual)) + /** Like `assertEquals` with `delta = 0.0f`, but positive and negative zeros + * compare not equal. + */ + private def assertSameFloat(expected: Float, actual: Float): Unit = + assertTrue(s"expected: $expected but was: $actual", expected.equals(actual)) + @Test def addExact(): Unit = { assertEquals(0, Math.addExact(0, 0)) assertEquals(1, Math.addExact(0, 1)) @@ -314,4 +320,26 @@ class MathTestOnJDK8 { assertSameDouble(9007199254740992.0, Math.nextDown(9007199254740994.0)) assertSameDouble(0.9999999999999999, Math.nextDown(1.0)) } + + @Test def nextDown_for_Float(): Unit = { + // Specials + assertSameFloat(-Float.MinPositiveValue, Math.nextDown(0.0f)) + assertSameFloat(-Float.MinPositiveValue, Math.nextDown(-0.0f)) + assertSameFloat(Float.MaxValue, Math.nextDown(Float.PositiveInfinity)) + assertSameFloat(Float.NegativeInfinity, Math.nextDown(Float.NegativeInfinity)) + assertSameFloat(Float.NaN, Math.nextDown(Float.NaN)) + + // Corner cases + val MinNormal = java.lang.Float.MIN_NORMAL + val MaxSubnormal = 1.1754942e-38f + assertSameFloat(3.4028233e38f, Math.nextDown(Float.MaxValue)) + assertSameFloat(Float.NegativeInfinity, Math.nextDown(Float.MinValue)) + assertSameFloat(0.0f, Math.nextDown(Float.MinPositiveValue)) + assertSameFloat(MaxSubnormal, Math.nextDown(MinNormal)) + assertSameFloat(-MinNormal, Math.nextDown(-MaxSubnormal)) + + // Random values + assertSameFloat(9007198700000000.0f, Math.nextDown(9007199300000000.0f)) + assertSameFloat(0.99999994f, Math.nextDown(1.0f)) + } } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/MathTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/MathTest.scala index b1a3697e7f..60160a132d 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/MathTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/MathTest.scala @@ -23,6 +23,12 @@ class MathTest { private def assertSameDouble(expected: Double, actual: Double): Unit = assertTrue(s"expected: $expected but was: $actual", expected.equals(actual)) + /** Like `assertEquals` with `delta = 0.0f`, but positive and negative zeros + * compare not equal. + */ + private def assertSameFloat(expected: Float, actual: Float): Unit = + assertTrue(s"expected: $expected but was: $actual", expected.equals(actual)) + @Test def abs(): Unit = { assertEquals(0, Math.abs(0)) assertEquals(42, Math.abs(42)) @@ -143,6 +149,28 @@ class MathTest { assertSameDouble(1.0000000000000002, Math.nextUp(1.0)) } + @Test def nextUp_for_Float(): Unit = { + // Specials + assertSameFloat(Float.MinPositiveValue, Math.nextUp(0.0f)) + assertSameFloat(Float.MinPositiveValue, Math.nextUp(-0.0f)) + assertSameFloat(Float.PositiveInfinity, Math.nextUp(Float.PositiveInfinity)) + assertSameFloat(Float.MinValue, Math.nextUp(Float.NegativeInfinity)) + assertSameFloat(Float.NaN, Math.nextUp(Float.NaN)) + + // Corner cases + val MinNormal = java.lang.Float.MIN_NORMAL + val MaxSubnormal = 1.1754942e-38f + assertSameFloat(Float.PositiveInfinity, Math.nextUp(Float.MaxValue)) + assertSameFloat(-3.4028233e38f, Math.nextUp(Float.MinValue)) + assertSameFloat(-0.0f, Math.nextUp(-Float.MinPositiveValue)) + assertSameFloat(MinNormal, Math.nextUp(MaxSubnormal)) + assertSameFloat(-MaxSubnormal, Math.nextUp(-MinNormal)) + + // Random values + assertSameFloat(9007200300000000.0f, Math.nextUp(9007199300000000.0f)) + assertSameFloat(1.0000001f, Math.nextUp(1.0f)) + } + @Test def nextAfter_for_Double(): Unit = { assertSameDouble(Double.NaN, Math.nextAfter(Double.NaN, Double.NaN)) assertSameDouble(Double.NaN, Math.nextAfter(1.0, Double.NaN)) @@ -176,6 +204,39 @@ class MathTest { assertSameDouble(0.9999999999999999, Math.nextAfter(1.0, 0.5)) } + @Test def nextAfter_for_Float(): Unit = { + assertSameFloat(Float.NaN, Math.nextAfter(Float.NaN, Double.NaN)) + assertSameFloat(Float.NaN, Math.nextAfter(1.0f, Double.NaN)) + assertSameFloat(Float.NaN, Math.nextAfter(Float.NaN, 1.0)) + + assertSameFloat(0.0f, Math.nextAfter(0.0f, 0.0)) + assertSameFloat(-0.0f, Math.nextAfter(0.0f, -0.0)) + assertSameFloat(0.0f, Math.nextAfter(-0.0f, 0.0)) + assertSameFloat(-0.0f, Math.nextAfter(-0.0f, -0.0)) + + assertSameFloat(Float.PositiveInfinity, + Math.nextAfter(Float.PositiveInfinity, Double.PositiveInfinity)) + assertSameFloat(Float.NegativeInfinity, + Math.nextAfter(Float.NegativeInfinity, Double.NegativeInfinity)) + + assertSameFloat(Float.NegativeInfinity, + Math.nextAfter(Float.MinValue, Double.NegativeInfinity)) + assertSameFloat(Float.PositiveInfinity, + Math.nextAfter(-Float.MinValue, Double.PositiveInfinity)) + assertSameFloat(Float.MaxValue, + Math.nextAfter(Float.PositiveInfinity, Double.NegativeInfinity)) + assertSameFloat(Float.MinValue, + Math.nextAfter(Float.NegativeInfinity, Double.PositiveInfinity)) + assertSameFloat(Float.PositiveInfinity, + Math.nextAfter(Float.MaxValue, Double.PositiveInfinity)) + assertSameFloat(Float.NegativeInfinity, + Math.nextAfter(-Float.MaxValue, Double.NegativeInfinity)) + + assertSameFloat(1.0f, Math.nextAfter(1.0f, 1.0)) + assertSameFloat(1.0000001f, Math.nextAfter(1.0f, 2.0)) + assertSameFloat(0.99999994f, Math.nextAfter(1.0f, 0.5)) + } + @Test def ulp_for_Double(): Unit = { assertEquals(4.440892098500626E-16, Math.ulp(3.4), 0.0) assertEquals(4.1718496795330275E93, Math.ulp(3.423E109), 0.0) From 1492b04cb4eba3c064b5445a2a42bb23787388eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 26 Apr 2017 17:12:16 +0200 Subject: [PATCH 0234/2665] Increase the memory for the bootstrap test to 3G. --- ci/matrix.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/matrix.xml b/ci/matrix.xml index c881149c03..9edfc6be9e 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -203,9 +203,9 @@ From 4ed1957edfecae93ca7a70cc068a62ac86e4399f Mon Sep 17 00:00:00 2001 From: Jiri Martinek Date: Mon, 20 Mar 2017 09:09:37 +0100 Subject: [PATCH 0235/2665] Fix #2821: Adapt column pos in source maps for printEscapeJS --- ir/src/main/scala/org/scalajs/core/ir/Utils.scala | 12 ++++++++++-- project/BinaryIncompatibilities.scala | 3 +++ .../org/scalajs/core/tools/javascript/Printers.scala | 11 ++++++++--- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Utils.scala b/ir/src/main/scala/org/scalajs/core/ir/Utils.scala index 9546d9a040..beacfd19f9 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Utils.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Utils.scala @@ -75,12 +75,13 @@ object Utils { sb.toString } - def printEscapeJS(str: String, out: java.lang.Appendable): Unit = { + def printEscapeJS(str: String, out: java.lang.Appendable): Int = { /* Note that Java and JavaScript happen to use the same encoding for * Unicode, namely UTF-16, which means that 1 char from Java always equals * 1 char in JavaScript. */ val end = str.length() var i = 0 + var writtenChars = 0 /* Loop prints all consecutive ASCII printable characters starting * from current i and one non ASCII printable character (if it exists). * The new i is set at the end of the appended characters. @@ -95,8 +96,10 @@ object Utils { c = str.charAt(i) } // Print ASCII printable characters from `start` - if (start != i) + if (start != i) { out.append(str, start, i) + writtenChars += i + } // Print next non ASCII printable character if (i != end) { @@ -104,18 +107,23 @@ object Utils { if (6 < c && c < 14) { val i = 2 * (c - 7) out.append(EscapeJSChars, i, i + 2) + writtenChars += 2 } else if (c == 34) { out.append(EscapeJSChars, 14, 16) + writtenChars += 2 } else if (c == 92) { out.append(EscapeJSChars, 16, 18) + writtenChars += 2 } else { out.append(f"\\u$c%04x") + writtenChars += 6 } } escapeJSEncoded(c) i += 1 } } + writtenChars } /** A ByteArrayOutput stream that allows to jump back to a given diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index c77318b933..71c9aa2bcb 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -3,6 +3,9 @@ import com.typesafe.tools.mima.core.ProblemFilters._ object BinaryIncompatibilities { val IR = Seq( + // Breaking: Utils.printEscapeJS now returns Int + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.core.ir.Utils.printEscapeJS") ) val Tools = Seq( diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala index 9aa744982e..5274965557 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala @@ -22,7 +22,6 @@ import org.scalajs.core.ir import ir.Position import ir.Position.NoPosition import ir.Printers.IndentationManager -import ir.Utils.printEscapeJS import Trees._ @@ -471,7 +470,7 @@ object Printers { case StringLiteral(value) => print('\"') - printEscapeJS(value, out) + printEscapeJS(value) print('\"') // Atomic expressions @@ -555,8 +554,11 @@ object Printers { } } + protected def printEscapeJS(s: String): Unit = + ir.Utils.printEscapeJS(s, out) + protected def print(ident: Ident): Unit = - printEscapeJS(ident.name, out) + printEscapeJS(ident.name) private final def print(propName: PropertyName): Unit = propName match { case lit: StringLiteral => print(lit: Tree) @@ -596,6 +598,9 @@ object Printers { sourceMap.endNode(column) } + override protected def printEscapeJS(s: String): Unit = + column += ir.Utils.printEscapeJS(s, out) + override protected def print(ident: Ident): Unit = { if (ident.pos.isDefined) sourceMap.startNode(column, ident.pos, ident.originalName) From 5b6b8511cd8ec63fe8ca40c03cfa9889d72690d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 26 Apr 2017 17:40:10 +0200 Subject: [PATCH 0236/2665] Separate the override of ArrayBuilder in 2.10 and 2.11. So that we can modify it for 2.11 in isolation later. --- .../collection/mutable/ArrayBuilder.scala | 0 .../collection/mutable/ArrayBuilder.scala | 765 ++++++++++++++++++ 2 files changed, 765 insertions(+) rename scalalib/{overrides => overrides-2.10}/scala/collection/mutable/ArrayBuilder.scala (100%) create mode 100644 scalalib/overrides-2.11/scala/collection/mutable/ArrayBuilder.scala diff --git a/scalalib/overrides/scala/collection/mutable/ArrayBuilder.scala b/scalalib/overrides-2.10/scala/collection/mutable/ArrayBuilder.scala similarity index 100% rename from scalalib/overrides/scala/collection/mutable/ArrayBuilder.scala rename to scalalib/overrides-2.10/scala/collection/mutable/ArrayBuilder.scala diff --git a/scalalib/overrides-2.11/scala/collection/mutable/ArrayBuilder.scala b/scalalib/overrides-2.11/scala/collection/mutable/ArrayBuilder.scala new file mode 100644 index 0000000000..0fc80a54ac --- /dev/null +++ b/scalalib/overrides-2.11/scala/collection/mutable/ArrayBuilder.scala @@ -0,0 +1,765 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala +package collection +package mutable + +import scala.reflect.ClassTag +import scala.runtime.BoxedUnit + +import scala.scalajs.js + +/** A builder class for arrays. + * + * @since 2.8 + * + * @tparam T the type of the elements for the builder. + */ +abstract class ArrayBuilder[T] extends Builder[T, Array[T]] with Serializable + +/** A companion object for array builders. + * + * @since 2.8 + */ +object ArrayBuilder { + + /** Creates a new arraybuilder of type `T`. + * + * @tparam T type of the elements for the array builder, with a `ClassTag` context bound. + * @return a new empty array builder. + */ + @inline + def make[T: ClassTag](): ArrayBuilder[T] = + new ArrayBuilder.generic[T](implicitly[ClassTag[T]].runtimeClass) + + /** A generic ArrayBuilder optimized for Scala.js. + * + * @tparam T type of elements for the array builder. + * @param elementClass runtime class of the elements in the array. + */ + @inline + private final class generic[T](elementClass: Class[_]) extends ArrayBuilder[T] { + + private val isCharArrayBuilder = classOf[Char] == elementClass + private val elems: js.Array[Any] = js.Array() + + def +=(elem: T): this.type = { + val unboxedElem = + if (isCharArrayBuilder) elem.asInstanceOf[Char].toInt + else if (elem == null) zeroOf(elementClass) + else elem + elems.push(unboxedElem) + this + } + + def clear(): Unit = + elems.length = 0 + + def result(): Array[T] = { + val elemRuntimeClass = + if (classOf[Unit] == elementClass) classOf[BoxedUnit] + else if (classOf[Null] == elementClass || classOf[Nothing] == elementClass) classOf[Object] + else elementClass + genericArrayBuilderResult(elemRuntimeClass, elems) + } + + override def toString(): String = "ArrayBuilder.generic" + } + + // Intrinsic + private def zeroOf(runtimeClass: Class[_]): Any = runtimeClass match { + case java.lang.Byte.TYPE => 0.toByte + case java.lang.Short.TYPE => 0.toShort + case java.lang.Character.TYPE => 0 // yes, as an Int + case java.lang.Integer.TYPE => 0 + case java.lang.Long.TYPE => 0L + case java.lang.Float.TYPE => 0.0f + case java.lang.Double.TYPE => 0.0 + case java.lang.Boolean.TYPE => false + case java.lang.Void.TYPE => () + case _ => null + } + + // Intrinsic + private def genericArrayBuilderResult[T](runtimeClass: Class[_], + a: js.Array[Any]): Array[T] = { + val len = a.length + + if (classOf[Char] == runtimeClass) { + val result = new Array[Char](len) + var i = 0 + while (i != len) { + result(i) = a(i).asInstanceOf[Int].toChar + i += 1 + } + result.asInstanceOf[Array[T]] + } else { + val result: Array[T] = java.lang.reflect.Array.newInstance( + runtimeClass, len).asInstanceOf[Array[T]] + var i = 0 + while (i != len) { + result(i) = a(i).asInstanceOf[T] + i += 1 + } + result + } + } + + /** A class for array builders for arrays of reference types. + * + * @tparam T type of elements for the array builder, subtype of `AnyRef` with a `ClassTag` context bound. + */ + @deprecatedInheritance("ArrayBuilder.ofRef is an internal implementation not intended for subclassing.", "2.11.0") + class ofRef[T <: AnyRef : ClassTag] extends ArrayBuilder[T] { + + private var elems: Array[T] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[T] = { + val newelems = new Array[T](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: T): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[T]): this.type = (xs.asInstanceOf[AnyRef]) match { + case xs: WrappedArray.ofRef[_] => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { + size = 0 + } + + def result() = { + if (capacity != 0 && capacity == size) elems + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofRef[_] => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofRef" + } + + /** A class for array builders for arrays of `byte`s. */ + @deprecatedInheritance("ArrayBuilder.ofByte is an internal implementation not intended for subclassing.", "2.11.0") + class ofByte extends ArrayBuilder[Byte] { + + private var elems: Array[Byte] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[Byte] = { + val newelems = new Array[Byte](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Byte): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Byte]): this.type = xs match { + case xs: WrappedArray.ofByte => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { + size = 0 + } + + def result() = { + if (capacity != 0 && capacity == size) elems + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofByte => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofByte" + } + + /** A class for array builders for arrays of `short`s. */ + @deprecatedInheritance("ArrayBuilder.ofShort is an internal implementation not intended for subclassing.", "2.11.0") + class ofShort extends ArrayBuilder[Short] { + + private var elems: Array[Short] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[Short] = { + val newelems = new Array[Short](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Short): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Short]): this.type = xs match { + case xs: WrappedArray.ofShort => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { + size = 0 + } + + def result() = { + if (capacity != 0 && capacity == size) elems + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofShort => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofShort" + } + + /** A class for array builders for arrays of `char`s. */ + @deprecatedInheritance("ArrayBuilder.ofChar is an internal implementation not intended for subclassing.", "2.11.0") + class ofChar extends ArrayBuilder[Char] { + + private var elems: Array[Char] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[Char] = { + val newelems = new Array[Char](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Char): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Char]): this.type = xs match { + case xs: WrappedArray.ofChar => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { + size = 0 + } + + def result() = { + if (capacity != 0 && capacity == size) elems + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofChar => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofChar" + } + + /** A class for array builders for arrays of `int`s. */ + @deprecatedInheritance("ArrayBuilder.ofInt is an internal implementation not intended for subclassing.", "2.11.0") + class ofInt extends ArrayBuilder[Int] { + + private var elems: Array[Int] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[Int] = { + val newelems = new Array[Int](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Int): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Int]): this.type = xs match { + case xs: WrappedArray.ofInt => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { + size = 0 + } + + def result() = { + if (capacity != 0 && capacity == size) elems + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofInt => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofInt" + } + + /** A class for array builders for arrays of `long`s. */ + @deprecatedInheritance("ArrayBuilder.ofLong is an internal implementation not intended for subclassing.", "2.11.0") + class ofLong extends ArrayBuilder[Long] { + + private var elems: Array[Long] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[Long] = { + val newelems = new Array[Long](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Long): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Long]): this.type = xs match { + case xs: WrappedArray.ofLong => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { + size = 0 + } + + def result() = { + if (capacity != 0 && capacity == size) elems + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofLong => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofLong" + } + + /** A class for array builders for arrays of `float`s. */ + @deprecatedInheritance("ArrayBuilder.ofFloat is an internal implementation not intended for subclassing.", "2.11.0") + class ofFloat extends ArrayBuilder[Float] { + + private var elems: Array[Float] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[Float] = { + val newelems = new Array[Float](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Float): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Float]): this.type = xs match { + case xs: WrappedArray.ofFloat => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { + size = 0 + } + + def result() = { + if (capacity != 0 && capacity == size) elems + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofFloat => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofFloat" + } + + /** A class for array builders for arrays of `double`s. */ + @deprecatedInheritance("ArrayBuilder.ofDouble is an internal implementation not intended for subclassing.", "2.11.0") + class ofDouble extends ArrayBuilder[Double] { + + private var elems: Array[Double] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[Double] = { + val newelems = new Array[Double](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Double): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Double]): this.type = xs match { + case xs: WrappedArray.ofDouble => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { + size = 0 + } + + def result() = { + if (capacity != 0 && capacity == size) elems + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofDouble => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofDouble" + } + + /** A class for array builders for arrays of `boolean`s. */ + class ofBoolean extends ArrayBuilder[Boolean] { + + private var elems: Array[Boolean] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[Boolean] = { + val newelems = new Array[Boolean](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Boolean): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Boolean]): this.type = xs match { + case xs: WrappedArray.ofBoolean => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { + size = 0 + } + + def result() = { + if (capacity != 0 && capacity == size) elems + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofBoolean => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofBoolean" + } + + /** A class for array builders for arrays of `Unit` type. */ + @deprecatedInheritance("ArrayBuilder.ofUnit is an internal implementation not intended for subclassing.", "2.11.0") + class ofUnit extends ArrayBuilder[Unit] { + + private var elems: Array[Unit] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[Unit] = { + val newelems = new Array[Unit](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Unit): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Unit]): this.type = xs match { + case xs: WrappedArray.ofUnit => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { + size = 0 + } + + def result() = { + if (capacity != 0 && capacity == size) elems + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofUnit => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofUnit" + } +} From 6d441f63f9fcd90ac811ae4100c8f95f5697ded3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 26 Apr 2017 17:40:58 +0200 Subject: [PATCH 0237/2665] Fix #2717: Make ArrayBuilder reusable in 2.11. This is a backport of https://github.com/scala/scala/commit/23040fe8da1dfd0595f7904211b8e391dceb78a6 to our override of `ArrayBuilder` for 2.11, combined with the changes of 4f3115f63e4a1225cae80fa4b7193ec3c3510a2d to `ArrayBuilder.generic`. --- .../resources/2.11.11/BlacklistedTests.txt | 5 +- .../resources/2.11.11/WhitelistedTests.txt | 1 + .../collection/mutable/ArrayBuilder.scala | 54 ++++++++++++++----- 3 files changed, 44 insertions(+), 16 deletions(-) diff --git a/scala-test-suite/src/test/resources/2.11.11/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.11.11/BlacklistedTests.txt index cdd52e55b1..67ab88dc99 100644 --- a/scala-test-suite/src/test/resources/2.11.11/BlacklistedTests.txt +++ b/scala-test-suite/src/test/resources/2.11.11/BlacklistedTests.txt @@ -87,10 +87,7 @@ scala/util/SortingTest.scala # Bugs scala/collection/convert/MapWrapperTest.scala -# Bug #2717 (ArrayBuilder needs to be reusable) -scala/collection/mutable/ArrayBuilderTest.scala - # Test fails only some times with # 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' # and' 'set scalaJSUseRhino in Global := false' -scala/collection/immutable/PagedSeqTest.scala \ No newline at end of file +scala/collection/immutable/PagedSeqTest.scala diff --git a/scala-test-suite/src/test/resources/2.11.11/WhitelistedTests.txt b/scala-test-suite/src/test/resources/2.11.11/WhitelistedTests.txt index b59d7b5f4c..821b37cdc7 100644 --- a/scala-test-suite/src/test/resources/2.11.11/WhitelistedTests.txt +++ b/scala-test-suite/src/test/resources/2.11.11/WhitelistedTests.txt @@ -9,6 +9,7 @@ scala/collection/immutable/SetTests.scala scala/collection/immutable/TreeMapTest.scala scala/collection/immutable/TreeSetTest.scala scala/collection/immutable/VectorTest.scala +scala/collection/mutable/ArrayBuilderTest.scala scala/collection/mutable/ArraySortingTest.scala scala/collection/mutable/BitSetTest.scala scala/collection/mutable/LinkedHashMapTest.scala diff --git a/scalalib/overrides-2.11/scala/collection/mutable/ArrayBuilder.scala b/scalalib/overrides-2.11/scala/collection/mutable/ArrayBuilder.scala index 0fc80a54ac..31f67a3931 100644 --- a/scalalib/overrides-2.11/scala/collection/mutable/ArrayBuilder.scala +++ b/scalalib/overrides-2.11/scala/collection/mutable/ArrayBuilder.scala @@ -47,7 +47,7 @@ object ArrayBuilder { private final class generic[T](elementClass: Class[_]) extends ArrayBuilder[T] { private val isCharArrayBuilder = classOf[Char] == elementClass - private val elems: js.Array[Any] = js.Array() + private var elems: js.Array[Any] = js.Array() def +=(elem: T): this.type = { val unboxedElem = @@ -59,7 +59,7 @@ object ArrayBuilder { } def clear(): Unit = - elems.length = 0 + elems = js.Array() def result(): Array[T] = { val elemRuntimeClass = @@ -167,7 +167,10 @@ object ArrayBuilder { } def result() = { - if (capacity != 0 && capacity == size) elems + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } else mkArray(size) } @@ -232,7 +235,10 @@ object ArrayBuilder { } def result() = { - if (capacity != 0 && capacity == size) elems + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } else mkArray(size) } @@ -297,7 +303,10 @@ object ArrayBuilder { } def result() = { - if (capacity != 0 && capacity == size) elems + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } else mkArray(size) } @@ -362,7 +371,10 @@ object ArrayBuilder { } def result() = { - if (capacity != 0 && capacity == size) elems + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } else mkArray(size) } @@ -427,7 +439,10 @@ object ArrayBuilder { } def result() = { - if (capacity != 0 && capacity == size) elems + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } else mkArray(size) } @@ -492,7 +507,10 @@ object ArrayBuilder { } def result() = { - if (capacity != 0 && capacity == size) elems + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } else mkArray(size) } @@ -557,7 +575,10 @@ object ArrayBuilder { } def result() = { - if (capacity != 0 && capacity == size) elems + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } else mkArray(size) } @@ -622,7 +643,10 @@ object ArrayBuilder { } def result() = { - if (capacity != 0 && capacity == size) elems + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } else mkArray(size) } @@ -686,7 +710,10 @@ object ArrayBuilder { } def result() = { - if (capacity != 0 && capacity == size) elems + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } else mkArray(size) } @@ -751,7 +778,10 @@ object ArrayBuilder { } def result() = { - if (capacity != 0 && capacity == size) elems + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } else mkArray(size) } From 3dda2910c51a9777cbb89f79e3a2b367432f608b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 27 Apr 2017 13:30:27 +0200 Subject: [PATCH 0238/2665] Fix #2914: Update the scalaVersion in referencedCrossProject. --- sbt-plugin-test/referencedCrossProject/build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbt-plugin-test/referencedCrossProject/build.sbt b/sbt-plugin-test/referencedCrossProject/build.sbt index b70cee7c58..4539fcc61a 100644 --- a/sbt-plugin-test/referencedCrossProject/build.sbt +++ b/sbt-plugin-test/referencedCrossProject/build.sbt @@ -1,7 +1,7 @@ lazy val referencedCrossProject = crossProject. crossType(CrossType.Pure). in(file(".")). - settings(scalaVersion := "2.11.8") + settings(scalaVersion := "2.11.11") lazy val referencedCrossProjectJS = referencedCrossProject.js lazy val referencedCrossProjectJVM = referencedCrossProject.jvm From f8972a235694fb7d8b3663a376a7f832168398ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 27 Apr 2017 13:32:56 +0200 Subject: [PATCH 0239/2665] Bump the timeout for Jenkins jobs to 35 minutes. Previously it was 25 minutes, but recently, that started to be too short from time to time. --- ci/jenkins-track/scalajs-task-worker.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/jenkins-track/scalajs-task-worker.sh b/ci/jenkins-track/scalajs-task-worker.sh index ff450fa546..b1b968092f 100644 --- a/ci/jenkins-track/scalajs-task-worker.sh +++ b/ci/jenkins-track/scalajs-task-worker.sh @@ -35,7 +35,7 @@ echo '}' >> tmp.sh # Define sbt and sbtretry echo 'sbtretry() {' >> tmp.sh -echo ' local TIMEOUT=25m' >> tmp.sh +echo ' local TIMEOUT=35m' >> tmp.sh echo ' echo "RUNNING timeout -k 5 $TIMEOUT sbt" "$@"' >> tmp.sh echo ' timeout -k 5 $TIMEOUT sbt $SBT_OPTS "$@"' >> tmp.sh echo ' local CODE=$?' >> tmp.sh From 99911a1ade2176fcaaaffce54f088a924d00e198 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 27 Apr 2017 13:50:52 +0200 Subject: [PATCH 0240/2665] Fix #2915: Blacklist neg/t7014 on 2.12.1. --- .../scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt | 3 +++ .../scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt index f0081eb856..31621c01a7 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt @@ -19,6 +19,9 @@ neg/t7494-right-after-before neg/t7622-multi-followers neg/t7622-cyclic-dependency +# Wants an old version of partest for the exact error message +neg/t7014 + # Uses some strange macro cross compile mechanism. neg/macro-incompatible-macro-engine-c.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt index f69bee00b7..28cddc79fe 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt @@ -3278,7 +3278,6 @@ pos/t7551 pos/t6978 pos/t7046-2 neg/t9953.scala -neg/t7014 neg/t7046-2 neg/t7046 run/t7046-1 From c2fc80f6c5a01dbac03812bf36b76aa8e120af8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 27 Apr 2017 17:09:14 +0200 Subject: [PATCH 0241/2665] Version 0.6.16. --- ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index 012d1ead12..514a0e6876 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.16-SNAPSHOT" + val current: String = "0.6.16" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" From 85e3264f404e8b74a38e2a981c203cbec235d9d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 28 Apr 2017 13:41:37 +0200 Subject: [PATCH 0242/2665] Towards 0.6.17. --- ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- project/BinaryIncompatibilities.scala | 3 --- project/Build.scala | 4 ++-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index 514a0e6876..2d405144d8 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.16" + val current: String = "0.6.17-SNAPSHOT" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 71c9aa2bcb..c77318b933 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -3,9 +3,6 @@ import com.typesafe.tools.mima.core.ProblemFilters._ object BinaryIncompatibilities { val IR = Seq( - // Breaking: Utils.printEscapeJS now returns Int - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.core.ir.Utils.printEscapeJS") ) val Tools = Seq( diff --git a/project/Build.scala b/project/Build.scala index fe2ef6d662..e65373f0c7 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -56,7 +56,7 @@ object Build { val shouldPartest = settingKey[Boolean]( "Whether we should partest the current scala version (and fail if we can't)") - val previousVersion = "0.6.15" + val previousVersion = "0.6.16" val previousSJSBinaryVersion = ScalaJSCrossVersion.binaryScalaJSVersion(previousVersion) val previousBinaryCrossVersion = @@ -65,7 +65,7 @@ object Build { val scalaVersionsUsedForPublishing: Set[String] = Set("2.10.6", "2.11.11", "2.12.2", "2.13.0-M1") val newScalaBinaryVersionsInThisRelease: Set[String] = - Set("2.13.0-M1") + Set() val javaVersion = settingKey[Int]( "The major Java SDK version that should be assumed for compatibility. " + From 52f07452808529a0c789875a24ad8163c64c2172 Mon Sep 17 00:00:00 2001 From: Tom Green Date: Wed, 26 Apr 2017 21:55:15 -0400 Subject: [PATCH 0243/2665] Implement Integer.reverse() and Long.reverse() --- .../src/main/scala/java/lang/Integer.scala | 7 +++ .../src/main/scala/java/lang/Long.scala | 7 +++ .../testsuite/javalib/lang/IntegerTest.scala | 44 ++++++++++++++++++ .../testsuite/javalib/lang/LongTest.scala | 45 +++++++++++++++++++ 4 files changed, 103 insertions(+) diff --git a/javalanglib/src/main/scala/java/lang/Integer.scala b/javalanglib/src/main/scala/java/lang/Integer.scala index fe687fac8d..a550e1b13b 100644 --- a/javalanglib/src/main/scala/java/lang/Integer.scala +++ b/javalanglib/src/main/scala/java/lang/Integer.scala @@ -186,6 +186,13 @@ object Integer { byte0 | byte1 | byte2 | byte3 } + def reverse(i: scala.Int): scala.Int = { + // From Hacker's Delight, 7-1, Figure 7-1 + val j = (i & 0x55555555) << 1 | (i >> 1) & 0x55555555 + val k = (j & 0x33333333) << 2 | (j >> 2) & 0x33333333 + reverseBytes((k & 0x0F0F0F0F) << 4 | (k >> 4) & 0x0F0F0F0F) + } + @inline def rotateLeft(i: scala.Int, distance: scala.Int): scala.Int = (i << distance) | (i >>> -distance) diff --git a/javalanglib/src/main/scala/java/lang/Long.scala b/javalanglib/src/main/scala/java/lang/Long.scala index 2a3c5a645a..1ed00d63b4 100644 --- a/javalanglib/src/main/scala/java/lang/Long.scala +++ b/javalanglib/src/main/scala/java/lang/Long.scala @@ -390,6 +390,13 @@ object Long { Integer.reverseBytes(i.toInt)) } + @inline + def reverse(i: scala.Long): scala.Long = { + makeLongFromLoHi( + Integer.reverse((i >>> 32).toInt), + Integer.reverse(i.toInt)) + } + /** Make a `Long` value from its lo and hi 32-bit parts. * When the optimizer is enabled, this operation is free. */ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/IntegerTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/IntegerTest.scala index 0dc409cf71..e8c5dbf692 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/IntegerTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/IntegerTest.scala @@ -21,6 +21,50 @@ class IntegerTest { @Test def `reverseBytes`(): Unit = { assertEquals(0xefbeadde, Integer.reverseBytes(0xdeadbeef)) + assertEquals(0x06d2d0eb, Integer.reverseBytes(0xebd0d206)) + assertEquals(0x17ec72cb, Integer.reverseBytes(0xcb72ec17)) + assertEquals(0x1c39d445, Integer.reverseBytes(0x45d4391c)) + assertEquals(0x26e6a938, Integer.reverseBytes(0x38a9e626)) + assertEquals(0x25fe71f0, Integer.reverseBytes(0xf071fe25)) + assertEquals(0x83f9264a, Integer.reverseBytes(0x4a26f983)) + assertEquals(0x9d61d874, Integer.reverseBytes(0x74d8619d)) + assertEquals(0x87e29d58, Integer.reverseBytes(0x589de287)) + assertEquals(0x98285c65, Integer.reverseBytes(0x655c2898)) + assertEquals(0x74e056e3, Integer.reverseBytes(0xe356e074)) + assertEquals(0x690eefd8, Integer.reverseBytes(0xd8ef0e69)) + assertEquals(0x1781a1a9, Integer.reverseBytes(0xa9a18117)) + assertEquals(0xb5bf9038, Integer.reverseBytes(0x3890bfb5)) + assertEquals(0xb6b88486, Integer.reverseBytes(0x8684b8b6)) + assertEquals(0xeed8df38, Integer.reverseBytes(0x38dfd8ee)) + assertEquals(0x70710c82, Integer.reverseBytes(0x820c7170)) + assertEquals(0xdbe10fb3, Integer.reverseBytes(0xb30fe1db)) + assertEquals(0xd65911ea, Integer.reverseBytes(0xea1159d6)) + assertEquals(0x1565fdb3, Integer.reverseBytes(0xb3fd6515)) + assertEquals(0xe90f0076, Integer.reverseBytes(0x76000fe9)) + } + + @Test def `reverse`(): Unit = { + assertEquals(0xf77db57b, Integer.reverse(0xdeadbeef)) + assertEquals(0x53b34100, Integer.reverse(0x0082cdca)) + assertEquals(0x1a8f61c1, Integer.reverse(0x8386f158)) + assertEquals(0x12355be0, Integer.reverse(0x07daac48)) + assertEquals(0x60d76ea4, Integer.reverse(0x2576eb06)) + assertEquals(0xb75763ef, Integer.reverse(0xf7c6eaed)) + assertEquals(0xf76c132e, Integer.reverse(0x74c836ef)) + assertEquals(0x38c1b936, Integer.reverse(0x6c9d831c)) + assertEquals(0xcaee6a4e, Integer.reverse(0x72567753)) + assertEquals(0x9a561ff5, Integer.reverse(0xaff86a59)) + assertEquals(0xafc31173, Integer.reverse(0xce88c3f5)) + assertEquals(0x5e13ebae, Integer.reverse(0x75d7c87a)) + assertEquals(0xdfc3a1a8, Integer.reverse(0x1585c3fb)) + assertEquals(0x46386e77, Integer.reverse(0xee761c62)) + assertEquals(0xf3706aef, Integer.reverse(0xf7560ecf)) + assertEquals(0xd6219da6, Integer.reverse(0x65b9846b)) + assertEquals(0xe3340ff2, Integer.reverse(0x4ff02cc7)) + assertEquals(0xdf4e6548, Integer.reverse(0x12a672fb)) + assertEquals(0x4b9f2346, Integer.reverse(0x62c4f9d2)) + assertEquals(0x0ebf8608, Integer.reverse(0x1061fd70)) + assertEquals(0x354c3cc8, Integer.reverse(0x133c32ac)) } @Test def rotateLeft(): Unit = { diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/LongTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/LongTest.scala index 6dfa4367cc..48e74665ab 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/LongTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/LongTest.scala @@ -21,6 +21,51 @@ class LongTest { @Test def reverseBytes(): Unit = { assertEquals(0x14ff01d49c68abf5L, JLong.reverseBytes(0xf5ab689cd401ff14L)) + assertEquals(0x780176af73b18fc7L, JLong.reverseBytes(0xc78fb173af760178L)) + assertEquals(0x361d65c5b948d4d6L, JLong.reverseBytes(0xd6d448b9c5651d36L)) + assertEquals(0xf7a1ef821b8f4864L, JLong.reverseBytes(0x64488f1b82efa1f7L)) + assertEquals(0xddc509a6de8e44c5L, JLong.reverseBytes(0xc5448edea609c5ddL)) + assertEquals(0x288824701c0a5355L, JLong.reverseBytes(0x55530a1c70248828L)) + assertEquals(0x8bf3fed839300267L, JLong.reverseBytes(0x67023039d8fef38bL)) + assertEquals(0x44c9ade0187f253eL, JLong.reverseBytes(0x3e257f18e0adc944L)) + assertEquals(0x79a345f33753c217L, JLong.reverseBytes(0x17c25337f345a379L)) + assertEquals(0x52934dd800c7e57eL, JLong.reverseBytes(0x7ee5c700d84d9352L)) + assertEquals(0xc60434cd3ee0d783L, JLong.reverseBytes(0x83d7e03ecd3404c6L)) + assertEquals(0xe35901c3015a16a0L, JLong.reverseBytes(0xa0165a01c30159e3L)) + assertEquals(0x3b6967d70dbed537L, JLong.reverseBytes(0x37d5be0dd767693bL)) + assertEquals(0xc64eec7456b1d217L, JLong.reverseBytes(0x17d2b15674ec4ec6L)) + assertEquals(0xcd82e5c594a61174L, JLong.reverseBytes(0x7411a694c5e582cdL)) + assertEquals(0xd5f85c6a11888b2aL, JLong.reverseBytes(0x2a8b88116a5cf8d5L)) + assertEquals(0xa8c6597640b32446L, JLong.reverseBytes(0x4624b3407659c6a8L)) + assertEquals(0x61aa72555ec08d2dL, JLong.reverseBytes(0x2d8dc05e5572aa61L)) + assertEquals(0xd506860a916bb2d5L, JLong.reverseBytes(0xd5b26b910a8606d5L)) + assertEquals(0xa5b42bd78ecda8f1L, JLong.reverseBytes(0xf1a8cd8ed72bb4a5L)) + assertEquals(0xe7cb5958d4f41bfaL, JLong.reverseBytes(0xfa1bf4d45859cbe7L)) + } + + @Test def reverse(): Unit = { + assertEquals(0x28ff802b3916d5afL, JLong.reverse(0xf5ab689cd401ff14L)) + assertEquals(0x0000000000000001L, JLong.reverse(0x8000000000000000L)) + assertEquals(0xc72a7066e1350f40L, JLong.reverse(0x02f0ac87660e54e3L)) + assertEquals(0x4455b80802f29f69L, JLong.reverse(0x96f94f40101daa22L)) + assertEquals(0xf8174394b3aaf2e6L, JLong.reverse(0x674f55cd29c2e81fL)) + assertEquals(0x9c6f15743242b439L, JLong.reverse(0x9c2d424c2ea8f639L)) + assertEquals(0x8ef01f0551b80ab0L, JLong.reverse(0x0d501d8aa0f80f71L)) + assertEquals(0xaeb088220ac8cf31L, JLong.reverse(0x8cf3135044110d75L)) + assertEquals(0x247e286155da22c9L, JLong.reverse(0x93445baa86147e24L)) + assertEquals(0xa45c9f296362d10cL, JLong.reverse(0x308b46c694f93a25L)) + assertEquals(0x16ca602244d14b85L, JLong.reverse(0xa1d28b2244065368L)) + assertEquals(0x878acb85b7fe40c5L, JLong.reverse(0xa3027feda1d351e1L)) + assertEquals(0xb8d996565b3f28d8L, JLong.reverse(0x1b14fcda6a699b1dL)) + assertEquals(0xc84e6c88148a6a27L, JLong.reverse(0xe456512811367213L)) + assertEquals(0x6bac67a3e7a7450cL, JLong.reverse(0x30a2e5e7c5e635d6L)) + assertEquals(0x2f17be6d95d551a5L, JLong.reverse(0xa58aaba9b67de8f4L)) + assertEquals(0x9ed3868d46155aaeL, JLong.reverse(0x755aa862b161cb79L)) + assertEquals(0x2de28f4e6b239166L, JLong.reverse(0x6689c4d672f147b4L)) + assertEquals(0x1528d4f46d89c9c9L, JLong.reverse(0x939391b62f2b14a8L)) + assertEquals(0xaca0de3697c073a4L, JLong.reverse(0x25ce03e96c7b0535L)) + assertEquals(0xe44211dee49bac56L, JLong.reverse(0x6a35d9277b884227L)) + assertEquals(0x438dc899d9c4de36L, JLong.reverse(0x6c7b239b9913b1c2L)) } @Test def rotateLeft(): Unit = { From 58dd96c769e457775952165d09335c85779c60af Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Wed, 3 May 2017 20:28:39 +0200 Subject: [PATCH 0244/2665] Disallow @JSName on non js-native classes This (hopefully) is the last step for #1111. --- .../scalajs/core/compiler/PrepJSInterop.scala | 7 +++---- .../core/compiler/test/JSInteropTest.scala | 18 +++++++++--------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 475bd137e2..fd5a790ff9 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -1008,10 +1008,9 @@ abstract class PrepJSInterop extends plugins.PluginComponent for (annot <- sym.annotations) { if (annot.symbol == JSNameAnnotation && !allowJSName) { - reporter.warning(annot.pos, - "Non JS-native classes, traits and objects should not have an " + - "@JSName annotation, as it does not have any effect. " + - "This will be enforced in 1.0.") + reporter.error(annot.pos, + "Non JS-native classes, traits and objects may not have an " + + "@JSName annotation.") } else if (annot.symbol == JSGlobalAnnotation) { reporter.error(annot.pos, "Non JS-native classes, traits and objects may not have an " + diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index 9a0f98362e..643ef67bbf 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -52,12 +52,12 @@ class JSInteropTest extends DirectTest with TestHelpers { @JSName(Sym.sym) $obj B extends js.Object - """ hasWarns + """ hasErrors s""" - |newSource1.scala:5: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. + |newSource1.scala:5: error: Non JS-native classes, traits and objects may not have an @JSName annotation. | @JSName("foo") | ^ - |newSource1.scala:12: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. + |newSource1.scala:12: error: Non JS-native classes, traits and objects may not have an @JSName annotation. | @JSName(Sym.sym) | ^ """ @@ -76,12 +76,12 @@ class JSInteropTest extends DirectTest with TestHelpers { @JSName(Sym.sym) $obj B - """ hasWarns + """ hasErrors s""" - |newSource1.scala:5: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. + |newSource1.scala:5: error: Non JS-native classes, traits and objects may not have an @JSName annotation. | @JSName("foo") | ^ - |newSource1.scala:12: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. + |newSource1.scala:12: error: Non JS-native classes, traits and objects may not have an @JSName annotation. | @JSName(Sym.sym) | ^ """ @@ -110,12 +110,12 @@ class JSInteropTest extends DirectTest with TestHelpers { @JSName("bar") private object tata extends js.Object } - """ hasWarns + """ hasErrors """ - |newSource1.scala:6: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. + |newSource1.scala:6: error: Non JS-native classes, traits and objects may not have an @JSName annotation. | @JSName("foo") | ^ - |newSource1.scala:9: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. + |newSource1.scala:9: error: Non JS-native classes, traits and objects may not have an @JSName annotation. | @JSName("bar") | ^ """ From 338e71ddf1633e78f881034e4925555032c937c3 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Wed, 3 May 2017 20:38:30 +0200 Subject: [PATCH 0245/2665] Fix #2924: FileVirtualTextFile does not read UTF-8 This also fixes #2845. --- .../scala/org/scalajs/core/tools/io/FileVirtualFiles.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala index 2b8475b7f1..23dc8f8efb 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala @@ -56,7 +56,8 @@ class FileVirtualTextFile(f: File) extends FileVirtualFile(f) import FileVirtualTextFile._ override def content: String = readFileToString(file) - override def reader: Reader = new BufferedReader(new FileReader(f)) + override def reader: Reader = new InputStreamReader( + new BufferedInputStream(new FileInputStream(f)), "UTF-8") } object FileVirtualTextFile extends (File => FileVirtualTextFile) { From 161e01d9debe67e7626ddc2f393c2d8e0786055f Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Thu, 4 May 2017 20:17:41 +0200 Subject: [PATCH 0246/2665] Fix #2804: Transform receiver of js.Dynamic#x This caused expressions like `js.constructorOf[Foo].x` to blow up with a "stub" error. --- .../scala/org/scalajs/core/compiler/PrepJSInterop.scala | 4 ++-- .../org/scalajs/testsuite/compiler/RegressionJSTest.scala | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index fd3ae4a23c..6c3dab04d3 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -337,7 +337,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent case Select(Select(trg, jsnme.x), nme.apply) if isJSDynamic(trg) => val newTree = atPos(tree.pos) { Apply( - Select(super.transform(trg), newTermName("applyDynamic")), + Select(transform(trg), newTermName("applyDynamic")), List(Literal(Constant("x"))) ) } @@ -349,7 +349,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent case Select(trg, jsnme.x) if isJSDynamic(trg) => val newTree = atPos(tree.pos) { Apply( - Select(super.transform(trg), newTermName("selectDynamic")), + Select(transform(trg), newTermName("selectDynamic")), List(Literal(Constant("x"))) ) } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala index 7fd9ff5b60..cd7a22775c 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala @@ -73,4 +73,12 @@ class RegressionJSTest { js.debugger() } + @Test def should_transform_js_dynamic_x_receiver_issue_2804(): Unit = { + @ScalaJSDefined + class Foo extends js.Object + + assertTrue(js.isUndefined(js.constructorOf[Foo].x)) + assertTrue(js.isUndefined(js.constructorOf[Foo].y)) + } + } From 023c56b494eb4e036a5e7e3ba7086f0971990379 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Thu, 4 May 2017 20:46:59 +0200 Subject: [PATCH 0247/2665] Fix #2785: No IIFE in fullOpt CommonJSModule --- .../linker/backend/closure/ClosureLinkerBackend.scala | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala index b9f97b2b4f..ec1e19c55c 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala @@ -54,6 +54,11 @@ final class ClosureLinkerBackend( val symbolRequirements: SymbolRequirement = emitter.symbolRequirements + private val needsIIFEWrapper = moduleKind match { + case ModuleKind.NoModule => true + case ModuleKind.CommonJSModule => false + } + private def toClosureSource(file: VirtualJSFile) = ClosureSource.fromReader(file.toURI.toString(), file.reader) @@ -139,10 +144,11 @@ final class ClosureLinkerBackend( private def writeResult(result: Result, compiler: ClosureCompiler, output: WritableVirtualJSFile): Unit = { def withNewLine(str: String): String = if (str == "") "" else str + "\n" + def ifIIFE(str: String): String = if (needsIIFEWrapper) str else "" val (header0, footer0) = config.customOutputWrapper - val header = withNewLine(header0) + "(function(){'use strict';\n" - val footer = "}).call(this);\n" + withNewLine(footer0) + val header = withNewLine(header0) + ifIIFE("(function(){") + "'use strict';\n" + val footer = ifIIFE("}).call(this);\n") + withNewLine(footer0) val outputContent = if (result.errors.nonEmpty) "// errors while producing source\n" From b4fa6fff0d2aaf205c3aae33e1713290fdeadf9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 5 May 2017 14:49:17 +0200 Subject: [PATCH 0248/2665] Remove the @JSExportDescendentClasses annotation. That removal was forgotten in facca8515a55a0969c618dc59a71a885449897da. --- .../JSExportDescendentClasses.scala | 29 ------------------- 1 file changed, 29 deletions(-) delete mode 100644 library/src/main/scala/scala/scalajs/js/annotation/JSExportDescendentClasses.scala diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSExportDescendentClasses.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSExportDescendentClasses.scala deleted file mode 100644 index 297ec78c59..0000000000 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSExportDescendentClasses.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - - -package scala.scalajs.js.annotation - -/** Specifies that all the concrete classes extending the annotated class or - * should have all their public constructors exported for use in raw JS. - * The constructors exported this way are exported under their fully - * qualified name. - * - * @param ignoreInvalidDescendants If true, descendants that cannot be exported - * are silently ignored. - * @see [[http://www.scala-js.org/doc/export-to-javascript.html Export Scala.js APIs to JavaScript]] - */ -class JSExportDescendentClasses(ignoreInvalidDescendants: Boolean) - extends scala.annotation.StaticAnnotation { - /** Constructor that makes invalid descendants fail. - * - * same as setting ingoreInvalidDescendants to false - */ - def this() = this(false) -} From ba06a2be4aed14d7d453f620235f33d336eb70e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 5 May 2017 15:52:27 +0200 Subject: [PATCH 0249/2665] Remove support for loading from the exports namespace in TestUtils. Since `@JSExportDescendent{Classes,Objects}` have been removed, this support is completely useless. --- .../org/scalajs/testinterface/TestUtils.scala | 24 +----- .../org/scalajs/testinterface/TestUtils.scala | 84 ++++--------------- 2 files changed, 17 insertions(+), 91 deletions(-) diff --git a/stubs/src/main/scala/org/scalajs/testinterface/TestUtils.scala b/stubs/src/main/scala/org/scalajs/testinterface/TestUtils.scala index f7a4b8e6a7..b70cfd4454 100644 --- a/stubs/src/main/scala/org/scalajs/testinterface/TestUtils.scala +++ b/stubs/src/main/scala/org/scalajs/testinterface/TestUtils.scala @@ -15,33 +15,11 @@ object TestUtils { import scala.reflect.macros._ // shadows blackbox from above import blackbox.Context - @deprecated( - "Use the overload with explicit formal constructor parameter types.", - "0.6.15") - def newInstance(name: String, loader: ClassLoader)(args: Seq[AnyRef]): AnyRef = - macro newInstance_impl - def newInstance(name: String, loader: ClassLoader, paramTypes: Seq[Class[_]])( args: Seq[AnyRef]): AnyRef = - macro newInstance_impl2 + macro newInstance_impl def newInstance_impl(c: Context)(name: c.Expr[String], - loader: c.Expr[ClassLoader])( - args: c.Expr[Seq[AnyRef]]): c.Expr[AnyRef] = c.universe.reify { - - val clazz = loader.splice.loadClass(name.splice) - val ctors = clazz.getConstructors() - - if (ctors.size != 1) { - throw new IllegalArgumentException( - "You may only call newInstance with single-ctor classes") - } - - val ctor = ctors.head - ctor.newInstance(args.splice: _*).asInstanceOf[AnyRef] - } - - def newInstance_impl2(c: Context)(name: c.Expr[String], loader: c.Expr[ClassLoader], paramTypes: c.Expr[Seq[Class[_]]])( args: c.Expr[Seq[AnyRef]]): c.Expr[AnyRef] = c.universe.reify { diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/TestUtils.scala b/test-interface/src/main/scala/org/scalajs/testinterface/TestUtils.scala index 27a5b62937..f901fa899a 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/TestUtils.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/TestUtils.scala @@ -7,92 +7,40 @@ object TestUtils { /** Instantiates the class given by its fully qualified name. * - * The target class must be exported under its fully qualified name. - * - * This overload of `newInstance` cannot instantiate classes with an - * ancestor annotated with + * The target class must extend a class or trait annotated with * [[scala.scalajs.reflect.annotation.EnableReflectiveInstantiation]]. * - * Prefer using the other overload of `newInstance` for new code, which - * supports reflective instantiation in addition to exports-based - * instantiation. - */ - @deprecated( - "Use the overload with explicit formal constructor parameter types.", - "0.6.15") - def newInstance(name: String, loader: ClassLoader)( - args: Seq[AnyRef]): AnyRef = { - Reflect.lookupInstantiatableClass(name).fold[AnyRef] { - val ctor = deepSelect(namespace(loader), name) - js.Dynamic.newInstance(ctor)(args.asInstanceOf[Seq[js.Any]]: _*) - } { clazz => - throw new InstantiationException( - s"The class '$name' should be loaded through reflective " + - "instantiation, but the overload of TestUtils.newIntance() that " + - "was used does not support it. You can fix it by calling the other " + - "overload of TestUtils.newInstance().") - } - } - - /** Instantiates the class given by its fully qualified name. - * - * The target class must either - * - * - extend a class or trait annotated with - * [[scala.scalajs.reflect.annotation.EnableReflectiveInstantiation]], or - * - be exported under its fully qualified name. - * - * In the former case, the overload is selected based on `paramTypes`. In - * the latter case, the overload is selected by the usual export overload - * resolution mechanism. + * The `paramTypes` argument is used to select the appropriate overloaded + * constructor. */ def newInstance(name: String, loader: ClassLoader, paramTypes: Seq[Class[_]])( args: Seq[Any]): AnyRef = { require(args.size == paramTypes.size, "argument count mismatch") - Reflect.lookupInstantiatableClass(name).fold[AnyRef] { - val ctor = deepSelect(namespace(loader), name) - js.Dynamic.newInstance(ctor)(args.asInstanceOf[Seq[js.Any]]: _*) - } { clazz => - val ctor = clazz.declaredConstructors.find { - _.parameterTypes == paramTypes - }.getOrElse { - throw new InstantiationError(name) - } - ctor.newInstance(args: _*).asInstanceOf[AnyRef] + val clazz = Reflect.lookupInstantiatableClass(name).getOrElse { + throw new InstantiationError(name) + } + val ctor = clazz.declaredConstructors.find { + _.parameterTypes == paramTypes + }.getOrElse { + throw new InstantiationError(name) } + ctor.newInstance(args: _*).asInstanceOf[AnyRef] } /** Loads the module given by its fully qualified name. * - * The target object must either - * - * - extend a class or trait annotated with - * [[scala.scalajs.reflect.annotation.EnableReflectiveInstantiation]], or - * - be exported under its fully qualified name. + * The target object must extend a class or trait annotated with + * [[scala.scalajs.reflect.annotation.EnableReflectiveInstantiation]]. * * The name *must not* include the trailing `$` that is part of the module * name, as added by the Scala compiler. */ def loadModule(name: String, loader: ClassLoader): AnyRef = { - Reflect.lookupLoadableModuleClass(name + "$").fold[AnyRef] { - val accessor = deepSelect(namespace(loader), name) - accessor() - } { loadableModule => - loadableModule.loadModule().asInstanceOf[AnyRef] + val loadableModule = Reflect.lookupLoadableModuleClass(name + "$").getOrElse { + throw new InstantiationError(name) } + loadableModule.loadModule().asInstanceOf[AnyRef] } - private def namespace(loader: ClassLoader): js.Dynamic = { - loader match { - case loader: ScalaJSClassLoader => - loader.namespace - case _ => - throw new IllegalArgumentException("Need a ScalaJSClassLoader.") - } - } - - private def deepSelect(receiver: js.Dynamic, name: String) = - name.split('.').foldLeft(receiver)((obj, n) => obj.selectDynamic(n)) - } From 5cd01d36383a323c0ea978815a84a4aaef520435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 5 May 2017 15:53:32 +0200 Subject: [PATCH 0250/2665] Remove the `namespace` argument of `ScalaJSClassLoader`. This was used to load classes and objects from the exports namespace in `TestUtils`. Since the latter does not support that anymore, the `namespace` argument is useless and can be removed. --- .../junit/utils/JUnitTestPlatformImpl.scala | 4 +--- .../org/scalajs/testinterface/HTMLRunner.scala | 2 +- .../testinterface/ScalaJSClassLoader.scala | 17 ++++++++++++----- .../scalajs/testinterface/internal/Master.scala | 3 +-- .../scalajs/testinterface/internal/Slave.scala | 4 +--- .../scalajs/core/tools/test/js/TestRunner.scala | 3 +-- 6 files changed, 17 insertions(+), 16 deletions(-) diff --git a/junit-test/output-js/src/test/scala/org/scalajs/junit/utils/JUnitTestPlatformImpl.scala b/junit-test/output-js/src/test/scala/org/scalajs/junit/utils/JUnitTestPlatformImpl.scala index 80f4a0c895..b153dc3e6c 100644 --- a/junit-test/output-js/src/test/scala/org/scalajs/junit/utils/JUnitTestPlatformImpl.scala +++ b/junit-test/output-js/src/test/scala/org/scalajs/junit/utils/JUnitTestPlatformImpl.scala @@ -2,12 +2,10 @@ package org.scalajs.junit.utils import sbt.testing._ -import scala.scalajs.js - object JUnitTestPlatformImpl { def getClassLoader: ClassLoader = - new org.scalajs.testinterface.ScalaJSClassLoader(js.Dynamic.global) + new org.scalajs.testinterface.ScalaJSClassLoader() def executeLoop(tasks: Array[Task], recorder: Logger with EventHandler): Unit = { if (tasks.nonEmpty) { diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala b/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala index d8c6780090..21a352b1d2 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala @@ -22,7 +22,7 @@ import scala.util.Try import sbt.testing._ protected[testinterface] object HTMLRunner { - private val classLoader = new ScalaJSClassLoader(js.Dynamic.global) + private val classLoader = new ScalaJSClassLoader() private object EventCounter { private val isErrorStatus = Set(Status.Error, Status.Failure) diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/ScalaJSClassLoader.scala b/test-interface/src/main/scala/org/scalajs/testinterface/ScalaJSClassLoader.scala index fc30c0f27d..cb420d3716 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/ScalaJSClassLoader.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/ScalaJSClassLoader.scala @@ -6,12 +6,19 @@ import java.net.URL import java.io.InputStream import java.util.Enumeration -/** A dummy [[java.lang.ClassLoader]] that allows to store a JavaScript object - * against which classes are resolved. The only reason it extends - * [[java.lang.ClassLoader]] is typing. +/** A dummy [[java.lang.ClassLoader]] for Scala.js testing frameworks. + * + * This class loader does *not* implement the contract of + * [[java.lang.ClassLoader]]. It is exclusively used as a dummy class loader + * to preserve source compatibility with the sbt testing interface. */ -final class ScalaJSClassLoader( - val namespace: js.Dynamic) extends ClassLoader(null) { +final class ScalaJSClassLoader extends ClassLoader(null) { + + @deprecated( + "The `namespace` argument is ignored. " + + "Use the constructor with 0 argument.", + "1.0.0") + def this(namespace: js.Dynamic) = this() private def nimp: Nothing = throw new NotImplementedError("A ScalaJSClassLoader is a dummy. " + diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Master.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/Master.scala index f4646b92a0..451192bb54 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Master.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/Master.scala @@ -36,8 +36,7 @@ final class Master(frameworkName: String) extends BridgeBase(frameworkName) { private def newRunner(data: js.Dynamic): Try[Unit] = { val args = data.args.asInstanceOf[js.Array[String]].toArray val remoteArgs = data.remoteArgs.asInstanceOf[js.Array[String]].toArray - val loader = new ScalaJSClassLoader( - scala.scalajs.runtime.environmentInfo.exportsNamespace) + val loader = new ScalaJSClassLoader() Try(runner = framework.runner(args, remoteArgs, loader)) } diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala index 0317380c1a..e55413484d 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala @@ -75,10 +75,8 @@ final class Slave(frameworkName: String, args: js.Array[String], // Message handler methods private def newRunner(): Try[Unit] = { - val loader = new ScalaJSClassLoader( - scala.scalajs.runtime.environmentInfo.exportsNamespace) Try(runner = framework.slaveRunner(args.toArray, remoteArgs.toArray, - loader, outboundRunnerMessage)) + new ScalaJSClassLoader(), outboundRunnerMessage)) } private def execute(data: js.Dynamic): Unit = { diff --git a/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala b/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala index eac39b462d..13f25547dc 100644 --- a/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala +++ b/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala @@ -29,8 +29,7 @@ object TestRunner { for { (framework, taskDefs) <- TestDetector.detectTests() } { - val runner = framework.runner(Array(), Array(), - new ScalaJSClassLoader(js.Dynamic.global)) + val runner = framework.runner(Array(), Array(), new ScalaJSClassLoader()) val tasks = runner.tasks(taskDefs.toArray) taskLoop(tasks) } From 4ae60a9fd9f184dbc00d3b9da47fa12063d97335 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 5 May 2017 20:25:34 +0200 Subject: [PATCH 0251/2665] Disallow implicit apply export --- .../org/scalajs/core/compiler/PrepJSExports.scala | 7 +++---- .../scalajs/core/compiler/test/JSExportTest.scala | 12 ++++++------ .../org/scalajs/testsuite/library/UseAsTest.scala | 1 + 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala index 8ae54874f5..7c6664d9c0 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala @@ -257,10 +257,9 @@ trait PrepJSExports { this: PrepJSInterop => // Get position for error message val pos = if (isExportAll) trgSym.pos else annot.pos - reporter.warning(pos, "Member cannot be exported to function " + - "application. It is available under the name apply " + - "instead. Add @JSExport(\"apply\") to silence this " + - "warning. This will be enforced in 1.0.") + reporter.error(pos, "A member cannot be exported to function " + + "application. Add @JSExport(\"apply\") to export under the " + + "name apply.") } case ExportDestination.TopLevel => diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index bf92a0fd8e..64fd189f73 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -820,9 +820,9 @@ class JSExportTest extends DirectTest with TestHelpers { @JSExport def apply(): Int = 1 } - """ hasWarns + """ hasErrors """ - |newSource1.scala:4: warning: Member cannot be exported to function application. It is available under the name apply instead. Add @JSExport("apply") to silence this warning. This will be enforced in 1.0. + |newSource1.scala:4: error: A member cannot be exported to function application. Add @JSExport("apply") to export under the name apply. | @JSExport | ^ """ @@ -832,9 +832,9 @@ class JSExportTest extends DirectTest with TestHelpers { class A { def apply(): Int = 1 } - """ hasWarns + """ hasErrors """ - |newSource1.scala:5: warning: Member cannot be exported to function application. It is available under the name apply instead. Add @JSExport("apply") to silence this warning. This will be enforced in 1.0. + |newSource1.scala:5: error: A member cannot be exported to function application. Add @JSExport("apply") to export under the name apply. | def apply(): Int = 1 | ^ """ @@ -845,9 +845,9 @@ class JSExportTest extends DirectTest with TestHelpers { @JSExport("foo") def apply(): Int = 1 } - """ hasWarns + """ hasErrors """ - |newSource1.scala:6: warning: Member cannot be exported to function application. It is available under the name apply instead. Add @JSExport("apply") to silence this warning. This will be enforced in 1.0. + |newSource1.scala:6: error: A member cannot be exported to function application. Add @JSExport("apply") to export under the name apply. | def apply(): Int = 1 | ^ """ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UseAsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UseAsTest.scala index efb63157f9..d213c8b1d3 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UseAsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UseAsTest.scala @@ -112,6 +112,7 @@ class UseAsScalaTypesTest { @Test def should_work_with_JSExportAll_with_an_apply_method(): Unit = { @JSExportAll class A { + @JSExport("apply") @JSExport("bar") def apply(x: Int): Int = x * 2 } From 805ee9af57e3298b6410c24fb0fc2a7a7748bb71 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 5 May 2017 20:25:49 +0200 Subject: [PATCH 0252/2665] Disallow bad JSName overrides --- .../scalajs/core/compiler/PrepJSInterop.scala | 2 +- .../core/compiler/test/JSInteropTest.scala | 124 +++++++++--------- 2 files changed, 63 insertions(+), 63 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index fd5a790ff9..0e34f5df79 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -601,7 +601,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent memberDefStringWithJSName(high) + "\n" } - reporter.warning(errorPos, msg) + reporter.error(errorPos, msg) } /* Cannot override a non-@JSOptional with an @JSOptional. Unfortunately diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index 643ef67bbf..6445466afb 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -1742,7 +1742,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } @Test - def scalaJSDefinedJSNameOverrideWarnings: Unit = { + def scalaJSDefinedJSNameOverrideErrors: Unit = { """ abstract class A extends js.Object { def bar(): Int @@ -1783,9 +1783,9 @@ class JSInteropTest extends DirectTest with TestHelpers { @JSName("baz") override def bar() = 1 } - """ hasWarns + """ hasErrors """ - |newSource1.scala:11: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:11: error: A member of a JS class is overriding another member with a different JS name. | |override def bar(): Int in class B with JSName 'baz' | is conflicting with @@ -1803,9 +1803,9 @@ class JSInteropTest extends DirectTest with TestHelpers { class B extends A { override def bar() = 1 } - """ hasWarns + """ hasErrors """ - |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: error: A member of a JS class is overriding another member with a different JS name. | |override def bar(): Int in class B with JSName 'bar' | is conflicting with @@ -1826,9 +1826,9 @@ class JSInteropTest extends DirectTest with TestHelpers { class C extends B { override def bar() = "1" } - """ hasWarns + """ hasErrors """ - |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: error: A member of a JS class is overriding another member with a different JS name. | |override def bar(): String in class B with JSName 'bar' | is conflicting with @@ -1836,7 +1836,7 @@ class JSInteropTest extends DirectTest with TestHelpers { | | override def bar(): String | ^ - |newSource1.scala:13: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:13: error: A member of a JS class is overriding another member with a different JS name. | |override def bar(): String in class C with JSName 'bar' | is conflicting with @@ -1857,9 +1857,9 @@ class JSInteropTest extends DirectTest with TestHelpers { class C extends B { override def bar() = "1" } - """ hasWarns + """ hasErrors """ - |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: error: A member of a JS class is overriding another member with a different JS name. | |override def bar(): String in class B with JSName 'foo' | is conflicting with @@ -1867,7 +1867,7 @@ class JSInteropTest extends DirectTest with TestHelpers { | | override def bar(): String | ^ - |newSource1.scala:13: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:13: error: A member of a JS class is overriding another member with a different JS name. | |override def bar(): String in class C with JSName 'bar' | is conflicting with @@ -1886,9 +1886,9 @@ class JSInteropTest extends DirectTest with TestHelpers { def foo: Int } class C extends B - """ hasWarns + """ hasErrors """ - |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: error: A member of a JS class is overriding another member with a different JS name. | |def foo: Int in class A with JSName 'foo' | is conflicting with @@ -1907,9 +1907,9 @@ class JSInteropTest extends DirectTest with TestHelpers { def foo: Int } class C extends B - """ hasWarns + """ hasErrors """ - |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: error: A member of a JS class is overriding another member with a different JS name. | |def foo: Int in class A with JSName 'bar' | is conflicting with @@ -1927,9 +1927,9 @@ class JSInteropTest extends DirectTest with TestHelpers { class B extends A[Int] { override def foo(x: Int): Int = x } - """ hasWarns + """ hasErrors """ - |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: error: A member of a JS class is overriding another member with a different JS name. | |override def foo(x: Int): Int in class B with JSName 'foo' | is conflicting with @@ -1947,9 +1947,9 @@ class JSInteropTest extends DirectTest with TestHelpers { class B extends A[Int] { override def foo(x: Int): Int = x } - """ hasWarns + """ hasErrors """ - |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: error: A member of a JS class is overriding another member with a different JS name. | |override def foo(x: Int): Int in class B with JSName 'foo' | is conflicting with @@ -1970,9 +1970,9 @@ class JSInteropTest extends DirectTest with TestHelpers { class C extends B { override def foo(x: Int): Int = x } - """ hasWarns + """ hasErrors """ - |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: error: A member of a JS class is overriding another member with a different JS name. | |def foo(x: Int): Int in class A with JSName 'bar' | is conflicting with @@ -1980,7 +1980,7 @@ class JSInteropTest extends DirectTest with TestHelpers { | | def foo(x: Int): Int | ^ - |newSource1.scala:13: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:13: error: A member of a JS class is overriding another member with a different JS name. | |override def foo(x: Int): Int in class C with JSName 'foo' | is conflicting with @@ -2001,9 +2001,9 @@ class JSInteropTest extends DirectTest with TestHelpers { class C extends B { override def foo(x: Int): Int = x } - """ hasWarns + """ hasErrors """ - |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: error: A member of a JS class is overriding another member with a different JS name. | |def foo(x: Int): Int in class A with JSName 'foo' | is conflicting with @@ -2011,7 +2011,7 @@ class JSInteropTest extends DirectTest with TestHelpers { | | def foo(x: Int): Int | ^ - |newSource1.scala:13: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:13: error: A member of a JS class is overriding another member with a different JS name. | |override def foo(x: Int): Int in class C with JSName 'foo' | is conflicting with @@ -2030,9 +2030,9 @@ class JSInteropTest extends DirectTest with TestHelpers { def foo: Int } trait C extends A with B - """ hasWarns + """ hasErrors """ - |newSource1.scala:12: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:12: error: A member of a JS class is overriding another member with a different JS name. | |def foo: Int in trait B with JSName 'bar' | is conflicting with @@ -2051,9 +2051,9 @@ class JSInteropTest extends DirectTest with TestHelpers { def foo: Int } abstract class C extends A with B - """ hasWarns + """ hasErrors """ - |newSource1.scala:12: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:12: error: A member of a JS class is overriding another member with a different JS name. | |def foo: Int in trait B with JSName 'bar' | is conflicting with @@ -2065,7 +2065,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } @Test - def scalaJSDefinedJSNameWithSymbolOverrideWarnings: Unit = { + def scalaJSDefinedJSNameWithSymbolOverrideErrors: Unit = { """ object Syms { val sym1 = js.Symbol() @@ -2110,9 +2110,9 @@ class JSInteropTest extends DirectTest with TestHelpers { @JSName(Syms.sym2) override def bar() = 1 } - """ hasWarns + """ hasErrors """ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:16: error: A member of a JS class is overriding another member with a different JS name. | |override def bar(): Int in class B with JSName 'Syms.sym2' | is conflicting with @@ -2135,9 +2135,9 @@ class JSInteropTest extends DirectTest with TestHelpers { @JSName("baz") override def bar() = 1 } - """ hasWarns + """ hasErrors """ - |newSource1.scala:15: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:15: error: A member of a JS class is overriding another member with a different JS name. | |override def bar(): Int in class B with JSName 'baz' | is conflicting with @@ -2160,9 +2160,9 @@ class JSInteropTest extends DirectTest with TestHelpers { @JSName(Syms.sym1) override def bar() = 1 } - """ hasWarns + """ hasErrors """ - |newSource1.scala:15: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:15: error: A member of a JS class is overriding another member with a different JS name. | |override def bar(): Int in class B with JSName 'Syms.sym1' | is conflicting with @@ -2184,9 +2184,9 @@ class JSInteropTest extends DirectTest with TestHelpers { class B extends A { override def bar() = 1 } - """ hasWarns + """ hasErrors """ - |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: error: A member of a JS class is overriding another member with a different JS name. | |override def bar(): Int in class B with JSName 'bar' | is conflicting with @@ -2211,9 +2211,9 @@ class JSInteropTest extends DirectTest with TestHelpers { class C extends B { override def bar() = "1" } - """ hasWarns + """ hasErrors """ - |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: error: A member of a JS class is overriding another member with a different JS name. | |override def bar(): String in class B with JSName 'bar' | is conflicting with @@ -2221,7 +2221,7 @@ class JSInteropTest extends DirectTest with TestHelpers { | | override def bar(): String | ^ - |newSource1.scala:17: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:17: error: A member of a JS class is overriding another member with a different JS name. | |override def bar(): String in class C with JSName 'bar' | is conflicting with @@ -2246,9 +2246,9 @@ class JSInteropTest extends DirectTest with TestHelpers { class C extends B { override def bar() = "1" } - """ hasWarns + """ hasErrors """ - |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: error: A member of a JS class is overriding another member with a different JS name. | |override def bar(): String in class B with JSName 'Syms.sym1' | is conflicting with @@ -2256,7 +2256,7 @@ class JSInteropTest extends DirectTest with TestHelpers { | | override def bar(): String | ^ - |newSource1.scala:17: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:17: error: A member of a JS class is overriding another member with a different JS name. | |override def bar(): String in class C with JSName 'bar' | is conflicting with @@ -2279,9 +2279,9 @@ class JSInteropTest extends DirectTest with TestHelpers { def foo: Int } class C extends B - """ hasWarns + """ hasErrors """ - |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: error: A member of a JS class is overriding another member with a different JS name. | |def foo: Int in class A with JSName 'foo' | is conflicting with @@ -2304,9 +2304,9 @@ class JSInteropTest extends DirectTest with TestHelpers { def foo: Int } class C extends B - """ hasWarns + """ hasErrors """ - |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: error: A member of a JS class is overriding another member with a different JS name. | |def foo: Int in class A with JSName 'Syms.sym1' | is conflicting with @@ -2328,9 +2328,9 @@ class JSInteropTest extends DirectTest with TestHelpers { class B extends A[Int] { override def foo(x: Int): Int = x } - """ hasWarns + """ hasErrors """ - |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: error: A member of a JS class is overriding another member with a different JS name. | |override def foo(x: Int): Int in class B with JSName 'foo' | is conflicting with @@ -2352,9 +2352,9 @@ class JSInteropTest extends DirectTest with TestHelpers { class B extends A[Int] { override def foo(x: Int): Int = x } - """ hasWarns + """ hasErrors """ - |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: error: A member of a JS class is overriding another member with a different JS name. | |override def foo(x: Int): Int in class B with JSName 'foo' | is conflicting with @@ -2379,9 +2379,9 @@ class JSInteropTest extends DirectTest with TestHelpers { class C extends B { override def foo(x: Int): Int = x } - """ hasWarns + """ hasErrors """ - |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: error: A member of a JS class is overriding another member with a different JS name. | |def foo(x: Int): Int in class A with JSName 'Syms.sym1' | is conflicting with @@ -2389,7 +2389,7 @@ class JSInteropTest extends DirectTest with TestHelpers { | | def foo(x: Int): Int | ^ - |newSource1.scala:17: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:17: error: A member of a JS class is overriding another member with a different JS name. | |override def foo(x: Int): Int in class C with JSName 'foo' | is conflicting with @@ -2414,9 +2414,9 @@ class JSInteropTest extends DirectTest with TestHelpers { class C extends B { override def foo(x: Int): Int = x } - """ hasWarns + """ hasErrors """ - |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: error: A member of a JS class is overriding another member with a different JS name. | |def foo(x: Int): Int in class A with JSName 'foo' | is conflicting with @@ -2424,7 +2424,7 @@ class JSInteropTest extends DirectTest with TestHelpers { | | def foo(x: Int): Int | ^ - |newSource1.scala:17: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:17: error: A member of a JS class is overriding another member with a different JS name. | |override def foo(x: Int): Int in class C with JSName 'foo' | is conflicting with @@ -2447,9 +2447,9 @@ class JSInteropTest extends DirectTest with TestHelpers { def foo: Int } trait C extends A with B - """ hasWarns + """ hasErrors """ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:16: error: A member of a JS class is overriding another member with a different JS name. | |def foo: Int in trait B with JSName 'Syms.sym1' | is conflicting with @@ -2472,9 +2472,9 @@ class JSInteropTest extends DirectTest with TestHelpers { def foo: Int } abstract class C extends A with B - """ hasWarns + """ hasErrors """ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:16: error: A member of a JS class is overriding another member with a different JS name. | |def foo: Int in trait B with JSName 'Syms.sym1' | is conflicting with From 269d1aaf1fa20afbcc3940b9dba58e99ee010dc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 6 May 2017 21:30:25 +0200 Subject: [PATCH 0253/2665] Fix #2937: Generate a constructor in the JUnit bootstrapper object. --- .../junit/plugin/ScalaJSJUnitPlugin.scala | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala index 202692ff75..7d52272f25 100644 --- a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala +++ b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala @@ -207,10 +207,11 @@ class ScalaJSJUnitPlugin(val global: Global) extends NscPlugin { mkInvokeJUnitMethodOnInstanceDef(annotatedMethods, bootSym, clazz.symbol) } + val ctorDef = mkConstructorDef(clazz.symbol, bootSym, clazz.pos) val bootBody = { List(getJUnitMetadataDef, newInstanceDef, invokeJUnitMethodDef, - invokeJUnitMethodOnInstanceDef) + invokeJUnitMethodOnInstanceDef, ctorDef) } val bootParents = List( TypeTree(definitions.ObjectTpe), @@ -252,6 +253,22 @@ class ScalaJSJUnitPlugin(val global: Global) extends NscPlugin { }.toList } + /** Generates the constructor of a bootstrapper class. */ + private def mkConstructorDef(classSym: Symbol, bootSymbol: Symbol, + pos: Position): DefDef = { + val rhs = Block( + Apply( + Select( + Super(This(tpnme.EMPTY) setSymbol bootSymbol, tpnme.EMPTY), + nme.CONSTRUCTOR).setSymbol( + definitions.ObjectClass.primaryConstructor), + Nil), + Literal(Constant(())) + ) + val sym = bootSymbol.newClassConstructor(pos) + typer.typedDefDef(newDefDef(sym, rhs)()) + } + /** This method generates a method that invokes a test method in the module * given its name. These methods have no parameters. * From 94e0fd3eb15e20840cfafe757a163af7623853bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 7 May 2017 13:27:38 +0200 Subject: [PATCH 0254/2665] Fix #2939: Fix `%g` formatting for exact powers of 10. The temporary variable `sig` needs to be the smallest value such 10^sig is *strictly* greater than `m`. It used to, sometimes (depending on rounding errors) be such that `10^sig = m`. --- javalib/src/main/scala/java/util/Formatter.scala | 11 ++++++++++- .../testsuite/javalib/util/FormatterTest.scala | 2 ++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/javalib/src/main/scala/java/util/Formatter.scala b/javalib/src/main/scala/java/util/Formatter.scala index 35045e3ac6..e91ecd6b26 100644 --- a/javalib/src/main/scala/java/util/Formatter.scala +++ b/javalib/src/main/scala/java/util/Formatter.scala @@ -220,7 +220,16 @@ final class Formatter(private val dest: Appendable) extends Closeable with Flush else precision // between 1e-4 and 10e(p): display as fixed if (m >= 1e-4 && m < Math.pow(10, p)) { - val sig = Math.ceil(Math.log10(m)).toInt + /* First approximation of the smallest power of 10 that is >= m. + * Due to rounding errors in the event of an imprecise `log10` + * function, sig0 could actually be the smallest power of 10 + * that is > m. + */ + val sig0 = Math.ceil(Math.log10(m)).toInt + /* Increment sig0 so that it is always the first power of 10 + * that is > m. + */ + val sig = if (Math.pow(10, sig0) <= m) sig0 + 1 else sig0 with_+(numberArg.toFixed(Math.max(p - sig, 0))) } else sciNotation(p - 1) case 'f' => diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/FormatterTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/FormatterTest.scala index eca174a951..c2976d6667 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/FormatterTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/FormatterTest.scala @@ -199,6 +199,8 @@ class FormatterTest { assertF("5.00000e-05", "%g", new JDouble(.5e-4)) assertF("0.000300000", "%g", new JDouble(3e-4)) assertF("0.000300", "%.3g", new JDouble(3e-4)) + assertF("10.0000", "%g", new JDouble(10.0)) + assertF("10.00", "%.4g", new JDouble(10.0)) assertF("0.0010", "%.2g", new JDouble(1e-3)) assertF("300000", "%g", new JDouble(3e5)) assertF("3.00e+05", "%.3g", new JDouble(3e5)) From ff567b3e17d66c99df81f2999303bc69837780f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 6 May 2017 21:31:52 +0200 Subject: [PATCH 0255/2665] Fix #2936: Remove deserialization hacks. Remove both hacks actually happening during deserialization and those happening during the first linking step. --- .../org/scalajs/core/ir/InfoSerializers.scala | 20 +- .../org/scalajs/core/ir/Serializers.scala | 219 ++---------------- .../main/scala/org/scalajs/core/ir/Tags.scala | 11 +- .../core/tools/linker/analyzer/Analysis.scala | 14 -- .../core/tools/linker/analyzer/Analyzer.scala | 26 +-- .../tools/linker/checker/InfoChecker.scala | 15 +- .../tools/linker/frontend/BaseLinker.scala | 30 +-- 7 files changed, 34 insertions(+), 301 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/InfoSerializers.scala b/ir/src/main/scala/org/scalajs/core/ir/InfoSerializers.scala index 9d1d7a752d..d9160a6022 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/InfoSerializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/InfoSerializers.scala @@ -104,11 +104,6 @@ object InfoSerializers { import input._ - val useHacks065 = - Set("0.6.0", "0.6.3", "0.6.4", "0.6.5").contains(version) - val useHacks0614 = - useHacks065 || Set("0.6.6", "0.6.8", "0.6.13", "0.6.14").contains(version) - val encodedName = readUTF() val isExported = readBoolean() val kind = ClassKind.fromByte(readByte()) @@ -124,12 +119,8 @@ object InfoSerializers { val isStatic = readBoolean() val isAbstract = readBoolean() val isExported = readBoolean() - val staticFieldsRead = - if (useHacks0614) Map.empty[String, List[String]] - else readPerClassStrings() - val staticFieldsWritten = - if (useHacks0614) Map.empty[String, List[String]] - else readPerClassStrings() + val staticFieldsRead = readPerClassStrings() + val staticFieldsWritten = readPerClassStrings() val methodsCalled = readPerClassStrings() val methodsCalledStatically = readPerClassStrings() val staticMethodsCalled = readPerClassStrings() @@ -144,12 +135,7 @@ object InfoSerializers { accessedClassData) } - val methods0 = readList(readMethod()) - val methods = if (useHacks065) { - methods0.filter(m => !Definitions.isReflProxyName(m.encodedName)) - } else { - methods0 - } + val methods = readList(readMethod()) val info = ClassInfo(encodedName, isExported, kind, superClass, interfaces, methods) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index 52b37fd691..ad672388d1 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -643,16 +643,6 @@ object Serializers { } private final class Deserializer(stream: InputStream, sourceVersion: String) { - private[this] val useHacks060 = sourceVersion == "0.6.0" - private[this] val useHacks065 = - Set("0.6.0", "0.6.3", "0.6.4", "0.6.5").contains(sourceVersion) - private[this] val useHacks066 = - useHacks065 || sourceVersion == "0.6.6" - private[this] val useHacks068 = - useHacks066 || sourceVersion == "0.6.8" - private[this] val useHacks0614 = - useHacks068 || Set("0.6.13", "0.6.14").contains(sourceVersion) - private[this] val input = new DataInputStream(stream) private[this] val files = @@ -663,8 +653,6 @@ object Serializers { private[this] var lastPosition: Position = Position.NoPosition - private[this] var foundArguments: Boolean = false - def deserialize(): Tree = { readTree() } @@ -689,10 +677,7 @@ object Serializers { sys.error("Found invalid TagEmptyTree") case TagVarDef => VarDef(readIdent(), readType(), readBoolean(), readTree()) - case TagParamDef => - ParamDef(readIdent(), readType(), readBoolean(), - rest = if (useHacks060) false else readBoolean()) - + case TagParamDef => ParamDef(readIdent(), readType(), readBoolean(), readBoolean()) case TagSkip => Skip() case TagBlock => Block(readTrees()) case TagLabeled => Labeled(readIdent(), readType(), readTree()) @@ -702,22 +687,6 @@ object Serializers { case TagWhile => While(readTree(), readTree(), readOptIdent()) case TagDoWhile => DoWhile(readTree(), readTree(), readOptIdent()) - case TagTry => - if (!useHacks068) { - sys.error("Invalid tag TagTry") - } - - val block = readTree() - val errVar = readIdent() - val handler = readOptTree() - val finalizer = readOptTree() - val tpe = readType() - - val maybeCatch = handler.fold(block)( - handler => TryCatch(block, errVar, handler)(tpe)) - finalizer.fold(maybeCatch)( - finalizer => TryFinally(maybeCatch, finalizer)) - case TagTryCatch => TryCatch(readTree(), readIdent(), readTree())(readType()) @@ -738,13 +707,7 @@ object Serializers { case TagSelect => Select(readTree(), readIdent())(readType()) case TagSelectStatic => SelectStatic(readClassType(), readIdent())(readType()) case TagApply => Apply(readTree(), readIdent(), readTrees())(readType()) - case TagApplyStatically => - val result1 = - ApplyStatically(readTree(), readClassType(), readIdent(), readTrees())(readType()) - if (useHacks065 && result1.tpe != NoType && isConstructorName(result1.method.name)) - result1.copy()(NoType) - else - result1 + case TagApplyStatically => ApplyStatically(readTree(), readClassType(), readIdent(), readTrees())(readType()) case TagApplyStatic => ApplyStatic(readClassType(), readIdent(), readTrees())(readType()) case TagUnaryOp => UnaryOp(readByte(), readTree()) case TagBinaryOp => BinaryOp(readByte(), readTree(), readTree()) @@ -780,12 +743,6 @@ object Serializers { JSObjectConstr(List.fill(readInt())((readPropertyName(), readTree()))) case TagJSLinkingInfo => JSLinkingInfo() - case TagJSEnvInfo => - if (useHacks066) - JSBracketSelect(JSLinkingInfo(), StringLiteral("envInfo")) - else - throw new MatchError(tag) - case TagUndefined => Undefined() case TagNull => Null() case TagBooleanLiteral => BooleanLiteral(readBoolean()) @@ -795,93 +752,40 @@ object Serializers { case TagDoubleLiteral => DoubleLiteral(readDouble()) case TagStringLiteral => StringLiteral(readString()) case TagClassOf => ClassOf(readReferenceType()) - case TagUndefinedParam => UndefinedParam()(readType()) - case TagVarRef => - val result = VarRef(readIdent())(readType()) - if (useHacks060 && result.ident.name == "arguments") - foundArguments = true - result - + case TagVarRef => VarRef(readIdent())(readType()) case TagThis => This()(readType()) - case TagClosure => - Closure(readParamDefs(), readParamDefs(), readTree(), readTrees()) + case TagClosure => Closure(readParamDefs(), readParamDefs(), readTree(), readTrees()) case TagClassDef => val name = readIdent() - val kind0 = ClassKind.fromByte(readByte()) + val kind = ClassKind.fromByte(readByte()) val superClass = readOptIdent() val parents = readIdents() val jsNativeLoadSpec = readJSNativeLoadSpec() - val defs0 = readTrees() - val defs = if (useHacks065) { - defs0.filter { - case MethodDef(_, Ident(name, _), _, _, _) => - !Definitions.isReflProxyName(name) - case _ => - true - } - } else { - defs0 - } + val defs = readTrees() val optimizerHints = new OptimizerHints(readInt()) - - val kind = { - if (useHacks068 && kind0 == ClassKind.AbstractJSType && - jsNativeLoadSpec.isDefined) { - ClassKind.NativeJSClass - } else { - kind0 - } - } - ClassDef(name, kind, superClass, parents, jsNativeLoadSpec, defs)( optimizerHints) case TagFieldDef => - if (useHacks0614) - FieldDef(static = false, readIdent(), readType(), readBoolean()) - else - FieldDef(readBoolean(), readPropertyName(), readType(), readBoolean()) - - case TagStringLitFieldDef if useHacks0614 => - FieldDef(static = false, readTree().asInstanceOf[StringLiteral], - readType(), readBoolean()) + FieldDef(readBoolean(), readPropertyName(), readType(), readBoolean()) case TagMethodDef => val optHash = readOptHash() // read and discard the length val len = readInt() assert(len >= 0) - val result1 = MethodDef(readBoolean(), readPropertyName(), + MethodDef(readBoolean(), readPropertyName(), readParamDefs(), readType(), readOptTree())( new OptimizerHints(readInt()), optHash) - val result2 = if (foundArguments) { - foundArguments = false - new RewriteArgumentsTransformer().transformMethodDef(result1) - } else { - result1 - } - if (useHacks065 && result2.resultType != NoType && - isConstructorName(result2.name.encodedName)) { - result2.copy(resultType = NoType, body = result2.body)( - result2.optimizerHints, result2.hash)( - result2.pos) - } else { - result2 - } case TagPropertyDef => - val static = - if (useHacks0614) false - else readBoolean() + val static = readBoolean() val name = readPropertyName() val getterBody = readOptTree() - val setterArgAndBody = if (useHacks068) { - val setterArg = readTree().asInstanceOf[ParamDef] - readOptTree().map(setterBody => (setterArg, setterBody)) - } else { + val setterArgAndBody = { if (readBoolean()) Some((readTree().asInstanceOf[ParamDef], readTree())) else @@ -890,13 +794,7 @@ object Serializers { PropertyDef(static, name, getterBody, setterArgAndBody) case TagConstructorExportDef => - val result = ConstructorExportDef(readString(), readParamDefs(), readTree()) - if (foundArguments) { - foundArguments = false - new RewriteArgumentsTransformer().transformConstructorExportDef(result) - } else { - result - } + ConstructorExportDef(readString(), readParamDefs(), readTree()) case TagJSClassExportDef => JSClassExportDef(readString()) case TagModuleExportDef => ModuleExportDef(readString()) @@ -974,20 +872,13 @@ object Serializers { readType().asInstanceOf[ReferenceType] def readPropertyName(): PropertyName = { - if (useHacks0614) { - if (input.readBoolean()) readIdent() - else readTree().asInstanceOf[StringLiteral] - } else { - input.readByte() match { - case TagPropertyNameIdent => - readIdent() - - case TagPropertyNameStringLiteral => - readTree().asInstanceOf[StringLiteral] - - case TagPropertyNameComputedName => - ComputedName(readTree(), readString()) - } + input.readByte() match { + case TagPropertyNameIdent => + readIdent() + case TagPropertyNameStringLiteral => + readTree().asInstanceOf[StringLiteral] + case TagPropertyNameComputedName => + ComputedName(readTree(), readString()) } } @@ -1040,19 +931,13 @@ object Serializers { } def readJSNativeLoadSpec(): Option[JSNativeLoadSpec] = { - if (useHacks068) { - Some(readString()).filter(_ != "").map { jsFullName => - JSNativeLoadSpec.Global(jsFullName.split("\\.").toList) - } - } else { - (input.readByte(): @switch) match { - case TagJSNativeLoadSpecNone => - None - case TagJSNativeLoadSpecGlobal => - Some(JSNativeLoadSpec.Global(readStrings())) - case TagJSNativeLoadSpecImport => - Some(JSNativeLoadSpec.Import(readString(), readStrings())) - } + (input.readByte(): @switch) match { + case TagJSNativeLoadSpecNone => + None + case TagJSNativeLoadSpecGlobal => + Some(JSNativeLoadSpec.Global(readStrings())) + case TagJSNativeLoadSpecImport => + Some(JSNativeLoadSpec.Import(readString(), readStrings())) } } @@ -1073,58 +958,4 @@ object Serializers { def readStrings(): List[String] = List.fill(input.readInt())(readString()) } - - private class RewriteArgumentsTransformer extends Transformers.Transformer { - import RewriteArgumentsTransformer._ - - private[this] var paramToIndex: Map[String, Int] = _ - - def transformMethodDef(tree: MethodDef): MethodDef = { - /* Ideally, we would re-hash the new MethodDef here, but we cannot do - * that because it prevents the JS version of the tools to link. - * Since the hashes of exported methods are not used by our pipeline - * anyway, we simply put None. - */ - val MethodDef(static, name, args, resultType, body) = tree - setupParamToIndex(args) - MethodDef(static, name, List(argumentsParamDef(tree.pos)), - resultType, body.map(transform(_, isStat = resultType == NoType)))( - tree.optimizerHints, None)(tree.pos) - } - - def transformConstructorExportDef( - tree: ConstructorExportDef): ConstructorExportDef = { - val ConstructorExportDef(name, args, body) = tree - setupParamToIndex(args) - ConstructorExportDef(name, List(argumentsParamDef(tree.pos)), - transformStat(body))(tree.pos) - } - - private def setupParamToIndex(params: List[ParamDef]): Unit = - paramToIndex = params.map(_.name.name).zipWithIndex.toMap - - private def argumentsParamDef(implicit pos: Position): ParamDef = - ParamDef(Ident(ArgumentsName), AnyType, mutable = false, rest = true) - - private def argumentsRef(implicit pos: Position): VarRef = - VarRef(Ident(ArgumentsName))(AnyType) - - override def transform(tree: Tree, isStat: Boolean): Tree = tree match { - case VarRef(Ident(name, origName)) => - implicit val pos = tree.pos - paramToIndex.get(name).fold { - if (name == "arguments") argumentsRef - else tree - } { paramIndex => - JSBracketSelect(argumentsRef, IntLiteral(paramIndex)) - } - - case _ => - super.transform(tree, isStat) - } - } - - private object RewriteArgumentsTransformer { - private final val ArgumentsName = "$arguments" - } } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala index f627595124..469f13380c 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala @@ -29,10 +29,7 @@ private[ir] object Tags { final val TagWhile = TagIf + 1 final val TagDoWhile = TagWhile + 1 - // TODO remove when we can break binary compat. - final val TagTry = TagDoWhile + 1 - - final val TagThrow = TagTry + 1 + final val TagThrow = TagDoWhile + 1 final val TagContinue = TagThrow + 1 final val TagMatch = TagContinue + 1 final val TagDebugger = TagMatch + 1 @@ -68,9 +65,8 @@ private[ir] object Tags { final val TagJSBinaryOp = TagJSUnaryOp + 1 final val TagJSArrayConstr = TagJSBinaryOp + 1 final val TagJSObjectConstr = TagJSArrayConstr + 1 - final val TagJSEnvInfo = TagJSObjectConstr + 1 - final val TagUndefined = TagJSEnvInfo + 1 + final val TagUndefined = TagJSObjectConstr + 1 final val TagUndefinedParam = TagUndefined + 1 // TODO Move this final val TagNull = TagUndefinedParam + 1 final val TagBooleanLiteral = TagNull + 1 @@ -95,8 +91,7 @@ private[ir] object Tags { // TODO Reorganize these when we can break binary compatibility final val TagJSSpread = TagModuleExportDef + 1 final val TagJSLinkingInfo = TagJSSpread + 1 - final val TagStringLitFieldDef = TagJSLinkingInfo + 1 - final val TagJSSuperBracketSelect = TagStringLitFieldDef + 1 + final val TagJSSuperBracketSelect = TagJSLinkingInfo + 1 final val TagJSSuperBracketCall = TagJSSuperBracketSelect + 1 final val TagJSSuperConstructorCall = TagJSSuperBracketCall + 1 final val TagLoadJSConstructor = TagJSSuperConstructorCall + 1 diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala index 18b209f638..d8f0d88c9a 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala @@ -117,20 +117,6 @@ object Analysis { /** Not a synthetic method. */ final case object None extends MethodSyntheticKind - // TODO Get rid of InheritedConstructor when we can break binary compat - /** An explicit call-super constructor. - * - * In a class `Foo` with parent class `Bar`, an inherited - * constructor `init___xyz` looks like - * - * {{{ - * def init___xyz(p1: T1, ..., pn: TN) { - * this.Bar::init___xyz(p1, ..., pn) - * } - * }}} - */ - final case object InheritedConstructor extends MethodSyntheticKind - /** A reflective proxy bridge to the appropriate target method. * * A reflective proxy `method__xyz__` dynamically calls some `target` diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala index 340a22b80f..4891b6891f 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala @@ -271,32 +271,8 @@ private final class Analyzer(semantics: Semantics, } def lookupConstructor(ctorName: String): MethodInfo = { - /* As of 0.6.6, constructors are not inherited, and so must be found - * directly in this class. However, to be able to read sjsir files from - * before 0.6.6, we tolerate finding it in a superclass, in which case - * we materialize a new constructor in this class. We only allow this - * during the initial link. In a refiner, this must not happen anymore. - */ methodInfos.get(ctorName).getOrElse { - if (!allowAddingSyntheticMethods) { - createNonExistentMethod(ctorName) - } else { - val inherited = lookupMethod(ctorName) - if (inherited.owner eq this) { - // Can happen only for non-existent constructors, at this point - assert(inherited.nonExistent) - inherited - } else { - val syntheticInfo = makeSyntheticMethodInfo( - encodedName = ctorName, - methodsCalledStatically = Map( - superClass.encodedName -> List(ctorName))) - val m = new MethodInfo(this, syntheticInfo) - m.syntheticKind = MethodSyntheticKind.InheritedConstructor - methodInfos += ctorName -> m - m - } - } + createNonExistentMethod(ctorName) } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/InfoChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/InfoChecker.scala index 18cfa7afb7..999e266b59 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/InfoChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/InfoChecker.scala @@ -43,22 +43,9 @@ private final class InfoChecker( private def checkClassInfo(info: ClassInfo, expectedInfo: ClassInfo): Unit = { val className = expectedInfo.encodedName - /* Due to the hack for AbstractJSType and NativeJSClass in the - * deserializer, it is possible to get info where `kind == AbstractJSType` - * but `expectedInfo == NativeJSClass`. We need to tolerate that here. - * TODO Get rid of this when we break binary compatibility. - */ - val patchedInfoKind = { - import ClassKind._ - if (info.kind == AbstractJSType && expectedInfo.kind == NativeJSClass) - NativeJSClass - else - info.kind - } - if (info.encodedName != expectedInfo.encodedName || info.isExported != expectedInfo.isExported || - patchedInfoKind != expectedInfo.kind || + info.kind != expectedInfo.kind || info.superClass != expectedInfo.superClass || info.interfaces.toSet != expectedInfo.interfaces.toSet) { errorCount += 1 diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index f04ed3f749..ea26ae5f73 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -250,11 +250,6 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, case MethodSyntheticKind.None => // nothing to do - case MethodSyntheticKind.InheritedConstructor => - val syntheticMDef = synthesizeInheritedConstructor( - analyzerInfo, m, getTree, analysis)(classDef.pos) - memberMethods += linkedSyntheticMethod(syntheticMDef) - case MethodSyntheticKind.ReflectiveProxy(targetName) => val syntheticMDef = synthesizeReflectiveProxy( analyzerInfo, m, targetName, getTree, analysis) @@ -298,28 +293,6 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, version) } - private def synthesizeInheritedConstructor( - classInfo: Analysis.ClassInfo, methodInfo: Analysis.MethodInfo, - getTree: TreeProvider, analysis: Analysis)( - implicit pos: Position): MethodDef = { - val encodedName = methodInfo.encodedName - - val inheritedMDef = findInheritedMethodDef(analysis, classInfo.superClass, - encodedName, getTree, _.syntheticKind == MethodSyntheticKind.None) - - val origName = inheritedMDef.name.asInstanceOf[Ident].originalName - val ctorIdent = Ident(encodedName, origName) - val params = inheritedMDef.args.map(_.copy()) // for the new pos - val currentClassType = ClassType(classInfo.encodedName) - val superClassType = ClassType(classInfo.superClass.encodedName) - MethodDef(static = false, ctorIdent, - params, NoType, - Some(ApplyStatically(This()(currentClassType), - superClassType, ctorIdent, params.map(_.ref))(NoType)))( - OptimizerHints.empty, - inheritedMDef.hash) // over-approximation - } - private def synthesizeReflectiveProxy( classInfo: Analysis.ClassInfo, methodInfo: Analysis.MethodInfo, targetName: String, getTree: TreeProvider, @@ -397,8 +370,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, val targetInterfaceInfo = analysis.classInfos(targetInterface) findMethodDef(targetInterfaceInfo, methodName, getTree) - case MethodSyntheticKind.InheritedConstructor | - MethodSyntheticKind.ReflectiveProxy(_) => + case MethodSyntheticKind.ReflectiveProxy(_) => throw new AssertionError( s"Cannot recursively follow $ancestorInfo.$methodName of " + s"kind ${m.syntheticKind}") From 918b0d171444c23b9bf0f6fef3a375d1a015dad9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 9 May 2017 13:59:39 +0200 Subject: [PATCH 0256/2665] Remove dead code related to the test interface and exportsNamespace. This is a follow up to #2932. The changes in this commit were forgotten in that PR. --- .../internal/FrameworkDetector.scala | 19 +------------------ .../internal/FrameworkLoader.scala | 11 +++-------- .../scalajs/testsuite/junit/JUnitUtil.scala | 3 +-- 3 files changed, 5 insertions(+), 28 deletions(-) diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkDetector.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkDetector.scala index f9dfe0c3ec..cd6480d87d 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkDetector.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkDetector.scala @@ -10,29 +10,12 @@ private[internal] object FrameworkDetector { def detectFrameworks( frameworksData: js.Array[js.Array[String]]): js.Array[js.UndefOr[String]] = { - def frameworkExistsInReflect(name: String): Boolean = { + def frameworkExists(name: String): Boolean = { Reflect.lookupInstantiatableClass(name).exists { clazz => classOf[sbt.testing.Framework].isAssignableFrom(clazz.runtimeClass) } } - def frameworkExistsInExportsNamespace(name: String): Boolean = { - /* This happens for testing frameworks developed before 0.6.15 that have - * not yet updated to using reflective instantiation, and are still - * using exports. - * Note that here, we have to assume that whatever we find is indeed a - * proper class export for a class extending sbt.testing.Framework. - */ - val exportsNamespace = - scala.scalajs.runtime.environmentInfo.exportsNamespace - name.split('.').foldLeft[js.UndefOr[js.Dynamic]](exportsNamespace) { - (prev, part) => prev.map(_.selectDynamic(part)) - }.isDefined - } - - def frameworkExists(name: String): Boolean = - frameworkExistsInReflect(name) || frameworkExistsInExportsNamespace(name) - for (frameworkNames <- frameworksData) yield frameworkNames.find(frameworkExists(_)).orUndefined } diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkLoader.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkLoader.scala index 3ca64d85fb..ed2b59aafa 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkLoader.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkLoader.scala @@ -8,15 +8,10 @@ import sbt.testing.Framework private[internal] object FrameworkLoader { def loadFramework(frameworkName: String): Framework = { - Reflect.lookupInstantiatableClass(frameworkName).fold[Framework] { - val exportsNamespace = - scala.scalajs.runtime.environmentInfo.exportsNamespace - val parts = frameworkName.split('.') - val ctor = parts.foldLeft(exportsNamespace)(_.selectDynamic(_)) - js.Dynamic.newInstance(ctor)().asInstanceOf[Framework] - } { clazz => - clazz.newInstance().asInstanceOf[Framework] + val clazz = Reflect.lookupInstantiatableClass(frameworkName).getOrElse { + throw new InstantiationError(frameworkName) } + clazz.newInstance().asInstanceOf[Framework] } } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala index dfdc3295c5..f1076986fc 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala @@ -11,8 +11,7 @@ object JUnitUtil { def loadBootstrapper(classFullName: String): JUnitTestBootstrapper = { val fullName = s"$classFullName$BootstrapperSuffix" try { - val loader = new ScalaJSClassLoader( - scala.scalajs.runtime.environmentInfo.exportsNamespace) + val loader = new ScalaJSClassLoader() TestUtils.loadModule(fullName, loader).asInstanceOf[JUnitTestBootstrapper] } catch { case ex: Throwable => From ba4f63fa1c4944212316f5927480ff7c0c6f0e3a Mon Sep 17 00:00:00 2001 From: "Marius B. Kotsbak" Date: Mon, 1 May 2017 16:33:36 +0200 Subject: [PATCH 0257/2665] Fix #1275: Use ES6 Math functions when available. Improve tests for the modified functions. --- .../src/main/scala/java/lang/Math.scala | 171 +++++++++++------- .../main/scala/scala/scalajs/js/Math.scala | 75 ++++++++ .../testsuite/javalib/lang/MathTest.scala | 56 ++++-- 3 files changed, 222 insertions(+), 80 deletions(-) diff --git a/javalanglib/src/main/scala/java/lang/Math.scala b/javalanglib/src/main/scala/java/lang/Math.scala index 4f2c0cf549..b7e944a236 100644 --- a/javalanglib/src/main/scala/java/lang/Math.scala +++ b/javalanglib/src/main/scala/java/lang/Math.scala @@ -2,6 +2,9 @@ package java package lang import scala.scalajs.js +import js.Dynamic.{ global => g } + +import scala.scalajs.LinkingInfo.assumingES6 object Math { final val E = 2.718281828459045 @@ -46,8 +49,20 @@ object Math { @inline def exp(a: scala.Double): scala.Double = js.Math.exp(a) @inline def log(a: scala.Double): scala.Double = js.Math.log(a) - @inline def log10(a: scala.Double): scala.Double = log(a) / 2.302585092994046 - @inline def log1p(a: scala.Double): scala.Double = log(a + 1) + + @inline def log10(a: scala.Double): scala.Double = { + if (assumingES6 || !js.isUndefined(g.Math.log10)) + js.Math.log10(a) + else + log(a) / 2.302585092994046 + } + + @inline def log1p(a: scala.Double): scala.Double = { + if (assumingES6 || !js.isUndefined(g.Math.log1p)) + js.Math.log1p(a) + else if (a == 0.0) a + else log(a + 1) + } @inline def sin(a: scala.Double): scala.Double = js.Math.sin(a) @inline def cos(a: scala.Double): scala.Double = js.Math.cos(a) @@ -75,24 +90,28 @@ object Math { } def cbrt(a: scala.Double): scala.Double = { - if (a == 0 || a.isNaN) { - a + if (assumingES6 || !js.isUndefined(g.Math.cbrt)) { + js.Math.cbrt(a) } else { - val sign = if (a < 0.0) -1.0 else 1.0 - val value = sign * a - - //Initial Approximation - var x = 0.0 - var xi = pow(value, 0.3333333333333333) - - //Halley's Method (http://metamerist.com/cbrt/cbrt.htm) - while (abs(x - xi) >= 1E-16) { - x = xi - val x3 = js.Math.pow(x, 3) - val x3Plusa = x3 + value - xi = x * (x3Plusa + value) / (x3Plusa + x3) + if (a == 0 || a.isNaN || a.isPosInfinity || a.isNegInfinity) { + a + } else { + val sign = if (a < 0.0) -1.0 else 1.0 + val value = sign * a + + //Initial Approximation + var x = 0.0 + var xi = pow(value, 0.3333333333333333) + + //Halley's Method (http://metamerist.com/cbrt/cbrt.htm) + while (abs(x - xi) >= 1E-16) { + x = xi + val x3 = js.Math.pow(x, 3) + val x3Plusa = x3 + value + xi = x * (x3Plusa + value) / (x3Plusa + x3) + } + sign * xi } - sign * xi } } @@ -176,69 +195,87 @@ object Math { } def hypot(a: scala.Double, b: scala.Double): scala.Double = { - // http://en.wikipedia.org/wiki/Hypot#Implementation - if (abs(a) == scala.Double.PositiveInfinity || abs(b) == scala.Double.PositiveInfinity) - scala.Double.PositiveInfinity - else if (a.isNaN || b.isNaN) - scala.Double.NaN - else if (a == 0 && b == 0) - 0.0 - else { - //To Avoid Overflow and UnderFlow - // calculate |x| * sqrt(1 - (y/x)^2) instead of sqrt(x^2 + y^2) - val x = abs(a) - val y = abs(b) - val m = max(x, y) - val t = min(x, y) / m - m * sqrt(1 + t * t) + if (assumingES6 || !js.isUndefined(g.Math.hypot)) { + js.Math.hypot(a, b) + } else { + // http://en.wikipedia.org/wiki/Hypot#Implementation + if (abs(a) == scala.Double.PositiveInfinity || abs(b) == scala.Double.PositiveInfinity) + scala.Double.PositiveInfinity + else if (a.isNaN || b.isNaN) + scala.Double.NaN + else if (a == 0 && b == 0) + 0.0 + else { + //To Avoid Overflow and UnderFlow + // calculate |x| * sqrt(1 - (y/x)^2) instead of sqrt(x^2 + y^2) + val x = abs(a) + val y = abs(b) + val m = max(x, y) + val t = min(x, y) / m + m * sqrt(1 + t * t) + } } } def expm1(a: scala.Double): scala.Double = { - // https://github.com/ghewgill/picomath/blob/master/javascript/expm1.js - if (a == 0 || a.isNaN) - a - // Power Series http://en.wikipedia.org/wiki/Power_series - // for small values of a, exp(a) = 1 + a + (a*a)/2 - else if (abs(a) < 1E-5) - a + 0.5 * a * a - else - exp(a) - 1.0 + if (assumingES6 || !js.isUndefined(g.Math.expm1)) { + js.Math.expm1(a) + } else { + // https://github.com/ghewgill/picomath/blob/master/javascript/expm1.js + if (a == 0 || a.isNaN) + a + // Power Series http://en.wikipedia.org/wiki/Power_series + // for small values of a, exp(a) = 1 + a + (a*a)/2 + else if (abs(a) < 1E-5) + a + 0.5 * a * a + else + exp(a) - 1.0 + } } def sinh(a: scala.Double): scala.Double = { - if (a.isNaN || a == 0.0 || abs(a) == scala.Double.PositiveInfinity) - a - else - (exp(a) - exp(-a)) / 2.0 + if (assumingES6 || !js.isUndefined(g.Math.sinh)) { + js.Math.sinh(a) + } else { + if (a.isNaN || a == 0.0 || abs(a) == scala.Double.PositiveInfinity) a + else (exp(a) - exp(-a)) / 2.0 + } } def cosh(a: scala.Double): scala.Double = { - if (a.isNaN) - a - else if (a == 0.0) - 1.0 - else if (abs(a) == scala.Double.PositiveInfinity) - scala.Double.PositiveInfinity - else - (exp(a) + exp(-a)) / 2.0 + if (assumingES6 || !js.isUndefined(g.Math.cosh)) { + js.Math.cosh(a) + } else { + if (a.isNaN) + a + else if (a == 0.0) + 1.0 + else if (abs(a) == scala.Double.PositiveInfinity) + scala.Double.PositiveInfinity + else + (exp(a) + exp(-a)) / 2.0 + } } def tanh(a: scala.Double): scala.Double = { - if (a.isNaN || a == 0.0) - a - else if (abs(a) == scala.Double.PositiveInfinity) - signum(a) - else { - // sinh(a) / cosh(a) = - // 1 - 2 * (exp(-a)/ (exp(-a) + exp (a))) - val expma = exp(-a) - if (expma == scala.Double.PositiveInfinity) //Infinity / Infinity - -1.0 + if (assumingES6 || !js.isUndefined(g.Math.tanh)) { + js.Math.tanh(a) + } else { + if (a.isNaN || a == 0.0) + a + else if (abs(a) == scala.Double.PositiveInfinity) + signum(a) else { - val expa = exp(a) - val ret = expma / (expa + expma) - 1.0 - (2.0 * ret) + // sinh(a) / cosh(a) = + // 1 - 2 * (exp(-a)/ (exp(-a) + exp (a))) + val expma = exp(-a) + if (expma == scala.Double.PositiveInfinity) //Infinity / Infinity + -1.0 + else { + val expa = exp(a) + val ret = expma / (expa + expma) + 1.0 - (2.0 * ret) + } } } } diff --git a/library/src/main/scala/scala/scalajs/js/Math.scala b/library/src/main/scala/scala/scalajs/js/Math.scala index c9f07a331b..db9f06b2e7 100644 --- a/library/src/main/scala/scala/scalajs/js/Math.scala +++ b/library/src/main/scala/scala/scalajs/js/Math.scala @@ -278,4 +278,79 @@ object Math extends Object { * MDN */ def tan(x: Double): Double = native + + /** ECMAScript 6 + * The Math.log1p() function returns the natural logarithm (base e) of + * 1 + a number + * + * @return The natural logarithm (base e) of 1 plus the given number. + * If the number is less than -1, NaN is returned. + * MDN + */ + def log1p(x: Double): Double = native + + /** ECMAScript 6 + * The Math.log10() function returns the base 10 logarithm of a number + * + * @return The base 10 logarithm of the given number. If the number is + * negative, NaN is returned. + * + * MDN + */ + def log10(x: Double): Double = native + + /** ECMAScript 6 + * The Math.sinh() function returns the hyperbolic sine of a number + * + * @return The hyperbolic sine of the given number + * + * MDN + */ + def sinh(x: Double): Double = native + + /** ECMAScript 6 + * The Math.cosh() function returns the hyperbolic cosine of a number + * + * @return The hyperbolic cosine of the given number + * + * MDN + */ + def cosh(x: Double): Double = native + + /** ECMAScript 6 + * The Math.tanh() function returns the hyperbolic tangent of a number + * + * @return The hyperbolic tangent of the given number + * + * MDN + */ + def tanh(x: Double): Double = native + + /** ECMAScript 6 + * The Math.cbrt() function returns the cube root of a number + * + * @return The cube root of the given number. + * + * MDN + */ + def cbrt(x: Double): Double = native + + /** ECMAScript 6 + * The Math.hypot() function returns the square root of the sum of squares + * of its arguments + * + * @return The square root of the sum of squares of the given arguments. + * + * MDN + */ + def hypot(x: Double*): Double = native + + /** ECMAScript 6 + * The Math.expm1() function returns e^x - 1, where x is the argument, + * and e the base of the natural logarithms. + * + * @return A number representing e^x - 1, where e is Euler's number and + * x is the argument. + */ + def expm1(x: Double): Double = native } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/MathTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/MathTest.scala index 60160a132d..9d3dc01bf1 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/MathTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/MathTest.scala @@ -30,7 +30,8 @@ class MathTest { assertTrue(s"expected: $expected but was: $actual", expected.equals(actual)) @Test def abs(): Unit = { - assertEquals(0, Math.abs(0)) + assertSameDouble(0, Math.abs(0)) + assertSameDouble(0.0, Math.abs(-0.0)) assertEquals(42, Math.abs(42)) assertEquals(42, Math.abs(-42)) assertTrue(Math.abs(0.0).equals(0.0)) @@ -81,33 +82,47 @@ class MathTest { } @Test def cbrt(): Unit = { - assertTrue(1 / Math.cbrt(-0.0) < 0) + assertSameDouble(-0.0, Math.cbrt(-0.0)) + assertSameDouble(0.0, Math.cbrt(0.0)) assertEquals(3.0, Math.cbrt(27.0), 0.0) assertEquals(100.0, Math.cbrt(1000000.0), 0.0) assertEquals(1000.0, Math.cbrt(1000000000.0), 0.0) assertEquals(-100000000.0, Math.cbrt(-1.0E24), 0.0) assertEquals(-4039.0E8, Math.cbrt(-65890311319.0E24), 0.0) + assertTrue(Math.cbrt(Double.NaN).isNaN) + assertSameDouble(Double.PositiveInfinity, Math.cbrt(Double.PositiveInfinity)) + assertSameDouble(Double.NegativeInfinity, Math.cbrt(Double.NegativeInfinity)) } @Test def log1p(): Unit = { assertTrue(Math.log1p(-2.0).isNaN) assertTrue(Math.log1p(Double.NaN).isNaN) - assertEquals(0.0, Math.log1p(0.0), 0.0) + assertSameDouble(0.0, Math.log1p(0.0)) + assertSameDouble(-0.0, Math.log1p(-0.0)) + assertTrue(Math.log1p(Double.NaN).isNaN) + assertSameDouble(Double.PositiveInfinity, Math.log1p(Double.PositiveInfinity)) + assertTrue(Math.log1p(Double.NegativeInfinity).isNaN) + assertSameDouble(Double.NegativeInfinity, Math.log1p(-1)) } @Test def log10(): Unit = { assertTrue(Math.log10(-230.0).isNaN) assertTrue(Math.log10(Double.NaN).isNaN) + assertSameDouble(Double.NegativeInfinity, Math.log10(0.0)) + assertSameDouble(Double.NegativeInfinity, Math.log10(-0.0)) + assertTrue(Math.log10(Double.NaN).isNaN) + assertSameDouble(Double.PositiveInfinity, Math.log10(Double.PositiveInfinity)) + assertTrue(Math.log10(Double.NegativeInfinity).isNaN) } @Test def signum_for_Double(): Unit = { assertEquals(1.0, Math.signum(234394.2198273), 0.0) assertEquals(-1.0, Math.signum(-124937498.58), 0.0) - assertEquals(0.0, Math.signum(+0.0), 0.0) + assertSameDouble(0.0, Math.signum(+0.0)) assertTrue(1 / Math.signum(+0.0) > 0) - assertEquals(-0.0, Math.signum(-0.0), 0.0) + assertSameDouble(-0.0, Math.signum(-0.0)) assertTrue(1 / Math.signum(-0.0) < 0) assertTrue(Math.signum(Double.NaN).isNaN) @@ -117,11 +132,8 @@ class MathTest { assertEquals(1.0f, Math.signum(234394.2198273f), 0.0f) assertEquals(-1.0f, Math.signum(-124937498.58f), 0.0f) - assertEquals(0.0f, Math.signum(+0.0f), 0.0f) - assertTrue(1 / Math.signum(+0.0f) > 0) - - assertEquals(-0.0f, Math.signum(-0.0f), 0.0f) - assertTrue(1 / Math.signum(-0.0f) < 0) + assertSameFloat(0.0f, Math.signum(+0.0f)) + assertSameFloat(-0.0f, Math.signum(-0.0f)) assertTrue(Math.signum(Float.NaN).isNaN) } @@ -247,41 +259,59 @@ class MathTest { assertEquals(0.0, Math.hypot(0.0, 0.0), 0.01) assertEquals(5.0, Math.hypot(3.0, 4.0), 0.01) assertTrue(Math.hypot(3.0, Double.NaN).isNaN) + assertTrue(Math.hypot(Double.NaN, 3.0).isNaN) assertEquals(Double.PositiveInfinity, Math.hypot(Double.NegativeInfinity, 4.0), 0.0) + assertEquals(Double.PositiveInfinity, Math.hypot(4.0, Double.NegativeInfinity), 0.0) + assertEquals(Double.PositiveInfinity, Math.hypot(Double.PositiveInfinity, 4.0), 0.0) + assertEquals(Double.PositiveInfinity, Math.hypot(4.0, Double.PositiveInfinity), 0.0) + assertSameDouble(0.0, Math.hypot(-0.0, -0.0)) + assertSameDouble(0.0, Math.hypot(0.0, -0.0)) + assertSameDouble(0.0, Math.hypot(-0.0, 0.0)) } @Test def expm1(): Unit = { assertTrue(1 / Math.expm1(-0.0) < 0) - assertEquals(0.0, Math.expm1(-0.0), 0.01) + assertTrue(1 / Math.expm1(0.0) > 0) + assertSameDouble(-0.0, Math.expm1(-0.0)) + assertSameDouble(0.0, Math.expm1(0.0)) assertEquals(19.085536923187668, Math.expm1(3.0), 0.01) assertEquals(3269016.3724721107, Math.expm1(15.0), 0.01) assertEquals(Double.PositiveInfinity, Math.expm1(1.8E10), 0.0) assertEquals(Double.PositiveInfinity, Math.expm1(Double.PositiveInfinity), 0.0) assertEquals(-1.0, Math.expm1(Double.NegativeInfinity), 0.01) assertEquals(4.9E-324, Math.expm1(4.9E-324), 0.01) + assertTrue(Math.expm1(Double.NaN).isNaN) } @Test def sinh(): Unit = { assertEquals(Double.NegativeInfinity, Math.sinh(-1234.56), 0.0) assertEquals(Double.PositiveInfinity, Math.sinh(1234.56), 0.0) - assertEquals(0.0, Math.sinh(0.0), 0.01) + assertSameDouble(0.0, Math.sinh(0.0)) + assertSameDouble(-0.0, Math.sinh(-0.0)) assertEquals(Double.PositiveInfinity, Math.sinh(Double.PositiveInfinity), 0.0) + assertEquals(Double.NegativeInfinity, Math.sinh(Double.NegativeInfinity), 0.0) + assertTrue(Math.sinh(Double.NaN).isNaN) } @Test def cosh(): Unit = { assertEquals(Double.PositiveInfinity, Math.cosh(-1234.56), 0.0) assertEquals(Double.PositiveInfinity, Math.cosh(1234.56), 0.0) assertEquals(1.0, Math.cosh(-0.0), 0.01) + assertEquals(1.0, Math.cosh(0.0), 0.01) assertEquals(Double.PositiveInfinity, Math.cosh(Double.PositiveInfinity), 0.0) + assertEquals(Double.PositiveInfinity, Math.cosh(Double.NegativeInfinity), 0.0) + assertTrue(Math.cosh(Double.NaN).isNaN) } @Test def tanh(): Unit = { assertEquals(-1.0, Math.tanh(-1234.56), 0.01) assertEquals(-1.0, Math.tanh(-120.56), 0.01) assertEquals(1.0, Math.tanh(1234.56), 0.01) - assertEquals(0.0, Math.tanh(0.0), 0.01) + assertSameDouble(0.0, Math.tanh(0.0)) + assertSameDouble(-0.0, Math.tanh(-0.0)) assertEquals(1.0, Math.tanh(Double.PositiveInfinity), 0.01) assertEquals(-1.0, Math.tanh(Double.NegativeInfinity), 0.01) + assertTrue(Math.tanh(Double.NaN).isNaN) } @Test def rint_for_Double(): Unit = { From f6e4f4f43953d5bc4118c71148ad81a465eca7fd Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Fri, 12 May 2017 20:40:24 +0200 Subject: [PATCH 0258/2665] Pass `remoteArgs` to `Slave` in test interface --- .../main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala index aebce10ce2..b49d7f8501 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala @@ -193,7 +193,7 @@ final class ScalaJSRunner private[testadapter] ( val prefix = framework.optionalExportsNamespacePrefix val frameworkJS = jsonToString(framework.frameworkName.toJSON) val argsJS = jsonToString(args.toList.toJSON) - val remoteArgsJS = jsonToString(args.toList.toJSON) + val remoteArgsJS = jsonToString(remoteArgs.toList.toJSON) val code = s""" new ${prefix}org.scalajs.testinterface.internal.Slave($frameworkJS, $argsJS, $remoteArgsJS).init(); From 3544341c57a2d1aa4a978e3eac785e3686921f38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 19 May 2017 16:40:13 +0200 Subject: [PATCH 0259/2665] Fix #2928: Handle the shapes produced by `return x match {...}`. For some reason, for such a snippet, the `Return` node directly wraps the `LabelDef(matchEnd)`, rather than the `Block` surrounding the entire translated pattern match. --- .../org/scalajs/core/compiler/GenJSCode.scala | 10 +++++++ .../testsuite/compiler/RegressionTest.scala | 27 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 992302020c..d511366ebe 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -2959,6 +2959,16 @@ abstract class GenJSCode extends plugins.PluginComponent if isCaseLabelDef(expr) => translateMatch(expr) + // Peculiar shape generated by `return x match {...}` - #2928 + case Return(retExpr: LabelDef) if isCaseLabelDef(retExpr) => + val result = translateMatch(retExpr) + if (result.tpe == jstpe.NoType) { + // Could not actually reproduce this, but better be safe than sorry + js.Block(result, js.Return(js.Undefined())) + } else { + js.Return(result) + } + case _ => assert(!stats.exists(isCaseLabelDef), "Found stats with case label " + s"def in non-match block at ${tree.pos}: $tree") diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala index e8ece13e2b..f126b6974f 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala @@ -384,6 +384,33 @@ class RegressionTest { assertThrows(classOf[MatchError], bug.bug(2, false)) } + @Test def return_x_match_issue_2928(): Unit = { + def testNonUnit(x: String): Boolean = { + return x match { + case "True" => true + case _ => false + } + } + + var r: Option[Boolean] = None + + def testUnit(x: String): Unit = { + return x match { + case "True" => r = Some(true) + case _ => r = Some(false) + } + } + + assertEquals(true, testNonUnit("True")) + assertEquals(false, testNonUnit("not true")) + + testUnit("True") + assertEquals(Some(true), r) + r = None + testUnit("not true") + assertEquals(Some(false), r) + } + @Test def null_asInstanceOf_Unit_should_succeed_issue_1691(): Unit = { /* Avoid scalac's special treatment of `.asInstanceOf[X]`. * It does have the benefit to test our constant-folder of that pattern, From eb0ca6e5ea930a6f543224c2aa41a71cffaee7df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 19 May 2017 18:39:56 +0200 Subject: [PATCH 0260/2665] Fix #2953: Avoid calling toString() in primitive isInstanceOf's. Even though `(v | 0) === v` will indeed return `false` when `v` is not even a `number`, the part `v | 0` will cause the internal spec function `ToPrimitive(v, hint Number)` to be called. That function (section 7.1.1 of the ES 2015 specification) will first try to call `v.valueOf()` if it exists, and otherwise will try `v.toString()`. We must avoid this scenario by preemptively ruling out values that are not `number`s, which we do with a simple `typeof` test. --- .../testsuite/compiler/RegressionTest.scala | 22 +++++++++++++++++++ tools/scalajsenv.js | 8 +++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala index e8ece13e2b..ee662bda1d 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala @@ -535,6 +535,28 @@ class RegressionTest { assertTrue(f3A != f4B) } + @Test def isInstanceOf_must_not_call_toString_issue_2953(): Unit = { + class C { + override def toString(): String = + throw new AssertionError("C.toString must not be called by isInstanceOf") + } + + @noinline def makeC(): Any = new C + + val c = makeC() + + assertFalse("Boolean", c.isInstanceOf[Boolean]) + assertFalse("Char", c.isInstanceOf[Char]) + assertFalse("Byte", c.isInstanceOf[Byte]) + assertFalse("Short", c.isInstanceOf[Short]) + assertFalse("Int", c.isInstanceOf[Int]) + assertFalse("Long", c.isInstanceOf[Long]) + assertFalse("Float", c.isInstanceOf[Float]) + assertFalse("Double", c.isInstanceOf[Double]) + assertFalse("Unit", c.isInstanceOf[Unit]) + assertFalse("String", c.isInstanceOf[String]) + } + } object RegressionTest { diff --git a/tools/scalajsenv.js b/tools/scalajsenv.js index 5345ba8e68..c89c951d15 100644 --- a/tools/scalajsenv.js +++ b/tools/scalajsenv.js @@ -602,20 +602,20 @@ ScalaJS.systemIdentityHashCode = // is/as for hijacked boxed classes (the non-trivial ones) ScalaJS.isByte = function(v) { - return (v << 24 >> 24) === v && 1/v !== 1/-0; + return typeof v === "number" && (v << 24 >> 24) === v && 1/v !== 1/-0; }; ScalaJS.isShort = function(v) { - return (v << 16 >> 16) === v && 1/v !== 1/-0; + return typeof v === "number" && (v << 16 >> 16) === v && 1/v !== 1/-0; }; ScalaJS.isInt = function(v) { - return (v | 0) === v && 1/v !== 1/-0; + return typeof v === "number" && (v | 0) === v && 1/v !== 1/-0; }; ScalaJS.isFloat = function(v) { //!if floats == Strict - return v !== v || ScalaJS.fround(v) === v; + return typeof v === "number" && (v !== v || ScalaJS.fround(v) === v); //!else return typeof v === "number"; //!endif From 4b9754029fdd97a97b6525ce77a1c5036ab3b7f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 19 May 2017 16:58:43 +0200 Subject: [PATCH 0261/2665] Fix #2773: Missing AsInstanceOf in some pattern matches. In fe887a930e50790c514c507a179e17db9672e953, we added some code to recognize shapes of pattern matches where the `expr` is a cast surrounding the `matchEnd`. However, that code forgot to actually translate the cast itself, yielding untypeable code. This commit fixes that omission. --- .../org/scalajs/core/compiler/GenJSCode.scala | 27 ++++++++++++------- .../frontend/optimizer/OptimizerCore.scala | 6 +---- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index d511366ebe..29b8917e94 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -2296,14 +2296,19 @@ abstract class GenJSCode extends plugins.PluginComponent /** Gen `isInstanceOf` or `asInstanceOf`. */ private def genIsAsInstanceOf(obj: Tree, targs: List[Tree], cast: Boolean)( implicit pos: Position): js.Tree = { - val to = targs.head.tpe - val l = toTypeKind(obj.tpe) + genIsAsInstanceOf(genExpr(obj), obj.tpe, targs.head.tpe, cast) + } + + /** Gen `isInstanceOf` or `asInstanceOf`. */ + private def genIsAsInstanceOf(expr: js.Tree, from: Type, to: Type, + cast: Boolean)( + implicit pos: Position): js.Tree = { + val l = toTypeKind(from) val r = toTypeKind(to) - val source = genExpr(obj) if (l.isValueType && r.isValueType) { if (cast) - genConversion(l, r, source) + genConversion(l, r, expr) else js.BooleanLiteral(l == r) } else if (l.isValueType) { @@ -2314,15 +2319,15 @@ abstract class GenJSCode extends plugins.PluginComponent } else { js.BooleanLiteral(false) } - js.Block(source, result) // eval and discard source + js.Block(expr, result) // eval and discard source } else if (r.isValueType) { assert(!cast, s"Unexpected asInstanceOf from ref type to value type") - genIsInstanceOf(source, boxedClass(to.typeSymbol).tpe) + genIsInstanceOf(expr, boxedClass(to.typeSymbol).tpe) } else { if (cast) - genAsInstanceOf(source, to) + genAsInstanceOf(expr, to) else - genIsInstanceOf(source, to) + genIsInstanceOf(expr, to) } } @@ -2955,9 +2960,11 @@ abstract class GenJSCode extends plugins.PluginComponent translateMatch(expr) // Sometimes the pattern matcher casts its final result - case Apply(TypeApply(Select(expr: LabelDef, nme.asInstanceOf_Ob), _), _) + case Apply(TypeApply(Select(expr: LabelDef, nme.asInstanceOf_Ob), + List(targ)), Nil) if isCaseLabelDef(expr) => - translateMatch(expr) + genIsAsInstanceOf(translateMatch(expr), expr.tpe, targ.tpe, + cast = true) // Peculiar shape generated by `return x match {...}` - #2928 case Return(retExpr: LabelDef) if isCaseLabelDef(retExpr) => diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index fc4119819e..a0fcc7ea45 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -651,11 +651,7 @@ private[optimizer] abstract class OptimizerCore( case JSObjectConstr(fields) => JSObjectConstr(fields map { case (name, value) => - /* #2773 - The ascription `: PropertyName` side-steps the issue by - * pushing down an appropriate expected type. - * TODO We need to minimize and fix the root cause. - */ - val newName: PropertyName = name match { + val newName = name match { case _:StringLiteral | _:Ident => name case ComputedName(nameExpr, logicalName) => From 9fec009dc5ed901d1a1e0906d7e5d3ec02cfc599 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 20 May 2017 17:37:55 +0200 Subject: [PATCH 0262/2665] Fix #2948: Remove js.use(x).as[T] --- .../main/scala/scala/scalajs/js/Using.scala | 19 - .../main/scala/scala/scalajs/js/package.scala | 103 --- .../scala/scalajs/macroimpls/Compat210.scala | 53 -- .../macroimpls/JSMemberSelection.scala | 26 - .../scala/scalajs/macroimpls/JSMembers.scala | 97 --- .../scalajs/macroimpls/UseAsMacros.scala | 355 ---------- project/Build.scala | 2 - .../scalajs/testsuite/library/UseAsTest.scala | 670 ------------------ 8 files changed, 1325 deletions(-) delete mode 100644 library/src/main/scala/scala/scalajs/js/Using.scala delete mode 100644 library/src/main/scala/scala/scalajs/macroimpls/Compat210.scala delete mode 100644 library/src/main/scala/scala/scalajs/macroimpls/JSMemberSelection.scala delete mode 100644 library/src/main/scala/scala/scalajs/macroimpls/JSMembers.scala delete mode 100644 library/src/main/scala/scala/scalajs/macroimpls/UseAsMacros.scala delete mode 100644 test-suite/js/src/test/scala/org/scalajs/testsuite/library/UseAsTest.scala diff --git a/library/src/main/scala/scala/scalajs/js/Using.scala b/library/src/main/scala/scala/scalajs/js/Using.scala deleted file mode 100644 index cc787ce067..0000000000 --- a/library/src/main/scala/scala/scalajs/js/Using.scala +++ /dev/null @@ -1,19 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package scala.scalajs.js - -import scala.language.experimental.macros - -import scala.scalajs.macroimpls.UseAsMacros - -/** Helper for syntactic sugar of [[js.use]]. Only use in `js.use(x).as[T]` */ -final class Using[A] private[js] (val x: A) extends AnyVal { - def as[B <: Any]: B = macro UseAsMacros.as_impl[A, B] -} diff --git a/library/src/main/scala/scala/scalajs/js/package.scala b/library/src/main/scala/scala/scalajs/js/package.scala index 5ad71af18a..a3a5f47192 100644 --- a/library/src/main/scala/scala/scalajs/js/package.scala +++ b/library/src/main/scala/scala/scalajs/js/package.scala @@ -130,107 +130,4 @@ package object js { "because you tried to run Scala.js binaries on the JVM. Make sure you " + "are using the JVM version of the libraries.") - /** Allows to cast a value to a facade trait in a type-safe way. - * - * Use as follows: - * {{{ - * js.use(x).as[MyFacade] - * }}} - * - * Note that the method calls are only syntactic sugar. There is no overhead - * at runtime for such an operation. Using `use(x).as[T]` is strictly - * equivalent to `x.asInstanceOf[T]` if the compile time check does not fail. - * - * This method supports both Scala classes with exports and facade types - * which are structurally equivalent. - * - * == Examples == - * Given the following facade type: - * {{{ - * trait MyFacade extends js.Object { - * def foo(x: Int): String = js.native - * val bar: Int = js.native - * } - * }}} - * - * We show a couple of examples: - * {{{ - * class MyClass1 { - * @JSExport - * def foo(x: Int): String = x.toString - * - * @JSExport - * val bar: Int = 1 - * } - * - * val x1 = new MyClass1 - * js.use(x1).as[MyFacade] // OK - * }}} - * - * Note that JS conventions apply: The `val bar` can be implemented with a - * `def`. - * - * {{{ - * class MyClass2 { - * @JSExport - * def foo(x: Int): String = x.toString - * - * @JSExport - * def bar: Int = 1 // def instead of val - * } - * - * val x2 = new MyClass2 - * js.use(x2).as[MyFacade] // OK - * }}} - * - * Missing methods or methods with wrong types will cause a compile-time - * failure. - * - * {{{ - * class MyClass3 { - * @JSExport - * def foo(x: String): String = x.toString // wrong type signature - * - * // bar is missing - * } - * - * val x3 = new MyClass3 - * js.use(x2).as[MyFacade] // Fails: bar is missing and foo has wrong type - * }}} - * - * Methods must be exported, otherwise they are not taken into consideration. - * - * {{{ - * class MyClass4 { - * def foo(x: Int): String = x.toString - * - * @JSExport - * def bar: Int = 1 // def instead of val - * } - * - * val x4 = new MyClass4 - * js.use(x4).as[MyFacade] // Fails, foo is missing - * }}} - * - * Other facade types can also be used - * - * {{{ - * trait MyOtherFacade extends js.Object { - * def foo(x: Any): String = js.native - * val bar: Int = js.native - * def otherMethod(): Unit = js.native - * } - * - * val x5: MyOtherFacade = // ... - * js.use(x5).as[MyFacade] // OK - * }}} - * - * == Restrictions == - * - Facade types may only be traits and not have any class ancestors - * - Polymorphic methods are currently not supported - * - Facade types defining an apply method cannot used (this is a JavaScript - * restriction). - */ - def use[A](x: A): Using[A] = new Using[A](x) - } diff --git a/library/src/main/scala/scala/scalajs/macroimpls/Compat210.scala b/library/src/main/scala/scala/scalajs/macroimpls/Compat210.scala deleted file mode 100644 index 2d2e52457b..0000000000 --- a/library/src/main/scala/scala/scalajs/macroimpls/Compat210.scala +++ /dev/null @@ -1,53 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package scala.scalajs.macroimpls - -@deprecated("Not actually deprecated, makes warnings go away", "") -private[macroimpls] object Compat210 { - object blackbox { // scalastyle:ignore - type Context = scala.reflect.macros.Context - } -} - -import Compat210._ - -@deprecated("Not actually deprecated, makes warnings go away", "") -private[macroimpls] trait Compat210Component { - // Import macros only here, otherwise we collide with the above - import scala.reflect.macros._ - import blackbox.Context - - val c: Context - - import c.universe._ - - implicit final class ContextCompat(self: c.type) { - def typecheck(tree: Tree): Tree = c.typeCheck(tree) - } - - implicit final class TypeCompat(self: Type) { - def dealias: Type = self.normalize - def decls: MemberScope = self.declarations - } - - implicit final class SymbolCompat(self: Symbol) { - def isConstructor: Boolean = self.isMethod && self.asMethod.isConstructor - def info: Type = self.typeSignature - } - - implicit final class AnnotationCompat(self: Annotation) { - def tree: Tree = { - // Taken from AnnotationInfos.scala (in 2.11.x) - // Assume that we only have scalaArgs - val ctorSelection = Select(New(TypeTree(self.tpe)), nme.CONSTRUCTOR) - c.typecheck(Apply(ctorSelection, self.scalaArgs)) - } - } -} diff --git a/library/src/main/scala/scala/scalajs/macroimpls/JSMemberSelection.scala b/library/src/main/scala/scala/scalajs/macroimpls/JSMemberSelection.scala deleted file mode 100644 index 1243021bc9..0000000000 --- a/library/src/main/scala/scala/scalajs/macroimpls/JSMemberSelection.scala +++ /dev/null @@ -1,26 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package scala.scalajs.macroimpls - -/** Represents the way a member of a JS object is selected */ -private[macroimpls] sealed abstract class JSMemberSelection - -/** A member with statically known name */ -private[macroimpls] final case class JSNamedMember(name: String) - extends JSMemberSelection - -/** Calling the object */ -private[macroimpls] case object JSMemberCall extends JSMemberSelection - -/** Accessing via brackets (array-like access) */ -private[macroimpls] case object JSMemberBracketAccess extends JSMemberSelection - -/** Accessing and calling a member via brackets (with dynamic name) */ -private[macroimpls] case object JSMemberBracketCall extends JSMemberSelection diff --git a/library/src/main/scala/scala/scalajs/macroimpls/JSMembers.scala b/library/src/main/scala/scala/scalajs/macroimpls/JSMembers.scala deleted file mode 100644 index 61094160f1..0000000000 --- a/library/src/main/scala/scala/scalajs/macroimpls/JSMembers.scala +++ /dev/null @@ -1,97 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package scala.scalajs.macroimpls - -import Compat210._ - -/** JSMember is an ADT more or less equivalent to Scala's MethodType - * that allows to distinguish setters and getters from methods. - * - * It also allows to check method conformance based on Scala.js' JavaScript - * calling conventions. - * - * Currently does not support polymorphic method types. - * - * @author Tobias Schlatter - */ -private[macroimpls] trait JSMembers { - // Import macros only here, otherwise we collide with Compat210._ - import scala.reflect.macros._ - import blackbox.Context - - val c: Context - - import c.universe._ - - sealed trait JSMember { - /** Whether this JSMember conforms to that JSMember */ - def conformsTo(that: JSMember): Boolean - - /** Create a display string of this member with a given name */ - def displayStr(name: String): String - } - - case class JSMethodParam(info: Type, isDefault: Boolean) { - def conformsTo(that: JSMethodParam): Boolean = - (!that.isDefault || this.isDefault) && that.info <:< this.info - - override def toString(): String = - if (isDefault) s"$info = ???" - else info.toString - } - - case class JSMethod(params: List[JSMethodParam], - resultType: Type) extends JSMember { - - def conformsTo(that: JSMember): Boolean = that match { - case JSMethod(thatParams, thatResultType) => - val (used, unused) = params.splitAt(thatParams.size) - - params.size >= thatParams.size && - resultType <:< thatResultType && - unused.forall(_.isDefault) && - (used zip thatParams).forall { case (x, y) => x.conformsTo(y) } - - case _ => - false - } - - def displayStr(name: String): String = - s"method $name(${params.mkString(", ")}): $resultType" - } - - case class JSGetter(tpe: Type) extends JSMember { - def conformsTo(that: JSMember): Boolean = that match { - case JSGetter(thatTpe) => tpe <:< thatTpe - case _ => false - } - - def displayStr(name: String): String = s"getter $name: $tpe" - } - - case class JSSetter(tpe: Type) extends JSMember { - def conformsTo(that: JSMember): Boolean = that match { - case JSSetter(thatTpe) => thatTpe <:< tpe - case _ => false - } - - def displayStr(name: String): String = s"setter $name: $tpe" - } - - /** Place holder for unsupported members. - * - * In source type position, these members can be ignored. - * In target type position, these members will trigger errors. - */ - case class UnsupportedMember(sym: Symbol, tpe: Type) extends JSMember { - def conformsTo(that: JSMember): Boolean = false - def displayStr(name: String): String = s"unsupported $name ($sym)" - } -} diff --git a/library/src/main/scala/scala/scalajs/macroimpls/UseAsMacros.scala b/library/src/main/scala/scala/scalajs/macroimpls/UseAsMacros.scala deleted file mode 100644 index 495e8c5089..0000000000 --- a/library/src/main/scala/scala/scalajs/macroimpls/UseAsMacros.scala +++ /dev/null @@ -1,355 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package scala.scalajs.macroimpls - -import scala.annotation.tailrec -import scala.scalajs.js - -import Compat210._ - -/** Macros for `js.use(x).as[T]`. - * - * This implements a structural typechecker conforming to the JavaScript calling - * convention in Scala.js' export and facade system. - * - * @author Tobias Schlatter - */ -@deprecated("Not actually deprecated, makes warnings go away", "") -private[scalajs] object UseAsMacros { - // Import macros only here, otherwise we collide with Compat210._ - import scala.reflect.macros._ - import blackbox.Context - - def as_impl[A: c.WeakTypeTag, B <: js.Any: c.WeakTypeTag]( - c: Context { type PrefixType = js.Using[_] }): c.Expr[B] = { - (new Macros[c.type](c)).as[A, B] - } - - private class Macros[C <: Context { type PrefixType = js.Using[_] }](val c: C) - extends JSMembers with Compat210Component { - - import c.universe._ - - private val JSNameAnnotation = typeOf[js.annotation.JSName].typeSymbol - private val JSBracketAccessAnnotation = typeOf[js.annotation.JSBracketAccess].typeSymbol - private val JSBracketCallAnnotation = typeOf[js.annotation.JSBracketCall].typeSymbol - private val JSExportAnnotation = typeOf[js.annotation.JSExport].typeSymbol - private val JSExportAllAnnotation = typeOf[js.annotation.JSExportAll].typeSymbol - - /** Base classes that are allowed in a target type. - * These are also the classes whose methods do not need to be provided. - */ - private val JSObjectAncestors = typeOf[js.Object].baseClasses.toSet - - type JSMemberSet = Map[JSMemberSelection, List[JSMember]] - - def as[A: WeakTypeTag, B <: js.Any: WeakTypeTag]: Expr[B] = { - val trgTpe = verifyTargetType(weakTypeOf[B]) - val srcTpe = weakTypeOf[A] - - val srcSym = srcTpe.typeSymbol - - // Nothing and Null have everything - if (srcSym != definitions.NothingClass && - srcSym != definitions.NullClass) { - check(srcTpe, trgTpe) - } - - reify { c.prefix.splice.x.asInstanceOf[B] } - } - - /** Perform the actual structural typechecking. - * - * Checks if [[srcTpe]] conforms to [[trgTpe]]. Reports errors otherwise. - */ - private def check(srcTpe: Type, trgTpe: Type): Unit = { - val requiredMembers = rawJSMembers(trgTpe) - val isRawJSType = srcTpe <:< typeOf[js.Any] - - val definedMembers = - if (isRawJSType) rawJSMembers(srcTpe) - else exportedMembers(srcTpe) - - for { - (jsMemberSelection, jsMembers) <- requiredMembers - jsMember <- jsMembers - } { - // Fail for required unsupported members - jsMember match { - case UnsupportedMember(sym, tpe) => - val msg = tpe match { - case _: PolyType => - "Polymorphic methods are currently " + - s"not supported. Offending method: ${sym.fullName}" - - case _: ExistentialType => - "Methods with existential types are " + - s"not supported. Offending method: ${sym.fullName}. This is " + - "likely caused by an abstract type in the method signature" - - case _ => - sys.error("Unknown type in unsupported member. " + - "Report this as a bug.\n" + - s"Offending method: ${sym.fullName}\n" + - s"Offending type: ${showRaw(tpe)}") - } - - c.error(c.enclosingPosition, msg) - - case _ => - } - - val hasConformingMember = { - val overloads = definedMembers.getOrElse(jsMemberSelection, Nil) - overloads.exists(_.conformsTo(jsMember)) - } - - if (!hasConformingMember) { - // Error: A member is missing. Construct an informative error message - - def noSuchMember(memberName: String) = { - val membershipStr = if (isRawJSType) "have" else "export" - val memberStr = jsMember.displayStr(memberName) - s"$srcTpe does not $membershipStr a $memberStr." - } - - val errMsg = jsMemberSelection match { - case JSNamedMember(name) => - noSuchMember(name) - - case JSMemberCall if !isRawJSType => - s"$trgTpe defines an apply method. This cannot be implemented " + - "by any Scala exported type, since it would need to chain " + - "Function's prototype." - - case JSMemberBracketAccess if !isRawJSType => - s"$trgTpe defines a @JSMemberBracketAccess method. Existence " + - "of such a method cannot be statically checked for any " + - "Scala exported type." - - case JSMemberBracketCall if !isRawJSType => - s"$trgTpe defines a @JSMemberBracketCall method. Existence of " + - "such a method cannot be statically checked for any Scala " + - "exported type." - - case JSMemberCall => - noSuchMember("") + " (type is not callable)" - - case JSMemberBracketAccess => - noSuchMember("") + " (type doesn't support " + - "member selection via []). Add @JSBracketAccess to use a " + - "method for member selection." - - case JSMemberBracketCall => - noSuchMember("") + " (type doesn't support " + - "dynamically calling methods). Add @JSBracketCall to use a " + - "method for dynamic calls." - } - - c.error(c.enclosingPosition, errMsg) - } - } - } - - /** Members that a facade type defines */ - private def rawJSMembers(tpe: Type): JSMemberSet = { - - def isAPIMember(member: Symbol) = { - !JSObjectAncestors(member.owner) && - !member.isConstructor && - member.isMethod && - !member.asTerm.isParamWithDefault - } - - val tups = for { - member <- tpe.members - if isAPIMember(member) - } yield { - val memberMethod = member.asMethod - (jsMemberSelection(memberMethod), jsMemberFor(tpe, memberMethod)) - } - - // Group by member selection - for { - (selection, members) <- tups.groupBy(_._1) - } yield { - (selection, members.map(_._2).toList) - } - } - - /** Returns the way a member of a raw JS type is selected in JS */ - private def jsMemberSelection(sym: MethodSymbol): JSMemberSelection = { - val annots = memberAnnotations(sym) - - def hasAnnot(annot: Symbol) = annots.exists(annotIs(_, annot)) - - if (hasAnnot(JSBracketAccessAnnotation)) { - JSMemberBracketAccess - } else if (hasAnnot(JSBracketCallAnnotation)) { - JSMemberBracketCall - } else { - val optAnnot = annots.find(annotIs(_, JSNameAnnotation)) - val optName = optAnnot.flatMap(annotStringArg) - - optName.fold { - val name = defaultName(sym) - if (name == "apply") JSMemberCall - else JSNamedMember(name) - } { name => JSNamedMember(name) } - } - } - - /** Returns all exported members of a type */ - private def exportedMembers(tpe: Type): JSMemberSet = { - val exports = tpe.baseClasses.flatMap(exportedDecls(tpe, _)) - - // Group exports by name - for { - (name, elems) <- exports.groupBy(_._1) - } yield { - (JSNamedMember(name), elems.map(_._2)) - } - } - - /** All exported declarations of a class. - * (both @JSExportAll and @JSExport) - */ - private def exportedDecls(origTpe: Type, sym: Symbol) = { - require(sym.isClass) - - val exportAll = sym.annotations.exists(annotIs(_, JSExportAllAnnotation)) - - for { - decl <- sym.info.decls if decl.isMethod && !decl.isConstructor - name <- exportNames(decl.asMethod, exportAll) - } yield { - (name, jsMemberFor(origTpe, decl.asMethod)) - } - } - - /** Get the JS member for a method in [[origTpe]] */ - private def jsMemberFor(origTpe: Type, sym: MethodSymbol): JSMember = { - sym.info.asSeenFrom(origTpe, sym.owner) match { - case MethodType(List(param), resultType) - if resultType.typeSymbol == definitions.UnitClass && - sym.name.decodedName.toString.endsWith("_=") => - JSSetter(param.info) - - case NullaryMethodType(returnType) => - JSGetter(returnType) - - case info: MethodType => - @tailrec - def flatParams(tpe: Type, acc: List[JSMethodParam]): JSMethod = { - tpe match { - case MethodType(params, returnTpe) => - val ps = params map { p => - JSMethodParam(p.info, p.asTerm.isParamWithDefault) - } - flatParams(returnTpe, ps reverse_::: acc) - case tpe => - JSMethod(acc.reverse, tpe) - } - } - - flatParams(info, Nil) - - case tpe => - UnsupportedMember(sym, tpe) - } - } - - /** Names a method is exported to */ - private def exportNames(sym: MethodSymbol, exportAll: Boolean) = { - lazy val default = defaultName(sym) - - val explicitNames = for { - annot <- memberAnnotations(sym) - if annotIs(annot, JSExportAnnotation) - } yield { - annotStringArg(annot).getOrElse(default) - } - - if (exportAll && sym.isPublic) default :: explicitNames - else explicitNames - } - - /** Default JavaScript name of a method */ - private def defaultName(sym: MethodSymbol): String = - sym.name.decodedName.toString.stripSuffix("_=") - - /** Verifies that the given type is a class type or a refined type, - * has no class ancestors lower than js.Object and does only - * refine type members. - * @returns dealiased tpe - */ - private def verifyTargetType(tpe: Type): Type = { - tpe.dealias match { - case tpe @ TypeRef(_, sym0, _) if sym0.isClass => - val sym = sym0.asClass - - if (!sym.isTrait) - c.abort(c.enclosingPosition, "Only traits can be used with as") - - def allowedParent(sym: Symbol) = - sym.asClass.isTrait || JSObjectAncestors(sym) - - for (base <- sym.baseClasses if !allowedParent(base)) { - c.abort(c.enclosingPosition, s"Supertype ${base.fullName} of $sym " + - "is a class. Cannot be used with as.") - } - - tpe - - case tpe @ RefinedType(parents, decls) => - parents.foreach(verifyTargetType) - - for (decl <- decls if !decl.isType) { - c.abort(c.enclosingPosition, s"Refinement ${decl.name} " + - "is not a type. Only types may be refined with as.") - } - - tpe - - case tpe => - c.abort(c.enclosingPosition, "Only class types can be used with as") - } - } - - /** Annotations of a member symbol. - * Looks on accessed field if this is an accessor - */ - private def memberAnnotations(sym: MethodSymbol): List[Annotation] = { - val trgSym = - if (sym.isAccessor && sym.accessed != NoSymbol) sym.accessed - else sym - - // Force typeSignature to calculate annotations - trgSym.typeSignature - - trgSym.annotations - } - - /** Retrieve first argument to the annotation as literal string */ - private def annotStringArg(annot: Annotation): Option[String] = { - val args = annot.tree.children.tail - args match { - case List(Literal(Constant(s: String))) => Some(s) - case _ => None - } - } - - /** Checks if [[annot]] is of class [[clsSym]] */ - private def annotIs(annot: Annotation, clsSym: Symbol) = - annot.tree.tpe.typeSymbol == clsSym - - } - -} diff --git a/project/Build.scala b/project/Build.scala index 91c8b7d062..98e790043d 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1016,8 +1016,6 @@ object Build { exportJars := !isGeneratingEclipse, previousArtifactSetting, mimaBinaryIssueFilters ++= BinaryIncompatibilities.Library, - libraryDependencies += - "org.scala-lang" % "scala-reflect" % scalaVersion.value % "provided", scalaJSExternalCompileSettings, inConfig(Compile)(Seq( diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UseAsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UseAsTest.scala deleted file mode 100644 index d213c8b1d3..0000000000 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UseAsTest.scala +++ /dev/null @@ -1,670 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ -package org.scalajs.testsuite.library - -import scala.scalajs.js -import scala.scalajs.js.annotation._ - -import org.scalajs.testsuite.Typechecking._ - -import org.junit.Assert._ -import org.junit.Test - -class UseAsScalaTypesTest { - import UseAsTest._ - - // js.use(x).as[T] - Scala Types - success cases - - @Test def should_support_basic_typechecking(): Unit = { - class A { - @JSExport - def m(a: Int, b: String): js.Object = ??? - } - - js.use(new A).as[JSBasic] - } - - @Test def should_support_covariance_in_return_types(): Unit = { - class A { - @JSExport - def m(a: Int, b: String): js.Array[Int] = ??? - } - - js.use(new A).as[JSBasic] - } - - @Test def should_support_contravariance_in_argument(): Unit = { - class A { - @JSExport - def m(a: Int, b: Any): js.Object = ??? - } - - js.use(new A).as[JSBasic] - } - - @Test def should_support_explicit_names_in_JSExports(): Unit = { - class A { - @JSExport("m") - def f(a: Int, b: String): js.Object = ??? - } - - js.use(new A).as[JSBasic] - } - - @Test def should_support_JSName(): Unit = { - class A { - @JSExport - def m(a: Int, b: String): js.Object = ??? - } - - class B { - @JSExport("m") - def bar(a: Int, b: String): js.Object = ??? - } - - js.use(new A).as[JSBasicJSName] - js.use(new B).as[JSBasicJSName] - } - - @Test def should_support_JSExportAll(): Unit = { - @JSExportAll - class A { - def m(a: Int, b: String): js.Object = ??? - } - - class B extends A - - js.use(new A).as[JSBasic] - js.use(new B).as[JSBasic] - } - - @Test def should_support_inherited_exports(): Unit = { - abstract class A { - @JSExport - def m(a: Int, b: String): js.Object - } - - class B extends A { - def m(a: Int, b: String): js.Object = ??? - } - - js.use(new B).as[JSBasic] - } - - @Test def should_support_JSExportAll_on_superclass(): Unit = { - @JSExportAll - abstract class A { - def m(a: Int, b: String): js.Object - } - - class B extends A { - def m(a: Int, b: String): js.Object = ??? - } - - js.use(new B).as[JSBasic] - } - - @Test def should_work_with_JSExportAll_with_an_apply_method(): Unit = { - @JSExportAll - class A { - @JSExport("apply") - @JSExport("bar") - def apply(x: Int): Int = x * 2 - } - - val a = js.use(new A).as[JSNamedApply] - - assertEquals(4, a(2)) - assertEquals(4, a.bar(2)) - } - - @Test def should_resolve_generics_in_JSRaw_types(): Unit = { - class A { - @JSExport - def arr: js.Array[Int] = ??? - } - - js.use(new A).as[JSGeneric[Int]] - js.use(new A).as[JSGenericInt] - } - - @Test def should_resolve_type_members_in_JSRaw_types(): Unit = { - class A { - @JSExport - def foo(x: Int): Int = ??? - } - - js.use(new A).as[JSTypeMember { type R = Int }] - } - - @Test def should_resolve_exports_with_class_level_type_parameter(): Unit = { - class A[T] { - @JSExport - def arr: js.Array[T] = ??? - } - - class B extends A[Int] - - js.use(new A[Int]).as[JSGeneric[Int]] - js.use(new B).as[JSGeneric[Int]] - } - - @Test def should_resolve_exports_with_type_member(): Unit = { - class A { - type T - - @JSExport - def arr: js.Array[T] = ??? - } - - class B extends A { - type T = Int - } - - js.use(new B).as[JSGeneric[Int]] - } - - @Test def should_resolve_overloading(): Unit = { - @JSExportAll - class A { - def m(a: Int, b: String): js.Object = ??? - def m(b: String): Int = ??? - - @JSExport("m") - def strangeName(a: Int): js.Object = ??? - } - - js.use(new A).as[JSOverload] - } - - @Test def should_support_vals_getters(): Unit = { - @JSExportAll - class A { - val a: Int = 1 - def b: String = ??? - // Test covariance as well - def c: js.Array[Int] = ??? - } - - js.use(new A).as[JSGetters] - } - - @Test def should_support_setters(): Unit = { - class A { - @JSExport("a") - def fooA_=(x: Int): Unit = ??? - - @JSExport - def b_=(x: String): Unit = ??? - - @JSExport("c_=") - def barC_=(x: js.Object): Unit = ??? - } - - js.use(new A).as[JSSetters] - } - - @Test def should_support_vars(): Unit = { - class A { - @JSExport - def a: Int = ??? - @JSExport - def a_=(x: Int): Unit = ??? - - @JSExport("b") - var fooB: String = _ - - @JSExport - var c: js.Object = _ - } - - js.use(new A).as[JSVars] - } - - @Test def should_support_abstract_members_class(): Unit = { - abstract class AbstractFieldsClass { - @JSExport - def a: Int - @JSExport - def a_=(x: Int): Unit - - @JSExport("b") - var fooB: String - - @JSExport - var c: js.Object - } - - js.use(null: AbstractFieldsClass).as[JSVars] - } - - @Test def should_support_abstract_members_trait(): Unit = { - trait AbstractFieldsTrait { - @JSExport - def a: Int - @JSExport - def a_=(x: Int): Unit - - @JSExport("b") - var fooB: String - - @JSExport - var c: js.Object - } - - js.use(null: AbstractFieldsTrait).as[JSVars] - } - - @Test def should_support_basic_default_arguments(): Unit = { - @JSExportAll - class A { - def sum4(a: Int, b: Int = 1, c: Int = 2, d: Int = 3): Int = a + b + c + d - def sum2(a: Int, b: Int = 1): Int = a + b - } - - js.use(new A).as[JSDefaultArgs] - } - - @Test def should_allow_additional_default_arguments_at_the_end_of_the_params(): Unit = { - class A { - @JSExport - def m(a: Int, b: String, c: Int = ???, d: String = ???): js.Object = ??? - } - - js.use(new A).as[JSBasic] - } - - @Test def should_support_repeated_parameter_lists(): Unit = { - @JSExportAll - class A { - def rep(a: Int, b: String*): Unit = ??? - def rep(a: Int*): Unit = ??? - } - - js.use(new A).as[JSRepeated] - } - - @Test def should_flatten_multi_parameter_lists_in_raw_JS_type(): Unit = { - @JSExportAll - class A { - def multi(a: Int, b: String): Int = ??? - } - - js.use(new A).as[JSMulti] - } - - @Test def should_flatten_multi_parameter_lists_in_exported_method(): Unit = { - @JSExportAll - class B { - def m(a: Int)(b: String): js.Object = ??? - } - - js.use(new B).as[JSBasic] - } - - @Test def should_support_anonymous_types(): Unit = { - js.use(new { @JSExport def m(a: Int, b: String): js.Object = ??? }).as[JSBasic] - } - - @Test def should_allow_Nothing(): Unit = { - if (false) { - js.use(???).as[JSBasic] - } - } - - @Test def should_allow_Null(): Unit = { - js.use(null).as[JSBasic] - } - - // js.use(x).as[T] - Raw JS Types - success cases - - @Test def should_support_basic_typechecking_raw_js(): Unit = { - js.use(null: JSBasic).as[JSBasicJSName] - js.use(null: JSBasicJSName).as[JSBasic] - } - - @Test def should_support_generics(): Unit = { - js.use(null: JSGeneric[Int]).as[JSGenericInt] - js.use(null: JSGenericInt).as[JSGeneric[Int]] - } - - @Test def should_support_JS_calls(): Unit = { - js.use(null: js.Function0[String]).as[JSApplyString] - } - - @Test def should_support_atJSBracketAccess(): Unit = { - js.use(new js.Array[Int](0)).as[JSBracketAccessInt] - } - - @Test def should_support_atJSBracketCall(): Unit = { - js.use(null: JSBracketCallInt1).as[JSBracketCallInt2] - } - - // js.use(x).as[T] - general failure cases - - @Test def fails_with_polymorphic_methods(): Unit = { - typeErrorWithMsg( - "js.use(new Object).as[JSPolyMethod]", - "Polymorphic methods are currently not supported. Offending " + - "method: org.scalajs.testsuite.library.UseAsTest.JSPolyMethod.poly") - } - - @Test def fails_with_non_type_refinements(): Unit = { - typeErrorWithMsg( - "js.use(???).as[JSBasic { def foo: Int }]", - "Refinement foo is not a type. Only types may be refined with as.") - } - - @Test def fails_with_non_trait(): Unit = { - typeErrorWithMsg( - "js.use(???).as[js.Date]", - "Only traits can be used with as") - } - - @Test def fails_with_class_parents(): Unit = { - typeErrorWithMsg( - "js.use(???).as[JSNonClassParent]", - "Supertype scala.scalajs.js.Date of trait JSNonClassParent is a " + - "class. Cannot be used with as.") - } - - @Test def fails_gracefully_with_existential_types_issue_1841(): Unit = { - typeErrorWithMsg( - "js.use(null: JSTypeMember).as[JSTypeMember]", - "Methods with existential types are not supported. Offending " + - "method: org.scalajs.testsuite.library.UseAsTest.JSTypeMember.foo. " + - "This is likely caused by an abstract type in the method signature") - } - - // js.use(x).as[T] - Scala Types - failure cases - - @Test def fails_with_apply_in_a_raw_JS_type(): Unit = { - typeErrorWithMsg( - "js.use(new Object).as[JSWithApply]", - "org.scalajs.testsuite.library.UseAsTest.JSWithApply defines an apply " + - "method. This cannot be implemented by any Scala exported type, " + - "since it would need to chain Function's prototype.") - } - - @Test def fails_with_atJSBracketAccess_in_a_raw_JS_type(): Unit = { - typeErrorWithMsg( - "js.use(new Object).as[JSWithBracketAccess]", - "org.scalajs.testsuite.library.UseAsTest.JSWithBracketAccess " + - "defines a @JSMemberBracketAccess method. Existence of such a " + - "method cannot be statically checked for any Scala exported type.") - } - - @Test def fails_with_atJSBracketCall_in_a_raw_JS_type(): Unit = { - typeErrorWithMsg( - "js.use(new Object).as[JSWithBracketCall]", - "org.scalajs.testsuite.library.UseAsTest.JSWithBracketCall defines " + - "a @JSMemberBracketCall method. Existence of such a method cannot " + - "be statically checked for any Scala exported type.") - } - - @Test def fails_with_a_missing_method_failure(): Unit = { - class A { - @JSExport - def e(a: Int, b: String): js.Object = ??? - } - - typeErrorWithMsg( - "js.use(new A).as[JSBasic]", - "A does not export a method m(Int, String): scala.scalajs.js.Object.") - } - - @Test def fails_with_a_missing_overload_failure(): Unit = { - class A { - @JSExport - def m(a: Int, b: String): js.Object = ??? - } - - typeErrorWithMsg( - "js.use(new A).as[JSOverload]", - "A does not export a method m(Int): scala.scalajs.js.Object.") - } - - @Test def fails_with_wrong_argument_types(): Unit = { - class A { - @JSExport - def m(a: String, b: Int): js.Object = ??? - } - - typeErrorWithMsg( - "js.use(new A).as[JSBasic]", - "A does not export a method m(Int, String): scala.scalajs.js.Object.") - } - - @Test def fails_with_wrong_return_types(): Unit = { - class A { - @JSExport - def m(a: Int, b: String): Any = ??? - } - - typeErrorWithMsg( - "js.use(new A).as[JSBasic]", - "A does not export a method m(Int, String): scala.scalajs.js.Object.") - } - - @Test def fails_with_a_missing_default_argument(): Unit = { - @JSExportAll - class A { - def sum4(a: Int, b: Int = 1, c: Int = 2, d: Int = 3): Int = a + b + c + d - def sum2(a: Int, b: Int): Int = a + b // should have default - } - - typeErrorWithMsg( - "js.use(new A).as[JSDefaultArgs]", - "A does not export a method sum2(Int, Int = ???): Int.") - } - - @Test def fails_with_a_mismatching_repeated_argument(): Unit = { - @JSExportAll - class A { - def rep(a: Int, b: String): Unit = ??? // should be repeated - def rep(a: Int*): Unit = ??? - } - - typeErrorWithMsg( - "js.use(new A).as[JSRepeated]", - "A does not export a method rep(Int, String*): Unit.") - - class B { - @JSExport - def m(a: Int, b: String*): js.Object = ??? // should not be repeated - } - - typeErrorWithMsg( - "js.use(new B).as[JSBasic]", - "B does not export a method m(Int, String): scala.scalajs.js.Object.") - } - - // js.use(x).as[T] - Raw JS Types - failure cases - - @Test def fails_with_a_missing_apply(): Unit = { - typeErrorWithMsg( - "js.use(new js.Object).as[JSWithApply]", - "scala.scalajs.js.Object does not have a method " + - "(String): Int. (type is not callable)") - } - - @Test def fails_with_a_missing_atJSBracketAccess(): Unit = { - typeErrorWithMsg( - "js.use(new js.Object).as[JSWithBracketAccess]", - "scala.scalajs.js.Object does not have a method " + - "(String): Int. (type doesn't support member " + - "selection via []). Add @JSBracketAccess to use a method for " + - "member selection.") - } - - @Test def fails_with_a_missing_atJSBracketCall(): Unit = { - typeErrorWithMsg( - "js.use(new js.Object).as[JSWithBracketCall]", - "scala.scalajs.js.Object does not have a method " + - "(String, String): Int. (type doesn't support " + - "dynamically calling methods). Add @JSBracketCall to use a method " + - "for dynamic calls.") - } - - @Test def fails_with_a_missing_method(): Unit = { - typeErrorWithMsg( - "js.use(new js.Object).as[JSBasic]", - "scala.scalajs.js.Object does not have a method " + - "m(Int, String): scala.scalajs.js.Object.") - } - - @Test def fails_with_a_missing_overload(): Unit = { - typeErrorWithMsg( - "js.use(null: JSBasic).as[JSOverload]", - "org.scalajs.testsuite.library.UseAsTest.JSBasic does not have a " + - "method m(Int): scala.scalajs.js.Object.") - } - - @Test def fails_with_wrongly_typed_generic(): Unit = { - typeErrorWithMsg( - "js.use(null: JSGeneric[Int]).as[JSGeneric[String]]", - "org.scalajs.testsuite.library.UseAsTest.JSGeneric[Int] does not " + - "have a getter arr: scala.scalajs.js.Array[String].") - } - -} - -object UseAsTest { - - @js.native - trait JSBasic extends js.Object { - def m(a: Int, b: String): js.Object = js.native - } - - @js.native - trait JSBasicJSName extends js.Object { - @JSName("m") - def foo(a: Int, b: String): js.Object = js.native - } - - @js.native - trait JSNamedApply extends js.Object { - @JSName("apply") - def apply(x: Int): Int = js.native - - def bar(x: Int): Int = js.native - } - - @js.native - trait JSGeneric[T] extends js.Object { - def arr: js.Array[T] = js.native - } - - @js.native - trait JSGenericInt extends JSGeneric[Int] - - @js.native - trait JSTypeMember extends js.Object { - type R - def foo(x: R): Int = js.native - } - - @js.native - trait JSOverload extends JSBasic { - def m(b: String): Int = js.native - def m(a: Int): js.Object = js.native - } - - @js.native - trait JSGetters extends js.Object { - def a: Int = js.native - val b: String = js.native - def c: js.Object = js.native - } - - @js.native - trait JSSetters extends js.Object { - def a_=(x: Int): Unit = js.native - - @JSName("b") - def fooJS_=(x: String): Unit = js.native - - @JSName("c_=") - def barJS_=(x: js.Array[Int]): Unit = js.native - } - - @js.native - trait JSVars extends js.Object { - var a: Int = js.native - def b: String = js.native - def b_=(x: String): Unit = js.native - - @JSName("c") - var fooJS: js.Object = js.native - } - - @js.native - trait JSDefaultArgs extends js.Object { - def sum4(a: Int, b: Int = ???, c: Int = ???, d: Int = ???): Int = js.native - def sum2(a: Int, b: Int = ???): Int = js.native - } - - @js.native - trait JSRepeated extends js.Object { - def rep(a: Int, b: String*): Unit = js.native - def rep(a: Int*): Unit = js.native - } - - @js.native - trait JSMulti extends js.Object { - def multi(a: Int)(b: String): Int = js.native - } - - @js.native - trait JSPolyMethod extends js.Object { - def poly[T](a: T): js.Array[T] = js.native - } - - @js.native - trait JSWithApply extends js.Object { - def apply(a: String): Int = js.native - } - - @js.native - trait JSWithBracketAccess extends js.Object { - @JSBracketAccess - def foo(a: String): Int = js.native - } - - @js.native - trait JSWithBracketCall extends js.Object { - @JSBracketCall - def foo(name: String, b: String): Int = js.native - } - - @js.native - trait JSNonClassParent extends js.Date - - @js.native - trait JSApplyString extends js.Object { - def apply(): String = js.native - } - - @js.native - trait JSBracketAccessInt extends js.Object { - @JSBracketAccess - def apply(x: Int): Int = js.native - } - - @js.native - trait JSBracketCallInt1 extends js.Object { - @JSBracketCall - def foo(method: String): Int = js.native - } - - @js.native - trait JSBracketCallInt2 extends js.Object { - @JSBracketCall - def bar(method: String): Int = js.native - } -} From f4896a50bc5c3f8eb70d8c54d6874a969140f88d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 20 May 2017 11:54:20 +0200 Subject: [PATCH 0263/2665] Fix #2797: Add an optional global fallback to `@JSImport`. If the codebase refers to an `@JSImport` entity, such as @js.native @JSImport("foo.js", "Bar") class Bar extends js.Object the codebase must be linked with `CommonJSModule` (or, in the future, other `ModuleKind`s supporting modules). Linking without module support causes a linking error. This causes facades for JS libraries supporting both module-style and script-style to be faced with an early choice: * either support linking with modules and use `@JSImport`, or * support linking without module support, and use `@JSGlobal` with whatever global names the JS library uses. It is however impossible to write a facade library that supports both use cases for their end users. This commit addresses this issue by adding an optional "global fallback" to `@JSImport`. We can now define a facade as follows: @js.native @JSImport("foo.js", "Bar", globalFallback = "Foo.Bar") class Bar extends js.Object That facade will successfully link both with and without module support. With module support, it links as if declared like in the first snippet. Without module support, it links as if declared as @js.native @JSGlobal("Foo.Bar") class Bar extends js.Object Using this global fallback, a facade library can cater both for users who want to take advantages of modules, and users who want to stick to the script style. --- Implementation-wise, this is quite easy to implement. We simply add a new `JSNativeLoadSpec.ImportWithGlobalFallback`. It wraps both a `JSNativeLoadSpec.Import` and `Global`. That JS native load spec goes through the entire pipeline and reaches the emitter as is. The emitter decides which one to use depending on the `moduleKind`. --- .../scalajs/core/compiler/PrepJSInterop.scala | 34 +- .../core/compiler/test/JSInteropTest.scala | 296 +++++++++++++++--- .../scala/org/scalajs/core/ir/Printers.scala | 5 + .../org/scalajs/core/ir/Serializers.scala | 36 ++- .../main/scala/org/scalajs/core/ir/Tags.scala | 1 + .../scala/org/scalajs/core/ir/Trees.scala | 10 + .../org/scalajs/core/ir/PrintersTest.scala | 11 + .../scalajs/js/annotation/JSImport.scala | 51 ++- project/BinaryIncompatibilities.scala | 3 + project/Build.scala | 7 +- .../scalajs/testsuite/utils/Platform.scala | 3 + .../testsuite/jsinterop/ModulesTest.scala | 5 +- .../testsuite/javalib/lang/SystemJSTest.scala | 5 + .../ModulesWithGlobalFallbackTest.scala | 207 ++++++++++++ .../core/tools/test/js/TestRunner.scala | 1 + .../linker/backend/emitter/Emitter.scala | 34 +- .../tools/linker/backend/emitter/JSGen.scala | 13 +- 17 files changed, 643 insertions(+), 79 deletions(-) create mode 100644 test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 6c3dab04d3..51e17a7843 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -708,6 +708,8 @@ abstract class PrepJSInterop extends plugins.PluginComponent private def checkAndComputeJSNativeLoadSpecOf(pos: Position, sym: Symbol): JSNativeLoadSpec = { + import JSNativeLoadSpec._ + if (enclosingOwner is OwnerKind.JSNativeMod) { for { annot <- sym.annotations @@ -732,10 +734,15 @@ abstract class PrepJSInterop extends plugins.PluginComponent val ownerLoadSpec = jsInterop.jsNativeLoadSpecOf(sym.owner) ownerLoadSpec match { - case JSNativeLoadSpec.Global(path) => - JSNativeLoadSpec.Global(path :+ jsName) - case JSNativeLoadSpec.Import(module, path) => - JSNativeLoadSpec.Import(module, path :+ jsName) + case Global(path) => + Global(path :+ jsName) + case Import(module, path) => + Import(module, path :+ jsName) + case ImportWithGlobalFallback( + Import(module, modulePath), Global(globalPath)) => + ImportWithGlobalFallback( + Import(module, modulePath :+ jsName), + Global(globalPath :+ jsName)) } } else { def parsePath(pathName: String): List[String] = @@ -782,7 +789,13 @@ abstract class PrepJSInterop extends plugins.PluginComponent "" // do not care because it does not compile anyway } val path = annot.stringArg(1).fold[List[String]](Nil)(parsePath) - JSNativeLoadSpec.Import(module, path) + val importSpec = Import(module, path) + annot.stringArg(2).fold[JSNativeLoadSpec] { + importSpec + } { globalPathName => + val globalSpec = Global(parsePath(globalPathName)) + ImportWithGlobalFallback(importSpec, globalSpec) + } case Some(annot) if annot.symbol == JSNameAnnotation => if (!scalaJSOpts.suppressMissingJSGlobalDeprecations) { @@ -1280,8 +1293,8 @@ abstract class PrepJSInterop extends plugins.PluginComponent for { annot <- sym.getAnnotation(JSImportAnnotation) } { - assert(annot.args.size == 2, - s"@JSImport annotation $annot does not have exactly 2 arguments") + assert(annot.args.size == 2 || annot.args.size == 3, + s"@JSImport annotation $annot does not have exactly 2 or 3 arguments") val firstArgIsValid = annot.stringArg(0).isDefined if (!firstArgIsValid) { @@ -1298,6 +1311,13 @@ abstract class PrepJSInterop extends plugins.PluginComponent "The second argument to @JSImport must be literal string or the " + "JSImport.Namespace object.") } + + val thirdArgIsValid = annot.args.size < 3 || annot.stringArg(2).isDefined + if (!thirdArgIsValid) { + reporter.error(annot.args(2).pos, + "The third argument to @JSImport, when present, must be a " + + "literal string.") + } } } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index 9cebad4c14..929ace7062 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -20,6 +20,7 @@ class JSInteropTest extends DirectTest with TestHelpers { "JSGlobal" -> "@JSGlobal", "JSGlobal" -> "@JSGlobal(\"foo\")", "JSImport" -> "@JSImport(\"foo\", \"bar\")", + "JSImport" -> "@JSImport(\"foo\", \"bar\", globalFallback = \"baz\")", "JSGlobalScope" -> "@JSGlobalScope" ) @@ -260,6 +261,35 @@ class JSInteropTest extends DirectTest with TestHelpers { """ } + for { + obj <- Seq("class", "trait", "object") + } yield { + s""" + @ScalaJSDefined + @JSImport("foo", JSImport.Namespace, globalFallback = "Foo") + $obj A extends js.Object + """ hasErrors + s""" + |newSource1.scala:6: error: Non JS-native classes, traits and objects may not have an @JSImport annotation. + | @JSImport("foo", JSImport.Namespace, globalFallback = "Foo") + | ^ + """ + } + + for { + obj <- Seq("class", "trait", "object") + } yield { + s""" + @JSImport("foo", JSImport.Namespace, globalFallback = "Foo") + $obj A + """ hasErrors + s""" + |newSource1.scala:5: error: Non JS-native classes, traits and objects may not have an @JSImport annotation. + | @JSImport("foo", JSImport.Namespace, globalFallback = "Foo") + | ^ + """ + } + } @Test @@ -330,6 +360,17 @@ class JSInteropTest extends DirectTest with TestHelpers { | ^ """ + s""" + @js.native + @JSImport("foo", JSImport.Namespace, globalFallback = "Foo") + trait A extends js.Object + """ hasErrors + s""" + |newSource1.scala:6: error: Traits may not have an @JSImport annotation. + | @JSImport("foo", JSImport.Namespace, globalFallback = "Foo") + | ^ + """ + } @Test def noTwoJSNativeLoadSpecAnnots: Unit = { @@ -877,6 +918,17 @@ class JSInteropTest extends DirectTest with TestHelpers { | ^ """ + """ + @js.native + @JSImport("foo", JSImport.Namespace, globalFallback = "Foo") + object Bar extends js.GlobalScope + """ hasErrors + """ + |newSource1.scala:6: error: Native JS classes and objects can only have one annotation among JSName, JSGlobal, JSImport and JSGlobalScope (extending js.GlobalScope is treated as having @JSGlobalScope). + | @JSImport("foo", JSImport.Namespace, globalFallback = "Foo") + | ^ + """ + } @Test @@ -1258,6 +1310,18 @@ class JSInteropTest extends DirectTest with TestHelpers { } """.hasNoWarns + """ + object A { + @JSImport("InnerB", JSImport.Namespace, globalFallback = "Foo") + @js.native + class B extends js.Object + + @JSImport("InnerC", JSImport.Namespace, globalFallback = "Foo") + @js.native + object C extends js.Object + } + """.hasNoWarns + """ object A { @js.native @@ -1570,23 +1634,26 @@ class JSInteropTest extends DirectTest with TestHelpers { @Test def noJSImportOnMembersOfClassesAndTraits: Unit = { - for (outer <- Seq("class", "trait")) { + for { + outer <- Seq("class", "trait") + fallbackStr <- Seq("", ", globalFallback = \"Foo\"") + } { s""" @js.native ${if (outer == "trait") "" else "@JSGlobal"} $outer Foo extends js.Object { - @JSImport("bar1", JSImport.Namespace) + @JSImport("bar1", JSImport.Namespace$fallbackStr) val bar1: Int = js.native - @JSImport("bar2", JSImport.Namespace) + @JSImport("bar2", JSImport.Namespace$fallbackStr) var bar2: Int = js.native - @JSImport("bar3", JSImport.Namespace) + @JSImport("bar3", JSImport.Namespace$fallbackStr) def bar3: Int = js.native @js.native - @JSImport("Inner", JSImport.Namespace) + @JSImport("Inner", JSImport.Namespace$fallbackStr) class Inner extends js.Object @js.native - @JSImport("Inner", JSImport.Namespace) + @JSImport("Inner", JSImport.Namespace$fallbackStr) object Inner extends js.Object } """ hasErrors @@ -1614,42 +1681,46 @@ class JSInteropTest extends DirectTest with TestHelpers { @Test def noJSImportOnMembersOfObjects: Unit = { - """ - @js.native @JSGlobal - object Foo extends js.Object { - @JSImport("bar1", JSImport.Namespace) - val bar1: Int = js.native - @JSImport("bar2", JSImport.Namespace) - var bar2: Int = js.native - @JSImport("bar3", JSImport.Namespace) - def bar3: Int = js.native + for { + fallbackStr <- Seq("", ", globalFallback = \"Foo\"") + } { + s""" + @js.native @JSGlobal + object Foo extends js.Object { + @JSImport("bar1", JSImport.Namespace$fallbackStr) + val bar1: Int = js.native + @JSImport("bar2", JSImport.Namespace$fallbackStr) + var bar2: Int = js.native + @JSImport("bar3", JSImport.Namespace$fallbackStr) + def bar3: Int = js.native - @js.native - @JSImport("Inner", JSImport.Namespace) - class Inner extends js.Object + @js.native + @JSImport("Inner", JSImport.Namespace$fallbackStr) + class Inner extends js.Object - @js.native - @JSImport("Inner", JSImport.Namespace) - object Inner extends js.Object + @js.native + @JSImport("Inner", JSImport.Namespace$fallbackStr) + object Inner extends js.Object + } + """ hasErrors + s""" + |newSource1.scala:8: error: Methods and fields cannot be annotated with @JSImport. + | val bar1: Int = js.native + | ^ + |newSource1.scala:10: error: Methods and fields cannot be annotated with @JSImport. + | var bar2: Int = js.native + | ^ + |newSource1.scala:12: error: Methods and fields cannot be annotated with @JSImport. + | def bar3: Int = js.native + | ^ + |newSource1.scala:15: error: Classes and objects nested in a JS native object cannot have an @JSImport annotation. + | @JSImport("Inner", JSImport.Namespace$fallbackStr) + | ^ + |newSource1.scala:19: error: Classes and objects nested in a JS native object cannot have an @JSImport annotation. + | @JSImport("Inner", JSImport.Namespace$fallbackStr) + | ^ + """ } - """ hasErrors - """ - |newSource1.scala:8: error: Methods and fields cannot be annotated with @JSImport. - | val bar1: Int = js.native - | ^ - |newSource1.scala:10: error: Methods and fields cannot be annotated with @JSImport. - | var bar2: Int = js.native - | ^ - |newSource1.scala:12: error: Methods and fields cannot be annotated with @JSImport. - | def bar3: Int = js.native - | ^ - |newSource1.scala:15: error: Classes and objects nested in a JS native object cannot have an @JSImport annotation. - | @JSImport("Inner", JSImport.Namespace) - | ^ - |newSource1.scala:19: error: Classes and objects nested in a JS native object cannot have an @JSImport annotation. - | @JSImport("Inner", JSImport.Namespace) - | ^ - """ } @@ -1683,6 +1754,8 @@ class JSInteropTest extends DirectTest with TestHelpers { @Test def noNonLiteralJSImport: Unit = { + // Without global fallback + """ object A { val a = "Hello" @@ -1743,6 +1816,151 @@ class JSInteropTest extends DirectTest with TestHelpers { | ^ """ + // With constant (valid) global fallback + + """ + object A { + val a = "Hello" + } + + @JSImport(A.a, JSImport.Namespace, globalFallback = "GlobB1") + @js.native + object B1 extends js.Object + + @JSImport(A.a, "B2", globalFallback = "GlobB2") + @js.native + object B2 extends js.Object + + @JSImport("B3", A.a, globalFallback = "GlobB3") + @js.native + object B3 extends js.Object + + @JSImport(A.a, JSImport.Namespace, globalFallback = "GlobC1") + @js.native + object C1 extends js.Object + + @JSImport(A.a, "C2", globalFallback = "GlobC2") + @js.native + object C2 extends js.Object + + @JSImport("C3", A.a, globalFallback = "GlobC3") + @js.native + object C3 extends js.Object + + @JSImport(A.a, A.a, globalFallback = "GlobD") + @js.native + object D extends js.Object + """ hasErrors + """ + |newSource1.scala:9: error: The first argument to @JSImport must be a literal string. + | @JSImport(A.a, JSImport.Namespace, globalFallback = "GlobB1") + | ^ + |newSource1.scala:13: error: The first argument to @JSImport must be a literal string. + | @JSImport(A.a, "B2", globalFallback = "GlobB2") + | ^ + |newSource1.scala:17: error: The second argument to @JSImport must be literal string or the JSImport.Namespace object. + | @JSImport("B3", A.a, globalFallback = "GlobB3") + | ^ + |newSource1.scala:21: error: The first argument to @JSImport must be a literal string. + | @JSImport(A.a, JSImport.Namespace, globalFallback = "GlobC1") + | ^ + |newSource1.scala:25: error: The first argument to @JSImport must be a literal string. + | @JSImport(A.a, "C2", globalFallback = "GlobC2") + | ^ + |newSource1.scala:29: error: The second argument to @JSImport must be literal string or the JSImport.Namespace object. + | @JSImport("C3", A.a, globalFallback = "GlobC3") + | ^ + |newSource1.scala:33: error: The first argument to @JSImport must be a literal string. + | @JSImport(A.a, A.a, globalFallback = "GlobD") + | ^ + |newSource1.scala:33: error: The second argument to @JSImport must be literal string or the JSImport.Namespace object. + | @JSImport(A.a, A.a, globalFallback = "GlobD") + | ^ + """ + + // With variable (invalid) global fallback + + """ + object A { + val a = "Hello" + } + + @JSImport(A.a, JSImport.Namespace, globalFallback = A.a) + @js.native + object B1 extends js.Object + + @JSImport(A.a, "B2", globalFallback = A.a) + @js.native + object B2 extends js.Object + + @JSImport("B3", A.a, globalFallback = A.a) + @js.native + object B3 extends js.Object + + @JSImport(A.a, JSImport.Namespace, globalFallback = A.a) + @js.native + object C1 extends js.Object + + @JSImport(A.a, "C2", globalFallback = A.a) + @js.native + object C2 extends js.Object + + @JSImport("C3", A.a, globalFallback = A.a) + @js.native + object C3 extends js.Object + + @JSImport(A.a, A.a, globalFallback = A.a) + @js.native + object D extends js.Object + """ hasErrors + """ + |newSource1.scala:9: error: The first argument to @JSImport must be a literal string. + | @JSImport(A.a, JSImport.Namespace, globalFallback = A.a) + | ^ + |newSource1.scala:9: error: The third argument to @JSImport, when present, must be a literal string. + | @JSImport(A.a, JSImport.Namespace, globalFallback = A.a) + | ^ + |newSource1.scala:13: error: The first argument to @JSImport must be a literal string. + | @JSImport(A.a, "B2", globalFallback = A.a) + | ^ + |newSource1.scala:13: error: The third argument to @JSImport, when present, must be a literal string. + | @JSImport(A.a, "B2", globalFallback = A.a) + | ^ + |newSource1.scala:17: error: The second argument to @JSImport must be literal string or the JSImport.Namespace object. + | @JSImport("B3", A.a, globalFallback = A.a) + | ^ + |newSource1.scala:17: error: The third argument to @JSImport, when present, must be a literal string. + | @JSImport("B3", A.a, globalFallback = A.a) + | ^ + |newSource1.scala:21: error: The first argument to @JSImport must be a literal string. + | @JSImport(A.a, JSImport.Namespace, globalFallback = A.a) + | ^ + |newSource1.scala:21: error: The third argument to @JSImport, when present, must be a literal string. + | @JSImport(A.a, JSImport.Namespace, globalFallback = A.a) + | ^ + |newSource1.scala:25: error: The first argument to @JSImport must be a literal string. + | @JSImport(A.a, "C2", globalFallback = A.a) + | ^ + |newSource1.scala:25: error: The third argument to @JSImport, when present, must be a literal string. + | @JSImport(A.a, "C2", globalFallback = A.a) + | ^ + |newSource1.scala:29: error: The second argument to @JSImport must be literal string or the JSImport.Namespace object. + | @JSImport("C3", A.a, globalFallback = A.a) + | ^ + |newSource1.scala:29: error: The third argument to @JSImport, when present, must be a literal string. + | @JSImport("C3", A.a, globalFallback = A.a) + | ^ + |newSource1.scala:33: error: The first argument to @JSImport must be a literal string. + | @JSImport(A.a, A.a, globalFallback = A.a) + | ^ + |newSource1.scala:33: error: The second argument to @JSImport must be literal string or the JSImport.Namespace object. + | @JSImport(A.a, A.a, globalFallback = A.a) + | ^ + |newSource1.scala:33: error: The third argument to @JSImport, when present, must be a literal string. + | @JSImport(A.a, A.a, globalFallback = A.a) + | ^ + """ + } @Test diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index 1c9ce7fe76..f62c7ff042 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -966,6 +966,11 @@ object Printers { print(module) print(')') printPath(path) + + case JSNativeLoadSpec.ImportWithGlobalFallback(importSpec, globalSpec) => + print(importSpec) + print(" fallback ") + print(globalSpec) } } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index 52b37fd691..43e4f7ebbf 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -609,18 +609,31 @@ object Serializers { def writeJSNativeLoadSpec(jsNativeLoadSpec: Option[JSNativeLoadSpec]): Unit = { import buffer._ + def writeGlobalSpec(spec: JSNativeLoadSpec.Global): Unit = { + writeStrings(spec.path) + } + + def writeImportSpec(spec: JSNativeLoadSpec.Import): Unit = { + writeString(spec.module) + writeStrings(spec.path) + } + jsNativeLoadSpec.fold { writeByte(TagJSNativeLoadSpecNone) } { spec => spec match { - case JSNativeLoadSpec.Global(path) => + case spec: JSNativeLoadSpec.Global => writeByte(TagJSNativeLoadSpecGlobal) - writeStrings(path) + writeGlobalSpec(spec) - case JSNativeLoadSpec.Import(module, path) => + case spec: JSNativeLoadSpec.Import => writeByte(TagJSNativeLoadSpecImport) - writeString(module) - writeStrings(path) + writeImportSpec(spec) + + case JSNativeLoadSpec.ImportWithGlobalFallback(importSpec, globalSpec) => + writeByte(TagJSNativeLoadSpecImportWithGlobalFallback) + writeImportSpec(importSpec) + writeGlobalSpec(globalSpec) } } } @@ -1045,13 +1058,22 @@ object Serializers { JSNativeLoadSpec.Global(jsFullName.split("\\.").toList) } } else { + def readGlobalSpec(): JSNativeLoadSpec.Global = + JSNativeLoadSpec.Global(readStrings()) + + def readImportSpec(): JSNativeLoadSpec.Import = + JSNativeLoadSpec.Import(readString(), readStrings()) + (input.readByte(): @switch) match { case TagJSNativeLoadSpecNone => None case TagJSNativeLoadSpecGlobal => - Some(JSNativeLoadSpec.Global(readStrings())) + Some(readGlobalSpec()) case TagJSNativeLoadSpecImport => - Some(JSNativeLoadSpec.Import(readString(), readStrings())) + Some(readImportSpec()) + case TagJSNativeLoadSpecImportWithGlobalFallback => + Some(JSNativeLoadSpec.ImportWithGlobalFallback( + readImportSpec(), readGlobalSpec())) } } } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala index f627595124..68096c6aa2 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala @@ -137,5 +137,6 @@ private[ir] object Tags { final val TagJSNativeLoadSpecNone = 0 final val TagJSNativeLoadSpecGlobal = TagJSNativeLoadSpecNone + 1 final val TagJSNativeLoadSpecImport = TagJSNativeLoadSpecGlobal + 1 + final val TagJSNativeLoadSpecImportWithGlobalFallback = TagJSNativeLoadSpecImport + 1 } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 771e82bd00..e8ccf8165c 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -946,6 +946,16 @@ object Trees { final case class Import(module: String, path: List[String]) extends JSNativeLoadSpec + /** Like [[Import]], but with a [[Global]] fallback when linking without + * modules. + * + * When linking with a module kind that supports modules, the `importSpec` + * is used. When modules are not supported, use the fallback `globalSpec`. + */ + final case class ImportWithGlobalFallback(importSpec: Import, + globalSpec: Global) + extends JSNativeLoadSpec + } /** A hash of a tree (usually a MethodDef). Contains two SHA-1 hashes */ diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala index f17099f07c..8834c35eac 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala @@ -895,6 +895,17 @@ class PrintersTest { ClassDef("LTest", ClassKind.NativeJSClass, Some(ObjectClass), Nil, Some(JSNativeLoadSpec.Import("foo", List("Bar"))), Nil)( NoOptHints)) + + assertPrintEquals( + """ + |native js class LTest extends O loadfrom import(foo).Bar fallback .Foo { + |} + """, + ClassDef("LTest", ClassKind.NativeJSClass, Some(ObjectClass), Nil, + Some(JSNativeLoadSpec.ImportWithGlobalFallback( + JSNativeLoadSpec.Import("foo", List("Bar")), + JSNativeLoadSpec.Global(List("Foo")))), Nil)( + NoOptHints)) } @Test def printClassDefOptimizerHints(): Unit = { diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSImport.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSImport.scala index 42d46a2c2d..d75b99b691 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSImport.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSImport.scala @@ -11,21 +11,28 @@ package scala.scalajs.js.annotation /** Marks the annotated class or object as imported from another JS module. * - * Intuitively, this corresponds to the following ECMAScript import - * directive: - * {{{ - * import { as AnnotatedClassOrObject } from - * }}} - * - * To import the default export of a module, use `JSImport.Default` as `name`. + * Intuitively, this corresponds to ECMAScript import directives. See the + * documentation of the various constructors. * * `@JSImport` is not compatible with the `jsDependencies` mechanism offered * by the Scala.js sbt plugin. You are responsible for resolving and/or * bundling the JavaScript modules that you are importing using other * mechanisms. */ -class JSImport(module: String, name: String) - extends scala.annotation.StaticAnnotation { +class JSImport private () extends scala.annotation.StaticAnnotation { + + /** Named import of a member of the module. + * + * Intuitively, this corresponds to the following ECMAScript import + * directive: + * {{{ + * import { as AnnotatedClassOrObject } from + * }}} + * + * To import the default export of a module, use `JSImport.Default` as + * `name`. + */ + def this(module: String, name: String) = this() /** Namespace import (import the module itself). * @@ -36,8 +43,30 @@ class JSImport(module: String, name: String) * import * as AnnotatedObject from * }}} */ - def this(module: String, name: JSImport.Namespace.type) = - this(module, null: String) + def this(module: String, name: JSImport.Namespace.type) = this() + + /** Named import of a member of the module, with a fallback on a global + * variable. + * + * When linking with module support, this is equivalent to + * `@JSImport(module, name)`. + * + * When linking without module support, this is equivalent to + * `@JSGlobal(globalFallback)`. + */ + def this(module: String, name: String, globalFallback: String) = this() + + /** Namespace import (import the module itself), with a fallback on a global + * variable. + * + * When linking with module support, this is equivalent to + * `@JSImport(module, name)`. + * + * When linking without module support, this is equivalent to + * `@JSGlobal(globalFallback)`. + */ + def this(module: String, name: JSImport.Namespace.type, + globalFallback: String) = this() } object JSImport { diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index c77318b933..3c841e96d6 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -6,6 +6,9 @@ object BinaryIncompatibilities { ) val Tools = Seq( + // private[emitter], not an issue + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.JSGen.this") ) val JSEnvs = Seq( diff --git a/project/Build.scala b/project/Build.scala index e65373f0c7..9996384f2e 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1342,7 +1342,12 @@ object Build { case FullOptStage => "fullopt-stage" } - envTags ++ (semTags :+ stageTag) + val moduleKindTag = scalaJSModuleKind.value match { + case ModuleKind.NoModule => "modulekind-nomodule" + case ModuleKind.CommonJSModule => "modulekind-commonjs" + } + + envTags ++ (semTags :+ stageTag :+ moduleKindTag) }, javaOptions in Test ++= { def scalaJSProp(name: String): String = diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala index 7947fb6d1d..bead868114 100644 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala +++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala @@ -54,6 +54,9 @@ object Platform { def hasCompliantModule: Boolean = sysProp("compliant-moduleinit") def hasStrictFloats: Boolean = sysProp("strict-floats") + def isNoModule: Boolean = sysProp("modulekind-nomodule") + def isCommonJSModule: Boolean = sysProp("modulekind-commonjs") + private def sysProp(key: String): Boolean = System.getProperty("scalajs." + key, "false") == "true" } diff --git a/test-suite/js/src/test/require-modules/org/scalajs/testsuite/jsinterop/ModulesTest.scala b/test-suite/js/src/test/require-modules/org/scalajs/testsuite/jsinterop/ModulesTest.scala index bc3d64bfd3..fb94b0805f 100644 --- a/test-suite/js/src/test/require-modules/org/scalajs/testsuite/jsinterop/ModulesTest.scala +++ b/test-suite/js/src/test/require-modules/org/scalajs/testsuite/jsinterop/ModulesTest.scala @@ -17,6 +17,9 @@ import org.junit.Test * We are importing built-in Node.js modules, because we do not have any * infrastructure to load non-built-in modules. In the future, we should use * our own user-defined ES6 modules written in JavaScript. + * + * !!! This is mostly copy-pasted in `ModulesWithGlobalFallbackTest.scala` in + * `src/test/scala/`, with a version with global fallbacks. */ class ModulesTest { import ModulesTest._ @@ -107,7 +110,7 @@ object ModulesTest { */ @js.native @JSImport("buffer", "Buffer") - class Buffer private () extends js.typedarray.Uint8Array(0) { + class Buffer private[this] () extends js.typedarray.Uint8Array(0) { def this(size: Int) = this() def this(array: js.Array[Short]) = this() } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala index 15fe8dccfc..e53fff63c0 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala @@ -142,5 +142,10 @@ class SystemJSTest { assertEquals(isInFastOpt, Platform.isInFastOpt) assertEquals(isInFullOpt, Platform.isInFullOpt) + val isNoModule = get("scalajs.modulekind-nomodule") == "true" + val isCommonJSModule = get("scalajs.modulekind-commonjs") == "true" + assertEquals(isNoModule, Platform.isNoModule) + assertEquals(isCommonJSModule, Platform.isCommonJSModule) + assertTrue(isNoModule ^ isCommonJSModule) } } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala new file mode 100644 index 0000000000..a29c62479a --- /dev/null +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala @@ -0,0 +1,207 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.jsinterop + +import scala.scalajs.js +import scala.scalajs.js.annotation._ +import scala.scalajs.js.typedarray._ + +import java.nio.{ByteBuffer, CharBuffer} + +import org.junit.Assert._ +import org.junit.Assume._ +import org.junit.BeforeClass +import org.junit.Test + +import org.scalajs.testsuite.utils.Platform._ + +/* !!! This is mostly copy-pasted from `ModulesTest.scala` in + * `src/test/require-modules/`. This is the version with global fallbacks. + */ +class ModulesWithGlobalFallbackTest { + import ModulesWithGlobalFallbackTest._ + + @Test def testImportModuleItself(): Unit = { + val qs = QueryString + assertTrue(qs.isInstanceOf[js.Object]) + + val dict = js.Dictionary("foo" -> "bar", "baz" -> "qux") + + assertEquals("foo=bar&baz=qux", qs.stringify(dict)) + assertEquals("foo:bar;baz:qux", qs.stringify(dict, ";", ":")) + + /* Potentially, this could be "optimized" by importing `stringify` as a + * global symbol if we are emitting ES2015 modules. + */ + assertEquals("foo=bar&baz=qux", QueryString.stringify(dict)) + assertEquals("foo:bar;baz:qux", QueryString.stringify(dict, ";", ":")) + } + + @Test def testImportLegacyModuleItselfAsDefault(): Unit = { + val qs = QueryStringAsDefault + assertTrue(qs.isInstanceOf[js.Object]) + + val dict = js.Dictionary("foo" -> "bar", "baz" -> "qux") + + assertEquals("foo=bar&baz=qux", qs.stringify(dict)) + assertEquals("foo:bar;baz:qux", qs.stringify(dict, ";", ":")) + + /* Potentially, this could be "optimized" by importing `stringify` as a + * global symbol if we are emitting ES2015 modules. + */ + assertEquals("foo=bar&baz=qux", QueryStringAsDefault.stringify(dict)) + assertEquals("foo:bar;baz:qux", QueryStringAsDefault.stringify(dict, ";", ":")) + } + + @Test def testImportObjectInModule(): Unit = { + assertTrue((Buffer: Any).isInstanceOf[js.Object]) + assertFalse(Buffer.isBuffer(5)) + } + + @Test def testImportClassInModule(): Unit = { + val b = new Buffer(5) + for (i <- 0 until 5) + b(i) = (i * i).toShort + + for (i <- 0 until 5) + assertEquals(i * i, b(i).toInt) + } + + @Test def testImportIntegrated(): Unit = { + val b = new Buffer(js.Array[Short](0xe3, 0x81, 0x93, 0xe3, 0x82, 0x93, 0xe3, + 0x81, 0xab, 0xe3, 0x81, 0xa1, 0xe3, 0x81, 0xaf)) + val decoder = new StringDecoder() + assertTrue(Buffer.isBuffer(b)) + assertFalse(Buffer.isBuffer(decoder)) + assertEquals("こんにちは", decoder.write(b)) + assertEquals("", decoder.end()) + } + +} + +object ModulesWithGlobalFallbackTest { + @ScalaJSDefined + private object QueryStringFallbackImpl extends js.Object { + def stringify(obj: js.Dictionary[String], sep: String = "&", + eq: String = "="): String = { + var result = "" + for ((key, value) <- obj) { + if (result != "") + result += sep + result += key + eq + value + } + result + } + } + + @ScalaJSDefined + private class StringDecoderFallbackImpl(charsetName: String = "utf8") + extends js.Object { + import java.nio.charset._ + + private val charset = Charset.forName(charsetName) + private val decoder = charset.newDecoder() + + private def writeInternal(buffer: Uint8Array, + endOfInput: Boolean): String = { + val in = TypedArrayBuffer.wrap(buffer.buffer, buffer.byteOffset, + buffer.byteLength) + + // +2 so that a pending incomplete character has some space + val out = CharBuffer.allocate( + Math.ceil(decoder.maxCharsPerByte().toDouble * in.remaining()).toInt + 2) + + val result = decoder.decode(in, out, endOfInput) + if (!result.isUnderflow()) + result.throwException() + + if (endOfInput) { + val flushResult = decoder.flush(out) + if (!flushResult.isUnderflow()) + flushResult.throwException() + } + + out.flip() + out.toString() + } + + def write(buffer: Uint8Array): String = + writeInternal(buffer, endOfInput = false) + + def end(buffer: Uint8Array): String = + writeInternal(buffer, endOfInput = true) + + def end(): String = + writeInternal(new Uint8Array(0), endOfInput = true) + } + + @ScalaJSDefined + object BufferStaticFallbackImpl extends js.Object { + def isBuffer(x: Any): Boolean = x.isInstanceOf[Uint8Array] + } + + @BeforeClass + def beforeClass(): Unit = { + assumeTrue("Assuming that Typed Arrays are supported", + areTypedArraysSupported) + + if (isNoModule) { + js.Dynamic.global.ModulesWithGlobalFallbackTest_QueryString = + QueryStringFallbackImpl + js.Dynamic.global.ModulesWithGlobalFallbackTest_StringDecoder = + js.constructorOf[StringDecoderFallbackImpl] + js.Dynamic.global.ModulesWithGlobalFallbackTest_Buffer = + js.constructorOf[Uint8Array] + js.Dynamic.global.ModulesWithGlobalFallbackTest_BufferStatic = + BufferStaticFallbackImpl + } + } + + @js.native + @JSImport("querystring", JSImport.Namespace, + globalFallback = "ModulesWithGlobalFallbackTest_QueryString") + object QueryString extends js.Object { + def stringify(obj: js.Dictionary[String], sep: String = "&", + eq: String = "="): String = js.native + } + + @js.native + @JSImport("querystring", JSImport.Default, + globalFallback = "ModulesWithGlobalFallbackTest_QueryString") + object QueryStringAsDefault extends js.Object { + def stringify(obj: js.Dictionary[String], sep: String = "&", + eq: String = "="): String = js.native + } + + @js.native + @JSImport("string_decoder", "StringDecoder", + globalFallback = "ModulesWithGlobalFallbackTest_StringDecoder") + class StringDecoder(encoding: String = "utf8") extends js.Object { + def write(buffer: Buffer): String = js.native + def end(buffer: Buffer): String = js.native + def end(): String = js.native + } + + /* To stay compatible with Node.js 4.2.1, we describe and use deprecated + * APIs. + */ + @js.native + @JSImport("buffer", "Buffer", + globalFallback = "ModulesWithGlobalFallbackTest_Buffer") + class Buffer private[this] () extends js.typedarray.Uint8Array(0) { + def this(size: Int) = this() + def this(array: js.Array[Short]) = this() + } + + @js.native + @JSImport("buffer", "Buffer", + globalFallback = "ModulesWithGlobalFallbackTest_BufferStatic") + object Buffer extends js.Object { + def isBuffer(x: Any): Boolean = js.native + } +} diff --git a/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala b/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala index eac39b462d..0abb9e22ff 100644 --- a/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala +++ b/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala @@ -16,6 +16,7 @@ object TestRunner { System.setProperty("scalajs.nodejs", "true") System.setProperty("scalajs.typedarray", "true") System.setProperty("scalajs.fastopt-stage", "true") + System.setProperty("scalajs.modulekind-nomodule", "true") val eventHandler = new SimpleEventHandler val loggers = Array[Logger](new SimpleLogger) diff --git 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 index ac6c4286a5..93eb212dc3 100644 --- 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 @@ -47,7 +47,8 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, private val knowledgeGuardian = new KnowledgeGuardian - private val jsGen = new JSGen(semantics, outputMode, internalOptions) + private val jsGen = + new JSGen(semantics, outputMode, moduleKind, internalOptions) private val classEmitter = new ClassEmitter(jsGen) private val classCaches = mutable.Map.empty[List[String], ClassCache] @@ -162,27 +163,38 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, } if (importsFound) { - sys.error("There were module imports, but module support is " + - "disabled.\nTo enable module support, set scalaJSModuleKind := " + + sys.error( + "There were module imports without fallback to global " + + "variables, but module support is disabled.\n" + + "To enable module support, set scalaJSModuleKind := " + "ModuleKind.CommonJSModule.") } case ModuleKind.CommonJSModule => val encounteredModuleNames = mutable.Set.empty[String] + for (classDef <- orderedClasses) { + def addModuleRef(module: String): Unit = { + if (encounteredModuleNames.add(module)) { + implicit val pos = classDef.pos + val rhs = js.Apply(js.VarRef(js.Ident("require")), + List(js.StringLiteral(module))) + val lhs = jsGen.envModuleField(module) + val decl = jsGen.genLet(lhs.ident, mutable = false, rhs) + builder.addJSTree(decl) + } + } + classDef.jsNativeLoadSpec match { case None => case Some(JSNativeLoadSpec.Global(_)) => case Some(JSNativeLoadSpec.Import(module, _)) => - if (encounteredModuleNames.add(module)) { - implicit val pos = classDef.pos - val rhs = js.Apply(js.VarRef(js.Ident("require")), - List(js.StringLiteral(module))) - val lhs = jsGen.envModuleField(module) - val decl = jsGen.genLet(lhs.ident, mutable = false, rhs) - builder.addJSTree(decl) - } + addModuleRef(module) + + case Some(JSNativeLoadSpec.ImportWithGlobalFallback( + JSNativeLoadSpec.Import(module, _), _)) => + addModuleRef(module) } } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala index 8ae3e3487b..9b4f9fd0fe 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala @@ -17,7 +17,7 @@ import ir.Types._ import ir.{Trees => irt} import org.scalajs.core.tools.sem._ -import org.scalajs.core.tools.linker.backend.OutputMode +import org.scalajs.core.tools.linker.backend.{ModuleKind, OutputMode} import org.scalajs.core.tools.javascript.Trees._ /** Collection of tree generators that are used accross the board. @@ -26,7 +26,8 @@ import org.scalajs.core.tools.javascript.Trees._ * Also carries around config (semantics and outputMode). */ private[emitter] final class JSGen(val semantics: Semantics, - val outputMode: OutputMode, internalOptions: InternalOptions) { + val outputMode: OutputMode, val moduleKind: ModuleKind, + internalOptions: InternalOptions) { import JSGen._ implicit def transformIdent(ident: irt.Ident): Ident = @@ -190,6 +191,14 @@ private[emitter] final class JSGen(val semantics: Semantics, case _ => pathSelection(moduleValue, path) } + + case irt.JSNativeLoadSpec.ImportWithGlobalFallback(importSpec, globalSpec) => + moduleKind match { + case ModuleKind.NoModule => + genLoadJSFromSpec(globalSpec) + case ModuleKind.CommonJSModule => + genLoadJSFromSpec(importSpec) + } } } From 3e0bedff573f4c1de512cf13d1d157ce9fed0139 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 7 May 2017 21:37:10 +0200 Subject: [PATCH 0264/2665] Simplify JUnit output test spec DSL --- .../org/scalajs/junit/AssertEquals2Test.scala | 21 +- .../org/scalajs/junit/AssertEqualsTest.scala | 20 +- .../org/scalajs/junit/AssertFalse2Test.scala | 20 +- .../org/scalajs/junit/AssertFalseTest.scala | 20 +- .../org/scalajs/junit/AssertTrueTest.scala | 20 +- .../scala/org/scalajs/junit/AssumeTest.scala | 21 +- .../scalajs/junit/BeforeAndAfterTest.scala | 18 +- .../scalajs/junit/BeforeAssumeFailTest.scala | 17 +- .../org/scalajs/junit/ExceptionTest.scala | 21 +- .../scala/org/scalajs/junit/IgnoreTest.scala | 19 +- .../scalajs/junit/MethodNameDecodeTest.scala | 19 +- .../scala/org/scalajs/junit/Multi1Test.scala | 22 +- .../scala/org/scalajs/junit/Multi2Test.scala | 34 +-- .../scalajs/junit/MultiAssumeFail1Test.scala | 39 +-- .../scalajs/junit/MultiAssumeFail2Test.scala | 41 +-- .../junit/MultiBeforeAssumeFailTest.scala | 20 +- .../org/scalajs/junit/MultiIgnore1Test.scala | 36 +-- .../org/scalajs/junit/MultiIgnore2Test.scala | 35 +-- .../scalajs/junit/MultiIgnoreAllTest.scala | 31 +- .../scala/org/scalajs/junit/TestTest.scala | 25 -- .../junit/utils/FailureFrameworkArgs.scala | 19 -- .../org/scalajs/junit/utils/JUnitTest.scala | 278 +++++++++++------- .../junit/utils/SuccessFrameworkArgs.scala | 12 - 23 files changed, 285 insertions(+), 523 deletions(-) delete mode 100644 junit-test/shared/src/test/scala/org/scalajs/junit/TestTest.scala delete mode 100644 junit-test/shared/src/test/scala/org/scalajs/junit/utils/FailureFrameworkArgs.scala delete mode 100644 junit-test/shared/src/test/scala/org/scalajs/junit/utils/SuccessFrameworkArgs.scala diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertEquals2Test.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertEquals2Test.scala index 7f080b44c3..d398323889 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertEquals2Test.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertEquals2Test.scala @@ -10,22 +10,7 @@ class AssertEquals2Test { } } -class AssertEquals2TestAssertions extends JUnitTest with FailureFrameworkArgs { - - override val expectedFail: Int = 1 - override val expectedTotal: Int = 1 - - protected def expectedOutput(context: OutputContext): List[Output] = { - import context._ - List( - testRunStartedOutput, - testStartedOutput("test"), - testAssertionErrorMsgOutput("test", - "This is the message expected: but was:"), - failureEvent, - testFinishedOutput("test"), - testRunFinishedOutput, - done - ) - } +class AssertEquals2TestAssertions extends JUnitTest { + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = + builder.assertion("test", "This is the message expected: but was:") } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertEqualsTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertEqualsTest.scala index dee1249180..5683609d3c 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertEqualsTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertEqualsTest.scala @@ -11,21 +11,7 @@ class AssertEqualsTest { } } -class AssertEqualsTestAssertions extends JUnitTest with FailureFrameworkArgs { - - override val expectedFail: Int = 1 - override val expectedTotal: Int = 1 - - protected def expectedOutput(context: OutputContext): List[Output] = { - import context._ - List( - testRunStartedOutput, - testStartedOutput("test"), - testAssertionErrorMsgOutput("test", "expected: but was:"), - failureEvent, - testFinishedOutput("test"), - testRunFinishedOutput, - done - ) - } +class AssertEqualsTestAssertions extends JUnitTest { + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = + builder.assertion("test", "expected: but was:") } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertFalse2Test.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertFalse2Test.scala index 4c81250f32..1b0b80efda 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertFalse2Test.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertFalse2Test.scala @@ -11,21 +11,7 @@ class AssertFalse2Test { } } -class AssertFalse2TestAssertions extends JUnitTest with FailureFrameworkArgs { - - override val expectedFail: Int = 1 - override val expectedTotal: Int = 1 - - protected def expectedOutput(context: OutputContext): List[Output] = { - import context._ - List( - testRunStartedOutput, - testStartedOutput("test"), - testAssertionErrorMsgOutput("test", "This is the message"), - failureEvent, - testFinishedOutput("test"), - testRunFinishedOutput, - done - ) - } +class AssertFalse2TestAssertions extends JUnitTest { + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = + builder.assertion("test", "This is the message") } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertFalseTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertFalseTest.scala index 8f81c4b89d..41b7bf2b4b 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertFalseTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertFalseTest.scala @@ -11,21 +11,7 @@ class AssertFalseTest { } } -class AssertFalseTestAssertions extends JUnitTest with FailureFrameworkArgs { - - override val expectedFail: Int = 1 - override val expectedTotal: Int = 1 - - protected def expectedOutput(context: OutputContext): List[Output] = { - import context._ - List( - testRunStartedOutput, - testStartedOutput("test"), - testAssertionErrorMsgOutput("test", "null"), - failureEvent, - testFinishedOutput("test"), - testRunFinishedOutput, - done - ) - } +class AssertFalseTestAssertions extends JUnitTest { + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = + builder.assertion("test", "null") } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertTrueTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertTrueTest.scala index eb34555643..bd6ff14dc6 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertTrueTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertTrueTest.scala @@ -11,21 +11,7 @@ class AssertTrueTest { } } -class AssertTrueTestAssertions extends JUnitTest with FailureFrameworkArgs { - - override val expectedFail: Int = 1 - override val expectedTotal: Int = 1 - - protected def expectedOutput(context: OutputContext): List[Output] = { - import context._ - List( - testRunStartedOutput, - testStartedOutput("test"), - testAssertionErrorMsgOutput("test", "null"), - failureEvent, - testFinishedOutput("test"), - testRunFinishedOutput, - done - ) - } +class AssertTrueTestAssertions extends JUnitTest { + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = + builder.assertion("test", "null") } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/AssumeTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/AssumeTest.scala index df3beb4ca2..3df1a0290c 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/AssumeTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/AssumeTest.scala @@ -11,20 +11,11 @@ class AssumeTest { } } -class AssumeTestAssertions extends JUnitTest with SuccessFrameworkArgs { +class AssumeTestAssertions extends JUnitTest { + // Don't test -c, due to #2944. + override protected def frameworkArgss: List[List[String]] = + super.frameworkArgss.filterNot(_.contains("-c")) - override val expectedTotal: Int = 1 - - protected def expectedOutput(context: OutputContext): List[Output] = { - import context._ - List( - testRunStartedOutput, - testStartedOutput("assumeFail"), - testAssumptionViolatedOutput("assumeFail"), - skippedEvent, - testFinishedOutput("assumeFail"), - testRunFinishedOutput, - done - ) - } + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = + builder.assumptionViolated("assumeFail") } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/BeforeAndAfterTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/BeforeAndAfterTest.scala index cb769b9cbe..e5ff0e147f 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/BeforeAndAfterTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/BeforeAndAfterTest.scala @@ -14,19 +14,7 @@ class BeforeAndAfterTest { @Test def test(): Unit = () } -class BeforeAndAfterTestAssertions extends JUnitTest with SuccessFrameworkArgs { - - override val expectedTotal: Int = 1 - - protected def expectedOutput(context: OutputContext): List[Output] = { - import context._ - List( - testRunStartedOutput, - testStartedOutput("test"), - testFinishedOutput("test"), - successEvent, - testRunFinishedOutput, - done - ) - } +class BeforeAndAfterTestAssertions extends JUnitTest { + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = + builder.success("test") } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/BeforeAssumeFailTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/BeforeAssumeFailTest.scala index db4d1090a1..a6e3aba16a 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/BeforeAssumeFailTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/BeforeAssumeFailTest.scala @@ -15,18 +15,7 @@ class BeforeAssumeFailTest { @Test def test(): Unit = () } -class BeforeAssumeFailTestAssertions extends JUnitTest with SuccessFrameworkArgs { - - override val expectedIgnored: Int = 1 - - protected def expectedOutput(context: OutputContext): List[Output] = { - import context._ - List( - testRunStartedOutput, - testIgnoredClassOutput, - skippedEvent, - testRunFinishedOutput, - done - ) - } +class BeforeAssumeFailTestAssertions extends JUnitTest { + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = + builder.ignoredClass() } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionTest.scala index ba9e2d1968..6bcfc55ec5 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionTest.scala @@ -10,22 +10,9 @@ class ExceptionTest { } } -class ExceptionTestAssertions extends JUnitTest with FailureFrameworkArgs { - - override val expectedFail: Int = 1 - override val expectedTotal: Int = 1 - - protected def expectedOutput(context: OutputContext): List[Output] = { - import context._ - List( - testRunStartedOutput, - testStartedOutput("test"), - testExceptionMsgOutput("test", "Exception message", - "java.lang", "IndexOutOfBoundsException"), - failureEvent, - testFinishedOutput("test"), - testRunFinishedOutput, - done - ) +class ExceptionTestAssertions extends JUnitTest { + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = { + builder.exception("test", + "Exception message", "java.lang.IndexOutOfBoundsException") } } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/IgnoreTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/IgnoreTest.scala index 8b03770b03..5827ad4108 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/IgnoreTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/IgnoreTest.scala @@ -1,24 +1,13 @@ package org.scalajs.junit import org.junit._ -import org.scalajs.junit.utils.{JUnitTest, SuccessFrameworkArgs} +import org.scalajs.junit.utils.JUnitTest class IgnoreTest { @Ignore @Test def onlyTest(): Unit = () } -class IgnoreTestAssertions extends JUnitTest with SuccessFrameworkArgs { - - override val expectedIgnored: Int = 1 - - protected def expectedOutput(context: OutputContext): List[Output] = { - import context._ - List( - testRunStartedOutput, - testIgnoredOutput("onlyTest"), - skippedEvent, - testRunFinishedOutput, - done - ) - } +class IgnoreTestAssertions extends JUnitTest { + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = + builder.ignored("onlyTest") } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/MethodNameDecodeTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/MethodNameDecodeTest.scala index 3b1c7a9169..812b2e97e5 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/MethodNameDecodeTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/MethodNameDecodeTest.scala @@ -8,28 +8,17 @@ class MethodNameDecodeTest { } class MethodNameDecodeTestAssertions extends JUnitTest { - - protected def frameworkArgss: List[List[String]] = List( + override protected val frameworkArgss: List[List[String]] = List( List("-v"), List("-v", "-n"), List("-v", "-s"), List("-v", "-s", "-n") ) - override val expectedTotal: Int = 1 - - protected def expectedOutput(context: OutputContext): List[Output] = { - import context._ + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = { val methodName = - if (decodeScalaNames) "abcd ∆ƒ \uD83D\uDE00 * #&$" + if (builder.argInfo.decodeScalaNames) "abcd ∆ƒ \uD83D\uDE00 * #&$" else "abcd$u0020$u2206ƒ$u0020$uD83D$uDE00$u0020$times$u0020$hash$amp$" - List( - testRunStartedOutput, - testStartedOutput(methodName), - testFinishedOutput(methodName), - successEvent, - testRunFinishedOutput, - done - ) + builder.success(methodName) } } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/Multi1Test.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/Multi1Test.scala index e93b2fbaa5..0c9f2e2fb8 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/Multi1Test.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/Multi1Test.scala @@ -9,22 +9,10 @@ class Multi1Test { @Test def multiTest2(): Unit = () } -class Multi1TestAssertions extends JUnitTest with SuccessFrameworkArgs { - - override val expectedTotal: Int = 2 - - protected def expectedOutput(context: OutputContext): List[Output] = { - import context._ - List( - testRunStartedOutput, - testStartedOutput("multiTest1"), - testFinishedOutput("multiTest1"), - successEvent, - testStartedOutput("multiTest2"), - testFinishedOutput("multiTest2"), - successEvent, - testRunFinishedOutput, - done - ) +class Multi1TestAssertions extends JUnitTest { + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = { + builder + .success("multiTest1") + .success("multiTest2") } } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/Multi2Test.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/Multi2Test.scala index 45e55dd74b..e6c4b95ce8 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/Multi2Test.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/Multi2Test.scala @@ -12,31 +12,13 @@ class Multi2Test { @Test def multiTest5(): Unit = () } -class Multi2TestAssertions extends JUnitTest with SuccessFrameworkArgs { - - override val expectedTotal: Int = 5 - - protected def expectedOutput(context: OutputContext): List[Output] = { - import context._ - List( - testRunStartedOutput, - testStartedOutput("multiTest1"), - testFinishedOutput("multiTest1"), - successEvent, - testStartedOutput("multiTest2"), - testFinishedOutput("multiTest2"), - successEvent, - testStartedOutput("multiTest3"), - testFinishedOutput("multiTest3"), - successEvent, - testStartedOutput("multiTest4"), - testFinishedOutput("multiTest4"), - successEvent, - testStartedOutput("multiTest5"), - testFinishedOutput("multiTest5"), - successEvent, - testRunFinishedOutput, - done - ) +class Multi2TestAssertions extends JUnitTest { + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = { + builder + .success("multiTest1") + .success("multiTest2") + .success("multiTest3") + .success("multiTest4") + .success("multiTest5") } } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiAssumeFail1Test.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiAssumeFail1Test.scala index 2f2555ff9c..8196635982 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiAssumeFail1Test.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiAssumeFail1Test.scala @@ -3,7 +3,7 @@ package org.scalajs.junit import org.junit.Assume._ import org.junit.Test -import org.scalajs.junit.utils.{JUnitTest, SuccessFrameworkArgs} +import org.scalajs.junit.utils.JUnitTest class MultiAssumeFail1Test { @Test def multiTest1(): Unit = { @@ -16,32 +16,17 @@ class MultiAssumeFail1Test { @Test def multiTest5(): Unit = () } -class MultiAssumeFail1TestAssertions extends JUnitTest with SuccessFrameworkArgs { +class MultiAssumeFail1TestAssertions extends JUnitTest { + // Don't test -c, due to #2944. + override protected def frameworkArgss: List[List[String]] = + super.frameworkArgss.filterNot(_.contains("-c")) - override val expectedTotal: Int = 5 - - protected def expectedOutput(context: OutputContext): List[Output] = { - import context._ - List( - testRunStartedOutput, - testStartedOutput("multiTest1"), - testAssumptionViolatedOutput("multiTest1"), - skippedEvent, - testFinishedOutput("multiTest1"), - testStartedOutput("multiTest2"), - testFinishedOutput("multiTest2"), - successEvent, - testStartedOutput("multiTest3"), - testFinishedOutput("multiTest3"), - successEvent, - testStartedOutput("multiTest4"), - testFinishedOutput("multiTest4"), - successEvent, - testStartedOutput("multiTest5"), - testFinishedOutput("multiTest5"), - successEvent, - testRunFinishedOutput, - done - ) + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = { + builder + .assumptionViolated("multiTest1") + .success("multiTest2") + .success("multiTest3") + .success("multiTest4") + .success("multiTest5") } } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiAssumeFail2Test.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiAssumeFail2Test.scala index 44aa3cbad1..0dccb15f66 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiAssumeFail2Test.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiAssumeFail2Test.scala @@ -2,7 +2,8 @@ package org.scalajs.junit import org.junit.Assume._ import org.junit.Test -import org.scalajs.junit.utils.{JUnitTest, SuccessFrameworkArgs} + +import org.scalajs.junit.utils.JUnitTest class MultiAssumeFail2Test { @Test def multiTest1(): Unit = { @@ -16,33 +17,17 @@ class MultiAssumeFail2Test { @Test def multiTest5(): Unit = () } -class MultiAssumeFail2TestAssertions extends JUnitTest with SuccessFrameworkArgs { - - override val expectedTotal: Int = 5 +class MultiAssumeFail2TestAssertions extends JUnitTest { + // Don't test -c, due to #2944. + override protected def frameworkArgss: List[List[String]] = + super.frameworkArgss.filterNot(_.contains("-c")) - protected def expectedOutput(context: OutputContext): List[Output] = { - import context._ - List( - testRunStartedOutput, - testStartedOutput("multiTest1"), - testAssumptionViolatedOutput("multiTest1"), - skippedEvent, - testFinishedOutput("multiTest1"), - testStartedOutput("multiTest2"), - testFinishedOutput("multiTest2"), - successEvent, - testStartedOutput("multiTest3"), - testFinishedOutput("multiTest3"), - successEvent, - testStartedOutput("multiTest4"), - testAssumptionViolatedOutput("multiTest4"), - skippedEvent, - testFinishedOutput("multiTest4"), - testStartedOutput("multiTest5"), - testFinishedOutput("multiTest5"), - successEvent, - testRunFinishedOutput, - done - ) + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = { + builder + .assumptionViolated("multiTest1") + .success("multiTest2") + .success("multiTest3") + .assumptionViolated("multiTest4") + .success("multiTest5") } } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiBeforeAssumeFailTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiBeforeAssumeFailTest.scala index 6fa76d1cfd..413297485a 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiBeforeAssumeFailTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiBeforeAssumeFailTest.scala @@ -3,7 +3,7 @@ package org.scalajs.junit import org.junit.Assume._ import org.junit._ -import org.scalajs.junit.utils.{JUnitTest, SuccessFrameworkArgs} +import org.scalajs.junit.utils.JUnitTest object MultiBeforeAssumeFailTest { @BeforeClass def beforeClass(): Unit = { @@ -19,19 +19,7 @@ class MultiBeforeAssumeFailTest { @Test def multiTest5(): Unit = () } -class MultiBeforeAssumeFailTestAssertions - extends JUnitTest with SuccessFrameworkArgs { - - override val expectedIgnored: Int = 1 - - protected def expectedOutput(context: OutputContext): List[Output] = { - import context._ - List( - testRunStartedOutput, - testIgnoredClassOutput, - skippedEvent, - testRunFinishedOutput, - done - ) - } +class MultiBeforeAssumeFailTestAssertions extends JUnitTest { + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = + builder.ignoredClass() } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiIgnore1Test.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiIgnore1Test.scala index b6c0ec872f..a083ac9f0a 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiIgnore1Test.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiIgnore1Test.scala @@ -1,7 +1,7 @@ package org.scalajs.junit import org.junit._ -import org.scalajs.junit.utils.{JUnitTest, SuccessFrameworkArgs} +import org.scalajs.junit.utils.JUnitTest class MultiIgnore1Test { @Ignore @Test def multiTest1(): Unit = () @@ -11,31 +11,13 @@ class MultiIgnore1Test { @Test def multiTest5(): Unit = () } -class MultiIgnore1TestAssertions extends JUnitTest with SuccessFrameworkArgs { - - override val expectedIgnored: Int = 1 - override val expectedTotal: Int = 4 - - protected def expectedOutput(context: OutputContext): List[Output] = { - import context._ - List( - testRunStartedOutput, - testIgnoredOutput("multiTest1"), - skippedEvent, - testStartedOutput("multiTest2"), - testFinishedOutput("multiTest2"), - successEvent, - testStartedOutput("multiTest3"), - testFinishedOutput("multiTest3"), - successEvent, - testStartedOutput("multiTest4"), - testFinishedOutput("multiTest4"), - successEvent, - testStartedOutput("multiTest5"), - testFinishedOutput("multiTest5"), - successEvent, - testRunFinishedOutput, - done - ) +class MultiIgnore1TestAssertions extends JUnitTest { + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = { + builder + .ignored("multiTest1") + .success("multiTest2") + .success("multiTest3") + .success("multiTest4") + .success("multiTest5") } } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiIgnore2Test.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiIgnore2Test.scala index 3a5d65359d..28580e04a7 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiIgnore2Test.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiIgnore2Test.scala @@ -1,7 +1,7 @@ package org.scalajs.junit import org.junit._ -import org.scalajs.junit.utils.{JUnitTest, SuccessFrameworkArgs} +import org.scalajs.junit.utils.JUnitTest class MultiIgnore2Test { @Ignore @Test def multiTest1(): Unit = () @@ -11,30 +11,13 @@ class MultiIgnore2Test { @Test def multiTest5(): Unit = () } -class MultiIgnore2TestAssertions extends JUnitTest with SuccessFrameworkArgs { - - override val expectedIgnored: Int = 2 - override val expectedTotal: Int = 3 - - protected def expectedOutput(context: OutputContext): List[Output] = { - import context._ - List( - testRunStartedOutput, - testIgnoredOutput("multiTest1"), - skippedEvent, - testStartedOutput("multiTest2"), - testFinishedOutput("multiTest2"), - successEvent, - testStartedOutput("multiTest3"), - testFinishedOutput("multiTest3"), - successEvent, - testIgnoredOutput("multiTest4"), - skippedEvent, - testStartedOutput("multiTest5"), - testFinishedOutput("multiTest5"), - successEvent, - testRunFinishedOutput, - done - ) +class MultiIgnore2TestAssertions extends JUnitTest { + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = { + builder + .ignored("multiTest1") + .success("multiTest2") + .success("multiTest3") + .ignored("multiTest4") + .success("multiTest5") } } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiIgnoreAllTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiIgnoreAllTest.scala index 892922313e..90b6a9a3c3 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiIgnoreAllTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiIgnoreAllTest.scala @@ -1,7 +1,7 @@ package org.scalajs.junit import org.junit._ -import org.scalajs.junit.utils.{JUnitTest, SuccessFrameworkArgs} +import org.scalajs.junit.utils.JUnitTest class MultiIgnoreAllTest { @Ignore @Test def multiTest1(): Unit = () @@ -11,26 +11,13 @@ class MultiIgnoreAllTest { @Ignore @Test def multiTest5(): Unit = () } -class MultiIgnoreAllTestAssertions extends JUnitTest with SuccessFrameworkArgs { - - override val expectedIgnored: Int = 5 - - protected def expectedOutput(context: OutputContext): List[Output] = { - import context._ - List( - testRunStartedOutput, - testIgnoredOutput("multiTest1"), - skippedEvent, - testIgnoredOutput("multiTest2"), - skippedEvent, - testIgnoredOutput("multiTest3"), - skippedEvent, - testIgnoredOutput("multiTest4"), - skippedEvent, - testIgnoredOutput("multiTest5"), - skippedEvent, - testRunFinishedOutput, - done - ) +class MultiIgnoreAllTestAssertions extends JUnitTest { + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = { + builder + .ignored("multiTest1") + .ignored("multiTest2") + .ignored("multiTest3") + .ignored("multiTest4") + .ignored("multiTest5") } } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/TestTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/TestTest.scala deleted file mode 100644 index 40ad5b19e6..0000000000 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/TestTest.scala +++ /dev/null @@ -1,25 +0,0 @@ -package org.scalajs.junit - -import org.junit.Test -import org.scalajs.junit.utils.{JUnitTest, SuccessFrameworkArgs} - -class TestTest { - @Test def onlyTest(): Unit = () -} - -class TestTestAssertions extends JUnitTest with SuccessFrameworkArgs { - - override val expectedTotal: Int = 1 - - protected def expectedOutput(context: OutputContext): List[Output] = { - import context._ - List( - testRunStartedOutput, - testStartedOutput("onlyTest"), - testFinishedOutput("onlyTest"), - successEvent, - testRunFinishedOutput, - done - ) - } -} diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/utils/FailureFrameworkArgs.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/utils/FailureFrameworkArgs.scala deleted file mode 100644 index 8c4bb70ee4..0000000000 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/utils/FailureFrameworkArgs.scala +++ /dev/null @@ -1,19 +0,0 @@ -package org.scalajs.junit.utils - -trait FailureFrameworkArgs { - protected def frameworkArgss: List[List[String]] = List( - Nil, - List("-q"), - List("-a"), - List("-v"), - List("-n"), - List("-n", "-a"), - List("-n", "-v"), - List("-n", "-v", "-a"), - List("-n", "-v", "-c"), - List("-n", "-v", "-c", "-a"), - List("-v", "-q"), - List("-v", "-a"), - List("-v", "-c") - ) -} diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala index 7572a8f366..bf8c34b75b 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala @@ -8,8 +8,6 @@ import scala.annotation.tailrec abstract class JUnitTest { import JUnitTest._ - type Output = JUnitTest.Output - // ANSI colors codes private final val NORMAL = "\u001B[0m" private final val RED = "\u001B[31m" @@ -31,13 +29,23 @@ abstract class JUnitTest { myName.stripSuffix("Assertions") } - protected def frameworkArgss: List[List[String]] - - protected def expectedOutput(context: OutputContext): List[Output] - - val expectedFail = 0 - val expectedIgnored = 0 - val expectedTotal = 0 + protected def frameworkArgss: List[List[String]] = List( + List(), + List("-q"), + List("-a"), + List("-v"), + List("-n"), + List("-n", "-a"), + List("-n", "-v"), + List("-n", "-v", "-a"), + List("-n", "-v", "-c"), + List("-n", "-v", "-c", "-a"), + List("-v", "-q"), + List("-v", "-a"), + List("-v", "-c") + ) + + protected def expectedOutput(builder: OutputBuilder): OutputBuilder @Test def testJUnitOutput(): Unit = { for (frameworkArgs <- frameworkArgss) { @@ -47,81 +55,177 @@ abstract class JUnitTest { val tasks = runner.tasks(Array(new TaskDef(suiteUnderTestName, jUnitFramework.fingerprints.head, true, Array.empty))) - val recorder: JUnitTestRecorder = - new JUnitTestRecorder(new OutputContext(frameworkArgs)) + val recorder: JUnitTestRecorder = new JUnitTestRecorder // run all tasks and the tasks they generate, needs platform extension JUnitTestPlatformImpl.executeLoop(tasks, recorder) recorder.recordDone(runner.done()) - recorder.checkOutput() + val expected = expectedOutput( + new OutputBuilder(new ArgInfo(frameworkArgs))) + + expected.checkOutput(recorder.result()) } } - protected class OutputContext(frameworkArgs: List[String]) { + protected final class ArgInfo private[JUnitTest] (args: List[String]) { + lazy val verbose: Boolean = args.contains("-v") + lazy val noColor: Boolean = args.contains("-n") + lazy val quiet: Boolean = args.contains("-q") + lazy val decodeScalaNames: Boolean = args.contains("-s") + lazy val logExceptionClass: Boolean = !args.contains("-c") + lazy val logAssert: Boolean = args.contains("-a") - lazy val verbose: Boolean = frameworkArgs.contains("-v") - lazy val noColor: Boolean = frameworkArgs.contains("-n") - lazy val quiet: Boolean = frameworkArgs.contains("-q") - lazy val decodeScalaNames: Boolean = frameworkArgs.contains("-s") - lazy val notLogExceptionClass: Boolean = frameworkArgs.contains("-c") - lazy val logAssert: Boolean = frameworkArgs.contains("-a") + override def toString(): String = args.mkString("[", ", ", "]") + } - def formattedTestClass: String = { - val (pack, cls) = - suiteUnderTestName.splitAt(suiteUnderTestName.lastIndexOf('.')) - pack + '.' + yellow(cls.tail) + protected final class OutputBuilder private (val argInfo: ArgInfo, + total: Int, ignored: Int, failed: Int, output: List[Output]) { + import argInfo._ + + private[JUnitTest] def this(argInfo: ArgInfo) = this(argInfo, 0, 0, 0, Nil) + + // Builder methods. + + def success(testName: String): OutputBuilder = append(1, 0, 0)( + testStartedOutput(testName), + testFinishedOutput(testName), + successEvent + ) + + def ignored(testName: String): OutputBuilder = append(0, 1, 0)( + testIgnoredOutput(testName), + skippedEvent + ) + + def ignoredClass(): OutputBuilder = append(0, 1, 0)( + testIgnoredClassOutput, + skippedEvent + ) + + def assumptionViolated(testName: String): OutputBuilder = append(1, 0, 0)( + testStartedOutput(testName), + testAssumptionViolatedOutput(testName), + skippedEvent, + testFinishedOutput(testName) + ) + + def exception(testName: String, msg: String, clazz: String): OutputBuilder = { + append(1, 0, 1)( + testStartedOutput(testName), + testExceptionMsgOutput(testName, msg, clazz), + failureEvent, + testFinishedOutput(testName) + ) } - def formattedAssumptionViolatedException: String = - "org.junit.internal." + red("AssumptionViolatedException") + def assertion(testName: String, message: String): OutputBuilder = { + append(1, 0, 1)( + testStartedOutput(testName), + testAssertionErrorMsgOutput(testName, message), + failureEvent, + testFinishedOutput(testName) + ) + } + + private def append(t: Int, i: Int, f: Int)(out: Output*) = { + new OutputBuilder(argInfo, total + t, ignored + i, failed + f, output ++ out) + } + + // Test method. + + private[JUnitTest] def checkOutput(actual: List[Output]): Unit = { + val expected = ( + testRunStartedOutput :: output ::: + List(testRunFinishedOutput(total, ignored, failed), done) + ) + + @tailrec def minimizeDiff(list1: List[Output], list2: List[Output], + dropped: Int): (List[Output], List[Output], Int) = { + (list1, list2) match { + case (x :: xs, y :: ys) if x == y => minimizeDiff(xs, ys, dropped + 1) + case _ => (list1, list2, dropped) + } + } + + val (expected1, actual1, droppedFront) = + minimizeDiff(expected, actual, 0) + val (expected2, actual2, droppedBack) = + minimizeDiff(expected1.reverse, actual1.reverse, 0) + val expectedMinimized = expected2.reverse + val actualMinimized = actual2.reverse + + if (expectedMinimized != actualMinimized) { + val msg = new StringBuilder + def appendElems(original: List[Output], minimized: List[Output]): Unit = { + def appendGreyLine(out: Output): Unit = { + msg.append(GREY + " " + withoutColor(out.toString) + NORMAL + "\n") + } + original.slice(droppedFront - 3, droppedFront).foreach(appendGreyLine) + minimized.foreach(out => msg.append(" " + out + "\n")) + val backIndex = original.size - droppedBack + original.slice(backIndex, backIndex + 3).foreach(appendGreyLine) + } + + msg.append(s"JUnit output mismatch with $argInfo:\n") + msg.append(s"Expected: List(\n") + appendElems(expected, expectedMinimized) + msg.append(")\nbut got: List(\n") + appendElems(actual, actualMinimized) + msg.append(")") + + throw new Exception(msg.result()) + } + } - def done: Output = Done("") + // Text builders. - def testStartedOutput(method: String): Output = { + private def done: Output = Done("") + + private def testStartedOutput(method: String): Output = { infoIfOrElseDebug(verbose, s"Test $formattedTestClass.${cyan(method)} started") } - def testIgnoredOutput(method: String): Output = + private def testIgnoredOutput(method: String): Output = Info(s"Test $formattedTestClass.${cyan(method)} ignored") - def testIgnoredClassOutput: Output = + private def testIgnoredClassOutput: Output = Info(s"Test $formattedTestClass ignored") - def testExceptionMsgOutput(method: String, msg: String, exPack: String, + private def testExceptionMsgOutput(method: String, msg: String, exClass: String): Output = { - val exClassStr = - if (notLogExceptionClass) "" - else ' ' + exPack + '.' + red(exClass) + ':' + val exClassStr = exceptionClassInfo(show = logExceptionClass, exClass) Error(s"Test $formattedTestClass.${red(method)} " + - s"failed:$exClassStr $msg, took $TIME_TAG sec") + s"failed: $exClassStr$msg, took $TIME_TAG sec") } - def testAssertionErrorMsgOutput(method: String, msg: String): Output = { - val assertClass = - if (notLogExceptionClass || !logAssert) "" - else " java.lang." + red("AssertionError") + ':' - Error(s"Test $formattedTestClass.${red(method)} failed:$assertClass " + + private def testAssertionErrorMsgOutput(method: String, msg: String): Output = { + val assertClass = exceptionClassInfo(show = logExceptionClass && logAssert, + "java.lang.AssertionError") + Error(s"Test $formattedTestClass.${red(method)} failed: $assertClass" + s"$msg, took $TIME_TAG sec") } - def testAssumptionViolatedOutput(method: String): Output = { + private def testAssumptionViolatedOutput(method: String): Output = { + val exceptionStr = exceptionClassInfo(logExceptionClass, + "org.junit.internal.AssumptionViolatedException") Warn(s"Test assumption in test $formattedTestClass.${red(method)}" + - s" failed: $formattedAssumptionViolatedException:" + - s" This assume should not pass, took $TIME_TAG sec") + s" failed: $exceptionStr" + + s"This assume should not pass, took $TIME_TAG sec") } - def testFinishedOutput(method: String): Output = { + private def testFinishedOutput(method: String): Output = { Debug(s"Test $formattedTestClass.${cyan(method)} finished, " + s"took $TIME_TAG sec") } - def testRunStartedOutput: Output = + private def testRunStartedOutput: Output = infoIfOrElseDebug(verbose, blue("Test run started")) - def testRunFinishedOutput: Output = { + private def testRunFinishedOutput(expectedTotal: Int, expectedIgnored: Int, + expectedFail: Int): Output = { val buff = new StringBuilder buff.append(blue("Test run finished: ")) val failedColor = if (expectedFail == 0) blue _ else red _ @@ -133,16 +237,27 @@ abstract class JUnitTest { infoIfOrElseDebug(verbose, buff.result()) } - def skippedEvent: Output = Event("Skipped") - def successEvent: Output = Event("Success") - def failureEvent: Output = Event("Failure") + private def skippedEvent: Output = Event("Skipped") + private def successEvent: Output = Event("Success") + private def failureEvent: Output = Event("Failure") + + private def formattedTestClass: String = + formatClass(suiteUnderTestName, yellow) + + private def exceptionClassInfo(show: Boolean, fullName: String) = { + if (show) formatClass(fullName, red) + ": " + else "" + } + + private def formatClass(fullName: String, color: String => String) = { + val (packAndDot, cls) = fullName.splitAt(fullName.lastIndexOf('.') + 1) + packAndDot + color(cls) + } - def infoIfOrElseDebug(p: Boolean, msg: String): Output = + private def infoIfOrElseDebug(p: Boolean, msg: String): Output = if (p) Info(msg) else Debug(msg) - override def toString: String = frameworkArgs.mkString("[", ", ", "]") - private def red(str: String): String = if (noColor) str else RED + str + NORMAL @@ -164,9 +279,8 @@ abstract class JUnitTest { else CYAN + str + NORMAL } - protected class JUnitTestRecorder(context: OutputContext) - extends Logger with EventHandler { - val buff = List.newBuilder[Output] + private class JUnitTestRecorder extends Logger with EventHandler { + private val buff = List.newBuilder[Output] def ansiCodesSupported(): Boolean = true @@ -192,45 +306,7 @@ abstract class JUnitTest { def recordDone(msg: String): Unit = buff += Done(msg) - def checkOutput(): Unit = { - @tailrec def minimizeDiff(list1: List[Output], list2: List[Output], - dropped: Int): (List[Output], List[Output], Int) = { - (list1, list2) match { - case (x :: xs, y :: ys) if x == y => minimizeDiff(xs, ys, dropped + 1) - case _ => (list1, list2, dropped) - } - } - - val expected = expectedOutput(context) - val actual = buff.result() - val (expected1, actual1, droppedFront) = - minimizeDiff(expected, actual, 0) - val (expected2, actual2, droppedBack) = - minimizeDiff(expected1.reverse, actual1.reverse, 0) - val expectedMinimized = expected2.reverse - val actualMinimized = actual2.reverse - - if (expectedMinimized != actualMinimized) { - val msg = new StringBuilder - def appendElems(original: List[Output], minimized: List[Output]): Unit = { - def appendGreyLine(out: Output): Unit = { - msg.append(GREY + " " + withoutColor(out.toString) + NORMAL + "\n") - } - original.slice(droppedFront - 3, droppedFront).foreach(appendGreyLine) - minimized.foreach(out => msg.append(" " + out + "\n")) - val backIndex = original.size - droppedBack - original.slice(backIndex, backIndex + 3).foreach(appendGreyLine) - } - msg.append(s"JUnit output mismatch with $context:\n") - msg.append(s"Expected: List(\n") - appendElems(expected, expectedMinimized) - msg.append(")\nbut got: List(\n") - appendElems(actual, actualMinimized) - msg.append(")") - - throw new Exception(msg.result()) - } - } + def result(): List[Output] = buff.result() private def encodeTimes(msg: String): String = { val enc1 = @@ -245,12 +321,12 @@ abstract class JUnitTest { } object JUnitTest { - sealed trait Output - final case class Info(msg: String) extends Output - final case class Warn(msg: String) extends Output - final case class Error(msg: String) extends Output - final case class Debug(msg: String) extends Output - final case class Trace(msg: String) extends Output - final case class Event(status: String) extends Output - final case class Done(msg: String) extends Output + private sealed trait Output + private final case class Info(msg: String) extends Output + private final case class Warn(msg: String) extends Output + private final case class Error(msg: String) extends Output + private final case class Debug(msg: String) extends Output + private final case class Trace(msg: String) extends Output + private final case class Event(status: String) extends Output + private final case class Done(msg: String) extends Output } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/utils/SuccessFrameworkArgs.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/utils/SuccessFrameworkArgs.scala deleted file mode 100644 index 30f498eaf6..0000000000 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/utils/SuccessFrameworkArgs.scala +++ /dev/null @@ -1,12 +0,0 @@ -package org.scalajs.junit.utils - -trait SuccessFrameworkArgs { - protected def frameworkArgss: List[List[String]] = List( - Nil, - List("-n"), - List("-v"), - List("-n", "-v"), - List("-q"), - List("-v", "-q") - ) -} From a782943956421384c80898d9421f0a745888eaf4 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Thu, 11 May 2017 10:40:36 +0200 Subject: [PATCH 0265/2665] Fix #2944: Respect -c flag for assumptions --- .../main/scala/org/scalajs/junit/JUnitExecuteTest.scala | 9 +++++---- .../src/test/scala/org/scalajs/junit/AssumeTest.scala | 4 ---- .../scala/org/scalajs/junit/MultiAssumeFail1Test.scala | 4 ---- .../scala/org/scalajs/junit/MultiAssumeFail2Test.scala | 4 ---- 4 files changed, 5 insertions(+), 16 deletions(-) diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala index 1edc22b461..ce516c2957 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala @@ -210,10 +210,11 @@ final class JUnitExecuteTest(taskDef: TaskDef, runner: JUnitBaseRunner, private[this] def logAssertionWarning(methodName: String, ex: Throwable, timeInSeconds: Double): Unit = { - val msg = { - "failed: org.junit.internal." + c("AssumptionViolatedException", ERRMSG) + - ": " + ex.getMessage + ", took " + timeInSeconds + " sec" - } + val exName = + if (runner.runSettings.notLogExceptionClass) "" + else "org.junit.internal." + c("AssumptionViolatedException", ERRMSG) + ": " + + val msg = s"failed: $exName${ex.getMessage}, took $timeInSeconds sec" logFormattedWarn("Test assumption in test ", methodName, msg) } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/AssumeTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/AssumeTest.scala index 3df1a0290c..889c75fe44 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/AssumeTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/AssumeTest.scala @@ -12,10 +12,6 @@ class AssumeTest { } class AssumeTestAssertions extends JUnitTest { - // Don't test -c, due to #2944. - override protected def frameworkArgss: List[List[String]] = - super.frameworkArgss.filterNot(_.contains("-c")) - protected def expectedOutput(builder: OutputBuilder): OutputBuilder = builder.assumptionViolated("assumeFail") } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiAssumeFail1Test.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiAssumeFail1Test.scala index 8196635982..3ea020ff62 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiAssumeFail1Test.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiAssumeFail1Test.scala @@ -17,10 +17,6 @@ class MultiAssumeFail1Test { } class MultiAssumeFail1TestAssertions extends JUnitTest { - // Don't test -c, due to #2944. - override protected def frameworkArgss: List[List[String]] = - super.frameworkArgss.filterNot(_.contains("-c")) - protected def expectedOutput(builder: OutputBuilder): OutputBuilder = { builder .assumptionViolated("multiTest1") diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiAssumeFail2Test.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiAssumeFail2Test.scala index 0dccb15f66..d9d2da82e6 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiAssumeFail2Test.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiAssumeFail2Test.scala @@ -18,10 +18,6 @@ class MultiAssumeFail2Test { } class MultiAssumeFail2TestAssertions extends JUnitTest { - // Don't test -c, due to #2944. - override protected def frameworkArgss: List[List[String]] = - super.frameworkArgss.filterNot(_.contains("-c")) - protected def expectedOutput(builder: OutputBuilder): OutputBuilder = { builder .assumptionViolated("multiTest1") From ee998e2c4df0a3af9b2fb80d09b48c767dc93aff Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 20 May 2017 16:54:42 +0200 Subject: [PATCH 0266/2665] Make JUnit assertions order independent. --- .../org/scalajs/junit/AssertTrueTest.scala | 10 +- .../org/scalajs/junit/utils/JUnitTest.scala | 108 ++++++++++++------ 2 files changed, 82 insertions(+), 36 deletions(-) diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertTrueTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertTrueTest.scala index bd6ff14dc6..d5ea148111 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertTrueTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertTrueTest.scala @@ -6,12 +6,18 @@ import org.junit.Test import org.scalajs.junit.utils._ class AssertTrueTest { - @Test def test(): Unit = { + @Test def failTest(): Unit = { assertTrue(false) } + + @Test def successTest(): Unit = { + assertTrue(true) + } } class AssertTrueTestAssertions extends JUnitTest { protected def expectedOutput(builder: OutputBuilder): OutputBuilder = - builder.assertion("test", "null") + builder + .success("successTest") + .assertion("failTest", "null") } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala index bf8c34b75b..fca35bca80 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala @@ -81,7 +81,7 @@ abstract class JUnitTest { } protected final class OutputBuilder private (val argInfo: ArgInfo, - total: Int, ignored: Int, failed: Int, output: List[Output]) { + total: Int, ignored: Int, failed: Int, output: List[List[Output]]) { import argInfo._ private[JUnitTest] def this(argInfo: ArgInfo) = this(argInfo, 0, 0, 0, Nil) @@ -130,55 +130,95 @@ abstract class JUnitTest { } private def append(t: Int, i: Int, f: Int)(out: Output*) = { - new OutputBuilder(argInfo, total + t, ignored + i, failed + f, output ++ out) + new OutputBuilder(argInfo, total + t, ignored + i, failed + f, + output :+ out.toList) } // Test method. - private[JUnitTest] def checkOutput(actual: List[Output]): Unit = { - val expected = ( - testRunStartedOutput :: output ::: - List(testRunFinishedOutput(total, ignored, failed), done) - ) + private class Matcher private (matched: List[Output], remaining: List[Output]) { + def this(remaining: List[Output]) = this(Nil, remaining) + + def matchOne(prefix: List[Output]): Matcher = { + tryMatch(prefix).getOrElse(fail(List(prefix))) + } - @tailrec def minimizeDiff(list1: List[Output], list2: List[Output], - dropped: Int): (List[Output], List[Output], Int) = { - (list1, list2) match { - case (x :: xs, y :: ys) if x == y => minimizeDiff(xs, ys, dropped + 1) - case _ => (list1, list2, dropped) + @tailrec + final def matchUnordered(prefixes: List[List[Output]]): Matcher = { + matchOneOf(prefixes) match { + case (newMatcher, Nil) => newMatcher + case (newMatcher, remaining) => newMatcher.matchUnordered(remaining) } } - - val (expected1, actual1, droppedFront) = - minimizeDiff(expected, actual, 0) - val (expected2, actual2, droppedBack) = - minimizeDiff(expected1.reverse, actual1.reverse, 0) - val expectedMinimized = expected2.reverse - val actualMinimized = actual2.reverse - - if (expectedMinimized != actualMinimized) { - val msg = new StringBuilder - def appendElems(original: List[Output], minimized: List[Output]): Unit = { - def appendGreyLine(out: Output): Unit = { - msg.append(GREY + " " + withoutColor(out.toString) + NORMAL + "\n") + + def assertEmpty(): Unit = assert(remaining.isEmpty) + + /** Tries to match the prefix. If succeeds, returns a new matcher. */ + private def tryMatch(prefix: List[Output]): Option[Matcher] = { + if (remaining.startsWith(prefix)) { + val (justMatched, newRemaining) = remaining.splitAt(prefix.length) + Some(new Matcher(matched ++ justMatched, newRemaining)) + } else { + None + } + } + + private def matchOneOf( + prefixes: List[List[Output]]): (Matcher, List[List[Output]]) = { + @tailrec + def loop(matcher: Matcher, toSearch: List[List[Output]], + tried: List[List[Output]]): (Matcher, List[List[Output]]) = { + toSearch match { + case x :: xs => + matcher.tryMatch(x) match { + case Some(m) => (m, xs ::: tried) + case None => loop(matcher, xs, x :: tried) + } + + case Nil => + matcher.fail(tried) } - original.slice(droppedFront - 3, droppedFront).foreach(appendGreyLine) - minimized.foreach(out => msg.append(" " + out + "\n")) - val backIndex = original.size - droppedBack - original.slice(backIndex, backIndex + 3).foreach(appendGreyLine) } - + + loop(this, prefixes, Nil) + } + + private def fail(expecteds: List[List[Output]]): Nothing = { + val msg = new StringBuilder msg.append(s"JUnit output mismatch with $argInfo:\n") - msg.append(s"Expected: List(\n") - appendElems(expected, expectedMinimized) - msg.append(")\nbut got: List(\n") - appendElems(actual, actualMinimized) + msg.append("Expected next, one of:\n") + + def appendOut(out: Output) = + msg.append(" " + out + "\n") + + for (expected <- expecteds) { + msg.append("List(\n") + expected.foreach(appendOut) + msg.append(")\n\n") + } + + msg.append("but got: List(\n") + + val maxLen = expecteds.map(_.size).max + + for (out <- matched.takeRight(3)) + msg.append(GREY + " " + withoutColor(out.toString) + NORMAL + "\n") + + remaining.take(maxLen).foreach(appendOut) msg.append(")") throw new Exception(msg.result()) } } + private[JUnitTest] def checkOutput(actual: List[Output]): Unit = { + new Matcher(actual) + .matchOne(List(testRunStartedOutput)) + .matchUnordered(output) + .matchOne(List(testRunFinishedOutput(total, ignored, failed), done)) + .assertEmpty() + } + // Text builders. private def done: Output = Done("") From 1c063791122f6c33005a41b507f71f2430085ee3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 22 May 2017 00:41:51 +0200 Subject: [PATCH 0267/2665] Fix #2839: Remove PhantomJS-related stuff in the core repo. PhantomJS support moved in the separate repository https://github.com/scala-js/scala-js-env-phantomjs. --- DEVELOPING.md | 8 +- build.sbt | 2 - ci/matrix.xml | 28 +- .../phantomjs/JettyWebsocketManager.scala | 135 ----- .../jsenv/phantomjs/PhantomJSEnv.scala | 495 ------------------ .../phantomjs/PhantomJettyClassLoader.scala | 71 --- .../jsenv/phantomjs/RetryingComJSEnv.scala | 195 ------- .../jsenv/phantomjs/WebsocketListener.scala | 18 - .../jsenv/phantomjs/WebsocketManager.scala | 18 - .../jsenv/phantomjs/PhantomJSTest.scala | 7 - .../PhantomJSWithCustomInitFilesTest.scala | 9 - .../phantomjs/RetryingComJSEnvTest.scala | 92 ---- .../sbtplugin/PhantomJSEnvPlugin.scala | 102 ---- project/Build.scala | 80 +-- project/build.sbt | 8 +- sbt-plugin-test/build.sbt | 9 - sbt-plugin-test/project/Jetty9Test.scala | 85 --- sbt-plugin-test/project/build.sbt | 5 - .../scalajs/testsuite/utils/Platform.scala | 1 - .../testsuite/compiler/IntJSTest.scala | 2 - .../compiler/InteroperabilityTest.scala | 18 +- .../testsuite/javalib/lang/SystemJSTest.scala | 11 +- .../scalajs/testsuite/utils/Platform.scala | 1 - .../javalib/lang/MathTestOnJDK8.scala | 5 +- 24 files changed, 17 insertions(+), 1388 deletions(-) delete mode 100644 phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/JettyWebsocketManager.scala delete mode 100644 phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala delete mode 100644 phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJettyClassLoader.scala delete mode 100644 phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnv.scala delete mode 100644 phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketListener.scala delete mode 100644 phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketManager.scala delete mode 100644 phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/PhantomJSTest.scala delete mode 100644 phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/PhantomJSWithCustomInitFilesTest.scala delete mode 100644 phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnvTest.scala delete mode 100644 phantomjs-sbt-plugin/src/main/scala/org/scalajs/jsenv/phantomjs/sbtplugin/PhantomJSEnvPlugin.scala delete mode 100644 sbt-plugin-test/project/Jetty9Test.scala diff --git a/DEVELOPING.md b/DEVELOPING.md index d9798cf676..af360cadb3 100644 --- a/DEVELOPING.md +++ b/DEVELOPING.md @@ -48,10 +48,6 @@ source map tests locally with this setting: > set jsEnv in testSuite := NodeJSEnv().value.withSourceMap(false) -To test with PhantomJS, use this setting: - - > set inScope(ThisScope in testSuite)(Seq(jsEnv := PhantomJSEnv().value)) - There are also a few additional tests in a separate testing project: > testSuiteEx/test @@ -111,7 +107,7 @@ of `library/package`. Note that the sbt plugin depends on the IR and the tools. -* `js-envs/` The JavaScript environments and runners (Node.js and PhantomJS) +* `js-envs/` The JavaScript environments and runners (generic definitions + Node.js) * `sbt-plugin/` The sbt plugin itself ### Testing projects @@ -124,7 +120,7 @@ Note that the sbt plugin depends on the IR and the tools. * `examples/helloworld/` A simple Hello World, typically used as sandbox for quick testing * `examples/reversi/` The historical Reversi demo - we use it to track the impact of changes on the emitted code size -* `examples/testing/` A simple project with tests using the DOM, mostly used to test the support for the DOM with jsdom and PhantomJS +* `examples/testing/` A simple project with tests using the DOM, mostly used to test the support for the DOM with jsdom These example projects also have HTML pages to run them in real browsers. diff --git a/build.sbt b/build.sbt index 69adf9832f..14fed3c921 100644 --- a/build.sbt +++ b/build.sbt @@ -21,8 +21,6 @@ val jUnitRuntime = Build.jUnitRuntime val jUnitTestOutputsJS = Build.jUnitTestOutputsJS val jUnitTestOutputsJVM = Build.jUnitTestOutputsJVM val jUnitPlugin = Build.jUnitPlugin -val phantomJSEnv = Build.phantomJSEnv -val phantomJSEnvPlugin = Build.phantomJSEnvPlugin val examples = Build.examples val helloworld = Build.helloworld val reversi = Build.reversi diff --git a/ci/matrix.xml b/ci/matrix.xml index cc8992f440..9d7bd84b01 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -31,12 +31,6 @@ sbtretry 'set scalaJSSemantics in helloworld ~= (_.withAsInstanceOfs(org.scalajs.core.tools.sem.CheckedBehavior.Unchecked))' \ ++$scala helloworld/run \ helloworld/clean && - sbtretry 'set inScope(ThisScope in helloworld)(jsEnv := new org.scalajs.jsenv.phantomjs.RetryingComJSEnv(PhantomJSEnv().value))' \ - ++$scala helloworld/run && - sbtretry 'set inScope(ThisScope in helloworld)(jsEnv := new org.scalajs.jsenv.phantomjs.RetryingComJSEnv(PhantomJSEnv().value))' \ - 'set scalaJSStage in Global := FullOptStage' \ - ++$scala helloworld/run \ - helloworld/clean && sbtretry ++$scala \ 'set scalaJSModuleKind in helloworld := ModuleKind.CommonJSModule' \ helloworld/run \ @@ -45,17 +39,8 @@ sbtretry 'set scalaJSStage in Global := FullOptStage' \ ++$scala testingExample/test \ testingExample/clean && - sbtretry 'set inScope(ThisScope in testingExample)(jsEnv := new org.scalajs.jsenv.phantomjs.RetryingComJSEnv(PhantomJSEnv().value))' \ - ++$scala testingExample/test && - sbtretry 'set inScope(ThisScope in testingExample)(jsEnv := new org.scalajs.jsenv.phantomjs.RetryingComJSEnv(PhantomJSEnv().value))' \ - 'set scalaJSStage in Global := FullOptStage' \ - ++$scala testingExample/test \ - testingExample/clean && sbtretry 'set scalaJSOptimizerOptions in testingExample ~= (_.withDisableOptimizer(true))' \ ++$scala testingExample/test && - sbtretry 'set inScope(ThisScope in testingExample)(jsEnv := new org.scalajs.jsenv.phantomjs.RetryingComJSEnv(PhantomJSEnv().value))' \ - 'set scalaJSOptimizerOptions in testingExample ~= (_.withDisableOptimizer(true))' \ - ++$scala testingExample/test && sbtretry ++$scala library/test && sbtretry ++$scala testSuiteJVM/test testSuiteJVM/clean && sbtretry ++$scala testSuite/test && @@ -98,14 +83,6 @@ 'set scalaJSOptimizerOptions in $testSuite ~= (_.withDisableOptimizer(true))' \ ++$scala $testSuite/test \ $testSuite/clean && - sbtretry 'set inScope(ThisScope in $testSuite)(jsEnv := new org.scalajs.jsenv.phantomjs.RetryingComJSEnv(PhantomJSEnv().value))' \ - 'set parallelExecution in ($testSuite, Test) := false' \ - ++$scala $testSuite/test && - sbtretry 'set inScope(ThisScope in $testSuite)(jsEnv := new org.scalajs.jsenv.phantomjs.RetryingComJSEnv(PhantomJSEnv().value))' \ - 'set parallelExecution in ($testSuite, Test) := false' \ - 'set scalaJSStage in Global := FullOptStage' \ - ++$scala $testSuite/test \ - $testSuite/clean && sbtretry 'set scalacOptions in $testSuite += "-Xexperimental"' \ ++$scala $testSuite/test && sbtretry 'set scalacOptions in $testSuite += "-Xexperimental"' \ @@ -226,13 +203,12 @@ testInterface/publishLocal stubs/publishLocal \ jUnitPlugin/publishLocal jUnitRuntime/publishLocal && sbt ++2.10.6 ir/publishLocal tools/publishLocal jsEnvs/publishLocal \ - testAdapter/publishLocal sbtPlugin/publishLocal \ - phantomJSEnv/publishLocal phantomJSEnvPlugin/publishLocal && + testAdapter/publishLocal sbtPlugin/publishLocal && cd sbt-plugin-test && sbt noDOM/run noDOM/testHtmlFastOpt noDOM/testHtmlFullOpt \ withDOM/run withDOM/testHtmlFastOpt withDOM/testHtmlFullOpt \ multiTestJS/testHtmlFastOpt multiTestJS/testHtmlFullOpt \ - jetty9/run test \ + test \ noDOM/clean noDOM/concurrentUseOfLinkerTest \ jsDependenciesTest/packageJSDependencies \ jsDependenciesTest/packageMinifiedJSDependencies \ diff --git a/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/JettyWebsocketManager.scala b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/JettyWebsocketManager.scala deleted file mode 100644 index 97a9b8c303..0000000000 --- a/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/JettyWebsocketManager.scala +++ /dev/null @@ -1,135 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ PhantomJS support for Scala.js ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ https://www.scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - -package org.scalajs.jsenv.phantomjs - -import javax.servlet.http.HttpServletRequest - -import org.eclipse.jetty.server.Server -import org.eclipse.jetty.server.nio.SelectChannelConnector -import org.eclipse.jetty.websocket.{WebSocket, WebSocketHandler} -import org.eclipse.jetty.util.component.{LifeCycle, AbstractLifeCycle} -import org.eclipse.jetty.util.log - -private[phantomjs] final class JettyWebsocketManager( - wsListener: WebsocketListener) extends WebsocketManager { thisMgr => - - private[this] var webSocketConn: WebSocket.Connection = null - private[this] var closed = false - - // We can just set the logger here, since we are supposed to be protected by - // the private ClassLoader that loads us reflectively. - log.Log.setLog(new WSLogger("root")) - - private[this] val connector = new SelectChannelConnector - - connector.setHost("localhost") - connector.setPort(0) - - private[this] val server = new Server() - - server.addConnector(connector) - server.setHandler(new WebSocketHandler { - // Support Hixie 76 for Phantom.js - getWebSocketFactory().setMinVersion(-1) - - override def doWebSocketConnect( - request: HttpServletRequest, protocol: String): WebSocket = - new ComWebSocketListener - }) - - server.addLifeCycleListener(new AbstractLifeCycle.AbstractLifeCycleListener { - override def lifeCycleStarted(event: LifeCycle): Unit = { - if (event.isRunning()) - wsListener.onRunning() - } - }) - - private class ComWebSocketListener extends WebSocket.OnTextMessage { - override def onOpen(connection: WebSocket.Connection): Unit = { - thisMgr.synchronized { - if (isConnected) - throw new IllegalStateException("Client connected twice") - connection.setMaxIdleTime(Int.MaxValue) - webSocketConn = connection - } - wsListener.onOpen() - } - - override def onClose(statusCode: Int, reason: String): Unit = { - thisMgr.synchronized { - webSocketConn = null - closed = true - } - wsListener.onClose() - server.stop() - - if (statusCode != 1000) { - throw new Exception("Abnormal closing of connection. " + - s"Code: $statusCode, Reason: $reason") - } - } - - override def onMessage(message: String): Unit = - wsListener.onMessage(message) - } - - private class WSLogger(fullName: String) extends log.AbstractLogger { - private[this] var debugEnabled = false - - def debug(msg: String, args: Object*): Unit = - if (debugEnabled) log("DEBUG", msg, args) - - def debug(msg: String, thrown: Throwable): Unit = - if (debugEnabled) log("DEBUG", msg, thrown) - - def debug(thrown: Throwable): Unit = - if (debugEnabled) log("DEBUG", thrown) - - def getName(): String = fullName - - def ignore(ignored: Throwable): Unit = () - - def info(msg: String, args: Object*): Unit = log("INFO", msg, args) - def info(msg: String, thrown: Throwable): Unit = log("INFO", msg, thrown) - def info(thrown: Throwable): Unit = log("INFO", thrown) - - def warn(msg: String, args: Object*): Unit = log("WARN", msg, args) - def warn(msg: String, thrown: Throwable): Unit = log("WARN", msg, thrown) - def warn(thrown: Throwable): Unit = log("WARN", thrown) - - def isDebugEnabled(): Boolean = debugEnabled - def setDebugEnabled(enabled: Boolean): Unit = debugEnabled = enabled - - private def log(lvl: String, msg: String, args: Object*): Unit = - wsListener.log(s"$lvl: $msg " + args.mkString(", ")) - - private def log(lvl: String, msg: String, thrown: Throwable): Unit = - wsListener.log(s"$lvl: $msg $thrown\n{$thrown.getStackStrace}") - - private def log(lvl: String, thrown: Throwable): Unit = - wsListener.log(s"$lvl: $thrown\n{$thrown.getStackStrace}") - - protected def newLogger(fullName: String) = new WSLogger(fullName) - } - - def start(): Unit = server.start() - - def stop(): Unit = server.stop() - - def isConnected: Boolean = webSocketConn != null && !closed - def isClosed: Boolean = closed - - def localPort: Int = connector.getLocalPort() - - def sendMessage(msg: String): Unit = synchronized { - if (webSocketConn != null) - webSocketConn.sendMessage(msg) - } - -} diff --git a/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala deleted file mode 100644 index b4edeecbf1..0000000000 --- a/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala +++ /dev/null @@ -1,495 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ PhantomJS support for Scala.js ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ https://www.scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - -package org.scalajs.jsenv.phantomjs - -import org.scalajs.jsenv._ -import org.scalajs.jsenv.Utils.OptDeadline - -import org.scalajs.core.ir.Utils.{escapeJS, fixFileURI} - -import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.logging._ - -import java.io.{ Console => _, _ } -import java.net._ - -import scala.io.Source -import scala.collection.mutable -import scala.annotation.tailrec - -import scala.concurrent.{ExecutionContext, TimeoutException, Future} -import scala.concurrent.duration.Duration - -class PhantomJSEnv( - @deprecatedName('phantomjsPath) - protected val executable: String = "phantomjs", - @deprecatedName('addArgs) - args: Seq[String] = Seq.empty, - @deprecatedName('addEnv) - env: Map[String, String] = Map.empty, - val autoExit: Boolean = true, - jettyClassLoader: ClassLoader = null -) extends ExternalJSEnv(args, env) with ComJSEnv { - - import PhantomJSEnv._ - - protected def vmName: String = "PhantomJS" - - override def jsRunner(files: Seq[VirtualJSFile]): JSRunner = - new PhantomRunner(files) - - override def asyncRunner(files: Seq[VirtualJSFile]): AsyncJSRunner = - new AsyncPhantomRunner(files) - - override def comRunner(files: Seq[VirtualJSFile]): ComJSRunner = - new ComPhantomRunner(files) - - protected class PhantomRunner(files: Seq[VirtualJSFile]) - extends ExtRunner(files) with AbstractPhantomRunner - - protected class AsyncPhantomRunner(files: Seq[VirtualJSFile]) - extends AsyncExtRunner(files) with AbstractPhantomRunner - - protected class ComPhantomRunner(files: Seq[VirtualJSFile]) - extends AsyncPhantomRunner(files) with ComJSRunner { - - private var mgrIsRunning: Boolean = false - - private object websocketListener extends WebsocketListener { // scalastyle:ignore - def onRunning(): Unit = ComPhantomRunner.this.synchronized { - mgrIsRunning = true - ComPhantomRunner.this.notifyAll() - } - - def onOpen(): Unit = ComPhantomRunner.this.synchronized { - ComPhantomRunner.this.notifyAll() - } - - def onClose(): Unit = ComPhantomRunner.this.synchronized { - ComPhantomRunner.this.notifyAll() - } - - def onMessage(msg: String): Unit = ComPhantomRunner.this.synchronized { - recvBuf.enqueue(msg) - ComPhantomRunner.this.notifyAll() - } - - def log(msg: String): Unit = logger.debug(s"PhantomJS WS Jetty: $msg") - } - - private def loadMgr() = { - val loader = - if (jettyClassLoader != null) jettyClassLoader - else getClass().getClassLoader() - - val clazz = loader.loadClass( - "org.scalajs.jsenv.phantomjs.JettyWebsocketManager") - - val ctors = clazz.getConstructors() - assert(ctors.length == 1, "JettyWebsocketManager may only have one ctor") - - val mgr = ctors.head.newInstance(websocketListener) - - mgr.asInstanceOf[WebsocketManager] - } - - private val mgr: WebsocketManager = loadMgr() - - future.onComplete(_ => synchronized(notifyAll()))(ExecutionContext.global) - - private[this] val recvBuf = mutable.Queue.empty[String] - private[this] val fragmentsBuf = new StringBuilder - - private def comSetup = { - def maybeExit(code: Int) = - if (autoExit) - s"window.callPhantom({ action: 'exit', returnValue: $code });" - else - "" - - /* The WebSocket server starts asynchronously. We must wait for it to - * be fully operational before a) retrieving the port it is running on - * and b) feeding the connecting JS script to the VM. - */ - synchronized { - while (!mgrIsRunning) - wait(10000) - if (!mgrIsRunning) - throw new TimeoutException( - "The PhantomJS WebSocket server startup timed out") - } - - val serverPort = mgr.localPort - assert(serverPort > 0, - s"Manager running with a non-positive port number: $serverPort") - - val code = s""" - |(function() { - | var MaxPayloadSize = $MaxCharPayloadSize; - | - | // The socket for communication - | var websocket = null; - | - | // Buffer for messages sent before socket is open - | var outMsgBuf = null; - | - | function sendImpl(msg) { - | var frags = (msg.length / MaxPayloadSize) | 0; - | - | for (var i = 0; i < frags; ++i) { - | var payload = msg.substring( - | i * MaxPayloadSize, (i + 1) * MaxPayloadSize); - | websocket.send("1" + payload); - | } - | - | websocket.send("0" + msg.substring(frags * MaxPayloadSize)); - | } - | - | function recvImpl(recvCB) { - | var recvBuf = ""; - | - | return function(evt) { - | var newData = recvBuf + evt.data.substring(1); - | if (evt.data.charAt(0) == "0") { - | recvBuf = ""; - | recvCB(newData); - | } else if (evt.data.charAt(0) == "1") { - | recvBuf = newData; - | } else { - | throw new Error("Bad fragmentation flag in " + evt.data); - | } - | }; - | } - | - | window.scalajsCom = { - | init: function(recvCB) { - | if (websocket !== null) throw new Error("Com already open"); - | - | outMsgBuf = []; - | - | websocket = new WebSocket("ws://localhost:$serverPort"); - | - | websocket.onopen = function(evt) { - | for (var i = 0; i < outMsgBuf.length; ++i) - | sendImpl(outMsgBuf[i]); - | outMsgBuf = null; - | }; - | websocket.onclose = function(evt) { - | websocket = null; - | if (outMsgBuf !== null) - | throw new Error("WebSocket closed before being opened: " + evt); - | ${maybeExit(0)} - | }; - | websocket.onmessage = recvImpl(recvCB); - | websocket.onerror = function(evt) { - | websocket = null; - | throw new Error("Websocket failed: " + evt); - | }; - | - | // Take over responsibility to auto exit - | window.callPhantom({ - | action: 'setAutoExit', - | autoExit: false - | }); - | }, - | send: function(msg) { - | if (websocket === null) - | return; // we are closed already. ignore message - | - | if (outMsgBuf !== null) - | outMsgBuf.push(msg); - | else - | sendImpl(msg); - | }, - | close: function() { - | if (websocket === null) - | return; // we are closed already. all is well. - | - | if (outMsgBuf !== null) - | // Reschedule ourselves to give onopen a chance to kick in - | window.setTimeout(window.scalajsCom.close, 10); - | else - | websocket.close(); - | } - | } - |}).call(this);""".stripMargin - - new MemVirtualJSFile("comSetup.js").withContent(code) - } - - override def start(logger: Logger, console: JSConsole): Future[Unit] = { - setupLoggerAndConsole(logger, console) - mgr.start() - startExternalJSEnv() - future - } - - def send(msg: String): Unit = synchronized { - if (awaitConnection()) { - val fragParts = msg.length / MaxCharPayloadSize - - for (i <- 0 until fragParts) { - val payload = msg.substring( - i * MaxCharPayloadSize, (i + 1) * MaxCharPayloadSize) - mgr.sendMessage("1" + payload) - } - - mgr.sendMessage("0" + msg.substring(fragParts * MaxCharPayloadSize)) - } - } - - def receive(timeout: Duration): String = synchronized { - if (recvBuf.isEmpty && !awaitConnection()) - throw new ComJSEnv.ComClosedException("Phantom.js isn't connected") - - val deadline = OptDeadline(timeout) - - @tailrec - def loop(): String = { - /* The fragments are accumulated in an instance-wide buffer in case - * receiving a non-first fragment times out. - */ - val frag = receiveFrag(deadline) - fragmentsBuf ++= frag.substring(1) - - if (frag(0) == '0') { - val result = fragmentsBuf.result() - fragmentsBuf.clear() - result - } else if (frag(0) == '1') { - loop() - } else { - throw new AssertionError("Bad fragmentation flag in " + frag) - } - } - - try { - loop() - } catch { - case e: Throwable if !e.isInstanceOf[TimeoutException] => - fragmentsBuf.clear() // the protocol is broken, so discard the buffer - throw e - } - } - - private def receiveFrag(deadline: OptDeadline): String = { - while (recvBuf.isEmpty && !mgr.isClosed && !deadline.isOverdue) - wait(deadline.millisLeft) - - if (recvBuf.isEmpty) { - if (mgr.isClosed) - throw new ComJSEnv.ComClosedException - else - throw new TimeoutException("Timeout expired") - } - - recvBuf.dequeue() - } - - def close(): Unit = mgr.stop() - - /** Waits until the JS VM has established a connection, or the VM - * terminated. Returns true if a connection was established. - */ - private def awaitConnection(): Boolean = { - while (!mgr.isConnected && !mgr.isClosed && isRunning) - wait(10000) - if (!mgr.isConnected && !mgr.isClosed && isRunning) - throw new TimeoutException( - "The PhantomJS WebSocket client took too long to connect") - - mgr.isConnected - } - - override protected def initFiles(): Seq[VirtualJSFile] = - super.initFiles :+ comSetup - } - - protected trait AbstractPhantomRunner extends AbstractExtRunner { - - protected[this] val codeCache = new VirtualFileMaterializer - - override protected def getVMArgs() = - // Add launcher file to arguments - additionalArgs :+ createTmpLauncherFile().getAbsolutePath - - /** In phantom.js, we include JS using HTML */ - override protected def writeJSFile(file: VirtualJSFile, writer: Writer) = { - val realFile = codeCache.materialize(file) - val fname = htmlEscape(fixFileURI(realFile.toURI).toASCIIString) - writer.write( - s"""""" + "\n") - } - - /** - * PhantomJS doesn't support Function.prototype.bind. We polyfill it. - * https://github.com/ariya/phantomjs/issues/10522 - */ - override protected def initFiles(): Seq[VirtualJSFile] = Seq( - // scalastyle:off line.size.limit - new MemVirtualJSFile("bindPolyfill.js").withContent( - """ - |// Polyfill for Function.bind from Facebook react: - |// https://github.com/facebook/react/blob/3dc10749080a460e48bee46d769763ec7191ac76/src/test/phantomjs-shims.js - |// Originally licensed under Apache 2.0 - |(function() { - | - | var Ap = Array.prototype; - | var slice = Ap.slice; - | var Fp = Function.prototype; - | - | if (!Fp.bind) { - | // PhantomJS doesn't support Function.prototype.bind natively, so - | // polyfill it whenever this module is required. - | Fp.bind = function(context) { - | var func = this; - | var args = slice.call(arguments, 1); - | - | function bound() { - | var invokedAsConstructor = func.prototype && (this instanceof func); - | return func.apply( - | // Ignore the context parameter when invoking the bound function - | // as a constructor. Note that this includes not only constructor - | // invocations using the new keyword but also calls to base class - | // constructors such as BaseClass.call(this, ...) or super(...). - | !invokedAsConstructor && context || this, - | args.concat(slice.call(arguments)) - | ); - | } - | - | // The bound function must share the .prototype of the unbound - | // function so that any object created by one constructor will count - | // as an instance of both constructors. - | bound.prototype = func.prototype; - | - | return bound; - | }; - | } - | - |})(); - |""".stripMargin - ), - new MemVirtualJSFile("scalaJSEnvInfo.js").withContent( - """ - |__ScalaJSEnv = { - | exitFunction: function(status) { - | window.callPhantom({ - | action: 'exit', - | returnValue: status | 0 - | }); - | } - |}; - """.stripMargin - ) - // scalastyle:on line.size.limit - ) - - protected def writeWebpageLauncher(out: Writer): Unit = { - out.write(s""" - Phantom.js Launcher - """) - sendJS(getJSFiles(), out) - out.write(s"\n\n\n") - } - - protected def createTmpLauncherFile(): File = { - val webF = createTmpWebpage() - - val launcherTmpF = File.createTempFile("phantomjs-launcher", ".js") - launcherTmpF.deleteOnExit() - - val out = new FileWriter(launcherTmpF) - - try { - out.write( - s"""// Scala.js Phantom.js launcher - |var page = require('webpage').create(); - |var url = "${escapeJS(fixFileURI(webF.toURI).toASCIIString)}"; - |var autoExit = $autoExit; - |page.onConsoleMessage = function(msg) { - | console.log(msg); - |}; - |page.onError = function(msg, trace) { - | console.error(msg); - | if (trace && trace.length) { - | console.error(''); - | trace.forEach(function(t) { - | console.error(' ' + t.file + ':' + t.line + - | (t.function ? ' (in function "' + t.function +'")' : '')); - | }); - | } - | - | phantom.exit(2); - |}; - |page.onCallback = function(data) { - | if (!data.action) { - | console.error('Called callback without action'); - | phantom.exit(3); - | } else if (data.action === 'exit') { - | phantom.exit(data.returnValue || 0); - | } else if (data.action === 'setAutoExit') { - | if (typeof(data.autoExit) === 'boolean') - | autoExit = data.autoExit; - | else - | autoExit = true; - | } else { - | console.error('Unknown callback action ' + data.action); - | phantom.exit(4); - | } - |}; - |page.open(url, function (status) { - | if (autoExit || status !== 'success') - | phantom.exit(status !== 'success'); - |}); - |""".stripMargin) - } finally { - out.close() - } - - logger.debug( - "PhantomJS using launcher at: " + launcherTmpF.getAbsolutePath()) - - launcherTmpF - } - - protected def createTmpWebpage(): File = { - val webTmpF = File.createTempFile("phantomjs-launcher-webpage", ".html") - webTmpF.deleteOnExit() - - val out = new BufferedWriter( - new OutputStreamWriter(new FileOutputStream(webTmpF), "UTF-8")) - - try { - writeWebpageLauncher(out) - } finally { - out.close() - } - - logger.debug( - "PhantomJS using webpage launcher at: " + webTmpF.getAbsolutePath()) - - webTmpF - } - } - - protected def htmlEscape(str: String): String = str.flatMap { - case '<' => "<" - case '>' => ">" - case '"' => """ - case '&' => "&" - case c => c :: Nil - } - -} - -private object PhantomJSEnv { - private final val MaxByteMessageSize = 32768 // 32 KB - private final val MaxCharMessageSize = MaxByteMessageSize / 2 // 2B per char - private final val MaxCharPayloadSize = MaxCharMessageSize - 1 // frag flag -} diff --git a/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJettyClassLoader.scala b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJettyClassLoader.scala deleted file mode 100644 index 6b9ab89628..0000000000 --- a/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJettyClassLoader.scala +++ /dev/null @@ -1,71 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ PhantomJS support for Scala.js ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ https://www.scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - -package org.scalajs.jsenv.phantomjs - -import org.scalajs.core.tools.io.IO - -/** A special [[java.lang.ClassLoader]] to load the Jetty 8 dependency of - * [[PhantomJSEnv]] in a private space. - * - * It loads everything that belongs to `JettyWebsocketManager` itself (while - * retrieving the requested class file from its parent. - * For all other classes, it first tries to load them from `jettyLoader`, - * which should only contain the Jetty 8 classpath. - * If this fails, it delegates to its parent. - * - * The rationale is, that `JettyWebsocketManager` and its dependees can use - * the classes on the Jetty 8 classpath, while they remain hidden from the rest - * of the Java world. This allows to load another version of Jetty in the same - * JVM for the rest of the project. - */ -final class PhantomJettyClassLoader(jettyLoader: ClassLoader, - parent: ClassLoader) extends ClassLoader(parent) { - - def this(loader: ClassLoader) = - this(loader, ClassLoader.getSystemClassLoader()) - - /** Classes needed to bridge private jetty classpath and public PhantomJS - * Basically everything defined in JettyWebsocketManager. - */ - private val bridgeClasses = Set( - "org.scalajs.jsenv.phantomjs.JettyWebsocketManager", - "org.scalajs.jsenv.phantomjs.JettyWebsocketManager$WSLogger", - "org.scalajs.jsenv.phantomjs.JettyWebsocketManager$ComWebSocketListener", - "org.scalajs.jsenv.phantomjs.JettyWebsocketManager$$anon$1", - "org.scalajs.jsenv.phantomjs.JettyWebsocketManager$$anon$2" - ) - - override protected def loadClass(name: String, resolve: Boolean): Class[_] = { - if (bridgeClasses.contains(name)) { - // Load bridgeClasses manually since they must be associated to this - // class loader, rather than the parent class loader in order to find the - // jetty classes - - // First check if we have loaded it already - Option(findLoadedClass(name)) getOrElse { - val wsManager = - parent.getResourceAsStream(name.replace('.', '/') + ".class") - - if (wsManager == null) { - throw new ClassNotFoundException(name) - } else { - val buf = IO.readInputStreamToByteArray(wsManager) - defineClass(name, buf, 0, buf.length) - } - } - } else { - try { - jettyLoader.loadClass(name) - } catch { - case _: ClassNotFoundException => - super.loadClass(name, resolve) - } - } - } -} diff --git a/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnv.scala b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnv.scala deleted file mode 100644 index 8da4e3fd03..0000000000 --- a/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnv.scala +++ /dev/null @@ -1,195 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ PhantomJS support for Scala.js ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ https://www.scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - -package org.scalajs.jsenv.phantomjs - -import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.logging.Logger - -import org.scalajs.jsenv._ - -import scala.concurrent.{Future, Promise, ExecutionContext} -import scala.concurrent.duration.Duration -import scala.collection.mutable -import scala.annotation.tailrec -import scala.util.control.NonFatal -import scala.util.{Try, Failure, Success} - -/** A RetryingComJSEnv allows to automatically retry if a call to the underlying - * ComJSRunner fails. - * - * While it protects the JVM side from observing state that differs inbetween - * runs that have been retried, it assumes that the executed JavaScript code - * does not have side-effects other than the ones visible through the channel - * (e.g. writing to a file). It is the users responsibility to ensure this - * property. - * - * No retrying is performed for synchronous, or normal asynchronous runs. - * - * Although `RetryingComJSEnv` is agnostic of the underlying JS env, and is - * therefore not tied to PhantomJS, it is most often used to compensate for - * flakiness effects of PhantomJS. - */ -final class RetryingComJSEnv(val baseEnv: ComJSEnv, - val maxRetries: Int) extends ComJSEnv { - - def this(baseEnv: ComJSEnv) = this(baseEnv, 5) - - def name: String = s"Retrying ${baseEnv.name}" - - def jsRunner(files: Seq[VirtualJSFile]): JSRunner = - baseEnv.jsRunner(files) - - def asyncRunner(files: Seq[VirtualJSFile]): AsyncJSRunner = - baseEnv.asyncRunner(files) - - def comRunner(files: Seq[VirtualJSFile]): ComJSRunner = - new RetryingComJSRunner(files) - - /** Hack to work around abstract override in ComJSRunner */ - private trait DummyJSRunner { - def stop(): Unit = () - } - - private class RetryingComJSRunner(files: Seq[VirtualJSFile]) - extends DummyJSRunner with ComJSRunner { - - private[this] val promise = Promise[Unit] - - private[this] var curRunner = baseEnv.comRunner(files) - - private[this] var hasReceived = false - private[this] var retryCount = 0 - - private[this] val log = mutable.Buffer.empty[LogItem] - - private[this] var _logger: Logger = _ - private[this] var _console: JSConsole = _ - - def future: Future[Unit] = promise.future - - def start(logger: Logger, console: JSConsole): Future[Unit] = { - require(log.isEmpty, "start() may only be called once") - - _logger = logger - _console = console - - logAndDo(Start) - future - } - - override def stop(): Unit = { - require(log.nonEmpty, "start() must have been called") - close() - logAndDo(Stop) - } - - def send(msg: String): Unit = { - require(log.nonEmpty, "start() must have been called") - logAndDo(Send(msg)) - } - - def receive(timeout: Duration): String = { - @tailrec - def recLoop(): String = { - // Need to use Try for tailrec - Try { - val result = curRunner.receive(timeout) - // At this point, we are sending state to the JVM, we cannot retry - // after this. - hasReceived = true - result - } match { - case Failure(t) => - retry(t) - recLoop() - case Success(v) => v - } - } - - recLoop() - } - - def close(): Unit = { - require(log.nonEmpty, "start() must have been called") - logAndDo(Close) - } - - @tailrec - private final def retry(cause: Throwable): Unit = { - retryCount += 1 - - // Accesses to promise and swaps in the curRunner must be synchronized - synchronized { - if (hasReceived || retryCount > maxRetries || promise.isCompleted) - throw cause - - _logger.warn("Retrying to launch a " + baseEnv.getClass.getName + - " after " + cause.toString) - - val oldRunner = curRunner - - curRunner = try { - baseEnv.comRunner(files) - } catch { - case NonFatal(t) => - _logger.error("Could not retry: creating an new runner failed: " + - t.toString) - throw cause - } - - try oldRunner.stop() // just in case - catch { - case NonFatal(t) => // ignore - } - } - - // Replay the whole log - // Need to use Try for tailrec - Try(log.foreach(executeTask)) match { - case Failure(t) => retry(t) - case _ => - } - } - - private def logAndDo(task: LogItem) = { - log += task - try executeTask(task) - catch { - case NonFatal(t) => retry(t) - } - } - - private def executeTask(task: LogItem) = task match { - case Start => - import ExecutionContext.Implicits.global - val runner = curRunner - runner.start(_logger, _console) onComplete { result => - // access to curRunner and promise must be synchronized - synchronized { - if (curRunner eq runner) - promise.complete(result) - } - } - case Send(msg) => - curRunner.send(msg) - case Stop => - curRunner.stop() - case Close => - curRunner.close() - } - - private sealed trait LogItem - private case object Start extends LogItem - private case class Send(msg: String) extends LogItem - private case object Stop extends LogItem - private case object Close extends LogItem - - } - -} diff --git a/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketListener.scala b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketListener.scala deleted file mode 100644 index a05f76407d..0000000000 --- a/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketListener.scala +++ /dev/null @@ -1,18 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ PhantomJS support for Scala.js ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ https://www.scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - -package org.scalajs.jsenv.phantomjs - -private[phantomjs] trait WebsocketListener { - def onRunning(): Unit - def onOpen(): Unit - def onClose(): Unit - def onMessage(msg: String): Unit - - def log(msg: String): Unit -} diff --git a/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketManager.scala b/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketManager.scala deleted file mode 100644 index 489c4b4201..0000000000 --- a/phantomjs-env/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketManager.scala +++ /dev/null @@ -1,18 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ PhantomJS support for Scala.js ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ https://www.scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - -package org.scalajs.jsenv.phantomjs - -private[phantomjs] trait WebsocketManager { - def start(): Unit - def stop(): Unit - def sendMessage(msg: String): Unit - def localPort: Int - def isConnected: Boolean - def isClosed: Boolean -} diff --git a/phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/PhantomJSTest.scala b/phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/PhantomJSTest.scala deleted file mode 100644 index c3894e1025..0000000000 --- a/phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/PhantomJSTest.scala +++ /dev/null @@ -1,7 +0,0 @@ -package org.scalajs.jsenv.phantomjs - -import org.scalajs.jsenv.test._ - -class PhantomJSTest extends JSEnvTest with ComTests { - protected def newJSEnv: PhantomJSEnv = new PhantomJSEnv -} diff --git a/phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/PhantomJSWithCustomInitFilesTest.scala b/phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/PhantomJSWithCustomInitFilesTest.scala deleted file mode 100644 index 17716457a3..0000000000 --- a/phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/PhantomJSWithCustomInitFilesTest.scala +++ /dev/null @@ -1,9 +0,0 @@ -package org.scalajs.jsenv.phantomjs - -import org.scalajs.jsenv.test._ - -class PhantomJSWithCustomInitFilesTest extends CustomInitFilesTest { - protected def newJSEnv: PhantomJSEnv = new PhantomJSEnv { - override def customInitFiles() = makeCustomInitFiles() - } -} diff --git a/phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnvTest.scala b/phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnvTest.scala deleted file mode 100644 index 2161b6118c..0000000000 --- a/phantomjs-env/src/test/scala/org/scalajs/jsenv/phantomjs/RetryingComJSEnvTest.scala +++ /dev/null @@ -1,92 +0,0 @@ -package org.scalajs.jsenv.phantomjs - -import org.scalajs.core.tools.io.VirtualJSFile -import org.scalajs.core.tools.logging._ - -import org.scalajs.jsenv.nodejs.NodeJSEnv -import org.scalajs.jsenv.{ComJSRunner, JSConsole, _} -import org.scalajs.jsenv.test._ - -import scala.concurrent.Future -import scala.concurrent.duration.Duration - -class RetryingComJSEnvTest extends JSEnvTest with ComTests { - - private final val maxFails = 5 - - // Don't log anything here - override protected def start(runner: AsyncJSRunner): Future[Unit] = { - runner.start(NullLogger, ConsoleJSConsole) - } - - protected def newJSEnv: RetryingComJSEnv = - new RetryingComJSEnv(new FailingEnv(new NodeJSEnv), maxFails) - - private final class FailingEnv(baseEnv: ComJSEnv) extends ComJSEnv { - def name: String = s"FailingJSEnv of ${baseEnv.name}" - - private[this] var fails = 0 - private[this] var failedReceive = false - - def jsRunner(files: Seq[VirtualJSFile]): JSRunner = - baseEnv.jsRunner(files) - - def asyncRunner(files: Seq[VirtualJSFile]): AsyncJSRunner = - baseEnv.asyncRunner(files) - - def comRunner(files: Seq[VirtualJSFile]): ComJSRunner = - new FailingComJSRunner(baseEnv.comRunner(files)) - - /** Hack to work around abstract override in ComJSRunner */ - private trait DummyJSRunner { - def stop(): Unit = () - } - - private class FailingComJSRunner(baseRunner: ComJSRunner) - extends DummyJSRunner with ComJSRunner { - - def future: Future[Unit] = baseRunner.future - - def send(msg: String): Unit = { - maybeFail() - baseRunner.send(msg) - } - - def receive(timeout: Duration): String = { - if (shouldFail) { - failedReceive = true - fail() - } - baseRunner.receive(timeout) - } - - def start(logger: Logger, console: JSConsole): Future[Unit] = { - maybeFail() - baseRunner.start(logger, console) - } - - override def stop(): Unit = { - maybeFail() - baseRunner.stop() - } - - def close(): Unit = { - maybeFail() - baseRunner.close() - } - - private def shouldFail = !failedReceive && fails < maxFails - - private def maybeFail() = { - if (shouldFail) - fail() - } - - private def fail() = { - fails += 1 - sys.error("Dummy fail for testing purposes") - } - } - } - -} diff --git a/phantomjs-sbt-plugin/src/main/scala/org/scalajs/jsenv/phantomjs/sbtplugin/PhantomJSEnvPlugin.scala b/phantomjs-sbt-plugin/src/main/scala/org/scalajs/jsenv/phantomjs/sbtplugin/PhantomJSEnvPlugin.scala deleted file mode 100644 index 363aab6d09..0000000000 --- a/phantomjs-sbt-plugin/src/main/scala/org/scalajs/jsenv/phantomjs/sbtplugin/PhantomJSEnvPlugin.scala +++ /dev/null @@ -1,102 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ PhantomJS support for Scala.js ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ https://www.scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - -package org.scalajs.jsenv.phantomjs.sbtplugin - -import sbt._ -import sbt.Keys._ - -import java.net.URLClassLoader - -import org.scalajs.sbtplugin.ScalaJSPlugin -import org.scalajs.sbtplugin.ScalaJSPlugin.autoImport._ - -import org.scalajs.jsenv._ -import org.scalajs.jsenv.phantomjs._ - -/** An sbt plugin that simplifies the setup of [[PhantomJSEnv]]s. - * - * There is no need to use `enablePlugins(PhantomJSEnvPlugin)`, as this plugin - * is automatically triggered by Scala.js projects. - * - * Usually, one only needs to use the - * [[PhantomJSEnvPlugin.autoImport.PhantomJSEnv]] method. - */ -object PhantomJSEnvPlugin extends AutoPlugin { - override def requires: Plugins = ScalaJSPlugin - override def trigger: PluginTrigger = allRequirements - - object autoImport { - /** Class loader for PhantomJSEnv, used to load jetty8. - * - * Usually, you should not need to use `scalaJSPhantomJSClassLoader` - * directly. Instead, use the `PhantomJSEnv()` function. - */ - val scalaJSPhantomJSClassLoader: TaskKey[ClassLoader] = { - TaskKey[ClassLoader]( - "scalaJSPhantomJSClassLoader", - "Private class loader to load jetty8 without polluting the " + - "classpath. Only use this as the `jettyClassLoader` argument of " + - "a PhantomJSEnv.", - KeyRanks.Invisible) - } - - /** An [[sbt.Def.Initialize Def.Initialize]] for a [[PhantomJSEnv]]. - * - * Use this to specify in your build that you would like to run and/or - * test a project 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(executable, args, env, autoExit, loader) - } - } - - import autoImport._ - - val phantomJSJettyModules: Seq[ModuleID] = Seq( - "org.eclipse.jetty" % "jetty-websocket" % "8.1.16.v20140903", - "org.eclipse.jetty" % "jetty-server" % "8.1.16.v20140903" - ) - - override def projectSettings: Seq[Setting[_]] = Seq( - /* Depend on jetty artifacts in a 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) - } - ) - -} diff --git a/project/Build.scala b/project/Build.scala index 98e790043d..8acbd9dc92 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -23,9 +23,6 @@ import org.scalajs.sbtplugin._ import org.scalajs.jsenv.JSEnv import org.scalajs.jsenv.nodejs.{NodeJSEnv, JSDOMNodeJSEnv} -import org.scalajs.jsenv.phantomjs.sbtplugin.PhantomJSEnvPlugin -import org.scalajs.jsenv.phantomjs.{PhantomJSEnv, RetryingComJSEnv} - import ScalaJSPlugin.autoImport._ import ExternalCompile.scalaJSExternalCompileSettings import Loggers._ @@ -49,7 +46,7 @@ object ExposedValues extends AutoPlugin { } object MyScalaJSPlugin extends AutoPlugin { - override def requires: Plugins = ScalaJSPlugin && PhantomJSEnvPlugin + override def requires: Plugins = ScalaJSPlugin val isGeneratingEclipse = Properties.envOrElse("GENERATING_ECLIPSE", "false").toBoolean @@ -1170,41 +1167,6 @@ object Build { exportJars := true ) - // PhantomJS support - to be moved out of the core repository - - lazy val phantomJSEnv: Project = (project in file("phantomjs-env")).settings( - commonSettings, - publishSettings, - fatalWarningsSettings, - name := "scalajs-env-phantomjs", - libraryDependencies ++= - PhantomJSEnvPlugin.phantomJSJettyModules.map(_ % "provided"), - libraryDependencies += - "com.novocode" % "junit-interface" % "0.9" % "test" - ).dependsOn(jsEnvs, jsEnvsTestKit % "test") - - lazy val phantomJSEnvPlugin: Project = (project in file("phantomjs-sbt-plugin")).settings( - commonSettings, - publishIvySettings, - fatalWarningsSettings, - name := "sbt-scalajs-env-phantomjs", - sbtPlugin := true, - scalaBinaryVersion := - CrossVersion.binaryScalaVersion(scalaVersion.value), - - // Add API mappings for sbt (seems they don't export their API URL) - apiMappings ++= { - val deps = (externalDependencyClasspath in Compile).value - val sbtJars = deps filter { attributed => - val p = attributed.data.getPath - p.contains("/org.scala-sbt/") && p.endsWith(".jar") - } - val docUrl = - url(s"http://www.scala-sbt.org/${sbtVersion.value}/api/") - sbtJars.map(_.data -> docUrl).toMap - } - ).dependsOn(plugin, phantomJSEnv) - // Examples lazy val examples: Project = project.settings( @@ -1251,7 +1213,6 @@ object Build { Seq( testOptionTags := { - @tailrec def envTagsFor(env: JSEnv): Seq[String] = env match { case env: NodeJSEnv => val baseArgs = Seq("nodejs", "typedarray") @@ -1271,12 +1232,6 @@ object Build { case env: JSDOMNodeJSEnv => Seq("nodejs.jsdom", "typedarray") - case _: PhantomJSEnv => - Seq("phantomjs") - - case env: RetryingComJSEnv => - envTagsFor(env.baseEnv) - case _ => throw new AssertionError( s"Unknown JSEnv of class ${env.getClass.getName}: " + @@ -1392,7 +1347,7 @@ object Build { // We need to patch the system properties. scalaJSJavaSystemProperties in Test in testHtmlKey ~= { base => val unsupported = - Seq("nodejs", "nodejs.jsdom", "phantomjs", "source-maps") + Seq("nodejs", "nodejs.jsdom", "source-maps") val supported = Seq("typedarray", "browser") @@ -1523,37 +1478,6 @@ object Build { sourceFiles1 }, - /* Reduce the amount of tests on PhantomJS to avoid a crash. - * It seems we reached the limits of what PhantomJS can handle in terms - * of code mass. Since PhantomJS support is due to be moved to a - * separate repository in 1.0.0, the easiest way to fix this is to - * reduce the pressure on PhantomJS. We therefore remove the tests of - * java.math (BigInteger and BigDecimal) when running with PhantomJS. - * These tests are well isolated, and the less likely to have - * environmental differences. - * - * Note that `jsEnv` is never set from this Build, but it is set via - * the command-line in the CI matrix. - */ - sources in Test := { - def isPhantomJS(env: JSEnv): Boolean = env match { - case _: PhantomJSEnv => true - case env: RetryingComJSEnv => isPhantomJS(env.baseEnv) - case _ => false - } - - val sourceFiles = (sources in Test).value - if ((jsEnv in Test).?.value.exists(isPhantomJS)) { - sourceFiles.filter { f => - !f.getAbsolutePath - .replace('\\', '/') - .contains("/org/scalajs/testsuite/javalib/math/") - } - } else { - sourceFiles - } - }, - // Module initializers. Duplicated in toolsJS/test scalaJSModuleInitializers += { ModuleInitializer.mainMethod( diff --git a/project/build.sbt b/project/build.sbt index 2ff758b90d..f1e42470f3 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -17,10 +17,6 @@ libraryDependencies += "org.eclipse.jgit" % "org.eclipse.jgit.pgm" % "3.2.0.2013 libraryDependencies += "com.googlecode.json-simple" % "json-simple" % "1.1.1" exclude("junit", "junit") -libraryDependencies += "org.eclipse.jetty" % "jetty-websocket" % "8.1.16.v20140903" - -libraryDependencies += "org.eclipse.jetty" % "jetty-server" % "8.1.16.v20140903" - unmanagedSourceDirectories in Compile ++= { val root = baseDirectory.value.getParentFile @@ -30,9 +26,7 @@ unmanagedSourceDirectories in Compile ++= { root / "tools/jvm/src/main/scala", root / "js-envs/src/main/scala", root / "test-adapter/src/main/scala", - root / "sbt-plugin/src/main/scala", - root / "phantomjs-env/src/main/scala", - root / "phantomjs-sbt-plugin/src/main/scala" + root / "sbt-plugin/src/main/scala" ) } diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index 774951173a..6d13a50a46 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -101,15 +101,6 @@ lazy val withDOM = project.settings(baseSettings: _*). scalaJSUseMainModuleInitializer := true ) -lazy val jetty9 = project.settings(baseSettings: _*). - enablePlugins(ScalaJSPlugin). - settings( - name := "Scala.js sbt test with jetty9 on classpath", - // Use PhantomJS, allow cross domain requests - jsEnv := PhantomJSEnv(args = Seq("--web-security=no")).value, - Jetty9Test.runSetting - ) - lazy val testFramework = crossProject.crossType(CrossType.Pure). settings(versionSettings: _*). settings(name := "Dummy cross JS/JVM test framework"). diff --git a/sbt-plugin-test/project/Jetty9Test.scala b/sbt-plugin-test/project/Jetty9Test.scala deleted file mode 100644 index 031bda1546..0000000000 --- a/sbt-plugin-test/project/Jetty9Test.scala +++ /dev/null @@ -1,85 +0,0 @@ -import sbt._ -import Keys._ - -import org.scalajs.sbtplugin._ -import ScalaJSPlugin.autoImport._ -import Implicits._ - -import org.scalajs.jsenv._ -import org.scalajs.core.tools.io._ - -import org.eclipse.jetty.server._ -import org.eclipse.jetty.server.handler._ -import org.eclipse.jetty.util.component._ - -import java.io.File - -import scala.concurrent.duration._ - -object Jetty9Test { - - private val jettyPort = 23548 - - val runSetting = run <<= Def.inputTask { - val env = (jsEnv in Compile).value.asInstanceOf[ComJSEnv] - val files = (jsExecutionFiles in Compile).value - val jsConsole = scalaJSConsole.value - - val code = new MemVirtualJSFile("runner.js").withContent( - """ - scalajsCom.init(function(msg) { - var xhr = new XMLHttpRequest(); - xhr.open("GET", msg); - xhr.onload = (function() { - scalajsCom.send(xhr.responseText.trim()); - scalajsCom.close(); - }); - xhr.onerror = (function() { - scalajsCom.send("failed!"); - scalajsCom.close(); - }); - xhr.send(); - }); - """ - ) - - val runner = env.comRunner(files :+ code) - - runner.start(streams.value.log, jsConsole) - - val jetty = setupJetty((resourceDirectory in Compile).value) - - jetty.addLifeCycleListener(new AbstractLifeCycle.AbstractLifeCycleListener { - override def lifeCycleStarted(event: LifeCycle): Unit = { - try { - runner.send(s"http://localhost:$jettyPort/test.txt") - val msg = runner.receive() - val expected = "It works!" - if (msg != expected) - sys.error(s"""received "$msg" instead of "$expected"""") - } finally { - runner.close() - jetty.stop() - } - } - }) - - jetty.start() - runner.await(30.seconds) - jetty.join() - } - - private def setupJetty(dir: File): Server = { - val server = new Server(jettyPort) - - val resource_handler = new ResourceHandler() - resource_handler.setResourceBase(dir.getAbsolutePath) - - val handlers = new HandlerList() - handlers.setHandlers(Array(resource_handler, new DefaultHandler())) - server.setHandler(handlers) - - server - } - -} diff --git a/sbt-plugin-test/project/build.sbt b/sbt-plugin-test/project/build.sbt index 79c666d229..6626b7a52e 100644 --- a/sbt-plugin-test/project/build.sbt +++ b/sbt-plugin-test/project/build.sbt @@ -1,7 +1,2 @@ addSbtPlugin("org.scala-js" % "sbt-scalajs" % org.scalajs.core.ir.ScalaJSVersions.current) - -addSbtPlugin("org.scala-js" % "sbt-scalajs-env-phantomjs" % - org.scalajs.core.ir.ScalaJSVersions.current) - -libraryDependencies += "org.eclipse.jetty" % "jetty-server" % "9.2.3.v20140905" diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala index 28c4c5ce08..e93a44b675 100644 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala +++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala @@ -35,7 +35,6 @@ object Platform { def executingInNodeJS: Boolean = sysProp("nodejs") def executingInNodeJSOnJSDOM: Boolean = sysProp("nodejs.jsdom") - def executingInPhantomJS: Boolean = sysProp("phantomjs") def executingInBrowser: Boolean = sysProp("browser") def typedArrays: Boolean = sysProp("typedarray") def sourceMaps: Boolean = sysProp("source-maps") diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/IntJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/IntJSTest.scala index 94c3fcba54..1bd89512e7 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/IntJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/IntJSTest.scala @@ -29,8 +29,6 @@ class IntJSTest { final val AlmostMaxVal = Int.MaxValue - 36 @Test def `should_support_%`(): Unit = { - assumeFalse("Assumed not executing in PhantomJS", executingInPhantomJS) // see #593 - def test(a: Int, b: Int, expected: Int): Unit = assertEquals(expected, a % b) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala index dec7cb79c0..5cd5ab306f 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala @@ -356,34 +356,28 @@ class InteroperabilityTest { val keys = js.Dynamic.global.Object.keys val undef = js.undefined - if (!executingInPhantomJS) - assertEquals(1, keys(obj.simple(1)).length) + assertEquals(1, keys(obj.simple(1)).length) assertEquals(1, obj.simple(1)("0")) - if (!executingInPhantomJS) - assertEquals(2, keys(obj.simple(1, 5)).length) + assertEquals(2, keys(obj.simple(1, 5)).length) assertEquals(1, obj.simple(1, 5)("0")) assertEquals(5, obj.simple(1, 5)("1")) - if (!executingInPhantomJS) - assertEquals(2, keys(obj.named(y = 5)).length) + assertEquals(2, keys(obj.named(y = 5)).length) assertEquals(undef, obj.named(y = 5)("0")) assertEquals(5, obj.named(y = 5)("1")) - if (!executingInPhantomJS) - assertEquals(1, keys(obj.named(x = 5)).length) + assertEquals(1, keys(obj.named(x = 5)).length) assertEquals(5, obj.named(x = 5)("0")) - if (!executingInPhantomJS) - assertEquals(5, keys(obj.multi()(1,2,3,4)()).length) + assertEquals(5, keys(obj.multi()(1,2,3,4)()).length) assertEquals(undef, obj.multi()(1,2,3,4)()("0")) assertEquals(1, obj.multi()(1,2,3,4)()("1")) assertEquals(2, obj.multi()(1,2,3,4)()("2")) assertEquals(3, obj.multi()(1,2,3,4)()("3")) assertEquals(4, obj.multi()(1,2,3,4)()("4")) - if (!executingInPhantomJS) - assertEquals(2, keys(obj.multi(2)()(5)).length) + assertEquals(2, keys(obj.multi(2)()(5)).length) assertEquals(2, obj.multi(2)()(5)("0")) assertEquals(5, obj.multi(2)()(5)("1")) } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala index 6e825b7c63..1c85e3478b 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala @@ -106,28 +106,23 @@ class SystemJSTest { val inBrowser = get("scalajs.browser") == "true" val inNode = get("scalajs.nodejs") == "true" val inNodeWithJSDOM = get("scalajs.nodejs.jsdom") == "true" - val inPhantomJS = get("scalajs.phantomjs") == "true" if (inBrowser) { assertFalse(js.isUndefined(js.Dynamic.global.window)) - assertFalse(inNode || inNodeWithJSDOM || inPhantomJS) + assertFalse(inNode || inNodeWithJSDOM) } else if (inNode) { val process = js.Dynamic.global.process assertFalse(js.isUndefined(process)) - assertFalse(inBrowser || inNodeWithJSDOM || inPhantomJS) + assertFalse(inBrowser || inNodeWithJSDOM) } else if (inNodeWithJSDOM) { val window = js.Dynamic.global.window assertFalse(js.isUndefined(window)) - assertFalse(inBrowser || inNode || inPhantomJS) - } else if (inPhantomJS) { - assertFalse(js.isUndefined(js.Dynamic.global.callPhantom)) - assertFalse(inBrowser || inNode || inNodeWithJSDOM) + assertFalse(inBrowser || inNode) } else { fail("No known platform tag found.") } assertEquals(inBrowser, Platform.executingInBrowser) assertEquals(inNode, Platform.executingInNodeJS) assertEquals(inNodeWithJSDOM, Platform.executingInNodeJSOnJSDOM) - assertEquals(inPhantomJS, Platform.executingInPhantomJS) val typedArrays = get("scalajs.typedarray") == "true" assertEquals(typedArrays, Platform.typedArrays) diff --git a/test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala b/test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala index 8df9397ae8..163c87e3f6 100644 --- a/test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala +++ b/test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala @@ -22,7 +22,6 @@ object Platform { def executingInNodeJS: Boolean = false def executingInNodeJSOnJSDOM: Boolean = false - def executingInPhantomJS: Boolean = false def typedArrays: Boolean = false def sourceMaps: Boolean = false diff --git 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 index ea5d21c0bd..3d0e35676e 100644 --- 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 @@ -5,7 +5,6 @@ import org.junit.Assert._ import org.junit.Test import org.scalajs.testsuite.utils.AssertThrows._ -import org.scalajs.testsuite.utils.Platform._ class MathTestOnJDK8 { @@ -257,9 +256,7 @@ class MathTestOnJDK8 { expectThrows(classOf[ArithmeticException], Math.floorDiv(n, 0)) } - @Test def floorMod() = { - assumeFalse("Assumed not executing in PhantomJS", executingInPhantomJS) // crashes otherwise, see #593 - + @Test def floorMod(): Unit = { assertEquals(0, Math.floorMod(0, 1)) assertEquals(0, Math.floorMod(0, -1)) assertEquals(0, Math.floorMod(1, 1)) From 52edd40d242a8a2cbc7083d8e0c38a3062734ba0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 23 May 2017 11:20:13 +0200 Subject: [PATCH 0268/2665] Fix two quadratic behaviors of fresh name management in the optimizer. There were two operations related to fresh names that were O(n) where n is the number of generated fresh names. Since those operations are called O(m) times, where m is the size of the generated code, this yielded overall quadratic time. The first one was fresh name generation itself. The i'th call of `freshLocalName("foo")` (for a given `foo`) would try `foo`, then `foo$1`, then `foo$2`, etc. until `foo$i`, which is O(i). We solve this by remembering what was the last `i` we had to jump to for `foo`, so that we can directly start with that one on the next call. This gives an essentially constant time algorithm. The second one was during snapshotting of the used names when starting a new optimistic branch in `tryOrRollback`. To solve this, we use persistent data structures, i.e., a `var` of type `Map` instead of a `val` of type `mutable.Map`, so that snapshotting is constant time. Together, those fixes bring the pathological case of #2943 from 20 minutes down to 3 minutes. --- project/BinaryIncompatibilities.scala | 10 +- .../frontend/optimizer/OptimizerCore.scala | 104 +++++++++++------- 2 files changed, 76 insertions(+), 38 deletions(-) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 3c841e96d6..76024a4386 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -8,7 +8,15 @@ object BinaryIncompatibilities { val Tools = Seq( // private[emitter], not an issue ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSGen.this") + "org.scalajs.core.tools.linker.backend.emitter.JSGen.this"), + + // private[optimizer], not an issue + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#RollbackException.this"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#RollbackException.savedUsedLabelNames"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#RollbackException.savedUsedLocalNames") ) val JSEnvs = Seq( diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index a0fcc7ea45..33b9856ddf 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -73,10 +73,12 @@ private[optimizer] abstract class OptimizerCore( */ protected def tryNewInlineableClass(className: String): Option[RecordValue] - /** Used local names and whether they are mutable */ - private val usedLocalNames = mutable.Map.empty[String, Boolean] + private val localNameAllocator: FreshNameAllocator = new FreshNameAllocator - private val usedLabelNames = mutable.Set.empty[String] + /** An allocated local variable name is mutable iff it belongs to this set. */ + private var mutableLocalNames: Set[String] = Set.empty + + private val labelNameAllocator: FreshNameAllocator = new FreshNameAllocator /** A list of the States that have been allocated so far, and must be saved. * @@ -135,8 +137,9 @@ private[optimizer] abstract class OptimizerCore( transformIsolatedBody(Some(myself), thisType, params, resultType, body) } catch { case _: TooManyRollbacksException => - usedLocalNames.clear() - usedLabelNames.clear() + localNameAllocator.clear() + mutableLocalNames = Set.empty + labelNameAllocator.clear() statesInUse = Nil disableOptimisticOptimizations = true transformIsolatedBody(Some(myself), thisType, params, resultType, body) @@ -195,33 +198,17 @@ private[optimizer] abstract class OptimizerCore( } private def freshLocalName(base: String, mutable: Boolean): String = { - val result = freshNameGeneric(usedLocalNames.contains, base) - usedLocalNames += result -> mutable - result - } - - private def freshLabelName(base: String): String = { - val result = freshNameGeneric(usedLabelNames, base) - usedLabelNames += result + val result = localNameAllocator.freshName(base) + if (mutable) + mutableLocalNames += result result } - private val isReserved = isKeyword ++ Seq("arguments", "eval", "ScalaJS") - - private def freshNameGeneric(nameUsed: String => Boolean, - base: String): String = { - if (!nameUsed(base) && !isReserved(base)) { - base - } else { - var i = 1 - while (nameUsed(base + "$" + i)) - i += 1 - base + "$" + i - } - } + private def freshLabelName(base: String): String = + labelNameAllocator.freshName(base) // Just a helper to make the callsites more understandable - private def localIsMutable(name: String): Boolean = usedLocalNames(name) + private def localIsMutable(name: String): Boolean = mutableLocalNames(name) private def tryOrRollback(body: CancelFun => TailRec[Tree])( fallbackFun: () => TailRec[Tree]): TailRec[Tree] = { @@ -229,14 +216,16 @@ private[optimizer] abstract class OptimizerCore( fallbackFun() } else { val trampolineId = curTrampolineId - val savedUsedLocalNames = usedLocalNames.toMap - val savedUsedLabelNames = usedLabelNames.toSet + val localNameAllocatorSnapshot = localNameAllocator.snapshot() + val savedMutableLocalNames = mutableLocalNames + val labelNameAllocatorSnapshot = labelNameAllocator.snapshot() val savedStatesInUse = statesInUse val stateBackups = statesInUse.map(_.makeBackup()) body { () => - throw new RollbackException(trampolineId, savedUsedLocalNames, - savedUsedLabelNames, savedStatesInUse, stateBackups, fallbackFun) + throw new RollbackException(trampolineId, localNameAllocatorSnapshot, + savedMutableLocalNames, labelNameAllocatorSnapshot, savedStatesInUse, + stateBackups, fallbackFun) } } } @@ -4149,10 +4138,9 @@ private[optimizer] abstract class OptimizerCore( if (rollbacksCount > MaxRollbacksPerMethod) throw new TooManyRollbacksException - usedLocalNames.clear() - usedLocalNames ++= e.savedUsedLocalNames - usedLabelNames.clear() - usedLabelNames ++= e.savedUsedLabelNames + localNameAllocator.restore(e.localNameAllocatorSnapshot) + mutableLocalNames = e.savedMutableLocalNames + labelNameAllocator.restore(e.labelNameAllocatorSnapshot) statesInUse = e.savedStatesInUse e.stateBackups.foreach(_.restore()) @@ -4992,8 +4980,9 @@ private[optimizer] object OptimizerCore { } private class RollbackException(val trampolineId: Int, - val savedUsedLocalNames: Map[String, Boolean], - val savedUsedLabelNames: Set[String], + val localNameAllocatorSnapshot: FreshNameAllocator.Snapshot, + val savedMutableLocalNames: Set[String], + val labelNameAllocatorSnapshot: FreshNameAllocator.Snapshot, val savedStatesInUse: List[State], val stateBackups: List[StateBackup], val cont: () => TailRec[Tree]) extends ControlThrowable @@ -5002,4 +4991,45 @@ private[optimizer] object OptimizerCore { val attemptedInlining: List[AbstractMethodID], cause: Throwable ) extends Exception(exceptionMsg(myself, attemptedInlining, cause), cause) + final class FreshNameAllocator private ( + private var usedNamesToNextCounter: Map[String, Int]) { + import FreshNameAllocator._ + + def this() = this(FreshNameAllocator.InitialMap) + + def clear(): Unit = usedNamesToNextCounter = InitialMap + + def freshName(base: String): String = { + if (!usedNamesToNextCounter.contains(base)) { + usedNamesToNextCounter = usedNamesToNextCounter.updated(base, 1) + base + } else { + var i = usedNamesToNextCounter(base) + var result = base + "$" + i + while (usedNamesToNextCounter.contains(result)) { + i += 1 + result = base + "$" + i + } + usedNamesToNextCounter = + usedNamesToNextCounter.updated(base, i + 1).updated(result, 1) + result + } + } + + def snapshot(): Snapshot = new Snapshot(usedNamesToNextCounter) + + def restore(snapshot: Snapshot): Unit = + usedNamesToNextCounter = snapshot.usedNamesToNextCounter + } + + object FreshNameAllocator { + private val InitialMap = { + val isReserved = isKeyword ++ Seq("arguments", "eval", "ScalaJS") + isReserved.map(_ -> 1).toMap + } + + final class Snapshot private[FreshNameAllocator] ( + private[FreshNameAllocator] val usedNamesToNextCounter: Map[String, Int]) + } + } From d397b2f9fa04945e44a93818338c240df3768372 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 23 May 2017 14:10:52 +0200 Subject: [PATCH 0269/2665] Fix a quadratic behavior in state backup management in the optimizer. When starting a new optimistic branch in `tryOrRollback`, we used to make a backup of all `statesInUse`. This was O(n) in the number of states in use, giving an overall quadratic behavior. We fix this using an amortized approach, where making the backups is O(1), and restoring the backups is amortized O(1). Instead of maintaining a list of all states in use, and creating backups in `tryOrRollback`, we make a backup immediately upon chaning the value of a `State`. Backups are maintained in a list `stateBackupChain` of all the backups that were made so far. When we start a new optimistic branch, we take a snapshot of that list (in O(1)). Upon rollback, we restore all the backups made *since* that snapshot, which we can compute as the "list diff", i.e., the prefix of the current `stateBackupChain` that is followed by the snapshot version. Since we make one backup per state change, and since each backup is restored at most once, the state changes pay for making and restoring the corresponding backups, giving an amortized O(1) implementation. This brings the pathological case of #2943 from 3 minutes down to about 5 seconds. --- project/BinaryIncompatibilities.scala | 16 ++++- .../frontend/optimizer/OptimizerCore.scala | 71 +++++++++++-------- 2 files changed, 54 insertions(+), 33 deletions(-) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 76024a4386..91cdcd3507 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -11,12 +11,24 @@ object BinaryIncompatibilities { "org.scalajs.core.tools.linker.backend.emitter.JSGen.this"), // private[optimizer], not an issue - ProblemFilters.exclude[DirectMissingMethodProblem]( + ProblemFilters.exclude[IncompatibleMethTypeProblem]( "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#RollbackException.this"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#RollbackException.savedStatesInUse"), ProblemFilters.exclude[DirectMissingMethodProblem]( "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#RollbackException.savedUsedLabelNames"), ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#RollbackException.savedUsedLocalNames") + "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#RollbackException.savedUsedLocalNames"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#RollbackException.stateBackups"), + ProblemFilters.exclude[MissingTypesProblem]( + "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore$SimpleState"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#SimpleState.this"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#SimpleState.makeBackup"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore$State") ) val JSEnvs = Seq( diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index 33b9856ddf..a5b015b823 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -80,20 +80,22 @@ private[optimizer] abstract class OptimizerCore( private val labelNameAllocator: FreshNameAllocator = new FreshNameAllocator - /** A list of the States that have been allocated so far, and must be saved. + /** A list of backups for all updates done to States so far (excluding + * those done in rolled back optimistic branches). * - * This list only ever grows, even though, in theory, it will keep - * references to states that are not used anymore. - * This creates a "temporary memory leak", but the list is discarded when - * `optimize` terminates anyway because the whole OptimizerCore is discarded. - * It also means that RollbackException will save more state than strictly - * necessary, but it is not incorrect to do so. + * This list grows (from the head) every time the value of a `State` changes. + * Each time, a `StateBackup` is prepended with the previous value. * - * Manual "memory management" of this list has caused issues such as #1515 - * and #1843 in the past. So now we just let it grow in a "region-allocated" - * style of memory management. + * When starting an optimistic branch in `tryOrRollback`, we take a snapshot + * of the current chain of backups. When doing a rollback, we restore all + * the backups that have been added to the chain since the snapshot. We can + * do this by comparing the nodes of the chain with `eq`. + * + * Manipulations of this list are amortized O(1). The act of modifying the + * value of a `State` "pays for" a) making the backup and b) restoring the + * backup. Indeed, a backup is restored at most once. */ - private var statesInUse: List[State] = Nil + private var stateBackupChain: List[StateBackup] = Nil private var disableOptimisticOptimizations: Boolean = false private var rollbacksCount: Int = 0 @@ -140,7 +142,7 @@ private[optimizer] abstract class OptimizerCore( localNameAllocator.clear() mutableLocalNames = Set.empty labelNameAllocator.clear() - statesInUse = Nil + stateBackupChain = Nil disableOptimisticOptimizations = true transformIsolatedBody(Some(myself), thisType, params, resultType, body) } @@ -191,11 +193,11 @@ private[optimizer] abstract class OptimizerCore( } } - private def newSimpleState[A](initialValue: A): SimpleState[A] = { - val state = new SimpleState[A](initialValue) - statesInUse ::= state - state - } + private def newSimpleState[A](initialValue: A): SimpleState[A] = + new SimpleState[A](this, initialValue) + + private def addStateBackup(backup: StateBackup): Unit = + stateBackupChain ::= backup private def freshLocalName(base: String, mutable: Boolean): String = { val result = localNameAllocator.freshName(base) @@ -219,13 +221,12 @@ private[optimizer] abstract class OptimizerCore( val localNameAllocatorSnapshot = localNameAllocator.snapshot() val savedMutableLocalNames = mutableLocalNames val labelNameAllocatorSnapshot = labelNameAllocator.snapshot() - val savedStatesInUse = statesInUse - val stateBackups = statesInUse.map(_.makeBackup()) + val savedStateBackupChain = stateBackupChain body { () => throw new RollbackException(trampolineId, localNameAllocatorSnapshot, - savedMutableLocalNames, labelNameAllocatorSnapshot, savedStatesInUse, - stateBackups, fallbackFun) + savedMutableLocalNames, labelNameAllocatorSnapshot, + savedStateBackupChain, fallbackFun) } } } @@ -4141,8 +4142,14 @@ private[optimizer] abstract class OptimizerCore( localNameAllocator.restore(e.localNameAllocatorSnapshot) mutableLocalNames = e.savedMutableLocalNames labelNameAllocator.restore(e.labelNameAllocatorSnapshot) - statesInUse = e.savedStatesInUse - e.stateBackups.foreach(_.restore()) + + val savedStateBackupChain = e.savedStateBackupChain + var stateBackupsToRestore = stateBackupChain + while (stateBackupsToRestore ne savedStateBackupChain) { + stateBackupsToRestore.head.restore() + stateBackupsToRestore = stateBackupsToRestore.tail + } + stateBackupChain = savedStateBackupChain rec = e.cont } @@ -4778,16 +4785,19 @@ private[optimizer] object OptimizerCore { def restore(): Unit } - private trait State { - def makeBackup(): StateBackup - } + private class SimpleState[A](owner: OptimizerCore, private var _value: A) { + def value: A = _value + + def value_=(v: A): Unit = { + if (v.asInstanceOf[AnyRef] ne _value.asInstanceOf[AnyRef]) { + owner.addStateBackup(new Backup(_value)) + _value = v + } + } - private class SimpleState[A](var value: A) extends State { private class Backup(savedValue: A) extends StateBackup { override def restore(): Unit = value = savedValue } - - def makeBackup(): StateBackup = new Backup(value) } trait AbstractMethodID { @@ -4983,8 +4993,7 @@ private[optimizer] object OptimizerCore { val localNameAllocatorSnapshot: FreshNameAllocator.Snapshot, val savedMutableLocalNames: Set[String], val labelNameAllocatorSnapshot: FreshNameAllocator.Snapshot, - val savedStatesInUse: List[State], - val stateBackups: List[StateBackup], + val savedStateBackupChain: List[StateBackup], val cont: () => TailRec[Tree]) extends ControlThrowable class OptimizeException(val myself: AbstractMethodID, From 99d3cd988265e7ca4eb55e4c29365374d80befaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 23 May 2017 14:17:06 +0200 Subject: [PATCH 0270/2665] Fix #2943: Cap the maximum size of JS array to virtualize to 64. There is probably no good reason to virtualize JS arrays that are bigger than 64. There is also no good reason *not* to, but this change ensures that e0eeb70d79753a8d9c621ba34abb496d7406783d does not do any more "arbitrarily large" damage to the optimizer execution time. --- .../tools/linker/frontend/optimizer/OptimizerCore.scala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index a5b015b823..e1d3fc09d2 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -845,7 +845,11 @@ private[optimizer] abstract class OptimizerCore( usePreTransform = true)(cont) case JSArrayConstr(items) => - if (items.exists(_.isInstanceOf[JSSpread])) { + /* Trying to virtualize more than 64 items in a JS array is probably + * a bad idea, and will slow down the optimizer for no good reason. + * See for example #2943. + */ + if (items.size > 64 || items.exists(_.isInstanceOf[JSSpread])) { /* TODO This means spread in array constr does not compose under * this optimization. We could improve this with a * pretransformExprsOrSpreads() or something like that. From 646c9edb839dab9b1c26b0578ee40e26fe6d58f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 13 Apr 2017 14:34:17 +0200 Subject: [PATCH 0271/2665] Definitively remove the --jsoutput option of scalajsld. As the `jsDependencies` mechanism will be extracted, there is no coming back for scalajsld to support that option. --- .../main/scala/org/scalajs/cli/Scalajsld.scala | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala b/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala index 03f38c8557..17056cc636 100644 --- a/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala +++ b/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala @@ -32,7 +32,6 @@ object Scalajsld { cp: Seq[File] = Seq.empty, moduleInitializers: Seq[ModuleInitializer] = Seq.empty, output: File = null, - jsoutput: Boolean = false, semantics: Semantics = Semantics.Defaults, outputMode: OutputMode = OutputMode.ECMAScript51Isolated, moduleKind: ModuleKind = ModuleKind.NoModule, @@ -90,12 +89,6 @@ object Scalajsld { .required() .action { (x, c) => c.copy(output = x) } .text("Output file of linker (required)") - opt[File]("jsoutput") - .hidden() - .valueName("") - .abbr("jo") - .action { (_, c) => c.copy(jsoutput = true) } - .text("Deprecated: Does nothing but printing a warning") opt[Unit]('f', "fastOpt") .action { (_, c) => c.copy(noOpt = false, fullOpt = false) } .text("Optimize code (this is the default)") @@ -164,15 +157,6 @@ object Scalajsld { val irContainers = FileScalaJSIRContainer.fromClasspath(classpath) val moduleInitializers = options.moduleInitializers - // Warn if writing JS dependencies was requested. - if (options.jsoutput) { - Console.err.println( - "Support for the --jsoutput flag has been dropped. " + - "JS dependencies will not be written to disk. " + - "Comment on https://github.com/scala-js/scala-js/issues/2163 " + - "if you rely on this feature.") - } - val semantics = if (options.fullOpt) options.semantics.optimized else options.semantics From a29984386f6d42c7bdc377655def6c98a858454d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 12 May 2017 16:59:23 +0200 Subject: [PATCH 0272/2665] Remove the `checkScalaJSSemantics` feature. The implementation of that feature was piggybacked on the `JS_DEPENDENCIES` file maintained for the `jsDependencies` mechanism. As the latter will be extracted in a separate sbt plugin, the required semantics information will not be part of all Scala.js artifacts, and will therefore be bogus. This means that the `checkScalaJSSemantics` feature would not do its job correctly anyway, and it is better to remove it than to give a false sense of security. An alternative would be to store the relevant information in a separate file, but I do not believe it is worth it. Reasonable Scala.js libraries should never require compliant semantics anyway. Moreover, I have never had any feedback mentioning that feature, which probably means no one ever saw that feature in action, so it is useless. --- .../scala/tools/nsc/MainGenericRunner.scala | 15 ++++- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 4 -- .../sbtplugin/ScalaJSPluginInternal.scala | 21 +----- .../tools/jsdep/ComplianceRequirement.scala | 59 ----------------- .../scalajs/core/tools/jsdep/Exceptions.scala | 15 ----- .../tools/jsdep/JSDependencyManifest.scala | 21 ++---- .../core/tools/jsdep/ManifestFilters.scala | 2 +- .../scalajs/core/tools/sem/Semantics.scala | 37 ----------- .../jsdep/ComplianceRequirementTest.scala | 66 ------------------- .../tools/jsdep/ManifestFiltersTest.scala | 3 +- 10 files changed, 22 insertions(+), 221 deletions(-) delete mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ComplianceRequirement.scala delete mode 100644 tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ComplianceRequirementTest.scala diff --git a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala index 8de5e690cf..6f7f7b43b7 100644 --- a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala +++ b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala @@ -40,10 +40,19 @@ class MainGenericRunner { val optMode = OptMode.fromId(sys.props("scalajs.partest.optMode")) def readSemantics() = { + import org.scalajs.core.tools.sem.CheckedBehavior.Compliant + val opt = sys.props.get("scalajs.partest.compliantSems") - opt.fold(Semantics.Defaults) { str => - val sems = str.split(',') - Semantics.compliantTo(sems.toList) + val compliantSems = + opt.fold[List[String]](Nil)(_.split(',').toList.filter(_.nonEmpty)) + + compliantSems.foldLeft(Semantics.Defaults) { (prev, compliantSem) => + compliantSem match { + case "asInstanceOfs" => prev.withAsInstanceOfs(Compliant) + case "arrayIndexOutOfBounds" => prev.withArrayIndexOutOfBounds(Compliant) + case "moduleInit" => prev.withModuleInit(Compliant) + case "strictFloats" => prev.withStrictFloats(true) + } } } diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index b94f7d5b2c..914b1aac07 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -227,10 +227,6 @@ object ScalaJSPlugin extends AutoPlugin { val resolvedJSDependencies = TaskKey[Attributed[Seq[ResolvedJSDependency]]]("resolvedJSDependencies", "JS dependencies after resolution.", DTask) - val checkScalaJSSemantics = SettingKey[Boolean]("checkScalaJSSemantics", - "Whether to check that the current semantics meet compliance " + - "requirements of dependencies.", CSetting) - val scalaJSOptimizerOptions = SettingKey[OptimizerOptions]("scalaJSOptimizerOptions", "All kinds of options for the Scala.js optimizer stages", DSetting) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 94ec64a65e..f8ae662f7b 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -441,14 +441,8 @@ object ScalaJSPluginInternal { case _ => false } - /* We make the assumption here, that scalaJSSemantics has not - * unreasonably overridden values for the fastOptJS and fullOptJS - * tasks. Otherwise this value does not really make sense. - */ - val compliantSemantics = scalaJSSemantics.value.compliants - val manifest = new JSDependencyManifest(new Origin(myModule, config), - jsDeps.toList, requiresDOM, compliantSemantics) + jsDeps.toList, requiresDOM) // Write dependency file to class directory val targetDir = classDirectory.value @@ -501,18 +495,6 @@ object ScalaJSPluginInternal { val attLibs = scalaJSNativeLibraries.value val attManifests = jsDependencyManifests.value - // Verify semantics compliance - if (checkScalaJSSemantics.value) { - import ComplianceRequirement._ - val requirements = mergeFromManifests(attManifests.data) - - /* We make the assumption here, that scalaJSSemantics has not - * unreasonably overridden values for the fastOptJS and fullOptJS - * tasks. Otherwise, this check is bogus. - */ - checkCompliance(requirements, scalaJSSemantics.value) - } - // Collect originating files val realFiles = { attLibs.get(scalaJSSourceFiles).get ++ @@ -878,7 +860,6 @@ object ScalaJSPluginInternal { scalaJSSemantics := Semantics.Defaults, scalaJSOutputMode := OutputMode.ECMAScript51Isolated, scalaJSModuleKind := ModuleKind.NoModule, - checkScalaJSSemantics := true, scalaJSModuleInitializers := Seq(), scalaJSModuleInitializers in Compile := scalaJSModuleInitializers.value, diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ComplianceRequirement.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ComplianceRequirement.scala deleted file mode 100644 index bcbe0a392b..0000000000 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ComplianceRequirement.scala +++ /dev/null @@ -1,59 +0,0 @@ -package org.scalajs.core.tools.jsdep - -import org.scalajs.core.tools.sem.Semantics - -/** Expresses a requirement for a given semantic to be compliant */ -final class ComplianceRequirement( - val semantics: String, val origins: List[Origin]) { - override def toString(): String = - s"ComplianceRequirement($semantics, origins = [${origins.mkString(", ")}])" - - override def equals(that: Any): Boolean = that match { - case that: ComplianceRequirement => - this.semantics == that.semantics && - this.origins == that.origins - case _ => - false - } - - override def hashCode(): Int = { - import scala.util.hashing.MurmurHash3._ - var acc = ComplianceRequirement.HashSeed - acc = mix(acc, semantics.##) - acc = mixLast(acc, origins.##) - finalizeHash(acc, 2) - } -} - -object ComplianceRequirement { - // "org.scalajs.core.tools.jsdep.ComplianceRequirement".## - private final val HashSeed = -1738348249 - - /** Checks whether the given semantics are compliant with the given - * requirements. - * @throws BadComplianceException if the semantics are not compliant. - */ - final def checkCompliance(requirements: Traversable[ComplianceRequirement], - semantics: Semantics): Unit = { - val unmet = requirements.filterNot(compliance => - semantics.isCompliant(compliance.semantics)) - - if (unmet.nonEmpty) - throw new BadComplianceException(unmet.toList) - } - - def mergeFromManifests( - manifests: Traversable[JSDependencyManifest] - ): Traversable[ComplianceRequirement] = { - - val flatTups = for { - manifest <- manifests - semantics <- manifest.compliantSemantics - } yield (semantics, manifest.origin) - - for { - (semantics, tups) <- flatTups.groupBy(_._1) - } yield new ComplianceRequirement(semantics, tups.map(_._2).toList) - } - -} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/Exceptions.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/Exceptions.scala index e490ba8f0e..ebe8b115a3 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/Exceptions.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/Exceptions.scala @@ -102,18 +102,3 @@ object JSLibResolveException { msg.toString() } } - -class BadComplianceException(val unmet: List[ComplianceRequirement]) - extends Exception(BadComplianceException.mkMsg(unmet)) - -private object BadComplianceException { - private def mkMsg(unmets: List[ComplianceRequirement]): String = { - val msg = new StringBuilder() - msg.append("Unmet required semantic compliance(s): \n") - for (unmet <- unmets) { - msg.append(s"- ${unmet.semantics}") - msg.append(s" originating from: ${unmet.origins.mkString(", ")}\n") - } - msg.toString - } -} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/JSDependencyManifest.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/JSDependencyManifest.scala index 86862ecc64..791fcdd6c2 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/JSDependencyManifest.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/JSDependencyManifest.scala @@ -11,8 +11,7 @@ import java.io.{Reader, Writer} final class JSDependencyManifest( val origin: Origin, val libDeps: List[JSDependency], - val requiresDOM: Boolean, - val compliantSemantics: List[String]) { + val requiresDOM: Boolean) { import JSDependencyManifest._ @@ -20,8 +19,7 @@ final class JSDependencyManifest( case that: JSDependencyManifest => this.origin == that.origin && this.libDeps == that.libDeps && - this.requiresDOM == that.requiresDOM && - this.compliantSemantics == that.compliantSemantics + this.requiresDOM == that.requiresDOM case _ => false } @@ -31,9 +29,8 @@ final class JSDependencyManifest( var acc = HashSeed acc = mix(acc, origin.##) acc = mix(acc, libDeps.##) - acc = mix(acc, requiresDOM.##) - acc = mixLast(acc, compliantSemantics.##) - finalizeHash(acc, 4) + acc = mixLast(acc, requiresDOM.##) + finalizeHash(acc, 3) } override def toString(): String = { @@ -43,8 +40,6 @@ final class JSDependencyManifest( b ++= s", libDeps=$libDeps" if (requiresDOM) b ++= s", requiresDOM=$requiresDOM" - if (compliantSemantics.nonEmpty) - b ++= s", compliantSemantics=$compliantSemantics" b ++= ")" b.result() } @@ -63,10 +58,9 @@ object JSDependencyManifest { def serialize(x: JSDependencyManifest): JSON = { new JSONObjBuilder() - .fld("origin", x.origin) + .fld("origin", x.origin) .opt("libDeps", optList(x.libDeps)) .opt("requiresDOM", if (x.requiresDOM) Some(true) else None) - .opt("compliantSemantics", optList(x.compliantSemantics)) .toJSON } } @@ -75,10 +69,9 @@ object JSDependencyManifest { def deserialize(x: JSON): JSDependencyManifest = { val obj = new JSONObjExtractor(x) new JSDependencyManifest( - obj.fld[Origin] ("origin"), + obj.fld[Origin]("origin"), obj.opt[List[JSDependency]]("libDeps").getOrElse(Nil), - obj.opt[Boolean] ("requiresDOM").getOrElse(false), - obj.opt[List[String]] ("compliantSemantics").getOrElse(Nil)) + obj.opt[Boolean]("requiresDOM").getOrElse(false)) } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ManifestFilters.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ManifestFilters.scala index 46b932d3a0..04e8280544 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ManifestFilters.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ManifestFilters.scala @@ -42,7 +42,7 @@ object ManifestFilters { jsDependency.commonJSName, jsDependency.minifiedResourceName.map(mapping)) new JSDependencyManifest(manifest.origin, filteredJSDeps, - manifest.requiresDOM, manifest.compliantSemantics) + manifest.requiresDOM) } } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/sem/Semantics.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/sem/Semantics.scala index 75de64ff84..4b92a019bd 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/sem/Semantics.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/sem/Semantics.scala @@ -82,25 +82,6 @@ final class Semantics private ( |)""".stripMargin } - /** Checks whether the given semantics setting is Java compliant */ - def isCompliant(name: String): Boolean = name match { - case "asInstanceOfs" => asInstanceOfs == Compliant - case "arrayIndexOutOfBounds" => arrayIndexOutOfBounds == Compliant - case "moduleInit" => moduleInit == Compliant - case "strictFloats" => strictFloats - case _ => false - } - - /** Retrieve a list of semantics which are set to compliant */ - def compliants: List[String] = { - def cl(name: String, cond: Boolean) = if (cond) List(name) else Nil - - cl("asInstanceOfs", asInstanceOfs == Compliant) ++ - cl("arrayIndexOutOfBounds", arrayIndexOutOfBounds == Compliant) ++ - cl("moduleInit", moduleInit == Compliant) ++ - cl("strictFloats", strictFloats) - } - private def copy( asInstanceOfs: CheckedBehavior = this.asInstanceOfs, arrayIndexOutOfBounds: CheckedBehavior = this.arrayIndexOutOfBounds, @@ -131,22 +112,4 @@ object Semantics { strictFloats = false, productionMode = false, runtimeClassName = _.fullName) - - def compliantTo(semantics: Traversable[String]): Semantics = { - import Defaults._ - - val semsSet = semantics.toSet - - def sw[T](name: String, compliant: T, default: T): T = - if (semsSet.contains(name)) compliant else default - - new Semantics( - asInstanceOfs = sw("asInstanceOfs", Compliant, asInstanceOfs), - arrayIndexOutOfBounds = - sw("arrayIndexOutOfBounds", Compliant, arrayIndexOutOfBounds), - moduleInit = sw("moduleInit", Compliant, moduleInit), - strictFloats = sw("strictFloats", true, strictFloats), - productionMode = false, - runtimeClassName = Defaults.runtimeClassName) - } } diff --git a/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ComplianceRequirementTest.scala b/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ComplianceRequirementTest.scala deleted file mode 100644 index f359c062eb..0000000000 --- a/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ComplianceRequirementTest.scala +++ /dev/null @@ -1,66 +0,0 @@ -package org.scalajs.core.tools.jsdep - -import org.scalajs.core.tools.sem.Semantics - -import org.junit.Test -import org.junit.Assert._ - -class ComplianceRequirementTest { - private val origin = new Origin("test", "compile") - private val semantics = Set("asInstanceOfs", "moduleInit", "strictFloats") - - private def mkComplianceRequirement(semantics: String) = - new ComplianceRequirement(semantics, origin :: Nil) - - @Test - def checkComplianceSuccess: Unit = { - for (sems <- semantics.subsets) { - val origin = new Origin("test", "compile") - val requirements = sems.map(mkComplianceRequirement) - val semantics = Semantics.compliantTo(sems) - ComplianceRequirement.checkCompliance(requirements, semantics) - } - } - - @Test - def checkComplianceFail: Unit = { - for { - required <- semantics.subsets - missing <- required.subsets - if missing.nonEmpty - } { - val present = required -- missing - val requirements = required.map(mkComplianceRequirement) - val semantics = Semantics.compliantTo(present) - try { - ComplianceRequirement.checkCompliance(requirements, semantics) - fail("Expected a BadComplianceException be thrown") - } catch { - case e: BadComplianceException => - val expected = requirements.filterNot(r => present(r.semantics)) - assertEquals(expected, e.unmet.toSet) - } - } - } - - @Test - def mergeFromManifests: Unit = { - val origins = Array("a", "b", "c").map(new Origin(_, "compile")) - - def mkManifest(o: Int, semantics: String*) = - new JSDependencyManifest(origins(o), Nil, false, semantics.toList) - - val manifests = Seq( - mkManifest(0, "isInstanceOfs"), - mkManifest(1, "isInstanceOfs", "moduleInit"), - mkManifest(2)) - - val result = ComplianceRequirement.mergeFromManifests(manifests).toSet - val expected = Set( - new ComplianceRequirement("isInstanceOfs", List(0, 1).map(origins)), - new ComplianceRequirement("moduleInit", List(1).map(origins))) - - assertEquals(expected, result) - } - -} diff --git a/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ManifestFiltersTest.scala b/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ManifestFiltersTest.scala index 49189fd396..16eb63397f 100644 --- a/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ManifestFiltersTest.scala +++ b/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ManifestFiltersTest.scala @@ -8,8 +8,7 @@ class ManifestFiltersTest { private def mkManifest(module: String, deps: String*) = { new JSDependencyManifest(new Origin(module, "compile"), - deps.map(new JSDependency(_)).toList, requiresDOM = false, - compliantSemantics = Nil) + deps.map(new JSDependency(_)).toList, requiresDOM = false) } @Test From d4f0605852434ca35513eb1d03c54df36eb9c243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 12 May 2017 23:17:44 +0200 Subject: [PATCH 0273/2665] Separate all jsDependencies-related things in separate projects. This is part of #2841. * The contents of `org.scalajs.core.tools.jsdep._` are extracted in a separate project `jsdependencies-core`. * All the settings related to `jsDependencies` are extracted in a separate sbt plugin `JSDependenciesPlugin` in `jsdependencies-plugin`. --- build.sbt | 2 + ci/matrix.xml | 9 +- .../jsenv/nodejs/AbstractNodeJSEnv.scala | 1 - .../core}/DependencyResolver.scala | 2 +- .../jsdependencies/core}/Exceptions.scala | 2 +- .../core}/FlatJSDependency.scala | 2 +- .../jsdependencies/core}/JSDependency.scala | 6 +- .../core}/JSDependencyManifest.scala | 6 +- .../core}/ManifestFilters.scala | 2 +- .../scalajs/jsdependencies/core}/Origin.scala | 6 +- .../jsdependencies/core}/ResolutionInfo.scala | 2 +- .../core}/ResolvedJSDependency.scala | 2 +- .../core}/ManifestFiltersTest.scala | 2 +- .../sbtplugin/AbstractJSDeps.scala | 4 +- .../sbtplugin/JSDependenciesPlugin.scala | 364 ++++++++++++++++++ .../scala/tools/nsc/MainGenericRunner.scala | 1 - project/Build.scala | 43 ++- project/ExternalCompile.scala | 7 +- project/build.sbt | 4 +- sbt-plugin-test/build.sbt | 15 +- sbt-plugin-test/project/build.sbt | 3 + .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 34 -- .../sbtplugin/ScalaJSPluginInternal.scala | 196 +--------- .../org/scalajs/sbtplugin/ScalajspUtils.scala | 1 - .../sbtplugin/impl/DependencyBuilders.scala | 33 -- .../scala/org/scalajs/core/tools/io/IO.scala | 18 - .../scalajs/core/tools/io/VirtualFiles.scala | 10 - 27 files changed, 450 insertions(+), 327 deletions(-) rename {tools/shared/src/main/scala/org/scalajs/core/tools/jsdep => jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core}/DependencyResolver.scala (99%) rename {tools/shared/src/main/scala/org/scalajs/core/tools/jsdep => jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core}/Exceptions.scala (98%) rename {tools/shared/src/main/scala/org/scalajs/core/tools/jsdep => jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core}/FlatJSDependency.scala (97%) rename {tools/shared/src/main/scala/org/scalajs/core/tools/jsdep => jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core}/JSDependency.scala (96%) rename {tools/shared/src/main/scala/org/scalajs/core/tools/jsdep => jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core}/JSDependencyManifest.scala (94%) rename {tools/shared/src/main/scala/org/scalajs/core/tools/jsdep => jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core}/ManifestFilters.scala (97%) rename {tools/shared/src/main/scala/org/scalajs/core/tools/jsdep => jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core}/Origin.scala (90%) rename {tools/shared/src/main/scala/org/scalajs/core/tools/jsdep => jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core}/ResolutionInfo.scala (96%) rename {tools/shared/src/main/scala/org/scalajs/core/tools/jsdep => jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core}/ResolvedJSDependency.scala (93%) rename {tools/shared/src/test/scala/org/scalajs/core/tools/jsdep => jsdependencies-core/src/test/scala/org/scalajs/jsdependencies/core}/ManifestFiltersTest.scala (97%) rename {sbt-plugin/src/main/scala/org/scalajs => jsdependencies-sbt-plugin/src/main/scala/org/scalajs/jsdependencies}/sbtplugin/AbstractJSDeps.scala (96%) create mode 100644 jsdependencies-sbt-plugin/src/main/scala/org/scalajs/jsdependencies/sbtplugin/JSDependenciesPlugin.scala diff --git a/build.sbt b/build.sbt index 14fed3c921..4258478967 100644 --- a/build.sbt +++ b/build.sbt @@ -21,6 +21,8 @@ val jUnitRuntime = Build.jUnitRuntime val jUnitTestOutputsJS = Build.jUnitTestOutputsJS val jUnitTestOutputsJVM = Build.jUnitTestOutputsJVM val jUnitPlugin = Build.jUnitPlugin +val jsDependenciesCore = Build.jsDependenciesCore +val jsDependenciesPlugin = Build.jsDependenciesPlugin val examples = Build.examples val helloworld = Build.helloworld val reversi = Build.reversi diff --git a/ci/matrix.xml b/ci/matrix.xml index 9d7bd84b01..d55f12d7ef 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -151,7 +151,7 @@ toolsIO, _} +import org.scalajs.core.tools.json._ + +import org.scalajs.jsenv.VirtualFileMaterializer + +import org.scalajs.sbtplugin.ScalaJSPlugin +import org.scalajs.sbtplugin.ScalaJSPlugin.autoImport._ +import org.scalajs.sbtplugin.ScalaJSPluginInternal.scalaJSSourceFiles + +import org.scalajs.jsdependencies.core._ +import org.scalajs.jsdependencies.core.DependencyResolver.DependencyFilter +import org.scalajs.jsdependencies.core.ManifestFilters.ManifestFilter + +object JSDependenciesPlugin extends AutoPlugin { + override def requires: Plugins = ScalaJSPlugin + + object autoImport { + import KeyRanks._ + + val scalaJSNativeLibraries = TaskKey[Attributed[Seq[VirtualJSFile with RelativeVirtualFile]]]( + "scalaJSNativeLibraries", "All the *.js files on the classpath", CTask) + + val packageJSDependencies = TaskKey[File]("packageJSDependencies", + "Packages all dependencies of the preLink classpath in a single file.", AMinusTask) + + val packageMinifiedJSDependencies = TaskKey[File]("packageMinifiedJSDependencies", + "Packages minified version (if available) of dependencies of the preLink " + + "classpath in a single file.", AMinusTask) + + val jsDependencyManifest = TaskKey[File]("jsDependencyManifest", + "Writes the JS_DEPENDENCIES file.", DTask) + + val jsDependencyManifests = TaskKey[Attributed[Traversable[JSDependencyManifest]]]( + "jsDependencyManifests", "All the JS_DEPENDENCIES on the classpath", DTask) + + val requiresDOM = SettingKey[Boolean]("requiresDOM", + "Whether this projects needs the DOM. Overrides anything inherited through dependencies.", AMinusSetting) + + val jsDependencies = SettingKey[Seq[AbstractJSDep]]("jsDependencies", + "JavaScript libraries this project depends upon. Also used to depend on the DOM.", APlusSetting) + + val jsDependencyFilter = SettingKey[DependencyFilter]("jsDependencyFilter", + "The filter applied to the raw JavaScript dependencies before execution", CSetting) + + val jsManifestFilter = SettingKey[ManifestFilter]("jsManifestFilter", + "The filter applied to JS dependency manifests before resolution", CSetting) + + val resolvedJSDependencies = TaskKey[Attributed[Seq[ResolvedJSDependency]]]("resolvedJSDependencies", + "JS dependencies after resolution.", DTask) + + /** 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) + + /** Dummy builder to allow declaractions like: + * + * {{{ + * RuntimeDOM % "test" + * }}} + */ + val RuntimeDOM = RuntimeDOMDep(None) + + /** Builder to allow declarations like: + * + * {{{ + * ProvidedJS / "foo.js" + * ProvidedJS / "foo.js" % "test" + * }}} + */ + object ProvidedJS { + def /(name: String): ProvidedJSModuleID = ProvidedJSModuleID(name, None) + } + + /** Builder to allow declarations like: + * + * {{{ + * "org.webjars" % "jquery" % "1.10.2" / "jquery.js" + * "org.webjars" % "jquery" % "1.10.2" / "jquery.js" % "test" + * }}} + */ + implicit class JSModuleIDBuilder(module: ModuleID) { + def /(name: String): JarJSModuleID = JarJSModuleID(module, name) + } + + } + + import autoImport._ + + /** Collect certain file types from a classpath. + * + * @param cp Classpath to collect from + * @param filter Filter for (real) files of interest (not in jars) + * @param collectJar Collect elements from a jar (called for all jars) + * @param collectFile Collect a single file. Params are the file and the + * relative path of the file (to its classpath entry root). + * @return Collected elements attributed with physical files they originated + * from (key: scalaJSSourceFiles). + */ + private def collectFromClasspath[T](cp: Def.Classpath, filter: FileFilter, + collectJar: VirtualJarFile => Seq[T], + collectFile: (File, String) => T): Attributed[Seq[T]] = { + + val realFiles = Seq.newBuilder[File] + val results = Seq.newBuilder[T] + + for (cpEntry <- Attributed.data(cp) if cpEntry.exists) { + if (cpEntry.isFile && cpEntry.getName.endsWith(".jar")) { + realFiles += cpEntry + val vf = new FileVirtualBinaryFile(cpEntry) with VirtualJarFile + results ++= collectJar(vf) + } else if (cpEntry.isDirectory) { + for { + (file, relPath0) <- Path.selectSubpaths(cpEntry, filter) + } { + val relPath = relPath0.replace(java.io.File.separatorChar, '/') + realFiles += file + results += collectFile(file, relPath) + } + } else { + sys.error("Illegal classpath entry: " + cpEntry.getPath) + } + } + + Attributed.blank(results.result()).put( + scalaJSSourceFiles, realFiles.result()) + } + + private def jsDependencyManifestsInJar( + container: VirtualFileContainer): List[JSDependencyManifest] = { + container.listEntries(_ == JSDependencyManifest.ManifestFileName) { + (_, stream) => + val json = readJSON(new InputStreamReader(stream, "UTF-8")) + fromJSON[JSDependencyManifest](json) + } + } + + /** Concatenates a bunch of VirtualTextFiles to a WritableVirtualTextFile. + * Adds a '\n' after each file. + */ + private def concatFiles(output: WritableVirtualTextFile, + files: Seq[VirtualTextFile]): Unit = { + val out = output.contentWriter + + try { + for (file <- files) { + toolsIO.writeTo(file, out) + // New line after each file + out.write('\n') + } + } finally { + out.close() + } + } + + private def packageJSDependenciesSetting(taskKey: TaskKey[File], + cacheName: String, + getLib: ResolvedJSDependency => VirtualJSFile): Setting[Task[File]] = { + taskKey := Def.taskDyn { + if ((skip in taskKey).value) + Def.task((artifactPath in taskKey).value) + else Def.task { + val s = (streams in taskKey).value + val deps = resolvedJSDependencies.value + val output = (artifactPath in taskKey).value + + val realFiles = deps.get(scalaJSSourceFiles).get + val resolvedDeps = deps.data + + FileFunction.cached(s.cacheDirectory / cacheName, + FilesInfo.lastModified, + FilesInfo.exists) { _ => // We don't need the files + + IO.createDirectory(output.getParentFile) + + val outFile = AtomicWritableFileVirtualJSFile(output) + concatFiles(outFile, resolvedDeps.map(getLib)) + + Set(output) + } (realFiles.toSet) + + output + } + }.value + } + + lazy val configSettings: Seq[Setting[_]] = Seq( + fastOptJS := fastOptJS.dependsOn(packageJSDependencies).value, + fullOptJS := fullOptJS.dependsOn(packageJSDependencies).value, + fullOptJS := fullOptJS.dependsOn(packageMinifiedJSDependencies).value, + + artifactPath in packageJSDependencies := + ((crossTarget in packageJSDependencies).value / + ((moduleName in packageJSDependencies).value + "-jsdeps.js")), + + packageJSDependenciesSetting(packageJSDependencies, "package-js-deps", _.lib), + + artifactPath in packageMinifiedJSDependencies := + ((crossTarget in packageMinifiedJSDependencies).value / + ((moduleName in packageMinifiedJSDependencies).value + "-jsdeps.min.js")), + + packageJSDependenciesSetting(packageMinifiedJSDependencies, + "package-min-js-deps", dep => dep.minifiedLib.getOrElse(dep.lib)), + + 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 RuntimeDOMDep(configurations) => + configurations.forall(_ == config) + case _ => false + } + + val manifest = new JSDependencyManifest(new Origin(myModule, config), + jsDeps.toList, requiresDOM) + + // 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).value, + + jsDependencyManifests := { + val filter = jsManifestFilter.value + val rawManifests = collectFromClasspath(fullClasspath.value, + new ExactFilter(JSDependencyManifest.ManifestFileName), + collectJar = jsDependencyManifestsInJar(_), + collectFile = { (file, _) => + fromJSON[JSDependencyManifest](readJSON(IO.read(file))) + }) + + rawManifests.map(manifests => filter(manifests.toTraversable)) + }, + + scalaJSNativeLibraries := { + collectFromClasspath(fullClasspath.value, + "*.js", collectJar = _.jsFiles, + collectFile = FileVirtualJSFile.relative) + }, + + resolvedJSDependencies := { + val dependencyFilter = jsDependencyFilter.value + val attLibs = scalaJSNativeLibraries.value + val attManifests = jsDependencyManifests.value + + // Collect originating files + val realFiles = { + attLibs.get(scalaJSSourceFiles).get ++ + attManifests.get(scalaJSSourceFiles).get + } + + // Collect available JS libraries + val availableLibs = { + val libs = mutable.Map.empty[String, VirtualJSFile] + for (lib <- attLibs.data) + libs.getOrElseUpdate(lib.relativePath, lib) + libs.toMap + } + + // Actually resolve the dependencies + val resolved = DependencyResolver.resolveDependencies( + attManifests.data, availableLibs, dependencyFilter) + + Attributed.blank[Seq[ResolvedJSDependency]](resolved) + .put(scalaJSSourceFiles, realFiles) + }, + + // Add the resolved JS dependencies to the list of JS files given to envs + jsExecutionFiles := { + val deps = resolvedJSDependencies.value.data + + /* Implement the behavior of commonJSName without having to burn it + * inside NodeJSEnv, and hence in the JSEnv API. + * Since this matches against NodeJSEnv specifically, it obviously + * breaks the OO approach, but oh well ... + */ + val libs = jsEnv.value match { + case _: org.scalajs.jsenv.nodejs.NodeJSEnv => + val libCache = new VirtualFileMaterializer(false) + + for (dep <- deps) yield { + dep.info.commonJSName.fold { + dep.lib + } { commonJSName => + val fname = libCache.materialize(dep.lib).getAbsolutePath + new MemVirtualJSFile(s"require-$fname").withContent( + s"""$commonJSName = require("${escapeJS(fname)}");""" + ) + } + } + + case _ => + deps.map(_.lib) + } + + libs ++ jsExecutionFiles.value + }, + + scalaJSRequestsDOM := { + requiresDOM.?.value.getOrElse( + jsDependencyManifests.value.data.exists(_.requiresDOM)) + } + ) + + lazy val compileSettings = configSettings + + lazy val testSettings = Def.settings( + configSettings, + + moduleName in packageJSDependencies := moduleName.value + "-test" + ) + + override def projectSettings: Seq[Setting[_]] = Def.settings( + inConfig(Compile)(compileSettings), + inConfig(Test)(testSettings), + + // add all the webjars your jsDependencies depend upon + libraryDependencies ++= jsDependencies.value.collect { + case JarJSModuleID(module, _) => module + }, + + jsDependencies := Seq(), + jsDependencyFilter := identity, + jsManifestFilter := identity + ) + +} diff --git a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala index 6f7f7b43b7..12c9f01f9b 100644 --- a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala +++ b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala @@ -5,7 +5,6 @@ package scala.tools.nsc import org.scalajs.core.tools.sem.Semantics import org.scalajs.core.tools.logging._ import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.jsdep.ResolvedJSDependency import org.scalajs.core.tools.linker.{Linker, ModuleInitializer} import org.scalajs.core.tools.linker.backend.{OutputMode, ModuleKind} diff --git a/project/Build.scala b/project/Build.scala index 8acbd9dc92..d1f892f103 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -23,13 +23,15 @@ import org.scalajs.sbtplugin._ import org.scalajs.jsenv.JSEnv import org.scalajs.jsenv.nodejs.{NodeJSEnv, JSDOMNodeJSEnv} +import org.scalajs.jsdependencies.sbtplugin.JSDependenciesPlugin +import org.scalajs.jsdependencies.sbtplugin.JSDependenciesPlugin.autoImport._ + import ScalaJSPlugin.autoImport._ import ExternalCompile.scalaJSExternalCompileSettings import Loggers._ import org.scalajs.core.tools.io.MemVirtualJSFile import org.scalajs.core.tools.sem._ -import org.scalajs.core.tools.jsdep.ResolvedJSDependency import org.scalajs.core.tools.json._ import org.scalajs.core.tools.linker.ModuleInitializer import org.scalajs.core.tools.linker.backend.OutputMode @@ -615,7 +617,8 @@ object Build { ).dependsOn(irProject) lazy val toolsJS: Project = (project in file("tools/js")).enablePlugins( - MyScalaJSPlugin + MyScalaJSPlugin, + JSDependenciesPlugin ).settings( commonToolsSettings, crossVersion := ScalaJSCrossVersion.binary, @@ -1167,6 +1170,39 @@ object Build { exportJars := true ) + // jsDependencies support - to be moved out of the core repository + + lazy val jsDependenciesCore: Project = (project in file("jsdependencies-core")).settings( + commonSettings, + publishSettings, + fatalWarningsSettings, + name := "scalajs-jsdependencies-core", + libraryDependencies += + "com.novocode" % "junit-interface" % "0.11" % "test" + ).dependsOn(tools) + + lazy val jsDependenciesPlugin: Project = (project in file("jsdependencies-sbt-plugin")).settings( + commonSettings, + publishIvySettings, + fatalWarningsSettings, + name := "sbt-scalajs-jsdependencies", + sbtPlugin := true, + scalaBinaryVersion := + CrossVersion.binaryScalaVersion(scalaVersion.value), + + // Add API mappings for sbt (seems they don't export their API URL) + apiMappings ++= { + val deps = (externalDependencyClasspath in Compile).value + val sbtJars = deps filter { attributed => + val p = attributed.data.getPath + p.contains("/org.scala-sbt/") && p.endsWith(".jar") + } + val docUrl = + url(s"http://www.scala-sbt.org/${sbtVersion.value}/api/") + sbtJars.map(_.data -> docUrl).toMap + } + ).dependsOn(plugin, jsDependenciesCore) + // Examples lazy val examples: Project = project.settings( @@ -1391,7 +1427,8 @@ object Build { ) lazy val testSuite: Project = (project in file("test-suite/js")).enablePlugins( - MyScalaJSPlugin + MyScalaJSPlugin, + JSDependenciesPlugin ).settings( commonSettings, testTagSettings, diff --git a/project/ExternalCompile.scala b/project/ExternalCompile.scala index d99a5d8ce0..ff87b466c7 100644 --- a/project/ExternalCompile.scala +++ b/project/ExternalCompile.scala @@ -2,7 +2,6 @@ import sbt._ import Keys._ import org.scalajs.sbtplugin.ScalaJSPlugin -import ScalaJSPlugin.autoImport.jsDependencyManifest object ExternalCompile { @@ -101,11 +100,7 @@ object ExternalCompile { // We do not have dependency analysis when compiling externally sbt.inc.Analysis.Empty - }, - - // Make sure jsDependencyManifest runs after compile, otherwise compile - // might remove the entire directory afterwards. - jsDependencyManifest := jsDependencyManifest.dependsOn(compile).value + } ) val scalaJSExternalCompileSettings = ( diff --git a/project/build.sbt b/project/build.sbt index f1e42470f3..7f3760b6b4 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -26,7 +26,9 @@ unmanagedSourceDirectories in Compile ++= { root / "tools/jvm/src/main/scala", root / "js-envs/src/main/scala", root / "test-adapter/src/main/scala", - root / "sbt-plugin/src/main/scala" + root / "sbt-plugin/src/main/scala", + root / "jsdependencies-core/src/main/scala", + root / "jsdependencies-sbt-plugin/src/main/scala" ) } diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index 6d13a50a46..f612995465 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -1,8 +1,8 @@ import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.jsdep.ManifestFilters import org.scalajs.jsenv.nodejs.JSDOMNodeJSEnv import org.scalajs.sbtplugin.ScalaJSPluginInternal._ import org.scalajs.sbtplugin.Loggers.sbtLogger2ToolsLogger +import org.scalajs.jsdependencies.core.ManifestFilters lazy val concurrentFakeFullOptJS = taskKey[Any]("") lazy val concurrentUseOfLinkerTest = taskKey[Any]("") @@ -129,8 +129,13 @@ lazy val multiTest = crossProject. jsSettings(baseSettings: _*). jsSettings( name := "Multi test framework test JS", + // Make FrameworkDetector resilient to other output - #1572 - jsDependencies in Test += ProvidedJS / "consoleWriter.js", + jsExecutionFiles in Test := { + val consoleWriter = FileVirtualJSFile( + (resourceDirectory in Test).value / "consoleWriter.js") + consoleWriter +: (jsExecutionFiles in Test).value + }, // Test isScalaJSProject (as a setting, it's evaluated when loading the build) isScalaJSProject ~= { value => @@ -181,7 +186,7 @@ lazy val multiTestJVM = multiTest.jvm lazy val jsDependenciesTestDependee = project. settings(versionSettings: _*). - enablePlugins(ScalaJSPlugin). + enablePlugins(ScalaJSPlugin, JSDependenciesPlugin). settings( // This project contains some jsDependencies to test in jsDependenciesTest jsDependencies ++= Seq( @@ -194,7 +199,7 @@ lazy val jsDependenciesTestDependee = project. lazy val jsDependenciesTest = withRegretionTestForIssue2243( project.settings(versionSettings: _*). - enablePlugins(ScalaJSPlugin). + enablePlugins(ScalaJSPlugin, JSDependenciesPlugin). settings( jsDependencies ++= Seq( "org.webjars" % "historyjs" % "1.8.0" / "uncompressed/history.js", @@ -264,7 +269,7 @@ lazy val jsDependenciesTest = withRegretionTestForIssue2243( lazy val jsNoDependenciesTest = withRegretionTestForIssue2243( project.settings(versionSettings: _*). - enablePlugins(ScalaJSPlugin) + enablePlugins(ScalaJSPlugin, JSDependenciesPlugin) ) // Test %%% macro - #1331 diff --git a/sbt-plugin-test/project/build.sbt b/sbt-plugin-test/project/build.sbt index 6626b7a52e..d4ef290b0e 100644 --- a/sbt-plugin-test/project/build.sbt +++ b/sbt-plugin-test/project/build.sbt @@ -1,2 +1,5 @@ addSbtPlugin("org.scala-js" % "sbt-scalajs" % org.scalajs.core.ir.ScalaJSVersions.current) + +addSbtPlugin("org.scala-js" % "sbt-scalajs-jsdependencies" % + org.scalajs.core.ir.ScalaJSVersions.current) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 914b1aac07..0a85f4fa87 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -15,9 +15,6 @@ 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.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 @@ -153,25 +150,9 @@ object ScalaJSPlugin extends AutoPlugin { "`scalaJSUseMainModuleInitializer` is true", CTask) - 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) - val packageJSDependencies = TaskKey[File]("packageJSDependencies", - "Packages all dependencies of the preLink classpath in a single file.", AMinusTask) - - val packageMinifiedJSDependencies = TaskKey[File]("packageMinifiedJSDependencies", - "Packages minified version (if available) of dependencies of the preLink " + - "classpath in a single file.", AMinusTask) - - val jsDependencyManifest = TaskKey[File]("jsDependencyManifest", - "Writes the JS_DEPENDENCIES file.", DTask) - - val jsDependencyManifests = TaskKey[Attributed[Traversable[JSDependencyManifest]]]( - "jsDependencyManifests", "All the JS_DEPENDENCIES on the classpath", DTask) - val scalaJSLinkedFile = TaskKey[VirtualJSFile]("scalaJSLinkedFile", "Linked Scala.js file. This is the result of fastOptJS or fullOptJS, " + "depending on the stage.", DTask) @@ -183,9 +164,6 @@ object ScalaJSPlugin extends AutoPlugin { "The JavaScript environment in which to run and test Scala.js applications.", AMinusTask) - val requiresDOM = SettingKey[Boolean]("requiresDOM", - "Whether this projects needs the DOM. Overrides anything inherited through dependencies.", AMinusSetting) - val relativeSourceMaps = SettingKey[Boolean]("relativeSourceMaps", "Make the referenced paths on source maps relative to target path", BPlusSetting) @@ -206,9 +184,6 @@ object ScalaJSPlugin extends AutoPlugin { "0.6.15") val scalaJSOutputWrapper = scalaJSOutputWrapperInternal - val jsDependencies = SettingKey[Seq[AbstractJSDep]]("jsDependencies", - "JavaScript libraries this project depends upon. Also used to depend on the DOM.", APlusSetting) - val scalaJSSemantics = SettingKey[Semantics]("scalaJSSemantics", "Configurable semantics of Scala.js.", BPlusSetting) @@ -218,15 +193,6 @@ object ScalaJSPlugin extends AutoPlugin { val scalaJSModuleKind = SettingKey[ModuleKind]("scalaJSModuleKind", "Kind of JavaScript modules emitted by Scala.js.", BPlusSetting) - val jsDependencyFilter = SettingKey[DependencyFilter]("jsDependencyFilter", - "The filter applied to the raw JavaScript dependencies before execution", CSetting) - - val jsManifestFilter = SettingKey[ManifestFilter]("jsManifestFilter", - "The filter applied to JS dependency manifests before resolution", CSetting) - - val resolvedJSDependencies = TaskKey[Attributed[Seq[ResolvedJSDependency]]]("resolvedJSDependencies", - "JS dependencies after resolution.", DTask) - val scalaJSOptimizerOptions = SettingKey[OptimizerOptions]("scalaJSOptimizerOptions", "All kinds of options for the Scala.js optimizer stages", DSetting) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index f8ae662f7b..6d969a21af 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -13,9 +13,7 @@ import complete.DefaultParsers._ 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} @@ -74,12 +72,6 @@ object ScalaJSPluginInternal { val scalaJSIRCache = TaskKey[globalIRCache.Cache]("scalaJSIRCache", "Scala.js internal: Task to access a cache.", 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) - /** All .sjsir files on the fullClasspath, used by scalajsp. */ val sjsirFilesOnClasspath = TaskKey[Seq[String]]("sjsirFilesOnClasspath", "All .sjsir files on the fullClasspath, used by scalajsp", @@ -138,35 +130,6 @@ object ScalaJSPluginInternal { incOptions.withNewClassfileManager(newClassfileManager) } - private def packageJSDependenciesSetting(taskKey: TaskKey[File], cacheName: String, - getLib: ResolvedJSDependency => VirtualJSFile): Setting[Task[File]] = { - taskKey := Def.taskDyn { - if ((skip in taskKey).value) - Def.task((artifactPath in taskKey).value) - else Def.task { - val s = (streams in taskKey).value - val deps = resolvedJSDependencies.value - val output = (artifactPath in taskKey).value - - val realFiles = deps.get(scalaJSSourceFiles).get - val resolvedDeps = deps.data - - FileFunction.cached(s.cacheDirectory / cacheName, FilesInfo.lastModified, - FilesInfo.exists) { _ => // We don't need the files - - IO.createDirectory(output.getParentFile) - - val outFile = AtomicWritableFileVirtualJSFile(output) - toolsIO.concatFiles(outFile, resolvedDeps.map(getLib)) - - Set(output) - } (realFiles.toSet) - - output - } - }.value - } - /** Settings for the production key (e.g. fastOptJS) of a given stage */ private def scalaJSStageSettings(stage: Stage, key: TaskKey[Attributed[File]]): Seq[Setting[_]] = Seq( @@ -261,8 +224,6 @@ object ScalaJSPluginInternal { } tag((usesScalaJSLinkerTag in key).value) }.value, - key := key.dependsOn(packageJSDependencies).value, - scalaJSLinkedFile in key := new FileVirtualJSFile(key.value.data) ) @@ -410,142 +371,11 @@ object ScalaJSPluginInternal { prev.withUseClosureCompiler(outputMode == OutputMode.ECMAScript51Isolated) }, - fullOptJS := fullOptJS.dependsOn(packageMinifiedJSDependencies).value, - - artifactPath in packageJSDependencies := - ((crossTarget in packageJSDependencies).value / - ((moduleName in packageJSDependencies).value + "-jsdeps.js")), - - packageJSDependenciesSetting(packageJSDependencies, "package-js-deps", _.lib), - - artifactPath in packageMinifiedJSDependencies := - ((crossTarget in packageMinifiedJSDependencies).value / - ((moduleName in packageMinifiedJSDependencies).value + "-jsdeps.min.js")), - - packageJSDependenciesSetting(packageMinifiedJSDependencies, - "package-min-js-deps", dep => dep.minifiedLib.getOrElse(dep.lib)), - - 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 RuntimeDOMDep(configurations) => - configurations.forall(_ == config) - case _ => false - } - - val manifest = new JSDependencyManifest(new Origin(myModule, config), - jsDeps.toList, requiresDOM) - - // 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).value, - 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.") }).value, - scalaJSNativeLibraries := { - collectFromClasspath(fullClasspath.value, - "*.js", collectJar = _.jsFiles, - collectFile = FileVirtualJSFile.relative) - }, - - jsDependencyManifests := { - val filter = jsManifestFilter.value - val rawManifests = collectFromClasspath(fullClasspath.value, - new ExactFilter(JSDependencyManifest.ManifestFileName), - collectJar = _.jsDependencyManifests, - collectFile = { (file, _) => - fromJSON[JSDependencyManifest](readJSON(IO.read(file))) - }) - - rawManifests.map(manifests => filter(manifests.toTraversable)) - }, - - resolvedJSDependencies := { - val dependencyFilter = jsDependencyFilter.value - val attLibs = scalaJSNativeLibraries.value - val attManifests = jsDependencyManifests.value - - // Collect originating files - val realFiles = { - attLibs.get(scalaJSSourceFiles).get ++ - attManifests.get(scalaJSSourceFiles).get - } - - // Collect available JS libraries - val availableLibs = { - val libs = mutable.Map.empty[String, VirtualJSFile] - for (lib <- attLibs.data) - libs.getOrElseUpdate(lib.relativePath, lib) - libs.toMap - } - - // Actually resolve the dependencies - val resolved = DependencyResolver.resolveDependencies( - attManifests.data, availableLibs, dependencyFilter) - - Attributed.blank[Seq[ResolvedJSDependency]](resolved) - .put(scalaJSSourceFiles, realFiles) - }, - - // Add the resolved JS dependencies to the list of JS files given to envs - jsExecutionFiles ++= { - val deps = resolvedJSDependencies.value.data - - /* Implement the behavior of commonJSName without having to burn it - * inside NodeJSEnv, and hence in the JSEnv API. - * Since this matches against NodeJSEnv specifically, it obviously - * breaks the OO approach, but oh well ... - */ - jsEnv.value match { - case _: org.scalajs.jsenv.nodejs.NodeJSEnv => - val libCache = new VirtualFileMaterializer(false) - - for (dep <- deps) yield { - dep.info.commonJSName.fold { - dep.lib - } { commonJSName => - val fname = libCache.materialize(dep.lib).getAbsolutePath - new MemVirtualJSFile(s"require-$fname").withContent( - s"""$commonJSName = require("${escapeJS(fname)}");""" - ) - } - } - - case _ => - deps.map(_.lib) - } - }, - // Give tasks ability to check we are not forking at build reading time scalaJSEnsureUnforked := { if (fork.value) @@ -554,11 +384,6 @@ object ScalaJSPluginInternal { true }, - scalaJSRequestsDOM := { - requiresDOM.?.value.getOrElse( - jsDependencyManifests.value.data.exists(_.requiresDOM)) - }, - scalaJSJavaSystemProperties ++= { val javaSysPropsPattern = "-D([^=]*)=(.*)".r javaOptions.value.map { @@ -738,7 +563,7 @@ object ScalaJSPluginInternal { val scalaJSTestBuildSettings = ( scalaJSConfigSettings ) ++ ( - Seq(fastOptJS, fullOptJS, packageJSDependencies) map { packageJSTask => + Seq(fastOptJS, fullOptJS) map { packageJSTask => moduleName in packageJSTask := moduleName.value + "-test" } ) @@ -823,23 +648,14 @@ object ScalaJSPluginInternal { scalaJSTestHtmlSettings ) - 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 + inConfig(Test)(scalaJSTestBuildSettings) ) val scalaJSDefaultConfigs = ( inConfig(Compile)(scalaJSCompileSettings) ++ - inConfig(Test)(scalaJSTestSettings) ++ - scalaJSDependenciesSettings + inConfig(Test)(scalaJSTestSettings) ) val scalaJSProjectBaseSettings = Seq( @@ -853,10 +669,6 @@ object ScalaJSPluginInternal { scalaJSOptimizerOptions := OptimizerOptions(), - jsDependencies := Seq(), - jsDependencyFilter := identity, - jsManifestFilter := identity, - scalaJSSemantics := Semantics.Defaults, scalaJSOutputMode := OutputMode.ECMAScript51Isolated, scalaJSModuleKind := ModuleKind.NoModule, diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalajspUtils.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalajspUtils.scala index eb8cefefd5..0281478ec8 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalajspUtils.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalajspUtils.scala @@ -15,7 +15,6 @@ import sbt._ import sbt.complete._ import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.jsdep.JSDependencyManifest private[sbtplugin] object ScalajspUtils { diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/DependencyBuilders.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/DependencyBuilders.scala index 01279e1155..5ea131d0a3 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/DependencyBuilders.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/DependencyBuilders.scala @@ -22,39 +22,6 @@ trait DependencyBuilders { nonEmpty(groupID, "Group ID") new ScalaJSGroupID(groupID) } - - /** - * Dummy builder to allow declaractions like: - * - * {{{ - * RuntimeDOM % "test" - * }}} - */ - val RuntimeDOM = org.scalajs.sbtplugin.RuntimeDOMDep(None) - - /** - * Builder to allow declarations like: - * - * {{{ - * ProvidedJS / "foo.js" - * ProvidedJS / "foo.js" % "test" - * }}} - */ - object ProvidedJS { - def /(name: String): ProvidedJSModuleID = ProvidedJSModuleID(name, None) - } - - /** - * Builder to allow declarations like: - * - * {{{ - * "org.webjars" % "jquery" % "1.10.2" / "jquery.js" - * "org.webjars" % "jquery" % "1.10.2" / "jquery.js" % "test" - * }}} - */ - implicit class JSModuleIDBuilder(module: ModuleID) { - def /(name: String): JarJSModuleID = JarJSModuleID(module, name) - } } final class ScalaJSGroupID private[sbtplugin] (private val groupID: String) { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/IO.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/IO.scala index bf68cb3969..ae35363d20 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/IO.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/IO.scala @@ -124,24 +124,6 @@ object IO { loop() } - /** Concatenates a bunch of VirtualTextFiles to a WritableVirtualTextFile. - * Adds a '\n' after each file. - */ - def concatFiles(output: WritableVirtualTextFile, - files: Seq[VirtualTextFile]): Unit = { - val out = output.contentWriter - - try { - for (file <- files) { - writeTo(file, out) - // New line after each file - out.write('\n') - } - } finally { - out.close() - } - } - @inline private def newBuffer[T : ClassTag] = new Array[T](4096) } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala index 70487bc1e6..7266558a03 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala @@ -6,9 +6,6 @@ import java.util.zip.{ZipInputStream, ZipEntry} import org.scalajs.core.ir -import org.scalajs.core.tools.jsdep.JSDependencyManifest -import org.scalajs.core.tools.json._ - /** A virtual input file. */ trait VirtualFile { @@ -239,13 +236,6 @@ trait VirtualFileContainer extends ScalaJSIRContainer { file } } - - def jsDependencyManifests: List[JSDependencyManifest] = { - listEntries(_ == JSDependencyManifest.ManifestFileName) { (_, stream) => - val json = readJSON(new InputStreamReader(stream, "UTF-8")) - fromJSON[JSDependencyManifest](json) - } - } } private object VirtualFileContainer { From a470134f44d0fe24751865f89b38aea55450a0f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 26 May 2017 13:33:05 +0200 Subject: [PATCH 0274/2665] Fix #2921: Forbid SAMs of JS types (except js.{This,}Function). Since using such a SAM before would produce invalid IR that sent the optimizer crashing, we directly make this into an *error*, rather than a warning. In theory, we could support SAMs of Scala.js-defined JS types, if they do not have an `apply` method. But that would require more work in the compiler backend. This commit does not attempt to do so. --- .../scalajs/core/compiler/PrepJSInterop.scala | 14 ++++ .../core/compiler/test/JSSAMTest.scala | 73 +++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 compiler/src/test/scala/org/scalajs/core/compiler/test/JSSAMTest.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 51e17a7843..ba2fc910ca 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -246,6 +246,20 @@ abstract class PrepJSInterop extends plugins.PluginComponent } super.transform(tree) + /* Anonymous function, need to check that it is not used as a SAM for a + * JS type, unless it is js.FunctionN or js.ThisFunctionN. + * See #2921. + */ + case tree: Function => + val tpeSym = tree.tpe.typeSymbol + if (isJSAny(tpeSym) && !AllJSFunctionClasses.contains(tpeSym)) { + reporter.error(tree.pos, + "Using an anonymous function as a SAM for the JavaScript " + + "type " + tpeSym.fullNameString + " is not allowed. " + + "Use an anonymous class instead.") + } + super.transform(tree) + // Catch Select on Enumeration.Value we couldn't transform but need to // we ignore the implementation of scala.Enumeration itself case ScalaEnumValue.NoName(_) if noEnclosingOwner is OwnerKind.EnumImpl => diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSSAMTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSSAMTest.scala new file mode 100644 index 0000000000..d2076f1c04 --- /dev/null +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSSAMTest.scala @@ -0,0 +1,73 @@ +package org.scalajs.core.compiler.test + +import org.scalajs.core.compiler.test.util._ + +import org.junit.Assume._ +import org.junit.Test + +// scalastyle:off line.size.limit + +class JSSAMTest extends DirectTest with TestHelpers { + + override def preamble: String = + """ + import scala.scalajs.js + import scala.scalajs.js.annotation._ + """ + + @Test + def noSAMAsJSTypeGeneric: Unit = { + + """ + @js.native + trait Foo extends js.Object { + def foo(x: Int): Int + } + + @ScalaJSDefined + trait Bar extends js.Object { + def bar(x: Int): Int + } + + class A { + val foo: Foo = x => x + 1 + val Bar: Bar = x => x + 1 + } + """.fails() + + } + + @Test + def noSAMAsJSType212: Unit = { + + val version = scala.util.Properties.versionNumberString + assumeTrue(!version.startsWith("2.10.") && !version.startsWith("2.11.")) + + """ + @js.native + trait Foo extends js.Object { + def foo(x: Int): Int + } + + @ScalaJSDefined + trait Bar extends js.Object { + def bar(x: Int): Int + } + + class A { + val foo: Foo = x => x + 1 + val Bar: Bar = x => x + 1 + } + """ hasErrors + """ + |newSource1.scala:16: error: Using an anonymous function as a SAM for the JavaScript type Foo is not allowed. Use an anonymous class instead. + | val foo: Foo = x => x + 1 + | ^ + |newSource1.scala:17: error: Using an anonymous function as a SAM for the JavaScript type Bar is not allowed. Use an anonymous class instead. + | val Bar: Bar = x => x + 1 + | ^ + """ + + } + +} From 615994b8b966b6f9d59ba6292f77b29b6361d368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 26 May 2017 19:44:18 +0200 Subject: [PATCH 0275/2665] Avoid `sys.props`. Use `System.{get,set}Property` instead. --- .../core/compiler/test/util/DirectTest.scala | 13 +++++++++---- .../tools/partest/scalajs/ScalaJSPartest.scala | 4 ++-- .../tools/partest/scalajs/ScalaJSPartest.scala | 4 ++-- .../scala/tools/nsc/MainGenericRunner.scala | 4 ++-- project/Build.scala | 16 ++++++++-------- .../scala/runtime/ScalaRunTime.scala | 2 +- .../scala/util/control/NoStackTrace.scala | 2 +- 7 files changed, 25 insertions(+), 20 deletions(-) diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala index 1a58d8d5a4..054b851c34 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala @@ -88,15 +88,20 @@ abstract class DirectTest { def defaultGlobal: Global = newScalaJSCompiler() def testOutputPath: String = { - val baseDir = sys.props("scala.scalajs.compiler.test.output") + val baseDir = System.getProperty("scala.scalajs.compiler.test.output") val outDir = new File(baseDir, getClass.getName) outDir.mkdirs() outDir.getAbsolutePath } - def scalaJSLibPath: String = sys.props("scala.scalajs.compiler.test.scalajslib") - def scalaLibPath: String = sys.props("scala.scalajs.compiler.test.scalalib") - def scalaReflectPath: String = sys.props("scala.scalajs.compiler.test.scalareflect") + def scalaJSLibPath: String = + System.getProperty("scala.scalajs.compiler.test.scalajslib") + + def scalaLibPath: String = + System.getProperty("scala.scalajs.compiler.test.scalalib") + + def scalaReflectPath: String = + System.getProperty("scala.scalajs.compiler.test.scalareflect") def classpath: List[String] = List(scalaJSLibPath) } diff --git a/partest/src/main-partest-1.0.13/scala/tools/partest/scalajs/ScalaJSPartest.scala b/partest/src/main-partest-1.0.13/scala/tools/partest/scalajs/ScalaJSPartest.scala index b1c26d96f6..da418ec3f0 100644 --- a/partest/src/main-partest-1.0.13/scala/tools/partest/scalajs/ScalaJSPartest.scala +++ b/partest/src/main-partest-1.0.13/scala/tools/partest/scalajs/ScalaJSPartest.scala @@ -185,10 +185,10 @@ class ScalaJSSBTRunner( // The test root for partest is read out through the system properties, // not passed as an argument - sys.props("partest.root") = testRoot.getAbsolutePath() + System.setProperty("partest.root", testRoot.getAbsolutePath()) // Partests take at least 5h. We double, just to be sure. (default is 4 hours) - sys.props("partest.timeout") = "10 hours" + System.setProperty("partest.timeout", "10 hours") // Set showDiff on global UI module if (options.showDiff) diff --git a/partest/src/main-partest-1.0.16/scala/tools/partest/scalajs/ScalaJSPartest.scala b/partest/src/main-partest-1.0.16/scala/tools/partest/scalajs/ScalaJSPartest.scala index 860497bfd6..84b38c0013 100644 --- a/partest/src/main-partest-1.0.16/scala/tools/partest/scalajs/ScalaJSPartest.scala +++ b/partest/src/main-partest-1.0.16/scala/tools/partest/scalajs/ScalaJSPartest.scala @@ -187,10 +187,10 @@ class ScalaJSSBTRunner( // The test root for partest is read out through the system properties, // not passed as an argument - sys.props("partest.root") = testRoot.getAbsolutePath() + System.setProperty("partest.root", testRoot.getAbsolutePath()) // Partests take at least 5h. We double, just to be sure. (default is 4 hours) - sys.props("partest.timeout") = "10 hours" + System.setProperty("partest.timeout", "10 hours") override val suiteRunner = new SuiteRunner( testSourcePath = config.optSourcePath orElse Option("test/files") getOrElse PartestDefaults.sourcePath, diff --git a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala index 7c85fa27be..2fd9192e95 100644 --- a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala +++ b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala @@ -38,10 +38,10 @@ class MainGenericRunner { false } - val optMode = OptMode.fromId(sys.props("scalajs.partest.optMode")) + val optMode = OptMode.fromId(System.getProperty("scalajs.partest.optMode")) def readSemantics() = { - val opt = sys.props.get("scalajs.partest.compliantSems") + val opt = Option(System.getProperty("scalajs.partest.compliantSems")) opt.fold(Semantics.Defaults) { str => val sems = str.split(',') Semantics.compliantTo(sems.toList) diff --git a/project/Build.scala b/project/Build.scala index 9996384f2e..18565901d3 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -536,10 +536,10 @@ object Build { testOptions += Tests.Setup { () => val testOutDir = (streams.value.cacheDirectory / "scalajs-compiler-test") IO.createDirectory(testOutDir) - sys.props("scala.scalajs.compiler.test.output") = - testOutDir.getAbsolutePath - sys.props("scala.scalajs.compiler.test.scalajslib") = - (packageBin in (library, Compile)).value.getAbsolutePath + System.setProperty("scala.scalajs.compiler.test.output", + testOutDir.getAbsolutePath) + System.setProperty("scala.scalajs.compiler.test.scalajslib", + (packageBin in (library, Compile)).value.getAbsolutePath) def scalaArtifact(name: String): String = { def isTarget(att: Attributed[File]) = { @@ -558,11 +558,11 @@ object Build { } } - sys.props("scala.scalajs.compiler.test.scalalib") = - scalaArtifact("scala-library") + System.setProperty("scala.scalajs.compiler.test.scalalib", + scalaArtifact("scala-library")) - sys.props("scala.scalajs.compiler.test.scalareflect") = - scalaArtifact("scala-reflect") + System.setProperty("scala.scalajs.compiler.test.scalareflect", + scalaArtifact("scala-reflect")) }, exportJars := true ) diff --git a/scalalib/overrides-2.10/scala/runtime/ScalaRunTime.scala b/scalalib/overrides-2.10/scala/runtime/ScalaRunTime.scala index c1562ceeaf..96a141b77a 100644 --- a/scalalib/overrides-2.10/scala/runtime/ScalaRunTime.scala +++ b/scalalib/overrides-2.10/scala/runtime/ScalaRunTime.scala @@ -340,7 +340,7 @@ object ScalaRunTime { nl + s + "\n" } private[scala] def checkZip(what: String, coll1: TraversableOnce[_], coll2: TraversableOnce[_]) { - if (sys.props contains "scala.debug.zip") { + if (System.getProperty("scala.debug.zip") != null) { val xs = coll1.toIndexedSeq val ys = coll2.toIndexedSeq if (xs.length != ys.length) { diff --git a/scalalib/overrides/scala/util/control/NoStackTrace.scala b/scalalib/overrides/scala/util/control/NoStackTrace.scala index bcc2839701..e1ddca9a5d 100644 --- a/scalalib/overrides/scala/util/control/NoStackTrace.scala +++ b/scalalib/overrides/scala/util/control/NoStackTrace.scala @@ -29,5 +29,5 @@ object NoStackTrace { // two-stage init to make checkinit happy, since sys.SystemProperties.noTraceSupression.value calls back into NoStackTrace.noSuppression final private var _noSuppression = false // !!! Disabled in Scala.js because SystemProperties is not supported - //_noSuppression = sys.SystemProperties.noTraceSupression.value + //_noSuppression = System.getProperty("scala.control.noTraceSuppression", "").equalsIgnoreCase("true") } From 614f409c7d8d113494714a40e3711104bfe206f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 26 May 2017 19:56:41 +0200 Subject: [PATCH 0276/2665] Avoid `sys.exit`. Use `System.exit` instead. --- cli/src/main/scala/org/scalajs/cli/Scalajsp.scala | 11 ++++++++--- .../scala/scala/tools/nsc/MainGenericRunner.scala | 4 ++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/cli/src/main/scala/org/scalajs/cli/Scalajsp.scala b/cli/src/main/scala/org/scalajs/cli/Scalajsp.scala index a06225cf0a..61710580bf 100644 --- a/cli/src/main/scala/org/scalajs/cli/Scalajsp.scala +++ b/cli/src/main/scala/org/scalajs/cli/Scalajsp.scala @@ -42,7 +42,7 @@ object Scalajsp { .action { (_, c) => c.copy(infos = true) } .text("Show DCE infos instead of trees") opt[Unit]('s', "supported") - .action { (_,_) => printSupported(); sys.exit() } + .action { (_,_) => printSupported(); exit(0) } .text("Show supported Scala.js IR versions") version("version") .abbr("v") @@ -85,9 +85,14 @@ object Scalajsp { stdout.flush() } - private def fail(msg: String) = { + private def fail(msg: String): Nothing = { Console.err.println(msg) - sys.exit(1) + exit(1) + } + + private def exit(code: Int): Nothing = { + System.exit(code) + throw new AssertionError("unreachable") } private def readFromFile(fileName: String) = { diff --git a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala index 2fd9192e95..dc6774c550 100644 --- a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala +++ b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala @@ -165,8 +165,8 @@ class MainGenericRunner { } object MainGenericRunner extends MainGenericRunner { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { if (!process(args)) - sys.exit(1) + System.exit(1) } } From 6a413ca716f95c74d98061e98ff655c91bca3b80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 26 May 2017 21:48:14 +0200 Subject: [PATCH 0277/2665] Use a custom `LinkingException` for all user-space linking errors. By "user-space", we mean errors that can legitimately be thrown by the linker, when it receives a bad set of input IR. This excludes any defect of the linker itself. --- .../core/tools/linker/LinkingException.scala | 21 ++++++++++++++++++ .../linker/backend/emitter/Emitter.scala | 2 +- .../tools/linker/frontend/BaseLinker.scala | 22 +++++++++++-------- 3 files changed, 35 insertions(+), 10 deletions(-) create mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingException.scala diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingException.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingException.scala new file mode 100644 index 0000000000..4d6e8a93a7 --- /dev/null +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingException.scala @@ -0,0 +1,21 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.core.tools.linker + +/** Thrown by the linker when linking cannot be performed. */ +class LinkingException(message: String, cause: Throwable) + extends Exception(message, cause) { + + def this(message: String) = this(message, null) + + def this(cause: Throwable) = + this(if (cause == null) null else cause.toString(), cause) + + def this() = this(null, null) +} diff --git 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 index 93eb212dc3..a4f053dc32 100644 --- 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 @@ -163,7 +163,7 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, } if (importsFound) { - sys.error( + throw new LinkingException( "There were module imports without fallback to global " + "variables, but module support is disabled.\n" + "To enable module support, set scalaJSModuleKind := " + diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index 62949e3d68..3d2aac3aa3 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -118,8 +118,10 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, val infoAndTrees = infoInput.map(info => (info, getTree(info.encodedName)._1)) val errorCount = InfoChecker.check(infoAndTrees, logger) - if (errorCount != 0) - sys.error(s"There were $errorCount Info checking errors.") + if (errorCount != 0) { + throw new LinkingException( + s"There were $errorCount Info checking errors.") + } } } @@ -155,7 +157,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, logger.log(linkingErrLevel, s"Not showing $skipped more linking errors") if (fatal) - sys.error("There were linking errors") + throw new LinkingException("There were linking errors") } val linkResult = logger.time("Linker: Assemble LinkedClasses") { @@ -169,10 +171,13 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, logger.time("Linker: Check IR") { if (linkResult.isComplete) { val errorCount = IRChecker.check(linkResult, logger) - if (errorCount != 0) - sys.error(s"There were $errorCount IR checking errors.") + if (errorCount != 0) { + throw new LinkingException( + s"There were $errorCount IR checking errors.") + } } else { - sys.error("Could not check IR because there were linking errors.") + throw new LinkingException( + "Could not check IR because there were linking errors.") } } } @@ -502,8 +507,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, () } - if (errors.nonEmpty && !bypassLinkingErrors) { - sys.error("There were conflicting exports.") - } + if (errors.nonEmpty && !bypassLinkingErrors) + throw new LinkingException("There were conflicting exports.") } } From fb49b7d3b997a4b49601f01cfa9aaf720a8e393a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 26 May 2017 21:50:24 +0200 Subject: [PATCH 0278/2665] Avoid `sys.error`. Throw specific types of exceptions instead. --- .../core/compiler/Compat210Component.scala | 34 ++++++++----- .../org/scalajs/core/compiler/GenJSCode.scala | 10 ++-- .../scalajs/core/compiler/JSDefinitions.scala | 4 -- .../core/compiler/JSGlobalAddons.scala | 9 ++-- .../scalajs/core/compiler/PrepJSInterop.scala | 12 +---- .../core/compiler/test/util/DirectTest.scala | 3 +- .../scala/org/scalajs/core/ir/Hashers.scala | 4 +- .../org/scalajs/core/ir/Serializers.scala | 7 ++- .../org/scalajs/core/ir/Transformers.scala | 6 ++- .../org/scalajs/core/ir/Traversers.scala | 3 +- .../main/scala/java/lang/MathJDK8Bridge.scala | 50 +++++++++---------- .../main/scala/java/util/regex/Pattern.scala | 2 +- .../jsenv/test/RetryingComJSEnvTest.scala | 2 +- .../org/scalajs/jsenv/rhino/RhinoJSEnv.scala | 10 ++-- .../main/scala/scala/runtime/BoxedUnit.scala | 2 +- .../main/scala/scala/scalajs/js/Array.scala | 2 +- .../scala/scalajs/js/ConstructorTag.scala | 3 +- .../scala/scala/scalajs/js/Dictionary.scala | 2 +- .../main/scala/scala/scalajs/js/Dynamic.scala | 12 ++--- .../main/scala/scala/scalajs/js/Object.scala | 5 +- .../main/scala/scala/scalajs/js/package.scala | 17 ++++--- .../typedarray/TypedArrayBufferBridge.scala | 45 +++++++---------- .../scalajs/macroimpls/UseAsMacros.scala | 3 +- .../scala/scala/scalajs/runtime/package.scala | 5 +- .../scalajs/ScalaJSPartestOptions.scala | 8 +-- project/Build.scala | 19 ++++--- project/ExternalCompile.scala | 5 +- sbt-plugin-test/project/Jetty9Test.scala | 2 +- .../sbtplugin/ScalaJSPluginInternal.scala | 17 ++++--- .../collection/immutable/RedBlackTree.scala | 12 ++--- .../collection/immutable/RedBlackTree.scala | 12 ++--- .../resources/SourceMapTestTemplate.scala | 4 +- .../testsuite/compiler/OptimizerTest.scala | 2 +- .../testsuite/compiler/RegressionTest.scala | 2 +- .../core/tools/test/js/QuickLinker.scala | 2 +- .../core/tools/test/js/TestRunner.scala | 2 +- .../core/tools/linker/LinkedClass.scala | 3 +- .../backend/emitter/FunctionEmitter.scala | 25 ++++++---- .../tools/linker/frontend/BaseLinker.scala | 3 +- .../frontend/optimizer/OptimizerCore.scala | 27 ++++++---- 40 files changed, 210 insertions(+), 187 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala b/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala index f574e06148..e0c1541c2a 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala @@ -16,6 +16,7 @@ import scala.tools.nsc._ * @author Sébastien Doeraene */ trait Compat210Component { + import Compat210Component.{infiniteLoop, noImplClasses} val global: Global @@ -25,7 +26,7 @@ trait Compat210Component { implicit final class SymbolCompat(self: Symbol) { def unexpandedName: Name = self.originalName - def originalName: Name = sys.error("infinite loop in Compat") + def originalName: Name = infiniteLoop() def isPrivateThis: Boolean = self.hasAllFlags(PRIVATE | LOCAL) def isLocalToBlock: Boolean = self.isLocal @@ -49,18 +50,20 @@ trait Compat210Component { self: Compat210Component.this.global.type) { def enteringPhase[T](ph: Phase)(op: => T): T = self.beforePhase(ph)(op) - def beforePhase[T](ph: Phase)(op: => T): T = sys.error("infinite loop in Compat") + def beforePhase[T](ph: Phase)(op: => T): T = infiniteLoop() def exitingPhase[T](ph: Phase)(op: => T): T = self.afterPhase(ph)(op) - def afterPhase[T](ph: Phase)(op: => T): T = sys.error("infinite loop in Compat") + def afterPhase[T](ph: Phase)(op: => T): T = infiniteLoop() def delambdafy: DelambdafyCompat.type = DelambdafyCompat } object DelambdafyCompat { object FreeVarTraverser { - def freeVarsOf(function: Function): mutable.LinkedHashSet[Symbol] = - sys.error("FreeVarTraverser should not be called on 2.10") + def freeVarsOf(function: Function): mutable.LinkedHashSet[Symbol] = { + throw new AssertionError( + "FreeVarTraverser should not be called on 2.10") + } } } @@ -70,16 +73,15 @@ trait Compat210Component { definitions.SeqClass.implClass != NoSymbol // a trait we know has an impl class implicit final class StdTermNamesCompat(self: global.nme.type) { - def IMPL_CLASS_SUFFIX: String = sys.error("No impl classes in this version") + def IMPL_CLASS_SUFFIX: String = noImplClasses() def isImplClassName(name: Name): Boolean = false } implicit final class StdTypeNamesCompat(self: global.tpnme.type) { - def IMPL_CLASS_SUFFIX: String = sys.error("No impl classes in this version") + def IMPL_CLASS_SUFFIX: String = noImplClasses() - def interfaceName(implname: Name): TypeName = - sys.error("No impl classes in this version") + def interfaceName(implname: Name): TypeName = noImplClasses() } // SAMFunction was introduced in 2.12.0-M4 for LMF-capable SAM types @@ -181,8 +183,8 @@ trait Compat210Component { * `overridden` are only present in 2.10. */ private implicit class Cursor210toCursor211(cursor: overridingPairs.Cursor) { - def overriding: Symbol = sys.error("infinite loop in Compat") - def overridden: Symbol = sys.error("infinite loop in Compat") + def overriding: Symbol = infiniteLoop() + def overridden: Symbol = infiniteLoop() } } @@ -193,7 +195,7 @@ trait Compat210Component { def erasedUnderlying: Type = enteringPhase(currentRun.erasurePhase)( erasure.erasedValueClassArg(self.original)) - def original: TypeRef = sys.error("infinite loop in Compat") + def original: TypeRef = infiniteLoop() } // Definitions @@ -237,7 +239,7 @@ trait Compat210Component { object Compat210Component { private object LowPriorityMode { object Mode { - def FUNmode: Nothing = sys.error("infinite loop in Compat") + def FUNmode: Nothing = infiniteLoop() } } @@ -250,6 +252,12 @@ object Compat210Component { } } } + + private def infiniteLoop(): Nothing = + throw new AssertionError("Infinite loop in Compat") + + private def noImplClasses(): Nothing = + throw new AssertionError("No impl classes in this version") } trait PluginComponent210Compat extends Compat210Component { diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 29b8917e94..6d5ab0c113 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -211,7 +211,7 @@ abstract class GenJSCode extends plugins.PluginComponent } optDef.getOrElse { - sys.error("Couldn't find tree for lazily generated anonymous class " + + abort("Couldn't find tree for lazily generated anonymous class " + s"${sym.fullName} at ${sym.pos}") } } @@ -635,7 +635,7 @@ abstract class GenJSCode extends plugins.PluginComponent classMembers += property case tree => - sys.error("Unexpected tree: " + tree) + abort("Unexpected tree: " + tree) } // Make new class def with static members only @@ -706,7 +706,7 @@ abstract class GenJSCode extends plugins.PluginComponent List(selfRef, name, descriptor)) case tree => - sys.error("Unexpected tree: " + tree) + abort("Unexpected tree: " + tree) } // Transform the constructor body. @@ -718,7 +718,7 @@ abstract class GenJSCode extends plugins.PluginComponent val newTree = { val ident = - origJsClass.superClass.getOrElse(sys.error("No superclass")) + origJsClass.superClass.getOrElse(abort("No superclass")) if (args.isEmpty && ident.name == "sjs_js_Object") { js.JSObjectConstr(Nil) } else { @@ -1869,7 +1869,7 @@ abstract class GenJSCode extends plugins.PluginComponent js.VarRef(encodeLocalSym(sym))(toIRType(sym.tpe)) } } else { - sys.error("Cannot use package as value: " + tree) + abort("Cannot use package as value: " + tree) } case Literal(value) => diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 9483da5a7b..2421beeabe 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -138,10 +138,6 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val BoxesRunTime_boxToCharacter = getMemberMethod(BoxesRunTimeModule, newTermName("boxToCharacter")) lazy val BoxesRunTime_unboxToChar = getMemberMethod(BoxesRunTimeModule, newTermName("unboxToChar")) - // Copy-pasted from `Definitions.scala`, because it was removed in 2.13. - lazy val SysPackage = getPackageObject("scala.sys") - def Sys_error: Symbol = getMemberMethod(SysPackage, nme.error) - lazy val ReflectModule = getRequiredModule("scala.scalajs.reflect.Reflect") lazy val Reflect_registerLoadableModuleClass = getMemberMethod(ReflectModule, newTermName("registerLoadableModuleClass")) lazy val Reflect_registerInstantiatableClass = getMemberMethod(ReflectModule, newTermName("registerInstantiatableClass")) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala index b3cf7936fd..e402c250b5 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala @@ -124,9 +124,12 @@ trait JSGlobalAddons extends JSDefinitions } else None } - dropPrefix(methodExportPrefix).map((_,false)) orElse - dropPrefix(propExportPrefix).map((_,true)) getOrElse - sys.error("non-exported name passed to jsInfoSpec") + dropPrefix(methodExportPrefix).map((_,false)).orElse { + dropPrefix(propExportPrefix).map((_,true)) + }.getOrElse { + throw new IllegalArgumentException( + "non-exported name passed to jsExportInfo") + } } def isJSProperty(sym: Symbol): Boolean = isJSGetter(sym) || isJSSetter(sym) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index ba2fc910ca..0d620ba11e 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -1100,17 +1100,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent * JS class/trait. */ } else if (jsPrimitives.isJavaScriptPrimitive(sym)) { - // Force rhs of a primitive to be `sys.error("stub")` except for the - // js.native primitive which displays an elaborate error message - if (sym != JSPackage_native) { - tree.rhs match { - case Apply(trg, Literal(Constant("stub")) :: Nil) - if trg.symbol == jsDefinitions.Sys_error => - case _ => - reporter.error(tree.pos, - "The body of a primitive must be `sys.error(\"stub\")`.") - } - } + // No check for primitives. We trust our own standard library. } else if (sym.isConstructor) { // Force secondary ctor to have only a call to the primary ctor inside tree.rhs match { diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala index 054b851c34..fbdcdc2803 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala @@ -47,7 +47,8 @@ abstract class DirectTest { override lazy val plugins = { val scalaJSPlugin = newScalaJSPlugin(global) - scalaJSPlugin.processOptions(scalaJSPlugin.options, sys.error(_)) + scalaJSPlugin.processOptions(scalaJSPlugin.options, + msg => throw new IllegalArgumentException(msg)) scalaJSPlugin :: Nil } } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala index ee52ad8e6f..bf19a39a2b 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala @@ -440,8 +440,8 @@ object Hashers { mixTrees(captureValues) case _ => - sys.error(s"Unable to hash tree of class ${tree.getClass}") - + throw new IllegalArgumentException( + s"Unable to hash tree of class ${tree.getClass}") } } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index 43e4f7ebbf..b78b4730a6 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -699,7 +699,7 @@ object Serializers { import input._ val result = (tag: @switch) match { case TagEmptyTree => - sys.error("Found invalid TagEmptyTree") + throw new IOException("Found invalid TagEmptyTree") case TagVarDef => VarDef(readIdent(), readType(), readBoolean(), readTree()) case TagParamDef => @@ -716,9 +716,8 @@ object Serializers { case TagDoWhile => DoWhile(readTree(), readTree(), readOptIdent()) case TagTry => - if (!useHacks068) { - sys.error("Invalid tag TagTry") - } + if (!useHacks068) + throw new IOException("Invalid tag TagTry") val block = readTree() val errVar = readIdent() diff --git a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala index fc3896745e..50141aae07 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala @@ -200,7 +200,8 @@ object Transformers { tree case _ => - sys.error(s"Invalid tree in transform() of class ${tree.getClass}") + throw new IllegalArgumentException( + s"Invalid tree in transform() of class ${tree.getClass}") } } } @@ -245,7 +246,8 @@ object Transformers { transformDef(methodDef).asInstanceOf[MethodDef]) case _ => - sys.error(s"Invalid tree in transformDef() of class ${tree.getClass}") + throw new IllegalArgumentException( + s"Invalid tree in transformDef() of class ${tree.getClass}") } } } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala index e8c8009894..dfa648ffc7 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala @@ -223,7 +223,8 @@ object Traversers { _:TopLevelFieldExportDef => case _ => - sys.error(s"Invalid tree in traverse() of class ${tree.getClass}") + throw new IllegalArgumentException( + s"Invalid tree in traverse() of class ${tree.getClass}") } } diff --git a/javalib/src/main/scala/java/lang/MathJDK8Bridge.scala b/javalib/src/main/scala/java/lang/MathJDK8Bridge.scala index 97e2fddad1..d3f081fd93 100644 --- a/javalib/src/main/scala/java/lang/MathJDK8Bridge.scala +++ b/javalib/src/main/scala/java/lang/MathJDK8Bridge.scala @@ -21,54 +21,54 @@ package java.lang private[java] object MathJDK8Bridge { - def addExact(a: scala.Int, b: scala.Int): scala.Int = sys.error("stub") + def addExact(a: scala.Int, b: scala.Int): scala.Int = stub() - def addExact(a: scala.Long, b: scala.Long): scala.Long = sys.error("stub") + def addExact(a: scala.Long, b: scala.Long): scala.Long = stub() - def subtractExact(a: scala.Int, b: scala.Int): scala.Int = sys.error("stub") + def subtractExact(a: scala.Int, b: scala.Int): scala.Int = stub() - def subtractExact(a: scala.Long, b: scala.Long): scala.Long = - sys.error("stub") + def subtractExact(a: scala.Long, b: scala.Long): scala.Long = stub() - def multiplyExact(a: scala.Int, b: scala.Int): scala.Int = sys.error("stub") + def multiplyExact(a: scala.Int, b: scala.Int): scala.Int = stub() - def multiplyExact(a: scala.Long, b: scala.Long): scala.Long = - sys.error("stub") + def multiplyExact(a: scala.Long, b: scala.Long): scala.Long = stub() - def incrementExact(a: scala.Int): scala.Int = sys.error("stub") + def incrementExact(a: scala.Int): scala.Int = stub() - def incrementExact(a: scala.Long): scala.Long = sys.error("stub") + def incrementExact(a: scala.Long): scala.Long = stub() - def decrementExact(a: scala.Int): scala.Int = sys.error("stub") + def decrementExact(a: scala.Int): scala.Int = stub() - def decrementExact(a: scala.Long): scala.Long = sys.error("stub") + def decrementExact(a: scala.Long): scala.Long = stub() - def negateExact(a: scala.Int): scala.Int = sys.error("stub") + def negateExact(a: scala.Int): scala.Int = stub() - def negateExact(a: scala.Long): scala.Long = sys.error("stub") + def negateExact(a: scala.Long): scala.Long = stub() - def toIntExact(a: scala.Long): scala.Int = sys.error("stub") + def toIntExact(a: scala.Long): scala.Int = stub() - def floorDiv(a: scala.Int, b: scala.Int): scala.Int = sys.error("stub") + def floorDiv(a: scala.Int, b: scala.Int): scala.Int = stub() - def floorDiv(a: scala.Long, b: scala.Long): scala.Long = sys.error("stub") + def floorDiv(a: scala.Long, b: scala.Long): scala.Long = stub() - def floorMod(a: scala.Int, b: scala.Int): scala.Int = sys.error("stub") + def floorMod(a: scala.Int, b: scala.Int): scala.Int = stub() - def floorMod(a: scala.Long, b: scala.Long): scala.Long = sys.error("stub") + def floorMod(a: scala.Long, b: scala.Long): scala.Long = stub() // A few other Math-related methods that are not really in Math - def toUnsignedString(i: scala.Int): String = sys.error("stub") + def toUnsignedString(i: scala.Int): String = stub() - def toUnsignedString(i: scala.Long): String = sys.error("stub") + def toUnsignedString(i: scala.Long): String = stub() - def divideUnsigned(a: scala.Int, b: scala.Int): scala.Int = sys.error("stub") + def divideUnsigned(a: scala.Int, b: scala.Int): scala.Int = stub() - def divideUnsigned(a: scala.Long, b: scala.Long): scala.Long = sys.error("stub") + def divideUnsigned(a: scala.Long, b: scala.Long): scala.Long = stub() - def remainderUnsigned(a: scala.Int, b: scala.Int): scala.Int = sys.error("stub") + def remainderUnsigned(a: scala.Int, b: scala.Int): scala.Int = stub() - def remainderUnsigned(a: scala.Long, b: scala.Long): scala.Long = sys.error("stub") + def remainderUnsigned(a: scala.Long, b: scala.Long): scala.Long = stub() + private def stub(): Nothing = + throw new Error("stub") } diff --git a/javalib/src/main/scala/java/util/regex/Pattern.scala b/javalib/src/main/scala/java/util/regex/Pattern.scala index 6ad79e8003..f2255cab21 100644 --- a/javalib/src/main/scala/java/util/regex/Pattern.scala +++ b/javalib/src/main/scala/java/util/regex/Pattern.scala @@ -179,7 +179,7 @@ object Pattern { case 'u' => UNICODE_CASE case 'x' => COMMENTS case 'U' => UNICODE_CHARACTER_CLASS - case _ => sys.error("bad in-pattern flag") + case _ => throw new IllegalArgumentException("bad in-pattern flag") } /** matches \Q\E to support StringLike.split */ diff --git a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/RetryingComJSEnvTest.scala b/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/RetryingComJSEnvTest.scala index 4aeccda56c..2e78424893 100644 --- a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/RetryingComJSEnvTest.scala +++ b/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/RetryingComJSEnvTest.scala @@ -89,7 +89,7 @@ class RetryingComJSEnvTest extends JSEnvTest with ComTests { private def fail() = { fails += 1 - sys.error("Dummy fail for testing purposes") + throw new Exception("Dummy fail for testing purposes") } } } diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/RhinoJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/RhinoJSEnv.scala index 0bc0087840..9ed8d0c6cc 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/RhinoJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/RhinoJSEnv.scala @@ -238,7 +238,8 @@ final class RhinoJSEnv private ( case e: RhinoException => // Trace here, since we want to be in the context to trace. logger.trace(e) - sys.error(s"Exception while running JS code: ${e.getMessage}") + throw new Exception( + s"Exception while running JS code: ${e.getMessage}") } } finally { // Ensure the channel is closed to release JVM side @@ -292,9 +293,9 @@ final class RhinoJSEnv private ( val ordering = Ordering.by[TimedTask, Deadline](_.deadline).reverse val taskQ = mutable.PriorityQueue.empty(ordering) - def ensure[T: ClassTag](v: AnyRef, errMsg: String) = v match { + def ensure[T: ClassTag](v: AnyRef, errMsg: String): T = v match { case v: T => v - case _ => sys.error(errMsg) + case _ => throw new IllegalArgumentException(errMsg) } scope.addFunction("setTimeout", args => { @@ -356,7 +357,8 @@ final class RhinoJSEnv private ( msg => f.call(context, scope, scope, Array(msg)) setCallback(cb) case _ => - sys.error("First argument to init must be a function") + throw new IllegalArgumentException( + "First argument to init must be a function") }) comObj.addFunction("close", _ => { diff --git a/library-aux/src/main/scala/scala/runtime/BoxedUnit.scala b/library-aux/src/main/scala/scala/runtime/BoxedUnit.scala index dc0cbc597b..1c53c2557e 100644 --- a/library-aux/src/main/scala/scala/runtime/BoxedUnit.scala +++ b/library-aux/src/main/scala/scala/runtime/BoxedUnit.scala @@ -13,7 +13,7 @@ class BoxedUnit private () extends AnyRef with java.io.Serializable { } object BoxedUnit { - def UNIT: BoxedUnit = sys.error("stub") + def UNIT: BoxedUnit = throw new Error("stub") final val TYPE = classOf[Unit] } diff --git a/library/src/main/scala/scala/scalajs/js/Array.scala b/library/src/main/scala/scala/scalajs/js/Array.scala index f6bb75118a..56c9fa25ae 100644 --- a/library/src/main/scala/scala/scalajs/js/Array.scala +++ b/library/src/main/scala/scala/scalajs/js/Array.scala @@ -176,7 +176,7 @@ object Array extends Object { // def apply[A](arrayLength: Int): Array[A] = native /** Creates a new array with the given items. */ - def apply[A](items: A*): Array[A] = sys.error("stub") + def apply[A](items: A*): Array[A] = throw new java.lang.Error("stub") /** Returns true if the given value is an array. */ def isArray(arg: Any): Boolean = native diff --git a/library/src/main/scala/scala/scalajs/js/ConstructorTag.scala b/library/src/main/scala/scala/scalajs/js/ConstructorTag.scala index f4463493fe..f4f8c51427 100644 --- a/library/src/main/scala/scala/scalajs/js/ConstructorTag.scala +++ b/library/src/main/scala/scala/scalajs/js/ConstructorTag.scala @@ -35,5 +35,6 @@ object ConstructorTag { * This method has the same preconditions as * [[constructorOf js.constructorOf]]. */ - implicit def materialize[T <: Any]: ConstructorTag[T] = sys.error("stub") + implicit def materialize[T <: Any]: ConstructorTag[T] = + throw new java.lang.Error("stub") } diff --git a/library/src/main/scala/scala/scalajs/js/Dictionary.scala b/library/src/main/scala/scala/scalajs/js/Dictionary.scala index dff2feaee3..509cc1f570 100644 --- a/library/src/main/scala/scala/scalajs/js/Dictionary.scala +++ b/library/src/main/scala/scala/scalajs/js/Dictionary.scala @@ -62,7 +62,7 @@ sealed trait Dictionary[A] extends Any { * Since we are using strict mode, this throws an exception, if the property * isn't configurable. */ - def delete(key: String): Unit = sys.error("stub") + def delete(key: String): Unit = throw new java.lang.Error("stub") } /** Factory for [[Dictionary]] instances. */ diff --git a/library/src/main/scala/scala/scalajs/js/Dynamic.scala b/library/src/main/scala/scala/scalajs/js/Dynamic.scala index a7b09c6a21..de3e9ea87a 100644 --- a/library/src/main/scala/scala/scalajs/js/Dynamic.scala +++ b/library/src/main/scala/scala/scalajs/js/Dynamic.scala @@ -78,7 +78,8 @@ object Dynamic { @inline def global: Dynamic = scala.scalajs.runtime.environmentInfo.global /** Instantiates a new object of a JavaScript class. */ - def newInstance(clazz: Dynamic)(args: Any*): Object with Dynamic = sys.error("stub") + def newInstance(clazz: Dynamic)(args: Any*): Object with Dynamic = + throw new java.lang.Error("stub") /** Creates a new object with a literal syntax. * @@ -91,8 +92,8 @@ object Dynamic { /** literal creation like this: * js.Dynamic.literal(name1 = "value", name2 = "value") */ - def applyDynamicNamed(name: String)( - fields: (String, Any)*): Object with Dynamic = sys.error("stub") + def applyDynamicNamed(name: String)(fields: (String, Any)*): Object with Dynamic = + throw new java.lang.Error("stub") /** literal creation like this: * js.Dynamic.literal("name1" -> "value", "name2" -> "value") @@ -101,8 +102,7 @@ object Dynamic { * applyDynamicNamed fail, since a call with named arguments would * be routed to the `def apply`, rather than def dynamic version. */ - def applyDynamic(name: String)( - fields: (String, Any)*): Object with Dynamic = sys.error("stub") - + def applyDynamic(name: String)(fields: (String, Any)*): Object with Dynamic = + throw new java.lang.Error("stub") } } diff --git a/library/src/main/scala/scala/scalajs/js/Object.scala b/library/src/main/scala/scala/scalajs/js/Object.scala index de292e2753..0fd670439e 100644 --- a/library/src/main/scala/scala/scalajs/js/Object.scala +++ b/library/src/main/scala/scala/scalajs/js/Object.scala @@ -57,7 +57,8 @@ object Object extends Object { /** Tests whether the object has a property on itself or in its prototype * chain. This method is the equivalent of `p in o` in JavaScript. */ - def hasProperty(o: Object, p: String): Boolean = sys.error("stub") + def hasProperty(o: Object, p: String): Boolean = + throw new java.lang.Error("stub") /** * The Object.getPrototypeOf() method returns the prototype (i.e. the @@ -220,5 +221,5 @@ object Object extends Object { * that the list returned by [[keys]] is a sublist of the list returned by * this method (not just a subset). */ - def properties(o: Any): Array[String] = sys.error("stub") + def properties(o: Any): Array[String] = throw new java.lang.Error("stub") } diff --git a/library/src/main/scala/scala/scalajs/js/package.scala b/library/src/main/scala/scala/scalajs/js/package.scala index 67e25a8510..102587009a 100644 --- a/library/src/main/scala/scala/scalajs/js/package.scala +++ b/library/src/main/scala/scala/scalajs/js/package.scala @@ -72,7 +72,7 @@ package object js { v.asInstanceOf[scala.AnyRef] eq undefined /** Returns the type of `x` as identified by `typeof x` in JavaScript. */ - def typeOf(x: Any): String = sys.error("stub") + def typeOf(x: Any): String = throw new java.lang.Error("stub") /** Returns the constructor function of a JavaScript class. * @@ -80,7 +80,7 @@ package object js { * `classOf[T]`) and represent a class extending `js.Any` (not a trait nor * an object). */ - def constructorOf[T <: js.Any]: js.Dynamic = sys.error("stub") + def constructorOf[T <: js.Any]: js.Dynamic = throw new java.lang.Error("stub") /** Makes explicit an implicitly available `ConstructorTag[T]`. */ def constructorTag[T <: js.Any](implicit tag: ConstructorTag[T]): ConstructorTag[T] = @@ -96,7 +96,7 @@ package object js { * - In Chrome, it has no effect unless the developer tools are opened * beforehand. */ - def debugger(): Unit = sys.error("stub") + def debugger(): Unit = throw new java.lang.Error("stub") /** Evaluates JavaScript code and returns the result. */ @inline def eval(x: String): Any = @@ -125,10 +125,13 @@ package object js { * } * }}} */ - def native: Nothing = sys.error("A method defined in a JavaScript raw " + - "type of a Scala.js library has been called. This is most likely " + - "because you tried to run Scala.js binaries on the JVM. Make sure you " + - "are using the JVM version of the libraries.") + def native: Nothing = { + throw new java.lang.Error( + "A method defined in a JavaScript raw type of a Scala.js library has " + + "been called. This is most likely because you tried to run Scala.js " + + "binaries on the JVM. Make sure you are using the JVM version of the " + + "libraries.") + } /** Allows to cast a value to a facade trait in a type-safe way. * diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/TypedArrayBufferBridge.scala b/library/src/main/scala/scala/scalajs/js/typedarray/TypedArrayBufferBridge.scala index ba611e80e1..fb063bf6af 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/TypedArrayBufferBridge.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/TypedArrayBufferBridge.scala @@ -34,45 +34,34 @@ package scala.scalajs.js.typedarray import java.nio._ private[typedarray] object TypedArrayBufferBridge { - def wrap(array: ArrayBuffer): ByteBuffer = - sys.error("stub") + def wrap(array: ArrayBuffer): ByteBuffer = stub() - def wrap(array: ArrayBuffer, byteOffset: Int, length: Int): ByteBuffer = - sys.error("stub") + def wrap(array: ArrayBuffer, byteOffset: Int, length: Int): ByteBuffer = stub() - def wrap(array: Int8Array): ByteBuffer = - sys.error("stub") + def wrap(array: Int8Array): ByteBuffer = stub() - def wrap(array: Uint16Array): CharBuffer = - sys.error("stub") + def wrap(array: Uint16Array): CharBuffer = stub() - def wrap(array: Int16Array): ShortBuffer = - sys.error("stub") + def wrap(array: Int16Array): ShortBuffer = stub() - def wrap(array: Int32Array): IntBuffer = - sys.error("stub") + def wrap(array: Int32Array): IntBuffer = stub() - def wrap(array: Float32Array): FloatBuffer = - sys.error("stub") + def wrap(array: Float32Array): FloatBuffer = stub() - def wrap(array: Float64Array): DoubleBuffer = - sys.error("stub") + def wrap(array: Float64Array): DoubleBuffer = stub() - def Buffer_hasArrayBuffer(buffer: Buffer): Boolean = - sys.error("stub") + def Buffer_hasArrayBuffer(buffer: Buffer): Boolean = stub() - def Buffer_arrayBuffer(buffer: Buffer): ArrayBuffer = - sys.error("stub") + def Buffer_arrayBuffer(buffer: Buffer): ArrayBuffer = stub() - def Buffer_arrayBufferOffset(buffer: Buffer): Int = - sys.error("stub") + def Buffer_arrayBufferOffset(buffer: Buffer): Int = stub() - def Buffer_dataView(buffer: Buffer): DataView = - sys.error("stub") + def Buffer_dataView(buffer: Buffer): DataView = stub() - def Buffer_hasTypedArray(buffer: Buffer): Boolean = - sys.error("stub") + def Buffer_hasTypedArray(buffer: Buffer): Boolean = stub() - def Buffer_typedArray(buffer: Buffer): TypedArray[_, _] = - sys.error("stub") + def Buffer_typedArray(buffer: Buffer): TypedArray[_, _] = stub() + + private def stub(): Nothing = + throw new Error("stub") } diff --git a/library/src/main/scala/scala/scalajs/macroimpls/UseAsMacros.scala b/library/src/main/scala/scala/scalajs/macroimpls/UseAsMacros.scala index 495e8c5089..1156184bf3 100644 --- a/library/src/main/scala/scala/scalajs/macroimpls/UseAsMacros.scala +++ b/library/src/main/scala/scala/scalajs/macroimpls/UseAsMacros.scala @@ -95,7 +95,8 @@ private[scalajs] object UseAsMacros { "likely caused by an abstract type in the method signature" case _ => - sys.error("Unknown type in unsupported member. " + + throw new NotImplementedError( + "Unknown type in unsupported member. " + "Report this as a bug.\n" + s"Offending method: ${sym.fullName}\n" + s"Offending type: ${showRaw(tpe)}") diff --git a/library/src/main/scala/scala/scalajs/runtime/package.scala b/library/src/main/scala/scala/scalajs/runtime/package.scala index 4f1ba7d705..3a4be2a54f 100644 --- a/library/src/main/scala/scala/scalajs/runtime/package.scala +++ b/library/src/main/scala/scala/scalajs/runtime/package.scala @@ -73,7 +73,8 @@ package object runtime { * The `clazz` parameter must be a literal `classOf[T]` constant such that * `T` represents a class extending `js.Any` (not a trait nor an object). */ - def constructorOf(clazz: Class[_ <: js.Any]): js.Dynamic = sys.error("stub") + def constructorOf(clazz: Class[_ <: js.Any]): js.Dynamic = + throw new Error("stub") /** Public access to `new ConstructorTag` for the codegen of * `js.ConstructorTag.materialize`. @@ -140,7 +141,7 @@ package object runtime { * * See [[LinkingInfo]] for details. */ - def linkingInfo: LinkingInfo = sys.error("stub") + def linkingInfo: LinkingInfo = throw new Error("stub") /** Polyfill for fround in case we use strict Floats and even Typed Arrays * are not available. diff --git a/partest/src/main/scala/scala/tools/partest/scalajs/ScalaJSPartestOptions.scala b/partest/src/main/scala/scala/tools/partest/scalajs/ScalaJSPartestOptions.scala index 1f1680a016..7b078a9757 100644 --- a/partest/src/main/scala/scala/tools/partest/scalajs/ScalaJSPartestOptions.scala +++ b/partest/src/main/scala/scala/tools/partest/scalajs/ScalaJSPartestOptions.scala @@ -35,10 +35,10 @@ object ScalaJSPartestOptions { } object OptMode { def fromId(id: String): OptMode = id match { - case "none" => NoOpt - case "fast" => FastOpt - case "full" => FullOpt - case _ => sys.error(s"Unknown optimization mode: $id") + case "none" => NoOpt + case "fast" => FastOpt + case "full" => FullOpt + case _ => throw new IllegalArgumentException(s"Unknown optimization mode: $id") } } case object NoOpt extends OptMode { diff --git a/project/Build.scala b/project/Build.scala index 18565901d3..628330d205 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -242,8 +242,10 @@ object Build { } } (docPaths.keySet + additionalStylesFile) - if (errorsSeen.size > 0) sys.error("ScalaDoc patching had errors") - else outDir + if (errorsSeen.size > 0) + throw new MessageOnlyException("ScalaDoc patching had errors") + + outDir } ) @@ -628,7 +630,7 @@ object Build { test := { val jsEnv = resolvedJSEnv.value if (!jsEnv.isInstanceOf[NodeJSEnv]) - sys.error("toolsJS/test must be run with Node.js") + throw new MessageOnlyException("toolsJS/test must be run with Node.js") /* Collect IR relevant files from the classpath * We assume here that the classpath is valid. This is checked by the @@ -906,7 +908,8 @@ object Build { configuration = Set("compile"), module = moduleFilter(name = "scala-library"), artifact = artifactFilter(classifier = "sources")).headOption.getOrElse { - sys.error(s"Could not fetch scala-library sources for version $ver") + throw new Exception( + s"Could not fetch scala-library sources for version $ver") } FileFunction.cached(cacheDir / s"fetchScalaSource-$ver", @@ -1279,7 +1282,8 @@ object Build { val baseArgs = Seq("nodejs", "typedarray") if (env.sourceMap) { if (!env.hasSourceMapSupport) { - sys.error("You must install Node.js source map support to " + + throw new MessageOnlyException( + "You must install Node.js source map support to " + "run the full Scala.js test suite (npm install " + "source-map-support). To deactivate source map " + "tests, do: set jsEnv in " + thisProject.value.id + @@ -1430,7 +1434,8 @@ object Build { // Fail if we are not in the right stage. testHtmlKey in Test := (testHtmlKey in Test).dependsOn(Def.task { if (scalaJSStage.value != targetStage) { - sys.error("In the Scala.js test-suite, the testHtml* tasks need " + + throw new MessageOnlyException( + "In the Scala.js test-suite, the testHtml* tasks need " + "scalaJSStage to be set to their respecitve stage. Stage is: " + scalaJSStage.value) } @@ -1511,7 +1516,7 @@ object Build { val unitTests = (0 until i).map(i => s"@Test def workTest$i(): Unit = test($i)").mkString("; ") IO.write(outFile, - replaced.replace("@Test def workTest(): Unit = sys.error(\"stubs\")", unitTests)) + replaced.replace("@Test def workTest(): Unit = ???", unitTests)) Seq(outFile) }.taskValue, diff --git a/project/ExternalCompile.scala b/project/ExternalCompile.scala index d99a5d8ce0..4c9018d341 100644 --- a/project/ExternalCompile.scala +++ b/project/ExternalCompile.scala @@ -72,12 +72,13 @@ object ExternalCompile { def doCompile(sourcesArgs: List[String]): Unit = { val run = (runner in compile).value - run.run("scala.tools.nsc.Main", compilerCp, + val optErrorMsg = run.run("scala.tools.nsc.Main", compilerCp, "-cp" :: cpStr :: "-d" :: classesDirectory.getAbsolutePath() :: options ++: sourcesArgs, - patchedLogger) foreach sys.error + patchedLogger) + optErrorMsg.foreach(errorMsg => throw new Exception(errorMsg)) } /* Crude way of overcoming the Windows limitation on command line diff --git a/sbt-plugin-test/project/Jetty9Test.scala b/sbt-plugin-test/project/Jetty9Test.scala index 809b1bd94e..dc025a756a 100644 --- a/sbt-plugin-test/project/Jetty9Test.scala +++ b/sbt-plugin-test/project/Jetty9Test.scala @@ -55,7 +55,7 @@ object Jetty9Test { val msg = runner.receive() val expected = "It works!" if (msg != expected) - sys.error(s"""received "$msg" instead of "$expected"""") + throw new AssertionError(s"""received "$msg" instead of "$expected"""") } finally { runner.close() jetty.stop() diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 9cd93942bd..f21cd12b5e 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -363,7 +363,8 @@ object ScalaJSPluginInternal { results += collectFile(file, relPath) } } else { - sys.error("Illegal classpath entry: " + cpEntry.getPath) + throw new IllegalArgumentException( + "Illegal classpath entry: " + cpEntry.getPath) } } @@ -459,7 +460,9 @@ object ScalaJSPluginInternal { // 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") + throw new MessageOnlyException( + "Cannot write launcher file, since there is no or multiple " + + "mainClasses") } } } @@ -591,7 +594,7 @@ object ScalaJSPluginInternal { // 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") + throw new MessageOnlyException("Scala.js cannot be run in a forked JVM") else true }, @@ -616,7 +619,8 @@ object ScalaJSPluginInternal { javaOptions.value.map { case javaSysPropsPattern(propName, propValue) => (propName, propValue) case opt => - sys.error("Scala.js javaOptions can only be \"-D=\"," + + throw new MessageOnlyException( + "Scala.js javaOptions can only be \"-D=\"," + " but received: " + opt) }.toMap }, @@ -789,7 +793,7 @@ object ScalaJSPluginInternal { } else { Def.task { (mainClass in scalaJSLauncherInternal).value.fold { - sys.error("No main class detected.") + throw new MessageOnlyException("No main class detected.") } { mainClass => val moduleKind = scalaJSModuleKind.value val moduleIdentifier = scalaJSModuleIdentifier.value @@ -855,7 +859,8 @@ object ScalaJSPluginInternal { case jsEnv: ComJSEnv => jsEnv case jsEnv => - sys.error(s"You need a ComJSEnv to test (found ${jsEnv.name})") + throw new MessageOnlyException( + s"You need a ComJSEnv to test (found ${jsEnv.name})") } val moduleKind = scalaJSModuleKind.value diff --git a/scalalib/overrides-2.10/scala/collection/immutable/RedBlackTree.scala b/scalalib/overrides-2.10/scala/collection/immutable/RedBlackTree.scala index 4aa4b4f63a..c31931da2f 100644 --- a/scalalib/overrides-2.10/scala/collection/immutable/RedBlackTree.scala +++ b/scalalib/overrides-2.10/scala/collection/immutable/RedBlackTree.scala @@ -168,7 +168,7 @@ object RedBlackTree { } def subl(t: Tree[A, B]) = if (t.isInstanceOf[BlackTree[_, _]]) t.red - else sys.error("Defect: invariance violation; expected black, got "+t) + else throw new IllegalStateException("Defect: invariance violation; expected black, got "+t) def balLeft(x: A, xv: B, tl: Tree[A, B], tr: Tree[A, B]) = if (isRedTree(tl)) { RedTree(x, xv, tl.black, tr) @@ -177,7 +177,7 @@ object RedBlackTree { } else if (isRedTree(tr) && isBlackTree(tr.left)) { RedTree(tr.left.key, tr.left.value, BlackTree(x, xv, tl, tr.left.left), balance(tr.key, tr.value, tr.left.right, subl(tr.right))) } else { - sys.error("Defect: invariance violation") + throw new IllegalStateException("Defect: invariance violation") } def balRight(x: A, xv: B, tl: Tree[A, B], tr: Tree[A, B]) = if (isRedTree(tr)) { RedTree(x, xv, tl, tr.black) @@ -186,7 +186,7 @@ object RedBlackTree { } else if (isRedTree(tl) && isBlackTree(tl.right)) { RedTree(tl.right.key, tl.right.value, balance(tl.key, tl.value, subl(tl.left), tl.right.left), BlackTree(x, xv, tl.right.right, tr)) } else { - sys.error("Defect: invariance violation") + throw new IllegalStateException("Defect: invariance violation") } def delLeft = if (isBlackTree(tree.left)) balLeft(tree.key, tree.value, del(tree.left, k), tree.right) else RedTree(tree.key, tree.value, del(tree.left, k), tree.right) def delRight = if (isBlackTree(tree.right)) balRight(tree.key, tree.value, tree.left, del(tree.right, k)) else RedTree(tree.key, tree.value, tree.left, del(tree.right, k)) @@ -213,7 +213,7 @@ object RedBlackTree { } else if (isRedTree(tl)) { RedTree(tl.key, tl.value, tl.left, append(tl.right, tr)) } else { - sys.error("unmatched tree on append: " + tl + ", " + tr) + throw new IllegalStateException("unmatched tree on append: " + tl + ", " + tr) } val cmp = ordering.compare(k, tree.key) @@ -334,7 +334,7 @@ object RedBlackTree { val leftMost = false (unzip(left :: leftZipper, leftMost), false, leftMost, smallerDepth) } else { - sys.error("unmatched trees in unzip: " + left + ", " + right) + throw new IllegalStateException("unmatched trees in unzip: " + left + ", " + right) } } unzipBoth(left, right, Nil, Nil, 0) @@ -346,7 +346,7 @@ object RedBlackTree { case head :: tail if isBlackTree(head) => if (depth == 1) zipper else findDepth(tail, depth - 1) case _ :: tail => findDepth(tail, depth) - case Nil => sys.error("Defect: unexpected empty zipper while computing range") + case Nil => throw new IllegalStateException("Defect: unexpected empty zipper while computing range") } // Blackening the smaller tree avoids balancing problems on union; diff --git a/scalalib/overrides/scala/collection/immutable/RedBlackTree.scala b/scalalib/overrides/scala/collection/immutable/RedBlackTree.scala index 31e59642d9..0e678d703e 100644 --- a/scalalib/overrides/scala/collection/immutable/RedBlackTree.scala +++ b/scalalib/overrides/scala/collection/immutable/RedBlackTree.scala @@ -194,7 +194,7 @@ object RedBlackTree { } def subl(t: Tree[A, B]) = if (t.isInstanceOf[BlackTree[_, _]]) t.red - else sys.error("Defect: invariance violation; expected black, got "+t) + else throw new IllegalStateException("Defect: invariance violation; expected black, got "+t) def balLeft(x: A, xv: B, tl: Tree[A, B], tr: Tree[A, B]) = if (isRedTree(tl)) { RedTree(x, xv, tl.black, tr) @@ -203,7 +203,7 @@ object RedBlackTree { } else if (isRedTree(tr) && isBlackTree(tr.left)) { RedTree(tr.left.key, tr.left.value, BlackTree(x, xv, tl, tr.left.left), balance(tr.key, tr.value, tr.left.right, subl(tr.right))) } else { - sys.error("Defect: invariance violation") + throw new IllegalStateException("Defect: invariance violation") } def balRight(x: A, xv: B, tl: Tree[A, B], tr: Tree[A, B]) = if (isRedTree(tr)) { RedTree(x, xv, tl, tr.black) @@ -212,7 +212,7 @@ object RedBlackTree { } else if (isRedTree(tl) && isBlackTree(tl.right)) { RedTree(tl.right.key, tl.right.value, balance(tl.key, tl.value, subl(tl.left), tl.right.left), BlackTree(x, xv, tl.right.right, tr)) } else { - sys.error("Defect: invariance violation") + throw new IllegalStateException("Defect: invariance violation") } def delLeft = if (isBlackTree(tree.left)) balLeft(tree.key, tree.value, del(tree.left, k), tree.right) else RedTree(tree.key, tree.value, del(tree.left, k), tree.right) def delRight = if (isBlackTree(tree.right)) balRight(tree.key, tree.value, tree.left, del(tree.right, k)) else RedTree(tree.key, tree.value, tree.left, del(tree.right, k)) @@ -239,7 +239,7 @@ object RedBlackTree { } else if (isRedTree(tl)) { RedTree(tl.key, tl.value, tl.left, append(tl.right, tr)) } else { - sys.error("unmatched tree on append: " + tl + ", " + tr) + throw new IllegalStateException("unmatched tree on append: " + tl + ", " + tr) } val cmp = ordering.compare(k, tree.key) @@ -359,7 +359,7 @@ object RedBlackTree { val leftMost = false (unzip(cons(left, leftZipper), leftMost), false, leftMost, smallerDepth) } else { - sys.error("unmatched trees in unzip: " + left + ", " + right) + throw new IllegalStateException("unmatched trees in unzip: " + left + ", " + right) } } unzipBoth(left, right, null, null, 0) @@ -370,7 +370,7 @@ object RedBlackTree { @tailrec def findDepth(zipper: NList[Tree[A, B]], depth: Int): NList[Tree[A, B]] = if (zipper eq null) { - sys.error("Defect: unexpected empty zipper while computing range") + throw new IllegalStateException("Defect: unexpected empty zipper while computing range") } else if (isBlackTree(zipper.head)) { if (depth == 1) zipper else findDepth(zipper.tail, depth - 1) } else { diff --git a/test-suite/js/src/test/resources/SourceMapTestTemplate.scala b/test-suite/js/src/test/resources/SourceMapTestTemplate.scala index 51b510b3fd..189226833d 100644 --- a/test-suite/js/src/test/resources/SourceMapTestTemplate.scala +++ b/test-suite/js/src/test/resources/SourceMapTestTemplate.scala @@ -40,14 +40,14 @@ object SourceMapTest { class SourceMapTest { - @Test def workTest(): Unit = sys.error("stubs") + @Test def workTest(): Unit = ??? def test(i: Int): Unit = { TC.testNum = i try { run() - sys.error("No exception thrown") + throw new AssertionError("No exception thrown") } catch { case e @ TestException(lineNo) => def normFileName(e: StackTraceElement): String = diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala index adb17d4215..83fee1337f 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala @@ -63,7 +63,7 @@ class OptimizerTest { val elements = js.Array[Int]() for (i <- start0 to 2 by -1) { if (i < 0) - sys.error("Going into infinite loop") + throw new AssertionError("Going into infinite loop") elements.push(i) } assertArrayEquals(Array(10, 9, 8, 7, 6, 5, 4, 3, 2), elements.toArray) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala index 0fd408c135..805e4dcae1 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala @@ -253,7 +253,7 @@ class RegressionTest { assertThrows(classOf[Exception], (giveMeANull(): StringBuilder).append(5)) assertThrows(classOf[Exception], (giveMeANull(): scala.runtime.IntRef).elem) - def giveMeANothing(): Nothing = sys.error("boom") + def giveMeANothing(): Nothing = throw new Exception("boom") assertThrows(classOf[Exception], (giveMeANothing(): StringBuilder).append(5)) assertThrows(classOf[Exception], (giveMeANothing(): scala.runtime.IntRef).elem) } diff --git 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 index 5e3449b39a..620ffadc28 100644 --- 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 @@ -52,7 +52,7 @@ object QuickLinker { } IRContainer.File(vf) } else { - sys.error("Illegal IR file / Jar: " + file) + throw new IllegalArgumentException("Illegal IR file / Jar: " + file) } } diff --git a/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala b/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala index 0abb9e22ff..60d5bed457 100644 --- a/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala +++ b/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala @@ -37,7 +37,7 @@ object TestRunner { } if (eventHandler.hasFailed) - sys.error("Some tests have failed") + throw new AssertionError("Some tests have failed") } private class SimpleEventHandler extends EventHandler { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala index 5075a5df87..6b94348875 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala @@ -184,7 +184,8 @@ object LinkedClass { classExports += e case tree => - sys.error(s"Illegal tree in ClassDef of class ${tree.getClass}") + throw new IllegalArgumentException( + s"Illegal tree in ClassDef of class ${tree.getClass}") } val classExportInfo = memberInfoByName.get(Definitions.ClassExportsName) diff --git 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 index 854c460241..d3db25fc75 100644 --- 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 @@ -448,7 +448,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { pushLhsInto(Lhs.Assign(lhs), rhs, tailPosLabels) case Assign(_, _) => - sys.error(s"Illegal Assign in transformStat: $tree") + throw new IllegalArgumentException( + s"Illegal Assign in transformStat: $tree") case StoreModule(cls, value) => unnest(value) { (newValue, env0) => @@ -516,7 +517,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { implicit val env = env0 val enclosingClassName = env.enclosingClassName.getOrElse { - sys.error("Need enclosing class for super constructor call.") + throw new AssertionError( + "Need enclosing class for super constructor call.") } val superCtorCall = { @@ -1624,14 +1626,16 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { _:StoreModule | _:ClassDef => transformStat(rhs, tailPosLabels) case _ => - sys.error("Illegal tree in JSDesugar.pushLhsInto():\n" + - "lhs = " + lhs + "\n" + "rhs = " + rhs + - " of class " + rhs.getClass) + throw new IllegalArgumentException( + "Illegal tree in JSDesugar.pushLhsInto():\n" + + "lhs = " + lhs + "\n" + + "rhs = " + rhs + " of class " + rhs.getClass) } } else { - sys.error("Illegal tree in JSDesugar.pushLhsInto():\n" + - "lhs = " + lhs + "\n" + "rhs = " + rhs + - " of class " + rhs.getClass) + throw new IllegalArgumentException( + "Illegal tree in JSDesugar.pushLhsInto():\n" + + "lhs = " + lhs + "\n" + + "rhs = " + rhs + " of class " + rhs.getClass) } }) } @@ -2143,8 +2147,9 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { // Invalid trees case _ => - sys.error("Invalid tree in JSDesugar.transformExpr() "+ - s"of class ${tree.getClass}") + throw new IllegalArgumentException( + "Invalid tree in JSDesugar.transformExpr() of class " + + tree.getClass) } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index 3d2aac3aa3..cb589bc4d1 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -298,7 +298,8 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, classExports += e case tree => - sys.error(s"Illegal tree in ClassDef of class ${tree.getClass}") + throw new IllegalArgumentException( + s"Illegal tree in ClassDef of class ${tree.getClass}") } // Synthetic members diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index e1d3fc09d2..5522acc83c 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -673,7 +673,8 @@ private[optimizer] abstract class OptimizerCore( tree case _ => - sys.error(s"Invalid tree in transform of class ${tree.getClass.getName}: $tree") + throw new IllegalArgumentException( + s"Invalid tree in transform of class ${tree.getClass.getName}: $tree") } if (isStat) keepOnlySideEffects(result) @@ -778,17 +779,23 @@ private[optimizer] abstract class OptimizerCore( pretransformBlock(tree)(cont) case VarRef(Ident(name, _)) => - val localDef = scope.env.localDefs.getOrElse(name, - sys.error(s"Cannot find local def '$name' at $pos\n" + - s"While optimizing $myself\n" + - s"Env is ${scope.env}\nInlining ${scope.implsBeingInlined}")) + val localDef = scope.env.localDefs.getOrElse(name, { + throw new AssertionError( + s"Cannot find local def '$name' at $pos\n" + + s"While optimizing $myself\n" + + s"Env is ${scope.env}\n" + + s"Inlining ${scope.implsBeingInlined}") + }) cont(localDef.toPreTransform) case This() => - val localDef = scope.env.localDefs.getOrElse("this", - sys.error(s"Found invalid 'this' at $pos\n" + - s"While optimizing $myself\n" + - s"Env is ${scope.env}\nInlining ${scope.implsBeingInlined}")) + val localDef = scope.env.localDefs.getOrElse("this", { + throw new AssertionError( + s"Found invalid 'this' at $pos\n" + + s"While optimizing $myself\n" + + s"Env is ${scope.env}\n" + + s"Inlining ${scope.implsBeingInlined}") + }) cont(localDef.toPreTransform) case tree: If => @@ -4159,7 +4166,7 @@ private[optimizer] abstract class OptimizerCore( } } - sys.error("Reached end of infinite loop") + throw new AssertionError("Reached end of infinite loop") } finally { curTrampolineId -= 1 } From 92fd5e2cee462b61f43c0083ad2fe441ffa1928e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 26 May 2017 21:56:57 +0200 Subject: [PATCH 0279/2665] Avoid `scala.compat._`. --- scalalib/overrides-2.10/scala/Array.scala | 2 +- scalalib/overrides/scala/App.scala | 2 +- scalalib/overrides/scala/Array.scala | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scalalib/overrides-2.10/scala/Array.scala b/scalalib/overrides-2.10/scala/Array.scala index 773c12928a..93e07028e0 100644 --- a/scalalib/overrides-2.10/scala/Array.scala +++ b/scalalib/overrides-2.10/scala/Array.scala @@ -11,7 +11,7 @@ package scala import scala.collection.generic._ import scala.collection.{ mutable, immutable } import mutable.{ ArrayBuilder, ArraySeq } -import scala.compat.Platform.arraycopy +import java.lang.System.arraycopy import scala.reflect.ClassTag import scala.runtime.ScalaRunTime.{ array_apply, array_update } diff --git a/scalalib/overrides/scala/App.scala b/scalalib/overrides/scala/App.scala index c49817b4c4..ff5f073f6d 100644 --- a/scalalib/overrides/scala/App.scala +++ b/scalalib/overrides/scala/App.scala @@ -8,7 +8,7 @@ package scala -import scala.compat.Platform.currentTime +import java.lang.System.{currentTimeMillis => currentTime} import scala.collection.mutable.ListBuffer import scala.scalajs.js.annotation.JSExport diff --git a/scalalib/overrides/scala/Array.scala b/scalalib/overrides/scala/Array.scala index e4e8b64b61..22cace2c7a 100644 --- a/scalalib/overrides/scala/Array.scala +++ b/scalalib/overrides/scala/Array.scala @@ -11,7 +11,7 @@ package scala import scala.collection.generic._ import scala.collection.{ mutable, immutable } import mutable.{ ArrayBuilder, ArraySeq } -import scala.compat.Platform.arraycopy +import java.lang.System.arraycopy import scala.reflect.ClassTag import scala.runtime.ScalaRunTime.{ array_apply, array_update } From 03ed07a6a16cf773fe1cbbd14beabc17aa13673e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 26 May 2017 22:12:22 +0200 Subject: [PATCH 0280/2665] Avoid using `sys.env`. Use `System.getenv` instead. --- .../src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala | 6 ++++-- .../scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala | 7 ++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala index d58bc6cfec..858d64db1e 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala @@ -7,6 +7,7 @@ import org.scalajs.core.tools.jsdep.ResolvedJSDependency import java.io.{ Console => _, _ } import scala.io.Source +import scala.collection.JavaConverters._ import scala.concurrent.{Future, Promise} import scala.util.Try @@ -67,10 +68,11 @@ abstract class ExternalJSEnv( /** VM environment. Override to adapt. * - * The default value in `ExternalJSEnv` is `sys.env ++ env`. + * The default value in `ExternalJSEnv` is + * `System.getenv().asScala.toMap ++ env`. */ protected def getVMEnv(): Map[String, String] = - sys.env ++ env + System.getenv().asScala.toMap ++ env /** Get files that are a library (i.e. that do not run anything) */ protected def getLibJSFiles(): Seq[VirtualJSFile] = diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala index a5304b63e5..9052e1c716 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala @@ -19,6 +19,7 @@ import org.scalajs.core.tools.logging.NullLogger import org.scalajs.jsenv._ import org.scalajs.jsenv.Utils.OptDeadline +import scala.collection.JavaConverters._ import scala.concurrent.TimeoutException import scala.concurrent.duration._ @@ -139,14 +140,14 @@ abstract class AbstractNodeJSEnv( // Node.js specific (system) environment override protected def getVMEnv(): Map[String, String] = { - val baseNodePath = sys.env.get("NODE_PATH").filter(_.nonEmpty) + val baseNodePath = Option(System.getenv("NODE_PATH")).filter(_.nonEmpty) val nodePath = libCache.cacheDir.getAbsolutePath + baseNodePath.fold("")(p => File.pathSeparator + p) - sys.env ++ Seq( + System.getenv().asScala.toMap ++ Seq( "NODE_MODULE_CONTEXTS" -> "0", "NODE_PATH" -> nodePath - ) ++ additionalEnv + ) ++ env } } From 46923bafdb56e2cf51650e5c6e6055c825dde9d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 26 May 2017 17:23:02 +0200 Subject: [PATCH 0281/2665] [no-master] Add an option -P:scalajs:sjsDefinedByDefault. When enabled, this option switches the default for js.Any things from `@js.native` (0.6.x style) to `@ScalaJSDefined` (1.x style). The option only applies to source files in the current run, not to things loaded from the classpath. This option is intended as a nicer transition between 0.6.x and 1.x. For a time, users will want to cross-compile their codebases. But there is no way to have Scala.js-defined JS classes that compile without deprecation warnings under the two versions. This option fixes that. The codebase can be written in 1.x style, and the option activated when `scalaJSVersion.startsWith("0.6.")`. The content of this commit should not reach the `master` branch. --- .../scalajs/core/compiler/PrepJSExports.scala | 2 +- .../scalajs/core/compiler/PrepJSInterop.scala | 23 +- .../core/compiler/ScalaJSOptions.scala | 5 + .../scalajs/core/compiler/ScalaJSPlugin.scala | 3 + .../test/SJSDefinedByDefaultTest.scala | 312 ++++++++++++++++++ 5 files changed, 342 insertions(+), 3 deletions(-) create mode 100644 compiler/src/test/scala/org/scalajs/core/compiler/test/SJSDefinedByDefaultTest.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala index 9c4f9f93e6..e375b2c3ff 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala @@ -416,7 +416,7 @@ trait PrepJSExports { this: PrepJSInterop => companion != NoSymbol && !companion.isTrait && isJSAny(companion) && - companion.hasAnnotation(ScalaJSDefinedAnnotation) + isScalaJSDefinedAcrossRuns(companion) } if (!symOwner.isStatic || !symOwner.isModuleClass || diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 0d620ba11e..32e024bfe7 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -483,7 +483,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent def isNativeJSTraitType(tpe: Type): Boolean = { val sym = tpe.typeSymbol - sym.isTrait && !sym.hasAnnotation(ScalaJSDefinedAnnotation) + sym.isTrait && !isScalaJSDefinedAcrossRuns(sym) } val isJSAnonFun = isJSLambda(sym) @@ -494,6 +494,14 @@ abstract class PrepJSInterop extends plugins.PluginComponent sym.addAnnotation(SJSDefinedAnonymousClassAnnotation) } + // Honor -P:scalajs:sjsDefinedByDefault + if (scalaJSOpts.sjsDefinedByDefault) { + if (!isJSAnonFun && !sym.hasAnnotation(JSNativeAnnotation) && + !sym.hasAnnotation(ScalaJSDefinedAnnotation)) { + sym.addAnnotation(ScalaJSDefinedAnnotation) + } + } + /* Convert `extends js.GlobalScope` to `@JSGlobalScope`. * No warning because `js.GlobalScope` already causes a deprecation * warning. @@ -697,7 +705,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent if (!isJSNative) { def isJSOptional(sym: Symbol): Boolean = { sym.owner.isTrait && !sym.isDeferred && !sym.isConstructor && - sym.owner.hasAnnotation(ScalaJSDefinedAnnotation) + isScalaJSDefinedAcrossRuns(sym.owner) } if (isJSOptional(low) && !(high.isDeferred || isJSOptional(high))) { @@ -1503,6 +1511,17 @@ abstract class PrepJSInterop extends plugins.PluginComponent !sym.isLocalToBlock && !sym.isSynthetic && !isPrivateMaybeWithin(sym) } + protected def isScalaJSDefinedAcrossRuns(sym: Symbol): Boolean = { + val sjsDefinedByDefaultAppliesToSym = { + scalaJSOpts.sjsDefinedByDefault && + (sym.sourceFile ne null) // it is compiled from source, i.e., not loaded from .class + } + if (sjsDefinedByDefaultAppliesToSym) + !sym.hasAnnotation(JSNativeAnnotation) + else + sym.hasAnnotation(ScalaJSDefinedAnnotation) + } + private def wasPublicBeforeTyper(sym: Symbol): Boolean = sym.hasAnnotation(WasPublicBeforeTyperClass) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala index 2008d5f26b..b80afd935f 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala @@ -29,6 +29,11 @@ trait ScalaJSOptions { * should they be mapped to)? */ def sourceURIMaps: List[URIMap] + /** Switch the default for JS types from `@js.native` to `@ScalaJSDefined`. + * This is intended as a transition option between 0.6.x and 1.x. + */ + def sjsDefinedByDefault: Boolean + } object ScalaJSOptions { diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala index d49db4c23d..878bb97bc5 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala @@ -55,6 +55,7 @@ class ScalaJSPlugin(val global: Global) extends NscPlugin { var _sourceURIMaps: List[URIMap] = Nil var relSourceMap: Option[URI] = None var absSourceMap: Option[URI] = None + var sjsDefinedByDefault: Boolean = false } /** Checks and registers module exports on the symbol. @@ -131,6 +132,8 @@ class ScalaJSPlugin(val global: Global) extends NscPlugin { catch { case e: URISyntaxException => error(s"$uriStr is not a valid URI") } + } else if (option == "sjsDefinedByDefault") { + sjsDefinedByDefault = true } else { error("Option not understood: " + option) } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/SJSDefinedByDefaultTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/SJSDefinedByDefaultTest.scala new file mode 100644 index 0000000000..202ee3d96e --- /dev/null +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/SJSDefinedByDefaultTest.scala @@ -0,0 +1,312 @@ +package org.scalajs.core.compiler.test + +import org.scalajs.core.compiler.test.util._ + +import org.junit.Test +import org.junit.Ignore + +// scalastyle:off line.size.limit + +class SJSDefinedByDefaultTest extends DirectTest with TestHelpers { + + /* We add the compiler's output path itself to the classpath, for tests + * involving separate compilation. + */ + override def classpath: List[String] = + super.classpath ++ List(testOutputPath) + + override def extraArgs: List[String] = + super.extraArgs :+ "-P:scalajs:sjsDefinedByDefault" + + override def preamble: String = + """ + import scala.scalajs.js + import scala.scalajs.js.annotation._ + """ + + @Test + def noWarnNoJSNativeAnnotation: Unit = { + + """ + class A extends js.Object + """.hasNoWarns() + + """ + object A extends js.Object + """.hasNoWarns() + + """ + trait A extends js.Object + """.hasNoWarns() + + } + + @Test + def treatedAsSJSDefined: Unit = { + + """ + class A extends js.Object { + def foo(): Int = js.native + } + """ hasErrors + """ + |newSource1.scala:6: error: js.native may only be used as stub implementation in facade types + | def foo(): Int = js.native + | ^ + """ + + """ + object A extends js.Object { + def foo(): Int = js.native + } + """ hasErrors + """ + |newSource1.scala:6: error: js.native may only be used as stub implementation in facade types + | def foo(): Int = js.native + | ^ + """ + + """ + trait A extends js.Object { + def foo(): Int = js.native + } + """ hasErrors + """ + |newSource1.scala:6: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. + | def foo(): Int = js.native + | ^ + """ + + } + + @Test + def noExtendNativeTrait: Unit = { + """ + @js.native + trait NativeTrait extends js.Object + + class A extends NativeTrait + + trait B extends NativeTrait + + object C extends NativeTrait + + object Container { + val x = new NativeTrait {} + } + """ hasErrors + """ + |newSource1.scala:8: error: A Scala.js-defined JS class cannot directly extend a native JS trait. + | class A extends NativeTrait + | ^ + |newSource1.scala:10: error: A Scala.js-defined JS trait cannot directly extend a native JS trait. + | trait B extends NativeTrait + | ^ + |newSource1.scala:12: error: A Scala.js-defined JS object cannot directly extend a native JS trait. + | object C extends NativeTrait + | ^ + |newSource1.scala:15: error: A Scala.js-defined JS class cannot directly extend a native JS trait. + | val x = new NativeTrait {} + | ^ + """ + } + + @Test + def noExtendNativeTraitSeparateCompilation: Unit = { + """ + @js.native + trait NativeTrait extends js.Object + """.succeeds() + + """ + class A extends NativeTrait + + trait B extends NativeTrait + + object C extends NativeTrait + + object Container { + val x = new NativeTrait {} + } + """ hasErrors + """ + |newSource1.scala:5: error: A Scala.js-defined JS class cannot directly extend a native JS trait. + | class A extends NativeTrait + | ^ + |newSource1.scala:7: error: A Scala.js-defined JS trait cannot directly extend a native JS trait. + | trait B extends NativeTrait + | ^ + |newSource1.scala:9: error: A Scala.js-defined JS object cannot directly extend a native JS trait. + | object C extends NativeTrait + | ^ + |newSource1.scala:12: error: A Scala.js-defined JS class cannot directly extend a native JS trait. + | val x = new NativeTrait {} + | ^ + """ + } + + @Test + def noOverrideConcreteNonOptionalWithOptional: Unit = { + """ + abstract class A extends js.Object { + val a1: js.UndefOr[Int] = 5 + val a2: js.UndefOr[Int] + + def b1: js.UndefOr[Int] = 5 + def b2: js.UndefOr[Int] + } + + trait B extends A { + override val a1: js.UndefOr[Int] = js.undefined + override val a2: js.UndefOr[Int] = js.undefined + + override def b1: js.UndefOr[Int] = js.undefined + override def b2: js.UndefOr[Int] = js.undefined + } + """ hasErrors + """ + |newSource1.scala:14: error: Cannot override concrete val a1: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + | override val a1: js.UndefOr[Int] = js.undefined + | ^ + |newSource1.scala:17: error: Cannot override concrete def b1: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + | override def b1: js.UndefOr[Int] = js.undefined + | ^ + """ + + """ + @js.native + @JSGlobal + class A extends js.Object { + val a: js.UndefOr[Int] = js.native + def b: js.UndefOr[Int] = js.native + } + + trait B extends A { + override val a: js.UndefOr[Int] = js.undefined + override def b: js.UndefOr[Int] = js.undefined + } + """ hasErrors + """ + |newSource1.scala:13: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + | override val a: js.UndefOr[Int] = js.undefined + | ^ + |newSource1.scala:14: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + | override def b: js.UndefOr[Int] = js.undefined + | ^ + """ + + """ + @js.native + trait A extends js.Object { + val a: js.UndefOr[Int] = js.native + def b: js.UndefOr[Int] = js.native + } + + @js.native + @JSGlobal + class B extends A + + trait C extends B { + override val a: js.UndefOr[Int] = js.undefined + override def b: js.UndefOr[Int] = js.undefined + } + """ hasErrors + """ + |newSource1.scala:16: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + | override val a: js.UndefOr[Int] = js.undefined + | ^ + |newSource1.scala:17: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + | override def b: js.UndefOr[Int] = js.undefined + | ^ + """ + } + + @Test + def noOverrideConcreteNonOptionalWithOptionalSeparateCompilation1: Unit = { + """ + abstract class A extends js.Object { + val a1: js.UndefOr[Int] = 5 + val a2: js.UndefOr[Int] + + def b1: js.UndefOr[Int] = 5 + def b2: js.UndefOr[Int] + } + """.succeeds() + + """ + trait B extends A { + override val a1: js.UndefOr[Int] = js.undefined + override val a2: js.UndefOr[Int] = js.undefined + + override def b1: js.UndefOr[Int] = js.undefined + override def b2: js.UndefOr[Int] = js.undefined + } + """ hasErrors + """ + |newSource1.scala:6: error: Cannot override concrete val a1: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + | override val a1: js.UndefOr[Int] = js.undefined + | ^ + |newSource1.scala:9: error: Cannot override concrete def b1: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + | override def b1: js.UndefOr[Int] = js.undefined + | ^ + """ + } + + @Test + def noOverrideConcreteNonOptionalWithOptionalSeparateCompilation2: Unit = { + """ + @js.native + @JSGlobal + class A extends js.Object { + val a: js.UndefOr[Int] = js.native + def b: js.UndefOr[Int] = js.native + } + """.succeeds() + + """ + trait B extends A { + override val a: js.UndefOr[Int] = js.undefined + override def b: js.UndefOr[Int] = js.undefined + } + """ hasErrors + """ + |newSource1.scala:6: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + | override val a: js.UndefOr[Int] = js.undefined + | ^ + |newSource1.scala:7: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + | override def b: js.UndefOr[Int] = js.undefined + | ^ + """ + } + + @Test + def noOverrideConcreteNonOptionalWithOptionalSeparateCompilation3: Unit = { + """ + @js.native + trait A extends js.Object { + val a: js.UndefOr[Int] = js.native + def b: js.UndefOr[Int] = js.native + } + + @js.native + @JSGlobal + class B extends A + """.succeeds() + + """ + trait C extends B { + override val a: js.UndefOr[Int] = js.undefined + override def b: js.UndefOr[Int] = js.undefined + } + """ hasErrors + """ + |newSource1.scala:6: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + | override val a: js.UndefOr[Int] = js.undefined + | ^ + |newSource1.scala:7: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + | override def b: js.UndefOr[Int] = js.undefined + | ^ + """ + } + +} From c1cc9d5fde650bf39a73a70d3bbd6f1196f0fa3d Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 7 May 2017 21:37:36 +0200 Subject: [PATCH 0282/2665] Fix #2927: Fail on assertEquals on floats/doubles --- .../src/main/scala/org/junit/Assert.scala | 20 +++ .../junit/AssertEqualsDoubleTest.scala | 50 +++++++ project/Build.scala | 2 +- .../testsuite/compiler/FloatJSTest.scala | 18 +-- ...nstanceTestsHijackedBoxedClassesTest.scala | 2 +- .../testsuite/compiler/OptimizerTest.scala | 4 +- .../testsuite/jsinterop/ExportsTest.scala | 4 +- .../testsuite/jsinterop/JSNameTest.scala | 8 +- .../testsuite/jsinterop/JSSymbolTest.scala | 16 +-- .../testsuite/jsinterop/RuntimeLongTest.scala | 124 ++++++++---------- .../testsuite/typedarray/DataViewTest.scala | 10 +- .../typedarray/TypedArrayConversionTest.scala | 26 ++-- 12 files changed, 173 insertions(+), 111 deletions(-) create mode 100644 junit-test/shared/src/test/scala/org/scalajs/junit/AssertEqualsDoubleTest.scala diff --git a/junit-runtime/src/main/scala/org/junit/Assert.scala b/junit-runtime/src/main/scala/org/junit/Assert.scala index febda63d03..7441af78ab 100644 --- a/junit-runtime/src/main/scala/org/junit/Assert.scala +++ b/junit-runtime/src/main/scala/org/junit/Assert.scala @@ -91,6 +91,26 @@ object Assert { def assertNotEquals(unexpected: Float, actual: Float, delta: Float): Unit = assertNotEquals(null, unexpected, actual, delta) + @deprecated("Use assertEquals(double expected, double actual, double " + + "epsilon) instead", "") + def assertEquals(expected: Double, actual: Double): Unit = { + fail("Use assertEquals(expected, actual, delta) to compare " + + "floating-point numbers") + } + + @deprecated("Use assertEquals(String message, double expected, double " + + "actual, double epsilon) instead", "") + def assertEquals(message: String, expected: Double, actual: Double): Unit = { + fail("Use assertEquals(expected, actual, delta) to compare " + + "floating-point numbers") + } + + def assertEquals(expected: Long, actual: Long): Unit = + assertEquals(null, expected, actual) + + def assertEquals(message: String, expected: Long, actual: Long): Unit = + assertEquals(message, expected: Any, actual: Any) + def assertArrayEquals(message: String, expecteds: Array[AnyRef], actuals: Array[AnyRef]): Unit = { internalArrayEquals(message, expecteds, actuals) diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertEqualsDoubleTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertEqualsDoubleTest.scala new file mode 100644 index 0000000000..13892ce90b --- /dev/null +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertEqualsDoubleTest.scala @@ -0,0 +1,50 @@ +package org.scalajs.junit + +import org.junit.Assert._ +import org.junit.Test + +import org.scalajs.junit.utils._ + +class AssertEqualsDoubleTest { + @Test def failsWithDouble(): Unit = { + assertEquals(1.0, 1.0) + } + + @Test def failsWithDoubleMessage(): Unit = { + assertEquals("Message", 1.0, 1.0) + } + + @Test def worksWithEpsilon(): Unit = { + assertEquals(1.0, 1.0, 0.1) + assertEquals("Message", 1.0, 1.0, 0.1) + } + + @Test def worksWithByte(): Unit = { + // This is supposed to take the (long, long) overload. + assertEquals(1.toByte, 1.toByte) + } + + @Test def worksWithShort(): Unit = { + // This is supposed to take the (long, long) overload. + assertEquals(2.toShort, 2.toShort) + } + + @Test def worksWithInt(): Unit = { + // This is supposed to take the (long, long) overload. + assertEquals(1, 1) + } +} + +class AssertEqualsDoubleTestAssertions extends JUnitTest { + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = { + builder + .success("worksWithEpsilon") + .assertion("failsWithDouble", + "Use assertEquals(expected, actual, delta) to compare floating-point numbers") + .assertion("failsWithDoubleMessage", + "Use assertEquals(expected, actual, delta) to compare floating-point numbers") + .success("worksWithByte") + .success("worksWithShort") + .success("worksWithInt") + } +} diff --git a/project/Build.scala b/project/Build.scala index 9996384f2e..72f11a89d5 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1167,7 +1167,7 @@ object Build { fatalWarningsSettings ++ Seq(name := "Scala.js JUnit test runtime") ).withScalaJSCompiler.dependsOn(testInterface) - val commonJUnitTestOutputsSettings = commonSettings ++ fatalWarningsSettings ++ Seq( + val commonJUnitTestOutputsSettings = commonSettings ++ Seq( publishArtifact in Compile := false, parallelExecution in Test := false, unmanagedSourceDirectories in Test += diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/FloatJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/FloatJSTest.scala index f4377ebb6f..2fe789faa4 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/FloatJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/FloatJSTest.scala @@ -21,25 +21,25 @@ class FloatJSTest { @Test def fround_for_special_values(): Unit = { assertTrue(froundNotInlined(Double.NaN).isNaN) - assertEquals(Double.PositiveInfinity, 1 / froundNotInlined(0.0).toDouble) - assertEquals(Double.NegativeInfinity, 1 / froundNotInlined(-0.0).toDouble) - assertEquals(Float.PositiveInfinity, froundNotInlined(Double.PositiveInfinity)) - assertEquals(Float.NegativeInfinity, froundNotInlined(Double.NegativeInfinity)) + assertEquals(Double.PositiveInfinity, 1 / froundNotInlined(0.0).toDouble, 0.0) + assertEquals(Double.NegativeInfinity, 1 / froundNotInlined(-0.0).toDouble, 0.0) + assertEquals(Float.PositiveInfinity, froundNotInlined(Double.PositiveInfinity), 0.0) + assertEquals(Float.NegativeInfinity, froundNotInlined(Double.NegativeInfinity), 0.0) } @Test def fround_overflows(): Unit = { - assertEquals(Double.PositiveInfinity, froundNotInlined(1e200)) - assertEquals(Double.NegativeInfinity, froundNotInlined(-1e200)) + assertEquals(Double.PositiveInfinity, froundNotInlined(1e200), 0.0) + assertEquals(Double.NegativeInfinity, froundNotInlined(-1e200), 0.0) } @Test def fround_underflows(): Unit = { - assertEquals(Double.PositiveInfinity, 1 / froundNotInlined(1e-300).toDouble) - assertEquals(Double.NegativeInfinity, 1 / froundNotInlined(-1e-300).toDouble) + assertEquals(Double.PositiveInfinity, 1 / froundNotInlined(1e-300).toDouble, 0.0) + assertEquals(Double.NegativeInfinity, 1 / froundNotInlined(-1e-300).toDouble, 0.0) } @Test def fround_normal_cases(): Unit = { def test(input: Double, expected: Double): Unit = - assertEquals(expected, input.toFloat.toDouble) + assertEquals(expected, input.toFloat.toDouble, 0.0) // From MDN documentation test(0.0, 0.0) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InstanceTestsHijackedBoxedClassesTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InstanceTestsHijackedBoxedClassesTest.scala index 71ec90d9ec..59f04736d4 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InstanceTestsHijackedBoxedClassesTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InstanceTestsHijackedBoxedClassesTest.scala @@ -108,7 +108,7 @@ class InstanceTestsHijackedBoxedClassesTest { @Test def asInstanceOf_Float_with_non_strict_floats(): Unit = { assumeFalse("Assumed strict floats", hasStrictFloats) - assertEquals(1.2, (1.2: Any).asInstanceOf[Float]) + assertEquals(1.2, (1.2: Any).asInstanceOf[Float], 0.0) } @Test def should_support_isInstanceOf_via_java_lang_Class_positive(): Unit = { diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala index adb17d4215..3d75465411 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala @@ -49,11 +49,11 @@ class OptimizerTest { @Test def `must_not_break_*_(-1)_for_Float_and_Double_issue_1478`(): Unit = { @noinline def a: Float = (() => 5.0f) () - assertEquals(-5.0f, a * -1.0f) + assertEquals(-5.0f, a * -1.0f, 0.0) @noinline def b: Double = (() => 7.0) () - assertEquals(-7.0, b * -1.0) + assertEquals(-7.0, b * -1.0, 0.0) } @Test def must_not_break_foreach_on_downward_Range_issue_1453(): Unit = { diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index 4177e0d6a8..5e94e0af9b 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -1081,8 +1081,8 @@ class ExportsTest { def doShort(x: Short): Unit = assertEquals(0, x) def doInt(x: Int): Unit = assertEquals(0, x) def doLong(x: Long): Unit = assertTrue(x.equals(0L)) - def doFloat(x: Float): Unit = assertEquals(0.0f, x) - def doDouble(x: Double): Unit = assertEquals(0.0, x) + def doFloat(x: Float): Unit = assertEquals(0.0f, x, 0.0) + def doDouble(x: Double): Unit = assertEquals(0.0, x, 0.0) def doUnit(x: Unit): Unit = assertTrue((x: Any) == null) } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNameTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNameTest.scala index b410d04b6f..0d6f9f5c33 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNameTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNameTest.scala @@ -28,9 +28,9 @@ class JSNameTest { @Test def should_work_with_vars(): Unit = { val obj = js.Dynamic.literal(jsVar = 0.1).asInstanceOf[PropVarFacade] - assertEquals(0.1, obj.internalVar) + assertEquals(0.1, obj.internalVar, 0.0) obj.internalVar = 0.2 - assertEquals(0.2, obj.internalVar) + assertEquals(0.2, obj.internalVar, 0.0) } @Test def should_work_with_defs_that_are_properties_in_Scala_js_defined_trait_issue_2197(): Unit = { @@ -45,9 +45,9 @@ class JSNameTest { @Test def should_work_with_vars_in_Scala_js_defined_trait_issue_2197(): Unit = { val obj = js.Dynamic.literal(jsVar = 0.1).asInstanceOf[PropVarSJSDefined] - assertEquals(0.1, obj.internalVar) + assertEquals(0.1, obj.internalVar, 0.0) obj.internalVar = 0.2 - assertEquals(0.2, obj.internalVar) + assertEquals(0.2, obj.internalVar, 0.0) } @Test def should_allow_names_ending_in__=(): Unit = { diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala index 9608e28652..5b93ac298a 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala @@ -56,14 +56,14 @@ class JSSymbolTest { @Test def native_with_vars(): Unit = { val obj0 = mkObject(sym1 -> 0.1).asInstanceOf[PropVarClass] - assertEquals(0.1, obj0.internalVar) + assertEquals(0.1, obj0.internalVar, 0.0) obj0.internalVar = 0.2 - assertEquals(0.2, obj0.internalVar) + assertEquals(0.2, obj0.internalVar, 0.0) val obj1 = mkObject(sym1 -> 8.0).asInstanceOf[PropVarTrait] - assertEquals(8.0, obj1.internalVar) + assertEquals(8.0, obj1.internalVar, 0.0) obj1.internalVar = 8.2 - assertEquals(8.2, obj1.internalVar) + assertEquals(8.2, obj1.internalVar, 0.0) val obj2 = mkObject(sym1 -> 8.0) assertEquals(8.0, selectSymbol(obj2, sym1)) @@ -73,14 +73,14 @@ class JSSymbolTest { @Test def sjsdefined_with_vars(): Unit = { val obj0 = new SJSDefinedPropVar - assertEquals(1511.1989, obj0.internalVar) + assertEquals(1511.1989, obj0.internalVar, 0.0) obj0.internalVar = 0.2 - assertEquals(0.2, obj0.internalVar) + assertEquals(0.2, obj0.internalVar, 0.0) val obj1: PropVarTrait = new SJSDefinedPropVar - assertEquals(1511.1989, obj1.internalVar) + assertEquals(1511.1989, obj1.internalVar, 0.0) obj1.internalVar = 8.2 - assertEquals(8.2, obj1.internalVar) + assertEquals(8.2, obj1.internalVar, 0.0) val obj2 = new SJSDefinedPropVar assertEquals(1511.1989, selectSymbol(obj2, sym1)) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/RuntimeLongTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/RuntimeLongTest.scala index fb003db4c9..2bfb55f54e 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/RuntimeLongTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/RuntimeLongTest.scala @@ -408,73 +408,65 @@ class RuntimeLongTest { @Test def toFloat_strict(): Unit = { assumeTrue("Assumed strict floats", hasStrictFloats) - assertEquals(0, lg(0).toFloat) - assertEquals(-1, lg(-1).toFloat) - - if (!isInFullOpt) { - assertEquals(9.223372E18f, MaxVal.toFloat) - assertEquals(-9.223372E18f, MinVal.toFloat) - } else { - // Closure seems to incorrectly rewrite the constant on the right :-( - assertEquals(9.223372E18f, MaxVal.toFloat, 1E4f) - assertEquals(-9.223372E18f, MinVal.toFloat, 1E4f) - } - - assertEquals(4.7971489E18f, lg(-1026388143, 1116923232).toFloat) - assertEquals(-2.24047663E18f, lg(-1288678667, -521651607).toFloat) - assertEquals(4.59211416E18f, lg(1192262605, 1069184891).toFloat) - assertEquals(3.38942079E18f, lg(-180353617, 789161022).toFloat) - assertEquals(-6.8076878E18f, lg(-1158443188, -1585038363).toFloat) - assertEquals(7.4159717E18f, lg(906981906, 1726665521).toFloat) - assertEquals(-1.85275997E18f, lg(2042933575, -431379283).toFloat) - assertEquals(5.7344188E18f, lg(599900903, 1335148382).toFloat) - assertEquals(3.20410168E18f, lg(1458166084, 746013039).toFloat) - assertEquals(-7.2310311E18f, lg(1956524672, -1683605603).toFloat) - assertEquals(7.7151362E18f, lg(478583639, 1796320118).toFloat) - assertEquals(1.41365268E18f, lg(-1645816617, 329141676).toFloat) - assertEquals(-3.03197918E18f, lg(184187116, -705937657).toFloat) - assertEquals(-4.04287594E18f, lg(659513335, -941305424).toFloat) - assertEquals(-7.8204678E18f, lg(770505156, -1820844549).toFloat) - assertEquals(-5.9733025E18f, lg(929928858, -1390767911).toFloat) - assertEquals(1.1261721E18f, lg(-1475096259, 262207373).toFloat) - assertEquals(4.00884963E18f, lg(787691795, 933383012).toFloat) - assertEquals(-1.43511611E18f, lg(1189057493, -334139018).toFloat) - assertEquals(3.81415059E18f, lg(-618946450, 888051141).toFloat) + assertEquals(0, lg(0).toFloat, 0.0) + assertEquals(-1, lg(-1).toFloat, 0.0) + + // Closure seems to incorrectly rewrite the constant on the right :-( + val epsilon = if (isInFullOpt) 1E4f else 0.0f + assertEquals(9.223372E18f, MaxVal.toFloat, epsilon) + assertEquals(-9.223372E18f, MinVal.toFloat, epsilon) + + assertEquals(4.7971489E18f, lg(-1026388143, 1116923232).toFloat, 0.0) + assertEquals(-2.24047663E18f, lg(-1288678667, -521651607).toFloat, 0.0) + assertEquals(4.59211416E18f, lg(1192262605, 1069184891).toFloat, 0.0) + assertEquals(3.38942079E18f, lg(-180353617, 789161022).toFloat, 0.0) + assertEquals(-6.8076878E18f, lg(-1158443188, -1585038363).toFloat, 0.0) + assertEquals(7.4159717E18f, lg(906981906, 1726665521).toFloat, 0.0) + assertEquals(-1.85275997E18f, lg(2042933575, -431379283).toFloat, 0.0) + assertEquals(5.7344188E18f, lg(599900903, 1335148382).toFloat, 0.0) + assertEquals(3.20410168E18f, lg(1458166084, 746013039).toFloat, 0.0) + assertEquals(-7.2310311E18f, lg(1956524672, -1683605603).toFloat, 0.0) + assertEquals(7.7151362E18f, lg(478583639, 1796320118).toFloat, 0.0) + assertEquals(1.41365268E18f, lg(-1645816617, 329141676).toFloat, 0.0) + assertEquals(-3.03197918E18f, lg(184187116, -705937657).toFloat, 0.0) + assertEquals(-4.04287594E18f, lg(659513335, -941305424).toFloat, 0.0) + assertEquals(-7.8204678E18f, lg(770505156, -1820844549).toFloat, 0.0) + assertEquals(-5.9733025E18f, lg(929928858, -1390767911).toFloat, 0.0) + assertEquals(1.1261721E18f, lg(-1475096259, 262207373).toFloat, 0.0) + assertEquals(4.00884963E18f, lg(787691795, 933383012).toFloat, 0.0) + assertEquals(-1.43511611E18f, lg(1189057493, -334139018).toFloat, 0.0) + assertEquals(3.81415059E18f, lg(-618946450, 888051141).toFloat, 0.0) } @Test def toDouble(): Unit = { - assertEquals(0, lg(0).toDouble) - assertEquals(-1, lg(-1).toDouble) - - if (!isInFullOpt) { - assertEquals(9.223372036854776E18, MaxVal.toDouble) - assertEquals(-9.223372036854776E18, MinVal.toDouble) - } else { - // Closure seems to incorrectly rewrite the constant on the right :-( - assertEquals(9.223372036854776E18, MaxVal.toDouble, 1E4) - assertEquals(-9.223372036854776E18, MinVal.toDouble, 1E4) - } - - assertEquals(3.4240179834317537E18, lg(-151011088, 797216310).toDouble) - assertEquals(8.5596043411285968E16, lg(-508205099, 19929381).toDouble) - assertEquals(-3.1630346897289943E18, lg(1249322201, -736451403).toDouble) - assertEquals(-4.4847682439933604E18, lg(483575860, -1044191477).toDouble) - assertEquals(-6.4014772289576371E17, lg(-1526343930, -149046007).toDouble) - assertEquals(-1.76968119148756736E18, lg(531728928, -412036011).toDouble) - assertEquals(-8.5606671350959739E18, lg(-734111585, -1993185640).toDouble) - assertEquals(-9.0403963253949932E18, lg(-1407864332, -2104881296).toDouble) - assertEquals(-6.4988752582247977E18, lg(-1712351423, -1513137310).toDouble) - assertEquals(-7.7788492399114394E17, lg(1969244733, -181115448).toDouble) - assertEquals(7.6357174849871442E18, lg(-907683842, 1777829016).toDouble) - assertEquals(1.25338659134517658E18, lg(-815927209, 291826806).toDouble) - assertEquals(-3.1910241505692349E18, lg(463523496, -742968207).toDouble) - assertEquals(7.4216510087652332E18, lg(1482622807, 1727987781).toDouble) - assertEquals(-8.189046896086654E18, lg(1170040143, -1906661060).toDouble) - assertEquals(6.8316272807487539E18, lg(-85609173, 1590612176).toDouble) - assertEquals(-8.0611115909320561E18, lg(-1212811257, -1876873801).toDouble) - assertEquals(1.7127521901359959E18, lg(-648802816, 398781194).toDouble) - assertEquals(-6.4442523492577423E18, lg(-1484519186, -1500419423).toDouble) - assertEquals(-1.71264450938175027E18, lg(-2016996893, -398756124).toDouble) + assertEquals(0, lg(0).toDouble, 0.0) + assertEquals(-1, lg(-1).toDouble, 0.0) + + // Closure seems to incorrectly rewrite the constant on the right :-( + val epsilon = if (isInFullOpt) 1E4 else 0.0 + assertEquals(9.223372036854776E18, MaxVal.toDouble, epsilon) + assertEquals(-9.223372036854776E18, MinVal.toDouble, epsilon) + + assertEquals(3.4240179834317537E18, lg(-151011088, 797216310).toDouble, 0.0) + assertEquals(8.5596043411285968E16, lg(-508205099, 19929381).toDouble, 0.0) + assertEquals(-3.1630346897289943E18, lg(1249322201, -736451403).toDouble, 0.0) + assertEquals(-4.4847682439933604E18, lg(483575860, -1044191477).toDouble, 0.0) + assertEquals(-6.4014772289576371E17, lg(-1526343930, -149046007).toDouble, 0.0) + assertEquals(-1.76968119148756736E18, lg(531728928, -412036011).toDouble, 0.0) + assertEquals(-8.5606671350959739E18, lg(-734111585, -1993185640).toDouble, 0.0) + assertEquals(-9.0403963253949932E18, lg(-1407864332, -2104881296).toDouble, 0.0) + assertEquals(-6.4988752582247977E18, lg(-1712351423, -1513137310).toDouble, 0.0) + assertEquals(-7.7788492399114394E17, lg(1969244733, -181115448).toDouble, 0.0) + assertEquals(7.6357174849871442E18, lg(-907683842, 1777829016).toDouble, 0.0) + assertEquals(1.25338659134517658E18, lg(-815927209, 291826806).toDouble, 0.0) + assertEquals(-3.1910241505692349E18, lg(463523496, -742968207).toDouble, 0.0) + assertEquals(7.4216510087652332E18, lg(1482622807, 1727987781).toDouble, 0.0) + assertEquals(-8.189046896086654E18, lg(1170040143, -1906661060).toDouble, 0.0) + assertEquals(6.8316272807487539E18, lg(-85609173, 1590612176).toDouble, 0.0) + assertEquals(-8.0611115909320561E18, lg(-1212811257, -1876873801).toDouble, 0.0) + assertEquals(1.7127521901359959E18, lg(-648802816, 398781194).toDouble, 0.0) + assertEquals(-6.4442523492577423E18, lg(-1484519186, -1500419423).toDouble, 0.0) + assertEquals(-1.71264450938175027E18, lg(-2016996893, -398756124).toDouble, 0.0) } @Test def fromDouble(): Unit = { @@ -2226,8 +2218,8 @@ class RuntimeLongOldTest { } @Test def should_correctly_implement_toDouble(): Unit = { - assertEquals(5.0, fromInt(5).toDouble) - assertEquals(2147483648.0, (maxInt+one).toDouble) + assertEquals(5.0, fromInt(5).toDouble, 0.0) + assertEquals(2147483648.0, (maxInt+one).toDouble, 0.0) } @Test def should_correctly_implement_numberOfLeadingZeros(): Unit = { diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/DataViewTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/DataViewTest.scala index 6cd7b4284c..3981f02632 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/DataViewTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/DataViewTest.scala @@ -141,10 +141,10 @@ class DataViewTest { view.setUint8(3, 0x30) view.setUint8(4, 0x1A) - assertEquals(0x01FFB330, view.getUint32(0)) - assertEquals(0x30B3FF01, view.getUint32(0, true)) - assertEquals(0xFFB3301AL.toDouble, view.getUint32(1)) - assertEquals(0x1A30B3FF, view.getUint32(1, true)) + assertEquals(0x01FFB330, view.getUint32(0), 0.0) + assertEquals(0x30B3FF01, view.getUint32(0, true), 0.0) + assertEquals(0xFFB3301AL.toDouble, view.getUint32(1), 0.0) + assertEquals(0x1A30B3FF, view.getUint32(1, true), 0.0) } @Test def getFloat32(): Unit = { @@ -163,7 +163,7 @@ class DataViewTest { view.setFloat64(0, 0.5) - assertEquals(0.5, view.getFloat64(0)) + assertEquals(0.5, view.getFloat64(0), 0.0) assertNotEquals(0.5, view.getFloat64(1), 0.0) assertNotEquals(0.5, view.getFloat64(0, true), 0.0) assertNotEquals(0.5, view.getFloat64(1, true), 0.0) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/TypedArrayConversionTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/TypedArrayConversionTest.scala index 0a288e987f..9045a644a0 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/TypedArrayConversionTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/TypedArrayConversionTest.scala @@ -28,11 +28,11 @@ class TypedArrayConversionTest { val y = x.toArray assertTrue(y.getClass == classOf[scala.Array[Byte]]) - assertEquals(sum(1), y.sum) + assertEquals(sum(1), y.sum, 0.0) // Ensure its a copy x(0) = 0 - assertEquals(sum(1), y.sum) + assertEquals(sum(1), y.sum, 0.0) } @Test def convert_an_Int16Array_to_a_scala_Array_Short(): Unit = { @@ -40,11 +40,11 @@ class TypedArrayConversionTest { val y = x.toArray assertTrue(y.getClass == classOf[scala.Array[Short]]) - assertEquals(sum(100), y.sum) + assertEquals(sum(100), y.sum, 0.0) // Ensure its a copy x(0) = 0 - assertEquals(sum(100), y.sum) + assertEquals(sum(100), y.sum, 0.0) } @Test def convert_an_Uint16Array_to_a_scala_Array_Char(): Unit = { @@ -67,11 +67,11 @@ class TypedArrayConversionTest { val y = x.toArray assertTrue(y.getClass == classOf[scala.Array[Int]]) - assertEquals(sum(10000), y.sum) + assertEquals(sum(10000), y.sum, 0.0) // Ensure its a copy x(0) = 0 - assertEquals(sum(10000), y.sum) + assertEquals(sum(10000), y.sum, 0.0) } @Test def convert_a_Float32Array_to_a_scala_Array_Float(): Unit = { @@ -91,11 +91,11 @@ class TypedArrayConversionTest { val y = x.toArray assertTrue(y.getClass == classOf[scala.Array[Double]]) - assertEquals(sum(0.2), y.sum) + assertEquals(sum(0.2), y.sum, 0.0) // Ensure its a copy x(0) = 0 - assertEquals(sum(0.2), y.sum) + assertEquals(sum(0.2), y.sum, 0.0) } @Test def convert_a_scala_Array_Byte__to_an_Int8Array(): Unit = { @@ -168,11 +168,11 @@ class TypedArrayConversionTest { assertEquals(x.length, y.length) for (i <- 0 until y.length) - assertEquals(x(i), y(i)) + assertEquals(x(i), y(i), 0.0) // Ensure its a copy x(0) = 0 - assertEquals(1.0f, y(0)) + assertEquals(1.0f, y(0), 0.0) } @Test def convert_a_scala_Array_Double__to_a_Float64Array(): Unit = { @@ -180,13 +180,13 @@ class TypedArrayConversionTest { val y = x.toTypedArray assertTrue(y.isInstanceOf[Float64Array]) - assertEquals(x.length, y.length) + assertEquals(x.length, y.length, 0.0) for (i <- 0 until y.length) - assertEquals(x(i), y(i)) + assertEquals(x(i), y(i), 0.0) // Ensure its a copy x(0) = 0 - assertEquals(1.0, y(0)) + assertEquals(1.0, y(0), 0.0) } } From 58d27e70614837ba08f9a8fb90b2175428332154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 30 May 2017 13:22:38 +0200 Subject: [PATCH 0283/2665] Fix #2798: Tolerate Java 9. Using the parallel optimizer does not work on Java 9, because the parallel collections of Scala 2.10 cannot parse its version number, and die. This commit falls back on the sequential optimizer in cases where parallel collections are not supported. --- .../scalajs/sbtplugin/OptimizerOptions.scala | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/OptimizerOptions.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/OptimizerOptions.scala index 5ed475f5ab..a6d60d3116 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/OptimizerOptions.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/OptimizerOptions.scala @@ -22,8 +22,8 @@ import OptimizerOptions._ final class OptimizerOptions private ( /** Whether to only warn if the linker has errors */ val bypassLinkingErrors: Boolean = false, - /** Whether to parallelize the optimizer (currently fastOptJS only) **/ - val parallel: Boolean = true, + /** Whether to parallelize the optimizer **/ + val parallel: Boolean = OptimizerOptions.DefaultParallel, /** Whether to run the optimizer in batch (i.e. non-incremental) mode */ val batchMode: Boolean = false, /** Whether to run the Scala.js optimizer */ @@ -86,5 +86,25 @@ final class OptimizerOptions private ( } object OptimizerOptions { + /* #2798 -- On Java 9+, the parallel collections on 2.10 die with a + * `NumberFormatException` and prevent the linker from working. + * + * By default, we therefore pre-emptively disable the parallel optimizer in + * case the parallel collections cannot deal with the current version of + * Java. + * + * TODO This will automatically "fix itself" once we upgrade to sbt 1.x, + * which uses Scala 2.12. We should get rid of that workaround at that point + * for tidiness, though. + */ + private val DefaultParallel: Boolean = { + try { + scala.util.Properties.isJavaAtLeast("1.8") + true + } catch { + case _: NumberFormatException => false + } + } + def apply(): OptimizerOptions = new OptimizerOptions() } From b63b48e7fd98873b4a3b3ec63a9ad73ef8581d43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 30 May 2017 16:23:27 +0200 Subject: [PATCH 0284/2665] Move the `delete` and `debugger` primitives to `js.special._`. The new package `scala.scalajs.js.special` is dedicated to rare JS interoperability primitives that should normally not be used. In some cases, though, they are required, and can be accessed through methods in that package. We move the two existing primitives for `delete` and `debugger` in that package: * `js.Dictionary.delete` -> `js.special.delete` * `js.debugger` -> `js.special.debugger` --- .../org/scalajs/core/compiler/GenJSCode.scala | 4 + .../scalajs/core/compiler/JSDefinitions.scala | 5 +- .../scalajs/core/compiler/JSPrimitives.scala | 8 +- .../scala/scala/scalajs/js/Dictionary.scala | 8 ++ .../scala/scalajs/js/WrappedDictionary.scala | 2 +- .../main/scala/scala/scalajs/js/package.scala | 4 +- .../scala/scalajs/js/special/package.scala | 55 +++++++++++ .../testsuite/compiler/RegressionJSTest.scala | 28 ------ .../testsuite/jsinterop/PromiseMock.scala | 2 +- .../jsinterop/ScalaJSDefinedTest.scala | 4 +- .../testsuite/jsinterop/SpecialTest.scala | 95 +++++++++++++++++++ 11 files changed, 179 insertions(+), 36 deletions(-) create mode 100644 library/src/main/scala/scala/scalajs/js/special/package.scala create mode 100644 test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 6d5ab0c113..3a1a32b986 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -4163,6 +4163,10 @@ abstract class GenJSCode extends plugins.PluginComponent js.VarDef(temp, jstpe.AnyType, mutable = false, arg1), js.Unbox(js.JSBinaryOp(js.JSBinaryOp.in, arg2, js.VarRef(temp)(jstpe.AnyType)), 'Z')) + + case DELETE => + // js.special.delete(arg1, arg2) + js.JSDelete(js.JSBracketSelect(arg1, arg2)) } }) } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 2421beeabe..472ce8304b 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -26,7 +26,6 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val ScalaJSJSPackage = getPackage(newTermNameCached("scala.scalajs.js")) // compat 2.10/2.11 lazy val JSPackage_typeOf = getMemberMethod(ScalaJSJSPackage, newTermName("typeOf")) lazy val JSPackage_constructorOf = getMemberMethod(ScalaJSJSPackage, newTermName("constructorOf")) - lazy val JSPackage_debugger = getMemberMethod(ScalaJSJSPackage, newTermName("debugger")) lazy val JSPackage_native = getMemberMethod(ScalaJSJSPackage, newTermName("native")) lazy val JSPackage_undefined = getMemberMethod(ScalaJSJSPackage, newTermName("undefined")) @@ -110,6 +109,10 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val RawJSTypeAnnot = getRequiredClass("scala.scalajs.js.annotation.RawJSType") lazy val ExposedJSMemberAnnot = getRequiredClass("scala.scalajs.js.annotation.ExposedJSMember") + lazy val SpecialPackageModule = getPackageObject("scala.scalajs.js.special") + lazy val Special_delete = getMemberMethod(SpecialPackageModule, newTermName("delete")) + lazy val Special_debugger = getMemberMethod(SpecialPackageModule, newTermName("debugger")) + lazy val RuntimeStringModule = getRequiredModule("scala.scalajs.runtime.RuntimeString") lazy val RuntimeStringModuleClass = RuntimeStringModule.moduleClass diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala index 9275a15b4c..7e033df05c 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala @@ -41,7 +41,6 @@ abstract class JSPrimitives { val ARR_CREATE = 337 // js.Array.apply (array literal syntax) val TYPEOF = 344 // typeof x - val DEBUGGER = 345 // js.debugger() val HASPROP = 346 // js.Object.hasProperty(o, p), equiv to `p in o` in JS val OBJPROPS = 347 // js.Object.properties(o), equiv to `for (p in o)` in JS val JS_NATIVE = 348 // js.native. Marker method. Fails if tried to be emitted. @@ -51,6 +50,9 @@ abstract class JSPrimitives { val CONSTRUCTOROF = 352 // runtime.constructorOf(clazz) val LINKING_INFO = 354 // $linkingInfo + val DELETE = 355 // js.special.delete + val DEBUGGER = 356 // js.special.debugger + /** Initialize the map of primitive methods (for GenJSCode) */ def init(): Unit = initWithPrimitives(addPrimitive) @@ -95,7 +97,6 @@ abstract class JSPrimitives { addPrimitive(JSArray_create, ARR_CREATE) addPrimitive(JSPackage_typeOf, TYPEOF) - addPrimitive(JSPackage_debugger, DEBUGGER) addPrimitive(JSPackage_native, JS_NATIVE) addPrimitive(JSObject_hasProperty, HASPROP) @@ -105,6 +106,9 @@ abstract class JSPrimitives { addPrimitive(Runtime_constructorOf, CONSTRUCTOROF) addPrimitive(Runtime_linkingInfo, LINKING_INFO) + + addPrimitive(Special_delete, DELETE) + addPrimitive(Special_debugger, DEBUGGER) } def isJavaScriptPrimitive(code: Int): Boolean = diff --git a/library/src/main/scala/scala/scalajs/js/Dictionary.scala b/library/src/main/scala/scala/scalajs/js/Dictionary.scala index 509cc1f570..821108abd9 100644 --- a/library/src/main/scala/scala/scalajs/js/Dictionary.scala +++ b/library/src/main/scala/scala/scalajs/js/Dictionary.scala @@ -54,6 +54,13 @@ sealed trait Dictionary[A] extends Any { @JSBracketAccess def update(key: String, value: A): Unit = native + /* Note: `delete` cannot be replaced by a user-land implementation in + * WrappedDictionary, because it would break forward compiler-library + * compatibility. If someone uses an 0.6.16 compiler with an 0.6.17 library + * (which can easily happen if depending on a third-party library compiled + * with 0.6.17), the compiler will look for this symbol and crash. + */ + /** Deletes a property of this object by its name. * * The property must be configurable. @@ -62,6 +69,7 @@ sealed trait Dictionary[A] extends Any { * Since we are using strict mode, this throws an exception, if the property * isn't configurable. */ + @deprecated("Use -= instead.", "0.6.17") def delete(key: String): Unit = throw new java.lang.Error("stub") } diff --git a/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala b/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala index f425fd0495..a38ec7ccea 100644 --- a/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala +++ b/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala @@ -52,7 +52,7 @@ class WrappedDictionary[A](val dict: Dictionary[A]) def -=(key: String): this.type = { if (contains(key)) - dict.delete(key) + js.special.delete(dict, key) this } diff --git a/library/src/main/scala/scala/scalajs/js/package.scala b/library/src/main/scala/scala/scalajs/js/package.scala index 102587009a..5ec5dcc11f 100644 --- a/library/src/main/scala/scala/scalajs/js/package.scala +++ b/library/src/main/scala/scala/scalajs/js/package.scala @@ -96,7 +96,9 @@ package object js { * - In Chrome, it has no effect unless the developer tools are opened * beforehand. */ - def debugger(): Unit = throw new java.lang.Error("stub") + @deprecated("Use scala.scalajs.js.sepcial.debugger instead", "0.6.17") + @inline + def debugger(): Unit = js.special.debugger() /** Evaluates JavaScript code and returns the result. */ @inline def eval(x: String): Any = diff --git a/library/src/main/scala/scala/scalajs/js/special/package.scala b/library/src/main/scala/scala/scalajs/js/special/package.scala new file mode 100644 index 0000000000..ac3987aa4f --- /dev/null +++ b/library/src/main/scala/scala/scalajs/js/special/package.scala @@ -0,0 +1,55 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js API ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package scala.scalajs.js + +/** Contains special primitives of interoperability with JavaScript which are + * of limited importance or rare usefulness. + * + * In theory, all of the members of this package could equally well be part of + * the `scala.scalajs.js` package. They are sligthly "hidden" in this + * `special` package so that they are not used on a daily basis, but only when + * absolutely necessary. + * + * Everything in this package is a "I-know-what-I-am-doing" API. Notably, no + * attempt is made to guide the user with types that are not hard + * requirements. + */ +package object special { + + /** Deletes a property of an object. + * + * This method is the exact equivalent of the `delete obj[key]` statement + * of JavaScript (and by extension of `delete obj.key` if `key` is a + * constant string). + * + * The property must be configurable. Otherwise, this method throws a + * [[js.TypeError]]. + * + * Rather than using this method, it is often preferable to use a + * [[js.Dictionary]] and its `-=` method. + */ + def delete(obj: scala.Any, key: scala.Any): Unit = + throw new java.lang.Error("stub") + + /** Exact equivalent of the `debugger` keyword of JavaScript. + * + * `debugger()` invokes any available debugging functionality. + * If no debugging functionality is available, this method has no effect. + * + * MDN + * + * Browser support: + * - Has no effect in Rhino nor, apparently, in Firefox + * - In Chrome, it has no effect unless the developer tools are opened + * beforehand. + */ + def debugger(): Unit = + throw new java.lang.Error("stub") + +} diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala index cd7a22775c..3375fe5aad 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala @@ -45,34 +45,6 @@ class RegressionJSTest { assertEquals(2, b) } - @Test def should_support_debugger_statements_through_the_whole_pipeline_issue_1402(): Unit = { - /* A function that hopefully persuades the optimizer not to optimize - * we need a debugger statement that is unreachable, but not eliminated. - */ - @noinline - class A(var z: Int = 4) { - var x: Int = _ - var y: Int = _ - - @noinline - def plus(x0: Int, y0: Int): Int = { - x = x0 - y = y0 - var res = 0 - while (x > 0 || y > 0 || z > 0) { - if (x > 0) x -= 1 - else if (y > 0) y -= 1 - else z -= 1 - res += 1 - } - res - } - } - - if (new A().plus(5, 10) < 3) - js.debugger() - } - @Test def should_transform_js_dynamic_x_receiver_issue_2804(): Unit = { @ScalaJSDefined class Foo extends js.Object diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PromiseMock.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PromiseMock.scala index 7d0ea67482..ceaa79bf35 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PromiseMock.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PromiseMock.scala @@ -22,7 +22,7 @@ object PromiseMock { body(MockPromise.processQueue _) } finally { oldPromise.fold { - global.asInstanceOf[js.Dictionary[Any]].delete("Promise") + js.special.delete(global, "Promise") } { old => global.Promise = old } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala index c6d9c69d60..3cbb58169a 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala @@ -650,7 +650,7 @@ class ScalaJSDefinedTest { // Delete property from prototype. val prototype = js.constructorOf[Foo].prototype - prototype.asInstanceOf[js.Dictionary[js.Any]].delete("myProp") + js.special.delete(prototype, "myProp") // Check it is actually gone. assertTrue(js.isUndefined((new Foo()).asInstanceOf[js.Dynamic].myProp)) @@ -662,7 +662,7 @@ class ScalaJSDefinedTest { // The property should be on the instance itself. assertTrue(y.hasOwnProperty("myProp")) - y.asInstanceOf[js.Dictionary[js.Any]].delete("myProp") + js.special.delete(y, "myProp") assertTrue(js.isUndefined(y.asInstanceOf[js.Dynamic].myProp)) assertFalse(y.hasOwnProperty("myProp")) } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala new file mode 100644 index 0000000000..c03e37bb36 --- /dev/null +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala @@ -0,0 +1,95 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.jsinterop + +import scala.scalajs.js + +import org.junit.Assert._ +import org.junit.Assume._ +import org.junit.Test + +import org.scalajs.testsuite.utils.AssertThrows._ +import org.scalajs.testsuite.utils.Platform._ + +class SpecialTest { + import SpecialTest._ + + // scala.scalajs.js.special.delete + + @Test def should_provide_an_equivalent_of_the_JS_delete_keyword_issue_255(): Unit = { + val obj = js.Dynamic.literal(foo = 42, bar = "foobar") + + assertEquals(42, obj.foo) + assertEquals("foobar", obj.bar) + js.special.delete(obj, "foo") + assertFalse(obj.hasOwnProperty("foo")) + assertEquals("foobar", obj.bar) + } + + @Test def should_behave_as_specified_when_deleting_a_non_configurable_property_issue_461_issue_679(): Unit = { + // This doesn't work on Rhino due to lack of full strict mode support - #679 + assumeFalse("Assumed not executing in Rhino", executingInRhino) + + val obj = js.Dynamic.literal() + js.Object.defineProperty(obj, "nonconfig", + js.Dynamic.literal(value = 4, writable = false).asInstanceOf[js.PropertyDescriptor]) + assertEquals(4, obj.nonconfig) + assertThrows(classOf[Exception], js.special.delete(obj, "nonconfig")) + assertEquals(4, obj.nonconfig) + } + + @Test def should_treat_delete_as_a_statement_issue_907(): Unit = { + val obj = js.Dynamic.literal(a = "A") + js.special.delete(obj, "a") + } + + @Test def should_desugar_arguments_to_delete_statements_issue_908(): Unit = { + val kh = js.Dynamic.literal(key = "a").asInstanceOf[KeyHolder] + val obj = js.Dynamic.literal(a = "A") + def a[T](foo: String): T = obj.asInstanceOf[T] + js.special.delete(a[js.Object]("foo"), kh.key) + } + + // js.special.debugger + + @Test def should_support_debugger_statements_through_the_whole_pipeline_issue_1402(): Unit = { + /* A function that hopefully persuades the optimizer not to optimize + * we need a debugger statement that is unreachable, but not eliminated. + */ + @noinline + class A(var z: Int = 4) { + var x: Int = _ + var y: Int = _ + + @noinline + def plus(x0: Int, y0: Int): Int = { + x = x0 + y = y0 + var res = 0 + while (x > 0 || y > 0 || z > 0) { + if (x > 0) x -= 1 + else if (y > 0) y -= 1 + else z -= 1 + res += 1 + } + res + } + } + + if (new A().plus(5, 10) < 3) + js.special.debugger() + } + +} + +object SpecialTest { + @js.native + trait KeyHolder extends js.Object { + def key: String = js.native + } +} From b837e919f0ff4e796a6c700ab4f5cab4002c3991 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 30 May 2017 16:37:32 +0200 Subject: [PATCH 0285/2665] Bump the binaryEmitted version. This should have been done as part of/before f4896a50bc5c3f8eb70d8c54d6874a969140f88d, which broke forward binary compatibility of the IR. --- ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index 2d405144d8..d7d960e5f0 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -21,7 +21,7 @@ object ScalaJSVersions { * - a prior release version (i.e. "0.5.0", *not* "0.5.0-SNAPSHOT") * - `current` */ - val binaryEmitted: String = "0.6.15" + val binaryEmitted: String = current /** Versions whose binary files we can support (used by deserializer) */ val binarySupported: Set[String] = { From 5827d267fa3edb8244893714299ca65dffcf12b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 30 May 2017 16:47:59 +0200 Subject: [PATCH 0286/2665] Add `js.special.globalThis` to access the global `this` value. In 1.x, because of #2800, Scala.js will not offer any built-in mechanism to detect the global object of JavaScript. Instead, user code should be written to do so. That is only possible if we give access to the global `this` value, as it appears to the top-level of the .js file produced by Scala.js. This commit adds a "primitive" `js.special.globalThis` to that effect. Technically speaking, it is not actually a primitive, as it is simply implemented as a linking info property. Introducing `globalThis` in 0.6.x is necessary for codebases that want to cross-compile between 0.6.x and 1.x, and need to detect the global object. --- .../scala/scalajs/js/special/package.scala | 32 +++++++++++++++++++ .../scala/scalajs/runtime/LinkingInfo.scala | 3 ++ project/BinaryIncompatibilities.scala | 5 +++ .../testsuite/jsinterop/SpecialTest.scala | 19 +++++++++++ tools/scalajsenv.js | 3 +- 5 files changed, 61 insertions(+), 1 deletion(-) diff --git a/library/src/main/scala/scala/scalajs/js/special/package.scala b/library/src/main/scala/scala/scalajs/js/special/package.scala index ac3987aa4f..d1073c3ec7 100644 --- a/library/src/main/scala/scala/scalajs/js/special/package.scala +++ b/library/src/main/scala/scala/scalajs/js/special/package.scala @@ -37,6 +37,38 @@ package object special { def delete(obj: scala.Any, key: scala.Any): Unit = throw new java.lang.Error("stub") + /** The value of the global JavaScript `this`. + * + * This returns the value that would be obtained by writing `this` at the + * top-level of the JavaScript file generated by Scala.js. In most + * JavaScript environments, this is equivalent to the *global object*, but + * it is not necessarily the case. For example, on Node.js, `this` is the + * object representing the `exports` of the current module. + * + * Using this value should be rare, and mostly limited to writing code + * detecting what the global object is. For example, a typical detection + * code looks like: + * {{{ + * val globalObject = { + * import js.Dynamic.{global => g} + * if (js.typeOf(g.global) != "undefined" && (g.global.Object eq g.Object)) { + * // Node.js environment detected + * g.global + * } else { + * // In all other well-known environment, we can use the global `this` + * js.special.globalThis + * } + * } + * }}} + * Note that the above code is not comprehensive, as there can be JavaScript + * environments where the global object cannot be fetched neither through + * `global` nor `this`. If your code needs to run in such an environment, it + * is up to you to use an appropriate detection procedure. + */ + @inline + def globalThis: scala.Any = + scala.scalajs.runtime.linkingInfo.globalThis + /** Exact equivalent of the `debugger` keyword of JavaScript. * * `debugger()` invokes any available debugging functionality. diff --git a/library/src/main/scala/scala/scalajs/runtime/LinkingInfo.scala b/library/src/main/scala/scala/scalajs/runtime/LinkingInfo.scala index 3d372b8d77..d4ea4b4090 100644 --- a/library/src/main/scala/scala/scalajs/runtime/LinkingInfo.scala +++ b/library/src/main/scala/scala/scalajs/runtime/LinkingInfo.scala @@ -16,6 +16,9 @@ trait LinkingInfo extends js.Object { /** Version of the linker */ val linkerVersion: js.UndefOr[String] = js.native + + /** The value of the global JavaScript `this`. */ + val globalThis: Any = js.native } object LinkingInfo { diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 91cdcd3507..e9c892a59c 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -47,6 +47,11 @@ object BinaryIncompatibilities { ) val Library = Seq( + // New members of an @js.native trait in `runtime`, not an issue + ProblemFilters.exclude[ReversedMissingMethodProblem]( + "scala.scalajs.runtime.LinkingInfo.globalThis"), + ProblemFilters.exclude[ReversedMissingMethodProblem]( + "scala.scalajs.runtime.LinkingInfo.scala$scalajs$runtime$LinkingInfo$_setter_$globalThis_=") ) val TestInterface = Seq( diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala index c03e37bb36..ee3f707af6 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala @@ -55,6 +55,25 @@ class SpecialTest { js.special.delete(a[js.Object]("foo"), kh.key) } + // js.special.globalThis + + @Test def globalThis_can_be_used_to_detect_the_global_object(): Unit = { + val globalObject = { + import js.Dynamic.{global => g} + // We've got to use selectDynamic explicitly not to crash Scala 2.10 + if (js.typeOf(g.selectDynamic("global")) != "undefined" && + (g.selectDynamic("global").selectDynamic("Object") eq g.selectDynamic("Object"))) { + // Node.js environment detected + g.selectDynamic("global") + } else { + // In all other well-known environment, we can use the global `this` + js.special.globalThis + } + } + + assertSame(js.Dynamic.global, globalObject) + } + // js.special.debugger @Test def should_support_debugger_statements_through_the_whole_pipeline_issue_1402(): Unit = { diff --git a/tools/scalajsenv.js b/tools/scalajsenv.js index c89c951d15..cc8162c98d 100644 --- a/tools/scalajsenv.js +++ b/tools/scalajsenv.js @@ -81,7 +81,8 @@ ScalaJS.linkingInfo = { //!else "assumingES6": false, //!endif - "linkerVersion": "{{LINKER_VERSION}}" + "linkerVersion": "{{LINKER_VERSION}}", + "globalThis": this }; ScalaJS.g["Object"]["freeze"](ScalaJS.linkingInfo); ScalaJS.g["Object"]["freeze"](ScalaJS.linkingInfo["semantics"]); From 13400c6db88f4420d356ac112eb363e04a1c243b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 14 May 2017 17:04:46 +0200 Subject: [PATCH 0287/2665] Integrate the setup of Node.js for the bootstrap test in the build. The setup is necessary on a local machine just as much as on the CI servers, so this is easier. --- ci/matrix.xml | 6 ++---- project/Build.scala | 3 +++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ci/matrix.xml b/ci/matrix.xml index d55f12d7ef..b2efc3e1c5 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -141,10 +141,8 @@ diff --git a/project/Build.scala b/project/Build.scala index 05ed629834..976524a7b4 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -639,6 +639,9 @@ object Build { Seq(outFile) }.taskValue, + // Give more memory to Node.js, and deactivate source maps + jsEnv := new NodeJSEnv(args = Seq("--max_old_space_size=3072")).withSourceMap(false), + jsDependencies += ProvidedJS / "js-test-definitions.js" % "test", jsDependencies += "org.webjars" % "jszip" % "2.4.0" % "test" / "jszip.min.js" commonJSName "JSZip", From e99e100208121c515885e39d2a684b115d32ecf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 14 May 2017 17:19:44 +0200 Subject: [PATCH 0288/2665] Give a meaningful `toString()` to `VirtualFile`s. --- .../main/scala/org/scalajs/core/tools/io/VirtualFiles.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala index 7266558a03..81c8b8ea86 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala @@ -37,6 +37,12 @@ trait VirtualFile { null // Fragment ) } + + override def toString(): String = { + val className = getClass.getName + val shortClassName = className.substring(className.lastIndexOf('.') + 1) + shortClassName + "(" + path + ")" + } } object VirtualFile { From 3be0ec248648696f4d68a9dac21c45db35ba7dc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 14 May 2017 17:20:14 +0200 Subject: [PATCH 0289/2665] Use `jsExecutionFiles` for toolsJS's `js-test-definitions.js` file. We used to use a resource generator combined with a `ProvidedJS` in `jsDependencies`. It is much simpler to directly use `jsExecutionFiles` with an in-memory virtual JS file instead. --- project/Build.scala | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 976524a7b4..1176c53ae1 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -624,25 +624,25 @@ object Build { ).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" + 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 + }, // Give more memory to Node.js, and deactivate source maps jsEnv := new NodeJSEnv(args = Seq("--max_old_space_size=3072")).withSourceMap(false), - jsDependencies += ProvidedJS / "js-test-definitions.js" % "test", jsDependencies += "org.webjars" % "jszip" % "2.4.0" % "test" / "jszip.min.js" commonJSName "JSZip", From 562657e8fbf6a95d5480ccc055d9fbc5cbbab176 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 14 May 2017 17:35:39 +0200 Subject: [PATCH 0290/2665] Use `jsExecutionFiles` for testSuite's `ScalaJSDefinedTestNative.js` file. This allows to get rid of the `JSDependenciesPlugin` for the `testSuite` project. Unfortunately, we now have to duplicate the setting in `toolsJS`, since the bootstrap test does not transitively receive the dependency anymore. --- project/Build.scala | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 1176c53ae1..1f5ceb6a33 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -30,7 +30,7 @@ import ScalaJSPlugin.autoImport._ import ExternalCompile.scalaJSExternalCompileSettings import Loggers._ -import org.scalajs.core.tools.io.MemVirtualJSFile +import org.scalajs.core.tools.io.{FileVirtualJSFile, MemVirtualJSFile} import org.scalajs.core.tools.sem._ import org.scalajs.core.tools.json._ import org.scalajs.core.tools.linker.ModuleInitializer @@ -640,6 +640,8 @@ object Build { 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), @@ -1438,9 +1440,17 @@ object Build { }).value ) + def testSuiteJSExecutionFilesSetting: Setting[_] = { + jsExecutionFiles in Test := { + val resourceDir = + (resourceDirectory in (LocalProject("testSuite"), Test)).value + val f = FileVirtualJSFile(resourceDir / "ScalaJSDefinedTestNatives.js") + f +: (jsExecutionFiles in Test).value + } + } + lazy val testSuite: Project = (project in file("test-suite/js")).enablePlugins( - MyScalaJSPlugin, - JSDependenciesPlugin + MyScalaJSPlugin ).settings( commonSettings, testTagSettings, @@ -1456,8 +1466,7 @@ object Build { scalaJSModuleKind.value != ModuleKind.NoModule) }, - jsDependencies += ProvidedJS / "ScalaJSDefinedTestNatives.js" % "test", - skip in packageJSDependencies in Test := false, + testSuiteJSExecutionFilesSetting, scalaJSSemantics ~= (_.withRuntimeClassName(_.fullName match { case "org.scalajs.testsuite.compiler.ReflectionTest$RenamedTestClass" => From 87f07869dc9153ef0def604aa3fdfc0c4e4c0fdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 29 May 2017 13:16:09 +0200 Subject: [PATCH 0291/2665] Setup Java sys props for the bootstrap test in the build. I.e., directly in the code that performs the bootstrap test. There was already one system property defined there. In general, it just makes more sense. --- project/Build.scala | 7 ++++++- .../scala/org/scalajs/core/tools/test/js/TestRunner.scala | 6 ------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 1f5ceb6a33..03d1810a32 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -689,7 +689,12 @@ object Build { val scalaJSEnv = { s""" {"javaSystemProperties": { - "scalajs.scalaVersion": "${scalaVersion.value}" + "scalajs.scalaVersion": "${scalaVersion.value}", + "scalajs.testsuite.testtag": "testtag.value", + "scalajs.nodejs": "true", + "scalajs.typedarray": "true", + "scalajs.fastopt-stage": "true", + "scalajs.modulekind-nomodule": "true" }} """ } diff --git a/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala b/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala index 31eb9944d6..395504ec17 100644 --- a/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala +++ b/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala @@ -12,12 +12,6 @@ object TestRunner { @JSExport def runTests(): Unit = { - System.setProperty("scalajs.testsuite.testtag", "testtag.value") - System.setProperty("scalajs.nodejs", "true") - System.setProperty("scalajs.typedarray", "true") - System.setProperty("scalajs.fastopt-stage", "true") - System.setProperty("scalajs.modulekind-nomodule", "true") - val eventHandler = new SimpleEventHandler val loggers = Array[Logger](new SimpleLogger) From 9f80404505ab364f550e50a7c15cbef23b2ec122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 29 May 2017 13:20:01 +0200 Subject: [PATCH 0292/2665] Make the bootstrap test more easily debuggable. * Print a summary of the failed tests at the end. * Print the full stack trace of any exception thrown. --- .../core/tools/test/js/TestRunner.scala | 54 ++++++++++++------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala b/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala index 395504ec17..e75c53a7ad 100644 --- a/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala +++ b/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala @@ -1,5 +1,7 @@ package org.scalajs.core.tools.test.js +import scala.collection.mutable + import scala.scalajs.js import scala.scalajs.js.annotation._ @@ -12,35 +14,49 @@ object TestRunner { @JSExport def runTests(): Unit = { - val eventHandler = new SimpleEventHandler - val loggers = Array[Logger](new SimpleLogger) + try { + val eventHandler = new SimpleEventHandler + val loggers = Array[Logger](new SimpleLogger) - def taskLoop(tasks: Iterable[Task]): Unit = { - if (tasks.nonEmpty) - tasks.head.execute(eventHandler, loggers, - newTasks => taskLoop(tasks.tail ++ newTasks)) - } + def taskLoop(tasks: Iterable[Task]): Unit = { + if (tasks.nonEmpty) + tasks.head.execute(eventHandler, loggers, + newTasks => taskLoop(tasks.tail ++ newTasks)) + } - for { - (framework, taskDefs) <- TestDetector.detectTests() - } { - val runner = framework.runner(Array(), Array(), new ScalaJSClassLoader()) - val tasks = runner.tasks(taskDefs.toArray) - taskLoop(tasks) - } + for { + (framework, taskDefs) <- TestDetector.detectTests() + } { + val runner = framework.runner(Array(), Array(), new ScalaJSClassLoader()) + val tasks = runner.tasks(taskDefs.toArray) + taskLoop(tasks) + } - if (eventHandler.hasFailed) - throw new AssertionError("Some tests have failed") + val failedEvents = eventHandler.failedEvents + if (failedEvents.nonEmpty) { + System.err.println("The following tests failed:") + for (event <- failedEvents) { + System.err.println("* " + event.fullyQualifiedName()) + if (event.throwable().isDefined()) + event.throwable().get().printStackTrace() + } + throw new AssertionError("Some tests have failed") + } + } catch { + case th: Throwable => + th.printStackTrace() + throw th + } } private class SimpleEventHandler extends EventHandler { - private[this] var failed = false + private[this] val _failedEvents = new mutable.ListBuffer[Event] - def hasFailed: Boolean = failed + def failedEvents: List[Event] = _failedEvents.toList def handle(ev: Event) = { if (ev.status == Status.Error || ev.status == Status.Failure) - failed = true + _failedEvents += ev } } From 9a8c4a7ff01bd751a06af4408e3783fd7c077109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 29 May 2017 13:57:54 +0200 Subject: [PATCH 0293/2665] Separate the tools- from the testSuite-classpath in the bootstrap test. Previously, the classpaths of the tools and the testSuite were merged and mixed together in the bootstrap test: * toolsJS/test:fullClasspath contained both, *and* * the classpath optimized by the bootstrapped optimizer contained both. This commit cleanly distinguishes the two. Now, `toolsJS/test:fullClasspath`, which is optimized by the JVM linker, only contains the tools, with `QuickLinker` as the entry point. The classpath given to `QuickLinker`, and hence optimized by the bootstrapped linker, only contains the test suite, including a `ConsoleTestRunner` as entry point. --- project/Build.scala | 15 +++++++-------- .../testsuite/utils/ConsoleTestRunner.scala | 6 +++--- 2 files changed, 10 insertions(+), 11 deletions(-) rename tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala => test-suite/js/src/main/scala/org/scalajs/testsuite/utils/ConsoleTestRunner.scala (94%) diff --git a/project/Build.scala b/project/Build.scala index 03d1810a32..50da07f1f5 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -649,16 +649,16 @@ object Build { "org.webjars" % "jszip" % "2.4.0" % "test" / "jszip.min.js" commonJSName "JSZip", inConfig(Test) { - // Redefine test to run Node.js and link HelloWorld + // Redefine test to perform the bootstrap test test := { if (!jsEnv.value.isInstanceOf[NodeJSEnv]) throw new MessageOnlyException("toolsJS/test must be run with Node.js") - /* Collect IR relevant files from the classpath + /* 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. */ - val cp = Attributed.data(fullClasspath.value) + val cp = Attributed.data((fullClasspath in (testSuite, Test)).value) // Files must be Jars, non-files must be dirs val (jars, dirs) = cp.filter(_.exists).partition(_.isFile) @@ -686,7 +686,7 @@ object Build { seqOfStringsToJSArrayCode(unescapedMainMethods) } - val scalaJSEnv = { + val scalaJSEnvForTestSuite = { s""" {"javaSystemProperties": { "scalajs.scalaVersion": "${scalaVersion.value}", @@ -704,11 +704,10 @@ object Build { var linker = scalajs.QuickLinker; var lib = linker.linkTestSuiteNode($irPaths, $mainMethods); - var __ScalaJSEnv = $scalaJSEnv; - + var __ScalaJSEnv = $scalaJSEnvForTestSuite; eval("(function() { 'use strict'; " + lib + ";" + - "scalajs.TestRunner.runTests();" + + "scalajs.ConsoleTestRunner.runTests();" + "}).call(this);"); """ } @@ -722,7 +721,7 @@ object Build { } } ).withScalaJSCompiler.dependsOn( - library, irProjectJS, testSuite % "test->test" + library, irProjectJS, jUnitRuntime % "test" ) lazy val jsEnvs: Project = (project in file("js-envs")).settings( diff --git a/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/ConsoleTestRunner.scala similarity index 94% rename from tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala rename to test-suite/js/src/main/scala/org/scalajs/testsuite/utils/ConsoleTestRunner.scala index e75c53a7ad..d825ffa36f 100644 --- a/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala +++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/ConsoleTestRunner.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.tools.test.js +package org.scalajs.testsuite.utils import scala.collection.mutable @@ -9,8 +9,8 @@ import org.scalajs.testinterface.{ScalaJSClassLoader, TestDetector} import sbt.testing._ -@JSExportTopLevel("scalajs.TestRunner") -object TestRunner { +@JSExportTopLevel("scalajs.ConsoleTestRunner") +object ConsoleTestRunner { @JSExport def runTests(): Unit = { From 8051a9ca5b9d3dfc220fd8a0f0d29ce600cb1dd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 29 May 2017 14:17:17 +0200 Subject: [PATCH 0294/2665] Remove `jsDependencies` from the bootstrap test. To do this without implementing ad hoc resolution of `jszip.js`, we turn the bootstrap test itself into a CommonJS module and `@JSImport` it. In turn, this requires that we install `jszip` through npm, which we automate with a `package.json`. We use the opportunity to also install the two other more-or-less optional npm packages that we use: `jsdom` and `source-map-support`. This finally allows to remove the `JSDependencies` from the `toolsJS` project, which was the last reference to it in our build. --- ci/matrix.xml | 11 +++++++++ package.json | 8 +++++++ project/Build.scala | 24 +++++++++++-------- .../core/tools/test/js/QuickLinker.scala | 2 +- 4 files changed, 34 insertions(+), 11 deletions(-) create mode 100644 package.json diff --git a/ci/matrix.xml b/ci/matrix.xml index b2efc3e1c5..513d3eb96c 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -15,6 +15,7 @@ diff --git a/package.json b/package.json new file mode 100644 index 0000000000..28a69413e5 --- /dev/null +++ b/package.json @@ -0,0 +1,8 @@ +{ + "private": true, + "devDependencies": { + "source-map-support": "0.4.15", + "jszip": "2.4.0", + "jsdom": "9.12.0" + } +} diff --git a/project/Build.scala b/project/Build.scala index 50da07f1f5..126eca0012 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -23,9 +23,6 @@ import org.scalajs.sbtplugin._ import org.scalajs.jsenv.JSEnv import org.scalajs.jsenv.nodejs.{NodeJSEnv, JSDOMNodeJSEnv} -import org.scalajs.jsdependencies.sbtplugin.JSDependenciesPlugin -import org.scalajs.jsdependencies.sbtplugin.JSDependenciesPlugin.autoImport._ - import ScalaJSPlugin.autoImport._ import ExternalCompile.scalaJSExternalCompileSettings import Loggers._ @@ -619,12 +616,14 @@ object Build { ).dependsOn(irProject) lazy val toolsJS: Project = (project in file("tools/js")).enablePlugins( - MyScalaJSPlugin, - JSDependenciesPlugin + MyScalaJSPlugin ).settings( commonToolsSettings, crossVersion := ScalaJSCrossVersion.binary, + scalaJSModuleKind in Test := + org.scalajs.core.tools.linker.backend.ModuleKind.CommonJSModule, + jsExecutionFiles in Test := { val testDefinitions = { org.scalajs.build.HTMLRunnerTemplateAccess.renderTestDefinitions( @@ -645,15 +644,19 @@ object Build { // Give more memory to Node.js, and deactivate source maps jsEnv := new NodeJSEnv(args = Seq("--max_old_space_size=3072")).withSourceMap(false), - jsDependencies += - "org.webjars" % "jszip" % "2.4.0" % "test" / "jszip.min.js" commonJSName "JSZip", - inConfig(Test) { // Redefine test to perform the bootstrap test test := { if (!jsEnv.value.isInstanceOf[NodeJSEnv]) throw new MessageOnlyException("toolsJS/test must be run with Node.js") + /* 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. @@ -701,7 +704,8 @@ object Build { val code = { s""" - var linker = scalajs.QuickLinker; + var toolsTestModule = require("${escapeJS(toolsTestModule.path)}"); + var linker = toolsTestModule.scalajs.QuickLinker; var lib = linker.linkTestSuiteNode($irPaths, $mainMethods); var __ScalaJSEnv = $scalaJSEnvForTestSuite; @@ -715,7 +719,7 @@ object Build { val launcher = new MemVirtualJSFile("Generated launcher file") .withContent(code) - val runner = jsEnv.value.jsRunner(jsExecutionFiles.value :+ launcher) + val runner = jsEnv.value.jsRunner(executionFiles :+ launcher) runner.run(sbtLogger2ToolsLogger(streams.value.log), scalaJSConsole.value) } diff --git 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 index 3f67a1f0c6..3ece296e36 100644 --- 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 @@ -118,7 +118,7 @@ object QuickLinker { } @js.native - @JSGlobal("JSZip") + @JSImport("jszip", JSImport.Default) private class JSZip(data: Uint8Array) extends js.Object { def files: js.Dictionary[JSZipEntry] = js.native } From 5918016b88f420c9678888450e2cbe6095f4581d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 31 May 2017 11:56:57 +0200 Subject: [PATCH 0295/2665] Fix #2786: Prevent Closure from renaming `$classData`. This property is used to determine whether an arbitrary JS object is a Scala object. If GCC renames it to something too common (e.g., a single letter like `b`), we can erroneously identify a JS object as being a Scala object, and then things go wrong. This slightly increases the size of `-opt.js` files, but it seems that gziped sizes are virtually not affected. --- ci/checksizes.sh | 8 ++++---- .../linker/backend/closure/ClosureLinkerBackend.scala | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ci/checksizes.sh b/ci/checksizes.sh index a4dd550104..c16a7d7ecf 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -38,25 +38,25 @@ REVERSI_OPT_GZ_SIZE=$(stat '-c%s' "$REVERSI_OPT.gz") case $FULLVER in 2.10.2) REVERSI_PREOPT_EXPECTEDSIZE=532000 - REVERSI_OPT_EXPECTEDSIZE=120000 + REVERSI_OPT_EXPECTEDSIZE=122000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=71000 REVERSI_OPT_GZ_EXPECTEDSIZE=31000 ;; 2.11.11) REVERSI_PREOPT_EXPECTEDSIZE=527000 - REVERSI_OPT_EXPECTEDSIZE=121000 + REVERSI_OPT_EXPECTEDSIZE=124000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=71000 REVERSI_OPT_GZ_EXPECTEDSIZE=32000 ;; 2.12.2) REVERSI_PREOPT_EXPECTEDSIZE=629000 - REVERSI_OPT_EXPECTEDSIZE=144000 + REVERSI_OPT_EXPECTEDSIZE=147000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=76000 REVERSI_OPT_GZ_EXPECTEDSIZE=33000 ;; 2.13.0-M1) REVERSI_PREOPT_EXPECTEDSIZE=627000 - REVERSI_OPT_EXPECTEDSIZE=144000 + REVERSI_OPT_EXPECTEDSIZE=147000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=76000 REVERSI_OPT_GZ_EXPECTEDSIZE=33000 ;; diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala index ec1e19c55c..4ed5fc83f3 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala @@ -196,7 +196,8 @@ private object ClosureLinkerBackend { private val ScalaJSExterns = """ /** @constructor */ function Object() {} - Object.protoype.toString = function() {}; + Object.prototype.toString = function() {}; + Object.prototype.$classData = {}; /** @constructor */ function Array() {} Array.prototype.length = 0; From d46ee0a093b439bfe5edc23964e8632eb9736a21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 31 May 2017 10:41:23 +0200 Subject: [PATCH 0296/2665] Fix #2979: Allow `%%%` in builds that contain no Scala.js project. In a build that declares a dependency on `sbt-scalajs`, but does not actually *enable* the `ScalaJSPlugin` in any project, its `globalSettings` will not be considered. This means that the setting `isScalaJSProject` is not initialized, and the `%%%` macro produces references to an undefined setting. We fix this by declaring a separate `AutoPlugin` that is *always* triggered, and only initializes that setting. That plugin should never be referred to in user code, so we put it in an `internal` package. Additionally, we deprecate it "since forever" so that users do not refer to it by accident in a `.sbt` file (which will import it due to it being an `AutoPlugin`). --- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 3 +- .../internal/ScalaJSGlobalPlugin.scala | 41 +++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 sbt-plugin/src/main/scala/org/scalajs/sbtplugin/internal/ScalaJSGlobalPlugin.scala diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 87d4b02f0e..0454a4567d 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -392,8 +392,7 @@ object ScalaJSPlugin extends AutoPlugin { import ScalaJSPluginInternal._ override def globalSettings: Seq[Setting[_]] = { - super.globalSettings ++ Seq( - isScalaJSProject := false, + Seq( scalaJSStage := Stage.FastOpt, scalaJSUseRhinoInternal := false, scalaJSClearCacheStats := globalIRCache.clearStats() diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/internal/ScalaJSGlobalPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/internal/ScalaJSGlobalPlugin.scala new file mode 100644 index 0000000000..80a7641f1f --- /dev/null +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/internal/ScalaJSGlobalPlugin.scala @@ -0,0 +1,41 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.sbtplugin.internal + +import sbt._ + +import org.scalajs.sbtplugin.ScalaJSPlugin.autoImport.isScalaJSProject + +/* Additional note about the deprecation below. Even though we are in the + * `internal` package, ScalaJSGlobalPlugin will be imported by default in the + * scope of `.sbt` files because it is an `AutoPlugin`. We do not want users to + * refer to it by accident, without noticing they are using something from + * `internal`. + * + * Since it will be loaded by sbt using reflection anyway, the deprecation will + * not creep into legitimate builds. + */ + +/** An `AutoPlugin` setting up some global settings that must be present in the + * build even if no project enables [[ScalaJSPlugin]]. + * + * This plugin should never be directly referenced in source code, and is + * therefore "deprecated forever". + */ +@deprecated("Do not explicitly mention ScalaJSGlobalPlugin in source code", + "forever") +object ScalaJSGlobalPlugin extends AutoPlugin { + override def trigger: PluginTrigger = allRequirements + + override def globalSettings: Seq[Setting[_]] = { + Seq( + isScalaJSProject := false + ) + } +} From 980277f365ceb64a45e70ab5b9926548ab455daa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 1 Jun 2017 16:10:06 +0200 Subject: [PATCH 0297/2665] Remove the scalaJSConsole sbt setting. sbt does not provide JVM projects with any similar setting, allowing to redirect the output of the processes. Providing one in Scala.js project is therefore useless complexity. --- project/Build.scala | 4 ++-- .../main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala | 3 --- .../org/scalajs/sbtplugin/ScalaJSPluginInternal.scala | 8 ++------ 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 126eca0012..451a7b7005 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -20,7 +20,7 @@ import org.scalajs.core.ir import org.scalajs.core.ir.Utils.escapeJS import org.scalajs.sbtplugin._ -import org.scalajs.jsenv.JSEnv +import org.scalajs.jsenv.{ConsoleJSConsole, JSEnv} import org.scalajs.jsenv.nodejs.{NodeJSEnv, JSDOMNodeJSEnv} import ScalaJSPlugin.autoImport._ @@ -721,7 +721,7 @@ object Build { val runner = jsEnv.value.jsRunner(executionFiles :+ launcher) - runner.run(sbtLogger2ToolsLogger(streams.value.log), scalaJSConsole.value) + runner.run(sbtLogger2ToolsLogger(streams.value.log), ConsoleJSConsole) } } ).withScalaJSCompiler.dependsOn( diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 0a85f4fa87..1738e95696 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -157,9 +157,6 @@ object ScalaJSPlugin extends AutoPlugin { "Linked Scala.js file. This is the result of fastOptJS or fullOptJS, " + "depending on the stage.", DTask) - val scalaJSConsole = TaskKey[JSConsole]("scalaJSConsole", - "The JS console used by the Scala.js runner/tester", DTask) - val jsEnv = TaskKey[JSEnv]("jsEnv", "The JavaScript environment in which to run and test Scala.js applications.", AMinusTask) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index fcede45b52..a29b108c13 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -510,8 +510,7 @@ object ScalaJSPluginInternal { log.info("Running " + mainClass.value.getOrElse("")) log.debug(s"with JSEnv ${env.name}") - env.jsRunner(files).run( - sbtLogger2ToolsLogger(log), scalaJSConsole.value) + env.jsRunner(files).run(sbtLogger2ToolsLogger(log), ConsoleJSConsole) }, runMain := { @@ -529,7 +528,6 @@ object ScalaJSPluginInternal { // use assert to prevent warning about pure expr in stat pos assert(scalaJSEnsureUnforked.value) - val console = scalaJSConsole.value val logger = streams.value.log val toolsLogger = sbtLogger2ToolsLogger(logger) val frameworks = testFrameworks.value @@ -552,7 +550,7 @@ object ScalaJSPluginInternal { detector.detect(frameworks, toolsLogger) map { case (tf, name) => (tf, new ScalaJSFramework(name, env, files, moduleKind, - moduleIdentifier, toolsLogger, console)) + moduleIdentifier, toolsLogger, ConsoleJSConsole)) } }, // Override default to avoid triggering a test:fastOptJS in a test:compile @@ -691,8 +689,6 @@ object ScalaJSPluginInternal { // Do not inherit jsExecutionFiles in Test from Compile jsExecutionFiles in Test := jsExecutionFiles.value, - scalaJSConsole := ConsoleJSConsole, - clean := { // have clean reset incremental linker state val _ = clean.value From 2d3a7e225048da27ef756c2a48ed623006dcb592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 1 Jun 2017 16:46:51 +0200 Subject: [PATCH 0298/2665] Remove the `JSConsole` argument to `new ScalaJSFramework`. It is not used anymore. Moreover, the sbt testing interface for the JVM does not offer a similar mechanism allowing to redirect the standard output. Therefore, providing it to the Scala.js testing framework adapter is useless complexity. --- .../org/scalajs/sbtplugin/ScalaJSPluginInternal.scala | 2 +- .../org/scalajs/sbttestadapter/ScalaJSFramework.scala | 10 ++++------ .../org/scalajs/sbttestadapter/ScalaJSRunner.scala | 4 ++-- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index a29b108c13..a4025d6c87 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -550,7 +550,7 @@ object ScalaJSPluginInternal { detector.detect(frameworks, toolsLogger) map { case (tf, name) => (tf, new ScalaJSFramework(name, env, files, moduleKind, - moduleIdentifier, toolsLogger, ConsoleJSConsole)) + moduleIdentifier, toolsLogger)) } }, // Override default to avoid triggering a test:fastOptJS in a test:compile diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala index 77b9c30db1..9fdcec9607 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala @@ -26,14 +26,12 @@ final class ScalaJSFramework( private val jsFiles: Seq[VirtualJSFile], private[testadapter] val moduleKind: ModuleKind, private[testadapter] val moduleIdentifier: Option[String], - private[testadapter] val logger: Logger, - private[testadapter] val jsConsole: JSConsole + private[testadapter] val logger: Logger ) extends Framework { def this(frameworkName: String, jsEnv: ComJSEnv, jsFiles: Seq[VirtualJSFile], - logger: Logger, jsConsole: JSConsole) = { - this(frameworkName, jsEnv, jsFiles, ModuleKind.NoModule, None, logger, - jsConsole) + logger: Logger) = { + this(frameworkName, jsEnv, jsFiles, ModuleKind.NoModule, None, logger) } private[this] val frameworkInfo = fetchFrameworkInfo() @@ -64,7 +62,7 @@ final class ScalaJSFramework( private def fetchFrameworkInfo() = { val runner = newComRunner(frameworkInfoLauncher :: Nil) - runner.start(logger, jsConsole) + runner.start(logger, ConsoleJSConsole) try { val msg = readJSON(runner.receive()) diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala index a10abdd4d5..037a16f3f8 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala @@ -178,7 +178,7 @@ final class ScalaJSRunner private[testadapter] ( // Launch the slave val slave = framework.newComRunner(slaveLauncher :: Nil) - slave.start(framework.logger, framework.jsConsole) + slave.start(framework.logger, ConsoleJSConsole) // Create a runner on the slave slave.send("newRunner") @@ -219,7 +219,7 @@ final class ScalaJSRunner private[testadapter] ( assert(master == null) master = framework.newComRunner(masterLauncher :: Nil) - master.start(framework.logger, framework.jsConsole) + master.start(framework.logger, ConsoleJSConsole) val data = { val bld = new JSONObjBuilder From 6a74e50eeb4b143b7d5ae95d5266dadbb978e733 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 2 Jun 2017 13:25:46 +0200 Subject: [PATCH 0299/2665] Version 0.6.17. --- ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index d7d960e5f0..f08b0159a5 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.17-SNAPSHOT" + val current: String = "0.6.17" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" @@ -21,12 +21,12 @@ object ScalaJSVersions { * - a prior release version (i.e. "0.5.0", *not* "0.5.0-SNAPSHOT") * - `current` */ - val binaryEmitted: String = current + val binaryEmitted: String = "0.6.17" /** Versions whose binary files we can support (used by deserializer) */ val binarySupported: Set[String] = { Set("0.6.0", "0.6.3", "0.6.4", "0.6.5", "0.6.6", "0.6.8", "0.6.13", - "0.6.14", "0.6.15", binaryEmitted) + "0.6.14", "0.6.15", "0.6.17", binaryEmitted) } // Just to be extra safe From 7821708e728e1cc045db2692ee03081ce40948a8 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 28 May 2017 16:08:05 +0200 Subject: [PATCH 0300/2665] Delete unused files from tools --- .../scalajs/core/tools/io/CacheUtils.scala | 52 ------------------- .../core/tools/javascript/package.scala | 12 ----- .../tools/linker/backend/LinkerBackend.scala | 2 +- 3 files changed, 1 insertion(+), 65 deletions(-) delete mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/io/CacheUtils.scala delete mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/javascript/package.scala diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/CacheUtils.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/CacheUtils.scala deleted file mode 100644 index 73acad5e74..0000000000 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/CacheUtils.scala +++ /dev/null @@ -1,52 +0,0 @@ -package org.scalajs.core.tools.io - -object CacheUtils { - - def joinVersions(vs: Option[String]*): Option[String] = { - val bld = new StringBuilder - - @scala.annotation.tailrec - def loop(vs: Seq[Option[String]]): Option[String] = { - vs match { - case Some(v) :: vss => - bld.append(mangleVersionString(v)) - loop(vss) - case None :: _ => - None - case Nil => - Some(bld.toString) - } - } - - loop(vs.toList) - } - - def joinVersions(vs: String*): String = - vs.map(mangleVersionString _).mkString - - private def mangleVersionString(str: String) = s"${str.length}:$str" - - def cached(version: Option[String], output: VirtualFile, - cache: Option[WritableVirtualTextFile])(action: => Unit): Unit = { - - val upToDate = output.exists && ( - for { - v <- version - c <- cache if c.exists - } yield c.content == v - ).getOrElse(false) - - // Are we outdated? - if (!upToDate) { - action - - // Write cache - for (c <- cache; v <- version) { - val w = c.contentWriter - try w.write(v) - finally w.close() - } - } - } - -} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/package.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/package.scala deleted file mode 100644 index 610a8170a1..0000000000 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/package.scala +++ /dev/null @@ -1,12 +0,0 @@ -package org.scalajs.core.tools - -package object javascript { - // Backward source compatibility for build files - - @deprecated("Use org.scalajs.core.tools.linker.backend.OutputMode instead.", "0.6.6") - type OutputMode = org.scalajs.core.tools.linker.backend.OutputMode - - @deprecated("Use org.scalajs.core.tools.linker.backend.OutputMode instead.", "0.6.6") - lazy val OutputMode = org.scalajs.core.tools.linker.backend.OutputMode - -} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala index 53c984d31c..4af83d8899 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala @@ -53,7 +53,7 @@ abstract class LinkerBackend( /** Verify that a [[LinkingUnit]] corresponds to this [[LinkerBackend]]'s * [[org.scalajs.core.tools.sem.Semantics Semantics]] and * [[org.scalajs.core.tools.javascript.ESLevel ESLevel]] (specified via the - * [[org.scalajs.core.tools.javascript.OutputMode OutputMode]]). + * [[OutputMode]]). * @throws java.lang.IllegalArgumentException if there is a mismatch */ protected def verifyUnit(unit: LinkingUnit): Unit = { From f661323839f3132c999285eab955feb2f1111899 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 3 Jun 2017 10:50:51 +0200 Subject: [PATCH 0301/2665] Towards 0.6.18. --- .../org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- project/BinaryIncompatibilities.scala | 28 ------------------- project/Build.scala | 2 +- 3 files changed, 2 insertions(+), 30 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index f08b0159a5..5895c46b3c 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.17" + val current: String = "0.6.18-SNAPSHOT" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index e9c892a59c..c77318b933 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -6,29 +6,6 @@ object BinaryIncompatibilities { ) val Tools = Seq( - // private[emitter], not an issue - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.JSGen.this"), - - // private[optimizer], not an issue - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#RollbackException.this"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#RollbackException.savedStatesInUse"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#RollbackException.savedUsedLabelNames"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#RollbackException.savedUsedLocalNames"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#RollbackException.stateBackups"), - ProblemFilters.exclude[MissingTypesProblem]( - "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore$SimpleState"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#SimpleState.this"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore#SimpleState.makeBackup"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore$State") ) val JSEnvs = Seq( @@ -47,11 +24,6 @@ object BinaryIncompatibilities { ) val Library = Seq( - // New members of an @js.native trait in `runtime`, not an issue - ProblemFilters.exclude[ReversedMissingMethodProblem]( - "scala.scalajs.runtime.LinkingInfo.globalThis"), - ProblemFilters.exclude[ReversedMissingMethodProblem]( - "scala.scalajs.runtime.LinkingInfo.scala$scalajs$runtime$LinkingInfo$_setter_$globalThis_=") ) val TestInterface = Seq( diff --git a/project/Build.scala b/project/Build.scala index 4081c53827..4859546ac8 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -56,7 +56,7 @@ object Build { val shouldPartest = settingKey[Boolean]( "Whether we should partest the current scala version (and fail if we can't)") - val previousVersion = "0.6.16" + val previousVersion = "0.6.17" val previousSJSBinaryVersion = ScalaJSCrossVersion.binaryScalaJSVersion(previousVersion) val previousBinaryCrossVersion = From be3c3a5e0b58a6e4884905c0626bfa2a1b24671e Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 3 Jun 2017 11:26:23 +0200 Subject: [PATCH 0302/2665] Update documentation on nativeness of JS types This is a remnant of #2829 (make ScalaJSDefined default). --- .../src/main/scala/scala/scalajs/js/Any.scala | 25 ++++++++++--------- .../main/scala/scala/scalajs/js/package.scala | 4 --- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/js/Any.scala b/library/src/main/scala/scala/scalajs/js/Any.scala index d6ca0f567d..5e97c4890b 100644 --- a/library/src/main/scala/scala/scalajs/js/Any.scala +++ b/library/src/main/scala/scala/scalajs/js/Any.scala @@ -28,22 +28,23 @@ import annotation.ScalaJSDefined * [[AnyVal]]). Operations on JavaScript types behave as the corresponding * operations in the JavaScript language. * - * By default, JavaScript types are native: they are facade types to APIs - * implemented in JavaScript code. Their implementation is irrelevant and - * never emitted. As such, all members must be defined with their - * right-hand-side being [[native js.native]]. For forward source - * compatibility with the next major version, the class/trait/object itself - * should be annotated with [[native @js.native]]. + * You can implement JavaScript types in Scala.js. The implementation + * (i.e., the method and constructor bodies) will follow Scala semantics, but + * the constructor and methods will be called using JavaScript semantics + * (e.g., runtime dispatch). + * + * A JavaScript type that is annotated with [[native @js.native]] is a facade + * type to APIs implemented in JavaScript code. Its implementation is + * irrelevant and never emitted. As such, all members must be defined with + * their right-hand-side being [[native js.native]]. + * Further, native JavaScript types must be annotated with one of + * [[annotation.JSGlobal @JSGlobal]], [[annotation.JSImport @JSImport]], + * [[annotation.JSGlobalScope @JSGlobalScope]] to specify where to fetch it + * from. * * In most cases, you should not directly extend this trait, but rather extend * [[Object js.Object]]. * - * To implement a JavaScript type in Scala.js (therefore non-native), its - * declaration must be annotated with - * [[annotation.ScalaJSDefined @ScalaJSDefined]]. Scala.js-defined JS types - * cannot directly extend native JS traits; and Scala.js-defined JS traits - * cannot declare concrete term members. - * * It is not possible to define traits or classes that inherit both from this * trait and a strict subtype of [[AnyRef]]. In fact, you should think of * [[Any js.Any]] as a third direct subclass of [[scala.Any]], besides diff --git a/library/src/main/scala/scala/scalajs/js/package.scala b/library/src/main/scala/scala/scalajs/js/package.scala index 8a3db3a436..31b9d8fb19 100644 --- a/library/src/main/scala/scala/scalajs/js/package.scala +++ b/library/src/main/scala/scala/scalajs/js/package.scala @@ -107,10 +107,6 @@ package object js { * Native JS entities are not implemented in Scala.js. They are facade types * for native JS libraries. * - * In Scala.js 0.6.x, all types extending [[Any js.Any]] are native by - * default (unless they are annotated with [[annotation.ScalaJSDefined]]), - * but this will not be the case in the next major version anymore. - * * Only types extending [[Any js.Any]] can be annotated with `@js.native`. * The body of all concrete members in a native JS class, trait or object * must be `= js.native`. From b50aa28cd41877273f32f8f9ff9dabeac3bd6994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 3 Jun 2017 17:55:08 +0200 Subject: [PATCH 0303/2665] Remove an unused file in sbt-plugin-test/jetty9/. This was forgotten in 1c063791122f6c33005a41b507f71f2430085ee3. --- sbt-plugin-test/jetty9/src/main/resources/test.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 sbt-plugin-test/jetty9/src/main/resources/test.txt diff --git a/sbt-plugin-test/jetty9/src/main/resources/test.txt b/sbt-plugin-test/jetty9/src/main/resources/test.txt deleted file mode 100644 index 68300b8563..0000000000 --- a/sbt-plugin-test/jetty9/src/main/resources/test.txt +++ /dev/null @@ -1 +0,0 @@ -It works! From 981a19335fba06e693dd974d9fa8bdbf5bef52b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 3 Jun 2017 18:16:36 +0200 Subject: [PATCH 0304/2665] Fix #2841: Remove jsDependencies-related stuff from the core repo. Support for `jsDependencies` has been moved to the separate repository https://github.com/scala-js/jsdependencies. --- build.sbt | 2 - ci/matrix.xml | 13 +- .../core/DependencyResolver.scala | 199 ---------- .../jsdependencies/core/Exceptions.scala | 104 ----- .../core/FlatJSDependency.scala | 39 -- .../jsdependencies/core/JSDependency.scala | 111 ------ .../core/JSDependencyManifest.scala | 96 ----- .../jsdependencies/core/ManifestFilters.scala | 48 --- .../scalajs/jsdependencies/core/Origin.scala | 49 --- .../jsdependencies/core/ResolutionInfo.scala | 36 -- .../core/ResolvedJSDependency.scala | 23 -- .../core/ManifestFiltersTest.scala | 46 --- .../sbtplugin/AbstractJSDeps.scala | 82 ---- .../sbtplugin/JSDependenciesPlugin.scala | 365 ------------------ project/Build.scala | 33 -- sbt-plugin-test/build.sbt | 104 ----- .../main/resources/js/customJQuery/jquery.js | 1 - .../src/main/resources/js/foo.js | 1 - .../main/resources/js/some-jquery-plugin.js | 1 - sbt-plugin-test/project/build.sbt | 3 - 20 files changed, 4 insertions(+), 1352 deletions(-) delete mode 100644 jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/DependencyResolver.scala delete mode 100644 jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/Exceptions.scala delete mode 100644 jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/FlatJSDependency.scala delete mode 100644 jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/JSDependency.scala delete mode 100644 jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/JSDependencyManifest.scala delete mode 100644 jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/ManifestFilters.scala delete mode 100644 jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/Origin.scala delete mode 100644 jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/ResolutionInfo.scala delete mode 100644 jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/ResolvedJSDependency.scala delete mode 100644 jsdependencies-core/src/test/scala/org/scalajs/jsdependencies/core/ManifestFiltersTest.scala delete mode 100644 jsdependencies-sbt-plugin/src/main/scala/org/scalajs/jsdependencies/sbtplugin/AbstractJSDeps.scala delete mode 100644 jsdependencies-sbt-plugin/src/main/scala/org/scalajs/jsdependencies/sbtplugin/JSDependenciesPlugin.scala delete mode 100644 sbt-plugin-test/jsDependenciesTest/src/main/resources/js/customJQuery/jquery.js delete mode 100644 sbt-plugin-test/jsDependenciesTest/src/main/resources/js/foo.js delete mode 100644 sbt-plugin-test/jsDependenciesTest/src/main/resources/js/some-jquery-plugin.js diff --git a/build.sbt b/build.sbt index 4258478967..14fed3c921 100644 --- a/build.sbt +++ b/build.sbt @@ -21,8 +21,6 @@ val jUnitRuntime = Build.jUnitRuntime val jUnitTestOutputsJS = Build.jUnitTestOutputsJS val jUnitTestOutputsJVM = Build.jUnitTestOutputsJVM val jUnitPlugin = Build.jUnitPlugin -val jsDependenciesCore = Build.jsDependenciesCore -val jsDependenciesPlugin = Build.jsDependenciesPlugin val examples = Build.examples val helloworld = Build.helloworld val reversi = Build.reversi diff --git a/ci/matrix.xml b/ci/matrix.xml index 513d3eb96c..569783d460 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -154,7 +154,7 @@ setJavaVersion $java npm install && sbt ++$scala tools/package ir/test tools/test cli/package cli/assembly \ - stubs/package jsEnvsTestSuite/test jsDependenciesCore/test \ + stubs/package jsEnvsTestSuite/test \ ir/mimaReportBinaryIssues tools/mimaReportBinaryIssues \ jsEnvs/mimaReportBinaryIssues jsEnvsTestKit/mimaReportBinaryIssues \ testAdapter/mimaReportBinaryIssues \ @@ -168,8 +168,8 @@ setJavaVersion $java npm install && sbt ++$scala tools/package ir/test tools/test cli/package cli/assembly \ - stubs/package jsEnvsTestSuite/test jsDependenciesCore/test \ - sbtPlugin/package jsDependenciesPlugin/package \ + stubs/package jsEnvsTestSuite/test \ + sbtPlugin/package \ ir/mimaReportBinaryIssues tools/mimaReportBinaryIssues \ jsEnvs/mimaReportBinaryIssues jsEnvsTestKit/mimaReportBinaryIssues \ testAdapter/mimaReportBinaryIssues \ @@ -209,18 +209,13 @@ testInterface/publishLocal stubs/publishLocal \ jUnitPlugin/publishLocal jUnitRuntime/publishLocal && sbt ++2.10.6 ir/publishLocal tools/publishLocal jsEnvs/publishLocal \ - testAdapter/publishLocal sbtPlugin/publishLocal \ - jsDependenciesCore/publishLocal jsDependenciesPlugin/publishLocal && + testAdapter/publishLocal sbtPlugin/publishLocal && cd sbt-plugin-test && sbt noDOM/run noDOM/testHtmlFastOpt noDOM/testHtmlFullOpt \ withDOM/run withDOM/testHtmlFastOpt withDOM/testHtmlFullOpt \ multiTestJS/testHtmlFastOpt multiTestJS/testHtmlFullOpt \ test \ noDOM/clean noDOM/concurrentUseOfLinkerTest \ - jsDependenciesTest/packageJSDependencies \ - jsDependenciesTest/packageMinifiedJSDependencies \ - jsDependenciesTest/regressionTestForIssue2243 \ - jsNoDependenciesTest/regressionTestForIssue2243 \ multiTestJS/test:testScalaJSSourceMapAttribute ]]> diff --git a/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/DependencyResolver.scala b/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/DependencyResolver.scala deleted file mode 100644 index 57df985401..0000000000 --- a/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/DependencyResolver.scala +++ /dev/null @@ -1,199 +0,0 @@ -package org.scalajs.jsdependencies.core - -import scala.collection.mutable - -import org.scalajs.core.tools.io.VirtualJSFile -import JSLibResolveException.Problem - -object DependencyResolver { - - type DependencyFilter = - Traversable[FlatJSDependency] => Traversable[FlatJSDependency] - - /** Constructs an ordered list of JS libraries to include. Fails if: - * - Resource names do not identify a unique resource on the classpath - * - Dependencies have cycles - * - Not all dependencies are available - */ - def resolveDependencies( - manifests: Traversable[JSDependencyManifest], - availableLibs: Map[String, VirtualJSFile], - dependencyFilter: DependencyFilter): List[ResolvedJSDependency] = { - - val resourceNames = collectAllResourceNames(manifests) - val resolvedJSLibs = - resolveAllResourceNames(resourceNames, availableLibs.keys) - - val allFlatDeps = for { - manifest <- manifests - dep <- manifest.libDeps - } yield { - new FlatJSDependency( - manifest.origin, - resolvedJSLibs(dep.resourceName), - dep.dependencies.map(resolvedJSLibs), - dep.commonJSName, - dep.minifiedResourceName.map(resolvedJSLibs)) - } - - val flatDeps = dependencyFilter(allFlatDeps) - val includeList = createIncludeList(flatDeps) - - for (info <- includeList) yield { - new ResolvedJSDependency(availableLibs(info.relPath), - info.relPathMinified.map(availableLibs), info) - } - } - - /** Collects all the resource names mentioned in the manifests. - * @param manifests to collect from - * @return Map from resource name to the list of origins mentioning them - */ - private def collectAllResourceNames( - manifests: Traversable[JSDependencyManifest]): Map[String, List[Origin]] = { - - def allResources(dep: JSDependency) = - dep.resourceName :: dep.dependencies ::: dep.minifiedResourceName.toList - - val nameOriginPairs = for { - manifest <- manifests.toList - dep <- manifest.libDeps - resourceName <- allResources(dep) - } yield (resourceName, manifest.origin) - - nameOriginPairs.groupBy(_._1).mapValues(_.map(_._2)) - } - - /** Resolves all the resource names wrt to the current classpath. - * @throws JSLibResolveException if any of the resource names cannot be resolved - * @return Map from resource name to relative path - */ - private def resolveAllResourceNames( - allResourceNames: Map[String, List[Origin]], - relPaths: Traversable[String]): Map[String, String] = { - val problems = mutable.ListBuffer.empty[Problem] - val resolvedLibs = Map.newBuilder[String, String] - - for ((resourceName, origins) <- allResourceNames) { - resolveResourceName(resourceName, origins, relPaths).fold[Unit]( - problems += _, - resolvedLibs += resourceName -> _) - } - - if (problems.nonEmpty) - throw new JSLibResolveException(problems.toList) - else - resolvedLibs.result() - } - - /** Resolves one resource name wrt to the current classpath. */ - private def resolveResourceName(resourceName: String, origins: List[Origin], - relPaths: Traversable[String]): Either[Problem, String] = { - val candidates = (relPaths collect { - case relPath if ("/" + relPath).endsWith("/" + resourceName) => - relPath - }).toList - - candidates match { - case relPath :: Nil => - Right(relPath) - case _ => - Left(new Problem(resourceName, candidates, origins)) - } - } - - /** Create a sorted include list for js libs */ - private def createIncludeList( - flatDeps: Traversable[FlatJSDependency]): List[ResolutionInfo] = { - val jsDeps = mergeManifests(flatDeps) - - // Verify all dependencies are met - for { - lib <- flatDeps - dep <- lib.dependencies - if !jsDeps.contains(dep) - } throw new MissingDependencyException(lib, dep) - - // Sort according to dependencies and return - - // Very simple O(n²) topological sort for elements assumed to be distinct - // Copied :( from GenJSExports (but different exception) - @scala.annotation.tailrec - def loop(coll: List[ResolutionInfo], - acc: List[ResolutionInfo]): List[ResolutionInfo] = { - - if (coll.isEmpty) acc - else if (coll.tail.isEmpty) coll.head :: acc - else { - val (selected, pending) = coll.partition { x => - coll forall { y => (x eq y) || !y.dependencies.contains(x.relPath) } - } - - if (selected.nonEmpty) - loop(pending, selected ::: acc) - else - throw new CyclicDependencyException(pending) - } - } - - loop(jsDeps.values.toList, Nil) - } - - /** Merges multiple JSDependencyManifests into a map of map: - * resourceName -> ResolutionInfo - */ - private def mergeManifests(flatDeps: Traversable[FlatJSDependency]) = { - checkCommonJSNameConflicts(flatDeps) - - val byRelPath = flatDeps.groupBy(_.relPath) - - checkMinifiedJSConflicts(byRelPath) - - byRelPath.mapValues { sameName => - new ResolutionInfo( - relPath = sameName.head.relPath, - dependencies = sameName.flatMap(_.dependencies).toSet, - origins = sameName.map(_.origin).toList, - commonJSName = sameName.flatMap(_.commonJSName).headOption, - relPathMinified = sameName.flatMap(_.relPathMinified).headOption - ) - } - } - - private def checkCommonJSNameConflicts(flatDeps: Traversable[FlatJSDependency]) = { - @inline - def hasConflict(x: FlatJSDependency, y: FlatJSDependency) = ( - x.commonJSName.isDefined && - y.commonJSName.isDefined && - (x.relPath == y.relPath ^ x.commonJSName == y.commonJSName) - ) - - val conflicts = for { - dep <- flatDeps - if flatDeps.exists(hasConflict(dep, _)) - } yield dep - - if (conflicts.nonEmpty) - throw new ConflictingNameException(conflicts.toList) - } - - private def checkMinifiedJSConflicts( - byRelPath: Map[String, Traversable[FlatJSDependency]]) = { - - @inline - def hasConflict(x: FlatJSDependency, y: FlatJSDependency) = ( - x.relPathMinified.isDefined && - y.relPathMinified.isDefined && - x.relPathMinified != y.relPathMinified - ) - - val conflicts = for { - (_, deps) <- byRelPath - x <- deps if deps.exists(y => hasConflict(x, y)) - } yield x - - if (conflicts.nonEmpty) - throw new ConflictingMinifiedJSException(conflicts.toList) - } - -} diff --git a/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/Exceptions.scala b/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/Exceptions.scala deleted file mode 100644 index d783774497..0000000000 --- a/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/Exceptions.scala +++ /dev/null @@ -1,104 +0,0 @@ -package org.scalajs.jsdependencies.core - -abstract class DependencyException(msg: String) extends Exception(msg) - -class MissingDependencyException( - val originatingLib: FlatJSDependency, - val missingLib: String -) extends DependencyException( - s"The JS dependency ${originatingLib.relPath} declared " + - s"from ${originatingLib.origin} has an unmet transitive " + - s"dependency $missingLib") - -class CyclicDependencyException( - val participants: List[ResolutionInfo] -) extends DependencyException( - CyclicDependencyException.mkMsg(participants)) - -private object CyclicDependencyException { - private def mkMsg(parts: List[ResolutionInfo]) = { - val lookup = parts.map(p => (p.relPath, p)).toMap - - val msg = new StringBuilder() - msg.append("There is a loop in the following JS dependencies:\n") - - def str(info: ResolutionInfo) = - s"${info.relPath} from: ${info.origins.mkString(", ")}" - - for (dep <- parts) { - msg.append(s" ${str(dep)} which depends on\n") - for (name <- dep.dependencies) { - val rdep = lookup(name) - msg.append(s" - ${str(rdep)}\n") - } - } - - msg.toString() - } -} - -class ConflictingNameException( - val participants: List[FlatJSDependency] -) extends DependencyException( - ConflictingNameException.mkMsg(participants)) - -private object ConflictingNameException { - private def mkMsg(parts: List[FlatJSDependency]) = { - val msg = new StringBuilder() - msg.append(s"CommonJSName conflicts in:\n") - - for (p <- parts) { - msg.append(p) - msg.append('\n') - } - - msg.toString() - } -} - -class ConflictingMinifiedJSException( - val participants: List[FlatJSDependency] -) extends DependencyException( - ConflictingMinifiedJSException.mkMsg(participants)) - -private object ConflictingMinifiedJSException { - private def mkMsg(parts: List[FlatJSDependency]) = { - val msg = new StringBuilder() - msg.append(s"Minified JS conflicts in:\n") - - for (p <- parts) { - msg.append(p) - msg.append('\n') - } - - msg.toString() - } -} - -class JSLibResolveException(val problems: List[JSLibResolveException.Problem]) - extends Exception(JSLibResolveException.mkMsg(problems)) - -object JSLibResolveException { - final class Problem(val resourceName: String, - val possiblePaths: List[String], val origins: List[Origin]) { - def isMissing: Boolean = possiblePaths.isEmpty - def isAmbiguous: Boolean = possiblePaths.nonEmpty - } - - private def mkMsg(problems: List[Problem]): String = { - val msg = new StringBuilder - msg.append("Some references to JS libraries could not be resolved:\n") - for (p <- problems) { - if (p.isMissing) { - msg.append(s"- Missing JS library: ${p.resourceName}\n") - } else { - msg.append(s"- Ambiguous reference to a JS library: ${p.resourceName}\n") - msg.append(" Possible paths found on the classpath:\n") - for (relPath <- p.possiblePaths) - msg.append(s" - $relPath\n") - } - msg.append(s" originating from: ${p.origins.mkString(", ")}\n") - } - msg.toString() - } -} diff --git a/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/FlatJSDependency.scala b/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/FlatJSDependency.scala deleted file mode 100644 index c3b143a410..0000000000 --- a/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/FlatJSDependency.scala +++ /dev/null @@ -1,39 +0,0 @@ -package org.scalajs.jsdependencies.core - -import org.scalajs.core.ir.Trees.isValidIdentifier - -/** The same as a [[JSDependency]] but containing the origin from the containing - * JSDependencyManifest, and resolved relative paths. - * - * This class is used for filtering of dependencies. - * - * @param origin What module declared this dependency - * @param relPath Path of the JavaScript file, relative to the classpath entry - * @param dependencies Relative paths of files this dependency depends on - * @param commonJSName Variable name in commonJS environments - * @param relPathMinified Path of the minified JavaScript file, relative to - * the classpath entry - */ -final class FlatJSDependency( - val origin: Origin, - val relPath: String, - val dependencies: List[String] = Nil, - val commonJSName: Option[String] = None, - val relPathMinified: Option[String] = None) { - - require(commonJSName.forall(isValidIdentifier), - "commonJSName must be a valid JavaScript identifier") - - override def toString(): String = { - val b = new StringBuilder - b ++= s"FlatJSDependency(origin=$origin, relPath=$relPath" - if (dependencies.nonEmpty) - b ++= s", dependencies=$dependencies" - if (commonJSName.nonEmpty) - b ++= s", commonJSName=$commonJSName" - if (relPathMinified.nonEmpty) - b ++= s", relPathMinified=$relPathMinified" - b ++= ")" - b.result() - } -} diff --git a/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/JSDependency.scala b/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/JSDependency.scala deleted file mode 100644 index 8c833cd56d..0000000000 --- a/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/JSDependency.scala +++ /dev/null @@ -1,111 +0,0 @@ -package org.scalajs.jsdependencies.core - -import org.scalajs.core.tools.json._ - -import org.scalajs.core.ir.Trees.isValidIdentifier - -/** Expresses a dependency on a raw JS library and the JS libraries this library - * itself depends on. - * - * Both the [[resourceName]] and each element of [[dependencies]] are - * potentially partial relative paths from the root of the classpath entry to - * the library. Examples are "jquery.js" or "compressed/history.js". - * - * @param resourceName Resource name, i.e., potentially partial relative path - * to the .js file. Examples: "jquery.js", "compressed/history.js". - * @param dependencies Potentially relative paths of the dependencies of this - * resource, i.e., JavaScript files that must be included before this - * JavaScript file. - * @param commonJSName A JavaScript variable name this dependency should be - * required in a commonJS environment (n.b. Node.js). Should only be set if - * the JavaScript library will register its exports. - * @param minifiedResourceName Resource name for the minified version - */ -final class JSDependency( - val resourceName: String, - val dependencies: List[String] = Nil, - val commonJSName: Option[String] = None, - val minifiedResourceName: Option[String] = None) { - - import JSDependency._ - - require(commonJSName.forall(isValidIdentifier), - "commonJSName must be a valid JavaScript identifier") - - def dependsOn(names: String*): JSDependency = - copy(dependencies = dependencies ++ names) - def commonJSName(name: String): JSDependency = - copy(commonJSName = Some(name)) - def minified(name: String): JSDependency = - copy(minifiedResourceName = Some(name)) - - private def copy( - resourceName: String = this.resourceName, - dependencies: List[String] = this.dependencies, - commonJSName: Option[String] = this.commonJSName, - minifiedResourceName: Option[String] = this.minifiedResourceName) = { - new JSDependency(resourceName, dependencies, - commonJSName, minifiedResourceName) - } - - override def equals(that: Any): Boolean = that match { - case that: JSDependency => - this.resourceName == that.resourceName && - this.dependencies == that.dependencies && - this.commonJSName == that.commonJSName && - this.minifiedResourceName == that.minifiedResourceName - case _ => - false - } - - override def hashCode(): Int = { - import scala.util.hashing.MurmurHash3._ - var acc = HashSeed - acc = mix(acc, resourceName.##) - acc = mix(acc, dependencies.##) - acc = mix(acc, commonJSName.##) - acc = mixLast(acc, minifiedResourceName.##) - finalizeHash(acc, 4) - } - - override def toString(): String = { - val b = new StringBuilder - b ++= s"JSDependency(resourceName=$resourceName" - if (commonJSName.nonEmpty) - b ++= s", commonJSName=$commonJSName" - if (minifiedResourceName.nonEmpty) - b ++= s", minifiedResourceName=$minifiedResourceName" - if (dependencies.nonEmpty) - b ++= s", dependencies=$dependencies" - b ++= ")" - b.result() - } -} - -object JSDependency { - // "org.scalajs.jsdependencies.core.JSDependency".## - private final val HashSeed = -579921360 - - implicit object JSDepJSONSerializer extends JSONSerializer[JSDependency] { - def serialize(x: JSDependency): JSON = { - new JSONObjBuilder() - .fld("resourceName", x.resourceName) - .opt("dependencies", - if (x.dependencies.nonEmpty) Some(x.dependencies) else None) - .opt("commonJSName", x.commonJSName) - .opt("minifiedResourceName", x.minifiedResourceName) - .toJSON - } - } - - implicit object JSDepJSONDeserializer extends JSONDeserializer[JSDependency] { - def deserialize(x: JSON): JSDependency = { - val obj = new JSONObjExtractor(x) - new JSDependency( - obj.fld[String] ("resourceName"), - obj.opt[List[String]]("dependencies").getOrElse(Nil), - obj.opt[String] ("commonJSName"), - obj.opt[String] ("minifiedResourceName")) - } - } -} diff --git a/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/JSDependencyManifest.scala b/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/JSDependencyManifest.scala deleted file mode 100644 index e1c5d0d07d..0000000000 --- a/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/JSDependencyManifest.scala +++ /dev/null @@ -1,96 +0,0 @@ -package org.scalajs.jsdependencies.core - -import org.scalajs.core.tools.json._ -import org.scalajs.core.tools.io._ - -import scala.collection.immutable.{Seq, Traversable} - -import java.io.{Reader, Writer} - -/** The information written to a "JS_DEPENDENCIES" manifest file. */ -final class JSDependencyManifest( - val origin: Origin, - val libDeps: List[JSDependency], - val requiresDOM: Boolean) { - - import JSDependencyManifest._ - - override def equals(that: Any): Boolean = that match { - case that: JSDependencyManifest => - this.origin == that.origin && - this.libDeps == that.libDeps && - this.requiresDOM == that.requiresDOM - case _ => - false - } - - override def hashCode(): Int = { - import scala.util.hashing.MurmurHash3._ - var acc = HashSeed - acc = mix(acc, origin.##) - acc = mix(acc, libDeps.##) - acc = mixLast(acc, requiresDOM.##) - finalizeHash(acc, 3) - } - - override def toString(): String = { - val b = new StringBuilder - b ++= s"JSDependencyManifest(origin=$origin" - if (libDeps.nonEmpty) - b ++= s", libDeps=$libDeps" - if (requiresDOM) - b ++= s", requiresDOM=$requiresDOM" - b ++= ")" - b.result() - } -} - -object JSDependencyManifest { - - // "org.scalajs.jsdependencies.core.JSDependencyManifest".## - private final val HashSeed = -902988673 - - final val ManifestFileName = "JS_DEPENDENCIES" - - implicit object JSDepManJSONSerializer extends JSONSerializer[JSDependencyManifest] { - @inline def optList[T](x: List[T]): Option[List[T]] = - if (x.nonEmpty) Some(x) else None - - def serialize(x: JSDependencyManifest): JSON = { - new JSONObjBuilder() - .fld("origin", x.origin) - .opt("libDeps", optList(x.libDeps)) - .opt("requiresDOM", if (x.requiresDOM) Some(true) else None) - .toJSON - } - } - - implicit object JSDepManJSONDeserializer extends JSONDeserializer[JSDependencyManifest] { - def deserialize(x: JSON): JSDependencyManifest = { - val obj = new JSONObjExtractor(x) - new JSDependencyManifest( - obj.fld[Origin]("origin"), - obj.opt[List[JSDependency]]("libDeps").getOrElse(Nil), - obj.opt[Boolean]("requiresDOM").getOrElse(false)) - } - } - - def write(dep: JSDependencyManifest, output: WritableVirtualTextFile): Unit = { - val writer = output.contentWriter - try write(dep, writer) - finally writer.close() - } - - def write(dep: JSDependencyManifest, writer: Writer): Unit = - writeJSON(dep.toJSON, writer) - - def read(file: VirtualTextFile): JSDependencyManifest = { - val reader = file.reader - try read(reader) - finally reader.close() - } - - def read(reader: Reader): JSDependencyManifest = - fromJSON[JSDependencyManifest](readJSON(reader)) - -} diff --git a/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/ManifestFilters.scala b/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/ManifestFilters.scala deleted file mode 100644 index fdc5a22dec..0000000000 --- a/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/ManifestFilters.scala +++ /dev/null @@ -1,48 +0,0 @@ -package org.scalajs.jsdependencies.core - -/** Holds useful JSDependencyManifest filters */ -object ManifestFilters { - - type ManifestFilter = - Traversable[JSDependencyManifest] => Traversable[JSDependencyManifest] - - /** Creates a manifest filter that maps resource names of a certain - * origin as if they were written differently - * @param moduleNames Modules for which the mapping should be applied - * @param nameMappings resource name mappings - */ - def reinterpretResourceNames(moduleNames: String*)( - nameMappings: (String, String)*): ManifestFilter = { - val modSet = moduleNames.toSet - val nameMap = nameMappings.toMap - - val mapper = { (origin: Origin) => (oldName: String) => - if (modSet(origin.moduleName)) - nameMap.getOrElse(oldName, oldName) - else - oldName - } - - reinterpretResourceNames(mapper) - } - - /** Creates a manifest filter that maps resource names of a certain - * origin as if they were written differently - * @param mappings Maps manifest origin to old resource name to new - * resource name - */ - def reinterpretResourceNames( - mappings: Origin => String => String): ManifestFilter = { manifests => - for (manifest <- manifests) yield { - val mapping = mappings(manifest.origin) - val filteredJSDeps = for (jsDependency <- manifest.libDeps) - yield new JSDependency( - mapping(jsDependency.resourceName), - jsDependency.dependencies.map(mapping), - jsDependency.commonJSName, - jsDependency.minifiedResourceName.map(mapping)) - new JSDependencyManifest(manifest.origin, filteredJSDeps, - manifest.requiresDOM) - } - } -} diff --git a/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/Origin.scala b/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/Origin.scala deleted file mode 100644 index 430d63709f..0000000000 --- a/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/Origin.scala +++ /dev/null @@ -1,49 +0,0 @@ -package org.scalajs.jsdependencies.core - -import org.scalajs.core.tools.json._ - -/** The place a JSDependency originated from */ -final class Origin(val moduleName: String, val configuration: String) { - import Origin._ - - override def toString(): String = s"$moduleName:$configuration" - - override def equals(that: Any): Boolean = that match { - case that: Origin => - this.moduleName == that.moduleName && - this.configuration == that.configuration - case _ => - false - } - - override def hashCode(): Int = { - import scala.util.hashing.MurmurHash3._ - var acc = HashSeed - acc = mix(acc, moduleName.##) - acc = mixLast(acc, configuration.##) - finalizeHash(acc, 2) - } -} - -object Origin { - // "org.scalajs.jsdependencies.core.Origin".## - private final val HashSeed = -1520336638 - - implicit object OriginJSONSerializer extends JSONSerializer[Origin] { - def serialize(x: Origin): JSON = { - new JSONObjBuilder() - .fld("moduleName", x.moduleName) - .fld("configuration", x.configuration) - .toJSON - } - } - - implicit object OriginDeserializer extends JSONDeserializer[Origin] { - def deserialize(x: JSON): Origin = { - val obj = new JSONObjExtractor(x) - new Origin( - obj.fld[String]("moduleName"), - obj.fld[String]("configuration")) - } - } -} diff --git a/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/ResolutionInfo.scala b/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/ResolutionInfo.scala deleted file mode 100644 index f65a9a55ef..0000000000 --- a/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/ResolutionInfo.scala +++ /dev/null @@ -1,36 +0,0 @@ -package org.scalajs.jsdependencies.core - -import org.scalajs.core.ir.Trees.isValidIdentifier - -/** Information about a resolved JSDependency - * - * @param relPath Path of the JavaScript file, relative to the classpath entry - * @param dependencies Relative paths of files this dependency depends on - * @param origins Who declared this dependency - * @param commonJSName Variable name in commonJS environments - */ -final class ResolutionInfo( - val relPath: String, - val dependencies: Set[String], - val origins: List[Origin], - val commonJSName: Option[String], - val relPathMinified: Option[String]) { - - require(commonJSName.forall(isValidIdentifier), - "commonJSName must be a valid JavaScript identifier") - - override def toString(): String = { - val b = new StringBuilder - b ++= s"ResolutionInfo(relPath=$relPath" - if (dependencies.nonEmpty) - b ++= s", dependencies=$dependencies" - if (origins.nonEmpty) - b ++= s", origins=$origins" - if (commonJSName.nonEmpty) - b ++= s", commonJSName=$commonJSName" - if (relPathMinified.nonEmpty) - b ++= s", relPathMinified=$relPathMinified" - b ++= ")" - b.result() - } -} diff --git a/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/ResolvedJSDependency.scala b/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/ResolvedJSDependency.scala deleted file mode 100644 index 26c700e4dd..0000000000 --- a/jsdependencies-core/src/main/scala/org/scalajs/jsdependencies/core/ResolvedJSDependency.scala +++ /dev/null @@ -1,23 +0,0 @@ -package org.scalajs.jsdependencies.core - -import org.scalajs.core.tools.io._ - -/** A dependency on a native JavaScript library that has been successfully - * resolved - */ -final class ResolvedJSDependency( - val lib: VirtualJSFile, - val minifiedLib: Option[VirtualJSFile], - val info: ResolutionInfo) - -object ResolvedJSDependency { - /** Absolute minimum for a [[ResolvedJSDependency]]: - * - * - The library itself - * - Its relative name (lib.name) - */ - def minimal(lib: VirtualJSFile): ResolvedJSDependency = { - val info = new ResolutionInfo(lib.name, Set.empty, Nil, None, None) - new ResolvedJSDependency(lib, None, info) - } -} diff --git a/jsdependencies-core/src/test/scala/org/scalajs/jsdependencies/core/ManifestFiltersTest.scala b/jsdependencies-core/src/test/scala/org/scalajs/jsdependencies/core/ManifestFiltersTest.scala deleted file mode 100644 index ceb13a06de..0000000000 --- a/jsdependencies-core/src/test/scala/org/scalajs/jsdependencies/core/ManifestFiltersTest.scala +++ /dev/null @@ -1,46 +0,0 @@ -package org.scalajs.jsdependencies.core - -import org.junit.Test -import org.junit.Assert._ - -class ManifestFiltersTest { - import ManifestFilters._ - - private def mkManifest(module: String, deps: String*) = { - new JSDependencyManifest(new Origin(module, "compile"), - deps.map(new JSDependency(_)).toList, requiresDOM = false) - } - - @Test - def reinterpretResourceNamesSimple(): Unit = { - val filter = reinterpretResourceNames("lib-b")( - "jquery.js" -> "2.1.3/jquery.js") - - val otherManifest = mkManifest("lib-a", "2.1.4/jquery.js", "bar.js") - val targetManifest = mkManifest("lib-b", "jquery.js", "foo.js") - - val result = filter(Seq(otherManifest, targetManifest)).toSet - val expected = Set(otherManifest, - mkManifest("lib-b", "2.1.3/jquery.js", "foo.js")) - - assertEquals(expected, result) - } - - @Test - def reinterpretResourceNamesFull(): Unit = { - val filter = reinterpretResourceNames( - origin => oldName => origin.moduleName + oldName) - - val manifests = for { - origin <- Seq("oa", "ob", "oc") - } yield { - val oldLibs = Seq("a.js", "b.js", "c.js") - val newLibs = oldLibs.map(origin + _) - (mkManifest(origin, oldLibs: _*), mkManifest(origin, newLibs: _*)) - } - - val (input, expected) = manifests.unzip - val result = filter(input) - assertEquals(expected, result) - } -} diff --git a/jsdependencies-sbt-plugin/src/main/scala/org/scalajs/jsdependencies/sbtplugin/AbstractJSDeps.scala b/jsdependencies-sbt-plugin/src/main/scala/org/scalajs/jsdependencies/sbtplugin/AbstractJSDeps.scala deleted file mode 100644 index 59e06cfb66..0000000000 --- a/jsdependencies-sbt-plugin/src/main/scala/org/scalajs/jsdependencies/sbtplugin/AbstractJSDeps.scala +++ /dev/null @@ -1,82 +0,0 @@ -package org.scalajs.jsdependencies.sbtplugin - -import sbt._ - -import StringUtilities.nonEmpty - -import org.scalajs.jsdependencies.core.JSDependency - -/** Something JavaScript related a project may depend on. Either a JavaScript - * module/library, or the DOM at runtime. */ -sealed trait AbstractJSDep { - def configurations: Option[String] - - protected def withConfigs(configs: Option[String]): AbstractJSDep - - def %(configurations: Configuration): AbstractJSDep = %(configurations.name) - def %(configurations: String): AbstractJSDep = { - require(this.configurations.isEmpty, - "Configurations already specified for jsModule " + this) - nonEmpty(configurations, "Configurations") - withConfigs(Some(configurations)) - } - -} - -/** A JavaScript module/library a Scala.js project may depend on */ -sealed trait JSModuleID extends AbstractJSDep { - def jsDep: JSDependency - - protected def withJSDep(jsDep: JSDependency): JSModuleID - - def commonJSName(name: String): JSModuleID = - withJSDep(jsDep = jsDep.commonJSName(name)) - - def dependsOn(names: String*): JSModuleID = - withJSDep(jsDep = jsDep.dependsOn(names: _*)) - - def minified(name: String): JSModuleID = - withJSDep(jsDep = jsDep.minified(name)) -} - -/** A JavaScript module that resides inside a jar (probably webjar) */ -final case class JarJSModuleID( - module: ModuleID, - jsDep: JSDependency) extends JSModuleID { - - def configurations: Option[String] = module.configurations - - protected def withConfigs(configs: Option[String]): JSModuleID = - copy(module = module.copy(configurations = configs)) - protected def withJSDep(jsDep: JSDependency): JSModuleID = - copy(jsDep = jsDep) -} - -object JarJSModuleID { - def apply(module: ModuleID, name: String): JarJSModuleID = - JarJSModuleID(module, new JSDependency(name, Nil)) -} - -/** A JavaScript module that we depend on, but is provided externally or - * by the project itself */ -final case class ProvidedJSModuleID( - jsDep: JSDependency, - configurations: Option[String]) extends JSModuleID { - - protected def withConfigs(configs: Option[String]): JSModuleID = - copy(configurations = configs) - protected def withJSDep(jsDep: JSDependency): JSModuleID = - copy(jsDep = jsDep) -} - -object ProvidedJSModuleID { - def apply(name: String, configurations: Option[String]): ProvidedJSModuleID = - ProvidedJSModuleID(new JSDependency(name, Nil), configurations) -} - -final case class RuntimeDOMDep( - configurations: Option[String]) extends AbstractJSDep { - - protected def withConfigs(configs: Option[String]): RuntimeDOMDep = - copy(configurations = configs) -} diff --git a/jsdependencies-sbt-plugin/src/main/scala/org/scalajs/jsdependencies/sbtplugin/JSDependenciesPlugin.scala b/jsdependencies-sbt-plugin/src/main/scala/org/scalajs/jsdependencies/sbtplugin/JSDependenciesPlugin.scala deleted file mode 100644 index f54fd4f643..0000000000 --- a/jsdependencies-sbt-plugin/src/main/scala/org/scalajs/jsdependencies/sbtplugin/JSDependenciesPlugin.scala +++ /dev/null @@ -1,365 +0,0 @@ -package org.scalajs.jsdependencies.sbtplugin - -import scala.collection.mutable -import scala.util.Try - -import java.io.InputStreamReader - -import sbt._ -import sbt.Keys._ - -import org.scalajs.core.ir.Utils.escapeJS - -import org.scalajs.core.tools.io.{IO => toolsIO, _} -import org.scalajs.core.tools.json._ - -import org.scalajs.jsenv.VirtualFileMaterializer - -import org.scalajs.sbtplugin.ScalaJSPlugin -import org.scalajs.sbtplugin.ScalaJSPlugin.autoImport._ -import org.scalajs.sbtplugin.ScalaJSPluginInternal.scalaJSSourceFiles - -import org.scalajs.jsdependencies.core._ -import org.scalajs.jsdependencies.core.DependencyResolver.DependencyFilter -import org.scalajs.jsdependencies.core.ManifestFilters.ManifestFilter - -object JSDependenciesPlugin extends AutoPlugin { - override def requires: Plugins = ScalaJSPlugin - - object autoImport { - import KeyRanks._ - - val scalaJSNativeLibraries = TaskKey[Attributed[Seq[VirtualJSFile with RelativeVirtualFile]]]( - "scalaJSNativeLibraries", "All the *.js files on the classpath", CTask) - - val packageJSDependencies = TaskKey[File]("packageJSDependencies", - "Packages all dependencies of the preLink classpath in a single file.", AMinusTask) - - val packageMinifiedJSDependencies = TaskKey[File]("packageMinifiedJSDependencies", - "Packages minified version (if available) of dependencies of the preLink " + - "classpath in a single file.", AMinusTask) - - val jsDependencyManifest = TaskKey[File]("jsDependencyManifest", - "Writes the JS_DEPENDENCIES file.", DTask) - - val jsDependencyManifests = TaskKey[Attributed[Traversable[JSDependencyManifest]]]( - "jsDependencyManifests", "All the JS_DEPENDENCIES on the classpath", DTask) - - val requiresDOM = SettingKey[Boolean]("requiresDOM", - "Whether this projects needs the DOM. Overrides anything inherited through dependencies.", AMinusSetting) - - val jsDependencies = SettingKey[Seq[AbstractJSDep]]("jsDependencies", - "JavaScript libraries this project depends upon. Also used to depend on the DOM.", APlusSetting) - - val jsDependencyFilter = SettingKey[DependencyFilter]("jsDependencyFilter", - "The filter applied to the raw JavaScript dependencies before execution", CSetting) - - val jsManifestFilter = SettingKey[ManifestFilter]("jsManifestFilter", - "The filter applied to JS dependency manifests before resolution", CSetting) - - val resolvedJSDependencies = TaskKey[Attributed[Seq[ResolvedJSDependency]]]("resolvedJSDependencies", - "JS dependencies after resolution.", DTask) - - /** 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) - - /** Dummy builder to allow declaractions like: - * - * {{{ - * RuntimeDOM % "test" - * }}} - */ - val RuntimeDOM = RuntimeDOMDep(None) - - /** Builder to allow declarations like: - * - * {{{ - * ProvidedJS / "foo.js" - * ProvidedJS / "foo.js" % "test" - * }}} - */ - object ProvidedJS { - def /(name: String): ProvidedJSModuleID = ProvidedJSModuleID(name, None) - } - - /** Builder to allow declarations like: - * - * {{{ - * "org.webjars" % "jquery" % "1.10.2" / "jquery.js" - * "org.webjars" % "jquery" % "1.10.2" / "jquery.js" % "test" - * }}} - */ - implicit class JSModuleIDBuilder(module: ModuleID) { - def /(name: String): JarJSModuleID = JarJSModuleID(module, name) - } - - } - - import autoImport._ - - /** Collect certain file types from a classpath. - * - * @param cp Classpath to collect from - * @param filter Filter for (real) files of interest (not in jars) - * @param collectJar Collect elements from a jar (called for all jars) - * @param collectFile Collect a single file. Params are the file and the - * relative path of the file (to its classpath entry root). - * @return Collected elements attributed with physical files they originated - * from (key: scalaJSSourceFiles). - */ - private def collectFromClasspath[T](cp: Def.Classpath, filter: FileFilter, - collectJar: VirtualJarFile => Seq[T], - collectFile: (File, String) => T): Attributed[Seq[T]] = { - - val realFiles = Seq.newBuilder[File] - val results = Seq.newBuilder[T] - - for (cpEntry <- Attributed.data(cp) if cpEntry.exists) { - if (cpEntry.isFile && cpEntry.getName.endsWith(".jar")) { - realFiles += cpEntry - val vf = new FileVirtualBinaryFile(cpEntry) with VirtualJarFile - results ++= collectJar(vf) - } else if (cpEntry.isDirectory) { - for { - (file, relPath0) <- Path.selectSubpaths(cpEntry, filter) - } { - val relPath = relPath0.replace(java.io.File.separatorChar, '/') - realFiles += file - results += collectFile(file, relPath) - } - } else { - throw new IllegalArgumentException( - "Illegal classpath entry: " + cpEntry.getPath) - } - } - - Attributed.blank(results.result()).put( - scalaJSSourceFiles, realFiles.result()) - } - - private def jsDependencyManifestsInJar( - container: VirtualFileContainer): List[JSDependencyManifest] = { - container.listEntries(_ == JSDependencyManifest.ManifestFileName) { - (_, stream) => - val json = readJSON(new InputStreamReader(stream, "UTF-8")) - fromJSON[JSDependencyManifest](json) - } - } - - /** Concatenates a bunch of VirtualTextFiles to a WritableVirtualTextFile. - * Adds a '\n' after each file. - */ - private def concatFiles(output: WritableVirtualTextFile, - files: Seq[VirtualTextFile]): Unit = { - val out = output.contentWriter - - try { - for (file <- files) { - toolsIO.writeTo(file, out) - // New line after each file - out.write('\n') - } - } finally { - out.close() - } - } - - private def packageJSDependenciesSetting(taskKey: TaskKey[File], - cacheName: String, - getLib: ResolvedJSDependency => VirtualJSFile): Setting[Task[File]] = { - taskKey := Def.taskDyn { - if ((skip in taskKey).value) - Def.task((artifactPath in taskKey).value) - else Def.task { - val s = (streams in taskKey).value - val deps = resolvedJSDependencies.value - val output = (artifactPath in taskKey).value - - val realFiles = deps.get(scalaJSSourceFiles).get - val resolvedDeps = deps.data - - FileFunction.cached(s.cacheDirectory / cacheName, - FilesInfo.lastModified, - FilesInfo.exists) { _ => // We don't need the files - - IO.createDirectory(output.getParentFile) - - val outFile = AtomicWritableFileVirtualJSFile(output) - concatFiles(outFile, resolvedDeps.map(getLib)) - - Set(output) - } (realFiles.toSet) - - output - } - }.value - } - - lazy val configSettings: Seq[Setting[_]] = Seq( - fastOptJS := fastOptJS.dependsOn(packageJSDependencies).value, - fullOptJS := fullOptJS.dependsOn(packageJSDependencies).value, - fullOptJS := fullOptJS.dependsOn(packageMinifiedJSDependencies).value, - - artifactPath in packageJSDependencies := - ((crossTarget in packageJSDependencies).value / - ((moduleName in packageJSDependencies).value + "-jsdeps.js")), - - packageJSDependenciesSetting(packageJSDependencies, "package-js-deps", _.lib), - - artifactPath in packageMinifiedJSDependencies := - ((crossTarget in packageMinifiedJSDependencies).value / - ((moduleName in packageMinifiedJSDependencies).value + "-jsdeps.min.js")), - - packageJSDependenciesSetting(packageMinifiedJSDependencies, - "package-min-js-deps", dep => dep.minifiedLib.getOrElse(dep.lib)), - - 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 RuntimeDOMDep(configurations) => - configurations.forall(_ == config) - case _ => false - } - - val manifest = new JSDependencyManifest(new Origin(myModule, config), - jsDeps.toList, requiresDOM) - - // 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).value, - - jsDependencyManifests := { - val filter = jsManifestFilter.value - val rawManifests = collectFromClasspath(fullClasspath.value, - new ExactFilter(JSDependencyManifest.ManifestFileName), - collectJar = jsDependencyManifestsInJar(_), - collectFile = { (file, _) => - fromJSON[JSDependencyManifest](readJSON(IO.read(file))) - }) - - rawManifests.map(manifests => filter(manifests.toTraversable)) - }, - - scalaJSNativeLibraries := { - collectFromClasspath(fullClasspath.value, - "*.js", collectJar = _.jsFiles, - collectFile = FileVirtualJSFile.relative) - }, - - resolvedJSDependencies := { - val dependencyFilter = jsDependencyFilter.value - val attLibs = scalaJSNativeLibraries.value - val attManifests = jsDependencyManifests.value - - // Collect originating files - val realFiles = { - attLibs.get(scalaJSSourceFiles).get ++ - attManifests.get(scalaJSSourceFiles).get - } - - // Collect available JS libraries - val availableLibs = { - val libs = mutable.Map.empty[String, VirtualJSFile] - for (lib <- attLibs.data) - libs.getOrElseUpdate(lib.relativePath, lib) - libs.toMap - } - - // Actually resolve the dependencies - val resolved = DependencyResolver.resolveDependencies( - attManifests.data, availableLibs, dependencyFilter) - - Attributed.blank[Seq[ResolvedJSDependency]](resolved) - .put(scalaJSSourceFiles, realFiles) - }, - - // Add the resolved JS dependencies to the list of JS files given to envs - jsExecutionFiles := { - val deps = resolvedJSDependencies.value.data - - /* Implement the behavior of commonJSName without having to burn it - * inside NodeJSEnv, and hence in the JSEnv API. - * Since this matches against NodeJSEnv specifically, it obviously - * breaks the OO approach, but oh well ... - */ - val libs = jsEnv.value match { - case _: org.scalajs.jsenv.nodejs.NodeJSEnv => - val libCache = new VirtualFileMaterializer(false) - - for (dep <- deps) yield { - dep.info.commonJSName.fold { - dep.lib - } { commonJSName => - val fname = libCache.materialize(dep.lib).getAbsolutePath - new MemVirtualJSFile(s"require-$fname").withContent( - s"""$commonJSName = require("${escapeJS(fname)}");""" - ) - } - } - - case _ => - deps.map(_.lib) - } - - libs ++ jsExecutionFiles.value - }, - - scalaJSRequestsDOM := { - requiresDOM.?.value.getOrElse( - jsDependencyManifests.value.data.exists(_.requiresDOM)) - } - ) - - lazy val compileSettings = configSettings - - lazy val testSettings = Def.settings( - configSettings, - - moduleName in packageJSDependencies := moduleName.value + "-test" - ) - - override def projectSettings: Seq[Setting[_]] = Def.settings( - inConfig(Compile)(compileSettings), - inConfig(Test)(testSettings), - - // add all the webjars your jsDependencies depend upon - libraryDependencies ++= jsDependencies.value.collect { - case JarJSModuleID(module, _) => module - }, - - jsDependencies := Seq(), - jsDependencyFilter := identity, - jsManifestFilter := identity - ) - -} diff --git a/project/Build.scala b/project/Build.scala index 3cc14c5700..ad872673b5 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1185,39 +1185,6 @@ object Build { exportJars := true ) - // jsDependencies support - to be moved out of the core repository - - lazy val jsDependenciesCore: Project = (project in file("jsdependencies-core")).settings( - commonSettings, - publishSettings, - fatalWarningsSettings, - name := "scalajs-jsdependencies-core", - libraryDependencies += - "com.novocode" % "junit-interface" % "0.11" % "test" - ).dependsOn(tools) - - lazy val jsDependenciesPlugin: Project = (project in file("jsdependencies-sbt-plugin")).settings( - commonSettings, - publishIvySettings, - fatalWarningsSettings, - name := "sbt-scalajs-jsdependencies", - sbtPlugin := true, - scalaBinaryVersion := - CrossVersion.binaryScalaVersion(scalaVersion.value), - - // Add API mappings for sbt (seems they don't export their API URL) - apiMappings ++= { - val deps = (externalDependencyClasspath in Compile).value - val sbtJars = deps filter { attributed => - val p = attributed.data.getPath - p.contains("/org.scala-sbt/") && p.endsWith(".jar") - } - val docUrl = - url(s"http://www.scala-sbt.org/${sbtVersion.value}/api/") - sbtJars.map(_.data -> docUrl).toMap - } - ).dependsOn(plugin, jsDependenciesCore) - // Examples lazy val examples: Project = project.settings( diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index f612995465..3576ca01a4 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -2,7 +2,6 @@ import org.scalajs.core.tools.io._ import org.scalajs.jsenv.nodejs.JSDOMNodeJSEnv import org.scalajs.sbtplugin.ScalaJSPluginInternal._ import org.scalajs.sbtplugin.Loggers.sbtLogger2ToolsLogger -import org.scalajs.jsdependencies.core.ManifestFilters lazy val concurrentFakeFullOptJS = taskKey[Any]("") lazy val concurrentUseOfLinkerTest = taskKey[Any]("") @@ -25,24 +24,9 @@ val baseSettings = versionSettings ++ Seq( "non-existent-directory-please-dont-ever-create-this" ) -val regressionTestForIssue2243 = TaskKey[Unit]("regressionTestForIssue2243", - "", KeyRanks.BTask) val testScalaJSSourceMapAttribute = TaskKey[Unit]( "testScalaJSSourceMapAttribute", "", KeyRanks.BTask) -def withRegretionTestForIssue2243(project: Project): Project = { - project.settings(inConfig(Compile)(Seq( - regressionTestForIssue2243 := { - // Regression test for issue #2243 - val _ = Def.sequential(packageJSDependencies in Compile, - packageMinifiedJSDependencies in Compile).value - assert((artifactPath in(Compile, packageJSDependencies)).value.exists) - assert((artifactPath in(Compile, packageMinifiedJSDependencies)).value.exists) - streams.value.log.info("Regression test for issue #2243 passed") - } - )): _*) -} - lazy val referencedCrossProjectJS = ProjectRef(file("referencedCrossProject"), "referencedCrossProjectJS") lazy val referencedCrossProjectJVM = ProjectRef(file("referencedCrossProject"), "referencedCrossProjectJVM") @@ -184,94 +168,6 @@ lazy val multiTest = crossProject. lazy val multiTestJS = multiTest.js lazy val multiTestJVM = multiTest.jvm -lazy val jsDependenciesTestDependee = project. - settings(versionSettings: _*). - enablePlugins(ScalaJSPlugin, JSDependenciesPlugin). - settings( - // This project contains some jsDependencies to test in jsDependenciesTest - jsDependencies ++= Seq( - RuntimeDOM, - // The jsDependenciesTest relies on this jQuery dependency - // If you change it, make sure we still test properly - "org.webjars" % "jquery" % "1.10.2" / "jquery.js" - ) - ) - -lazy val jsDependenciesTest = withRegretionTestForIssue2243( - project.settings(versionSettings: _*). - enablePlugins(ScalaJSPlugin, JSDependenciesPlugin). - settings( - jsDependencies ++= Seq( - "org.webjars" % "historyjs" % "1.8.0" / "uncompressed/history.js", - ProvidedJS / "some-jquery-plugin.js" dependsOn "1.10.2/jquery.js", - ProvidedJS / "js/foo.js" dependsOn "uncompressed/history.js", - - // cause a circular dependency error if both "history.js"'s are considered equal - "org.webjars" % "historyjs" % "1.8.0" / "compressed/history.js" dependsOn "foo.js", - - // cause a duplicate commonJSName if the following are not considered equal - "org.webjars" % "mustachejs" % "0.8.2" / "mustache.js" commonJSName "Mustache", - "org.webjars" % "mustachejs" % "0.8.2" / "0.8.2/mustache.js" commonJSName "Mustache", - - // cause an ambiguity with the jQuery dependency from the - // jsDependenciesTestDependee project (if we don't filter) - ProvidedJS / "js/customJQuery/jquery.js" dependsOn "1.10.2/jquery.js", - - // Test minified dependencies - "org.webjars" % "immutable" % "3.4.0" / "immutable.js" minified "immutable.min.js" - ), - jsManifestFilter := { - ManifestFilters.reinterpretResourceNames("jsDependenciesTestDependee")( - "jquery.js" -> "1.10.2/jquery.js") - } - ). - settings(inConfig(Compile)(Seq( - packageJSDependencies <<= packageJSDependencies.dependsOn(Def.task { - // perform verifications on the ordering and deduplications - val resolvedDeps = resolvedJSDependencies.value.data - val relPaths = resolvedDeps.map(_.info.relPath) - - assert(relPaths.toSet == Set( - "META-INF/resources/webjars/mustachejs/0.8.2/mustache.js", - "META-INF/resources/webjars/historyjs/1.8.0/scripts/uncompressed/history.js", - "META-INF/resources/webjars/historyjs/1.8.0/scripts/compressed/history.js", - "META-INF/resources/webjars/jquery/1.10.2/jquery.js", - "META-INF/resources/webjars/immutable/3.4.0/immutable.js", - "js/foo.js", - "js/some-jquery-plugin.js", - "js/customJQuery/jquery.js"), - s"Bad set of relPathes: ${relPaths.toSet}") - - val minifiedRelPaths = resolvedDeps.flatMap(_.info.relPathMinified) - - assert(minifiedRelPaths.toSet == Set( - "META-INF/resources/webjars/immutable/3.4.0/immutable.min.js"), - s"Bad set of minifiedRelPathes: ${minifiedRelPaths.toSet}") - - val jQueryIndex = relPaths.indexWhere(_ endsWith "1.10.2/jquery.js") - val jQueryPluginIndex = relPaths.indexWhere(_ endsWith "/some-jquery-plugin.js") - assert(jQueryPluginIndex > jQueryIndex, - "the jQuery plugin appears before jQuery") - - val uncompressedHistoryIndex = relPaths.indexWhere(_ endsWith "/uncompressed/history.js") - val fooIndex = relPaths.indexWhere(_ endsWith "/foo.js") - val compressedHistoryIndex = relPaths.indexWhere(_ endsWith "/compressed/history.js") - assert(fooIndex > uncompressedHistoryIndex, - "foo.js appears before uncompressed/history.js") - assert(compressedHistoryIndex > fooIndex, - "compressed/history.js appears before foo.js") - - streams.value.log.info("jsDependencies resolution test passed") - }) - )): _*). - dependsOn(jsDependenciesTestDependee) // depends on jQuery -) - -lazy val jsNoDependenciesTest = withRegretionTestForIssue2243( - project.settings(versionSettings: _*). - enablePlugins(ScalaJSPlugin, JSDependenciesPlugin) -) - // Test %%% macro - #1331 val unusedSettings = Seq( libraryDependencies += "org.example" %%% "dummy" % "0.1" diff --git a/sbt-plugin-test/jsDependenciesTest/src/main/resources/js/customJQuery/jquery.js b/sbt-plugin-test/jsDependenciesTest/src/main/resources/js/customJQuery/jquery.js deleted file mode 100644 index f5dfcbd7f3..0000000000 --- a/sbt-plugin-test/jsDependenciesTest/src/main/resources/js/customJQuery/jquery.js +++ /dev/null @@ -1 +0,0 @@ -// js/customJQuery/jquery.js diff --git a/sbt-plugin-test/jsDependenciesTest/src/main/resources/js/foo.js b/sbt-plugin-test/jsDependenciesTest/src/main/resources/js/foo.js deleted file mode 100644 index 7eea44b421..0000000000 --- a/sbt-plugin-test/jsDependenciesTest/src/main/resources/js/foo.js +++ /dev/null @@ -1 +0,0 @@ -// js/foo.js diff --git a/sbt-plugin-test/jsDependenciesTest/src/main/resources/js/some-jquery-plugin.js b/sbt-plugin-test/jsDependenciesTest/src/main/resources/js/some-jquery-plugin.js deleted file mode 100644 index 5eae5ac336..0000000000 --- a/sbt-plugin-test/jsDependenciesTest/src/main/resources/js/some-jquery-plugin.js +++ /dev/null @@ -1 +0,0 @@ -// js/some-jquery-plugin.js diff --git a/sbt-plugin-test/project/build.sbt b/sbt-plugin-test/project/build.sbt index d4ef290b0e..6626b7a52e 100644 --- a/sbt-plugin-test/project/build.sbt +++ b/sbt-plugin-test/project/build.sbt @@ -1,5 +1,2 @@ addSbtPlugin("org.scala-js" % "sbt-scalajs" % org.scalajs.core.ir.ScalaJSVersions.current) - -addSbtPlugin("org.scala-js" % "sbt-scalajs-jsdependencies" % - org.scalajs.core.ir.ScalaJSVersions.current) From 0fc2dc0063ddb61387dc9d90c7afa81597c532cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 5 Jun 2017 14:56:10 +0200 Subject: [PATCH 0305/2665] Fix #2382 for good, on all Scala versions. We simply remove the guard that prevented the fix from being applied in 2.10 and 2.11. It was necessary in 0.6.x not to break backward binary compatibility, but we can now fix it for good. --- .../scalajs/core/compiler/JSEncoding.scala | 23 +++++-------------- project/Build.scala | 16 ------------- .../testsuite/compiler/OuterClassTest.scala | 3 --- 3 files changed, 6 insertions(+), 36 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala index 0c2936c0d7..308a62548b 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala @@ -80,12 +80,6 @@ trait JSEncoding extends SubComponent { self: GenJSCode => js.Ident(localSymbolName(sym), Some(sym.unexpandedName.decoded)) } - /** See comment in `encodeFieldSym()`. */ - private lazy val shouldMangleOuterPointerName = { - val v = scala.util.Properties.versionNumberString - !(v.startsWith("2.10.") || v.startsWith("2.11.") || v == "2.12.0-RC1") - } - def encodeFieldSym(sym: Symbol)(implicit pos: Position): js.Ident = { require(sym.owner.isClass && sym.isTerm && !sym.isMethod && !sym.isModule, "encodeFieldSym called with non-field symbol: " + sym) @@ -105,16 +99,10 @@ trait JSEncoding extends SubComponent { self: GenJSCode => * Caveat: because of this, changing the length of the superclass chain of * a Java-defined class is a binary incompatible change. * - * Starting with 2.12.0-RC2, we also special case outer fields. This - * essentially fixes #2382, which is caused by a class having various $outer - * pointers in its hierarchy that points to different outer instances. - * Without this fix, they all collapse to the same field in the IR. We - * cannot fix this for all Scala versions at the moment, because that would - * break backwards binary compatibility. We *do* fix it for 2.12.0-RC2 - * onwards because that also fixes #2625, which surfaced in 2.12 and is - * therefore a regression. We can do this because the 2.12 ecosystem is - * not binary compatible anyway (because of Scala) so we can break it on - * our side at the same time. + * We also special case outer fields. This essentially fixes #2382, which + * is caused by a class having various $outer pointers in its hierarchy + * that point to different outer instances. Without this fix, they all + * collapse to the same field in the IR. * * TODO We should probably consider emitting *all* fields with an ancestor * count. We cannot do that in a binary compatible way, though. This is @@ -124,7 +112,8 @@ trait JSEncoding extends SubComponent { self: GenJSCode => val usePerClassSuffix = { sym.isPrivate || sym.isJavaDefined || - (shouldMangleOuterPointerName && sym.isOuterField) + sym.isOuterField || // Scala 2.11+ + sym.isOuterAccessor // Scala 2.10 workaround } if (usePerClassSuffix) sym.owner.ancestors.count(!_.isTraitOrInterface).toString diff --git a/project/Build.scala b/project/Build.scala index 3cc14c5700..5b1736f8f0 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1528,22 +1528,6 @@ object Build { Seq(outFile) }.taskValue, - // Exclude tests based on version-dependent bugs - sources in Test := { - val sourceFiles = (sources in Test).value - val v = scalaVersion.value - - val hasBug2382 = v.startsWith("2.10.") || v.startsWith("2.11.") - val sourceFiles1 = { - if (hasBug2382) - sourceFiles.filterNot(_.getName == "OuterClassTest.scala") - else - sourceFiles - } - - sourceFiles1 - }, - // Module initializers. Duplicated in toolsJS/test scalaJSModuleInitializers += { ModuleInitializer.mainMethod( diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/OuterClassTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/OuterClassTest.scala index 2baed6a5ea..a688444c8f 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/OuterClassTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/OuterClassTest.scala @@ -3,9 +3,6 @@ package org.scalajs.testsuite.compiler import org.junit.Test import org.junit.Assert._ -/* This test only works with 2.12.0-RC2 onwards. With previous versions of - * Scala, it suffers from #2382. - */ class OuterClassTest { @Test def `Test code variant 1 from #2382`(): Unit = { From 718b18929e46417bca448e1fc843a10185745e4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 6 Jun 2017 11:55:34 +0200 Subject: [PATCH 0306/2665] Fix #2987: Migrate to sbt-crossproject. https://github.com/scala-native/sbt-crossproject sbt-crossproject was designed to be a backward source compatible replacement for Scala.js' own `crossProject`, with a generalization to arbitrary platforms, notably Scala Native. This commit drops our own implementation of `CrossProject` and its associated features (e.g., the `%%%` macro), and delegates everything to sbt-crossproject instead. --- project/Build.scala | 2 + project/build.sbt | 2 + .../org/scalajs/sbtplugin/JSPlatform.scala | 24 ++ .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 41 +- .../sbtplugin/ScalaJSPluginInternal.scala | 3 + .../cross/CrossClasspathDependency.scala | 29 -- .../sbtplugin/cross/CrossProject.scala | 375 ------------------ .../scalajs/sbtplugin/cross/CrossType.scala | 64 --- .../scalajs/sbtplugin/cross/MacroUtils.scala | 47 --- .../sbtplugin/impl/DependencyBuilders.scala | 79 ---- 10 files changed, 54 insertions(+), 612 deletions(-) create mode 100644 sbt-plugin/src/main/scala/org/scalajs/sbtplugin/JSPlatform.scala delete mode 100644 sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossClasspathDependency.scala delete mode 100644 sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossProject.scala delete mode 100644 sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossType.scala delete mode 100644 sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/MacroUtils.scala delete mode 100644 sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/DependencyBuilders.scala diff --git a/project/Build.scala b/project/Build.scala index c231823404..9add6e7362 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -779,6 +779,8 @@ object Build { previousArtifactSetting, mimaBinaryIssueFilters ++= BinaryIncompatibilities.SbtPlugin, + addSbtPlugin("org.scala-native" % "sbt-crossproject" % "0.2.0"), + // Add API mappings for sbt (seems they don't export their API URL) apiMappings ++= { val deps = (externalDependencyClasspath in Compile).value diff --git a/project/build.sbt b/project/build.sbt index 7f3760b6b4..c72ce19f7f 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -11,6 +11,8 @@ addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.13") addSbtPlugin("org.scalastyle" % "scalastyle-sbt-plugin" % "0.8.0") +addSbtPlugin("org.scala-native" % "sbt-crossproject" % "0.2.0") + libraryDependencies += "org.scala-js" % "closure-compiler-java-6" % "v20160517" libraryDependencies += "org.eclipse.jgit" % "org.eclipse.jgit.pgm" % "3.2.0.201312181205-r" diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/JSPlatform.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/JSPlatform.scala new file mode 100644 index 0000000000..b9a51ec449 --- /dev/null +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/JSPlatform.scala @@ -0,0 +1,24 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.sbtplugin + +import sbt._ + +import sbtcrossproject._ + +case object JSPlatform extends Platform { + val crossBinary: CrossVersion = ScalaJSCrossVersion.binary + val crossFull: CrossVersion = ScalaJSCrossVersion.full + + def identifier: String = "js" + def sbtSuffix: String = "JS" + + def enable(project: Project): Project = + project.enablePlugins(ScalaJSPlugin) +} diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 8f2509ec91..a1fd60dfc0 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -9,8 +9,12 @@ 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} @@ -24,21 +28,7 @@ import org.scalajs.jsenv.nodejs.{NodeJSEnv, JSDOMNodeJSEnv} object ScalaJSPlugin extends AutoPlugin { override def requires: Plugins = plugins.JvmPlugin - /* 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 { // scalastyle:ignore import KeyRanks._ // Some constants @@ -46,15 +36,30 @@ object ScalaJSPlugin extends AutoPlugin { val scalaJSIsSnapshotVersion = ScalaJSVersions.currentIsSnapshot val scalaJSBinaryVersion = ScalaJSCrossVersion.currentBinaryVersion + // The JS platform for sbt-crossproject + val JSPlatform = org.scalajs.sbtplugin.JSPlatform + + implicit def JSCrossProjectBuilderOps( + builder: CrossProject.Builder): JSCrossProjectOps = { + new JSCrossProjectOps(builder.crossType(CrossType.Full)) + } + + implicit class JSCrossProjectOps(project: CrossProject) { + def js: Project = project.projects(JSPlatform) + + def jsSettings(ss: Def.SettingsDefinition*): CrossProject = + jsConfigure(_.settings(ss: _*)) + + def jsConfigure(transformer: Project => Project): CrossProject = + project.configurePlatform(JSPlatform)(transformer) + } + // Stage values @deprecated("Use FastOptStage instead", "0.6.6") val PreLinkStage = Stage.FastOpt val FastOptStage = Stage.FastOpt val FullOptStage = Stage.FullOpt - // CrossType - val CrossType = cross.CrossType - // Factory methods for JSEnvs /** diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index a4025d6c87..9c24494e67 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -10,6 +10,8 @@ import Cache.seqFormat import complete.Parser import complete.DefaultParsers._ +import sbtcrossproject.CrossPlugin.autoImport._ + import Loggers._ import org.scalajs.core.tools.sem.Semantics @@ -660,6 +662,7 @@ object ScalaJSPluginInternal { ) val scalaJSProjectBaseSettings = Seq( + crossPlatform := JSPlatform, isScalaJSProject := true, relativeSourceMaps := false, diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossClasspathDependency.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossClasspathDependency.scala deleted file mode 100644 index 91ef49acc5..0000000000 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossClasspathDependency.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.sbtplugin.cross - -import sbt._ - -final class CrossClasspathDependency( - val project: CrossProject, - val configuration: Option[String] -) { - def jvm: ClasspathDependency = ClasspathDependency(project.jvm, configuration) - def js: ClasspathDependency = ClasspathDependency(project.js, configuration) -} - -object CrossClasspathDependency { - final class Constructor(crossProject: CrossProject) { - def %(conf: Configuration): CrossClasspathDependency = %(conf.name) - - def %(conf: String): CrossClasspathDependency = - new CrossClasspathDependency(crossProject, Some(conf)) - } -} diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossProject.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossProject.scala deleted file mode 100644 index 7017118195..0000000000 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossProject.scala +++ /dev/null @@ -1,375 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.sbtplugin.cross - -import org.scalajs.sbtplugin.ScalaJSPlugin - -import scala.language.implicitConversions -import scala.language.experimental.macros - -import scala.reflect.macros.Context - -import sbt._ -import Keys._ -import Project.projectToRef - -import java.io.File - -/** A convenience structure that creates a JVM and a Scala.js project under the - * hood and forwards common operations to it. - * - *

Basic Usage

- * In your `build.sbt`, use [[CrossProject]] as follows: - * {{{ - * lazy val p1 = crossProject. - * settings( - * name := "test", // default name would be p1 - * libraryDependencies += "org.example" %%% "test" % "0.1" - * ). - * jvmSettings( - * libraryDependencies += "org.example" %% "jvm-specific" % "0.1" - * ). - * jsSettings( - * libraryDependencies += "org.example" %%% "js-specific" % "0.1", - * jsDependencies += "org.example" %% "js-thing" % "0.1" / "foo.js" - * ) - * - * // Needed, so sbt finds the projects - * lazy val p1JVM = p1.jvm - * lazy val p1JS = p1.js - * - * lazy val p2 = crossProject.crossType(CrossType.Pure).dependsOn(p1 % "test") - * - * // Needed, so sbt finds the projects - * lazy val p2JVM = p2.jvm - * lazy val p2JS = p2.js - * }}} - * - *

CrossProject types

- * There are three built-in types of [[CrossProject]]s. Each of them - * corresponds to a concrete subclass of [[CrossType]]: - * - *

Full CrossProject ([[CrossType.Full]])

- * A CrossProject that has both shared and individual JVM/JS sources. - * This is the default. - * - * The directory structure is as follows: - * - *
- *  project/
- *    shared/
- *      src/
- *        main/
- *        test/
- *    jvm/
- *      src/
- *        main/
- *        test/
- *    js/
- *      src/
- *        main/
- *        test/
- *  
- * - * The shared source tree is included in both the JVM and the JS project. - * - *

Pure CrossProject ([[CrossType.Pure]])

- * A CrossProject that does not have individual JVM/JS sources. - * - * The directory structure is as follows: - * - *
- *  project/
- *    src/
- *      main/
- *      test/
- *    .jvm/
- *    .js/
- *  
- * - * The source tree is included in both the JVM and the JS project. The hidden - * folders are the true project roots in sbt's terms. - * - *

Dummy CrossProject ([[CrossType.Dummy]])

- * A CrossProject that does not have shared JVM/JS sources. It is useful, since - * it can still be used for dependency tracking and aggregation. - * - * The directory structure is as follows: - * - *
- *  project/
- *    jvm/
- *      src/
- *        main/
- *        test/
- *    js/
- *      src/
- *        main/
- *        test/
- *  
- * - *

Eclipse Support

- * Note that by default, the sbteclipse plugin uses sbt's project names to name - * the Eclipse projects it generates. Since the CrossProject generates two - * projects with the same name, this may result in a conflict when importing - * the projects into Eclipse. - * - * You can configure sbteclipse to - * [[https://github.com/typesafehub/sbteclipse/wiki/Using-sbteclipse#useprojectid - * use the project ID]] instead (which is unique in sbt as well): - * - * {{{ - * EclipseKeys.useProjectId := true - * }}} - * - * Alternatively, you can of course also just import one of the two projects - * into your Eclipse. - * - *

IntelliJ IDEA Support

- * While CrossProject works out of the box with Eclipse and the sbt eclipse - * plugin, it does not with IntelliJ IDEA due to its missing support for shared - * source directories. - * - * To fix this, you should add symlinks in the hierarchy to the shared source - * directory and include them in your imported IntelliJ IDEA project (but not - * in sbt). The recommended structure is as follows (for a Full CrossProject): - * - *
- *  project/
- *    shared/
- *      src/
- *        main/
- *        test/
- *    jvm/
- *      src/
- *        main/
- *        test/
- *        idea-shared-main/ --> project/shared/src/main
- *        idea-shared-test/ --> project/shared/src/test
- *    js/
- *      src/
- *        main/
- *        test/
- *        idea-shared-main/ --> project/shared/src/main
- *        idea-shared-test/ --> project/shared/src/test
- *  
- * - * Note that we do not recommend to put the symlinks in version control, since - * they do not work on Windows (Git, for example, just ignores their existence - * when cloning). - * - *

Pitfalls to Avoid

- * - *

Altering a contained Project outside the CrossProject

- * Since sbt projects are immutable structures, it is important that you do not - * "mutate" (i.e. create a new Project) outside of the CrossProject. - * - *

DON'T

- * {{{ - * lazy val p1 = crossProject - * - * lazy val p1JVM = p1.jvm - * lazy val p1JS = p1.js.settings(jsDependencies += RuntimeDOM) - * - * // Now we have p1JS != p1.js... Dependency tracking will not work anymore. - * }}} - * - *

DO

- * {{{ - * lazy val p1 = crossProject. - * jsSettings(jsDependencies += RuntimeDOM) - * - * lazy val p1JVM = p1.jvm - * lazy val p1JS = p1.js - * }}} - * - *

Manually setting the base of a contained Project

- * CrossProject puts its contained projects in a given directory structure. If - * you try to work around that, things will fail (and non-existing directories - * will be referenced). If you want to put your projects in a different - * directory structure, you are encouraged to implement your own subclass of - * [[CrossType]]. - * - *

DON'T

- * {{{ - * lazy val p1 = crossProject.jsConfigure(_.in(file("myJSDir"))) - * }}} - * - *

DO

- * Implement your own subclass (sub-object) of [[CrossType]]. - * - */ -final class CrossProject private ( - crossType: CrossType, - val jvm: Project, - val js: Project -) { - - import CrossProject._ - - // Transformers for inner projects - - /** Transform the underlying JVM project */ - def jvmConfigure(transformer: Project => Project): CrossProject = - copy(jvm = transformer(jvm)) - - /** Transform the underlying JS project */ - def jsConfigure(transformer: Project => Project): CrossProject = - copy(js = transformer(js)) - - /** Add settings specific to the underlying JVM project */ - def jvmSettings(ss: Def.SettingsDefinition*): CrossProject = - jvmConfigure(_.settings(ss: _*)) - - /** Add settings specific to the underlying JS project */ - def jsSettings(ss: Def.SettingsDefinition*): CrossProject = - jsConfigure(_.settings(ss: _*)) - - // Concrete alteration members - - def aggregate(refs: CrossProject*): CrossProject = { - copy( - jvm.aggregate(refs.map(_.jvm: ProjectReference): _*), - js.aggregate(refs.map(_.js: ProjectReference): _*)) - } - - def configs(cs: Configuration*): CrossProject = - copy(jvm.configs(cs: _*), js.configs(cs: _*)) - - def configureCross(transforms: (CrossProject => CrossProject)*): CrossProject = - transforms.foldLeft(this)((p, t) => t(p)) - - @deprecated("Use configureCross instead.", "0.6.10") - def configure(transforms: (CrossProject => CrossProject)*): CrossProject = - configureCross(transforms: _*) - - // TODO: rename to "configure" when compatibility can be broken (1.0.0) - // and the existing deprecated "configure" is removed - def configureAll(transforms: (Project => Project)*): CrossProject = - copy(jvm.configure(transforms: _*), js.configure(transforms: _*)) - - def dependsOn(deps: CrossClasspathDependency*): CrossProject = - copy(jvm.dependsOn(deps.map(_.jvm): _*), js.dependsOn(deps.map(_.js): _*)) - - def disablePlugins(ps: AutoPlugin*): CrossProject = - copy(jvm.disablePlugins(ps: _*), js.disablePlugins(ps: _*)) - - def enablePlugins(ns: Plugins*): CrossProject = - copy(jvm.enablePlugins(ns: _*), js.enablePlugins(ns: _*)) - - def in(dir: File): CrossProject = - copy(jvm.in(crossType.jvmDir(dir)), js.in(crossType.jsDir(dir))) - - def overrideConfigs(cs: Configuration*): CrossProject = - copy(jvm.overrideConfigs(cs: _*), js.overrideConfigs(cs: _*)) - - /** Configures how settings from other sources, such as .sbt files, are - * appended to the explicitly specified settings for this project. - * - * Note: If you disable AutoPlugins here, Scala.js will not work - */ - @deprecated( - "Project#settingSets will be removed from sbt 1.0, hence " + - "CrossProject#settingSets will be removed from Scala.js 1.0. " + - "As a temporary measure, use `.configureAll(_.settingSets(select))`.", - "0.6.16") - def settingSets(select: AddSettings*): CrossProject = - copy(jvm.settingSets(select: _*), js.settingSets(select: _*)) - - def settings(ss: Def.SettingsDefinition*): CrossProject = - copy(jvm.settings(ss: _*), js.settings(ss: _*)) - - override def toString(): String = s"CrossProject(jvm = $jvm, js = $js)" - - // Helpers - - private def copy(jvm: Project = jvm, js: Project = js): CrossProject = - new CrossProject(crossType, jvm, js) - -} - -object CrossProject extends CrossProjectExtra { - - def apply(id: String, base: File, crossType: CrossType): CrossProject = { - CrossProject(id + "JVM", id + "JS", base, crossType). - settings(name := id) - } - - def apply(jvmId: String, jsId: String, base: File, - crossType: CrossType): CrossProject = { - - val sss = sharedSrcSettings(crossType) - - val jvm = Project(jvmId, crossType.jvmDir(base)). - settings(sss: _*) - - val js = Project(jsId, crossType.jsDir(base)). - settings(sss: _*). - enablePlugins(ScalaJSPlugin) - - new CrossProject(crossType, jvm, js) - } - - private def sharedSrcSettings(crossType: CrossType) = Seq( - unmanagedSourceDirectories in Compile ++= { - makeCrossSources(crossType.sharedSrcDir(baseDirectory.value, "main"), - scalaBinaryVersion.value, crossPaths.value) - }, - unmanagedSourceDirectories in Test ++= { - makeCrossSources(crossType.sharedSrcDir(baseDirectory.value, "test"), - scalaBinaryVersion.value, crossPaths.value) - } - ) - - // Inspired by sbt's Defaults.makeCrossSources - private def makeCrossSources(sharedSrcDir: Option[File], - scalaBinaryVersion: String, cross: Boolean): Seq[File] = { - sharedSrcDir.fold[Seq[File]] { - Seq.empty - } { srcDir => - if (cross) - Seq(srcDir.getParentFile / s"${srcDir.name}-$scalaBinaryVersion", srcDir) - else - Seq(srcDir) - } - } - - final class Builder(id: String, base: File) { - def crossType(crossType: CrossType): CrossProject = - CrossProject(id, base, crossType) - } - - def crossProject_impl(c: Context): c.Expr[Builder] = { - import c.universe._ - val enclosingValName = MacroUtils.definingValName(c, methodName => - s"""$methodName must be directly assigned to a val, such as `val x = $methodName`.""") - val name = c.Expr[String](Literal(Constant(enclosingValName))) - reify { new Builder(name.splice, new File(name.splice)) } - } - -} - -trait CrossProjectExtra { - - def crossProject: CrossProject.Builder = macro CrossProject.crossProject_impl - - implicit def crossProjectFromBuilder( - builder: CrossProject.Builder): CrossProject = { - builder.crossType(CrossType.Full) - } - - implicit def crossClasspathDependencyConstructor( - cp: CrossProject): CrossClasspathDependency.Constructor = - new CrossClasspathDependency.Constructor(cp) - - implicit def crossClasspathDependency( - cp: CrossProject): CrossClasspathDependency = - new CrossClasspathDependency(cp, None) -} diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossType.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossType.scala deleted file mode 100644 index 643c3c615e..0000000000 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossType.scala +++ /dev/null @@ -1,64 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.sbtplugin.cross - -import sbt._ - -import java.io.File - -abstract class CrossType { - - /** The base directory for a (true sbt) Project - * @param crossBase The base directory of the CrossProject - * @param projectType "jvm" or "js". Other values may be supported - */ - def projectDir(crossBase: File, projectType: String): File - - /** The base directory for the JVM project */ - final def jvmDir(crossBase: File): File = projectDir(crossBase, "jvm") - - /** The base directory for the JS project */ - final def jsDir(crossBase: File): File = projectDir(crossBase, "js") - - /** The location of a shared source directory (if it exists) - * @param projectBase the base directory of a (true sbt) Project - * @param conf name of sub-directory for the configuration (typically "main" - * or "test") - */ - def sharedSrcDir(projectBase: File, conf: String): Option[File] - -} - -object CrossType { - - object Full extends CrossType { - def projectDir(crossBase: File, projectType: String): File = - crossBase / projectType - - def sharedSrcDir(projectBase: File, conf: String): Option[File] = - Some(projectBase.getParentFile / "shared" / "src" / conf / "scala") - } - - object Pure extends CrossType { - def projectDir(crossBase: File, projectType: String): File = - crossBase / ("." + projectType) - - def sharedSrcDir(projectBase: File, conf: String): Option[File] = - Some(projectBase.getParentFile / "src" / conf / "scala") - } - - object Dummy extends CrossType { - def projectDir(crossBase: File, projectType: String): File = - crossBase / projectType - - def sharedSrcDir(projectBase: File, conf: String): Option[File] = None - } - -} diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/MacroUtils.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/MacroUtils.scala deleted file mode 100644 index 1a310ea291..0000000000 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/MacroUtils.scala +++ /dev/null @@ -1,47 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.sbtplugin.cross - -import scala.reflect.macros.Context - -private[cross] object MacroUtils { - - // Copied from sbt.std.KeyMacros - - def definingValName(c: Context, invalidEnclosingTree: String => String): String = { - import c.universe._ - val methodName = c.macroApplication.symbol.name - - // trim is not strictly correct, but macros don't expose the API necessary - def processName(n: Name): String = n.decoded.trim - - def enclosingVal(trees: List[c.Tree]): String = trees match { - case vd @ ValDef(_, name, _, _) :: ts => - processName(name) - - case (_: Apply | _: Select | _: TypeApply) :: xs => - enclosingVal(xs) - - // lazy val x: X = has this form for some reason - // (only when the explicit type is present, though) - case Block(_, _) :: DefDef(mods, name, _, _, _, _) :: xs if mods.hasFlag(Flag.LAZY) => - processName(name) - case _ => - c.error(c.enclosingPosition, invalidEnclosingTree(methodName.decoded)) - "" - } - - enclosingVal(enclosingTrees(c).toList) - } - - def enclosingTrees(c: Context): Seq[c.Tree] = - c.asInstanceOf[reflect.macros.runtime.Context].callsiteTyper. - context.enclosingContextChain.map(_.tree.asInstanceOf[c.Tree]) -} diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/DependencyBuilders.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/DependencyBuilders.scala deleted file mode 100644 index 5ea131d0a3..0000000000 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/DependencyBuilders.scala +++ /dev/null @@ -1,79 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.sbtplugin -package impl - -import scala.language.implicitConversions -import scala.language.experimental.macros - -import sbt._ - -import StringUtilities.nonEmpty - -trait DependencyBuilders { - final implicit def toScalaJSGroupID(groupID: String): ScalaJSGroupID = { - nonEmpty(groupID, "Group ID") - new ScalaJSGroupID(groupID) - } -} - -final class ScalaJSGroupID private[sbtplugin] (private val groupID: String) { - def %%%(artifactID: String): CrossGroupArtifactID = - macro ScalaJSGroupID.auto_impl - - def %%%!(artifactID: String): CrossGroupArtifactID = - ScalaJSGroupID.withCross(this, artifactID, ScalaJSCrossVersion.binary) -} - -object ScalaJSGroupID { - import scala.reflect.macros.Context - - /** Internal. Used by the macro implementing [[ScalaJSGroupID.%%%]]. Use: - * {{{ - * ("a" % artifactID % revision).cross(cross) - * }}} - * instead. - */ - def withCross(groupID: ScalaJSGroupID, artifactID: String, - cross: CrossVersion): CrossGroupArtifactID = { - nonEmpty(artifactID, "Artifact ID") - new CrossGroupArtifactID(groupID.groupID, artifactID, cross) - } - - def auto_impl(c: Context { type PrefixType = ScalaJSGroupID })( - artifactID: c.Expr[String]): c.Expr[CrossGroupArtifactID] = { - import c.universe._ - - // Hack to work around bug in sbt macros (wrong way of collecting local - // definitions) - val keysSym = rootMirror.staticModule( - "_root_.org.scalajs.sbtplugin.ScalaJSPlugin.AutoImport") - val keys = c.Expr[ScalaJSPlugin.AutoImport.type](Ident(keysSym)) - - reify { - val cross = { - if (keys.splice.isScalaJSProject.value) - ScalaJSCrossVersion.binary - else - CrossVersion.binary - } - ScalaJSGroupID.withCross(c.prefix.splice, artifactID.splice, cross) - } - } - -} - -final class CrossGroupArtifactID(groupID: String, - artifactID: String, crossVersion: CrossVersion) { - def %(revision: String): ModuleID = { - nonEmpty(revision, "Revision") - ModuleID(groupID, artifactID, revision).cross(crossVersion) - } -} From 2514e5fc2e0824ef011bac13315570fcd1d833a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 15 Apr 2017 05:31:10 +0900 Subject: [PATCH 0307/2665] Delegate the choice of `thisIdent` to `JSDesugar`. It relieves `ClassEmitter` from the only decision it took regarding allocation of local variable names in functions. --- .../linker/backend/emitter/ClassEmitter.scala | 20 +++------- .../backend/emitter/FunctionEmitter.scala | 37 +++++++++++++------ 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index 989c27c359..95c5e03771 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -352,19 +352,9 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { implicit globalKnowledge: GlobalKnowledge): js.Tree = { implicit val pos = method.pos - /* TODO The identifier `$thiz` cannot be produced by 0.6.x compilers due to - * their name mangling, which guarantees that it is unique. We should find - * a better way to do this in the future, though. - */ - val thisIdent = js.Ident("$thiz", Some("this")) - - val methodFun0 = desugarToFunction(className, Some(thisIdent), + val methodFun = desugarToFunctionWithExplicitThis(className, method.args, method.body.get, method.resultType == NoType) - val methodFun = js.Function( - js.ParamDef(thisIdent, rest = false) :: methodFun0.args, - methodFun0.body)(methodFun0.pos) - val Ident(methodName, origName) = method.name envFieldDef("f", className + "__" + methodName, methodFun, origName) @@ -911,11 +901,11 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val baseCtor = envField("c", cd.name.name, cd.name.originalName) - val thisIdent = js.Ident("$thiz") + val js.Function(thisParam :: ctorParams, ctorBody) = + desugarToFunctionWithExplicitThis(cd.encodedName, + args, body, isStat = true) - val js.Function(ctorParams, ctorBody) = - desugarToFunction(cd.encodedName, - Some(thisIdent), args, body, isStat = true) + val thisIdent = thisParam.name val exportedCtor = js.Function(ctorParams, js.Block( genLet(thisIdent, mutable = false, js.New(baseCtor, Nil)), diff --git 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 index 7824123d51..8f72213dfa 100644 --- 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 @@ -203,22 +203,19 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { enclosingClassName: String, params: List[ParamDef], body: Tree, isStat: Boolean)( implicit globalKnowledge: GlobalKnowledge, pos: Position): js.Function = { - desugarToFunction(enclosingClassName, - None, params, body, isStat) + new JSDesugar().desugarToFunction(params, body, isStat, + Env.empty.withEnclosingClassName(Some(enclosingClassName))) } - /** Desugars parameters and body to a JS function. + /** Desugars parameters and body to a JS function where `this` is given as + * an explicit normal parameter. */ - def desugarToFunction( - enclosingClassName: String, - thisIdent: Option[js.Ident], params: List[ParamDef], + def desugarToFunctionWithExplicitThis( + enclosingClassName: String, params: List[ParamDef], body: Tree, isStat: Boolean)( implicit globalKnowledge: GlobalKnowledge, pos: Position): js.Function = { - val env = Env.empty - .withThisIdent(thisIdent) - .withEnclosingClassName(Some(enclosingClassName)) - - new JSDesugar().desugarToFunction(params, body, isStat, env) + new JSDesugar().desugarToFunctionWithExplicitThis(params, body, isStat, + Env.empty.withEnclosingClassName(Some(enclosingClassName))) } /** Desugars parameters and body to a JS function. @@ -292,6 +289,24 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { // Now the work + /** Desugars parameters and body to a JS function where `this` is given as + * a normal parameter. + */ + def desugarToFunctionWithExplicitThis( + params: List[ParamDef], body: Tree, isStat: Boolean, env0: Env)( + implicit pos: Position): js.Function = { + + /* TODO The identifier `$thiz` cannot be produced by 0.6.x compilers due + * to their name mangling, which guarantees that it is unique. We should + * find a better way to do this in the future, though. + */ + val thisIdent = js.Ident("$thiz", Some("this")) + val env = env0.withThisIdent(Some(thisIdent)) + val js.Function(jsParams, jsBody) = + desugarToFunction(params, body, isStat, env) + js.Function(js.ParamDef(thisIdent, rest = false) :: jsParams, jsBody) + } + /** Desugars parameters and body to a JS function. */ def desugarToFunction( From 014382e931af640decf6e0f5938e59eeaf6e5084 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 22 Apr 2017 19:02:12 -0400 Subject: [PATCH 0308/2665] Remove the implicit conversion from ir.Ident to js.Ident. Instead, we use explicit conversions, in the form of three different `transformXIdent`, to transform identifiers in the three different "scopes": local variables, properties and labels. In practice, all three transformation methods do exactly the same thing for now, but this will change with the upcoming more elaborate handling of identifiers prompted by global references. --- .../linker/backend/emitter/ClassEmitter.scala | 28 ++++--- .../backend/emitter/FunctionEmitter.scala | 78 ++++++++++++------- .../tools/linker/backend/emitter/JSGen.scala | 3 - 3 files changed, 62 insertions(+), 47 deletions(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index 95c5e03771..d9a8e67d6f 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -474,8 +474,8 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { def genPropertyName(name: PropertyName)( implicit globalKnowledge: GlobalKnowledge): js.PropertyName = { name match { - case ident: Ident => transformIdent(ident) - case StringLiteral(value) => js.StringLiteral(value)(name.pos) + case Ident(nameStr, origName) => js.Ident(nameStr, origName)(name.pos) + case StringLiteral(value) => js.StringLiteral(value)(name.pos) case ComputedName(tree, _) => implicit val pos = name.pos @@ -518,7 +518,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val isAncestorOfBoxedUnitClass = AncestorsOfBoxedUnitClass.contains(className) - val objParam = js.ParamDef(Ident("obj"), rest = false) + val objParam = js.ParamDef(js.Ident("obj"), rest = false) val obj = objParam.ref val createIsStat = { @@ -599,17 +599,17 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val className = tree.name.name val displayName = decodeClassName(className) - val objParam = js.ParamDef(Ident("obj"), rest = false) + val objParam = js.ParamDef(js.Ident("obj"), rest = false) val obj = objParam.ref - val depthParam = js.ParamDef(Ident("depth"), rest = false) + val depthParam = js.ParamDef(js.Ident("depth"), rest = false) val depth = depthParam.ref val createIsArrayOfStat = { envFieldDef("isArrayOf", className, js.Function(List(objParam, depthParam), className match { case Definitions.ObjectClass => - val dataVarDef = genLet(Ident("data"), mutable = false, { + val dataVarDef = genLet(js.Ident("data"), mutable = false, { obj && (obj DOT "$classData") }) val data = dataVarDef.ref @@ -618,7 +618,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { js.If(!data, { js.Return(js.BooleanLiteral(false)) }, { - val arrayDepthVarDef = genLet(Ident("arrayDepth"), mutable = false, { + val arrayDepthVarDef = genLet(js.Ident("arrayDepth"), mutable = false, { (data DOT "arrayDepth") || js.IntLiteral(0) }) val arrayDepth = arrayDepthVarDef.ref @@ -681,8 +681,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { implicit val pos = tree.pos - val classIdent = transformIdent(tree.name) - val className = classIdent.name + val className = tree.name.name val kind = tree.kind val isObjectClass = @@ -718,7 +717,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { (envField("is", className), envField("isArrayOf", className)) } else if (isHijackedBoxedClass) { /* Hijacked boxed classes have a special isInstanceOf test. */ - val xParam = js.ParamDef(Ident("x"), rest = false) + val xParam = js.ParamDef(js.Ident("x"), rest = false) (js.Function(List(xParam), js.Return { genIsInstanceOf(xParam.ref, ClassType(className)) }), js.Undefined()) @@ -738,8 +737,8 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { (envField("noIsInstance"), js.Undefined()) } else { val jsCtor = genRawJSClassConstructor(className, tree.jsNativeLoadSpec) - (js.Function(List(js.ParamDef(Ident("x"), rest = false)), js.Return { - js.BinaryOp(JSBinaryOp.instanceof, js.VarRef(Ident("x")), jsCtor) + (js.Function(List(js.ParamDef(js.Ident("x"), rest = false)), js.Return { + js.BinaryOp(JSBinaryOp.instanceof, js.VarRef(js.Ident("x")), jsCtor) }), js.Undefined()) } } else { @@ -749,7 +748,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { } val allParams = List( - js.ObjectConstr(List(classIdent -> js.IntLiteral(0))), + js.ObjectConstr(List(js.Ident(className) -> js.IntLiteral(0))), js.BooleanLiteral(kind == ClassKind.Interface), js.StringLiteral(semantics.runtimeClassName(tree)), ancestorsRecord, @@ -784,8 +783,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { implicit val pos = tree.pos - val classIdent = transformIdent(tree.name) - val className = classIdent.name + val className = tree.name.name val tpe = ClassType(className) require(tree.kind.hasModuleAccessor, diff --git 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 index 8f72213dfa..3430b4de83 100644 --- 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 @@ -240,9 +240,6 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { desugar.transformExpr(tree)(env) } - private def transformParamDef(paramDef: ParamDef): js.ParamDef = - js.ParamDef(paramDef.name, paramDef.rest)(paramDef.pos) - private class JSDesugar()(implicit globalKnowledge: GlobalKnowledge) { // Synthetic variables @@ -346,13 +343,13 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { val offset = params.size - 1 val restParamDef = params.last - val lenIdent = newSyntheticVar() + val lenIdent = transformLocalVarIdent(newSyntheticVar()) val len = js.VarRef(lenIdent) - val counterIdent = newSyntheticVar() + val counterIdent = transformLocalVarIdent(newSyntheticVar()) val counter = js.VarRef(counterIdent) - val restParamIdent = restParamDef.name + val restParamIdent = transformLocalVarIdent(restParamDef.name) val restParam = js.VarRef(restParamIdent) val arguments = js.VarRef(js.Ident("arguments")) @@ -407,7 +404,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { unnest(qualifier, rhs) { (newQualifier, newRhs, env0) => implicit val env = env0 js.Assign( - js.DotSelect(transformExpr(newQualifier), item)(select.pos), + js.DotSelect(transformExpr(newQualifier), + transformPropIdent(item))(select.pos), transformExpr(newRhs)) } @@ -435,7 +433,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { unnest(qualifier, rhs) { (newQualifier, newRhs, env0) => implicit val env = env0 js.Assign( - js.DotSelect(transformExpr(newQualifier), item)(select.pos), + js.DotSelect(transformExpr(newQualifier), + transformPropIdent(item))(select.pos), transformExpr(newRhs)) } @@ -478,7 +477,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { /* We cannot simply unnest(cond) here, because that would eject the * evaluation of the condition out of the loop. */ - val newLabel = label.map(transformIdent) + val newLabel = label.map(transformLabelIdent) val bodyBreakTargets = tailPosLabels ++ label.map(_.name) if (isExpression(cond)) { js.While(transformExpr(cond), @@ -501,7 +500,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { /* We cannot simply unnest(cond) here, because that would eject the * evaluation of the condition out of the loop. */ - val newLabel = label.map(transformIdent) + val newLabel = label.map(transformLabelIdent) val bodyBreakTargets = tailPosLabels ++ label.map(_.name) if (isExpression(cond)) { js.DoWhile( @@ -625,7 +624,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { newName match { case newName: Ident => val descriptors = js.ObjectConstr(List( - transformIdent(newName) -> descriptor)) + transformPropIdent(newName) -> descriptor)) makeObjectMethodApply("defineProperties", List(js.This(), descriptors)) @@ -646,7 +645,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case JSDelete(JSDotSelect(obj, prop)) => unnest(obj) { (newObj, env0) => implicit val env = env0 - js.Delete(js.DotSelect(transformExpr(newObj), prop)) + js.Delete(js.DotSelect(transformExpr(newObj), + transformPropIdent(prop))) } case JSDelete(JSBracketSelect(obj, prop)) => @@ -1127,7 +1127,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { }) case _ => - genLet(ident, mutable, transformExpr(rhs)) + genLet(transformLocalVarIdent(ident), mutable, transformExpr(rhs)) } } @@ -1142,7 +1142,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { }) case _ => - genEmptyMutableLet(ident) + genEmptyMutableLet(transformLocalVarIdent(ident)) } } @@ -1212,7 +1212,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { js.Block(body, js.Break(None)) } else { usedLabels += l.name - js.Block(body, js.Break(Some(transformIdent(l)))) + js.Block(body, js.Break(Some(transformLabelIdent(l)))) } } @@ -1295,7 +1295,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { val newBody = pushLhsInto(newLhs, body, tailPosLabels + label.name)(bodyEnv) if (usedLabels.contains(label.name)) - js.Labeled(label, newBody) + js.Labeled(transformLabelIdent(label), newBody) else newBody } @@ -1304,7 +1304,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { pushLhsInto(Lhs.Return(label), expr, tailPosLabels) case Continue(label) => - js.Continue(label.map(transformIdent)) + js.Continue(label.map(transformLabelIdent)) case If(cond, thenp, elsep) => unnest(cond) { (newCond, env0) => @@ -1320,7 +1320,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { extractLet { newLhs => val newBlock = pushLhsInto(newLhs, block, tailPosLabels) val newHandler = pushLhsInto(newLhs, handler, tailPosLabels) - js.TryCatch(newBlock, errVar, newHandler) + js.TryCatch(newBlock, transformLocalVarIdent(errVar), newHandler) } case TryFinally(block, finalizer) => @@ -1761,17 +1761,20 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { // Scala expressions case New(cls, ctor, args) => - js.Apply(js.New(encodeClassVar(cls.className), Nil) DOT ctor, + js.Apply( + js.DotSelect( + js.New(encodeClassVar(cls.className), Nil), + transformPropIdent(ctor)), args map transformExpr) case LoadModule(cls) => genLoadModule(cls.className) case RecordFieldVarRef(VarRef(name)) => - js.VarRef(name) + js.VarRef(transformLocalVarIdent(name)) case Select(qualifier, item) => - transformExpr(qualifier) DOT item + transformExpr(qualifier) DOT transformPropIdent(item) case SelectStatic(cls, item) => genSelectStatic(cls.className, item) @@ -1791,7 +1794,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { val helperName = hijackedClassMethodToHelperName(method.name) genCallHelper(helperName, newReceiver :: newArgs: _*) } else { - js.Apply(newReceiver DOT method, newArgs) + js.Apply(newReceiver DOT transformPropIdent(method), newArgs) } case ApplyStatically(receiver, cls, method, args) => @@ -1804,7 +1807,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { js.Apply(envField("f", fullName, origName), transformedArgs) } else { - val fun = encodeClassVar(className).prototype DOT method + val fun = + encodeClassVar(className).prototype DOT transformPropIdent(method) js.Apply(fun DOT "call", transformedArgs) } @@ -1952,7 +1956,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case ArrayLength(array) => genIdentBracketSelect(js.DotSelect(transformExpr(array), - Ident("u")), "length") + js.Ident("u")), "length") case ArraySelect(array, index) => val newArray = transformExpr(array) @@ -2033,7 +2037,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { js.New(transformExpr(constr), args map transformExpr) case JSDotSelect(qualifier, item) => - js.DotSelect(transformExpr(qualifier), item) + js.DotSelect(transformExpr(qualifier), transformPropIdent(item)) case JSBracketSelect(qualifier, item) => genBracketSelect(transformExpr(qualifier), transformExpr(item)) @@ -2059,7 +2063,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { js.Apply(protectedFun, args map transformExpr) case JSDotMethodApply(receiver, method, args) => - js.Apply(js.DotSelect(transformExpr(receiver), method), + js.Apply( + js.DotSelect(transformExpr(receiver), transformPropIdent(method)), args map transformExpr) case JSBracketMethodApply(receiver, method, args) => @@ -2130,12 +2135,13 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { } case ClassOf(cls) => - js.Apply(js.DotSelect(genClassDataOf(cls), Ident("getClassOf")), Nil) + js.Apply(js.DotSelect(genClassDataOf(cls), js.Ident("getClassOf")), + Nil) // Atomic expressions case VarRef(name) => - js.VarRef(name) + js.VarRef(transformLocalVarIdent(name)) case This() => env.thisIdent.fold[js.Tree] { @@ -2216,16 +2222,30 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { "isInfinite__Z" -> "isInfinite" ) + private def transformParamDef(paramDef: ParamDef): js.ParamDef = { + js.ParamDef(transformLocalVarIdent(paramDef.name), paramDef.rest)( + paramDef.pos) + } + def transformPropertyName(pName: PropertyName)( implicit env: Env): js.PropertyName = { implicit val pos = pName.pos pName match { - case name: Ident => transformIdent(name) + case name: Ident => transformPropIdent(name) case StringLiteral(s) => js.StringLiteral(s) case ComputedName(tree, _) => js.ComputedName(transformExpr(tree)) } } + 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(ident.name, ident.originalName)(ident.pos) + def genClassDataOf(cls: ReferenceType)(implicit pos: Position): js.Tree = { cls match { case ClassType(className) => diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala index f23d649432..32a747cdad 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala @@ -30,9 +30,6 @@ private[emitter] final class JSGen(val semantics: Semantics, internalOptions: InternalOptions) { import JSGen._ - implicit def transformIdent(ident: irt.Ident): Ident = - Ident(ident.name, ident.originalName)(ident.pos) - def genZeroOf(tpe: Type)(implicit pos: Position): Tree = { tpe match { case BooleanType => BooleanLiteral(false) From e202b8b62937615c5b25ac51eb7ba8e57fc7b396 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 28 Apr 2017 21:05:52 +0200 Subject: [PATCH 0309/2665] Remove FunctionEmitter.desugarTree. It had only one call site, which used that method only to desugar a trivial assignment constructed for the occasion. It is nicer to directly emit the corresponding `js.Tree`. --- .../linker/backend/emitter/ClassEmitter.scala | 15 +++++++-------- .../linker/backend/emitter/FunctionEmitter.scala | 13 ------------- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index d9a8e67d6f..9d5ee27eb8 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -165,7 +165,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { js.DotSelect(encodeClassVar(parentIdent.name), js.Ident("call")), List(js.This())) } - val fieldDefs = genFieldDefs(tree) + val fieldDefs = genFieldDefsOfScalaClass(tree) js.Function(Nil, js.Block(superCtorCall :: fieldDefs)) } else { genConstructorFunForJSClass(tree) @@ -209,7 +209,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val js.Function(params, body) = genConstructorFunForJSClass(tree) js.MethodDef(static = false, js.Ident("constructor"), params, body) } else { - val fieldDefs = genFieldDefs(tree) + val fieldDefs = genFieldDefsOfScalaClass(tree) if (fieldDefs.isEmpty && outputMode == OutputMode.ECMAScript6) { js.Skip() } else { @@ -239,19 +239,18 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { } } - /** Generates the creation of fields for a class. */ - private def genFieldDefs(tree: LinkedClass)( + /** Generates the creation of fields for a Scala class. */ + private def genFieldDefsOfScalaClass(tree: LinkedClass)( implicit globalKnowledge: GlobalKnowledge): List[js.Tree] = { val tpe = ClassType(tree.encodedName) for { field @ FieldDef(false, name, ftpe, mutable) <- tree.fields } yield { implicit val pos = field.pos - val selectField = (name: @unchecked) match { - case name: Ident => Select(This()(tpe), name)(ftpe) + val jsIdent = (name: @unchecked) match { + case Ident(name, origName) => js.Ident(name, origName) } - desugarTree(Some(tree.encodedName), - Assign(selectField, zeroOf(ftpe)), isStat = true) + js.Assign(js.DotSelect(js.This(), jsIdent), genZeroOf(ftpe)) } } diff --git 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 index 3430b4de83..60df0ea775 100644 --- 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 @@ -227,19 +227,6 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { new JSDesugar().desugarToFunction(params, body, isStat, Env.empty) } - /** Desugars a statement or an expression. */ - def desugarTree( - enclosingClassName: Option[String], - tree: Tree, isStat: Boolean)( - implicit globalKnowledge: GlobalKnowledge): js.Tree = { - val env = Env.empty.withEnclosingClassName(enclosingClassName) - val desugar = new JSDesugar() - if (isStat) - desugar.transformStat(tree, Set.empty)(env) - else - desugar.transformExpr(tree)(env) - } - private class JSDesugar()(implicit globalKnowledge: GlobalKnowledge) { // Synthetic variables From 9896277ed1c9b8ff5e792fd7381911dc4d20db3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 4 Jun 2017 13:14:47 +0200 Subject: [PATCH 0310/2665] Reuse the `testsuite.utils.Platform` of testSuite in testSuiteEx. This avoids some code duplication. --- project/Build.scala | 4 +++- .../org/scalajs/testsuite/utils/Platform.scala | 17 ----------------- 2 files changed, 3 insertions(+), 18 deletions(-) delete mode 100644 test-suite-ex/src/test/scala/org/scalajs/testsuite/utils/Platform.scala diff --git a/project/Build.scala b/project/Build.scala index 9add6e7362..e06dd363d4 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1550,7 +1550,9 @@ object Build { publishArtifact in Compile := false, testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a", "-s"), scalacOptions in Test ~= (_.filter(_ != "-deprecation")) - ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn(library, jUnitRuntime) + ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( + library, jUnitRuntime, testSuite + ) lazy val partest: Project = project.settings( commonSettings, diff --git a/test-suite-ex/src/test/scala/org/scalajs/testsuite/utils/Platform.scala b/test-suite-ex/src/test/scala/org/scalajs/testsuite/utils/Platform.scala deleted file mode 100644 index a7a047ecd4..0000000000 --- a/test-suite-ex/src/test/scala/org/scalajs/testsuite/utils/Platform.scala +++ /dev/null @@ -1,17 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ -package org.scalajs.testsuite.utils - -/** This is a partial copy of the implementation in the testSuite */ -object Platform { - - def typedArrays: Boolean = sysProp("typedarray") - - private def sysProp(key: String): Boolean = - System.getProperty("scalajs." + key, "false") == "true" -} From ff35a233598a610ba622423e9fb525391d1ba068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 7 Jun 2017 13:50:20 +0200 Subject: [PATCH 0311/2665] Introduce the `WithGlobals` monad around trees in the emitter. The next commit will need to keep track of a set of global variable names referred to by a `js.Tree`. When combining trees, the sets must be union'ed together and propagated. The need for this is particularly present in the `ClassEmitter`. To ease this propagation, we introduce the monad `WithGlobals`, which encapsulates the association of a set of global variables. However, in this commit, the set is actually always empty. It will become non-empty in the next commit. Almost only `ClassEmitter` is affected by the rewrite, but some of its interfaces are too. `FunctionEmitter` now returns a `WithGlobals[js.Function]`, and some of `JSGen`'s methods return a `WithGlobals[js.Tree]`. The `Emitter` is also adapted to receive `WithGlobals[_]` from the `ClassEmitter`. This commit cannot be understood on its own; it needs to be put in the context of the next commit (about referring to the global scope). This commit isolates the non-functional changes involving `WithGlobals[_]`. --- .../linker/backend/emitter/ClassEmitter.scala | 595 ++++++++++-------- .../linker/backend/emitter/Emitter.scala | 28 +- .../backend/emitter/FunctionEmitter.scala | 61 +- .../tools/linker/backend/emitter/JSGen.scala | 22 +- .../linker/backend/emitter/WithGlobals.scala | 113 ++++ 5 files changed, 518 insertions(+), 301 deletions(-) create mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/WithGlobals.scala diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index 9d5ee27eb8..e8e2b669f4 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -32,78 +32,88 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { import jsGen._ def genStaticMembers(tree: LinkedClass)( - implicit globalKnowledge: GlobalKnowledge): js.Tree = { + implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { val className = tree.name.name - val staticMemberDefs = + val staticMemberDefsWithGlobals = tree.staticMethods.map(m => genMethod(className, m.tree)) - js.Block(staticMemberDefs)(tree.pos) + for (staticMemberDefs <- WithGlobals.list(staticMemberDefsWithGlobals)) + yield js.Block(staticMemberDefs)(tree.pos) } def genDefaultMethods(tree: LinkedClass)( - implicit globalKnowledge: GlobalKnowledge): js.Tree = { + implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { val className = tree.name.name - val defaultMethodDefs = + val defaultMethodDefsWithGlobals = tree.memberMethods.map(m => genDefaultMethod(className, m.tree)) - js.Block(defaultMethodDefs)(tree.pos) + for (defaultMethodDefs <- WithGlobals.list(defaultMethodDefsWithGlobals)) + yield js.Block(defaultMethodDefs)(tree.pos) } - def buildClass(tree: LinkedClass, ctor: js.Tree, memberDefs: List[js.Tree], - exportedDefs: js.Tree)( - implicit globalKnowledge: GlobalKnowledge): js.Tree = { - val className = tree.name.name - val allDefsBlock = - js.Block(ctor +: memberDefs :+ exportedDefs)(tree.pos) - - val entireClassDef = outputMode match { - case OutputMode.ECMAScript51Isolated => - allDefsBlock + def buildClass(tree: LinkedClass, ctor: WithGlobals[js.Tree], + memberDefs: List[WithGlobals[js.Tree]], exportedDefs: WithGlobals[js.Tree])( + implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { - case OutputMode.ECMAScript6 => - val allDefs = allDefsBlock match { - case js.Block(allDefs) => allDefs - case js.Skip() => Nil - case oneDef => List(oneDef) - } - genES6Class(tree, allDefs) - } + WithGlobals.list(ctor +: memberDefs :+ exportedDefs).flatMap { allDefs => + val className = tree.name.name + val allDefsBlock = js.Block(allDefs)(tree.pos) - if (!tree.kind.isJSClass) { - entireClassDef - } else { - // Wrap the entire class def in an accessor function - import TreeDSL._ - implicit val pos = tree.pos - - val createClassValueVar = - envFieldDef("b", className, js.Undefined(), mutable = true) - - val createAccessor = { - val classValueVar = envField("b", className) - - val body = js.Block( - js.If(!classValueVar, { - js.Block( - entireClassDef, - genCreateStaticFieldsOfJSClass(tree), - classValueVar := envField("c", className), - genStaticInitialization(tree) - ) - }, { - js.Skip() - }), - js.Return(classValueVar) - ) + val entireClassDefWithGlobals = outputMode match { + case OutputMode.ECMAScript51Isolated => + WithGlobals(allDefsBlock) - envFieldDef("a", className, js.Function(Nil, body)) + case OutputMode.ECMAScript6 => + val allDefs = allDefsBlock match { + case js.Block(allDefs) => allDefs + case js.Skip() => Nil + case oneDef => List(oneDef) + } + genES6Class(tree, allDefs) } - js.Block(createClassValueVar, createAccessor) + if (!tree.kind.isJSClass) { + entireClassDefWithGlobals + } else { + // Wrap the entire class def in an accessor function + import TreeDSL._ + implicit val pos = tree.pos + + val createClassValueVar = + envFieldDef("b", className, js.Undefined(), mutable = true) + + for { + entireClassDef <- entireClassDefWithGlobals + createStaticFields <- genCreateStaticFieldsOfJSClass(tree) + } yield { + val createAccessor = { + val classValueVar = envField("b", className) + + val body = js.Block( + js.If(!classValueVar, { + js.Block( + entireClassDef :: + createStaticFields ::: + (classValueVar := envField("c", className)) :: + genStaticInitialization(tree) :: + Nil + ) + }, { + js.Skip() + }), + js.Return(classValueVar) + ) + + envFieldDef("a", className, js.Function(Nil, body)) + } + + js.Block(createClassValueVar, createAccessor) + } + } } } /** Generates an ECMAScript 6 class for a linked class. */ def genES6Class(tree: LinkedClass, members: List[js.Tree])( - implicit globalKnowledge: GlobalKnowledge): js.Tree = { + implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { require(outputMode == OutputMode.ECMAScript6) @@ -111,20 +121,22 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val classIdent = encodeClassVar(className)(tree.name.pos).asInstanceOf[js.VarRef].ident - val parentVar = for (parentIdent <- tree.superClass) yield { + val parentVarWithGlobals = for (parentIdent <- tree.superClass) yield { implicit val pos = parentIdent.pos - if (!tree.kind.isJSClass) - encodeClassVar(parentIdent.name) - else + if (!tree.kind.isJSClass) { + WithGlobals(encodeClassVar(parentIdent.name)) + } else { genRawJSClassConstructor(parentIdent.name) + } } - js.ClassDef(Some(classIdent), parentVar, members)(tree.pos) + for (parentVar <- WithGlobals.option(parentVarWithGlobals)) + yield js.ClassDef(Some(classIdent), parentVar, members)(tree.pos) } /** Generates the JS constructor for a class. */ def genConstructor(tree: LinkedClass)( - implicit globalKnowledge: GlobalKnowledge): js.Tree = { + implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { assert(tree.kind.isAnyScalaJSDefinedClass) assert(tree.superClass.isDefined || tree.name.name == Definitions.ObjectClass, @@ -141,12 +153,13 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { /** Generates the JS constructor for a class, ES5 style. */ private def genES5Constructor(tree: LinkedClass)( - implicit globalKnowledge: GlobalKnowledge): js.Tree = { + implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { import TreeDSL._ implicit val pos = tree.pos val className = tree.name.name val isJSClass = tree.kind.isJSClass + val typeVar = encodeClassVar(className) def makeInheritableCtorDef(ctorToMimic: js.Tree) = { js.Block( @@ -157,7 +170,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { ) } - val ctorFun = if (!isJSClass) { + val ctorFunWithGlobals = if (!isJSClass) { val superCtorCall = tree.superClass.fold[js.Tree] { js.Skip() } { parentIdent => @@ -166,66 +179,75 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { List(js.This())) } val fieldDefs = genFieldDefsOfScalaClass(tree) - js.Function(Nil, js.Block(superCtorCall :: fieldDefs)) + WithGlobals(js.Function(Nil, js.Block(superCtorCall :: fieldDefs))) } else { genConstructorFunForJSClass(tree) } - val typeVar = encodeClassVar(className) - val docComment = js.DocComment("@constructor") - val ctorDef = envFieldDef("c", className, ctorFun, - keepFunctionExpression = isJSClass) - - val chainProto = tree.superClass.fold[js.Tree] { - js.Skip() + val chainProtoWithGlobals = tree.superClass.fold[WithGlobals[js.Tree]] { + WithGlobals(js.Skip()) } { parentIdent => - val (inheritedCtorDef, inheritedCtorRef) = if (!isJSClass) { - (js.Skip(), envField("h", parentIdent.name)) + val (inheritedCtorDefWithGlobals, inheritedCtorRef) = if (!isJSClass) { + (WithGlobals(js.Skip()), envField("h", parentIdent.name)) } else { val superCtor = genRawJSClassConstructor(parentIdent.name) - (makeInheritableCtorDef(superCtor), envField("h", className)) + (superCtor.map(makeInheritableCtorDef(_)), envField("h", className)) } - js.Block( - inheritedCtorDef, - typeVar.prototype := js.New(inheritedCtorRef, Nil), - genAddToPrototype(className, js.StringLiteral("constructor"), typeVar) - ) + for (inheritedCtorDef <- inheritedCtorDefWithGlobals) yield { + js.Block( + inheritedCtorDef, + typeVar.prototype := js.New(inheritedCtorRef, Nil), + genAddToPrototype(className, js.StringLiteral("constructor"), typeVar) + ) + } } - val inheritableCtorDef = - if (isJSClass) js.Skip() - else makeInheritableCtorDef(typeVar) + for { + ctorFun <- ctorFunWithGlobals + chainProto <- chainProtoWithGlobals + } yield { + val docComment = js.DocComment("@constructor") + val ctorDef = envFieldDef("c", className, ctorFun, + keepFunctionExpression = isJSClass) + + val inheritableCtorDef = + if (isJSClass) js.Skip() + else makeInheritableCtorDef(typeVar) - js.Block(docComment, ctorDef, chainProto, inheritableCtorDef) + js.Block(docComment, ctorDef, chainProto, inheritableCtorDef) + } } /** Generates the JS constructor for a class, ES6 style. */ private def genES6Constructor(tree: LinkedClass)( - implicit globalKnowledge: GlobalKnowledge): js.Tree = { + implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { implicit val pos = tree.pos if (tree.kind.isJSClass) { - val js.Function(params, body) = genConstructorFunForJSClass(tree) - js.MethodDef(static = false, js.Ident("constructor"), params, body) + for (fun <- genConstructorFunForJSClass(tree)) yield { + js.MethodDef(static = false, js.Ident("constructor"), fun.args, + fun.body) + } } else { val fieldDefs = genFieldDefsOfScalaClass(tree) if (fieldDefs.isEmpty && outputMode == OutputMode.ECMAScript6) { - js.Skip() + WithGlobals(js.Skip()) } else { val superCtorCall = tree.superClass.fold[js.Tree] { js.Skip()(tree.pos) } { parentIdent => js.Apply(js.Super(), Nil) } - js.MethodDef(static = false, js.Ident("constructor"), Nil, - js.Block(superCtorCall :: fieldDefs)) + val methodDef = js.MethodDef(static = false, js.Ident("constructor"), + Nil, js.Block(superCtorCall :: fieldDefs)) + WithGlobals(methodDef) } } } private def genConstructorFunForJSClass(tree: LinkedClass)( - implicit globalKnowledge: GlobalKnowledge): js.Function = { + implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Function] = { implicit val pos = tree.pos require(tree.kind.isJSClass) @@ -270,17 +292,19 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { /** Generates the creation of the static fields for a JavaScript class. */ private def genCreateStaticFieldsOfJSClass(tree: LinkedClass)( - implicit globalKnowledge: GlobalKnowledge): js.Tree = { + implicit globalKnowledge: GlobalKnowledge): WithGlobals[List[js.Tree]] = { val className = tree.encodedName - val stats = for { + val statsWithGlobals = for { field @ FieldDef(true, name, ftpe, mutable) <- tree.fields } yield { implicit val pos = field.pos val classVar = envField("c", className) - val select = genPropSelect(classVar, genPropertyName(name)) - js.Assign(select, genZeroOf(ftpe)) + for (propName <- genPropertyName(name)) yield { + val select = genPropSelect(classVar, propName) + js.Assign(select, genZeroOf(ftpe)) + } } - js.Block(stats)(tree.pos) + WithGlobals.list(statsWithGlobals) } /** Generates the static initializer invocation of a JavaScript class. */ @@ -297,71 +321,79 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { /** Generates a method. */ def genMethod(className: String, method: MethodDef)( - implicit globalKnowledge: GlobalKnowledge): js.Tree = { + implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { val methodBody = method.body.getOrElse( throw new AssertionError("Cannot generate an abstract method")) implicit val pos = method.pos - val methodFun0 = desugarToFunction(className, + val methodFun0WithGlobals = desugarToFunction(className, method.args, methodBody, method.resultType == NoType) - val methodFun = if (Definitions.isConstructorName(method.name.encodedName)) { - // init methods have to return `this` so that we can chain them to `new` - js.Function(methodFun0.args, { - implicit val pos = methodFun0.body.pos - js.Block( - methodFun0.body, - js.Return(js.This())) - })(methodFun0.pos) - } else { - methodFun0 - } - - if (method.static) { - method.name match { - case Ident(methodName, origName) => - envFieldDef("s", className + "__" + methodName, methodFun, origName) - - case methodName => - outputMode match { - case OutputMode.ECMAScript51Isolated => - genAddToObject(className, encodeClassVar(className), methodName, - methodFun) - - case OutputMode.ECMAScript6 => - js.MethodDef(static = true, genPropertyName(methodName), - methodFun.args, methodFun.body) - } + methodFun0WithGlobals.flatMap { methodFun0 => + val methodFun = if (Definitions.isConstructorName(method.name.encodedName)) { + // init methods have to return `this` so that we can chain them to `new` + js.Function(methodFun0.args, { + implicit val pos = methodFun0.body.pos + js.Block( + methodFun0.body, + js.Return(js.This())) + })(methodFun0.pos) + } else { + methodFun0 } - } else { - outputMode match { - case OutputMode.ECMAScript51Isolated => - genAddToPrototype(className, method.name, methodFun) - case OutputMode.ECMAScript6 => - js.MethodDef(static = false, genPropertyName(method.name), - methodFun.args, methodFun.body) + if (method.static) { + method.name match { + case Ident(methodName, origName) => + WithGlobals(envFieldDef("s", className + "__" + methodName, + methodFun, origName)) + + case methodName => + outputMode match { + case OutputMode.ECMAScript51Isolated => + genAddToObject(className, encodeClassVar(className), methodName, + methodFun) + + case OutputMode.ECMAScript6 => + for (propName <- genPropertyName(methodName)) yield { + js.MethodDef(static = true, propName, methodFun.args, + methodFun.body) + } + } + } + } else { + outputMode match { + case OutputMode.ECMAScript51Isolated => + genAddToPrototype(className, method.name, methodFun) + + case OutputMode.ECMAScript6 => + for (propName <- genPropertyName(method.name)) yield { + js.MethodDef(static = false, propName, methodFun.args, + methodFun.body) + } + } } } } /** Generates a default method. */ def genDefaultMethod(className: String, method: MethodDef)( - implicit globalKnowledge: GlobalKnowledge): js.Tree = { + implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { implicit val pos = method.pos - val methodFun = desugarToFunctionWithExplicitThis(className, - method.args, method.body.get, method.resultType == NoType) + val methodFunWithGlobals = desugarToFunctionWithExplicitThis( + className, method.args, method.body.get, method.resultType == NoType) - val Ident(methodName, origName) = method.name - - envFieldDef("f", className + "__" + methodName, methodFun, origName) + for (methodFun <- methodFunWithGlobals) yield { + val Ident(methodName, origName) = method.name + envFieldDef("f", className + "__" + methodName, methodFun, origName) + } } /** Generates a property. */ def genProperty(className: String, property: PropertyDef)( - implicit globalKnowledge: GlobalKnowledge): js.Tree = { + implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { outputMode match { case OutputMode.ECMAScript51Isolated => genPropertyES5(className, property) @@ -371,7 +403,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { } private def genPropertyES5(className: String, property: PropertyDef)( - implicit globalKnowledge: GlobalKnowledge): js.Tree = { + implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { import TreeDSL._ implicit val pos = property.pos @@ -386,61 +418,75 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { else classVar.prototype // property name - val name = genPropertyName(property.name) match { - case value: js.StringLiteral => value - case js.ComputedName(tree) => tree - - case id: js.Ident => - // We need to work around the closure compiler. Call propertyName to - // get a string representation of the optimized name - genCallHelper("propertyName", - js.ObjectConstr(id -> js.IntLiteral(0) :: Nil)) - } + val propNameWithGlobals = genPropertyName(property.name) // optional getter definition - val optGetter = property.getterBody map { body => - val fun = desugarToFunction(className, Nil, body, isStat = false) - js.StringLiteral("get") -> fun + val optGetterWithGlobals = property.getterBody map { body => + desugarToFunction(className, Nil, body, isStat = false) } // optional setter definition - val optSetter = property.setterArgAndBody map { case (arg, body) => - val fun = desugarToFunction(className, arg :: Nil, body, isStat = true) - js.StringLiteral("set") -> fun + val optSetterWithGlobals = property.setterArgAndBody map { + case (arg, body) => + desugarToFunction(className, arg :: Nil, body, isStat = true) } - // Options passed to the defineProperty method - val descriptor = js.ObjectConstr( - optGetter.toList ++ - optSetter ++ - List(js.StringLiteral("configurable") -> js.BooleanLiteral(true)) - ) + for { + propName <- propNameWithGlobals + optGetter <- WithGlobals.option(optGetterWithGlobals) + optSetter <- WithGlobals.option(optSetterWithGlobals) + } yield { + val name = propName match { + case value: js.StringLiteral => value + case js.ComputedName(tree) => tree + + case id: js.Ident => + // We need to work around the closure compiler. Call propertyName to + // get a string representation of the optimized name + genCallHelper("propertyName", + js.ObjectConstr(id -> js.IntLiteral(0) :: Nil)) + } + + // Options passed to the defineProperty method + val descriptor = js.ObjectConstr( + optGetter.map(js.StringLiteral("get") -> _).toList ::: + optSetter.map(js.StringLiteral("set") -> _).toList ::: + (js.StringLiteral("configurable") -> js.BooleanLiteral(true)) :: + Nil + ) - js.Apply(defProp, targetObject :: name :: descriptor :: Nil) + js.Apply(defProp, targetObject :: name :: descriptor :: Nil) + } } private def genPropertyES6(className: String, property: PropertyDef)( - implicit globalKnowledge: GlobalKnowledge): js.Tree = { + implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { implicit val pos = property.pos val static = property.static - val propName = genPropertyName(property.name) - val getter = property.getterBody.fold[js.Tree] { - js.Skip() - } { body => - val fun = desugarToFunction(className, Nil, body, isStat = false) - js.GetterDef(static, propName, fun.body) - } + genPropertyName(property.name).flatMap { propName => + val getterWithGlobals = property.getterBody.fold { + WithGlobals[js.Tree](js.Skip()) + } { body => + for (fun <- desugarToFunction(className, Nil, body, isStat = false)) + yield js.GetterDef(static, propName, fun.body) + } - val setter = property.setterArgAndBody.fold[js.Tree] { - js.Skip() - } { case (arg, body) => - val fun = desugarToFunction(className, arg :: Nil, body, isStat = true) - js.SetterDef(static, propName, fun.args.head, fun.body) - } + val setterWithGlobals = property.setterArgAndBody.fold { + WithGlobals[js.Tree](js.Skip()) + } { case (arg, body) => + for (fun <- desugarToFunction(className, arg :: Nil, body, isStat = true)) + yield js.SetterDef(static, propName, fun.args.head, fun.body) + } - js.Block(getter, setter) + for { + getter <- getterWithGlobals + setter <- setterWithGlobals + } yield { + js.Block(getter, setter) + } + } } /** Generate `classVar.prototype.name = value` */ @@ -453,8 +499,10 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { /** Generate `classVar.prototype.name = value` */ def genAddToPrototype(className: String, name: PropertyName, value: js.Tree)( - implicit globalKnowledge: GlobalKnowledge, pos: Position): js.Tree = { - genAddToPrototype(className, genPropertyName(name), value) + implicit globalKnowledge: GlobalKnowledge, + pos: Position): WithGlobals[js.Tree] = { + for (propName <- genPropertyName(name)) + yield genAddToPrototype(className, propName, value) } /** Generate `obj.name = value` */ @@ -466,27 +514,35 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { /** Generate `obj.name = value` */ def genAddToObject(className: String, obj: js.Tree, name: PropertyName, value: js.Tree)( - implicit globalKnowledge: GlobalKnowledge, pos: Position): js.Tree = { - genAddToObject(obj, genPropertyName(name), value) + implicit globalKnowledge: GlobalKnowledge, + pos: Position): WithGlobals[js.Tree] = { + for (propName <- genPropertyName(name)) + yield genAddToObject(obj, propName, value) } def genPropertyName(name: PropertyName)( - implicit globalKnowledge: GlobalKnowledge): js.PropertyName = { + implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.PropertyName] = { name match { - case Ident(nameStr, origName) => js.Ident(nameStr, origName)(name.pos) - case StringLiteral(value) => js.StringLiteral(value)(name.pos) + case Ident(nameStr, origName) => + WithGlobals(js.Ident(nameStr, origName)(name.pos)) + + case StringLiteral(value) => + WithGlobals(js.StringLiteral(value)(name.pos)) case ComputedName(tree, _) => implicit val pos = name.pos - val fun = desugarToFunction(params = Nil, body = tree, isStat = false) - val nameTree = fun match { - case js.Function(Nil, js.Return(expr)) => - // no need for an IIFE, we can just use `expr` directly - expr - case _ => - js.Apply(fun, Nil) + for { + fun <- desugarToFunction(params = Nil, body = tree, isStat = false) + } yield { + val nameTree = fun match { + case js.Function(Nil, js.Return(expr)) => + // no need for an IIFE, we can just use `expr` directly + expr + case _ => + js.Apply(fun, Nil) + } + js.ComputedName(nameTree) } - js.ComputedName(nameTree) } } @@ -674,7 +730,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { } def genTypeData(tree: LinkedClass)( - implicit globalKnowledge: GlobalKnowledge): js.Tree = { + implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { import Definitions._ import TreeDSL._ @@ -688,7 +744,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val isHijackedBoxedClass = HijackedBoxedClasses.contains(className) val isAncestorOfHijackedClass = - AncestorsOfHijackedClasses.contains(className) + isObjectClass || AncestorsOfHijackedClasses.contains(className) val isJSType = kind.isJSType @@ -710,20 +766,19 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val ancestorsRecord = js.ObjectConstr( tree.ancestors.map(ancestor => (js.Ident(ancestor), js.IntLiteral(1)))) - val (isInstanceFun, isArrayOfFun) = { - if (isObjectClass) { - /* Object has special $is_O *and* $isArrayOf_O. */ - (envField("is", className), envField("isArrayOf", className)) - } else if (isHijackedBoxedClass) { + val isInstanceFunWithGlobals: WithGlobals[js.Tree] = { + if (isHijackedBoxedClass) { /* Hijacked boxed classes have a special isInstanceOf test. */ val xParam = js.ParamDef(js.Ident("x"), rest = false) - (js.Function(List(xParam), js.Return { + WithGlobals(js.Function(List(xParam), js.Return { genIsInstanceOf(xParam.ref, ClassType(className)) - }), js.Undefined()) + })) } else if (isAncestorOfHijackedClass || className == StringClass) { - /* java.lang.String and ancestors of hijacked classes have a normal - * $is_pack_Class test but with a non-standard behavior. */ - (envField("is", className), js.Undefined()) + /* java.lang.String and ancestors of hijacked classes, including + * java.lang.Object, have a normal $is_pack_Class test but with a + * non-standard behavior. + */ + WithGlobals(envField("is", className)) } else if (isJSType) { /* Native JS classes have an instanceof operator-based isInstanceOf * test dictated by their jsNativeLoadSpec. @@ -733,37 +788,52 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { * cannot be performed and must throw. */ if (kind != ClassKind.JSClass && kind != ClassKind.NativeJSClass) { - (envField("noIsInstance"), js.Undefined()) + WithGlobals(envField("noIsInstance")) } else { - val jsCtor = genRawJSClassConstructor(className, tree.jsNativeLoadSpec) - (js.Function(List(js.ParamDef(js.Ident("x"), rest = false)), js.Return { - js.BinaryOp(JSBinaryOp.instanceof, js.VarRef(js.Ident("x")), jsCtor) - }), js.Undefined()) + for { + jsCtor <- genRawJSClassConstructor(className, tree.jsNativeLoadSpec) + } yield { + js.Function(List(js.ParamDef(js.Ident("x"), rest = false)), js.Return { + js.BinaryOp(JSBinaryOp.instanceof, js.VarRef(js.Ident("x")), jsCtor) + }) + } } } else { // For other classes, the isInstance function can be inferred. - (js.Undefined(), js.Undefined()) + WithGlobals(js.Undefined()) } } - val allParams = List( - js.ObjectConstr(List(js.Ident(className) -> js.IntLiteral(0))), - js.BooleanLiteral(kind == ClassKind.Interface), - js.StringLiteral(semantics.runtimeClassName(tree)), - ancestorsRecord, - isRawJSTypeParam, - parentData, - isInstanceFun, - isArrayOfFun - ) + val isArrayOfFun = { + if (isObjectClass) { + // Object is the only class that has a special $isArrayOf_O. + envField("isArrayOf", className) + } else { + // For other classes, the isArrayOf function can be inferred. + js.Undefined() + } + } + + for (isInstanceFun <- isInstanceFunWithGlobals) yield { + val allParams = List( + js.ObjectConstr(List(js.Ident(className) -> js.IntLiteral(0))), + js.BooleanLiteral(kind == ClassKind.Interface), + js.StringLiteral(semantics.runtimeClassName(tree)), + ancestorsRecord, + isRawJSTypeParam, + parentData, + isInstanceFun, + isArrayOfFun + ) - val prunedParams = - allParams.reverse.dropWhile(_.isInstanceOf[js.Undefined]).reverse + val prunedParams = + allParams.reverse.dropWhile(_.isInstanceOf[js.Undefined]).reverse - val typeData = js.Apply(js.New(envField("TypeData"), Nil) DOT "initClass", - prunedParams) + val typeData = js.Apply(js.New(envField("TypeData"), Nil) DOT "initClass", + prunedParams) - envFieldDef("d", className, typeData) + envFieldDef("d", className, typeData) + } } def genSetTypeData(tree: LinkedClass): js.Tree = { @@ -798,7 +868,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { moduleInstanceVar := { if (tree.kind == ClassKind.JSModuleClass) { js.New( - genRawJSClassConstructor(className, None), + genNonNativeJSClassConstructor(className), Nil) } else { js.Apply( @@ -846,12 +916,12 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { } def genExportedMembers(tree: LinkedClass)( - implicit globalKnowledge: GlobalKnowledge): js.Tree = { - val exports = tree.exportedMembers map { member => + implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { + val exportsWithGlobals = tree.exportedMembers map { member => member.tree match { case MethodDef(false, StringLiteral("constructor"), _, _, _) if tree.kind.isJSClass => - js.Skip()(member.tree.pos) + WithGlobals(js.Skip()(member.tree.pos)) case m: MethodDef => genMethod(tree.encodedName, m) case p: PropertyDef => @@ -862,34 +932,35 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { } } - js.Block(exports)(tree.pos) + for (exports <- WithGlobals.list(exportsWithGlobals)) + yield js.Block(exports)(tree.pos) } def genClassExports(tree: LinkedClass)( - implicit globalKnowledge: GlobalKnowledge): js.Tree = { - val exports = tree.classExports map { + implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { + val exportsWithGlobals = tree.classExports map { case e: ConstructorExportDef => genConstructorExportDef(tree, e) case e: JSClassExportDef => - genJSClassExportDef(tree, e) + WithGlobals(genJSClassExportDef(tree, e)) case e: ModuleExportDef => - genModuleExportDef(tree, e) + WithGlobals(genModuleExportDef(tree, e)) case e: TopLevelModuleExportDef => - genTopLevelModuleExportDef(tree, e) + WithGlobals(genTopLevelModuleExportDef(tree, e)) case e: TopLevelMethodExportDef => genTopLevelMethodExportDef(tree, e) case e: TopLevelFieldExportDef => - genTopLevelFieldExportDef(tree, e) + WithGlobals(genTopLevelFieldExportDef(tree, e)) case tree => throw new AssertionError( "Illegal class export " + tree.getClass.getName) } - js.Block(exports)(tree.pos) + WithGlobals.list(exportsWithGlobals).map(js.Block(_)(tree.pos)) } def genConstructorExportDef(cd: LinkedClass, tree: ConstructorExportDef)( - implicit globalKnowledge: GlobalKnowledge): js.Tree = { + implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { import TreeDSL._ implicit val pos = tree.pos @@ -898,26 +969,28 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val baseCtor = envField("c", cd.name.name, cd.name.originalName) - val js.Function(thisParam :: ctorParams, ctorBody) = - desugarToFunctionWithExplicitThis(cd.encodedName, - args, body, isStat = true) + val generatedFunWithGlobals = desugarToFunctionWithExplicitThis( + cd.encodedName, args, body, isStat = true) - val thisIdent = thisParam.name + for (generatedFun <- generatedFunWithGlobals) yield { + val js.Function(thisParam :: ctorParams, ctorBody) = generatedFun + val thisIdent = thisParam.name - val exportedCtor = js.Function(ctorParams, js.Block( - genLet(thisIdent, mutable = false, js.New(baseCtor, Nil)), - ctorBody, - js.Return(js.VarRef(thisIdent)) - )) + val exportedCtor = js.Function(ctorParams, js.Block( + genLet(thisIdent, mutable = false, js.New(baseCtor, Nil)), + ctorBody, + js.Return(js.VarRef(thisIdent)) + )) - val (createNamespace, expCtorVar) = - genCreateNamespaceInExports(fullName) - js.Block( - createNamespace, - js.DocComment("@constructor"), - expCtorVar := exportedCtor, - expCtorVar DOT "prototype" := baseCtor DOT "prototype" - ) + val (createNamespace, expCtorVar) = + genCreateNamespaceInExports(fullName) + js.Block( + createNamespace, + js.DocComment("@constructor"), + expCtorVar := exportedCtor, + expCtorVar DOT "prototype" := baseCtor DOT "prototype" + ) + } } def genJSClassExportDef(cd: LinkedClass, tree: JSClassExportDef): js.Tree = { @@ -925,7 +998,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { implicit val pos = tree.pos - val classVar = genRawJSClassConstructor(cd.name.name, None) + val classVar = genNonNativeJSClassConstructor(cd.name.name) genClassOrModuleExportDef(cd, tree.fullName, classVar) } @@ -976,7 +1049,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { private def genTopLevelMethodExportDef(cd: LinkedClass, tree: TopLevelMethodExportDef)( - implicit globalKnowledge: GlobalKnowledge): js.Tree = { + implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { import TreeDSL._ val MethodDef(true, StringLiteral(fullName), args, resultType, Some(body)) = @@ -987,13 +1060,15 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val (createNamespace, expAccessorVar) = genCreateNamespaceInExports(fullName) - val methodDef = desugarToFunction(cd.encodedName, args, body, + val methodDefWithGlobals = desugarToFunction(cd.encodedName, args, body, isStat = resultType == NoType) - js.Block( - createNamespace, - expAccessorVar := methodDef - ) + for (methodDef <- methodDefWithGlobals) yield { + js.Block( + createNamespace, + expAccessorVar := methodDef + ) + } } private def genTopLevelFieldExportDef(cd: LinkedClass, diff --git 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 index 0634954400..d088fdf733 100644 --- 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 @@ -229,7 +229,12 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, private def emitLinkedClass( linkedClass: LinkedClass, builder: JSTreeBuilder): Unit = { - def addTree(tree: js.Tree): Unit = builder.addJSTree(tree) + def addTreeBase(tree: js.Tree): Unit = builder.addJSTree(tree) + + def addTree(treeWithGlobals: WithGlobals[js.Tree]): Unit = { + // Disregard treeWithGlobals.globalVarNames for now + addTreeBase(treeWithGlobals.value) + } val className = linkedClass.encodedName val classCache = getClassCache(linkedClass.ancestors) @@ -272,7 +277,7 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, } if (classEmitter.needInstanceTests(linkedClass)) { - addTree(classTreeCache.instanceTests.getOrElseUpdate(js.Block( + addTreeBase(classTreeCache.instanceTests.getOrElseUpdate(js.Block( classEmitter.genInstanceTests(linkedClass), classEmitter.genArrayInstanceTests(linkedClass) )(linkedClass.pos))) @@ -284,11 +289,11 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, } if (linkedClass.hasInstances && kind.isClass && linkedClass.hasRuntimeTypeInfo) - addTree(classTreeCache.setTypeData.getOrElseUpdate( + addTreeBase(classTreeCache.setTypeData.getOrElseUpdate( classEmitter.genSetTypeData(linkedClass))) if (linkedClass.kind.hasModuleAccessor) - addTree(classTreeCache.moduleAccessor.getOrElseUpdate( + addTreeBase(classTreeCache.moduleAccessor.getOrElseUpdate( classEmitter.genModuleAccessor(linkedClass))) } @@ -334,7 +339,7 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, val classTreeCache = classCache.getCache(linkedClass.version) builder.addJSTree(classTreeCache.classExports.getOrElseUpdate( - classEmitter.genClassExports(linkedClass)(classCache))) + classEmitter.genClassExports(linkedClass)(classCache)).value) } } @@ -425,7 +430,7 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, } private final class MethodCache extends knowledgeGuardian.KnowledgeAccessor { - private[this] var _tree: js.Tree = null + private[this] var _tree: WithGlobals[js.Tree] = null private[this] var _lastVersion: Option[String] = None private[this] var _cacheUsed = false @@ -437,7 +442,8 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, def startRun(): Unit = _cacheUsed = false - def getOrElseUpdate(version: Option[String], v: => js.Tree): js.Tree = { + def getOrElseUpdate(version: Option[String], + v: => WithGlobals[js.Tree]): WithGlobals[js.Tree] = { if (_tree == null || _lastVersion.isEmpty || _lastVersion != version) { invalidate() statsMethodsInvalidated += 1 @@ -461,14 +467,14 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, private object Emitter { private final class DesugaredClassCache { - val constructor = new OneTimeCache[js.Tree] - val exportedMembers = new OneTimeCache[js.Tree] + val constructor = new OneTimeCache[WithGlobals[js.Tree]] + val exportedMembers = new OneTimeCache[WithGlobals[js.Tree]] val instanceTests = new OneTimeCache[js.Tree] - val typeData = new OneTimeCache[js.Tree] + val typeData = new OneTimeCache[WithGlobals[js.Tree]] val setTypeData = new OneTimeCache[js.Tree] val moduleAccessor = new OneTimeCache[js.Tree] val staticFields = new OneTimeCache[js.Tree] - val classExports = new OneTimeCache[js.Tree] + val classExports = new OneTimeCache[WithGlobals[js.Tree]] } private final class OneTimeCache[A >: Null] { diff --git 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 index 60df0ea775..956a361754 100644 --- 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 @@ -199,10 +199,10 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { /** Desugars parameters and body to a JS function. */ - def desugarToFunction( - enclosingClassName: String, - params: List[ParamDef], body: Tree, isStat: Boolean)( - implicit globalKnowledge: GlobalKnowledge, pos: Position): js.Function = { + def desugarToFunction(enclosingClassName: String, params: List[ParamDef], + body: Tree, isStat: Boolean)( + implicit globalKnowledge: GlobalKnowledge, + pos: Position): WithGlobals[js.Function] = { new JSDesugar().desugarToFunction(params, body, isStat, Env.empty.withEnclosingClassName(Some(enclosingClassName))) } @@ -210,25 +210,29 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { /** Desugars parameters and body to a JS function where `this` is given as * an explicit normal parameter. */ - def desugarToFunctionWithExplicitThis( - enclosingClassName: String, params: List[ParamDef], - body: Tree, isStat: Boolean)( - implicit globalKnowledge: GlobalKnowledge, pos: Position): js.Function = { + def desugarToFunctionWithExplicitThis(enclosingClassName: String, + params: List[ParamDef], body: Tree, isStat: Boolean)( + implicit globalKnowledge: GlobalKnowledge, + pos: Position): WithGlobals[js.Function] = { new JSDesugar().desugarToFunctionWithExplicitThis(params, body, isStat, Env.empty.withEnclosingClassName(Some(enclosingClassName))) } /** Desugars parameters and body to a JS function. */ - def desugarToFunction( - params: List[ParamDef], - body: Tree, isStat: Boolean)( - implicit globalKnowledge: GlobalKnowledge, pos: Position): js.Function = { + def desugarToFunction(params: List[ParamDef], body: Tree, isStat: Boolean)( + implicit globalKnowledge: GlobalKnowledge, + pos: Position): WithGlobals[js.Function] = { new JSDesugar().desugarToFunction(params, body, isStat, Env.empty) } private class JSDesugar()(implicit globalKnowledge: GlobalKnowledge) { + private def extractWithGlobals[A](withGlobals: WithGlobals[A]): A = { + // Disregard withGlobals.globalVarNames for now + withGlobals.value + } + // Synthetic variables var syntheticVarCounter: Int = 0 @@ -278,7 +282,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { */ def desugarToFunctionWithExplicitThis( params: List[ParamDef], body: Tree, isStat: Boolean, env0: Env)( - implicit pos: Position): js.Function = { + implicit pos: Position): WithGlobals[js.Function] = { /* TODO The identifier `$thiz` cannot be produced by 0.6.x compilers due * to their name mangling, which guarantees that it is unique. We should @@ -287,13 +291,25 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { val thisIdent = js.Ident("$thiz", Some("this")) val env = env0.withThisIdent(Some(thisIdent)) val js.Function(jsParams, jsBody) = - desugarToFunction(params, body, isStat, env) - js.Function(js.ParamDef(thisIdent, rest = false) :: jsParams, jsBody) + desugarToFunctionInternal(params, body, isStat, env) + val result = + js.Function(js.ParamDef(thisIdent, rest = false) :: jsParams, jsBody) + WithGlobals(result) } /** Desugars parameters and body to a JS function. */ def desugarToFunction( + params: List[ParamDef], body: Tree, isStat: Boolean, env0: Env)( + implicit pos: Position): WithGlobals[js.Function] = { + val result = + desugarToFunctionInternal(params, body, isStat, env0) + WithGlobals(result) + } + + /** Desugars parameters and body to a JS function. + */ + private def desugarToFunctionInternal( params: List[ParamDef], body: Tree, isStat: Boolean, env0: Env)( implicit pos: Position): js.Function = { @@ -439,7 +455,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { unnest(List(qualifier, item, rhs)) { case (List(newQualifier, newItem, newRhs), env0) => implicit val env = env0 - val ctor = genRawJSClassConstructor(cls.className) + val ctor = + extractWithGlobals(genRawJSClassConstructor(cls.className)) genCallHelper("superSet", ctor DOT "prototype", transformExpr(newQualifier), transformExpr(item), transformExpr(rhs)) @@ -525,8 +542,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { val superCtorCall = { outputMode match { case OutputMode.ECMAScript51Isolated => - val superCtor = genRawJSClassConstructor( - globalKnowledge.getSuperClassOfJSClass(enclosingClassName)) + val superCtor = extractWithGlobals(genRawJSClassConstructor( + globalKnowledge.getSuperClassOfJSClass(enclosingClassName))) if (containsAnySpread(newArgs)) { val argArray = spreadToArgArray(newArgs) @@ -2059,12 +2076,12 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { transformExpr(method)), args map transformExpr) case JSSuperBracketSelect(cls, qualifier, item) => - val ctor = genRawJSClassConstructor(cls.className) + val ctor = extractWithGlobals(genRawJSClassConstructor(cls.className)) genCallHelper("superGet", ctor DOT "prototype", transformExpr(qualifier), transformExpr(item)) case LoadJSConstructor(cls) => - genRawJSClassConstructor(cls.className) + extractWithGlobals(genRawJSClassConstructor(cls.className)) case LoadJSModule(cls) => val className = cls.className @@ -2074,7 +2091,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { genLoadModule(className) case Some(spec) => - genLoadJSFromSpec(spec) + extractWithGlobals(genLoadJSFromSpec(spec)) } case JSSpread(items) => @@ -2139,7 +2156,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case Closure(captureParams, params, body, captureValues) => val innerFunction = - desugarToFunction(params, body, isStat = false, + desugarToFunctionInternal(params, body, isStat = false, Env.empty.withParams(captureParams ++ params)) if (captureParams.isEmpty) { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala index 32a747cdad..f09b04c2a8 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala @@ -147,7 +147,8 @@ private[emitter] final class JSGen(val semantics: Semantics, } def genRawJSClassConstructor(className: String)( - implicit globalKnowledge: GlobalKnowledge, pos: Position): Tree = { + implicit globalKnowledge: GlobalKnowledge, + pos: Position): WithGlobals[Tree] = { genRawJSClassConstructor(className, globalKnowledge.getJSNativeLoadSpec(className)) @@ -155,19 +156,24 @@ private[emitter] final class JSGen(val semantics: Semantics, def genRawJSClassConstructor(className: String, spec: Option[irt.JSNativeLoadSpec])( - implicit pos: Position): Tree = { + implicit pos: Position): WithGlobals[Tree] = { spec match { case None => - // This is a Scala.js-defined JS class, call its class value accessor - Apply(envField("a", className), Nil) + // This is a non-native JS class + WithGlobals(genNonNativeJSClassConstructor(className)) case Some(spec) => genLoadJSFromSpec(spec) } } - def genLoadJSFromSpec(spec: irt.JSNativeLoadSpec)( + def genNonNativeJSClassConstructor(className: String)( implicit pos: Position): Tree = { + Apply(envField("a", className), Nil) + } + + def genLoadJSFromSpec(spec: irt.JSNativeLoadSpec)( + implicit pos: Position): WithGlobals[Tree] = { def pathSelection(from: Tree, path: List[String]): Tree = { path.foldLeft(from) { @@ -177,16 +183,16 @@ private[emitter] final class JSGen(val semantics: Semantics, spec match { case irt.JSNativeLoadSpec.Global(path) => - pathSelection(envField("g"), path) + WithGlobals(pathSelection(envField("g"), path)) case irt.JSNativeLoadSpec.Import(module, path) => val moduleValue = envModuleField(module) path match { case DefaultExportName :: rest => val defaultField = genCallHelper("moduleDefault", moduleValue) - pathSelection(defaultField, rest) + WithGlobals(pathSelection(defaultField, rest)) case _ => - pathSelection(moduleValue, path) + WithGlobals(pathSelection(moduleValue, path)) } case irt.JSNativeLoadSpec.ImportWithGlobalFallback(importSpec, globalSpec) => diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/WithGlobals.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/WithGlobals.scala new file mode 100644 index 0000000000..40fcdf5903 --- /dev/null +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/WithGlobals.scala @@ -0,0 +1,113 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.core.tools.linker.backend.emitter + +/** A monad that associates a set of global variable names to a value. + * + * This is used to track the set of (dangerous) global variable names used in + * a tree (or a list of trees), and easily perform operations that compose + * such trees while accumulating all the mentioned global variable names. + * + * Below follows a proof that `WithGlobals` is indeed a monad. We do not + * actually use that property anywhere. The proof is there only so that I can + * call it a monad and not be attacked by an army of cats. + * + * Definition: + * {{{ + * WithGlobals.apply(a) === WithGlobals(a, ∅) + * + * WithGlobals(v, w).flatMap(f) === WithGlobals(f(v).value, w ∪ f(v).globalVarNames) + * }}} + * + * Left identity: + * {{{ + * WithGlobals.apply(a).flatMap(f) =?= f(a) + * -------------------- + * WithGlobals(a, ∅).flatMap(f) =?= f(a) + * ---------------------------- + * WithGlobals(f(a).value, ∅ ∪ f(a).globalVarNames) =?= f(a) + * ----------------------- + * WithGlobals(f(a).value, f(a).globalVarNames ) =?= f(a) + * }}} + * + * Right identity: + * {{{ + * WithGlobals(v, w).flatMap(WithGlobals.apply) =?= WithGlobals(v, w) + * -------------------------------------------- + * WithGlobals(WithGlobals.apply(v).value, w ∪ WithGlobals.apply(v).globalVarNames) =?= WithGlobals(v, w) + * -------------------------- ----------------------------------- + * WithGlobals( v , w ∪ ∅ =?= WithGlobals(v, w) + * }}} + * + * Associativity: + * {{{ + * WithGlobals(v, w).flatMap(f).flatMap(g) =?= WithGlobals(v, w).flatMap(x => f(x).flatMap(g)) + * ------------ + * WithGlobals(f(v).value, w ∪ f(v).globalVarNames).flatMap(g) =?= ... + * ----------------------------------------------------------- + * WithGlobals(g(f(v).value).value, (w ∪ f(v).globalVarNames) ∪ g(f(v).value).globalVarNames) =?= ... + * + * ... =?= WithGlobals(v, w).flatMap(x => f(x).flatMap(g)) + * ----------------------------------------------- + * ... =?= WithGlobals((x => f(x).flatMap(g))(v).value, w ∪ (x => f(x).flatMap(g))(v).globalVarNames) + * ------------------------------- ---------------------------------------- + * + * Aside: + * (x => f(x).flatMap(g))(v) + * === f(v).flatMap(g) + * === WithGlobals(g(f(v).value).value, f(v).globalVarNames ∪ g(f(v).value).globalVarNames) + * + * ... =?= WithGlobals(g(f(v).value).value, w ∪ (f(v).globalVarNames ∪ g(f(v).value).globalVarNames)) + * }}} + */ +private[emitter] final case class WithGlobals[+A]( + value: A, globalVarNames: Set[String]) { + + import WithGlobals._ + + def map[B](f: A => B): WithGlobals[B] = + WithGlobals(f(value), globalVarNames) + + def flatMap[B](f: A => WithGlobals[B]): WithGlobals[B] = { + val t = f(value) + WithGlobals(t.value, unionPreserveEmpty(globalVarNames, t.globalVarNames)) + } +} + +private[emitter] object WithGlobals { + /** Constructs a `WithGlobals` with an empty set `globalVarNames`. */ + def apply[A](value: A): WithGlobals[A] = + new WithGlobals(value, Set.empty) + + def list[A](xs: List[WithGlobals[A]]): WithGlobals[List[A]] = { + /* This could be a cascade of flatMap's, but the following should be more + * efficient. + */ + val values = xs.map(_.value) + val globalVarNames = xs.foldLeft(Set.empty[String]) { (prev, x) => + unionPreserveEmpty(prev, x.globalVarNames) + } + WithGlobals(values, globalVarNames) + } + + def option[A](xs: Option[WithGlobals[A]]): WithGlobals[Option[A]] = + xs.fold[WithGlobals[Option[A]]](WithGlobals(None))(_.map(Some(_))) + + /** Semantically equivalent to `a ++ b`, but optimized for empty sets. + * + * Using this method over `a ++ b` is meaningful is there is a strong + * likelihood that one or both parameters are empty, which is the case for + * sets of mentioned global refs. + */ + private def unionPreserveEmpty(a: Set[String], b: Set[String]): Set[String] = { + if (a.isEmpty) b + else if (b.isEmpty) a + else a ++ b + } +} From 0b776fa0037e720d89bd59c0cfa13a4f0e486a96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 12 May 2017 11:22:31 +0200 Subject: [PATCH 0312/2665] Fix #2800: Refer to the global scope instead of the global object. This is a major redesign of accesses to "global" variables, both from a spec point of view and in the implementation. Previously, Scala.js specified accesses to global variables in terms of the *global object*. It assumed that it was capable of accurately detecting the global object of any JS environment, and worked from there. For example, `js.Dynamic.global.foo` referred to `$g.foo`, where `$g` was supposed to be the global object. From a spec point of view, this was therefore different than how a typical JavaScript code would be written. Indeed, in "normal" JS we would just write `foo`, and let it be evaluated as a binding in the *global scope*. This was however fine as, in ECMAScript 5.1, the global scope and the global object were basically the same thing. However, ECMAScript 2015 changed the situation. There are now bindings in the global scope that are *not* properties of the global object. Those are `let`, `const` and `class` bindings at the top-level of scripts. This means that the previous spec of Scala.js was utterly incapable of referencing those. They were totally invisible to Scala.js. Hence, in this commit we completely change the spec of Scala.js, and consequently the implementation. Language changes ================ A reference such as `js.Dynamic.global.foo` is therefore specified as referring to the binding `foo` in the *global scope* of JS. Note that it is safer than just saying "it is equivalent to writing `foo` verbatim in JS", as the latter could collide with local bindings in the scope chain. The spec protects references to the global scope from any local definition. Objects annotated with `@JSGlobalScope` are specified similarly to `js.Dynamic.global`. Although this trivially solves the problem of accessing `let`, `const` and `class` bindings, this spec change comes with some backward source incompatible changes. Compile-time validation ----------------------- First, only static bindings (known at compile-time) to variables whose names are valid JS identifiers are allowed. For example, the following are legal: js.Dynamic.global.foo js.Dynamic.global.selectDynamic("bar") but those are illegal: js.Dynamic.global.`not-a-JS-identifier` js.Dynamic.global.selectDynamic(computedName) This restriction directly comes from the fact that only statically known bindings with valid identifier names can be looked up in the global scope, even in JavaScript. The particular identifier `arguments` is similarly forbidden, as it is a magic variable that automatically lexically binds to the most nested enclosing function. It cannot be looked up in the global scope in JavaScript either. Note that `eval` is allowed, but will systematically be protected as `(0, eval)` when it is *called*, so as to enforce that the execution of the script is done at the global level, and does not see (compiler-generated) local bindings. The second restriction is that references to the global scope, either as `js.Dynamic.global` or as `GlobalFoo` where `GlobalFoo` is annotated with `@JSGlobalScope`, cannot be loaded as a *value*. For example, the following is illegal: val x = js.Dynamic.global This follows from the previous restriction, as references to the members of such a reference would have to be looked up dynamically, and that is not possible with the global scope. More generally, it makes sense since the "global scope" is not a *value* either in JavaScript, contrary to the global object. Run-time semantic changes ------------------------- In addition to the above compile-time restrictions, the spec change incurs some differences in run-time semantics, when accessing a global variable that was not declared. For example: val x = js.Dynamic.global.doesNotExist would previously return `undefined`, but now throws a `ReferenceError`. Similarly, assignments to non-existent global variables throw a `ReferenceError`, rather than creating the variable. This run-time semantic change is the largest source of actual breakages in user code, as it invalidates the previous idiom used to perform feature detection in Scala.js. For example: if (js.isUndefined(js.Dynamic.global.Promise)) would previously return `true` when `Promise` was not declared, but will now throw a `ReferenceError`. The fix is to use `js.typeOf` instead: if (js.typeOf(js.Dynamic.global.Promise) == "undefined") This brings us to the last semantic change, which is that `js.typeOf` cannot be understood as a *method* anymore, as it does not follow the evaluation model of Scala, which guarantees that `method(expr)` is always equivalent to `{ val x = expr; method(x) }`. With `js.typeOf(expr)`, if `expr` is a reference to a non-existent global variable, `"undefined"` is returned, whereas the rewriting throws a `ReferenceError`. --- Implementation changes ====================== The above changes mostly impact the compiler and the emitter. The other steps of the pipeline are basically kept intact. The IR is augmented with an IR node `JSGlobalRef(ident)` which denotes a reference to a global variable, in the global scope. It is a valid lhs for the `Assign` node. The compiler implements the compile-time validation described above, and emits `JSGlobalRef`s instead of references to `.envInfo.global`. Other than that, nothing changes. The emitter had to be completely overhauled. The presence of `JSGlobalRef`s caused significant issues with scoping and naming. As a naive approach, the translation of `JSGlobalRef(Ident("Foo"))` is straightforwardly `js.VarRef(js.Ident("Foo"))`. However, this can cause collisions with two sources of compiler-generated identifiers: * Local bindings, such as `VarDef`s and `ParamDef`s. * Global encoding bindings, such as `$c_sci_List` or `$doubleToInt`. The first group can be dealt with locally in `JSDesugar`. If there is a reference to a `JSGlobalRef(Ident("Foo"))` in the method, then a local identifier `Foo` must be renamed. `JSDesugar` proceeds in two passes to do so, with a mechanism that stops after the first pass if possible. In the entire test-suite, the second pass is necessary for only a single method. The second group is significantly more complicated to address. If *anywhere in the program*, someone references `$c_sci_List`, then *everywhere in the program* we need to rename our internal encoding of `$c_sci_List` into something else (we use `$$c_sci_List`, adding as many `$`s as necessary to get a non-colliding name). To do so, `JSDesugar` and `ClassEmitter` keep track of all global variables that are referenced anywhere, wrapped in `WithGlobals`, a monadic data structure that eases that propagation. The `Emitter` invalidates all its caches and re-emits the entire program if the set of global variables changes in an incremental run, wrt. to the previous run. In batch-mode, there can therefore be two passes. To reduce the likelihood of this happening, we eagerly filter out non "dangerous global refs". A dangerous global ref is one that starts with a `$` (and is not the single-char string `"$"`). Indeed, only "dangerous global refs" can collide with our internal global encodings. In the test-suite, there is not a single reference to a dangerous global ref, which means that the emitter can stop after a single pass. We expect most reasonable codebases to exhibit the same property. The test for dangerous global refs is therefore put in the test-suite-ex, so that we do not unnecessarily slow down the emission of the normal test-suite. --- .../org/scalajs/core/compiler/GenJSCode.scala | 252 ++++++++++++++-- .../scalajs/core/compiler/JSDefinitions.scala | 1 + .../scalajs/core/compiler/JSPrimitives.scala | 4 +- .../scalajs/core/compiler/PrepJSInterop.scala | 47 ++- .../compiler/test/JSGlobalScopeTest.scala | 280 ++++++++++++++++++ .../core/compiler/test/JSInteropTest.scala | 84 ++++++ examples/helloworld/HelloWorld.scala | 3 +- .../scala/org/scalajs/core/ir/Hashers.scala | 4 + .../scala/org/scalajs/core/ir/Printers.scala | 20 +- .../org/scalajs/core/ir/Serializers.scala | 14 +- .../main/scala/org/scalajs/core/ir/Tags.scala | 1 + .../org/scalajs/core/ir/Transformers.scala | 2 +- .../org/scalajs/core/ir/Traversers.scala | 2 +- .../scala/org/scalajs/core/ir/Trees.scala | 48 +-- .../org/scalajs/core/ir/PrintersTest.scala | 14 +- .../src/main/scala/java/lang/System.scala | 6 +- .../concurrent/QueueExecutionContext.scala | 2 +- .../main/scala/scala/scalajs/js/Dynamic.scala | 2 +- .../scala/scala/scalajs/runtime/Bits.scala | 9 +- .../scalajs/runtime/EnvironmentInfo.scala | 6 - .../jsinterop/GlobalScopeTestEx.scala | 62 ++++ .../scalajs/testsuite/utils/Platform.scala | 16 +- .../compiler/InteroperabilityTest.scala | 74 ++++- .../testsuite/compiler/ReflectionTest.scala | 3 +- .../testsuite/javalib/lang/SystemJSTest.scala | 10 +- .../testsuite/jsinterop/AsyncTest.scala | 4 +- .../jsinterop/JSNativeInPackage.scala | 30 +- .../ModulesWithGlobalFallbackTest.scala | 9 +- .../testsuite/jsinterop/PromiseMock.scala | 6 +- .../testsuite/jsinterop/SpecialTest.scala | 4 +- .../testsuite/jsinterop/TimeoutMock.scala | 3 +- .../org/scalajs/testsuite/utils/JSUtils.scala | 14 + .../closure/ClosureLinkerBackend.scala | 7 +- tools/scalajsenv.js | 75 +++-- .../linker/backend/emitter/ClassEmitter.scala | 30 +- .../linker/backend/emitter/CoreJSLibs.scala | 5 +- .../linker/backend/emitter/Emitter.scala | 261 +++++++++++----- .../backend/emitter/FunctionEmitter.scala | 161 ++++++++-- .../backend/emitter/GlobalRefUtils.scala | 76 +++++ .../tools/linker/backend/emitter/JSGen.scala | 68 ++++- .../linker/backend/emitter/WithGlobals.scala | 14 +- .../core/tools/linker/checker/IRChecker.scala | 10 +- .../frontend/optimizer/OptimizerCore.scala | 3 +- 43 files changed, 1398 insertions(+), 348 deletions(-) create mode 100644 compiler/src/test/scala/org/scalajs/core/compiler/test/JSGlobalScopeTest.scala create mode 100644 test-suite-ex/src/test/scala/org/scalajs/testsuite/jsinterop/GlobalScopeTestEx.scala create mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalRefUtils.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 66286198e2..863a3d8d9e 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -679,8 +679,7 @@ abstract class GenJSCode extends plugins.PluginComponent case pdef: js.PropertyDef => implicit val pos = pdef.pos val name = pdef.name.asInstanceOf[js.StringLiteral] - val jsObject = - js.JSBracketSelect(genLoadGlobal(), js.StringLiteral("Object")) + val jsObject = js.JSGlobalRef(js.Ident("Object")) def field(name: String, value: js.Tree) = List(js.StringLiteral(name) -> value) @@ -769,9 +768,11 @@ abstract class GenJSCode extends plugins.PluginComponent val superClass = if (sym.isTraitOrInterface) None else Some(encodeClassFullNameIdent(sym.superClass)) - val jsNativeLoadSpec = + val jsNativeLoadSpec = { if (sym.isTraitOrInterface) None + else if (sym.hasAnnotation(JSGlobalScopeAnnotation)) None else Some(jsNativeLoadSpecOf(sym)) + } js.ClassDef(classIdent, kind, superClass, genClassInterfaces(sym), jsNativeLoadSpec, Nil)( @@ -1738,6 +1739,40 @@ abstract class GenJSCode extends plugins.PluginComponent result } + /** Gen JS code for a tree in expression position (in the IR) or the + * global scope. + */ + def genExprOrGlobalScope(tree: Tree): MaybeGlobalScope = { + implicit def pos: Position = tree.pos + + tree match { + case _: This => + val sym = tree.symbol + if (sym != currentClassSym.get && sym.isModule) + genLoadModuleOrGlobalScope(sym) + else + MaybeGlobalScope.NotGlobalScope(genExpr(tree)) + + case _:Ident | _:Select => + val sym = tree.symbol + if (sym.isModule) { + assert(!sym.isPackageClass, "Cannot use package as value: " + tree) + genLoadModuleOrGlobalScope(sym) + } else { + MaybeGlobalScope.NotGlobalScope(genExpr(tree)) + } + + case Apply(fun, _) => + if (fun.symbol == JSDynamic_global) + MaybeGlobalScope.GlobalScope(pos) + else + MaybeGlobalScope.NotGlobalScope(genExpr(tree)) + + case _ => + MaybeGlobalScope.NotGlobalScope(genExpr(tree)) + } + } + /** Gen JS code for a tree in statement or expression position (in the IR). * * This is the main transformation method. Each node of the Scala AST @@ -4060,6 +4095,7 @@ abstract class GenJSCode extends plugins.PluginComponent } else (genArgs match { case Nil => code match { + case DYNGLOBAL => reportErrorLoadGlobalScope() case LINKING_INFO => js.JSLinkingInfo() case DEBUGGER => js.Debugger() case UNITVAL => js.Undefined() @@ -4177,12 +4213,18 @@ abstract class GenJSCode extends plugins.PluginComponent * * Setters are translated to Assigns of Selects */ private def genPrimitiveJSCall(tree: Apply, isStat: Boolean): js.Tree = { - implicit val pos = tree.pos - val sym = tree.symbol val Apply(fun @ Select(receiver0, _), args0) = tree - val receiver = genExpr(receiver0) + /* In 2.10, scalac does not give a position to updateDynamic calls, and + * this causes significantly bad error messages for global scope + * selection. Therefore, we are a bit more careful here. + */ + implicit val pos = + if (tree.pos.isDefined) tree.pos + else fun.pos + + val receiver = genExprOrGlobalScope(receiver0) val args = genPrimitiveJSArgs(sym, args0) genJSCallGeneric(sym, receiver, args, isStat) @@ -4209,12 +4251,12 @@ abstract class GenJSCode extends plugins.PluginComponent // Reroute to the static method genApplyJSClassMethod(genReceiver, sym, genScalaArgs) } else { - genJSCallGeneric(sym, genReceiver, genJSArgs, isStat, - superIn = Some(currentClassSym)) + genJSCallGeneric(sym, MaybeGlobalScope.NotGlobalScope(genReceiver), + genJSArgs, isStat, superIn = Some(currentClassSym)) } } - private def genJSCallGeneric(sym: Symbol, receiver: js.Tree, + private def genJSCallGeneric(sym: Symbol, receiver: MaybeGlobalScope, args: List[js.Tree], isStat: Boolean, superIn: Option[Symbol] = None)( implicit pos: Position): js.Tree = { def noSpread = !args.exists(_.isInstanceOf[js.JSSpread]) @@ -4235,30 +4277,31 @@ abstract class GenJSCode extends plugins.PluginComponent val boxedResult = sym.name match { case JSUnaryOpMethodName(code) if argc == 0 => requireNotSuper() - js.JSUnaryOp(code, receiver) + js.JSUnaryOp(code, ruleOutGlobalScope(receiver)) case JSBinaryOpMethodName(code) if argc == 1 => requireNotSuper() - js.JSBinaryOp(code, receiver, args.head) + js.JSBinaryOp(code, ruleOutGlobalScope(receiver), args.head) case nme.apply if sym.owner.isSubClass(JSThisFunctionClass) => requireNotSuper() - js.JSBracketMethodApply(receiver, js.StringLiteral("call"), args) + genJSBracketMethodApplyOrGlobalRefApply(receiver, + js.StringLiteral("call"), args) case nme.apply if !hasExplicitJSEncoding => requireNotSuper() - js.JSFunctionApply(receiver, args) + js.JSFunctionApply(ruleOutGlobalScope(receiver), args) case _ => def jsFunName: js.Tree = genExpr(jsNameOf(sym)) def genSuperReference(propName: js.Tree): js.Tree = { superIn.fold[js.Tree] { - js.JSBracketSelect(receiver, propName) + genJSBracketSelectOrGlobalRef(receiver, propName) } { superInSym => js.JSSuperBracketSelect( jstpe.ClassType(encodeClassFullName(superInSym)), - receiver, propName) + ruleOutGlobalScope(receiver), propName) } } @@ -4270,12 +4313,12 @@ abstract class GenJSCode extends plugins.PluginComponent def genCall(methodName: js.Tree, args: List[js.Tree]): js.Tree = { superIn.fold[js.Tree] { - js.JSBracketMethodApply( + genJSBracketMethodApplyOrGlobalRefApply( receiver, methodName, args) } { superInSym => js.JSSuperBracketCall( jstpe.ClassType(encodeClassFullName(superInSym)), - receiver, methodName, args) + ruleOutGlobalScope(receiver), methodName, args) } } @@ -5217,11 +5260,12 @@ abstract class GenJSCode extends plugins.PluginComponent * Therefore, at this point, we can invoke it by loading its owner and * calling it. */ - val module = genLoadModule(sym.owner) + def moduleOrGlobalScope = genLoadModuleOrGlobalScope(sym.owner) + def module = genLoadModule(sym.owner) if (isRawJSType(sym.owner.tpe)) { if (!isScalaJSDefinedJSClass(sym.owner) || isExposed(sym)) - genJSCallGeneric(sym, module, args = Nil, isStat = false) + genJSCallGeneric(sym, moduleOrGlobalScope, args = Nil, isStat = false) else genApplyJSClassMethod(module, sym, arguments = Nil) } else { @@ -5242,10 +5286,28 @@ abstract class GenJSCode extends plugins.PluginComponent case _ => js.Null() } - /** Generate loading of a module value - * Can be given either the module symbol, or its module class symbol. + /** Generate loading of a module value. + * + * Can be given either the module symbol or its module class symbol. + * + * If the module we load refers to the global scope (i.e., it is + * annotated with `@JSGlobalScope`), report a compile error specifying + * that a global scope object should only be used as the qualifier of a + * `.`-selection. + */ + def genLoadModule(sym0: Symbol)(implicit pos: Position): js.Tree = + ruleOutGlobalScope(genLoadModuleOrGlobalScope(sym0)) + + /** Generate loading of a module value or the global scope. + * + * Can be given either the module symbol of its module class symbol. + * + * Unlike `genLoadModule`, this method does not fail if the module we load + * refers to the global scope. */ - def genLoadModule(sym0: Symbol)(implicit pos: Position): js.Tree = { + def genLoadModuleOrGlobalScope(sym0: Symbol)( + implicit pos: Position): MaybeGlobalScope = { + require(sym0.isModuleOrModuleClass, "genLoadModule called with non-module symbol: " + sym0) val sym1 = if (sym0.isModule) sym0.moduleClass else sym0 @@ -5253,18 +5315,138 @@ abstract class GenJSCode extends plugins.PluginComponent if (sym1 == StringModule) RuntimeStringModule.moduleClass else sym1 - val moduleClassName = encodeClassFullName(sym) + // Does that module refer to the global scope? + if (sym.hasAnnotation(JSGlobalScopeAnnotation)) { + MaybeGlobalScope.GlobalScope(pos) + } else { + val cls = jstpe.ClassType(encodeClassFullName(sym)) + val tree = + if (isRawJSType(sym.tpe)) js.LoadJSModule(cls) + else js.LoadModule(cls) + MaybeGlobalScope.NotGlobalScope(tree) + } + } + + private final val GenericGlobalObjectInformationMsg = { + "\n " + + "See https://www.scala-js.org/doc/interoperability/global-scope.html " + + "for further information." + } + + /** Rule out the `GlobalScope` case of a `MaybeGlobalScope` and extract the + * value tree. + * + * If `tree` represents the global scope, report a compile error. + */ + private def ruleOutGlobalScope(tree: MaybeGlobalScope): js.Tree = { + tree match { + case MaybeGlobalScope.NotGlobalScope(t) => + t + case MaybeGlobalScope.GlobalScope(pos) => + reportErrorLoadGlobalScope()(pos) + } + } + + /** Report a compile error specifying that the global scope cannot be + * loaded as a value. + */ + private def reportErrorLoadGlobalScope()(implicit pos: Position): js.Tree = { + reporter.error(pos, + "Loading the global scope as a value (anywhere but as the " + + "left-hand-side of a `.`-selection) is not allowed." + + GenericGlobalObjectInformationMsg) + js.Undefined()(pos) + } - val cls = jstpe.ClassType(moduleClassName) - if (isRawJSType(sym.tpe)) js.LoadJSModule(cls) - else js.LoadModule(cls) + /** Gen a JS bracket select or a `JSGlobalRef`. + * + * If the receiver is a normal value, i.e., not the global scope, then + * emit a `JSBracketSelect`. + * + * Otherwise, if the `item` is a constant string that is a valid + * JavaScript identifier, emit a `JSGlobalRef`. + * + * Otherwise, report a compile error. + */ + private def genJSBracketSelectOrGlobalRef(qual: MaybeGlobalScope, + item: js.Tree)(implicit pos: Position): js.Tree = { + qual match { + case MaybeGlobalScope.NotGlobalScope(qualTree) => + js.JSBracketSelect(qualTree, item) + + case MaybeGlobalScope.GlobalScope(_) => + item match { + case js.StringLiteral(value) => + if (value == "arguments") { + reporter.error(pos, + "Selecting a field of the global scope whose name is " + + "`arguments` is not allowed." + + GenericGlobalObjectInformationMsg) + js.JSGlobalRef(js.Ident("erroneous")) + } else if (js.isValidIdentifier(value)) { + js.JSGlobalRef(js.Ident(value)) + } else { + reporter.error(pos, + "Selecting a field of the global scope whose name is " + + "not a valid JavaScript identifier is not allowed." + + GenericGlobalObjectInformationMsg) + js.JSGlobalRef(js.Ident("erroneous")) + } + + case _ => + reporter.error(pos, + "Selecting a field of the global scope with a dynamic " + + "name is not allowed." + + GenericGlobalObjectInformationMsg) + js.JSGlobalRef(js.Ident("erroneous")) + } + } } - /** Gen JS code to load the global scope. */ - private def genLoadGlobal()(implicit pos: ir.Position): js.Tree = { - js.JSBracketSelect( - js.JSBracketSelect(js.JSLinkingInfo(), js.StringLiteral("envInfo")), - js.StringLiteral("global")) + /** Gen a JS bracket method apply or an apply of a `GlobalRef`. + * + * If the receiver is a normal value, i.e., not the global scope, then + * emit a `JSBracketMethodApply`. + * + * Otherwise, if the `method` is a constant string that is a valid + * JavaScript identifier, emit a `JSFunctionApply(JSGlobalRef(...), ...)`. + * + * Otherwise, report a compile error. + */ + private def genJSBracketMethodApplyOrGlobalRefApply( + receiver: MaybeGlobalScope, method: js.Tree, args: List[js.Tree])( + implicit pos: Position): js.Tree = { + receiver match { + case MaybeGlobalScope.NotGlobalScope(receiverTree) => + js.JSBracketMethodApply(receiverTree, method, args) + + case MaybeGlobalScope.GlobalScope(_) => + method match { + case js.StringLiteral(value) => + if (value == "arguments") { + reporter.error(pos, + "Calling a method of the global scope whose name is " + + "`arguments` is not allowed." + + GenericGlobalObjectInformationMsg) + js.Undefined() + } else if (js.isValidIdentifier(value)) { + js.JSFunctionApply(js.JSGlobalRef(js.Ident(value)), args) + } else { + reporter.error(pos, + "Calling a method of the global scope whose name is not " + + "a valid JavaScript identifier is not allowed." + + GenericGlobalObjectInformationMsg) + js.Undefined() + } + + case _ => + reporter.error(pos, + "Calling a method of the global scope with a dynamic " + + "name is not allowed." + + GenericGlobalObjectInformationMsg) + js.Undefined() + } + } } /** Generate access to a static member */ @@ -5438,4 +5620,12 @@ abstract class GenJSCode extends plugins.PluginComponent def isStaticModule(sym: Symbol): Boolean = sym.isModuleClass && !sym.isImplClass && !sym.isLifted + + sealed abstract class MaybeGlobalScope + + object MaybeGlobalScope { + case class NotGlobalScope(tree: js.Tree) extends MaybeGlobalScope + + case class GlobalScope(pos: Position) extends MaybeGlobalScope + } } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 3220ec0817..25ddd21792 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -80,6 +80,7 @@ trait JSDefinitions { self: JSGlobalAddons => def JSAny_fromFunction(arity: Int): TermSymbol = getMemberMethod(JSAnyModule, newTermName("fromFunction"+arity)) lazy val JSDynamicModule = JSDynamicClass.companionModule + lazy val JSDynamic_global = getMemberMethod(JSDynamicModule, newTermName("global")) lazy val JSDynamic_newInstance = getMemberMethod(JSDynamicModule, newTermName("newInstance")) lazy val JSDynamicLiteral = getMemberModule(JSDynamicModule, newTermName("literal")) lazy val JSDynamicLiteral_applyDynamicNamed = getMemberMethod(JSDynamicLiteral, newTermName("applyDynamicNamed")) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala index 7e033df05c..27ff34d455 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala @@ -32,7 +32,8 @@ abstract class JSPrimitives { val F2JS = 305 // FunctionN to js.FunctionN val F2JSTHIS = 306 // FunctionN to js.ThisFunction{N-1} - val DYNNEW = 321 // Instantiate a new JavaScript object + val DYNGLOBAL = 320 // js.Dynamic.global + val DYNNEW = 321 // Instantiate a new JavaScript object val DYNLIT = 334 // js.Dynamic.literal.applyDynamic{,Named} @@ -87,6 +88,7 @@ abstract class JSPrimitives { for (i <- 1 to 22) addPrimitive(JSThisFunction_fromFunction(i), F2JSTHIS) + addPrimitive(JSDynamic_global, DYNGLOBAL) addPrimitive(JSDynamic_newInstance, DYNNEW) addPrimitive(JSDynamicLiteral_applyDynamicNamed, DYNLIT) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 6e94a4df0f..522070502d 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -11,7 +11,7 @@ import nsc._ import scala.collection.immutable.ListMap import scala.collection.mutable -import org.scalajs.core.ir.Trees.JSNativeLoadSpec +import org.scalajs.core.ir.Trees.{isValidIdentifier, JSNativeLoadSpec} /** Prepares classes extending js.Any for JavaScript interop * @@ -565,8 +565,9 @@ abstract class PrepJSInterop extends plugins.PluginComponent * and (in 2.10) the original owner chain. We store it in a global * map. */ - val loadSpec = checkAndComputeJSNativeLoadSpecOf(implDef.pos, sym) - jsInterop.storeJSNativeLoadSpec(sym, loadSpec) + val optLoadSpec = checkAndComputeJSNativeLoadSpecOf(implDef.pos, sym) + for (loadSpec <- optLoadSpec) + jsInterop.storeJSNativeLoadSpec(sym, loadSpec) // Mark module classes as having the new format if (sym.isModuleClass) @@ -649,7 +650,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent } private def checkAndComputeJSNativeLoadSpecOf(pos: Position, - sym: Symbol): JSNativeLoadSpec = { + sym: Symbol): Option[JSNativeLoadSpec] = { import JSNativeLoadSpec._ if (enclosingOwner is OwnerKind.JSNativeMod) { @@ -674,28 +675,39 @@ abstract class PrepJSInterop extends plugins.PluginComponent } val ownerLoadSpec = jsInterop.jsNativeLoadSpecOf(sym.owner) - ownerLoadSpec match { - case Global(path) => - Global(path :+ jsName) + val loadSpec = ownerLoadSpec match { + case Global(globalRef, path) => + Global(globalRef, path :+ jsName) case Import(module, path) => Import(module, path :+ jsName) case ImportWithGlobalFallback( - Import(module, modulePath), Global(globalPath)) => + Import(module, modulePath), Global(globalRef, globalPath)) => ImportWithGlobalFallback( Import(module, modulePath :+ jsName), - Global(globalPath :+ jsName)) + Global(globalRef, globalPath :+ jsName)) } + Some(loadSpec) } else { def parsePath(pathName: String): List[String] = pathName.split('.').toList + def parseGlobalPath(pathName: String): Global = { + val globalRef :: path = parsePath(pathName) + if (!isValidIdentifier(globalRef)) { + reporter.error(pos, + "The name of a JS global variable must be a valid JS " + + s"identifier (got '$globalRef')") + } + JSNativeLoadSpec.Global(globalRef, path) + } + checkAndGetJSNativeLoadingSpecAnnotOf(pos, sym) match { case Some(annot) if annot.symbol == JSGlobalScopeAnnotation => if (!sym.isModuleClass) { reporter.error(annot.pos, "Only native JS objects can have an @JSGlobalScope annotation.") } - JSNativeLoadSpec.Global(Nil) + None case Some(annot) if annot.symbol == JSGlobalAnnotation => val pathName = annot.stringArg(0).getOrElse { @@ -711,7 +723,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent } jsInterop.defaultJSNameOf(sym) } - JSNativeLoadSpec.Global(parsePath(pathName)) + Some(parseGlobalPath(pathName)) case Some(annot) if annot.symbol == JSImportAnnotation => val module = annot.stringArg(0).getOrElse { @@ -719,16 +731,17 @@ abstract class PrepJSInterop extends plugins.PluginComponent } val path = annot.stringArg(1).fold[List[String]](Nil)(parsePath) val importSpec = Import(module, path) - annot.stringArg(2).fold[JSNativeLoadSpec] { + val loadSpec = annot.stringArg(2).fold[JSNativeLoadSpec] { importSpec } { globalPathName => - val globalSpec = Global(parsePath(globalPathName)) - ImportWithGlobalFallback(importSpec, globalSpec) + ImportWithGlobalFallback(importSpec, + parseGlobalPath(globalPathName)) } + Some(loadSpec) case None => // We already emitted an error. Just propagate something. - JSNativeLoadSpec.Global(Nil) + None } } } @@ -1302,6 +1315,10 @@ abstract class PrepJSInterop extends plugins.PluginComponent } } + /* Note that we consider @JSGlobalScope as a JS native loading spec because + * it's convenient for the purposes of PrepJSInterop. Actually @JSGlobalScope + * objects do not receive a JS loading spec in their IR. + */ private lazy val JSNativeLoadingSpecAnnots: Set[Symbol] = { Set(JSGlobalAnnotation, JSImportAnnotation, JSGlobalScopeAnnotation) } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSGlobalScopeTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSGlobalScopeTest.scala new file mode 100644 index 0000000000..2a85e36907 --- /dev/null +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSGlobalScopeTest.scala @@ -0,0 +1,280 @@ +package org.scalajs.core.compiler.test + +import org.scalajs.core.compiler.test.util._ + +import org.junit.Test +import org.junit.Ignore + +// scalastyle:off line.size.limit + +class JSGlobalScopeTest extends DirectTest with TestHelpers { + + override def preamble: String = { + """ + import scala.scalajs.js + import scala.scalajs.js.annotation._ + + object Symbols { + val sym: js.Symbol = js.Symbol() + } + + @js.native + @JSGlobalScope + object SomeGlobalScope extends js.Any { + var validVar: Int = js.native + def validDef(): Int = js.native + + var `not-a-valid-identifier-var`: Int = js.native + def `not-a-valid-identifier-def`(): Int = js.native + + def +(that: Int): Int = js.native + + @JSBracketAccess + def bracketSelect(name: String): Int = js.native + @JSBracketAccess + def bracketUpdate(name: String, v: Int): Unit = js.native + + @JSBracketCall + def bracketCall(name: String)(arg: Int): Int = js.native + + @JSName(Symbols.sym) + var symbolVar: Int = js.native + @JSName(Symbols.sym) + def symbolDef(): Int = js.native + + var arguments: js.Array[Any] = js.native + @JSName("arguments") def arguments2(x: Int): Int = js.native + } + """ + } + + @Test + def canAccessLegitMembers: Unit = { + s""" + object Main { + def main(): Unit = { + val a = js.Dynamic.global.validVar + js.Dynamic.global.validVar = 3 + val b = js.Dynamic.global.validDef() + + val c = SomeGlobalScope.validVar + SomeGlobalScope.validVar = 3 + val d = SomeGlobalScope.validDef() + + val e = SomeGlobalScope.bracketSelect("validVar") + SomeGlobalScope.bracketUpdate("validVar", 3) + val f = SomeGlobalScope.bracketCall("validDef")(4) + } + } + """.hasNoWarns + } + + @Test + def noLoadGlobalValue: Unit = { + s""" + object Main { + def main(): Unit = { + val g1 = js.Dynamic.global + val g2 = SomeGlobalScope + } + } + """ hasErrors + s""" + |newSource1.scala:39: error: Loading the global scope as a value (anywhere but as the left-hand-side of a `.`-selection) is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | val g1 = js.Dynamic.global + | ^ + |newSource1.scala:40: error: Loading the global scope as a value (anywhere but as the left-hand-side of a `.`-selection) is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | val g2 = SomeGlobalScope + | ^ + """ + } + + @Test + def rejectInvalidJSIdentifiers: Unit = { + s""" + object Main { + def main(): Unit = { + val a = js.Dynamic.global.`not-a-valid-identifier-var` + js.Dynamic.global.`not-a-valid-identifier-var` = 3 + val b = js.Dynamic.global.`not-a-valid-identifier-def`() + + val c = SomeGlobalScope.`not-a-valid-identifier-var` + SomeGlobalScope.`not-a-valid-identifier-var` = 3 + val d = SomeGlobalScope.`not-a-valid-identifier-def`() + + val e = SomeGlobalScope.bracketSelect("not-a-valid-identifier-var") + SomeGlobalScope.bracketUpdate("not-a-valid-identifier-var", 3) + val f = SomeGlobalScope.bracketCall("not-a-valid-identifier-def")(4) + } + } + """ hasErrors + s""" + |newSource1.scala:39: error: Selecting a field of the global scope whose name is not a valid JavaScript identifier is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | val a = js.Dynamic.global.`not-a-valid-identifier-var` + | ^ + |newSource1.scala:40: error: Selecting a field of the global scope whose name is not a valid JavaScript identifier is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | js.Dynamic.global.`not-a-valid-identifier-var` = 3 + | ^ + |newSource1.scala:41: error: Calling a method of the global scope whose name is not a valid JavaScript identifier is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | val b = js.Dynamic.global.`not-a-valid-identifier-def`() + | ^ + |newSource1.scala:43: error: Selecting a field of the global scope whose name is not a valid JavaScript identifier is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | val c = SomeGlobalScope.`not-a-valid-identifier-var` + | ^ + |newSource1.scala:44: error: Selecting a field of the global scope whose name is not a valid JavaScript identifier is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | SomeGlobalScope.`not-a-valid-identifier-var` = 3 + | ^ + |newSource1.scala:45: error: Calling a method of the global scope whose name is not a valid JavaScript identifier is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | val d = SomeGlobalScope.`not-a-valid-identifier-def`() + | ^ + |newSource1.scala:47: error: Selecting a field of the global scope whose name is not a valid JavaScript identifier is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | val e = SomeGlobalScope.bracketSelect("not-a-valid-identifier-var") + | ^ + |newSource1.scala:48: error: Selecting a field of the global scope whose name is not a valid JavaScript identifier is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | SomeGlobalScope.bracketUpdate("not-a-valid-identifier-var", 3) + | ^ + |newSource1.scala:49: error: Calling a method of the global scope whose name is not a valid JavaScript identifier is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | val f = SomeGlobalScope.bracketCall("not-a-valid-identifier-def")(4) + | ^ + """ + } + + @Test + def rejectJSOperators: Unit = { + s""" + object Main { + def main(): Unit = { + val a = js.Dynamic.global + 3.asInstanceOf[js.Dynamic] + + val b = SomeGlobalScope + 3 + } + } + """ hasErrors + s""" + |newSource1.scala:39: error: Loading the global scope as a value (anywhere but as the left-hand-side of a `.`-selection) is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | val a = js.Dynamic.global + 3.asInstanceOf[js.Dynamic] + | ^ + |newSource1.scala:41: error: Loading the global scope as a value (anywhere but as the left-hand-side of a `.`-selection) is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | val b = SomeGlobalScope + 3 + | ^ + """ + } + + @Test + def rejectDynamicNames: Unit = { + s""" + object Main { + def dynName: String = "foo" + + def main(): Unit = { + val a = js.Dynamic.global.selectDynamic(dynName) + js.Dynamic.global.updateDynamic(dynName)(3) + val b = js.Dynamic.global.applyDynamic(dynName)(3) + + val e = SomeGlobalScope.bracketSelect(dynName) + SomeGlobalScope.bracketUpdate(dynName, 3) + val f = SomeGlobalScope.bracketCall(dynName)(4) + + val i = SomeGlobalScope.symbolVar + SomeGlobalScope.symbolVar = 3 + val k = SomeGlobalScope.symbolDef() + } + } + """ hasErrors + s""" + |newSource1.scala:41: error: Selecting a field of the global scope with a dynamic name is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | val a = js.Dynamic.global.selectDynamic(dynName) + | ^ + |newSource1.scala:42: error: Selecting a field of the global scope with a dynamic name is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | js.Dynamic.global.updateDynamic(dynName)(3) + | ^ + |newSource1.scala:43: error: Calling a method of the global scope with a dynamic name is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | val b = js.Dynamic.global.applyDynamic(dynName)(3) + | ^ + |newSource1.scala:45: error: Selecting a field of the global scope with a dynamic name is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | val e = SomeGlobalScope.bracketSelect(dynName) + | ^ + |newSource1.scala:46: error: Selecting a field of the global scope with a dynamic name is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | SomeGlobalScope.bracketUpdate(dynName, 3) + | ^ + |newSource1.scala:47: error: Calling a method of the global scope with a dynamic name is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | val f = SomeGlobalScope.bracketCall(dynName)(4) + | ^ + |newSource1.scala:49: error: Selecting a field of the global scope with a dynamic name is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | val i = SomeGlobalScope.symbolVar + | ^ + |newSource1.scala:50: error: Selecting a field of the global scope with a dynamic name is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | SomeGlobalScope.symbolVar = 3 + | ^ + |newSource1.scala:51: error: Calling a method of the global scope with a dynamic name is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | val k = SomeGlobalScope.symbolDef() + | ^ + """ + } + + @Test + def rejectArguments: Unit = { + s""" + object Main { + def main(): Unit = { + val a = js.Dynamic.global.arguments + js.Dynamic.global.arguments = null + val b = js.Dynamic.global.arguments(5) + + val c = SomeGlobalScope.arguments + SomeGlobalScope.arguments = null + val d = SomeGlobalScope.arguments2(5) + } + } + """ hasErrors + s""" + |newSource1.scala:39: error: Selecting a field of the global scope whose name is `arguments` is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | val a = js.Dynamic.global.arguments + | ^ + |newSource1.scala:40: error: Selecting a field of the global scope whose name is `arguments` is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | js.Dynamic.global.arguments = null + | ^ + |newSource1.scala:41: error: Calling a method of the global scope whose name is `arguments` is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | val b = js.Dynamic.global.arguments(5) + | ^ + |newSource1.scala:43: error: Selecting a field of the global scope whose name is `arguments` is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | val c = SomeGlobalScope.arguments + | ^ + |newSource1.scala:44: error: Selecting a field of the global scope whose name is `arguments` is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | SomeGlobalScope.arguments = null + | ^ + |newSource1.scala:45: error: Calling a method of the global scope whose name is `arguments` is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | val d = SomeGlobalScope.arguments2(5) + | ^ + """ + } + +} diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index 8bf5023a93..e3ce1cfcf4 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -1607,6 +1607,90 @@ class JSInteropTest extends DirectTest with TestHelpers { } + @Test + def noNonJSIdentifierJSGlobal: Unit = { + + """ + @js.native + @JSGlobal + class `not-a-valid-JS-identifier` extends js.Object + + @js.native + @JSGlobal("not-a-valid-JS-identifier") + object A extends js.Object + + @js.native + @JSGlobal("not-a-valid-JS-identifier.further") + object B extends js.Object + + @js.native + @JSGlobal("TopLevel.not-a-valid-JS-identifier") // valid + object C extends js.Object + + @js.native + @JSGlobal("") + object D extends js.Object + + @js.native + @JSGlobal(".tricky") + object E extends js.Object + """ hasErrors + """ + |newSource1.scala:7: error: The name of a JS global variable must be a valid JS identifier (got 'not-a-valid-JS-identifier') + | class `not-a-valid-JS-identifier` extends js.Object + | ^ + |newSource1.scala:11: error: The name of a JS global variable must be a valid JS identifier (got 'not-a-valid-JS-identifier') + | object A extends js.Object + | ^ + |newSource1.scala:15: error: The name of a JS global variable must be a valid JS identifier (got 'not-a-valid-JS-identifier') + | object B extends js.Object + | ^ + |newSource1.scala:23: error: The name of a JS global variable must be a valid JS identifier (got '') + | object D extends js.Object + | ^ + |newSource1.scala:27: error: The name of a JS global variable must be a valid JS identifier (got '') + | object E extends js.Object + | ^ + """ + + """ + @js.native + @JSImport("foo.js", "foo", globalFallback = "not-a-valid-JS-identifier") + object A extends js.Object + + @js.native + @JSImport("foo.js", "foo", globalFallback = "not-a-valid-JS-identifier.further") + object B extends js.Object + + @js.native + @JSImport("foo.js", "foo", globalFallback = "TopLevel.not-a-valid-JS-identifier") // valid + object C extends js.Object + + @js.native + @JSImport("foo.js", "foo", globalFallback = "") + object D extends js.Object + + @js.native + @JSImport("foo.js", "foo", globalFallback = ".tricky") + object E extends js.Object + """ hasErrors + """ + |newSource1.scala:7: error: The name of a JS global variable must be a valid JS identifier (got 'not-a-valid-JS-identifier') + | object A extends js.Object + | ^ + |newSource1.scala:11: error: The name of a JS global variable must be a valid JS identifier (got 'not-a-valid-JS-identifier') + | object B extends js.Object + | ^ + |newSource1.scala:19: error: The name of a JS global variable must be a valid JS identifier (got '') + | object D extends js.Object + | ^ + |newSource1.scala:23: error: The name of a JS global variable must be a valid JS identifier (got '') + | object E extends js.Object + | ^ + """ + + } + @Test def noNonLiteralJSImport: Unit = { diff --git a/examples/helloworld/HelloWorld.scala b/examples/helloworld/HelloWorld.scala index 2fbf2c4f6f..90e5bfa11c 100644 --- a/examples/helloworld/HelloWorld.scala +++ b/examples/helloworld/HelloWorld.scala @@ -12,7 +12,8 @@ object HelloWorld extends js.JSApp { def main() { import js.DynamicImplicits.truthValue - if (js.Dynamic.global.document && + if (js.typeOf(js.Dynamic.global.document) != "undefined" && + js.Dynamic.global.document && js.Dynamic.global.document.getElementById("playground")) { sayHelloFromDOM() sayHelloFromTypedDOM() diff --git a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala index bf19a39a2b..24a104de5a 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala @@ -432,6 +432,10 @@ object Hashers { mixTag(TagThis) mixType(tree.tpe) + case JSGlobalRef(ident) => + mixTag(TagJSGlobalRef) + mixIdent(ident) + case Closure(captureParams, params, body, captureValues) => mixTag(TagClosure) mixTrees(captureParams) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index f62c7ff042..0c51b868af 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -747,6 +747,10 @@ object Printers { case This() => print("this") + case JSGlobalRef(ident) => + print("global:") + print(ident) + case Closure(captureParams, params, body, captureValues) => print("(lambda<") var first = true @@ -945,20 +949,16 @@ object Printers { private def print(spec: JSNativeLoadSpec): Unit = { def printPath(path: List[String]): Unit = { for (propName <- path) { - if (isValidIdentifier(propName)) { - print('.') - print(propName) - } else { - print('[') - print(propName) - print(']') - } + print("[\"") + printEscapeJS(propName, out) + print("\"]") } } spec match { - case JSNativeLoadSpec.Global(path) => - print("") + case JSNativeLoadSpec.Global(globalRef, path) => + print("global:") + print(globalRef) printPath(path) case JSNativeLoadSpec.Import(module, path) => diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index 7966d59634..d6ab7e38f2 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -389,6 +389,10 @@ object Serializers { writeByte(TagThis) writeType(tree.tpe) + case JSGlobalRef(ident) => + writeByte(TagJSGlobalRef) + writeIdent(ident) + case Closure(captureParams, params, body, captureValues) => writeByte(TagClosure) writeTrees(captureParams) @@ -610,6 +614,7 @@ object Serializers { import buffer._ def writeGlobalSpec(spec: JSNativeLoadSpec.Global): Unit = { + writeString(spec.globalRef) writeStrings(spec.path) } @@ -767,9 +772,10 @@ object Serializers { case TagClassOf => ClassOf(readReferenceType()) case TagUndefinedParam => UndefinedParam()(readType()) - case TagVarRef => VarRef(readIdent())(readType()) - case TagThis => This()(readType()) - case TagClosure => Closure(readParamDefs(), readParamDefs(), readTree(), readTrees()) + case TagVarRef => VarRef(readIdent())(readType()) + case TagThis => This()(readType()) + case TagJSGlobalRef => JSGlobalRef(readIdent()) + case TagClosure => Closure(readParamDefs(), readParamDefs(), readTree(), readTrees()) case TagClassDef => val name = readIdent() @@ -945,7 +951,7 @@ object Serializers { def readJSNativeLoadSpec(): Option[JSNativeLoadSpec] = { def readGlobalSpec(): JSNativeLoadSpec.Global = - JSNativeLoadSpec.Global(readStrings()) + JSNativeLoadSpec.Global(readString(), readStrings()) def readImportSpec(): JSNativeLoadSpec.Import = JSNativeLoadSpec.Import(readString(), readStrings()) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala index c130dcd2ad..f52b580db4 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala @@ -103,6 +103,7 @@ private[ir] object Tags { final val TagSelectStatic = TagTopLevelMethodExportDef + 1 final val TagTopLevelFieldExportDef = TagSelectStatic + 1 final val TagTopLevelModuleExportDef = TagTopLevelFieldExportDef + 1 + final val TagJSGlobalRef = TagTopLevelModuleExportDef + 1 // Tags for Types diff --git a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala index 50141aae07..6fb14aa6b2 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala @@ -196,7 +196,7 @@ object Transformers { case _:Skip | _:Continue | _:Debugger | _:LoadModule | _:SelectStatic | _:LoadJSConstructor | _:LoadJSModule | _:JSLinkingInfo | - _:Literal | _:UndefinedParam | _:VarRef | _:This => + _:Literal | _:UndefinedParam | _:VarRef | _:This | _:JSGlobalRef => tree case _ => diff --git a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala index dfa648ffc7..5a7d36781e 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala @@ -218,7 +218,7 @@ object Traversers { case _:Skip | _:Continue | _:Debugger | _:LoadModule | _:SelectStatic | _:LoadJSConstructor | _:LoadJSModule | _:JSLinkingInfo | _:Literal | - _:UndefinedParam | _:VarRef | _:This | _:FieldDef | + _:UndefinedParam | _:VarRef | _:This | _:JSGlobalRef | _:FieldDef | _:JSClassExportDef | _:ModuleExportDef | _:TopLevelModuleExportDef | _:TopLevelFieldExportDef => diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 6ce585883f..992ed2e58f 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -53,10 +53,12 @@ object Trees { } final def isValidIdentifier(name: String): Boolean = { - val c = name.head - (c == '$' || c == '_' || c.isUnicodeIdentifierStart) && - name.tail.forall(c => (c == '$') || c.isUnicodeIdentifierPart) && - !isKeyword(name) + name.nonEmpty && { + val c = name.head + (c == '$' || c == '_' || c.isUnicodeIdentifierStart) && + name.tail.forall(c => (c == '$') || c.isUnicodeIdentifierPart) && + !isKeyword(name) + } } @inline final def requireValidIdent(name: String): Unit = { @@ -149,8 +151,11 @@ object Trees { implicit val pos: Position) extends Tree { require(lhs match { case _:VarRef | _:Select | _:SelectStatic | _:ArraySelect | - _:JSDotSelect | _:JSBracketSelect | _:JSSuperBracketSelect => true - case _ => false + _:JSDotSelect | _:JSBracketSelect | _:JSSuperBracketSelect | + _:JSGlobalRef => + true + case _ => + false }, s"Invalid lhs for Assign: $lhs") val tpe = NoType // cannot be in expression position @@ -773,6 +778,11 @@ object Trees { case class This()(val tpe: Type)(implicit val pos: Position) extends Tree + case class JSGlobalRef(ident: Ident)( + implicit val pos: Position) extends Tree { + val tpe = AnyType + } + /** Closure with explicit captures. * The n captures map to the n first formal arguments. */ @@ -890,28 +900,26 @@ object Trees { /** Load from the global scope. * - * The `path` is a series of nested property names starting from the - * global object. + * The `globalRef` is the name of a global variable (found in the global + * scope). * - * The path can be empty, in which case this denotes the global object - * itself. + * The `path` is a series of nested property names starting from that + * variable. * - * Any element in the path is a property selection from there. A global - * scope loading spec with one path element is therefore a global variable. + * The path can be empty, in which case this denotes the specified global + * variable itself. * * Examples: * {{{ - * // - * Global(None, Nil) + * // Foo + * Global("Foo", Nil) * - * // .Date - * Global(None, List("Date")) - * - * // .cp.Vect - * Global(None, List("cp", "Vect")) + * // cp.Vect + * Global("cp", List("Vect")) * }}} */ - final case class Global(path: List[String]) extends JSNativeLoadSpec + final case class Global(globalRef: String, path: List[String]) + extends JSNativeLoadSpec /** Load from a module import. * diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala index 8834c35eac..292a8862a5 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala @@ -753,6 +753,10 @@ class PrintersTest { assertPrintEquals("this", This()(AnyType)) } + @Test def printGlobalRef(): Unit = { + assertPrintEquals("global:Foo", JSGlobalRef("Foo")) + } + @Test def printClosure(): Unit = { assertPrintEquals( """ @@ -880,16 +884,16 @@ class PrintersTest { @Test def printClassDefJSNativeLoadSpec(): Unit = { assertPrintEquals( """ - |native js class LTest extends O loadfrom .Foo { + |native js class LTest extends O loadfrom global:Foo["Bar"] { |} """, ClassDef("LTest", ClassKind.NativeJSClass, Some(ObjectClass), Nil, - Some(JSNativeLoadSpec.Global(List("Foo"))), Nil)( + Some(JSNativeLoadSpec.Global("Foo", List("Bar"))), Nil)( NoOptHints)) assertPrintEquals( """ - |native js class LTest extends O loadfrom import(foo).Bar { + |native js class LTest extends O loadfrom import(foo)["Bar"] { |} """, ClassDef("LTest", ClassKind.NativeJSClass, Some(ObjectClass), Nil, @@ -898,13 +902,13 @@ class PrintersTest { assertPrintEquals( """ - |native js class LTest extends O loadfrom import(foo).Bar fallback .Foo { + |native js class LTest extends O loadfrom import(foo)["Bar"] fallback global:Baz["Foobar"] { |} """, ClassDef("LTest", ClassKind.NativeJSClass, Some(ObjectClass), Nil, Some(JSNativeLoadSpec.ImportWithGlobalFallback( JSNativeLoadSpec.Import("foo", List("Bar")), - JSNativeLoadSpec.Global(List("Foo")))), Nil)( + JSNativeLoadSpec.Global("Baz", List("Foobar")))), Nil)( NoOptHints)) } diff --git a/javalanglib/src/main/scala/java/lang/System.scala b/javalanglib/src/main/scala/java/lang/System.scala index de07c62c68..4378b58904 100644 --- a/javalanglib/src/main/scala/java/lang/System.scala +++ b/javalanglib/src/main/scala/java/lang/System.scala @@ -31,7 +31,7 @@ object System { import js.DynamicImplicits.truthValue // We've got to use selectDynamic explicitly not to crash Scala 2.10 - if (global.selectDynamic("performance")) { + if (js.typeOf(global.selectDynamic("performance")) != "undefined") { if (global.performance.selectDynamic("now")) { () => global.performance.now().asInstanceOf[scala.Double] } else if (global.performance.selectDynamic("webkitNow")) { @@ -202,7 +202,7 @@ object System { private var lastIDHashCode: Int = 0 val idHashCodeMap = - if (assumingES6 || !js.isUndefined(global.WeakMap)) + if (assumingES6 || js.typeOf(global.WeakMap) != "undefined") js.Dynamic.newInstance(global.WeakMap)() else null @@ -360,7 +360,7 @@ private[lang] final class JSConsoleBasedPrintStream(isErr: Boolean) import js.DynamicImplicits.truthValue // We've got to use selectDynamic explicitly not to crash Scala 2.10 - if (global.selectDynamic("console")) { + if (js.typeOf(global.selectDynamic("console")) != "undefined") { if (isErr && global.console.selectDynamic("error")) global.console.error(line) else diff --git a/library/src/main/scala/scala/scalajs/concurrent/QueueExecutionContext.scala b/library/src/main/scala/scala/scalajs/concurrent/QueueExecutionContext.scala index f3ea14edc6..1c404bd8e3 100644 --- a/library/src/main/scala/scala/scalajs/concurrent/QueueExecutionContext.scala +++ b/library/src/main/scala/scala/scalajs/concurrent/QueueExecutionContext.scala @@ -13,7 +13,7 @@ object QueueExecutionContext { new PromisesExecutionContext def apply(): ExecutionContextExecutor = - if (js.isUndefined(js.Dynamic.global.Promise)) timeouts() + if (js.typeOf(js.Dynamic.global.Promise) == "undefined") timeouts() else promises() private final class TimeoutsExecutionContext extends ExecutionContextExecutor { diff --git a/library/src/main/scala/scala/scalajs/js/Dynamic.scala b/library/src/main/scala/scala/scalajs/js/Dynamic.scala index de3e9ea87a..70482545af 100644 --- a/library/src/main/scala/scala/scalajs/js/Dynamic.scala +++ b/library/src/main/scala/scala/scalajs/js/Dynamic.scala @@ -75,7 +75,7 @@ sealed trait Dynamic extends Any with scala.Dynamic { /** Factory for dynamically typed JavaScript values. */ object Dynamic { /** Dynamic view of the global scope. */ - @inline def global: Dynamic = scala.scalajs.runtime.environmentInfo.global + def global: Dynamic = sys.error("stub") /** Instantiates a new object of a JavaScript class. */ def newInstance(clazz: Dynamic)(args: Any*): Object with Dynamic = diff --git a/library/src/main/scala/scala/scalajs/runtime/Bits.scala b/library/src/main/scala/scala/scalajs/runtime/Bits.scala index a25e69c726..eb94a0763a 100644 --- a/library/src/main/scala/scala/scalajs/runtime/Bits.scala +++ b/library/src/main/scala/scala/scalajs/runtime/Bits.scala @@ -20,9 +20,12 @@ object Bits { private[this] val _areTypedArraysSupported = { // Here we use `assumingES6` to dce the 4 subsequent tests - assumingES6 || js.DynamicImplicits.truthValue( - global.ArrayBuffer && global.Int32Array && - global.Float32Array && global.Float64Array) + assumingES6 || { + js.typeOf(global.ArrayBuffer) != "undefined" && + js.typeOf(global.Int32Array) != "undefined" && + js.typeOf(global.Float32Array) != "undefined" && + js.typeOf(global.Float64Array) != "undefined" + } } @inline diff --git a/library/src/main/scala/scala/scalajs/runtime/EnvironmentInfo.scala b/library/src/main/scala/scala/scalajs/runtime/EnvironmentInfo.scala index 9786932403..d44744d4a7 100644 --- a/library/src/main/scala/scala/scalajs/runtime/EnvironmentInfo.scala +++ b/library/src/main/scala/scala/scalajs/runtime/EnvironmentInfo.scala @@ -25,12 +25,6 @@ import StackTrace.JSStackTraceElem @js.native trait EnvironmentInfo extends js.Object { - /** The global JavaScript scope (corresponds to js.Dynamic.global) - * - * @group envInfo - */ - def global: js.Dynamic = js.native - /** The scope for Scala.js exports (i.e. objects and classes) * * @group envInfo diff --git a/test-suite-ex/src/test/scala/org/scalajs/testsuite/jsinterop/GlobalScopeTestEx.scala b/test-suite-ex/src/test/scala/org/scalajs/testsuite/jsinterop/GlobalScopeTestEx.scala new file mode 100644 index 0000000000..d6601df0b5 --- /dev/null +++ b/test-suite-ex/src/test/scala/org/scalajs/testsuite/jsinterop/GlobalScopeTestEx.scala @@ -0,0 +1,62 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.jsinterop + +import org.junit.Test +import org.junit.Assert._ +import org.junit.Assume._ + +import scala.scalajs.js +import scala.scalajs.js.annotation._ + +import org.scalajs.testsuite.utils.Platform._ + +/** Additional tests for access to the global scope. + * + * If moved to testSuite, those tests will cause the test suite to be emitted + * significantly more slowly on the first pass, because a "dangerous global + * ref" is accessed. + */ +class GlobalScopeTestEx { + import GlobalScopeTestEx._ + + @Test def access_dangerous_global_ref(): Unit = { + assumeTrue("Assuming execution in Node.js", executingInNodeJS) + + nodejs_runInThisContext(""" + let $h_O = "evil global"; + """) + + assertEquals("evil global", js.Dynamic.global.$h_O) + assertEquals("evil global", GlobalScope.`$h_O`) + + js.Dynamic.global.$h_O = "more evil" + assertEquals("more evil", js.Dynamic.global.$h_O) + assertEquals("more evil", GlobalScope.`$h_O`) + + GlobalScope.`$h_O` = "yet a bit more evil" + assertEquals("yet a bit more evil", js.Dynamic.global.$h_O) + assertEquals("yet a bit more evil", GlobalScope.`$h_O`) + } + + @Test def can_still_create_an_array(): Unit = { + val a = new Array[Int](3) + a(1) = 42 + assertEquals(42, a(1)) + assertSame(classOf[Array[Int]], a.getClass) + } + +} + +object GlobalScopeTestEx { + @js.native + @JSGlobalScope + object GlobalScope extends js.Any { + var `$h_O`: String = js.native + } +} diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala index 107725442a..a93dd7e269 100644 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala +++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala @@ -31,7 +31,7 @@ object Platform { runtime.Bits.areTypedArraysSupported def areJSSymbolsSupported: Boolean = - !js.isUndefined(js.Dynamic.global.Symbol) + js.typeOf(js.Dynamic.global.Symbol) != "undefined" def executingInNodeJS: Boolean = sysProp("nodejs") def executingInNodeJSOnJSDOM: Boolean = sysProp("nodejs.jsdom") @@ -57,4 +57,18 @@ object Platform { private def sysProp(key: String): Boolean = System.getProperty("scalajs." + key, "false") == "true" + + /** Runs the specified piece of code in the global context. + * + * This only works on Node.js. It needs functionality from the `vm` module. + * + * This method can be used to declare global let/const/classes. Any other + * attempt to do so (e.g., using a `require`d source file or a `js.eval`) + * would not expose the bindings in the global scope. + */ + def nodejs_runInThisContext(code: String): Unit = { + val vm = js.Dynamic.global.require("vm") + val script = js.Dynamic.newInstance(vm.Script)(code) + script.runInThisContext() + } } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala index 5cd5ab306f..73833729b6 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala @@ -313,7 +313,7 @@ class InteroperabilityTest { """) // Use alias for convenience: see end of file for definition - val Global = InteroperabilityTestGlobalScope + import org.scalajs.testsuite.compiler.{InteroperabilityTestGlobalScope => Global} assertEquals("7357", Global.interoperabilityTestGlobalScopeValue) assertEquals(7357, Global.interoperabilityTestGlobalScopeValueAsInt) @@ -517,6 +517,60 @@ class InteroperabilityTest { obj.testAny() // should not throw } + @Test def should_access_global_scope_for_object(): Unit = { + assumeTrue("Assuming execution in Node.js", executingInNodeJS) + + nodejs_runInThisContext(""" + const InteroperabilityTestConstObject = { + x: 42 + }; + """) + + assertEquals("object", js.typeOf(InteroperabilityTestConstObject)) + assertEquals(42, InteroperabilityTestConstObject.x) + } + + @Test def should_access_global_scope_for_class(): Unit = { + assumeTrue("Assuming execution in Node.js", executingInNodeJS) + + nodejs_runInThisContext(""" + class InteroperabilityTestConstClass { + constructor(x) { + this.x = x; + } + }; + """) + + assertEquals("function", + js.typeOf(js.constructorOf[InteroperabilityTestConstClass])) + val obj = new InteroperabilityTestConstClass(5) + assertEquals(5, obj.x) + } + + @Test def should_access_global_scope_for_JSGlobalScope_members(): Unit = { + assumeTrue("Assuming execution in Node.js", executingInNodeJS) + + nodejs_runInThisContext(""" + const InteroperabilityTestLetConstGlobals_value = 456; + let InteroperabilityTestLetConstGlobals_variable = "hello"; + const InteroperabilityTestLetConstGlobals_method = (function(x) { + return x + 1; + }); + """) + + import InteroperabilityTestLetConstGlobals._ + + assertEquals("number", js.typeOf(InteroperabilityTestLetConstGlobals_value)) + assertEquals(456, InteroperabilityTestLetConstGlobals_value) + + assertEquals("string", js.typeOf(InteroperabilityTestLetConstGlobals_variable)) + assertEquals("hello", InteroperabilityTestLetConstGlobals_variable) + InteroperabilityTestLetConstGlobals_variable = "world" + assertEquals("world", InteroperabilityTestLetConstGlobals_variable) + + assertEquals(6, InteroperabilityTestLetConstGlobals_method(5)) + } + } object InteroperabilityTest { @@ -744,3 +798,21 @@ class InteroperabilityTestCtor(x: Int = 5, y: Int = ???) extends js.Object { @js.native @JSGlobal class InteroparabilityCtorInlineValue(val x: Int, var y: Int) extends js.Object + +@js.native +@JSGlobal +object InteroperabilityTestConstObject extends js.Object { + val x: Int = js.native +} + +@js.native +@JSGlobal +class InteroperabilityTestConstClass(val x: Int) extends js.Object + +@js.native +@JSGlobalScope +object InteroperabilityTestLetConstGlobals extends js.Any { + val InteroperabilityTestLetConstGlobals_value: Int = js.native + var InteroperabilityTestLetConstGlobals_variable: String = js.native + def InteroperabilityTestLetConstGlobals_method(x: Int): Int = js.native +} diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectionTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectionTest.scala index f85cbee1a2..2bc40ae5ff 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectionTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectionTest.scala @@ -69,8 +69,7 @@ class ReflectionTest { } @Test def isInstance_for_raw_JS_class(): Unit = { - js.Dynamic.global.ReflectionTestRawJSClass = - js.eval("""(function() {})""") + js.eval("""var ReflectionTestRawJSClass = (function() {})""") val obj = new ReflectionTestRawJSClass assertTrue(obj.isInstanceOf[ReflectionTestRawJSClass]) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala index 3acd3d09b0..0b610351ce 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala @@ -40,7 +40,7 @@ class SystemJSTest { } @Test def identityHashCode_for_JS_objects(): Unit = { - if (assumingES6 || !js.isUndefined(js.Dynamic.global.WeakMap)) { + if (assumingES6 || js.typeOf(js.Dynamic.global.WeakMap) != "undefined") { /* This test is more restrictive than the spec, but we know our * implementation will always pass the test. */ @@ -107,15 +107,13 @@ class SystemJSTest { val inNode = get("scalajs.nodejs") == "true" val inNodeWithJSDOM = get("scalajs.nodejs.jsdom") == "true" if (inBrowser) { - assertFalse(js.isUndefined(js.Dynamic.global.window)) + assertNotEquals("undefined", js.typeOf(js.Dynamic.global.window)) assertFalse(inNode || inNodeWithJSDOM) } else if (inNode) { - val process = js.Dynamic.global.process - assertFalse(js.isUndefined(process)) + assertNotEquals("undefined", js.typeOf(js.Dynamic.global.process)) assertFalse(inBrowser || inNodeWithJSDOM) } else if (inNodeWithJSDOM) { - val window = js.Dynamic.global.window - assertFalse(js.isUndefined(window)) + assertNotEquals("undefined", js.typeOf(js.Dynamic.global.window)) assertFalse(inBrowser || inNode) } else { fail("No known platform tag found.") diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/AsyncTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/AsyncTest.scala index ec9326a912..ab41b16286 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/AsyncTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/AsyncTest.scala @@ -78,7 +78,7 @@ class AsyncTest { @Test def scala_scalajs_concurrent_JSExecutionContext_queue(): Unit = { assumeTrue("Assumed js.Dynamic.global.Promise is undefined", - js.isUndefined(js.Dynamic.global.Promise)) + js.typeOf(js.Dynamic.global.Promise) == "undefined") TimeoutMock.withMockedTimeout { tick => queueExecOrderTests { () => tick(1) @@ -101,7 +101,7 @@ class AsyncTest { @Test def scala_scala_concurrent_ExecutionContext_global(): Unit = { assumeTrue("Assumed js.Dynamic.global.Promise is undefined", - js.isUndefined(js.Dynamic.global.Promise)) + js.typeOf(js.Dynamic.global.Promise) == "undefined") TimeoutMock.withMockedTimeout { tick => queueExecOrderTests { () => tick(1) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNativeInPackage.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNativeInPackage.scala index 6df36bfd45..9432aa0f5d 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNativeInPackage.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNativeInPackage.scala @@ -33,41 +33,35 @@ class JSNativeInPackage { import js.Dynamic.global @Test def testObjectDefaultJSGlobal(): Unit = { - val gJSNativeObjectInPackageFoo = global.JSNativeObjectInPackageFoo - assertFalse(js.isUndefined(gJSNativeObjectInPackageFoo)) - assertSame(JSNativeObjectInPackageFoo, gJSNativeObjectInPackageFoo) + assertNotEquals("undefined", js.typeOf(global.JSNativeObjectInPackageFoo)) + assertSame(JSNativeObjectInPackageFoo, global.JSNativeObjectInPackageFoo) } @Test def testObjectJSGlobal(): Unit = { - val gJSNativeObjectInPackageBar = global.JSNativeObjectInPackageBar - val gJSNativeObjectInPackageBaz = global.JSNativeObjectInPackageBaz - assertFalse(js.isUndefined(gJSNativeObjectInPackageBar)) - assertTrue(js.isUndefined(gJSNativeObjectInPackageBaz)) - assertSame(JSNativeObjectInPackageBaz, gJSNativeObjectInPackageBar) + assertNotEquals("undefined", js.typeOf(global.JSNativeObjectInPackageBar)) + assertEquals("undefined", js.typeOf(global.JSNativeObjectInPackageBaz)) + assertSame(JSNativeObjectInPackageBaz, global.JSNativeObjectInPackageBar) } @Test def testClassDefaultJSGlobal(): Unit = { - val gJSNativeClassInPackageFooCtr = global.JSNativeClassInPackageFoo - assertFalse(js.isUndefined(gJSNativeClassInPackageFooCtr)) + assertNotEquals("undefined", js.typeOf(global.JSNativeClassInPackageFoo)) assertEquals(js.constructorOf[JSNativeClassInPackageFoo], - gJSNativeClassInPackageFooCtr) + global.JSNativeClassInPackageFoo) val gJSNativeClassInPackageFoo = - js.Dynamic.newInstance(gJSNativeClassInPackageFooCtr)() + js.Dynamic.newInstance(global.JSNativeClassInPackageFoo)() assertEquals("foo", gJSNativeClassInPackageFoo.foo()) assertEquals("foo", new JSNativeClassInPackageFoo().foo()) } @Test def testClassJSGlobal(): Unit = { - val gJSNativeClassInPackageBarCtr = global.JSNativeClassInPackageBar - val gJSNativeClassInPackageBazCtr = global.JSNativeClassInPackageBaz - assertFalse(js.isUndefined(gJSNativeClassInPackageBarCtr)) + assertNotEquals("undefined", js.typeOf(global.JSNativeClassInPackageBar)) assertSame(js.constructorOf[JSNativeClassInPackageBaz], - gJSNativeClassInPackageBarCtr) - assertTrue(js.isUndefined(gJSNativeClassInPackageBazCtr)) + global.JSNativeClassInPackageBar) + assertEquals("undefined", js.typeOf(global.JSNativeClassInPackageBaz)) val gJSNativeClassInPackageBar = - js.Dynamic.newInstance(gJSNativeClassInPackageBarCtr)() + js.Dynamic.newInstance(global.JSNativeClassInPackageBar)() assertEquals("baz", gJSNativeClassInPackageBar.baz()) assertEquals("baz", new JSNativeClassInPackageBaz().baz()) } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala index a29c62479a..1f2291f03c 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala @@ -151,13 +151,14 @@ object ModulesWithGlobalFallbackTest { areTypedArraysSupported) if (isNoModule) { - js.Dynamic.global.ModulesWithGlobalFallbackTest_QueryString = + val global = org.scalajs.testsuite.utils.JSUtils.globalObject + global.ModulesWithGlobalFallbackTest_QueryString = QueryStringFallbackImpl - js.Dynamic.global.ModulesWithGlobalFallbackTest_StringDecoder = + global.ModulesWithGlobalFallbackTest_StringDecoder = js.constructorOf[StringDecoderFallbackImpl] - js.Dynamic.global.ModulesWithGlobalFallbackTest_Buffer = + global.ModulesWithGlobalFallbackTest_Buffer = js.constructorOf[Uint8Array] - js.Dynamic.global.ModulesWithGlobalFallbackTest_BufferStatic = + global.ModulesWithGlobalFallbackTest_BufferStatic = BufferStaticFallbackImpl } } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PromiseMock.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PromiseMock.scala index b431ac112c..62304bfb98 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PromiseMock.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PromiseMock.scala @@ -7,12 +7,12 @@ import scala.scalajs.js.| import js.Thenable object PromiseMock { - import js.Dynamic.global - MockPromise.initMockPromiseStaticMethods() @noinline def withMockedPromise[A](body: (() => Unit) => A): A = { + val global = org.scalajs.testsuite.utils.JSUtils.globalObject + val oldPromise = if (global.hasOwnProperty("Promise").asInstanceOf[Boolean]) Some(global.Promise) else None @@ -31,6 +31,8 @@ object PromiseMock { @noinline def withMockedPromiseIfExists[A](body: (Option[() => Unit]) => A): A = { + val global = org.scalajs.testsuite.utils.JSUtils.globalObject + val oldPromise = global.Promise if (js.isUndefined(oldPromise)) { diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala index 3d54fd159e..f4db5e3bc9 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala @@ -62,11 +62,11 @@ class SpecialTest { g.selectDynamic("global") } else { // In all other well-known environment, we can use the global `this` - js.special.globalThis + js.special.globalThis.asInstanceOf[js.Dynamic] } } - assertSame(js.Dynamic.global, globalObject) + assertSame(js.Math, globalObject.Math) } // js.special.debugger diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/TimeoutMock.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/TimeoutMock.scala index d43cf62183..0f21e0609c 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/TimeoutMock.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/TimeoutMock.scala @@ -9,7 +9,8 @@ object TimeoutMock { @noinline def withMockedTimeout[A](body: (Int => Unit) => A): A = { assert(!installed, "Mock timeout already installed.") - import js.Dynamic.global + + val global = org.scalajs.testsuite.utils.JSUtils.globalObject val realSetTimeout = global.setTimeout val realClearTimeout = global.clearTimeout diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/JSUtils.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/JSUtils.scala index 7c6f95189f..49dc072c6d 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/JSUtils.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/JSUtils.scala @@ -6,6 +6,20 @@ import scala.scalajs.js import js.annotation.JSExport object JSUtils { + /** The detected global object. */ + val globalObject: js.Dynamic = { + import js.Dynamic.{global => g} + // We've got to use selectDynamic explicitly not to crash Scala 2.10 + if (js.typeOf(g.selectDynamic("global")) != "undefined" && + (g.selectDynamic("global").selectDynamic("Object") eq g.selectDynamic("Object"))) { + // Node.js environment detected + g.selectDynamic("global") + } else { + // In all other well-known environment, we can use the global `this` + js.special.globalThis.asInstanceOf[js.Dynamic] + } + } + /* We use java.lang.Character explicitly, because this class is used by * tests that check that Chars are actually boxed by the compiler. * If we rely on the compiler doing the job in here, we might have false diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala index 4ed5fc83f3..8bc99bba9f 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala @@ -74,15 +74,14 @@ final class ClosureLinkerBackend( val builder = new ClosureAstBuilder(config.relativizeSourceMapBase) // Build Closure IR - logger.time("Emitter (create Closure trees)") { - emitter.emit(unit, builder, logger) + val coreJSLib = logger.time("Emitter (create Closure trees)") { + emitter.emitForClosure(unit, builder, logger) } // Build a Closure JSModule which includes the core libs val module = new JSModule("Scala.js") - module.add(new CompilerInput(toClosureSource( - CoreJSLibs.lib(semantics, OutputMode.ECMAScript51Isolated, moduleKind)))) + module.add(new CompilerInput(toClosureSource(coreJSLib))) val ast = builder.closureAST module.add(new CompilerInput(ast, ast.getInputId(), false)) diff --git a/tools/scalajsenv.js b/tools/scalajsenv.js index 1a59d95054..ad383255ce 100644 --- a/tools/scalajsenv.js +++ b/tools/scalajsenv.js @@ -10,25 +10,20 @@ // Get the environment info const $env = (typeof __ScalaJSEnv === "object" && __ScalaJSEnv) ? __ScalaJSEnv : {}; -// Global scope -const $g = - (typeof $env["global"] === "object" && $env["global"]) - ? $env["global"] - : ((typeof global === "object" && global && global["Object"] === Object) ? global : this); -$env["global"] = $g; - // Where to send exports //!if moduleKind == CommonJSModule const $e = exports; //!else +// TODO Do not use global object detection, and rather export with actual `var` declarations const $e = (typeof $env["exportsNamespace"] === "object" && $env["exportsNamespace"]) - ? $env["exportsNamespace"] : $g; + ? $env["exportsNamespace"] + : ((typeof global === "object" && global && global["Object"] === Object) ? global : this); //!endif $env["exportsNamespace"] = $e; // Freeze the environment info -$g["Object"]["freeze"]($env); +Object["freeze"]($env); // Linking info - must be in sync with scala.scalajs.runtime.LinkingInfo const $linkingInfo = { @@ -80,17 +75,17 @@ const $linkingInfo = { "linkerVersion": "{{LINKER_VERSION}}", "globalThis": this }; -$g["Object"]["freeze"]($linkingInfo); -$g["Object"]["freeze"]($linkingInfo["semantics"]); +Object["freeze"]($linkingInfo); +Object["freeze"]($linkingInfo["semantics"]); // Snapshots of builtins and polyfills //!if outputMode == ECMAScript6 -const $imul = $g["Math"]["imul"]; -const $fround = $g["Math"]["fround"]; -const $clz32 = $g["Math"]["clz32"]; +const $imul = Math["imul"]; +const $fround = Math["fround"]; +const $clz32 = Math["clz32"]; //!else -const $imul = $g["Math"]["imul"] || (function(a, b) { +const $imul = Math["imul"] || (function(a, b) { // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul const ah = (a >>> 16) & 0xffff; const al = a & 0xffff; @@ -101,10 +96,10 @@ const $imul = $g["Math"]["imul"] || (function(a, b) { return ((al * bl) + (((ah * bl + al * bh) << 16) >>> 0) | 0); }); -const $fround = $g["Math"]["fround"] || +const $fround = Math["fround"] || //!if floats == Strict - ($g["Float32Array"] ? (function(v) { - const array = new $g["Float32Array"](1); + (typeof Float32Array !== "undefined" ? (function(v) { + const array = new Float32Array(1); array[0] = v; return array[0]; }) : (function(v) { @@ -116,7 +111,7 @@ const $fround = $g["Math"]["fround"] || }); //!endif -const $clz32 = $g["Math"]["clz32"] || (function(i) { +const $clz32 = Math["clz32"] || (function(i) { // See Hacker's Delight, Section 5-3 if (i === 0) return 32; let r = 1; @@ -131,9 +126,9 @@ const $clz32 = $g["Math"]["clz32"] || (function(i) { // identityHashCode support let $lastIDHash = 0; // last value attributed to an id hash code //!if outputMode == ECMAScript6 -const $idHashCodeMap = new $g["WeakMap"](); +const $idHashCodeMap = new WeakMap(); //!else -const $idHashCodeMap = $g["WeakMap"] ? new $g["WeakMap"]() : null; +const $idHashCodeMap = typeof WeakMap !== "undefined" ? new WeakMap() : null; //!endif // Core mechanism @@ -209,7 +204,7 @@ function $throwArrayIndexOutOfBoundsException(i) { //!endif function $noIsInstance(instance) { - throw new $g["TypeError"]( + throw new TypeError( "Cannot call isInstance() on a Class representing a raw JS trait/object"); }; @@ -438,7 +433,7 @@ function $isNaN(instance) { }; function $isInfinite(instance) { - return !$g["isFinite"](instance) && !$isNaN(instance); + return !isFinite(instance) && !$isNaN(instance); }; function $doubleToInt(x) { @@ -448,7 +443,7 @@ function $doubleToInt(x) { /** Instantiates a JS object with variadic arguments to the constructor. */ function $newJSObjectWithVarargs(ctor, args) { // This basically emulates the ECMAScript specification for 'new'. - const instance = $g["Object"]["create"](ctor.prototype); + const instance = Object["create"](ctor.prototype); const result = ctor["apply"](instance, args); switch (typeof result) { case "string": case "number": case "boolean": case "undefined": case "symbol": @@ -459,8 +454,8 @@ function $newJSObjectWithVarargs(ctor, args) { }; function $resolveSuperRef(initialProto, propName) { - const getPrototypeOf = $g["Object"]["getPrototypeOf"]; - const getOwnPropertyDescriptor = $g["Object"]["getOwnPropertyDescriptor"]; + const getPrototypeOf = Object["getPrototypeOf"]; + const getOwnPropertyDescriptor = Object["getOwnPropertyDescriptor"]; let superProto = getPrototypeOf(initialProto); while (superProto !== null) { @@ -494,7 +489,7 @@ function $superSet(initialProto, self, propName, value) { return void 0; } } - throw new $g["TypeError"]("super has no setter '" + propName + "'."); + throw new TypeError("super has no setter '" + propName + "'."); }; //!if moduleKind == CommonJSModule @@ -559,7 +554,7 @@ const $systemIdentityHashCode = let hash = obj["$idHashCode$0"]; if (hash !== void 0) { return hash; - } else if (!$g["Object"]["isSealed"](obj)) { + } else if (!Object["isSealed"](obj)) { hash = ($lastIDHash + 1) | 0; $lastIDHash = hash; obj["$idHashCode$0"] = hash; @@ -684,36 +679,36 @@ function $uJ(value) { // TypeArray conversions -function $byteArray2TypedArray(value) { return new $g["Int8Array"](value.u); }; -function $shortArray2TypedArray(value) { return new $g["Int16Array"](value.u); }; -function $charArray2TypedArray(value) { return new $g["Uint16Array"](value.u); }; -function $intArray2TypedArray(value) { return new $g["Int32Array"](value.u); }; -function $floatArray2TypedArray(value) { return new $g["Float32Array"](value.u); }; -function $doubleArray2TypedArray(value) { return new $g["Float64Array"](value.u); }; +function $byteArray2TypedArray(value) { return new Int8Array(value.u); }; +function $shortArray2TypedArray(value) { return new Int16Array(value.u); }; +function $charArray2TypedArray(value) { return new Uint16Array(value.u); }; +function $intArray2TypedArray(value) { return new Int32Array(value.u); }; +function $floatArray2TypedArray(value) { return new Float32Array(value.u); }; +function $doubleArray2TypedArray(value) { return new Float64Array(value.u); }; function $typedArray2ByteArray(value) { const arrayClassData = $d_B.getArrayOf(); - return new arrayClassData.constr(new $g["Int8Array"](value)); + return new arrayClassData.constr(new Int8Array(value)); }; function $typedArray2ShortArray(value) { const arrayClassData = $d_S.getArrayOf(); - return new arrayClassData.constr(new $g["Int16Array"](value)); + return new arrayClassData.constr(new Int16Array(value)); }; function $typedArray2CharArray(value) { const arrayClassData = $d_C.getArrayOf(); - return new arrayClassData.constr(new $g["Uint16Array"](value)); + return new arrayClassData.constr(new Uint16Array(value)); }; function $typedArray2IntArray(value) { const arrayClassData = $d_I.getArrayOf(); - return new arrayClassData.constr(new $g["Int32Array"](value)); + return new arrayClassData.constr(new Int32Array(value)); }; function $typedArray2FloatArray(value) { const arrayClassData = $d_F.getArrayOf(); - return new arrayClassData.constr(new $g["Float32Array"](value)); + return new arrayClassData.constr(new Float32Array(value)); }; function $typedArray2DoubleArray(value) { const arrayClassData = $d_D.getArrayOf(); - return new arrayClassData.constr(new $g["Float64Array"](value)); + return new arrayClassData.constr(new Float64Array(value)); }; // TypeData class diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index e8e2b669f4..6f81b55b7d 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -93,8 +93,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { entireClassDef :: createStaticFields ::: (classValueVar := envField("c", className)) :: - genStaticInitialization(tree) :: - Nil + genStaticInitialization(tree) ) }, { js.Skip() @@ -126,7 +125,8 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { if (!tree.kind.isJSClass) { WithGlobals(encodeClassVar(parentIdent.name)) } else { - genRawJSClassConstructor(parentIdent.name) + genRawJSClassConstructor(parentIdent.name, + keepOnlyDangerousVarNames = true) } } @@ -190,7 +190,8 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val (inheritedCtorDefWithGlobals, inheritedCtorRef) = if (!isJSClass) { (WithGlobals(js.Skip()), envField("h", parentIdent.name)) } else { - val superCtor = genRawJSClassConstructor(parentIdent.name) + val superCtor = genRawJSClassConstructor(parentIdent.name, + keepOnlyDangerousVarNames = true) (superCtor.map(makeInheritableCtorDef(_)), envField("h", className)) } @@ -278,16 +279,14 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { /** Generates the creation of the static fields for a Scala class. */ def genCreateStaticFieldsOfScalaClass(tree: LinkedClass)( - implicit globalKnowledge: GlobalKnowledge): js.Tree = { - val className = tree.encodedName - val stats = for { + implicit globalKnowledge: GlobalKnowledge): List[js.Tree] = { + for { field @ FieldDef(true, Ident(name, origName), ftpe, mutable) <- tree.fields } yield { implicit val pos = field.pos - val fullName = className + "__" + name + val fullName = tree.encodedName + "__" + name envFieldDef("t", fullName, genZeroOf(ftpe), origName, mutable) } - js.Block(stats)(tree.pos) } /** Generates the creation of the static fields for a JavaScript class. */ @@ -308,14 +307,14 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { } /** Generates the static initializer invocation of a JavaScript class. */ - def genStaticInitialization(tree: LinkedClass): js.Tree = { + def genStaticInitialization(tree: LinkedClass): List[js.Tree] = { import Definitions.StaticInitializerName implicit val pos = tree.pos if (tree.staticMethods.exists(_.tree.name.encodedName == StaticInitializerName)) { val fullName = tree.encodedName + "__" + StaticInitializerName - js.Apply(envField("s", fullName, Some("")), Nil) + js.Apply(envField("s", fullName, Some("")), Nil) :: Nil } else { - js.Skip() + Nil } } @@ -791,7 +790,8 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { WithGlobals(envField("noIsInstance")) } else { for { - jsCtor <- genRawJSClassConstructor(className, tree.jsNativeLoadSpec) + jsCtor <- genRawJSClassConstructor(className, tree.jsNativeLoadSpec, + keepOnlyDangerousVarNames = true) } yield { js.Function(List(js.ParamDef(js.Ident("x"), rest = false)), js.Return { js.BinaryOp(JSBinaryOp.instanceof, js.VarRef(js.Ident("x")), jsCtor) @@ -937,7 +937,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { } def genClassExports(tree: LinkedClass)( - implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { + implicit globalKnowledge: GlobalKnowledge): WithGlobals[List[js.Tree]] = { val exportsWithGlobals = tree.classExports map { case e: ConstructorExportDef => genConstructorExportDef(tree, e) @@ -956,7 +956,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { "Illegal class export " + tree.getClass.getName) } - WithGlobals.list(exportsWithGlobals).map(js.Block(_)(tree.pos)) + WithGlobals.list(exportsWithGlobals) } def genConstructorExportDef(cd: LinkedClass, tree: ConstructorExportDef)( diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala index a2aacfb19a..59c57252c9 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala @@ -20,10 +20,7 @@ import org.scalajs.core.tools.linker.backend.{ModuleKind, OutputMode} import scala.collection.immutable.Seq import scala.collection.mutable -/* The only reason this is not private[emitter] is that Closure needs it. - * TODO We should try and get rid of this coupling. - */ -private[backend] object CoreJSLibs { +private[emitter] object CoreJSLibs { private type Config = (Semantics, OutputMode, ModuleKind) diff --git 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 index d088fdf733..34ef724bf4 100644 --- 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,6 +17,7 @@ import org.scalajs.core.ir.{ClassKind, Position} 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._ @@ -26,6 +27,8 @@ import org.scalajs.core.tools.linker._ import org.scalajs.core.tools.linker.analyzer.SymbolRequirement import org.scalajs.core.tools.linker.backend.{OutputMode, ModuleKind} +import GlobalRefUtils._ + /** Emits a desugared JS tree to a builder */ final class Emitter private (semantics: Semantics, outputMode: OutputMode, moduleKind: ModuleKind, internalOptions: InternalOptions) { @@ -43,9 +46,47 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, private val knowledgeGuardian = new KnowledgeGuardian - private val jsGen = - new JSGen(semantics, outputMode, moduleKind, internalOptions) - private val classEmitter = new ClassEmitter(jsGen) + private val baseCoreJSLib = CoreJSLibs.lib(semantics, outputMode, moduleKind) + + private class State(val lastMentionedDangerousGlobalRefs: Set[String]) { + val jsGen: JSGen = { + new JSGen(semantics, outputMode, moduleKind, internalOptions, + lastMentionedDangerousGlobalRefs) + } + + val classEmitter: ClassEmitter = new ClassEmitter(jsGen) + + val coreJSLib: VirtualJSFile = { + if (lastMentionedDangerousGlobalRefs.isEmpty) { + baseCoreJSLib + } else { + var content = { + val reader = baseCoreJSLib.reader + try IO.readReaderToString(reader) + finally reader.close() + } + + for { + globalRef <- lastMentionedDangerousGlobalRefs + if !globalRef.startsWith("$$") + } { + val replacement = jsGen.avoidClashWithGlobalRef(globalRef) + content = content.replaceAll(raw"\$globalRef\b", + java.util.regex.Matcher.quoteReplacement(replacement)) + } + + val result = new MemVirtualJSFile(baseCoreJSLib.path) + result.content = content + result + } + } + } + + private var state: State = new State(Set.empty) + + private def jsGen: JSGen = state.jsGen + private def classEmitter: ClassEmitter = state.classEmitter + private def coreJSLib: VirtualJSFile = state.coreJSLib private val classCaches = mutable.Map.empty[List[String], ClassCache] @@ -73,26 +114,43 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, def emitAll(unit: LinkingUnit, builder: JSFileBuilder, logger: Logger): Unit = { - emitPrelude(builder, logger) - emit(unit, builder, logger) - emitPostlude(builder, logger) + emitInternal(unit, builder, logger) { + if (needsIIFEWrapper) + builder.addLine("(function(){") + + builder.addLine("'use strict';") + builder.addFile(coreJSLib) + } { + if (needsIIFEWrapper) + builder.addLine("}).call(this);") + } } def emitCustomHeader(customHeader: String, builder: JSFileBuilder): Unit = emitLines(customHeader, builder) - def emitPrelude(builder: JSFileBuilder, logger: Logger): Unit = { - if (needsIIFEWrapper) - builder.addLine("(function(){") - - builder.addLine("'use strict';") - builder.addFile(CoreJSLibs.lib(semantics, outputMode, moduleKind)) + /** Emits everything but the core JS lib to the builder, and returns the + * core JS lib. + * + * This is special for the Closure back-end. + */ + private[backend] def emitForClosure(unit: LinkingUnit, builder: JSTreeBuilder, + logger: Logger): VirtualJSFile = { + emitInternal(unit, builder, logger)(())(()) + coreJSLib } - def emit(unit: LinkingUnit, builder: JSTreeBuilder, logger: Logger): Unit = { + private def emitInternal(unit: LinkingUnit, builder: JSTreeBuilder, + logger: Logger)( + emitPrelude: => Unit)( + emitPostlude: => Unit): Unit = { startRun(unit) try { val orderedClasses = unit.classDefs.sortWith(compareClasses) + val generatedClasses = + genAllClasses(orderedClasses, logger, secondAttempt = false) + + emitPrelude emitModuleImports(orderedClasses, builder, logger) @@ -110,22 +168,27 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, * observe a non-initialized state of other static fields. */ - for (linkedClass <- orderedClasses) - emitLinkedClass(linkedClass, builder) + def emitJSTrees(trees: List[js.Tree]): Unit = + trees.foreach(builder.addJSTree(_)) + + for (generatedClass <- generatedClasses) + emitJSTrees(generatedClass.main) - for (linkedClass <- orderedClasses) - emitLinkedClassStaticFields(linkedClass, builder) + for (generatedClass <- generatedClasses) + emitJSTrees(generatedClass.staticFields) - for (linkedClass <- orderedClasses) - emitLinkedClassStaticInitializer(linkedClass, builder) + for (generatedClass <- generatedClasses) + emitJSTrees(generatedClass.staticInitialization) - for (linkedClass <- orderedClasses) - emitLinkedClassClassExports(linkedClass, builder) + for (generatedClass <- generatedClasses) + emitJSTrees(generatedClass.classExports) // Emit the module initializers for (moduleInitializer <- unit.moduleInitializers) emitModuleInitializer(moduleInitializer, builder) + + emitPostlude } finally { endRun(logger) } @@ -175,7 +238,7 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, classDef.jsNativeLoadSpec match { case None => - case Some(JSNativeLoadSpec.Global(_)) => + case Some(JSNativeLoadSpec.Global(_, _)) => case Some(JSNativeLoadSpec.Import(module, _)) => addModuleRef(module) @@ -188,11 +251,6 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, } } - def emitPostlude(builder: JSFileBuilder, logger: Logger): Unit = { - if (needsIIFEWrapper) - builder.addLine("}).call(this);") - } - def emitCustomFooter(customFooter: String, builder: JSFileBuilder): Unit = emitLines(customFooter, builder) @@ -226,29 +284,73 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, classCaches.retain((_, c) => c.cleanAfterRun()) } - private def emitLinkedClass( - linkedClass: LinkedClass, builder: JSTreeBuilder): Unit = { + /** Generates all the desugared classes. + * + * If, at the end of the process, the set of accessed dangerous globals has + * changed, invalidate *everything* and start over. If at first you don't + * succeed, ... + */ + @tailrec + private def genAllClasses(orderedClasses: List[LinkedClass], logger: Logger, + secondAttempt: Boolean): List[GeneratedClass] = { + val generatedClasses = orderedClasses.map(genClass) + val mentionedDangerousGlobalRefs = generatedClasses.foldLeft(Set.empty[String]) { + (prev, generatedClass) => + unionPreserveEmpty(prev, generatedClass.mentionedDangerousGlobalRefs) + } + + if (mentionedDangerousGlobalRefs == state.lastMentionedDangerousGlobalRefs) { + generatedClasses + } else { + assert(!secondAttempt, + "Uh oh! The second attempt gave a different set of dangerous " + + "global refs than the first one.") - def addTreeBase(tree: js.Tree): Unit = builder.addJSTree(tree) + logger.debug( + "Emitter: The set of dangerous global refs has changed. " + + "Going to re-generate the world.") - def addTree(treeWithGlobals: WithGlobals[js.Tree]): Unit = { - // Disregard treeWithGlobals.globalVarNames for now - addTreeBase(treeWithGlobals.value) + state = new State(mentionedDangerousGlobalRefs) + classCaches.clear() + genAllClasses(orderedClasses, logger, secondAttempt = true) } + } + private def genClass(linkedClass: LinkedClass): GeneratedClass = { val className = linkedClass.encodedName val classCache = getClassCache(linkedClass.ancestors) val classTreeCache = classCache.getCache(linkedClass.version) val kind = linkedClass.kind - // Statics + // Global ref management + + var mentionedDangerousGlobalRefs: Set[String] = Set.empty + + def addGlobalRefs(globalRefs: Set[String]): Unit = { + mentionedDangerousGlobalRefs = + unionPreserveEmpty(globalRefs, mentionedDangerousGlobalRefs) + } + + // Main part + + var main: List[js.Tree] = Nil + + def addToMainBase(tree: js.Tree): Unit = main ::= tree + + def addToMain(treeWithGlobals: WithGlobals[js.Tree]): Unit = { + addToMainBase(treeWithGlobals.value) + addGlobalRefs(treeWithGlobals.globalVarNames) + } + + // Static methods for (m <- linkedClass.staticMethods) { val methodCache = classCache.getStaticCache(m.info.encodedName) - addTree(methodCache.getOrElseUpdate(m.version, + addToMain(methodCache.getOrElseUpdate(m.version, classEmitter.genMethod(className, m.tree)(methodCache))) } + // Class definition if (linkedClass.hasInstances && kind.isAnyScalaJSDefinedClass) { val ctor = classTreeCache.constructor.getOrElseUpdate( classEmitter.genConstructor(linkedClass)(classCache)) @@ -265,82 +367,77 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, val exportedMembers = classTreeCache.exportedMembers.getOrElseUpdate( classEmitter.genExportedMembers(linkedClass)(classCache)) - addTree(classEmitter.buildClass(linkedClass, ctor, memberMethods, + addToMain(classEmitter.buildClass(linkedClass, ctor, memberMethods, exportedMembers)(classCache)) } else if (kind == ClassKind.Interface) { // Default methods for (m <- linkedClass.memberMethods) yield { val methodCache = classCache.getMethodCache(m.info.encodedName) - addTree(methodCache.getOrElseUpdate(m.version, + addToMain(methodCache.getOrElseUpdate(m.version, classEmitter.genDefaultMethod(className, m.tree)(methodCache))) } } if (classEmitter.needInstanceTests(linkedClass)) { - addTreeBase(classTreeCache.instanceTests.getOrElseUpdate(js.Block( + addToMainBase(classTreeCache.instanceTests.getOrElseUpdate(js.Block( classEmitter.genInstanceTests(linkedClass), classEmitter.genArrayInstanceTests(linkedClass) )(linkedClass.pos))) } if (linkedClass.hasRuntimeTypeInfo) { - addTree(classTreeCache.typeData.getOrElseUpdate( + addToMain(classTreeCache.typeData.getOrElseUpdate( classEmitter.genTypeData(linkedClass)(classCache))) } if (linkedClass.hasInstances && kind.isClass && linkedClass.hasRuntimeTypeInfo) - addTreeBase(classTreeCache.setTypeData.getOrElseUpdate( + addToMainBase(classTreeCache.setTypeData.getOrElseUpdate( classEmitter.genSetTypeData(linkedClass))) if (linkedClass.kind.hasModuleAccessor) - addTreeBase(classTreeCache.moduleAccessor.getOrElseUpdate( + addToMainBase(classTreeCache.moduleAccessor.getOrElseUpdate( classEmitter.genModuleAccessor(linkedClass))) - } - /** Emits the static fields of a linked class. - * - * They are initialized with the zero of their type at this point. It is - * the job of static initializers to properly initialize them. - */ - private def emitLinkedClassStaticFields(linkedClass: LinkedClass, - builder: JSTreeBuilder): Unit = { + // Static fields - if (!linkedClass.kind.isJSType) { + val staticFields = if (linkedClass.kind.isJSType) { + Nil + } else { val classCache = getClassCache(linkedClass.ancestors) val classTreeCache = classCache.getCache(linkedClass.version) - builder.addJSTree(classTreeCache.staticFields.getOrElseUpdate( - classEmitter.genCreateStaticFieldsOfScalaClass(linkedClass)(classCache))) + classTreeCache.staticFields.getOrElseUpdate( + classEmitter.genCreateStaticFieldsOfScalaClass(linkedClass)(classCache)) } - } - - /** Emits the static initializer of a linked class, if any. */ - private def emitLinkedClassStaticInitializer(linkedClass: LinkedClass, - builder: JSTreeBuilder): Unit = { - if (!linkedClass.kind.isJSType) - builder.addJSTree(classEmitter.genStaticInitialization(linkedClass)) - } + // Static initialization - /** Emits the class exports of a linked class. - * - * This is done after everything else has been emitted for all the classes - * in the program. That is necessary because class exports can call class - * value accessors, which may have unknown circular references. - */ - private def emitLinkedClassClassExports(linkedClass: LinkedClass, - builder: JSTreeBuilder): Unit = { + val staticInitialization = if (linkedClass.kind.isJSType) { + Nil + } else { + classEmitter.genStaticInitialization(linkedClass) + } - /* `if` to avoid looking up the caches for nothing. Probably worth doing - * because only few classes have class exports. - */ - if (linkedClass.classExports.nonEmpty) { - val classCache = getClassCache(linkedClass.ancestors) - val classTreeCache = classCache.getCache(linkedClass.version) + // Class exports - builder.addJSTree(classTreeCache.classExports.getOrElseUpdate( - classEmitter.genClassExports(linkedClass)(classCache)).value) + val classExports = if (linkedClass.classExports.isEmpty) { + Nil + } else { + val treeWithGlobals = classTreeCache.classExports.getOrElseUpdate( + classEmitter.genClassExports(linkedClass)(classCache)) + addGlobalRefs(treeWithGlobals.globalVarNames) + treeWithGlobals.value } + + // Build the result + + new GeneratedClass( + main.reverse, + staticFields, + staticInitialization, + classExports, + mentionedDangerousGlobalRefs + ) } /** Emits an [[EntryPoint]]. @@ -473,10 +570,18 @@ private object Emitter { val typeData = new OneTimeCache[WithGlobals[js.Tree]] val setTypeData = new OneTimeCache[js.Tree] val moduleAccessor = new OneTimeCache[js.Tree] - val staticFields = new OneTimeCache[js.Tree] - val classExports = new OneTimeCache[WithGlobals[js.Tree]] + val staticFields = new OneTimeCache[List[js.Tree]] + val classExports = new OneTimeCache[WithGlobals[List[js.Tree]]] } + private final class GeneratedClass( + val main: List[js.Tree], + val staticFields: List[js.Tree], + val staticInitialization: List[js.Tree], + val classExports: List[js.Tree], + val mentionedDangerousGlobalRefs: Set[String] + ) + private final class OneTimeCache[A >: Null] { private[this] var value: A = null def getOrElseUpdate(v: => A): A = { diff --git 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 index 956a361754..7cd8e3c2cf 100644 --- 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 @@ -228,16 +228,74 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { private class JSDesugar()(implicit globalKnowledge: GlobalKnowledge) { + // Name management + + /** Whether we are running in the "optimistic naming" run. + * + * In theory, `JSDesugar` works in two passes: the optimistic run, + * followed by the pessimistic run should the first one fail. + * + * The optimistic run assumes that there is no clash between a local + * variable name and a global variable name (i.e., a `JSGlobalRef`). This + * allows it to straightforwardly translate IR identifiers to JS + * identifiers. While it does that, it records all the local variable and + * global variable names that are used in the method. + * + * At the end of the translation, we check whether there was a clash by + * testing if the two sets intersect. If they do not, we are lucky, and + * can completely by-pass the pessimistic run. If there is a clash, then + * we need to restart everything in pessimistic mode. + * + * In the pessimistic run, we use the set of global variable names that + * was collected during the optimistic run to *prevent* clashes from + * happening. This requires that we maintain a map of IR identifiers to + * allocated JS identifiers, as some IR identifiers need to be renamed. + */ + private var isOptimisticNamingRun: Boolean = true + + private val globalVarNames = mutable.Set.empty[String] + private val localVarNames = mutable.Set.empty[String] + + private lazy val localVarAllocs = mutable.Map.empty[String, String] + + private def referenceGlobalName(name: String): Unit = + globalVarNames += name + private def extractWithGlobals[A](withGlobals: WithGlobals[A]): A = { - // Disregard withGlobals.globalVarNames for now + for (globalRef <- withGlobals.globalVarNames) + referenceGlobalName(globalRef) withGlobals.value } - // Synthetic variables + private def transformLocalName(name: String): String = { + if (isOptimisticNamingRun) { + localVarNames += name + name + } else { + // Slow path in a different `def` to keep it out of the JIT's way + def slowPath(): String = { + localVarAllocs.getOrElseUpdate(name, { + var suffix = 0 + var result = name + while (globalVarNames.contains(result) || + localVarNames.contains(result)) { + suffix += 1 + result = name + "$" + suffix + } + localVarNames += result + result + }) + } + slowPath() + } + } var syntheticVarCounter: Int = 0 def newSyntheticVar()(implicit pos: Position): Ident = { + /* TODO Integrate this with proper name management. + * This is filed as #2971. + */ syntheticVarCounter += 1 Ident("jsx$" + syntheticVarCounter, None) } @@ -249,6 +307,31 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { finally syntheticVarCounter = savedCounter } + @inline + @tailrec + private def performOptimisticThenPessimisticRuns[A]( + body: => A): WithGlobals[A] = { + val result = body + if (!isOptimisticNamingRun || !globalVarNames.exists(localVarNames)) { + /* Filter out non-dangerous global refs at this point. Outside of the + * function being desugared, only dangerous global refs still need to + * be tracked. Hopefully, the set is already emptied at this point for + * the large majority of methods, if not all. + */ + WithGlobals(result, + GlobalRefUtils.keepOnlyDangerousGlobalRefs(globalVarNames.toSet)) + } else { + /* Clear the local var names, but *not* the global var names. + * In the pessimistic run, we will use the knowledge gathered during + * the optimistic run about the set of global variable names that are + * used. + */ + localVarNames.clear() + isOptimisticNamingRun = false + performOptimisticThenPessimisticRuns(body) + } + } + // Record names def makeRecordFieldIdent(recIdent: Ident, fieldIdent: Ident)( @@ -284,17 +367,18 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { params: List[ParamDef], body: Tree, isStat: Boolean, env0: Env)( implicit pos: Position): WithGlobals[js.Function] = { - /* TODO The identifier `$thiz` cannot be produced by 0.6.x compilers due - * to their name mangling, which guarantees that it is unique. We should - * find a better way to do this in the future, though. - */ - val thisIdent = js.Ident("$thiz", Some("this")) - val env = env0.withThisIdent(Some(thisIdent)) - val js.Function(jsParams, jsBody) = - desugarToFunctionInternal(params, body, isStat, env) - val result = + performOptimisticThenPessimisticRuns { + /* TODO The identifier `$thiz` cannot be produced by 0.6.x compilers due + * to their name mangling, which guarantees that it is unique. We should + * find a better way to do this in the future, though. + * This is filed as #2972. + */ + val thisIdent = js.Ident("$thiz", Some("this")) + val env = env0.withThisIdent(Some(thisIdent)) + val js.Function(jsParams, jsBody) = + desugarToFunctionInternal(params, body, isStat, env) js.Function(js.ParamDef(thisIdent, rest = false) :: jsParams, jsBody) - WithGlobals(result) + } } /** Desugars parameters and body to a JS function. @@ -302,9 +386,9 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { def desugarToFunction( params: List[ParamDef], body: Tree, isStat: Boolean, env0: Env)( implicit pos: Position): WithGlobals[js.Function] = { - val result = + performOptimisticThenPessimisticRuns { desugarToFunctionInternal(params, body, isStat, env0) - WithGlobals(result) + } } /** Desugars parameters and body to a JS function. @@ -462,7 +546,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { transformExpr(rhs)) } - case Assign(lhs @ (_:VarRef | _:SelectStatic), rhs) => + case Assign(lhs @ (_:VarRef | _:SelectStatic | _:JSGlobalRef), rhs) => pushLhsInto(Lhs.Assign(lhs), rhs, tailPosLabels) case Assign(_, _) => @@ -608,10 +692,10 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { def makeObjectMethodApply(methodName: String, args: List[js.Tree]): js.Tree = { + referenceGlobalName("Object") js.Apply( - genIdentBracketSelect(genIdentBracketSelect( - envField("g"), - "Object"), + genIdentBracketSelect( + js.VarRef(js.Ident("Object", Some("Object"))), methodName), args) } @@ -1078,6 +1162,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { allowSideEffects && test(qualifier) && test(item) case LoadJSModule(_) => allowSideEffects + case JSGlobalRef(_) => + allowSideEffects /* LoadJSConstructor is pure only for Scala.js-defined JS classes, * which do not have a native load spec. Note that this test makes @@ -2025,18 +2111,6 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { // JavaScript expressions - case JSBracketSelect( - JSBracketSelect(JSLinkingInfo(), StringLiteral("envInfo")), - StringLiteral("global")) => - // Shortcut for this field which is heavily used - envField("g") - - case JSBracketSelect(JSLinkingInfo(), StringLiteral("envInfo")) => - /* environmentInfo is not used that often, but it makes sense to - * short-cut it too anyway. - */ - envField("env") - case JSNew(constr, args) => js.New(transformExpr(constr), args map transformExpr) @@ -2056,10 +2130,15 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { * If we emit the latter, then `this` will be bound to `path` in * `f`, which is sometimes extremely harmful (e.g., for builtin * methods of `window`). + * + * A bare identifier `eval` also need to be protected in the same + * way, because calling a bare `eval` executes the code in the + * current lexical scope, as opposed to the global scope. */ val transformedFun = transformExpr(fun) val protectedFun = transformedFun match { - case _:js.DotSelect | _:js.BracketSelect => + case _:js.DotSelect | _:js.BracketSelect | + js.VarRef(js.Ident("eval", _)) => js.Block(js.IntLiteral(0), transformedFun) case _ => transformedFun @@ -2091,7 +2170,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { genLoadModule(className) case Some(spec) => - extractWithGlobals(genLoadJSFromSpec(spec)) + extractWithGlobals( + genLoadJSFromSpec(spec, keepOnlyDangerousVarNames = false)) } case JSSpread(items) => @@ -2154,6 +2234,9 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { js.VarRef(ident) } + case JSGlobalRef(name) => + js.VarRef(transformGlobalVarIdent(name)) + case Closure(captureParams, params, body, captureValues) => val innerFunction = desugarToFunctionInternal(params, body, isStat = false, @@ -2248,7 +2331,12 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { 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 { @@ -2261,6 +2349,15 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { } } + /* 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/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalRefUtils.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalRefUtils.scala new file mode 100644 index 0000000000..51254164f9 --- /dev/null +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalRefUtils.scala @@ -0,0 +1,76 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.core.tools.linker.backend.emitter + +import org.scalajs.core.tools.linker.backend.OutputMode + +/** Utilities related to global refs mentioned in the program. + * + * When a global ref is mentioned somewhere in the program, bad things happen. + * + * On the one hand, in the local method where it is mentioned, no local + * variable can use the same name, as it would shadow the reference to the + * global variable. That is however a local property, and is handled by the + * name management of [[FunctionEmitter]]. + * + * On the other hand, there are so-called "dangerous" global refs, which are + * global refs that could collide with the emitter's own internal encoding, + * such as `$doubleToInt` or `$c_O`. When a dangerous global ref is mentioned + * somewhere in the program, the *entire* emitted program is affected, because + * the internal name must be changed. + * + * Dangerous global refs are those that start with `$`, with the exception of + * the string `"$"` itself (because jQuery ...). + * + * Hopefully, in a reasonable program, there is actually no dangerous global + * ref mentioned anywhere, and the [[Emitter]] can do its job in one pass. + * That is why we eagerly filter out non-dangerous global refs in individual + * caches, and why we have most paths optimized for empty sets. + */ +private[emitter] object GlobalRefUtils { + /** Semantically equivalent to `a ++ b`, but optimized for empty sets. + * + * Using this method over `a ++ b` is meaningful is there is a strong + * likelihood that one or both parameters are empty, which is the case for + * sets of mentioned global refs. + */ + def unionPreserveEmpty(a: Set[String], b: Set[String]): Set[String] = { + if (a.isEmpty) b + else if (b.isEmpty) a + else a ++ b + } + + /** Tests whether a global ref is dangerous. */ + def isDangerousGlobalRef(globalRef: String): Boolean = { + // Note that this intentionally filters out `$` itself + globalRef.length > 1 && globalRef.charAt(0) == '$' + } + + /** Filters a set to keep only the dangerous global refs. */ + def keepOnlyDangerousGlobalRefs(allGlobalRefs: Set[String]): Set[String] = { + if (allGlobalRefs.isEmpty) { + // Fast path, make sure to return a Set.EmptySet + Set.empty + } else { + // Slow path in a different `def` to keep it out of the JIT's way + def slowPath(): Set[String] = { + val r = allGlobalRefs.filter(isDangerousGlobalRef(_)) + /* In the likely empty case, make sure to return a Set.EmptySet, + * whose `contains()` method is super efficient and can potentially + * be JIT'ed away. + */ + if (r.isEmpty) + Set.empty + else + r + } + slowPath() + } + } +} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala index f09b04c2a8..40c9e4c5a0 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala @@ -11,6 +11,8 @@ package org.scalajs.core.tools.linker.backend.emitter import scala.language.implicitConversions +import scala.annotation.tailrec + import org.scalajs.core.ir import ir._ import ir.Types._ @@ -27,7 +29,9 @@ import org.scalajs.core.tools.javascript.Trees._ */ private[emitter] final class JSGen(val semantics: Semantics, val outputMode: OutputMode, val moduleKind: ModuleKind, - internalOptions: InternalOptions) { + internalOptions: InternalOptions, + mentionedDangerousGlobalRefs: Set[String]) { + import JSGen._ def genZeroOf(tpe: Type)(implicit pos: Position): Tree = { @@ -146,16 +150,19 @@ private[emitter] final class JSGen(val semantics: Semantics, Apply(envField("m", moduleClass), Nil) } - def genRawJSClassConstructor(className: String)( + def genRawJSClassConstructor(className: String, + keepOnlyDangerousVarNames: Boolean)( implicit globalKnowledge: GlobalKnowledge, pos: Position): WithGlobals[Tree] = { genRawJSClassConstructor(className, - globalKnowledge.getJSNativeLoadSpec(className)) + globalKnowledge.getJSNativeLoadSpec(className), + keepOnlyDangerousVarNames) } def genRawJSClassConstructor(className: String, - spec: Option[irt.JSNativeLoadSpec])( + spec: Option[irt.JSNativeLoadSpec], + keepOnlyDangerousVarNames: Boolean)( implicit pos: Position): WithGlobals[Tree] = { spec match { case None => @@ -163,7 +170,7 @@ private[emitter] final class JSGen(val semantics: Semantics, WithGlobals(genNonNativeJSClassConstructor(className)) case Some(spec) => - genLoadJSFromSpec(spec) + genLoadJSFromSpec(spec, keepOnlyDangerousVarNames) } } @@ -172,7 +179,8 @@ private[emitter] final class JSGen(val semantics: Semantics, Apply(envField("a", className), Nil) } - def genLoadJSFromSpec(spec: irt.JSNativeLoadSpec)( + def genLoadJSFromSpec(spec: irt.JSNativeLoadSpec, + keepOnlyDangerousVarNames: Boolean)( implicit pos: Position): WithGlobals[Tree] = { def pathSelection(from: Tree, path: List[String]): Tree = { @@ -182,8 +190,15 @@ private[emitter] final class JSGen(val semantics: Semantics, } spec match { - case irt.JSNativeLoadSpec.Global(path) => - WithGlobals(pathSelection(envField("g"), path)) + case irt.JSNativeLoadSpec.Global(globalRef, path) => + val globalVarRef = VarRef(Ident(globalRef, Some(globalRef))) + val globalVarNames = { + if (keepOnlyDangerousVarNames && !GlobalRefUtils.isDangerousGlobalRef(globalRef)) + Set.empty[String] + else + Set(globalRef) + } + WithGlobals(pathSelection(globalVarRef, path), globalVarNames) case irt.JSNativeLoadSpec.Import(module, path) => val moduleValue = envModuleField(module) @@ -198,9 +213,9 @@ private[emitter] final class JSGen(val semantics: Semantics, case irt.JSNativeLoadSpec.ImportWithGlobalFallback(importSpec, globalSpec) => moduleKind match { case ModuleKind.NoModule => - genLoadJSFromSpec(globalSpec) + genLoadJSFromSpec(globalSpec, keepOnlyDangerousVarNames) case ModuleKind.CommonJSModule => - genLoadJSFromSpec(importSpec) + genLoadJSFromSpec(importSpec, keepOnlyDangerousVarNames) } } } @@ -243,16 +258,43 @@ private[emitter] final class JSGen(val semantics: Semantics, if (containsOnlyValidChars()) "$i_" + module else buildValidName() - VarRef(Ident(varName, Some(module))) + VarRef(Ident(avoidClashWithGlobalRef(varName), Some(module))) } def envField(field: String, subField: String, origName: Option[String] = None)( implicit pos: Position): VarRef = { - VarRef(Ident("$" + field + "_" + subField, origName)) + VarRef(Ident(avoidClashWithGlobalRef("$" + field + "_" + subField), + origName)) } def envField(field: String)(implicit pos: Position): VarRef = - VarRef(Ident("$" + field)) + VarRef(Ident(avoidClashWithGlobalRef("$" + field))) + + def avoidClashWithGlobalRef(envFieldName: String): String = { + /* This is not cached because it should virtually never happen. + * slowPath() is only called if we use a dangerous global ref, which should + * already be very rare. And if do a second iteration in the loop only if + * we refer to the global variables `$foo` *and* `$$foo`. At this point the + * likelihood is so close to 0 that caching would be more expensive than + * not caching. + */ + @tailrec + def slowPath(lastNameTried: String): String = { + val nextNameToTry = "$" + lastNameTried + if (mentionedDangerousGlobalRefs.contains(nextNameToTry)) + slowPath(nextNameToTry) + else + nextNameToTry + } + + /* Hopefully this is JIT'ed away as `false` because + * `mentionedDangerousGlobalRefs` is in fact `Set.EmptySet`. + */ + if (mentionedDangerousGlobalRefs.contains(envFieldName)) + slowPath(envFieldName) + else + envFieldName + } def genPropSelect(qual: Tree, item: PropertyName)( implicit pos: Position): Tree = { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/WithGlobals.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/WithGlobals.scala index 40fcdf5903..ecac8ab68d 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/WithGlobals.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/WithGlobals.scala @@ -8,6 +8,8 @@ package org.scalajs.core.tools.linker.backend.emitter +import GlobalRefUtils.unionPreserveEmpty + /** A monad that associates a set of global variable names to a value. * * This is used to track the set of (dangerous) global variable names used in @@ -98,16 +100,4 @@ private[emitter] object WithGlobals { def option[A](xs: Option[WithGlobals[A]]): WithGlobals[Option[A]] = xs.fold[WithGlobals[Option[A]]](WithGlobals(None))(_.map(Some(_))) - - /** Semantically equivalent to `a ++ b`, but optimized for empty sets. - * - * Using this method over `a ++ b` is meaningful is there is a strong - * likelihood that one or both parameters are empty, which is the case for - * sets of mentioned global refs. - */ - private def unionPreserveEmpty(a: Set[String], b: Set[String]): Set[String] = { - if (a.isEmpty) b - else if (b.isEmpty) a - else a ++ b - } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 285fdc0e56..79c3e70733 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -543,13 +543,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { case _ => } val lhsTpe = typecheckExpr(select, env) - val expectedRhsTpe = select match { - case _:JSDotSelect | _:JSBracketSelect | _:JSSuperBracketSelect => - AnyType - case _ => - lhsTpe - } - typecheckExpect(rhs, env, expectedRhsTpe) + typecheckExpect(rhs, env, lhsTpe) env case StoreModule(cls, value) => @@ -982,6 +976,8 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { if (!isSubtype(env.thisTpe, tree.tpe)) reportError(s"this of type ${env.thisTpe} typed as ${tree.tpe}") + case JSGlobalRef(_) => + case Closure(captureParams, params, body, captureValues) => /* Check compliance of captureValues wrt. captureParams in the current * method state, i.e., outside `withPerMethodState`. diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index 5522acc83c..c3cd53bcab 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -669,7 +669,8 @@ private[optimizer] abstract class OptimizerCore( // Trees that need not be transformed case _:Skip | _:Debugger | _:LoadModule | _:SelectStatic | - _:LoadJSConstructor | _:LoadJSModule | _:JSLinkingInfo | _:Literal => + _:LoadJSConstructor | _:LoadJSModule | _:JSLinkingInfo | _:Literal | + _:JSGlobalRef => tree case _ => From 52c498f2d95f8ebe862a6f393d6e782cdc818958 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 5 Jun 2017 21:36:26 +0200 Subject: [PATCH 0313/2665] Update the manual CLI tests for the `-mm` argument. This is a good opportunity to test that argument, and it is the future anyway, since `js.JSApp` will disappear in 1.x. --- TESTING | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/TESTING b/TESTING index 23b3ad2f7d..0c53b9b091 100644 --- a/TESTING +++ b/TESTING @@ -11,16 +11,16 @@ For each major Scala version on a *NIX distro and a Windows distro: 5. Create a temporary directory and do: mkdir bin - echo 'import scala.scalajs.js.JSApp - object Foo extends JSApp { - - def main() = { + echo ' + object Foo { + def main(): Unit = { println(s"asdf ${1 + 1}") new A } class A - }' > foo.scala + } + ' > foo.scala scalajsc -d bin foo.scala scalajsp bin/Foo$.sjsir @@ -28,10 +28,9 @@ For each major Scala version on a *NIX distro and a Windows distro: scalajsp bin/Foo\$A.sjsir # Verify output - scalajsld -o test.js bin + scalajsld -o test.js -mm Foo.main bin # Verify output - echo "Foo().main()" >> test.js node test.js # Or your favorite thing to run JS # Expect "asdf 2" From 6e96ec257b14249276d1580b5158177b583a93cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 5 Jun 2017 15:32:27 +0200 Subject: [PATCH 0314/2665] Assume in the linker that the library has the new RuntimeLong. --- .../backend/emitter/FunctionEmitter.scala | 12 +- .../backend/emitter/GlobalKnowledge.scala | 6 - .../backend/emitter/KnowledgeGuardian.scala | 14 +- .../linker/backend/emitter/LongImpl.scala | 39 +---- .../frontend/optimizer/GenIncOptimizer.scala | 1 - .../frontend/optimizer/OptimizerCore.scala | 151 ++++++++---------- 6 files changed, 74 insertions(+), 149 deletions(-) diff --git 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 index 7cd8e3c2cf..f529f8d4fa 100644 --- 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 @@ -2208,15 +2208,9 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case LongLiteral(0L) => genLongZero() case LongLiteral(value) => - if (globalKnowledge.hasNewRuntimeLong) { - val (lo, hi) = LongImpl.extractParts(value) - genNewLong(LongImpl.initFromParts, - js.IntLiteral(lo), js.IntLiteral(hi)) - } else { - val (l, m, h) = LongImpl.extractPartsOld(value) - genNewLong(LongImpl.initFromPartsOld, - js.IntLiteral(l), js.IntLiteral(m), js.IntLiteral(h)) - } + val (lo, hi) = LongImpl.extractParts(value) + genNewLong(LongImpl.initFromParts, + js.IntLiteral(lo), js.IntLiteral(hi)) case ClassOf(cls) => js.Apply(js.DotSelect(genClassDataOf(cls), js.Ident("getClassOf")), diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala index 036dcca7c8..89bdbe4371 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala @@ -15,12 +15,6 @@ private[emitter] trait GlobalKnowledge { /** Tests whether the parent class data is accessed in the linking unit. */ def isParentDataAccessed: Boolean - // TODO Get rid of this when we break backward binary compatibility - /** Whether the standard library we're using has the new `RuntimeLong` - * implementation, with `lo` and `hi`. - */ - def hasNewRuntimeLong: Boolean - /** Tests whether the specified class name refers to an `Interface`. */ def isInterface(className: String): Boolean diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala index 34f76a37f2..bd275f24c1 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala @@ -21,14 +21,10 @@ private[emitter] final class KnowledgeGuardian { private var firstRun: Boolean = true - private var hasNewRuntimeLong: Boolean = _ private var isParentDataAccessed: Boolean = _ private val classes = mutable.Map.empty[String, Class] - private def askHasNewRuntimeLong(invalidatable: Invalidatable): Boolean = - hasNewRuntimeLong - private def askIsParentDataAccessed(invalidatable: Invalidatable): Boolean = isParentDataAccessed @@ -42,7 +38,6 @@ private[emitter] final class KnowledgeGuardian { */ def update(linkingUnit: LinkingUnit): Boolean = { var newIsParentDataAccessed = false - var newHasNewRuntimeLong: Boolean = false // Update classes for (linkedClass <- linkingUnit.classDefs) { @@ -59,8 +54,6 @@ private[emitter] final class KnowledgeGuardian { linkedClass.encodedName match { case Definitions.ClassClass => newIsParentDataAccessed = methodExists("getSuperclass__jl_Class") - case LongImpl.RuntimeLongClass => - newHasNewRuntimeLong = methodExists(LongImpl.initFromParts) case _ => } } @@ -69,13 +62,11 @@ private[emitter] final class KnowledgeGuardian { classes.retain((_, cls) => cls.testAndResetIsAlive()) val invalidateAll = !firstRun && { - newIsParentDataAccessed != isParentDataAccessed || - newHasNewRuntimeLong != hasNewRuntimeLong + newIsParentDataAccessed != isParentDataAccessed } firstRun = false isParentDataAccessed = newIsParentDataAccessed - hasNewRuntimeLong = newHasNewRuntimeLong if (invalidateAll) classes.valuesIterator.foreach(_.unregisterAll()) @@ -88,9 +79,6 @@ private[emitter] final class KnowledgeGuardian { * footprint and pointer indirections. */ - def hasNewRuntimeLong: Boolean = - askHasNewRuntimeLong(this) - def isParentDataAccessed: Boolean = askIsParentDataAccessed(this) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/LongImpl.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/LongImpl.scala index f293d6c118..d5b1b4f7eb 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/LongImpl.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/LongImpl.scala @@ -75,27 +75,16 @@ private[linker] object LongImpl { final val divideUnsigned = "divideUnsigned__sjsr_RuntimeLong__sjsr_RuntimeLong" final val remainderUnsigned = "remainderUnsigned__sjsr_RuntimeLong__sjsr_RuntimeLong" - val AllIntrinsicMethods = Set.empty[String] - - // TODO Move these to AllIntrinsicMethods when we can break binary compatibility - val OptionalIntrinsicMethods = Set( + val AllIntrinsicMethods = Set( divideUnsigned, remainderUnsigned) // Constructors - final val initFromParts = "init___I__I" - final val initFromPartsOld = "init___I__I__I" - final val initFromInt = "init___I" - - /* Note that initFromPartsOld depends on initFromParts in the new - * implementation of RuntimeLong, so this ensures that the new one is - * reachable. - * We do not directly refer to the new one, other we would crash on earlier - * versions of RuntimeLong that do not yet have the new constructor. - * TODO Get rid of this when we break backward binary compatibility - */ + final val initFromParts = "init___I__I" + final val initFromInt = "init___I" + val AllConstructors = Set( - initFromPartsOld, initFromInt) + initFromParts, initFromInt) // Methods on the companion @@ -110,22 +99,4 @@ private[linker] object LongImpl { def extractParts(value: Long): (Int, Int) = (value.toInt, (value >>> 32).toInt) - - /* Boldly copied from the old version of library/scala.scalajs.runtime.RuntimeLong - * TODO Get rid of this when we break backward binary compatibility - */ - - /** Number of relevant bits in l and m each. */ - private final val BITS = 22 - /** Number of relevant bits in l and m together. */ - private final val BITS01 = 2 * BITS - /** Number of relevant bits in h. */ - private final val BITS2 = 64 - BITS01 - /** Bitmask for l and m. */ - private final val MASK = (1 << BITS) - 1 - /** Bitmask for h. */ - private final val MASK_2 = (1 << BITS2) - 1 - - def extractPartsOld(value: Long): (Int, Int, Int) = - (value.toInt & MASK, (value >> BITS).toInt & MASK, (value >> BITS01).toInt & MASK_2) } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala index dabcfb9a37..7887e1bc29 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala @@ -51,7 +51,6 @@ abstract class GenIncOptimizer private[optimizer] (semantics: Semantics, import factory._ callMethods(LongImpl.RuntimeLongClass, LongImpl.AllIntrinsicMethods) ++ - optional(callMethods(LongImpl.RuntimeLongClass, LongImpl.OptionalIntrinsicMethods)) ++ /* #2184 + #2780: we need to keep all methods of j.l.Integer, in case * the corresponding methods are called on j.l.Byte or j.l.Short, and * through optimizations become calls on j.l.Integer. diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index c3cd53bcab..258ec96479 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -104,29 +104,17 @@ private[optimizer] abstract class OptimizerCore( private var curTrampolineId = 0 - /** The record type for inlined `RuntimeLong`, if the `RuntimeLong` in the - * library is inlineable, otherwise `None` - */ + /** The record type for inlined `RuntimeLong`. */ private lazy val inlinedRTLongRecordType = - tryNewInlineableClass(LongImpl.RuntimeLongClass).map(_.tpe) - - /** Tests whether the RuntimeLong in the library is inlineable. */ - private lazy val hasInlineableRTLongImplementation = - inlinedRTLongRecordType.isDefined + tryNewInlineableClass(LongImpl.RuntimeLongClass).map(_.tpe).get - /** The name of the `lo` field of in the record type of `RuntimeLong`. - * Using this val is only valid when `hasInlineableRTLongImplementation` is - * true. - */ + /** The name of the `lo` field of in the record type of `RuntimeLong`. */ private lazy val inlinedRTLongLoField = - inlinedRTLongRecordType.get.fields(0).name + inlinedRTLongRecordType.fields(0).name - /** The name of the `lo` field of in the record type of `RuntimeLong`. - * Using this val is only valid when `hasInlineableRTLongImplementation` is - * true. - */ + /** The name of the `lo` field of in the record type of `RuntimeLong`. */ private lazy val inlinedRTLongHiField = - inlinedRTLongRecordType.get.fields(1).name + inlinedRTLongRecordType.fields(1).name def optimize(thisType: Type, originalDef: MethodDef): LinkedMember[MethodDef] = { try { @@ -1087,8 +1075,7 @@ private[optimizer] abstract class OptimizerCore( } // Select the lo or hi "field" of a Long literal - case PreTransLit(LongLiteral(value)) - if hasInlineableRTLongImplementation => + case PreTransLit(LongLiteral(value)) => val itemName = item.name assert(itemName == inlinedRTLongLoField || itemName == inlinedRTLongHiField) @@ -2442,9 +2429,6 @@ private[optimizer] abstract class OptimizerCore( private def expandLongValue(value: PreTransform)(cont: PreTransCont)( implicit scope: Scope, pos: Position): TailRec[Tree] = { - assert(hasInlineableRTLongImplementation, - "Cannot call expandLongValue if RuntimeLong is not @inline") - /* To force the expansion, we first store the `value` in a temporary * variable of type `RuntimeLong` (not `Long`, otherwise we would go into * infinite recursion), then we create a `new RuntimeLong` with its lo and @@ -2489,77 +2473,73 @@ private[optimizer] abstract class OptimizerCore( cont) } - if (!hasInlineableRTLongImplementation) { - cont(pretrans) - } else { - pretrans match { - case PreTransUnaryOp(op, arg) => - import UnaryOp._ - - (op: @switch) match { - case IntToLong => - pretransformNew(AllocationSite.Anonymous, rtLongClassType, - Ident(LongImpl.initFromInt), - arg :: Nil)( - cont) - - case LongToInt => - expandUnaryOp(LongImpl.toInt, arg, IntType) - - case LongToDouble => - expandUnaryOp(LongImpl.toDouble, arg, DoubleType) - - case DoubleToLong => - val receiver = LoadModule(rtLongModuleClassType).toPreTransform - pretransformApply(receiver, Ident(LongImpl.fromDouble), - arg :: Nil, rtLongClassType, isStat = false, - usePreTransform = true)( - cont) + pretrans match { + case PreTransUnaryOp(op, arg) => + import UnaryOp._ - case _ => - cont(pretrans) - } + (op: @switch) match { + case IntToLong => + pretransformNew(AllocationSite.Anonymous, rtLongClassType, + Ident(LongImpl.initFromInt), + arg :: Nil)( + cont) - case PreTransBinaryOp(op, lhs, rhs) => - import BinaryOp._ + case LongToInt => + expandUnaryOp(LongImpl.toInt, arg, IntType) - (op: @switch) match { - case Long_+ => expandBinaryOp(LongImpl.+, lhs, rhs) + case LongToDouble => + expandUnaryOp(LongImpl.toDouble, arg, DoubleType) - case Long_- => - lhs match { - case PreTransLit(LongLiteral(0L)) => - expandUnaryOp(LongImpl.UNARY_-, rhs) - case _ => - expandBinaryOp(LongImpl.-, lhs, rhs) - } + case DoubleToLong => + val receiver = LoadModule(rtLongModuleClassType).toPreTransform + pretransformApply(receiver, Ident(LongImpl.fromDouble), + arg :: Nil, rtLongClassType, isStat = false, + usePreTransform = true)( + cont) + + case _ => + cont(pretrans) + } - case Long_* => expandBinaryOp(LongImpl.*, lhs, rhs) - case Long_/ => expandBinaryOp(LongImpl./, lhs, rhs) - case Long_% => expandBinaryOp(LongImpl.%, lhs, rhs) + case PreTransBinaryOp(op, lhs, rhs) => + import BinaryOp._ - case Long_& => expandBinaryOp(LongImpl.&, lhs, rhs) - case Long_| => expandBinaryOp(LongImpl.|, lhs, rhs) - case Long_^ => expandBinaryOp(LongImpl.^, lhs, rhs) + (op: @switch) match { + case Long_+ => expandBinaryOp(LongImpl.+, lhs, rhs) - case Long_<< => expandBinaryOp(LongImpl.<<, lhs, rhs) - case Long_>>> => expandBinaryOp(LongImpl.>>>, lhs, rhs) - case Long_>> => expandBinaryOp(LongImpl.>>, lhs, rhs) + case Long_- => + lhs match { + case PreTransLit(LongLiteral(0L)) => + expandUnaryOp(LongImpl.UNARY_-, rhs) + case _ => + expandBinaryOp(LongImpl.-, lhs, rhs) + } - case Long_== => expandBinaryOp(LongImpl.===, lhs, rhs) - case Long_!= => expandBinaryOp(LongImpl.!==, lhs, rhs) - case Long_< => expandBinaryOp(LongImpl.<, lhs, rhs) - case Long_<= => expandBinaryOp(LongImpl.<=, lhs, rhs) - case Long_> => expandBinaryOp(LongImpl.>, lhs, rhs) - case Long_>= => expandBinaryOp(LongImpl.>=, lhs, rhs) + case Long_* => expandBinaryOp(LongImpl.*, lhs, rhs) + case Long_/ => expandBinaryOp(LongImpl./, lhs, rhs) + case Long_% => expandBinaryOp(LongImpl.%, lhs, rhs) - case _ => - cont(pretrans) - } + case Long_& => expandBinaryOp(LongImpl.&, lhs, rhs) + case Long_| => expandBinaryOp(LongImpl.|, lhs, rhs) + case Long_^ => expandBinaryOp(LongImpl.^, lhs, rhs) - case _ => - cont(pretrans) - } + case Long_<< => expandBinaryOp(LongImpl.<<, lhs, rhs) + case Long_>>> => expandBinaryOp(LongImpl.>>>, lhs, rhs) + case Long_>> => expandBinaryOp(LongImpl.>>, lhs, rhs) + + case Long_== => expandBinaryOp(LongImpl.===, lhs, rhs) + case Long_!= => expandBinaryOp(LongImpl.!==, lhs, rhs) + case Long_< => expandBinaryOp(LongImpl.<, lhs, rhs) + case Long_<= => expandBinaryOp(LongImpl.<=, lhs, rhs) + case Long_> => expandBinaryOp(LongImpl.>, lhs, rhs) + case Long_>= => expandBinaryOp(LongImpl.>=, lhs, rhs) + + case _ => + cont(pretrans) + } + + case _ => + cont(pretrans) } } @@ -3982,8 +3962,7 @@ private[optimizer] abstract class OptimizerCore( def withDedicatedVar(tpe: RefinedType): TailRec[Tree] = { val rtLongClassType = ClassType(LongImpl.RuntimeLongClass) - if (tpe.base == LongType && declaredType != rtLongClassType && - hasInlineableRTLongImplementation) { + if (tpe.base == LongType && declaredType != rtLongClassType) { /* If the value's type is a primitive Long, and the declared type is * not RuntimeLong, we want to force the expansion of the primitive * Long (which we know is in fact a RuntimeLong) into a local variable, From f5aeee711cc2242bb6570f0bddc1fbc3b40cb385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 5 Jun 2017 16:28:40 +0200 Subject: [PATCH 0315/2665] Remove deprecated stuff in the Scala.js standard library. --- .../org/scalajs/core/compiler/GenJSCode.scala | 4 - .../scalajs/core/compiler/JSDefinitions.scala | 3 - .../scalajs/core/compiler/JSPrimitives.scala | 4 - .../scalajs/core/compiler/PrepJSInterop.scala | 1 - .../test/InternalAnnotationsTest.scala | 5 - .../concurrent/JSExecutionContext.scala | 9 - .../concurrent/RunNowExcecutionContext.scala | 19 --- .../scala/scala/scalajs/js/Dictionary.scala | 18 -- .../scalajs/js/annotation/JSFullName.scala | 20 --- .../main/scala/scala/scalajs/js/package.scala | 14 -- .../scala/scalajs/runtime/RuntimeLong.scala | 113 ------------- .../scala/scalajs/runtime/StackTrace.scala | 9 - .../scala/scala/scalajs/runtime/package.scala | 18 -- .../testsuite/jsinterop/AsyncTest.scala | 44 +++-- .../testsuite/jsinterop/DictionaryTest.scala | 36 +--- .../testsuite/jsinterop/DynamicTest.scala | 12 -- .../testsuite/jsinterop/MiscInteropTest.scala | 2 +- .../testsuite/jsinterop/RuntimeLongTest.scala | 155 ------------------ 18 files changed, 30 insertions(+), 456 deletions(-) delete mode 100644 library/src/main/scala/scala/scalajs/concurrent/RunNowExcecutionContext.scala delete mode 100644 library/src/main/scala/scala/scalajs/js/annotation/JSFullName.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 863a3d8d9e..9995592b37 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -4162,10 +4162,6 @@ abstract class GenJSCode extends plugins.PluginComponent case F2JSTHIS => genFunctionToJSFunction(isThisFunction = true) - case DICT_DEL => - // js.Dictionary.delete(arg) - js.JSDelete(js.JSBracketSelect(receiver, arg)) - case TYPEOF => // js.typeOf(arg) genAsInstanceOf(js.JSUnaryOp(js.JSUnaryOp.typeof, arg), diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 25ddd21792..c5a1d3b575 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -33,8 +33,6 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val JSAnyClass = getRequiredClass("scala.scalajs.js.Any") lazy val JSDynamicClass = getRequiredClass("scala.scalajs.js.Dynamic") - lazy val JSDictionaryClass = getRequiredClass("scala.scalajs.js.Dictionary") - lazy val JSDictionary_delete = getMemberMethod(JSDictionaryClass, newTermName("delete")) lazy val JSObjectClass = getRequiredClass("scala.scalajs.js.Object") lazy val JSThisFunctionClass = getRequiredClass("scala.scalajs.js.ThisFunction") @@ -53,7 +51,6 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val JavaScriptExceptionClass = getClassIfDefined("scala.scalajs.js.JavaScriptException") lazy val JSNameAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSName") - lazy val JSFullNameAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSFullName") lazy val JSBracketAccessAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSBracketAccess") lazy val JSBracketCallAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSBracketCall") lazy val JSExportAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExport") diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala index 27ff34d455..0a5d8cdf60 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala @@ -37,8 +37,6 @@ abstract class JSPrimitives { val DYNLIT = 334 // js.Dynamic.literal.applyDynamic{,Named} - val DICT_DEL = 335 // js.Dictionary.delete - val ARR_CREATE = 337 // js.Array.apply (array literal syntax) val TYPEOF = 344 // typeof x @@ -94,8 +92,6 @@ abstract class JSPrimitives { addPrimitive(JSDynamicLiteral_applyDynamicNamed, DYNLIT) addPrimitive(JSDynamicLiteral_applyDynamic, DYNLIT) - addPrimitive(JSDictionary_delete, DICT_DEL) - addPrimitive(JSArray_create, ARR_CREATE) addPrimitive(JSPackage_typeOf, TYPEOF) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 522070502d..0a046d54b2 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -1372,7 +1372,6 @@ abstract class PrepJSInterop extends plugins.PluginComponent */ def isCompilerAnnotation(annotation: AnnotationInfo): Boolean = { annotation.symbol == ExposedJSMemberAnnot || - annotation.symbol == JSFullNameAnnotation || annotation.symbol == RawJSTypeAnnot || annotation.symbol == SJSDefinedAnonymousClassAnnotation || annotation.symbol == JSOptionalAnnotation diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/InternalAnnotationsTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/InternalAnnotationsTest.scala index 5e2c061ed7..3de116738c 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/InternalAnnotationsTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/InternalAnnotationsTest.scala @@ -16,11 +16,6 @@ class InternalAnnotationsTest extends DirectTest with TestHelpers { test("ExposedJSMember") } - @Test - def jsFullName: Unit = { - test("JSFullName(\"abc\")") - } - @Test def rawJSType: Unit = { test("RawJSType") diff --git a/library/src/main/scala/scala/scalajs/concurrent/JSExecutionContext.scala b/library/src/main/scala/scala/scalajs/concurrent/JSExecutionContext.scala index ee5a1f592b..534fd3f1be 100644 --- a/library/src/main/scala/scala/scalajs/concurrent/JSExecutionContext.scala +++ b/library/src/main/scala/scala/scalajs/concurrent/JSExecutionContext.scala @@ -10,13 +10,6 @@ import scala.concurrent.ExecutionContextExecutor */ object JSExecutionContext { - /** Execution context that runs immediately. - * - * Beware of stack growth! - */ - @deprecated("Not asynchronous. Use JSExecutionContext.queue instead.", "0.6.6") - val runNow: ExecutionContextExecutor = RunNowExecutionContext - /** Execution context that submits into the JavaScript runtime's task queue. * * It uses JavaScript [[scala.scalajs.js.Promise Promises]] if available, @@ -25,8 +18,6 @@ object JSExecutionContext { val queue: ExecutionContextExecutor = QueueExecutionContext() object Implicits { - @deprecated("Not asynchronous. Use JSExecutionContext.Implicits.queue instead.", "0.6.6") - implicit val runNow: ExecutionContextExecutor = RunNowExecutionContext implicit val queue: ExecutionContextExecutor = JSExecutionContext.queue } diff --git a/library/src/main/scala/scala/scalajs/concurrent/RunNowExcecutionContext.scala b/library/src/main/scala/scala/scalajs/concurrent/RunNowExcecutionContext.scala deleted file mode 100644 index ff793f22c9..0000000000 --- a/library/src/main/scala/scala/scalajs/concurrent/RunNowExcecutionContext.scala +++ /dev/null @@ -1,19 +0,0 @@ -package scala.scalajs.concurrent - -import scala.concurrent.ExecutionContextExecutor - -private[concurrent] object RunNowExecutionContext - extends ExecutionContextExecutor { - - def execute(runnable: Runnable): Unit = { - try { - runnable.run() - } catch { - case t: Throwable => reportFailure(t) - } - } - - def reportFailure(t: Throwable): Unit = - t.printStackTrace() - -} diff --git a/library/src/main/scala/scala/scalajs/js/Dictionary.scala b/library/src/main/scala/scala/scalajs/js/Dictionary.scala index 821108abd9..37235c3cd2 100644 --- a/library/src/main/scala/scala/scalajs/js/Dictionary.scala +++ b/library/src/main/scala/scala/scalajs/js/Dictionary.scala @@ -53,24 +53,6 @@ sealed trait Dictionary[A] extends Any { /** Writes a field of this object by its name. */ @JSBracketAccess def update(key: String, value: A): Unit = native - - /* Note: `delete` cannot be replaced by a user-land implementation in - * WrappedDictionary, because it would break forward compiler-library - * compatibility. If someone uses an 0.6.16 compiler with an 0.6.17 library - * (which can easily happen if depending on a third-party library compiled - * with 0.6.17), the compiler will look for this symbol and crash. - */ - - /** Deletes a property of this object by its name. - * - * The property must be configurable. - * This method is equivalent to the "delete" keyword in JavaScript. - * - * Since we are using strict mode, this throws an exception, if the property - * isn't configurable. - */ - @deprecated("Use -= instead.", "0.6.17") - def delete(key: String): Unit = throw new java.lang.Error("stub") } /** Factory for [[Dictionary]] instances. */ diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSFullName.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSFullName.scala deleted file mode 100644 index 8005276033..0000000000 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSFullName.scala +++ /dev/null @@ -1,20 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package scala.scalajs.js.annotation - -/** IMPLEMENTATION DETAIL: Saves the fully qualified JS name of a symbol. - * - * This annotation was used prior to Scala.js 0.6.13. It is only kept for - * backwards binary compatibility, and should not be used anymore. - * - * Do not use this annotation yourself. - */ -@deprecated("Replaced by internal.JSNativeLoadSpec.", "0.6.13") -class JSFullName(fullName: String) extends scala.annotation.StaticAnnotation diff --git a/library/src/main/scala/scala/scalajs/js/package.scala b/library/src/main/scala/scala/scalajs/js/package.scala index baeacf86ac..b105a2f88f 100644 --- a/library/src/main/scala/scala/scalajs/js/package.scala +++ b/library/src/main/scala/scala/scalajs/js/package.scala @@ -86,20 +86,6 @@ package object js { def constructorTag[T <: js.Any](implicit tag: ConstructorTag[T]): ConstructorTag[T] = tag - /** Invokes any available debugging functionality. - * If no debugging functionality is available, this statement has no effect. - * - * MDN - * - * Browser support: - * - Has no effect in Firefox, apparently - * - In Chrome, it has no effect unless the developer tools are opened - * beforehand. - */ - @deprecated("Use scala.scalajs.js.sepcial.debugger instead", "0.6.17") - @inline - def debugger(): Unit = js.special.debugger() - /** Evaluates JavaScript code and returns the result. */ @inline def eval(x: String): Any = js.Dynamic.global.eval(x) diff --git a/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala b/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala index af4304147b..3b94769968 100644 --- a/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala +++ b/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala @@ -42,21 +42,6 @@ final class RuntimeLong(val lo: Int, val hi: Int) /** Constructs a Long from an Int. */ def this(value: Int) = this(value, value >> 31) - // Binary compatibility for the old (l, m, h) encoding - - @deprecated("Use the constructor with (lo, hi) instead.", "0.6.6") - def this(l: Int, m: Int, h: Int) = - this(l | (m << 22), (m >> 10) | (h << 12)) - - @deprecated("Use lo and hi instead.", "0.6.6") - def l: Int = lo & ((1 << 22) - 1) - - @deprecated("Use lo and hi instead.", "0.6.6") - def m: Int = (lo >>> 22) & ((hi & ((1 << 12) - 1)) << 10) - - @deprecated("Use lo and hi instead.", "0.6.6") - def h: Int = hi >>> 12 - // Universal equality @inline @@ -545,92 +530,6 @@ final class RuntimeLong(val lo: Int, val hi: Int) def remainderUnsigned(b: RuntimeLong): RuntimeLong = RuntimeLong.remainderUnsigned(a, b) - // TODO Remove these. They were support for intrinsics before 0.6.6. - - @deprecated("Use java.lang.Long.toBinaryString instead.", "0.6.6") - def toBinaryString: String = { - val zeros = "00000000000000000000000000000000" // 32 zeros - @inline def padBinary32(i: Int) = { - val s = Integer.toBinaryString(i) - zeros.substring(s.length) + s - } - - val lo = this.lo - val hi = this.hi - - if (hi != 0) Integer.toBinaryString(hi) + padBinary32(lo) - else Integer.toBinaryString(lo) - } - - @deprecated("Use java.lang.Long.toHexString instead.", "0.6.6") - def toHexString: String = { - val zeros = "00000000" // 8 zeros - @inline def padHex8(i: Int) = { - val s = Integer.toHexString(i) - zeros.substring(s.length) + s - } - - val lo = this.lo - val hi = this.hi - - if (hi != 0) Integer.toHexString(hi) + padHex8(lo) - else Integer.toHexString(lo) - } - - @deprecated("Use java.lang.Long.toOctalString instead.", "0.6.6") - def toOctalString: String = { - val zeros = "0000000000" // 10 zeros - @inline def padOctal10(i: Int) = { - val s = Integer.toOctalString(i) - zeros.substring(s.length) + s - } - - val lo = this.lo - val hi = this.hi - - val lp = lo & 0x3fffffff - val mp = ((lo >>> 30) + (hi << 2)) & 0x3fffffff - val hp = hi >>> 28 - - if (hp != 0) Integer.toOctalString(hp) + padOctal10(mp) + padOctal10(lp) - else if (mp != 0) Integer.toOctalString(mp) + padOctal10(lp) - else Integer.toOctalString(lp) - } - - @deprecated("Use java.lang.Long.bitCount instead.", "0.6.6") - def bitCount: Int = - Integer.bitCount(lo) + Integer.bitCount(hi) - - @deprecated("Use java.lang.Long.signum instead.", "0.6.6") - def signum: RuntimeLong = { - val hi = this.hi - if (hi < 0) MinusOne - else if (isZero(lo, hi)) Zero - else One - } - - @deprecated("Use java.lang.Long.numberOfLeadingZeros instead.", "0.6.6") - def numberOfLeadingZeros: Int = { - val hi = this.hi - if (hi != 0) Integer.numberOfLeadingZeros(hi) - else Integer.numberOfLeadingZeros(lo) + 32 - } - - @deprecated("Use java.lang.Long.numberOfTrailingZeros instead.", "0.6.6") - def numberOfTrailingZeros: Int = { - val lo = this.lo - if (lo != 0) Integer.numberOfTrailingZeros(lo) - else Integer.numberOfTrailingZeros(hi) + 32 - } - - // TODO Remove those. There are remnant of before we had LongReflectiveCall - - @deprecated("Just use `this` instead.", "0.6.6") - def unary_+ : RuntimeLong = this // scalastyle:ignore - - @deprecated("Use `this.toString + y` instead.", "0.6.6") - def +(y: String): String = this.toString + y - } object RuntimeLong { @@ -655,18 +554,6 @@ object RuntimeLong { /** The instance of 0L, which is used by the `Emitter` in various places. */ val Zero = new RuntimeLong(0, 0) - @deprecated("Use new RuntimeLong(1, 0) instead.", "0.6.11") - def One: RuntimeLong = new RuntimeLong(1, 0) - - @deprecated("Use new RuntimeLong(-1, -1) instead.", "0.6.11") - def MinusOne: RuntimeLong = new RuntimeLong(-1, -1) - - @deprecated("Use new RuntimeLong(0, 0x80000000) instead.", "0.6.11") - def MinValue: RuntimeLong = new RuntimeLong(0, 0x80000000) - - @deprecated("Use new RuntimeLong(0xffffffff, 0x7fffffff) instead.", "0.6.11") - def MaxValue: RuntimeLong = new RuntimeLong(0xffffffff, 0x7fffffff) - private def toString(lo: Int, hi: Int): String = { if (isInt32(lo, hi)) { lo.toString() diff --git a/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala b/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala index a5b684f466..2dc1128d2a 100644 --- a/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala +++ b/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala @@ -535,15 +535,6 @@ object StackTrace { } } - /** - * Implicit class to access magic column element created in STE - */ - @deprecated("Use Implicits.StackTraceElementOps instead.", "0.6.3") - implicit class ColumnStackTraceElement(ste: StackTraceElement) { - def getColumnNumber: Int = - new Implicits.StackTraceElementOps(ste).getColumnNumber() - } - object Implicits { /** Access to the additional methods `getColumnNumber` and `setColumnNumber` * of [[java.lang.StackTraceElement StackTraceElement]]. diff --git a/library/src/main/scala/scala/scalajs/runtime/package.scala b/library/src/main/scala/scala/scalajs/runtime/package.scala index 3a4be2a54f..81f0b966a3 100644 --- a/library/src/main/scala/scala/scalajs/runtime/package.scala +++ b/library/src/main/scala/scala/scalajs/runtime/package.scala @@ -6,11 +6,6 @@ import scala.collection.GenTraversableOnce package object runtime { - @deprecated("Use scala.scalajs.LinkingInfo.assumingES6 instead.", "0.6.6") - @inline - def assumingES6: Boolean = - scala.scalajs.LinkingInfo.assumingES6 - def wrapJavaScriptException(e: Any): Throwable = e match { case e: Throwable => e case _ => js.JavaScriptException(e) @@ -51,19 +46,6 @@ package object runtime { result } - /** Instantiates a JS object with variadic arguments to the constructor. - * - * This method was needed by the codegen of 0.6.0 through 0.6.2. It is not - * needed anymore, and should not be used directly. - * - * It is kept for backward binary compatibility with 0.6.{0,1,2}, but will - * be removed in the next major version. - */ - @deprecated("Use js.Dynamic.newInstance instead.", "0.6.3") - @inline - def newJSObjectWithVarargs(ctor: js.Dynamic, args: js.Array[_]): js.Any = - js.Dynamic.newInstance(ctor)(args.asInstanceOf[js.Array[js.Any]]: _*) - /** Dummy method used to preserve the type parameter of * `js.constructorOf[T]` through erasure. * diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/AsyncTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/AsyncTest.scala index ab41b16286..a60a782c13 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/AsyncTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/AsyncTest.scala @@ -23,6 +23,7 @@ import org.junit.Assume._ import org.junit.Test class AsyncTest { + import AsyncTest._ implicit def eraseArray[T](a: Array[T]): Array[AnyRef] = a.map(_.asInstanceOf[AnyRef]) @@ -86,19 +87,6 @@ class AsyncTest { } } - @Test def scala_scalajs_concurrent_JSExecutionContext_runNow(): Unit = { - val res = asyncTest(JSExecutionContext.runNow) - - assertArrayEquals(Array( - "prep-future", - "future", - "prep-map", - "map", - "prep-foreach", - "foreach", - "done"), res.toArray) - } - @Test def scala_scala_concurrent_ExecutionContext_global(): Unit = { assumeTrue("Assumed js.Dynamic.global.Promise is undefined", js.typeOf(js.Dynamic.global.Promise) == "undefined") @@ -142,19 +130,19 @@ class AsyncTest { } @Test def scala_concurrent_future_should_support_map(): Unit = { - implicit val ec = JSExecutionContext.runNow + implicit val ec = RunNowExecutionContext val f = Future(3).map(x => x*2) assertEquals(6, f.value.get.get) } @Test def scala_concurrent_future_should_support_flatMap(): Unit = { - implicit val ec = JSExecutionContext.runNow + implicit val ec = RunNowExecutionContext val f = Future(Future(3)).flatMap(x => x) assertEquals(3, f.value.get.get) } @Test def scala_concurrent_future_should_support_sequence(): Unit = { - implicit val ec = JSExecutionContext.runNow + implicit val ec = RunNowExecutionContext val f = Future.sequence(Seq(Future(3), Future(5))) assertEquals(Seq(3, 5), f.value.get.get) } @@ -233,3 +221,27 @@ class AsyncTest { } } } + +object AsyncTest { + /** A super hacky `ExecutionContext` that is synchronous. + * + * This should not be used in normal code. It should not even be used in + * testing code. We need it here to test some basic `Future` methods, + * because we are stuck with JUnit, which obviously does not support + * asynchronous test suites. + */ + private object RunNowExecutionContext + extends scala.concurrent.ExecutionContextExecutor { + + def execute(runnable: Runnable): Unit = { + try { + runnable.run() + } catch { + case t: Throwable => reportFailure(t) + } + } + + def reportFailure(t: Throwable): Unit = + t.printStackTrace() + } +} diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DictionaryTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DictionaryTest.scala index 61cafaaa7f..4e92c9e7e0 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DictionaryTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DictionaryTest.scala @@ -21,28 +21,6 @@ class DictionaryTest { // scala.scalajs.js.Dictionary - @Test def should_provide_an_equivalent_of_the_JS_delete_keyword_issue_255(): Unit = { - val obj = js.Dictionary.empty[js.Any] - obj("foo") = 42 - obj("bar") = "foobar" - - assertEquals(42, obj("foo")) - assertEquals("foobar", obj("bar")) - obj.delete("foo") - assertFalse(obj.contains("foo")) - assertFalse(obj.asInstanceOf[js.Object].hasOwnProperty("foo")) - assertEquals("foobar", obj("bar")) - } - - @Test def should_behave_as_specified_when_deleting_a_non_configurable_property_issue_461_issue_679(): Unit = { - val obj = js.Dictionary.empty[js.Any] - js.Object.defineProperty(obj.asInstanceOf[js.Object], "nonconfig", - js.Dynamic.literal(value = 4, writable = false).asInstanceOf[js.PropertyDescriptor]) - assertEquals(4, obj("nonconfig")) - assertThrows(classOf[Exception], obj.delete("nonconfig")) - assertEquals(4, obj("nonconfig")) - } - @Test def apply_should_throw_when_not_found(): Unit = { val obj = js.Dictionary("foo" -> "bar") assertThrows(classOf[NoSuchElementException], obj("bar")) @@ -61,11 +39,6 @@ class DictionaryTest { obj -= "b" } - @Test def should_treat_delete_as_a_statement_issue_907(): Unit = { - val obj = js.Dictionary("a" -> "A") - obj.delete("a") - } - @Test def should_provide_keys(): Unit = { val obj = js.Dictionary("a" -> "A", "b" -> "B") val keys = obj.keys.toList @@ -79,7 +52,7 @@ class DictionaryTest { assertFalse(obj.contains("hasOwnProperty")) obj("hasOwnProperty") = 5 assertTrue(obj.contains("hasOwnProperty")) - obj.delete("hasOwnProperty") + obj -= "hasOwnProperty" assertFalse(obj.contains("hasOwnProperty")) } @@ -95,13 +68,6 @@ class DictionaryTest { assertTrue(elems.contains(("babar", 0))) } - @Test def should_desugar_arguments_to_delete_statements_issue_908(): Unit = { - val kh = js.Dynamic.literal(key = "a").asInstanceOf[KeyHolder] - val dict = js.Dictionary[String]("a" -> "A") - def a[T](foo: String): T = dict.asInstanceOf[T] - a[js.Dictionary[String]]("foo").delete(kh.key) - } - // scala.scalajs.js.JSConverters.JSRichGenMap @Test def should_provide_toJSDictionary(): Unit = { diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DynamicTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DynamicTest.scala index b9feb9047e..92483c2404 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DynamicTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DynamicTest.scala @@ -109,18 +109,6 @@ class DynamicTest { assertEquals(42, obj3_elem1) val obj3_elem2 = obj3.elem2 assertTrue(obj3_elem2) - - // Check backward binary compatibility with the 0.6.{0,1,2} codegen output - val obj4 = scala.scalajs.runtime.newJSObjectWithVarargs( - DynamicTestClassVarArgs, obj3Args.toJSArray).asInstanceOf[js.Dynamic] - val obj4_count = obj4.count - assertEquals(3, obj4_count) - val obj4_elem0 = obj4.elem0 - assertEquals("Scala.js", obj4_elem0) - val obj4_elem1 = obj4.elem1 - assertEquals(42, obj4_elem1) - val obj4_elem2 = obj4.elem2 - assertTrue(obj4_elem2) } @Test def should_provide_an_object_literal_construction(): Unit = { diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala index 2098f325e7..567d124b93 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala @@ -83,7 +83,7 @@ class MiscInteropTest { * This will be fixed when we can use ...spread calls with `new`, which * we can't yet do because the latest io.js does not support them yet. */ - import scala.scalajs.runtime.assumingES6 + import scala.scalajs.LinkingInfo.assumingES6 val concreteInstance = { val tag = js.constructorTag[ConcreteJSClass] diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/RuntimeLongTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/RuntimeLongTest.scala index 2bfb55f54e..fb574c23df 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/RuntimeLongTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/RuntimeLongTest.scala @@ -2088,158 +2088,3 @@ class RuntimeLongTest { } } - -class RuntimeLongOldTest { - - import RuntimeLong.fromDouble - - def assertHexEquals(expected: String, l: RuntimeLong): Unit = - assertEquals(expected, l.toHexString) - - def fromInt(x: Int): RuntimeLong = new RuntimeLong(x) - - val maxInt = fromInt(Int.MaxValue) - val minInt = fromInt(Int.MinValue) - val one = fromInt(1) - val billion = fromInt(1000000000) - - val `4503599627370510L` = new RuntimeLong(14, 0, 256) - val `613354684553L` = new RuntimeLong(639113, 146235, 0) - val `9863155567412L` = new RuntimeLong(2247476, 2351559, 0) - val `3632147899696541255L` = new RuntimeLong(1568327, 2954580, 206463) - val `7632147899696541255L` = new RuntimeLong(2616903, 1593290, 433837) - - val minValue = new RuntimeLong(0, 0, 524288) - val minus1 = new RuntimeLong(4194303, 4194303, 1048575) - val minus2 = new RuntimeLong(4194302, 4194303, 1048575) - val minus3 = new RuntimeLong(4194301, 4194303, 1048575) - val minus4 = new RuntimeLong(4194300, 4194303, 1048575) - val minus15 = new RuntimeLong(4194289, 4194303, 1048575) - val minus16 = new RuntimeLong(4194288, 4194303, 1048575) - - @Test def should_correctly_implement_negation(): Unit = { - assertHexEquals("fffffffffffffffb", -fromInt(5)) - assertHexEquals("0", -fromInt(0)) - assertHexEquals("80000000", -minInt) - } - - @Test def should_correctly_implement_comparison(): Unit = { - assertEquals(true, fromInt(7) < fromInt(15)) - assertEquals(false, fromInt(15) < fromInt(15)) - assertEquals(true, fromInt(15) <= fromInt(15)) - assertEquals(true, fromInt(14) <= fromInt(15)) - assertEquals(false, fromInt(15) > fromInt(15)) - assertEquals(false, fromInt(14) > fromInt(15)) - assertEquals(true, fromInt(16) > fromInt(15)) - assertEquals(true, fromInt(15) >= fromInt(15)) - assertEquals(false, fromInt(14) >= fromInt(15)) - assertEquals(true, fromInt(16) >= fromInt(15)) - } - - @Test def should_correctly_implement_addition(): Unit = { - assertHexEquals("16", fromInt(7) + fromInt(15)) - assertHexEquals("fffffffe", maxInt + maxInt) - assertHexEquals("80000000", maxInt + one) - } - - @Test def should_correctly_implement_subtraction(): Unit = { - assertHexEquals("fffffffffffffff8", fromInt(7) - fromInt(15)) - assertHexEquals("0", maxInt - maxInt) - } - - @Test def should_correctly_implement_multiplication(): Unit = { - assertHexEquals("69", fromInt(7) * fromInt(15)) - assertHexEquals("ffffffffffffff97", fromInt(-7) * fromInt(15)) - assertHexEquals("3fffffff00000001", maxInt * maxInt) - assertHexEquals("ffbfffffffffffc8", `4503599627370510L` * fromInt(-4)) - } - - @Test def should_correctly_implement_division(): Unit = { - assertHexEquals("0", fromInt(7) / fromInt(15)) - assertHexEquals("4", fromInt(24) / fromInt(5)) - assertHexEquals("fffffffffffffffc", fromInt(24) / fromInt(-5)) - assertHexEquals("ffffffffe6666667", maxInt / fromInt(-5)) - assertHexEquals("2", maxInt / billion) - assertHexEquals("2", (maxInt+one) / billion) - - assertHexEquals("1", minValue / minValue) - assertHexEquals("8000000000000000", minValue / minus1) - assertHexEquals("4000000000000000", minValue / minus2) - assertHexEquals("2aaaaaaaaaaaaaaa", minValue / minus3) - assertHexEquals("2000000000000000", minValue / minus4) - assertHexEquals("888888888888888", minValue / minus15) - assertHexEquals("800000000000000", minValue / minus16) - - assertHexEquals("0", `7632147899696541255L` / minValue) - assertHexEquals("961529ec0d5811b9", `7632147899696541255L` / minus1) - assertHexEquals("cb0a94f606ac08dd", `7632147899696541255L` / minus2) - assertHexEquals("dcb1b8a40472b093", `7632147899696541255L` / minus3) - assertHexEquals("e5854a7b0356046f", `7632147899696541255L` / minus4) - assertHexEquals("f8f05820cdb089b7", `7632147899696541255L` / minus15) - assertHexEquals("f961529ec0d5811c", `7632147899696541255L` / minus16) - } - - @Test def should_correctly_implement_modulus(): Unit = { - assertHexEquals("7", fromInt(7) % fromInt(15)) - assertHexEquals("4", fromInt(24) % fromInt(5)) - assertHexEquals("4", fromInt(24) % fromInt(-5)) - assertHexEquals("8ca6bff", maxInt % billion) - assertHexEquals("8ca6c00", (maxInt+one) % billion) - assertHexEquals("2", maxInt % fromInt(-5)) - - assertHexEquals("0", minValue % minValue) - assertHexEquals("0", minValue % minus1) - assertHexEquals("0", minValue % minus2) - assertHexEquals("fffffffffffffffe", minValue % minus3) - assertHexEquals("0", minValue % minus4) - assertHexEquals("fffffffffffffff8", minValue % minus15) - assertHexEquals("0", minValue % minus16) - - assertHexEquals("69ead613f2a7ee47", `7632147899696541255L` % minValue) - assertHexEquals("0", `7632147899696541255L` % minus1) - assertHexEquals("1", `7632147899696541255L` % minus2) - assertHexEquals("0", `7632147899696541255L` % minus3) - assertHexEquals("3", `7632147899696541255L` % minus4) - assertHexEquals("0", `7632147899696541255L` % minus15) - assertHexEquals("7", `7632147899696541255L` % minus16) - } - - @Test def should_correctly_implement_toString(): Unit = { - assertEquals("2147483647", maxInt.toString) - assertEquals("-50", fromInt(-50).toString) - assertEquals("-1000000000", fromInt(-1000000000).toString) - assertEquals("2147483648", (maxInt+one).toString) - assertEquals("-2147483648", minInt.toString) - } - - @Test def should_correctly_implement_fromDouble(): Unit = { - assertHexEquals("4", fromDouble(4.5)) - assertHexEquals("fffffffffffffffc", fromDouble(-4.5)) - } - - @Test def should_correctly_implement_toDouble(): Unit = { - assertEquals(5.0, fromInt(5).toDouble, 0.0) - assertEquals(2147483648.0, (maxInt+one).toDouble, 0.0) - } - - @Test def should_correctly_implement_numberOfLeadingZeros(): Unit = { - assertEquals(64, fromInt(0).numberOfLeadingZeros) - assertEquals(63, fromInt(1).numberOfLeadingZeros) - assertEquals(0, fromInt(-1).numberOfLeadingZeros) - assertEquals(62, fromInt(2).numberOfLeadingZeros) - } - - @Test def should_implement_hashCode_according_to_spec_in_j_l_Long(): Unit = { - assertEquals(0, fromInt(0).hashCode()) - assertEquals(55, fromInt(55).hashCode()) - assertEquals(11, fromInt(-12).hashCode()) - assertEquals(10006548, fromInt(10006548).hashCode()) - assertEquals(1098747, fromInt(-1098748).hashCode()) - - assertEquals(-825638905, `613354684553L`.hashCode()) - assertEquals(1910653900, `9863155567412L`.hashCode()) - assertEquals(1735398658, `3632147899696541255L`.hashCode()) - assertEquals(-1689438124, `7632147899696541255L`.hashCode()) - } - -} From b3f5839e7b4f88e0c94457f0d37d7befdb392ab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 5 Jun 2017 16:50:24 +0200 Subject: [PATCH 0316/2665] Fix #2830: Move internal annotations to `js.annotations.internal`. --- .../org/scalajs/core/compiler/JSDefinitions.scala | 13 +++++++------ .../scalajs/core/compiler/PreTyperComponent.scala | 7 ++++--- .../org/scalajs/core/compiler/PrepJSInterop.scala | 2 -- .../compiler/test/InternalAnnotationsTest.scala | 4 ++-- .../annotation/{ => internal}/ExposedJSMember.scala | 2 +- .../js/annotation/{ => internal}/RawJSType.scala | 2 +- .../{ => internal}/SJSDefinedAnonymousClass.scala | 2 +- .../{ => internal}/WasPublicBeforeTyper.scala | 2 +- 8 files changed, 17 insertions(+), 17 deletions(-) rename library/src/main/scala/scala/scalajs/js/annotation/{ => internal}/ExposedJSMember.scala (95%) rename library/src/main/scala/scala/scalajs/js/annotation/{ => internal}/RawJSType.scala (95%) rename library/src/main/scala/scala/scalajs/js/annotation/{ => internal}/SJSDefinedAnonymousClass.scala (86%) rename library/src/main/scala/scala/scalajs/js/annotation/{ => internal}/WasPublicBeforeTyper.scala (87%) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index c5a1d3b575..cfa52568fa 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -60,14 +60,18 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val JSImportAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSImport") lazy val JSGlobalAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSGlobal") lazy val JSGlobalScopeAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSGlobalScope") - lazy val SJSDefinedAnonymousClassAnnotation = getRequiredClass("scala.scalajs.js.annotation.SJSDefinedAnonymousClass") - lazy val HasJSNativeLoadSpecAnnotation = getRequiredClass("scala.scalajs.js.annotation.internal.HasJSNativeLoadSpec") - lazy val JSOptionalAnnotation = getRequiredClass("scala.scalajs.js.annotation.internal.JSOptional") lazy val JavaDefaultMethodAnnotation = getRequiredClass("scala.scalajs.js.annotation.JavaDefaultMethod") lazy val JSImportNamespaceObject = getRequiredModule("scala.scalajs.js.annotation.JSImport.Namespace") + lazy val ExposedJSMemberAnnot = getRequiredClass("scala.scalajs.js.annotation.internal.ExposedJSMember") + lazy val HasJSNativeLoadSpecAnnotation = getRequiredClass("scala.scalajs.js.annotation.internal.HasJSNativeLoadSpec") + lazy val JSOptionalAnnotation = getRequiredClass("scala.scalajs.js.annotation.internal.JSOptional") + lazy val RawJSTypeAnnot = getRequiredClass("scala.scalajs.js.annotation.internal.RawJSType") + lazy val SJSDefinedAnonymousClassAnnotation = getRequiredClass("scala.scalajs.js.annotation.internal.SJSDefinedAnonymousClass") + lazy val WasPublicBeforeTyperClass = getRequiredClass("scala.scalajs.js.annotation.internal.WasPublicBeforeTyper") + lazy val JSAnyTpe = JSAnyClass.toTypeConstructor lazy val JSObjectTpe = JSObjectClass.toTypeConstructor @@ -96,9 +100,6 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val JSConstructorTagModule = getRequiredModule("scala.scalajs.js.ConstructorTag") lazy val JSConstructorTag_materialize = getMemberMethod(JSConstructorTagModule, newTermName("materialize")) - lazy val RawJSTypeAnnot = getRequiredClass("scala.scalajs.js.annotation.RawJSType") - lazy val ExposedJSMemberAnnot = getRequiredClass("scala.scalajs.js.annotation.ExposedJSMember") - lazy val SpecialPackageModule = getPackageObject("scala.scalajs.js.special") lazy val Special_delete = getMemberMethod(SpecialPackageModule, newTermName("delete")) lazy val Special_debugger = getMemberMethod(SpecialPackageModule, newTermName("debugger")) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PreTyperComponent.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PreTyperComponent.scala index 126e7e09fd..7d1b158952 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PreTyperComponent.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PreTyperComponent.scala @@ -123,12 +123,13 @@ abstract class PreTyperComponent extends plugins.PluginComponent private val scalajs = newTermName("scalajs") private val js = newTermName("js") + private val internal_ = newTermName("internal") private val wasPublicBeforeTyper = newTypeName("WasPublicBeforeTyper") private def anonymousClassMethodWasPublicAnnotation: Tree = { - val runtimePackage = Select(Select(Select(Select(Ident(nme.ROOTPKG), - nme.scala_), scalajs), js), nme.annotation) - val cls = Select(runtimePackage, wasPublicBeforeTyper) + val cls = Select(Select(Select(Select(Select(Select(Ident(nme.ROOTPKG), + nme.scala_), scalajs), js), nme.annotation), internal_), + wasPublicBeforeTyper) Apply(Select(New(cls), nme.CONSTRUCTOR), Nil) } } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 0a046d54b2..46c892cfe8 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -1324,8 +1324,6 @@ abstract class PrepJSInterop extends plugins.PluginComponent } private lazy val ScalaEnumClass = getRequiredClass("scala.Enumeration") - private lazy val WasPublicBeforeTyperClass = - getRequiredClass("scala.scalajs.js.annotation.WasPublicBeforeTyper") /** checks if the primary constructor of the ClassDef `cldef` does not * take any arguments diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/InternalAnnotationsTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/InternalAnnotationsTest.scala index 3de116738c..759521d419 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/InternalAnnotationsTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/InternalAnnotationsTest.scala @@ -28,11 +28,11 @@ class InternalAnnotationsTest extends DirectTest with TestHelpers { @Test def jsOptional: Unit = { - test("JSOptional", "scala.scalajs.js.annotation.internal.JSOptional") + test("JSOptional") } private def test(annotation: String): Unit = - test(annotation, s"scala.scalajs.js.annotation.$annotation") + test(annotation, s"scala.scalajs.js.annotation.internal.$annotation") private def test(annotation: String, annotFullName: String): Unit = { s""" diff --git a/library/src/main/scala/scala/scalajs/js/annotation/ExposedJSMember.scala b/library/src/main/scala/scala/scalajs/js/annotation/internal/ExposedJSMember.scala similarity index 95% rename from library/src/main/scala/scala/scalajs/js/annotation/ExposedJSMember.scala rename to library/src/main/scala/scala/scalajs/js/annotation/internal/ExposedJSMember.scala index da830cfad7..91ebd44ff3 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/ExposedJSMember.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/internal/ExposedJSMember.scala @@ -7,7 +7,7 @@ \* */ -package scala.scalajs.js.annotation +package scala.scalajs.js.annotation.internal /** IMPLEMENTATION DETAIL: Marks the annotated member as exposed as a JS member. * diff --git a/library/src/main/scala/scala/scalajs/js/annotation/RawJSType.scala b/library/src/main/scala/scala/scalajs/js/annotation/internal/RawJSType.scala similarity index 95% rename from library/src/main/scala/scala/scalajs/js/annotation/RawJSType.scala rename to library/src/main/scala/scala/scalajs/js/annotation/internal/RawJSType.scala index a5bb77169c..23f0b4f71c 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/RawJSType.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/internal/RawJSType.scala @@ -8,7 +8,7 @@ -package scala.scalajs.js.annotation +package scala.scalajs.js.annotation.internal /** Marks the annotated class, trait or object as a raw JavaScript type. * diff --git a/library/src/main/scala/scala/scalajs/js/annotation/SJSDefinedAnonymousClass.scala b/library/src/main/scala/scala/scalajs/js/annotation/internal/SJSDefinedAnonymousClass.scala similarity index 86% rename from library/src/main/scala/scala/scalajs/js/annotation/SJSDefinedAnonymousClass.scala rename to library/src/main/scala/scala/scalajs/js/annotation/internal/SJSDefinedAnonymousClass.scala index dfda86c554..e424c88c4d 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/SJSDefinedAnonymousClass.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/internal/SJSDefinedAnonymousClass.scala @@ -1,4 +1,4 @@ -package scala.scalajs.js.annotation +package scala.scalajs.js.annotation.internal /** IMPLEMENTATION DETAIL: Marks anonymous Scala.js-defined JS classes. * diff --git a/library/src/main/scala/scala/scalajs/js/annotation/WasPublicBeforeTyper.scala b/library/src/main/scala/scala/scalajs/js/annotation/internal/WasPublicBeforeTyper.scala similarity index 87% rename from library/src/main/scala/scala/scalajs/js/annotation/WasPublicBeforeTyper.scala rename to library/src/main/scala/scala/scalajs/js/annotation/internal/WasPublicBeforeTyper.scala index 5fbe18b0a2..d32b5cc54f 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/WasPublicBeforeTyper.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/internal/WasPublicBeforeTyper.scala @@ -1,4 +1,4 @@ -package scala.scalajs.js.annotation +package scala.scalajs.js.annotation.internal /** IMPLEMENTATION DETAIL: Marks public members of anonymous classes before typer. * From d9abdb8c0afe64cc8138f35a79ecf0feba054ae7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 5 Jun 2017 16:54:28 +0200 Subject: [PATCH 0317/2665] Remove the unused internal annotation `HasJSNativeLoadSpec`. It has stopped being used in 602828200d639ab42292daba26e7fd6eb5383569. --- .../scalajs/core/compiler/JSDefinitions.scala | 1 - .../scalajs/core/compiler/PrepJSInterop.scala | 4 ---- .../internal/HasJSNativeLoadSpec.scala | 20 ------------------- 3 files changed, 25 deletions(-) delete mode 100644 library/src/main/scala/scala/scalajs/js/annotation/internal/HasJSNativeLoadSpec.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index cfa52568fa..90a50b3d1b 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -66,7 +66,6 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val JSImportNamespaceObject = getRequiredModule("scala.scalajs.js.annotation.JSImport.Namespace") lazy val ExposedJSMemberAnnot = getRequiredClass("scala.scalajs.js.annotation.internal.ExposedJSMember") - lazy val HasJSNativeLoadSpecAnnotation = getRequiredClass("scala.scalajs.js.annotation.internal.HasJSNativeLoadSpec") lazy val JSOptionalAnnotation = getRequiredClass("scala.scalajs.js.annotation.internal.JSOptional") lazy val RawJSTypeAnnot = getRequiredClass("scala.scalajs.js.annotation.internal.RawJSType") lazy val SJSDefinedAnonymousClassAnnotation = getRequiredClass("scala.scalajs.js.annotation.internal.SJSDefinedAnonymousClass") diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 46c892cfe8..7e8748c8a9 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -568,10 +568,6 @@ abstract class PrepJSInterop extends plugins.PluginComponent val optLoadSpec = checkAndComputeJSNativeLoadSpecOf(implDef.pos, sym) for (loadSpec <- optLoadSpec) jsInterop.storeJSNativeLoadSpec(sym, loadSpec) - - // Mark module classes as having the new format - if (sym.isModuleClass) - sym.addAnnotation(HasJSNativeLoadSpecAnnotation) } else { assert(sym.isTrait) // just tested in the previous `if` for (annot <- sym.annotations) { diff --git a/library/src/main/scala/scala/scalajs/js/annotation/internal/HasJSNativeLoadSpec.scala b/library/src/main/scala/scala/scalajs/js/annotation/internal/HasJSNativeLoadSpec.scala deleted file mode 100644 index 10d230b5e0..0000000000 --- a/library/src/main/scala/scala/scalajs/js/annotation/internal/HasJSNativeLoadSpec.scala +++ /dev/null @@ -1,20 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package scala.scalajs.js.annotation.internal - -/** IMPLEMENTATION DETAIL: Marks this JS native module class as having stored - * a loading spec in its IR. - * - * This is true iff the module class was compiled with Scala.js 0.6.13 or - * later. - * - * Do not use this annotation yourself. - */ -class HasJSNativeLoadSpec extends scala.annotation.StaticAnnotation From f4414fc3020be28f712c3c112935cc2fdfaf490c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 5 Jun 2017 17:35:59 +0200 Subject: [PATCH 0318/2665] Do not expose `js.Dictionary.update`. Instead, rely on the one available through the implicit conversion to `js.WrappedDictionary`. `update` was the only operation left in `js.Dictionary`. Even its sister method `apply` had already been moved exclusively to `js.WrappedDictionary`. It makes more sense that `update` also be moved there. --- library/src/main/scala/scala/scalajs/js/Dictionary.scala | 6 +----- .../src/main/scala/scala/scalajs/js/WrappedDictionary.scala | 6 +++++- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/js/Dictionary.scala b/library/src/main/scala/scala/scalajs/js/Dictionary.scala index 37235c3cd2..9381e0e4f2 100644 --- a/library/src/main/scala/scala/scalajs/js/Dictionary.scala +++ b/library/src/main/scala/scala/scalajs/js/Dictionary.scala @@ -49,11 +49,7 @@ import annotation.JSBracketAccess * methods could be used as keys in the dictionary. */ @native -sealed trait Dictionary[A] extends Any { - /** Writes a field of this object by its name. */ - @JSBracketAccess - def update(key: String, value: A): Unit = native -} +sealed trait Dictionary[A] extends Any /** Factory for [[Dictionary]] instances. */ object Dictionary { diff --git a/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala b/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala index a38ec7ccea..f9380ccd77 100644 --- a/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala +++ b/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala @@ -57,7 +57,7 @@ class WrappedDictionary[A](val dict: Dictionary[A]) } override def update(key: String, value: A): Unit = - dict.update(key, value) + dict.asInstanceOf[DictionaryRawApply[A]].rawUpdate(key, value) def +=(kv: (String, A)): this.type = { dict(kv._1) = kv._2 @@ -98,6 +98,10 @@ object WrappedDictionary { */ @JSBracketAccess def rawApply(key: String): A = native + + /** Writes a field of this object. */ + @JSBracketAccess + def rawUpdate(key: String, value: A): Unit = native } private final class DictionaryIterator[+A]( From ca3373b2d65ab59a284774354d3868d9e979c1bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 5 Jun 2017 17:42:14 +0200 Subject: [PATCH 0319/2665] Deprecate the conversion from `Long` to `js.Any`. That conversion is not lossless, as it coerces the `Long` into a `Double` to do so. We deprecate the conversion so that it does not happen by mistake. We mark the conversion as deprecated since "forever" rather than "1.0.0", as a signal that it should never be removed. Indeed, if the conversion is removed, Scala's weak conversion from `Long` to `Double` will kick in anyway, also producing the lossy behavior. We also mark two existing similar conversions in `JSNumberOps` as deprecated "forever", for the same reason. --- .../src/main/scala/scala/scalajs/js/Any.scala | 25 ++++++++++++++++--- .../scala/scala/scalajs/js/JSNumberOps.scala | 4 +-- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/js/Any.scala b/library/src/main/scala/scala/scalajs/js/Any.scala index 5e97c4890b..8a09521e72 100644 --- a/library/src/main/scala/scala/scalajs/js/Any.scala +++ b/library/src/main/scala/scala/scalajs/js/Any.scala @@ -67,8 +67,6 @@ object Any extends LowPrioAnyImplicits { value.asInstanceOf[Any] @inline implicit def fromInt(value: Int): Any = value.asInstanceOf[Any] - @inline implicit def fromLong(value: Long): Any = - value.toDouble.asInstanceOf[Any] @inline implicit def fromFloat(value: Float): Any = value.asInstanceOf[Any] @inline implicit def fromDouble(value: Double): Any = @@ -76,6 +74,18 @@ object Any extends LowPrioAnyImplicits { @inline implicit def fromString(s: String): Any = s.asInstanceOf[Any] + /* The following overload makes sure that the developer does not + * inadvertently convert a Long to a Double to fit it in a js.Any. + */ + @deprecated( + "A Long is converted to Double to be cast to js.Any. " + + "This is almost certainly not what you want. " + + "Use `.toDouble` explicitly if you need it.", + "forever") + @inline + implicit def fromLong(value: Long): Any = + value.toDouble.asInstanceOf[Any] + implicit def jsArrayOps[A](array: Array[A]): ArrayOps[A] = new ArrayOps(array) @@ -166,7 +176,16 @@ object Any extends LowPrioAnyImplicits { @inline implicit def fromJInteger(value: java.lang.Integer): Any = value.asInstanceOf[Any] - @inline implicit def fromJLong(value: java.lang.Long): Any = + /* The following overload makes sure that the developer does not + * inadvertently convert a Long to a Double to fit it in a js.Any. + */ + @deprecated( + "A Long is converted to Double to be cast to js.Any. " + + "This is almost certainly not what you want. " + + "Use `.toDouble` explicitly if you need it.", + "forever") + @inline + implicit def fromJLong(value: java.lang.Long): Any = if (value eq null) null else value.doubleValue.asInstanceOf[Any] diff --git a/library/src/main/scala/scala/scalajs/js/JSNumberOps.scala b/library/src/main/scala/scala/scalajs/js/JSNumberOps.scala index f694a7066a..ee7157260a 100644 --- a/library/src/main/scala/scala/scalajs/js/JSNumberOps.scala +++ b/library/src/main/scala/scala/scalajs/js/JSNumberOps.scala @@ -93,13 +93,13 @@ object JSNumberOps { @deprecated("A Long is converted to Double to perform JavaScript "+ "operations. This is almost certainly not what you want. "+ - "Use `.toDouble` explicitly if you need it.", "0.6.0") + "Use `.toDouble` explicitly if you need it.", "forever") implicit def enableJSNumberOps(x: Long): JSNumberOps = x.toDouble.asInstanceOf[JSNumberOps] @deprecated("A Long is converted to Double to perform JavaScript "+ "operations. This is almost certainly not what you want. "+ - "Use `.toDouble` explicitly if you need it.", "0.6.0") + "Use `.toDouble` explicitly if you need it.", "forever") implicit def enableJSNumberExtOps(x: Long): ExtOps = new ExtOps(x.toDouble.asInstanceOf[Dynamic]) } From 784d0c81a0dd3b8417ad7d4aa1cfcc9621fcc260 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 5 Jun 2017 17:53:26 +0200 Subject: [PATCH 0320/2665] Do not expose the type alias `js.WrappedDictionary.CBF`. It is not a common practice in the Scala collections library. This type alias was introduced only to avoid a long line in our source code, but it is not worth the cost of exposing it in the public API. --- .../scala/scala/scalajs/js/WrappedDictionary.scala | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala b/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala index f9380ccd77..b01f8e6c15 100644 --- a/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala +++ b/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala @@ -118,12 +118,13 @@ object WrappedDictionary { def empty[A]: WrappedDictionary[A] = new WrappedDictionary(Dictionary.empty) - type CBF[A] = CanBuildFrom[WrappedDictionary[_], (String, A), WrappedDictionary[A]] - implicit def canBuildFrom[A]: CBF[A] = new CBF[A] { - def apply(from: WrappedDictionary[_]): Builder[(String, A), WrappedDictionary[A]] = - new WrappedDictionaryBuilder[A] - def apply(): Builder[(String, A), WrappedDictionary[A]] = - new WrappedDictionaryBuilder[A] + implicit def canBuildFrom[A]: CanBuildFrom[WrappedDictionary[_], (String, A), WrappedDictionary[A]] = { + new CanBuildFrom[WrappedDictionary[_], (String, A), WrappedDictionary[A]] { + def apply(from: WrappedDictionary[_]): Builder[(String, A), WrappedDictionary[A]] = + new WrappedDictionaryBuilder[A] + def apply(): Builder[(String, A), WrappedDictionary[A]] = + new WrappedDictionaryBuilder[A] + } } class WrappedDictionaryBuilder[A] From 2ed11e9464c815330a166eeef1d4d8eafc7ed83b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 5 Jun 2017 18:04:36 +0200 Subject: [PATCH 0321/2665] Privatize `js.WrappedDictionary.WrappedDictionaryBuilder`. I don't see any reason that this class should be exposed. We also make it final for good measure. --- .../src/main/scala/scala/scalajs/js/WrappedDictionary.scala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala b/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala index b01f8e6c15..c0c8e3b1f9 100644 --- a/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala +++ b/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala @@ -127,15 +127,19 @@ object WrappedDictionary { } } - class WrappedDictionaryBuilder[A] + private final class WrappedDictionaryBuilder[A] extends Builder[(String, A), WrappedDictionary[A]] { + private[this] var dict: Dictionary[A] = Dictionary.empty + def +=(elem: (String, A)): this.type = { dict(elem._1) = elem._2 this } + def clear(): Unit = dict = Dictionary.empty + def result(): WrappedDictionary[A] = new WrappedDictionary(dict) } From 7b75c7a948cf67056127724bcf4e59052778d412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 5 Jun 2017 18:09:12 +0200 Subject: [PATCH 0322/2665] Make `js.JavaScriptException` final. --- .../src/main/scala/scala/scalajs/js/JavaScriptException.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/src/main/scala/scala/scalajs/js/JavaScriptException.scala b/library/src/main/scala/scala/scalajs/js/JavaScriptException.scala index 2995efc5ea..30034d6484 100644 --- a/library/src/main/scala/scala/scalajs/js/JavaScriptException.scala +++ b/library/src/main/scala/scala/scalajs/js/JavaScriptException.scala @@ -10,7 +10,9 @@ package scala.scalajs.js -case class JavaScriptException(exception: scala.Any) extends RuntimeException { +final case class JavaScriptException(exception: scala.Any) + extends RuntimeException { + override def getMessage(): String = exception.toString() override def fillInStackTrace(): Throwable = { From 4cfdbc997aa77e54e9521640d8dbca887566061f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 5 Jun 2017 18:33:07 +0200 Subject: [PATCH 0323/2665] Seal all "low-prio-implicit" traits in the library. We even use a self-type for ultimate sealing. --- library/src/main/scala/scala/scalajs/js/Any.scala | 6 +++++- library/src/main/scala/scala/scalajs/js/UndefOr.scala | 2 +- library/src/main/scala/scala/scalajs/js/Union.scala | 7 +++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/js/Any.scala b/library/src/main/scala/scala/scalajs/js/Any.scala index 8a09521e72..c295ac2bd1 100644 --- a/library/src/main/scala/scala/scalajs/js/Any.scala +++ b/library/src/main/scala/scala/scalajs/js/Any.scala @@ -195,7 +195,9 @@ object Any extends LowPrioAnyImplicits { value.asInstanceOf[Any] } -trait LowPrioAnyImplicits extends LowestPrioAnyImplicits { +sealed trait LowPrioAnyImplicits extends LowestPrioAnyImplicits { + this: Any.type => + implicit def wrapArray[A](array: Array[A]): WrappedArray[A] = new WrappedArray(array) implicit def wrapDictionary[A](dict: Dictionary[A]): WrappedDictionary[A] = @@ -203,6 +205,8 @@ trait LowPrioAnyImplicits extends LowestPrioAnyImplicits { } sealed trait LowestPrioAnyImplicits { + this: Any.type => + implicit def iterableOps[A](iterable: Iterable[A]): IterableOps[A] = new IterableOps(iterable) } diff --git a/library/src/main/scala/scala/scalajs/js/UndefOr.scala b/library/src/main/scala/scala/scalajs/js/UndefOr.scala index fcf421bcf4..3cd4c4e620 100644 --- a/library/src/main/scala/scala/scalajs/js/UndefOr.scala +++ b/library/src/main/scala/scala/scalajs/js/UndefOr.scala @@ -23,7 +23,7 @@ import scala.scalajs.js.|.Evidence */ sealed trait UndefOr[+A] -sealed abstract class UndefOrLowPrioImplicits { +sealed abstract class UndefOrLowPrioImplicits { this: UndefOr.type => /** Upcast `A` to `UndefOr[B1 | B2]`. * * This needs evidence that `A <: B1 | B2`. diff --git a/library/src/main/scala/scala/scalajs/js/Union.scala b/library/src/main/scala/scala/scalajs/js/Union.scala index ad8479105b..41a378fd4b 100644 --- a/library/src/main/scala/scala/scalajs/js/Union.scala +++ b/library/src/main/scala/scala/scalajs/js/Union.scala @@ -29,7 +29,7 @@ object | { // scalastyle:ignore */ private object ReusableEvidence extends Evidence[scala.Any, scala.Any] - abstract sealed class EvidenceLowestPrioImplicits { + abstract sealed class EvidenceLowestPrioImplicits { this: Evidence.type => /** If `A <: B2`, then `A <: B1 | B2`. */ implicit def right[A, B1, B2](implicit ev: Evidence[A, B2]): Evidence[A, B1 | B2] = ReusableEvidence.asInstanceOf[Evidence[A, B1 | B2]] @@ -47,7 +47,10 @@ object | { // scalastyle:ignore ReusableEvidence.asInstanceOf[Evidence[F[A], F[B]]] } - abstract sealed class EvidenceLowPrioImplicits extends EvidenceLowestPrioImplicits { + abstract sealed class EvidenceLowPrioImplicits + extends EvidenceLowestPrioImplicits { + this: Evidence.type => + /** `Int <: Double`, because that's true in Scala.js. */ implicit def intDouble: Evidence[Int, Double] = ReusableEvidence.asInstanceOf[Evidence[Int, Double]] From b9ef78358ba49010700e86b9459bb9a827171c31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 5 Jun 2017 19:08:50 +0200 Subject: [PATCH 0324/2665] Turn most native JS traits in the library into non-native JS traits. For most of those, it does not make any practical difference, as they were sealed anyway (or we sealed them in the process). But it will be easier to convince people that native JS traits should typically not exist if we do not declare that many ourselves. Were exempted the traits that define an `apply` method, as those cannot be non-native. --- .../scala/scala/scalajs/js/Dictionary.scala | 1 - .../scala/scala/scalajs/js/JSArrayOps.scala | 69 ++- .../scala/scala/scalajs/js/JSNumberOps.scala | 15 +- .../scala/scala/scalajs/js/JSStringOps.scala | 55 +- .../scala/scalajs/js/PropertyDescriptor.scala | 23 +- .../main/scala/scala/scalajs/js/RegExp.scala | 5 +- .../scala/scala/scalajs/js/ThisFunction.scala | 1 - .../scala/scala/scalajs/js/Tuple.nodoc.scala | 514 +++++++++--------- .../main/scala/scala/scalajs/js/Tuple.scala | 12 +- .../scalajs/js/UnicodeNormalizationForm.scala | 3 +- .../scala/scalajs/js/timers/Handles.scala | 6 +- .../scalajs/runtime/EnvironmentInfo.scala | 9 +- .../scala/scalajs/runtime/LinkingInfo.scala | 26 +- .../scala/scalajs/runtime/RuntimeString.scala | 11 +- .../scala/scalajs/runtime/StackTrace.scala | 11 +- 15 files changed, 369 insertions(+), 392 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/js/Dictionary.scala b/library/src/main/scala/scala/scalajs/js/Dictionary.scala index 9381e0e4f2..dee0c9d623 100644 --- a/library/src/main/scala/scala/scalajs/js/Dictionary.scala +++ b/library/src/main/scala/scala/scalajs/js/Dictionary.scala @@ -48,7 +48,6 @@ import annotation.JSBracketAccess * call methods of [[Object js.Object]] on it, given that the name of these * methods could be used as keys in the dictionary. */ -@native sealed trait Dictionary[A] extends Any /** Factory for [[Dictionary]] instances. */ diff --git a/library/src/main/scala/scala/scalajs/js/JSArrayOps.scala b/library/src/main/scala/scala/scalajs/js/JSArrayOps.scala index 8a29a38093..9ccef2b178 100644 --- a/library/src/main/scala/scala/scalajs/js/JSArrayOps.scala +++ b/library/src/main/scala/scala/scalajs/js/JSArrayOps.scala @@ -27,7 +27,6 @@ import scala.scalajs.js.annotation._ * To enable the use of these functions on js.[[Array]]s, import the implicit * conversion [[JSArrayOps.jsArrayOps]]. */ -@native trait JSArrayOps[A] extends Object { /** @@ -37,9 +36,9 @@ trait JSArrayOps[A] extends Object { * MDN */ @JSName("indexOf") - def jsIndexOf(searchElement: A, fromIndex: Int): Int = native + def jsIndexOf(searchElement: A, fromIndex: Int): Int @JSName("indexOf") - def jsIndexOf(searchElement: A): Int = native + def jsIndexOf(searchElement: A): Int /** * The lastIndexOf() method returns the last index at which a given element @@ -49,9 +48,9 @@ trait JSArrayOps[A] extends Object { * MDN */ @JSName("lastIndexOf") - def jsLastIndexOf(searchElement: A, fromIndex: Int): Int = native + def jsLastIndexOf(searchElement: A, fromIndex: Int): Int @JSName("lastIndexOf") - def jsLastIndexOf(searchElement: A): Int = native + def jsLastIndexOf(searchElement: A): Int /** * The every method executes the provided callback function once for each @@ -83,9 +82,9 @@ trait JSArrayOps[A] extends Object { */ @JSName("every") def jsEvery[T](callbackfn: ThisFunction3[T, A, Int, Array[A], Boolean], - thisArg: T): Boolean = native + thisArg: T): Boolean @JSName("every") - def jsEvery(callbackfn: Function3[A, Int, Array[A], Boolean]): Boolean = native + def jsEvery(callbackfn: Function3[A, Int, Array[A], Boolean]): Boolean /** * some executes the callback function once for each element present in the @@ -108,13 +107,13 @@ trait JSArrayOps[A] extends Object { */ @JSName("some") def jsSome[T](callbackfn: ThisFunction3[T, A, Int, Array[A], Boolean], - thisArg: T): Boolean = native + thisArg: T): Boolean @JSName("some") - def jsSome(callbackfn: Function3[A, Int, Array[A], Boolean]): Boolean = native + def jsSome(callbackfn: Function3[A, Int, Array[A], Boolean]): Boolean @JSName("some") - def jsSome(callbackfn: Function2[A, Int, Boolean]): Boolean = native + def jsSome(callbackfn: Function2[A, Int, Boolean]): Boolean @JSName("some") - def jsSome(callbackfn: Function1[A, Boolean]): Boolean = native + def jsSome(callbackfn: Function1[A, Boolean]): Boolean /** * forEach executes the provided callback once for each element of the array @@ -138,13 +137,13 @@ trait JSArrayOps[A] extends Object { */ @JSName("forEach") def jsForEach[T](callbackfn: ThisFunction3[T, A, Int, Array[A], _], - thisArg: T): Unit = native + thisArg: T): Unit @JSName("forEach") - def jsForEach(callbackfn: Function3[A, Int, Array[A], _]): Unit = native + def jsForEach(callbackfn: Function3[A, Int, Array[A], _]): Unit @JSName("forEach") - def jsForEach(callbackfn: Function2[A, Int, _]): Unit = native + def jsForEach(callbackfn: Function2[A, Int, _]): Unit @JSName("forEach") - def jsForEach(callbackfn: Function1[A, _]): Unit = native + def jsForEach(callbackfn: Function1[A, _]): Unit /** * map calls a provided callback function once for each element in an array, @@ -166,13 +165,13 @@ trait JSArrayOps[A] extends Object { */ @JSName("map") def jsMap[B, T](callbackfn: ThisFunction3[T, A, Int, Array[A], B], - thisArg: T): Array[B] = native + thisArg: T): Array[B] @JSName("map") - def jsMap[B](callbackfn: Function3[A, Int, Array[A], B]): Array[B] = native + def jsMap[B](callbackfn: Function3[A, Int, Array[A], B]): Array[B] @JSName("map") - def jsMap[B](callbackfn: Function2[A, Int, B]): Array[B] = native + def jsMap[B](callbackfn: Function2[A, Int, B]): Array[B] @JSName("map") - def jsMap[B](callbackfn: Function1[A, B]): Array[B] = native + def jsMap[B](callbackfn: Function1[A, B]): Array[B] /** * filter calls a provided callback function once for each element in an array, @@ -198,13 +197,13 @@ trait JSArrayOps[A] extends Object { */ @JSName("filter") def jsFilter[T](callbackfn: ThisFunction3[T, A, Int, Array[A], Boolean], - thisArg: T): Array[A] = native + thisArg: T): Array[A] @JSName("filter") - def jsFilter(callbackfn: Function3[A, Int, Array[A], Boolean]): Array[A] = native + def jsFilter(callbackfn: Function3[A, Int, Array[A], Boolean]): Array[A] @JSName("filter") - def jsFilter(callbackfn: Function2[A, Int, Boolean]): Array[A] = native + def jsFilter(callbackfn: Function2[A, Int, Boolean]): Array[A] @JSName("filter") - def jsFilter(callbackfn: Function1[A, Boolean]): Array[A] = native + def jsFilter(callbackfn: Function1[A, Boolean]): Array[A] /** * reduce executes the callback function once for each element present in @@ -223,17 +222,17 @@ trait JSArrayOps[A] extends Object { * MDN */ @JSName("reduce") - def jsReduce[B](callbackfn: Function4[B, A, Int, Array[A], B], initialValue: B): B = native + def jsReduce[B](callbackfn: Function4[B, A, Int, Array[A], B], initialValue: B): B @JSName("reduce") - def jsReduce[B](callbackfn: Function3[B, A, Int, B], initialValue: B): B = native + def jsReduce[B](callbackfn: Function3[B, A, Int, B], initialValue: B): B @JSName("reduce") - def jsReduce[B](callbackfn: Function2[B, A, B], initialValue: B): B = native + def jsReduce[B](callbackfn: Function2[B, A, B], initialValue: B): B @JSName("reduce") - def jsReduce[B](callbackfn: Function4[B, A, Int, Array[A], B]): B = native + def jsReduce[B](callbackfn: Function4[B, A, Int, Array[A], B]): B @JSName("reduce") - def jsReduce[B](callbackfn: Function3[B, A, Int, B]): B = native + def jsReduce[B](callbackfn: Function3[B, A, Int, B]): B @JSName("reduce") - def jsReduce[B](callbackfn: Function2[B, A, B]): B = native + def jsReduce[B](callbackfn: Function2[B, A, B]): B /** * reduceRight executes the callback function once for each element present @@ -245,17 +244,17 @@ trait JSArrayOps[A] extends Object { * MDN */ @JSName("reduceRight") - def jsReduceRight[B](callbackfn: Function4[B, A, Int, Array[A], B], initialValue: B): B = native + def jsReduceRight[B](callbackfn: Function4[B, A, Int, Array[A], B], initialValue: B): B @JSName("reduceRight") - def jsReduceRight[B](callbackfn: Function3[B, A, Int, B], initialValue: B): B = native + def jsReduceRight[B](callbackfn: Function3[B, A, Int, B], initialValue: B): B @JSName("reduceRight") - def jsReduceRight[B](callbackfn: Function2[B, A, B], initialValue: B): B = native + def jsReduceRight[B](callbackfn: Function2[B, A, B], initialValue: B): B @JSName("reduceRight") - def jsReduceRight[B](callbackfn: Function4[B, A, Int, Array[A], B]): B = native + def jsReduceRight[B](callbackfn: Function4[B, A, Int, Array[A], B]): B @JSName("reduceRight") - def jsReduceRight[B](callbackfn: Function3[B, A, Int, B]): B = native + def jsReduceRight[B](callbackfn: Function3[B, A, Int, B]): B @JSName("reduceRight") - def jsReduceRight[B](callbackfn: Function2[B, A, B]): B = native + def jsReduceRight[B](callbackfn: Function2[B, A, B]): B } diff --git a/library/src/main/scala/scala/scalajs/js/JSNumberOps.scala b/library/src/main/scala/scala/scalajs/js/JSNumberOps.scala index ee7157260a..7267f6ef88 100644 --- a/library/src/main/scala/scala/scalajs/js/JSNumberOps.scala +++ b/library/src/main/scala/scala/scalajs/js/JSNumberOps.scala @@ -19,10 +19,9 @@ import scala.language.implicitConversions import scala.scalajs.js.annotation._ /** Operations on JavaScript numbers. */ -@native trait JSNumberOps extends Any { - def toString(radix: Int): String = native + def toString(radix: Int): String /** * Returns a string representation of number that does not use exponential @@ -34,8 +33,8 @@ trait JSNumberOps extends Any { * * MDN */ - def toFixed(fractionDigits: Int): String = native - def toFixed(): String = native + def toFixed(fractionDigits: Int): String + def toFixed(): String /** * Returns a string representing a Number object in exponential notation with one @@ -51,8 +50,8 @@ trait JSNumberOps extends Any { * * MDN */ - def toExponential(fractionDigits: Int): String = native - def toExponential(): String = native + def toExponential(fractionDigits: Int): String + def toExponential(): String /** * Returns a string representing a Number object in fixed-point or exponential @@ -65,8 +64,8 @@ trait JSNumberOps extends Any { * * MDN */ - def toPrecision(precision: Int): String = native - def toPrecision(): String = native + def toPrecision(precision: Int): String + def toPrecision(): String } object JSNumberOps { diff --git a/library/src/main/scala/scala/scalajs/js/JSStringOps.scala b/library/src/main/scala/scala/scalajs/js/JSStringOps.scala index e7eace5c57..a64d8d04aa 100644 --- a/library/src/main/scala/scala/scalajs/js/JSStringOps.scala +++ b/library/src/main/scala/scala/scalajs/js/JSStringOps.scala @@ -23,7 +23,6 @@ import scala.scalajs.js.annotation._ * The methods with an equivalent signature in [[java.lang.String String]] but * with a different meaning are prefixed by `js` in this trait. */ -@native trait JSStringOps extends Any { /** @@ -35,9 +34,9 @@ trait JSStringOps extends Any { * MDN */ @JSName("indexOf") - def jsIndexOf(searchString: String, position: Int): Int = native + def jsIndexOf(searchString: String, position: Int): Int @JSName("indexOf") - def jsIndexOf(searchString: String): Int = native + def jsIndexOf(searchString: String): Int /** * Returns the index within the calling String object of the last occurrence @@ -47,9 +46,9 @@ trait JSStringOps extends Any { * MDN */ @JSName("lastIndexOf") - def jsLastIndexOf(searchString: String, position: Int): Int = native + def jsLastIndexOf(searchString: String, position: Int): Int @JSName("lastIndexOf") - def jsLastIndexOf(searchString: String): Int = native + def jsLastIndexOf(searchString: String): Int /** * Returns a number indicating whether a reference string comes before or @@ -61,7 +60,7 @@ trait JSStringOps extends Any { * * MDN */ - def localeCompare(that: String): Int = native + def localeCompare(that: String): Int /** * Used to retrieve the matches when matching a string against a regular @@ -78,8 +77,8 @@ trait JSStringOps extends Any { * * MDN */ - def `match`(regexp: String): Array[String] = native - def `match`(regexp: RegExp): Array[String] = native + def `match`(regexp: String): Array[String] + def `match`(regexp: RegExp): Array[String] /** * Returns a new string with some or all matches of a pattern replaced by a @@ -96,13 +95,13 @@ trait JSStringOps extends Any { * MDN */ @JSName("replace") - def jsReplace(searchValue: String, replaceValue: String): String = native + def jsReplace(searchValue: String, replaceValue: String): String @JSName("replace") - def jsReplace(searchValue: String, replaceValue: Any): String = native + def jsReplace(searchValue: String, replaceValue: Any): String @JSName("replace") - def jsReplace(searchValue: RegExp, replaceValue: String): String = native + def jsReplace(searchValue: RegExp, replaceValue: String): String @JSName("replace") - def jsReplace(searchValue: RegExp, replaceValue: Any): String = native + def jsReplace(searchValue: RegExp, replaceValue: Any): String /** * If successful, search returns the index of the regular expression inside @@ -115,8 +114,8 @@ trait JSStringOps extends Any { * * MDN */ - def search(regexp: String): Int = native - def search(regexp: RegExp): Int = native + def search(regexp: String): Int + def search(regexp: RegExp): Int /** * slice extracts the text from one string and returns a new string. Changes @@ -132,9 +131,9 @@ trait JSStringOps extends Any { * MDN */ @JSName("slice") - def jsSlice(start: Int, end: Int): String = native + def jsSlice(start: Int, end: Int): String @JSName("slice") - def jsSlice(start: Int): String = native + def jsSlice(start: Int): String /** * Splits a String object into an array of strings by separating the string @@ -156,13 +155,13 @@ trait JSStringOps extends Any { * MDN */ @JSName("split") - def jsSplit(separator: String, limit: Int): Array[String] = native + def jsSplit(separator: String, limit: Int): Array[String] @JSName("split") - def jsSplit(separator: String): Array[String] = native + def jsSplit(separator: String): Array[String] @JSName("split") - def jsSplit(separator: RegExp, limit: Int): Array[String] = native + def jsSplit(separator: RegExp, limit: Int): Array[String] @JSName("split") - def jsSplit(separator: RegExp): Array[String] = native + def jsSplit(separator: RegExp): Array[String] /** * Returns a subset of a string between one index and another, or through @@ -171,9 +170,9 @@ trait JSStringOps extends Any { * MDN */ @JSName("substring") - def jsSubstring(start: Int, end: Int): String = native + def jsSubstring(start: Int, end: Int): String @JSName("substring") - def jsSubstring(start: Int): String = native + def jsSubstring(start: Int): String /** * The toLocaleLowerCase method returns the value of the string converted to @@ -185,7 +184,7 @@ trait JSStringOps extends Any { * * MDN */ - def toLocaleLowerCase(): String = native + def toLocaleLowerCase(): String /** * The toLocaleUpperCase method returns the value of the string converted to @@ -197,13 +196,17 @@ trait JSStringOps extends Any { * * MDN */ - def toLocaleUpperCase(): String = native + def toLocaleUpperCase(): String /** ECMAScript 6 * Returns the Unicode Normalization Form of this string. */ - def normalize( - form: UnicodeNormalizationForm = UnicodeNormalizationForm.NFC): String = native + def normalize(form: UnicodeNormalizationForm): String + + /** ECMAScript 6 + * Returns the Unicode Normalization Form of this string, with the NFC form. + */ + def normalize(): String } object JSStringOps { diff --git a/library/src/main/scala/scala/scalajs/js/PropertyDescriptor.scala b/library/src/main/scala/scala/scalajs/js/PropertyDescriptor.scala index 676ddef976..58e6f67670 100644 --- a/library/src/main/scala/scala/scalajs/js/PropertyDescriptor.scala +++ b/library/src/main/scala/scala/scalajs/js/PropertyDescriptor.scala @@ -10,12 +10,21 @@ package scala.scalajs.js -@native +import scala.scalajs.js + trait PropertyDescriptor extends Object { - var configurable: Boolean = native - var enumerable: Boolean = native - var value: Any = native - var writable: Boolean = native - var get: Function0[Any] = native - var set: Function1[Any, Any] = native + // All kinds of property descriptors + + var configurable: js.UndefOr[Boolean] = js.undefined + var enumerable: js.UndefOr[Boolean] = js.undefined + + // Data descriptors + + var value: js.UndefOr[scala.Any] = js.undefined + var writable: js.UndefOr[Boolean] = js.undefined + + // Accessor descriptors + + var get: js.UndefOr[js.Function0[scala.Any]] = js.undefined + var set: js.UndefOr[js.Function1[scala.Any, scala.Any]] = js.undefined } diff --git a/library/src/main/scala/scala/scalajs/js/RegExp.scala b/library/src/main/scala/scala/scalajs/js/RegExp.scala index 3a9281465a..33ae1c5e7f 100644 --- a/library/src/main/scala/scala/scalajs/js/RegExp.scala +++ b/library/src/main/scala/scala/scalajs/js/RegExp.scala @@ -110,9 +110,8 @@ class RegExp(pattern: String, flags: String = "") extends Object { object RegExp extends Object { def apply(pattern: String, flags: String = ""): RegExp = native - @native trait ExecResult extends Array[UndefOr[String]] { - var index: Int = native - var input: String = native + var index: Int + var input: String } } diff --git a/library/src/main/scala/scala/scalajs/js/ThisFunction.scala b/library/src/main/scala/scala/scalajs/js/ThisFunction.scala index ad7532a29f..981d10922a 100644 --- a/library/src/main/scala/scala/scalajs/js/ThisFunction.scala +++ b/library/src/main/scala/scala/scalajs/js/ThisFunction.scala @@ -20,7 +20,6 @@ import scala.language.implicitConversions * * @see [[http://www.scala-js.org/doc/calling-javascript.html Calling JavaScript from Scala.js]] */ -@native trait ThisFunction extends Function object ThisFunction { diff --git a/library/src/main/scala/scala/scalajs/js/Tuple.nodoc.scala b/library/src/main/scala/scala/scalajs/js/Tuple.nodoc.scala index 89a79da575..5089ff4ba4 100644 --- a/library/src/main/scala/scala/scalajs/js/Tuple.nodoc.scala +++ b/library/src/main/scala/scala/scalajs/js/Tuple.nodoc.scala @@ -19,12 +19,11 @@ import scala.language.implicitConversions * * @see [[Tuple2]] */ -@native sealed trait Tuple4[+T1, +T2, +T3, +T4] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native + @JSName("0") val _1: T1 + @JSName("1") val _2: T2 + @JSName("2") val _3: T3 + @JSName("3") val _4: T4 } object Tuple4 { @@ -41,19 +40,17 @@ object Tuple4 { (t._1, t._2, t._3, t._4) } - /** * A tuple "view" of 5 elements of a JavaScript [[Array]]. * * @see [[Tuple2]] */ -@native sealed trait Tuple5[+T1, +T2, +T3, +T4, +T5] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native + @JSName("0") val _1: T1 + @JSName("1") val _2: T2 + @JSName("2") val _3: T3 + @JSName("3") val _4: T4 + @JSName("4") val _5: T5 } object Tuple5 { @@ -75,14 +72,13 @@ object Tuple5 { * * @see [[Tuple2]] */ -@native sealed trait Tuple6[+T1, +T2, +T3, +T4, +T5, +T6] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native + @JSName("0") val _1: T1 + @JSName("1") val _2: T2 + @JSName("2") val _3: T3 + @JSName("3") val _4: T4 + @JSName("4") val _5: T5 + @JSName("5") val _6: T6 } object Tuple6 { @@ -104,15 +100,14 @@ object Tuple6 { * * @see [[Tuple2]] */ -@native sealed trait Tuple7[+T1, +T2, +T3, +T4, +T5, +T6, +T7] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native + @JSName("0") val _1: T1 + @JSName("1") val _2: T2 + @JSName("2") val _3: T3 + @JSName("3") val _4: T4 + @JSName("4") val _5: T5 + @JSName("5") val _6: T6 + @JSName("6") val _7: T7 } object Tuple7 { @@ -134,16 +129,15 @@ object Tuple7 { * * @see [[Tuple2]] */ -@native sealed trait Tuple8[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native + @JSName("0") val _1: T1 + @JSName("1") val _2: T2 + @JSName("2") val _3: T3 + @JSName("3") val _4: T4 + @JSName("4") val _5: T5 + @JSName("5") val _6: T6 + @JSName("6") val _7: T7 + @JSName("7") val _8: T8 } object Tuple8 { @@ -165,17 +159,16 @@ object Tuple8 { * * @see [[Tuple2]] */ -@native sealed trait Tuple9[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native + @JSName("0") val _1: T1 + @JSName("1") val _2: T2 + @JSName("2") val _3: T3 + @JSName("3") val _4: T4 + @JSName("4") val _5: T5 + @JSName("5") val _6: T6 + @JSName("6") val _7: T7 + @JSName("7") val _8: T8 + @JSName("8") val _9: T9 } object Tuple9 { @@ -197,18 +190,17 @@ object Tuple9 { * * @see [[Tuple2]] */ -@native sealed trait Tuple10[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native + @JSName("0") val _1: T1 + @JSName("1") val _2: T2 + @JSName("2") val _3: T3 + @JSName("3") val _4: T4 + @JSName("4") val _5: T5 + @JSName("5") val _6: T6 + @JSName("6") val _7: T7 + @JSName("7") val _8: T8 + @JSName("8") val _9: T9 + @JSName("9") val _10: T10 } object Tuple10 { @@ -230,19 +222,18 @@ object Tuple10 { * * @see [[Tuple2]] */ -@native sealed trait Tuple11[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native - @JSName("10") val _11: T11 = native + @JSName("0") val _1: T1 + @JSName("1") val _2: T2 + @JSName("2") val _3: T3 + @JSName("3") val _4: T4 + @JSName("4") val _5: T5 + @JSName("5") val _6: T6 + @JSName("6") val _7: T7 + @JSName("7") val _8: T8 + @JSName("8") val _9: T9 + @JSName("9") val _10: T10 + @JSName("10") val _11: T11 } object Tuple11 { @@ -264,20 +255,19 @@ object Tuple11 { * * @see [[Tuple2]] */ -@native sealed trait Tuple12[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native - @JSName("10") val _11: T11 = native - @JSName("11") val _12: T12 = native + @JSName("0") val _1: T1 + @JSName("1") val _2: T2 + @JSName("2") val _3: T3 + @JSName("3") val _4: T4 + @JSName("4") val _5: T5 + @JSName("5") val _6: T6 + @JSName("6") val _7: T7 + @JSName("7") val _8: T8 + @JSName("8") val _9: T9 + @JSName("9") val _10: T10 + @JSName("10") val _11: T11 + @JSName("11") val _12: T12 } object Tuple12 { @@ -299,21 +289,20 @@ object Tuple12 { * * @see [[Tuple2]] */ -@native sealed trait Tuple13[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native - @JSName("10") val _11: T11 = native - @JSName("11") val _12: T12 = native - @JSName("12") val _13: T13 = native + @JSName("0") val _1: T1 + @JSName("1") val _2: T2 + @JSName("2") val _3: T3 + @JSName("3") val _4: T4 + @JSName("4") val _5: T5 + @JSName("5") val _6: T6 + @JSName("6") val _7: T7 + @JSName("7") val _8: T8 + @JSName("8") val _9: T9 + @JSName("9") val _10: T10 + @JSName("10") val _11: T11 + @JSName("11") val _12: T12 + @JSName("12") val _13: T13 } object Tuple13 { @@ -335,22 +324,21 @@ object Tuple13 { * * @see [[Tuple2]] */ -@native sealed trait Tuple14[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native - @JSName("10") val _11: T11 = native - @JSName("11") val _12: T12 = native - @JSName("12") val _13: T13 = native - @JSName("13") val _14: T14 = native + @JSName("0") val _1: T1 + @JSName("1") val _2: T2 + @JSName("2") val _3: T3 + @JSName("3") val _4: T4 + @JSName("4") val _5: T5 + @JSName("5") val _6: T6 + @JSName("6") val _7: T7 + @JSName("7") val _8: T8 + @JSName("8") val _9: T9 + @JSName("9") val _10: T10 + @JSName("10") val _11: T11 + @JSName("11") val _12: T12 + @JSName("12") val _13: T13 + @JSName("13") val _14: T14 } object Tuple14 { @@ -372,23 +360,22 @@ object Tuple14 { * * @see [[Tuple2]] */ -@native sealed trait Tuple15[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native - @JSName("10") val _11: T11 = native - @JSName("11") val _12: T12 = native - @JSName("12") val _13: T13 = native - @JSName("13") val _14: T14 = native - @JSName("14") val _15: T15 = native + @JSName("0") val _1: T1 + @JSName("1") val _2: T2 + @JSName("2") val _3: T3 + @JSName("3") val _4: T4 + @JSName("4") val _5: T5 + @JSName("5") val _6: T6 + @JSName("6") val _7: T7 + @JSName("7") val _8: T8 + @JSName("8") val _9: T9 + @JSName("9") val _10: T10 + @JSName("10") val _11: T11 + @JSName("11") val _12: T12 + @JSName("12") val _13: T13 + @JSName("13") val _14: T14 + @JSName("14") val _15: T15 } object Tuple15 { @@ -410,24 +397,23 @@ object Tuple15 { * * @see [[Tuple16]] */ -@native sealed trait Tuple16[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native - @JSName("10") val _11: T11 = native - @JSName("11") val _12: T12 = native - @JSName("12") val _13: T13 = native - @JSName("13") val _14: T14 = native - @JSName("14") val _15: T15 = native - @JSName("15") val _16: T16 = native + @JSName("0") val _1: T1 + @JSName("1") val _2: T2 + @JSName("2") val _3: T3 + @JSName("3") val _4: T4 + @JSName("4") val _5: T5 + @JSName("5") val _6: T6 + @JSName("6") val _7: T7 + @JSName("7") val _8: T8 + @JSName("8") val _9: T9 + @JSName("9") val _10: T10 + @JSName("10") val _11: T11 + @JSName("11") val _12: T12 + @JSName("12") val _13: T13 + @JSName("13") val _14: T14 + @JSName("14") val _15: T15 + @JSName("15") val _16: T16 } object Tuple16 { @@ -449,25 +435,24 @@ object Tuple16 { * * @see [[Tuple2]] */ -@native sealed trait Tuple17[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native - @JSName("10") val _11: T11 = native - @JSName("11") val _12: T12 = native - @JSName("12") val _13: T13 = native - @JSName("13") val _14: T14 = native - @JSName("14") val _15: T15 = native - @JSName("15") val _16: T16 = native - @JSName("16") val _17: T17 = native + @JSName("0") val _1: T1 + @JSName("1") val _2: T2 + @JSName("2") val _3: T3 + @JSName("3") val _4: T4 + @JSName("4") val _5: T5 + @JSName("5") val _6: T6 + @JSName("6") val _7: T7 + @JSName("7") val _8: T8 + @JSName("8") val _9: T9 + @JSName("9") val _10: T10 + @JSName("10") val _11: T11 + @JSName("11") val _12: T12 + @JSName("12") val _13: T13 + @JSName("13") val _14: T14 + @JSName("14") val _15: T15 + @JSName("15") val _16: T16 + @JSName("16") val _17: T17 } object Tuple17 { @@ -489,26 +474,25 @@ object Tuple17 { * * @see [[Tuple2]] */ -@native sealed trait Tuple18[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native - @JSName("10") val _11: T11 = native - @JSName("11") val _12: T12 = native - @JSName("12") val _13: T13 = native - @JSName("13") val _14: T14 = native - @JSName("14") val _15: T15 = native - @JSName("15") val _16: T16 = native - @JSName("16") val _17: T17 = native - @JSName("17") val _18: T18 = native + @JSName("0") val _1: T1 + @JSName("1") val _2: T2 + @JSName("2") val _3: T3 + @JSName("3") val _4: T4 + @JSName("4") val _5: T5 + @JSName("5") val _6: T6 + @JSName("6") val _7: T7 + @JSName("7") val _8: T8 + @JSName("8") val _9: T9 + @JSName("9") val _10: T10 + @JSName("10") val _11: T11 + @JSName("11") val _12: T12 + @JSName("12") val _13: T13 + @JSName("13") val _14: T14 + @JSName("14") val _15: T15 + @JSName("15") val _16: T16 + @JSName("16") val _17: T17 + @JSName("17") val _18: T18 } object Tuple18 { @@ -530,27 +514,26 @@ object Tuple18 { * * @see [[Tuple2]] */ -@native sealed trait Tuple19[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native - @JSName("10") val _11: T11 = native - @JSName("11") val _12: T12 = native - @JSName("12") val _13: T13 = native - @JSName("13") val _14: T14 = native - @JSName("14") val _15: T15 = native - @JSName("15") val _16: T16 = native - @JSName("16") val _17: T17 = native - @JSName("17") val _18: T18 = native - @JSName("18") val _19: T19 = native + @JSName("0") val _1: T1 + @JSName("1") val _2: T2 + @JSName("2") val _3: T3 + @JSName("3") val _4: T4 + @JSName("4") val _5: T5 + @JSName("5") val _6: T6 + @JSName("6") val _7: T7 + @JSName("7") val _8: T8 + @JSName("8") val _9: T9 + @JSName("9") val _10: T10 + @JSName("10") val _11: T11 + @JSName("11") val _12: T12 + @JSName("12") val _13: T13 + @JSName("13") val _14: T14 + @JSName("14") val _15: T15 + @JSName("15") val _16: T16 + @JSName("16") val _17: T17 + @JSName("17") val _18: T18 + @JSName("18") val _19: T19 } object Tuple19 { @@ -572,28 +555,27 @@ object Tuple19 { * * @see [[Tuple2]] */ -@native sealed trait Tuple20[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native - @JSName("10") val _11: T11 = native - @JSName("11") val _12: T12 = native - @JSName("12") val _13: T13 = native - @JSName("13") val _14: T14 = native - @JSName("14") val _15: T15 = native - @JSName("15") val _16: T16 = native - @JSName("16") val _17: T17 = native - @JSName("17") val _18: T18 = native - @JSName("18") val _19: T19 = native - @JSName("19") val _20: T20 = native + @JSName("0") val _1: T1 + @JSName("1") val _2: T2 + @JSName("2") val _3: T3 + @JSName("3") val _4: T4 + @JSName("4") val _5: T5 + @JSName("5") val _6: T6 + @JSName("6") val _7: T7 + @JSName("7") val _8: T8 + @JSName("8") val _9: T9 + @JSName("9") val _10: T10 + @JSName("10") val _11: T11 + @JSName("11") val _12: T12 + @JSName("12") val _13: T13 + @JSName("13") val _14: T14 + @JSName("14") val _15: T15 + @JSName("15") val _16: T16 + @JSName("16") val _17: T17 + @JSName("17") val _18: T18 + @JSName("18") val _19: T19 + @JSName("19") val _20: T20 } object Tuple20 { @@ -615,29 +597,28 @@ object Tuple20 { * * @see [[Tuple2]] */ -@native sealed trait Tuple21[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20, +T21] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native - @JSName("10") val _11: T11 = native - @JSName("11") val _12: T12 = native - @JSName("12") val _13: T13 = native - @JSName("13") val _14: T14 = native - @JSName("14") val _15: T15 = native - @JSName("15") val _16: T16 = native - @JSName("16") val _17: T17 = native - @JSName("17") val _18: T18 = native - @JSName("18") val _19: T19 = native - @JSName("19") val _20: T20 = native - @JSName("20") val _21: T21 = native + @JSName("0") val _1: T1 + @JSName("1") val _2: T2 + @JSName("2") val _3: T3 + @JSName("3") val _4: T4 + @JSName("4") val _5: T5 + @JSName("5") val _6: T6 + @JSName("6") val _7: T7 + @JSName("7") val _8: T8 + @JSName("8") val _9: T9 + @JSName("9") val _10: T10 + @JSName("10") val _11: T11 + @JSName("11") val _12: T12 + @JSName("12") val _13: T13 + @JSName("13") val _14: T14 + @JSName("14") val _15: T15 + @JSName("15") val _16: T16 + @JSName("16") val _17: T17 + @JSName("17") val _18: T18 + @JSName("18") val _19: T19 + @JSName("19") val _20: T20 + @JSName("20") val _21: T21 } object Tuple21 { @@ -659,30 +640,29 @@ object Tuple21 { * * @see [[Tuple2]] */ -@native sealed trait Tuple22[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20, +T21, +T22] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native - @JSName("3") val _4: T4 = native - @JSName("4") val _5: T5 = native - @JSName("5") val _6: T6 = native - @JSName("6") val _7: T7 = native - @JSName("7") val _8: T8 = native - @JSName("8") val _9: T9 = native - @JSName("9") val _10: T10 = native - @JSName("10") val _11: T11 = native - @JSName("11") val _12: T12 = native - @JSName("12") val _13: T13 = native - @JSName("13") val _14: T14 = native - @JSName("14") val _15: T15 = native - @JSName("15") val _16: T16 = native - @JSName("16") val _17: T17 = native - @JSName("17") val _18: T18 = native - @JSName("18") val _19: T19 = native - @JSName("19") val _20: T20 = native - @JSName("20") val _21: T21 = native - @JSName("21") val _22: T22 = native + @JSName("0") val _1: T1 + @JSName("1") val _2: T2 + @JSName("2") val _3: T3 + @JSName("3") val _4: T4 + @JSName("4") val _5: T5 + @JSName("5") val _6: T6 + @JSName("6") val _7: T7 + @JSName("7") val _8: T8 + @JSName("8") val _9: T9 + @JSName("9") val _10: T10 + @JSName("10") val _11: T11 + @JSName("11") val _12: T12 + @JSName("12") val _13: T13 + @JSName("13") val _14: T14 + @JSName("14") val _15: T15 + @JSName("15") val _16: T16 + @JSName("16") val _17: T17 + @JSName("17") val _18: T18 + @JSName("18") val _19: T19 + @JSName("19") val _20: T20 + @JSName("20") val _21: T21 + @JSName("21") val _22: T22 } object Tuple22 { diff --git a/library/src/main/scala/scala/scalajs/js/Tuple.scala b/library/src/main/scala/scala/scalajs/js/Tuple.scala index 255c294eea..b7d4cf08c1 100644 --- a/library/src/main/scala/scala/scalajs/js/Tuple.scala +++ b/library/src/main/scala/scala/scalajs/js/Tuple.scala @@ -40,10 +40,9 @@ import scala.language.implicitConversions * val obj: js.Tuple2[Int, String] = (42, "foobar") * }}} */ -@native sealed trait Tuple2[+T1, +T2] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native + @JSName("0") val _1: T1 + @JSName("1") val _2: T2 } object Tuple2 { @@ -65,11 +64,10 @@ object Tuple2 { * * @see [[Tuple2]] */ -@native sealed trait Tuple3[+T1, +T2, +T3] extends Object { - @JSName("0") val _1: T1 = native - @JSName("1") val _2: T2 = native - @JSName("2") val _3: T3 = native + @JSName("0") val _1: T1 + @JSName("1") val _2: T2 + @JSName("2") val _3: T3 } object Tuple3 { diff --git a/library/src/main/scala/scala/scalajs/js/UnicodeNormalizationForm.scala b/library/src/main/scala/scala/scalajs/js/UnicodeNormalizationForm.scala index 7770e36d69..1b713730cd 100644 --- a/library/src/main/scala/scala/scalajs/js/UnicodeNormalizationForm.scala +++ b/library/src/main/scala/scala/scalajs/js/UnicodeNormalizationForm.scala @@ -16,10 +16,9 @@ package scala.scalajs.js /** A Unicode Normalization Form. * - * @see [[JSStringOps.normalize]] + * @see [[JSStringOps JSStringOps.normalize]] * @see [[http://www.unicode.org/reports/tr15/ Unicode Normalization Forms]] */ -@native sealed trait UnicodeNormalizationForm extends Any object UnicodeNormalizationForm { diff --git a/library/src/main/scala/scala/scalajs/js/timers/Handles.scala b/library/src/main/scala/scala/scalajs/js/timers/Handles.scala index 29813b5c05..50bdaf180c 100644 --- a/library/src/main/scala/scala/scalajs/js/timers/Handles.scala +++ b/library/src/main/scala/scala/scalajs/js/timers/Handles.scala @@ -17,8 +17,7 @@ import scala.scalajs.js * * May only be used to pass to [[clearTimeout]]. */ -@js.native -trait SetTimeoutHandle extends js.Any +sealed trait SetTimeoutHandle extends js.Any /** Non-Standard * A handle returned from a call to @@ -26,5 +25,4 @@ trait SetTimeoutHandle extends js.Any * * May only be used to pass to [[clearInterval]]. */ -@js.native -trait SetIntervalHandle extends js.Any +sealed trait SetIntervalHandle extends js.Any diff --git a/library/src/main/scala/scala/scalajs/runtime/EnvironmentInfo.scala b/library/src/main/scala/scala/scalajs/runtime/EnvironmentInfo.scala index d44744d4a7..59daf29c5a 100644 --- a/library/src/main/scala/scala/scalajs/runtime/EnvironmentInfo.scala +++ b/library/src/main/scala/scala/scalajs/runtime/EnvironmentInfo.scala @@ -22,28 +22,27 @@ import StackTrace.JSStackTraceElem * @groupname envInfo Scala.js environment configuration * @groupprio envInfo 1 */ -@js.native -trait EnvironmentInfo extends js.Object { +sealed trait EnvironmentInfo extends js.Object { /** The scope for Scala.js exports (i.e. objects and classes) * * @group envInfo */ - def exportsNamespace: js.Dynamic = js.native + def exportsNamespace: js.Dynamic // Can't link to java.lang.Runtime.exit - #1969 /** The function that is called by `java.lang.Runtime.exit` * * @group envInfo */ - def exitFunction: js.UndefOr[js.Function1[Int, Nothing]] = js.native + def exitFunction: js.UndefOr[js.Function1[Int, Nothing]] /** Method used to source map JavaScript stack traces * * @group envInfo */ def sourceMapper: js.UndefOr[js.Function1[ // scalastyle:ignore - js.Array[JSStackTraceElem], js.Array[JSStackTraceElem]]] = js.native + js.Array[JSStackTraceElem], js.Array[JSStackTraceElem]]] /** Dictionary of system properties to add to java.lang.System.getProperties() * diff --git a/library/src/main/scala/scala/scalajs/runtime/LinkingInfo.scala b/library/src/main/scala/scala/scalajs/runtime/LinkingInfo.scala index d4ea4b4090..b89435eaf1 100644 --- a/library/src/main/scala/scala/scalajs/runtime/LinkingInfo.scala +++ b/library/src/main/scala/scala/scalajs/runtime/LinkingInfo.scala @@ -3,42 +3,40 @@ package scala.scalajs.runtime import scala.scalajs.js /** Information about link-time configuration of Scala.js. */ -@js.native -trait LinkingInfo extends js.Object { +sealed trait LinkingInfo extends js.Object { /** Environment info. */ - val envInfo: EnvironmentInfo = js.native + val envInfo: EnvironmentInfo /** Semantics configuration. */ - val semantics: LinkingInfo.Semantics = js.native + val semantics: LinkingInfo.Semantics /** Whether we are assuming ECMAScript 6 support or not. */ - val assumingES6: Boolean = js.native + val assumingES6: Boolean /** Version of the linker */ - val linkerVersion: js.UndefOr[String] = js.native + val linkerVersion: js.UndefOr[String] /** The value of the global JavaScript `this`. */ - val globalThis: Any = js.native + val globalThis: Any } object LinkingInfo { /** Semantics configuration. */ - @js.native - trait Semantics extends js.Object { + sealed trait Semantics extends js.Object { /** Compliance level of asInstanceOfs. */ - val asInstanceOfs: Int = js.native + val asInstanceOfs: Int /** Compliance level of arrayIndexOutOfBounds. */ - val arrayIndexOutOfBounds: Int = js.native + val arrayIndexOutOfBounds: Int /** Compliance level of moduleInit. */ - val moduleInit: Int = js.native + val moduleInit: Int /** Whether floats have strict semantics. */ - val strictFloats: Boolean = js.native + val strictFloats: Boolean /** Whether we are linking in production mode. */ - val productionMode: Boolean = js.native + val productionMode: Boolean } object Semantics { diff --git a/library/src/main/scala/scala/scalajs/runtime/RuntimeString.scala b/library/src/main/scala/scala/scalajs/runtime/RuntimeString.scala index 354553c278..1595204365 100644 --- a/library/src/main/scala/scala/scalajs/runtime/RuntimeString.scala +++ b/library/src/main/scala/scala/scalajs/runtime/RuntimeString.scala @@ -22,14 +22,13 @@ private[runtime] object RuntimeString { /** Operations on a primitive JS string that are shadowed by Scala methods, * and that we need to implement these very Scala methods. */ - @js.native private trait SpecialJSStringOps extends js.Any { - def length: Int = js.native - def charCodeAt(index: Int): Int = js.native + def length: Int + def charCodeAt(index: Int): Int - def toLowerCase(): String = js.native - def toUpperCase(): String = js.native - def trim(): String = js.native + def toLowerCase(): String + def toUpperCase(): String + def trim(): String } private def specialJSStringOps(s: String): SpecialJSStringOps = diff --git a/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala b/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala index 2dc1128d2a..3c30f95da7 100644 --- a/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala +++ b/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala @@ -509,15 +509,14 @@ object StackTrace { * --------------------------------------------------------------------------- */ - @js.native trait JSStackTraceElem extends js.Object { - var declaringClass: String = js.native - var methodName: String = js.native - var fileName: String = js.native + var declaringClass: String + var methodName: String + var fileName: String /** 1-based line number */ - var lineNumber: Int = js.native + var lineNumber: Int /** 1-based optional columnNumber */ - var columnNumber: js.UndefOr[Int] = js.native + var columnNumber: js.UndefOr[Int] = js.undefined } object JSStackTraceElem { From c69a62ecd215505e6e2ebc49feefc296c06983ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 5 Jun 2017 19:19:35 +0200 Subject: [PATCH 0325/2665] Make `UndefOr.WithFilter` final. --- library/src/main/scala/scala/scalajs/js/UndefOr.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/src/main/scala/scala/scalajs/js/UndefOr.scala b/library/src/main/scala/scala/scalajs/js/UndefOr.scala index 3cd4c4e620..268eb55447 100644 --- a/library/src/main/scala/scala/scalajs/js/UndefOr.scala +++ b/library/src/main/scala/scala/scalajs/js/UndefOr.scala @@ -264,7 +264,7 @@ object UndefOrOps { * collection" contract even though it seems unlikely to matter much in a * collection with max size 1. */ - class WithFilter[A](self: UndefOr[A], p: A => Boolean) { + final class WithFilter[A](self: UndefOr[A], p: A => Boolean) { def map[B](f: A => B): UndefOr[B] = self filter p map f def flatMap[B](f: A => UndefOr[B]): UndefOr[B] = self filter p flatMap f def foreach[U](f: A => U): Unit = self filter p foreach f From 8f319a8bb6653308b04b7f344e72481336c76335 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 5 Jun 2017 19:31:17 +0200 Subject: [PATCH 0326/2665] Make the `XyzReflectiveCall` classes final. --- .../scala/scala/scalajs/runtime/BooleanReflectiveCall.scala | 2 +- .../scala/scala/scalajs/runtime/IntegerReflectiveCall.scala | 2 +- .../main/scala/scala/scalajs/runtime/LongReflectiveCall.scala | 2 +- .../main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/runtime/BooleanReflectiveCall.scala b/library/src/main/scala/scala/scalajs/runtime/BooleanReflectiveCall.scala index 9da5dc342b..f9f65c0f14 100644 --- a/library/src/main/scala/scala/scalajs/runtime/BooleanReflectiveCall.scala +++ b/library/src/main/scala/scala/scalajs/runtime/BooleanReflectiveCall.scala @@ -6,7 +6,7 @@ import java.lang.{Boolean => JBoolean} * This class and its methods are only here to properly support reflective * calls on booleans. */ -class BooleanReflectiveCall(value: Boolean) { +final class BooleanReflectiveCall(value: Boolean) { // Methods of java.lang.Boolean diff --git a/library/src/main/scala/scala/scalajs/runtime/IntegerReflectiveCall.scala b/library/src/main/scala/scala/scalajs/runtime/IntegerReflectiveCall.scala index a2197449fa..93319b5835 100644 --- a/library/src/main/scala/scala/scalajs/runtime/IntegerReflectiveCall.scala +++ b/library/src/main/scala/scala/scalajs/runtime/IntegerReflectiveCall.scala @@ -8,7 +8,7 @@ import java.lang.{Double => JDouble, Integer => JInteger} * This class and its methods are only here to properly support reflective * calls on numbers. */ -class IntegerReflectiveCall(value: Int) { +final class IntegerReflectiveCall(value: Int) { // Methods of scala.Int whose result type is different than in scala.Double diff --git a/library/src/main/scala/scala/scalajs/runtime/LongReflectiveCall.scala b/library/src/main/scala/scala/scalajs/runtime/LongReflectiveCall.scala index 70a2228b2c..9f63c875c9 100644 --- a/library/src/main/scala/scala/scalajs/runtime/LongReflectiveCall.scala +++ b/library/src/main/scala/scala/scalajs/runtime/LongReflectiveCall.scala @@ -6,7 +6,7 @@ import java.lang.{Long => JLong} * This class and its methods are only here to properly support reflective * calls on longs. */ -class LongReflectiveCall(value: Long) { +final class LongReflectiveCall(value: Long) { // Methods of java.lang.Long diff --git a/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala b/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala index f09a5d3182..24a90bf8bc 100644 --- a/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala +++ b/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala @@ -6,7 +6,7 @@ import java.lang.{Double => JDouble, Integer => JInteger} * This class and its methods are only here to properly support reflective * calls on numbers. */ -class NumberReflectiveCall(value: Double) { +final class NumberReflectiveCall(value: Double) { // Methods of java.lang.Double and java.lang.Integer From 860936972ca5063ec29729398b5f57982bbf19e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 7 Jun 2017 11:45:22 +0200 Subject: [PATCH 0327/2665] Generalize some `js.Any`s to `scala.Any`s in the library. These few references to `Any` should probably always have been `scala.Any`, but were `js.Any`s by accident. --- library/src/main/scala/scala/scalajs/js/Array.scala | 2 +- library/src/main/scala/scala/scalajs/js/Object.scala | 4 ++-- library/src/main/scala/scala/scalajs/js/package.scala | 4 ++-- .../org/scalajs/testsuite/jsinterop/MiscInteropTest.scala | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/js/Array.scala b/library/src/main/scala/scala/scalajs/js/Array.scala index 56c9fa25ae..be2a855bad 100644 --- a/library/src/main/scala/scala/scalajs/js/Array.scala +++ b/library/src/main/scala/scala/scalajs/js/Array.scala @@ -179,5 +179,5 @@ object Array extends Object { def apply[A](items: A*): Array[A] = throw new java.lang.Error("stub") /** Returns true if the given value is an array. */ - def isArray(arg: Any): Boolean = native + def isArray(arg: scala.Any): Boolean = native } diff --git a/library/src/main/scala/scala/scalajs/js/Object.scala b/library/src/main/scala/scala/scalajs/js/Object.scala index 0fd670439e..63dc520e6d 100644 --- a/library/src/main/scala/scala/scalajs/js/Object.scala +++ b/library/src/main/scala/scala/scalajs/js/Object.scala @@ -20,7 +20,7 @@ import scala.scalajs.js.annotation._ @native @JSGlobal class Object extends Any { - def this(value: Any) = this() + def this(value: scala.Any) = this() def toLocaleString(): String = native def valueOf(): scala.Any = native @@ -52,7 +52,7 @@ class Object extends Any { @JSGlobal object Object extends Object { def apply(): Object = native - def apply(value: Any): Object = native + def apply(value: scala.Any): Object = native /** Tests whether the object has a property on itself or in its prototype * chain. This method is the equivalent of `p in o` in JavaScript. diff --git a/library/src/main/scala/scala/scalajs/js/package.scala b/library/src/main/scala/scala/scalajs/js/package.scala index b105a2f88f..c9e8ed62d8 100644 --- a/library/src/main/scala/scala/scalajs/js/package.scala +++ b/library/src/main/scala/scala/scalajs/js/package.scala @@ -72,7 +72,7 @@ package object js { v.asInstanceOf[scala.AnyRef] eq undefined /** Returns the type of `x` as identified by `typeof x` in JavaScript. */ - def typeOf(x: Any): String = throw new java.lang.Error("stub") + def typeOf(x: scala.Any): String = throw new java.lang.Error("stub") /** Returns the constructor function of a JavaScript class. * @@ -87,7 +87,7 @@ package object js { tag /** Evaluates JavaScript code and returns the result. */ - @inline def eval(x: String): Any = + @inline def eval(x: String): scala.Any = js.Dynamic.global.eval(x) /** Marks the annotated class, trait or object as a native JS entity. diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala index 567d124b93..7b9f397122 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala @@ -30,7 +30,7 @@ class MiscInteropTest { assertEquals("object", typeOf(null)) assertEquals("object", typeOf(new js.Object)) assertEquals("undefined", typeOf(())) - assertEquals("function", typeOf(() => 42)) + assertEquals("function", typeOf((() => 42): js.Function)) } @Test def js_constructorOf_T_for_native_classes(): Unit = { From 8b754d4b2ed7b3bbfa4633770e32decc6643f57d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 7 Jun 2017 11:46:40 +0200 Subject: [PATCH 0328/2665] Systematically use the `js.` prefix in the `js` package. Within the `scala.scalajs.js` package, bare names such as `Any` refer to `js.Any`. It is however confusing, as we usually expect such bare names to refer to `scala.Any`. In this commit, we systematically and consistently write `js.X` everywhere, except in the very definition of `X`, where it is not allowed. --- .../src/main/scala/scala/scalajs/js/Any.scala | 198 +++++------ .../main/scala/scala/scalajs/js/Array.scala | 51 +-- .../scala/scala/scalajs/js/ArrayOps.scala | 44 ++- .../scala/scalajs/js/ConstructorTag.scala | 24 +- .../main/scala/scala/scalajs/js/Date.scala | 101 +++--- .../scala/scala/scalajs/js/Dictionary.scala | 12 +- .../main/scala/scala/scalajs/js/Dynamic.scala | 113 ++++--- .../scala/scalajs/js/DynamicImplicits.scala | 18 +- .../main/scala/scala/scalajs/js/Error.scala | 78 ++--- .../scala/scalajs/js/Function.nodoc.scala | 82 ++--- .../scala/scala/scalajs/js/Function.scala | 27 +- .../scala/scala/scalajs/js/Iterable.scala | 4 +- .../scala/scala/scalajs/js/IterableOps.scala | 4 +- .../scala/scala/scalajs/js/Iterator.scala | 6 +- .../scala/scala/scalajs/js/JSArrayOps.scala | 74 +++-- .../scala/scala/scalajs/js/JSConverters.scala | 53 +-- .../scala/scala/scalajs/js/JSNumberOps.scala | 25 +- .../main/scala/scala/scalajs/js/JSON.scala | 17 +- .../scala/scala/scalajs/js/JSStringOps.scala | 29 +- .../main/scala/scala/scalajs/js/Math.scala | 79 ++--- .../main/scala/scala/scalajs/js/Object.scala | 58 ++-- .../main/scala/scala/scalajs/js/Promise.scala | 18 +- .../scala/scalajs/js/PropertyDescriptor.scala | 2 +- .../main/scala/scala/scalajs/js/RegExp.scala | 29 +- .../main/scala/scala/scalajs/js/Symbol.scala | 30 +- .../scala/scala/scalajs/js/Thenable.scala | 22 +- .../scala/scalajs/js/ThisFunction.nodoc.scala | 78 ++--- .../scala/scala/scalajs/js/ThisFunction.scala | 104 +++--- .../scala/scala/scalajs/js/Tuple.nodoc.scala | 308 +++++++++--------- .../main/scala/scala/scalajs/js/Tuple.scala | 48 ++- .../scala/scala/scalajs/js/URIUtils.scala | 15 +- .../main/scala/scala/scalajs/js/UndefOr.scala | 66 ++-- .../scalajs/js/UnicodeNormalizationForm.scala | 14 +- .../main/scala/scala/scalajs/js/Union.scala | 6 +- .../scala/scala/scalajs/js/WrappedArray.scala | 32 +- .../scala/scalajs/js/WrappedDictionary.scala | 48 +-- .../main/scala/scala/scalajs/js/package.scala | 6 +- 37 files changed, 1000 insertions(+), 923 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/js/Any.scala b/library/src/main/scala/scala/scalajs/js/Any.scala index c295ac2bd1..1005dbec9a 100644 --- a/library/src/main/scala/scala/scalajs/js/Any.scala +++ b/library/src/main/scala/scala/scalajs/js/Any.scala @@ -16,11 +16,11 @@ package scala.scalajs.js import scala.language.implicitConversions +import scala.scalajs.js + import scala.collection.mutable import scala.collection.generic.CanBuildFrom -import annotation.ScalaJSDefined - /** Root of the hierarchy of JavaScript types. * * Subtypes of [[Any js.Any]] are JavaScript types, which have different @@ -56,23 +56,23 @@ import annotation.ScalaJSDefined trait Any extends scala.AnyRef /** Provides implicit conversions from Scala values to JavaScript values. */ -object Any extends LowPrioAnyImplicits { - @inline implicit def fromUnit(value: Unit): Any = - value.asInstanceOf[Any] - @inline implicit def fromBoolean(value: Boolean): Any = - value.asInstanceOf[Any] - @inline implicit def fromByte(value: Byte): Any = - value.asInstanceOf[Any] - @inline implicit def fromShort(value: Short): Any = - value.asInstanceOf[Any] - @inline implicit def fromInt(value: Int): Any = - value.asInstanceOf[Any] - @inline implicit def fromFloat(value: Float): Any = - value.asInstanceOf[Any] - @inline implicit def fromDouble(value: Double): Any = - value.asInstanceOf[Any] - @inline implicit def fromString(s: String): Any = - s.asInstanceOf[Any] +object Any extends js.LowPrioAnyImplicits { + @inline implicit def fromUnit(value: Unit): js.Any = + value.asInstanceOf[js.Any] + @inline implicit def fromBoolean(value: Boolean): js.Any = + value.asInstanceOf[js.Any] + @inline implicit def fromByte(value: Byte): js.Any = + value.asInstanceOf[js.Any] + @inline implicit def fromShort(value: Short): js.Any = + value.asInstanceOf[js.Any] + @inline implicit def fromInt(value: Int): js.Any = + value.asInstanceOf[js.Any] + @inline implicit def fromFloat(value: Float): js.Any = + value.asInstanceOf[js.Any] + @inline implicit def fromDouble(value: Double): js.Any = + value.asInstanceOf[js.Any] + @inline implicit def fromString(s: String): js.Any = + s.asInstanceOf[js.Any] /* The following overload makes sure that the developer does not * inadvertently convert a Long to a Double to fit it in a js.Any. @@ -83,19 +83,19 @@ object Any extends LowPrioAnyImplicits { "Use `.toDouble` explicitly if you need it.", "forever") @inline - implicit def fromLong(value: Long): Any = - value.toDouble.asInstanceOf[Any] + implicit def fromLong(value: Long): js.Any = + value.toDouble.asInstanceOf[js.Any] - implicit def jsArrayOps[A](array: Array[A]): ArrayOps[A] = - new ArrayOps(array) + implicit def jsArrayOps[A](array: js.Array[A]): js.ArrayOps[A] = + new js.ArrayOps(array) - implicit def canBuildFromArray[A]: CanBuildFrom[Array[_], A, Array[A]] = { + implicit def canBuildFromArray[A]: CanBuildFrom[Array[_], A, js.Array[A]] = { @inline - class CanBuildFromArray extends CanBuildFrom[Array[_], A, Array[A]] { - def apply(from: Array[_]): mutable.Builder[A, Array[A]] = - new ArrayOps[A] - def apply(): mutable.Builder[A, Array[A]] = - new ArrayOps[A] + class CanBuildFromArray extends CanBuildFrom[Array[_], A, js.Array[A]] { + def apply(from: js.Array[_]): mutable.Builder[A, js.Array[A]] = + new js.ArrayOps[A] + def apply(): mutable.Builder[A, js.Array[A]] = + new js.ArrayOps[A] } new CanBuildFromArray } @@ -118,63 +118,63 @@ object Any extends LowPrioAnyImplicits { * With proper SAM treatment, none of this happens, since there is no * implicit materialization of a recursive call in the first place. */ - implicit def fromFunction0[R](f: scala.Function0[R]): Function0[R] = identity(() => f()) - implicit def fromFunction1[T1, R](f: scala.Function1[T1, R]): Function1[T1, R] = identity((x1: T1) => f(x1)) - implicit def fromFunction2[T1, T2, R](f: scala.Function2[T1, T2, R]): Function2[T1, T2, R] = identity((x1: T1, x2: T2) => f(x1, x2)) - implicit def fromFunction3[T1, T2, T3, R](f: scala.Function3[T1, T2, T3, R]): Function3[T1, T2, T3, R] = identity((x1: T1, x2: T2, x3: T3) => f(x1, x2, x3)) - implicit def fromFunction4[T1, T2, T3, T4, R](f: scala.Function4[T1, T2, T3, T4, R]): Function4[T1, T2, T3, T4, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4) => f(x1, x2, x3, x4)) - implicit def fromFunction5[T1, T2, T3, T4, T5, R](f: scala.Function5[T1, T2, T3, T4, T5, R]): Function5[T1, T2, T3, T4, T5, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5) => f(x1, x2, x3, x4, x5)) - implicit def fromFunction6[T1, T2, T3, T4, T5, T6, R](f: scala.Function6[T1, T2, T3, T4, T5, T6, R]): Function6[T1, T2, T3, T4, T5, T6, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6) => f(x1, x2, x3, x4, x5, x6)) - implicit def fromFunction7[T1, T2, T3, T4, T5, T6, T7, R](f: scala.Function7[T1, T2, T3, T4, T5, T6, T7, R]): Function7[T1, T2, T3, T4, T5, T6, T7, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7) => f(x1, x2, x3, x4, x5, x6, x7)) - implicit def fromFunction8[T1, T2, T3, T4, T5, T6, T7, T8, R](f: scala.Function8[T1, T2, T3, T4, T5, T6, T7, T8, R]): Function8[T1, T2, T3, T4, T5, T6, T7, T8, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8) => f(x1, x2, x3, x4, x5, x6, x7, x8)) - implicit def fromFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R](f: scala.Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R]): Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9)) - implicit def fromFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R](f: scala.Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R]): Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)) - implicit def fromFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R](f: scala.Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R]): Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)) - implicit def fromFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R](f: scala.Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R]): Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12)) - implicit def fromFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R](f: scala.Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R]): Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13)) - implicit def fromFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R](f: scala.Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R]): Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14)) - implicit def fromFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R](f: scala.Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R]): Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15)) - implicit def fromFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R](f: scala.Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R]): Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16)) - implicit def fromFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R](f: scala.Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R]): Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17)) - implicit def fromFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R](f: scala.Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R]): Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18)) - implicit def fromFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R](f: scala.Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R]): Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19)) - implicit def fromFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R](f: scala.Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R]): Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20)) - implicit def fromFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R](f: scala.Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R]): Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20, x21: T21) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21)) - implicit def fromFunction22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R](f: scala.Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R]): Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20, x21: T21, x22: T22) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22)) - - implicit def toFunction0[R](f: Function0[R]): scala.Function0[R] = () => f() - implicit def toFunction1[T1, R](f: Function1[T1, R]): scala.Function1[T1, R] = (x1) => f(x1) - implicit def toFunction2[T1, T2, R](f: Function2[T1, T2, R]): scala.Function2[T1, T2, R] = (x1, x2) => f(x1, x2) - implicit def toFunction3[T1, T2, T3, R](f: Function3[T1, T2, T3, R]): scala.Function3[T1, T2, T3, R] = (x1, x2, x3) => f(x1, x2, x3) - implicit def toFunction4[T1, T2, T3, T4, R](f: Function4[T1, T2, T3, T4, R]): scala.Function4[T1, T2, T3, T4, R] = (x1, x2, x3, x4) => f(x1, x2, x3, x4) - implicit def toFunction5[T1, T2, T3, T4, T5, R](f: Function5[T1, T2, T3, T4, T5, R]): scala.Function5[T1, T2, T3, T4, T5, R] = (x1, x2, x3, x4, x5) => f(x1, x2, x3, x4, x5) - implicit def toFunction6[T1, T2, T3, T4, T5, T6, R](f: Function6[T1, T2, T3, T4, T5, T6, R]): scala.Function6[T1, T2, T3, T4, T5, T6, R] = (x1, x2, x3, x4, x5, x6) => f(x1, x2, x3, x4, x5, x6) - implicit def toFunction7[T1, T2, T3, T4, T5, T6, T7, R](f: Function7[T1, T2, T3, T4, T5, T6, T7, R]): scala.Function7[T1, T2, T3, T4, T5, T6, T7, R] = (x1, x2, x3, x4, x5, x6, x7) => f(x1, x2, x3, x4, x5, x6, x7) - implicit def toFunction8[T1, T2, T3, T4, T5, T6, T7, T8, R](f: Function8[T1, T2, T3, T4, T5, T6, T7, T8, R]): scala.Function8[T1, T2, T3, T4, T5, T6, T7, T8, R] = (x1, x2, x3, x4, x5, x6, x7, x8) => f(x1, x2, x3, x4, x5, x6, x7, x8) - implicit def toFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R](f: Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R]): scala.Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9) - implicit def toFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R](f: Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R]): scala.Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) - implicit def toFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R](f: Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R]): scala.Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11) - implicit def toFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R](f: Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R]): scala.Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12) - implicit def toFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R](f: Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R]): scala.Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13) - implicit def toFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R](f: Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R]): scala.Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14) - implicit def toFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R](f: Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R]): scala.Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) - implicit def toFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R](f: Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R]): scala.Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16) - implicit def toFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R](f: Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R]): scala.Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17) - implicit def toFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R](f: Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R]): scala.Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18) - implicit def toFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R](f: Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R]): scala.Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19) - implicit def toFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R](f: Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R]): scala.Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20) - implicit def toFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R](f: Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R]): scala.Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21) - implicit def toFunction22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R](f: Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R]): scala.Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22) + implicit def fromFunction0[R](f: scala.Function0[R]): js.Function0[R] = identity(() => f()) + implicit def fromFunction1[T1, R](f: scala.Function1[T1, R]): js.Function1[T1, R] = identity((x1: T1) => f(x1)) + implicit def fromFunction2[T1, T2, R](f: scala.Function2[T1, T2, R]): js.Function2[T1, T2, R] = identity((x1: T1, x2: T2) => f(x1, x2)) + implicit def fromFunction3[T1, T2, T3, R](f: scala.Function3[T1, T2, T3, R]): js.Function3[T1, T2, T3, R] = identity((x1: T1, x2: T2, x3: T3) => f(x1, x2, x3)) + implicit def fromFunction4[T1, T2, T3, T4, R](f: scala.Function4[T1, T2, T3, T4, R]): js.Function4[T1, T2, T3, T4, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4) => f(x1, x2, x3, x4)) + implicit def fromFunction5[T1, T2, T3, T4, T5, R](f: scala.Function5[T1, T2, T3, T4, T5, R]): js.Function5[T1, T2, T3, T4, T5, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5) => f(x1, x2, x3, x4, x5)) + implicit def fromFunction6[T1, T2, T3, T4, T5, T6, R](f: scala.Function6[T1, T2, T3, T4, T5, T6, R]): js.Function6[T1, T2, T3, T4, T5, T6, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6) => f(x1, x2, x3, x4, x5, x6)) + implicit def fromFunction7[T1, T2, T3, T4, T5, T6, T7, R](f: scala.Function7[T1, T2, T3, T4, T5, T6, T7, R]): js.Function7[T1, T2, T3, T4, T5, T6, T7, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7) => f(x1, x2, x3, x4, x5, x6, x7)) + implicit def fromFunction8[T1, T2, T3, T4, T5, T6, T7, T8, R](f: scala.Function8[T1, T2, T3, T4, T5, T6, T7, T8, R]): js.Function8[T1, T2, T3, T4, T5, T6, T7, T8, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8) => f(x1, x2, x3, x4, x5, x6, x7, x8)) + implicit def fromFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R](f: scala.Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R]): js.Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9)) + implicit def fromFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R](f: scala.Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R]): js.Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)) + implicit def fromFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R](f: scala.Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R]): js.Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)) + implicit def fromFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R](f: scala.Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R]): js.Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12)) + implicit def fromFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R](f: scala.Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R]): js.Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13)) + implicit def fromFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R](f: scala.Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R]): js.Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14)) + implicit def fromFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R](f: scala.Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R]): js.Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15)) + implicit def fromFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R](f: scala.Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R]): js.Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16)) + implicit def fromFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R](f: scala.Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R]): js.Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17)) + implicit def fromFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R](f: scala.Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R]): js.Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18)) + implicit def fromFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R](f: scala.Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R]): js.Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19)) + implicit def fromFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R](f: scala.Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R]): js.Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20)) + implicit def fromFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R](f: scala.Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R]): js.Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20, x21: T21) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21)) + implicit def fromFunction22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R](f: scala.Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R]): js.Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20, x21: T21, x22: T22) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22)) + + implicit def toFunction0[R](f: js.Function0[R]): scala.Function0[R] = () => f() + implicit def toFunction1[T1, R](f: js.Function1[T1, R]): scala.Function1[T1, R] = (x1) => f(x1) + implicit def toFunction2[T1, T2, R](f: js.Function2[T1, T2, R]): scala.Function2[T1, T2, R] = (x1, x2) => f(x1, x2) + implicit def toFunction3[T1, T2, T3, R](f: js.Function3[T1, T2, T3, R]): scala.Function3[T1, T2, T3, R] = (x1, x2, x3) => f(x1, x2, x3) + implicit def toFunction4[T1, T2, T3, T4, R](f: js.Function4[T1, T2, T3, T4, R]): scala.Function4[T1, T2, T3, T4, R] = (x1, x2, x3, x4) => f(x1, x2, x3, x4) + implicit def toFunction5[T1, T2, T3, T4, T5, R](f: js.Function5[T1, T2, T3, T4, T5, R]): scala.Function5[T1, T2, T3, T4, T5, R] = (x1, x2, x3, x4, x5) => f(x1, x2, x3, x4, x5) + implicit def toFunction6[T1, T2, T3, T4, T5, T6, R](f: js.Function6[T1, T2, T3, T4, T5, T6, R]): scala.Function6[T1, T2, T3, T4, T5, T6, R] = (x1, x2, x3, x4, x5, x6) => f(x1, x2, x3, x4, x5, x6) + implicit def toFunction7[T1, T2, T3, T4, T5, T6, T7, R](f: js.Function7[T1, T2, T3, T4, T5, T6, T7, R]): scala.Function7[T1, T2, T3, T4, T5, T6, T7, R] = (x1, x2, x3, x4, x5, x6, x7) => f(x1, x2, x3, x4, x5, x6, x7) + implicit def toFunction8[T1, T2, T3, T4, T5, T6, T7, T8, R](f: js.Function8[T1, T2, T3, T4, T5, T6, T7, T8, R]): scala.Function8[T1, T2, T3, T4, T5, T6, T7, T8, R] = (x1, x2, x3, x4, x5, x6, x7, x8) => f(x1, x2, x3, x4, x5, x6, x7, x8) + implicit def toFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R](f: js.Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R]): scala.Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9) + implicit def toFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R](f: js.Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R]): scala.Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) + implicit def toFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R](f: js.Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R]): scala.Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11) + implicit def toFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R](f: js.Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R]): scala.Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12) + implicit def toFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R](f: js.Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R]): scala.Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13) + implicit def toFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R](f: js.Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R]): scala.Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14) + implicit def toFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R](f: js.Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R]): scala.Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) + implicit def toFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R](f: js.Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R]): scala.Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16) + implicit def toFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R](f: js.Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R]): scala.Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17) + implicit def toFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R](f: js.Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R]): scala.Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18) + implicit def toFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R](f: js.Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R]): scala.Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19) + implicit def toFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R](f: js.Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R]): scala.Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20) + implicit def toFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R](f: js.Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R]): scala.Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21) + implicit def toFunction22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R](f: js.Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R]): scala.Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22) // scalastyle:on line.size.limit - @inline implicit def fromJBoolean(value: java.lang.Boolean): Any = - value.asInstanceOf[Any] - @inline implicit def fromJByte(value: java.lang.Byte): Any = - value.asInstanceOf[Any] - @inline implicit def fromJShort(value: java.lang.Short): Any = - value.asInstanceOf[Any] - @inline implicit def fromJInteger(value: java.lang.Integer): Any = - value.asInstanceOf[Any] + @inline implicit def fromJBoolean(value: java.lang.Boolean): js.Any = + value.asInstanceOf[js.Any] + @inline implicit def fromJByte(value: java.lang.Byte): js.Any = + value.asInstanceOf[js.Any] + @inline implicit def fromJShort(value: java.lang.Short): js.Any = + value.asInstanceOf[js.Any] + @inline implicit def fromJInteger(value: java.lang.Integer): js.Any = + value.asInstanceOf[js.Any] /* The following overload makes sure that the developer does not * inadvertently convert a Long to a Double to fit it in a js.Any. @@ -185,28 +185,28 @@ object Any extends LowPrioAnyImplicits { "Use `.toDouble` explicitly if you need it.", "forever") @inline - implicit def fromJLong(value: java.lang.Long): Any = + implicit def fromJLong(value: java.lang.Long): js.Any = if (value eq null) null - else value.doubleValue.asInstanceOf[Any] + else value.doubleValue.asInstanceOf[js.Any] - @inline implicit def fromJFloat(value: java.lang.Float): Any = - value.asInstanceOf[Any] - @inline implicit def fromJDouble(value: java.lang.Double): Any = - value.asInstanceOf[Any] + @inline implicit def fromJFloat(value: java.lang.Float): js.Any = + value.asInstanceOf[js.Any] + @inline implicit def fromJDouble(value: java.lang.Double): js.Any = + value.asInstanceOf[js.Any] } -sealed trait LowPrioAnyImplicits extends LowestPrioAnyImplicits { - this: Any.type => +sealed trait LowPrioAnyImplicits extends js.LowestPrioAnyImplicits { + this: js.Any.type => - implicit def wrapArray[A](array: Array[A]): WrappedArray[A] = - new WrappedArray(array) - implicit def wrapDictionary[A](dict: Dictionary[A]): WrappedDictionary[A] = - new WrappedDictionary(dict) + implicit def wrapArray[A](array: js.Array[A]): js.WrappedArray[A] = + new js.WrappedArray(array) + implicit def wrapDictionary[A](dict: js.Dictionary[A]): js.WrappedDictionary[A] = + new js.WrappedDictionary(dict) } sealed trait LowestPrioAnyImplicits { - this: Any.type => + this: js.Any.type => - implicit def iterableOps[A](iterable: Iterable[A]): IterableOps[A] = - new IterableOps(iterable) + implicit def iterableOps[A](iterable: js.Iterable[A]): js.IterableOps[A] = + new js.IterableOps(iterable) } diff --git a/library/src/main/scala/scala/scalajs/js/Array.scala b/library/src/main/scala/scala/scalajs/js/Array.scala index be2a855bad..be2046193c 100644 --- a/library/src/main/scala/scala/scalajs/js/Array.scala +++ b/library/src/main/scala/scala/scalajs/js/Array.scala @@ -14,7 +14,8 @@ */ package scala.scalajs.js -import annotation._ +import scala.scalajs.js +import scala.scalajs.js.annotation._ /** * Arrays are list-like objects whose prototype has methods to perform @@ -36,9 +37,9 @@ import annotation._ * * @constructor Creates a new array of length 0. */ -@native +@js.native @JSGlobal -class Array[A] extends Object with Iterable[A] { +class Array[A] extends js.Object with js.Iterable[A] { /** Creates a new array with the given length. * @param arrayLength Initial length of the array. */ @@ -48,21 +49,21 @@ class Array[A] extends Object with Iterable[A] { // def this(items: A*) = this() /** Length of the array. */ - def length: Int = native + def length: Int = js.native /** Sets the length of the array. * If the new length is bigger than the old length, created slots are * filled with `undefined` (irrespective of the type argument `A`!). * If the new length is smaller than the old length, the array is shrunk. */ - def length_=(v: Int): Unit = native + def length_=(v: Int): Unit = js.native /** Access the element at the given index. */ @JSBracketAccess - def apply(index: Int): A = native + def apply(index: Int): A = js.native /** Set the element at the given index. */ @JSBracketAccess - def update(index: Int, value: A): Unit = native + def update(index: Int, value: A): Unit = js.native /** * concat creates a new array consisting of the elements in the this object @@ -72,13 +73,13 @@ class Array[A] extends Object with Iterable[A] { * * MDN */ - def concat[B >: A](items: Array[_ <: B]*): Array[B] = native + def concat[B >: A](items: js.Array[_ <: B]*): js.Array[B] = js.native /** ECMAScript 6 * JavaScript Iterator for this Array. */ - @JSName(Symbol.iterator) - def jsIterator(): Iterator[A] = native + @JSName(js.Symbol.iterator) + def jsIterator(): js.Iterator[A] = js.native /** * The join() method joins all elements of an array into a string. @@ -87,7 +88,7 @@ class Array[A] extends Object with Iterable[A] { * The separator is converted to a string if necessary. If omitted, the * array elements are separated with a comma. */ - def join(seperator: String = ","): String = native + def join(seperator: String = ","): String = js.native /** * The pop() method removes the last element from an array and returns that @@ -95,7 +96,7 @@ class Array[A] extends Object with Iterable[A] { * * MDN */ - def pop(): A = native + def pop(): A = js.native /** * The push() method mutates an array by appending the given elements and @@ -103,7 +104,7 @@ class Array[A] extends Object with Iterable[A] { * * MDN */ - def push(items: A*): Int = native + def push(items: A*): Int = js.native /** * The reverse() method reverses an array in place. The first array element @@ -112,7 +113,7 @@ class Array[A] extends Object with Iterable[A] { * MDN */ @JSName("reverse") - def reverseInPlace(): Array[A] = native + def reverseInPlace(): js.Array[A] = js.native /** * The shift() method removes the first element from an array and returns that @@ -120,7 +121,7 @@ class Array[A] extends Object with Iterable[A] { * * MDN */ - def shift(): A = native + def shift(): A = js.native /** * The slice() method returns a shallow copy of a portion of an array. @@ -128,7 +129,7 @@ class Array[A] extends Object with Iterable[A] { * MDN */ @JSName("slice") - def jsSlice(start: Int = 0, end: Int = Int.MaxValue): Array[A] = native + def jsSlice(start: Int = 0, end: Int = Int.MaxValue): js.Array[A] = js.native /** * The sort() method sorts the elements of an array in place and returns the @@ -142,7 +143,7 @@ class Array[A] extends Object with Iterable[A] { * * MDN */ - def sort(compareFn: Function2[A, A, Int] = ???): Array[A] = native + def sort(compareFn: js.Function2[A, A, Int] = ???): js.Array[A] = js.native /** Removes and adds new elements at a given index in the array. * @@ -157,7 +158,7 @@ class Array[A] extends Object with Iterable[A] { * @param items Elements to insert at index * @return An array of the elements that were deleted */ - def splice(index: Int, deleteCount: Int, items: A*): Array[A] = native + def splice(index: Int, deleteCount: Int, items: A*): js.Array[A] = js.native /** * The unshift() method adds one or more elements to the beginning of an array @@ -165,19 +166,19 @@ class Array[A] extends Object with Iterable[A] { * * MDN */ - def unshift(items: A*): Int = native + def unshift(items: A*): Int = js.native } /** Factory for [[js.Array]] objects. */ -@native +@js.native @JSGlobal -object Array extends Object { - // Do not expose this one - use new Array(len) instead - // def apply[A](arrayLength: Int): Array[A] = native +object Array extends js.Object { + // Do not expose this one - use new js.Array(len) instead + // def apply[A](arrayLength: Int): js.Array[A] = js.native /** Creates a new array with the given items. */ - def apply[A](items: A*): Array[A] = throw new java.lang.Error("stub") + def apply[A](items: A*): js.Array[A] = throw new java.lang.Error("stub") /** Returns true if the given value is an array. */ - def isArray(arg: scala.Any): Boolean = native + def isArray(arg: scala.Any): Boolean = js.native } diff --git a/library/src/main/scala/scala/scalajs/js/ArrayOps.scala b/library/src/main/scala/scala/scalajs/js/ArrayOps.scala index f7948ca092..ebaeadf44d 100644 --- a/library/src/main/scala/scala/scalajs/js/ArrayOps.scala +++ b/library/src/main/scala/scala/scalajs/js/ArrayOps.scala @@ -10,19 +10,21 @@ package scala.scalajs.js import scala.annotation.tailrec +import scala.scalajs.js + import scala.collection.mutable import mutable.Builder -/** Equivalent of scm.ArrayOps for js.Array */ +/** Equivalent of `scm.ArrayOps` for [[js.Array]]. */ @inline -final class ArrayOps[A](private[this] val array: Array[A]) - extends mutable.ArrayLike[A, Array[A]] - with Builder[A, Array[A]] { +final class ArrayOps[A](private[this] val array: js.Array[A]) + extends mutable.ArrayLike[A, js.Array[A]] + with Builder[A, js.Array[A]] { import ArrayOps._ - /** Creates a new empty [[ArrayOps]]. */ - def this() = this(Array()) + /** Creates a new empty [[js.ArrayOps]]. */ + def this() = this(js.Array()) // Implementation of ArrayLike @@ -30,17 +32,20 @@ final class ArrayOps[A](private[this] val array: Array[A]) @inline def length: Int = array.length @inline def update(index: Int, element: A): Unit = array(index) = element - def seq: IndexedSeq[A] = new WrappedArray(array) + def seq: IndexedSeq[A] = new js.WrappedArray(array) - override def repr: Array[A] = array + override def repr: js.Array[A] = array override protected[this] def thisCollection: mutable.IndexedSeq[A] = toCollection(array) + override protected[this] def toCollection( - repr: Array[A]): mutable.IndexedSeq[A] = new WrappedArray(repr) + repr: js.Array[A]): mutable.IndexedSeq[A] = { + new js.WrappedArray(repr) + } - protected[this] def newBuilder: Builder[A, Array[A]] = - new ArrayOps[A] + protected[this] def newBuilder: Builder[A, js.Array[A]] = + new js.ArrayOps[A] // Implementation of Builder @@ -52,11 +57,11 @@ final class ArrayOps[A](private[this] val array: Array[A]) @inline def clear(): Unit = array.length = 0 - @inline def result(): Array[A] = array + @inline def result(): js.Array[A] = array // Scala notation for a fast concat() - @inline def ++[B >: A](that: Array[_ <: B]): Array[B] = + @inline def ++[B >: A](that: js.Array[_ <: B]): js.Array[B] = concat(array, that) // Methods whose inherited implementations do not play nice with the optimizer @@ -98,18 +103,21 @@ object ArrayOps { throw new UnsupportedOperationException(msg) /** Non-inlined implementation of [[ArrayOps.++]]. */ - private def concat[A](left: Array[_ <: A], right: Array[_ <: A]): Array[A] = { + private def concat[A](left: js.Array[_ <: A], + right: js.Array[_ <: A]): js.Array[A] = { + val leftLength = left.length val rightLength = right.length - val result = new Array[A](leftLength + rightLength) + val result = new js.Array[A](leftLength + rightLength) @inline @tailrec - def loop(src: Array[_ <: A], i: Int, len: Int, offset: Int): Unit = + def loop(src: js.Array[_ <: A], i: Int, len: Int, offset: Int): Unit = { if (i != len) { - result(i+offset) = src(i) - loop(src, i+1, len, offset) + result(i + offset) = src(i) + loop(src, i + 1, len, offset) } + } loop(left, 0, leftLength, 0) loop(right, 0, rightLength, leftLength) diff --git a/library/src/main/scala/scala/scalajs/js/ConstructorTag.scala b/library/src/main/scala/scala/scalajs/js/ConstructorTag.scala index f4f8c51427..1f0fec19ab 100644 --- a/library/src/main/scala/scala/scalajs/js/ConstructorTag.scala +++ b/library/src/main/scala/scala/scalajs/js/ConstructorTag.scala @@ -9,6 +9,8 @@ package scala.scalajs.js +import scala.scalajs.js + /** Stores the JS constructor function of a JS class. * * A `ConstructorTag[T]` holds the constructor function of a JS class, as @@ -17,24 +19,26 @@ package scala.scalajs.js * materialized when `T` is statically known to be a JS class, i.e., a valid * type argument to `js.constructorOf`. */ -final class ConstructorTag[T <: Any] private[scalajs] ( - val constructor: Dynamic) extends AnyVal { +final class ConstructorTag[T <: js.Any] private[scalajs] ( + val constructor: js.Dynamic) + extends AnyVal { /** Instantiates the class `T` with the specified arguments. * - * Note that, unlike [[Dynamic.newInstance js.Dynamic.newInstance]], this - * method accepts `scala.Any`s as parameters. + * Note that, unlike [[js.Dynamic.newInstance]], this method accepts + * `scala.Any`s as parameters. */ - def newInstance(args: scala.Any*): T = - Dynamic.newInstance(constructor)(args.asInstanceOf[Seq[Any]]: _*).asInstanceOf[T] + def newInstance(args: scala.Any*): T = { + js.Dynamic.newInstance(constructor)( + args.asInstanceOf[Seq[js.Any]]: _*).asInstanceOf[T] + } } object ConstructorTag { - /** Implicitly materializes a [[ConstructorTag]]. + /** Implicitly materializes a [[js.ConstructorTag]]. * - * This method has the same preconditions as - * [[constructorOf js.constructorOf]]. + * This method has the same preconditions as [[js.constructorOf]]. */ - implicit def materialize[T <: Any]: ConstructorTag[T] = + implicit def materialize[T <: js.Any]: js.ConstructorTag[T] = throw new java.lang.Error("stub") } diff --git a/library/src/main/scala/scala/scalajs/js/Date.scala b/library/src/main/scala/scala/scalajs/js/Date.scala index fbd7c09b70..1f52f11ec9 100644 --- a/library/src/main/scala/scala/scalajs/js/Date.scala +++ b/library/src/main/scala/scala/scalajs/js/Date.scala @@ -14,6 +14,7 @@ */ package scala.scalajs.js +import scala.scalajs.js import scala.scalajs.js.annotation._ /** @@ -23,9 +24,9 @@ import scala.scalajs.js.annotation._ * * MDN */ -@native +@js.native @JSGlobal -class Date extends Object { +class Date extends js.Object { def this(value: Double) = this() def this(value: String) = this() @@ -33,167 +34,167 @@ class Date extends Object { def this(year: Int, month: Int, date: Int = 1, hours: Int = 0, minutes: Int = 0, seconds: Int = 0, ms: Int = 0) = this() - def toDateString(): String = native - def toTimeString(): String = native - def toLocaleDateString(): String = native - def toLocaleTimeString(): String = native + def toDateString(): String = js.native + def toTimeString(): String = js.native + def toLocaleDateString(): String = js.native + def toLocaleTimeString(): String = js.native - override def valueOf(): Double = native + override def valueOf(): Double = js.native - def getTime(): Double = native + def getTime(): Double = js.native /** * Returns the year (4 digits for 4-digit years) of the specified date according to local time. * * MDN */ - def getFullYear(): Int = native + def getFullYear(): Int = js.native /** * Returns the year (4 digits for 4-digit years) in the specified date according to universal time. * * MDN */ - def getUTCFullYear(): Int = native + def getUTCFullYear(): Int = js.native /** * Returns the month (0-11) in the specified date according to local time. * * MDN */ - def getMonth(): Int = native + def getMonth(): Int = js.native /** * Returns the month (0-11) in the specified date according to universal time. * * MDN */ - def getUTCMonth(): Int = native + def getUTCMonth(): Int = js.native /** * Returns the day of the month (1-31) for the specified date according to local time. * * MDN */ - def getDate(): Int = native + def getDate(): Int = js.native /** * Returns the day (date) of the month (1-31) in the specified date according to universal time. * * MDN */ - def getUTCDate(): Int = native + def getUTCDate(): Int = js.native /** * Returns the day of the week (0-6) for the specified date according to local time. * * MDN */ - def getDay(): Int = native + def getDay(): Int = js.native /** * Returns the day of the week (0-6) in the specified date according to universal time. * MDN */ - def getUTCDay(): Int = native + def getUTCDay(): Int = js.native /** * Returns the hour (0-23) in the specified date according to local time. * * MDN */ - def getHours(): Int = native + def getHours(): Int = js.native /** * Returns the hours (0-23) in the specified date according to universal time. * * MDN */ - def getUTCHours(): Int = native + def getUTCHours(): Int = js.native /** * Returns the minutes (0-59) in the specified date according to local time. * * MDN */ - def getMinutes(): Int = native + def getMinutes(): Int = js.native /** * Returns the minutes (0-59) in the specified date according to universal time. * * MDN */ - def getUTCMinutes(): Int = native + def getUTCMinutes(): Int = js.native /** * Returns the seconds (0-59) in the specified date according to local time. * * MDN */ - def getSeconds(): Int = native + def getSeconds(): Int = js.native /** * Returns the seconds (0-59) in the specified date according to universal time. * * MDN */ - def getUTCSeconds(): Int = native + def getUTCSeconds(): Int = js.native /** * Returns the milliseconds (0-999) in the specified date according to local time. * * MDN */ - def getMilliseconds(): Int = native + def getMilliseconds(): Int = js.native /** * Returns the milliseconds (0-999) in the specified date according to universal time. * * MDN */ - def getUTCMilliseconds(): Int = native + def getUTCMilliseconds(): Int = js.native /** * Returns the time-zone offset in minutes for the current locale. * * MDN */ - def getTimezoneOffset(): Int = native + def getTimezoneOffset(): Int = js.native - def setTime(time: Double): Unit = native - def setMilliseconds(ms: Int): Unit = native - def setUTCMilliseconds(ms: Int): Unit = native - def setSeconds(sec: Int, ms: Int = getMilliseconds()): Unit = native - def setUTCSeconds(sec: Int, ms: Int = getMilliseconds()): Unit = native + def setTime(time: Double): Unit = js.native + def setMilliseconds(ms: Int): Unit = js.native + def setUTCMilliseconds(ms: Int): Unit = js.native + def setSeconds(sec: Int, ms: Int = getMilliseconds()): Unit = js.native + def setUTCSeconds(sec: Int, ms: Int = getMilliseconds()): Unit = js.native def setMinutes(min: Int, sec: Int = getSeconds(), - ms: Int = getMilliseconds()): Unit = native + ms: Int = getMilliseconds()): Unit = js.native def setUTCMinutes(min: Int, sec: Int = getSeconds(), - ms: Int = getMilliseconds()): Unit = native + ms: Int = getMilliseconds()): Unit = js.native def setHours(hours: Int, min: Int = getMinutes(), - sec: Int = getSeconds(), ms: Int = getMilliseconds()): Unit = native + sec: Int = getSeconds(), ms: Int = getMilliseconds()): Unit = js.native def setUTCHours(hours: Int, min: Int = getMinutes(), - sec: Int = getSeconds(), ms: Int = getMilliseconds()): Unit = native + sec: Int = getSeconds(), ms: Int = getMilliseconds()): Unit = js.native - def setDate(date: Int): Unit = native - def setUTCDate(date: Int): Unit = native - def setMonth(month: Int, date: Int = getDate()): Unit = native - def setUTCMonth(month: Int, date: Int = getDate()): Unit = native + def setDate(date: Int): Unit = js.native + def setUTCDate(date: Int): Unit = js.native + def setMonth(month: Int, date: Int = getDate()): Unit = js.native + def setUTCMonth(month: Int, date: Int = getDate()): Unit = js.native def setFullYear(year: Int, month: Int = getMonth(), - date: Int = getDate()): Unit = native + date: Int = getDate()): Unit = js.native def setUTCFullYear(year: Int, month: Int = getMonth(), - date: Int = getDate()): Unit = native + date: Int = getDate()): Unit = js.native - def toUTCString(): String = native - def toISOString(): String = native - def toJSON(key: Any): String = native - def toJSON(): String = native + def toUTCString(): String = js.native + def toISOString(): String = js.native + def toJSON(key: Any): String = js.native + def toJSON(): String = js.native } /** Factory for [[js.Date]] objects. */ -@native +@js.native @JSGlobal -object Date extends Object { - def apply(): String = native +object Date extends js.Object { + def apply(): String = js.native /** * Parses a string representation of a date and returns the number of @@ -216,10 +217,10 @@ object Date extends Object { * * MDN */ - def parse(s: String): Double = native + def parse(s: String): Double = js.native def UTC(year: Int, month: Int, date: Int = 1, hours: Int = 0, - minutes: Int = 0, seconds: Int = 0, ms: Int = 0): Double = native + minutes: Int = 0, seconds: Int = 0, ms: Int = 0): Double = js.native /** * Returns the numeric value corresponding to the current time - the number @@ -227,5 +228,5 @@ object Date extends Object { * * MDN */ - def now(): Double = native + def now(): Double = js.native } diff --git a/library/src/main/scala/scala/scalajs/js/Dictionary.scala b/library/src/main/scala/scala/scalajs/js/Dictionary.scala index dee0c9d623..2e951a185f 100644 --- a/library/src/main/scala/scala/scalajs/js/Dictionary.scala +++ b/library/src/main/scala/scala/scalajs/js/Dictionary.scala @@ -14,7 +14,7 @@ */ package scala.scalajs.js -import annotation.JSBracketAccess +import scala.scalajs.js /** Dictionary "view" of a JavaScript value. * @@ -48,15 +48,15 @@ import annotation.JSBracketAccess * call methods of [[Object js.Object]] on it, given that the name of these * methods could be used as keys in the dictionary. */ -sealed trait Dictionary[A] extends Any +sealed trait Dictionary[A] extends js.Any -/** Factory for [[Dictionary]] instances. */ +/** Factory for [[js.Dictionary]] instances. */ object Dictionary { /** Returns a new empty dictionary */ - @inline def empty[A]: Dictionary[A] = - (new Object).asInstanceOf[Dictionary[A]] + @inline def empty[A]: js.Dictionary[A] = + (new js.Object).asInstanceOf[js.Dictionary[A]] - def apply[A](properties: (String, A)*): Dictionary[A] = { + def apply[A](properties: (String, A)*): js.Dictionary[A] = { val result = empty[A] for ((key, value) <- properties) result(key) = value diff --git a/library/src/main/scala/scala/scalajs/js/Dynamic.scala b/library/src/main/scala/scala/scalajs/js/Dynamic.scala index 70482545af..0e854eaaee 100644 --- a/library/src/main/scala/scala/scalajs/js/Dynamic.scala +++ b/library/src/main/scala/scala/scalajs/js/Dynamic.scala @@ -16,7 +16,8 @@ package scala.scalajs.js import scala.language.dynamics -import annotation.{JSBracketAccess, JSBracketCall} +import scala.scalajs.js +import scala.scalajs.js.annotation._ /** Dynamically typed JavaScript value. * @@ -24,85 +25,103 @@ import annotation.{JSBracketAccess, JSBracketCall} * dynamically typed way. You can read and write any field, call any method, * apply any JavaScript operator to values of this type. */ -@native -sealed trait Dynamic extends Any with scala.Dynamic { +@js.native +sealed trait Dynamic extends js.Any with scala.Dynamic { /** Calls a method of this object. */ @JSBracketCall - def applyDynamic(name: String)(args: Any*): Dynamic = native + def applyDynamic(name: String)(args: js.Any*): js.Dynamic = js.native /** Reads a field of this object. */ @JSBracketAccess - def selectDynamic(name: String): Dynamic = native + def selectDynamic(name: String): js.Dynamic = js.native /** Writes a field of this object. */ @JSBracketAccess - def updateDynamic(name: String)(value: Any): Unit = native + def updateDynamic(name: String)(value: js.Any): Unit = js.native /** Calls this object as a callable. */ - def apply(args: Any*): Dynamic = native - - def unary_!(): Dynamic = native - - def unary_+(): Dynamic = native - def unary_-(): Dynamic = native - def unary_~(): Dynamic = native - - def +(that: Dynamic): Dynamic = native - def -(that: Dynamic): Dynamic = native - def *(that: Dynamic): Dynamic = native - def /(that: Dynamic): Dynamic = native - def %(that: Dynamic): Dynamic = native - def <<(that: Dynamic): Dynamic = native - def >>(that: Dynamic): Dynamic = native - def >>>(that: Dynamic): Dynamic = native - def &(that: Dynamic): Dynamic = native - def |(that: Dynamic): Dynamic = native - def ^(that: Dynamic): Dynamic = native - - def <(that: Dynamic): Dynamic = native - def >(that: Dynamic): Dynamic = native - def <=(that: Dynamic): Dynamic = native - def >=(that: Dynamic): Dynamic = native - - def &&(that: Dynamic): Dynamic = native - def ||(that: Dynamic): Dynamic = native + def apply(args: js.Any*): js.Dynamic = js.native + + def unary_!(): js.Dynamic = js.native + + def unary_+(): js.Dynamic = js.native + def unary_-(): js.Dynamic = js.native + def unary_~(): js.Dynamic = js.native + + def +(that: js.Dynamic): js.Dynamic = js.native + def -(that: js.Dynamic): js.Dynamic = js.native + def *(that: js.Dynamic): js.Dynamic = js.native + def /(that: js.Dynamic): js.Dynamic = js.native + def %(that: js.Dynamic): js.Dynamic = js.native + def <<(that: js.Dynamic): js.Dynamic = js.native + def >>(that: js.Dynamic): js.Dynamic = js.native + def >>>(that: js.Dynamic): js.Dynamic = js.native + def &(that: js.Dynamic): js.Dynamic = js.native + def |(that: js.Dynamic): js.Dynamic = js.native + def ^(that: js.Dynamic): js.Dynamic = js.native + + def <(that: js.Dynamic): js.Dynamic = js.native + def >(that: js.Dynamic): js.Dynamic = js.native + def <=(that: js.Dynamic): js.Dynamic = js.native + def >=(that: js.Dynamic): js.Dynamic = js.native + + def &&(that: js.Dynamic): js.Dynamic = js.native + def ||(that: js.Dynamic): js.Dynamic = js.native // Work around the annoying implicits in Predef in Scala 2.10. - def x: Dynamic = native - def x_=(value: Any): Unit = native + def x: js.Dynamic = js.native + def x_=(value: js.Any): Unit = js.native } /** Factory for dynamically typed JavaScript values. */ object Dynamic { /** Dynamic view of the global scope. */ - def global: Dynamic = sys.error("stub") + def global: js.Dynamic = throw new java.lang.Error("stub") /** 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") + * {{{ + * js.Dynamic.literal(foo = 3, bar = "foobar") + * }}} * returns the JavaScript object - * {foo: 3, bar: "foobar"} + * {{{ + * {foo: 3, bar: "foobar"} + * }}} */ object literal extends scala.Dynamic { // scalastyle:ignore - /** 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 --git a/library/src/main/scala/scala/scalajs/js/DynamicImplicits.scala b/library/src/main/scala/scala/scalajs/js/DynamicImplicits.scala index 3e69b6d838..0c423eaa65 100644 --- a/library/src/main/scala/scala/scalajs/js/DynamicImplicits.scala +++ b/library/src/main/scala/scala/scalajs/js/DynamicImplicits.scala @@ -11,24 +11,26 @@ package scala.scalajs.js import scala.language.implicitConversions +import scala.scalajs.js + /** Provides implicit conversions and operations to write in JavaScript - * style with [[Dynamic js.Dynamic]]. + * style with [[js.Dynamic]]. * * Be **very** careful when importing members of this object. You may want * to selectively import the implicits that you want to reduce the likelihood * of making mistakes. */ object DynamicImplicits { - @inline implicit def truthValue(x: Dynamic): Boolean = + @inline implicit def truthValue(x: js.Dynamic): Boolean = (!(!x)).asInstanceOf[Boolean] // Useful for Scala 2.10 - implicit def number2dynamic(x: Int): Dynamic = - x.asInstanceOf[Dynamic] + implicit def number2dynamic(x: Int): js.Dynamic = + x.asInstanceOf[js.Dynamic] - implicit def number2dynamic(x: Double): Dynamic = - x.asInstanceOf[Dynamic] + implicit def number2dynamic(x: Double): js.Dynamic = + x.asInstanceOf[js.Dynamic] - implicit def boolean2dynamic(x: Boolean): Dynamic = - x.asInstanceOf[Dynamic] + implicit def boolean2dynamic(x: Boolean): js.Dynamic = + x.asInstanceOf[js.Dynamic] } diff --git a/library/src/main/scala/scala/scalajs/js/Error.scala b/library/src/main/scala/scala/scalajs/js/Error.scala index f3f6e09c94..aea7a72157 100644 --- a/library/src/main/scala/scala/scalajs/js/Error.scala +++ b/library/src/main/scala/scala/scalajs/js/Error.scala @@ -14,40 +14,42 @@ */ package scala.scalajs.js +import scala.scalajs.js import scala.scalajs.js.annotation._ -@native +@js.native @JSGlobal -class Error(message0: String = "") extends Object { - val name: String = native +class Error(message0: String = "") extends js.Object { + val name: String = js.native + /** * Human-readable description of the error * * MDN */ - val message: String = native + val message: String = js.native } -@native +@js.native @JSGlobal -object Error extends Object { - def apply(message: String = ""): Error = native +object Error extends js.Object { + def apply(message: String = ""): js.Error = js.native } /** * An instance representing an error that occurs regarding the global function - * eval() + * `eval()`. * * MDN */ -@native +@js.native @JSGlobal -class EvalError(message: String = "") extends Error +class EvalError(message: String = "") extends js.Error -@native +@js.native @JSGlobal -object EvalError extends Object { - def apply(message: String = ""): EvalError = native +object EvalError extends js.Object { + def apply(message: String = ""): js.EvalError = js.native } /** @@ -62,14 +64,14 @@ object EvalError extends Object { * * MDN */ -@native +@js.native @JSGlobal -class RangeError(message: String = "") extends Error +class RangeError(message: String = "") extends js.Error -@native +@js.native @JSGlobal -object RangeError extends Object { - def apply(message: String = ""): RangeError = native +object RangeError extends js.Object { + def apply(message: String = ""): js.RangeError = js.native } /** @@ -80,14 +82,14 @@ object RangeError extends Object { * * MDN */ -@native +@js.native @JSGlobal -class ReferenceError(message: String = "") extends Error +class ReferenceError(message: String = "") extends js.Error -@native +@js.native @JSGlobal -object ReferenceError extends Object { - def apply(message: String = ""): ReferenceError = native +object ReferenceError extends js.Object { + def apply(message: String = ""): js.ReferenceError = js.native } /** @@ -98,14 +100,14 @@ object ReferenceError extends Object { * * MDN */ -@native +@js.native @JSGlobal -class SyntaxError(message: String = "") extends Error +class SyntaxError(message: String = "") extends js.Error -@native +@js.native @JSGlobal -object SyntaxError extends Object { - def apply(message: String = ""): SyntaxError = native +object SyntaxError extends js.Object { + def apply(message: String = ""): js.SyntaxError = js.native } /** @@ -116,14 +118,14 @@ object SyntaxError extends Object { * * MDN */ -@native +@js.native @JSGlobal -class TypeError(message: String = "") extends Error +class TypeError(message: String = "") extends js.Error -@native +@js.native @JSGlobal -object TypeError extends Object { - def apply(message: String = ""): TypeError = native +object TypeError extends js.Object { + def apply(message: String = ""): js.TypeError = js.native } /** @@ -133,12 +135,12 @@ object TypeError extends Object { * * MDN */ -@native +@js.native @JSGlobal -class URIError(message: String = "") extends Error +class URIError(message: String = "") extends js.Error -@native +@js.native @JSGlobal -object URIError extends Object { - def apply(message: String = ""): URIError = native +object URIError extends js.Object { + def apply(message: String = ""): js.URIError = js.native } diff --git a/library/src/main/scala/scala/scalajs/js/Function.nodoc.scala b/library/src/main/scala/scala/scalajs/js/Function.nodoc.scala index 577d5ee300..df15c7d134 100644 --- a/library/src/main/scala/scala/scalajs/js/Function.nodoc.scala +++ b/library/src/main/scala/scala/scalajs/js/Function.nodoc.scala @@ -9,105 +9,107 @@ /* Definitions for js.Function3 to js.Function22 that do not show in doc */ package scala.scalajs.js +import scala.scalajs.js + // scalastyle:off line.size.limit -@native -trait Function3[-T1, -T2, -T3, +R] extends Function { +@js.native +trait Function3[-T1, -T2, -T3, +R] extends js.Function { def apply(arg1: T1, arg2: T2, arg3: T3): R } -@native -trait Function4[-T1, -T2, -T3, -T4, +R] extends Function { +@js.native +trait Function4[-T1, -T2, -T3, -T4, +R] extends js.Function { def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4): R } -@native -trait Function5[-T1, -T2, -T3, -T4, -T5, +R] extends Function { +@js.native +trait Function5[-T1, -T2, -T3, -T4, -T5, +R] extends js.Function { def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5): R } -@native -trait Function6[-T1, -T2, -T3, -T4, -T5, -T6, +R] extends Function { +@js.native +trait Function6[-T1, -T2, -T3, -T4, -T5, -T6, +R] extends js.Function { def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6): R } -@native -trait Function7[-T1, -T2, -T3, -T4, -T5, -T6, -T7, +R] extends Function { +@js.native +trait Function7[-T1, -T2, -T3, -T4, -T5, -T6, -T7, +R] extends js.Function { def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7): R } -@native -trait Function8[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, +R] extends Function { +@js.native +trait Function8[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, +R] extends js.Function { def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8): R } -@native -trait Function9[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, +R] extends Function { +@js.native +trait Function9[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, +R] extends js.Function { def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9): R } -@native -trait Function10[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, +R] extends Function { +@js.native +trait Function10[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, +R] extends js.Function { def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10): R } -@native -trait Function11[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, +R] extends Function { +@js.native +trait Function11[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, +R] extends js.Function { def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11): R } -@native -trait Function12[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, +R] extends Function { +@js.native +trait Function12[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, +R] extends js.Function { def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12): R } -@native -trait Function13[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, +R] extends Function { +@js.native +trait Function13[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, +R] extends js.Function { def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13): R } -@native -trait Function14[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, +R] extends Function { +@js.native +trait Function14[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, +R] extends js.Function { def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14): R } -@native -trait Function15[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, +R] extends Function { +@js.native +trait Function15[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, +R] extends js.Function { def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15): R } -@native -trait Function16[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, +R] extends Function { +@js.native +trait Function16[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, +R] extends js.Function { def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16): R } -@native -trait Function17[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, +R] extends Function { +@js.native +trait Function17[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, +R] extends js.Function { def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17): R } -@native -trait Function18[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, +R] extends Function { +@js.native +trait Function18[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, +R] extends js.Function { def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18): R } -@native -trait Function19[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, +R] extends Function { +@js.native +trait Function19[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, +R] extends js.Function { def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19): R } -@native -trait Function20[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, +R] extends Function { +@js.native +trait Function20[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, +R] extends js.Function { def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19, arg20: T20): R } -@native -trait Function21[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, +R] extends Function { +@js.native +trait Function21[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, +R] extends js.Function { def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19, arg20: T20, arg21: T21): R } -@native -trait Function22[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, -T22, +R] extends Function { +@js.native +trait Function22[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, -T22, +R] extends js.Function { def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19, arg20: T20, arg21: T21, arg22: T22): R } diff --git a/library/src/main/scala/scala/scalajs/js/Function.scala b/library/src/main/scala/scala/scalajs/js/Function.scala index 3d6e4fec56..c049aa3c6a 100644 --- a/library/src/main/scala/scala/scalajs/js/Function.scala +++ b/library/src/main/scala/scala/scalajs/js/Function.scala @@ -14,6 +14,7 @@ */ package scala.scalajs.js +import scala.scalajs.js import scala.scalajs.js.annotation._ /** @@ -41,9 +42,9 @@ import scala.scalajs.js.annotation._ * * MDN */ -@native +@js.native @JSGlobal -class Function(args: String*) extends Object { +class Function(args: String*) extends js.Object { /** * length is a property of a function object, and indicates how many arguments * the function expects, i.e. the number of formal parameters. This number @@ -85,7 +86,7 @@ class Function(args: String*) extends Object { * }}} * */ - def call(thisArg: Any, argArray: Any*): Dynamic = native + def call(thisArg: js.Any, argArray: js.Any*): js.Dynamic = js.native // Do not expose apply: use call(thisArg, argArray: _*) instead. // def apply[A](thisArg: Any, argArray: Array[A]): Dynamic = native @@ -98,26 +99,26 @@ class Function(args: String*) extends Object { * * MDN */ - def bind(thisArg: Any, argArray: Any*): Dynamic = native + def bind(thisArg: js.Any, argArray: js.Any*): js.Dynamic = js.native } -@native +@js.native @JSGlobal -object Function extends Object { - def apply(args: String*): Function = native +object Function extends js.Object { + def apply(args: String*): js.Function = js.native } -@native -trait Function0[+R] extends Function { +@js.native +trait Function0[+R] extends js.Function { def apply(): R } -@native -trait Function1[-T1, +R] extends Function { +@js.native +trait Function1[-T1, +R] extends js.Function { def apply(arg1: T1): R } -@native -trait Function2[-T1, -T2, +R] extends Function { +@js.native +trait Function2[-T1, -T2, +R] extends js.Function { def apply(arg1: T1, arg2: T2): R } diff --git a/library/src/main/scala/scala/scalajs/js/Iterable.scala b/library/src/main/scala/scala/scalajs/js/Iterable.scala index 97a898cda0..a7b2fb561f 100644 --- a/library/src/main/scala/scala/scalajs/js/Iterable.scala +++ b/library/src/main/scala/scala/scalajs/js/Iterable.scala @@ -17,6 +17,6 @@ import js.annotation._ */ trait Iterable[+A] extends js.Object { /** JavaScript Iterator for this Iterable. */ - @JSName(Symbol.iterator) - def jsIterator(): Iterator[A] + @JSName(js.Symbol.iterator) + def jsIterator(): js.Iterator[A] } diff --git a/library/src/main/scala/scala/scalajs/js/IterableOps.scala b/library/src/main/scala/scala/scalajs/js/IterableOps.scala index 37b9a79fb0..fbf5e8cd84 100644 --- a/library/src/main/scala/scala/scalajs/js/IterableOps.scala +++ b/library/src/main/scala/scala/scalajs/js/IterableOps.scala @@ -8,9 +8,11 @@ package scala.scalajs.js +import scala.scalajs.js + /** Adapts a JavaScript Iterable to a Scala Iterable */ @inline -final class IterableOps[+A](self: Iterable[A]) +final class IterableOps[+A](self: js.Iterable[A]) extends scala.collection.Iterable[A] { @inline def iterator: scala.collection.Iterator[A] = self.jsIterator().toIterator diff --git a/library/src/main/scala/scala/scalajs/js/Iterator.scala b/library/src/main/scala/scala/scalajs/js/Iterator.scala index 086202fcdb..be17d1ef6a 100644 --- a/library/src/main/scala/scala/scalajs/js/Iterator.scala +++ b/library/src/main/scala/scala/scalajs/js/Iterator.scala @@ -16,7 +16,7 @@ import js.annotation._ * JavaScript Iterator. */ trait Iterator[+A] extends js.Object { - def next(): Iterator.Entry[A] + def next(): js.Iterator.Entry[A] } object Iterator { @@ -30,7 +30,7 @@ object Iterator { } @inline - private final class WrappedIterator[+A](self: Iterator[A]) + private final class WrappedIterator[+A](self: js.Iterator[A]) extends scala.collection.Iterator[A] { private[this] var lastEntry = self.next() @@ -45,7 +45,7 @@ object Iterator { } } - final implicit class IteratorOps[A](val __self: Iterator[A]) extends AnyVal { + final implicit class IteratorOps[A](val __self: js.Iterator[A]) extends AnyVal { @inline def toIterator: scala.collection.Iterator[A] = new WrappedIterator(__self) } diff --git a/library/src/main/scala/scala/scalajs/js/JSArrayOps.scala b/library/src/main/scala/scala/scalajs/js/JSArrayOps.scala index 9ccef2b178..b12f9990da 100644 --- a/library/src/main/scala/scala/scalajs/js/JSArrayOps.scala +++ b/library/src/main/scala/scala/scalajs/js/JSArrayOps.scala @@ -16,6 +16,7 @@ package scala.scalajs.js import scala.language.implicitConversions +import scala.scalajs.js import scala.scalajs.js.annotation._ /** Discouraged native JavaScript Array methods. @@ -27,7 +28,7 @@ import scala.scalajs.js.annotation._ * To enable the use of these functions on js.[[Array]]s, import the implicit * conversion [[JSArrayOps.jsArrayOps]]. */ -trait JSArrayOps[A] extends Object { +trait JSArrayOps[A] extends js.Object { /** * The indexOf() method returns the first index at which a given element can @@ -81,10 +82,10 @@ trait JSArrayOps[A] extends Object { * MDN */ @JSName("every") - def jsEvery[T](callbackfn: ThisFunction3[T, A, Int, Array[A], Boolean], + def jsEvery[T](callbackfn: js.ThisFunction3[T, A, Int, js.Array[A], Boolean], thisArg: T): Boolean @JSName("every") - def jsEvery(callbackfn: Function3[A, Int, Array[A], Boolean]): Boolean + def jsEvery(callbackfn: js.Function3[A, Int, js.Array[A], Boolean]): Boolean /** * some executes the callback function once for each element present in the @@ -106,14 +107,14 @@ trait JSArrayOps[A] extends Object { * MDN */ @JSName("some") - def jsSome[T](callbackfn: ThisFunction3[T, A, Int, Array[A], Boolean], + def jsSome[T](callbackfn: js.ThisFunction3[T, A, Int, js.Array[A], Boolean], thisArg: T): Boolean @JSName("some") - def jsSome(callbackfn: Function3[A, Int, Array[A], Boolean]): Boolean + def jsSome(callbackfn: js.Function3[A, Int, js.Array[A], Boolean]): Boolean @JSName("some") - def jsSome(callbackfn: Function2[A, Int, Boolean]): Boolean + def jsSome(callbackfn: js.Function2[A, Int, Boolean]): Boolean @JSName("some") - def jsSome(callbackfn: Function1[A, Boolean]): Boolean + def jsSome(callbackfn: js.Function1[A, Boolean]): Boolean /** * forEach executes the provided callback once for each element of the array @@ -136,14 +137,14 @@ trait JSArrayOps[A] extends Object { * MDN */ @JSName("forEach") - def jsForEach[T](callbackfn: ThisFunction3[T, A, Int, Array[A], _], + def jsForEach[T](callbackfn: js.ThisFunction3[T, A, Int, js.Array[A], _], thisArg: T): Unit @JSName("forEach") - def jsForEach(callbackfn: Function3[A, Int, Array[A], _]): Unit + def jsForEach(callbackfn: js.Function3[A, Int, js.Array[A], _]): Unit @JSName("forEach") - def jsForEach(callbackfn: Function2[A, Int, _]): Unit + def jsForEach(callbackfn: js.Function2[A, Int, _]): Unit @JSName("forEach") - def jsForEach(callbackfn: Function1[A, _]): Unit + def jsForEach(callbackfn: js.Function1[A, _]): Unit /** * map calls a provided callback function once for each element in an array, @@ -164,14 +165,14 @@ trait JSArrayOps[A] extends Object { * MDN */ @JSName("map") - def jsMap[B, T](callbackfn: ThisFunction3[T, A, Int, Array[A], B], - thisArg: T): Array[B] + def jsMap[B, T](callbackfn: js.ThisFunction3[T, A, Int, js.Array[A], B], + thisArg: T): js.Array[B] @JSName("map") - def jsMap[B](callbackfn: Function3[A, Int, Array[A], B]): Array[B] + def jsMap[B](callbackfn: js.Function3[A, Int, js.Array[A], B]): js.Array[B] @JSName("map") - def jsMap[B](callbackfn: Function2[A, Int, B]): Array[B] + def jsMap[B](callbackfn: js.Function2[A, Int, B]): js.Array[B] @JSName("map") - def jsMap[B](callbackfn: Function1[A, B]): Array[B] + def jsMap[B](callbackfn: js.Function1[A, B]): js.Array[B] /** * filter calls a provided callback function once for each element in an array, @@ -196,14 +197,14 @@ trait JSArrayOps[A] extends Object { * MDN */ @JSName("filter") - def jsFilter[T](callbackfn: ThisFunction3[T, A, Int, Array[A], Boolean], - thisArg: T): Array[A] + def jsFilter[T](callbackfn: js.ThisFunction3[T, A, Int, js.Array[A], Boolean], + thisArg: T): js.Array[A] @JSName("filter") - def jsFilter(callbackfn: Function3[A, Int, Array[A], Boolean]): Array[A] + def jsFilter(callbackfn: js.Function3[A, Int, js.Array[A], Boolean]): js.Array[A] @JSName("filter") - def jsFilter(callbackfn: Function2[A, Int, Boolean]): Array[A] + def jsFilter(callbackfn: js.Function2[A, Int, Boolean]): js.Array[A] @JSName("filter") - def jsFilter(callbackfn: Function1[A, Boolean]): Array[A] + def jsFilter(callbackfn: js.Function1[A, Boolean]): js.Array[A] /** * reduce executes the callback function once for each element present in @@ -222,17 +223,18 @@ trait JSArrayOps[A] extends Object { * MDN */ @JSName("reduce") - def jsReduce[B](callbackfn: Function4[B, A, Int, Array[A], B], initialValue: B): B + def jsReduce[B](callbackfn: js.Function4[B, A, Int, js.Array[A], B], + initialValue: B): B @JSName("reduce") - def jsReduce[B](callbackfn: Function3[B, A, Int, B], initialValue: B): B + def jsReduce[B](callbackfn: js.Function3[B, A, Int, B], initialValue: B): B @JSName("reduce") - def jsReduce[B](callbackfn: Function2[B, A, B], initialValue: B): B + def jsReduce[B](callbackfn: js.Function2[B, A, B], initialValue: B): B @JSName("reduce") - def jsReduce[B](callbackfn: Function4[B, A, Int, Array[A], B]): B + def jsReduce[B](callbackfn: js.Function4[B, A, Int, js.Array[A], B]): B @JSName("reduce") - def jsReduce[B](callbackfn: Function3[B, A, Int, B]): B + def jsReduce[B](callbackfn: js.Function3[B, A, Int, B]): B @JSName("reduce") - def jsReduce[B](callbackfn: Function2[B, A, B]): B + def jsReduce[B](callbackfn: js.Function2[B, A, B]): B /** * reduceRight executes the callback function once for each element present @@ -244,21 +246,23 @@ trait JSArrayOps[A] extends Object { * MDN */ @JSName("reduceRight") - def jsReduceRight[B](callbackfn: Function4[B, A, Int, Array[A], B], initialValue: B): B + def jsReduceRight[B](callbackfn: js.Function4[B, A, Int, js.Array[A], B], + initialValue: B): B @JSName("reduceRight") - def jsReduceRight[B](callbackfn: Function3[B, A, Int, B], initialValue: B): B + def jsReduceRight[B](callbackfn: js.Function3[B, A, Int, B], + initialValue: B): B @JSName("reduceRight") - def jsReduceRight[B](callbackfn: Function2[B, A, B], initialValue: B): B + def jsReduceRight[B](callbackfn: js.Function2[B, A, B], initialValue: B): B @JSName("reduceRight") - def jsReduceRight[B](callbackfn: Function4[B, A, Int, Array[A], B]): B + def jsReduceRight[B](callbackfn: js.Function4[B, A, Int, js.Array[A], B]): B @JSName("reduceRight") - def jsReduceRight[B](callbackfn: Function3[B, A, Int, B]): B + def jsReduceRight[B](callbackfn: js.Function3[B, A, Int, B]): B @JSName("reduceRight") - def jsReduceRight[B](callbackfn: Function2[B, A, B]): B + def jsReduceRight[B](callbackfn: js.Function2[B, A, B]): B } object JSArrayOps { - @inline implicit def jsArrayOps[A](array: Array[A]): JSArrayOps[A] = - array.asInstanceOf[JSArrayOps[A]] + @inline implicit def jsArrayOps[A](array: js.Array[A]): js.JSArrayOps[A] = + array.asInstanceOf[js.JSArrayOps[A]] } diff --git a/library/src/main/scala/scala/scalajs/js/JSConverters.scala b/library/src/main/scala/scala/scalajs/js/JSConverters.scala index 34ce5c52ba..8b78321279 100644 --- a/library/src/main/scala/scala/scalajs/js/JSConverters.scala +++ b/library/src/main/scala/scala/scalajs/js/JSConverters.scala @@ -12,61 +12,62 @@ package scala.scalajs.js import scala.language.implicitConversions import scala.scalajs.js -import scala.scalajs.js.annotation.{JSName, ScalaJSDefined} +import scala.scalajs.js.annotation._ import scala.collection._ import scala.concurrent.{ExecutionContext, Future} import scala.scalajs.runtime.genTraversableOnce2jsArray -sealed abstract class JSConvertersLowPrioImplicits { this: JSConverters.type => +sealed abstract class JSConvertersLowPrioImplicits { + this: js.JSConverters.type => @inline implicit def JSRichFutureNonThenable[A](f: Future[A]): JSRichFuture[A] = - new JSRichFuture[A](f.asInstanceOf[Future[A | Thenable[A]]]) + new JSRichFuture[A](f) } /** A collection of decorators that allow converting Scala types to * corresponding JS facade types */ -object JSConverters extends JSConvertersLowPrioImplicits { +object JSConverters extends js.JSConvertersLowPrioImplicits { implicit class JSRichOption[T](val opt: Option[T]) extends AnyVal { - @inline final def orUndefined: UndefOr[T] = - opt.fold[UndefOr[T]](undefined)(v => v) + @inline final def orUndefined: js.UndefOr[T] = + opt.fold[js.UndefOr[T]](undefined)(v => v) } implicit class JSRichGenTraversableOnce[T]( val col: GenTraversableOnce[T]) extends AnyVal { - @inline final def toJSArray: Array[T] = genTraversableOnce2jsArray(col) + @inline final def toJSArray: js.Array[T] = genTraversableOnce2jsArray(col) } implicit class JSRichGenIterable[T]( val __self: GenIterable[T]) extends AnyVal { - @inline final def toJSIterable: Iterable[T] = new IterableAdapter(__self) + @inline final def toJSIterable: js.Iterable[T] = new IterableAdapter(__self) } implicit class JSRichIterator[T]( val __self: scala.collection.Iterator[T]) extends AnyVal { - @inline final def toJSIterator: Iterator[T] = new IteratorAdapter(__self) + @inline final def toJSIterator: js.Iterator[T] = new IteratorAdapter(__self) } - private class IterableAdapter[+T](col: GenIterable[T]) extends Iterable[T] { - @JSName(Symbol.iterator) - final def jsIterator(): Iterator[T] = col.iterator.toJSIterator + private class IterableAdapter[+T](col: GenIterable[T]) extends js.Iterable[T] { + @JSName(js.Symbol.iterator) + final def jsIterator(): js.Iterator[T] = col.iterator.toJSIterator } private class IteratorAdapter[+T]( - it: scala.collection.Iterator[T]) extends Iterator[T] { - final def next(): Iterator.Entry[T] = { + it: scala.collection.Iterator[T]) extends js.Iterator[T] { + final def next(): js.Iterator.Entry[T] = { if (it.hasNext) { - new Iterator.Entry[T] { + new js.Iterator.Entry[T] { val done: Boolean = false val value: T = it.next() } } else { - new Iterator.Entry[T] { + new js.Iterator.Entry[T] { val done: Boolean = true // Evil cast to work around typing. By specification, reading `value` // is undefined behavior, so this is ok. @@ -77,8 +78,8 @@ object JSConverters extends JSConvertersLowPrioImplicits { } implicit class JSRichGenMap[T](val map: GenMap[String, T]) extends AnyVal { - @inline final def toJSDictionary: Dictionary[T] = { - val result = Dictionary.empty[T] + @inline final def toJSDictionary: js.Dictionary[T] = { + val result = js.Dictionary.empty[T] map.foreach { case (key, value) => result(key) = value } result } @@ -98,10 +99,10 @@ object JSConverters extends JSConvertersLowPrioImplicits { new JSRichGenTraversableOnce(arr) @inline - implicit def JSRichFutureThenable[A](f: Future[Thenable[A]]): JSRichFuture[A] = - new JSRichFuture[A](f.asInstanceOf[Future[A | Thenable[A]]]) + implicit def JSRichFutureThenable[A](f: Future[js.Thenable[A]]): JSRichFuture[A] = + new JSRichFuture[A](f) - final class JSRichFuture[A](val self: Future[A | Thenable[A]]) extends AnyVal { + final class JSRichFuture[A](val self: Future[A | js.Thenable[A]]) extends AnyVal { /** Converts the Future to a JavaScript [[Promise]]. * * Attention! The nature of the [[Promise]] class, from the ECMAScript @@ -111,17 +112,17 @@ object JSConverters extends JSConvertersLowPrioImplicits { * The signature of the `toJSPromise` method is only valid * provided that the values of `A` do not have a `then` method. */ - def toJSPromise(implicit executor: ExecutionContext): Promise[A] = { - new Promise[A]({ - (resolve: js.Function1[A | Thenable[A], _], reject: js.Function1[scala.Any, _]) => + def toJSPromise(implicit executor: ExecutionContext): js.Promise[A] = { + new js.Promise[A]({ + (resolve: js.Function1[A | js.Thenable[A], _], reject: js.Function1[scala.Any, _]) => self onComplete { case scala.util.Success(value) => resolve(value) case scala.util.Failure(th) => reject(th match { - case JavaScriptException(e) => e - case _ => th + case js.JavaScriptException(e) => e + case _ => th }) } }) diff --git a/library/src/main/scala/scala/scalajs/js/JSNumberOps.scala b/library/src/main/scala/scala/scalajs/js/JSNumberOps.scala index 7267f6ef88..b81f18b0c7 100644 --- a/library/src/main/scala/scala/scalajs/js/JSNumberOps.scala +++ b/library/src/main/scala/scala/scalajs/js/JSNumberOps.scala @@ -16,10 +16,11 @@ package scala.scalajs.js import scala.language.implicitConversions +import scala.scalajs.js import scala.scalajs.js.annotation._ /** Operations on JavaScript numbers. */ -trait JSNumberOps extends Any { +trait JSNumberOps extends js.Any { def toString(radix: Int): String @@ -69,21 +70,21 @@ trait JSNumberOps extends Any { } object JSNumberOps { - implicit def enableJSNumberOps(x: Int): JSNumberOps = - x.asInstanceOf[JSNumberOps] + implicit def enableJSNumberOps(x: Int): js.JSNumberOps = + x.asInstanceOf[js.JSNumberOps] - implicit def enableJSNumberOps(x: Double): JSNumberOps = - x.asInstanceOf[JSNumberOps] + implicit def enableJSNumberOps(x: Double): js.JSNumberOps = + x.asInstanceOf[js.JSNumberOps] implicit def enableJSNumberExtOps(x: Int): ExtOps = - new ExtOps(x.asInstanceOf[Dynamic]) + new ExtOps(x.asInstanceOf[js.Dynamic]) implicit def enableJSNumberExtOps(x: Double): ExtOps = - new ExtOps(x.asInstanceOf[Dynamic]) + new ExtOps(x.asInstanceOf[js.Dynamic]) - final class ExtOps(val self: Dynamic) extends AnyVal { + final class ExtOps(val self: js.Dynamic) extends AnyVal { @inline def toUint: Double = - (self >>> 0.asInstanceOf[Dynamic]).asInstanceOf[Double] + (self >>> 0.asInstanceOf[js.Dynamic]).asInstanceOf[Double] } /* The following overloads make sure that the developer does not use JS @@ -93,12 +94,12 @@ object JSNumberOps { @deprecated("A Long is converted to Double to perform JavaScript "+ "operations. This is almost certainly not what you want. "+ "Use `.toDouble` explicitly if you need it.", "forever") - implicit def enableJSNumberOps(x: Long): JSNumberOps = - x.toDouble.asInstanceOf[JSNumberOps] + implicit def enableJSNumberOps(x: Long): js.JSNumberOps = + x.toDouble.asInstanceOf[js.JSNumberOps] @deprecated("A Long is converted to Double to perform JavaScript "+ "operations. This is almost certainly not what you want. "+ "Use `.toDouble` explicitly if you need it.", "forever") implicit def enableJSNumberExtOps(x: Long): ExtOps = - new ExtOps(x.toDouble.asInstanceOf[Dynamic]) + new ExtOps(x.toDouble.asInstanceOf[js.Dynamic]) } diff --git a/library/src/main/scala/scala/scalajs/js/JSON.scala b/library/src/main/scala/scala/scalajs/js/JSON.scala index 2578b84609..8b9b6e7432 100644 --- a/library/src/main/scala/scala/scalajs/js/JSON.scala +++ b/library/src/main/scala/scala/scalajs/js/JSON.scala @@ -14,6 +14,7 @@ */ package scala.scalajs.js +import scala.scalajs.js import scala.scalajs.js.annotation._ /** @@ -22,9 +23,9 @@ import scala.scalajs.js.annotation._ * * MDN */ -@native +@js.native @JSGlobal -object JSON extends Object { +object JSON extends js.Object { /** * Parse a string as JSON, optionally transforming the value produced by parsing. * @param text The string to parse as JSON. See the JSON object for a @@ -34,7 +35,8 @@ object JSON extends Object { * * MDN */ - def parse(text: String, reviver: Function2[Any, Any, Any] = ???): Dynamic = native + def parse(text: String, + reviver: js.Function2[js.Any, js.Any, js.Any] = ???): js.Dynamic = js.native /** * Convert a value to JSON, optionally replacing values if a replacer function @@ -49,7 +51,10 @@ object JSON extends Object { * * MDN */ - def stringify(value: Any, replacer: Function2[String, Any, Any] = ???, space: Any = ???): String = native - def stringify(value: Any, replacer: Array[Any]): String = native - def stringify(value: Any, replacer: Array[Any], space: Any): String = native + def stringify(value: js.Any, + replacer: js.Function2[String, js.Any, js.Any] = ???, + space: js.Any = ???): String = js.native + def stringify(value: js.Any, replacer: js.Array[Any]): String = js.native + def stringify(value: js.Any, replacer: js.Array[Any], + space: js.Any): String = js.native } diff --git a/library/src/main/scala/scala/scalajs/js/JSStringOps.scala b/library/src/main/scala/scala/scalajs/js/JSStringOps.scala index a64d8d04aa..7e43b8a3fd 100644 --- a/library/src/main/scala/scala/scalajs/js/JSStringOps.scala +++ b/library/src/main/scala/scala/scalajs/js/JSStringOps.scala @@ -16,6 +16,7 @@ package scala.scalajs.js import scala.language.implicitConversions +import scala.scalajs.js import scala.scalajs.js.annotation._ /** Operations on JavaScript strings. @@ -23,7 +24,7 @@ import scala.scalajs.js.annotation._ * The methods with an equivalent signature in [[java.lang.String String]] but * with a different meaning are prefixed by `js` in this trait. */ -trait JSStringOps extends Any { +trait JSStringOps extends js.Any { /** * Returns the index within the calling String object of the first occurrence @@ -77,8 +78,8 @@ trait JSStringOps extends Any { * * MDN */ - def `match`(regexp: String): Array[String] - def `match`(regexp: RegExp): Array[String] + def `match`(regexp: String): js.Array[String] + def `match`(regexp: js.RegExp): js.Array[String] /** * Returns a new string with some or all matches of a pattern replaced by a @@ -97,11 +98,11 @@ trait JSStringOps extends Any { @JSName("replace") def jsReplace(searchValue: String, replaceValue: String): String @JSName("replace") - def jsReplace(searchValue: String, replaceValue: Any): String + def jsReplace(searchValue: String, replaceValue: js.Any): String @JSName("replace") - def jsReplace(searchValue: RegExp, replaceValue: String): String + def jsReplace(searchValue: js.RegExp, replaceValue: String): String @JSName("replace") - def jsReplace(searchValue: RegExp, replaceValue: Any): String + def jsReplace(searchValue: js.RegExp, replaceValue: js.Any): String /** * If successful, search returns the index of the regular expression inside @@ -115,7 +116,7 @@ trait JSStringOps extends Any { * MDN */ def search(regexp: String): Int - def search(regexp: RegExp): Int + def search(regexp: js.RegExp): Int /** * slice extracts the text from one string and returns a new string. Changes @@ -155,13 +156,13 @@ trait JSStringOps extends Any { * MDN */ @JSName("split") - def jsSplit(separator: String, limit: Int): Array[String] + def jsSplit(separator: String, limit: Int): js.Array[String] @JSName("split") - def jsSplit(separator: String): Array[String] + def jsSplit(separator: String): js.Array[String] @JSName("split") - def jsSplit(separator: RegExp, limit: Int): Array[String] + def jsSplit(separator: js.RegExp, limit: Int): js.Array[String] @JSName("split") - def jsSplit(separator: RegExp): Array[String] + def jsSplit(separator: js.RegExp): js.Array[String] /** * Returns a subset of a string between one index and another, or through @@ -201,7 +202,7 @@ trait JSStringOps extends Any { /** ECMAScript 6 * Returns the Unicode Normalization Form of this string. */ - def normalize(form: UnicodeNormalizationForm): String + def normalize(form: js.UnicodeNormalizationForm): String /** ECMAScript 6 * Returns the Unicode Normalization Form of this string, with the NFC form. @@ -210,6 +211,6 @@ trait JSStringOps extends Any { } object JSStringOps { - implicit def enableJSStringOps(x: String): JSStringOps = - x.asInstanceOf[JSStringOps] + implicit def enableJSStringOps(x: String): js.JSStringOps = + x.asInstanceOf[js.JSStringOps] } diff --git a/library/src/main/scala/scala/scalajs/js/Math.scala b/library/src/main/scala/scala/scalajs/js/Math.scala index db9f06b2e7..9d571dc70d 100644 --- a/library/src/main/scala/scala/scalajs/js/Math.scala +++ b/library/src/main/scala/scala/scalajs/js/Math.scala @@ -14,6 +14,7 @@ */ package scala.scalajs.js +import scala.scalajs.js import scala.scalajs.js.annotation._ /** @@ -22,59 +23,59 @@ import scala.scalajs.js.annotation._ * * MDN */ -@native +@js.native @JSGlobal -object Math extends Object { +object Math extends js.Object { /** * Euler's constant and the base of natural logarithms, approximately 2.718. * * MDN */ - val E: Double = native + val E: Double = js.native /** * Natural logarithm of 10, approximately 2.303. * * MDN */ - val LN10: Double = native + val LN10: Double = js.native /** * Natural logarithm of 2, approximately 0.693. * * MDN */ - val LN2: Double = native + val LN2: Double = js.native /** * Base 2 logarithm of E, approximately 1.443. * * MDN */ - val LOG2E: Double = native + val LOG2E: Double = js.native /** * Base 10 logarithm of E, approximately 0.434. * * MSN */ - val LOG10E: Double = native + val LOG10E: Double = js.native /** * Ratio of the circumference of a circle to its diameter, approximately 3.14159. * * MDN */ - val PI: Double = native + val PI: Double = js.native /** * Square root of 1/2; equivalently, 1 over the square root of 2, approximately 0.707. * * MDN */ - val SQRT1_2: Double = native + val SQRT1_2: Double = js.native /** * Square root of 2, approximately 1.414. * * MDN */ - val SQRT2: Double = native + val SQRT2: Double = js.native /** * Returns the absolute value of a number. @@ -84,7 +85,7 @@ object Math extends Object { * * MDN */ - def abs(x: Int): Int = native + def abs(x: Int): Int = js.native /** * Returns the absolute value of a number. @@ -94,7 +95,7 @@ object Math extends Object { * * MDN */ - def abs(x: Double): Double = native + def abs(x: Double): Double = js.native /** * The Math.acos() function returns the arccosine (in radians) of a number. @@ -104,7 +105,7 @@ object Math extends Object { * * MDN */ - def acos(x: Double): Double = native + def acos(x: Double): Double = js.native /** * The Math.asin() function returns the arcsine (in radians) of a number. @@ -114,7 +115,7 @@ object Math extends Object { * * MDN */ - def asin(x: Double): Double = native + def asin(x: Double): Double = js.native /** * The Math.atan() function returns the arctangent (in radians) of a number. @@ -123,7 +124,7 @@ object Math extends Object { * * MDN */ - def atan(x: Double): Double = native + def atan(x: Double): Double = js.native /** * The Math.atan2() function returns the arctangent of the quotient of its @@ -140,7 +141,7 @@ object Math extends Object { * * MDN */ - def atan2(y: Double, x: Double): Double = native + def atan2(y: Double, x: Double): Double = js.native /** * The Math.ceil() function returns the smallest integer greater than or @@ -148,7 +149,7 @@ object Math extends Object { * * MDN */ - def ceil(x: Double): Double = native + def ceil(x: Double): Double = js.native /** * The Math.cos() function returns the cosine of a number. @@ -158,7 +159,7 @@ object Math extends Object { * * MDN */ - def cos(x: Double): Double = native + def cos(x: Double): Double = js.native /** * The Math.exp() function returns E^x, where x is the argument, and E is @@ -166,7 +167,7 @@ object Math extends Object { * * MDN */ - def exp(x: Double): Double = native + def exp(x: Double): Double = js.native /** * The Math.floor() function returns the largest integer less than or equal @@ -174,7 +175,7 @@ object Math extends Object { * * MDN */ - def floor(x: Double): Double = native + def floor(x: Double): Double = js.native /** * The Math.log() function returns the natural logarithm (base E) of a number. @@ -183,14 +184,14 @@ object Math extends Object { * * MDN */ - def log(x: Double): Double = native + def log(x: Double): Double = js.native /** * The Math.max() function returns the largest of zero or more numbers. * * MDN */ - def max(value1: Int, values: Int*): Int = native + def max(value1: Int, values: Int*): Int = js.native /** * The Math.max() function returns the largest of zero or more numbers. @@ -201,14 +202,14 @@ object Math extends Object { * * MDN */ - def max(values: Double*): Double = native + def max(values: Double*): Double = js.native /** * The Math.min() function returns the smallest of zero or more numbers. * * MDN */ - def min(value1: Int, values: Int*): Int = native + def min(value1: Int, values: Int*): Int = js.native /** * The Math.min() function returns the smallest of zero or more numbers. @@ -219,14 +220,14 @@ object Math extends Object { * * MDN */ - def min(values: Double*): Double = native + def min(values: Double*): Double = js.native /** * The Math.pow() function returns the base to the exponent Power, that is, base^^exponent. * * MDN */ - def pow(x: Double, y: Double): Double = native + def pow(x: Double, y: Double): Double = js.native /** * The Math.random() function returns a floating-point, pseudo-random number in @@ -237,7 +238,7 @@ object Math extends Object { * * MDN */ - def random(): Double = native + def random(): Double = js.native /** * The Math.round() function returns the value of a number rounded to the @@ -249,7 +250,7 @@ object Math extends Object { * * MDN */ - def round(x: Double): Double = native + def round(x: Double): Double = js.native /** * The Math.sin() function returns the sine of a number. @@ -259,7 +260,7 @@ object Math extends Object { * * MDN */ - def sin(x: Double): Double = native + def sin(x: Double): Double = js.native /** * The Math.sqrt() function returns the square root (x\sqrt{x}) of a number. @@ -268,7 +269,7 @@ object Math extends Object { * * MDN */ - def sqrt(x: Double): Double = native + def sqrt(x: Double): Double = js.native /** * The Math.tan() function returns the tangent of a number. @@ -277,7 +278,7 @@ object Math extends Object { * * MDN */ - def tan(x: Double): Double = native + def tan(x: Double): Double = js.native /** ECMAScript 6 * The Math.log1p() function returns the natural logarithm (base e) of @@ -287,7 +288,7 @@ object Math extends Object { * If the number is less than -1, NaN is returned. * MDN */ - def log1p(x: Double): Double = native + def log1p(x: Double): Double = js.native /** ECMAScript 6 * The Math.log10() function returns the base 10 logarithm of a number @@ -297,7 +298,7 @@ object Math extends Object { * * MDN */ - def log10(x: Double): Double = native + def log10(x: Double): Double = js.native /** ECMAScript 6 * The Math.sinh() function returns the hyperbolic sine of a number @@ -306,7 +307,7 @@ object Math extends Object { * * MDN */ - def sinh(x: Double): Double = native + def sinh(x: Double): Double = js.native /** ECMAScript 6 * The Math.cosh() function returns the hyperbolic cosine of a number @@ -315,7 +316,7 @@ object Math extends Object { * * MDN */ - def cosh(x: Double): Double = native + def cosh(x: Double): Double = js.native /** ECMAScript 6 * The Math.tanh() function returns the hyperbolic tangent of a number @@ -324,7 +325,7 @@ object Math extends Object { * * MDN */ - def tanh(x: Double): Double = native + def tanh(x: Double): Double = js.native /** ECMAScript 6 * The Math.cbrt() function returns the cube root of a number @@ -333,7 +334,7 @@ object Math extends Object { * * MDN */ - def cbrt(x: Double): Double = native + def cbrt(x: Double): Double = js.native /** ECMAScript 6 * The Math.hypot() function returns the square root of the sum of squares @@ -343,7 +344,7 @@ object Math extends Object { * * MDN */ - def hypot(x: Double*): Double = native + def hypot(x: Double*): Double = js.native /** ECMAScript 6 * The Math.expm1() function returns e^x - 1, where x is the argument, @@ -352,5 +353,5 @@ object Math extends Object { * @return A number representing e^x - 1, where e is Euler's number and * x is the argument. */ - def expm1(x: Double): Double = native + def expm1(x: Double): Double = js.native } diff --git a/library/src/main/scala/scala/scalajs/js/Object.scala b/library/src/main/scala/scala/scalajs/js/Object.scala index 63dc520e6d..fb578e005d 100644 --- a/library/src/main/scala/scala/scalajs/js/Object.scala +++ b/library/src/main/scala/scala/scalajs/js/Object.scala @@ -14,16 +14,17 @@ */ package scala.scalajs.js +import scala.scalajs.js import scala.scalajs.js.annotation._ /** Base class of all JavaScript objects. */ -@native +@js.native @JSGlobal -class Object extends Any { +class Object extends js.Any { def this(value: scala.Any) = this() - def toLocaleString(): String = native - def valueOf(): scala.Any = native + def toLocaleString(): String = js.native + def valueOf(): scala.Any = js.native /** Tests whether this object has the specified property as a direct property. * @@ -32,10 +33,10 @@ class Object extends Any { * * MDN */ - def hasOwnProperty(v: String): Boolean = native + def hasOwnProperty(v: String): Boolean = js.native /** Tests whether this object is in the prototype chain of another object. */ - def isPrototypeOf(v: Object): Boolean = native + def isPrototypeOf(v: Object): Boolean = js.native /** Tests whether the specified property in an object can be enumerated by a * call to [[js.Object.properties]], with the exception of properties @@ -44,20 +45,20 @@ class Object extends Any { * * MDN */ - def propertyIsEnumerable(v: String): Boolean = native + def propertyIsEnumerable(v: String): Boolean = js.native } /** The top-level `Object` JavaScript object. */ -@native +@js.native @JSGlobal -object Object extends Object { - def apply(): Object = native - def apply(value: scala.Any): Object = native +object Object extends js.Object { + def apply(): js.Object = js.native + def apply(value: scala.Any): js.Object = js.native /** Tests whether the object has a property on itself or in its prototype * chain. This method is the equivalent of `p in o` in JavaScript. */ - def hasProperty(o: Object, p: String): Boolean = + def hasProperty(o: js.Object, p: String): Boolean = throw new java.lang.Error("stub") /** @@ -66,7 +67,7 @@ object Object extends Object { * * MDN */ - def getPrototypeOf(o: Object): Object = native + def getPrototypeOf(o: js.Object): js.Object = js.native /** * The Object.getOwnPropertyDescriptor() method returns a property descriptor @@ -75,7 +76,8 @@ object Object extends Object { * * MDN */ - def getOwnPropertyDescriptor(o: Object, p: String): PropertyDescriptor = native + def getOwnPropertyDescriptor(o: js.Object, + p: String): js.PropertyDescriptor = js.native /** * Object.getOwnPropertyNames returns an array whose elements are strings @@ -87,7 +89,7 @@ object Object extends Object { * * MDN */ - def getOwnPropertyNames(o: Object): Array[String] = native + def getOwnPropertyNames(o: js.Object): js.Array[String] = js.native /** * The Object.create() method creates a new object with the specified @@ -95,8 +97,8 @@ object Object extends Object { * * MDN */ - def create(o: Object, properties: Any): Object = native - def create(o: Object): Object = native + def create(o: js.Object, properties: js.Any): js.Object = js.native + def create(o: js.Object): js.Object = native /** * The Object.defineProperty() method defines a new property directly on an @@ -117,7 +119,8 @@ object Object extends Object { * * MDN */ - def defineProperty(o: Object, p: String, attributes: PropertyDescriptor): o.type = native + def defineProperty(o: js.Object, p: String, + attributes: js.PropertyDescriptor): o.type = js.native /** * The Object.defineProperties() method defines new or modifies existing @@ -125,7 +128,7 @@ object Object extends Object { * * MDN */ - def defineProperties(o: Object, properties: Any): o.type = native + def defineProperties(o: js.Object, properties: js.Any): o.type = js.native /** * The Object.seal() method seals an object, preventing new properties from @@ -135,7 +138,7 @@ object Object extends Object { * * MDN */ - def seal(o: Object): o.type = native + def seal(o: js.Object): o.type = js.native /** * The Object.freeze() method freezes an object: that is, prevents new properties @@ -146,7 +149,7 @@ object Object extends Object { * * MDN */ - def freeze(o: Object): o.type = native + def freeze(o: js.Object): o.type = js.native /** * The Object.preventExtensions() method prevents new properties from ever @@ -166,7 +169,7 @@ object Object extends Object { * * MDN */ - def preventExtensions(o: Object): o.type = native + def preventExtensions(o: js.Object): o.type = js.native /** * Returns true if the object is sealed, otherwise false. An object is sealed @@ -175,7 +178,7 @@ object Object extends Object { * * MDN */ - def isSealed(o: Object): Boolean = native + def isSealed(o: js.Object): Boolean = js.native /** * The Object.isFrozen() determines if an object is frozen. @@ -186,7 +189,7 @@ object Object extends Object { * * MDN */ - def isFrozen(o: Object): Boolean = native + def isFrozen(o: js.Object): Boolean = js.native /** * Determines if extending of an object is allowed @@ -198,7 +201,7 @@ object Object extends Object { * * MDN */ - def isExtensible(o: Object): Boolean = native + def isExtensible(o: js.Object): Boolean = js.native /** * The Object.keys() method returns an array of a given object's own enumerable @@ -208,7 +211,7 @@ object Object extends Object { * * MDN */ - def keys(o: Object): Array[String] = native + def keys(o: js.Object): js.Array[String] = js.native /** Returns the names of all the enumerable properties of this object, * including properties in its prototype chain. @@ -221,5 +224,6 @@ object Object extends Object { * that the list returned by [[keys]] is a sublist of the list returned by * this method (not just a subset). */ - def properties(o: Any): Array[String] = throw new java.lang.Error("stub") + def properties(o: js.Any): js.Array[String] = + throw new java.lang.Error("stub") } diff --git a/library/src/main/scala/scala/scalajs/js/Promise.scala b/library/src/main/scala/scala/scalajs/js/Promise.scala index e016e35a14..7598d8e4dd 100644 --- a/library/src/main/scala/scala/scalajs/js/Promise.scala +++ b/library/src/main/scala/scala/scalajs/js/Promise.scala @@ -40,31 +40,31 @@ import scala.concurrent.Future @js.native @JSGlobal class Promise[+A]( - executor: js.Function2[js.Function1[A | Thenable[A], _], js.Function1[scala.Any, _], _]) + executor: js.Function2[js.Function1[A | js.Thenable[A], _], js.Function1[scala.Any, _], _]) extends js.Object with js.Thenable[A] { def `then`[B]( - onFulfilled: js.Function1[A, B | Thenable[B]], - onRejected: js.UndefOr[js.Function1[scala.Any, B | Thenable[B]]] = js.undefined): Thenable[B] = js.native + onFulfilled: js.Function1[A, B | js.Thenable[B]], + onRejected: js.UndefOr[js.Function1[scala.Any, B | js.Thenable[B]]] = js.undefined): js.Thenable[B] = js.native def `then`[B >: A]( onFulfilled: Unit, - onRejected: js.UndefOr[js.Function1[scala.Any, B | Thenable[B]]]): Thenable[B] = js.native + onRejected: js.UndefOr[js.Function1[scala.Any, B | js.Thenable[B]]]): js.Thenable[B] = js.native def `catch`[B >: A]( - onRejected: js.UndefOr[js.Function1[scala.Any, B | Thenable[B]]] = js.undefined): Promise[B] = js.native + onRejected: js.UndefOr[js.Function1[scala.Any, B | js.Thenable[B]]] = js.undefined): js.Promise[B] = js.native } @js.native @JSGlobal object Promise extends js.Object { /** Returns a new [[Promise]] completed with the specified `value`. */ - def resolve[A](value: A | Thenable[A]): Promise[A] = js.native + def resolve[A](value: A | js.Thenable[A]): js.Promise[A] = js.native /** Returns a new [[Promise]] failed with the specified `reason`. */ - def reject(reason: scala.Any): Promise[Nothing] = js.native + def reject(reason: scala.Any): js.Promise[Nothing] = js.native - def all[A](promises: js.Iterable[Promise[A]]): Promise[js.Array[A]] = js.native + def all[A](promises: js.Iterable[js.Promise[A]]): js.Promise[js.Array[A]] = js.native - def race[A](promises: js.Iterable[Promise[A]]): Promise[A] = js.native + def race[A](promises: js.Iterable[js.Promise[A]]): js.Promise[A] = js.native } diff --git a/library/src/main/scala/scala/scalajs/js/PropertyDescriptor.scala b/library/src/main/scala/scala/scalajs/js/PropertyDescriptor.scala index 58e6f67670..91ea994573 100644 --- a/library/src/main/scala/scala/scalajs/js/PropertyDescriptor.scala +++ b/library/src/main/scala/scala/scalajs/js/PropertyDescriptor.scala @@ -12,7 +12,7 @@ package scala.scalajs.js import scala.scalajs.js -trait PropertyDescriptor extends Object { +trait PropertyDescriptor extends js.Object { // All kinds of property descriptors var configurable: js.UndefOr[Boolean] = js.undefined diff --git a/library/src/main/scala/scala/scalajs/js/RegExp.scala b/library/src/main/scala/scala/scalajs/js/RegExp.scala index 33ae1c5e7f..06d9c1ab72 100644 --- a/library/src/main/scala/scala/scalajs/js/RegExp.scala +++ b/library/src/main/scala/scala/scalajs/js/RegExp.scala @@ -14,6 +14,7 @@ */ package scala.scalajs.js +import scala.scalajs.js import scala.scalajs.js.annotation._ /** @@ -22,11 +23,11 @@ import scala.scalajs.js.annotation._ * * MDN */ -@native +@js.native @JSGlobal -class RegExp(pattern: String, flags: String = "") extends Object { +class RegExp(pattern: String, flags: String = "") extends js.Object { /** Creates a new RegExp with the same pattern and flags as the given one. */ - def this(pattern: RegExp) = this("", "") + def this(pattern: js.RegExp) = this("", "") /** * The source property returns a String containing the text of the pattern, @@ -36,7 +37,7 @@ class RegExp(pattern: String, flags: String = "") extends Object { * * MDN */ - val source: String = native + val source: String = js.native /** * The value of global is a Boolean and true if the "g" flag was used; * otherwise, false. The "g" flag indicates that the regular expression @@ -44,7 +45,7 @@ class RegExp(pattern: String, flags: String = "") extends Object { * * MDN */ - val global: Boolean = native + val global: Boolean = js.native /** * The value of ignoreCase is a Boolean and true if the "i" flag was used; * otherwise, false. The "i" flag indicates that case should be ignored while @@ -52,7 +53,7 @@ class RegExp(pattern: String, flags: String = "") extends Object { * * MDN */ - val ignoreCase: Boolean = native + val ignoreCase: Boolean = js.native /** * The value of multiline is a Boolean and is true if the "m" flag was used; * otherwise, false. The "m" flag indicates that a multiline input string @@ -62,7 +63,7 @@ class RegExp(pattern: String, flags: String = "") extends Object { * MDN */ - val multiline: Boolean = native + val multiline: Boolean = js.native /** * The lastIndex is a read/write integer property of regular expressions that @@ -70,7 +71,7 @@ class RegExp(pattern: String, flags: String = "") extends Object { * * MDN */ - var lastIndex: Int = native + var lastIndex: Int = js.native /** * The exec() method executes a search for a match in a specified string. @@ -88,7 +89,7 @@ class RegExp(pattern: String, flags: String = "") extends Object { * * MDN */ - def exec(string: String): RegExp.ExecResult = native + def exec(string: String): js.RegExp.ExecResult = js.native /** * The test() method executes a search for a match between a regular expression @@ -102,15 +103,15 @@ class RegExp(pattern: String, flags: String = "") extends Object { * * MDN */ - def test(string: String): Boolean = native + def test(string: String): Boolean = js.native } -@native +@js.native @JSGlobal -object RegExp extends Object { - def apply(pattern: String, flags: String = ""): RegExp = native +object RegExp extends js.Object { + def apply(pattern: String, flags: String = ""): js.RegExp = js.native - trait ExecResult extends Array[UndefOr[String]] { + trait ExecResult extends js.Array[js.UndefOr[String]] { var index: Int var input: String } diff --git a/library/src/main/scala/scala/scalajs/js/Symbol.scala b/library/src/main/scala/scala/scalajs/js/Symbol.scala index c6a8a8bd9f..3bcf1a2fc6 100644 --- a/library/src/main/scala/scala/scalajs/js/Symbol.scala +++ b/library/src/main/scala/scala/scalajs/js/Symbol.scala @@ -37,13 +37,13 @@ object Symbol extends js.Object { * * @group factories */ - def apply(): Symbol = js.native + def apply(): js.Symbol = js.native /** Creates a new unique symbol with the specified description. * * @group factories */ - def apply(description: String): Symbol = js.native + def apply(description: String): js.Symbol = js.native /** Retrieves the symbol with the specified key in the global symbol registry. * @@ -55,78 +55,78 @@ object Symbol extends js.Object { * @group registry */ @JSName("for") - def forKey(key: String): Symbol = js.native + def forKey(key: String): js.Symbol = js.native /** Retrieves the key under which the specified symbol is registered in the * global symbol registry, or `undefined` if it is not registered. * * @group registry */ - def keyFor(sym: Symbol): js.UndefOr[String] = js.native + def keyFor(sym: js.Symbol): js.UndefOr[String] = js.native /** The well-known symbol `@@hasInstance`. * * @group wellknownsyms */ - val hasInstance: Symbol = js.native + val hasInstance: js.Symbol = js.native /** The well-known symbol `@@isConcatSpreadable`. * * @group wellknownsyms */ - val isConcatSpreadable: Symbol = js.native + val isConcatSpreadable: js.Symbol = js.native /** The well-known symbol `@@iterator`. * * @group wellknownsyms */ - val iterator: Symbol = js.native + val iterator: js.Symbol = js.native /** The well-known symbol `@@match`. * * @group wellknownsyms */ - val `match`: Symbol = js.native + val `match`: js.Symbol = js.native /** The well-known symbol `@@replace`. * * @group wellknownsyms */ - val replace: Symbol = js.native + val replace: js.Symbol = js.native /** The well-known symbol `@@search`. * * @group wellknownsyms */ - val search: Symbol = js.native + val search: js.Symbol = js.native /** The well-known symbol `@@species`. * * @group wellknownsyms */ - val species: Symbol = js.native + val species: js.Symbol = js.native /** The well-known symbol `@@split`. * * @group wellknownsyms */ - val split: Symbol = js.native + val split: js.Symbol = js.native /** The well-known symbol `@@toPrimitive`. * * @group wellknownsyms */ - val toPrimitive: Symbol = js.native + val toPrimitive: js.Symbol = js.native /** The well-known symbol `@@toStringTag`. * * @group wellknownsyms */ - val toStringTag: Symbol = js.native + val toStringTag: js.Symbol = js.native /** The well-known symbol `@@unscopables`. * * @group wellknownsyms */ - val unscopables: Symbol = js.native + val unscopables: js.Symbol = js.native } diff --git a/library/src/main/scala/scala/scalajs/js/Thenable.scala b/library/src/main/scala/scala/scalajs/js/Thenable.scala index 8736ecfd17..9f92775b16 100644 --- a/library/src/main/scala/scala/scalajs/js/Thenable.scala +++ b/library/src/main/scala/scala/scalajs/js/Thenable.scala @@ -12,7 +12,7 @@ package scala.scalajs.js import scala.language.implicitConversions import scala.scalajs.js -import js.annotation._ +import scala.scalajs.js.annotation._ import scala.concurrent.Future @@ -29,16 +29,16 @@ import scala.concurrent.Future */ trait Thenable[+A] extends js.Object { def `then`[B]( - onFulfilled: js.Function1[A, B | Thenable[B]], - onRejected: js.UndefOr[js.Function1[scala.Any, B | Thenable[B]]]): Thenable[B] + onFulfilled: js.Function1[A, B | js.Thenable[B]], + onRejected: js.UndefOr[js.Function1[scala.Any, B | js.Thenable[B]]]): js.Thenable[B] def `then`[B >: A]( onFulfilled: Unit, - onRejected: js.UndefOr[js.Function1[scala.Any, B | Thenable[B]]]): Thenable[B] + onRejected: js.UndefOr[js.Function1[scala.Any, B | js.Thenable[B]]]): js.Thenable[B] } object Thenable { - implicit class ThenableOps[+A](val p: Thenable[A]) extends AnyVal { + implicit class ThenableOps[+A](val p: js.Thenable[A]) extends AnyVal { /** Converts the [[Thenable]] into a Scala [[scala.concurrent.Future Future]]. * * Unlike when calling the `then` methods of [[Thenable]], the resulting @@ -50,30 +50,30 @@ object Thenable { p.`then`[Unit]( { (v: A) => p2.success(v) - (): Unit | Thenable[Unit] + (): Unit | js.Thenable[Unit] }, js.defined { (e: scala.Any) => p2.failure(e match { case th: Throwable => th - case _ => JavaScriptException(e) + case _ => js.JavaScriptException(e) }) - (): Unit | Thenable[Unit] + (): Unit | js.Thenable[Unit] }) p2.future } } - /** Implicits for [[Thenable]]s. + /** Implicits for [[js.Thenable]]s. * * Import `Implicits._` to enable [[scala.concurrent.Future Future]]'s - * operations directly on [[Thenable]]s, without needing to convert them + * operations directly on [[js.Thenable]]s, without needing to convert them * with [[ThenableOps.toFuture toFuture]]. * * Unlike the `then` methods in [[Thenable]], * [[scala.concurrent.Future Future]]'s operations are always well-typed. */ object Implicits { - implicit def thenable2future[A](p: Thenable[A]): Future[A] = + implicit def thenable2future[A](p: js.Thenable[A]): Future[A] = p.toFuture } } diff --git a/library/src/main/scala/scala/scalajs/js/ThisFunction.nodoc.scala b/library/src/main/scala/scala/scalajs/js/ThisFunction.nodoc.scala index 2dbc8d2941..2df29dedff 100644 --- a/library/src/main/scala/scala/scalajs/js/ThisFunction.nodoc.scala +++ b/library/src/main/scala/scala/scalajs/js/ThisFunction.nodoc.scala @@ -10,100 +10,102 @@ /* Definitions for js.ThisFunction3 to js.ThisFunction22 that do not show in doc */ package scala.scalajs.js +import scala.scalajs.js + // scalastyle:off line.size.limit -@native -trait ThisFunction3[-T0, -T1, -T2, -T3, +R] extends ThisFunction { +@js.native +trait ThisFunction3[-T0, -T1, -T2, -T3, +R] extends js.ThisFunction { def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3): R } -@native -trait ThisFunction4[-T0, -T1, -T2, -T3, -T4, +R] extends ThisFunction { +@js.native +trait ThisFunction4[-T0, -T1, -T2, -T3, -T4, +R] extends js.ThisFunction { def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4): R } -@native -trait ThisFunction5[-T0, -T1, -T2, -T3, -T4, -T5, +R] extends ThisFunction { +@js.native +trait ThisFunction5[-T0, -T1, -T2, -T3, -T4, -T5, +R] extends js.ThisFunction { def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5): R } -@native -trait ThisFunction6[-T0, -T1, -T2, -T3, -T4, -T5, -T6, +R] extends ThisFunction { +@js.native +trait ThisFunction6[-T0, -T1, -T2, -T3, -T4, -T5, -T6, +R] extends js.ThisFunction { def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6): R } -@native -trait ThisFunction7[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, +R] extends ThisFunction { +@js.native +trait ThisFunction7[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, +R] extends js.ThisFunction { def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7): R } -@native -trait ThisFunction8[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, +R] extends ThisFunction { +@js.native +trait ThisFunction8[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, +R] extends js.ThisFunction { def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8): R } -@native -trait ThisFunction9[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, +R] extends ThisFunction { +@js.native +trait ThisFunction9[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, +R] extends js.ThisFunction { def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9): R } -@native -trait ThisFunction10[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, +R] extends ThisFunction { +@js.native +trait ThisFunction10[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, +R] extends js.ThisFunction { def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10): R } -@native -trait ThisFunction11[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, +R] extends ThisFunction { +@js.native +trait ThisFunction11[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, +R] extends js.ThisFunction { def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11): R } -@native -trait ThisFunction12[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, +R] extends ThisFunction { +@js.native +trait ThisFunction12[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, +R] extends js.ThisFunction { def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12): R } -@native -trait ThisFunction13[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, +R] extends ThisFunction { +@js.native +trait ThisFunction13[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, +R] extends js.ThisFunction { def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13): R } -@native -trait ThisFunction14[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, +R] extends ThisFunction { +@js.native +trait ThisFunction14[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, +R] extends js.ThisFunction { def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14): R } -@native -trait ThisFunction15[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, +R] extends ThisFunction { +@js.native +trait ThisFunction15[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, +R] extends js.ThisFunction { def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15): R } -@native -trait ThisFunction16[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, +R] extends ThisFunction { +@js.native +trait ThisFunction16[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, +R] extends js.ThisFunction { def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16): R } -@native -trait ThisFunction17[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, +R] extends ThisFunction { +@js.native +trait ThisFunction17[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, +R] extends js.ThisFunction { def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17): R } -@native -trait ThisFunction18[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, +R] extends ThisFunction { +@js.native +trait ThisFunction18[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, +R] extends js.ThisFunction { def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18): R } -@native -trait ThisFunction19[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, +R] extends ThisFunction { +@js.native +trait ThisFunction19[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, +R] extends js.ThisFunction { def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19): R } -@native -trait ThisFunction20[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, +R] extends ThisFunction { +@js.native +trait ThisFunction20[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, +R] extends js.ThisFunction { def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19, arg20: T20): R } -@native -trait ThisFunction21[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, +R] extends ThisFunction { +@js.native +trait ThisFunction21[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, +R] extends js.ThisFunction { def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19, arg20: T20, arg21: T21): R } diff --git a/library/src/main/scala/scala/scalajs/js/ThisFunction.scala b/library/src/main/scala/scala/scalajs/js/ThisFunction.scala index 981d10922a..ecd3d63285 100644 --- a/library/src/main/scala/scala/scalajs/js/ThisFunction.scala +++ b/library/src/main/scala/scala/scalajs/js/ThisFunction.scala @@ -16,11 +16,13 @@ package scala.scalajs.js import scala.language.implicitConversions +import scala.scalajs.js + /** A JavaScript function where `this` is considered as a first parameter. * * @see [[http://www.scala-js.org/doc/calling-javascript.html Calling JavaScript from Scala.js]] */ -trait ThisFunction extends Function +trait ThisFunction extends js.Function object ThisFunction { // scalastyle:off line.size.limit @@ -28,65 +30,65 @@ object ThisFunction { /* identity() is important! It prevents the tail-rec treatment in the absence * of SAM treatment. See js.Any.fromFunctionN for more details. */ - implicit def fromFunction1[T1, R](f: scala.Function1[T1, R]): ThisFunction0[T1, R] = identity((x1: T1) => f(x1)) - implicit def fromFunction2[T1, T2, R](f: scala.Function2[T1, T2, R]): ThisFunction1[T1, T2, R] = identity((x1: T1, x2: T2) => f(x1, x2)) - implicit def fromFunction3[T1, T2, T3, R](f: scala.Function3[T1, T2, T3, R]): ThisFunction2[T1, T2, T3, R] = identity((x1: T1, x2: T2, x3: T3) => f(x1, x2, x3)) - implicit def fromFunction4[T1, T2, T3, T4, R](f: scala.Function4[T1, T2, T3, T4, R]): ThisFunction3[T1, T2, T3, T4, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4) => f(x1, x2, x3, x4)) - implicit def fromFunction5[T1, T2, T3, T4, T5, R](f: scala.Function5[T1, T2, T3, T4, T5, R]): ThisFunction4[T1, T2, T3, T4, T5, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5) => f(x1, x2, x3, x4, x5)) - implicit def fromFunction6[T1, T2, T3, T4, T5, T6, R](f: scala.Function6[T1, T2, T3, T4, T5, T6, R]): ThisFunction5[T1, T2, T3, T4, T5, T6, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6) => f(x1, x2, x3, x4, x5, x6)) - implicit def fromFunction7[T1, T2, T3, T4, T5, T6, T7, R](f: scala.Function7[T1, T2, T3, T4, T5, T6, T7, R]): ThisFunction6[T1, T2, T3, T4, T5, T6, T7, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7) => f(x1, x2, x3, x4, x5, x6, x7)) - implicit def fromFunction8[T1, T2, T3, T4, T5, T6, T7, T8, R](f: scala.Function8[T1, T2, T3, T4, T5, T6, T7, T8, R]): ThisFunction7[T1, T2, T3, T4, T5, T6, T7, T8, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8) => f(x1, x2, x3, x4, x5, x6, x7, x8)) - implicit def fromFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R](f: scala.Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R]): ThisFunction8[T1, T2, T3, T4, T5, T6, T7, T8, T9, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9)) - implicit def fromFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R](f: scala.Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R]): ThisFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)) - implicit def fromFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R](f: scala.Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R]): ThisFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)) - implicit def fromFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R](f: scala.Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R]): ThisFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12)) - implicit def fromFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R](f: scala.Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R]): ThisFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13)) - implicit def fromFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R](f: scala.Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R]): ThisFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14)) - implicit def fromFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R](f: scala.Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R]): ThisFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15)) - implicit def fromFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R](f: scala.Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R]): ThisFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16)) - implicit def fromFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R](f: scala.Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R]): ThisFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17)) - implicit def fromFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R](f: scala.Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R]): ThisFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18)) - implicit def fromFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R](f: scala.Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R]): ThisFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19)) - implicit def fromFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R](f: scala.Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R]): ThisFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20)) - implicit def fromFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R](f: scala.Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R]): ThisFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20, x21: T21) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21)) - implicit def fromFunction22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R](f: scala.Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R]): ThisFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20, x21: T21, x22: T22) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22)) + implicit def fromFunction1[T1, R](f: scala.Function1[T1, R]): js.ThisFunction0[T1, R] = identity((x1: T1) => f(x1)) + implicit def fromFunction2[T1, T2, R](f: scala.Function2[T1, T2, R]): js.ThisFunction1[T1, T2, R] = identity((x1: T1, x2: T2) => f(x1, x2)) + implicit def fromFunction3[T1, T2, T3, R](f: scala.Function3[T1, T2, T3, R]): js.ThisFunction2[T1, T2, T3, R] = identity((x1: T1, x2: T2, x3: T3) => f(x1, x2, x3)) + implicit def fromFunction4[T1, T2, T3, T4, R](f: scala.Function4[T1, T2, T3, T4, R]): js.ThisFunction3[T1, T2, T3, T4, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4) => f(x1, x2, x3, x4)) + implicit def fromFunction5[T1, T2, T3, T4, T5, R](f: scala.Function5[T1, T2, T3, T4, T5, R]): js.ThisFunction4[T1, T2, T3, T4, T5, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5) => f(x1, x2, x3, x4, x5)) + implicit def fromFunction6[T1, T2, T3, T4, T5, T6, R](f: scala.Function6[T1, T2, T3, T4, T5, T6, R]): js.ThisFunction5[T1, T2, T3, T4, T5, T6, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6) => f(x1, x2, x3, x4, x5, x6)) + implicit def fromFunction7[T1, T2, T3, T4, T5, T6, T7, R](f: scala.Function7[T1, T2, T3, T4, T5, T6, T7, R]): js.ThisFunction6[T1, T2, T3, T4, T5, T6, T7, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7) => f(x1, x2, x3, x4, x5, x6, x7)) + implicit def fromFunction8[T1, T2, T3, T4, T5, T6, T7, T8, R](f: scala.Function8[T1, T2, T3, T4, T5, T6, T7, T8, R]): js.ThisFunction7[T1, T2, T3, T4, T5, T6, T7, T8, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8) => f(x1, x2, x3, x4, x5, x6, x7, x8)) + implicit def fromFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R](f: scala.Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R]): js.ThisFunction8[T1, T2, T3, T4, T5, T6, T7, T8, T9, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9)) + implicit def fromFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R](f: scala.Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R]): js.ThisFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)) + implicit def fromFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R](f: scala.Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R]): js.ThisFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)) + implicit def fromFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R](f: scala.Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R]): js.ThisFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12)) + implicit def fromFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R](f: scala.Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R]): js.ThisFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13)) + implicit def fromFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R](f: scala.Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R]): js.ThisFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14)) + implicit def fromFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R](f: scala.Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R]): js.ThisFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15)) + implicit def fromFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R](f: scala.Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R]): js.ThisFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16)) + implicit def fromFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R](f: scala.Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R]): js.ThisFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17)) + implicit def fromFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R](f: scala.Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R]): js.ThisFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18)) + implicit def fromFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R](f: scala.Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R]): js.ThisFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19)) + implicit def fromFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R](f: scala.Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R]): js.ThisFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20)) + implicit def fromFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R](f: scala.Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R]): js.ThisFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20, x21: T21) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21)) + implicit def fromFunction22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R](f: scala.Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R]): js.ThisFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20, x21: T21, x22: T22) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22)) - implicit def toFunction1[T1, R](f: ThisFunction0[T1, R]): scala.Function1[T1, R] = (x1) => f(x1) - implicit def toFunction2[T1, T2, R](f: ThisFunction1[T1, T2, R]): scala.Function2[T1, T2, R] = (x1, x2) => f(x1, x2) - implicit def toFunction3[T1, T2, T3, R](f: ThisFunction2[T1, T2, T3, R]): scala.Function3[T1, T2, T3, R] = (x1, x2, x3) => f(x1, x2, x3) - implicit def toFunction4[T1, T2, T3, T4, R](f: ThisFunction3[T1, T2, T3, T4, R]): scala.Function4[T1, T2, T3, T4, R] = (x1, x2, x3, x4) => f(x1, x2, x3, x4) - implicit def toFunction5[T1, T2, T3, T4, T5, R](f: ThisFunction4[T1, T2, T3, T4, T5, R]): scala.Function5[T1, T2, T3, T4, T5, R] = (x1, x2, x3, x4, x5) => f(x1, x2, x3, x4, x5) - implicit def toFunction6[T1, T2, T3, T4, T5, T6, R](f: ThisFunction5[T1, T2, T3, T4, T5, T6, R]): scala.Function6[T1, T2, T3, T4, T5, T6, R] = (x1, x2, x3, x4, x5, x6) => f(x1, x2, x3, x4, x5, x6) - implicit def toFunction7[T1, T2, T3, T4, T5, T6, T7, R](f: ThisFunction6[T1, T2, T3, T4, T5, T6, T7, R]): scala.Function7[T1, T2, T3, T4, T5, T6, T7, R] = (x1, x2, x3, x4, x5, x6, x7) => f(x1, x2, x3, x4, x5, x6, x7) - implicit def toFunction8[T1, T2, T3, T4, T5, T6, T7, T8, R](f: ThisFunction7[T1, T2, T3, T4, T5, T6, T7, T8, R]): scala.Function8[T1, T2, T3, T4, T5, T6, T7, T8, R] = (x1, x2, x3, x4, x5, x6, x7, x8) => f(x1, x2, x3, x4, x5, x6, x7, x8) - implicit def toFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R](f: ThisFunction8[T1, T2, T3, T4, T5, T6, T7, T8, T9, R]): scala.Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9) - implicit def toFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R](f: ThisFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R]): scala.Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) - implicit def toFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R](f: ThisFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R]): scala.Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11) - implicit def toFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R](f: ThisFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R]): scala.Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12) - implicit def toFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R](f: ThisFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R]): scala.Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13) - implicit def toFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R](f: ThisFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R]): scala.Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14) - implicit def toFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R](f: ThisFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R]): scala.Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) - implicit def toFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R](f: ThisFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R]): scala.Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16) - implicit def toFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R](f: ThisFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R]): scala.Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17) - implicit def toFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R](f: ThisFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R]): scala.Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18) - implicit def toFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R](f: ThisFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R]): scala.Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19) - implicit def toFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R](f: ThisFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R]): scala.Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20) - implicit def toFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R](f: ThisFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R]): scala.Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21) - implicit def toFunction22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R](f: ThisFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R]): scala.Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22) + implicit def toFunction1[T1, R](f: js.ThisFunction0[T1, R]): scala.Function1[T1, R] = (x1) => f(x1) + implicit def toFunction2[T1, T2, R](f: js.ThisFunction1[T1, T2, R]): scala.Function2[T1, T2, R] = (x1, x2) => f(x1, x2) + implicit def toFunction3[T1, T2, T3, R](f: js.ThisFunction2[T1, T2, T3, R]): scala.Function3[T1, T2, T3, R] = (x1, x2, x3) => f(x1, x2, x3) + implicit def toFunction4[T1, T2, T3, T4, R](f: js.ThisFunction3[T1, T2, T3, T4, R]): scala.Function4[T1, T2, T3, T4, R] = (x1, x2, x3, x4) => f(x1, x2, x3, x4) + implicit def toFunction5[T1, T2, T3, T4, T5, R](f: js.ThisFunction4[T1, T2, T3, T4, T5, R]): scala.Function5[T1, T2, T3, T4, T5, R] = (x1, x2, x3, x4, x5) => f(x1, x2, x3, x4, x5) + implicit def toFunction6[T1, T2, T3, T4, T5, T6, R](f: js.ThisFunction5[T1, T2, T3, T4, T5, T6, R]): scala.Function6[T1, T2, T3, T4, T5, T6, R] = (x1, x2, x3, x4, x5, x6) => f(x1, x2, x3, x4, x5, x6) + implicit def toFunction7[T1, T2, T3, T4, T5, T6, T7, R](f: js.ThisFunction6[T1, T2, T3, T4, T5, T6, T7, R]): scala.Function7[T1, T2, T3, T4, T5, T6, T7, R] = (x1, x2, x3, x4, x5, x6, x7) => f(x1, x2, x3, x4, x5, x6, x7) + implicit def toFunction8[T1, T2, T3, T4, T5, T6, T7, T8, R](f: js.ThisFunction7[T1, T2, T3, T4, T5, T6, T7, T8, R]): scala.Function8[T1, T2, T3, T4, T5, T6, T7, T8, R] = (x1, x2, x3, x4, x5, x6, x7, x8) => f(x1, x2, x3, x4, x5, x6, x7, x8) + implicit def toFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R](f: js.ThisFunction8[T1, T2, T3, T4, T5, T6, T7, T8, T9, R]): scala.Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9) + implicit def toFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R](f: js.ThisFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R]): scala.Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) + implicit def toFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R](f: js.ThisFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R]): scala.Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11) + implicit def toFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R](f: js.ThisFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R]): scala.Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12) + implicit def toFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R](f: js.ThisFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R]): scala.Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13) + implicit def toFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R](f: js.ThisFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R]): scala.Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14) + implicit def toFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R](f: js.ThisFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R]): scala.Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) + implicit def toFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R](f: js.ThisFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R]): scala.Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16) + implicit def toFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R](f: js.ThisFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R]): scala.Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17) + implicit def toFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R](f: js.ThisFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R]): scala.Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18) + implicit def toFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R](f: js.ThisFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R]): scala.Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19) + implicit def toFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R](f: js.ThisFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R]): scala.Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20) + implicit def toFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R](f: js.ThisFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R]): scala.Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21) + implicit def toFunction22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R](f: js.ThisFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R]): scala.Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22) // scalastyle:on line.size.limit } -@native -trait ThisFunction0[-T0, +R] extends ThisFunction { +@js.native +trait ThisFunction0[-T0, +R] extends js.ThisFunction { def apply(thisArg: T0): R } -@native -trait ThisFunction1[-T0, -T1, +R] extends ThisFunction { +@js.native +trait ThisFunction1[-T0, -T1, +R] extends js.ThisFunction { def apply(thisArg: T0, arg1: T1): R } -@native -trait ThisFunction2[-T0, -T1, -T2, +R] extends ThisFunction { +@js.native +trait ThisFunction2[-T0, -T1, -T2, +R] extends js.ThisFunction { def apply(thisArg: T0, arg1: T1, arg2: T2): R } diff --git a/library/src/main/scala/scala/scalajs/js/Tuple.nodoc.scala b/library/src/main/scala/scala/scalajs/js/Tuple.nodoc.scala index 5089ff4ba4..6f81784a9c 100644 --- a/library/src/main/scala/scala/scalajs/js/Tuple.nodoc.scala +++ b/library/src/main/scala/scala/scalajs/js/Tuple.nodoc.scala @@ -9,17 +9,19 @@ /* Definitions for js.Tuple4 to js.Tuple22 that do not show in doc */ package scala.scalajs.js -import scala.scalajs.js.annotation.JSName import scala.language.implicitConversions +import scala.scalajs.js +import scala.scalajs.js.annotation._ + // scalastyle:off line.size.limit /** - * A tuple "view" of 4 elements of a JavaScript [[Array]]. + * A tuple "view" of 4 elements of a JavaScript [[js.Array]]. * - * @see [[Tuple2]] + * @see [[js.Tuple2]] */ -sealed trait Tuple4[+T1, +T2, +T3, +T4] extends Object { +sealed trait Tuple4[+T1, +T2, +T3, +T4] extends js.Object { @JSName("0") val _1: T1 @JSName("1") val _2: T2 @JSName("2") val _3: T3 @@ -27,25 +29,25 @@ sealed trait Tuple4[+T1, +T2, +T3, +T4] extends Object { } object Tuple4 { - @inline def apply[T1, T2, T3, T4](_1: T1, _2: T2, _3: T3, _4: T4): Tuple4[T1, T2, T3, T4] = - Array(_1, _2, _3, _4).asInstanceOf[Tuple4[T1, T2, T3, T4]] + @inline def apply[T1, T2, T3, T4](_1: T1, _2: T2, _3: T3, _4: T4): js.Tuple4[T1, T2, T3, T4] = + js.Array(_1, _2, _3, _4).asInstanceOf[js.Tuple4[T1, T2, T3, T4]] - @inline def unapply[T1, T2, T3, T4](t: Tuple4[T1, T2, T3, T4]): Option[(T1, T2, T3, T4)] = + @inline def unapply[T1, T2, T3, T4](t: js.Tuple4[T1, T2, T3, T4]): Option[(T1, T2, T3, T4)] = Some(t) - @inline implicit def fromScalaTuple4[T1, T2, T3, T4](t: (T1, T2, T3, T4)): Tuple4[T1, T2, T3, T4] = + @inline implicit def fromScalaTuple4[T1, T2, T3, T4](t: (T1, T2, T3, T4)): js.Tuple4[T1, T2, T3, T4] = apply(t._1, t._2, t._3, t._4) - @inline implicit def toScalaTuple4[T1, T2, T3, T4](t: Tuple4[T1, T2, T3, T4]): (T1, T2, T3, T4) = + @inline implicit def toScalaTuple4[T1, T2, T3, T4](t: js.Tuple4[T1, T2, T3, T4]): (T1, T2, T3, T4) = (t._1, t._2, t._3, t._4) } /** - * A tuple "view" of 5 elements of a JavaScript [[Array]]. + * A tuple "view" of 5 elements of a JavaScript [[js.Array]]. * - * @see [[Tuple2]] + * @see [[js.Tuple2]] */ -sealed trait Tuple5[+T1, +T2, +T3, +T4, +T5] extends Object { +sealed trait Tuple5[+T1, +T2, +T3, +T4, +T5] extends js.Object { @JSName("0") val _1: T1 @JSName("1") val _2: T2 @JSName("2") val _3: T3 @@ -54,25 +56,25 @@ sealed trait Tuple5[+T1, +T2, +T3, +T4, +T5] extends Object { } object Tuple5 { - @inline def apply[T1, T2, T3, T4, T5](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5): Tuple5[T1, T2, T3, T4, T5] = - Array(_1, _2, _3, _4, _5).asInstanceOf[Tuple5[T1, T2, T3, T4, T5]] + @inline def apply[T1, T2, T3, T4, T5](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5): js.Tuple5[T1, T2, T3, T4, T5] = + js.Array(_1, _2, _3, _4, _5).asInstanceOf[js.Tuple5[T1, T2, T3, T4, T5]] - @inline def unapply[T1, T2, T3, T4, T5](t: Tuple5[T1, T2, T3, T4, T5]): Option[(T1, T2, T3, T4, T5)] = + @inline def unapply[T1, T2, T3, T4, T5](t: js.Tuple5[T1, T2, T3, T4, T5]): Option[(T1, T2, T3, T4, T5)] = Some(t) - @inline implicit def fromScalaTuple5[T1, T2, T3, T4, T5](t: (T1, T2, T3, T4, T5)): Tuple5[T1, T2, T3, T4, T5] = + @inline implicit def fromScalaTuple5[T1, T2, T3, T4, T5](t: (T1, T2, T3, T4, T5)): js.Tuple5[T1, T2, T3, T4, T5] = apply(t._1, t._2, t._3, t._4, t._5) - @inline implicit def toScalaTuple5[T1, T2, T3, T4, T5](t: Tuple5[T1, T2, T3, T4, T5]): (T1, T2, T3, T4, T5) = + @inline implicit def toScalaTuple5[T1, T2, T3, T4, T5](t: js.Tuple5[T1, T2, T3, T4, T5]): (T1, T2, T3, T4, T5) = (t._1, t._2, t._3, t._4, t._5) } /** - * A tuple "view" of 6 elements of a JavaScript [[Array]]. + * A tuple "view" of 6 elements of a JavaScript [[js.Array]]. * - * @see [[Tuple2]] + * @see [[js.Tuple2]] */ -sealed trait Tuple6[+T1, +T2, +T3, +T4, +T5, +T6] extends Object { +sealed trait Tuple6[+T1, +T2, +T3, +T4, +T5, +T6] extends js.Object { @JSName("0") val _1: T1 @JSName("1") val _2: T2 @JSName("2") val _3: T3 @@ -82,25 +84,25 @@ sealed trait Tuple6[+T1, +T2, +T3, +T4, +T5, +T6] extends Object { } object Tuple6 { - @inline def apply[T1, T2, T3, T4, T5, T6](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6): Tuple6[T1, T2, T3, T4, T5, T6] = - Array(_1, _2, _3, _4, _5, _6).asInstanceOf[Tuple6[T1, T2, T3, T4, T5, T6]] + @inline def apply[T1, T2, T3, T4, T5, T6](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6): js.Tuple6[T1, T2, T3, T4, T5, T6] = + js.Array(_1, _2, _3, _4, _5, _6).asInstanceOf[js.Tuple6[T1, T2, T3, T4, T5, T6]] - @inline def unapply[T1, T2, T3, T4, T5, T6](t: Tuple6[T1, T2, T3, T4, T5, T6]): Option[(T1, T2, T3, T4, T5, T6)] = + @inline def unapply[T1, T2, T3, T4, T5, T6](t: js.Tuple6[T1, T2, T3, T4, T5, T6]): Option[(T1, T2, T3, T4, T5, T6)] = Some(t) - @inline implicit def fromScalaTuple6[T1, T2, T3, T4, T5, T6](t: (T1, T2, T3, T4, T5, T6)): Tuple6[T1, T2, T3, T4, T5, T6] = + @inline implicit def fromScalaTuple6[T1, T2, T3, T4, T5, T6](t: (T1, T2, T3, T4, T5, T6)): js.Tuple6[T1, T2, T3, T4, T5, T6] = apply(t._1, t._2, t._3, t._4, t._5, t._6) - @inline implicit def toScalaTuple6[T1, T2, T3, T4, T5, T6](t: Tuple6[T1, T2, T3, T4, T5, T6]): (T1, T2, T3, T4, T5, T6) = + @inline implicit def toScalaTuple6[T1, T2, T3, T4, T5, T6](t: js.Tuple6[T1, T2, T3, T4, T5, T6]): (T1, T2, T3, T4, T5, T6) = (t._1, t._2, t._3, t._4, t._5, t._6) } /** - * A tuple "view" of 7 elements of a JavaScript [[Array]]. + * A tuple "view" of 7 elements of a JavaScript [[js.Array]]. * - * @see [[Tuple2]] + * @see [[js.Tuple2]] */ -sealed trait Tuple7[+T1, +T2, +T3, +T4, +T5, +T6, +T7] extends Object { +sealed trait Tuple7[+T1, +T2, +T3, +T4, +T5, +T6, +T7] extends js.Object { @JSName("0") val _1: T1 @JSName("1") val _2: T2 @JSName("2") val _3: T3 @@ -111,25 +113,25 @@ sealed trait Tuple7[+T1, +T2, +T3, +T4, +T5, +T6, +T7] extends Object { } object Tuple7 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7): Tuple7[T1, T2, T3, T4, T5, T6, T7] = - Array(_1, _2, _3, _4, _5, _6, _7).asInstanceOf[Tuple7[T1, T2, T3, T4, T5, T6, T7]] + @inline def apply[T1, T2, T3, T4, T5, T6, T7](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7): js.Tuple7[T1, T2, T3, T4, T5, T6, T7] = + js.Array(_1, _2, _3, _4, _5, _6, _7).asInstanceOf[js.Tuple7[T1, T2, T3, T4, T5, T6, T7]] - @inline def unapply[T1, T2, T3, T4, T5, T6, T7](t: Tuple7[T1, T2, T3, T4, T5, T6, T7]): Option[(T1, T2, T3, T4, T5, T6, T7)] = + @inline def unapply[T1, T2, T3, T4, T5, T6, T7](t: js.Tuple7[T1, T2, T3, T4, T5, T6, T7]): Option[(T1, T2, T3, T4, T5, T6, T7)] = Some(t) - @inline implicit def fromScalaTuple7[T1, T2, T3, T4, T5, T6, T7](t: (T1, T2, T3, T4, T5, T6, T7)): Tuple7[T1, T2, T3, T4, T5, T6, T7] = + @inline implicit def fromScalaTuple7[T1, T2, T3, T4, T5, T6, T7](t: (T1, T2, T3, T4, T5, T6, T7)): js.Tuple7[T1, T2, T3, T4, T5, T6, T7] = apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7) - @inline implicit def toScalaTuple7[T1, T2, T3, T4, T5, T6, T7](t: Tuple7[T1, T2, T3, T4, T5, T6, T7]): (T1, T2, T3, T4, T5, T6, T7) = + @inline implicit def toScalaTuple7[T1, T2, T3, T4, T5, T6, T7](t: js.Tuple7[T1, T2, T3, T4, T5, T6, T7]): (T1, T2, T3, T4, T5, T6, T7) = (t._1, t._2, t._3, t._4, t._5, t._6, t._7) } /** - * A tuple "view" of 8 elements of a JavaScript [[Array]]. + * A tuple "view" of 8 elements of a JavaScript [[js.Array]]. * - * @see [[Tuple2]] + * @see [[js.Tuple2]] */ -sealed trait Tuple8[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8] extends Object { +sealed trait Tuple8[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8] extends js.Object { @JSName("0") val _1: T1 @JSName("1") val _2: T2 @JSName("2") val _3: T3 @@ -141,25 +143,25 @@ sealed trait Tuple8[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8] extends Object { } object Tuple8 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8): Tuple8[T1, T2, T3, T4, T5, T6, T7, T8] = - Array(_1, _2, _3, _4, _5, _6, _7, _8).asInstanceOf[Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]] + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8): js.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8] = + js.Array(_1, _2, _3, _4, _5, _6, _7, _8).asInstanceOf[js.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]] - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8](t: Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]): Option[(T1, T2, T3, T4, T5, T6, T7, T8)] = + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8](t: js.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]): Option[(T1, T2, T3, T4, T5, T6, T7, T8)] = Some(t) - @inline implicit def fromScalaTuple8[T1, T2, T3, T4, T5, T6, T7, T8](t: (T1, T2, T3, T4, T5, T6, T7, T8)): Tuple8[T1, T2, T3, T4, T5, T6, T7, T8] = + @inline implicit def fromScalaTuple8[T1, T2, T3, T4, T5, T6, T7, T8](t: (T1, T2, T3, T4, T5, T6, T7, T8)): js.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8] = apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8) - @inline implicit def toScalaTuple8[T1, T2, T3, T4, T5, T6, T7, T8](t: Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]): (T1, T2, T3, T4, T5, T6, T7, T8) = + @inline implicit def toScalaTuple8[T1, T2, T3, T4, T5, T6, T7, T8](t: js.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]): (T1, T2, T3, T4, T5, T6, T7, T8) = (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8) } /** - * A tuple "view" of 9 elements of a JavaScript [[Array]]. + * A tuple "view" of 9 elements of a JavaScript [[js.Array]]. * - * @see [[Tuple2]] + * @see [[js.Tuple2]] */ -sealed trait Tuple9[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9] extends Object { +sealed trait Tuple9[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9] extends js.Object { @JSName("0") val _1: T1 @JSName("1") val _2: T2 @JSName("2") val _3: T3 @@ -172,25 +174,25 @@ sealed trait Tuple9[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9] extends Object } object Tuple9 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9): Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9).asInstanceOf[Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]] + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9): js.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9] = + js.Array(_1, _2, _3, _4, _5, _6, _7, _8, _9).asInstanceOf[js.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]] - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9](t: Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9)] = + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9](t: js.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9)] = Some(t) - @inline implicit def fromScalaTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9)): Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9] = + @inline implicit def fromScalaTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9)): js.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9] = apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9) - @inline implicit def toScalaTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9](t: Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]): (T1, T2, T3, T4, T5, T6, T7, T8, T9) = + @inline implicit def toScalaTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9](t: js.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]): (T1, T2, T3, T4, T5, T6, T7, T8, T9) = (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9) } /** - * A tuple "view" of 10 elements of a JavaScript [[Array]]. + * A tuple "view" of 10 elements of a JavaScript [[js.Array]]. * - * @see [[Tuple2]] + * @see [[js.Tuple2]] */ -sealed trait Tuple10[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10] extends Object { +sealed trait Tuple10[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10] extends js.Object { @JSName("0") val _1: T1 @JSName("1") val _2: T2 @JSName("2") val _3: T3 @@ -204,25 +206,25 @@ sealed trait Tuple10[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10] extends } object Tuple10 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10): Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10).asInstanceOf[Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]] + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10): js.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10] = + js.Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10).asInstanceOf[js.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]] - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10](t: Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)] = + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10](t: js.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)] = Some(t) - @inline implicit def fromScalaTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)): Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10] = + @inline implicit def fromScalaTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)): js.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10] = apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10) - @inline implicit def toScalaTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10](t: Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) = + @inline implicit def toScalaTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10](t: js.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) = (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10) } /** - * A tuple "view" of 11 elements of a JavaScript [[Array]]. + * A tuple "view" of 11 elements of a JavaScript [[js.Array]]. * - * @see [[Tuple2]] + * @see [[js.Tuple2]] */ -sealed trait Tuple11[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11] extends Object { +sealed trait Tuple11[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11] extends js.Object { @JSName("0") val _1: T1 @JSName("1") val _2: T2 @JSName("2") val _3: T3 @@ -237,25 +239,25 @@ sealed trait Tuple11[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11] ex } object Tuple11 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11): Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11).asInstanceOf[Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]] + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11): js.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11] = + js.Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11).asInstanceOf[js.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]] - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11](t: Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)] = + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11](t: js.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)] = Some(t) - @inline implicit def fromScalaTuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)): Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11] = + @inline implicit def fromScalaTuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)): js.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11] = apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11) - @inline implicit def toScalaTuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11](t: Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) = + @inline implicit def toScalaTuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11](t: js.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) = (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11) } /** - * A tuple "view" of 12 elements of a JavaScript [[Array]]. + * A tuple "view" of 12 elements of a JavaScript [[js.Array]]. * - * @see [[Tuple2]] + * @see [[js.Tuple2]] */ -sealed trait Tuple12[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12] extends Object { +sealed trait Tuple12[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12] extends js.Object { @JSName("0") val _1: T1 @JSName("1") val _2: T2 @JSName("2") val _3: T3 @@ -271,25 +273,25 @@ sealed trait Tuple12[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T } object Tuple12 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12): Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12).asInstanceOf[Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]] + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12): js.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12] = + js.Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12).asInstanceOf[js.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]] - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12](t: Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)] = + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12](t: js.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)] = Some(t) - @inline implicit def fromScalaTuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)): Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12] = + @inline implicit def fromScalaTuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)): js.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12] = apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12) - @inline implicit def toScalaTuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12](t: Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) = + @inline implicit def toScalaTuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12](t: js.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) = (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12) } /** - * A tuple "view" of 13 elements of a JavaScript [[Array]]. + * A tuple "view" of 13 elements of a JavaScript [[js.Array]]. * - * @see [[Tuple2]] + * @see [[js.Tuple2]] */ -sealed trait Tuple13[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13] extends Object { +sealed trait Tuple13[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13] extends js.Object { @JSName("0") val _1: T1 @JSName("1") val _2: T2 @JSName("2") val _3: T3 @@ -306,25 +308,25 @@ sealed trait Tuple13[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T } object Tuple13 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13): Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13).asInstanceOf[Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]] + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13): js.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13] = + js.Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13).asInstanceOf[js.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]] - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13](t: Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)] = + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13](t: js.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)] = Some(t) - @inline implicit def fromScalaTuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)): Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13] = + @inline implicit def fromScalaTuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)): js.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13] = apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13) - @inline implicit def toScalaTuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13](t: Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) = + @inline implicit def toScalaTuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13](t: js.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) = (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13) } /** - * A tuple "view" of 14 elements of a JavaScript [[Array]]. + * A tuple "view" of 14 elements of a JavaScript [[js.Array]]. * - * @see [[Tuple2]] + * @see [[js.Tuple2]] */ -sealed trait Tuple14[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14] extends Object { +sealed trait Tuple14[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14] extends js.Object { @JSName("0") val _1: T1 @JSName("1") val _2: T2 @JSName("2") val _3: T3 @@ -342,25 +344,25 @@ sealed trait Tuple14[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T } object Tuple14 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14): Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14).asInstanceOf[Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]] + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14): js.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14] = + js.Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14).asInstanceOf[js.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]] - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14](t: Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)] = + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14](t: js.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)] = Some(t) - @inline implicit def fromScalaTuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)): Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14] = + @inline implicit def fromScalaTuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)): js.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14] = apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14) - @inline implicit def toScalaTuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14](t: Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) = + @inline implicit def toScalaTuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14](t: js.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) = (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14) } /** - * A tuple "view" of 15 elements of a JavaScript [[Array]]. + * A tuple "view" of 15 elements of a JavaScript [[js.Array]]. * - * @see [[Tuple2]] + * @see [[js.Tuple2]] */ -sealed trait Tuple15[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15] extends Object { +sealed trait Tuple15[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15] extends js.Object { @JSName("0") val _1: T1 @JSName("1") val _2: T2 @JSName("2") val _3: T3 @@ -379,25 +381,25 @@ sealed trait Tuple15[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T } object Tuple15 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15): Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15).asInstanceOf[Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]] + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15): js.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15] = + js.Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15).asInstanceOf[js.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]] - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15](t: Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)] = + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15](t: js.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)] = Some(t) - @inline implicit def fromScalaTuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)): Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15] = + @inline implicit def fromScalaTuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)): js.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15] = apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15) - @inline implicit def toScalaTuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15](t: Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) = + @inline implicit def toScalaTuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15](t: js.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) = (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15) } /** - * A tuple "view" of 16 elements of a JavaScript [[Array]]. + * A tuple "view" of 16 elements of a JavaScript [[js.Array]]. * - * @see [[Tuple16]] + * @see [[js.Tuple16]] */ -sealed trait Tuple16[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16] extends Object { +sealed trait Tuple16[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16] extends js.Object { @JSName("0") val _1: T1 @JSName("1") val _2: T2 @JSName("2") val _3: T3 @@ -417,25 +419,25 @@ sealed trait Tuple16[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T } object Tuple16 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16): Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16).asInstanceOf[Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]] + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16): js.Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16] = + js.Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16).asInstanceOf[js.Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]] - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16](t: Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16)] = + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16](t: js.Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16)] = Some(t) - @inline implicit def fromScalaTuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16)): Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16] = + @inline implicit def fromScalaTuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16)): js.Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16] = apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16) - @inline implicit def toScalaTuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16](t: Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) = + @inline implicit def toScalaTuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16](t: js.Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) = (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16) } /** - * A tuple "view" of 17 elements of a JavaScript [[Array]]. + * A tuple "view" of 17 elements of a JavaScript [[js.Array]]. * - * @see [[Tuple2]] + * @see [[js.Tuple2]] */ -sealed trait Tuple17[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17] extends Object { +sealed trait Tuple17[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17] extends js.Object { @JSName("0") val _1: T1 @JSName("1") val _2: T2 @JSName("2") val _3: T3 @@ -456,25 +458,25 @@ sealed trait Tuple17[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T } object Tuple17 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17): Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17).asInstanceOf[Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]] + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17): js.Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17] = + js.Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17).asInstanceOf[js.Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]] - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17](t: Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17)] = + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17](t: js.Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17)] = Some(t) - @inline implicit def fromScalaTuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17)): Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17] = + @inline implicit def fromScalaTuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17)): js.Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17] = apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17) - @inline implicit def toScalaTuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17](t: Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) = + @inline implicit def toScalaTuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17](t: js.Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) = (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17) } /** - * A tuple "view" of 18 elements of a JavaScript [[Array]]. + * A tuple "view" of 18 elements of a JavaScript [[js.Array]]. * - * @see [[Tuple2]] + * @see [[js.Tuple2]] */ -sealed trait Tuple18[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18] extends Object { +sealed trait Tuple18[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18] extends js.Object { @JSName("0") val _1: T1 @JSName("1") val _2: T2 @JSName("2") val _3: T3 @@ -496,25 +498,25 @@ sealed trait Tuple18[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T } object Tuple18 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18): Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18).asInstanceOf[Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]] + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18): js.Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18] = + js.Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18).asInstanceOf[js.Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]] - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18](t: Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18)] = + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18](t: js.Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18)] = Some(t) - @inline implicit def fromScalaTuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18)): Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18] = + @inline implicit def fromScalaTuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18)): js.Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18] = apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18) - @inline implicit def toScalaTuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18](t: Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) = + @inline implicit def toScalaTuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18](t: js.Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) = (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18) } /** - * A tuple "view" of 19 elements of a JavaScript [[Array]]. + * A tuple "view" of 19 elements of a JavaScript [[js.Array]]. * - * @see [[Tuple2]] + * @see [[js.Tuple2]] */ -sealed trait Tuple19[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19] extends Object { +sealed trait Tuple19[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19] extends js.Object { @JSName("0") val _1: T1 @JSName("1") val _2: T2 @JSName("2") val _3: T3 @@ -537,25 +539,25 @@ sealed trait Tuple19[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T } object Tuple19 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18, _19: T19): Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19).asInstanceOf[Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]] + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18, _19: T19): js.Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19] = + js.Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19).asInstanceOf[js.Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]] - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19](t: Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19)] = + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19](t: js.Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19)] = Some(t) - @inline implicit def fromScalaTuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19)): Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19] = + @inline implicit def fromScalaTuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19)): js.Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19] = apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18, t._19) - @inline implicit def toScalaTuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19](t: Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) = + @inline implicit def toScalaTuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19](t: js.Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) = (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18, t._19) } /** - * A tuple "view" of 20 elements of a JavaScript [[Array]]. + * A tuple "view" of 20 elements of a JavaScript [[js.Array]]. * - * @see [[Tuple2]] + * @see [[js.Tuple2]] */ -sealed trait Tuple20[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20] extends Object { +sealed trait Tuple20[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20] extends js.Object { @JSName("0") val _1: T1 @JSName("1") val _2: T2 @JSName("2") val _3: T3 @@ -579,25 +581,25 @@ sealed trait Tuple20[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T } object Tuple20 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18, _19: T19, _20: T20): Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20).asInstanceOf[Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]] + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18, _19: T19, _20: T20): js.Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20] = + js.Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20).asInstanceOf[js.Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]] - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20](t: Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20)] = + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20](t: js.Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20)] = Some(t) - @inline implicit def fromScalaTuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20)): Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20] = + @inline implicit def fromScalaTuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20)): js.Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20] = apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18, t._19, t._20) - @inline implicit def toScalaTuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20](t: Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) = + @inline implicit def toScalaTuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20](t: js.Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) = (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18, t._19, t._20) } /** - * A tuple "view" of 21 elements of a JavaScript [[Array]]. + * A tuple "view" of 21 elements of a JavaScript [[js.Array]]. * - * @see [[Tuple2]] + * @see [[js.Tuple2]] */ -sealed trait Tuple21[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20, +T21] extends Object { +sealed trait Tuple21[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20, +T21] extends js.Object { @JSName("0") val _1: T1 @JSName("1") val _2: T2 @JSName("2") val _3: T3 @@ -622,25 +624,25 @@ sealed trait Tuple21[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T } object Tuple21 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18, _19: T19, _20: T20, _21: T21): Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21).asInstanceOf[Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]] + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18, _19: T19, _20: T20, _21: T21): js.Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21] = + js.Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21).asInstanceOf[js.Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]] - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21](t: Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21)] = + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21](t: js.Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21)] = Some(t) - @inline implicit def fromScalaTuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21)): Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21] = + @inline implicit def fromScalaTuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21)): js.Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21] = apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18, t._19, t._20, t._21) - @inline implicit def toScalaTuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21](t: Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) = + @inline implicit def toScalaTuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21](t: js.Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) = (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18, t._19, t._20, t._21) } /** - * A tuple "view" of 22 elements of a JavaScript [[Array]]. + * A tuple "view" of 22 elements of a JavaScript [[js.Array]]. * - * @see [[Tuple2]] + * @see [[js.Tuple2]] */ -sealed trait Tuple22[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20, +T21, +T22] extends Object { +sealed trait Tuple22[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20, +T21, +T22] extends js.Object { @JSName("0") val _1: T1 @JSName("1") val _2: T2 @JSName("2") val _3: T3 @@ -666,16 +668,16 @@ sealed trait Tuple22[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T } object Tuple22 { - @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18, _19: T19, _20: T20, _21: T21, _22: T22): Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22] = - Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22).asInstanceOf[Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]] + @inline def apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18, _19: T19, _20: T20, _21: T21, _22: T22): js.Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22] = + js.Array(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22).asInstanceOf[js.Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]] - @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22](t: Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22)] = + @inline def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22](t: js.Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]): Option[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22)] = Some(t) - @inline implicit def fromScalaTuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22)): Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22] = + @inline implicit def fromScalaTuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22](t: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22)): js.Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22] = apply(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18, t._19, t._20, t._21, t._22) - @inline implicit def toScalaTuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22](t: Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) = + @inline implicit def toScalaTuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22](t: js.Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) = (t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10, t._11, t._12, t._13, t._14, t._15, t._16, t._17, t._18, t._19, t._20, t._21, t._22) } diff --git a/library/src/main/scala/scala/scalajs/js/Tuple.scala b/library/src/main/scala/scala/scalajs/js/Tuple.scala index b7d4cf08c1..8e0995fc60 100644 --- a/library/src/main/scala/scala/scalajs/js/Tuple.scala +++ b/library/src/main/scala/scala/scalajs/js/Tuple.scala @@ -14,23 +14,17 @@ */ package scala.scalajs.js -import scala.scalajs.js.annotation.JSName import scala.language.implicitConversions +import scala.scalajs.js +import scala.scalajs.js.annotation._ + /** - * A tuple "view" of 2 elements of a JavaScript [[Array]]. - * Combines - * {{{ - * 0: T0; - * 1: T1; - * }}} - * to - * {{{ - * js.Tuple2[T0,T1] - * }}} + * A tuple "view" of 2 elements of a JavaScript [[js.Array]]. + * + * Supports implicit conversions to and from [[scala.Tuple2]]. * - * Supports implicit conversion to [[scala.Tuple2]]. - * To use it, cast your array into a [[Tuple2]] using + * To use it, cast your array into a [[js.Tuple2]] using * {{{ * val array = js.Array[Any](42, "foobar") * val tuple2 = array.asInstanceOf[js.Tuple2[Int, String]] @@ -40,46 +34,46 @@ import scala.language.implicitConversions * val obj: js.Tuple2[Int, String] = (42, "foobar") * }}} */ -sealed trait Tuple2[+T1, +T2] extends Object { +sealed trait Tuple2[+T1, +T2] extends js.Object { @JSName("0") val _1: T1 @JSName("1") val _2: T2 } object Tuple2 { - @inline def apply[T1, T2](_1: T1, _2: T2): Tuple2[T1, T2] = - Array(_1, _2).asInstanceOf[Tuple2[T1, T2]] + @inline def apply[T1, T2](_1: T1, _2: T2): js.Tuple2[T1, T2] = + js.Array(_1, _2).asInstanceOf[js.Tuple2[T1, T2]] - @inline def unapply[T1, T2](t: Tuple2[T1, T2]): Option[(T1, T2)] = + @inline def unapply[T1, T2](t: js.Tuple2[T1, T2]): Option[(T1, T2)] = Some(t) - @inline implicit def fromScalaTuple2[T1, T2](t: (T1, T2)): Tuple2[T1, T2] = + @inline implicit def fromScalaTuple2[T1, T2](t: (T1, T2)): js.Tuple2[T1, T2] = apply(t._1, t._2) - @inline implicit def toScalaTuple2[T1, T2](t: Tuple2[T1, T2]): (T1, T2) = + @inline implicit def toScalaTuple2[T1, T2](t: js.Tuple2[T1, T2]): (T1, T2) = (t._1, t._2) } /** - * A tuple "view" of 3 elements of a JavaScript [[Array]]. + * A tuple "view" of 3 elements of a JavaScript [[js.Array]]. * - * @see [[Tuple2]] + * @see [[js.Tuple2]] */ -sealed trait Tuple3[+T1, +T2, +T3] extends Object { +sealed trait Tuple3[+T1, +T2, +T3] extends js.Object { @JSName("0") val _1: T1 @JSName("1") val _2: T2 @JSName("2") val _3: T3 } object Tuple3 { - @inline def apply[T1, T2, T3](_1: T1, _2: T2, _3: T3): Tuple3[T1, T2, T3] = - Array(_1, _2, _3).asInstanceOf[Tuple3[T1, T2, T3]] + @inline def apply[T1, T2, T3](_1: T1, _2: T2, _3: T3): js.Tuple3[T1, T2, T3] = + js.Array(_1, _2, _3).asInstanceOf[js.Tuple3[T1, T2, T3]] - @inline def unapply[T1, T2, T3](t: Tuple3[T1, T2, T3]): Option[(T1, T2, T3)] = + @inline def unapply[T1, T2, T3](t: js.Tuple3[T1, T2, T3]): Option[(T1, T2, T3)] = Some(t) - @inline implicit def fromScalaTuple3[T1, T2, T3](t: (T1, T2, T3)): Tuple3[T1, T2, T3] = + @inline implicit def fromScalaTuple3[T1, T2, T3](t: (T1, T2, T3)): js.Tuple3[T1, T2, T3] = apply(t._1, t._2, t._3) - @inline implicit def toScalaTuple3[T1, T2, T3](t: Tuple3[T1, T2, T3]): (T1, T2, T3) = + @inline implicit def toScalaTuple3[T1, T2, T3](t: js.Tuple3[T1, T2, T3]): (T1, T2, T3) = (t._1, t._2, t._3) } diff --git a/library/src/main/scala/scala/scalajs/js/URIUtils.scala b/library/src/main/scala/scala/scalajs/js/URIUtils.scala index ec102a3162..b47704e8e8 100644 --- a/library/src/main/scala/scala/scalajs/js/URIUtils.scala +++ b/library/src/main/scala/scala/scalajs/js/URIUtils.scala @@ -10,31 +10,32 @@ package scala.scalajs.js -import scala.scalajs.js.annotation.JSGlobalScope +import scala.scalajs.js +import scala.scalajs.js.annotation._ /** Methods related to URIs, provided by ECMAScript 5.1. */ -@native +@js.native @JSGlobalScope -object URIUtils extends Object { +object URIUtils extends js.Object { /** Decodes a Uniform Resource Identifier (URI). * @see [[encodeURI]] */ - def decodeURI(encodedURI: String): String = native + def decodeURI(encodedURI: String): String = js.native /** Decodes a Uniform Resource Identifier (URI) component. * @see [[encodeURIComponent]] */ - def decodeURIComponent(encodedURIComponent: String): String = native + def decodeURIComponent(encodedURIComponent: String): String = js.native /** Encodes a Uniform Resource Identifier (URI). * @see [[decodeURI]] */ - def encodeURI(uri: String): String = native + def encodeURI(uri: String): String = js.native /** Encodes a Uniform Resource Identifier (URI) component. * @see [[decodeURIComponent]] */ - def encodeURIComponent(uriComponent: String): String = native + def encodeURIComponent(uriComponent: String): String = js.native } diff --git a/library/src/main/scala/scala/scalajs/js/UndefOr.scala b/library/src/main/scala/scala/scalajs/js/UndefOr.scala index 268eb55447..4a3add8c64 100644 --- a/library/src/main/scala/scala/scalajs/js/UndefOr.scala +++ b/library/src/main/scala/scala/scalajs/js/UndefOr.scala @@ -10,6 +10,8 @@ package scala.scalajs.js import scala.language.implicitConversions + +import scala.scalajs.js import scala.scalajs.js.|.Evidence /** Value of type A or the JS undefined value. @@ -23,37 +25,39 @@ import scala.scalajs.js.|.Evidence */ sealed trait UndefOr[+A] -sealed abstract class UndefOrLowPrioImplicits { this: UndefOr.type => +sealed abstract class UndefOrLowPrioImplicits { this: js.UndefOr.type => /** Upcast `A` to `UndefOr[B1 | B2]`. * * This needs evidence that `A <: B1 | B2`. */ implicit def any2undefOrUnion[A, B1, B2](a: A)( - implicit ev: Evidence[A, B1 | B2]): UndefOr[B1 | B2] = { - a.asInstanceOf[UndefOr[B1 | B2]] + implicit ev: Evidence[A, B1 | B2]): js.UndefOr[B1 | B2] = { + a.asInstanceOf[js.UndefOr[B1 | B2]] } } -object UndefOr extends UndefOrLowPrioImplicits { - implicit def any2undefOrA[A](value: A): UndefOr[A] = - value.asInstanceOf[UndefOr[A]] +object UndefOr extends js.UndefOrLowPrioImplicits { + implicit def any2undefOrA[A](value: A): js.UndefOr[A] = + value.asInstanceOf[js.UndefOr[A]] - implicit def undefOr2ops[A](value: UndefOr[A]): UndefOrOps[A] = - new UndefOrOps(value) + implicit def undefOr2ops[A](value: js.UndefOr[A]): js.UndefOrOps[A] = + new js.UndefOrOps(value) - implicit def undefOr2jsAny[A](value: UndefOr[A])(implicit ev: A => Any): Any = - value.map(ev).asInstanceOf[Any] + implicit def undefOr2jsAny[A](value: js.UndefOr[A])( + implicit ev: A => js.Any): js.Any = { + value.map(ev).asInstanceOf[js.Any] + } } -/** @define option [[UndefOr]] - * @define none [[undefined]] +/** @define option [[js.UndefOr]] + * @define none [[js.undefined]] */ -final class UndefOrOps[A](val self: UndefOr[A]) extends AnyVal { +final class UndefOrOps[A](val self: js.UndefOr[A]) extends AnyVal { import UndefOrOps._ /** Returns true if the option is `undefined`, false otherwise. */ - @inline final def isEmpty: Boolean = isUndefined(self) + @inline final def isEmpty: Boolean = js.isUndefined(self) /** Returns true if the option is not `undefined`, false otherwise. */ @@ -100,8 +104,8 @@ final class UndefOrOps[A](val self: UndefOr[A]) extends AnyVal { * @see flatMap * @see foreach */ - @inline final def map[B](f: A => B): UndefOr[B] = - if (isEmpty) undefined else f(this.forceGet) + @inline final def map[B](f: A => B): js.UndefOr[B] = + if (isEmpty) js.undefined else f(this.forceGet) /** Returns the result of applying `f` to this $option's * value if the $option is nonempty. Otherwise, evaluates @@ -125,27 +129,27 @@ final class UndefOrOps[A](val self: UndefOr[A]) extends AnyVal { * @see map * @see foreach */ - @inline final def flatMap[B](f: A => UndefOr[B]): UndefOr[B] = - if (isEmpty) undefined else f(this.forceGet) + @inline final def flatMap[B](f: A => js.UndefOr[B]): js.UndefOr[B] = + if (isEmpty) js.undefined else f(this.forceGet) - def flatten[B](implicit ev: A <:< UndefOr[B]): UndefOr[B] = - if (isEmpty) undefined else ev(this.forceGet) + def flatten[B](implicit ev: A <:< js.UndefOr[B]): js.UndefOr[B] = + if (isEmpty) js.undefined else ev(this.forceGet) /** Returns this $option if it is nonempty '''and''' applying the predicate `p` to * this $option's value returns true. Otherwise, return $none. * * @param p the predicate used for testing. */ - @inline final def filter(p: A => Boolean): UndefOr[A] = - if (isEmpty || p(this.forceGet)) self else undefined + @inline final def filter(p: A => Boolean): js.UndefOr[A] = + if (isEmpty || p(this.forceGet)) self else js.undefined /** Returns this $option if it is nonempty '''and''' applying the predicate `p` to * this $option's value returns false. Otherwise, return $none. * * @param p the predicate used for testing. */ - @inline final def filterNot(p: A => Boolean): UndefOr[A] = - if (isEmpty || !p(this.forceGet)) self else undefined + @inline final def filterNot(p: A => Boolean): js.UndefOr[A] = + if (isEmpty || !p(this.forceGet)) self else js.undefined /** Returns false if the option is $none, true otherwise. * @note Implemented here to avoid the implicit conversion to Iterable. @@ -206,15 +210,15 @@ final class UndefOrOps[A](val self: UndefOr[A]) extends AnyVal { * @return the result of applying `pf` to this $option's * value (if possible), or $none. */ - @inline final def collect[B](pf: PartialFunction[A, B]): UndefOr[B] = - if (isEmpty) undefined - else pf.applyOrElse(this.forceGet, (_: A) => undefined).asInstanceOf[UndefOr[B]] + @inline final def collect[B](pf: PartialFunction[A, B]): js.UndefOr[B] = + if (isEmpty) js.undefined + else pf.applyOrElse(this.forceGet, (_: A) => js.undefined).asInstanceOf[js.UndefOr[B]] /** Returns this $option if it is nonempty, * otherwise return the result of evaluating `alternative`. * @param alternative the alternative expression. */ - @inline final def orElse[B >: A](alternative: => UndefOr[B]): UndefOr[B] = + @inline final def orElse[B >: A](alternative: => js.UndefOr[B]): js.UndefOr[B] = if (isEmpty) alternative else self /** Returns a singleton iterator returning the $option's value @@ -264,9 +268,9 @@ object UndefOrOps { * collection" contract even though it seems unlikely to matter much in a * collection with max size 1. */ - final class WithFilter[A](self: UndefOr[A], p: A => Boolean) { - def map[B](f: A => B): UndefOr[B] = self filter p map f - def flatMap[B](f: A => UndefOr[B]): UndefOr[B] = self filter p flatMap f + final class WithFilter[A](self: js.UndefOr[A], p: A => Boolean) { + def map[B](f: A => B): js.UndefOr[B] = self filter p map f + def flatMap[B](f: A => js.UndefOr[B]): js.UndefOr[B] = self filter p flatMap f def foreach[U](f: A => U): Unit = self filter p foreach f def withFilter(q: A => Boolean): WithFilter[A] = new WithFilter[A](self, x => p(x) && q(x)) diff --git a/library/src/main/scala/scala/scalajs/js/UnicodeNormalizationForm.scala b/library/src/main/scala/scala/scalajs/js/UnicodeNormalizationForm.scala index 1b713730cd..951c1c86f2 100644 --- a/library/src/main/scala/scala/scalajs/js/UnicodeNormalizationForm.scala +++ b/library/src/main/scala/scala/scalajs/js/UnicodeNormalizationForm.scala @@ -14,23 +14,25 @@ package scala.scalajs.js +import scala.scalajs.js + /** A Unicode Normalization Form. * - * @see [[JSStringOps JSStringOps.normalize]] + * @see [[JSStringOps js.JSStringOps.normalize]] * @see [[http://www.unicode.org/reports/tr15/ Unicode Normalization Forms]] */ -sealed trait UnicodeNormalizationForm extends Any +sealed trait UnicodeNormalizationForm extends js.Any object UnicodeNormalizationForm { /** Normalization Form Canonical Composition. */ - final val NFC = "NFC".asInstanceOf[UnicodeNormalizationForm] + final val NFC = "NFC".asInstanceOf[js.UnicodeNormalizationForm] /** Normalization Form Canonical Decomposition. */ - final val NFD = "NFD".asInstanceOf[UnicodeNormalizationForm] + final val NFD = "NFD".asInstanceOf[js.UnicodeNormalizationForm] /** Normalization Form Compatibility Composition. */ - final val NFKC = "NFKC".asInstanceOf[UnicodeNormalizationForm] + final val NFKC = "NFKC".asInstanceOf[js.UnicodeNormalizationForm] /** Normalization Form Compatibility Decomposition. */ - final val NFKD = "NFKD".asInstanceOf[UnicodeNormalizationForm] + final val NFKD = "NFKD".asInstanceOf[js.UnicodeNormalizationForm] } diff --git a/library/src/main/scala/scala/scalajs/js/Union.scala b/library/src/main/scala/scala/scalajs/js/Union.scala index 41a378fd4b..61c96d0bfe 100644 --- a/library/src/main/scala/scala/scalajs/js/Union.scala +++ b/library/src/main/scala/scala/scalajs/js/Union.scala @@ -12,6 +12,8 @@ package scala.scalajs.js import scala.language.implicitConversions import scala.language.higherKinds +import scala.scalajs.js + /** Value of type A or B (union type). * * Scala does not have union types, but they are important to many @@ -60,8 +62,8 @@ object | { // scalastyle:ignore ReusableEvidence.asInstanceOf[Evidence[A, B1 | B2]] /** If `A <: B`, then `A <: js.UndefOr[B]`. */ - implicit def undefOr[A, B](implicit ev: Evidence[A, B]): Evidence[A, UndefOr[B]] = - ReusableEvidence.asInstanceOf[Evidence[A, UndefOr[B]]] + implicit def undefOr[A, B](implicit ev: Evidence[A, B]): Evidence[A, js.UndefOr[B]] = + ReusableEvidence.asInstanceOf[Evidence[A, js.UndefOr[B]]] } object Evidence extends EvidenceLowPrioImplicits { diff --git a/library/src/main/scala/scala/scalajs/js/WrappedArray.scala b/library/src/main/scala/scala/scalajs/js/WrappedArray.scala index 00669ad976..1f9874b190 100644 --- a/library/src/main/scala/scala/scalajs/js/WrappedArray.scala +++ b/library/src/main/scala/scala/scalajs/js/WrappedArray.scala @@ -10,25 +10,27 @@ package scala.scalajs.js import scala.language.implicitConversions +import scala.scalajs.js + import scala.collection.mutable import mutable.Builder import scala.collection.generic.{CanBuildFrom, GenericCompanion, SeqFactory} -/** Equivalent of scm.WrappedArray for js.Array */ +/** Equivalent of `scm.WrappedArray` for [[js.Array]]. */ @inline -final class WrappedArray[A](val array: Array[A]) +final class WrappedArray[A](val array: js.Array[A]) extends mutable.AbstractBuffer[A] - with scala.collection.generic.GenericTraversableTemplate[A, WrappedArray] + with scala.collection.generic.GenericTraversableTemplate[A, js.WrappedArray] with mutable.IndexedSeq[A] - with mutable.BufferLike[A, WrappedArray[A]] - with mutable.ArrayLike[A, WrappedArray[A]] - with Builder[A, WrappedArray[A]] { + with mutable.BufferLike[A, js.WrappedArray[A]] + with mutable.ArrayLike[A, js.WrappedArray[A]] + with Builder[A, js.WrappedArray[A]] { - /** Creates a new empty [[WrappedArray]]. */ - def this() = this(Array()) + /** Creates a new empty [[js.WrappedArray]]. */ + def this() = this(js.Array()) - override def companion: GenericCompanion[WrappedArray] = WrappedArray + override def companion: GenericCompanion[js.WrappedArray] = js.WrappedArray // IndexedSeq interface @@ -46,7 +48,7 @@ final class WrappedArray[A](val array: Array[A]) @inline def clear(): Unit = array.length = 0 - @inline def result(): WrappedArray[A] = this + @inline def result(): js.WrappedArray[A] = this // Rest of BufferLike interface @@ -75,18 +77,18 @@ final class WrappedArray[A](val array: Array[A]) } -/** Factory for [[WrappedArray]]. Mainly provides the relevant +/** Factory for [[js.WrappedArray]]. Mainly provides the relevant * [[scala.collection.generic.CanBuildFrom CanBuildFroms]]s and implicit * conversions. */ -object WrappedArray extends SeqFactory[WrappedArray] { +object WrappedArray extends SeqFactory[js.WrappedArray] { /** Standard CBF for [[WrappedArray]] */ - implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, WrappedArray[A]] = + implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, js.WrappedArray[A]] = ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]] - def newBuilder[A]: Builder[A, WrappedArray[A]] = new WrappedArray[A] + def newBuilder[A]: Builder[A, js.WrappedArray[A]] = new js.WrappedArray[A] - implicit def toJSArray[A](wrappedArray: WrappedArray[A]): Array[A] = + implicit def toJSArray[A](wrappedArray: js.WrappedArray[A]): js.Array[A] = wrappedArray.array } diff --git a/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala b/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala index c0c8e3b1f9..cfd52b88a6 100644 --- a/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala +++ b/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala @@ -18,10 +18,10 @@ import scala.collection.generic.CanBuildFrom /** Wrapper to use a js.Dictionary as a scala.mutable.Map */ @inline -class WrappedDictionary[A](val dict: Dictionary[A]) +class WrappedDictionary[A](val dict: js.Dictionary[A]) extends mutable.AbstractMap[String, A] with mutable.Map[String, A] - with mutable.MapLike[String, A, WrappedDictionary[A]] { + with mutable.MapLike[String, A, js.WrappedDictionary[A]] { import WrappedDictionary._ @@ -69,10 +69,10 @@ class WrappedDictionary[A](val dict: Dictionary[A]) @inline override def keys: scala.collection.Iterable[String] = - Object.keys(dict.asInstanceOf[Object]) + js.Object.keys(dict.asInstanceOf[js.Object]) - override def empty: WrappedDictionary[A] = - new WrappedDictionary(Dictionary.empty) + override def empty: js.WrappedDictionary[A] = + new js.WrappedDictionary(Dictionary.empty) } @@ -82,12 +82,12 @@ object WrappedDictionary { private object Cache { val safeHasOwnProperty = - Dynamic.global.Object.prototype.hasOwnProperty - .asInstanceOf[ThisFunction1[Dictionary[_], String, Boolean]] + js.Dynamic.global.Object.prototype.hasOwnProperty + .asInstanceOf[js.ThisFunction1[js.Dictionary[_], String, Boolean]] } @inline - private def safeHasOwnProperty(dict: Dictionary[_], key: String): Boolean = + private def safeHasOwnProperty(dict: js.Dictionary[_], key: String): Boolean = Cache.safeHasOwnProperty(dict, key) @js.native @@ -97,18 +97,21 @@ object WrappedDictionary { * This must not be called if the dictionary does not contain the key. */ @JSBracketAccess - def rawApply(key: String): A = native + def rawApply(key: String): A = js.native /** Writes a field of this object. */ @JSBracketAccess - def rawUpdate(key: String, value: A): Unit = native + def rawUpdate(key: String, value: A): Unit = js.native } private final class DictionaryIterator[+A]( - dict: Dictionary[A]) extends scala.collection.Iterator[(String, A)] { - private[this] val keys = Object.keys(dict.asInstanceOf[Object]) + dict: js.Dictionary[A]) extends scala.collection.Iterator[(String, A)] { + + private[this] val keys = js.Object.keys(dict.asInstanceOf[js.Object]) private[this] var index: Int = 0 + def hasNext(): Boolean = index < keys.length + def next(): (String, A) = { val key = keys(index) index += 1 @@ -116,21 +119,22 @@ object WrappedDictionary { } } - def empty[A]: WrappedDictionary[A] = new WrappedDictionary(Dictionary.empty) + def empty[A]: js.WrappedDictionary[A] = + new js.WrappedDictionary(js.Dictionary.empty) - implicit def canBuildFrom[A]: CanBuildFrom[WrappedDictionary[_], (String, A), WrappedDictionary[A]] = { - new CanBuildFrom[WrappedDictionary[_], (String, A), WrappedDictionary[A]] { - def apply(from: WrappedDictionary[_]): Builder[(String, A), WrappedDictionary[A]] = + implicit def canBuildFrom[A]: CanBuildFrom[js.WrappedDictionary[_], (String, A), js.WrappedDictionary[A]] = { + new CanBuildFrom[js.WrappedDictionary[_], (String, A), js.WrappedDictionary[A]] { + def apply(from: js.WrappedDictionary[_]): Builder[(String, A), js.WrappedDictionary[A]] = new WrappedDictionaryBuilder[A] - def apply(): Builder[(String, A), WrappedDictionary[A]] = + def apply(): Builder[(String, A), js.WrappedDictionary[A]] = new WrappedDictionaryBuilder[A] } } private final class WrappedDictionaryBuilder[A] - extends Builder[(String, A), WrappedDictionary[A]] { + extends Builder[(String, A), js.WrappedDictionary[A]] { - private[this] var dict: Dictionary[A] = Dictionary.empty + private[this] var dict: js.Dictionary[A] = js.Dictionary.empty def +=(elem: (String, A)): this.type = { dict(elem._1) = elem._2 @@ -138,10 +142,10 @@ object WrappedDictionary { } def clear(): Unit = - dict = Dictionary.empty + dict = js.Dictionary.empty - def result(): WrappedDictionary[A] = - new WrappedDictionary(dict) + def result(): js.WrappedDictionary[A] = + new js.WrappedDictionary(dict) } } diff --git a/library/src/main/scala/scala/scalajs/js/package.scala b/library/src/main/scala/scala/scalajs/js/package.scala index c9e8ed62d8..67b577efb3 100644 --- a/library/src/main/scala/scala/scalajs/js/package.scala +++ b/library/src/main/scala/scala/scalajs/js/package.scala @@ -82,9 +82,11 @@ package object js { */ def constructorOf[T <: js.Any]: js.Dynamic = throw new java.lang.Error("stub") - /** Makes explicit an implicitly available `ConstructorTag[T]`. */ - def constructorTag[T <: js.Any](implicit tag: ConstructorTag[T]): ConstructorTag[T] = + /** Makes explicit an implicitly available [[js.ConstructorTag]]. */ + def constructorTag[T <: js.Any]( + implicit tag: js.ConstructorTag[T]): js.ConstructorTag[T] = { tag + } /** Evaluates JavaScript code and returns the result. */ @inline def eval(x: String): scala.Any = From 16e93b49f931c16e7b9b5383eb542e4dfe194594 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 5 Jun 2017 20:54:31 +0200 Subject: [PATCH 0329/2665] Add support for module initializers with an `args: Array[String]`. This allows to use "standard", cross-platform `main` methods as module initializers. --- project/BinaryIncompatibilities.scala | 3 ++ project/Build.scala | 14 +++++- .../compiler/ModuleInitializersTest.scala | 20 +++++++- .../core/tools/test/js/QuickLinker.scala | 49 ++++++++++++++----- .../core/tools/linker/ModuleInitializer.scala | 43 ++++++++++++++++ .../linker/backend/emitter/ClassEmitter.scala | 5 ++ .../backend/emitter/FunctionEmitter.scala | 14 +----- .../tools/linker/backend/emitter/JSGen.scala | 17 +++++++ 8 files changed, 137 insertions(+), 28 deletions(-) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index c77318b933..36dca7dc7a 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -6,6 +6,9 @@ object BinaryIncompatibilities { ) val Tools = Seq( + // private[emitter], not an issue + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.backend.emitter.FunctionEmitter#JSDesugar.genClassDataOf") ) val JSEnvs = Seq( diff --git a/project/Build.scala b/project/Build.scala index 4859546ac8..c4a8ff8d1d 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -659,7 +659,9 @@ object Build { val unescapedMainMethods = List( "org.scalajs.testsuite.compiler.ModuleInitializerInNoConfiguration.main", "org.scalajs.testsuite.compiler.ModuleInitializerInTestConfiguration.main2", - "org.scalajs.testsuite.compiler.ModuleInitializerInTestConfiguration.main1" + "org.scalajs.testsuite.compiler.ModuleInitializerInTestConfiguration.main1", + "org.scalajs.testsuite.compiler.ModuleInitializerInTestConfiguration.mainArgs1()", + "org.scalajs.testsuite.compiler.ModuleInitializerInTestConfiguration.mainArgs2(foo,bar)" ) seqOfStringsToJSArrayCode(unescapedMainMethods) } @@ -1587,6 +1589,16 @@ object Build { ModuleInitializer.mainMethod( "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")) } ) ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ModuleInitializersTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ModuleInitializersTest.scala index 1ef295c39e..8555cdd235 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ModuleInitializersTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ModuleInitializersTest.scala @@ -15,7 +15,13 @@ class ModuleInitializersTest { @Test def correctInitializers(): Unit = { assertArrayEquals( - Array[AnyRef](NoConfigMain, TestConfigMain2, TestConfigMain1), + Array[AnyRef]( + NoConfigMain, + TestConfigMain2, + TestConfigMain1, + TestConfigMainArgs1 + "()", + TestConfigMainArgs2 + "(foo, bar)" + ), moduleInitializersEffects.toArray[AnyRef]) } @@ -26,6 +32,8 @@ object ModuleInitializersTest { final val CompileConfigMain = "ModuleInitializerInCompileConfiguration.main" final val TestConfigMain1 = "ModuleInitializerInTestConfiguration.main1" final val TestConfigMain2 = "ModuleInitializerInTestConfiguration.main2" + final val TestConfigMainArgs1 = "ModuleInitializerInTestConfiguration.mainArgs1" + final val TestConfigMainArgs2 = "ModuleInitializerInTestConfiguration.mainArgs2" val moduleInitializersEffects = new scala.collection.mutable.ListBuffer[String] @@ -58,4 +66,14 @@ object ModuleInitializerInTestConfiguration { def main2(): Unit = { moduleInitializersEffects += TestConfigMain2 } + + def mainArgs1(args: Array[String]): Unit = { + moduleInitializersEffects += + TestConfigMainArgs1 + args.mkString("(", ", ", ")") + } + + def mainArgs2(args: Array[String]): Unit = { + moduleInitializersEffects += + TestConfigMainArgs2 + args.mkString("(", ", ", ")") + } } diff --git 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 index 620ffadc28..a071d2bf0c 100644 --- 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 @@ -16,26 +16,26 @@ object QuickLinker { /** Link a Scala.js application on Node.js */ @JSExport def linkNode(irFilesAndJars: js.Array[String], - mainMethods: js.Array[String]): String = { - linkNodeInternal(Semantics.Defaults, irFilesAndJars, mainMethods) + moduleInitializers: js.Array[String]): String = { + linkNodeInternal(Semantics.Defaults, irFilesAndJars, moduleInitializers) } /** Link the Scala.js test suite on Node.js */ @JSExport def linkTestSuiteNode(irFilesAndJars: js.Array[String], - mainMethods: js.Array[String]): String = { + moduleInitializers: js.Array[String]): String = { val semantics = Semantics.Defaults.withRuntimeClassName(_.fullName match { case "org.scalajs.testsuite.compiler.ReflectionTest$RenamedTestClass" => "renamed.test.Class" case fullName => fullName }) - linkNodeInternal(semantics, irFilesAndJars, mainMethods) + linkNodeInternal(semantics, irFilesAndJars, moduleInitializers) } /** Link a Scala.js application on Node.js */ def linkNodeInternal(semantics: Semantics, - irFilesAndJars: Seq[String], mainMethods: Seq[String]): String = { + irFilesAndJars: Seq[String], moduleInitializers: Seq[String]): String = { val cache = (new IRFileCache).newCache val linker = Linker(semantics, OutputMode.ECMAScript51Isolated, @@ -58,18 +58,41 @@ object QuickLinker { val ir = cache.cached(irContainers) - val moduleInitializers = mainMethods.map { mainMethod => - val lastDot = mainMethod.lastIndexOf('.') - if (lastDot < 0) - throw new IllegalArgumentException(s"$mainMethod is not a valid main method") - ModuleInitializer.mainMethod(mainMethod.substring(0, lastDot), - mainMethod.substring(lastDot + 1)) - } + val parsedModuleInitializers = + moduleInitializers.map(parseModuleInitializer) val out = WritableMemVirtualJSFile("out.js") - linker.link(ir, moduleInitializers, out, new ScalaConsoleLogger) + linker.link(ir, parsedModuleInitializers, out, new ScalaConsoleLogger) 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) + } + } + } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ModuleInitializer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ModuleInitializer.scala index cdefb0f912..7189519f01 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ModuleInitializer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ModuleInitializer.scala @@ -33,6 +33,10 @@ object ModuleInitializer { encodedMainMethodName: String) extends ModuleInitializer + private[linker] final case class MainMethodWithArgs(moduleClassName: String, + encodedMainMethodName: String, args: List[String]) + extends ModuleInitializer + /** Makes an [[ModuleInitializer]] that calls a zero-argument method returning * `Unit` in a top-level `object`. * @@ -48,6 +52,41 @@ object ModuleInitializer { mainMethodName + "__V") } + /** Makes an [[ModuleInitializer]] that calls a method of a top-level + * `object`, taking an `Array[String]` and returning `Unit`. + * + * An empty array is passed as argument. + * + * @param moduleClassName + * The fully-qualified name of the module class, e.g., `"foo.bar.Babar"`. + * Note that it does not end with `$`. + * @param mainMethodName + * The name of the main method to invoke, e.g., `"main"`. + */ + def mainMethodWithArgs(moduleClassName: String, + mainMethodName: String): ModuleInitializer = { + mainMethodWithArgs(moduleClassName, mainMethodName, Nil) + } + + /** Makes an [[ModuleInitializer]] that calls a method of a top-level + * `object`, taking an `Array[String]` and returning `Unit`. + * + * An array containing the specified `args` is passed as argument. + * + * @param moduleClassName + * The fully-qualified name of the module class, e.g., `"foo.bar.Babar"`. + * Note that it does not end with `$`. + * @param mainMethodName + * The name of the main method to invoke, e.g., `"main"`. + * @param args + * The arguments to pass as an array. + */ + def mainMethodWithArgs(moduleClassName: String, mainMethodName: String, + args: List[String]): ModuleInitializer = { + MainMethodWithArgs(encodeClassName(moduleClassName + "$"), + mainMethodName + "__AT__V", args) + } + def toSymbolRequirement( entryPoints: Seq[ModuleInitializer]): SymbolRequirement = { val factory = SymbolRequirement.factory("module initializers") @@ -55,6 +94,10 @@ object ModuleInitializer { entryPoint match { case VoidMainMethod(moduleClassName, mainMethodName) => factory.callOnModule(moduleClassName, mainMethodName) + + case MainMethodWithArgs(moduleClassName, mainMethodName, _) => + factory.callOnModule(moduleClassName, mainMethodName) ++ + factory.classData("T") } } factory.multiple(requirements: _*) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index 47c870d258..314e15f460 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -1174,6 +1174,11 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { moduleInitializer match { case ModuleInitializer.VoidMainMethod(moduleClassName, mainMethodName) => js.Apply(genLoadModule(moduleClassName) DOT mainMethodName, Nil) + + case ModuleInitializer.MainMethodWithArgs(moduleClassName, mainMethodName, + args) => + js.Apply(genLoadModule(moduleClassName) DOT mainMethodName, + genArrayValue(ArrayType("T", 1), args.map(js.StringLiteral(_))) :: Nil) } } diff --git 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 index d3db25fc75..f049f4f9b7 100644 --- 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 @@ -1932,8 +1932,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { genClassDataOf(tpe), js.ArrayConstr(lengths map transformExpr)) case ArrayValue(tpe, elems) => - genCallHelper("makeNativeArrayWrapper", - genClassDataOf(tpe), js.ArrayConstr(elems map transformExpr)) + genArrayValue(tpe, elems.map(transformExpr)) case ArrayLength(array) => genIdentBracketSelect(js.DotSelect(transformExpr(array), @@ -2211,17 +2210,6 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { } } - 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(envField("d", base)) { (prev, _) => - js.Apply(js.DotSelect(prev, js.Ident("getArrayOf")), Nil) - } - } - } - private def genFround(arg: js.Tree)(implicit pos: Position): js.Tree = { genCallHelper("fround", arg) } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala index 9b4f9fd0fe..4b6b245ba7 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala @@ -202,6 +202,23 @@ private[emitter] final class JSGen(val semantics: Semantics, } } + def genArrayValue(tpe: ArrayType, elems: List[Tree])( + implicit pos: Position): Tree = { + genCallHelper("makeNativeArrayWrapper", genClassDataOf(tpe), + ArrayConstr(elems)) + } + + def genClassDataOf(cls: ReferenceType)(implicit pos: Position): Tree = { + cls match { + case ClassType(className) => + envField("d", className) + case ArrayType(base, dims) => + (1 to dims).foldLeft[Tree](envField("d", base)) { (prev, _) => + Apply(DotSelect(prev, Ident("getArrayOf")), Nil) + } + } + } + def envModuleField(module: String)(implicit pos: Position): VarRef = { /* This is written so that the happy path, when `module` contains only * valid characters, is fast. From 48683843abc956c654dd1a1f50fb747988080f16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 5 Jun 2017 21:55:36 +0200 Subject: [PATCH 0330/2665] Use the new `mainWithArgs` module initiliazer in the partest runner. This completely replaces the synthetic `runnerIR`. --- .../scala/tools/nsc/MainGenericRunner.scala | 70 +------------------ 1 file changed, 3 insertions(+), 67 deletions(-) diff --git a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala index dc6774c550..9212a394b6 100644 --- a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala +++ b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala @@ -61,13 +61,10 @@ class MainGenericRunner { val logger = new ScalaConsoleLogger(Level.Warn) val jsConsole = new ScalaConsoleJSConsole val semantics = readSemantics() - val ir = ( - loadIR(command.settings.classpathURLs) :+ - runnerIR(command.thingToRun, command.arguments) - ) + val ir = loadIR(command.settings.classpathURLs) - val moduleInitializers = - Seq(ModuleInitializer.mainMethod("PartestLauncher", "main")) + val moduleInitializers = Seq(ModuleInitializer.mainMethodWithArgs( + command.thingToRun, "main", command.arguments)) val linkerConfig = Linker.Config() .withSourceMap(false) @@ -94,67 +91,6 @@ class MainGenericRunner { cache.cached(irContainers) } - private def runnerIR(mainObj: String, args: List[String]) = { - import ir.Infos._ - import ir.ClassKind - import ir.Trees._ - import ir.Types._ - - val mainModuleClassName = ir.Definitions.encodeClassName(mainObj + "$") - val className = "PartestLauncher$" - val encodedClassName = ir.Definitions.encodeClassName(className) - - val definition = { - implicit val DummyPos = ir.Position.NoPosition - ClassDef( - Ident(encodedClassName, Some(className)), - ClassKind.ModuleClass, - Some(Ident("O", Some("java.lang.Object"))), - Nil, - None, - List( - MethodDef( - static = false, - Ident("init___", Some("")), - Nil, - NoType, - Some( - ApplyStatically(This()(ClassType(encodedClassName)), - ClassType(ir.Definitions.ObjectClass), - Ident("init___"), - Nil - )(NoType) - ) - )(OptimizerHints.empty, None), - MethodDef( - static = false, - Ident("main__V", Some("main")), - Nil, - NoType, - Some( - Apply(LoadModule(ClassType(mainModuleClassName)), - Ident("main__AT__V"), - List( - ArrayValue(ArrayType("T", 1), args.map(StringLiteral(_))) - ) - )(NoType) - ) - )(OptimizerHints.empty, None) - ) - )(OptimizerHints.empty) - } - - val info = generateClassInfo(definition) - - val infoAndDefinition = (info, definition) - - new VirtualScalaJSIRFile { - def exists: Boolean = true - def path: String = "PartestLauncher$.sjsir" - def infoAndTree: (ClassInfo, ClassDef) = infoAndDefinition - } - } - private def urlToFile(url: java.net.URL) = { try { new File(url.toURI()) From 42708843ecf5dfa957bf4e5f5c08432095ccb4b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 7 Jun 2017 17:03:33 +0200 Subject: [PATCH 0331/2665] Recognize any "standard" JVM-style main object in the sbt plugin. In addition to recognizing objects extending `js.JSApp`, the sbt plugin now recognizes "standard" main methods as well, i.e., objects with a method of the form def main(args: Array[String]): Unit = ... If such an object is used as main class, its main method is called using the new `ModuleInitializer.mainMethodWithArgs`. This has the nice benefit that we can finally write a cross-platform main object. We "softly" deprecate `js.JSApp`: its documentation says not to use anymore, but it does not cause a deprecation warning yet. For backward compatibility, objects extending `js.JSApp` are still recognized, and their `main(): Unit` method will be called. There are some subtle scenarios regarding backward compatibility: * If an object *both* extends `js.JSApp` and has a standard main method, the `main()` method of `js.JSApp` is preferred, for backward compatibility. * If an object has a `main(): Unit` method but does not extend `js.JSApp`, it will not be *discovered*. In that case, we assume the old style and call `main()`. This can happen if the user explicitly sets the `mainClass` setting. * If an object has *both* a `main(): Unit` method and a `main(args: Array[String]): Unit` method, it *will* now be discovered, and the new style will be assumed. This can potentially break compatibility, as now the standard main will be called. This only happens in case the user has explicitly set `mainClass`. Moreover, it is only problematic if `main()` does not behave the same as `main(Array())`, in which case the codebase is arguably in a bad shape to begin with. * The very fact of recognizing *more* objects as potential main objects means that the sbt build can break because it cannot automatically choose between several discovered objects. This will however fail to link with a nice error message, so it is not too bad. Here are some examples. * Old-style only, `main()` is selected object OldStyleOnly extends js.JSApp { def main(): Unit = ... } * New-style only, `main(Array[String])` is selected object NewStyleOnly { def main(args: Array[String]): Unit = ... } * Old and new style combined, `main()` is selected object OldAndNewStyle extends js.JSApp { def main(): Unit = ... def main(args: Array[String]): Unit = ... } * `def main(): Unit` without `js.JSApp` only, `main()` is selected object OldStyleNonJSApp { def main(): Unit = ... } * Both styles of methods without `js.JSApp`, `main(Array[String])` is selected (potentially silently breaking) object OldAndNewStyleNonJSApp { def main(): Unit = ... def main(args: Array[String]): Unit = ... } * Both styles exist in two different objects, sbt reports an ambiguity and demands that `mainClass` be set explicitly object OldStyle extends js.JSApp { def main(): Unit = ... } object NewStyle { def main(args: Array[String]): Unit = ... } --- .../main/scala/scala/scalajs/js/JSApp.scala | 19 +++++++- sbt-plugin-test/build.sbt | 6 ++- .../main/scala/sbttest/noDOM/TestApp.scala | 6 +-- .../main/scala/sbttest/withDOM/TestApp.scala | 6 +-- .../sbtplugin/ScalaJSPluginInternal.scala | 47 ++++++++++++++++--- 5 files changed, 66 insertions(+), 18 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/js/JSApp.scala b/library/src/main/scala/scala/scalajs/js/JSApp.scala index fd12207afa..a2705e7c34 100644 --- a/library/src/main/scala/scala/scalajs/js/JSApp.scala +++ b/library/src/main/scala/scala/scalajs/js/JSApp.scala @@ -2,7 +2,12 @@ package scala.scalajs.js import annotation.{JSExport, JSExportDescendentObjects} -/** Base class for top-level, entry point main objects. +/** 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. @@ -12,6 +17,18 @@ import annotation.{JSExport, JSExportDescendentObjects} * 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. + * + * 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 { diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index ef8a62a4f5..c94eb52d18 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -49,7 +49,8 @@ lazy val noDOM = project.settings(baseSettings: _*). name := "Scala.js sbt test w/o DOM", scalaJSOutputWrapper := ( "// Scala.js - noDOM sbt test\n//\n// Compiled with Scala.js\n", - "// End of Scala.js generated script") + "// End of Scala.js generated script"), + scalaJSUseMainModuleInitializer := true ). /* This hopefully exposes concurrent uses of the linker. If it fails/gets * flaky, there is a bug somewhere - #2202 @@ -66,7 +67,8 @@ lazy val withDOM = project.settings(baseSettings: _*). "org.webjars" % "jquery" % "1.10.2" / "jquery.js"), scalaJSOutputWrapper := ( "// Scala.js - withDOM sbt test\n//\n// Compiled with Scala.js\n", - "// End of Scala.js generated script") + "// End of Scala.js generated script"), + scalaJSUseMainModuleInitializer := true ) lazy val jetty9 = project.settings(baseSettings: _*). diff --git a/sbt-plugin-test/noDOM/src/main/scala/sbttest/noDOM/TestApp.scala b/sbt-plugin-test/noDOM/src/main/scala/sbttest/noDOM/TestApp.scala index 16a4cbe430..8f62001441 100644 --- a/sbt-plugin-test/noDOM/src/main/scala/sbttest/noDOM/TestApp.scala +++ b/sbt-plugin-test/noDOM/src/main/scala/sbttest/noDOM/TestApp.scala @@ -1,10 +1,8 @@ package sbttest.noDOM -import scala.scalajs.js +object TestApp { -object TestApp extends js.JSApp { - - def main(): Unit = { + def main(args: Array[String]): Unit = { println(Lib.foo("Hello World")) println(Lib.sq(10)) } diff --git a/sbt-plugin-test/withDOM/src/main/scala/sbttest/withDOM/TestApp.scala b/sbt-plugin-test/withDOM/src/main/scala/sbttest/withDOM/TestApp.scala index e61ed20a17..4c91bbac99 100644 --- a/sbt-plugin-test/withDOM/src/main/scala/sbttest/withDOM/TestApp.scala +++ b/sbt-plugin-test/withDOM/src/main/scala/sbttest/withDOM/TestApp.scala @@ -1,10 +1,8 @@ package sbttest.withDOM -import scala.scalajs.js +object TestApp { -object TestApp extends js.JSApp { - - def main(): Unit = { + def main(args: Array[String]): Unit = { Lib.appendDocument("Hello World") Lib.appendDocument("Still Here!") diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index f21cd12b5e..8ba38285ac 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -86,6 +86,15 @@ object ScalaJSPluginInternal { "All .sjsir files on the fullClasspath, used by scalajsp", KeyRanks.Invisible) + /** Internal task to map discovered main classes to whether they are in the + * "new" style (true, standard main method) or the "old" style (false, + * `js.JSApp` or `main(): Unit` method). + */ + val scalaJSDiscoveredMainClasses = TaskKey[Map[String, Boolean]]( + "scalaJSDiscoveredMainClasses", + "Discovered main classes and whether they use the \"new\" style", + KeyRanks.Invisible) + val scalaJSModuleIdentifier = TaskKey[Option[String]]( "scalaJSModuleIdentifier", "An identifier for the module which contains the exports of Scala.js", @@ -731,7 +740,15 @@ object ScalaJSPluginInternal { .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" @@ -739,10 +756,13 @@ object ScalaJSPluginInternal { def isJSApp(discovered: Discovered) = discovered.isModule && discovered.baseClasses.contains(jsApp) - Discovery(Set(jsApp), Set.empty)(Tests.allDefs(analysis)) collect { + Map(Discovery(Set(jsApp), Set.empty)(Tests.allDefs(analysis)).collect { + // Old-style first, so that in case of ambiguity, we keep backward compat case (definition, discovered) if isJSApp(discovered) => - definition.name - } + definition.name -> false + case (definition, discovered) if discovered.hasMain => + definition.name -> true + }: _*) } private val runMainParser = { @@ -754,8 +774,24 @@ object ScalaJSPluginInternal { // These settings will be filtered by the stage dummy tasks val scalaJSRunSettings = Seq( + scalaJSDiscoveredMainClasses := { + discoverScalaJSMainClasses(compile.value) + }, + + discoveredMainClasses := { + scalaJSDiscoveredMainClasses.map(_.keys.toList.sorted: Seq[String]) + .storeAs(discoveredMainClasses).triggeredBy(compile).value + }, + scalaJSMainModuleInitializer := { - mainClass.value.map(ModuleInitializer.mainMethod(_, "main")) + val allDiscoveredMainClasses = scalaJSDiscoveredMainClasses.value + mainClass.value.map { mainCl => + val newStyleMain = allDiscoveredMainClasses.getOrElse(mainCl, false) + if (newStyleMain) + ModuleInitializer.mainMethodWithArgs(mainCl, "main") + else + ModuleInitializer.mainMethod(mainCl, "main") + } }, scalaJSModuleInitializers ++= { @@ -806,9 +842,6 @@ object ScalaJSPluginInternal { } }.value, - discoveredMainClasses := compile.map(discoverJSApps). - storeAs(discoveredMainClasses).triggeredBy(compile).value, - run := { // use assert to prevent warning about pure expr in stat pos assert(scalaJSEnsureUnforked.value) From c86ed6e89f484510b599142bd2c0f61d267c8ced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 14 May 2017 17:04:46 +0200 Subject: [PATCH 0332/2665] [backport] Integrate the setup of Node.js for the bootstrap test in the build. The setup is necessary on a local machine just as much as on the CI servers, so this is easier. (cherry picked from commit 13400c6db88f4420d356ac112eb363e04a1c243b) --- ci/matrix.xml | 6 ++---- project/Build.scala | 4 ++++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ci/matrix.xml b/ci/matrix.xml index 9edfc6be9e..1a58cf10bf 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -203,10 +203,8 @@ diff --git a/project/Build.scala b/project/Build.scala index 4859546ac8..3001b357f4 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -624,6 +624,10 @@ object Build { IO.write(outFile, testDefinitions) Seq(outFile) }.taskValue, + + // Give more memory to Node.js, and deactivate source maps + jsEnv := new NodeJSEnv(args = Seq("--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 From f4d600c58119ded23b74e9679368ef427a435db8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 9 Jun 2017 16:08:31 +0200 Subject: [PATCH 0333/2665] Introduce a new surface API for JS envs with `Config` objects. This only changes the surface API of concrete JS envs. Their existing constructors are deprecated in favor of an overload with a `Config` object. This change provides in the 0.6.x series an API that can be used in a source-compatible way between 0.6.x and 1.x. In 1.x, deeper changes to the internal API of JS envs will be done. We also take this opportunity to "move" `JSDOMNodeJSEnv` in a different package `org.scalajs.jsenv.jsdomnodejs`. Since this JS env is scheduled to be moved in a different repository in 1.x, it should eventually be in a different package anyway. --- ci/matrix.xml | 18 ++-- .../jsenv/test/JSDOMNodeJSEnvTest.scala | 2 +- .../jsenv/jsdomnodejs/JSDOMNodeJSEnv.scala | 61 ++++++++++++ .../scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala | 26 +++-- .../org/scalajs/jsenv/nodejs/NodeJSEnv.scala | 76 +++++++++++--- .../jsenv/phantomjs/PhantomJSEnv.scala | 99 ++++++++++++++++--- project/Build.scala | 7 +- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 25 ++++- .../sbtplugin/ScalaJSPluginInternal.scala | 2 +- 9 files changed, 268 insertions(+), 48 deletions(-) create mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnv.scala diff --git a/ci/matrix.xml b/ci/matrix.xml index 1a58cf10bf..daa12462b4 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -156,46 +156,46 @@ _, _ } -class NodeJSEnv private ( - @deprecatedName('nodejsPath) - override protected val executable: String, // override val for bin compat - @deprecatedName('addArgs) - args: Seq[String], - @deprecatedName('addEnv) - env: Map[String, String], - sourceMap: Boolean) - extends AbstractNodeJSEnv(executable, args, env, sourceMap) { +class NodeJSEnv(config: NodeJSEnv.Config) + extends AbstractNodeJSEnv(config.executable, config.args, config.env, + config.sourceMap) { + def this() = this(NodeJSEnv.Config()) + + @deprecated("Use the overload with a NodeJSEnv.Config.", "0.6.18") def this( @deprecatedName('nodejsPath) executable: String = "node", @@ -36,14 +33,19 @@ class NodeJSEnv private ( args: Seq[String] = Seq.empty, @deprecatedName('addEnv) env: Map[String, String] = Map.empty) = { - this(executable, args, env, sourceMap = true) + this(NodeJSEnv.Config().withExecutable(executable).withArgs(args.toList).withEnv(env)) } + @deprecated("Use the overloaded constructor with a NodeJSEnv.Config.", + "0.6.18") def withSourceMap(sourceMap: Boolean): NodeJSEnv = - new NodeJSEnv(executable, args, env, sourceMap) + new NodeJSEnv(config.withSourceMap(sourceMap)) protected def vmName: String = "Node.js" + // For binary compatibility + override protected val executable: String = config.executable + override def jsRunner(libs: Seq[ResolvedJSDependency], code: VirtualJSFile): JSRunner = { new NodeRunner(libs, code) @@ -99,3 +101,55 @@ class NodeJSEnv private ( } } + +object NodeJSEnv { + final class Config private ( + val executable: String, + val args: List[String], + val env: Map[String, String], + val sourceMap: Boolean + ) { + private def this() = { + this( + executable = "node", + args = Nil, + env = Map.empty, + sourceMap = true + ) + } + + def withExecutable(executable: String): Config = + copy(executable = executable) + + def withArgs(args: List[String]): Config = + copy(args = args) + + def withEnv(env: Map[String, String]): Config = + copy(env = env) + + def withSourceMap(sourceMap: Boolean): Config = + copy(sourceMap = sourceMap) + + private def copy( + executable: String = executable, + args: List[String] = args, + env: Map[String, String] = env, + sourceMap: Boolean = sourceMap + ): Config = { + new Config(executable, args, env, sourceMap) + } + } + + object Config { + /** Returns a default configuration for a [[NodeJSEnv]]. + * + * The defaults are: + * + * - `executable`: `"node"` + * - `args`: `Nil` + * - `env`: `Map.empty` + * - `sourceMap`: `true` + */ + def apply(): Config = new Config() + } +} diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala index 239aa4b37d..4bb8a9dbbe 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala @@ -28,21 +28,39 @@ import scala.annotation.tailrec import scala.concurrent.{ExecutionContext, TimeoutException, Future} import scala.concurrent.duration.Duration -class PhantomJSEnv( - @deprecatedName('phantomjsPath) - protected val executable: String = "phantomjs", - @deprecatedName('addArgs) - args: Seq[String] = Seq.empty, - @deprecatedName('addEnv) - env: Map[String, String] = Map.empty, - val autoExit: Boolean = true, - jettyClassLoader: ClassLoader = null -) extends ExternalJSEnv(args, env) with ComJSEnv { +class PhantomJSEnv(config: PhantomJSEnv.Config) + extends ExternalJSEnv(config.args, config.env) with ComJSEnv { import PhantomJSEnv._ + def this() = this(PhantomJSEnv.Config()) + + @deprecated("Use the overload with a PhantomJSEnv.Config.", "0.6.18") + def this( + @deprecatedName('phantomjsPath) + executable: String = "phantomjs", + @deprecatedName('addArgs) + args: Seq[String] = Seq.empty, + @deprecatedName('addEnv) + env: Map[String, String] = Map.empty, + autoExit: Boolean = true, + jettyClassLoader: ClassLoader = null + ) = { + this( + PhantomJSEnv.Config() + .withExecutable(executable) + .withArgs(args.toList) + .withEnv(env) + .withAutoExit(autoExit) + .withJettyClassLoader(jettyClassLoader)) + } + protected def vmName: String = "PhantomJS" + protected val executable: String = config.executable + + val autoExit: Boolean = config.autoExit + override def jsRunner(libs: Seq[ResolvedJSDependency], code: VirtualJSFile): JSRunner = { new PhantomRunner(libs, code) @@ -96,7 +114,7 @@ class PhantomJSEnv( private def loadMgr() = { val loader = - if (jettyClassLoader != null) jettyClassLoader + if (config.jettyClassLoader != null) config.jettyClassLoader else getClass().getClassLoader() val clazz = loader.loadClass( @@ -511,10 +529,67 @@ class PhantomJSEnv( } -private object PhantomJSEnv { +object PhantomJSEnv { private final val MaxByteMessageSize = 32768 // 32 KB private final val MaxCharMessageSize = MaxByteMessageSize / 2 // 2B per char private final val MaxCharPayloadSize = MaxCharMessageSize - 1 // frag flag private final val launcherName = "scalaJSPhantomJSEnvLauncher" + + final class Config private ( + val executable: String, + val args: List[String], + val env: Map[String, String], + val autoExit: Boolean, + val jettyClassLoader: ClassLoader + ) { + private def this() = { + this( + executable = "phantomjs", + args = Nil, + env = Map.empty, + autoExit = true, + jettyClassLoader = null + ) + } + + def withExecutable(executable: String): Config = + copy(executable = executable) + + def withArgs(args: List[String]): Config = + copy(args = args) + + def withEnv(env: Map[String, String]): Config = + copy(env = env) + + def withAutoExit(autoExit: Boolean): Config = + copy(autoExit = autoExit) + + def withJettyClassLoader(jettyClassLoader: ClassLoader): Config = + copy(jettyClassLoader = jettyClassLoader) + + private def copy( + executable: String = executable, + args: List[String] = args, + env: Map[String, String] = env, + autoExit: Boolean = autoExit, + jettyClassLoader: ClassLoader = jettyClassLoader + ): Config = { + new Config(executable, args, env, autoExit, jettyClassLoader) + } + } + + object Config { + /** Returns a default configuration for a [[PhantomJSEnv]]. + * + * The defaults are: + * + * - `executable`: `"phantomjs"` + * - `args`: `Nil` + * - `env`: `Map.empty` + * - `autoExit`: `true` + * - `jettyClassLoader`: `null` (will use the current class loader) + */ + def apply(): Config = new Config() + } } diff --git a/project/Build.scala b/project/Build.scala index 3001b357f4..b5439d248b 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -626,7 +626,12 @@ object Build { }.taskValue, // 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) { diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 0454a4567d..433c980774 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -23,7 +23,8 @@ import org.scalajs.core.ir.ScalaJSVersions import org.scalajs.jsenv.{JSEnv, JSConsole} import org.scalajs.jsenv.rhino.RhinoJSEnv -import org.scalajs.jsenv.nodejs.{NodeJSEnv, JSDOMNodeJSEnv} +import org.scalajs.jsenv.nodejs.NodeJSEnv +import org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv import org.scalajs.jsenv.phantomjs.PhantomJSEnv object ScalaJSPlugin extends AutoPlugin { @@ -121,7 +122,11 @@ object ScalaJSPlugin extends AutoPlugin { args: Seq[String] = Seq.empty, env: Map[String, String] = Map.empty ): Def.Initialize[Task[NodeJSEnv]] = Def.task { - new NodeJSEnv(executable, args, env) + new NodeJSEnv( + org.scalajs.jsenv.nodejs.NodeJSEnv.Config() + .withExecutable(executable) + .withArgs(args.toList) + .withEnv(env)) } /** @@ -141,7 +146,7 @@ object ScalaJSPlugin extends AutoPlugin { * [[sbt.ProjectExtra.inScope[* Project.inScope]]. */ @deprecated( - "Use `jsEnv := new org.scalajs.jsenv.nodejs.JSDOMNodeJSEnv(...)` " + + "Use `jsEnv := new org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv(...)` " + "instead.", "0.6.16") def JSDOMNodeJSEnv( @@ -149,7 +154,11 @@ object ScalaJSPlugin extends AutoPlugin { 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)) } /** @@ -175,7 +184,13 @@ object ScalaJSPlugin extends AutoPlugin { autoExit: Boolean = true ): Def.Initialize[Task[PhantomJSEnv]] = Def.task { val loader = scalaJSPhantomJSClassLoader.value - new PhantomJSEnv(executable, args, env, autoExit, loader) + new PhantomJSEnv( + org.scalajs.jsenv.phantomjs.PhantomJSEnv.Config() + .withExecutable(executable) + .withArgs(args.toList) + .withEnv(env) + .withAutoExit(autoExit) + .withJettyClassLoader(loader)) } // ModuleKind diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index f21cd12b5e..806fa8bea3 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -608,7 +608,7 @@ object ScalaJSPluginInternal { if (scalaJSUseRhinoInternal.value) { RhinoJSEnvInternal().value } else if (scalaJSRequestsDOM.value) { - new org.scalajs.jsenv.nodejs.JSDOMNodeJSEnv() + new org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv() } else { new org.scalajs.jsenv.nodejs.NodeJSEnv() } From ac428d8ab2d9ad9857e9f1c21d9abf3efba36500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 11 Jun 2017 14:35:14 +0200 Subject: [PATCH 0334/2665] Remove the sbt setting `isScalaJSProject`. It is redundant wrt. the `crossPlatform` setting coming from sbt-crossproject. --- sbt-plugin-test/build.sbt | 14 ++++--- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 5 --- .../sbtplugin/ScalaJSPluginInternal.scala | 1 - .../internal/ScalaJSGlobalPlugin.scala | 41 ------------------- 4 files changed, 8 insertions(+), 53 deletions(-) delete mode 100644 sbt-plugin/src/main/scala/org/scalajs/sbtplugin/internal/ScalaJSGlobalPlugin.scala diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index 3576ca01a4..cc692e1074 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -121,9 +121,10 @@ lazy val multiTest = crossProject. consoleWriter +: (jsExecutionFiles in Test).value }, - // Test isScalaJSProject (as a setting, it's evaluated when loading the build) - isScalaJSProject ~= { value => - assert(value, "isScalaJSProject should be true in multiTestJS") + // Test crossPlatform (as a setting, it's evaluated when loading the build) + crossPlatform ~= { value => + assert(value == JSPlatform, + "crossPlatform should be JSPlatform in multiTestJS") value }, @@ -146,9 +147,10 @@ lazy val multiTest = crossProject. libraryDependencies += "com.novocode" % "junit-interface" % "0.9" % "test", - // Test isScalaJSProject (as a setting, it's evaluated when loading the build) - isScalaJSProject ~= { value => - assert(!value, "isScalaJSProject should be true in multiTestJVM") + // Test crossPlatform (as a setting, it's evaluated when loading the build) + crossPlatform ~= { value => + assert(value == JVMPlatform, + "crossPlatform should be JVMPlatform in multiTestJVM") value } ). diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index a1fd60dfc0..06a7911052 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -121,11 +121,6 @@ object ScalaJSPlugin extends AutoPlugin { // All our public-facing keys - val isScalaJSProject = SettingKey[Boolean]("isScalaJSProject", - "Tests whether the current project is a Scala.js project. " + - "Do not set the value of this setting (only use it as read-only).", - BSetting) - val fastOptJS = TaskKey[Attributed[File]]("fastOptJS", "Quickly link all compiled JavaScript into a single file", APlusTask) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 9c24494e67..f0d93e7736 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -663,7 +663,6 @@ object ScalaJSPluginInternal { val scalaJSProjectBaseSettings = Seq( crossPlatform := JSPlatform, - isScalaJSProject := true, relativeSourceMaps := false, diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/internal/ScalaJSGlobalPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/internal/ScalaJSGlobalPlugin.scala deleted file mode 100644 index 80a7641f1f..0000000000 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/internal/ScalaJSGlobalPlugin.scala +++ /dev/null @@ -1,41 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - -package org.scalajs.sbtplugin.internal - -import sbt._ - -import org.scalajs.sbtplugin.ScalaJSPlugin.autoImport.isScalaJSProject - -/* Additional note about the deprecation below. Even though we are in the - * `internal` package, ScalaJSGlobalPlugin will be imported by default in the - * scope of `.sbt` files because it is an `AutoPlugin`. We do not want users to - * refer to it by accident, without noticing they are using something from - * `internal`. - * - * Since it will be loaded by sbt using reflection anyway, the deprecation will - * not creep into legitimate builds. - */ - -/** An `AutoPlugin` setting up some global settings that must be present in the - * build even if no project enables [[ScalaJSPlugin]]. - * - * This plugin should never be directly referenced in source code, and is - * therefore "deprecated forever". - */ -@deprecated("Do not explicitly mention ScalaJSGlobalPlugin in source code", - "forever") -object ScalaJSGlobalPlugin extends AutoPlugin { - override def trigger: PluginTrigger = allRequirements - - override def globalSettings: Seq[Setting[_]] = { - Seq( - isScalaJSProject := false - ) - } -} From 9c35263b29ff84143180a1b8b5c241b60f3763d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 12 Jun 2017 17:28:43 +0200 Subject: [PATCH 0335/2665] Fuse `testHtml{Fast,Full}Opt` in a unique `testHtml` task. The new task honors `scalaJSStage` to decide which stage to use. This gets rid of 2 hacks in our repo: one in our build, and one in the sbt plugin itself. It also allows `testHtml` to correctly use `jsExecutionFiles` that are dependent on the `scalaJSStage`, such as those produced by the `jsDependencies` plugin. Or more generally, correctly integrate with any custom tasks that produce different results depending on the stage. The new behavior also makes more sense when we regard the HTML test runners as a peculiar form of JS envs. In that sense, `testHtml` is more similar to `test` than it was before. --- TESTING | 8 +- ci/matrix.xml | 9 +- project/Build.scala | 28 ++---- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 7 +- .../sbtplugin/ScalaJSPluginInternal.scala | 98 +++++++------------ 5 files changed, 54 insertions(+), 96 deletions(-) diff --git a/TESTING b/TESTING index 23b3ad2f7d..5b114a4dec 100644 --- a/TESTING +++ b/TESTING @@ -43,11 +43,11 @@ The following HTML-runners must be manually tested: examples/helloworld/helloworld-{2.10|2.11}{|-fastopt}.html examples/reversi/reversi-{2.10|2.11}{|-fastopt}.html -The following sbt-plugin generated test runners must be manually tested (in both -2.10 and 2.11): +The following sbt-plugin generated test runners must be manually tested (with +Scala 2.10, 2.11 and 2.12, and in `FastOptStage` and `FullOptStage`): - testingExample/testHtml{Fast,Full}Opt - testSuite/testHtml{Fast,Full}Opt + testingExample/testHtml + testSuite/testHtml ## Sourcemaps diff --git a/ci/matrix.xml b/ci/matrix.xml index 569783d460..ca9989d22c 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -211,12 +211,13 @@ sbt ++2.10.6 ir/publishLocal tools/publishLocal jsEnvs/publishLocal \ testAdapter/publishLocal sbtPlugin/publishLocal && cd sbt-plugin-test && - sbt noDOM/run noDOM/testHtmlFastOpt noDOM/testHtmlFullOpt \ - withDOM/run withDOM/testHtmlFastOpt withDOM/testHtmlFullOpt \ - multiTestJS/testHtmlFastOpt multiTestJS/testHtmlFullOpt \ + sbt noDOM/run withDOM/run \ + noDOM/testHtml withDOM/testHtml multiTestJS/testHtml \ test \ noDOM/clean noDOM/concurrentUseOfLinkerTest \ - multiTestJS/test:testScalaJSSourceMapAttribute + multiTestJS/test:testScalaJSSourceMapAttribute && + sbt 'set scalaJSStage in Global := FullOptStage' \ + noDOM/testHtml withDOM/testHtml multiTestJS/testHtml ]]> + scalaJSJavaSystemProperties in Test in testHtml ~= { base => val unsupported = Seq("nodejs", "nodejs.jsdom", "source-maps") val supported = @@ -1382,11 +1382,11 @@ object Build { }, // And we need to actually use those patched system properties. - jsExecutionFiles in (Test, testHtmlKey) := { - val previousFiles = (jsExecutionFiles in (Test, testHtmlKey)).value + jsExecutionFiles in (Test, testHtml) := { + val previousFiles = (jsExecutionFiles in (Test, testHtml)).value val patchedSystemProperties = - (scalaJSJavaSystemProperties in (Test, testHtmlKey)).value + (scalaJSJavaSystemProperties in (Test, testHtml)).value val code = s""" var __ScalaJSEnv = { @@ -1404,17 +1404,7 @@ object Build { else file } - }, - - // Fail if we are not in the right stage. - testHtmlKey in Test := (testHtmlKey in Test).dependsOn(Def.task { - if (scalaJSStage.value != targetStage) { - throw new MessageOnlyException( - "In the Scala.js test-suite, the testHtml* tasks need " + - "scalaJSStage to be set to their respecitve stage. Stage is: " + - scalaJSStage.value) - } - }).value + } ) def testSuiteJSExecutionFilesSetting: Setting[_] = { @@ -1432,8 +1422,6 @@ object Build { commonSettings, testTagSettings, testSuiteCommonSettings(isJSTest = true), - testHtmlSettings(testHtmlFastOpt, FastOptStage), - testHtmlSettings(testHtmlFullOpt, FullOptStage), name := "Scala.js test suite", unmanagedSourceDirectories in Test ++= { @@ -1517,7 +1505,9 @@ object Build { ModuleInitializer.mainMethod( "org.scalajs.testsuite.compiler.ModuleInitializerInTestConfiguration", "main1") - } + }, + + testSuiteTestHtmlSetting ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( library, jUnitRuntime ) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 06a7911052..93c0190b35 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -127,11 +127,8 @@ object ScalaJSPlugin extends AutoPlugin { val fullOptJS = TaskKey[Attributed[File]]("fullOptJS", "Link all compiled JavaScript into a single file and fully optimize", APlusTask) - val testHtmlFastOpt = TaskKey[Attributed[File]]("testHtmlFastOpt", - "Create an HTML test runner for fastOptJS", AMinusTask) - - val testHtmlFullOpt = TaskKey[Attributed[File]]("testHtmlFullOpt", - "Create an HTML test runner for fullOptJS", AMinusTask) + val testHtml = TaskKey[Attributed[File]]("testHtml", + "Create an HTML test runner. Honors `scalaJSStage`.", AMinusTask) val scalaJSIR = TaskKey[Attributed[Seq[VirtualScalaJSIRFile with RelativeVirtualFile]]]( "scalaJSIR", "All the *.sjsir files on the classpath", CTask) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index f0d93e7736..222c95b9e6 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -571,77 +571,47 @@ object ScalaJSPluginInternal { } ) - private def scalaJSTestHtmlTaskSettings( - testHtmlKey: TaskKey[Attributed[File]], - sjsFileKey: TaskKey[Attributed[File]]) = { - Def.settings( - jsExecutionFiles in testHtmlKey := { - /* Forcefully choose the appropriate Scala.js-generated .js file - * (fastOptJS or fullOptJS). The way we do this is absolutely hacky. - * We find in `inherited` the `VirtualFile` that corresponds to - * `scalaJSLinkedFile.value` (which depends on `scalaJSStage`) and - * replace it with `sjsFileKey` (which does not). Since tasks are - * only evaluated once per command run, we know that - * `scalaJSLinkedFile.value` returns the exact same file (as in `eq`) - * which we will find in `inherited`, hence we can reliably recognize - * the proper and replace it. If we do not find it, we do not touch - * anything. - */ - val inherited = jsExecutionFiles.value - val stageDependentSJSFile = scalaJSLinkedFile.value - val replacementSJSFile = (scalaJSLinkedFile in sjsFileKey).value - for (file <- inherited) yield { - if (file eq stageDependentSJSFile) - replacementSJSFile - else - file - } - }, + val scalaJSTestHtmlSettings = Seq( + artifactPath in testHtml := { + val stageSuffix = scalaJSStage.value match { + case Stage.FastOpt => "fastopt" + case Stage.FullOpt => "opt" + } + ((crossTarget in testHtml).value / + ((moduleName in testHtml).value + s"-$stageSuffix-test.html")) + }, - testHtmlKey := { - val log = streams.value.log - val output = (artifactPath in testHtmlKey).value + testHtml := { + val log = streams.value.log + val output = (artifactPath in testHtml).value - val jsFileCache = new VirtualFileMaterializer(true) - val jsFileURIs = (jsExecutionFiles in testHtmlKey).value.map { - case file: FileVirtualFile => file.toURI - case file => jsFileCache.materialize(file).toURI - } + val jsFileCache = new VirtualFileMaterializer(true) + val jsFileURIs = (jsExecutionFiles in testHtml).value.map { + case file: FileVirtualFile => file.toURI + case file => jsFileCache.materialize(file).toURI + } - val css: java.io.File = { - val name = "test-runner.css" - val inputStream = getClass.getResourceAsStream(name) - try { - val outFile = (resourceManaged in testHtmlKey).value / name - IO.transfer(inputStream, outFile) - outFile - } finally { - inputStream.close() - } + val css: java.io.File = { + val name = "test-runner.css" + val inputStream = getClass.getResourceAsStream(name) + try { + val outFile = (resourceManaged in testHtml).value / name + IO.transfer(inputStream, outFile) + outFile + } finally { + inputStream.close() } + } - IO.write(output, HTMLRunnerTemplate.render(output.toURI, - name.value + " - tests", jsFileURIs, css.toURI, - (loadedTestFrameworks in testHtmlKey).value, - (definedTests in testHtmlKey).value)) - - log.info(s"Wrote HTML test runner. Point your browser to ${output.toURI}") + IO.write(output, HTMLRunnerTemplate.render(output.toURI, + name.value + " - tests", jsFileURIs, css.toURI, + (loadedTestFrameworks in testHtml).value, + (definedTests in testHtml).value)) - Attributed.blank(output) - } - ) - } + log.info(s"Wrote HTML test runner. Point your browser to ${output.toURI}") - val scalaJSTestHtmlSettings = Seq( - artifactPath in testHtmlFastOpt := - ((crossTarget in testHtmlFastOpt).value / - ((moduleName in testHtmlFastOpt).value + "-fastopt-test.html")), - artifactPath in testHtmlFullOpt := - ((crossTarget in testHtmlFullOpt).value / - ((moduleName in testHtmlFullOpt).value + "-opt-test.html")) - ) ++ ( - scalaJSTestHtmlTaskSettings(testHtmlFastOpt, fastOptJS) ++ - scalaJSTestHtmlTaskSettings(testHtmlFullOpt, fullOptJS) + Attributed.blank(output) + } ) val scalaJSTestSettings = ( From 481dfb59ae4d5e2a1be10db00700fc874f5bd2ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 13 Jun 2017 15:01:06 +0200 Subject: [PATCH 0336/2665] Give some discipline to fetching the `.value`s in `{fast,full}OptJS. We now make it very explicit that all `.value`s performed by `{fast,full}OptJS` are within the `Def.taskDyn { ... }`, rather than within the anonymous `Def.task { ... }` inside. This is very important for `inspect tree` to be meaningful. Previously we were accessing `(scalaJSLinker in key).value` from the inner task, and it would not show up in `inspect tree`. --- .../sbtplugin/ScalaJSPluginInternal.scala | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 8ba38285ac..5e1a44d484 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -236,15 +236,26 @@ object ScalaJSPluginInternal { Tags.limit((usesScalaJSLinkerTag in key).value, 1), key := Def.taskDyn { - val s = (streams in key).value - val log = s.log + /* It is very important that we evaluate all of those `.value`s from + * here, and not from within the `Def.task { ... }`, otherwise the + * relevant dependencies will not show up in `inspect tree`. We use a + * `Def.taskDyn` only to be able to tag the inner task with a tag that + * is setting-dependent. But otherwise, the task does not have actually + * dynamic dependencies, so `inspect tree` is happy with it. + */ + val s = streams.value val irInfo = (scalaJSIR in key).value - val realFiles = irInfo.get(scalaJSSourceFiles).get - val ir = irInfo.data val moduleInitializers = scalaJSModuleInitializers.value val output = (artifactPath in key).value + val linker = (scalaJSLinker in key).value + val usesLinkerTag = (usesScalaJSLinkerTag in key).value Def.task { + val log = s.log + val realFiles = irInfo.get(scalaJSSourceFiles).get + val ir = irInfo.data + log.warn(s.cacheDirectory.toString) + FileFunction.cached(s.cacheDirectory, FilesInfo.lastModified, FilesInfo.exists) { _ => // We don't need the files @@ -257,7 +268,6 @@ object ScalaJSPluginInternal { IO.createDirectory(output.getParentFile) - val linker = (scalaJSLinker in key).value linker.link(ir, moduleInitializers, AtomicWritableFileVirtualJSFile(output), sbtLogger2ToolsLogger(log)) @@ -269,7 +279,7 @@ object ScalaJSPluginInternal { 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, From e055b83ea4b68627172ee0d05b2086d70317d0a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 13 Jun 2017 15:03:52 +0200 Subject: [PATCH 0337/2665] Replace `Def.taskDyn` by `Def.settingDyn` where possible. Regardless of whether the *result* key is a setting key or a task key, it is possible to use `Def.settingDyn` as long as the dynamic part (the part that decides what `Initialize` to return) only depends on settings. That's because a `TaskKey[T]` is nothing more than a `SettingKey[Task[T]]`, so the type parameter of `settingDyn` can be instantiated to `Task[T]` without any problem. Assuming https://github.com/sbt/sbt/issues/3258 is eventually implemented, using `Def.settingDyn` will provide a better sbt experience in `inspect tree`. Not all `taskDyn`s are removed, but the only remaining ones are either * `{fast,full}OptJS`, which do not actually have any dynamic dependency, so they already show up nicely in `inspect tree`, or * things related to the launcher generation, which will not survive in Scala.js 1.x. --- .../scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 5e1a44d484..425216e336 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -295,7 +295,7 @@ object ScalaJSPluginInternal { ) private def dispatchTaskKeySettings[T](key: TaskKey[T]) = Seq( - key := Def.taskDyn { + key := Def.settingDyn { val stageKey = stageKeys(scalaJSStage.value) Def.task { (key in stageKey).value } }.value @@ -694,7 +694,7 @@ object ScalaJSPluginInternal { } }.value, - scalaJSModuleIdentifier := Def.taskDyn[Option[String]] { + scalaJSModuleIdentifier := Def.settingDyn[Task[Option[String]]] { scalaJSModuleKind.value match { case ModuleKind.NoModule => Def.task { @@ -821,7 +821,7 @@ object ScalaJSPluginInternal { }, mainClass in scalaJSLauncherInternal := (mainClass in run).value, - scalaJSLauncherInternal := Def.taskDyn[Attributed[VirtualJSFile]] { + scalaJSLauncherInternal := Def.settingDyn[Task[Attributed[VirtualJSFile]]] { if (persistLauncherInternal.value) { Def.task { packageScalaJSLauncherInternal.value.map(FileVirtualJSFile) From 56ff843cdbc62e18d62fb843f6dc0085b0ea928f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 13 Jun 2017 23:40:04 +0200 Subject: [PATCH 0338/2665] Define `js.UndefOr[A]` as a mere alias to `A | Unit`. This will give a much better status to `js.UndefOr` in a compiler that supports true union types (understand, Dotty). --- .../scalajs/core/compiler/JSDefinitions.scala | 1 - .../scalajs/core/compiler/PrepJSInterop.scala | 2 +- javalib/src/main/scala/java/net/URI.scala | 2 +- .../js/{UndefOr.scala => UndefOrOps.scala} | 35 ------------------- .../main/scala/scala/scalajs/js/Union.scala | 18 +++++++--- .../main/scala/scala/scalajs/js/package.scala | 18 ++++++++++ project/Build.scala | 15 ++++++++ .../testsuite/jsinterop/UndefOrTest.scala | 8 +++-- .../jsinterop/UndefOrTestRequire211.scala | 31 ++++++++++++++++ 9 files changed, 85 insertions(+), 45 deletions(-) rename library/src/main/scala/scala/scalajs/js/{UndefOr.scala => UndefOrOps.scala} (88%) create mode 100644 test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTestRequire211.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 90a50b3d1b..5ea5c39b3b 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -36,7 +36,6 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val JSObjectClass = getRequiredClass("scala.scalajs.js.Object") lazy val JSThisFunctionClass = getRequiredClass("scala.scalajs.js.ThisFunction") - lazy val UndefOrClass = getRequiredClass("scala.scalajs.js.UndefOr") lazy val UnionClass = getRequiredClass("scala.scalajs.js.$bar") lazy val JSArrayClass = getRequiredClass("scala.scalajs.js.Array") diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 7e8748c8a9..675d1e6ce5 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -194,7 +194,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent checkJSAnySpecificAnnotsOnNonJSAny(cldef) - if (sym == UndefOrClass || sym == UnionClass) + if (sym == UnionClass) sym.addAnnotation(RawJSTypeAnnot) if (shouldPrepareExports) diff --git a/javalib/src/main/scala/java/net/URI.scala b/javalib/src/main/scala/java/net/URI.scala index ba72411f22..3ba6a7259d 100644 --- a/javalib/src/main/scala/java/net/URI.scala +++ b/javalib/src/main/scala/java/net/URI.scala @@ -49,7 +49,7 @@ final class URI(origStr: String) extends Serializable with Comparable[URI] { private val _path = { val useNetPath = fld(AbsAuthority, RelAuthority).isDefined if (useNetPath) - fld(AbsNetPath, RelNetPath) orElse "" + fld(AbsNetPath, RelNetPath) orElse ("": js.UndefOr[String]) // 2.10 wants the type ascription else if (_isAbsolute) fld(AbsAbsPath) else diff --git a/library/src/main/scala/scala/scalajs/js/UndefOr.scala b/library/src/main/scala/scala/scalajs/js/UndefOrOps.scala similarity index 88% rename from library/src/main/scala/scala/scalajs/js/UndefOr.scala rename to library/src/main/scala/scala/scalajs/js/UndefOrOps.scala index 4a3add8c64..96d050b133 100644 --- a/library/src/main/scala/scala/scalajs/js/UndefOr.scala +++ b/library/src/main/scala/scala/scalajs/js/UndefOrOps.scala @@ -14,41 +14,6 @@ import scala.language.implicitConversions import scala.scalajs.js import scala.scalajs.js.|.Evidence -/** Value of type A or the JS undefined value. - * - * `js.UndefOr[A]` is the type of a value that can be either `undefined` or - * an `A`. It provides an API similar to that of [[scala.Option]] through the - * [[UndefOrOps]] implicit class, where `undefined` take the role of [[None]]. - * - * By extension, this type is also suited to typing optional fields in native - * JS types, i.e., fields that may not exist on the object. - */ -sealed trait UndefOr[+A] - -sealed abstract class UndefOrLowPrioImplicits { this: js.UndefOr.type => - /** Upcast `A` to `UndefOr[B1 | B2]`. - * - * This needs evidence that `A <: B1 | B2`. - */ - implicit def any2undefOrUnion[A, B1, B2](a: A)( - implicit ev: Evidence[A, B1 | B2]): js.UndefOr[B1 | B2] = { - a.asInstanceOf[js.UndefOr[B1 | B2]] - } -} - -object UndefOr extends js.UndefOrLowPrioImplicits { - implicit def any2undefOrA[A](value: A): js.UndefOr[A] = - value.asInstanceOf[js.UndefOr[A]] - - implicit def undefOr2ops[A](value: js.UndefOr[A]): js.UndefOrOps[A] = - new js.UndefOrOps(value) - - implicit def undefOr2jsAny[A](value: js.UndefOr[A])( - implicit ev: A => js.Any): js.Any = { - value.map(ev).asInstanceOf[js.Any] - } -} - /** @define option [[js.UndefOr]] * @define none [[js.undefined]] */ diff --git a/library/src/main/scala/scala/scalajs/js/Union.scala b/library/src/main/scala/scala/scalajs/js/Union.scala index 61c96d0bfe..9acb1db808 100644 --- a/library/src/main/scala/scala/scalajs/js/Union.scala +++ b/library/src/main/scala/scala/scalajs/js/Union.scala @@ -60,10 +60,6 @@ object | { // scalastyle:ignore /** If `A <: B1`, then `A <: B1 | B2`. */ implicit def left[A, B1, B2](implicit ev: Evidence[A, B1]): Evidence[A, B1 | B2] = ReusableEvidence.asInstanceOf[Evidence[A, B1 | B2]] - - /** If `A <: B`, then `A <: js.UndefOr[B]`. */ - implicit def undefOr[A, B](implicit ev: Evidence[A, B]): Evidence[A, js.UndefOr[B]] = - ReusableEvidence.asInstanceOf[Evidence[A, js.UndefOr[B]]] } object Evidence extends EvidenceLowPrioImplicits { @@ -102,4 +98,18 @@ object | { // scalastyle:ignore def merge[B](implicit ev: |.Evidence[A, B]): B = self.asInstanceOf[B] } + + /** Provides an [[Option]]-like API to [[js.UndefOr]]. */ + implicit def undefOr2ops[A](value: js.UndefOr[A]): js.UndefOrOps[A] = + new js.UndefOrOps(value) + + /* This one is not very "in the spirit" of the union type, but it used to be + * available for `js.UndefOr[A]`, so we keep it for backward source + * compatibility. It is not really harmful, and has some perks in certain + * interoperability scenarios. + */ + implicit def undefOr2jsAny[A](value: js.UndefOr[A])( + implicit ev: A => js.Any): js.Any = { + value.map(ev).asInstanceOf[js.Any] + } } diff --git a/library/src/main/scala/scala/scalajs/js/package.scala b/library/src/main/scala/scala/scalajs/js/package.scala index 67b577efb3..ad3a639eb5 100644 --- a/library/src/main/scala/scala/scalajs/js/package.scala +++ b/library/src/main/scala/scala/scalajs/js/package.scala @@ -10,6 +10,8 @@ package scala.scalajs +import scala.annotation.unchecked.uncheckedVariance + // Can't link to Null - #1969 /** Types, methods and values for interoperability with JavaScript libraries. * @@ -63,6 +65,22 @@ package scala.scalajs * admit several unrelated types in facade types. */ package object js { + + /** Value of type A or the JS undefined value. + * + * This type is actually strictly equivalent to `A | Unit`, since `Unit` is + * the type of the `undefined` value. + * + * `js.UndefOr[A]` is the type of a value that can be either `undefined` or + * an `A`. It provides an API similar to that of [[scala.Option]] through + * the [[UndefOrOps]] implicit class, where `undefined` take the role of + * [[None]]. + * + * By extension, this type is also suited to typing optional fields in + * native JS types, i.e., fields that may not exist on the object. + */ + type UndefOr[+A] = (A @uncheckedVariance) | Unit + /** The undefined value. */ @inline def undefined: js.UndefOr[Nothing] = ().asInstanceOf[js.UndefOr[Nothing]] diff --git a/project/Build.scala b/project/Build.scala index e06dd363d4..1cf60ddbeb 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1497,6 +1497,21 @@ object Build { Seq(outFile) }.taskValue, + // Exclude tests based on version-dependent limitations + sources in Test := { + val sourceFiles = (sources in Test).value + val v = scalaVersion.value + + val sourceFiles1 = { + if (v.startsWith("2.10.")) + sourceFiles.filterNot(_.getName.endsWith("Require211.scala")) + else + sourceFiles + } + + sourceFiles1 + }, + // Module initializers. Duplicated in toolsJS/test scalaJSModuleInitializers += { ModuleInitializer.mainMethod( diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTest.scala index 12c8b2d1d9..a07db54556 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTest.scala @@ -171,9 +171,11 @@ class UndefOrTest { assertEquals("yes", none orElse some("yes")) assertJSUndefined(none orElse none) - // #2095 - assertEquals("ok", some("ok") orElse "yes") - assertEquals("yes", none orElse "yes") + /* #2095 + * Scala 2.10 requires the type ascriptions (see also UndefOrTestRequire211) + */ + assertEquals("ok", some("ok") orElse ("yes": js.UndefOr[String])) + assertEquals("yes", none orElse ("yes": js.UndefOr[String])) } @Test def toList(): Unit = { diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTestRequire211.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTestRequire211.scala new file mode 100644 index 0000000000..94d33c6907 --- /dev/null +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTestRequire211.scala @@ -0,0 +1,31 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.jsinterop + +import scala.scalajs.js + +import org.junit.Assert._ +import org.junit.Test + +import org.scalajs.testsuite.utils.AssertThrows._ +import org.scalajs.testsuite.utils.JSAssert._ + +class UndefOrTestRequire211 { + + def some[A](v: A): js.UndefOr[A] = v + def none[A]: js.UndefOr[A] = js.undefined + + // scala.scalajs.js.UndefOr[A] + + @Test def orElse(): Unit = { + // #2095 + assertEquals("ok", some("ok") orElse "yes") + assertEquals("yes", none orElse "yes") + } + +} From a3ff8dbf2d637290d90d8661319546d58acd4898 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 9 Jun 2017 00:04:00 +0200 Subject: [PATCH 0339/2665] Introduce the surface of the new linker API. This commit introduces the portion of the new linker API described in #2998 that is targeted for the 0.6.x series. It contains: * `linker.StandardLinker._` * `linker.Semantics` * `linker.ModuleKind` * `linker.standard.OutputMode` * `linker.standard.StandardLinkerConfigStandardOps` This is enough to implement the CLI, the sbt plugin, the `QuickLinker` and partest's `MainGenericRunner` entirely in terms of the new API. We deprecate `Linker.apply` in favor of `StandardLinker.apply` in order to nudge other users of the linker towards the new API, assuming they use that "easy" entry point (instead of manually manipulating front-end and back-end). --- .../scala/org/scalajs/cli/Scalajsld.scala | 29 +- .../scala/tools/nsc/MainGenericRunner.scala | 11 +- project/BinaryIncompatibilities.scala | 4 + .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 4 +- .../sbtplugin/ScalaJSPluginInternal.scala | 31 +-- .../linker/LinkerPlatformExtensions.scala | 11 +- .../StandardLinkerPlatformExtensions.scala | 22 ++ .../core/tools/test/js/QuickLinker.scala | 8 +- .../linker/LinkerPlatformExtensions.scala | 11 +- .../StandardLinkerPlatformExtensions.scala | 21 ++ .../core/tools/linker/ClearableLinker.scala | 1 - .../scalajs/core/tools/linker/GenLinker.scala | 1 - .../scalajs/core/tools/linker/Linker.scala | 1 - .../core/tools/linker/LinkingUnit.scala | 1 - .../core/tools/linker/StandardLinker.scala | 248 ++++++++++++++++++ .../linker/backend/emitter/ClassEmitter.scala | 5 +- .../linker/backend/emitter/Emitter.scala | 1 - .../scalajs/core/tools/linker/package.scala | 26 ++ .../core/tools/linker/standard/package.scala | 28 ++ .../core/tools/linker/LinkerTest.scala | 6 +- 20 files changed, 401 insertions(+), 69 deletions(-) create mode 100644 tools/js/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala create mode 100644 tools/jvm/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala create mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/linker/StandardLinker.scala create mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/linker/package.scala create mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/package.scala diff --git a/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala b/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala index f1c0374882..3814a0a60a 100644 --- a/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala +++ b/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala @@ -11,15 +11,13 @@ package org.scalajs.cli import org.scalajs.core.ir.ScalaJSVersions -import org.scalajs.core.tools.sem._ import org.scalajs.core.tools.io._ import org.scalajs.core.tools.logging._ -import CheckedBehavior.Compliant +import org.scalajs.core.tools.linker._ +import org.scalajs.core.tools.linker.standard._ -import org.scalajs.core.tools.linker.{ModuleInitializer, Linker} -import org.scalajs.core.tools.linker.frontend.LinkerFrontend -import org.scalajs.core.tools.linker.backend.{LinkerBackend, OutputMode, ModuleKind} +import CheckedBehavior.Compliant import scala.collection.immutable.Seq @@ -188,25 +186,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) + val linker = StandardLinker(config) val logger = new ScalaConsoleLogger(options.logLevel) val outFile = WritableFileVirtualJSFile(options.output) val cache = (new IRFileCache).newCache diff --git a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala index 9212a394b6..c389cbcb27 100644 --- a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala +++ b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala @@ -2,13 +2,10 @@ package scala.tools.nsc /* 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.jsdep.ResolvedJSDependency import org.scalajs.core.tools.io.IRFileCache.IRContainer -import org.scalajs.core.tools.linker.{Linker, ModuleInitializer} -import org.scalajs.core.tools.linker.backend.{OutputMode, ModuleKind} +import org.scalajs.core.tools.linker._ import org.scalajs.core.ir @@ -66,12 +63,12 @@ class MainGenericRunner { val moduleInitializers = Seq(ModuleInitializer.mainMethodWithArgs( command.thingToRun, "main", command.arguments)) - val linkerConfig = Linker.Config() + val linkerConfig = StandardLinker.Config() + .withSemantics(semantics) .withSourceMap(false) .withClosureCompiler(optMode == FullOpt) - val linker = Linker(semantics, OutputMode.ECMAScript51Isolated, - ModuleKind.NoModule, linkerConfig) + val linker = StandardLinker(linkerConfig) val sjsCode = { val output = WritableMemVirtualJSFile("partest.js") diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 36dca7dc7a..e23de09213 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -6,6 +6,10 @@ object BinaryIncompatibilities { ) val Tools = Seq( + // New method in a trait sealed via self-type, not an issue + ProblemFilters.exclude[ReversedMissingMethodProblem]( + "org.scalajs.core.tools.linker.LinkerPlatformExtensions.applyInternal"), + // private[emitter], not an issue ProblemFilters.exclude[DirectMissingMethodProblem]( "org.scalajs.core.tools.linker.backend.emitter.FunctionEmitter#JSDesugar.genClassDataOf") diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 433c980774..fdedd346af 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -13,8 +13,8 @@ import sbt._ 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 diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 90d67a53c9..65b0db1842 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -16,9 +16,8 @@ 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.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 @@ -195,28 +194,22 @@ object ScalaJSPluginInternal { None } - val frontendConfig = LinkerFrontend.Config() + val config = StandardLinker.Config() + .withSemantics(semantics) + .withModuleKind(moduleKind) + .withOutputMode(outputMode) .withBypassLinkingErrorsInternal(opts.bypassLinkingErrors) .withCheckIR(opts.checkScalaJSIR) - - val backendConfig = LinkerBackend.Config() - .withRelativizeSourceMapBase(relSourceMapBase) - .withCustomOutputWrapperInternal(scalaJSOutputWrapperInternal.value) - .withPrettyPrint(opts.prettyPrintFullOptJS) - - val config = Linker.Config() - .withSourceMap(withSourceMap) .withOptimizer(!opts.disableOptimizer) .withParallel(opts.parallel) + .withSourceMap(withSourceMap) + .withRelativizeSourceMapBase(relSourceMapBase) .withClosureCompiler(opts.useClosureCompiler) - .withFrontendConfig(frontendConfig) - .withBackendConfig(backendConfig) - - val newLinker = { () => - Linker(semantics, outputMode, moduleKind, config) - } + .withCustomOutputWrapperInternal(scalaJSOutputWrapperInternal.value) + .withPrettyPrint(opts.prettyPrintFullOptJS) + .withBatchMode(opts.batchMode) - new ClearableLinker(newLinker, opts.batchMode) + new ClearableLinker(() => StandardLinker(config), config.batchMode) }, usesScalaJSLinkerTag in key := { diff --git a/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala b/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala index cb96d12d90..8a32965242 100644 --- a/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala +++ b/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala @@ -9,15 +9,20 @@ package org.scalajs.core.tools.linker -import org.scalajs.core.tools.sem.Semantics - import org.scalajs.core.tools.linker.frontend.LinkerFrontend import org.scalajs.core.tools.linker.frontend.optimizer.IncOptimizer import org.scalajs.core.tools.linker.backend._ trait LinkerPlatformExtensions { this: Linker.type => + @deprecated("Use StandardLinker.apply() instead.", "0.6.18") def apply(semantics: Semantics, outputMode: OutputMode, moduleKind: ModuleKind, config: Config): Linker = { + applyInternal(semantics, outputMode, moduleKind, config) + } + + private[linker] def applyInternal(semantics: Semantics, + outputMode: OutputMode, moduleKind: ModuleKind, + config: Config): Linker = { val optOptimizerFactory = { if (!config.optimizer) None @@ -33,7 +38,7 @@ trait LinkerPlatformExtensions { this: Linker.type => new Linker(frontend, backend) } - @deprecated("Use the overload with a Config object.", "0.6.13") + @deprecated("Use StandardLinker.apply() instead.", "0.6.13") def apply( semantics: Semantics = Semantics.Defaults, outputMode: OutputMode = OutputMode.Default, diff --git a/tools/js/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala b/tools/js/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala new file mode 100644 index 0000000000..af3e689ef7 --- /dev/null +++ b/tools/js/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala @@ -0,0 +1,22 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.core.tools.linker + +object StandardLinkerPlatformExtensions { + import StandardLinker.Config + + final class ConfigExt(val config: Config) extends AnyVal { + /** Whether to actually use the Google Closure Compiler pass. + * + * On the JavaScript platform, this always returns `false`, as GCC is not + * available. + */ + def closureCompiler: Boolean = false + } +} diff --git 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 index a071d2bf0c..4cf5285849 100644 --- 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,10 +1,8 @@ package org.scalajs.core.tools.test.js -import org.scalajs.core.tools.sem.Semantics import org.scalajs.core.tools.io._ import org.scalajs.core.tools.io.IRFileCache.IRContainer -import org.scalajs.core.tools.linker.{ModuleInitializer, Linker} -import org.scalajs.core.tools.linker.backend.{OutputMode, ModuleKind} +import org.scalajs.core.tools.linker._ import org.scalajs.core.tools.logging._ import scala.scalajs.js @@ -38,8 +36,8 @@ object QuickLinker { irFilesAndJars: Seq[String], moduleInitializers: Seq[String]): String = { val cache = (new IRFileCache).newCache - val linker = Linker(semantics, OutputMode.ECMAScript51Isolated, - ModuleKind.NoModule, Linker.Config()) + val linker = + StandardLinker(StandardLinker.Config().withSemantics(semantics)) val irContainers = irFilesAndJars.map { file => if (file.endsWith(".jar")) { diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala index def532f099..b15f7ad351 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala @@ -9,16 +9,21 @@ package org.scalajs.core.tools.linker -import org.scalajs.core.tools.sem.Semantics - import org.scalajs.core.tools.linker.frontend.LinkerFrontend import org.scalajs.core.tools.linker.frontend.optimizer.{ParIncOptimizer, IncOptimizer} import org.scalajs.core.tools.linker.backend._ import org.scalajs.core.tools.linker.backend.closure.ClosureLinkerBackend trait LinkerPlatformExtensions { this: Linker.type => + @deprecated("Use StandardLinker.apply() instead.", "0.6.18") def apply(semantics: Semantics, outputMode: OutputMode, moduleKind: ModuleKind, config: Config): Linker = { + applyInternal(semantics, outputMode, moduleKind, config) + } + + private[linker] def applyInternal(semantics: Semantics, + outputMode: OutputMode, moduleKind: ModuleKind, + config: Config): Linker = { val optOptimizerFactory = { if (!config.optimizer) None @@ -44,7 +49,7 @@ trait LinkerPlatformExtensions { this: Linker.type => new Linker(frontend, backend) } - @deprecated("Use the overload with a Config object.", "0.6.13") + @deprecated("Use StandardLinker.apply() instead.", "0.6.13") def apply( semantics: Semantics = Semantics.Defaults, outputMode: OutputMode = OutputMode.Default, diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala new file mode 100644 index 0000000000..58c6befd4b --- /dev/null +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala @@ -0,0 +1,21 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.core.tools.linker + +object StandardLinkerPlatformExtensions { + import StandardLinker.Config + + final class ConfigExt(val config: Config) extends AnyVal { + /** Whether to actually use the Google Closure Compiler pass. */ + def closureCompiler: Boolean = config.closureCompilerIfAvailable + + def withClosureCompiler(closureCompiler: Boolean): Config = + config.withClosureCompilerIfAvailable(closureCompiler) + } +} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ClearableLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ClearableLinker.scala index 9fb20ce618..b5592f8207 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ClearableLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ClearableLinker.scala @@ -12,7 +12,6 @@ package org.scalajs.core.tools.linker import org.scalajs.core.tools.logging.Logger import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.sem.Semantics import org.scalajs.core.tools.javascript.ESLevel import org.scalajs.core.tools.linker.analyzer.SymbolRequirement diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala index f9c0aa651c..5564e56c07 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala @@ -12,7 +12,6 @@ package org.scalajs.core.tools.linker import org.scalajs.core.tools.logging.Logger import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.sem.Semantics import org.scalajs.core.tools.javascript.ESLevel import org.scalajs.core.tools.linker.analyzer.SymbolRequirement diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala index b4d8f33873..6aa9921f16 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala @@ -16,7 +16,6 @@ import java.util.concurrent.atomic.AtomicBoolean import org.scalajs.core.tools.logging.Logger import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.sem.Semantics import org.scalajs.core.tools.javascript.ESLevel import org.scalajs.core.tools.linker.analyzer.SymbolRequirement import org.scalajs.core.tools.linker.frontend.LinkerFrontend diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala index 6b8150b197..2aedf0611c 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala @@ -1,6 +1,5 @@ package org.scalajs.core.tools.linker -import org.scalajs.core.tools.sem.Semantics import org.scalajs.core.tools.javascript.ESLevel import org.scalajs.core.ir 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 new file mode 100644 index 0000000000..8c9f68e24e --- /dev/null +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/StandardLinker.scala @@ -0,0 +1,248 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.core.tools.linker + +import scala.language.implicitConversions + +import java.net.URI + +import org.scalajs.core.tools.linker.frontend.LinkerFrontend +import org.scalajs.core.tools.linker.backend.{LinkerBackend, OutputMode} + +object StandardLinker { + import StandardLinkerPlatformExtensions._ + + def apply(config: Config): Linker = { + val frontendConfig = LinkerFrontend.Config() + .withBypassLinkingErrorsInternal(config.bypassLinkingErrors) + .withCheckIR(config.checkIR) + + val backendConfig = LinkerBackend.Config() + .withRelativizeSourceMapBase(config.relativizeSourceMapBase) + .withCustomOutputWrapperInternal(config.customOutputWrapper) + .withPrettyPrint(config.prettyPrint) + + val oldAPIConfig = Linker.Config() + .withSourceMap(config.sourceMap) + .withOptimizer(config.optimizer) + .withParallel(config.parallel) + .withClosureCompilerIfAvailable(config.closureCompilerIfAvailable) + .withFrontendConfig(frontendConfig) + .withBackendConfig(backendConfig) + + Linker.applyInternal(config.semantics, config.outputMode, config.moduleKind, + oldAPIConfig) + } + + implicit def configExt(config: Config): ConfigExt = + new ConfigExt(config) + + /** Configuration of a standard linker. */ + final class Config private ( + /** Scala.js semantics. */ + 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. */ + val optimizer: Boolean, + /** Whether things that can be parallelized should be parallelized. + * On the JavaScript platform, this does not have any effect. + */ + val parallel: Boolean, + /** Whether to emit a source map. */ + val sourceMap: Boolean, + /** Base path to relativize paths in the source map. */ + val relativizeSourceMapBase: Option[URI], + /** Custom js code that wraps the output */ + val customOutputWrapper: (String, String), + /** Whether to use the Google Closure Compiler pass, if it is available. + * On the JavaScript platform, this does not have any effect. + */ + val closureCompilerIfAvailable: Boolean, + /** Pretty-print the output. */ + val prettyPrint: Boolean, + /** Whether the linker should run in batch mode. + * + * In batch mode, the linker can throw away intermediate state that is + * otherwise maintained for incremental runs. + * + * This setting is only a hint. A linker and/or its subcomponents may + * ignore it. This applies in both directions: a linker not supporting + * incrementality can ignore `batchMode = false`, and a contrario, a + * linker mainly designed for incremental runs may ignore + * `batchMode = true`. + */ + val batchMode: Boolean, + /** Standard output mode. */ + private[linker] val outputMode: OutputMode + ) { + private def this() = { + this( + semantics = Semantics.Defaults, + moduleKind = ModuleKind.NoModule, + bypassLinkingErrors = false, + checkIR = false, + optimizer = true, + parallel = true, + sourceMap = true, + relativizeSourceMapBase = None, + customOutputWrapper = ("", ""), + closureCompilerIfAvailable = false, + prettyPrint = false, + batchMode = false, + outputMode = OutputMode.Default + ) + } + + def withSemantics(semantics: Semantics): Config = + copy(semantics = semantics) + + def withSemantics(f: Semantics => Semantics): Config = + copy(semantics = f(semantics)) + + 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) + + def withOptimizer(optimizer: Boolean): Config = + copy(optimizer = optimizer) + + def withParallel(parallel: Boolean): Config = + copy(parallel = parallel) + + def withSourceMap(sourceMap: Boolean): Config = + copy(sourceMap = sourceMap) + + def withRelativizeSourceMapBase(relativizeSourceMapBase: Option[URI]): Config = + copy(relativizeSourceMapBase = relativizeSourceMapBase) + + @deprecated( + "The functionality of custom output wrappers has been superseded " + + "by the support for CommonJS modules, module initializers, and " + + "top-level exports.", + "0.6.15") + def withCustomOutputWrapper(customOutputWrapper: (String, String)): Config = + copy(customOutputWrapper = customOutputWrapper) + + // Non-deprecated version to call from the sbt plugin + private[scalajs] def withCustomOutputWrapperInternal( + customOutputWrapper: (String, String)): Config = { + copy(customOutputWrapper = customOutputWrapper) + } + + def withClosureCompilerIfAvailable(closureCompilerIfAvailable: Boolean): Config = + copy(closureCompilerIfAvailable = closureCompilerIfAvailable) + + def withPrettyPrint(prettyPrint: Boolean): Config = + copy(prettyPrint = prettyPrint) + + def withBatchMode(batchMode: Boolean): Config = + copy(batchMode = batchMode) + + private[linker] def withOutputMode(outputMode: OutputMode): Config = + copy(outputMode = outputMode) + + override def toString(): String = { + s"""StandardLinker.Config( + | semantics = $semantics, + | moduleKind = $moduleKind, + | bypassLinkingErrors = $bypassLinkingErrors, + | checkIR = $checkIR, + | optimizer = $optimizer, + | parallel = $parallel, + | sourceMap = $sourceMap, + | relativizeSourceMapBase = $relativizeSourceMapBase, + | customOutputWrapper = $customOutputWrapper, + | closureCompilerIfAvailable = $closureCompilerIfAvailable, + | prettyPrint = $prettyPrint, + | batchMode = $batchMode, + | outputMode = $outputMode, + |)""".stripMargin + } + + private def copy( + semantics: Semantics = semantics, + moduleKind: ModuleKind = moduleKind, + bypassLinkingErrors: Boolean = bypassLinkingErrors, + checkIR: Boolean = checkIR, + optimizer: Boolean = optimizer, + parallel: Boolean = parallel, + sourceMap: Boolean = sourceMap, + relativizeSourceMapBase: Option[URI] = relativizeSourceMapBase, + customOutputWrapper: (String, String) = customOutputWrapper, + closureCompilerIfAvailable: Boolean = closureCompilerIfAvailable, + prettyPrint: Boolean = prettyPrint, + batchMode: Boolean = batchMode, + outputMode: OutputMode = outputMode + ): Config = { + new Config( + semantics, + moduleKind, + bypassLinkingErrors, + checkIR, + optimizer, + parallel, + sourceMap, + relativizeSourceMapBase, + customOutputWrapper, + closureCompilerIfAvailable, + prettyPrint, + batchMode, + outputMode + ) + } + } + + object Config { + /** Returns the default configuration for a [[StandardLinker]]. + * + * The defaults are: + * + * - `semantics`: [[org.scalajs.core.tools.sem.Semantics.Defaults Semantics.Defaults]] + * - `moduleKind`: [[ModuleKind.NoModule]] + * - `bypassLinkingErrors`: `false` (deprecated) + * - `checkIR`: `false` + * - `optimizer`: `true` + * - `parallel`: `true` + * - `sourceMap`: `true` + * - `relativizeSourceMapBase`: `None` + * - `customOutputWrapper`: `("", "")` (deprecated) + * - `closureCompilerIfAvailable`: `false` + * - `prettyPrint`: `false` + * - `batchMode`: `false` + * + * The following additional options are configurable through + * {{{ + * import org.scalajs.core.tools.linker.standard._ + * }}} + * + * - `outputMode`: [[org.scalajs.core.tools.linker.backend.OutputMode.Default OutputMode.Default]] + */ + def apply(): Config = new Config() + } + +} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index 314e15f460..4aa324a17b 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -15,13 +15,12 @@ import Transformers._ import org.scalajs.core.ir.Trees._ import Types._ -import org.scalajs.core.tools.sem._ -import CheckedBehavior.Unchecked - import org.scalajs.core.tools.javascript.{Trees => js} import org.scalajs.core.tools.linker._ import org.scalajs.core.tools.linker.backend.OutputMode +import CheckedBehavior.Unchecked + /** Emitter for the skeleton of classes. */ private[emitter] final class ClassEmitter(jsGen: JSGen) { diff --git 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 index a4f053dc32..30cab7a77b 100644 --- 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,7 +17,6 @@ import org.scalajs.core.ir.{ClassKind, Position} import org.scalajs.core.ir.Trees.JSNativeLoadSpec import org.scalajs.core.ir.Definitions.decodeClassName -import org.scalajs.core.tools.sem._ import org.scalajs.core.tools.logging._ import org.scalajs.core.tools.javascript.{Trees => js, _} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/package.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/package.scala new file mode 100644 index 0000000000..d23ef0c007 --- /dev/null +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/package.scala @@ -0,0 +1,26 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.core.tools + +package object linker { + type Semantics = org.scalajs.core.tools.sem.Semantics + + val Semantics: org.scalajs.core.tools.sem.Semantics.type = + org.scalajs.core.tools.sem.Semantics + + type CheckedBehavior = org.scalajs.core.tools.sem.CheckedBehavior + + val CheckedBehavior: org.scalajs.core.tools.sem.CheckedBehavior.type = + org.scalajs.core.tools.sem.CheckedBehavior + + type ModuleKind = org.scalajs.core.tools.linker.backend.ModuleKind + + val ModuleKind: org.scalajs.core.tools.linker.backend.ModuleKind.type = + org.scalajs.core.tools.linker.backend.ModuleKind +} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/package.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/package.scala new file mode 100644 index 0000000000..a880b1c5b8 --- /dev/null +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/package.scala @@ -0,0 +1,28 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.core.tools.linker + +package object standard { + type OutputMode = org.scalajs.core.tools.linker.backend.OutputMode + + val OutputMode: org.scalajs.core.tools.linker.backend.OutputMode.type = + org.scalajs.core.tools.linker.backend.OutputMode + + implicit class StandardLinkerConfigStandardOps( + val __self: StandardLinker.Config) extends AnyVal { + + import StandardLinker.Config + + /** Standard output mode. */ + def outputMode: OutputMode = __self.outputMode + + def withOutputMode(outputMode: OutputMode): Config = + __self.withOutputMode(outputMode) + } +} diff --git a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala index 8d9575d62a..f0b7e5af40 100644 --- a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala +++ b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala @@ -5,8 +5,7 @@ import org.junit.Assert._ import org.scalajs.core.tools.logging.NullLogger import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.sem.Semantics -import org.scalajs.core.tools.linker.backend.{OutputMode, ModuleKind} +import org.scalajs.core.tools.linker._ class LinkerTest { @@ -22,8 +21,7 @@ class LinkerTest { def length: Int = throw new DummyException() } - val linker = Linker(Semantics.Defaults, OutputMode.ECMAScript51Isolated, - ModuleKind.NoModule, Linker.Config()) + val linker = StandardLinker(StandardLinker.Config()) def callLink(): Unit = linker.link(badSeq, Nil, WritableMemVirtualJSFile("some_file"), NullLogger) From 587905436642bca8a3ff6f27730f8e56b722223d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 9 Jun 2017 13:25:32 +0200 Subject: [PATCH 0340/2665] Expose `StandardLinker.Config` as an sbt setting. This commit introduces the new sbt setting `scalaJSLinkerConfig`, which directly exposes the `StandardLinker.Config` used to create the `scalaJSLinker`. This setting replaces the bag of settings that we had before: * `scalaJSSemantics` * `scalaJSModuleKind` * `scalaJSOutputMode` * `emitSourceMaps` * `relativeSourceMaps` * `scalaJSOutputWrapper` * `scalaJSOptimizerOptions` For backward compatibility reasons, we must preserve the behavior of any sbt build that sets the old options, in any arbitrary ways and in any scopes. At the same time, we want the new sbt settings to be usable, at least in typical scenarios. We choose to support setting the new API in two places: * In the project scope, without any configuration or task axis * In the fully qualified scope, with all of project, configuration and task specified To achieve this, we derive the old config settings from the new config settings in the project scope, and derive back the new config settings from the old config settings in the fully qualified scope. --- .../scalajs/sbtplugin/OptimizerOptions.scala | 8 +- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 5 ++ .../sbtplugin/ScalaJSPluginInternal.scala | 88 ++++++++++++++++--- 3 files changed, 89 insertions(+), 12 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/OptimizerOptions.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/OptimizerOptions.scala index a6d60d3116..bfb32a161b 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/OptimizerOptions.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/OptimizerOptions.scala @@ -42,6 +42,12 @@ final class OptimizerOptions private ( def withBypassLinkingErrors(bypassLinkingErrors: Boolean): OptimizerOptions = copy(bypassLinkingErrors = bypassLinkingErrors) + // Non-deprecated version to call from the sbt plugin + private[sbtplugin] def withBypassLinkingErrorsInternal( + bypassLinkingErrors: Boolean): OptimizerOptions = { + copy(bypassLinkingErrors = bypassLinkingErrors) + } + def withParallel(parallel: Boolean): OptimizerOptions = copy(parallel = parallel) @@ -97,7 +103,7 @@ object OptimizerOptions { * which uses Scala 2.12. We should get rid of that workaround at that point * for tidiness, though. */ - private val DefaultParallel: Boolean = { + private[sbtplugin] val DefaultParallel: Boolean = { try { scala.util.Properties.isJavaAtLeast("1.8") true diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index fdedd346af..4ebc31a371 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -232,6 +232,11 @@ object ScalaJSPlugin extends AutoPlugin { "`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) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 65b0db1842..b242ca58e0 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -179,7 +179,8 @@ object ScalaJSPluginInternal { /** Settings for the production key (e.g. fastOptJS) of a given stage */ private def scalaJSStageSettings(stage: Stage, key: TaskKey[Attributed[File]]): Seq[Setting[_]] = Seq( - scalaJSLinker in key := { + + scalaJSLinkerConfig in key := { val opts = (scalaJSOptimizerOptions in key).value val semantics = (scalaJSSemantics in key).value @@ -187,14 +188,21 @@ object ScalaJSPluginInternal { val moduleKind = scalaJSModuleKind.value // intentionally not 'in key' val withSourceMap = (emitSourceMaps in key).value - val relSourceMapBase = { + /* For `relativizeSourceMapBase`, preserve the one in the new config + * if it is set, otherwise fall back on the old config. + */ + val oldConfigRelSourceMapBase = { if ((relativeSourceMaps in key).value) Some((artifactPath in key).value.getParentFile.toURI()) else None } + val newConfigRelSourceMapBase = + (scalaJSLinkerConfig in key).value.relativizeSourceMapBase + val relSourceMapBase = + newConfigRelSourceMapBase.orElse(oldConfigRelSourceMapBase) - val config = StandardLinker.Config() + StandardLinker.Config() .withSemantics(semantics) .withModuleKind(moduleKind) .withOutputMode(outputMode) @@ -208,6 +216,21 @@ object ScalaJSPluginInternal { .withCustomOutputWrapperInternal(scalaJSOutputWrapperInternal.value) .withPrettyPrint(opts.prettyPrintFullOptJS) .withBatchMode(opts.batchMode) + }, + + scalaJSLinker in key := { + val config = (scalaJSLinkerConfig in key).value + + 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(() => StandardLinker(config), config.batchMode) }, @@ -1012,23 +1035,66 @@ object ScalaJSPluginInternal { val scalaJSProjectBaseSettings = Seq( isScalaJSProject := true, + /* 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, - - scalaJSOutputWrapperInternal := ("", ""), - - scalaJSOptimizerOptions := OptimizerOptions(), + emitSourceMaps := scalaJSLinkerConfig.value.sourceMap, + + scalaJSOutputWrapperInternal := + scalaJSLinkerConfig.value.customOutputWrapper, + + 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) + }, jsDependencies := Seq(), jsDependencyFilter := identity, jsManifestFilter := identity, - scalaJSSemantics := Semantics.Defaults, - scalaJSOutputMode := OutputMode.ECMAScript51Isolated, - scalaJSModuleKind := ModuleKind.NoModule, + scalaJSSemantics := scalaJSLinkerConfig.value.semantics, + scalaJSOutputMode := scalaJSLinkerConfig.value.outputMode, + scalaJSModuleKind := scalaJSLinkerConfig.value.moduleKind, checkScalaJSSemantics := true, scalaJSModuleInitializers := Seq(), From d07af7c79b0ecca3498c0fe96c8fc223ad4abdb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 10 Jun 2017 17:39:04 +0200 Subject: [PATCH 0341/2665] Remove support for `exportsNamespace`. There are two aspects that are gone. First, Scala.js will not recognize `__ScalaJSEnv.exportsNamespace` anymore. It will therefore always export in the global object in `NoModule`. Second, `envInfo.exportsNamespace` is gone, so Scala.js code cannot detect where its own exports are going. This will become very important when we add ECMAScript 2015 modules, as a module cannot see its own "exports namespace". It will also be important if we truly export things in the global *scope* in `NoModule` with `let`s, since in that case there wouldn't even *be* a namespace where they can be looked up. --- .../scalajs/runtime/EnvironmentInfo.scala | 6 ----- .../scalajs/testinterface/TestDetector.scala | 19 +-------------- .../testsuite/jsinterop/ExportsTest.scala | 23 +++++++++++++++++-- tools/scalajsenv.js | 6 +---- .../tools/linker/backend/ModuleKind.scala | 4 +--- 5 files changed, 24 insertions(+), 34 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/runtime/EnvironmentInfo.scala b/library/src/main/scala/scala/scalajs/runtime/EnvironmentInfo.scala index 59daf29c5a..3a5fec18ff 100644 --- a/library/src/main/scala/scala/scalajs/runtime/EnvironmentInfo.scala +++ b/library/src/main/scala/scala/scalajs/runtime/EnvironmentInfo.scala @@ -24,12 +24,6 @@ import StackTrace.JSStackTraceElem */ sealed trait EnvironmentInfo extends js.Object { - /** The scope for Scala.js exports (i.e. objects and classes) - * - * @group envInfo - */ - def exportsNamespace: js.Dynamic - // Can't link to java.lang.Runtime.exit - #1969 /** The function that is called by `java.lang.Runtime.exit` * diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala b/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala index 9f3101bc27..df410d8717 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala @@ -27,30 +27,13 @@ private[scalajs] object TestDetector { } private def tryLoadFramework(names: js.Array[String]): Option[Framework] = { - def tryLoadFromReflect(name: String): Option[Framework] = { + def tryLoad(name: String): Option[Framework] = { Reflect.lookupInstantiatableClass(name).collect { case clazz if classOf[Framework].isAssignableFrom(clazz.runtimeClass) => clazz.newInstance().asInstanceOf[Framework] } } - def tryLoadFromExportsNamespace(name: String): Option[Framework] = { - val exportsNamespace = - scala.scalajs.runtime.linkingInfo.envInfo.exportsNamespace - - val parts = name.split('.') - val ctor = parts.foldLeft[js.UndefOr[js.Dynamic]](exportsNamespace) { - (parent, name) => parent.map(_.selectDynamic(name)) - } - - ctor.map(js.Dynamic.newInstance(_)()).collect { - case framework: Framework => framework - }.toOption - } - - def tryLoad(name: String): Option[Framework] = - tryLoadFromReflect(name).orElse(tryLoadFromExportsNamespace(name)) - names.toStream.map(tryLoad).flatten.headOption } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index e7eb6864ba..d9bb1f279f 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -25,8 +25,27 @@ import org.scalajs.testsuite.utils.AssertThrows.assertThrows class ExportsTest { - /** The namespace in which top-level exports are stored. */ - val exportsNamespace = scala.scalajs.runtime.environmentInfo.exportsNamespace + /** The namespace in which top-level exports are stored. + * + * If we are linking the test suite in `NoModule`, then exports are in the + * global object (technically they're in the global scope, but at least so + * far we can find them in the global object too). + * + * If we are linking in `CommonJSModule`, then exports are in the `exports` + * module-global variable, which we can retrieve as if it were in the global + * scope. + */ + val exportsNamespace: js.Dynamic = { + if (Platform.isNoModule) { + org.scalajs.testsuite.utils.JSUtils.globalObject + } else if (Platform.isCommonJSModule) { + js.Dynamic.global.exports + } else { + throw new NotImplementedError( + "Don't know how to fetch the exports namespace in an unknown " + + "module kind.") + } + } /** This package in the JS (export) namespace */ val jsPackage = exportsNamespace.org.scalajs.testsuite.jsinterop diff --git a/tools/scalajsenv.js b/tools/scalajsenv.js index ad383255ce..d8f11512c9 100644 --- a/tools/scalajsenv.js +++ b/tools/scalajsenv.js @@ -15,12 +15,8 @@ const $env = (typeof __ScalaJSEnv === "object" && __ScalaJSEnv) ? __ScalaJSEnv : const $e = exports; //!else // TODO Do not use global object detection, and rather export with actual `var` declarations -const $e = - (typeof $env["exportsNamespace"] === "object" && $env["exportsNamespace"]) - ? $env["exportsNamespace"] - : ((typeof global === "object" && global && global["Object"] === Object) ? global : this); +const $e = (typeof global === "object" && global && global["Object"] === Object) ? global : this; //!endif -$env["exportsNamespace"] = $e; // Freeze the environment info Object["freeze"]($env); diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/ModuleKind.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/ModuleKind.scala index 477a6d6b54..33c3bbd07d 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/ModuleKind.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/ModuleKind.scala @@ -25,9 +25,7 @@ object ModuleKind { /** No module structure. * - * With this module kind, exports are stored on the global object by - * default, or to a separate object specified with - * `__ScalaJSEnv.exportsNamespace`. + * With this module kind, exports are stored on the global object. * * Imports are not supported. */ From 2e45ad057731f6be8c55dba00248abf5f6f4b5a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 11 Jun 2017 13:50:58 +0200 Subject: [PATCH 0342/2665] Get rid of of `linkingInfo.envInfo`. Now that the only places reading `environmentInfo` are in Scala.js code (and not in the `Emitter` or in `scalajsenv.js`), we can get rid of it as a "primitive" known by the emitter. Instead, we access `__ScalaJSEnv` as a global variable from user-space code in the library. This means that `__ScalaJSEnv` is still a magic variable from the standard library point of view, but at least it isn't so from the *language* point of view anymore. --- .../src/main/scala/java/lang/Runtime.scala | 4 +-- .../src/main/scala/java/lang/System.scala | 6 ++-- .../scalajs/runtime/EnvironmentInfo.scala | 30 +++++++++++++------ .../scala/scalajs/runtime/LinkingInfo.scala | 3 -- .../scala/scalajs/runtime/StackTrace.scala | 12 ++++++-- .../scala/scala/scalajs/runtime/package.scala | 7 ----- .../closure/ClosureLinkerBackend.scala | 1 - tools/scalajsenv.js | 7 ----- .../backend/emitter/FunctionEmitter.scala | 9 ------ 9 files changed, 37 insertions(+), 42 deletions(-) diff --git a/javalanglib/src/main/scala/java/lang/Runtime.scala b/javalanglib/src/main/scala/java/lang/Runtime.scala index 70fd4cb3eb..0019680b37 100644 --- a/javalanglib/src/main/scala/java/lang/Runtime.scala +++ b/javalanglib/src/main/scala/java/lang/Runtime.scala @@ -10,9 +10,9 @@ class Runtime private { //def removeShutdownHook(hook: Thread): Unit def halt(status: Int): Unit = { - val envInfo = scala.scalajs.runtime.environmentInfo + val envInfo = scala.scalajs.runtime.EnvironmentInfo.envInfo - envInfo.exitFunction.fold { + envInfo.flatMap(_.exitFunction).fold { // We don't have an exit function. Fail throw new SecurityException("Cannot terminate a JavaScript program. " + "Define a JavaScript function `__ScalaJSEnv.exitFunction` to " + diff --git a/javalanglib/src/main/scala/java/lang/System.scala b/javalanglib/src/main/scala/java/lang/System.scala index 4378b58904..c978ed3495 100644 --- a/javalanglib/src/main/scala/java/lang/System.scala +++ b/javalanglib/src/main/scala/java/lang/System.scala @@ -5,7 +5,7 @@ import java.io._ import scala.scalajs.js import scala.scalajs.js.Dynamic.global import scala.scalajs.LinkingInfo.assumingES6 -import scala.scalajs.runtime.{environmentInfo, linkingInfo, SemanticsUtils} +import scala.scalajs.runtime.{linkingInfo, SemanticsUtils} import java.{util => ju} @@ -233,11 +233,13 @@ object System { sysProp.setProperty("line.separator", "\n") for { - jsEnvProperties <- environmentInfo.javaSystemProperties + envInfo <- scala.scalajs.runtime.EnvironmentInfo.envInfo + jsEnvProperties <- envInfo.javaSystemProperties (key, value) <- jsEnvProperties } { sysProp.setProperty(key, value) } + sysProp } } diff --git a/library/src/main/scala/scala/scalajs/runtime/EnvironmentInfo.scala b/library/src/main/scala/scala/scalajs/runtime/EnvironmentInfo.scala index 3a5fec18ff..6630e15e21 100644 --- a/library/src/main/scala/scala/scalajs/runtime/EnvironmentInfo.scala +++ b/library/src/main/scala/scala/scalajs/runtime/EnvironmentInfo.scala @@ -7,17 +7,14 @@ import StackTrace.JSStackTraceElem /** Information about the JavaScript environment Scala.js runs in. * * Holds configuration for the Scala.js internals and should not be used - * directly (could be retrieved via [[runtime.environmentInfo]]). + * directly (could be retrieved via [[EnvironmentInfo.envInfo]]). * - * This facade type serves as a documentation on what aspects of Scala.js can - * be influenced through environment options. + * This facade type serves as a documentation on what aspects of the Scala.js + * standard library can be influenced through environment options. * - * Upon startup, Scala.js checks whether the name __ScalaJSEnv is - * defined in its scope (and references an object). If so, it uses it as - * environment info. - * Missing, non-optional fields (according to this facade type) are initialized - * to default values, optional fields are kept as in the original object. - * Finally, [[js.Object.freeze]] is called on the object to avoid modification. + * If there is a variable named `__ScalaJSEnv` in Scala.js' scope (and it + * references an object), it is used as the value of + * [[EnvironmentInfo.envInfo]]. Otherwise, the latter is `undefined`. * * @groupname envInfo Scala.js environment configuration * @groupprio envInfo 1 @@ -44,3 +41,18 @@ sealed trait EnvironmentInfo extends js.Object { */ def javaSystemProperties: js.UndefOr[js.Dictionary[String]] } + +object EnvironmentInfo { + /** The value of the `__ScalaJSEnv` variable, if it exists. */ + val envInfo: js.UndefOr[EnvironmentInfo] = { + import js.Dynamic.{global => g} + + // We've got to use selectDynamic explicitly not to crash Scala 2.10 + if (js.typeOf(g.selectDynamic("__ScalaJSEnv")) == "object" && + g.selectDynamic("__ScalaJSEnv") != null) { + g.selectDynamic("__ScalaJSEnv").asInstanceOf[EnvironmentInfo] + } else { + js.undefined + } + } +} diff --git a/library/src/main/scala/scala/scalajs/runtime/LinkingInfo.scala b/library/src/main/scala/scala/scalajs/runtime/LinkingInfo.scala index b89435eaf1..65007c50a3 100644 --- a/library/src/main/scala/scala/scalajs/runtime/LinkingInfo.scala +++ b/library/src/main/scala/scala/scalajs/runtime/LinkingInfo.scala @@ -4,9 +4,6 @@ import scala.scalajs.js /** Information about link-time configuration of Scala.js. */ sealed trait LinkingInfo extends js.Object { - /** Environment info. */ - val envInfo: EnvironmentInfo - /** Semantics configuration. */ val semantics: LinkingInfo.Semantics diff --git a/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala b/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala index 3c30f95da7..48303008a6 100644 --- a/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala +++ b/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala @@ -18,6 +18,15 @@ object StackTrace { import Implicits._ + private type SourceMapper = + js.Function1[js.Array[JSStackTraceElem], js.Array[JSStackTraceElem]] + + private lazy val sourceMapper: SourceMapper = { + EnvironmentInfo.envInfo.flatMap(_.sourceMapper).getOrElse { + (s: js.Array[JSStackTraceElem]) => s + } + } + /** Returns the current stack trace. * If the stack trace cannot be analyzed in meaningful way (because we don't * know the browser), an empty array is returned. @@ -136,8 +145,7 @@ object StackTrace { } // Map stack trace through environment (if supported) - val mappedTrace = - environmentInfo.sourceMapper.fold(trace)(mapper => mapper(trace)) + val mappedTrace = sourceMapper(trace) // Convert JS objects to java.lang.StackTraceElements // While loop due to space concerns diff --git a/library/src/main/scala/scala/scalajs/runtime/package.scala b/library/src/main/scala/scala/scalajs/runtime/package.scala index 81f0b966a3..8a7e1e81ea 100644 --- a/library/src/main/scala/scala/scalajs/runtime/package.scala +++ b/library/src/main/scala/scala/scalajs/runtime/package.scala @@ -112,13 +112,6 @@ package object runtime { } } - /** Information about the environment Scala.js runs in - * - * See [[EnvironmentInfo]] for details. - */ - @inline def environmentInfo: EnvironmentInfo = - linkingInfo.envInfo - /** Information known at link-time, given the output configuration. * * See [[LinkingInfo]] for details. diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala index 8bc99bba9f..f34e20acbf 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala @@ -208,7 +208,6 @@ private object ClosureLinkerBackend { function require() {} var global = {}; var exports = {}; - var __ScalaJSEnv = {}; var NaN = 0.0/0.0, Infinity = 1.0/0.0, undefined = void 0; """ diff --git a/tools/scalajsenv.js b/tools/scalajsenv.js index d8f11512c9..0e4f582c8f 100644 --- a/tools/scalajsenv.js +++ b/tools/scalajsenv.js @@ -7,9 +7,6 @@ * The top-level Scala.js environment * * ---------------------------------- */ -// Get the environment info -const $env = (typeof __ScalaJSEnv === "object" && __ScalaJSEnv) ? __ScalaJSEnv : {}; - // Where to send exports //!if moduleKind == CommonJSModule const $e = exports; @@ -18,12 +15,8 @@ const $e = exports; const $e = (typeof global === "object" && global && global["Object"] === Object) ? global : this; //!endif -// Freeze the environment info -Object["freeze"]($env); - // Linking info - must be in sync with scala.scalajs.runtime.LinkingInfo const $linkingInfo = { - "envInfo": $env, "semantics": { //!if asInstanceOfs == Compliant "asInstanceOfs": 0, diff --git 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 index f529f8d4fa..5e04082d97 100644 --- 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 @@ -1136,15 +1136,6 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case Unbox(expr, _) => (allowSideEffects || semantics.asInstanceOfs == Unchecked) && test(expr) - // Because the linking info is a frozen object, linkingInfo["envInfo"] is pure - case JSBracketSelect(JSLinkingInfo(), StringLiteral("envInfo")) => true - - // And because the env is a frozen object too, linkingInfo["envInfo"]["global"] is pure - case JSBracketSelect( - JSBracketSelect(JSLinkingInfo(), StringLiteral("envInfo")), - StringLiteral("global")) => - true - // JavaScript expressions that can always have side-effects case JSNew(fun, args) => allowSideEffects && test(fun) && (args forall test) From 6114a92f075bdb2eea9936d25cd3fc599dbc8964 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 4 Jun 2017 13:38:55 +0200 Subject: [PATCH 0343/2665] Remove unnecessary @ScalaJSDefined They probably creeped in from the 0.6.x branch (or forgotten imports). --- .../org/scalajs/core/compiler/test/JSInteropTest.scala | 3 +-- .../scala/org/scalajs/core/compiler/test/JSSAMTest.scala | 6 ++---- .../org/scalajs/testsuite/compiler/RegressionJSTest.scala | 1 - .../org/scalajs/testsuite/jsinterop/IterableTest.scala | 2 +- .../testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala | 3 --- 5 files changed, 4 insertions(+), 11 deletions(-) diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index e3ce1cfcf4..0572755ff3 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -203,12 +203,11 @@ class JSInteropTest extends DirectTest with TestHelpers { obj <- Seq("class", "trait", "object") } yield { s""" - @ScalaJSDefined @JSImport("foo", JSImport.Namespace, globalFallback = "Foo") $obj A extends js.Object """ hasErrors s""" - |newSource1.scala:6: error: Non JS-native classes, traits and objects may not have an @JSImport annotation. + |newSource1.scala:5: error: Non JS-native classes, traits and objects may not have an @JSImport annotation. | @JSImport("foo", JSImport.Namespace, globalFallback = "Foo") | ^ """ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSSAMTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSSAMTest.scala index d2076f1c04..6d805ecac1 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSSAMTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSSAMTest.scala @@ -24,7 +24,6 @@ class JSSAMTest extends DirectTest with TestHelpers { def foo(x: Int): Int } - @ScalaJSDefined trait Bar extends js.Object { def bar(x: Int): Int } @@ -49,7 +48,6 @@ class JSSAMTest extends DirectTest with TestHelpers { def foo(x: Int): Int } - @ScalaJSDefined trait Bar extends js.Object { def bar(x: Int): Int } @@ -60,10 +58,10 @@ class JSSAMTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:16: error: Using an anonymous function as a SAM for the JavaScript type Foo is not allowed. Use an anonymous class instead. + |newSource1.scala:15: error: Using an anonymous function as a SAM for the JavaScript type Foo is not allowed. Use an anonymous class instead. | val foo: Foo = x => x + 1 | ^ - |newSource1.scala:17: error: Using an anonymous function as a SAM for the JavaScript type Bar is not allowed. Use an anonymous class instead. + |newSource1.scala:16: error: Using an anonymous function as a SAM for the JavaScript type Bar is not allowed. Use an anonymous class instead. | val Bar: Bar = x => x + 1 | ^ """ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala index 3375fe5aad..650eb1314d 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala @@ -46,7 +46,6 @@ class RegressionJSTest { } @Test def should_transform_js_dynamic_x_receiver_issue_2804(): Unit = { - @ScalaJSDefined class Foo extends js.Object assertTrue(js.isUndefined(js.constructorOf[Foo].x)) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/IterableTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/IterableTest.scala index ec7a95027a..6e8c91e3ae 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/IterableTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/IterableTest.scala @@ -8,7 +8,7 @@ package org.scalajs.testsuite.jsinterop import scala.scalajs.js -import scala.scalajs.js.annotation.{JSName, ScalaJSDefined} +import scala.scalajs.js.annotation.JSName import org.junit.Assert._ import org.junit.Assume._ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala index 1f2291f03c..fc936ac548 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala @@ -85,7 +85,6 @@ class ModulesWithGlobalFallbackTest { } object ModulesWithGlobalFallbackTest { - @ScalaJSDefined private object QueryStringFallbackImpl extends js.Object { def stringify(obj: js.Dictionary[String], sep: String = "&", eq: String = "="): String = { @@ -99,7 +98,6 @@ object ModulesWithGlobalFallbackTest { } } - @ScalaJSDefined private class StringDecoderFallbackImpl(charsetName: String = "utf8") extends js.Object { import java.nio.charset._ @@ -140,7 +138,6 @@ object ModulesWithGlobalFallbackTest { writeInternal(new Uint8Array(0), endOfInput = true) } - @ScalaJSDefined object BufferStaticFallbackImpl extends js.Object { def isBuffer(x: Any): Boolean = x.isInstanceOf[Uint8Array] } From 75d81c0845bae50f08dc8017e750c735280ec1c3 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 3 Jun 2017 10:43:45 +0200 Subject: [PATCH 0344/2665] Fix #2837: Remove the term "Scala.js defined" It is replaced by non-native JS class/type (except for tests). With this commit, the following regexes (case insensitive) to not return any result outside of tests and the definition of the @ScalaJSDefined annotation itself. Scala\.js[- ]defined SJS ?defined ScalaJSDefined --- .../org/scalajs/core/compiler/GenJSCode.scala | 98 +++++++++---------- .../scalajs/core/compiler/GenJSExports.scala | 6 +- .../scalajs/core/compiler/JSDefinitions.scala | 2 +- .../scalajs/core/compiler/JSEncoding.scala | 2 +- .../scalajs/core/compiler/PrepJSExports.scala | 6 +- .../scalajs/core/compiler/PrepJSInterop.scala | 46 +++++---- .../test/InternalAnnotationsTest.scala | 4 +- .../core/compiler/test/JSExportTest.scala | 8 +- .../core/compiler/test/JSInteropTest.scala | 22 ++--- .../core/compiler/test/JSOptionalTest.scala | 30 +++--- ...edTest.scala => NonNativeJSTypeTest.scala} | 64 ++++++------ .../scala/org/scalajs/core/ir/ClassKind.scala | 2 +- .../scala/org/scalajs/core/ir/Trees.scala | 18 ++-- .../js/annotation/JSExportStatic.scala | 2 +- .../internal/AnonymousJSClass.scala | 10 ++ .../annotation/internal/ExposedJSMember.scala | 2 +- .../js/annotation/internal/JSOptional.scala | 2 +- .../internal/SJSDefinedAnonymousClass.scala | 10 -- project/Build.scala | 2 +- scalalib/overrides/scala/Enumeration.scala | 2 +- ...stEx.scala => NonNativeJSTypeTestEx.scala} | 4 +- ...ala => NonNativeTypeTestSeparateRun.scala} | 4 +- ...tives.js => NonNativeJSTypeTestNatives.js} | 24 ++--- ...edTest.scala => NonNativeJSTypeTest.scala} | 30 +++--- .../testsuite/niobuffer/FloatBufferTest.scala | 2 +- .../testsuite/niobuffer/IntBufferTest.scala | 2 +- .../testsuite/niobuffer/LongBufferTest.scala | 2 +- .../testsuite/niobuffer/ShortBufferTest.scala | 2 +- .../linker/backend/emitter/ClassEmitter.scala | 2 +- .../linker/backend/emitter/Emitter.scala | 2 +- .../backend/emitter/FunctionEmitter.scala | 4 +- .../core/tools/linker/checker/IRChecker.scala | 4 +- 32 files changed, 209 insertions(+), 211 deletions(-) rename compiler/src/test/scala/org/scalajs/core/compiler/test/{ScalaJSDefinedTest.scala => NonNativeJSTypeTest.scala} (77%) create mode 100644 library/src/main/scala/scala/scalajs/js/annotation/internal/AnonymousJSClass.scala delete mode 100644 library/src/main/scala/scala/scalajs/js/annotation/internal/SJSDefinedAnonymousClass.scala rename test-suite-ex/src/test/scala/org/scalajs/testsuite/jsinterop/{ScalaJSDefinedTestEx.scala => NonNativeJSTypeTestEx.scala} (91%) rename test-suite/js/src/main/scala/org/scalajs/testsuite/jsinterop/{ScalaJSDefinedTestSeparateRun.scala => NonNativeTypeTestSeparateRun.scala} (89%) rename test-suite/js/src/test/resources/{ScalaJSDefinedTestNatives.js => NonNativeJSTypeTestNatives.js} (65%) rename test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/{ScalaJSDefinedTest.scala => NonNativeJSTypeTest.scala} (97%) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 9995592b37..49235d88c1 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -240,11 +240,11 @@ abstract class GenJSCode extends plugins.PluginComponent * function in the method that instantiates it. * * Other ClassDefs are emitted according to their nature: - * * Scala.js-defined JS class -> `genScalaJSDefinedJSClass()` - * * Other raw JS type (<: js.Any) -> `genRawJSClassData()` - * * Interface -> `genInterface()` - * * Implementation class -> `genImplClass()` - * * Normal class -> `genClass()` + * * Non-native JS class -> `genNonNativeJSClass()` + * * Other JS type (<: js.Any) -> `genRawJSClassData()` + * * Interface -> `genInterface()` + * * Implementation class -> `genImplClass()` + * * Normal class -> `genClass()` */ override def apply(cunit: CompilationUnit): Unit = { try { @@ -271,9 +271,8 @@ abstract class GenJSCode extends plugins.PluginComponent * * - lambdas for js.FunctionN and js.ThisFunctionN (SAMs). (We may not * generate actual Scala classes for these). - * - anonymous Scala.js defined JS classes. These classes may not have - * their own prototype. Therefore, their constructor *must* be - * inlined. + * - anonymous (non-lambda) JS classes. These classes may not have their + * own prototype. Therefore, their constructor *must* be inlined. * - lambdas for scala.FunctionN. This is only an optimization and may * fail. In the case of failure, we fall back to generating a * fully-fledged Scala class. @@ -284,7 +283,7 @@ abstract class GenJSCode extends plugins.PluginComponent val (lazyAnons, fullClassDefs) = allClassDefs.partition { cd => val sym = cd.symbol isRawJSFunctionDef(sym) || sym.isAnonymousFunction || - isScalaJSDefinedAnonJSClass(sym) + isAnonJSClass(sym) } lazilyGeneratedAnonClasses ++= lazyAnons.map(cd => cd.symbol -> cd) @@ -307,8 +306,8 @@ abstract class GenJSCode extends plugins.PluginComponent val tree = if (isRawJSType(sym.tpe)) { assert(!isRawJSFunctionDef(sym), s"Raw JS function def should have been recorded: $cd") - if (!sym.isTraitOrInterface && isScalaJSDefinedJSClass(sym)) - genScalaJSDefinedJSClass(cd) + if (!sym.isTraitOrInterface && isNonNativeJSClass(sym)) + genNonNativeJSClass(cd) else genRawJSClassData(cd) } else if (sym.isTraitOrInterface) { @@ -472,14 +471,14 @@ abstract class GenJSCode extends plugins.PluginComponent classDefinition } - /** Gen the IR ClassDef for a Scala.js-defined JS class. */ - def genScalaJSDefinedJSClass(cd: ClassDef): js.ClassDef = { + /** Gen the IR ClassDef for a non-native JS class. */ + def genNonNativeJSClass(cd: ClassDef): js.ClassDef = { val sym = cd.symbol implicit val pos = sym.pos - assert(isScalaJSDefinedJSClass(sym), - "genScalaJSDefinedJSClass() must be called only for " + - s"Scala.js-defined JS classes: $sym") + assert(isNonNativeJSClass(sym), + "genNonNativeJSClass() must be called only for " + + s"non-native JS classes: $sym") assert(sym.superClass != NoSymbol, sym) val classIdent = encodeClassFullNameIdent(sym) @@ -585,23 +584,23 @@ abstract class GenJSCode extends plugins.PluginComponent classDefinition } - /** Generate an instance of an anonymous Scala.js defined class inline + /** Generate an instance of an anonymous (non-lambda) JS class inline * * @param sym Class to generate the instance of * @param args Arguments to the constructor * @param pos Position of the original New tree */ - def genAnonSJSDefinedNew(sym: Symbol, args: List[js.Tree], + def genAnonJSClassNew(sym: Symbol, args: List[js.Tree], pos: Position): js.Tree = { - assert(isScalaJSDefinedAnonJSClass(sym), - "Generating AnonSJSDefinedNew of non anonymous SJSDefined JS class") + assert(isAnonJSClass(sym), + "Generating AnonJSClassNew of non anonymous JS class") // Find the ClassDef for this anonymous class val classDef = consumeLazilyGeneratedAnonClass(sym) - // Generate a normal SJSDefinedJSClass + // Generate a normal, non-native JS class val origJsClass = - nestedGenerateClass(sym)(genScalaJSDefinedJSClass(classDef)) + nestedGenerateClass(sym)(genNonNativeJSClass(classDef)) // Partition class members. val staticMembers = ListBuffer.empty[js.Tree] @@ -615,7 +614,8 @@ abstract class GenJSCode extends plugins.PluginComponent case mdef: js.MethodDef => mdef.name match { case _: js.Ident => - assert(mdef.static, "Non-static method in SJS defined JS class") + assert(mdef.static, + "Non-static, unexported method in non-native JS class") staticMembers += mdef case js.StringLiteral("constructor") => @@ -895,7 +895,7 @@ abstract class GenJSCode extends plugins.PluginComponent else encodeFieldSym(f) val irTpe = { - if (isScalaJSDefinedJSClass(classSym)) genExposedFieldIRType(f) + if (isNonNativeJSClass(classSym)) genExposedFieldIRType(f) else if (static) jstpe.AnyType else toIRType(f.tpe) } @@ -1033,7 +1033,7 @@ abstract class GenJSCode extends plugins.PluginComponent } } - // Constructor of a Scala.js-defined JS class ------------------------------ + // Constructor of a non-native JS class ------------------------------ def genJSClassConstructor(classSym: Symbol, constructorTrees: List[DefDef]): js.Tree = { @@ -1042,7 +1042,7 @@ abstract class GenJSCode extends plugins.PluginComponent if (hasDefaultCtorArgsAndRawJSModule(classSym)) { reporter.error(pos, "Implementation restriction: constructors of " + - "Scala.js-defined JS classes cannot have default parameters " + + "non-native JS classes cannot have default parameters " + "if their companion module is JS native.") js.Skip() } else { @@ -1419,7 +1419,7 @@ abstract class GenJSCode extends plugins.PluginComponent val params = if (vparamss.isEmpty) Nil else vparamss.head map (_.symbol) val isJSClassConstructor = - sym.isClassConstructor && isScalaJSDefinedJSClass(currentClassSym) + sym.isClassConstructor && isNonNativeJSClass(currentClassSym) val methodName: js.PropertyName = encodeMethodSym(sym) @@ -1591,7 +1591,7 @@ abstract class GenJSCode extends plugins.PluginComponent /** Moves all statements after the super constructor call. * - * This is used for the primary constructor of a Scala.js-defined JS + * This is used for the primary constructor of a non-native JS * class, because those cannot access `this` before the super constructor * call. * @@ -1612,7 +1612,7 @@ abstract class GenJSCode extends plugins.PluginComponent assert(!beforeSuper.exists(_.isInstanceOf[js.VarDef]), "Trying to move a local VarDef after the super constructor call " + - "of a Scala.js-defined JS class at ${body.pos}") + "of a non-native JS class at ${body.pos}") js.Block( superCall :: @@ -1691,7 +1691,7 @@ abstract class GenJSCode extends plugins.PluginComponent else genExpr(tree) } - if (!isScalaJSDefinedJSClass(currentClassSym) || + if (!isNonNativeJSClass(currentClassSym) || isRawJSFunctionDef(currentClassSym)) { js.MethodDef(static, methodName, jsParams, resultIRType, Some(genBody()))(optimizerHints, None) @@ -1871,7 +1871,7 @@ abstract class GenJSCode extends plugins.PluginComponent genStaticMember(sym) } else if (paramAccessorLocals contains sym) { paramAccessorLocals(sym).ref - } else if (isScalaJSDefinedJSClass(sym.owner)) { + } else if (isNonNativeJSClass(sym.owner)) { val genQual = genExpr(qualifier) val boxed = if (isExposed(sym)) js.JSBracketSelect(genQual, genExpr(jsNameOf(sym))) @@ -1957,7 +1957,7 @@ abstract class GenJSCode extends plugins.PluginComponent enteringPhase(currentRun.posterasurePhase)(rhs.tpe)) } - if (isScalaJSDefinedJSClass(sym.owner)) { + if (isNonNativeJSClass(sym.owner)) { val genLhs = if (isExposed(sym)) js.JSBracketSelect(genQual, genExpr(jsNameOf(sym))) else @@ -2247,7 +2247,7 @@ abstract class GenJSCode extends plugins.PluginComponent sym.hasFlag(reflect.internal.Flags.DEFAULTPARAM) && isRawJSType(sym.owner.tpe) && { /* If this is a default parameter accessor on a - * ScalaJSDefinedJSClass, we need to know if the method for which we + * non-native JS class, we need to know if the method for which we * are the default parameter is exposed or not. * We do this by removing the $default suffix from the method name, * and looking up a member with that name in the owner. @@ -2262,7 +2262,7 @@ abstract class GenJSCode extends plugins.PluginComponent ownerMethod.filter(isExposed).exists } - !isScalaJSDefinedJSClass(sym.owner) || isAttachedMethodExposed + !isNonNativeJSClass(sym.owner) || isAttachedMethodExposed } } } @@ -2375,7 +2375,7 @@ abstract class GenJSCode extends plugins.PluginComponent val Apply(fun @ Select(sup @ Super(_, mix), _), args) = tree val sym = fun.symbol - if (isScalaJSDefinedJSClass(currentClassSym)) { + if (isNonNativeJSClass(currentClassSym)) { if (sym.isMixinConstructor) { /* Do not emit a call to the $init$ method of JS traits. * This exception is necessary because @JSOptional fields cause the @@ -2569,7 +2569,7 @@ abstract class GenJSCode extends plugins.PluginComponent if (sym.owner == StringClass && !isStringMethodFromObject) { genStringCall(tree) } else if (isRawJSType(receiver.tpe) && sym.owner != ObjectClass) { - if (!isScalaJSDefinedJSClass(sym.owner) || isExposed(sym)) + if (!isNonNativeJSClass(sym.owner) || isExposed(sym)) genPrimitiveJSCall(tree, isStat) else genApplyJSClassMethod(genExpr(receiver), sym, genActualArgs(sym, args)) @@ -4239,11 +4239,11 @@ abstract class GenJSCode extends plugins.PluginComponent // 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) { 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 { @@ -4261,7 +4261,7 @@ abstract class GenJSCode extends plugins.PluginComponent def requireNotSuper(): Unit = { if (superIn.isDefined) { reporter.error(pos, - "Illegal super call in Scala.js-defined JS class") + "Illegal super call in non-native JS class") } } @@ -4479,8 +4479,8 @@ abstract class GenJSCode extends plugins.PluginComponent js.JSObjectConstr(Nil) else if (cls == JSArrayClass && args.isEmpty) js.JSArrayConstr(Nil) - else if (isScalaJSDefinedAnonJSClass(cls)) - genAnonSJSDefinedNew(cls, args, fun.pos) + else if (isAnonJSClass(cls)) + genAnonJSClassNew(cls, args, fun.pos) else js.JSNew(genPrimitiveJSClass(cls), args) } @@ -4546,7 +4546,7 @@ abstract class GenJSCode extends plugins.PluginComponent implicit pos: Position): List[js.Tree] = { /* lambdalift might have to introduce some parameters when transforming - * nested Scala.js-defined JS classes. Hence, the list of parameters + * nested non-native JS classes. Hence, the list of parameters * exiting typer and entering posterasure might not be compatible with * the list of actual arguments we receive now. * @@ -5056,7 +5056,7 @@ abstract class GenJSCode extends plugins.PluginComponent val thisCaptureArg = thisFormalCapture.ref val body = if (isRawJSType(receiver.tpe) && target.owner != ObjectClass) { - assert(isScalaJSDefinedJSClass(target.owner) && !isExposed(target), + assert(isNonNativeJSClass(target.owner) && !isExposed(target), s"A Function lambda is trying to call an exposed JS method ${target.fullName}") genApplyJSClassMethod(thisCaptureArg, target, allArgs) } else { @@ -5260,7 +5260,7 @@ abstract class GenJSCode extends plugins.PluginComponent def module = genLoadModule(sym.owner) if (isRawJSType(sym.owner.tpe)) { - if (!isScalaJSDefinedJSClass(sym.owner) || isExposed(sym)) + if (!isNonNativeJSClass(sym.owner) || isExposed(sym)) genJSCallGeneric(sym, moduleOrGlobalScope, args = Nil, isStat = false) else genApplyJSClassMethod(module, sym, arguments = Nil) @@ -5476,12 +5476,12 @@ abstract class GenJSCode extends plugins.PluginComponent def isRawJSType(tpe: Type): Boolean = tpe.typeSymbol.annotations.find(_.tpe =:= RawJSTypeAnnot.tpe).isDefined - /** Tests whether the given class is a Scala.js-defined JS class. */ - def isScalaJSDefinedJSClass(sym: Symbol): Boolean = + /** Tests whether the given class is a non-native JS class. */ + def isNonNativeJSClass(sym: Symbol): Boolean = !sym.isTrait && isRawJSType(sym.tpe) && !sym.hasAnnotation(JSNativeAnnotation) - def isScalaJSDefinedAnonJSClass(sym: Symbol): Boolean = - sym.hasAnnotation(SJSDefinedAnonymousClassAnnotation) + def isAnonJSClass(sym: Symbol): Boolean = + sym.hasAnnotation(AnonymousJSClassAnnotation) /** Tests whether the given class is a JS native class. */ private def isJSNativeClass(sym: Symbol): Boolean = @@ -5494,7 +5494,7 @@ abstract class GenJSCode extends plugins.PluginComponent } /** Tests whether the given member is exposed, i.e., whether it was - * originally a public or protected member of a Scala.js-defined JS class. + * originally a public or protected member of a non-native JS class. */ private def isExposed(sym: Symbol): Boolean = sym.hasAnnotation(ExposedJSMemberAnnot) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index ccf50d5929..bb0b6be32e 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -608,7 +608,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => */ private def genApplyForSym(minArgc: Int, hasRestParam: Boolean, sym: Symbol, static: Boolean): js.Tree = { - if (isScalaJSDefinedJSClass(currentClassSym) && + if (isNonNativeJSClass(currentClassSym) && sym.owner != currentClassSym.get) { assert(!static) genApplyForSymJSSuperCall(minArgc, hasRestParam, sym) @@ -737,7 +737,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => result.take(defaultGetter.tpe.params.size).toList.map(_.ref) if (isRawJSType(trgSym.toTypeConstructor)) { - if (isScalaJSDefinedJSClass(defaultGetter.owner)) { + if (isNonNativeJSClass(defaultGetter.owner)) { genApplyJSClassMethod(trgTree, defaultGetter, defaultGetterArgs) } else { reporter.error(param.pos, "When overriding a native method " + @@ -778,7 +778,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => if (static) genLoadModule(sym.owner) else js.This()(thisType) val call = { - if (isScalaJSDefinedJSClass(currentClassSym)) { + if (isNonNativeJSClass(currentClassSym)) { assert(sym.owner == currentClassSym.get, sym.fullName) genApplyJSClassMethod(receiver, sym, args) } else { diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 90a50b3d1b..0635cf315f 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -68,7 +68,7 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val ExposedJSMemberAnnot = getRequiredClass("scala.scalajs.js.annotation.internal.ExposedJSMember") lazy val JSOptionalAnnotation = getRequiredClass("scala.scalajs.js.annotation.internal.JSOptional") lazy val RawJSTypeAnnot = getRequiredClass("scala.scalajs.js.annotation.internal.RawJSType") - lazy val SJSDefinedAnonymousClassAnnotation = getRequiredClass("scala.scalajs.js.annotation.internal.SJSDefinedAnonymousClass") + lazy val AnonymousJSClassAnnotation = getRequiredClass("scala.scalajs.js.annotation.internal.AnonymousJSClass") lazy val WasPublicBeforeTyperClass = getRequiredClass("scala.scalajs.js.annotation.internal.WasPublicBeforeTyper") lazy val JSAnyTpe = JSAnyClass.toTypeConstructor diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala index 308a62548b..21f34858ca 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala @@ -245,7 +245,7 @@ trait JSEncoding extends SubComponent { self: GenJSCode => val paramTypeNames0 = tpe.params map (p => internalName(p.tpe)) val hasExplicitThisParameter = - inRTClass || isScalaJSDefinedJSClass(sym.owner) + inRTClass || isNonNativeJSClass(sym.owner) val paramTypeNames = if (!hasExplicitThisParameter) paramTypeNames0 else internalName(sym.owner.toTypeConstructor) :: paramTypeNames0 diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala index 7c6664d9c0..cb125bcf90 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala @@ -318,7 +318,7 @@ trait PrepJSExports { this: PrepJSInterop => } case ExportDestination.Static => - def companionIsScalaJSDefinedJSClass: Boolean = { + def companionIsNonNativeJSClass: Boolean = { val companion = symOwner.companionClass companion != NoSymbol && !companion.isTrait && @@ -327,10 +327,10 @@ trait PrepJSExports { this: PrepJSInterop => } if (!symOwner.isStatic || !symOwner.isModuleClass || - !companionIsScalaJSDefinedJSClass) { + !companionIsNonNativeJSClass) { reporter.error(annot.pos, "Only a static object whose companion class is a " + - "Scala.js-defined JS class may export its members as static.") + "non-native JS class may export its members as static.") } if (isMember) { diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 7e8748c8a9..e633b9c41a 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -441,7 +441,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent assert(exports.isEmpty, "Generated exports for local definition.") } - // Expose objects (modules) members of Scala.js-defined JS classes + // Expose objects (modules) members of non-native JS classes if (sym.isModule && (enclosingOwner is OwnerKind.JSNonNative)) { if (shouldModuleBeExposed(sym)) sym.addAnnotation(ExposedJSMemberAnnot) @@ -478,7 +478,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent sym.addAnnotation(RawJSTypeAnnot) if (sym.isAnonymousClass && !isJSAnonFun) { - sym.addAnnotation(SJSDefinedAnonymousClassAnnotation) + sym.addAnnotation(AnonymousJSClassAnnotation) } /* Anonymous functions are considered native, since they are handled @@ -515,26 +515,26 @@ abstract class PrepJSInterop extends plugins.PluginComponent "which does not extend js.Any.") } - // Checks for Scala.js-defined JS stuff + // Checks for non-native JS stuff if (!isJSNative) { // Unless it is a trait, it cannot be in a native JS object if (!sym.isTrait && (enclosingOwner is OwnerKind.JSNativeMod)) { reporter.error(implDef.pos, - "Native JS objects cannot contain inner Scala.js-defined JS " + + "Native JS objects cannot contain inner non-native JS " + "classes or objects") } // Unless it is a trait, it cannot inherit directly from AnyRef if (!sym.isTrait && sym.info.parents.exists(_ =:= AnyRefClass.tpe)) { reporter.error(implDef.pos, - s"A Scala.js-defined JS $strKind cannot directly extend AnyRef. " + + s"A non-native JS $strKind cannot directly extend AnyRef. " + "It must extend a JS class (native or not).") } // Check that we do not inherit directly from a native JS trait if (sym.info.parents.exists(isNativeJSTraitType)) { reporter.error(implDef.pos, - s"A Scala.js-defined JS $strKind cannot directly extend a "+ + s"A non-native JS $strKind cannot directly extend a "+ "native JS trait.") } @@ -558,7 +558,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent reporter.error(implDef.pos, "Traits and classes " + "may not have inner native JS traits, classes or objects") } else if (enclosingOwner is OwnerKind.JSMod) { - reporter.error(implDef.pos, "Scala.js-defined JS objects " + + reporter.error(implDef.pos, "non-native JS objects " + "may not have inner native JS classes or objects") } else if (!sym.isTrait) { /* Compute the loading spec now, before `flatten` destroys the name @@ -628,7 +628,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent if (isJSOptional(low) && !(high.isDeferred || isJSOptional(high))) { reporter.error(errorPos, s"Cannot override concrete ${memberDefString(high)} from " + - s"${high.owner.fullName} in a Scala.js-defined JS trait.") + s"${high.owner.fullName} in a non-native JS trait.") } } } @@ -755,7 +755,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent assert(exports.isEmpty, "Generated exports for member JS type.") /* Add the @ExposedJSMember annotation to exposed symbols in - * Scala.js-defined classes. + * non-native JS classes. */ if (enclosingOwner is OwnerKind.JSNonNative) { def shouldBeExposed: Boolean = { @@ -795,7 +795,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent "exported as a property. You must add @JSName(\"apply\")") } else if (enclosingOwner is OwnerKind.JSNonNative) { reporter.error(sym.pos, - "A Scala.js-defined JavaScript class cannot declare a method " + + "A non-native JS class cannot declare a method " + "named `apply` without `@JSName`") } } @@ -806,7 +806,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent if (jsInterop.isJSBracketAccess(sym)) { if (enclosingOwner is OwnerKind.JSNonNative) { reporter.error(tree.pos, - "@JSBracketAccess is not allowed in Scala.js-defined JS classes") + "@JSBracketAccess is not allowed in non-native JS classes") } else { val paramCount = sym.paramss.map(_.size).sum if (paramCount != 1 && paramCount != 2) { @@ -833,7 +833,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent if (jsInterop.isJSBracketCall(sym)) { if (enclosingOwner is OwnerKind.JSNonNative) { reporter.error(tree.pos, - "@JSBracketCall is not allowed in Scala.js-defined JS classes") + "@JSBracketCall is not allowed in non-native JS classes") } else { // JS bracket calls must have at least one non-repeated parameter sym.tpe.paramss match { @@ -899,7 +899,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent val alts = sym.owner.info.member(sym.name).filter(_.isMethod) if (alts.isOverloaded) { reporter.error(tree.pos, - "Private methods in Scala.js-defined JS classes cannot be " + + "Private methods in non-native JS classes cannot be " + "overloaded. Use different names instead.") } } @@ -908,7 +908,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent if (sym.isMethod && (sym.hasAccessBoundary && !sym.isProtected) && !sym.isFinal && !sym.isClassConstructor) { reporter.error(tree.pos, - "Qualified private members in Scala.js-defined JS classes " + + "Qualified private members in non-native JS classes " + "must be final") } @@ -916,7 +916,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent if (sym.owner.isTrait && sym.isTerm && !sym.isConstructor) { if (sym.isMethod && isPrivateMaybeWithin(sym)) { reporter.error(tree.pos, - "A Scala.js-defined JS trait cannot contain private members") + "A non-native JS trait cannot contain private members") } else if (!sym.isDeferred) { /* Tell the back-end not emit this thing. In fact, this only * matters for mixed-in members created from this member. @@ -932,7 +932,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent // ok case _ => reporter.error(tree.rhs.pos, - "In Scala.js-defined JS traits, defs with parentheses " + + "In non-native JS traits, defs with parentheses " + "must be abstract.") } } @@ -953,7 +953,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent // ok case _ => reporter.error(tree.rhs.pos, - "Members of Scala.js-defined JS traits must either be " + + "Members of non-native JS traits must either be " + "abstract, or their right-hand-side must be " + "`js.undefined`.") } @@ -971,8 +971,8 @@ abstract class PrepJSInterop extends plugins.PluginComponent * getters, accessors, param accessors, abstract members, synthetic * methods (to avoid double errors with case classes, e.g. generated * copy method), js.Functions and js.ThisFunctions (they need abstract - * methods for SAM treatment), and any member of a Scala.js-defined - * JS class/trait. + * methods for SAM treatment), and any member of a non-native JS + * class/trait. */ } else if (jsPrimitives.isJavaScriptPrimitive(sym)) { // No check for primitives. We trust our own standard library. @@ -1367,7 +1367,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent def isCompilerAnnotation(annotation: AnnotationInfo): Boolean = { annotation.symbol == ExposedJSMemberAnnot || annotation.symbol == RawJSTypeAnnot || - annotation.symbol == SJSDefinedAnonymousClassAnnotation || + annotation.symbol == AnonymousJSClassAnnotation || annotation.symbol == JSOptionalAnnotation } @@ -1413,9 +1413,9 @@ object PrepJSInterop { val JSNativeClass = new OwnerKind(0x04) /** A native JS object, which extends js.Any. */ val JSNativeMod = new OwnerKind(0x08) - /** A Scala.js-defined JS class/trait. */ + /** A non-native JS class/trait. */ val JSClass = new OwnerKind(0x10) - /** A Scala.js-defined JS oobject. */ + /** A non-native JS object. */ val JSMod = new OwnerKind(0x20) /** A Scala class/trait that extends Enumeration. */ val EnumClass = new OwnerKind(0x40) @@ -1443,8 +1443,6 @@ object PrepJSInterop { /** A raw JS type, i.e., something extending js.Any. */ val RawJSType = JSNative | JSNonNative - /** Anything defined in Scala.js, i.e., anything but a native JS declaration. */ - val ScalaJSDefined = ScalaThing | JSNonNative /** Any kind of class/trait, i.e., a Scala or raw JS class/trait. */ val AnyClass = ScalaClass | JSNativeClass | JSClass } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/InternalAnnotationsTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/InternalAnnotationsTest.scala index 759521d419..145481baa0 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/InternalAnnotationsTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/InternalAnnotationsTest.scala @@ -22,8 +22,8 @@ class InternalAnnotationsTest extends DirectTest with TestHelpers { } @Test - def sjsDefinedAnonymousClass: Unit = { - test("SJSDefinedAnonymousClass") + def anonymousJSClass: Unit = { + test("AnonymousJSClass") } @Test diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index 64fd189f73..c0a17879bc 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -1532,7 +1532,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Only a static object whose companion class is a Scala.js-defined JS class may export its members as static. + |newSource1.scala:7: error: Only a static object whose companion class is a non-native JS class may export its members as static. | @JSExportStatic | ^ """ @@ -1582,7 +1582,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:6: error: Only a static object whose companion class is a Scala.js-defined JS class may export its members as static. + |newSource1.scala:6: error: Only a static object whose companion class is a non-native JS class may export its members as static. | @JSExportStatic | ^ """ @@ -1596,7 +1596,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:6: error: Only a static object whose companion class is a Scala.js-defined JS class may export its members as static. + |newSource1.scala:6: error: Only a static object whose companion class is a non-native JS class may export its members as static. | @JSExportStatic | ^ """ @@ -1612,7 +1612,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Only a static object whose companion class is a Scala.js-defined JS class may export its members as static. + |newSource1.scala:8: error: Only a static object whose companion class is a non-native JS class may export its members as static. | @JSExportStatic | ^ """ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index 0572755ff3..7b0252ef89 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -470,13 +470,13 @@ class JSInteropTest extends DirectTest with TestHelpers { for { outer <- Seq("class", "trait") inner <- Seq("class", "trait", "object") - innerSJSDefined <- Seq(false, true) + innerIsJSType <- Seq(false, true) } yield { val jsGlobalAnnot = if (outer == "trait") "" else "@JSGlobal" val innerLine = - if (innerSJSDefined) s"$inner A extends js.Object" + if (innerIsJSType) s"$inner A extends js.Object" else s"$inner A" s""" @js.native $jsGlobalAnnot @@ -542,7 +542,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } @Test - def noScalaJSDefinedClassObjectInsideNativeJSObject: Unit = { + def noNonNativeJSTypesInsideNativeJSObject: Unit = { for { inner <- Seq("class", "object") @@ -555,7 +555,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } """ hasErrors s""" - |newSource1.scala:8: error: Native JS objects cannot contain inner Scala.js-defined JS classes or objects + |newSource1.scala:8: error: Native JS objects cannot contain inner non-native JS classes or objects | $inner A extends js.Object | ${" " * inner.length} ^ """ @@ -762,10 +762,10 @@ class JSInteropTest extends DirectTest with TestHelpers { for { outer <- outers inner <- inners - outerSJSDefined <- Seq(false, true) + outerIsJSType <- Seq(false, true) } yield { val outerLine = - if (outerSJSDefined) s"$outer A extends js.Object" + if (outerIsJSType) s"$outer A extends js.Object" else s"$outer A" val jsGlobalAnnot = @@ -1249,7 +1249,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } @Test - def noNativeClassObjectInsideScalaJSDefinedObject: Unit = { + def noNativeClassObjectInsideNonNativeJSObject: Unit = { for { inner <- Seq("class", "object") @@ -1262,7 +1262,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } """ hasErrors s""" - |newSource1.scala:8: error: Scala.js-defined JS objects may not have inner native JS classes or objects + |newSource1.scala:8: error: non-native JS objects may not have inner native JS classes or objects | $inner B extends js.Object | ${" " * inner.length} ^ """ @@ -2032,7 +2032,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } @Test - def scalaJSDefinedJSNameOverrideErrors: Unit = { + def nonNativeJSTypesNameOverrideErrors: Unit = { """ abstract class A extends js.Object { def bar(): Int @@ -2355,7 +2355,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } @Test - def scalaJSDefinedJSNameWithSymbolOverrideErrors: Unit = { + def nonNativeJSTypesJSNameWithSymbolOverrideErrors: Unit = { """ object Syms { val sym1 = js.Symbol() @@ -2785,7 +2785,7 @@ class JSInteropTest extends DirectTest with TestHelpers { object A extends js.Object """ hasErrors """ - |newSource1.scala:5: error: Implementation restriction: constructors of Scala.js-defined JS classes cannot have default parameters if their companion module is JS native. + |newSource1.scala:5: error: Implementation restriction: constructors of non-native JS classes cannot have default parameters if their companion module is JS native. | class A(x: Int = 1) extends js.Object | ^ """ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala index 4b320c3d7e..1ddbccca17 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala @@ -31,22 +31,22 @@ class JSOptionalTest extends DirectTest with TestHelpers { } """ hasErrors s""" - |newSource1.scala:6: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. + |newSource1.scala:6: error: Members of non-native JS traits must either be abstract, or their right-hand-side must be `js.undefined`. | val a1: js.UndefOr[Int] = 5 | ^ - |newSource1.scala:7: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. + |newSource1.scala:7: error: Members of non-native JS traits must either be abstract, or their right-hand-side must be `js.undefined`. | val a2: Int = 5 | ^ - |newSource1.scala:9: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. + |newSource1.scala:9: error: Members of non-native JS traits must either be abstract, or their right-hand-side must be `js.undefined`. | def b1: js.UndefOr[Int] = 5 | ^ - |newSource1.scala:10: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. + |newSource1.scala:10: error: Members of non-native JS traits must either be abstract, or their right-hand-side must be `js.undefined`. | def b2: Int = 5 | ^ - |newSource1.scala:12: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. + |newSource1.scala:12: error: Members of non-native JS traits must either be abstract, or their right-hand-side must be `js.undefined`. | var c1: js.UndefOr[Int] = 5 | ^ - |newSource1.scala:13: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. + |newSource1.scala:13: error: Members of non-native JS traits must either be abstract, or their right-hand-side must be `js.undefined`. | var c2: Int = 5 | ^ """ @@ -72,10 +72,10 @@ class JSOptionalTest extends DirectTest with TestHelpers { } """ hasErrors s""" - |newSource1.scala:14: error: Cannot override concrete val a1: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + |newSource1.scala:14: error: Cannot override concrete val a1: scala.scalajs.js.UndefOr[Int] from A in a non-native JS trait. | override val a1: js.UndefOr[Int] = js.undefined | ^ - |newSource1.scala:17: error: Cannot override concrete def b1: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + |newSource1.scala:17: error: Cannot override concrete def b1: scala.scalajs.js.UndefOr[Int] from A in a non-native JS trait. | override def b1: js.UndefOr[Int] = js.undefined | ^ """ @@ -94,10 +94,10 @@ class JSOptionalTest extends DirectTest with TestHelpers { } """ hasErrors s""" - |newSource1.scala:13: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + |newSource1.scala:13: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a non-native JS trait. | override val a: js.UndefOr[Int] = js.undefined | ^ - |newSource1.scala:14: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + |newSource1.scala:14: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a non-native JS trait. | override def b: js.UndefOr[Int] = js.undefined | ^ """ @@ -119,10 +119,10 @@ class JSOptionalTest extends DirectTest with TestHelpers { } """ hasErrors s""" - |newSource1.scala:16: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + |newSource1.scala:16: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a non-native JS trait. | override val a: js.UndefOr[Int] = js.undefined | ^ - |newSource1.scala:17: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + |newSource1.scala:17: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a non-native JS trait. | override def b: js.UndefOr[Int] = js.undefined | ^ """ @@ -138,16 +138,16 @@ class JSOptionalTest extends DirectTest with TestHelpers { } """ hasErrors s""" - |newSource1.scala:6: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. + |newSource1.scala:6: error: In non-native JS traits, defs with parentheses must be abstract. | def a(): js.UndefOr[Int] = js.undefined | ^ - |newSource1.scala:7: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. + |newSource1.scala:7: error: In non-native JS traits, defs with parentheses must be abstract. | def b(x: Int): js.UndefOr[Int] = js.undefined | ^ |newSource1.scala:8: error: Raw JS setters must return Unit | def c_=(v: Int): js.UndefOr[Int] = js.undefined | ^ - |newSource1.scala:8: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. + |newSource1.scala:8: error: In non-native JS traits, defs with parentheses must be abstract. | def c_=(v: Int): js.UndefOr[Int] = js.undefined | ^ """ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/NonNativeJSTypeTest.scala similarity index 77% rename from compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala rename to compiler/src/test/scala/org/scalajs/core/compiler/test/NonNativeJSTypeTest.scala index 7d705b01fa..5e1546e59b 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/NonNativeJSTypeTest.scala @@ -7,7 +7,7 @@ import org.junit.Ignore // scalastyle:off line.size.limit -class ScalaJSDefinedTest extends DirectTest with TestHelpers { +class NonNativeJSTypeTest extends DirectTest with TestHelpers { override def preamble: String = """ @@ -21,7 +21,7 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { class A extends js.Any """ hasErrors """ - |newSource1.scala:5: error: A Scala.js-defined JS class cannot directly extend AnyRef. It must extend a JS class (native or not). + |newSource1.scala:5: error: A non-native JS class cannot directly extend AnyRef. It must extend a JS class (native or not). | class A extends js.Any | ^ """ @@ -30,7 +30,7 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { object A extends js.Any """ hasErrors """ - |newSource1.scala:5: error: A Scala.js-defined JS object cannot directly extend AnyRef. It must extend a JS class (native or not). + |newSource1.scala:5: error: A non-native JS object cannot directly extend AnyRef. It must extend a JS class (native or not). | object A extends js.Any | ^ """ @@ -53,16 +53,16 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: A Scala.js-defined JS class cannot directly extend a native JS trait. + |newSource1.scala:8: error: A non-native JS class cannot directly extend a native JS trait. | class A extends NativeTrait | ^ - |newSource1.scala:10: error: A Scala.js-defined JS trait cannot directly extend a native JS trait. + |newSource1.scala:10: error: A non-native JS trait cannot directly extend a native JS trait. | trait B extends NativeTrait | ^ - |newSource1.scala:12: error: A Scala.js-defined JS object cannot directly extend a native JS trait. + |newSource1.scala:12: error: A non-native JS object cannot directly extend a native JS trait. | object C extends NativeTrait | ^ - |newSource1.scala:15: error: A Scala.js-defined JS class cannot directly extend a native JS trait. + |newSource1.scala:15: error: A non-native JS class cannot directly extend a native JS trait. | val x = new NativeTrait {} | ^ """ @@ -76,7 +76,7 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:6: error: A Scala.js-defined JavaScript class cannot declare a method named `apply` without `@JSName` + |newSource1.scala:6: error: A non-native JS class cannot declare a method named `apply` without `@JSName` | def apply(arg: Int): Int = arg | ^ """ @@ -91,7 +91,7 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: @JSBracketAccess is not allowed in Scala.js-defined JS classes + |newSource1.scala:7: error: @JSBracketAccess is not allowed in non-native JS classes | def foo(index: Int, arg: Int): Int = arg | ^ """ @@ -106,7 +106,7 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: @JSBracketCall is not allowed in Scala.js-defined JS classes + |newSource1.scala:7: error: @JSBracketCall is not allowed in non-native JS classes | def foo(m: String, arg: Int): Int = arg | ^ """ @@ -121,10 +121,10 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:6: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. + |newSource1.scala:6: error: Private methods in non-native JS classes cannot be overloaded. Use different names instead. | private def foo(i: Int): Int = i | ^ - |newSource1.scala:7: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. + |newSource1.scala:7: error: Private methods in non-native JS classes cannot be overloaded. Use different names instead. | private def foo(s: String): String = s | ^ """ @@ -136,10 +136,10 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:6: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. + |newSource1.scala:6: error: Private methods in non-native JS classes cannot be overloaded. Use different names instead. | private def foo(i: Int): Int = i | ^ - |newSource1.scala:7: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. + |newSource1.scala:7: error: Private methods in non-native JS classes cannot be overloaded. Use different names instead. | private def foo(s: String): String = s | ^ """ @@ -153,10 +153,10 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. + |newSource1.scala:7: error: Private methods in non-native JS classes cannot be overloaded. Use different names instead. | private[Enclosing] def foo(i: Int): Int = i | ^ - |newSource1.scala:8: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. + |newSource1.scala:8: error: Private methods in non-native JS classes cannot be overloaded. Use different names instead. | private def foo(s: String): String = s | ^ """ @@ -168,7 +168,7 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:6: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. + |newSource1.scala:6: error: Private methods in non-native JS classes cannot be overloaded. Use different names instead. | private def foo(i: Int): Int = i | ^ """ @@ -182,7 +182,7 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. + |newSource1.scala:7: error: Private methods in non-native JS classes cannot be overloaded. Use different names instead. | private[Enclosing] def foo(i: Int): Int = i | ^ """ @@ -204,13 +204,13 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:7: error: Qualified private members in non-native JS classes must be final | private[Enclosing] def foo(i: Int): Int = i | ^ - |newSource1.scala:8: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:8: error: Qualified private members in non-native JS classes must be final | private[Enclosing] val x: Int = 3 | ^ - |newSource1.scala:9: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:9: error: Qualified private members in non-native JS classes must be final | private[Enclosing] var y: Int = 5 | ^ """ @@ -225,13 +225,13 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:7: error: Qualified private members in non-native JS classes must be final | private[Enclosing] def foo(i: Int): Int = i | ^ - |newSource1.scala:8: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:8: error: Qualified private members in non-native JS classes must be final | private[Enclosing] val x: Int = 3 | ^ - |newSource1.scala:9: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:9: error: Qualified private members in non-native JS classes must be final | private[Enclosing] var y: Int = 5 | ^ """ @@ -250,13 +250,13 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:7: error: Qualified private members in non-native JS classes must be final | private[Enclosing] def foo(i: Int): Int | ^ - |newSource1.scala:8: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:8: error: Qualified private members in non-native JS classes must be final | private[Enclosing] val x: Int | ^ - |newSource1.scala:9: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:9: error: Qualified private members in non-native JS classes must be final | private[Enclosing] var y: Int | ^ """ @@ -271,13 +271,13 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:7: error: Qualified private members in non-native JS classes must be final | private[Enclosing] def foo(i: Int): Int | ^ - |newSource1.scala:8: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:8: error: Qualified private members in non-native JS classes must be final | private[Enclosing] val x: Int | ^ - |newSource1.scala:9: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:9: error: Qualified private members in non-native JS classes must be final | private[Enclosing] var y: Int | ^ """ @@ -539,10 +539,10 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:6: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. + |newSource1.scala:6: error: In non-native JS traits, defs with parentheses must be abstract. | def foo(x: Int): Int = x + 1 | ^ - |newSource1.scala:7: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. + |newSource1.scala:7: error: In non-native JS traits, defs with parentheses must be abstract. | def bar[A](x: A): A = x | ^ """ diff --git a/ir/src/main/scala/org/scalajs/core/ir/ClassKind.scala b/ir/src/main/scala/org/scalajs/core/ir/ClassKind.scala index 2e895212a0..473ea47789 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ClassKind.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ClassKind.scala @@ -37,7 +37,7 @@ sealed abstract class ClassKind { case _ => false } - def isAnyScalaJSDefinedClass: Boolean = this match { + def isAnyNonNativeClass: Boolean = this match { case Class | ModuleClass | JSClass | JSModuleClass => true case _ => false } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 992ed2e58f..1369ac4573 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -463,9 +463,9 @@ object Trees { /** Selects a property inherited from the parent class of `cls` on `receiver`. * - * `cls` must be a Scala.js-defined JS class. + * `cls` must be a non-native JS class. * - * Given the Scala.js-defined JS classes + * Given the non-native JS classes * * {{{ * class Bar extends js.Object @@ -500,9 +500,9 @@ object Trees { /** Calls a method inherited from the parent class of `cls` on `receiver`. * - * `cls` must be a Scala.js-defined JS class. + * `cls` must be a non-native JS class. * - * Given the Scala.js-defined JS classes + * Given the non-native JS classes * * {{{ * class Bar extends js.Object @@ -540,10 +540,10 @@ object Trees { val tpe = AnyType } - /** Super constructor call in the constructor of a Scala.js-defined JS class. + /** Super constructor call in the constructor of a non-native JS class. * * Exactly one such node must appear in the constructor of a - * Scala.js-defined JS class, at the top-level (possibly as a direct child + * non-native JS class, at the top-level (possibly as a direct child * of a top-level `Block`). Any other use of this node is invalid. * * Statements before this node, as well as the `args`, cannot contain any @@ -587,7 +587,7 @@ object Trees { * `cls` must represent a non-trait JS class (native or not). * * This is used typically to instantiate a JS class, and most importantly - * if it is a Scala.js-defined JS class. Given the class + * if it is a non-native JS class. Given the class * * {{{ * class Foo(x: Int) extends js.Object @@ -605,8 +605,8 @@ object Trees { * JSBinaryOp(instanceof, o, LoadJSConstructor(ClassType("Foo"))) * }}} * - * If `Foo` is Scala.js-defined, the presence of this node makes it - * instantiable, and therefore reachable. + * If `Foo` is non-native, the presence of this node makes it instantiable, + * and therefore reachable. */ case class LoadJSConstructor(cls: ClassType)( implicit val pos: Position) extends Tree { diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSExportStatic.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSExportStatic.scala index 8af0820b4a..f4eabc7429 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSExportStatic.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSExportStatic.scala @@ -16,7 +16,7 @@ import scala.annotation.meta._ * static member of the companion class. * * This annotation may only be used on members of a Scala `object` whose - * companion class is a Scala.js-defined JavaScript class. The annotated + * companion class is a non-native JS class. The annotated * member will be available as a static member of the companion class. * * @see [[https://www.scala-js.org/doc/export-to-javascript.html Export Scala.js APIs to JavaScript]] diff --git a/library/src/main/scala/scala/scalajs/js/annotation/internal/AnonymousJSClass.scala b/library/src/main/scala/scala/scalajs/js/annotation/internal/AnonymousJSClass.scala new file mode 100644 index 0000000000..5c7e5867a8 --- /dev/null +++ b/library/src/main/scala/scala/scalajs/js/annotation/internal/AnonymousJSClass.scala @@ -0,0 +1,10 @@ +package scala.scalajs.js.annotation.internal + +/** IMPLEMENTATION DETAIL: Marks anonymous non-native JS classes. + * + * This annotation is added automatically by the compiler to anonymous + * JS classes (that are not lambdas). + * + * Do not use this annotation yourself. + */ +class AnonymousJSClass extends scala.annotation.Annotation diff --git a/library/src/main/scala/scala/scalajs/js/annotation/internal/ExposedJSMember.scala b/library/src/main/scala/scala/scalajs/js/annotation/internal/ExposedJSMember.scala index 91ebd44ff3..e23e716a11 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/internal/ExposedJSMember.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/internal/ExposedJSMember.scala @@ -12,7 +12,7 @@ package scala.scalajs.js.annotation.internal /** IMPLEMENTATION DETAIL: Marks the annotated member as exposed as a JS member. * * This annotation is added automatically by the compiler to all public and - * protected members of a Scala.js-defined JS class. It marks the annotated + * protected members of a non-native JS class. It marks the annotated * member as being exposed as a JS member. * * Do not use this annotation yourself. diff --git a/library/src/main/scala/scala/scalajs/js/annotation/internal/JSOptional.scala b/library/src/main/scala/scala/scalajs/js/annotation/internal/JSOptional.scala index 4d4ab3b3fa..b5320366b9 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/internal/JSOptional.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/internal/JSOptional.scala @@ -10,7 +10,7 @@ package scala.scalajs.js.annotation.internal import scala.annotation.meta._ -/** IMPLEMENTATION DETAIL: Marks concrete members of Scala.js-defined JS +/** IMPLEMENTATION DETAIL: Marks concrete members of non-native JS * traits, so that they can be identified by the back-end not to emit them. * * Internally, such members are known as "optional", in reference to their diff --git a/library/src/main/scala/scala/scalajs/js/annotation/internal/SJSDefinedAnonymousClass.scala b/library/src/main/scala/scala/scalajs/js/annotation/internal/SJSDefinedAnonymousClass.scala deleted file mode 100644 index e424c88c4d..0000000000 --- a/library/src/main/scala/scala/scalajs/js/annotation/internal/SJSDefinedAnonymousClass.scala +++ /dev/null @@ -1,10 +0,0 @@ -package scala.scalajs.js.annotation.internal - -/** IMPLEMENTATION DETAIL: Marks anonymous Scala.js-defined JS classes. - * - * This annotation is added automatically by the compiler to Scala.js defined - * anonymous classes. - * - * Do not use this annotation yourself. - */ -class SJSDefinedAnonymousClass extends scala.annotation.Annotation diff --git a/project/Build.scala b/project/Build.scala index e06dd363d4..c5a820279f 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1421,7 +1421,7 @@ object Build { jsExecutionFiles in Test := { val resourceDir = (resourceDirectory in (LocalProject("testSuite"), Test)).value - val f = FileVirtualJSFile(resourceDir / "ScalaJSDefinedTestNatives.js") + val f = FileVirtualJSFile(resourceDir / "NonNativeJSTypeTestNatives.js") f +: (jsExecutionFiles in Test).value } } diff --git a/scalalib/overrides/scala/Enumeration.scala b/scalalib/overrides/scala/Enumeration.scala index bdc170156a..c0699fff50 100644 --- a/scalalib/overrides/scala/Enumeration.scala +++ b/scalalib/overrides/scala/Enumeration.scala @@ -281,4 +281,4 @@ abstract class Enumeration (initial: Int) extends Serializable { def apply() = newBuilder } } -} \ No newline at end of file +} diff --git a/test-suite-ex/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTestEx.scala b/test-suite-ex/src/test/scala/org/scalajs/testsuite/jsinterop/NonNativeJSTypeTestEx.scala similarity index 91% rename from test-suite-ex/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTestEx.scala rename to test-suite-ex/src/test/scala/org/scalajs/testsuite/jsinterop/NonNativeJSTypeTestEx.scala index d2e31f07ae..c5529a3d63 100644 --- a/test-suite-ex/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTestEx.scala +++ b/test-suite-ex/src/test/scala/org/scalajs/testsuite/jsinterop/NonNativeJSTypeTestEx.scala @@ -13,13 +13,13 @@ import org.junit.Assert._ import scala.scalajs.js import scala.scalajs.js.annotation._ -/** Additional tests for Scala.js-defined JS classes that have to be in a +/** Additional tests for non-native JS classes that have to be in a * separate codebase than testSuite to be meaningful. * * If moved to testSuite, those tests "fail to fail" due to mass effects * produced by the immensity of the testSuite codebase. */ -class ScalaJSDefinedTestEx { +class NonNativeJSTypeTestEx { @Test def constructor_property_on_the_prototype_issue_1963(): Unit = { class ParentClass extends js.Object diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTestSeparateRun.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/jsinterop/NonNativeTypeTestSeparateRun.scala similarity index 89% rename from test-suite/js/src/main/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTestSeparateRun.scala rename to test-suite/js/src/main/scala/org/scalajs/testsuite/jsinterop/NonNativeTypeTestSeparateRun.scala index 431bcf3325..e97e0ef3c5 100644 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTestSeparateRun.scala +++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/jsinterop/NonNativeTypeTestSeparateRun.scala @@ -10,10 +10,10 @@ package org.scalajs.testsuite.jsinterop import scala.scalajs.js import scala.scalajs.js.annotation._ -/** Elements of ScalaJSDefinedTest in `src/test/` to be compiled in a +/** Elements of NonNativeJSTypeTest in `src/test/` to be compiled in a * separate compiler run, to test separate compilation. */ -object ScalaJSDefinedTestSeparateRun { +object NonNativeJSTypeTestSeparateRun { class SimpleParentClass extends js.Object { def foo(x: Int): Int = x + 1 diff --git a/test-suite/js/src/test/resources/ScalaJSDefinedTestNatives.js b/test-suite/js/src/test/resources/NonNativeJSTypeTestNatives.js similarity index 65% rename from test-suite/js/src/test/resources/ScalaJSDefinedTestNatives.js rename to test-suite/js/src/test/resources/NonNativeJSTypeTestNatives.js index 54e4cb44a6..42c484acdf 100644 --- a/test-suite/js/src/test/resources/ScalaJSDefinedTestNatives.js +++ b/test-suite/js/src/test/resources/NonNativeJSTypeTestNatives.js @@ -2,47 +2,47 @@ var $g = (typeof global !== "undefined" && global.Object === Object) ? global : this; - var ScalaJSDefinedTestNativeParentClass = function(x) { + var NonNativeJSTypeTestNativeParentClass = function(x) { $g.Object.call(this); this.x = x; }; - ScalaJSDefinedTestNativeParentClass.prototype.foo = function(s) { + NonNativeJSTypeTestNativeParentClass.prototype.foo = function(s) { return s + this.x; }; - ScalaJSDefinedTestNativeParentClass.prototype.methodWithDefault = function (x) { + NonNativeJSTypeTestNativeParentClass.prototype.methodWithDefault = function (x) { return x || 5; } - $g.Object.defineProperty(ScalaJSDefinedTestNativeParentClass.prototype, "bar", { + $g.Object.defineProperty(NonNativeJSTypeTestNativeParentClass.prototype, "bar", { "configurable": false, "enumerable": false, "get": function() { return this.x << 1; // x * 2 would not return an Int, technically } }); - $g.ScalaJSDefinedTestNativeParentClass = ScalaJSDefinedTestNativeParentClass; + $g.NonNativeJSTypeTestNativeParentClass = NonNativeJSTypeTestNativeParentClass; /* Deferred members: * val x: Int * def bar(y: Int): Int */ - var ScalaJSDefinedTestNativeParentClassWithDeferred = function() { + var NonNativeJSTypeTestNativeParentClassWithDeferred = function() { $g.Object.call(this); }; - ScalaJSDefinedTestNativeParentClassWithDeferred.prototype.foo = function(y) { + NonNativeJSTypeTestNativeParentClassWithDeferred.prototype.foo = function(y) { return (this.bar((y + 4) | 0) + this.x) | 0; }; - $g.ScalaJSDefinedTestNativeParentClassWithDeferred = - ScalaJSDefinedTestNativeParentClassWithDeferred; + $g.NonNativeJSTypeTestNativeParentClassWithDeferred = + NonNativeJSTypeTestNativeParentClassWithDeferred; - var ScalaJSDefinedTestNativeParentClassWithVarargs = function(x) { + var NonNativeJSTypeTestNativeParentClassWithVarargs = function(x) { $g.Object.call(this); this.x = x; this.args = []; for (var i = 1; i != arguments.length; ++i) this.args.push(arguments[i]); }; - $g.ScalaJSDefinedTestNativeParentClassWithVarargs = - ScalaJSDefinedTestNativeParentClassWithVarargs; + $g.NonNativeJSTypeTestNativeParentClassWithVarargs = + NonNativeJSTypeTestNativeParentClassWithVarargs; var ConstructorDefaultParam = function(foo) { $g.Object.call(this); diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/NonNativeJSTypeTest.scala similarity index 97% rename from test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala rename to test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/NonNativeJSTypeTest.scala index cf61baf085..34b80911a2 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/NonNativeJSTypeTest.scala @@ -18,9 +18,9 @@ import org.scalajs.testsuite.utils.JSAssert._ import org.scalajs.testsuite.utils.Platform import org.scalajs.testsuite.utils.AssertThrows.assertThrows -class ScalaJSDefinedTest { - import org.scalajs.testsuite.jsinterop.{ScalaJSDefinedTestSeparateRun => SepRun} - import ScalaJSDefinedTest._ +class NonNativeJSTypeTest { + import org.scalajs.testsuite.jsinterop.{NonNativeJSTypeTestSeparateRun => SepRun} + import NonNativeJSTypeTest._ @Test def minimal_definition(): Unit = { val obj = new Minimal @@ -962,25 +962,25 @@ class ScalaJSDefinedTest { assertEquals(-1, dyn.dependent(8)) } - @Test def `constructors_with_default_parameters_(ScalaJSDefined/-)`(): Unit = { + @Test def `constructors_with_default_parameters_(NonNative/-)`(): Unit = { assertEquals(-1, new ConstructorDefaultParamJSNonNativeNone().foo) assertEquals(1, new ConstructorDefaultParamJSNonNativeNone(1).foo) assertEquals(5, new ConstructorDefaultParamJSNonNativeNone(5).foo) } - @Test def `constructors_with_default_parameters_(ScalaJSDefined/ScalaJSDefined)`(): Unit = { + @Test def `constructors_with_default_parameters_(NonNative/NonNative)`(): Unit = { assertEquals(-1, new ConstructorDefaultParamJSNonNativeJSNonNative().foo) assertEquals(1, new ConstructorDefaultParamJSNonNativeJSNonNative(1).foo) assertEquals(5, new ConstructorDefaultParamJSNonNativeJSNonNative(5).foo) } - @Test def `constructors_with_default_parameters_(ScalaJSDefined/Scala)`(): Unit = { + @Test def `constructors_with_default_parameters_(NonNative/Scala)`(): Unit = { assertEquals(-1, new ConstructorDefaultParamJSNonNativeScala().foo) assertEquals(1, new ConstructorDefaultParamJSNonNativeScala(1).foo) assertEquals(5, new ConstructorDefaultParamJSNonNativeScala(5).foo) } - @Test def `constructors_with_default_parameters_(Scala/ScalaJSDefined)`(): Unit = { + @Test def `constructors_with_default_parameters_(Scala/NonNative)`(): Unit = { assertEquals(-1, new ConstructorDefaultParamScalaJSNonNative().foo) assertEquals(1, new ConstructorDefaultParamScalaJSNonNative(1).foo) assertEquals(5, new ConstructorDefaultParamScalaJSNonNative(5).foo) @@ -998,7 +998,7 @@ class ScalaJSDefinedTest { assertEquals(5, new ConstructorDefaultParamJSNativeScala(5).foo) } - @Test def `constructors_with_default_parameters_(Native/ScalaJSDefined)`(): Unit = { + @Test def `constructors_with_default_parameters_(Native/NonNative)`(): Unit = { assertEquals(-1, new ConstructorDefaultParamJSNativeJSNonNative().foo) assertEquals(1, new ConstructorDefaultParamJSNativeJSNonNative(1).foo) assertEquals(5, new ConstructorDefaultParamJSNativeJSNonNative(5).foo) @@ -1495,10 +1495,10 @@ class ScalaJSDefinedTest { } } -object ScalaJSDefinedTest { +object NonNativeJSTypeTest { - // Defined in test-suite/src/test/resources/ScalaJSDefinedTestNatives.js - @JSGlobal("ScalaJSDefinedTestNativeParentClass") + // Defined in test-suite/src/test/resources/NonNativeJSTypeTestNatives.js + @JSGlobal("NonNativeJSTypeTestNativeParentClass") @js.native class NativeParentClass(val x: Int) extends js.Object { def foo(s: String): String = js.native @@ -1519,8 +1519,8 @@ object ScalaJSDefinedTest { val x: Int } - // Defined in test-suite/src/test/resources/ScalaJSDefinedTestNatives.js - @JSGlobal("ScalaJSDefinedTestNativeParentClassWithDeferred") + // Defined in test-suite/src/test/resources/NonNativeJSTypeTestNatives.js + @JSGlobal("NonNativeJSTypeTestNativeParentClassWithDeferred") @js.native abstract class NativeParentClassWithDeferred extends NativeTraitWithDeferred { def foo(y: Int): Int = js.native // = bar(y + 4) + x @@ -1528,8 +1528,8 @@ object ScalaJSDefinedTest { def bar(y: Int): Int } - // Defined in test-suite/src/test/resources/ScalaJSDefinedTestNatives.js - @JSGlobal("ScalaJSDefinedTestNativeParentClassWithVarargs") + // Defined in test-suite/src/test/resources/NonNativeJSTypeTestNatives.js + @JSGlobal("NonNativeJSTypeTestNativeParentClassWithVarargs") @js.native class NativeParentClassWithVarargs( _x: Int, _args: Int*) extends js.Object { diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/FloatBufferTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/FloatBufferTest.scala index 12198cb68b..1437349300 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/FloatBufferTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/FloatBufferTest.scala @@ -113,4 +113,4 @@ class ReadOnlyFloatViewOfWrappedByteBufferLittleEndianTest extends ReadOnlyFloatViewOfByteBufferTest(new WrappedByteBufferFactory, ByteOrder.LITTLE_ENDIAN) class ReadOnlyFloatViewOfSlicedAllocByteBufferLittleEndianTest - extends ReadOnlyFloatViewOfByteBufferTest(new SlicedAllocByteBufferFactory, ByteOrder.LITTLE_ENDIAN) \ No newline at end of file + extends ReadOnlyFloatViewOfByteBufferTest(new SlicedAllocByteBufferFactory, ByteOrder.LITTLE_ENDIAN) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/IntBufferTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/IntBufferTest.scala index f34fc2098a..90aeabbae5 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/IntBufferTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/IntBufferTest.scala @@ -113,4 +113,4 @@ class ReadOnlyIntViewOfWrappedByteBufferLittleEndianTest extends ReadOnlyIntViewOfByteBufferTest(new WrappedByteBufferFactory, ByteOrder.LITTLE_ENDIAN) class ReadOnlyIntViewOfSlicedAllocByteBufferLittleEndianTest - extends ReadOnlyIntViewOfByteBufferTest(new SlicedAllocByteBufferFactory, ByteOrder.LITTLE_ENDIAN) \ No newline at end of file + extends ReadOnlyIntViewOfByteBufferTest(new SlicedAllocByteBufferFactory, ByteOrder.LITTLE_ENDIAN) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/LongBufferTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/LongBufferTest.scala index c5f33f92a8..cd1c8084b7 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/LongBufferTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/LongBufferTest.scala @@ -113,4 +113,4 @@ class ReadOnlyLongViewOfWrappedByteBufferLittleEndianTest extends ReadOnlyLongViewOfByteBufferTest(new WrappedByteBufferFactory, ByteOrder.LITTLE_ENDIAN) class ReadOnlyLongViewOfSlicedAllocByteBufferLittleEndianTest - extends ReadOnlyLongViewOfByteBufferTest(new SlicedAllocByteBufferFactory, ByteOrder.LITTLE_ENDIAN) \ No newline at end of file + extends ReadOnlyLongViewOfByteBufferTest(new SlicedAllocByteBufferFactory, ByteOrder.LITTLE_ENDIAN) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/ShortBufferTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/ShortBufferTest.scala index 6400bcefe5..03b5b52007 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/ShortBufferTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/ShortBufferTest.scala @@ -113,4 +113,4 @@ class ReadOnlyShortViewOfWrappedByteBufferLittleEndianTest extends ReadOnlyShortViewOfByteBufferTest(new WrappedByteBufferFactory, ByteOrder.LITTLE_ENDIAN) class ReadOnlyShortViewOfSlicedAllocByteBufferLittleEndianTest - extends ReadOnlyShortViewOfByteBufferTest(new SlicedAllocByteBufferFactory, ByteOrder.LITTLE_ENDIAN) \ No newline at end of file + extends ReadOnlyShortViewOfByteBufferTest(new SlicedAllocByteBufferFactory, ByteOrder.LITTLE_ENDIAN) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index 6f81b55b7d..685b5e2dd3 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -138,7 +138,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { def genConstructor(tree: LinkedClass)( implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { - assert(tree.kind.isAnyScalaJSDefinedClass) + assert(tree.kind.isAnyNonNativeClass) assert(tree.superClass.isDefined || tree.name.name == Definitions.ObjectClass, s"Class ${tree.name.name} is missing a parent class") diff --git 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 index 34ef724bf4..1ab844550a 100644 --- 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 @@ -351,7 +351,7 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, } // Class definition - if (linkedClass.hasInstances && kind.isAnyScalaJSDefinedClass) { + if (linkedClass.hasInstances && kind.isAnyNonNativeClass) { val ctor = classTreeCache.constructor.getOrElseUpdate( classEmitter.genConstructor(linkedClass)(classCache)) diff --git 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 index f529f8d4fa..3cea60bbff 100644 --- 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 @@ -1165,7 +1165,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case JSGlobalRef(_) => allowSideEffects - /* LoadJSConstructor is pure only for Scala.js-defined JS classes, + /* LoadJSConstructor is pure only for non-native JS classes, * which do not have a native load spec. Note that this test makes * sense per se, as the actual desugaring of `LoadJSConstructor` is * based on the jsNativeLoadSpec of the class. @@ -2166,7 +2166,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { val className = cls.className globalKnowledge.getJSNativeLoadSpec(className) match { case None => - // this is a Scala.js-defined JS module class + // this is a non-native JS module class genLoadModule(className) case Some(spec) => diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 79c3e70733..bf475f0fb4 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -292,7 +292,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { val MethodDef(static, pName, params, resultType, body) = methodDef implicit val ctx = ErrorContext(methodDef) - if (!isTopLevel && !classDef.kind.isAnyScalaJSDefinedClass) { + if (!isTopLevel && !classDef.kind.isAnyNonNativeClass) { reportError(s"Exported method def can only appear in a class") return } @@ -401,7 +401,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { val PropertyDef(static, pName, getterBody, setterArgAndBody) = propDef implicit val ctx = ErrorContext(propDef) - if (!classDef.kind.isAnyScalaJSDefinedClass) { + if (!classDef.kind.isAnyNonNativeClass) { reportError(s"Exported property def can only appear in a class") return } From 2131c141c3a316f11db1ea1953570252cf347a59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 12 Jun 2017 13:04:02 +0200 Subject: [PATCH 0345/2665] Allow lower-cases and `_` in object and class names in Scalastyle. This adapts Scalastyle to our style, rather than us adapting to Scalastyle by adding `scalastyle:ignore` in zillions of places. --- .../org/scalajs/core/compiler/Compat210Component.scala | 4 ++-- .../main/scala/org/scalajs/core/compiler/GenJSCode.scala | 4 ++-- .../scala/org/scalajs/core/compiler/JSDefinitions.scala | 2 +- .../scala/org/scalajs/core/compiler/JSGlobalAddons.scala | 4 ++-- .../scala/org/scalajs/core/compiler/JSTreeExtractors.scala | 2 +- .../scala/org/scalajs/core/compiler/PrepJSInterop.scala | 6 +++--- .../scala/org/scalajs/core/compiler/ScalaJSPlugin.scala | 4 ++-- .../scalajs/core/compiler/test/JSUndefinedParamTest.scala | 2 +- library/src/main/scala/scala/scalajs/js/Dynamic.scala | 2 +- library/src/main/scala/scala/scalajs/js/defined.scala | 2 +- library/src/main/scala/scala/scalajs/js/package.scala | 2 +- .../main/scala/scala/scalajs/niocharset/ISO_8859_1.scala | 2 +- .../scalajs/niocharset/ISO_8859_1_And_US_ASCII_Common.scala | 2 +- .../src/main/scala/scala/scalajs/niocharset/US_ASCII.scala | 2 +- .../src/main/scala/scala/scalajs/niocharset/UTF_16.scala | 2 +- .../src/main/scala/scala/scalajs/niocharset/UTF_16BE.scala | 2 +- .../src/main/scala/scala/scalajs/niocharset/UTF_16LE.scala | 2 +- .../main/scala/scala/scalajs/niocharset/UTF_16_Common.scala | 4 ++-- library/src/main/scala/scala/scalajs/niocharset/UTF_8.scala | 2 +- scalastyle-config.xml | 4 ++-- .../main/scala/org/scalajs/testinterface/TestUtils.scala | 2 +- .../main/scala/org/scalajs/testinterface/HTMLRunner.scala | 4 ++-- .../js/src/main/scala/org/scalajs/testsuite/Compat210.scala | 2 +- .../org/scalajs/testsuite/jsinterop/JSSymbolTest.scala | 2 +- .../org/scalajs/testsuite/jsinterop/StrangeNamedTests.scala | 2 +- 25 files changed, 34 insertions(+), 34 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala b/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala index e0c1541c2a..750fab97f2 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala @@ -120,8 +120,8 @@ trait Compat210Component { */ object LowPrioGenBCodeCompat { - object genBCode { // scalastyle:ignore - object bTypes { // scalastyle:ignore + object genBCode { + object bTypes { def initializeCoreBTypes(): Unit = () } } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 3a1a32b986..50140d82a0 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -69,7 +69,7 @@ abstract class GenJSCode extends plugins.PluginComponent } } - private[this] object pos2irPosCache { // scalastyle:ignore + private[this] object pos2irPosCache { import scala.reflect.internal.util._ private[this] var lastNscSource: SourceFile = null @@ -114,7 +114,7 @@ abstract class GenJSCode extends plugins.PluginComponent override def newPhase(p: Phase): StdPhase = new JSCodePhase(p) - private object jsnme { // scalastyle:ignore + private object jsnme { val anyHash = newTermName("anyHash") val arg_outer = newTermName("arg$outer") val newString = newTermName("newString") diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 472ce8304b..27ece4d962 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -16,7 +16,7 @@ trait JSDefinitions { self: JSGlobalAddons => // scalastyle:off line.size.limit - object jsDefinitions extends JSDefinitionsClass // scalastyle:ignore + object jsDefinitions extends JSDefinitionsClass import definitions._ import rootMirror._ diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala index e402c250b5..c9369f90e7 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala @@ -24,7 +24,7 @@ trait JSGlobalAddons extends JSDefinitions import definitions._ /** JavaScript primitives, used in jscode */ - object jsPrimitives extends JSPrimitives { // scalastyle:ignore + object jsPrimitives extends JSPrimitives { val global: JSGlobalAddons.this.global.type = JSGlobalAddons.this.global val jsAddons: ThisJSGlobalAddons = JSGlobalAddons.this.asInstanceOf[ThisJSGlobalAddons] @@ -46,7 +46,7 @@ trait JSGlobalAddons extends JSDefinitions } /** global javascript interop related helpers */ - object jsInterop { // scalastyle:ignore + object jsInterop { import scala.reflect.NameTransformer import scala.reflect.internal.Flags diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSTreeExtractors.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSTreeExtractors.scala index 4e70ff5ce0..9a574da858 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSTreeExtractors.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSTreeExtractors.scala @@ -13,7 +13,7 @@ import org.scalajs.core.ir.Types._ /** Useful extractors for JavaScript trees */ object JSTreeExtractors { - object jse { // scalastyle:ignore + object jse { object BlockOrAlone { def unapply(tree: Tree): Some[(List[Tree], Tree)] = Some(tree match { diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 32e024bfe7..05c51f30d2 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -62,7 +62,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent override protected def newTransformer(unit: CompilationUnit): Transformer = new JSInteropTransformer(unit) - private object jsnme { // scalastyle:ignore + private object jsnme { val hasNext = newTermName("hasNext") val next = newTermName("next") val nextName = newTermName("nextName") @@ -71,7 +71,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent val Val = newTermName("Val") } - private object jstpnme { // scalastyle:ignore + private object jstpnme { val scala_ = newTypeName("scala") // not defined in 2.10's tpnme } @@ -98,7 +98,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent private def anyEnclosingOwner: OwnerKind = allEnclosingOwners /** Nicer syntax for `allEnclosingOwners isnt kind`. */ - private object noEnclosingOwner { // scalastyle:ignore + private object noEnclosingOwner { @inline def is(kind: OwnerKind): Boolean = allEnclosingOwners isnt kind } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala index 878bb97bc5..6f12f2149d 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala @@ -37,11 +37,11 @@ class ScalaJSPlugin(val global: Global) extends NscPlugin { def generatedJSAST(clDefs: List[Trees.Tree]): Unit = {} /** Addons for JavaScript platform */ - object jsAddons extends { // scalastyle:ignore + object jsAddons extends { val global: ScalaJSPlugin.this.global.type = ScalaJSPlugin.this.global } with JSGlobalAddons with Compat210Component - object scalaJSOpts extends ScalaJSOptions { // scalastyle:ignore + object scalaJSOpts extends ScalaJSOptions { import ScalaJSOptions.URIMap var fixClassOf: Boolean = false var suppressExportDeprecations: Boolean = false diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSUndefinedParamTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSUndefinedParamTest.scala index 4e96076583..b3c4a20e68 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSUndefinedParamTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSUndefinedParamTest.scala @@ -33,7 +33,7 @@ class JSUndefinedParamTest extends DirectTest with TestHelpers { /** Dummy object to get the right shadowing for cross compilation */ private object Compat210 { - object blackbox { // scalastyle:ignore + object blackbox { type Context = scala.reflect.macros.Context } } diff --git a/library/src/main/scala/scala/scalajs/js/Dynamic.scala b/library/src/main/scala/scala/scalajs/js/Dynamic.scala index de3e9ea87a..e3742687f2 100644 --- a/library/src/main/scala/scala/scalajs/js/Dynamic.scala +++ b/library/src/main/scala/scala/scalajs/js/Dynamic.scala @@ -88,7 +88,7 @@ object Dynamic { * returns the JavaScript object * {foo: 3, bar: "foobar"} */ - object literal extends scala.Dynamic { // scalastyle:ignore + object literal extends scala.Dynamic { /** literal creation like this: * js.Dynamic.literal(name1 = "value", name2 = "value") */ diff --git a/library/src/main/scala/scala/scalajs/js/defined.scala b/library/src/main/scala/scala/scalajs/js/defined.scala index 7fc7249e2e..f91048fd41 100644 --- a/library/src/main/scala/scala/scalajs/js/defined.scala +++ b/library/src/main/scala/scala/scalajs/js/defined.scala @@ -10,7 +10,7 @@ package scala.scalajs.js import scala.scalajs.js -object defined { // scalastyle:ignore +object defined { /** Explicitly upcasts an `A` to a `js.UndefOr[A]`. * * This method is useful in some cases to drive Scala's type inference. diff --git a/library/src/main/scala/scala/scalajs/js/package.scala b/library/src/main/scala/scala/scalajs/js/package.scala index 5ec5dcc11f..95350b9720 100644 --- a/library/src/main/scala/scala/scalajs/js/package.scala +++ b/library/src/main/scala/scala/scalajs/js/package.scala @@ -117,7 +117,7 @@ package object js { * The body of all concrete members in a native JS class, trait or object * must be `= js.native`. */ - class native extends scala.annotation.StaticAnnotation // scalastyle:ignore + class native extends scala.annotation.StaticAnnotation /** Denotes a method body as native JavaScript. For use in facade types: * diff --git a/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1.scala b/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1.scala index a49c7bf542..7765f0ca36 100644 --- a/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1.scala +++ b/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1.scala @@ -11,7 +11,7 @@ package scala.scalajs.niocharset import java.nio.charset._ -private[niocharset] object ISO_8859_1 extends ISO_8859_1_And_US_ASCII_Common( // scalastyle:ignore +private[niocharset] object ISO_8859_1 extends ISO_8859_1_And_US_ASCII_Common( "ISO-8859-1", Array( "csISOLatin1", "IBM-819", "iso-ir-100", "8859_1", "ISO_8859-1", "l1", "ISO8859-1", "ISO_8859_1", "cp819", "ISO8859_1", "latin1", diff --git a/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1_And_US_ASCII_Common.scala b/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1_And_US_ASCII_Common.scala index ee453f3fec..d2b1aba2b6 100644 --- a/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1_And_US_ASCII_Common.scala +++ b/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1_And_US_ASCII_Common.scala @@ -20,7 +20,7 @@ import java.nio.charset._ * * `maxValue` is therefore either 0xff (ISO_8859_1) or 0x7f (US_ASCII). */ -private[niocharset] abstract class ISO_8859_1_And_US_ASCII_Common protected ( // scalastyle:ignore +private[niocharset] abstract class ISO_8859_1_And_US_ASCII_Common protected ( name: String, aliases: Array[String], private val maxValue: Int) extends Charset(name, aliases) { diff --git a/library/src/main/scala/scala/scalajs/niocharset/US_ASCII.scala b/library/src/main/scala/scala/scalajs/niocharset/US_ASCII.scala index 68443fbc59..746c75b871 100644 --- a/library/src/main/scala/scala/scalajs/niocharset/US_ASCII.scala +++ b/library/src/main/scala/scala/scalajs/niocharset/US_ASCII.scala @@ -11,7 +11,7 @@ package scala.scalajs.niocharset import java.nio.charset._ -private[niocharset] object US_ASCII extends ISO_8859_1_And_US_ASCII_Common( // scalastyle:ignore +private[niocharset] object US_ASCII extends ISO_8859_1_And_US_ASCII_Common( "US-ASCII", Array( "cp367", "ascii7", "ISO646-US", "646", "csASCII", "us", "iso_646.irv:1983", "ISO_646.irv:1991", "IBM367", "ASCII", "default", "ANSI_X3.4-1986", diff --git a/library/src/main/scala/scala/scalajs/niocharset/UTF_16.scala b/library/src/main/scala/scala/scalajs/niocharset/UTF_16.scala index f725d62cf4..9d1748a7cf 100644 --- a/library/src/main/scala/scala/scalajs/niocharset/UTF_16.scala +++ b/library/src/main/scala/scala/scalajs/niocharset/UTF_16.scala @@ -11,7 +11,7 @@ package scala.scalajs.niocharset import java.nio.charset._ -private[niocharset] object UTF_16 extends UTF_16_Common( // scalastyle:ignore +private[niocharset] object UTF_16 extends UTF_16_Common( "UTF-16", Array( "utf16", "UTF_16", "UnicodeBig", "unicode"), endianness = UTF_16_Common.AutoEndian) diff --git a/library/src/main/scala/scala/scalajs/niocharset/UTF_16BE.scala b/library/src/main/scala/scala/scalajs/niocharset/UTF_16BE.scala index 00da83ad39..dece19161b 100644 --- a/library/src/main/scala/scala/scalajs/niocharset/UTF_16BE.scala +++ b/library/src/main/scala/scala/scalajs/niocharset/UTF_16BE.scala @@ -11,7 +11,7 @@ package scala.scalajs.niocharset import java.nio.charset._ -private[niocharset] object UTF_16BE extends UTF_16_Common( // scalastyle:ignore +private[niocharset] object UTF_16BE extends UTF_16_Common( "UTF-16BE", Array( "X-UTF-16BE", "UTF_16BE", "ISO-10646-UCS-2", "UnicodeBigUnmarked"), endianness = UTF_16_Common.BigEndian) diff --git a/library/src/main/scala/scala/scalajs/niocharset/UTF_16LE.scala b/library/src/main/scala/scala/scalajs/niocharset/UTF_16LE.scala index 1b1cc2523c..de469c40aa 100644 --- a/library/src/main/scala/scala/scalajs/niocharset/UTF_16LE.scala +++ b/library/src/main/scala/scala/scalajs/niocharset/UTF_16LE.scala @@ -11,7 +11,7 @@ package scala.scalajs.niocharset import java.nio.charset._ -private[niocharset] object UTF_16LE extends UTF_16_Common( // scalastyle:ignore +private[niocharset] object UTF_16LE extends UTF_16_Common( "UTF-16LE", Array( "UnicodeLittleUnmarked", "UTF_16LE", "X-UTF-16LE"), endianness = UTF_16_Common.LittleEndian) diff --git a/library/src/main/scala/scala/scalajs/niocharset/UTF_16_Common.scala b/library/src/main/scala/scala/scalajs/niocharset/UTF_16_Common.scala index 5be8ac6be3..10d8a0e3ec 100644 --- a/library/src/main/scala/scala/scalajs/niocharset/UTF_16_Common.scala +++ b/library/src/main/scala/scala/scalajs/niocharset/UTF_16_Common.scala @@ -16,7 +16,7 @@ import java.nio.charset._ /** This is a very specific common implementation for UTF_16BE and UTF_16LE. */ -private[niocharset] abstract class UTF_16_Common protected ( // scalastyle:ignore +private[niocharset] abstract class UTF_16_Common protected ( name: String, aliases: Array[String], private val endianness: Int) extends Charset(name, aliases) { @@ -198,7 +198,7 @@ private[niocharset] abstract class UTF_16_Common protected ( // scalastyle:ignor } } -private[niocharset] object UTF_16_Common { // scalastyle:ignore +private[niocharset] object UTF_16_Common { final val AutoEndian = 0 final val BigEndian = 1 final val LittleEndian = 2 diff --git a/library/src/main/scala/scala/scalajs/niocharset/UTF_8.scala b/library/src/main/scala/scala/scalajs/niocharset/UTF_8.scala index 913b685d9f..6fc26b61c7 100644 --- a/library/src/main/scala/scala/scalajs/niocharset/UTF_8.scala +++ b/library/src/main/scala/scala/scalajs/niocharset/UTF_8.scala @@ -14,7 +14,7 @@ import scala.annotation.{switch, tailrec} import java.nio._ import java.nio.charset._ -private[niocharset] object UTF_8 extends Charset("UTF-8", Array( // scalastyle:ignore +private[niocharset] object UTF_8 extends Charset("UTF-8", Array( "UTF8", "unicode-1-1-utf-8")) { import java.lang.Character._ diff --git a/scalastyle-config.xml b/scalastyle-config.xml index 3a42f2610e..af76c9ccf1 100644 --- a/scalastyle-config.xml +++ b/scalastyle-config.xml @@ -28,12 +28,12 @@ - + - + diff --git a/stubs/src/main/scala/org/scalajs/testinterface/TestUtils.scala b/stubs/src/main/scala/org/scalajs/testinterface/TestUtils.scala index f7a4b8e6a7..6ed1561321 100644 --- a/stubs/src/main/scala/org/scalajs/testinterface/TestUtils.scala +++ b/stubs/src/main/scala/org/scalajs/testinterface/TestUtils.scala @@ -4,7 +4,7 @@ import language.experimental.macros /** Dummy object to get the right shadowing for 2.10 / 2.11 cross compilation */ private object Compat210 { - object blackbox { // scalastyle:ignore + object blackbox { type Context = scala.reflect.macros.Context } } diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala b/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala index 3c1708bc35..313fd14875 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala @@ -431,10 +431,10 @@ protected[testinterface] object HTMLRunner extends js.JSApp { } // Mini dom facade. - private object dom { // scalastyle:ignore + private object dom { @JSGlobal("document") @js.native - object document extends js.Object { // scalastyle:ignore + object document extends js.Object { def body: Element = js.native def createElement(tag: String): Element = js.native def createTextNode(tag: String): Node = js.native diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/Compat210.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/Compat210.scala index 32ba360079..117be3fbe9 100644 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/Compat210.scala +++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/Compat210.scala @@ -8,7 +8,7 @@ package org.scalajs.testsuite private[testsuite] object Compat210 { - object blackbox { // scalastyle:ignore + object blackbox { type Context = scala.reflect.macros.Context } } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala index 5b93ac298a..cb82dd32aa 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala @@ -400,7 +400,7 @@ object JSSymbolTest { @ScalaJSDefined class SJSDefinedInnerObject extends js.Object with InnerObjectTrait { @JSName(sym1) - object innerObject { // scalastyle:ignore + object innerObject { override def toString(): String = "SJSDefinedInnerObject.innerObject" } } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/StrangeNamedTests.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/StrangeNamedTests.scala index d1dc5f9408..d15ac25e95 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/StrangeNamedTests.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/StrangeNamedTests.scala @@ -14,7 +14,7 @@ class `1_TestName` { // scalastyle:ignore @Test def `a test with name 1_TestName`(): Unit = () } -class eval { // scalastyle:ignore +class eval { @Test def `a test with name eval`(): Unit = () } From 9b3598ed3250b2a7b1c370c17da63493672c3299 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 12 Jun 2017 15:18:06 +0200 Subject: [PATCH 0346/2665] Enable Scalastyle in shared source directories. Sadly, the Scalastyle sbt plugin only processes files in the `scalaSource` directory, rather than in all `unmanagedSourceDirectories`. This means that our shared sources were never checked by Scalastyle. We fix this in this commit. The Scalastyle sbt plugin still being a non-Auto plugin from sbt < 0.13.5, there are a few complications. The problem is that settings of such plugins are applied *after* those defined in `.settings(...)`, hence overriding them (instead of the other way around). We have to resort to the `.settingSets` hack that still exists in 0.13. It won't exist in sbt 1.x, but then neither will non-Auto plugins, so by the time we get there, Scalastyle will have to use an `AutoPlugin`. --- ci/matrix.xml | 2 +- .../org/scalajs/junit/utils/JUnitTest.scala | 2 +- project/BinaryIncompatibilities.scala | 4 +++ project/Build.scala | 35 ++++++++++++++----- .../javalib/util/CollectionsTestOnJDK7.scala | 2 +- .../javalib/lang/MathTestOnJDK8.scala | 2 +- .../testsuite/compiler/MatchTest.scala | 2 +- .../testsuite/compiler/RegressionTest.scala | 4 +++ .../testsuite/javalib/util/MapTest.scala | 2 +- .../testsuite/niobuffer/CharBufferTest.scala | 2 +- .../testsuite/niobuffer/FloatBufferTest.scala | 2 +- .../testsuite/niobuffer/IntBufferTest.scala | 2 +- .../testsuite/niobuffer/LongBufferTest.scala | 2 +- .../testsuite/niobuffer/ShortBufferTest.scala | 2 +- .../core/tools/test/js/TestRunner.scala | 2 +- .../scala/org/scalajs/core/tools/io/IO.scala | 2 +- .../core/tools/javascript/Printers.scala | 2 +- .../tools/javascript/SourceMapWriter.scala | 14 +++++++- .../scalajs/core/tools/javascript/Trees.scala | 2 +- .../core/tools/json/JSONDeserializer.scala | 14 +++++--- .../core/tools/json/JSONObjBuilder.scala | 4 +-- .../core/tools/json/JSONObjExtractor.scala | 4 +-- .../core/tools/json/JSONSerializer.scala | 8 +++-- .../org/scalajs/core/tools/json/package.scala | 2 +- .../core/tools/linker/LinkedClass.scala | 2 +- .../core/tools/linker/analyzer/Analyzer.scala | 6 ++-- .../backend/emitter/FunctionEmitter.scala | 20 +++++------ .../tools/linker/backend/emitter/JSGen.scala | 2 ++ .../core/tools/linker/checker/IRChecker.scala | 3 ++ .../frontend/optimizer/GenIncOptimizer.scala | 16 +++++---- .../frontend/optimizer/OptimizerCore.scala | 12 +++++-- .../scalajs/core/tools/logging/Level.scala | 2 +- 32 files changed, 120 insertions(+), 62 deletions(-) diff --git a/ci/matrix.xml b/ci/matrix.xml index daa12462b4..6772179e2d 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -238,7 +238,7 @@ 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 \ reversi/scalastyle testingExample/scalastyle \ diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala index fca35bca80..bdfebf529e 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala @@ -206,7 +206,7 @@ abstract class JUnitTest { remaining.take(maxLen).foreach(appendOut) msg.append(")") - + throw new Exception(msg.result()) } } diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index e23de09213..b0d852aa64 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -10,6 +10,10 @@ object BinaryIncompatibilities { ProblemFilters.exclude[ReversedMissingMethodProblem]( "org.scalajs.core.tools.linker.LinkerPlatformExtensions.applyInternal"), + // private[optimizer], not an issue + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.core.tools.linker.frontend.optimizer.GenIncOptimizer#MethodContainer.optimizedDefs"), + // private[emitter], not an issue ProblemFilters.exclude[DirectMissingMethodProblem]( "org.scalajs.core.tools.linker.backend.emitter.FunctionEmitter#JSDesugar.genClassDataOf") diff --git a/project/Build.scala b/project/Build.scala index 0d5aa1f7a6..5ea90b114c 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -417,6 +417,23 @@ 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 = ( @@ -507,7 +524,7 @@ object Build { libraryDependencies += "com.novocode" % "junit-interface" % "0.9" % "test" ) - ) + ).enableScalastyleInSharedSources lazy val irProjectJS: Project = Project( id = "irJS", @@ -521,7 +538,7 @@ object Build { ) ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( javalibEx, jUnitRuntime % "test" - ) + ).enableScalastyleInSharedSources lazy val compiler: Project = Project( id = "compiler", @@ -603,7 +620,7 @@ object Build { parallelCollectionsDependencies(scalaVersion.value) ) ) - ).dependsOn(irProject) + ).dependsOn(irProject).enableScalastyleInSharedSources lazy val toolsJS: Project = Project( id = "toolsJS", @@ -708,7 +725,9 @@ object Build { runner.run(sbtLogger2ToolsLogger(streams.value.log), scalaJSConsole.value) } } - ).withScalaJSCompiler.dependsOn(javalibEx, testSuite % "test->test", irProjectJS) + ).withScalaJSCompiler.dependsOn( + javalibEx, testSuite % "test->test", irProjectJS + ).enableScalastyleInSharedSources lazy val jsEnvs: Project = Project( id = "jsEnvs", @@ -1200,7 +1219,7 @@ object Build { ) ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( jUnitRuntime % "test", testInterface % "test" - ) + ).enableScalastyleInSharedSources lazy val jUnitTestOutputsJVM = Project( @@ -1213,7 +1232,7 @@ object Build { "com.novocode" % "junit-interface" % "0.11" % "test" ) ) - ) + ).enableScalastyleInSharedSources lazy val jUnitPlugin = Project( id = "jUnitPlugin", @@ -1612,7 +1631,7 @@ object Build { ) ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( library, jUnitRuntime - ) + ).enableScalastyleInSharedSources lazy val testSuiteJVM: Project = Project( id = "testSuiteJVM", @@ -1623,7 +1642,7 @@ object Build { libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % "test" ) - ) + ).enableScalastyleInSharedSources lazy val noIrCheckTest: Project = Project( id = "noIrCheckTest", diff --git a/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/util/CollectionsTestOnJDK7.scala b/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/util/CollectionsTestOnJDK7.scala index 1f1439a756..5be095a648 100644 --- a/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/util/CollectionsTestOnJDK7.scala +++ b/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/util/CollectionsTestOnJDK7.scala @@ -26,7 +26,7 @@ class CollectionsTestOnJDK7 { } @Test def should_implement_emptyListIterator(): Unit = { - def test[E : ClassTag](toElem: Int => E): Unit = { + def test[E: ClassTag](toElem: Int => E): Unit = { def freshIter: ju.ListIterator[E] = ju.Collections.emptyListIterator[E] assertFalse(freshIter.hasNext) diff --git 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 index ea5d21c0bd..267cad65c1 100644 --- 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 @@ -257,7 +257,7 @@ class MathTestOnJDK8 { expectThrows(classOf[ArithmeticException], Math.floorDiv(n, 0)) } - @Test def floorMod() = { + @Test def floorMod(): Unit = { assumeFalse("Assumed not executing in PhantomJS", executingInPhantomJS) // crashes otherwise, see #593 assertEquals(0, Math.floorMod(0, 1)) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/MatchTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/MatchTest.scala index abde360994..1eb475b16f 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/MatchTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/MatchTest.scala @@ -96,6 +96,6 @@ object MatchTest { } class ValueClass(val x: Int) extends AnyVal with ValueClassBase[Int] { - def f() = x * 2 + def f(): Int = x * 2 } } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala index 805e4dcae1..ac638c1790 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala @@ -385,6 +385,8 @@ class RegressionTest { } @Test def return_x_match_issue_2928(): Unit = { + // scalastyle:off return + def testNonUnit(x: String): Boolean = { return x match { case "True" => true @@ -409,6 +411,8 @@ class RegressionTest { r = None testUnit("not true") assertEquals(Some(false), r) + + // scalastyle:on return } @Test def null_asInstanceOf_Unit_should_succeed_issue_1691(): Unit = { diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/MapTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/MapTest.scala index 940d4998b3..4681d9ac90 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/MapTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/MapTest.scala @@ -599,7 +599,7 @@ trait MapTest { assertTrue(mp.containsKey("TWO")) assertFalse(mp.containsKey("THREE")) } - + } object MapFactory { diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/CharBufferTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/CharBufferTest.scala index f5d67ad64f..e640d2f62f 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/CharBufferTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/CharBufferTest.scala @@ -61,7 +61,7 @@ class AllocCharSlicedBufferTest extends CharBufferTest { } class CharBufferWrappingACharSequenceTest extends CharBufferTest { - + val factory: CharBufferFactory = new CharBufferWrappingACharSequenceFactory class CharBufferWrappingACharSequenceFactory extends Factory { diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/FloatBufferTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/FloatBufferTest.scala index 12198cb68b..1437349300 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/FloatBufferTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/FloatBufferTest.scala @@ -113,4 +113,4 @@ class ReadOnlyFloatViewOfWrappedByteBufferLittleEndianTest extends ReadOnlyFloatViewOfByteBufferTest(new WrappedByteBufferFactory, ByteOrder.LITTLE_ENDIAN) class ReadOnlyFloatViewOfSlicedAllocByteBufferLittleEndianTest - extends ReadOnlyFloatViewOfByteBufferTest(new SlicedAllocByteBufferFactory, ByteOrder.LITTLE_ENDIAN) \ No newline at end of file + extends ReadOnlyFloatViewOfByteBufferTest(new SlicedAllocByteBufferFactory, ByteOrder.LITTLE_ENDIAN) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/IntBufferTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/IntBufferTest.scala index f34fc2098a..90aeabbae5 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/IntBufferTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/IntBufferTest.scala @@ -113,4 +113,4 @@ class ReadOnlyIntViewOfWrappedByteBufferLittleEndianTest extends ReadOnlyIntViewOfByteBufferTest(new WrappedByteBufferFactory, ByteOrder.LITTLE_ENDIAN) class ReadOnlyIntViewOfSlicedAllocByteBufferLittleEndianTest - extends ReadOnlyIntViewOfByteBufferTest(new SlicedAllocByteBufferFactory, ByteOrder.LITTLE_ENDIAN) \ No newline at end of file + extends ReadOnlyIntViewOfByteBufferTest(new SlicedAllocByteBufferFactory, ByteOrder.LITTLE_ENDIAN) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/LongBufferTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/LongBufferTest.scala index c5f33f92a8..cd1c8084b7 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/LongBufferTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/LongBufferTest.scala @@ -113,4 +113,4 @@ class ReadOnlyLongViewOfWrappedByteBufferLittleEndianTest extends ReadOnlyLongViewOfByteBufferTest(new WrappedByteBufferFactory, ByteOrder.LITTLE_ENDIAN) class ReadOnlyLongViewOfSlicedAllocByteBufferLittleEndianTest - extends ReadOnlyLongViewOfByteBufferTest(new SlicedAllocByteBufferFactory, ByteOrder.LITTLE_ENDIAN) \ No newline at end of file + extends ReadOnlyLongViewOfByteBufferTest(new SlicedAllocByteBufferFactory, ByteOrder.LITTLE_ENDIAN) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/ShortBufferTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/ShortBufferTest.scala index 6400bcefe5..03b5b52007 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/ShortBufferTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/ShortBufferTest.scala @@ -113,4 +113,4 @@ class ReadOnlyShortViewOfWrappedByteBufferLittleEndianTest extends ReadOnlyShortViewOfByteBufferTest(new WrappedByteBufferFactory, ByteOrder.LITTLE_ENDIAN) class ReadOnlyShortViewOfSlicedAllocByteBufferLittleEndianTest - extends ReadOnlyShortViewOfByteBufferTest(new SlicedAllocByteBufferFactory, ByteOrder.LITTLE_ENDIAN) \ No newline at end of file + extends ReadOnlyShortViewOfByteBufferTest(new SlicedAllocByteBufferFactory, ByteOrder.LITTLE_ENDIAN) diff --git a/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala b/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala index 60d5bed457..ee43bb95a1 100644 --- a/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala +++ b/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala @@ -45,7 +45,7 @@ object TestRunner { def hasFailed: Boolean = failed - def handle(ev: Event) = { + def handle(ev: Event): Unit = { if (ev.status == Status.Error || ev.status == Status.Failure) failed = true } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/IO.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/IO.scala index bf68cb3969..763a787105 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/IO.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/IO.scala @@ -143,5 +143,5 @@ object IO { } @inline - private def newBuffer[T : ClassTag] = new Array[T](4096) + private def newBuffer[T: ClassTag] = new Array[T](4096) } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala index 5274965557..03db778d6a 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala @@ -34,7 +34,7 @@ object Printers { class JSTreePrinter(protected val out: Writer) extends IndentationManager { - def printTopLevelTree(tree: Tree) { + def printTopLevelTree(tree: Tree): Unit = { tree match { case Skip() => // do not print anything diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/SourceMapWriter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/SourceMapWriter.scala index 995467c466..7cd10d9142 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/SourceMapWriter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/SourceMapWriter.scala @@ -171,6 +171,8 @@ class SourceMapWriter( private def startSegment(startColumn: Int, originalPos: Position, originalName: String): Unit = { + // scalastyle:off return + // There is no point in outputting a segment with the same information if ((originalPos == pendingPos) && (originalName == pendingName)) return @@ -183,9 +185,13 @@ class SourceMapWriter( pendingColumnInGenerated = startColumn pendingPos = originalPos pendingName = originalName + + // scalastyle:on return } - private def writePendingSegment() { + private def writePendingSegment(): Unit = { + // scalastyle:off return + if (pendingColumnInGenerated < 0) return @@ -231,6 +237,8 @@ class SourceMapWriter( writeBase64VLQ(nameIndex-lastNameIndex) lastNameIndex = nameIndex } + + // scalastyle:on return } def complete(): Unit = { @@ -263,6 +271,8 @@ class SourceMapWriter( * http://code.google.com/p/closure-compiler/source/browse/src/com/google/debugging/sourcemap/Base64VLQ.java */ private def writeBase64VLQ(value0: Int): Unit = { + // scalastyle:off return + /* The sign is encoded in the least significant bit, while the * absolute value is shifted one bit to the left. * So in theory the "definition" of `value` is: @@ -303,6 +313,8 @@ class SourceMapWriter( } writeBase64VLQSlowPath(value) } + + // scalastyle:on return } private def writeBase64VLQ0(): Unit = diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala index 6451d79ab1..6a0ce1f907 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala @@ -51,7 +51,7 @@ object Trees { } case class ComputedName(tree: Tree) extends PropertyName { - def pos = tree.pos + def pos: Position = tree.pos } // Definitions diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONDeserializer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONDeserializer.scala index dd765a27ea..fd45c21ac2 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONDeserializer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONDeserializer.scala @@ -18,13 +18,17 @@ object JSONDeserializer { def deserialize(x: JSON): Boolean = Impl.toBoolean(x) } - implicit def listJSON[T : JSONDeserializer] = new JSONDeserializer[List[T]] { - def deserialize(x: JSON): List[T] = Impl.toList(x).map(fromJSON[T] _) + implicit def listJSON[T: JSONDeserializer]: JSONDeserializer[List[T]] = { + new JSONDeserializer[List[T]] { + def deserialize(x: JSON): List[T] = Impl.toList(x).map(fromJSON[T] _) + } } - implicit def mapJSON[V : JSONDeserializer] = new JSONDeserializer[Map[String, V]] { - def deserialize(x: JSON): Map[String, V] = - Impl.toMap(x).mapValues(fromJSON[V] _) + implicit def mapJSON[V: JSONDeserializer]: JSONDeserializer[Map[String, V]] = { + new JSONDeserializer[Map[String, V]] { + def deserialize(x: JSON): Map[String, V] = + Impl.toMap(x).mapValues(fromJSON[V] _) + } } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONObjBuilder.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONObjBuilder.scala index 9736a18d4b..0834b5740f 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONObjBuilder.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONObjBuilder.scala @@ -6,12 +6,12 @@ class JSONObjBuilder { private val flds = mutable.Map.empty[String, JSON] - def fld[T : JSONSerializer](name: String, v: T): this.type = { + def fld[T: JSONSerializer](name: String, v: T): this.type = { flds.put(name, v.toJSON) this } - def opt[T : JSONSerializer](name: String, v: Option[T]): this.type = { + def opt[T: JSONSerializer](name: String, v: Option[T]): this.type = { v.foreach(v => flds.put(name, v.toJSON)) this } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONObjExtractor.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONObjExtractor.scala index d31e31634e..f9baa9cb88 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONObjExtractor.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONObjExtractor.scala @@ -5,9 +5,9 @@ import scala.collection.mutable class JSONObjExtractor(rawData: JSON) { private val data = Impl.toMap(rawData) - def fld[T : JSONDeserializer](name: String): T = + def fld[T: JSONDeserializer](name: String): T = fromJSON[T](data(name)) - def opt[T : JSONDeserializer](name: String): Option[T] = + def opt[T: JSONDeserializer](name: String): Option[T] = data.get(name).map(fromJSON[T] _) } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONSerializer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONSerializer.scala index 8a239d79f4..04d0f05347 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONSerializer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONSerializer.scala @@ -18,11 +18,13 @@ object JSONSerializer { def serialize(x: Boolean): JSON = Impl.fromBoolean(x) } - implicit def listJSON[T : JSONSerializer] = new JSONSerializer[List[T]] { - def serialize(x: List[T]): JSON = Impl.fromList(x.map(_.toJSON)) + implicit def listJSON[T: JSONSerializer]: JSONSerializer[List[T]] = { + new JSONSerializer[List[T]] { + def serialize(x: List[T]): JSON = Impl.fromList(x.map(_.toJSON)) + } } - implicit def mapJSON[V : JSONSerializer] = { + implicit def mapJSON[V: JSONSerializer]:JSONSerializer[Map[String, V]] = { new JSONSerializer[Map[String, V]] { def serialize(x: Map[String, V]): JSON = Impl.fromMap(x.mapValues(_.toJSON)) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/json/package.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/json/package.scala index f1a69ad756..be4d8f0ac7 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/json/package.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/json/package.scala @@ -11,7 +11,7 @@ import java.io.{Reader, Writer} package object json { type JSON = Impl.Repr - implicit class JSONPimp[T : JSONSerializer](x: T) { + implicit class JSONPimp[T: JSONSerializer](x: T) { def toJSON: JSON = implicitly[JSONSerializer[T]].serialize(x) } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala index 6b94348875..592aa41505 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala @@ -107,7 +107,7 @@ final class LinkedClass( hasInstances: Boolean = this.hasInstances, hasInstanceTests: Boolean = this.hasInstanceTests, hasRuntimeTypeInfo: Boolean = this.hasRuntimeTypeInfo, - version: Option[String] = this.version) = { + version: Option[String] = this.version): LinkedClass = { new LinkedClass( name, kind, diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala index 74a084498e..1f2961f0bf 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala @@ -250,7 +250,7 @@ private final class Analyzer(semantics: Semantics, val delayedCalls = mutable.Map.empty[String, From] - def isNeededAtAll = + def isNeededAtAll: Boolean = areInstanceTestsUsed || isDataAccessed || isAnySubclassInstantiated || @@ -259,7 +259,7 @@ private final class Analyzer(semantics: Semantics, isAnyStaticMethodReachable || isAnyDefaultMethodReachable - def isAnyStaticMethodReachable = + def isAnyStaticMethodReachable: Boolean = staticMethodInfos.values.exists(_.isReachable) private def isAnyDefaultMethodReachable = @@ -726,7 +726,7 @@ private final class Analyzer(semantics: Semantics, var syntheticKind: MethodSyntheticKind = MethodSyntheticKind.None - def isDefaultBridge = + def isDefaultBridge: Boolean = syntheticKind.isInstanceOf[MethodSyntheticKind.DefaultBridge] /** Throws MatchError if `!isDefaultBridge`. */ diff --git 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 index f049f4f9b7..c3eedd4973 100644 --- 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 @@ -1890,9 +1890,9 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case Double_/ => js.BinaryOp(JSBinaryOp./, newLhs, newRhs) case Double_% => js.BinaryOp(JSBinaryOp.%, newLhs, newRhs) - case Num_< => js.BinaryOp(JSBinaryOp.< , newLhs, newRhs) + case Num_< => js.BinaryOp(JSBinaryOp.<, newLhs, newRhs) case Num_<= => js.BinaryOp(JSBinaryOp.<=, newLhs, newRhs) - case Num_> => js.BinaryOp(JSBinaryOp.> , newLhs, newRhs) + case Num_> => js.BinaryOp(JSBinaryOp.>, newLhs, newRhs) case Num_>= => js.BinaryOp(JSBinaryOp.>=, newLhs, newRhs) case Long_+ => genLongMethodApply(newLhs, LongImpl.+, newRhs) @@ -1905,23 +1905,23 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case Long_/ => genLongMethodApply(newLhs, LongImpl./, newRhs) case Long_% => genLongMethodApply(newLhs, LongImpl.%, newRhs) - case Long_| => genLongMethodApply(newLhs, LongImpl.|, newRhs) - case Long_& => genLongMethodApply(newLhs, LongImpl.&, newRhs) + case Long_| => genLongMethodApply(newLhs, LongImpl.|, newRhs) + case Long_& => genLongMethodApply(newLhs, LongImpl.&, newRhs) case Long_^ => lhs match { case LongLiteral(-1L) => genLongMethodApply(newRhs, LongImpl.UNARY_~) case _ => genLongMethodApply(newLhs, LongImpl.^, newRhs) } - case Long_<< => genLongMethodApply(newLhs, LongImpl.<<, newRhs) + case Long_<< => genLongMethodApply(newLhs, LongImpl.<<, newRhs) case Long_>>> => genLongMethodApply(newLhs, LongImpl.>>>, newRhs) - case Long_>> => genLongMethodApply(newLhs, LongImpl.>>, newRhs) + case Long_>> => genLongMethodApply(newLhs, LongImpl.>>, newRhs) case Long_== => genLongMethodApply(newLhs, LongImpl.===, newRhs) case Long_!= => genLongMethodApply(newLhs, LongImpl.!==, newRhs) - case Long_< => genLongMethodApply(newLhs, LongImpl.<, newRhs) - case Long_<= => genLongMethodApply(newLhs, LongImpl.<=, newRhs) - case Long_> => genLongMethodApply(newLhs, LongImpl.>, newRhs) - case Long_>= => genLongMethodApply(newLhs, LongImpl.>=, newRhs) + case Long_< => genLongMethodApply(newLhs, LongImpl.<, newRhs) + case Long_<= => genLongMethodApply(newLhs, LongImpl.<=, newRhs) + case Long_> => genLongMethodApply(newLhs, LongImpl.>, newRhs) + case Long_>= => genLongMethodApply(newLhs, LongImpl.>=, newRhs) case Boolean_| => !(!js.BinaryOp(JSBinaryOp.|, newLhs, newRhs)) case Boolean_& => !(!js.BinaryOp(JSBinaryOp.&, newLhs, newRhs)) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala index 4b6b245ba7..a60eae073a 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala @@ -228,6 +228,7 @@ private[emitter] final class JSGen(val semantics: Semantics, (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') def containsOnlyValidChars(): Boolean = { + // scalastyle:off return val len = module.length var i = 0 while (i != len) { @@ -236,6 +237,7 @@ private[emitter] final class JSGen(val semantics: Semantics, i += 1 } true + // scalastyle:on return } def buildValidName(): String = { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 285fdc0e56..95a848ce0b 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -9,6 +9,9 @@ package org.scalajs.core.tools.linker.checker +// In the IR checker, we allow early returns for improved readability +// scalastyle:off return + import scala.language.implicitConversions import scala.annotation.switch diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala index e5bfbd227f..e57fd4ea4d 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala @@ -138,9 +138,7 @@ abstract class GenIncOptimizer private[optimizer] (semantics: Semantics, val newLinkedClasses = for (linkedClass <- unit.classDefs) yield { def defs(container: Option[MethodContainer]) = - container.fold[List[LinkedMember[MethodDef]]](Nil) { - _.optimizedDefs.toList - } + container.fold[List[LinkedMember[MethodDef]]](Nil)(_.optimizedDefs) val encodedName = linkedClass.encodedName val memberNamespace = @@ -316,10 +314,14 @@ abstract class GenIncOptimizer private[optimizer] (semantics: Semantics, val methods = mutable.Map.empty[String, MethodImpl] - def optimizedDefs = for { - method <- methods.values - if !method.deleted - } yield method.optimizedMethodDef + def optimizedDefs: List[LinkedMember[MethodDef]] = { + (for { + method <- methods.values + if !method.deleted + } yield { + method.optimizedMethodDef + }).toList + } /** UPDATE PASS ONLY. Global concurrency safe but not on same instance */ def updateWith(linkedClass: LinkedClass): diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index 5522acc83c..e12b769852 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -2815,7 +2815,7 @@ private[optimizer] abstract class OptimizerCore( /** Translate literals to their Scala.js String representation. */ private def foldToStringForString_+(preTrans: PreTransform)( - implicit pos : Position): PreTransform = preTrans match { + implicit pos: Position): PreTransform = preTrans match { case PreTransLit(literal) => literal match { case LongLiteral(value) => PreTransLit(StringLiteral(value.toString)) @@ -4134,6 +4134,8 @@ private[optimizer] abstract class OptimizerCore( /** Trampolines a pretransform */ private def trampoline(tailrec: => TailRec[Tree]): Tree = { + // scalastyle:off return + curTrampolineId += 1 val myTrampolineId = curTrampolineId @@ -4170,6 +4172,8 @@ private[optimizer] abstract class OptimizerCore( } finally { curTrampolineId -= 1 } + + // scalastyle:on return } } @@ -4475,7 +4479,7 @@ private[optimizer] object OptimizerCore { private final class PreTransBlock private ( val bindingsAndStats: List[BindingOrStat], val result: PreTransResult) extends PreTransform { - def pos = result.pos + def pos: Position = result.pos val tpe = result.tpe assert(bindingsAndStats.nonEmpty) @@ -4585,7 +4589,7 @@ private[optimizer] object OptimizerCore { */ private final case class PreTransRecordTree(tree: Tree, tpe: RefinedType, cancelFun: CancelFun) extends PreTransGenTree { - def pos = tree.pos + def pos: Position = tree.pos assert(tree.tpe.isInstanceOf[RecordType], s"Cannot create a PreTransRecordTree with non-record type ${tree.tpe}") @@ -4749,6 +4753,7 @@ private[optimizer] object OptimizerCore { final val Float32ArrayToFloatArray = Int32ArrayToIntArray + 1 final val Float64ArrayToDoubleArray = Float32ArrayToFloatArray + 1 + // scalastyle:off line.size.limit val intrinsics: Map[String, Int] = Map( "jl_System$.arraycopy__O__I__O__I__I__V" -> ArrayCopy, "jl_System$.identityHashCode__O__I" -> IdentityHashCode, @@ -4787,6 +4792,7 @@ private[optimizer] object OptimizerCore { "sjs_js_typedarray_package$.float32Array2FloatArray__sjs_js_typedarray_Float32Array__AF" -> Float32ArrayToFloatArray, "sjs_js_typedarray_package$.float64Array2DoubleArray__sjs_js_typedarray_Float64Array__AD" -> Float64ArrayToDoubleArray ).withDefaultValue(-1) + // scalastyle:on line.size.limit } private def getIntrinsicCode(target: AbstractMethodID): Int = diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/logging/Level.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/logging/Level.scala index 818118b3b5..196b9809c5 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/logging/Level.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/logging/Level.scala @@ -13,7 +13,7 @@ import scala.math.Ordered abstract sealed class Level extends Ordered[Level] { x => protected val order: Int - def compare(y: Level) = x.order - y.order + def compare(y: Level): Int = x.order - y.order } object Level { From abd3f390ea6fab62216bb82f5a362f9a4df123a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 10 Jun 2017 18:00:15 +0200 Subject: [PATCH 0347/2665] Forbid top-level exports to invalid JS identifiers. It won't be possible to export things as invalid JS identifiers when we export to the global scope or to ECMAScript 2015 modules. Therefore, we prevent that in the source code. In the rare cases that someone does want to do something like that, they can do it manually. For example, in a CommonJS module, one could use js.Dynamic.global.exports.`not-an-identifier` = 42; in a module initializer to export under a non-identifier. --- .../scalajs/core/compiler/PrepJSExports.scala | 9 +++ .../core/compiler/test/JSExportTest.scala | 60 +++++++++++++++++++ .../testsuite/jsinterop/ExportsTest.scala | 22 ------- 3 files changed, 69 insertions(+), 22 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala index cb125bcf90..f304c5246a 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala @@ -7,6 +7,8 @@ package org.scalajs.core.compiler import scala.collection.mutable +import org.scalajs.core.ir.Trees.isValidIdentifier + /** * Prepare export generation * @@ -317,6 +319,13 @@ trait PrepJSExports { this: PrepJSInterop => "Only static objects may export their members to the top level") } + // The top-level name must be a valid JS identifier + if (!isValidIdentifier(name.split('.').head)) { + reporter.error(annot.pos, + "The top-level export name must be a valid JavaScript " + + "identifier") + } + case ExportDestination.Static => def companionIsNonNativeJSClass: Boolean = { val companion = symOwner.companionClass diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index c0a17879bc..a4a62b3d39 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -930,6 +930,66 @@ class JSExportTest extends DirectTest with TestHelpers { """ } + @Test + def noExportTopLevelInvalidJSIdentifier: Unit = { + """ + @JSExportTopLevel("not-a-valid-JS-identifier-1") + object A + + @JSExportTopLevel("not-a-valid-JS-identifier-2") + class B + + object C { + @JSExportTopLevel("not-a-valid-JS-identifier-3") + val a: Int = 1 + + @JSExportTopLevel("not-a-valid-JS-identifier-4") + var b: Int = 1 + + @JSExportTopLevel("not-a-valid-JS-identifier-5") + def c(): Int = 1 + } + + @JSExportTopLevel("") + object D + + @JSExportTopLevel("not-a-valid-JS-identifier-6.foo") + object E + + @JSExportTopLevel("foo.not-a-valid-JS-identifier-7") // valid + object F + + @JSExportTopLevel(".tricky") + object G + """ hasErrors + """ + |newSource1.scala:3: error: The top-level export name must be a valid JavaScript identifier + | @JSExportTopLevel("not-a-valid-JS-identifier-1") + | ^ + |newSource1.scala:6: error: The top-level export name must be a valid JavaScript identifier + | @JSExportTopLevel("not-a-valid-JS-identifier-2") + | ^ + |newSource1.scala:10: error: The top-level export name must be a valid JavaScript identifier + | @JSExportTopLevel("not-a-valid-JS-identifier-3") + | ^ + |newSource1.scala:13: error: The top-level export name must be a valid JavaScript identifier + | @JSExportTopLevel("not-a-valid-JS-identifier-4") + | ^ + |newSource1.scala:16: error: The top-level export name must be a valid JavaScript identifier + | @JSExportTopLevel("not-a-valid-JS-identifier-5") + | ^ + |newSource1.scala:20: error: The top-level export name must be a valid JavaScript identifier + | @JSExportTopLevel("") + | ^ + |newSource1.scala:23: error: The top-level export name must be a valid JavaScript identifier + | @JSExportTopLevel("not-a-valid-JS-identifier-6.foo") + | ^ + |newSource1.scala:29: error: The top-level export name must be a valid JavaScript identifier + | @JSExportTopLevel(".tricky") + | ^ + """ + } + @Test def noExportTopLevelGetter: Unit = { """ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index d9bb1f279f..0333548632 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -1043,16 +1043,6 @@ class ExportsTest { assertThrows(classOf[Exception], foo.doA("a")) } - @Test def `exports_for_classes_ending_in__=_issue_1090`(): Unit = { - val constr = exportsNamespace.ExportClassSetterNamed_= - val obj = js.Dynamic.newInstance(constr)() - assertEquals(obj.x, 1) - } - - @Test def `exports_for_objects_ending_in__=_issue_1090`(): Unit = { - assertEquals(exportsNamespace.ExportObjSetterNamed_=.x, 1) - } - @Test def should_expose_public_members_of_new_js_Object_issue_1899(): Unit = { // Test that the bug is fixed for js.Any classes. @@ -1346,18 +1336,6 @@ object ExportedUnderOrgObject class SomeValueClass(val i: Int) extends AnyVal -@JSExportTopLevel("ExportClassSetterNamed_=") -class ExportClassSetterNamed_= { // scalastyle:ignore - @JSExport - val x = 1 -} - -@JSExportTopLevel("ExportObjSetterNamed_=") -object ExportObjSetterNamed_= { // scalastyle:ignore - @JSExport - val x = 1 -} - object ExportHolder { @JSExportTopLevel("qualified.nested.ExportedClass") class ExportedClass From 106ee37c5f1e7074ec3182ed40c35fd01ac046ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 14 Jun 2017 22:42:58 +0200 Subject: [PATCH 0348/2665] Add some tests for top-level exports under nested non-JS-identifiers. --- .../testsuite/jsinterop/ExportsTest.scala | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index 0333548632..e87337c4b7 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -732,6 +732,15 @@ class ExportsTest { assertTrue((obj: Any).isInstanceOf[ExportHolder.SJSDefinedExportedClass]) } + @Test def toplevel_exports_under_nested_invalid_js_identifier(): Unit = { + val constr = exportsNamespace.qualified.selectDynamic("not-a-JS-identifier") + assertJSNotUndefined(constr) + assertEquals("function", js.typeOf(constr)) + val obj = js.Dynamic.newInstance(constr)() + assertTrue( + (obj: Any).isInstanceOf[ExportHolder.ClassExportedUnderNestedInvalidJSIdentifier]) + } + @Test def exports_for_classes_with_constant_folded_name(): Unit = { val constr = exportsNamespace.ConstantFoldedClassExport assertJSNotUndefined(constr) @@ -1189,6 +1198,11 @@ class ExportsTest { assertEquals(10, jsPackage.toplevel.overload(1, 2, 3, 4)) } + @Test def method_top_level_export_under_invalid_js_identifier(): Unit = { + assertEquals("not an identifier", + jsPackage.toplevel.applyDynamic("not-a-JS-identifier")()) + } + @Test def top_level_export_uses_unique_object(): Unit = { jsPackage.toplevel.set(3) assertEquals(3, TopLevelExports.myVar) @@ -1345,6 +1359,9 @@ object ExportHolder { @JSExportTopLevel("qualified.nested.SJSDefinedExportedClass") class SJSDefinedExportedClass extends js.Object + + @JSExportTopLevel("qualified.not-a-JS-identifier") + class ClassExportedUnderNestedInvalidJSIdentifier } object TopLevelExports { @@ -1357,6 +1374,9 @@ object TopLevelExports { @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.overload") def overload(x: Int, y: Int*): Int = x + y.sum + @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.not-a-JS-identifier") + def methodExportedUnderNestedInvalidJSIdentifier(): String = "not an identifier" + var myVar: Int = _ @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.set") From 46a1d2903b63ebd69d6f81198cc56f9fcd41f160 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 13 Jun 2017 20:34:39 +0200 Subject: [PATCH 0349/2665] Make `js.Dynamic.global` user-defined again. Instead of it being a primitive, it can simply be a user-defined native JS object annotated with `@JSGlobalScope`. --- .../org/scalajs/core/compiler/GenJSCode.scala | 7 -- .../scalajs/core/compiler/JSDefinitions.scala | 1 - .../scalajs/core/compiler/JSPrimitives.scala | 4 +- .../compiler/test/JSGlobalScopeTest.scala | 104 ++++++++++++------ .../main/scala/scala/scalajs/js/Dynamic.scala | 30 ++++- 5 files changed, 103 insertions(+), 43 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 49235d88c1..68e11be5b7 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -1762,12 +1762,6 @@ abstract class GenJSCode extends plugins.PluginComponent MaybeGlobalScope.NotGlobalScope(genExpr(tree)) } - case Apply(fun, _) => - if (fun.symbol == JSDynamic_global) - MaybeGlobalScope.GlobalScope(pos) - else - MaybeGlobalScope.NotGlobalScope(genExpr(tree)) - case _ => MaybeGlobalScope.NotGlobalScope(genExpr(tree)) } @@ -4095,7 +4089,6 @@ abstract class GenJSCode extends plugins.PluginComponent } else (genArgs match { case Nil => code match { - case DYNGLOBAL => reportErrorLoadGlobalScope() case LINKING_INFO => js.JSLinkingInfo() case DEBUGGER => js.Debugger() case UNITVAL => js.Undefined() diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 0aa7a59633..fb56a17ed2 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -79,7 +79,6 @@ trait JSDefinitions { self: JSGlobalAddons => def JSAny_fromFunction(arity: Int): TermSymbol = getMemberMethod(JSAnyModule, newTermName("fromFunction"+arity)) lazy val JSDynamicModule = JSDynamicClass.companionModule - lazy val JSDynamic_global = getMemberMethod(JSDynamicModule, newTermName("global")) lazy val JSDynamic_newInstance = getMemberMethod(JSDynamicModule, newTermName("newInstance")) lazy val JSDynamicLiteral = getMemberModule(JSDynamicModule, newTermName("literal")) lazy val JSDynamicLiteral_applyDynamicNamed = getMemberMethod(JSDynamicLiteral, newTermName("applyDynamicNamed")) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala index 0a5d8cdf60..d156c71260 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala @@ -32,8 +32,7 @@ abstract class JSPrimitives { val F2JS = 305 // FunctionN to js.FunctionN val F2JSTHIS = 306 // FunctionN to js.ThisFunction{N-1} - val DYNGLOBAL = 320 // js.Dynamic.global - val DYNNEW = 321 // Instantiate a new JavaScript object + val DYNNEW = 321 // Instantiate a new JavaScript object val DYNLIT = 334 // js.Dynamic.literal.applyDynamic{,Named} @@ -86,7 +85,6 @@ abstract class JSPrimitives { for (i <- 1 to 22) addPrimitive(JSThisFunction_fromFunction(i), F2JSTHIS) - addPrimitive(JSDynamic_global, DYNGLOBAL) addPrimitive(JSDynamic_newInstance, DYNNEW) addPrimitive(JSDynamicLiteral_applyDynamicNamed, DYNLIT) diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSGlobalScopeTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSGlobalScopeTest.scala index 2a85e36907..0157172d9e 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSGlobalScopeTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSGlobalScopeTest.scala @@ -29,6 +29,8 @@ class JSGlobalScopeTest extends DirectTest with TestHelpers { def +(that: Int): Int = js.native + def apply(x: Int): Int = js.native + @JSBracketAccess def bracketSelect(name: String): Int = js.native @JSBracketAccess @@ -80,11 +82,11 @@ class JSGlobalScopeTest extends DirectTest with TestHelpers { } """ hasErrors s""" - |newSource1.scala:39: error: Loading the global scope as a value (anywhere but as the left-hand-side of a `.`-selection) is not allowed. + |newSource1.scala:41: error: Loading the global scope as a value (anywhere but as the left-hand-side of a `.`-selection) is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | val g1 = js.Dynamic.global | ^ - |newSource1.scala:40: error: Loading the global scope as a value (anywhere but as the left-hand-side of a `.`-selection) is not allowed. + |newSource1.scala:42: error: Loading the global scope as a value (anywhere but as the left-hand-side of a `.`-selection) is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | val g2 = SomeGlobalScope | ^ @@ -111,39 +113,39 @@ class JSGlobalScopeTest extends DirectTest with TestHelpers { } """ hasErrors s""" - |newSource1.scala:39: error: Selecting a field of the global scope whose name is not a valid JavaScript identifier is not allowed. + |newSource1.scala:41: error: Selecting a field of the global scope whose name is not a valid JavaScript identifier is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | val a = js.Dynamic.global.`not-a-valid-identifier-var` | ^ - |newSource1.scala:40: error: Selecting a field of the global scope whose name is not a valid JavaScript identifier is not allowed. + |newSource1.scala:42: error: Selecting a field of the global scope whose name is not a valid JavaScript identifier is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | js.Dynamic.global.`not-a-valid-identifier-var` = 3 | ^ - |newSource1.scala:41: error: Calling a method of the global scope whose name is not a valid JavaScript identifier is not allowed. + |newSource1.scala:43: error: Calling a method of the global scope whose name is not a valid JavaScript identifier is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | val b = js.Dynamic.global.`not-a-valid-identifier-def`() | ^ - |newSource1.scala:43: error: Selecting a field of the global scope whose name is not a valid JavaScript identifier is not allowed. + |newSource1.scala:45: error: Selecting a field of the global scope whose name is not a valid JavaScript identifier is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | val c = SomeGlobalScope.`not-a-valid-identifier-var` | ^ - |newSource1.scala:44: error: Selecting a field of the global scope whose name is not a valid JavaScript identifier is not allowed. + |newSource1.scala:46: error: Selecting a field of the global scope whose name is not a valid JavaScript identifier is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | SomeGlobalScope.`not-a-valid-identifier-var` = 3 | ^ - |newSource1.scala:45: error: Calling a method of the global scope whose name is not a valid JavaScript identifier is not allowed. + |newSource1.scala:47: error: Calling a method of the global scope whose name is not a valid JavaScript identifier is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | val d = SomeGlobalScope.`not-a-valid-identifier-def`() | ^ - |newSource1.scala:47: error: Selecting a field of the global scope whose name is not a valid JavaScript identifier is not allowed. + |newSource1.scala:49: error: Selecting a field of the global scope whose name is not a valid JavaScript identifier is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | val e = SomeGlobalScope.bracketSelect("not-a-valid-identifier-var") | ^ - |newSource1.scala:48: error: Selecting a field of the global scope whose name is not a valid JavaScript identifier is not allowed. + |newSource1.scala:50: error: Selecting a field of the global scope whose name is not a valid JavaScript identifier is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | SomeGlobalScope.bracketUpdate("not-a-valid-identifier-var", 3) | ^ - |newSource1.scala:49: error: Calling a method of the global scope whose name is not a valid JavaScript identifier is not allowed. + |newSource1.scala:51: error: Calling a method of the global scope whose name is not a valid JavaScript identifier is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | val f = SomeGlobalScope.bracketCall("not-a-valid-identifier-def")(4) | ^ @@ -152,23 +154,63 @@ class JSGlobalScopeTest extends DirectTest with TestHelpers { @Test def rejectJSOperators: Unit = { - s""" + """ object Main { def main(): Unit = { val a = js.Dynamic.global + 3.asInstanceOf[js.Dynamic] + } + } + """ hasErrors + s""" + |newSource1.scala:41: error: type mismatch; + | found : scala.scalajs.js.Dynamic + | required: String + | val a = js.Dynamic.global + 3.asInstanceOf[js.Dynamic] + | ^ + """ - val b = SomeGlobalScope + 3 + """ + object Main { + def main(): Unit = { + val a = SomeGlobalScope + 3 } } """ hasErrors s""" - |newSource1.scala:39: error: Loading the global scope as a value (anywhere but as the left-hand-side of a `.`-selection) is not allowed. + |newSource1.scala:41: error: Loading the global scope as a value (anywhere but as the left-hand-side of a `.`-selection) is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. - | val a = js.Dynamic.global + 3.asInstanceOf[js.Dynamic] + | val a = SomeGlobalScope + 3 + | ^ + """ + } + + @Test + def rejectApply: Unit = { + """ + object Main { + def main(): Unit = { + val a = js.Dynamic.global(3) + } + } + """ hasErrors + s""" + |newSource1.scala:41: error: Loading the global scope as a value (anywhere but as the left-hand-side of a `.`-selection) is not allowed. + | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. + | val a = js.Dynamic.global(3) | ^ + """ + + """ + object Main { + def main(): Unit = { + val a = SomeGlobalScope(3) + } + } + """ hasErrors + s""" |newSource1.scala:41: error: Loading the global scope as a value (anywhere but as the left-hand-side of a `.`-selection) is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. - | val b = SomeGlobalScope + 3 + | val a = SomeGlobalScope(3) | ^ """ } @@ -195,39 +237,39 @@ class JSGlobalScopeTest extends DirectTest with TestHelpers { } """ hasErrors s""" - |newSource1.scala:41: error: Selecting a field of the global scope with a dynamic name is not allowed. + |newSource1.scala:43: error: Selecting a field of the global scope with a dynamic name is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | val a = js.Dynamic.global.selectDynamic(dynName) | ^ - |newSource1.scala:42: error: Selecting a field of the global scope with a dynamic name is not allowed. + |newSource1.scala:44: error: Selecting a field of the global scope with a dynamic name is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | js.Dynamic.global.updateDynamic(dynName)(3) | ^ - |newSource1.scala:43: error: Calling a method of the global scope with a dynamic name is not allowed. + |newSource1.scala:45: error: Calling a method of the global scope with a dynamic name is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | val b = js.Dynamic.global.applyDynamic(dynName)(3) | ^ - |newSource1.scala:45: error: Selecting a field of the global scope with a dynamic name is not allowed. + |newSource1.scala:47: error: Selecting a field of the global scope with a dynamic name is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | val e = SomeGlobalScope.bracketSelect(dynName) | ^ - |newSource1.scala:46: error: Selecting a field of the global scope with a dynamic name is not allowed. + |newSource1.scala:48: error: Selecting a field of the global scope with a dynamic name is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | SomeGlobalScope.bracketUpdate(dynName, 3) | ^ - |newSource1.scala:47: error: Calling a method of the global scope with a dynamic name is not allowed. + |newSource1.scala:49: error: Calling a method of the global scope with a dynamic name is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | val f = SomeGlobalScope.bracketCall(dynName)(4) | ^ - |newSource1.scala:49: error: Selecting a field of the global scope with a dynamic name is not allowed. + |newSource1.scala:51: error: Selecting a field of the global scope with a dynamic name is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | val i = SomeGlobalScope.symbolVar | ^ - |newSource1.scala:50: error: Selecting a field of the global scope with a dynamic name is not allowed. + |newSource1.scala:52: error: Selecting a field of the global scope with a dynamic name is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | SomeGlobalScope.symbolVar = 3 | ^ - |newSource1.scala:51: error: Calling a method of the global scope with a dynamic name is not allowed. + |newSource1.scala:53: error: Calling a method of the global scope with a dynamic name is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | val k = SomeGlobalScope.symbolDef() | ^ @@ -250,27 +292,27 @@ class JSGlobalScopeTest extends DirectTest with TestHelpers { } """ hasErrors s""" - |newSource1.scala:39: error: Selecting a field of the global scope whose name is `arguments` is not allowed. + |newSource1.scala:41: error: Selecting a field of the global scope whose name is `arguments` is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | val a = js.Dynamic.global.arguments | ^ - |newSource1.scala:40: error: Selecting a field of the global scope whose name is `arguments` is not allowed. + |newSource1.scala:42: error: Selecting a field of the global scope whose name is `arguments` is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | js.Dynamic.global.arguments = null | ^ - |newSource1.scala:41: error: Calling a method of the global scope whose name is `arguments` is not allowed. + |newSource1.scala:43: error: Calling a method of the global scope whose name is `arguments` is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | val b = js.Dynamic.global.arguments(5) | ^ - |newSource1.scala:43: error: Selecting a field of the global scope whose name is `arguments` is not allowed. + |newSource1.scala:45: error: Selecting a field of the global scope whose name is `arguments` is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | val c = SomeGlobalScope.arguments | ^ - |newSource1.scala:44: error: Selecting a field of the global scope whose name is `arguments` is not allowed. + |newSource1.scala:46: error: Selecting a field of the global scope whose name is `arguments` is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | SomeGlobalScope.arguments = null | ^ - |newSource1.scala:45: error: Calling a method of the global scope whose name is `arguments` is not allowed. + |newSource1.scala:47: error: Calling a method of the global scope whose name is `arguments` is not allowed. | See https://www.scala-js.org/doc/interoperability/global-scope.html for further information. | val d = SomeGlobalScope.arguments2(5) | ^ diff --git a/library/src/main/scala/scala/scalajs/js/Dynamic.scala b/library/src/main/scala/scala/scalajs/js/Dynamic.scala index 0e854eaaee..a175e53542 100644 --- a/library/src/main/scala/scala/scalajs/js/Dynamic.scala +++ b/library/src/main/scala/scala/scalajs/js/Dynamic.scala @@ -76,7 +76,35 @@ sealed trait Dynamic extends js.Any with scala.Dynamic { /** Factory for dynamically typed JavaScript values. */ object Dynamic { /** Dynamic view of the global scope. */ - def global: js.Dynamic = throw new java.lang.Error("stub") + @js.native + @JSGlobalScope + object global extends js.Any with scala.Dynamic { // scalastyle:ignore + /** 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: js.Dynamic)(args: js.Any*): js.Object with js.Dynamic = From e02799b636b577eb56593d08c21a7cb2e68719e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 14 Jun 2017 16:48:34 +0200 Subject: [PATCH 0350/2665] Fix #3013: Use `genExpr()` for the qualifier of super calls. Since Scala 2.12, the `qual` part of a super call is not always `this`. It can be `this.$outer()` or similar things. Therefore, we cannot blindly assume that the receiver is `this`, nor that the super call is a JS super call iff the current class is a JS class. Instead, we correctly use `genExpr(qual)` and inspect `isRawJSType(qual.tpe)`. --- .../org/scalajs/core/compiler/GenJSCode.scala | 19 +++++--- .../testsuite/compiler/RegressionJSTest.scala | 44 +++++++++++++++++++ .../testsuite/compiler/RegressionTest.scala | 37 ++++++++++++++++ 3 files changed, 95 insertions(+), 5 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 50140d82a0..5c1138a116 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -2342,10 +2342,10 @@ abstract class GenJSCode extends plugins.PluginComponent */ private def genSuperCall(tree: Apply, isStat: Boolean): js.Tree = { implicit val pos = tree.pos - val Apply(fun @ Select(sup @ Super(_, mix), _), args) = tree + val Apply(fun @ Select(sup @ Super(qual, _), _), args) = tree val sym = fun.symbol - if (isScalaJSDefinedJSClass(currentClassSym)) { + if (isRawJSType(qual.tpe)) { if (sym.isMixinConstructor) { /* Do not emit a call to the $init$ method of JS traits. * This exception is necessary because @JSOptional fields cause the @@ -2356,8 +2356,11 @@ abstract class GenJSCode extends plugins.PluginComponent genJSSuperCall(tree, isStat) } } else { + /* #3013 `qual` can be `this.$outer()` in some cases since Scala 2.12, + * so we call `genExpr(qual)`, not just `genThis()`. + */ val superCall = genApplyMethodStatically( - genThis()(sup.pos), sym, genActualArgs(sym, args)) + genExpr(qual), sym, genActualArgs(sym, args)) // Initialize the module instance just after the super constructor call. if (isStaticModule(currentClassSym) && !isModuleInitialized.value && @@ -4195,10 +4198,13 @@ abstract class GenJSCode extends plugins.PluginComponent private def genJSSuperCall(tree: Apply, isStat: Boolean): js.Tree = { implicit val pos = tree.pos - val Apply(fun @ Select(sup @ Super(_, _), _), args) = tree + val Apply(fun @ Select(sup @ Super(qual, _), _), args) = tree val sym = fun.symbol - val genReceiver = genThis()(sup.pos) + /* #3013 `qual` can be `this.$outer()` in some cases since Scala 2.12, + * so we call `genExpr(qual)`, not just `genThis()`. + */ + val genReceiver = genExpr(qual) lazy val genScalaArgs = genActualArgs(sym, args) lazy val genJSArgs = genPrimitiveJSArgs(sym, args) @@ -4209,6 +4215,9 @@ abstract class GenJSCode extends plugins.PluginComponent s"Scala.js-defined 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)) { // Reroute to the static method diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala index 3375fe5aad..177a64175f 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala @@ -14,6 +14,7 @@ import org.junit.Test import org.junit.Assert._ class RegressionJSTest { + import RegressionJSTest._ @Test def should_not_swallow_Unit_expressions_when_converting_to_js_Any_issue_83(): Unit = { var effectHappened = false @@ -53,4 +54,47 @@ class RegressionJSTest { assertTrue(js.isUndefined(js.constructorOf[Foo].y)) } + @Test def super_mixin_call_in_2_12_issue_3013_ScalaOuter_JSInner(): Unit = { + import Bug3013_ScalaOuter_JSInner._ + + val b = new B + val c = new b.C + assertEquals("A1", c.t1()) + assertEquals("A2", c.t2()) + assertEquals("B", c.t3()) + } + +} + +object RegressionJSTest { + + /* The combination Scala/Scala is done in the cross-platform RegressionTest. + * + * The combinations where the outer class is a JS type cannot happen by + * construction, because they would require a non-native JS trait with a + * concrete method, which is prohibited. + */ + object Bug3013_ScalaOuter_JSInner { + trait A1 { + private val s = "A1" + def f(): String = s + } + + trait A2 { + private val s = "A2" + def f(): String = s + } + + class B extends A1 with A2 { + override def f(): String = "B" + + @ScalaJSDefined + class C extends js.Object { + def t1(): String = B.super[A1].f() + def t2(): String = B.super[A2].f() + def t3(): String = B.this.f() + } + } + } + } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala index ac638c1790..1f8713596d 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala @@ -588,6 +588,21 @@ class RegressionTest { assertFalse("String", c.isInstanceOf[String]) } + @Test def super_mixin_call_in_2_12_issue_3013(): Unit = { + assumeTrue( + "Super mixin calls are broken in Scala/JVM 2.12.{0-2} and 2.13.0-M1", + !Platform.executingInJVM || + !Set("2.12.0", "2.12.1", "2.12.2", "2.13.0-M1").contains(Platform.scalaVersion)) + + import Bug3013._ + + val b = new B + val c = new b.C + assertEquals("A1", c.t1) + assertEquals("A2", c.t2) + assertEquals("B", c.t3) + } + } object RegressionTest { @@ -616,4 +631,26 @@ object RegressionTest { if (false) () } } + + object Bug3013 { + trait A1 { + private val s = "A1" + def f: String = s + } + + trait A2 { + private val s = "A2" + def f: String = s + } + + class B extends A1 with A2 { + override def f: String = "B" + + class C { + def t1: String = B.super[A1].f + def t2: String = B.super[A2].f + def t3: String = B.this.f + } + } + } } From 7e990da81603f095a2d333952e0e608748a08cf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 15 Jun 2017 00:32:09 +0200 Subject: [PATCH 0351/2665] Remove a debugging warning in the sbt plugin. It was erroneously introduced in 481dfb59ae4d5e2a1be10db00700fc874f5bd2ab. --- .../main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index b242ca58e0..c3fb38a17b 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -270,7 +270,6 @@ object ScalaJSPluginInternal { val log = s.log val realFiles = irInfo.get(scalaJSSourceFiles).get val ir = irInfo.data - log.warn(s.cacheDirectory.toString) FileFunction.cached(s.cacheDirectory, FilesInfo.lastModified, FilesInfo.exists) { _ => // We don't need the files From e24fc59912f0ab004719343bbd11eb718cce6678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 15 Jun 2017 00:34:20 +0200 Subject: [PATCH 0352/2665] Set the linkers of the CLI, partest and QuickLinker in batch mode. It is of course completely useless, because currently the linker ignores that setting, but it makes sense. --- cli/src/main/scala/org/scalajs/cli/Scalajsld.scala | 1 + .../src/main/scala/scala/tools/nsc/MainGenericRunner.scala | 1 + .../scala/org/scalajs/core/tools/test/js/QuickLinker.scala | 6 ++++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala b/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala index 3814a0a60a..f63f8716e8 100644 --- a/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala +++ b/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala @@ -198,6 +198,7 @@ object Scalajsld { .withRelativizeSourceMapBase(options.relativizeSourceMap) .withClosureCompiler(options.fullOpt) .withPrettyPrint(options.prettyPrint) + .withBatchMode(true) val linker = StandardLinker(config) val logger = new ScalaConsoleLogger(options.logLevel) diff --git a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala index c389cbcb27..c2bf750f1b 100644 --- a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala +++ b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala @@ -67,6 +67,7 @@ class MainGenericRunner { .withSemantics(semantics) .withSourceMap(false) .withClosureCompiler(optMode == FullOpt) + .withBatchMode(true) val linker = StandardLinker(linkerConfig) diff --git 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 index 4cf5285849..78304db3a8 100644 --- 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 @@ -36,8 +36,10 @@ object QuickLinker { irFilesAndJars: Seq[String], moduleInitializers: Seq[String]): String = { val cache = (new IRFileCache).newCache - val linker = - StandardLinker(StandardLinker.Config().withSemantics(semantics)) + val config = StandardLinker.Config() + .withSemantics(semantics) + .withBatchMode(true) + val linker = StandardLinker(config) val irContainers = irFilesAndJars.map { file => if (file.endsWith(".jar")) { From 1ae82be52e251aa5420a01138ed7e0a707835949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 15 Jun 2017 00:48:51 +0200 Subject: [PATCH 0353/2665] Fix #3000: Fix the linker config of partest for `--{no,full}Opt`. * `--noOpt` was not honored at all: the optimizer was not disabled * `--fullOpt` enabled GCC but did not use the optimized semantics --- .../src/main/scala/scala/tools/nsc/MainGenericRunner.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala index c2bf750f1b..9ac74d4df0 100644 --- a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala +++ b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala @@ -57,7 +57,8 @@ class MainGenericRunner { val logger = new ScalaConsoleLogger(Level.Warn) val jsConsole = new ScalaConsoleJSConsole - val semantics = readSemantics() + val semantics0 = readSemantics() + val semantics = if (optMode == FullOpt) semantics0.optimized else semantics0 val ir = loadIR(command.settings.classpathURLs) val moduleInitializers = Seq(ModuleInitializer.mainMethodWithArgs( @@ -66,6 +67,7 @@ class MainGenericRunner { val linkerConfig = StandardLinker.Config() .withSemantics(semantics) .withSourceMap(false) + .withOptimizer(optMode != NoOpt) .withClosureCompiler(optMode == FullOpt) .withBatchMode(true) From 74c9af0d85b08e92435b488b97c8f6ac5392002f Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 9 Jun 2017 18:11:54 +0200 Subject: [PATCH 0354/2665] Fix #2945: Leave it to sbt to buffer logs When we created the test adapter, we implemented log buffering ourselves to prevent interleaved output when running in parallel. However, this is not necessary since sbt implements its own log buffering. To make matters worse, this interfered with it. We fully remove log buffering in the test adapter while keeping an escape hatch (via Java system properites) in case something goes wrong. --- .../scalajs/sbttestadapter/ScalaJSTask.scala | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSTask.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSTask.scala index f6659ada77..08e5e046b8 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSTask.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSTask.scala @@ -14,6 +14,7 @@ import org.scalajs.core.tools.json._ import org.scalajs.jsenv._ import scala.collection.mutable +import scala.util.Try import sbt.testing._ @@ -45,15 +46,25 @@ final class ScalaJSTask private ( slave.send("execute:" + jsonToString(data)) // Prepare result handler + // TODO rip this out once we know it doesn't garble the logs. + val shouldBufferLog = { + val propName = "org.scalajs.testadapter.bufferlog" + Try(System.getProperty(propName, "false").toBoolean).getOrElse(false) + } + val logBuffer = mutable.Buffer.empty[LogElement[_]] + val logger: LogElement[_] => Unit = + if (shouldBufferLog) logBuffer += _ + else _.call(loggers) + val doneHandler: LoopHandler[List[TaskInfo]] = { case ("ok", msg) => Some(fromJSON[List[TaskInfo]](readJSON(msg))) } val handlerChain = ( eventHandler(handler) orElse - loggerHandler(logBuffer) orElse + loggerHandler(logger) orElse runner.msgHandler(slave) orElse doneHandler) @@ -61,8 +72,10 @@ final class ScalaJSTask private ( val taskInfos = ComUtils.receiveLoop(slave)(handlerChain) // Flush log buffer - runner.loggerLock.synchronized { - logBuffer.foreach(_.call(loggers)) + if (shouldBufferLog) { + runner.loggerLock.synchronized { + logBuffer.foreach(_.call(loggers)) + } } taskInfos.map(ScalaJSTask.fromInfo(runner, _)).toArray @@ -76,7 +89,7 @@ final class ScalaJSTask private ( } private def loggerHandler( - buf: mutable.Buffer[LogElement[_]]): LoopHandler[Nothing] = { + logger: LogElement[_] => Unit): LoopHandler[Nothing] = { def processData(data: String) = { val pos = data.indexOf(':') @@ -89,7 +102,7 @@ final class ScalaJSTask private ( def log(level: Logger => (String => Unit), data: String) = { val (index, msg) = processData(data) - buf += new LogElement(index, level, msg) + logger(new LogElement(index, level, msg)) None } @@ -101,7 +114,7 @@ final class ScalaJSTask private ( case ("trace", data) => val (index, innerData) = processData(data) val throwable = fromJSON[RemoteException](readJSON(innerData)) - buf += new LogElement(index, _.trace, throwable) + logger(new LogElement(index, _.trace, throwable)) None } From bce1a2109fbf5e76a3940137e29c8c85c61ba053 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 10 Jun 2017 11:31:15 +0200 Subject: [PATCH 0355/2665] Move the `tools.json` package exclusively in the JVM sources. This effectively removes that API from the JS version of the tools. In the process, we get rid of `AbstractJSONImpl`, which is useless in this setup. --- .../org/scalajs/core/tools/json/Impl.scala | 36 ------------------- .../org/scalajs/core/tools/json/Impl.scala | 2 +- .../core/tools/json/JSONDeserializer.scala | 0 .../core/tools/json/JSONObjBuilder.scala | 0 .../core/tools/json/JSONObjExtractor.scala | 0 .../core/tools/json/JSONSerializer.scala | 0 .../org/scalajs/core/tools/json/package.scala | 0 .../core/tools/json/AbstractJSONImpl.scala | 32 ----------------- 8 files changed, 1 insertion(+), 69 deletions(-) delete mode 100644 tools/js/src/main/scala/org/scalajs/core/tools/json/Impl.scala rename tools/{shared => jvm}/src/main/scala/org/scalajs/core/tools/json/JSONDeserializer.scala (100%) rename tools/{shared => jvm}/src/main/scala/org/scalajs/core/tools/json/JSONObjBuilder.scala (100%) rename tools/{shared => jvm}/src/main/scala/org/scalajs/core/tools/json/JSONObjExtractor.scala (100%) rename tools/{shared => jvm}/src/main/scala/org/scalajs/core/tools/json/JSONSerializer.scala (100%) rename tools/{shared => jvm}/src/main/scala/org/scalajs/core/tools/json/package.scala (100%) delete mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/json/AbstractJSONImpl.scala diff --git a/tools/js/src/main/scala/org/scalajs/core/tools/json/Impl.scala b/tools/js/src/main/scala/org/scalajs/core/tools/json/Impl.scala deleted file mode 100644 index bb328e4bcd..0000000000 --- a/tools/js/src/main/scala/org/scalajs/core/tools/json/Impl.scala +++ /dev/null @@ -1,36 +0,0 @@ -package org.scalajs.core.tools.json - -import org.scalajs.core.tools.io.IO - -import scala.scalajs.js - -import java.io.{Writer, Reader} - -private[json] object Impl extends AbstractJSONImpl { - - type Repr = js.Any - - def fromString(x: String): Repr = x - def fromNumber(x: Number): Repr = x.doubleValue() - def fromBoolean(x: Boolean): Repr = x - def fromList(x: List[Repr]): Repr = js.Array(x: _*) - def fromMap(x: Map[String, Repr]): Repr = js.Dictionary(x.toSeq: _*) - - def toString(x: Repr): String = x.asInstanceOf[String] - def toNumber(x: Repr): Number = x.asInstanceOf[Double] - def toBoolean(x: Repr): Boolean = x.asInstanceOf[Boolean] - def toList(x: Repr): List[Repr] = x.asInstanceOf[js.Array[Repr]].toList - def toMap(x: Repr): Map[String, Repr] = - x.asInstanceOf[js.Dictionary[Repr]].toMap - - def serialize(x: Repr): String = js.JSON.stringify(x) - - def serialize(x: Repr, writer: Writer): Unit = - writer.write(serialize(x)) - - def deserialize(str: String): Repr = js.JSON.parse(str) - - def deserialize(reader: Reader): Repr = - deserialize(IO.readReaderToString(reader)) - -} diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/json/Impl.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/json/Impl.scala index 08e9f88498..ff8201b178 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/json/Impl.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/json/Impl.scala @@ -6,7 +6,7 @@ import scala.collection.JavaConverters._ import java.io.{Writer, Reader} -private[json] object Impl extends AbstractJSONImpl { +private[json] object Impl { type Repr = Object diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONDeserializer.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/json/JSONDeserializer.scala similarity index 100% rename from tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONDeserializer.scala rename to tools/jvm/src/main/scala/org/scalajs/core/tools/json/JSONDeserializer.scala diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONObjBuilder.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/json/JSONObjBuilder.scala similarity index 100% rename from tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONObjBuilder.scala rename to tools/jvm/src/main/scala/org/scalajs/core/tools/json/JSONObjBuilder.scala diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONObjExtractor.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/json/JSONObjExtractor.scala similarity index 100% rename from tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONObjExtractor.scala rename to tools/jvm/src/main/scala/org/scalajs/core/tools/json/JSONObjExtractor.scala diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONSerializer.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/json/JSONSerializer.scala similarity index 100% rename from tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONSerializer.scala rename to tools/jvm/src/main/scala/org/scalajs/core/tools/json/JSONSerializer.scala diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/json/package.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/json/package.scala similarity index 100% rename from tools/shared/src/main/scala/org/scalajs/core/tools/json/package.scala rename to tools/jvm/src/main/scala/org/scalajs/core/tools/json/package.scala diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/json/AbstractJSONImpl.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/json/AbstractJSONImpl.scala deleted file mode 100644 index 2aa8dc4955..0000000000 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/json/AbstractJSONImpl.scala +++ /dev/null @@ -1,32 +0,0 @@ -package org.scalajs.core.tools.json - -import java.io.{Reader, Writer} - -/** A JSON implementation. Has a representation type and methods to convert - * this type to/from primitives, lists and maps. - * - * Further, it can write/read a value of this type to a string. - */ -private[json] trait AbstractJSONImpl { - - type Repr - - def fromString(x: String): Repr - def fromNumber(x: Number): Repr - def fromBoolean(x: Boolean): Repr - def fromList(x: List[Repr]): Repr - def fromMap(x: Map[String, Repr]): Repr - - def toString(x: Repr): String - def toNumber(x: Repr): Number - def toBoolean(x: Repr): Boolean - def toList(x: Repr): List[Repr] - def toMap(x: Repr): Map[String, Repr] - - def serialize(x: Repr): String - def serialize(x: Repr, writer: Writer): Unit - - def deserialize(str: String): Repr - def deserialize(reader: Reader): Repr - -} From a9ee15e1a2b4efd64b62ae7572e2eb4684bb632d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 10 Jun 2017 13:02:39 +0200 Subject: [PATCH 0356/2665] Do not rely on the `tools.json` API in `Build.scala`. --- project/Build.scala | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index acc6ddc3c4..2cc441b6bb 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -29,7 +29,6 @@ import Loggers._ import org.scalajs.core.tools.io.{FileVirtualJSFile, MemVirtualJSFile} import org.scalajs.core.tools.sem._ -import org.scalajs.core.tools.json._ import org.scalajs.core.tools.linker.ModuleInitializer import org.scalajs.core.tools.linker.backend.OutputMode @@ -1412,9 +1411,13 @@ object Build { val patchedSystemProperties = (scalaJSJavaSystemProperties in (Test, testHtml)).value + val formattedProps = patchedSystemProperties.map { + case (propName, propValue) => + "\"" + escapeJS(propName) + "\": \"" + escapeJS(propValue) + "\"" + }.mkString("{ ", ", ", " }") val code = s""" var __ScalaJSEnv = { - javaSystemProperties: ${jsonToString(patchedSystemProperties.toJSON)} + javaSystemProperties: $formattedProps }; """ From 19dddec2441532d376d7eaa16cb2cb9f47eb6c83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 10 Jun 2017 16:28:49 +0200 Subject: [PATCH 0357/2665] Move FrameworkDetector and HTMLRunnerTemplate to test-adapter. These two services were `private[sbtplugin]`, but a) they could be needed by other build tools and b) they require cooperation from the test-interface. Therefore, it is pretty clear that they must be public services of the test-adapter. Moving them required significant amendments, because they relied on `sbt.TestFramework` and `sbt.TestDefinition`, which are not available in the context of the test-adapter. --- project/Build.scala | 14 ++- project/HTMLRunnerBuilderAccess.scala | 13 ++ project/HTMLRunnerTemplateAccess.scala | 12 -- project/build.sbt | 2 +- .../scalajs/sbtplugin/FrameworkDetector.scala | 94 -------------- .../sbtplugin/HTMLRunnerTemplate.scala | 69 ----------- .../sbtplugin/ScalaJSPluginInternal.scala | 64 +++------- .../org/scalajs/testadapter}/test-runner.css | 0 .../sbttestadapter/FrameworkDetector.scala | 116 ++++++++++++++++++ .../sbttestadapter/HTMLRunnerBuilder.scala | 104 ++++++++++++++++ .../sbttestadapter/ScalaJSFramework.scala | 9 +- 11 files changed, 271 insertions(+), 226 deletions(-) create mode 100644 project/HTMLRunnerBuilderAccess.scala delete mode 100644 project/HTMLRunnerTemplateAccess.scala delete mode 100644 sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala delete mode 100644 sbt-plugin/src/main/scala/org/scalajs/sbtplugin/HTMLRunnerTemplate.scala rename {sbt-plugin/src/main/resources/org/scalajs/sbtplugin => test-adapter/src/main/resources/org/scalajs/testadapter}/test-runner.css (100%) create mode 100644 test-adapter/src/main/scala/org/scalajs/sbttestadapter/FrameworkDetector.scala create mode 100644 test-adapter/src/main/scala/org/scalajs/sbttestadapter/HTMLRunnerBuilder.scala diff --git a/project/Build.scala b/project/Build.scala index 2cc441b6bb..e067a7f7d1 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -641,10 +641,18 @@ object Build { org.scalajs.core.tools.linker.backend.ModuleKind.CommonJSModule, jsExecutionFiles in Test := { + val frameworks = (loadedTestFrameworks in testSuite in Test).value + val frameworkImplClassNames = + frameworks.toList.map(_._1.implClassNames.toList) + + val taskDefs = for (td <- (definedTests in testSuite in Test).value) yield { + new sbt.testing.TaskDef(td.name, td.fingerprint, + td.explicitlySpecified, td.selectors) + } + val testDefinitions = { - org.scalajs.build.HTMLRunnerTemplateAccess.renderTestDefinitions( - (loadedTestFrameworks in testSuite in Test).value, - (definedTests in testSuite in Test).value) + org.scalajs.build.HTMLRunnerBuilderAccess.renderTestDefinitions( + frameworkImplClassNames, taskDefs.toList) } val testDefinitionsFile = { diff --git a/project/HTMLRunnerBuilderAccess.scala b/project/HTMLRunnerBuilderAccess.scala new file mode 100644 index 0000000000..f33cb718b0 --- /dev/null +++ b/project/HTMLRunnerBuilderAccess.scala @@ -0,0 +1,13 @@ +package org.scalajs.build + +import sbt.testing.TaskDef + +/** Accessor for renderTestDefinitions to avoid exposing things. */ +object HTMLRunnerBuilderAccess { + def renderTestDefinitions( + frameworkImplClassNames: List[List[String]], + taskDefs: List[TaskDef]): String = { + org.scalajs.testadapter.HTMLRunnerBuilder.renderTestDefinitions( + frameworkImplClassNames, taskDefs) + } +} diff --git a/project/HTMLRunnerTemplateAccess.scala b/project/HTMLRunnerTemplateAccess.scala deleted file mode 100644 index 40dc332450..0000000000 --- a/project/HTMLRunnerTemplateAccess.scala +++ /dev/null @@ -1,12 +0,0 @@ -package org.scalajs.build - -import sbt.testing.Framework - -/** Accessor for renderTestDefinitions to avoid exposing things. */ -object HTMLRunnerTemplateAccess { - def renderTestDefinitions(loadedFrameworks: Map[sbt.TestFramework, Framework], - definedTests: Seq[sbt.TestDefinition]): String = { - org.scalajs.sbtplugin.HTMLRunnerTemplate.renderTestDefinitions( - loadedFrameworks, definedTests) - } -} diff --git a/project/build.sbt b/project/build.sbt index c72ce19f7f..986409d885 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -46,5 +46,5 @@ sourceGenerators in Compile += Def.task { unmanagedResourceDirectories in Compile += { val root = baseDirectory.value.getParentFile - root / "sbt-plugin/src/main/resources" + root / "test-adapter/src/main/resources" } diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala deleted file mode 100644 index db38db7de7..0000000000 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala +++ /dev/null @@ -1,94 +0,0 @@ -package org.scalajs.sbtplugin - -import sbt._ - -import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.json._ -import org.scalajs.core.tools.logging.Logger -import org.scalajs.core.tools.linker.backend.ModuleKind - -import org.scalajs.jsenv._ - -import scala.collection.mutable - -private[sbtplugin] final class FrameworkDetector(jsEnv: JSEnv, - jsFiles: Seq[VirtualJSFile], moduleKind: ModuleKind, - moduleIdentifier: Option[String]) { - - import FrameworkDetector._ - - /** - * Detects which of the test frameworks in `frameworks` exists on - * the classpath. - * - * Each potential name in each [[sbt.TestFramework TestFramework]] is checked - * for existance (on the JavaScript global namespace, using nested bracket select). - * - * Returns a map with found frameworks and the first name with an existing - * definition on the classpath. - * - * Note: No JavaScript type tests are performed by this method - */ - def detect(frameworks: Seq[TestFramework], - logger: Logger): Map[TestFramework, String] = { - val data = frameworks.map(_.implClassNames.toList).toList.toJSON - - val exportsNamespaceExpr = - ScalaJSPluginInternal.makeExportsNamespaceExpr(moduleKind, moduleIdentifier) - - val code = s""" - (function(exportsNamespace) { - "use strict"; - - /* #2752: if there is no testing framework at all on the classpath, - * the testing interface will not be there, and therefore the - * `detectFrameworks` function will not exist. We must therefore be - * careful when selecting it. - */ - var namespace = exportsNamespace; - namespace = namespace.org || {}; - namespace = namespace.scalajs || {}; - namespace = namespace.testinterface || {}; - namespace = namespace.internal || {}; - var detectFrameworksFun = namespace.detectFrameworks || (function(data) { - var results = []; - for (var i = 0; i < data.length; ++i) - results.push(void 0); - return results; - }); - - var data = ${jsonToString(data)}; - var results = detectFrameworksFun(data); - for (var i = 0; i < results.length; ++i) { - console.log("$ConsoleFrameworkPrefix" + (results[i] || "")); - } - })($exportsNamespaceExpr); - """ - - val vf = new MemVirtualJSFile("frameworkDetector.js").withContent(code) - val console = new StoreConsole - - val runner = jsEnv.jsRunner(jsFiles :+ vf) - runner.run(logger, console) - - // Filter jsDependencies unexpected output - val results = console.buf collect { - case s if s.startsWith(ConsoleFrameworkPrefix) => - s.stripPrefix(ConsoleFrameworkPrefix) - } - - assert(results.size == frameworks.size) - - (frameworks zip results).filter(_._2.nonEmpty).toMap - } - -} - -object FrameworkDetector { - private class StoreConsole extends JSConsole { - val buf = mutable.Buffer.empty[String] - def log(msg: Any): Unit = buf += msg.toString - } - - private val ConsoleFrameworkPrefix = "@scalajs-test-framework-detector:" -} diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/HTMLRunnerTemplate.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/HTMLRunnerTemplate.scala deleted file mode 100644 index 58acfdd60f..0000000000 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/HTMLRunnerTemplate.scala +++ /dev/null @@ -1,69 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.sbtplugin - -import java.net.URI - -import sbt.testing.{Framework, TaskDef} - -import org.scalajs.core.ir.Utils -import org.scalajs.core.tools.json._ -import org.scalajs.testadapter.TaskDefSerializers._ - -/** Template for the HTML runner. */ -private[scalajs] object HTMLRunnerTemplate { - - def render(baseURI: URI, title: String, jsFiles: Seq[URI], - css: URI, loadedFrameworks: Map[sbt.TestFramework, Framework], - definedTests: Seq[sbt.TestDefinition]): String = { - def relURI(uri: URI) = - htmlEscaped(Utils.relativize(baseURI, uri).toASCIIString) - - s""" - - - - ${htmlEscaped(title)} - - - ${(for (jsFile <- jsFiles) yield s""" - - """).mkString("")} - - - - """ - } - - def renderTestDefinitions( - loadedFrameworks: Map[sbt.TestFramework, Framework], - definedTests: Seq[sbt.TestDefinition]): String = { - val frameworks = loadedFrameworks.map(_._1.implClassNames.toList).toList - - val tests = definedTests.map { t => - new TaskDef(t.name, t.fingerprint, t.explicitlySpecified, t.selectors) - }.toList - - s""" - var definedTests = ${jsonToString(tests.toJSON)}; - var testFrameworkNames = ${jsonToString(frameworks.toJSON)}; - """ - } - - private def htmlEscaped(str: String): String = str.flatMap { - case '<' => "<" - case '>' => ">" - case '"' => """ - case '&' => "&" - case c => c :: Nil - } -} diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 4889cfdcd5..a9fa29a9b2 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -26,7 +26,7 @@ import org.scalajs.core.ir.Utils.escapeJS import org.scalajs.core.ir.ScalaJSVersions import org.scalajs.core.ir.Printers.{InfoPrinter, IRTreePrinter} -import org.scalajs.testadapter.ScalaJSFramework +import org.scalajs.testadapter.{FrameworkDetector, HTMLRunnerBuilder} import scala.util.Try import scala.collection.mutable @@ -467,22 +467,6 @@ object ScalaJSPluginInternal { }.value ) - private[sbtplugin] def makeExportsNamespaceExpr(moduleKind: ModuleKind, - moduleIdentifier: Option[String]): String = { - // !!! DUPLICATE code with ScalaJSFramework.optionalExportsNamespacePrefix - moduleKind match { - case ModuleKind.NoModule => - jsGlobalExpr - - case ModuleKind.CommonJSModule => - val moduleIdent = moduleIdentifier.getOrElse { - throw new IllegalArgumentException( - "The module identifier must be specified for CommonJS modules") - } - s"""require("${escapeJS(moduleIdent)}")""" - } - } - @deprecated("js.JSApps are going away, and this method with them.", "0.6.18") def discoverJSApps(analysis: inc.Analysis): Seq[String] = { discoverScalaJSMainClasses(analysis).collect { @@ -587,10 +571,6 @@ object ScalaJSPluginInternal { // use assert to prevent warning about pure expr in stat pos assert(scalaJSEnsureUnforked.value) - val logger = streams.value.log - val toolsLogger = sbtLogger2ToolsLogger(logger) - val frameworks = testFrameworks.value - val env = jsEnv.value match { case env: ComJSEnv => env @@ -604,14 +584,15 @@ object ScalaJSPluginInternal { val moduleKind = scalaJSModuleKind.value val moduleIdentifier = scalaJSModuleIdentifier.value - val detector = - new FrameworkDetector(env, files, moduleKind, moduleIdentifier) + val frameworksAndTheirImplNames = + testFrameworks.value.map(f => f -> f.implClassNames.toList) - detector.detect(frameworks, toolsLogger) map { case (tf, name) => - (tf, new ScalaJSFramework(name, env, files, moduleKind, - moduleIdentifier, toolsLogger)) - } + val logger = sbtLogger2ToolsLogger(streams.value.log) + + FrameworkDetector.detectFrameworks(env, files, moduleKind, + moduleIdentifier, frameworksAndTheirImplNames, logger) }, + // Override default to avoid triggering a test:fastOptJS in a test:compile // without loosing autocompletion. definedTestNames := { @@ -641,29 +622,20 @@ object ScalaJSPluginInternal { testHtml := { val log = streams.value.log val output = (artifactPath in testHtml).value + val title = name.value + " - tests" + val jsFiles = (jsExecutionFiles in testHtml).value - val jsFileCache = new VirtualFileMaterializer(true) - val jsFileURIs = (jsExecutionFiles in testHtml).value.map { - case file: FileVirtualFile => file.toURI - case file => jsFileCache.materialize(file).toURI - } + val frameworks = (loadedTestFrameworks in testHtml).value.toList + val frameworkImplClassNames = + frameworks.map(_._1.implClassNames.toList) - val css: java.io.File = { - val name = "test-runner.css" - val inputStream = getClass.getResourceAsStream(name) - try { - val outFile = (resourceManaged in testHtml).value / name - IO.transfer(inputStream, outFile) - outFile - } finally { - inputStream.close() - } + val taskDefs = for (td <- (definedTests in testHtml).value) yield { + new sbt.testing.TaskDef(td.name, td.fingerprint, + td.explicitlySpecified, td.selectors) } - IO.write(output, HTMLRunnerTemplate.render(output.toURI, - name.value + " - tests", jsFileURIs, css.toURI, - (loadedTestFrameworks in testHtml).value, - (definedTests in testHtml).value)) + HTMLRunnerBuilder.writeToFile(output, title, jsFiles, + frameworkImplClassNames, taskDefs.toList) log.info(s"Wrote HTML test runner. Point your browser to ${output.toURI}") diff --git a/sbt-plugin/src/main/resources/org/scalajs/sbtplugin/test-runner.css b/test-adapter/src/main/resources/org/scalajs/testadapter/test-runner.css similarity index 100% rename from sbt-plugin/src/main/resources/org/scalajs/sbtplugin/test-runner.css rename to test-adapter/src/main/resources/org/scalajs/testadapter/test-runner.css diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/FrameworkDetector.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/FrameworkDetector.scala new file mode 100644 index 0000000000..bd7024f002 --- /dev/null +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/FrameworkDetector.scala @@ -0,0 +1,116 @@ +package org.scalajs.testadapter + +import sbt.testing._ + +import org.scalajs.core.tools.io._ +import org.scalajs.core.tools.json._ +import org.scalajs.core.tools.logging.Logger +import org.scalajs.core.tools.linker.backend.ModuleKind + +import org.scalajs.jsenv._ + +import scala.collection.mutable + +object FrameworkDetector { + + /** Detects which of the specified test frameworks exists. + * + * Each potential implementation name in `frameworksAndTheirImplNames` is + * checked for existence in the module specified by `moduleKind` and + * `moduleIdentifier`. + * + * Returns a map with found frameworks and their corresponding + * `sbt.testing.Framework`s. + */ + def detectFrameworks[TestFramework](jsEnv: ComJSEnv, + jsFiles: Seq[VirtualJSFile], moduleKind: ModuleKind, + moduleIdentifier: Option[String], + frameworksAndTheirImplNames: Seq[(TestFramework, List[String])], + logger: Logger): Map[TestFramework, Framework] = { + detectImplementationNames(jsEnv, jsFiles, moduleKind, moduleIdentifier, + frameworksAndTheirImplNames, logger).map { + case (framework, implName) => + (framework, new ScalaJSFramework(implName, jsEnv, jsFiles, moduleKind, + moduleIdentifier, logger)) + } + } + + /** Detects which of the specified test frameworks exists. + * + * Each potential implementation name in `frameworksAndTheirImplNames` is + * checked for existence in the module specified by `moduleKind` and + * `moduleIdentifier`. + * + * Returns a map with found frameworks and their corresponding + * implementation names. + */ + def detectImplementationNames[TestFramework](jsEnv: JSEnv, + jsFiles: Seq[VirtualJSFile], moduleKind: ModuleKind, + moduleIdentifier: Option[String], + frameworksAndTheirImplNames: Seq[(TestFramework, List[String])], + logger: Logger): Map[TestFramework, String] = { + + val (frameworks, implementationNames) = frameworksAndTheirImplNames.unzip + + val prefix = ScalaJSFramework.optionalExportsNamespacePrefix( + moduleKind, moduleIdentifier) + + val code = s""" + (function() { + "use strict"; + + /* #2752: if there is no testing framework at all on the classpath, + * the testing interface will not be there, and therefore the + * `detectFrameworks` function will not exist. We must therefore be + * careful when selecting it. + */ + var orgNS = ${ + if (prefix == "") "typeof org !== 'undefined' ? org : (void 0)" + else (prefix + "org") + }; + var detectFrameworksFun = ( + orgNS && + orgNS.scalajs && + orgNS.scalajs.testinterface && + orgNS.scalajs.testinterface.internal && + orgNS.scalajs.testinterface.internal.detectFrameworks + ); + detectFrameworksFun = detectFrameworksFun || (function(data) { + var results = []; + for (var i = 0; i < data.length; ++i) + results.push(void 0); + return results; + }); + + var data = ${jsonToString(implementationNames.toList.toJSON)}; + var results = detectFrameworksFun(data); + for (var i = 0; i < results.length; ++i) { + console.log("$ConsoleFrameworkPrefix" + (results[i] || "")); + } + })(); + """ + + val vf = new MemVirtualJSFile("frameworkDetector.js").withContent(code) + val console = new StoreConsole + + val runner = jsEnv.jsRunner(jsFiles :+ vf) + runner.run(logger, console) + + // Filter jsDependencies unexpected output + val results = console.buf collect { + case s if s.startsWith(ConsoleFrameworkPrefix) => + s.stripPrefix(ConsoleFrameworkPrefix) + } + + assert(results.size == frameworks.size) + + frameworks.zip(results).filter(_._2.nonEmpty).toMap + } + + private class StoreConsole extends JSConsole { + val buf = mutable.Buffer.empty[String] + def log(msg: Any): Unit = buf += msg.toString + } + + private val ConsoleFrameworkPrefix = "@scalajs-test-framework-detector:" +} diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/HTMLRunnerBuilder.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/HTMLRunnerBuilder.scala new file mode 100644 index 0000000000..4f28dd48a9 --- /dev/null +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/HTMLRunnerBuilder.scala @@ -0,0 +1,104 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package org.scalajs.testadapter + +import java.io.File +import java.net.URI + +import sbt.testing.{Framework, TaskDef} + +import org.scalajs.core.ir.Utils +import org.scalajs.core.tools.io._ +import org.scalajs.core.tools.json._ + +import org.scalajs.jsenv.VirtualFileMaterializer + +import TaskDefSerializers._ + +/** Template for the HTML runner. */ +object HTMLRunnerBuilder { + + private val cssFile: MemVirtualTextFile = { + val name = "test-runner.css" + val inputStream = getClass.getResourceAsStream(name) + val content = try { + IO.readInputStreamToString(inputStream) + } finally { + inputStream.close() + } + new MemVirtualTextFile(name).withContent(content) + } + + def writeToFile(output: File, title: String, jsFiles: Seq[VirtualJSFile], + frameworkImplClassNames: List[List[String]], + taskDefs: List[TaskDef]): Unit = { + + val jsFileCache = new VirtualFileMaterializer(true) + val jsFileURIs = jsFiles.map { + case file: FileVirtualFile => file.toURI + case file => jsFileCache.materialize(file).toURI + } + val cssFileURI = jsFileCache.materialize(cssFile).toURI + + val htmlContent = render(output.toURI, title, jsFileURIs, cssFileURI, + frameworkImplClassNames, taskDefs) + + val outputWriter = WritableFileVirtualTextFile(output).contentWriter + try { + outputWriter.write(htmlContent) + } finally { + outputWriter.close() + } + } + + private def render(baseURI: URI, title: String, jsFiles: Seq[URI], + css: URI, frameworkImplClassNames: List[List[String]], + taskDefs: List[TaskDef]): String = { + def relURI(uri: URI) = + htmlEscaped(Utils.relativize(baseURI, uri).toASCIIString) + + s""" + + + + ${htmlEscaped(title)} + + + ${(for (jsFile <- jsFiles) yield s""" + + """).mkString("")} + + + + """ + } + + /** Courtesy to our own build. + * This is a hack. The build should take care of its own mess, but oh well. + */ + private[scalajs] def renderTestDefinitions( + frameworkImplClassNames: List[List[String]], + taskDefs: List[TaskDef]): String = { + s""" + var definedTests = ${jsonToString(taskDefs.toJSON)}; + var testFrameworkNames = ${jsonToString(frameworkImplClassNames.toJSON)}; + """ + } + + private def htmlEscaped(str: String): String = str.flatMap { + case '<' => "<" + case '>' => ">" + case '"' => """ + case '&' => "&" + case c => c :: Nil + } +} diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala index 9fdcec9607..1b78db6963 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala @@ -83,7 +83,14 @@ final class ScalaJSFramework( } private[testadapter] def optionalExportsNamespacePrefix: String = { - // !!! DUPLICATE code with ScalaJSPlugin.makeExportsNamespaceExpr + ScalaJSFramework.optionalExportsNamespacePrefix(moduleKind, + moduleIdentifier) + } +} + +private[testadapter] object ScalaJSFramework { + private[testadapter] def optionalExportsNamespacePrefix( + moduleKind: ModuleKind, moduleIdentifier: Option[String]): String = { moduleKind match { case ModuleKind.NoModule => "" From cef9ae95602d49c1d3a6ff7208d88858f6c9aefc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 10 Jun 2017 16:41:19 +0200 Subject: [PATCH 0358/2665] Move the test-adapter sources to the right directory. They were in `org/scalajs/sbttestadapter/` but they should be in `org/scalajs/testadapter/`. --- .../org/scalajs/{sbttestadapter => testadapter}/ComUtils.scala | 0 .../{sbttestadapter => testadapter}/EventSerializers.scala | 0 .../{sbttestadapter => testadapter}/FingerprintSerializers.scala | 0 .../{sbttestadapter => testadapter}/FrameworkDetector.scala | 0 .../scalajs/{sbttestadapter => testadapter}/FrameworkInfo.scala | 0 .../{sbttestadapter => testadapter}/HTMLRunnerBuilder.scala | 0 .../scalajs/{sbttestadapter => testadapter}/RemoteException.scala | 0 .../{sbttestadapter => testadapter}/ScalaJSFramework.scala | 0 .../scalajs/{sbttestadapter => testadapter}/ScalaJSRunner.scala | 0 .../org/scalajs/{sbttestadapter => testadapter}/ScalaJSTask.scala | 0 .../{sbttestadapter => testadapter}/SelectorSerializers.scala | 0 .../{sbttestadapter => testadapter}/TaskDefSerializers.scala | 0 .../org/scalajs/{sbttestadapter => testadapter}/TaskInfo.scala | 0 .../org/scalajs/{sbttestadapter => testadapter}/package.scala | 0 14 files changed, 0 insertions(+), 0 deletions(-) rename test-adapter/src/main/scala/org/scalajs/{sbttestadapter => testadapter}/ComUtils.scala (100%) rename test-adapter/src/main/scala/org/scalajs/{sbttestadapter => testadapter}/EventSerializers.scala (100%) rename test-adapter/src/main/scala/org/scalajs/{sbttestadapter => testadapter}/FingerprintSerializers.scala (100%) rename test-adapter/src/main/scala/org/scalajs/{sbttestadapter => testadapter}/FrameworkDetector.scala (100%) rename test-adapter/src/main/scala/org/scalajs/{sbttestadapter => testadapter}/FrameworkInfo.scala (100%) rename test-adapter/src/main/scala/org/scalajs/{sbttestadapter => testadapter}/HTMLRunnerBuilder.scala (100%) rename test-adapter/src/main/scala/org/scalajs/{sbttestadapter => testadapter}/RemoteException.scala (100%) rename test-adapter/src/main/scala/org/scalajs/{sbttestadapter => testadapter}/ScalaJSFramework.scala (100%) rename test-adapter/src/main/scala/org/scalajs/{sbttestadapter => testadapter}/ScalaJSRunner.scala (100%) rename test-adapter/src/main/scala/org/scalajs/{sbttestadapter => testadapter}/ScalaJSTask.scala (100%) rename test-adapter/src/main/scala/org/scalajs/{sbttestadapter => testadapter}/SelectorSerializers.scala (100%) rename test-adapter/src/main/scala/org/scalajs/{sbttestadapter => testadapter}/TaskDefSerializers.scala (100%) rename test-adapter/src/main/scala/org/scalajs/{sbttestadapter => testadapter}/TaskInfo.scala (100%) rename test-adapter/src/main/scala/org/scalajs/{sbttestadapter => testadapter}/package.scala (100%) diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ComUtils.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/ComUtils.scala similarity index 100% rename from test-adapter/src/main/scala/org/scalajs/sbttestadapter/ComUtils.scala rename to test-adapter/src/main/scala/org/scalajs/testadapter/ComUtils.scala diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/EventSerializers.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/EventSerializers.scala similarity index 100% rename from test-adapter/src/main/scala/org/scalajs/sbttestadapter/EventSerializers.scala rename to test-adapter/src/main/scala/org/scalajs/testadapter/EventSerializers.scala diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/FingerprintSerializers.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/FingerprintSerializers.scala similarity index 100% rename from test-adapter/src/main/scala/org/scalajs/sbttestadapter/FingerprintSerializers.scala rename to test-adapter/src/main/scala/org/scalajs/testadapter/FingerprintSerializers.scala diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/FrameworkDetector.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/FrameworkDetector.scala similarity index 100% rename from test-adapter/src/main/scala/org/scalajs/sbttestadapter/FrameworkDetector.scala rename to test-adapter/src/main/scala/org/scalajs/testadapter/FrameworkDetector.scala diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/FrameworkInfo.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/FrameworkInfo.scala similarity index 100% rename from test-adapter/src/main/scala/org/scalajs/sbttestadapter/FrameworkInfo.scala rename to test-adapter/src/main/scala/org/scalajs/testadapter/FrameworkInfo.scala diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/HTMLRunnerBuilder.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala similarity index 100% rename from test-adapter/src/main/scala/org/scalajs/sbttestadapter/HTMLRunnerBuilder.scala rename to test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/RemoteException.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/RemoteException.scala similarity index 100% rename from test-adapter/src/main/scala/org/scalajs/sbttestadapter/RemoteException.scala rename to test-adapter/src/main/scala/org/scalajs/testadapter/RemoteException.scala diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSFramework.scala similarity index 100% rename from test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala rename to test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSFramework.scala diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSRunner.scala similarity index 100% rename from test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala rename to test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSRunner.scala diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSTask.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSTask.scala similarity index 100% rename from test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSTask.scala rename to test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSTask.scala diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/SelectorSerializers.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/SelectorSerializers.scala similarity index 100% rename from test-adapter/src/main/scala/org/scalajs/sbttestadapter/SelectorSerializers.scala rename to test-adapter/src/main/scala/org/scalajs/testadapter/SelectorSerializers.scala diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TaskDefSerializers.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/TaskDefSerializers.scala similarity index 100% rename from test-adapter/src/main/scala/org/scalajs/sbttestadapter/TaskDefSerializers.scala rename to test-adapter/src/main/scala/org/scalajs/testadapter/TaskDefSerializers.scala diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TaskInfo.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/TaskInfo.scala similarity index 100% rename from test-adapter/src/main/scala/org/scalajs/sbttestadapter/TaskInfo.scala rename to test-adapter/src/main/scala/org/scalajs/testadapter/TaskInfo.scala diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/package.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/package.scala similarity index 100% rename from test-adapter/src/main/scala/org/scalajs/sbttestadapter/package.scala rename to test-adapter/src/main/scala/org/scalajs/testadapter/package.scala From e71ae28367de8b590058928541d88424c41ff66b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 10 Jun 2017 16:45:56 +0200 Subject: [PATCH 0359/2665] Move the `tools.json` package inside `testadapter.json`. --- .../src/main/scala/org/scalajs/testadapter/ComUtils.scala | 5 +++-- .../scala/org/scalajs/testadapter/EventSerializers.scala | 2 +- .../org/scalajs/testadapter/FingerprintSerializers.scala | 2 +- .../scala/org/scalajs/testadapter/FrameworkDetector.scala | 3 ++- .../scala/org/scalajs/testadapter/FrameworkInfo.scala | 2 +- .../scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala | 3 ++- .../scala/org/scalajs/testadapter/RemoteException.scala | 2 +- .../scala/org/scalajs/testadapter/ScalaJSFramework.scala | 2 +- .../scala/org/scalajs/testadapter/ScalaJSRunner.scala | 3 ++- .../main/scala/org/scalajs/testadapter/ScalaJSTask.scala | 8 ++++---- .../org/scalajs/testadapter/SelectorSerializers.scala | 2 +- .../org/scalajs/testadapter/TaskDefSerializers.scala | 2 +- .../src/main/scala/org/scalajs/testadapter/TaskInfo.scala | 2 +- .../main/scala/org/scalajs/testadapter}/json/Impl.scala | 2 +- .../org/scalajs/testadapter}/json/JSONDeserializer.scala | 2 +- .../org/scalajs/testadapter}/json/JSONObjBuilder.scala | 2 +- .../org/scalajs/testadapter}/json/JSONObjExtractor.scala | 2 +- .../org/scalajs/testadapter}/json/JSONSerializer.scala | 2 +- .../scala/org/scalajs/testadapter}/json/package.scala | 2 +- 19 files changed, 27 insertions(+), 23 deletions(-) rename {tools/jvm/src/main/scala/org/scalajs/core/tools => test-adapter/src/main/scala/org/scalajs/testadapter}/json/Impl.scala (96%) rename {tools/jvm/src/main/scala/org/scalajs/core/tools => test-adapter/src/main/scala/org/scalajs/testadapter}/json/JSONDeserializer.scala (96%) rename {tools/jvm/src/main/scala/org/scalajs/core/tools => test-adapter/src/main/scala/org/scalajs/testadapter}/json/JSONObjBuilder.scala (91%) rename {tools/jvm/src/main/scala/org/scalajs/core/tools => test-adapter/src/main/scala/org/scalajs/testadapter}/json/JSONObjExtractor.scala (88%) rename {tools/jvm/src/main/scala/org/scalajs/core/tools => test-adapter/src/main/scala/org/scalajs/testadapter}/json/JSONSerializer.scala (95%) rename {tools/jvm/src/main/scala/org/scalajs/core/tools => test-adapter/src/main/scala/org/scalajs/testadapter}/json/package.scala (95%) diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/ComUtils.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/ComUtils.scala index be6147fac0..64bbf0ae28 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/ComUtils.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/ComUtils.scala @@ -1,9 +1,10 @@ package org.scalajs.testadapter -import org.scalajs.core.tools.json._ +import scala.annotation.tailrec + import org.scalajs.jsenv._ -import scala.annotation.tailrec +import org.scalajs.testadapter.json._ import scala.concurrent.duration._ diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/EventSerializers.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/EventSerializers.scala index 4457fdeec8..444b08ef1c 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/EventSerializers.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/EventSerializers.scala @@ -11,7 +11,7 @@ package org.scalajs.testadapter import sbt.testing._ -import org.scalajs.core.tools.json._ +import org.scalajs.testadapter.json._ import FingerprintSerializers._ import SelectorSerializers._ diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/FingerprintSerializers.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/FingerprintSerializers.scala index 9c322745f0..d641d5928b 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/FingerprintSerializers.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/FingerprintSerializers.scala @@ -11,7 +11,7 @@ package org.scalajs.testadapter import sbt.testing._ -import org.scalajs.core.tools.json._ +import org.scalajs.testadapter.json._ private[testadapter] object FingerprintSerializers { diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/FrameworkDetector.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/FrameworkDetector.scala index bd7024f002..236b53a797 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/FrameworkDetector.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/FrameworkDetector.scala @@ -3,12 +3,13 @@ package org.scalajs.testadapter import sbt.testing._ import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.json._ import org.scalajs.core.tools.logging.Logger import org.scalajs.core.tools.linker.backend.ModuleKind import org.scalajs.jsenv._ +import org.scalajs.testadapter.json._ + import scala.collection.mutable object FrameworkDetector { diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/FrameworkInfo.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/FrameworkInfo.scala index ef06bb1154..3acb9346db 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/FrameworkInfo.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/FrameworkInfo.scala @@ -11,7 +11,7 @@ package org.scalajs.testadapter import sbt.testing._ -import org.scalajs.core.tools.json._ +import org.scalajs.testadapter.json._ import FingerprintSerializers._ diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala index 4f28dd48a9..d3bdf431e1 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala @@ -16,10 +16,11 @@ import sbt.testing.{Framework, TaskDef} import org.scalajs.core.ir.Utils import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.json._ import org.scalajs.jsenv.VirtualFileMaterializer +import org.scalajs.testadapter.json._ + import TaskDefSerializers._ /** Template for the HTML runner. */ diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/RemoteException.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/RemoteException.scala index 3e170310d6..cdcd9563ad 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/RemoteException.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/RemoteException.scala @@ -11,7 +11,7 @@ package org.scalajs.testadapter import sbt.testing._ -import org.scalajs.core.tools.json._ +import org.scalajs.testadapter.json._ import FingerprintSerializers._ diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSFramework.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSFramework.scala index 1b78db6963..c51d68e732 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSFramework.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSFramework.scala @@ -12,10 +12,10 @@ package org.scalajs.testadapter import org.scalajs.core.ir.Utils.escapeJS import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.json._ import org.scalajs.core.tools.logging._ import org.scalajs.core.tools.linker.backend.ModuleKind +import org.scalajs.testadapter.json._ import org.scalajs.jsenv._ import sbt.testing.{Logger => _, _} diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSRunner.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSRunner.scala index 037a16f3f8..24a807dce4 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSRunner.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSRunner.scala @@ -10,10 +10,11 @@ package org.scalajs.testadapter import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.json._ import org.scalajs.jsenv._ +import org.scalajs.testadapter.json._ + import scala.collection.concurrent.TrieMap import scala.concurrent.duration._ diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSTask.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSTask.scala index 08e5e046b8..f0efabf98f 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSTask.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSTask.scala @@ -9,15 +9,15 @@ package org.scalajs.testadapter -import org.scalajs.core.tools.json._ - -import org.scalajs.jsenv._ - import scala.collection.mutable import scala.util.Try import sbt.testing._ +import org.scalajs.jsenv._ + +import org.scalajs.testadapter.json._ + import TaskDefSerializers._ import EventSerializers._ import ComUtils.LoopHandler diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/SelectorSerializers.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/SelectorSerializers.scala index 2508b379c6..34a46c5ef6 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/SelectorSerializers.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/SelectorSerializers.scala @@ -11,7 +11,7 @@ package org.scalajs.testadapter import sbt.testing._ -import org.scalajs.core.tools.json._ +import org.scalajs.testadapter.json._ private[testadapter] object SelectorSerializers { diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/TaskDefSerializers.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/TaskDefSerializers.scala index 9385080e59..d960351f1a 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/TaskDefSerializers.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/TaskDefSerializers.scala @@ -11,7 +11,7 @@ package org.scalajs.testadapter import sbt.testing._ -import org.scalajs.core.tools.json._ +import org.scalajs.testadapter.json._ import FingerprintSerializers._ import SelectorSerializers._ diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/TaskInfo.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/TaskInfo.scala index c74b9cc468..eb296f3571 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/TaskInfo.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/TaskInfo.scala @@ -11,7 +11,7 @@ package org.scalajs.testadapter import sbt.testing._ -import org.scalajs.core.tools.json._ +import org.scalajs.testadapter.json._ import TaskDefSerializers._ diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/json/Impl.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/json/Impl.scala similarity index 96% rename from tools/jvm/src/main/scala/org/scalajs/core/tools/json/Impl.scala rename to test-adapter/src/main/scala/org/scalajs/testadapter/json/Impl.scala index ff8201b178..696e59ed1b 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/json/Impl.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/json/Impl.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.tools.json +package org.scalajs.testadapter.json import org.json.simple.JSONValue diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/json/JSONDeserializer.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONDeserializer.scala similarity index 96% rename from tools/jvm/src/main/scala/org/scalajs/core/tools/json/JSONDeserializer.scala rename to test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONDeserializer.scala index fd45c21ac2..3adec53de5 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/json/JSONDeserializer.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONDeserializer.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.tools.json +package org.scalajs.testadapter.json trait JSONDeserializer[T] { def deserialize(x: JSON): T diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/json/JSONObjBuilder.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONObjBuilder.scala similarity index 91% rename from tools/jvm/src/main/scala/org/scalajs/core/tools/json/JSONObjBuilder.scala rename to test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONObjBuilder.scala index 0834b5740f..cf9a770456 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/json/JSONObjBuilder.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONObjBuilder.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.tools.json +package org.scalajs.testadapter.json import scala.collection.mutable diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/json/JSONObjExtractor.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONObjExtractor.scala similarity index 88% rename from tools/jvm/src/main/scala/org/scalajs/core/tools/json/JSONObjExtractor.scala rename to test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONObjExtractor.scala index f9baa9cb88..d129a18e9e 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/json/JSONObjExtractor.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONObjExtractor.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.tools.json +package org.scalajs.testadapter.json import scala.collection.mutable diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/json/JSONSerializer.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONSerializer.scala similarity index 95% rename from tools/jvm/src/main/scala/org/scalajs/core/tools/json/JSONSerializer.scala rename to test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONSerializer.scala index 04d0f05347..45adf399d2 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/json/JSONSerializer.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONSerializer.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.tools.json +package org.scalajs.testadapter.json trait JSONSerializer[T] { def serialize(x: T): JSON diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/json/package.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/json/package.scala similarity index 95% rename from tools/jvm/src/main/scala/org/scalajs/core/tools/json/package.scala rename to test-adapter/src/main/scala/org/scalajs/testadapter/json/package.scala index be4d8f0ac7..4d0f54ed3c 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/json/package.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/json/package.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.tools +package org.scalajs.testadapter import java.io.{Reader, Writer} From f51e06aa972ce5e02133b3dc79e865c069e78063 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 10 Jun 2017 16:59:14 +0200 Subject: [PATCH 0360/2665] Fix #2989: Privatize `testadapter.json` inside `testadapter`. --- .../scalajs/testadapter/RemoteException.scala | 2 +- .../org/scalajs/testadapter/ScalaJSTask.scala | 2 +- .../testadapter/TaskDefSerializers.scala | 2 +- .../testadapter/json/JSONDeserializer.scala | 4 ++-- .../testadapter/json/JSONObjBuilder.scala | 2 +- .../testadapter/json/JSONObjExtractor.scala | 2 +- .../testadapter/json/JSONSerializer.scala | 4 ++-- .../scalajs/testadapter/json/package.scala | 21 ++++++++++++------- 8 files changed, 23 insertions(+), 16 deletions(-) diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/RemoteException.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/RemoteException.scala index cdcd9563ad..c8b32fb84d 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/RemoteException.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/RemoteException.scala @@ -20,7 +20,7 @@ final class RemoteException private (msg: String, _toString: String, override def toString(): String = _toString } -object RemoteException { +private[testadapter] object RemoteException { implicit object StackTraceDeserializer extends JSONDeserializer[StackTraceElement] { def deserialize(x: JSON): StackTraceElement = { val obj = new JSONObjExtractor(x) diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSTask.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSTask.scala index f0efabf98f..823201cbf0 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSTask.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSTask.scala @@ -123,7 +123,7 @@ final class ScalaJSTask private ( } -object ScalaJSTask { +private[testadapter] object ScalaJSTask { private final class LogElement[T](index: Int, log: Logger => (T => Unit), data: T) { def call(arr: Array[Logger]): Unit = log(arr(index))(data) diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/TaskDefSerializers.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/TaskDefSerializers.scala index d960351f1a..85fa624cc6 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/TaskDefSerializers.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/TaskDefSerializers.scala @@ -16,7 +16,7 @@ import org.scalajs.testadapter.json._ import FingerprintSerializers._ import SelectorSerializers._ -private[scalajs] object TaskDefSerializers { +private[testadapter] object TaskDefSerializers { implicit object TaskDefSerializer extends JSONSerializer[TaskDef] { def serialize(td: TaskDef): JSON = { diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONDeserializer.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONDeserializer.scala index 3adec53de5..0daf3080e4 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONDeserializer.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONDeserializer.scala @@ -1,10 +1,10 @@ package org.scalajs.testadapter.json -trait JSONDeserializer[T] { +private[testadapter] trait JSONDeserializer[T] { def deserialize(x: JSON): T } -object JSONDeserializer { +private[testadapter] object JSONDeserializer { implicit object stringJSON extends JSONDeserializer[String] { def deserialize(x: JSON): String = Impl.toString(x) diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONObjBuilder.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONObjBuilder.scala index cf9a770456..b419411347 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONObjBuilder.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONObjBuilder.scala @@ -2,7 +2,7 @@ package org.scalajs.testadapter.json import scala.collection.mutable -class JSONObjBuilder { +private[testadapter] class JSONObjBuilder { private val flds = mutable.Map.empty[String, JSON] diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONObjExtractor.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONObjExtractor.scala index d129a18e9e..4fc8e8a117 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONObjExtractor.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONObjExtractor.scala @@ -2,7 +2,7 @@ package org.scalajs.testadapter.json import scala.collection.mutable -class JSONObjExtractor(rawData: JSON) { +private[testadapter] class JSONObjExtractor(rawData: JSON) { private val data = Impl.toMap(rawData) def fld[T: JSONDeserializer](name: String): T = diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONSerializer.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONSerializer.scala index 45adf399d2..0e3649440c 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONSerializer.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONSerializer.scala @@ -1,10 +1,10 @@ package org.scalajs.testadapter.json -trait JSONSerializer[T] { +private[testadapter] trait JSONSerializer[T] { def serialize(x: T): JSON } -object JSONSerializer { +private[testadapter] object JSONSerializer { implicit object stringJSON extends JSONSerializer[String] { def serialize(x: String): JSON = Impl.fromString(x) diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/json/package.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/json/package.scala index 4d0f54ed3c..f74ef2172c 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/json/package.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/json/package.scala @@ -9,18 +9,25 @@ import java.io.{Reader, Writer} * object back. */ package object json { - type JSON = Impl.Repr + private[testadapter] type JSON = Impl.Repr - implicit class JSONPimp[T: JSONSerializer](x: T) { + private[testadapter] implicit class JSONPimp[T: JSONSerializer](x: T) { def toJSON: JSON = implicitly[JSONSerializer[T]].serialize(x) } - def fromJSON[T](x: JSON)(implicit d: JSONDeserializer[T]): T = + private[testadapter] def fromJSON[T](x: JSON)(implicit d: JSONDeserializer[T]): T = d.deserialize(x) - def writeJSON(x: JSON, writer: Writer): Unit = Impl.serialize(x, writer) - def jsonToString(x: JSON): String = Impl.serialize(x) - def readJSON(str: String): JSON = Impl.deserialize(str) - def readJSON(reader: Reader): JSON = Impl.deserialize(reader) + private[testadapter] def writeJSON(x: JSON, writer: Writer): Unit = + Impl.serialize(x, writer) + + private[testadapter] def jsonToString(x: JSON): String = + Impl.serialize(x) + + private[testadapter] def readJSON(str: String): JSON = + Impl.deserialize(str) + + private[testadapter] def readJSON(reader: Reader): JSON = + Impl.deserialize(reader) } From 9e11069a913c963396d6a07c3efabdadca6fd519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 16 Jun 2017 11:28:02 +0200 Subject: [PATCH 0361/2665] Remove the deprecated custom output wrapper. --- sbt-plugin-test/build.sbt | 6 ----- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 14 ------------ .../sbtplugin/ScalaJSPluginInternal.scala | 4 ---- .../closure/ClosureLinkerBackend.scala | 7 +++--- .../core/tools/linker/StandardLinker.scala | 22 ------------------- .../linker/backend/BasicLinkerBackend.scala | 2 -- .../tools/linker/backend/LinkerBackend.scala | 19 +--------------- .../linker/backend/emitter/Emitter.scala | 6 ----- 8 files changed, 4 insertions(+), 76 deletions(-) diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index cc692e1074..89c932e41b 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -38,9 +38,6 @@ lazy val noDOM = project.settings(baseSettings: _*). enablePlugins(ScalaJSJUnitPlugin). settings( name := "Scala.js sbt test w/o DOM", - scalaJSOutputWrapper := ( - "// Scala.js - noDOM sbt test\n//\n// Compiled with Scala.js\n", - "// End of Scala.js generated script"), scalaJSUseMainModuleInitializer := true ). /* This hopefully exposes concurrent uses of the linker. If it fails/gets @@ -79,9 +76,6 @@ lazy val withDOM = project.settings(baseSettings: _*). settings( name := "Scala.js sbt test w/ DOM", jsEnv := new JSDOMNodeJSEnv(), - scalaJSOutputWrapper := ( - "// Scala.js - withDOM sbt test\n//\n// Compiled with Scala.js\n", - "// End of Scala.js generated script"), scalaJSUseMainModuleInitializer := true ) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 6c24bc955f..5cd2ee2c4d 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -178,20 +178,6 @@ object ScalaJSPlugin extends AutoPlugin { val emitSourceMaps = SettingKey[Boolean]("emitSourceMaps", "Whether package and optimize stages should emit source maps at all", BPlusSetting) - /** Non-deprecated alias of `scalaJSOutputWrapper` for internal use. */ - private[sbtplugin] val scalaJSOutputWrapperInternal = SettingKey[(String, String)]( - "scalaJSOutputWrapper", - "Custom wrapper for the generated .js files. Formatted as tuple (header, footer).", - BPlusSetting) - - @deprecated( - "The functionality of `scalaJSOutputWrapper` has been superseded by " + - "a combination of more direct and more reliable features. Depending " + - "on your use case, use `scalaJSUseMainModuleInitializer`, " + - "`scalaJSModuleKind` and/or `@JSExportTopLevel` instead.", - "0.6.15") - val scalaJSOutputWrapper = scalaJSOutputWrapperInternal - val scalaJSSemantics = SettingKey[Semantics]("scalaJSSemantics", "Configurable semantics of Scala.js.", BPlusSetting) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 4889cfdcd5..094502a0eb 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -175,7 +175,6 @@ object ScalaJSPluginInternal { .withSourceMap(withSourceMap) .withRelativizeSourceMapBase(relSourceMapBase) .withClosureCompiler(opts.useClosureCompiler) - .withCustomOutputWrapperInternal(scalaJSOutputWrapperInternal.value) .withPrettyPrint(opts.prettyPrintFullOptJS) .withBatchMode(opts.batchMode) }, @@ -727,9 +726,6 @@ object ScalaJSPluginInternal { emitSourceMaps := scalaJSLinkerConfig.value.sourceMap, - scalaJSOutputWrapperInternal := - scalaJSLinkerConfig.value.customOutputWrapper, - scalaJSOptimizerOptions := { val config = scalaJSLinkerConfig.value OptimizerOptions() diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala index f34e20acbf..84d7f42a90 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala @@ -142,12 +142,11 @@ final class ClosureLinkerBackend( private def writeResult(result: Result, compiler: ClosureCompiler, output: WritableVirtualJSFile): Unit = { - def withNewLine(str: String): String = if (str == "") "" else str + "\n" + def ifIIFE(str: String): String = if (needsIIFEWrapper) str else "" - val (header0, footer0) = config.customOutputWrapper - val header = withNewLine(header0) + ifIIFE("(function(){") + "'use strict';\n" - val footer = ifIIFE("}).call(this);\n") + withNewLine(footer0) + val header = ifIIFE("(function(){") + "'use strict';\n" + val footer = ifIIFE("}).call(this);\n") val outputContent = if (result.errors.nonEmpty) "// errors while producing source\n" 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 1b5fa40b05..912a2aeb3c 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 @@ -24,7 +24,6 @@ object StandardLinker { val backendConfig = LinkerBackend.Config() .withRelativizeSourceMapBase(config.relativizeSourceMapBase) - .withCustomOutputWrapperInternal(config.customOutputWrapper) .withPrettyPrint(config.prettyPrint) val oldAPIConfig = Linker.Config() @@ -60,8 +59,6 @@ object StandardLinker { val sourceMap: Boolean, /** Base path to relativize paths in the source map. */ val relativizeSourceMapBase: Option[URI], - /** Custom js code that wraps the output */ - val customOutputWrapper: (String, String), /** Whether to use the Google Closure Compiler pass, if it is available. * On the JavaScript platform, this does not have any effect. */ @@ -92,7 +89,6 @@ object StandardLinker { parallel = true, sourceMap = true, relativizeSourceMapBase = None, - customOutputWrapper = ("", ""), closureCompilerIfAvailable = false, prettyPrint = false, batchMode = false, @@ -124,20 +120,6 @@ object StandardLinker { def withRelativizeSourceMapBase(relativizeSourceMapBase: Option[URI]): Config = copy(relativizeSourceMapBase = relativizeSourceMapBase) - @deprecated( - "The functionality of custom output wrappers has been superseded " + - "by the support for CommonJS modules, module initializers, and " + - "top-level exports.", - "0.6.15") - def withCustomOutputWrapper(customOutputWrapper: (String, String)): Config = - copy(customOutputWrapper = customOutputWrapper) - - // Non-deprecated version to call from the sbt plugin - private[scalajs] def withCustomOutputWrapperInternal( - customOutputWrapper: (String, String)): Config = { - copy(customOutputWrapper = customOutputWrapper) - } - def withClosureCompilerIfAvailable(closureCompilerIfAvailable: Boolean): Config = copy(closureCompilerIfAvailable = closureCompilerIfAvailable) @@ -159,7 +141,6 @@ object StandardLinker { | parallel = $parallel, | sourceMap = $sourceMap, | relativizeSourceMapBase = $relativizeSourceMapBase, - | customOutputWrapper = $customOutputWrapper, | closureCompilerIfAvailable = $closureCompilerIfAvailable, | prettyPrint = $prettyPrint, | batchMode = $batchMode, @@ -175,7 +156,6 @@ object StandardLinker { parallel: Boolean = parallel, sourceMap: Boolean = sourceMap, relativizeSourceMapBase: Option[URI] = relativizeSourceMapBase, - customOutputWrapper: (String, String) = customOutputWrapper, closureCompilerIfAvailable: Boolean = closureCompilerIfAvailable, prettyPrint: Boolean = prettyPrint, batchMode: Boolean = batchMode, @@ -189,7 +169,6 @@ object StandardLinker { parallel, sourceMap, relativizeSourceMapBase, - customOutputWrapper, closureCompilerIfAvailable, prettyPrint, batchMode, @@ -210,7 +189,6 @@ object StandardLinker { * - `parallel`: `true` * - `sourceMap`: `true` * - `relativizeSourceMapBase`: `None` - * - `customOutputWrapper`: `("", "")` (deprecated) * - `closureCompilerIfAvailable`: `false` * - `prettyPrint`: `false` * - `batchMode`: `false` diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala index a0659a3600..fa855927cc 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala @@ -54,9 +54,7 @@ final class BasicLinkerBackend( try { logger.time("Emitter (write output)") { - emitter.emitCustomHeader(config.customOutputWrapper._1, builder) emitter.emitAll(unit, builder, logger) - emitter.emitCustomFooter(config.customOutputWrapper._2, builder) } builder.complete() diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala index 4af83d8899..909d1168e1 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala @@ -69,36 +69,19 @@ object LinkerBackend { final class Config private ( /** Base path to relativize paths in the source map. */ val relativizeSourceMapBase: Option[URI] = None, - /** Custom js code that wraps the output */ - val customOutputWrapper: (String, String) = ("", ""), /** Pretty-print the output. */ val prettyPrint: Boolean = false ) { def withRelativizeSourceMapBase(relativizeSourceMapBase: Option[URI]): Config = copy(relativizeSourceMapBase = relativizeSourceMapBase) - @deprecated( - "The functionality of custom output wrappers has been superseded " + - "by the support for CommonJS modules, module initializers, and " + - "top-level exports.", - "0.6.15") - def withCustomOutputWrapper(customOutputWrapper: (String, String)): Config = - copy(customOutputWrapper = customOutputWrapper) - - // Non-deprecated version to call from the sbt plugin - private[scalajs] def withCustomOutputWrapperInternal( - customOutputWrapper: (String, String)): Config = { - copy(customOutputWrapper = customOutputWrapper) - } - def withPrettyPrint(prettyPrint: Boolean): Config = copy(prettyPrint = prettyPrint) private def copy( relativizeSourceMapBase: Option[URI] = relativizeSourceMapBase, - customOutputWrapper: (String, String) = customOutputWrapper, prettyPrint: Boolean = prettyPrint): Config = { - new Config(relativizeSourceMapBase, customOutputWrapper, prettyPrint) + new Config(relativizeSourceMapBase, prettyPrint) } } diff --git 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 index 2f4ada0bf0..1434812495 100644 --- 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 @@ -125,9 +125,6 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, } } - def emitCustomHeader(customHeader: String, builder: JSFileBuilder): Unit = - emitLines(customHeader, builder) - /** Emits everything but the core JS lib to the builder, and returns the * core JS lib. * @@ -250,9 +247,6 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, } } - def emitCustomFooter(customFooter: String, builder: JSFileBuilder): Unit = - emitLines(customFooter, builder) - private def compareClasses(lhs: LinkedClass, rhs: LinkedClass) = { val lhsAC = lhs.ancestors.size val rhsAC = rhs.ancestors.size From 75cc34ba7d67e8c91e0738d5ab245f779ebafcfc Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 16 Jun 2017 13:13:17 +0200 Subject: [PATCH 0362/2665] Fix #3017: Remove unused var --- .../src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala index 6f2c52c8cc..d2b3f36afa 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala @@ -62,7 +62,6 @@ final class IRFileCache { /** A cache to use for individual runs. Not threadsafe */ final class Cache private[IRFileCache] { - private[this] var readyToUse: Boolean = false private[this] var localCache: Seq[PersistedFiles] = _ /** Extract and cache IR. From 02b12635931a9bf1327f7469f3cb354db60173d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 16 Jun 2017 14:05:30 +0200 Subject: [PATCH 0363/2665] Remove the deprecated APIs in JS envs. In the process, the implementation of `org.scalajs.jsenv.nodejs.JSDOMNodeJSEnv` is transferred to the new `org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv`. --- ci/matrix.xml | 8 +- .../org/scalajs/jsenv/ExternalJSEnv.scala | 8 - .../jsenv/jsdomnodejs/JSDOMNodeJSEnv.scala | 119 +++++++++++++- .../jsenv/nodejs/AbstractNodeJSEnv.scala | 3 - .../scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala | 145 ------------------ .../org/scalajs/jsenv/nodejs/NodeJSEnv.scala | 16 -- project/Build.scala | 3 +- sbt-plugin-test/build.sbt | 2 +- 8 files changed, 124 insertions(+), 180 deletions(-) delete mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala diff --git a/ci/matrix.xml b/ci/matrix.xml index 49c02a898d..30e59aa995 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -20,9 +20,9 @@ sbtretry 'set scalaJSStage in Global := FullOptStage' \ ++$scala helloworld/run \ helloworld/clean && - sbtretry 'set jsEnv in helloworld := new org.scalajs.jsenv.nodejs.JSDOMNodeJSEnv' \ + sbtretry 'set jsEnv in helloworld := new org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv' \ ++$scala helloworld/run && - sbtretry 'set jsEnv in helloworld := new org.scalajs.jsenv.nodejs.JSDOMNodeJSEnv' \ + sbtretry 'set jsEnv in helloworld := new org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv' \ 'set scalaJSStage in Global := FullOptStage' \ ++$scala helloworld/run \ helloworld/clean && @@ -66,9 +66,9 @@ sbtretry 'set scalaJSStage in Global := FullOptStage' \ ++$scala $testSuite/test \ $testSuite/clean && - sbtretry 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.JSDOMNodeJSEnv' \ + sbtretry 'set jsEnv in $testSuite := new org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv' \ ++$scala $testSuite/test && - sbtretry 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.JSDOMNodeJSEnv' \ + sbtretry 'set jsEnv in $testSuite := new org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv' \ 'set scalaJSStage in Global := FullOptStage' \ ++$scala $testSuite/test \ $testSuite/clean && diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala index e8afe879ad..262e568de3 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala @@ -11,9 +11,7 @@ import scala.concurrent.{Future, Promise} import scala.util.Try abstract class ExternalJSEnv( - @deprecatedName('additionalArgs) final protected val args: Seq[String], - @deprecatedName('additionalEnv) final protected val env: Map[String, String]) extends AsyncJSEnv { @@ -27,12 +25,6 @@ abstract class ExternalJSEnv( /** Command to execute (on shell) for this VM */ protected def executable: String - @deprecated("Use `args` instead.", "0.6.16") - final protected def additionalArgs: Seq[String] = args - - @deprecated("Use `env` instead.", "0.6.16") - final protected def additionalEnv: Map[String, String] = env - /** Custom initialization scripts. */ protected def customInitFiles(): Seq[VirtualJSFile] = Nil diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnv.scala index e696fa4141..616522a736 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnv.scala @@ -8,11 +8,126 @@ package org.scalajs.jsenv.jsdomnodejs +import java.io.OutputStream + +import org.scalajs.core.tools.io._ +import org.scalajs.jsenv._ +import org.scalajs.jsenv.nodejs.AbstractNodeJSEnv + +import org.scalajs.core.ir.Utils.escapeJS + class JSDOMNodeJSEnv(config: JSDOMNodeJSEnv.Config) - extends org.scalajs.jsenv.nodejs.JSDOMNodeJSEnv(config.executable, - config.args, config.env, internal = ()) { + extends AbstractNodeJSEnv(config.executable, config.args, config.env, + sourceMap = false) { def this() = this(JSDOMNodeJSEnv.Config()) + + protected def vmName: String = "Node.js with JSDOM" + + override def jsRunner(files: Seq[VirtualJSFile]): JSRunner = + new DOMNodeRunner(files) + + override def asyncRunner(files: Seq[VirtualJSFile]): AsyncJSRunner = + new AsyncDOMNodeRunner(files) + + override def comRunner(files: Seq[VirtualJSFile]): ComJSRunner = + new ComDOMNodeRunner(files) + + protected class DOMNodeRunner(files: Seq[VirtualJSFile]) + extends ExtRunner(files) with AbstractDOMNodeRunner + + protected class AsyncDOMNodeRunner(files: Seq[VirtualJSFile]) + extends AsyncExtRunner(files) with AbstractDOMNodeRunner + + protected class ComDOMNodeRunner(files: Seq[VirtualJSFile]) + extends AsyncDOMNodeRunner(files) with NodeComJSRunner + + protected trait AbstractDOMNodeRunner extends AbstractNodeRunner { + + protected def codeWithJSDOMContext(): Seq[VirtualJSFile] = { + val scriptsPaths = getScriptsJSFiles().map { + case file: FileVirtualFile => file.path + case file => libCache.materialize(file).getAbsolutePath + } + val scriptsURIs = + scriptsPaths.map(path => new java.io.File(path).toURI.toASCIIString) + val scriptsURIsAsJSStrings = scriptsURIs.map('"' + escapeJS(_) + '"') + val jsDOMCode = { + s""" + |(function () { + | var jsdom; + | try { + | jsdom = require("jsdom/lib/old-api.js"); // jsdom >= 10.x + | } catch (e) { + | jsdom = require("jsdom"); // jsdom <= 9.x + | } + | + | var virtualConsole = jsdom.createVirtualConsole() + | .sendTo(console, { omitJsdomErrors: true }); + | virtualConsole.on("jsdomError", function (error) { + | /* This inelegant if + console.error is the only way I found + | * to make sure the stack trace of the original error is + | * printed out. + | */ + | if (error.detail && error.detail.stack) + | console.error(error.detail.stack); + | + | // Throw the error anew to make sure the whole execution fails + | throw error; + | }); + | + | jsdom.env({ + | html: "", + | url: "http://localhost/", + | virtualConsole: virtualConsole, + | created: function (error, window) { + | if (error == null) { + | window["__ScalaJSEnv"] = __ScalaJSEnv; + | window["scalajsCom"] = global.scalajsCom; + | } else { + | throw error; + | } + | }, + | scripts: [${scriptsURIsAsJSStrings.mkString(", ")}] + | }); + |})(); + |""".stripMargin + } + Seq(new MemVirtualJSFile("codeWithJSDOMContext.js").withContent(jsDOMCode)) + } + + /** All the JS files that are passed to the VM. + * + * This method can overridden to provide custom behavior in subclasses. + * + * This method is overridden in `JSDOMNodeJSEnv` so that user-provided + * JS files (excluding "init" files) are executed as *scripts* within the + * jsdom environment, rather than being directly executed by the VM. + * + * The value returned by this method in `JSDOMNodeJSEnv` is + * `initFiles() ++ customInitFiles() ++ codeWithJSDOMContext()`. + */ + override protected def getJSFiles(): Seq[VirtualJSFile] = + initFiles() ++ customInitFiles() ++ codeWithJSDOMContext() + + /** JS files to be loaded via scripts in the jsdom environment. + * + * This method can be overridden to provide a different list of scripts. + * + * The default value in `JSDOMNodeJSEnv` is `files`. + */ + protected def getScriptsJSFiles(): Seq[VirtualJSFile] = + files + + // Send code to Stdin + override protected def sendVMStdin(out: OutputStream): Unit = { + /* Do not factor this method out into AbstractNodeRunner or when mixin in + * the traits it would use AbstractExtRunner.sendVMStdin due to + * linearization order. + */ + sendJS(getJSFiles(), out) + } + } } object JSDOMNodeJSEnv { diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala index 9f691dd6d8..f0be72e924 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala @@ -23,11 +23,8 @@ import scala.concurrent.TimeoutException import scala.concurrent.duration._ abstract class AbstractNodeJSEnv( - @deprecatedName('nodejsPath) protected val executable: String, - @deprecatedName('addArgs) args: Seq[String], - @deprecatedName('addEnv) env: Map[String, String], val sourceMap: Boolean) extends ExternalJSEnv(args, env) with ComJSEnv { diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala deleted file mode 100644 index 98fef4077a..0000000000 --- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala +++ /dev/null @@ -1,145 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.jsenv.nodejs - -import java.io.{Console => _, _} - -import org.scalajs.core.tools.io._ -import org.scalajs.jsenv._ - -import org.scalajs.core.ir.Utils.escapeJS - -class JSDOMNodeJSEnv private[jsenv] ( - executable: String, - args: Seq[String], - env: Map[String, String], - internal: Unit -) extends AbstractNodeJSEnv(executable, args, env, sourceMap = false) { - - @deprecated("Use org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv.", "0.6.18") - def this( - @deprecatedName('nodejsPath) - executable: String = "node", - @deprecatedName('addArgs) - args: Seq[String] = Seq.empty, - @deprecatedName('addEnv) - env: Map[String, String] = Map.empty - ) = { - this(executable, args, env, internal = ()) - } - - protected def vmName: String = "Node.js with JSDOM" - - override def jsRunner(files: Seq[VirtualJSFile]): JSRunner = - new DOMNodeRunner(files) - - override def asyncRunner(files: Seq[VirtualJSFile]): AsyncJSRunner = - new AsyncDOMNodeRunner(files) - - override def comRunner(files: Seq[VirtualJSFile]): ComJSRunner = - new ComDOMNodeRunner(files) - - protected class DOMNodeRunner(files: Seq[VirtualJSFile]) - extends ExtRunner(files) with AbstractDOMNodeRunner - - protected class AsyncDOMNodeRunner(files: Seq[VirtualJSFile]) - extends AsyncExtRunner(files) with AbstractDOMNodeRunner - - protected class ComDOMNodeRunner(files: Seq[VirtualJSFile]) - extends AsyncDOMNodeRunner(files) with NodeComJSRunner - - protected trait AbstractDOMNodeRunner extends AbstractNodeRunner { - - protected def codeWithJSDOMContext(): Seq[VirtualJSFile] = { - val scriptsPaths = getScriptsJSFiles().map { - case file: FileVirtualFile => file.path - case file => libCache.materialize(file).getAbsolutePath - } - val scriptsURIs = - scriptsPaths.map(path => new java.io.File(path).toURI.toASCIIString) - val scriptsURIsAsJSStrings = scriptsURIs.map('"' + escapeJS(_) + '"') - val jsDOMCode = { - s""" - |(function () { - | var jsdom; - | try { - | jsdom = require("jsdom/lib/old-api.js"); // jsdom >= 10.x - | } catch (e) { - | jsdom = require("jsdom"); // jsdom <= 9.x - | } - | - | var virtualConsole = jsdom.createVirtualConsole() - | .sendTo(console, { omitJsdomErrors: true }); - | virtualConsole.on("jsdomError", function (error) { - | /* This inelegant if + console.error is the only way I found - | * to make sure the stack trace of the original error is - | * printed out. - | */ - | if (error.detail && error.detail.stack) - | console.error(error.detail.stack); - | - | // Throw the error anew to make sure the whole execution fails - | throw error; - | }); - | - | jsdom.env({ - | html: "", - | url: "http://localhost/", - | virtualConsole: virtualConsole, - | created: function (error, window) { - | if (error == null) { - | window["__ScalaJSEnv"] = __ScalaJSEnv; - | window["scalajsCom"] = global.scalajsCom; - | } else { - | throw error; - | } - | }, - | scripts: [${scriptsURIsAsJSStrings.mkString(", ")}] - | }); - |})(); - |""".stripMargin - } - Seq(new MemVirtualJSFile("codeWithJSDOMContext.js").withContent(jsDOMCode)) - } - - /** All the JS files that are passed to the VM. - * - * This method can overridden to provide custom behavior in subclasses. - * - * This method is overridden in `JSDOMNodeJSEnv` so that user-provided - * JS files (excluding "init" files) are executed as *scripts* within the - * jsdom environment, rather than being directly executed by the VM. - * - * The value returned by this method in `JSDOMNodeJSEnv` is - * `initFiles() ++ customInitFiles() ++ codeWithJSDOMContext()`. - */ - override protected def getJSFiles(): Seq[VirtualJSFile] = - initFiles() ++ customInitFiles() ++ codeWithJSDOMContext() - - /** JS files to be loaded via scripts in the jsdom environment. - * - * This method can be overridden to provide a different list of scripts. - * - * The default value in `JSDOMNodeJSEnv` is `files`. - */ - protected def getScriptsJSFiles(): Seq[VirtualJSFile] = - files - - // Send code to Stdin - override protected def sendVMStdin(out: OutputStream): Unit = { - /* Do not factor this method out into AbstractNodeRunner or when mixin in - * the traits it would use AbstractExtRunner.sendVMStdin due to - * linearization order. - */ - sendJS(getJSFiles(), out) - } - } - -} diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala index e2b4dd545c..c86a59d6a3 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala @@ -22,22 +22,6 @@ class NodeJSEnv(config: NodeJSEnv.Config) def this() = this(NodeJSEnv.Config()) - @deprecated("Use the overload with a NodeJSEnv.Config.", "0.6.18") - def this( - @deprecatedName('nodejsPath) - executable: String = "node", - @deprecatedName('addArgs) - args: Seq[String] = Seq.empty, - @deprecatedName('addEnv) - env: Map[String, String] = Map.empty) = { - this(NodeJSEnv.Config().withExecutable(executable).withArgs(args.toList).withEnv(env)) - } - - @deprecated("Use the overloaded constructor with a NodeJSEnv.Config.", - "0.6.18") - def withSourceMap(sourceMap: Boolean): NodeJSEnv = - new NodeJSEnv(config.withSourceMap(sourceMap)) - protected def vmName: String = "Node.js" override def jsRunner(files: Seq[VirtualJSFile]): JSRunner = diff --git a/project/Build.scala b/project/Build.scala index e067a7f7d1..01800e8cc0 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -21,7 +21,8 @@ import org.scalajs.core.ir.Utils.escapeJS import org.scalajs.sbtplugin._ import org.scalajs.jsenv.{ConsoleJSConsole, JSEnv} -import org.scalajs.jsenv.nodejs.{NodeJSEnv, JSDOMNodeJSEnv} +import org.scalajs.jsenv.nodejs.NodeJSEnv +import org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv import ScalaJSPlugin.autoImport._ import ExternalCompile.scalaJSExternalCompileSettings diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index cc692e1074..3ff5d6e889 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -1,5 +1,5 @@ import org.scalajs.core.tools.io._ -import org.scalajs.jsenv.nodejs.JSDOMNodeJSEnv +import org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv import org.scalajs.sbtplugin.ScalaJSPluginInternal._ import org.scalajs.sbtplugin.Loggers.sbtLogger2ToolsLogger From 6028dbd5c8f53be35f00cb8b77559348bc5e9470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 16 Jun 2017 14:20:18 +0200 Subject: [PATCH 0364/2665] Fix #2877: Internal JS envs config amenable to bincompat evolution. The internal configuration of (abstract) classes in the JS env API is now `protected def`-based, rather than based on constructor parameters. This can be evolved in binary-compatible ways, as we can add new `protected def`s with default implementations in the superclasses. --- .../org/scalajs/jsenv/ExternalJSEnv.scala | 13 +++++++++---- .../jsenv/jsdomnodejs/JSDOMNodeJSEnv.scala | 15 ++++++++++++--- .../jsenv/nodejs/AbstractNodeJSEnv.scala | 19 +++++++++---------- .../org/scalajs/jsenv/nodejs/NodeJSEnv.scala | 15 ++++++++++++--- project/Build.scala | 2 +- 5 files changed, 43 insertions(+), 21 deletions(-) diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala index 262e568de3..e5a18a9fa3 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala @@ -1,5 +1,7 @@ package org.scalajs.jsenv +import scala.collection.immutable + import org.scalajs.core.tools.io._ import org.scalajs.core.tools.logging.Logger @@ -10,10 +12,7 @@ import scala.collection.JavaConverters._ import scala.concurrent.{Future, Promise} import scala.util.Try -abstract class ExternalJSEnv( - final protected val args: Seq[String], - final protected val env: Map[String, String]) - extends AsyncJSEnv { +abstract class ExternalJSEnv extends AsyncJSEnv { import ExternalJSEnv._ @@ -25,6 +24,12 @@ abstract class ExternalJSEnv( /** Command to execute (on shell) for this VM */ protected def executable: String + /** Command-line arguments to give to the external process. */ + protected def args: immutable.Seq[String] = Nil + + /** Environment in which to run the external process. */ + protected def env: Map[String, String] = Map.empty + /** Custom initialization scripts. */ protected def customInitFiles(): Seq[VirtualJSFile] = Nil diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnv.scala index 616522a736..ac6fbab3d6 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnv.scala @@ -8,6 +8,8 @@ package org.scalajs.jsenv.jsdomnodejs +import scala.collection.immutable + import java.io.OutputStream import org.scalajs.core.tools.io._ @@ -16,14 +18,21 @@ import org.scalajs.jsenv.nodejs.AbstractNodeJSEnv import org.scalajs.core.ir.Utils.escapeJS -class JSDOMNodeJSEnv(config: JSDOMNodeJSEnv.Config) - extends AbstractNodeJSEnv(config.executable, config.args, config.env, - sourceMap = false) { +class JSDOMNodeJSEnv(config: JSDOMNodeJSEnv.Config) extends AbstractNodeJSEnv { def this() = this(JSDOMNodeJSEnv.Config()) protected def vmName: String = "Node.js with JSDOM" + protected def executable: String = config.executable + + override protected def args: immutable.Seq[String] = config.args + + override protected def env: Map[String, String] = config.env + + // TODO We might want to make this configurable - not sure why it isn't + override protected def wantSourceMap: Boolean = false + override def jsRunner(files: Seq[VirtualJSFile]): JSRunner = new DOMNodeRunner(files) diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala index f0be72e924..d12abe867a 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala @@ -22,12 +22,9 @@ import scala.collection.JavaConverters._ import scala.concurrent.TimeoutException import scala.concurrent.duration._ -abstract class AbstractNodeJSEnv( - protected val executable: String, - args: Seq[String], - env: Map[String, String], - val sourceMap: Boolean) - extends ExternalJSEnv(args, env) with ComJSEnv { +abstract class AbstractNodeJSEnv extends ExternalJSEnv with ComJSEnv { + + protected def wantSourceMap: Boolean = true /** True, if the installed node executable supports source mapping. * @@ -57,15 +54,17 @@ abstract class AbstractNodeJSEnv( * Is used by [[initFiles]], override to change/disable. */ protected def installSourceMap(): Seq[VirtualJSFile] = { - if (sourceMap) Seq( - new MemVirtualJSFile("sourceMapSupport.js").withContent( + if (wantSourceMap) { + val content = """ |try { | require('source-map-support').install(); |} catch (e) {} """.stripMargin - ) - ) else Seq() + Seq(new MemVirtualJSFile("sourceMapSupport.js").withContent(content)) + } else { + Seq() + } } /** File(s) to hack console.log to prevent if from changing `%%` to `%`. diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala index c86a59d6a3..25392c0fe1 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala @@ -9,6 +9,8 @@ package org.scalajs.jsenv.nodejs +import scala.collection.immutable + import org.scalajs.jsenv._ import org.scalajs.core.tools.io._ @@ -16,14 +18,21 @@ import org.scalajs.core.tools.logging._ import java.io.{ Console => _, _ } -class NodeJSEnv(config: NodeJSEnv.Config) - extends AbstractNodeJSEnv(config.executable, config.args, config.env, - config.sourceMap) { +class NodeJSEnv(config: NodeJSEnv.Config) extends AbstractNodeJSEnv { def this() = this(NodeJSEnv.Config()) protected def vmName: String = "Node.js" + protected def executable: String = config.executable + + override protected def args: immutable.Seq[String] = config.args + + override protected def env: Map[String, String] = config.env + + // TODO Our Build wants this to be public, but it does not seem clean + override def wantSourceMap: Boolean = config.sourceMap + override def jsRunner(files: Seq[VirtualJSFile]): JSRunner = new NodeRunner(files) diff --git a/project/Build.scala b/project/Build.scala index 01800e8cc0..1a870ae06b 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1268,7 +1268,7 @@ object Build { def envTagsFor(env: JSEnv): Seq[String] = env match { case env: NodeJSEnv => val baseArgs = Seq("nodejs", "typedarray") - if (env.sourceMap) { + if (env.wantSourceMap) { if (!env.hasSourceMapSupport) { throw new MessageOnlyException( "You must install Node.js source map support to " + From 0b2fe4103187a9d4b1358250698df0f259a9a37f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 16 Jun 2017 11:45:45 +0200 Subject: [PATCH 0365/2665] Switch the CLI to use main methods with args. This is not backward compatible. It will potentially break existing invocations of the CLI. --- TESTING | 2 +- cli/src/main/scala/org/scalajs/cli/Scalajsld.scala | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/TESTING b/TESTING index f255a00dbb..af1d74c97b 100644 --- a/TESTING +++ b/TESTING @@ -13,7 +13,7 @@ For each major Scala version on a *NIX distro and a Windows distro: mkdir bin echo ' object Foo { - def main(): Unit = { + def main(args: Array[String]): Unit = { println(s"asdf ${1 + 1}") new A } diff --git a/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala b/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala index 1d5aac4116..890ab55d31 100644 --- a/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala +++ b/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala @@ -48,7 +48,7 @@ object Scalajsld { val lastDot = s.lastIndexOf('.') if (lastDot < 0) throw new IllegalArgumentException(s"$s is not a valid main method") - ModuleInitializer.mainMethod(s.substring(0, lastDot), + ModuleInitializer.mainMethodWithArgs(s.substring(0, lastDot), s.substring(lastDot + 1)) } } @@ -81,7 +81,7 @@ object Scalajsld { .abbr("mm") .unbounded() .action { (x, c) => c.copy(moduleInitializers = c.moduleInitializers :+ x) } - .text("Execute the specified main method on startup") + .text("Execute the specified main(Array[String]) method on startup") opt[File]('o', "output") .valueName("") .required() From d26245d12ef6ed8f210e0528e139869e730ca3cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 16 Jun 2017 12:01:07 +0200 Subject: [PATCH 0366/2665] Deprecate `js.JSApp` and do not special-case them in the sbt plugin. For backward source compatibility, we add in `js.JSApp` a forwarder def main(args: Array[String]): Unit = main() which allows existing `js.JSApp` to still be recognized and run. --- examples/helloworld/HelloWorld.scala | 4 +- .../main/scala/scala/scalajs/js/JSApp.scala | 47 +++++++++------ .../sbtplugin/ScalaJSPluginInternal.scala | 57 +------------------ 3 files changed, 33 insertions(+), 75 deletions(-) diff --git a/examples/helloworld/HelloWorld.scala b/examples/helloworld/HelloWorld.scala index 90e5bfa11c..d6065b292f 100644 --- a/examples/helloworld/HelloWorld.scala +++ b/examples/helloworld/HelloWorld.scala @@ -8,8 +8,8 @@ package helloworld import scala.scalajs.js import js.annotation._ -object HelloWorld extends js.JSApp { - def main() { +object HelloWorld { + def main(args: Array[String]): Unit = { import js.DynamicImplicits.truthValue if (js.typeOf(js.Dynamic.global.document) != "undefined" && diff --git a/library/src/main/scala/scala/scalajs/js/JSApp.scala b/library/src/main/scala/scala/scalajs/js/JSApp.scala index 2c9fdba432..fed28f1e11 100644 --- a/library/src/main/scala/scala/scalajs/js/JSApp.scala +++ b/library/src/main/scala/scala/scalajs/js/JSApp.scala @@ -1,27 +1,40 @@ package scala.scalajs.js -/** Base class for top-level, entry point main objects (softly deprecated). +/** Base class for top-level, entry point main objects. * - * 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). - * - * [[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`. - * - * To execute the [[main]] method immediately when your Scala.js file is - * loaded, use the `scalaJSUseMainModuleInitializer` setting in the sbt plugin. + * Before Scala.js 0.6.18, a top-level object had to extend `js.JSApp` to be + * recognized by the sbt plugin as a "main" object, to be executed with `run`. + * Starting with Scala.js 0.6.18, any object with a standard main method of + * the form + * {{{ + * def main(args: Array[String]): Unit = ??? + * }}} + * will be recognized by the sbt plugin, just like for a JVM project. * - * Starting with Scala.js 0.6.18, the sbt plugin can also recognize "standard" - * `main` methods of the form + * In order for the `main` method to be considered by the sbt plugin, set * {{{ - * def main(args: Array[String]): Unit = ... + * scalaJSUseMainModuleInitializer := true * }}} - * 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. + * in your build. + * + * [[JSApp]] is therefore deprecated, and should not be used anymore. It will + * disappear before 1.0.0 final. + * + * Also note that an object extending [[JSApp]] is not exported to JavaScript + * anymore, nor is its `main()` method. Explicitly export the object and/or + * its main method if necessary. */ +@deprecated( + "Extending js.JSApp is not necessary anymore for an object to be " + + "recognized by the Scala.js sbt plugin. " + + "Use a normal object with a `def main(args: Array[String]): Unit` " + + "instead, which will also be cross-platform. " + + "Note that js.JSApp objects and their main() method are not " + + "automatically exported to JavaScript anymore either; explicitly export " + + "your object if you relied on this behavior.", + "1.0.0-M1") trait JSApp { + def main(args: scala.Array[String]): Unit = main() + def main(): Unit } diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 2fef2670fb..b81c907d44 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -77,15 +77,6 @@ object ScalaJSPluginInternal { "All .sjsir files on the fullClasspath, used by scalajsp", KeyRanks.Invisible) - /** Internal task to map discovered main classes to whether they are in the - * "new" style (true, standard main method) or the "old" style (false, - * `js.JSApp` or `main(): Unit` method). - */ - val scalaJSDiscoveredMainClasses = TaskKey[Map[String, Boolean]]( - "scalaJSDiscoveredMainClasses", - "Discovered main classes and whether they use the \"new\" style", - KeyRanks.Invisible) - val scalaJSModuleIdentifier = TaskKey[Option[String]]( "scalaJSModuleIdentifier", "An identifier for the module which contains the exports of Scala.js", @@ -466,57 +457,11 @@ object ScalaJSPluginInternal { }.value ) - @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" - - def isJSApp(discovered: Discovered) = - discovered.isModule && discovered.baseClasses.contains(jsApp) - - Map(Discovery(Set(jsApp), Set.empty)(Tests.allDefs(analysis)).collect { - // Old-style first, so that in case of ambiguity, we keep backward compat - case (definition, discovered) if isJSApp(discovered) => - definition.name -> false - case (definition, discovered) if discovered.hasMain => - definition.name -> true - }: _*) - } - - private val runMainParser = { - Defaults.loadForParser(discoveredMainClasses) { (_, names) => - val mainClasses = names.getOrElse(Nil).toSet - Space ~> token(NotSpace examples mainClasses) - } - } - // These settings will be filtered by the stage dummy tasks val scalaJSRunSettings = Seq( - scalaJSDiscoveredMainClasses := { - discoverScalaJSMainClasses(compile.value) - }, - - discoveredMainClasses := { - scalaJSDiscoveredMainClasses.map(_.keys.toList.sorted: Seq[String]) - .storeAs(discoveredMainClasses).triggeredBy(compile).value - }, - scalaJSMainModuleInitializer := { - val allDiscoveredMainClasses = scalaJSDiscoveredMainClasses.value mainClass.value.map { mainCl => - val newStyleMain = allDiscoveredMainClasses.getOrElse(mainCl, false) - if (newStyleMain) - ModuleInitializer.mainMethodWithArgs(mainCl, "main") - else - ModuleInitializer.mainMethod(mainCl, "main") + ModuleInitializer.mainMethodWithArgs(mainCl, "main") } }, From cce158fc1ed7cf9f2dd98a99d37a1beca194130c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 16 Jun 2017 15:26:01 +0200 Subject: [PATCH 0367/2665] Remove deprecated stuff in the sbt plugin. --- .../org/scalajs/sbtplugin/Implicits.scala | 19 ----- .../scalajs/sbtplugin/LoggerJSConsole.scala | 21 ------ .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 75 +------------------ 3 files changed, 3 insertions(+), 112 deletions(-) delete mode 100644 sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Implicits.scala delete mode 100644 sbt-plugin/src/main/scala/org/scalajs/sbtplugin/LoggerJSConsole.scala diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Implicits.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Implicits.scala deleted file mode 100644 index 60d4949c69..0000000000 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Implicits.scala +++ /dev/null @@ -1,19 +0,0 @@ -package org.scalajs.sbtplugin - -import scala.language.implicitConversions - -import org.scalajs.core.tools.logging._ -import sbt.{Logger => SbtLogger, Level => SbtLevel} - -@deprecated("Use sbtplugin.Loggers explicitly instead.", "0.6.10") -object Implicits { - - implicit def sbtLogger2ToolsLogger(logger: SbtLogger): Logger = - Loggers.sbtLogger2ToolsLogger(logger) - - implicit def sbtLevel2ToolsLevel(level: SbtLevel.Value): Level = - Loggers.sbtLevel2ToolsLevel(level) - - implicit def toolsLevel2sbtLevel(level: Level): SbtLevel.Value = - Loggers.toolsLevel2sbtLevel(level) -} diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/LoggerJSConsole.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/LoggerJSConsole.scala deleted file mode 100644 index 6342cab434..0000000000 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/LoggerJSConsole.scala +++ /dev/null @@ -1,21 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.sbtplugin - -import sbt.Logger -import org.scalajs.jsenv.JSConsole - -/** A proxy for a Logger that looks like a Mozilla console object */ -@deprecated( - "Use org.scalajs.jsenv.ConsoleJSConsole or define your own instead.", - "0.6.10") -class LoggerJSConsole(logger: Logger) extends JSConsole { - def log(msg: Any): Unit = logger.info(msg.toString) -} diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 5cd2ee2c4d..db4f4065b1 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -15,16 +15,13 @@ import sbt._ import sbtcrossproject._ -import org.scalajs.core.tools.sem.Semantics +import org.scalajs.core.ir.ScalaJSVersions + import org.scalajs.core.tools.io._ import org.scalajs.core.tools.linker._ import org.scalajs.core.tools.linker.standard._ -import org.scalajs.core.ir.ScalaJSVersions - -import org.scalajs.jsenv.{JSEnv, JSConsole} -import org.scalajs.jsenv.nodejs.NodeJSEnv -import org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv +import org.scalajs.jsenv.JSEnv object ScalaJSPlugin extends AutoPlugin { override def requires: Plugins = plugins.JvmPlugin @@ -56,75 +53,9 @@ object ScalaJSPlugin extends AutoPlugin { } // Stage values - @deprecated("Use FastOptStage instead", "0.6.6") - val PreLinkStage = Stage.FastOpt val FastOptStage = Stage.FastOpt val FullOptStage = Stage.FullOpt - // Factory methods for JSEnvs - - /** - * Creates a [[sbt.Def.Initialize Def.Initialize]] for a NodeJSEnv. Use - * this to explicitly specify in your build that you would like to run with Node.js: - * - * {{{ - * jsEnv := NodeJSEnv().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]]. - */ - @deprecated( - "Use `jsEnv := new org.scalajs.jsenv.nodejs.NodeJSEnv(...)` instead.", - "0.6.16") - def NodeJSEnv( - executable: String = "node", - args: Seq[String] = Seq.empty, - env: Map[String, String] = Map.empty - ): Def.Initialize[Task[NodeJSEnv]] = Def.task { - new NodeJSEnv( - org.scalajs.jsenv.nodejs.NodeJSEnv.Config() - .withExecutable(executable) - .withArgs(args.toList) - .withEnv(env)) - } - - /** - * Creates a [[sbt.Def.Initialize Def.Initialize]] for a JSDOMNodeJSEnv. Use - * this to explicitly specify in your build that you would like to run with - * Node.js on a JSDOM window: - * - * {{{ - * jsEnv := JSDOMNodeJSEnv().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]]. - */ - @deprecated( - "Use `jsEnv := new org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv(...)` " + - "instead.", - "0.6.16") - def JSDOMNodeJSEnv( - executable: String = "node", - args: Seq[String] = Seq.empty, - env: Map[String, String] = Map.empty - ): Def.Initialize[Task[JSDOMNodeJSEnv]] = Def.task { - new JSDOMNodeJSEnv( - org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv.Config() - .withExecutable(executable) - .withArgs(args.toList) - .withEnv(env)) - } - // ModuleKind val ModuleKind = org.scalajs.core.tools.linker.backend.ModuleKind From ee8b228ed7a72b76532a406532e9bd3c8f235168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 16 Jun 2017 16:32:52 +0200 Subject: [PATCH 0368/2665] Remove all sbt settings covered by `scalaJSLinkerConfig`. This also gives first-class status to `scalaJSLinkerConfig`, whose value is now relevant in all scopes. --- ci/matrix.xml | 52 ++++---- project/Build.scala | 75 ++++++----- .../scalajs/sbtplugin/OptimizerOptions.scala | 100 -------------- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 18 --- .../sbtplugin/ScalaJSPluginInternal.scala | 123 +++++------------- .../resources/2.11.11/BlacklistedTests.txt | 3 +- .../resources/2.11.5/BlacklistedTests.txt | 2 +- .../resources/2.11.6/BlacklistedTests.txt | 2 +- .../resources/2.11.7/BlacklistedTests.txt | 4 +- .../resources/2.11.8/BlacklistedTests.txt | 4 +- .../resources/2.12.0/BlacklistedTests.txt | 2 +- .../resources/2.12.1/BlacklistedTests.txt | 2 +- .../resources/2.12.2/BlacklistedTests.txt | 3 +- .../resources/2.13.0-M1/BlacklistedTests.txt | 3 +- .../javalib/math/BigIntegerConvertTest.scala | 2 - .../linker/backend/emitter/Emitter.scala | 4 +- .../core/tools/linker/frontend/Refiner.scala | 2 +- 17 files changed, 113 insertions(+), 288 deletions(-) delete mode 100644 sbt-plugin/src/main/scala/org/scalajs/sbtplugin/OptimizerOptions.scala diff --git a/ci/matrix.xml b/ci/matrix.xml index 49c02a898d..4fa5f7cce0 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -26,21 +26,21 @@ 'set scalaJSStage in Global := FullOptStage' \ ++$scala helloworld/run \ helloworld/clean && - sbtretry 'set scalaJSOptimizerOptions in helloworld ~= (_.withDisableOptimizer(true))' \ + sbtretry 'set scalaJSLinkerConfig in helloworld ~= (_.withOptimizer(false))' \ ++$scala helloworld/run \ helloworld/clean && - sbtretry 'set scalaJSSemantics in helloworld ~= (_.withAsInstanceOfs(org.scalajs.core.tools.sem.CheckedBehavior.Unchecked))' \ + sbtretry 'set scalaJSLinkerConfig in helloworld ~= (_.withSemantics(_.withAsInstanceOfs(CheckedBehavior.Unchecked)))' \ ++$scala helloworld/run \ helloworld/clean && sbtretry ++$scala \ - 'set scalaJSModuleKind in helloworld := ModuleKind.CommonJSModule' \ + 'set scalaJSLinkerConfig in helloworld ~= (_.withModuleKind(ModuleKind.CommonJSModule))' \ helloworld/run \ helloworld/clean && sbtretry ++$scala testingExample/test && sbtretry 'set scalaJSStage in Global := FullOptStage' \ ++$scala testingExample/test \ testingExample/clean && - sbtretry 'set scalaJSOptimizerOptions in testingExample ~= (_.withDisableOptimizer(true))' \ + sbtretry 'set scalaJSLinkerConfig in testingExample ~= (_.withOptimizer(false))' \ ++$scala testingExample/test && sbtretry ++$scala library/test && sbtretry ++$scala testSuiteJVM/test testSuiteJVM/clean && @@ -72,17 +72,17 @@ 'set scalaJSStage in Global := FullOptStage' \ ++$scala $testSuite/test \ $testSuite/clean && - sbtretry 'set scalaJSOptimizerOptions in $testSuite ~= (_.withDisableOptimizer(true))' \ + sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withOptimizer(false))' \ ++$scala $testSuite/test \ $testSuite/clean && - sbtretry 'set scalaJSSemantics in $testSuite ~= makeCompliant' \ + sbtretry 'set scalaJSLinkerConfig in $testSuite ~= makeCompliant' \ ++$scala $testSuite/test && - sbtretry 'set scalaJSSemantics in $testSuite ~= makeCompliant' \ + sbtretry 'set scalaJSLinkerConfig in $testSuite ~= makeCompliant' \ 'set scalaJSStage in Global := FullOptStage' \ ++$scala $testSuite/test \ $testSuite/clean && - sbtretry 'set scalaJSSemantics in $testSuite ~= makeCompliant' \ - 'set scalaJSOptimizerOptions in $testSuite ~= (_.withDisableOptimizer(true))' \ + sbtretry 'set scalaJSLinkerConfig in $testSuite ~= makeCompliant' \ + 'set scalaJSLinkerConfig in $testSuite ~= (_.withOptimizer(false))' \ ++$scala $testSuite/test \ $testSuite/clean && sbtretry 'set scalacOptions in $testSuite += "-Xexperimental"' \ @@ -90,9 +90,9 @@ sbtretry 'set scalacOptions in $testSuite += "-Xexperimental"' \ 'set scalaJSStage in Global := FullOptStage' \ ++$scala $testSuite/test && - sbtretry 'set scalaJSModuleKind in $testSuite := ModuleKind.CommonJSModule' \ + sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withModuleKind(ModuleKind.CommonJSModule))' \ ++$scala $testSuite/test && - sbtretry 'set scalaJSModuleKind in $testSuite := ModuleKind.CommonJSModule' \ + sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withModuleKind(ModuleKind.CommonJSModule))' \ 'set scalaJSStage in Global := FullOptStage' \ ++$scala $testSuite/test ]]> @@ -100,44 +100,44 @@ diff --git a/project/Build.scala b/project/Build.scala index e067a7f7d1..6646f75e98 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1,8 +1,10 @@ -import sbt._ -import Keys._ +import scala.language.implicitConversions import scala.annotation.tailrec +import sbt._ +import Keys._ + import bintray.Plugin.bintrayPublishSettings import bintray.Keys.{repository, bintrayOrganization, bintray} @@ -23,23 +25,39 @@ import org.scalajs.sbtplugin._ import org.scalajs.jsenv.{ConsoleJSConsole, JSEnv} import org.scalajs.jsenv.nodejs.{NodeJSEnv, JSDOMNodeJSEnv} -import ScalaJSPlugin.autoImport._ +import ScalaJSPlugin.autoImport.{ModuleKind => _, _} import ExternalCompile.scalaJSExternalCompileSettings import Loggers._ import org.scalajs.core.tools.io.{FileVirtualJSFile, MemVirtualJSFile} -import org.scalajs.core.tools.sem._ -import org.scalajs.core.tools.linker.ModuleInitializer -import org.scalajs.core.tools.linker.backend.OutputMode +import org.scalajs.core.tools.linker._ import sbtassembly.AssemblyPlugin.autoImport._ -/* In sbt 0.13 the Build trait would expose all vals to the shell, where you - * can use them in "set a := b" like expressions. This re-exposes them. +/* Things that we want to expose in the sbt command line (and hence also in + * `ci/matrix.xml`). */ object ExposedValues extends AutoPlugin { object autoImport { - val makeCompliant = Build.makeCompliant + // set scalaJSLinkerConfig in someProject ~= makeCompliant + val makeCompliant: StandardLinker.Config => StandardLinker.Config = { + _.withSemantics { semantics => + semantics + .withAsInstanceOfs(CheckedBehavior.Compliant) + .withArrayIndexOutOfBounds(CheckedBehavior.Compliant) + .withModuleInit(CheckedBehavior.Compliant) + .withStrictFloats(true) + } + } + + val CheckedBehavior = org.scalajs.core.tools.linker.CheckedBehavior + + val OutputMode = org.scalajs.core.tools.linker.standard.OutputMode + + implicit def StandardLinkerConfigStandardOps( + config: StandardLinker.Config): standard.StandardLinkerConfigStandardOps = { + standard.StandardLinkerConfigStandardOps(config) + } } } @@ -64,7 +82,7 @@ object MyScalaJSPlugin extends AutoPlugin { */ crossVersion := CrossVersion.binary, - scalaJSOptimizerOptions ~= (_.withCheckScalaJSIR(true)), + scalaJSLinkerConfig ~= (_.withCheckIR(true)), // Link source maps scalacOptions ++= { @@ -108,15 +126,6 @@ object Build { val javaDocBaseURL: String = "http://docs.oracle.com/javase/8/docs/api/" - // set scalaJSSemantics in someProject ~= makeCompliant - val makeCompliant: Semantics => Semantics = { semantics => - semantics - .withAsInstanceOfs(CheckedBehavior.Compliant) - .withArrayIndexOutOfBounds(CheckedBehavior.Compliant) - .withModuleInit(CheckedBehavior.Compliant) - .withStrictFloats(true) - } - private def includeIf(testDir: File, condition: Boolean): List[File] = if (condition) List(testDir) else Nil @@ -637,8 +646,7 @@ object Build { commonToolsSettings, crossVersion := ScalaJSCrossVersion.binary, - scalaJSModuleKind in Test := - org.scalajs.core.tools.linker.backend.ModuleKind.CommonJSModule, + scalaJSLinkerConfig in Test ~= (_.withModuleKind(ModuleKind.CommonJSModule)), jsExecutionFiles in Test := { val frameworks = (loadedTestFrameworks in testSuite in Test).value @@ -1294,10 +1302,11 @@ object Build { val stage = (scalaJSStage in Test).value - val sems = stage match { - case FastOptStage => (scalaJSSemantics in (Test, fastOptJS)).value - case FullOptStage => (scalaJSSemantics in (Test, fullOptJS)).value + val linkerConfig = stage match { + case FastOptStage => (scalaJSLinkerConfig in (Test, fastOptJS)).value + case FullOptStage => (scalaJSLinkerConfig in (Test, fullOptJS)).value } + val sems = linkerConfig.semantics val semTags = ( if (sems.asInstanceOfs == CheckedBehavior.Compliant) @@ -1327,7 +1336,7 @@ object Build { case FullOptStage => "fullopt-stage" } - val moduleKindTag = scalaJSModuleKind.value match { + val moduleKindTag = linkerConfig.moduleKind match { case ModuleKind.NoModule => "modulekind-nomodule" case ModuleKind.CommonJSModule => "modulekind-commonjs" } @@ -1463,17 +1472,19 @@ object Build { val testDir = (sourceDirectory in Test).value includeIf(testDir / "require-modules", - scalaJSModuleKind.value != ModuleKind.NoModule) + scalaJSLinkerConfig.value.moduleKind != ModuleKind.NoModule) }, testSuiteJSExecutionFilesSetting, - scalaJSSemantics ~= (_.withRuntimeClassName(_.fullName match { - case "org.scalajs.testsuite.compiler.ReflectionTest$RenamedTestClass" => - "renamed.test.Class" - case fullName => - fullName - })), + scalaJSLinkerConfig ~= { prevConfig => + prevConfig.withSemantics(_.withRuntimeClassName(_.fullName match { + case "org.scalajs.testsuite.compiler.ReflectionTest$RenamedTestClass" => + "renamed.test.Class" + case fullName => + fullName + })) + }, javaOptions in Test += "-Dscalajs.scalaVersion=" + scalaVersion.value, diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/OptimizerOptions.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/OptimizerOptions.scala deleted file mode 100644 index f4fc4f389b..0000000000 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/OptimizerOptions.scala +++ /dev/null @@ -1,100 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.sbtplugin - -import OptimizerOptions._ - -/** Various options for the Scala.js optimizer tool chain - * - * This is not a case class and does have a private constructor so that we - * can add fields in a binary-compatible manner. - * - * Use [[OptimizerOptions.apply]] and the `with` methods to create a configured - * instance. - */ -final class OptimizerOptions private ( - /** Whether to parallelize the optimizer **/ - val parallel: Boolean = OptimizerOptions.DefaultParallel, - /** Whether to run the optimizer in batch (i.e. non-incremental) mode */ - val batchMode: Boolean = false, - /** Whether to run the Scala.js optimizer */ - val disableOptimizer: Boolean = false, - /** Whether to pretty-print in fullOptJS */ - val prettyPrintFullOptJS: Boolean = false, - /** Perform expensive checks of the sanity of the Scala.js IR */ - val checkScalaJSIR: Boolean = false, - /** Use Google Closure Backend */ - val useClosureCompiler: Boolean = false -) { - - def withParallel(parallel: Boolean): OptimizerOptions = - copy(parallel = parallel) - - def withBatchMode(batchMode: Boolean): OptimizerOptions = - copy(batchMode = batchMode) - - def withDisableOptimizer(disableOptimizer: Boolean): OptimizerOptions = - copy(disableOptimizer = disableOptimizer) - - def withPrettyPrintFullOptJS(prettyPrintFullOptJS: Boolean): OptimizerOptions = - copy(prettyPrintFullOptJS = prettyPrintFullOptJS) - - def withCheckScalaJSIR(checkScalaJSIR: Boolean): OptimizerOptions = - copy(checkScalaJSIR = checkScalaJSIR) - - def withUseClosureCompiler(useClosureCompiler: Boolean): OptimizerOptions = - copy(useClosureCompiler = useClosureCompiler) - - private def copy( - parallel: Boolean = parallel, batchMode: Boolean = batchMode, - disableOptimizer: Boolean = disableOptimizer, - prettyPrintFullOptJS: Boolean = prettyPrintFullOptJS, - checkScalaJSIR: Boolean = checkScalaJSIR, - useClosureCompiler: Boolean = useClosureCompiler) = { - new OptimizerOptions(parallel, batchMode, disableOptimizer, - prettyPrintFullOptJS, checkScalaJSIR, useClosureCompiler) - } - - override def toString: String = { - s"""OptimizerOptions( - | parallel = $parallel - | batchMode = $batchMode - | disableOptimizer = $disableOptimizer - | prettyPrintFullOptJS = $prettyPrintFullOptJS - | checkScalaJSIR = $checkScalaJSIR - | useClosureCompiler = $useClosureCompiler - |)""".stripMargin - } - -} - -object OptimizerOptions { - /* #2798 -- On Java 9+, the parallel collections on 2.10 die with a - * `NumberFormatException` and prevent the linker from working. - * - * By default, we therefore pre-emptively disable the parallel optimizer in - * case the parallel collections cannot deal with the current version of - * Java. - * - * TODO This will automatically "fix itself" once we upgrade to sbt 1.x, - * which uses Scala 2.12. We should get rid of that workaround at that point - * for tidiness, though. - */ - private[sbtplugin] val DefaultParallel: Boolean = { - try { - scala.util.Properties.isJavaAtLeast("1.8") - true - } catch { - case _: NumberFormatException => false - } - } - - def apply(): OptimizerOptions = new OptimizerOptions() -} diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index db4f4065b1..9c410bf0e5 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -103,24 +103,6 @@ object ScalaJSPlugin extends AutoPlugin { "The JavaScript environment in which to run and test Scala.js applications.", AMinusTask) - val relativeSourceMaps = SettingKey[Boolean]("relativeSourceMaps", - "Make the referenced paths on source maps relative to target path", BPlusSetting) - - val emitSourceMaps = SettingKey[Boolean]("emitSourceMaps", - "Whether package and optimize stages should emit source maps at all", BPlusSetting) - - val scalaJSSemantics = SettingKey[Semantics]("scalaJSSemantics", - "Configurable semantics of Scala.js.", BPlusSetting) - - val scalaJSOutputMode = SettingKey[OutputMode]("scalaJSOutputMode", - "Output mode of Scala.js.", BPlusSetting) - - val scalaJSModuleKind = SettingKey[ModuleKind]("scalaJSModuleKind", - "Kind of JavaScript modules emitted by Scala.js.", BPlusSetting) - - val scalaJSOptimizerOptions = SettingKey[OptimizerOptions]("scalaJSOptimizerOptions", - "All kinds of options for the Scala.js optimizer stages", DSetting) - /** Prints the content of a .sjsir file in human readable form. */ val scalajsp = InputKey[Unit]("scalajsp", "Prints the content of a .sjsir file in human readable form.", diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index b81c907d44..6e36af8ef4 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -97,6 +97,26 @@ object ScalaJSPluginInternal { global["Object"] === Object) ? global : this)""" } + /* #2798 -- On Java 9+, the parallel collections on 2.10 die with a + * `NumberFormatException` and prevent the linker from working. + * + * By default, we therefore pre-emptively disable the parallel optimizer in + * case the parallel collections cannot deal with the current version of + * Java. + * + * TODO This will automatically "fix itself" once we upgrade to sbt 1.x, + * which uses Scala 2.12. We should get rid of that workaround at that point + * for tidiness, though. + */ + private val DefaultParallelLinker: Boolean = { + try { + scala.util.Properties.isJavaAtLeast("1.8") + true + } catch { + case _: NumberFormatException => false + } + } + def logIRCacheStats(logger: Logger): Unit = { logger.debug("Global IR cache stats: " + globalIRCache.stats.logLine) } @@ -134,53 +154,17 @@ object ScalaJSPluginInternal { private def scalaJSStageSettings(stage: Stage, key: TaskKey[Attributed[File]]): Seq[Setting[_]] = Seq( - scalaJSLinkerConfig in key := { - val opts = (scalaJSOptimizerOptions in key).value - - val semantics = (scalaJSSemantics in key).value - val outputMode = (scalaJSOutputMode in key).value - val moduleKind = scalaJSModuleKind.value // intentionally not 'in key' - val withSourceMap = (emitSourceMaps in key).value - - /* For `relativizeSourceMapBase`, preserve the one in the new config - * if it is set, otherwise fall back on the old config. - */ - val oldConfigRelSourceMapBase = { - if ((relativeSourceMaps in key).value) - Some((artifactPath in key).value.getParentFile.toURI()) - else - None - } - val newConfigRelSourceMapBase = - (scalaJSLinkerConfig in key).value.relativizeSourceMapBase - val relSourceMapBase = - newConfigRelSourceMapBase.orElse(oldConfigRelSourceMapBase) - - StandardLinker.Config() - .withSemantics(semantics) - .withModuleKind(moduleKind) - .withOutputMode(outputMode) - .withCheckIR(opts.checkScalaJSIR) - .withOptimizer(!opts.disableOptimizer) - .withParallel(opts.parallel) - .withSourceMap(withSourceMap) - .withRelativizeSourceMapBase(relSourceMapBase) - .withClosureCompiler(opts.useClosureCompiler) - .withPrettyPrint(opts.prettyPrintFullOptJS) - .withBatchMode(opts.batchMode) - }, - scalaJSLinker in key := { val config = (scalaJSLinkerConfig in key).value - if (config.moduleKind != scalaJSModuleKind.value) { + if (config.moduleKind != scalaJSLinkerConfig.value.moduleKind) { 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)`. " + + s"$configName, $keyName)` is different than the one `in " + + s"`($projectID, $configName)`. " + "Some things will go wrong.") } @@ -390,11 +374,10 @@ object ScalaJSPluginInternal { ((crossTarget in fullOptJS).value / ((moduleName in fullOptJS).value + "-opt.js")), - scalaJSSemantics in fullOptJS ~= (_.optimized), - scalaJSOptimizerOptions in fullOptJS := { - val prev = (scalaJSOptimizerOptions in fullOptJS).value - val outputMode = (scalaJSOutputMode in fullOptJS).value - prev.withUseClosureCompiler(outputMode == OutputMode.ECMAScript51Isolated) + scalaJSLinkerConfig in fullOptJS ~= { prevConfig => + prevConfig + .withSemantics(_.optimized) + .withClosureCompiler(prevConfig.outputMode == OutputMode.ECMAScript51Isolated) }, console := console.dependsOn(Def.task { @@ -443,7 +426,7 @@ object ScalaJSPluginInternal { jsExecutionFiles += scalaJSLinkedFile.value, scalaJSModuleIdentifier := Def.settingDyn[Task[Option[String]]] { - scalaJSModuleKind.value match { + scalaJSLinkerConfig.value.moduleKind match { case ModuleKind.NoModule => Def.task { None @@ -525,7 +508,7 @@ object ScalaJSPluginInternal { val files = jsExecutionFiles.value - val moduleKind = scalaJSModuleKind.value + val moduleKind = scalaJSLinkerConfig.value.moduleKind val moduleIdentifier = scalaJSModuleIdentifier.value val frameworksAndTheirImplNames = @@ -607,57 +590,11 @@ object ScalaJSPluginInternal { val scalaJSProjectBaseSettings = Seq( 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) + .withParallel(DefaultParallelLinker) }, - relativeSourceMaps := false, - - emitSourceMaps := scalaJSLinkerConfig.value.sourceMap, - - scalaJSOptimizerOptions := { - val config = scalaJSLinkerConfig.value - OptimizerOptions() - .withParallel(config.parallel) - .withBatchMode(config.batchMode) - .withDisableOptimizer(!config.optimizer) - .withPrettyPrintFullOptJS(config.prettyPrint) - .withCheckScalaJSIR(config.checkIR) - .withUseClosureCompiler(config.closureCompiler) - }, - - scalaJSSemantics := scalaJSLinkerConfig.value.semantics, - scalaJSOutputMode := scalaJSLinkerConfig.value.outputMode, - scalaJSModuleKind := scalaJSLinkerConfig.value.moduleKind, - scalaJSModuleInitializers := Seq(), scalaJSModuleInitializers in Compile := scalaJSModuleInitializers.value, // Do not inherit scalaJSModuleInitializers in Test from Compile diff --git a/scala-test-suite/src/test/resources/2.11.11/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.11.11/BlacklistedTests.txt index 67ab88dc99..1ea7a9470b 100644 --- a/scala-test-suite/src/test/resources/2.11.11/BlacklistedTests.txt +++ b/scala-test-suite/src/test/resources/2.11.11/BlacklistedTests.txt @@ -88,6 +88,5 @@ scala/util/SortingTest.scala scala/collection/convert/MapWrapperTest.scala # Test fails only some times with -# 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' -# and' 'set scalaJSUseRhino in Global := false' +# 'set scalaJSLinkerConfig in scalaTestSuite ~= (_.withOptimizer(false))' scala/collection/immutable/PagedSeqTest.scala diff --git a/scala-test-suite/src/test/resources/2.11.5/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.11.5/BlacklistedTests.txt index 4cb46ffb0a..3482a93651 100644 --- a/scala-test-suite/src/test/resources/2.11.5/BlacklistedTests.txt +++ b/scala-test-suite/src/test/resources/2.11.5/BlacklistedTests.txt @@ -63,5 +63,5 @@ scala/collection/SetMapConsistencyTest.scala scala/collection/convert/MapWrapperTest.scala # Test fails only some times with -# 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' +# 'set scalaJSLinkerConfig in scalaTestSuite ~= (_.withOptimizer(false))' scala/collection/immutable/PagedSeqTest.scala diff --git a/scala-test-suite/src/test/resources/2.11.6/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.11.6/BlacklistedTests.txt index 01f38969e4..b4a7a29e14 100644 --- a/scala-test-suite/src/test/resources/2.11.6/BlacklistedTests.txt +++ b/scala-test-suite/src/test/resources/2.11.6/BlacklistedTests.txt @@ -71,5 +71,5 @@ scala/collection/SetMapConsistencyTest.scala scala/collection/convert/MapWrapperTest.scala # Test fails only some times with -# 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' +# 'set scalaJSLinkerConfig in scalaTestSuite ~= (_.withOptimizer(false))' scala/collection/immutable/PagedSeqTest.scala diff --git a/scala-test-suite/src/test/resources/2.11.7/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.11.7/BlacklistedTests.txt index f47d1ebe6e..eb318835aa 100644 --- a/scala-test-suite/src/test/resources/2.11.7/BlacklistedTests.txt +++ b/scala-test-suite/src/test/resources/2.11.7/BlacklistedTests.txt @@ -82,5 +82,5 @@ scala/util/SortingTest.scala scala/collection/convert/MapWrapperTest.scala # Test fails only some times with -# 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' -scala/collection/immutable/PagedSeqTest.scala \ No newline at end of file +# 'set scalaJSLinkerConfig in scalaTestSuite ~= (_.withOptimizer(false))' +scala/collection/immutable/PagedSeqTest.scala diff --git a/scala-test-suite/src/test/resources/2.11.8/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.11.8/BlacklistedTests.txt index 9dda810713..c9df0f6ef6 100644 --- a/scala-test-suite/src/test/resources/2.11.8/BlacklistedTests.txt +++ b/scala-test-suite/src/test/resources/2.11.8/BlacklistedTests.txt @@ -87,5 +87,5 @@ scala/util/SortingTest.scala scala/collection/convert/MapWrapperTest.scala # Test fails only some times with -# 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' -scala/collection/immutable/PagedSeqTest.scala \ No newline at end of file +# 'set scalaJSLinkerConfig in scalaTestSuite ~= (_.withOptimizer(false))' +scala/collection/immutable/PagedSeqTest.scala diff --git a/scala-test-suite/src/test/resources/2.12.0/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.12.0/BlacklistedTests.txt index d68c4fb325..a349929242 100644 --- a/scala-test-suite/src/test/resources/2.12.0/BlacklistedTests.txt +++ b/scala-test-suite/src/test/resources/2.12.0/BlacklistedTests.txt @@ -105,7 +105,7 @@ scala/util/matching/RegexTest.scala scala/math/BigDecimalTest.scala # Test fails only some times with -# 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' +# 'set scalaJSLinkerConfig in scalaTestSuite ~= (_.withOptimizer(false))' scala/collection/immutable/PagedSeqTest.scala # Bugs diff --git a/scala-test-suite/src/test/resources/2.12.1/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.12.1/BlacklistedTests.txt index 5140f481d5..130abf861b 100644 --- a/scala-test-suite/src/test/resources/2.12.1/BlacklistedTests.txt +++ b/scala-test-suite/src/test/resources/2.12.1/BlacklistedTests.txt @@ -109,7 +109,7 @@ scala/util/matching/RegexTest.scala scala/math/BigDecimalTest.scala # Test fails only some times with -# 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' +# 'set scalaJSLinkerConfig in scalaTestSuite ~= (_.withOptimizer(false))' scala/collection/immutable/PagedSeqTest.scala # Bugs diff --git a/scala-test-suite/src/test/resources/2.12.2/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.12.2/BlacklistedTests.txt index c3bad1906e..8916cecd27 100644 --- a/scala-test-suite/src/test/resources/2.12.2/BlacklistedTests.txt +++ b/scala-test-suite/src/test/resources/2.12.2/BlacklistedTests.txt @@ -116,8 +116,7 @@ scala/math/BigDecimalTest.scala scala/collection/immutable/RangeTest.scala # Test fails only some times with -# 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' -# and' 'set scalaJSUseRhino in Global := false' +# 'set scalaJSLinkerConfig in scalaTestSuite ~= (_.withOptimizer(false))' scala/collection/immutable/PagedSeqTest.scala # Bugs diff --git a/scala-test-suite/src/test/resources/2.13.0-M1/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.13.0-M1/BlacklistedTests.txt index de9f1669f0..ff85a44787 100644 --- a/scala-test-suite/src/test/resources/2.13.0-M1/BlacklistedTests.txt +++ b/scala-test-suite/src/test/resources/2.13.0-M1/BlacklistedTests.txt @@ -116,8 +116,7 @@ scala/math/BigDecimalTest.scala scala/collection/immutable/RangeTest.scala # Test fails only some times with -# 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' -# and' 'set scalaJSUseRhino in Global := false' +# 'set scalaJSLinkerConfig in scalaTestSuite ~= (_.withOptimizer(false))' scala/collection/immutable/PagedSeqTest.scala # Bugs diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerConvertTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerConvertTest.scala index 7e4c905bde..8647dd776e 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerConvertTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerConvertTest.scala @@ -553,8 +553,6 @@ class BigIntegerConvertTest { } @Test def testFloatValueBug2482(): Unit = { - // To test that it works with strict floats, do: - // > set scalaJSSemantics in testSuite ~= { _.withStrictFloats(true) } assumeTrue("Assumed strict floats", hasStrictFloats) val a = "2147483649" diff --git 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 index 1434812495..5f30f67aa2 100644 --- 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 @@ -213,8 +213,8 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, throw new LinkingException( "There were module imports without fallback to global " + "variables, but module support is disabled.\n" + - "To enable module support, set scalaJSModuleKind := " + - "ModuleKind.CommonJSModule.") + "To enable module support, set `scalaJSLinkerConfig ~= " + + "(_.withModuleKind(ModuleKind.CommonJSModule))`.") } case ModuleKind.CommonJSModule => diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala index d23de59d56..501f3ca29f 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala @@ -41,7 +41,7 @@ final class Refiner { "This is a bug, please report it. " + "You can work around the bug by disabling the optimizer. " + "In the sbt plugin, this can be done with " + - "`scalaJSOptimizerOptions ~= { _.withDisableOptimizer(true) }`.") + "`scalaJSLinkerConfig ~= { _.withOptimizer(false) }`.") } logger.time("Refiner: Assemble LinkedClasses") { From 5c6e2925d273f7583581d6d39060375ecba71578 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 16 Jun 2017 16:44:12 +0200 Subject: [PATCH 0369/2665] Remove the scalaJSEnsureUnforked sbt setting. It is actually possible to `run` when `fork := true`. The only other task that used `scalaJSEnsureUnforked` was `loadedTestFrameworks`, so we move the check there. --- .../sbtplugin/ScalaJSPluginInternal.scala | 22 +++++-------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 6e36af8ef4..74dce42cd3 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -48,10 +48,6 @@ object ScalaJSPluginInternal { "Scala.js internal: Clear the global IR cache's statistics. Used to " + "implement cache statistics.", KeyRanks.Invisible) - /** 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 a Scala.js linker. */ val scalaJSLinker = SettingKey[ClearableLinker]("scalaJSLinker", "Scala.js internal: Setting to persist a linker", KeyRanks.Invisible) @@ -385,14 +381,6 @@ object ScalaJSPluginInternal { "are running a JVM REPL. JavaScript things won't work.") }).value, - // Give tasks ability to check we are not forking at build reading time - scalaJSEnsureUnforked := { - if (fork.value) - throw new MessageOnlyException("Scala.js cannot be run in a forked JVM") - else - true - }, - scalaJSJavaSystemProperties ++= { val javaSysPropsPattern = "-D([^=]*)=(.*)".r javaOptions.value.map { @@ -465,9 +453,6 @@ object ScalaJSPluginInternal { }, run := { - // use assert to prevent warning about pure expr in stat pos - assert(scalaJSEnsureUnforked.value) - if (!scalaJSUseMainModuleInitializer.value) { throw new MessageOnlyException("`run` is only supported with " + "scalaJSUseMainModuleInitializer := true") @@ -495,8 +480,11 @@ object ScalaJSPluginInternal { val scalaJSTestFrameworkSettings = Seq( loadedTestFrameworks := { - // use assert to prevent warning about pure expr in stat pos - assert(scalaJSEnsureUnforked.value) + if (fork.value) { + throw new MessageOnlyException( + "`test` tasks in a Scala.js project require " + + "`fork in Test := false`.") + } val env = jsEnv.value match { case env: ComJSEnv => env From 03f7acaf6060c61e198b7328d99d9469d67b3309 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 16 Jun 2017 16:48:21 +0200 Subject: [PATCH 0370/2665] Remove the scalaJSModuleKind sbt task. It was only used by `loadedTestFrameworks`, so we move its computation there. Note that, in the process, we "lose" the dynamism of the computation, which means that even in `NoModule`, we will force evaluation of `scalaJSLinkedFile`. However that seems irrelevant as it is also (most likely) evaluated because of the dependency on `jsExecutionFiles`. --- .../sbtplugin/ScalaJSPluginInternal.scala | 26 ++++--------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 74dce42cd3..ee0c6e0095 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -73,11 +73,6 @@ object ScalaJSPluginInternal { "All .sjsir files on the fullClasspath, used by scalajsp", KeyRanks.Invisible) - val scalaJSModuleIdentifier = TaskKey[Option[String]]( - "scalaJSModuleIdentifier", - "An identifier for the module which contains the exports of Scala.js", - KeyRanks.Invisible) - val scalaJSSourceFiles = AttributeKey[Seq[File]]("scalaJSSourceFiles", "Files used to compute this value (can be used in FileFunctions later).", KeyRanks.Invisible) @@ -411,21 +406,7 @@ object ScalaJSPluginInternal { }, // Crucially, add the Scala.js linked file to the JS files - jsExecutionFiles += scalaJSLinkedFile.value, - - scalaJSModuleIdentifier := Def.settingDyn[Task[Option[String]]] { - scalaJSLinkerConfig.value.moduleKind match { - case ModuleKind.NoModule => - Def.task { - None - } - - case ModuleKind.CommonJSModule => - Def.task { - Some(scalaJSLinkedFile.value.path) - } - } - }.value + jsExecutionFiles += scalaJSLinkedFile.value ) // These settings will be filtered by the stage dummy tasks @@ -497,7 +478,10 @@ object ScalaJSPluginInternal { val files = jsExecutionFiles.value val moduleKind = scalaJSLinkerConfig.value.moduleKind - val moduleIdentifier = scalaJSModuleIdentifier.value + val moduleIdentifier = moduleKind match { + case ModuleKind.NoModule => None + case ModuleKind.CommonJSModule => Some(scalaJSLinkedFile.value.path) + } val frameworksAndTheirImplNames = testFrameworks.value.map(f => f -> f.implClassNames.toList) From a6fe686c0045671218b299556082adc0614329d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 16 Jun 2017 16:50:07 +0200 Subject: [PATCH 0371/2665] Remove the unused val `ScalaJSPluginInternal.jsGlobalExpr`. --- .../scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index ee0c6e0095..22b61eb50a 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -82,12 +82,6 @@ object ScalaJSPluginInternal { Stage.FullOpt -> fullOptJS ) - /** A JS expression that detects the global scope just like Scala.js */ - val jsGlobalExpr: String = { - """((typeof global === "object" && global && - global["Object"] === Object) ? global : this)""" - } - /* #2798 -- On Java 9+, the parallel collections on 2.10 die with a * `NumberFormatException` and prevent the linker from working. * From 8e0e4ab54f4c36a372258907917a3297979f89d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 16 Jun 2017 17:04:32 +0200 Subject: [PATCH 0372/2665] Reduce the public-ish API in `ScalaJSPluginInternal`. --- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 5 +- .../sbtplugin/ScalaJSPluginInternal.scala | 50 ++++++------------- 2 files changed, 15 insertions(+), 40 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 9c410bf0e5..2c72ea88a2 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -133,8 +133,5 @@ object ScalaJSPlugin extends AutoPlugin { ) } - override def projectSettings: Seq[Setting[_]] = ( - scalaJSAbstractSettings ++ - scalaJSEcosystemSettings - ) + override def projectSettings: Seq[Setting[_]] = scalaJSProjectSettings } diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 22b61eb50a..39900500dd 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -400,11 +400,8 @@ object ScalaJSPluginInternal { }, // Crucially, add the Scala.js linked file to the JS files - jsExecutionFiles += scalaJSLinkedFile.value - ) + jsExecutionFiles += scalaJSLinkedFile.value, - // These settings will be filtered by the stage dummy tasks - val scalaJSRunSettings = Seq( scalaJSMainModuleInitializer := { mainClass.value.map { mainCl => ModuleInitializer.mainMethodWithArgs(mainCl, "main") @@ -448,12 +445,11 @@ object ScalaJSPluginInternal { } ) - val scalaJSCompileSettings = ( - scalaJSConfigSettings ++ - scalaJSRunSettings + val scalaJSCompileSettings: Seq[Setting[_]] = ( + scalaJSConfigSettings ) - val scalaJSTestFrameworkSettings = Seq( + private val scalaJSTestFrameworkSettings = Seq( loadedTestFrameworks := { if (fork.value) { throw new MessageOnlyException( @@ -494,7 +490,7 @@ object ScalaJSPluginInternal { } ) - val scalaJSTestBuildSettings = ( + private val scalaJSTestBuildSettings = ( scalaJSConfigSettings ) ++ ( Seq(fastOptJS, fullOptJS) map { packageJSTask => @@ -502,7 +498,7 @@ object ScalaJSPluginInternal { } ) - val scalaJSTestHtmlSettings = Seq( + private val scalaJSTestHtmlSettings = Seq( artifactPath in testHtml := { val stageSuffix = scalaJSStage.value match { case Stage.FastOpt => "fastopt" @@ -536,24 +532,13 @@ object ScalaJSPluginInternal { } ) - val scalaJSTestSettings = ( + val scalaJSTestSettings: Seq[Setting[_]] = ( scalaJSTestBuildSettings ++ - scalaJSRunSettings ++ scalaJSTestFrameworkSettings ++ scalaJSTestHtmlSettings ) - val scalaJSDefaultBuildConfigs = ( - inConfig(Compile)(scalaJSConfigSettings) ++ // build settings for Compile - inConfig(Test)(scalaJSTestBuildSettings) - ) - - val scalaJSDefaultConfigs = ( - inConfig(Compile)(scalaJSCompileSettings) ++ - inConfig(Test)(scalaJSTestSettings) - ) - - val scalaJSProjectBaseSettings = Seq( + private val scalaJSProjectBaseSettings = Seq( crossPlatform := JSPlatform, scalaJSLinkerConfig := { @@ -586,20 +571,8 @@ object ScalaJSPluginInternal { () }, - scalaJSJavaSystemProperties := Map.empty - ) + scalaJSJavaSystemProperties := Map.empty, - val scalaJSAbstractSettings: Seq[Setting[_]] = ( - scalaJSProjectBaseSettings ++ - scalaJSDefaultConfigs - ) - - val scalaJSAbstractBuildSettings: Seq[Setting[_]] = ( - scalaJSProjectBaseSettings ++ - scalaJSDefaultBuildConfigs - ) - - val scalaJSEcosystemSettings = Seq( // you will need the Scala.js compiler plugin autoCompilerPlugins := true, addCompilerPlugin( @@ -616,4 +589,9 @@ object ScalaJSPluginInternal { crossVersion := ScalaJSCrossVersion.binary ) + val scalaJSProjectSettings: Seq[Setting[_]] = ( + scalaJSProjectBaseSettings ++ + inConfig(Compile)(scalaJSCompileSettings) ++ + inConfig(Test)(scalaJSTestSettings) + ) } From 2364a54d4c5770c6ea41cf66a01cc8b3bdc0516e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 19 Jun 2017 10:24:38 +0200 Subject: [PATCH 0373/2665] Remove scalaJSIsSnapshotVersion and scalaJSBinaryVersion. They are of very limited use, and can be reconstructed with other parts of the API (namely, `ir.ScalaJSVersions.currentIsSnapshot` and `sbtplugin.ScalaJSCrossVersion.currentBinaryVersion`. --- project/Build.scala | 21 ++----------------- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 4 +--- 2 files changed, 3 insertions(+), 22 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 6646f75e98..0effbb75fb 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -88,7 +88,7 @@ object MyScalaJSPlugin extends AutoPlugin { scalacOptions ++= { val base = (baseDirectory in LocalProject("scalajs")).value if (isGeneratingEclipse) Seq() - else if (scalaJSIsSnapshotVersion) Seq() + else if (isSnapshot.value) Seq() else Seq( // Link source maps to github sources "-P:scalajs:mapSourceURI:" + base.toURI + @@ -359,23 +359,6 @@ object Build { } ) - private def publishToScalaJSRepoSettings = Seq( - publishTo := { - Seq("PUBLISH_USER", "PUBLISH_PASS").map(Properties.envOrNone) match { - case Seq(Some(user), Some(pass)) => - val snapshotsOrReleases = - if (scalaJSIsSnapshotVersion) "snapshots" else "releases" - Some(Resolver.sftp( - s"scala-js-$snapshotsOrReleases", - "repo.scala-js.org", - s"/home/scalajsrepo/www/repo/$snapshotsOrReleases")( - Resolver.ivyStylePatterns) as (user, pass)) - case _ => - None - } - } - ) - private def publishToBintraySettings = Def.settings( bintrayPublishSettings, repository in bintray := "scala-js-releases", @@ -386,7 +369,7 @@ object Build { if (Properties.envOrNone("PUBLISH_TO_BINTRAY") == Some("true")) publishToBintraySettings else - publishToScalaJSRepoSettings, + Nil, publishMavenStyle := false ) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 2c72ea88a2..beef0a9b9a 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -29,10 +29,8 @@ object ScalaJSPlugin extends AutoPlugin { object autoImport { import KeyRanks._ - // Some constants + /** The current version of the Scala.js sbt plugin and tool chain. */ val scalaJSVersion = ScalaJSVersions.current - val scalaJSIsSnapshotVersion = ScalaJSVersions.currentIsSnapshot - val scalaJSBinaryVersion = ScalaJSCrossVersion.currentBinaryVersion // The JS platform for sbt-crossproject val JSPlatform = org.scalajs.sbtplugin.JSPlatform From 917afe3f2ddbe0879139fa38f8433438f465bc73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 22 Jun 2017 11:11:28 +0200 Subject: [PATCH 0374/2665] Fix #3025: Honor `@noinline` when trying to multi-inline. The optimizer was disregarding the `inlineable` flag when deciding whether or not to perform multi-inlining. This was caught later by a `require` statement ensuring that only `inlineable` methods are indeed inlined. --- .../core/tools/linker/frontend/optimizer/OptimizerCore.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index e12b769852..b777a1191e 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -1466,7 +1466,7 @@ private[optimizer] abstract class OptimizerCore( private def canMultiInline(impls: List[MethodID]): Boolean = { // TODO? Inline multiple non-forwarders with the exact same body? - impls.forall(_.isForwarder) && + impls.forall(impl => impl.isForwarder && impl.inlineable) && (getMethodBody(impls.head).body.get match { // Trait impl forwarder case ApplyStatic(ClassType(staticCls), Ident(methodName, _), _) => From 1ab78ac50b2b0d692c2c9aa5a49d7be13b7a568e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 22 Jun 2017 18:23:42 +0200 Subject: [PATCH 0375/2665] Have the `partest` project actually *depend* on its dependencies. Before, it sourced them in. There does not seem to be any reason to still do that. --- project/Build.scala | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 60bb949e16..f8b27081a5 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1651,12 +1651,7 @@ object Build { "org.scala-lang.modules" %% "scala-partest" % "1.0.16" else "org.scala-lang.modules" %% "scala-partest" % "1.1.1" - }, - "org.scala-js" % "closure-compiler-java-6" % "v20160517", - "io.apigee" % "rhino" % "1.7R5pre4", - "com.googlecode.json-simple" % "json-simple" % "1.1.1" exclude("junit", "junit") - ) ++ ( - parallelCollectionsDependencies(scalaVersion.value) + } ) } else { Seq() @@ -1673,27 +1668,12 @@ object Build { }, sources in Compile := { - if (shouldPartest.value) { - // Partest sources and some sources of sbtplugin (see above) - val baseSrcs = (sources in Compile).value - // Sources for tools (and hence IR) - val toolSrcs = (sources in (tools, Compile)).value - // Sources for js-envs - val jsenvSrcs = { - val jsenvBase = ((scalaSource in (jsEnvs, Compile)).value / - "org/scalajs/jsenv") - - val scalaFilter: FileFilter = "*.scala" - val files = ( - (jsenvBase * scalaFilter) +++ - (jsenvBase / "nodejs" ** scalaFilter)) - - files.get - } - toolSrcs ++ baseSrcs ++ jsenvSrcs - } else Seq() + if (shouldPartest.value) + (sources in Compile).value + else + Nil } - ).dependsOn(compiler) + ).dependsOn(compiler, tools, jsEnvs) lazy val partestSuite: Project = (project in file("partest-suite")).settings( commonSettings, From f7c9f17d53b6c5639e0fd4ef3662f521fdf94249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 22 Jun 2017 16:45:24 +0200 Subject: [PATCH 0376/2665] Extract JSDOMNodeJSEnv in its own project. So that we can move it to a different repository afterwards. In the process, we also move the standard `NodeJSEnv` in a dedicated project, although this one will obviously stay in the same repository. Now that all JS environments are in different artifacts, it makes sense that Node.js have its own artifact as well, even though the sbt plugin will depend on that artifact. The separation has a nice benefit that the `jsEnvsTestSuite` is not necessary anymore, since its last tests can be moved to the test directories of the relevant JS env implementations. --- DEVELOPING.md | 5 ++-- build.sbt | 3 ++- ci/matrix.xml | 18 ++++++++----- .../jsenv/jsdomnodejs/JSDOMNodeJSEnv.scala | 0 .../jsdomnodejs}/JSDOMNodeJSEnvTest.scala | 4 +-- .../jsenv/nodejs/AbstractNodeJSEnv.scala | 0 .../org/scalajs/jsenv/nodejs/NodeJSEnv.scala | 0 .../scalajs/jsenv/nodejs}/NodeJSTest.scala | 4 +-- .../NodeJSWithCustomInitFilesTest.scala | 4 +-- project/Build.scala | 25 ++++++++++++++----- project/build.sbt | 2 ++ sbt-plugin-test/project/build.sbt | 3 +++ 12 files changed, 47 insertions(+), 21 deletions(-) rename {js-envs => jsdom-nodejs-env}/src/main/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnv.scala (100%) rename {js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test => jsdom-nodejs-env/src/test/scala/org/scalajs/jsenv/jsdomnodejs}/JSDOMNodeJSEnvTest.scala (84%) rename {js-envs => nodejs-env}/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala (100%) rename {js-envs => nodejs-env}/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala (100%) rename {js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test => nodejs-env/src/test/scala/org/scalajs/jsenv/nodejs}/NodeJSTest.scala (95%) rename {js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test => nodejs-env/src/test/scala/org/scalajs/jsenv/nodejs}/NodeJSWithCustomInitFilesTest.scala (71%) diff --git a/DEVELOPING.md b/DEVELOPING.md index af360cadb3..c571cba723 100644 --- a/DEVELOPING.md +++ b/DEVELOPING.md @@ -107,7 +107,8 @@ of `library/package`. Note that the sbt plugin depends on the IR and the tools. -* `js-envs/` The JavaScript environments and runners (generic definitions + Node.js) +* `js-envs/` The generic definitions of JavaScript environments and runners +* `nodejs-env/` The Node.js environment * `sbt-plugin/` The sbt plugin itself ### Testing projects @@ -140,4 +141,4 @@ following incantations. > ++SCALA_VERSION > ;compiler/publishLocal;library/publishLocal;testInterface/publishLocal;stubs/publishLocal;jUnitRuntime/publishLocal;jUnitPlugin/publishLocal > ++2.10.6 - > ;ir/publishLocal;tools/publishLocal;jsEnvs/publishLocal;jsEnvsTestKit/publishLocal;testAdapter/publishLocal;sbtPlugin/publishLocal + > ;ir/publishLocal;tools/publishLocal;jsEnvs/publishLocal;jsEnvsTestKit/publishLocal;nodeJSEnv/publishLocal;testAdapter/publishLocal;sbtPlugin/publishLocal diff --git a/build.sbt b/build.sbt index 14fed3c921..2821d50a58 100644 --- a/build.sbt +++ b/build.sbt @@ -6,7 +6,8 @@ val tools = Build.tools val toolsJS = Build.toolsJS val jsEnvs = Build.jsEnvs val jsEnvsTestKit = Build.jsEnvsTestKit -val jsEnvsTestSuite = Build.jsEnvsTestSuite +val nodeJSEnv = Build.nodeJSEnv +val jsdomNodeJSEnv = Build.jsdomNodeJSEnv val testAdapter = Build.testAdapter val sbtPlugin = Build.plugin val javalanglib = Build.javalanglib diff --git a/ci/matrix.xml b/ci/matrix.xml index dadd2fcf97..4a18a86004 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -154,24 +154,27 @@ setJavaVersion $java npm install && sbt ++$scala tools/package ir/test tools/test cli/package cli/assembly \ - stubs/package jsEnvsTestSuite/test \ + stubs/package nodeJSEnv/test jsdomNodeJSEnv/test \ ir/mimaReportBinaryIssues tools/mimaReportBinaryIssues \ jsEnvs/mimaReportBinaryIssues jsEnvsTestKit/mimaReportBinaryIssues \ + nodeJSEnv/mimaReportBinaryIssues \ testAdapter/mimaReportBinaryIssues \ stubs/mimaReportBinaryIssues cli/mimaReportBinaryIssues \ irJS/mimaReportBinaryIssues toolsJS/mimaReportBinaryIssues && sbt ++$scala ir/compile:doc tools/compile:doc jsEnvs/compile:doc \ - jsEnvsTestKit/compile:doc testAdapter/compile:doc stubs/compile:doc + jsEnvsTestKit/compile:doc nodeJSEnv/compile:doc \ + jsdomNodeJSEnv/compile:doc testAdapter/compile:doc stubs/compile:doc ]]>
@@ -209,6 +214,7 @@ testInterface/publishLocal stubs/publishLocal \ jUnitPlugin/publishLocal jUnitRuntime/publishLocal && sbt ++2.10.6 ir/publishLocal tools/publishLocal jsEnvs/publishLocal \ + nodeJSEnv/publishLocal jsdomNodeJSEnv/publishLocal \ testAdapter/publishLocal sbtPlugin/publishLocal && cd sbt-plugin-test && sbt noDOM/run withDOM/run \ diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnv.scala b/jsdom-nodejs-env/src/main/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnv.scala similarity index 100% rename from js-envs/src/main/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnv.scala rename to jsdom-nodejs-env/src/main/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnv.scala diff --git a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/JSDOMNodeJSEnvTest.scala b/jsdom-nodejs-env/src/test/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnvTest.scala similarity index 84% rename from js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/JSDOMNodeJSEnvTest.scala rename to jsdom-nodejs-env/src/test/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnvTest.scala index 5be81d5b8b..0957c6e998 100644 --- a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/JSDOMNodeJSEnvTest.scala +++ b/jsdom-nodejs-env/src/test/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnvTest.scala @@ -1,6 +1,6 @@ -package org.scalajs.jsenv.test +package org.scalajs.jsenv.jsdomnodejs -import org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv +import org.scalajs.jsenv.test._ import org.junit.Test import org.junit.Assert._ diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala similarity index 100% rename from js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala rename to nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala similarity index 100% rename from js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala rename to nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala diff --git a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/NodeJSTest.scala b/nodejs-env/src/test/scala/org/scalajs/jsenv/nodejs/NodeJSTest.scala similarity index 95% rename from js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/NodeJSTest.scala rename to nodejs-env/src/test/scala/org/scalajs/jsenv/nodejs/NodeJSTest.scala index f8fe024091..764d8ac8ef 100644 --- a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/NodeJSTest.scala +++ b/nodejs-env/src/test/scala/org/scalajs/jsenv/nodejs/NodeJSTest.scala @@ -1,6 +1,6 @@ -package org.scalajs.jsenv.test +package org.scalajs.jsenv.nodejs -import org.scalajs.jsenv.nodejs.NodeJSEnv +import org.scalajs.jsenv.test._ import org.junit.Test import org.junit.Assert._ diff --git a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/NodeJSWithCustomInitFilesTest.scala b/nodejs-env/src/test/scala/org/scalajs/jsenv/nodejs/NodeJSWithCustomInitFilesTest.scala similarity index 71% rename from js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/NodeJSWithCustomInitFilesTest.scala rename to nodejs-env/src/test/scala/org/scalajs/jsenv/nodejs/NodeJSWithCustomInitFilesTest.scala index 758a919f39..d1841bd603 100644 --- a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/NodeJSWithCustomInitFilesTest.scala +++ b/nodejs-env/src/test/scala/org/scalajs/jsenv/nodejs/NodeJSWithCustomInitFilesTest.scala @@ -1,6 +1,6 @@ -package org.scalajs.jsenv.test +package org.scalajs.jsenv.nodejs -import org.scalajs.jsenv.nodejs.NodeJSEnv +import org.scalajs.jsenv.test._ class NodeJSWithCustomInitFilesTest extends CustomInitFilesTest { protected def newJSEnv: NodeJSEnv = new NodeJSEnv { diff --git a/project/Build.scala b/project/Build.scala index f8b27081a5..d7c61d9867 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -494,7 +494,8 @@ object Build { clean in compiler, clean in irProject, clean in irProjectJS, clean in tools, clean in toolsJS, - clean in jsEnvs, clean in jsEnvsTestKit, clean in jsEnvsTestSuite, + clean in jsEnvs, clean in jsEnvsTestKit, clean in nodeJSEnv, + clean in jsdomNodeJSEnv, clean in testAdapter, clean in plugin, clean in javalanglib, clean in javalib, clean in scalalib, clean in libraryAux, clean in library, @@ -771,13 +772,25 @@ object Build { mimaBinaryIssueFilters ++= BinaryIncompatibilities.JSEnvsTestKit ).dependsOn(tools, jsEnvs) - lazy val jsEnvsTestSuite: Project = (project in file("js-envs-test-suite")).settings( + lazy val nodeJSEnv: Project = (project in file("nodejs-env")).settings( commonSettings, fatalWarningsSettings, - name := "Scala.js JS Envs Test Suite", + name := "Scala.js Node.js env", + normalizedName := "scalajs-nodejs-env", + libraryDependencies += + "com.novocode" % "junit-interface" % "0.9" % "test", + previousArtifactSetting + ).dependsOn(jsEnvs, jsEnvsTestKit % "test") + + // Node.js with jsdom - to be moved in a separate repository + lazy val jsdomNodeJSEnv: Project = (project in file("jsdom-nodejs-env")).settings( + commonSettings, + fatalWarningsSettings, + name := "Scala.js JSDOM Node.js env", + normalizedName := "scalajs-jsdom-nodejs-env", libraryDependencies += "com.novocode" % "junit-interface" % "0.9" % "test" - ).dependsOn(tools, jsEnvs, jsEnvsTestKit % "test") + ).dependsOn(jsEnvs, nodeJSEnv, jsEnvsTestKit % "test") lazy val testAdapter = (project in file("test-adapter")).settings( commonSettings, @@ -818,7 +831,7 @@ object Build { sbtJars.map(_.data -> docUrl).toMap } - ).dependsOn(tools, jsEnvs, testAdapter) + ).dependsOn(tools, jsEnvs, nodeJSEnv, testAdapter) lazy val delambdafySetting = { scalacOptions ++= ( @@ -1673,7 +1686,7 @@ object Build { else Nil } - ).dependsOn(compiler, tools, jsEnvs) + ).dependsOn(compiler, tools, nodeJSEnv) lazy val partestSuite: Project = (project in file("partest-suite")).settings( commonSettings, diff --git a/project/build.sbt b/project/build.sbt index 986409d885..b4425ac674 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -27,6 +27,8 @@ unmanagedSourceDirectories in Compile ++= { root / "tools/shared/src/main/scala", root / "tools/jvm/src/main/scala", root / "js-envs/src/main/scala", + root / "nodejs-env/src/main/scala", + root / "jsdom-nodejs-env/src/main/scala", root / "test-adapter/src/main/scala", root / "sbt-plugin/src/main/scala", root / "jsdependencies-core/src/main/scala", diff --git a/sbt-plugin-test/project/build.sbt b/sbt-plugin-test/project/build.sbt index 6626b7a52e..7f835dfb85 100644 --- a/sbt-plugin-test/project/build.sbt +++ b/sbt-plugin-test/project/build.sbt @@ -1,2 +1,5 @@ addSbtPlugin("org.scala-js" % "sbt-scalajs" % org.scalajs.core.ir.ScalaJSVersions.current) + +libraryDependencies += + "org.scala-js" %% "scalajs-jsdom-nodejs-env" % org.scalajs.core.ir.ScalaJSVersions.current From 6168d19ce0aae70222d891ce9499d9801fd8886f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 23 Jun 2017 10:23:04 +0200 Subject: [PATCH 0377/2665] Remove obsolete version test on 2.12.0-M4. --- .../test/scala/org/scalajs/testsuite/compiler/IntTest.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/IntTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/IntTest.scala index 402f52c04d..70c2e7d13b 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/IntTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/IntTest.scala @@ -338,8 +338,7 @@ class IntTest { private def scalacCorrectlyHandlesIntShiftLong: Boolean = { import Platform.scalaVersion - !(scalaVersion.startsWith("2.10.") || scalaVersion.startsWith("2.11.") || - scalaVersion.startsWith("2.12.0-M4")) + !(scalaVersion.startsWith("2.10.") || scalaVersion.startsWith("2.11.")) } @Test def intShiftLeftLongConstantFolded(): Unit = { From 9e5cc2d5487a64367ba3830062790c8b017b32b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 23 Jun 2017 10:24:32 +0200 Subject: [PATCH 0378/2665] (Don't) fix #3024: Drop support for Scala 2.12.0. That version suffers from a regression for fields of traits in some situations, which in particular affects all fields of JS traits with `= js.undefined` since `js.UndefOr[A]` is an alias for `A | Unit`. Since it comes to a choice between supporting that version of Scala and the ability to define `js.UndefOr[A]` as such an alias, we favor the latter. --- ci/checksizes.sh | 2 +- ci/matrix.xml | 16 ---------------- .../org/scalajs/core/compiler/GenJSCode.scala | 1 - .../core/compiler/test/JSExportTest.scala | 3 --- project/Build.scala | 1 - scripts/assemble-cli.sh | 2 +- scripts/publish.sh | 2 +- .../testsuite/compiler/RegressionTest.scala | 3 +-- 8 files changed, 4 insertions(+), 26 deletions(-) diff --git a/ci/checksizes.sh b/ci/checksizes.sh index c16a7d7ecf..ebe90022c4 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -17,7 +17,7 @@ case $FULLVER in 2.13.0-M1) VER=2.13.0-M1 ;; - 2.10.3|2.10.4|2.10.5|2.10.6|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7|2.11.8|2.12.0|2.12.1) + 2.10.3|2.10.4|2.10.5|2.10.6|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7|2.11.8|2.12.1) echo "Ignoring checksizes for Scala $FULLVER" exit 0 ;; diff --git a/ci/matrix.xml b/ci/matrix.xml index dadd2fcf97..bef806c4e0 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -471,10 +471,6 @@ 2.11.8 1.8
- - 2.12.0 - 1.8 - 2.12.1 1.8 @@ -663,18 +659,6 @@ 2.11.11 1.8 - - 2.12.0 - 1.8 - - - 2.12.0 - 1.8 - - - 2.12.0 - 1.8 - 2.12.1 1.8 diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index ad3191552f..08efc4c1a5 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -3410,7 +3410,6 @@ abstract class GenJSCode extends plugins.PluginComponent { v.startsWith("2.10.") || v.startsWith("2.11.") || - v == "2.12.0" || v == "2.12.1" } } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index a4a62b3d39..67c694b016 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -1313,9 +1313,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticLazyVal: Unit = { - // Affected by Scala bug SI-10075 - assumeTrue(scala.util.Properties.versionNumberString != "2.12.0") - """ class StaticContainer extends js.Object diff --git a/project/Build.scala b/project/Build.scala index 60bb949e16..c96234c326 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -465,7 +465,6 @@ object Build { "2.11.7", "2.11.8", "2.11.11", - "2.12.0", "2.12.1", "2.12.2", "2.13.0-M1" diff --git a/scripts/assemble-cli.sh b/scripts/assemble-cli.sh index bc27fac4e9..d122e6f96f 100755 --- a/scripts/assemble-cli.sh +++ b/scripts/assemble-cli.sh @@ -20,7 +20,7 @@ case $BINVER in BASEVER="2.11.11" ;; 2.12) - FULLVERS="2.12.0 2.12.1 2.12.2" + FULLVERS="2.12.1 2.12.2" BASEVER="2.12.2" ;; *) diff --git a/scripts/publish.sh b/scripts/publish.sh index 327e26df92..209f1501ee 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -8,7 +8,7 @@ else CMD="echo sbt" fi -FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.12.0 2.12.1 2.12.2 2.13.0-M1" +FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.12.1 2.12.2 2.13.0-M1" BIN_VERSIONS="2.10.6 2.11.11 2.12.2 2.13.0-M1" CLI_VERSIONS="2.10.6 2.11.11 2.12.2" SBT_VERSION="2.10.6" diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala index 1f8713596d..c06f0f73db 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala @@ -472,7 +472,6 @@ class RegressionTest { { v.startsWith("2.10.") || v.startsWith("2.11.") || - v == "2.12.0" || v == "2.12.1" } } @@ -592,7 +591,7 @@ class RegressionTest { assumeTrue( "Super mixin calls are broken in Scala/JVM 2.12.{0-2} and 2.13.0-M1", !Platform.executingInJVM || - !Set("2.12.0", "2.12.1", "2.12.2", "2.13.0-M1").contains(Platform.scalaVersion)) + !Set("2.12.1", "2.12.2", "2.13.0-M1").contains(Platform.scalaVersion)) import Bug3013._ From 3bee4785ee027b640a74dcad6fd1b13cf1f2bfa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 26 Jun 2017 10:34:57 +0200 Subject: [PATCH 0379/2665] Fix #2842: Remove the jsdom environment from the core. Node.js with jsdom support moved to the separate repository https://github.com/scala-js/scala-js-env-jsdom-nodejs. --- DEVELOPING.md | 2 +- build.sbt | 1 - ci/matrix.xml | 39 ++-- .../jsenv/jsdomnodejs/JSDOMNodeJSEnv.scala | 185 ------------------ .../jsdomnodejs/JSDOMNodeJSEnvTest.scala | 23 --- package.json | 3 +- project/Build.scala | 24 +-- project/build.sbt | 1 - sbt-plugin-test/build.sbt | 12 +- sbt-plugin-test/project/build.sbt | 3 - .../src/main/scala/sbttest/withDOM/Lib.scala | 19 -- .../main/scala/sbttest/withDOM/TestApp.scala | 12 -- .../test/scala/sbttest/withDOM/LibTest.scala | 16 -- .../scalajs/testsuite/utils/Platform.scala | 1 - .../testsuite/javalib/lang/SystemJSTest.scala | 9 +- .../scalajs/testsuite/utils/Platform.scala | 1 - 16 files changed, 24 insertions(+), 327 deletions(-) delete mode 100644 jsdom-nodejs-env/src/main/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnv.scala delete mode 100644 jsdom-nodejs-env/src/test/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnvTest.scala delete mode 100644 sbt-plugin-test/withDOM/src/main/scala/sbttest/withDOM/Lib.scala delete mode 100644 sbt-plugin-test/withDOM/src/main/scala/sbttest/withDOM/TestApp.scala delete mode 100644 sbt-plugin-test/withDOM/src/test/scala/sbttest/withDOM/LibTest.scala diff --git a/DEVELOPING.md b/DEVELOPING.md index c571cba723..d14dfabd1f 100644 --- a/DEVELOPING.md +++ b/DEVELOPING.md @@ -121,7 +121,7 @@ Note that the sbt plugin depends on the IR and the tools. * `examples/helloworld/` A simple Hello World, typically used as sandbox for quick testing * `examples/reversi/` The historical Reversi demo - we use it to track the impact of changes on the emitted code size -* `examples/testing/` A simple project with tests using the DOM, mostly used to test the support for the DOM with jsdom +* `examples/testing/` A simple project with tests using the DOM, mostly used to test `testHtml` with DOM interaction These example projects also have HTML pages to run them in real browsers. diff --git a/build.sbt b/build.sbt index 2821d50a58..f7fbed7c1a 100644 --- a/build.sbt +++ b/build.sbt @@ -7,7 +7,6 @@ val toolsJS = Build.toolsJS val jsEnvs = Build.jsEnvs val jsEnvsTestKit = Build.jsEnvsTestKit val nodeJSEnv = Build.nodeJSEnv -val jsdomNodeJSEnv = Build.jsdomNodeJSEnv val testAdapter = Build.testAdapter val sbtPlugin = Build.plugin val javalanglib = Build.javalanglib diff --git a/ci/matrix.xml b/ci/matrix.xml index fd6eb9b1ed..d1acd1a333 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -20,12 +20,6 @@ sbtretry 'set scalaJSStage in Global := FullOptStage' \ ++$scala helloworld/run \ helloworld/clean && - sbtretry 'set jsEnv in helloworld := new org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv' \ - ++$scala helloworld/run && - sbtretry 'set jsEnv in helloworld := new org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv' \ - 'set scalaJSStage in Global := FullOptStage' \ - ++$scala helloworld/run \ - helloworld/clean && sbtretry 'set scalaJSLinkerConfig in helloworld ~= (_.withOptimizer(false))' \ ++$scala helloworld/run \ helloworld/clean && @@ -36,12 +30,10 @@ 'set scalaJSLinkerConfig in helloworld ~= (_.withModuleKind(ModuleKind.CommonJSModule))' \ helloworld/run \ helloworld/clean && - sbtretry ++$scala testingExample/test && + sbtretry ++$scala testingExample/testHtml && sbtretry 'set scalaJSStage in Global := FullOptStage' \ - ++$scala testingExample/test \ + ++$scala testingExample/testHtml \ testingExample/clean && - sbtretry 'set scalaJSLinkerConfig in testingExample ~= (_.withOptimizer(false))' \ - ++$scala testingExample/test && sbtretry ++$scala library/test && sbtretry ++$scala testSuiteJVM/test testSuiteJVM/clean && sbtretry ++$scala testSuite/test && @@ -66,12 +58,6 @@ sbtretry 'set scalaJSStage in Global := FullOptStage' \ ++$scala $testSuite/test \ $testSuite/clean && - sbtretry 'set jsEnv in $testSuite := new org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv' \ - ++$scala $testSuite/test && - sbtretry 'set jsEnv in $testSuite := new org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv' \ - 'set scalaJSStage in Global := FullOptStage' \ - ++$scala $testSuite/test \ - $testSuite/clean && sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withOptimizer(false))' \ ++$scala $testSuite/test \ $testSuite/clean && @@ -154,7 +140,7 @@ setJavaVersion $java npm install && sbt ++$scala tools/package ir/test tools/test cli/package cli/assembly \ - stubs/package nodeJSEnv/test jsdomNodeJSEnv/test \ + stubs/package nodeJSEnv/test \ ir/mimaReportBinaryIssues tools/mimaReportBinaryIssues \ jsEnvs/mimaReportBinaryIssues jsEnvsTestKit/mimaReportBinaryIssues \ nodeJSEnv/mimaReportBinaryIssues \ @@ -163,14 +149,14 @@ irJS/mimaReportBinaryIssues toolsJS/mimaReportBinaryIssues && sbt ++$scala ir/compile:doc tools/compile:doc jsEnvs/compile:doc \ jsEnvsTestKit/compile:doc nodeJSEnv/compile:doc \ - jsdomNodeJSEnv/compile:doc testAdapter/compile:doc stubs/compile:doc + testAdapter/compile:doc stubs/compile:doc ]]>
@@ -214,16 +199,16 @@ testInterface/publishLocal stubs/publishLocal \ jUnitPlugin/publishLocal jUnitRuntime/publishLocal && sbt ++2.10.6 ir/publishLocal tools/publishLocal jsEnvs/publishLocal \ - nodeJSEnv/publishLocal jsdomNodeJSEnv/publishLocal \ - testAdapter/publishLocal sbtPlugin/publishLocal && + nodeJSEnv/publishLocal testAdapter/publishLocal \ + sbtPlugin/publishLocal && cd sbt-plugin-test && - sbt noDOM/run withDOM/run \ - noDOM/testHtml withDOM/testHtml multiTestJS/testHtml \ + sbt noDOM/run \ + noDOM/testHtml multiTestJS/testHtml \ test \ noDOM/clean noDOM/concurrentUseOfLinkerTest \ multiTestJS/test:testScalaJSSourceMapAttribute && sbt 'set scalaJSStage in Global := FullOptStage' \ - noDOM/testHtml withDOM/testHtml multiTestJS/testHtml + noDOM/testHtml multiTestJS/testHtml ]]> file.path - case file => libCache.materialize(file).getAbsolutePath - } - val scriptsURIs = - scriptsPaths.map(path => new java.io.File(path).toURI.toASCIIString) - val scriptsURIsAsJSStrings = scriptsURIs.map('"' + escapeJS(_) + '"') - val jsDOMCode = { - s""" - |(function () { - | var jsdom; - | try { - | jsdom = require("jsdom/lib/old-api.js"); // jsdom >= 10.x - | } catch (e) { - | jsdom = require("jsdom"); // jsdom <= 9.x - | } - | - | var virtualConsole = jsdom.createVirtualConsole() - | .sendTo(console, { omitJsdomErrors: true }); - | virtualConsole.on("jsdomError", function (error) { - | /* This inelegant if + console.error is the only way I found - | * to make sure the stack trace of the original error is - | * printed out. - | */ - | if (error.detail && error.detail.stack) - | console.error(error.detail.stack); - | - | // Throw the error anew to make sure the whole execution fails - | throw error; - | }); - | - | jsdom.env({ - | html: "", - | url: "http://localhost/", - | virtualConsole: virtualConsole, - | created: function (error, window) { - | if (error == null) { - | window["__ScalaJSEnv"] = __ScalaJSEnv; - | window["scalajsCom"] = global.scalajsCom; - | } else { - | throw error; - | } - | }, - | scripts: [${scriptsURIsAsJSStrings.mkString(", ")}] - | }); - |})(); - |""".stripMargin - } - Seq(new MemVirtualJSFile("codeWithJSDOMContext.js").withContent(jsDOMCode)) - } - - /** All the JS files that are passed to the VM. - * - * This method can overridden to provide custom behavior in subclasses. - * - * This method is overridden in `JSDOMNodeJSEnv` so that user-provided - * JS files (excluding "init" files) are executed as *scripts* within the - * jsdom environment, rather than being directly executed by the VM. - * - * The value returned by this method in `JSDOMNodeJSEnv` is - * `initFiles() ++ customInitFiles() ++ codeWithJSDOMContext()`. - */ - override protected def getJSFiles(): Seq[VirtualJSFile] = - initFiles() ++ customInitFiles() ++ codeWithJSDOMContext() - - /** JS files to be loaded via scripts in the jsdom environment. - * - * This method can be overridden to provide a different list of scripts. - * - * The default value in `JSDOMNodeJSEnv` is `files`. - */ - protected def getScriptsJSFiles(): Seq[VirtualJSFile] = - files - - // Send code to Stdin - override protected def sendVMStdin(out: OutputStream): Unit = { - /* Do not factor this method out into AbstractNodeRunner or when mixin in - * the traits it would use AbstractExtRunner.sendVMStdin due to - * linearization order. - */ - sendJS(getJSFiles(), out) - } - } -} - -object JSDOMNodeJSEnv { - final class Config private ( - val executable: String, - val args: List[String], - val env: Map[String, String] - ) { - private def this() = { - this( - executable = "node", - args = Nil, - env = Map.empty - ) - } - - def withExecutable(executable: String): Config = - copy(executable = executable) - - def withArgs(args: List[String]): Config = - copy(args = args) - - def withEnv(env: Map[String, String]): Config = - copy(env = env) - - private def copy( - executable: String = executable, - args: List[String] = args, - env: Map[String, String] = env - ): Config = { - new Config(executable, args, env) - } - } - - object Config { - /** Returns a default configuration for a [[JSDOMNodeJSEnv]]. - * - * The defaults are: - * - * - `executable`: `"node"` - * - `args`: `Nil` - * - `env`: `Map.empty` - */ - def apply(): Config = new Config() - } -} diff --git a/jsdom-nodejs-env/src/test/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnvTest.scala b/jsdom-nodejs-env/src/test/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnvTest.scala deleted file mode 100644 index 0957c6e998..0000000000 --- a/jsdom-nodejs-env/src/test/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnvTest.scala +++ /dev/null @@ -1,23 +0,0 @@ -package org.scalajs.jsenv.jsdomnodejs - -import org.scalajs.jsenv.test._ - -import org.junit.Test -import org.junit.Assert._ - -class JSDOMNodeJSEnvTest extends TimeoutComTests { - - protected def newJSEnv: JSDOMNodeJSEnv = new JSDOMNodeJSEnv() - - @Test - def historyAPI: Unit = { - """|console.log(window.location.href); - |window.history.pushState({}, "", "/foo"); - |console.log(window.location.href); - """.stripMargin hasOutput - """|http://localhost/ - |http://localhost/foo - |""".stripMargin - } - -} diff --git a/package.json b/package.json index 28a69413e5..9c61a9b571 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,6 @@ "private": true, "devDependencies": { "source-map-support": "0.4.15", - "jszip": "2.4.0", - "jsdom": "9.12.0" + "jszip": "2.4.0" } } diff --git a/project/Build.scala b/project/Build.scala index 0ad4c95a9e..13196e38f6 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -24,7 +24,6 @@ import org.scalajs.core.ir.Utils.escapeJS import org.scalajs.sbtplugin._ import org.scalajs.jsenv.{ConsoleJSConsole, JSEnv} import org.scalajs.jsenv.nodejs.NodeJSEnv -import org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv import ScalaJSPlugin.autoImport.{ModuleKind => _, _} import ExternalCompile.scalaJSExternalCompileSettings @@ -494,7 +493,6 @@ object Build { clean in irProject, clean in irProjectJS, clean in tools, clean in toolsJS, clean in jsEnvs, clean in jsEnvsTestKit, clean in nodeJSEnv, - clean in jsdomNodeJSEnv, clean in testAdapter, clean in plugin, clean in javalanglib, clean in javalib, clean in scalalib, clean in libraryAux, clean in library, @@ -781,16 +779,6 @@ object Build { previousArtifactSetting ).dependsOn(jsEnvs, jsEnvsTestKit % "test") - // Node.js with jsdom - to be moved in a separate repository - lazy val jsdomNodeJSEnv: Project = (project in file("jsdom-nodejs-env")).settings( - commonSettings, - fatalWarningsSettings, - name := "Scala.js JSDOM Node.js env", - normalizedName := "scalajs-jsdom-nodejs-env", - libraryDependencies += - "com.novocode" % "junit-interface" % "0.9" % "test" - ).dependsOn(jsEnvs, nodeJSEnv, jsEnvsTestKit % "test") - lazy val testAdapter = (project in file("test-adapter")).settings( commonSettings, publishSettings, @@ -1254,7 +1242,12 @@ object Build { exampleSettings, name := "Testing - Scala.js example", moduleName := "testing", - jsEnv := new JSDOMNodeJSEnv() + + test in Test := { + throw new MessageOnlyException( + "testingExample/test is not supported because it requires DOM " + + "support. Use testingExample/testHtml instead.") + } ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( library, jUnitRuntime % "test" ) @@ -1285,9 +1278,6 @@ object Build { baseArgs } - case env: JSDOMNodeJSEnv => - Seq("nodejs.jsdom", "typedarray") - case _ => throw new AssertionError( s"Unknown JSEnv of class ${env.getClass.getName}: " + @@ -1409,7 +1399,7 @@ object Build { // We need to patch the system properties. scalaJSJavaSystemProperties in Test in testHtml ~= { base => val unsupported = - Seq("nodejs", "nodejs.jsdom", "source-maps") + Seq("nodejs", "source-maps") val supported = Seq("typedarray", "browser") diff --git a/project/build.sbt b/project/build.sbt index b4425ac674..fac9407d39 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -28,7 +28,6 @@ unmanagedSourceDirectories in Compile ++= { root / "tools/jvm/src/main/scala", root / "js-envs/src/main/scala", root / "nodejs-env/src/main/scala", - root / "jsdom-nodejs-env/src/main/scala", root / "test-adapter/src/main/scala", root / "sbt-plugin/src/main/scala", root / "jsdependencies-core/src/main/scala", diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index 1f3293219e..ab178c6ac7 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -1,5 +1,4 @@ import org.scalajs.core.tools.io._ -import org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv import org.scalajs.sbtplugin.ScalaJSPluginInternal._ import org.scalajs.sbtplugin.Loggers.sbtLogger2ToolsLogger @@ -31,7 +30,7 @@ lazy val referencedCrossProjectJS = ProjectRef(file("referencedCrossProject"), " lazy val referencedCrossProjectJVM = ProjectRef(file("referencedCrossProject"), "referencedCrossProjectJVM") lazy val root = project.in(file(".")). - aggregate(noDOM, withDOM, multiTestJS, multiTestJVM, referencedCrossProjectJS, referencedCrossProjectJVM) + aggregate(noDOM, multiTestJS, multiTestJVM, referencedCrossProjectJS, referencedCrossProjectJVM) lazy val noDOM = project.settings(baseSettings: _*). enablePlugins(ScalaJSPlugin). @@ -70,15 +69,6 @@ lazy val noDOM = project.settings(baseSettings: _*). } ))) -lazy val withDOM = project.settings(baseSettings: _*). - enablePlugins(ScalaJSPlugin). - enablePlugins(ScalaJSJUnitPlugin). - settings( - name := "Scala.js sbt test w/ DOM", - jsEnv := new JSDOMNodeJSEnv(), - scalaJSUseMainModuleInitializer := true - ) - lazy val testFramework = crossProject.crossType(CrossType.Pure). settings(versionSettings: _*). settings(name := "Dummy cross JS/JVM test framework"). diff --git a/sbt-plugin-test/project/build.sbt b/sbt-plugin-test/project/build.sbt index 7f835dfb85..6626b7a52e 100644 --- a/sbt-plugin-test/project/build.sbt +++ b/sbt-plugin-test/project/build.sbt @@ -1,5 +1,2 @@ addSbtPlugin("org.scala-js" % "sbt-scalajs" % org.scalajs.core.ir.ScalaJSVersions.current) - -libraryDependencies += - "org.scala-js" %% "scalajs-jsdom-nodejs-env" % org.scalajs.core.ir.ScalaJSVersions.current diff --git a/sbt-plugin-test/withDOM/src/main/scala/sbttest/withDOM/Lib.scala b/sbt-plugin-test/withDOM/src/main/scala/sbttest/withDOM/Lib.scala deleted file mode 100644 index 4c22036338..0000000000 --- a/sbt-plugin-test/withDOM/src/main/scala/sbttest/withDOM/Lib.scala +++ /dev/null @@ -1,19 +0,0 @@ -package sbttest.withDOM - -import scala.scalajs.js - -object Lib { - - val document: js.Dynamic = js.Dynamic.global.document - - def getElementsByTagName(name: String): js.Array[js.Dynamic] = - document.getElementsByTagName(name).asInstanceOf[js.Array[js.Dynamic]] - - /** appends a

with the message to the document */ - def appendDocument(msg: String): Unit = { - val elem = document.createElement("p") - elem.appendChild(document.createTextNode(msg)) - document.body.appendChild(elem) - } - -} diff --git a/sbt-plugin-test/withDOM/src/main/scala/sbttest/withDOM/TestApp.scala b/sbt-plugin-test/withDOM/src/main/scala/sbttest/withDOM/TestApp.scala deleted file mode 100644 index 08e9cecbf0..0000000000 --- a/sbt-plugin-test/withDOM/src/main/scala/sbttest/withDOM/TestApp.scala +++ /dev/null @@ -1,12 +0,0 @@ -package sbttest.withDOM - -object TestApp { - - def main(args: Array[String]): Unit = { - Lib.appendDocument("Hello World") - Lib.appendDocument("Still Here!") - - println(Lib.getElementsByTagName("p").head.innerHTML) - } - -} diff --git a/sbt-plugin-test/withDOM/src/test/scala/sbttest/withDOM/LibTest.scala b/sbt-plugin-test/withDOM/src/test/scala/sbttest/withDOM/LibTest.scala deleted file mode 100644 index 174ec87af2..0000000000 --- a/sbt-plugin-test/withDOM/src/test/scala/sbttest/withDOM/LibTest.scala +++ /dev/null @@ -1,16 +0,0 @@ -package sbttest.withDOM - -import scala.scalajs.js - -import org.junit.Test -import org.junit.Assert._ - -class LibTest { - @Test def dummy_library_should_append_an_element(): Unit = { - def count = Lib.getElementsByTagName("p").length - - val oldCount = count - Lib.appendDocument("foo") - assertEquals(1, count - oldCount) - } -} diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala index a93dd7e269..a7b8cda5ef 100644 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala +++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala @@ -34,7 +34,6 @@ object Platform { js.typeOf(js.Dynamic.global.Symbol) != "undefined" def executingInNodeJS: Boolean = sysProp("nodejs") - def executingInNodeJSOnJSDOM: Boolean = sysProp("nodejs.jsdom") def executingInBrowser: Boolean = sysProp("browser") def typedArrays: Boolean = sysProp("typedarray") def sourceMaps: Boolean = sysProp("source-maps") diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala index 0b610351ce..b5cb513834 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala @@ -105,22 +105,17 @@ class SystemJSTest { val inBrowser = get("scalajs.browser") == "true" val inNode = get("scalajs.nodejs") == "true" - val inNodeWithJSDOM = get("scalajs.nodejs.jsdom") == "true" if (inBrowser) { assertNotEquals("undefined", js.typeOf(js.Dynamic.global.window)) - assertFalse(inNode || inNodeWithJSDOM) + assertFalse(inNode) } else if (inNode) { assertNotEquals("undefined", js.typeOf(js.Dynamic.global.process)) - assertFalse(inBrowser || inNodeWithJSDOM) - } else if (inNodeWithJSDOM) { - assertNotEquals("undefined", js.typeOf(js.Dynamic.global.window)) - assertFalse(inBrowser || inNode) + assertFalse(inBrowser) } else { fail("No known platform tag found.") } assertEquals(inBrowser, Platform.executingInBrowser) assertEquals(inNode, Platform.executingInNodeJS) - assertEquals(inNodeWithJSDOM, Platform.executingInNodeJSOnJSDOM) val typedArrays = get("scalajs.typedarray") == "true" assertEquals(typedArrays, Platform.typedArrays) diff --git a/test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala b/test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala index 163c87e3f6..da043e5ae6 100644 --- a/test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala +++ b/test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala @@ -21,7 +21,6 @@ object Platform { } def executingInNodeJS: Boolean = false - def executingInNodeJSOnJSDOM: Boolean = false def typedArrays: Boolean = false def sourceMaps: Boolean = false From ba9b27721eac92d1cbaabd73878aca86a09295d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 26 Jun 2017 10:52:45 +0200 Subject: [PATCH 0380/2665] Fix the artifact name of the Node.js environment. It was `scalajs-nodejs-env`, but it should be `scalajs-env-nodejs` to be consistent with `scalajs-env-selenium` which is already public. --- project/Build.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/project/Build.scala b/project/Build.scala index 0ad4c95a9e..036b65c856 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -776,6 +776,7 @@ object Build { fatalWarningsSettings, name := "Scala.js Node.js env", normalizedName := "scalajs-nodejs-env", + moduleName := "scalajs-env-nodejs", libraryDependencies += "com.novocode" % "junit-interface" % "0.9" % "test", previousArtifactSetting From 764c286b20ca217f4fb947ecb5ce90ad44db72e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 26 Jun 2017 14:49:53 +0200 Subject: [PATCH 0381/2665] Version 0.6.18. --- ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index 5895c46b3c..8f762b27b2 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.18-SNAPSHOT" + val current: String = "0.6.18" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" From b54a26c1c2126bedb5b6dd8a450a5e6891e06612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 27 Jun 2017 15:40:28 +0200 Subject: [PATCH 0382/2665] Towards 0.6.19. --- .../scala/org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- project/BinaryIncompatibilities.scala | 11 ----------- project/Build.scala | 2 +- 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index 8f762b27b2..e7169e5ccb 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.18" + val current: String = "0.6.19-SNAPSHOT" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index b0d852aa64..c77318b933 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -6,17 +6,6 @@ object BinaryIncompatibilities { ) val Tools = Seq( - // New method in a trait sealed via self-type, not an issue - ProblemFilters.exclude[ReversedMissingMethodProblem]( - "org.scalajs.core.tools.linker.LinkerPlatformExtensions.applyInternal"), - - // private[optimizer], not an issue - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.core.tools.linker.frontend.optimizer.GenIncOptimizer#MethodContainer.optimizedDefs"), - - // private[emitter], not an issue - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.backend.emitter.FunctionEmitter#JSDesugar.genClassDataOf") ) val JSEnvs = Seq( diff --git a/project/Build.scala b/project/Build.scala index 5ea90b114c..aa160f519a 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -56,7 +56,7 @@ object Build { val shouldPartest = settingKey[Boolean]( "Whether we should partest the current scala version (and fail if we can't)") - val previousVersion = "0.6.17" + val previousVersion = "0.6.18" val previousSJSBinaryVersion = ScalaJSCrossVersion.binaryScalaJSVersion(previousVersion) val previousBinaryCrossVersion = From fc4d12fc584da8096bf20148a62bb286bc42f550 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 28 Jun 2017 17:00:40 +0200 Subject: [PATCH 0383/2665] Fix #3036: Workaround GCC's dce being too enthusiastic. In `NoModule`, sometimes GCC thinks that `$e` is not used and can therefore be dce'ed away ... along with all our exports. We work around that bug by forcing a non-dce'able read of `$e`. This workaround existed in the past. It was first introduced in 6680f72e8167af954d58797d26e943cf3326c4af. It was later removed in d28845a866bca1968658de1556577564cf9b74b3 to fix #2708, as it appeared not to be necessary anymore. However, we later broke what it was solving in d07af7c79b0ecca3498c0fe96c8fc223ad4abdb4. This commit reintroduces the previous workaround, but only in `NoModule` so that we do not recreate #2708. --- tools/scalajsenv.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/scalajsenv.js b/tools/scalajsenv.js index 0e4f582c8f..291a2d4dbe 100644 --- a/tools/scalajsenv.js +++ b/tools/scalajsenv.js @@ -13,6 +13,8 @@ const $e = exports; //!else // TODO Do not use global object detection, and rather export with actual `var` declarations const $e = (typeof global === "object" && global && global["Object"] === Object) ? global : this; +// #3036 - convince GCC that $e must not be dce'ed away +this["__ScalaJSWorkaroundToRetainExportsInGCC"] = $e; //!endif // Linking info - must be in sync with scala.scalajs.runtime.LinkingInfo From f6a69146844ff049eea3a341cbf636042a96be19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 28 Jun 2017 23:27:41 +0200 Subject: [PATCH 0384/2665] Version 1.0.0-M1. --- ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index f7c6b68c58..37dcc46a75 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "1.0.0-SNAPSHOT" + val current: String = "1.0.0-M1" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" From 12d4e64d94d4f0d012e45fa188ad97f474eff830 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 29 Jun 2017 19:08:47 +0200 Subject: [PATCH 0385/2665] Towards 1.0.0 again. --- ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index 37dcc46a75..f7c6b68c58 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "1.0.0-M1" + val current: String = "1.0.0-SNAPSHOT" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" From b890208228b9db6303b400a346bc12a51d07703d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 5 Jul 2017 14:57:29 +0200 Subject: [PATCH 0386/2665] Fix #3038: Setup nodeJSEnv for publishing. * Add `publishSettings` to its settings * List it in `scripts/publish.sh` --- project/Build.scala | 1 + scripts/publish.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/project/Build.scala b/project/Build.scala index 52f82aceb4..0eb2be66b0 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -771,6 +771,7 @@ object Build { lazy val nodeJSEnv: Project = (project in file("nodejs-env")).settings( commonSettings, + publishSettings, fatalWarningsSettings, name := "Scala.js Node.js env", normalizedName := "scalajs-nodejs-env", diff --git a/scripts/publish.sh b/scripts/publish.sh index 209f1501ee..671c81abed 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -14,7 +14,7 @@ CLI_VERSIONS="2.10.6 2.11.11 2.12.2" SBT_VERSION="2.10.6" COMPILER="compiler jUnitPlugin" -LIBS="library ir irJS tools toolsJS jsEnvs jsEnvsTestKit testAdapter stubs testInterface jUnitRuntime" +LIBS="library ir irJS tools toolsJS jsEnvs jsEnvsTestKit nodeJSEnv testAdapter stubs testInterface jUnitRuntime" # Publish compiler for v in $FULL_VERSIONS; do From 63731e0fb68bcfdb5add948fe223784bae66779e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 7 Jul 2017 13:27:34 +0200 Subject: [PATCH 0387/2665] Get rid of the workaround to find export annotations on `accessed`. A long time ago, `@JSExport` used not to have `@field @getter @setter`, and that meant we needed a workaround to go look in `sym.accessed` for annotations if `sym` was an accessor. Now that we break binary compatibility, this is not necessary anymore. Removing the workaround revealed that we had similarly forgot to add the meta-annotations to `@JSExportStatic`, which we also fix here. The two test that are removed were specifically designed to simulate a scenario in which we were loading things compiled by an old version. They are not relevant anymore. --- .../org/scalajs/core/compiler/PrepJSExports.scala | 8 +------- .../scala/scalajs/js/annotation/JSExportStatic.scala | 1 + .../scalajs/testsuite/jsinterop/ExportsTest.scala | 12 ------------ 3 files changed, 2 insertions(+), 19 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala index f304c5246a..7d9df2ffd3 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala @@ -171,14 +171,8 @@ trait PrepJSExports { this: PrepJSInterop => val trgSym = { def isOwnerScalaClass = !sym.owner.isModuleClass && !isJSAny(sym.owner) - /* For accessors, look on the val/var def, if there is one. - * TODO Get rid of this when we can break binary compatibility, as - * @JSExport and @JSExportNamed are now annotated with - * @field @getter @setter - */ - if (sym.isAccessor && sym.accessed != NoSymbol) sym.accessed // For primary Scala class constructors, look on the class itself - else if (sym.isPrimaryConstructor && isOwnerScalaClass) sym.owner + if (sym.isPrimaryConstructor && isOwnerScalaClass) sym.owner else sym } diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSExportStatic.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSExportStatic.scala index f4eabc7429..3a58c44e04 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSExportStatic.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSExportStatic.scala @@ -23,6 +23,7 @@ import scala.annotation.meta._ * * @see [[https://www.scala-js.org/doc/interoperability/sjs-defined-js-classes.html Write JavaScript classes in Scala.js]] */ +@field @getter @setter class JSExportStatic extends scala.annotation.StaticAnnotation { def this(name: String) = this() } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index e87337c4b7..8e8e214afa 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -869,18 +869,6 @@ class ExportsTest { assertEquals(7, bar.y) } - @Test def exporting_constructor_parameter_fields_issue_970_old(): Unit = { - class Foo(@(JSExport @meta.field) val x: Int) - val foo = (new Foo(1)).asInstanceOf[js.Dynamic] - assertEquals(1, foo.x) - } - - @Test def exporting_case_class_fields_issue_970_old(): Unit = { - case class Foo(@(JSExport @meta.field) x: Int) - val foo = (new Foo(1)).asInstanceOf[js.Dynamic] - assertEquals(1, foo.x) - } - @Test def exporting_lazy_values_issue_977(): Unit = { class Foo { @JSExport From 8166dc0ba182eb2523e9c11502d142250d8eaca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 10 Jul 2017 10:51:06 +0200 Subject: [PATCH 0388/2665] Fix #3042: Use phase travel instead of companionModuleClasses. `flatten` breaks the `companionModule` relationship of nested classes. We used to recover it through a map built from the reverse mapping. We now use phase travel instead, which is apparently what the JVM backend does in similar situations. --- .../org/scalajs/core/compiler/GenJSCode.scala | 29 +++++-------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 5c1138a116..3eed6d7428 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -183,14 +183,6 @@ abstract class GenJSCode extends plugins.PluginComponent // Global class generation state ------------------------------------------- - /** Map a class from this compilation unit to its companion module class. - * This should be accessible through `sym.linkedClassOfClass`, but is - * broken for nested classes. The reverse link is not broken, though, - * which allows us to build this map in [[apply]] for the whole - * compilation unit before processing it. - */ - private var companionModuleClasses: Map[Symbol, Symbol] = Map.empty - private val lazilyGeneratedAnonClasses = mutable.Map.empty[Symbol, ClassDef] private val generatedClasses = ListBuffer.empty[(Symbol, Option[String], js.ClassDef)] @@ -257,15 +249,6 @@ abstract class GenJSCode extends plugins.PluginComponent } val allClassDefs = collectClassDefs(cunit.body) - // Build up companionModuleClasses - companionModuleClasses = (for { - classDef <- allClassDefs - sym = classDef.symbol - if sym.isModuleClass - } yield { - patchedLinkedClassOfClass(sym) -> sym - }).toMap - /* There are three types of anonymous classes we want to generate * only once we need them so we can inline them at construction site: * @@ -333,7 +316,6 @@ abstract class GenJSCode extends plugins.PluginComponent } finally { lazilyGeneratedAnonClasses.clear() generatedClasses.clear() - companionModuleClasses = Map.empty pos2irPosCache.clear() } } @@ -533,12 +515,15 @@ abstract class GenJSCode extends plugins.PluginComponent // Static members (exported from the companion object) val staticMembers = { - /* This should be `sym.linkedClassOfClass`, but it does not work for - * classes and objects nested inside objects. + /* Phase travel is necessary for non-top-level classes, because flatten + * breaks their companionModule. This is tracked upstream at + * https://github.com/scala/scala-dev/issues/403 */ - companionModuleClasses.get(sym).fold[List[js.Tree]] { + val companionModuleClass = + exitingPhase(currentRun.picklerPhase)(sym.linkedClassOfClass) + if (companionModuleClass == NoSymbol) { Nil - } { companionModuleClass => + } else { val exports = withScopedVars(currentClassSym := companionModuleClass) { genStaticExports(companionModuleClass) } From 7b24a5f7c5ef5fbe6dbfbd72327cb6913ae488ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 10 Jul 2017 16:58:39 +0200 Subject: [PATCH 0389/2665] Use a fixed structure rather than functions for runtime class name. Arbitrary functions cannot be compared for equality, which means that currently, there is no way to correctly determine whether two instances of `Semantics` are equivalent. This is an issue for caches, which cannot invalidate their outputs if the input `Semantics` have changed. Moreover, the existing `Semantics.runtimeClassName` field was a function from `LinkedClass` to `String`, but `LinkedClass`es are a concept of `linker.standard._` whereas `Semantics` is in `linker._`. We replace the unconstrained `LinkedClass => String` function by an ADT `RuntimeClassNameMapper`. Ultimately, it will only have 3 possibilities, plus an `andThen` combinator: * Keep all class names unchanged * Discard all class names and replace everything by `""` * Regular expression-based replacements In 0.6.x, however, we have a "custom" combinator to keep supporting the deprecated arbitrary `LinkedClass => String`. --- project/BinaryIncompatibilities.scala | 3 + project/Build.scala | 32 ++++- .../testsuite/compiler/ReflectionTest.scala | 11 ++ .../core/tools/test/js/QuickLinker.scala | 25 +++- .../linker/backend/emitter/ClassEmitter.scala | 2 +- .../scalajs/core/tools/sem/Semantics.scala | 133 ++++++++++++++++-- 6 files changed, 184 insertions(+), 22 deletions(-) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index c77318b933..5d9f0f269d 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -6,6 +6,9 @@ object BinaryIncompatibilities { ) val Tools = Seq( + // private, not an issue + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "org.scalajs.core.tools.sem.Semantics.this") ) val JSEnvs = Seq( diff --git a/project/Build.scala b/project/Build.scala index aa160f519a..8a095971ff 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -627,6 +627,12 @@ object Build { base = file("tools/js"), settings = myScalaJSSettings ++ commonToolsSettings ++ Seq( crossVersion := ScalaJSCrossVersion.binary, + + /* We need RuntimeClassNameMapper.custom() in QuickLinker + * TODO Remove this in 1.x. + */ + scalacOptions in Test -= "-Xfatal-warnings", + resourceGenerators in Test += Def.task { val base = (resourceManaged in Compile).value IO.createDirectory(base) @@ -1498,12 +1504,26 @@ object Build { jsDependencies += ProvidedJS / "ScalaJSDefinedTestNatives.js" % "test", skip in packageJSDependencies in Test := false, - scalaJSSemantics ~= (_.withRuntimeClassName(_.fullName match { - case "org.scalajs.testsuite.compiler.ReflectionTest$RenamedTestClass" => - "renamed.test.Class" - case fullName => - fullName - })), + scalaJSSemantics ~= { sems => + import Semantics.RuntimeClassNameMapper + + sems.withRuntimeClassNameMapper( + RuntimeClassNameMapper.custom(_.fullName match { + case "org.scalajs.testsuite.compiler.ReflectionTest$RenamedTestClass" => + "renamed.test.Class" + case fullName => + fullName + }).andThen( + RuntimeClassNameMapper.regexReplace( + raw"""^org\.scalajs\.testsuite\.compiler\.ReflectionTest\$$Prefix""".r, + "renamed.test.byprefix.") + ).andThen( + RuntimeClassNameMapper.regexReplace( + raw"""^org\.scalajs\.testsuite\.compiler\.ReflectionTest\$$OtherPrefix""".r, + "renamed.test.byotherprefix.") + ) + ) + }, javaOptions in Test += "-Dscalajs.scalaVersion=" + scalaVersion.value, diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectionTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectionTest.scala index f85cbee1a2..5a5bf487c9 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectionTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectionTest.scala @@ -44,6 +44,12 @@ class ReflectionTest { @Test def java_lang_Class_getName_renamed_through_semantics(): Unit = { assertEquals("renamed.test.Class", classOf[RenamedTestClass].getName) + assertEquals("renamed.test.byprefix.RenamedTestClass1", + classOf[PrefixRenamedTestClass1].getName) + assertEquals("renamed.test.byprefix.RenamedTestClass2", + classOf[PrefixRenamedTestClass2].getName) + assertEquals("renamed.test.byotherprefix.RenamedTestClass", + classOf[OtherPrefixRenamedTestClass].getName) } @Test def should_support_isInstance(): Unit = { @@ -161,6 +167,11 @@ object ReflectionTest { class RenamedTestClass + class PrefixRenamedTestClass1 + class PrefixRenamedTestClass2 + + class OtherPrefixRenamedTestClass + @JSGlobal("ReflectionTestRawJSClass") @js.native class ReflectionTestRawJSClass extends js.Object diff --git 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 index 78304db3a8..0720215cf8 100644 --- 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 @@ -22,12 +22,25 @@ object QuickLinker { @JSExport def linkTestSuiteNode(irFilesAndJars: js.Array[String], moduleInitializers: js.Array[String]): String = { - val semantics = Semantics.Defaults.withRuntimeClassName(_.fullName match { - case "org.scalajs.testsuite.compiler.ReflectionTest$RenamedTestClass" => - "renamed.test.Class" - case fullName => - fullName - }) + import Semantics.RuntimeClassNameMapper + + val semantics = Semantics.Defaults.withRuntimeClassNameMapper( + RuntimeClassNameMapper.custom(_.fullName match { + case "org.scalajs.testsuite.compiler.ReflectionTest$RenamedTestClass" => + "renamed.test.Class" + case fullName => + fullName + }).andThen( + RuntimeClassNameMapper.regexReplace( + raw"""^org\.scalajs\.testsuite\.compiler\.ReflectionTest\$$Prefix""".r, + "renamed.test.byprefix.") + ).andThen( + RuntimeClassNameMapper.regexReplace( + raw"""^org\.scalajs\.testsuite\.compiler\.ReflectionTest\$$OtherPrefix""".r, + "renamed.test.byotherprefix.") + ) + ) + linkNodeInternal(semantics, irFilesAndJars, moduleInitializers) } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index 4aa324a17b..111ef242d2 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -808,7 +808,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val allParams = List( js.ObjectConstr(List(classIdent -> js.IntLiteral(0))), js.BooleanLiteral(kind == ClassKind.Interface), - js.StringLiteral(semantics.runtimeClassName(tree)), + js.StringLiteral(semantics.runtimeClassNameMapper(tree)), ancestorsRecord, isRawJSTypeParam, parentData, diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/sem/Semantics.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/sem/Semantics.scala index 75de64ff84..96b4a5dfe4 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/sem/Semantics.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/sem/Semantics.scala @@ -21,10 +21,14 @@ final class Semantics private ( val moduleInit: CheckedBehavior, val strictFloats: Boolean, val productionMode: Boolean, - val runtimeClassName: Semantics.RuntimeClassNameFunction) { + val runtimeClassNameMapper: Semantics.RuntimeClassNameMapper) { import Semantics._ + @deprecated("Use runtimeClassNameMapper instead.", "0.6.19") + def runtimeClassName: Semantics.RuntimeClassNameFunction = + runtimeClassNameMapper(_) + def withAsInstanceOfs(behavior: CheckedBehavior): Semantics = copy(asInstanceOfs = behavior) @@ -40,8 +44,14 @@ final class Semantics private ( def withProductionMode(productionMode: Boolean): Semantics = copy(productionMode = productionMode) + def withRuntimeClassNameMapper( + runtimeClassNameMapper: RuntimeClassNameMapper): Semantics = { + copy(runtimeClassNameMapper = runtimeClassNameMapper) + } + + @deprecated("Use withRuntimeClassNameMapper instead.", "0.6.19") def withRuntimeClassName(runtimeClassName: RuntimeClassNameFunction): Semantics = - copy(runtimeClassName = runtimeClassName) + withRuntimeClassNameMapper(RuntimeClassNameMapper.custom(runtimeClassName)) def optimized: Semantics = { copy(asInstanceOfs = this.asInstanceOfs.optimized, @@ -56,7 +66,8 @@ final class Semantics private ( this.arrayIndexOutOfBounds == that.arrayIndexOutOfBounds && this.moduleInit == that.moduleInit && this.strictFloats == that.strictFloats && - this.productionMode == that.productionMode + this.productionMode == that.productionMode && + this.runtimeClassNameMapper == that.runtimeClassNameMapper case _ => false } @@ -68,8 +79,9 @@ final class Semantics private ( acc = mix(acc, arrayIndexOutOfBounds.##) acc = mix(acc, moduleInit.##) acc = mix(acc, strictFloats.##) - acc = mixLast(acc, productionMode.##) - finalizeHash(acc, 5) + acc = mix(acc, productionMode.##) + acc = mixLast(acc, runtimeClassNameMapper.##) + finalizeHash(acc, 6) } override def toString(): String = { @@ -107,14 +119,15 @@ final class Semantics private ( moduleInit: CheckedBehavior = this.moduleInit, strictFloats: Boolean = this.strictFloats, productionMode: Boolean = this.productionMode, - runtimeClassName: RuntimeClassNameFunction = this.runtimeClassName): Semantics = { + runtimeClassNameMapper: RuntimeClassNameMapper = + this.runtimeClassNameMapper): Semantics = { new Semantics( asInstanceOfs = asInstanceOfs, arrayIndexOutOfBounds = arrayIndexOutOfBounds, moduleInit = moduleInit, strictFloats = strictFloats, productionMode = productionMode, - runtimeClassName = runtimeClassName) + runtimeClassNameMapper = runtimeClassNameMapper) } } @@ -122,6 +135,108 @@ object Semantics { private val HashSeed = scala.util.hashing.MurmurHash3.stringHash(classOf[Semantics].getName) + sealed abstract class RuntimeClassNameMapper { + import RuntimeClassNameMapper._ + + def andThen(that: RuntimeClassNameMapper): RuntimeClassNameMapper = { + require(!that.isInstanceOf[Custom], + "RuntimeClassNameMapper.custom(...) is not a valid argument to " + + "RuntimeClassNameMapper#andThen(), because it takes a LinkedClass " + + "as input instead of a String.") + AndThen(this, that) + } + + private[tools] def apply(linkedClass: LinkedClass): String = { + def rec(mapper: RuntimeClassNameMapper, className: String): String = { + mapper match { + case KeepAll => + className + case DiscardAll => + "" + case mapper @ RegexReplace(_, _, replacement) => + mapper.compiledPattern.matcher(className).replaceAll(replacement) + case AndThen(first, second) => + rec(second, rec(first, className)) + case Custom(mapper) => + /* Discards `className`, but that's fine because we cannot + * construct an AndThen(_, Custom()). + */ + mapper(linkedClass) + } + } + + rec(this, linkedClass.fullName) + } + } + + object RuntimeClassNameMapper { + private case object KeepAll extends RuntimeClassNameMapper + + private case object DiscardAll extends RuntimeClassNameMapper + + /* We use `pattern` and `flags` in the case parameters, rather than the + * `j.u.regex.Pattern`, because the latter does not have meaningful + * equality. + */ + private case class RegexReplace(pattern: String, flags: Int, + replacement: String)( + val compiledPattern: java.util.regex.Pattern) + extends RuntimeClassNameMapper + + private case class AndThen(first: RuntimeClassNameMapper, + second: RuntimeClassNameMapper) + extends RuntimeClassNameMapper + + /** For compatibility with `RuntimeClassNameFunction`s only. */ + private case class Custom(mapper: LinkedClass => String) + extends RuntimeClassNameMapper { + /* For compatibility of `Semantics.==` of previous versions, we need to + * consider all `Custom` instances as being equal, even though this + * definitely breaks the case class contract. + * Since this is deprecated, this issue will eventually go away. + */ + + override def equals(that: Any): Boolean = that.isInstanceOf[Custom] + + override def hashCode(): Int = 369581025 // generated at random + } + + def keepAll(): RuntimeClassNameMapper = KeepAll + + def discardAll(): RuntimeClassNameMapper = DiscardAll + + /** Returns a mapper that performs regular expression-based replacements. + * + * Given an input class name `className`, the mapper will return a new + * class name equivalent to + * {{{ + * pattern.matcher(className).replaceAll(replacement) + * }}} + */ + def regexReplace(pattern: java.util.regex.Pattern, + replacement: String): RuntimeClassNameMapper = { + RegexReplace(pattern.pattern(), pattern.flags(), replacement)(pattern) + } + + /** Returns a mapper that performs regular expression-based replacements. + * + * Given an input class name `className`, the mapper will return a new + * class name equivalent to + * {{{ + * regex.replaceAllIn(className, replacement) + * }}} + */ + def regexReplace(regex: scala.util.matching.Regex, + replacement: String): RuntimeClassNameMapper = { + regexReplace(regex.pattern, replacement) + } + + @deprecated("Will be removed in Scala.js 1.x.", "0.6.19") + def custom(mapper: LinkedClass => String): RuntimeClassNameMapper = + Custom(mapper) + } + + @deprecated("Use RuntimeClassNameMapper instead.", "0.6.19") type RuntimeClassNameFunction = LinkedClass => String val Defaults: Semantics = new Semantics( @@ -130,7 +245,7 @@ object Semantics { moduleInit = Unchecked, strictFloats = false, productionMode = false, - runtimeClassName = _.fullName) + runtimeClassNameMapper = RuntimeClassNameMapper.keepAll()) def compliantTo(semantics: Traversable[String]): Semantics = { import Defaults._ @@ -147,6 +262,6 @@ object Semantics { moduleInit = sw("moduleInit", Compliant, moduleInit), strictFloats = sw("strictFloats", true, strictFloats), productionMode = false, - runtimeClassName = Defaults.runtimeClassName) + runtimeClassNameMapper = RuntimeClassNameMapper.keepAll()) } } From 5cb66c361af3d96da95bcc12163683c7f7981489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 10 Jul 2017 14:49:21 +0200 Subject: [PATCH 0390/2665] Fix #3047: Refuse to compile overloads collapsing through @JSName. This is potentially a source breaking change, as it may be that a codebase happened to compile to something that worked. However, it is binary compatible. --- .../scalajs/core/compiler/GenJSExports.scala | 45 +++++--- .../compiler/test/ScalaJSDefinedTest.scala | 101 ++++++++++++++++++ 2 files changed, 133 insertions(+), 13 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index 667b77df53..291f6f0d89 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -323,14 +323,8 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } private def genJSClassDispatcher(classSym: Symbol, name: JSName): js.Tree = { - var alts: List[Symbol] = Nil - for { - sym <- classSym.info.members - if !sym.isBridge && jsNameOf(sym) == name - } { - val tpe = sym.tpe - if (!alts.exists(alt => tpe.matches(alt.tpe))) - alts ::= sym + val alts = classSym.info.members.toList.filter { sym => + !sym.isBridge && jsNameOf(sym) == name } assert(!alts.isEmpty, @@ -559,12 +553,9 @@ trait GenJSExports extends SubComponent { self: GenJSCode => // 2. The optional argument count restriction has triggered // 3. We only have (more than once) repeated parameters left // Therefore, we should fail - reporter.error(pos, - s"""Cannot disambiguate overloads for exported method ${alts.head.name} with types - | ${alts.map(_.typeInfo).mkString("\n ")}""".stripMargin) + reportCannotDisambiguateError(alts) js.Undefined() } else { - val altsByTypeTest = groupByWithoutHashCode(alts) { case ExportedSymbol(alt) => typeTestForTpe(computeExportArgType(alt, paramIndex)) @@ -627,6 +618,29 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } } + private def reportCannotDisambiguateError(alts: List[Exported]): Unit = { + val currentClass = currentClassSym.get + + // Find a position that is in the current class for decent error reporting + val pos = alts.collectFirst { + case ExportedSymbol(sym) if sym.owner == currentClass => sym.pos + case alt: ExportedBody => alt.pos + }.getOrElse { + currentClass.pos + } + + val kind = + if (isScalaJSDefinedJSClass(currentClass)) "method" + else "exported method" + + val name = alts.head.name + val altsTypesInfo = alts.map(_.typeInfo).mkString("\n ") + + reporter.error(pos, + s"Cannot disambiguate overloads for $kind $name with types\n" + + s" $altsTypesInfo") + } + private def computeExportArgType(alt: Symbol, paramIndex: Int): Type = { // See the comment in genPrimitiveJSArgs for a rationale about this enteringPhase(currentRun.uncurryPhase) { @@ -878,9 +892,14 @@ trait GenJSExports extends SubComponent { self: GenJSCode => private case class ExportedSymbol(sym: Symbol) extends Exported { def pos: Position = sym.pos def params: List[Type] = sym.tpe.params.map(_.tpe) + def genBody(minArgc: Int, hasRestParam: Boolean, static: Boolean): js.Tree = genApplyForSym(minArgc, hasRestParam, sym, static) - def name: String = sym.name.toString + + def name: String = + if (isScalaJSDefinedJSClass(sym.owner)) jsNameOf(sym).displayName + else sym.name.toString + def typeInfo: String = sym.tpe.toString def hasRepeatedParam: Boolean = GenJSExports.this.hasRepeatedParam(sym) } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala index 20d73829fb..513ea8b873 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala @@ -142,6 +142,107 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { """ } + @Test + def noCollapseOverloadsOnJSName: Unit = { + """ + @ScalaJSDefined + class A extends js.Object { + @JSName("bar") + def foo(): Int = 42 + + def bar(): Int = 24 + } + """ hasErrors + """ + |newSource1.scala:10: error: Cannot disambiguate overloads for method bar with types + | ()Int + | ()Int + | def bar(): Int = 24 + | ^ + """ + + """ + @ScalaJSDefined + class A extends js.Object { + def bar(): Int = 24 + + @JSName("bar") + def foo(): Int = 42 + } + """ hasErrors + """ + |newSource1.scala:10: error: Cannot disambiguate overloads for method bar with types + | ()Int + | ()Int + | def foo(): Int = 42 + | ^ + """ + + """ + @ScalaJSDefined + class A extends js.Object { + @JSName("bar") + def foo(): Int = 42 + } + + @ScalaJSDefined + class B extends A { + def bar(): Int = 24 + } + """ hasErrors + """ + |newSource1.scala:13: error: Cannot disambiguate overloads for method bar with types + | ()Int + | ()Int + | def bar(): Int = 24 + | ^ + """ + + """ + @js.native + @JSGlobal + class A extends js.Object { + @JSName("bar") + def foo(): Int = js.native + } + + @ScalaJSDefined + class B extends A { + def bar(): Int = 24 + } + """ hasErrors + """ + |newSource1.scala:14: error: Cannot disambiguate overloads for method bar with types + | ()Int + | ()Int + | def bar(): Int = 24 + | ^ + """ + + """ + @js.native + @JSGlobal + class Foo extends js.Object { + def foo(x: Int): Int = js.native + + @JSName("foo") + def bar(x: Int): Int = js.native + } + + @ScalaJSDefined + class Bar extends Foo { + def foo(): Int = 42 + } + """ hasErrors + """ + |newSource1.scala:15: error: Cannot disambiguate overloads for method bar with types + | (x: Int)Int + | (x: Int)Int + | class Bar extends Foo { + | ^ + """ + } + @Test def noOverloadedPrivate: Unit = { """ From e5597ee5a09ffe52fc20de557ea09f8f5daba220 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 11 Jul 2017 15:27:49 +0200 Subject: [PATCH 0391/2665] Fix #3051: Initialize fields of anon JS classes to the zero of their type. They were erroneously always initialized to `null`, unlike in equivalent named JS classes. --- .../src/main/scala/org/scalajs/core/compiler/GenJSCode.scala | 2 +- .../org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 3eed6d7428..df97156e2e 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -655,7 +655,7 @@ abstract class GenJSCode extends plugins.PluginComponent case lit: js.StringLiteral => js.JSBracketSelect(selfRef, lit) case js.ComputedName(tree, _) => js.JSBracketSelect(selfRef, tree) } - js.Assign(select, jstpe.zeroOf(fdef.tpe)) + js.Assign(select, jstpe.zeroOf(fdef.ftpe)) case mdef: js.MethodDef => implicit val pos = mdef.pos diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala index 3cbb58169a..6d45523ce9 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala @@ -383,9 +383,11 @@ class ScalaJSDefinedTest { @Test def anonymous_class_uninitialized_fields(): Unit = { val obj = new js.Object { var x: String = _ + var y: Int = _ } assertNull(obj.asInstanceOf[js.Dynamic].x) + assertEquals(0, obj.asInstanceOf[js.Dynamic].y) } @Test def anonymous_class_field_init_order(): Unit = { From 8881c24a0847424945bd3803ac5e6aebbab5234b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 11 Jul 2017 15:32:06 +0200 Subject: [PATCH 0392/2665] Fix #3050: Detect export name conflict for `@JSExportTopLevel object`. We now use a `map` instead of a `collect` to make sure that a missing case crashes hard instead of being ignored. --- .../scalajs/core/tools/linker/LinkedClass.scala | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala index 592aa41505..d7541755a9 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala @@ -62,15 +62,18 @@ final class LinkedClass( def isExported: Boolean = classExports.nonEmpty /** Names this class / module is exported under */ - def topLevelExportNames: List[String] = classExports.collect { - case ConstructorExportDef(name, _, _) => name - case ModuleExportDef(name) => name - case JSClassExportDef(name) => name + def topLevelExportNames: List[String] = classExports.map { export => + (export: @unchecked) match { + case ConstructorExportDef(name, _, _) => name + case ModuleExportDef(name) => name + case TopLevelModuleExportDef(name) => name + case JSClassExportDef(name) => name - case TopLevelMethodExportDef(MethodDef(_, StringLiteral(name), _, _, _)) => - name + case TopLevelMethodExportDef(MethodDef(_, StringLiteral(name), _, _, _)) => + name - case TopLevelFieldExportDef(name, _) => name + case TopLevelFieldExportDef(name, _) => name + } } def fullName: String = Definitions.decodeClassName(encodedName) From 1518b704802ea95c3521831d91610905f022ca25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 14 Jul 2017 15:54:37 +0200 Subject: [PATCH 0393/2665] Fix #3058: Use the proper type for the "thisLocalVar" of tailrec. In Scala 2.12, if a tail-recursive method is in a class or trait with a self-type, the type of the `_$this` local variable is the self type. We previously assumed it was always the current class type, which produced invalid IR in that case. --- .../org/scalajs/core/compiler/GenJSCode.scala | 24 +++++++------ .../testsuite/compiler/RegressionTest.scala | 36 +++++++++++++++++++ 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 3eed6d7428..b35c5d173e 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -136,7 +136,7 @@ abstract class GenJSCode extends plugins.PluginComponent // Per method body private val currentMethodSym = new ScopedVar[Symbol] - private val thisLocalVarIdent = new ScopedVar[Option[js.Ident]] + private val thisLocalVarInfo = new ScopedVar[Option[(js.Ident, jstpe.Type)]] private val fakeTailJumpParamRepl = new ScopedVar[(Symbol, Symbol)] private val enclosingLabelDefParams = new ScopedVar[Map[Symbol, List[Symbol]]] private val isModuleInitialized = new ScopedVar[VarBox[Boolean]] @@ -168,7 +168,7 @@ abstract class GenJSCode extends plugins.PluginComponent unexpectedMutatedFields := mutable.Set.empty, generatedSAMWrapperCount := null, currentMethodSym := null, - thisLocalVarIdent := null, + thisLocalVarInfo := null, fakeTailJumpParamRepl := null, enclosingLabelDefParams := null, isModuleInitialized := null, @@ -1397,7 +1397,7 @@ abstract class GenJSCode extends plugins.PluginComponent withScopedVars( currentMethodSym := sym, - thisLocalVarIdent := None, + thisLocalVarInfo := None, fakeTailJumpParamRepl := (NoSymbol, NoSymbol), enclosingLabelDefParams := Map.empty, isModuleInitialized := new VarBox(false), @@ -1661,13 +1661,15 @@ abstract class GenJSCode extends plugins.PluginComponent mutableLocalVars += thisSym val thisLocalIdent = encodeLocalSym(thisSym) + val thisLocalType = toIRType(thisSym.tpe) + val genRhs = genExpr(initialThis) val thisLocalVarDef = js.VarDef(thisLocalIdent, - currentClassType, thisSym.isMutable, genRhs) + thisLocalType, thisSym.isMutable, genRhs) val innerBody = { withScopedVars( - thisLocalVarIdent := Some(thisLocalIdent) + thisLocalVarInfo := Some((thisLocalIdent, thisLocalType)) ) { genInnerBody() } @@ -1687,10 +1689,11 @@ abstract class GenJSCode extends plugins.PluginComponent } else { assert(!static, tree.pos) + val thisLocalIdent = freshLocalIdent("this") withScopedVars( - thisLocalVarIdent := Some(freshLocalIdent("this")) + thisLocalVarInfo := Some((thisLocalIdent, jstpe.AnyType)) ) { - val thisParamDef = js.ParamDef(thisLocalVarIdent.get.get, + val thisParamDef = js.ParamDef(thisLocalIdent, jstpe.AnyType, mutable = false, rest = false) js.MethodDef(static = true, methodName, thisParamDef :: jsParams, @@ -1959,14 +1962,15 @@ abstract class GenJSCode extends plugins.PluginComponent * is one. */ private def genThis()(implicit pos: Position): js.Tree = { - thisLocalVarIdent.fold[js.Tree] { + thisLocalVarInfo.fold[js.Tree] { if (tryingToGenMethodAsJSFunction) { throw new CancelGenMethodAsJSFunction( "Trying to generate `this` inside the body") } js.This()(currentClassType) - } { thisLocalIdent => - js.VarRef(thisLocalIdent)(currentClassType) + } { case (thisLocalVarIdent, thisLocalVarTpe) => + // .copy() to get the correct position + js.VarRef(thisLocalVarIdent.copy())(thisLocalVarTpe) } } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala index 1f8713596d..36a22e1446 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala @@ -603,6 +603,42 @@ class RegressionTest { assertEquals("B", c.t3) } + @Test def tailrec_in_trait_with_self_type_scala_2_12_issue_3058(): Unit = { + trait Parent { this: Child => + @tailrec final def bar(i: Int, acc: Int): Int = { + println(s"bar($i, $acc)") + if (i <= count) + bar(i + 1, acc + i) + else + acc + } + } + + class Child extends Parent { + def count: Int = 5 + } + + assertEquals(15, new Child().bar(1, 0)) + } + + @Test def tailrec_in_class_with_self_type_scala_2_12_issue_3058(): Unit = { + class Parent { this: Child => + @tailrec final def bar(i: Int, acc: Int): Int = { + println(s"bar($i, $acc)") + if (i <= count) + bar(i + 1, acc + i) + else + acc + } + } + + class Child extends Parent { + def count: Int = 5 + } + + assertEquals(15, new Child().bar(1, 0)) + } + } object RegressionTest { From 3442701679ea5b29f9d2aabb3cc84af8dc8a7221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 12 Jul 2017 16:25:12 +0200 Subject: [PATCH 0394/2665] Fix #3054: Allow rest parameters in `Closure`s in the IR. It turns out that most of the linker was already perfectly happy with rest parameters in `Closure`s. In particular, the emitter is unchanged. It was mostly just the IR checker which was overzealous. The optimizer did make a silent assumption that there was no rest parameters in `Closure`s when inlining them, so we make sure that it does not attempt to inline such `Closure`s. --- .../jsinterop/ScalaJSDefinedTest.scala | 65 +++++++++++++++++++ .../core/tools/linker/checker/IRChecker.scala | 9 ++- .../frontend/optimizer/OptimizerCore.scala | 50 ++++++++------ 3 files changed, 103 insertions(+), 21 deletions(-) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala index 6d45523ce9..4d49e27c71 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala @@ -742,6 +742,26 @@ class ScalaJSDefinedTest { assertEquals(6, dyn.foo(3)) } + @Test def simple_overloaded_methods_anon_js_class_issue_3054(): Unit = { + @ScalaJSDefined + trait SimpleOverloadedMethodsAnonJSClass extends js.Object { + def foo(): Int + def foo(x: Int): Int + } + + val foo = new SimpleOverloadedMethodsAnonJSClass { + def foo(): Int = 42 + def foo(x: Int): Int = x * 2 + } + assertEquals(42, foo.foo()) + assertEquals(6, foo.foo(3)) + + val dyn = foo.asInstanceOf[js.Dynamic] + assertEquals(js.typeOf(dyn.foo), "function") + assertEquals(42, dyn.foo()) + assertEquals(6, dyn.foo(3)) + } + @Test def renamed_overloaded_methods(): Unit = { @ScalaJSDefined class RenamedOverloadedMethods extends js.Object { @@ -761,6 +781,51 @@ class ScalaJSDefinedTest { assertEquals(6, dyn.foobar(3)) } + @Test def overloaded_methods_with_varargs(): Unit = { + @ScalaJSDefined + class OverloadedMethodsWithVarargs extends js.Object { + def foo(x: Int): Int = x * 2 + def foo(strs: String*): Int = strs.foldLeft(0)(_ + _.length) + } + + val foo = new OverloadedMethodsWithVarargs + assertEquals(42, foo.foo(21)) + assertEquals(0, foo.foo()) + assertEquals(3, foo.foo("bar")) + assertEquals(8, foo.foo("bar", "babar")) + + val dyn = foo.asInstanceOf[js.Dynamic] + assertEquals(js.typeOf(dyn.foo), "function") + assertEquals(42, dyn.foo(21)) + assertEquals(0, dyn.foo()) + assertEquals(3, dyn.foo("bar")) + assertEquals(8, dyn.foo("bar", "babar")) + } + + @Test def overloaded_methods_with_varargs_anon_js_class_issue_3054(): Unit = { + @ScalaJSDefined + trait OverloadedMethodsWithVarargsAnonJSClass extends js.Object { + def foo(x: Int): Int + def foo(strs: String*): Int + } + + val foo = new OverloadedMethodsWithVarargsAnonJSClass { + def foo(x: Int): Int = x * 2 + def foo(strs: String*): Int = strs.foldLeft(0)(_ + _.length) + } + assertEquals(42, foo.foo(21)) + assertEquals(0, foo.foo()) + assertEquals(3, foo.foo("bar")) + assertEquals(8, foo.foo("bar", "babar")) + + val dyn = foo.asInstanceOf[js.Dynamic] + assertEquals(js.typeOf(dyn.foo), "function") + assertEquals(42, dyn.foo(21)) + assertEquals(0, dyn.foo()) + assertEquals(3, dyn.foo("bar")) + assertEquals(8, dyn.foo("bar", "babar")) + } + @Test def overloaded_constructors_num_parameters_resolution(): Unit = { assertEquals(1, new OverloadedConstructorParamNumber(1).foo) assertEquals(3, new OverloadedConstructorParamNumber(1, 2).foo) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 95a848ce0b..a3b430e6e5 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -1013,8 +1013,13 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { reportError(s"Parameter $name has type NoType") else if (ptpe != AnyType) reportError(s"Closure parameter $name has type $ptpe instead of any") - if (rest) - reportError(s"Closure parameter $name cannot be a rest parameter") + } + + if (params.nonEmpty) { + for (ParamDef(name, _, _, rest) <- params.init) { + if (rest) + reportError(s"Non-last rest parameter $name is illegal") + } } val bodyEnv = Env.fromSignature( diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index b777a1191e..8d35cce7da 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -903,31 +903,43 @@ private[optimizer] abstract class OptimizerCore( case Closure(captureParams, params, body, captureValues) => pretransformExprs(captureValues) { tcaptureValues => - tryOrRollback { cancelFun => - val captureBindings = for { - (ParamDef(Ident(name, origName), tpe, mutable, rest), value) <- - captureParams zip tcaptureValues - } yield { - assert(!rest, s"Found a rest capture parameter at $pos") - Binding(name, origName, tpe, mutable, value) - } - withNewLocalDefs(captureBindings) { (captureLocalDefs, cont1) => - val replacement = TentativeClosureReplacement( - captureParams, params, body, captureLocalDefs, - alreadyUsed = newSimpleState(false), cancelFun) - val localDef = LocalDef( - RefinedType(AnyType, isExact = false, isNullable = false), - mutable = false, - replacement) - cont1(localDef.toPreTransform) - } (cont) - } { () => + def default(): TailRec[Tree] = { val newClosure = transformClosureCommon(captureParams, params, body, tcaptureValues.map(finishTransformExpr)) cont(PreTransTree( newClosure, RefinedType(AnyType, isExact = false, isNullable = false))) } + + if (params.exists(_.rest)) { + /* TentativeClosureReplacement assumes there are no rest + * parameters, because that would not be inlineable anyway. + * So we never try to inline a Closure with a rest parameter. + */ + default() + } else { + tryOrRollback { cancelFun => + val captureBindings = for { + (ParamDef(Ident(name, origName), tpe, mutable, rest), value) <- + captureParams zip tcaptureValues + } yield { + assert(!rest, s"Found a rest capture parameter at $pos") + Binding(name, origName, tpe, mutable, value) + } + withNewLocalDefs(captureBindings) { (captureLocalDefs, cont1) => + val replacement = TentativeClosureReplacement( + captureParams, params, body, captureLocalDefs, + alreadyUsed = newSimpleState(false), cancelFun) + val localDef = LocalDef( + RefinedType(AnyType, isExact = false, isNullable = false), + mutable = false, + replacement) + cont1(localDef.toPreTransform) + } (cont) + } { () => + default() + } + } } case _ => From ec1489927e47a2e4701bea68fbf21052aefc59ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 15 Jul 2017 15:40:40 +0200 Subject: [PATCH 0395/2665] Fix #3055: Correct codegen for super in anonymous JS classes. In a named JS class, super method calls (resp. super property accesses) are translated to `JSSuperBracketCall` (resp. `JSSuperBracketSelect`). These IR nodes receive as first parameter a reference to enclosing class, so that they can tell in which prototype they have to start the lookup. This translation is not valid in anonymous JS classes, because the enclosing class becomes an `AbstractJSType` rather than a `JSClass`. Instead, we now eagerly desugar the nodes in the compiler back-end. This strategy is consistent with how anonymous JS classes are otherwise translated: they are purely a compiler back-end concept, and require no support from the IR. To translate super property accesses (reads and writes), we need run-time helpers, which we add in `scala.scalajs.runtime`. Their code is unfortunately duplicated with similar helpers used by the emitter to translate `JSSuperBracketSelect`s. --- .../org/scalajs/core/compiler/GenJSCode.scala | 47 +++++++++++++++--- .../scalajs/core/compiler/JSDefinitions.scala | 2 + .../scala/scala/scalajs/runtime/package.scala | 49 +++++++++++++++++++ .../jsinterop/ScalaJSDefinedTest.scala | 38 ++++++++++++++ 4 files changed, 129 insertions(+), 7 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index df97156e2e..7a0286c468 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -4261,20 +4261,53 @@ abstract class GenJSCode extends plugins.PluginComponent } } - def genSelectGet(propName: js.Tree): js.Tree = - genSuperReference(propName) + def genSelectGet(propName: js.Tree): js.Tree = { + if (superIn.exists(isScalaJSDefinedAnonJSClass(_))) { + // #3055 + genApplyMethod( + genLoadModule(RuntimePackageModule), + Runtime_jsObjectSuperGet, + List(receiver, propName)) + } else { + genSuperReference(propName) + } + } - def genSelectSet(propName: js.Tree, value: js.Tree): js.Tree = - js.Assign(genSuperReference(propName), value) + def genSelectSet(propName: js.Tree, value: js.Tree): js.Tree = { + if (superIn.exists(isScalaJSDefinedAnonJSClass(_))) { + // #3055 + genApplyMethod( + genLoadModule(RuntimePackageModule), + Runtime_jsObjectSuperSet, + List(receiver, propName, value)) + } else { + js.Assign(genSuperReference(propName), value) + } + } def genCall(methodName: js.Tree, args: List[js.Tree]): js.Tree = { superIn.fold[js.Tree] { js.JSBracketMethodApply( receiver, methodName, args) } { superInSym => - js.JSSuperBracketCall( - jstpe.ClassType(encodeClassFullName(superInSym)), - receiver, methodName, args) + if (isScalaJSDefinedAnonJSClass(superInSym)) { + // #3055 + val superClassType = + jstpe.ClassType(encodeClassFullName(superInSym.superClass)) + val superProto = js.JSBracketSelect( + js.LoadJSConstructor(superClassType), + js.StringLiteral("prototype")) + val superMethod = + js.JSBracketSelect(superProto, methodName) + js.JSBracketMethodApply( + superMethod, + js.StringLiteral("call"), + receiver :: args) + } else { + js.JSSuperBracketCall( + jstpe.ClassType(encodeClassFullName(superInSym)), + receiver, methodName, args) + } } } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 27ece4d962..f3e237a76f 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -124,6 +124,8 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val RuntimePackageModule = getPackageObject("scala.scalajs.runtime") lazy val Runtime_wrapJavaScriptException = getMemberMethod(RuntimePackageModule, newTermName("wrapJavaScriptException")) lazy val Runtime_unwrapJavaScriptException = getMemberMethod(RuntimePackageModule, newTermName("unwrapJavaScriptException")) + lazy val Runtime_jsObjectSuperGet = getMemberMethod(RuntimePackageModule, newTermName("jsObjectSuperGet")) + lazy val Runtime_jsObjectSuperSet = getMemberMethod(RuntimePackageModule, newTermName("jsObjectSuperSet")) lazy val Runtime_genTraversableOnce2jsArray = getMemberMethod(RuntimePackageModule, newTermName("genTraversableOnce2jsArray")) lazy val Runtime_jsTupleArray2jsObject = getMemberMethod(RuntimePackageModule, newTermName("jsTupleArray2jsObject")) lazy val Runtime_constructorOf = getMemberMethod(RuntimePackageModule, newTermName("constructorOf")) diff --git a/library/src/main/scala/scala/scalajs/runtime/package.scala b/library/src/main/scala/scala/scalajs/runtime/package.scala index 3a4be2a54f..64e530ade7 100644 --- a/library/src/main/scala/scala/scalajs/runtime/package.scala +++ b/library/src/main/scala/scala/scalajs/runtime/package.scala @@ -31,6 +31,55 @@ package object runtime { result } + private final def resolveSuperRef(self: Any, + propName: Any): js.Dynamic = { + // !!! Duplicate code with the $resolveSuperRef helper + // scalastyle:off return + val getPrototypeOf = js.constructorOf[js.Object].getPrototypeOf + val getOwnPropertyDescriptor = js.constructorOf[js.Object].getOwnPropertyDescriptor + + var superProto = getPrototypeOf(self.asInstanceOf[js.Any]) + while (superProto != null) { + val desc = getOwnPropertyDescriptor(superProto, propName.asInstanceOf[js.Any]) + if (!js.isUndefined(desc)) + return desc + superProto = getPrototypeOf(superProto) + } + + js.undefined.asInstanceOf[js.Dynamic] + // scalastyle:on return + } + + final def jsObjectSuperGet(self: Any, propName: Any): Any = { + // !!! Duplicate code with the $superGet helper + val desc = resolveSuperRef(self, propName) + if (!js.isUndefined(desc)) { + val getter = desc.get + if (!js.isUndefined(getter)) + getter.call(self.asInstanceOf[js.Any]) + else + desc.value + } else { + js.undefined + } + } + + final def jsObjectSuperSet(self: Any, propName: Any, value: Any): Unit = { + // !!! Duplicate code with the $superSet helper + // scalastyle:off return + val desc = resolveSuperRef(self, propName) + if (!js.isUndefined(desc)) { + val setter = desc.set + if (!js.isUndefined(setter)) { + setter.call(self.asInstanceOf[js.Any], value.asInstanceOf[js.Any]) + return + } + } + throw js.JavaScriptException( + new js.TypeError("super has no setter '" + propName + "'.")) + // scalastyle:on return + } + @inline final def genTraversableOnce2jsArray[A]( col: GenTraversableOnce[A]): js.Array[A] = { col match { diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala index 6d45523ce9..43e0ecc93d 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala @@ -1167,6 +1167,19 @@ class ScalaJSDefinedTest { assertEquals("bar3hello", dyn.foo("hello")) } + @Test def super_method_call_in_anon_JS_class_issue_3055(): Unit = { + @ScalaJSDefined + class Foo extends js.Object { + def bar(msg: String): String = "super: " + msg + } + + val foo = new Foo { + override def bar(msg: String): String = super.bar("foo: " + msg) + } + + assertEquals("super: foo: foobar", foo.bar("foobar")) + } + @Test def override_native_val(): Unit = { @ScalaJSDefined class OverrideNativeVal extends NativeParentClass(3) { @@ -1331,6 +1344,31 @@ class ScalaJSDefinedTest { assertEquals(18, dyn.x) } + @Test def super_property_get_set_in_anon_JS_class_issue_3055(): Unit = { + @ScalaJSDefined + class Foo extends js.Object { + var x: Int = 1 + var lastSetValue: Int = 0 + + def bar: Int = x + def bar_=(v: Int): Unit = x = v + } + + val foo = new Foo { + override def bar: Int = super.bar * 2 + override def bar_=(v: Int): Unit = { + lastSetValue = v + super.bar = v + 3 + } + } + + assertEquals(2, foo.bar) + foo.bar = 6 + assertEquals(6, foo.lastSetValue) + assertEquals(9, foo.x) + assertEquals(18, foo.bar) + } + @Test def add_setter_in_subclass(): Unit = { @ScalaJSDefined class AddSetterInSubclassParent extends js.Object { From d8fc6f02f6d5e3e1e3d0572c80690fe96998b3fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 14 Jul 2017 18:12:26 +0200 Subject: [PATCH 0396/2665] Fix #3060: Do not check field existence for classes with no instances. If a class has no instances, the `BaseLinker` will trim it down and remove all its fields. However, it is still possible that there is some reachable code that reads or writes those fields (although such code would inevitably crash with an NPE if actually executed). The IR checker must not complain in such cases. We also add a test for a `Select` on a class that is not even "needed at all". This worked before, but we had no explicit test for that scenario. --- project/BinaryIncompatibilities.scala | 6 ++- .../testsuite/compiler/RegressionTest.scala | 45 +++++++++++++++++++ .../core/tools/linker/checker/IRChecker.scala | 37 +++++++++++---- 3 files changed, 79 insertions(+), 9 deletions(-) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 5d9f0f269d..000ec620fe 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -8,7 +8,11 @@ object BinaryIncompatibilities { val Tools = Seq( // private, not an issue ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.tools.sem.Semantics.this") + "org.scalajs.core.tools.sem.Semantics.this"), + + // private, not an issue + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.checker.IRChecker#CheckedClass.this") ) val JSEnvs = Seq( diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala index 36a22e1446..fe81abd4ed 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala @@ -258,6 +258,51 @@ class RegressionTest { assertThrows(classOf[Exception], (giveMeANothing(): scala.runtime.IntRef).elem) } + @Test def IR_checker_must_not_check_field_existence_on_non_existent_classes(): Unit = { + // In this test, Outer is not "needed at all" + + class Outer(x: Int) { + class Inner { + def get(): Int = x + } + } + + def test(outer: Outer): Int = { + if (outer == null) { + 3 + } else { + val inner = new outer.Inner + inner.get() + } + } + + assertEquals(3, test(null)) + } + + @Test def IR_checker_must_not_check_field_existence_on_classes_with_no_instance_issue_3060(): Unit = { + // In this test, Outer is "needed at all", but does not have any instance + + class Outer(x: Int) { + class Inner { + def get(): Int = x + } + } + + def test(outer: Outer): Int = { + if (outer == null) { + 3 + } else { + val inner = new outer.Inner + inner.get() + } + } + + // make sure Outer is "needed at all" + assertFalse(classOf[Outer].isInterface) + + assertEquals(3, test(null)) + } + @Test def should_properly_order_ctor_statements_when_inlining_issue_1369(): Unit = { trait Bar { def x: Int diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index a3b430e6e5..429360c974 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -760,13 +760,32 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { if (!kind.isClass) { reportError(s"Cannot select $item of non-class $cls") } else { - maybeClass.foreach { - _.lookupField(item).fold[Unit] { - reportError(s"Class $cls does not have a field $item") - } { fieldDef => - if (fieldDef.tpe != tree.tpe) - reportError(s"Select $cls.$item of type "+ - s"${fieldDef.tpe} typed as ${tree.tpe}") + /* Actually checking the field is done only if + * + * * the class exists, and + * * it has instances (including instances of subclasses). + * + * The latter test is necessary because the BaseLinker can + * completely get rid of all the fields of a class that has no + * instance. Obviously in such cases, the only value that + * `qualifier` can assume is `null`, and the `Select` will fail + * with an NPE. But the IR is still valid per se. + * + * The former case is necessary too because, if the class is not + * even "needed at all", the BaseLinker will simply remove the + * class entirely. + * + * See #3060. + */ + maybeClass.foreach { c => + if (c.hasInstances) { + c.lookupField(item).fold[Unit] { + reportError(s"Class $cls does not have a field $item") + } { fieldDef => + if (fieldDef.tpe != tree.tpe) + reportError(s"Select $cls.$item of type "+ + s"${fieldDef.tpe} typed as ${tree.tpe}") + } } } } @@ -1119,7 +1138,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { classes.getOrElseUpdate(className, { reportError(s"Cannot find class $className") new CheckedClass(className, ClassKind.Class, - Some(ObjectClass), Set(ObjectClass), None, Nil) + Some(ObjectClass), Set(ObjectClass), hasInstances = true, None, Nil) }) } @@ -1206,6 +1225,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { val kind: ClassKind, val superClassName: Option[String], val ancestors: Set[String], + val hasInstances: Boolean, val jsNativeLoadSpec: Option[JSNativeLoadSpec], _fields: TraversableOnce[CheckedField])( implicit ctx: ErrorContext) { @@ -1219,6 +1239,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { this(classDef.name.name, classDef.kind, classDef.superClass.map(_.name), classDef.ancestors.toSet, + classDef.hasInstances, classDef.jsNativeLoadSpec, if (classDef.kind.isJSClass) Nil else classDef.fields.map(CheckedClass.checkedField)) From acf053f0dce02c13e1d8c4cc2fbe82ba33f08798 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 7 Jul 2017 11:55:47 +0200 Subject: [PATCH 0397/2665] Remove dead code `LinkedClass.apply`. --- .../core/tools/linker/LinkedClass.scala | 83 ------------------- 1 file changed, 83 deletions(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala index af07bba4d5..d0902ff560 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala @@ -133,86 +133,3 @@ final class LinkedClass( version) } } - -object LinkedClass { - - def apply(info: Infos.ClassInfo, classDef: ClassDef, - ancestors: List[String]): LinkedClass = { - - val memberInfoByName = Map(info.methods.map(m => m.encodedName -> m): _*) - - val fields = mutable.Buffer.empty[FieldDef] - val staticMethods = mutable.Buffer.empty[LinkedMember[MethodDef]] - val memberMethods = mutable.Buffer.empty[LinkedMember[MethodDef]] - val abstractMethods = mutable.Buffer.empty[LinkedMember[MethodDef]] - val exportedMembers = mutable.Buffer.empty[LinkedMember[Tree]] - val classExports = mutable.Buffer.empty[Tree] - - def linkedMethod(m: MethodDef) = { - val info = memberInfoByName(m.name.encodedName) - new LinkedMember(info, m, None) - } - - def linkedProperty(p: PropertyDef) = { - val info = memberInfoByName(p.name.encodedName) - new LinkedMember(info, p, None) - } - - classDef.defs.foreach { - // Static methods - case m: MethodDef if m.static => - staticMethods += linkedMethod(m) - - // Fields - case field @ FieldDef(_, _, _, _) => - fields += field - - // Normal methods - case m: MethodDef if m.name.isInstanceOf[Ident] => - if (m.body.isDefined) - memberMethods += linkedMethod(m) - else - abstractMethods += linkedMethod(m) - - case m: MethodDef if m.name.isInstanceOf[StringLiteral] => - exportedMembers += linkedMethod(m) - - case m: PropertyDef => - exportedMembers += linkedProperty(m) - - case e: ConstructorExportDef => - classExports += e - - case e: ModuleExportDef => - classExports += e - - case tree => - throw new IllegalArgumentException( - s"Illegal tree in ClassDef of class ${tree.getClass}") - } - - val classExportInfo = memberInfoByName.get(Definitions.ClassExportsName) - - new LinkedClass( - classDef.name, - classDef.kind, - classDef.superClass, - classDef.interfaces, - classDef.jsNativeLoadSpec, - fields.toList, - staticMethods.toList, - memberMethods.toList, - abstractMethods.toList, - exportedMembers.toList, - classExports.toList, - classExportInfo, - classDef.optimizerHints, - classDef.pos, - ancestors, - hasInstances = true, - hasInstanceTests = true, - hasRuntimeTypeInfo = true, - version = None) - } - -} From 2e39b5a42075d27a757f0cfd38db7354710ab503 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 7 Jul 2017 11:59:16 +0200 Subject: [PATCH 0398/2665] Rename "class exports" to "top-level exports". The concept of class exports dates back when only classes and modules could be exported at the top-level. Now we also have methods and fields exported at the top-level, so "class exports" is not fully representative anymore. --- .../org/scalajs/core/compiler/GenJSCode.scala | 6 ++-- .../org/scalajs/core/ir/Definitions.scala | 12 ++------ .../scala/org/scalajs/core/ir/Infos.scala | 29 ++++--------------- .../core/tools/linker/LinkedClass.scala | 20 ++++++------- .../linker/backend/emitter/ClassEmitter.scala | 6 ++-- .../linker/backend/emitter/Emitter.scala | 16 +++++----- .../core/tools/linker/checker/IRChecker.scala | 12 ++++---- .../tools/linker/frontend/BaseLinker.scala | 22 +++++++------- 8 files changed, 49 insertions(+), 74 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index c72619b3d9..7be5355f17 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -533,8 +533,8 @@ abstract class GenJSCode extends plugins.PluginComponent } } - // Generate class-level exporters - val classExports = + // Generate top-level exporters + val topLevelExports = if (isStaticModule(sym)) genModuleAccessorExports(sym) else genJSClassExports(sym) @@ -545,7 +545,7 @@ abstract class GenJSCode extends plugins.PluginComponent genJSClassDispatchers(sym, dispatchMethodNames.result().distinct) ::: generatedMethods.toList ::: staticMembers ::: - classExports + topLevelExports } // Hashed definitions of the class diff --git a/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala b/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala index 617bb7b5fc..b84ebb7d7b 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala @@ -69,16 +69,8 @@ object Definitions { /** Name of the static initializer method. */ final val StaticInitializerName = "clinit___" - /** Name used for infos of class exports - * - * These currently are exported constructors and top level exports) - * - * TODO give this a better name once we can break backwards compat. - */ - val ClassExportsName = "__exportedInits" - - @deprecated("Use ClassExportsName instead", "0.6.14") - def ExportedConstructorsName: String = "__exportedInits" + /** Name used for infos of top-level exports. */ + val TopLevelExportsName = "__topLevelExports" /** Encodes a class name. */ def encodeClassName(fullName: String): String = { diff --git a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala index 2b8689b961..98615db3cf 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala @@ -327,7 +327,7 @@ object Infos { if (exportedConstructors.nonEmpty || topLevelMethodExports.nonEmpty || topLevelFieldExports.nonEmpty) { - builder.addMethod(generateClassExportsInfo(classDef.name.name, + builder.addMethod(generateTopLevelExportsInfo(classDef.name.name, exportedConstructors, topLevelMethodExports, topLevelFieldExports)) } @@ -342,29 +342,12 @@ object Infos { def generatePropertyInfo(propertyDef: PropertyDef): MethodInfo = new GenInfoTraverser().generatePropertyInfo(propertyDef) - /** Generates the [[MethodInfo]] of a list of [[Trees.ConstructorExportDef]]s. */ - @deprecated("Use generateClassExportsInfo instead", "0.6.14") - def generateExportedConstructorsInfo( - constructorDefs: List[ConstructorExportDef]): MethodInfo = { - generateClassExportsInfo(constructorDefs, Nil) - } - - /** Generates the [[MethodInfo]] for the class exports. */ - @deprecated( - "Use the overload with an enclosingClass and topLevelFieldExports.", - "0.6.15") - def generateClassExportsInfo(constructorDefs: List[ConstructorExportDef], - topLevelMethodExports: List[TopLevelMethodExportDef]): MethodInfo = { - // enclosingClass won't be used when topLevelFieldExports is empty - generateClassExportsInfo("", constructorDefs, topLevelMethodExports, Nil) - } - - /** Generates the [[MethodInfo]] for the class exports. */ - def generateClassExportsInfo(enclosingClass: String, + /** Generates the [[MethodInfo]] for the top-level exports. */ + def generateTopLevelExportsInfo(enclosingClass: String, constructorDefs: List[ConstructorExportDef], topLevelMethodExports: List[TopLevelMethodExportDef], topLevelFieldExports: List[TopLevelFieldExportDef]): MethodInfo = { - new GenInfoTraverser().generateClassExportsInfo(enclosingClass, + new GenInfoTraverser().generateTopLevelExportsInfo(enclosingClass, constructorDefs, topLevelMethodExports, topLevelFieldExports) } @@ -409,12 +392,12 @@ object Infos { builder.result() } - def generateClassExportsInfo(enclosingClass: String, + def generateTopLevelExportsInfo(enclosingClass: String, constructorDefs: List[ConstructorExportDef], topLevelMethodExports: List[TopLevelMethodExportDef], topLevelFieldExports: List[TopLevelFieldExportDef]): MethodInfo = { builder - .setEncodedName(ClassExportsName) + .setEncodedName(TopLevelExportsName) .setIsExported(true) for (constructorDef <- constructorDefs) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala index d0902ff560..280ab65fc5 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala @@ -45,8 +45,8 @@ final class LinkedClass( val memberMethods: List[LinkedMember[MethodDef]], val abstractMethods: List[LinkedMember[MethodDef]], val exportedMembers: List[LinkedMember[Tree]], - val classExports: List[Tree], - val classExportInfo: Option[Infos.MethodInfo], + val topLevelExports: List[Tree], + val topLevelExportsInfo: Option[Infos.MethodInfo], val optimizerHints: OptimizerHints, val pos: Position, @@ -59,10 +59,10 @@ final class LinkedClass( // Helpers to give Info-Like access def encodedName: String = name.name - def isExported: Boolean = classExports.nonEmpty + def isExported: Boolean = topLevelExports.nonEmpty - /** Names this class / module is exported under */ - def topLevelExportNames: List[String] = classExports.map { export => + /** Names of all top-level exports in this class. */ + def topLevelExportNames: List[String] = topLevelExports.map { export => (export: @unchecked) match { case ConstructorExportDef(name, _, _) => name case ModuleExportDef(name) => name @@ -84,7 +84,7 @@ final class LinkedClass( memberMethods.map(_.info) ++ abstractMethods.map(_.info) ++ exportedMembers.map(_.info) ++ - classExportInfo + topLevelExportsInfo ) Infos.ClassInfo(encodedName, isExported, kind, superClass.map(_.name), @@ -102,8 +102,8 @@ final class LinkedClass( memberMethods: List[LinkedMember[MethodDef]] = this.memberMethods, abstractMethods: List[LinkedMember[MethodDef]] = this.abstractMethods, exportedMembers: List[LinkedMember[Tree]] = this.exportedMembers, - classExports: List[Tree] = this.classExports, - classExportInfo: Option[Infos.MethodInfo] = this.classExportInfo, + topLevelExports: List[Tree] = this.topLevelExports, + topLevelExportsInfo: Option[Infos.MethodInfo] = this.topLevelExportsInfo, optimizerHints: OptimizerHints = this.optimizerHints, pos: Position = this.pos, ancestors: List[String] = this.ancestors, @@ -122,8 +122,8 @@ final class LinkedClass( memberMethods, abstractMethods, exportedMembers, - classExports, - classExportInfo, + topLevelExports, + topLevelExportsInfo, optimizerHints, pos, ancestors, diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index cf816dad38..4eada26ebe 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -935,9 +935,9 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { yield js.Block(exports)(tree.pos) } - def genClassExports(tree: LinkedClass)( + def genTopLevelExports(tree: LinkedClass)( implicit globalKnowledge: GlobalKnowledge): WithGlobals[List[js.Tree]] = { - val exportsWithGlobals = tree.classExports map { + val exportsWithGlobals = tree.topLevelExports map { case e: ConstructorExportDef => genConstructorExportDef(tree, e) case e: JSClassExportDef => @@ -952,7 +952,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { WithGlobals(genTopLevelFieldExportDef(tree, e)) case tree => throw new AssertionError( - "Illegal class export " + tree.getClass.getName) + "Illegal top-level export " + tree.getClass.getName) } WithGlobals.list(exportsWithGlobals) diff --git 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 index 5f30f67aa2..30e8e6cd6c 100644 --- 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 @@ -177,7 +177,7 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, emitJSTrees(generatedClass.staticInitialization) for (generatedClass <- generatedClasses) - emitJSTrees(generatedClass.classExports) + emitJSTrees(generatedClass.topLevelExports) // Emit the module initializers @@ -411,13 +411,13 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, classEmitter.genStaticInitialization(linkedClass) } - // Class exports + // Top-level exports - val classExports = if (linkedClass.classExports.isEmpty) { + val topLevelExports = if (linkedClass.topLevelExports.isEmpty) { Nil } else { - val treeWithGlobals = classTreeCache.classExports.getOrElseUpdate( - classEmitter.genClassExports(linkedClass)(classCache)) + val treeWithGlobals = classTreeCache.topLevelExports.getOrElseUpdate( + classEmitter.genTopLevelExports(linkedClass)(classCache)) addGlobalRefs(treeWithGlobals.globalVarNames) treeWithGlobals.value } @@ -428,7 +428,7 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, main.reverse, staticFields, staticInitialization, - classExports, + topLevelExports, mentionedDangerousGlobalRefs ) } @@ -564,14 +564,14 @@ private object Emitter { val setTypeData = new OneTimeCache[js.Tree] val moduleAccessor = new OneTimeCache[js.Tree] val staticFields = new OneTimeCache[List[js.Tree]] - val classExports = new OneTimeCache[WithGlobals[List[js.Tree]]] + val topLevelExports = new OneTimeCache[WithGlobals[List[js.Tree]]] } private final class GeneratedClass( val main: List[js.Tree], val staticFields: List[js.Tree], val staticInitialization: List[js.Tree], - val classExports: List[js.Tree], + val topLevelExports: List[js.Tree], val mentionedDangerousGlobalRefs: Set[String] ) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 48e5d94c27..8541d336c2 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -68,7 +68,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { classDef.memberMethods.nonEmpty || classDef.abstractMethods.nonEmpty || classDef.exportedMembers.nonEmpty || - classDef.classExports.nonEmpty) { + classDef.topLevelExports.nonEmpty) { reportError(s"Raw JS type ${classDef.name} cannot "+ "have instance members") } @@ -156,8 +156,8 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { } } - // Check classExports - for (tree <- classDef.classExports) { + // Check top-level exports + for (tree <- classDef.topLevelExports) { implicit val ctx = ErrorContext(tree) tree match { @@ -187,7 +187,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { // Anything else is illegal case _ => - reportError("Illegal class export of type " + + reportError("Illegal top-level export of type " + tree.getClass.getName) } } @@ -201,7 +201,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { if (classDef.fields.nonEmpty) reportError(s"$kindStr may not have fields") - if (classDef.exportedMembers.nonEmpty || classDef.classExports.nonEmpty) + if (classDef.exportedMembers.nonEmpty || classDef.topLevelExports.nonEmpty) reportError(s"$kindStr may not have exports") } @@ -441,7 +441,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { throw new AssertionError("Exported method may not have Ident as name") case StringLiteral(name) => - if (name.contains("__") && name != Definitions.ClassExportsName) + if (name.contains("__") && name != Definitions.TopLevelExportsName) reportError("Exported method def name cannot contain __") case ComputedName(tree, _) => diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index 8bd75426e5..24d3401c7b 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -172,7 +172,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, val memberMethods = mutable.Buffer.empty[LinkedMember[MethodDef]] val abstractMethods = mutable.Buffer.empty[LinkedMember[MethodDef]] val exportedMembers = mutable.Buffer.empty[LinkedMember[Tree]] - val classExports = mutable.Buffer.empty[Tree] + val topLevelExports = mutable.Buffer.empty[Tree] def linkedMethod(m: MethodDef) = { val info = memberInfoByStaticAndName((m.static, m.name.encodedName)) @@ -224,22 +224,22 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, exportedMembers += linkedProperty(m) case e: ConstructorExportDef => - classExports += e + topLevelExports += e case e: JSClassExportDef => - classExports += e + topLevelExports += e case e: ModuleExportDef => - classExports += e + topLevelExports += e case e: TopLevelModuleExportDef => - classExports += e + topLevelExports += e case e: TopLevelMethodExportDef => - classExports += e + topLevelExports += e case e: TopLevelFieldExportDef => - classExports += e + topLevelExports += e case tree => throw new IllegalArgumentException( @@ -267,8 +267,8 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, } } - val classExportInfo = - memberInfoByStaticAndName.get((false, Definitions.ClassExportsName)) + val topLevelExportInfo = + memberInfoByStaticAndName.get((false, Definitions.TopLevelExportsName)) val kind = if (analyzerInfo.isModuleAccessed) classDef.kind @@ -287,8 +287,8 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, memberMethods.toList, abstractMethods.toList, exportedMembers.toList, - classExports.toList, - classExportInfo, + topLevelExports.toList, + topLevelExportInfo, classDef.optimizerHints, classDef.pos, ancestors.toList, From b78536ee8c130ba4142a1a4f12e303c23a00e554 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 7 Jul 2017 13:49:27 +0200 Subject: [PATCH 0399/2665] Always mix the `rest` flag of a `ParamDef` in `Hashers`. It was not always mixed for binary compatibility reasons. --- ir/src/main/scala/org/scalajs/core/ir/Hashers.scala | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala index 24a104de5a..3ef3131805 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala @@ -101,13 +101,7 @@ object Hashers { mixIdent(ident) mixType(ptpe) mixBoolean(mutable) - /* TODO Remove this test in the next major release. - * In 0.6.x we need this test so that the hash of a non-rest ParamDef - * emitted in 0.6.3 format is the same as an (implicitly non-rest) - * ParamDef emitted in 0.6.0 format. - */ - if (rest) - mixBoolean(rest) + mixBoolean(rest) case Skip() => mixTag(TagSkip) From 16a7923775e655634e3979de29e240857c336db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 7 Jul 2017 13:52:11 +0200 Subject: [PATCH 0400/2665] Remove a workaround for deserialization hacks in `Analyzer`. --- .../scalajs/core/tools/linker/analyzer/Analyzer.scala | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala index 090c2d069f..34c0bb5b7c 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala @@ -573,15 +573,7 @@ private final class Analyzer(semantics: Semantics, def instantiated()(implicit from: From): Unit = { instantiatedFrom ::= from - /* TODO Get rid of this when we break binary compatibility. - * Due to the deserialization hacks for the 0.6.8 binary format, we - * might reach this point with `kind == ClassKind.AbstractJSType`, where - * in fact the ClassDef has `kind == ClassKind.NativeJSClass`. If an - * AbstractJSType is `instantiated()` here, we have to assume it is in - * fact a NativeJSClass. - */ - val isNativeJSClass = - kind == ClassKind.NativeJSClass || kind == ClassKind.AbstractJSType + val isNativeJSClass = kind == ClassKind.NativeJSClass /* TODO? When the second line is false, shouldn't this be a linking error * instead? From 1c20facac71b451fc554d28b59b1be1719061889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 7 Jul 2017 14:07:28 +0200 Subject: [PATCH 0401/2665] Reorganize the tags for tree serialization. The order now matches the order of definitions of `Tree` case classes. --- .../main/scala/org/scalajs/core/ir/Tags.scala | 52 +++++++++---------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala index f52b580db4..1a527f45e1 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala @@ -28,8 +28,9 @@ private[ir] object Tags { final val TagIf = TagReturn + 1 final val TagWhile = TagIf + 1 final val TagDoWhile = TagWhile + 1 - - final val TagThrow = TagDoWhile + 1 + final val TagTryCatch = TagDoWhile + 1 + final val TagTryFinally = TagTryCatch + 1 + final val TagThrow = TagTryFinally + 1 final val TagContinue = TagThrow + 1 final val TagMatch = TagContinue + 1 final val TagDebugger = TagMatch + 1 @@ -38,7 +39,8 @@ private[ir] object Tags { final val TagLoadModule = TagNew + 1 final val TagStoreModule = TagLoadModule + 1 final val TagSelect = TagStoreModule + 1 - final val TagApply = TagSelect + 1 + final val TagSelectStatic = TagSelect + 1 + final val TagApply = TagSelectStatic + 1 final val TagApplyStatically = TagApply + 1 final val TagApplyStatic = TagApplyStatically + 1 final val TagUnaryOp = TagApplyStatic + 1 @@ -60,15 +62,21 @@ private[ir] object Tags { final val TagJSFunctionApply = TagJSBracketSelect + 1 final val TagJSDotMethodApply = TagJSFunctionApply + 1 final val TagJSBracketMethodApply = TagJSDotMethodApply + 1 - final val TagJSDelete = TagJSBracketMethodApply + 1 + final val TagJSSuperBracketSelect = TagJSBracketMethodApply + 1 + final val TagJSSuperBracketCall = TagJSSuperBracketSelect + 1 + final val TagJSSuperConstructorCall = TagJSSuperBracketCall + 1 + final val TagLoadJSConstructor = TagJSSuperConstructorCall + 1 + final val TagLoadJSModule = TagLoadJSConstructor + 1 + final val TagJSSpread = TagLoadJSModule + 1 + final val TagJSDelete = TagJSSpread + 1 final val TagJSUnaryOp = TagJSDelete + 1 final val TagJSBinaryOp = TagJSUnaryOp + 1 final val TagJSArrayConstr = TagJSBinaryOp + 1 final val TagJSObjectConstr = TagJSArrayConstr + 1 + final val TagJSLinkingInfo = TagJSObjectConstr + 1 - final val TagUndefined = TagJSObjectConstr + 1 - final val TagUndefinedParam = TagUndefined + 1 // TODO Move this - final val TagNull = TagUndefinedParam + 1 + final val TagUndefined = TagJSLinkingInfo + 1 + final val TagNull = TagUndefined + 1 final val TagBooleanLiteral = TagNull + 1 final val TagIntLiteral = TagBooleanLiteral + 1 final val TagLongLiteral = TagIntLiteral + 1 @@ -77,33 +85,23 @@ private[ir] object Tags { final val TagStringLiteral = TagDoubleLiteral + 1 final val TagClassOf = TagStringLiteral + 1 - final val TagVarRef = TagClassOf + 1 + final val TagUndefinedParam = TagClassOf + 1 + + final val TagVarRef = TagUndefinedParam + 1 final val TagThis = TagVarRef + 1 - final val TagClosure = TagThis + 1 + final val TagJSGlobalRef = TagThis + 1 + final val TagClosure = TagJSGlobalRef + 1 final val TagClassDef = TagClosure + 1 final val TagFieldDef = TagClassDef + 1 final val TagMethodDef = TagFieldDef + 1 final val TagPropertyDef = TagMethodDef + 1 final val TagConstructorExportDef = TagPropertyDef + 1 - final val TagModuleExportDef = TagConstructorExportDef + 1 - - // TODO Reorganize these when we can break binary compatibility - final val TagJSSpread = TagModuleExportDef + 1 - final val TagJSLinkingInfo = TagJSSpread + 1 - final val TagJSSuperBracketSelect = TagJSLinkingInfo + 1 - final val TagJSSuperBracketCall = TagJSSuperBracketSelect + 1 - final val TagJSSuperConstructorCall = TagJSSuperBracketCall + 1 - final val TagLoadJSConstructor = TagJSSuperConstructorCall + 1 - final val TagLoadJSModule = TagLoadJSConstructor + 1 - final val TagJSClassExportDef = TagLoadJSModule + 1 - final val TagTryCatch = TagJSClassExportDef + 1 - final val TagTryFinally = TagTryCatch + 1 - final val TagTopLevelMethodExportDef = TagTryFinally + 1 - final val TagSelectStatic = TagTopLevelMethodExportDef + 1 - final val TagTopLevelFieldExportDef = TagSelectStatic + 1 - final val TagTopLevelModuleExportDef = TagTopLevelFieldExportDef + 1 - final val TagJSGlobalRef = TagTopLevelModuleExportDef + 1 + final val TagJSClassExportDef = TagConstructorExportDef + 1 + final val TagModuleExportDef = TagJSClassExportDef + 1 + final val TagTopLevelModuleExportDef = TagModuleExportDef + 1 + final val TagTopLevelMethodExportDef = TagTopLevelModuleExportDef + 1 + final val TagTopLevelFieldExportDef = TagTopLevelMethodExportDef + 1 // Tags for Types From fd9d4aa90588d5b7ca82722013ece369ef14aa5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 7 Jul 2017 15:54:08 +0200 Subject: [PATCH 0402/2665] Move `JSGlobalRef` together with other JS interop IR nodes. This is purely a cosmetic change. --- .../main/scala/org/scalajs/core/ir/Hashers.scala | 8 ++++---- .../scala/org/scalajs/core/ir/Printers.scala | 8 ++++---- .../scala/org/scalajs/core/ir/Serializers.scala | 16 ++++++++-------- ir/src/main/scala/org/scalajs/core/ir/Tags.scala | 6 +++--- .../main/scala/org/scalajs/core/ir/Trees.scala | 10 +++++----- .../scala/org/scalajs/core/ir/PrintersTest.scala | 8 ++++---- .../linker/backend/emitter/FunctionEmitter.scala | 6 +++--- .../core/tools/linker/checker/IRChecker.scala | 4 ++-- .../frontend/optimizer/OptimizerCore.scala | 4 ++-- 9 files changed, 35 insertions(+), 35 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala index 3ef3131805..8c862f5ed9 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala @@ -376,6 +376,10 @@ object Hashers { mixTree(value) } + case JSGlobalRef(ident) => + mixTag(TagJSGlobalRef) + mixIdent(ident) + case JSLinkingInfo() => mixTag(TagJSLinkingInfo) @@ -426,10 +430,6 @@ object Hashers { mixTag(TagThis) mixType(tree.tpe) - case JSGlobalRef(ident) => - mixTag(TagJSGlobalRef) - mixIdent(ident) - case Closure(captureParams, params, body, captureValues) => mixTag(TagClosure) mixTrees(captureParams) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index 0c51b868af..520fcaf0e0 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -669,6 +669,10 @@ object Printers { } undent; println(); print('}') + case JSGlobalRef(ident) => + print("global:") + print(ident) + case JSLinkingInfo() => print("") @@ -747,10 +751,6 @@ object Printers { case This() => print("this") - case JSGlobalRef(ident) => - print("global:") - print(ident) - case Closure(captureParams, params, body, captureValues) => print("(lambda<") var first = true diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index d6ab7e38f2..b6b56c9217 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -339,6 +339,10 @@ object Serializers { writePropertyName(field._1); writeTree(field._2) } + case JSGlobalRef(ident) => + writeByte(TagJSGlobalRef) + writeIdent(ident) + case JSLinkingInfo() => writeByte(TagJSLinkingInfo) @@ -389,10 +393,6 @@ object Serializers { writeByte(TagThis) writeType(tree.tpe) - case JSGlobalRef(ident) => - writeByte(TagJSGlobalRef) - writeIdent(ident) - case Closure(captureParams, params, body, captureValues) => writeByte(TagClosure) writeTrees(captureParams) @@ -759,6 +759,7 @@ object Serializers { case TagJSArrayConstr => JSArrayConstr(readTrees()) case TagJSObjectConstr => JSObjectConstr(List.fill(readInt())((readPropertyName(), readTree()))) + case TagJSGlobalRef => JSGlobalRef(readIdent()) case TagJSLinkingInfo => JSLinkingInfo() case TagUndefined => Undefined() @@ -772,10 +773,9 @@ object Serializers { case TagClassOf => ClassOf(readReferenceType()) case TagUndefinedParam => UndefinedParam()(readType()) - case TagVarRef => VarRef(readIdent())(readType()) - case TagThis => This()(readType()) - case TagJSGlobalRef => JSGlobalRef(readIdent()) - case TagClosure => Closure(readParamDefs(), readParamDefs(), readTree(), readTrees()) + case TagVarRef => VarRef(readIdent())(readType()) + case TagThis => This()(readType()) + case TagClosure => Closure(readParamDefs(), readParamDefs(), readTree(), readTrees()) case TagClassDef => val name = readIdent() diff --git a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala index 1a527f45e1..6060cc4e18 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala @@ -73,7 +73,8 @@ private[ir] object Tags { final val TagJSBinaryOp = TagJSUnaryOp + 1 final val TagJSArrayConstr = TagJSBinaryOp + 1 final val TagJSObjectConstr = TagJSArrayConstr + 1 - final val TagJSLinkingInfo = TagJSObjectConstr + 1 + final val TagJSGlobalRef = TagJSObjectConstr + 1 + final val TagJSLinkingInfo = TagJSGlobalRef + 1 final val TagUndefined = TagJSLinkingInfo + 1 final val TagNull = TagUndefined + 1 @@ -89,8 +90,7 @@ private[ir] object Tags { final val TagVarRef = TagUndefinedParam + 1 final val TagThis = TagVarRef + 1 - final val TagJSGlobalRef = TagThis + 1 - final val TagClosure = TagJSGlobalRef + 1 + final val TagClosure = TagThis + 1 final val TagClassDef = TagClosure + 1 final val TagFieldDef = TagClassDef + 1 diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 1369ac4573..98dc13ea9e 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -713,6 +713,11 @@ object Trees { val tpe = AnyType } + case class JSGlobalRef(ident: Ident)( + implicit val pos: Position) extends Tree { + val tpe = AnyType + } + case class JSLinkingInfo()(implicit val pos: Position) extends Tree { val tpe = AnyType } @@ -778,11 +783,6 @@ object Trees { case class This()(val tpe: Type)(implicit val pos: Position) extends Tree - case class JSGlobalRef(ident: Ident)( - implicit val pos: Position) extends Tree { - val tpe = AnyType - } - /** Closure with explicit captures. * The n captures map to the n first formal arguments. */ diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala index 292a8862a5..766bc5671e 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala @@ -679,6 +679,10 @@ class PrintersTest { JSObjectConstr(List(Ident("f") -> i(5), StringLiteral("g") -> i(6)))) } + @Test def printGlobalRef(): Unit = { + assertPrintEquals("global:Foo", JSGlobalRef("Foo")) + } + @Test def printJSLinkingInfo(): Unit = { assertPrintEquals("", JSLinkingInfo()) } @@ -753,10 +757,6 @@ class PrintersTest { assertPrintEquals("this", This()(AnyType)) } - @Test def printGlobalRef(): Unit = { - assertPrintEquals("global:Foo", JSGlobalRef("Foo")) - } - @Test def printClosure(): Unit = { assertPrintEquals( """ diff --git 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 index 941a728305..5f1fc0ce19 100644 --- 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 @@ -2182,6 +2182,9 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { (transformPropertyName(name), transformExpr(value)) }) + case JSGlobalRef(name) => + js.VarRef(transformGlobalVarIdent(name)) + case JSLinkingInfo() => envField("linkingInfo") @@ -2218,9 +2221,6 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { js.VarRef(ident) } - case JSGlobalRef(name) => - js.VarRef(transformGlobalVarIdent(name)) - case Closure(captureParams, params, body, captureValues) => val innerFunction = desugarToFunctionInternal(params, body, isStat = false, diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 8541d336c2..88d4f8f22c 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -977,6 +977,8 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { for ((_, value) <- fields) typecheckExpr(value, env) + case JSGlobalRef(_) => + case JSLinkingInfo() => // Literals @@ -998,8 +1000,6 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { if (!isSubtype(env.thisTpe, tree.tpe)) reportError(s"this of type ${env.thisTpe} typed as ${tree.tpe}") - case JSGlobalRef(_) => - case Closure(captureParams, params, body, captureValues) => /* Check compliance of captureValues wrt. captureParams in the current * method state, i.e., outside `withPerMethodState`. diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index 15a076cc3d..dfa688a40e 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -657,8 +657,8 @@ private[optimizer] abstract class OptimizerCore( // Trees that need not be transformed case _:Skip | _:Debugger | _:LoadModule | _:SelectStatic | - _:LoadJSConstructor | _:LoadJSModule | _:JSLinkingInfo | _:Literal | - _:JSGlobalRef => + _:LoadJSConstructor | _:LoadJSModule | _:JSLinkingInfo | _:JSGlobalRef | + _:Literal => tree case _ => From c578ebc0d738b736afc1a13987fe8cccb2af0328 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 9 Jul 2017 17:09:24 +0200 Subject: [PATCH 0403/2665] Remove the IR node `ModuleExportDef`. It used to be generated for `@JSExport` on module classes, but that is not legal anymore. Only `@JSExportTopLevel` is allowed, and that produces a `TopLevelModuleExportDef`. --- .../scalajs/core/compiler/GenJSExports.scala | 3 ++- .../scala/org/scalajs/core/ir/Infos.scala | 2 +- .../scala/org/scalajs/core/ir/Printers.scala | 5 ---- .../org/scalajs/core/ir/Serializers.scala | 5 ---- .../main/scala/org/scalajs/core/ir/Tags.scala | 3 +-- .../org/scalajs/core/ir/Transformers.scala | 4 +-- .../org/scalajs/core/ir/Traversers.scala | 2 +- .../scala/org/scalajs/core/ir/Trees.scala | 17 ++---------- .../org/scalajs/core/ir/PrintersTest.scala | 6 ----- .../core/tools/linker/LinkedClass.scala | 1 - .../linker/backend/emitter/ClassEmitter.scala | 26 +++---------------- .../core/tools/linker/checker/IRChecker.scala | 11 -------- .../tools/linker/frontend/BaseLinker.scala | 3 --- 13 files changed, 12 insertions(+), 76 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index f491848988..fbd1ac0652 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -113,7 +113,8 @@ trait GenJSExports extends SubComponent { self: GenJSCode => exp.destination match { case ExportDestination.Normal => - js.ModuleExportDef(exp.jsName) + throw new AssertionError( + "Found a non-top-level module export for " + classSym.fullName) case ExportDestination.TopLevel => js.TopLevelModuleExportDef(exp.jsName) case ExportDestination.Static => diff --git a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala index 98615db3cf..baae54fc19 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala @@ -314,7 +314,7 @@ object Infos { case constructorDef: ConstructorExportDef => builder.setIsExported(true) exportedConstructors ::= constructorDef - case _:JSClassExportDef | _:ModuleExportDef | _:TopLevelModuleExportDef => + case _:JSClassExportDef | _:TopLevelModuleExportDef => builder.setIsExported(true) case topLevelMethodExport: TopLevelMethodExportDef => builder.setIsExported(true) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index 520fcaf0e0..3173943a89 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -866,11 +866,6 @@ object Printers { printEscapeJS(fullName, out) print('\"') - case ModuleExportDef(fullName) => - print("export module \"") - printEscapeJS(fullName, out) - print('\"') - case TopLevelModuleExportDef(fullName) => print("export top module \"") printEscapeJS(fullName, out) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index b6b56c9217..678fa4dc93 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -457,10 +457,6 @@ object Serializers { writeByte(TagJSClassExportDef) writeString(fullName) - case ModuleExportDef(fullName) => - writeByte(TagModuleExportDef) - writeString(fullName) - case TopLevelModuleExportDef(fullName) => writeByte(TagTopLevelModuleExportDef) writeString(fullName) @@ -816,7 +812,6 @@ object Serializers { ConstructorExportDef(readString(), readParamDefs(), readTree()) case TagJSClassExportDef => JSClassExportDef(readString()) - case TagModuleExportDef => ModuleExportDef(readString()) case TagTopLevelModuleExportDef => TopLevelModuleExportDef(readString()) case TagTopLevelMethodExportDef => TopLevelMethodExportDef(readTree().asInstanceOf[MethodDef]) case TagTopLevelFieldExportDef => TopLevelFieldExportDef(readString(), readIdent()) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala index 6060cc4e18..01e5953eef 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala @@ -98,8 +98,7 @@ private[ir] object Tags { final val TagPropertyDef = TagMethodDef + 1 final val TagConstructorExportDef = TagPropertyDef + 1 final val TagJSClassExportDef = TagConstructorExportDef + 1 - final val TagModuleExportDef = TagJSClassExportDef + 1 - final val TagTopLevelModuleExportDef = TagModuleExportDef + 1 + final val TagTopLevelModuleExportDef = TagJSClassExportDef + 1 final val TagTopLevelMethodExportDef = TagTopLevelModuleExportDef + 1 final val TagTopLevelFieldExportDef = TagTopLevelMethodExportDef + 1 diff --git a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala index 6fb14aa6b2..220a904b0a 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala @@ -237,8 +237,8 @@ object Transformers { case ConstructorExportDef(fullName, args, body) => ConstructorExportDef(fullName, args, transformStat(body)) - case _:JSClassExportDef | _:ModuleExportDef | - _:TopLevelModuleExportDef | _:TopLevelFieldExportDef => + case _:JSClassExportDef | _:TopLevelModuleExportDef | + _:TopLevelFieldExportDef => tree case TopLevelMethodExportDef(methodDef) => diff --git a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala index 5a7d36781e..f1d23c523c 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala @@ -219,7 +219,7 @@ object Traversers { case _:Skip | _:Continue | _:Debugger | _:LoadModule | _:SelectStatic | _:LoadJSConstructor | _:LoadJSModule | _:JSLinkingInfo | _:Literal | _:UndefinedParam | _:VarRef | _:This | _:JSGlobalRef | _:FieldDef | - _:JSClassExportDef | _:ModuleExportDef | _:TopLevelModuleExportDef | + _:JSClassExportDef | _:TopLevelModuleExportDef | _:TopLevelFieldExportDef => case _ => diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 98dc13ea9e..1cf5e07bb9 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -831,22 +831,9 @@ object Trees { val tpe = NoType } - /** Traditional `@JSExport` for top-level objects, as a 0-arg function. + /** Export for a top-level object. * - * This exports a module as a 0-arg function that returns the module - * instance. It is initialized lazily in that case. - * - * This alternative should eventually disappear. - */ - case class ModuleExportDef(fullName: String)( - implicit val pos: Position) extends Tree { - val tpe = NoType - } - - /** New-style `@JSExportTopLevel` for top-level objects, directly as the - * object. - * - * This exports a module directly as a variable holding the module instance. + * This exports the singleton instance of the containing module class. * The instance is initialized during ES module instantiation. */ case class TopLevelModuleExportDef(fullName: String)( diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala index 766bc5671e..9cb05e5f36 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala @@ -1082,12 +1082,6 @@ class PrintersTest { JSClassExportDef("pkg.Foo")) } - @Test def printModuleExportDef(): Unit = { - assertPrintEquals( - """export module "pkg.Foo"""", - ModuleExportDef("pkg.Foo")) - } - @Test def printTopLevelModuleExportDef(): Unit = { assertPrintEquals( """export top module "pkg.Foo"""", diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala index 280ab65fc5..98807c4408 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala @@ -65,7 +65,6 @@ final class LinkedClass( def topLevelExportNames: List[String] = topLevelExports.map { export => (export: @unchecked) match { case ConstructorExportDef(name, _, _) => name - case ModuleExportDef(name) => name case TopLevelModuleExportDef(name) => name case JSClassExportDef(name) => name diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index 4eada26ebe..2c5739102a 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -942,8 +942,6 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { genConstructorExportDef(tree, e) case e: JSClassExportDef => WithGlobals(genJSClassExportDef(tree, e)) - case e: ModuleExportDef => - WithGlobals(genModuleExportDef(tree, e)) case e: TopLevelModuleExportDef => WithGlobals(genTopLevelModuleExportDef(tree, e)) case e: TopLevelMethodExportDef => @@ -1001,28 +999,10 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { genClassOrModuleExportDef(cd, tree.fullName, classVar) } - /** Generates an exporter for a module as a 0-arg function. + /** Generates an exporter for a module at the top-level. * - * This corresponds to the old-style `@JSExport` of modules. Basically this - * exports the module accessor. The object will be initialized lazily on - * the first call of the accessor, exactly like the accesses to objects from - * Scala code. - */ - def genModuleExportDef(cd: LinkedClass, tree: ModuleExportDef): js.Tree = { - import TreeDSL._ - - implicit val pos = tree.pos - - val baseAccessor = envField("m", cd.name.name) - genClassOrModuleExportDef(cd, tree.fullName, baseAccessor) - } - - /** Generates an exporter for a module at the "top-level", which is directly - * as a variable holding the module instance. - * - * This corresponds the the new-style `@JSExportTopLevel` of modules. In - * this case, the module instance is initialized during ES moduleµ - * instantiation. + * This corresponds to an `@JSExportTopLevel` on a module class. The module + * instance is initialized during ES module instantiation. */ def genTopLevelModuleExportDef(cd: LinkedClass, tree: TopLevelModuleExportDef): js.Tree = { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 88d4f8f22c..31e87d2435 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -167,9 +167,6 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { case tree: JSClassExportDef => checkJSClassExportDef(tree, classDef) - case tree: ModuleExportDef => - checkModuleExportDef(tree, classDef) - case tree: TopLevelModuleExportDef => checkTopLevelModuleExportDef(tree, classDef) @@ -489,14 +486,6 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { reportError(s"Exported JS class def can only appear in a JS class") } - private def checkModuleExportDef(moduleDef: ModuleExportDef, - classDef: LinkedClass): Unit = { - implicit val ctx = ErrorContext(moduleDef) - - if (!classDef.kind.hasModuleAccessor) - reportError(s"Exported module def can only appear in a module class") - } - private def checkTopLevelModuleExportDef( topLevelModuleDef: TopLevelModuleExportDef, classDef: LinkedClass): Unit = { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index 24d3401c7b..e184c7c096 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -229,9 +229,6 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, case e: JSClassExportDef => topLevelExports += e - case e: ModuleExportDef => - topLevelExports += e - case e: TopLevelModuleExportDef => topLevelExports += e From a8b33b52bb6b312c06a2ff2e392d40e1d97b1856 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 9 Jul 2017 17:24:51 +0200 Subject: [PATCH 0404/2665] Rename `{Constructor,JSClass}ExportDef` to `TopLevel{...}ExportDef`. This way, all top-level export IR nodes start with `TopLevel`. --- .../scalajs/core/compiler/GenJSExports.scala | 11 ++++++---- .../scala/org/scalajs/core/ir/Infos.scala | 16 +++++++------- .../scala/org/scalajs/core/ir/Printers.scala | 8 +++---- .../org/scalajs/core/ir/Serializers.scala | 21 ++++++++++--------- .../main/scala/org/scalajs/core/ir/Tags.scala | 6 +++--- .../org/scalajs/core/ir/Transformers.scala | 6 +++--- .../org/scalajs/core/ir/Traversers.scala | 4 ++-- .../scala/org/scalajs/core/ir/Trees.scala | 4 ++-- .../org/scalajs/core/ir/PrintersTest.scala | 8 +++---- .../core/tools/linker/LinkedClass.scala | 6 +++--- .../linker/backend/emitter/ClassEmitter.scala | 16 +++++++------- .../core/tools/linker/checker/IRChecker.scala | 17 ++++++++------- .../tools/linker/frontend/BaseLinker.scala | 4 ++-- 13 files changed, 67 insertions(+), 60 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index fbd1ac0652..e3558ec12f 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -59,7 +59,9 @@ trait GenJSExports extends SubComponent { self: GenJSCode => .map(genJSClassDispatcher(classSym, _)) } - def genConstructorExports(classSym: Symbol): List[js.ConstructorExportDef] = { + def genConstructorExports( + classSym: Symbol): List[js.TopLevelConstructorExportDef] = { + val constructors = classSym.tpe.member(nme.CONSTRUCTOR).alternatives // Generate exports from constructors and their annotations @@ -82,14 +84,15 @@ trait GenJSExports extends SubComponent { self: GenJSCode => withNewLocalNameScope(genExportMethod(ctors, JSName.Literal(jsName), static = false)) - js.ConstructorExportDef(jsName, args, body.get) + js.TopLevelConstructorExportDef(jsName, args, body.get) } exports.toList } } - def genJSClassExports(classSym: Symbol): List[js.JSClassExportDef] = { + def genJSClassExports( + classSym: Symbol): List[js.TopLevelJSClassExportDef] = { for { exp <- jsInterop.registeredExportsOf(classSym) } yield { @@ -97,7 +100,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => exp.destination match { case ExportDestination.Normal | ExportDestination.TopLevel => - js.JSClassExportDef(exp.jsName) + js.TopLevelJSClassExportDef(exp.jsName) case ExportDestination.Static => throw new AssertionError( "Found a class export static for " + classSym.fullName) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala index baae54fc19..0187cfd9ea 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala @@ -302,7 +302,7 @@ object Infos { .setSuperClass(classDef.superClass.map(_.name)) .addInterfaces(classDef.interfaces.map(_.name)) - var exportedConstructors: List[ConstructorExportDef] = Nil + var exportedConstructors: List[TopLevelConstructorExportDef] = Nil var topLevelMethodExports: List[TopLevelMethodExportDef] = Nil var topLevelFieldExports: List[TopLevelFieldExportDef] = Nil @@ -311,10 +311,10 @@ object Infos { builder.addMethod(generateMethodInfo(methodDef)) case propertyDef: PropertyDef => builder.addMethod(generatePropertyInfo(propertyDef)) - case constructorDef: ConstructorExportDef => + case constructorDef: TopLevelConstructorExportDef => builder.setIsExported(true) exportedConstructors ::= constructorDef - case _:JSClassExportDef | _:TopLevelModuleExportDef => + case _:TopLevelJSClassExportDef | _:TopLevelModuleExportDef => builder.setIsExported(true) case topLevelMethodExport: TopLevelMethodExportDef => builder.setIsExported(true) @@ -344,11 +344,11 @@ object Infos { /** Generates the [[MethodInfo]] for the top-level exports. */ def generateTopLevelExportsInfo(enclosingClass: String, - constructorDefs: List[ConstructorExportDef], + topLevelConstructorDefs: List[TopLevelConstructorExportDef], topLevelMethodExports: List[TopLevelMethodExportDef], topLevelFieldExports: List[TopLevelFieldExportDef]): MethodInfo = { new GenInfoTraverser().generateTopLevelExportsInfo(enclosingClass, - constructorDefs, topLevelMethodExports, topLevelFieldExports) + topLevelConstructorDefs, topLevelMethodExports, topLevelFieldExports) } private final class GenInfoTraverser extends Traversers.Traverser { @@ -393,15 +393,15 @@ object Infos { } def generateTopLevelExportsInfo(enclosingClass: String, - constructorDefs: List[ConstructorExportDef], + topLevelConstructorDefs: List[TopLevelConstructorExportDef], topLevelMethodExports: List[TopLevelMethodExportDef], topLevelFieldExports: List[TopLevelFieldExportDef]): MethodInfo = { builder .setEncodedName(TopLevelExportsName) .setIsExported(true) - for (constructorDef <- constructorDefs) - traverse(constructorDef.body) + for (topLevelConstructorDef <- topLevelConstructorDefs) + traverse(topLevelConstructorDef.body) for (topLevelMethodExport <- topLevelMethodExports) traverse(topLevelMethodExport.methodDef) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index 3173943a89..6869913d50 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -854,15 +854,15 @@ object Printers { printBlock(body) } - case ConstructorExportDef(fullName, args, body) => - print("export \"") + case TopLevelConstructorExportDef(fullName, args, body) => + print("export top constructor \"") printEscapeJS(fullName, out) print('\"') printSig(args, NoType) // NoType as trick not to display a type printBlock(body) - case JSClassExportDef(fullName) => - print("export class \"") + case TopLevelJSClassExportDef(fullName) => + print("export top class \"") printEscapeJS(fullName, out) print('\"') diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index 678fa4dc93..74754e0e6a 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -449,12 +449,12 @@ object Serializers { writeTree(arg); writeTree(body) } - case ConstructorExportDef(fullName, args, body) => - writeByte(TagConstructorExportDef) + case TopLevelConstructorExportDef(fullName, args, body) => + writeByte(TagTopLevelConstructorExportDef) writeString(fullName); writeTrees(args); writeTree(body) - case JSClassExportDef(fullName) => - writeByte(TagJSClassExportDef) + case TopLevelJSClassExportDef(fullName) => + writeByte(TagTopLevelJSClassExportDef) writeString(fullName) case TopLevelModuleExportDef(fullName) => @@ -808,13 +808,14 @@ object Serializers { } PropertyDef(static, name, getterBody, setterArgAndBody) - case TagConstructorExportDef => - ConstructorExportDef(readString(), readParamDefs(), readTree()) + case TagTopLevelConstructorExportDef => + TopLevelConstructorExportDef(readString(), readParamDefs(), + readTree()) - case TagJSClassExportDef => JSClassExportDef(readString()) - case TagTopLevelModuleExportDef => TopLevelModuleExportDef(readString()) - case TagTopLevelMethodExportDef => TopLevelMethodExportDef(readTree().asInstanceOf[MethodDef]) - case TagTopLevelFieldExportDef => TopLevelFieldExportDef(readString(), readIdent()) + case TagTopLevelJSClassExportDef => TopLevelJSClassExportDef(readString()) + case TagTopLevelModuleExportDef => TopLevelModuleExportDef(readString()) + case TagTopLevelMethodExportDef => TopLevelMethodExportDef(readTree().asInstanceOf[MethodDef]) + case TagTopLevelFieldExportDef => TopLevelFieldExportDef(readString(), readIdent()) } if (UseDebugMagic) { val magic = readInt() diff --git a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala index 01e5953eef..f96afa9f9d 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala @@ -96,9 +96,9 @@ private[ir] object Tags { final val TagFieldDef = TagClassDef + 1 final val TagMethodDef = TagFieldDef + 1 final val TagPropertyDef = TagMethodDef + 1 - final val TagConstructorExportDef = TagPropertyDef + 1 - final val TagJSClassExportDef = TagConstructorExportDef + 1 - final val TagTopLevelModuleExportDef = TagJSClassExportDef + 1 + final val TagTopLevelConstructorExportDef = TagPropertyDef + 1 + final val TagTopLevelJSClassExportDef = TagTopLevelConstructorExportDef + 1 + final val TagTopLevelModuleExportDef = TagTopLevelJSClassExportDef + 1 final val TagTopLevelMethodExportDef = TagTopLevelModuleExportDef + 1 final val TagTopLevelFieldExportDef = TagTopLevelMethodExportDef + 1 diff --git a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala index 220a904b0a..c23f36857f 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala @@ -234,10 +234,10 @@ object Transformers { (arg, transformStat(body)) }) - case ConstructorExportDef(fullName, args, body) => - ConstructorExportDef(fullName, args, transformStat(body)) + case TopLevelConstructorExportDef(fullName, args, body) => + TopLevelConstructorExportDef(fullName, args, transformStat(body)) - case _:JSClassExportDef | _:TopLevelModuleExportDef | + case _:TopLevelJSClassExportDef | _:TopLevelModuleExportDef | _:TopLevelFieldExportDef => tree diff --git a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala index f1d23c523c..f42838ad2d 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala @@ -208,7 +208,7 @@ object Traversers { traverse(body) } - case ConstructorExportDef(fullName, args, body) => + case TopLevelConstructorExportDef(fullName, args, body) => traverse(body) case TopLevelMethodExportDef(methodDef) => @@ -219,7 +219,7 @@ object Traversers { case _:Skip | _:Continue | _:Debugger | _:LoadModule | _:SelectStatic | _:LoadJSConstructor | _:LoadJSModule | _:JSLinkingInfo | _:Literal | _:UndefinedParam | _:VarRef | _:This | _:JSGlobalRef | _:FieldDef | - _:JSClassExportDef | _:TopLevelModuleExportDef | + _:TopLevelJSClassExportDef | _:TopLevelModuleExportDef | _:TopLevelFieldExportDef => case _ => diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 1cf5e07bb9..2e1960f2da 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -821,12 +821,12 @@ object Trees { val tpe = NoType } - case class ConstructorExportDef(name: String, args: List[ParamDef], + case class TopLevelConstructorExportDef(name: String, args: List[ParamDef], body: Tree)(implicit val pos: Position) extends Tree { val tpe = NoType } - case class JSClassExportDef(fullName: String)( + case class TopLevelJSClassExportDef(fullName: String)( implicit val pos: Position) extends Tree { val tpe = NoType } diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala index 9cb05e5f36..bb18d91016 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala @@ -1067,19 +1067,19 @@ class PrintersTest { @Test def printConstructorExportDef(): Unit = { assertPrintEquals( """ - |export "pkg.Foo"(x: any) { + |export top constructor "pkg.Foo"(x: any) { | 5 |} """, - ConstructorExportDef("pkg.Foo", + TopLevelConstructorExportDef("pkg.Foo", List(ParamDef("x", AnyType, mutable = false, rest = false)), i(5))) } @Test def printJSClassExportDef(): Unit = { assertPrintEquals( - """export class "pkg.Foo"""", - JSClassExportDef("pkg.Foo")) + """export top class "pkg.Foo"""", + TopLevelJSClassExportDef("pkg.Foo")) } @Test def printTopLevelModuleExportDef(): Unit = { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala index 98807c4408..a374b4e65e 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala @@ -64,9 +64,9 @@ final class LinkedClass( /** Names of all top-level exports in this class. */ def topLevelExportNames: List[String] = topLevelExports.map { export => (export: @unchecked) match { - case ConstructorExportDef(name, _, _) => name - case TopLevelModuleExportDef(name) => name - case JSClassExportDef(name) => name + case TopLevelConstructorExportDef(name, _, _) => name + case TopLevelModuleExportDef(name) => name + case TopLevelJSClassExportDef(name) => name case TopLevelMethodExportDef(MethodDef(_, StringLiteral(name), _, _, _)) => name diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index 2c5739102a..05f30d4fbd 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -938,10 +938,10 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { def genTopLevelExports(tree: LinkedClass)( implicit globalKnowledge: GlobalKnowledge): WithGlobals[List[js.Tree]] = { val exportsWithGlobals = tree.topLevelExports map { - case e: ConstructorExportDef => - genConstructorExportDef(tree, e) - case e: JSClassExportDef => - WithGlobals(genJSClassExportDef(tree, e)) + case e: TopLevelConstructorExportDef => + genTopLevelConstructorExportDef(tree, e) + case e: TopLevelJSClassExportDef => + WithGlobals(genTopLevelJSClassExportDef(tree, e)) case e: TopLevelModuleExportDef => WithGlobals(genTopLevelModuleExportDef(tree, e)) case e: TopLevelMethodExportDef => @@ -956,13 +956,14 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { WithGlobals.list(exportsWithGlobals) } - def genConstructorExportDef(cd: LinkedClass, tree: ConstructorExportDef)( + def genTopLevelConstructorExportDef(cd: LinkedClass, + tree: TopLevelConstructorExportDef)( implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { import TreeDSL._ implicit val pos = tree.pos val classType = ClassType(cd.name.name) - val ConstructorExportDef(fullName, args, body) = tree + val TopLevelConstructorExportDef(fullName, args, body) = tree val baseCtor = envField("c", cd.name.name, cd.name.originalName) @@ -990,7 +991,8 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { } } - def genJSClassExportDef(cd: LinkedClass, tree: JSClassExportDef): js.Tree = { + def genTopLevelJSClassExportDef(cd: LinkedClass, + tree: TopLevelJSClassExportDef): js.Tree = { import TreeDSL._ implicit val pos = tree.pos diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 31e87d2435..e719f78b54 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -161,11 +161,11 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { implicit val ctx = ErrorContext(tree) tree match { - case tree: ConstructorExportDef => - checkConstructorExportDef(tree, classDef) + case tree: TopLevelConstructorExportDef => + checkTopLevelConstructorExportDef(tree, classDef) - case tree: JSClassExportDef => - checkJSClassExportDef(tree, classDef) + case tree: TopLevelJSClassExportDef => + checkTopLevelJSClassExportDef(tree, classDef) case tree: TopLevelModuleExportDef => checkTopLevelModuleExportDef(tree, classDef) @@ -448,9 +448,10 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { } } - private def checkConstructorExportDef(ctorDef: ConstructorExportDef, + private def checkTopLevelConstructorExportDef( + ctorDef: TopLevelConstructorExportDef, classDef: LinkedClass): Unit = withPerMethodState { - val ConstructorExportDef(_, params, body) = ctorDef + val TopLevelConstructorExportDef(_, params, body) = ctorDef implicit val ctx = ErrorContext(ctorDef) if (!classDef.kind.isClass) { @@ -478,8 +479,8 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { typecheckStat(body, bodyEnv) } - private def checkJSClassExportDef(classExportDef: JSClassExportDef, - classDef: LinkedClass): Unit = { + private def checkTopLevelJSClassExportDef( + classExportDef: TopLevelJSClassExportDef, classDef: LinkedClass): Unit = { implicit val ctx = ErrorContext(classExportDef) if (classDef.kind != ClassKind.JSClass) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index e184c7c096..4b85ad9365 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -223,10 +223,10 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, if (analyzerInfo.isAnySubclassInstantiated) exportedMembers += linkedProperty(m) - case e: ConstructorExportDef => + case e: TopLevelConstructorExportDef => topLevelExports += e - case e: JSClassExportDef => + case e: TopLevelJSClassExportDef => topLevelExports += e case e: TopLevelModuleExportDef => From 720901b8761c7a76db4eb74e803c5f6abed1ccef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 9 Jul 2017 20:41:14 +0200 Subject: [PATCH 0405/2665] Decompose IR nodes into several categories for better type safety. There are several categories of IR nodes, and they were previously all tucked under the `Tree` type. This had several issues: * Some nodes had a `tpe` field although it was irrelevant. * Too many pattern matches had to be unchecked because they only handled one subcategory. * More generally, a lack of type safety. We now decompose IR nodes into several subtypes: * IRNode: Superclass of all IR nodes * Tree: statements and expressions * ClassDef: Stands on its own * MemberDef: fields, methods and properties (static or not) * TopLevelExportDef: top-level exports * ParamDef, Ident and ComputedName, standing on their own We kept the name `Tree` for statements and expressions because most places in the codebase were manipulating such kinds of nodes. Using a different name for that kind of nodes would have cause too many changes across the codebase. --- .../main/scala/org/scalajs/cli/Scalajsp.scala | 2 +- .../org/scalajs/core/compiler/GenJSCode.scala | 68 +++--- .../scalajs/core/compiler/GenJSExports.scala | 57 +++-- .../scalajs/core/compiler/ScalaJSPlugin.scala | 4 +- .../core/compiler/test/util/JSASTTest.scala | 40 +++- .../scala/org/scalajs/core/ir/Hashers.scala | 28 ++- .../scala/org/scalajs/core/ir/Infos.scala | 17 +- .../scala/org/scalajs/core/ir/Printers.scala | 142 +++++------ .../org/scalajs/core/ir/Serializers.scala | 220 ++++++++++++------ .../main/scala/org/scalajs/core/ir/Tags.scala | 13 +- .../org/scalajs/core/ir/Transformers.scala | 41 ++-- .../org/scalajs/core/ir/Traversers.scala | 51 ++-- .../scala/org/scalajs/core/ir/Trees.scala | 84 +++---- .../org/scalajs/core/ir/PrintersTest.scala | 26 ++- project/JavaLangObject.scala | 3 +- project/JavaLangString.scala | 3 +- .../sbtplugin/ScalaJSPluginInternal.scala | 2 +- .../closure/ClosureLinkerBackend.scala | 2 +- .../scalajs/core/tools/io/VirtualFiles.scala | 3 +- .../core/tools/linker/LinkedClass.scala | 25 +- .../core/tools/linker/LinkedMember.scala | 2 +- .../backend/emitter/FunctionEmitter.scala | 2 +- .../core/tools/linker/checker/IRChecker.scala | 20 +- .../tools/linker/frontend/BaseLinker.scala | 29 +-- 24 files changed, 501 insertions(+), 383 deletions(-) diff --git a/cli/src/main/scala/org/scalajs/cli/Scalajsp.scala b/cli/src/main/scala/org/scalajs/cli/Scalajsp.scala index 61710580bf..52e0d0318a 100644 --- a/cli/src/main/scala/org/scalajs/cli/Scalajsp.scala +++ b/cli/src/main/scala/org/scalajs/cli/Scalajsp.scala @@ -80,7 +80,7 @@ object Scalajsp { if (opts.infos) new InfoPrinter(stdout).print(vfile.info) else - new IRTreePrinter(stdout).printTopLevelTree(vfile.tree) + new IRTreePrinter(stdout).print(vfile.tree) stdout.flush() } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 7be5355f17..efa4e58c40 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -57,7 +57,7 @@ abstract class GenJSCode extends plugins.PluginComponent override val description: String = "generate JavaScript code from ASTs" /** testing: this will be called when ASTs are generated */ - def generatedJSAST(clDefs: List[js.Tree]): Unit + def generatedJSAST(clDefs: List[js.ClassDef]): Unit /** Implicit conversion from nsc Position to ir.Position. */ implicit def pos2irPos(pos: Position): ir.Position = { @@ -386,11 +386,11 @@ abstract class GenJSCode extends plugins.PluginComponent if (!isHijacked) genClassFields(cd) ++ generatedMethods.toList else generatedMethods.toList // No fields needed - // Generate the exported members, constructors and accessors - val exports = { - // Generate the exported members - val memberExports = genMemberExports(sym) + // Generate member exports + val memberExports = genMemberExports(sym) + // Generate the exported members, constructors and accessors + val topLevelExportDefs = { // Generate exported constructors or accessors val exportedConstructorsOrAccessors = if (isStaticModule(sym)) genModuleAccessorExports(sym) @@ -398,7 +398,7 @@ abstract class GenJSCode extends plugins.PluginComponent val topLevelExports = genTopLevelExports(sym) - memberExports ++ exportedConstructorsOrAccessors ++ topLevelExports + exportedConstructorsOrAccessors ++ topLevelExports } // Static initializer @@ -418,7 +418,7 @@ abstract class GenJSCode extends plugins.PluginComponent // Initialization of the module because of field exports val needsStaticModuleInit = - exports.exists(_.isInstanceOf[js.TopLevelFieldExportDef]) + topLevelExportDefs.exists(_.isInstanceOf[js.TopLevelFieldExportDef]) val staticModuleInit = if (!needsStaticModuleInit) None else Some(genLoadModule(sym)) @@ -432,8 +432,8 @@ abstract class GenJSCode extends plugins.PluginComponent } // Hashed definitions of the class - val hashedDefs = - Hashers.hashDefs(generatedMembers ++ exports ++ optStaticInitializer) + val hashedMemberDefs = + Hashers.hashMemberDefs(generatedMembers ++ memberExports ++ optStaticInitializer) // The complete class definition val kind = @@ -447,7 +447,8 @@ abstract class GenJSCode extends plugins.PluginComponent Some(encodeClassFullNameIdent(sym.superClass)), genClassInterfaces(sym), None, - hashedDefs)( + hashedMemberDefs, + topLevelExportDefs)( optimizerHints) classDefinition @@ -544,13 +545,12 @@ abstract class GenJSCode extends plugins.PluginComponent genJSClassConstructor(sym, constructorTrees.toList) :: genJSClassDispatchers(sym, dispatchMethodNames.result().distinct) ::: generatedMethods.toList ::: - staticMembers ::: - topLevelExports + staticMembers } // Hashed definitions of the class - val hashedDefs = - Hashers.hashDefs(generatedMembers) + val hashedMemberDefs = + Hashers.hashMemberDefs(generatedMembers) // The complete class definition val kind = @@ -563,7 +563,8 @@ abstract class GenJSCode extends plugins.PluginComponent Some(encodeClassFullNameIdent(sym.superClass)), genClassInterfaces(sym), None, - hashedDefs)( + hashedMemberDefs, + topLevelExports)( OptimizerHints.empty) classDefinition @@ -588,11 +589,11 @@ abstract class GenJSCode extends plugins.PluginComponent nestedGenerateClass(sym)(genNonNativeJSClass(classDef)) // Partition class members. - val staticMembers = ListBuffer.empty[js.Tree] - val classMembers = ListBuffer.empty[js.Tree] + val staticMembers = ListBuffer.empty[js.MemberDef] + val classMembers = ListBuffer.empty[js.MemberDef] var constructor: Option[js.MethodDef] = None - origJsClass.defs.foreach { + origJsClass.memberDefs.foreach { case fdef: js.FieldDef => classMembers += fdef @@ -615,18 +616,18 @@ abstract class GenJSCode extends plugins.PluginComponent case property: js.PropertyDef => classMembers += property - - case tree => - abort("Unexpected tree: " + tree) } + assert(origJsClass.topLevelExportDefs.isEmpty, + "Found top-level exports in anonymous JS class at " + pos) + // Make new class def with static members only val newClassDef = { implicit val pos = origJsClass.pos val parent = js.Ident(ir.Definitions.ObjectClass) js.ClassDef(origJsClass.name, ClassKind.AbstractJSType, Some(parent), interfaces = Nil, jsNativeLoadSpec = None, - staticMembers.toList)(origJsClass.optimizerHints) + staticMembers.toList, Nil)(origJsClass.optimizerHints) } generatedClasses += ((sym, None, newClassDef)) @@ -760,7 +761,7 @@ abstract class GenJSCode extends plugins.PluginComponent } js.ClassDef(classIdent, kind, superClass, genClassInterfaces(sym), - jsNativeLoadSpec, Nil)( + jsNativeLoadSpec, Nil, Nil)( OptimizerHints.empty) } @@ -791,11 +792,11 @@ abstract class GenJSCode extends plugins.PluginComponent val interfaces = genClassInterfaces(sym) // Hashed definitions of the interface - val hashedDefs = - Hashers.hashDefs(generatedMethods) + val hashedMemberDefs = + Hashers.hashMemberDefs(generatedMethods) js.ClassDef(classIdent, ClassKind.Interface, None, interfaces, None, - hashedDefs)(OptimizerHints.empty) + hashedMemberDefs, Nil)(OptimizerHints.empty) } // Generate an implementation class of a trait ----------------------------- @@ -827,12 +828,12 @@ abstract class GenJSCode extends plugins.PluginComponent val objectClassIdent = encodeClassFullNameIdent(ObjectClass) // Hashed definitions of the impl class - val hashedDefs = - Hashers.hashDefs(generatedMethods) + val hashedMemberDefs = + Hashers.hashMemberDefs(generatedMethods) js.ClassDef(classIdent, ClassKind.Class, Some(objectClassIdent), Nil, None, - hashedDefs)(OptimizerHints.empty) + hashedMemberDefs, Nil)(OptimizerHints.empty) } private def genClassInterfaces(sym: Symbol)( @@ -1021,7 +1022,7 @@ abstract class GenJSCode extends plugins.PluginComponent // Constructor of a non-native JS class ------------------------------ def genJSClassConstructor(classSym: Symbol, - constructorTrees: List[DefDef]): js.Tree = { + constructorTrees: List[DefDef]): js.MethodDef = { implicit val pos = classSym.pos if (hasDefaultCtorArgsAndRawJSModule(classSym)) { @@ -1029,7 +1030,9 @@ abstract class GenJSCode extends plugins.PluginComponent "Implementation restriction: constructors of " + "non-native JS classes cannot have default parameters " + "if their companion module is JS native.") - js.Skip() + js.MethodDef(static = false, js.StringLiteral("constructor"), Nil, + jstpe.AnyType, Some(js.Skip()))( + OptimizerHints.empty, None) } else { withNewLocalNameScope { val ctors: List[js.MethodDef] = constructorTrees.flatMap { tree => @@ -5197,7 +5200,8 @@ abstract class GenJSCode extends plugins.PluginComponent Some(js.Ident(ir.Definitions.ObjectClass)), List(js.Ident(intfName)), None, - List(fFieldDef, ctorDef, samMethodDef))( + List(fFieldDef, ctorDef, samMethodDef), + Nil)( js.OptimizerHints.empty.withInline(true)) generatedClasses += ((currentClassSym.get, Some(suffix), classDef)) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index e3558ec12f..1a7fb411f7 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -9,6 +9,7 @@ import scala.collection.mutable import scala.tools.nsc._ import scala.math.PartialOrdering +import scala.reflect.{ClassTag, classTag} import scala.reflect.internal.Flags import org.scalajs.core.ir @@ -35,7 +36,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => * * @param classSym symbol of the class we export for */ - def genMemberExports(classSym: Symbol): List[js.Tree] = { + def genMemberExports(classSym: Symbol): List[js.MemberDef] = { val allExports = classSym.info.members.filter(jsInterop.isExport(_)) val newlyDecldExports = if (classSym.superClass == NoSymbol) { @@ -54,7 +55,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } def genJSClassDispatchers(classSym: Symbol, - dispatchMethodsNames: List[JSName]): List[js.Tree] = { + dispatchMethodsNames: List[JSName]): List[js.MemberDef] = { dispatchMethodsNames .map(genJSClassDispatcher(classSym, _)) } @@ -108,7 +109,9 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } } - def genModuleAccessorExports(classSym: Symbol): List[js.Tree] = { + def genModuleAccessorExports( + classSym: Symbol): List[js.TopLevelExportDef] = { + for { exp <- jsInterop.registeredExportsOf(classSym) } yield { @@ -127,14 +130,14 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } } - def genTopLevelExports(classSym: Symbol): List[js.Tree] = - genTopLevelOrStaticExports(classSym, ExportDestination.TopLevel) + def genTopLevelExports(classSym: Symbol): List[js.TopLevelExportDef] = + genTopLevelOrStaticExports[js.TopLevelExportDef](classSym, ExportDestination.TopLevel) - def genStaticExports(classSym: Symbol): List[js.Tree] = - genTopLevelOrStaticExports(classSym, ExportDestination.Static) + def genStaticExports(classSym: Symbol): List[js.MemberDef] = + genTopLevelOrStaticExports[js.MemberDef](classSym, ExportDestination.Static) - private def genTopLevelOrStaticExports(classSym: Symbol, - destination: ExportDestination): List[js.Tree] = { + private def genTopLevelOrStaticExports[A <: js.IRNode: ClassTag]( + classSym: Symbol, destination: ExportDestination): List[A] = { require( destination == ExportDestination.TopLevel || destination == ExportDestination.Static) @@ -160,8 +163,9 @@ trait GenJSExports extends SubComponent { self: GenJSCode => exportsNamesAndPositions.map(_._1) } - private def genTopLevelOrStaticFieldExports(classSym: Symbol, - destination: ExportDestination): List[(js.Tree, String, Position)] = { + private def genTopLevelOrStaticFieldExports[A <: js.IRNode: ClassTag]( + classSym: Symbol, + destination: ExportDestination): List[(A, String, Position)] = { (for { fieldSym <- classSym.info.members if !fieldSym.isMethod && fieldSym.isTerm && !fieldSym.isModule @@ -174,17 +178,19 @@ trait GenJSExports extends SubComponent { self: GenJSCode => val mutable = true // static fields must always be mutable val name = js.StringLiteral(export.jsName) val irTpe = genExposedFieldIRType(fieldSym) - js.FieldDef(static = true, name, irTpe, mutable) + checkedCast[A](js.FieldDef(static = true, name, irTpe, mutable)) } else { - js.TopLevelFieldExportDef(export.jsName, encodeFieldSym(fieldSym)) + checkedCast[A]( + js.TopLevelFieldExportDef(export.jsName, encodeFieldSym(fieldSym))) } (tree, export.jsName, pos) }).toList } - private def genTopLevelOrStaticMethodExports(classSym: Symbol, - destination: ExportDestination): List[(js.Tree, String, Position)] = { + private def genTopLevelOrStaticMethodExports[A <: js.IRNode: ClassTag]( + classSym: Symbol, + destination: ExportDestination): List[(A, String, Position)] = { val allRelevantExports = for { methodSym <- classSym.info.members if methodSym.isMethod && !methodSym.isConstructor @@ -219,15 +225,21 @@ trait GenJSExports extends SubComponent { self: GenJSCode => val exportedMember = genMemberExportOrDispatcher(classSym, JSName.Literal(jsName), isProp, alts, static = true) - val exportDef = - if (destination == ExportDestination.Static) exportedMember - else js.TopLevelMethodExportDef(exportedMember.asInstanceOf[js.MethodDef]) + val exportDef = { + if (destination == ExportDestination.Static) + checkedCast[A](exportedMember) + else + checkedCast[A](js.TopLevelMethodExportDef(exportedMember.asInstanceOf[js.MethodDef])) + } (exportDef, jsName, pos) } } - private def genMemberExport(classSym: Symbol, name: TermName): js.Tree = { + private def checkedCast[A: ClassTag](x: js.IRNode): A = + classTag[A].runtimeClass.asInstanceOf[Class[A]].cast(x) + + private def genMemberExport(classSym: Symbol, name: TermName): js.MemberDef = { val alts = classSym.info.member(name).alternatives assert(!alts.isEmpty, @@ -252,7 +264,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => alts, static = false) } - private def genJSClassDispatcher(classSym: Symbol, name: JSName): js.Tree = { + private def genJSClassDispatcher(classSym: Symbol, name: JSName): js.MemberDef = { val alts = classSym.info.members.toList.filter { sym => !sym.isBridge && jsNameOf(sym) == name } @@ -266,7 +278,8 @@ trait GenJSExports extends SubComponent { self: GenJSCode => if (isProp && methodSyms.nonEmpty) { reporter.error(alts.head.pos, s"Conflicting properties and methods for ${classSym.fullName}::$name.") - js.Skip()(ir.Position.NoPosition) + implicit val pos = alts.head.pos + js.PropertyDef(static = false, genPropertyName(name), None, None) } else { genMemberExportOrDispatcher(classSym, name, isProp, alts, static = false) @@ -274,7 +287,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } def genMemberExportOrDispatcher(classSym: Symbol, jsName: JSName, - isProp: Boolean, alts: List[Symbol], static: Boolean): js.Tree = { + isProp: Boolean, alts: List[Symbol], static: Boolean): js.MemberDef = { withNewLocalNameScope { if (isProp) genExportProperty(alts, jsName, static) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala index d7355bceea..875d033614 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala @@ -34,7 +34,7 @@ class ScalaJSPlugin(val global: Global) extends NscPlugin { } /** Called when the JS ASTs are generated. Override for testing */ - def generatedJSAST(clDefs: List[Trees.Tree]): Unit = {} + def generatedJSAST(clDefs: List[Trees.ClassDef]): Unit = {} /** Addons for JavaScript platform */ object jsAddons extends { @@ -85,7 +85,7 @@ class ScalaJSPlugin(val global: Global) extends NscPlugin { override val runsAfter = List("mixin") override val runsBefore = List("delambdafy", "cleanup", "terminal") } with GenJSCode { - def generatedJSAST(clDefs: List[Trees.Tree]): Unit = + def generatedJSAST(clDefs: List[Trees.ClassDef]): Unit = ScalaJSPlugin.this.generatedJSAST(clDefs) } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/JSASTTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/util/JSASTTest.scala index f324f2bc2a..d5de443ec9 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/JSASTTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/util/JSASTTest.scala @@ -18,8 +18,8 @@ abstract class JSASTTest extends DirectTest { private var lastAST: JSAST = _ - class JSAST(val clDefs: List[js.Tree]) { - type Pat = PartialFunction[js.Tree, Unit] + class JSAST(val clDefs: List[js.ClassDef]) { + type Pat = PartialFunction[js.IRNode, Unit] class PFTraverser(pf: Pat) extends ir.Traversers.Traverser { private case object Found extends ControlThrowable @@ -29,7 +29,7 @@ abstract class JSASTTest extends DirectTest { def find: Boolean = { finding = true try { - clDefs.map(traverse) + clDefs.map(traverseClassDef) false } catch { case Found => true @@ -38,17 +38,37 @@ abstract class JSASTTest extends DirectTest { def traverse(): Unit = { finding = false - clDefs.map(traverse) + clDefs.map(traverseClassDef) } override def traverse(tree: js.Tree): Unit = { - if (finding && pf.isDefinedAt(tree)) - throw Found + handle(tree) + super.traverse(tree) + } - if (!finding) - pf.lift(tree) + override def traverseClassDef(classDef: js.ClassDef): Unit = { + handle(classDef) + super.traverseClassDef(classDef) + } - super.traverse(tree) + override def traverseMemberDef(memberDef: js.MemberDef): Unit = { + handle(memberDef) + super.traverseMemberDef(memberDef) + } + + override def traverseTopLevelExportDef( + exportDef: js.TopLevelExportDef): Unit = { + handle(exportDef) + super.traverseTopLevelExportDef(exportDef) + } + + private def handle(node: js.IRNode): Unit = { + if (finding) { + if (pf.isDefinedAt(node)) + throw Found + } else { + pf.lift(node) + } } } @@ -89,7 +109,7 @@ abstract class JSASTTest extends DirectTest { override def newScalaJSPlugin(global: Global): ScalaJSPlugin = { new ScalaJSPlugin(global) { - override def generatedJSAST(cld: List[js.Tree]): Unit = { + override def generatedJSAST(cld: List[js.ClassDef]): Unit = { lastAST = new JSAST(cld) } } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala index 8c862f5ed9..0b502392b5 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala @@ -19,7 +19,7 @@ object Hashers { hasher.mixPos(methodDef.pos) hasher.mixBoolean(static) hasher.mixPropertyName(name) - hasher.mixTrees(args) + hasher.mixParamDefs(args) hasher.mixType(resultType) body.foreach(hasher.mixTree) hasher.mixInt(methodDef.optimizerHints.bits) @@ -32,14 +32,14 @@ object Hashers { } /** Hash definitions from a ClassDef where applicable */ - def hashDefs(defs: List[Tree]): List[Tree] = defs map { + def hashMemberDefs(memberDefs: List[MemberDef]): List[MemberDef] = memberDefs.map { case methodDef: MethodDef => hashMethodDef(methodDef) case otherDef => otherDef } /** Hash the definitions in a ClassDef (where applicable) */ def hashClassDef(classDef: ClassDef): ClassDef = { - classDef.copy(defs = hashDefs(classDef.defs))( + classDef.copy(memberDefs = hashMemberDefs(classDef.memberDefs))( classDef.optimizerHints)(classDef.pos) } @@ -86,6 +86,17 @@ object Hashers { def finalizeHash(): TreeHash = new TreeHash(treeDigest.digest(), posDigest.digest()) + def mixParamDef(paramDef: ParamDef): Unit = { + mixPos(paramDef.pos) + mixIdent(paramDef.name) + mixType(paramDef.ptpe) + mixBoolean(paramDef.mutable) + mixBoolean(paramDef.rest) + } + + def mixParamDefs(paramDefs: List[ParamDef]): Unit = + paramDefs.foreach(mixParamDef) + def mixTree(tree: Tree): Unit = { mixPos(tree.pos) tree match { @@ -96,13 +107,6 @@ object Hashers { mixBoolean(mutable) mixTree(rhs) - case ParamDef(ident, ptpe, mutable, rest) => - mixTag(TagParamDef) - mixIdent(ident) - mixType(ptpe) - mixBoolean(mutable) - mixBoolean(rest) - case Skip() => mixTag(TagSkip) @@ -432,8 +436,8 @@ object Hashers { case Closure(captureParams, params, body, captureValues) => mixTag(TagClosure) - mixTrees(captureParams) - mixTrees(params) + mixParamDefs(captureParams) + mixParamDefs(params) mixTree(body) mixTrees(captureValues) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala index 0187cfd9ea..302141412b 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala @@ -302,15 +302,19 @@ object Infos { .setSuperClass(classDef.superClass.map(_.name)) .addInterfaces(classDef.interfaces.map(_.name)) - var exportedConstructors: List[TopLevelConstructorExportDef] = Nil - var topLevelMethodExports: List[TopLevelMethodExportDef] = Nil - var topLevelFieldExports: List[TopLevelFieldExportDef] = Nil - - classDef.defs foreach { + classDef.memberDefs foreach { + case fieldDef: FieldDef => case methodDef: MethodDef => builder.addMethod(generateMethodInfo(methodDef)) case propertyDef: PropertyDef => builder.addMethod(generatePropertyInfo(propertyDef)) + } + + var exportedConstructors: List[TopLevelConstructorExportDef] = Nil + var topLevelMethodExports: List[TopLevelMethodExportDef] = Nil + var topLevelFieldExports: List[TopLevelFieldExportDef] = Nil + + classDef.topLevelExportDefs foreach { case constructorDef: TopLevelConstructorExportDef => builder.setIsExported(true) exportedConstructors ::= constructorDef @@ -322,7 +326,6 @@ object Infos { case topLevelFieldExport: TopLevelFieldExportDef => builder.setIsExported(true) topLevelFieldExports ::= topLevelFieldExport - case _ => } if (exportedConstructors.nonEmpty || topLevelMethodExports.nonEmpty || @@ -404,7 +407,7 @@ object Infos { traverse(topLevelConstructorDef.body) for (topLevelMethodExport <- topLevelMethodExports) - traverse(topLevelMethodExport.methodDef) + topLevelMethodExport.methodDef.body.foreach(traverse(_)) for (topLevelFieldExport <- topLevelFieldExports) { val field = topLevelFieldExport.field.name diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index 6869913d50..f6ded00e97 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -47,26 +47,13 @@ object Printers { } class IRTreePrinter(protected val out: Writer) extends IndentationManager { - def printTopLevelTree(tree: Tree): Unit = { - tree match { - case Skip() => - // do not print anything - case Block(stats) => - for (stat <- stats) - printTopLevelTree(stat) - case _ => - print(tree) - println() - } - } - - protected final def printColumn(ts: List[Tree], start: String, sep: String, - end: String): Unit = { + protected final def printColumn(ts: List[IRNode], start: String, + sep: String, end: String): Unit = { print(start); indent() var rest = ts while (rest.nonEmpty) { println() - print(rest.head) + printAnyNode(rest.head) rest = rest.tail if (rest.nonEmpty) print(sep) @@ -74,12 +61,12 @@ object Printers { undent(); println(); print(end) } - protected final def printRow(ts: List[Tree], start: String, sep: String, + protected final def printRow(ts: List[IRNode], start: String, sep: String, end: String): Unit = { print(start) var rest = ts while (rest.nonEmpty) { - print(rest.head) + printAnyNode(rest.head) rest = rest.tail if (rest.nonEmpty) print(sep) @@ -114,6 +101,30 @@ object Printers { printRow(args, "(", ", ", ")") } + def printAnyNode(node: IRNode): Unit = { + node match { + case node: Ident => print(node) + case node: ComputedName => print(node) + case node: ParamDef => print(node) + case node: Tree => print(node) + case node: ClassDef => print(node) + case node: MemberDef => print(node) + case node: TopLevelExportDef => print(node) + } + } + + def print(paramDef: ParamDef): Unit = { + val ParamDef(ident, ptpe, mutable, rest) = paramDef + + if (mutable) + print("var ") + if (rest) + print("...") + print(ident) + print(": ") + print(ptpe) + } + def print(tree: Tree): Unit = { tree match { // Definitions @@ -129,15 +140,6 @@ object Printers { print(" = ") print(rhs) - case ParamDef(ident, ptpe, mutable, rest) => - if (mutable) - print("var ") - if (rest) - print("...") - print(ident) - print(": ") - print(ptpe) - // Control flow constructs case Skip() => @@ -766,46 +768,49 @@ object Printers { printRow(params, ">(", ", ", ") = ") printBlock(body) print(')') + } + } - // Classes - - case tree: ClassDef => - val ClassDef(name, kind, superClass, interfaces, jsNativeLoadSpec, - defs) = tree - print(tree.optimizerHints) - kind match { - case ClassKind.Class => print("class ") - case ClassKind.ModuleClass => print("module class ") - case ClassKind.Interface => print("interface ") - case ClassKind.AbstractJSType => print("abstract js type ") - case ClassKind.HijackedClass => print("hijacked class ") - case ClassKind.JSClass => print("js class ") - case ClassKind.JSModuleClass => print("js module class ") - case ClassKind.NativeJSClass => print("native js class ") - case ClassKind.NativeJSModuleClass => print("native js module class ") - } - print(name) - superClass.foreach { cls => - print(" extends ") - print(cls) - } - if (interfaces.nonEmpty) { - print(" implements ") - var rest = interfaces - while (rest.nonEmpty) { - print(rest.head) - rest = rest.tail - if (rest.nonEmpty) - print(", ") - } - } - jsNativeLoadSpec.foreach { spec => - print(" loadfrom ") - print(spec) - } - print(" ") - printColumn(defs, "{", "", "}") + def print(classDef: ClassDef): Unit = { + val ClassDef(name, kind, superClass, interfaces, jsNativeLoadSpec, + memberDefs, topLevelExportDefs) = classDef + print(classDef.optimizerHints) + kind match { + case ClassKind.Class => print("class ") + case ClassKind.ModuleClass => print("module class ") + case ClassKind.Interface => print("interface ") + case ClassKind.AbstractJSType => print("abstract js type ") + case ClassKind.HijackedClass => print("hijacked class ") + case ClassKind.JSClass => print("js class ") + case ClassKind.JSModuleClass => print("js module class ") + case ClassKind.NativeJSClass => print("native js class ") + case ClassKind.NativeJSModuleClass => print("native js module class ") + } + print(name) + superClass.foreach { cls => + print(" extends ") + print(cls) + } + if (interfaces.nonEmpty) { + print(" implements ") + var rest = interfaces + while (rest.nonEmpty) { + print(rest.head) + rest = rest.tail + if (rest.nonEmpty) + print(", ") + } + } + jsNativeLoadSpec.foreach { spec => + print(" loadfrom ") + print(spec) + } + print(" ") + printColumn(memberDefs ::: topLevelExportDefs, "{", "", "}") + } + def print(memberDef: MemberDef): Unit = { + memberDef match { case FieldDef(static, name, vtpe, mutable) => if (static) print("static ") @@ -853,7 +858,11 @@ object Printers { printSig(arg :: Nil, NoType) printBlock(body) } + } + } + def print(topLevelExportDef: TopLevelExportDef): Unit = { + topLevelExportDef match { case TopLevelConstructorExportDef(fullName, args, body) => print("export top constructor \"") printEscapeJS(fullName, out) @@ -881,9 +890,6 @@ object Printers { print(" as \"") printEscapeJS(fullName, out) print('\"') - - case _ => - print(s"") } } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index 74754e0e6a..de71b2a748 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -25,11 +25,11 @@ import Tags._ import Utils.JumpBackByteArrayOutputStream object Serializers { - def serialize(stream: OutputStream, tree: Tree): Unit = { - new Serializer().serialize(stream, tree) + def serialize(stream: OutputStream, classDef: ClassDef): Unit = { + new Serializer().serialize(stream, classDef) } - def deserialize(stream: InputStream, version: String): Tree = { + def deserialize(stream: InputStream, version: String): ClassDef = { new Deserializer(stream, version).deserialize() } @@ -87,9 +87,9 @@ object Serializers { private[this] var lastPosition: Position = Position.NoPosition - def serialize(stream: OutputStream, tree: Tree): Unit = { + def serialize(stream: OutputStream, classDef: ClassDef): Unit = { // Write tree to buffer and record files and strings - writeTree(tree) + writeClassDef(classDef) val s = new DataOutputStream(stream) @@ -115,10 +115,6 @@ object Serializers { writeByte(TagVarDef) writeIdent(ident); writeType(vtpe); writeBoolean(mutable); writeTree(rhs) - case ParamDef(ident, ptpe, mutable, rest) => - writeByte(TagParamDef) - writeIdent(ident); writeType(ptpe); writeBoolean(mutable); writeBoolean(rest) - case Skip() => writeByte(TagSkip) @@ -395,23 +391,49 @@ object Serializers { case Closure(captureParams, params, body, captureValues) => writeByte(TagClosure) - writeTrees(captureParams) - writeTrees(params) + writeParamDefs(captureParams) + writeParamDefs(params) writeTree(body) writeTrees(captureValues) + } + if (UseDebugMagic) + writeInt(DebugMagic) + } - case tree: ClassDef => - val ClassDef(name, kind, superClass, parents, jsNativeLoadSpec, - defs) = tree - writeByte(TagClassDef) - writeIdent(name) - writeByte(ClassKind.toByte(kind)) - writeOptIdent(superClass) - writeIdents(parents) - writeJSNativeLoadSpec(jsNativeLoadSpec) - writeTrees(defs) - writeInt(tree.optimizerHints.bits) + def writeTrees(trees: List[Tree]): Unit = { + buffer.writeInt(trees.size) + trees.foreach(writeTree) + } + def writeOptTree(optTree: Option[Tree]): Unit = { + optTree.fold { + writePosition(Position.NoPosition) + buffer.writeByte(TagEmptyTree) + } { tree => + writeTree(tree) + } + } + + def writeClassDef(classDef: ClassDef): Unit = { + import buffer._ + + val ClassDef(name, kind, superClass, parents, jsNativeLoadSpec, + memberDefs, topLevelExportDefs) = classDef + writePosition(classDef.pos) + writeIdent(name) + writeByte(ClassKind.toByte(kind)) + writeOptIdent(superClass) + writeIdents(parents) + writeJSNativeLoadSpec(jsNativeLoadSpec) + writeMemberDefs(memberDefs) + writeTopLevelExportDefs(topLevelExportDefs) + writeInt(classDef.optimizerHints.bits) + } + + def writeMemberDef(memberDef: MemberDef): Unit = { + import buffer._ + writePosition(memberDef.pos) + memberDef match { case FieldDef(static, name, ftpe, mutable) => writeByte(TagFieldDef) writeBoolean(static) @@ -431,7 +453,7 @@ object Serializers { // Write out method def writeBoolean(static); writePropertyName(name) - writeTrees(args); writeType(resultType); writeOptTree(body) + writeParamDefs(args); writeType(resultType); writeOptTree(body) writeInt(methodDef.optimizerHints.bits) // Jump back and write true length @@ -446,12 +468,23 @@ object Serializers { writeOptTree(getter) writeBoolean(setterArgAndBody.isDefined) setterArgAndBody foreach { case (arg, body) => - writeTree(arg); writeTree(body) + writeParamDef(arg); writeTree(body) } + } + } + + def writeMemberDefs(memberDefs: List[MemberDef]): Unit = { + buffer.writeInt(memberDefs.size) + memberDefs.foreach(writeMemberDef) + } + def writeTopLevelExportDef(topLevelExportDef: TopLevelExportDef): Unit = { + import buffer._ + writePosition(topLevelExportDef.pos) + topLevelExportDef match { case TopLevelConstructorExportDef(fullName, args, body) => writeByte(TagTopLevelConstructorExportDef) - writeString(fullName); writeTrees(args); writeTree(body) + writeString(fullName); writeParamDefs(args); writeTree(body) case TopLevelJSClassExportDef(fullName) => writeByte(TagTopLevelJSClassExportDef) @@ -463,28 +496,18 @@ object Serializers { case TopLevelMethodExportDef(methodDef) => writeByte(TagTopLevelMethodExportDef) - writeTree(methodDef) + writeMemberDef(methodDef) case TopLevelFieldExportDef(fullName, field) => writeByte(TagTopLevelFieldExportDef) writeString(fullName); writeIdent(field) } - if (UseDebugMagic) - writeInt(DebugMagic) } - def writeTrees(trees: List[Tree]): Unit = { - buffer.writeInt(trees.size) - trees.foreach(writeTree) - } - - def writeOptTree(optTree: Option[Tree]): Unit = { - optTree.fold { - writePosition(Position.NoPosition) - buffer.writeByte(TagEmptyTree) - } { tree => - writeTree(tree) - } + def writeTopLevelExportDefs( + topLevelExportDefs: List[TopLevelExportDef]): Unit = { + buffer.writeInt(topLevelExportDefs.size) + topLevelExportDefs.foreach(writeTopLevelExportDef) } def writeIdent(ident: Ident): Unit = { @@ -502,6 +525,19 @@ object Serializers { optIdent.foreach(writeIdent) } + def writeParamDef(paramDef: ParamDef): Unit = { + writePosition(paramDef.pos) + writeIdent(paramDef.name) + writeType(paramDef.ptpe) + buffer.writeBoolean(paramDef.mutable) + buffer.writeBoolean(paramDef.rest) + } + + def writeParamDefs(paramDefs: List[ParamDef]): Unit = { + buffer.writeInt(paramDefs.size) + paramDefs.foreach(writeParamDef) + } + def writeType(tpe: Type): Unit = { tpe match { case AnyType => buffer.write(TagAnyType) @@ -667,8 +703,8 @@ object Serializers { private[this] var lastPosition: Position = Position.NoPosition - def deserialize(): Tree = { - readTree() + def deserialize(): ClassDef = { + readClassDef() } def readTree(): Tree = { @@ -690,16 +726,15 @@ object Serializers { case TagEmptyTree => throw new IOException("Found invalid TagEmptyTree") - case TagVarDef => VarDef(readIdent(), readType(), readBoolean(), readTree()) - case TagParamDef => ParamDef(readIdent(), readType(), readBoolean(), readBoolean()) - case TagSkip => Skip() - case TagBlock => Block(readTrees()) - case TagLabeled => Labeled(readIdent(), readType(), readTree()) - case TagAssign => Assign(readTree(), readTree()) - case TagReturn => Return(readTree(), readOptIdent()) - case TagIf => If(readTree(), readTree(), readTree())(readType()) - case TagWhile => While(readTree(), readTree(), readOptIdent()) - case TagDoWhile => DoWhile(readTree(), readTree(), readOptIdent()) + case TagVarDef => VarDef(readIdent(), readType(), readBoolean(), readTree()) + case TagSkip => Skip() + case TagBlock => Block(readTrees()) + case TagLabeled => Labeled(readIdent(), readType(), readTree()) + case TagAssign => Assign(readTree(), readTree()) + case TagReturn => Return(readTree(), readOptIdent()) + case TagIf => If(readTree(), readTree(), readTree())(readType()) + case TagWhile => While(readTree(), readTree(), readOptIdent()) + case TagDoWhile => DoWhile(readTree(), readTree(), readOptIdent()) case TagTryCatch => TryCatch(readTree(), readIdent(), readTree())(readType()) @@ -772,18 +807,42 @@ object Serializers { case TagVarRef => VarRef(readIdent())(readType()) case TagThis => This()(readType()) case TagClosure => Closure(readParamDefs(), readParamDefs(), readTree(), readTrees()) + } + if (UseDebugMagic) { + val magic = readInt() + assert(magic == DebugMagic, + s"Bad magic after reading a ${result.getClass}!") + } + result + } + + def readTrees(): List[Tree] = + List.fill(input.readInt())(readTree()) - case TagClassDef => - val name = readIdent() - val kind = ClassKind.fromByte(readByte()) - val superClass = readOptIdent() - val parents = readIdents() - val jsNativeLoadSpec = readJSNativeLoadSpec() - val defs = readTrees() - val optimizerHints = new OptimizerHints(readInt()) - ClassDef(name, kind, superClass, parents, jsNativeLoadSpec, defs)( - optimizerHints) + def readClassDef(): ClassDef = { + import input._ + implicit val pos = readPosition() + val name = readIdent() + val kind = ClassKind.fromByte(readByte()) + val superClass = readOptIdent() + val parents = readIdents() + val jsNativeLoadSpec = readJSNativeLoadSpec() + val memberDefs = readMemberDefs() + val topLevelExportDefs = readTopLevelExportDefs() + val optimizerHints = new OptimizerHints(readInt()) + ClassDef(name, kind, superClass, parents, jsNativeLoadSpec, memberDefs, + topLevelExportDefs)( + optimizerHints) + } + + def readMemberDef(): MemberDef = { + import input._ + + implicit val pos = readPosition() + val tag = input.readByte() + + (tag: @switch) match { case TagFieldDef => FieldDef(readBoolean(), readPropertyName(), readType(), readBoolean()) @@ -802,34 +861,35 @@ object Serializers { val getterBody = readOptTree() val setterArgAndBody = { if (readBoolean()) - Some((readTree().asInstanceOf[ParamDef], readTree())) + Some((readParamDef(), readTree())) else None } PropertyDef(static, name, getterBody, setterArgAndBody) + } + } + def readMemberDefs(): List[MemberDef] = + List.fill(input.readInt())(readMemberDef()) + + def readTopLevelExportDef(): TopLevelExportDef = { + implicit val pos = readPosition() + val tag = input.readByte() + + (tag: @switch) match { case TagTopLevelConstructorExportDef => TopLevelConstructorExportDef(readString(), readParamDefs(), readTree()) case TagTopLevelJSClassExportDef => TopLevelJSClassExportDef(readString()) case TagTopLevelModuleExportDef => TopLevelModuleExportDef(readString()) - case TagTopLevelMethodExportDef => TopLevelMethodExportDef(readTree().asInstanceOf[MethodDef]) + case TagTopLevelMethodExportDef => TopLevelMethodExportDef(readMemberDef().asInstanceOf[MethodDef]) case TagTopLevelFieldExportDef => TopLevelFieldExportDef(readString(), readIdent()) } - if (UseDebugMagic) { - val magic = readInt() - assert(magic == DebugMagic, - s"Bad magic after reading a ${result.getClass}!") - } - result } - def readTrees(): List[Tree] = - List.fill(input.readInt())(readTree()) - - def readParamDefs(): List[ParamDef] = - readTrees().map(_.asInstanceOf[ParamDef]) + def readTopLevelExportDefs(): List[TopLevelExportDef] = + List.fill(input.readInt())(readTopLevelExportDef()) def readIdent(): Ident = { implicit val pos = readPosition() @@ -846,6 +906,16 @@ object Serializers { else None } + def readParamDef(): ParamDef = { + import input._ + + implicit val pos = readPosition() + ParamDef(readIdent(), readType(), readBoolean(), readBoolean()) + } + + def readParamDefs(): List[ParamDef] = + List.fill(input.readInt())(readParamDef()) + def readType(): Type = { val tag = input.readByte() (tag: @switch) match { diff --git a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala index f96afa9f9d..9b81f58692 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala @@ -18,9 +18,8 @@ private[ir] object Tags { final val TagEmptyTree = 1 final val TagVarDef = TagEmptyTree + 1 - final val TagParamDef = TagVarDef + 1 - final val TagSkip = TagParamDef + 1 + final val TagSkip = TagVarDef + 1 final val TagBlock = TagSkip + 1 final val TagLabeled = TagBlock + 1 final val TagAssign = TagLabeled + 1 @@ -92,11 +91,15 @@ private[ir] object Tags { final val TagThis = TagVarRef + 1 final val TagClosure = TagThis + 1 - final val TagClassDef = TagClosure + 1 - final val TagFieldDef = TagClassDef + 1 + // Tags for member defs + + final val TagFieldDef = 1 final val TagMethodDef = TagFieldDef + 1 final val TagPropertyDef = TagMethodDef + 1 - final val TagTopLevelConstructorExportDef = TagPropertyDef + 1 + + // Tags for top-level export defs + + final val TagTopLevelConstructorExportDef = 1 final val TagTopLevelJSClassExportDef = TagTopLevelConstructorExportDef + 1 final val TagTopLevelModuleExportDef = TagTopLevelJSClassExportDef + 1 final val TagTopLevelMethodExportDef = TagTopLevelModuleExportDef + 1 diff --git a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala index c23f36857f..99e0d05f04 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala @@ -198,32 +198,31 @@ object Transformers { _:LoadJSConstructor | _:LoadJSModule | _:JSLinkingInfo | _:Literal | _:UndefinedParam | _:VarRef | _:This | _:JSGlobalRef => tree - - case _ => - throw new IllegalArgumentException( - s"Invalid tree in transform() of class ${tree.getClass}") } } } abstract class ClassTransformer extends Transformer { def transformClassDef(tree: ClassDef): ClassDef = { - val ClassDef(name, kind, superClass, parents, jsName, defs) = tree - ClassDef(name, kind, superClass, parents, jsName, defs.map(transformDef))( + val ClassDef(name, kind, superClass, parents, jsName, memberDefs, + topLevelExportDefs) = tree + ClassDef(name, kind, superClass, parents, jsName, + memberDefs.map(transformMemberDef), + topLevelExportDefs.map(transformTopLevelExportDef))( tree.optimizerHints)(tree.pos) } - def transformDef(tree: Tree): Tree = { - implicit val pos = tree.pos + def transformMemberDef(memberDef: MemberDef): MemberDef = { + implicit val pos = memberDef.pos - tree match { + memberDef match { case FieldDef(_, _, _, _) => - tree + memberDef - case tree: MethodDef => - val MethodDef(static, name, args, resultType, body) = tree + case memberDef: MethodDef => + val MethodDef(static, name, args, resultType, body) = memberDef MethodDef(static, name, args, resultType, body.map(transformStat))( - tree.optimizerHints, None) + memberDef.optimizerHints, None) case PropertyDef(static, name, getterBody, setterArgAndBody) => PropertyDef( @@ -233,21 +232,25 @@ object Transformers { setterArgAndBody map { case (arg, body) => (arg, transformStat(body)) }) + } + } + + def transformTopLevelExportDef( + exportDef: TopLevelExportDef): TopLevelExportDef = { + + implicit val pos = exportDef.pos + exportDef match { case TopLevelConstructorExportDef(fullName, args, body) => TopLevelConstructorExportDef(fullName, args, transformStat(body)) case _:TopLevelJSClassExportDef | _:TopLevelModuleExportDef | _:TopLevelFieldExportDef => - tree + exportDef case TopLevelMethodExportDef(methodDef) => TopLevelMethodExportDef( - transformDef(methodDef).asInstanceOf[MethodDef]) - - case _ => - throw new IllegalArgumentException( - s"Invalid tree in transformDef() of class ${tree.getClass}") + transformMemberDef(methodDef).asInstanceOf[MethodDef]) } } } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala index f42838ad2d..7605be38f5 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala @@ -194,37 +194,42 @@ object Traversers { traverse(body) captureValues.foreach(traverse) - // Classes + // Trees that need not be traversed - case ClassDef(name, kind, superClass, parents, jsName, defs) => - defs foreach traverse + case _:Skip | _:Continue | _:Debugger | _:LoadModule | _:SelectStatic | + _:LoadJSConstructor | _:LoadJSModule | _:JSLinkingInfo | _:Literal | + _:UndefinedParam | _:VarRef | _:This | _:JSGlobalRef => + } - case MethodDef(static, name, args, resultType, body) => - body.foreach(traverse) + def traverseClassDef(tree: ClassDef): Unit = { + tree.memberDefs.foreach(traverseMemberDef) + tree.topLevelExportDefs.foreach(traverseTopLevelExportDef) + } - case PropertyDef(static, name, getterBody, setterArgAndBody) => - getterBody.foreach(traverse) - setterArgAndBody foreach { case (_, body) => - traverse(body) - } + def traverseMemberDef(memberDef: MemberDef): Unit = { + memberDef match { + case FieldDef(_, _, _, _) => - case TopLevelConstructorExportDef(fullName, args, body) => - traverse(body) + case MethodDef(_, _, _, _, body) => + body.foreach(traverse) - case TopLevelMethodExportDef(methodDef) => - traverse(methodDef) + case PropertyDef(_, _, getterBody, setterArgAndBody) => + getterBody.foreach(traverse) + setterArgAndBody.foreach(argAndBody => traverse(argAndBody._2)) + } + } - // Trees that need not be traversed + def traverseTopLevelExportDef(exportDef: TopLevelExportDef): Unit = { + exportDef match { + case TopLevelConstructorExportDef(fullName, args, body) => + traverse(body) - case _:Skip | _:Continue | _:Debugger | _:LoadModule | _:SelectStatic | - _:LoadJSConstructor | _:LoadJSModule | _:JSLinkingInfo | _:Literal | - _:UndefinedParam | _:VarRef | _:This | _:JSGlobalRef | _:FieldDef | - _:TopLevelJSClassExportDef | _:TopLevelModuleExportDef | - _:TopLevelFieldExportDef => + case _:TopLevelJSClassExportDef | _:TopLevelModuleExportDef | + _:TopLevelFieldExportDef => - case _ => - throw new IllegalArgumentException( - s"Invalid tree in traverse() of class ${tree.getClass}") + case TopLevelMethodExportDef(methodDef) => + traverseMemberDef(methodDef) + } } } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 2e1960f2da..cd6ab8c30c 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -15,35 +15,43 @@ import Position.NoPosition import Types._ object Trees { - /** AST node of the IR. */ - abstract sealed class Tree { - val pos: Position - val tpe: Type + /** Base class for all nodes in the IR. + * + * Usually, one of the direct subclasses of `IRNode` should be used instead. + */ + abstract sealed class IRNode { + def pos: Position def show: String = { val writer = new java.io.StringWriter val printer = new Printers.IRTreePrinter(writer) - printer.print(this) + printer.printAnyNode(this) writer.toString() } } + /** Node for a statement or expression in the IR. */ + abstract sealed class Tree extends IRNode { + val tpe: Type + } + // Identifiers and properties - sealed trait PropertyName { + sealed trait PropertyName extends IRNode { /** Encoded name of this PropertyName within its owner's scope. * * For [[ComputedName]]s, the value of `encodedName` cannot be relied on * beyond equality tests, and the fact that it starts with `"__computed_"`. */ def encodedName: String - - def pos: Position } case class Ident(name: String, originalName: Option[String])( - implicit val pos: Position) extends PropertyName { + implicit val pos: Position) + extends IRNode with PropertyName { + requireValidIdent(name) + def encodedName: String = name } @@ -88,9 +96,13 @@ object Trees { "transient", "volatile" ) - case class ComputedName(tree: Tree, logicalName: String) extends PropertyName { + case class ComputedName(tree: Tree, logicalName: String) + extends IRNode with PropertyName { + requireValidIdent(logicalName) + def pos: Position = tree.pos + override def encodedName: String = "__computed_" + logicalName } @@ -104,9 +116,7 @@ object Trees { } case class ParamDef(name: Ident, ptpe: Type, mutable: Boolean, rest: Boolean)( - implicit val pos: Position) extends Tree { - val tpe = NoType - + implicit val pos: Position) extends IRNode { def ref(implicit pos: Position): VarRef = VarRef(name)(ptpe) } @@ -796,40 +806,36 @@ object Trees { case class ClassDef(name: Ident, kind: ClassKind, superClass: Option[Ident], interfaces: List[Ident], jsNativeLoadSpec: Option[JSNativeLoadSpec], - defs: List[Tree])( + memberDefs: List[MemberDef], topLevelExportDefs: List[TopLevelExportDef])( val optimizerHints: OptimizerHints)( - implicit val pos: Position) extends Tree { - val tpe = NoType - } + implicit val pos: Position) extends IRNode + + // Class members + + sealed abstract class MemberDef extends IRNode case class FieldDef(static: Boolean, name: PropertyName, ftpe: Type, mutable: Boolean)( - implicit val pos: Position) extends Tree { - val tpe = NoType - } + implicit val pos: Position) extends MemberDef case class MethodDef(static: Boolean, name: PropertyName, args: List[ParamDef], resultType: Type, body: Option[Tree])( val optimizerHints: OptimizerHints, val hash: Option[TreeHash])( - implicit val pos: Position) extends Tree { - val tpe = NoType - } + implicit val pos: Position) extends MemberDef case class PropertyDef(static: Boolean, name: PropertyName, getterBody: Option[Tree], setterArgAndBody: Option[(ParamDef, Tree)])( - implicit val pos: Position) extends Tree { - val tpe = NoType - } + implicit val pos: Position) extends MemberDef + + // Top-level export defs + + sealed abstract class TopLevelExportDef extends IRNode case class TopLevelConstructorExportDef(name: String, args: List[ParamDef], - body: Tree)(implicit val pos: Position) extends Tree { - val tpe = NoType - } + body: Tree)(implicit val pos: Position) extends TopLevelExportDef case class TopLevelJSClassExportDef(fullName: String)( - implicit val pos: Position) extends Tree { - val tpe = NoType - } + implicit val pos: Position) extends TopLevelExportDef /** Export for a top-level object. * @@ -837,19 +843,15 @@ object Trees { * The instance is initialized during ES module instantiation. */ case class TopLevelModuleExportDef(fullName: String)( - implicit val pos: Position) extends Tree { - val tpe = NoType - } + implicit val pos: Position) extends TopLevelExportDef case class TopLevelMethodExportDef(methodDef: MethodDef)( - implicit val pos: Position) extends Tree { - val tpe = NoType - } + implicit val pos: Position) extends TopLevelExportDef case class TopLevelFieldExportDef(fullName: String, field: Ident)( - implicit val pos: Position) extends Tree { - val tpe = NoType - } + implicit val pos: Position) extends TopLevelExportDef + + // Miscellaneous final class OptimizerHints(val bits: Int) extends AnyVal { import OptimizerHints._ diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala index bb18d91016..6ac97b35ae 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala @@ -15,8 +15,8 @@ import OptimizerHints.{empty => NoOptHints} class PrintersTest { private implicit val dummyPos = Position.NoPosition - private def assertPrintEquals(expected: String, tree: Tree): Unit = - assertPrintEqualsImpl(expected, _.print(tree)) + private def assertPrintEquals(expected: String, node: IRNode): Unit = + assertPrintEqualsImpl(expected, _.printAnyNode(node)) private def assertPrintEquals(expected: String, tpe: Type): Unit = assertPrintEqualsImpl(expected, _.print(tpe)) @@ -785,7 +785,7 @@ class PrintersTest { import ClassKind._ def makeForKind(kind: ClassKind): ClassDef = { - ClassDef("LTest", kind, Some(ObjectClass), Nil, None, Nil)(NoOptHints) + ClassDef("LTest", kind, Some(ObjectClass), Nil, None, Nil, Nil)(NoOptHints) } assertPrintEquals( @@ -855,7 +855,7 @@ class PrintersTest { @Test def printClassDefParents(): Unit = { def makeForParents(superClass: Option[Ident], interfaces: List[Ident]): ClassDef = { - ClassDef("LTest", ClassKind.Class, superClass, interfaces, None, Nil)( + ClassDef("LTest", ClassKind.Class, superClass, interfaces, None, Nil, Nil)( NoOptHints) } @@ -888,7 +888,7 @@ class PrintersTest { |} """, ClassDef("LTest", ClassKind.NativeJSClass, Some(ObjectClass), Nil, - Some(JSNativeLoadSpec.Global("Foo", List("Bar"))), Nil)( + Some(JSNativeLoadSpec.Global("Foo", List("Bar"))), Nil, Nil)( NoOptHints)) assertPrintEquals( @@ -897,7 +897,7 @@ class PrintersTest { |} """, ClassDef("LTest", ClassKind.NativeJSClass, Some(ObjectClass), Nil, - Some(JSNativeLoadSpec.Import("foo", List("Bar"))), Nil)( + Some(JSNativeLoadSpec.Import("foo", List("Bar"))), Nil, Nil)( NoOptHints)) assertPrintEquals( @@ -908,7 +908,7 @@ class PrintersTest { ClassDef("LTest", ClassKind.NativeJSClass, Some(ObjectClass), Nil, Some(JSNativeLoadSpec.ImportWithGlobalFallback( JSNativeLoadSpec.Import("foo", List("Bar")), - JSNativeLoadSpec.Global("Baz", List("Foobar")))), Nil)( + JSNativeLoadSpec.Global("Baz", List("Foobar")))), Nil, Nil)( NoOptHints)) } @@ -918,22 +918,26 @@ class PrintersTest { |@hints(1) class LTest extends O { |} """, - ClassDef("LTest", ClassKind.Class, Some(ObjectClass), Nil, None, Nil)( + ClassDef("LTest", ClassKind.Class, Some(ObjectClass), Nil, None, Nil, + Nil)( NoOptHints.withInline(true))) } @Test def printClassDefDefs(): Unit = { assertPrintEquals( """ - |class LTest extends O { + |module class LTest extends O { | val x$1: int | var y$1: int + | export top module "pkg.Foo" |} """, - ClassDef("LTest", ClassKind.Class, Some(ObjectClass), Nil, None, + ClassDef("LTest", ClassKind.ModuleClass, Some(ObjectClass), Nil, None, List( FieldDef(static = false, "x$1", IntType, mutable = false), - FieldDef(static = false, "y$1", IntType, mutable = true)))( + FieldDef(static = false, "y$1", IntType, mutable = true)), + List( + TopLevelModuleExportDef("pkg.Foo")))( NoOptHints)) } diff --git a/project/JavaLangObject.scala b/project/JavaLangObject.scala index 954cd4bb94..a5ac168b4c 100644 --- a/project/JavaLangObject.scala +++ b/project/JavaLangObject.scala @@ -161,7 +161,8 @@ object JavaLangObject { Ident("toString__T", Some("toString__T")), Nil)(ClassType(StringClass)) })(OptimizerHints.empty, None) - ))(OptimizerHints.empty) + ), + Nil)(OptimizerHints.empty) val hashedClassedDef = Hashers.hashClassDef(classDef) val info = generateClassInfo(hashedClassedDef) diff --git a/project/JavaLangString.scala b/project/JavaLangString.scala index b0509ec40a..96dea2f81b 100644 --- a/project/JavaLangString.scala +++ b/project/JavaLangString.scala @@ -155,7 +155,8 @@ object JavaLangString { VarRef(Ident("end", Some("end")))(IntType)))( ClassType("jl_CharSequence")) })(OptimizerHints.empty.withInline(true), None) - ))(OptimizerHints.empty) + ), + Nil)(OptimizerHints.empty) val hashedClassDef = Hashers.hashClassDef(classDef) val info = generateClassInfo(hashedClassDef) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 39900500dd..51a4a1ea9e 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -277,7 +277,7 @@ object ScalaJSPluginInternal { if (options.infos) new InfoPrinter(stdout).print(vfile.info) else - new IRTreePrinter(stdout).printTopLevelTree(vfile.tree) + new IRTreePrinter(stdout).print(vfile.tree) stdout.flush() logIRCacheStats(streams.value.log) diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala index 84d7f42a90..819f7267a5 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala @@ -111,7 +111,7 @@ final class ClosureLinkerBackend( private def makeExternsForExports(linkingUnit: LinkingUnit): VirtualJSFile = { import org.scalajs.core.ir.Trees._ - def exportName(tree: Tree): Option[String] = (tree: @unchecked) match { + def exportName(memberDef: MemberDef): Option[String] = memberDef match { case MethodDef(_, StringLiteral(name), _, _, _) => Some(name) case PropertyDef(_, StringLiteral(name), _, _) => Some(name) case _ => None diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala index 81c8b8ea86..c67be0d264 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala @@ -183,8 +183,7 @@ trait VirtualSerializedScalaJSIRFile extends VirtualBinaryFile with VirtualScala val stream = inputStream try { val (version, info) = ir.InfoSerializers.deserializeWithVersion(stream) - val tree = ir.Serializers.deserialize( - stream, version).asInstanceOf[ir.Trees.ClassDef] + val tree = ir.Serializers.deserialize(stream, version) (info, tree) } catch { case e: IOException => diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala index a374b4e65e..44c5051060 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala @@ -44,8 +44,8 @@ final class LinkedClass( val staticMethods: List[LinkedMember[MethodDef]], val memberMethods: List[LinkedMember[MethodDef]], val abstractMethods: List[LinkedMember[MethodDef]], - val exportedMembers: List[LinkedMember[Tree]], - val topLevelExports: List[Tree], + val exportedMembers: List[LinkedMember[MemberDef]], + val topLevelExports: List[TopLevelExportDef], val topLevelExportsInfo: Option[Infos.MethodInfo], val optimizerHints: OptimizerHints, val pos: Position, @@ -62,17 +62,16 @@ final class LinkedClass( def isExported: Boolean = topLevelExports.nonEmpty /** Names of all top-level exports in this class. */ - def topLevelExportNames: List[String] = topLevelExports.map { export => - (export: @unchecked) match { - case TopLevelConstructorExportDef(name, _, _) => name - case TopLevelModuleExportDef(name) => name - case TopLevelJSClassExportDef(name) => name + def topLevelExportNames: List[String] = topLevelExports.map { + case TopLevelConstructorExportDef(name, _, _) => name + case TopLevelModuleExportDef(name) => name + case TopLevelJSClassExportDef(name) => name - case TopLevelMethodExportDef(MethodDef(_, StringLiteral(name), _, _, _)) => - name + case TopLevelMethodExportDef(MethodDef(_, propName, _, _, _)) => + val StringLiteral(name) = propName + name - case TopLevelFieldExportDef(name, _) => name - } + case TopLevelFieldExportDef(name, _) => name } def fullName: String = Definitions.decodeClassName(encodedName) @@ -100,8 +99,8 @@ final class LinkedClass( staticMethods: List[LinkedMember[MethodDef]] = this.staticMethods, memberMethods: List[LinkedMember[MethodDef]] = this.memberMethods, abstractMethods: List[LinkedMember[MethodDef]] = this.abstractMethods, - exportedMembers: List[LinkedMember[Tree]] = this.exportedMembers, - topLevelExports: List[Tree] = this.topLevelExports, + exportedMembers: List[LinkedMember[MemberDef]] = this.exportedMembers, + topLevelExports: List[TopLevelExportDef] = this.topLevelExports, topLevelExportsInfo: Option[Infos.MethodInfo] = this.topLevelExportsInfo, optimizerHints: OptimizerHints = this.optimizerHints, pos: Position = this.pos, diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedMember.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedMember.scala index 4b2b5b188a..1618fa7b30 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedMember.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedMember.scala @@ -23,7 +23,7 @@ import ir.Infos * reliably to determine at phase P+1 whether a linked member coming from * phase P must be reprocessed. */ -final class LinkedMember[+T <: Tree]( +final class LinkedMember[+T <: MemberDef]( val info: Infos.MethodInfo, val tree: T, val version: Option[String] diff --git 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 index 5f1fc0ce19..46e7da3f7b 100644 --- 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 @@ -1719,7 +1719,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { rhs match { case _:Skip | _:VarDef | _:Assign | _:While | _:DoWhile | _:Debugger | _:JSSuperConstructorCall | _:JSDelete | - _:StoreModule | _:ClassDef => + _:StoreModule => transformStat(rhs, tailPosLabels) case _ => throw new IllegalArgumentException( diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index e719f78b54..17fa1294dd 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -1268,21 +1268,21 @@ object IRChecker { * any kind of allocation. * * The parameter is an `Any` for that reason. It should be an - * `Either[Tree, LinkedClass]`, but that would also require an allocation of - * the `Left` or `Right` (in fact, we'd love to type it as - * `Tree | LinkedClass`). `ErrorContext` is also made an `AnyVal` for the + * `Either[IRNode, LinkedClass]`, but that would also require an allocation + * of the `Left` or `Right` (in fact, we'd love to type it as + * `IRNode | LinkedClass`). `ErrorContext` is also made an `AnyVal` for the * same reasons, again. * * If `toString()` is called, we're in a bad situation anyway, because the * IR is invalid, so all bets are off and we can be slow and allocate stuff; * we don't care. */ - private final class ErrorContext private (val treeOrLinkedClass: Any) + private final class ErrorContext private (val nodeOrLinkedClass: Any) extends AnyVal { override def toString(): String = { - val (pos, name) = treeOrLinkedClass match { - case tree: Tree => (tree.pos, tree.getClass.getSimpleName) + val (pos, name) = nodeOrLinkedClass match { + case tree: IRNode => (tree.pos, tree.getClass.getSimpleName) case linkedClass: LinkedClass => (linkedClass.pos, "ClassDef") } s"${pos.source}(${pos.line+1}:${pos.column+1}:$name)" @@ -1290,11 +1290,11 @@ object IRChecker { } private object ErrorContext { - implicit def tree2errorContext(tree: Tree): ErrorContext = - ErrorContext(tree) + implicit def node2errorContext(node: IRNode): ErrorContext = + ErrorContext(node) - def apply(tree: Tree): ErrorContext = - new ErrorContext(tree) + def apply(node: IRNode): ErrorContext = + new ErrorContext(node) def apply(linkedClass: LinkedClass): ErrorContext = new ErrorContext(linkedClass) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index 4b85ad9365..b81cdaae87 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -171,8 +171,8 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, val staticMethods = mutable.Buffer.empty[LinkedMember[MethodDef]] val memberMethods = mutable.Buffer.empty[LinkedMember[MethodDef]] val abstractMethods = mutable.Buffer.empty[LinkedMember[MethodDef]] - val exportedMembers = mutable.Buffer.empty[LinkedMember[Tree]] - val topLevelExports = mutable.Buffer.empty[Tree] + val exportedMembers = mutable.Buffer.empty[LinkedMember[MemberDef]] + val topLevelExports = mutable.Buffer.empty[TopLevelExportDef] def linkedMethod(m: MethodDef) = { val info = memberInfoByStaticAndName((m.static, m.name.encodedName)) @@ -191,7 +191,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, new LinkedMember(info, m, version) } - classDef.defs.foreach { + classDef.memberDefs.foreach { // Static methods case m: MethodDef if m.static => if (analyzerInfo.staticMethodInfos(m.name.encodedName).isReachable) { @@ -222,25 +222,6 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, case m: PropertyDef => if (analyzerInfo.isAnySubclassInstantiated) exportedMembers += linkedProperty(m) - - case e: TopLevelConstructorExportDef => - topLevelExports += e - - case e: TopLevelJSClassExportDef => - topLevelExports += e - - case e: TopLevelModuleExportDef => - topLevelExports += e - - case e: TopLevelMethodExportDef => - topLevelExports += e - - case e: TopLevelFieldExportDef => - topLevelExports += e - - case tree => - throw new IllegalArgumentException( - s"Illegal tree in ClassDef of class ${tree.getClass}") } // Synthetic members @@ -284,7 +265,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, memberMethods.toList, abstractMethods.toList, exportedMembers.toList, - topLevelExports.toList, + classDef.topLevelExportDefs, topLevelExportInfo, classDef.optimizerHints, classDef.pos, @@ -389,7 +370,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, private def findMethodDef(classInfo: Analysis.ClassInfo, methodName: String, getTree: TreeProvider): MethodDef = { val (classDef, _) = getTree(classInfo.encodedName) - classDef.defs.collectFirst { + classDef.memberDefs.collectFirst { case mDef: MethodDef if !mDef.static && mDef.name.encodedName == methodName => mDef }.getOrElse { From 08665f8f971a002cd1c55d17cfc983a559bb37cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 9 Jul 2017 22:05:25 +0200 Subject: [PATCH 0406/2665] Rename `ReferenceType` to `TypeRef`, make it distinct from `Type`. This just makes sense. It should have been like that since the beginning. Their usages are distinct, and `ClassType`s cannot in general be converted to/from `ClassRef`s, so using the same class for both was complete nonsense. --- .../org/scalajs/core/compiler/GenJSCode.scala | 21 ++-- .../scalajs/core/compiler/GenJSExports.scala | 2 +- .../org/scalajs/core/compiler/TypeKinds.scala | 26 ++--- .../org/scalajs/core/ir/Definitions.scala | 14 +-- .../scala/org/scalajs/core/ir/Hashers.scala | 27 +++-- .../scala/org/scalajs/core/ir/Infos.scala | 34 +++--- .../scala/org/scalajs/core/ir/Printers.scala | 32 ++--- .../org/scalajs/core/ir/Serializers.scala | 45 +++++--- .../main/scala/org/scalajs/core/ir/Tags.scala | 5 + .../scala/org/scalajs/core/ir/Trees.scala | 17 +-- .../scala/org/scalajs/core/ir/Types.scala | 82 +++++++------ .../org/scalajs/core/ir/PrintersTest.scala | 34 ++++-- project/JavaLangObject.scala | 2 +- project/JavaLangString.scala | 2 +- .../core/tools/linker/analyzer/Analysis.scala | 6 +- .../core/tools/linker/analyzer/Analyzer.scala | 14 +-- .../linker/backend/emitter/ClassEmitter.scala | 5 +- .../backend/emitter/FunctionEmitter.scala | 3 +- .../tools/linker/backend/emitter/JSGen.scala | 26 ++--- .../core/tools/linker/checker/IRChecker.scala | 23 ++-- .../frontend/optimizer/OptimizerCore.scala | 109 ++++++++++-------- 21 files changed, 305 insertions(+), 224 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index efa4e58c40..51c3f6f82b 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -946,7 +946,7 @@ abstract class GenJSCode extends plugins.PluginComponent private def genRegisterReflectiveInstantiationForModuleClass(sym: Symbol)( implicit pos: Position): Option[js.Tree] = { val fqcnArg = js.StringLiteral(sym.fullName + "$") - val runtimeClassArg = js.ClassOf(toReferenceType(sym.info)) + val runtimeClassArg = js.ClassOf(toTypeRef(sym.info)) val loadModuleFunArg = js.Closure(Nil, Nil, genLoadModule(sym), Nil) val stat = genApplyMethod( @@ -989,7 +989,7 @@ abstract class GenJSCode extends plugins.PluginComponent * parameter types is `List(classOf[Int])`, and when invoked * reflectively, it must be given an `Int` (or `Integer`). */ - val paramType = js.ClassOf(toReferenceType(param.tpe)) + val paramType = js.ClassOf(toTypeRef(param.tpe)) val paramDef = js.ParamDef(encodeLocalSym(param), jstpe.AnyType, mutable = false, rest = false) val actualParam = fromAny(paramDef.ref, param.tpe) @@ -1007,7 +1007,7 @@ abstract class GenJSCode extends plugins.PluginComponent } val fqcnArg = js.StringLiteral(sym.fullName) - val runtimeClassArg = js.ClassOf(toReferenceType(sym.info)) + val runtimeClassArg = js.ClassOf(toTypeRef(sym.info)) val ctorsInfosArg = js.JSArrayConstr(constructorsInfos) val stat = genApplyMethod( @@ -1906,7 +1906,7 @@ abstract class GenJSCode extends plugins.PluginComponent case NullTag => js.Null() case ClazzTag => - js.ClassOf(toReferenceType(value.typeValue)) + js.ClassOf(toTypeRef(value.typeValue)) case EnumTag => genStaticMember(value.symbolValue) } @@ -2660,7 +2660,7 @@ abstract class GenJSCode extends plugins.PluginComponent js.JSBinaryOp.instanceof, value, genPrimitiveJSClass(sym)), 'Z') } } else { - js.IsInstanceOf(value, toReferenceType(to)) + js.IsInstanceOf(value, toTypeRef(to)) } } @@ -2669,7 +2669,7 @@ abstract class GenJSCode extends plugins.PluginComponent implicit pos: Position): js.Tree = { def default: js.Tree = - js.AsInstanceOf(value, toReferenceType(to)) + js.AsInstanceOf(value, toTypeRef(to)) val sym = to.typeSymbol @@ -2756,9 +2756,10 @@ abstract class GenJSCode extends plugins.PluginComponent */ def genNewArray(arrayType: jstpe.ArrayType, arguments: List[js.Tree])( implicit pos: Position): js.Tree = { - assert(arguments.length <= arrayType.dimensions, + assert(arguments.length <= arrayType.arrayTypeRef.dimensions, "too many arguments for array constructor: found " + arguments.length + - " but array has only " + arrayType.dimensions + " dimension(s)") + " but array has only " + arrayType.arrayTypeRef.dimensions + + " dimension(s)") js.NewArray(arrayType, arguments) } @@ -2769,8 +2770,8 @@ abstract class GenJSCode extends plugins.PluginComponent implicit val pos = tree.pos val ArrayValue(tpt @ TypeTree(), elems) = tree - val arrType = toReferenceType(tree.tpe).asInstanceOf[jstpe.ArrayType] - js.ArrayValue(arrType, elems map genExpr) + val arrayTypeRef = toTypeRef(tree.tpe).asInstanceOf[jstpe.ArrayTypeRef] + js.ArrayValue(jstpe.ArrayType(arrayTypeRef), elems map genExpr) } /** Gen JS code for a Match, i.e., a switch-able pattern match. diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index 1a7fb411f7..768f464d2d 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -537,7 +537,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => val optCond = typeTest match { case HijackedTypeTest(boxedClassName, _) => - Some(js.IsInstanceOf(paramRef, jstpe.ClassType(boxedClassName))) + Some(js.IsInstanceOf(paramRef, jstpe.ClassRef(boxedClassName))) case InstanceOfTypeTest(tpe) => Some(genIsInstanceOf(paramRef, tpe)) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/TypeKinds.scala b/compiler/src/main/scala/org/scalajs/core/compiler/TypeKinds.scala index 0766a92281..b317962ff2 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/TypeKinds.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/TypeKinds.scala @@ -57,14 +57,14 @@ trait TypeKinds extends SubComponent { this: GenJSCode => def isValueType: Boolean = false def toIRType: Types.Type - def toReferenceType: Types.ReferenceType + def toTypeRef: Types.TypeRef } sealed abstract class TypeKindButArray extends TypeKind { protected def typeSymbol: Symbol - override def toReferenceType: Types.ClassType = - Types.ClassType(encodeClassFullName(typeSymbol)) + override def toTypeRef: Types.ClassRef = + Types.ClassRef(encodeClassFullName(typeSymbol)) } /** The void, for trees that can only appear in statement position. */ @@ -117,16 +117,16 @@ trait TypeKinds extends SubComponent { this: GenJSCode => case object NOTHING extends TypeKindButArray { protected def typeSymbol: Symbol = definitions.NothingClass def toIRType: Types.NothingType.type = Types.NothingType - override def toReferenceType: Types.ClassType = - Types.ClassType(Definitions.RuntimeNothingClass) + override def toTypeRef: Types.ClassRef = + Types.ClassRef(Definitions.RuntimeNothingClass) } /** Null */ case object NULL extends TypeKindButArray { protected def typeSymbol: Symbol = definitions.NullClass def toIRType: Types.NullType.type = Types.NullType - override def toReferenceType: Types.ClassType = - Types.ClassType(Definitions.RuntimeNullClass) + override def toTypeRef: Types.ClassRef = + Types.ClassRef(Definitions.RuntimeNullClass) } /** An object */ @@ -147,11 +147,11 @@ trait TypeKinds extends SubComponent { this: GenJSCode => case _ => 1 } - override def toIRType: Types.ArrayType = toReferenceType + override def toIRType: Types.ArrayType = Types.ArrayType(toTypeRef) - override def toReferenceType: Types.ArrayType = { - Types.ArrayType( - elementKind.toReferenceType.className, + override def toTypeRef: Types.ArrayTypeRef = { + Types.ArrayTypeRef( + elementKind.toTypeRef.className, dimensions) } @@ -167,8 +167,8 @@ trait TypeKinds extends SubComponent { this: GenJSCode => def toIRType(t: Type): Types.Type = toTypeKind(t).toIRType - def toReferenceType(t: Type): Types.ReferenceType = - toTypeKind(t).toReferenceType + def toTypeRef(t: Type): Types.TypeRef = + toTypeKind(t).toTypeRef // The following code is a hard copy-and-paste from backend.icode.TypeKinds diff --git a/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala b/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala index b84ebb7d7b..532dba795a 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala @@ -155,7 +155,7 @@ object Definitions { * information from `encodedName.indexOf("__p") >= 0`. */ def decodeMethodName( - encodedName: String): (String, List[ReferenceType], Option[ReferenceType]) = { + encodedName: String): (String, List[TypeRef], Option[TypeRef]) = { val (simpleName, privateAndSigString) = if (isConstructorName(encodedName)) { val privateAndSigString = if (encodedName == "init___") "" @@ -179,22 +179,22 @@ object Definitions { val paramStrings :+ resultString = paramsAndResultStrings - val paramTypes = paramStrings.map(decodeReferenceType).toList + val paramTypes = paramStrings.map(decodeTypeRef).toList val resultType = if (resultString == "") None // constructor or reflective proxy - else Some(decodeReferenceType(resultString)) + else Some(decodeTypeRef(resultString)) (simpleName, paramTypes, resultType) } - /** Decodes a [[Types.ReferenceType]], such as in an encoded method signature. + /** Decodes a [[Types.TypeRef]], such as in an encoded method signature. */ - def decodeReferenceType(encodedName: String): ReferenceType = { + def decodeTypeRef(encodedName: String): TypeRef = { val arrayDepth = encodedName.indexWhere(_ != 'A') if (arrayDepth == 0) - ClassType(encodedName) + ClassRef(encodedName) else - ArrayType(encodedName.substring(arrayDepth), arrayDepth) + ArrayTypeRef(encodedName.substring(arrayDepth), arrayDepth) } /* Common predicates on encoded names */ diff --git a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala index 0b502392b5..6921085372 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala @@ -271,12 +271,12 @@ object Hashers { case IsInstanceOf(expr, cls) => mixTag(TagIsInstanceOf) mixTree(expr) - mixRefType(cls) + mixTypeRef(cls) case AsInstanceOf(expr, cls) => mixTag(TagAsInstanceOf) mixTree(expr) - mixRefType(cls) + mixTypeRef(cls) case Unbox(expr, charCode) => mixTag(TagUnbox) @@ -423,7 +423,7 @@ object Hashers { case ClassOf(cls) => mixTag(TagClassOf) - mixRefType(cls) + mixTypeRef(cls) case VarRef(ident) => mixTag(TagVarRef) @@ -450,8 +450,15 @@ object Hashers { def mixTrees(trees: List[Tree]): Unit = trees.foreach(mixTree) - def mixRefType(tpe: ReferenceType): Unit = - mixType(tpe.asInstanceOf[Type]) + def mixTypeRef(typeRef: TypeRef): Unit = typeRef match { + case ClassRef(className) => + mixTag(TagClassRef) + mixString(className) + case ArrayTypeRef(baseClassName, dimensions) => + mixTag(TagArrayTypeRef) + mixString(baseClassName) + mixInt(dimensions) + } def mixType(tpe: Type): Unit = tpe match { case AnyType => mixTag(TagAnyType) @@ -466,14 +473,14 @@ object Hashers { case NullType => mixTag(TagNullType) case NoType => mixTag(TagNoType) - case tpe: ClassType => + case ClassType(className) => mixTag(TagClassType) - mixString(tpe.className) + mixString(className) - case tpe: ArrayType => + case ArrayType(ArrayTypeRef(baseClassName, dimensions)) => mixTag(TagArrayType) - mixString(tpe.baseClassName) - mixInt(tpe.dimensions) + mixString(baseClassName) + mixInt(dimensions) case RecordType(fields) => mixTag(TagRecordType) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala index 302141412b..18321c209a 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala @@ -199,16 +199,16 @@ object Infos { def addMethodCalled(receiverTpe: Type, method: String): this.type = { receiverTpe match { - case ClassType(cls) => addMethodCalled(cls, method) - case AnyType => addMethodCalled(ObjectClass, method) - case UndefType => addMethodCalled(BoxedUnitClass, method) - case BooleanType => addMethodCalled(BoxedBooleanClass, method) - case IntType => addMethodCalled(BoxedIntegerClass, method) - case LongType => addMethodCalled(BoxedLongClass, method) - case FloatType => addMethodCalled(BoxedFloatClass, method) - case DoubleType => addMethodCalled(BoxedDoubleClass, method) - case StringType => addMethodCalled(StringClass, method) - case ArrayType(_, _) => addMethodCalled(PseudoArrayClass, method) + case ClassType(cls) => addMethodCalled(cls, method) + case AnyType => addMethodCalled(ObjectClass, method) + case UndefType => addMethodCalled(BoxedUnitClass, method) + case BooleanType => addMethodCalled(BoxedBooleanClass, method) + case IntType => addMethodCalled(BoxedIntegerClass, method) + case LongType => addMethodCalled(BoxedLongClass, method) + case FloatType => addMethodCalled(BoxedFloatClass, method) + case DoubleType => addMethodCalled(BoxedDoubleClass, method) + case StringType => addMethodCalled(StringClass, method) + case ArrayType(_) => addMethodCalled(PseudoArrayClass, method) case NullType | NothingType => // Nothing to do @@ -249,7 +249,7 @@ object Infos { this } - def addUsedInstanceTest(tpe: ReferenceType): this.type = + def addUsedInstanceTest(tpe: TypeRef): this.type = addUsedInstanceTest(baseNameOf(tpe)) def addUsedInstanceTest(cls: String): this.type = { @@ -257,7 +257,7 @@ object Infos { this } - def addAccessedClassData(tpe: ReferenceType): this.type = + def addAccessedClassData(tpe: TypeRef): this.type = addAccessedClassData(baseNameOf(tpe)) def addAccessedClassData(cls: String): this.type = { @@ -265,9 +265,9 @@ object Infos { this } - private def baseNameOf(tpe: ReferenceType): String = tpe match { - case ClassType(name) => name - case ArrayType(base, _) => base + private def baseNameOf(tpe: TypeRef): String = tpe match { + case ClassRef(name) => name + case ArrayTypeRef(base, _) => base } def result(): MethodInfo = { @@ -452,9 +452,9 @@ object Infos { builder.addUsedInstanceTest(tpe) case NewArray(tpe, _) => - builder.addAccessedClassData(tpe) + builder.addAccessedClassData(tpe.arrayTypeRef) case ArrayValue(tpe, _) => - builder.addAccessedClassData(tpe) + builder.addAccessedClassData(tpe.arrayTypeRef) case ClassOf(cls) => builder.addAccessedClassData(cls) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index f6ded00e97..5370c70527 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -444,13 +444,13 @@ object Printers { case NewArray(tpe, lengths) => print("new ") - print(tpe.baseClassName) + print(tpe.arrayTypeRef.baseClassName) for (length <- lengths) { print('[') print(length) print(']') } - for (dim <- lengths.size until tpe.dimensions) + for (dim <- lengths.size until tpe.arrayTypeRef.dimensions) print("[]") case ArrayValue(tpe, elems) => @@ -479,16 +479,16 @@ object Printers { } print(')') - case IsInstanceOf(expr, cls) => + case IsInstanceOf(expr, typeRef) => print(expr) print(".isInstanceOf[") - printRefType(cls) + print(typeRef) print(']') - case AsInstanceOf(expr, cls) => + case AsInstanceOf(expr, typeRef) => print(expr) print(".asInstanceOf[") - printRefType(cls) + print(typeRef) print(']') case Unbox(expr, charCode) => @@ -735,9 +735,9 @@ object Printers { printEscapeJS(value, out) print('\"') - case ClassOf(cls) => + case ClassOf(typeRef) => print("classOf[") - printRefType(cls) + print(typeRef) print(']') // Specials @@ -893,8 +893,14 @@ object Printers { } } - def printRefType(tpe: ReferenceType): Unit = - print(tpe.asInstanceOf[Type]) + def print(tpe: TypeRef): Unit = tpe match { + case ClassRef(className) => + print(className) + case ArrayTypeRef(base, dims) => + print(base) + for (i <- 1 to dims) + print("[]") + } def print(tpe: Type): Unit = tpe match { case AnyType => print("any") @@ -910,10 +916,8 @@ object Printers { case ClassType(className) => print(className) case NoType => print("") - case ArrayType(base, dims) => - print(base) - for (i <- 1 to dims) - print("[]") + case ArrayType(arrayTypeRef) => + print(arrayTypeRef) case RecordType(fields) => print('(') diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index de71b2a748..a5a1b839bd 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -243,13 +243,13 @@ object Serializers { writeByte(TagRecordValue) writeType(tpe); writeTrees(elems) - case IsInstanceOf(expr, cls) => + case IsInstanceOf(expr, typeRef) => writeByte(TagIsInstanceOf) - writeTree(expr); writeReferenceType(cls) + writeTree(expr); writeTypeRef(typeRef) - case AsInstanceOf(expr, cls) => + case AsInstanceOf(expr, typeRef) => writeByte(TagAsInstanceOf) - writeTree(expr); writeReferenceType(cls) + writeTree(expr); writeTypeRef(typeRef) case Unbox(expr, charCode) => writeByte(TagUnbox) @@ -372,9 +372,9 @@ object Serializers { writeByte(TagStringLiteral) writeString(value) - case ClassOf(cls) => + case ClassOf(typeRef) => writeByte(TagClassOf) - writeReferenceType(cls) + writeTypeRef(typeRef) case UndefinedParam() => writeByte(TagUndefinedParam) @@ -576,12 +576,19 @@ object Serializers { writeString(tpe.className) def writeArrayType(tpe: ArrayType): Unit = { - writeString(tpe.baseClassName) - buffer.writeInt(tpe.dimensions) + writeString(tpe.arrayTypeRef.baseClassName) + buffer.writeInt(tpe.arrayTypeRef.dimensions) } - def writeReferenceType(tpe: ReferenceType): Unit = - writeType(tpe.asInstanceOf[Type]) + def writeTypeRef(tpe: TypeRef): Unit = tpe match { + case ClassRef(className) => + buffer.writeByte(TagClassRef) + writeString(className) + case ArrayTypeRef(baseClassName, dimensions) => + buffer.writeByte(TagArrayTypeRef) + writeString(baseClassName) + buffer.writeInt(dimensions) + } def writePropertyName(name: PropertyName): Unit = name match { case name: Ident => @@ -765,8 +772,8 @@ object Serializers { case TagArrayLength => ArrayLength(readTree()) case TagArraySelect => ArraySelect(readTree(), readTree())(readType()) case TagRecordValue => RecordValue(readType().asInstanceOf[RecordType], readTrees()) - case TagIsInstanceOf => IsInstanceOf(readTree(), readReferenceType()) - case TagAsInstanceOf => AsInstanceOf(readTree(), readReferenceType()) + case TagIsInstanceOf => IsInstanceOf(readTree(), readTypeRef()) + case TagAsInstanceOf => AsInstanceOf(readTree(), readTypeRef()) case TagUnbox => Unbox(readTree(), readByte().toChar) case TagGetClass => GetClass(readTree()) case TagCallHelper => CallHelper(readString(), readTrees())(readType()) @@ -801,7 +808,7 @@ object Serializers { case TagFloatLiteral => FloatLiteral(readFloat()) case TagDoubleLiteral => DoubleLiteral(readDouble()) case TagStringLiteral => StringLiteral(readString()) - case TagClassOf => ClassOf(readReferenceType()) + case TagClassOf => ClassOf(readTypeRef()) case TagUndefinedParam => UndefinedParam()(readType()) case TagVarRef => VarRef(readIdent())(readType()) @@ -951,10 +958,16 @@ object Serializers { ClassType(readString()) def readArrayType(): ArrayType = - ArrayType(readString(), input.readInt()) + ArrayType(ArrayTypeRef(readString(), input.readInt())) - def readReferenceType(): ReferenceType = - readType().asInstanceOf[ReferenceType] + def readTypeRef(): TypeRef = { + input.readByte() match { + case TagClassRef => + ClassRef(readString()) + case TagArrayTypeRef => + ArrayTypeRef(readString(), input.readInt()) + } + } def readPropertyName(): PropertyName = { input.readByte() match { diff --git a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala index 9b81f58692..7784a33873 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala @@ -122,6 +122,11 @@ private[ir] object Tags { final val TagRecordType = TagArrayType + 1 final val TagNoType = TagRecordType + 1 + // Tags for TypeRefs + + final val TagClassRef = 1 + final val TagArrayTypeRef = TagClassRef + 1 + // Tags for PropertyNames final val TagPropertyNameIdent = 1 diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index cd6ab8c30c..01af0ca8c1 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -384,7 +384,7 @@ object Trees { case class NewArray(tpe: ArrayType, lengths: List[Tree])( implicit val pos: Position) extends Tree { - require(lengths.nonEmpty && lengths.size <= tpe.dimensions) + require(lengths.nonEmpty && lengths.size <= tpe.arrayTypeRef.dimensions) } case class ArrayValue(tpe: ArrayType, elems: List[Tree])( @@ -400,17 +400,18 @@ object Trees { case class RecordValue(tpe: RecordType, elems: List[Tree])( implicit val pos: Position) extends Tree - case class IsInstanceOf(expr: Tree, cls: ReferenceType)( + case class IsInstanceOf(expr: Tree, typeRef: TypeRef)( implicit val pos: Position) extends Tree { val tpe = BooleanType } - case class AsInstanceOf(expr: Tree, cls: ReferenceType)( + case class AsInstanceOf(expr: Tree, typeRef: TypeRef)( implicit val pos: Position) extends Tree { - val tpe = cls match { - case ClassType(Definitions.RuntimeNullClass) => NullType - case ClassType(Definitions.RuntimeNothingClass) => NothingType - case _ => cls.asInstanceOf[Type] + val tpe = typeRef match { + case ClassRef(Definitions.RuntimeNullClass) => NullType + case ClassRef(Definitions.RuntimeNothingClass) => NothingType + case ClassRef(className) => ClassType(className) + case typeRef: ArrayTypeRef => ArrayType(typeRef) } } @@ -776,7 +777,7 @@ object Trees { override def encodedName: String = value } - case class ClassOf(cls: ReferenceType)( + case class ClassOf(typeRef: TypeRef)( implicit val pos: Position) extends Literal { val tpe = ClassType(Definitions.ClassClass) } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Types.scala b/ir/src/main/scala/org/scalajs/core/ir/Types.scala index 8411b69be9..b5851bd8ce 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Types.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Types.scala @@ -15,16 +15,16 @@ import Trees._ object Types { - /** Type of an term (expression or statement) in the IR. + /** Type of a term (expression or statement) in the IR. * - * There is a many-to-one relationship from [[ReferenceType]]s to types, + * There is a many-to-one relationship from [[TypeRef]]s to `Type`s, * because: * * - `scala.Byte`, `scala.Short` and `scala.Int` collapse to [[IntType]] * - `java.lang.Object` and raw JS types all collapse to [[AnyType]] * * In fact, there are two `Type`s that do not have any real equivalent in - * reference types: [[StringType]] and [[UndefType]], as they refer to the + * type refs: [[StringType]] and [[UndefType]], as they refer to the * non-null variants of `java.lang.String` and `scala.runtime.BoxedUnit`, * respectively. */ @@ -95,36 +95,11 @@ object Types { */ case object NullType extends Type - /** Reference types (allowed for classOf[], is/asInstanceOf[]). - * - * A `ReferenceType` has exactly the same level of precision as a JVM type. - * There is a one-to-one relationship between a `ReferenceType` and an - * instance of `java.lang.Class` at run-time. This means that: - * - * - All primitive types have their reference type (including `scala.Byte` - * and `scala.Short`), and they are different from their boxed versions. - * - Raw JS types are not erased to `any` - * - Array types are like on the JVM - * - * A `ReferenceType` therefore uniquely identifies a `classOf[T]`. It is - * also the reference types that are used in method signatures, and which - * therefore dictate JVM/IR overloading. - */ - sealed trait ReferenceType - /** Class (or interface) type. */ - final case class ClassType(className: String) extends Type with ReferenceType + final case class ClassType(className: String) extends Type /** Array type. */ - final case class ArrayType(baseClassName: String, dimensions: Int) - extends Type with ReferenceType - - object ArrayType { - def apply(innerType: ReferenceType): ArrayType = innerType match { - case ClassType(className) => ArrayType(className, 1) - case ArrayType(className, dim) => ArrayType(className, dim + 1) - } - } + final case class ArrayType(arrayTypeRef: ArrayTypeRef) extends Type /** Record type. * Used by the optimizer to inline classes as records with multiple fields. @@ -146,6 +121,44 @@ object Types { /** No type. */ case object NoType extends Type + /** Type reference (allowed for classOf[], is/asInstanceOf[]). + * + * A `TypeRef` has exactly the same level of precision as a JVM type. + * There is a one-to-one relationship between a `TypeRef` and an instance of + * `java.lang.Class` at run-time. This means that: + * + * - All primitive types have their `TypeRef` (including `scala.Byte` and + * `scala.Short`), and they are different from their boxed versions. + * - Raw JS types are not erased to `any` + * - Array types are like on the JVM + * + * A `TypeRef` therefore uniquely identifies a `classOf[T]`. It is also the + * type refs that are used in method signatures, and which therefore dictate + * JVM/IR overloading. + */ + sealed abstract class TypeRef { + def show(): String = { + val writer = new java.io.StringWriter + val printer = new Printers.IRTreePrinter(writer) + printer.print(this) + writer.toString() + } + } + + /** Class (or interface) type. */ + final case class ClassRef(className: String) extends TypeRef + + /** Array type. */ + final case class ArrayTypeRef(baseClassName: String, dimensions: Int) + extends TypeRef + + object ArrayTypeRef { + def of(innerType: TypeRef): ArrayTypeRef = innerType match { + case ClassRef(className) => ArrayTypeRef(className, 1) + case ArrayTypeRef(className, dim) => ArrayTypeRef(className, dim + 1) + } + } + /** Generates a literal zero of the given type. */ def zeroOf(tpe: Type)(implicit pos: Position): Literal = tpe match { case BooleanType => BooleanLiteral(false) @@ -177,8 +190,8 @@ object Types { case (ClassType(lhsClass), ClassType(rhsClass)) => isSubclass(lhsClass, rhsClass) - case (NullType, ClassType(_)) => true - case (NullType, ArrayType(_, _)) => true + case (NullType, ClassType(_)) => true + case (NullType, ArrayType(_)) => true case (UndefType, ClassType(cls)) => isSubclass(BoxedUnitClass, cls) @@ -202,7 +215,8 @@ object Types { case (IntType, DoubleType) => true case (FloatType, DoubleType) => true - case (ArrayType(lhsBase, lhsDims), ArrayType(rhsBase, rhsDims)) => + case (ArrayType(ArrayTypeRef(lhsBase, lhsDims)), + ArrayType(ArrayTypeRef(rhsBase, rhsDims))) => if (lhsDims < rhsDims) { false // because Array[A] rhsDims) { @@ -220,7 +234,7 @@ object Types { } } - case (ArrayType(_, _), ClassType(cls)) => + case (ArrayType(_), ClassType(cls)) => AncestorsOfPseudoArrayClass.contains(cls) case _ => diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala index 6ac97b35ae..f9fc461963 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala @@ -21,6 +21,9 @@ class PrintersTest { private def assertPrintEquals(expected: String, tpe: Type): Unit = assertPrintEqualsImpl(expected, _.print(tpe)) + private def assertPrintEquals(expected: String, typeRef: TypeRef): Unit = + assertPrintEqualsImpl(expected, _.print(typeRef)) + private def assertPrintEqualsImpl(expected: String, print: IRTreePrinter => Unit): Unit = { val sw = new java.io.StringWriter @@ -31,6 +34,7 @@ class PrintersTest { private implicit def string2ident(name: String): Ident = Ident(name) private implicit def string2classType(cls: String): ClassType = ClassType(cls) + private implicit def string2classRef(cls: String): ClassRef = ClassRef(cls) private def b(value: Boolean): BooleanLiteral = BooleanLiteral(value) private def i(value: Int): IntLiteral = IntLiteral(value) @@ -40,6 +44,9 @@ class PrintersTest { private def ref(ident: Ident, tpe: Type): VarRef = VarRef(ident)(tpe) + private def arrayType(baseClassName: String, dimensions: Int): ArrayType = + ArrayType(ArrayTypeRef(baseClassName, dimensions)) + @Test def printType(): Unit = { assertPrintEquals("any", AnyType) assertPrintEquals("nothing", NothingType) @@ -55,8 +62,8 @@ class PrintersTest { assertPrintEquals("O", ClassType(ObjectClass)) - assertPrintEquals("O[]", ArrayType(ObjectClass, 1)) - assertPrintEquals("I[][]", ArrayType("I", 2)) + assertPrintEquals("O[]", arrayType(ObjectClass, 1)) + assertPrintEquals("I[][]", arrayType("I", 2)) assertPrintEquals("(x: int, var y: any)", RecordType(List( @@ -64,6 +71,13 @@ class PrintersTest { RecordType.Field("y", None, AnyType, mutable = true)))) } + @Test def printTypeRef(): Unit = { + assertPrintEquals("O", ClassRef(ObjectClass)) + + assertPrintEquals("O[]", ArrayTypeRef(ObjectClass, 1)) + assertPrintEquals("I[][]", ArrayTypeRef("I", 2)) + } + @Test def printVarDef(): Unit = { assertPrintEquals("val x: int = 5", VarDef("x", IntType, mutable = false, i(5))) @@ -460,29 +474,29 @@ class PrintersTest { } @Test def printNewArray(): Unit = { - assertPrintEquals("new I[3]", NewArray(ArrayType("I", 1), List(i(3)))) - assertPrintEquals("new I[3][]", NewArray(ArrayType("I", 2), List(i(3)))) + assertPrintEquals("new I[3]", NewArray(arrayType("I", 1), List(i(3)))) + assertPrintEquals("new I[3][]", NewArray(arrayType("I", 2), List(i(3)))) assertPrintEquals("new O[3][4][][]", - NewArray(ArrayType("O", 4), List(i(3), i(4)))) + NewArray(arrayType("O", 4), List(i(3), i(4)))) } @Test def printArrayValue(): Unit = { assertPrintEquals("I[]()", - ArrayValue(ArrayType("I", 1), List())) + ArrayValue(arrayType("I", 1), List())) assertPrintEquals("I[](5, 6)", - ArrayValue(ArrayType("I", 1), List(i(5), i(6)))) + ArrayValue(arrayType("I", 1), List(i(5), i(6)))) assertPrintEquals("I[][](null)", - ArrayValue(ArrayType("I", 2), List(Null()))) + ArrayValue(arrayType("I", 2), List(Null()))) } @Test def printArrayLength(): Unit = { - assertPrintEquals("x.length", ArrayLength(ref("x", ArrayType("I", 1)))) + assertPrintEquals("x.length", ArrayLength(ref("x", arrayType("I", 1)))) } @Test def printArraySelect(): Unit = { assertPrintEquals("x[3]", - ArraySelect(ref("x", ArrayType("I", 1)), i(3))(IntType)) + ArraySelect(ref("x", arrayType("I", 1)), i(3))(IntType)) } @Test def printRecordValue(): Unit = { diff --git a/project/JavaLangObject.scala b/project/JavaLangObject.scala index a5ac168b4c..9664c6caeb 100644 --- a/project/JavaLangObject.scala +++ b/project/JavaLangObject.scala @@ -85,7 +85,7 @@ object JavaLangObject { Nil, AnyType, Some { - If(IsInstanceOf(This()(ThisType), ClassType("jl_Cloneable")), { + If(IsInstanceOf(This()(ThisType), ClassRef("jl_Cloneable")), { Apply(LoadModule(ClassType("sjsr_package$")), Ident("cloneObject__sjs_js_Object__sjs_js_Object", Some("cloneObject")), List(This()(ThisType)))(AnyType) diff --git a/project/JavaLangString.scala b/project/JavaLangString.scala index 96dea2f81b..07920b10b3 100644 --- a/project/JavaLangString.scala +++ b/project/JavaLangString.scala @@ -88,7 +88,7 @@ object JavaLangString { Ident("compareTo__T__I", Some("compareTo__T__I")), List(AsInstanceOf( VarRef(Ident("that", Some("that")))(AnyType), - ThisType)))(IntType) + ClassRef(StringClass))))(IntType) })(OptimizerHints.empty.withInline(true), None), /* def toString(): String = this */ diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala index d8f0d88c9a..257ac6b70e 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala @@ -94,9 +94,9 @@ object Analysis { } else { import ir.Types._ - def typeDisplayName(tpe: ReferenceType): String = tpe match { - case ClassType(encodedName) => decodeClassName(encodedName) - case ArrayType(base, dimensions) => "[" * dimensions + decodeClassName(base) + def typeDisplayName(tpe: TypeRef): String = tpe match { + case ClassRef(encodedName) => decodeClassName(encodedName) + case ArrayTypeRef(base, dimensions) => "[" * dimensions + decodeClassName(base) } val (simpleName, paramTypes, resultType) = diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala index 34c0bb5b7c..65551f46ce 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala @@ -462,11 +462,11 @@ private final class Analyzer(semantics: Semantics, sepPos >= 0 && methodName.substring(0, sepPos + 2) == proxyName } - private def methodResultType(methodName: String): ir.Types.ReferenceType = - decodeReferenceType(methodName.substring(methodName.lastIndexOf("__") + 2)) + private def methodResultType(methodName: String): ir.Types.TypeRef = + decodeTypeRef(methodName.substring(methodName.lastIndexOf("__") + 2)) - private def isMoreSpecific(left: ir.Types.ReferenceType, - right: ir.Types.ReferenceType): Boolean = { + private def isMoreSpecific(left: ir.Types.TypeRef, + right: ir.Types.TypeRef): Boolean = { import ir.Types._ def classIsMoreSpecific(leftCls: String, rightCls: String): Boolean = { @@ -480,11 +480,11 @@ private final class Analyzer(semantics: Semantics, } (left, right) match { - case (ClassType(leftCls), ClassType(rightCls)) => + case (ClassRef(leftCls), ClassRef(rightCls)) => classIsMoreSpecific(leftCls, rightCls) - case (ArrayType(leftBase, leftDepth), ArrayType(rightBase, rightDepth)) => + case (ArrayTypeRef(leftBase, leftDepth), ArrayTypeRef(rightBase, rightDepth)) => leftDepth == rightDepth && classIsMoreSpecific(leftBase, rightBase) - case (ArrayType(_, _), ClassType(ObjectClass)) => + case (ArrayTypeRef(_, _), ClassRef(ObjectClass)) => true case _ => false diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index 05f30d4fbd..0cebd06760 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -769,7 +769,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { /* Hijacked boxed classes have a special isInstanceOf test. */ val xParam = js.ParamDef(js.Ident("x"), rest = false) WithGlobals(js.Function(List(xParam), js.Return { - genIsInstanceOf(xParam.ref, ClassType(className)) + genIsInstanceOf(xParam.ref, ClassRef(className)) })) } else if (isAncestorOfHijackedClass || className == StringClass) { /* java.lang.String and ancestors of hijacked classes, including @@ -1169,8 +1169,9 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { case ModuleInitializer.MainMethodWithArgs(moduleClassName, mainMethodName, args) => + val stringArrayTpe = ArrayType(ArrayTypeRef("T", 1)) js.Apply(genLoadModule(moduleClassName) DOT mainMethodName, - genArrayValue(ArrayType("T", 1), args.map(js.StringLiteral(_))) :: Nil) + genArrayValue(stringArrayTpe, args.map(js.StringLiteral(_))) :: Nil) } } diff --git 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 index 46e7da3f7b..1fe785ff54 100644 --- 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 @@ -2029,7 +2029,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case NewArray(tpe, lengths) => genCallHelper("newArrayObject", - genClassDataOf(tpe), js.ArrayConstr(lengths map transformExpr)) + genClassDataOf(tpe.arrayTypeRef), + js.ArrayConstr(lengths.map(transformExpr))) case ArrayValue(tpe, elems) => genArrayValue(tpe, elems.map(transformExpr)) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala index 7435f9c737..1543067cc3 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala @@ -83,21 +83,21 @@ private[emitter] final class JSGen(val semantics: Semantics, envField("t", className + "__" + item.name) } - def genIsInstanceOf(expr: Tree, cls: ReferenceType)( + def genIsInstanceOf(expr: Tree, typeRef: TypeRef)( implicit pos: Position): Tree = - genIsAsInstanceOf(expr, cls, test = true) + genIsAsInstanceOf(expr, typeRef, test = true) - def genAsInstanceOf(expr: Tree, cls: ReferenceType)( + def genAsInstanceOf(expr: Tree, typeRef: TypeRef)( implicit pos: Position): Tree = - genIsAsInstanceOf(expr, cls, test = false) + genIsAsInstanceOf(expr, typeRef, test = false) - private def genIsAsInstanceOf(expr: Tree, cls: ReferenceType, test: Boolean)( + private def genIsAsInstanceOf(expr: Tree, typeRef: TypeRef, test: Boolean)( implicit pos: Position): Tree = { import Definitions._ import TreeDSL._ - cls match { - case ClassType(className0) => + typeRef match { + case ClassRef(className0) => val className = if (className0 == BoxedLongClass) LongImpl.RuntimeLongClass else className0 @@ -130,7 +130,7 @@ private[emitter] final class JSGen(val semantics: Semantics, List(expr)) } - case ArrayType(base, depth) => + case ArrayTypeRef(base, depth) => Apply( envField(if (test) "isArrayOf" else "asArrayOf", base), List(expr, IntLiteral(depth))) @@ -222,15 +222,15 @@ private[emitter] final class JSGen(val semantics: Semantics, def genArrayValue(tpe: ArrayType, elems: List[Tree])( implicit pos: Position): Tree = { - genCallHelper("makeNativeArrayWrapper", genClassDataOf(tpe), + genCallHelper("makeNativeArrayWrapper", genClassDataOf(tpe.arrayTypeRef), ArrayConstr(elems)) } - def genClassDataOf(cls: ReferenceType)(implicit pos: Position): Tree = { - cls match { - case ClassType(className) => + def genClassDataOf(typeRef: TypeRef)(implicit pos: Position): Tree = { + typeRef match { + case ClassRef(className) => envField("d", className) - case ArrayType(base, dims) => + case ArrayTypeRef(base, dims) => (1 to dims).foldLeft[Tree](envField("d", base)) { (prev, _) => Apply(DotSelect(prev, Ident("getArrayOf")), Nil) } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 17fa1294dd..53316f6b02 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -1048,25 +1048,25 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { private def inferMethodType(encodedName: String, isStatic: Boolean)( implicit ctx: ErrorContext): (List[Type], Type) = { - val (_, paramRefTypes, resultRefType) = decodeMethodName(encodedName) - val paramTypes = paramRefTypes.map(refTypeToType) + val (_, paramTypeRefs, resultTypeRef) = decodeMethodName(encodedName) + val paramTypes = paramTypeRefs.map(typeRefToType) - val resultType = resultRefType.fold[Type] { + val resultType = resultTypeRef.fold[Type] { if (isConstructorName(encodedName)) NoType else if (encodedName == StaticInitializerName) NoType else AnyType // reflective proxy - } { refType => - refTypeToType(refType) + } { typeRef => + typeRefToType(typeRef) } (paramTypes, resultType) } - private def refTypeToType(refType: ReferenceType)( + private def typeRefToType(typeRef: TypeRef)( implicit ctx: ErrorContext): Type = { - refType match { - case arrayType: ArrayType => arrayType - case ClassType(encodedName) => classNameToType(encodedName) + typeRef match { + case arrayTypeRef: ArrayTypeRef => ArrayType(arrayTypeRef) + case ClassRef(encodedName) => classNameToType(encodedName) } } @@ -1096,8 +1096,9 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { private def arrayElemType(arrayType: ArrayType)( implicit ctx: ErrorContext): Type = { - if (arrayType.dimensions == 1) classNameToType(arrayType.baseClassName) - else ArrayType(arrayType.baseClassName, arrayType.dimensions-1) + val ArrayType(ArrayTypeRef(baseClassName, dimensions)) = arrayType + if (dimensions == 1) classNameToType(baseClassName) + else ArrayType(ArrayTypeRef(baseClassName, dimensions - 1)) } private def reportError(msg: String)(implicit ctx: ErrorContext): Unit = { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index dfa688a40e..c50fd98b54 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -514,15 +514,16 @@ private[optimizer] abstract class OptimizerCore( case RecordValue(tpe, elems) => RecordValue(tpe, elems map transformExpr) - case IsInstanceOf(expr, ClassType(ObjectClass)) => + case IsInstanceOf(expr, ClassRef(ObjectClass)) => transformExpr(BinaryOp(BinaryOp.!==, expr, Null())) - case IsInstanceOf(expr, tpe) => + case IsInstanceOf(expr, typeRef) => trampoline { pretransformExpr(expr) { texpr => val result = { - // TODO This cast is suspicious - if (isSubtype(texpr.tpe.base, tpe.asInstanceOf[Type])) { + val typeRefTpe = isAsInstanceOfTypeRefToType(typeRef) + + if (isSubtype(texpr.tpe.base, typeRefTpe)) { if (texpr.tpe.isNullable) BinaryOp(BinaryOp.!==, finishTransformExpr(texpr), Null()) else @@ -531,17 +532,17 @@ private[optimizer] abstract class OptimizerCore( if (texpr.tpe.isExact) Block(finishTransformStat(texpr), BooleanLiteral(false)) else - IsInstanceOf(finishTransformExpr(texpr), tpe) + IsInstanceOf(finishTransformExpr(texpr), typeRef) } } TailCalls.done(result) } } - case AsInstanceOf(expr, ClassType(ObjectClass)) => + case AsInstanceOf(expr, ClassRef(ObjectClass)) => transformExpr(expr) - case AsInstanceOf(expr, cls) => + case AsInstanceOf(_, _) => trampoline { pretransformExpr(tree)(finishTransform(isStat)) } @@ -556,17 +557,16 @@ private[optimizer] abstract class OptimizerCore( case GetClass(expr) => trampoline { pretransformExpr(expr) { texpr => + def constant(typeRef: TypeRef): TailRec[Tree] = + TailCalls.done(Block(finishTransformStat(texpr), ClassOf(typeRef))) + texpr.tpe match { - case RefinedType(base: ReferenceType, true, false) => - val actualBase = base match { - case ClassType(LongImpl.RuntimeLongClass) => - ClassType(Definitions.BoxedLongClass) - case _ => - base - } - TailCalls.done(Block( - finishTransformStat(texpr), - ClassOf(actualBase))) + case RefinedType(ClassType(LongImpl.RuntimeLongClass), true, false) => + constant(ClassRef(Definitions.BoxedLongClass)) + case RefinedType(ClassType(className), true, false) => + constant(ClassRef(className)) + case RefinedType(ArrayType(arrayTypeRef), true, false) => + constant(arrayTypeRef) case _ => TailCalls.done(GetClass(finishTransformExpr(texpr))) } @@ -875,17 +875,17 @@ private[optimizer] abstract class OptimizerCore( } } - case AsInstanceOf(expr, tpe) => + case AsInstanceOf(expr, typeRef) => pretransformExpr(expr) { texpr => - tpe match { - case ClassType(ObjectClass) => + typeRef match { + case ClassRef(ObjectClass) => cont(texpr) case _ => - // TODO This cast is suspicious - if (isSubtype(texpr.tpe.base, tpe.asInstanceOf[Type])) { + val typeRefTpe = isAsInstanceOfTypeRefToType(typeRef) + if (isSubtype(texpr.tpe.base, typeRefTpe)) { cont(texpr) } else { - cont(AsInstanceOf(finishTransformExpr(texpr), tpe).toPreTransform) + cont(AsInstanceOf(finishTransformExpr(texpr), typeRef).toPreTransform) } } } @@ -1508,15 +1508,15 @@ private[optimizer] abstract class OptimizerCore( if (cls == Definitions.BoxedLongClass) LongImpl.RuntimeLongClass else cls - case AnyType => Definitions.ObjectClass - case UndefType => Definitions.BoxedUnitClass - case BooleanType => Definitions.BoxedBooleanClass - case IntType => Definitions.BoxedIntegerClass - case LongType => LongImpl.RuntimeLongClass - case FloatType => Definitions.BoxedFloatClass - case DoubleType => Definitions.BoxedDoubleClass - case StringType => Definitions.StringClass - case ArrayType(_, _) => Definitions.ObjectClass + case AnyType => Definitions.ObjectClass + case UndefType => Definitions.BoxedUnitClass + case BooleanType => Definitions.BoxedBooleanClass + case IntType => Definitions.BoxedIntegerClass + case LongType => LongImpl.RuntimeLongClass + case FloatType => Definitions.BoxedFloatClass + case DoubleType => Definitions.BoxedDoubleClass + case StringType => Definitions.StringClass + case ArrayType(_) => Definitions.ObjectClass } private def pretransformStaticApply(tree: ApplyStatically, isStat: Boolean, @@ -1933,8 +1933,8 @@ private[optimizer] abstract class OptimizerCore( contTree(Apply(newReceiver, Ident(methodName), newArgs)(resultType)) def cursoryArrayElemType(tpe: ArrayType): Type = { - if (tpe.dimensions != 1) AnyType - else (tpe.baseClassName match { + if (tpe.arrayTypeRef.dimensions != 1) AnyType + else (tpe.arrayTypeRef.baseClassName match { case "Z" => BooleanType case "B" | "C" | "S" | "I" => IntType case "F" => FloatType @@ -1957,7 +1957,7 @@ private[optimizer] abstract class OptimizerCore( case ArrayApply => val List(array, index) = newArgs array.tpe match { - case arrayTpe @ ArrayType(base, depth) => + case arrayTpe @ ArrayType(ArrayTypeRef(base, _)) => val elemType = cursoryArrayElemType(arrayTpe) val select = ArraySelect(array, index)(elemType) if (base == "C") @@ -1972,7 +1972,7 @@ private[optimizer] abstract class OptimizerCore( case ArrayUpdate => val List(tarray, tindex, tvalue) = targs tarray.tpe.base match { - case arrayTpe @ ArrayType(base, depth) => + case arrayTpe @ ArrayType(ArrayTypeRef(base, depth)) => val array = finishTransformExpr(tarray) val index = finishTransformExpr(tindex) val elemType = cursoryArrayElemType(arrayTpe) @@ -2039,8 +2039,8 @@ private[optimizer] abstract class OptimizerCore( case GenericArrayBuilderResult => val List(runtimeClass, array) = newArgs val (resultType, isExact) = runtimeClass match { - case ClassOf(elemType) => (ArrayType(elemType), true) - case _ => (AnyType, false) + case ClassOf(elemTypeRef) => (ArrayType(ArrayTypeRef.of(elemTypeRef)), true) + case _ => (AnyType, false) } cont(PreTransTree(CallHelper("makeNativeArrayWrapper", CallHelper("arrayDataOf", @@ -2050,7 +2050,7 @@ private[optimizer] abstract class OptimizerCore( case ArrayBuilderZeroOf => contTree(finishTransformExpr(targs.head) match { - case ClassOf(ClassType(cls)) => + case ClassOf(ClassRef(cls)) => cls match { case "B" | "S" | "C" | "I" | "D" => IntLiteral(0) case "L" => LongLiteral(0L) @@ -2069,11 +2069,11 @@ private[optimizer] abstract class OptimizerCore( case ClassGetComponentType => newReceiver match { - case ClassOf(ArrayType(base, depth)) => + case ClassOf(ArrayTypeRef(base, depth)) => contTree(ClassOf( - if (depth == 1) ClassType(base) - else ArrayType(base, depth - 1))) - case ClassOf(ClassType(_)) => + if (depth == 1) ClassRef(base) + else ArrayTypeRef(base, depth - 1))) + case ClassOf(ClassRef(_)) => contTree(Null()) case receiver => defaultApply("getComponentType__jl_Class", @@ -2084,8 +2084,9 @@ private[optimizer] abstract class OptimizerCore( case ArrayNewInstance => newArgs.head match { - case ClassOf(elementTpe) => - contTree(NewArray(ArrayType(elementTpe), List(newArgs.tail.head))) + case ClassOf(elementTypeRef) => + val arrayTypeRef = ArrayTypeRef.of(elementTypeRef) + contTree(NewArray(ArrayType(arrayTypeRef), List(newArgs.tail.head))) case _ => defaultApply("newInstance__jl_Class__I__O", AnyType) } @@ -4124,6 +4125,24 @@ private[optimizer] abstract class OptimizerCore( else upperBound } + /** Converts a `TypeRef` on the rhs of an `In/AsInstanceOf` to the + * corresponding `Type`. + */ + private def isAsInstanceOfTypeRefToType(typeRef: TypeRef): Type = { + /* Since ClassRefs of primitive types and JS types are not admissible + * in an Is- or AsInstanceOf node, we can translate all of them to + * their corresponding ClassType (with the exception of j.l.Object). + * + * TODO Investigate whether Null and Nothing should be handled specially + * here. + */ + typeRef match { + case ClassRef(ObjectClass) => AnyType + case ClassRef(className) => ClassType(className) + case typeRef: ArrayTypeRef => ArrayType(typeRef) + } + } + /** Trampolines a pretransform */ private def trampoline(tailrec: => TailRec[Tree]): Tree = { // scalastyle:off return From 481660fe18eca2494334ecb9db358d470899bf5e Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Tue, 18 Jul 2017 17:57:45 -0400 Subject: [PATCH 0407/2665] Fix 2.13 community build: add Numeric#parseString in RangesTest Numeric#parseString got newly added in 2.13 (see scala/community-builds#572). --- .../test/scala/org/scalajs/testsuite/scalalib/RangesTest.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/RangesTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/RangesTest.scala index 7acb5d146b..cdcd78a3a1 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/RangesTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/RangesTest.scala @@ -129,6 +129,7 @@ class RangesTest { def toFloat(x: A): Float = x.v.toFloat def toInt(x: A): Int = x.v def toLong(x: A): Long = x.v.toLong + def parseString(str: String): Option[A] = Some(A(str.toInt)) } val r = NumericRange(A(1), A(10), A(1)) From e6920d8c28d4c9b7240f8eb42234cc89517cf791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 20 Jul 2017 22:38:30 +0200 Subject: [PATCH 0408/2665] Remove the deprecated `RuntimeClassNameMapper.custom()`. --- project/Build.scala | 16 +++----- .../core/tools/test/js/QuickLinker.scala | 11 +++-- .../scalajs/core/tools/sem/Semantics.scala | 41 +------------------ 3 files changed, 11 insertions(+), 57 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index e3ba24f3b0..e3b4031960 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -628,11 +628,6 @@ object Build { commonToolsSettings, crossVersion := ScalaJSCrossVersion.binary, - /* We need RuntimeClassNameMapper.custom() in QuickLinker - * TODO Remove this in 1.x. - */ - scalacOptions in Test -= "-Xfatal-warnings", - scalaJSLinkerConfig in Test ~= (_.withModuleKind(ModuleKind.CommonJSModule)), jsExecutionFiles in Test := { @@ -1475,12 +1470,11 @@ object Build { prevConfig.withSemantics { sems => sems.withRuntimeClassNameMapper( - RuntimeClassNameMapper.custom(_.fullName match { - case "org.scalajs.testsuite.compiler.ReflectionTest$RenamedTestClass" => - "renamed.test.Class" - case fullName => - fullName - }).andThen( + RuntimeClassNameMapper.keepAll().andThen( + RuntimeClassNameMapper.regexReplace( + raw"""^org\.scalajs\.testsuite\.compiler\.ReflectionTest\$$RenamedTestClass$$""".r, + "renamed.test.Class") + ).andThen( RuntimeClassNameMapper.regexReplace( raw"""^org\.scalajs\.testsuite\.compiler\.ReflectionTest\$$Prefix""".r, "renamed.test.byprefix.") diff --git 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 index af85a27064..96a871910b 100644 --- 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 @@ -27,12 +27,11 @@ object QuickLinker { import Semantics.RuntimeClassNameMapper val semantics = Semantics.Defaults.withRuntimeClassNameMapper( - RuntimeClassNameMapper.custom(_.fullName match { - case "org.scalajs.testsuite.compiler.ReflectionTest$RenamedTestClass" => - "renamed.test.Class" - case fullName => - fullName - }).andThen( + RuntimeClassNameMapper.keepAll().andThen( + RuntimeClassNameMapper.regexReplace( + raw"""^org\.scalajs\.testsuite\.compiler\.ReflectionTest\$$RenamedTestClass$$""".r, + "renamed.test.Class") + ).andThen( RuntimeClassNameMapper.regexReplace( raw"""^org\.scalajs\.testsuite\.compiler\.ReflectionTest\$$Prefix""".r, "renamed.test.byprefix.") diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/sem/Semantics.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/sem/Semantics.scala index 7314984861..56ce92e24a 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/sem/Semantics.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/sem/Semantics.scala @@ -25,10 +25,6 @@ final class Semantics private ( import Semantics._ - @deprecated("Use runtimeClassNameMapper instead.", "0.6.19") - def runtimeClassName: Semantics.RuntimeClassNameFunction = - runtimeClassNameMapper(_) - def withAsInstanceOfs(behavior: CheckedBehavior): Semantics = copy(asInstanceOfs = behavior) @@ -49,10 +45,6 @@ final class Semantics private ( copy(runtimeClassNameMapper = runtimeClassNameMapper) } - @deprecated("Use withRuntimeClassNameMapper instead.", "0.6.19") - def withRuntimeClassName(runtimeClassName: RuntimeClassNameFunction): Semantics = - withRuntimeClassNameMapper(RuntimeClassNameMapper.custom(runtimeClassName)) - def optimized: Semantics = { copy(asInstanceOfs = this.asInstanceOfs.optimized, arrayIndexOutOfBounds = this.arrayIndexOutOfBounds.optimized, @@ -119,13 +111,8 @@ object Semantics { sealed abstract class RuntimeClassNameMapper { import RuntimeClassNameMapper._ - def andThen(that: RuntimeClassNameMapper): RuntimeClassNameMapper = { - require(!that.isInstanceOf[Custom], - "RuntimeClassNameMapper.custom(...) is not a valid argument to " + - "RuntimeClassNameMapper#andThen(), because it takes a LinkedClass " + - "as input instead of a String.") + def andThen(that: RuntimeClassNameMapper): RuntimeClassNameMapper = AndThen(this, that) - } private[tools] def apply(linkedClass: LinkedClass): String = { def rec(mapper: RuntimeClassNameMapper, className: String): String = { @@ -138,11 +125,6 @@ object Semantics { mapper.compiledPattern.matcher(className).replaceAll(replacement) case AndThen(first, second) => rec(second, rec(first, className)) - case Custom(mapper) => - /* Discards `className`, but that's fine because we cannot - * construct an AndThen(_, Custom()). - */ - mapper(linkedClass) } } @@ -168,20 +150,6 @@ object Semantics { second: RuntimeClassNameMapper) extends RuntimeClassNameMapper - /** For compatibility with `RuntimeClassNameFunction`s only. */ - private case class Custom(mapper: LinkedClass => String) - extends RuntimeClassNameMapper { - /* For compatibility of `Semantics.==` of previous versions, we need to - * consider all `Custom` instances as being equal, even though this - * definitely breaks the case class contract. - * Since this is deprecated, this issue will eventually go away. - */ - - override def equals(that: Any): Boolean = that.isInstanceOf[Custom] - - override def hashCode(): Int = 369581025 // generated at random - } - def keepAll(): RuntimeClassNameMapper = KeepAll def discardAll(): RuntimeClassNameMapper = DiscardAll @@ -211,15 +179,8 @@ object Semantics { replacement: String): RuntimeClassNameMapper = { regexReplace(regex.pattern, replacement) } - - @deprecated("Will be removed in Scala.js 1.x.", "0.6.19") - def custom(mapper: LinkedClass => String): RuntimeClassNameMapper = - Custom(mapper) } - @deprecated("Use RuntimeClassNameMapper instead.", "0.6.19") - type RuntimeClassNameFunction = LinkedClass => String - val Defaults: Semantics = new Semantics( asInstanceOfs = Fatal, arrayIndexOutOfBounds = Fatal, From 4a7b57193dd9ce1c94564168cf87ba7f4e29411e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 5 Jul 2017 15:23:25 +0200 Subject: [PATCH 0409/2665] Remove all deprecated stuff in the tools. --- .../linker/LinkerPlatformExtensions.scala | 24 -------- .../linker/LinkerPlatformExtensions.scala | 28 --------- .../closure/ClosureLinkerBackend.scala | 6 -- .../scalajs/core/tools/linker/GenLinker.scala | 12 ---- .../core/tools/linker/LinkingUnit.scala | 59 +------------------ .../linker/backend/BasicLinkerBackend.scala | 6 -- .../tools/linker/backend/LinkerBackend.scala | 6 -- .../tools/linker/backend/OutputMode.scala | 4 -- .../linker/backend/emitter/Emitter.scala | 4 -- .../core/tools/linker/checker/IRChecker.scala | 2 +- .../tools/linker/frontend/BaseLinker.scala | 6 -- .../linker/frontend/LinkerFrontend.scala | 7 --- .../core/tools/linker/frontend/Refiner.scala | 2 +- 13 files changed, 4 insertions(+), 162 deletions(-) diff --git a/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala b/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala index 8a32965242..ae8784b588 100644 --- a/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala +++ b/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala @@ -14,12 +14,6 @@ import org.scalajs.core.tools.linker.frontend.optimizer.IncOptimizer import org.scalajs.core.tools.linker.backend._ trait LinkerPlatformExtensions { this: Linker.type => - @deprecated("Use StandardLinker.apply() instead.", "0.6.18") - def apply(semantics: Semantics, outputMode: OutputMode, - moduleKind: ModuleKind, config: Config): Linker = { - applyInternal(semantics, outputMode, moduleKind, config) - } - private[linker] def applyInternal(semantics: Semantics, outputMode: OutputMode, moduleKind: ModuleKind, config: Config): Linker = { @@ -37,24 +31,6 @@ trait LinkerPlatformExtensions { this: Linker.type => new Linker(frontend, backend) } - - @deprecated("Use StandardLinker.apply() instead.", "0.6.13") - def apply( - semantics: Semantics = Semantics.Defaults, - outputMode: OutputMode = OutputMode.Default, - withSourceMap: Boolean = true, - disableOptimizer: Boolean = false, - frontendConfig: LinkerFrontend.Config = LinkerFrontend.Config(), - backendConfig: LinkerBackend.Config = LinkerBackend.Config()): Linker = { - - val config = Config() - .withSourceMap(withSourceMap) - .withOptimizer(!disableOptimizer) - .withFrontendConfig(frontendConfig) - .withBackendConfig(backendConfig) - - apply(semantics, outputMode, ModuleKind.NoModule, config) - } } object LinkerPlatformExtensions { diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala index b15f7ad351..af315e85e8 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala @@ -15,12 +15,6 @@ import org.scalajs.core.tools.linker.backend._ import org.scalajs.core.tools.linker.backend.closure.ClosureLinkerBackend trait LinkerPlatformExtensions { this: Linker.type => - @deprecated("Use StandardLinker.apply() instead.", "0.6.18") - def apply(semantics: Semantics, outputMode: OutputMode, - moduleKind: ModuleKind, config: Config): Linker = { - applyInternal(semantics, outputMode, moduleKind, config) - } - private[linker] def applyInternal(semantics: Semantics, outputMode: OutputMode, moduleKind: ModuleKind, config: Config): Linker = { @@ -48,28 +42,6 @@ trait LinkerPlatformExtensions { this: Linker.type => new Linker(frontend, backend) } - - @deprecated("Use StandardLinker.apply() instead.", "0.6.13") - def apply( - semantics: Semantics = Semantics.Defaults, - outputMode: OutputMode = OutputMode.Default, - withSourceMap: Boolean = true, - disableOptimizer: Boolean = false, - parallel: Boolean = true, - useClosureCompiler: Boolean = false, - frontendConfig: LinkerFrontend.Config = LinkerFrontend.Config(), - backendConfig: LinkerBackend.Config = LinkerBackend.Config()): Linker = { - - val config = Config() - .withSourceMap(withSourceMap) - .withOptimizer(!disableOptimizer) - .withParallel(parallel) - .withClosureCompiler(useClosureCompiler) - .withFrontendConfig(frontendConfig) - .withBackendConfig(backendConfig) - - apply(semantics, outputMode, ModuleKind.NoModule, config) - } } object LinkerPlatformExtensions { diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala index 819f7267a5..a33db3789a 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala @@ -41,12 +41,6 @@ final class ClosureLinkerBackend( ) extends LinkerBackend(semantics, ESLevel.ES5, moduleKind, withSourceMap, config) { - @deprecated("Use the overload with an explicit ModuleKind", "0.6.13") - def this(semantics: Semantics, withSourceMap: Boolean, - config: LinkerBackend.Config) { - this(semantics, ModuleKind.NoModule, withSourceMap, config) - } - private[this] val emitter = { new Emitter(semantics, OutputMode.ECMAScript51Isolated, moduleKind) .withOptimizeBracketSelects(false) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala index 5564e56c07..eb70d19474 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala @@ -23,22 +23,10 @@ trait GenLinker { def semantics: Semantics def esLevel: ESLevel - @deprecated("Use the overload with explicit module initializers.", "0.6.15") - def linkUnit(irFiles: Seq[VirtualScalaJSIRFile], - symbolRequirements: SymbolRequirement, logger: Logger): LinkingUnit = { - linkUnit(irFiles, Nil, symbolRequirements, logger) - } - def linkUnit(irFiles: Seq[VirtualScalaJSIRFile], moduleInitializers: Seq[ModuleInitializer], symbolRequirements: SymbolRequirement, logger: Logger): LinkingUnit - @deprecated("Use the overload with explicit module initializers.", "0.6.15") - def link(irFiles: Seq[VirtualScalaJSIRFile], - output: WritableVirtualJSFile, logger: Logger): Unit = { - link(irFiles, Nil, output, logger) - } - def link(irFiles: Seq[VirtualScalaJSIRFile], moduleInitializers: Seq[ModuleInitializer], output: WritableVirtualJSFile, logger: Logger): Unit diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala index e6283b6dfb..7067bf08ea 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala @@ -9,67 +9,12 @@ final class LinkingUnit private[linker] ( val semantics: Semantics, val esLevel: ESLevel, val classDefs: List[LinkedClass], - private[linker] val infosInternal: Map[String, Infos.ClassInfo], + private[linker] val infos: Map[String, Infos.ClassInfo], val moduleInitializers: List[ModuleInitializer] ) { - - import LinkingUnit._ - - @deprecated( - "LinkingUnit.infos was not intended to be exposed to user code. " + - "It will be removed in 1.0.0. " + - "Use linkingUnit.classDefs.map(_.toInfo) instead.", - "0.6.15") - val infos: Map[String, Infos.ClassInfo] = infosInternal - - /* This used to be a `lazy val`, but that causes scalac to complain about - * uses of GlobalInfo inside globalInfo. The issue also appears with a `val` - * but not with a `def`. - * A `def` is binary compatible with a `lazy val`, although not source - * compatible (a `lazy val` is *stable*, so can be imported from). - */ - @deprecated( - "LinkingUnit.globalInfo was not intended to be exposed to user code. " + - "It will be removed in 1.0.0. " + - "Inspect the relevant data in linkingUnit.classDefs instead.", - "0.6.15") - def globalInfo: GlobalInfo = { - classDefs.find(_.encodedName == Definitions.ClassClass).fold { - GlobalInfo( - isParentDataAccessed = false) - } { classClassDef => - val methodNames = classClassDef.memberMethods.map(_.info.encodedName).toSet - GlobalInfo( - isParentDataAccessed = methodNames.contains("getSuperclass__jl_Class")) - } - } - private[linker] def updated(classDefs: List[LinkedClass]): LinkingUnit = { val newInfos = - infosInternal ++ classDefs.map(cd => cd.encodedName -> cd.toInfo) + infos ++ classDefs.map(cd => cd.encodedName -> cd.toInfo) new LinkingUnit(semantics, esLevel, classDefs, newInfos, moduleInitializers) } } - -@deprecated("This object only contains deprecated members.", "0.6.15") -object LinkingUnit { - - @deprecated("See LinkingInfo.globalInfo.", "0.6.15") - final class GlobalInfo private ( - /** Whether the parent data of class data is accessed. - * This is true iff the java.lang.Class.getSuperclass() method exists, - * since it is the only one that can do it. - */ - val isParentDataAccessed: Boolean - ) - - @deprecated("See LinkingInfo.globalInfo.", "0.6.15") - object GlobalInfo { - private[LinkingUnit] def apply( - isParentDataAccessed: Boolean - ): GlobalInfo = { - new GlobalInfo(isParentDataAccessed) - } - } - -} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala index fa855927cc..a779d492c0 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala @@ -30,12 +30,6 @@ final class BasicLinkerBackend( ) extends LinkerBackend(semantics, outputMode.esLevel, moduleKind, withSourceMap, config) { - @deprecated("Use the overload with an explicit ModuleKind", "0.6.13") - def this(semantics: Semantics, outputMode: OutputMode, withSourceMap: Boolean, - config: LinkerBackend.Config) { - this(semantics, outputMode, ModuleKind.NoModule, withSourceMap, config) - } - private[this] val emitter = new Emitter(semantics, outputMode, moduleKind) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala index 909d1168e1..b598bb3c75 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala @@ -32,12 +32,6 @@ abstract class LinkerBackend( val withSourceMap: Boolean, protected val config: LinkerBackend.Config) { - @deprecated("Use the overload with an explicit ModuleKind", "0.6.13") - def this(semantics: Semantics, esLevel: ESLevel, withSourceMap: Boolean, - config: LinkerBackend.Config) { - this(semantics, esLevel, ModuleKind.NoModule, withSourceMap, config) - } - /** Symbols this backend needs to be present in the linking unit. */ val symbolRequirements: SymbolRequirement diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala index 8f9f7acd5f..99f003d599 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala @@ -54,8 +54,4 @@ object OutputMode { case object ECMAScript6 extends OutputMode { val esLevel: ESLevel = ESLevel.ES6 } - - // Not binary compatible, but source compatible with deprecation - @deprecated("Support for ES6 Strong Mode was removed. Use ECMAScript6 instead.", "0.6.8") - lazy val ECMAScript6StrongMode: ECMAScript6.type = ECMAScript6 } diff --git 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 index 30e8e6cd6c..92e66d555c 100644 --- 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 @@ -39,10 +39,6 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, this(semantics, outputMode, moduleKind, InternalOptions()) } - @deprecated("Use the overload with an explicit ModuleKind.", "0.6.13") - def this(semantics: Semantics, outputMode: OutputMode) = - this(semantics, outputMode, ModuleKind.NoModule, InternalOptions()) - private val knowledgeGuardian = new KnowledgeGuardian private val baseCoreJSLib = CoreJSLibs.lib(semantics, outputMode, moduleKind) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 53316f6b02..6efb10603b 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -1108,7 +1108,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { private def lookupInfo(className: String)( implicit ctx: ErrorContext): Infos.ClassInfo = { - unit.infosInternal.getOrElse(className, { + unit.infos.getOrElse(className, { reportError(s"Cannot find info for class $className") Infos.ClassInfo(className) }) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index b81cdaae87..b63da62b47 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -42,12 +42,6 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, private type TreeProvider = String => (ClassDef, Option[String]) - @deprecated("Use the overload with explicit module initializers.", "0.6.15") - def link(irInput: Seq[VirtualScalaJSIRFile], logger: Logger, - symbolRequirements: SymbolRequirement, checkIR: Boolean): LinkingUnit = { - link(irInput, Nil, logger, symbolRequirements, checkIR) - } - def link(irInput: Seq[VirtualScalaJSIRFile], moduleInitializers: Seq[ModuleInitializer], logger: Logger, symbolRequirements: SymbolRequirement, checkIR: Boolean): LinkingUnit = { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala index 0ac8ee4144..3ca5a382d3 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala @@ -42,13 +42,6 @@ final class LinkerFrontend( private[this] val refiner: Refiner = new Refiner - /** Link and optionally optimize the given IR to a [[LinkingUnit]]. */ - @deprecated("Use the overload with explicit module initializers.", "0.6.15") - def link(irFiles: Seq[VirtualScalaJSIRFile], - symbolRequirements: SymbolRequirement, logger: Logger): LinkingUnit = { - link(irFiles, Nil, symbolRequirements, logger) - } - /** Link and optionally optimize the given IR to a [[LinkingUnit]]. */ def link(irFiles: Seq[VirtualScalaJSIRFile], moduleInitializers: Seq[ModuleInitializer], diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala index 501f3ca29f..371003a88b 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala @@ -28,7 +28,7 @@ final class Refiner { ModuleInitializer.toSymbolRequirement(unit.moduleInitializers) } Analyzer.computeReachability(unit.semantics, allSymbolRequirements, - unit.infosInternal.values.toList, allowAddingSyntheticMethods = false) + unit.infos.values.toList, allowAddingSyntheticMethods = false) } /* There must not be linking errors at this point. If there are, it is a From dca4e90227f9750a1bc39fe7c71675b5d74fd7df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 5 Jul 2017 15:59:58 +0200 Subject: [PATCH 0410/2665] Remove all deprecated stuff in the IR. --- .../scala/org/scalajs/core/ir/Infos.scala | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala index 18321c209a..b7f82d4349 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala @@ -59,27 +59,6 @@ object Infos { ) object MethodInfo { - @deprecated("Use the overload with all the fields and no defaults", - "0.6.15") - def apply( - encodedName: String, - isStatic: Boolean = false, - isAbstract: Boolean = false, - isExported: Boolean = false, - methodsCalled: Map[String, List[String]] = Map.empty, - methodsCalledStatically: Map[String, List[String]] = Map.empty, - staticMethodsCalled: Map[String, List[String]] = Map.empty, - instantiatedClasses: List[String] = Nil, - accessedModules: List[String] = Nil, - usedInstanceTests: List[String] = Nil, - accessedClassData: List[String] = Nil): MethodInfo = { - apply(encodedName, isStatic, isAbstract, isExported, - staticFieldsRead = Map.empty, staticFieldsWritten = Map.empty, - methodsCalled, methodsCalledStatically, staticMethodsCalled, - instantiatedClasses, accessedModules, usedInstanceTests, - accessedClassData) - } - def apply( encodedName: String, isStatic: Boolean, From f3dc11698eb769623cf0529877d7f3a2773be890 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 27 May 2017 11:31:54 +0200 Subject: [PATCH 0411/2665] Always assume that source maps will be needed in LinkerFrontend. The only reason that the frontend wants to know whether source maps will be emitted or not is to decide whether to take tree positions into account when detecting changes. This is supposed to somewhat speed up incremental runs. Now, it is very rare to disable source maps in fastOpt; and fullOpt runs, even if incremental in our pipeline, are bottlenecked in Closure anyway. Therefore, the benefit of this "optimization" is most likely negligible, and is not worth the complexity. --- .../core/tools/linker/LinkerPlatformExtensions.scala | 2 +- .../core/tools/linker/LinkerPlatformExtensions.scala | 2 +- .../tools/linker/frontend/optimizer/ParIncOptimizer.scala | 7 +++---- .../main/scala/org/scalajs/core/tools/linker/Linker.scala | 2 -- .../scalajs/core/tools/linker/frontend/BaseLinker.scala | 7 +++---- .../core/tools/linker/frontend/LinkerFrontend.scala | 5 ++--- .../tools/linker/frontend/optimizer/GenIncOptimizer.scala | 8 +++----- .../tools/linker/frontend/optimizer/IncOptimizer.scala | 7 +++---- 8 files changed, 16 insertions(+), 24 deletions(-) diff --git a/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala b/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala index ae8784b588..08a9ae8d8a 100644 --- a/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala +++ b/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala @@ -24,7 +24,7 @@ trait LinkerPlatformExtensions { this: Linker.type => } val frontend = new LinkerFrontend(semantics, outputMode.esLevel, - config.sourceMap, config.frontendConfig, optOptimizerFactory) + config.frontendConfig, optOptimizerFactory) val backend = new BasicLinkerBackend(semantics, outputMode, moduleKind, config.sourceMap, config.backendConfig) diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala index af315e85e8..d04d7b4a81 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala @@ -26,7 +26,7 @@ trait LinkerPlatformExtensions { this: Linker.type => } val frontend = new LinkerFrontend(semantics, outputMode.esLevel, - config.sourceMap, config.frontendConfig, optOptimizerFactory) + config.frontendConfig, optOptimizerFactory) val backend = { if (config.closureCompiler) { diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ParIncOptimizer.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ParIncOptimizer.scala index 89ed78b597..da3ee9028e 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ParIncOptimizer.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ParIncOptimizer.scala @@ -21,9 +21,8 @@ import org.scalajs.core.tools.javascript.ESLevel import ConcurrencyUtils._ -final class ParIncOptimizer(semantics: Semantics, esLevel: ESLevel, - considerPositions: Boolean) - extends GenIncOptimizer(semantics, esLevel, considerPositions) { +final class ParIncOptimizer(semantics: Semantics, esLevel: ESLevel) + extends GenIncOptimizer(semantics, esLevel) { private[optimizer] object CollOps extends GenIncOptimizer.AbsCollOps { type Map[K, V] = TrieMap[K, V] @@ -202,5 +201,5 @@ final class ParIncOptimizer(semantics: Semantics, esLevel: ESLevel, } object ParIncOptimizer { - val factory: GenIncOptimizer.OptimizerFactory = new ParIncOptimizer(_, _, _) + val factory: GenIncOptimizer.OptimizerFactory = new ParIncOptimizer(_, _) } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala index 6aa9921f16..806ed29d26 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala @@ -26,8 +26,6 @@ import org.scalajs.core.tools.linker.backend.{LinkerBackend, BasicLinkerBackend} final class Linker(frontend: LinkerFrontend, backend: LinkerBackend) extends GenLinker { - require(!backend.withSourceMap || frontend.withSourceMap, - "Frontend must have source maps enabled if backend has them enabled") require(frontend.semantics == backend.semantics, "Frontend and backend must agree on semantics") require(frontend.esLevel == backend.esLevel, diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index b63da62b47..5dccdf8509 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -37,8 +37,7 @@ import Analysis._ /** Links the information from [[io.VirtualScalaJSIRFile]]s into * [[LinkedClass]]es. Does a dead code elimination pass. */ -final class BaseLinker(semantics: Semantics, esLevel: ESLevel, - considerPositions: Boolean) { +final class BaseLinker(semantics: Semantics, esLevel: ESLevel) { private type TreeProvider = String => (ClassDef, Option[String]) @@ -170,7 +169,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, def linkedMethod(m: MethodDef) = { val info = memberInfoByStaticAndName((m.static, m.name.encodedName)) - val version = m.hash.map(Hashers.hashAsVersion(_, considerPositions)) + val version = m.hash.map(Hashers.hashAsVersion(_, considerPos = true)) new LinkedMember(info, m, version) } @@ -181,7 +180,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel, def linkedSyntheticMethod(m: MethodDef) = { val info = Infos.generateMethodInfo(m) - val version = m.hash.map(Hashers.hashAsVersion(_, considerPositions)) + val version = m.hash.map(Hashers.hashAsVersion(_, considerPos = true)) new LinkedMember(info, m, version) } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala index 3ca5a382d3..a51d104625 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala @@ -30,15 +30,14 @@ import org.scalajs.core.tools.linker.frontend.optimizer.{GenIncOptimizer, IncOpt final class LinkerFrontend( val semantics: Semantics, val esLevel: ESLevel, - val withSourceMap: Boolean, config: LinkerFrontend.Config, optimizerFactory: Option[GenIncOptimizer.OptimizerFactory]) { private[this] val linker: BaseLinker = - new BaseLinker(semantics, esLevel, withSourceMap) + new BaseLinker(semantics, esLevel) private[this] val optOptimizer: Option[GenIncOptimizer] = - optimizerFactory.map(_(semantics, esLevel, withSourceMap)) + optimizerFactory.map(_(semantics, esLevel)) private[this] val refiner: Refiner = new Refiner diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala index 84db20d6f8..8ca07bcb55 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala @@ -38,11 +38,9 @@ import org.scalajs.core.tools.linker.backend.emitter.LongImpl * * @param semantics Required Scala.js Semantics * @param esLevel ECMAScript level - * @param considerPositions Should positions be considered when comparing tree - * hashes */ abstract class GenIncOptimizer private[optimizer] (semantics: Semantics, - esLevel: ESLevel, considerPositions: Boolean) { + esLevel: ESLevel) { import GenIncOptimizer._ @@ -903,7 +901,7 @@ abstract class GenIncOptimizer private[optimizer] (semantics: Semantics, val changed = { originalDef == null || (methodDef.hash zip originalDef.hash).forall { - case (h1, h2) => !Hashers.hashesEqual(h1, h2, considerPositions) + case (h1, h2) => !Hashers.hashesEqual(h1, h2, considerPos = true) } } @@ -1014,7 +1012,7 @@ abstract class GenIncOptimizer private[optimizer] (semantics: Semantics, object GenIncOptimizer { - type OptimizerFactory = (Semantics, ESLevel, Boolean) => GenIncOptimizer + type OptimizerFactory = (Semantics, ESLevel) => GenIncOptimizer private val isAdHocElidableModuleAccessor = Set("s_Predef$") diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/IncOptimizer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/IncOptimizer.scala index 07566bf137..96955b2102 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/IncOptimizer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/IncOptimizer.scala @@ -15,9 +15,8 @@ import scala.collection.mutable import org.scalajs.core.tools.sem.Semantics import org.scalajs.core.tools.javascript.ESLevel -final class IncOptimizer(semantics: Semantics, esLevel: ESLevel, - considerPositions: Boolean) - extends GenIncOptimizer(semantics, esLevel, considerPositions) { +final class IncOptimizer(semantics: Semantics, esLevel: ESLevel) + extends GenIncOptimizer(semantics, esLevel) { private[optimizer] object CollOps extends GenIncOptimizer.AbsCollOps { type Map[K, V] = mutable.Map[K, V] @@ -169,5 +168,5 @@ final class IncOptimizer(semantics: Semantics, esLevel: ESLevel, } object IncOptimizer { - val factory: GenIncOptimizer.OptimizerFactory = new IncOptimizer(_, _, _) + val factory: GenIncOptimizer.OptimizerFactory = new IncOptimizer(_, _) } From be9e1c26387090776fa804d068869117644e0e22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 27 May 2017 12:04:33 +0200 Subject: [PATCH 0412/2665] Move the `sourceMap` configuration option to `LinkerBackend.Config`. As it is now used only by the backend, it makes more sense to put it there. --- .../tools/linker/LinkerPlatformExtensions.scala | 2 +- .../tools/linker/LinkerPlatformExtensions.scala | 5 ++--- .../backend/closure/ClosureLinkerBackend.scala | 6 ++---- .../org/scalajs/core/tools/linker/Linker.scala | 15 ++++++--------- .../core/tools/linker/StandardLinker.scala | 2 +- .../tools/linker/backend/BasicLinkerBackend.scala | 6 ++---- .../core/tools/linker/backend/LinkerBackend.scala | 9 +++++++-- 7 files changed, 21 insertions(+), 24 deletions(-) diff --git a/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala b/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala index 08a9ae8d8a..0355ff6007 100644 --- a/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala +++ b/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala @@ -27,7 +27,7 @@ trait LinkerPlatformExtensions { this: Linker.type => config.frontendConfig, optOptimizerFactory) val backend = new BasicLinkerBackend(semantics, outputMode, moduleKind, - config.sourceMap, config.backendConfig) + config.backendConfig) new Linker(frontend, backend) } diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala index d04d7b4a81..8e42cdea2d 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala @@ -32,11 +32,10 @@ trait LinkerPlatformExtensions { this: Linker.type => if (config.closureCompiler) { require(outputMode == OutputMode.ECMAScript51Isolated, s"Cannot use output mode $outputMode with the Closure Compiler") - new ClosureLinkerBackend(semantics, moduleKind, - config.sourceMap, config.backendConfig) + new ClosureLinkerBackend(semantics, moduleKind, config.backendConfig) } else { new BasicLinkerBackend(semantics, outputMode, moduleKind, - config.sourceMap, config.backendConfig) + config.backendConfig) } } diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala index a33db3789a..c09555349c 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala @@ -36,10 +36,8 @@ import org.scalajs.core.tools.linker.backend.emitter.{Emitter, CoreJSLibs} final class ClosureLinkerBackend( semantics: Semantics, moduleKind: ModuleKind, - withSourceMap: Boolean, config: LinkerBackend.Config -) extends LinkerBackend(semantics, ESLevel.ES5, moduleKind, withSourceMap, - config) { +) extends LinkerBackend(semantics, ESLevel.ES5, moduleKind, config) { private[this] val emitter = { new Emitter(semantics, OutputMode.ECMAScript51Isolated, moduleKind) @@ -174,7 +172,7 @@ final class ClosureLinkerBackend( options.setLanguageIn(ClosureOptions.LanguageMode.ECMASCRIPT5) options.setCheckGlobalThisLevel(CheckLevel.OFF) - if (withSourceMap) { + if (config.sourceMap) { options.setSourceMapOutputPath(outputName + ".map") options.setSourceMapDetailLevel(SourceMap.DetailLevel.ALL) } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala index 806ed29d26..54a930a3d9 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala @@ -78,8 +78,6 @@ final class Linker(frontend: LinkerFrontend, backend: LinkerBackend) object Linker extends LinkerPlatformExtensions { /** Configuration to be passed to the `apply()` method. */ final class Config private ( - /** Whether to generate source maps. */ - val sourceMap: Boolean, /** Whether to use the Scala.js optimizer. */ val optimizer: Boolean, /** Whether things that can be parallelized should be parallelized. @@ -95,9 +93,6 @@ object Linker extends LinkerPlatformExtensions { /** Additional configuration for the linker backend. */ val backendConfig: LinkerBackend.Config ) { - def withSourceMap(sourceMap: Boolean): Config = - copy(sourceMap = sourceMap) - def withOptimizer(optimizer: Boolean): Config = copy(optimizer = optimizer) @@ -110,18 +105,22 @@ object Linker extends LinkerPlatformExtensions { def withFrontendConfig(frontendConfig: LinkerFrontend.Config): Config = copy(frontendConfig = frontendConfig) + def withFrontendConfig(f: LinkerFrontend.Config => LinkerFrontend.Config): Config = + copy(frontendConfig = f(frontendConfig)) + def withBackendConfig(backendConfig: LinkerBackend.Config): Config = copy(backendConfig = backendConfig) + def withBackendConfig(f: LinkerBackend.Config => LinkerBackend.Config): Config = + copy(backendConfig = f(backendConfig)) + private def copy( - sourceMap: Boolean = sourceMap, optimizer: Boolean = optimizer, parallel: Boolean = parallel, closureCompilerIfAvailable: Boolean = closureCompilerIfAvailable, frontendConfig: LinkerFrontend.Config = frontendConfig, backendConfig: LinkerBackend.Config = backendConfig): Config = { new Config( - sourceMap = sourceMap, optimizer = optimizer, parallel = parallel, closureCompilerIfAvailable = closureCompilerIfAvailable, @@ -138,7 +137,6 @@ object Linker extends LinkerPlatformExtensions { /** Default configuration. * - * - `sourceMap`: true * - `optimizer`: true * - `parallel`: true * - `closureCompilerIfAvailable`: false @@ -149,7 +147,6 @@ object Linker extends LinkerPlatformExtensions { */ def apply(): Config = { new Config( - sourceMap = true, optimizer = true, parallel = true, closureCompilerIfAvailable = false, 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 912a2aeb3c..8c88a29161 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 @@ -23,11 +23,11 @@ object StandardLinker { .withCheckIR(config.checkIR) val backendConfig = LinkerBackend.Config() + .withSourceMap(config.sourceMap) .withRelativizeSourceMapBase(config.relativizeSourceMapBase) .withPrettyPrint(config.prettyPrint) val oldAPIConfig = Linker.Config() - .withSourceMap(config.sourceMap) .withOptimizer(config.optimizer) .withParallel(config.parallel) .withClosureCompilerIfAvailable(config.closureCompilerIfAvailable) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala index a779d492c0..ee849c1ad3 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala @@ -25,10 +25,8 @@ final class BasicLinkerBackend( semantics: Semantics, outputMode: OutputMode, moduleKind: ModuleKind, - withSourceMap: Boolean, config: LinkerBackend.Config -) extends LinkerBackend(semantics, outputMode.esLevel, moduleKind, - withSourceMap, config) { +) extends LinkerBackend(semantics, outputMode.esLevel, moduleKind, config) { private[this] val emitter = new Emitter(semantics, outputMode, moduleKind) @@ -58,7 +56,7 @@ final class BasicLinkerBackend( } private def newBuilder(output: WritableVirtualJSFile): JSFileBuilder = { - if (withSourceMap) { + if (config.sourceMap) { new JSFileBuilderWithSourceMap(output.name, output.contentWriter, output.sourceMapWriter, config.relativizeSourceMapBase) } else { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala index b598bb3c75..82073a12fd 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala @@ -29,7 +29,6 @@ abstract class LinkerBackend( val semantics: Semantics, val esLevel: ESLevel, val moduleKind: ModuleKind, - val withSourceMap: Boolean, protected val config: LinkerBackend.Config) { /** Symbols this backend needs to be present in the linking unit. */ @@ -61,11 +60,16 @@ abstract class LinkerBackend( object LinkerBackend { /** Configurations relevant to the backend */ final class Config private ( + /** Whether to emit a source map. */ + val sourceMap: Boolean = true, /** Base path to relativize paths in the source map. */ val relativizeSourceMapBase: Option[URI] = None, /** Pretty-print the output. */ val prettyPrint: Boolean = false ) { + def withSourceMap(sourceMap: Boolean): Config = + copy(sourceMap = sourceMap) + def withRelativizeSourceMapBase(relativizeSourceMapBase: Option[URI]): Config = copy(relativizeSourceMapBase = relativizeSourceMapBase) @@ -73,9 +77,10 @@ object LinkerBackend { copy(prettyPrint = prettyPrint) private def copy( + sourceMap: Boolean = sourceMap, relativizeSourceMapBase: Option[URI] = relativizeSourceMapBase, prettyPrint: Boolean = prettyPrint): Config = { - new Config(relativizeSourceMapBase, prettyPrint) + new Config(sourceMap, relativizeSourceMapBase, prettyPrint) } } From d57ce943825d29ff8016008eeef0d3d7ab65f1c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 5 Jul 2017 16:20:00 +0200 Subject: [PATCH 0413/2665] Remove the distinction tree/pos in `TreeHash`. Since positions are now always taken into account when comparing `TreeHash`es, the distinction is only a source of complexity and slight performance hit. --- .../scala/org/scalajs/core/ir/Hashers.scala | 49 +++++++------------ .../org/scalajs/core/ir/Serializers.scala | 14 ++---- .../scala/org/scalajs/core/ir/Trees.scala | 10 ++-- .../tools/linker/frontend/BaseLinker.scala | 4 +- .../frontend/optimizer/GenIncOptimizer.scala | 2 +- 5 files changed, 33 insertions(+), 46 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala index 6921085372..7bcf2ed3f8 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala @@ -43,26 +43,18 @@ object Hashers { classDef.optimizerHints)(classDef.pos) } - def hashesEqual(x: TreeHash, y: TreeHash, considerPos: Boolean): Boolean = { - Arrays.equals(x.treeHash, y.treeHash) && - (!considerPos || Arrays.equals(x.posHash, y.posHash)) - } + def hashesEqual(x: TreeHash, y: TreeHash): Boolean = + Arrays.equals(x.hash, y.hash) - def hashAsVersion(hash: TreeHash, considerPos: Boolean): String = { - // 2 chars per byte, 20 bytes per hash - val size = 2 * (if (considerPos) 2 else 1) * 20 + def hashAsVersion(hash: TreeHash): String = { + // 2 chars per byte, 20 bytes in a hash + val size = 2 * 20 val builder = new StringBuilder(size) def hexDigit(digit: Int): Char = Character.forDigit(digit, 16) - def append(hash: Array[Byte]): Unit = { - for (b <- hash) - builder.append(hexDigit(b >> 4)).append(hexDigit(b & 0xF)) - } - append(hash.treeHash) - - if (considerPos) - append(hash.posHash) + for (b <- hash.hash) + builder.append(hexDigit(b >> 4)).append(hexDigit(b & 0xF)) builder.toString } @@ -77,14 +69,11 @@ object Hashers { new DataOutputStream(digOut) } - private[this] val treeDigest = newDigest - private[this] val treeStream = newDigestStream(treeDigest) - - private[this] val posDigest = newDigest - private[this] val posStream = newDigestStream(posDigest) + private[this] val digest = newDigest + private[this] val digestStream = newDigestStream(digest) def finalizeHash(): TreeHash = - new TreeHash(treeDigest.digest(), posDigest.digest()) + new TreeHash(digest.digest()) def mixParamDef(paramDef: ParamDef): Unit = { mixPos(paramDef.pos) @@ -516,31 +505,31 @@ object Hashers { } def mixPos(pos: Position): Unit = { - posStream.writeUTF(pos.source.toString) - posStream.writeInt(pos.line) - posStream.writeInt(pos.column) + digestStream.writeUTF(pos.source.toString) + digestStream.writeInt(pos.line) + digestStream.writeInt(pos.column) } @inline final def mixTag(tag: Int): Unit = mixInt(tag) @inline - final def mixString(str: String): Unit = treeStream.writeUTF(str) + final def mixString(str: String): Unit = digestStream.writeUTF(str) @inline - final def mixInt(i: Int): Unit = treeStream.writeInt(i) + final def mixInt(i: Int): Unit = digestStream.writeInt(i) @inline - final def mixLong(l: Long): Unit = treeStream.writeLong(l) + final def mixLong(l: Long): Unit = digestStream.writeLong(l) @inline - final def mixBoolean(b: Boolean): Unit = treeStream.writeBoolean(b) + final def mixBoolean(b: Boolean): Unit = digestStream.writeBoolean(b) @inline - final def mixFloat(f: Float): Unit = treeStream.writeFloat(f) + final def mixFloat(f: Float): Unit = digestStream.writeFloat(f) @inline - final def mixDouble(d: Double): Unit = treeStream.writeDouble(d) + final def mixDouble(d: Double): Unit = digestStream.writeDouble(d) } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index a5a1b839bd..72768d8e79 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -684,10 +684,8 @@ object Serializers { def writeOptHash(optHash: Option[TreeHash]): Unit = { buffer.writeBoolean(optHash.isDefined) - for (hash <- optHash) { - buffer.write(hash.treeHash) - buffer.write(hash.posHash) - } + for (hash <- optHash) + buffer.write(hash.hash) } def writeString(s: String): Unit = @@ -1050,11 +1048,9 @@ object Serializers { def readOptHash(): Option[TreeHash] = { if (input.readBoolean()) { - val treeHash = new Array[Byte](20) - val posHash = new Array[Byte](20) - input.readFully(treeHash) - input.readFully(posHash) - Some(new TreeHash(treeHash, posHash)) + val hash = new Array[Byte](20) + input.readFully(hash) + Some(new TreeHash(hash)) } else None } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 01af0ca8c1..62f53fc6db 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -955,9 +955,11 @@ object Trees { } - /** A hash of a tree (usually a MethodDef). Contains two SHA-1 hashes */ - final class TreeHash(val treeHash: Array[Byte], val posHash: Array[Byte]) { - assert(treeHash.length == 20) - assert(posHash.length == 20) + /** A hash of a tree (usually a MethodDef). + * + * Contains a SHA-1 hash. + */ + final class TreeHash(val hash: Array[Byte]) { + assert(hash.length == 20) } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index 5dccdf8509..5aabf985ff 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -169,7 +169,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel) { def linkedMethod(m: MethodDef) = { val info = memberInfoByStaticAndName((m.static, m.name.encodedName)) - val version = m.hash.map(Hashers.hashAsVersion(_, considerPos = true)) + val version = m.hash.map(Hashers.hashAsVersion(_)) new LinkedMember(info, m, version) } @@ -180,7 +180,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel) { def linkedSyntheticMethod(m: MethodDef) = { val info = Infos.generateMethodInfo(m) - val version = m.hash.map(Hashers.hashAsVersion(_, considerPos = true)) + val version = m.hash.map(Hashers.hashAsVersion(_)) new LinkedMember(info, m, version) } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala index 8ca07bcb55..b8977066d8 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala @@ -901,7 +901,7 @@ abstract class GenIncOptimizer private[optimizer] (semantics: Semantics, val changed = { originalDef == null || (methodDef.hash zip originalDef.hash).forall { - case (h1, h2) => !Hashers.hashesEqual(h1, h2, considerPos = true) + case (h1, h2) => !Hashers.hashesEqual(h1, h2) } } From 78e7dd3899b4bee1f664cd3ee0e39dffa5cbbdbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 22 Jul 2017 14:03:09 +0200 Subject: [PATCH 0414/2665] Reduce the maximum memory consumption in the bootstrap test. We do this by restarting sbt more often, so that irJS, testSuite and toolsJS are full-optimized in 3 separate VMs. --- ci/matrix.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ci/matrix.xml b/ci/matrix.xml index 6772179e2d..e42608467e 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -205,7 +205,10 @@ setJavaVersion $java sbt ++$scala irJS/test toolsJS/test && sbt 'set scalaJSStage in Global := FullOptStage' \ - ++$scala irJS/test toolsJS/test + ++$scala irJS/test && + sbt ++$scala testSuite/test:fullOptJS && + sbt 'set scalaJSStage in Global := FullOptStage' \ + ++$scala toolsJS/test ]]> Date: Sat, 22 Jul 2017 11:08:39 +0200 Subject: [PATCH 0415/2665] Fix #3064: Validate the target type of Is/AsInstanceOf nodes. They must not be primitive types nor JS types. --- .../core/tools/linker/checker/IRChecker.scala | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 429360c974..16f3bab15b 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -893,9 +893,11 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { case IsInstanceOf(expr, cls) => typecheckExpr(expr, env) + checkIsAsInstanceTargetType(cls) case AsInstanceOf(expr, cls) => typecheckExpr(expr, env) + checkIsAsInstanceTargetType(cls) case Unbox(expr, _) => typecheckExpr(expr, env) @@ -1059,6 +1061,28 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { reportError(s"Duplicate label named ${label.name}.") } + private def checkIsAsInstanceTargetType(refType: ReferenceType)( + implicit ctx: ErrorContext): Unit = { + refType match { + case ClassType(encodedName) => + if (Definitions.isPrimitiveClass(encodedName)) { + reportError( + s"Primitive type $encodedName is not a valid target type for " + + "Is/AsInstanceOf") + } else { + val kind = lookupClass(encodedName).kind + if (kind.isJSType) { + reportError( + s"JS type $encodedName is not a valid target type for " + + "Is/AsInstanceOf") + } + } + + case ArrayType(_, _) => + // Nothing to check + } + } + private def inferMethodType(encodedName: String, isStatic: Boolean)( implicit ctx: ErrorContext): (List[Type], Type) = { From 4e0ab34cd2fa49e60e1c05e96db996f4b9d6f1ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 25 Jul 2017 17:33:18 +0200 Subject: [PATCH 0416/2665] IR check that module classes have exactly one, parameterless ctor. --- .../scalajs/core/tools/linker/checker/IRChecker.scala | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 53316f6b02..1c665f2048 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -138,6 +138,16 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { reportError(s"Duplicate static field with name '${duplicate.name}'") } + // Module classes must have exactly one constructor, without parameter + if (classDef.kind == ClassKind.ModuleClass) { + implicit val ctx = ErrorContext(classDef) + val methods = classDef.memberMethods + if (methods.count(m => isConstructorName(m.info.encodedName)) != 1) + reportError(s"Module class must have exactly 1 constructor") + if (!methods.exists(_.info.encodedName == "init___")) + reportError(s"Module class must have a parameterless constructor") + } + // Check exported members for (member <- classDef.exportedMembers) { implicit val ctx = ErrorContext(member.tree) From ace0c214f3650d104a7dd9ffc5c6197847740744 Mon Sep 17 00:00:00 2001 From: tOverney Date: Sun, 23 Jul 2017 17:55:08 +0200 Subject: [PATCH 0417/2665] Inline init methods in the JS constructors. At definition site, instead of having a constructor that only creates fields, and an `init___XYZ` method for the actual constructor, we inline the body of the `init___XYZ` method inside the JavaScript constructor, giving: class $c_Foo extends $c_O { constructor(args) { super(); this.x$1 = 0; this.y$1 = 0; // body of the init method } } At call site, this allows to emit new $c_Foo(args); instead of new $c_Foo().init___XYZ(args); This produces shorter code, and is potentially friendlier to JavaScript JITs. We can do this for a class when all of the following apply: * The class is not instantiated from `scalajsenv.js`, unless it has exactly one constructor and it is final * It does not have any instantiated subclasses * It has exactly one (regular) constructor * It does not have any exported constructor --- ci/checksizes.sh | 32 ++--- .../scala/scalajs/runtime/StackTrace.scala | 36 +++--- tools/scalajsenv.js | 2 +- .../linker/backend/emitter/ClassEmitter.scala | 115 ++++++++++++++---- .../linker/backend/emitter/Emitter.scala | 42 ++++++- .../backend/emitter/FunctionEmitter.scala | 16 ++- .../backend/emitter/GlobalKnowledge.scala | 14 +++ .../backend/emitter/KnowledgeGuardian.scala | 89 +++++++++++++- 8 files changed, 275 insertions(+), 71 deletions(-) diff --git a/ci/checksizes.sh b/ci/checksizes.sh index ebe90022c4..db95cee443 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -37,28 +37,28 @@ REVERSI_OPT_GZ_SIZE=$(stat '-c%s' "$REVERSI_OPT.gz") case $FULLVER in 2.10.2) - REVERSI_PREOPT_EXPECTEDSIZE=532000 - REVERSI_OPT_EXPECTEDSIZE=122000 - REVERSI_PREOPT_GZ_EXPECTEDSIZE=71000 - REVERSI_OPT_GZ_EXPECTEDSIZE=31000 + REVERSI_PREOPT_EXPECTEDSIZE=512000 + REVERSI_OPT_EXPECTEDSIZE=114000 + REVERSI_PREOPT_GZ_EXPECTEDSIZE=69000 + REVERSI_OPT_GZ_EXPECTEDSIZE=30000 ;; 2.11.11) - REVERSI_PREOPT_EXPECTEDSIZE=527000 - REVERSI_OPT_EXPECTEDSIZE=124000 - REVERSI_PREOPT_GZ_EXPECTEDSIZE=71000 - REVERSI_OPT_GZ_EXPECTEDSIZE=32000 + REVERSI_PREOPT_EXPECTEDSIZE=509000 + REVERSI_OPT_EXPECTEDSIZE=116000 + REVERSI_PREOPT_GZ_EXPECTEDSIZE=69000 + REVERSI_OPT_GZ_EXPECTEDSIZE=30000 ;; 2.12.2) - REVERSI_PREOPT_EXPECTEDSIZE=629000 - REVERSI_OPT_EXPECTEDSIZE=147000 - REVERSI_PREOPT_GZ_EXPECTEDSIZE=76000 - REVERSI_OPT_GZ_EXPECTEDSIZE=33000 + REVERSI_PREOPT_EXPECTEDSIZE=608000 + REVERSI_OPT_EXPECTEDSIZE=138000 + REVERSI_PREOPT_GZ_EXPECTEDSIZE=74000 + REVERSI_OPT_GZ_EXPECTEDSIZE=32000 ;; 2.13.0-M1) - REVERSI_PREOPT_EXPECTEDSIZE=627000 - REVERSI_OPT_EXPECTEDSIZE=147000 - REVERSI_PREOPT_GZ_EXPECTEDSIZE=76000 - REVERSI_OPT_GZ_EXPECTEDSIZE=33000 + REVERSI_PREOPT_EXPECTEDSIZE=606000 + REVERSI_OPT_EXPECTEDSIZE=138000 + REVERSI_PREOPT_GZ_EXPECTEDSIZE=75000 + REVERSI_OPT_GZ_EXPECTEDSIZE=32000 ;; esac diff --git a/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala b/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala index 48303008a6..91a493ecfb 100644 --- a/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala +++ b/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala @@ -168,6 +168,7 @@ object StackTrace { * * The recognized patterns are * {{{ + * new \$c_ * \$c_.prototype. * \$c_. * \$s___ @@ -175,6 +176,7 @@ object StackTrace { * \$m_ * }}} * all of them optionally prefixed by `Object.` or `[object Object].`. + * (it comes after the "new " for the patterns where it start with a "new ") * * When the function name is none of those, the pair * `("", functionName)` @@ -184,27 +186,25 @@ object StackTrace { private def extractClassMethod(functionName: String): (String, String) = { val PatC = """^(?:Object\.|\[object Object\]\.)?\$c_([^\.]+)(?:\.prototype)?\.([^\.]+)$""".re val PatS = """^(?:Object\.|\[object Object\]\.)?\$[sf]_((?:_[^_]|[^_])+)__([^\.]+)$""".re + val PatN = """^new (?:Object\.|\[object Object\]\.)?\$c_([^\.]+)$""".re val PatM = """^(?:Object\.|\[object Object\]\.)?\$m_([^\.]+)$""".re - var isModule = false - var mtch = PatC.exec(functionName) - if (mtch eq null) { - mtch = PatS.exec(functionName) - if (mtch eq null) { - mtch = PatM.exec(functionName) - isModule = true - } - } - - if (mtch ne null) { - val className = decodeClassName(mtch(1).get) - val methodName = if (isModule) - "" // that's how it would be reported on the JVM - else - decodeMethodName(mtch(2).get) - (className, methodName) + val matchC = PatC.exec(functionName) + val matchCOrS = if (matchC ne null) matchC else PatS.exec(functionName) + if (matchCOrS ne null) { + (decodeClassName(matchCOrS(1).get), decodeMethodName(matchCOrS(2).get)) } else { - ("", functionName) + val matchN = PatN.exec(functionName) + if (matchN ne null) { + (decodeClassName(matchN(1).get), "") + } else { + val matchM = PatM.exec(functionName) + if (matchM ne null) { + (decodeClassName(matchM(1).get), "") + } else { + ("", functionName) + } + } } } diff --git a/tools/scalajsenv.js b/tools/scalajsenv.js index 291a2d4dbe..b448aef705 100644 --- a/tools/scalajsenv.js +++ b/tools/scalajsenv.js @@ -922,7 +922,7 @@ $TypeData.prototype.getClassOf = function() { getClassOf() { //!endif if (!this._classOf) - this._classOf = new $c_jl_Class().init___jl_ScalaJSClassData(this); + this._classOf = new $c_jl_Class(this); return this._classOf; }; diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index 0cebd06760..7f5f49b017 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -133,8 +133,27 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { yield js.ClassDef(Some(classIdent), parentVar, members)(tree.pos) } + /** Extracts the inlineable init method, if there is one. */ + def extractInlineableInit(tree: LinkedClass)( + implicit globalKnowledge: GlobalKnowledge): (Option[LinkedMember[MethodDef]], List[LinkedMember[MethodDef]]) = { + + val memberMethods = tree.memberMethods + + if (globalKnowledge.hasInlineableInit(tree.encodedName)) { + val (constructors, otherMethods) = memberMethods.partition { method => + Definitions.isConstructorName(method.info.encodedName) + } + assert(constructors.size == 1, + s"Found ${constructors.size} constructors in class " + + s"${tree.encodedName} which has an inlined init.") + (Some(constructors.head), otherMethods) + } else { + (None, memberMethods) + } + } + /** Generates the JS constructor for a class. */ - def genConstructor(tree: LinkedClass)( + def genConstructor(tree: LinkedClass, initToInline: Option[MethodDef])( implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { assert(tree.kind.isAnyNonNativeClass) @@ -143,15 +162,16 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { outputMode match { case OutputMode.ECMAScript51Isolated => - genES5Constructor(tree) + genES5Constructor(tree, initToInline) case OutputMode.ECMAScript6 => - genES6Constructor(tree) + genES6Constructor(tree, initToInline) } } /** Generates the JS constructor for a class, ES5 style. */ - private def genES5Constructor(tree: LinkedClass)( + private def genES5Constructor(tree: LinkedClass, + initToInline: Option[MethodDef])( implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { import TreeDSL._ implicit val pos = tree.pos @@ -177,8 +197,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { js.DotSelect(encodeClassVar(parentIdent.name), js.Ident("call")), List(js.This())) } - val fieldDefs = genFieldDefsOfScalaClass(tree) - WithGlobals(js.Function(Nil, js.Block(superCtorCall :: fieldDefs))) + genJSConstructorFun(tree, superCtorCall, initToInline) } else { genConstructorFunForJSClass(tree) } @@ -220,7 +239,8 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { } /** Generates the JS constructor for a class, ES6 style. */ - private def genES6Constructor(tree: LinkedClass)( + private def genES6Constructor(tree: LinkedClass, + initToInline: Option[MethodDef])( implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { implicit val pos = tree.pos @@ -230,18 +250,73 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { fun.body) } } else { - val fieldDefs = genFieldDefsOfScalaClass(tree) - if (fieldDefs.isEmpty && outputMode == OutputMode.ECMAScript6) { - WithGlobals(js.Skip()) - } else { - val superCtorCall = tree.superClass.fold[js.Tree] { - js.Skip()(tree.pos) - } { parentIdent => - js.Apply(js.Super(), Nil) + val superCtorCall = tree.superClass.fold[js.Tree] { + js.Skip()(tree.pos) + } { parentIdent => + js.Apply(js.Super(), Nil) + } + + val jsConstructorFunWithGlobals = + genJSConstructorFun(tree, superCtorCall, initToInline) + + for (jsConstructorFun <- jsConstructorFunWithGlobals) yield { + val js.Function(args, body) = jsConstructorFun + if (args.isEmpty && (body eq superCtorCall)) + js.Skip() + else + js.MethodDef(static = false, js.Ident("constructor"), args, body) + } + } + } + + /** Generates the JavaScript constructor of a class, as a `js.Function`. + * + * For ECMAScript 2015, that `js.Function` must be decomposed and reformed + * into a `js.MethodDef` afterwards. + * + * The generated function performs the following steps: + * + * - Call the super constructor, as specified by `superCtorCall` + * - Create the fields of the current class, initialized to the zero of + * their respective types + * - Executes the body of the `init` method to inline, if any + * + * @param tree + * The `LinkedClass` for which we generate a JS constructor. + * + * @param superCtorCall + * The call to the super JS constructor. This will be different depending + * on the output mode. + * + * @param initToInline + * The `init` method to inline in the JS constructor, if any. + */ + private def genJSConstructorFun(tree: LinkedClass, superCtorCall: js.Tree, + initToInline: Option[MethodDef])( + implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Function] = { + + implicit val pos = tree.pos + + val fieldDefs = genFieldDefsOfScalaClass(tree) + + initToInline.fold { + WithGlobals(js.Function(Nil, js.Block(superCtorCall :: fieldDefs))) + } { initMethodDef => + val generatedInitMethodFunWithGlobals = { + implicit val pos = initMethodDef.pos + val initMethodBody = initMethodDef.body.getOrElse { + throw new AssertionError("Cannot generate an abstract constructor") } - val methodDef = js.MethodDef(static = false, js.Ident("constructor"), - Nil, js.Block(superCtorCall :: fieldDefs)) - WithGlobals(methodDef) + assert(initMethodDef.resultType == NoType, + s"Found a constructor with type ${initMethodDef.resultType} at $pos") + desugarToFunction(tree.encodedName, initMethodDef.args, initMethodBody, + isStat = true) + } + + for (generatedInitMethodFun <- generatedInitMethodFunWithGlobals) yield { + val js.Function(args, initMethodFunBody) = generatedInitMethodFun + js.Function(args, + js.Block(superCtorCall :: fieldDefs ::: initMethodFunBody :: Nil)) } } } @@ -870,9 +945,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { genNonNativeJSClassConstructor(className), Nil) } else { - js.Apply( - js.New(encodeClassVar(className), Nil) DOT js.Ident("init___"), - Nil) + js.New(encodeClassVar(className), Nil) } } } diff --git 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 index 30e8e6cd6c..14a8abc3f6 100644 --- 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 @@ -345,11 +345,27 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, // Class definition if (linkedClass.hasInstances && kind.isAnyNonNativeClass) { - val ctor = classTreeCache.constructor.getOrElseUpdate( - classEmitter.genConstructor(linkedClass)(classCache)) + val (linkedInlineableInit, linkedMemberMethods) = + classEmitter.extractInlineableInit(linkedClass)(classCache) + + // JS constructor + val ctor = { + /* The constructor depends both on the class version, and the version + * of the inlineable init, if there is one. + */ + val ctorCache = classCache.getConstructorCache() + val ctorVersion = linkedInlineableInit.fold[Option[String]] { + linkedClass.version.map("1-" + _) + } { linkedInit => + mergeVersions(linkedClass.version, linkedInit.version).map("2-" + _) + } + val initToInline = linkedInlineableInit.map(_.tree) + ctorCache.getOrElseUpdate(ctorVersion, + classEmitter.genConstructor(linkedClass, initToInline)(ctorCache)) + } // Normal methods - val memberMethods = for (m <- linkedClass.memberMethods) yield { + val memberMethods = for (m <- linkedMemberMethods) yield { val methodCache = classCache.getMethodCache(m.info.encodedName) methodCache.getOrElseUpdate(m.version, @@ -444,6 +460,11 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, // Helpers + private def mergeVersions(v1: Option[String], + v2: Option[String]): Option[String] = { + v1.flatMap(s1 => v2.map(s2 => s1.length + "-" + s1 + s2)) + } + private def getClassTreeCache(linkedClass: LinkedClass): DesugaredClassCache = getClassCache(linkedClass.ancestors).getCache(linkedClass.version) @@ -474,6 +495,8 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, private[this] val _staticCaches = mutable.Map.empty[String, MethodCache] private[this] val _methodCaches = mutable.Map.empty[String, MethodCache] + private[this] var _constructorCache: Option[MethodCache] = None + override def invalidate(): Unit = { /* Do not invalidate contained methods, as they have their own * invalidation logic. @@ -487,6 +510,7 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, _cacheUsed = false _staticCaches.valuesIterator.foreach(_.startRun()) _methodCaches.valuesIterator.foreach(_.startRun()) + _constructorCache.foreach(_.startRun()) } def getCache(version: Option[String]): DesugaredClassCache = { @@ -508,10 +532,21 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, def getMethodCache(encodedName: String): MethodCache = _methodCaches.getOrElseUpdate(encodedName, new MethodCache) + def getConstructorCache(): MethodCache = { + _constructorCache.getOrElse { + val cache = new MethodCache + _constructorCache = Some(cache) + cache + } + } + def cleanAfterRun(): Boolean = { _staticCaches.retain((_, c) => c.cleanAfterRun()) _methodCaches.retain((_, c) => c.cleanAfterRun()) + if (_constructorCache.exists(!_.cleanAfterRun())) + _constructorCache = None + if (!_cacheUsed) invalidate() @@ -557,7 +592,6 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, private object Emitter { private final class DesugaredClassCache { - val constructor = new OneTimeCache[WithGlobals[js.Tree]] val exportedMembers = new OneTimeCache[WithGlobals[js.Tree]] val instanceTests = new OneTimeCache[js.Tree] val typeData = new OneTimeCache[WithGlobals[js.Tree]] diff --git 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 index 1fe785ff54..f6f7c5c4d8 100644 --- 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 @@ -1842,11 +1842,17 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { // Scala expressions case New(cls, ctor, args) => - js.Apply( - js.DotSelect( - js.New(encodeClassVar(cls.className), Nil), - transformPropIdent(ctor)), - args map transformExpr) + val encodedClassVar = encodeClassVar(cls.className) + val newArgs = args.map(transformExpr) + if (globalKnowledge.hasInlineableInit(cls.className)) { + js.New(encodedClassVar, newArgs) + } else { + js.Apply( + js.DotSelect( + js.New(encodedClassVar, Nil), + transformPropIdent(ctor)), + newArgs) + } case LoadModule(cls) => genLoadModule(cls.className) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala index 89bdbe4371..dad8f4ce6e 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala @@ -18,6 +18,20 @@ private[emitter] trait GlobalKnowledge { /** Tests whether the specified class name refers to an `Interface`. */ def isInterface(className: String): Boolean + /** Tests whether the specified class uses an inlineable init. + * + * When it does, its (only) `init___` method is inlined inside the JS + * constructor. This means that instantiation should look like + * {{{ + * new \$c_Foo(args) + * }}} + * instead of + * {{{ + * new \$c_Foo().init___XY(args) + * }}} + */ + def hasInlineableInit(className: String): Boolean + /** `None` for non-native JS classes/objects; `Some(spec)` for native JS * classes/objects. * diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala index bd275f24c1..d0e0c61680 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala @@ -12,7 +12,7 @@ package org.scalajs.core.tools.linker.backend.emitter import scala.collection.mutable import org.scalajs.core.ir.{ClassKind, Definitions} -import org.scalajs.core.ir.Trees.{FieldDef, JSNativeLoadSpec} +import org.scalajs.core.ir.Trees._ import org.scalajs.core.tools.linker._ @@ -37,15 +37,20 @@ private[emitter] final class KnowledgeGuardian { * the rare events where they do change. */ def update(linkingUnit: LinkingUnit): Boolean = { + val hasInlineableInit = computeHasInlineableInit(linkingUnit) + var newIsParentDataAccessed = false // Update classes for (linkedClass <- linkingUnit.classDefs) { - classes.get(linkedClass.encodedName).fold[Unit] { + val encodedName = linkedClass.encodedName + val thisClassHasInlineableInit = hasInlineableInit(encodedName) + classes.get(encodedName).fold[Unit] { // new class - classes.put(linkedClass.encodedName, new Class(linkedClass)) + classes.put(encodedName, + new Class(linkedClass, thisClassHasInlineableInit)) } { existingCls => - existingCls.update(linkedClass) + existingCls.update(linkedClass, thisClassHasInlineableInit) } def methodExists(encodedName: String): Boolean = @@ -73,6 +78,57 @@ private[emitter] final class KnowledgeGuardian { invalidateAll } + private def computeHasInlineableInit(linkingUnit: LinkingUnit): Set[String] = { + /* Those classes are instantiated in scalajsenv.js. Since they have + * multiple constructors and/or are not final, scalajsenv.js is written + * with the assumption that they will not have an inlineable init. We + * therefore blacklist them here so that this is always true. + * + * Note that j.l.Class is not in this list, because it has only one + * constructor and is final, so even scalajsenv.js can assume it always + * has an inlineable init. + */ + val blackList = Set( + "jl_ClassCastException", + "jl_ArrayIndexOutOfBoundsException", + "sjsr_UndefinedBehaviorError", + "js_CloneNotSupportedException" + ) + + val scalaClassDefs = linkingUnit.classDefs.filter(_.kind.isClass) + + val classesWithInstantiatedSubclasses = scalaClassDefs + .withFilter(_.hasInstances) + .flatMap(_.superClass) + .map(_.name) + .toSet + + def enableInlineableInitFor(classDef: LinkedClass): Boolean = { + /* We can enable inlined init if all of the following apply: + * - The class is not blacklisted + * - It does not have any instantiated subclass + * - It has exactly one (regular) constructor + * - It does not have any exported constructor (since they are + * effectively secondary constructors) + * + * By construction, this is always true for module classes. + */ + !blackList(classDef.encodedName) && + !classesWithInstantiatedSubclasses(classDef.encodedName) && { + classDef.memberMethods.count( + x => Definitions.isConstructorName(x.info.encodedName)) == 1 + } && { + !classDef.topLevelExports.exists( + _.isInstanceOf[TopLevelConstructorExportDef]) + } + } + + scalaClassDefs + .withFilter(enableInlineableInitFor(_)) + .map(_.encodedName) + .toSet + } + abstract class KnowledgeAccessor extends GlobalKnowledge with Invalidatable { /* In theory, a KnowledgeAccessor should *contain* a GlobalKnowledge, not * *be* a GlobalKnowledge. We organize it that way to reduce memory @@ -85,6 +141,9 @@ private[emitter] final class KnowledgeGuardian { def isInterface(className: String): Boolean = classes(className).askIsInterface(this) + def hasInlineableInit(className: String): Boolean = + classes(className).askHasInlineableInit(this) + def getJSNativeLoadSpec(className: String): Option[JSNativeLoadSpec] = classes(className).askJSNativeLoadSpec(this) @@ -120,20 +179,25 @@ private[emitter] object KnowledgeGuardian { } } - private class Class(initClass: LinkedClass) extends Unregisterable { + private class Class(initClass: LinkedClass, + initHasInlineableInit: Boolean) + extends Unregisterable { + private var isAlive: Boolean = true private var isInterface = computeIsInterface(initClass) + private var hasInlineableInit = initHasInlineableInit private var jsNativeLoadSpec = computeJSNativeLoadSpec(initClass) private var jsSuperClass = computeJSSuperClass(initClass) private var jsClassFieldDefs = computeJSClassFieldDefs(initClass) private val isInterfaceAskers = mutable.Set.empty[Invalidatable] + private val hasInlineableInitAskers = mutable.Set.empty[Invalidatable] private val jsNativeLoadSpecAskers = mutable.Set.empty[Invalidatable] private val jsSuperClassAskers = mutable.Set.empty[Invalidatable] private val jsClassFieldDefsAskers = mutable.Set.empty[Invalidatable] - def update(linkedClass: LinkedClass): Unit = { + def update(linkedClass: LinkedClass, newHasInlineableInit: Boolean): Unit = { isAlive = true val newIsInterface = computeIsInterface(linkedClass) @@ -142,6 +206,11 @@ private[emitter] object KnowledgeGuardian { invalidateAskers(isInterfaceAskers) } + if (newHasInlineableInit != hasInlineableInit) { + hasInlineableInit = newHasInlineableInit + invalidateAskers(hasInlineableInitAskers) + } + val newJSNativeLoadSpec = computeJSNativeLoadSpec(linkedClass) if (newJSNativeLoadSpec != jsNativeLoadSpec) { jsNativeLoadSpec = newJSNativeLoadSpec @@ -207,6 +276,12 @@ private[emitter] object KnowledgeGuardian { isInterface } + def askHasInlineableInit(invalidatable: Invalidatable): Boolean = { + invalidatable.registeredTo(this) + hasInlineableInitAskers += invalidatable + hasInlineableInit + } + def askJSNativeLoadSpec(invalidatable: Invalidatable): Option[JSNativeLoadSpec] = { invalidatable.registeredTo(this) jsNativeLoadSpecAskers += invalidatable @@ -227,6 +302,7 @@ private[emitter] object KnowledgeGuardian { def unregister(invalidatable: Invalidatable): Unit = { isInterfaceAskers -= invalidatable + hasInlineableInitAskers -= invalidatable jsNativeLoadSpecAskers -= invalidatable jsSuperClassAskers -= invalidatable jsClassFieldDefsAskers -= invalidatable @@ -235,6 +311,7 @@ private[emitter] object KnowledgeGuardian { /** Call this when we invalidate all caches. */ def unregisterAll(): Unit = { isInterfaceAskers.clear() + hasInlineableInitAskers.clear() jsNativeLoadSpecAskers.clear() jsSuperClassAskers.clear() jsClassFieldDefsAskers.clear() From 7f4f6ea73a02d4bdb03eb211db0905612d8b0244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 6 Jul 2017 14:00:49 +0200 Subject: [PATCH 0418/2665] Review all the Configs in the linker. This is a first step towards the new linker API described in #2998. The classes and interfaces are really touched yet, but all the `Config` classes have been reviewed, as well as the constructors using them. Here are some highlights. The class `standard.CoreSpec` aggregates the "core specifications" of a Scala.js linker. At the moment, this contains the `Semantics`, the `ModuleKind` and the `OutputMode`. These are all the settings that can affect how the generated `.js` file behaves in an observable way (for some definition of "observable", e.g., we consider here that performing better or worse is not observable). The class `standard.CommonPhaseConfig` contains configuration that is potentially relevant to any linker phase. This includes future linking plugins. They currently contain the core specs as well as the parallel and batch mode flags. `ESLevel` is gone. We always use `OutputMode` in places where `ESLevel` was previously used. `ClearableLinker` does not check consistency over time of the `GenLinker`s returned by `newLinker()`. This was not possible anymore since `GenLinker` does not expose any information allowing it to do so. Anyway, `ClearableLinker` does not have internal consistency problems even if `newLinker()` would return inconsistent linkers, so performing the check does not appear to be necessary. --- .../linker/LinkerPlatformExtensions.scala | 47 --------- .../backend/LinkerBackendPlatform.scala} | 14 ++- .../LinkerBackendPlatformExtensions.scala | 22 +++++ .../frontend/LinkerFrontendPlatform.scala | 22 +++++ .../linker/LinkerPlatformExtensions.scala | 56 ----------- .../backend/LinkerBackendPlatform.scala | 22 +++++ .../LinkerBackendPlatformExtensions.scala | 23 +++++ .../closure/ClosureLinkerBackend.scala | 18 ++-- .../frontend/LinkerFrontendPlatform.scala | 26 +++++ .../frontend/optimizer/ParIncOptimizer.scala | 11 +-- .../core/tools/linker/ClearableLinker.scala | 30 +----- .../scalajs/core/tools/linker/GenLinker.scala | 4 - .../scalajs/core/tools/linker/Linker.scala | 95 ++----------------- .../core/tools/linker/LinkingUnit.scala | 9 +- .../core/tools/linker/StandardLinker.scala | 27 ++++-- .../core/tools/linker/analyzer/Analyzer.scala | 9 +- .../linker/backend/BasicLinkerBackend.scala | 13 +-- .../tools/linker/backend/LinkerBackend.scala | 80 ++++++++++++---- .../tools/linker/backend/OutputMode.scala | 14 +-- .../linker/backend/emitter/Emitter.scala | 28 +++--- .../tools/linker/frontend/BaseLinker.scala | 9 +- .../linker/frontend/LinkerFrontend.scala | 47 ++++++--- .../core/tools/linker/frontend/Refiner.scala | 6 +- .../frontend/optimizer/GenIncOptimizer.scala | 10 +- .../frontend/optimizer/IncOptimizer.scala | 11 +-- .../frontend/optimizer/OptimizerCore.scala | 14 +-- .../linker/standard/CommonPhaseConfig.scala | 62 ++++++++++++ .../core/tools/linker/standard/CoreSpec.scala | 68 +++++++++++++ 28 files changed, 433 insertions(+), 364 deletions(-) delete mode 100644 tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala rename tools/{shared/src/main/scala/org/scalajs/core/tools/javascript/ESLevel.scala => js/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatform.scala} (62%) create mode 100644 tools/js/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatformExtensions.scala create mode 100644 tools/js/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontendPlatform.scala delete mode 100644 tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala create mode 100644 tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatform.scala create mode 100644 tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatformExtensions.scala create mode 100644 tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontendPlatform.scala create mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/CommonPhaseConfig.scala create mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/CoreSpec.scala diff --git a/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala b/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala deleted file mode 100644 index 0355ff6007..0000000000 --- a/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala +++ /dev/null @@ -1,47 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.core.tools.linker - -import org.scalajs.core.tools.linker.frontend.LinkerFrontend -import org.scalajs.core.tools.linker.frontend.optimizer.IncOptimizer -import org.scalajs.core.tools.linker.backend._ - -trait LinkerPlatformExtensions { this: Linker.type => - private[linker] def applyInternal(semantics: Semantics, - outputMode: OutputMode, moduleKind: ModuleKind, - config: Config): Linker = { - - val optOptimizerFactory = { - if (!config.optimizer) None - else Some(IncOptimizer.factory) - } - - val frontend = new LinkerFrontend(semantics, outputMode.esLevel, - config.frontendConfig, optOptimizerFactory) - - val backend = new BasicLinkerBackend(semantics, outputMode, moduleKind, - config.backendConfig) - - new Linker(frontend, backend) - } -} - -object LinkerPlatformExtensions { - import Linker.Config - - final class ConfigExt(val config: Config) extends AnyVal { - /** Whether to actually use the Google Closure Compiler pass. - * - * On the JavaScript platform, this always returns `false`, as GCC is not - * available. - */ - def closureCompiler: Boolean = false - } -} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/ESLevel.scala b/tools/js/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatform.scala similarity index 62% rename from tools/shared/src/main/scala/org/scalajs/core/tools/javascript/ESLevel.scala rename to tools/js/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatform.scala index 7cc3cd14c5..51c713e218 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/ESLevel.scala +++ b/tools/js/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatform.scala @@ -1,18 +1,16 @@ /* __ *\ ** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** ** /____/\___/_/ |_/____/_/ | |__/ /____/ ** ** |/____/ ** \* */ +package org.scalajs.core.tools.linker.backend -package org.scalajs.core.tools.javascript +private[backend] object LinkerBackendPlatform { + import LinkerBackend.Config -/** ECMAScript level the target supports */ -sealed abstract class ESLevel - -object ESLevel { - case object ES5 extends ESLevel - case object ES6 extends ESLevel + def createLinkerBackend(config: Config): LinkerBackend = + new BasicLinkerBackend(config) } diff --git a/tools/js/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatformExtensions.scala b/tools/js/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatformExtensions.scala new file mode 100644 index 0000000000..4c64b92d5a --- /dev/null +++ b/tools/js/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatformExtensions.scala @@ -0,0 +1,22 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.core.tools.linker.backend + +object LinkerBackendPlatformExtensions { + import LinkerBackend.Config + + final class ConfigExt(val config: Config) extends AnyVal { + /** Whether to actually use the Google Closure Compiler pass. + * + * On the JavaScript platform, this always returns `false`, as GCC is not + * available. + */ + def closureCompiler: Boolean = false + } +} diff --git a/tools/js/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontendPlatform.scala b/tools/js/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontendPlatform.scala new file mode 100644 index 0000000000..eded409bd7 --- /dev/null +++ b/tools/js/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontendPlatform.scala @@ -0,0 +1,22 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.core.tools.linker.frontend + +import org.scalajs.core.tools.linker.frontend.optimizer._ + +private[frontend] object LinkerFrontendPlatform { + import LinkerFrontend.Config + + def createOptimizer(config: Config): Option[GenIncOptimizer] = { + if (!config.optimizer) + None + else + Some(new IncOptimizer(config.commonConfig)) + } +} diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala deleted file mode 100644 index 8e42cdea2d..0000000000 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala +++ /dev/null @@ -1,56 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.core.tools.linker - -import org.scalajs.core.tools.linker.frontend.LinkerFrontend -import org.scalajs.core.tools.linker.frontend.optimizer.{ParIncOptimizer, IncOptimizer} -import org.scalajs.core.tools.linker.backend._ -import org.scalajs.core.tools.linker.backend.closure.ClosureLinkerBackend - -trait LinkerPlatformExtensions { this: Linker.type => - private[linker] def applyInternal(semantics: Semantics, - outputMode: OutputMode, moduleKind: ModuleKind, - config: Config): Linker = { - - val optOptimizerFactory = { - if (!config.optimizer) None - else if (config.parallel) Some(ParIncOptimizer.factory) - else Some(IncOptimizer.factory) - } - - val frontend = new LinkerFrontend(semantics, outputMode.esLevel, - config.frontendConfig, optOptimizerFactory) - - val backend = { - if (config.closureCompiler) { - require(outputMode == OutputMode.ECMAScript51Isolated, - s"Cannot use output mode $outputMode with the Closure Compiler") - new ClosureLinkerBackend(semantics, moduleKind, config.backendConfig) - } else { - new BasicLinkerBackend(semantics, outputMode, moduleKind, - config.backendConfig) - } - } - - new Linker(frontend, backend) - } -} - -object LinkerPlatformExtensions { - import Linker.Config - - final class ConfigExt(val config: Config) extends AnyVal { - /** Whether to actually use the Google Closure Compiler pass. */ - def closureCompiler: Boolean = config.closureCompilerIfAvailable - - def withClosureCompiler(closureCompiler: Boolean): Config = - config.withClosureCompilerIfAvailable(closureCompiler) - } -} diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatform.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatform.scala new file mode 100644 index 0000000000..b44d9a34c4 --- /dev/null +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatform.scala @@ -0,0 +1,22 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.core.tools.linker.backend + +import org.scalajs.core.tools.linker.backend.closure.ClosureLinkerBackend + +private[backend] object LinkerBackendPlatform { + import LinkerBackend.Config + + def createLinkerBackend(config: Config): LinkerBackend = { + if (config.closureCompiler) + new ClosureLinkerBackend(config) + else + new BasicLinkerBackend(config) + } +} diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatformExtensions.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatformExtensions.scala new file mode 100644 index 0000000000..d2578b9b3a --- /dev/null +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatformExtensions.scala @@ -0,0 +1,23 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.core.tools.linker.backend + +import org.scalajs.core.tools.linker.backend.closure.ClosureLinkerBackend + +object LinkerBackendPlatformExtensions { + import LinkerBackend.Config + + final class ConfigExt(val config: Config) extends AnyVal { + /** Whether to actually use the Google Closure Compiler pass. */ + def closureCompiler: Boolean = config.closureCompilerIfAvailable + + def withClosureCompiler(closureCompiler: Boolean): Config = + config.withClosureCompilerIfAvailable(closureCompiler) + } +} diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala index c09555349c..73465cfe3b 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala @@ -19,28 +19,28 @@ import com.google.javascript.jscomp.{ } import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.javascript.ESLevel import org.scalajs.core.tools.logging.Logger -import org.scalajs.core.tools.sem.Semantics import org.scalajs.core.tools.linker.LinkingUnit import org.scalajs.core.tools.linker.analyzer.SymbolRequirement import org.scalajs.core.tools.linker.backend._ -import org.scalajs.core.tools.linker.backend.emitter.{Emitter, CoreJSLibs} +import org.scalajs.core.tools.linker.backend.emitter.Emitter /** The Closure backend of the Scala.js linker. * * Runs a the Google Closure Compiler in advanced mode on the emitted code. * Use this for production builds. */ -final class ClosureLinkerBackend( - semantics: Semantics, - moduleKind: ModuleKind, - config: LinkerBackend.Config -) extends LinkerBackend(semantics, ESLevel.ES5, moduleKind, config) { +final class ClosureLinkerBackend(config: LinkerBackend.Config) + extends LinkerBackend(config) { + + import config.commonConfig.coreSpec._ + + require(outputMode == OutputMode.ECMAScript51Isolated, + s"Cannot use output mode $outputMode with the Closure Compiler") private[this] val emitter = { - new Emitter(semantics, OutputMode.ECMAScript51Isolated, moduleKind) + new Emitter(config.commonConfig) .withOptimizeBracketSelects(false) } diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontendPlatform.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontendPlatform.scala new file mode 100644 index 0000000000..ba4c3ecaa4 --- /dev/null +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontendPlatform.scala @@ -0,0 +1,26 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.core.tools.linker.frontend + +import org.scalajs.core.tools.linker.frontend.optimizer._ + +private[frontend] object LinkerFrontendPlatform { + import LinkerFrontend.Config + + def createOptimizer(config: Config): Option[GenIncOptimizer] = { + import config.commonConfig + + if (!config.optimizer) + None + else if (commonConfig.parallel) + Some(new ParIncOptimizer(commonConfig)) + else + Some(new IncOptimizer(commonConfig)) + } +} diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ParIncOptimizer.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ParIncOptimizer.scala index da3ee9028e..ec1614d938 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ParIncOptimizer.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ParIncOptimizer.scala @@ -16,13 +16,12 @@ import scala.collection.parallel._ import java.util.concurrent.atomic._ -import org.scalajs.core.tools.sem.Semantics -import org.scalajs.core.tools.javascript.ESLevel +import org.scalajs.core.tools.linker.standard._ import ConcurrencyUtils._ -final class ParIncOptimizer(semantics: Semantics, esLevel: ESLevel) - extends GenIncOptimizer(semantics, esLevel) { +final class ParIncOptimizer(config: CommonPhaseConfig) + extends GenIncOptimizer(config) { private[optimizer] object CollOps extends GenIncOptimizer.AbsCollOps { type Map[K, V] = TrieMap[K, V] @@ -199,7 +198,3 @@ final class ParIncOptimizer(semantics: Semantics, esLevel: ESLevel) } } - -object ParIncOptimizer { - val factory: GenIncOptimizer.OptimizerFactory = new ParIncOptimizer(_, _) -} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ClearableLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ClearableLinker.scala index b5592f8207..695c50f711 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ClearableLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ClearableLinker.scala @@ -12,7 +12,6 @@ package org.scalajs.core.tools.linker import org.scalajs.core.tools.logging.Logger import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.javascript.ESLevel import org.scalajs.core.tools.linker.analyzer.SymbolRequirement /** A box around a [[GenLinker]] to support clearing. @@ -26,20 +25,8 @@ import org.scalajs.core.tools.linker.analyzer.SymbolRequirement final class ClearableLinker(newLinker: () => GenLinker, batchMode: Boolean) extends GenLinker { - private[this] var _semantics: Semantics = _ - private[this] var _esLevel: ESLevel = _ private[this] var _linker: GenLinker = _ - def semantics: Semantics = { - ensureLinker() - _semantics - } - - def esLevel: ESLevel = { - ensureLinker() - _esLevel - } - def linkUnit(irFiles: Seq[VirtualScalaJSIRFile], moduleInitializers: Seq[ModuleInitializer], symbolRequirements: SymbolRequirement, logger: Logger): LinkingUnit = { @@ -75,20 +62,7 @@ final class ClearableLinker(newLinker: () => GenLinker, batchMode: Boolean) private def ensureLinker(): Unit = { // Ensure we have a linker - if (_linker == null) { - val candidate = newLinker() - - if (_semantics == null) - _semantics = candidate.semantics - else - require(_semantics == candidate.semantics, "Linker changed Semantics") - - if (_esLevel == null) - _esLevel = candidate.esLevel - else - require(_esLevel == candidate.esLevel, "Linker changed ESLevel") - - _linker = candidate - } + if (_linker == null) + _linker = newLinker() } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala index eb70d19474..19822d5bbf 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala @@ -12,7 +12,6 @@ package org.scalajs.core.tools.linker import org.scalajs.core.tools.logging.Logger import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.javascript.ESLevel import org.scalajs.core.tools.linker.analyzer.SymbolRequirement /** Common supertrait of [[Linker]] and [[ClearableLinker]]. @@ -20,9 +19,6 @@ import org.scalajs.core.tools.linker.analyzer.SymbolRequirement * Essentially anything that has the `link` and `linkUnit` methods. */ trait GenLinker { - def semantics: Semantics - def esLevel: ESLevel - def linkUnit(irFiles: Seq[VirtualScalaJSIRFile], moduleInitializers: Seq[ModuleInitializer], symbolRequirements: SymbolRequirement, logger: Logger): LinkingUnit diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala index 54a930a3d9..e1cccb5046 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala @@ -16,23 +16,18 @@ import java.util.concurrent.atomic.AtomicBoolean import org.scalajs.core.tools.logging.Logger import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.javascript.ESLevel +import org.scalajs.core.tools.linker.standard._ import org.scalajs.core.tools.linker.analyzer.SymbolRequirement import org.scalajs.core.tools.linker.frontend.LinkerFrontend import org.scalajs.core.tools.linker.frontend.optimizer.IncOptimizer import org.scalajs.core.tools.linker.backend.{LinkerBackend, BasicLinkerBackend} /** The Scala.js linker */ -final class Linker(frontend: LinkerFrontend, backend: LinkerBackend) +final class Linker private (frontend: LinkerFrontend, backend: LinkerBackend) extends GenLinker { - require(frontend.semantics == backend.semantics, - "Frontend and backend must agree on semantics") - require(frontend.esLevel == backend.esLevel, - "Frontend and backend must agree on ESLevel") - - val semantics: Semantics = frontend.semantics - val esLevel: ESLevel = backend.esLevel + require(frontend.coreSpec == backend.coreSpec, + "Frontend and backend must implement the same core specification") private[this] var _valid = true private[this] val _linking = new AtomicBoolean(false) @@ -75,83 +70,7 @@ final class Linker(frontend: LinkerFrontend, backend: LinkerBackend) } } -object Linker extends LinkerPlatformExtensions { - /** Configuration to be passed to the `apply()` method. */ - final class Config private ( - /** Whether to use the Scala.js optimizer. */ - val optimizer: Boolean, - /** Whether things that can be parallelized should be parallelized. - * On the JavaScript platform, this does not have any effect. - */ - val parallel: Boolean, - /** Whether to use the Google Closure Compiler pass, if it is available. - * On the JavaScript platform, this does not have any effect. - */ - val closureCompilerIfAvailable: Boolean, - /** Additional configuration for the linker frontend. */ - val frontendConfig: LinkerFrontend.Config, - /** Additional configuration for the linker backend. */ - val backendConfig: LinkerBackend.Config - ) { - def withOptimizer(optimizer: Boolean): Config = - copy(optimizer = optimizer) - - def withParallel(parallel: Boolean): Config = - copy(parallel = parallel) - - def withClosureCompilerIfAvailable(closureCompilerIfAvailable: Boolean): Config = - copy(closureCompilerIfAvailable = closureCompilerIfAvailable) - - def withFrontendConfig(frontendConfig: LinkerFrontend.Config): Config = - copy(frontendConfig = frontendConfig) - - def withFrontendConfig(f: LinkerFrontend.Config => LinkerFrontend.Config): Config = - copy(frontendConfig = f(frontendConfig)) - - def withBackendConfig(backendConfig: LinkerBackend.Config): Config = - copy(backendConfig = backendConfig) - - def withBackendConfig(f: LinkerBackend.Config => LinkerBackend.Config): Config = - copy(backendConfig = f(backendConfig)) - - private def copy( - optimizer: Boolean = optimizer, - parallel: Boolean = parallel, - closureCompilerIfAvailable: Boolean = closureCompilerIfAvailable, - frontendConfig: LinkerFrontend.Config = frontendConfig, - backendConfig: LinkerBackend.Config = backendConfig): Config = { - new Config( - optimizer = optimizer, - parallel = parallel, - closureCompilerIfAvailable = closureCompilerIfAvailable, - frontendConfig = frontendConfig, - backendConfig = backendConfig) - } - } - - object Config { - import LinkerPlatformExtensions._ - - implicit def toPlatformExtensions(config: Config): ConfigExt = - new ConfigExt(config) - - /** Default configuration. - * - * - `optimizer`: true - * - `parallel`: true - * - `closureCompilerIfAvailable`: false - * - `frontendConfig`: default frontend configuration as returned by - * [[org.scalajs.core.tools.linker.frontend.LinkerFrontend.Config.apply]] - * - `backendConfig`: default backend configuration as returned by - * [[org.scalajs.core.tools.linker.backend.LinkerBackend.Config.apply]] - */ - def apply(): Config = { - new Config( - optimizer = true, - parallel = true, - closureCompilerIfAvailable = false, - frontendConfig = LinkerFrontend.Config(), - backendConfig = LinkerBackend.Config()) - } - } +object Linker { + def apply(frontend: LinkerFrontend, backend: LinkerBackend): Linker = + new Linker(frontend, backend) } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala index 7067bf08ea..6d54cbd996 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala @@ -1,13 +1,12 @@ package org.scalajs.core.tools.linker -import org.scalajs.core.tools.javascript.ESLevel - import org.scalajs.core.ir import ir.{Definitions, Infos} +import org.scalajs.core.tools.linker.standard._ + final class LinkingUnit private[linker] ( - val semantics: Semantics, - val esLevel: ESLevel, + val coreSpec: CoreSpec, val classDefs: List[LinkedClass], private[linker] val infos: Map[String, Infos.ClassInfo], val moduleInitializers: List[ModuleInitializer] @@ -15,6 +14,6 @@ final class LinkingUnit private[linker] ( private[linker] def updated(classDefs: List[LinkedClass]): LinkingUnit = { val newInfos = infos ++ classDefs.map(cd => cd.encodedName -> cd.toInfo) - new LinkingUnit(semantics, esLevel, classDefs, newInfos, moduleInitializers) + new LinkingUnit(coreSpec, classDefs, newInfos, moduleInitializers) } } 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 8c88a29161..0594116181 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 @@ -12,30 +12,37 @@ import scala.language.implicitConversions import java.net.URI +import org.scalajs.core.tools.linker.standard._ import org.scalajs.core.tools.linker.frontend.LinkerFrontend -import org.scalajs.core.tools.linker.backend.{LinkerBackend, OutputMode} +import org.scalajs.core.tools.linker.backend.LinkerBackend object StandardLinker { import StandardLinkerPlatformExtensions._ def apply(config: Config): Linker = { + val coreSpec = CoreSpec( + config.semantics, + config.moduleKind, + config.outputMode) + + val commonConfig = CommonPhaseConfig() + .withCoreSpec(coreSpec) + .withParallel(config.parallel) + .withBatchMode(config.batchMode) + val frontendConfig = LinkerFrontend.Config() + .withCommonConfig(commonConfig) .withCheckIR(config.checkIR) + .withOptimizer(config.optimizer) val backendConfig = LinkerBackend.Config() + .withCommonConfig(commonConfig) .withSourceMap(config.sourceMap) .withRelativizeSourceMapBase(config.relativizeSourceMapBase) - .withPrettyPrint(config.prettyPrint) - - val oldAPIConfig = Linker.Config() - .withOptimizer(config.optimizer) - .withParallel(config.parallel) .withClosureCompilerIfAvailable(config.closureCompilerIfAvailable) - .withFrontendConfig(frontendConfig) - .withBackendConfig(backendConfig) + .withPrettyPrint(config.prettyPrint) - Linker.applyInternal(config.semantics, config.outputMode, config.moduleKind, - oldAPIConfig) + Linker(LinkerFrontend(frontendConfig), LinkerBackend(backendConfig)) } implicit def configExt(config: Config): ConfigExt = diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala index 65551f46ce..b74c112444 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala @@ -17,9 +17,10 @@ import org.scalajs.core.ir import ir.{ClassKind, Definitions, Infos} import Definitions._ -import org.scalajs.core.tools.sem._ +import org.scalajs.core.tools.linker._ +import org.scalajs.core.tools.linker.standard._ -private final class Analyzer(semantics: Semantics, +private final class Analyzer(config: CommonPhaseConfig, symbolRequirements: SymbolRequirement, allowAddingSyntheticMethods: Boolean) extends Analysis { import Analyzer._ @@ -871,11 +872,11 @@ private final class Analyzer(semantics: Semantics, } object Analyzer { - def computeReachability(semantics: Semantics, + def computeReachability(config: CommonPhaseConfig, symbolRequirements: SymbolRequirement, allData: Seq[Infos.ClassInfo], allowAddingSyntheticMethods: Boolean): Analysis = { - val analyzer = new Analyzer(semantics, symbolRequirements, + val analyzer = new Analyzer(config, symbolRequirements, allowAddingSyntheticMethods) analyzer.computeReachability(allData) analyzer diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala index ee849c1ad3..2370ffdf6a 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala @@ -11,7 +11,7 @@ package org.scalajs.core.tools.linker.backend import org.scalajs.core.tools.logging.Logger import org.scalajs.core.tools.io.WritableVirtualJSFile -import org.scalajs.core.tools.sem.Semantics + import org.scalajs.core.tools.linker.LinkingUnit import org.scalajs.core.tools.linker.analyzer.SymbolRequirement import org.scalajs.core.tools.linker.backend.emitter.Emitter @@ -21,15 +21,10 @@ import org.scalajs.core.tools.javascript.{JSFileBuilder, JSFileBuilderWithSource * * Simply emits the JavaScript without applying any further optimizations. */ -final class BasicLinkerBackend( - semantics: Semantics, - outputMode: OutputMode, - moduleKind: ModuleKind, - config: LinkerBackend.Config -) extends LinkerBackend(semantics, outputMode.esLevel, moduleKind, config) { +final class BasicLinkerBackend(config: LinkerBackend.Config) + extends LinkerBackend(config) { - private[this] val emitter = - new Emitter(semantics, outputMode, moduleKind) + private[this] val emitter = new Emitter(config.commonConfig) val symbolRequirements: SymbolRequirement = emitter.symbolRequirements diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala index 82073a12fd..b0bbbf8079 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala @@ -9,14 +9,15 @@ package org.scalajs.core.tools.linker.backend +import scala.language.implicitConversions + import java.net.URI import org.scalajs.core.tools.io.WritableVirtualJSFile -import org.scalajs.core.tools.javascript.ESLevel import org.scalajs.core.tools.logging.Logger -import org.scalajs.core.tools.sem.Semantics -import org.scalajs.core.tools.linker.LinkingUnit +import org.scalajs.core.tools.linker._ +import org.scalajs.core.tools.linker.standard._ import org.scalajs.core.tools.linker.analyzer.SymbolRequirement /** A backend of the Scala.js linker. Produces a @@ -25,16 +26,19 @@ import org.scalajs.core.tools.linker.analyzer.SymbolRequirement * You probably want to use an instance of [[linker.Linker]], rather than this * low-level class. */ -abstract class LinkerBackend( - val semantics: Semantics, - val esLevel: ESLevel, - val moduleKind: ModuleKind, - protected val config: LinkerBackend.Config) { +abstract class LinkerBackend(protected val config: LinkerBackend.Config) { + /** Core specification that this linker backend implements. */ + val coreSpec = config.commonConfig.coreSpec /** Symbols this backend needs to be present in the linking unit. */ val symbolRequirements: SymbolRequirement - /** Emit the given [[LinkingUnit]] to the target output + /** Emit the given [[LinkingUnit]] to the target output. + * + * The linking unit given to `emit` must: + * + * - have the same `coreSpec` as this linker backend, and + * - contain the symbols listed in [[symbolRequirements]]. * * @param unit [[LinkingUnit]] to emit * @param output File to write to @@ -43,48 +47,82 @@ abstract class LinkerBackend( def emit(unit: LinkingUnit, output: WritableVirtualJSFile, logger: Logger): Unit - /** Verify that a [[LinkingUnit]] corresponds to this [[LinkerBackend]]'s - * [[org.scalajs.core.tools.sem.Semantics Semantics]] and - * [[org.scalajs.core.tools.javascript.ESLevel ESLevel]] (specified via the - * [[OutputMode]]). + /** Verify that a [[LinkingUnit]] can be processed by this [[LinkerBackend]]. + * + * Currently, this only tests that the linking unit core specification + * matches [[coreSpec]]. + * + * In the future, this test could be extended to test [[symbolRequirements]] + * too. + * * @throws java.lang.IllegalArgumentException if there is a mismatch */ protected def verifyUnit(unit: LinkingUnit): Unit = { - require(unit.semantics == semantics, - "LinkingUnit and LinkerBackend must agree on semantics") - require(unit.esLevel == esLevel, - "LinkingUnit and LinkerBackend must agree on esLevel") + require(unit.coreSpec == coreSpec, + "LinkingUnit and LinkerBackend must agree on their core specification") } } object LinkerBackend { + def apply(config: Config): LinkerBackend = + LinkerBackendPlatform.createLinkerBackend(config) + /** Configurations relevant to the backend */ final class Config private ( + /** Common phase config. */ + val commonConfig: CommonPhaseConfig, /** Whether to emit a source map. */ - val sourceMap: Boolean = true, + val sourceMap: Boolean, /** Base path to relativize paths in the source map. */ - val relativizeSourceMapBase: Option[URI] = None, + val relativizeSourceMapBase: Option[URI], + /** Whether to use the Google Closure Compiler pass, if it is available. + * On the JavaScript platform, this does not have any effect. + */ + val closureCompilerIfAvailable: Boolean, /** Pretty-print the output. */ - val prettyPrint: Boolean = false + val prettyPrint: Boolean ) { + private def this() = { + this( + commonConfig = CommonPhaseConfig(), + sourceMap = true, + relativizeSourceMapBase = None, + closureCompilerIfAvailable = false, + prettyPrint = false) + } + + def withCommonConfig(commonConfig: CommonPhaseConfig): Config = + copy(commonConfig = commonConfig) + def withSourceMap(sourceMap: Boolean): Config = copy(sourceMap = sourceMap) def withRelativizeSourceMapBase(relativizeSourceMapBase: Option[URI]): Config = copy(relativizeSourceMapBase = relativizeSourceMapBase) + def withClosureCompilerIfAvailable(closureCompilerIfAvailable: Boolean): Config = + copy(closureCompilerIfAvailable = closureCompilerIfAvailable) + def withPrettyPrint(prettyPrint: Boolean): Config = copy(prettyPrint = prettyPrint) private def copy( + commonConfig: CommonPhaseConfig = commonConfig, sourceMap: Boolean = sourceMap, relativizeSourceMapBase: Option[URI] = relativizeSourceMapBase, + closureCompilerIfAvailable: Boolean = closureCompilerIfAvailable, prettyPrint: Boolean = prettyPrint): Config = { - new Config(sourceMap, relativizeSourceMapBase, prettyPrint) + new Config(commonConfig, sourceMap, relativizeSourceMapBase, + closureCompilerIfAvailable, prettyPrint) } } object Config { + import LinkerBackendPlatformExtensions._ + + implicit def toPlatformExtensions(config: Config): ConfigExt = + new ConfigExt(config) + def apply(): Config = new Config() } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala index 99f003d599..d71c5ea911 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala @@ -9,12 +9,8 @@ package org.scalajs.core.tools.linker.backend -import org.scalajs.core.tools.javascript.ESLevel - /** JavaScript output mode. */ -sealed abstract class OutputMode { - def esLevel: ESLevel -} +sealed abstract class OutputMode object OutputMode { /** All the available output modes. @@ -33,9 +29,7 @@ object OutputMode { * The output must be enclosed in an anonymous function isolating the code * in a dedicated scope. */ - case object ECMAScript51Isolated extends OutputMode { - val esLevel: ESLevel = ESLevel.ES5 - } + case object ECMAScript51Isolated extends OutputMode /** Experimental output mode compliant with ECMAScript 6 in a function scope. * @@ -51,7 +45,5 @@ object OutputMode { * The output must be enclosed in an anonymous function isolating the code * in a dedicated scope. */ - case object ECMAScript6 extends OutputMode { - val esLevel: ESLevel = ESLevel.ES6 - } + case object ECMAScript6 extends OutputMode } diff --git 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 index 92e66d555c..756777c91b 100644 --- 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 @@ -23,20 +23,20 @@ import org.scalajs.core.tools.logging._ import org.scalajs.core.tools.javascript.{Trees => js, _} import org.scalajs.core.tools.linker._ +import org.scalajs.core.tools.linker.standard._ import org.scalajs.core.tools.linker.analyzer.SymbolRequirement -import org.scalajs.core.tools.linker.backend.{OutputMode, ModuleKind} import GlobalRefUtils._ /** Emits a desugared JS tree to a builder */ -final class Emitter private (semantics: Semantics, outputMode: OutputMode, - moduleKind: ModuleKind, internalOptions: InternalOptions) { +final class Emitter private (config: CommonPhaseConfig, + internalOptions: InternalOptions) { import Emitter._ + import config.coreSpec._ - def this(semantics: Semantics, outputMode: OutputMode, - moduleKind: ModuleKind) = { - this(semantics, outputMode, moduleKind, InternalOptions()) + def this(config: CommonPhaseConfig) = { + this(config, InternalOptions()) } private val knowledgeGuardian = new KnowledgeGuardian @@ -91,7 +91,7 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, private[this] var statsMethodsInvalidated: Int = 0 val symbolRequirements: SymbolRequirement = - Emitter.symbolRequirements(semantics, outputMode.esLevel) + Emitter.symbolRequirements(config.coreSpec) private val needsIIFEWrapper = { moduleKind match { @@ -103,7 +103,7 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, // Private API for the Closure backend (could be opened if necessary) private[backend] def withOptimizeBracketSelects( optimizeBracketSelects: Boolean): Emitter = { - new Emitter(semantics, outputMode, moduleKind, + new Emitter(config, internalOptions.withOptimizeBracketSelects(optimizeBracketSelects)) } @@ -580,9 +580,8 @@ private object Emitter { } } - private def symbolRequirements(semantics: Semantics, - esLevel: ESLevel): SymbolRequirement = { - import semantics._ + private def symbolRequirements(coreSpec: CoreSpec): SymbolRequirement = { + import coreSpec.semantics._ import CheckedBehavior._ val factory = SymbolRequirement.factory("emitter") @@ -591,6 +590,11 @@ private object Emitter { def cond(p: Boolean)(v: => SymbolRequirement): SymbolRequirement = if (p) v else none() + def assumingES6: Boolean = coreSpec.outputMode match { + case OutputMode.ECMAScript51Isolated => false + case OutputMode.ECMAScript6 => true + } + multiple( instantiateClass("O", "init___"), classData("O"), @@ -624,7 +628,7 @@ private object Emitter { callOnModule(LongImpl.RuntimeLongModuleClass, LongImpl.AllModuleMethods), - cond(semantics.strictFloats && esLevel == ESLevel.ES5) { + cond(strictFloats && !assumingES6) { callOnModule("sjsr_package$", "froundPolyfill__D__D") }, callOnModule("sjsr_Bits$", "numberHashCode__D__I") diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index 5aabf985ff..88c961b1f5 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -14,12 +14,11 @@ import scala.annotation.tailrec import scala.collection.mutable import scala.util.Try -import org.scalajs.core.tools.sem._ -import org.scalajs.core.tools.javascript.ESLevel import org.scalajs.core.tools.logging._ import org.scalajs.core.tools.io._ import org.scalajs.core.tools.linker._ +import org.scalajs.core.tools.linker.standard._ import org.scalajs.core.tools.linker.checker._ import org.scalajs.core.tools.linker.analyzer._ @@ -37,7 +36,7 @@ import Analysis._ /** Links the information from [[io.VirtualScalaJSIRFile]]s into * [[LinkedClass]]es. Does a dead code elimination pass. */ -final class BaseLinker(semantics: Semantics, esLevel: ESLevel) { +final class BaseLinker(config: CommonPhaseConfig) { private type TreeProvider = String => (ClassDef, Option[String]) @@ -91,7 +90,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel) { symbolRequirements ++ ModuleInitializer.toSymbolRequirement(moduleInitializers) } - Analyzer.computeReachability(semantics, allSymbolRequirements, infoInput, + Analyzer.computeReachability(config, allSymbolRequirements, infoInput, allowAddingSyntheticMethods = true) } @@ -146,7 +145,7 @@ final class BaseLinker(semantics: Semantics, esLevel: ESLevel) { getTree, analysis) } - new LinkingUnit(semantics, esLevel, linkedClassDefs.toList, infoByName, + new LinkingUnit(config.coreSpec, linkedClassDefs.toList, infoByName, moduleInitializers.toList) } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala index a51d104625..06fbeab9f8 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala @@ -12,10 +12,8 @@ package org.scalajs.core.tools.linker.frontend import org.scalajs.core.tools.logging.Logger import org.scalajs.core.tools.io.VirtualScalaJSIRFile -import org.scalajs.core.tools.sem.Semantics -import org.scalajs.core.tools.javascript.ESLevel - import org.scalajs.core.tools.linker._ +import org.scalajs.core.tools.linker.standard._ import org.scalajs.core.tools.linker.analyzer.SymbolRequirement import org.scalajs.core.tools.linker.frontend.optimizer.{GenIncOptimizer, IncOptimizer} @@ -27,19 +25,18 @@ import org.scalajs.core.tools.linker.frontend.optimizer.{GenIncOptimizer, IncOpt * Attention: [[LinkerFrontend]] does not cache the IR input. It is advisable to do * so, unless all IR is already in memory. */ -final class LinkerFrontend( - val semantics: Semantics, - val esLevel: ESLevel, - config: LinkerFrontend.Config, - optimizerFactory: Option[GenIncOptimizer.OptimizerFactory]) { +final class LinkerFrontend private (config: LinkerFrontend.Config) { + + /** Core specification that this linker frontend implements. */ + val coreSpec = config.commonConfig.coreSpec private[this] val linker: BaseLinker = - new BaseLinker(semantics, esLevel) + new BaseLinker(config.commonConfig) private[this] val optOptimizer: Option[GenIncOptimizer] = - optimizerFactory.map(_(semantics, esLevel)) + LinkerFrontendPlatform.createOptimizer(config) - private[this] val refiner: Refiner = new Refiner + private[this] val refiner: Refiner = new Refiner(config.commonConfig) /** Link and optionally optimize the given IR to a [[LinkingUnit]]. */ def link(irFiles: Seq[VirtualScalaJSIRFile], @@ -73,17 +70,39 @@ final class LinkerFrontend( } object LinkerFrontend { + def apply(config: Config): LinkerFrontend = + new LinkerFrontend(config) + /** Configurations relevant to the frontend */ final class Config private ( + /** Common phase config. */ + val commonConfig: CommonPhaseConfig, /** If true, performs expensive checks of the IR for the used parts. */ - val checkIR: Boolean = false + val checkIR: Boolean, + /** Whether to use the Scala.js optimizer. */ + val optimizer: Boolean ) { + private def this() = { + this( + commonConfig = CommonPhaseConfig(), + checkIR = false, + optimizer = true) + } + + def withCommonConfig(commonConfig: CommonPhaseConfig): Config = + copy(commonConfig = commonConfig) + def withCheckIR(checkIR: Boolean): Config = copy(checkIR = checkIR) + def withOptimizer(optimizer: Boolean): Config = + copy(optimizer = optimizer) + private def copy( - checkIR: Boolean = checkIR): Config = { - new Config(checkIR) + commonConfig: CommonPhaseConfig = commonConfig, + checkIR: Boolean = checkIR, + optimizer: Boolean = optimizer): Config = { + new Config(commonConfig, checkIR, optimizer) } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala index 371003a88b..f833c60328 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala @@ -9,16 +9,16 @@ package org.scalajs.core.tools.linker.frontend -import org.scalajs.core.tools.sem._ import org.scalajs.core.tools.logging._ import org.scalajs.core.tools.linker._ +import org.scalajs.core.tools.linker.standard._ import org.scalajs.core.tools.linker.analyzer._ import org.scalajs.core.ir.ClassKind /** Does a dead code elimination pass on [[LinkedClass]]es */ -final class Refiner { +final class Refiner(config: CommonPhaseConfig) { def refine(unit: LinkingUnit, symbolRequirements: SymbolRequirement, logger: Logger): LinkingUnit = { @@ -27,7 +27,7 @@ final class Refiner { symbolRequirements ++ ModuleInitializer.toSymbolRequirement(unit.moduleInitializers) } - Analyzer.computeReachability(unit.semantics, allSymbolRequirements, + Analyzer.computeReachability(config, allSymbolRequirements, unit.infos.values.toList, allowAddingSyntheticMethods = false) } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala index b8977066d8..6d473f7407 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala @@ -21,13 +21,12 @@ import Definitions.isConstructorName import Trees._ import Types._ -import org.scalajs.core.tools.sem._ -import org.scalajs.core.tools.javascript.ESLevel import org.scalajs.core.tools.logging._ import org.scalajs.core.tools.linker._ import org.scalajs.core.tools.linker.analyzer.SymbolRequirement import org.scalajs.core.tools.linker.backend.emitter.LongImpl +import org.scalajs.core.tools.linker.standard._ /** Incremental optimizer. * An incremental optimizer optimizes a [[LinkingUnit]] in an incremental way. @@ -39,8 +38,7 @@ import org.scalajs.core.tools.linker.backend.emitter.LongImpl * @param semantics Required Scala.js Semantics * @param esLevel ECMAScript level */ -abstract class GenIncOptimizer private[optimizer] (semantics: Semantics, - esLevel: ESLevel) { +abstract class GenIncOptimizer private[optimizer] (config: CommonPhaseConfig) { import GenIncOptimizer._ @@ -954,7 +952,7 @@ abstract class GenIncOptimizer private[optimizer] (semantics: Semantics, } /** All methods are PROCESS PASS ONLY */ - private class Optimizer extends OptimizerCore(semantics, esLevel) { + private class Optimizer extends OptimizerCore(config) { type MethodID = MethodImpl val myself: MethodImpl.this.type = MethodImpl.this @@ -1012,8 +1010,6 @@ abstract class GenIncOptimizer private[optimizer] (semantics: Semantics, object GenIncOptimizer { - type OptimizerFactory = (Semantics, ESLevel) => GenIncOptimizer - private val isAdHocElidableModuleAccessor = Set("s_Predef$") diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/IncOptimizer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/IncOptimizer.scala index 96955b2102..8321a728ad 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/IncOptimizer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/IncOptimizer.scala @@ -12,11 +12,10 @@ package org.scalajs.core.tools.linker.frontend.optimizer import scala.collection.{GenTraversableOnce, GenIterable} import scala.collection.mutable -import org.scalajs.core.tools.sem.Semantics -import org.scalajs.core.tools.javascript.ESLevel +import org.scalajs.core.tools.linker.standard._ -final class IncOptimizer(semantics: Semantics, esLevel: ESLevel) - extends GenIncOptimizer(semantics, esLevel) { +final class IncOptimizer(config: CommonPhaseConfig) + extends GenIncOptimizer(config) { private[optimizer] object CollOps extends GenIncOptimizer.AbsCollOps { type Map[K, V] = mutable.Map[K, V] @@ -166,7 +165,3 @@ final class IncOptimizer(semantics: Semantics, esLevel: ESLevel) } } - -object IncOptimizer { - val factory: GenIncOptimizer.OptimizerFactory = new IncOptimizer(_, _) -} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index c50fd98b54..476d35bbed 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -23,10 +23,9 @@ import Definitions.{ObjectClass, isConstructorName, isReflProxyName} import Trees._ import Types._ -import org.scalajs.core.tools.sem.{CheckedBehavior, Semantics} -import org.scalajs.core.tools.javascript.ESLevel import org.scalajs.core.tools.logging._ import org.scalajs.core.tools.linker._ +import org.scalajs.core.tools.linker.standard._ import org.scalajs.core.tools.linker.backend.emitter.LongImpl /** Optimizer core. @@ -35,8 +34,7 @@ import org.scalajs.core.tools.linker.backend.emitter.LongImpl * optimizer does. To perform inlining, it relies on abstract protected * methods to identify the target of calls. */ -private[optimizer] abstract class OptimizerCore( - semantics: Semantics, esLevel: ESLevel) { +private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { import OptimizerCore._ type MethodID <: AbstractMethodID @@ -3699,6 +3697,8 @@ private[optimizer] abstract class OptimizerCore( implicit pos: Position): Tree = { // !!! Must be in sync with scala.scalajs.runtime.LinkingInfo + import config.coreSpec._ + @inline def default = JSBracketSelect(qualifier, item) @@ -3728,9 +3728,9 @@ private[optimizer] abstract class OptimizerCore( } case (JSLinkingInfo(), StringLiteral("assumingES6")) => - BooleanLiteral(esLevel match { - case ESLevel.ES5 => false - case ESLevel.ES6 => true + BooleanLiteral(outputMode match { + case OutputMode.ECMAScript51Isolated => false + case OutputMode.ECMAScript6 => true }) case (JSLinkingInfo(), StringLiteral("version")) => diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/CommonPhaseConfig.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/CommonPhaseConfig.scala new file mode 100644 index 0000000000..24db67c71f --- /dev/null +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/CommonPhaseConfig.scala @@ -0,0 +1,62 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.core.tools.linker.standard + +import org.scalajs.core.tools.linker._ + +/** Common configuration given to all phases of the linker. */ +final class CommonPhaseConfig private ( + /** Core specification. */ + val coreSpec: CoreSpec, + /** Whether things that can be parallelized should be parallelized. + * On the JavaScript platform, this setting is typically ignored. + */ + val parallel: Boolean, + /** Whether the linker runs in batch mode. + * + * In batch mode, the linker phase can throw away intermediate state that + * is otherwise maintained for incremental runs. + * + * This setting is only a hint. A linker phase may ignore it. This applies + * in both directions: a phase not supporting incrementality can ignore + * `batchMode = false`, and a contrario, a phase mainly designed for + * incremental runs may ignore `batchMode = true`. + */ + val batchMode: Boolean +) { + private def this() = { + this( + coreSpec = CoreSpec.Defaults, + parallel = true, + batchMode = false) + } + + private[linker] def withCoreSpec(coreSpec: CoreSpec): CommonPhaseConfig = + copy(coreSpec = coreSpec) + + private[linker] def withParallel(parallel: Boolean): CommonPhaseConfig = + copy(parallel = parallel) + + private[linker] def withBatchMode(batchMode: Boolean): CommonPhaseConfig = + copy(batchMode = batchMode) + + private def copy( + coreSpec: CoreSpec = coreSpec, + parallel: Boolean = parallel, + batchMode: Boolean = batchMode): CommonPhaseConfig = { + new CommonPhaseConfig( + coreSpec = coreSpec, + parallel = parallel, + batchMode = batchMode) + } +} + +private[linker] object CommonPhaseConfig { + private[linker] def apply(): CommonPhaseConfig = new CommonPhaseConfig() +} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/CoreSpec.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/CoreSpec.scala new file mode 100644 index 0000000000..e9ced4848b --- /dev/null +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/CoreSpec.scala @@ -0,0 +1,68 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.core.tools.linker.standard + +import org.scalajs.core.tools.linker._ + +/** Core specification for the Scala.js code. */ +final class CoreSpec private ( + /** Scala.js semantics. */ + val semantics: Semantics, + /** Module kind. */ + val moduleKind: ModuleKind, + /** Standard output mode. */ + val outputMode: OutputMode +) { + import CoreSpec._ + + override def equals(that: Any): Boolean = that match { + case that: CoreSpec => + this.semantics == that.semantics && + this.moduleKind == that.moduleKind && + this.outputMode == that.outputMode + case _ => + false + } + + override def hashCode(): Int = { + import scala.util.hashing.MurmurHash3._ + var acc = HashSeed + acc = mix(acc, semantics.##) + acc = mix(acc, moduleKind.##) + acc = mixLast(acc, outputMode.##) + finalizeHash(acc, 3) + } + + override def toString(): String = { + s"""CoreSpec( + | semantics = $semantics, + | moduleKind = $moduleKind, + | outputMode = $outputMode + |)""".stripMargin + } +} + +private[linker] object CoreSpec { + private val HashSeed = + scala.util.hashing.MurmurHash3.stringHash(classOf[CoreSpec].getName) + + private[linker] val Defaults: CoreSpec = { + new CoreSpec( + semantics = Semantics.Defaults, + moduleKind = ModuleKind.NoModule, + outputMode = OutputMode.Default) + } + + private[linker] def apply( + semantics: Semantics, + moduleKind: ModuleKind, + outputMode: OutputMode): CoreSpec = { + new CoreSpec(semantics, moduleKind, outputMode) + } +} From 46fdf249c9d16ecd7081979e4b67a52de8a7f22a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 6 Jul 2017 15:47:04 +0200 Subject: [PATCH 0419/2665] Move the `javascript` package inside `linker.backend`. Only the backends should be concerned with manipulating JavaScript trees and printing them. --- .../tools/linker/backend/closure/ClosureAstBuilder.scala | 4 ++-- .../linker/backend/closure/ClosureAstTransformer.scala | 2 +- .../core/tools/linker/backend/BasicLinkerBackend.scala | 5 ++++- .../core/tools/linker/backend/emitter/ClassEmitter.scala | 4 ++-- .../scalajs/core/tools/linker/backend/emitter/Emitter.scala | 3 +-- .../core/tools/linker/backend/emitter/FunctionEmitter.scala | 4 ++-- .../scalajs/core/tools/linker/backend/emitter/JSGen.scala | 6 +++--- .../scalajs/core/tools/linker/backend/emitter/TreeDSL.scala | 2 +- .../tools/{ => linker/backend}/javascript/JSBuilders.scala | 2 +- .../tools/{ => linker/backend}/javascript/Printers.scala | 2 +- .../{ => linker/backend}/javascript/SourceMapWriter.scala | 2 +- .../core/tools/{ => linker/backend}/javascript/Trees.scala | 2 +- 12 files changed, 20 insertions(+), 18 deletions(-) rename tools/shared/src/main/scala/org/scalajs/core/tools/{ => linker/backend}/javascript/JSBuilders.scala (98%) rename tools/shared/src/main/scala/org/scalajs/core/tools/{ => linker/backend}/javascript/Printers.scala (99%) rename tools/shared/src/main/scala/org/scalajs/core/tools/{ => linker/backend}/javascript/SourceMapWriter.scala (99%) rename tools/shared/src/main/scala/org/scalajs/core/tools/{ => linker/backend}/javascript/Trees.scala (99%) diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstBuilder.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstBuilder.scala index 9a9923eec5..f48077bdb4 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstBuilder.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstBuilder.scala @@ -3,8 +3,8 @@ package org.scalajs.core.tools.linker.backend.closure import org.scalajs.core.ir import ir.Position.NoPosition -import org.scalajs.core.tools.javascript.Trees.Tree -import org.scalajs.core.tools.javascript.JSTreeBuilder +import org.scalajs.core.tools.linker.backend.javascript.Trees.Tree +import org.scalajs.core.tools.linker.backend.javascript.JSTreeBuilder import com.google.javascript.rhino._ import com.google.javascript.jscomp._ diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala index e3e44ea032..217f5fe52d 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala @@ -6,7 +6,7 @@ import org.scalajs.core.ir import ir.Position import ir.Position.NoPosition -import org.scalajs.core.tools.javascript.Trees._ +import org.scalajs.core.tools.linker.backend.javascript.Trees._ import com.google.javascript.rhino._ import com.google.javascript.jscomp._ diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala index 2370ffdf6a..77e8778479 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala @@ -15,7 +15,10 @@ import org.scalajs.core.tools.io.WritableVirtualJSFile import org.scalajs.core.tools.linker.LinkingUnit import org.scalajs.core.tools.linker.analyzer.SymbolRequirement import org.scalajs.core.tools.linker.backend.emitter.Emitter -import org.scalajs.core.tools.javascript.{JSFileBuilder, JSFileBuilderWithSourceMap} + +import org.scalajs.core.tools.linker.backend.javascript.{ + JSFileBuilder, JSFileBuilderWithSourceMap +} /** The basic backend for the Scala.js linker. * diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index 0cebd06760..ff0e5b3da6 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -15,9 +15,9 @@ import Transformers._ import org.scalajs.core.ir.Trees._ import Types._ -import org.scalajs.core.tools.javascript.{Trees => js} import org.scalajs.core.tools.linker._ -import org.scalajs.core.tools.linker.backend.OutputMode +import org.scalajs.core.tools.linker.standard.OutputMode +import org.scalajs.core.tools.linker.backend.javascript.{Trees => js} import CheckedBehavior.Unchecked diff --git 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 index 756777c91b..68fb66c6b7 100644 --- 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 @@ -20,11 +20,10 @@ import org.scalajs.core.ir.Definitions.decodeClassName import org.scalajs.core.tools.io._ import org.scalajs.core.tools.logging._ -import org.scalajs.core.tools.javascript.{Trees => js, _} - import org.scalajs.core.tools.linker._ import org.scalajs.core.tools.linker.standard._ import org.scalajs.core.tools.linker.analyzer.SymbolRequirement +import org.scalajs.core.tools.linker.backend.javascript.{Trees => js, _} import GlobalRefUtils._ diff --git 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 index 1fe785ff54..15988b2fcf 100644 --- 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 @@ -24,8 +24,8 @@ import org.scalajs.core.tools.sem._ import CheckedBehavior._ import org.scalajs.core.tools.linker.LinkedClass -import org.scalajs.core.tools.linker.backend.OutputMode -import org.scalajs.core.tools.javascript.{Trees => js} +import org.scalajs.core.tools.linker.standard.OutputMode +import org.scalajs.core.tools.linker.backend.javascript.{Trees => js} import java.io.StringWriter diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala index 1543067cc3..e73fb7e11f 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala @@ -18,9 +18,9 @@ import ir._ import ir.Types._ import ir.{Trees => irt} -import org.scalajs.core.tools.sem._ -import org.scalajs.core.tools.linker.backend.{ModuleKind, OutputMode} -import org.scalajs.core.tools.javascript.Trees._ +import org.scalajs.core.tools.linker._ +import org.scalajs.core.tools.linker.standard.OutputMode +import org.scalajs.core.tools.linker.backend.javascript.Trees._ /** Collection of tree generators that are used accross the board. * This class is fully stateless. diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/TreeDSL.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/TreeDSL.scala index a90ea68abf..90a9a68709 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/TreeDSL.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/TreeDSL.scala @@ -14,7 +14,7 @@ import scala.language.implicitConversions import org.scalajs.core.ir import org.scalajs.core.ir.Position -import org.scalajs.core.tools.javascript.Trees._ +import org.scalajs.core.tools.linker.backend.javascript.Trees._ private[emitter] object TreeDSL { implicit class TreeOps(val self: Tree) extends AnyVal { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/JSBuilders.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/JSBuilders.scala similarity index 98% rename from tools/shared/src/main/scala/org/scalajs/core/tools/javascript/JSBuilders.scala rename to tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/JSBuilders.scala index 77cb982fb0..269bba78d4 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/JSBuilders.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/JSBuilders.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.javascript +package org.scalajs.core.tools.linker.backend.javascript import scala.annotation.tailrec diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Printers.scala similarity index 99% rename from tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala rename to tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Printers.scala index 7fbf231f19..f75a21dc98 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Printers.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.javascript +package org.scalajs.core.tools.linker.backend.javascript import scala.annotation.switch diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/SourceMapWriter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/SourceMapWriter.scala similarity index 99% rename from tools/shared/src/main/scala/org/scalajs/core/tools/javascript/SourceMapWriter.scala rename to tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/SourceMapWriter.scala index 7cd10d9142..3ecdb4549a 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/SourceMapWriter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/SourceMapWriter.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.javascript +package org.scalajs.core.tools.linker.backend.javascript import java.io.Writer import java.net.URI diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Trees.scala similarity index 99% rename from tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala rename to tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Trees.scala index 6a0ce1f907..0bc9292ea3 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Trees.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.javascript +package org.scalajs.core.tools.linker.backend.javascript import scala.annotation.switch From d0d059a76aee7be066a440dca3506e6556948fbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 6 Jul 2017 16:00:05 +0200 Subject: [PATCH 0420/2665] Move `Semantics`, `CheckedBehavior` and `ModuleKind` to `linker._`. This is part of the plan for the new linker API #2998. --- CODINGSTYLE.md | 5 ++-- .../scala/tools/nsc/MainGenericRunner.scala | 2 +- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 2 +- .../testadapter/FrameworkDetector.scala | 2 +- .../testadapter/ScalaJSFramework.scala | 2 +- .../closure/ClosureLinkerBackend.scala | 2 +- .../{sem => linker}/CheckedBehavior.scala | 2 +- .../linker/{backend => }/ModuleKind.scala | 2 +- .../tools/{sem => linker}/Semantics.scala | 4 +-- .../core/tools/linker/StandardLinker.scala | 2 +- .../linker/backend/emitter/CoreJSLibs.scala | 4 +-- .../backend/emitter/FunctionEmitter.scala | 6 ++--- .../scalajs/core/tools/linker/package.scala | 26 ------------------- 13 files changed, 15 insertions(+), 46 deletions(-) rename tools/shared/src/main/scala/org/scalajs/core/tools/{sem => linker}/CheckedBehavior.scala (95%) rename tools/shared/src/main/scala/org/scalajs/core/tools/linker/{backend => }/ModuleKind.scala (96%) rename tools/shared/src/main/scala/org/scalajs/core/tools/{sem => linker}/Semantics.scala (98%) delete mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/linker/package.scala diff --git a/CODINGSTYLE.md b/CODINGSTYLE.md index 5781b4dfd9..518b7e269e 100644 --- a/CODINGSTYLE.md +++ b/CODINGSTYLE.md @@ -268,9 +268,8 @@ import scala.collection.mutable import java.{util => ju} -import org.scalajs.core.tools.sem._ -import org.scalajs.core.tools.javascript._ -import org.scalajs.core.tools.optimizer._ +import org.scalajs.core.tools.linker._ +import org.scalajs.core.tools.linker.standard._ ``` Language imports must always come first, and must always be at the top of the file (right after the `package` declaration). diff --git a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala index 14d7d04dd2..1c9384a0c6 100644 --- a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala +++ b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala @@ -37,7 +37,7 @@ class MainGenericRunner { val optMode = OptMode.fromId(System.getProperty("scalajs.partest.optMode")) def readSemantics() = { - import org.scalajs.core.tools.sem.CheckedBehavior.Compliant + import org.scalajs.core.tools.linker.CheckedBehavior.Compliant val opt = Option(System.getProperty("scalajs.partest.compliantSems")) val compliantSems = diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index beef0a9b9a..cf9aa0932c 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -55,7 +55,7 @@ object ScalaJSPlugin extends AutoPlugin { val FullOptStage = Stage.FullOpt // ModuleKind - val ModuleKind = org.scalajs.core.tools.linker.backend.ModuleKind + val ModuleKind = org.scalajs.core.tools.linker.ModuleKind // All our public-facing keys diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/FrameworkDetector.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/FrameworkDetector.scala index 236b53a797..cf15b8fb1b 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/FrameworkDetector.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/FrameworkDetector.scala @@ -4,7 +4,7 @@ import sbt.testing._ import org.scalajs.core.tools.io._ import org.scalajs.core.tools.logging.Logger -import org.scalajs.core.tools.linker.backend.ModuleKind +import org.scalajs.core.tools.linker.ModuleKind import org.scalajs.jsenv._ diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSFramework.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSFramework.scala index c51d68e732..1e3bb774f6 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSFramework.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSFramework.scala @@ -13,7 +13,7 @@ import org.scalajs.core.ir.Utils.escapeJS import org.scalajs.core.tools.io._ import org.scalajs.core.tools.logging._ -import org.scalajs.core.tools.linker.backend.ModuleKind +import org.scalajs.core.tools.linker.ModuleKind import org.scalajs.testadapter.json._ import org.scalajs.jsenv._ diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala index 73465cfe3b..c894db6c30 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala @@ -21,7 +21,7 @@ import com.google.javascript.jscomp.{ import org.scalajs.core.tools.io._ import org.scalajs.core.tools.logging.Logger -import org.scalajs.core.tools.linker.LinkingUnit +import org.scalajs.core.tools.linker._ import org.scalajs.core.tools.linker.analyzer.SymbolRequirement import org.scalajs.core.tools.linker.backend._ import org.scalajs.core.tools.linker.backend.emitter.Emitter diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/sem/CheckedBehavior.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/CheckedBehavior.scala similarity index 95% rename from tools/shared/src/main/scala/org/scalajs/core/tools/sem/CheckedBehavior.scala rename to tools/shared/src/main/scala/org/scalajs/core/tools/linker/CheckedBehavior.scala index 5a43c7ee71..c813603f66 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/sem/CheckedBehavior.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/CheckedBehavior.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.sem +package org.scalajs.core.tools.linker sealed abstract class CheckedBehavior { import CheckedBehavior._ diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/ModuleKind.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ModuleKind.scala similarity index 96% rename from tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/ModuleKind.scala rename to tools/shared/src/main/scala/org/scalajs/core/tools/linker/ModuleKind.scala index 33c3bbd07d..e6d3d21d0e 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/ModuleKind.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ModuleKind.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.linker.backend +package org.scalajs.core.tools.linker /** Kind of module structure emitted for the Scala.js output. */ sealed abstract class ModuleKind diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/sem/Semantics.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Semantics.scala similarity index 98% rename from tools/shared/src/main/scala/org/scalajs/core/tools/sem/Semantics.scala rename to tools/shared/src/main/scala/org/scalajs/core/tools/linker/Semantics.scala index 56ce92e24a..a554803e8c 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/sem/Semantics.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Semantics.scala @@ -7,12 +7,10 @@ \* */ -package org.scalajs.core.tools.sem +package org.scalajs.core.tools.linker import scala.collection.immutable.Traversable -import org.scalajs.core.tools.linker.LinkedClass - import CheckedBehavior._ final class Semantics private ( 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 0594116181..23a8b75112 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 @@ -189,7 +189,7 @@ object StandardLinker { * * The defaults are: * - * - `semantics`: [[org.scalajs.core.tools.sem.Semantics.Defaults Semantics.Defaults]] + * - `semantics`: [[Semantics.Defaults]] * - `moduleKind`: [[ModuleKind.NoModule]] * - `checkIR`: `false` * - `optimizer`: `true` diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala index 59c57252c9..499d80ba94 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala @@ -14,8 +14,8 @@ import java.net.URI import org.scalajs.core.ir.ScalaJSVersions import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.sem._ -import org.scalajs.core.tools.linker.backend.{ModuleKind, OutputMode} +import org.scalajs.core.tools.linker._ +import org.scalajs.core.tools.linker.standard._ import scala.collection.immutable.Seq import scala.collection.mutable diff --git 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 index 15988b2fcf..0569205446 100644 --- 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 @@ -20,10 +20,8 @@ import ir.Transformers._ import ir.Trees._ import ir.Types._ -import org.scalajs.core.tools.sem._ -import CheckedBehavior._ - -import org.scalajs.core.tools.linker.LinkedClass +import org.scalajs.core.tools.linker._ +import org.scalajs.core.tools.linker.CheckedBehavior._ import org.scalajs.core.tools.linker.standard.OutputMode import org.scalajs.core.tools.linker.backend.javascript.{Trees => js} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/package.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/package.scala deleted file mode 100644 index d23ef0c007..0000000000 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/package.scala +++ /dev/null @@ -1,26 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - -package org.scalajs.core.tools - -package object linker { - type Semantics = org.scalajs.core.tools.sem.Semantics - - val Semantics: org.scalajs.core.tools.sem.Semantics.type = - org.scalajs.core.tools.sem.Semantics - - type CheckedBehavior = org.scalajs.core.tools.sem.CheckedBehavior - - val CheckedBehavior: org.scalajs.core.tools.sem.CheckedBehavior.type = - org.scalajs.core.tools.sem.CheckedBehavior - - type ModuleKind = org.scalajs.core.tools.linker.backend.ModuleKind - - val ModuleKind: org.scalajs.core.tools.linker.backend.ModuleKind.type = - org.scalajs.core.tools.linker.backend.ModuleKind -} From 2e8382da092f61b424d3e0dd6c61cf327e080322 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 6 Jul 2017 16:16:10 +0200 Subject: [PATCH 0421/2665] Move `OutputMode` to `linker.standard._`. This is part of the plan for the new linker API #2998. --- .../tools/linker/backend/closure/ClosureLinkerBackend.scala | 1 + .../scala/org/scalajs/core/tools/linker/StandardLinker.scala | 2 +- .../core/tools/linker/backend/emitter/GlobalRefUtils.scala | 2 +- .../core/tools/linker/{backend => standard}/OutputMode.scala | 2 +- .../org/scalajs/core/tools/linker/standard/package.scala | 5 ----- 5 files changed, 4 insertions(+), 8 deletions(-) rename tools/shared/src/main/scala/org/scalajs/core/tools/linker/{backend => standard}/OutputMode.scala (97%) diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala index c894db6c30..0e7a85f75c 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala @@ -22,6 +22,7 @@ import org.scalajs.core.tools.io._ import org.scalajs.core.tools.logging.Logger import org.scalajs.core.tools.linker._ +import org.scalajs.core.tools.linker.standard._ import org.scalajs.core.tools.linker.analyzer.SymbolRequirement import org.scalajs.core.tools.linker.backend._ import org.scalajs.core.tools.linker.backend.emitter.Emitter 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 23a8b75112..ad0caa4662 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 @@ -205,7 +205,7 @@ object StandardLinker { * import org.scalajs.core.tools.linker.standard._ * }}} * - * - `outputMode`: [[org.scalajs.core.tools.linker.backend.OutputMode.Default OutputMode.Default]] + * - `outputMode`: [[org.scalajs.core.tools.linker.standard.OutputMode.Default OutputMode.Default]] */ def apply(): Config = new Config() } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalRefUtils.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalRefUtils.scala index 51254164f9..5a81217f1a 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalRefUtils.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalRefUtils.scala @@ -8,7 +8,7 @@ package org.scalajs.core.tools.linker.backend.emitter -import org.scalajs.core.tools.linker.backend.OutputMode +import org.scalajs.core.tools.linker.standard.OutputMode /** Utilities related to global refs mentioned in the program. * diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/OutputMode.scala similarity index 97% rename from tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala rename to tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/OutputMode.scala index d71c5ea911..3f7189dec4 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/OutputMode.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.linker.backend +package org.scalajs.core.tools.linker.standard /** JavaScript output mode. */ sealed abstract class OutputMode diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/package.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/package.scala index a880b1c5b8..c2b62642fa 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/package.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/package.scala @@ -9,11 +9,6 @@ package org.scalajs.core.tools.linker package object standard { - type OutputMode = org.scalajs.core.tools.linker.backend.OutputMode - - val OutputMode: org.scalajs.core.tools.linker.backend.OutputMode.type = - org.scalajs.core.tools.linker.backend.OutputMode - implicit class StandardLinkerConfigStandardOps( val __self: StandardLinker.Config) extends AnyVal { From dfc3bed6582a99d801dec10f441b99f1e67eb8a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 19 Jul 2017 14:11:17 +0200 Subject: [PATCH 0422/2665] Upgrade to sbt 0.13.16. That version adds support for `^^` which allows to cross-compile sbt plugins without having the change the version of sbt used for the build itself. --- project/build.properties | 2 +- sbt-plugin-test/project/build.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/project/build.properties b/project/build.properties index 64317fdae5..c091b86ca4 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.15 +sbt.version=0.13.16 diff --git a/sbt-plugin-test/project/build.properties b/sbt-plugin-test/project/build.properties index 64317fdae5..c091b86ca4 100644 --- a/sbt-plugin-test/project/build.properties +++ b/sbt-plugin-test/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.15 +sbt.version=0.13.16 From 81a9571d58548e4b0db5231f537f987909f5b064 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 19 Jul 2017 14:16:30 +0200 Subject: [PATCH 0423/2665] Do not rely on `sbt.StringUtilities.nonEmpty`. This method has become internal to sbt in 1.x. --- .../main/scala/org/scalajs/sbtplugin/AbstractJSDeps.scala | 4 +--- .../org/scalajs/sbtplugin/impl/DependencyBuilders.scala | 8 +++----- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/AbstractJSDeps.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/AbstractJSDeps.scala index 5f506a992f..aeb35fc62a 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/AbstractJSDeps.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/AbstractJSDeps.scala @@ -2,8 +2,6 @@ package org.scalajs.sbtplugin import sbt._ -import StringUtilities.nonEmpty - import org.scalajs.core.tools.jsdep.JSDependency /** Something JavaScript related a project may depend on. Either a JavaScript @@ -17,7 +15,7 @@ sealed trait AbstractJSDep { def %(configurations: String): AbstractJSDep = { require(this.configurations.isEmpty, "Configurations already specified for jsModule " + this) - nonEmpty(configurations, "Configurations") + require(configurations.trim.nonEmpty, "Configurations cannot be empty.") withConfigs(Some(configurations)) } diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/DependencyBuilders.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/DependencyBuilders.scala index 01279e1155..ed5c6cf9da 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/DependencyBuilders.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/DependencyBuilders.scala @@ -15,11 +15,9 @@ import scala.language.experimental.macros import sbt._ -import StringUtilities.nonEmpty - trait DependencyBuilders { final implicit def toScalaJSGroupID(groupID: String): ScalaJSGroupID = { - nonEmpty(groupID, "Group ID") + require(groupID.trim.nonEmpty, "Group ID cannot be empty.") new ScalaJSGroupID(groupID) } @@ -76,7 +74,7 @@ object ScalaJSGroupID { */ def withCross(groupID: ScalaJSGroupID, artifactID: String, cross: CrossVersion): CrossGroupArtifactID = { - nonEmpty(artifactID, "Artifact ID") + require(artifactID.trim.nonEmpty, "Artifact ID cannot be empty.") new CrossGroupArtifactID(groupID.groupID, artifactID, cross) } @@ -106,7 +104,7 @@ object ScalaJSGroupID { final class CrossGroupArtifactID(groupID: String, artifactID: String, crossVersion: CrossVersion) { def %(revision: String): ModuleID = { - nonEmpty(revision, "Revision") + require(revision.trim.nonEmpty, "Revision cannot be empty.") ModuleID(groupID, artifactID, revision).cross(crossVersion) } } From 8a48b4ccba4e7cf62bbc6a784352957cc71b31a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 19 Jul 2017 15:47:06 +0200 Subject: [PATCH 0424/2665] Move accesses to task values outside of the control flow. Dependent tasks are always executed as soon as they are referred to by another task, even if it is behind control flow. sbt 1.x prevents that kind of uses so that users do not get confused, so we move some `.value`s out of control flow structures to make sbt 1.x happy. --- .../sbtplugin/ScalaJSPluginInternal.scala | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index c3fb38a17b..8c1f8b2c43 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -638,13 +638,19 @@ object ScalaJSPluginInternal { jsDependencyManifests.value.data.exists(_.requiresDOM)) }, - resolvedJSEnv := jsEnv.?.value.getOrElse { - if (scalaJSUseRhinoInternal.value) { - RhinoJSEnvInternal().value - } else if (scalaJSRequestsDOM.value) { - new org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv() - } else { - new org.scalajs.jsenv.nodejs.NodeJSEnv() + resolvedJSEnv := { + val useRhino = scalaJSUseRhinoInternal.value + val rhinoJSEnv = RhinoJSEnvInternal().value + val requestsDOM = scalaJSRequestsDOM.value + + jsEnv.?.value.getOrElse { + if (useRhino) { + rhinoJSEnv + } else if (requestsDOM) { + new org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv() + } else { + new org.scalajs.jsenv.nodejs.NodeJSEnv() + } } }, @@ -853,11 +859,12 @@ object ScalaJSPluginInternal { } } else { Def.task { + val moduleKind = scalaJSModuleKind.value + val moduleIdentifier = scalaJSModuleIdentifier.value + (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)( From af28b22b2b048c92a87e9d38a09ec702e3af7201 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 20 Jul 2017 11:13:59 +0200 Subject: [PATCH 0425/2665] Address sbt-related deprecations in sbt-plugin-test. --- sbt-plugin-test/build.sbt | 12 +++++++----- sbt-plugin-test/project/Jetty9Test.scala | 8 ++++---- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index c94eb52d18..ee8c333a15 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -14,7 +14,7 @@ val baseSettings = versionSettings ++ Seq( TestFramework("com.novocode.junit.JUnitFramework"), "-v", "-a", "-s"), // Test that non-existent classpath entries are allowed - #2198 - fullClasspath in Compile += (baseDirectory in "root").value / + fullClasspath in Compile += (baseDirectory in LocalProject("root")).value / "non-existent-directory-please-dont-ever-create-this" ) @@ -55,7 +55,9 @@ lazy val noDOM = project.settings(baseSettings: _*). /* This hopefully exposes concurrent uses of the linker. If it fails/gets * flaky, there is a bug somewhere - #2202 */ - settings(inConfig(Compile)(run <<= run.dependsOn(fastOptJS, loadedJSEnv)): _*) + settings( + inConfig(Compile)(run := run.dependsOn(fastOptJS, loadedJSEnv).evaluated) + ) lazy val withDOM = project.settings(baseSettings: _*). enablePlugins(ScalaJSPlugin). @@ -83,7 +85,7 @@ lazy val jetty9 = project.settings(baseSettings: _*). "org.webjars" % "jquery" % "1.10.2" / "jquery.js" ), // Use PhantomJS, allow cross domain requests - postLinkJSEnv := PhantomJSEnv(args = Seq("--web-security=no")).value, + jsEnv := PhantomJSEnv(args = Seq("--web-security=no")).value, Jetty9Test.runSetting ) @@ -191,7 +193,7 @@ lazy val jsDependenciesTest = withRegretionTestForIssue2243( "jquery.js" -> "1.10.2/jquery.js") ). settings(inConfig(Compile)(Seq( - packageJSDependencies <<= packageJSDependencies.dependsOn(Def.task { + packageJSDependencies := packageJSDependencies.dependsOn(Def.task { // perform verifications on the ordering and deduplications val resolvedDeps = resolvedJSDependencies.value.data val relPaths = resolvedDeps.map(_.info.relPath) @@ -227,7 +229,7 @@ lazy val jsDependenciesTest = withRegretionTestForIssue2243( "compressed/history.js appears before foo.js") streams.value.log.info("jsDependencies resolution test passed") - }) + }).value )): _*). dependsOn(jetty9) // depends on jQuery ) diff --git a/sbt-plugin-test/project/Jetty9Test.scala b/sbt-plugin-test/project/Jetty9Test.scala index dc025a756a..b5b2bfda8d 100644 --- a/sbt-plugin-test/project/Jetty9Test.scala +++ b/sbt-plugin-test/project/Jetty9Test.scala @@ -3,7 +3,7 @@ import Keys._ import org.scalajs.sbtplugin._ import ScalaJSPlugin.autoImport._ -import Implicits._ +import Loggers._ import org.scalajs.jsenv._ import org.scalajs.core.tools.io._ @@ -20,7 +20,7 @@ object Jetty9Test { private val jettyPort = 23548 - val runSetting = run <<= Def.inputTask { + val runSetting = run := Def.inputTask { val jsEnv = (loadedJSEnv in Compile).value.asInstanceOf[ComJSEnv] val jsConsole = scalaJSConsole.value @@ -44,7 +44,7 @@ object Jetty9Test { val runner = jsEnv.comRunner(code) - runner.start(streams.value.log, jsConsole) + runner.start(sbtLogger2ToolsLogger(streams.value.log), jsConsole) val jetty = setupJetty((resourceDirectory in Compile).value) @@ -66,7 +66,7 @@ object Jetty9Test { jetty.start() runner.await(30.seconds) jetty.join() - } + }.evaluated private def setupJetty(dir: File): Server = { val server = new Server(jettyPort) From 9c2438ddab098eb30179833bd234e880e8d1a443 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 20 Jul 2017 11:18:15 +0200 Subject: [PATCH 0426/2665] Remove the deprecated method `CrossProject.settingSets`. This method cannot be implemented in sbt 1.x anymore, so we need to remove it before we can cross-compile to sbt 1.x. --- project/BinaryIncompatibilities.scala | 3 +++ .../org/scalajs/sbtplugin/cross/CrossProject.scala | 13 ------------- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 000ec620fe..5a6913079a 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -22,6 +22,9 @@ object BinaryIncompatibilities { ) val SbtPlugin = Seq( + // Breaking! Removal of `CrossProject.settingSets`, deprecated since 0.6.16 + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.sbtplugin.cross.CrossProject.settingSets") ) val TestAdapter = Seq( diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossProject.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossProject.scala index 7017118195..ec75bcd707 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossProject.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossProject.scala @@ -270,19 +270,6 @@ final class CrossProject private ( def overrideConfigs(cs: Configuration*): CrossProject = copy(jvm.overrideConfigs(cs: _*), js.overrideConfigs(cs: _*)) - /** Configures how settings from other sources, such as .sbt files, are - * appended to the explicitly specified settings for this project. - * - * Note: If you disable AutoPlugins here, Scala.js will not work - */ - @deprecated( - "Project#settingSets will be removed from sbt 1.0, hence " + - "CrossProject#settingSets will be removed from Scala.js 1.0. " + - "As a temporary measure, use `.configureAll(_.settingSets(select))`.", - "0.6.16") - def settingSets(select: AddSettings*): CrossProject = - copy(jvm.settingSets(select: _*), js.settingSets(select: _*)) - def settings(ss: Def.SettingsDefinition*): CrossProject = copy(jvm.settings(ss: _*), js.settings(ss: _*)) From a9dba3c64bf4417561240df7d0dec57dad2ef2f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 20 Jul 2017 14:02:45 +0200 Subject: [PATCH 0427/2665] Fix a linear stack usage in OptimizerCore.transformExprsOrSpreads. When running with Scala 2.12.2 (e.g., under sbt 1.0.0-RC2), this code produced `StackOverflowError`s. --- .../frontend/optimizer/OptimizerCore.scala | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index 8d35cce7da..83ca4aea79 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -1732,8 +1732,16 @@ private[optimizer] abstract class OptimizerCore( private def transformExprsOrSpreads(trees: List[Tree])( implicit scope: Scope): List[Tree] = { - trees match { - case (spread: JSSpread) :: rest => + /* This is basically a flatMap, but we do it manually because flatMap would + * generate many garbage intermediate lists, when in fact the case JSSpread + * should be fairly rare. In general, we avoid flatMaps over collections in + * OptimizerCore. + */ + + val builder = List.newBuilder[Tree] + + trees.foreach { + case spread: JSSpread => implicit val pos = spread.pos val newSpreadItems = trampoline { @@ -1752,19 +1760,16 @@ private[optimizer] abstract class OptimizerCore( } } - val newRest = transformExprsOrSpreads(rest) - newSpreadItems match { - case JSArrayConstr(newFirsts) => newFirsts ::: newRest - case _ => JSSpread(newSpreadItems) :: newRest + case JSArrayConstr(newFirsts) => builder ++= newFirsts + case _ => builder += JSSpread(newSpreadItems) } - case first :: rest => - transformExpr(first) :: transformExprsOrSpreads(rest) - - case Nil => - Nil + case tree => + builder += transformExpr(tree) } + + builder.result() } private val ClassNamesThatShouldBeInlined = Set( From 831fd38d1acb82fa241d58e9fd9ef1ebfa0d4786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 20 Jul 2017 15:21:01 +0200 Subject: [PATCH 0428/2665] Fix #3065: Cross-compile the sbt plugin for sbt 1.0.0-RC2. We use the `^^` command of sbt 0.13.16-M1 to cross-compile the sbt plugin for sbt 1.0.0-RC2 without actually changing our own build to use sbt 1.0.0-RC2. Our own build, as it currently stands, does not yet support 1.0.0-RC2. This upgrade should only be done in master. --- ci/matrix.xml | 20 +++++- project/Build.scala | 7 +- project/build.sbt | 3 +- .../org/scalajs/sbtplugin/SBTCompat.scala | 61 +++++++++++++++++ .../org/scalajs/sbtplugin/SBTCompat.scala | 68 +++++++++++++++++++ .../scalajs/sbtplugin/AbstractJSDeps.scala | 5 +- .../sbtplugin/ScalaJSCrossVersion.scala | 18 ++--- .../sbtplugin/ScalaJSJUnitPlugin.scala | 7 +- .../sbtplugin/ScalaJSPluginInternal.scala | 56 ++++++--------- scripts/publish.sh | 3 + 10 files changed, 190 insertions(+), 58 deletions(-) create mode 100644 sbt-plugin/src/main/scala-sbt-0.13/org/scalajs/sbtplugin/SBTCompat.scala create mode 100644 sbt-plugin/src/main/scala-sbt-1.0/org/scalajs/sbtplugin/SBTCompat.scala diff --git a/ci/matrix.xml b/ci/matrix.xml index e42608467e..111bb44830 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -260,14 +260,18 @@ ]]> ./project/build.properties; fi && sbt noDOM/run noDOM/testHtmlFastOpt noDOM/testHtmlFullOpt \ withDOM/run withDOM/testHtmlFastOpt withDOM/testHtmlFullOpt \ multiTestJS/test:run multiTestJS/testHtmlFastOpt multiTestJS/testHtmlFullOpt \ @@ -473,7 +477,17 @@ 1.8 - + + + 1.7 + 2.10.6 + + + + 1.8 + 2.12.2 + 1.0.0-RC2 + diff --git a/project/Build.scala b/project/Build.scala index 8a095971ff..66ad34d38d 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -806,6 +806,11 @@ object Build { previousArtifactSetting, mimaBinaryIssueFilters ++= BinaryIncompatibilities.SbtPlugin, + /* TODO Remove this in 1.x, since there are no macros in sbt-plugin + * anymore. + */ + scalacOptions -= "-Xfatal-warnings", + // Add API mappings for sbt (seems they don't export their API URL) apiMappings ++= { val deps = (externalDependencyClasspath in Compile).value @@ -821,7 +826,7 @@ object Build { sbtJars.map(_.data -> docUrl).toMap } ) - ).dependsOn(tools, jsEnvs, testAdapter) + ).dependsOn(tools, jsEnvs, testAdapter).enableScalastyleInSharedSources lazy val delambdafySetting = { scalacOptions ++= ( diff --git a/project/build.sbt b/project/build.sbt index ba4d3524d3..b573ab835b 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -34,7 +34,8 @@ unmanagedSourceDirectories in Compile ++= { root / "tools/jvm/src/main/scala", root / "js-envs/src/main/scala", root / "test-adapter/src/main/scala", - root / "sbt-plugin/src/main/scala" + root / "sbt-plugin/src/main/scala", + root / "sbt-plugin/src/main/scala-sbt-0.13" ) } diff --git a/sbt-plugin/src/main/scala-sbt-0.13/org/scalajs/sbtplugin/SBTCompat.scala b/sbt-plugin/src/main/scala-sbt-0.13/org/scalajs/sbtplugin/SBTCompat.scala new file mode 100644 index 0000000000..3f5d4acf0c --- /dev/null +++ b/sbt-plugin/src/main/scala-sbt-0.13/org/scalajs/sbtplugin/SBTCompat.scala @@ -0,0 +1,61 @@ +package org.scalajs.sbtplugin + +import sbt._ + +import org.scalajs.core.tools.io.FileVirtualFile + +private[sbtplugin] object SBTCompat { + type IncOptions = sbt.inc.IncOptions + + type CompileAnalysis = sbt.inc.Analysis + + val formatImplicits: sbt.Cache.type = sbt.Cache + + def moduleIDWithConfigurations(moduleID: ModuleID, + configurations: Option[String]): ModuleID = { + moduleID.copy(configurations = configurations) + } + + def crossVersionAddScalaJSPart(cross: CrossVersion, + part: String): CrossVersion = { + cross match { + case CrossVersion.Disabled => + CrossVersion.binaryMapped(_ => part) + case cross: CrossVersion.Binary => + CrossVersion.binaryMapped( + cross.remapVersion.andThen(part + "_" + _)) + case cross: CrossVersion.Full => + CrossVersion.fullMapped( + cross.remapVersion.andThen(part + "_" + _)) + } + } + + /** 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 sbt.inc.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.withNewClassfileManager(newClassfileManager) + } +} diff --git a/sbt-plugin/src/main/scala-sbt-1.0/org/scalajs/sbtplugin/SBTCompat.scala b/sbt-plugin/src/main/scala-sbt-1.0/org/scalajs/sbtplugin/SBTCompat.scala new file mode 100644 index 0000000000..1e1ce5dea6 --- /dev/null +++ b/sbt-plugin/src/main/scala-sbt-1.0/org/scalajs/sbtplugin/SBTCompat.scala @@ -0,0 +1,68 @@ +package org.scalajs.sbtplugin + +import sbt._ + +import org.scalajs.core.tools.io.FileVirtualFile + +private[sbtplugin] object SBTCompat { + type IncOptions = xsbti.compile.IncOptions + + type CompileAnalysis = xsbti.compile.CompileAnalysis + + val formatImplicits: sjsonnew.BasicJsonProtocol.type = + sjsonnew.BasicJsonProtocol + + def moduleIDWithConfigurations(moduleID: ModuleID, + configurations: Option[String]): ModuleID = { + moduleID.withConfigurations(configurations) + } + + def crossVersionAddScalaJSPart(cross: CrossVersion, + part: String): CrossVersion = { + cross match { + case CrossVersion.Disabled => + CrossVersion.constant(part) + case cross: sbt.librarymanagement.Constant => + cross.withValue(part + "_" + cross.value) + case cross: CrossVersion.Binary => + cross.withPrefix(part + "_" + cross.prefix) + case cross: CrossVersion.Full => + cross.withPrefix(part + "_" + cross.prefix) + } + } + + /** 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 = { + import xsbti.compile.{ClassFileManager, ClassFileManagerUtil} + + val sjsirFileManager = new ClassFileManager { + private[this] val inherited = + ClassFileManagerUtil.getDefaultClassFileManager(incOptions) + + def delete(classes: Array[File]): Unit = { + inherited.delete(classes.flatMap { classFile => + if (classFile.getPath.endsWith(".class")) { + val f = FileVirtualFile.withExtension(classFile, ".class", ".sjsir") + if (f.exists) List(f) + else Nil + } else { + Nil + } + }) + } + + def generated(classes: Array[File]): Unit = {} + def complete(success: Boolean): Unit = {} + } + + val newExternalHooks = + incOptions.externalHooks.withExternalClassFileManager(sjsirFileManager) + incOptions.withExternalHooks(newExternalHooks) + } +} diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/AbstractJSDeps.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/AbstractJSDeps.scala index aeb35fc62a..5312f7906c 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/AbstractJSDeps.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/AbstractJSDeps.scala @@ -4,6 +4,8 @@ import sbt._ import org.scalajs.core.tools.jsdep.JSDependency +import SBTCompat._ + /** Something JavaScript related a project may depend on. Either a JavaScript * module/library, or the DOM at runtime. */ sealed trait AbstractJSDep { @@ -45,7 +47,8 @@ final case class JarJSModuleID( def configurations: Option[String] = module.configurations protected def withConfigs(configs: Option[String]): JSModuleID = - copy(module = module.copy(configurations = configs)) + copy(module = moduleIDWithConfigurations(module, configs)) + protected def withJSDep(jsDep: JSDependency): JSModuleID = copy(jsDep = jsDep) } diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSCrossVersion.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSCrossVersion.scala index 4e22ecce43..a93f9ab227 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSCrossVersion.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSCrossVersion.scala @@ -13,13 +13,9 @@ import sbt._ import org.scalajs.core.ir.ScalaJSVersions -object ScalaJSCrossVersion { - private val scalaJSVersionUnmapped: String => String = - _ => s"sjs$currentBinaryVersion" - - private val scalaJSVersionMap: String => String = - version => s"sjs${currentBinaryVersion}_$version" +import SBTCompat._ +object ScalaJSCrossVersion { private final val ReleaseVersion = raw"""(\d+)\.(\d+)\.(\d+)""".r private final val MinorSnapshotVersion = @@ -33,14 +29,8 @@ object ScalaJSCrossVersion { case _ => full } - def scalaJSMapped(cross: CrossVersion): CrossVersion = cross match { - case CrossVersion.Disabled => - CrossVersion.binaryMapped(scalaJSVersionUnmapped) - case cross: CrossVersion.Binary => - CrossVersion.binaryMapped(cross.remapVersion andThen scalaJSVersionMap) - case cross: CrossVersion.Full => - CrossVersion.fullMapped(cross.remapVersion andThen scalaJSVersionMap) - } + def scalaJSMapped(cross: CrossVersion): CrossVersion = + crossVersionAddScalaJSPart(cross, "sjs" + currentBinaryVersion) val binary: CrossVersion = scalaJSMapped(CrossVersion.binary) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSJUnitPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSJUnitPlugin.scala index eb018174d1..a5eb206ec3 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSJUnitPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSJUnitPlugin.scala @@ -16,12 +16,17 @@ object ScalaJSJUnitPlugin extends AutoPlugin { import ScalaJSPlugin.autoImport._ + /* As of sbt 1, a `config()` must be assigned to a `val` starting with an + * uppercase letter, which will become the "id" of the configuration. + */ + val ScalaJSTestPlugin = config("scala-js-test-plugin").hide + override def projectSettings: Seq[Setting[_]] = Seq( /* The `scala-js-test-plugin` configuration adds a plugin only to the `test` * configuration. It is a refinement of the `plugin` configuration which adds * it to both `compile` and `test`. */ - ivyConfigurations += config("scala-js-test-plugin").hide, + ivyConfigurations += ScalaJSTestPlugin, libraryDependencies ++= Seq( "org.scala-js" % "scalajs-junit-test-plugin" % scalaJSVersion % "scala-js-test-plugin" cross CrossVersion.full, diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 8c1f8b2c43..76150f3078 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -3,14 +3,14 @@ package org.scalajs.sbtplugin import java.util.IllegalFormatException import sbt._ -import sbt.inc.{IncOptions, ClassfileManager} import Keys._ -import sbinary.DefaultProtocol._ -import Cache.seqFormat import complete.Parser import complete.DefaultParsers._ import Loggers._ +import SBTCompat._ +import SBTCompat.formatImplicits._ +import SBTCompat.formatImplicits.seqFormat import org.scalajs.core.tools.sem.Semantics import org.scalajs.core.tools.io.{IO => toolsIO, _} @@ -118,34 +118,9 @@ object ScalaJSPluginInternal { logger.debug("Global IR cache stats: " + globalIRCache.stats.logLine) } - /** 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.withNewClassfileManager(newClassfileManager) - } + /** Patches the IncOptions so that .sjsir files are pruned as needed. */ + def scalaJSPatchIncOptions(incOptions: IncOptions): IncOptions = + SBTCompat.scalaJSPatchIncOptions(incOptions) private def packageJSDependenciesSetting(taskKey: TaskKey[File], cacheName: String, getLib: ResolvedJSDependency => VirtualJSFile): Setting[Task[File]] = { @@ -458,15 +433,16 @@ object ScalaJSPluginInternal { ((moduleName in packageScalaJSLauncherInternal).value + "-launcher.js")), skip in packageScalaJSLauncherInternal := { + // @sbtUnchecked because of https://github.com/sbt/sbt/issues/3299 val value = !persistLauncherInternal.value if (!value) { - if (scalaJSUseMainModuleInitializer.value) { + if (scalaJSUseMainModuleInitializer.value: @sbtUnchecked) { throw new MessageOnlyException( "persistLauncher := true is not compatible with using a main " + "module initializer (scalaJSUseMainModuleInitializer := " + "true), nor is it necessary, since fastOptJS/fullOptJS " + "includes the call to the main method") - } else if (scalaJSModuleKind.value != ModuleKind.NoModule) { + } else if ((scalaJSModuleKind.value: @sbtUnchecked) != ModuleKind.NoModule) { throw new MessageOnlyException( "persistLauncher := true is not compatible with emitting " + "JavaScript modules") @@ -600,7 +576,8 @@ object ScalaJSPluginInternal { * unreasonably overridden values for the fastOptJS and fullOptJS * tasks. Otherwise, this check is bogus. */ - checkCompliance(requirements, scalaJSSemantics.value) + // @sbtUnchecked because of https://github.com/sbt/sbt/issues/3299 + checkCompliance(requirements, scalaJSSemantics.value: @sbtUnchecked) } // Collect originating files @@ -772,14 +749,14 @@ object ScalaJSPluginInternal { } @deprecated("js.JSApps are going away, and this method with them.", "0.6.18") - def discoverJSApps(analysis: inc.Analysis): Seq[String] = { + def discoverJSApps(analysis: CompileAnalysis): Seq[String] = { discoverScalaJSMainClasses(analysis).collect { case (name, false) => name }.toList } private def discoverScalaJSMainClasses( - analysis: inc.Analysis): Map[String, Boolean] = { + analysis: CompileAnalysis): Map[String, Boolean] = { import xsbt.api.{Discovered, Discovery} val jsApp = "scala.scalajs.js.JSApp" @@ -1038,6 +1015,11 @@ object ScalaJSPluginInternal { "org.eclipse.jetty" % "jetty-server" % "8.1.16.v20140903" ) + /* As of sbt 1, a `config()` must be assigned to a `val` starting with an + * uppercase letter, which will become the "id" of the configuration. + */ + val PhantomJSJetty = config("phantom-js-jetty").hide + val scalaJSProjectBaseSettings = Seq( isScalaJSProject := true, @@ -1127,7 +1109,7 @@ object ScalaJSPluginInternal { * them into the PhantomJS runner if necessary. * See scalaJSPhantomJSClassLoader */ - ivyConfigurations += config("phantom-js-jetty").hide, + ivyConfigurations += PhantomJSJetty, libraryDependencies ++= phantomJSJettyModules.map(_ % "phantom-js-jetty"), scalaJSPhantomJSClassLoader := { val report = update.value diff --git a/scripts/publish.sh b/scripts/publish.sh index 27502988c1..2fee9127aa 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -12,6 +12,8 @@ FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.11.0 2.11.1 2.11.2 2.11.4 2. BIN_VERSIONS="2.10.6 2.11.11 2.12.2 2.13.0-M1" CLI_VERSIONS="2.10.6 2.11.11 2.12.2" SBT_VERSION="2.10.6" +SBT1_VERSION="2.12.2" +SBT1_SBTVERSION="1.0.0-RC2" COMPILER="compiler jUnitPlugin" LIBS="library javalibEx ir irJS tools toolsJS jsEnvs jsEnvsTestKit testAdapter stubs testInterface jUnitRuntime" @@ -41,3 +43,4 @@ done # Publish sbt-plugin $CMD "++$SBT_VERSION" "sbtPlugin/publishSigned" +$CMD "++$SBT1_VERSION" "^^$SBT1_SBTVERSION" "sbtPlugin/publishSigned" From 41d3e73a5b8920368f489353ee759d6fa5342ca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 28 Jul 2017 15:22:37 +0200 Subject: [PATCH 0429/2665] Version 0.6.19. --- ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index e7169e5ccb..b083fe525b 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.19-SNAPSHOT" + val current: String = "0.6.19" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" From 5e9886dcf39d55247878d5ba8134ee403388384a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 28 Jul 2017 23:49:31 +0200 Subject: [PATCH 0430/2665] Towards 0.6.20. --- .../scala/org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- project/BinaryIncompatibilities.scala | 10 ---------- project/Build.scala | 2 +- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index b083fe525b..2efab2f894 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.19" + val current: String = "0.6.20-SNAPSHOT" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 5a6913079a..c77318b933 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -6,13 +6,6 @@ object BinaryIncompatibilities { ) val Tools = Seq( - // private, not an issue - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "org.scalajs.core.tools.sem.Semantics.this"), - - // private, not an issue - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.checker.IRChecker#CheckedClass.this") ) val JSEnvs = Seq( @@ -22,9 +15,6 @@ object BinaryIncompatibilities { ) val SbtPlugin = Seq( - // Breaking! Removal of `CrossProject.settingSets`, deprecated since 0.6.16 - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.sbtplugin.cross.CrossProject.settingSets") ) val TestAdapter = Seq( diff --git a/project/Build.scala b/project/Build.scala index 66ad34d38d..d5cd24ba73 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -56,7 +56,7 @@ object Build { val shouldPartest = settingKey[Boolean]( "Whether we should partest the current scala version (and fail if we can't)") - val previousVersion = "0.6.18" + val previousVersion = "0.6.19" val previousSJSBinaryVersion = ScalaJSCrossVersion.binaryScalaJSVersion(previousVersion) val previousBinaryCrossVersion = From 8159bf91fea93e841337755be770e39e2dd85a7b Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 2 Jul 2017 10:31:46 +0200 Subject: [PATCH 0431/2665] Remove brittleness from test adapter tests The test adapter test was making unreasonable assumptions about the ordering guarantees between invocations and messages passed from slave to master. We relax the tests to require only that messages get eventually delivered before a test needs to complete. --- .../scala/sbttest/framework/BaseRunner.scala | 8 +++++ .../scala/sbttest/framework/DummyTask.scala | 5 +++- .../sbttest/framework/MasterRunner.scala | 7 +++++ .../scala/sbttest/framework/SlaveRunner.scala | 29 ++++--------------- 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/BaseRunner.scala b/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/BaseRunner.scala index 8c1702a343..805f390d51 100644 --- a/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/BaseRunner.scala +++ b/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/BaseRunner.scala @@ -2,6 +2,8 @@ package sbttest.framework import sbt.testing._ +import scala.concurrent._ + abstract class BaseRunner( val args: Array[String], val remoteArgs: Array[String], @@ -14,6 +16,12 @@ abstract class BaseRunner( /** Called by task when it has finished executing */ private[framework] def taskDone(): Unit + /** Tasks need to wait for this future to complete if they get called with a + * continuation. This is used to ensure that the master/slave message channel + * eventually delivers messages. + */ + private[framework] val taskBlock: Future[Unit] + def serializeTask(task: Task, serializer: TaskDef => String): String = serializer(task.taskDef) diff --git a/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/DummyTask.scala b/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/DummyTask.scala index 2ea89b7f50..0082ada2a8 100644 --- a/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/DummyTask.scala +++ b/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/DummyTask.scala @@ -4,6 +4,8 @@ import sbt.testing._ import org.scalajs.testinterface.TestUtils +import scala.concurrent.ExecutionContext.Implicits.global + final class DummyTask( val taskDef: TaskDef, runner: BaseRunner @@ -34,7 +36,8 @@ final class DummyTask( def execute(eventHandler: EventHandler, loggers: Array[Logger], continuation: Array[Task] => Unit): Unit = { - continuation(execute(eventHandler, loggers)) + val tasks = execute(eventHandler, loggers) + runner.taskBlock.foreach(_ => continuation(tasks)) } private class DummyEvent(taskDef: TaskDef, t: Option[Throwable]) extends Event { diff --git a/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/MasterRunner.scala b/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/MasterRunner.scala index 45161a4b67..e815ee013f 100644 --- a/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/MasterRunner.scala +++ b/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/MasterRunner.scala @@ -2,6 +2,8 @@ package sbttest.framework import sbt.testing._ +import scala.concurrent._ + import java.util.concurrent.atomic.AtomicInteger final class MasterRunner( @@ -19,6 +21,11 @@ final class MasterRunner( /** Number of running slaves in the whole system */ private[this] val slaveCount = new AtomicInteger(0) + /** If a task gets called in the master, there is no point waiting for + * messages. + */ + private[framework] override val taskBlock = Future.successful(()) + def tasks(taskDefs: Array[TaskDef]): Array[Task] = { registeredCount.addAndGet(taskDefs.length) taskDefs.map(newTask) diff --git a/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/SlaveRunner.scala b/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/SlaveRunner.scala index 2f2a0ffc5f..9035573d42 100644 --- a/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/SlaveRunner.scala +++ b/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/SlaveRunner.scala @@ -2,6 +2,8 @@ package sbttest.framework import sbt.testing._ +import scala.concurrent._ + final class SlaveRunner( args: Array[String], remoteArgs: Array[String], @@ -13,21 +15,20 @@ final class SlaveRunner( private[this] var doneCount = 0 /** Whether we have seen a Hello message from the master yet */ - private[this] var seenHello = false + private[this] val seenHello = Promise[Unit]() + + private[framework] override val taskBlock = seenHello.future // Notify master of our existence send("s") def tasks(taskDefs: Array[TaskDef]): Array[Task] = { - ensureSeenHello() - // Notify master of new tasks send("t" + taskDefs.length) taskDefs.map(newTask) } def done(): String = { - ensureSeenHello() send("d" + doneCount) "" // <- ignored } @@ -36,25 +37,7 @@ final class SlaveRunner( def receiveMessage(msg: String): Option[String] = { assert(msg == "Hello") - seenHello = true + seenHello.success(()) None // <- ignored } - - override def serializeTask(task: Task, - serializer: TaskDef => String): String = { - ensureSeenHello() - super.serializeTask(task, serializer) - } - - override def deserializeTask(task: String, - deserializer: String => TaskDef): Task = { - ensureSeenHello() - super.deserializeTask(task, deserializer) - } - - private def ensureSeenHello(): Unit = { - if (!seenHello) - throw new IllegalStateException("Have not seen the master yet") - } - } From 9cd338c0d37093552acde7be7361f82340b9a45f Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Mon, 31 Jul 2017 10:48:01 +0200 Subject: [PATCH 0432/2665] Remove lingering printlns --- .../scala/org/scalajs/testsuite/compiler/RegressionTest.scala | 2 -- 1 file changed, 2 deletions(-) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala index fe81abd4ed..830befc087 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala @@ -651,7 +651,6 @@ class RegressionTest { @Test def tailrec_in_trait_with_self_type_scala_2_12_issue_3058(): Unit = { trait Parent { this: Child => @tailrec final def bar(i: Int, acc: Int): Int = { - println(s"bar($i, $acc)") if (i <= count) bar(i + 1, acc + i) else @@ -669,7 +668,6 @@ class RegressionTest { @Test def tailrec_in_class_with_self_type_scala_2_12_issue_3058(): Unit = { class Parent { this: Child => @tailrec final def bar(i: Int, acc: Int): Int = { - println(s"bar($i, $acc)") if (i <= count) bar(i + 1, acc + i) else From 7cfc2e918490db3fe1bc0ac6d8f0b96aec02e238 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 2 Aug 2017 18:21:46 +0200 Subject: [PATCH 0433/2665] Consider `UndefinedParam` as a "transient" IR node. A transient IR node cannot be serialized nor hashed. This moves the dangling `UndefinedParam` detection earlier in `GenJSCode`, from the time of generating Infos to the time of hashing the members of a `ClassDef`. This is necessary because we will not generate Infos in the compiler anymore. In the future, we should have a generalized notion of transient IR nodes so that `UndefinedParam` is not singled out like this. --- .../org/scalajs/core/compiler/GenJSCode.scala | 49 +++++++++++++------ .../scalajs/core/compiler/GenJSFiles.scala | 14 ------ .../scala/org/scalajs/core/ir/Hashers.scala | 9 +++- .../scala/org/scalajs/core/ir/Infos.scala | 8 --- .../org/scalajs/core/ir/Serializers.scala | 10 ++-- .../main/scala/org/scalajs/core/ir/Tags.scala | 4 +- 6 files changed, 49 insertions(+), 45 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 51c3f6f82b..370e71883a 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -286,22 +286,41 @@ abstract class GenJSCode extends plugins.PluginComponent unexpectedMutatedFields := mutable.Set.empty, generatedSAMWrapperCount := new VarBox(0) ) { - val tree = if (isRawJSType(sym.tpe)) { - assert(!isRawJSFunctionDef(sym), - s"Raw JS function def should have been recorded: $cd") - if (!sym.isTraitOrInterface && isNonNativeJSClass(sym)) - genNonNativeJSClass(cd) - else - genRawJSClassData(cd) - } else if (sym.isTraitOrInterface) { - genInterface(cd) - } else if (sym.isImplClass) { - genImplClass(cd) - } else { - genClass(cd) - } + try { + val tree = if (isRawJSType(sym.tpe)) { + assert(!isRawJSFunctionDef(sym), + s"Raw JS function def should have been recorded: $cd") + if (!sym.isTraitOrInterface && isNonNativeJSClass(sym)) + genNonNativeJSClass(cd) + else + genRawJSClassData(cd) + } else if (sym.isTraitOrInterface) { + genInterface(cd) + } else if (sym.isImplClass) { + genImplClass(cd) + } else { + genClass(cd) + } - generatedClasses += ((sym, None, tree)) + generatedClasses += ((sym, None, tree)) + } catch { + case e: ir.InvalidIRException => + e.tree match { + case ir.Trees.UndefinedParam() => + reporter.error(sym.pos, + "Found a dangling UndefinedParam at " + + s"${e.tree.pos}. This is likely due to a bad " + + "interaction between a macro or a compiler plugin " + + "and the Scala.js compiler plugin. If you hit " + + "this, please let us know.") + + case _ => + reporter.error(sym.pos, + "The Scala.js compiler generated invalid IR for " + + "this class. Please report this as a bug. IR: " + + e.tree) + } + } } } } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSFiles.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSFiles.scala index 8f1101d84e..fe49926a26 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSFiles.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSFiles.scala @@ -29,20 +29,6 @@ trait GenJSFiles extends SubComponent { self: GenJSCode => try { ir.InfoSerializers.serialize(output, Infos.generateClassInfo(tree)) ir.Serializers.serialize(output, tree) - } catch { - case e: ir.InvalidIRException => - e.tree match { - case ir.Trees.UndefinedParam() => - reporter.error(sym.pos, "Found a dangling UndefinedParam at " + - s"${e.tree.pos}. This is likely due to a bad interaction " + - "between a macro or a compiler plugin and the Scala.js " + - "compiler plugin. If you hit this, please let us know.") - - case _ => - reporter.error(sym.pos, "The Scala.js compiler generated " + - "invalid IR for this class. Please report this as a bug. IR: " + - e.tree) - } } finally { output.close() } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala index 7bcf2ed3f8..1c2a877a6b 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala @@ -380,8 +380,13 @@ object Hashers { mixTag(TagUndefined) case UndefinedParam() => - mixTag(TagUndefinedParam) - mixType(tree.tpe) + /* UndefinedParam is a "transient" IR node, and cannot be hashed. + * TODO At the moment, this is quite ad hoc to support dangling + * UndefinedParam detection in the compiler back-end. This should be + * generalized for custom transient nodes. + */ + throw new InvalidIRException(tree, + "Cannot hash a transient IR node of type UndefinedParam") case Null() => mixTag(TagNull) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala index b7f82d4349..99f50be0c8 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala @@ -443,14 +443,6 @@ object Infos { case LoadJSModule(ClassType(cls)) => builder.addAccessedModule(cls) - /* We explicitly catch UndefinedParam here to make sure, we do not - * emit it in the compiler. This does not entirely belong here, as - * it supports GenJSCode, but it is not wrong to throw an exception. - */ - case UndefinedParam() => - throw new InvalidIRException(tree, - "Found UndefinedParam while building infos") - case _ => } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index 72768d8e79..aa30b63f29 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -377,8 +377,13 @@ object Serializers { writeTypeRef(typeRef) case UndefinedParam() => - writeByte(TagUndefinedParam) - writeType(tree.tpe) + /* UndefinedParam is a "transient" IR node, and cannot be serialized. + * TODO At the moment, this is quite ad hoc to support dangling + * UndefinedParam detection in the compiler back-end. This should be + * generalized for custom transient nodes. + */ + throw new InvalidIRException(tree, + "Cannot serialize a transient IR node of type UndefinedParam") case VarRef(ident) => writeByte(TagVarRef) @@ -807,7 +812,6 @@ object Serializers { case TagDoubleLiteral => DoubleLiteral(readDouble()) case TagStringLiteral => StringLiteral(readString()) case TagClassOf => ClassOf(readTypeRef()) - case TagUndefinedParam => UndefinedParam()(readType()) case TagVarRef => VarRef(readIdent())(readType()) case TagThis => This()(readType()) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala index 7784a33873..e9e77f41ed 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala @@ -85,9 +85,7 @@ private[ir] object Tags { final val TagStringLiteral = TagDoubleLiteral + 1 final val TagClassOf = TagStringLiteral + 1 - final val TagUndefinedParam = TagClassOf + 1 - - final val TagVarRef = TagUndefinedParam + 1 + final val TagVarRef = TagClassOf + 1 final val TagThis = TagVarRef + 1 final val TagClosure = TagThis + 1 From bf2c835982198310b2793204e6c6c194e624772d Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 25 Jun 2017 16:47:18 +0200 Subject: [PATCH 0434/2665] Add an RPC layer to the test interface This replaces the ad-hoc message passing with a simple RPC layer and is the first step in implementing #2645. It also mostly removes dependencies on tools.json by replacing the serialization with a binary protocol. The next steps will be to consolidate functionality into a single JS controller so that we do not need to restart the JS VMs so often. Note that this change is potentially dangerous as it exercises functionality in JSEnvs that has never been used before. Notably: - Calling {`send`|`close`} and `receive` concurrently. - Relying on blocking calls to `receive` to throw if another thread calls `close`. Since in the 0.6.x branch most of the enviroments are still in the core repository, the risk is minimal. --- ci/matrix.xml | 4 +- project/BinaryIncompatibilities.scala | 100 ++++++ project/Build.scala | 21 +- project/build.sbt | 1 + .../sbtplugin/HTMLRunnerTemplate.scala | 6 +- .../scalajs/sbttestadapter/ComJSEnvRPC.scala | 67 ++++ .../org/scalajs/sbttestadapter/ComUtils.scala | 101 ------ .../sbttestadapter/EventSerializers.scala | 50 --- .../FingerprintSerializers.scala | 69 ---- .../sbttestadapter/FrameworkInfo.scala | 30 -- .../sbttestadapter/RemoteException.scala | 4 +- .../sbttestadapter/ScalaJSFramework.scala | 4 +- .../sbttestadapter/ScalaJSRunner.scala | 198 +++++------- .../scalajs/sbttestadapter/ScalaJSTask.scala | 131 +++----- .../sbttestadapter/SelectorSerializers.scala | 70 ----- .../sbttestadapter/TaskDefSerializers.scala | 43 --- .../org/scalajs/sbttestadapter/TaskInfo.scala | 33 -- .../org/scalajs/testcommon/Endpoints.scala | 52 +++ .../scalajs/testcommon/ExecuteRequest.scala | 17 + .../scalajs/testcommon/FrameworkInfo.scala | 19 ++ .../scalajs/testcommon/FrameworkMessage.scala | 16 + .../testcommon/JSMasterEndpoints.scala | 16 + .../scalajs/testcommon/JSSlaveEndpoints.scala | 16 + .../testcommon/JVMMasterEndpoints.scala | 7 + .../testcommon/JVMSlaveEndpoints.scala | 24 ++ .../org/scalajs/testcommon/LogElement.scala | 18 ++ .../org/scalajs/testcommon/RPCCore.scala | 235 ++++++++++++++ .../org/scalajs/testcommon/RunnerArgs.scala | 16 + .../org/scalajs/testcommon/Serializer.scala | 297 ++++++++++++++++++ .../org/scalajs/testcommon/TaskInfo.scala | 21 ++ .../org/scalajs/testcommon/RPCCoreTest.scala | 169 ++++++++++ .../scalajs/testcommon/SerializerTest.scala | 19 ++ .../scalajs/testinterface/TestDetector.scala | 8 +- .../testinterface/internal/BridgeBase.scala | 65 ---- .../internal/EventSerializer.scala | 27 -- .../internal/FingerprintSerializer.scala | 52 --- .../testinterface/internal/InfoSender.scala | 19 +- .../testinterface/internal/JSRPC.scala | 20 ++ .../testinterface/internal/Master.scala | 56 ++-- .../internal/SelectorSerializer.scala | 53 ---- .../testinterface/internal/Slave.scala | 132 +++----- .../internal/TaskDefSerializer.scala | 29 -- .../internal/TaskInfoBuilder.scala | 24 ++ .../internal/ThrowableSerializer.scala | 31 -- 44 files changed, 1375 insertions(+), 1015 deletions(-) create mode 100644 test-adapter/src/main/scala/org/scalajs/sbttestadapter/ComJSEnvRPC.scala delete mode 100644 test-adapter/src/main/scala/org/scalajs/sbttestadapter/ComUtils.scala delete mode 100644 test-adapter/src/main/scala/org/scalajs/sbttestadapter/EventSerializers.scala delete mode 100644 test-adapter/src/main/scala/org/scalajs/sbttestadapter/FingerprintSerializers.scala delete mode 100644 test-adapter/src/main/scala/org/scalajs/sbttestadapter/FrameworkInfo.scala delete mode 100644 test-adapter/src/main/scala/org/scalajs/sbttestadapter/SelectorSerializers.scala delete mode 100644 test-adapter/src/main/scala/org/scalajs/sbttestadapter/TaskDefSerializers.scala delete mode 100644 test-adapter/src/main/scala/org/scalajs/sbttestadapter/TaskInfo.scala create mode 100644 test-common/src/main/scala/org/scalajs/testcommon/Endpoints.scala create mode 100644 test-common/src/main/scala/org/scalajs/testcommon/ExecuteRequest.scala create mode 100644 test-common/src/main/scala/org/scalajs/testcommon/FrameworkInfo.scala create mode 100644 test-common/src/main/scala/org/scalajs/testcommon/FrameworkMessage.scala create mode 100644 test-common/src/main/scala/org/scalajs/testcommon/JSMasterEndpoints.scala create mode 100644 test-common/src/main/scala/org/scalajs/testcommon/JSSlaveEndpoints.scala create mode 100644 test-common/src/main/scala/org/scalajs/testcommon/JVMMasterEndpoints.scala create mode 100644 test-common/src/main/scala/org/scalajs/testcommon/JVMSlaveEndpoints.scala create mode 100644 test-common/src/main/scala/org/scalajs/testcommon/LogElement.scala create mode 100644 test-common/src/main/scala/org/scalajs/testcommon/RPCCore.scala create mode 100644 test-common/src/main/scala/org/scalajs/testcommon/RunnerArgs.scala create mode 100644 test-common/src/main/scala/org/scalajs/testcommon/Serializer.scala create mode 100644 test-common/src/main/scala/org/scalajs/testcommon/TaskInfo.scala create mode 100644 test-common/src/test/scala/org/scalajs/testcommon/RPCCoreTest.scala create mode 100644 test-common/src/test/scala/org/scalajs/testcommon/SerializerTest.scala delete mode 100644 test-interface/src/main/scala/org/scalajs/testinterface/internal/BridgeBase.scala delete mode 100644 test-interface/src/main/scala/org/scalajs/testinterface/internal/EventSerializer.scala delete mode 100644 test-interface/src/main/scala/org/scalajs/testinterface/internal/FingerprintSerializer.scala create mode 100644 test-interface/src/main/scala/org/scalajs/testinterface/internal/JSRPC.scala delete mode 100644 test-interface/src/main/scala/org/scalajs/testinterface/internal/SelectorSerializer.scala delete mode 100644 test-interface/src/main/scala/org/scalajs/testinterface/internal/TaskDefSerializer.scala create mode 100644 test-interface/src/main/scala/org/scalajs/testinterface/internal/TaskInfoBuilder.scala delete mode 100644 test-interface/src/main/scala/org/scalajs/testinterface/internal/ThrowableSerializer.scala diff --git a/ci/matrix.xml b/ci/matrix.xml index 111bb44830..43c09d99cb 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -214,7 +214,7 @@ + } + } + } catch { + case _: ComJSEnv.ComClosedException => + case _: InterruptedException => + case _: Exception if closed => + // Some JSEnvs might throw something else if they got closed. + // We are graceful in the 0.6.x branch. + } + } + } + + receiverThread.start() + + override protected def send(msg: String): Unit = synchronized { + if (!closed) + runner.send(msg) + } + + override def close(): Unit = synchronized { + closed = true + + super.close() + + // Close the com first so the receiver thread terminates. + runner.close() + + receiverThread.interrupt() + receiverThread.join() + } +} diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ComUtils.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ComUtils.scala deleted file mode 100644 index be6147fac0..0000000000 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ComUtils.scala +++ /dev/null @@ -1,101 +0,0 @@ -package org.scalajs.testadapter - -import org.scalajs.core.tools.json._ -import org.scalajs.jsenv._ - -import scala.annotation.tailrec - -import scala.concurrent.duration._ - -private[testadapter] object ComUtils { - - type Handler[+T] = PartialFunction[(String, String), T] - type LoopHandler[+T] = Handler[Option[T]] - - def receiveLoop[T](com: ComJSRunner)(handler: LoopHandler[T]): T = - receiveLoop(com, Duration.Inf)(handler) - - @tailrec - def receiveLoop[T](com: ComJSRunner, timeout: Duration)( - handler: LoopHandler[T]): T = { - receiveResponse(com, timeout)(handler) match { - case Some(v) => v - case None => receiveLoop(com, timeout)(handler) - } - } - - @tailrec - def receiveLoop[T](com: ComJSRunner, deadline: Deadline)( - handler: LoopHandler[T]): T = { - receiveResponse(com, deadline.timeLeft)(handler) match { - case Some(v) => v - case None => receiveLoop(com, deadline)(handler) - } - } - - def receiveResponse[T](com: ComJSRunner)(handler: Handler[T]): T = - receiveResponse(com, Duration.Inf)(handler) - - def receiveResponse[T](com: ComJSRunner, timeout: Duration)( - handler: Handler[T]): T = { - val resp = { - try com.receive(timeout) - catch { - case t: ComJSEnv.ComClosedException => - // Check if runner failed. If it did, throw that exception instead - if (!com.isRunning()) - com.await() // Will throw if runner failed - - throw t - } - } - - def badResponse(cause: Throwable = null) = { - throw new AssertionError( - s"JS test interface sent bad reply: $resp", cause) - } - - val pos = resp.indexOf(':') - - if (pos == -1) - badResponse() - - val status = resp.substring(0, pos) - val data = resp.substring(pos + 1) - - def throwable = { - try fromJSON[RemoteException](readJSON(data)) - catch { - case t: Throwable => badResponse(t) - } - } - - def onFail = status match { - case "fail" => - throw throwable - case "bad" => - throw new AssertionError( - s"JS test interface rejected command.", throwable) - case _ => - badResponse() - } - - val result = { - try handler.lift((status, data)) - catch { - case t: Throwable => badResponse(t) - } - } - - result.getOrElse(onFail) - } - - val doneHandler: LoopHandler[Unit] = { - case ("ok", "") => Some(()) - } - - val okHandler: Handler[Unit] = { - case ("ok", "") => - } - -} diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/EventSerializers.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/EventSerializers.scala deleted file mode 100644 index 4457fdeec8..0000000000 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/EventSerializers.scala +++ /dev/null @@ -1,50 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.testadapter - -import sbt.testing._ - -import org.scalajs.core.tools.json._ - -import FingerprintSerializers._ -import SelectorSerializers._ - -import language.implicitConversions - -private[testadapter] object EventSerializers { - - implicit object EventDeserializer extends JSONDeserializer[Event] { - private implicit def optT2optT(x: Option[Throwable]): OptionalThrowable = - x.fold(new OptionalThrowable)(t => new OptionalThrowable(t)) - - def deserialize(x: JSON): Event = { - val obj = new JSONObjExtractor(x) - - new DeserializedEvent( - obj.fld[String]("fullyQualifiedName"), - obj.fld[Fingerprint]("fingerprint"), - obj.fld[Selector]("selector"), - Status.valueOf(obj.fld[String]("status")), - obj.opt[RemoteException]("throwable"), - (obj.fld[Int]("durationMS").toLong << 32) | - (obj.fld[Int]("durationLS").toLong & 0xffffffffL)) - } - } - - final class DeserializedEvent( - val fullyQualifiedName: String, - val fingerprint: Fingerprint, - val selector: Selector, - val status: Status, - val throwable: OptionalThrowable, - val duration: Long - ) extends Event - -} diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/FingerprintSerializers.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/FingerprintSerializers.scala deleted file mode 100644 index 9c322745f0..0000000000 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/FingerprintSerializers.scala +++ /dev/null @@ -1,69 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.testadapter - -import sbt.testing._ - -import org.scalajs.core.tools.json._ - -private[testadapter] object FingerprintSerializers { - - implicit object FingerprintSerializer extends JSONSerializer[Fingerprint] { - def serialize(fp: Fingerprint): JSON = { - val bld = new JSONObjBuilder() - fp match { - case fp: AnnotatedFingerprint => bld - .fld("fpType", "AnnotatedFingerprint") - .fld("isModule", fp.isModule) - .fld("annotationName", fp.annotationName) - case fp: SubclassFingerprint => bld - .fld("fpType", "SubclassFingerprint") - .fld("isModule", fp.isModule) - .fld("superclassName", fp.superclassName) - .fld("requireNoArgConstructor", fp.requireNoArgConstructor) - case _ => - throw new IllegalArgumentException( - s"Unknown Fingerprint type: ${fp.getClass}") - } - bld.toJSON - } - } - - implicit object FingerprintDeserializer extends JSONDeserializer[Fingerprint] { - def deserialize(x: JSON): Fingerprint = { - val obj = new JSONObjExtractor(x) - obj.fld[String]("fpType") match { - case "AnnotatedFingerprint" => - new DeserializedAnnotatedFingerprint( - obj.fld[Boolean]("isModule"), - obj.fld[String]("annotationName")) - case "SubclassFingerprint" => - new DeserializedSubclassFingerprint( - obj.fld[Boolean]("isModule"), - obj.fld[String]("superclassName"), - obj.fld[Boolean]("requireNoArgConstructor")) - case tpe => - throw new IllegalArgumentException(s"Unknown Fingerprint type: $tpe") - } - } - } - - final class DeserializedAnnotatedFingerprint( - val isModule: Boolean, - val annotationName: String - ) extends AnnotatedFingerprint - - final class DeserializedSubclassFingerprint( - val isModule: Boolean, - val superclassName: String, - val requireNoArgConstructor: Boolean - ) extends SubclassFingerprint - -} diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/FrameworkInfo.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/FrameworkInfo.scala deleted file mode 100644 index ef06bb1154..0000000000 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/FrameworkInfo.scala +++ /dev/null @@ -1,30 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.testadapter - -import sbt.testing._ - -import org.scalajs.core.tools.json._ - -import FingerprintSerializers._ - -private[testadapter] final class FrameworkInfo private ( - val name: String, val fingerprints: List[Fingerprint]) - -private[testadapter] object FrameworkInfo { - implicit object Deserializer extends JSONDeserializer[FrameworkInfo] { - def deserialize(x: JSON): FrameworkInfo = { - val obj = new JSONObjExtractor(x) - new FrameworkInfo( - obj.fld[String] ("name"), - obj.fld[List[Fingerprint]]("fingerprints")) - } - } -} diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/RemoteException.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/RemoteException.scala index 3e170310d6..37378d8ff3 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/RemoteException.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/RemoteException.scala @@ -13,13 +13,13 @@ import sbt.testing._ import org.scalajs.core.tools.json._ -import FingerprintSerializers._ - +@deprecated("Unused. Is going to be removed.", "0.6.20.") final class RemoteException private (msg: String, _toString: String, cause: Throwable, val originalClass: String) extends Exception(msg, cause) { override def toString(): String = _toString } +@deprecated("Unused. Is going to be removed.", "0.6.20.") object RemoteException { implicit object StackTraceDeserializer extends JSONDeserializer[StackTraceElement] { def deserialize(x: JSON): StackTraceElement = { diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala index afc83db285..aac2a07c82 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala @@ -17,6 +17,7 @@ import org.scalajs.core.tools.logging._ import org.scalajs.core.tools.linker.backend.ModuleKind import org.scalajs.jsenv._ +import org.scalajs.testcommon._ import sbt.testing.{Logger => _, _} @@ -62,8 +63,7 @@ final class ScalaJSFramework( runner.start(logger, jsConsole) try { - val msg = readJSON(runner.receive()) - fromJSON[FrameworkInfo](msg) + Serializer.deserialize[FrameworkInfo](runner.receive()) } finally { runner.close() runner.await(VMTermTimeout) diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala index b49d7f8501..2b2c6bf0ff 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala @@ -11,33 +11,34 @@ package org.scalajs.testadapter import org.scalajs.core.tools.io._ import org.scalajs.core.tools.json._ - import org.scalajs.jsenv._ +import org.scalajs.testcommon._ import scala.collection.concurrent.TrieMap +import scala.concurrent.{Await, Future} import scala.concurrent.duration._ +import scala.concurrent.ExecutionContext.Implicits.global + import scala.util.{Try, Failure, Success} import java.util.concurrent.atomic.AtomicInteger import sbt.testing._ -import TaskDefSerializers._ -import ComUtils.LoopHandler - final class ScalaJSRunner private[testadapter] ( framework: ScalaJSFramework, val args: Array[String], val remoteArgs: Array[String] ) extends Runner { + import ScalaJSRunner._ // State and simple vals - private[this] var master: ComJSRunner = null + private[this] var master: ComJSEnvRPC = null /** Map of ThreadId -> Slave */ - private[this] val slaves = TrieMap.empty[Long, ComJSRunner] + private[this] val slaves = TrieMap.empty[Long, ComJSEnvRPC] /** An object used as lock for the loggers. Ensures output does not get * interleaved. @@ -53,126 +54,72 @@ final class ScalaJSRunner private[testadapter] ( def tasks(taskDefs: Array[TaskDef]): Array[Task] = synchronized { ensureNotDone() - val outData = taskDefs.toList.toJSON - master.send("tasks:" + jsonToString(outData)) - - val taskInfos = ComUtils.receiveResponse(master) { - case ("ok", data) => fromJSON[List[TaskInfo]](readJSON(data)) - } + val taskInfos = Await.result( + master.call(JSMasterEndpoints.tasks)(taskDefs.toList), 1.minutes) - taskInfos.map(ScalaJSTask.fromInfo(this, _)).toArray + taskInfos.map(new ScalaJSTask(this, _)).toArray } def done(): String = synchronized { ensureNotDone() - /* Whatever happens in here, we must close and eventually terminate all - * VMs. So we capture all exceptions in Try's, and we'll rethrow one of - * them (if any) at the end. - */ - - // First we run the stopping sequence of the slaves - val slavesDeadline = VMTermTimeout.fromNow - val slavesClosing = stopSlaves(slavesDeadline) - - /* Once all slaves are closing, we can schedule termination of the master. - * We need a fresh deadline for the master, since we can only start its - * scheduling when the slaves are closing. - * If we used the same deadline, and a slave timed out during its stopping - * sequence, the master would have 0 ms to stop, which is not fair. - */ - val masterDeadline = VMTermTimeout.fromNow - val summaryTry = Try { - master.send("runnerDone") - val summary = ComUtils.receiveResponse(master, masterDeadline.timeLeft) { - case ("ok", summary) => summary - } - master.close() - summary - } + val slaves = this.slaves.values.toList // .toList to make it strict. - // Now we wait for everyone to be completely stopped - val slavesStopped = - slaves.values.toList.map(s => Try(s.awaitOrStop(slavesDeadline.timeLeft))) - val masterStopped = Try(master.awaitOrStop(masterDeadline.timeLeft)) + def waitAndClose[T](v: Future[T], r: ComJSEnvRPC): Future[Try[T]] = + v.liftToTry.map { x => r.close(); x }.liftToTry.map(_.flatten) - // Cleanup - master = null - slaves.clear() + def stopSlave(slave: ComJSEnvRPC): Future[Try[Unit]] = + waitAndClose(slave.call(JSSlaveEndpoints.stopSlave)(()), slave) - framework.runDone() + def stopMaster(): Future[Try[String]] = + waitAndClose(master.call(JSMasterEndpoints.runnerDone)(()), master) - // At this point, rethrow any exception we captured on the way with Try's - slavesClosing.get - slavesStopped.foreach(_.get) - masterStopped.get + val futureSummary = for { + // First we run the stopping sequence of the slaves + slaveTries <- Future.sequence(slaves.map(stopSlave)) - // And finally, if all went well, return the summary - summaryTry.get - } + // Once all slaves are closing, we can schedule termination of the master. + summaryTry <- stopMaster() - // Runner Messaging - - /** A handler for messages sent from the slave to the master */ - private[testadapter] def msgHandler( - slave: ComJSRunner): LoopHandler[Nothing] = { - case ("msg", msg) => - val optReply = synchronized { - master.send(s"msg:$msg") - ComUtils.receiveResponse(master) { - case ("ok", msg) => - if (msg.startsWith(":s:")) Some(msg.stripPrefix(":s:")) - else None - } - } - - for (reply <- optReply) - slave.send(s"msg:$reply") - - None - } + // Now wait for termination of the VMs + doneTries <- Future.sequence(master.runner.future.liftToTry :: + slaves.map(_.runner.future.liftToTry)) + } yield { + // Now that everything is done, we can throw any exception. + (slaveTries ::: summaryTry :: doneTries).foreach(_.get) - // Slave Management + // Get the summary. + summaryTry.get + } - private[testadapter] def getSlave(): ComJSRunner = { - val threadId = Thread.currentThread().getId() + try { + /* We need to double the VMTermTimeout since we wait for the slaves and + * the master in sequence. + */ + Await.result(futureSummary, VMTermTimeout * 2) + } finally { + // Do the best we can to stop the VMs. + master.runner.stop() + slaves.foreach(_.runner.stop()) - // Note that this is thread safe, since each thread can only operate on - // the value associated to its thread id. - if (!slaves.contains(threadId)) { - val slave = createSlave() - slaves.put(threadId, slave) - slave - } else { - slaves(threadId) + master = null + this.slaves.clear() + + framework.runDone() } } - /** Starts the stopping sequence of all slaves. - * The returned future will be completed when all slaves are closing. - */ - private def stopSlaves(deadline: Deadline): Try[Unit] = { - val slaves = this.slaves.values.toList // .toList to make it strict - - // First launch the stopping sequence on all slaves - val stopMessagesSent = for (slave <- slaves) yield Try { - slave.send("stopSlave") - } + // Slave Management - // Then process all their messages and close them - val slavesClosed = for (slave <- slaves) yield Try { - ComUtils.receiveLoop(slave, deadline)( - msgHandler(slave) orElse ComUtils.doneHandler) - slave.close() - } + private[testadapter] def getSlave(): ComJSEnvRPC = { + val threadId = Thread.currentThread().getId() - // Return the first failed of all these Try's - (stopMessagesSent ++ slavesClosed) collectFirst { - case failure: Failure[Unit] => failure - } getOrElse Success(()) + // Note that this is thread safe, since each thread can only operate on + // the value associated to its thread id. + slaves.getOrElse(threadId, createSlave(threadId)) } - private def createSlave(): ComJSRunner = { + private def createSlave(threadId: Long): ComJSEnvRPC = { // We don't want to create new slaves when we're closing/closed ensureNotDone() @@ -180,11 +127,19 @@ final class ScalaJSRunner private[testadapter] ( val slave = framework.libEnv.comRunner(slaveLauncher) slave.start(framework.logger, framework.jsConsole) + // Setup RPC + val com = new ComJSEnvRPC(slave) + com.attach(JVMSlaveEndpoints.msg) { msg => + master.send(JSMasterEndpoints.msg)(new FrameworkMessage(threadId, msg)) + } + + // Put the slave into the map, so replies from the master can be routed. + slaves.put(threadId, com) + // Create a runner on the slave - slave.send("newRunner") - ComUtils.receiveLoop(slave)(msgHandler(slave) orElse ComUtils.doneHandler) + Await.result(com.call(JSSlaveEndpoints.newRunner)(()), 1.minutes) - slave + com } // Helpers @@ -196,7 +151,7 @@ final class ScalaJSRunner private[testadapter] ( val remoteArgsJS = jsonToString(remoteArgs.toList.toJSON) val code = s""" new ${prefix}org.scalajs.testinterface.internal.Slave($frameworkJS, - $argsJS, $remoteArgsJS).init(); + $argsJS, $remoteArgsJS); """ new MemVirtualJSFile("testSlave.js").withContent(code) } @@ -205,7 +160,7 @@ final class ScalaJSRunner private[testadapter] ( val prefix = framework.optionalExportsNamespacePrefix val name = jsonToString(framework.frameworkName.toJSON) val code = s""" - new ${prefix}org.scalajs.testinterface.internal.Master($name).init(); + new ${prefix}org.scalajs.testinterface.internal.Master($name); """ new MemVirtualJSFile(s"testMaster.js").withContent(code) } @@ -218,20 +173,23 @@ final class ScalaJSRunner private[testadapter] ( private def createRemoteRunner(): Unit = { assert(master == null) - master = framework.libEnv.comRunner(masterLauncher) - master.start(framework.logger, framework.jsConsole) + val runner = framework.libEnv.comRunner(masterLauncher) + runner.start(framework.logger, framework.jsConsole) - val data = { - val bld = new JSONObjBuilder - bld.fld("args", args.toList) - bld.fld("remoteArgs", remoteArgs.toList) - bld.toJSON - } + master = new ComJSEnvRPC(runner) - master.send("newRunner:" + jsonToString(data)) - ComUtils.receiveResponse(master) { - case ("ok", "") => + master.attach(JVMMasterEndpoints.msg) { msg => + slaves(msg.slaveId).send(JSSlaveEndpoints.msg)(msg.msg) } + + val req = new RunnerArgs(args.toList, remoteArgs.toList) + Await.result(master.call(JSMasterEndpoints.newRunner)(req), 1.minute) } +} +private object ScalaJSRunner { + implicit class RichFuture[T](val __self: Future[T]) extends AnyVal { + def liftToTry: Future[Try[T]] = + __self.map(Success(_)).recover(PartialFunction(Failure(_))) + } } diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSTask.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSTask.scala index 08e5e046b8..e8bb1fc111 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSTask.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSTask.scala @@ -9,42 +9,27 @@ package org.scalajs.testadapter -import org.scalajs.core.tools.json._ - import org.scalajs.jsenv._ +import org.scalajs.testcommon._ +import scala.concurrent.Await +import scala.concurrent.duration.Duration import scala.collection.mutable import scala.util.Try import sbt.testing._ -import TaskDefSerializers._ -import EventSerializers._ -import ComUtils.LoopHandler -import ScalaJSTask.LogElement - -final class ScalaJSTask private ( +final class ScalaJSTask private[testadapter] ( runner: ScalaJSRunner, - val taskDef: TaskDef, - val tags: Array[String], - serializedTask: String + taskInfo: TaskInfo ) extends Task { + def taskDef: TaskDef = taskInfo.taskDef + def tags: Array[String] = taskInfo.tags.toArray + def execute(handler: EventHandler, loggers: Array[Logger]): Array[Task] = { val slave = runner.getSlave() - // Prepare data to send to Slave VM - val colorSupport = loggers.map(_.ansiCodesSupported).toList - val data = { - val bld = new JSONObjBuilder - bld.fld("serializedTask", serializedTask) - bld.fld("loggerColorSupport", colorSupport) - bld.toJSON - } - - // Send command to VM - slave.send("execute:" + jsonToString(data)) - // Prepare result handler // TODO rip this out once we know it doesn't garble the logs. val shouldBufferLog = { @@ -52,75 +37,47 @@ final class ScalaJSTask private ( Try(System.getProperty(propName, "false").toBoolean).getOrElse(false) } - val logBuffer = mutable.Buffer.empty[LogElement[_]] + val logBuffer = mutable.Buffer.empty[ScalaJSTask.LogElement[_]] - val logger: LogElement[_] => Unit = - if (shouldBufferLog) logBuffer += _ - else _.call(loggers) - - val doneHandler: LoopHandler[List[TaskInfo]] = { - case ("ok", msg) => Some(fromJSON[List[TaskInfo]](readJSON(msg))) - } - - val handlerChain = ( - eventHandler(handler) orElse - loggerHandler(logger) orElse - runner.msgHandler(slave) orElse - doneHandler) - - // Wait for result - val taskInfos = ComUtils.receiveLoop(slave)(handlerChain) - - // Flush log buffer - if (shouldBufferLog) { - runner.loggerLock.synchronized { - logBuffer.foreach(_.call(loggers)) + def log[T](level: Logger => (T => Unit))(log: LogElement[T]): Unit = { + if (shouldBufferLog) { + logBuffer += new ScalaJSTask.LogElement(log.index, level, log.x) + } else { + level(loggers(log.index))(log.x) } } - taskInfos.map(ScalaJSTask.fromInfo(runner, _)).toArray - } - - private def eventHandler(handler: EventHandler): LoopHandler[Nothing] = { - case ("event", data) => - val event = fromJSON[Event](readJSON(data)) - handler.handle(event) - None - } - - private def loggerHandler( - logger: LogElement[_] => Unit): LoopHandler[Nothing] = { - - def processData(data: String) = { - val pos = data.indexOf(':') - assert(pos != -1, "Log command needs logger index") - val index = data.substring(0, pos).toInt - val innerData = data.substring(pos + 1) - - (index, innerData) - } - - def log(level: Logger => (String => Unit), data: String) = { - val (index, msg) = processData(data) - logger(new LogElement(index, level, msg)) - None - } + slave.attach(JVMSlaveEndpoints.event)(handler.handle _) + slave.attach(JVMSlaveEndpoints.logError)(log(_.error)) + slave.attach(JVMSlaveEndpoints.logWarn)(log(_.warn)) + slave.attach(JVMSlaveEndpoints.logInfo)(log(_.info)) + slave.attach(JVMSlaveEndpoints.logDebug)(log(_.debug)) + slave.attach(JVMSlaveEndpoints.logTrace)(log(_.trace)) + + try { + // Execute task. No (!) timeout. + val req = + new ExecuteRequest(taskInfo, loggers.map(_.ansiCodesSupported).toList) + val taskInfos = Await.result( + slave.call(JSSlaveEndpoints.execute)(req), Duration.Inf) + + // Flush log buffer + if (shouldBufferLog) { + runner.loggerLock.synchronized { + logBuffer.foreach(_.call(loggers)) + } + } - val pf: LoopHandler[Nothing] = { - case ("error", data) => log(_.error, data) - case ("warn", data) => log(_.warn, data) - case ("info", data) => log(_.info, data) - case ("debug", data) => log(_.debug, data) - case ("trace", data) => - val (index, innerData) = processData(data) - val throwable = fromJSON[RemoteException](readJSON(innerData)) - logger(new LogElement(index, _.trace, throwable)) - None + taskInfos.map(new ScalaJSTask(runner, _)).toArray + } finally { + slave.detach(JVMSlaveEndpoints.event) + slave.detach(JVMSlaveEndpoints.logError) + slave.detach(JVMSlaveEndpoints.logWarn) + slave.detach(JVMSlaveEndpoints.logInfo) + slave.detach(JVMSlaveEndpoints.logDebug) + slave.detach(JVMSlaveEndpoints.logTrace) } - - pf } - } object ScalaJSTask { @@ -128,8 +85,4 @@ object ScalaJSTask { log: Logger => (T => Unit), data: T) { def call(arr: Array[Logger]): Unit = log(arr(index))(data) } - - private[testadapter] def fromInfo(runner: ScalaJSRunner, - info: TaskInfo): ScalaJSTask = - new ScalaJSTask(runner, info.taskDef, info.tags, info.serializedTask) } diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/SelectorSerializers.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/SelectorSerializers.scala deleted file mode 100644 index 2508b379c6..0000000000 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/SelectorSerializers.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.testadapter - -import sbt.testing._ - -import org.scalajs.core.tools.json._ - -private[testadapter] object SelectorSerializers { - - implicit object SelectorSerializer extends JSONSerializer[Selector] { - def serialize(sel: Selector): JSON = { - val bld = new JSONObjBuilder() - sel match { - case sel: SuiteSelector => bld - .fld("selType", "SuiteSelector") - case sel: TestSelector => bld - .fld("selType", "TestSelector") - .fld("testName", sel.testName) - case sel: NestedSuiteSelector => bld - .fld("selType", "NestedSuiteSelector") - .fld("suiteId", sel.suiteId) - case sel: NestedTestSelector => bld - .fld("selType", "NestedTestSelector") - .fld("suiteId", sel.suiteId) - .fld("testName", sel.testName) - case sel: TestWildcardSelector => bld - .fld("selType", "TestWildcardSelector") - .fld("testWildcard", sel.testWildcard) - case _ => - throw new IllegalArgumentException( - s"Unknown Selector type: ${sel.getClass}") - } - bld.toJSON - } - } - - implicit object SelectorDeserializer extends JSONDeserializer[Selector] { - def deserialize(x: JSON): Selector = { - val obj = new JSONObjExtractor(x) - obj.fld[String]("selType") match { - case "SuiteSelector" => - new SuiteSelector() - case "TestSelector" => - new TestSelector( - obj.fld[String]("testName")) - case "NestedSuiteSelector" => - new NestedSuiteSelector( - obj.fld[String]("suiteId")) - case "NestedTestSelector" => - new NestedTestSelector( - obj.fld[String]("suiteId"), - obj.fld[String]("testName")) - case "TestWildcardSelector" => - new TestWildcardSelector( - obj.fld[String]("testWildcard")) - case tpe => - throw new IllegalArgumentException(s"Unknown Selector type: $tpe") - } - } - } - -} diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TaskDefSerializers.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TaskDefSerializers.scala deleted file mode 100644 index 9385080e59..0000000000 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TaskDefSerializers.scala +++ /dev/null @@ -1,43 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.testadapter - -import sbt.testing._ - -import org.scalajs.core.tools.json._ - -import FingerprintSerializers._ -import SelectorSerializers._ - -private[scalajs] object TaskDefSerializers { - - implicit object TaskDefSerializer extends JSONSerializer[TaskDef] { - def serialize(td: TaskDef): JSON = { - new JSONObjBuilder() - .fld("fullyQualifiedName", td.fullyQualifiedName) - .fld("fingerprint", td.fingerprint) - .fld("explicitlySpecified", td.explicitlySpecified) - .fld("selectors", td.selectors.toList) - .toJSON - } - } - - implicit object TaskDefDeserializer extends JSONDeserializer[TaskDef] { - def deserialize(x: JSON): TaskDef = { - val obj = new JSONObjExtractor(x) - new TaskDef( - obj.fld[String]("fullyQualifiedName"), - obj.fld[Fingerprint]("fingerprint"), - obj.fld[Boolean]("explicitlySpecified"), - obj.fld[List[Selector]]("selectors").toArray) - } - } - -} diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TaskInfo.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TaskInfo.scala deleted file mode 100644 index c74b9cc468..0000000000 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TaskInfo.scala +++ /dev/null @@ -1,33 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.testadapter - -import sbt.testing._ - -import org.scalajs.core.tools.json._ - -import TaskDefSerializers._ - -private[testadapter] final class TaskInfo private ( - val serializedTask: String, - val taskDef: TaskDef, - val tags: Array[String]) - -private[testadapter] object TaskInfo { - implicit object Deserializer extends JSONDeserializer[TaskInfo] { - def deserialize(x: JSON): TaskInfo = { - val obj = new JSONObjExtractor(x) - new TaskInfo( - obj.fld[String] ("serializedTask"), - obj.fld[TaskDef] ("taskDef"), - obj.fld[List[String]]("tags").toArray) - } - } -} diff --git a/test-common/src/main/scala/org/scalajs/testcommon/Endpoints.scala b/test-common/src/main/scala/org/scalajs/testcommon/Endpoints.scala new file mode 100644 index 0000000000..c6cacebda8 --- /dev/null +++ b/test-common/src/main/scala/org/scalajs/testcommon/Endpoints.scala @@ -0,0 +1,52 @@ +package org.scalajs.testcommon + +private[scalajs] sealed trait Endpoint { + val opCode: RPCCore.OpCode +} + +private[scalajs] sealed trait MsgEndpoint extends Endpoint { + type Msg + + implicit val msgSerializer: Serializer[Msg] +} + +private[scalajs] object MsgEndpoint { + /** Helper type for readability */ + type EP[M] = MsgEndpoint { type Msg = M } + + def apply[M](opc: RPCCore.OpCode)(implicit ms: Serializer[M]): EP[M] = { + require(!RPCCore.isReservedOpCode(opc), s"Reserved op code: $opc") + + new MsgEndpoint { + type Msg = M + val opCode: RPCCore.OpCode = opc + implicit val msgSerializer: Serializer[Msg] = ms + } + } +} + +private[scalajs] sealed trait RPCEndpoint extends Endpoint { + type Req + type Resp + + implicit val reqSerializer: Serializer[Req] + implicit val respSerializer: Serializer[Resp] +} + +private[scalajs] object RPCEndpoint { + /** Helper type for readability */ + type EP[Rq, Rp] = RPCEndpoint { type Req = Rq; type Resp = Rp } + + def apply[Rq, Rp](opc: RPCCore.OpCode)(implicit rqs: Serializer[Rq], + rps: Serializer[Rp]): EP[Rq, Rp] = { + require(!RPCCore.isReservedOpCode(opc), s"Reserved op code: $opc") + + new RPCEndpoint { + type Req = Rq + type Resp = Rp + val opCode: RPCCore.OpCode = opc + implicit val reqSerializer: Serializer[Req] = rqs + implicit val respSerializer: Serializer[Resp] = rps + } + } +} diff --git a/test-common/src/main/scala/org/scalajs/testcommon/ExecuteRequest.scala b/test-common/src/main/scala/org/scalajs/testcommon/ExecuteRequest.scala new file mode 100644 index 0000000000..c7cf653deb --- /dev/null +++ b/test-common/src/main/scala/org/scalajs/testcommon/ExecuteRequest.scala @@ -0,0 +1,17 @@ +package org.scalajs.testcommon + +private[scalajs] final class ExecuteRequest( + val taskInfo: TaskInfo, val loggerColorSupport: List[Boolean]) + +private[scalajs] object ExecuteRequest { + implicit object ExecuteRequestSerializer extends Serializer[ExecuteRequest] { + def serialize(x: ExecuteRequest, out: Serializer.SerializeState): Unit = { + out.write(x.taskInfo) + out.write(x.loggerColorSupport) + } + + def deserialize(in: Serializer.DeserializeState): ExecuteRequest = { + new ExecuteRequest(in.read[TaskInfo](), in.read[List[Boolean]]()) + } + } +} diff --git a/test-common/src/main/scala/org/scalajs/testcommon/FrameworkInfo.scala b/test-common/src/main/scala/org/scalajs/testcommon/FrameworkInfo.scala new file mode 100644 index 0000000000..3a3775110d --- /dev/null +++ b/test-common/src/main/scala/org/scalajs/testcommon/FrameworkInfo.scala @@ -0,0 +1,19 @@ +package org.scalajs.testcommon + +import sbt.testing._ + +private[scalajs] final class FrameworkInfo( + val name: String, val fingerprints: List[Fingerprint]) + +private[scalajs] object FrameworkInfo { + implicit object FrameworkInfoSerializer extends Serializer[FrameworkInfo] { + def serialize(x: FrameworkInfo, out: Serializer.SerializeState): Unit = { + out.write(x.name) + out.write(x.fingerprints) + } + + def deserialize(in: Serializer.DeserializeState): FrameworkInfo = { + new FrameworkInfo(in.read[String](), in.read[List[Fingerprint]]()) + } + } +} diff --git a/test-common/src/main/scala/org/scalajs/testcommon/FrameworkMessage.scala b/test-common/src/main/scala/org/scalajs/testcommon/FrameworkMessage.scala new file mode 100644 index 0000000000..5b8a5d27fc --- /dev/null +++ b/test-common/src/main/scala/org/scalajs/testcommon/FrameworkMessage.scala @@ -0,0 +1,16 @@ +package org.scalajs.testcommon + +private[scalajs] final class FrameworkMessage(val slaveId: Long, val msg: String) + +private[scalajs] object FrameworkMessage { + implicit object FrameworkMessageSerializer extends Serializer[FrameworkMessage] { + def serialize(x: FrameworkMessage, out: Serializer.SerializeState): Unit = { + out.write(x.slaveId) + out.write(x.msg) + } + + def deserialize(in: Serializer.DeserializeState): FrameworkMessage = { + new FrameworkMessage(in.read[Long](), in.read[String]()) + } + } +} diff --git a/test-common/src/main/scala/org/scalajs/testcommon/JSMasterEndpoints.scala b/test-common/src/main/scala/org/scalajs/testcommon/JSMasterEndpoints.scala new file mode 100644 index 0000000000..1d168702f8 --- /dev/null +++ b/test-common/src/main/scala/org/scalajs/testcommon/JSMasterEndpoints.scala @@ -0,0 +1,16 @@ +package org.scalajs.testcommon + +import sbt.testing._ + +private[scalajs] object JSMasterEndpoints { + val newRunner: RPCEndpoint.EP[RunnerArgs, Unit] = + RPCEndpoint[RunnerArgs, Unit](2) + + val runnerDone: RPCEndpoint.EP[Unit, String] = + RPCEndpoint[Unit, String](3) + + val tasks: RPCEndpoint.EP[List[TaskDef], List[TaskInfo]] = + RPCEndpoint[List[TaskDef], List[TaskInfo]](4) + + val msg: MsgEndpoint.EP[FrameworkMessage] = MsgEndpoint[FrameworkMessage](5) +} diff --git a/test-common/src/main/scala/org/scalajs/testcommon/JSSlaveEndpoints.scala b/test-common/src/main/scala/org/scalajs/testcommon/JSSlaveEndpoints.scala new file mode 100644 index 0000000000..774c32e59a --- /dev/null +++ b/test-common/src/main/scala/org/scalajs/testcommon/JSSlaveEndpoints.scala @@ -0,0 +1,16 @@ +package org.scalajs.testcommon + +import sbt.testing._ + +private[scalajs] object JSSlaveEndpoints { + val newRunner: RPCEndpoint.EP[Unit, Unit] = + RPCEndpoint[Unit, Unit](2) + + val execute: RPCEndpoint.EP[ExecuteRequest, List[TaskInfo]] = + RPCEndpoint[ExecuteRequest, List[TaskInfo]](3) + + val stopSlave: RPCEndpoint.EP[Unit, Unit] = + RPCEndpoint[Unit, Unit](4) + + val msg: MsgEndpoint.EP[String] = MsgEndpoint[String](5) +} diff --git a/test-common/src/main/scala/org/scalajs/testcommon/JVMMasterEndpoints.scala b/test-common/src/main/scala/org/scalajs/testcommon/JVMMasterEndpoints.scala new file mode 100644 index 0000000000..d0cb4e65c8 --- /dev/null +++ b/test-common/src/main/scala/org/scalajs/testcommon/JVMMasterEndpoints.scala @@ -0,0 +1,7 @@ +package org.scalajs.testcommon + +import sbt.testing._ + +private[scalajs] object JVMMasterEndpoints { + val msg: MsgEndpoint.EP[FrameworkMessage] = MsgEndpoint[FrameworkMessage](2) +} diff --git a/test-common/src/main/scala/org/scalajs/testcommon/JVMSlaveEndpoints.scala b/test-common/src/main/scala/org/scalajs/testcommon/JVMSlaveEndpoints.scala new file mode 100644 index 0000000000..a011b4cd70 --- /dev/null +++ b/test-common/src/main/scala/org/scalajs/testcommon/JVMSlaveEndpoints.scala @@ -0,0 +1,24 @@ +package org.scalajs.testcommon + +import sbt.testing._ + +private[scalajs] object JVMSlaveEndpoints { + val msg: MsgEndpoint.EP[String] = MsgEndpoint[String](2) + + val event: MsgEndpoint.EP[Event] = MsgEndpoint[Event](3) + + val logError: MsgEndpoint.EP[LogElement[String]] = + MsgEndpoint[LogElement[String]](4) + + val logWarn: MsgEndpoint.EP[LogElement[String]] = + MsgEndpoint[LogElement[String]](5) + + val logInfo: MsgEndpoint.EP[LogElement[String]] = + MsgEndpoint[LogElement[String]](6) + + val logDebug: MsgEndpoint.EP[LogElement[String]] = + MsgEndpoint[LogElement[String]](7) + + val logTrace: MsgEndpoint.EP[LogElement[Throwable]] = + MsgEndpoint[LogElement[Throwable]](8) +} diff --git a/test-common/src/main/scala/org/scalajs/testcommon/LogElement.scala b/test-common/src/main/scala/org/scalajs/testcommon/LogElement.scala new file mode 100644 index 0000000000..29ae677525 --- /dev/null +++ b/test-common/src/main/scala/org/scalajs/testcommon/LogElement.scala @@ -0,0 +1,18 @@ +package org.scalajs.testcommon + +private[scalajs] final class LogElement[T](val index: Int, val x: T) + +private[scalajs] object LogElement { + implicit def logElementSerializer[T: Serializer]: Serializer[LogElement[T]] = { + new Serializer[LogElement[T]] { + def serialize(x: LogElement[T], out: Serializer.SerializeState): Unit = { + out.write(x.index) + out.write(x.x) + } + + def deserialize(in: Serializer.DeserializeState): LogElement[T] = { + new LogElement(in.read[Int](), in.read[T]()) + } + } + } +} diff --git a/test-common/src/main/scala/org/scalajs/testcommon/RPCCore.scala b/test-common/src/main/scala/org/scalajs/testcommon/RPCCore.scala new file mode 100644 index 0000000000..90f169a10a --- /dev/null +++ b/test-common/src/main/scala/org/scalajs/testcommon/RPCCore.scala @@ -0,0 +1,235 @@ +package org.scalajs.testcommon + +import scala.util.{Try, Failure, Success} + +import scala.collection.JavaConverters._ +import scala.concurrent._ +import scala.concurrent.duration._ + +import java.io._ +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.atomic.AtomicLong + +import Serializer.{serialize, deserialize} + +private[scalajs] abstract class RPCCore { + import RPCCore._ + + /** Pending calls. + * + * @note We do deliberately not timeout calls in here since there will be + * timeouts on a higher level and a test run is relatively short lived + * (< 10h) and we expect failure ratio to be extremely low. + */ + private[this] val pending = new ConcurrentHashMap[Long, PendingCall] + + private[this] val nextID = new AtomicLong(0L) + + private[this] val endpoints = new ConcurrentHashMap[OpCode, BoundEndpoint] + + /** Subclass should call this whenever a new message arrives */ + final protected def handleMessage(msg: String): Unit = { + Serializer.withInputStream(msg) { in => + val opCode = in.readByte() + + def getPending(): Option[PendingCall] = { + val callID = in.readLong() + /* Note that `callID` might not be in `pending` anymore if it got + * removed during a close operation. In this case we're not doing + * anything. + */ + Option(pending.remove(callID)) + } + + opCode match { + case RPCCore.ReplyOK => + getPending().foreach { p => + import p._ + promise.complete(Try(deserialize[Resp](in))) + } + + case RPCCore.ReplyErr => + getPending().foreach { p => + val throwable = Try(deserialize[Throwable](in)) match { + case Success(t) => new RPCException(t) + case Failure(t) => t + } + + p.promise.failure(throwable) + } + + case _ => + endpoints.get(opCode) match { + case null => + throw new IllegalStateException(s"Unknown opcode: $opCode") + + case bep: BoundMsgEndpoint => + val ep: bep.endpoint.type = bep.endpoint + import ep._ + + bep.exec(deserialize[Msg](in)) + + case bep: BoundRPCEndpoint => + val callID = in.readLong() + + val ep: bep.endpoint.type = bep.endpoint + import ep._ + + import scala.concurrent.ExecutionContext.Implicits.global + + futureFromTry(Try(deserialize[Req](in))) + .flatMap(bep.exec) + .onComplete(repl => send(makeReply(callID, repl))) + } + } + } + } + + /** Subclass needs to implement message sending. */ + protected def send(msg: String): Unit + + /** Used to send a message to the other end. */ + final def send(ep: MsgEndpoint)(msg: ep.Msg): Unit = { + import ep._ + send(makeMsgMsg(opCode, msg)) + } + + /** Used to make an actual call to the other end. */ + final def call(ep: RPCEndpoint)(req: ep.Req): Future[ep.Resp] = { + import ep._ + + // Reserve an id for this call. + val id = nextID.incrementAndGet() + + // Prepare message. + val msg = makeRPCMsg(opCode, id, req) + + // Register pending call. + val promise = Promise[Resp] + val oldCall = pending.put(id, PendingCall(promise)) + + if (oldCall != null) { + throw new AssertionError("Ran out of call ids!") + } + + // Actually send message. + send(msg) + + promise.future + } + + final def attach(ep: MsgEndpoint)(ex: ep.Msg => Unit): Unit = { + attach(new BoundMsgEndpoint { + val endpoint: ep.type = ep + val exec = ex + }) + } + + /** Attaches the given method to the given (local) endpoint. */ + final def attach(ep: RPCEndpoint)(ex: ep.Req => ep.Resp): Unit = { + attachAsync(ep)(x => futureFromTry(Try(ex(x)))) + } + + /** Attaches the given method to the given (local) endpoint. */ + final def attachAsync(ep: RPCEndpoint)(ex: ep.Req => Future[ep.Resp]): Unit = { + attach(new BoundRPCEndpoint { + val endpoint: ep.type = ep + val exec = ex + }) + } + + private final def attach(bep: BoundEndpoint): Unit = { + val opCode = bep.endpoint.opCode + val old = endpoints.put(opCode, bep) + require(old == null, s"Duplicate endpoint for opcode $opCode.") + } + + final def detach(ep: Endpoint): Unit = { + val old = endpoints.remove(ep.opCode) + require(old != null, "Endpoint was not attached.") + } + + /** Close the communication channel. */ + def close(): Unit = { + for { + callID <- pending.keySet().asScala + failing <- Option(pending.remove(callID)) + } { + failing.promise.failure(new IOException("Channel got closed")) + } + } + + private def makeReply[T: Serializer](id: Long, result: Try[T]): String = { + result.map(makeRPCMsg(ReplyOK, id, _)) match { + case Success(m) => m + case Failure(t) => makeRPCMsg(ReplyErr, id, t) + } + } + + private def makeRPCMsg[T: Serializer](opCode: OpCode, id: Long, + payload: T): String = { + Serializer.withOutputStream { out => + out.writeByte(opCode) + out.writeLong(id) + serialize(payload, out) + } + } + + private def makeMsgMsg[T: Serializer](opCode: OpCode, payload: T): String = { + Serializer.withOutputStream { out => + out.writeByte(opCode) + serialize(payload, out) + } + } + + /** Same as Future.fromTry(x) but works in 2.10 */ + private def futureFromTry[T](x: Try[T]): Future[T] = { + val promise = Promise[T] + promise.complete(x) + promise.future + } +} + +private[scalajs] object RPCCore { + type OpCode = Byte + + /** Exception thrown if a remote invocation fails. */ + class RPCException(c: Throwable) extends Exception(null, c) + + private val ReplyOK: Byte = 0.toByte + private val ReplyErr: Byte = 1.toByte + + def isReservedOpCode(opc: OpCode): Boolean = + opc == ReplyOK || opc == ReplyErr + + private sealed trait BoundEndpoint { + val endpoint: Endpoint + } + + private sealed trait BoundMsgEndpoint extends BoundEndpoint { + val endpoint: MsgEndpoint + val exec: endpoint.Msg => Unit + } + + private sealed trait BoundRPCEndpoint extends BoundEndpoint { + val endpoint: RPCEndpoint + val exec: endpoint.Req => Future[endpoint.Resp] + } + + private trait PendingCall { + type Resp + val promise: Promise[Resp] + implicit val serializer: Serializer[Resp] + } + + private object PendingCall { + def apply[R](p: Promise[R])(implicit s: Serializer[R]): PendingCall = { + new PendingCall { + type Resp = R + val promise: Promise[Resp] = p + + implicit val serializer: Serializer[R] = s + } + } + } +} diff --git a/test-common/src/main/scala/org/scalajs/testcommon/RunnerArgs.scala b/test-common/src/main/scala/org/scalajs/testcommon/RunnerArgs.scala new file mode 100644 index 0000000000..6fac5bce6a --- /dev/null +++ b/test-common/src/main/scala/org/scalajs/testcommon/RunnerArgs.scala @@ -0,0 +1,16 @@ +package org.scalajs.testcommon + +private[scalajs] final class RunnerArgs( + val args: List[String], val remoteArgs: List[String]) + +private[scalajs] object RunnerArgs { + implicit object RunnerArgsSerializer extends Serializer[RunnerArgs] { + def serialize(x: RunnerArgs, out: Serializer.SerializeState): Unit = { + out.write(x.args) + out.write(x.remoteArgs) + } + + def deserialize(in: Serializer.DeserializeState): RunnerArgs = + new RunnerArgs(in.read[List[String]](), in.read[List[String]]()) + } +} diff --git a/test-common/src/main/scala/org/scalajs/testcommon/Serializer.scala b/test-common/src/main/scala/org/scalajs/testcommon/Serializer.scala new file mode 100644 index 0000000000..31b7995d8a --- /dev/null +++ b/test-common/src/main/scala/org/scalajs/testcommon/Serializer.scala @@ -0,0 +1,297 @@ +package org.scalajs.testcommon + +import sbt.testing._ +import java.io._ + +private[scalajs] trait Serializer[T] { + def serialize(x: T, out: Serializer.SerializeState): Unit + def deserialize(in: Serializer.DeserializeState): T +} + +private[scalajs] object Serializer { + /* Serialization states. Serialization is currently stateless, in the sense + * that the same value will always get serialized to the same bytes, no matter + * where it is in the bytestream. + * In the future we might want to deduplicate things like package prefixes, + * since a lot of data seems to be redundant. + */ + final class SerializeState private[Serializer](val out: DataOutputStream) + extends AnyVal { + def write[T](t: T)(implicit s: Serializer[T]): Unit = s.serialize(t, this) + } + + final class DeserializeState private[Serializer](val in: DataInputStream) + extends AnyVal { + def read[T]()(implicit s: Serializer[T]): T = s.deserialize(this) + } + + // Methods to actually perform serialization and deserialization. + + def serialize[T](t: T, out: DataOutputStream)(implicit s: Serializer[T]): Unit = { + s.serialize(t, new SerializeState(out)) + } + + def deserialize[T](in: DataInputStream)(implicit s: Serializer[T]): T = { + s.deserialize(new DeserializeState(in)) + } + + def serialize[T: Serializer](t: T): String = + withOutputStream(Serializer.serialize(t, _)) + + def deserialize[T: Serializer](s: String): T = + withInputStream(s)(Serializer.deserialize[T](_)) + + @inline + def withInputStream[T](s: String)(body: DataInputStream => T): T = { + val bytes = s.toArray.map(_.toByte) + val in = new DataInputStream(new ByteArrayInputStream(bytes)) + try body(in) + finally in.close() + } + + @inline + def withOutputStream(body: DataOutputStream => Unit): String = { + val byteOut = new ByteArrayOutputStream() + val dataOut = new DataOutputStream(byteOut) + + try body(dataOut) + finally dataOut.close() + + new String(byteOut.toByteArray.map(b => (b & 0xFF).toChar)) + } + + implicit def listSerializer[T: Serializer]: Serializer[List[T]] = { + new Serializer[List[T]] { + def serialize(x: List[T], out: SerializeState): Unit = { + out.write(x.size) + x.foreach(out.write(_)) + } + + def deserialize(in: DeserializeState): List[T] = + List.fill(in.read[Int]())(in.read[T]()) + } + } + + implicit def optionSerializer[T: Serializer]: Serializer[Option[T]] = { + new Serializer[Option[T]] { + def serialize(x: Option[T], out: SerializeState): Unit = { + out.write(x.isDefined) + x.foreach(out.write(_)) + } + + def deserialize(in: DeserializeState): Option[T] = { + if (in.read[Boolean]()) Some(in.read[T]()) + else None + } + } + } + + implicit object BooleanSerializer extends Serializer[Boolean] { + def serialize(x: Boolean, out: SerializeState): Unit = out.out.writeBoolean(x) + def deserialize(in: DeserializeState): Boolean = in.in.readBoolean() + } + + implicit object ByteSerializer extends Serializer[Byte] { + def serialize(x: Byte, out: SerializeState): Unit = out.out.writeByte(x) + def deserialize(in: DeserializeState): Byte = in.in.readByte() + } + + implicit object IntSerializer extends Serializer[Int] { + def serialize(x: Int, out: SerializeState): Unit = out.out.writeInt(x) + def deserialize(in: DeserializeState): Int = in.in.readInt() + } + + implicit object LongSerializer extends Serializer[Long] { + def serialize(x: Long, out: SerializeState): Unit = out.out.writeLong(x) + def deserialize(in: DeserializeState): Long = in.in.readLong() + } + + implicit object StringSerializer extends Serializer[String] { + def serialize(x: String, out: SerializeState): Unit = out.out.writeUTF(x) + def deserialize(in: DeserializeState): String = in.in.readUTF() + } + + implicit object UnitSerializer extends Serializer[Unit] { + def serialize(x: Unit, out: SerializeState): Unit = () + def deserialize(in: DeserializeState): Unit = () + } + + implicit object StackTraceElementSerializer extends Serializer[StackTraceElement] { + def serialize(x: StackTraceElement, out: SerializeState): Unit = { + out.write(x.getClassName()) + out.write(x.getMethodName()) + out.write(x.getFileName()) + out.write(x.getLineNumber()) + } + + def deserialize(in: DeserializeState): StackTraceElement = { + new StackTraceElement(in.read[String](), in.read[String](), + in.read[String](), in.read[Int]()) + } + } + + implicit object ThrowableSerializer extends Serializer[Throwable] { + def serialize(x: Throwable, out: SerializeState): Unit = { + out.write(Option(x.getMessage())) + out.write(x.toString()) + out.write(x.getStackTrace().toList) + out.write(Option(x.getCause())) + } + + def deserialize(in: DeserializeState): Throwable = { + val msg = in.read[Option[String]]().orNull + val toStr = in.read[String]() + val trace = in.read[List[StackTraceElement]]() + val cause = in.read[Option[Throwable]]() + + val res = new Throwable(msg, cause.orNull) { + override def toString(): String = toStr + } + + res.setStackTrace(trace.toArray) + + res + } + } + + implicit object FingerprintSerializer extends Serializer[Fingerprint] { + // Type tags. + private val Annotated: Byte = 1 + private val Subclass: Byte = 2 + + def serialize(fp: Fingerprint, out: SerializeState): Unit = fp match { + case fp: AnnotatedFingerprint => + out.write(Annotated) + out.write(fp.isModule) + out.write(fp.annotationName) + case fp: SubclassFingerprint => + out.write(Subclass) + out.write(fp.isModule) + out.write(fp.superclassName) + out.write(fp.requireNoArgConstructor) + case _ => + throw new IllegalArgumentException( + s"Unknown Fingerprint type: ${fp.getClass}") + } + + def deserialize(in: DeserializeState): Fingerprint = in.read[Byte]() match { + case Annotated => + new AnnotatedFingerprint { + val isModule: Boolean = in.read[Boolean]() + val annotationName: String = in.read[String]() + } + + case Subclass => + new SubclassFingerprint { + val isModule: Boolean = in.read[Boolean]() + val superclassName: String = in.read[String]() + val requireNoArgConstructor: Boolean = in.read[Boolean]() + } + + case t => + throw new IOException(s"Unknown Fingerprint type: $t") + } + } + + implicit object SelectorSerializer extends Serializer[Selector] { + // Type tags. + private val Suite: Byte = 1 + private val Test: Byte = 2 + private val NestedSuite: Byte = 3 + private val NestedTest: Byte = 4 + private val TestWildcard: Byte = 5 + + def serialize(sel: Selector, out: SerializeState): Unit = sel match { + case sel: SuiteSelector => out.write(Suite) + + case sel: TestSelector => + out.write(Test) + out.write(sel.testName) + + case sel: NestedSuiteSelector => + out.write(NestedSuite) + out.write(sel.suiteId) + + case sel: NestedTestSelector => + out.write(NestedTest) + out.write(sel.suiteId) + out.write(sel.testName) + + case sel: TestWildcardSelector => + out.write(TestWildcard) + out.write(sel.testWildcard) + + case _ => + throw new IllegalArgumentException( + s"Unknown Selector type: ${sel.getClass}") + } + + def deserialize(in: DeserializeState): Selector = in.read[Byte]() match { + case Suite => new SuiteSelector() + case Test => new TestSelector(in.read[String]()) + case NestedSuite => new NestedSuiteSelector(in.read[String]()) + case NestedTest => new NestedTestSelector(in.read[String](), in.read[String]()) + case TestWildcard => new TestWildcardSelector(in.read[String]()) + case t => throw new IOException(s"Unknown Selector type: $t") + } + } + + implicit object TaskDefSerializer extends Serializer[TaskDef] { + def serialize(x: TaskDef, out: SerializeState): Unit = { + out.write(x.fullyQualifiedName) + out.write(x.fingerprint) + out.write(x.explicitlySpecified) + out.write(x.selectors.toList) + } + + def deserialize(in: DeserializeState): TaskDef = { + new TaskDef(in.read[String](), in.read[Fingerprint](), in.read[Boolean](), + in.read[List[Selector]]().toArray) + } + } + + implicit object StatusSerializer extends Serializer[Status] { + def serialize(x: Status, out: SerializeState): Unit = out.write(x.ordinal) + + def deserialize(in: DeserializeState): Status = { + val values = Status.values() + val ord = in.read[Int]() + if (ord < 0 || ord >= values.size) + throw new IOException(s"Got bad status ordinal: $ord") + values(ord) + } + } + + implicit object OptionalThrowableSerializer extends Serializer[OptionalThrowable] { + def serialize(x: OptionalThrowable, out: SerializeState): Unit = { + out.write(x.isDefined()) + if (x.isDefined()) + out.write(x.get()) + } + + def deserialize(in: DeserializeState): OptionalThrowable = { + if (in.read[Boolean]()) new OptionalThrowable(in.read[Throwable]()) + else new OptionalThrowable() + } + } + + implicit object EventSerializer extends Serializer[Event] { + def serialize(x: Event, out: SerializeState): Unit = { + out.write(x.fullyQualifiedName) + out.write(x.fingerprint) + out.write(x.selector) + out.write(x.status) + out.write(x.throwable) + out.write(x.duration) + } + + def deserialize(in: DeserializeState): Event = new Event { + val fullyQualifiedName: String = in.read[String]() + val fingerprint: Fingerprint = in.read[Fingerprint]() + val selector: Selector = in.read[Selector]() + val status: Status = in.read[Status]() + val throwable: OptionalThrowable = in.read[OptionalThrowable]() + val duration: Long = in.read[Long]() + } + } +} diff --git a/test-common/src/main/scala/org/scalajs/testcommon/TaskInfo.scala b/test-common/src/main/scala/org/scalajs/testcommon/TaskInfo.scala new file mode 100644 index 0000000000..bc98deccf8 --- /dev/null +++ b/test-common/src/main/scala/org/scalajs/testcommon/TaskInfo.scala @@ -0,0 +1,21 @@ +package org.scalajs.testcommon + +import sbt.testing._ + +private[scalajs] final class TaskInfo( + val serializedTask: String, + val taskDef: TaskDef, + val tags: List[String]) + +private[scalajs] object TaskInfo { + implicit object TaskInfoSerializer extends Serializer[TaskInfo] { + def serialize(x: TaskInfo, out: Serializer.SerializeState): Unit = { + out.write(x.serializedTask) + out.write(x.taskDef) + out.write(x.tags) + } + + def deserialize(in: Serializer.DeserializeState): TaskInfo = + new TaskInfo(in.read[String](), in.read[TaskDef](), in.read[List[String]]()) + } +} diff --git a/test-common/src/test/scala/org/scalajs/testcommon/RPCCoreTest.scala b/test-common/src/test/scala/org/scalajs/testcommon/RPCCoreTest.scala new file mode 100644 index 0000000000..c943251e4e --- /dev/null +++ b/test-common/src/test/scala/org/scalajs/testcommon/RPCCoreTest.scala @@ -0,0 +1,169 @@ +package org.scalajs.testcommon + +import scala.concurrent._ +import scala.concurrent.duration._ +import scala.concurrent.ExecutionContext.Implicits.global + +import java.util.concurrent.atomic.AtomicInteger + +import org.junit.Test +import org.junit.Assert._ + +class RPCCoreTest { + import RPCCoreTest._ + + lazy val x: TestRPC = new TestRPC(y) + lazy val y: TestRPC = new TestRPC(x) + + object eps { + val simple: RPCEndpoint.EP[Unit, Unit] = RPCEndpoint[Unit, Unit](2) + val number: RPCEndpoint.EP[Unit, Int] = RPCEndpoint[Unit, Int](3) + val msg0: MsgEndpoint.EP[Int] = MsgEndpoint[Int](4) + val msg1: MsgEndpoint.EP[Int] = MsgEndpoint[Int](5) + } + + private def fail(msg: String): Nothing = { + org.junit.Assert.fail(msg) + throw new AssertionError("Shouldn't reach here") + } + + @Test + def simpleEndpoint: Unit = { + var called = false + x.attach(eps.simple)((_: Unit) => called = true) + Await.result(y.call(eps.simple)(()), atMost = 1.second) + assertTrue(called) + } + + @Test + def multiplePendingCalls: Unit = { + val p = Promise[Int] + + x.attachAsync(eps.number)(_ => p.future) + + val futures = List.fill(20)(y.call(eps.number)(())) + + p.success(1) + + val results = Await.result(Future.sequence(futures), atMost = 10.second) + assertEquals(List.fill(20)(1), results) + } + + @Test + def singleMsgEndpoint: Unit = { + var intMsg = 0 + x.attach(eps.msg0)(intMsg = _) + assertEquals(0, intMsg) + + y.send(eps.msg0)(1) + assertEquals(1, intMsg) + } + + @Test + def msgEndpointOrdering: Unit = { + var calls: List[(Int, Int)] = Nil + + x.attach(eps.msg0)(calls ::= (0, _)) + x.attach(eps.msg1)(calls ::= (1, _)) + + val numbers = 0 to 10 + + for (i <- numbers) { + y.send(eps.msg0)(i) + y.send(eps.msg1)(i) + } + + val expected = for { + i <- numbers + c <- 0 to 1 + } yield (c, i) + + assertArrayEquals(expected.toArray.asInstanceOf[Array[Object]], + calls.reverse.toArray.asInstanceOf[Array[Object]]) + } + + @Test + def msgRPCOrdering: Unit = { + val msgsX = new AtomicInteger(0) + val msgsY = new AtomicInteger(0) + + x.attach(eps.msg0)(_ => msgsX.incrementAndGet()) + y.attach(eps.msg0)(_ => msgsY.incrementAndGet()) + + val p = Promise[Unit]() + + x.attachAsync(eps.simple) { _ => + // Message from y must be here by now. + assertEquals(1, msgsX.get()) + assertEquals(0, msgsY.get()) + + x.send(eps.msg0)(0) + + p.future + } + + y.send(eps.msg0)(0) + p.success(()) + + Await.result(y.call(eps.simple)(()), atMost = 1.second) + + // Message from x must be here by now. + assertEquals(1, msgsX.get()) + assertEquals(1, msgsY.get()) + } + + @Test + def unboundEndpoint: Unit = { + try { + y.call(eps.simple)(()) + fail("Expected exception") + } catch { + case e: IllegalStateException => + assertEquals(s"Unknown opcode: ${eps.simple.opCode}", e.getMessage()) + } + } + + @Test + def remoteException: Unit = { + val msg0 = "My message for the outer exception" + val msg1 = "My message for the inner exception" + x.attach(eps.simple)( + (_: Unit) => throw new Exception(msg0, new Exception(msg1))) + + try { + Await.result(y.call(eps.simple)(()), atMost = 1.second) + fail("Expected exception") + } catch { + case e: RPCCore.RPCException => + assertNotNull(e.getCause()) + assertEquals(msg0, e.getCause().getMessage()) + assertNotNull(e.getCause().getCause()) + assertEquals(msg1, e.getCause().getCause().getMessage()) + } + } + + @Test + def closeChannel: Unit = { + // Attach something that never completes. + x.attachAsync(eps.number)((_: Unit) => Promise[Int].future) + + val future = y.call(eps.number)(()) + + y.close() + + try { + Await.result(future, atMost = 1.second) + fail("Expected exception") + } catch { + case e: java.io.IOException => + assertEquals("Channel got closed", e.getMessage()) + } + } +} + +object RPCCoreTest { + class TestRPC(otherThunk: => TestRPC) extends RPCCore { + private lazy val other = otherThunk + protected def send(msg: String): Unit = other.handleMessage(msg) + } +} diff --git a/test-common/src/test/scala/org/scalajs/testcommon/SerializerTest.scala b/test-common/src/test/scala/org/scalajs/testcommon/SerializerTest.scala new file mode 100644 index 0000000000..3663f8affd --- /dev/null +++ b/test-common/src/test/scala/org/scalajs/testcommon/SerializerTest.scala @@ -0,0 +1,19 @@ +package org.scalajs.testcommon + +import org.junit.Test +import org.junit.Assert._ + +class SerializerTest { + def roundTrip[T: Serializer](x: T): T = + Serializer.deserialize[T](Serializer.serialize(x)) + + @Test + def serializeThrowableWithNullFields: Unit = { + val in = new Throwable(null, null) + val out = roundTrip(in) + assertEquals(in.getMessage(), out.getMessage()) + assertEquals(in.getCause(), out.getCause()) + assertEquals(in.toString(), out.toString()) + assertEquals(in.getStackTrace().size, out.getStackTrace().size) + } +} diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala b/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala index 9f3101bc27..d9018cdcf6 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala @@ -1,10 +1,12 @@ package org.scalajs.testinterface +import java.io._ + import scala.scalajs.js import scala.scalajs.js.annotation.JSGlobalScope import scala.scalajs.reflect.Reflect -import org.scalajs.testinterface.internal.TaskDefSerializer +import org.scalajs.testcommon.Serializer import sbt.testing._ @@ -13,7 +15,7 @@ private[scalajs] object TestDetector { def detectTests(): Seq[(Framework, Seq[TaskDef])] = { import RawDefinitions._ - val taskDefs = definedTests.map(TaskDefSerializer.deserialize _) + val taskDefs = Serializer.deserialize[List[TaskDef]](definedTests) val frameworks = testFrameworkNames.flatMap(tryLoadFramework).toList for { @@ -70,7 +72,7 @@ private[scalajs] object TestDetector { @js.native @JSGlobalScope private object RawDefinitions extends js.Object { - val definedTests: js.Array[js.Dynamic] = js.native + val definedTests: String = js.native val testFrameworkNames: js.Array[js.Array[String]] = js.native } } diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/BridgeBase.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/BridgeBase.scala deleted file mode 100644 index 688ae332ea..0000000000 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/BridgeBase.scala +++ /dev/null @@ -1,65 +0,0 @@ -package org.scalajs.testinterface.internal - -import scala.scalajs.js -import js.JSConverters._ -import js.annotation.JSExport -import js.Dynamic.{literal => lit} - -import scala.util.control.NonFatal -import scala.util.{Try, Success, Failure} - -import sbt.testing._ - -abstract class BridgeBase(frameworkName: String) { - - protected[this] val framework = FrameworkLoader.loadFramework(frameworkName) - - @JSExport - def init(): Unit = { - Com.init(handleMsg _) - } - - private def handleMsg(msg: String): Unit = { - val pos = msg.indexOf(':') - val cmd = if (pos == -1) msg else msg.substring(0, pos) - - def strArg = { - if (pos == -1) - throw new IllegalArgumentException(s"$cmd needs args") - else - msg.substring(pos + 1) - } - - try { - handleMsgImpl(cmd, strArg) - } catch { - case NonFatal(t) => - val data = js.JSON.stringify(ThrowableSerializer.serialize(t)) - Com.send("bad:" + data) - } - } - - protected def reply(result: Try[Any]): Unit = result match { - case Success(()) => - Com.send("ok:") - case Success(v) => - Com.send("ok:" + v) - case Failure(e) => - val data = js.JSON.stringify(ThrowableSerializer.serialize(e)) - Com.send("fail:" + data) - } - - protected def handleMsgImpl(cmd: String, strArg: => String): Unit - - protected def tasks2TaskInfos(tasks: Array[Task], runner: Runner): js.Any = { - tasks.map { task => - val serTask = runner.serializeTask(task, taskDef => - js.JSON.stringify(TaskDefSerializer.serialize(taskDef))) - - lit(serializedTask = serTask, - taskDef = TaskDefSerializer.serialize(task.taskDef), - tags = task.tags.toJSArray) - }.toJSArray - } - -} diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/EventSerializer.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/EventSerializer.scala deleted file mode 100644 index a7b26e1bf7..0000000000 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/EventSerializer.scala +++ /dev/null @@ -1,27 +0,0 @@ -package org.scalajs.testinterface.internal - -import scala.scalajs.js -import js.Dynamic.{literal => lit} -import js.JSConverters._ - -import sbt.testing._ - -object EventSerializer { - - def serialize(ev: Event): js.Dynamic = { - val res = lit( - fullyQualifiedName = ev.fullyQualifiedName, - fingerprint = FingerprintSerializer.serialize(ev.fingerprint), - selector = SelectorSerializer.serialize(ev.selector), - status = ev.status.name(), - durationLS = ev.duration().toInt, - durationMS = (ev.duration() >>> 32).toInt) - - val optT = ev.throwable() - if (optT.isDefined) - res.throwable = ThrowableSerializer.serialize(optT.get()) - - res - } - -} diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/FingerprintSerializer.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/FingerprintSerializer.scala deleted file mode 100644 index b42474d480..0000000000 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/FingerprintSerializer.scala +++ /dev/null @@ -1,52 +0,0 @@ -package org.scalajs.testinterface.internal - -import scala.scalajs.js -import js.Dynamic.{literal => lit} - -import sbt.testing._ - -object FingerprintSerializer { - - def serialize(fp: Fingerprint): js.Dynamic = fp match { - case fp: AnnotatedFingerprint => lit( - fpType = "AnnotatedFingerprint", - isModule = fp.isModule, - annotationName = fp.annotationName) - case fp: SubclassFingerprint => lit( - fpType = "SubclassFingerprint", - isModule = fp.isModule, - superclassName = fp.superclassName, - requireNoArgConstructor = fp.requireNoArgConstructor) - case _ => - throw new IllegalArgumentException( - s"Unknown Fingerprint type: ${fp.getClass}") - } - - def deserialize(obj: js.Dynamic): Fingerprint = { - obj.fpType.asInstanceOf[String] match { - case "AnnotatedFingerprint" => - new DeserializedAnnotatedFingerprint( - obj.isModule.asInstanceOf[Boolean], - obj.annotationName.asInstanceOf[String]) - case "SubclassFingerprint" => - new DeserializedSubclassFingerprint( - obj.isModule.asInstanceOf[Boolean], - obj.superclassName.asInstanceOf[String], - obj.requireNoArgConstructor.asInstanceOf[Boolean]) - case tpe => - throw new IllegalArgumentException(s"Unknown Fingerprint type: $tpe") - } - } - - final class DeserializedAnnotatedFingerprint( - val isModule: Boolean, - val annotationName: String - ) extends AnnotatedFingerprint - - final class DeserializedSubclassFingerprint( - val isModule: Boolean, - val superclassName: String, - val requireNoArgConstructor: Boolean - ) extends SubclassFingerprint - -} diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/InfoSender.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/InfoSender.scala index 6928842c70..6a3c745613 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/InfoSender.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/InfoSender.scala @@ -1,13 +1,13 @@ package org.scalajs.testinterface.internal -import scala.scalajs.js -import js.Dynamic.{literal => lit} -import js.JSConverters._ -import js.annotation._ +import scala.scalajs.js.annotation._ + +import java.io._ + +import org.scalajs.testcommon._ @JSExportTopLevel("org.scalajs.testinterface.internal.InfoSender") final class InfoSender(frameworkName: String) { - @JSExport def initAndSend(): Unit = { Com.init((_: String) => ()) @@ -17,12 +17,7 @@ final class InfoSender(frameworkName: String) { private def sendFrameworkInfo(): Unit = { val framework = FrameworkLoader.loadFramework(frameworkName) - val fingerprints = - framework.fingerprints.map(FingerprintSerializer.serialize).toJSArray - val data = lit( - name = framework.name, - fingerprints = fingerprints) - Com.send(js.JSON.stringify(data)) + val info = new FrameworkInfo(framework.name, framework.fingerprints.toList) + Com.send(Serializer.serialize(info)) } - } diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/JSRPC.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/JSRPC.scala new file mode 100644 index 0000000000..2c20abc256 --- /dev/null +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/JSRPC.scala @@ -0,0 +1,20 @@ +package org.scalajs.testinterface.internal + +import scala.scalajs.js +import scala.scalajs.js.annotation._ + +import scala.concurrent.duration._ + +import org.scalajs.testcommon.RPCCore + +/** JS RPC Core. Uses `scalajsCom`. */ +private[internal] final object JSRPC extends RPCCore { + Com.init(handleMessage _) + + override protected def send(msg: String): Unit = Com.send(msg) + + override def close(): Unit = { + super.close() + Com.close() + } +} diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Master.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/Master.scala index f4646b92a0..eea474d450 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Master.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/Master.scala @@ -6,65 +6,51 @@ import js.annotation._ import sbt.testing._ +import scala.concurrent.Future import scala.util.Try +import org.scalajs.testcommon._ import org.scalajs.testinterface.ScalaJSClassLoader @JSExportTopLevel("org.scalajs.testinterface.internal.Master") -final class Master(frameworkName: String) extends BridgeBase(frameworkName) { +final class Master(frameworkName: String) { private[this] var runner: Runner = _ - protected def handleMsgImpl(cmd: String, strArg: => String): Unit = { - def jsonArg = js.JSON.parse(strArg) - cmd match { - case "newRunner" => - reply(newRunner(jsonArg)) - case "runnerDone" => - reply(runnerDone()) - case "tasks" => - reply(tasks(jsonArg)) - case "msg" => - reply(inboundMessage(strArg)) - case cmd => - throw new IllegalArgumentException(s"Unknown command: $cmd") - } - } + JSRPC.attach(JSMasterEndpoints.newRunner)(newRunner _) + JSRPC.attach(JSMasterEndpoints.runnerDone)(runnerDone _) + JSRPC.attach(JSMasterEndpoints.tasks)(tasks _) + JSRPC.attach(JSMasterEndpoints.msg)(inboundMessage _) // Message handler methods - private def newRunner(data: js.Dynamic): Try[Unit] = { - val args = data.args.asInstanceOf[js.Array[String]].toArray - val remoteArgs = data.remoteArgs.asInstanceOf[js.Array[String]].toArray + private def newRunner(req: RunnerArgs): Unit = { + val framework = FrameworkLoader.loadFramework(frameworkName) val loader = new ScalaJSClassLoader( scala.scalajs.runtime.environmentInfo.exportsNamespace) - - Try(runner = framework.runner(args, remoteArgs, loader)) + runner = framework.runner(req.args.toArray, req.remoteArgs.toArray, loader) } - private def runnerDone(): Try[String] = { + private def runnerDone(req: Unit): String = { ensureRunnerExists() - val result = Try(runner.done()) - runner = null - result + try runner.done() + finally runner = null } - private def tasks(data: js.Dynamic): Try[String] = { + private def tasks(taskDefs: List[TaskDef]): List[TaskInfo] = { ensureRunnerExists() - val taskDefs = data.asInstanceOf[js.Array[js.Dynamic]] - .map(TaskDefSerializer.deserialize).toArray - - Try { - val tasks = runner.tasks(taskDefs) - js.JSON.stringify(tasks2TaskInfos(tasks, runner)) - } + val tasks = runner.tasks(taskDefs.toArray) + tasks.map(TaskInfoBuilder.detachTask(_, runner)).toList } - private def inboundMessage(msg: String): Try[String] = { + private def inboundMessage(msg: FrameworkMessage): Unit = { ensureRunnerExists() - Try(runner.receiveMessage(msg).fold(":n")(":s:" + _)) + for (reply <- runner.receiveMessage(msg.msg)) { + JSRPC.send(JVMMasterEndpoints.msg)( + new FrameworkMessage(msg.slaveId, reply)) + } } // Utility methods diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/SelectorSerializer.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/SelectorSerializer.scala deleted file mode 100644 index 2326ed914c..0000000000 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/SelectorSerializer.scala +++ /dev/null @@ -1,53 +0,0 @@ -package org.scalajs.testinterface.internal - -import scala.scalajs.js -import js.Dynamic.{literal => lit} - -import sbt.testing._ - -object SelectorSerializer { - - def serialize(sel: Selector): js.Dynamic = sel match { - case sel: SuiteSelector => lit( - selType = "SuiteSelector") - case sel: TestSelector => lit( - selType = "TestSelector", - testName = sel.testName) - case sel: NestedSuiteSelector => lit( - selType = "NestedSuiteSelector", - suiteId = sel.suiteId) - case sel: NestedTestSelector => lit( - selType = "NestedTestSelector", - suiteId = sel.suiteId, - testName = sel.testName) - case sel: TestWildcardSelector => lit( - selType = "TestWildcardSelector", - testWildcard = sel.testWildcard) - case _ => - throw new IllegalArgumentException( - s"Unknown Selector type: ${sel.getClass}") - } - - def deserialize(obj: js.Dynamic): Selector = { - obj.selType.asInstanceOf[String] match { - case "SuiteSelector" => - new SuiteSelector() - case "TestSelector" => - new TestSelector( - obj.testName.asInstanceOf[String]) - case "NestedSuiteSelector" => - new NestedSuiteSelector( - obj.suiteId.asInstanceOf[String]) - case "NestedTestSelector" => - new NestedTestSelector( - obj.suiteId.asInstanceOf[String], - obj.testName.asInstanceOf[String]) - case "TestWildcardSelector" => - new TestWildcardSelector( - obj.testWildcard.asInstanceOf[String]) - case tpe => - throw new IllegalArgumentException(s"Unknown Selector type: $tpe") - } - } - -} diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala index 0317380c1a..fbd355af85 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala @@ -5,120 +5,74 @@ import js.annotation._ import sbt.testing._ -import scala.collection.mutable +import scala.concurrent.{Future, Promise} +import scala.concurrent.duration._ +import scala.concurrent.ExecutionContext.Implicits.global import scala.util.control.NonFatal -import scala.util.{Try, Success, Failure} +import scala.util.Try +import org.scalajs.testcommon._ import org.scalajs.testinterface.ScalaJSClassLoader @JSExportTopLevel("org.scalajs.testinterface.internal.Slave") final class Slave(frameworkName: String, args: js.Array[String], - remoteArgs: js.Array[String]) extends BridgeBase(frameworkName) { - - // State - - private[this] var canSendRunnerMessage = false - - /** Queue for messages from the slave runner to the master runner */ - private[this] val messageQueue = mutable.Queue.empty[String] + remoteArgs: js.Array[String]) { private[this] var runner: Runner = _ - protected def handleMsgImpl(cmd: String, strArg: => String): Unit = { - def jsonArg = js.JSON.parse(strArg) - allowSendRunnerMessage { - cmd match { - case "newRunner" => - reply(newRunner()) - case "execute" => - // No reply here. execute is async - execute(jsonArg) - case "stopSlave" => - reply(stopSlave()) - case "msg" => - val res = incomingRunnerMessage(strArg) - // Only reply if something failed - if (res.isFailure) - reply(res) - case cmd => - throw new IllegalArgumentException(s"Unknown command: $cmd") - } - } - } - - // Runner message handler methods - - private def outboundRunnerMessage(msg: String): Unit = - if (canSendRunnerMessage) sendOutboundRunnerMessage(msg) - else messageQueue.enqueue(msg) - - private def sendOutboundRunnerMessage(msg: String): Unit = { - assert(canSendRunnerMessage) - Com.send(s"msg:$msg") - } - - private def allowSendRunnerMessage[T](body: => T): T = { - try { - canSendRunnerMessage = true - - // Flush the queue - while (!messageQueue.isEmpty) - sendOutboundRunnerMessage(messageQueue.dequeue) - - body - } finally { - canSendRunnerMessage = false - } - } + JSRPC.attach(JSSlaveEndpoints.newRunner)(newRunner _) + JSRPC.attachAsync(JSSlaveEndpoints.execute)(execute _) + JSRPC.attach(JSSlaveEndpoints.stopSlave)(stopSlave _) + JSRPC.attach(JSSlaveEndpoints.msg)(receiveMessage _) // Message handler methods - private def newRunner(): Try[Unit] = { + private def newRunner(req: Unit): Unit = { + val framework = FrameworkLoader.loadFramework(frameworkName) val loader = new ScalaJSClassLoader( scala.scalajs.runtime.environmentInfo.exportsNamespace) - Try(runner = framework.slaveRunner(args.toArray, remoteArgs.toArray, - loader, outboundRunnerMessage)) + runner = framework.slaveRunner(args.toArray, remoteArgs.toArray, + loader, JSRPC.send(JVMSlaveEndpoints.msg)) } - private def execute(data: js.Dynamic): Unit = { + private def execute(req: ExecuteRequest): Future[List[TaskInfo]] = { ensureRunnerExists() - val sTask = data.serializedTask.asInstanceOf[String] - val task = runner.deserializeTask(sTask, str => - TaskDefSerializer.deserialize(js.JSON.parse(str))) - + val task = TaskInfoBuilder.attachTask(req.taskInfo, runner) val eventHandler = new RemoteEventHandler - val colorSupport = data.loggerColorSupport.asInstanceOf[js.Array[Boolean]] val loggers = for { - (withColor, i) <- colorSupport.zipWithIndex + (withColor, i) <- req.loggerColorSupport.zipWithIndex } yield new RemoteLogger(i, withColor) + val promise = Promise[List[TaskInfo]] + def cont(tasks: Array[Task]) = { - val result = Try(js.JSON.stringify(tasks2TaskInfos(tasks, runner))) + val result = Try(tasks.map(TaskInfoBuilder.detachTask(_, runner)).toList) eventHandler.invalidate() loggers.foreach(_.invalidate()) - reply(result) + promise.complete(result) } - val launched = Try(task.execute(eventHandler, loggers.toArray, cont)) + try { + task.execute(eventHandler, loggers.toArray, cont) + } catch { + case NonFatal(t) => + promise.tryFailure(t) + } - if (launched.isFailure) - reply(launched) + promise.future } - private def stopSlave(): Try[Unit] = { + private def stopSlave(req: Unit): Unit = { ensureRunnerExists() - val res = Try { runner.done(); () } - runner = null - res + try runner.done() + finally runner = null } - private def incomingRunnerMessage(msg: String): Try[Unit] = { - ensureRunnerExists() - Try { runner.receiveMessage(msg); () } - } + private def receiveMessage(msg: String): Unit = + runner.receiveMessage(msg) // Private helper classes @@ -134,26 +88,22 @@ final class Slave(frameworkName: String, args: js.Array[String], private class RemoteEventHandler extends Invalidatable with EventHandler { def handle(event: Event): Unit = { ensureValid() - val serEvent = EventSerializer.serialize(event) - Com.send("event:" + js.JSON.stringify(serEvent)) + JSRPC.send(JVMSlaveEndpoints.event)(event) } } private class RemoteLogger(index: Int, val ansiCodesSupported: Boolean) extends Invalidatable with Logger { - def error(msg: String): Unit = send("error", msg) - def warn(msg: String): Unit = send("warn", msg) - def info(msg: String): Unit = send("info", msg) - def debug(msg: String): Unit = send("debug", msg) + import JVMSlaveEndpoints._ - def trace(t: Throwable): Unit = - send("trace", js.JSON.stringify(ThrowableSerializer.serialize(t))) + private def l[T](x: T) = new LogElement(index, x) - private def send(cmd: String, data: String): Unit = { - ensureValid() - Com.send(s"$cmd:$index:$data") - } + def error(msg: String): Unit = JSRPC.send(logError)(l(msg)) + def warn(msg: String): Unit = JSRPC.send(logWarn)(l(msg)) + def info(msg: String): Unit = JSRPC.send(logInfo)(l(msg)) + def debug(msg: String): Unit = JSRPC.send(logDebug)(l(msg)) + def trace(t: Throwable): Unit = JSRPC.send(logTrace)(l(t)) } // Utility methods diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/TaskDefSerializer.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/TaskDefSerializer.scala deleted file mode 100644 index a1f1e7bd61..0000000000 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/TaskDefSerializer.scala +++ /dev/null @@ -1,29 +0,0 @@ -package org.scalajs.testinterface.internal - -import scala.scalajs.js -import js.Dynamic.{literal => lit} -import js.JSConverters._ - -import sbt.testing._ - -private[testinterface] object TaskDefSerializer { - - def serialize(td: TaskDef): js.Dynamic = { - lit(fullyQualifiedName = td.fullyQualifiedName, - fingerprint = FingerprintSerializer.serialize(td.fingerprint), - explicitlySpecified = td.explicitlySpecified, - selectors = td.selectors.map(SelectorSerializer.serialize _).toJSArray) - } - - def deserialize(obj: js.Dynamic): TaskDef = { - val selectors = obj.selectors.asInstanceOf[js.Array[js.Dynamic]] - .map(SelectorSerializer.deserialize _).toArray - - new TaskDef( - obj.fullyQualifiedName.asInstanceOf[String], - FingerprintSerializer.deserialize(obj.fingerprint), - obj.explicitlySpecified.asInstanceOf[Boolean], - selectors) - } - -} diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/TaskInfoBuilder.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/TaskInfoBuilder.scala new file mode 100644 index 0000000000..6aded8a49a --- /dev/null +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/TaskInfoBuilder.scala @@ -0,0 +1,24 @@ +package org.scalajs.testinterface.internal + +import sbt.testing._ + +import org.scalajs.testcommon.{TaskInfo, Serializer} + +private[internal] object TaskInfoBuilder { + def detachTask(task: Task, runner: Runner): TaskInfo = { + def optSerializer(t: TaskDef) = + if (t == task.taskDef) "" + else Serializer.serialize(t) + + new TaskInfo(runner.serializeTask(task, optSerializer), + task.taskDef, task.tags.toList) + } + + def attachTask(info: TaskInfo, runner: Runner): Task = { + def optDeserializer(s: String) = + if (s == "") info.taskDef + else Serializer.deserialize[TaskDef](s) + + runner.deserializeTask(info.serializedTask, optDeserializer) + } +} diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/ThrowableSerializer.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/ThrowableSerializer.scala deleted file mode 100644 index 1e4454ad6b..0000000000 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/ThrowableSerializer.scala +++ /dev/null @@ -1,31 +0,0 @@ -package org.scalajs.testinterface.internal - -import scala.scalajs.js -import js.Dynamic.{literal => lit} -import js.JSConverters._ - -import sbt.testing._ - -object ThrowableSerializer { - - def serialize(t: Throwable): js.Dynamic = { - val res = lit( - `class` = t.getClass().toString, - message = t.getMessage(), - toString = t.toString(), - stackTrace = t.getStackTrace().map(serializeTraceElem).toJSArray) - - if (t.getCause() != null) - res.cause = serialize(t.getCause()) - - res - } - - private def serializeTraceElem(e: StackTraceElement): js.Dynamic = { - lit(className = e.getClassName, - methodName = e.getMethodName, - fileName = e.getFileName, - lineNumber = e.getLineNumber) - } - -} From 0cb966b2ceb89f73d9302d3fc81861b21242d261 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 9 Aug 2017 14:12:45 +0200 Subject: [PATCH 0435/2665] Upgrade to sbt-crossproject 0.2.1. This will be necessary to support sbt 1.x. --- project/Build.scala | 2 +- project/build.sbt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index e3b4031960..f3076794f0 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -804,7 +804,7 @@ object Build { previousArtifactSetting, mimaBinaryIssueFilters ++= BinaryIncompatibilities.SbtPlugin, - addSbtPlugin("org.scala-native" % "sbt-crossproject" % "0.2.0"), + addSbtPlugin("org.scala-native" % "sbt-crossproject" % "0.2.1"), // Add API mappings for sbt (seems they don't export their API URL) apiMappings ++= { diff --git a/project/build.sbt b/project/build.sbt index fac9407d39..f9bdcdff79 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -11,7 +11,7 @@ addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.13") addSbtPlugin("org.scalastyle" % "scalastyle-sbt-plugin" % "0.8.0") -addSbtPlugin("org.scala-native" % "sbt-crossproject" % "0.2.0") +addSbtPlugin("org.scala-native" % "sbt-crossproject" % "0.2.1") libraryDependencies += "org.scala-js" % "closure-compiler-java-6" % "v20160517" From 807e3237a7a9d5c8df12a1733a33e647d441e6be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 3 Aug 2017 05:43:29 +0200 Subject: [PATCH 0436/2665] Clean up `callMethod` in the `Analyzer`. * Replace the boolean parameter `statically` by two distinct methods `callMethod` and `callMethodStatically`. * Rename `delayedCallMethod` into `callMethodResolved`. --- .../core/tools/linker/analyzer/Analyzer.scala | 60 +++++++++++-------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala index b74c112444..aaeaad7051 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala @@ -118,7 +118,7 @@ private final class Analyzer(config: CommonPhaseConfig, withMethod(className, constructor) { clazz => implicit val from = FromCore(origin) clazz.instantiated() - clazz.callMethod(constructor, statically = true) + clazz.callMethodStatically(constructor) } case InstanceTests(origin, className) => @@ -128,8 +128,13 @@ private final class Analyzer(config: CommonPhaseConfig, withClass(className)(_.accessData()(FromCore(origin))) case CallMethod(origin, className, methodName, statically) => - withMethod(className, methodName)( - _.callMethod(methodName, statically)(FromCore(origin))) + withMethod(className, methodName) { classInfo => + implicit val from = FromCore(origin) + if (statically) + classInfo.callMethodStatically(methodName) + else + classInfo.callMethod(methodName) + } case CallStaticMethod(origin, className, methodName) => withMethod(className, methodName)( @@ -566,7 +571,7 @@ private final class Analyzer(config: CommonPhaseConfig, if (kind != ClassKind.NativeJSModuleClass) { instantiated() if (isScalaClass) - callMethod("init___", statically = true) + callMethodStatically("init___") } } } @@ -588,7 +593,7 @@ private final class Analyzer(config: CommonPhaseConfig, ancestors.foreach(_.subclassInstantiated()) for ((methodName, from) <- delayedCalls) - delayedCallMethod(methodName)(from) + callMethodResolved(methodName)(from) } else { assert(isJSClass || isNativeJSClass) @@ -639,28 +644,21 @@ private final class Analyzer(config: CommonPhaseConfig, _errors += MissingClass(this, from) } - def callMethod(methodName: String, statically: Boolean = false)( - implicit from: From): Unit = { - if (isConstructorName(methodName)) { - // constructors must always be called statically - assert(statically, - s"Trying to call dynamically the constructor $this.$methodName from $from") - lookupConstructor(methodName).reachStatic() - } else if (statically) { - assert(!isReflProxyName(methodName), - s"Trying to call statically refl proxy $this.$methodName") - lookupMethod(methodName).reachStatic() - } else { - for (descendentClass <- descendentClasses) { - if (descendentClass.isInstantiated) - descendentClass.delayedCallMethod(methodName) - else - descendentClass.delayedCalls += ((methodName, from)) - } + def callMethod(methodName: String)(implicit from: From): Unit = { + // Constructors must always be called statically + assert(!isConstructorName(methodName), + s"Trying to dynamically call the constructor $this.$methodName from $from") + + for (descendentClass <- descendentClasses) { + if (descendentClass.isInstantiated) + descendentClass.callMethodResolved(methodName) + else + descendentClass.delayedCalls += ((methodName, from)) } } - private def delayedCallMethod(methodName: String)(implicit from: From): Unit = { + private def callMethodResolved(methodName: String)( + implicit from: From): Unit = { if (isReflProxyName(methodName)) { tryLookupReflProxyMethod(methodName).foreach(_.reach(this)) } else { @@ -668,6 +666,16 @@ private final class Analyzer(config: CommonPhaseConfig, } } + def callMethodStatically(methodName: String)(implicit from: From): Unit = { + if (isConstructorName(methodName)) { + lookupConstructor(methodName).reachStatic() + } else { + assert(!isReflProxyName(methodName), + s"Trying to call statically refl proxy $this.$methodName") + lookupMethod(methodName).reachStatic() + } + } + def callStaticMethod(methodName: String)(implicit from: From): Unit = { lookupStaticMethod(methodName).reachStatic() } @@ -795,7 +803,7 @@ private final class Analyzer(config: CommonPhaseConfig, val objectClass = lookupClass(Definitions.ObjectClass) for (methodName <- methods) { if (methodName != "clone__O") - objectClass.callMethod(methodName, statically = true) + objectClass.callMethodStatically(methodName) } } else { val classInfo = lookupClass(className) @@ -809,7 +817,7 @@ private final class Analyzer(config: CommonPhaseConfig, val (className, methods) = methodsCalledStaticallyIterator.next() val classInfo = lookupClass(className) for (methodName <- methods) - classInfo.callMethod(methodName, statically = true) + classInfo.callMethodStatically(methodName) } val staticMethodsCalledIterator = data.staticMethodsCalled.iterator From 5b0fcd08c1c5d6e652f612ff425206799cde2a2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 3 Aug 2017 06:23:56 +0200 Subject: [PATCH 0437/2665] Remove useless members of `Analysis`. --- .../org/scalajs/core/tools/linker/analyzer/Analysis.scala | 5 ----- .../org/scalajs/core/tools/linker/analyzer/Analyzer.scala | 6 +----- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala index 257ac6b70e..e6df845ded 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala @@ -44,13 +44,9 @@ object Analysis { trait ClassInfo { def encodedName: String def kind: ClassKind - def isExported: Boolean def superClass: ClassInfo def ancestors: Seq[ClassInfo] - def descendants: Seq[ClassInfo] def nonExistent: Boolean - def ancestorCount: Int - def descendentClasses: Seq[ClassInfo] /** For a Scala class, it is instantiated with a `New`; for a JS class, * its constructor is accessed with a `JSLoadConstructor` or because it * is needed for a subclass. @@ -62,7 +58,6 @@ object Analysis { def isDataAccessed: Boolean def instantiatedFrom: Seq[From] def isNeededAtAll: Boolean - def isAnyStaticMethodReachable: Boolean def methodInfos: scala.collection.Map[String, MethodInfo] def staticMethodInfos: scala.collection.Map[String, MethodInfo] diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala index aaeaad7051..188e7216b7 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala @@ -237,10 +237,6 @@ private final class Analyzer(config: CommonPhaseConfig, ancestor.descendants += this } - lazy val ancestorCount: Int = - if (superClass == null) 0 - else superClass.ancestorCount + 1 - lazy val descendentClasses = descendants.filter(_.isScalaClass) var isInstantiated: Boolean = false @@ -263,7 +259,7 @@ private final class Analyzer(config: CommonPhaseConfig, isAnyStaticMethodReachable || isAnyDefaultMethodReachable - def isAnyStaticMethodReachable: Boolean = + private def isAnyStaticMethodReachable: Boolean = staticMethodInfos.values.exists(_.isReachable) private def isAnyDefaultMethodReachable = From be9455242608248b1451773b209e3c66d053086b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 3 Aug 2017 06:24:18 +0200 Subject: [PATCH 0438/2665] Clean up: make `Analyzer.ClassInfo.superClass` an `Option`. Previously, it was nullable instead. --- .../core/tools/linker/analyzer/Analysis.scala | 2 +- .../core/tools/linker/analyzer/Analyzer.scala | 31 ++++++++++--------- .../tools/linker/frontend/BaseLinker.scala | 7 ++--- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala index e6df845ded..d0d13f59e3 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala @@ -44,7 +44,7 @@ object Analysis { trait ClassInfo { def encodedName: String def kind: ClassKind - def superClass: ClassInfo + def superClass: Option[ClassInfo] def ancestors: Seq[ClassInfo] def nonExistent: Boolean /** For a Scala class, it is instantiated with a `New`; for a JS class, diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala index 188e7216b7..8e58b483c2 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala @@ -169,9 +169,10 @@ private final class Analyzer(config: CommonPhaseConfig, for (classInfo <- _classInfos.values.filter(_.isDataAccessed).toList) { @tailrec def loop(classInfo: ClassInfo): Unit = { - if (classInfo != null) { - classInfo.accessData() - loop(classInfo.superClass) + classInfo.accessData() + classInfo.superClass match { + case Some(superClass) => loop(superClass) + case None => } } loop(classInfo) @@ -194,7 +195,7 @@ private final class Analyzer(config: CommonPhaseConfig, val isAnyClass = isScalaClass || isJSClass val isExported = data.isExported - var superClass: ClassInfo = _ + var superClass: Option[ClassInfo] = _ var ancestors: List[ClassInfo] = _ val descendants = mutable.ListBuffer.empty[ClassInfo] @@ -222,8 +223,7 @@ private final class Analyzer(config: CommonPhaseConfig, } private[this] def linkClassesImpl(): Unit = { - for (superCls <- data.superClass) - superClass = lookupClass(superCls) + superClass = data.superClass.map(lookupClass) val parents = data.superClass ++: data.interfaces @@ -298,13 +298,14 @@ private final class Analyzer(config: CommonPhaseConfig, @tailrec def tryLookupInherited(ancestorInfo: ClassInfo): Option[MethodInfo] = { - if (ancestorInfo ne null) { - ancestorInfo.methodInfos.get(methodName) match { - case Some(m) if !m.isAbstract => Some(m) - case _ => tryLookupInherited(ancestorInfo.superClass) - } - } else { - None + ancestorInfo.methodInfos.get(methodName) match { + case Some(m) if !m.isAbstract => + Some(m) + case _ => + ancestorInfo.superClass match { + case Some(superClass) => tryLookupInherited(superClass) + case None => None + } } } val existing = @@ -421,7 +422,7 @@ private final class Analyzer(config: CommonPhaseConfig, */ val superClasses = - Iterator.iterate(this)(_.superClass).takeWhile(_ ne null) + Iterator.iterate(this)(_.superClass.orNull).takeWhile(_ ne null) val superClassesThenAncestors = superClasses ++ ancestors.iterator superClassesThenAncestors.map(_.findProxyMatch(proxyName)).collectFirst { @@ -596,7 +597,7 @@ private final class Analyzer(config: CommonPhaseConfig, subclassInstantiated() if (isJSClass) { - superClass.instantiated() + superClass.foreach(_.instantiated()) tryLookupStaticMethod(Definitions.StaticInitializerName).foreach { staticInit => staticInit.reachStatic() } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index 88c961b1f5..8a779d68fb 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -331,9 +331,6 @@ final class BaseLinker(config: CommonPhaseConfig) { p: Analysis.MethodInfo => Boolean = _ => true): MethodDef = { @tailrec def loop(ancestorInfo: Analysis.ClassInfo): MethodDef = { - assert(ancestorInfo != null, - s"Could not find $methodName anywhere in ${classInfo.encodedName}") - val inherited = ancestorInfo.methodInfos.get(methodName) inherited.find(p) match { case Some(m) => @@ -352,7 +349,9 @@ final class BaseLinker(config: CommonPhaseConfig) { } case None => - loop(ancestorInfo.superClass) + assert(ancestorInfo.superClass.isDefined, + s"Could not find $methodName anywhere in ${classInfo.encodedName}") + loop(ancestorInfo.superClass.get) } } From 4b68af00a6a4b873585ef70e4abbd4c322d68f94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 5 Aug 2017 11:53:51 +0200 Subject: [PATCH 0439/2665] Fix #3078: New Analyzer, bye bye Infos. This is a big rewrite of all the infrastructure around `Infos`, and how they are used by the `Analyzer` to compute the reachability analysis. Previously, Infos were a "specified" part of the IR, and were stored in .sjsir files. This was limiting the evolution of the reachability analysis in binary compatible releases, as explained in #3078. With this commit, Infos become almost an implementation detail of the `Analyzer`. They are also known from the `BaseLinker` and `Refiner`, who need to provide inputs to the `Analyzer`, but are otherwise unknown from the rest of the codebase. Obviously, they are not stored in .sjsir files anymore. The `Analyzer` will now lazily read the full `ClassDef`s of classes it needs, and derive Infos from them at link time. In the Refiner, Infos are also lazily derived from `LinkedClass`es, whereas they were eagerly recomputed in `GenIncOptimizer` before. However, whereas before all Infos on the classpath were read and deserialized, now the Analyzer is smarter: it only reads trees and computes Infos for classes that are actually touched by the reachability analysis algorithm. In other words, only classes that are "needed at all" are deserialized. In fact, with this commit, the concept of "needed at all" disappears: classes that appear in the resulting `Analysis` are by construction "needed at all". In order for the Analyzer to know its entry points, .sjsir files store a tiny structure `EntryPointsInfo` containing the encoded name of the class, and a flag indicating whether the class has any entry point. That structure is all that is deserialized for all .sjsir files on the classpath. For incremental runs, the `BaseLinker` and `Refiner` obviously cache the computed Infos between runs, and avoid recomputing them if their inputs (`ClassDef`s or `LinkedClass`es, resp.) have not changed. Since Infos become an implementation detail of the `Analyzer` and its "friends" `BaseLinker` and `Refiner`, the `-i`/`--info` option of `scalajsp` is removed (both in the CLI and in the sbt plugin). The `InfoPrinter` class is consequently removed as well. Moreover, since Infos are computed at link time, there is no point in *checking* them anymore, which means that the `InfoChecker` is removed. --- .../main/scala/org/scalajs/cli/Scalajsp.scala | 12 +- .../scalajs/core/compiler/GenJSFiles.scala | 9 +- .../org/scalajs/core/ir/EntryPointsInfo.scala | 31 ++ .../org/scalajs/core/ir/InfoSerializers.scala | 166 --------- .../scala/org/scalajs/core/ir/Printers.scala | 136 ------- .../org/scalajs/core/ir/Serializers.scala | 73 +++- .../scala/org/scalajs/core/ir/Trees.scala | 21 +- project/Build.scala | 16 +- project/JavaLangObject.scala | 8 +- project/JavaLangString.scala | 8 +- .../sbtplugin/ScalaJSPluginInternal.scala | 25 +- .../closure/ClosureLinkerBackend.scala | 2 +- .../scalajs/core/tools/io/IRFileCache.scala | 10 +- .../scalajs/core/tools/io/VirtualFiles.scala | 46 +-- .../core/tools/linker/LinkedClass.scala | 59 +-- .../core/tools/linker/LinkedMember.scala | 30 -- .../core/tools/linker/LinkingUnit.scala | 12 +- .../scalajs/core/tools/linker/Versioned.scala | 24 ++ .../core/tools/linker/analyzer/Analysis.scala | 12 +- .../core/tools/linker/analyzer/Analyzer.scala | 352 ++++++++++-------- .../core/tools/linker/analyzer}/Infos.scala | 76 ++-- .../linker/backend/emitter/ClassEmitter.scala | 45 ++- .../linker/backend/emitter/Emitter.scala | 14 +- .../backend/emitter/KnowledgeGuardian.scala | 6 +- .../core/tools/linker/checker/IRChecker.scala | 38 +- .../tools/linker/checker/InfoChecker.scala | 158 -------- .../tools/linker/frontend/BaseLinker.scala | 240 +++++++----- .../core/tools/linker/frontend/Refiner.scala | 202 +++++++++- .../frontend/optimizer/GenIncOptimizer.scala | 23 +- .../frontend/optimizer/OptimizerCore.scala | 7 +- 30 files changed, 851 insertions(+), 1010 deletions(-) create mode 100644 ir/src/main/scala/org/scalajs/core/ir/EntryPointsInfo.scala delete mode 100644 ir/src/main/scala/org/scalajs/core/ir/InfoSerializers.scala delete mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedMember.scala create mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/linker/Versioned.scala rename {ir/src/main/scala/org/scalajs/core/ir => tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer}/Infos.scala (92%) delete mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/InfoChecker.scala diff --git a/cli/src/main/scala/org/scalajs/cli/Scalajsp.scala b/cli/src/main/scala/org/scalajs/cli/Scalajsp.scala index 52e0d0318a..786dce8998 100644 --- a/cli/src/main/scala/org/scalajs/cli/Scalajsp.scala +++ b/cli/src/main/scala/org/scalajs/cli/Scalajsp.scala @@ -12,7 +12,7 @@ package org.scalajs.cli import org.scalajs.core.ir import ir.ScalaJSVersions import ir.Trees.{Tree, ClassDef} -import ir.Printers.{InfoPrinter, IRTreePrinter} +import ir.Printers.IRTreePrinter import org.scalajs.core.tools.io._ import scala.collection.immutable.Seq @@ -23,7 +23,6 @@ import java.util.zip.{ZipFile, ZipEntry} object Scalajsp { private case class Options( - infos: Boolean = false, jar: Option[File] = None, fileNames: Seq[String] = Seq.empty) @@ -38,9 +37,6 @@ object Scalajsp { .valueName("") .action { (x, c) => c.copy(jar = Some(x)) } .text("Read *.sjsir file(s) from the given JAR.") - opt[Unit]('i', "infos") - .action { (_, c) => c.copy(infos = true) } - .text("Show DCE infos instead of trees") opt[Unit]('s', "supported") .action { (_,_) => printSupported(); exit(0) } .text("Show supported Scala.js IR versions") @@ -77,11 +73,7 @@ object Scalajsp { private def displayFileContent(vfile: VirtualScalaJSIRFile, opts: Options): Unit = { - if (opts.infos) - new InfoPrinter(stdout).print(vfile.info) - else - new IRTreePrinter(stdout).print(vfile.tree) - + new IRTreePrinter(stdout).print(vfile.tree) stdout.flush() } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSFiles.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSFiles.scala index fe49926a26..a55db832a2 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSFiles.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSFiles.scala @@ -12,7 +12,6 @@ import scala.reflect.internal.pickling.PickleBuffer import java.io._ import org.scalajs.core.ir -import ir.Infos /** Send JS ASTs to files * @@ -26,12 +25,8 @@ trait GenJSFiles extends SubComponent { self: GenJSCode => tree: ir.Trees.ClassDef): Unit = { val outfile = getFileFor(cunit, sym, suffix.getOrElse("") + ".sjsir") val output = outfile.bufferedOutput - try { - ir.InfoSerializers.serialize(output, Infos.generateClassInfo(tree)) - ir.Serializers.serialize(output, tree) - } finally { - output.close() - } + try ir.Serializers.serialize(output, tree) + finally output.close() } private def getFileFor(cunit: CompilationUnit, sym: Symbol, diff --git a/ir/src/main/scala/org/scalajs/core/ir/EntryPointsInfo.scala b/ir/src/main/scala/org/scalajs/core/ir/EntryPointsInfo.scala new file mode 100644 index 0000000000..16a7eb37d3 --- /dev/null +++ b/ir/src/main/scala/org/scalajs/core/ir/EntryPointsInfo.scala @@ -0,0 +1,31 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js IR ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.core.ir + +import Trees._ + +final class EntryPointsInfo( + val encodedName: String, + val hasEntryPoint: Boolean +) + +object EntryPointsInfo { + def forClassDef(classDef: ClassDef): EntryPointsInfo = { + val hasEntryPoint = { + classDef.topLevelExportDefs.nonEmpty || + classDef.memberDefs.exists { + case m: MethodDef => + m.static && m.encodedName == Definitions.StaticInitializerName + case _ => + false + } + } + new EntryPointsInfo(classDef.name.name, hasEntryPoint) + } +} diff --git a/ir/src/main/scala/org/scalajs/core/ir/InfoSerializers.scala b/ir/src/main/scala/org/scalajs/core/ir/InfoSerializers.scala deleted file mode 100644 index d9160a6022..0000000000 --- a/ir/src/main/scala/org/scalajs/core/ir/InfoSerializers.scala +++ /dev/null @@ -1,166 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js IR ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.core.ir - -import java.io._ - -import Infos._ - -object InfoSerializers { - - /** Scala.js IR File Magic Number - * - * CA FE : first part of magic number of Java class files - * 4A 53 : "JS" in ASCII - * - */ - final val IRMagicNumber = 0xCAFE4A53 - - def serialize(stream: OutputStream, classInfo: ClassInfo): Unit = { - new Serializer().serialize(stream, classInfo) - } - - def deserialize(stream: InputStream): ClassInfo = { - deserializeWithVersion(stream)._2 - } - - def deserializeWithVersion(stream: InputStream): (String, ClassInfo) = { - new Deserializer(stream).deserialize() - } - - private final class Serializer { - def serialize(stream: OutputStream, classInfo: ClassInfo): Unit = { - val s = new DataOutputStream(stream) - - def writeSeq[A](seq: Seq[A])(writeElem: A => Unit): Unit = { - s.writeInt(seq.size) - seq.foreach(writeElem) - } - - def writeStrings(seq: Seq[String]): Unit = - writeSeq(seq)(s.writeUTF(_)) - - // Write the Scala.js IR magic number - s.writeInt(IRMagicNumber) - - // Write the Scala.js Version - s.writeUTF(ScalaJSVersions.binaryEmitted) - - import classInfo._ - s.writeUTF(encodedName) - s.writeBoolean(isExported) - s.writeByte(ClassKind.toByte(kind)) - s.writeUTF(superClass.getOrElse("")) - writeStrings(interfaces) - - def writeMethodInfo(methodInfo: MethodInfo): Unit = { - import methodInfo._ - - def writePerClassStrings(m: Map[String, List[String]]): Unit = { - writeSeq(m.toSeq) { - case (cls, items) => s.writeUTF(cls); writeStrings(items) - } - } - - s.writeUTF(encodedName) - s.writeBoolean(isStatic) - s.writeBoolean(isAbstract) - s.writeBoolean(isExported) - writePerClassStrings(staticFieldsRead) - writePerClassStrings(staticFieldsWritten) - writePerClassStrings(methodsCalled) - writePerClassStrings(methodsCalledStatically) - writePerClassStrings(staticMethodsCalled) - writeStrings(instantiatedClasses) - writeStrings(accessedModules) - writeStrings(usedInstanceTests) - writeStrings(accessedClassData) - } - - writeSeq(methods)(writeMethodInfo(_)) - - s.flush() - } - } - - private final class Deserializer(stream: InputStream) { - private[this] val input = new DataInputStream(stream) - - def readList[A](readElem: => A): List[A] = - List.fill(input.readInt())(readElem) - - def readStrings(): List[String] = - readList(input.readUTF()) - - def deserialize(): (String, ClassInfo) = { - val version = readHeader() - - import input._ - - val encodedName = readUTF() - val isExported = readBoolean() - val kind = ClassKind.fromByte(readByte()) - val superClass0 = readUTF() - val superClass = if (superClass0 == "") None else Some(superClass0) - val interfaces = readList(readUTF()) - - def readMethod(): MethodInfo = { - def readPerClassStrings(): Map[String, List[String]] = - readList(readUTF() -> readStrings()).toMap - - val encodedName = readUTF() - val isStatic = readBoolean() - val isAbstract = readBoolean() - val isExported = readBoolean() - val staticFieldsRead = readPerClassStrings() - val staticFieldsWritten = readPerClassStrings() - val methodsCalled = readPerClassStrings() - val methodsCalledStatically = readPerClassStrings() - val staticMethodsCalled = readPerClassStrings() - val instantiatedClasses = readStrings() - val accessedModules = readStrings() - val usedInstanceTests = readStrings() - val accessedClassData = readStrings() - MethodInfo(encodedName, isStatic, isAbstract, isExported, - staticFieldsRead, staticFieldsWritten, - methodsCalled, methodsCalledStatically, staticMethodsCalled, - instantiatedClasses, accessedModules, usedInstanceTests, - accessedClassData) - } - - val methods = readList(readMethod()) - - val info = ClassInfo(encodedName, isExported, kind, - superClass, interfaces, methods) - - (version, info) - } - - /** Reads the Scala.js IR header and verifies the version compatibility. - * Returns the emitted binary version. - */ - def readHeader(): String = { - // Check magic number - if (input.readInt() != IRMagicNumber) - throw new IOException("Not a Scala.js IR file") - - // Check that we support this version of the IR - val version = input.readUTF() - val supported = ScalaJSVersions.binarySupported - if (!supported.contains(version)) { - throw new IRVersionNotSupportedException(version, supported, - s"This version ($version) of Scala.js IR is not supported. " + - s"Supported versions are: ${supported.mkString(", ")}") - } - - version - } - } -} diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index 5370c70527..5153e2717c 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -19,7 +19,6 @@ import java.io.Writer import Position._ import Trees._ import Types._ -import Infos._ import Utils.printEscapeJS object Printers { @@ -1000,139 +999,4 @@ object Printers { def complete(): Unit = () } - class InfoPrinter(protected val out: Writer) extends IndentationManager { - def printClassInfoHeader(classInfo: ClassInfo): Unit = { - import classInfo._ - print("encodedName: ") - printEscapeJS(encodedName, out) - println() - print("isExported: ") - print(isExported.toString) - println() - print("kind: ") - print(kind.toString) - println() - print("superClass: ") - print(if (superClass == null) "null" else superClass.toString) - println() - - if (interfaces.nonEmpty) { - print("interfaces: [") - var rest = interfaces - while (rest.nonEmpty) { - printEscapeJS(rest.head, out) - rest = rest.tail - if (rest.nonEmpty) - print(", ") - } - print(']') - println() - } - } - - def print(classInfo: ClassInfo): Unit = { - import classInfo._ - - printClassInfoHeader(classInfo) - - print("methods:") - indent(); println() - methods.foreach((mi: MethodInfo) => print(mi)) - undent(); println() - } - - def print(methodInfo: MethodInfo): Unit = { - import methodInfo._ - printEscapeJS(encodedName, out) - print(":") - indent(); println() - - if (isStatic) { - print("isStatic: ") - print(isStatic.toString) - println() - } - if (isAbstract) { - print("isAbstract: ") - print(isAbstract.toString) - println() - } - if (isExported) { - print("isExported: ") - print(isExported.toString) - println() - } - if (methodsCalled.nonEmpty) { - print("methodsCalled:") - indent(); println() - val iter = methodsCalled.iterator - while (iter.hasNext) { - val (cls, callers) = iter.next() - printEscapeJS(cls, out) - printRow(callers, ": [", ", ", "]") - if (iter.hasNext) - println() - } - undent(); println() - } - if (methodsCalledStatically.nonEmpty) { - print("methodsCalledStatically:") - indent(); println() - val iter = methodsCalledStatically.iterator - while (iter.hasNext) { - val (cls, callers) = iter.next - printEscapeJS(cls, out) - printRow(callers, ": [", ", ", "]") - if (iter.hasNext) - println() - } - undent(); println() - } - if (staticMethodsCalled.nonEmpty) { - print("staticMethodsCalled:") - indent(); println() - val iter = staticMethodsCalled.iterator - while (iter.hasNext) { - val (cls, callers) = iter.next() - printEscapeJS(cls, out) - printRow(callers, ": [", ", ", "]") - if (iter.hasNext) - println() - } - undent(); println() - } - if (instantiatedClasses.nonEmpty) - printRow(instantiatedClasses, "instantiatedClasses: [", ", ", "]") - if (accessedModules.nonEmpty) - printRow(accessedModules, "accessedModules: [", ", ", "]") - if (usedInstanceTests.nonEmpty) - printRow(usedInstanceTests, "usedInstanceTests: [", ", ", "]") - if (accessedClassData.nonEmpty) - printRow(accessedClassData, "accessedClassData: [", ", ", "]") - - undent(); println() - } - - protected def printRow(ts: List[String], start: String, sep: String, - end: String): Unit = { - print(start) - var rest = ts - while (rest.nonEmpty) { - print(rest.head) - rest = rest.tail - if (rest.nonEmpty) - print(sep) - } - print(end) - } - - protected def print(s: String): Unit = - out.write(s) - - protected def print(c: Int): Unit = - out.write(c) - - def complete(): Unit = () - } - } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index aa30b63f29..f43c33a62f 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -25,12 +25,24 @@ import Tags._ import Utils.JumpBackByteArrayOutputStream object Serializers { + /** Scala.js IR File Magic Number + * + * CA FE : first part of magic number of Java class files + * 4A 53 : "JS" in ASCII + * + */ + final val IRMagicNumber = 0xCAFE4A53 + def serialize(stream: OutputStream, classDef: ClassDef): Unit = { new Serializer().serialize(stream, classDef) } - def deserialize(stream: InputStream, version: String): ClassDef = { - new Deserializer(stream, version).deserialize() + def deserializeEntryPointsInfo(stream: InputStream): EntryPointsInfo = { + new Deserializer(stream).deserializeEntryPointsInfo() + } + + def deserialize(stream: InputStream): ClassDef = { + new Deserializer(stream).deserialize() } // true for easier debugging (not for "production", it adds 8 bytes per node) @@ -93,6 +105,17 @@ object Serializers { val s = new DataOutputStream(stream) + // Write the Scala.js IR magic number + s.writeInt(IRMagicNumber) + + // Write the Scala.js Version + s.writeUTF(ScalaJSVersions.binaryEmitted) + + // Write the entry points info + val entryPointsInfo = EntryPointsInfo.forClassDef(classDef) + s.writeUTF(entryPointsInfo.encodedName) + s.writeBoolean(entryPointsInfo.hasEntryPoint) + // Emit the files s.writeInt(files.size) files.foreach(f => s.writeUTF(f.toString)) @@ -702,21 +725,55 @@ object Serializers { } } - private final class Deserializer(stream: InputStream, sourceVersion: String) { + private final class Deserializer(stream: InputStream) { private[this] val input = new DataInputStream(stream) - private[this] val files = - Array.fill(input.readInt())(new URI(input.readUTF())) - - private[this] val strings = - Array.fill(input.readInt())(input.readUTF()) + private[this] var sourceVersion: String = _ + private[this] var files: Array[URI] = _ + private[this] var strings: Array[String] = _ private[this] var lastPosition: Position = Position.NoPosition + def deserializeEntryPointsInfo(): EntryPointsInfo = { + sourceVersion = readHeader() + readEntryPointsInfo() + } + def deserialize(): ClassDef = { + sourceVersion = readHeader() + readEntryPointsInfo() // discarded + files = Array.fill(input.readInt())(new URI(input.readUTF())) + strings = Array.fill(input.readInt())(input.readUTF()) readClassDef() } + /** Reads the Scala.js IR header and verifies the version compatibility. + * + * @return the binary version that was read + */ + private def readHeader(): String = { + // Check magic number + if (input.readInt() != IRMagicNumber) + throw new IOException("Not a Scala.js IR file") + + // Check that we support this version of the IR + val version = input.readUTF() + val supported = ScalaJSVersions.binarySupported + if (!supported.contains(version)) { + throw new IRVersionNotSupportedException(version, supported, + s"This version ($version) of Scala.js IR is not supported. " + + s"Supported versions are: ${supported.mkString(", ")}") + } + + version + } + + private def readEntryPointsInfo(): EntryPointsInfo = { + val encodedName = input.readUTF() + val hasEntryPoint = input.readBoolean() + new EntryPointsInfo(encodedName, hasEntryPoint) + } + def readTree(): Tree = { val pos = readPosition() readTreeFromTag(input.readByte())(pos) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 62f53fc6db..d09e17dcfa 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -813,7 +813,12 @@ object Trees { // Class members - sealed abstract class MemberDef extends IRNode + sealed abstract class MemberDef extends IRNode { + val static: Boolean + val name: PropertyName + + def encodedName: String = name.encodedName + } case class FieldDef(static: Boolean, name: PropertyName, ftpe: Type, mutable: Boolean)( @@ -830,7 +835,19 @@ object Trees { // Top-level export defs - sealed abstract class TopLevelExportDef extends IRNode + sealed abstract class TopLevelExportDef extends IRNode { + final def topLevelExportName: String = this match { + case TopLevelConstructorExportDef(name, _, _) => name + case TopLevelModuleExportDef(name) => name + case TopLevelJSClassExportDef(name) => name + + case TopLevelMethodExportDef(MethodDef(_, propName, _, _, _)) => + val StringLiteral(name) = propName + name + + case TopLevelFieldExportDef(name, _) => name + } + } case class TopLevelConstructorExportDef(name: String, args: List[ParamDef], body: Tree)(implicit val pos: Position) extends TopLevelExportDef diff --git a/project/Build.scala b/project/Build.scala index e3b4031960..8e1516ffd4 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -830,20 +830,16 @@ object Build { } private def serializeHardcodedIR(base: File, - infoAndTree: (ir.Infos.ClassInfo, ir.Trees.ClassDef)): File = { + classDef: ir.Trees.ClassDef): File = { // We assume that there are no weird characters in the full name - val fullName = ir.Definitions.decodeClassName(infoAndTree._1.encodedName) + val fullName = ir.Definitions.decodeClassName(classDef.name.name) val output = base / (fullName.replace('.', '/') + ".sjsir") if (!output.exists()) { IO.createDirectory(output.getParentFile) val stream = new BufferedOutputStream(new FileOutputStream(output)) - try { - ir.InfoSerializers.serialize(stream, infoAndTree._1) - ir.Serializers.serialize(stream, infoAndTree._2) - } finally { - stream.close() - } + try ir.Serializers.serialize(stream, classDef) + finally stream.close() } output } @@ -861,8 +857,8 @@ object Build { resourceGenerators in Compile += Def.task { val base = (resourceManaged in Compile).value Seq( - serializeHardcodedIR(base, JavaLangObject.InfoAndTree), - serializeHardcodedIR(base, JavaLangString.InfoAndTree) + serializeHardcodedIR(base, JavaLangObject.TheClassDef), + serializeHardcodedIR(base, JavaLangString.TheClassDef) ) }.taskValue, scalaJSExternalCompileSettings diff --git a/project/JavaLangObject.scala b/project/JavaLangObject.scala index 9664c6caeb..2be487dd3e 100644 --- a/project/JavaLangObject.scala +++ b/project/JavaLangObject.scala @@ -5,7 +5,6 @@ import org.scalajs.core.ir import ir._ import ir.Definitions._ -import ir.Infos._ import ir.Trees._ import ir.Types._ import ir.Position.NoPosition @@ -18,7 +17,7 @@ import ir.Position.NoPosition */ object JavaLangObject { - val InfoAndTree = { + val TheClassDef = { implicit val DummyPos = NoPosition // ClassType(Object) is normally invalid, but not in this class def @@ -164,10 +163,7 @@ object JavaLangObject { ), Nil)(OptimizerHints.empty) - val hashedClassedDef = Hashers.hashClassDef(classDef) - val info = generateClassInfo(hashedClassedDef) - - (info, hashedClassedDef) + Hashers.hashClassDef(classDef) } } diff --git a/project/JavaLangString.scala b/project/JavaLangString.scala index 07920b10b3..0334b06a76 100644 --- a/project/JavaLangString.scala +++ b/project/JavaLangString.scala @@ -5,7 +5,6 @@ import org.scalajs.core.ir import ir._ import ir.Definitions._ -import ir.Infos._ import ir.Trees._ import ir.Types._ import ir.Position.NoPosition @@ -17,7 +16,7 @@ import ir.Position.NoPosition */ object JavaLangString { - val InfoAndTree = { + val TheClassDef = { implicit val DummyPos = NoPosition val ThisType = ClassType(StringClass) @@ -158,10 +157,7 @@ object JavaLangString { ), Nil)(OptimizerHints.empty) - val hashedClassDef = Hashers.hashClassDef(classDef) - val info = generateClassInfo(hashedClassDef) - - (info, hashedClassDef) + Hashers.hashClassDef(classDef) } } diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 51a4a1ea9e..b23f20c75c 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -24,7 +24,7 @@ import org.scalajs.jsenv.nodejs.NodeJSEnv import org.scalajs.core.ir import org.scalajs.core.ir.Utils.escapeJS import org.scalajs.core.ir.ScalaJSVersions -import org.scalajs.core.ir.Printers.{InfoPrinter, IRTreePrinter} +import org.scalajs.core.ir.Printers.IRTreePrinter import org.scalajs.testadapter.{FrameworkDetector, HTMLRunnerBuilder} @@ -236,26 +236,14 @@ object ScalaJSPluginInternal { ) private def scalajspSettings: Seq[Setting[_]] = { - case class Options( - infos: Boolean = false - ) - - val optionsParser: Parser[Options] = { - token(OptSpace ~> ( - (literal("-i") | "--infos") ^^^ ((_: Options).copy(infos = true)) - )).* map { - fns => Function.chain(fns)(Options()) - } - } - def sjsirFileOnClasspathParser( relPaths: Seq[String]): Parser[String] = { OptSpace ~> StringBasic .examples(ScalajspUtils.relPathsExamples(relPaths)) } - def scalajspParser(state: State, relPaths: Seq[String]) = - optionsParser ~ sjsirFileOnClasspathParser(relPaths) + def scalajspParser(state: State, relPaths: Seq[String]): Parser[String] = + sjsirFileOnClasspathParser(relPaths) val parser = loadForParser(sjsirFilesOnClasspath) { (state, relPaths) => scalajspParser(state, relPaths.getOrElse(Nil)) @@ -267,17 +255,14 @@ object ScalaJSPluginInternal { }.storeAs(sjsirFilesOnClasspath).triggeredBy(scalaJSIR).value, scalajsp := { - val (options, relPath) = parser.parsed + val relPath = parser.parsed val vfile = scalaJSIR.value.data .find(_.relativePath == relPath) .getOrElse(throw new FileNotFoundException(relPath)) val stdout = new java.io.PrintWriter(System.out) - if (options.infos) - new InfoPrinter(stdout).print(vfile.info) - else - new IRTreePrinter(stdout).print(vfile.tree) + new IRTreePrinter(stdout).print(vfile.tree) stdout.flush() logIRCacheStats(streams.value.log) diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala index 0e7a85f75c..1abac71f7b 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala @@ -113,7 +113,7 @@ final class ClosureLinkerBackend(config: LinkerBackend.Config) val exportedPropertyNames = for { classDef <- linkingUnit.classDefs member <- classDef.exportedMembers - name <- exportName(member.tree) + name <- exportName(member.value) if isValidIdentifier(name) } yield { name diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala index 59fbfd20a9..73c90656c0 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala @@ -16,7 +16,8 @@ import java.net.URI import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.atomic.AtomicInteger -import org.scalajs.core.ir +import org.scalajs.core.ir.EntryPointsInfo +import org.scalajs.core.ir.Trees.ClassDef /** Centralized Scala.js IR cache. * @@ -227,15 +228,12 @@ final class IRFileCache { private[this] var _irFile: VirtualRelativeScalaJSIRFile) extends VirtualRelativeScalaJSIRFile { - import ir.Trees._ - import ir.Infos - @volatile private[this] var _tree: ClassDef = null override val path: String = _irFile.path override val version: Option[String] = _irFile.version - override val info: Infos.ClassInfo = _irFile.info + override val entryPointsInfo: EntryPointsInfo = _irFile.entryPointsInfo override val relativePath: String = _irFile.relativePath override def exists: Boolean = { @@ -254,8 +252,6 @@ final class IRFileCache { _tree } - def infoAndTree: (Infos.ClassInfo, ClassDef) = (info, tree) - /** Must be called under synchronization only */ private def loadTree(): Unit = clearOnThrow { statsTreesRead.incrementAndGet() diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala index c67be0d264..6ae6f67a7e 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala @@ -139,16 +139,12 @@ trait ScalaJSIRContainer extends VirtualFile { * It contains the class info and the IR tree. */ trait VirtualScalaJSIRFile extends VirtualFile { - /** Class info of this file. */ - def info: ir.Infos.ClassInfo = - infoAndTree._1 + /** Entry points information for this file. */ + def entryPointsInfo: ir.EntryPointsInfo = + ir.EntryPointsInfo.forClassDef(tree) /** IR Tree of this file. */ - def tree: ir.Trees.ClassDef = - infoAndTree._2 - - /** Class info and IR tree of this file. */ - def infoAndTree: (ir.Infos.ClassInfo, ir.Trees.ClassDef) + def tree: ir.Trees.ClassDef } trait VirtualRelativeScalaJSIRFile extends VirtualScalaJSIRFile @@ -158,34 +154,28 @@ trait VirtualRelativeScalaJSIRFile extends VirtualScalaJSIRFile /** Base trait for virtual Scala.js IR files that are serialized as binary file. */ -trait VirtualSerializedScalaJSIRFile extends VirtualBinaryFile with VirtualScalaJSIRFile { - /** Class info of this file. */ - override def info: ir.Infos.ClassInfo = { +trait VirtualSerializedScalaJSIRFile + extends VirtualBinaryFile with VirtualScalaJSIRFile { + + override def entryPointsInfo: ir.EntryPointsInfo = { // Overridden to read only the necessary parts + withInputStream(ir.Serializers.deserializeEntryPointsInfo) + } + + override def tree: ir.Trees.ClassDef = + withInputStream(ir.Serializers.deserialize) + + @inline + private def withInputStream[A](f: InputStream => A): A = { val stream = inputStream try { - ir.InfoSerializers.deserialize(stream) + f(stream) } catch { case e: ir.IRVersionNotSupportedException => throw new ir.IRVersionNotSupportedException(e.version, e.supported, - s"Failed to deserialize info of file compiled with Scala.js ${e.version}" + + "Failed to deserialize a file compiled with Scala.js ${e.version}" + s" (supported: ${e.supported.mkString(", ")}): $path", e) - case e: IOException => - throw new IOException(s"Failed to deserialize info of $path", e) - } finally { - stream.close() - } - } - - /** Class info and IR tree of this file. */ - override def infoAndTree: (ir.Infos.ClassInfo, ir.Trees.ClassDef) = { - val stream = inputStream - try { - val (version, info) = ir.InfoSerializers.deserializeWithVersion(stream) - val tree = ir.Serializers.deserialize(stream, version) - (info, tree) - } catch { case e: IOException => throw new IOException(s"Failed to deserialize $path", e) } finally { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala index 44c5051060..7afa1ec464 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala @@ -14,7 +14,6 @@ import scala.collection.mutable import org.scalajs.core.ir import ir.Trees._ import ir.Position -import ir.Infos import ir.ClassKind import ir.Definitions @@ -41,12 +40,11 @@ final class LinkedClass( val interfaces: List[Ident], val jsNativeLoadSpec: Option[JSNativeLoadSpec], val fields: List[FieldDef], - val staticMethods: List[LinkedMember[MethodDef]], - val memberMethods: List[LinkedMember[MethodDef]], - val abstractMethods: List[LinkedMember[MethodDef]], - val exportedMembers: List[LinkedMember[MemberDef]], - val topLevelExports: List[TopLevelExportDef], - val topLevelExportsInfo: Option[Infos.MethodInfo], + val staticMethods: List[Versioned[MethodDef]], + val memberMethods: List[Versioned[MethodDef]], + val abstractMethods: List[Versioned[MethodDef]], + val exportedMembers: List[Versioned[MemberDef]], + val topLevelExports: List[Versioned[TopLevelExportDef]], val optimizerHints: OptimizerHints, val pos: Position, @@ -57,37 +55,20 @@ final class LinkedClass( val hasRuntimeTypeInfo: Boolean, val version: Option[String]) { - // Helpers to give Info-Like access def encodedName: String = name.name - def isExported: Boolean = topLevelExports.nonEmpty - /** Names of all top-level exports in this class. */ - def topLevelExportNames: List[String] = topLevelExports.map { - case TopLevelConstructorExportDef(name, _, _) => name - case TopLevelModuleExportDef(name) => name - case TopLevelJSClassExportDef(name) => name - - case TopLevelMethodExportDef(MethodDef(_, propName, _, _, _)) => - val StringLiteral(name) = propName - name - - case TopLevelFieldExportDef(name, _) => name + val hasEntryPoint: Boolean = { + topLevelExports.nonEmpty || + staticMethods.exists { m => + m.value.encodedName == Definitions.StaticInitializerName + } } - def fullName: String = Definitions.decodeClassName(encodedName) - - def toInfo: Infos.ClassInfo = { - val methodInfos = ( - staticMethods.map(_.info) ++ - memberMethods.map(_.info) ++ - abstractMethods.map(_.info) ++ - exportedMembers.map(_.info) ++ - topLevelExportsInfo - ) + /** Names of all top-level exports in this class. */ + def topLevelExportNames: List[String] = + topLevelExports.map(_.value.topLevelExportName) - Infos.ClassInfo(encodedName, isExported, kind, superClass.map(_.name), - interfaces.map(_.name), methodInfos) - } + def fullName: String = Definitions.decodeClassName(encodedName) def copy( name: Ident = this.name, @@ -96,12 +77,11 @@ final class LinkedClass( interfaces: List[Ident] = this.interfaces, jsNativeLoadSpec: Option[JSNativeLoadSpec] = this.jsNativeLoadSpec, fields: List[FieldDef] = this.fields, - staticMethods: List[LinkedMember[MethodDef]] = this.staticMethods, - memberMethods: List[LinkedMember[MethodDef]] = this.memberMethods, - abstractMethods: List[LinkedMember[MethodDef]] = this.abstractMethods, - exportedMembers: List[LinkedMember[MemberDef]] = this.exportedMembers, - topLevelExports: List[TopLevelExportDef] = this.topLevelExports, - topLevelExportsInfo: Option[Infos.MethodInfo] = this.topLevelExportsInfo, + staticMethods: List[Versioned[MethodDef]] = this.staticMethods, + memberMethods: List[Versioned[MethodDef]] = this.memberMethods, + abstractMethods: List[Versioned[MethodDef]] = this.abstractMethods, + exportedMembers: List[Versioned[MemberDef]] = this.exportedMembers, + topLevelExports: List[Versioned[TopLevelExportDef]] = this.topLevelExports, optimizerHints: OptimizerHints = this.optimizerHints, pos: Position = this.pos, ancestors: List[String] = this.ancestors, @@ -121,7 +101,6 @@ final class LinkedClass( abstractMethods, exportedMembers, topLevelExports, - topLevelExportsInfo, optimizerHints, pos, ancestors, diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedMember.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedMember.scala deleted file mode 100644 index 1618fa7b30..0000000000 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedMember.scala +++ /dev/null @@ -1,30 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.core.tools.linker - -import org.scalajs.core.ir -import ir.Trees._ -import ir.Infos - -/** A MethodDef or a PropertyDef after linking. - * - * Note that the [[version]] is relative to the identity of a LinkedMember. - * The definition of identity varies as linked members progress through the - * linking pipeline, but it only gets stronger, i.e., if two linked members - * are id-different at phase P, then they must also be id-different at phase - * P+1. The converse is not true. This guarantees that versions can be used - * reliably to determine at phase P+1 whether a linked member coming from - * phase P must be reprocessed. - */ -final class LinkedMember[+T <: MemberDef]( - val info: Infos.MethodInfo, - val tree: T, - val version: Option[String] -) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala index 6d54cbd996..6db0dbd0ce 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala @@ -1,19 +1,9 @@ package org.scalajs.core.tools.linker -import org.scalajs.core.ir -import ir.{Definitions, Infos} - import org.scalajs.core.tools.linker.standard._ final class LinkingUnit private[linker] ( val coreSpec: CoreSpec, val classDefs: List[LinkedClass], - private[linker] val infos: Map[String, Infos.ClassInfo], val moduleInitializers: List[ModuleInitializer] -) { - private[linker] def updated(classDefs: List[LinkedClass]): LinkingUnit = { - val newInfos = - infos ++ classDefs.map(cd => cd.encodedName -> cd.toInfo) - new LinkingUnit(coreSpec, classDefs, newInfos, moduleInitializers) - } -} +) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Versioned.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Versioned.scala new file mode 100644 index 0000000000..b084af24f3 --- /dev/null +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Versioned.scala @@ -0,0 +1,24 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.core.tools.linker + +import org.scalajs.core.ir +import ir.Trees._ + +/** A versioned thing, accompanied by its version. + * + * Note that, as used in `LinkingUnit`, the [[version]] is relative to the + * identity of the versioned thing. The definition of identity varies as + * items progress through the linking pipeline, but it only gets stronger, + * i.e., if two items are id-different at phase P, then they must also be + * id-different at phase P+1. The converse is not true. This guarantees that + * versions can be reliably used to determine at phase P+1 whether the given + * item coming from phase P must be reprocessed. + */ +final class Versioned[+T](val value: T, val version: Option[String]) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala index d0d13f59e3..0836e7c5f9 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala @@ -17,7 +17,6 @@ import org.scalajs.core.tools.logging._ import org.scalajs.core.ir import ir.ClassKind -import ir.Infos import ir.Definitions.{decodeClassName, decodeMethodName} /** Reachability graph produced by the [[Analyzer]]. @@ -45,6 +44,7 @@ object Analysis { def encodedName: String def kind: ClassKind def superClass: Option[ClassInfo] + def interfaces: Seq[ClassInfo] def ancestors: Seq[ClassInfo] def nonExistent: Boolean /** For a Scala class, it is instantiated with a `New`; for a JS class, @@ -56,8 +56,8 @@ object Analysis { def isModuleAccessed: Boolean def areInstanceTestsUsed: Boolean def isDataAccessed: Boolean + def linkedFrom: Seq[From] def instantiatedFrom: Seq[From] - def isNeededAtAll: Boolean def methodInfos: scala.collection.Map[String, MethodInfo] def staticMethodInfos: scala.collection.Map[String, MethodInfo] @@ -154,6 +154,7 @@ object Analysis { } final case class MissingJavaLangObjectClass(from: From) extends Error + final case class InvalidJavaLangObjectClass(from: From) extends Error final case class CycleInInheritanceChain(cycle: List[ClassInfo], from: From) extends Error final case class MissingClass(info: ClassInfo, from: From) extends Error final case class NotAModule(info: ClassInfo, from: From) extends Error @@ -162,6 +163,7 @@ object Analysis { sealed trait From final case class FromMethod(methodInfo: MethodInfo) extends From + final case class FromClass(classInfo: ClassInfo) extends From final case class FromCore(moduleName: String) extends From case object FromExports extends From @@ -169,6 +171,9 @@ object Analysis { val headMsg = error match { case MissingJavaLangObjectClass(_) => "Fatal error: java.lang.Object is missing" + case InvalidJavaLangObjectClass(_) => + "Fatal error: java.lang.Object is invalid (it must be a Scala class " + + "without superclass nor any implemented interface)" case CycleInInheritanceChain(cycle, _) => ("Fatal error: cycle in inheritance chain involving " + cycle.map(_.displayName).mkString(", ")) @@ -231,6 +236,9 @@ object Analysis { involvedClasses ++= methodInfo.instantiatedSubclasses loopTrace(methodInfo.calledFrom.lastOption) } + case FromClass(classInfo) => + log(level, s"$verb from ${classInfo.displayName}") + loopTrace(classInfo.linkedFrom.lastOption) case FromCore(moduleName) => log(level, s"$verb from core module $moduleName") case FromExports => diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala index 8e58b483c2..3a6d842dc2 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala @@ -14,17 +14,22 @@ import scala.annotation.tailrec import scala.collection.mutable import org.scalajs.core.ir -import ir.{ClassKind, Definitions, Infos} +import ir.{ClassKind, Definitions} import Definitions._ import org.scalajs.core.tools.linker._ import org.scalajs.core.tools.linker.standard._ +import Analysis._ + private final class Analyzer(config: CommonPhaseConfig, symbolRequirements: SymbolRequirement, - allowAddingSyntheticMethods: Boolean) extends Analysis { + allowAddingSyntheticMethods: Boolean, + inputProvider: Analyzer.InputProvider) + extends Analysis { + import Analyzer._ - import Analysis._ + import ClassInfo.newClassInfo private[this] val _classInfos = mutable.Map.empty[String, ClassInfo] private[this] val _errors = mutable.Buffer.empty[Error] @@ -34,59 +39,48 @@ private final class Analyzer(config: CommonPhaseConfig, def classInfos: scala.collection.Map[String, Analysis.ClassInfo] = _classInfos def errors: Seq[Error] = _errors - private def lookupClass(encodedName: String): ClassInfo = { - _classInfos.get(encodedName) match { - case Some(info) => info - case None => - val c = new ClassInfo(createMissingClassInfo(encodedName)) - _classInfos += encodedName -> c - c.nonExistent = true - c.linkClasses() - c - } - } - - def computeReachability(allData: Seq[Infos.ClassInfo]): Unit = { + def computeReachability(): Unit = { require(_classInfos.isEmpty, "Cannot run the same Analyzer multiple times") - // Load data - for (classData <- allData) - _classInfos += classData.encodedName -> new ClassInfo(classData) + implicit val from = fromAnalyzer - linkClasses() + // Load the java.lang.Object class, and validate it + inputProvider.loadInfo(Definitions.ObjectClass) match { + case None => + _errors += MissingJavaLangObjectClass(fromAnalyzer) + case Some(data) => + if (data.kind != ClassKind.Class || data.superClass.isDefined || + data.interfaces.nonEmpty) { + _errors += InvalidJavaLangObjectClass(fromAnalyzer) + } else { + newClassInfo(data, nonExistent = false) + } + } - if (errors.nonEmpty) { - /* If we have errors after linkClasses(), we're in deep trouble, and - * we cannot continue. + if (_errors.nonEmpty) { + /* If java.lang.Object was missing or invalid, we're in deep trouble, and + * cannot continue. */ } else { - /* Hijacked classes are always instantiated, because values of primitive - * types are their instances. - */ - for (hijacked <- HijackedClasses) - lookupClass(hijacked).instantiated()(fromAnalyzer) - - reachSymbolRequirement(symbolRequirements) + try { + /* Hijacked classes are always instantiated, because values of primitive + * types are their instances. + */ + for (hijacked <- HijackedClasses) + lookupClass(hijacked).instantiated() - // Reach all user stuff - for (classInfo <- _classInfos.values) - classInfo.reachExports() + // External symbol requirements, including module initializers + reachSymbolRequirement(symbolRequirements) - // Reach additional data, based on reflection methods used - reachDataThroughReflection() - } - } + // Entry points (top-level exports and static initializers) + for (encodedName <- inputProvider.classesWithEntryPoints()) + lookupClass(encodedName).reachEntryPoints() - private def linkClasses(): Unit = { - if (!_classInfos.contains(ir.Definitions.ObjectClass)) { - _errors += MissingJavaLangObjectClass(fromAnalyzer) - } else { - try { - for (classInfo <- _classInfos.values.toList) - classInfo.linkClasses() + // Reach additional data, based on reflection methods used + reachDataThroughReflection() } catch { - case CyclicDependencyException(chain) => - _errors += CycleInInheritanceChain(chain, fromAnalyzer) + case CyclicDependencyException(chain, from) => + _errors += CycleInInheritanceChain(chain, from) } } } @@ -94,13 +88,17 @@ private final class Analyzer(config: CommonPhaseConfig, private def reachSymbolRequirement(requirement: SymbolRequirement, optional: Boolean = false): Unit = { - def withClass(className: String)(body: ClassInfo => Unit) = { - val clazz = lookupClass(className) - if (!clazz.nonExistent || !optional) - body(clazz) + def withClass(className: String)(body: ClassInfo => Unit)( + implicit from: From): Unit = { + if (optional) + tryLookupClass(className).foreach(body) + else + body(lookupClass(className)) } - def withMethod(className: String, methodName: String)(body: ClassInfo => Unit) = { + def withMethod(className: String, methodName: String)( + body: ClassInfo => Unit)( + implicit from: From): Unit = { withClass(className) { clazz => val doReach = !optional || clazz.tryLookupMethod(methodName).isDefined if (doReach) @@ -112,24 +110,27 @@ private final class Analyzer(config: CommonPhaseConfig, requirement match { case AccessModule(origin, moduleName) => - withClass(moduleName)(_.accessModule()(FromCore(origin))) + implicit val from = FromCore(origin) + withClass(moduleName)(_.accessModule()) case InstantiateClass(origin, className, constructor) => + implicit val from = FromCore(origin) withMethod(className, constructor) { clazz => - implicit val from = FromCore(origin) clazz.instantiated() clazz.callMethodStatically(constructor) } case InstanceTests(origin, className) => - withClass(className)(_.useInstanceTests()(FromCore(origin))) + implicit val from = FromCore(origin) + withClass(className)(_.useInstanceTests()) case ClassData(origin, className) => - withClass(className)(_.accessData()(FromCore(origin))) + implicit val from = FromCore(origin) + withClass(className)(_.accessData()) case CallMethod(origin, className, methodName, statically) => + implicit val from = FromCore(origin) withMethod(className, methodName) { classInfo => - implicit val from = FromCore(origin) if (statically) classInfo.callMethodStatically(methodName) else @@ -137,8 +138,8 @@ private final class Analyzer(config: CommonPhaseConfig, } case CallStaticMethod(origin, className, methodName) => - withMethod(className, methodName)( - _.callStaticMethod(methodName)(FromCore(origin))) + implicit val from = FromCore(origin) + withMethod(className, methodName)(_.callStaticMethod(methodName)) case Optional(requirement) => reachSymbolRequirement(requirement, optional = true) @@ -180,9 +181,62 @@ private final class Analyzer(config: CommonPhaseConfig, } } - private class ClassInfo(data: Infos.ClassInfo) extends Analysis.ClassInfo { - private[this] var _linking = false - private[this] var _linked = false + private def tryLookupClass(encodedName: String)( + implicit from: From): Option[ClassInfo] = { + /* There is a significant amount of duplication with lookupClass, but it + * is unclear how to factor that out without hurting the performance of + * lookupClass, which is the common case. + */ + _classInfos.get(encodedName) match { + case Some(info) => + Some(info) + case None => + inputProvider.loadInfo(encodedName) match { + case Some(data) => + Some(newClassInfo(data, nonExistent = false)) + case None => + None + } + } + } + + private def lookupClass(encodedName: String)( + implicit from: From): ClassInfo = { + // See the comment in tryLookupClass about the code duplication + _classInfos.get(encodedName) match { + case Some(info) => + if (info.nonExistent) + _errors += MissingClass(info, from) + info + case None => + inputProvider.loadInfo(encodedName) match { + case Some(data) => + newClassInfo(data, nonExistent = false) + case None => + val data = createMissingClassInfo(encodedName) + val info = newClassInfo(data, nonExistent = true) + _errors += MissingClass(info, from) + info + } + } + } + + private object ClassInfo { + def newClassInfo(data: Infos.ClassInfo, nonExistent: Boolean)( + implicit from: From): ClassInfo = { + val info = new ClassInfo(data, nonExistent) + _classInfos += data.encodedName -> info + info.linkClasses() + info + } + } + + private class ClassInfo private (data: Infos.ClassInfo, + val nonExistent: Boolean) + extends Analysis.ClassInfo { + + var linked: Boolean = false + var linkedFrom: List[From] = Nil val encodedName = data.encodedName val kind = data.kind @@ -196,48 +250,40 @@ private final class Analyzer(config: CommonPhaseConfig, val isExported = data.isExported var superClass: Option[ClassInfo] = _ + var interfaces: List[ClassInfo] = _ var ancestors: List[ClassInfo] = _ - val descendants = mutable.ListBuffer.empty[ClassInfo] - - var nonExistent: Boolean = false - /** Ensures that this class and its dependencies are linked. - * - * @throws CyclicDependencyException if this class is already linking - */ - def linkClasses(): Unit = { - if (_linking) - throw CyclicDependencyException(this :: Nil) - - if (!_linked) { - _linking = true - try { - linkClassesImpl() - } catch { - case CyclicDependencyException(chain) => - throw CyclicDependencyException(this :: chain) - } - _linking = false - _linked = true + /** Links this class to its superclass and implemented interfaces. */ + def linkClasses()(implicit from: From): Unit = { + assert(!linked) + linkedFrom ::= from + try { + linkClassesImpl() + } catch { + case CyclicDependencyException(chain, _) => + throw CyclicDependencyException(this :: chain, from) } + linked = true } private[this] def linkClassesImpl(): Unit = { - superClass = data.superClass.map(lookupClass) + implicit val from = FromClass(this) - val parents = data.superClass ++: data.interfaces + def lookupClassAndCheckCycles(encodedName: String): ClassInfo = { + val info = lookupClass(encodedName) + if (!info.linked) + throw CyclicDependencyException(Nil, from) + info + } - ancestors = this +: parents.flatMap { parent => - val cls = lookupClass(parent) - cls.linkClasses() - cls.ancestors - }.distinct + superClass = data.superClass.map(lookupClassAndCheckCycles) + interfaces = data.interfaces.map(lookupClassAndCheckCycles) - for (ancestor <- ancestors) - ancestor.descendants += this - } + // TODO #3076: Validate the super class and implemented interfaces - lazy val descendentClasses = descendants.filter(_.isScalaClass) + val parents = superClass ++: interfaces + ancestors = this +: parents.flatMap(_.ancestors).distinct + } var isInstantiated: Boolean = false var isAnySubclassInstantiated: Boolean = false @@ -248,22 +294,11 @@ private final class Analyzer(config: CommonPhaseConfig, var instantiatedFrom: List[From] = Nil - val delayedCalls = mutable.Map.empty[String, From] - - def isNeededAtAll: Boolean = - areInstanceTestsUsed || - isDataAccessed || - isAnySubclassInstantiated || - isModuleAccessed || - isAnyStaticFieldReachable || - isAnyStaticMethodReachable || - isAnyDefaultMethodReachable - - private def isAnyStaticMethodReachable: Boolean = - staticMethodInfos.values.exists(_.isReachable) - - private def isAnyDefaultMethodReachable = - isInterface && methodInfos.values.exists(_.isReachable) + /** List of all instantiated (Scala) subclasses of this Scala class/trait. + * For JS types, this always remains empty. + */ + var instantiatedSubclasses: List[ClassInfo] = Nil + var methodsCalledLog: List[(String, From)] = Nil lazy val (methodInfos, staticMethodInfos) = { val allInfos = for (methodData <- data.methods) @@ -531,27 +566,19 @@ private final class Analyzer(config: CommonPhaseConfig, override def toString(): String = encodedName - /** Start reachability algorithm with the exports for that class. */ - def reachExports(): Unit = { + /** Start the reachability algorithm with the entry points of this class. */ + def reachEntryPoints(): Unit = { implicit val from = FromExports // Myself if (isExported) { - if (isAnyModuleClass) accessModule() - else instantiated() - } - - // My methods - if (!isJSClass) { - for (methodInfo <- methodInfos.values) { - if (methodInfo.isExported) - callMethod(methodInfo.encodedName) - } + if (isAnyModuleClass) + accessModule() + else + instantiated() } - /* My static initializer. - * Not technically an export, but also reachable out of thin air. - */ + // Static initializer if (!isJSType) { staticMethodInfos.get(StaticInitializerName).foreach { _.reachStatic()(fromAnalyzer) @@ -587,10 +614,21 @@ private final class Analyzer(config: CommonPhaseConfig, if (isScalaClass) { accessData() - ancestors.foreach(_.subclassInstantiated()) - for ((methodName, from) <- delayedCalls) - callMethodResolved(methodName)(from) + val allMethodsCalledLogs = for (ancestor <- ancestors) yield { + ancestor.subclassInstantiated() + ancestor.instantiatedSubclasses ::= this + ancestor.methodsCalledLog + } + + for { + log <- allMethodsCalledLogs + logEntry <- log + } { + val methodName = logEntry._1 + implicit val from = logEntry._2 + callMethodResolved(methodName) + } } else { assert(isJSClass || isNativeJSClass) @@ -619,26 +657,26 @@ private final class Analyzer(config: CommonPhaseConfig, instantiatedFrom ::= from if (!isAnySubclassInstantiated && (isScalaClass || isJSType)) { isAnySubclassInstantiated = true + + // Reach exported members + if (!isJSClass) { + implicit val from = FromExports + for (methodInfo <- methodInfos.values) { + if (methodInfo.isExported) + callMethod(methodInfo.encodedName) + } + } } } def useInstanceTests()(implicit from: From): Unit = { - if (!areInstanceTestsUsed) { - checkExistent() + if (!areInstanceTestsUsed) areInstanceTestsUsed = true - } } def accessData()(implicit from: From): Unit = { - if (!isDataAccessed) { - checkExistent() + if (!isDataAccessed) isDataAccessed = true - } - } - - def checkExistent()(implicit from: From): Unit = { - if (nonExistent) - _errors += MissingClass(this, from) } def callMethod(methodName: String)(implicit from: From): Unit = { @@ -646,12 +684,16 @@ private final class Analyzer(config: CommonPhaseConfig, assert(!isConstructorName(methodName), s"Trying to dynamically call the constructor $this.$methodName from $from") - for (descendentClass <- descendentClasses) { - if (descendentClass.isInstantiated) - descendentClass.callMethodResolved(methodName) - else - descendentClass.delayedCalls += ((methodName, from)) - } + /* First add the call to the log, then fetch the instantiated subclasses, + * then perform the resolved call. This order is important because, + * during the resolved calls, new instantiated subclasses could be + * detected, and those need to see the updated log, since the loop in + * this method won't see them. + */ + methodsCalledLog ::= ((methodName, from)) + val subclasses = instantiatedSubclasses + for (subclass <- subclasses) + subclass.callMethodResolved(methodName) } private def callMethodResolved(methodName: String)( @@ -828,15 +870,13 @@ private final class Analyzer(config: CommonPhaseConfig, } private def createMissingClassInfo(encodedName: String): Infos.ClassInfo = { - // We create a module class to avoid cascading errors Infos.ClassInfo( encodedName = encodedName, isExported = false, - kind = ClassKind.ModuleClass, + kind = ClassKind.Class, superClass = Some("O"), interfaces = Nil, - methods = List( - createMissingMethodInfo("init___")) + methods = List(createMissingMethodInfo("init___")) ) } @@ -879,15 +919,21 @@ private final class Analyzer(config: CommonPhaseConfig, object Analyzer { def computeReachability(config: CommonPhaseConfig, symbolRequirements: SymbolRequirement, - allData: Seq[Infos.ClassInfo], - allowAddingSyntheticMethods: Boolean): Analysis = { + allowAddingSyntheticMethods: Boolean, + inputProvider: InputProvider): Analysis = { val analyzer = new Analyzer(config, symbolRequirements, - allowAddingSyntheticMethods) - analyzer.computeReachability(allData) + allowAddingSyntheticMethods, inputProvider) + analyzer.computeReachability() analyzer } + trait InputProvider { + def classesWithEntryPoints(): TraversableOnce[String] + + def loadInfo(encodedName: String): Option[Infos.ClassInfo] + } + private final case class CyclicDependencyException( - chain: List[Analysis.ClassInfo]) + chain: List[Analysis.ClassInfo], from: From) extends Exception(s"Cyclic dependency: $chain") } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala similarity index 92% rename from ir/src/main/scala/org/scalajs/core/ir/Infos.scala rename to tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala index 99f50be0c8..5ed3c0cd9e 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala @@ -1,5 +1,5 @@ /* __ *\ -** ________ ___ / / ___ __ ____ Scala.js IR ** +** ________ ___ / / ___ __ ____ Scala.js tools ** ** / __/ __// _ | / / / _ | __ / // __/ (c) 2014, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** ** /____/\___/_/ |_/____/_/ | |__/ /____/ ** @@ -7,13 +7,17 @@ \* */ -package org.scalajs.core.ir +package org.scalajs.core.tools.linker.analyzer import scala.collection.mutable -import Definitions._ -import Trees._ -import Types._ +import org.scalajs.core.ir.ClassKind +import org.scalajs.core.ir.Definitions._ +import org.scalajs.core.ir.Traversers._ +import org.scalajs.core.ir.Trees._ +import org.scalajs.core.ir.Types._ + +import org.scalajs.core.tools.linker.LinkedClass object Infos { @@ -273,7 +277,9 @@ object Infos { } } - /** Generates the [[ClassInfo]] of a [[Trees.ClassDef]]. */ + /** Generates the [[ClassInfo]] of a + * [[org.scalajs.core.ir.Trees.ClassDef Trees.ClassDef]]. + */ def generateClassInfo(classDef: ClassDef): ClassInfo = { val builder = new ClassInfoBuilder() .setEncodedName(classDef.name.name) @@ -289,51 +295,57 @@ object Infos { builder.addMethod(generatePropertyInfo(propertyDef)) } + if (classDef.topLevelExportDefs.nonEmpty) { + builder.setIsExported(true) + + val optInfo = generateTopLevelExportsInfo(classDef.name.name, + classDef.topLevelExportDefs) + optInfo.foreach(builder.addMethod(_)) + } + + builder.result() + } + + /** Generates the [[MethodInfo]] of a + * [[org.scalajs.core.ir.Trees.MethodDef Trees.MethodDef]]. + */ + def generateMethodInfo(methodDef: MethodDef): MethodInfo = + new GenInfoTraverser().generateMethodInfo(methodDef) + + /** Generates the [[MethodInfo]] of a + * [[org.scalajs.core.ir.Trees.PropertyDef Trees.PropertyDef]]. + */ + def generatePropertyInfo(propertyDef: PropertyDef): MethodInfo = + new GenInfoTraverser().generatePropertyInfo(propertyDef) + + /** Generates the [[MethodInfo]] for the top-level exports. */ + def generateTopLevelExportsInfo(enclosingClass: String, + topLevelExportDefs: List[TopLevelExportDef]): Option[MethodInfo] = { + var exportedConstructors: List[TopLevelConstructorExportDef] = Nil var topLevelMethodExports: List[TopLevelMethodExportDef] = Nil var topLevelFieldExports: List[TopLevelFieldExportDef] = Nil - classDef.topLevelExportDefs foreach { + topLevelExportDefs.foreach { case constructorDef: TopLevelConstructorExportDef => - builder.setIsExported(true) exportedConstructors ::= constructorDef case _:TopLevelJSClassExportDef | _:TopLevelModuleExportDef => - builder.setIsExported(true) case topLevelMethodExport: TopLevelMethodExportDef => - builder.setIsExported(true) topLevelMethodExports ::= topLevelMethodExport case topLevelFieldExport: TopLevelFieldExportDef => - builder.setIsExported(true) topLevelFieldExports ::= topLevelFieldExport } if (exportedConstructors.nonEmpty || topLevelMethodExports.nonEmpty || topLevelFieldExports.nonEmpty) { - builder.addMethod(generateTopLevelExportsInfo(classDef.name.name, + Some(new GenInfoTraverser().generateTopLevelExportsInfo(enclosingClass, exportedConstructors, topLevelMethodExports, topLevelFieldExports)) + } else { + None } - - builder.result() - } - - /** Generates the [[MethodInfo]] of a [[Trees.MethodDef]]. */ - def generateMethodInfo(methodDef: MethodDef): MethodInfo = - new GenInfoTraverser().generateMethodInfo(methodDef) - - /** Generates the [[MethodInfo]] of a [[Trees.PropertyDef]]. */ - def generatePropertyInfo(propertyDef: PropertyDef): MethodInfo = - new GenInfoTraverser().generatePropertyInfo(propertyDef) - - /** Generates the [[MethodInfo]] for the top-level exports. */ - def generateTopLevelExportsInfo(enclosingClass: String, - topLevelConstructorDefs: List[TopLevelConstructorExportDef], - topLevelMethodExports: List[TopLevelMethodExportDef], - topLevelFieldExports: List[TopLevelFieldExportDef]): MethodInfo = { - new GenInfoTraverser().generateTopLevelExportsInfo(enclosingClass, - topLevelConstructorDefs, topLevelMethodExports, topLevelFieldExports) } - private final class GenInfoTraverser extends Traversers.Traverser { + private final class GenInfoTraverser extends Traverser { private val builder = new MethodInfoBuilder def generateMethodInfo(methodDef: MethodDef): MethodInfo = { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index 00825b5337..8fd805a91a 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -34,7 +34,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { val className = tree.name.name val staticMemberDefsWithGlobals = - tree.staticMethods.map(m => genMethod(className, m.tree)) + tree.staticMethods.map(m => genMethod(className, m.value)) for (staticMemberDefs <- WithGlobals.list(staticMemberDefsWithGlobals)) yield js.Block(staticMemberDefs)(tree.pos) } @@ -43,7 +43,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { val className = tree.name.name val defaultMethodDefsWithGlobals = - tree.memberMethods.map(m => genDefaultMethod(className, m.tree)) + tree.memberMethods.map(m => genDefaultMethod(className, m.value)) for (defaultMethodDefs <- WithGlobals.list(defaultMethodDefsWithGlobals)) yield js.Block(defaultMethodDefs)(tree.pos) } @@ -135,13 +135,13 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { /** Extracts the inlineable init method, if there is one. */ def extractInlineableInit(tree: LinkedClass)( - implicit globalKnowledge: GlobalKnowledge): (Option[LinkedMember[MethodDef]], List[LinkedMember[MethodDef]]) = { + implicit globalKnowledge: GlobalKnowledge): (Option[Versioned[MethodDef]], List[Versioned[MethodDef]]) = { val memberMethods = tree.memberMethods if (globalKnowledge.hasInlineableInit(tree.encodedName)) { val (constructors, otherMethods) = memberMethods.partition { method => - Definitions.isConstructorName(method.info.encodedName) + Definitions.isConstructorName(method.value.encodedName) } assert(constructors.size == 1, s"Found ${constructors.size} constructors in class " + @@ -327,7 +327,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { require(tree.kind.isJSClass) - tree.exportedMembers.map(_.tree) collectFirst { + tree.exportedMembers.map(_.value) collectFirst { case MethodDef(false, StringLiteral("constructor"), params, _, body) => desugarToFunction(tree.encodedName, params, body.get, isStat = true) } getOrElse { @@ -384,7 +384,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { def genStaticInitialization(tree: LinkedClass): List[js.Tree] = { import Definitions.StaticInitializerName implicit val pos = tree.pos - if (tree.staticMethods.exists(_.tree.name.encodedName == StaticInitializerName)) { + if (tree.staticMethods.exists(_.value.encodedName == StaticInitializerName)) { val fullName = tree.encodedName + "__" + StaticInitializerName js.Apply(envField("s", fullName, Some("")), Nil) :: Nil } else { @@ -404,7 +404,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { method.args, methodBody, method.resultType == NoType) methodFun0WithGlobals.flatMap { methodFun0 => - val methodFun = if (Definitions.isConstructorName(method.name.encodedName)) { + val methodFun = if (Definitions.isConstructorName(method.encodedName)) { // init methods have to return `this` so that we can chain them to `new` js.Function(methodFun0.args, { implicit val pos = methodFun0.body.pos @@ -990,10 +990,10 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { def genExportedMembers(tree: LinkedClass)( implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { val exportsWithGlobals = tree.exportedMembers map { member => - member.tree match { + member.value match { case MethodDef(false, StringLiteral("constructor"), _, _, _) if tree.kind.isJSClass => - WithGlobals(js.Skip()(member.tree.pos)) + WithGlobals(js.Skip()(member.value.pos)) case m: MethodDef => genMethod(tree.encodedName, m) case p: PropertyDef => @@ -1010,20 +1010,19 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { def genTopLevelExports(tree: LinkedClass)( implicit globalKnowledge: GlobalKnowledge): WithGlobals[List[js.Tree]] = { - val exportsWithGlobals = tree.topLevelExports map { - case e: TopLevelConstructorExportDef => - genTopLevelConstructorExportDef(tree, e) - case e: TopLevelJSClassExportDef => - WithGlobals(genTopLevelJSClassExportDef(tree, e)) - case e: TopLevelModuleExportDef => - WithGlobals(genTopLevelModuleExportDef(tree, e)) - case e: TopLevelMethodExportDef => - genTopLevelMethodExportDef(tree, e) - case e: TopLevelFieldExportDef => - WithGlobals(genTopLevelFieldExportDef(tree, e)) - case tree => - throw new AssertionError( - "Illegal top-level export " + tree.getClass.getName) + val exportsWithGlobals = tree.topLevelExports.map { topLevelExport => + topLevelExport.value match { + case e: TopLevelConstructorExportDef => + genTopLevelConstructorExportDef(tree, e) + case e: TopLevelJSClassExportDef => + WithGlobals(genTopLevelJSClassExportDef(tree, e)) + case e: TopLevelModuleExportDef => + WithGlobals(genTopLevelModuleExportDef(tree, e)) + case e: TopLevelMethodExportDef => + genTopLevelMethodExportDef(tree, e) + case e: TopLevelFieldExportDef => + WithGlobals(genTopLevelFieldExportDef(tree, e)) + } } WithGlobals.list(exportsWithGlobals) diff --git 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 index 83e9c57493..ae074f97de 100644 --- 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 @@ -332,10 +332,10 @@ final class Emitter private (config: CommonPhaseConfig, // Static methods for (m <- linkedClass.staticMethods) { - val methodCache = classCache.getStaticCache(m.info.encodedName) + val methodCache = classCache.getStaticCache(m.value.encodedName) addToMain(methodCache.getOrElseUpdate(m.version, - classEmitter.genMethod(className, m.tree)(methodCache))) + classEmitter.genMethod(className, m.value)(methodCache))) } // Class definition @@ -354,17 +354,17 @@ final class Emitter private (config: CommonPhaseConfig, } { linkedInit => mergeVersions(linkedClass.version, linkedInit.version).map("2-" + _) } - val initToInline = linkedInlineableInit.map(_.tree) + val initToInline = linkedInlineableInit.map(_.value) ctorCache.getOrElseUpdate(ctorVersion, classEmitter.genConstructor(linkedClass, initToInline)(ctorCache)) } // Normal methods val memberMethods = for (m <- linkedMemberMethods) yield { - val methodCache = classCache.getMethodCache(m.info.encodedName) + val methodCache = classCache.getMethodCache(m.value.encodedName) methodCache.getOrElseUpdate(m.version, - classEmitter.genMethod(className, m.tree)(methodCache)) + classEmitter.genMethod(className, m.value)(methodCache)) } // Exported Members @@ -376,9 +376,9 @@ final class Emitter private (config: CommonPhaseConfig, } else if (kind == ClassKind.Interface) { // Default methods for (m <- linkedClass.memberMethods) yield { - val methodCache = classCache.getMethodCache(m.info.encodedName) + val methodCache = classCache.getMethodCache(m.value.encodedName) addToMain(methodCache.getOrElseUpdate(m.version, - classEmitter.genDefaultMethod(className, m.tree)(methodCache))) + classEmitter.genDefaultMethod(className, m.value)(methodCache))) } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala index d0e0c61680..c1a9f83feb 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala @@ -54,7 +54,7 @@ private[emitter] final class KnowledgeGuardian { } def methodExists(encodedName: String): Boolean = - linkedClass.memberMethods.exists(_.tree.name.encodedName == encodedName) + linkedClass.memberMethods.exists(_.value.encodedName == encodedName) linkedClass.encodedName match { case Definitions.ClassClass => @@ -116,10 +116,10 @@ private[emitter] final class KnowledgeGuardian { !blackList(classDef.encodedName) && !classesWithInstantiatedSubclasses(classDef.encodedName) && { classDef.memberMethods.count( - x => Definitions.isConstructorName(x.info.encodedName)) == 1 + x => Definitions.isConstructorName(x.value.encodedName)) == 1 } && { !classDef.topLevelExports.exists( - _.isInstanceOf[TopLevelConstructorExportDef]) + _.value.isInstanceOf[TopLevelConstructorExportDef]) } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 8447b00a4d..755535c623 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -25,9 +25,12 @@ import Types._ import org.scalajs.core.tools.logging._ import org.scalajs.core.tools.linker.{LinkingUnit, LinkedClass} +import org.scalajs.core.tools.linker.analyzer.{Analyzer, Infos} /** Checker for the validity of the IR. */ -private final class IRChecker(unit: LinkingUnit, logger: Logger) { +private final class IRChecker(unit: LinkingUnit, + inputProvider: Analyzer.InputProvider, logger: Logger) { + import IRChecker._ private var errorCount: Int = 0 @@ -99,7 +102,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { private def checkStaticMembers(classDef: LinkedClass): Unit = { for (member <- classDef.staticMethods) { - val methodDef = member.tree + val methodDef = member.value implicit val ctx = ErrorContext(methodDef) assert(methodDef.static, "Found non-static member in static defs") @@ -131,7 +134,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { */ val staticFieldDefs = classDef.fields.filter(_.static) for { - fieldsWithSameName <- staticFieldDefs.groupBy(_.name.encodedName).values + fieldsWithSameName <- staticFieldDefs.groupBy(_.encodedName).values duplicate <- fieldsWithSameName.tail } { implicit val ctx = ErrorContext(duplicate) @@ -142,17 +145,17 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { if (classDef.kind == ClassKind.ModuleClass) { implicit val ctx = ErrorContext(classDef) val methods = classDef.memberMethods - if (methods.count(m => isConstructorName(m.info.encodedName)) != 1) + if (methods.count(m => isConstructorName(m.value.encodedName)) != 1) reportError(s"Module class must have exactly 1 constructor") - if (!methods.exists(_.info.encodedName == "init___")) + if (!methods.exists(_.value.encodedName == "init___")) reportError(s"Module class must have a parameterless constructor") } // Check exported members for (member <- classDef.exportedMembers) { - implicit val ctx = ErrorContext(member.tree) + implicit val ctx = ErrorContext(member.value) - member.tree match { + member.value match { case m: MethodDef => checkExportedMethodDef(m, classDef, isTopLevel = false) @@ -162,12 +165,13 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { // Anything else is illegal case _ => reportError("Illegal exported class member of type " + - member.tree.getClass.getName) + member.value.getClass.getName) } } // Check top-level exports - for (tree <- classDef.topLevelExports) { + for (topLevelExport <- classDef.topLevelExports) { + val tree = topLevelExport.value implicit val ctx = ErrorContext(tree) tree match { @@ -191,11 +195,6 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { if (tpe != AnyType) reportError(s"Cannot export field '$field' of type $tpe") } - - // Anything else is illegal - case _ => - reportError("Illegal top-level export of type " + - tree.getClass.getName) } } } else { @@ -214,7 +213,7 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { // Check methods for (method <- classDef.memberMethods ++ classDef.abstractMethods) { - val tree = method.tree + val tree = method.value implicit val ctx = ErrorContext(tree) assert(!tree.static, "Member or abstract method may not be static") @@ -1118,10 +1117,10 @@ private final class IRChecker(unit: LinkingUnit, logger: Logger) { private def lookupInfo(className: String)( implicit ctx: ErrorContext): Infos.ClassInfo = { - unit.infos.getOrElse(className, { + inputProvider.loadInfo(className).getOrElse { reportError(s"Cannot find info for class $className") Infos.ClassInfo(className) - }) + } } private def tryLookupClass(className: String)( @@ -1268,8 +1267,9 @@ object IRChecker { * * @return Count of IR checking errors (0 in case of success) */ - def check(unit: LinkingUnit, logger: Logger): Int = { - new IRChecker(unit, logger).check() + def check(unit: LinkingUnit, inputProvider: Analyzer.InputProvider, + logger: Logger): Int = { + new IRChecker(unit, inputProvider, logger).check() } /** The context in which to report IR check errors. diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/InfoChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/InfoChecker.scala deleted file mode 100644 index 999e266b59..0000000000 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/InfoChecker.scala +++ /dev/null @@ -1,158 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.core.tools.linker.checker - -import scala.language.implicitConversions - -import scala.annotation.switch - -import scala.collection.mutable - -import java.io.StringWriter - -import org.scalajs.core.ir._ -import Definitions._ -import Infos._ -import Trees._ -import Types._ -import Printers._ - -import org.scalajs.core.tools.logging._ - -/** Checker for the validity of the IR. */ -private final class InfoChecker( - infoAndTrees: Traversable[(ClassInfo, ClassDef)], logger: Logger) { - - private var errorCount: Int = 0 - - def check(): Int = { - for ((info, classDef) <- infoAndTrees) { - val generatedInfo = generateClassInfo(classDef) - checkClassInfo(info, generatedInfo) - } - errorCount - } - - private def checkClassInfo(info: ClassInfo, expectedInfo: ClassInfo): Unit = { - val className = expectedInfo.encodedName - - if (info.encodedName != expectedInfo.encodedName || - info.isExported != expectedInfo.isExported || - info.kind != expectedInfo.kind || - info.superClass != expectedInfo.superClass || - info.interfaces.toSet != expectedInfo.interfaces.toSet) { - errorCount += 1 - logger.error(s"Class info mismatch for $className") - logger.error(s"Expected:\n${classInfoHeaderString(expectedInfo)}") - logger.error(s"Got:\n${classInfoHeaderString(info)}") - } - - def methodID(methodInfo: MethodInfo) = - (methodInfo.encodedName, methodInfo.isStatic) - - val actualMethods = info.methods.map(m => methodID(m) -> m).toMap - val expectedMethods = expectedInfo.methods.map(m => methodID(m) -> m).toMap - - val actualMethodIDs = actualMethods.keySet - val expectedMethodIDs = expectedMethods.keySet - - if (actualMethodIDs != expectedMethodIDs) { - val missingMethods = expectedMethodIDs -- actualMethodIDs - if (missingMethods.nonEmpty) { - errorCount += 1 - logger.error( - s"Missing methods in $className: $missingMethods") - } - - val unexpectedMethods = actualMethodIDs -- expectedMethodIDs - if (unexpectedMethods.nonEmpty) { - errorCount += 1 - logger.error( - s"Unexpected methods in $className: $unexpectedMethods") - } - } - - for { - (id, actualMethodInfo) <- actualMethods - expectedMethodInfo <- expectedMethods.get(id) - } { - checkMethodInfo(className, actualMethodInfo, expectedMethodInfo) - } - } - - private def checkMethodInfo(className: String, info: MethodInfo, - expectedInfo: MethodInfo): Unit = { - - /* Note that it is fine for the actual info to contain *more* than the - * expected info. It can produce non-optimal results, but it is still - * correct. - * Our compiler does generate such non-optimal info in some cases, for - * example when it deconstructs a `new AnonFunctionN` when converting it - * immediately to a js.FunctionN. - */ - - def listIncludes(actual: List[String], expected: List[String]) = { - val actualSet = actual.toSet - expected.forall(actualSet) - } - - def mapIncludes(actual: Map[String, List[String]], - expected: Map[String, List[String]]) = { - expected forall { case (cls, expectedMethods) => - actual.get(cls) exists { actualMethods => - listIncludes(actualMethods, expectedMethods) - } - } - } - - if (info.encodedName != expectedInfo.encodedName || - info.isStatic != expectedInfo.isStatic || - info.isAbstract != expectedInfo.isAbstract || - info.isExported != expectedInfo.isExported || - !mapIncludes(info.methodsCalled, expectedInfo.methodsCalled) || - !mapIncludes(info.methodsCalledStatically, expectedInfo.methodsCalledStatically) || - !mapIncludes(info.staticMethodsCalled, expectedInfo.staticMethodsCalled) || - !listIncludes(info.instantiatedClasses, expectedInfo.instantiatedClasses) || - !listIncludes(info.accessedModules, expectedInfo.accessedModules) || - !listIncludes(info.usedInstanceTests, expectedInfo.usedInstanceTests) || - !listIncludes(info.accessedClassData, expectedInfo.accessedClassData)) { - errorCount += 1 - logger.error(s"Method info mismatch for $className.${expectedInfo.encodedName}" + - (if (expectedInfo.isStatic) " (static)" else "")) - logger.error(s"Expected:\n${methodInfoString(expectedInfo)}") - logger.error(s"Got:\n${methodInfoString(info)}") - } - } - - private def classInfoHeaderString(info: ClassInfo): String = { - val writer = new StringWriter - val printer = new InfoPrinter(writer) - printer.printClassInfoHeader(info) - writer.toString() - } - - private def methodInfoString(info: MethodInfo): String = { - val writer = new StringWriter - val printer = new InfoPrinter(writer) - printer.print(info) - writer.toString() - } -} - -object InfoChecker { - /** Checks that the `ClassInfo`s associated with `ClassDef`s are correct. - * - * @return Count of info checking errors (0 in case of success) - */ - def check(infoAndTrees: Traversable[(ClassInfo, ClassDef)], - logger: Logger): Int = { - new InfoChecker(infoAndTrees, logger).check() - } -} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index 8a779d68fb..3ba4d2820b 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -23,7 +23,6 @@ import org.scalajs.core.tools.linker.checker._ import org.scalajs.core.tools.linker.analyzer._ import org.scalajs.core.ir -import ir.Infos import ir.Trees._ import ir.Types._ import ir.ClassKind @@ -37,61 +36,24 @@ import Analysis._ * [[LinkedClass]]es. Does a dead code elimination pass. */ final class BaseLinker(config: CommonPhaseConfig) { + import BaseLinker._ - private type TreeProvider = String => (ClassDef, Option[String]) + private val inputProvider = new InputProvider def link(irInput: Seq[VirtualScalaJSIRFile], moduleInitializers: Seq[ModuleInitializer], logger: Logger, symbolRequirements: SymbolRequirement, checkIR: Boolean): LinkingUnit = { - val infosBuilder = List.newBuilder[Infos.ClassInfo] - val encodedNameToFile = mutable.Map.empty[String, VirtualScalaJSIRFile] - - for (irFile <- irInput) { - val info = irFile.info - - // Remove duplicates. Just like the JVM - if (!encodedNameToFile.contains(info.encodedName)) { - infosBuilder += info - encodedNameToFile += info.encodedName -> irFile - } - } - - val infos = infosBuilder.result() - - val getTree: TreeProvider = { name => - val pf = encodedNameToFile(name) - (pf.tree, pf.version) - } - - linkInternal(infos, getTree, moduleInitializers, logger, symbolRequirements, - checkIR) - } - - private def linkInternal(infoInput: List[Infos.ClassInfo], - getTree: TreeProvider, moduleInitializers: Seq[ModuleInitializer], - logger: Logger, symbolRequirements: SymbolRequirement, - checkIR: Boolean): LinkingUnit = { - - if (checkIR) { - logger.time("Linker: Check Infos") { - val infoAndTrees = - infoInput.map(info => (info, getTree(info.encodedName)._1)) - val errorCount = InfoChecker.check(infoAndTrees, logger) - if (errorCount != 0) { - throw new LinkingException( - s"There were $errorCount Info checking errors.") - } - } - } + inputProvider.update(irInput) val analysis = logger.time("Linker: Compute reachability") { val allSymbolRequirements = { symbolRequirements ++ ModuleInitializer.toSymbolRequirement(moduleInitializers) } - Analyzer.computeReachability(config, allSymbolRequirements, infoInput, - allowAddingSyntheticMethods = true) + Analyzer.computeReachability(config, + allSymbolRequirements, allowAddingSyntheticMethods = true, + inputProvider) } if (analysis.errors.nonEmpty) { @@ -112,7 +74,7 @@ final class BaseLinker(config: CommonPhaseConfig) { } val linkResult = logger.time("Linker: Assemble LinkedClasses") { - assemble(infoInput, getTree, moduleInitializers, analysis) + assemble(moduleInitializers, analysis) } // Make sure we don't export to the same name twice. @@ -120,7 +82,7 @@ final class BaseLinker(config: CommonPhaseConfig) { if (checkIR) { logger.time("Linker: Check IR") { - val errorCount = IRChecker.check(linkResult, logger) + val errorCount = IRChecker.check(linkResult, inputProvider, logger) if (errorCount != 0) { throw new LinkingException( s"There were $errorCount IR checking errors.") @@ -128,65 +90,56 @@ final class BaseLinker(config: CommonPhaseConfig) { } } + inputProvider.cleanAfterRun() + linkResult } - private def assemble(infoInput: List[Infos.ClassInfo], getTree: TreeProvider, - moduleInitializers: Seq[ModuleInitializer], analysis: Analysis) = { - val infoByName = Map(infoInput.map(c => c.encodedName -> c): _*) - + private def assemble(moduleInitializers: Seq[ModuleInitializer], + analysis: Analysis): LinkingUnit = { val linkedClassDefs = for { analyzerInfo <- analysis.classInfos.values - if analyzerInfo.isNeededAtAll } yield { - val encodedName = analyzerInfo.encodedName - val (tree, version) = getTree(encodedName) - linkedClassDef(infoByName(encodedName), tree, analyzerInfo, version, - getTree, analysis) + linkedClassDef(analyzerInfo, analysis) } - new LinkingUnit(config.coreSpec, linkedClassDefs.toList, infoByName, + new LinkingUnit(config.coreSpec, linkedClassDefs.toList, moduleInitializers.toList) } - /** Takes a Infos, a ClassDef and DCE infos to construct a stripped down - * LinkedClassDef */ - private def linkedClassDef(info: Infos.ClassInfo, classDef: ClassDef, - analyzerInfo: Analysis.ClassInfo, version: Option[String], - getTree: TreeProvider, analysis: Analysis) = { + /** Takes a ClassDef and DCE infos to construct a stripped down LinkedClass. + */ + private def linkedClassDef(analyzerInfo: Analysis.ClassInfo, + analysis: Analysis): LinkedClass = { import ir.Trees._ - val memberInfoByStaticAndName = - Map(info.methods.map(m => (m.isStatic, m.encodedName) -> m): _*) + val (classDef, version) = + inputProvider.loadClassDefAndVersion(analyzerInfo.encodedName) val fields = mutable.Buffer.empty[FieldDef] - val staticMethods = mutable.Buffer.empty[LinkedMember[MethodDef]] - val memberMethods = mutable.Buffer.empty[LinkedMember[MethodDef]] - val abstractMethods = mutable.Buffer.empty[LinkedMember[MethodDef]] - val exportedMembers = mutable.Buffer.empty[LinkedMember[MemberDef]] - val topLevelExports = mutable.Buffer.empty[TopLevelExportDef] + val staticMethods = mutable.Buffer.empty[Versioned[MethodDef]] + val memberMethods = mutable.Buffer.empty[Versioned[MethodDef]] + val abstractMethods = mutable.Buffer.empty[Versioned[MethodDef]] + val exportedMembers = mutable.Buffer.empty[Versioned[MemberDef]] def linkedMethod(m: MethodDef) = { - val info = memberInfoByStaticAndName((m.static, m.name.encodedName)) val version = m.hash.map(Hashers.hashAsVersion(_)) - new LinkedMember(info, m, version) + new Versioned(m, version) } def linkedProperty(p: PropertyDef) = { - val info = memberInfoByStaticAndName((p.static, p.name.encodedName)) - new LinkedMember(info, p, None) + new Versioned(p, None) } def linkedSyntheticMethod(m: MethodDef) = { - val info = Infos.generateMethodInfo(m) val version = m.hash.map(Hashers.hashAsVersion(_)) - new LinkedMember(info, m, version) + new Versioned(m, version) } classDef.memberDefs.foreach { // Static methods case m: MethodDef if m.static => - if (analyzerInfo.staticMethodInfos(m.name.encodedName).isReachable) { + if (analyzerInfo.staticMethodInfos(m.encodedName).isReachable) { if (m.name.isInstanceOf[Ident]) staticMethods += linkedMethod(m) else @@ -200,7 +153,7 @@ final class BaseLinker(config: CommonPhaseConfig) { // Normal methods case m: MethodDef => - if (analyzerInfo.methodInfos(m.name.encodedName).isReachable) { + if (analyzerInfo.methodInfos(m.encodedName).isReachable) { if (m.name.isInstanceOf[Ident]) { if (m.body.isDefined) memberMethods += linkedMethod(m) @@ -227,18 +180,18 @@ final class BaseLinker(config: CommonPhaseConfig) { case MethodSyntheticKind.ReflectiveProxy(targetName) => val syntheticMDef = synthesizeReflectiveProxy( - analyzerInfo, m, targetName, getTree, analysis) + analyzerInfo, m, targetName, analysis) memberMethods += linkedSyntheticMethod(syntheticMDef) case MethodSyntheticKind.DefaultBridge(targetInterface) => val syntheticMDef = synthesizeDefaultBridge( - analyzerInfo, m, targetInterface, getTree, analysis) + analyzerInfo, m, targetInterface, analysis) memberMethods += linkedSyntheticMethod(syntheticMDef) } } - val topLevelExportInfo = - memberInfoByStaticAndName.get((false, Definitions.TopLevelExportsName)) + val topLevelExports = + classDef.topLevelExportDefs.map(new Versioned(_, version)) val kind = if (analyzerInfo.isModuleAccessed) classDef.kind @@ -257,8 +210,7 @@ final class BaseLinker(config: CommonPhaseConfig) { memberMethods.toList, abstractMethods.toList, exportedMembers.toList, - classDef.topLevelExportDefs, - topLevelExportInfo, + topLevelExports, classDef.optimizerHints, classDef.pos, ancestors.toList, @@ -270,12 +222,10 @@ final class BaseLinker(config: CommonPhaseConfig) { private def synthesizeReflectiveProxy( classInfo: Analysis.ClassInfo, methodInfo: Analysis.MethodInfo, - targetName: String, getTree: TreeProvider, - analysis: Analysis): MethodDef = { + targetName: String, analysis: Analysis): MethodDef = { val encodedName = methodInfo.encodedName - val targetMDef = findInheritedMethodDef(analysis, classInfo, targetName, - getTree) + val targetMDef = findInheritedMethodDef(analysis, classInfo, targetName) implicit val pos = targetMDef.pos @@ -304,12 +254,11 @@ final class BaseLinker(config: CommonPhaseConfig) { private def synthesizeDefaultBridge( classInfo: Analysis.ClassInfo, methodInfo: Analysis.MethodInfo, - targetInterface: String, - getTree: TreeProvider, analysis: Analysis): MethodDef = { + targetInterface: String, analysis: Analysis): MethodDef = { val encodedName = methodInfo.encodedName val targetInterfaceInfo = analysis.classInfos(targetInterface) - val targetMDef = findMethodDef(targetInterfaceInfo, encodedName, getTree) + val targetMDef = findMethodDef(targetInterfaceInfo, encodedName) implicit val pos = targetMDef.pos @@ -327,7 +276,7 @@ final class BaseLinker(config: CommonPhaseConfig) { } private def findInheritedMethodDef(analysis: Analysis, - classInfo: Analysis.ClassInfo, methodName: String, getTree: TreeProvider, + classInfo: Analysis.ClassInfo, methodName: String, p: Analysis.MethodInfo => Boolean = _ => true): MethodDef = { @tailrec def loop(ancestorInfo: Analysis.ClassInfo): MethodDef = { @@ -336,11 +285,11 @@ final class BaseLinker(config: CommonPhaseConfig) { case Some(m) => m.syntheticKind match { case MethodSyntheticKind.None => - findMethodDef(ancestorInfo, methodName, getTree) + findMethodDef(ancestorInfo, methodName) case MethodSyntheticKind.DefaultBridge(targetInterface) => val targetInterfaceInfo = analysis.classInfos(targetInterface) - findMethodDef(targetInterfaceInfo, methodName, getTree) + findMethodDef(targetInterfaceInfo, methodName) case MethodSyntheticKind.ReflectiveProxy(_) => throw new AssertionError( @@ -359,11 +308,11 @@ final class BaseLinker(config: CommonPhaseConfig) { } private def findMethodDef(classInfo: Analysis.ClassInfo, - methodName: String, getTree: TreeProvider): MethodDef = { - val (classDef, _) = getTree(classInfo.encodedName) + methodName: String): MethodDef = { + val classDef = inputProvider.loadClassDef(classInfo.encodedName) classDef.memberDefs.collectFirst { case mDef: MethodDef - if !mDef.static && mDef.name.encodedName == methodName => mDef + if !mDef.static && mDef.encodedName == methodName => mDef }.getOrElse { throw new AssertionError( s"Cannot find $methodName in ${classInfo.encodedName}") @@ -396,3 +345,104 @@ final class BaseLinker(config: CommonPhaseConfig) { throw new LinkingException("There were conflicting exports.") } } + +private object BaseLinker { + private class InputProvider extends Analyzer.InputProvider { + private var encodedNameToFile: collection.Map[String, VirtualScalaJSIRFile] = _ + private val cache = mutable.Map.empty[String, ClassDefAndInfoCache] + + def update(irInput: Seq[VirtualScalaJSIRFile]): Unit = { + val encodedNameToFile = mutable.Map.empty[String, VirtualScalaJSIRFile] + for (irFile <- irInput) { + // Remove duplicates. Just like the JVM + val encodedName = irFile.entryPointsInfo.encodedName + if (!encodedNameToFile.contains(encodedName)) + encodedNameToFile += encodedName -> irFile + } + this.encodedNameToFile = encodedNameToFile + } + + def classesWithEntryPoints(): TraversableOnce[String] = { + for { + irFile <- encodedNameToFile.valuesIterator + entryPointsInfo = irFile.entryPointsInfo + if entryPointsInfo.hasEntryPoint + } yield { + entryPointsInfo.encodedName + } + } + + def loadInfo(encodedName: String): Option[Infos.ClassInfo] = + getCache(encodedName).map(_.loadInfo(encodedNameToFile(encodedName))) + + def loadClassDefAndVersion( + encodedName: String): (ClassDef, Option[String]) = { + val fileCache = getCache(encodedName).getOrElse { + throw new AssertionError(s"Cannot load file for class $encodedName") + } + fileCache.loadClassDefAndVersion(encodedNameToFile(encodedName)) + } + + def loadClassDef(encodedName: String): ClassDef = + loadClassDefAndVersion(encodedName)._1 + + private def getCache(encodedName: String): Option[ClassDefAndInfoCache] = { + cache.get(encodedName).orElse { + if (encodedNameToFile.contains(encodedName)) { + val fileCache = new ClassDefAndInfoCache + cache += encodedName -> fileCache + Some(fileCache) + } else { + None + } + } + } + + def cleanAfterRun(): Unit = { + encodedNameToFile = null + cache.retain((_, fileCache) => fileCache.cleanAfterRun()) + } + } + + private final class ClassDefAndInfoCache { + private var cacheUsed: Boolean = false + private var version: Option[String] = None + private var classDef: ClassDef = _ + private var info: Infos.ClassInfo = _ + + def loadInfo(irFile: VirtualScalaJSIRFile): Infos.ClassInfo = { + update(irFile) + info + } + + def loadClassDefAndVersion( + irFile: VirtualScalaJSIRFile): (ClassDef, Option[String]) = { + update(irFile) + (classDef, version) + } + + def update(irFile: VirtualScalaJSIRFile): Unit = { + /* If the cache was already used in this run, the classDef and info are + * already correct, no matter what the versions say. + */ + if (!cacheUsed) { + cacheUsed = true + + val newVersion = irFile.version + if (version.isEmpty || newVersion.isEmpty || + version.get != newVersion.get) { + classDef = irFile.tree + info = Infos.generateClassInfo(classDef) + version = newVersion + } + } + } + + /** Returns true if the cache has been used and should be kept. */ + def cleanAfterRun(): Boolean = { + val result = cacheUsed + cacheUsed = false + result + } + } +} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala index f833c60328..f91778a949 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala @@ -9,26 +9,37 @@ package org.scalajs.core.tools.linker.frontend +import scala.collection.mutable + +import org.scalajs.core.ir.Trees._ + import org.scalajs.core.tools.logging._ import org.scalajs.core.tools.linker._ import org.scalajs.core.tools.linker.standard._ import org.scalajs.core.tools.linker.analyzer._ -import org.scalajs.core.ir.ClassKind - /** Does a dead code elimination pass on [[LinkedClass]]es */ final class Refiner(config: CommonPhaseConfig) { + import Refiner._ + + private val inputProvider = new InputProvider def refine(unit: LinkingUnit, symbolRequirements: SymbolRequirement, logger: Logger): LinkingUnit = { + + val linkedClassesByName = + Map(unit.classDefs.map(c => c.encodedName -> c): _*) + inputProvider.update(linkedClassesByName) + val analysis = logger.time("Refiner: Compute reachability") { val allSymbolRequirements = { symbolRequirements ++ ModuleInitializer.toSymbolRequirement(unit.moduleInitializers) } - Analyzer.computeReachability(config, allSymbolRequirements, - unit.infos.values.toList, allowAddingSyntheticMethods = false) + Analyzer.computeReachability(config, + allSymbolRequirements, allowAddingSyntheticMethods = false, + inputProvider) } /* There must not be linking errors at this point. If there are, it is a @@ -44,20 +55,21 @@ final class Refiner(config: CommonPhaseConfig) { "`scalaJSLinkerConfig ~= { _.withOptimizer(false) }`.") } - logger.time("Refiner: Assemble LinkedClasses") { - val linkedClassesByName = - Map(unit.classDefs.map(c => c.encodedName -> c): _*) - + val result = logger.time("Refiner: Assemble LinkedClasses") { val linkedClassDefs = for { analyzerInfo <- analysis.classInfos.values - if analyzerInfo.isNeededAtAll } yield { refineClassDef(linkedClassesByName(analyzerInfo.encodedName), analyzerInfo) } - unit.updated(classDefs = linkedClassDefs.toList) + new LinkingUnit(unit.coreSpec, linkedClassDefs.toList, + unit.moduleInitializers) } + + inputProvider.cleanAfterRun() + + result } private def refineClassDef(classDef: LinkedClass, @@ -68,15 +80,15 @@ final class Refiner(config: CommonPhaseConfig) { else Nil val staticMethods = classDef.staticMethods filter { m => - info.staticMethodInfos(m.info.encodedName).isReachable + info.staticMethodInfos(m.value.encodedName).isReachable } val memberMethods = classDef.memberMethods filter { m => - info.methodInfos(m.info.encodedName).isReachable + info.methodInfos(m.value.encodedName).isReachable } val abstractMethods = classDef.abstractMethods filter { m => - info.methodInfos(m.info.encodedName).isReachable + info.methodInfos(m.value.encodedName).isReachable } val kind = @@ -95,3 +107,167 @@ final class Refiner(config: CommonPhaseConfig) { } } + +private object Refiner { + private class InputProvider extends Analyzer.InputProvider { + private var linkedClassesByName: Map[String, LinkedClass] = _ + private val cache = mutable.Map.empty[String, LinkedClassInfoCache] + + def update(linkedClassesByName: Map[String, LinkedClass]): Unit = { + this.linkedClassesByName = linkedClassesByName + } + + def classesWithEntryPoints(): TraversableOnce[String] = { + for { + linkedClass <- linkedClassesByName.valuesIterator + if linkedClass.hasEntryPoint + } yield { + linkedClass.encodedName + } + } + + def loadInfo(encodedName: String): Option[Infos.ClassInfo] = + getCache(encodedName).map(_.loadInfo(linkedClassesByName(encodedName))) + + private def getCache(encodedName: String): Option[LinkedClassInfoCache] = { + cache.get(encodedName).orElse { + if (linkedClassesByName.contains(encodedName)) { + val fileCache = new LinkedClassInfoCache + cache += encodedName -> fileCache + Some(fileCache) + } else { + None + } + } + } + + def cleanAfterRun(): Unit = { + linkedClassesByName = null + cache.retain((_, linkedClassCache) => linkedClassCache.cleanAfterRun()) + } + } + + private class LinkedClassInfoCache { + private var cacheUsed: Boolean = false + private val staticMethodsInfoCaches = LinkedMembersInfosCache() + private val memberMethodsInfoCaches = LinkedMembersInfosCache() + private val abstractMethodsInfoCaches = LinkedMembersInfosCache() + private val exportedMembersInfoCaches = LinkedMembersInfosCache() + private var info: Infos.ClassInfo = _ + + def loadInfo(linkedClass: LinkedClass): Infos.ClassInfo = { + update(linkedClass) + info + } + + private def update(linkedClass: LinkedClass): Unit = { + if (!cacheUsed) { + cacheUsed = true + + val builder = new Infos.ClassInfoBuilder() + .setEncodedName(linkedClass.encodedName) + .setKind(linkedClass.kind) + .setSuperClass(linkedClass.superClass.map(_.name)) + .addInterfaces(linkedClass.interfaces.map(_.name)) + + for (linkedMethod <- linkedClass.staticMethods) + builder.addMethod(staticMethodsInfoCaches.getInfo(linkedMethod)) + for (linkedMethod <- linkedClass.memberMethods) + builder.addMethod(memberMethodsInfoCaches.getInfo(linkedMethod)) + for (linkedMethod <- linkedClass.abstractMethods) + builder.addMethod(abstractMethodsInfoCaches.getInfo(linkedMethod)) + for (linkedMember <- linkedClass.exportedMembers) + builder.addMethod(exportedMembersInfoCaches.getInfo(linkedMember)) + + if (linkedClass.topLevelExports.nonEmpty) { + /* We do not cache top-level exports, because they're quite rare, + * and usually quite small when they exist. + */ + builder.setIsExported(true) + + val optInfo = Infos.generateTopLevelExportsInfo( + linkedClass.encodedName, linkedClass.topLevelExports.map(_.value)) + optInfo.foreach(builder.addMethod(_)) + } + + info = builder.result() + } + } + + /** Returns true if the cache has been used and should be kept. */ + def cleanAfterRun(): Boolean = { + val result = cacheUsed + cacheUsed = false + if (result) { + // No point in cleaning the inner caches if the whole class disappears + staticMethodsInfoCaches.cleanAfterRun() + memberMethodsInfoCaches.cleanAfterRun() + abstractMethodsInfoCaches.cleanAfterRun() + exportedMembersInfoCaches.cleanAfterRun() + } + result + } + } + + private final class LinkedMembersInfosCache( + val caches: mutable.Map[(Boolean, String), LinkedMemberInfoCache]) + extends AnyVal { + + def getInfo(member: Versioned[MemberDef]): Infos.MethodInfo = { + val memberDef = member.value + val cache = caches.getOrElseUpdate( + (memberDef.static, memberDef.encodedName), new LinkedMemberInfoCache) + cache.getInfo(member) + } + + def cleanAfterRun(): Unit = { + caches.retain((_, cache) => cache.cleanAfterRun()) + } + } + + private object LinkedMembersInfosCache { + def apply(): LinkedMembersInfosCache = + new LinkedMembersInfosCache(mutable.Map.empty) + } + + private final class LinkedMemberInfoCache { + private var cacheUsed: Boolean = false + private var lastVersion: Option[String] = None + private var info: Infos.MethodInfo = _ + + def getInfo(member: Versioned[MemberDef]): Infos.MethodInfo = { + update(member) + info + } + + def update(member: Versioned[MemberDef]): Unit = { + if (!cacheUsed) { + cacheUsed = true + + val newVersion = member.version + if (!versionsMatch(newVersion, lastVersion)) { + info = member.value match { + case _: FieldDef => + throw new AssertionError( + "A LinkedMemberInfoCache cannot be used for a FieldDef") + case methodDef: MethodDef => + Infos.generateMethodInfo(methodDef) + case propertyDef: PropertyDef => + Infos.generatePropertyInfo(propertyDef) + } + lastVersion = newVersion + } + } + } + + /** Returns true if the cache has been used and should be kept. */ + def cleanAfterRun(): Boolean = { + val result = cacheUsed + cacheUsed = false + result + } + } + + private def versionsMatch(a: Option[String], b: Option[String]): Boolean = + a.isDefined && b.isDefined && a.get == b.get +} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala index 6d473f7407..b319dc31d1 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala @@ -131,7 +131,7 @@ abstract class GenIncOptimizer private[optimizer] (config: CommonPhaseConfig) { val newLinkedClasses = for (linkedClass <- unit.classDefs) yield { def defs(container: Option[MethodContainer]) = - container.fold[List[LinkedMember[MethodDef]]](Nil)(_.optimizedDefs) + container.fold[List[Versioned[MethodDef]]](Nil)(_.optimizedDefs) val encodedName = linkedClass.encodedName val memberNamespace = @@ -143,7 +143,7 @@ abstract class GenIncOptimizer private[optimizer] (config: CommonPhaseConfig) { memberMethods = defs(memberNamespace)) } - unit.updated(classDefs = newLinkedClasses) + new LinkingUnit(unit.coreSpec, newLinkedClasses, unit.moduleInitializers) } } @@ -307,7 +307,7 @@ abstract class GenIncOptimizer private[optimizer] (config: CommonPhaseConfig) { val methods = mutable.Map.empty[String, MethodImpl] - def optimizedDefs: List[LinkedMember[MethodDef]] = { + def optimizedDefs: List[Versioned[MethodDef]] = { (for { method <- methods.values if !method.deleted @@ -328,7 +328,7 @@ abstract class GenIncOptimizer private[optimizer] (config: CommonPhaseConfig) { if (isStatic) linkedClass.staticMethods else linkedClass.memberMethods - val newMethodNames = linkedMethodDefs.map(_.info.encodedName).toSet + val newMethodNames = linkedMethodDefs.map(_.value.encodedName).toSet val methodSetChanged = methods.keySet != newMethodNames if (methodSetChanged) { // Remove deleted methods @@ -351,8 +351,7 @@ abstract class GenIncOptimizer private[optimizer] (config: CommonPhaseConfig) { } for (linkedMethodDef <- linkedMethodDefs) { - val methodInfo = linkedMethodDef.info - val methodName = methodInfo.encodedName + val methodName = linkedMethodDef.value.encodedName methods.get(methodName).fold { addedMethods += methodName @@ -811,7 +810,7 @@ abstract class GenIncOptimizer private[optimizer] (config: CommonPhaseConfig) { var optimizerHints: OptimizerHints = OptimizerHints.empty var originalDef: MethodDef = _ - var optimizedMethodDef: LinkedMember[MethodDef] = _ + var optimizedMethodDef: Versioned[MethodDef] = _ def thisType: Type = owner.thisType def deleted: Boolean = _deleted @@ -886,7 +885,7 @@ abstract class GenIncOptimizer private[optimizer] (config: CommonPhaseConfig) { * In the process, tags all the body askers if the body changes. * UPDATE PASS ONLY. Not concurrency safe on same instance. */ - def updateWith(linkedMethod: LinkedMember[MethodDef]): Boolean = { + def updateWith(linkedMethod: Versioned[MethodDef]): Boolean = { assert(!_deleted, "updateWith() called on a deleted method") if (lastInVersion.isDefined && lastInVersion == linkedMethod.version) { @@ -894,7 +893,7 @@ abstract class GenIncOptimizer private[optimizer] (config: CommonPhaseConfig) { } else { lastInVersion = linkedMethod.version - val methodDef = linkedMethod.tree + val methodDef = linkedMethod.value val changed = { originalDef == null || @@ -944,10 +943,10 @@ abstract class GenIncOptimizer private[optimizer] (config: CommonPhaseConfig) { /** PROCESS PASS ONLY. */ def process(): Unit = if (!_deleted) { - val rawOptimizedDef = new Optimizer().optimize(thisType, originalDef) + val optimizedDef = new Optimizer().optimize(thisType, originalDef) lastOutVersion += 1 - optimizedMethodDef = new LinkedMember(rawOptimizedDef.info, - rawOptimizedDef.tree, Some(lastOutVersion.toString)) + optimizedMethodDef = + new Versioned(optimizedDef, Some(lastOutVersion.toString)) resetTag() } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index 476d35bbed..b0de1fbf29 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -114,7 +114,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { private lazy val inlinedRTLongHiField = inlinedRTLongRecordType.fields(1).name - def optimize(thisType: Type, originalDef: MethodDef): LinkedMember[MethodDef] = { + def optimize(thisType: Type, originalDef: MethodDef): MethodDef = { try { val MethodDef(static, name, params, resultType, optBody) = originalDef val body = optBody getOrElse { @@ -135,11 +135,8 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { val newBody = if (name.encodedName == "init___") tryElimStoreModule(newBody1) else newBody1 - val m = MethodDef(static, name, newParams, resultType, + MethodDef(static, name, newParams, resultType, Some(newBody))(originalDef.optimizerHints, None)(originalDef.pos) - val info = Infos.generateMethodInfo(m) - - new LinkedMember(info, m, None) } catch { case NonFatal(cause) => throw new OptimizeException(myself, attemptedInlining.distinct.toList, cause) From 9890ee769ee55adc0ef0514760d08e3fe3a3c2a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 7 Aug 2017 19:07:11 +0200 Subject: [PATCH 0440/2665] Redesign primitive numeric types in the IR. * Add types for `char`, `byte` and `short` in the IR. * Remove the subtyping relationships between primitive types, for example `int <: double`. Instead of the subtyping relationships, we introduce explicit widening conversions as `UnaryOp`s. In order to avoid widening `int`s to `double`s for the purpose of comparing them, we separate `Num_<` and friends into `Int_<` and `Double_<`. For floats, we do introduce the conversions in that case. There is one subtlety for `char` (`CharType`): it is *not* a subtype of `any`. That's because `char`s must always be boxed in `j.l.Character` when they are assigned to an `any`. This fixes #3085, and provides a cleaner solution to the old issues #2184 and #2780. --- .../org/scalajs/core/compiler/GenJSCode.scala | 489 ++++++++---------- .../org/scalajs/core/compiler/TypeKinds.scala | 14 +- .../scala/org/scalajs/core/ir/Hashers.scala | 24 + .../scala/org/scalajs/core/ir/Printers.scala | 100 +++- .../org/scalajs/core/ir/Serializers.scala | 21 + .../main/scala/org/scalajs/core/ir/Tags.scala | 10 +- .../scala/org/scalajs/core/ir/Trees.scala | 203 +++++--- .../scala/org/scalajs/core/ir/Types.scala | 44 +- .../org/scalajs/core/ir/PrintersTest.scala | 142 +++-- .../src/main/scala/java/lang/Integer.scala | 16 - project/JavaLangString.scala | 4 +- ...nstanceTestsHijackedBoxedClassesTest.scala | 4 + .../testsuite/compiler/OptimizerTest.scala | 67 +++ .../testsuite/javalib/lang/DoubleTest.scala | 18 + .../core/tools/linker/analyzer/Infos.scala | 4 +- .../backend/emitter/FunctionEmitter.scala | 116 +++-- .../tools/linker/backend/emitter/JSGen.scala | 3 + .../core/tools/linker/checker/IRChecker.scala | 83 +-- .../frontend/optimizer/GenIncOptimizer.scala | 19 - .../frontend/optimizer/OptimizerCore.scala | 484 ++++++++++------- 20 files changed, 1125 insertions(+), 740 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 370e71883a..1f95e77382 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -1233,13 +1233,13 @@ abstract class GenJSCode extends plugins.PluginComponent js.BinaryOp(js.BinaryOp.===, js.IntLiteral(lo), numRef) case (lo, hi) if lo == hi - 1 => - val lhs = js.BinaryOp(js.BinaryOp.===, numRef, js.IntLiteral(lo)) - val rhs = js.BinaryOp(js.BinaryOp.===, numRef, js.IntLiteral(hi)) + val lhs = js.BinaryOp(js.BinaryOp.Int_==, numRef, js.IntLiteral(lo)) + val rhs = js.BinaryOp(js.BinaryOp.Int_==, numRef, js.IntLiteral(hi)) js.If(lhs, js.BooleanLiteral(true), rhs)(jstpe.BooleanType) case (lo, hi) => - val lhs = js.BinaryOp(js.BinaryOp.Num_<=, js.IntLiteral(lo), numRef) - val rhs = js.BinaryOp(js.BinaryOp.Num_<=, numRef, js.IntLiteral(hi)) + val lhs = js.BinaryOp(js.BinaryOp.Int_<=, js.IntLiteral(lo), numRef) + val rhs = js.BinaryOp(js.BinaryOp.Int_<=, numRef, js.IntLiteral(hi)) js.BinaryOp(js.BinaryOp.Boolean_&, lhs, rhs) js.If(lhs, rhs, js.BooleanLiteral(false))(jstpe.BooleanType) } @@ -1799,7 +1799,7 @@ abstract class GenJSCode extends plugins.PluginComponent val sym = tree.symbol val rhsTree = - if (rhs == EmptyTree) genZeroOf(sym.tpe) + if (rhs == EmptyTree) jstpe.zeroOf(toIRType(sym.tpe)) else genExpr(rhs) rhsTree match { @@ -1912,7 +1912,13 @@ abstract class GenJSCode extends plugins.PluginComponent js.Skip() case BooleanTag => js.BooleanLiteral(value.booleanValue) - case ByteTag | ShortTag | CharTag | IntTag => + case ByteTag => + js.ByteLiteral(value.byteValue) + case ShortTag => + js.ShortLiteral(value.shortValue) + case CharTag => + js.CharLiteral(value.charValue) + case IntTag => js.IntLiteral(value.intValue) case LongTag => js.LongLiteral(value.longValue) @@ -2342,10 +2348,17 @@ abstract class GenJSCode extends plugins.PluginComponent val r = toTypeKind(to) if (l.isValueType && r.isValueType) { - if (cast) - genConversion(l, r, expr) - else + if (cast) { + /* It is unclear whether this case can be reached for all type + * conversions, but scalac handles all cases, so we do too. + * Three known user code patterns that become code handled by this + * case are `byte.##`, `short.##` and `char.##`, which become, e.g., + * `char.toChar().$asInstanceOf[Int]`. + */ + genConversion(l.toIRType, r.toIRType, expr) + } else { js.BooleanLiteral(l == r) + } } else if (l.isValueType) { val result = if (cast) { val ctor = ClassCastExceptionClass.info.member( @@ -2636,29 +2649,63 @@ abstract class GenJSCode extends plugins.PluginComponent arguments)(resultType) } - /** Gen JS code for a conversion between primitive value types */ - def genConversion(from: TypeKind, to: TypeKind, value: js.Tree)( + private def adaptPrimitive(value: js.Tree, to: jstpe.Type)( implicit pos: Position): js.Tree = { - def int0 = js.IntLiteral(0) - def int1 = js.IntLiteral(1) - def long0 = js.LongLiteral(0L) - def long1 = js.LongLiteral(1L) - def float0 = js.FloatLiteral(0.0f) - def float1 = js.FloatLiteral(1.0f) - - // scalastyle:off disallow.space.before.token - (from, to) match { - case (INT(_), BOOL) => js.BinaryOp(js.BinaryOp.Num_!=, value, int0) - case (LONG, BOOL) => js.BinaryOp(js.BinaryOp.Long_!=, value, long0) - case (FLOAT(_), BOOL) => js.BinaryOp(js.BinaryOp.Num_!=, value, float0) - - case (BOOL, INT(_)) => js.If(value, int1, int0 )(jstpe.IntType) - case (BOOL, LONG) => js.If(value, long1, long0 )(jstpe.LongType) - case (BOOL, FLOAT(_)) => js.If(value, float1, float0)(jstpe.FloatType) - - case _ => value - } - // scalastyle:on disallow.space.before.token + genConversion(value.tpe, to, value) + } + + /* This method corresponds to the method of the same name in + * BCodeBodyBuilder of the JVM back-end. It ends up calling the method + * BCodeIdiomatic.emitT2T, whose logic we replicate here. + */ + private def genConversion(from: jstpe.Type, to: jstpe.Type, value: js.Tree)( + implicit pos: Position): js.Tree = { + import js.UnaryOp._ + + if (from == to || from == jstpe.NothingType) { + value + } else if (from == jstpe.BooleanType || to == jstpe.BooleanType) { + throw new AssertionError(s"Invalid genConversion from $from to $to") + } else { + def intValue = (from: @unchecked) match { + case jstpe.IntType => value + case jstpe.CharType => js.UnaryOp(CharToInt, value) + case jstpe.ByteType => js.UnaryOp(ByteToInt, value) + case jstpe.ShortType => js.UnaryOp(ShortToInt, value) + case jstpe.LongType => js.UnaryOp(LongToInt, value) + case jstpe.FloatType => js.UnaryOp(DoubleToInt, js.UnaryOp(FloatToDouble, value)) + case jstpe.DoubleType => js.UnaryOp(DoubleToInt, value) + } + + def doubleValue = from match { + case jstpe.DoubleType => value + case jstpe.FloatType => js.UnaryOp(FloatToDouble, value) + case jstpe.LongType => js.UnaryOp(LongToDouble, value) + case _ => js.UnaryOp(IntToDouble, intValue) + } + + (to: @unchecked) match { + case jstpe.CharType => + js.UnaryOp(IntToChar, intValue) + case jstpe.ByteType => + js.UnaryOp(IntToByte, intValue) + case jstpe.ShortType => + js.UnaryOp(IntToShort, intValue) + case jstpe.IntType => + intValue + case jstpe.LongType => + from match { + case jstpe.FloatType | jstpe.DoubleType => + js.UnaryOp(DoubleToLong, doubleValue) + case _ => + js.UnaryOp(IntToLong, intValue) + } + case jstpe.FloatType => + js.UnaryOp(js.UnaryOp.DoubleToFloat, doubleValue) + case jstpe.DoubleType => + doubleValue + } + } } /** Gen JS code for an isInstanceOf test (for reference types only) */ @@ -3209,135 +3256,176 @@ abstract class GenJSCode extends plugins.PluginComponent implicit val pos = tree.pos - val isShift = isShiftOp(code) - - def isLongOp(ltpe: Type, rtpe: Type) = { - if (isShift) { - isLongType(ltpe) - } else { - (isLongType(ltpe) || isLongType(rtpe)) && - !(toTypeKind(ltpe).isInstanceOf[FLOAT] || - toTypeKind(rtpe).isInstanceOf[FLOAT] || - isStringType(ltpe) || isStringType(rtpe)) - } - } - - val sources = args map genExpr - - val resultType = toIRType(tree.tpe) + val sources = args.map(genExpr) sources match { // Unary operation - case List(source) => + case List(src_in) => + val opType = toIRType(tree.tpe) + val src = adaptPrimitive(src_in, opType) + (code match { case POS => - source + src case NEG => - (resultType: @unchecked) match { + (opType: @unchecked) match { case jstpe.IntType => - js.BinaryOp(js.BinaryOp.Int_-, js.IntLiteral(0), source) + js.BinaryOp(js.BinaryOp.Int_-, js.IntLiteral(0), src) case jstpe.LongType => - js.BinaryOp(js.BinaryOp.Long_-, js.LongLiteral(0), source) + js.BinaryOp(js.BinaryOp.Long_-, js.LongLiteral(0), src) case jstpe.FloatType => - js.BinaryOp(js.BinaryOp.Float_-, js.FloatLiteral(0.0f), source) + js.BinaryOp(js.BinaryOp.Float_-, js.FloatLiteral(0.0f), src) case jstpe.DoubleType => - js.BinaryOp(js.BinaryOp.Double_-, js.DoubleLiteral(0), source) + js.BinaryOp(js.BinaryOp.Double_-, js.DoubleLiteral(0), src) } case NOT => - (resultType: @unchecked) match { + (opType: @unchecked) match { case jstpe.IntType => - js.BinaryOp(js.BinaryOp.Int_^, js.IntLiteral(-1), source) + js.BinaryOp(js.BinaryOp.Int_^, js.IntLiteral(-1), src) case jstpe.LongType => - js.BinaryOp(js.BinaryOp.Long_^, js.LongLiteral(-1), source) + js.BinaryOp(js.BinaryOp.Long_^, js.LongLiteral(-1), src) } case ZNOT => - js.UnaryOp(js.UnaryOp.Boolean_!, source) + js.UnaryOp(js.UnaryOp.Boolean_!, src) case _ => abort("Unknown unary operation code: " + code) }) - // Binary operation on Longs - case List(lsrc, rsrc) if isLongOp(args(0).tpe, args(1).tpe) => - def toLong(tree: js.Tree, tpe: Type) = - if (isLongType(tpe)) tree - else js.UnaryOp(js.UnaryOp.IntToLong, tree) - - def toInt(tree: js.Tree, tpe: Type) = - if (isLongType(tpe)) js.UnaryOp(js.UnaryOp.LongToInt, rsrc) - else tree - - val ltree = toLong(lsrc, args(0).tpe) - def rtree = toLong(rsrc, args(1).tpe) - def rtreeInt = toInt(rsrc, args(1).tpe) - - import js.BinaryOp._ - (code: @switch) match { - case ADD => js.BinaryOp(Long_+, ltree, rtree) - case SUB => js.BinaryOp(Long_-, ltree, rtree) - case MUL => js.BinaryOp(Long_*, ltree, rtree) - case DIV => js.BinaryOp(Long_/, ltree, rtree) - case MOD => js.BinaryOp(Long_%, ltree, rtree) - case OR => js.BinaryOp(Long_|, ltree, rtree) - case XOR => js.BinaryOp(Long_^, ltree, rtree) - case AND => js.BinaryOp(Long_&, ltree, rtree) - case LSL => js.BinaryOp(Long_<<, ltree, rtreeInt) - case LSR => js.BinaryOp(Long_>>>, ltree, rtreeInt) - case ASR => js.BinaryOp(Long_>>, ltree, rtreeInt) - case EQ => js.BinaryOp(Long_==, ltree, rtree) - case NE => js.BinaryOp(Long_!=, ltree, rtree) - case LT => js.BinaryOp(Long_<, ltree, rtree) - case LE => js.BinaryOp(Long_<=, ltree, rtree) - case GT => js.BinaryOp(Long_>, ltree, rtree) - case GE => js.BinaryOp(Long_>=, ltree, rtree) - case _ => - abort("Unknown binary operation code: " + code) - } - // Binary operation case List(lsrc_in, rsrc_in) => + import js.BinaryOp._ + + val isShift = isShiftOp(code) val leftKind = toTypeKind(args(0).tpe) val rightKind = toTypeKind(args(1).tpe) - val opType = (leftKind, rightKind) match { - case (DoubleKind, _) | (_, DoubleKind) => jstpe.DoubleType - case (FloatKind, _) | (_, FloatKind) => jstpe.FloatType - case (INT(_), _) | (_, INT(_)) => jstpe.IntType - case (BooleanKind, BooleanKind) => jstpe.BooleanType - case _ => jstpe.AnyType + val opType = { + if (isShift) { + if (leftKind == LongKind) jstpe.LongType + else jstpe.IntType + } else { + (leftKind, rightKind) match { + case (DoubleKind, _) | (_, DoubleKind) => jstpe.DoubleType + case (FloatKind, _) | (_, FloatKind) => jstpe.FloatType + case (LONG, _) | (_, LONG) => jstpe.LongType + case (INT(_), _) | (_, INT(_)) => jstpe.IntType + case (BOOL, _) | (_, BOOL) => jstpe.BooleanType + case _ => jstpe.AnyType + } + } } - def convertArg(tree: js.Tree, kind: TypeKind) = { - /* If we end up with a long, the op type must be float or double, - * so we can first eliminate the Long case by converting to Double. - * - * Unless it is a shift operation, in which case the op type would - * be int. - */ - val notLong = { - if (kind != LongKind) tree - else if (isShift) js.UnaryOp(js.UnaryOp.LongToInt, tree) - else js.UnaryOp(js.UnaryOp.LongToDouble, tree) - } + val lsrc = + if (opType == jstpe.AnyType) lsrc_in + else adaptPrimitive(lsrc_in, opType) + val rsrc = + if (opType == jstpe.AnyType) rsrc_in + else adaptPrimitive(rsrc_in, if (isShift) jstpe.IntType else opType) + + (opType: @unchecked) match { + case jstpe.IntType => + val op = (code: @switch) match { + case ADD => Int_+ + case SUB => Int_- + case MUL => Int_* + case DIV => Int_/ + case MOD => Int_% + case OR => Int_| + case AND => Int_& + case XOR => Int_^ + case LSL => Int_<< + case LSR => Int_>>> + case ASR => Int_>> + case EQ => Int_== + case NE => Int_!= + case LT => Int_< + case LE => Int_<= + case GT => Int_> + case GE => Int_>= + } + js.BinaryOp(op, lsrc, rsrc) - if (opType != jstpe.FloatType) notLong - else if (kind == FloatKind) notLong - else js.UnaryOp(js.UnaryOp.DoubleToFloat, notLong) - } + case jstpe.LongType => + val op = (code: @switch) match { + case ADD => Long_+ + case SUB => Long_- + case MUL => Long_* + case DIV => Long_/ + case MOD => Long_% + case OR => Long_| + case XOR => Long_^ + case AND => Long_& + case LSL => Long_<< + case LSR => Long_>>> + case ASR => Long_>> + case EQ => Long_== + case NE => Long_!= + case LT => Long_< + case LE => Long_<= + case GT => Long_> + case GE => Long_>= + } + js.BinaryOp(op, lsrc, rsrc) - val lsrc = convertArg(lsrc_in, leftKind) - val rsrc = convertArg(rsrc_in, rightKind) - - def genEquality(eqeq: Boolean, not: Boolean) = { - opType match { - case jstpe.IntType | jstpe.DoubleType | jstpe.FloatType => - js.BinaryOp( - if (not) js.BinaryOp.Num_!= else js.BinaryOp.Num_==, - lsrc, rsrc) - case jstpe.BooleanType => - js.BinaryOp( - if (not) js.BinaryOp.Boolean_!= else js.BinaryOp.Boolean_==, - lsrc, rsrc) - case _ => + case jstpe.FloatType => + def withFloats(op: Int): js.Tree = + js.BinaryOp(op, lsrc, rsrc) + + def toDouble(value: js.Tree): js.Tree = + js.UnaryOp(js.UnaryOp.FloatToDouble, value) + + def withDoubles(op: Int): js.Tree = + js.BinaryOp(op, toDouble(lsrc), toDouble(rsrc)) + + (code: @switch) match { + case ADD => withFloats(Float_+) + case SUB => withFloats(Float_-) + case MUL => withFloats(Float_*) + case DIV => withFloats(Float_/) + case MOD => withFloats(Float_%) + + case EQ => withDoubles(Double_==) + case NE => withDoubles(Double_!=) + case LT => withDoubles(Double_<) + case LE => withDoubles(Double_<=) + case GT => withDoubles(Double_>) + case GE => withDoubles(Double_>=) + } + + case jstpe.DoubleType => + val op = (code: @switch) match { + case ADD => Double_+ + case SUB => Double_- + case MUL => Double_* + case DIV => Double_/ + case MOD => Double_% + case EQ => Double_== + case NE => Double_!= + case LT => Double_< + case LE => Double_<= + case GT => Double_> + case GE => Double_>= + } + js.BinaryOp(op, lsrc, rsrc) + + case jstpe.BooleanType => + (code: @switch) match { + case OR => + js.BinaryOp(Boolean_|, lsrc, rsrc) + case AND => + js.BinaryOp(Boolean_&, lsrc, rsrc) + case EQ => + js.BinaryOp(Boolean_==, lsrc, rsrc) + case XOR | NE => + js.BinaryOp(Boolean_!=, lsrc, rsrc) + case ZOR => + js.If(lsrc, js.BooleanLiteral(true), rsrc)(jstpe.BooleanType) + case ZAND => + js.If(lsrc, rsrc, js.BooleanLiteral(false))(jstpe.BooleanType) + } + + case jstpe.AnyType => + def genAnyEquality(eqeq: Boolean, not: Boolean): js.Tree = { if (eqeq && // don't call equals if we have a literal null at either side !lsrc.isInstanceOf[js.Null] && @@ -3351,63 +3439,14 @@ abstract class GenJSCode extends plugins.PluginComponent if (not) js.BinaryOp.!== else js.BinaryOp.===, lsrc, rsrc) } - } - } - - (code: @switch) match { - case EQ => genEquality(eqeq = true, not = false) - case NE => genEquality(eqeq = true, not = true) - case ID => genEquality(eqeq = false, not = false) - case NI => genEquality(eqeq = false, not = true) - - case ZOR => js.If(lsrc, js.BooleanLiteral(true), rsrc)(jstpe.BooleanType) - case ZAND => js.If(lsrc, rsrc, js.BooleanLiteral(false))(jstpe.BooleanType) + } - case _ => - import js.BinaryOp._ - val op = (resultType: @unchecked) match { - case jstpe.IntType => - (code: @switch) match { - case ADD => Int_+ - case SUB => Int_- - case MUL => Int_* - case DIV => Int_/ - case MOD => Int_% - case OR => Int_| - case AND => Int_& - case XOR => Int_^ - case LSL => Int_<< - case LSR => Int_>>> - case ASR => Int_>> - } - case jstpe.FloatType => - (code: @switch) match { - case ADD => Float_+ - case SUB => Float_- - case MUL => Float_* - case DIV => Float_/ - case MOD => Float_% - } - case jstpe.DoubleType => - (code: @switch) match { - case ADD => Double_+ - case SUB => Double_- - case MUL => Double_* - case DIV => Double_/ - case MOD => Double_% - } - case jstpe.BooleanType => - (code: @switch) match { - case LT => Num_< - case LE => Num_<= - case GT => Num_> - case GE => Num_>= - case OR => Boolean_| - case AND => Boolean_& - case XOR => Boolean_!= - } + (code: @switch) match { + case EQ => genAnyEquality(eqeq = true, not = false) + case NE => genAnyEquality(eqeq = true, not = true) + case ID => genAnyEquality(eqeq = false, not = false) + case NI => genAnyEquality(eqeq = false, not = true) } - js.BinaryOp(op, lsrc, rsrc) } case _ => @@ -3598,74 +3637,11 @@ abstract class GenJSCode extends plugins.PluginComponent /** Gen JS code for a coercion */ private def genCoercion(tree: Apply, receiver: Tree, code: Int): js.Tree = { - import scalaPrimitives._ - implicit val pos = tree.pos val source = genExpr(receiver) - - def source2int = (code: @switch) match { - case F2C | D2C | F2B | D2B | F2S | D2S | F2I | D2I => - js.UnaryOp(js.UnaryOp.DoubleToInt, source) - case L2C | L2B | L2S | L2I => - js.UnaryOp(js.UnaryOp.LongToInt, source) - case _ => - source - } - - (code: @switch) match { - // To Char, need to crop at unsigned 16-bit - case B2C | S2C | I2C | L2C | F2C | D2C => - js.BinaryOp(js.BinaryOp.Int_&, source2int, js.IntLiteral(0xffff)) - - // To Byte, need to crop at signed 8-bit - case C2B | S2B | I2B | L2B | F2B | D2B => - // note: & 0xff would not work because of negative values - js.BinaryOp(js.BinaryOp.Int_>>, - js.BinaryOp(js.BinaryOp.Int_<<, source2int, js.IntLiteral(24)), - js.IntLiteral(24)) - - // To Short, need to crop at signed 16-bit - case C2S | I2S | L2S | F2S | D2S => - // note: & 0xffff would not work because of negative values - js.BinaryOp(js.BinaryOp.Int_>>, - js.BinaryOp(js.BinaryOp.Int_<<, source2int, js.IntLiteral(16)), - js.IntLiteral(16)) - - // To Int, need to crop at signed 32-bit - case L2I | F2I | D2I => - source2int - - // Any int to Long - case C2L | B2L | S2L | I2L => - js.UnaryOp(js.UnaryOp.IntToLong, source) - - // Any double to Long - case F2L | D2L => - js.UnaryOp(js.UnaryOp.DoubleToLong, source) - - // Long to Double - case L2D => - js.UnaryOp(js.UnaryOp.LongToDouble, source) - - // Any int, or Double, to Float - case C2F | B2F | S2F | I2F | D2F => - js.UnaryOp(js.UnaryOp.DoubleToFloat, source) - - // Long to Float === Long to Double to Float - case L2F => - js.UnaryOp(js.UnaryOp.DoubleToFloat, - js.UnaryOp(js.UnaryOp.LongToDouble, source)) - - // Identities and IR upcasts - case C2C | B2B | S2S | I2I | L2L | F2F | D2D | - C2I | C2D | - B2S | B2I | B2D | - S2I | S2D | - I2D | - F2D => - source - } + val resultType = toIRType(tree.tpe) + adaptPrimitive(source, resultType) } /** Gen JS code for an ApplyDynamic @@ -5318,17 +5294,6 @@ abstract class GenJSCode extends plugins.PluginComponent // Utilities --------------------------------------------------------------- - /** Generate a literal "zero" for the requested type */ - def genZeroOf(tpe: Type)(implicit pos: Position): js.Tree = toTypeKind(tpe) match { - case VOID => abort("Cannot call genZeroOf(VOID)") - case BOOL => js.BooleanLiteral(false) - case LONG => js.LongLiteral(0L) - case INT(_) => js.IntLiteral(0) - case FloatKind => js.FloatLiteral(0.0f) - case DoubleKind => js.DoubleLiteral(0.0) - case _ => js.Null() - } - /** Generate loading of a module value. * * Can be given either the module symbol or its module class symbol. diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/TypeKinds.scala b/compiler/src/main/scala/org/scalajs/core/compiler/TypeKinds.scala index b317962ff2..20ee759cf6 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/TypeKinds.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/TypeKinds.scala @@ -91,7 +91,12 @@ trait TypeKinds extends SubComponent { this: GenJSCode => /** Integer number (Byte, Short, Char or Int). */ case class INT private[TypeKinds] (typeSymbol: Symbol) extends ValueTypeKind { - def toIRType: Types.IntType.type = Types.IntType + val toIRType: Types.Type = typeSymbol match { + case CharClass => Types.CharType + case ByteClass => Types.ByteType + case ShortClass => Types.ShortType + case IntClass => Types.IntType + } } /** Long */ @@ -102,9 +107,10 @@ trait TypeKinds extends SubComponent { this: GenJSCode => /** Floating-point number (Float or Double). */ case class FLOAT private[TypeKinds] (typeSymbol: Symbol) extends ValueTypeKind { - def toIRType: Types.Type = - if (typeSymbol == FloatClass) Types.FloatType - else Types.DoubleType + val toIRType: Types.Type = typeSymbol match { + case FloatClass => Types.FloatType + case DoubleClass => Types.DoubleType + } } /** Boolean */ diff --git a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala index 1c2a877a6b..c726dfc416 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala @@ -395,6 +395,18 @@ object Hashers { mixTag(TagBooleanLiteral) mixBoolean(value) + case CharLiteral(value) => + mixTag(TagCharLiteral) + mixChar(value) + + case ByteLiteral(value) => + mixTag(TagByteLiteral) + mixByte(value) + + case ShortLiteral(value) => + mixTag(TagShortLiteral) + mixShort(value) + case IntLiteral(value) => mixTag(TagIntLiteral) mixInt(value) @@ -459,6 +471,9 @@ object Hashers { case NothingType => mixTag(TagNothingType) case UndefType => mixTag(TagUndefType) case BooleanType => mixTag(TagBooleanType) + case CharType => mixTag(TagCharType) + case ByteType => mixTag(TagByteType) + case ShortType => mixTag(TagShortType) case IntType => mixTag(TagIntType) case LongType => mixTag(TagLongType) case FloatType => mixTag(TagFloatType) @@ -521,6 +536,15 @@ object Hashers { @inline final def mixString(str: String): Unit = digestStream.writeUTF(str) + @inline + final def mixChar(c: Char): Unit = digestStream.writeChar(c) + + @inline + final def mixByte(b: Byte): Unit = digestStream.writeByte(b) + + @inline + final def mixShort(s: Short): Unit = digestStream.writeShort(s) + @inline final def mixInt(i: Int): Unit = digestStream.writeInt(i) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index 5153e2717c..d65f3074df 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -329,11 +329,22 @@ object Printers { import UnaryOp._ print('(') print((op: @switch) match { - case Boolean_! => "!" - case IntToLong | DoubleToLong => "(long)" - case DoubleToInt | LongToInt => "(int)" - case DoubleToFloat => "(float)" - case LongToDouble => "(double)" + case Boolean_! => + "!" + case IntToChar => + "(char)" + case IntToByte => + "(byte)" + case IntToShort => + "(short)" + case CharToInt | ByteToInt | ShortToInt | LongToInt | DoubleToInt => + "(int)" + case IntToLong | DoubleToLong => + "(long)" + case DoubleToFloat => + "(float)" + case IntToDouble | LongToDouble | FloatToDouble => + "(double)" }) print(lhs) print(')') @@ -380,6 +391,11 @@ object Printers { case String_+ => "+[string]" + case Boolean_== => "==[bool]" + case Boolean_!= => "!=[bool]" + case Boolean_| => "|[bool]" + case Boolean_& => "&[bool]" + case Int_+ => "+[int]" case Int_- => "-[int]" case Int_* => "*[int]" @@ -393,24 +409,12 @@ object Printers { case Int_>>> => ">>>[int]" case Int_>> => ">>[int]" - case Float_+ => "+[float]" - case Float_- => "-[float]" - case Float_* => "*[float]" - case Float_/ => "/[float]" - case Float_% => "%[float]" - - case Double_+ => "+[double]" - case Double_- => "-[double]" - case Double_* => "*[double]" - case Double_/ => "/[double]" - case Double_% => "%[double]" - - case Num_== => "==" - case Num_!= => "!=" - case Num_< => "<" - case Num_<= => "<=" - case Num_> => ">" - case Num_>= => ">=" + case Int_== => "==[int]" + case Int_!= => "!=[int]" + case Int_< => "<[int]" + case Int_<= => "<=[int]" + case Int_> => ">[int]" + case Int_>= => ">=[int]" case Long_+ => "+[long]" case Long_- => "-[long]" @@ -432,10 +436,24 @@ object Printers { case Long_> => ">[long]" case Long_>= => ">=[long]" - case Boolean_== => "==[bool]" - case Boolean_!= => "!=[bool]" - case Boolean_| => "|[bool]" - case Boolean_& => "&[bool]" + case Float_+ => "+[float]" + case Float_- => "-[float]" + case Float_* => "*[float]" + case Float_/ => "/[float]" + case Float_% => "%[float]" + + case Double_+ => "+[double]" + case Double_- => "-[double]" + case Double_* => "*[double]" + case Double_/ => "/[double]" + case Double_% => "%[double]" + + case Double_== => "==[double]" + case Double_!= => "!=[double]" + case Double_< => "<[double]" + case Double_<= => "<=[double]" + case Double_> => ">[double]" + case Double_>= => ">=[double]" }) print(' ') print(rhs) @@ -688,6 +706,31 @@ object Printers { case BooleanLiteral(value) => print(if (value) "true" else "false") + case CharLiteral(value) => + print('\'') + printEscapeJS(value.toString(), out) + print('\'') + + case ByteLiteral(value) => + if (value >= 0) { + print(value.toString) + print("_b") + } else { + print('(') + print(value.toString) + print("_b)") + } + + case ShortLiteral(value) => + if (value >= 0) { + print(value.toString) + print("_s") + } else { + print('(') + print(value.toString) + print("_s)") + } + case IntLiteral(value) => if (value >= 0) { print(value.toString) @@ -906,6 +949,9 @@ object Printers { case NothingType => print("nothing") case UndefType => print("void") case BooleanType => print("boolean") + case CharType => print("char") + case ByteType => print("byte") + case ShortType => print("short") case IntType => print("int") case LongType => print("long") case FloatType => print("float") diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index f43c33a62f..801ff69733 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -375,6 +375,18 @@ object Serializers { writeByte(TagBooleanLiteral) writeBoolean(value) + case CharLiteral(value) => + writeByte(TagCharLiteral) + writeChar(value) + + case ByteLiteral(value) => + writeByte(TagByteLiteral) + writeByte(value) + + case ShortLiteral(value) => + writeByte(TagShortLiteral) + writeShort(value) + case IntLiteral(value) => writeByte(TagIntLiteral) writeInt(value) @@ -572,6 +584,9 @@ object Serializers { case NothingType => buffer.write(TagNothingType) case UndefType => buffer.write(TagUndefType) case BooleanType => buffer.write(TagBooleanType) + case CharType => buffer.write(TagCharType) + case ByteType => buffer.write(TagByteType) + case ShortType => buffer.write(TagShortType) case IntType => buffer.write(TagIntType) case LongType => buffer.write(TagLongType) case FloatType => buffer.write(TagFloatType) @@ -863,6 +878,9 @@ object Serializers { case TagUndefined => Undefined() case TagNull => Null() case TagBooleanLiteral => BooleanLiteral(readBoolean()) + case TagCharLiteral => CharLiteral(readChar()) + case TagByteLiteral => ByteLiteral(readByte()) + case TagShortLiteral => ShortLiteral(readShort()) case TagIntLiteral => IntLiteral(readInt()) case TagLongLiteral => LongLiteral(readLong()) case TagFloatLiteral => FloatLiteral(readFloat()) @@ -989,6 +1007,9 @@ object Serializers { case TagNothingType => NothingType case TagUndefType => UndefType case TagBooleanType => BooleanType + case TagCharType => CharType + case TagByteType => ByteType + case TagShortType => ShortType case TagIntType => IntType case TagLongType => LongType case TagFloatType => FloatType diff --git a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala index e9e77f41ed..ee42d01568 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala @@ -78,7 +78,10 @@ private[ir] object Tags { final val TagUndefined = TagJSLinkingInfo + 1 final val TagNull = TagUndefined + 1 final val TagBooleanLiteral = TagNull + 1 - final val TagIntLiteral = TagBooleanLiteral + 1 + final val TagCharLiteral = TagBooleanLiteral + 1 + final val TagByteLiteral = TagCharLiteral + 1 + final val TagShortLiteral = TagByteLiteral + 1 + final val TagIntLiteral = TagShortLiteral + 1 final val TagLongLiteral = TagIntLiteral + 1 final val TagFloatLiteral = TagLongLiteral + 1 final val TagDoubleLiteral = TagFloatLiteral + 1 @@ -109,7 +112,10 @@ private[ir] object Tags { final val TagNothingType = TagAnyType + 1 final val TagUndefType = TagNothingType + 1 final val TagBooleanType = TagUndefType + 1 - final val TagIntType = TagBooleanType + 1 + final val TagCharType = TagBooleanType + 1 + final val TagByteType = TagCharType + 1 + final val TagShortType = TagByteType + 1 + final val TagIntType = TagShortType + 1 final val TagLongType = TagIntType + 1 final val TagFloatType = TagLongType + 1 final val TagDoubleType = TagFloatType + 1 diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index d09e17dcfa..4409ac7e84 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -272,19 +272,43 @@ object Trees { final val Boolean_! = 1 - final val IntToLong = 2 - final val LongToInt = 3 - final val LongToDouble = 4 - final val DoubleToInt = 5 - final val DoubleToFloat = 6 - final val DoubleToLong = 7 + // Widening conversions + final val CharToInt = 2 + final val ByteToInt = 3 + final val ShortToInt = 4 + final val IntToLong = 5 + final val IntToDouble = 6 + final val FloatToDouble = 7 + + // Narrowing conversions + final val IntToChar = 8 + final val IntToByte = 9 + final val IntToShort = 10 + final val LongToInt = 11 + final val DoubleToInt = 12 + final val DoubleToFloat = 13 + + // Long <-> Double (neither widening nor narrowing) + final val LongToDouble = 14 + final val DoubleToLong = 15 def resultTypeOf(op: Code): Type = (op: @switch) match { - case LongToInt | DoubleToInt => IntType - case IntToLong | DoubleToLong => LongType - case DoubleToFloat => FloatType - case LongToDouble => DoubleType - case Boolean_! => BooleanType + case Boolean_! => + BooleanType + case IntToChar => + CharType + case IntToByte => + ByteType + case IntToShort => + ShortType + case CharToInt | ByteToInt | ShortToInt | LongToInt | DoubleToInt => + IntType + case IntToLong | DoubleToLong => + LongType + case DoubleToFloat => + FloatType + case IntToDouble | LongToDouble | FloatToDouble => + DoubleType } } @@ -304,81 +328,89 @@ object Trees { final val String_+ = 3 - final val Int_+ = 4 - final val Int_- = 5 - final val Int_* = 6 - final val Int_/ = 7 - final val Int_% = 8 - - final val Int_| = 9 - final val Int_& = 10 - final val Int_^ = 11 - final val Int_<< = 12 - final val Int_>>> = 13 - final val Int_>> = 14 - - final val Float_+ = 15 - final val Float_- = 16 - final val Float_* = 17 - final val Float_/ = 18 - final val Float_% = 19 - - final val Double_+ = 20 - final val Double_- = 21 - final val Double_* = 22 - final val Double_/ = 23 - final val Double_% = 24 - - final val Num_== = 25 - final val Num_!= = 26 - final val Num_< = 27 - final val Num_<= = 28 - final val Num_> = 29 - final val Num_>= = 30 - - final val Long_+ = 31 - final val Long_- = 32 - final val Long_* = 33 - final val Long_/ = 34 - final val Long_% = 35 - - final val Long_| = 36 - final val Long_& = 37 - final val Long_^ = 38 - final val Long_<< = 39 - final val Long_>>> = 40 - final val Long_>> = 41 - - final val Long_== = 42 - final val Long_!= = 43 - final val Long_< = 44 - final val Long_<= = 45 - final val Long_> = 46 - final val Long_>= = 47 - - final val Boolean_== = 48 - final val Boolean_!= = 49 - final val Boolean_| = 50 - final val Boolean_& = 51 + final val Boolean_== = 4 + final val Boolean_!= = 5 + final val Boolean_| = 6 + final val Boolean_& = 7 + + final val Int_+ = 8 + final val Int_- = 9 + final val Int_* = 10 + final val Int_/ = 11 + final val Int_% = 12 + + final val Int_| = 13 + final val Int_& = 14 + final val Int_^ = 15 + final val Int_<< = 16 + final val Int_>>> = 17 + final val Int_>> = 18 + + final val Int_== = 19 + final val Int_!= = 20 + final val Int_< = 21 + final val Int_<= = 22 + final val Int_> = 23 + final val Int_>= = 24 + + final val Long_+ = 25 + final val Long_- = 26 + final val Long_* = 27 + final val Long_/ = 28 + final val Long_% = 29 + + final val Long_| = 30 + final val Long_& = 31 + final val Long_^ = 32 + final val Long_<< = 33 + final val Long_>>> = 34 + final val Long_>> = 35 + + final val Long_== = 36 + final val Long_!= = 37 + final val Long_< = 38 + final val Long_<= = 39 + final val Long_> = 40 + final val Long_>= = 41 + + final val Float_+ = 42 + final val Float_- = 43 + final val Float_* = 44 + final val Float_/ = 45 + final val Float_% = 46 + + final val Double_+ = 47 + final val Double_- = 48 + final val Double_* = 49 + final val Double_/ = 50 + final val Double_% = 51 + + final val Double_== = 52 + final val Double_!= = 53 + final val Double_< = 54 + final val Double_<= = 55 + final val Double_> = 56 + final val Double_>= = 57 def resultTypeOf(op: Code): Type = (op: @switch) match { case === | !== | - Num_== | Num_!= | Num_< | Num_<= | Num_> | Num_>= | + Boolean_== | Boolean_!= | Boolean_| | Boolean_& | + Int_== | Int_!= | Int_< | Int_<= | Int_> | Int_>= | Long_== | Long_!= | Long_< | Long_<= | Long_> | Long_>= | - Boolean_== | Boolean_!= | Boolean_| | Boolean_& => + Double_== | Double_!= | Double_< | Double_<= | Double_> | Double_>= => BooleanType case String_+ => StringType case Int_+ | Int_- | Int_* | Int_/ | Int_% | Int_| | Int_& | Int_^ | Int_<< | Int_>>> | Int_>> => IntType + case Long_+ | Long_- | Long_* | Long_/ | Long_% | + Long_| | Long_& | Long_^ | Long_<< | Long_>>> | Long_>> => + LongType case Float_+ | Float_- | Float_* | Float_/ | Float_% => FloatType case Double_+ | Double_- | Double_* | Double_/ | Double_% => DoubleType - case Long_+ | Long_- | Long_* | Long_/ | Long_% | - Long_| | Long_& | Long_^ | Long_<< | Long_>>> | Long_>> => - LongType } } @@ -418,11 +450,13 @@ object Trees { case class Unbox(expr: Tree, charCode: Char)( implicit val pos: Position) extends Tree { val tpe = (charCode: @switch) match { - case 'Z' => BooleanType - case 'B' | 'S' | 'I' => IntType - case 'J' => LongType - case 'F' => FloatType - case 'D' => DoubleType + case 'Z' => BooleanType + case 'B' => ByteType + case 'S' => ShortType + case 'I' => IntType + case 'J' => LongType + case 'F' => FloatType + case 'D' => DoubleType } } @@ -751,6 +785,21 @@ object Trees { val tpe = BooleanType } + case class CharLiteral(value: Char)( + implicit val pos: Position) extends Literal { + val tpe = CharType + } + + case class ByteLiteral(value: Byte)( + implicit val pos: Position) extends Literal { + val tpe = ByteType + } + + case class ShortLiteral(value: Short)( + implicit val pos: Position) extends Literal { + val tpe = ShortType + } + case class IntLiteral(value: Int)( implicit val pos: Position) extends Literal { val tpe = IntType diff --git a/ir/src/main/scala/org/scalajs/core/ir/Types.scala b/ir/src/main/scala/org/scalajs/core/ir/Types.scala index b5851bd8ce..cda6c7f11e 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Types.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Types.scala @@ -18,10 +18,7 @@ object Types { /** Type of a term (expression or statement) in the IR. * * There is a many-to-one relationship from [[TypeRef]]s to `Type`s, - * because: - * - * - `scala.Byte`, `scala.Short` and `scala.Int` collapse to [[IntType]] - * - `java.lang.Object` and raw JS types all collapse to [[AnyType]] + * because `java.lang.Object` and raw JS types all collapse to [[AnyType]]. * * In fact, there are two `Type`s that do not have any real equivalent in * type refs: [[StringType]] and [[UndefType]], as they refer to the @@ -64,6 +61,26 @@ object Types { */ case object BooleanType extends Type + /** `Char` type, a 16-bit UTF-16 code unit. + * It does not accept `null` nor `undefined`. + * + * `CharType` has the peculiarity that it is *not* a subtype of [[AnyType]]. + * As such, no method can be called on a `CharType` either. In fact, very + * few operations manipulate `CharType`s. It is usually necessary to convert + * to/from [[IntType]]s using the appropriate `UnaryOp` conversions. + */ + case object CharType extends Type + + /** 8-bit signed integer type. + * It does not accept `null` nor `undefined`. + */ + case object ByteType extends Type + + /** 16-bit signed integer type. + * It does not accept `null` nor `undefined`. + */ + case object ShortType extends Type + /** 32-bit signed integer type. * It does not accept `null` nor `undefined`. */ @@ -162,6 +179,9 @@ object Types { /** Generates a literal zero of the given type. */ def zeroOf(tpe: Type)(implicit pos: Position): Literal = tpe match { case BooleanType => BooleanLiteral(false) + case CharType => CharLiteral('\u0000') + case ByteType => ByteLiteral(0) + case ShortType => ShortLiteral(0) case IntType => IntLiteral(0) case LongType => LongLiteral(0L) case FloatType => FloatLiteral(0.0f) @@ -184,6 +204,7 @@ object Types { (lhs != NoType && rhs != NoType) && { (lhs == rhs) || ((lhs, rhs) match { + case (CharType, _) => false case (_, AnyType) => true case (NothingType, _) => true @@ -197,24 +218,21 @@ object Types { isSubclass(BoxedUnitClass, cls) case (BooleanType, ClassType(cls)) => isSubclass(BoxedBooleanClass, cls) + case (ByteType, ClassType(cls)) => + isSubclass(BoxedByteClass, cls) + case (ShortType, ClassType(cls)) => + isSubclass(BoxedShortClass, cls) case (IntType, ClassType(cls)) => - isSubclass(BoxedIntegerClass, cls) || - cls == BoxedByteClass || - cls == BoxedShortClass || - cls == BoxedDoubleClass + isSubclass(BoxedIntegerClass, cls) case (LongType, ClassType(cls)) => isSubclass(BoxedLongClass, cls) case (FloatType, ClassType(cls)) => - isSubclass(BoxedFloatClass, cls) || - cls == BoxedDoubleClass + isSubclass(BoxedFloatClass, cls) case (DoubleType, ClassType(cls)) => isSubclass(BoxedDoubleClass, cls) case (StringType, ClassType(cls)) => isSubclass(StringClass, cls) - case (IntType, DoubleType) => true - case (FloatType, DoubleType) => true - case (ArrayType(ArrayTypeRef(lhsBase, lhsDims)), ArrayType(ArrayTypeRef(rhsBase, rhsDims))) => if (lhsDims < rhsDims) { diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala index f9fc461963..9deacf9e1e 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala @@ -52,6 +52,9 @@ class PrintersTest { assertPrintEquals("nothing", NothingType) assertPrintEquals("void", UndefType) assertPrintEquals("boolean", BooleanType) + assertPrintEquals("char", CharType) + assertPrintEquals("byte", ByteType) + assertPrintEquals("short", ShortType) assertPrintEquals("int", IntType) assertPrintEquals("long", LongType) assertPrintEquals("float", FloatType) @@ -349,11 +352,22 @@ class PrintersTest { import UnaryOp._ assertPrintEquals("(!x)", UnaryOp(Boolean_!, ref("x", BooleanType))) + + assertPrintEquals("((int)x)", UnaryOp(CharToInt, ref("x", CharType))) + assertPrintEquals("((int)x)", UnaryOp(ByteToInt, ref("x", ByteType))) + assertPrintEquals("((int)x)", UnaryOp(ShortToInt, ref("x", ShortType))) assertPrintEquals("((long)x)", UnaryOp(IntToLong, ref("x", IntType))) + assertPrintEquals("((double)x)", UnaryOp(IntToDouble, ref("x", IntType))) + assertPrintEquals("((double)x)", UnaryOp(FloatToDouble, ref("x", FloatType))) + + assertPrintEquals("((char)x)", UnaryOp(IntToChar, ref("x", IntType))) + assertPrintEquals("((byte)x)", UnaryOp(IntToByte, ref("x", IntType))) + assertPrintEquals("((short)x)", UnaryOp(IntToShort, ref("x", IntType))) assertPrintEquals("((int)x)", UnaryOp(LongToInt, ref("x", LongType))) - assertPrintEquals("((double)x)", UnaryOp(LongToDouble, ref("x", LongType))) assertPrintEquals("((int)x)", UnaryOp(DoubleToInt, ref("x", DoubleType))) assertPrintEquals("((float)x)", UnaryOp(DoubleToFloat, ref("x", DoubleType))) + + assertPrintEquals("((double)x)", UnaryOp(LongToDouble, ref("x", LongType))) assertPrintEquals("((long)x)", UnaryOp(DoubleToLong, ref("x", DoubleType))) } @@ -380,6 +394,15 @@ class PrintersTest { assertPrintEquals("(x +[string] y)", BinaryOp(String_+, ref("x", AnyType), ref("y", AnyType))) + assertPrintEquals("(x ==[bool] y)", + BinaryOp(Boolean_==, ref("x", BooleanType), ref("y", BooleanType))) + assertPrintEquals("(x !=[bool] y)", + BinaryOp(Boolean_!=, ref("x", BooleanType), ref("y", BooleanType))) + assertPrintEquals("(x |[bool] y)", + BinaryOp(Boolean_|, ref("x", BooleanType), ref("y", BooleanType))) + assertPrintEquals("(x &[bool] y)", + BinaryOp(Boolean_&, ref("x", BooleanType), ref("y", BooleanType))) + assertPrintEquals("(x +[int] y)", BinaryOp(Int_+, ref("x", IntType), ref("y", IntType))) assertPrintEquals("(x -[int] y)", @@ -404,40 +427,18 @@ class PrintersTest { assertPrintEquals("(x >>[int] y)", BinaryOp(Int_>>, ref("x", IntType), ref("y", IntType))) - assertPrintEquals("(x +[float] y)", - BinaryOp(Float_+, ref("x", FloatType), ref("y", FloatType))) - assertPrintEquals("(x -[float] y)", - BinaryOp(Float_-, ref("x", FloatType), ref("y", FloatType))) - assertPrintEquals("(x *[float] y)", - BinaryOp(Float_*, ref("x", FloatType), ref("y", FloatType))) - assertPrintEquals("(x /[float] y)", - BinaryOp(Float_/, ref("x", FloatType), ref("y", FloatType))) - assertPrintEquals("(x %[float] y)", - BinaryOp(Float_%, ref("x", FloatType), ref("y", FloatType))) - - assertPrintEquals("(x +[double] y)", - BinaryOp(Double_+, ref("x", DoubleType), ref("y", DoubleType))) - assertPrintEquals("(x -[double] y)", - BinaryOp(Double_-, ref("x", DoubleType), ref("y", DoubleType))) - assertPrintEquals("(x *[double] y)", - BinaryOp(Double_*, ref("x", DoubleType), ref("y", DoubleType))) - assertPrintEquals("(x /[double] y)", - BinaryOp(Double_/, ref("x", DoubleType), ref("y", DoubleType))) - assertPrintEquals("(x %[double] y)", - BinaryOp(Double_%, ref("x", DoubleType), ref("y", DoubleType))) - - assertPrintEquals("(x == y)", - BinaryOp(Num_==, ref("x", DoubleType), ref("y", DoubleType))) - assertPrintEquals("(x != y)", - BinaryOp(Num_!=, ref("x", DoubleType), ref("y", DoubleType))) - assertPrintEquals("(x < y)", - BinaryOp(Num_<, ref("x", DoubleType), ref("y", DoubleType))) - assertPrintEquals("(x <= y)", - BinaryOp(Num_<=, ref("x", DoubleType), ref("y", DoubleType))) - assertPrintEquals("(x > y)", - BinaryOp(Num_>, ref("x", DoubleType), ref("y", DoubleType))) - assertPrintEquals("(x >= y)", - BinaryOp(Num_>=, ref("x", DoubleType), ref("y", DoubleType))) + assertPrintEquals("(x ==[int] y)", + BinaryOp(Int_==, ref("x", IntType), ref("y", IntType))) + assertPrintEquals("(x !=[int] y)", + BinaryOp(Int_!=, ref("x", IntType), ref("y", IntType))) + assertPrintEquals("(x <[int] y)", + BinaryOp(Int_<, ref("x", IntType), ref("y", IntType))) + assertPrintEquals("(x <=[int] y)", + BinaryOp(Int_<=, ref("x", IntType), ref("y", IntType))) + assertPrintEquals("(x >[int] y)", + BinaryOp(Int_>, ref("x", IntType), ref("y", IntType))) + assertPrintEquals("(x >=[int] y)", + BinaryOp(Int_>=, ref("x", IntType), ref("y", IntType))) assertPrintEquals("(x +[long] y)", BinaryOp(Long_+, ref("x", LongType), ref("y", LongType))) @@ -463,14 +464,53 @@ class PrintersTest { assertPrintEquals("(x >>[long] y)", BinaryOp(Long_>>, ref("x", LongType), ref("y", IntType))) - assertPrintEquals("(x ==[bool] y)", - BinaryOp(Boolean_==, ref("x", BooleanType), ref("y", BooleanType))) - assertPrintEquals("(x !=[bool] y)", - BinaryOp(Boolean_!=, ref("x", BooleanType), ref("y", BooleanType))) - assertPrintEquals("(x |[bool] y)", - BinaryOp(Boolean_|, ref("x", BooleanType), ref("y", BooleanType))) - assertPrintEquals("(x &[bool] y)", - BinaryOp(Boolean_&, ref("x", BooleanType), ref("y", BooleanType))) + assertPrintEquals("(x ==[long] y)", + BinaryOp(Long_==, ref("x", LongType), ref("y", LongType))) + assertPrintEquals("(x !=[long] y)", + BinaryOp(Long_!=, ref("x", LongType), ref("y", LongType))) + assertPrintEquals("(x <[long] y)", + BinaryOp(Long_<, ref("x", LongType), ref("y", LongType))) + assertPrintEquals("(x <=[long] y)", + BinaryOp(Long_<=, ref("x", LongType), ref("y", LongType))) + assertPrintEquals("(x >[long] y)", + BinaryOp(Long_>, ref("x", LongType), ref("y", LongType))) + assertPrintEquals("(x >=[long] y)", + BinaryOp(Long_>=, ref("x", LongType), ref("y", LongType))) + + assertPrintEquals("(x +[float] y)", + BinaryOp(Float_+, ref("x", FloatType), ref("y", FloatType))) + assertPrintEquals("(x -[float] y)", + BinaryOp(Float_-, ref("x", FloatType), ref("y", FloatType))) + assertPrintEquals("(x *[float] y)", + BinaryOp(Float_*, ref("x", FloatType), ref("y", FloatType))) + assertPrintEquals("(x /[float] y)", + BinaryOp(Float_/, ref("x", FloatType), ref("y", FloatType))) + assertPrintEquals("(x %[float] y)", + BinaryOp(Float_%, ref("x", FloatType), ref("y", FloatType))) + + assertPrintEquals("(x +[double] y)", + BinaryOp(Double_+, ref("x", DoubleType), ref("y", DoubleType))) + assertPrintEquals("(x -[double] y)", + BinaryOp(Double_-, ref("x", DoubleType), ref("y", DoubleType))) + assertPrintEquals("(x *[double] y)", + BinaryOp(Double_*, ref("x", DoubleType), ref("y", DoubleType))) + assertPrintEquals("(x /[double] y)", + BinaryOp(Double_/, ref("x", DoubleType), ref("y", DoubleType))) + assertPrintEquals("(x %[double] y)", + BinaryOp(Double_%, ref("x", DoubleType), ref("y", DoubleType))) + + assertPrintEquals("(x ==[double] y)", + BinaryOp(Double_==, ref("x", DoubleType), ref("y", DoubleType))) + assertPrintEquals("(x !=[double] y)", + BinaryOp(Double_!=, ref("x", DoubleType), ref("y", DoubleType))) + assertPrintEquals("(x <[double] y)", + BinaryOp(Double_<, ref("x", DoubleType), ref("y", DoubleType))) + assertPrintEquals("(x <=[double] y)", + BinaryOp(Double_<=, ref("x", DoubleType), ref("y", DoubleType))) + assertPrintEquals("(x >[double] y)", + BinaryOp(Double_>, ref("x", DoubleType), ref("y", DoubleType))) + assertPrintEquals("(x >=[double] y)", + BinaryOp(Double_>=, ref("x", DoubleType), ref("y", DoubleType))) } @Test def printNewArray(): Unit = { @@ -714,6 +754,22 @@ class PrintersTest { assertPrintEquals("false", BooleanLiteral(false)) } + @Test def printCharLiteral(): Unit = { + assertPrintEquals("'A'", CharLiteral('A')) + assertPrintEquals("'\\u0005'", CharLiteral('\u0005')) + assertPrintEquals("'\\ufffb'", CharLiteral('\ufffb')) + } + + @Test def printByteLiteral(): Unit = { + assertPrintEquals("5_b", ByteLiteral(5)) + assertPrintEquals("(-5_b)", ByteLiteral(-5)) + } + + @Test def printShortLiteral(): Unit = { + assertPrintEquals("5_s", ShortLiteral(5)) + assertPrintEquals("(-5_s)", ShortLiteral(-5)) + } + @Test def printIntLiteral(): Unit = { assertPrintEquals("5", IntLiteral(5)) assertPrintEquals("(-5)", IntLiteral(-5)) diff --git a/javalanglib/src/main/scala/java/lang/Integer.scala b/javalanglib/src/main/scala/java/lang/Integer.scala index a550e1b13b..bc14f16dd0 100644 --- a/javalanglib/src/main/scala/java/lang/Integer.scala +++ b/javalanglib/src/main/scala/java/lang/Integer.scala @@ -30,22 +30,6 @@ final class Integer private () extends Number with Comparable[Integer] { @inline override def toString(): String = Integer.toString(intValue) - - /* Methods of java.lang.Byte and java.lang.Short. - * When calling a method of j.l.Byte or j.l.Short on a primitive value, - * it appears to be called directly on the primitive value, which has type - * IntType. Call resolution, by the analyzer and the optimizer, will then - * look for the method in the class j.l.Integer instead of j.l.Byte or - * j.l.Short. This is why we add here the methods of these two classes that - * are not already in j.l.Integer. - */ - - @inline def compareTo(that: Byte): Int = - Integer.compare(intValue, that.intValue) - - @inline def compareTo(that: Short): Int = - Integer.compare(intValue, that.intValue) - } object Integer { diff --git a/project/JavaLangString.scala b/project/JavaLangString.scala index 0334b06a76..34deb107ea 100644 --- a/project/JavaLangString.scala +++ b/project/JavaLangString.scala @@ -106,14 +106,14 @@ object JavaLangString { Ident("charAt__I__C", Some("charAt__I__C")), List(ParamDef(Ident("i", Some("i")), IntType, mutable = false, rest = false)), - IntType, + CharType, Some { Apply( LoadModule(ClassType("sjsr_RuntimeString$")), Ident("charAt__T__I__C", Some("charAt__T__I__C")), List( This()(ThisType), - VarRef(Ident("i", Some("i")))(IntType)))(IntType) + VarRef(Ident("i", Some("i")))(IntType)))(CharType) })(OptimizerHints.empty.withInline(true), None), /* def length(): Int = RuntimeString.length(this) */ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InstanceTestsHijackedBoxedClassesTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InstanceTestsHijackedBoxedClassesTest.scala index 59f04736d4..c40f8e0823 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InstanceTestsHijackedBoxedClassesTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InstanceTestsHijackedBoxedClassesTest.scala @@ -34,6 +34,10 @@ class InstanceTestsHijackedBoxedClassesTest { assertTrue((5.0: Any).isInstanceOf[Int]) assertTrue((5.0: Any).isInstanceOf[Float]) + assertTrue((5.toByte: Any).isInstanceOf[Int]) + assertTrue((5.toShort: Any).isInstanceOf[Int]) + assertTrue((5: Any).isInstanceOf[Byte]) + assertTrue((5: Any).isInstanceOf[Short]) assertTrue((0.0: Any).isInstanceOf[Int]) assertTrue((0.0: Any).isInstanceOf[Float]) assertTrue((-0.0: Any).isInstanceOf[Float]) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala index d0a1e395d5..f76904be74 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala @@ -151,6 +151,73 @@ class OptimizerTest { // scalastyle:on return } + // === constant folding + + @Test def constant_folding_===(): Unit = { + @inline def test(expectEq: Boolean, lhs: Any, rhs: Any): Unit = { + assertEquals(expectEq, + lhs.asInstanceOf[AnyRef] eq rhs.asInstanceOf[AnyRef]) + assertEquals(!expectEq, + lhs.asInstanceOf[AnyRef] ne rhs.asInstanceOf[AnyRef]) + } + + test(true, false, false) + test(true, 5, 5) + test(true, 5.toByte, 5.toByte) + test(true, 5.toByte, 5) + test(true, 5.0, 5) + test(true, 5.0f, 5.toShort) + test(true, classOf[String], classOf[String]) + test(true, "hello", "hello") + + test(false, false, true) + test(false, 'A', 'A') // they're boxed, so not === + test(false, 5, 6) + test(false, 5.toByte, 6.toByte) + test(false, 5.toByte, 5L) + test(false, 5, 5L) + test(false, 5L, 6L) + test(false, 5L, 5L) // they're instances of RuntimeLong, so not === + test(false, false, 0) + test(false, 65, 'A') + test(false, classOf[String], classOf[Boolean]) + test(false, "hello", "world") + } + + @Test def constant_folding_==(): Unit = { + @inline def testChar(expectEq: Boolean, lhs: Char, rhs: Char): Unit = { + assertEquals(expectEq, lhs == rhs) + assertEquals(!expectEq, lhs != rhs) + } + + testChar(true, 'A', 'A') + testChar(false, 'A', 'B') + + @inline def testInt(expectEq: Boolean, lhs: Int, rhs: Int): Unit = { + assertEquals(expectEq, lhs == rhs) + assertEquals(!expectEq, lhs != rhs) + } + + testInt(true, 5, 5) + testInt(false, 5, 6) + + @inline def testLong(expectEq: Boolean, lhs: Long, rhs: Long): Unit = { + assertEquals(expectEq, lhs == rhs) + assertEquals(!expectEq, lhs != rhs) + } + + testLong(true, 5L, 5L) + testLong(false, 5L, 6L) + + @inline def testDouble(expectEq: Boolean, lhs: Double, rhs: Double): Unit = { + assertEquals(expectEq, lhs == rhs) + assertEquals(!expectEq, lhs != rhs) + } + + testDouble(true, 5.5, 5.5) + testDouble(false, 5.5, 6.5) + } + // +[string] constant folding @Test def must_not_break_when_folding_two_constant_strings(): Unit = { diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/DoubleTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/DoubleTest.scala index ac79152660..db4ebd681b 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/DoubleTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/DoubleTest.scala @@ -148,6 +148,24 @@ class DoubleTest { assertTrue(compare(0.0, -0.0) > 0) } + @Test def compareToConvertedFromInt_issue_3085(): Unit = { + @noinline + def foo(x: Int): Unit = + bar(x.toDouble) + + @inline + def bar(x: Double): Unit = { + assertTrue(x.compareTo(5.5) < 0) + foobar(x) + } + + @inline + def foobar(x: Comparable[java.lang.Double]): Unit = + assertTrue(x.compareTo(5.5) < 0) + + foo(5) + } + @Test def should_be_a_Comparable(): Unit = { def compare(x: Any, y: Any): Int = x.asInstanceOf[Comparable[Any]].compareTo(y) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala index 5ed3c0cd9e..c8d2e94c3c 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala @@ -186,6 +186,8 @@ object Infos { case AnyType => addMethodCalled(ObjectClass, method) case UndefType => addMethodCalled(BoxedUnitClass, method) case BooleanType => addMethodCalled(BoxedBooleanClass, method) + case ByteType => addMethodCalled(BoxedByteClass, method) + case ShortType => addMethodCalled(BoxedShortClass, method) case IntType => addMethodCalled(BoxedIntegerClass, method) case LongType => addMethodCalled(BoxedLongClass, method) case FloatType => addMethodCalled(BoxedFloatClass, method) @@ -196,7 +198,7 @@ object Infos { case NullType | NothingType => // Nothing to do - case NoType | RecordType(_) => + case NoType | CharType | RecordType(_) => throw new IllegalArgumentException( s"Illegal receiver type: $receiverTpe") } diff --git 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 index 6c3dc3d320..756a0d05ea 100644 --- 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 @@ -1906,43 +1906,47 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { import UnaryOp._ val newLhs = transformExpr(lhs) (op: @switch) match { - case Boolean_! => js.UnaryOp(JSUnaryOp.!, newLhs) - case DoubleToInt => genCallHelper("doubleToInt", newLhs) - - case LongToInt => genLongMethodApply(newLhs, LongImpl.toInt) - case LongToDouble => genLongMethodApply(newLhs, LongImpl.toDouble) - - case DoubleToFloat => genFround(newLhs) + case Boolean_! => js.UnaryOp(JSUnaryOp.!, newLhs) + // Widening conversions + case CharToInt | ByteToInt | ShortToInt | IntToDouble | + FloatToDouble => + newLhs case IntToLong => genNewLong(LongImpl.initFromInt, newLhs) - case DoubleToLong => - genLongModuleApply(LongImpl.fromDouble, newLhs) + + // Narrowing conversions + case IntToChar => + js.BinaryOp(JSBinaryOp.&, js.IntLiteral(0xffff), newLhs) + case IntToByte => + js.BinaryOp(JSBinaryOp.>>, + js.BinaryOp(JSBinaryOp.<<, newLhs, js.IntLiteral(24)), + js.IntLiteral(24)) + case IntToShort => + js.BinaryOp(JSBinaryOp.>>, + js.BinaryOp(JSBinaryOp.<<, newLhs, js.IntLiteral(16)), + js.IntLiteral(16)) + case LongToInt => + genLongMethodApply(newLhs, LongImpl.toInt) + case DoubleToInt => + genCallHelper("doubleToInt", newLhs) + case DoubleToFloat => + genFround(newLhs) + + // Long <-> Double (neither widening nor narrowing) + case LongToDouble => genLongMethodApply(newLhs, LongImpl.toDouble) + case DoubleToLong => genLongModuleApply(LongImpl.fromDouble, newLhs) } case BinaryOp(op, lhs, rhs) => import BinaryOp._ - val lhs1 = lhs match { - case UnaryOp(UnaryOp.DoubleToInt, inner) - if op == Int_& || op == Int_<< => - /* This case is emitted typically by conversions from - * Float/Double to Char/Byte/Short. We have to introduce an - * (int) cast in the IR so that it typechecks, but in JavaScript - * this is redundant because & and << already convert both their - * operands to ints. So we get rid of the conversion here. - */ - inner - case _ => - lhs - } - - val newLhs = transformExpr(lhs1) + val newLhs = transformExpr(lhs) val newRhs = transformExpr(rhs) (op: @switch) match { - case === | Num_== | Boolean_== => + case === | Int_== | Double_== | Boolean_== => js.BinaryOp(JSBinaryOp.===, newLhs, newRhs) - case !== | Num_!= | Boolean_!= => + case !== | Int_!= | Double_!= | Boolean_!= => js.BinaryOp(JSBinaryOp.!==, newLhs, newRhs) case String_+ => @@ -1974,30 +1978,10 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case Int_>>> => or0(js.BinaryOp(JSBinaryOp.>>>, newLhs, newRhs)) case Int_>> => js.BinaryOp(JSBinaryOp.>>, newLhs, newRhs) - case Float_+ => genFround(js.BinaryOp(JSBinaryOp.+, newLhs, newRhs)) - case Float_- => - genFround(lhs match { - case DoubleLiteral(0.0) => js.UnaryOp(JSUnaryOp.-, newRhs) - case _ => js.BinaryOp(JSBinaryOp.-, newLhs, newRhs) - }) - case Float_* => genFround(js.BinaryOp(JSBinaryOp.*, newLhs, newRhs)) - case Float_/ => genFround(js.BinaryOp(JSBinaryOp./, newLhs, newRhs)) - case Float_% => genFround(js.BinaryOp(JSBinaryOp.%, newLhs, newRhs)) - - case Double_+ => js.BinaryOp(JSBinaryOp.+, newLhs, newRhs) - case Double_- => - lhs match { - case DoubleLiteral(0.0) => js.UnaryOp(JSUnaryOp.-, newRhs) - case _ => js.BinaryOp(JSBinaryOp.-, newLhs, newRhs) - } - case Double_* => js.BinaryOp(JSBinaryOp.*, newLhs, newRhs) - case Double_/ => js.BinaryOp(JSBinaryOp./, newLhs, newRhs) - case Double_% => js.BinaryOp(JSBinaryOp.%, newLhs, newRhs) - - case Num_< => js.BinaryOp(JSBinaryOp.<, newLhs, newRhs) - case Num_<= => js.BinaryOp(JSBinaryOp.<=, newLhs, newRhs) - case Num_> => js.BinaryOp(JSBinaryOp.>, newLhs, newRhs) - case Num_>= => js.BinaryOp(JSBinaryOp.>=, newLhs, newRhs) + case Int_< => js.BinaryOp(JSBinaryOp.<, newLhs, newRhs) + case Int_<= => js.BinaryOp(JSBinaryOp.<=, newLhs, newRhs) + case Int_> => js.BinaryOp(JSBinaryOp.>, newLhs, newRhs) + case Int_>= => js.BinaryOp(JSBinaryOp.>=, newLhs, newRhs) case Long_+ => genLongMethodApply(newLhs, LongImpl.+, newRhs) case Long_- => @@ -2027,6 +2011,31 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case Long_> => genLongMethodApply(newLhs, LongImpl.>, newRhs) case Long_>= => genLongMethodApply(newLhs, LongImpl.>=, newRhs) + case Float_+ => genFround(js.BinaryOp(JSBinaryOp.+, newLhs, newRhs)) + case Float_- => + genFround(lhs match { + case DoubleLiteral(0.0) => js.UnaryOp(JSUnaryOp.-, newRhs) + case _ => js.BinaryOp(JSBinaryOp.-, newLhs, newRhs) + }) + case Float_* => genFround(js.BinaryOp(JSBinaryOp.*, newLhs, newRhs)) + case Float_/ => genFround(js.BinaryOp(JSBinaryOp./, newLhs, newRhs)) + case Float_% => genFround(js.BinaryOp(JSBinaryOp.%, newLhs, newRhs)) + + case Double_+ => js.BinaryOp(JSBinaryOp.+, newLhs, newRhs) + case Double_- => + lhs match { + case DoubleLiteral(0.0) => js.UnaryOp(JSUnaryOp.-, newRhs) + case _ => js.BinaryOp(JSBinaryOp.-, newLhs, newRhs) + } + case Double_* => js.BinaryOp(JSBinaryOp.*, newLhs, newRhs) + case Double_/ => js.BinaryOp(JSBinaryOp./, newLhs, newRhs) + case Double_% => js.BinaryOp(JSBinaryOp.%, newLhs, newRhs) + + case Double_< => js.BinaryOp(JSBinaryOp.<, newLhs, newRhs) + case Double_<= => js.BinaryOp(JSBinaryOp.<=, newLhs, newRhs) + case Double_> => js.BinaryOp(JSBinaryOp.>, newLhs, newRhs) + case Double_>= => js.BinaryOp(JSBinaryOp.>=, newLhs, newRhs) + case Boolean_| => !(!js.BinaryOp(JSBinaryOp.|, newLhs, newRhs)) case Boolean_& => !(!js.BinaryOp(JSBinaryOp.&, newLhs, newRhs)) } @@ -2198,6 +2207,9 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case Undefined() => js.Undefined() case Null() => js.Null() case BooleanLiteral(value) => js.BooleanLiteral(value) + case CharLiteral(value) => js.IntLiteral(value.toInt) + case ByteLiteral(value) => js.IntLiteral(value.toInt) + case ShortLiteral(value) => js.IntLiteral(value.toInt) case IntLiteral(value) => js.IntLiteral(value) case FloatLiteral(value) => js.DoubleLiteral(value.toDouble) case DoubleLiteral(value) => js.DoubleLiteral(value) @@ -2254,8 +2266,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case ClassType(cls) => Definitions.HijackedClasses.contains(cls) || Definitions.AncestorsOfHijackedClasses.contains(cls) - case AnyType | UndefType | BooleanType | IntType | LongType | - FloatType | DoubleType | StringType => + case AnyType | UndefType | BooleanType | ByteType | ShortType | IntType | + LongType | FloatType | DoubleType | StringType => true case _ => false diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala index e73fb7e11f..39d57e98c0 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala @@ -37,6 +37,9 @@ private[emitter] final class JSGen(val semantics: Semantics, def genZeroOf(tpe: Type)(implicit pos: Position): Tree = { tpe match { case BooleanType => BooleanLiteral(false) + case CharType => IntLiteral(0) + case ByteType => IntLiteral(0) + case ShortType => IntLiteral(0) case IntType => IntLiteral(0) case LongType => genLongZero() case FloatType => DoubleLiteral(0.0) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 755535c623..1dbce0801f 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -819,46 +819,54 @@ private final class IRChecker(unit: LinkingUnit, case UnaryOp(op, lhs) => import UnaryOp._ - (op: @switch) match { - case IntToLong => - typecheckExpect(lhs, env, IntType) + val expectedArgType = (op: @switch) match { + case Boolean_! => + BooleanType + case CharToInt => + CharType + case ByteToInt => + ByteType + case ShortToInt => + ShortType + case IntToLong | IntToDouble | IntToChar | IntToByte | IntToShort => + IntType case LongToInt | LongToDouble => - typecheckExpect(lhs, env, LongType) + LongType + case FloatToDouble => + FloatType case DoubleToInt | DoubleToFloat | DoubleToLong => - typecheckExpect(lhs, env, DoubleType) - case Boolean_! => - typecheckExpect(lhs, env, BooleanType) + DoubleType } + typecheckExpect(lhs, env, expectedArgType) case BinaryOp(op, lhs, rhs) => import BinaryOp._ - (op: @switch) match { + val expectedLhsType = (op: @switch) match { case === | !== | String_+ => - typecheckExpr(lhs, env) - typecheckExpr(rhs, env) + AnyType + case Boolean_== | Boolean_!= | Boolean_| | Boolean_& => + BooleanType case Int_+ | Int_- | Int_* | Int_/ | Int_% | - Int_| | Int_& | Int_^ | Int_<< | Int_>>> | Int_>> => - typecheckExpect(lhs, env, IntType) - typecheckExpect(rhs, env, IntType) - case Float_+ | Float_- | Float_* | Float_/ | Float_% => - typecheckExpect(lhs, env, FloatType) - typecheckExpect(rhs, env, FloatType) + Int_| | Int_& | Int_^ | Int_<< | Int_>>> | Int_>> | + Int_== | Int_!= | Int_< | Int_<= | Int_> | Int_>= => + IntType case Long_+ | Long_- | Long_* | Long_/ | Long_% | - Long_| | Long_& | Long_^ | + Long_| | Long_& | Long_^ | Long_<< | Long_>>> | Long_>> | Long_== | Long_!= | Long_< | Long_<= | Long_> | Long_>= => - typecheckExpect(lhs, env, LongType) - typecheckExpect(rhs, env, LongType) - case Long_<< | Long_>>> | Long_>> => - typecheckExpect(lhs, env, LongType) - typecheckExpect(rhs, env, IntType) + LongType + case Float_+ | Float_- | Float_* | Float_/ | Float_% => + FloatType case Double_+ | Double_- | Double_* | Double_/ | Double_% | - Num_== | Num_!= | Num_< | Num_<= | Num_> | Num_>= => - typecheckExpect(lhs, env, DoubleType) - typecheckExpect(rhs, env, DoubleType) - case Boolean_== | Boolean_!= | Boolean_| | Boolean_& => - typecheckExpect(lhs, env, BooleanType) - typecheckExpect(rhs, env, BooleanType) + Double_== | Double_!= | + Double_< | Double_<= | Double_> | Double_>= => + DoubleType + } + val expectedRhsType = (op: @switch) match { + case Long_<< | Long_>>> | Long_>> => IntType + case _ => expectedLhsType } + typecheckExpect(lhs, env, expectedLhsType) + typecheckExpect(rhs, env, expectedRhsType) case NewArray(tpe, lengths) => for (length <- lengths) @@ -1083,14 +1091,17 @@ private final class IRChecker(unit: LinkingUnit, implicit ctx: ErrorContext): Type = { if (encodedName.length == 1) { (encodedName.charAt(0): @switch) match { - case 'V' => NoType - case 'Z' => BooleanType - case 'C' | 'B' | 'S' | 'I' => IntType - case 'J' => LongType - case 'F' => FloatType - case 'D' => DoubleType - case 'O' => AnyType - case 'T' => ClassType(StringClass) // NOT StringType + case 'V' => NoType + case 'Z' => BooleanType + case 'C' => CharType + case 'B' => ByteType + case 'S' => ShortType + case 'I' => IntType + case 'J' => LongType + case 'F' => FloatType + case 'D' => DoubleType + case 'O' => AnyType + case 'T' => ClassType(StringClass) // NOT StringType } } else if (encodedName == "sr_Nothing$") { NothingType diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala index b319dc31d1..774458466a 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala @@ -47,25 +47,6 @@ abstract class GenIncOptimizer private[optimizer] (config: CommonPhaseConfig) { import factory._ callMethods(LongImpl.RuntimeLongClass, LongImpl.AllIntrinsicMethods) ++ - /* #2184 + #2780: we need to keep all methods of j.l.Integer, in case - * the corresponding methods are called on j.l.Byte or j.l.Short, and - * through optimizations become calls on j.l.Integer. - */ - callMethods(Definitions.BoxedIntegerClass, Seq( - "byteValue__B", - "shortValue__S", - "intValue__I", - "longValue__J", - "floatValue__F", - "doubleValue__D", - "equals__O__Z", - "hashCode__I", - "compareTo__jl_Integer__I", - "toString__T", - "compareTo__jl_Byte__I", - "compareTo__jl_Short__I", - "compareTo__O__I" - )) ++ instantiateClass("jl_NullPointerException", "init___") } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index b0de1fbf29..ead3ea561e 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -1506,6 +1506,8 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case AnyType => Definitions.ObjectClass case UndefType => Definitions.BoxedUnitClass case BooleanType => Definitions.BoxedBooleanClass + case ByteType => Definitions.BoxedByteClass + case ShortType => Definitions.BoxedShortClass case IntType => Definitions.BoxedIntegerClass case LongType => LongImpl.RuntimeLongClass case FloatType => Definitions.BoxedFloatClass @@ -1930,11 +1932,14 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { def cursoryArrayElemType(tpe: ArrayType): Type = { if (tpe.arrayTypeRef.dimensions != 1) AnyType else (tpe.arrayTypeRef.baseClassName match { - case "Z" => BooleanType - case "B" | "C" | "S" | "I" => IntType - case "F" => FloatType - case "D" => DoubleType - case _ => AnyType + case "Z" => BooleanType + case "C" => CharType + case "B" => ByteType + case "S" => ShortType + case "I" => IntType + case "F" => FloatType + case "D" => DoubleType + case _ => AnyType }) } @@ -2046,13 +2051,24 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case ArrayBuilderZeroOf => contTree(finishTransformExpr(targs.head) match { case ClassOf(ClassRef(cls)) => + /* Note that the 'C' case produces a literal int instead of char. + * This ensures that we fill up the JS array with numbers 0 rather + * than boxed '\0'. We need to do this because the result() method + * (see intrinsic right above) will directly feed that JS array to + * `makeNativeArrayWrapper`, which expects an array of numbers when + * builing an `Array[Char]`. + */ cls match { - case "B" | "S" | "C" | "I" | "D" => IntLiteral(0) - case "L" => LongLiteral(0L) - case "F" => FloatLiteral(0.0f) - case "Z" => BooleanLiteral(false) - case "V" => Undefined() - case _ => Null() + case "C" => IntLiteral(0) + case "B" => ByteLiteral(0) + case "S" => ShortLiteral(0) + case "I" => IntLiteral(0) + case "L" => LongLiteral(0L) + case "F" => FloatLiteral(0.0f) + case "D" => DoubleLiteral(0.0) + case "Z" => BooleanLiteral(false) + case "V" => Undefined() + case _ => Null() } case ClassOf(_) => Null() @@ -2360,45 +2376,45 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { elsep // Example: (x > y) || (x == y) -> (x >= y) - case (BinaryOp(op1 @ (Num_== | Num_!= | Num_< | Num_<= | Num_> | Num_>=), l1, r1), + case (BinaryOp(op1 @ (Int_== | Int_!= | Int_< | Int_<= | Int_> | Int_>=), l1, r1), BooleanLiteral(true), - BinaryOp(op2 @ (Num_== | Num_!= | Num_< | Num_<= | Num_> | Num_>=), l2, r2)) + BinaryOp(op2 @ (Int_== | Int_!= | Int_< | Int_<= | Int_> | Int_>=), l2, r2)) if ((l1.isInstanceOf[Literal] || l1.isInstanceOf[VarRef]) && (r1.isInstanceOf[Literal] || r1.isInstanceOf[VarRef]) && (l1 == l2 && r1 == r2)) => val canBeEqual = - ((op1 == Num_==) || (op1 == Num_<=) || (op1 == Num_>=)) || - ((op2 == Num_==) || (op2 == Num_<=) || (op2 == Num_>=)) + ((op1 == Int_==) || (op1 == Int_<=) || (op1 == Int_>=)) || + ((op2 == Int_==) || (op2 == Int_<=) || (op2 == Int_>=)) val canBeLessThan = - ((op1 == Num_!=) || (op1 == Num_<) || (op1 == Num_<=)) || - ((op2 == Num_!=) || (op2 == Num_<) || (op2 == Num_<=)) + ((op1 == Int_!=) || (op1 == Int_<) || (op1 == Int_<=)) || + ((op2 == Int_!=) || (op2 == Int_<) || (op2 == Int_<=)) val canBeGreaterThan = - ((op1 == Num_!=) || (op1 == Num_>) || (op1 == Num_>=)) || - ((op2 == Num_!=) || (op2 == Num_>) || (op2 == Num_>=)) + ((op1 == Int_!=) || (op1 == Int_>) || (op1 == Int_>=)) || + ((op2 == Int_!=) || (op2 == Int_>) || (op2 == Int_>=)) finishTransformExpr( - fold3WayComparison(canBeEqual, canBeLessThan, + fold3WayIntComparison(canBeEqual, canBeLessThan, canBeGreaterThan, l1.toPreTransform, r1.toPreTransform)) // Example: (x >= y) && (x <= y) -> (x == y) - case (BinaryOp(op1 @ (Num_== | Num_!= | Num_< | Num_<= | Num_> | Num_>=), l1, r1), - BinaryOp(op2 @ (Num_== | Num_!= | Num_< | Num_<= | Num_> | Num_>=), l2, r2), + case (BinaryOp(op1 @ (Int_== | Int_!= | Int_< | Int_<= | Int_> | Int_>=), l1, r1), + BinaryOp(op2 @ (Int_== | Int_!= | Int_< | Int_<= | Int_> | Int_>=), l2, r2), BooleanLiteral(false)) if ((l1.isInstanceOf[Literal] || l1.isInstanceOf[VarRef]) && (r1.isInstanceOf[Literal] || r1.isInstanceOf[VarRef]) && (l1 == l2 && r1 == r2)) => val canBeEqual = - ((op1 == Num_==) || (op1 == Num_<=) || (op1 == Num_>=)) && - ((op2 == Num_==) || (op2 == Num_<=) || (op2 == Num_>=)) + ((op1 == Int_==) || (op1 == Int_<=) || (op1 == Int_>=)) && + ((op2 == Int_==) || (op2 == Int_<=) || (op2 == Int_>=)) val canBeLessThan = - ((op1 == Num_!=) || (op1 == Num_<) || (op1 == Num_<=)) && - ((op2 == Num_!=) || (op2 == Num_<) || (op2 == Num_<=)) + ((op1 == Int_!=) || (op1 == Int_<) || (op1 == Int_<=)) && + ((op2 == Int_!=) || (op2 == Int_<) || (op2 == Int_<=)) val canBeGreaterThan = - ((op1 == Num_!=) || (op1 == Num_>) || (op1 == Num_>=)) && - ((op2 == Num_!=) || (op2 == Num_>) || (op2 == Num_>=)) + ((op1 == Int_!=) || (op1 == Int_>) || (op1 == Int_>=)) && + ((op2 == Int_!=) || (op2 == Int_>) || (op2 == Int_>=)) finishTransformExpr( - fold3WayComparison(canBeEqual, canBeLessThan, + fold3WayIntComparison(canBeEqual, canBeLessThan, canBeGreaterThan, l1.toPreTransform, r1.toPreTransform)) case _ => default @@ -2585,12 +2601,12 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case BinaryOp.=== => BinaryOp.!== case BinaryOp.!== => BinaryOp.=== - case BinaryOp.Num_== => BinaryOp.Num_!= - case BinaryOp.Num_!= => BinaryOp.Num_== - case BinaryOp.Num_< => BinaryOp.Num_>= - case BinaryOp.Num_<= => BinaryOp.Num_> - case BinaryOp.Num_> => BinaryOp.Num_<= - case BinaryOp.Num_>= => BinaryOp.Num_< + case BinaryOp.Int_== => BinaryOp.Int_!= + case BinaryOp.Int_!= => BinaryOp.Int_== + case BinaryOp.Int_< => BinaryOp.Int_>= + case BinaryOp.Int_<= => BinaryOp.Int_> + case BinaryOp.Int_> => BinaryOp.Int_<= + case BinaryOp.Int_>= => BinaryOp.Int_< case BinaryOp.Long_== => BinaryOp.Long_!= case BinaryOp.Long_!= => BinaryOp.Long_== @@ -2599,6 +2615,13 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case BinaryOp.Long_> => BinaryOp.Long_<= case BinaryOp.Long_>= => BinaryOp.Long_< + case BinaryOp.Double_== => BinaryOp.Double_!= + case BinaryOp.Double_!= => BinaryOp.Double_== + case BinaryOp.Double_< => BinaryOp.Double_>= + case BinaryOp.Double_<= => BinaryOp.Double_> + case BinaryOp.Double_> => BinaryOp.Double_<= + case BinaryOp.Double_>= => BinaryOp.Double_< + case BinaryOp.Boolean_== => BinaryOp.Boolean_!= case BinaryOp.Boolean_!= => BinaryOp.Boolean_== @@ -2611,6 +2634,29 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { default } + // Widening conversions + + case CharToInt => + arg match { + case PreTransLit(CharLiteral(v)) => + PreTransLit(IntLiteral(v.toInt)) + case _ => + default + } + case ByteToInt => + arg match { + case PreTransLit(ByteLiteral(v)) => + PreTransLit(IntLiteral(v.toInt)) + case _ => + default + } + case ShortToInt => + arg match { + case PreTransLit(ShortLiteral(v)) => + PreTransLit(IntLiteral(v.toInt)) + case _ => + default + } case IntToLong => arg match { case PreTransLit(IntLiteral(v)) => @@ -2618,14 +2664,56 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case _ => default } + case IntToDouble => + arg match { + case PreTransLit(IntLiteral(v)) => + PreTransLit(DoubleLiteral(v.toDouble)) + case _ => + default + } + case FloatToDouble => + arg match { + case PreTransLit(FloatLiteral(v)) => + PreTransLit(DoubleLiteral(v.toDouble)) + case _ => + default + } + + // Narrowing conversions + case IntToChar => + arg match { + case PreTransLit(IntLiteral(v)) => + PreTransLit(CharLiteral(v.toChar)) + case PreTransUnaryOp(CharToInt, x) => + x + case _ => + default + } + case IntToByte => + arg match { + case PreTransLit(IntLiteral(v)) => + PreTransLit(ByteLiteral(v.toByte)) + case PreTransUnaryOp(ByteToInt, x) => + x + case _ => + default + } + case IntToShort => + arg match { + case PreTransLit(IntLiteral(v)) => + PreTransLit(ShortLiteral(v.toShort)) + case PreTransUnaryOp(ShortToInt, x) => + x + case _ => + default + } case LongToInt => arg match { case PreTransLit(LongLiteral(v)) => PreTransLit(IntLiteral(v.toInt)) - - case PreTransUnaryOp(IntToLong, x) => x - + case PreTransUnaryOp(IntToLong, x) => + x case PreTransBinaryOp(BinaryOp.Long_+, x, y) => foldBinaryOp(BinaryOp.Int_+, foldUnaryOp(LongToInt, x), @@ -2634,44 +2722,49 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { foldBinaryOp(BinaryOp.Int_-, foldUnaryOp(LongToInt, x), foldUnaryOp(LongToInt, y)) - - case _ => default - } - - case LongToDouble => - arg match { - case PreTransLit(LongLiteral(v)) => - PreTransLit(DoubleLiteral(v.toDouble)) case _ => default } case DoubleToInt => arg match { - case _ if arg.tpe == IntType => - arg - case PreTransLit(NumberLiteral(v)) => + case PreTransLit(DoubleLiteral(v)) => PreTransLit(IntLiteral(v.toInt)) + case PreTransUnaryOp(IntToDouble, x) => + x case _ => default } case DoubleToFloat => arg match { - case _ if arg.tpe == FloatType => - arg - case PreTransLit(NumberLiteral(v)) => + case PreTransLit(DoubleLiteral(v)) => PreTransLit(FloatLiteral(v.toFloat)) + case PreTransUnaryOp(FloatToDouble, x) => + x case _ => default } + + // Long <-> Double + + case LongToDouble => + arg match { + case PreTransLit(LongLiteral(v)) => + PreTransLit(DoubleLiteral(v.toDouble)) + case PreTransUnaryOp(IntToLong, x) => + foldUnaryOp(IntToDouble, x) + case _ => + default + } case DoubleToLong => arg match { - case _ if arg.tpe == IntType => - foldUnaryOp(IntToLong, arg) - case PreTransLit(NumberLiteral(v)) => + case PreTransLit(DoubleLiteral(v)) => PreTransLit(LongLiteral(v.toLong)) + case PreTransUnaryOp(IntToDouble, x) => + foldUnaryOp(IntToLong, x) case _ => default } + case _ => default } @@ -2679,16 +2772,30 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { /** Performs === for two literals. * The result is always known statically. + * + * Bytes, Shorts, Ints, Floats and Doubles all live in the same "space" for + * `===` comparison, since they all upcast as primitive numbers. + * + * Chars and Longs, however, never compare as `===`, since they are boxed + * chars and instances of `RuntimeLong`, respectively. */ private def literal_===(lhs: Literal, rhs: Literal): Boolean = { + object AnyNumLiteral { + def unapply(tree: Literal): Option[Double] = tree match { + case ByteLiteral(v) => Some(v.toDouble) + case ShortLiteral(v) => Some(v.toDouble) + case IntLiteral(v) => Some(v.toDouble) + case FloatLiteral(v) => Some(v.toDouble) + case DoubleLiteral(v) => Some(v) + case _ => None + } + } + (lhs, rhs) match { - case (IntLiteral(l), IntLiteral(r)) => l == r - case (FloatLiteral(l), FloatLiteral(r)) => l == r - case (NumberLiteral(l), NumberLiteral(r)) => l == r - case (LongLiteral(l), LongLiteral(r)) => l == r case (BooleanLiteral(l), BooleanLiteral(r)) => l == r case (StringLiteral(l), StringLiteral(r)) => l == r case (ClassOf(l), ClassOf(r)) => l == r + case (AnyNumLiteral(l), AnyNumLiteral(r)) => l == r case (Undefined(), Undefined()) => true case (Null(), Null()) => true case _ => false @@ -2712,7 +2819,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { } @inline def double(lit: Literal): Double = (lit: @unchecked) match { - case NumberLiteral(value) => value + case DoubleLiteral(value) => value } @inline def boolean(lit: Literal): Boolean = (lit: @unchecked) match { @@ -2720,10 +2827,8 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { } (op: @switch) match { - case === | Num_== | Long_== | Boolean_== => - BooleanLiteral(literal_===(lhs, rhs)) - case !== | Num_!= | Long_!= | Boolean_!= => - BooleanLiteral(!literal_===(lhs, rhs)) + case === => BooleanLiteral(literal_===(lhs, rhs)) + case !== => BooleanLiteral(!literal_===(lhs, rhs)) case String_+ => throw new IllegalArgumentException( @@ -2752,22 +2857,12 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case Int_>>> => IntLiteral(int(lhs) >>> int(rhs)) case Int_>> => IntLiteral(int(lhs) >> int(rhs)) - case Float_+ => FloatLiteral(float(lhs) + float(rhs)) - case Float_- => FloatLiteral(float(lhs) - float(rhs)) - case Float_* => FloatLiteral(float(lhs) * float(rhs)) - case Float_/ => FloatLiteral(float(lhs) / float(rhs)) - case Float_% => FloatLiteral(float(lhs) % float(rhs)) - - case Double_+ => DoubleLiteral(double(lhs) + double(rhs)) - case Double_- => DoubleLiteral(double(lhs) - double(rhs)) - case Double_* => DoubleLiteral(double(lhs) * double(rhs)) - case Double_/ => DoubleLiteral(double(lhs) / double(rhs)) - case Double_% => DoubleLiteral(double(lhs) % double(rhs)) - - case Num_< => BooleanLiteral(double(lhs) < double(rhs)) - case Num_<= => BooleanLiteral(double(lhs) <= double(rhs)) - case Num_> => BooleanLiteral(double(lhs) > double(rhs)) - case Num_>= => BooleanLiteral(double(lhs) >= double(rhs)) + case Int_== => BooleanLiteral(int(lhs) == int(rhs)) + case Int_!= => BooleanLiteral(int(lhs) != int(rhs)) + case Int_< => BooleanLiteral(int(lhs) < int(rhs)) + case Int_<= => BooleanLiteral(int(lhs) <= int(rhs)) + case Int_> => BooleanLiteral(int(lhs) > int(rhs)) + case Int_>= => BooleanLiteral(int(lhs) >= int(rhs)) case Long_+ => LongLiteral(long(lhs) + long(rhs)) case Long_- => LongLiteral(long(lhs) - long(rhs)) @@ -2792,13 +2887,36 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case Long_>>> => LongLiteral(long(lhs) >>> int(rhs)) case Long_>> => LongLiteral(long(lhs) >> int(rhs)) + case Long_== => BooleanLiteral(long(lhs) == long(rhs)) + case Long_!= => BooleanLiteral(long(lhs) != long(rhs)) case Long_< => BooleanLiteral(long(lhs) < long(rhs)) case Long_<= => BooleanLiteral(long(lhs) <= long(rhs)) case Long_> => BooleanLiteral(long(lhs) > long(rhs)) case Long_>= => BooleanLiteral(long(lhs) >= long(rhs)) - case Boolean_| => BooleanLiteral(boolean(lhs) | boolean(rhs)) - case Boolean_& => BooleanLiteral(boolean(lhs) & boolean(rhs)) + case Float_+ => FloatLiteral(float(lhs) + float(rhs)) + case Float_- => FloatLiteral(float(lhs) - float(rhs)) + case Float_* => FloatLiteral(float(lhs) * float(rhs)) + case Float_/ => FloatLiteral(float(lhs) / float(rhs)) + case Float_% => FloatLiteral(float(lhs) % float(rhs)) + + case Double_+ => DoubleLiteral(double(lhs) + double(rhs)) + case Double_- => DoubleLiteral(double(lhs) - double(rhs)) + case Double_* => DoubleLiteral(double(lhs) * double(rhs)) + case Double_/ => DoubleLiteral(double(lhs) / double(rhs)) + case Double_% => DoubleLiteral(double(lhs) % double(rhs)) + + case Double_== => BooleanLiteral(double(lhs) == double(rhs)) + case Double_!= => BooleanLiteral(double(lhs) != double(rhs)) + case Double_< => BooleanLiteral(double(lhs) < double(rhs)) + case Double_<= => BooleanLiteral(double(lhs) <= double(rhs)) + case Double_> => BooleanLiteral(double(lhs) > double(rhs)) + case Double_>= => BooleanLiteral(double(lhs) >= double(rhs)) + + case Boolean_== => BooleanLiteral(boolean(lhs) == boolean(rhs)) + case Boolean_!= => BooleanLiteral(boolean(lhs) != boolean(rhs)) + case Boolean_| => BooleanLiteral(boolean(lhs) | boolean(rhs)) + case Boolean_& => BooleanLiteral(boolean(lhs) & boolean(rhs)) } } @@ -2806,21 +2924,24 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { private def foldToStringForString_+(preTrans: PreTransform)( implicit pos: Position): PreTransform = preTrans match { case PreTransLit(literal) => - literal match { - case LongLiteral(value) => PreTransLit(StringLiteral(value.toString)) - case IntLiteral(value) => PreTransLit(StringLiteral(value.toString)) - case BooleanLiteral(value) => PreTransLit(StringLiteral(value.toString)) - case Null() => PreTransLit(StringLiteral("null")) - case Undefined() => PreTransLit(StringLiteral("undefined")) - - case NumberLiteral(value) => - jsNumberToString(value).fold { - preTrans - } { - s => PreTransLit(StringLiteral(s)) - } + def constant(s: String): PreTransform = + PreTransLit(StringLiteral(s)) - case _ => preTrans + def forFloatingPoint(value: Double): PreTransform = + jsNumberToString(value).fold(preTrans)(s => constant(s)) + + literal match { + case CharLiteral(value) => constant(value.toString) + case ByteLiteral(value) => constant(value.toString) + case ShortLiteral(value) => constant(value.toString) + case IntLiteral(value) => constant(value.toString) + case LongLiteral(value) => constant(value.toString) + case FloatLiteral(value) => forFloatingPoint(value) + case DoubleLiteral(value) => forFloatingPoint(value) + case BooleanLiteral(value) => constant(value.toString) + case Null() => constant("null") + case Undefined() => constant("undefined") + case _ => preTrans } case _ => @@ -3298,10 +3419,10 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { } def intOp = (op: @switch) match { - case Long_< => Num_< - case Long_<= => Num_<= - case Long_> => Num_> - case Long_>= => Num_>= + case Long_< => Int_< + case Long_<= => Int_<= + case Long_> => Int_> + case Long_>= => Int_>= } (lhs, rhs) match { @@ -3394,9 +3515,9 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { val tempX = tempXDef.newReplacement val tempY = tempYDef.newReplacement cont(AndThen(AndThen( - BinaryOp(Num_>, tempX, IntLiteral(0)), - BinaryOp(Num_>, tempY, IntLiteral(0))), - BinaryOp(Num_<, BinaryOp(Int_+, tempX, tempY), IntLiteral(0)) + BinaryOp(Int_>, tempX, IntLiteral(0)), + BinaryOp(Int_>, tempY, IntLiteral(0))), + BinaryOp(Int_<, BinaryOp(Int_+, tempX, tempY), IntLiteral(0)) ).toPreTransform) } (finishTransform(isStat = false))(emptyScope) }.toPreTransform @@ -3471,14 +3592,14 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case Double_+ => (lhs, rhs) match { - case (PreTransLit(NumberLiteral(0)), _) => + case (PreTransLit(DoubleLiteral(0)), _) => rhs - case (_, PreTransLit(NumberLiteral(_))) => + case (_, PreTransLit(DoubleLiteral(_))) => foldBinaryOp(Double_+, rhs, lhs) - case (PreTransLit(NumberLiteral(x)), + case (PreTransLit(DoubleLiteral(x)), PreTransBinaryOp(innerOp @ (Double_+ | Double_-), - PreTransLit(NumberLiteral(y)), z)) => + PreTransLit(DoubleLiteral(y)), z)) => foldBinaryOp(innerOp, PreTransLit(DoubleLiteral(x + y)), z) case _ => default @@ -3486,19 +3607,19 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case Double_- => (lhs, rhs) match { - case (_, PreTransLit(NumberLiteral(r))) => + case (_, PreTransLit(DoubleLiteral(r))) => foldBinaryOp(Double_+, lhs, PreTransLit(DoubleLiteral(-r))) - case (PreTransLit(NumberLiteral(x)), - PreTransBinaryOp(Double_+, PreTransLit(NumberLiteral(y)), z)) => + case (PreTransLit(DoubleLiteral(x)), + PreTransBinaryOp(Double_+, PreTransLit(DoubleLiteral(y)), z)) => foldBinaryOp(Double_-, PreTransLit(DoubleLiteral(x - y)), z) - case (PreTransLit(NumberLiteral(x)), - PreTransBinaryOp(Double_-, PreTransLit(NumberLiteral(y)), z)) => + case (PreTransLit(DoubleLiteral(x)), + PreTransBinaryOp(Double_-, PreTransLit(DoubleLiteral(y)), z)) => foldBinaryOp(Double_+, PreTransLit(DoubleLiteral(x - y)), z) case (_, PreTransBinaryOp(BinaryOp.Double_-, - PreTransLit(NumberLiteral(0)), x)) => + PreTransLit(DoubleLiteral(0)), x)) => foldBinaryOp(Double_+, lhs, x) case _ => default @@ -3506,12 +3627,12 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case Double_* => (lhs, rhs) match { - case (_, PreTransLit(NumberLiteral(_))) => + case (_, PreTransLit(DoubleLiteral(_))) => foldBinaryOp(Double_*, rhs, lhs) - case (PreTransLit(NumberLiteral(1)), _) => + case (PreTransLit(DoubleLiteral(1)), _) => rhs - case (PreTransLit(NumberLiteral(-1)), _) => + case (PreTransLit(DoubleLiteral(-1)), _) => foldBinaryOp(Double_-, PreTransLit(DoubleLiteral(0)), rhs) case _ => default @@ -3519,9 +3640,9 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case Double_/ => (lhs, rhs) match { - case (_, PreTransLit(NumberLiteral(1))) => + case (_, PreTransLit(DoubleLiteral(1))) => lhs - case (_, PreTransLit(NumberLiteral(-1))) => + case (_, PreTransLit(DoubleLiteral(-1))) => foldBinaryOp(Double_-, PreTransLit(DoubleLiteral(0)), lhs) case _ => default @@ -3562,8 +3683,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case _ => default } - case Num_== | Num_!= => - val positive = (op == Num_==) + case Int_== | Int_!= => (lhs, rhs) match { case (PreTransBinaryOp(Int_+, PreTransLit(IntLiteral(x)), y), PreTransLit(IntLiteral(z))) => @@ -3582,54 +3702,48 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case _ => default } - case Num_< | Num_<= | Num_> | Num_>= => + case Int_< | Int_<= | Int_> | Int_>= => def flippedOp = (op: @switch) match { - case Num_< => Num_> - case Num_<= => Num_>= - case Num_> => Num_< - case Num_>= => Num_<= - } - - if (lhs.tpe.base == IntType && rhs.tpe.base == IntType) { - (lhs, rhs) match { - case (_, PreTransLit(IntLiteral(y))) => - y match { - case Int.MinValue => - if (op == Num_< || op == Num_>=) { - Block(finishTransformStat(lhs), - BooleanLiteral(op == Num_>=)).toPreTransform - } else { - foldBinaryOp(if (op == Num_<=) Num_== else Num_!=, lhs, rhs) - } + case Int_< => Int_> + case Int_<= => Int_>= + case Int_> => Int_< + case Int_>= => Int_<= + } - case Int.MaxValue => - if (op == Num_> || op == Num_<=) { - Block(finishTransformStat(lhs), - BooleanLiteral(op == Num_<=)).toPreTransform - } else { - foldBinaryOp(if (op == Num_>=) Num_== else Num_!=, lhs, rhs) - } + (lhs, rhs) match { + case (_, PreTransLit(IntLiteral(y))) => + y match { + case Int.MinValue => + if (op == Int_< || op == Int_>=) { + Block(finishTransformStat(lhs), + BooleanLiteral(op == Int_>=)).toPreTransform + } else { + foldBinaryOp(if (op == Int_<=) Int_== else Int_!=, lhs, rhs) + } - case _ if y == Int.MinValue + 1 && (op == Num_< || op == Num_>=) => - foldBinaryOp(if (op == Num_<) Num_== else Num_!=, lhs, - PreTransLit(IntLiteral(Int.MinValue))) + case Int.MaxValue => + if (op == Int_> || op == Int_<=) { + Block(finishTransformStat(lhs), + BooleanLiteral(op == Int_<=)).toPreTransform + } else { + foldBinaryOp(if (op == Int_>=) Int_== else Int_!=, lhs, rhs) + } - case _ if y == Int.MaxValue - 1 && (op == Num_> || op == Num_<=) => - foldBinaryOp(if (op == Num_>) Num_== else Num_!=, lhs, - PreTransLit(IntLiteral(Int.MaxValue))) + case _ if y == Int.MinValue + 1 && (op == Int_< || op == Int_>=) => + foldBinaryOp(if (op == Int_<) Int_== else Int_!=, lhs, + PreTransLit(IntLiteral(Int.MinValue))) - case _ => default - } + case _ if y == Int.MaxValue - 1 && (op == Int_> || op == Int_<=) => + foldBinaryOp(if (op == Int_>) Int_== else Int_!=, lhs, + PreTransLit(IntLiteral(Int.MaxValue))) - case (PreTransLit(IntLiteral(_)), _) => - foldBinaryOp(flippedOp, rhs, lhs) + case _ => default + } - case _ => default - } - } else { - (lhs, rhs) match { - case _ => default - } + case (PreTransLit(IntLiteral(_)), _) => + foldBinaryOp(flippedOp, rhs, lhs) + + case _ => default } case _ => @@ -3637,7 +3751,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { } } - private def fold3WayComparison(canBeEqual: Boolean, canBeLessThan: Boolean, + private def fold3WayIntComparison(canBeEqual: Boolean, canBeLessThan: Boolean, canBeGreaterThan: Boolean, lhs: PreTransform, rhs: PreTransform)( implicit pos: Position): PreTransform = { import BinaryOp._ @@ -3649,23 +3763,23 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { finishTransformStat(rhs), BooleanLiteral(true)).toPreTransform } else { - foldBinaryOp(Num_<=, lhs, rhs) + foldBinaryOp(Int_<=, lhs, rhs) } } else { if (canBeGreaterThan) - foldBinaryOp(Num_>=, lhs, rhs) + foldBinaryOp(Int_>=, lhs, rhs) else - foldBinaryOp(Num_==, lhs, rhs) + foldBinaryOp(Int_==, lhs, rhs) } } else { if (canBeLessThan) { if (canBeGreaterThan) - foldBinaryOp(Num_!=, lhs, rhs) + foldBinaryOp(Int_!=, lhs, rhs) else - foldBinaryOp(Num_<, lhs, rhs) + foldBinaryOp(Int_<, lhs, rhs) } else { if (canBeGreaterThan) { - foldBinaryOp(Num_>, lhs, rhs) + foldBinaryOp(Int_>, lhs, rhs) } else { Block( finishTransformStat(lhs), @@ -3680,11 +3794,12 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { cont: PreTransCont): TailRec[Tree] = { (charCode: @switch) match { case 'Z' if arg.tpe.base == BooleanType => cont(arg) + case 'B' if arg.tpe.base == ByteType => cont(arg) + case 'S' if arg.tpe.base == ShortType => cont(arg) case 'I' if arg.tpe.base == IntType => cont(arg) case 'F' if arg.tpe.base == FloatType => cont(arg) case 'J' if arg.tpe.base == LongType => cont(arg) - case 'D' if arg.tpe.base == DoubleType || - arg.tpe.base == IntType || arg.tpe.base == FloatType => cont(arg) + case 'D' if arg.tpe.base == DoubleType => cont(arg) case _ => cont(Unbox(finishTransformExpr(arg), charCode)(arg.pos).toPreTransform) } @@ -4212,15 +4327,20 @@ private[optimizer] object OptimizerCore { RefinedType(base, isExact, isNullable, AllocationSite.Anonymous) def apply(tpe: Type): RefinedType = tpe match { - case IntType | FloatType | DoubleType => - RefinedType(tpe, isExact = false, isNullable = false) - case BooleanType | StringType | UndefType | NothingType | - _:RecordType | NoType => - RefinedType(tpe, isExact = true, isNullable = false) + case AnyType | ClassType(_) | ArrayType(_) => + RefinedType(tpe, isExact = false, isNullable = true) case NullType => RefinedType(tpe, isExact = true, isNullable = true) - case _ => - RefinedType(tpe, isExact = false, isNullable = true) + case NothingType | UndefType | BooleanType | CharType | LongType | + StringType | NoType => + RefinedType(tpe, isExact = true, isNullable = false) + case ByteType | ShortType | IntType | FloatType | DoubleType | + RecordType(_) => + /* At run-time, a byte will answer true to `x.isInstanceOf[Int]`, + * therefore `byte`s must be non-exact. The same reasoning applies to + * other primitive numberic types. + */ + RefinedType(tpe, isExact = false, isNullable = false) } val NoRefinedType = RefinedType(NoType) @@ -4657,15 +4777,6 @@ private[optimizer] object OptimizerCore { private final case class Binding(name: String, originalName: Option[String], declaredType: Type, mutable: Boolean, value: PreTransform) - private object NumberLiteral { - def unapply(tree: Literal): Option[Double] = tree match { - case DoubleLiteral(v) => Some(v) - case IntLiteral(v) => Some(v.toDouble) - case FloatLiteral(v) => Some(v.toDouble) - case _ => None - } - } - private object LongFromInt { def apply(x: PreTransform)(implicit pos: Position): PreTransform = x match { case PreTransLit(IntLiteral(v)) => @@ -4976,6 +5087,7 @@ private[optimizer] object OptimizerCore { case Unbox(inner, _) => isSimpleArg(inner) case AsInstanceOf(inner, _) => isSimpleArg(inner) + case UnaryOp(_, inner) => isSimpleArg(inner) case _ => isTrivialArg(arg) From cc56fe758fbd1e6505ba05494142eb89b159780e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 11 Aug 2017 16:38:09 +0200 Subject: [PATCH 0441/2665] Hijack `j.l.Character` and make `char <: Character` in the IR. This brings `Char` on par with all the other primitive types as far as the IR is concerned. A primitive `char` (`CharType`) is a subtype of `j.l.Character`. This removes the complexity in the compiler and optimizer related to Chars being "special". Instead, it is now the Emitter's responsibility to deal with Chars. Indeed, the JS representation of primitive `char`s is *not*, in fact, a subtype of the JS representation of `j.l.Character`s. The root cause being that the `toString()` representation is different. Therefore, now the Emitter auto-boxes primitive `char`s when used in a place where a non-`char` is expected. This makes the Emitter a bit more complex, and definitely acutely aware of `char`'s. However, it allows the IR to be much cleaner, with no special primitive type that does not behave like the others. --- .../org/scalajs/core/compiler/GenJSCode.scala | 55 +--- .../scalajs/core/compiler/GenJSExports.scala | 19 +- .../scalajs/core/compiler/JSDefinitions.scala | 1 + .../org/scalajs/core/ir/Definitions.scala | 7 +- .../scala/org/scalajs/core/ir/Trees.scala | 1 + .../scala/org/scalajs/core/ir/Types.scala | 8 +- .../src/main/scala/java/lang/Character.scala | 167 ++--------- .../runtime/CharacterReflectiveCall.scala | 149 ++++++++++ .../scala/runtime/BoxesRunTime.scala | 8 - .../jsinterop/JSExportStaticTest.scala | 2 +- .../scalajs/testsuite/compiler/CharTest.scala | 21 ++ tools/scalajsenv.js | 63 ++++- .../core/tools/linker/analyzer/Analyzer.scala | 9 +- .../core/tools/linker/analyzer/Infos.scala | 3 +- .../linker/backend/emitter/ClassEmitter.scala | 31 +- .../backend/emitter/FunctionEmitter.scala | 267 +++++++++++------- .../tools/linker/backend/emitter/JSGen.scala | 30 +- .../tools/linker/frontend/BaseLinker.scala | 6 +- .../frontend/optimizer/OptimizerCore.scala | 61 +--- 19 files changed, 497 insertions(+), 411 deletions(-) create mode 100644 library/src/main/scala/scala/scalajs/runtime/CharacterReflectiveCall.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 1f95e77382..54eadfa0b9 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -927,12 +927,6 @@ abstract class GenJSCode extends plugins.PluginComponent */ jstpe.ClassType(encodeClassFullName(tpe.valueClazz)) - case _ if f.tpe.typeSymbol == CharClass => - /* Will be initialized to null, which will unbox to '\0' when - * read. - */ - jstpe.ClassType(ir.Definitions.BoxedCharacterClass) - case _ => /* Other types are not boxed, so we can initialize them to * their true zero. @@ -3777,6 +3771,7 @@ abstract class GenJSCode extends plugins.PluginComponent (StringClass, StringClass), (BoxedDoubleClass, NumberReflectiveCallClass), (BoxedBooleanClass, BooleanReflectiveCallClass), + (BoxedCharacterClass, CharacterReflectiveCallClass), (BoxedLongClass, LongReflectiveCallClass) ) implMethodSym = matchingSymIn(reflBoxClass) @@ -3805,6 +3800,7 @@ abstract class GenJSCode extends plugins.PluginComponent } else { val reflBoxClassPatched = { def isIntOrLongKind(kind: TypeKind) = kind match { + case CharKind => false case _:INT | LONG => true case _ => false } @@ -3894,14 +3890,7 @@ abstract class GenJSCode extends plugins.PluginComponent case VOID => // must be handled at least for JS interop js.Block(expr, js.Undefined()) case kind: ValueTypeKind => - if (kind == CharKind) { - genApplyMethod( - genLoadModule(BoxesRunTimeClass), - BoxesRunTime_boxToCharacter, - List(expr)) - } else { - expr // box is identity for all non-Char types - } + expr // box is identity for all primitive types case _ => abort(s"makePrimitiveBox requires a primitive type, found $tpe at $pos") } @@ -3914,14 +3903,7 @@ abstract class GenJSCode extends plugins.PluginComponent case VOID => // must be handled at least for JS interop expr case kind: ValueTypeKind => - if (kind == CharKind) { - genApplyMethod( - genLoadModule(BoxesRunTimeClass), - BoxesRunTime_unboxToChar, - List(expr)) - } else { - js.Unbox(expr, kind.primitiveCharCode) - } + js.Unbox(expr, kind.primitiveCharCode) case _ => abort(s"makePrimitiveUnbox requires a primitive type, found $tpe at $pos") } @@ -5586,27 +5568,14 @@ abstract class GenJSCode extends plugins.PluginComponent private def isStringType(tpe: Type): Boolean = tpe.typeSymbol == StringClass - private def isLongType(tpe: Type): Boolean = - tpe.typeSymbol == LongClass - - private lazy val BoxedBooleanClass = boxedClass(BooleanClass) - private lazy val BoxedByteClass = boxedClass(ByteClass) - private lazy val BoxedShortClass = boxedClass(ShortClass) - private lazy val BoxedIntClass = boxedClass(IntClass) - private lazy val BoxedLongClass = boxedClass(LongClass) - private lazy val BoxedFloatClass = boxedClass(FloatClass) - private lazy val BoxedDoubleClass = boxedClass(DoubleClass) - - private lazy val NumberClass = requiredClass[java.lang.Number] - - private lazy val HijackedNumberClasses = - Seq(BoxedByteClass, BoxedShortClass, BoxedIntClass, BoxedLongClass, - BoxedFloatClass, BoxedDoubleClass) - private lazy val HijackedBoxedClasses = - Seq(BoxedUnitClass, BoxedBooleanClass) ++ HijackedNumberClasses - - protected lazy val isHijackedBoxedClass: Set[Symbol] = - HijackedBoxedClasses.toSet + protected lazy val isHijackedBoxedClass: Set[Symbol] = { + /* This list is a duplicate of ir.Definitions.HijackedBoxedClasses, but + * with global.Symbol's instead of IR encoded names as Strings. + */ + Set(BoxedUnitClass, BoxedBooleanClass, BoxedCharacterClass, BoxedByteClass, + BoxedShortClass, BoxedIntClass, BoxedLongClass, BoxedFloatClass, + BoxedDoubleClass) + } private lazy val InlineAnnotationClass = requiredClass[scala.inline] private lazy val NoinlineAnnotationClass = requiredClass[scala.noinline] diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index 768f464d2d..ec646af51c 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -930,21 +930,20 @@ trait GenJSExports extends SubComponent { self: GenJSCode => case _ => import ir.{Definitions => Defs} (toTypeKind(tpe): @unchecked) match { - case VoidKind => HijackedTypeTest(Defs.BoxedUnitClass, 0) + case VoidKind => HijackedTypeTest(Defs.BoxedUnitClass, 0) case BooleanKind => HijackedTypeTest(Defs.BoxedBooleanClass, 1) - case ByteKind => HijackedTypeTest(Defs.BoxedByteClass, 2) - case ShortKind => HijackedTypeTest(Defs.BoxedShortClass, 3) - case IntKind => HijackedTypeTest(Defs.BoxedIntegerClass, 4) - case FloatKind => HijackedTypeTest(Defs.BoxedFloatClass, 5) - case DoubleKind => HijackedTypeTest(Defs.BoxedDoubleClass, 6) - - case CharKind => InstanceOfTypeTest(boxedClass(CharClass).tpe) - case LongKind => InstanceOfTypeTest(boxedClass(LongClass).tpe) + case CharKind => HijackedTypeTest(Defs.BoxedCharacterClass, 2) + case ByteKind => HijackedTypeTest(Defs.BoxedByteClass, 3) + case ShortKind => HijackedTypeTest(Defs.BoxedShortClass, 4) + case IntKind => HijackedTypeTest(Defs.BoxedIntegerClass, 5) + case LongKind => HijackedTypeTest(Defs.BoxedLongClass, 6) + case FloatKind => HijackedTypeTest(Defs.BoxedFloatClass, 7) + case DoubleKind => HijackedTypeTest(Defs.BoxedDoubleClass, 8) case REFERENCE(cls) => cls match { case BoxedUnitClass => HijackedTypeTest(Defs.BoxedUnitClass, 0) - case StringClass => HijackedTypeTest(Defs.StringClass, 7) + case StringClass => HijackedTypeTest(Defs.StringClass, 9) case ObjectClass => NoTypeTest case _ => if (isRawJSType(tpe)) NoTypeTest diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 98d6fe2052..ef01ea0e67 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -105,6 +105,7 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val RuntimeStringModuleClass = RuntimeStringModule.moduleClass lazy val BooleanReflectiveCallClass = getRequiredClass("scala.scalajs.runtime.BooleanReflectiveCall") + lazy val CharacterReflectiveCallClass = getRequiredClass("scala.scalajs.runtime.CharacterReflectiveCall") lazy val NumberReflectiveCallClass = getRequiredClass("scala.scalajs.runtime.NumberReflectiveCall") lazy val IntegerReflectiveCallClass = getRequiredClass("scala.scalajs.runtime.IntegerReflectiveCall") lazy val LongReflectiveCallClass = getRequiredClass("scala.scalajs.runtime.LongReflectiveCall") diff --git a/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala b/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala index 532dba795a..360bfd8a8e 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala @@ -39,13 +39,16 @@ object Definitions { val NumberClass = "jl_Number" val HijackedBoxedClasses = Set( - BoxedUnitClass, BoxedBooleanClass, BoxedByteClass, BoxedShortClass, - BoxedIntegerClass, BoxedLongClass, BoxedFloatClass, BoxedDoubleClass) + BoxedUnitClass, BoxedBooleanClass, BoxedCharacterClass, BoxedByteClass, + BoxedShortClass, BoxedIntegerClass, BoxedLongClass, BoxedFloatClass, + BoxedDoubleClass) val HijackedClasses = HijackedBoxedClasses + StringClass val AncestorsOfStringClass = Set( CharSequenceClass, ComparableClass, SerializableClass) + val AncestorsOfBoxedCharacterClass = Set( + ComparableClass, SerializableClass) val AncestorsOfHijackedNumberClasses = Set( NumberClass, ComparableClass, SerializableClass) val AncestorsOfBoxedBooleanClass = Set( diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 4409ac7e84..a29fccea45 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -451,6 +451,7 @@ object Trees { implicit val pos: Position) extends Tree { val tpe = (charCode: @switch) match { case 'Z' => BooleanType + case 'C' => CharType case 'B' => ByteType case 'S' => ShortType case 'I' => IntType diff --git a/ir/src/main/scala/org/scalajs/core/ir/Types.scala b/ir/src/main/scala/org/scalajs/core/ir/Types.scala index cda6c7f11e..926bd875d0 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Types.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Types.scala @@ -63,11 +63,6 @@ object Types { /** `Char` type, a 16-bit UTF-16 code unit. * It does not accept `null` nor `undefined`. - * - * `CharType` has the peculiarity that it is *not* a subtype of [[AnyType]]. - * As such, no method can be called on a `CharType` either. In fact, very - * few operations manipulate `CharType`s. It is usually necessary to convert - * to/from [[IntType]]s using the appropriate `UnaryOp` conversions. */ case object CharType extends Type @@ -204,7 +199,6 @@ object Types { (lhs != NoType && rhs != NoType) && { (lhs == rhs) || ((lhs, rhs) match { - case (CharType, _) => false case (_, AnyType) => true case (NothingType, _) => true @@ -218,6 +212,8 @@ object Types { isSubclass(BoxedUnitClass, cls) case (BooleanType, ClassType(cls)) => isSubclass(BoxedBooleanClass, cls) + case (CharType, ClassType(cls)) => + isSubclass(BoxedCharacterClass, cls) case (ByteType, ClassType(cls)) => isSubclass(BoxedByteClass, cls) case (ShortType, ClassType(cls)) => diff --git a/javalanglib/src/main/scala/java/lang/Character.scala b/javalanglib/src/main/scala/java/lang/Character.scala index 6d8bf062e4..b5efca8f69 100644 --- a/javalanglib/src/main/scala/java/lang/Character.scala +++ b/javalanglib/src/main/scala/java/lang/Character.scala @@ -4,159 +4,34 @@ import scala.scalajs.js import java.util.Arrays -@inline -class Character(private val value: scala.Char) +/* This is a hijacked class. Its instances are primitive chars. + * + * In fact, "primitive" is only true at the IR level. In JS, there is no such + * thing as a primitive character. Turning IR chars into valid JS is the + * responsibility of the Emitter. + * + * Constructors are not emitted. + */ +class Character private () extends AnyRef with java.io.Serializable with Comparable[Character] { - def charValue(): scala.Char = value + def this(value: scala.Char) = this() - override def equals(that: Any): scala.Boolean = - that.isInstanceOf[Character] && (value == that.asInstanceOf[Character].charValue) + @inline def charValue(): scala.Char = + this.asInstanceOf[scala.Char] - override def compareTo(that: Character): Int = - Character.compare(charValue, that.charValue) + @inline override def hashCode(): Int = charValue.toInt - override def toString(): String = - Character.toString(value) + @inline override def equals(that: Any): scala.Boolean = { + that.isInstanceOf[Character] && + (charValue == that.asInstanceOf[Character].charValue) + } - override def hashCode(): Int = value.## - - /* - * Methods on scala.Char - * The following methods are only here to properly support reflective calls - * on boxed primitive values. YOU WILL NOT BE ABLE TO USE THESE METHODS, since - * we use the true javalib to lookup symbols, this file contains only - * implementations. - */ - protected def toByte: scala.Byte = value.toByte - protected def toShort: scala.Short = value.toShort - protected def toChar: scala.Char = value.toChar - protected def toInt: scala.Int = value - protected def toLong: scala.Long = value.toLong - protected def toFloat: scala.Float = value.toFloat - protected def toDouble: scala.Double = value.toDouble - - // scalastyle:off disallow.space.before.token - protected def unary_~ : scala.Int = ~value - protected def unary_+ : scala.Int = value - protected def unary_- : scala.Int = -value - // scalastyle:on disallow.space.before.token - - protected def +(x: String): String = value + x - - protected def <<(x: scala.Int): scala.Int = value << x - protected def <<(x: scala.Long): scala.Int = value << x - protected def >>>(x: scala.Int): scala.Int = value >>> x - protected def >>>(x: scala.Long): scala.Int = value >>> x - protected def >>(x: scala.Int): scala.Int = value >> x - protected def >>(x: scala.Long): scala.Int = value >> x - - protected def ==(x: scala.Byte): scala.Boolean = value == x - protected def ==(x: scala.Short): scala.Boolean = value == x - protected def ==(x: scala.Char): scala.Boolean = value == x - protected def ==(x: scala.Int): scala.Boolean = value == x - protected def ==(x: scala.Long): scala.Boolean = value == x - protected def ==(x: scala.Float): scala.Boolean = value == x - protected def ==(x: scala.Double): scala.Boolean = value == x - - protected def !=(x: scala.Byte): scala.Boolean = value != x - protected def !=(x: scala.Short): scala.Boolean = value != x - protected def !=(x: scala.Char): scala.Boolean = value != x - protected def !=(x: scala.Int): scala.Boolean = value != x - protected def !=(x: scala.Long): scala.Boolean = value != x - protected def !=(x: scala.Float): scala.Boolean = value != x - protected def !=(x: scala.Double): scala.Boolean = value != x - - protected def <(x: scala.Byte): scala.Boolean = value < x - protected def <(x: scala.Short): scala.Boolean = value < x - protected def <(x: scala.Char): scala.Boolean = value < x - protected def <(x: scala.Int): scala.Boolean = value < x - protected def <(x: scala.Long): scala.Boolean = value < x - protected def <(x: scala.Float): scala.Boolean = value < x - protected def <(x: scala.Double): scala.Boolean = value < x - - protected def <=(x: scala.Byte): scala.Boolean = value <= x - protected def <=(x: scala.Short): scala.Boolean = value <= x - protected def <=(x: scala.Char): scala.Boolean = value <= x - protected def <=(x: scala.Int): scala.Boolean = value <= x - protected def <=(x: scala.Long): scala.Boolean = value <= x - protected def <=(x: scala.Float): scala.Boolean = value <= x - protected def <=(x: scala.Double): scala.Boolean = value <= x - - protected def >(x: scala.Byte): scala.Boolean = value > x - protected def >(x: scala.Short): scala.Boolean = value > x - protected def >(x: scala.Char): scala.Boolean = value > x - protected def >(x: scala.Int): scala.Boolean = value > x - protected def >(x: scala.Long): scala.Boolean = value > x - protected def >(x: scala.Float): scala.Boolean = value > x - protected def >(x: scala.Double): scala.Boolean = value > x - - protected def >=(x: scala.Byte): scala.Boolean = value >= x - protected def >=(x: scala.Short): scala.Boolean = value >= x - protected def >=(x: scala.Char): scala.Boolean = value >= x - protected def >=(x: scala.Int): scala.Boolean = value >= x - protected def >=(x: scala.Long): scala.Boolean = value >= x - protected def >=(x: scala.Float): scala.Boolean = value >= x - protected def >=(x: scala.Double): scala.Boolean = value >= x - - protected def |(x: scala.Byte): scala.Int = value | x - protected def |(x: scala.Short): scala.Int = value | x - protected def |(x: scala.Char): scala.Int = value | x - protected def |(x: scala.Int): scala.Int = value | x - protected def |(x: scala.Long): scala.Long = value | x - - protected def &(x: scala.Byte): scala.Int = value & x - protected def &(x: scala.Short): scala.Int = value & x - protected def &(x: scala.Char): scala.Int = value & x - protected def &(x: scala.Int): scala.Int = value & x - protected def &(x: scala.Long): scala.Long = value & x - - protected def ^(x: scala.Byte): scala.Int = value ^ x - protected def ^(x: scala.Short): scala.Int = value ^ x - protected def ^(x: scala.Char): scala.Int = value ^ x - protected def ^(x: scala.Int): scala.Int = value ^ x - protected def ^(x: scala.Long): scala.Long = value ^ x - - protected def +(x: scala.Byte): scala.Int = value + x - protected def +(x: scala.Short): scala.Int = value + x - protected def +(x: scala.Char): scala.Int = value + x - protected def +(x: scala.Int): scala.Int = value + x - protected def +(x: scala.Long): scala.Long = value + x - protected def +(x: scala.Float): scala.Float = value + x - protected def +(x: scala.Double): scala.Double = value + x - - protected def -(x: scala.Byte): scala.Int = value - x - protected def -(x: scala.Short): scala.Int = value - x - protected def -(x: scala.Char): scala.Int = value - x - protected def -(x: scala.Int): scala.Int = value - x - protected def -(x: scala.Long): scala.Long = value - x - protected def -(x: scala.Float): scala.Float = value - x - protected def -(x: scala.Double): scala.Double = value - x - - protected def *(x: scala.Byte): scala.Int = value * x - protected def *(x: scala.Short): scala.Int = value * x - protected def *(x: scala.Char): scala.Int = value * x - protected def *(x: scala.Int): scala.Int = value * x - protected def *(x: scala.Long): scala.Long = value * x - protected def *(x: scala.Float): scala.Float = value * x - protected def *(x: scala.Double): scala.Double = value * x - - protected def /(x: scala.Byte): scala.Int = value / x - protected def /(x: scala.Short): scala.Int = value / x - protected def /(x: scala.Char): scala.Int = value / x - protected def /(x: scala.Int): scala.Int = value / x - protected def /(x: scala.Long): scala.Long = value / x - protected def /(x: scala.Float): scala.Float = value / x - protected def /(x: scala.Double): scala.Double = value / x - - protected def %(x: scala.Byte): scala.Int = value % x - protected def %(x: scala.Short): scala.Int = value % x - protected def %(x: scala.Char): scala.Int = value % x - protected def %(x: scala.Int): scala.Int = value % x - protected def %(x: scala.Long): scala.Long = value % x - protected def %(x: scala.Float): scala.Float = value % x - protected def %(x: scala.Double): scala.Double = value % x + @inline override def toString(): String = + Character.toString(charValue) + @inline override def compareTo(that: Character): Int = + Character.compare(charValue, that.charValue) } object Character { diff --git a/library/src/main/scala/scala/scalajs/runtime/CharacterReflectiveCall.scala b/library/src/main/scala/scala/scalajs/runtime/CharacterReflectiveCall.scala new file mode 100644 index 0000000000..fbbf661c73 --- /dev/null +++ b/library/src/main/scala/scala/scalajs/runtime/CharacterReflectiveCall.scala @@ -0,0 +1,149 @@ +package scala.scalajs.runtime + +/** Explicit box for char values when doing a reflective call. + * This class and its methods are only here to properly support reflective + * calls on characters. + */ +final class CharacterReflectiveCall(value: Char) { + + // Methods of java.lang.Character + + def charValue(): Char = value + + def compareTo(that: Character): Int = + new Character(value).compareTo(that) + def compareTo(that: AnyRef): Int = + new Character(value).compareTo(that.asInstanceOf[Character]) + + // Methods of Char + + def toByte: Byte = value.toByte + def toShort: Short = value.toShort + def toChar: Char = value.toChar + def toInt: Int = value + def toLong: Long = value.toLong + def toFloat: Float = value.toFloat + def toDouble: Double = value.toDouble + + // scalastyle:off disallow.space.before.token + def unary_~ : Int = ~value + def unary_+ : Int = value + def unary_- : Int = -value + // scalastyle:on disallow.space.before.token + + def +(x: String): String = value + x + + def <<(x: Int): Int = value << x + def <<(x: Long): Int = value << x + def >>>(x: Int): Int = value >>> x + def >>>(x: Long): Int = value >>> x + def >>(x: Int): Int = value >> x + def >>(x: Long): Int = value >> x + + def ==(x: Byte): Boolean = value == x + def ==(x: Short): Boolean = value == x + def ==(x: Char): Boolean = value == x + def ==(x: Int): Boolean = value == x + def ==(x: Long): Boolean = value == x + def ==(x: Float): Boolean = value == x + def ==(x: Double): Boolean = value == x + + def !=(x: Byte): Boolean = value != x + def !=(x: Short): Boolean = value != x + def !=(x: Char): Boolean = value != x + def !=(x: Int): Boolean = value != x + def !=(x: Long): Boolean = value != x + def !=(x: Float): Boolean = value != x + def !=(x: Double): Boolean = value != x + + def <(x: Byte): Boolean = value < x + def <(x: Short): Boolean = value < x + def <(x: Char): Boolean = value < x + def <(x: Int): Boolean = value < x + def <(x: Long): Boolean = value < x + def <(x: Float): Boolean = value < x + def <(x: Double): Boolean = value < x + + def <=(x: Byte): Boolean = value <= x + def <=(x: Short): Boolean = value <= x + def <=(x: Char): Boolean = value <= x + def <=(x: Int): Boolean = value <= x + def <=(x: Long): Boolean = value <= x + def <=(x: Float): Boolean = value <= x + def <=(x: Double): Boolean = value <= x + + def >(x: Byte): Boolean = value > x + def >(x: Short): Boolean = value > x + def >(x: Char): Boolean = value > x + def >(x: Int): Boolean = value > x + def >(x: Long): Boolean = value > x + def >(x: Float): Boolean = value > x + def >(x: Double): Boolean = value > x + + def >=(x: Byte): Boolean = value >= x + def >=(x: Short): Boolean = value >= x + def >=(x: Char): Boolean = value >= x + def >=(x: Int): Boolean = value >= x + def >=(x: Long): Boolean = value >= x + def >=(x: Float): Boolean = value >= x + def >=(x: Double): Boolean = value >= x + + def |(x: Byte): Int = value | x + def |(x: Short): Int = value | x + def |(x: Char): Int = value | x + def |(x: Int): Int = value | x + def |(x: Long): Long = value | x + + def &(x: Byte): Int = value & x + def &(x: Short): Int = value & x + def &(x: Char): Int = value & x + def &(x: Int): Int = value & x + def &(x: Long): Long = value & x + + def ^(x: Byte): Int = value ^ x + def ^(x: Short): Int = value ^ x + def ^(x: Char): Int = value ^ x + def ^(x: Int): Int = value ^ x + def ^(x: Long): Long = value ^ x + + def +(x: Byte): Int = value + x + def +(x: Short): Int = value + x + def +(x: Char): Int = value + x + def +(x: Int): Int = value + x + def +(x: Long): Long = value + x + def +(x: Float): Float = value + x + def +(x: Double): Double = value + x + + def -(x: Byte): Int = value - x + def -(x: Short): Int = value - x + def -(x: Char): Int = value - x + def -(x: Int): Int = value - x + def -(x: Long): Long = value - x + def -(x: Float): Float = value - x + def -(x: Double): Double = value - x + + def *(x: Byte): Int = value * x + def *(x: Short): Int = value * x + def *(x: Char): Int = value * x + def *(x: Int): Int = value * x + def *(x: Long): Long = value * x + def *(x: Float): Float = value * x + def *(x: Double): Double = value * x + + def /(x: Byte): Int = value / x + def /(x: Short): Int = value / x + def /(x: Char): Int = value / x + def /(x: Int): Int = value / x + def /(x: Long): Long = value / x + def /(x: Float): Float = value / x + def /(x: Double): Double = value / x + + def %(x: Byte): Int = value % x + def %(x: Short): Int = value % x + def %(x: Char): Int = value % x + def %(x: Int): Int = value % x + def %(x: Long): Long = value % x + def %(x: Float): Float = value % x + def %(x: Double): Double = value % x + +} diff --git a/scalalib/overrides/scala/runtime/BoxesRunTime.scala b/scalalib/overrides/scala/runtime/BoxesRunTime.scala index 9a6bad0fdd..b8a5157cd8 100644 --- a/scalalib/overrides/scala/runtime/BoxesRunTime.scala +++ b/scalalib/overrides/scala/runtime/BoxesRunTime.scala @@ -3,14 +3,6 @@ package scala.runtime import scala.math.ScalaNumber object BoxesRunTime { - def boxToCharacter(c: Char): java.lang.Character = - java.lang.Character.valueOf(c) - - @inline - def unboxToChar(c: Object): Char = - if (c eq null) 0 - else c.asInstanceOf[java.lang.Character].charValue() - def equals(x: Object, y: Object): Boolean = if (x eq y) true else equals2(x, y) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala index 1ac2abb4ba..374f9be1fd 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala @@ -260,7 +260,7 @@ class JSExportStaticTest { assertEquals('\0', JSExportStaticTest.StaticExportFields.uninitializedVarChar) - assertEquals(null, statics.uninitializedVarChar) + assertEquals('\0', statics.uninitializedVarChar) } @Test def field_also_exists_in_member(): Unit = { diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/CharTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/CharTest.scala index 703ddc1aa5..1f052015be 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/CharTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/CharTest.scala @@ -35,4 +35,25 @@ class CharTest { // note: expected values are constant-folded by the compiler on the JVM test(Char.MaxValue, Char.MaxValue, Char.MaxValue * Char.MaxValue) } + + @Test + def do_not_box_several_times_in_a_block(): Unit = { + @noinline def test(x: Any): Unit = + assertEquals('A', x) + + test({ + test('A') + 'A' + }: Char) + } + + @Test + def do_not_box_several_times_in_an_if(): Unit = { + @noinline def test(x: Any): Unit = + assertEquals('A', x) + + @noinline def cond: Boolean = true + + test((if (cond) 'A' else 'B'): Char) + } } diff --git a/tools/scalajsenv.js b/tools/scalajsenv.js index b448aef705..18c8bc0aaa 100644 --- a/tools/scalajsenv.js +++ b/tools/scalajsenv.js @@ -157,6 +157,26 @@ function $propertyName(obj) { return prop; }; +// Boxed Char + +//!if outputMode == ECMAScript6 +class $Char { + constructor(c) { + this.c = c; + } + toString() { + return String["fromCharCode"](this.c); + } +} +//!else +function $Char(c) { + this.c = c; +}; +$Char.prototype.toString = (function() { + return String["fromCharCode"](this.c); +}); +//!endif + // Runtime functions function $isScalaJSObject(obj) { @@ -259,6 +279,8 @@ function $objectGetClass(instance) { return instance.getClass__jl_Class(); else if ($is_sjsr_RuntimeLong(instance)) return $d_jl_Long.getClassOf(); + else if ($isChar(instance)) + return $d_jl_Character.getClassOf(); else if ($isScalaJSObject(instance)) return instance.$classData.getClassOf(); else @@ -296,6 +318,8 @@ function $objectEquals(instance, rhs) { return instance.equals__O__Z(rhs); else if (typeof instance === "number") return typeof rhs === "number" && $numberEquals(instance, rhs); + else if ($isChar(instance)) + return $isChar(rhs) && instance.c === rhs.c; else return instance === rhs; }; @@ -323,6 +347,8 @@ function $objectHashCode(instance) { default: if ($isScalaJSObject(instance) || instance === null) return instance.hashCode__I(); + else if ($isChar(instance)) + return instance.c; //!if outputMode != ECMAScript6 else if ($idHashCodeMap === null) return 42; @@ -350,7 +376,14 @@ function $comparableCompareTo(instance, rhs) { //!endif return instance - rhs; // yes, this gives the right result default: - return instance.compareTo__O__I(rhs); + if ($isChar(instance)) { +//!if asInstanceOfs != Unchecked + $asChar(rhs); +//!endif + return instance.c - rhs.c; + } else { + return instance.compareTo__O__I(rhs); + } } }; @@ -392,6 +425,10 @@ function $booleanBooleanValue(instance) { else return instance.booleanValue__Z(); }; +function $characterCharValue(instance) { + return instance.c; +} + function $numberByteValue(instance) { if (typeof instance === "number") return (instance << 24) >> 24; else return instance.byteValue__B(); @@ -563,6 +600,10 @@ const $systemIdentityHashCode = // is/as for hijacked boxed classes (the non-trivial ones) +function $isChar(v) { + return v instanceof $Char; +}; + function $isByte(v) { return typeof v === "number" && (v << 24 >> 24) === v && 1/v !== 1/-0; }; @@ -598,6 +639,13 @@ function $asBoolean(v) { $throwClassCastException(v, "java.lang.Boolean"); }; +function $asChar(v) { + if (v instanceof $Char || v === null) + return v; + else + $throwClassCastException(v, "java.lang.Character"); +}; + function $asByte(v) { if ($isByte(v) || v === null) return v; @@ -634,12 +682,22 @@ function $asDouble(v) { }; //!endif +// Boxes + +function $bC(c) { + return new $Char(c); +} +const $bC0 = $bC(0); + // Unboxes //!if asInstanceOfs != Unchecked function $uZ(value) { return !!$asBoolean(value); }; +function $uC(value) { + return null === value ? 0 : $asChar(value).c; +}; function $uB(value) { return $asByte(value) | 0; }; @@ -663,6 +721,9 @@ function $uD(value) { return +$asDouble(value); }; //!else +function $uC(value) { + return null === value ? 0 : value.c; +} function $uJ(value) { return null === value ? $m_sjsr_RuntimeLong$().Zero$1 : value; }; diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala index 3a6d842dc2..9cf8bbb6b2 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala @@ -534,17 +534,10 @@ private final class Analyzer(config: CommonPhaseConfig, assert(this.isScalaClass, s"Cannot create reflective proxy in non-Scala class $this") - val returnsChar = targetName.endsWith("__C") val syntheticInfo = makeSyntheticMethodInfo( encodedName = proxyName, methodsCalled = Map( - this.encodedName -> List(targetName)), - methodsCalledStatically = ( - if (returnsChar) Map(BoxedCharacterClass -> List("init___C")) - else Map.empty), - instantiatedClasses = ( - if (returnsChar) List(BoxedCharacterClass) - else Nil)) + this.encodedName -> List(targetName))) val m = new MethodInfo(this, syntheticInfo) m.syntheticKind = MethodSyntheticKind.ReflectiveProxy(targetName) methodInfos += proxyName -> m diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala index c8d2e94c3c..8b1a9eff35 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala @@ -186,6 +186,7 @@ object Infos { case AnyType => addMethodCalled(ObjectClass, method) case UndefType => addMethodCalled(BoxedUnitClass, method) case BooleanType => addMethodCalled(BoxedBooleanClass, method) + case CharType => addMethodCalled(BoxedCharacterClass, method) case ByteType => addMethodCalled(BoxedByteClass, method) case ShortType => addMethodCalled(BoxedShortClass, method) case IntType => addMethodCalled(BoxedIntegerClass, method) @@ -198,7 +199,7 @@ object Infos { case NullType | NothingType => // Nothing to do - case NoType | CharType | RecordType(_) => + case NoType | RecordType(_) => throw new IllegalArgumentException( s"Illegal receiver type: $receiverTpe") } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index 8fd805a91a..ccc1b28f19 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -310,7 +310,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { assert(initMethodDef.resultType == NoType, s"Found a constructor with type ${initMethodDef.resultType} at $pos") desugarToFunction(tree.encodedName, initMethodDef.args, initMethodBody, - isStat = true) + resultType = NoType) } for (generatedInitMethodFun <- generatedInitMethodFunWithGlobals) yield { @@ -329,7 +329,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { tree.exportedMembers.map(_.value) collectFirst { case MethodDef(false, StringLiteral("constructor"), params, _, body) => - desugarToFunction(tree.encodedName, params, body.get, isStat = true) + desugarToFunction(tree.encodedName, params, body.get, resultType = NoType) } getOrElse { throw new IllegalArgumentException( s"${tree.encodedName} does not have an exported constructor") @@ -374,7 +374,10 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val classVar = envField("c", className) for (propName <- genPropertyName(name)) yield { val select = genPropSelect(classVar, propName) - js.Assign(select, genZeroOf(ftpe)) + val zero = + if (ftpe == CharType) js.VarRef(js.Ident("$bC0")) + else genZeroOf(ftpe) + js.Assign(select, zero) } } WithGlobals.list(statsWithGlobals) @@ -401,7 +404,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { implicit val pos = method.pos val methodFun0WithGlobals = desugarToFunction(className, - method.args, methodBody, method.resultType == NoType) + method.args, methodBody, method.resultType) methodFun0WithGlobals.flatMap { methodFun0 => val methodFun = if (Definitions.isConstructorName(method.encodedName)) { @@ -456,7 +459,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { implicit val pos = method.pos val methodFunWithGlobals = desugarToFunctionWithExplicitThis( - className, method.args, method.body.get, method.resultType == NoType) + className, method.args, method.body.get, method.resultType) for (methodFun <- methodFunWithGlobals) yield { val Ident(methodName, origName) = method.name @@ -495,13 +498,13 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { // optional getter definition val optGetterWithGlobals = property.getterBody map { body => - desugarToFunction(className, Nil, body, isStat = false) + desugarToFunction(className, Nil, body, resultType = AnyType) } // optional setter definition val optSetterWithGlobals = property.setterArgAndBody map { case (arg, body) => - desugarToFunction(className, arg :: Nil, body, isStat = true) + desugarToFunction(className, arg :: Nil, body, resultType = NoType) } for { @@ -542,14 +545,14 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val getterWithGlobals = property.getterBody.fold { WithGlobals[js.Tree](js.Skip()) } { body => - for (fun <- desugarToFunction(className, Nil, body, isStat = false)) + for (fun <- desugarToFunction(className, Nil, body, resultType = AnyType)) yield js.GetterDef(static, propName, fun.body) } val setterWithGlobals = property.setterArgAndBody.fold { WithGlobals[js.Tree](js.Skip()) } { case (arg, body) => - for (fun <- desugarToFunction(className, arg :: Nil, body, isStat = true)) + for (fun <- desugarToFunction(className, arg :: Nil, body, resultType = NoType)) yield js.SetterDef(static, propName, fun.args.head, fun.body) } @@ -605,7 +608,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { case ComputedName(tree, _) => implicit val pos = name.pos for { - fun <- desugarToFunction(params = Nil, body = tree, isStat = false) + fun <- desugarToFunction(params = Nil, body = tree, resultType = AnyType) } yield { val nameTree = fun match { case js.Function(Nil, js.Return(expr)) => @@ -643,6 +646,8 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { AncestorsOfHijackedNumberClasses.contains(className) val isAncestorOfBoxedBooleanClass = AncestorsOfBoxedBooleanClass.contains(className) + val isAncestorOfBoxedCharacterClass = + AncestorsOfBoxedCharacterClass.contains(className) val isAncestorOfBoxedUnitClass = AncestorsOfBoxedUnitClass.contains(className) @@ -678,6 +683,8 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { if (isAncestorOfBoxedBooleanClass) test = test || ( js.UnaryOp(JSUnaryOp.typeof, obj) === js.StringLiteral("boolean")) + if (isAncestorOfBoxedCharacterClass) + test = test || genCallHelper("isChar", obj) if (isAncestorOfBoxedUnitClass) test = test || (obj === js.Undefined()) @@ -1040,7 +1047,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val baseCtor = envField("c", cd.name.name, cd.name.originalName) val generatedFunWithGlobals = desugarToFunctionWithExplicitThis( - cd.encodedName, args, body, isStat = true) + cd.encodedName, args, body, resultType = NoType) for (generatedFun <- generatedFunWithGlobals) yield { val js.Function(thisParam :: ctorParams, ctorBody) = generatedFun @@ -1114,7 +1121,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { genCreateNamespaceInExports(fullName) val methodDefWithGlobals = desugarToFunction(cd.encodedName, args, body, - isStat = resultType == NoType) + resultType) for (methodDef <- methodDefWithGlobals) yield { js.Block( diff --git 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 index 756a0d05ea..e8038b5c71 100644 --- 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 @@ -198,30 +198,33 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { /** Desugars parameters and body to a JS function. */ def desugarToFunction(enclosingClassName: String, params: List[ParamDef], - body: Tree, isStat: Boolean)( + body: Tree, resultType: Type)( implicit globalKnowledge: GlobalKnowledge, pos: Position): WithGlobals[js.Function] = { - new JSDesugar().desugarToFunction(params, body, isStat, - Env.empty.withEnclosingClassName(Some(enclosingClassName))) + new JSDesugar().desugarToFunction(params, body, + isStat = resultType == NoType, + Env.empty(resultType).withEnclosingClassName(Some(enclosingClassName))) } /** Desugars parameters and body to a JS function where `this` is given as * an explicit normal parameter. */ def desugarToFunctionWithExplicitThis(enclosingClassName: String, - params: List[ParamDef], body: Tree, isStat: Boolean)( + params: List[ParamDef], body: Tree, resultType: Type)( implicit globalKnowledge: GlobalKnowledge, pos: Position): WithGlobals[js.Function] = { - new JSDesugar().desugarToFunctionWithExplicitThis(params, body, isStat, - Env.empty.withEnclosingClassName(Some(enclosingClassName))) + new JSDesugar().desugarToFunctionWithExplicitThis(params, body, + isStat = resultType == NoType, + Env.empty(resultType).withEnclosingClassName(Some(enclosingClassName))) } /** Desugars parameters and body to a JS function. */ - def desugarToFunction(params: List[ParamDef], body: Tree, isStat: Boolean)( + def desugarToFunction(params: List[ParamDef], body: Tree, resultType: Type)( implicit globalKnowledge: GlobalKnowledge, pos: Position): WithGlobals[js.Function] = { - new JSDesugar().desugarToFunction(params, body, isStat, Env.empty) + new JSDesugar().desugarToFunction(params, body, + isStat = resultType == NoType, Env.empty(resultType)) } private class JSDesugar()(implicit globalKnowledge: GlobalKnowledge) { @@ -489,18 +492,18 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { unnest(qualifier, rhs) { (newQualifier, newRhs, env0) => implicit val env = env0 js.Assign( - js.DotSelect(transformExpr(newQualifier), + js.DotSelect(transformExprNoChar(newQualifier), transformPropIdent(item))(select.pos), - transformExpr(newRhs)) + transformExpr(newRhs, select.tpe)) } case Assign(select @ ArraySelect(array, index), rhs) => unnest(List(array, index, rhs)) { case (List(newArray, newIndex, newRhs), env0) => implicit val env = env0 - val genArray = transformExpr(newArray) - val genIndex = transformExpr(newIndex) - val genRhs = transformExpr(newRhs) + val genArray = transformExprNoChar(newArray) + val genIndex = transformExprNoChar(newIndex) + val genRhs = transformExpr(newRhs, select.tpe) semantics.arrayIndexOutOfBounds match { case CheckedBehavior.Compliant | CheckedBehavior.Fatal => js.Apply(js.DotSelect(genArray, js.Ident("set")), @@ -518,9 +521,9 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { unnest(qualifier, rhs) { (newQualifier, newRhs, env0) => implicit val env = env0 js.Assign( - js.DotSelect(transformExpr(newQualifier), + js.DotSelect(transformExprNoChar(newQualifier), transformPropIdent(item))(select.pos), - transformExpr(newRhs)) + transformExprNoChar(newRhs)) } case Assign(select @ JSBracketSelect(qualifier, item), rhs) => @@ -528,9 +531,9 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case (List(newQualifier, newItem, newRhs), env0) => implicit val env = env0 js.Assign( - genBracketSelect(transformExpr(newQualifier), - transformExpr(newItem))(select.pos), - transformExpr(newRhs)) + genBracketSelect(transformExprNoChar(newQualifier), + transformExprNoChar(newItem))(select.pos), + transformExprNoChar(newRhs)) } case Assign(select @ JSSuperBracketSelect(cls, qualifier, item), rhs) => @@ -540,8 +543,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { val ctor = extractWithGlobals(genRawJSClassConstructor(cls.className)) genCallHelper("superSet", ctor DOT "prototype", - transformExpr(newQualifier), transformExpr(item), - transformExpr(rhs)) + transformExprNoChar(newQualifier), transformExprNoChar(item), + transformExprNoChar(rhs)) } case Assign(lhs @ (_:VarRef | _:SelectStatic | _:JSGlobalRef), rhs) => @@ -556,7 +559,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { implicit val env = env0 js.Assign( envField("n", cls.className), - transformExpr(newValue)) + transformExprNoChar(newValue)) } case While(cond, body, label) => @@ -566,7 +569,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { val newLabel = label.map(transformLabelIdent) val bodyBreakTargets = tailPosLabels ++ label.map(_.name) if (isExpression(cond)) { - js.While(transformExpr(cond), + js.While(transformExprNoChar(cond), transformStat(body, Set.empty)( env.withDefaultBreakTargets(bodyBreakTargets)), newLabel) @@ -574,7 +577,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { js.While(js.BooleanLiteral(true), { unnest(cond) { (newCond, env0) => implicit val env = env0 - js.If(transformExpr(newCond), + js.If(transformExprNoChar(newCond), transformStat(body, Set.empty)( env.withDefaultBreakTargets(bodyBreakTargets)), js.Break()) @@ -592,7 +595,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { js.DoWhile( transformStat(body, Set.empty)( env.withDefaultBreakTargets(bodyBreakTargets)), - transformExpr(cond), newLabel) + transformExprNoChar(cond), newLabel) } else { /* This breaks 'continue' statements for this loop, but we don't * care because we never emit continue statements for do..while @@ -604,7 +607,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { env.withDefaultBreakTargets(bodyBreakTargets)), unnest(cond) { (newCond, env0) => implicit val env = env0 - js.If(transformExpr(newCond), js.Skip(), js.Break()) + js.If(transformExprNoChar(newCond), js.Skip(), js.Break()) }) }, newLabel) } @@ -631,15 +634,15 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { val argArray = spreadToArgArray(newArgs) js.Apply( genIdentBracketSelect(superCtor, "apply"), - List(js.This(), transformExpr(argArray))) + List(js.This(), transformExprNoChar(argArray))) } else { js.Apply( genIdentBracketSelect(superCtor, "call"), - js.This() :: newArgs.map(transformExpr)) + js.This() :: newArgs.map(transformExprNoChar)) } case OutputMode.ECMAScript6 => - js.Apply(js.Super(), newArgs.map(transformExpr)) + js.Apply(js.Super(), newArgs.map(transformExprNoChar)) } } @@ -698,11 +701,15 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { args) } + val zero = + if (ftpe == CharType) js.VarRef(js.Ident("$bC0")) + else genZeroOf(ftpe) + val descriptor = js.ObjectConstr(List( js.StringLiteral("configurable") -> js.BooleanLiteral(true), js.StringLiteral("enumerable") -> js.BooleanLiteral(true), js.StringLiteral("writable") -> js.BooleanLiteral(true), - js.StringLiteral("value") -> genZeroOf(ftpe) + js.StringLiteral("value") -> zero )) unnestPropertyName(name) { (newName, env0) => @@ -716,11 +723,11 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case newName: StringLiteral => makeObjectMethodApply("defineProperty", - List(js.This(), transformExpr(newName), descriptor)) + List(js.This(), transformExprNoChar(newName), descriptor)) case ComputedName(nameTree, _) => makeObjectMethodApply("defineProperty", - List(js.This(), transformExpr(nameTree), descriptor)) + List(js.This(), transformExprNoChar(nameTree), descriptor)) } } } @@ -731,7 +738,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case JSDelete(JSDotSelect(obj, prop)) => unnest(obj) { (newObj, env0) => implicit val env = env0 - js.Delete(js.DotSelect(transformExpr(newObj), + js.Delete(js.DotSelect(transformExprNoChar(newObj), transformPropIdent(prop))) } @@ -739,7 +746,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { unnest(obj, prop) { (newObj, newProp, env0) => implicit val env = env0 js.Delete(genBracketSelect( - transformExpr(newObj), transformExpr(newProp))) + transformExprNoChar(newObj), transformExprNoChar(newProp))) } // Treat 'return' as an LHS @@ -1206,7 +1213,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { }) case _ => - genLet(transformLocalVarIdent(ident), mutable, transformExpr(rhs)) + genLet(transformLocalVarIdent(ident), mutable, + transformExpr(rhs, tpe)) } } @@ -1243,7 +1251,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { }) case _ => - js.Assign(transformExpr(lhs), transformExpr(rhs)) + js.Assign(transformExpr(lhs, preserveChar = true), + transformExpr(rhs, lhs.tpe)) } } @@ -1325,13 +1334,13 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { lhs match { case Lhs.Discard => if (isSideEffectFreeExpression(rhs)) js.Skip() - else transformExpr(rhs) + else transformExpr(rhs, preserveChar = true) case Lhs.VarDef(name, tpe, mutable) => doVarDef(name, tpe, mutable, rhs) case Lhs.Assign(lhs) => doAssign(lhs, rhs) case Lhs.Return(None) => - js.Return(transformExpr(rhs)) + js.Return(transformExpr(rhs, env.expectedReturnType)) case Lhs.Return(Some(l)) => doReturnToLabel(l) } @@ -1389,7 +1398,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { unnest(cond) { (newCond, env0) => implicit val env = env0 extractLet { newLhs => - js.If(transformExpr(newCond), + js.If(transformExprNoChar(newCond), pushLhsInto(newLhs, thenp, tailPosLabels), pushLhsInto(newLhs, elsep, tailPosLabels)) } @@ -1412,7 +1421,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { // TODO Treat throw as an LHS? case Throw(expr) => unnest(expr) { (newExpr, env) => - js.Throw(transformExpr(newExpr)(env)) + js.Throw(transformExprNoChar(newExpr)(env)) } /** Matches are desugared into switches @@ -1433,7 +1442,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { val newCases = { for { (values, body) <- cases - newValues = (values map transformExpr) + newValues = values.map(transformExpr(_, preserveChar = true)) // add the break statement newBody = js.Block( pushLhsInto(newLhs, body, tailPosLabels), @@ -1445,7 +1454,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { } } val newDefault = pushLhsInto(newLhs, default, tailPosLabels) - js.Switch(transformExpr(newSelector), newCases, newDefault) + js.Switch(transformExpr(newSelector, preserveChar = true), + newCases, newDefault) } } @@ -1810,10 +1820,36 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { } } - // Desugar Scala operations to JavaScript operations ----------------------- + def transformExprNoChar(tree: Tree)(implicit env: Env): js.Tree = + transformExpr(tree, preserveChar = false) + + def transformExpr(tree: Tree, expectedType: Type)( + implicit env: Env): js.Tree = { + transformExpr(tree, preserveChar = expectedType == CharType) + } + + def transformTypedArgs(methodName: String, args: List[Tree])( + implicit env: Env): List[js.Tree] = { + if (args.forall(_.tpe != CharType)) { + // Fast path + args.map(transformExpr(_, preserveChar = true)) + } else { + /* TODO Optimize this. We don't really need to decode the full + * signature. We can simply walk the string and look for "__C__"'s, + * without allocating anything. + */ + val (_, paramTypeRefs, _) = Definitions.decodeMethodName(methodName) + args.zip(paramTypeRefs).map { + case (arg, ClassRef("C")) => transformExpr(arg, preserveChar = true) + case (arg, _) => transformExpr(arg, preserveChar = false) + } + } + } + + /** Desugar an expression of the IR into JavaScript. */ + def transformExpr(tree: Tree, preserveChar: Boolean)( + implicit env: Env): js.Tree = { - /** Desugar an expression of the IR into ES5 JS */ - def transformExpr(tree: Tree)(implicit env: Env): js.Tree = { import TreeDSL._ implicit val pos = tree.pos @@ -1821,27 +1857,30 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { def or0(tree: js.Tree): js.Tree = js.BinaryOp(JSBinaryOp.|, tree, js.IntLiteral(0)) - tree match { + val baseResult = tree match { // Control flow constructs case Block(stats :+ expr) => val (newStats, newEnv) = transformBlockStats(stats) - js.Block(newStats :+ transformExpr(expr)(newEnv)) + js.Block(newStats :+ transformExpr(expr, tree.tpe)(newEnv)) // Note that these work even if thenp/elsep is not a BooleanType case If(cond, BooleanLiteral(true), elsep) => - js.BinaryOp(JSBinaryOp.||, transformExpr(cond), transformExpr(elsep)) + js.BinaryOp(JSBinaryOp.||, transformExprNoChar(cond), + transformExpr(elsep, tree.tpe)) case If(cond, thenp, BooleanLiteral(false)) => - js.BinaryOp(JSBinaryOp.&&, transformExpr(cond), transformExpr(thenp)) + js.BinaryOp(JSBinaryOp.&&, transformExprNoChar(cond), + transformExpr(thenp, tree.tpe)) case If(cond, thenp, elsep) => - js.If(transformExpr(cond), transformExpr(thenp), transformExpr(elsep)) + js.If(transformExprNoChar(cond), transformExpr(thenp, tree.tpe), + transformExpr(elsep, tree.tpe)) // Scala expressions case New(cls, ctor, args) => val encodedClassVar = encodeClassVar(cls.className) - val newArgs = args.map(transformExpr) + val newArgs = transformTypedArgs(ctor.name, args) if (globalKnowledge.hasInlineableInit(cls.className)) { js.New(encodedClassVar, newArgs) } else { @@ -1859,14 +1898,14 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { js.VarRef(transformLocalVarIdent(name)) case Select(qualifier, item) => - transformExpr(qualifier) DOT transformPropIdent(item) + transformExprNoChar(qualifier) DOT transformPropIdent(item) case SelectStatic(cls, item) => genSelectStatic(cls.className, item) case Apply(receiver, method, args) => - val newReceiver = transformExpr(receiver) - val newArgs = args map transformExpr + val newReceiver = transformExprNoChar(receiver) + val newArgs = transformTypedArgs(method.name, args) /* If the receiver is maybe a hijacked class instance, and there * exists a hijacked method helper for the method, use it. Methods @@ -1884,7 +1923,9 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case ApplyStatically(receiver, cls, method, args) => val className = cls.className - val transformedArgs = (receiver :: args) map transformExpr + val newReceiver = transformExprNoChar(receiver) + val newArgs = transformTypedArgs(method.name, args) + val transformedArgs = newReceiver :: newArgs if (globalKnowledge.isInterface(className)) { val Ident(methodName, origName) = method @@ -1900,11 +1941,12 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case ApplyStatic(cls, method, args) => val Ident(methodName, origName) = method val fullName = cls.className + "__" + methodName - js.Apply(envField("s", fullName, origName), args map transformExpr) + js.Apply(envField("s", fullName, origName), + transformTypedArgs(method.name, args)) case UnaryOp(op, lhs) => import UnaryOp._ - val newLhs = transformExpr(lhs) + val newLhs = transformExpr(lhs, preserveChar = op == CharToInt) (op: @switch) match { case Boolean_! => js.UnaryOp(JSUnaryOp.!, newLhs) @@ -1940,8 +1982,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case BinaryOp(op, lhs, rhs) => import BinaryOp._ - val newLhs = transformExpr(lhs) - val newRhs = transformExpr(rhs) + val newLhs = transformExprNoChar(lhs) + val newRhs = transformExprNoChar(rhs) (op: @switch) match { case === | Int_== | Double_== | Boolean_== => @@ -2043,18 +2085,20 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case NewArray(tpe, lengths) => genCallHelper("newArrayObject", genClassDataOf(tpe.arrayTypeRef), - js.ArrayConstr(lengths.map(transformExpr))) + js.ArrayConstr(lengths.map(transformExprNoChar))) case ArrayValue(tpe, elems) => - genArrayValue(tpe, elems.map(transformExpr)) + val ArrayTypeRef(baseClassName, dimensions) = tpe.arrayTypeRef + val preserveChar = baseClassName == "C" && dimensions == 1 + genArrayValue(tpe, elems.map(transformExpr(_, preserveChar))) case ArrayLength(array) => - genIdentBracketSelect(js.DotSelect(transformExpr(array), + genIdentBracketSelect(js.DotSelect(transformExprNoChar(array), js.Ident("u")), "length") case ArraySelect(array, index) => - val newArray = transformExpr(array) - val newIndex = transformExpr(index) + val newArray = transformExprNoChar(array) + val newIndex = transformExprNoChar(index) semantics.arrayIndexOutOfBounds match { case CheckedBehavior.Compliant | CheckedBehavior.Fatal => js.Apply(js.DotSelect(newArray, js.Ident("get")), List(newIndex)) @@ -2063,19 +2107,20 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { } case IsInstanceOf(expr, cls) => - genIsInstanceOf(transformExpr(expr), cls) + genIsInstanceOf(transformExprNoChar(expr), cls) case AsInstanceOf(expr, cls) => - val newExpr = transformExpr(expr) + val newExpr = transformExprNoChar(expr) if (semantics.asInstanceOfs == Unchecked) newExpr else genAsInstanceOf(newExpr, cls) case Unbox(expr, charCode) => - val newExpr = transformExpr(expr) + val newExpr = transformExprNoChar(expr) if (semantics.asInstanceOfs == Unchecked) { (charCode: @switch) match { case 'Z' => !(!newExpr) + case 'C' => genCallHelper("uC", newExpr) case 'B' | 'S' | 'I' => or0(newExpr) case 'J' => genCallHelper("uJ", newExpr) case 'D' => js.UnaryOp(JSUnaryOp.+, newExpr) @@ -2091,7 +2136,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { } case GetClass(expr) => - genCallHelper("objectGetClass", transformExpr(expr)) + genCallHelper("objectGetClass", transformExprNoChar(expr)) case CallHelper(helper, args) => helper match { @@ -2100,29 +2145,31 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case ClassOf(tpe) => genClassDataOf(tpe) case jlClass => - js.DotSelect(transformExpr(jlClass), js.Ident("data$1")) + js.DotSelect(transformExprNoChar(jlClass), js.Ident("data$1")) } case "arrayDataOf" => - js.Apply(js.DotSelect(transformExpr(args.head), + js.Apply(js.DotSelect(transformExprNoChar(args.head), js.Ident("getArrayOf")), Nil) case "zeroOf" => js.DotSelect( - js.DotSelect(transformExpr(args.head), js.Ident("data$1")), + js.DotSelect(transformExprNoChar(args.head), js.Ident("data$1")), js.Ident("zero")) case _ => - genCallHelper(helper, args map transformExpr: _*) + genCallHelper(helper, + args.map(transformExpr(_, preserveChar = true)): _*) } // JavaScript expressions case JSNew(constr, args) => - js.New(transformExpr(constr), args map transformExpr) + js.New(transformExprNoChar(constr), args.map(transformExprNoChar)) case JSDotSelect(qualifier, item) => - js.DotSelect(transformExpr(qualifier), transformPropIdent(item)) + js.DotSelect(transformExprNoChar(qualifier), transformPropIdent(item)) case JSBracketSelect(qualifier, item) => - genBracketSelect(transformExpr(qualifier), transformExpr(item)) + genBracketSelect(transformExprNoChar(qualifier), + transformExprNoChar(item)) case JSFunctionApply(fun, args) => /* Protect the fun so that if it is, e.g., @@ -2139,7 +2186,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { * way, because calling a bare `eval` executes the code in the * current lexical scope, as opposed to the global scope. */ - val transformedFun = transformExpr(fun) + val transformedFun = transformExprNoChar(fun) val protectedFun = transformedFun match { case _:js.DotSelect | _:js.BracketSelect | js.VarRef(js.Ident("eval", _)) => @@ -2147,21 +2194,22 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case _ => transformedFun } - js.Apply(protectedFun, args map transformExpr) + js.Apply(protectedFun, args.map(transformExprNoChar)) case JSDotMethodApply(receiver, method, args) => js.Apply( - js.DotSelect(transformExpr(receiver), transformPropIdent(method)), - args map transformExpr) + js.DotSelect(transformExprNoChar(receiver), + transformPropIdent(method)), + args.map(transformExprNoChar)) case JSBracketMethodApply(receiver, method, args) => - js.Apply(genBracketSelect(transformExpr(receiver), - transformExpr(method)), args map transformExpr) + js.Apply(genBracketSelect(transformExprNoChar(receiver), + transformExprNoChar(method)), args.map(transformExprNoChar)) case JSSuperBracketSelect(cls, qualifier, item) => val ctor = extractWithGlobals(genRawJSClassConstructor(cls.className)) genCallHelper("superGet", ctor DOT "prototype", - transformExpr(qualifier), transformExpr(item)) + transformExprNoChar(qualifier), transformExprNoChar(item)) case LoadJSConstructor(cls) => extractWithGlobals(genRawJSClassConstructor(cls.className)) @@ -2180,20 +2228,20 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case JSSpread(items) => assert(outputMode == OutputMode.ECMAScript6) - js.Spread(transformExpr(items)) + js.Spread(transformExprNoChar(items)) case JSUnaryOp(op, lhs) => - js.UnaryOp(op, transformExpr(lhs)) + js.UnaryOp(op, transformExprNoChar(lhs)) case JSBinaryOp(op, lhs, rhs) => - js.BinaryOp(op, transformExpr(lhs), transformExpr(rhs)) + js.BinaryOp(op, transformExprNoChar(lhs), transformExprNoChar(rhs)) case JSArrayConstr(items) => - js.ArrayConstr(items map transformExpr) + js.ArrayConstr(items.map(transformExprNoChar)) case JSObjectConstr(fields) => js.ObjectConstr(fields map { case (name, value) => - (transformPropertyName(name), transformExpr(value)) + (transformPropertyName(name), transformExprNoChar(value)) }) case JSGlobalRef(name) => @@ -2241,7 +2289,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case Closure(captureParams, params, body, captureValues) => val innerFunction = desugarToFunctionInternal(params, body, isStat = false, - Env.empty.withParams(captureParams ++ params)) + Env.empty(AnyType).withParams(captureParams ++ params)) if (captureParams.isEmpty) { innerFunction @@ -2250,7 +2298,9 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { js.Function(captureParams.map(transformParamDef), { js.Return(innerFunction) }), - captureValues.map(transformExpr)) + captureValues.zip(captureParams).map { + case (value, param) => transformExpr(value, param.ptpe) + }) } // Invalid trees @@ -2260,14 +2310,19 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { "Invalid tree in JSDesugar.transformExpr() of class " + tree.getClass) } + + if (preserveChar || tree.tpe != CharType) + baseResult + else + genCallHelper("bC", baseResult) } def isMaybeHijackedClass(tpe: Type): Boolean = tpe match { case ClassType(cls) => Definitions.HijackedClasses.contains(cls) || Definitions.AncestorsOfHijackedClasses.contains(cls) - case AnyType | UndefType | BooleanType | ByteType | ShortType | IntType | - LongType | FloatType | DoubleType | StringType => + case AnyType | UndefType | BooleanType | CharType | ByteType | ShortType | + IntType | LongType | FloatType | DoubleType | StringType => true case _ => false @@ -2287,18 +2342,21 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { "charAt__I__C" -> "charSequenceCharAt", "subSequence__I__I__jl_CharSequence" -> "charSequenceSubSequence", - "compareTo__O__I" -> "comparableCompareTo", - "compareTo__jl_Boolean__I" -> "comparableCompareTo", - "compareTo__jl_Byte__I" -> "comparableCompareTo", - "compareTo__jl_Short__I" -> "comparableCompareTo", - "compareTo__jl_Integer__I" -> "comparableCompareTo", - "compareTo__jl_Long__I" -> "comparableCompareTo", - "compareTo__jl_Float__I" -> "comparableCompareTo", - "compareTo__jl_Double__I" -> "comparableCompareTo", - "compareTo__jl_String__I" -> "comparableCompareTo", + "compareTo__O__I" -> "comparableCompareTo", + "compareTo__jl_Boolean__I" -> "comparableCompareTo", + "compareTo__jl_Character__I" -> "comparableCompareTo", + "compareTo__jl_Byte__I" -> "comparableCompareTo", + "compareTo__jl_Short__I" -> "comparableCompareTo", + "compareTo__jl_Integer__I" -> "comparableCompareTo", + "compareTo__jl_Long__I" -> "comparableCompareTo", + "compareTo__jl_Float__I" -> "comparableCompareTo", + "compareTo__jl_Double__I" -> "comparableCompareTo", + "compareTo__jl_String__I" -> "comparableCompareTo", "booleanValue__Z" -> "booleanBooleanValue", + "charValue__C" -> "characterCharValue", + "byteValue__B" -> "numberByteValue", "shortValue__S" -> "numberShortValue", "intValue__I" -> "numberIntValue", @@ -2321,7 +2379,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { pName match { case name: Ident => transformPropIdent(name) case StringLiteral(s) => js.StringLiteral(s) - case ComputedName(tree, _) => js.ComputedName(transformExpr(tree)) + case ComputedName(tree, _) => js.ComputedName(transformExprNoChar(tree)) } } @@ -2408,6 +2466,7 @@ private object FunctionEmitter { final class Env private ( val thisIdent: Option[js.Ident], + val expectedReturnType: Type, val enclosingClassName: Option[String], vars: Map[String, Boolean], labeledExprLHSes: Map[String, Lhs], @@ -2445,16 +2504,18 @@ private object FunctionEmitter { private def copy( thisIdent: Option[js.Ident] = this.thisIdent, + expectedReturnType: Type = this.expectedReturnType, enclosingClassName: Option[String] = this.enclosingClassName, vars: Map[String, Boolean] = this.vars, labeledExprLHSes: Map[String, Lhs] = this.labeledExprLHSes, defaultBreakTargets: Set[String] = this.defaultBreakTargets): Env = { - new Env(thisIdent, enclosingClassName, vars, labeledExprLHSes, - defaultBreakTargets) + new Env(thisIdent, expectedReturnType, enclosingClassName, vars, + labeledExprLHSes, defaultBreakTargets) } } object Env { - def empty: Env = new Env(None, None, Map.empty, Map.empty, Set.empty) + def empty(expectedReturnType: Type): Env = + new Env(None, expectedReturnType, None, Map.empty, Map.empty, Set.empty) } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala index 39d57e98c0..959114a15e 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala @@ -108,23 +108,25 @@ private[emitter] final class JSGen(val semantics: Semantics, if (HijackedBoxedClasses.contains(className)) { if (test) { className match { - case BoxedUnitClass => expr === Undefined() - case BoxedBooleanClass => typeof(expr) === "boolean" - case BoxedByteClass => genCallHelper("isByte", expr) - case BoxedShortClass => genCallHelper("isShort", expr) - case BoxedIntegerClass => genCallHelper("isInt", expr) - case BoxedFloatClass => genCallHelper("isFloat", expr) - case BoxedDoubleClass => typeof(expr) === "number" + case BoxedUnitClass => expr === Undefined() + case BoxedBooleanClass => typeof(expr) === "boolean" + case BoxedCharacterClass => genCallHelper("isChar", expr) + case BoxedByteClass => genCallHelper("isByte", expr) + case BoxedShortClass => genCallHelper("isShort", expr) + case BoxedIntegerClass => genCallHelper("isInt", expr) + case BoxedFloatClass => genCallHelper("isFloat", expr) + case BoxedDoubleClass => typeof(expr) === "number" } } else { className match { - case BoxedUnitClass => genCallHelper("asUnit", expr) - case BoxedBooleanClass => genCallHelper("asBoolean", expr) - case BoxedByteClass => genCallHelper("asByte", expr) - case BoxedShortClass => genCallHelper("asShort", expr) - case BoxedIntegerClass => genCallHelper("asInt", expr) - case BoxedFloatClass => genCallHelper("asFloat", expr) - case BoxedDoubleClass => genCallHelper("asDouble", expr) + case BoxedUnitClass => genCallHelper("asUnit", expr) + case BoxedBooleanClass => genCallHelper("asBoolean", expr) + case BoxedCharacterClass => genCallHelper("asChar", expr) + case BoxedByteClass => genCallHelper("asByte", expr) + case BoxedShortClass => genCallHelper("asShort", expr) + case BoxedIntegerClass => genCallHelper("asInt", expr) + case BoxedFloatClass => genCallHelper("asFloat", expr) + case BoxedDoubleClass => genCallHelper("asDouble", expr) } } } else { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index 3ba4d2820b..dfe2be9a75 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -237,11 +237,7 @@ final class BaseLinker(config: CommonPhaseConfig) { val call = Apply(This()(currentClassType), targetIdent, params.map(_.ref))(targetMDef.resultType) - val body = if (targetName.endsWith("__C")) { - // A Char needs to be boxed - New(ClassType(Definitions.BoxedCharacterClass), - Ident("init___C"), List(call)) - } else if (targetName.endsWith("__V")) { + val body = if (targetName.endsWith("__V")) { // Materialize an `undefined` result for void methods Block(call, Undefined()) } else { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index ead3ea561e..a1de8d2505 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -1482,9 +1482,9 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { }) // Bridge method - case MaybeBox(Apply(This(), Ident(methodName, _), referenceArgs), boxID) => + case Apply(This(), Ident(methodName, _), referenceArgs) => impls.tail.forall(getMethodBody(_).body.get match { - case MaybeBox(Apply(This(), Ident(`methodName`, _), implArgs), `boxID`) => + case Apply(This(), Ident(`methodName`, _), implArgs) => referenceArgs.zip(implArgs) forall { case (MaybeUnbox(_, unboxID1), MaybeUnbox(_, unboxID2)) => unboxID1 == unboxID2 @@ -1506,6 +1506,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case AnyType => Definitions.ObjectClass case UndefType => Definitions.BoxedUnitClass case BooleanType => Definitions.BoxedBooleanClass + case CharType => Definitions.BoxedCharacterClass case ByteType => Definitions.BoxedByteClass case ShortType => Definitions.BoxedShortClass case IntType => Definitions.BoxedIntegerClass @@ -1782,13 +1783,11 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { } def isLocalOnlyInlineType(tpe: RefinedType): Boolean = { - /* java.lang.Character and RuntimeLong are @inline so that *local* - * box/unbox pairs and instances can be eliminated. But we don't want - * that to force inlining of a method only because we pass it a boxed - * Char or an instance of RuntimeLong. + /* RuntimeLong is @inline so that *local* box/unbox pairs and instances + * can be eliminated. But we don't want that to force inlining of a + * method only because we pass it an instance of RuntimeLong. */ tpe.base match { - case ClassType(Definitions.BoxedCharacterClass) => true case ClassType(LongImpl.RuntimeLongClass) => true case _ => false } @@ -1959,11 +1958,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { array.tpe match { case arrayTpe @ ArrayType(ArrayTypeRef(base, _)) => val elemType = cursoryArrayElemType(arrayTpe) - val select = ArraySelect(array, index)(elemType) - if (base == "C") - boxChar(select)(cont) - else - contTree(select) + contTree(ArraySelect(array, index)(elemType)) case _ => defaultApply("array$undapply__O__I__O", AnyType) @@ -1981,10 +1976,8 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { contTree(Assign(select, finishTransformExpr(tunboxedValue))) } base match { - case "Z" | "B" | "S" | "I" | "L" | "F" | "D" if depth == 1 => + case "Z" | "C" | "B" | "S" | "I" | "L" | "F" | "D" if depth == 1 => foldUnbox(tvalue, base.charAt(0))(cont1) - case "C" if depth == 1 => - unboxChar(tvalue)(cont1) case _ => cont1(tvalue) } @@ -2132,28 +2125,6 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { } } - private def boxChar(value: Tree)( - cont: PreTransCont)( - implicit scope: Scope, pos: Position): TailRec[Tree] = { - pretransformNew(AllocationSite.Tree(value), - ClassType(Definitions.BoxedCharacterClass), Ident("init___C"), - List(value.toPreTransform))(cont) - } - - private def unboxChar(tvalue: PreTransform)( - cont: PreTransCont)( - implicit scope: Scope, pos: Position): TailRec[Tree] = { - val BoxesRunTimeModuleClassName = "sr_BoxesRunTime$" - val treceiver = LoadModule( - ClassType(BoxesRunTimeModuleClassName)).toPreTransform - val target = staticCall(BoxesRunTimeModuleClassName, "unboxToChar__O__C").getOrElse { - throw new AssertionError("Cannot find method sr_BoxesRunTime$.unboxToChar__O__C") - } - val allocationSites = List(treceiver, tvalue).map(_.tpe.allocationSite) - inline(allocationSites, Some(treceiver), List(tvalue), target, - isStat = false, usePreTransform = true)(cont) - } - private def inlineClassConstructor(allocationSite: AllocationSite, cls: ClassType, initialValue: RecordValue, ctor: Ident, args: List[PreTransform], cancelFun: CancelFun)( @@ -3794,6 +3765,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { cont: PreTransCont): TailRec[Tree] = { (charCode: @switch) match { case 'Z' if arg.tpe.base == BooleanType => cont(arg) + case 'C' if arg.tpe.base == CharType => cont(arg) case 'B' if arg.tpe.base == ByteType => cont(arg) case 'S' if arg.tpe.base == ShortType => cont(arg) case 'I' if arg.tpe.base == IntType => cont(arg) @@ -4981,7 +4953,7 @@ private[optimizer] object OptimizerCore { } // Shape of bridges for generic methods - case MaybeBox(Apply(This(), method, args), _) => + case Apply(This(), method, args) => (args.size == params.size) && args.zip(params).forall { case (MaybeUnbox(VarRef(Ident(aname, _)), _), @@ -5018,25 +4990,12 @@ private[optimizer] object OptimizerCore { } } - private object MaybeBox { - def unapply(tree: Tree): Some[(Tree, Any)] = tree match { - case Apply(LoadModule(ClassType("sr_BoxesRunTime$")), - Ident("boxToCharacter__C__jl_Character", _), List(arg)) => - Some((arg, "C")) - case _ => - Some((tree, ())) - } - } - private object MaybeUnbox { def unapply(tree: Tree): Some[(Tree, Any)] = tree match { case AsInstanceOf(arg, tpe) => Some((arg, tpe)) case Unbox(arg, charCode) => Some((arg, charCode)) - case Apply(LoadModule(ClassType("sr_BoxesRunTime$")), - Ident("unboxToChar__O__C", _), List(arg)) => - Some((arg, "C")) case _ => Some((tree, ())) } From 159761e61c985a8ad59a623ae7a073c8fa91de8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 15 Aug 2017 12:53:46 +0200 Subject: [PATCH 0442/2665] Remove reflective call classes and handle everything in the compiler. The compiler already had to do some special-casing for primitives and hijacked classes in the codegen for reflective calls. For primitives, it relied on the presence of dedicated classes in the run-time library. Now, the compiler directly generates code for what used to be the body of the target method in reflective call class. This allows to entirely remove the reflective call classes from the library. --- .../org/scalajs/core/compiler/GenJSCode.scala | 199 ++++++++++++------ .../runtime/BooleanReflectiveCall.scala | 34 --- .../runtime/CharacterReflectiveCall.scala | 149 ------------- .../runtime/IntegerReflectiveCall.scala | 91 -------- .../scalajs/runtime/LongReflectiveCall.scala | 154 -------------- .../runtime/NumberReflectiveCall.scala | 166 --------------- .../compiler/ReflectiveCallTest.scala | 55 +++++ 7 files changed, 190 insertions(+), 658 deletions(-) delete mode 100644 library/src/main/scala/scala/scalajs/runtime/BooleanReflectiveCall.scala delete mode 100644 library/src/main/scala/scala/scalajs/runtime/CharacterReflectiveCall.scala delete mode 100644 library/src/main/scala/scala/scalajs/runtime/IntegerReflectiveCall.scala delete mode 100644 library/src/main/scala/scala/scalajs/runtime/LongReflectiveCall.scala delete mode 100644 library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 54eadfa0b9..58131594a0 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -3244,18 +3244,51 @@ abstract class GenJSCode extends plugins.PluginComponent fun.symbol.simpleName + ") " + " at: " + (tree.pos)) } - /** Gen JS code for a simple operation (arithmetic, logical, or comparison) */ - private def genSimpleOp(tree: Apply, args: List[Tree], code: Int): js.Tree = { + private def genPrimitiveOpForReflectiveCall(sym: Symbol, receiver: js.Tree, + args: List[js.Tree])( + implicit pos: Position): js.Tree = { + import scalaPrimitives._ + if (!isPrimitive(sym)) { + abort( + "Trying to reflectively call a method of a primitive type that " + + "is not itself a primitive method: " + sym.fullName + " at " + pos) + } + val code = getPrimitive(sym) + + if (isArithmeticOp(code) || isLogicalOp(code) || isComparisonOp(code)) { + genSimpleOp(sym.owner.tpe :: sym.tpe.paramTypes, sym.tpe.resultType, + receiver :: args, code) + } else if (code == CONCAT) { + js.BinaryOp(js.BinaryOp.String_+, receiver, args.head) + } else if (isCoercion(code)) { + adaptPrimitive(receiver, toIRType(sym.tpe.resultType)) + } else { + abort( + "Unknown primitive operation for reflective call: " + sym.fullName + + " at " + pos) + } + } + + /** Gen JS code for a simple operation (arithmetic, logical, or comparison) */ + private def genSimpleOp(tree: Apply, args: List[Tree], code: Int): js.Tree = { implicit val pos = tree.pos - val sources = args.map(genExpr) + genSimpleOp(args.map(_.tpe), tree.tpe, args.map(genExpr), code) + } + + /** Gen JS code for a simple operation (arithmetic, logical, or comparison) */ + private def genSimpleOp(argTpes: List[Type], resultTpe: Type, + sources: List[js.Tree], code: Int)( + implicit pos: Position): js.Tree = { + + import scalaPrimitives._ sources match { // Unary operation case List(src_in) => - val opType = toIRType(tree.tpe) + val opType = toIRType(resultTpe) val src = adaptPrimitive(src_in, opType) (code match { @@ -3290,8 +3323,8 @@ abstract class GenJSCode extends plugins.PluginComponent import js.BinaryOp._ val isShift = isShiftOp(code) - val leftKind = toTypeKind(args(0).tpe) - val rightKind = toTypeKind(args(1).tpe) + val leftKind = toTypeKind(argTpes(0)) + val rightKind = toTypeKind(argTpes(1)) val opType = { if (isShift) { @@ -3426,7 +3459,7 @@ abstract class GenJSCode extends plugins.PluginComponent !rsrc.isInstanceOf[js.Null] && // Arrays, Null, Nothing do not have an equals() method leftKind.isInstanceOf[REFERENCE]) { - val body = genEqEqPrimitive(args(0).tpe, args(1).tpe, lsrc, rsrc) + val body = genEqEqPrimitive(argTpes(0), argTpes(1), lsrc, rsrc) if (not) js.UnaryOp(js.UnaryOp.Boolean_!, body) else body } else { js.BinaryOp( @@ -3444,7 +3477,7 @@ abstract class GenJSCode extends plugins.PluginComponent } case _ => - abort("Too many arguments for primitive function: " + tree) + abort("Too many arguments for primitive function at " + pos) } } @@ -3740,6 +3773,13 @@ abstract class GenJSCode extends plugins.PluginComponent genApplyMethod(callTrg, proxyIdent, arguments, jstpe.AnyType) if (!isAnyRefPrimitive) { + def boxIfNeeded(call: js.Tree, returnType: Type): js.Tree = { + if (isPrimitiveValueType(returnType)) + makePrimitiveBox(call, returnType) + else + call + } + if (isArrayLikeOp) { def genRTCall(method: Symbol, args: js.Tree*) = genApplyMethod(genLoadModule(ScalaRunTimeModule), @@ -3766,69 +3806,100 @@ abstract class GenJSCode extends plugins.PluginComponent })(jstpe.AnyType) } - for { - (rtClass, reflBoxClass) <- Seq( - (StringClass, StringClass), - (BoxedDoubleClass, NumberReflectiveCallClass), - (BoxedBooleanClass, BooleanReflectiveCallClass), - (BoxedCharacterClass, CharacterReflectiveCallClass), - (BoxedLongClass, LongReflectiveCallClass) - ) - implMethodSym = matchingSymIn(reflBoxClass) - if implMethodSym != NoSymbol && implMethodSym.isPublic - } { - callStatement = js.If(genIsInstanceOf(callTrg, rtClass.tpe), { - if (implMethodSym.owner == ObjectClass) { + /* Look for a matching method in String. If we find one, we must + * redirect it to RuntimeString. + */ + val methodInStringClass = matchingSymIn(StringClass) + if (methodInStringClass != NoSymbol && methodInStringClass.isPublic) { + callStatement = js.If(genIsInstanceOf(callTrg, StringClass.tpe), { + if (methodInStringClass.owner == ObjectClass) { // If the method is defined on Object, we can call it normally. - genApplyMethod(callTrg, implMethodSym, arguments) + genApplyMethod(callTrg, methodInStringClass, arguments) } else { - if (rtClass == StringClass) { - val (rtModuleClass, methodIdent) = - encodeRTStringMethodSym(implMethodSym) - val retTpe = implMethodSym.tpe.resultType - val castCallTrg = fromAny(callTrg, StringClass.toTypeConstructor) - val rawApply = genApplyMethod( - genLoadModule(rtModuleClass), - methodIdent, - castCallTrg :: arguments, - toIRType(retTpe)) - // Box the result of the implementing method if required - if (isPrimitiveValueType(retTpe)) - makePrimitiveBox(rawApply, retTpe) - else - rawApply - } else { - val reflBoxClassPatched = { - def isIntOrLongKind(kind: TypeKind) = kind match { - case CharKind => false - case _:INT | LONG => true - case _ => false - } - if (rtClass == BoxedDoubleClass && - toTypeKind(implMethodSym.tpe.resultType) == DoubleKind && - isIntOrLongKind(toTypeKind(sym.tpe.resultType))) { - // This must be an Int, and not a Double - IntegerReflectiveCallClass - } else { - reflBoxClass - } - } - val castCallTrg = - fromAny(callTrg, - reflBoxClassPatched.primaryConstructor.tpe.params.head.tpe) - val reflBox = genNew(reflBoxClassPatched, - reflBoxClassPatched.primaryConstructor, List(castCallTrg)) - genApplyMethod( - reflBox, - proxyIdent, - arguments, - jstpe.AnyType) - } + // Otherwise, we need to call it on RuntimeString + val (rtModuleClass, methodIdent) = + encodeRTStringMethodSym(methodInStringClass) + val retTpe = methodInStringClass.tpe.resultType + val castCallTrg = fromAny(callTrg, StringClass.toTypeConstructor) + boxIfNeeded( + genApplyMethod( + genLoadModule(rtModuleClass), + methodIdent, + castCallTrg :: arguments, + toIRType(retTpe)), + retTpe) } }, { // else callStatement })(jstpe.AnyType) } + + /* For primitive types, we need to handle two cases. The method could + * either be defined in the boxed class of the primitive type, or it + * could be defined in the primitive class itself. In the former case, + * we generate a direct call to the actual (hijacked) method. In the + * latter case, we directly generate the primitive operation. + */ + + def addCallForPrimitive(primitiveClass: Symbol): Boolean = { + val boxedClass = definitions.boxedClass(primitiveClass) + val boxedTpe = boxedClass.tpe + val methodInBoxedClass = matchingSymIn(boxedClass) + if (methodInBoxedClass != NoSymbol && methodInBoxedClass.isPublic) { + callStatement = js.If(genIsInstanceOf(callTrg, boxedTpe), { + boxIfNeeded( + genApplyMethod( + genAsInstanceOf(callTrg, boxedTpe), + methodInBoxedClass, + arguments), + methodInBoxedClass.tpe.resultType) + }, { // else + callStatement + })(jstpe.AnyType) + true + } else { + val methodInPrimClass = matchingSymIn(primitiveClass) + if (methodInPrimClass != NoSymbol && methodInPrimClass.isPublic) { + def isIntOrLongKind(kind: TypeKind) = kind match { + case CharKind => false + case _:INT | LONG => true + case _ => false + } + val ignoreBecauseItMustBeAnInt = { + primitiveClass == DoubleClass && + toTypeKind(methodInPrimClass.tpe.resultType) == DoubleKind && + isIntOrLongKind(toTypeKind(sym.tpe.resultType)) + } + if (ignoreBecauseItMustBeAnInt) { + // Fall through to the Int case that will come next + false + } else { + callStatement = js.If(genIsInstanceOf(callTrg, boxedTpe), { + val castCallTrg = + makePrimitiveUnbox(callTrg, primitiveClass.tpe) + val call = genPrimitiveOpForReflectiveCall(methodInPrimClass, + castCallTrg, arguments) + boxIfNeeded(call, methodInPrimClass.tpe.resultType) + }, { // else + callStatement + })(jstpe.AnyType) + true + } + } else { + false + } + } + } + + addCallForPrimitive(BooleanClass) + addCallForPrimitive(LongClass) + addCallForPrimitive(CharClass) + + /* For primitive numeric types that box as JS numbers, find the first + * one that matches. It will be able to handle the subsequent cases. + */ + Seq(DoubleClass, IntClass, FloatClass, ShortClass, ByteClass).find( + addCallForPrimitive) } js.Block(callTrgVarDef, callStatement) diff --git a/library/src/main/scala/scala/scalajs/runtime/BooleanReflectiveCall.scala b/library/src/main/scala/scala/scalajs/runtime/BooleanReflectiveCall.scala deleted file mode 100644 index f9f65c0f14..0000000000 --- a/library/src/main/scala/scala/scalajs/runtime/BooleanReflectiveCall.scala +++ /dev/null @@ -1,34 +0,0 @@ -package scala.scalajs.runtime - -import java.lang.{Boolean => JBoolean} - -/** Explicit box for boolean values when doing a reflective call. - * This class and its methods are only here to properly support reflective - * calls on booleans. - */ -final class BooleanReflectiveCall(value: Boolean) { - - // Methods of java.lang.Boolean - - def booleanValue(): Boolean = value - - def compareTo(that: JBoolean): Int = - new JBoolean(value).compareTo(that) - def compareTo(that: AnyRef): Int = - new JBoolean(value).compareTo(that.asInstanceOf[JBoolean]) - - // Methods of scala.Boolean - - // scalastyle:off disallow.space.before.token - def unary_! : Boolean = !value - // scalastyle:on disallow.space.before.token - - def ==(x: Boolean): Boolean = value == x - def !=(x: Boolean): Boolean = value != x - def ||(x: Boolean): Boolean = value || x - def &&(x: Boolean): Boolean = value && x - def |(x: Boolean): Boolean = value | x - def &(x: Boolean): Boolean = value & x - def ^(x: Boolean): Boolean = value ^ x - -} diff --git a/library/src/main/scala/scala/scalajs/runtime/CharacterReflectiveCall.scala b/library/src/main/scala/scala/scalajs/runtime/CharacterReflectiveCall.scala deleted file mode 100644 index fbbf661c73..0000000000 --- a/library/src/main/scala/scala/scalajs/runtime/CharacterReflectiveCall.scala +++ /dev/null @@ -1,149 +0,0 @@ -package scala.scalajs.runtime - -/** Explicit box for char values when doing a reflective call. - * This class and its methods are only here to properly support reflective - * calls on characters. - */ -final class CharacterReflectiveCall(value: Char) { - - // Methods of java.lang.Character - - def charValue(): Char = value - - def compareTo(that: Character): Int = - new Character(value).compareTo(that) - def compareTo(that: AnyRef): Int = - new Character(value).compareTo(that.asInstanceOf[Character]) - - // Methods of Char - - def toByte: Byte = value.toByte - def toShort: Short = value.toShort - def toChar: Char = value.toChar - def toInt: Int = value - def toLong: Long = value.toLong - def toFloat: Float = value.toFloat - def toDouble: Double = value.toDouble - - // scalastyle:off disallow.space.before.token - def unary_~ : Int = ~value - def unary_+ : Int = value - def unary_- : Int = -value - // scalastyle:on disallow.space.before.token - - def +(x: String): String = value + x - - def <<(x: Int): Int = value << x - def <<(x: Long): Int = value << x - def >>>(x: Int): Int = value >>> x - def >>>(x: Long): Int = value >>> x - def >>(x: Int): Int = value >> x - def >>(x: Long): Int = value >> x - - def ==(x: Byte): Boolean = value == x - def ==(x: Short): Boolean = value == x - def ==(x: Char): Boolean = value == x - def ==(x: Int): Boolean = value == x - def ==(x: Long): Boolean = value == x - def ==(x: Float): Boolean = value == x - def ==(x: Double): Boolean = value == x - - def !=(x: Byte): Boolean = value != x - def !=(x: Short): Boolean = value != x - def !=(x: Char): Boolean = value != x - def !=(x: Int): Boolean = value != x - def !=(x: Long): Boolean = value != x - def !=(x: Float): Boolean = value != x - def !=(x: Double): Boolean = value != x - - def <(x: Byte): Boolean = value < x - def <(x: Short): Boolean = value < x - def <(x: Char): Boolean = value < x - def <(x: Int): Boolean = value < x - def <(x: Long): Boolean = value < x - def <(x: Float): Boolean = value < x - def <(x: Double): Boolean = value < x - - def <=(x: Byte): Boolean = value <= x - def <=(x: Short): Boolean = value <= x - def <=(x: Char): Boolean = value <= x - def <=(x: Int): Boolean = value <= x - def <=(x: Long): Boolean = value <= x - def <=(x: Float): Boolean = value <= x - def <=(x: Double): Boolean = value <= x - - def >(x: Byte): Boolean = value > x - def >(x: Short): Boolean = value > x - def >(x: Char): Boolean = value > x - def >(x: Int): Boolean = value > x - def >(x: Long): Boolean = value > x - def >(x: Float): Boolean = value > x - def >(x: Double): Boolean = value > x - - def >=(x: Byte): Boolean = value >= x - def >=(x: Short): Boolean = value >= x - def >=(x: Char): Boolean = value >= x - def >=(x: Int): Boolean = value >= x - def >=(x: Long): Boolean = value >= x - def >=(x: Float): Boolean = value >= x - def >=(x: Double): Boolean = value >= x - - def |(x: Byte): Int = value | x - def |(x: Short): Int = value | x - def |(x: Char): Int = value | x - def |(x: Int): Int = value | x - def |(x: Long): Long = value | x - - def &(x: Byte): Int = value & x - def &(x: Short): Int = value & x - def &(x: Char): Int = value & x - def &(x: Int): Int = value & x - def &(x: Long): Long = value & x - - def ^(x: Byte): Int = value ^ x - def ^(x: Short): Int = value ^ x - def ^(x: Char): Int = value ^ x - def ^(x: Int): Int = value ^ x - def ^(x: Long): Long = value ^ x - - def +(x: Byte): Int = value + x - def +(x: Short): Int = value + x - def +(x: Char): Int = value + x - def +(x: Int): Int = value + x - def +(x: Long): Long = value + x - def +(x: Float): Float = value + x - def +(x: Double): Double = value + x - - def -(x: Byte): Int = value - x - def -(x: Short): Int = value - x - def -(x: Char): Int = value - x - def -(x: Int): Int = value - x - def -(x: Long): Long = value - x - def -(x: Float): Float = value - x - def -(x: Double): Double = value - x - - def *(x: Byte): Int = value * x - def *(x: Short): Int = value * x - def *(x: Char): Int = value * x - def *(x: Int): Int = value * x - def *(x: Long): Long = value * x - def *(x: Float): Float = value * x - def *(x: Double): Double = value * x - - def /(x: Byte): Int = value / x - def /(x: Short): Int = value / x - def /(x: Char): Int = value / x - def /(x: Int): Int = value / x - def /(x: Long): Long = value / x - def /(x: Float): Float = value / x - def /(x: Double): Double = value / x - - def %(x: Byte): Int = value % x - def %(x: Short): Int = value % x - def %(x: Char): Int = value % x - def %(x: Int): Int = value % x - def %(x: Long): Long = value % x - def %(x: Float): Float = value % x - def %(x: Double): Double = value % x - -} diff --git a/library/src/main/scala/scala/scalajs/runtime/IntegerReflectiveCall.scala b/library/src/main/scala/scala/scalajs/runtime/IntegerReflectiveCall.scala deleted file mode 100644 index 93319b5835..0000000000 --- a/library/src/main/scala/scala/scalajs/runtime/IntegerReflectiveCall.scala +++ /dev/null @@ -1,91 +0,0 @@ -package scala.scalajs.runtime - -import java.lang.{Double => JDouble, Integer => JInteger} - -/** Explicit box for number values when doing a reflective call that was - * identified to be a call on Int rather than on Double (based on the - * result type of the method called reflectively). - * This class and its methods are only here to properly support reflective - * calls on numbers. - */ -final class IntegerReflectiveCall(value: Int) { - - // Methods of scala.Int whose result type is different than in scala.Double - - // scalastyle:off disallow.space.before.token - def unary_+ : scala.Int = value - def unary_- : scala.Int = -value - // scalastyle:on disallow.space.before.token - - def +(x: scala.Byte): scala.Int = value + x - def +(x: scala.Short): scala.Int = value + x - def +(x: scala.Char): scala.Int = value + x - def +(x: scala.Int): scala.Int = value + x - def +(x: scala.Long): scala.Long = value + x - def +(x: scala.Float): scala.Float = value + x - def +(x: scala.Double): scala.Double = value + x - - def -(x: scala.Byte): scala.Int = value - x - def -(x: scala.Short): scala.Int = value - x - def -(x: scala.Char): scala.Int = value - x - def -(x: scala.Int): scala.Int = value - x - def -(x: scala.Long): scala.Long = value - x - def -(x: scala.Float): scala.Float = value - x - def -(x: scala.Double): scala.Double = value - x - - def *(x: scala.Byte): scala.Int = value * x - def *(x: scala.Short): scala.Int = value * x - def *(x: scala.Char): scala.Int = value * x - def *(x: scala.Int): scala.Int = value * x - def *(x: scala.Long): scala.Long = value * x - def *(x: scala.Float): scala.Float = value * x - def *(x: scala.Double): scala.Double = value * x - - def /(x: scala.Byte): scala.Int = value / x - def /(x: scala.Short): scala.Int = value / x - def /(x: scala.Char): scala.Int = value / x - def /(x: scala.Int): scala.Int = value / x - def /(x: scala.Long): scala.Long = value / x - def /(x: scala.Float): scala.Float = value / x - def /(x: scala.Double): scala.Double = value / x - - def %(x: scala.Byte): scala.Int = value % x - def %(x: scala.Short): scala.Int = value % x - def %(x: scala.Char): scala.Int = value % x - def %(x: scala.Int): scala.Int = value % x - def %(x: scala.Long): scala.Long = value % x - def %(x: scala.Float): scala.Float = value % x - def %(x: scala.Double): scala.Double = value % x - - // Methods of scala.Int that are not defined on scala.Double - - // scalastyle:off disallow.space.before.token - def unary_~ : scala.Int = ~value - // scalastyle:on disallow.space.before.token - - def <<(x: scala.Int): scala.Int = value << x - def <<(x: scala.Long): scala.Int = value << x - def >>>(x: scala.Int): scala.Int = value >>> x - def >>>(x: scala.Long): scala.Int = value >>> x - def >>(x: scala.Int): scala.Int = value >> x - def >>(x: scala.Long): scala.Int = value >> x - - def |(x: scala.Byte): scala.Int = value | x - def |(x: scala.Short): scala.Int = value | x - def |(x: scala.Char): scala.Int = value | x - def |(x: scala.Int): scala.Int = value | x - def |(x: scala.Long): scala.Long = value | x - - def &(x: scala.Byte): scala.Int = value & x - def &(x: scala.Short): scala.Int = value & x - def &(x: scala.Char): scala.Int = value & x - def &(x: scala.Int): scala.Int = value & x - def &(x: scala.Long): scala.Long = value & x - - def ^(x: scala.Byte): scala.Int = value ^ x - def ^(x: scala.Short): scala.Int = value ^ x - def ^(x: scala.Char): scala.Int = value ^ x - def ^(x: scala.Int): scala.Int = value ^ x - def ^(x: scala.Long): scala.Long = value ^ x - -} diff --git a/library/src/main/scala/scala/scalajs/runtime/LongReflectiveCall.scala b/library/src/main/scala/scala/scalajs/runtime/LongReflectiveCall.scala deleted file mode 100644 index 9f63c875c9..0000000000 --- a/library/src/main/scala/scala/scalajs/runtime/LongReflectiveCall.scala +++ /dev/null @@ -1,154 +0,0 @@ -package scala.scalajs.runtime - -import java.lang.{Long => JLong} - -/** Explicit box for longs when doing a reflective call. - * This class and its methods are only here to properly support reflective - * calls on longs. - */ -final class LongReflectiveCall(value: Long) { - - // Methods of java.lang.Long - - def byteValue(): Byte = value.toByte - def shortValue(): Short = value.toShort - def intValue(): Int = value.toInt - def longValue(): Long = value - def floatValue(): Float = value.toFloat - def doubleValue(): Double = value.toDouble - - def compareTo(that: JLong): Int = - new JLong(value).compareTo(that) - def compareTo(that: AnyRef): Int = - new JLong(value).compareTo(that.asInstanceOf[JLong]) - - // Methods of scala.Long - - def toByte: Byte = value.toByte - def toShort: Short = value.toShort - def toChar: Char = value.toChar - def toInt: Int = value.toInt - def toLong: Long = value - def toFloat: Float = value.toFloat - def toDouble: Double = value.toDouble - - // scalastyle:off disallow.space.before.token - def unary_~ : Long = ~value - def unary_+ : Long = value - def unary_- : Long = -value - // scalastyle:on disallow.space.before.token - - def <<(y: Int): Long = value << y - def <<(y: Long): Long = value << y - def >>>(y: Int): Long = value >>> y - def >>>(y: Long): Long = value >>> y - def >>(y: Int): Long = value >> y - def >>(y: Long): Long = value >> y - - def ==(y: Byte): Boolean = value == y - def ==(y: Short): Boolean = value == y - def ==(y: Char): Boolean = value == y - def ==(y: Int): Boolean = value == y - def ==(y: Long): Boolean = value == y - def ==(y: Float): Boolean = value == y - def ==(y: Double): Boolean = value == y - - def !=(y: Byte): Boolean = value != y - def !=(y: Short): Boolean = value != y - def !=(y: Char): Boolean = value != y - def !=(y: Int): Boolean = value != y - def !=(y: Long): Boolean = value != y - def !=(y: Float): Boolean = value != y - def !=(y: Double): Boolean = value != y - - def <(y: Byte): Boolean = value < y - def <(y: Short): Boolean = value < y - def <(y: Char): Boolean = value < y - def <(y: Int): Boolean = value < y - def <(y: Long): Boolean = value < y - def <(y: Float): Boolean = value < y - def <(y: Double): Boolean = value < y - - def <=(y: Byte): Boolean = value <= y - def <=(y: Short): Boolean = value <= y - def <=(y: Char): Boolean = value <= y - def <=(y: Int): Boolean = value <= y - def <=(y: Long): Boolean = value <= y - def <=(y: Float): Boolean = value <= y - def <=(y: Double): Boolean = value <= y - - def >(y: Byte): Boolean = value > y - def >(y: Short): Boolean = value > y - def >(y: Char): Boolean = value > y - def >(y: Int): Boolean = value > y - def >(y: Long): Boolean = value > y - def >(y: Float): Boolean = value > y - def >(y: Double): Boolean = value > y - - def >=(y: Byte): Boolean = value >= y - def >=(y: Short): Boolean = value >= y - def >=(y: Char): Boolean = value >= y - def >=(y: Int): Boolean = value >= y - def >=(y: Long): Boolean = value >= y - def >=(y: Float): Boolean = value >= y - def >=(y: Double): Boolean = value >= y - - def |(y: Byte): Long = value | y - def |(y: Short): Long = value | y - def |(y: Char): Long = value | y - def |(y: Int): Long = value | y - def |(y: Long): Long = value | y - - def &(y: Byte): Long = value & y - def &(y: Short): Long = value & y - def &(y: Char): Long = value & y - def &(y: Int): Long = value & y - def &(y: Long): Long = value & y - - def ^(y: Byte): Long = value ^ y - def ^(y: Short): Long = value ^ y - def ^(y: Char): Long = value ^ y - def ^(y: Int): Long = value ^ y - def ^(y: Long): Long = value ^ y - - def +(y: Byte): Long = value + y - def +(y: Short): Long = value + y - def +(y: Char): Long = value + y - def +(y: Int): Long = value + y - def +(y: Long): Long = value + y - def +(y: Float): Float = value + y - def +(y: Double): Double = value + y - - def -(y: Byte): Long = value - y - def -(y: Short): Long = value - y - def -(y: Char): Long = value - y - def -(y: Int): Long = value - y - def -(y: Long): Long = value - y - def -(y: Float): Float = value - y - def -(y: Double): Double = value - y - - def *(y: Byte): Long = value - y - def *(y: Short): Long = value - y - def *(y: Char): Long = value - y - def *(y: Int): Long = value - y - def *(y: Long): Long = value - y - def *(y: Float): Float = value - y - def *(y: Double): Double = value - y - - def /(y: Byte): Long = value / y - def /(y: Short): Long = value / y - def /(y: Char): Long = value / y - def /(y: Int): Long = value / y - def /(y: Long): Long = value / y - def /(y: Float): Float = value / y - def /(y: Double): Double = value / y - - def %(y: Byte): Long = value % y - def %(y: Short): Long = value % y - def %(y: Char): Long = value % y - def %(y: Int): Long = value % y - def %(y: Long): Long = value % y - def %(y: Float): Float = value % y - def %(y: Double): Double = value % y - -} diff --git a/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala b/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala deleted file mode 100644 index 24a90bf8bc..0000000000 --- a/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala +++ /dev/null @@ -1,166 +0,0 @@ -package scala.scalajs.runtime - -import java.lang.{Double => JDouble, Integer => JInteger} - -/** Explicit box for number values when doing a reflective call. - * This class and its methods are only here to properly support reflective - * calls on numbers. - */ -final class NumberReflectiveCall(value: Double) { - - // Methods of java.lang.Double and java.lang.Integer - - def byteValue(): Byte = value.toByte - def shortValue(): Short = value.toShort - def intValue(): Int = value.toInt - def longValue(): scala.Long = value.toLong - def floatValue(): Float = value.toFloat - def doubleValue(): Double = value - - def compareTo(that: JDouble): Int = - new JDouble(value).compareTo(that) - def compareTo(that: JInteger): Int = - new JDouble(value).compareTo(new JDouble(that.doubleValue())) - def compareTo(that: AnyRef): Int = - new JDouble(value).compareTo(that.asInstanceOf[JDouble]) - - def isNaN(): scala.Boolean = new JDouble(value).isNaN() - def isInfinite(): scala.Boolean = new JDouble(value).isInfinite() - - // Methods of scala.Double - - def toByte: scala.Byte = value.toByte - def toShort: scala.Short = value.toShort - def toChar: scala.Char = value.toChar - def toInt: scala.Int = value.toInt - def toLong: scala.Long = value.toLong - def toFloat: scala.Float = value.toFloat - def toDouble: scala.Double = value - - // scalastyle:off disallow.space.before.token - def unary_+ : scala.Double = value - def unary_- : scala.Double = -value - // scalastyle:on disallow.space.before.token - - def +(x: String): String = value + x - - def ==(x: scala.Byte): scala.Boolean = value == x - def ==(x: scala.Short): scala.Boolean = value == x - def ==(x: scala.Char): scala.Boolean = value == x - def ==(x: scala.Int): scala.Boolean = value == x - def ==(x: scala.Long): scala.Boolean = value == x - def ==(x: scala.Float): scala.Boolean = value == x - def ==(x: scala.Double): scala.Boolean = value == x - - def !=(x: scala.Byte): scala.Boolean = value != x - def !=(x: scala.Short): scala.Boolean = value != x - def !=(x: scala.Char): scala.Boolean = value != x - def !=(x: scala.Int): scala.Boolean = value != x - def !=(x: scala.Long): scala.Boolean = value != x - def !=(x: scala.Float): scala.Boolean = value != x - def !=(x: scala.Double): scala.Boolean = value != x - - def <(x: scala.Byte): scala.Boolean = value < x - def <(x: scala.Short): scala.Boolean = value < x - def <(x: scala.Char): scala.Boolean = value < x - def <(x: scala.Int): scala.Boolean = value < x - def <(x: scala.Long): scala.Boolean = value < x - def <(x: scala.Float): scala.Boolean = value < x - def <(x: scala.Double): scala.Boolean = value < x - - def <=(x: scala.Byte): scala.Boolean = value <= x - def <=(x: scala.Short): scala.Boolean = value <= x - def <=(x: scala.Char): scala.Boolean = value <= x - def <=(x: scala.Int): scala.Boolean = value <= x - def <=(x: scala.Long): scala.Boolean = value <= x - def <=(x: scala.Float): scala.Boolean = value <= x - def <=(x: scala.Double): scala.Boolean = value <= x - - def >(x: scala.Byte): scala.Boolean = value > x - def >(x: scala.Short): scala.Boolean = value > x - def >(x: scala.Char): scala.Boolean = value > x - def >(x: scala.Int): scala.Boolean = value > x - def >(x: scala.Long): scala.Boolean = value > x - def >(x: scala.Float): scala.Boolean = value > x - def >(x: scala.Double): scala.Boolean = value > x - - def >=(x: scala.Byte): scala.Boolean = value >= x - def >=(x: scala.Short): scala.Boolean = value >= x - def >=(x: scala.Char): scala.Boolean = value >= x - def >=(x: scala.Int): scala.Boolean = value >= x - def >=(x: scala.Long): scala.Boolean = value >= x - def >=(x: scala.Float): scala.Boolean = value >= x - def >=(x: scala.Double): scala.Boolean = value >= x - - def +(x: scala.Byte): scala.Double = value + x - def +(x: scala.Short): scala.Double = value + x - def +(x: scala.Char): scala.Double = value + x - def +(x: scala.Int): scala.Double = value + x - def +(x: scala.Long): scala.Double = value + x - def +(x: scala.Float): scala.Double = value + x - def +(x: scala.Double): scala.Double = value + x - - def -(x: scala.Byte): scala.Double = value - x - def -(x: scala.Short): scala.Double = value - x - def -(x: scala.Char): scala.Double = value - x - def -(x: scala.Int): scala.Double = value - x - def -(x: scala.Long): scala.Double = value - x - def -(x: scala.Float): scala.Double = value - x - def -(x: scala.Double): scala.Double = value - x - - def *(x: scala.Byte): scala.Double = value * x - def *(x: scala.Short): scala.Double = value * x - def *(x: scala.Char): scala.Double = value * x - def *(x: scala.Int): scala.Double = value * x - def *(x: scala.Long): scala.Double = value * x - def *(x: scala.Float): scala.Double = value * x - def *(x: scala.Double): scala.Double = value * x - - def /(x: scala.Byte): scala.Double = value / x - def /(x: scala.Short): scala.Double = value / x - def /(x: scala.Char): scala.Double = value / x - def /(x: scala.Int): scala.Double = value / x - def /(x: scala.Long): scala.Double = value / x - def /(x: scala.Float): scala.Double = value / x - def /(x: scala.Double): scala.Double = value / x - - def %(x: scala.Byte): scala.Double = value % x - def %(x: scala.Short): scala.Double = value % x - def %(x: scala.Char): scala.Double = value % x - def %(x: scala.Int): scala.Double = value % x - def %(x: scala.Long): scala.Double = value % x - def %(x: scala.Float): scala.Double = value % x - def %(x: scala.Double): scala.Double = value % x - - // Methods of scala.Int that are not defined on scala.Double - - // scalastyle:off disallow.space.before.token - def unary_~ : scala.Int = ~value.toInt - // scalastyle:on disallow.space.before.token - - def <<(x: scala.Int): scala.Int = value.toInt << x - def <<(x: scala.Long): scala.Int = value.toInt << x - def >>>(x: scala.Int): scala.Int = value.toInt >>> x - def >>>(x: scala.Long): scala.Int = value.toInt >>> x - def >>(x: scala.Int): scala.Int = value.toInt >> x - def >>(x: scala.Long): scala.Int = value.toInt >> x - - def |(x: scala.Byte): scala.Int = value.toInt | x - def |(x: scala.Short): scala.Int = value.toInt | x - def |(x: scala.Char): scala.Int = value.toInt | x - def |(x: scala.Int): scala.Int = value.toInt | x - def |(x: scala.Long): scala.Long = value.toInt | x - - def &(x: scala.Byte): scala.Int = value.toInt & x - def &(x: scala.Short): scala.Int = value.toInt & x - def &(x: scala.Char): scala.Int = value.toInt & x - def &(x: scala.Int): scala.Int = value.toInt & x - def &(x: scala.Long): scala.Long = value.toInt & x - - def ^(x: scala.Byte): scala.Int = value.toInt ^ x - def ^(x: scala.Short): scala.Int = value.toInt ^ x - def ^(x: scala.Char): scala.Int = value.toInt ^ x - def ^(x: scala.Int): scala.Int = value.toInt ^ x - def ^(x: scala.Long): scala.Long = value.toInt ^ x - -} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ReflectiveCallTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ReflectiveCallTest.scala index 580a19c54d..4f87a8f975 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ReflectiveCallTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ReflectiveCallTest.scala @@ -158,6 +158,57 @@ class ReflectiveCallTest { assertFalse(fBoolN(false)) } + @Test def should_work_with_compareTo_for_primitives(): Unit = { + def fCompareToBoolean(x: { def compareTo(y: java.lang.Boolean): Int }, y: Boolean): Int = + x.compareTo(y) + assertTrue(fCompareToBoolean(false, true) < 0) + + def fCompareToChar(x: { def compareTo(y: java.lang.Character): Int }, y: Char): Int = + x.compareTo(y) + assertTrue(fCompareToChar('A', 'C') < 0) + + def fCompareToByte(x: { def compareTo(y: java.lang.Byte): Int }, y: Byte): Int = + x.compareTo(y) + assertTrue(fCompareToByte(5.toByte, 6.toByte) < 0) + + def fCompareToShort(x: { def compareTo(y: java.lang.Short): Int }, y: Short): Int = + x.compareTo(y) + assertTrue(fCompareToShort(5.toShort, 6.toShort) < 0) + + def fCompareToInt(x: { def compareTo(y: java.lang.Integer): Int }, y: Int): Int = + x.compareTo(y) + assertTrue(fCompareToInt(5, 6) < 0) + + def fCompareToLong(x: { def compareTo(y: java.lang.Long): Int }, y: Long): Int = + x.compareTo(y) + assertTrue(fCompareToLong(5L, 6L) < 0) + + def fCompareToFloat(x: { def compareTo(y: java.lang.Float): Int }, y: Float): Int = + x.compareTo(y) + assertTrue(fCompareToFloat(5.5f, 6.5f) < 0) + + def fCompareToDouble(x: { def compareTo(y: java.lang.Double): Int }, y: Double): Int = + x.compareTo(y) + assertTrue(fCompareToDouble(5.5, 6.5) < 0) + } + + @Test def should_work_with_concat_for_primitives(): Unit = { + // See https://github.com/scala/bug/issues/10469 + assumeFalse("Reflective call prim.+(String) broken on the JVM", + Platform.executingInJVM) + + def concat(x: Any { def +(y: String): String }, y: String): String = x + y + + assertEquals("truefoo", concat(true, "foo")) + assertEquals("Afoo", concat('A', "foo")) + assertEquals("5foo", concat(5.toByte, "foo")) + assertEquals("5foo", concat(5.toShort, "foo")) + assertEquals("5foo", concat(5, "foo")) + assertEquals("5foo", concat(5L, "foo")) + assertEquals("5.5foo", concat(5.5f, "foo")) + assertEquals("5.5foo", concat(5.5, "foo")) + } + @Test def should_work_with_Arrays(): Unit = { type UPD = { def update(i: Int, x: String): Unit } type APL = { def apply(i: Int): String } @@ -211,6 +262,10 @@ class ReflectiveCallTest { type LEN_A = { def length: Any } def lenA(x: LEN_A): Any = x.length assertEquals(4, lenA("asdf")) + + def compareToString(x: { def compareTo(y: String): Int }, y: String): Int = + x.compareTo(y) + assertTrue(compareToString("hello", "world") < 0) } @Test def should_properly_generate_forwarders_for_inherited_methods(): Unit = { From a0fcb0ff56acd80d464b8813fae227969a670c73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 16 Aug 2017 16:38:09 +0200 Subject: [PATCH 0443/2665] Upgrade to sbt 1.0.0 final to cross-build the sbt plugin. --- ci/matrix.xml | 2 +- scripts/publish.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/matrix.xml b/ci/matrix.xml index 43c09d99cb..de4ed81220 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -486,7 +486,7 @@ 1.8 2.12.2 - 1.0.0-RC2 + 1.0.0 diff --git a/scripts/publish.sh b/scripts/publish.sh index 2fee9127aa..7e1bf32db3 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -13,7 +13,7 @@ BIN_VERSIONS="2.10.6 2.11.11 2.12.2 2.13.0-M1" CLI_VERSIONS="2.10.6 2.11.11 2.12.2" SBT_VERSION="2.10.6" SBT1_VERSION="2.12.2" -SBT1_SBTVERSION="1.0.0-RC2" +SBT1_SBTVERSION="1.0.0" COMPILER="compiler jUnitPlugin" LIBS="library javalibEx ir irJS tools toolsJS jsEnvs jsEnvsTestKit testAdapter stubs testInterface jUnitRuntime" From 39567a7bfc7184bccfcc8a849334a180faee16d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 16 Aug 2017 17:16:59 +0200 Subject: [PATCH 0444/2665] [no-master] Fix #3082: Refuse to generate a launcher for new-style main. When using a new-style main class (with a `main(Array[String])` method), it is not possible to use launchers. In particular, the setting `scalaJSUseMainModuleInitializer` must be true. Previously the sbt plugin was not checking this and would simply generate a broken launcher, resulting in a run-time error. Now we report a meaningful error when trying to generate the launcher. --- .../sbtplugin/ScalaJSPluginInternal.scala | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 76150f3078..743508ef82 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -380,6 +380,18 @@ object ScalaJSPluginInternal { Attributed.blank(results.result()).put(scalaJSSourceFiles, realFiles.result()) } + private def ensureOldStyleMainClass(mainClass: String, + scalaJSDiscoveredMainClassesValue: Map[String, Boolean]): Unit = { + val newStyle = scalaJSDiscoveredMainClassesValue.getOrElse(mainClass, false) + if (newStyle) { + throw new MessageOnlyException( + s"The main class $mainClass uses the new style with an " + + "Array[String] argument, but scalaJSUseMainModuleInitializer is " + + "false. Did you forget to specify `scalaJSUseMainModuleInitializer " + + ":= true` in your project settings?") + } + } + val scalaJSConfigSettings: Seq[Setting[_]] = Seq( incOptions ~= scalaJSPatchIncOptions ) ++ ( @@ -458,7 +470,11 @@ object ScalaJSPluginInternal { } } else { Def.task { + val scalaJSDiscoveredMainClassesValue = + scalaJSDiscoveredMainClasses.value mainClass.value map { mainCl => + ensureOldStyleMainClass(mainCl, scalaJSDiscoveredMainClassesValue) + val file = (artifactPath in packageScalaJSLauncherInternal).value assert(scalaJSModuleKind.value == ModuleKind.NoModule, "Cannot produce a launcher file when scalaJSModuleKind " + @@ -838,10 +854,13 @@ object ScalaJSPluginInternal { Def.task { val moduleKind = scalaJSModuleKind.value val moduleIdentifier = scalaJSModuleIdentifier.value + val scalaJSDiscoveredMainClassesValue = + scalaJSDiscoveredMainClasses.value (mainClass in scalaJSLauncherInternal).value.fold { throw new MessageOnlyException("No main class detected.") } { mainClass => + ensureOldStyleMainClass(mainClass, scalaJSDiscoveredMainClassesValue) val memLaunch = memLauncher(mainClass, moduleKind, moduleIdentifier) Attributed[VirtualJSFile](memLaunch)( @@ -874,6 +893,17 @@ object ScalaJSPluginInternal { "the (unique) entry point is burned in the fastOptJS/fullOptJS.") } + val scalaJSDiscoveredMainClassesValue = + scalaJSDiscoveredMainClasses.value + val newStyleMain = scalaJSDiscoveredMainClassesValue.getOrElse( + mainClass, false) + if (newStyleMain) { + throw new MessageOnlyException( + "`runMain` is not supported when using a main class with an " + + "Array[String] argument. It is only supported for objects that " + + "extend js.JSApp.") + } + val moduleKind = scalaJSModuleKind.value val moduleIdentifier = scalaJSModuleIdentifier.value jsRun(loadedJSEnv.value, mainClass, From 9d28433939f7af4826d7c370567f14493ac0c103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 16 Aug 2017 18:14:28 +0200 Subject: [PATCH 0445/2665] Make testSuiteJVM/test pass on all system configurations. This commit forces testSuiteJVM to use * UTF-8 as default encoding * en-US as default locale * `\n` as line separator This ensures that it succeeds on all system configurations, e.g., on Windows or on a system configured with a non-English default locale. It is necessary because Scala.js ensures those defaults "by spec", and hence our test suite relies on these defaults, notably to test them. --- project/Build.scala | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/project/Build.scala b/project/Build.scala index 476677d9f2..2f711472cc 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1677,6 +1677,17 @@ object Build { settings = commonSettings ++ testSuiteCommonSettings(isJSTest = false) ++ Seq( name := "Scala.js test suite on JVM", + /* Scala.js always assumes en-US, UTF-8 and NL as line separator by + * default. Since some of our tests rely on these defaults (notably to + * test them), we have to force the same values on the JVM. + */ + fork in Test := true, + javaOptions in Test ++= Seq( + "-Dfile.encoding=UTF-8", + "-Duser.country=US", "-Duser.language=en", + "-Dline.separator=\n" + ), + libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % "test" ) From 6bfbb15fd2bd902ea59cde2fc291d9b39bad80d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 17 Aug 2017 17:29:58 +0200 Subject: [PATCH 0446/2665] [no-master] Add `PhantomJSEnv(...).value` with a `PhantomJSEnv.Config`. This is more consistent with the constructor of `PhantomJSEnv`, and will allow `sbt-scalajs-env-phantomjs` to evolve in binary compatible ways. The changes of this commit should be forward-ported to https://github.com/scala-js/scala-js-env-phantomjs. --- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 41 ++++++++++++++----- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 4ebc31a371..8b32e8fc9c 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -161,15 +161,18 @@ object ScalaJSPlugin extends AutoPlugin { .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: + /** 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 + * jsEnv := PhantomJSEnv(...).value * }}} * + * The specified `Config` is augmented with an appropriate Jetty class + * loader (through `withJettyClassLoader`). + * * 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. @@ -177,20 +180,38 @@ object ScalaJSPlugin extends AutoPlugin { * case) or scope it manually, using * [[sbt.ProjectExtra.inScope[* Project.inScope]]. */ + def PhantomJSEnv( + config: org.scalajs.jsenv.phantomjs.PhantomJSEnv.Config + ): Def.Initialize[Task[PhantomJSEnv]] = Def.task { + val loader = scalaJSPhantomJSClassLoader.value + new PhantomJSEnv(config.withJettyClassLoader(loader)) + } + + /** Creates a [[sbt.Def.Initialize Def.Initialize]] for a PhantomJSEnv + * with the default configuration. + * + * This is equivalent to + * {{{ + * PhantomJSEnv(org.scalajs.jsenv.phantomjs.PhantomJSEnv.Config()) + * }}} + */ + def PhantomJSEnv(): Def.Initialize[Task[PhantomJSEnv]] = + PhantomJSEnv(org.scalajs.jsenv.phantomjs.PhantomJSEnv.Config()) + + /** Creates a [[sbt.Def.Initialize Def.Initialize]] for a PhantomJSEnv. */ + @deprecated("Use the overload with a PhantomJSEnv.Config.", "0.6.20") 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( + ): Def.Initialize[Task[PhantomJSEnv]] = { + PhantomJSEnv( org.scalajs.jsenv.phantomjs.PhantomJSEnv.Config() .withExecutable(executable) .withArgs(args.toList) .withEnv(env) - .withAutoExit(autoExit) - .withJettyClassLoader(loader)) + .withAutoExit(autoExit)) } // ModuleKind From 111e414557eb8fb041fc5578531b275b0cb9a7cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 18 Aug 2017 13:45:10 +0200 Subject: [PATCH 0447/2665] Fix #3090: Better default settings for custom sbt configurations. Previously, some settings involving `in Compile` or `in Test` were defined in the project-level settings. We now define them from `scalaJSCompileSettings` and `scalaJSTestSettings`, so that they are automatically and accurately applied when those sets of settings are reused on custom sbt configurations (e.g., `IntegrationTest`). We also make sure that those settings do not hard-code the `-test` suffix, but rather derive it from the current configuration name. --- .../sbtplugin/ScalaJSPluginInternal.scala | 65 ++++++++++++------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 743508ef82..482c6c420e 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -210,6 +210,13 @@ object ScalaJSPluginInternal { new ClearableLinker(() => StandardLinker(config), config.batchMode) }, + // Have `clean` reset the state of the incremental linker + clean in (This, Zero, This) := { + val _ = (clean in (This, Zero, This)).value + (scalaJSLinker in key).value.clear() + () + }, + usesScalaJSLinkerTag in key := { val projectPart = thisProject.value.id val configPart = configuration.value.name @@ -400,6 +407,17 @@ object ScalaJSPluginInternal { dispatchTaskKeySettings(scalaJSLinkedFile) ++ dispatchSettingKeySettings(scalaJSLinker) ++ dispatchSettingKeySettings(usesScalaJSLinkerTag) + ) ++ ( + Seq(fastOptJS, fullOptJS, packageScalaJSLauncherInternal, + packageJSDependencies, packageMinifiedJSDependencies).map { key => + moduleName in key := { + val configSuffix = configuration.value match { + case Compile => "" + case config => "-" + config.name + } + moduleName.value + configSuffix + } + } ) ++ Seq( /* Note: This cache only gets freed by its finalizer. Otherwise we'd need * to intercept reloads in sbt (see #2171). @@ -818,6 +836,13 @@ object ScalaJSPluginInternal { } }, + /* Do not inherit scalaJSModuleInitializers from the parent configuration. + * Instead, always derive them straight from the Zero configuration + * scope. + */ + scalaJSModuleInitializers := + (scalaJSModuleInitializers in (This, Zero, This)).value, + scalaJSModuleInitializers ++= { if (scalaJSUseMainModuleInitializer.value) { Seq(scalaJSMainModuleInitializer.value.getOrElse { @@ -956,11 +981,6 @@ object ScalaJSPluginInternal { val scalaJSTestBuildSettings = ( scalaJSConfigSettings - ) ++ ( - Seq(fastOptJS, fullOptJS, packageScalaJSLauncherInternal, - packageJSDependencies) map { packageJSTask => - moduleName in packageJSTask := moduleName.value + "-test" - } ) private def scalaJSTestHtmlTaskSettings( @@ -1001,12 +1021,16 @@ object ScalaJSPluginInternal { } val scalaJSTestHtmlSettings = Seq( - artifactPath in testHtmlFastOpt := + artifactPath in testHtmlFastOpt := { + val config = configuration.value.name ((crossTarget in testHtmlFastOpt).value / - ((moduleName in testHtmlFastOpt).value + "-fastopt-test.html")), - artifactPath in testHtmlFullOpt := + ((moduleName in testHtmlFastOpt).value + s"-fastopt-$config.html")) + }, + artifactPath in testHtmlFullOpt := { + val config = configuration.value.name ((crossTarget in testHtmlFullOpt).value / - ((moduleName in testHtmlFullOpt).value + "-opt-test.html")) + ((moduleName in testHtmlFullOpt).value + s"-opt-$config.html")) + } ) ++ ( scalaJSTestHtmlTaskSettings(testHtmlFastOpt, fastOptJS, packageJSDependencies) ++ @@ -1019,6 +1043,13 @@ object ScalaJSPluginInternal { scalaJSRunSettings ++ scalaJSTestFrameworkSettings ++ scalaJSTestHtmlSettings + ) ++ Seq( + /* Always default to false for scalaJSUseMainModuleInitializer and + * persistLauncher in testing configurations, even if it is true in the + * Global configuration scope. + */ + scalaJSUseMainModuleInitializer := false, + persistLauncherInternal := false ) val scalaJSDependenciesSettings = Seq( @@ -1087,7 +1118,6 @@ object ScalaJSPluginInternal { relativeSourceMaps := false, persistLauncherInternal := false, - persistLauncherInternal in Test := false, emitSourceMaps := scalaJSLinkerConfig.value.sourceMap, @@ -1116,25 +1146,10 @@ object ScalaJSPluginInternal { checkScalaJSSemantics := true, scalaJSModuleInitializers := Seq(), - scalaJSModuleInitializers in Compile := scalaJSModuleInitializers.value, - // Do not inherit scalaJSModuleInitializers in Test from Compile - scalaJSModuleInitializers in Test := scalaJSModuleInitializers.value, - scalaJSUseMainModuleInitializer := false, - scalaJSUseMainModuleInitializer in Test := false, scalaJSConsole := ConsoleJSConsole, - clean := { - // have clean reset incremental linker state - val _ = clean.value - (scalaJSLinker in (Compile, fastOptJS)).value.clear() - (scalaJSLinker in (Test, fastOptJS)).value.clear() - (scalaJSLinker in (Compile, fullOptJS)).value.clear() - (scalaJSLinker in (Test, fullOptJS)).value.clear() - () - }, - /* Depend on jetty artifacts in dummy configuration to be able to inject * them into the PhantomJS runner if necessary. * See scalaJSPhantomJSClassLoader From d1ebc349c3e8a59a10273761f28026fa4efccb3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 18 Aug 2017 15:36:20 +0200 Subject: [PATCH 0448/2665] [no-master] Fix #3102: Provide a shim for JSDependenciesPlugin. This will make it easier to write builds cross-compiling against sbt-scalajs 0.6.x and sbt-jsdependencies 1.x. --- sbt-plugin-test/build.sbt | 1 + .../sbtplugin/JSDependenciesPlugin.scala | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 sbt-plugin/src/main/scala/org/scalajs/jsdependencies/sbtplugin/JSDependenciesPlugin.scala diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index ee8c333a15..b522f85f15 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -170,6 +170,7 @@ lazy val multiTestJVM = multiTest.jvm lazy val jsDependenciesTest = withRegretionTestForIssue2243( project.settings(versionSettings: _*). enablePlugins(ScalaJSPlugin). + enablePlugins(JSDependenciesPlugin). settings( jsDependencies ++= Seq( "org.webjars" % "historyjs" % "1.8.0" / "uncompressed/history.js", diff --git a/sbt-plugin/src/main/scala/org/scalajs/jsdependencies/sbtplugin/JSDependenciesPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/jsdependencies/sbtplugin/JSDependenciesPlugin.scala new file mode 100644 index 0000000000..e5d97099b9 --- /dev/null +++ b/sbt-plugin/src/main/scala/org/scalajs/jsdependencies/sbtplugin/JSDependenciesPlugin.scala @@ -0,0 +1,32 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.jsdependencies.sbtplugin + +import sbt._ + +import org.scalajs.sbtplugin.ScalaJSPlugin + +/** Shim for [[https://github.com/scala-js/jsdependencies sbt-jsdependencies]] + * in Scala.js 0.6.x. + * + * This sbt plugin is empty. It only serves as a source-compatible shim to + * be able to cross-compile builds across `sbt-scalajs` 0.6.x and + * `sbt-jsdependencies` 1.x. + */ +object JSDependenciesPlugin extends AutoPlugin { + override def requires: Plugins = ScalaJSPlugin + + object autoImport + + lazy val configSettings: Seq[Setting[_]] = Nil + + lazy val compileSettings: Seq[Setting[_]] = Nil + + lazy val testSettings: Seq[Setting[_]] = Nil +} From 2cdbbfd4dd7182bb0cbedb088cfbe6bd2cbe72e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 19 Aug 2017 11:29:36 +0200 Subject: [PATCH 0449/2665] Remove `with java.io.Serializable` from `RuntimeLong`. `RuntimeLong` already extends `java.lang.Number`, which itself implements `java.io.Serializable` anyway, so this is fine. We need to do this now because 2.12.3 will anyway remove the mention to `java.io.Serializable` from `RuntimeLong`'s class file, so we end up with a binary incompatibility. It is cleaner to keep source and binary in sync by preemptively remove it ourselves. Note that `java.lang.Long` was already declared without the explicit `with java.io.Serializable`, so this brings `RuntimeLong` more in sync with `java.lang.Long`, which is not a bad thing. --- .../src/main/scala/scala/scalajs/runtime/RuntimeLong.scala | 4 ++-- project/BinaryIncompatibilities.scala | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala b/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala index af4304147b..2660cfb74c 100644 --- a/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala +++ b/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala @@ -33,8 +33,8 @@ import js.JSStringOps._ /** Emulates a Long on the JavaScript platform. */ @inline final class RuntimeLong(val lo: Int, val hi: Int) - extends java.lang.Number with java.io.Serializable - with java.lang.Comparable[java.lang.Long] { a => + extends java.lang.Number with java.lang.Comparable[java.lang.Long] { + a => import RuntimeLong._ import Utils._ diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 2e6b661b6e..62550e2cb0 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -87,6 +87,12 @@ object BinaryIncompatibilities { ) val Library = Seq( + /* RuntimeLong lost its `with java.io.Serializable`, but that is not a + * problem because it also extends `java.lang.Number`, which itself + * implements `java.io.Serializable` anyway. + */ + ProblemFilters.exclude[MissingTypesProblem]( + "scala.scalajs.runtime.RuntimeLong") ) val TestInterface = Seq( From e8a28eb42bdef13ccf7bdb8babd4d3bbbbb83b15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 17 Aug 2017 15:43:01 +0200 Subject: [PATCH 0450/2665] Fix #3077: Add Scala 2.12.3 to the CI. --- ci/checksizes.sh | 6 +- ci/matrix.xml | 38 +- .../scalajs/2.12.3/BlacklistedTests.txt | 1047 +++++ .../partest/scalajs/2.12.3/BuglistedTests.txt | 7 + .../scalajs/2.12.3/WhitelistedTests.txt | 3365 +++++++++++++++++ .../scalajs/2.12.3/neg/t6446-additional.check | 30 + .../scalajs/2.12.3/neg/t6446-list.check | 2 + .../scalajs/2.12.3/neg/t6446-missing.check | 30 + .../2.12.3/neg/t6446-show-phases.check | 29 + .../scalajs/2.12.3/neg/t7494-no-options.check | 31 + .../scalajs/2.12.3/run/Course-2002-01.check | 37 + .../scalajs/2.12.3/run/Course-2002-02.check | 187 + .../scalajs/2.12.3/run/Course-2002-04.check | 64 + .../scalajs/2.12.3/run/Course-2002-08.check | 171 + .../scalajs/2.12.3/run/Course-2002-09.check | 50 + .../scalajs/2.12.3/run/Course-2002-10.check | 46 + .../partest/scalajs/2.12.3/run/Meter.check | 16 + .../scalajs/2.12.3/run/MeterCaseClass.check | 16 + .../tools/partest/scalajs/2.12.3/run/bugs.sem | 1 + .../scalajs/2.12.3/run/caseClassHash.check | 9 + .../partest/scalajs/2.12.3/run/deeps.check | 87 + .../scalajs/2.12.3/run/dynamic-anyval.check | 4 + .../scalajs/2.12.3/run/impconvtimes.check | 1 + .../partest/scalajs/2.12.3/run/imports.check | 21 + .../scalajs/2.12.3/run/interpolation.check | 32 + .../2.12.3/run/interpolationMultiline1.check | 26 + .../partest/scalajs/2.12.3/run/issue192.sem | 1 + .../2.12.3/run/macro-bundle-static.check | 6 + .../2.12.3/run/macro-bundle-toplevel.check | 6 + .../run/macro-bundle-whitebox-decl.check | 6 + .../partest/scalajs/2.12.3/run/misc.check | 62 + .../scalajs/2.12.3/run/promotion.check | 4 + .../partest/scalajs/2.12.3/run/runtime.check | 70 + .../scalajs/2.12.3/run/spec-self.check | 2 + .../scalajs/2.12.3/run/structural.check | 37 + .../scalajs/2.12.3/run/t0421-new.check | 3 + .../scalajs/2.12.3/run/t0421-old.check | 3 + .../partest/scalajs/2.12.3/run/t1503.sem | 1 + .../partest/scalajs/2.12.3/run/t3702.check | 2 + .../partest/scalajs/2.12.3/run/t4148.sem | 1 + .../partest/scalajs/2.12.3/run/t4617.check | 1 + .../partest/scalajs/2.12.3/run/t5356.check | 6 + .../partest/scalajs/2.12.3/run/t5552.check | 6 + .../partest/scalajs/2.12.3/run/t5568.check | 9 + .../partest/scalajs/2.12.3/run/t5629b.check | 10 + .../partest/scalajs/2.12.3/run/t5680.check | 3 + .../partest/scalajs/2.12.3/run/t5866.check | 2 + .../scalajs/2.12.3/run/t6318_primitives.check | 54 + .../partest/scalajs/2.12.3/run/t6662.check | 1 + .../partest/scalajs/2.12.3/run/t7657.check | 3 + .../partest/scalajs/2.12.3/run/t7763.sem | 1 + .../partest/scalajs/2.12.3/run/t8570a.check | 1 + .../partest/scalajs/2.12.3/run/t8764.check | 5 + .../partest/scalajs/2.12.3/run/t9387b.check | 1 + .../partest/scalajs/2.12.3/run/t9656.check | 14 + .../scalajs/2.12.3/run/try-catch-unify.check | 4 + .../2.12.3/run/virtpatmat_switch.check | 7 + .../2.12.3/run/virtpatmat_typetag.check | 10 + project/Build.scala | 3 +- .../resources/2.12.3/BlacklistedTests.txt | 133 + .../resources/2.12.3/WhitelistedTests.txt | 40 + scripts/assemble-cli.sh | 4 +- scripts/build-all-js.sh | 2 +- scripts/publish.sh | 8 +- 64 files changed, 5863 insertions(+), 22 deletions(-) create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/BlacklistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/BuglistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/WhitelistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-additional.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-list.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-missing.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-show-phases.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t7494-no-options.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Course-2002-01.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Course-2002-02.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Course-2002-04.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Course-2002-08.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Course-2002-09.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Course-2002-10.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Meter.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/MeterCaseClass.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/bugs.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/caseClassHash.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/deeps.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/dynamic-anyval.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/impconvtimes.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/imports.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/interpolation.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/interpolationMultiline1.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/issue192.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/macro-bundle-static.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/macro-bundle-toplevel.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/macro-bundle-whitebox-decl.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/misc.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/promotion.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/runtime.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/spec-self.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/structural.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t0421-new.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t0421-old.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t1503.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t3702.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t4148.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t4617.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t5356.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t5552.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t5568.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t5629b.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t5680.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t5866.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t6318_primitives.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t6662.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t7657.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t7763.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t8570a.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t8764.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t9387b.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t9656.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/try-catch-unify.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/virtpatmat_switch.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/virtpatmat_typetag.check create mode 100644 scala-test-suite/src/test/resources/2.12.3/BlacklistedTests.txt create mode 100644 scala-test-suite/src/test/resources/2.12.3/WhitelistedTests.txt diff --git a/ci/checksizes.sh b/ci/checksizes.sh index c16a7d7ecf..ce308ea906 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -11,13 +11,13 @@ case $FULLVER in 2.11.11) VER=2.11 ;; - 2.12.2) + 2.12.3) VER=2.12 ;; 2.13.0-M1) VER=2.13.0-M1 ;; - 2.10.3|2.10.4|2.10.5|2.10.6|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7|2.11.8|2.12.0|2.12.1) + 2.10.3|2.10.4|2.10.5|2.10.6|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7|2.11.8|2.12.0|2.12.1|2.12.2) echo "Ignoring checksizes for Scala $FULLVER" exit 0 ;; @@ -48,7 +48,7 @@ case $FULLVER in REVERSI_PREOPT_GZ_EXPECTEDSIZE=71000 REVERSI_OPT_GZ_EXPECTEDSIZE=32000 ;; - 2.12.2) + 2.12.3) REVERSI_PREOPT_EXPECTEDSIZE=629000 REVERSI_OPT_EXPECTEDSIZE=147000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=76000 diff --git a/ci/matrix.xml b/ci/matrix.xml index de4ed81220..dc61f4a53d 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -326,7 +326,7 @@ 1.8 - 2.12.2 + 2.12.3 1.8 @@ -346,7 +346,7 @@ testSuite - 2.12.2 + 2.12.3 1.8 testSuite @@ -363,7 +363,7 @@ scalaTestSuite - 2.12.2 + 2.12.3 1.8 scalaTestSuite @@ -385,7 +385,7 @@ testSuite - 2.12.2 + 2.12.3 1.8 testSuite @@ -402,7 +402,7 @@ scalaTestSuite - 2.12.2 + 2.12.3 1.8 scalaTestSuite @@ -422,7 +422,7 @@ 1.8 - 2.12.2 + 2.12.3 1.8 @@ -453,7 +453,7 @@ 1.8 - 2.12.2 + 2.12.3 1.8 @@ -469,7 +469,7 @@ 1.7 - 2.12.2 + 2.12.3 1.8 @@ -485,7 +485,7 @@ 1.8 - 2.12.2 + 2.12.3 1.0.0 @@ -550,6 +550,10 @@ 2.12.1 1.8 + + 2.12.2 + 1.8 + @@ -605,11 +609,11 @@ 1.7 - 2.12.2 + 2.12.3 1.8 - 2.12.2 + 2.12.3 1.8 @@ -758,6 +762,18 @@ 2.12.1 1.8 + + 2.12.2 + 1.8 + + + 2.12.2 + 1.8 + + + 2.12.2 + 1.8 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/BlacklistedTests.txt new file mode 100644 index 0000000000..b87c684414 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/BlacklistedTests.txt @@ -0,0 +1,1047 @@ +# +# POS +# + +# Using Jsoup, what's that? +pos/cycle-jsoup.scala + +# Kills our IR serializer, it's an artificially super-deep if/else if +pos/t9181.scala + +# +# NEG +# + +# Screws up, but not really our problem (error: None.get instead of +# phase ordering error) +neg/t7494-multi-right-after +neg/t7494-right-after-before +neg/t7622-multi-followers +neg/t7622-cyclic-dependency + +# Uses some strange macro cross compile mechanism. +neg/macro-incompatible-macro-engine-c.scala + +# Spurious failures +neg/patmatexhaust-huge.scala + +# Uses .java files +run/t9200 +run/noInlineUnknownIndy + +# +# RUN +# + +# Relies on the exact toString() representation of Floats/Doubles +run/t2378.scala + +# Uses ClassTags on existentials which are broken in Scala (see #251) +run/valueclasses-classtag-existential.scala + +# Relies on a particular execution speed +run/t5857.scala + +# Using parts of the javalib we don't plan to support + +run/t5018.scala +run/t2417.scala +run/t4813.scala +run/lazy-concurrent.scala +run/t3667.scala +run/t3038d.scala +run/shutdownhooks.scala +run/t5590.scala +run/t3895b.scala +run/t5974.scala +run/hashset.scala +run/t5262.scala +run/serialize-stream.scala +run/sysprops.scala +run/lambda-serialization-gc.scala +run/t9390.scala +run/t9390b.scala +run/t9390c.scala +run/trait-defaults-super.scala + +run/t2849.scala +run/t1360.scala +run/t3199b.scala +run/t8690.scala + +run/various-flat-classpath-types.scala + +# Uses java.util.Collections +run/t2250.scala + +# Uses java.math.BigDecimal / BigInteger : but failures not due to them +run/hashhash.scala +run/is-valid-num.scala + +# Documented semantic difference on String.split(x: Array[Char]) +run/t0325.scala + +# Using Threads +run/t6969.scala +run/inner-obj-auto.scala +run/predef-cycle.scala +run/synchronized.scala + +# Uses java.security +run/t2318.scala + +# Tries to catch java.lang.StackOverflowError +run/t6154.scala + +# Tries to catch java.lang.OutOfMemoryError +run/t7880.scala + +# Taking too much time, because JavaScript is not as fast as the JVM + +run/collections.scala +run/t3989.scala +run/adding-growing-set.scala +run/t3242.scala +run/hashCodeDistribution.scala +run/t408.scala +run/t6584.scala +run/t6853.scala +run/UnrolledBuffer.scala +run/t6253a.scala +run/t6253b.scala +run/t6253c.scala +run/numbereq.scala +run/t4658.scala + +# Crashes Rhino + +run/bridges.scala +run/patmat-exprs.scala + +# Using partest properties + +run/tailcalls.scala +run/t4294.scala +run/t6331b.scala + +# Using IO + +run/t6488.scala +run/t6988.scala + +# Object{Output|Input}Streams +run/t6935.scala +run/t8188.scala +run/t9375.scala +run/t9365.scala +run/inlineAddDeserializeLambda.scala +run/sammy_seriazable.scala +run/lambda-serialization-security.scala +run/t10232.scala +run/t10233.scala +run/t10244.scala + +# Using System.getProperties + +run/t4426.scala + +# Using Await + +run/t7336.scala +run/t7775.scala +run/future-flatmap-exec-count.scala + +# Using detailed stack trace + +run/t6308.scala + +# Using reflection + +run/t6063 + +run/mixin-bridge-methods.scala +run/t5125.scala +run/outertest.scala +run/t6223.scala +run/t5652b +run/elidable-opt.scala +run/nullable-lazyvals.scala +run/t4794.scala +run/t5652 +run/t5652c +run/getClassTest-old.scala +run/t8960.scala +run/t7965.scala +run/t8087.scala +run/t8931.scala +run/t8445.scala +run/lambda-serialization.scala + +run/reflection-repl-classes.scala +run/t5256e.scala +run/typetags_core.scala +run/reflection-constructormirror-toplevel-badpath.scala +run/t5276_1b.scala +run/reflection-sorted-decls.scala +run/toolbox_typecheck_implicitsdisabled.scala +run/t5418b.scala +run/toolbox_typecheck_macrosdisabled2.scala +run/abstypetags_serialize.scala +run/all-overridden.scala +run/showraw_tree_kinds.scala +run/showraw_tree_types_ids.scala +run/showraw_tree_types_typed.scala +run/showraw_tree_ids.scala +run/showraw_tree_ultimate.scala +run/t5266_2.scala +run/t5274_1.scala +run/t5224.scala +run/reflection-sanitychecks.scala +run/t6086-vanilla.scala +run/t5277_2.scala +run/reflection-methodsymbol-params.scala +run/reflection-valueclasses-standard.scala +run/t5274_2.scala +run/t5423.scala +run/reflection-modulemirror-toplevel-good.scala +run/t5419.scala +run/t5271_3.scala +run/reflection-enclosed-nested-basic.scala +run/reflection-enclosed-nested-nested-basic.scala +run/fail-non-value-types.scala +run/exprs_serialize.scala +run/t5258a.scala +run/typetags_without_scala_reflect_manifest_lookup.scala +run/t4110-new.scala +run/t5273_2b_newpatmat.scala +run/t6277.scala +run/t5335.scala +run/toolbox_typecheck_macrosdisabled.scala +run/reflection-modulemirror-inner-good.scala +run/t5229_2.scala +run/typetags_multi.scala +run/typetags_without_scala_reflect_typetag_manifest_interop.scala +run/reflection-constructormirror-toplevel-good.scala +run/reflection-magicsymbols-invoke.scala +run/t6392b.scala +run/t5229_1.scala +run/reflection-magicsymbols-vanilla.scala +run/t5225_2.scala +run/runtimeEval1.scala +run/reflection-enclosed-nested-inner-basic.scala +run/reflection-fieldmirror-ctorparam.scala +run/t6181.scala +run/reflection-magicsymbols-repl.scala +run/t5272_2_newpatmat.scala +run/t5270.scala +run/t5418a.scala +run/t5276_2b.scala +run/t5256f.scala +run/reflection-enclosed-basic.scala +run/reflection-constructormirror-inner-badpath.scala +run/interop_typetags_are_manifests.scala +run/newTags.scala +run/t5273_1_newpatmat.scala +run/reflection-constructormirror-nested-good.scala +run/t2236-new.scala +run/existentials3-new.scala +run/t6323b.scala +run/t5943a1.scala +run/reflection-fieldmirror-getsetval.scala +run/t5272_1_oldpatmat.scala +run/t5256h.scala +run/t1195-new.scala +run/t5840.scala +run/reflection-methodsymbol-returntype.scala +run/reflection-fieldmirror-accessorsareokay.scala +run/reflection-sorted-members.scala +run/reflection-allmirrors-tostring.scala +run/valueclasses-typetag-existential.scala +run/toolbox_console_reporter.scala +run/reflection-enclosed-inner-inner-basic.scala +run/t5256b.scala +run/bytecodecs.scala +run/elidable.scala +run/freetypes_false_alarm1.scala +run/freetypes_false_alarm2.scala +run/getClassTest-new.scala +run/idempotency-extractors.scala +run/idempotency-case-classes.scala +run/idempotency-this.scala +run/idempotency-labels.scala +run/idempotency-lazy-vals.scala +run/interop_manifests_are_abstypetags.scala +run/interop_manifests_are_typetags.scala +run/abstypetags_core.scala +run/macro-reify-abstypetag-notypeparams +run/macro-reify-abstypetag-typeparams-tags +run/macro-reify-abstypetag-typeparams-notags +run/macro-reify-abstypetag-usetypetag +run/macro-reify-freevars +run/macro-reify-splice-outside-reify +run/macro-reify-tagless-a +run/macro-reify-type +run/macro-reify-typetag-typeparams-tags +run/macro-reify-typetag-notypeparams +run/macro-undetparams-implicitval +run/manifests-new.scala +run/manifests-old.scala +run/no-pickle-skolems +run/position-val-def.scala +run/reflect-priv-ctor.scala +run/primitive-sigs-2-new.scala +run/primitive-sigs-2-old.scala +run/reflection-enclosed-inner-basic.scala +run/reflection-enclosed-inner-nested-basic.scala +run/reflection-constructormirror-inner-good.scala +run/reflection-constructormirror-nested-badpath.scala +run/reflection-fancy-java-classes +run/reflection-fieldsymbol-navigation.scala +run/reflection-fieldmirror-nmelocalsuffixstring.scala +run/reflection-fieldmirror-getsetvar.scala +run/reflection-fieldmirror-privatethis.scala +run/reflection-implicit.scala +run/reflection-mem-glbs.scala +run/reflection-mem-tags.scala +run/reflection-java-annotations +run/reflection-java-crtp +run/reflection-methodsymbol-typeparams.scala +run/reflection-modulemirror-nested-badpath.scala +run/reflection-modulemirror-inner-badpath.scala +run/reflection-modulemirror-nested-good.scala +run/reflection-modulemirror-toplevel-badpath.scala +run/reflection-sync-subtypes.scala +run/reflinit.scala +run/reflection-valueclasses-derived.scala +run/reflection-valueclasses-magic.scala +run/resetattrs-this.scala +run/runtimeEval2.scala +run/showraw_aliases.scala +run/showraw_mods.scala +run/shortClass.scala +run/showraw_nosymbol.scala +run/showraw_tree.scala +run/showraw_tree_types_untyped.scala +run/t1167.scala +run/t2577.scala +run/t2873.scala +run/t2886.scala +run/t2251b.scala +run/t3346j.scala +run/t3507-new.scala +run/t3569.scala +run/t5125b.scala +run/t5225_1.scala +run/t3425b +run/t5256a.scala +run/t5230.scala +run/t5256c.scala +run/t5256g.scala +run/t5266_1.scala +run/t5269.scala +run/t5271_1.scala +run/t5271_2.scala +run/t5271_4.scala +run/t5272_1_newpatmat.scala +run/t5272_2_oldpatmat.scala +run/t5273_1_oldpatmat.scala +run/t5273_2a_newpatmat.scala +run/t5273_2a_oldpatmat.scala +run/t5275.scala +run/t5276_1a.scala +run/t5276_2a.scala +run/t5277_1.scala +run/t5279.scala +run/t5334_1.scala +run/t5334_2.scala +run/t5415.scala +run/t5418.scala +run/t5676.scala +run/t5704.scala +run/t5710-1.scala +run/t5710-2.scala +run/t5770.scala +run/t5894.scala +run/t5816.scala +run/t5824.scala +run/t5912.scala +run/t5942.scala +run/t5943a2.scala +run/t6023.scala +run/t6113.scala +run/t6175.scala +run/t6178.scala +run/t6199-mirror.scala +run/t6199-toolbox.scala +run/t6240-universe-code-gen.scala +run/t6221 +run/t6260b.scala +run/t6259.scala +run/t6287.scala +run/t6344.scala +run/t6392a.scala +run/t6591_1.scala +run/t6591_2.scala +run/t6591_3.scala +run/t6591_5.scala +run/t6591_6.scala +run/t6591_7.scala +run/t6608.scala +run/t6677.scala +run/t6687.scala +run/t6715.scala +run/t6719.scala +run/t6793.scala +run/t6860.scala +run/t6793b.scala +run/t6793c.scala +run/t7045.scala +run/t7046.scala +run/t7008-scala-defined +run/t7120b.scala +run/t7151.scala +run/t7214.scala +run/t7235.scala +run/t7331a.scala +run/t7331b.scala +run/t7331c.scala +run/t7558.scala +run/t7556 +run/t7779.scala +run/t7868b.scala +run/toolbox_current_run_compiles.scala +run/toolbox_default_reporter_is_silent.scala +run/toolbox_parse_package.scala +run/toolbox_silent_reporter.scala +run/toolbox_typecheck_inferimplicitvalue.scala +run/typetags_serialize.scala +run/valueclasses-typetag-basic.scala +run/WeakHashSetTest.scala +run/valueclasses-typetag-generic.scala +run/t4023.scala +run/t4024.scala +run/t6380.scala +run/t5273_2b_oldpatmat.scala +run/t8104 +run/t8047.scala +run/t6992 +run/var-arity-class-symbol.scala +run/typetags_symbolof_x.scala +run/typecheck +run/t8190.scala +run/t8192 +run/t8177f.scala +run/t8199.scala +run/t7932.scala +run/t7700.scala +run/t7570c.scala +run/t7570b.scala +run/t7533.scala +run/t7570a.scala +run/t7044 +run/t7328.scala +run/t6733.scala +run/t6554.scala +run/t6732.scala +run/t6379 +run/t6411b.scala +run/t6411a.scala +run/t6260c.scala +run/t6260-delambdafy.scala +run/showdecl +run/reflection-sync-potpourri.scala +run/reflection-tags.scala +run/reflection-companiontype.scala +run/reflection-scala-annotations.scala +run/reflection-idtc.scala +run/macro-reify-nested-b2 +run/mixin-signatures.scala +run/reflection-companion.scala +run/macro-reify-nested-b1 +run/macro-reify-nested-a2 +run/macro-reify-nested-a1 +run/macro-reify-chained2 +run/macro-reify-chained1 +run/inferred-type-constructors.scala +run/mirror_symbolof_x.scala +run/t8196.scala +run/t8549b.scala +run/t8574.scala +run/t8549.scala +run/t8637.scala +run/t8253.scala +run/t9027.scala +run/t6622.scala +run/toolbox_expand_macro.scala +run/toolbox-varargs +run/t9252.scala +run/t9182.scala +run/t9102.scala +run/t720.scala +run/t9408.scala +run/trait-default-specialize.scala +run/lazy-locals-2.scala +run/t5294.scala +run/trait_fields_final.scala +run/trait_fields_bytecode.scala +run/trait_fields_volatile.scala +run/junitForwarders + +run/reify_newimpl_29.scala +run/reify_magicsymbols.scala +run/reify_inheritance.scala +run/reify_newimpl_12.scala +run/reify_typerefs_2b.scala +run/reify_csv.scala +run/reify_inner2.scala +run/reify_maps_oldpatmat.scala +run/reify_newimpl_43.scala +run/reify_nested_inner_refers_to_local.scala +run/reify_closure7.scala +run/reify_closure8b.scala +run/reify_typerefs_3b.scala +run/reify_newimpl_44.scala +run/reify_newimpl_06.scala +run/reify_newimpl_05.scala +run/reify_newimpl_20.scala +run/reify_newimpl_23.scala +run/reify_metalevel_breach_-1_refers_to_1.scala +run/reify_newimpl_41.scala +run/reify-repl-fail-gracefully.scala +run/reify_fors_oldpatmat.scala +run/reify_inner3.scala +run/reify_closure8a.scala +run/reify_closures10.scala +run/reify_ann2a.scala +run/reify_newimpl_51.scala +run/reify_newimpl_47.scala +run/reify_extendbuiltins.scala +run/reify_newimpl_30.scala +run/reify_newimpl_38.scala +run/reify_closure2a.scala +run/reify_newimpl_45.scala +run/reify_closure1.scala +run/reify_generic2.scala +run/reify_printf.scala +run/reify_closure6.scala +run/reify_newimpl_37.scala +run/reify_newimpl_35.scala +run/reify_typerefs_3a.scala +run/reify_newimpl_25.scala +run/reify_ann4.scala +run/reify_typerefs_1b.scala +run/reify_newimpl_22.scala +run/reify_this.scala +run/reify_typerefs_2a.scala +run/reify_newimpl_03.scala +run/reify_newimpl_48.scala +run/reify_varargs.scala +run/reify_newimpl_42.scala +run/reify_newimpl_15.scala +run/reify_nested_inner_refers_to_global.scala +run/reify_newimpl_02.scala +run/reify_newimpl_01.scala +run/reify_fors_newpatmat.scala +run/reify_classfileann_a.scala +run/reify_nested_outer_refers_to_local.scala +run/reify_newimpl_13.scala +run/reify_closure5a.scala +run/reify_inner4.scala +run/reify_sort.scala +run/reify_ann1a.scala +run/reify_classfileann_b.scala +run/reify_closure4a.scala +run/reify_newimpl_33.scala +run/reify_sort1.scala +run/reify_properties.scala +run/reify_generic.scala +run/reify_newimpl_27.scala +run/reify-aliases.scala +run/reify_ann3.scala +run/reify-staticXXX.scala +run/reify_ann1b.scala +run/reify_ann5.scala +run/reify_anonymous.scala +run/reify-each-node-type.scala +run/reify_copypaste2.scala +run/reify_closure3a.scala +run/reify_copypaste1.scala +run/reify_complex.scala +run/reify_for1.scala +run/reify_getter.scala +run/reify_implicits-new.scala +run/reify_inner1.scala +run/reify_implicits-old.scala +run/reify_lazyunit.scala +run/reify_lazyevaluation.scala +run/reify_maps_newpatmat.scala +run/reify_metalevel_breach_+0_refers_to_1.scala +run/reify_metalevel_breach_-1_refers_to_0_a.scala +run/reify_metalevel_breach_-1_refers_to_0_b.scala +run/reify_nested_outer_refers_to_global.scala +run/reify_newimpl_04.scala +run/reify_newimpl_14.scala +run/reify_newimpl_11.scala +run/reify_newimpl_18.scala +run/reify_newimpl_19.scala +run/reify_newimpl_31.scala +run/reify_newimpl_21.scala +run/reify_newimpl_36.scala +run/reify_newimpl_39.scala +run/reify_newimpl_40.scala +run/reify_newimpl_49.scala +run/reify_newimpl_50.scala +run/reify_newimpl_52.scala +run/reify_renamed_term_basic.scala +run/reify_renamed_term_local_to_reifee.scala +run/reify_renamed_term_overloaded_method.scala +run/reify_renamed_type_basic.scala +run/reify_renamed_type_local_to_reifee.scala +run/reify_renamed_type_spliceable.scala +run/reify_typerefs_1a.scala +run/reify_timeofday.scala +run/reify_renamed_term_t5841.scala + +run/t7521b.scala +run/t8575b.scala +run/t8575c.scala +run/t8944c.scala +run/t9535.scala +run/t9437a +run/t9437b +run/t9814.scala +run/t10009.scala +run/t10075.scala +run/t10075b + +run/t8756.scala +run/inferred-type-constructors-hou.scala +run/trait-static-forwarder +run/SD-235.scala +run/t10026.scala +run/checkinit.scala +run/reflection-clinit +run/reflection-clinit-nested + +# Uses refletction indirectly through +# scala.runtime.ScalaRunTime.replStringOf +run/t6634.scala + +# Using reflection to invoke macros. These tests actually don't require +# or test reflection, but use it to separate compilation units nicely. +# It's a pity we cannot use them + +run/macro-abort-fresh +run/macro-expand-varargs-explicit-over-nonvarargs-bad +run/macro-invalidret-doesnt-conform-to-def-rettype +run/macro-invalidret-nontypeable +run/macro-invalidusage-badret +run/macro-invalidusage-partialapplication +run/macro-invalidusage-partialapplication-with-tparams +run/macro-reflective-ma-normal-mdmi +run/macro-reflective-mamd-normal-mi + +# Using macros, but indirectly creating calls to reflection +run/macro-reify-unreify + +# Using Enumeration in a way we cannot fix + +run/enums.scala +run/t3719.scala +run/t8611b.scala + +# Exceptions that become JavaScriptException + +run/pf-catch.scala +run/exceptions-2.scala +run/exceptions-nest.scala +run/t8601c.scala +run/t8601b.scala +run/inlineHandlers.scala + +# Expecting unsupported exceptions (e.g. ArrayIndexOutOfBounds) +run/optimizer-array-load.scala +run/t6827.scala +run/t8601.scala + +# Expecting exceptions that are linking errors in Scala.js (e.g. NoSuchMethodException) +run/t10334.scala + +# Playing with classfile format + +run/classfile-format-51.scala +run/classfile-format-52.scala + +# Concurrent collections (TrieMap) +# has too much stuff implemented in *.java, so no support +run/triemap-hash.scala + +# Using parallel collections + +run/t5375.scala +run/t4894.scala +run/ctries-new +run/collection-conversions.scala +run/concurrent-map-conversions.scala +run/t4761.scala +run/t7498.scala +run/t6448.scala +run/ctries-old +run/map_java_conversions.scala +run/parmap-ops.scala +run/pc-conversions.scala +run/t4459.scala +run/t4608.scala +run/t4723.scala +run/t4895.scala +run/t6052.scala +run/t6410.scala +run/t6467.scala +run/t6908.scala +run/t8955.scala + +# Using scala.xml + +run/t4124.scala + +# Using Swing + +run/t3613.scala + +# Using the REPL + +run/t4285.scala +run/constant-type.scala +run/repl-bare-expr.scala +run/repl-parens.scala +run/repl-assign.scala +run/t5583.scala +run/treePrint.scala +run/constrained-types.scala +run/repl-power.scala +run/t4710.scala +run/repl-paste.scala +run/repl-reset.scala +run/repl-paste-3.scala +run/t6329_repl.scala +run/t6273.scala +run/repl-paste-2.scala +run/t5655.scala +run/t5072.scala +run/repl-colon-type.scala +run/repl-trim-stack-trace.scala +run/t4594-repl-settings.scala +run/repl-save.scala +run/repl-paste-raw.scala +run/repl-paste-4.scala +run/t7801.scala +run/repl-backticks.scala +run/t6633.scala +run/repl-inline.scala + +# Using the Repl (scala.tools.partest.ReplTest) +run/class-symbol-contravariant.scala +run/lub-visibility.scala +run/macro-bundle-repl.scala +run/macro-repl-basic.scala +run/macro-repl-dontexpand.scala +run/macro-system-properties.scala +run/reflection-equality.scala +run/reflection-repl-elementary.scala +run/reify_newimpl_26.scala +run/repl-out-dir.scala +run/repl-term-macros.scala +run/repl-transcript.scala +run/repl-type-verbose.scala +run/t3376.scala +run/t4025.scala +run/t4172.scala +run/t4216.scala +run/t4542.scala +run/t4671.scala +run/t5256d.scala +run/t5535.scala +run/t5537.scala +run/t5789.scala +run/t6086-repl.scala +run/t6146b.scala +run/t6187.scala +run/t6320.scala +run/t6381.scala +run/t6434.scala +run/t6439.scala +run/t6507.scala +run/t6549.scala +run/t6937.scala +run/t7185.scala +run/t7319.scala +run/t7482a.scala +run/t7634.scala +run/t7747-repl.scala +run/t7805-repl-i.scala +run/tpeCache-tyconCache.scala +run/repl-empty-package +run/repl-javap-def.scala +run/repl-javap-mem.scala +run/repl-javap-outdir +run/repl-javap.scala +run/t6329_repl_bug.scala +run/t4950.scala +run/xMigration.scala +run/t6541-option.scala +run/repl-serialization.scala +run/t9174.scala +run/repl-paste-5.scala +run/repl-no-uescape.scala +run/repl-no-imports-no-predef-classbased.scala +run/repl-implicits-nopredef.scala +run/repl-classbased.scala +run/repl-no-imports-no-predef-power.scala +run/repl-paste-b.scala +run/repl-paste-6.scala +run/repl-implicits.scala +run/repl-no-imports-no-predef.scala +run/repl-paste-raw-b.scala +run/repl-paste-raw-c.scala +run/t9749-repl-dot.scala +run/trait_fields_repl.scala +run/t7139 +run/t9689 +run/trailing-commas.scala +run/t4700.scala +run/t9880-9881.scala +run/repl-kind.scala +run/t10284.scala +run/t9016.scala + +# Using Scala Script (partest.ScriptTest) + +run/t7711-script-args.scala +run/t4625.scala +run/t4625c.scala +run/t4625b.scala + +# Using the compiler API + +run/t2512.scala +run/analyzerPlugins.scala +run/compiler-asSeenFrom.scala +run/t5603.scala +run/t6440.scala +run/t5545.scala +run/existentials-in-compiler.scala +run/global-showdef.scala +run/stream_length.scala +run/annotatedRetyping.scala +run/imain.scala +run/existential-rangepos.scala +run/delambdafy_uncurry_byname_inline.scala +run/delambdafy_uncurry_byname_method.scala +run/delambdafy_uncurry_inline.scala +run/delambdafy_t6555.scala +run/delambdafy_uncurry_method.scala +run/delambdafy_t6028.scala +run/memberpos.scala +run/programmatic-main.scala +run/reflection-names.scala +run/settings-parse.scala +run/sm-interpolator.scala +run/t1501.scala +run/t1500.scala +run/sammy_java8.scala +run/t1618.scala +run/t2464 +run/t4072.scala +run/t5064.scala +run/t5385.scala +run/t5699.scala +run/t5717.scala +run/t5940.scala +run/t6028.scala +run/t6194.scala +run/t6669.scala +run/t6745-2.scala +run/t7096.scala +run/t7271.scala +run/t7337.scala +run/t7398.scala +run/t7569.scala +run/t7852.scala +run/t7817-tree-gen.scala +run/t7825.scala + +# partest.ParserTest +run/t3368.scala +run/t3368-b.scala +run/t3368-c.scala +run/t3368-d.scala +run/t9944.scala + +# partest.DirectTest +run/t6288.scala +run/t6331.scala +run/t6440b.scala +run/t6555.scala +run/t7876.scala +run/typetags_without_scala_reflect_typetag_lookup.scala +run/dynamic-updateDynamic.scala +run/dynamic-selectDynamic.scala +run/dynamic-applyDynamic.scala +run/dynamic-applyDynamicNamed.scala +run/t4841-isolate-plugins +run/large_code.scala +run/macroPlugins-namerHooks.scala +run/t4841-no-plugin.scala +run/t4332.scala +run/t8029.scala +run/t8046 +run/t5905-features.scala +run/t5905b-features.scala +run/large_class.scala +run/t8708_b +run/icode-reader-dead-code.scala +run/t5938.scala +run/t8502.scala +run/t6502.scala +run/t8907.scala +run/t9097.scala +run/macroPlugins-enterStats.scala +run/sbt-icode-interface.scala +run/t8502b.scala +run/t9437c +run/repl-paste-parse.scala +run/t5463.scala +run/t8433.scala +run/sd275.scala +run/sd275-java + +# Using partest.StoreReporterDirectTest +run/t10171 + +# partest.StubErrorMessageTest +run/StubErrorBInheritsFromA.scala +run/StubErrorComplexInnerClass.scala +run/StubErrorHK.scala +run/StubErrorReturnTypeFunction.scala +run/StubErrorReturnTypeFunction2.scala +run/StubErrorReturnTypePolyFunction.scala +run/StubErrorSubclasses.scala +run/StubErrorTypeclass.scala +run/StubErrorTypeDef.scala + +# partest.CompilerTest +run/t8852a.scala + +# partest.ASMConverters +run/t9403 + +# partest.BytecodeTest +run/t7106 +run/t7974 +run/t8601-closure-elim.scala +run/t4788 +run/t4788-separate-compilation + +# partest.SessionTest +run/t8843-repl-xlat.scala +run/t9206.scala +run/t9170.scala +run/t8918-unary-ids.scala +run/t1931.scala +run/t8935-class.scala +run/t8935-object.scala + +# partest.JavapTest +run/t8608-no-format.scala + +# Using .java source files + +run/t4317 +run/t4238 +run/t2296c +run/t4119 +run/t4283 +run/t4891 +run/t6168 +run/t6168b +run/t6240a +run/t6240b +run/t6548 +run/t6989 +run/t7008 +run/t7246 +run/t7246b +run/t7359 +run/t7439 +run/t7455 +run/t7510 +run/t7582-private-within +run/t7582 +run/t7582b +run/t3897 +run/t7374 +run/t3452e +run/t3452g +run/t3452d +run/t3452b +run/t3452a +run/t8442 +run/t8601e +run/t9298 +run/t9298b +run/t9359 +run/t7741a +run/t7741b +run/bcodeInlinerMixed +run/t9268 +run/t9489 +run/t9915 +run/t10059 +run/t1459 +run/t1459generic +run/t3236 +run/t9013 +run/t10231 +run/t10067 +run/t10249 +run/sd143 +run/t4283b +run/t7936 +run/t7936b +run/t9937 +run/t10368 +run/t10334b + +# Using scala-script +run/t7791-script-linenums.scala + +# Suffers from bug in Node.js (https://github.com/joyent/node/issues/7528) +run/range-unit.scala + +# Using scalap +run/scalapInvokedynamic.scala + +# Using Manifests (which use Class.getInterfaces) +run/valueclasses-manifest-existential.scala +run/existentials3-old.scala +run/t2236-old.scala +run/interop_manifests_are_classtags.scala +run/valueclasses-manifest-generic.scala +run/valueclasses-manifest-basic.scala +run/t1195-old.scala +run/t3758-old.scala +run/t4110-old.scala +run/t6246.scala + +# Using ScalaRunTime.stringOf +run/value-class-extractor-seq.scala +run/t3493.scala + +# Custom invoke dynamic node +run/indy-via-macro +run/indy-via-macro-with-dynamic-args + +### Incorrect partests ### +# Badly uses constract of Console.print (no flush) +run/t429.scala +run/t6102.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/BuglistedTests.txt new file mode 100644 index 0000000000..273cb2c2d4 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/BuglistedTests.txt @@ -0,0 +1,7 @@ +# The tests in this file should pass but have never passed so far +# use scala.tools.partest.scalajs.testunknownonly to only run tests +# which are neither in BuglistedTests.txt, WhitelistedTests.txt or +# BlacklistedTests.txt + +# Broken by GCC, filed as #2815 +run/Predef.readLine.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/WhitelistedTests.txt new file mode 100644 index 0000000000..96dd9d2926 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/WhitelistedTests.txt @@ -0,0 +1,3365 @@ +pos/spec-super.scala +pos/t1035.scala +pos/t5897.scala +pos/irrefutable.scala +pos/spec-partialmap.scala +pos/tcpoly_seq.scala +pos/partialfun.scala +pos/t2795-new.scala +pos/clsrefine.scala +pos/t0774 +pos/t1070.scala +pos/t5957 +pos/looping-jsig.scala +pos/t3274.scala +pos/spec-fields-old.scala +pos/t262.scala +pos/t7486.scala +pos/t2261.scala +pos/t6600.scala +pos/t4786.scala +pos/t5406.scala +pos/tcpoly_late_method_params.scala +pos/t2726 +pos/pos-bug1210.scala +pos/t3312.scala +pos/manifest1-old.scala +pos/gadt-gilles.scala +pos/t4842.scala +pos/ted.scala +pos/NoCyclicReference.scala +pos/t3568.scala +pos/t0030.scala +pos/t2635.scala +pos/t7232b +pos/t0017.scala +pos/t812.scala +pos/t2179.scala +pos/t651.scala +pos/spurious-overload.scala +pos/t758.scala +pos/t4760.scala +pos/t1672.scala +pos/mixins.scala +pos/patterns.scala +pos/t1260.scala +pos/t6551.scala +pos/t2060.scala +pos/t6575a.scala +pos/t1318.scala +pos/t4266.scala +pos/t0695 +pos/protected-static +pos/t5738.scala +pos/t1226.scala +pos/t5013 +pos/t6215.scala +pos/t5692b +pos/traits.scala +pos/t2994a.scala +pos/t3371.scala +pos/t613.scala +pos/t6499.scala +pos/xlint1.scala +pos/t1150 +pos/test4a.scala +pos/t2664.scala +pos/t3528.scala +pos/t3174.scala +pos/t6994.scala +pos/t4812.scala +pos/t5777.scala +pos/t5223.scala +pos/t439.scala +pos/t3079.scala +pos/t5829.scala +pos/t0036.scala +pos/scoping2.scala +pos/t4717.scala +pos/t4257.scala +pos/t1210a.scala +pos/getClassType.scala +pos/t5330.scala +pos/t4524.scala +pos/t2945.scala +pos/t6562.scala +pos/t0273.scala +pos/override-object-yes.scala +pos/t7426.scala +pos/t6601 +pos/t3076 +pos/seq-ordering.scala +pos/spec-groups.scala +pos/t296.scala +pos/t5545 +pos/spec-multiplectors.scala +pos/t1789.scala +pos/t2569 +pos/ksbug1.scala +pos/t0599.scala +pos/local-objects.scala +pos/t0081.scala +pos/t5756.scala +pos/t7126.scala +pos/t7716.scala +pos/t2797.scala +pos/t5399.scala +pos/t1101 +pos/t767.scala +pos/contrib467.scala +pos/t7532b +pos/self-type-override.scala +pos/t4853.scala +pos/t839.scala +pos/t5644 +pos/t5853.scala +pos/t5178.scala +pos/unapplyNeedsMemberType.scala +pos/t5390.scala +pos/t6575b.scala +pos/t151.scala +pos/t2665.scala +pos/t5120.scala +pos/erasure-nsquared.scala +pos/arrays3.scala +pos/t3136.scala +pos/inline-access-levels +pos/t3972.scala +pos/t2591.scala +pos/t3486 +pos/variances-flip.scala +pos/annotated-original +pos/typesafecons.scala +pos/stable.scala +pos/t1996.scala +pos/t3037.scala +pos/t1711 +pos/t3374.scala +pos/t0029.scala +pos/t3278.scala +pos/matthias3.scala +pos/t5546.scala +pos/t4020.scala +pos/matthias4.scala +pos/value-class-override-spec.scala +pos/arrays2.scala +pos/t5119.scala +pos/t2613.scala +pos/t4070b.scala +pos/virtpatmat_exist_uncurry.scala +pos/modules1.scala +pos/spec-constr-new.scala +pos/t6335.scala +pos/t675.scala +pos/t0644.scala +pos/t5892.scala +pos/t360.scala +pos/override.scala +pos/t1798.scala +pos/strip-tvars-for-lubbasetypes.scala +pos/hk-infer.scala +pos/t2119.scala +pos/t0231.scala +pos/t1459 +pos/t1381-new.scala +pos/t2610.scala +pos/t2708.scala +pos/t5604b +pos/t3951 +pos/t361.scala +pos/t319.scala +pos/largecasetest.scala +pos/switchUnbox.scala +pos/typetags.scala +pos/java-access-pos +pos/t803.scala +pos/t3898.scala +pos/t5692a +pos/t2421.scala +pos/t1102 +pos/t0654.scala +pos/exhaust_alternatives.scala +pos/t807.scala +pos/t5702-pos-infix-star.scala +pos/t1186 +pos/t1439.scala +pos/t7427.scala +pos/virtpatmat_binding_opt.scala +pos/t247.scala +pos/abstract.scala +pos/gen-traversable-methods.scala +pos/t2795-old.scala +pos/t5639 +pos/t2667.scala +pos/t2405.scala +pos/t1438.scala +pos/t1659.scala +pos/unchecked-a.scala +pos/t3636.scala +pos/t6745.scala +pos/t2809.scala +pos/t7022.scala +pos/t6447.scala +pos/t6367.scala +pos/t5846.scala +pos/lubs.scala +pos/t1987a.scala +pos/spec-arrays.scala +pos/virtpatmat_anonfun_for.scala +pos/listpattern.scala +pos/t5742.scala +pos/test5refine.scala +pos/t5604 +pos/return_thistype.scala +pos/t348plus.scala +pos/t3420.scala +pos/t3440.scala +pos/maxim1.scala +pos/caseClassInMethod.scala +pos/t3833.scala +pos/t6675.scala +pos/t4402 +pos/t5953.scala +pos/t1152 +pos/t0591.scala +pos/t210.scala +pos/t7035.scala +pos/t5769.scala +pos/pmbug.scala +pos/t2331.scala +pos/t5240.scala +pos/t304.scala +pos/annotated-treecopy +pos/t2081.scala +pos/t0904.scala +pos/t7649.scala +pos/t3498-new.scala +pos/contrib701.scala +pos/t6624.scala +pos/t3924.scala +pos/t374.scala +pos/t1642 +pos/t1591_pos.scala +pos/depmet_implicit_oopsla_session_2.scala +pos/t5899.scala +pos/thistype.scala +pos/t4176b.scala +pos/elidable-tparams.scala +pos/lambdalift.scala +pos/nothing_manifest_disambig-old.scala +pos/t372.scala +pos/t5399a.scala +pos/t2782.scala +pos/patmat-extract-tparam.scala +pos/t4114.scala +pos/unapplyVal.scala +pos/t2486.scala +pos/t5877b.scala +pos/t0625.scala +pos/t6358_2.scala +pos/viewtest1.scala +pos/t1237.scala +pos/scala-singleton.scala +pos/t1254 +pos/t5504 +pos/bounds.scala +pos/t3631.scala +pos/t3177.scala +pos/unapplyContexts2.scala +pos/t0438.scala +pos/t1642b.scala +pos/inferbroadtype.scala +pos/t1858.scala +pos/t3731.scala +pos/t6963c.scala +pos/classtag-pos.scala +pos/t6221.scala +pos/t3343.scala +pos/spec-asseenfrom.scala +pos/t604.scala +pos/spec-example1.scala +pos/t0786.scala +pos/annot-inner.scala +pos/t5886.scala +pos/t1056.scala +pos/t294 +pos/spec-Function1.scala +pos/t1836 +pos/spec-private.scala +pos/depmet_implicit_tpbetareduce.scala +pos/exhaust_2.scala +pos/t7532 +pos/t5175.scala +pos/t802.scala +pos/t5809.scala +pos/tcpoly_typesub.scala +pos/t6029.scala +pos/contextbounds-implicits-new.scala +pos/t3480.scala +pos/patterns3.scala +pos/caseaccs.scala +pos/spec-sparsearray-old.scala +pos/patterns1213.scala +pos/spec-traits.scala +pos/t0020.scala +pos/cycle +pos/t5968.scala +pos/typealiases.scala +pos/init.scala +pos/t697.scala +pos/t2693.scala +pos/t2377 +pos/unapplyGeneric.scala +pos/t1385.scala +pos/t3363-old.scala +pos/t1236.scala +pos/t0068.scala +pos/t4052.scala +pos/lambdalift1.scala +pos/z1730.scala +pos/variances-local.scala +pos/virtpatmat_gadt_array.scala +pos/t2421_delitedsl.scala +pos/t5626.scala +pos/t690.scala +pos/t711.scala +pos/t1937 +pos/t3999 +pos/t2305.scala +pos/t2168.scala +pos/t2660.scala +pos/t1693.scala +pos/t2799.scala +pos/t6966.scala +pos/t1001.scala +pos/S5.scala +pos/t0301.scala +pos/t1048.scala +pos/t415.scala +pos/t6386.scala +pos/t2187.scala +pos/hashhash-overloads.scala +pos/t6921.scala +pos/t0227.scala +pos/t6556.scala +pos/t3946 +pos/t1053.scala +pos/t1000.scala +pos/t0586.scala +pos/t7011.scala +pos/t7329.scala +pos/t4975.scala +pos/t1131.scala +pos/t1027.scala +pos/t2913.scala +pos/t3494.scala +pos/t5606.scala +pos/t4716.scala +pos/tcpoly_gm.scala +pos/t4859.scala +pos/t514.scala +pos/lexical.scala +pos/t2624.scala +pos/t4036.scala +pos/t2741 +pos/t703.scala +pos/five-dot-f.scala +pos/t805.scala +pos/strings.scala +pos/t2433 +pos/t6925.scala +pos/t1085.scala +pos/t7461 +pos/t1942 +pos/spec-lists.scala +pos/t3349 +pos/tcpoly_infer_ticket474.scala +pos/t1614 +pos/virtpatmat_reach_const.scala +pos/t2194.scala +pos/t6976 +pos/t1560.scala +pos/t6891.scala +pos/t3883.scala +pos/infersingle.scala +pos/gui.scala +pos/t1164.scala +pos/t3175-pos.scala +pos/t4336.scala +pos/annotations2.scala +pos/proj-rec-test.scala +pos/t2973.scala +pos/t1123.scala +pos/t6205.scala +pos/t5727.scala +pos/t6537.scala +pos/t6712.scala +pos/t3866.scala +pos/t4831.scala +pos/selftails.scala +pos/t397.scala +pos/spec-vector.scala +pos/t7233b.scala +pos/t1391.scala +pos/spec.scala +pos/t3106.scala +pos/contextbounds-implicits-old.scala +pos/packageobjs.scala +pos/michel3.scala +pos/t628.scala +pos/collections.scala +pos/tcpoly_boundedmonad.scala +pos/t7668.scala +pos/t0032.scala +pos/t0069.scala +pos/t4345.scala +pos/t3521 +pos/t3071.scala +pos/tcpoly_infer_easy.scala +pos/t289.scala +pos/t4365 +pos/rangepos-anonapply.scala +pos/t5033.scala +pos/lambda.scala +pos/S8.scala +pos/t6014.scala +pos/t1785.scala +pos/t6034.scala +pos/t7433.scala +pos/imp2-pos.scala +pos/t0504.scala +pos/t1272.scala +pos/t0612 +pos/value-class-override-no-spec.scala +pos/overloaded-unapply.scala +pos/t5859.scala +pos/chang +pos/localmodules.scala +pos/t4237.scala +pos/rangepos-patmat.scala +pos/t1974.scala +pos/t0054.scala +pos/michel2.scala +pos/t0770.scala +pos/t1146.scala +pos/t2441pos.scala +pos/t5099.scala +pos/tcpoly_seq_typealias.scala +pos/t946.scala +pos/tcpoly_infer_ticket1864.scala +pos/t4737 +pos/t7377b.scala +pos/t616.scala +pos/t201.scala +pos/t6355pos.scala +pos/escapes2.scala +pos/t1675.scala +pos/t3890.scala +pos/t6040.scala +pos/spec-tailcall.scala +pos/existentials.scala +pos/t5317.scala +pos/t7782b.scala +pos/t4758.scala +pos/t7296.scala +pos/t6896.scala +pos/cls1.scala +pos/t402.scala +pos/gosh.scala +pos/t2619.scala +pos/javaConversions-2.10-regression.scala +pos/t759.scala +pos/t5259.scala +pos/t5130.scala +pos/t5156.scala +pos/t0905.scala +pos/package-implicit +pos/t2669.scala +pos/trait-parents.scala +pos/virtpatmat_exhaust.scala +pos/patterns1.scala +pos/t1231 +pos/t1751 +pos/t7233.scala +pos/t6022.scala +pos/tcpoly_checkkinds_mix.scala +pos/depmet_implicit_norm_ret.scala +pos/package-case.scala +pos/philippe4.scala +pos/michel6.scala +pos/t4188.scala +pos/t3936 +pos/t1280.scala +pos/t6722.scala +pos/t796.scala +pos/t5542.scala +pos/t3927.scala +pos/t2293.scala +pos/t3800.scala +pos/t7285a.scala +pos/t927.scala +pos/t4494.scala +pos/t3864 +pos/ilya2 +pos/t2940 +pos/S1.scala +pos/tcpoly_wildcards.scala +pos/tryexpr.scala +pos/t6089b.scala +pos/depmet_implicit_oopsla_zipwith.scala +pos/t245.scala +pos/t6146.scala +pos/t1782 +pos/t851.scala +pos/spec-thistype.scala +pos/tcpoly_poly.scala +pos/t6815_import.scala +pos/t4649.scala +pos/t0453.scala +pos/t5020.scala +pos/ilya +pos/t2435.scala +pos/t1279a.scala +pos/t1957.scala +pos/gadts2.scala +pos/t3567 +pos/Z.scala +pos/t1203b +pos/nested2.scala +pos/t1896 +pos/viewtest2.scala +pos/t5541.scala +pos/existentials-harmful.scala +pos/t4063.scala +pos/t6485a +pos/t1208.scala +pos/t5041.scala +pos/unapplyComplex.scala +pos/t3384.scala +pos/t4112.scala +pos/t788.scala +pos/hklub0.scala +pos/t757.scala +pos/t1197 +pos/t359.scala +pos/t5667.scala +pos/t1107a.scala +pos/virtpatmat_castbinder.scala +pos/t267.scala +pos/t3419 +pos/t3861.scala +pos/t6797.scala +pos/spec-localdefs.scala +pos/t3404 +pos/t4457_1.scala +pos/matthias5.scala +pos/spec-polymeth.scala +pos/kinds.scala +pos/t2310.scala +pos/t6552.scala +pos/valdefs.scala +pos/hkarray.scala +pos/homonym.scala +pos/t1235 +pos/t3429 +pos/t0053.scala +pos/depmet_implicit_chaining_zw.scala +pos/virtpatmat_partialfun_nsdnho.scala +pos/t6664.scala +pos/ticket2251.scala +pos/t3495.scala +pos/super +pos/t121.scala +pos/javaConversions-2.10-ambiguity.scala +pos/t1803.scala +pos/t5877.scala +pos/t0085.scala +pos/t3582.scala +pos/t2939.scala +pos/t1422_pos.scala +pos/manifest1-new.scala +pos/t7505.scala +pos/t5720-ownerous.scala +pos/misc-unapply_pos.scala +pos/tcpoly_variance_pos.scala +pos/t5127.scala +pos/t6123-explaintypes-implicits.scala +pos/t2764 +pos/presuperContext.scala +pos/spec-simple.scala +pos/t3120 +pos/tcpoly_infer_ticket716.scala +pos/tcpoly_bounds1.scala +pos/t7369.scala +pos/imports-pos.scala +pos/t5654.scala +pos/t0123.scala +pos/raw-map +pos/t5330b.scala +pos/t6485b +pos/t6072.scala +pos/t5692c.scala +pos/tcpoly_param_scoping.scala +pos/t6204-b.scala +pos/attachments-typed-another-ident +pos/t5359.scala +pos/ticket2197.scala +pos/t720.scala +pos/t2130-2.scala +pos/t2260.scala +pos/t0304.scala +pos/t464.scala +pos/spec-maps.scala +pos/annotDepMethType.scala +pos/t6117.scala +pos/t911.scala +pos/t757a.scala +pos/t2504.scala +pos/t1381-old.scala +pos/t1232 +pos/needstypeearly.scala +pos/moduletrans.scala +pos/t4957.scala +pos/kinzer.scala +pos/t318.scala +pos/widen-existential.scala +pos/t0095.scala +pos/t566.scala +pos/tcpoly_overloaded.scala +pos/t7516 +pos/t7232 +pos/t698.scala +pos/t0002.scala +pos/t0288 +pos/t2994b.scala +pos/cls.scala +pos/t3622 +pos/t3671.scala +pos/tcpoly_subst.scala +pos/t5703 +pos/depmet_implicit_oopsla_session_simpler.scala +pos/t5022.scala +pos/builders.scala +pos/spec-foo.scala +pos/t756.scala +pos/t1569.scala +pos/implicit-unwrap-tc.scala +pos/t3688.scala +pos/t5198.scala +pos/t432.scala +pos/t6022b.scala +pos/channels.scala +pos/t1075.scala +pos/null.scala +pos/t1840 +pos/t6479.scala +pos/t6311.scala +pos/t0039.scala +pos/t1119.scala +pos/t573.scala +pos/t1136.scala +pos/t3938 +pos/spec-sealed.scala +pos/tcpoly_return_overriding.scala +pos/t3582b.scala +pos/t229.scala +pos/t3498-old.scala +pos/t531.scala +pos/t4545.scala +pos/t6651.scala +pos/t2133.scala +pos/tinondefcons.scala +pos/t6358.scala +pos/t7690.scala +pos/t5779-numeq-warn.scala +pos/list-extractor.scala +pos/t892.scala +pos/t2127.scala +pos/t7180.scala +pos/nullary_poly.scala +pos/virtpatmat_exist3.scala +pos/t1176 +pos/spec-funs.scala +pos/specialize10.scala +pos/t6514.scala +pos/exhaustive_heuristics.scala +pos/t0066.scala +pos/t460.scala +pos/t2130-1.scala +pos/t124.scala +pos/annotations.scala +pos/pat_gilles.scala +pos/array-interfaces.scala +pos/t6210.scala +pos/t3792.scala +pos/implicits-old.scala +pos/t389.scala +pos/t115.scala +pos/virtpatmat_exhaust_unchecked.scala +pos/scoping3.scala +pos/t6033.scala +pos/depmet_implicit_oopsla_session.scala +pos/t602.scala +pos/test5.scala +pos/t611.scala +pos/t5932.scala +pos/t4910.scala +pos/unapplySeq.scala +pos/t344.scala +pos/t3363-new.scala +pos/t4018.scala +pos/t4553.scala +pos/t5082.scala +pos/t3869.scala +pos/t3836.scala +pos/tcpoly_typeapp.scala +pos/t1409 +pos/nonlocal-unchecked.scala +pos/t0082.scala +pos/z1720.scala +pos/t7232c +pos/t2018.scala +pos/t3943 +pos/t2187-2.scala +pos/unicode-decode.scala +pos/t4757 +pos/t0710.scala +pos/t0305.scala +pos/t160.scala +pos/t7591 +pos/simplelists.scala +pos/List1.scala +pos/t516.scala +pos/t6648.scala +pos/t5165 +pos/t0055.scala +pos/t4744 +pos/t7377 +pos/t5726.scala +pos/t0091.scala +pos/t6595.scala +pos/compile.scala +pos/depmet_1_pos.scala +pos/t7364 +pos/philippe3.scala +pos/spec-doubledef-old.scala +pos/t4651.scala +pos/tcpoly_infer_implicit_tuple_wrapper.scala +pos/t6274.scala +pos/tcpoly_infer_explicit_tuple_wrapper.scala +pos/ticket2201.scala +pos/spec-fields-new.scala +pos/optmatch.scala +pos/t7517.scala +pos/t3560.scala +pos/t0165.scala +pos/t0872.scala +pos/t522.scala +pos/t2234.scala +pos/t5031_2.scala +pos/tcpoly_method.scala +pos/t6482.scala +pos/pos-bug1241.scala +pos/implicits-new.scala +pos/t2484.scala +pos/t2425.scala +pos/t1049.scala +pos/michel4.scala +pos/t5958.scala +pos/virtpatmat_instof_valuetype.scala +pos/spec-t6286.scala +pos/t873.scala +pos/t3137.scala +pos/Transactions.scala +pos/t0064.scala +pos/t7486-named.scala +pos/t5444.scala +pos/simple-exceptions.scala +pos/t1006.scala +pos/t7200b.scala +pos/t3777.scala +pos/t4840.scala +pos/t211.scala +pos/nullary.scala +pos/michel1.scala +pos/t5031_3 +pos/typealias_dubious.scala +pos/spec-doubledef-new.scala +pos/philippe1.scala +pos/thistypes.scala +pos/t3570.scala +pos/t6516.scala +pos/context.scala +pos/t3808.scala +pos/philippe2.scala +pos/constfold.scala +pos/t1292.scala +pos/t1147.scala +pos/t404.scala +pos/t4430.scala +pos/A.scala +pos/spec-partially.scala +pos/t5796.scala +pos/t2409 +pos/t284-pos.scala +pos/t5313.scala +pos/t2464 +pos/t1591b.scala +pos/hk-match +pos/t595.scala +pos/t6846.scala +pos/t6162-inheritance.scala +pos/relax_implicit_divergence.scala +pos/patterns2.scala +pos/t4692.scala +pos/t3837.scala +pos/t661.scala +pos/t2810.scala +pos/depexists.scala +pos/virtpatmat_exist4.scala +pos/t5245.scala +pos/t7190.scala +pos/isApplicableSafe.scala +pos/t6204-a.scala +pos/t0076.scala +pos/t1756.scala +pos/t1745 +pos/t6091.scala +pos/t0154.scala +pos/t530.scala +pos/t2094.scala +pos/t1034.scala +pos/t6084.scala +pos/t2454.scala +pos/t2956 +pos/tcpoly_ticket2096.scala +pos/attachments-typed-ident +pos/polymorphic-case-class.scala +pos/t252.scala +pos/spec-constr-old.scala +pos/t2421c.scala +pos/t122.scala +pos/t6574.scala +pos/t3859.scala +pos/spec-params-old.scala +pos/t1196 +pos/t4593.scala +pos/t596.scala +pos/t615.scala +pos/t7689.scala +pos/t3960.scala +pos/t3986.scala +pos/exbound.scala +pos/t2545.scala +pos/t1722 +pos/t159.scala +pos/t3272.scala +pos/t6301.scala +pos/t2794.scala +pos/t3048.scala +pos/t4970.scala +pos/t607.scala +pos/FPTest.scala +pos/test1.scala +pos/t4176.scala +pos/t112606A.scala +pos/t2183.scala +pos/t430-feb09.scala +pos/t6275.scala +pos/t1832.scala +pos/t8965.scala +pos/t7596b +pos/t8900.scala +pos/t9008.scala +pos/t7704.scala +pos/t7459c.scala +pos/sammy_override.scala +pos/t8828.scala +pos/t8868c +pos/t7459d.scala +pos/t8267.scala +pos/t8844.scala +pos/t8868a +pos/t8894.scala +pos/t7459a.scala +pos/t7596c +pos/t8498.scala +pos/t8868b +pos/t5413.scala +pos/t8781 +pos/t8934a +pos/t8310.scala +pos/t3439.scala +pos/t6582_exhaust_big.scala +pos/t8954 +pos/t5217.scala +pos/t7459b.scala +pos/t9018.scala +pos/sammy_exist.scala +pos/t8893.scala +pos/t7596 +pos/t8793.scala +pos/sammy_overload.scala +pos/t6051.scala +pos/t7683-stop-after-parser +pos/t7750.scala +pos/t5454.scala +pos/t8962.scala +pos/t8947 +pos/t8719 +pos/t8410.scala +pos/patmat-suppress.scala +pos/t8999.scala +pos/t8743.scala +pos/t9157.scala +pos/t8801.scala +pos/t9086.scala +pos/t9050.scala +pos/t9135.scala +pos/t9116.scala +pos/t5154.scala +pos/t3368.scala +pos/t9321.scala +pos/t9285.scala +pos/t8861.scala +pos/t9020.scala +pos/jesper.scala +pos/t9356 +pos/virtpatmat_exhaust_big.scala +pos/t9239 +pos/t9111-inliner-workaround + +neg/volatile_no_override.scala +neg/t800.scala +neg/t5426.scala +neg/t2462a.scala +neg/t2641.scala +neg/classtags_dont_use_typetags.scala +neg/t5031 +neg/t2275b.scala +neg/macro-qmarkqmarkqmark.scala +neg/t4879.scala +neg/t5956.scala +neg/t4196.scala +neg/reify_ann2b.scala +neg/t6666b.scala +neg/warn-unused-privates.scala +neg/t6928.scala +neg/t6337.scala +neg/sealed-java-enums.scala +neg/t563.scala +neg/t900.scala +neg/deadline-inf-illegal.scala +neg/t766.scala +neg/t5429.scala +neg/overloaded-implicit.scala +neg/t875.scala +neg/abstract-class-error +neg/unchecked2.scala +neg/predef-masking.scala +neg/viewtest.scala +neg/macro-noexpand +neg/varargs.scala +neg/t963b.scala +neg/t909.scala +neg/sensitive2.scala +neg/t5390b.scala +neg/abstraction-from-volatile-type-error.scala +neg/macro-exception +neg/t4431.scala +neg/t5689.scala +neg/valueclasses.scala +neg/overload.scala +neg/t0204.scala +neg/t908.scala +neg/t750 +neg/patmatexhaust.scala +neg/macro-invalidusage-badtargs +neg/t1168.scala +neg/t5761.scala +neg/t0503.scala +neg/t7235.scala +neg/t1215.scala +neg/primitive-sigs-1 +neg/t5578.scala +neg/names-defaults-neg-warn.scala +neg/t6436b.scala +neg/t3098 +neg/t910.scala +neg/parstar.scala +neg/t4568.scala +neg/newpat_unreachable.scala +neg/t1181.scala +neg/t5903c +neg/t7294.scala +neg/t4091.scala +neg/t5452-old.scala +neg/t5696.scala +neg/t0209.scala +neg/t2910.scala +neg/t7388.scala +neg/noMember2.scala +neg/no-predef.scala +neg/t6952.scala +neg/t1909b.scala +neg/abstract-report2.scala +neg/t5318.scala +neg/t6074.scala +neg/t7171.scala +neg/abstract-vars.scala +neg/unchecked-impossible.scala +neg/variances-refinement.scala +neg/t3453.scala +neg/t5189.scala +neg/t4302.scala +neg/xmltruncated7.scala +neg/t8217-local-alias-requires-rhs.scala +neg/t7602.scala +neg/t8869.scala +neg/t9008.scala +neg/sammy_error_exist_no_crash.scala +neg/t2866.scala +neg/t8597b.scala +neg/t5691.scala +neg/t8534b.scala +neg/t5091.scala +neg/literals.scala +neg/t8534.scala +neg/t8890.scala +neg/t9008b.scala +neg/t8731.scala +neg/t8291.scala +neg/t8597.scala +neg/t5639b +neg/t6582_exhaust_big.scala +neg/t8841.scala +neg/t9041.scala +neg/t9093.scala +neg/t7623.scala +neg/t9231.scala +neg/t9286b.scala +neg/t9273.scala +neg/t9127.scala +neg/t9286c.scala +neg/t9286a.scala +neg/virtpatmat_exhaust_big.scala +neg/inlineMaxSize.scala + +run/t7249.scala +run/t3563.scala +run/t6111.scala +run/classtags_multi.scala +run/t5201.scala +run/checked.scala +run/valueclasses-classtag-basic.scala +run/t7171.scala +run/t5053.scala +run/t4535.scala +run/t5923d +run/t7291.scala +run/partialfun.scala +run/macro-term-declared-in-package-object +run/mapValues.scala +run/gadts.scala +run/t2386-new.scala +run/virtpatmat_stringinterp.scala +run/t657.scala +run/t0017.scala +run/t5713 +run/t576.scala +run/t3580.scala +run/virtpatmat_partial.scala +run/t6646.scala +run/mixins.scala +run/t1672.scala +run/macro-expand-implicit-macro-has-implicit +run/tuple-match.scala +run/t7039.scala +run/virtpatmat_opt_sharing.scala +run/virtpatmat_casting.scala +run/t2176.scala +run/macro-impl-relaxed +run/intmap.scala +run/t751.scala +run/t1591.scala +run/macro-typecheck-implicitsdisabled +run/t6911.scala +run/t5604.scala +run/macro-term-declared-in-default-param +run/collection-stacks.scala +run/multi-array.scala +run/t4560b.scala +run/buffer-slice.scala +run/t5629.scala +run/t6690.scala +run/matchonstream.scala +run/t3603.scala +run/lazy-exprs.scala +run/macro-quasiquotes +run/Course-2002-13.scala +run/t6337a.scala +run/exoticnames.scala +run/t0936.scala +run/runtime-richChar.scala +run/t6272.scala +run/t7215.scala +run/t1939.scala +run/ReverseSeqView.scala +run/lazy-leaks.scala +run/t0048.scala +run/t3994.scala +run/t2241.scala +run/t627.scala +run/t5966.scala +run/getClassTest-valueClass.scala +run/t3619.scala +run/t1300.scala +run/t2177.scala +run/t3760.scala +run/t1829.scala +run/macro-expand-implicit-macro-is-view +run/t889.scala +run/QueueTest.scala +run/t4537 +run/t3699.scala +run/t1192.scala +run/macro-expand-tparams-bounds +run/macro-expand-nullary-generic +run/t1434.scala +run/t6443-varargs.scala +run/macro-term-declared-in-trait +run/t4080.scala +run/matcharraytail.scala +run/infiniteloop.scala +run/t5733.scala +run/virtpatmat_nested_lists.scala +run/t5158.scala +run/t6695.scala +run/t6070.scala +run/t4558.scala +run/exc2.scala +run/patmat-behavior-2.scala +run/overloads.scala +run/t6957.scala +run/transform.scala +run/t5500.scala +run/t6663.scala +run/castsingleton.scala +run/t4147.scala +run/virtpatmat_staging.scala +run/t4565_1.scala +run/t5588.scala +run/run-bug4840.scala +run/t3496.scala +run/t5867.scala +run/search.scala +run/t3112.scala +run/hashsetremove.scala +run/t6443.scala +run/macro-expand-tparams-prefix +run/contrib674.scala +run/t3508.scala +run/t4300.scala +run/virtpatmat_typed.scala +run/macro-term-declared-in-class-object +run/map_test.scala +run/t5040.scala +run/t4827b.scala +run/lift-and-unlift.scala +run/t6574b.scala +run/t7240 +run/t3984.scala +run/virtpatmat_tailcalls_verifyerror.scala +run/macro-term-declared-in-class-class +run/emptypf.scala +run/t6104.scala +run/t2818.scala +run/t3761-overload-byname.scala +run/t2526.scala +run/phantomValueClass.scala +run/t3126.scala +run/arybufgrow.scala +run/t3980.scala +run/t7375b +run/t6077_patmat_cse_irrefutable.scala +run/classmanifests_new_core.scala +run/t3395.scala +run/name-based-patmat.scala +run/inliner-infer.scala +run/t5171.scala +run/t3726.scala +run/null-hash.scala +run/t4027.scala +run/t2544.scala +run/patmatnew.scala +run/t5923b +run/t7242.scala +run/classtags_core.scala +run/streamWithFilter.scala +run/t3038b.scala +run/macro-expand-varargs-explicit-over-nonvarargs-good +run/macro-divergence-spurious +run/macro-duplicate +run/t2958.scala +run/patch-boundary.scala +run/t2333.scala +run/lazy-override-run.scala +run/macro-quasiinvalidbody-c +run/t5037.scala +run/takeAndDrop.scala +run/t6126.scala +run/t0883.scala +run/t7617a +run/t4171.scala +run/empty-array.scala +run/t7198.scala +run/t493.scala +run/genericValueClass.scala +run/t0677-old.scala +run/t1373.scala +run/t4461.scala +run/t6011b.scala +run/t7584.scala +run/t3935.scala +run/t6928-run.scala +run/t744.scala +run/t3241.scala +run/blame_eye_triple_eee-double.scala +run/t3829.scala +run/t5577.scala +run/t5914.scala +run/t601.scala +run/t5610.scala +run/macro-basic-mamd-mi +run/t6150.scala +run/stringbuilder.scala +run/t7290.scala +run/t6888.scala +run/t6327.scala +run/virtpatmat_unapplyseq.scala +run/t4656.scala +run/macro-term-declared-in-method +run/macro-expand-implicit-macro-is-implicit +run/blame_eye_triple_eee-float.scala +run/t4482.scala +run/t5488.scala +run/matchemptyarray.scala +run/t3714.scala +run/richWrapperEquals.scala +run/t5328.scala +run/stream_flatmap_odds.scala +run/implicitclasses.scala +run/t6394b +run/complicatedmatch.scala +run/valueclasses-classmanifest-basic.scala +run/unreachable.scala +run/caseclasses.scala +run/withIndex.scala +run/exc1.scala +run/amp.scala +run/t1423.scala +run/t594.scala +run/t6353.scala +run/byname.scala +run/vector1.scala +run/t5879.scala +run/t1048.scala +run/t5080.scala +run/t4190.scala +run/caseClassEquality.scala +run/macro-enclosures +run/collections-toSelf.scala +run/implicits.scala +run/finalvar.scala +run/lazy-locals.scala +run/t7231.scala +run/t0508.scala +run/t6628.scala +run/t6406-regextract.scala +run/t0911.scala +run/t4013c.scala +run/t3502.scala +run/t5648.scala +run/retclosure.scala +run/t2857.scala +run/t4859.scala +run/t5162.scala +run/t3038.scala +run/classof.scala +run/t4062.scala +run/unapplyArray.scala +run/t4297.scala +run/t5923a +run/t1537.scala +run/boolexprs.scala +run/valueclasses-classtag-generic.scala +run/macro-term-declared-in-anonymous +run/tcpoly_monads.scala +run/t5407.scala +run/scan.scala +run/forvaleq.scala +run/null-and-intersect.scala +run/t7047 +run/t0607.scala +run/sequenceComparisons.scala +run/t4396.scala +run/macro-undetparams-consfromsls +run/t2029.scala +run/t1220.scala +run/option-fold.scala +run/t5284c.scala +run/macro-auto-duplicate +run/t3529.scala +run/t4697.scala +run/t2251.scala +run/t5300.scala +run/virtpatmat_valdef.scala +run/t2147.scala +run/virtpatmat_extends_product.scala +run/list_map.scala +run/t1333.scala +run/matchbytes.scala +run/valueclasses-classmanifest-existential.scala +run/records.scala +run/t3088.scala +run/macro-def-path-dependent +run/t6443-by-name.scala +run/t1044.scala +run/delay-good.scala +run/case-class-23.scala +run/weakconform.scala +run/patmat-bind-typed.scala +run/t4835.scala +run/t3097.scala +run/t405.scala +run/existentials.scala +run/t2876.scala +run/t4809.scala +run/t1427.scala +run/t6135.scala +run/t3575.scala +run/t5688.scala +run/t6900.scala +run/macro-expand-unapply-a +run/t6677b.scala +run/t7375a.scala +run/t7300.scala +run/typed-annotated +run/elidable-noflags.scala +run/t0042.scala +run/t3050.scala +run/t4536.scala +run/NestedClasses.scala +run/t3877.scala +run/seqlike-kmp.scala +run/t5907.scala +run/t266.scala +run/missingparams.scala +run/t2255.scala +run/t3488.scala +run/t3950.scala +run/typealias_overriding.scala +run/constant-optimization.scala +run/t7507.scala +run/t6090.scala +run/t4582.scala +run/macro-term-declared-in-class +run/macro-typecheck-macrosdisabled2 +run/t3425.scala +run/t4935.scala +run/t3326.scala +run/boolord.scala +run/t1141.scala +run/virtpatmat_unapply.scala +run/t5971.scala +run/t3651.scala +run/macro-sip19-revised +run/pure-args-byname-noinline.scala +run/preinits.scala +run/t5532.scala +run/concat-two-strings.scala +run/t3269.scala +run/macro-impl-default-params +run/t2162.scala +run/matchonseq.scala +run/t5428.scala +run/macro-expand-overload +run/t4660.scala +run/enrich-gentraversable.scala +run/macro-expand-override +run/t4054.scala +run/t4753.scala +run/macro-typecheck-macrosdisabled +run/t2308a.scala +run/duplicate-meth.scala +run/interop_classtags_are_classmanifests.scala +run/t3232.scala +run/t2075.scala +run/virtpatmat_partial_backquoted.scala +run/try-2.scala +run/macro-openmacros +run/macro-undetparams-macroitself +run/t6318_derived.scala +run/deprecate-early-type-defs.scala +run/dead-code-elimination.scala +run/t4827.scala +run/Course-2002-07.scala +run/slice-strings.scala +run/t6292.scala +run/t6206.scala +run/t1042.scala +run/t1718.scala +run/t2074_2.scala +run/arraycopy.scala +run/indexedSeq.scala +run/macro-term-declared-in-implicit-class +run/t3511.scala +run/t6290.scala +run/distinct.scala +run/virtpatmat_alts.scala +run/valueclasses-pavlov.scala +run/exceptions.scala +run/t1368.scala +run/t5856.scala +run/t6968.scala +run/names-defaults.scala +run/macro-expand-tparams-implicit +run/t5881.scala +run/t3540.scala +run/virtpatmat_try.scala +run/t7181.scala +run/value-class-extractor.scala +run/value-class-extractor-2.scala +run/t3150.scala +run/exc.scala +run/delay-bad.scala +run/infix.scala +run/t1309.scala +run/t6370.scala +run/t6725-2.scala +run/macro-impl-tparam-typetag-is-optional +run/macro-term-declared-in-block +run/matchnull.scala +run/t2127.scala +run/t7325.scala +run/groupby.scala +run/t3932.scala +run/t4871.scala +run/longmap.scala +run/t1524.scala +run/t6187b.scala +run/kmpSliceSearch.scala +run/t7088.scala +run/t5804.scala +run/stringbuilder-drop.scala +run/t5753_1 +run/t9223.scala +run/function-null-unbox.scala +run/t9223b.scala +run/disable-assertions.scala +run/valueClassSelfType.scala +run/indylambda-boxing +run/t9219.scala + +pos/cyclics-pos.scala +pos/cfcrash.scala +pos/tcpoly_higherorder_bound_method.scala +pos/t5084.scala +pos/macro-qmarkqmarkqmark.scala +pos/t7785.scala +pos/nested.scala +pos/t3152.scala +pos/t5031 +pos/t6925b.scala +pos/t1107b +pos/t5012.scala +pos/virtpatmat_obj_in_case.scala +pos/t4938.scala +pos/t3856.scala +pos/spec-cyclic.scala +pos/aliases.scala +pos/typerep_pos.scala +pos/t119.scala +pos/t1050.scala +pos/t3670.scala +pos/t6145.scala +pos/t7315.scala +pos/t5930.scala +pos/t789.scala +pos/t5071.scala +pos/t4731.scala +pos/t4547.scala +pos/t2038.scala +pos/testCoercionThis.scala +pos/t2444.scala +pos/t5744 +pos/t780.scala +pos/t1722-A.scala +pos/virtpatmat_exist1.scala +pos/t6225.scala +pos/t762.scala +pos/t0204.scala +pos/rebind.scala +pos/spec-short.scala +pos/comp-rec-test.scala +pos/lub-dealias-widen.scala +pos/t1168.scala +pos/modules.scala +pos/t4220.scala +pos/t4070.scala +pos/t175.scala +pos/t2500.scala +pos/t5029.scala +pos/itay.scala +pos/t4202.scala +pos/t1987b +pos/t3534.scala +pos/infer2-pos.scala +pos/spec-sparsearray-new.scala +pos/t7091.scala +pos/ticket0137.scala +pos/collectGenericCC.scala +pos/t640.scala +pos/t4305.scala +pos/extractor-types.scala +pos/t3880.scala +pos/spec-annotations.scala +pos/t3577.scala +pos/compile1.scala +pos/spec-t3497.scala +pos/hkrange.scala +pos/t287.scala +pos/t6008.scala +pos/t4432.scala +pos/CustomGlobal.scala +pos/patmat.scala +pos/t2413 +pos/t2910.scala +pos/t592.scala +pos/t6245 +pos/infer.scala +pos/t7228.scala +pos/compound.scala +pos/attributes.scala +pos/t6771.scala +pos/t1090.scala +pos/t684.scala +pos/t577.scala +pos/t4273.scala +pos/t6278-synth-def.scala +pos/t6184.scala +neg/t0214.scala +neg/t4842.scala +neg/t6214.scala +neg/reify_nested_inner_refers_to_local.scala +neg/t576.scala +neg/t5969.scala +neg/tcpoly_variance.scala +neg/t7509.scala +neg/mixins.scala +neg/parent-inherited-twice-error.scala +neg/macro-abort +neg/constructor-init-order.scala +neg/t6042.scala +neg/t0590.scala +neg/t4221.scala +neg/t6263.scala +neg/t783.scala +neg/t5554.scala +neg/macro-invalidsig-params-badtype +neg/multi-array.scala +neg/raw-types-stubs +neg/spec-overrides.scala +neg/t836.scala +neg/t7289_status_quo.scala +neg/t5675.scala +neg/macro-quasiquotes +neg/t6667.scala +neg/t6597.scala +neg/t6264.scala +neg/t0345.scala +neg/t7294b.scala +neg/t5340.scala +neg/t2144.scala +neg/t1010.scala +neg/t1838.scala +neg/t5189b.scala +neg/reify_metalevel_breach_-1_refers_to_1.scala +neg/t6601 +neg/wellkinded_wrongarity.scala +neg/t3909.scala +neg/t876.scala +neg/t5390.scala +neg/unit2anyref.scala +neg/t0351.scala +neg/t5120.scala +neg/t1038.scala +neg/t5878.scala +neg/qualifying-class-error-2.scala +neg/t3816.scala +neg/tailrec.scala +neg/volatile.scala +neg/t944.scala +neg/t1705.scala +neg/t3977.scala +neg/t5553_2.scala +neg/t5318c.scala +neg/overload-msg.scala +neg/t5440.scala +neg/t6335.scala +neg/compile-time-only-b.scala +neg/t501.scala +neg/override.scala +neg/t663.scala +neg/t5892.scala +neg/t1980.scala +neg/macro-false-deprecation-warning +neg/t585.scala +neg/t3776.scala +neg/interop_classtags_arenot_manifests.scala +neg/t4044.scala +neg/macro-invalidusage-nontypeable +neg/t500.scala +neg/t4877.scala +neg/t5357.scala +neg/interop_abstypetags_arenot_manifests.scala +neg/t4460a.scala +neg/t5318b.scala +neg/t4440.scala +neg/t6663.scala +neg/t6357.scala +neg/gadts1.scala +neg/cyclics.scala +neg/t5060.scala +neg/scopes.scala +run/t4013.scala +run/macro-expand-tparams-explicit +run/tuples.scala +run/t5753_2 +run/t0528.scala +run/t5105.scala +run/t7341.scala +run/t3670.scala +run/t2594_tcpoly.scala +run/t3895.scala +run/t0668.scala +run/slices.scala +run/t6666a.scala +run/valueclasses-classmanifest-generic.scala +run/t2316_run.scala +run/t3004.scala +run/viewtest.scala +run/t6481.scala +run/t0005.scala +run/t4766.scala +run/t5500b.scala +run/t7407b.scala +run/backreferences.scala +run/arrayview.scala +run/t629.scala +run/t5903c +run/unittest_collection.scala +run/spec-nlreturn.scala +run/macro-term-declared-in-object-object +run/triple-quoted-expr.scala +run/t5937.scala +run/t6011c.scala +run/macro-expand-implicit-argument +run/try.scala +run/t1987b +run/t6089.scala +run/macro-range +run/t2524.scala +run/t4770.scala +run/virtpatmat_unapplyprod.scala +run/t1535.scala +run/ctor-order.scala +pos/t5210.scala +pos/t5384.scala +pos/rangepos.scala +pos/t443.scala +pos/t1480.scala +pos/t116.scala +pos/seqtest2.scala +pos/scoping1.scala +pos/t4269.scala +pos/lookupswitch.scala +pos/t3642 +pos/t5706.scala +pos/t7264 +pos/t0031.scala +pos/macro-deprecate-dont-touch-backquotedidents.scala +pos/t6815.scala +pos/test4refine.scala +pos/michel5.scala +pos/t0851.scala +pos/t1185.scala +pos/sudoku.scala +pos/t7520.scala +pos/t6208.scala +pos/t3411.scala +pos/t295.scala +pos/S3.scala +pos/t0674.scala +pos/t6664b.scala +pos/variances_pos.scala +pos/liftcode_polymorphic.scala +pos/t3174b.scala +pos/t7232d +pos/t578.scala +pos/implicit-infix-ops.scala +pos/t4363.scala +pos/t532.scala +pos/exponential-spec.scala +pos/t599.scala +pos/t5862.scala +pos/t4603 +pos/t3676.scala +pos/t1357.scala +pos/native-warning.scala +pos/t1230 +pos/t6028 +pos/t4275.scala +pos/overloaded_extractor_and_regular_def.scala +pos/t4205 +pos/matthias1.scala +pos/testcast.scala +pos/generic-sigs.scala +pos/t0093.scala +pos/specializes-sym-crash.scala +pos/t0061.scala +pos/t2429.scala +pos/t694.scala +pos/javaReadsSigs +pos/t2023.scala +pos/t704.scala +pos/t2208_pos.scala +pos/t5137.scala +pos/t2683.scala +pos/t0049.scala +pos/t1029 +pos/t4243.scala +pos/typerep-stephane.scala +pos/t177.scala +pos/t5967.scala +pos/t430.scala +pos/virtpatmat_infer_single_1.scala +pos/pat_iuli.scala +pos/t1071.scala +pos/t7226.scala +pos/t1843.scala +pos/t419.scala +pos/t7364b +pos/t1159.scala +pos/t5305.scala +pos/t7694.scala +pos/t6047.scala +pos/t3578.scala +pos/t2082.scala +pos/setter-not-implicit.scala +pos/t1133.scala +pos/t3862.scala +pos/t942 +pos/nothing_manifest_disambig-new.scala +pos/iterator-traversable-mix.scala +pos/eta.scala +pos/test4.scala +pos/t2691.scala +pos/t4502.scala +pos/t7183.scala +pos/protected-t1010.scala +pos/X.scala +pos/virtpatmat_exist2.scala +pos/t4911.scala +pos/t3477.scala +pos/t4173.scala +pos/t7782.scala +pos/t2399.scala +pos/virtpatmat_alts_subst.scala +pos/propagate.scala +pos/t2421b_pos.scala +pos/t183.scala +pos/t7033.scala +pos/t3612.scala +pos/t5330c.scala +pos/t3020.scala +pos/t4869.scala +pos/t3373.scala +pos/spec-params-new.scala +pos/t3672.scala +pos/t4501.scala +pos/t1565.scala +pos/t3774.scala +pos/t6942 +pos/t845.scala +pos/t3240.scala + +neg/t3275.scala +neg/t421.scala +neg/t5702-neg-bad-brace.scala +neg/t3663 +neg/badtok-1.scala +neg/t677.scala +neg/t7756b.scala +neg/t6534.scala +neg/t6276.scala +neg/t5762.scala +neg/abstract.scala +neg/t2405.scala +neg/t0418.scala +neg/t5390c.scala +neg/lazyvals.scala +neg/lubs.scala +neg/abstract-report.scala +neg/t4163.scala +neg/t5702-neg-bad-and-wild.scala +neg/macro-invalidret +neg/t6728.scala +neg/t5152.scala +neg/t1432.scala +neg/abstract-inaccessible.scala +neg/import-precedence.scala +neg/t2462b.scala +neg/macro-invalidusage-presuper +neg/specification-scopes +neg/t6048.scala +neg/t4079 +neg/macro-basic-mamdmi +neg/t7020.scala +neg/t3015.scala +neg/t0207.scala +neg/t2296b +neg/t0673 +neg/t3761-overload-byname.scala +neg/t6675.scala +neg/t5529.scala +neg/sensitive.scala +neg/t742.scala +neg/t5067.scala +neg/t6162-overriding.scala +neg/variances.scala +neg/t5728.scala +neg/t6323a.scala +neg/compile-time-only-a.scala +neg/t6795.scala +neg/t2494.scala +neg/t3649.scala +neg/macro-invalidsig +neg/t2796.scala +neg/t112706A.scala +neg/t0764.scala +neg/t3757 +neg/t1431.scala +neg/exhausting.scala +neg/t1523.scala +neg/t779.scala +neg/xmltruncated1.scala +neg/t2208.scala +neg/t2078.scala +neg/t521.scala +neg/null-unsoundness.scala +neg/stmt-expr-discard.scala +neg/t0513.scala +neg/unchecked-abstract.scala +neg/t4460c.scala +neg/divergent-implicit.scala +neg/t5078.scala +neg/t1701.scala +neg/t0816.scala +neg/t1672b.scala +neg/macro-invalidusage-badbounds +neg/tailrec-2.scala +neg/t4064.scala +neg/t5510.scala +neg/t3873.scala +neg/tailrec-3.scala +neg/t0226.scala +neg/t2031.scala +neg/t633.scala +neg/constrs.scala +neg/anyval-anyref-parent.scala +neg/t7290.scala +neg/t1041.scala +neg/patternalts.scala +neg/error_tooManyArgsPattern.scala +neg/checksensibleUnit.scala +neg/t6539 +neg/t4417.scala +neg/wellkinded_app.scala +neg/for-comprehension-old.scala +neg/t2779.scala +neg/object-not-a-value.scala +neg/t2968b.scala +neg/t6483.scala +neg/t6902.scala +neg/t6963a.scala +neg/t3399.scala +neg/t0015.scala +neg/t3995.scala +neg/t276.scala +neg/t6758.scala +neg/t2441.scala +neg/cycle-bounds.scala +neg/t1241.scala +neg/t4137.scala +neg/unicode-unterminated-quote.scala +neg/t4762.scala +neg/typeerror.scala +neg/implicits.scala +neg/t961.scala +neg/ambiguous-float-dots2.scala +neg/t2416.scala +neg/t5799.scala +neg/t7285.scala +neg/implicit-shadow.scala +neg/t2388.scala +neg/java-access-neg +neg/found-req-variance.scala +neg/hk-bad-bounds.scala +neg/t3224.scala +neg/t1033.scala +neg/t7385.scala +neg/t5882.scala +neg/t4541.scala +neg/t2973.scala +neg/t6406-regextract.scala +neg/t6666.scala +neg/t4831.scala +neg/t425.scala +neg/t1845.scala +neg/t3683b.scala +neg/t2801.scala +neg/t6083.scala +neg/t0528neg.scala +neg/stringinterpolation_macro-neg.scala +neg/t668.scala +neg/t5666.scala +neg/t4271.scala +neg/interop_typetags_arenot_classmanifests.scala +neg/t1355.scala +neg/t715.scala +neg/t7238.scala +neg/t7473.scala +neg/t7292-removal.scala +neg/tcpoly_infer_ticket1162.scala +neg/t4098.scala +neg/t6013 +neg/t6227.scala +neg/t464-neg.scala +neg/badtok-3.scala +neg/t6082.scala +neg/anytrait.scala +neg/valueclasses-doubledefs.scala +neg/t7519.scala +neg/overloaded-unapply.scala +neg/t1163.scala +neg/wellkinded_bounds.scala +neg/t7292-deprecation.scala +neg/t5044.scala +neg/t0842.scala +neg/t6436.scala +neg/interop_typetags_arenot_classtags.scala +neg/t3653.scala +neg/higherkind_novalue.scala +neg/t935.scala +neg/t6040.scala +neg/annot-nonconst.scala +neg/macro-deprecate-idents.scala +neg/illegal-stmt-start.scala +neg/t565.scala +neg/case-collision.scala +neg/t3209.scala +neg/t5821.scala +neg/abstract-class-2.scala +neg/t846.scala +neg/quasiquotes-syntax-error-position.scala +neg/t3987.scala +neg/t877.scala +neg/t0117.scala +neg/t692.scala +neg/t5702-neg-ugly-xbrace.scala +neg/t7752.scala +neg/case-collision2.scala +neg/t6526.scala +neg/t2213.scala +neg/t7756a.scala +neg/macro-override-macro-overrides-abstract-method-a +neg/tcpoly_ticket2101.scala +neg/delayed-init-ref.scala +neg/caseinherit.scala +neg/t3189.scala +neg/unchecked-suppress.scala +neg/t2180.scala +neg/t1371.scala +neg/macro-cyclic +neg/t6123-explaintypes-macros +neg/t4134.scala +neg/t691.scala +neg/t2421b.scala +neg/t4691_exhaust_extractor.scala +neg/t4419.scala +neg/t5801.scala +neg/t650.scala +neg/t5735.scala +neg/t696.scala +neg/t882.scala +neg/t2968.scala +neg/t7507.scala +neg/macro-invalidusage-badargs +neg/macro-reify-typetag-typeparams-notags +neg/wellkinded_app2.scala +neg/t4425b.scala +neg/t2296a +neg/t1878.scala +neg/t649.scala +neg/override-object-no.scala +neg/t4174.scala +neg/t2070.scala +neg/sabin2.scala +neg/t5903e +neg/t6566a.scala +neg/finitary-error.scala +neg/t4818.scala +neg/t3614.scala +neg/t6666c.scala +neg/ticket513.scala +neg/suggest-similar.scala +neg/t4457_1.scala +neg/t6666e.scala +neg/tcpoly_bounds.scala +neg/t4727.scala +neg/t4425.scala +neg/macro-invalidusage-methodvaluesyntax +neg/t3854.scala +neg/t3006.scala +neg/t5580b.scala +neg/t5378.scala +neg/t639.scala +neg/wrong-args-for-none.scala +neg/t7171b.scala +neg/t5361.scala +neg/unreachablechar.scala +neg/t5572.scala +neg/t7757a.scala +neg/macro-invalidimpl +neg/t2773.scala +neg/t6359.scala +neg/saito.scala +neg/xmltruncated2.scala +neg/t667.scala +neg/t3934.scala +neg/t6771b.scala +neg/t4584.scala +neg/wellkinded_wrongarity2.scala +neg/t7369.scala +neg/t1477.scala +neg/t5617.scala +neg/t7299.scala +neg/faculty.scala +neg/virtpatmat_reach_null.scala +neg/macro-reify-typetag-hktypeparams-notags +neg/t1224.scala +neg/xmltruncated3.scala +neg/t1872.scala +neg/t558.scala +neg/t7110.scala +neg/any-vs-anyref.scala +neg/t6340.scala +neg/t4166.scala +neg/t2918.scala +neg/t5856.scala +neg/t4989.scala +neg/t0003.scala +neg/t1183.scala +neg/t963.scala +neg/t4515.scala +neg/valueclasses-pavlov.scala +neg/t608.scala +neg/choices.scala +neg/patmat-type-check.scala +neg/valueclasses-impl-restrictions.scala +neg/imp2.scala +neg/protected-constructors.scala +neg/t6788.scala +neg/nullary-override.scala +neg/t200.scala +neg/t343.scala +neg/names-defaults-neg-ref.scala +neg/tcpoly_typealias.scala +neg/classtags_contextbound_b.scala +neg/t729.scala +neg/t5683.scala +neg/t4928.scala +neg/t700.scala +neg/t7669.scala +neg/macro-invalidshape +neg/t6011.scala +neg/t7325.scala +neg/check-dead.scala +neg/t550.scala +neg/t5663-badwarneq.scala +neg/t0699 +neg/nopredefs.scala +neg/t3507-old.scala +neg/t5352.scala +neg/t6336.scala +neg/interop_classmanifests_arenot_typetags.scala +neg/sealed-final-neg.scala +neg/t2102.scala +neg/t7636.scala +neg/t5031b +neg/t798.scala +neg/t5702-neg-bad-xbrace.scala +neg/t0899.scala +neg/cyclics-import.scala +neg/badtok-2.scala +neg/t473.scala +neg/t3160ambiguous.scala +neg/t5106.scala +neg/t1286 +neg/macro-override-macro-overrides-abstract-method-b +neg/t0259.scala +neg/t510.scala +neg/t3836.scala +neg/t5830.scala +neg/t1548 +neg/t5580a.scala +neg/forward.scala +neg/t591.scala +neg/t6558b.scala +neg/t556.scala +neg/xmltruncated4.scala +neg/t5497.scala +neg/t409.scala +neg/t6283.scala +neg/override-object-flag.scala +neg/constructor-prefix-error.scala +neg/eta-expand-star.scala +neg/t3392.scala +neg/t1275.scala +neg/nested-fn-print.scala +neg/t7330.scala +neg/t2275a.scala +neg/t630.scala +neg/t4270.scala +neg/t2775.scala +neg/pat_unreachable.scala +neg/t4158.scala +neg/unit-returns-value.scala +neg/t1422.scala +neg/reify_metalevel_breach_-1_refers_to_0_b.scala +neg/reassignment.scala +neg/t3683a.scala +neg/noMember1.scala +neg/macro-without-xmacros-b +neg/t1106.scala +neg/t5182.scala +neg/t6889.scala +neg/t4217.scala +neg/t7501 +neg/t5063.scala +neg/t1009.scala +neg/t997.scala +neg/unchecked.scala +neg/classtags_contextbound_c.scala +neg/applydynamic_sip.scala +neg/t7715.scala +neg/t588.scala +neg/t6667b.scala +neg/t7757b.scala +neg/t4069.scala +neg/t515.scala +neg/variances2.scala +neg/t1049.scala +neg/t7289.scala +neg/t1623.scala +neg/permanent-blindness.scala +neg/t5803.scala +neg/super-cast-or-test.scala +neg/nonlocal-warning.scala +neg/t5687.scala +neg/t5903a +neg/t6566b.scala +neg/unchecked-knowable.scala +neg/t5093.scala +neg/protected-static-fail +neg/type-diagnostics.scala +neg/forgot-interpolator.scala +neg/interop_abstypetags_arenot_classmanifests.scala +neg/t5376.scala +neg/t545.scala +neg/xmlcorner.scala +neg/switch.scala +neg/depmet_1.scala +neg/abstract-concrete-methods.scala +neg/t4987.scala +neg/t5452-new.scala +neg/t750b +neg/unchecked-refinement.scala +neg/t418.scala +neg/t5354.scala +neg/t3736.scala +neg/t631.scala +neg/t6829.scala +neg/t0218.scala +neg/volatile-intersection.scala +neg/t412.scala +neg/t693.scala +neg/t4882.scala +neg/t1960.scala +neg/macro-divergence-controlled +neg/t712.scala +neg/t5544 +neg/t3222.scala +neg/t3604.scala +neg/t1112.scala +neg/t7157 +neg/accesses.scala +neg/t452.scala +neg/t6162-inheritance +neg/t2442 +neg/t6567.scala +neg/lazy-override.scala +neg/abstract-explaintypes.scala +neg/nested-annotation.scala +neg/t5753 +neg/t3691.scala +neg/infix-op-positions.scala +neg/t3403.scala +neg/t4851 +neg/structural.scala +neg/error_dependentMethodTpeConversionToFunction.scala +neg/t5839.scala +neg/t5553_1.scala +neg/reify_metalevel_breach_+0_refers_to_1.scala +neg/t752.scala +neg/t6574.scala +neg/t3714-neg.scala +neg/t4457_2.scala +neg/t2148.scala +neg/t1364.scala +neg/saferJavaConversions.scala +neg/t414.scala +neg/t5493.scala +neg/classtags_contextbound_a.scala +neg/reify_metalevel_breach_-1_refers_to_0_a.scala +neg/t3118.scala +neg/t512.scala +neg/t2336.scala +neg/t856.scala +neg/xmltruncated6.scala +neg/t2206.scala +neg/virtpatmat_unreach_select.scala +neg/t6258.scala +neg/t6815.scala +neg/not-possible-cause.scala +neg/dbldef.scala +neg/qualifying-class-error-1.scala +neg/t835.scala +neg/t5455.scala +neg/t6558.scala +neg/t708.scala +neg/macro-nontypeablebody +neg/t0565.scala +neg/xmltruncated5.scala +neg/t5390d.scala +neg/t520.scala +neg/t6138.scala +neg/macro-without-xmacros-a +neg/t7214neg.scala +neg/t2870.scala +neg/t593.scala +neg/t4541b.scala +neg/t4460b.scala +neg/t284.scala +neg/t2488.scala +neg/macro-override-method-overrides-macro +neg/interop_abstypetags_arenot_classtags.scala +neg/t3769.scala +neg/warn-inferred-any.scala +neg/t664.scala +neg/t5903d +neg/t562.scala +neg/t2316.scala +neg/t0152.scala +neg/migration28.scala +neg/t6443c.scala +neg/tcpoly_override.scala +neg/t7324.scala +neg/t987.scala +neg/t5903b +neg/t3481.scala +neg/t6912.scala +neg/tcpoly_variance_enforce.scala +neg/t3913.scala +neg/names-defaults-neg.scala +neg/t765.scala +neg/t5358.scala +neg/t391.scala +neg/serialversionuid-not-const.scala +neg/t771.scala +neg/t0903.scala +neg/catch-all.scala +neg/classmanifests_new_deprecations.scala +neg/t0606.scala +neg/t5189_inferred.scala +neg/macro-reify-typetag-useabstypetag +neg/t5543.scala +neg/logImplicits.scala +neg/interop_typetags_without_classtags_arenot_manifests.scala +neg/t6535.scala +neg/t7259.scala +neg/t2139.scala +neg/t278.scala +neg/t5564.scala +neg/unchecked3.scala +neg/virtpatmat_reach_sealed_unsealed.scala +neg/checksensible.scala +neg/t7721.scala +run/t3798.scala +run/macro-expand-varargs-explicit-over-varargs +run/t3888.scala +run/t0677-new.scala +run/t3273.scala +run/t3763.scala +run/t2755.scala +run/t920.scala +run/t5610a.scala +run/literals.scala +run/proxy.scala +run/unapply.scala +run/t5830.scala +run/array-addition.scala +run/macro-expand-nullary-nongeneric +run/macro-basic-ma-mdmi +run/valueclasses-constr.scala +run/t1247.scala +run/t3487.scala +run/rawstrings.scala +run/patmat-seqs.scala +run/eta-expand-star.scala +run/t7436.scala +run/t3996.scala +run/constructors.scala +run/t498.scala +run/t3835.scala +run/t298.scala +run/t2867.scala +run/t7120 +run/virtpatmat_literal.scala +run/t2175.scala +run/t2503.scala +run/t3026.scala +run/t603.scala +run/t0091.scala +run/t6394a +run/macro-expand-varargs-implicit-over-varargs +run/t7407.scala +run/t2552.scala +run/virtpatmat_npe.scala +run/macro-sip19 +run/t6644.scala +run/t6614.scala +run/t2005.scala +run/t4680.scala +run/t5903a +run/classtags_contextbound.scala +run/Course-2002-05.scala +run/applydynamic_sip.scala +run/t1766.scala +run/retsynch.scala +run/t7715.scala +run/t102.scala +run/nonlocalreturn.scala +run/macro-reify-staticXXX +run/Course-2002-06.scala +run/t6863.scala +run/t6500.scala +run/macro-impl-rename-context +run/t4351.scala +run/t5009.scala +run/macro-term-declared-in-annotation +run/t6271.scala +run/array-existential-bound.scala +run/t6443b.scala +run/t1987.scala +run/MutableListTest.scala +run/t7571.scala +run/t5488-fn.scala +run/macro-bodyexpandstoimpl +run/macro-reify-ref-to-packageless +run/t2212.scala +run/macro-expand-varargs-implicit-over-nonvarargs +run/t0807.scala +run/patmat-behavior.scala +run/t2446.scala +run/breakout.scala +run/t4122.scala +run/macro-settings +run/t7157 +run/t1323.scala +run/t4013b.scala +run/t6309.scala +run/t4047.scala +run/t5544 +run/t978.scala +run/t3361.scala +run/t6611.scala +run/t5387.scala +run/t5656.scala +run/t4897.scala +run/numeric-range.scala +run/t4777.scala +run/Course-2002-03.scala +run/string-extractor.scala +run/view-headoption.scala +run/patmat_unapp_abstype-new.scala +run/stream-stack-overflow-filter-map.scala +run/macro-impl-tparam-only-in-impl +run/t6559.scala +run/macro-reify-tagful-a +run/macro-expand-multiple-arglists +run/t4709.scala +run/t3509.scala +run/t5284b.scala +run/t7617b +run/t3923.scala +run/virtpatmat_apply.scala +run/t363.scala +run/manifests-undeprecated-in-2.10.0.scala +run/matchintasany.scala +run/t3970.scala +run/t4996.scala +run/t5530.scala +run/macro-term-declared-in-object-class +run/t3242b.scala +run/indexedSeq-apply.scala +run/t107.scala +run/t2337.scala +run/t2754.scala +run/flat-flat-flat.scala +run/t6673.scala +run/interpolationMultiline2.scala +run/t0631.scala +run/t2800.scala +run/t6506.scala +run/t6260.scala +run/t2418.scala +run/t4415.scala +run/classmanifests_new_alias.scala +run/t5380.scala +run/tcpoly_parseridioms.scala +run/t1747.scala +run/t5903d +run/t3530.scala +run/t216.scala +run/macro-term-declared-in-refinement +run/t4592.scala +run/t2488.scala +run/t3327.scala +run/t5614.scala +run/t5903b +run/iterables.scala +run/t3964.scala +run/t6329_vanilla.scala +run/t3038c +run/t1697.scala +run/t2030.scala +run/t3397.scala +run/t1005.scala +run/t3353.scala +run/t1466.scala +run/t3186.scala +run/tcpoly_overriding.scala +run/t5394.scala +run/t5284.scala +run/unboxingBug.scala +run/t7200.scala +run/macro-reify-basic +run/t153.scala +run/iterator3444.scala +run/macro-expand-implicit-macro-is-val +run/macro-basic-ma-md-mi +run/interpolationArgs.scala +run/t4954.scala +run/t3645.scala +run/transpose.scala +run/t3887.scala +run/t4288.scala +run/unittest_iterator.scala +run/t5543.scala +run/macro-term-declared-in-object +run/iq.scala +run/t2788.scala +run/t2027.scala +run/macro-expand-recursive +run/t949.scala +run/t1909b.scala +run/delambdafy-nested-by-name.scala +run/delambdafy-two-lambdas.scala +run/macro-blackbox-materialization +run/lists-run.scala +run/macro-parse-position +run/macro-parse-position-malformed +run/macro-whitebox-dynamic-materialization +run/macro-whitebox-extractor +run/macro-vampire-false-warning +run/macro-whitebox-fundep-materialization +run/macro-whitebox-structural +run/mutable-treeset.scala +run/static-module-method.scala +run/sort.scala +run/t1909.scala +run/t1909c.scala +run/t3346a.scala +run/t3346d.scala +run/t3346f.scala +run/t3346h.scala +run/t3346g.scala +run/t3832.scala +run/t4742.scala +run/t5377.scala +run/t5923c.scala +run/t6188.scala +run/t6333.scala +run/t6385.scala +run/t7899.scala +run/t7584b.scala +run/t7223.scala +run/t7859 +run/t7868.scala +run/t7871 +run/arrayclone-new.scala +run/arrayclone-old.scala +run/bitsets.scala +run/comparable-comparator.scala +run/colltest1.scala +run/t2106.scala +run/t5986.scala +run/view-iterator-stream.scala +run/array-charSeq.scala +pos/signatures +pos/t1263 +pos/t3249 +neg/t4749.scala +neg/main1.scala +neg/t7251 +neg/t7494-after-terminal +neg/t7494-before-parser +neg/t7494-right-after-terminal +run/lazy-traits.scala +run/OrderingTest.scala +run/ReplacementMatching.scala +run/patmat-finally.scala +run/t3158.scala +run/t3346e.scala +run/t4398.scala +run/t4930.scala +run/t6534.scala +pos/sammy_scope.scala +pos/delambdafy-patterns.scala +pos/private-types-after-typer.scala +pos/delambdafy-lambdalift.scala +pos/sammy_poly.scala +pos/sammy_single.scala +pos/sammy_twice.scala +pos/t3160.scala +pos/t1014.scala +pos/t4970b.scala +pos/t2698.scala +pos/t5845.scala +pos/t6201.scala +pos/t6260a.scala +pos/t7688.scala +pos/t7818.scala +pos/t1203a.scala +pos/t7834.scala +pos/t7853.scala +pos/t7815.scala +pos/t7853-partial-function.scala +pos/t7864.scala +pos/t7928.scala +pos/t7902.scala +pos/t7944.scala +pos/t7847 +neg/accesses2.scala +neg/bad-advice.scala +neg/gadts2.scala +neg/gadts2-strict.scala +neg/macro-bundle-abstract.scala +neg/macro-bundle-object.scala +neg/macro-bundle-trait.scala +neg/macro-blackbox-dynamic-materialization +neg/macro-blackbox-extractor +neg/run-gadts-strict.scala +neg/macro-blackbox-structural +neg/sammy_restrictions.scala +neg/sammy_wrong_arity.scala +neg/t2462c.scala +neg/t3346b.scala +neg/t1909-object.scala +neg/macro-blackbox-fundep-materialization +neg/t3346c.scala +neg/t3871.scala +neg/t3871b.scala +neg/t3971.scala +neg/t3346i.scala +neg/t6120.scala +neg/t6260c.scala +neg/t6680a.scala +neg/t7239.scala +neg/t7007.scala +neg/t7605-deprecation.scala +neg/t7622-missing-required.scala +neg/t7629-view-bounds-deprecation.scala +neg/t7834neg.scala +neg/t7783.scala +neg/t7848-interp-warn.scala +neg/t7519-b +neg/t7622-missing-dependency +neg/t7870.scala +neg/t7877.scala +neg/t7895.scala +neg/t7895b.scala +neg/t7899.scala +neg/t7895c.scala +neg/t7859 +run/t4752.scala +run/t2087-and-2400.scala +run/t3855.scala +run/t6637.scala +run/t6731.scala +pos/t3999b.scala +run/t0432.scala +run/t2514.scala +run/t7817.scala +run/t874.scala +run/type-currying.scala +run/t3616.scala +run/t3687.scala +run/t4570.scala +run/t5612.scala +run/t1110.scala +run/t2636.scala +run/verify-ctor.scala +run/t3647.scala +run/t4560.scala +run/t6632.scala +run/richs.scala +run/t6725-1.scala +pos/t7776.scala +run/fors.scala +run/t6706.scala +run/t3175.scala +run/delambdafy-dependent-on-param-subst.scala +run/t4332b.scala +run/t8048a +run/t8017 +run/t7985b.scala +run/t8100.scala +run/patmat-mix-case-extractor.scala +run/t4750.scala +run/t7912.scala +run/delambdafy-dependent-on-param-subst-2.scala +run/t8048b +run/t8091.scala +run/macroPlugins-macroRuntime +run/macro-default-params +run/t6355.scala +run/t7777 +run/t8002.scala +run/t8015-ffc.scala +run/macro-subpatterns +run/t7985.scala +run/macroPlugins-macroArgs +run/t7326.scala +run/t5045.scala +run/value-class-partial-func-depmet.scala +run/t6329_vanilla_bug.scala +run/macroPlugins-macroExpand +run/t8010.scala +run/macroPlugins-typedMacroBody +run/t7406.scala +pos/t8146a.scala +pos/t8046c.scala +pos/t8132.scala +pos/t8045.scala +pos/overzealous-assert-genbcode.scala +pos/t8128.scala +pos/t8013 +pos/t8064b +pos/t6780.scala +pos/t7987 +pos/bcode_throw_null +pos/t8064 +pos/t8046.scala +pos/t6231.scala +pos/t7983.scala +pos/t5508.scala +pos/t5508-min.scala +pos/t8023b.scala +pos/t6231b.scala +pos/debug-reset-local-attrs.scala +pos/t8054.scala +pos/t2066.scala +pos/dotless-targs.scala +pos/t8120.scala +pos/t5508-min-okay.scala +pos/t8060.scala +pos/t8001 +pos/t8138.scala +pos/t8111.scala +pos/t8011.scala +pos/t8146b.scala +pos/t8046b.scala +pos/t8023.scala +pos/t5508-min-okay2.scala +pos/macro-implicit-invalidate-on-error.scala +neg/t6563.scala +neg/missing-param-type-tuple.scala +neg/not-a-legal-formal-parameter-tuple.scala +neg/t7897.scala +neg/t8015-ffa.scala +neg/quasiquotes-unliftable-not-found.scala +neg/t2066b.scala +neg/dotless-targs.scala +neg/patmat-classtag-compound.scala +neg/t2066.scala +neg/t8035-deprecated.scala +neg/t6675b.scala +neg/t8104 +neg/t7872.scala +neg/t7850.scala +neg/t7967.scala +neg/macro-bundle-overloaded.scala +neg/t6355a.scala +neg/class-of-double-targs.scala +neg/t6355b.scala +neg/macro-reify-splice-splice +neg/macro-bundle-noncontext.scala +neg/t8015-ffb.scala +neg/t8035-removed.scala +neg/t7984.scala +neg/t8024.scala +neg/t8024b.scala +neg/t8157.scala +neg/t8146-non-finitary-2.scala +neg/t8006.scala +neg/t7872c.scala +neg/t8146-non-finitary.scala +neg/t7872b.scala +neg/t6920.scala +run/t6200.scala +run/t6196.scala +run/macro-bundle-context-refinement +run/macro-enclosingowner-detectvar +run/macro-enclosingowner-sbt +run/macro-bundle-context-alias +run/macro-bundle-whitebox-use-refined +run/macro-bundle-whitebox-use-raw +neg/name-lookup-stable.scala +neg/t0764b.scala +neg/no-implicit-to-anyref-any-val.scala +neg/t1503.scala +neg/t4728.scala +neg/t6455.scala +neg/t6260-named.scala +neg/t6844.scala +neg/t7475c.scala +neg/t7475e.scala +neg/t7475f.scala +neg/macro-bundle-whitebox-use-raw +neg/macro-bundle-whitebox-use-refined +neg/macro-incompatible-macro-engine-b +neg/t7980.scala +neg/macro-incompatible-macro-engine-a +neg/t8143a.scala +neg/t8072.scala +neg/t8207.scala +neg/t8182.scala +neg/t8219-any-any-ref-equals.scala +neg/t8177a.scala +neg/t8228.scala +neg/t8229.scala +neg/t8237-default.scala +neg/t8244b.scala +neg/t8244e +neg/t8244c.scala +neg/t8265.scala +neg/t8266-invalid-interp.scala +neg/t6931 +neg/t8376 +neg/t8372.scala +neg/t8300-overloading.scala +neg/t8244 +neg/t8158 +neg/t8431.scala +pos/implicit-anyval-2.10.scala +pos/delambdafy_t6260_method.scala +pos/macro-bundle-disambiguate-bundle.scala +pos/macro-bundle-disambiguate-nonbundle.scala +pos/package-ob-case +pos/t1786-counter.scala +pos/reflection-compat-api-universe.scala +pos/existential-java-case-class +pos/t1786-cycle.scala +pos/reflection-compat-c.scala +pos/t3452f.scala +pos/reflection-compat-ru.scala +pos/t2066-2.10-compat.scala +pos/reflection-compat-macro-universe.scala +pos/t5900a.scala +pos/t5760-pkgobj-warn +pos/t5954a +pos/t5954b +pos/t5954d +pos/t6260.scala +pos/t5165b +pos/t5954c +pos/t6260b.scala +pos/t7475b.scala +pos/t7475a.scala +pos/t7753.scala +pos/t7322.scala +pos/t6948.scala +pos/t7475d.scala +pos/t7475e.scala +pos/t6169 +pos/t7788.scala +pos/t7919.scala +pos/t8177a.scala +pos/t8177.scala +pos/t8170.scala +pos/t8170b.scala +pos/t8177d.scala +pos/t8177b.scala +pos/t8177e.scala +pos/t8134 +pos/t8177h.scala +pos/t8177g.scala +pos/t8207.scala +pos/t8187.scala +pos/t8219.scala +pos/t8219b.scala +pos/t8224.scala +pos/t8237.scala +pos/t8223.scala +pos/t8237b.scala +pos/t8300-conversions-a.scala +pos/t8300-conversions-b.scala +pos/t8209a +pos/t8209b +pos/t8244d +pos/t8300-overloading.scala +pos/t8300-patmat-a.scala +pos/t8300-patmat-b.scala +pos/t8301.scala +pos/t8324.scala +pos/t8301b.scala +pos/t8363.scala +pos/t8367.scala +pos/t8369a.scala +pos/t8369b.scala +pos/t8403.scala +pos/t8364.scala +pos/t8352 +pos/t8376 +neg/macro-bundle-nonpublic-c.scala +neg/literate_existentials.scala +neg/macro-bundle-nonpublic-impl.scala +neg/macro-bundle-ambiguous.scala +neg/macro-bundle-priority-bundle.scala +neg/macro-bundle-need-qualifier.scala +neg/macro-bundle-nonstatic.scala +neg/macro-bundle-polymorphic.scala +neg/macro-bundle-priority-nonbundle.scala +neg/macro-bundle-wrongcontext-a.scala +neg/macro-bundle-wrongcontext-b.scala +run/t8425 +run/t8245.scala +run/t8266-octal-interp.scala +run/t8280.scala +run/t8395.scala +run/t8321 +run/t8153.scala +run/t8197.scala +run/t8197b.scala +run/t8233.scala +run/t8133 +run/t8133b +run/t7475b.scala +run/t6814 +run/t4577.scala +run/t5134.scala +run/t3452f.scala +run/t3452h.scala +run/t3452c.scala +run/t3452.scala +run/t261.scala +run/t3235-minimal.scala +run/t1503_future.scala +run/t5565.scala +pos/t8411 +pos/t8460.scala +run/t8428.scala +run/t8437 +run/absoverride.scala +run/arrays.scala +run/duration-coarsest.scala +run/iterator-from.scala +run/SymbolsTest.scala +run/t1074.scala +run/t1505.scala +run/streams.scala +run/t2111.scala +run/t4601.scala +neg/t3692-new.scala +run/t7015.scala +run/t7992b.scala +run/t7992.scala +run/t8570.scala +pos/t8157-2.10.scala +pos/t8325.scala +pos/t8523.scala +pos/t8578.scala +pos/t8329.scala +pos/t8497 +pos/t8546.scala +pos/t8531 +neg/t8325-c.scala +neg/t8325-b.scala +neg/t8325.scala +neg/t6988.scala +neg/t8463.scala +neg/t8450.scala +neg/t8430.scala +run/finally.scala +neg/t8630.scala +neg/t8035-no-adapted-args.scala +neg/t8675b.scala +neg/t8610-arg.scala +neg/t8736-c.scala +neg/tailrec-4.scala +neg/double-def-top-level +neg/t8610.scala +neg/aladdin1055 +neg/virtpatmat_exhaust_compound.scala +neg/t8675.scala +neg/t8525.scala +pos/t8736.scala +pos/t8625.scala +pos/t8596.scala +pos/t8617.scala +pos/t8736-b.scala +pos/t8708 +pos/macro-attachments +run/t8611a.scala +run/t8738.scala +run/macro-rangepos-args +run/t8610.scala +run/macro-rangepos-subpatterns +run/t8611c.scala +run/macroPlugins-isBlackbox +run/t8601d.scala +run/t8607.scala +run/bugs.scala +run/t1503.scala +run/t4148.scala +run/t7763.scala +run/issue192.scala +run/t8893b.scala +run/t8845.scala +run/t8933 +run/t7459c.scala +run/t9003.scala +run/t7459f.scala +run/t8933c.scala +run/t1994.scala +run/t2866.scala +run/t5665.scala +run/t7459d.scala +run/t8933b +run/t8888.scala +run/t7459b-optimize.scala +run/t7459a.scala +run/t7019.scala +run/t8893.scala +run/t8803.scala +run/t7459b.scala +run/t8823.scala +run/t6541.scala +run/nothingTypeDce.scala +run/t8680.scala +run/t8925.scala +run/nothingTypeNoOpt.scala +run/t9030.scala +run/bigDecimalTest.scala +run/bigDecimalCache.scala +run/range.scala +run/t6064.scala +run/t7521 +run/t8710.scala +run/t8575.scala +run/t8944 +run/t8944b.scala +run/t9387.scala +run/t9387b.scala +pos/t7784.scala +pos/t8862a.scala +pos/t9074.scala +pos/t8462.scala +pos/t8862b.scala +pos/alladin763.scala +pos/t6778.scala +pos/t9074b.scala +pos/t9326a.scala +pos/t9131.scala +pos/t9393 +pos/t9392 +neg/missing-arg-list.scala +neg/deprecated-target.scala +neg/t6895.scala +neg/beanInfoDeprecation.scala +neg/t8777.scala +neg/t6895b.scala +neg/t8892.scala +neg/t8849.scala +neg/inlineIndyLambdaPrivate +run/t9029.scala +run/t7850c.scala +run/t7850d.scala +run/t8334.scala +run/t9029c.scala +run/t9029b.scala +run/t9422.scala +run/t9425.scala +pos/t9475.scala +pos/t9498.scala +pos/t9479.scala +pos/t9479b.scala +pos/t9442.scala +pos/t9369.scala +pos/t6666d.scala +pos/t9370 +neg/t6810.scala +neg/t8127a.scala +neg/t8989.scala +neg/t9401.scala +neg/implicit-ambiguous.scala +neg/implicit-ambiguous-2.scala +neg/implicit-ambiguous-invalid.scala +neg/warn-unused-imports +run/t7269.scala +run/equality.scala +run/number-parsing.scala +run/t6220.scala +run/mapConserve.scala +run/colltest.scala +run/t0412.scala +run/t6261.scala +run/java-erasure.scala +run/t5880.scala +run/t6197.scala +run/t4201.scala +run/t5608.scala +run/t3518.scala +run/t6198.scala +run/t2813.2.scala +pos/java-type-annotations +pos/sammy_infer_argtype_subtypes.scala +pos/sammy_ctor_arg.scala +pos/fun_undo_eta.scala +pos/sammy_inferargs.scala +pos/existental-slow-compile2.scala +pos/existential-slow-compile1.scala +pos/sammy_implicit.scala +pos/t9178b.scala +pos/t9449.scala +pos/t3234.scala +pos/t9542.scala +pos/t8429.scala +pos/t9658.scala +pos/t9630 +pos/t9399.scala +pos/t9411a.scala +pos/t9411b.scala +neg/partestInvalidFlag.scala +neg/sammy_error.scala +neg/sammy_disabled.scala +neg/sammy_overload.scala +neg/sammy_expected.scala +neg/t8700a +neg/t9527b.scala +neg/t9527a.scala +neg/t9572.scala +neg/t9535.scala +neg/t9629.scala +neg/optimiseDeprecated.scala +neg/t9398 +neg/outer-ref-checks.scala +neg/t8685.scala +neg/t8700b +run/t9349 +run/t9178a.scala +run/t9110.scala +run/sammy_cbn.scala +run/sammy_erasure_cce.scala +run/sammy_after_implicit_view.scala +run/sammy_restrictions_LMF.scala +run/sammy_vararg_cbn.scala +run/t7807.scala +run/sammy_return.scala +run/t9546.scala +run/t9546b.scala +run/lisp.scala +run/t9546c.scala +run/t9546d.scala +run/t9546e.scala +run/t9567.scala +run/t9567b.scala +run/trait-clonable.scala +run/t9567c.scala +run/trait-defaults-modules.scala +run/trait-defaults-modules3.scala +run/trait-defaults-modules2 +pos/functions.scala +pos/MailBox.scala +neg/t6289 +run/t4729 +run/t6114.scala +run/t1430 +pos/constant-warning.scala +pos/t2712-5.scala +pos/t2712-2.scala +pos/t2712-4.scala +pos/t2712-1.scala +pos/t2712-3.scala +pos/t2712-6.scala +pos/t6895b.scala +pos/t5683.scala +pos/hkgadt.scala +pos/t2712-7.scala +pos/t9245.scala +pos/t7088.scala +pos/t8044.scala +pos/t9665.scala +pos/t9397.scala +pos/t5183.scala +pos/t8449 +neg/t8044-b.scala +neg/t8044.scala +neg/t2712-3.scala +neg/t2712-2.scala +neg/t2712-1.scala +neg/t9045.scala +neg/t8667.scala +neg/t9361.scala +neg/t9781.scala +neg/trait-no-native.scala +neg/hkgadt.scala +neg/t9684b.scala +neg/t9382.scala +neg/trait-defaults-super.scala +neg/t9684.scala +run/hashCodeStatics.scala +run/t9390d.scala +run/trait-static-clash.scala +run/t5568.scala +run/t6318_primitives.scala +pos/fields_widen_trait_var.scala +pos/sammy_extends_function.scala +pos/infer_override_def_args.scala +pos/t482.scala +pos/t8079b.scala +pos/t6161b.scala +pos/t5294b.scala +pos/t5294c.scala +pos/overloaded_ho_fun.scala +pos/t4914.scala +pos/trait_fields_dependent_conflict.scala +pos/t2377b +pos/trait_fields_dependent_rebind.scala +pos/t9855b.scala +pos/trait_fields_inherit_double_def.scala +pos/t9855.scala +pos/t8873.scala +pos/trait_fields_nested_private_object.scala +pos/trait_fields_nested_public_object.scala +pos/trait_fields_private_this.scala +pos/trait_fields_var_override_deferred.scala +pos/trait_fields_static_fwd.scala +pos/trait_fields_owners.scala +pos/trait_fields_volatile.scala +pos/trait_lazy_accessboundary.scala +pos/trait_fields_lambdalift.scala +pos/typevar-in-prefix.scala +pos/val_infer.scala +pos/lub-from-hell.scala +neg/t8079a.scala +neg/sd128 +neg/t9849.scala +neg/trait_fields_var_override.scala +neg/val_infer.scala +neg/val_sig_infer_match.scala +neg/t7187.scala +neg/trait_fields_deprecated_overriding.scala +neg/t9847.scala +neg/val_sig_infer_struct.scala +neg/trait_fields_conflicts.scala +neg/lub-from-hell-2.scala +run/t2946 +run/lazy_local_labels.scala +run/sd167.scala +run/t9841.scala +run/trait-fields-override-lazy.scala +run/trait_fields_init.scala +run/trait_fields_three_layer_overrides.scala +run/t9516.scala +run/t10032.scala +pos/sam_erasure_boundedwild.scala +pos/t10154.scala +pos/t10066.scala +pos/t10154b.scala +pos/t10093.scala +pos/t8040.scala +pos/t3772.scala +pos/t10206.scala +pos/t9331.scala +pos/userdefined_apply_poly_overload.scala +pos/userdefined_apply.scala +pos/trailing-commas.scala +neg/t10097.scala +neg/t10068.scala +neg/ambiguous-same.scala +neg/maxerrs.scala +neg/maxwarns.scala +neg/t10207.scala +neg/t10066.scala +neg/t3236-neg +neg/t3772.scala +neg/t8704.scala +neg/t8002-nested-scope.scala +neg/t10097b.scala +neg/trailing-commas.scala +neg/t9834.scala +neg/userdefined_apply.scala +neg/t8417.scala +neg/warn-unused-implicits.scala +neg/t7860.scala +neg/t8763.scala +neg/t9636.scala +neg/warn-unused-params.scala +neg/t9675.scala +neg/warn-unused-patvars.scala +run/t10069.scala +run/SD-290.scala +run/sd329.scala +run/t10097.scala +run/t10072.scala +run/t10261 +run/t9114.scala +run/t10069b.scala +pos/t10205.scala +pos/t7100.scala +pos/t5788.scala +pos/t4012-b.scala +pos/t7638.scala +pos/t4012-a.scala +pos/dotless-targs-ranged.scala +neg/t5355.scala +neg/badtok-1-212.scala +neg/t6714.scala +neg/t10249 +run/macro-implicit-decorator +run/t10290.scala +run/t10298.scala +run/t10389.scala +run/t10423 +run/t6714.scala +run/t9146.scala +run/wacky-value-classes.scala + +# Adapt checkfiles for (1.0).toString == "1" +run/Course-2002-01.scala +run/t0421-new.scala +run/runtime.scala +run/t0421-old.scala +run/spec-self.scala +run/t5552.scala +run/Course-2002-02.scala +run/Course-2002-04.scala +run/promotion.scala +run/t4617.scala +run/Course-2002-09.scala +run/t5866.scala +run/try-catch-unify.scala +run/impconvtimes.scala +run/Course-2002-10.scala +run/Course-2002-08.scala +run/MeterCaseClass.scala +run/Meter.scala +run/deeps.scala +run/caseClassHash.scala +run/interpolation.scala +run/interpolationMultiline1.scala +run/t9656.scala +pos/sd219.scala +pos/t9918 +pos/shapeless-regression.scala +pos/issue244.scala +pos/t9920.scala +pos/t9943.scala +neg/t5148.scala +run/sd242.scala +run/local_obj.scala +run/t9697.scala +run/t9920.scala +run/t9920c.scala +run/t9920d.scala +run/t9920b.scala +run/t9946a.scala +run/t9946c.scala +run/t9946b.scala +run/trait-super-calls.scala +pos/sd268.scala +pos/sd248 +pos/t6734.scala +pos/t10009.scala +pos/t7551 +pos/t6978 +pos/t7046-2 +neg/t9953.scala +neg/t7014 +neg/t7046-2 +neg/t7046 +run/t7046-1 +run/t7046-2 + +# Adapt checkfiles for ().toString == "undefined" +run/t5680.scala +run/dynamic-anyval.scala +run/macro-bundle-toplevel +run/macro-bundle-whitebox-decl +run/t6662 +run/t8570a.scala +run/t3702.scala +run/t7657 +run/macro-bundle-static +run/structural.scala + +# Adapt checkfiles for print & flush (which we cannot 100% emulate) +run/imports.scala +run/misc.scala + +# Adapt checkfiles for compiler phase list +neg/t7494-no-options +neg/t6446-list +neg/t6446-missing +neg/t6446-show-phases.scala +neg/t6446-additional + +# Adapt checkfiles for different behavior with boxed types +run/virtpatmat_typetag.scala +run/virtpatmat_switch.scala +run/t5629b.scala +run/t5356.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-additional.check new file mode 100644 index 0000000000..b7ce23da2f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-additional.check @@ -0,0 +1,30 @@ + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + ploogin 27 A sample phase that does so many things it's kind of hard... + terminal 28 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-list.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-list.check new file mode 100644 index 0000000000..95883c8c81 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-list.check @@ -0,0 +1,2 @@ +ploogin - A sample plugin for testing. +scalajs - Compile to JavaScript diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-missing.check new file mode 100644 index 0000000000..56b74a3128 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-missing.check @@ -0,0 +1,30 @@ +Error: unable to load class: t6446.Ploogin + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + terminal 27 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-show-phases.check new file mode 100644 index 0000000000..cde255e3b1 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-show-phases.check @@ -0,0 +1,29 @@ + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + terminal 27 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t7494-no-options.check new file mode 100644 index 0000000000..d8be421e5e --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t7494-no-options.check @@ -0,0 +1,31 @@ +error: Error: ploogin takes no options + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + ploogin 27 A sample phase that does so many things it's kind of hard... + terminal 28 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Course-2002-01.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Course-2002-01.check new file mode 100644 index 0000000000..fcda9433de --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Course-2002-01.check @@ -0,0 +1,37 @@ +Course-2002-01.scala:41: warning: method loop in object M0 does nothing other than call itself recursively + def loop: Int = loop; + ^ +232 +667 +11 +10 +62.8318 +62.8318 +62.8318 +4 +81 +256 +25 +1 +737 +1 +0 +1 +76 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +sqrt(2) = 1.4142135623746899 +sqrt(2) = 1.4142135623746899 +cbrt(2) = 1.2599210500177698 +1 +1 1 +1 2 1 +1 3 3 1 +1 4 6 4 1 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Course-2002-02.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Course-2002-02.check new file mode 100644 index 0000000000..ab75cfdb61 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Course-2002-02.check @@ -0,0 +1,187 @@ +7 +120 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +pi = 3.181104885577714 +pi = 3.181104885577714 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 +pi = 3.181104885577714 +pi = 3.181104885577714 + +1.5 +1.4166666666666665 +1.4142156862745097 +1.4142135623746899 +sqrt(2) = 1.4142135623746899 + +1.5 +1.4166666666666665 +1.4142156862745097 +1.4142135623746899 +sqrt(2) = 1.4142135623746899 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +power(0,0) = 1 +power(0,1) = 0 +power(0,2) = 0 +power(0,3) = 0 +power(0,4) = 0 +power(0,5) = 0 +power(0,6) = 0 +power(0,7) = 0 +power(0,8) = 0 + +power(1,0) = 1 +power(1,1) = 1 +power(1,2) = 1 +power(1,3) = 1 +power(1,4) = 1 +power(1,5) = 1 +power(1,6) = 1 +power(1,7) = 1 +power(1,8) = 1 + +power(2,0) = 1 +power(2,1) = 2 +power(2,2) = 4 +power(2,3) = 8 +power(2,4) = 16 +power(2,5) = 32 +power(2,6) = 64 +power(2,7) = 128 +power(2,8) = 256 + +power(3,0) = 1 +power(3,1) = 3 +power(3,2) = 9 +power(3,3) = 27 +power(3,4) = 81 +power(3,5) = 243 +power(3,6) = 729 +power(3,7) = 2187 +power(3,8) = 6561 + +power(4,0) = 1 +power(4,1) = 4 +power(4,2) = 16 +power(4,3) = 64 +power(4,4) = 256 +power(4,5) = 1024 +power(4,6) = 4096 +power(4,7) = 16384 +power(4,8) = 65536 + +power(5,0) = 1 +power(5,1) = 5 +power(5,2) = 25 +power(5,3) = 125 +power(5,4) = 625 +power(5,5) = 3125 +power(5,6) = 15625 +power(5,7) = 78125 +power(5,8) = 390625 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Course-2002-04.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Course-2002-04.check new file mode 100644 index 0000000000..fc6ad96eed --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Course-2002-04.check @@ -0,0 +1,64 @@ +list0 = List(6, 3, 1, 8, 7, 1, 2, 5, 8, 4, 3, 4, 8) +list1 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list2 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list3 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list4 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list5 = List(8, 8, 8, 7, 6, 5, 4, 4, 3, 3, 2, 1, 1) +list6 = List(8, 8, 8, 7, 6, 5, 4, 4, 3, 3, 2, 1, 1) + +list0: List() -> List() +list1: List(0) -> List(0) +list2: List(0, 1) -> List(0, 1) +list3: List(1, 0) -> List(0, 1) +list4: List(0, 1, 2) -> List(0, 1, 2) +list5: List(1, 0, 2) -> List(0, 1, 2) +list6: List(0, 1, 2) -> List(0, 1, 2) +list7: List(1, 0, 2) -> List(0, 1, 2) +list8: List(2, 0, 1) -> List(0, 1, 2) +list9: List(2, 1, 0) -> List(0, 1, 2) +listA: List(6, 3, 1, 8, 7, 1, 2, 5, 8, 4) -> List(1, 1, 2, 3, 4, 5, 6, 7, 8, 8) + +f(x) = 5x^3+7x^2+5x+9 +f(0) = 9 +f(1) = 26 +f(2) = 87 +f(3) = 222 + +v1 = List(2, 3, 4) +v2 = List(6, 7, 8) + +id = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +m1 = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m2 = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) + +v1 * v1 = 29 +v1 * v2 = 65 +v2 * v1 = 65 +v1 * v2 = 65 + +id * v1 = List(2, 3, 4) +m1 * v1 = List(4, 6, 8) +m2 * v1 = List(20, 47, 74) + +trn(id) = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +trn(m1) = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +trn(m2) = List(List(1, 4, 7), List(2, 5, 8), List(3, 6, 9)) + +List(v1) * id = List(List(2, 3, 4)) +List(v1) * m1 = List(List(4, 6, 8)) +List(v1) * m2 = List(List(42, 51, 60)) + +id * List(v1) = List(List(2, 3, 4), List(0, 0, 0), List(0, 0, 0)) +m1 * List(v1) = List(List(4, 6, 8), List(0, 0, 0), List(0, 0, 0)) +m2 * List(v1) = List(List(2, 3, 4), List(8, 12, 16), List(14, 21, 28)) + +id * id = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +id * m1 = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m1 * id = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m1 * m1 = List(List(4, 0, 0), List(0, 4, 0), List(0, 0, 4)) +id * m2 = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) +m2 * id = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) +m1 * m2 = List(List(2, 4, 6), List(8, 10, 12), List(14, 16, 18)) +m2 * m1 = List(List(2, 4, 6), List(8, 10, 12), List(14, 16, 18)) +m2 * m2 = List(List(30, 36, 42), List(66, 81, 96), List(102, 126, 150)) + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Course-2002-08.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Course-2002-08.check new file mode 100644 index 0000000000..0585d5b44f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Course-2002-08.check @@ -0,0 +1,171 @@ +x = abc +count = 111 +x = hello +count = 112 + +account deposit 50 -> undefined +account withdraw 20 -> 30 +account withdraw 20 -> 10 +account withdraw 15 -> + +x deposit 30 -> undefined +y withdraw 20 -> + +x deposit 30 -> undefined +x withdraw 20 -> 10 + +x deposit 30 -> undefined +y withdraw 20 -> 10 + +2^0 = 1 +2^1 = 2 +2^2 = 4 +2^3 = 8 + +2^0 = 1 +2^1 = 2 +2^2 = 4 +2^3 = 8 + +1 2 3 +List(1, 2, 3) + +out 0 new-value = false +*** simulation started *** +out 1 new-value = true +!0 = 1 + +*** simulation started *** +out 2 new-value = false +!1 = 0 + +out 2 new-value = false + +*** simulation started *** +0 & 0 = 0 + +*** simulation started *** +0 & 1 = 0 + +*** simulation started *** +out 11 new-value = true +out 11 new-value = false +1 & 0 = 0 + +*** simulation started *** +out 14 new-value = true +1 & 1 = 1 + +out 14 new-value = false + +*** simulation started *** +0 | 0 = 0 + +*** simulation started *** +out 24 new-value = true +0 | 1 = 1 + +*** simulation started *** +1 | 0 = 1 + +*** simulation started *** +1 | 1 = 1 + +sum 34 new-value = false +carry 34 new-value = false + +*** simulation started *** +0 + 0 = 0 + +*** simulation started *** +sum 47 new-value = true +0 + 1 = 1 + +*** simulation started *** +carry 50 new-value = true +carry 50 new-value = false +sum 54 new-value = false +sum 54 new-value = true +1 + 0 = 1 + +*** simulation started *** +carry 57 new-value = true +sum 61 new-value = false +1 + 1 = 2 + +sum 61 new-value = false +carry 61 new-value = false + +*** simulation started *** +0 + 0 + 0 = 0 + +*** simulation started *** +sum 82 new-value = true +0 + 0 + 1 = 1 + +*** simulation started *** +sum 89 new-value = false +carry 90 new-value = true +sum 97 new-value = true +carry 98 new-value = false +0 + 1 + 0 = 1 + +*** simulation started *** +sum 113 new-value = false +carry 114 new-value = true +0 + 1 + 1 = 2 + +*** simulation started *** +sum 121 new-value = true +carry 122 new-value = false +sum 129 new-value = false +sum 129 new-value = true +1 + 0 + 0 = 1 + +*** simulation started *** +carry 137 new-value = true +sum 144 new-value = false +1 + 0 + 1 = 2 + +*** simulation started *** +carry 152 new-value = false +sum 152 new-value = true +sum 158 new-value = false +carry 159 new-value = true +1 + 1 + 0 = 2 + +*** simulation started *** +sum 173 new-value = true +1 + 1 + 1 = 3 + +in 0 new-value = false +ctrl0 0 new-value = false +ctrl1 0 new-value = false +ctrl2 0 new-value = false +out0 0 new-value = false +out1 0 new-value = false +out2 0 new-value = false +out3 0 new-value = false +out4 0 new-value = false +out5 0 new-value = false +out6 0 new-value = false +out7 0 new-value = false +in 0 new-value = true +*** simulation started *** +out0 10 new-value = true +ctrl0 10 new-value = true +*** simulation started *** +out1 13 new-value = true +out0 14 new-value = false +ctrl1 14 new-value = true +*** simulation started *** +out3 20 new-value = true +out1 21 new-value = false +ctrl2 21 new-value = true +*** simulation started *** +out7 30 new-value = true +out3 31 new-value = false +ctrl0 31 new-value = false +*** simulation started *** +out7 34 new-value = false +out6 35 new-value = true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Course-2002-09.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Course-2002-09.check new file mode 100644 index 0000000000..c921361db7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Course-2002-09.check @@ -0,0 +1,50 @@ +Probe: f = 32 +Probe: c = 0 +Probe: f = ? +Probe: c = ? + +Probe: f = 212 +Probe: c = 100 +Probe: f = ? +Probe: c = ? + +Probe: c = 0 +Probe: f = 32 +Probe: c = ? +Probe: f = ? + +Probe: c = 100 +Probe: f = 212 +Probe: c = ? +Probe: f = ? + +0 Celsius -> 32 Fahrenheits +100 Celsius -> 212 Fahrenheits +32 Fahrenheits -> 0 Celsius +212 Fahrenheits -> 100 Celsius + +a = ?, b = ?, c = ? => ? * ? = ? +a = 2, b = ?, c = ? => 2 * ? = ? +a = ?, b = 3, c = ? => ? * 3 = ? +a = ?, b = ?, c = 6 => ? * ? = 6 +a = 2, b = 3, c = ? => 2 * 3 = 6 +a = 2, b = ?, c = 6 => 2 * 3 = 6 +a = ?, b = 3, c = 6 => 2 * 3 = 6 +a = 2, b = 3, c = 6 => 2 * 3 = 6 + +a = 0, b = ?, c = ? => 0 * ? = 0 +a = ?, b = 0, c = ? => ? * 0 = 0 +a = ?, b = ?, c = 0 => ? * ? = 0 +a = 0, b = 7, c = ? => 0 * 7 = 0 +a = 7, b = 0, c = ? => 7 * 0 = 0 +a = 0, b = 0, c = ? => 0 * 0 = 0 +a = 0, b = ?, c = 0 => 0 * ? = 0 +a = ?, b = 0, c = 0 => ? * 0 = 0 +a = 0, b = 7, c = 0 => 0 * 7 = 0 +a = 7, b = 0, c = 0 => 7 * 0 = 0 +a = 0, b = 0, c = 0 => 0 * 0 = 0 + +a = 3, b = 4 => c = 5 +a = 3, c = 5 => b = 4 +b = 4, c = 5 => a = 3 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Course-2002-10.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Course-2002-10.check new file mode 100644 index 0000000000..847f0fa703 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Course-2002-10.check @@ -0,0 +1,46 @@ +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +fib(10) = 55 +fib(11) = 89 +fib(12) = 144 +fib(13) = 233 +fib(14) = 377 +fib(15) = 610 +fib(16) = 987 +fib(17) = 1597 +fib(18) = 2584 +fib(19) = 4181 + +pi(0) = 4 , 3.166666666666667 , 4 +pi(1) = 2.666666666666667 , 3.1333333333333337, 3.166666666666667 +pi(2) = 3.466666666666667 , 3.1452380952380956, 3.142105263157895 +pi(3) = 2.8952380952380956, 3.1396825396825396, 3.1415993573190044 +pi(4) = 3.33968253968254 , 3.142712842712843 , 3.141592714033778 +pi(5) = 2.976046176046176 , 3.140881340881341 , 3.1415926539752923 +pi(6) = 3.283738483738484 , 3.142071817071817 , 3.141592653591176 +pi(7) = 3.017071817071817 , 3.1412548236077646, 3.141592653589777 +pi(8) = 3.252365934718876 , 3.1418396189294024, 3.141592653589794 +pi(9) = 3.0418396189294024, 3.141406718496502 , 3.1415926535897936 +pi = 3.141592653589793 , 3.141592653589793 , 3.141592653589793 + +ln(0) = 1 , 0.7 , 1 +ln(1) = 0.5 , 0.6904761904761905, 0.7 +ln(2) = 0.8333333333333333, 0.6944444444444444, 0.6932773109243697 +ln(3) = 0.5833333333333333, 0.6924242424242424, 0.6931488693329254 +ln(4) = 0.7833333333333333, 0.6935897435897436, 0.6931471960735491 +ln(5) = 0.6166666666666667, 0.6928571428571428, 0.6931471806635636 +ln(6) = 0.7595238095238095, 0.6933473389355742, 0.6931471805604038 +ln(7) = 0.6345238095238095, 0.6930033416875522, 0.6931471805599444 +ln(8) = 0.7456349206349207, 0.6932539682539682, 0.6931471805599426 +ln(9) = 0.6456349206349206, 0.6930657506744463, 0.6931471805599453 +ln = 0.6931471805599453, 0.6931471805599453, 0.6931471805599453 + +prime numbers: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Meter.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Meter.check new file mode 100644 index 0000000000..f46fd557c8 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/Meter.check @@ -0,0 +1,16 @@ +Meter.scala:72: warning: a.Meter and Int are unrelated: they will never compare equal + println("x == 1: "+(x == 1)) + ^ +2 +4m +false +x.isInstanceOf[Meter]: true +x.hashCode: 1 +x == 1: false +x == y: true +a == b: true +testing native arrays +Array(1m, 2m) +1m +>>>1m<<< 1m +>>>2m<<< 2m diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/MeterCaseClass.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/MeterCaseClass.check new file mode 100644 index 0000000000..ac538d240f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/MeterCaseClass.check @@ -0,0 +1,16 @@ +MeterCaseClass.scala:69: warning: comparing values of types a.Meter and Int using `==' will always yield false + println("x == 1: "+(x == 1)) + ^ +2 +Meter(4) +false +x.isInstanceOf[Meter]: true +x.hashCode: 1 +x == 1: false +x == y: true +a == b: true +testing native arrays +Array(Meter(1), Meter(2)) +Meter(1) +>>>Meter(1)<<< Meter(1) +>>>Meter(2)<<< Meter(2) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/bugs.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/bugs.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/bugs.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/caseClassHash.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/caseClassHash.check new file mode 100644 index 0000000000..f975151e9c --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/caseClassHash.check @@ -0,0 +1,9 @@ +Foo(true,-1,-1,d,-5,-10,500,500,List(),5) +Foo(true,-1,-1,d,-5,-10,500,500,List(),5) +1383698062 +1383698062 +true +## method 1: 1383698062 +## method 2: 1383698062 + Murmur 1: 1383698062 + Murmur 2: 1383698062 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/deeps.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/deeps.check new file mode 100644 index 0000000000..e533b87dc5 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/deeps.check @@ -0,0 +1,87 @@ +testEquals1 +false +false +true + +testEquals2 +false +false +true + +testEquals3 +x=Array(1) +y=Array(1) +false +false +true + +x=Array(Array(1), Array(1)) +y=Array(Array(1), Array(1)) +false +false +true + +x=Array(Array(Array(1), Array(1)), Array(Array(1), Array(1))) +y=Array(Array(Array(1), Array(1)), Array(Array(1), Array(1))) +false +false +true + +testEquals4 +false +false +true +false +false +true +Array(true, false) +Array(true, false) +[true;false] +true;false + +Array(Array(true, false), Array(true, false)) +Array(Array(true, false), Array(true, false)) +[Array(true, false);Array(true, false)] +Array(true, false);Array(true, false) + +Array(Array(Array(true, false), Array(true, false)), Array(Array(true, false), Array(true, false))) +Array(Array(Array(true, false), Array(true, false)), Array(Array(true, false), Array(true, false))) +[Array(Array(true, false), Array(true, false));Array(Array(true, false), Array(true, false))] +Array(Array(true, false), Array(true, false));Array(Array(true, false), Array(true, false)) + +Array(1, 0) +Array(1, 0) +[1;0] +1;0 + +Array(Array(1, 0), Array(1, 0)) +Array(Array(1, 0), Array(1, 0)) +[Array(1, 0);Array(1, 0)] +Array(1, 0);Array(1, 0) + +Array(Array(Array(1, 0), Array(1, 0)), Array(Array(1, 0), Array(1, 0))) +Array(Array(Array(1, 0), Array(1, 0)), Array(Array(1, 0), Array(1, 0))) +[Array(Array(1, 0), Array(1, 0));Array(Array(1, 0), Array(1, 0))] +Array(Array(1, 0), Array(1, 0));Array(Array(1, 0), Array(1, 0)) + +Array(a, b) +Array(a, b) +[a;b] +a;b + +Array(Array(a, b), Array(a, b)) +Array(Array(a, b), Array(a, b)) +[Array(a, b);Array(a, b)] +Array(a, b);Array(a, b) + +Array(Array(Array(a, b), Array(a, b)), Array(Array(a, b), Array(a, b))) +Array(Array(Array(a, b), Array(a, b)), Array(Array(a, b), Array(a, b))) +[Array(Array(a, b), Array(a, b));Array(Array(a, b), Array(a, b))] +Array(Array(a, b), Array(a, b));Array(Array(a, b), Array(a, b)) + +[Array(true, false); Array(false)] +[Array(1, 2); Array(3)] +[Array(1, 2); Array(3)] + +Array(boo, and, foo) +Array(a) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/dynamic-anyval.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/dynamic-anyval.check new file mode 100644 index 0000000000..c125372c9a --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/dynamic-anyval.check @@ -0,0 +1,4 @@ +undefined.dingo(bippy, 5) +List(1, 2, 3).dingo(bippy, 5) +undefined.dingo(bippy, 5) +List(1, 2, 3).dingo(bippy, 5) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/impconvtimes.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/impconvtimes.check new file mode 100644 index 0000000000..082377e474 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/impconvtimes.check @@ -0,0 +1 @@ +3.0 * Hour = Measure(3,Hour) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/imports.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/imports.check new file mode 100644 index 0000000000..1aad598062 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/imports.check @@ -0,0 +1,21 @@ +In C_ico, v_ico .toString() returns ↩ +↪C_ico -> ok +In C_ico, field .toString() returns ↩ +↪C_ico -> ok +In C_ico, method.toString() returns ↩ +↪C_ico -> ok + +In C_ioc, v_ioc .toString() returns ↩ +↪C_ioc -> ok +In C_ioc, field .toString() returns ↩ +↪C_ioc -> ok +In C_ioc, method.toString() returns ↩ +↪C_ioc -> ok + +In C_oic, v_oic .toString() returns ↩ +↪C_oic -> ok +In C_oic, field .toString() returns ↩ +↪C_oic -> ok +In C_oic, method.toString() returns ↩ +↪C_oic -> ok + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/interpolation.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/interpolation.check new file mode 100644 index 0000000000..9c4a77715b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/interpolation.check @@ -0,0 +1,32 @@ +Bob is 1 years old +Bob is 1 years old +Bob will be 2 years old +Bob will be 2 years old +1+1 = 2 +1+1 = 2 +Bob is 12 years old +Bob is 12 years old +Bob will be 13 years old +Bob will be 13 years old +12+1 = 13 +12+1 = 13 +Bob is 123 years old +Bob is 123 years old +Bob will be 124 years old +Bob will be 124 years old +123+1 = 124 +123+1 = 124 +Best price: 10 +Best price: 10.00 +10% discount included +10.00% discount included +Best price: 13.345000267028809 +Best price: 13.35 +13.345000267028809% discount included +13.35% discount included + +0 +00 + +0 +00 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/interpolationMultiline1.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/interpolationMultiline1.check new file mode 100644 index 0000000000..1b6e140c13 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/interpolationMultiline1.check @@ -0,0 +1,26 @@ +Bob is 1 years old +Bob is 1 years old +Bob will be 2 years old +Bob will be 2 years old +1+1 = 2 +1+1 = 2 +Bob is 12 years old +Bob is 12 years old +Bob will be 13 years old +Bob will be 13 years old +12+1 = 13 +12+1 = 13 +Bob is 123 years old +Bob is 123 years old +Bob will be 124 years old +Bob will be 124 years old +123+1 = 124 +123+1 = 124 +Best price: 10 +Best price: 10.00 +10% discount included +10.00% discount included +Best price: 13.345000267028809 +Best price: 13.35 +13.345000267028809% discount included +13.35% discount included diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/issue192.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/issue192.sem new file mode 100644 index 0000000000..10abbf7f3b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/issue192.sem @@ -0,0 +1 @@ +strictFloats diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/macro-bundle-static.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/macro-bundle-static.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/macro-bundle-static.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/macro-bundle-toplevel.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/macro-bundle-toplevel.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/macro-bundle-toplevel.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/macro-bundle-whitebox-decl.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/macro-bundle-whitebox-decl.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/macro-bundle-whitebox-decl.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/misc.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/misc.check new file mode 100644 index 0000000000..85f37c51d7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/misc.check @@ -0,0 +1,62 @@ +misc.scala:46: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 42; + ^ +misc.scala:47: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 42l; + ^ +misc.scala:48: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 23.5f; + ^ +misc.scala:49: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 23.5; + ^ +misc.scala:50: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + "Hello"; + ^ +misc.scala:51: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 32 + 45; + ^ +misc.scala:62: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + x; + ^ +misc.scala:74: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 1 < 2; + ^ +### Hello +### 17 +### Bye + +### fib(0) = ↩ +↪1 +### fib(1) = ↩ +↪1 +### fib(2) = ↩ +↪2 +### fib(3) = ↩ +↪3 +### fib(4) = ↩ +↪5 +=== MyClass::toString === +=== MySubclass::toString === +=== MyClass::test === + +identity + +A.a = 1 +B.a = 5 +B.b = 2 + +X.a = 4 +Y.a = 11 +Y.b = 5 +Y.b = 5 + +X::foo + +Y::foo +X::foo + +3 +3 + +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/promotion.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/promotion.check new file mode 100644 index 0000000000..41e36c369d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/promotion.check @@ -0,0 +1,4 @@ +2 +6 +20 +30 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/runtime.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/runtime.check new file mode 100644 index 0000000000..0450b9498a --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/runtime.check @@ -0,0 +1,70 @@ +runtime.scala:141: warning: comparing values of types Null and Null using `eq' will always yield true + check(true , null eq null, null ne null); + ^ +runtime.scala:141: warning: comparing values of types Null and Null using `ne' will always yield false + check(true , null eq null, null ne null); + ^ +<<< Test0 +[false,true] +[0,1,2] +[3,4,5] +[a,b,c] +[6,7,8] +[9,10,11] +[12,13] +[14,15] +[string] +>>> Test0 + +<<< Test1 +10 +14 +15 +16 +20 +23 +24 +25 +26 +>>> Test1 + +<<< Test2 +A +M0 +N0 + +A +N0 +M0 + +A +M0 +M1 +N0 + +A +N0 +N1 +M0 + +>>> Test2 + +<<< Test3 +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +>>> Test3 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/spec-self.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/spec-self.check new file mode 100644 index 0000000000..fd3c81a4d7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/spec-self.check @@ -0,0 +1,2 @@ +5 +5 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/structural.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/structural.check new file mode 100644 index 0000000000..2fec112a87 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/structural.check @@ -0,0 +1,37 @@ + 1. hey + 2. 11 + 3. dee + 4. iei + 5. 6 + 6. 51 + 7. 2 + 8. 11 +10. 12 +11. eitch +12. 1 +13. ohone +14. 1 +15. undefined +16. one +17. tieone +18. 2 +19. true +20. 1 +21. undefined +22. one +23. oy +24. 1 +25. null +26. iei +31. 4 +32. undefined +33. iei +33. tieone +1 +2 +3 +4 +5 +caught +3 +2 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t0421-new.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t0421-new.check new file mode 100644 index 0000000000..00d29b7e5b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t0421-new.check @@ -0,0 +1,3 @@ +[Array(0, 1),Array(2, 3),Array(4, 5)] +[Array(31)] +[Array(24, 32)] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t0421-old.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t0421-old.check new file mode 100644 index 0000000000..00d29b7e5b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t0421-old.check @@ -0,0 +1,3 @@ +[Array(0, 1),Array(2, 3),Array(4, 5)] +[Array(31)] +[Array(24, 32)] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t1503.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t1503.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t1503.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t3702.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t3702.check new file mode 100644 index 0000000000..3fce98715c --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t3702.check @@ -0,0 +1,2 @@ +undefined +6 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t4148.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t4148.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t4148.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t4617.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t4617.check new file mode 100644 index 0000000000..a6790f16f7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t4617.check @@ -0,0 +1 @@ +Str 8 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t5356.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t5356.check new file mode 100644 index 0000000000..870c901131 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t5356.check @@ -0,0 +1,6 @@ +1 java.lang.Byte +1 java.lang.Byte +1 scala.math.BigInt +1 java.lang.Byte +1 java.lang.Byte +1 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t5552.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t5552.check new file mode 100644 index 0000000000..9e767b6d7b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t5552.check @@ -0,0 +1,6 @@ +lazy: 3 +(3,3) +(3,3) +lazy: 3 +(3,3) +(3,3) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t5568.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t5568.check new file mode 100644 index 0000000000..6f30cc5070 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t5568.check @@ -0,0 +1,9 @@ +void +int +class scala.runtime.BoxedUnit +class scala.runtime.BoxedUnit +class java.lang.Byte +class java.lang.Byte +5 +5 +5 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t5629b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t5629b.check new file mode 100644 index 0000000000..c65298a6ce --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t5629b.check @@ -0,0 +1,10 @@ +=== pf(1): +MySmartPF.apply entered... +newPF.applyOrElse entered... +default +scala.MatchError: 1 (of class java.lang.Byte) +=== pf(42): +MySmartPF.apply entered... +newPF.applyOrElse entered... +ok +=== done diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t5680.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t5680.check new file mode 100644 index 0000000000..a3b8b64a43 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t5680.check @@ -0,0 +1,3 @@ +[Lscala.runtime.BoxedUnit +undefined +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t5866.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t5866.check new file mode 100644 index 0000000000..64df1cec7f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t5866.check @@ -0,0 +1,2 @@ +0 +Foo(0) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t6318_primitives.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t6318_primitives.check new file mode 100644 index 0000000000..654ef1beec --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t6318_primitives.check @@ -0,0 +1,54 @@ +Checking if byte matches byte +Some(1) +Checking if byte matches short +Some(1) +Checking if class java.lang.Byte matches byte +Some(1) +Checking if short matches short +Some(1) +Checking if short matches char +None +Checking if class java.lang.Byte matches short +Some(1) +Checking if char matches char +Some() +Checking if char matches int +None +Checking if class java.lang.Character matches char +Some() +Checking if int matches int +Some(1) +Checking if int matches long +None +Checking if class java.lang.Byte matches int +Some(1) +Checking if long matches long +Some(1) +Checking if long matches float +None +Checking if class java.lang.Long matches long +Some(1) +Checking if float matches float +Some(1) +Checking if float matches double +Some(1) +Checking if class java.lang.Byte matches float +Some(1) +Checking if double matches double +Some(1) +Checking if double matches boolean +None +Checking if class java.lang.Byte matches double +Some(1) +Checking if boolean matches boolean +Some(true) +Checking if boolean matches void +None +Checking if class java.lang.Boolean matches boolean +Some(true) +Checking if void matches void +Some(undefined) +Checking if void matches byte +None +Checking if class scala.runtime.BoxedUnit matches void +Some(undefined) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t6662.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t6662.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t6662.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t7657.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t7657.check new file mode 100644 index 0000000000..1a87c1e866 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t7657.check @@ -0,0 +1,3 @@ +undefined +undefined +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t7763.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t7763.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t7763.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t8570a.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t8570a.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t8570a.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t8764.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t8764.check new file mode 100644 index 0000000000..121120217e --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t8764.check @@ -0,0 +1,5 @@ +IntOnly: should return an unboxed int +Int: int +IntAndDouble: should just box and return Anyval +Double: class java.lang.Byte +Int: class java.lang.Byte diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t9387b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t9387b.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t9387b.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t9656.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t9656.check new file mode 100644 index 0000000000..a16c04eaad --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/t9656.check @@ -0,0 +1,14 @@ +Range 1 to 10 +Range 1 to 10 +inexact Range 1 to 10 by 2 +Range 1 to 10 by 3 +inexact Range 1 until 10 by 2 +Range 100 to 100 +empty Range 100 until 100 +NumericRange 1 to 10 +NumericRange 1 to 10 by 2 +NumericRange 0.1 until 1 by 0.1 +NumericRange 0.1 until 1.0 by 0.1 +NumericRange 0.1 until 1 by 0.1 (using NumericRange 0.1 until 1 by 0.1 of BigDecimal) +NumericRange 0 days until 10 seconds by 1 second +empty NumericRange 0 days until 0 days by 1 second diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/try-catch-unify.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/try-catch-unify.check new file mode 100644 index 0000000000..813f01166d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/try-catch-unify.check @@ -0,0 +1,4 @@ +Failure(java.lang.NumberFormatException: For input string: "Hi") +Success(5) +O NOES +Failure(java.lang.NumberFormatException: For input string: "Hi") diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/virtpatmat_switch.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/virtpatmat_switch.check new file mode 100644 index 0000000000..0900a9ca32 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/virtpatmat_switch.check @@ -0,0 +1,7 @@ +zero +one +many +got a +got b +got some letter +scala.MatchError: 5 (of class java.lang.Byte) \ No newline at end of file diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/virtpatmat_typetag.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/virtpatmat_typetag.check new file mode 100644 index 0000000000..048c3aeed0 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/run/virtpatmat_typetag.check @@ -0,0 +1,10 @@ +1 is a Int +1 is a java.lang.Integer +1 is not a java.lang.String; it's a class java.lang.Byte +true is a Any +woele is a java.lang.String +1 is a Int +1 is a java.lang.Integer +1 is not a java.lang.String; it's a class java.lang.Byte +true is a Any +woele is a java.lang.String diff --git a/project/Build.scala b/project/Build.scala index 2f711472cc..df4235002f 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -63,7 +63,7 @@ object Build { CrossVersion.binaryMapped(v => s"sjs${previousSJSBinaryVersion}_$v") val scalaVersionsUsedForPublishing: Set[String] = - Set("2.10.6", "2.11.11", "2.12.2", "2.13.0-M1") + Set("2.10.6", "2.11.11", "2.12.3", "2.13.0-M1") val newScalaBinaryVersionsInThisRelease: Set[String] = Set() @@ -458,6 +458,7 @@ object Build { "2.12.0", "2.12.1", "2.12.2", + "2.12.3", "2.13.0-M1" ), // JDK version we are running with diff --git a/scala-test-suite/src/test/resources/2.12.3/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.12.3/BlacklistedTests.txt new file mode 100644 index 0000000000..daf7afa088 --- /dev/null +++ b/scala-test-suite/src/test/resources/2.12.3/BlacklistedTests.txt @@ -0,0 +1,133 @@ +## Do not compile +scala/lang/annotations/BytecodeTest.scala +scala/lang/annotations/RunTest.scala +scala/lang/traits/BytecodeTest.scala +scala/lang/traits/RunTest.scala +scala/lang/primitives/NaNTest.scala +scala/lang/primitives/BoxUnboxTest.scala +scala/reflect/ClassOfTest.scala +scala/reflect/QTest.scala +scala/reflect/io/ZipArchiveTest.scala +scala/reflect/internal/util/AbstractFileClassLoaderTest.scala +scala/reflect/internal/util/SourceFileTest.scala +scala/reflect/internal/util/StringOpsTest.scala +scala/reflect/internal/PrintersTest.scala +scala/reflect/internal/ScopeTest.scala +scala/reflect/internal/TreeGenTest.scala +scala/reflect/internal/TypesTest.scala +scala/reflect/internal/util/WeakHashSetTest.scala +scala/reflect/internal/MirrorsTest.scala +scala/reflect/internal/NamesTest.scala +scala/tools/nsc/backend/jvm/BTypesTest.scala +scala/tools/nsc/backend/jvm/BytecodeTest.scala +scala/tools/nsc/backend/jvm/DefaultMethodTest.scala +scala/tools/nsc/backend/jvm/DirectCompileTest.scala +scala/tools/nsc/backend/jvm/GenericSignaturesTest.scala +scala/tools/nsc/backend/jvm/IndyLambdaTest.scala +scala/tools/nsc/backend/jvm/IndySammyTest.scala +scala/tools/nsc/backend/jvm/InnerClassAttributeTest.scala +scala/tools/nsc/backend/jvm/NestedClassesCollectorTest.scala +scala/tools/nsc/backend/jvm/OptimizedBytecodeTest.scala +scala/tools/nsc/backend/jvm/StringConcatTest.scala +scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala +scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala +scala/tools/nsc/backend/jvm/opt/AnalyzerTest.scala +scala/tools/nsc/backend/jvm/opt/BTypesFromClassfileTest.scala +scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala +scala/tools/nsc/backend/jvm/opt/ClosureOptimizerTest.scala +scala/tools/nsc/backend/jvm/opt/CompactLocalVariablesTest.scala +scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala +scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala +scala/tools/nsc/backend/jvm/opt/InlineInfoTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerIllegalAccessTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerTest.scala +scala/tools/nsc/backend/jvm/opt/InlineSourceMatcherTest.scala +scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala +scala/tools/nsc/backend/jvm/opt/MethodLevelOptsTest.scala +scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala +scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala +scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala +scala/tools/nsc/backend/jvm/opt/UnusedLocalVariablesTest.scala +scala/tools/nsc/ScriptRunnerTest.scala +scala/tools/nsc/classpath/AggregateClassPathTest.scala +scala/tools/nsc/classpath/JrtClassPathTest.scala +scala/tools/nsc/classpath/PathResolverBaseTest.scala +scala/tools/nsc/classpath/VirtualDirectoryClassPathTest.scala +scala/tools/nsc/doc/html/HtmlDocletTest.scala +scala/tools/nsc/interpreter/CompletionTest.scala +scala/tools/nsc/interpreter/ScriptedTest.scala +scala/tools/nsc/interpreter/TabulatorTest.scala +scala/tools/nsc/reporters/ConsoleReporterTest.scala +scala/tools/nsc/settings/ScalaVersionTest.scala +scala/tools/nsc/settings/SettingsTest.scala +scala/tools/nsc/symtab/CannotHaveAttrsTest.scala +scala/tools/nsc/symtab/FlagsTest.scala +scala/tools/nsc/symtab/FreshNameExtractorTest.scala +scala/tools/nsc/symtab/StdNamesTest.scala +scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala +scala/tools/nsc/symtab/SymbolTableTest.scala +scala/tools/nsc/transform/delambdafy/DelambdafyTest.scala +scala/tools/nsc/transform/patmat/SolvingTest.scala +scala/tools/nsc/transform/patmat/PatmatBytecodeTest.scala +scala/tools/nsc/typechecker/Implicits.scala +scala/tools/nsc/util/StackTraceTest.scala +scala/tools/testing/BytecodeTesting.scala +scala/tools/testing/RunTesting.scala + +## Do not link +scala/MatchErrorSerializationTest.scala +scala/PartialFunctionSerializationTest.scala +scala/lang/stringinterpol/StringContextTest.scala +scala/collection/IteratorTest.scala +scala/collection/NewBuilderTest.scala +scala/collection/ParallelConsistencyTest.scala +scala/collection/SeqViewTest.scala +scala/collection/SetMapConsistencyTest.scala +scala/collection/concurrent/TrieMapTest.scala +scala/collection/convert/WrapperSerializationTest.scala +scala/collection/immutable/ListTest.scala +scala/collection/immutable/StreamTest.scala +scala/collection/immutable/StringLikeTest.scala +scala/collection/mutable/ArrayBufferTest.scala +scala/collection/mutable/MutableListTest.scala +scala/collection/mutable/OpenHashMapTest.scala +scala/collection/mutable/PriorityQueueTest.scala +scala/collection/parallel/immutable/ParRangeTest.scala +scala/concurrent/duration/SerializationTest.scala +scala/concurrent/impl/DefaultPromiseTest.scala +scala/io/SourceTest.scala +scala/runtime/ScalaRunTimeTest.scala +scala/sys/process/PipedProcessTest.scala +scala/sys/process/ProcessTest.scala +scala/tools/testing/AssertUtilTest.scala +scala/tools/testing/AssertThrowsTest.scala +scala/util/SpecVersionTest.scala +scala/util/SystemPropertiesTest.scala + +## Tests fail + +# Reflection +scala/reflect/ClassTagTest.scala + +# Regex +scala/util/matching/CharRegexTest.scala +scala/util/matching/RegexTest.scala + +# Require strict-floats +scala/math/BigDecimalTest.scala + +# Difference of getClass() on primitive values +scala/collection/immutable/RangeTest.scala + +# Test fails only some times with +# 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' +# and' 'set scalaJSUseRhino in Global := false' +scala/collection/immutable/PagedSeqTest.scala + +# Bugs +scala/collection/convert/MapWrapperTest.scala + +# Tests passed but are too slow (timeouts) +scala/collection/immutable/ListSetTest.scala +scala/util/SortingTest.scala diff --git a/scala-test-suite/src/test/resources/2.12.3/WhitelistedTests.txt b/scala-test-suite/src/test/resources/2.12.3/WhitelistedTests.txt new file mode 100644 index 0000000000..60f3a24edb --- /dev/null +++ b/scala-test-suite/src/test/resources/2.12.3/WhitelistedTests.txt @@ -0,0 +1,40 @@ +scala/collection/IndexedSeqOptimizedTest.scala +scala/collection/IndexedSeqTest.scala +scala/collection/IterableViewLikeTest.scala +scala/collection/LinearSeqOptimizedTest.scala +scala/collection/ReusableBuildersTest.scala +scala/collection/SearchingTest.scala +scala/collection/SeqLikeTest.scala +scala/collection/TraversableLikeTest.scala +scala/collection/TraversableOnceTest.scala +scala/collection/convert/NullSafetyToJavaTest.scala +scala/collection/convert/NullSafetyToScalaTest.scala +scala/collection/immutable/HashMapTest.scala +scala/collection/immutable/ListMapTest.scala +scala/collection/immutable/QueueTest.scala +scala/collection/immutable/RangeConsistencyTest.scala +scala/collection/immutable/SetTest.scala +scala/collection/immutable/TreeMapTest.scala +scala/collection/immutable/TreeSetTest.scala +scala/collection/immutable/VectorTest.scala +scala/collection/mutable/ArraySortingTest.scala +scala/collection/mutable/BitSetTest.scala +scala/collection/mutable/HashMapTest.scala +scala/collection/mutable/LinkedHashMapTest.scala +scala/collection/mutable/LinkedHashSetTest.scala +scala/collection/mutable/SetLikeTest.scala +scala/collection/mutable/TreeMapTest.scala +scala/collection/mutable/TreeSetTest.scala +scala/collection/mutable/UnrolledBufferTest.scala +scala/collection/mutable/VectorTest.scala +scala/lang/primitives/PredefAutoboxingTest.scala +scala/math/BigIntTest.scala +scala/math/NumericTest.scala +scala/math/OrderingTest.scala +scala/runtime/ZippedTest.scala +scala/tools/nsc/SampleTest.scala +scala/tools/testing/AssertUtil.scala +scala/tools/testing/TempDir.scala +scala/util/RandomTest.scala +scala/util/TryTest.scala +scala/util/control/ExceptionTest.scala diff --git a/scripts/assemble-cli.sh b/scripts/assemble-cli.sh index bc27fac4e9..f1092e07b7 100755 --- a/scripts/assemble-cli.sh +++ b/scripts/assemble-cli.sh @@ -20,8 +20,8 @@ case $BINVER in BASEVER="2.11.11" ;; 2.12) - FULLVERS="2.12.0 2.12.1 2.12.2" - BASEVER="2.12.2" + FULLVERS="2.12.0 2.12.1 2.12.2 2.12.3" + BASEVER="2.12.3" ;; *) echo "Invalid Scala version $BINVER" >&2 diff --git a/scripts/build-all-js.sh b/scripts/build-all-js.sh index 6e23f098c8..aab8f84812 100755 --- a/scripts/build-all-js.sh +++ b/scripts/build-all-js.sh @@ -3,7 +3,7 @@ tasks="fastOptJS fullOptJS" projects="helloworld/ reversi/ testingExample/test: testSuite/test:" -for v in 2.11.11 2.10.6 2.12.2 2.13.0-M1; do +for v in 2.11.11 2.10.6 2.12.3 2.13.0-M1; do echo "++$v" echo "package" diff --git a/scripts/publish.sh b/scripts/publish.sh index 7e1bf32db3..b6a7327c96 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -8,11 +8,11 @@ else CMD="echo sbt" fi -FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.12.0 2.12.1 2.12.2 2.13.0-M1" -BIN_VERSIONS="2.10.6 2.11.11 2.12.2 2.13.0-M1" -CLI_VERSIONS="2.10.6 2.11.11 2.12.2" +FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0-M1" +BIN_VERSIONS="2.10.6 2.11.11 2.12.3 2.13.0-M1" +CLI_VERSIONS="2.10.6 2.11.11 2.12.3" SBT_VERSION="2.10.6" -SBT1_VERSION="2.12.2" +SBT1_VERSION="2.12.3" SBT1_SBTVERSION="1.0.0" COMPILER="compiler jUnitPlugin" From 7e154d6d4a65a3ab38c23e2c1d94a43a9160e6dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 17 Aug 2017 16:12:59 +0200 Subject: [PATCH 0451/2665] Fix #3079: Replace 2.13.0-M1 by 2.13.0-M2 in the CI. --- ci/checksizes.sh | 6 ++-- ci/matrix.xml | 18 ++++++------ .../BlacklistedTests.txt | 24 ++++++++++++++- .../BuglistedTests.txt | 0 .../WhitelistedTests.txt | 29 ++++++++++++++----- .../neg/t6446-additional.check | 0 .../neg/t6446-list.check | 0 .../neg/t6446-missing.check | 0 .../neg/t6446-show-phases.check | 0 .../neg/t7494-no-options.check | 0 .../run/Course-2002-01.check | 0 .../run/Course-2002-02.check | 0 .../run/Course-2002-04.check | 0 .../run/Course-2002-08.check | 0 .../run/Course-2002-09.check | 0 .../run/Course-2002-10.check | 0 .../{2.13.0-M1 => 2.13.0-M2}/run/Meter.check | 0 .../run/MeterCaseClass.check | 0 .../{2.13.0-M1 => 2.13.0-M2}/run/bugs.sem | 0 .../run/caseClassHash.check | 0 .../{2.13.0-M1 => 2.13.0-M2}/run/deeps.check | 0 .../run/dynamic-anyval.check | 0 .../run/impconvtimes.check | 0 .../run/imports.check | 0 .../run/interpolation.check | 0 .../run/interpolationMultiline1.check | 0 .../{2.13.0-M1 => 2.13.0-M2}/run/issue192.sem | 0 .../run/macro-bundle-static.check | 0 .../run/macro-bundle-toplevel.check | 0 .../run/macro-bundle-whitebox-decl.check | 0 .../{2.13.0-M1 => 2.13.0-M2}/run/misc.check | 0 .../run/promotion.check | 0 .../run/runtime.check | 0 .../run/spec-self.check | 0 .../run/structural.check | 0 .../run/t0421-new.check | 0 .../run/t0421-old.check | 0 .../{2.13.0-M1 => 2.13.0-M2}/run/t1503.sem | 0 .../{2.13.0-M1 => 2.13.0-M2}/run/t3702.check | 0 .../{2.13.0-M1 => 2.13.0-M2}/run/t4148.sem | 0 .../{2.13.0-M1 => 2.13.0-M2}/run/t4617.check | 0 .../{2.13.0-M1 => 2.13.0-M2}/run/t5356.check | 0 .../{2.13.0-M1 => 2.13.0-M2}/run/t5552.check | 0 .../{2.13.0-M1 => 2.13.0-M2}/run/t5568.check | 0 .../{2.13.0-M1 => 2.13.0-M2}/run/t5629b.check | 0 .../{2.13.0-M1 => 2.13.0-M2}/run/t5680.check | 0 .../{2.13.0-M1 => 2.13.0-M2}/run/t5866.check | 0 .../run/t6318_primitives.check | 0 .../{2.13.0-M1 => 2.13.0-M2}/run/t6662.check | 0 .../{2.13.0-M1 => 2.13.0-M2}/run/t7657.check | 0 .../{2.13.0-M1 => 2.13.0-M2}/run/t7763.sem | 0 .../{2.13.0-M1 => 2.13.0-M2}/run/t8570a.check | 0 .../{2.13.0-M1 => 2.13.0-M2}/run/t8764.check | 0 .../{2.13.0-M1 => 2.13.0-M2}/run/t9387b.check | 0 .../{2.13.0-M1 => 2.13.0-M2}/run/t9656.check | 0 .../run/try-catch-unify.check | 0 .../run/virtpatmat_switch.check | 0 .../run/virtpatmat_typetag.check | 0 project/Build.scala | 4 +-- .../BlacklistedTests.txt | 5 ++++ .../WhitelistedTests.txt | 0 scripts/build-all-js.sh | 2 +- scripts/publish.sh | 4 +-- .../testsuite/compiler/RegressionTest.scala | 4 +-- 64 files changed, 68 insertions(+), 28 deletions(-) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/BlacklistedTests.txt (98%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/BuglistedTests.txt (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/WhitelistedTests.txt (99%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/neg/t6446-additional.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/neg/t6446-list.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/neg/t6446-missing.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/neg/t6446-show-phases.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/neg/t7494-no-options.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/Course-2002-01.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/Course-2002-02.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/Course-2002-04.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/Course-2002-08.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/Course-2002-09.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/Course-2002-10.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/Meter.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/MeterCaseClass.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/bugs.sem (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/caseClassHash.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/deeps.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/dynamic-anyval.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/impconvtimes.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/imports.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/interpolation.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/interpolationMultiline1.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/issue192.sem (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/macro-bundle-static.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/macro-bundle-toplevel.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/macro-bundle-whitebox-decl.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/misc.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/promotion.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/runtime.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/spec-self.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/structural.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/t0421-new.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/t0421-old.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/t1503.sem (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/t3702.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/t4148.sem (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/t4617.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/t5356.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/t5552.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/t5568.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/t5629b.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/t5680.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/t5866.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/t6318_primitives.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/t6662.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/t7657.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/t7763.sem (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/t8570a.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/t8764.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/t9387b.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/t9656.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/try-catch-unify.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/virtpatmat_switch.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M1 => 2.13.0-M2}/run/virtpatmat_typetag.check (100%) rename scala-test-suite/src/test/resources/{2.13.0-M1 => 2.13.0-M2}/BlacklistedTests.txt (95%) rename scala-test-suite/src/test/resources/{2.13.0-M1 => 2.13.0-M2}/WhitelistedTests.txt (100%) diff --git a/ci/checksizes.sh b/ci/checksizes.sh index ce308ea906..3d5baecf83 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -14,8 +14,8 @@ case $FULLVER in 2.12.3) VER=2.12 ;; - 2.13.0-M1) - VER=2.13.0-M1 + 2.13.0-M2) + VER=2.13.0-M2 ;; 2.10.3|2.10.4|2.10.5|2.10.6|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7|2.11.8|2.12.0|2.12.1|2.12.2) echo "Ignoring checksizes for Scala $FULLVER" @@ -54,7 +54,7 @@ case $FULLVER in REVERSI_PREOPT_GZ_EXPECTEDSIZE=76000 REVERSI_OPT_GZ_EXPECTEDSIZE=33000 ;; - 2.13.0-M1) + 2.13.0-M2) REVERSI_PREOPT_EXPECTEDSIZE=627000 REVERSI_OPT_EXPECTEDSIZE=147000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=76000 diff --git a/ci/matrix.xml b/ci/matrix.xml index dc61f4a53d..a83bab2bf5 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -330,7 +330,7 @@ 1.8 - 2.13.0-M1 + 2.13.0-M2 1.8 @@ -351,7 +351,7 @@ testSuite - 2.13.0-M1 + 2.13.0-M2 1.8 testSuite @@ -368,7 +368,7 @@ scalaTestSuite - 2.13.0-M1 + 2.13.0-M2 1.8 scalaTestSuite @@ -390,7 +390,7 @@ testSuite - 2.13.0-M1 + 2.13.0-M2 1.8 testSuite @@ -407,7 +407,7 @@ scalaTestSuite - 2.13.0-M1 + 2.13.0-M2 1.8 scalaTestSuite @@ -426,7 +426,7 @@ 1.8 - 2.13.0-M1 + 2.13.0-M2 1.8 @@ -473,7 +473,7 @@ 1.8 - 2.13.0-M1 + 2.13.0-M2 1.8 @@ -617,11 +617,11 @@ 1.8 - 2.13.0-M1 + 2.13.0-M2 1.8 - 2.13.0-M1 + 2.13.0-M2 1.8 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/BlacklistedTests.txt similarity index 98% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/BlacklistedTests.txt rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/BlacklistedTests.txt index 2040dfafd3..bfcaacc440 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/BlacklistedTests.txt @@ -60,6 +60,7 @@ run/lambda-serialization-gc.scala run/t9390.scala run/t9390b.scala run/t9390c.scala +run/trait-defaults-super.scala run/t2849.scala run/t1360.scala @@ -134,6 +135,9 @@ run/t9365.scala run/inlineAddDeserializeLambda.scala run/sammy_seriazable.scala run/lambda-serialization-security.scala +run/t10232.scala +run/t10233.scala +run/t10244.scala # Using System.getProperties @@ -612,6 +616,9 @@ run/inferred-type-constructors-hou.scala run/trait-static-forwarder run/SD-235.scala run/t10026.scala +run/checkinit.scala +run/reflection-clinit +run/reflection-clinit-nested # Uses refletction indirectly through # scala.runtime.ScalaRunTime.replStringOf @@ -654,6 +661,9 @@ run/optimizer-array-load.scala run/t6827.scala run/t8601.scala +# Expecting exceptions that are linking errors in Scala.js (e.g. NoSuchMethodException) +run/t10334.scala + # Playing with classfile format run/classfile-format-51.scala @@ -697,7 +707,6 @@ run/repl-paste-2.scala run/t5655.scala run/t5072.scala run/repl-colon-type.scala -run/kind-repl-command.scala run/repl-trim-stack-trace.scala run/t4594-repl-settings.scala run/repl-save.scala @@ -779,6 +788,9 @@ run/t9689 run/trailing-commas.scala run/t4700.scala run/t9880-9881.scala +run/repl-kind.scala +run/t10284.scala +run/t9016.scala # Using Scala Script (partest.ScriptTest) @@ -914,6 +926,8 @@ run/t9206.scala run/t9170.scala run/t8918-unary-ids.scala run/t1931.scala +run/t8935-class.scala +run/t8935-object.scala # partest.JavapTest run/t8608-no-format.scala @@ -967,6 +981,14 @@ run/t3236 run/t9013 run/t10231 run/t10067 +run/t10249 +run/sd143 +run/t4283b +run/t7936 +run/t7936b +run/t9937 +run/t10368 +run/t10334b # Using scala-script run/t7791-script-linenums.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/BuglistedTests.txt similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/BuglistedTests.txt rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/BuglistedTests.txt diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/WhitelistedTests.txt similarity index 99% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/WhitelistedTests.txt rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/WhitelistedTests.txt index c7eb192cbd..68440d3843 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/WhitelistedTests.txt @@ -193,7 +193,6 @@ pos/t5639 pos/t2667.scala pos/t2405.scala pos/t1438.scala -pos/SI-7100.scala pos/t1659.scala pos/unchecked-a.scala pos/t3636.scala @@ -210,7 +209,6 @@ pos/virtpatmat_anonfun_for.scala pos/listpattern.scala pos/t5742.scala pos/test5refine.scala -pos/t5604 pos/return_thistype.scala pos/t348plus.scala pos/t3420.scala @@ -1687,7 +1685,6 @@ pos/t4269.scala pos/lookupswitch.scala pos/t3642 pos/t5706.scala -pos/SI-5788.scala pos/t7264 pos/t0031.scala pos/macro-deprecate-dont-touch-backquotedidents.scala @@ -2225,7 +2222,6 @@ neg/lazy-override.scala neg/abstract-explaintypes.scala neg/nested-annotation.scala neg/t5753 -neg/t4283b neg/t3691.scala neg/infix-op-positions.scala neg/t3403.scala @@ -2565,7 +2561,6 @@ pos/private-types-after-typer.scala pos/delambdafy-lambdalift.scala pos/sammy_poly.scala pos/sammy_single.scala -pos/SI-4012-b.scala pos/sammy_twice.scala pos/t3160.scala pos/t1014.scala @@ -2916,8 +2911,6 @@ run/t1505.scala run/streams.scala run/t2111.scala run/t4601.scala -pos/SI-4012-a.scala -pos/SI-7638.scala neg/t3692-new.scala run/t7015.scala run/t7992b.scala @@ -3146,7 +3139,6 @@ pos/hkgadt.scala pos/t2712-7.scala pos/t9245.scala pos/t7088.scala -pos/trait-defaults-super.scala pos/t8044.scala pos/t9665.scala pos/t9397.scala @@ -3266,6 +3258,27 @@ run/t10261 run/t9114.scala run/InferOverloadedPartialFunction.scala run/t10069b.scala +pos/t5788.scala +pos/t10205.scala +pos/t7100.scala +pos/t4012-b.scala +pos/t7638.scala +pos/leibniz_liskov.scala +pos/t4012-a.scala +pos/dotless-targs-ranged.scala +neg/badtok-1-212.scala +neg/moduleClassReference.scala +neg/t5355.scala +neg/t10081.scala +neg/t6714.scala +neg/t10249 +run/macro-implicit-decorator +run/t10290.scala +run/t10298.scala +run/t10389.scala +run/t6714.scala +run/t9146.scala +run/wacky-value-classes.scala # Adapt checkfiles for (1.0).toString == "1" run/Course-2002-01.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-additional.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t6446-additional.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-additional.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t6446-list.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-list.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t6446-list.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-list.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-missing.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t6446-missing.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-missing.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-show-phases.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t6446-show-phases.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-show-phases.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t7494-no-options.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/neg/t7494-no-options.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t7494-no-options.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-01.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Course-2002-01.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-01.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Course-2002-01.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-02.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Course-2002-02.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-02.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Course-2002-02.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-04.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Course-2002-04.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-04.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Course-2002-04.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-08.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Course-2002-08.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-08.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Course-2002-08.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-09.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Course-2002-09.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-09.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Course-2002-09.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-10.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Course-2002-10.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Course-2002-10.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Course-2002-10.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Meter.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Meter.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/Meter.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Meter.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/MeterCaseClass.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/MeterCaseClass.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/MeterCaseClass.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/MeterCaseClass.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/bugs.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/bugs.sem similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/bugs.sem rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/bugs.sem diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/caseClassHash.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/caseClassHash.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/caseClassHash.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/caseClassHash.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/deeps.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/deeps.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/deeps.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/deeps.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/dynamic-anyval.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/dynamic-anyval.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/dynamic-anyval.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/dynamic-anyval.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/impconvtimes.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/impconvtimes.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/impconvtimes.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/impconvtimes.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/imports.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/imports.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/imports.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/imports.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/interpolation.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/interpolation.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/interpolation.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/interpolation.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/interpolationMultiline1.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/interpolationMultiline1.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/interpolationMultiline1.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/interpolationMultiline1.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/issue192.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/issue192.sem similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/issue192.sem rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/issue192.sem diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/macro-bundle-static.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/macro-bundle-static.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/macro-bundle-static.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/macro-bundle-static.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/macro-bundle-toplevel.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/macro-bundle-toplevel.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/macro-bundle-toplevel.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/macro-bundle-toplevel.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/macro-bundle-whitebox-decl.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/macro-bundle-whitebox-decl.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/macro-bundle-whitebox-decl.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/macro-bundle-whitebox-decl.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/misc.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/misc.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/misc.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/misc.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/promotion.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/promotion.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/promotion.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/promotion.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/runtime.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/runtime.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/runtime.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/runtime.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/spec-self.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/spec-self.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/spec-self.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/spec-self.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/structural.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/structural.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/structural.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/structural.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t0421-new.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t0421-new.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t0421-new.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t0421-new.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t0421-old.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t0421-old.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t0421-old.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t0421-old.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t1503.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t1503.sem similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t1503.sem rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t1503.sem diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t3702.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t3702.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t3702.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t3702.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t4148.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t4148.sem similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t4148.sem rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t4148.sem diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t4617.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t4617.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t4617.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t4617.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5356.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t5356.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5356.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t5356.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5552.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t5552.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5552.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t5552.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5568.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t5568.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5568.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t5568.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5629b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t5629b.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5629b.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t5629b.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5680.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t5680.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5680.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t5680.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5866.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t5866.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t5866.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t5866.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t6318_primitives.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t6318_primitives.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t6318_primitives.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t6318_primitives.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t6662.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t6662.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t6662.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t6662.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t7657.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t7657.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t7657.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t7657.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t7763.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t7763.sem similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t7763.sem rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t7763.sem diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t8570a.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t8570a.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t8570a.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t8570a.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t8764.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t8764.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t8764.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t8764.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t9387b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t9387b.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t9387b.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t9387b.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t9656.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t9656.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/t9656.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t9656.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/try-catch-unify.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/try-catch-unify.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/try-catch-unify.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/try-catch-unify.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/virtpatmat_switch.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/virtpatmat_switch.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/virtpatmat_switch.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/virtpatmat_switch.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/virtpatmat_typetag.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/virtpatmat_typetag.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M1/run/virtpatmat_typetag.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/virtpatmat_typetag.check diff --git a/project/Build.scala b/project/Build.scala index df4235002f..d64af0e1b7 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -63,7 +63,7 @@ object Build { CrossVersion.binaryMapped(v => s"sjs${previousSJSBinaryVersion}_$v") val scalaVersionsUsedForPublishing: Set[String] = - Set("2.10.6", "2.11.11", "2.12.3", "2.13.0-M1") + Set("2.10.6", "2.11.11", "2.12.3", "2.13.0-M2") val newScalaBinaryVersionsInThisRelease: Set[String] = Set() @@ -459,7 +459,7 @@ object Build { "2.12.1", "2.12.2", "2.12.3", - "2.13.0-M1" + "2.13.0-M2" ), // JDK version we are running with javaVersion in Global := { diff --git a/scala-test-suite/src/test/resources/2.13.0-M1/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.13.0-M2/BlacklistedTests.txt similarity index 95% rename from scala-test-suite/src/test/resources/2.13.0-M1/BlacklistedTests.txt rename to scala-test-suite/src/test/resources/2.13.0-M2/BlacklistedTests.txt index de9f1669f0..ee24361b6f 100644 --- a/scala-test-suite/src/test/resources/2.13.0-M1/BlacklistedTests.txt +++ b/scala-test-suite/src/test/resources/2.13.0-M2/BlacklistedTests.txt @@ -23,8 +23,11 @@ scala/tools/nsc/backend/jvm/BTypesTest.scala scala/tools/nsc/backend/jvm/BytecodeTest.scala scala/tools/nsc/backend/jvm/DefaultMethodTest.scala scala/tools/nsc/backend/jvm/DirectCompileTest.scala +scala/tools/nsc/backend/jvm/GenericSignaturesTest.scala scala/tools/nsc/backend/jvm/IndyLambdaTest.scala scala/tools/nsc/backend/jvm/IndySammyTest.scala +scala/tools/nsc/backend/jvm/InnerClassAttributeTest.scala +scala/tools/nsc/backend/jvm/NestedClassesCollectorTest.scala scala/tools/nsc/backend/jvm/OptimizedBytecodeTest.scala scala/tools/nsc/backend/jvm/StringConcatTest.scala scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala @@ -40,6 +43,7 @@ scala/tools/nsc/backend/jvm/opt/InlineInfoTest.scala scala/tools/nsc/backend/jvm/opt/InlinerIllegalAccessTest.scala scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala scala/tools/nsc/backend/jvm/opt/InlinerTest.scala +scala/tools/nsc/backend/jvm/opt/InlineSourceMatcherTest.scala scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala scala/tools/nsc/backend/jvm/opt/MethodLevelOptsTest.scala scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala @@ -74,6 +78,7 @@ scala/tools/testing/RunTesting.scala ## Do not link scala/CollectTest.scala +scala/MatchErrorSerializationTest.scala scala/PartialFunctionSerializationTest.scala scala/lang/stringinterpol/StringContextTest.scala scala/collection/IteratorTest.scala diff --git a/scala-test-suite/src/test/resources/2.13.0-M1/WhitelistedTests.txt b/scala-test-suite/src/test/resources/2.13.0-M2/WhitelistedTests.txt similarity index 100% rename from scala-test-suite/src/test/resources/2.13.0-M1/WhitelistedTests.txt rename to scala-test-suite/src/test/resources/2.13.0-M2/WhitelistedTests.txt diff --git a/scripts/build-all-js.sh b/scripts/build-all-js.sh index aab8f84812..d35327a904 100755 --- a/scripts/build-all-js.sh +++ b/scripts/build-all-js.sh @@ -3,7 +3,7 @@ tasks="fastOptJS fullOptJS" projects="helloworld/ reversi/ testingExample/test: testSuite/test:" -for v in 2.11.11 2.10.6 2.12.3 2.13.0-M1; do +for v in 2.11.11 2.10.6 2.12.3 2.13.0-M2; do echo "++$v" echo "package" diff --git a/scripts/publish.sh b/scripts/publish.sh index b6a7327c96..f5257dcaf2 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -8,8 +8,8 @@ else CMD="echo sbt" fi -FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0-M1" -BIN_VERSIONS="2.10.6 2.11.11 2.12.3 2.13.0-M1" +FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0-M2" +BIN_VERSIONS="2.10.6 2.11.11 2.12.3 2.13.0-M2" CLI_VERSIONS="2.10.6 2.11.11 2.12.3" SBT_VERSION="2.10.6" SBT1_VERSION="2.12.3" diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala index 830befc087..0a70030878 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala @@ -635,9 +635,9 @@ class RegressionTest { @Test def super_mixin_call_in_2_12_issue_3013(): Unit = { assumeTrue( - "Super mixin calls are broken in Scala/JVM 2.12.{0-2} and 2.13.0-M1", + "Super mixin calls are broken in Scala/JVM 2.12.{0-2}", !Platform.executingInJVM || - !Set("2.12.0", "2.12.1", "2.12.2", "2.13.0-M1").contains(Platform.scalaVersion)) + !Set("2.12.0", "2.12.1", "2.12.2").contains(Platform.scalaVersion)) import Bug3013._ From 7057b070a1dae1a521acc2e5b74a94f0b830383c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 20 Aug 2017 13:13:05 +0200 Subject: [PATCH 0452/2665] Introduce better names for `OutputMode`s in the public API. The "Isolated" in `ECMAScript51Isolated` does not mean anything to external users. It really should be `ECMAScript51` from a user point of view. ECMAScript 2015 is the real, official name of ES 6. Therefore we introduce `ECMAScript2015` as replacement for `ECMAScript6`. --- .../tools/linker/backend/OutputMode.scala | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala index aa849a4e70..dd9479c062 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala @@ -36,33 +36,38 @@ object OutputMode { val esLevel: ESLevel = ESLevel.ES5 } - /** Modern output mode compliant with ECMAScript 5.1 in a function scope. - * This is the default output mode used by fastOpt and fullOpt. - * The output must be enclosed in an anonymous function isolating the code - * in a dedicated scope. + /** Output mode compliant with ECMAScript 5.1 (deprecated alias). + * + * This value is not annotated with `@deprecated` for technical reasons, but + * it should be considered as such. Use [[ECMAScript51]] instead. */ case object ECMAScript51Isolated extends OutputMode { val esLevel: ESLevel = ESLevel.ES5 } - /** Experimental output mode compliant with ECMAScript 6 in a function scope. - * - * This output mode assumes that the target platform supports ECMAScript 6, - * at least for the following aspects: + /** Output mode compliant with ECMAScript 5.1. * - * * Classes - * * let and const - * * Rest parameters and the spread operator (...args) - * * New methods in Math - * * Symbols and the "well-known symbol" Symbol.iterator + * This is the default output mode. It assumes that the target platform + * supports ECMAScript 5.1, ideally with correct handling of strict mode. + */ + val ECMAScript51: ECMAScript51Isolated.type = ECMAScript51Isolated + + /** Output mode compliant with ECMAScript 2015 (deprecated alias). * - * The output must be enclosed in an anonymous function isolating the code - * in a dedicated scope. + * This value is not annotated with `@deprecated` for technical reasons, but + * it should be considered as such. Use [[ECMAScript2015]] instead. */ case object ECMAScript6 extends OutputMode { val esLevel: ESLevel = ESLevel.ES6 } + /** Output mode compliant with ECMAScript 2015. + * + * This output mode assumes that the target platform supports ECMAScript + * 2015 (aka ES 6). + */ + val ECMAScript2015: ECMAScript6.type = ECMAScript6 + // Not binary compatible, but source compatible with deprecation @deprecated("Support for ES6 Strong Mode was removed. Use ECMAScript6 instead.", "0.6.8") lazy val ECMAScript6StrongMode: ECMAScript6.type = ECMAScript6 From 8a0bd6fcfa5c72ab5816c3ce7eff8e0d0998f2ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 19 Aug 2017 12:19:06 +0200 Subject: [PATCH 0453/2665] [no-master] Deprecate `jsDependencies += RuntimeDOM` and `requiresDOM := true`. Along with other related stuff, such as `scalaJSRequestsDOM` and `JSDependencyManifest.requiresDOM`. They will not be supported by `sbt-jsdependencies` 1.x. --- project/Build.scala | 2 +- .../scalajs/sbtplugin/AbstractJSDeps.scala | 12 +++++++ .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 15 ++++++-- .../sbtplugin/ScalaJSPluginInternal.scala | 27 +++++++++----- .../sbtplugin/impl/DependencyBuilders.scala | 6 ++++ .../tools/jsdep/JSDependencyManifest.scala | 36 ++++++++++++++----- .../core/tools/jsdep/ManifestFilters.scala | 3 +- .../jsdep/ComplianceRequirementTest.scala | 2 +- .../tools/jsdep/ManifestFiltersTest.scala | 3 +- 9 files changed, 81 insertions(+), 25 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index d64af0e1b7..d22ca98108 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1309,7 +1309,7 @@ object Build { moduleName := "testing", jsDependencies ++= Seq( - RuntimeDOM % "test", + RuntimeDOMDep(None) % "test", "org.webjars" % "jquery" % "1.10.2" / "jquery.js" % "test" ) ) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/AbstractJSDeps.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/AbstractJSDeps.scala index 5312f7906c..37b365fc30 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/AbstractJSDeps.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/AbstractJSDeps.scala @@ -75,6 +75,18 @@ object ProvidedJSModuleID { ProvidedJSModuleID(new JSDependency(name, Nil), configurations) } +/* If we mark RuntimeDOMDep as @deprecated, we cannot pattern-match on it in + * our own implementation to implement its behavior. Therefore it is only + * deprecated in the documentation. This shouldn't be an issue because it is + * not advertised as a public API anyway. Instead, it is typically constructed + * using the RuntimeDOM DSL in sbtplugin.impl.DependencyBuilders (which is + * actually @deprecated). + */ +/** Deprecated. + * + * For internal reasons, this class is not marked as `@deprecated`, but should + * be considered as such. + */ final case class RuntimeDOMDep( configurations: Option[String]) extends AbstractJSDep { diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 8b32e8fc9c..a5a8d31861 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -69,9 +69,9 @@ object ScalaJSPlugin extends AutoPlugin { /* We take the semantics from the linker, since they depend on the stage. * This way we are sure we agree on the semantics with the linker. */ - import ScalaJSPluginInternal.{scalaJSLinker, scalaJSRequestsDOM} + import ScalaJSPluginInternal.{scalaJSLinker, scalaJSRequestsDOMInternal} val semantics = scalaJSLinker.value.semantics - val withDOM = scalaJSRequestsDOM.value + val withDOM = scalaJSRequestsDOMInternal.value new RhinoJSEnv(semantics, withDOM, internal = ()) } @@ -337,9 +337,18 @@ object ScalaJSPlugin extends AutoPlugin { @deprecated("Use jsEnv instead.", "0.6.6") val postLinkJSEnv = jsEnv - val requiresDOM = SettingKey[Boolean]("requiresDOM", + /** Non-deprecated alias of `requiresDOM` for internal use. */ + private[sbtplugin] val requiresDOMInternal = SettingKey[Boolean]("requiresDOM", "Whether this projects needs the DOM. Overrides anything inherited through dependencies.", AMinusSetting) + @deprecated( + "Requesting a DOM-enabled JS env with `jsDependencies += RuntimeDOM` " + + "or `requiresDOM := true` will not be supported in Scala.js 1.x. " + + "Instead, explicitly select a suitable JS with `jsEnv`, e.g., " + + "`jsEnv := new org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv`.", + "0.6.20") + val requiresDOM = requiresDOMInternal + val relativeSourceMaps = SettingKey[Boolean]("relativeSourceMaps", "Make the referenced paths on source maps relative to target path", BPlusSetting) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 482c6c420e..6d02a69570 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -74,12 +74,23 @@ object ScalaJSPluginInternal { val scalaJSIRCache = TaskKey[globalIRCache.Cache]("scalaJSIRCache", "Scala.js internal: Task to access a cache.", KeyRanks.Invisible) - /** Internal task to calculate whether a project requests the DOM - * (through jsDependencies or requiresDOM) */ - val scalaJSRequestsDOM = TaskKey[Boolean]("scalaJSRequestsDOM", + /** Non-deprecated alias of `scalaJSRequestsDOM` for internal use. */ + private[sbtplugin] val scalaJSRequestsDOMInternal = TaskKey[Boolean]( + "scalaJSRequestsDOM", "Scala.js internal: Whether a project really wants the DOM. " + "Calculated using requiresDOM and jsDependencies", KeyRanks.Invisible) + /** Internal task to calculate whether a project requests the DOM + * (through jsDependencies or requiresDOM) */ + @deprecated( + "`scalaJSRequestsDOM` will always be false in new builds, because " + + "`jsDependencies += RuntimeDOM` and `requiresDOM := true` are " + + "deprecated. A better alternative to reading `scalaJSRequestsDOM` is " + + "to detect whether `resolvedJSEnv` is a DOM-enabled JS env, or to use " + + "your own setting key.", + "0.6.20") + val scalaJSRequestsDOM = scalaJSRequestsDOMInternal + /** All .sjsir files on the fullClasspath, used by scalajsp. */ val sjsirFilesOnClasspath = TaskKey[Seq[String]]("sjsirFilesOnClasspath", "All .sjsir files on the fullClasspath, used by scalajsp", @@ -548,7 +559,7 @@ object ScalaJSPluginInternal { val compliantSemantics = scalaJSSemantics.value.compliants val manifest = new JSDependencyManifest(new Origin(myModule, config), - jsDeps.toList, requiresDOM, compliantSemantics) + jsDeps.toList, requiresDOM, compliantSemantics, internal = ()) // Write dependency file to class directory val targetDir = classDirectory.value @@ -644,15 +655,15 @@ object ScalaJSPluginInternal { true }, - scalaJSRequestsDOM := { - requiresDOM.?.value.getOrElse( - jsDependencyManifests.value.data.exists(_.requiresDOM)) + scalaJSRequestsDOMInternal := { + requiresDOMInternal.?.value.getOrElse( + jsDependencyManifests.value.data.exists(_.requiresDOMInternal)) }, resolvedJSEnv := { val useRhino = scalaJSUseRhinoInternal.value val rhinoJSEnv = RhinoJSEnvInternal().value - val requestsDOM = scalaJSRequestsDOM.value + val requestsDOM = scalaJSRequestsDOMInternal.value jsEnv.?.value.getOrElse { if (useRhino) { diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/DependencyBuilders.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/DependencyBuilders.scala index ed5c6cf9da..ab1e29306e 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/DependencyBuilders.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/DependencyBuilders.scala @@ -28,6 +28,12 @@ trait DependencyBuilders { * RuntimeDOM % "test" * }}} */ + @deprecated( + "Requesting a DOM-enabled JS env with `jsDependencies += RuntimeDOM` " + + "or `requiresDOM := true` will not be supported in Scala.js 1.x. " + + "Instead, explicitly select a suitable JS with `jsEnv`, e.g., " + + "`jsEnv := new org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv`.", + "0.6.20") val RuntimeDOM = org.scalajs.sbtplugin.RuntimeDOMDep(None) /** diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/JSDependencyManifest.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/JSDependencyManifest.scala index 86862ecc64..368cb9edfa 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/JSDependencyManifest.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/JSDependencyManifest.scala @@ -8,19 +8,36 @@ import scala.collection.immutable.{Seq, Traversable} import java.io.{Reader, Writer} /** The information written to a "JS_DEPENDENCIES" manifest file. */ -final class JSDependencyManifest( +final class JSDependencyManifest private[scalajs] ( val origin: Origin, val libDeps: List[JSDependency], - val requiresDOM: Boolean, - val compliantSemantics: List[String]) { + private[scalajs] val requiresDOMInternal: Boolean, + val compliantSemantics: List[String], + internal: Unit) { import JSDependencyManifest._ + def this(origin: Origin, libDeps: List[JSDependency], + compliantSemantics: List[String]) = { + this(origin, libDeps, false, compliantSemantics, internal = ()) + } + + @deprecated( + "requiresDOM will be removed in 1.x, use the overload without it.", + "0.6.20") + def this(origin: Origin, libDeps: List[JSDependency], requiresDOM: Boolean, + compliantSemantics: List[String]) = { + this(origin, libDeps, requiresDOM, compliantSemantics, internal = ()) + } + + @deprecated("requiresDOM will be removed in 1.x", "0.6.20") + val requiresDOM: Boolean = requiresDOMInternal + override def equals(that: Any): Boolean = that match { case that: JSDependencyManifest => this.origin == that.origin && this.libDeps == that.libDeps && - this.requiresDOM == that.requiresDOM && + this.requiresDOMInternal == that.requiresDOMInternal && this.compliantSemantics == that.compliantSemantics case _ => false @@ -31,7 +48,7 @@ final class JSDependencyManifest( var acc = HashSeed acc = mix(acc, origin.##) acc = mix(acc, libDeps.##) - acc = mix(acc, requiresDOM.##) + acc = mix(acc, requiresDOMInternal.##) acc = mixLast(acc, compliantSemantics.##) finalizeHash(acc, 4) } @@ -41,8 +58,8 @@ final class JSDependencyManifest( b ++= s"JSDependencyManifest(origin=$origin" if (libDeps.nonEmpty) b ++= s", libDeps=$libDeps" - if (requiresDOM) - b ++= s", requiresDOM=$requiresDOM" + if (requiresDOMInternal) + b ++= s", requiresDOM=$requiresDOMInternal" if (compliantSemantics.nonEmpty) b ++= s", compliantSemantics=$compliantSemantics" b ++= ")" @@ -65,7 +82,7 @@ object JSDependencyManifest { new JSONObjBuilder() .fld("origin", x.origin) .opt("libDeps", optList(x.libDeps)) - .opt("requiresDOM", if (x.requiresDOM) Some(true) else None) + .opt("requiresDOM", if (x.requiresDOMInternal) Some(true) else None) .opt("compliantSemantics", optList(x.compliantSemantics)) .toJSON } @@ -78,7 +95,8 @@ object JSDependencyManifest { obj.fld[Origin] ("origin"), obj.opt[List[JSDependency]]("libDeps").getOrElse(Nil), obj.opt[Boolean] ("requiresDOM").getOrElse(false), - obj.opt[List[String]] ("compliantSemantics").getOrElse(Nil)) + obj.opt[List[String]] ("compliantSemantics").getOrElse(Nil), + internal = ()) } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ManifestFilters.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ManifestFilters.scala index 46b932d3a0..5db45ef29f 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ManifestFilters.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ManifestFilters.scala @@ -42,7 +42,8 @@ object ManifestFilters { jsDependency.commonJSName, jsDependency.minifiedResourceName.map(mapping)) new JSDependencyManifest(manifest.origin, filteredJSDeps, - manifest.requiresDOM, manifest.compliantSemantics) + manifest.requiresDOMInternal, manifest.compliantSemantics, + internal = ()) } } } diff --git a/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ComplianceRequirementTest.scala b/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ComplianceRequirementTest.scala index f359c062eb..027ea46036 100644 --- a/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ComplianceRequirementTest.scala +++ b/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ComplianceRequirementTest.scala @@ -48,7 +48,7 @@ class ComplianceRequirementTest { val origins = Array("a", "b", "c").map(new Origin(_, "compile")) def mkManifest(o: Int, semantics: String*) = - new JSDependencyManifest(origins(o), Nil, false, semantics.toList) + new JSDependencyManifest(origins(o), Nil, semantics.toList) val manifests = Seq( mkManifest(0, "isInstanceOfs"), diff --git a/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ManifestFiltersTest.scala b/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ManifestFiltersTest.scala index 49189fd396..9a38d24501 100644 --- a/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ManifestFiltersTest.scala +++ b/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ManifestFiltersTest.scala @@ -8,8 +8,7 @@ class ManifestFiltersTest { private def mkManifest(module: String, deps: String*) = { new JSDependencyManifest(new Origin(module, "compile"), - deps.map(new JSDependency(_)).toList, requiresDOM = false, - compliantSemantics = Nil) + deps.map(new JSDependency(_)).toList, compliantSemantics = Nil) } @Test From 17c95c8531dca74a1df82beedc4b10c922800eba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 19 Aug 2017 13:52:21 +0200 Subject: [PATCH 0454/2665] [no-master] Deprecate js.JSApp. The Scaladoc contains migration tips towards * using a standard `main(args: Array[String]): Unit` method, and/or * explicitly exporting the object. --- .../main/scala/scala/scalajs/js/JSApp.scala | 78 ++++++++++++++----- project/BinaryIncompatibilities.scala | 4 + project/Build.scala | 12 ++- .../sbtplugin/HTMLRunnerTemplate.scala | 2 +- .../scalajs/testinterface/HTMLRunner.scala | 3 +- 5 files changed, 76 insertions(+), 23 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/js/JSApp.scala b/library/src/main/scala/scala/scalajs/js/JSApp.scala index a2705e7c34..c529863189 100644 --- a/library/src/main/scala/scala/scalajs/js/JSApp.scala +++ b/library/src/main/scala/scala/scalajs/js/JSApp.scala @@ -2,34 +2,72 @@ package scala.scalajs.js import annotation.{JSExport, JSExportDescendentObjects} -/** Base class for top-level, entry point main objects (softly deprecated). +/** Old-style base class for top-level, entry point main objects. * - * 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). + * [[JSApp]] provides two services to an `object Foo` that extends it. These + * two services are replaced by two different features, starting with Scala.js + * 0.6.18. * - * Objects inheriting from [[JSApp]] are automatically exported to JavaScript - * under their fully qualified name, and their [[main]] method as well. + * == Discoverability by sbt as main object == * - * [[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. - * - * Starting with Scala.js 0.6.18, the sbt plugin can also recognize "standard" - * `main` methods of the form + * Since Scala.js 0.6.18, the sbt plugin can 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: + * in objects, even if they do not extend `JSApp`. Use such a main method to + * replace [[JSApp]] in the context of discoverability by sbt. + * + * To enable it as main method, make sure you also set + * {{{ + * scalaJSUseMainModuleInitializer := true + * }}} + * in your project settings. + * + * == Automatic export to JavaScript == + * + * Given + * {{{ + * package bar + * + * object Foo extends js.JSApp { + * def main(): Unit = println("Hello world!") + * } + * }}} + * the object `Foo` and its `main` method are automatically exported such that + * JavaScript code can call + * {{{ + * bar.Foo().main(); + * }}} * - * - the sbt plugin cannot create a launcher snippet for such objects, and - * - these objects are not automatically exported to JavaScript. + * To achieve exactly the same behavior without [[JSApp]], define `Foo` as + * {{{ + * package bar + * + * object Foo { + * @JSExportTopLevel("bar.Foo") + * protected def getInstance(): this.type = this + * + * @JSExport + * def main(): Unit = println("Hello world!") + * } + * }}} + * + * Alternatively, you can define it as + * {{{ + * package bar + * + * object Foo { + * @JSExportTopLevel("bar.Foo.main") + * def main(): Unit = println("Hello world!") + * } + * }}} + * but in that case, the JavaScript code will have to be changed to + * {{{ + * bar.Foo.main() + * }}} */ +@deprecated("Consult the Scaladoc of js.JSApp for migration tips.", "0.6.20") @JSExportDescendentObjects trait JSApp { @JSExport diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 62550e2cb0..0bf8f52d8d 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -96,6 +96,10 @@ object BinaryIncompatibilities { ) val TestInterface = Seq( + // protected[testinterface], not an issue. + ProblemFilters.exclude[MissingTypesProblem]( + "org.scalajs.testinterface.HTMLRunner$"), + // internal, not an issue. ProblemFilters.exclude[MissingClassProblem]( "org.scalajs.testinterface.internal.BridgeBase"), diff --git a/project/Build.scala b/project/Build.scala index d22ca98108..69e4f0b38d 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1288,7 +1288,12 @@ object Build { settings = exampleSettings ++ Seq( name := "Hello World - Scala.js example", moduleName := "helloworld", - scalaJSUseMainModuleInitializer := true + scalaJSUseMainModuleInitializer := true, + + /* We have to test js.JSApp somewhere, so we avoid the fatal + * deprecation warning here. + */ + scalacOptions -= "-Xfatal-warnings" ) ).withScalaJSCompiler.dependsOn(library) @@ -1308,6 +1313,11 @@ object Build { name := "Testing - Scala.js example", moduleName := "testing", + /* We have a test for test:run which runs a js.JSApp in the Test + * config. We avoid the fatal deprecation warning here. + */ + scalacOptions -= "-Xfatal-warnings", + jsDependencies ++= Seq( RuntimeDOMDep(None) % "test", "org.webjars" % "jquery" % "1.10.2" / "jquery.js" % "test" diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/HTMLRunnerTemplate.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/HTMLRunnerTemplate.scala index 80674f1ca1..b5122648fe 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/HTMLRunnerTemplate.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/HTMLRunnerTemplate.scala @@ -45,7 +45,7 @@ private[scalajs] object HTMLRunnerTemplate { ${renderTestDefinitions(loadedFrameworks, definedTests)} - + """ } diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala b/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala index 313fd14875..c1b230b0fe 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala @@ -21,7 +21,7 @@ import scala.util.Try import sbt.testing._ -protected[testinterface] object HTMLRunner extends js.JSApp { +protected[testinterface] object HTMLRunner { private val classLoader = new ScalaJSClassLoader(js.Dynamic.global) private object EventCounter { @@ -42,6 +42,7 @@ protected[testinterface] object HTMLRunner extends js.JSApp { } } + @JSExportTopLevel("org.scalajs.testinterface.HTMLRunner.main") def main(): Unit = { /* Note: Test filtering is currently done based on the fully qualified name * of a test. While this is reasonable in most cases, there could be a test From 9c52b02ee760195622fd719e11f4a635f02c8266 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 19 Aug 2017 19:18:52 +0200 Subject: [PATCH 0455/2665] [no-master] Deprecate `@ScalaJSDefined`. Developers are advised to enable `-P:scalajs:sjsDefinedByDefault` and remove `@ScalaJSDefined`. --- .../scalajs/core/compiler/PrepJSInterop.scala | 7 + .../compiler/test/DiverseErrorsTest.scala | 20 +- .../core/compiler/test/JSExportTest.scala | 139 +++----- .../core/compiler/test/JSInteropTest.scala | 254 ++++---------- .../compiler/test/JSNativeByDefaultTest.scala | 199 +++++++++++ .../core/compiler/test/JSOptionalTest.scala | 144 ++++++-- .../core/compiler/test/JSSAMTest.scala | 6 +- .../core/compiler/test/OptimizationTest.scala | 2 - .../core/compiler/test/ReflectTest.scala | 13 +- .../test/SJSDefinedByDefaultTest.scala | 312 ------------------ .../compiler/test/ScalaJSDefinedTest.scala | 144 +++----- .../core/compiler/test/util/DirectTest.scala | 2 +- .../scala/org/scalajs/core/ir/Trees.scala | 3 - .../jsinterop/ScalaJSDefinedTestEx.scala | 2 - .../src/main/scala/scala/scalajs/js/Any.scala | 13 +- .../scala/scala/scalajs/js/Iterable.scala | 1 - .../scala/scala/scalajs/js/Iterator.scala | 2 - .../scala/scala/scalajs/js/JSConverters.scala | 2 - .../scala/scala/scalajs/js/Thenable.scala | 1 - .../scalajs/js/annotation/JSExportNamed.scala | 1 - project/Build.scala | 4 +- .../ScalaJSDefinedTestSeparateRun.scala | 3 - .../jsinterop/JSOptionalTest212.scala | 10 - .../compiler/InteroperabilityTest.scala | 1 - .../testsuite/compiler/OptimizerTest.scala | 1 - .../testsuite/compiler/RegressionJSTest.scala | 2 - .../testsuite/jsinterop/ExportsTest.scala | 21 -- .../testsuite/jsinterop/IterableTest.scala | 2 - .../jsinterop/JSExportStaticTest.scala | 4 - .../testsuite/jsinterop/JSNameTest.scala | 3 - .../testsuite/jsinterop/JSOptionalTest.scala | 13 - .../testsuite/jsinterop/JSSymbolTest.scala | 19 -- .../testsuite/jsinterop/MiscInteropTest.scala | 5 - .../ModulesWithGlobalFallbackTest.scala | 3 - .../testsuite/jsinterop/PromiseMock.scala | 1 - .../jsinterop/ScalaJSDefinedTest.scala | 98 ------ 36 files changed, 513 insertions(+), 944 deletions(-) create mode 100644 compiler/src/test/scala/org/scalajs/core/compiler/test/JSNativeByDefaultTest.scala delete mode 100644 compiler/src/test/scala/org/scalajs/core/compiler/test/SJSDefinedByDefaultTest.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 05c51f30d2..55b3139a62 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -488,6 +488,13 @@ abstract class PrepJSInterop extends plugins.PluginComponent val isJSAnonFun = isJSLambda(sym) + for (annot <- sym.getAnnotation(ScalaJSDefinedAnnotation)) { + reporter.warning(annot.pos, + "@ScalaJSDefined is deprecated: " + + "add `-P:scalajs:sjsDefinedByDefault` to your scalac options and " + + "simply remove `@ScalaJSDefined`") + } + sym.addAnnotation(RawJSTypeAnnot) if (sym.isAnonymousClass && !isJSAnonFun) { sym.addAnnotation(ScalaJSDefinedAnnotation) diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/DiverseErrorsTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/DiverseErrorsTest.scala index 88cd50b182..b71e6aedb6 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/DiverseErrorsTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/DiverseErrorsTest.scala @@ -62,9 +62,9 @@ class DiverseErrorsTest extends DirectTest with TestHelpers { @js.native trait NativeJSTrait extends js.Object @js.native @JSGlobal object NativeJSObject extends js.Object - @ScalaJSDefined class JSClass extends js.Object - @ScalaJSDefined trait JSTrait extends js.Object - @ScalaJSDefined object JSObject extends js.Object + class JSClass extends js.Object + trait JSTrait extends js.Object + object JSObject extends js.Object object A { val a = js.constructorOf[NativeJSTrait] @@ -149,9 +149,9 @@ class DiverseErrorsTest extends DirectTest with TestHelpers { @js.native trait NativeJSTrait extends js.Object @js.native @JSGlobal object NativeJSObject extends js.Object - @ScalaJSDefined class JSClass extends js.Object - @ScalaJSDefined trait JSTrait extends js.Object - @ScalaJSDefined object JSObject extends js.Object + class JSClass extends js.Object + trait JSTrait extends js.Object + object JSObject extends js.Object object A { val a = js.constructorTag[NativeJSTrait] @@ -213,7 +213,7 @@ class DiverseErrorsTest extends DirectTest with TestHelpers { object ScalaObject @js.native @JSGlobal object NativeJSObject extends js.Object - @ScalaJSDefined object JSObject extends js.Object + object JSObject extends js.Object object A { val a = runtime.constructorOf(classOf[ScalaObject.type].asInstanceOf[Class[_ <: js.Any]]) @@ -243,9 +243,9 @@ class DiverseErrorsTest extends DirectTest with TestHelpers { @js.native trait NativeJSTrait extends js.Object @js.native @JSGlobal object NativeJSObject extends js.Object - @ScalaJSDefined class JSClass extends js.Object - @ScalaJSDefined trait JSTrait extends js.Object - @ScalaJSDefined object JSObject extends js.Object + class JSClass extends js.Object + trait JSTrait extends js.Object + object JSObject extends js.Object object A { val a = runtime.constructorOf(classOf[ScalaClass].asInstanceOf[Class[_ <: js.Any]]) diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index 43bc326ef7..320231a47f 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -32,7 +32,7 @@ class JSExportTest extends DirectTest with TestHelpers { class B__ @JSExport - @ScalaJSDefined class C__ extends js.Object + class C__ extends js.Object """ hasErrors """ |newSource1.scala:4: error: An exported name may not contain a double underscore (`__`) @@ -45,8 +45,8 @@ class JSExportTest extends DirectTest with TestHelpers { | class B__ | ^ |newSource1.scala:15: error: An exported name may not contain a double underscore (`__`) - | @ScalaJSDefined class C__ extends js.Object - | ^ + | class C__ extends js.Object + | ^ """ // Inherited exports (objects) @@ -66,16 +66,16 @@ class JSExportTest extends DirectTest with TestHelpers { """ @JSExportDescendentObjects - @ScalaJSDefined trait A extends js.Object + trait A extends js.Object package fo__o { - @ScalaJSDefined object B extends A + object B extends A } """ hasErrors """ |newSource1.scala:7: error: B may not have a double underscore (`__`) in its fully qualified name, since it is forced to be exported by a @JSExportDescendentObjects on trait A - | @ScalaJSDefined object B extends A - | ^ + | object B extends A + | ^ """ // Inherited exports (classes) @@ -101,16 +101,16 @@ class JSExportTest extends DirectTest with TestHelpers { """ @JSExportDescendentClasses - @ScalaJSDefined trait A extends js.Object + trait A extends js.Object package fo__o { - @ScalaJSDefined class B(x: Int) extends A + class B(x: Int) extends A } """ hasErrors """ |newSource1.scala:7: error: B may not have a double underscore (`__`) in its fully qualified name, since it is forced to be exported by a @JSExportDescendentClasses on trait A - | @ScalaJSDefined class B(x: Int) extends A - | ^ + | class B(x: Int) extends A + | ^ """ } @@ -211,7 +211,7 @@ class JSExportTest extends DirectTest with TestHelpers { class A @JSExport - @ScalaJSDefined class B extends js.Object + class B extends js.Object } } """ hasErrors @@ -232,7 +232,7 @@ class JSExportTest extends DirectTest with TestHelpers { object A @JSExport - @ScalaJSDefined object B extends js.Object + object B extends js.Object } } """ hasErrors @@ -339,7 +339,7 @@ class JSExportTest extends DirectTest with TestHelpers { } @JSExport - @ScalaJSDefined abstract class C extends js.Object + abstract class C extends js.Object """ hasErrors """ |newSource1.scala:3: error: You may not export an abstract class @@ -363,7 +363,7 @@ class JSExportTest extends DirectTest with TestHelpers { trait Test @JSExport - @ScalaJSDefined trait Test2 extends js.Object + trait Test2 extends js.Object @JSExport @js.native @@ -394,10 +394,10 @@ class JSExportTest extends DirectTest with TestHelpers { protected[this] class B @JSExport - @ScalaJSDefined private class C extends js.Object + private class C extends js.Object @JSExport - @ScalaJSDefined protected[this] class D extends js.Object + protected[this] class D extends js.Object """ hasErrors """ |newSource1.scala:3: error: You may only export public and protected classes @@ -422,10 +422,10 @@ class JSExportTest extends DirectTest with TestHelpers { protected[this] object B @JSExport - @ScalaJSDefined private object C extends js.Object + private object C extends js.Object @JSExport - @ScalaJSDefined protected[this] object D extends js.Object + protected[this] object D extends js.Object """ hasErrors """ |newSource1.scala:3: error: You may only export public and protected objects @@ -479,7 +479,7 @@ class JSExportTest extends DirectTest with TestHelpers { } @JSExport - @ScalaJSDefined class Nested2 extends js.Object + class Nested2 extends js.Object } """ hasErrors """ @@ -508,7 +508,7 @@ class JSExportTest extends DirectTest with TestHelpers { } @JSExport - @ScalaJSDefined class Nested2 extends js.Object + class Nested2 extends js.Object } """ hasErrors """ @@ -534,7 +534,7 @@ class JSExportTest extends DirectTest with TestHelpers { object Nested @JSExport - @ScalaJSDefined object Nested2 extends js.Object + object Nested2 extends js.Object } """ hasErrors """ @@ -557,7 +557,7 @@ class JSExportTest extends DirectTest with TestHelpers { object Nested @JSExport - @ScalaJSDefined object Nested2 extends js.Object + object Nested2 extends js.Object } """ hasErrors """ @@ -645,14 +645,13 @@ class JSExportTest extends DirectTest with TestHelpers { """ import scala.scalajs.js - @ScalaJSDefined class A extends js.Object { @JSExport def foo: Int = js.native } """ hasErrors """ - |newSource1.scala:7: error: You may not export a method of a subclass of js.Any + |newSource1.scala:6: error: You may not export a method of a subclass of js.Any | @JSExport | ^ """ @@ -889,7 +888,7 @@ class JSExportTest extends DirectTest with TestHelpers { object A @JSExportNamed - @ScalaJSDefined object B extends js.Object + object B extends js.Object """ hasErrors """ |newSource1.scala:3: error: You may not use @JSNamedExport on an object @@ -907,7 +906,7 @@ class JSExportTest extends DirectTest with TestHelpers { """ @JSExportNamed - @ScalaJSDefined class A extends js.Object + class A extends js.Object """ hasErrors """ |newSource1.scala:3: error: You may not use @JSNamedExport on a Scala.js-defined JS class @@ -1108,7 +1107,6 @@ class JSExportTest extends DirectTest with TestHelpers { trait A @JSExportTopLevel("bar") - @ScalaJSDefined trait B extends js.Object """ hasErrors """ @@ -1126,7 +1124,6 @@ class JSExportTest extends DirectTest with TestHelpers { trait A @JSExportTopLevel("bar") - @ScalaJSDefined trait B extends js.Object } """ hasErrors @@ -1279,7 +1276,6 @@ class JSExportTest extends DirectTest with TestHelpers { """ class A { @JSExportTopLevel("Foo") - @ScalaJSDefined object B extends js.Object } """ hasErrors @@ -1292,7 +1288,6 @@ class JSExportTest extends DirectTest with TestHelpers { """ class A { @JSExportTopLevel("Foo") - @ScalaJSDefined class B extends js.Object } """ hasErrors @@ -1318,14 +1313,13 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportTopLevelJSModule: Unit = { """ - @ScalaJSDefined object A extends js.Object { @JSExportTopLevel("foo") def a(): Unit = () } """ hasErrors """ - |newSource1.scala:5: error: You may not export a method of a subclass of js.Any + |newSource1.scala:4: error: You may not export a method of a subclass of js.Any | @JSExportTopLevel("foo") | ^ """ @@ -1334,7 +1328,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticModule: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1343,7 +1336,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Implementation restriction: cannot export a class or object as static + |newSource1.scala:6: error: Implementation restriction: cannot export a class or object as static | @JSExportStatic | ^ """ @@ -1352,7 +1345,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticTrait: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1361,7 +1353,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: You may not export a trait as static. + |newSource1.scala:6: error: You may not export a trait as static. | @JSExportStatic | ^ """ @@ -1370,7 +1362,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticClass: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1379,13 +1370,12 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Implementation restriction: cannot export a class or object as static + |newSource1.scala:6: error: Implementation restriction: cannot export a class or object as static | @JSExportStatic | ^ """ """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1396,7 +1386,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Implementation restriction: cannot export a class or object as static + |newSource1.scala:7: error: Implementation restriction: cannot export a class or object as static | @JSExportStatic | ^ """ @@ -1405,7 +1395,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticValTwice: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1415,7 +1404,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Fields (val or var) cannot be exported as static more than once + |newSource1.scala:7: error: Fields (val or var) cannot be exported as static more than once | @JSExportStatic("b") | ^ """ @@ -1424,7 +1413,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticVarTwice: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1434,7 +1422,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Fields (val or var) cannot be exported as static more than once + |newSource1.scala:7: error: Fields (val or var) cannot be exported as static more than once | @JSExportStatic("b") | ^ """ @@ -1446,7 +1434,6 @@ class JSExportTest extends DirectTest with TestHelpers { assumeTrue(scala.util.Properties.versionNumberString != "2.12.0") """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1455,7 +1442,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: You may not export a lazy val as static + |newSource1.scala:6: error: You may not export a lazy val as static | @JSExportStatic | ^ """ @@ -1464,7 +1451,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportValAsStaticAndTopLevel: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1474,7 +1460,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Fields (val or var) cannot be exported both as static and at the top-level + |newSource1.scala:7: error: Fields (val or var) cannot be exported both as static and at the top-level | @JSExportTopLevel("foo") | ^ """ @@ -1483,7 +1469,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportVarAsStaticAndTopLevel: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1493,7 +1478,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Fields (val or var) cannot be exported both as static and at the top-level + |newSource1.scala:7: error: Fields (val or var) cannot be exported both as static and at the top-level | @JSExportTopLevel("foo") | ^ """ @@ -1502,7 +1487,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportSetterWithBadSetterType: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1511,7 +1495,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Exported setters must have exactly one argument + |newSource1.scala:6: error: Exported setters must have exactly one argument | @JSExportStatic | ^ """ @@ -1520,7 +1504,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticCollapsingMethods: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1532,7 +1515,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:11: error: Cannot disambiguate overloads for exported method bar with types + |newSource1.scala:10: error: Cannot disambiguate overloads for exported method bar with types | (x: Int)Int | (x: Int)Int | def bar(x: Int): Int = x + 1 @@ -1543,7 +1526,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticCollapsingGetters: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1555,7 +1537,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Duplicate static getter export with name 'foo' + |newSource1.scala:7: error: Duplicate static getter export with name 'foo' | def foo: Int = 1 | ^ """ @@ -1564,7 +1546,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticCollapsingSetters: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1576,7 +1557,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:11: error: Cannot disambiguate overloads for exported method bar_$eq with types + |newSource1.scala:10: error: Cannot disambiguate overloads for exported method bar_$eq with types | (v: Int)Unit | (v: Int)Unit | def bar_=(v: Int): Unit = () @@ -1587,7 +1568,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticFieldsWithSameName: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1599,7 +1579,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Duplicate static export with name 'a': a field may not share its exported name with another field or method + |newSource1.scala:7: error: Duplicate static export with name 'a': a field may not share its exported name with another field or method | val a: Int = 1 | ^ """ @@ -1608,7 +1588,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticFieldsAndMethodsWithSameName: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1620,13 +1599,12 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:10: error: Duplicate static export with name 'a': a field may not share its exported name with another field or method + |newSource1.scala:9: error: Duplicate static export with name 'a': a field may not share its exported name with another field or method | @JSExportStatic("a") | ^ """ """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1638,7 +1616,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Duplicate static export with name 'a': a field may not share its exported name with another field or method + |newSource1.scala:6: error: Duplicate static export with name 'a': a field may not share its exported name with another field or method | @JSExportStatic | ^ """ @@ -1647,7 +1625,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticFieldsAndPropertiesWithSameName: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1659,13 +1636,12 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:10: error: Duplicate static export with name 'a': a field may not share its exported name with another field or method + |newSource1.scala:9: error: Duplicate static export with name 'a': a field may not share its exported name with another field or method | @JSExportStatic("a") | ^ """ """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1677,7 +1653,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Duplicate static export with name 'a': a field may not share its exported name with another field or method + |newSource1.scala:6: error: Duplicate static export with name 'a': a field may not share its exported name with another field or method | @JSExportStatic | ^ """ @@ -1686,7 +1662,6 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticPropertiesAndMethodsWithSameName: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1698,13 +1673,12 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Exported property a conflicts with b + |newSource1.scala:7: error: Exported property a conflicts with b | def a: Int = 1 | ^ """ """ - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1716,7 +1690,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Exported method a conflicts with b + |newSource1.scala:7: error: Exported method a conflicts with b | def a(x: Int): Int = x + 1 | ^ """ @@ -1726,7 +1700,6 @@ class JSExportTest extends DirectTest with TestHelpers { def noExportStaticNonStatic: Unit = { """ class A { - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1736,7 +1709,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Only a static object whose companion class is a Scala.js-defined JS class may export its members as static. + |newSource1.scala:7: error: Only a static object whose companion class is a Scala.js-defined JS class may export its members as static. | @JSExportStatic | ^ """ @@ -1745,23 +1718,20 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noExportStaticInJSModule: Unit = { """ - @ScalaJSDefined class StaticContainer extends js.Object - @ScalaJSDefined object StaticContainer extends js.Object { @JSExportStatic def a(): Unit = () } """ hasErrors """ - |newSource1.scala:8: error: You may not export a method of a subclass of js.Any + |newSource1.scala:6: error: You may not export a method of a subclass of js.Any | @JSExportStatic | ^ """ """ - @ScalaJSDefined class StaticContainer extends js.Object @js.native @@ -1772,7 +1742,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:9: error: You may not export a method of a subclass of js.Any + |newSource1.scala:8: error: You may not export a method of a subclass of js.Any | @JSExportStatic | ^ """ @@ -1795,7 +1765,6 @@ class JSExportTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined trait StaticContainer extends js.Object object StaticContainer { @@ -1804,7 +1773,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Only a static object whose companion class is a Scala.js-defined JS class may export its members as static. + |newSource1.scala:6: error: Only a static object whose companion class is a Scala.js-defined JS class may export its members as static. | @JSExportStatic | ^ """ @@ -1836,7 +1805,6 @@ class JSExportTest extends DirectTest with TestHelpers { ) } s""" - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { @@ -1859,10 +1827,10 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:10: error: @JSExportStatic vals and vars must be defined before any other val/var, and before any constructor statement. + |newSource1.scala:9: error: @JSExportStatic vals and vars must be defined before any other val/var, and before any constructor statement. | val b: Int = 1 | ^ - |newSource1.scala:13: error: @JSExportStatic vals and vars must be defined before any other val/var, and before any constructor statement. + |newSource1.scala:12: error: @JSExportStatic vals and vars must be defined before any other val/var, and before any constructor statement. | var c: Int = 1 | ^ """ @@ -1885,7 +1853,6 @@ class JSExportTest extends DirectTest with TestHelpers { ) } s""" - @ScalaJSDefined class StaticContainer extends js.Object object StaticContainer { diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index 929ace7062..8a811e9894 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -24,38 +24,6 @@ class JSInteropTest extends DirectTest with TestHelpers { "JSGlobalScope" -> "@JSGlobalScope" ) - @Test - def warnNoJSNativeAnnotation: Unit = { - - """ - class A extends js.Object - """ containsWarns - """ - |newSource1.scala:5: warning: Classes, traits and objects inheriting from js.Any should be annotated with @js.native, unless they have @ScalaJSDefined. The default will switch to Scala.js-defined in the next major version of Scala.js. - | class A extends js.Object - | ^ - """ - - """ - object A extends js.Object - """ containsWarns - """ - |newSource1.scala:5: warning: Classes, traits and objects inheriting from js.Any should be annotated with @js.native, unless they have @ScalaJSDefined. The default will switch to Scala.js-defined in the next major version of Scala.js. - | object A extends js.Object - | ^ - """ - - """ - trait A extends js.Object - """ hasWarns - """ - |newSource1.scala:5: warning: Classes, traits and objects inheriting from js.Any should be annotated with @js.native, unless they have @ScalaJSDefined. The default will switch to Scala.js-defined in the next major version of Scala.js. - | trait A extends js.Object - | ^ - """ - - } - @Test def warnJSPackageObjectDeprecated: Unit = { @@ -82,6 +50,9 @@ class JSInteropTest extends DirectTest with TestHelpers { $obj A extends js.Object """ hasErrors s""" + |newSource1.scala:5: warning: @ScalaJSDefined is deprecated: add `-P:scalajs:sjsDefinedByDefault` to your scalac options and simply remove `@ScalaJSDefined` + | @ScalaJSDefined + | ^ |newSource1.scala:7: error: @ScalaJSDefined and @js.native cannot be used together | $obj A extends js.Object | ${" " * obj.length} ^ @@ -97,7 +68,6 @@ class JSInteropTest extends DirectTest with TestHelpers { obj <- Seq("class", "trait", "object") } yield { s""" - @ScalaJSDefined @JSName("foo") $obj A extends js.Object @@ -105,15 +75,14 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym = js.Symbol() } - @ScalaJSDefined @JSName(Sym.sym) $obj B extends js.Object """ hasWarns s""" - |newSource1.scala:6: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. + |newSource1.scala:5: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. | @JSName("foo") | ^ - |newSource1.scala:14: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. + |newSource1.scala:12: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. | @JSName(Sym.sym) | ^ """ @@ -149,33 +118,29 @@ class JSInteropTest extends DirectTest with TestHelpers { def okJSNameOnNestedObjects: Unit = { """ - @ScalaJSDefined class A extends js.Object { @JSName("foo") object toto @JSName("bar") - @ScalaJSDefined object tata extends js.Object } """.hasNoWarns """ - @ScalaJSDefined class A extends js.Object { @JSName("foo") private object toto @JSName("bar") - @ScalaJSDefined private object tata extends js.Object } """ hasWarns """ - |newSource1.scala:7: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. + |newSource1.scala:6: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. | @JSName("foo") | ^ - |newSource1.scala:10: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. + |newSource1.scala:9: warning: Non JS-native classes, traits and objects should not have an @JSName annotation, as it does not have any effect. This will be enforced in 1.0. | @JSName("bar") | ^ """ @@ -189,19 +154,17 @@ class JSInteropTest extends DirectTest with TestHelpers { obj <- Seq("class", "trait", "object") } yield { s""" - @ScalaJSDefined @JSGlobal $obj A extends js.Object - @ScalaJSDefined @JSGlobal("Foo") $obj B extends js.Object """ hasErrors s""" - |newSource1.scala:6: error: Non JS-native classes, traits and objects may not have an @JSGlobal annotation. + |newSource1.scala:5: error: Non JS-native classes, traits and objects may not have an @JSGlobal annotation. | @JSGlobal | ^ - |newSource1.scala:10: error: Non JS-native classes, traits and objects may not have an @JSGlobal annotation. + |newSource1.scala:8: error: Non JS-native classes, traits and objects may not have an @JSGlobal annotation. | @JSGlobal("Foo") | ^ """ @@ -236,12 +199,11 @@ class JSInteropTest extends DirectTest with TestHelpers { obj <- Seq("class", "trait", "object") } yield { s""" - @ScalaJSDefined @JSImport("foo", JSImport.Namespace) $obj A extends js.Object """ hasErrors s""" - |newSource1.scala:6: error: Non JS-native classes, traits and objects may not have an @JSImport annotation. + |newSource1.scala:5: error: Non JS-native classes, traits and objects may not have an @JSImport annotation. | @JSImport("foo", JSImport.Namespace) | ^ """ @@ -265,12 +227,11 @@ class JSInteropTest extends DirectTest with TestHelpers { obj <- Seq("class", "trait", "object") } yield { s""" - @ScalaJSDefined @JSImport("foo", JSImport.Namespace, globalFallback = "Foo") $obj A extends js.Object """ hasErrors s""" - |newSource1.scala:6: error: Non JS-native classes, traits and objects may not have an @JSImport annotation. + |newSource1.scala:5: error: Non JS-native classes, traits and objects may not have an @JSImport annotation. | @JSImport("foo", JSImport.Namespace, globalFallback = "Foo") | ^ """ @@ -502,8 +463,8 @@ class JSInteropTest extends DirectTest with TestHelpers { if (outer == "trait") "" else "@JSGlobal" val innerLine = - if (innerSJSDefined) s"@ScalaJSDefined $inner A extends js.Object" - else s"$inner A" + if (innerSJSDefined) s"$inner A extends js.Object" + else s"@js.native $inner A" s""" @js.native $jsGlobalAnnot $outer A extends js.Object { @@ -577,13 +538,13 @@ class JSInteropTest extends DirectTest with TestHelpers { @js.native @JSGlobal object A extends js.Object { - @ScalaJSDefined $inner A extends js.Object + $inner A extends js.Object } """ hasErrors s""" |newSource1.scala:8: error: Native JS objects cannot contain inner Scala.js-defined JS classes or objects - | @ScalaJSDefined $inner A extends js.Object - | ${" " * inner.length} ^ + | $inner A extends js.Object + | ${" " * inner.length} ^ """ } @@ -760,21 +721,19 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined case class A(x: Int) extends js.Object """ hasErrors """ - |newSource1.scala:6: error: Classes and objects extending js.Any may not have a case modifier + |newSource1.scala:5: error: Classes and objects extending js.Any may not have a case modifier | case class A(x: Int) extends js.Object | ^ """ """ - @ScalaJSDefined case object B extends js.Object """ hasErrors """ - |newSource1.scala:6: error: Classes and objects extending js.Any may not have a case modifier + |newSource1.scala:5: error: Classes and objects extending js.Any may not have a case modifier | case object B extends js.Object | ^ """ @@ -793,7 +752,7 @@ class JSInteropTest extends DirectTest with TestHelpers { outerSJSDefined <- Seq(false, true) } yield { val outerLine = - if (outerSJSDefined) s"@ScalaJSDefined $outer A extends js.Object" + if (outerSJSDefined) s"$outer A extends js.Object" else s"$outer A" val jsGlobalAnnot = @@ -841,31 +800,28 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined class A extends js.Object with js.GlobalScope """ hasErrors """ - |newSource1.scala:6: error: A Scala.js-defined JS class cannot directly extend a native JS trait. + |newSource1.scala:5: error: A Scala.js-defined JS class cannot directly extend a native JS trait. | class A extends js.Object with js.GlobalScope | ^ """ """ - @ScalaJSDefined trait A extends js.Object with js.GlobalScope """ hasErrors """ - |newSource1.scala:6: error: A Scala.js-defined JS trait cannot directly extend a native JS trait. + |newSource1.scala:5: error: A Scala.js-defined JS trait cannot directly extend a native JS trait. | trait A extends js.Object with js.GlobalScope | ^ """ """ - @ScalaJSDefined object A extends js.Object with js.GlobalScope """ hasErrors """ - |newSource1.scala:6: error: A Scala.js-defined JS object cannot directly extend a native JS trait. + |newSource1.scala:5: error: A Scala.js-defined JS object cannot directly extend a native JS trait. | object A extends js.Object with js.GlobalScope | ^ """ @@ -1365,7 +1321,6 @@ class JSInteropTest extends DirectTest with TestHelpers { inner <- Seq("class", "object") } { s""" - @ScalaJSDefined object A extends js.Object { @js.native @JSGlobal @@ -1373,7 +1328,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } """ hasErrors s""" - |newSource1.scala:9: error: Scala.js-defined JS objects may not have inner native JS classes or objects + |newSource1.scala:8: error: Scala.js-defined JS objects may not have inner native JS classes or objects | $inner B extends js.Object | ${" " * inner.length} ^ """ @@ -1461,7 +1416,6 @@ class JSInteropTest extends DirectTest with TestHelpers { def bar: Int = js.native } - @ScalaJSDefined class C extends js.Object { @JSName(js.Symbol()) def foo: Int = js.native @@ -1476,10 +1430,10 @@ class JSInteropTest extends DirectTest with TestHelpers { |newSource1.scala:16: error: A js.Symbol argument to JSName must be a static, stable identifier | @JSName(new A().a) | ^ - |newSource1.scala:22: error: A js.Symbol argument to JSName must be a static, stable identifier + |newSource1.scala:21: error: A js.Symbol argument to JSName must be a static, stable identifier | @JSName(js.Symbol()) | ^ - |newSource1.scala:24: error: A js.Symbol argument to JSName must be a static, stable identifier + |newSource1.scala:23: error: A js.Symbol argument to JSName must be a static, stable identifier | @JSName(new A().a) | ^ """ @@ -1490,7 +1444,6 @@ class JSInteropTest extends DirectTest with TestHelpers { def noSelfReferenceJSNameSymbol: Unit = { """ - @ScalaJSDefined object A extends js.Object { val a = js.Symbol("foo") @@ -1499,7 +1452,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } """ hasWarns """ - |newSource1.scala:9: warning: This symbol is defined in the same object as the annotation's target. This will cause a stackoverflow at runtime + |newSource1.scala:8: warning: This symbol is defined in the same object as the annotation's target. This will cause a stackoverflow at runtime | @JSName(a) | ^ """ @@ -2122,23 +2075,19 @@ class JSInteropTest extends DirectTest with TestHelpers { @Test def scalaJSDefinedJSNameOverrideWarnings: Unit = { """ - @ScalaJSDefined abstract class A extends js.Object { def bar(): Int } - @ScalaJSDefined class B extends A { override def bar() = 1 } """.hasNoWarns """ - @ScalaJSDefined trait A extends js.Object { @JSName("foo") def bar(): Int } - @ScalaJSDefined class B extends A { @JSName("foo") override def bar() = 1 @@ -2146,12 +2095,10 @@ class JSInteropTest extends DirectTest with TestHelpers { """.hasNoWarns """ - @ScalaJSDefined abstract class A extends js.Object { @JSName("foo") def bar(): Int } - @ScalaJSDefined class B extends A { @JSName("foo") override def bar() = 1 @@ -2159,19 +2106,17 @@ class JSInteropTest extends DirectTest with TestHelpers { """.hasNoWarns """ - @ScalaJSDefined abstract class A extends js.Object { @JSName("foo") def bar(): Int } - @ScalaJSDefined class B extends A { @JSName("baz") override def bar() = 1 } """ hasWarns """ - |newSource1.scala:13: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:11: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): Int in class B with JSName 'baz' | is conflicting with @@ -2182,18 +2127,16 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined abstract class A extends js.Object { @JSName("foo") def bar(): Int } - @ScalaJSDefined class B extends A { override def bar() = 1 } """ hasWarns """ - |newSource1.scala:12: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): Int in class B with JSName 'bar' | is conflicting with @@ -2204,22 +2147,19 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined abstract class A extends js.Object { @JSName("foo") def bar(): Object } - @ScalaJSDefined abstract class B extends A { override def bar(): String } - @ScalaJSDefined class C extends B { override def bar() = "1" } """ hasWarns """ - |newSource1.scala:12: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): String in class B with JSName 'bar' | is conflicting with @@ -2227,7 +2167,7 @@ class JSInteropTest extends DirectTest with TestHelpers { | | override def bar(): String | ^ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:13: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): String in class C with JSName 'bar' | is conflicting with @@ -2238,22 +2178,19 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined abstract class A extends js.Object { def bar(): Object } - @ScalaJSDefined abstract class B extends A { @JSName("foo") override def bar(): String } - @ScalaJSDefined class C extends B { override def bar() = "1" } """ hasWarns """ - |newSource1.scala:12: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): String in class B with JSName 'foo' | is conflicting with @@ -2261,7 +2198,7 @@ class JSInteropTest extends DirectTest with TestHelpers { | | override def bar(): String | ^ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:13: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): String in class C with JSName 'bar' | is conflicting with @@ -2272,20 +2209,17 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined class A extends js.Object { def foo: Int = 5 } - @ScalaJSDefined trait B extends A { @JSName("bar") def foo: Int } - @ScalaJSDefined class C extends B """ hasWarns """ - |newSource1.scala:12: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. | |def foo: Int in class A with JSName 'foo' | is conflicting with @@ -2296,20 +2230,17 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined class A extends js.Object { @JSName("bar") def foo: Int = 5 } - @ScalaJSDefined trait B extends A { def foo: Int } - @ScalaJSDefined class C extends B """ hasWarns """ - |newSource1.scala:12: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. | |def foo: Int in class A with JSName 'bar' | is conflicting with @@ -2320,18 +2251,16 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined class A[T] extends js.Object { @JSName("bar") def foo(x: T): T = x } - @ScalaJSDefined class B extends A[Int] { override def foo(x: Int): Int = x } """ hasWarns """ - |newSource1.scala:12: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. | |override def foo(x: Int): Int in class B with JSName 'foo' | is conflicting with @@ -2342,18 +2271,16 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined trait A[T] extends js.Object { @JSName("bar") def foo(x: T): T } - @ScalaJSDefined class B extends A[Int] { override def foo(x: Int): Int = x } """ hasWarns """ - |newSource1.scala:12: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. | |override def foo(x: Int): Int in class B with JSName 'foo' | is conflicting with @@ -2364,22 +2291,19 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined class A[T] extends js.Object { @JSName("bar") def foo(x: T): T = x } - @ScalaJSDefined trait B extends A[Int] { def foo(x: Int): Int } - @ScalaJSDefined class C extends B { override def foo(x: Int): Int = x } """ hasWarns """ - |newSource1.scala:12: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. | |def foo(x: Int): Int in class A with JSName 'bar' | is conflicting with @@ -2387,7 +2311,7 @@ class JSInteropTest extends DirectTest with TestHelpers { | | def foo(x: Int): Int | ^ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:13: warning: A member of a JS class is overriding another member with a different JS name. | |override def foo(x: Int): Int in class C with JSName 'foo' | is conflicting with @@ -2398,22 +2322,19 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined class A[T] extends js.Object { def foo(x: T): T = x } - @ScalaJSDefined trait B extends A[Int] { @JSName("bar") def foo(x: Int): Int } - @ScalaJSDefined class C extends B { override def foo(x: Int): Int = x } """ hasWarns """ - |newSource1.scala:12: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:10: warning: A member of a JS class is overriding another member with a different JS name. | |def foo(x: Int): Int in class A with JSName 'foo' | is conflicting with @@ -2421,7 +2342,7 @@ class JSInteropTest extends DirectTest with TestHelpers { | | def foo(x: Int): Int | ^ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:13: warning: A member of a JS class is overriding another member with a different JS name. | |override def foo(x: Int): Int in class C with JSName 'foo' | is conflicting with @@ -2432,20 +2353,17 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined trait A extends js.Object { def foo: Int } - @ScalaJSDefined trait B extends js.Object { @JSName("bar") def foo: Int } - @ScalaJSDefined trait C extends A with B """ hasWarns """ - |newSource1.scala:15: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:12: warning: A member of a JS class is overriding another member with a different JS name. | |def foo: Int in trait B with JSName 'bar' | is conflicting with @@ -2456,20 +2374,17 @@ class JSInteropTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined trait A extends js.Object { def foo: Int } - @ScalaJSDefined trait B extends js.Object { @JSName("bar") def foo: Int } - @ScalaJSDefined abstract class C extends A with B """ hasWarns """ - |newSource1.scala:15: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:12: warning: A member of a JS class is overriding another member with a different JS name. | |def foo: Int in trait B with JSName 'bar' | is conflicting with @@ -2487,12 +2402,10 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined trait A extends js.Object { @JSName(Syms.sym1) def bar(): Int } - @ScalaJSDefined class B extends A { @JSName(Syms.sym1) override def bar() = 1 @@ -2504,12 +2417,10 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined abstract class A extends js.Object { @JSName(Syms.sym1) def bar(): Int } - @ScalaJSDefined class B extends A { @JSName(Syms.sym1) override def bar() = 1 @@ -2522,19 +2433,17 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym2 = js.Symbol() } - @ScalaJSDefined abstract class A extends js.Object { @JSName(Syms.sym1) def bar(): Int } - @ScalaJSDefined class B extends A { @JSName(Syms.sym2) override def bar() = 1 } """ hasWarns """ - |newSource1.scala:18: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): Int in class B with JSName 'Syms.sym2' | is conflicting with @@ -2549,19 +2458,17 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined abstract class A extends js.Object { @JSName(Syms.sym1) def bar(): Int } - @ScalaJSDefined class B extends A { @JSName("baz") override def bar() = 1 } """ hasWarns """ - |newSource1.scala:17: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:15: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): Int in class B with JSName 'baz' | is conflicting with @@ -2576,19 +2483,17 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined abstract class A extends js.Object { @JSName("foo") def bar(): Int } - @ScalaJSDefined class B extends A { @JSName(Syms.sym1) override def bar() = 1 } """ hasWarns """ - |newSource1.scala:17: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:15: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): Int in class B with JSName 'Syms.sym1' | is conflicting with @@ -2603,18 +2508,16 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined abstract class A extends js.Object { @JSName(Syms.sym1) def bar(): Int } - @ScalaJSDefined class B extends A { override def bar() = 1 } """ hasWarns """ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): Int in class B with JSName 'bar' | is conflicting with @@ -2629,22 +2532,19 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined abstract class A extends js.Object { @JSName(Syms.sym1) def bar(): Object } - @ScalaJSDefined abstract class B extends A { override def bar(): String } - @ScalaJSDefined class C extends B { override def bar() = "1" } """ hasWarns """ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): String in class B with JSName 'bar' | is conflicting with @@ -2652,7 +2552,7 @@ class JSInteropTest extends DirectTest with TestHelpers { | | override def bar(): String | ^ - |newSource1.scala:20: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:17: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): String in class C with JSName 'bar' | is conflicting with @@ -2667,22 +2567,19 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined abstract class A extends js.Object { def bar(): Object } - @ScalaJSDefined abstract class B extends A { @JSName(Syms.sym1) override def bar(): String } - @ScalaJSDefined class C extends B { override def bar() = "1" } """ hasWarns """ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): String in class B with JSName 'Syms.sym1' | is conflicting with @@ -2690,7 +2587,7 @@ class JSInteropTest extends DirectTest with TestHelpers { | | override def bar(): String | ^ - |newSource1.scala:20: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:17: warning: A member of a JS class is overriding another member with a different JS name. | |override def bar(): String in class C with JSName 'bar' | is conflicting with @@ -2705,20 +2602,17 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined class A extends js.Object { def foo: Int = 5 } - @ScalaJSDefined trait B extends A { @JSName(Syms.sym1) def foo: Int } - @ScalaJSDefined class C extends B """ hasWarns """ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. | |def foo: Int in class A with JSName 'foo' | is conflicting with @@ -2733,20 +2627,17 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined class A extends js.Object { @JSName(Syms.sym1) def foo: Int = 5 } - @ScalaJSDefined trait B extends A { def foo: Int } - @ScalaJSDefined class C extends B """ hasWarns """ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. | |def foo: Int in class A with JSName 'Syms.sym1' | is conflicting with @@ -2761,18 +2652,16 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined class A[T] extends js.Object { @JSName(Syms.sym1) def foo(x: T): T = x } - @ScalaJSDefined class B extends A[Int] { override def foo(x: Int): Int = x } """ hasWarns """ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. | |override def foo(x: Int): Int in class B with JSName 'foo' | is conflicting with @@ -2787,18 +2676,16 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined trait A[T] extends js.Object { @JSName(Syms.sym1) def foo(x: T): T } - @ScalaJSDefined class B extends A[Int] { override def foo(x: Int): Int = x } """ hasWarns """ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. | |override def foo(x: Int): Int in class B with JSName 'foo' | is conflicting with @@ -2813,22 +2700,19 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined class A[T] extends js.Object { @JSName(Syms.sym1) def foo(x: T): T = x } - @ScalaJSDefined trait B extends A[Int] { def foo(x: Int): Int } - @ScalaJSDefined class C extends B { override def foo(x: Int): Int = x } """ hasWarns """ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. | |def foo(x: Int): Int in class A with JSName 'Syms.sym1' | is conflicting with @@ -2836,7 +2720,7 @@ class JSInteropTest extends DirectTest with TestHelpers { | | def foo(x: Int): Int | ^ - |newSource1.scala:20: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:17: warning: A member of a JS class is overriding another member with a different JS name. | |override def foo(x: Int): Int in class C with JSName 'foo' | is conflicting with @@ -2851,22 +2735,19 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined class A[T] extends js.Object { def foo(x: T): T = x } - @ScalaJSDefined trait B extends A[Int] { @JSName(Syms.sym1) def foo(x: Int): Int } - @ScalaJSDefined class C extends B { override def foo(x: Int): Int = x } """ hasWarns """ - |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:14: warning: A member of a JS class is overriding another member with a different JS name. | |def foo(x: Int): Int in class A with JSName 'foo' | is conflicting with @@ -2874,7 +2755,7 @@ class JSInteropTest extends DirectTest with TestHelpers { | | def foo(x: Int): Int | ^ - |newSource1.scala:20: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:17: warning: A member of a JS class is overriding another member with a different JS name. | |override def foo(x: Int): Int in class C with JSName 'foo' | is conflicting with @@ -2889,20 +2770,17 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined trait A extends js.Object { def foo: Int } - @ScalaJSDefined trait B extends js.Object { @JSName(Syms.sym1) def foo: Int } - @ScalaJSDefined trait C extends A with B """ hasWarns """ - |newSource1.scala:19: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. | |def foo: Int in trait B with JSName 'Syms.sym1' | is conflicting with @@ -2917,20 +2795,17 @@ class JSInteropTest extends DirectTest with TestHelpers { val sym1 = js.Symbol() } - @ScalaJSDefined trait A extends js.Object { def foo: Int } - @ScalaJSDefined trait B extends js.Object { @JSName(Syms.sym1) def foo: Int } - @ScalaJSDefined abstract class C extends A with B """ hasWarns """ - |newSource1.scala:19: warning: A member of a JS class is overriding another member with a different JS name. + |newSource1.scala:16: warning: A member of a JS class is overriding another member with a different JS name. | |def foo: Int in trait B with JSName 'Syms.sym1' | is conflicting with @@ -2944,7 +2819,6 @@ class JSInteropTest extends DirectTest with TestHelpers { @Test def noDefaultConstructorArgsIfModuleIsJSNative: Unit = { """ - @ScalaJSDefined class A(x: Int = 1) extends js.Object @js.native @@ -2952,7 +2826,7 @@ class JSInteropTest extends DirectTest with TestHelpers { object A extends js.Object """ hasErrors """ - |newSource1.scala:6: error: Implementation restriction: constructors of Scala.js-defined JS classes cannot have default parameters if their companion module is JS native. + |newSource1.scala:5: error: Implementation restriction: constructors of Scala.js-defined JS classes cannot have default parameters if their companion module is JS native. | class A(x: Int = 1) extends js.Object | ^ """ @@ -2979,13 +2853,12 @@ class JSInteropTest extends DirectTest with TestHelpers { class NativeBase extends js.Object { def add(option: js.Any = js.native): js.Any = js.native } - @ScalaJSDefined class Derived extends NativeBase { override def add(option: js.Any): js.Any = super.add(option) } """ hasErrors """ - |newSource1.scala:12: error: When overriding a native method with default arguments, the overriding method must explicitly repeat the default arguments. + |newSource1.scala:11: error: When overriding a native method with default arguments, the overriding method must explicitly repeat the default arguments. | override def add(option: js.Any): js.Any = super.add(option) | ^ """ @@ -3000,13 +2873,12 @@ class JSInteropTest extends DirectTest with TestHelpers { @JSGlobal class NativeBase extends NativeTrait - @ScalaJSDefined class Derived extends NativeBase { override def add(option: js.Any): js.Any = super.add(option) } """ hasErrors """ - |newSource1.scala:16: error: When overriding a native method with default arguments, the overriding method must explicitly repeat the default arguments. + |newSource1.scala:15: error: When overriding a native method with default arguments, the overriding method must explicitly repeat the default arguments. | override def add(option: js.Any): js.Any = super.add(option) | ^ """ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSNativeByDefaultTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSNativeByDefaultTest.scala new file mode 100644 index 0000000000..404e38d09b --- /dev/null +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSNativeByDefaultTest.scala @@ -0,0 +1,199 @@ +package org.scalajs.core.compiler.test + +import org.scalajs.core.compiler.test.util._ + +import org.junit.Test +import org.junit.Ignore + +// scalastyle:off line.size.limit + +class JSNativeByDefaultTest extends DirectTest with TestHelpers { + + /* We add the compiler's output path itself to the classpath, for tests + * involving separate compilation. + */ + override def classpath: List[String] = + super.classpath ++ List(testOutputPath) + + override def extraArgs: List[String] = + super.extraArgs.filter(_ != "-P:scalajs:sjsDefinedByDefault") + + override def preamble: String = + """ + import scala.scalajs.js + import scala.scalajs.js.annotation._ + """ + + @Test + def warnNoJSNativeAnnotation: Unit = { + + """ + class A extends js.Object + """ containsWarns + """ + |newSource1.scala:5: warning: Classes, traits and objects inheriting from js.Any should be annotated with @js.native, unless they have @ScalaJSDefined. The default will switch to Scala.js-defined in the next major version of Scala.js. + | class A extends js.Object + | ^ + """ + + """ + object A extends js.Object + """ containsWarns + """ + |newSource1.scala:5: warning: Classes, traits and objects inheriting from js.Any should be annotated with @js.native, unless they have @ScalaJSDefined. The default will switch to Scala.js-defined in the next major version of Scala.js. + | object A extends js.Object + | ^ + """ + + """ + trait A extends js.Object + """ hasWarns + """ + |newSource1.scala:5: warning: Classes, traits and objects inheriting from js.Any should be annotated with @js.native, unless they have @ScalaJSDefined. The default will switch to Scala.js-defined in the next major version of Scala.js. + | trait A extends js.Object + | ^ + """ + + } + + @Test + def treatedAsJSNative: Unit = { + + """ + @JSGlobal + class A extends js.Object { + def foo(): Int = 42 + } + """ hasWarns + """ + |newSource1.scala:6: warning: Classes, traits and objects inheriting from js.Any should be annotated with @js.native, unless they have @ScalaJSDefined. The default will switch to Scala.js-defined in the next major version of Scala.js. + | class A extends js.Object { + | ^ + |newSource1.scala:7: warning: Members of traits, classes and objects extending js.Any may only contain members that call js.native. This will be enforced in 1.0. + | def foo(): Int = 42 + | ^ + """ + + """ + @JSGlobal + object A extends js.Object { + def foo(): Int = 42 + } + """ hasWarns + """ + |newSource1.scala:6: warning: Classes, traits and objects inheriting from js.Any should be annotated with @js.native, unless they have @ScalaJSDefined. The default will switch to Scala.js-defined in the next major version of Scala.js. + | object A extends js.Object { + | ^ + |newSource1.scala:7: warning: Members of traits, classes and objects extending js.Any may only contain members that call js.native. This will be enforced in 1.0. + | def foo(): Int = 42 + | ^ + """ + + """ + trait A extends js.Object { + def foo(): Int = 42 + } + """ hasWarns + """ + |newSource1.scala:5: warning: Classes, traits and objects inheriting from js.Any should be annotated with @js.native, unless they have @ScalaJSDefined. The default will switch to Scala.js-defined in the next major version of Scala.js. + | trait A extends js.Object { + | ^ + |newSource1.scala:6: warning: Members of traits, classes and objects extending js.Any may only contain members that call js.native. This will be enforced in 1.0. + | def foo(): Int = 42 + | ^ + """ + + } + + @Test + def noExtendNativeTrait: Unit = { + """ + trait NativeTrait extends js.Object + + @ScalaJSDefined + class A extends NativeTrait + + @ScalaJSDefined + trait B extends NativeTrait + + @ScalaJSDefined + object C extends NativeTrait + + object Container { + val x = new NativeTrait {} + } + """ hasErrors + """ + |newSource1.scala:5: warning: Classes, traits and objects inheriting from js.Any should be annotated with @js.native, unless they have @ScalaJSDefined. The default will switch to Scala.js-defined in the next major version of Scala.js. + | trait NativeTrait extends js.Object + | ^ + |newSource1.scala:7: warning: @ScalaJSDefined is deprecated: add `-P:scalajs:sjsDefinedByDefault` to your scalac options and simply remove `@ScalaJSDefined` + | @ScalaJSDefined + | ^ + |newSource1.scala:8: error: A Scala.js-defined JS class cannot directly extend a native JS trait. + | class A extends NativeTrait + | ^ + |newSource1.scala:10: warning: @ScalaJSDefined is deprecated: add `-P:scalajs:sjsDefinedByDefault` to your scalac options and simply remove `@ScalaJSDefined` + | @ScalaJSDefined + | ^ + |newSource1.scala:11: error: A Scala.js-defined JS trait cannot directly extend a native JS trait. + | trait B extends NativeTrait + | ^ + |newSource1.scala:13: warning: @ScalaJSDefined is deprecated: add `-P:scalajs:sjsDefinedByDefault` to your scalac options and simply remove `@ScalaJSDefined` + | @ScalaJSDefined + | ^ + |newSource1.scala:14: error: A Scala.js-defined JS object cannot directly extend a native JS trait. + | object C extends NativeTrait + | ^ + |newSource1.scala:17: error: A Scala.js-defined JS class cannot directly extend a native JS trait. + | val x = new NativeTrait {} + | ^ + """ + } + + @Test + def noExtendNativeTraitSeparateCompilation: Unit = { + """ + trait NativeTrait extends js.Object + """.succeeds() + + """ + @ScalaJSDefined + class A extends NativeTrait + + @ScalaJSDefined + trait B extends NativeTrait + + @ScalaJSDefined + object C extends NativeTrait + + object Container { + val x = new NativeTrait {} + } + """ hasErrors + """ + |newSource1.scala:5: warning: @ScalaJSDefined is deprecated: add `-P:scalajs:sjsDefinedByDefault` to your scalac options and simply remove `@ScalaJSDefined` + | @ScalaJSDefined + | ^ + |newSource1.scala:6: error: A Scala.js-defined JS class cannot directly extend a native JS trait. + | class A extends NativeTrait + | ^ + |newSource1.scala:8: warning: @ScalaJSDefined is deprecated: add `-P:scalajs:sjsDefinedByDefault` to your scalac options and simply remove `@ScalaJSDefined` + | @ScalaJSDefined + | ^ + |newSource1.scala:9: error: A Scala.js-defined JS trait cannot directly extend a native JS trait. + | trait B extends NativeTrait + | ^ + |newSource1.scala:11: warning: @ScalaJSDefined is deprecated: add `-P:scalajs:sjsDefinedByDefault` to your scalac options and simply remove `@ScalaJSDefined` + | @ScalaJSDefined + | ^ + |newSource1.scala:12: error: A Scala.js-defined JS object cannot directly extend a native JS trait. + | object C extends NativeTrait + | ^ + |newSource1.scala:15: error: A Scala.js-defined JS class cannot directly extend a native JS trait. + | val x = new NativeTrait {} + | ^ + """ + } + +} diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala index 3de7da1cfc..12f340f3b9 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala @@ -9,6 +9,12 @@ import org.junit.Ignore class JSOptionalTest extends DirectTest with TestHelpers { + /* We add the compiler's output path itself to the classpath, for tests + * involving separate compilation. + */ + override def classpath: List[String] = + super.classpath ++ List(testOutputPath) + override def preamble: String = { """ import scala.scalajs.js @@ -19,7 +25,6 @@ class JSOptionalTest extends DirectTest with TestHelpers { @Test def optionalRequiresUndefinedRHS: Unit = { s""" - @ScalaJSDefined trait A extends js.Object { val a1: js.UndefOr[Int] = 5 val a2: Int = 5 @@ -32,22 +37,22 @@ class JSOptionalTest extends DirectTest with TestHelpers { } """ hasErrors s""" - |newSource1.scala:7: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. + |newSource1.scala:6: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. | val a1: js.UndefOr[Int] = 5 | ^ - |newSource1.scala:8: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. + |newSource1.scala:7: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. | val a2: Int = 5 | ^ - |newSource1.scala:10: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. + |newSource1.scala:9: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. | def b1: js.UndefOr[Int] = 5 | ^ - |newSource1.scala:11: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. + |newSource1.scala:10: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. | def b2: Int = 5 | ^ - |newSource1.scala:13: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. + |newSource1.scala:12: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. | var c1: js.UndefOr[Int] = 5 | ^ - |newSource1.scala:14: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. + |newSource1.scala:13: error: Members of Scala.js-defined JS traits must either be abstract, or their right-hand-side must be `js.undefined`. | var c2: Int = 5 | ^ """ @@ -55,8 +60,7 @@ class JSOptionalTest extends DirectTest with TestHelpers { @Test def noOverrideConcreteNonOptionalWithOptional: Unit = { - s""" - @ScalaJSDefined + """ abstract class A extends js.Object { val a1: js.UndefOr[Int] = 5 val a2: js.UndefOr[Int] @@ -65,7 +69,6 @@ class JSOptionalTest extends DirectTest with TestHelpers { def b2: js.UndefOr[Int] } - @ScalaJSDefined trait B extends A { override val a1: js.UndefOr[Int] = js.undefined override val a2: js.UndefOr[Int] = js.undefined @@ -74,16 +77,16 @@ class JSOptionalTest extends DirectTest with TestHelpers { override def b2: js.UndefOr[Int] = js.undefined } """ hasErrors - s""" - |newSource1.scala:16: error: Cannot override concrete val a1: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + """ + |newSource1.scala:14: error: Cannot override concrete val a1: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. | override val a1: js.UndefOr[Int] = js.undefined | ^ - |newSource1.scala:19: error: Cannot override concrete def b1: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + |newSource1.scala:17: error: Cannot override concrete def b1: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. | override def b1: js.UndefOr[Int] = js.undefined | ^ """ - s""" + """ @js.native @JSGlobal class A extends js.Object { @@ -91,22 +94,21 @@ class JSOptionalTest extends DirectTest with TestHelpers { def b: js.UndefOr[Int] = js.native } - @ScalaJSDefined trait B extends A { override val a: js.UndefOr[Int] = js.undefined override def b: js.UndefOr[Int] = js.undefined } """ hasErrors - s""" - |newSource1.scala:14: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + """ + |newSource1.scala:13: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. | override val a: js.UndefOr[Int] = js.undefined | ^ - |newSource1.scala:15: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + |newSource1.scala:14: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. | override def b: js.UndefOr[Int] = js.undefined | ^ """ - s""" + """ @js.native trait A extends js.Object { val a: js.UndefOr[Int] = js.native @@ -117,17 +119,104 @@ class JSOptionalTest extends DirectTest with TestHelpers { @JSGlobal class B extends A - @ScalaJSDefined trait C extends B { override val a: js.UndefOr[Int] = js.undefined override def b: js.UndefOr[Int] = js.undefined } """ hasErrors - s""" - |newSource1.scala:17: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + """ + |newSource1.scala:16: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. | override val a: js.UndefOr[Int] = js.undefined | ^ - |newSource1.scala:18: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + |newSource1.scala:17: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + | override def b: js.UndefOr[Int] = js.undefined + | ^ + """ + } + + @Test + def noOverrideConcreteNonOptionalWithOptionalSeparateCompilation1: Unit = { + """ + abstract class A extends js.Object { + val a1: js.UndefOr[Int] = 5 + val a2: js.UndefOr[Int] + + def b1: js.UndefOr[Int] = 5 + def b2: js.UndefOr[Int] + } + """.succeeds() + + """ + trait B extends A { + override val a1: js.UndefOr[Int] = js.undefined + override val a2: js.UndefOr[Int] = js.undefined + + override def b1: js.UndefOr[Int] = js.undefined + override def b2: js.UndefOr[Int] = js.undefined + } + """ hasErrors + """ + |newSource1.scala:6: error: Cannot override concrete val a1: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + | override val a1: js.UndefOr[Int] = js.undefined + | ^ + |newSource1.scala:9: error: Cannot override concrete def b1: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + | override def b1: js.UndefOr[Int] = js.undefined + | ^ + """ + } + + @Test + def noOverrideConcreteNonOptionalWithOptionalSeparateCompilation2: Unit = { + """ + @js.native + @JSGlobal + class A extends js.Object { + val a: js.UndefOr[Int] = js.native + def b: js.UndefOr[Int] = js.native + } + """.succeeds() + + """ + trait B extends A { + override val a: js.UndefOr[Int] = js.undefined + override def b: js.UndefOr[Int] = js.undefined + } + """ hasErrors + """ + |newSource1.scala:6: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + | override val a: js.UndefOr[Int] = js.undefined + | ^ + |newSource1.scala:7: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + | override def b: js.UndefOr[Int] = js.undefined + | ^ + """ + } + + @Test + def noOverrideConcreteNonOptionalWithOptionalSeparateCompilation3: Unit = { + """ + @js.native + trait A extends js.Object { + val a: js.UndefOr[Int] = js.native + def b: js.UndefOr[Int] = js.native + } + + @js.native + @JSGlobal + class B extends A + """.succeeds() + + """ + trait C extends B { + override val a: js.UndefOr[Int] = js.undefined + override def b: js.UndefOr[Int] = js.undefined + } + """ hasErrors + """ + |newSource1.scala:6: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. + | override val a: js.UndefOr[Int] = js.undefined + | ^ + |newSource1.scala:7: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. | override def b: js.UndefOr[Int] = js.undefined | ^ """ @@ -136,7 +225,6 @@ class JSOptionalTest extends DirectTest with TestHelpers { @Test def noOptionalDefWithParens: Unit = { s""" - @ScalaJSDefined trait A extends js.Object { def a(): js.UndefOr[Int] = js.undefined def b(x: Int): js.UndefOr[Int] = js.undefined @@ -144,16 +232,16 @@ class JSOptionalTest extends DirectTest with TestHelpers { } """ hasErrors s""" - |newSource1.scala:7: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. + |newSource1.scala:6: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. | def a(): js.UndefOr[Int] = js.undefined | ^ - |newSource1.scala:8: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. + |newSource1.scala:7: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. | def b(x: Int): js.UndefOr[Int] = js.undefined | ^ - |newSource1.scala:9: error: Raw JS setters must return Unit + |newSource1.scala:8: error: Raw JS setters must return Unit | def c_=(v: Int): js.UndefOr[Int] = js.undefined | ^ - |newSource1.scala:9: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. + |newSource1.scala:8: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. | def c_=(v: Int): js.UndefOr[Int] = js.undefined | ^ """ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSSAMTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSSAMTest.scala index d2076f1c04..6d805ecac1 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSSAMTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSSAMTest.scala @@ -24,7 +24,6 @@ class JSSAMTest extends DirectTest with TestHelpers { def foo(x: Int): Int } - @ScalaJSDefined trait Bar extends js.Object { def bar(x: Int): Int } @@ -49,7 +48,6 @@ class JSSAMTest extends DirectTest with TestHelpers { def foo(x: Int): Int } - @ScalaJSDefined trait Bar extends js.Object { def bar(x: Int): Int } @@ -60,10 +58,10 @@ class JSSAMTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:16: error: Using an anonymous function as a SAM for the JavaScript type Foo is not allowed. Use an anonymous class instead. + |newSource1.scala:15: error: Using an anonymous function as a SAM for the JavaScript type Foo is not allowed. Use an anonymous class instead. | val foo: Foo = x => x + 1 | ^ - |newSource1.scala:17: error: Using an anonymous function as a SAM for the JavaScript type Bar is not allowed. Use an anonymous class instead. + |newSource1.scala:16: error: Using an anonymous function as a SAM for the JavaScript type Bar is not allowed. Use an anonymous class instead. | val Bar: Bar = x => x + 1 | ^ """ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala index 0188aa3096..1acdadd6cc 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala @@ -214,7 +214,6 @@ class OptimizationTest extends JSASTTest { import scala.scalajs.js import scala.scalajs.js.annotation._ - @ScalaJSDefined trait Point extends js.Object { val x: Double val y: Double @@ -238,7 +237,6 @@ class OptimizationTest extends JSASTTest { import scala.scalajs.js import scala.scalajs.js.annotation._ - @ScalaJSDefined trait Point extends js.Object { var x: js.UndefOr[Double] = js.undefined var y: js.UndefOr[Double] = js.undefined diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/ReflectTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/ReflectTest.scala index 5f985f77bc..93859def11 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/ReflectTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/ReflectTest.scala @@ -16,15 +16,12 @@ class ReflectTest extends DirectTest with TestHelpers { def noEnableReflectiveInstantiationOnJSType: Unit = { """ @EnableReflectiveInstantiation - @ScalaJSDefined class A extends js.Object @EnableReflectiveInstantiation - @ScalaJSDefined trait B extends js.Object @EnableReflectiveInstantiation - @ScalaJSDefined object C extends js.Object @EnableReflectiveInstantiation @@ -45,19 +42,19 @@ class ReflectTest extends DirectTest with TestHelpers { |newSource1.scala:4: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. | @EnableReflectiveInstantiation | ^ - |newSource1.scala:8: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. + |newSource1.scala:7: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. | @EnableReflectiveInstantiation | ^ - |newSource1.scala:12: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. + |newSource1.scala:10: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. | @EnableReflectiveInstantiation | ^ - |newSource1.scala:16: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. + |newSource1.scala:13: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. | @EnableReflectiveInstantiation | ^ - |newSource1.scala:21: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. + |newSource1.scala:18: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. | @EnableReflectiveInstantiation | ^ - |newSource1.scala:25: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. + |newSource1.scala:22: error: @EnableReflectiveInstantiation cannot be used on types extending js.Any. | @EnableReflectiveInstantiation | ^ """ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/SJSDefinedByDefaultTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/SJSDefinedByDefaultTest.scala deleted file mode 100644 index 202ee3d96e..0000000000 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/SJSDefinedByDefaultTest.scala +++ /dev/null @@ -1,312 +0,0 @@ -package org.scalajs.core.compiler.test - -import org.scalajs.core.compiler.test.util._ - -import org.junit.Test -import org.junit.Ignore - -// scalastyle:off line.size.limit - -class SJSDefinedByDefaultTest extends DirectTest with TestHelpers { - - /* We add the compiler's output path itself to the classpath, for tests - * involving separate compilation. - */ - override def classpath: List[String] = - super.classpath ++ List(testOutputPath) - - override def extraArgs: List[String] = - super.extraArgs :+ "-P:scalajs:sjsDefinedByDefault" - - override def preamble: String = - """ - import scala.scalajs.js - import scala.scalajs.js.annotation._ - """ - - @Test - def noWarnNoJSNativeAnnotation: Unit = { - - """ - class A extends js.Object - """.hasNoWarns() - - """ - object A extends js.Object - """.hasNoWarns() - - """ - trait A extends js.Object - """.hasNoWarns() - - } - - @Test - def treatedAsSJSDefined: Unit = { - - """ - class A extends js.Object { - def foo(): Int = js.native - } - """ hasErrors - """ - |newSource1.scala:6: error: js.native may only be used as stub implementation in facade types - | def foo(): Int = js.native - | ^ - """ - - """ - object A extends js.Object { - def foo(): Int = js.native - } - """ hasErrors - """ - |newSource1.scala:6: error: js.native may only be used as stub implementation in facade types - | def foo(): Int = js.native - | ^ - """ - - """ - trait A extends js.Object { - def foo(): Int = js.native - } - """ hasErrors - """ - |newSource1.scala:6: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. - | def foo(): Int = js.native - | ^ - """ - - } - - @Test - def noExtendNativeTrait: Unit = { - """ - @js.native - trait NativeTrait extends js.Object - - class A extends NativeTrait - - trait B extends NativeTrait - - object C extends NativeTrait - - object Container { - val x = new NativeTrait {} - } - """ hasErrors - """ - |newSource1.scala:8: error: A Scala.js-defined JS class cannot directly extend a native JS trait. - | class A extends NativeTrait - | ^ - |newSource1.scala:10: error: A Scala.js-defined JS trait cannot directly extend a native JS trait. - | trait B extends NativeTrait - | ^ - |newSource1.scala:12: error: A Scala.js-defined JS object cannot directly extend a native JS trait. - | object C extends NativeTrait - | ^ - |newSource1.scala:15: error: A Scala.js-defined JS class cannot directly extend a native JS trait. - | val x = new NativeTrait {} - | ^ - """ - } - - @Test - def noExtendNativeTraitSeparateCompilation: Unit = { - """ - @js.native - trait NativeTrait extends js.Object - """.succeeds() - - """ - class A extends NativeTrait - - trait B extends NativeTrait - - object C extends NativeTrait - - object Container { - val x = new NativeTrait {} - } - """ hasErrors - """ - |newSource1.scala:5: error: A Scala.js-defined JS class cannot directly extend a native JS trait. - | class A extends NativeTrait - | ^ - |newSource1.scala:7: error: A Scala.js-defined JS trait cannot directly extend a native JS trait. - | trait B extends NativeTrait - | ^ - |newSource1.scala:9: error: A Scala.js-defined JS object cannot directly extend a native JS trait. - | object C extends NativeTrait - | ^ - |newSource1.scala:12: error: A Scala.js-defined JS class cannot directly extend a native JS trait. - | val x = new NativeTrait {} - | ^ - """ - } - - @Test - def noOverrideConcreteNonOptionalWithOptional: Unit = { - """ - abstract class A extends js.Object { - val a1: js.UndefOr[Int] = 5 - val a2: js.UndefOr[Int] - - def b1: js.UndefOr[Int] = 5 - def b2: js.UndefOr[Int] - } - - trait B extends A { - override val a1: js.UndefOr[Int] = js.undefined - override val a2: js.UndefOr[Int] = js.undefined - - override def b1: js.UndefOr[Int] = js.undefined - override def b2: js.UndefOr[Int] = js.undefined - } - """ hasErrors - """ - |newSource1.scala:14: error: Cannot override concrete val a1: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. - | override val a1: js.UndefOr[Int] = js.undefined - | ^ - |newSource1.scala:17: error: Cannot override concrete def b1: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. - | override def b1: js.UndefOr[Int] = js.undefined - | ^ - """ - - """ - @js.native - @JSGlobal - class A extends js.Object { - val a: js.UndefOr[Int] = js.native - def b: js.UndefOr[Int] = js.native - } - - trait B extends A { - override val a: js.UndefOr[Int] = js.undefined - override def b: js.UndefOr[Int] = js.undefined - } - """ hasErrors - """ - |newSource1.scala:13: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. - | override val a: js.UndefOr[Int] = js.undefined - | ^ - |newSource1.scala:14: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. - | override def b: js.UndefOr[Int] = js.undefined - | ^ - """ - - """ - @js.native - trait A extends js.Object { - val a: js.UndefOr[Int] = js.native - def b: js.UndefOr[Int] = js.native - } - - @js.native - @JSGlobal - class B extends A - - trait C extends B { - override val a: js.UndefOr[Int] = js.undefined - override def b: js.UndefOr[Int] = js.undefined - } - """ hasErrors - """ - |newSource1.scala:16: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. - | override val a: js.UndefOr[Int] = js.undefined - | ^ - |newSource1.scala:17: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. - | override def b: js.UndefOr[Int] = js.undefined - | ^ - """ - } - - @Test - def noOverrideConcreteNonOptionalWithOptionalSeparateCompilation1: Unit = { - """ - abstract class A extends js.Object { - val a1: js.UndefOr[Int] = 5 - val a2: js.UndefOr[Int] - - def b1: js.UndefOr[Int] = 5 - def b2: js.UndefOr[Int] - } - """.succeeds() - - """ - trait B extends A { - override val a1: js.UndefOr[Int] = js.undefined - override val a2: js.UndefOr[Int] = js.undefined - - override def b1: js.UndefOr[Int] = js.undefined - override def b2: js.UndefOr[Int] = js.undefined - } - """ hasErrors - """ - |newSource1.scala:6: error: Cannot override concrete val a1: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. - | override val a1: js.UndefOr[Int] = js.undefined - | ^ - |newSource1.scala:9: error: Cannot override concrete def b1: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. - | override def b1: js.UndefOr[Int] = js.undefined - | ^ - """ - } - - @Test - def noOverrideConcreteNonOptionalWithOptionalSeparateCompilation2: Unit = { - """ - @js.native - @JSGlobal - class A extends js.Object { - val a: js.UndefOr[Int] = js.native - def b: js.UndefOr[Int] = js.native - } - """.succeeds() - - """ - trait B extends A { - override val a: js.UndefOr[Int] = js.undefined - override def b: js.UndefOr[Int] = js.undefined - } - """ hasErrors - """ - |newSource1.scala:6: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. - | override val a: js.UndefOr[Int] = js.undefined - | ^ - |newSource1.scala:7: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. - | override def b: js.UndefOr[Int] = js.undefined - | ^ - """ - } - - @Test - def noOverrideConcreteNonOptionalWithOptionalSeparateCompilation3: Unit = { - """ - @js.native - trait A extends js.Object { - val a: js.UndefOr[Int] = js.native - def b: js.UndefOr[Int] = js.native - } - - @js.native - @JSGlobal - class B extends A - """.succeeds() - - """ - trait C extends B { - override val a: js.UndefOr[Int] = js.undefined - override def b: js.UndefOr[Int] = js.undefined - } - """ hasErrors - """ - |newSource1.scala:6: error: Cannot override concrete val a: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. - | override val a: js.UndefOr[Int] = js.undefined - | ^ - |newSource1.scala:7: error: Cannot override concrete def b: scala.scalajs.js.UndefOr[Int] from A in a Scala.js-defined JS trait. - | override def b: js.UndefOr[Int] = js.undefined - | ^ - """ - } - -} diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala index 513ea8b873..e2943ba5c3 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala @@ -40,21 +40,19 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { @Test def noExtendAnyRef: Unit = { """ - @ScalaJSDefined class A extends js.Any """ hasErrors """ - |newSource1.scala:6: error: A Scala.js-defined JS class cannot directly extend AnyRef. It must extend a JS class (native or not). + |newSource1.scala:5: error: A Scala.js-defined JS class cannot directly extend AnyRef. It must extend a JS class (native or not). | class A extends js.Any | ^ """ """ - @ScalaJSDefined object A extends js.Any """ hasErrors """ - |newSource1.scala:6: error: A Scala.js-defined JS object cannot directly extend AnyRef. It must extend a JS class (native or not). + |newSource1.scala:5: error: A Scala.js-defined JS object cannot directly extend AnyRef. It must extend a JS class (native or not). | object A extends js.Any | ^ """ @@ -66,13 +64,10 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { @js.native trait NativeTrait extends js.Object - @ScalaJSDefined class A extends NativeTrait - @ScalaJSDefined trait B extends NativeTrait - @ScalaJSDefined object C extends NativeTrait object Container { @@ -80,16 +75,16 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:9: error: A Scala.js-defined JS class cannot directly extend a native JS trait. + |newSource1.scala:8: error: A Scala.js-defined JS class cannot directly extend a native JS trait. | class A extends NativeTrait | ^ - |newSource1.scala:12: error: A Scala.js-defined JS trait cannot directly extend a native JS trait. + |newSource1.scala:10: error: A Scala.js-defined JS trait cannot directly extend a native JS trait. | trait B extends NativeTrait | ^ - |newSource1.scala:15: error: A Scala.js-defined JS object cannot directly extend a native JS trait. + |newSource1.scala:12: error: A Scala.js-defined JS object cannot directly extend a native JS trait. | object C extends NativeTrait | ^ - |newSource1.scala:18: error: A Scala.js-defined JS class cannot directly extend a native JS trait. + |newSource1.scala:15: error: A Scala.js-defined JS class cannot directly extend a native JS trait. | val x = new NativeTrait {} | ^ """ @@ -98,13 +93,12 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { @Test def noApplyMethod: Unit = { """ - @ScalaJSDefined class A extends js.Object { def apply(arg: Int): Int = arg } """ hasErrors """ - |newSource1.scala:7: error: A Scala.js-defined JavaScript class cannot declare a method named `apply` without `@JSName` + |newSource1.scala:6: error: A Scala.js-defined JavaScript class cannot declare a method named `apply` without `@JSName` | def apply(arg: Int): Int = arg | ^ """ @@ -113,14 +107,13 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { @Test def noBracketAccess: Unit = { """ - @ScalaJSDefined class A extends js.Object { @JSBracketAccess def foo(index: Int, arg: Int): Int = arg } """ hasErrors """ - |newSource1.scala:8: error: @JSBracketAccess is not allowed in Scala.js-defined JS classes + |newSource1.scala:7: error: @JSBracketAccess is not allowed in Scala.js-defined JS classes | def foo(index: Int, arg: Int): Int = arg | ^ """ @@ -129,14 +122,13 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { @Test def noBracketCall: Unit = { """ - @ScalaJSDefined class A extends js.Object { @JSBracketCall def foo(m: String, arg: Int): Int = arg } """ hasErrors """ - |newSource1.scala:8: error: @JSBracketCall is not allowed in Scala.js-defined JS classes + |newSource1.scala:7: error: @JSBracketCall is not allowed in Scala.js-defined JS classes | def foo(m: String, arg: Int): Int = arg | ^ """ @@ -145,7 +137,6 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { @Test def noCollapseOverloadsOnJSName: Unit = { """ - @ScalaJSDefined class A extends js.Object { @JSName("bar") def foo(): Int = 42 @@ -154,7 +145,7 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:10: error: Cannot disambiguate overloads for method bar with types + |newSource1.scala:9: error: Cannot disambiguate overloads for method bar with types | ()Int | ()Int | def bar(): Int = 24 @@ -162,7 +153,6 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined class A extends js.Object { def bar(): Int = 24 @@ -171,7 +161,7 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:10: error: Cannot disambiguate overloads for method bar with types + |newSource1.scala:9: error: Cannot disambiguate overloads for method bar with types | ()Int | ()Int | def foo(): Int = 42 @@ -179,19 +169,17 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { """ """ - @ScalaJSDefined class A extends js.Object { @JSName("bar") def foo(): Int = 42 } - @ScalaJSDefined class B extends A { def bar(): Int = 24 } """ hasErrors """ - |newSource1.scala:13: error: Cannot disambiguate overloads for method bar with types + |newSource1.scala:11: error: Cannot disambiguate overloads for method bar with types | ()Int | ()Int | def bar(): Int = 24 @@ -206,13 +194,12 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { def foo(): Int = js.native } - @ScalaJSDefined class B extends A { def bar(): Int = 24 } """ hasErrors """ - |newSource1.scala:14: error: Cannot disambiguate overloads for method bar with types + |newSource1.scala:13: error: Cannot disambiguate overloads for method bar with types | ()Int | ()Int | def bar(): Int = 24 @@ -229,13 +216,12 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { def bar(x: Int): Int = js.native } - @ScalaJSDefined class Bar extends Foo { def foo(): Int = 42 } """ hasErrors """ - |newSource1.scala:15: error: Cannot disambiguate overloads for method bar with types + |newSource1.scala:14: error: Cannot disambiguate overloads for method bar with types | (x: Int)Int | (x: Int)Int | class Bar extends Foo { @@ -246,40 +232,37 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { @Test def noOverloadedPrivate: Unit = { """ - @ScalaJSDefined class A extends js.Object { private def foo(i: Int): Int = i private def foo(s: String): String = s } """ hasErrors """ - |newSource1.scala:7: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. + |newSource1.scala:6: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. | private def foo(i: Int): Int = i | ^ - |newSource1.scala:8: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. + |newSource1.scala:7: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. | private def foo(s: String): String = s | ^ """ """ - @ScalaJSDefined object A extends js.Object { private def foo(i: Int): Int = i private def foo(s: String): String = s } """ hasErrors """ - |newSource1.scala:7: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. + |newSource1.scala:6: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. | private def foo(i: Int): Int = i | ^ - |newSource1.scala:8: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. + |newSource1.scala:7: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. | private def foo(s: String): String = s | ^ """ """ object Enclosing { - @ScalaJSDefined class A extends js.Object { private[Enclosing] def foo(i: Int): Int = i private def foo(s: String): String = s @@ -287,30 +270,28 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. + |newSource1.scala:7: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. | private[Enclosing] def foo(i: Int): Int = i | ^ - |newSource1.scala:9: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. + |newSource1.scala:8: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. | private def foo(s: String): String = s | ^ """ """ - @ScalaJSDefined class A extends js.Object { private def foo(i: Int): Int = i def foo(s: String): String = s } """ hasErrors """ - |newSource1.scala:7: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. + |newSource1.scala:6: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. | private def foo(i: Int): Int = i | ^ """ """ object Enclosing { - @ScalaJSDefined class A extends js.Object { private[Enclosing] def foo(i: Int): Int = i def foo(s: String): String = s @@ -318,7 +299,7 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. + |newSource1.scala:7: error: Private methods in Scala.js-defined JS classes cannot be overloaded. Use different names instead. | private[Enclosing] def foo(i: Int): Int = i | ^ """ @@ -328,34 +309,31 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { def noVirtualQualifiedPrivate: Unit = { """ object Enclosing { - @ScalaJSDefined class A extends js.Object { private[Enclosing] def foo(i: Int): Int = i private[Enclosing] val x: Int = 3 private[Enclosing] var y: Int = 5 } - @ScalaJSDefined class B extends A { override private[Enclosing] final def foo(i: Int): Int = i + 1 } } """ hasErrors """ - |newSource1.scala:8: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:7: error: Qualified private members in Scala.js-defined JS classes must be final | private[Enclosing] def foo(i: Int): Int = i | ^ - |newSource1.scala:9: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:8: error: Qualified private members in Scala.js-defined JS classes must be final | private[Enclosing] val x: Int = 3 | ^ - |newSource1.scala:10: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:9: error: Qualified private members in Scala.js-defined JS classes must be final | private[Enclosing] var y: Int = 5 | ^ """ """ object Enclosing { - @ScalaJSDefined object A extends js.Object { private[Enclosing] def foo(i: Int): Int = i private[Enclosing] val x: Int = 3 @@ -364,47 +342,44 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:7: error: Qualified private members in Scala.js-defined JS classes must be final | private[Enclosing] def foo(i: Int): Int = i | ^ - |newSource1.scala:9: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:8: error: Qualified private members in Scala.js-defined JS classes must be final | private[Enclosing] val x: Int = 3 | ^ - |newSource1.scala:10: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:9: error: Qualified private members in Scala.js-defined JS classes must be final | private[Enclosing] var y: Int = 5 | ^ """ """ object Enclosing { - @ScalaJSDefined abstract class A extends js.Object { private[Enclosing] def foo(i: Int): Int private[Enclosing] val x: Int private[Enclosing] var y: Int } - @ScalaJSDefined class B extends A { override private[Enclosing] final def foo(i: Int): Int = i + 1 } } """ hasErrors """ - |newSource1.scala:8: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:7: error: Qualified private members in Scala.js-defined JS classes must be final | private[Enclosing] def foo(i: Int): Int | ^ - |newSource1.scala:9: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:8: error: Qualified private members in Scala.js-defined JS classes must be final | private[Enclosing] val x: Int | ^ - |newSource1.scala:10: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:9: error: Qualified private members in Scala.js-defined JS classes must be final | private[Enclosing] var y: Int | ^ """ """ object Enclosing { - @ScalaJSDefined trait A extends js.Object { private[Enclosing] def foo(i: Int): Int private[Enclosing] val x: Int @@ -413,33 +388,29 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:7: error: Qualified private members in Scala.js-defined JS classes must be final | private[Enclosing] def foo(i: Int): Int | ^ - |newSource1.scala:9: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:8: error: Qualified private members in Scala.js-defined JS classes must be final | private[Enclosing] val x: Int | ^ - |newSource1.scala:10: error: Qualified private members in Scala.js-defined JS classes must be final + |newSource1.scala:9: error: Qualified private members in Scala.js-defined JS classes must be final | private[Enclosing] var y: Int | ^ """ """ object Enclosing { - @ScalaJSDefined class A private () extends js.Object - @ScalaJSDefined class B private[this] () extends js.Object - @ScalaJSDefined class C private[Enclosing] () extends js.Object } """.succeeds """ object Enclosing { - @ScalaJSDefined class A extends js.Object { final private[Enclosing] def foo(i: Int): Int = i } @@ -448,7 +419,6 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { """ object Enclosing { - @ScalaJSDefined class A extends js.Object { private def foo(i: Int): Int = i private[this] def bar(i: Int): Int = i + 1 @@ -458,7 +428,6 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { """ object Enclosing { - @ScalaJSDefined object A extends js.Object { final private[Enclosing] def foo(i: Int): Int = i } @@ -467,7 +436,6 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { """ object Enclosing { - @ScalaJSDefined object A extends js.Object { private def foo(i: Int): Int = i private[this] def bar(i: Int): Int = i + 1 @@ -477,28 +445,26 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { """ object Enclosing { - @ScalaJSDefined abstract class A extends js.Object { final private[Enclosing] def foo(i: Int): Int } } """ hasErrors """ - |newSource1.scala:8: error: abstract member may not have final modifier + |newSource1.scala:7: error: abstract member may not have final modifier | final private[Enclosing] def foo(i: Int): Int | ^ """ """ object Enclosing { - @ScalaJSDefined trait A extends js.Object { final private[Enclosing] def foo(i: Int): Int } } """ hasErrors """ - |newSource1.scala:8: error: abstract member may not have final modifier + |newSource1.scala:7: error: abstract member may not have final modifier | final private[Enclosing] def foo(i: Int): Int | ^ """ @@ -507,25 +473,23 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { @Test def noUseJsNative: Unit = { """ - @ScalaJSDefined class A extends js.Object { def foo = js.native } """ hasErrors """ - |newSource1.scala:7: error: js.native may only be used as stub implementation in facade types + |newSource1.scala:6: error: js.native may only be used as stub implementation in facade types | def foo = js.native | ^ """ """ - @ScalaJSDefined object A extends js.Object { def foo = js.native } """ hasErrors """ - |newSource1.scala:7: error: js.native may only be used as stub implementation in facade types + |newSource1.scala:6: error: js.native may only be used as stub implementation in facade types | def foo = js.native | ^ """ @@ -552,7 +516,6 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { final val b = "World" } - @ScalaJSDefined class B extends js.Object { @JSName(A.a) def foo: Int = 5 @@ -561,7 +524,7 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:12: error: A string argument to JSName must be a literal string + |newSource1.scala:11: error: A string argument to JSName must be a literal string | @JSName(A.a) | ^ """ @@ -572,7 +535,6 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { final val b = "World" } - @ScalaJSDefined object B extends js.Object { @JSName(A.a) def foo: Int = 5 @@ -581,7 +543,7 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:12: error: A string argument to JSName must be a literal string + |newSource1.scala:11: error: A string argument to JSName must be a literal string | @JSName(A.a) | ^ """ @@ -592,19 +554,17 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { // def apply """ - @ScalaJSDefined class A extends js.Object { def apply: Int = 42 } """ hasErrors """ - |newSource1.scala:7: error: A member named apply represents function application in JavaScript. A parameterless member should be exported as a property. You must add @JSName("apply") + |newSource1.scala:6: error: A member named apply represents function application in JavaScript. A parameterless member should be exported as a property. You must add @JSName("apply") | def apply: Int = 42 | ^ """ """ - @ScalaJSDefined class A extends js.Object { @JSName("apply") def apply: Int = 42 @@ -614,19 +574,17 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { // val apply """ - @ScalaJSDefined class A extends js.Object { val apply: Int = 42 } """ hasErrors """ - |newSource1.scala:7: error: A member named apply represents function application in JavaScript. A parameterless member should be exported as a property. You must add @JSName("apply") + |newSource1.scala:6: error: A member named apply represents function application in JavaScript. A parameterless member should be exported as a property. You must add @JSName("apply") | val apply: Int = 42 | ^ """ """ - @ScalaJSDefined class A extends js.Object { @JSName("apply") val apply: Int = 42 @@ -636,19 +594,17 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { // var apply """ - @ScalaJSDefined class A extends js.Object { var apply: Int = 42 } """ hasErrors """ - |newSource1.scala:7: error: A member named apply represents function application in JavaScript. A parameterless member should be exported as a property. You must add @JSName("apply") + |newSource1.scala:6: error: A member named apply represents function application in JavaScript. A parameterless member should be exported as a property. You must add @JSName("apply") | var apply: Int = 42 | ^ """ """ - @ScalaJSDefined class A extends js.Object { @JSName("apply") var apply: Int = 42 @@ -659,36 +615,33 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { @Test def noExportClassWithOnlyPrivateCtors: Unit = { """ - @ScalaJSDefined @JSExport class A private () extends js.Object """ hasErrors """ - |newSource1.scala:6: error: You may not export a class that has only private constructors + |newSource1.scala:5: error: You may not export a class that has only private constructors | @JSExport | ^ """ """ - @ScalaJSDefined @JSExport class A private[this] () extends js.Object """ hasErrors """ - |newSource1.scala:6: error: You may not export a class that has only private constructors + |newSource1.scala:5: error: You may not export a class that has only private constructors | @JSExport | ^ """ """ - @ScalaJSDefined @JSExport class A private[A] () extends js.Object object A """ hasErrors """ - |newSource1.scala:6: error: You may not export a class that has only private constructors + |newSource1.scala:5: error: You may not export a class that has only private constructors | @JSExport | ^ """ @@ -697,17 +650,16 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { @Test def noConcreteMemberInTrait: Unit = { """ - @ScalaJSDefined trait A extends js.Object { def foo(x: Int): Int = x + 1 def bar[A](x: A): A = x } """ hasErrors """ - |newSource1.scala:7: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. + |newSource1.scala:6: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. | def foo(x: Int): Int = x + 1 | ^ - |newSource1.scala:8: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. + |newSource1.scala:7: error: In Scala.js-defined JS traits, defs with parentheses must be abstract. | def bar[A](x: A): A = x | ^ """ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala index fbdcdc2803..f899cd024b 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala @@ -15,7 +15,7 @@ import java.io.File abstract class DirectTest { /** these arguments are always added to the args passed to newSettings */ - def extraArgs: List[String] = Nil + def extraArgs: List[String] = List("-P:scalajs:sjsDefinedByDefault") /** create settings objects for test from arg string */ def newSettings(args: List[String]): Settings = { diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index e8ccf8165c..35984cfa8d 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -463,7 +463,6 @@ object Trees { * Given the Scala.js-defined JS class * * {{{ - * @ScalaJSDefined * class Foo extends Bar * }}} * @@ -500,7 +499,6 @@ object Trees { * Given the Scala.js-defined JS class * * {{{ - * @ScalaJSDefined * class Foo extends Bar * }}} * @@ -585,7 +583,6 @@ object Trees { * if it is a Scala.js-defined JS class. Given the class * * {{{ - * @ScalaJSDefined * class Foo(x: Int) extends js.Object * }}} * diff --git a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ScalaJSDefinedTestEx.scala b/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ScalaJSDefinedTestEx.scala index 784a8e8963..ada3db13b6 100644 --- a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ScalaJSDefinedTestEx.scala +++ b/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ScalaJSDefinedTestEx.scala @@ -22,10 +22,8 @@ import scala.scalajs.js.annotation._ class ScalaJSDefinedTestEx { @Test def constructor_property_on_the_prototype_issue_1963(): Unit = { - @ScalaJSDefined class ParentClass extends js.Object - @ScalaJSDefined class ChildClass extends ParentClass val child = new ChildClass().asInstanceOf[js.Dynamic] diff --git a/library/src/main/scala/scala/scalajs/js/Any.scala b/library/src/main/scala/scala/scalajs/js/Any.scala index 623b853814..45ea692756 100644 --- a/library/src/main/scala/scala/scalajs/js/Any.scala +++ b/library/src/main/scala/scala/scalajs/js/Any.scala @@ -33,16 +33,16 @@ import annotation.ScalaJSDefined * never emitted. As such, all members must be defined with their * right-hand-side being [[native js.native]]. For forward source * compatibility with the next major version, the class/trait/object itself - * should be annotated with [[native @js.native]]. + * should be annotated with [[native @js.native]]. This becomes mandatory with + * the compiler option `-P:scalajs:sjsDefinedByDefault`. * * In most cases, you should not directly extend this trait, but rather extend * [[Object js.Object]]. * - * To implement a JavaScript type in Scala.js (therefore non-native), its - * declaration must be annotated with - * [[annotation.ScalaJSDefined @ScalaJSDefined]]. Scala.js-defined JS types - * cannot directly extend native JS traits; and Scala.js-defined JS traits - * cannot declare concrete term members. + * To implement a JavaScript type in Scala.js (therefore non-native), you must + * add `-P:scalajs:sjsDefinedByDefault` to your scalac options. + * Scala.js-defined JS types cannot directly extend native JS traits; and + * Scala.js-defined JS traits cannot declare concrete term members. * * It is not possible to define traits or classes that inherit both from this * trait and a strict subtype of [[AnyRef]]. In fact, you should think of @@ -52,7 +52,6 @@ import annotation.ScalaJSDefined * See the [[http://www.scala-js.org/doc/js-interoperability.html JavaScript * interoperability guide]] of Scala.js for more details. */ -@ScalaJSDefined trait Any extends scala.AnyRef /** Provides implicit conversions from Scala values to JavaScript values. */ diff --git a/library/src/main/scala/scala/scalajs/js/Iterable.scala b/library/src/main/scala/scala/scalajs/js/Iterable.scala index 477e5b7f39..97a898cda0 100644 --- a/library/src/main/scala/scala/scalajs/js/Iterable.scala +++ b/library/src/main/scala/scala/scalajs/js/Iterable.scala @@ -15,7 +15,6 @@ import js.annotation._ /** ECMAScript 6 * JavaScript Iterable. */ -@ScalaJSDefined trait Iterable[+A] extends js.Object { /** JavaScript Iterator for this Iterable. */ @JSName(Symbol.iterator) diff --git a/library/src/main/scala/scala/scalajs/js/Iterator.scala b/library/src/main/scala/scala/scalajs/js/Iterator.scala index 9b4fbbb48b..086202fcdb 100644 --- a/library/src/main/scala/scala/scalajs/js/Iterator.scala +++ b/library/src/main/scala/scala/scalajs/js/Iterator.scala @@ -15,14 +15,12 @@ import js.annotation._ /** ECMAScript 6 * JavaScript Iterator. */ -@ScalaJSDefined trait Iterator[+A] extends js.Object { def next(): Iterator.Entry[A] } object Iterator { /** Return value of [[Iterator.next]]. */ - @ScalaJSDefined trait Entry[+A] extends js.Object { /** Whether the iterator has completed. */ def done: Boolean diff --git a/library/src/main/scala/scala/scalajs/js/JSConverters.scala b/library/src/main/scala/scala/scalajs/js/JSConverters.scala index 14eac7fb58..34ce5c52ba 100644 --- a/library/src/main/scala/scala/scalajs/js/JSConverters.scala +++ b/library/src/main/scala/scala/scalajs/js/JSConverters.scala @@ -52,13 +52,11 @@ object JSConverters extends JSConvertersLowPrioImplicits { @inline final def toJSIterator: Iterator[T] = new IteratorAdapter(__self) } - @ScalaJSDefined private class IterableAdapter[+T](col: GenIterable[T]) extends Iterable[T] { @JSName(Symbol.iterator) final def jsIterator(): Iterator[T] = col.iterator.toJSIterator } - @ScalaJSDefined private class IteratorAdapter[+T]( it: scala.collection.Iterator[T]) extends Iterator[T] { final def next(): Iterator.Entry[T] = { diff --git a/library/src/main/scala/scala/scalajs/js/Thenable.scala b/library/src/main/scala/scala/scalajs/js/Thenable.scala index 2131ea9b23..8736ecfd17 100644 --- a/library/src/main/scala/scala/scalajs/js/Thenable.scala +++ b/library/src/main/scala/scala/scalajs/js/Thenable.scala @@ -27,7 +27,6 @@ import scala.concurrent.Future * The signature of the `then` method is only valid provided that the * values of `B` do not have a `then` method. */ -@ScalaJSDefined trait Thenable[+A] extends js.Object { def `then`[B]( onFulfilled: js.Function1[A, B | Thenable[B]], diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSExportNamed.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSExportNamed.scala index ad229b2043..bb91787f62 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSExportNamed.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSExportNamed.scala @@ -46,7 +46,6 @@ package scala.scalajs.js.annotation * }}} * you should write: * {{{ - * @ScalaJSDefined * trait FooOptions extends js.Object { * val a: Int * val b: String diff --git a/project/Build.scala b/project/Build.scala index 69e4f0b38d..7239ce2019 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -359,7 +359,9 @@ object Build { "->https://raw.githubusercontent.com/scala-js/scala-js/v" + scalaJSVersion + "/" ) - } + }, + + scalacOptions += "-P:scalajs:sjsDefinedByDefault" ) private def parallelCollectionsDependencies( diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTestSeparateRun.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTestSeparateRun.scala index f92f514b96..431bcf3325 100644 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTestSeparateRun.scala +++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTestSeparateRun.scala @@ -15,17 +15,14 @@ import scala.scalajs.js.annotation._ */ object ScalaJSDefinedTestSeparateRun { - @ScalaJSDefined class SimpleParentClass extends js.Object { def foo(x: Int): Int = x + 1 } - @ScalaJSDefined class SimpleChildClass extends SimpleParentClass { override def foo(x: Int): Int = x + 3 } - @ScalaJSDefined trait SimpleTrait extends js.Any { def foo(x: Int): Int } diff --git a/test-suite/js/src/test/require-2.12/org/scalajs/testsuite/jsinterop/JSOptionalTest212.scala b/test-suite/js/src/test/require-2.12/org/scalajs/testsuite/jsinterop/JSOptionalTest212.scala index cd27c67489..08caa4ee40 100644 --- a/test-suite/js/src/test/require-2.12/org/scalajs/testsuite/jsinterop/JSOptionalTest212.scala +++ b/test-suite/js/src/test/require-2.12/org/scalajs/testsuite/jsinterop/JSOptionalTest212.scala @@ -138,7 +138,6 @@ class JSOptionalTest212 { } @Test def overrideClassAbstractWithOptional(): Unit = { - @ScalaJSDefined abstract class ClassWithAbstracts extends js.Object { val x: js.UndefOr[Int] def y: js.UndefOr[String] @@ -146,7 +145,6 @@ class JSOptionalTest212 { var z: js.UndefOr[Option[Int]] } - @ScalaJSDefined trait OverrideClassAbstractWithOptional extends ClassWithAbstracts { val x = js.undefined def y = js.undefined @@ -172,7 +170,6 @@ class JSOptionalTest212 { } @Test def overrideTraitAbstractWithOptional(): Unit = { - @ScalaJSDefined trait TraitWithAbstracts extends js.Object { val x: js.UndefOr[Int] def y: js.UndefOr[String] @@ -180,7 +177,6 @@ class JSOptionalTest212 { var z: js.UndefOr[Option[Int]] } - @ScalaJSDefined trait OverrideTraitAbstractWithOptional extends TraitWithAbstracts { val x = js.undefined def y = js.undefined @@ -216,7 +212,6 @@ class JSOptionalTest212 { } object JSOptionalTest212 { - @ScalaJSDefined trait TraitWithOptional extends js.Object { val x: js.UndefOr[Int] = js.undefined def y: js.UndefOr[String] = js.undefined @@ -224,10 +219,8 @@ object JSOptionalTest212 { var z: js.UndefOr[Option[Int]] = js.undefined } - @ScalaJSDefined class ClassImplementsTraitWithOptional extends TraitWithOptional - @ScalaJSDefined class UndefinedInClassIsNotOptional extends js.Object { val x: js.UndefOr[Int] = js.undefined def y: js.UndefOr[String] = js.undefined @@ -235,7 +228,6 @@ object JSOptionalTest212 { var z: js.UndefOr[Option[Int]] = js.undefined } - @ScalaJSDefined class OverrideWithUndefinedInClassIsNotOptional extends TraitWithOptional { override val x = js.undefined override def y = js.undefined // scalastyle:ignore @@ -243,7 +235,6 @@ object JSOptionalTest212 { z = js.undefined } - @ScalaJSDefined class ClassImplementsTraitWithOptionalOverrideWithConcrete extends TraitWithOptional { override val x = 42 @@ -252,7 +243,6 @@ object JSOptionalTest212 { z = Some(5) } - @ScalaJSDefined trait TraitWithOptionalFunction extends js.Object { val f: js.UndefOr[js.Function1[Int, Int]] = js.undefined } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala index 2648724b70..de41a44ed5 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala @@ -862,7 +862,6 @@ trait InteroperabilityTestPolyTypeNullaryMethodNative extends js.Object { def emptyArray[T]: js.Array[T] = js.native } -@ScalaJSDefined trait InteroperabilityTestPolyTypeNullaryMethodNonNative extends js.Object { def emptyArray[T]: js.Array[T] } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala index d97aa515cc..d0a1e395d5 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala @@ -402,7 +402,6 @@ class OptimizerTest { } @Test def must_not_break_virtualized_jsarrayconstr_in_spread(): Unit = { - @ScalaJSDefined class Foo extends js.Object { def check(a: Int, b: String, rest: Any*): Unit = { assertEquals(5, a) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala index 177a64175f..8555f145db 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala @@ -47,7 +47,6 @@ class RegressionJSTest { } @Test def should_transform_js_dynamic_x_receiver_issue_2804(): Unit = { - @ScalaJSDefined class Foo extends js.Object assertTrue(js.isUndefined(js.constructorOf[Foo].x)) @@ -88,7 +87,6 @@ object RegressionJSTest { class B extends A1 with A2 { override def f(): String = "B" - @ScalaJSDefined class C extends js.Object { def t1(): String = B.super[A1].f() def t2(): String = B.super[A2].f() diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index 5e94e0af9b..2946effb70 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -1248,7 +1248,6 @@ class ExportsTest { def checkOriginalY3() = y3 } - @ScalaJSDefined class JSClass extends js.Object def getJSObj2(): js.Object = new JSClass { @@ -1266,7 +1265,6 @@ class ExportsTest { def checkOriginalY3() = y3 } - @ScalaJSDefined abstract class JSAbstractClass extends js.Object def getJSObj3(): js.Object = new JSAbstractClass { @@ -1284,7 +1282,6 @@ class ExportsTest { def checkOriginalY3() = y3 } - @ScalaJSDefined abstract class JSTrait extends js.Object def getJSObj4(): js.Object = new JSTrait { @@ -1500,7 +1497,6 @@ class ExportsTest { object A extends AutoExportIgnoreTrait { var x = 1 } object B extends AutoExportIgnoreClass { var x = 2 } - @ScalaJSDefined object C extends SJSDefinedAutoExportIgnoreClass { var x = 3 } // Check that the objects are usable @@ -1618,14 +1614,12 @@ class ExportsTest { @Test def should_ignore_invalid_descendants2(): Unit = { trait HasBar { def bar: Int } - @ScalaJSDefined trait SJSDefinedHasBar extends js.Any { def bar: Int } // This is just to check that everything here compiles class A extends AutoExportIgnoreTrait { def foo: Int = 1 } class B extends AutoExportIgnoreClass { def foo: Int = 2 } - @ScalaJSDefined class C extends SJSDefinedAutoExportIgnoreClass { def foo: Int = 3 } val a = new A { override def foo: Int = 3 } @@ -1673,14 +1667,12 @@ object TopLevelExportedObject { @JSExport @JSExport("TheSJSDefinedExportedObject") -@ScalaJSDefined object SJSDefinedExportedObject extends js.Object { def witness: String = "witness" } @JSExportTopLevel("SJSDefinedTopLevelExportedObject") @JSExportTopLevel("TheSJSDefinedTopLevelExportedObject") -@ScalaJSDefined object SJSDefinedTopLevelExportedObject extends js.Object { val witness: String = "witness" } @@ -1710,12 +1702,10 @@ class TopLevelExportedClass(_x: Int) { @JSExport @JSExport("TheSJSDefinedExportedClass") @JSExport("qualified.testclass.SJSDefinedExportedClass") -@ScalaJSDefined class SJSDefinedExportedClass(val x: Int) extends js.Object @JSExportTopLevel("SJSDefinedTopLevelExportedClass") @JSExportTopLevel("TheSJSDefinedTopLevelExportedClass") -@ScalaJSDefined class SJSDefinedTopLevelExportedClass(val x: Int) extends js.Object @JSExport @@ -1771,22 +1761,16 @@ class AutoExportedClassClass(_x: Int) extends AutoExportTrait { @JSExportDescendentClasses @JSExportDescendentObjects -@ScalaJSDefined trait SJSDefinedAutoExportTrait extends js.Object -@ScalaJSDefined object SJSDefinedAutoExportedTraitObject extends SJSDefinedAutoExportTrait -@ScalaJSDefined class SJSDefinedAutoExportedTraitClass(val x: Int) extends SJSDefinedAutoExportTrait @JSExportDescendentClasses @JSExportDescendentObjects -@ScalaJSDefined class SJSDefinedAutoExportClass extends js.Object -@ScalaJSDefined object SJSDefinedAutoExportedClassObject extends SJSDefinedAutoExportClass -@ScalaJSDefined class SJSDefinedAutoExportedClassClass(val x: Int) extends SJSDefinedAutoExportClass @JSExportDescendentClasses(ignoreInvalidDescendants = true) @@ -1813,19 +1797,15 @@ class AutoExportIgnoreClassClass(_x: Int) extends AutoExportIgnoreTrait { @JSExportDescendentClasses(ignoreInvalidDescendants = true) @JSExportDescendentObjects(ignoreInvalidDescendants = true) -@ScalaJSDefined class SJSDefinedAutoExportIgnoreClass extends js.Object -@ScalaJSDefined object SJSDefinedAutoExportedIgnoreClassObject extends SJSDefinedAutoExportIgnoreClass -@ScalaJSDefined class SJSDefinedAutoExportedIgnoreClassClass(val x: Int) extends SJSDefinedAutoExportIgnoreClass @js.native @JSGlobal object NativeInvalidExportObject extends SJSDefinedAutoExportIgnoreClass @js.native @JSGlobal class NativeInvalidExportClass extends SJSDefinedAutoExportIgnoreClass -@ScalaJSDefined class SJSDefinedInvalidExportClass private () extends SJSDefinedAutoExportIgnoreClass class SomeValueClass(val i: Int) extends AnyVal @@ -1862,7 +1842,6 @@ object ExportHolder { object TopLevelExportedObject @JSExport("qualified.nested.SJSDefinedExportedClass") - @ScalaJSDefined class SJSDefinedExportedClass extends js.Object } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/IterableTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/IterableTest.scala index e2fc8df2f3..ec7a95027a 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/IterableTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/IterableTest.scala @@ -20,13 +20,11 @@ object IterableTest { org.scalajs.testsuite.utils.Platform.areJSSymbolsSupported) } - @ScalaJSDefined private class CounterIterable(val max: Int) extends js.Iterable[Int] { @JSName(js.Symbol.iterator) def jsIterator(): js.Iterator[Int] = new CounterIterator(max) } - @ScalaJSDefined private class CounterIterator(val max: Int) extends js.Iterator[Int] { private[this] var nextNum = 0 diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala index 2e3767836f..1ac2abb4ba 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala @@ -273,7 +273,6 @@ class JSExportStaticTest { } -@ScalaJSDefined class TopLevelStaticExportMethods extends js.Object { def alsoExistsAsMember(x: Int): Int = x * 2 } @@ -310,7 +309,6 @@ object TopLevelStaticExportMethods { } object JSExportStaticTest { - @ScalaJSDefined class StaticExportMethods extends js.Object { def alsoExistsAsMember(x: Int): Int = x * 2 } @@ -346,7 +344,6 @@ object JSExportStaticTest { def alsoExistsAsMember(x: Int): Int = x * 5 } - @ScalaJSDefined class StaticExportProperties extends js.Object { def alsoExistsAsMember: Int = 54 } @@ -392,7 +389,6 @@ object JSExportStaticTest { def alsoExistsAsMember: String = "also a member" } - @ScalaJSDefined class StaticExportFields extends js.Object { val alsoExistsAsMember: Int = 5 } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNameTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNameTest.scala index 0d6f9f5c33..f2e6c791e0 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNameTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNameTest.scala @@ -81,19 +81,16 @@ object JSNameTest { var internalVar: Double = js.native } - @ScalaJSDefined trait PropDefSJSDefined extends js.Any { @JSName("jsDef") def internalDef: Int } - @ScalaJSDefined trait PropValSJSDefined extends js.Any { @JSName("jsVal") val internalVal: String } - @ScalaJSDefined trait PropVarSJSDefined extends js.Any { @JSName("jsVar") var internalVar: Double diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala index f56f4af49a..e7948a68fc 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala @@ -158,7 +158,6 @@ class JSOptionalTest { } @Test def overrideClassAbstractWithOptional(): Unit = { - @ScalaJSDefined abstract class ClassWithAbstracts extends js.Object { val x: js.UndefOr[Int] def y: js.UndefOr[String] @@ -166,7 +165,6 @@ class JSOptionalTest { var z: js.UndefOr[Option[Int]] } - @ScalaJSDefined trait OverrideClassAbstractWithOptional extends ClassWithAbstracts { val x: js.UndefOr[Int] = js.undefined def y: js.UndefOr[String] = js.undefined @@ -192,7 +190,6 @@ class JSOptionalTest { } @Test def overrideTraitAbstractWithOptional(): Unit = { - @ScalaJSDefined trait TraitWithAbstracts extends js.Object { val x: js.UndefOr[Int] def y: js.UndefOr[String] @@ -200,7 +197,6 @@ class JSOptionalTest { var z: js.UndefOr[Option[Int]] } - @ScalaJSDefined trait OverrideTraitAbstractWithOptional extends TraitWithAbstracts { val x: js.UndefOr[Int] = js.undefined def y: js.UndefOr[String] = js.undefined @@ -226,7 +222,6 @@ class JSOptionalTest { } @Test def polyOptionalMethod(): Unit = { - @ScalaJSDefined trait TraitWithPolyOptionalMethod extends js.Object { def foo[A]: js.UndefOr[A] = js.undefined } @@ -249,7 +244,6 @@ class JSOptionalTest { } object JSOptionalTest { - @ScalaJSDefined trait TraitWithOptional extends js.Object { val x: js.UndefOr[Int] = js.undefined def y: js.UndefOr[String] = js.undefined @@ -257,10 +251,8 @@ object JSOptionalTest { var z: js.UndefOr[Option[Int]] = js.undefined } - @ScalaJSDefined class ClassImplementsTraitWithOptional extends TraitWithOptional - @ScalaJSDefined class UndefinedInClassIsNotOptional extends js.Object { val x: js.UndefOr[Int] = js.undefined def y: js.UndefOr[String] = js.undefined @@ -268,7 +260,6 @@ object JSOptionalTest { var z: js.UndefOr[Option[Int]] = js.undefined } - @ScalaJSDefined class OverrideWithUndefinedInClassIsNotOptional extends TraitWithOptional { override val x: js.UndefOr[Int] = js.undefined override def y: js.UndefOr[String] = js.undefined @@ -276,7 +267,6 @@ object JSOptionalTest { z = js.undefined } - @ScalaJSDefined class ClassImplementsTraitWithOptionalOverrideWithConcrete extends TraitWithOptional { override val x: js.UndefOr[Int] = 42 @@ -285,14 +275,12 @@ object JSOptionalTest { z = Some(5) } - @ScalaJSDefined trait OverrideOptionalWithOptional extends TraitWithOptional { override val x: js.UndefOr[Int] = js.undefined override val y: js.UndefOr[String] = js.undefined override def y2: js.UndefOr[String] = js.undefined } - @ScalaJSDefined trait OverrideOptionalWithOptionalImplicitType extends TraitWithOptional { /* Unlike cases where the rhs is an Int, String, etc., this compiles even * in 2.10 and 2.11, because the inferred type is `js.UndefOr[Nothing]` @@ -307,7 +295,6 @@ object JSOptionalTest { override def y2 = js.undefined // scalastyle:ignore } - @ScalaJSDefined trait TraitWithOptionalFunction extends js.Object { val f: js.UndefOr[js.Function1[Int, Int]] = js.undefined } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala index cb82dd32aa..0cb33c224b 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala @@ -261,7 +261,6 @@ object JSSymbolTest { lazy val sym1 = js.Symbol() lazy val sym2 = js.Symbol() - @ScalaJSDefined object SJSDefinedWithSyms extends js.Object { val sym3 = js.Symbol() } @@ -334,7 +333,6 @@ object JSSymbolTest { def update(s: js.Symbol, v: js.Any): Unit = js.native } - @ScalaJSDefined trait PropDefTrait extends js.Any { @JSName(sym1) def internalDef: Int @@ -347,13 +345,11 @@ object JSSymbolTest { def internalDef: Int = js.native } - @ScalaJSDefined class SJSDefinedPropDef extends js.Object with PropDefTrait { @JSName(sym1) def internalDef: Int = 456 } - @ScalaJSDefined trait PropValTrait extends js.Any { @JSName(sym1) val internalVal: String @@ -366,13 +362,11 @@ object JSSymbolTest { val internalVal: String = js.native } - @ScalaJSDefined class SJSDefinedPropVal extends js.Object with PropValTrait { @JSName(sym1) val internalVal: String = "hello" } - @ScalaJSDefined trait PropVarTrait extends js.Any { @JSName(sym1) var internalVar: Double @@ -385,19 +379,16 @@ object JSSymbolTest { var internalVar: Double = js.native } - @ScalaJSDefined class SJSDefinedPropVar extends js.Object with PropVarTrait { @JSName(sym1) var internalVar: Double = 1511.1989 } - @ScalaJSDefined trait InnerObjectTrait extends js.Any { @JSName(sym1) val innerObject: AnyRef } - @ScalaJSDefined class SJSDefinedInnerObject extends js.Object with InnerObjectTrait { @JSName(sym1) object innerObject { @@ -405,7 +396,6 @@ object JSSymbolTest { } } - @ScalaJSDefined trait MethodTrait extends js.Any { @JSName(sym1) def foo(x: Int): Int @@ -424,7 +414,6 @@ object JSSymbolTest { def bar(x: String): String = js.native } - @ScalaJSDefined class SJSDefinedMethod extends js.Object with MethodTrait { @JSName(sym1) def foo(x: Int): Int = x + 2 @@ -433,7 +422,6 @@ object JSSymbolTest { def bar(x: String): String = "Hello " + x } - @ScalaJSDefined trait OverloadedMethodTrait extends js.Any { @JSName(sym1) def foo(x: Int): Int @@ -452,7 +440,6 @@ object JSSymbolTest { def foo(x: String): String = js.native } - @ScalaJSDefined class SJSDefinedOverloadedMethod extends js.Object with OverloadedMethodTrait { @JSName(sym1) def foo(x: Int): Int = x + 3 @@ -461,7 +448,6 @@ object JSSymbolTest { def foo(x: String): String = "Hello " + x } - @ScalaJSDefined trait OverloadedRuntimeDispatchMethodTrait extends js.Any { @JSName(sym1) def foo(x: Int): Int @@ -480,7 +466,6 @@ object JSSymbolTest { def foo(x: String): String = js.native } - @ScalaJSDefined class SJSDefinedOverloadedRuntimeDispatchMethod extends js.Object with OverloadedRuntimeDispatchMethodTrait { @JSName(sym1) @@ -490,7 +475,6 @@ object JSSymbolTest { def foo(x: String): String = "Hello " + x } - @ScalaJSDefined trait TraitWithSymsInSJSDefinedObject extends js.Object { @JSName(sym3) def symInSJSDefinedObject(x: Int): Int @@ -503,14 +487,12 @@ object JSSymbolTest { def symInSJSDefinedObject(x: Int): Int = js.native } - @ScalaJSDefined class SJSDefinedWithSymsInSJSDefinedObject extends TraitWithSymsInSJSDefinedObject { @JSName(sym3) def symInSJSDefinedObject(x: Int): Int = x + 2 } - @ScalaJSDefined trait JSIterable[+A] extends js.Object { @JSName(js.Symbol.iterator) def iterator(): js.Dynamic @@ -523,7 +505,6 @@ object JSSymbolTest { def iterator(): js.Dynamic = js.native } - @ScalaJSDefined class SJSDefinedIterable extends JSIterable[Int] { @JSName(js.Symbol.iterator) def iterator(): js.Dynamic = singletonIterator(532) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala index 0a3657d086..e8d6cfbbad 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala @@ -198,16 +198,12 @@ class MiscInteropTest { object MiscInteropTest { - @ScalaJSDefined abstract class AbstractJSClass extends js.Object - @ScalaJSDefined class ConcreteJSClass extends AbstractJSClass - @ScalaJSDefined class OtherwiseUnreferencedJSClass(val x: Int) extends js.Object - @ScalaJSDefined class OtherwiseUnreferencedJSClassForTag(val x: Int) extends js.Object @js.native @@ -223,7 +219,6 @@ object MiscInteropTest { class SomeScalaClass - @ScalaJSDefined class SomeJSClass extends js.Object } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala index a29c62479a..ea7f088f30 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala @@ -85,7 +85,6 @@ class ModulesWithGlobalFallbackTest { } object ModulesWithGlobalFallbackTest { - @ScalaJSDefined private object QueryStringFallbackImpl extends js.Object { def stringify(obj: js.Dictionary[String], sep: String = "&", eq: String = "="): String = { @@ -99,7 +98,6 @@ object ModulesWithGlobalFallbackTest { } } - @ScalaJSDefined private class StringDecoderFallbackImpl(charsetName: String = "utf8") extends js.Object { import java.nio.charset._ @@ -140,7 +138,6 @@ object ModulesWithGlobalFallbackTest { writeInternal(new Uint8Array(0), endOfInput = true) } - @ScalaJSDefined object BufferStaticFallbackImpl extends js.Object { def isBuffer(x: Any): Boolean = x.isInstanceOf[Uint8Array] } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PromiseMock.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PromiseMock.scala index ceaa79bf35..b431ac112c 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PromiseMock.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PromiseMock.scala @@ -115,7 +115,6 @@ object PromiseMock { } } - @ScalaJSDefined private class MockPromise[+A]( executor: js.Function2[js.Function1[A | Thenable[A], _], js.Function1[scala.Any, _], _]) extends js.Object with js.Thenable[A] { diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala index c1b11168d1..64267a016f 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala @@ -216,7 +216,6 @@ class ScalaJSDefinedTest { } @Test def lambda_inside_a_method_issue_2220(): Unit = { - @ScalaJSDefined class LambdaInsideMethod extends js.Object { def foo(): Int = { List(1, 2, 3).map(_ * 2).sum @@ -228,7 +227,6 @@ class ScalaJSDefinedTest { @Test def nested_inside_a_Scala_class(): Unit = { class OuterScalaClass(val x: Int) { - @ScalaJSDefined class InnerJSClass(val y: Int) extends js.Object { def sum(z: Int): Int = x + y + z } @@ -241,9 +239,7 @@ class ScalaJSDefinedTest { } @Test def nested_inside_a_Scala_js_defined_JS_class(): Unit = { - @ScalaJSDefined class OuterJSClass(val x: Int) extends js.Object { - @ScalaJSDefined class InnerJSClass(val y: Int) extends js.Object { def sum(z: Int): Int = x + y + z } @@ -256,7 +252,6 @@ class ScalaJSDefinedTest { } @Test def Scala_class_nested_inside_a_Scala_js_defined_JS_class(): Unit = { - @ScalaJSDefined class OuterJSClass(val x: Int) extends js.Object { class InnerScalaClass(val y: Int) { def sum(z: Int): Int = x + y + z @@ -270,7 +265,6 @@ class ScalaJSDefinedTest { } @Test def Scala_object_nested_inside_a_Scala_js_defined_JS_class(): Unit = { - @ScalaJSDefined class Foo extends js.Object { var innerInitCount: Int = _ @@ -298,7 +292,6 @@ class ScalaJSDefinedTest { // #2772 @Test def Scala_object_nested_inside_a_Scala_js_defined_JS_class_JSName(): Unit = { - @ScalaJSDefined class Foo extends js.Object { var innerInitCount: Int = _ @@ -348,7 +341,6 @@ class ScalaJSDefinedTest { } @Test def local_class_has_own_prototype(): Unit = { - @ScalaJSDefined class Local extends js.Object { val x = 1 } @@ -448,7 +440,6 @@ class ScalaJSDefinedTest { @Test def local_object_is_lazy(): Unit = { var initCount: Int = 0 - @ScalaJSDefined object Obj extends js.Object { initCount += 1 } @@ -465,7 +456,6 @@ class ScalaJSDefinedTest { @Test def local_object_with_captures(): Unit = { val x = (() => 5)() - @ScalaJSDefined object Obj extends js.Object { val y = 10 def sum(z: Int): Int = x + y + z @@ -480,11 +470,9 @@ class ScalaJSDefinedTest { } @Test def object_in_Scala_js_defined_JS_class(): Unit = { - @ScalaJSDefined class Foo extends js.Object { var innerInitCount: Int = _ - @ScalaJSDefined object Inner extends js.Object { innerInitCount += 1 } @@ -508,7 +496,6 @@ class ScalaJSDefinedTest { } @Test def local_defs_must_not_be_exposed(): Unit = { - @ScalaJSDefined class LocalDefsMustNotBeExposed extends js.Object { def foo(): String = { def bar(): String = "hello" @@ -521,7 +508,6 @@ class ScalaJSDefinedTest { } @Test def local_objects_must_not_be_exposed(): Unit = { - @ScalaJSDefined class LocalObjectsMustNotBeExposed extends js.Object { def foo(): String = { object Bar @@ -534,7 +520,6 @@ class ScalaJSDefinedTest { } @Test def local_defs_with_captures_issue_1975(): Unit = { - @ScalaJSDefined class LocalDefsWithCaptures extends js.Object { def foo(suffix: String): String = { def bar(): String = "hello " + suffix @@ -547,7 +532,6 @@ class ScalaJSDefinedTest { } @Test def methods_with_explicit_name(): Unit = { - @ScalaJSDefined class MethodsWithExplicitName extends js.Object { @JSName("theAnswer") def bar(): Int = 42 @@ -567,7 +551,6 @@ class ScalaJSDefinedTest { } @Test def methods_with_constant_folded_name(): Unit = { - @ScalaJSDefined class MethodsWithConstantFoldedName extends js.Object { @JSName(JSNameHolder.MethodName) def bar(): Int = 42 @@ -582,7 +565,6 @@ class ScalaJSDefinedTest { } @Test def protected_methods(): Unit = { - @ScalaJSDefined class ProtectedMethods extends js.Object { protected def bar(): Int = 42 @@ -605,7 +587,6 @@ class ScalaJSDefinedTest { Platform.executingInRhino) // Named classes - @ScalaJSDefined class Foo extends js.Object { def bar: Int = 1 } @@ -627,7 +608,6 @@ class ScalaJSDefinedTest { @Test def properties_are_not_enumerable(): Unit = { // Named classes - @ScalaJSDefined class Foo extends js.Object { def myProp: Int = 1 } @@ -645,7 +625,6 @@ class ScalaJSDefinedTest { @Test def properties_are_configurable(): Unit = { // Named classes - @ScalaJSDefined class Foo extends js.Object { def myProp: Int = 1 } @@ -670,7 +649,6 @@ class ScalaJSDefinedTest { } @Test def properties_with_explicit_name(): Unit = { - @ScalaJSDefined class PropertiesWithExplicitName extends js.Object { private[this] var myY: String = "hello" @JSName("answer") @@ -711,7 +689,6 @@ class ScalaJSDefinedTest { } @Test def protected_properties(): Unit = { - @ScalaJSDefined class ProtectedProperties extends js.Object { protected val x: Int = 42 protected[testsuite] val y: Int = 43 @@ -726,7 +703,6 @@ class ScalaJSDefinedTest { } @Test def simple_overloaded_methods(): Unit = { - @ScalaJSDefined class SimpleOverloadedMethods extends js.Object { def foo(): Int = 42 def foo(x: Int): Int = x*2 @@ -743,7 +719,6 @@ class ScalaJSDefinedTest { } @Test def simple_overloaded_methods_anon_js_class_issue_3054(): Unit = { - @ScalaJSDefined trait SimpleOverloadedMethodsAnonJSClass extends js.Object { def foo(): Int def foo(x: Int): Int @@ -763,7 +738,6 @@ class ScalaJSDefinedTest { } @Test def renamed_overloaded_methods(): Unit = { - @ScalaJSDefined class RenamedOverloadedMethods extends js.Object { @JSName("foobar") def foo(): Int = 42 @@ -782,7 +756,6 @@ class ScalaJSDefinedTest { } @Test def overloaded_methods_with_varargs(): Unit = { - @ScalaJSDefined class OverloadedMethodsWithVarargs extends js.Object { def foo(x: Int): Int = x * 2 def foo(strs: String*): Int = strs.foldLeft(0)(_ + _.length) @@ -803,7 +776,6 @@ class ScalaJSDefinedTest { } @Test def overloaded_methods_with_varargs_anon_js_class_issue_3054(): Unit = { - @ScalaJSDefined trait OverloadedMethodsWithVarargsAnonJSClass extends js.Object { def foo(x: Int): Int def foo(strs: String*): Int @@ -837,13 +809,11 @@ class ScalaJSDefinedTest { } @Test def overloaded_constructors_with_captured_parameters(): Unit = { - @ScalaJSDefined class OverloadedConstructorWithOuterContextOnly(val x: Int) extends js.Object { def this(y: String) = this(y.length) } val z = (() => 5)() - @ScalaJSDefined class OverloadedConstructorWithValCapture(val x: Int) extends js.Object { def this(y: String) = this(z) } @@ -856,11 +826,9 @@ class ScalaJSDefinedTest { } @Test def overloaded_constructors_with_super_class(): Unit = { - @ScalaJSDefined class OverloadedConstructorSup(val x: Int) extends js.Object { def this(y: String) = this(y.length) } - @ScalaJSDefined class OverloadedConstructorSub(x: Int) extends OverloadedConstructorSup(3 * x) { def this(y: String) = this(2 * y.length) @@ -873,7 +841,6 @@ class ScalaJSDefinedTest { } @Test def overloaded_constructors_with_repeated_parameters(): Unit = { - @ScalaJSDefined class OverloadedConstructorWithRepeatedParameters(xs: Int*) extends js.Object { def this(y: String, ys: String*) = this(y.length +: ys.map(_.length): _*) @@ -937,7 +904,6 @@ class ScalaJSDefinedTest { } @Test def polytype_nullary_method_issue_2445(): Unit = { - @ScalaJSDefined class PolyTypeNullaryMethod extends js.Object { def emptyArray[T]: js.Array[T] = js.Array() } @@ -954,7 +920,6 @@ class ScalaJSDefinedTest { } @Test def default_parameters(): Unit = { - @ScalaJSDefined class DefaultParameters extends js.Object { def bar(x: Int, y: Int = 1): Int = x + y def dependent(x: Int)(y: Int = x + 1): Int = x + y @@ -962,7 +927,6 @@ class ScalaJSDefinedTest { def foobar(x: Int): Int = bar(x) } - @ScalaJSDefined object DefaultParametersMod extends js.Object { def bar(x: Int, y: Int = 1): Int = x + y def dependent(x: Int)(y: Int = x + 1): Int = x + y @@ -995,7 +959,6 @@ class ScalaJSDefinedTest { } @Test def override_default_parameters(): Unit = { - @ScalaJSDefined class OverrideDefaultParametersParent extends js.Object { def bar(x: Int, y: Int = 1): Int = x + y def dependent(x: Int)(y: Int = x + 1): Int = x + y @@ -1003,7 +966,6 @@ class ScalaJSDefinedTest { def foobar(x: Int): Int = bar(x) } - @ScalaJSDefined class OverrideDefaultParametersChild extends OverrideDefaultParametersParent { override def bar(x: Int, y: Int = 10): Int = super.bar(x, y) @@ -1033,7 +995,6 @@ class ScalaJSDefinedTest { } @Test def override_method_with_default_parameters_without_new_default(): Unit = { - @ScalaJSDefined class OverrideDefaultParametersWithoutDefaultParent extends js.Object { def bar(x: Int, y: Int = 1): Int = x + y def dependent(x: Int)(y: Int = x + 1): Int = x + y @@ -1041,7 +1002,6 @@ class ScalaJSDefinedTest { def foobar(x: Int): Int = bar(x) } - @ScalaJSDefined class OverrideDefaultParametersWithoutDefaultChild extends OverrideDefaultParametersWithoutDefaultParent { override def bar(x: Int, y: Int): Int = x - y @@ -1131,7 +1091,6 @@ class ScalaJSDefinedTest { } @Test def `call_super_constructor_with_:__*`(): Unit = { - @ScalaJSDefined class CallSuperCtorWithSpread(x: Int, y: Int, z: Int) extends NativeParentClassWithVarargs(x, Seq(y, z): _*) @@ -1146,7 +1105,6 @@ class ScalaJSDefinedTest { } @Test def override_native_method(): Unit = { - @ScalaJSDefined class OverrideNativeMethod extends NativeParentClass(3) { override def foo(s: String): String = s + s + x } @@ -1165,7 +1123,6 @@ class ScalaJSDefinedTest { } @Test def override_non_native_method(): Unit = { - @ScalaJSDefined class OverrideNonNativeMethod extends NonNativeParentClass(3) { override def foo(s: String): String = s + s + x } @@ -1195,7 +1152,6 @@ class ScalaJSDefinedTest { } @Test def override_native_method_and_call_super(): Unit = { - @ScalaJSDefined class OverrideNativeMethodSuperCall extends NativeParentClass(3) { override def foo(s: String): String = super.foo("bar") + s } @@ -1214,7 +1170,6 @@ class ScalaJSDefinedTest { } @Test def override_non_native_method_and_call_super(): Unit = { - @ScalaJSDefined class OverrideNonNativeMethodSuperCall extends NonNativeParentClass(3) { override def foo(s: String): String = super.foo("bar") + s } @@ -1233,7 +1188,6 @@ class ScalaJSDefinedTest { } @Test def super_method_call_in_anon_JS_class_issue_3055(): Unit = { - @ScalaJSDefined class Foo extends js.Object { def bar(msg: String): String = "super: " + msg } @@ -1246,7 +1200,6 @@ class ScalaJSDefinedTest { } @Test def override_native_val(): Unit = { - @ScalaJSDefined class OverrideNativeVal extends NativeParentClass(3) { override val x: Int = 42 } @@ -1268,7 +1221,6 @@ class ScalaJSDefinedTest { } @Test def override_non_native_val(): Unit = { - @ScalaJSDefined class OverrideNonNativeVal extends NonNativeParentClass(3) { override val x: Int = 42 } @@ -1290,7 +1242,6 @@ class ScalaJSDefinedTest { } @Test def override_native_getter(): Unit = { - @ScalaJSDefined class OverrideNativeGetter extends NativeParentClass(3) { override def bar: Int = x * 3 } @@ -1309,7 +1260,6 @@ class ScalaJSDefinedTest { } @Test def override_non_native_getter(): Unit = { - @ScalaJSDefined class OverrideNonNativeGetter extends NonNativeParentClass(3) { override def bar: Int = x * 3 } @@ -1328,7 +1278,6 @@ class ScalaJSDefinedTest { } @Test def override_native_getter_with_val(): Unit = { - @ScalaJSDefined class OverrideNativeGetterWithVal extends NativeParentClass(3) { override val bar: Int = 1 } @@ -1347,7 +1296,6 @@ class ScalaJSDefinedTest { } @Test def override_non_native_getter_with_val(): Unit = { - @ScalaJSDefined class OverrideNonNativeGetterWithVal extends NonNativeParentClass(3) { override val bar: Int = 1 } @@ -1366,11 +1314,9 @@ class ScalaJSDefinedTest { } @Test def override_getter_with_super(): Unit = { - @ScalaJSDefined class OverrideGetterSuperParent extends js.Object { def bar: Int = 43 } - @ScalaJSDefined class OverrideGetterSuperChild extends OverrideGetterSuperParent { override def bar: Int = super.bar * 3 } @@ -1386,12 +1332,10 @@ class ScalaJSDefinedTest { } @Test def override_setter_with_super(): Unit = { - @ScalaJSDefined class OverrideSetterSuperParent extends js.Object { var x: Int = 43 def bar_=(v: Int): Unit = x = v } - @ScalaJSDefined class OverrideSetterSuperChild extends OverrideSetterSuperParent { override def bar_=(v: Int): Unit = super.bar_=(v * 3) } @@ -1410,7 +1354,6 @@ class ScalaJSDefinedTest { } @Test def super_property_get_set_in_anon_JS_class_issue_3055(): Unit = { - @ScalaJSDefined class Foo extends js.Object { var x: Int = 1 var lastSetValue: Int = 0 @@ -1435,12 +1378,10 @@ class ScalaJSDefinedTest { } @Test def add_setter_in_subclass(): Unit = { - @ScalaJSDefined class AddSetterInSubclassParent extends js.Object { var x: Int = 43 def bar: Int = x } - @ScalaJSDefined class AddSetterInSubclassChild extends AddSetterInSubclassParent { def bar_=(v: Int): Unit = x = v } @@ -1457,12 +1398,10 @@ class ScalaJSDefinedTest { } @Test def add_getter_in_subclass(): Unit = { - @ScalaJSDefined class AddGetterInSubclassParent extends js.Object { var x: Int = 43 def bar_=(v: Int): Unit = x = v } - @ScalaJSDefined class AddGetterInSubclassChild extends AddGetterInSubclassParent { def bar: Int = x } @@ -1479,7 +1418,6 @@ class ScalaJSDefinedTest { } @Test def overload_native_method(): Unit = { - @ScalaJSDefined class OverloadNativeMethod extends NativeParentClass(3) { def foo(s: String, y: Int): String = foo(s) + " " + y } @@ -1497,7 +1435,6 @@ class ScalaJSDefinedTest { } @Test def overload_non_native_method(): Unit = { - @ScalaJSDefined class OverloadNonNativeMethod extends NonNativeParentClass(3) { def foo(s: String, y: Int): String = foo(s) + " " + y } @@ -1515,7 +1452,6 @@ class ScalaJSDefinedTest { } @Test def overload_with_default_parameter(): Unit = { - @ScalaJSDefined class OverloadDefaultParameter extends js.Object { def foo(x: Int): Int = x def foo(x: String = ""): String = x @@ -1528,7 +1464,6 @@ class ScalaJSDefinedTest { } @Test def implement_a_simple_trait(): Unit = { - @ScalaJSDefined class ImplementSimpleTrait extends js.Object with SimpleTrait { def foo(x: Int): Int = x + 1 } @@ -1541,7 +1476,6 @@ class ScalaJSDefinedTest { } @Test def implement_a_simple_trait_under_separate_compilation(): Unit = { - @ScalaJSDefined class ImplementSimpleTraitSepRun extends js.Object with SepRun.SimpleTrait { def foo(x: Int): Int = x + 1 } @@ -1554,12 +1488,10 @@ class ScalaJSDefinedTest { } @Test def implement_a_trait_with_a_val(): Unit = { - @ScalaJSDefined trait TraitWithVal extends js.Object { val x: Int } - @ScalaJSDefined class ImplWithVal extends TraitWithVal { val x: Int = 3 } @@ -1572,12 +1504,10 @@ class ScalaJSDefinedTest { } @Test def implement_a_trait_with_a_var(): Unit = { - @ScalaJSDefined trait TraitWithVar extends js.Object { var x: Int } - @ScalaJSDefined class ImplWithVar extends TraitWithVar { var x: Int = 3 } @@ -1595,12 +1525,10 @@ class ScalaJSDefinedTest { } @Test def implement_a_trait_extending_a_native_JS_class(): Unit = { - @ScalaJSDefined trait TraitExtendsJSClass extends NativeParentClass { def foobar(x: Int): Int } - @ScalaJSDefined class ImplExtendsJSClassAndTrait extends NativeParentClass(5) with TraitExtendsJSClass { def foobar(x: Int): Int = x * 3 @@ -1611,7 +1539,6 @@ class ScalaJSDefinedTest { } @Test def implement_abstract_members_coming_from_a_native_JS_class(): Unit = { - @ScalaJSDefined class ImplDeferredMembersFromJSParent extends NativeParentClassWithDeferred { val x: Int = 43 @@ -1638,7 +1565,6 @@ class ScalaJSDefinedTest { } @Test def override_a_method_with_default_values_from_a_native_JS_class(): Unit = { - @ScalaJSDefined class OverrideDefault extends NativeParentClass(7) { override def methodWithDefault(x: Int = 9): Int = x * 2 } @@ -1654,7 +1580,6 @@ class ScalaJSDefinedTest { // #2603 @Test def default_values_in_non_exposed_methods(): Unit = { - @ScalaJSDefined class DefaultParameterss(val default: Int) extends js.Object { /* We don't use a constant default value to make sure it actually comes * from the default parameter accessors. @@ -1687,7 +1612,6 @@ object ScalaJSDefinedTest { def methodWithDefault(x: Int = 5): Int = js.native } - @ScalaJSDefined class NonNativeParentClass(val x: Int) extends js.Object { def foo(s: String): String = s + x @@ -1717,34 +1641,28 @@ object ScalaJSDefinedTest { val args: js.Array[Int] = js.native } - @ScalaJSDefined trait SimpleTrait extends js.Any { def foo(x: Int): Int } - @ScalaJSDefined class Minimal extends js.Object private var staticNonNativeObjectInitCount: Int = _ - @ScalaJSDefined object StaticNonNativeObject extends js.Object { staticNonNativeObjectInitCount += 1 } - @ScalaJSDefined class SimpleMethod extends js.Object { def foo(x: Int): Int = x + 3 def bar(s: String, i: Int): String = s + i } - @ScalaJSDefined object StaticObjectSimpleMethod extends js.Object { def foo(x: Int): Int = x + 3 def bar(s: String, i: Int): String = s + i } - @ScalaJSDefined class SimpleField extends js.Object { val x = 5 var y = 10 @@ -1752,7 +1670,6 @@ object ScalaJSDefinedTest { def sum(): Int = x + y } - @ScalaJSDefined object StaticObjectSimpleField extends js.Object { val x = 5 var y = 10 @@ -1760,7 +1677,6 @@ object ScalaJSDefinedTest { def sum(): Int = x + y } - @ScalaJSDefined class SimpleAccessors extends js.Object { var x = 1 def readPlus1: Int = x + 1 @@ -1769,7 +1685,6 @@ object ScalaJSDefinedTest { def neg_=(v: Int): Unit = x = -v } - @ScalaJSDefined class SimpleConstructor(_x: Int, _y: Int) extends js.Object { val x = _x var y = _y @@ -1777,20 +1692,15 @@ object ScalaJSDefinedTest { def sum(): Int = x + y } - @ScalaJSDefined class ConstructorDefaultParamJSNonNativeNone(val foo: Int = -1) extends js.Object - @ScalaJSDefined class ConstructorDefaultParamJSNonNativeJSNonNative(val foo: Int = -1) extends js.Object - @ScalaJSDefined object ConstructorDefaultParamJSNonNativeJSNonNative extends js.Object - @ScalaJSDefined class ConstructorDefaultParamJSNonNativeScala(val foo: Int = -1) extends js.Object object ConstructorDefaultParamJSNonNativeScala class ConstructorDefaultParamScalaJSNonNative(val foo: Int = -1) - @ScalaJSDefined object ConstructorDefaultParamScalaJSNonNative extends js.Object @js.native @@ -1805,7 +1715,6 @@ object ScalaJSDefinedTest { @js.native @JSGlobal("ConstructorDefaultParam") class ConstructorDefaultParamJSNativeJSNonNative(val foo: Int = -1) extends js.Object - @ScalaJSDefined object ConstructorDefaultParamJSNativeJSNonNative extends js.Object @js.native @@ -1822,19 +1731,16 @@ object ScalaJSDefinedTest { // sanity check class ConstructorDefaultParamScalaNone(val foo: Int = -1) - @ScalaJSDefined class OverloadedConstructorParamNumber(val foo: Int) extends js.Object { def this(x: Int, y: Int) = this(x + y) def this(x: Int, y: Int, z: Int) = this(x + y, z) } - @ScalaJSDefined class OverloadedConstructorParamType(val foo: Int) extends js.Object { def this(x: String) = this(x.length) def this(x: Option[String]) = this(x.get) } - @ScalaJSDefined class OverloadedConstructorComplex(val foo: Int, var bar: Int) extends js.Object { def this() = this(5, 6) def this(x: Int) = this(x, x) @@ -1853,17 +1759,14 @@ object ScalaJSDefinedTest { this((a + b).length, (x + y).length) } - @ScalaJSDefined class SimpleConstructorAutoFields(val x: Int, var y: Int) extends js.Object { def sum(): Int = x + y } - @ScalaJSDefined class SimpleConstructorParamAccessors(x: Int, y: Int) extends js.Object { def sum(): Int = x + y } - @ScalaJSDefined class DefaultFieldValues extends js.Object { var int: Int = _ var bool: Boolean = _ @@ -1873,7 +1776,6 @@ object ScalaJSDefinedTest { var valueClass: SomeValueClass = _ } - @ScalaJSDefined class SimpleInheritedFromNative( x: Int, val y: Int) extends NativeParentClass(x) From 0d8245dc411e18a2a69d14e40ae2cf385f41a05e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 17 Aug 2017 21:46:53 +0200 Subject: [PATCH 0456/2665] Directly expose everything useful as public in `ScalaJSPlugin`. By "useful", we mean everything that is still public in `ScalaJSPluginInternal` in Scala.js 1.x. Exposing them directly in `ScalaJSPlugin` will allow us to not expose `ScalaJSPluginInternal` at all in Scala.js 1.x anymore. There are two exceptions: * the duo `scalaJSClearCacheStats` and `scalaJSIRCacheHolder`, because we still hope to be able to remove them (see #2171) * `scalaJSPatchIncOptions`, which we'll silently not expose in 1.x anymore (we can reintroduce it later if asked for) --- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 109 +++++++++++++++++- .../sbtplugin/ScalaJSPluginInternal.scala | 43 +++---- 2 files changed, 120 insertions(+), 32 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index a5a8d31861..ddb9fdea28 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -28,6 +28,9 @@ import org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv import org.scalajs.jsenv.phantomjs.PhantomJSEnv object ScalaJSPlugin extends AutoPlugin { + /** The global Scala.js IR cache */ + val globalIRCache: IRFileCache = new IRFileCache() + override def requires: Plugins = plugins.JvmPlugin /* The following module-case double definition is a workaround for a bug @@ -69,7 +72,7 @@ object ScalaJSPlugin extends AutoPlugin { /* We take the semantics from the linker, since they depend on the stage. * This way we are sure we agree on the semantics with the linker. */ - import ScalaJSPluginInternal.{scalaJSLinker, scalaJSRequestsDOMInternal} + import ScalaJSPluginInternal.scalaJSRequestsDOMInternal val semantics = scalaJSLinker.value.semantics val withDOM = scalaJSRequestsDOMInternal.value new RhinoJSEnv(semantics, withDOM, internal = ()) @@ -224,6 +227,47 @@ object ScalaJSPlugin extends AutoPlugin { "Do not set the value of this setting (only use it as read-only).", BSetting) + val scalaJSIRCache = TaskKey[globalIRCache.Cache]("scalaJSIRCache", + "Scala.js internal: Task to access a cache.", KeyRanks.Invisible) + + /** Persisted instance of the Scala.js linker. + * + * This setting must be scoped per project, configuration, and stage task + * (`fastOptJS` or `fullOptJS`). + * + * If a task uses the `link` method of the `ClearableLinker`, it must be + * protected from running in parallel with any other task doing the same + * thing, by tagging the task with the value of [[usesScalaJSLinkerTag]] + * in the same scope. The typical shape of such a task will be: + * {{{ + * myTask in (Compile, fastOptJS) := Def.taskDyn { + * val linker = (scalaJSLinker in (Compile, fastOptJS)).value + * val usesLinkerTag = (usesScalaJSLinkerTag in (Compile, fastOptJS)).value + * // Read the `.value` of other settings and tasks here + * + * Def.task { + * // Do the actual work of the task here, in particular calling + * linker.link(...) + * }.tag(usesLinkerTag) + * }.value, + * }}} + */ + val scalaJSLinker = SettingKey[ClearableLinker]("scalaJSLinker", + "Persisted instance of the Scala.js linker", KeyRanks.Invisible) + + /** A tag to indicate that a task is using the value of [[scalaJSLinker]] + * and its `link` method. + * + * This setting's value should always be retrieved from the same scope + * than [[scalaJSLinker]] was retrieved from. + * + * @see [[scalaJSLinker]] + */ + val usesScalaJSLinkerTag = SettingKey[Tags.Tag]("usesScalaJSLinkerTag", + "Tag to indicate that a task uses the link method of the value of " + + "scalaJSLinker", + KeyRanks.Invisible) + val fastOptJS = TaskKey[Attributed[File]]("fastOptJS", "Quickly link all compiled JavaScript into a single file", APlusTask) @@ -419,6 +463,11 @@ object ScalaJSPlugin extends AutoPlugin { "as the `jettyClassLoader` argument of the PhantomJSEnv", KeyRanks.Invisible) + /** All .sjsir files on the fullClasspath, used by scalajsp. */ + val sjsirFilesOnClasspath = TaskKey[Seq[String]]("sjsirFilesOnClasspath", + "All .sjsir files on the fullClasspath, used by scalajsp", + KeyRanks.Invisible) + /** Prints the content of a .sjsir file in human readable form. */ val scalajsp = InputKey[Unit]("scalajsp", "Prints the content of a .sjsir file in human readable form.", @@ -433,24 +482,74 @@ object ScalaJSPlugin extends AutoPlugin { "List of arguments to pass to the Scala.js Java System.properties.", CTask) + val scalaJSSourceFiles = AttributeKey[Seq[File]]("scalaJSSourceFiles", + "Files used to compute this value (can be used in FileFunctions later).", + KeyRanks.Invisible) + val scalaJSSourceMap = AttributeKey[File]("scalaJSSourceMap", "Source map file attached to an Attributed .js file.", BSetting) } import autoImport._ - import ScalaJSPluginInternal._ + + /** Maps a [[Stage]] to the corresponding [[sbt.Def.TaskKey TaskKey]]. + * + * For example, [[Stage.FastOpt]] (aka `FastOptStage`) is mapped to + * [[fastOptJS]]. + */ + val stageKeys: Map[Stage, TaskKey[Attributed[File]]] = Map( + Stage.FastOpt -> fastOptJS, + Stage.FullOpt -> fullOptJS + ) + + /** Logs the current statistics about the global IR cache. */ + def logIRCacheStats(logger: Logger): Unit = + logger.debug("Global IR cache stats: " + globalIRCache.stats.logLine) override def globalSettings: Seq[Setting[_]] = { Seq( scalaJSStage := Stage.FastOpt, scalaJSUseRhinoInternal := false, - scalaJSClearCacheStats := globalIRCache.clearStats() + ScalaJSPluginInternal.scalaJSClearCacheStats := globalIRCache.clearStats() ) } override def projectSettings: Seq[Setting[_]] = ( - scalaJSAbstractSettings ++ - scalaJSEcosystemSettings + ScalaJSPluginInternal.scalaJSAbstractSettings ++ + ScalaJSPluginInternal.scalaJSEcosystemSettings ) + + /** Basic set of settings enabling Scala.js for a configuration. + * + * The `Compile` and `Test` configurations of sbt are already equipped with + * these settings. Directly using this method is only necessary if you want + * to configure a custom configuration. + * + * Moreover, if your custom configuration is similar in spirit to `Compile` + * (resp. `Test`), you should use [[compileConfigSettings]] (resp. + * [[testConfigSettings]]) instead. + */ + def baseConfigSettings: Seq[Setting[_]] = + ScalaJSPluginInternal.scalaJSConfigSettings + + /** Complete set of settings enabling Scala.js for a `Compile`-like + * configuration. + * + * The `Compile` configuration of sbt is already equipped with these + * settings. Directly using this method is only necessary if you want to + * configure a custom `Compile`-like configuration. + */ + def compileConfigSettings: Seq[Setting[_]] = + ScalaJSPluginInternal.scalaJSCompileSettings + + /** Complete set of settings enabling Scala.js for a `Test`-like + * configuration. + * + * The `Test` configuration of sbt is already equipped with these settings. + * Directly using this method is only necessary if you want to configure a + * custom `Test`-like configuration, e.g., `IntegrationTest`. + */ + def testConfigSettings: Seq[Setting[_]] = + ScalaJSPluginInternal.scalaJSTestSettings } diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 6d02a69570..085f5a1cb4 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -44,7 +44,8 @@ object ScalaJSPluginInternal { import ScalaJSPlugin.autoImport.{ModuleKind => _, _} /** The global Scala.js IR cache */ - val globalIRCache: IRFileCache = new IRFileCache() + val globalIRCache: ScalaJSPlugin.globalIRCache.type = + ScalaJSPlugin.globalIRCache val scalaJSClearCacheStats = TaskKey[Unit]("scalaJSClearCacheStats", "Scala.js internal: Clear the global IR cache's statistics. Used to " + @@ -54,25 +55,18 @@ object ScalaJSPluginInternal { val scalaJSEnsureUnforked = SettingKey[Boolean]("ensureUnforked", "Scala.js internal: Fails if fork is true.", KeyRanks.Invisible) - /** Dummy setting to persist a Scala.js linker. */ - val scalaJSLinker = SettingKey[ClearableLinker]("scalaJSLinker", - "Scala.js internal: Setting to persist a linker", KeyRanks.Invisible) + val scalaJSLinker: SettingKey[ClearableLinker] = + ScalaJSPlugin.autoImport.scalaJSLinker - /** A tag to indicate that a task is using the value of [[scalaJSLinker]] - * - * This setting's value should always be retrieved from the same scope than - * [[scalaJSLinker]] was retrieved from. - */ - val usesScalaJSLinkerTag = SettingKey[Tags.Tag]("usesScalaJSLinkerTag", - "Scala.js internal: Tag to indicate that a task uses the link or " + - "linkUnit method of the value of scalaJSLinker", KeyRanks.Invisible) + val usesScalaJSLinkerTag: SettingKey[Tags.Tag] = + ScalaJSPlugin.autoImport.usesScalaJSLinkerTag val scalaJSIRCacheHolder = SettingKey[globalIRCache.Cache]("scalaJSIRCacheHolder", "Scala.js internal: Setting to persist a cache. Do NOT use this directly. " + "Use scalaJSIRCache instead.", KeyRanks.Invisible) - val scalaJSIRCache = TaskKey[globalIRCache.Cache]("scalaJSIRCache", - "Scala.js internal: Task to access a cache.", KeyRanks.Invisible) + val scalaJSIRCache: TaskKey[globalIRCache.Cache] = + ScalaJSPlugin.autoImport.scalaJSIRCache /** Non-deprecated alias of `scalaJSRequestsDOM` for internal use. */ private[sbtplugin] val scalaJSRequestsDOMInternal = TaskKey[Boolean]( @@ -92,9 +86,8 @@ object ScalaJSPluginInternal { val scalaJSRequestsDOM = scalaJSRequestsDOMInternal /** All .sjsir files on the fullClasspath, used by scalajsp. */ - val sjsirFilesOnClasspath = TaskKey[Seq[String]]("sjsirFilesOnClasspath", - "All .sjsir files on the fullClasspath, used by scalajsp", - KeyRanks.Invisible) + val sjsirFilesOnClasspath: TaskKey[Seq[String]] = + ScalaJSPlugin.autoImport.sjsirFilesOnClasspath /** Internal task to map discovered main classes to whether they are in the * "new" style (true, standard main method) or the "old" style (false, @@ -110,14 +103,11 @@ object ScalaJSPluginInternal { "An identifier for the module which contains the exports of Scala.js", KeyRanks.Invisible) - val scalaJSSourceFiles = AttributeKey[Seq[File]]("scalaJSSourceFiles", - "Files used to compute this value (can be used in FileFunctions later).", - KeyRanks.Invisible) + val scalaJSSourceFiles: AttributeKey[Seq[File]] = + ScalaJSPlugin.autoImport.scalaJSSourceFiles - val stageKeys: Map[Stage, TaskKey[Attributed[File]]] = Map( - Stage.FastOpt -> fastOptJS, - Stage.FullOpt -> fullOptJS - ) + val stageKeys: Map[Stage, TaskKey[Attributed[File]]] = + ScalaJSPlugin.stageKeys /** A JS expression that detects the global scope just like Scala.js */ val jsGlobalExpr: String = { @@ -125,9 +115,8 @@ object ScalaJSPluginInternal { global["Object"] === Object) ? global : this)""" } - def logIRCacheStats(logger: Logger): Unit = { - logger.debug("Global IR cache stats: " + globalIRCache.stats.logLine) - } + def logIRCacheStats(logger: Logger): Unit = + ScalaJSPlugin.logIRCacheStats(logger) /** Patches the IncOptions so that .sjsir files are pruned as needed. */ def scalaJSPatchIncOptions(incOptions: IncOptions): IncOptions = From 670144bf31b80a33a36f98a50a85c30bb4d83012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 28 Aug 2017 11:21:32 +0200 Subject: [PATCH 0457/2665] Fix #3107: Make Closeable extend AutoCloseable. Because `AutoCloseable` does not exist on JDK6, we have to move the definition of `java.lang.AutoCloseable` from the javalanglib to the javalib. It so happens that no class or trait in the javalanglib needs to extend `AutoCloseable`, so we're fine. --- .../main/scala/java/lang/AutoCloseable.scala | 5 --- .../src/main/scala/java/io/Closeable.scala | 3 +- .../main/scala/java/lang/AutoCloseable.scala | 11 +++++ .../javalib/io/AutoCloseableTest.scala | 41 +++++++++++++++++++ 4 files changed, 53 insertions(+), 7 deletions(-) delete mode 100644 javalanglib/src/main/scala/java/lang/AutoCloseable.scala create mode 100644 javalib/src/main/scala/java/lang/AutoCloseable.scala create mode 100644 test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/io/AutoCloseableTest.scala diff --git a/javalanglib/src/main/scala/java/lang/AutoCloseable.scala b/javalanglib/src/main/scala/java/lang/AutoCloseable.scala deleted file mode 100644 index 21a3d0fb97..0000000000 --- a/javalanglib/src/main/scala/java/lang/AutoCloseable.scala +++ /dev/null @@ -1,5 +0,0 @@ -package java.lang - -trait AutoCloseable { - def close(): Unit -} diff --git a/javalib/src/main/scala/java/io/Closeable.scala b/javalib/src/main/scala/java/io/Closeable.scala index e57239091d..b1aab01e9a 100644 --- a/javalib/src/main/scala/java/io/Closeable.scala +++ b/javalib/src/main/scala/java/io/Closeable.scala @@ -1,6 +1,5 @@ package java.io -/** Note that Closeable doesn't extend AutoCloseable for Java6 compat */ -trait Closeable { +trait Closeable extends AutoCloseable { def close(): Unit } diff --git a/javalib/src/main/scala/java/lang/AutoCloseable.scala b/javalib/src/main/scala/java/lang/AutoCloseable.scala new file mode 100644 index 0000000000..1a079c366e --- /dev/null +++ b/javalib/src/main/scala/java/lang/AutoCloseable.scala @@ -0,0 +1,11 @@ +package java.lang + +/* Even though this trait belongs to the java.lang package, we compile it as + * part of javalib instead of javalanglib, so that classes and interfaces in + * the javalib can inherit from AutoCloseable, even when we compile with JDK 6. + * It turns out that no class in java.lang needs to inherit from this trait, + * fortunately. + */ +trait AutoCloseable { + def close(): Unit +} diff --git a/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/io/AutoCloseableTest.scala b/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/io/AutoCloseableTest.scala new file mode 100644 index 0000000000..7377732516 --- /dev/null +++ b/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/io/AutoCloseableTest.scala @@ -0,0 +1,41 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.javalib.io + +import org.junit.Test +import org.junit.Assert._ + +import java.io.Closeable + +class AutoCloseableTest { + import AutoCloseableTest._ + + private def close(x: AutoCloseable): Unit = x.close() + + @Test + def closeableExtendsAutoCloseable(): Unit = { + val x = new SomeCloseable + assertFalse(x.closed) + close(x) + assertTrue(x.closed) + } + + @Test + def byteArrayOutputStreamIsAnAutoCloseable_issue_3107(): Unit = { + val x = new java.io.ByteArrayOutputStream + close(x) + } +} + +object AutoCloseableTest { + class SomeCloseable extends Closeable { + var closed: Boolean = false + + def close(): Unit = closed = true + } +} From 826e889f4b88807e484a9b3356c7e0acae6cbd48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 28 Aug 2017 11:35:13 +0200 Subject: [PATCH 0458/2665] Remove the bintray-sbt-plugin-releases resolver. It is not necessary, as sbt automatically resolves sbt plugins from that repository. --- project/build.sbt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/project/build.sbt b/project/build.sbt index 116de37bb7..25d7b2e536 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -1,8 +1,3 @@ -resolvers += Resolver.url( - "bintray-sbt-plugin-releases", - url("http://dl.bintray.com/content/sbt/sbt-plugin-releases"))( - Resolver.ivyStylePatterns) - addSbtPlugin("me.lessis" % "bintray-sbt" % "0.1.2") addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.4") From 037d0aee7d1c6865d191599f4475d6e697fab23c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 28 Aug 2017 11:37:38 +0200 Subject: [PATCH 0459/2665] Upgrade to sbt-assembly 0.14.5. This is the latest version, and the first version supporting sbt 1.0. --- project/build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.sbt b/project/build.sbt index 25d7b2e536..1ca5762f2f 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -1,6 +1,6 @@ addSbtPlugin("me.lessis" % "bintray-sbt" % "0.1.2") -addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.4") +addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.5") addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.13") From 15cca37aca7ec303058be111c27f9091a1e5a6f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 28 Aug 2017 11:44:46 +0200 Subject: [PATCH 0460/2665] Upgrade to sbt-mima-plugin 0.1.18. This is the latest version. The first version supporting sbt 1.0 was 0.1.15, but the three later versions seem to contain fixes for major binary compatibility issues (ironically). --- project/build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.sbt b/project/build.sbt index 1ca5762f2f..045bd6b866 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -2,7 +2,7 @@ addSbtPlugin("me.lessis" % "bintray-sbt" % "0.1.2") addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.5") -addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.13") +addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.18") addSbtPlugin("org.scalastyle" % "scalastyle-sbt-plugin" % "0.8.0") From b5368656234cffde7a25f768e396f3798bc173b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 28 Aug 2017 11:50:59 +0200 Subject: [PATCH 0461/2665] Upgrade to scalastyle-sbt-plugin 1.0.0. This the latest version, and the first one supporting sbt 1.0. Moreover, it now takes "shared" source directories into account by default, i.e., all `unmanagedSourceDirectories`. See the issue https://github.com/scalastyle/scalastyle-sbt-plugin/issues/47. Therefore, we remove the workaround we had for that issue. --- project/Build.scala | 39 +++++++++++---------------------------- project/build.sbt | 2 +- 2 files changed, 12 insertions(+), 29 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 7239ce2019..274eaa3145 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -419,23 +419,6 @@ 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 = ( @@ -527,7 +510,7 @@ object Build { libraryDependencies += "com.novocode" % "junit-interface" % "0.9" % "test" ) - ).enableScalastyleInSharedSources + ) lazy val irProjectJS: Project = Project( id = "irJS", @@ -541,7 +524,7 @@ object Build { ) ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( javalibEx, jUnitRuntime % "test" - ).enableScalastyleInSharedSources + ) lazy val compiler: Project = Project( id = "compiler", @@ -623,7 +606,7 @@ object Build { parallelCollectionsDependencies(scalaVersion.value) ) ) - ).dependsOn(irProject).enableScalastyleInSharedSources + ).dependsOn(irProject) lazy val toolsJS: Project = Project( id = "toolsJS", @@ -736,7 +719,7 @@ object Build { } ).withScalaJSCompiler.dependsOn( javalibEx, testSuite % "test->test", irProjectJS - ).enableScalastyleInSharedSources + ) lazy val jsEnvs: Project = Project( id = "jsEnvs", @@ -799,7 +782,7 @@ object Build { unmanagedSourceDirectories in Test += baseDirectory.value.getParentFile / "test-common/src/test/scala" ) - ).dependsOn(jsEnvs).enableScalastyleInSharedSources + ).dependsOn(jsEnvs) lazy val plugin: Project = Project( id = "sbtPlugin", @@ -836,7 +819,7 @@ object Build { sbtJars.map(_.data -> docUrl).toMap } ) - ).dependsOn(tools, jsEnvs, testAdapter).enableScalastyleInSharedSources + ).dependsOn(tools, jsEnvs, testAdapter) lazy val delambdafySetting = { scalacOptions ++= ( @@ -1218,7 +1201,7 @@ object Build { * block, so we cannot run on JS. */ ) - ).withScalaJSCompiler.dependsOn(library).enableScalastyleInSharedSources + ).withScalaJSCompiler.dependsOn(library) lazy val jUnitRuntime = Project( id = "jUnitRuntime", @@ -1246,7 +1229,7 @@ object Build { ) ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( jUnitRuntime % "test", testInterface % "test" - ).enableScalastyleInSharedSources + ) lazy val jUnitTestOutputsJVM = Project( @@ -1259,7 +1242,7 @@ object Build { "com.novocode" % "junit-interface" % "0.11" % "test" ) ) - ).enableScalastyleInSharedSources + ) lazy val jUnitPlugin = Project( id = "jUnitPlugin", @@ -1682,7 +1665,7 @@ object Build { ) ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( library, jUnitRuntime - ).enableScalastyleInSharedSources + ) lazy val testSuiteJVM: Project = Project( id = "testSuiteJVM", @@ -1704,7 +1687,7 @@ object Build { libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % "test" ) - ).enableScalastyleInSharedSources + ) lazy val noIrCheckTest: Project = Project( id = "noIrCheckTest", diff --git a/project/build.sbt b/project/build.sbt index 045bd6b866..03b24587eb 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -4,7 +4,7 @@ addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.5") addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.18") -addSbtPlugin("org.scalastyle" % "scalastyle-sbt-plugin" % "0.8.0") +addSbtPlugin("org.scalastyle" % "scalastyle-sbt-plugin" % "1.0.0") libraryDependencies += "org.scala-js" % "closure-compiler-java-6" % "v20160517" From fa5bccf80fcad3c7f37b8822e17be290865cad4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 29 Aug 2017 10:14:44 +0200 Subject: [PATCH 0462/2665] Remove `publishToScalaJSRepoSettings`. These settings to publish to a self-hosted repository for snapshots have not been used in years. --- project/Build.scala | 22 +--------------------- scripts/publish.sh | 1 - 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 274eaa3145..2612fbd45f 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -312,23 +312,6 @@ object Build { } ) - private def publishToScalaJSRepoSettings = Seq( - publishTo := { - Seq("PUBLISH_USER", "PUBLISH_PASS").map(Properties.envOrNone) match { - case Seq(Some(user), Some(pass)) => - val snapshotsOrReleases = - if (scalaJSIsSnapshotVersion) "snapshots" else "releases" - Some(Resolver.sftp( - s"scala-js-$snapshotsOrReleases", - "repo.scala-js.org", - s"/home/scalajsrepo/www/repo/$snapshotsOrReleases")( - Resolver.ivyStylePatterns) as (user, pass)) - case _ => - None - } - } - ) - private def publishToBintraySettings = ( bintrayPublishSettings ) ++ Seq( @@ -337,10 +320,7 @@ object Build { ) val publishIvySettings = ( - if (Properties.envOrNone("PUBLISH_TO_BINTRAY") == Some("true")) - publishToBintraySettings - else - publishToScalaJSRepoSettings + publishToBintraySettings ) ++ Seq( publishMavenStyle := false ) diff --git a/scripts/publish.sh b/scripts/publish.sh index f5257dcaf2..b0795043b2 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -1,7 +1,6 @@ #! /bin/sh if [ $# -eq 1 -a "$1" = "-x" ]; then - export PUBLISH_TO_BINTRAY=true CMD="sbt" else echo "Showing commands that would be executed. Use -x to run." From 23747d61470246215fb5faa297957a7610644f47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 29 Aug 2017 12:54:58 +0200 Subject: [PATCH 0463/2665] Do It Ourselves publishing to Bintray; remove bintray-sbt. Since we're not quite happy with the current state of bintray-sbt (see https://github.com/sbt/sbt-bintray/issues/130), this commit gets rid of it. Instead, we configure publishing to Bintray by hand. This turns out to be only slightly more complex than configuring Sonatype. The new behavior will not automatically *release* the newly published files. Instead, a manual intervention in the Bintray Web UI will be necessary. This actually brings our Bintray publishing more in line with Sonatype, so that's also a win. --- project/Build.scala | 26 +++++++++++++++++--------- project/build.sbt | 2 -- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 2612fbd45f..07cc801f1e 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -3,9 +3,6 @@ import Keys._ import scala.annotation.tailrec -import bintray.Plugin.bintrayPublishSettings -import bintray.Keys.{repository, bintrayOrganization, bintray} - import com.typesafe.tools.mima.plugin.MimaPlugin.autoImport._ import java.io.{ @@ -51,6 +48,9 @@ object Build { val isGeneratingEclipse = Properties.envOrElse("GENERATING_ECLIPSE", "false").toBoolean + val bintrayProjectName = settingKey[String]( + "Project name on Bintray") + val fetchScalaSource = taskKey[File]( "Fetches the scala source for the current scala version") val shouldPartest = settingKey[Boolean]( @@ -312,11 +312,19 @@ object Build { } ) - private def publishToBintraySettings = ( - bintrayPublishSettings - ) ++ Seq( - repository in bintray := "scala-js-releases", - bintrayOrganization in bintray := Some("scala-js") + private def publishToBintraySettings = Seq( + publishTo := { + val proj = bintrayProjectName.value + val ver = version.value + if (isSnapshot.value) { + None // Bintray does not support snapshots + } else { + val url = new java.net.URL( + s"https://api.bintray.com/content/scala-js/scala-js-releases/$proj/$ver") + val patterns = Resolver.ivyStylePatterns + Some(Resolver.url("bintray", url)(patterns)) + } + } ) val publishIvySettings = ( @@ -772,7 +780,7 @@ object Build { ) ++ Seq( name := "Scala.js sbt plugin", normalizedName := "sbt-scalajs", - name in bintray := "sbt-scalajs-plugin", // "sbt-scalajs" was taken + bintrayProjectName := "sbt-scalajs-plugin", // "sbt-scalajs" was taken sbtPlugin := true, scalaBinaryVersion := CrossVersion.binaryScalaVersion(scalaVersion.value), diff --git a/project/build.sbt b/project/build.sbt index 03b24587eb..01a80cd7c6 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -1,5 +1,3 @@ -addSbtPlugin("me.lessis" % "bintray-sbt" % "0.1.2") - addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.5") addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.18") From ef489d80bbf2bd378fa76130a90e0430f9c7b310 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 29 Aug 2017 20:39:17 +0200 Subject: [PATCH 0464/2665] Remove scala.scalajs.js.ScalaJSDefined. Since it is deprecated in Scala.js 0.6.20, we can now remove it from 1.x. --- .../js/annotation/ScalaJSDefined.scala | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 library/src/main/scala/scala/scalajs/js/annotation/ScalaJSDefined.scala diff --git a/library/src/main/scala/scala/scalajs/js/annotation/ScalaJSDefined.scala b/library/src/main/scala/scala/scalajs/js/annotation/ScalaJSDefined.scala deleted file mode 100644 index 878253c4da..0000000000 --- a/library/src/main/scala/scala/scalajs/js/annotation/ScalaJSDefined.scala +++ /dev/null @@ -1,19 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package scala.scalajs.js.annotation - -/** Marks the annotated class as a Scala.js-defined JavaScript class. - * - * This annotation may only be used on a class extending - * [[scala.scalajs.js.Any js.Any]]. - */ -@deprecated("Scala.js defined is now the default. This annotation has no " + - "effect and can be safely removed.", "1.0.0") -class ScalaJSDefined extends scala.annotation.StaticAnnotation From 95d83ca532692a612c74fdba395155468d1906c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 29 Aug 2017 20:40:23 +0200 Subject: [PATCH 0465/2665] Remove scala.scalajs.js.JSApp. Since it is deprecated in Scala.js 0.6.20, we can now remove it from 1.x. --- .../main/scala/scala/scalajs/js/JSApp.scala | 40 ------------------- 1 file changed, 40 deletions(-) delete mode 100644 library/src/main/scala/scala/scalajs/js/JSApp.scala diff --git a/library/src/main/scala/scala/scalajs/js/JSApp.scala b/library/src/main/scala/scala/scalajs/js/JSApp.scala deleted file mode 100644 index fed28f1e11..0000000000 --- a/library/src/main/scala/scala/scalajs/js/JSApp.scala +++ /dev/null @@ -1,40 +0,0 @@ -package scala.scalajs.js - -/** Base class for top-level, entry point main objects. - * - * Before Scala.js 0.6.18, a top-level object had to extend `js.JSApp` to be - * recognized by the sbt plugin as a "main" object, to be executed with `run`. - * Starting with Scala.js 0.6.18, any object with a standard main method of - * the form - * {{{ - * def main(args: Array[String]): Unit = ??? - * }}} - * will be recognized by the sbt plugin, just like for a JVM project. - * - * In order for the `main` method to be considered by the sbt plugin, set - * {{{ - * scalaJSUseMainModuleInitializer := true - * }}} - * in your build. - * - * [[JSApp]] is therefore deprecated, and should not be used anymore. It will - * disappear before 1.0.0 final. - * - * Also note that an object extending [[JSApp]] is not exported to JavaScript - * anymore, nor is its `main()` method. Explicitly export the object and/or - * its main method if necessary. - */ -@deprecated( - "Extending js.JSApp is not necessary anymore for an object to be " + - "recognized by the Scala.js sbt plugin. " + - "Use a normal object with a `def main(args: Array[String]): Unit` " + - "instead, which will also be cross-platform. " + - "Note that js.JSApp objects and their main() method are not " + - "automatically exported to JavaScript anymore either; explicitly export " + - "your object if you relied on this behavior.", - "1.0.0-M1") -trait JSApp { - def main(args: scala.Array[String]): Unit = main() - - def main(): Unit -} From 4486da66bd1ca188f2cc32b247e93eb3342da666 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 30 Aug 2017 10:38:10 +0200 Subject: [PATCH 0466/2665] Hide `globalIRCache` back inside `ScalaJSPluginInternal`. --- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 15 +++++++++------ .../scalajs/sbtplugin/ScalaJSPluginInternal.scala | 3 +-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index ddb9fdea28..be2bb219da 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -28,9 +28,6 @@ import org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv import org.scalajs.jsenv.phantomjs.PhantomJSEnv object ScalaJSPlugin extends AutoPlugin { - /** The global Scala.js IR cache */ - val globalIRCache: IRFileCache = new IRFileCache() - override def requires: Plugins = plugins.JvmPlugin /* The following module-case double definition is a workaround for a bug @@ -227,7 +224,9 @@ object ScalaJSPlugin extends AutoPlugin { "Do not set the value of this setting (only use it as read-only).", BSetting) - val scalaJSIRCache = TaskKey[globalIRCache.Cache]("scalaJSIRCache", + // This is lazy to avoid initialization order issues + lazy val scalaJSIRCache = TaskKey[ScalaJSPluginInternal.globalIRCache.Cache]( + "scalaJSIRCache", "Scala.js internal: Task to access a cache.", KeyRanks.Invisible) /** Persisted instance of the Scala.js linker. @@ -504,14 +503,18 @@ object ScalaJSPlugin extends AutoPlugin { ) /** Logs the current statistics about the global IR cache. */ - def logIRCacheStats(logger: Logger): Unit = + def logIRCacheStats(logger: Logger): Unit = { + import ScalaJSPluginInternal.globalIRCache logger.debug("Global IR cache stats: " + globalIRCache.stats.logLine) + } override def globalSettings: Seq[Setting[_]] = { Seq( scalaJSStage := Stage.FastOpt, scalaJSUseRhinoInternal := false, - ScalaJSPluginInternal.scalaJSClearCacheStats := globalIRCache.clearStats() + + ScalaJSPluginInternal.scalaJSClearCacheStats := + ScalaJSPluginInternal.globalIRCache.clearStats() ) } diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 085f5a1cb4..133b659e7c 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -44,8 +44,7 @@ object ScalaJSPluginInternal { import ScalaJSPlugin.autoImport.{ModuleKind => _, _} /** The global Scala.js IR cache */ - val globalIRCache: ScalaJSPlugin.globalIRCache.type = - ScalaJSPlugin.globalIRCache + val globalIRCache: IRFileCache = new IRFileCache() val scalaJSClearCacheStats = TaskKey[Unit]("scalaJSClearCacheStats", "Scala.js internal: Clear the global IR cache's statistics. Used to " + From 6bbb4ee076698beccf4575518c344e60058df7d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 29 Aug 2017 15:32:47 +0200 Subject: [PATCH 0467/2665] Fix #2171: Sanitize state persistence in the sbt plugin. * All the IR caches are explicitly freed when the build is unloaded. * The global IR cache stats are cleared every time a sequence of tasks end. This removes the need for `scalaJSClearCacheStats` and `scalaJSIRCacheHolder`, although the latter is still needed for binary compatibility in the 0.6.x series since `scalaJSIRCache` needs to stay a task. In 1.x we will be able to turn it into a setting, at which point `scalaJSIRCacheHolder` will be unnecessary. --- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 26 ++++++++- .../sbtplugin/ScalaJSPluginInternal.scala | 56 +++++++++++++++---- 2 files changed, 70 insertions(+), 12 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index be2bb219da..fcf94dfb53 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -10,6 +10,7 @@ package org.scalajs.sbtplugin import sbt._ +import sbt.Keys._ import org.scalajs.core.tools.sem.Semantics import org.scalajs.core.tools.io._ @@ -513,8 +514,29 @@ object ScalaJSPlugin extends AutoPlugin { scalaJSStage := Stage.FastOpt, scalaJSUseRhinoInternal := false, - ScalaJSPluginInternal.scalaJSClearCacheStats := - ScalaJSPluginInternal.globalIRCache.clearStats() + ScalaJSPluginInternal.scalaJSClearCacheStatsInternal := {}, + + // Clear the IR cache stats every time a sequence of tasks ends + onComplete := { + val prev = onComplete.value + + { () => + prev() + ScalaJSPluginInternal.globalIRCache.clearStats() + } + }, + + /* When unloading the build, free all the IR caches. + * Note that this runs on `reload`s, for example, but not when we + * *exit* sbt. That is fine, though, since in that case the process + * is killed altogether. + */ + onUnload := { + onUnload.value.andThen { state => + ScalaJSPluginInternal.freeAllIRCaches() + state + } + } ) } diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 133b659e7c..676c491860 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -1,6 +1,9 @@ package org.scalajs.sbtplugin +import scala.annotation.tailrec + import java.util.IllegalFormatException +import java.util.concurrent.atomic.AtomicReference import sbt._ import Keys._ @@ -46,10 +49,43 @@ object ScalaJSPluginInternal { /** The global Scala.js IR cache */ val globalIRCache: IRFileCache = new IRFileCache() - val scalaJSClearCacheStats = TaskKey[Unit]("scalaJSClearCacheStats", + private val allocatedIRCaches = + new AtomicReference[List[globalIRCache.Cache]](Nil) + + /** Allocates a new IR cache linked to the [[globalIRCache]]. + * + * The allocated IR cache will automatically be freed when the build is + * unloaded. + */ + private def newIRCache: globalIRCache.Cache = { + val cache = globalIRCache.newCache + + @tailrec + def registerLoop(): Unit = { + val prevValue = allocatedIRCaches.get() + if (!allocatedIRCaches.compareAndSet(prevValue, cache :: prevValue)) + registerLoop() + } + registerLoop() + + cache + } + + private[sbtplugin] def freeAllIRCaches(): Unit = { + val allCaches = allocatedIRCaches.getAndSet(Nil) + for (cache <- allCaches) + cache.free() + } + + /** Non-deprecated alias of `scalaJSClearCacheStats` for internal use. */ + private[sbtplugin] val scalaJSClearCacheStatsInternal = TaskKey[Unit]( + "scalaJSClearCacheStats", "Scala.js internal: Clear the global IR cache's statistics. Used to " + "implement cache statistics.", KeyRanks.Invisible) + @deprecated("Not used anymore.", "0.6.20") + val scalaJSClearCacheStats = scalaJSClearCacheStatsInternal + /** 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) @@ -60,10 +96,15 @@ object ScalaJSPluginInternal { val usesScalaJSLinkerTag: SettingKey[Tags.Tag] = ScalaJSPlugin.autoImport.usesScalaJSLinkerTag - val scalaJSIRCacheHolder = SettingKey[globalIRCache.Cache]("scalaJSIRCacheHolder", + /** Non-deprecated alias of `scalaJSIRCacheHolder` for internal use. */ + private[sbtplugin] val scalaJSIRCacheHolderInternal = SettingKey[globalIRCache.Cache]( + "scalaJSIRCacheHolder", "Scala.js internal: Setting to persist a cache. Do NOT use this directly. " + "Use scalaJSIRCache instead.", KeyRanks.Invisible) + @deprecated("Use scalaJSIRCache instead", "0.6.20") + val scalaJSIRCacheHolder = scalaJSIRCacheHolderInternal + val scalaJSIRCache: TaskKey[globalIRCache.Cache] = ScalaJSPlugin.autoImport.scalaJSIRCache @@ -418,14 +459,9 @@ object ScalaJSPluginInternal { } } ) ++ Seq( - /* Note: This cache only gets freed by its finalizer. Otherwise we'd need - * to intercept reloads in sbt (see #2171). - * Also note that it doesn't get cleared by the sbt's clean task. - */ - scalaJSIRCacheHolder := globalIRCache.newCache, - scalaJSIRCache := Def.task { - scalaJSIRCacheHolder.value - }.dependsOn(scalaJSClearCacheStats).value, + // Note: this cache is not cleared by the sbt's clean task. + scalaJSIRCacheHolderInternal := newIRCache, + scalaJSIRCache := scalaJSIRCacheHolderInternal.value, scalaJSIR := { import IRFileCache.IRContainer From d4a4af1498079e439df5368cb904d928863ad7e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 30 Aug 2017 15:01:53 +0200 Subject: [PATCH 0468/2665] Better defaults for `jsExecutionFiles` in custom sbt configurations. This is a followup to https://github.com/scala-js/scala-js/pull/3101 for `jsExecutionFiles`, which does not exist in 0.6.x and hence was not addressed in the original PR. --- .../org/scalajs/sbtplugin/ScalaJSPluginInternal.scala | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 9f4da5efe7..f98fee6099 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -336,6 +336,12 @@ object ScalaJSPluginInternal { "are running a JVM REPL. JavaScript things won't work.") }).value, + /* Do not inherit jsExecutionFiles from the parent configuration. + * Instead, always derive them straight from the Zero configuration + * scope. + */ + jsExecutionFiles := (jsExecutionFiles in (This, Zero, This)).value, + scalaJSJavaSystemProperties ++= { val javaSysPropsPattern = "-D([^=]*)=(.*)".r javaOptions.value.map { @@ -527,9 +533,6 @@ object ScalaJSPluginInternal { jsEnv := new NodeJSEnv(), jsExecutionFiles := Nil, - jsExecutionFiles in Compile := jsExecutionFiles.value, - // Do not inherit jsExecutionFiles in Test from Compile - jsExecutionFiles in Test := jsExecutionFiles.value, scalaJSJavaSystemProperties := Map.empty, From c395416fdf7b722d31486c024392bb261d9f4271 Mon Sep 17 00:00:00 2001 From: andrea Date: Fri, 18 Aug 2017 19:15:20 +0100 Subject: [PATCH 0469/2665] Implementation of SplittableRandom --- .../scala/java/util/SplittableRandom.scala | 120 +++++++++++++ .../javalib/util/SplittableRandom.scala | 157 ++++++++++++++++++ 2 files changed, 277 insertions(+) create mode 100644 javalib/src/main/scala/java/util/SplittableRandom.scala create mode 100644 test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/SplittableRandom.scala diff --git a/javalib/src/main/scala/java/util/SplittableRandom.scala b/javalib/src/main/scala/java/util/SplittableRandom.scala new file mode 100644 index 0000000000..15cb070b84 --- /dev/null +++ b/javalib/src/main/scala/java/util/SplittableRandom.scala @@ -0,0 +1,120 @@ +package java.util + +/* + * This is a clean room implementation derived from the original paper + * and Java implementation mentioned there: + * + * Fast Splittable Pseudorandom Number Generators + * by Guy L. Steele Jr., Doug Lea, Christine H. Flood + * http://gee.cs.oswego.edu/dl/papers/oopsla14.pdf + * + */ +private object SplittableRandom { + + private final val DoubleULP = 1.0 / (1L << 53) + private final val GoldenGamma = 0x9e3779b97f4a7c15L + + private var defaultGen: Long = new Random().nextLong() + + private def nextDefaultGen(): Long = { + val s = defaultGen + defaultGen = s + (2 * GoldenGamma) + s + } + + // This function implements the original MurmurHash 3 finalizer + private final def mix64ForGamma(z: Long): Long = { + val z1 = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL + val z2 = (z1 ^ (z1 >>> 33)) * 0xc4ceb9fe1a85ec53L + z2 ^ (z2 >>> 33) + } + + /* + * This function implements David Stafford's variant 4, + * while the paper version uses the original MurmurHash3 finalizer + * reference: + * http://zimbry.blogspot.pt/2011/09/better-bit-mixing-improving-on.html + */ + private final def mix32(z: Long): Int = { + val z1 = (z ^ (z >>> 33)) * 0x62a9d9ed799705f5L + val z2 = (z1 ^ (z1 >>> 28)) * 0xcb24d0a5c88c35b3L + (z2 >>> 32).toInt + } + + /* + * This function implements Stafford's variant 13, + * whereas the paper uses the original MurmurHash3 finalizer + */ + private final def mix64(z: Long): Long = { + val z1 = (z ^ (z >>> 30)) * 0xbf58476d1ce4e5b9L + val z2 = (z1 ^ (z1 >>> 27)) * 0x94d049bb133111ebL + z2 ^ (z2 >>> 31) + } + + private final def mixGamma(z: Long): Long = { + val z1 = mix64ForGamma(z) | 1L + val n = java.lang.Long.bitCount(z1 ^ (z1 >>> 1)) + /* Reference implementation is wrong since we can read in the paper: + * + * ... Therefore we require that the number of such + * pairs, as computed by Long.bitCount(z ^ (z >>> 1)), + * exceed 24; if it does not, then the candidate z is replaced by + * the XOR of z and 0xaaaaaaaaaaaaaaaaL ... + * ... so the new value necessarily has more than 24 bit pairs whose bits differ + */ + if (n <= 24) z1 ^ 0xaaaaaaaaaaaaaaaaL + else z1 + } + +} + +final class SplittableRandom private (private var seed: Long, gamma: Long) { + import SplittableRandom._ + + def this(seed: Long) = { + this(seed, SplittableRandom.GoldenGamma) + } + + private def this(ll: (Long, Long)) = this(ll._1, ll._2) + + def this() = { + this({ + val s = SplittableRandom.nextDefaultGen() + + (SplittableRandom.mix64(s), + SplittableRandom.mixGamma(s + SplittableRandom.GoldenGamma)) + }) + } + + def split(): SplittableRandom = + new SplittableRandom(mix64(nextSeed()), mixGamma(nextSeed())) + + private def nextSeed(): Long = { + seed += gamma + seed + } + + def nextInt(): Int = mix32(nextSeed()) + + //def nextInt(bound: Int): Int + + //def nextInt(origin: Int, bound: Int): Int + + def nextLong(): Long = mix64(nextSeed()) + + //def nextLong(bound: Long): Long + + //def nextLong(origin: Long, bound: Long): Long + + def nextDouble(): Double = + (nextLong() >>> 11).toDouble * DoubleULP + + //def nextDouble(bound: Double): Double + + //def nextDouble(origin: Double, bound: Double): Double + + // this should be properly tested + // looks to work but just by chance maybe + def nextBoolean(): Boolean = nextInt < 0 + +} diff --git a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/SplittableRandom.scala b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/SplittableRandom.scala new file mode 100644 index 0000000000..262181750a --- /dev/null +++ b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/SplittableRandom.scala @@ -0,0 +1,157 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.javalib.util + +import org.junit.Assert._ +import org.junit.Test + +import java.util.SplittableRandom + +import org.scalajs.testsuite.utils.AssertThrows._ + +class SplittableRandomTest { + + @Test def should_correctly_implement_nextLong(): Unit = { + val sr1 = new SplittableRandom(205620432625028L) + assertEquals(-546649510716590878L, sr1.nextLong()) + assertEquals(5574037117696891406L, sr1.nextLong()) + assertEquals(-2877648745898596966L, sr1.nextLong()) + assertEquals(5734720902145206190L, sr1.nextLong()) + assertEquals(1684781725002208217L, sr1.nextLong()) + assertEquals(687902890032948154L, sr1.nextLong()) + assertEquals(176280366443457561L, sr1.nextLong()) + assertEquals(-2944062288620903198L, sr1.nextLong()) + assertEquals(6872063775710978746L, sr1.nextLong()) + assertEquals(-7374959378916621341L, sr1.nextLong()) + + val sr2 = new SplittableRandom(-7374959378916621341L) + assertEquals(3241340805431811560L, sr2.nextLong()) + assertEquals(-2124831722811234979L, sr2.nextLong()) + assertEquals(7339249063279462363L, sr2.nextLong()) + assertEquals(1969867631102365324L, sr2.nextLong()) + assertEquals(81632902222022867L, sr2.nextLong()) + assertEquals(3451014011249622471L, sr2.nextLong()) + assertEquals(-1727223780574897556L, sr2.nextLong()) + assertEquals(-5128686556801302975L, sr2.nextLong()) + assertEquals(-6412221907719417908L, sr2.nextLong()) + assertEquals(-110482401893286265L, sr2.nextLong()) + } + + @Test def should_correctly_implement_nextInt(): Unit = { + val sr1 = new SplittableRandom(-84638) + assertEquals(962946964, sr1.nextInt()) + assertEquals(1723227640, sr1.nextInt()) + assertEquals(-621790539, sr1.nextInt()) + assertEquals(-1848500421, sr1.nextInt()) + assertEquals(-614898617, sr1.nextInt()) + assertEquals(-628601850, sr1.nextInt()) + assertEquals(-463597391, sr1.nextInt()) + assertEquals(1874082924, sr1.nextInt()) + assertEquals(-1206032701, sr1.nextInt()) + assertEquals(1549874426, sr1.nextInt()) + + val sr2 = new SplittableRandom(1549874426) + assertEquals(-495782737, sr2.nextInt()) + assertEquals(-1487672352, sr2.nextInt()) + assertEquals(-538628223, sr2.nextInt()) + assertEquals(1117712970, sr2.nextInt()) + assertEquals(2081437683, sr2.nextInt()) + assertEquals(2134440938, sr2.nextInt()) + assertEquals(-2102672277, sr2.nextInt()) + assertEquals(832521577, sr2.nextInt()) + assertEquals(518494223, sr2.nextInt()) + assertEquals(-42114979, sr2.nextInt()) + } + + @Test def should_correctly_implement_nextDouble(): Unit = { + val sr1 = new SplittableRandom(-45) + assertEquals(0.8229662358649753, sr1.nextDouble(), 0.0) + assertEquals(0.43324117570991283, sr1.nextDouble(), 0.0) + assertEquals(0.2639712712295723, sr1.nextDouble(), 0.0) + assertEquals(0.5576376282289696, sr1.nextDouble(), 0.0) + assertEquals(0.5505810186639037, sr1.nextDouble(), 0.0) + assertEquals(0.3944509738261206, sr1.nextDouble(), 0.0) + assertEquals(0.3108138671457821, sr1.nextDouble(), 0.0) + assertEquals(0.585951421265481, sr1.nextDouble(), 0.0) + assertEquals(0.2009547438834305, sr1.nextDouble(), 0.0) + assertEquals(0.8317691736686829, sr1.nextDouble(), 0.0) + + val sr2 = new SplittableRandom(45) + assertEquals(0.9684135896502549, sr2.nextDouble(), 0.0) + assertEquals(0.9819686323309464, sr2.nextDouble(), 0.0) + assertEquals(0.5311927268453047, sr2.nextDouble(), 0.0) + assertEquals(0.8521356026917833, sr2.nextDouble(), 0.0) + assertEquals(0.01880601374789126, sr2.nextDouble(), 0.0) + assertEquals(0.37792881248018584, sr2.nextDouble(), 0.0) + assertEquals(0.7179744490511354, sr2.nextDouble(), 0.0) + assertEquals(0.3448879713662756, sr2.nextDouble(), 0.0) + assertEquals(0.023020123407108684, sr2.nextDouble(), 0.0) + assertEquals(0.6454709437764473, sr2.nextDouble(), 0.0) + } + + @Test def should_correctly_implement_nextBoolean(): Unit = { + val sr1 = new SplittableRandom(4782934) + assertFalse(sr1.nextBoolean()) + assertFalse(sr1.nextBoolean()) + assertTrue(sr1.nextBoolean()) + assertTrue(sr1.nextBoolean()) + assertTrue(sr1.nextBoolean()) + assertFalse(sr1.nextBoolean()) + assertFalse(sr1.nextBoolean()) + assertTrue(sr1.nextBoolean()) + assertTrue(sr1.nextBoolean()) + assertTrue(sr1.nextBoolean()) + + val sr2 = new SplittableRandom(-4782934) + assertFalse(sr2.nextBoolean()) + assertFalse(sr2.nextBoolean()) + assertTrue(sr2.nextBoolean()) + assertTrue(sr2.nextBoolean()) + assertTrue(sr2.nextBoolean()) + assertFalse(sr2.nextBoolean()) + assertFalse(sr2.nextBoolean()) + assertTrue(sr2.nextBoolean()) + assertTrue(sr2.nextBoolean()) + assertTrue(sr2.nextBoolean()) + } + + @Test def should_correctly_implement_split(): Unit = { + val sr1 = new SplittableRandom(205620432625028L).split() + assertEquals(-2051870635339219700L, sr1.nextLong()) + assertEquals(-4512002368431042276L, sr1.nextLong()) + + val sr2 = new SplittableRandom(-4512002368431042276L).split() + assertEquals(7607532382842316154L, sr2.nextLong()) + assertEquals(-1011899051174066375L, sr2.nextLong()) + + val sr3 = new SplittableRandom(7607532382842316154L).split() + assertEquals(-1531465968943756660L, sr3.nextLong()) + assertEquals(948449286892387518L, sr3.nextLong()) + + val sr4 = new SplittableRandom(948449286892387518L).split() + assertEquals(2486448889230464769L, sr4.nextLong()) + assertEquals(4550542803092639410L, sr4.nextLong()) + + val sr5 = sr4.split() + assertEquals(8668601242423591169L, sr5.nextLong()) + assertEquals(-986244092642826172L, sr5.nextLong()) + + val sr6 = sr4.split() + assertEquals(274792684182118046L, sr6.nextLong()) + assertEquals(683259797650761389L, sr6.nextLong()) + + val sr7 = sr6.split() + assertEquals(1682793527903105269L, sr7.nextLong()) + assertEquals(2140483520539013019L, sr7.nextLong()) + + val sr8 = sr6.split() + assertEquals(-7468768144124082123L, sr8.nextLong()) + assertEquals(6163667569279435512L, sr8.nextLong()) + } + +} From 2fd375dc7d79a12f4a8d12915eb83db279693c42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 31 Aug 2017 10:23:59 +0200 Subject: [PATCH 0470/2665] Version 0.6.20. --- ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index 2efab2f894..a69a57ff61 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.20-SNAPSHOT" + val current: String = "0.6.20" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" From 9371fa909df68e9cf6d0b35ea4085845021b587e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 1 Sep 2017 00:56:07 +0200 Subject: [PATCH 0471/2665] Towards 0.6.21. --- .../org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- project/BinaryIncompatibilities.scala | 110 ------------------ project/Build.scala | 2 +- 3 files changed, 2 insertions(+), 112 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index a69a57ff61..d9f10f9265 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.20" + val current: String = "0.6.21-SNAPSHOT" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 0bf8f52d8d..c77318b933 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -18,124 +18,14 @@ object BinaryIncompatibilities { ) val TestAdapter = Seq( - // private[scalajs], not an issue. - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.TaskDefSerializers"), - - // private[testadapter], not an issue. - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.ComUtils"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.ComUtils$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.EventSerializers"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.EventSerializers$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.EventSerializers$DeserializedEvent"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.EventSerializers$EventDeserializer$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.FingerprintSerializers"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.FingerprintSerializers$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.FingerprintSerializers$DeserializedAnnotatedFingerprint"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.FingerprintSerializers$DeserializedSubclassFingerprint"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.FingerprintSerializers$FingerprintDeserializer$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.FingerprintSerializers$FingerprintSerializer$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.FrameworkInfo"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.FrameworkInfo$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.FrameworkInfo$Deserializer$"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testadapter.ScalaJSRunner.msgHandler"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.testadapter.ScalaJSRunner.getSlave"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testadapter.ScalaJSTask.fromInfo"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testadapter.ScalaJSTask.this"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.SelectorSerializers"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.SelectorSerializers$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.SelectorSerializers$SelectorDeserializer$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.SelectorSerializers$SelectorSerializer$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.TaskDefSerializers$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.TaskDefSerializers$TaskDefDeserializer$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.TaskDefSerializers$TaskDefSerializer$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.TaskInfo"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.TaskInfo$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.TaskInfo$Deserializer$") ) val CLI = Seq( ) val Library = Seq( - /* RuntimeLong lost its `with java.io.Serializable`, but that is not a - * problem because it also extends `java.lang.Number`, which itself - * implements `java.io.Serializable` anyway. - */ - ProblemFilters.exclude[MissingTypesProblem]( - "scala.scalajs.runtime.RuntimeLong") ) val TestInterface = Seq( - // protected[testinterface], not an issue. - ProblemFilters.exclude[MissingTypesProblem]( - "org.scalajs.testinterface.HTMLRunner$"), - - // internal, not an issue. - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.BridgeBase"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.EventSerializer"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.EventSerializer$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.FingerprintSerializer"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.FingerprintSerializer$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.FingerprintSerializer$DeserializedAnnotatedFingerprint"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.FingerprintSerializer$DeserializedSubclassFingerprint"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.SelectorSerializer"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.SelectorSerializer$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.TaskDefSerializer"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.TaskDefSerializer$"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.testinterface.TestDetector#RawDefinitions.definedTests"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.ThrowableSerializer"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.ThrowableSerializer$"), - ProblemFilters.exclude[MissingTypesProblem]( - "org.scalajs.testinterface.internal.Master"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testinterface.internal.Master.handleMsgImpl"), - ProblemFilters.exclude[MissingTypesProblem]( - "org.scalajs.testinterface.internal.Slave"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testinterface.internal.Slave.handleMsgImpl") ) } diff --git a/project/Build.scala b/project/Build.scala index 07cc801f1e..1cb00adbc4 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -56,7 +56,7 @@ object Build { val shouldPartest = settingKey[Boolean]( "Whether we should partest the current scala version (and fail if we can't)") - val previousVersion = "0.6.19" + val previousVersion = "0.6.20" val previousSJSBinaryVersion = ScalaJSCrossVersion.binaryScalaJSVersion(previousVersion) val previousBinaryCrossVersion = From f5f724cb92a20d2b2ed10d72ba48be2dc6185750 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 1 Sep 2017 16:26:30 +0200 Subject: [PATCH 0472/2665] Remove scalaJSIRCacheHolder and scalaJSClearCacheStats. `scalaJSIRCache` becomes a `SettingKey` to perist the cache that was previously presisted in `scalaJSIRCacheHolder`. --- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 4 +--- .../sbtplugin/ScalaJSPluginInternal.scala | 23 ++----------------- 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index ceb42a29dd..7d1c550152 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -66,7 +66,7 @@ object ScalaJSPlugin extends AutoPlugin { BSetting) // This is lazy to avoid initialization order issues - lazy val scalaJSIRCache = TaskKey[ScalaJSPluginInternal.globalIRCache.Cache]( + lazy val scalaJSIRCache = SettingKey[ScalaJSPluginInternal.globalIRCache.Cache]( "scalaJSIRCache", "Scala.js internal: Task to access a cache.", KeyRanks.Invisible) @@ -201,8 +201,6 @@ object ScalaJSPlugin extends AutoPlugin { Seq( scalaJSStage := Stage.FastOpt, - ScalaJSPluginInternal.scalaJSClearCacheStatsInternal := {}, - // Clear the IR cache stats every time a sequence of tasks ends onComplete := { val prev = onComplete.value diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 97d106573e..aca9724a5b 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -75,31 +75,13 @@ object ScalaJSPluginInternal { cache.free() } - /** Non-deprecated alias of `scalaJSClearCacheStats` for internal use. */ - private[sbtplugin] val scalaJSClearCacheStatsInternal = TaskKey[Unit]( - "scalaJSClearCacheStats", - "Scala.js internal: Clear the global IR cache's statistics. Used to " + - "implement cache statistics.", KeyRanks.Invisible) - - @deprecated("Not used anymore.", "0.6.20") - val scalaJSClearCacheStats = scalaJSClearCacheStatsInternal - val scalaJSLinker: SettingKey[ClearableLinker] = ScalaJSPlugin.autoImport.scalaJSLinker val usesScalaJSLinkerTag: SettingKey[Tags.Tag] = ScalaJSPlugin.autoImport.usesScalaJSLinkerTag - /** Non-deprecated alias of `scalaJSIRCacheHolder` for internal use. */ - private[sbtplugin] val scalaJSIRCacheHolderInternal = SettingKey[globalIRCache.Cache]( - "scalaJSIRCacheHolder", - "Scala.js internal: Setting to persist a cache. Do NOT use this directly. " + - "Use scalaJSIRCache instead.", KeyRanks.Invisible) - - @deprecated("Use scalaJSIRCache instead", "0.6.20") - val scalaJSIRCacheHolder = scalaJSIRCacheHolderInternal - - val scalaJSIRCache: TaskKey[globalIRCache.Cache] = + val scalaJSIRCache: SettingKey[globalIRCache.Cache] = ScalaJSPlugin.autoImport.scalaJSIRCache /** All .sjsir files on the fullClasspath, used by scalajsp. */ @@ -340,8 +322,7 @@ object ScalaJSPluginInternal { } ) ++ Seq( // Note: this cache is not cleared by the sbt's clean task. - scalaJSIRCacheHolderInternal := newIRCache, - scalaJSIRCache := scalaJSIRCacheHolderInternal.value, + scalaJSIRCache := newIRCache, scalaJSIR := { val rawIR = collectFromClasspath(fullClasspath.value, "*.sjsir", From e53865d85379d93bb6968cb5f76f5dc62af52433 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 1 Sep 2017 16:29:13 +0200 Subject: [PATCH 0473/2665] Widen the type of `scalaJSIRCache` to `IRFileCache#Cache`. So that it does not contain a path-dependent type to `ScalaJSPluginInternal.globalIRCache`. --- .../src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala | 3 +-- .../scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 7d1c550152..3eb8cffd50 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -65,8 +65,7 @@ object ScalaJSPlugin extends AutoPlugin { "Do not set the value of this setting (only use it as read-only).", BSetting) - // This is lazy to avoid initialization order issues - lazy val scalaJSIRCache = SettingKey[ScalaJSPluginInternal.globalIRCache.Cache]( + val scalaJSIRCache = SettingKey[IRFileCache#Cache]( "scalaJSIRCache", "Scala.js internal: Task to access a cache.", KeyRanks.Invisible) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index aca9724a5b..3e54eee80e 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -81,7 +81,7 @@ object ScalaJSPluginInternal { val usesScalaJSLinkerTag: SettingKey[Tags.Tag] = ScalaJSPlugin.autoImport.usesScalaJSLinkerTag - val scalaJSIRCache: SettingKey[globalIRCache.Cache] = + val scalaJSIRCache: SettingKey[IRFileCache#Cache] = ScalaJSPlugin.autoImport.scalaJSIRCache /** All .sjsir files on the fullClasspath, used by scalajsp. */ From 2ee5c44bc48f1524773418f27f5dbe8c27c3aaa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 1 Sep 2017 16:33:37 +0200 Subject: [PATCH 0474/2665] Make `ScalaJSPluginInternal` private to the sbt plugin. --- .../sbtplugin/ScalaJSPluginInternal.scala | 29 ++----------------- 1 file changed, 3 insertions(+), 26 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 3e54eee80e..8199fcf4a2 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -37,12 +37,11 @@ import scala.collection.mutable import java.io.FileNotFoundException import java.nio.charset.Charset -/** Contains settings used by ScalaJSPlugin that should not be automatically - * be in the *.sbt file's scope. - */ -object ScalaJSPluginInternal { +/** Implementation details of `ScalaJSPlugin`. */ +private[sbtplugin] object ScalaJSPluginInternal { import ScalaJSPlugin.autoImport.{ModuleKind => _, _} + import ScalaJSPlugin.{logIRCacheStats, stageKeys} /** The global Scala.js IR cache */ val globalIRCache: IRFileCache = new IRFileCache() @@ -75,25 +74,6 @@ object ScalaJSPluginInternal { cache.free() } - val scalaJSLinker: SettingKey[ClearableLinker] = - ScalaJSPlugin.autoImport.scalaJSLinker - - val usesScalaJSLinkerTag: SettingKey[Tags.Tag] = - ScalaJSPlugin.autoImport.usesScalaJSLinkerTag - - val scalaJSIRCache: SettingKey[IRFileCache#Cache] = - ScalaJSPlugin.autoImport.scalaJSIRCache - - /** All .sjsir files on the fullClasspath, used by scalajsp. */ - val sjsirFilesOnClasspath: TaskKey[Seq[String]] = - ScalaJSPlugin.autoImport.sjsirFilesOnClasspath - - val scalaJSSourceFiles: AttributeKey[Seq[File]] = - ScalaJSPlugin.autoImport.scalaJSSourceFiles - - val stageKeys: Map[Stage, TaskKey[Attributed[File]]] = - ScalaJSPlugin.stageKeys - /* #2798 -- On Java 9+, the parallel collections on 2.10 die with a * `NumberFormatException` and prevent the linker from working. * @@ -114,9 +94,6 @@ object ScalaJSPluginInternal { } } - def logIRCacheStats(logger: Logger): Unit = - ScalaJSPlugin.logIRCacheStats(logger) - /** Patches the IncOptions so that .sjsir files are pruned as needed. */ def scalaJSPatchIncOptions(incOptions: IncOptions): IncOptions = SBTCompat.scalaJSPatchIncOptions(incOptions) From 5a9a54653e114bee76e55f3bc78d2c2d5dc3f34f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 5 Sep 2017 12:06:14 +0200 Subject: [PATCH 0475/2665] Fix #3125: Do not pretty-print '\u0007' as '\a'. Unlike in Java, '\a' is not a valid escape sequence in JavaScript. --- .../main/scala/org/scalajs/core/ir/Utils.scala | 10 +++++----- .../testsuite/compiler/RegressionTest.scala | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Utils.scala b/ir/src/main/scala/org/scalajs/core/ir/Utils.scala index beacfd19f9..d6083139cd 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Utils.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Utils.scala @@ -16,7 +16,7 @@ import scala.annotation.switch object Utils { - private final val EscapeJSChars = "\\a\\b\\t\\n\\v\\f\\r\\\"\\\\" + private final val EscapeJSChars = "\\b\\t\\n\\v\\f\\r\\\"\\\\" /** Relativize target URI w.r.t. base URI */ def relativize(base0: URI, trgt0: URI): URI = { @@ -104,15 +104,15 @@ object Utils { // Print next non ASCII printable character if (i != end) { def escapeJSEncoded(c: Int): Unit = { - if (6 < c && c < 14) { - val i = 2 * (c - 7) + if (7 < c && c < 14) { + val i = 2 * (c - 8) out.append(EscapeJSChars, i, i + 2) writtenChars += 2 } else if (c == 34) { - out.append(EscapeJSChars, 14, 16) + out.append(EscapeJSChars, 12, 14) writtenChars += 2 } else if (c == 92) { - out.append(EscapeJSChars, 16, 18) + out.append(EscapeJSChars, 14, 16) writtenChars += 2 } else { out.append(f"\\u$c%04x") diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala index 0a70030878..282393fa9b 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala @@ -52,6 +52,22 @@ class RegressionTest { assertEquals("65 8704 55349 56491 ", s) } + @Test def characterEscapes_issue_3125(): Unit = { + val str = { + // The space at the end is intended. It is 0x20. + "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\u000a" + + "\u000b\u000c\u000d\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015" + + "\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f " + } + + for (i <- 0 until str.length) + assertEquals(i, str.charAt(i).toInt) + + val strQuotes = "\"'" + assertEquals(34, strQuotes.charAt(0).toInt) + assertEquals(39, strQuotes.charAt(1).toInt) + } + @Test def String_concatenation_with_null_issue_26(): Unit = { val x: Object = null assertEquals("nullcheck", x + "check") From cb194ae118c02744c52bc9be268602425fbf56e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 5 Sep 2017 11:07:09 +0200 Subject: [PATCH 0476/2665] Fix #3128: Avoid a binary incompatibility on JDK 7. The method `java.util.concurrent.ConcurrentHashMap.keySet()` got a more precise result type in JDK 8. Since we build the distribution on JDK 8, the compiler links to the more precise signature, which then fails to link at run-time on a JDK 7. We work around the problem by an explicit upcast to `java.util.Map`, to force the compiler to resolve to the binary compatible bridge. --- ci/matrix.xml | 3 ++- .../src/main/scala/org/scalajs/testcommon/RPCCore.scala | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ci/matrix.xml b/ci/matrix.xml index a83bab2bf5..1313d44507 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -260,7 +260,7 @@ ]]> ./project/build.properties; fi && sbt noDOM/run noDOM/testHtmlFastOpt noDOM/testHtmlFullOpt \ withDOM/run withDOM/testHtmlFastOpt withDOM/testHtmlFullOpt \ diff --git a/test-common/src/main/scala/org/scalajs/testcommon/RPCCore.scala b/test-common/src/main/scala/org/scalajs/testcommon/RPCCore.scala index 90f169a10a..b07671c2ea 100644 --- a/test-common/src/main/scala/org/scalajs/testcommon/RPCCore.scala +++ b/test-common/src/main/scala/org/scalajs/testcommon/RPCCore.scala @@ -151,8 +151,13 @@ private[scalajs] abstract class RPCCore { /** Close the communication channel. */ def close(): Unit = { + /* Fix for #3128: explicitly upcast to java.util.Map so that the keySet() + * method is binary compatible on JDK7. + */ + val pendingCallIDs = (pending: java.util.Map[Long, _]).keySet() + for { - callID <- pending.keySet().asScala + callID <- pendingCallIDs.asScala failing <- Option(pending.remove(callID)) } { failing.promise.failure(new IOException("Channel got closed")) From 312e4d9db80f09c282222ba225dcfa7123902aaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 22 Aug 2017 17:24:40 +0200 Subject: [PATCH 0477/2665] Remove the `ExportedBody` case of `Exported` in `GenJSExports`. It was dead code since 4d4e4b7e99d5437d2f1953a87a9c32a6b0ed7500. --- .../org/scalajs/core/compiler/GenJSExports.scala | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index ec646af51c..89109493c9 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -383,8 +383,6 @@ trait GenJSExports extends SubComponent { self: GenJSCode => val dParam = params.indexWhere { _.hasFlag(Flags.DEFAULTPARAM) } if (dParam == -1) Seq(params.size) else dParam to params.size - case ex: ExportedBody => - List(ex.params.size) } // Generate tuples (argc, method) @@ -502,9 +500,6 @@ trait GenJSExports extends SubComponent { self: GenJSCode => val altsByTypeTest = groupByWithoutHashCode(alts) { case ExportedSymbol(alt) => typeTestForTpe(computeExportArgType(alt, paramIndex)) - - case ex: ExportedBody => - typeTestForTpe(ex.params(paramIndex)) } if (altsByTypeTest.size == 1) { @@ -532,7 +527,6 @@ trait GenJSExports extends SubComponent { self: GenJSCode => val params = p.tpe.params params.size > paramIndex && params(paramIndex).hasFlag(Flags.DEFAULTPARAM) - case _: ExportedBody => false } val optCond = typeTest match { @@ -567,7 +561,6 @@ trait GenJSExports extends SubComponent { self: GenJSCode => // Find a position that is in the current class for decent error reporting val pos = alts.collectFirst { case ExportedSymbol(sym) if sym.owner == currentClass => sym.pos - case alt: ExportedBody => alt.pos }.getOrElse { currentClass.pos } @@ -846,13 +839,6 @@ trait GenJSExports extends SubComponent { self: GenJSCode => def typeInfo: String = sym.tpe.toString def hasRepeatedParam: Boolean = GenJSExports.this.hasRepeatedParam(sym) } - - private case class ExportedBody(params: List[Type], body: js.Tree, - name: String, pos: Position) extends Exported { - def genBody(minArgc: Int, hasRestParam: Boolean, static: Boolean): js.Tree = body - def typeInfo: String = params.mkString("(", ", ", ")") - val hasRepeatedParam: Boolean = false - } } private sealed abstract class RTTypeTest From a7d364eec8c5a0c3c9dbac890b3d76a8e472d09c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 6 Sep 2017 17:12:49 +0200 Subject: [PATCH 0478/2665] Rename `isRawJSType` to `isJSType` and optimize it. --- .../org/scalajs/core/compiler/GenJSCode.scala | 51 +++++++++++-------- .../scalajs/core/compiler/GenJSExports.scala | 4 +- .../scalajs/core/compiler/JSEncoding.scala | 2 +- 3 files changed, 32 insertions(+), 25 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 58131594a0..176a1ebfd1 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -287,7 +287,7 @@ abstract class GenJSCode extends plugins.PluginComponent generatedSAMWrapperCount := new VarBox(0) ) { try { - val tree = if (isRawJSType(sym.tpe)) { + val tree = if (isJSType(sym)) { assert(!isRawJSFunctionDef(sym), s"Raw JS function def should have been recorded: $cd") if (!sym.isTraitOrInterface && isNonNativeJSClass(sym)) @@ -2250,7 +2250,7 @@ abstract class GenJSCode extends plugins.PluginComponent isRawJSCtorDefaultParam(sym) } else { sym.hasFlag(reflect.internal.Flags.DEFAULTPARAM) && - isRawJSType(sym.owner.tpe) && { + isJSType(sym.owner) && { /* If this is a default parameter accessor on a * non-native JS class, we need to know if the method for which we * are the default parameter is exposed or not. @@ -2387,7 +2387,7 @@ abstract class GenJSCode extends plugins.PluginComponent val Apply(fun @ Select(sup @ Super(qual, _), _), args) = tree val sym = fun.symbol - if (isRawJSType(qual.tpe)) { + if (isJSType(qual.tpe)) { if (sym.isMixinConstructor) { /* Do not emit a call to the $init$ method of JS traits. * This exception is necessary because @JSOptional fields cause the @@ -2451,7 +2451,7 @@ abstract class GenJSCode extends plugins.PluginComponent ((clsSym, None, nestedGenerateClass(clsSym)(genClass(classDef)))) genNew(clsSym, ctor, genActualArgs(ctor, args)) } - } else if (isRawJSType(tpe)) { + } else if (isJSType(clsSym)) { genPrimitiveJSNew(tree) } else { toTypeKind(tpe) match { @@ -2583,7 +2583,7 @@ abstract class GenJSCode extends plugins.PluginComponent if (sym.owner == StringClass && !isStringMethodFromObject) { genStringCall(tree) - } else if (isRawJSType(receiver.tpe) && sym.owner != ObjectClass) { + } else if (isJSType(receiver.tpe) && sym.owner != ObjectClass) { if (!isNonNativeJSClass(sym.owner) || isExposed(sym)) genPrimitiveJSCall(tree, isStat) else @@ -2710,7 +2710,7 @@ abstract class GenJSCode extends plugins.PluginComponent if (sym == ObjectClass) { js.BinaryOp(js.BinaryOp.!==, value, js.Null()) - } else if (isRawJSType(to)) { + } else if (isJSType(sym)) { if (sym.isTrait) { reporter.error(pos, s"isInstanceOf[${sym.fullName}] not supported because it is a raw JS trait") @@ -2733,7 +2733,7 @@ abstract class GenJSCode extends plugins.PluginComponent val sym = to.typeSymbol - if (sym == ObjectClass || isRawJSType(to)) { + if (sym == ObjectClass || isJSType(sym)) { /* asInstanceOf[Object] always succeeds, and * asInstanceOf to a raw JS type is completely erased. */ @@ -3512,13 +3512,14 @@ abstract class GenJSCode extends plugins.PluginComponent * with the Scala/JVM compiler. */ val mustUseAnyComparator: Boolean = { - isRawJSType(ltpe) || isRawJSType(rtpe) || { - isMaybeBoxed(ltpe.typeSymbol) && isMaybeBoxed(rtpe.typeSymbol) && { + val lsym = ltpe.typeSymbol + val rsym = rtpe.typeSymbol + isJSType(lsym) || isJSType(rsym) || { + isMaybeBoxed(lsym) && isMaybeBoxed(rsym) && { val areSameFinals = - ltpe.isFinalType && rtpe.isFinalType && (ltpe =:= rtpe) + ltpe.isFinalType && rtpe.isFinalType && lsym == rsym !areSameFinals || { - val sym = ltpe.typeSymbol - (sym == BoxedFloatClass || sym == BoxedDoubleClass) && { + (lsym == BoxedFloatClass || lsym == BoxedDoubleClass) && { // Bug-compatibility for Scala < 2.12.2 !shouldPreserveEqEqBugWithJLFloatDouble } @@ -4120,7 +4121,7 @@ abstract class GenJSCode extends plugins.PluginComponent case List(Literal(value)) if value.tag == ClazzTag => val kind = toTypeKind(value.typeValue) kind match { - case REFERENCE(classSym) if isRawJSType(classSym.tpe) && + case REFERENCE(classSym) if isJSType(classSym) && !classSym.isTrait && !classSym.isModuleClass => genPrimitiveJSClass(classSym) case _ => @@ -5130,7 +5131,7 @@ abstract class GenJSCode extends plugins.PluginComponent thisActualCapture.tpe, mutable = false, rest = false)(receiver.pos) val thisCaptureArg = thisFormalCapture.ref - val body = if (isRawJSType(receiver.tpe) && target.owner != ObjectClass) { + val body = if (isJSType(receiver.tpe) && target.owner != ObjectClass) { assert(isNonNativeJSClass(target.owner) && !isExposed(target), s"A Function lambda is trying to call an exposed JS method ${target.fullName}") genApplyJSClassMethod(thisCaptureArg, target, allArgs) @@ -5335,7 +5336,7 @@ abstract class GenJSCode extends plugins.PluginComponent def moduleOrGlobalScope = genLoadModuleOrGlobalScope(sym.owner) def module = genLoadModule(sym.owner) - if (isRawJSType(sym.owner.tpe)) { + if (isJSType(sym.owner)) { if (!isNonNativeJSClass(sym.owner) || isExposed(sym)) genJSCallGeneric(sym, moduleOrGlobalScope, args = Nil, isStat = false) else @@ -5382,7 +5383,7 @@ abstract class GenJSCode extends plugins.PluginComponent } else { val cls = jstpe.ClassType(encodeClassFullName(sym)) val tree = - if (isRawJSType(sym.tpe)) js.LoadJSModule(cls) + if (isJSType(sym)) js.LoadJSModule(cls) else js.LoadModule(cls) MaybeGlobalScope.NotGlobalScope(tree) } @@ -5538,12 +5539,18 @@ abstract class GenJSCode extends plugins.PluginComponent /** Tests whether the given type represents a raw JavaScript type, * i.e., whether it extends scala.scalajs.js.Any. */ - def isRawJSType(tpe: Type): Boolean = - tpe.typeSymbol.annotations.find(_.tpe =:= RawJSTypeAnnot.tpe).isDefined + def isJSType(tpe: Type): Boolean = + isJSType(tpe.typeSymbol) + + /** Tests whether the given type symbol represents a raw JavaScript type, + * i.e., whether it extends scala.scalajs.js.Any. + */ + def isJSType(sym: Symbol): Boolean = + sym.hasAnnotation(RawJSTypeAnnot) /** Tests whether the given class is a non-native JS class. */ def isNonNativeJSClass(sym: Symbol): Boolean = - !sym.isTrait && isRawJSType(sym.tpe) && !sym.hasAnnotation(JSNativeAnnotation) + !sym.isTrait && isJSType(sym) && !sym.hasAnnotation(JSNativeAnnotation) def isAnonJSClass(sym: Symbol): Boolean = sym.hasAnnotation(AnonymousJSClassAnnotation) @@ -5554,8 +5561,8 @@ abstract class GenJSCode extends plugins.PluginComponent /** Tests whether the given class is the impl class of a raw JS trait. */ private def isRawJSImplClass(sym: Symbol): Boolean = { - sym.isImplClass && isRawJSType( - sym.owner.info.decl(sym.name.dropRight(nme.IMPL_CLASS_SUFFIX.length)).tpe) + sym.isImplClass && + isJSType(sym.owner.info.decl(sym.name.dropRight(nme.IMPL_CLASS_SUFFIX.length))) } /** Tests whether the given member is exposed, i.e., whether it was @@ -5570,7 +5577,7 @@ abstract class GenJSCode extends plugins.PluginComponent private def isRawJSCtorDefaultParam(sym: Symbol) = { isCtorDefaultParam(sym) && - isRawJSType(patchedLinkedClassOfClass(sym.owner).tpe) + isJSType(patchedLinkedClassOfClass(sym.owner)) } private def isJSNativeCtorDefaultParam(sym: Symbol) = { diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index 89109493c9..c7f8bd8321 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -760,7 +760,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => val defaultGetterArgs = result.take(defaultGetter.tpe.params.size).toList.map(_.ref) - if (isRawJSType(trgSym.toTypeConstructor)) { + if (isJSType(trgSym)) { if (isNonNativeJSClass(defaultGetter.owner)) { genApplyJSClassMethod(trgTree, defaultGetter, defaultGetterArgs) } else { @@ -932,7 +932,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => case StringClass => HijackedTypeTest(Defs.StringClass, 9) case ObjectClass => NoTypeTest case _ => - if (isRawJSType(tpe)) NoTypeTest + if (isJSType(cls)) NoTypeTest else InstanceOfTypeTest(tpe) } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala index 21f34858ca..1f5d22da54 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala @@ -208,7 +208,7 @@ trait JSEncoding extends SubComponent { self: GenJSCode => def encodeClassType(sym: Symbol): jstpe.Type = { if (sym == definitions.ObjectClass) jstpe.AnyType - else if (isRawJSType(sym.toTypeConstructor)) jstpe.AnyType + else if (isJSType(sym)) jstpe.AnyType else { assert(sym != definitions.ArrayClass, "encodeClassType() cannot be called with ArrayClass") From 7616489416daccad8aa5fc6918638c8a3fb849d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 4 Sep 2017 11:28:37 +0200 Subject: [PATCH 0479/2665] Use a dedicated task bootstrapTest for the bootstrap test. This allows `test` to do its normal job, i.e., run the testing framework. We can therefore now run the shared unit tests of the tools on JS as well. --- ci/matrix.xml | 6 ++++-- project/Build.scala | 15 ++++++++------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/ci/matrix.xml b/ci/matrix.xml index d3ddac8e66..9c81a74548 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -133,10 +133,12 @@ npm install && sbt ++$scala irJS/test toolsJS/test && sbt 'set scalaJSStage in Global := FullOptStage' \ - ++$scala irJS/test && + ++$scala irJS/test toolsJS/test && + sbt ++$scala testSuite/test:fastOptJS && + sbt ++$scala toolsJS/bootstrapTest && sbt ++$scala testSuite/test:fullOptJS && sbt 'set scalaJSStage in Global := FullOptStage' \ - ++$scala toolsJS/test + ++$scala toolsJS/bootstrapTest ]]> Date: Mon, 4 Sep 2017 17:04:55 +0200 Subject: [PATCH 0480/2665] Add unit tests for failing cases of the Analyzer. The test are pretty minimal at the moment. They only make sure that each kind of `Analysis.Error` is tested at least in one scenario. --- project/Build.scala | 9 +- .../linker/testutils/NodeVirtualJarFile.scala | 68 +++++ .../tools/linker/testutils/Platform.scala | 8 + .../core/tools/test/js/QuickLinker.scala | 62 +--- .../tools/linker/testutils/Platform.scala | 10 + .../core/tools/linker/AnalyzerTest.scala | 267 ++++++++++++++++++ .../tools/linker/testutils/TestIRRepo.scala | 31 ++ 7 files changed, 394 insertions(+), 61 deletions(-) create mode 100644 tools/js/src/test/scala/org/scalajs/core/tools/linker/testutils/NodeVirtualJarFile.scala create mode 100644 tools/js/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala create mode 100644 tools/jvm/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala create mode 100644 tools/shared/src/test/scala/org/scalajs/core/tools/linker/AnalyzerTest.scala create mode 100644 tools/shared/src/test/scala/org/scalajs/core/tools/linker/testutils/TestIRRepo.scala diff --git a/project/Build.scala b/project/Build.scala index 263ac3da9a..71893d6ebd 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -602,7 +602,11 @@ object Build { mimaBinaryIssueFilters ++= BinaryIncompatibilities.Tools, exportJars := true, // required so ScalaDoc linking works - testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a") + testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a"), + javaOptions in Test += { + val libJar = (packageBin in (LocalProject("library"), Compile)).value + "-Dorg.scalajs.core.tools.linker.stdlibjar=" + libJar.getAbsolutePath + } ) lazy val tools: Project = (project in file("tools/jvm")).settings( @@ -613,7 +617,8 @@ object Build { "com.novocode" % "junit-interface" % "0.9" % "test" ) ++ ( parallelCollectionsDependencies(scalaVersion.value) - ) + ), + fork in Test := true ).dependsOn(irProject) lazy val toolsJS: Project = (project in file("tools/js")).enablePlugins( diff --git a/tools/js/src/test/scala/org/scalajs/core/tools/linker/testutils/NodeVirtualJarFile.scala b/tools/js/src/test/scala/org/scalajs/core/tools/linker/testutils/NodeVirtualJarFile.scala new file mode 100644 index 0000000000..d78146488a --- /dev/null +++ b/tools/js/src/test/scala/org/scalajs/core/tools/linker/testutils/NodeVirtualJarFile.scala @@ -0,0 +1,68 @@ +package org.scalajs.core.tools.linker.testutils + +import java.io.InputStream + +import scala.scalajs.js +import scala.scalajs.js.annotation._ +import scala.scalajs.js.typedarray._ + +import org.scalajs.core.tools.io._ + +class NodeVirtualJarFile(file: String) + extends NodeVirtualBinaryFile(file) with VirtualFileContainer { + + import NodeVirtualJarFile._ + + 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() + } + } +} + +object NodeVirtualJarFile { + @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 --git a/tools/js/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala b/tools/js/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala new file mode 100644 index 0000000000..5a7f19068c --- /dev/null +++ b/tools/js/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala @@ -0,0 +1,8 @@ +package org.scalajs.core.tools.linker.testutils + +import org.scalajs.core.tools.io._ + +object Platform { + def loadJar(path: String): ScalaJSIRContainer = + new NodeVirtualJarFile(path) +} diff --git 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 index 96a871910b..87ef468e1f 100644 --- 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,14 +1,13 @@ package org.scalajs.core.tools.test.js -import java.io.InputStream - import org.scalajs.core.tools.io._ import org.scalajs.core.tools.linker._ import org.scalajs.core.tools.logging._ import scala.scalajs.js import scala.scalajs.js.annotation._ -import scala.scalajs.js.typedarray._ + +import org.scalajs.core.tools.linker.testutils.Platform @JSExportTopLevel("scalajs.QuickLinker") object QuickLinker { @@ -57,7 +56,7 @@ object QuickLinker { val irContainers = irFilesAndJars.map { file => if (file.endsWith(".jar")) { - new NodeVirtualJarFile(file) + Platform.loadJar(file) } else if (file.endsWith(".sjsir")) { new NodeVirtualScalaJSIRFile(file) with VirtualRelativeScalaJSIRFile { // The compiler should not use this (only scalajsp does) @@ -107,59 +106,4 @@ object QuickLinker { } } - 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 --git a/tools/jvm/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala b/tools/jvm/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala new file mode 100644 index 0000000000..67c1f6d95d --- /dev/null +++ b/tools/jvm/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala @@ -0,0 +1,10 @@ +package org.scalajs.core.tools.linker.testutils + +import java.io.File + +import org.scalajs.core.tools.io._ + +object Platform { + def loadJar(path: String): ScalaJSIRContainer = + new FileVirtualBinaryFile(new File(path)) with VirtualJarFile +} diff --git a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/AnalyzerTest.scala b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/AnalyzerTest.scala new file mode 100644 index 0000000000..2730514d64 --- /dev/null +++ b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/AnalyzerTest.scala @@ -0,0 +1,267 @@ +package org.scalajs.core.tools.linker + +import org.junit.Test +import org.junit.Assert._ + +import org.scalajs.core.ir +import org.scalajs.core.ir.ClassKind +import org.scalajs.core.ir.Definitions._ +import org.scalajs.core.ir.Trees._ +import org.scalajs.core.ir.Types._ + +import org.scalajs.core.tools.logging.NullLogger +import org.scalajs.core.tools.io._ +import org.scalajs.core.tools.linker._ +import org.scalajs.core.tools.linker.analyzer._ +import org.scalajs.core.tools.linker.standard._ + +import Analysis._ + +import org.scalajs.core.tools.linker.testutils._ + +class AnalyzerTest { + import AnalyzerTest._ + + private val reqsFactory = SymbolRequirement.factory("unit test") + + private val emptyOptHints: OptimizerHints = OptimizerHints.empty + + implicit private val noPosition: ir.Position = ir.Position.NoPosition + + private val fromAnalyzer = FromCore("analyzer") + private val fromUnitTest = FromCore("unit test") + + private def classDef( + encodedName: String, + kind: ClassKind = ClassKind.Class, + superClass: Option[String] = None, + interfaces: List[String] = Nil, + jsNativeLoadSpec: Option[JSNativeLoadSpec] = None, + memberDefs: List[MemberDef] = Nil, + topLevelExportDefs: List[TopLevelExportDef] = Nil): ClassDef = { + ClassDef(Ident(encodedName), kind, superClass.map(Ident(_)), + interfaces.map(Ident(_)), jsNativeLoadSpec, memberDefs, + topLevelExportDefs)( + emptyOptHints) + } + + private def trivialCtor(enclosingClassName: String): MethodDef = { + MethodDef(static = false, Ident("init___"), Nil, NoType, + Some(ApplyStatically(This()(ClassType(enclosingClassName)), + ClassType(ObjectClass), Ident("init___"), Nil)(NoType)))( + emptyOptHints, None) + } + + @Test + def trivialOK(): Unit = { + val analysis = computeAnalysis(Nil) + assertNoError(analysis) + } + + @Test + def missingJavaLangObject(): Unit = { + val analysis = computeAnalysis(Nil, stdlib = false) + assertExactErrors(analysis, + MissingJavaLangObjectClass(fromAnalyzer)) + } + + @Test + def invalidJavaLangObject(): Unit = { + val invalidJLObjectDefs = Seq( + // j.l.Object cannot have a super class + classDef(ObjectClass, superClass = Some("Lparent")), + // j.l.Object must have kind == ClassKind.Class + classDef(ObjectClass, kind = ClassKind.ModuleClass), + // j.l.Object cannot extend any interface + classDef(ObjectClass, interfaces = List("Lparent")) + ) + + for (jlObjectDef <- invalidJLObjectDefs) { + val analysis = computeAnalysis(Seq(jlObjectDef), stdlib = false) + assertExactErrors(analysis, + InvalidJavaLangObjectClass(fromAnalyzer)) + } + } + + @Test + def cycleInInheritanceChainThroughParentClasses(): Unit = { + val classDefs = Seq( + classDef("LA", superClass = Some("LB")), + classDef("LB", superClass = Some("LA")) + ) + + val analysis = computeAnalysis(classDefs, reqsFactory.classData("LA")) + + assertContainsError("CycleInInheritanceChain(LA, LB)", analysis) { + case CycleInInheritanceChain(List(ClsInfo("LA"), ClsInfo("LB")), + `fromUnitTest`) => + true + } + } + + @Test + def cycleInInheritanceChainThroughInterfaces(): Unit = { + val classDefs = Seq( + classDef("LA", superClass = Some("LB")), + classDef("LB", superClass = Some(ObjectClass), interfaces = List("LA")) + ) + + val analysis = computeAnalysis(classDefs, reqsFactory.classData("LA")) + + assertContainsError("CycleInInheritanceChain(LA, LB)", analysis) { + case CycleInInheritanceChain(List(ClsInfo("LA"), ClsInfo("LB")), + `fromUnitTest`) => + true + } + } + + @Test + def missingClassDirect(): Unit = { + val analysis = computeAnalysis(Nil, reqsFactory.classData("LA")) + + assertContainsError("MissingClass(LA)", analysis) { + case MissingClass(ClsInfo("LA"), `fromUnitTest`) => true + } + } + + @Test + def missingClassParent(): Unit = { + val classDefs = Seq( + classDef("LA", superClass = Some("LB")) + ) + + val analysis = computeAnalysis(classDefs, reqsFactory.classData("LA")) + + assertContainsError("MissingClass(LB)", analysis) { + case MissingClass(ClsInfo("LB"), FromClass(ClsInfo("LA"))) => true + } + } + + @Test + def notAModule(): Unit = { + val classDefs = Seq( + classDef("LA", superClass = Some(ObjectClass), + memberDefs = List(trivialCtor("LA"))) + ) + + val analysis = computeAnalysis(classDefs, reqsFactory.accessModule("LA")) + + assertContainsError("NotAModule(LA)", analysis) { + case NotAModule(ClsInfo("LA"), `fromUnitTest`) => true + } + } + + @Test + def missingMethod(): Unit = { + val classDefs = Seq( + classDef("LA", superClass = Some(ObjectClass), + memberDefs = List(trivialCtor("LA"))) + ) + + val analysis = computeAnalysis(classDefs, + reqsFactory.instantiateClass("LA", "init___") ++ + reqsFactory.callMethod("LA", "foo__V")) + + assertContainsError("MissingMethod(LA.foo__V)", analysis) { + case MissingMethod(MethInfo("LA", "foo__V"), `fromUnitTest`) => true + } + } + + @Test + def conflictingDefaultMethods(): Unit = { + val defaultMethodDef = MethodDef(static = false, Ident("foo__V"), Nil, + NoType, Some(Skip()))(emptyOptHints, None) + val classDefs = Seq( + classDef("LI1", kind = ClassKind.Interface, + memberDefs = List(defaultMethodDef)), + classDef("LI2", kind = ClassKind.Interface, + memberDefs = List(defaultMethodDef)), + classDef("LA", superClass = Some(ObjectClass), + interfaces = List("LI1", "LI2"), + memberDefs = List(trivialCtor("LA"))) + ) + + val analysis = computeAnalysis(classDefs, + reqsFactory.instantiateClass("LA", "init___") ++ + reqsFactory.callMethod("LA", "foo__V")) + + assertContainsError("ConflictingDefaultMethods(LI1.foo__V, LI2.foo__V)", + analysis) { + case ConflictingDefaultMethods( + List(MethInfo("LI1", "foo__V"), MethInfo("LI2", "foo__V")), + `fromAnalyzer`) => + true + case ConflictingDefaultMethods( + List(MethInfo("LI2", "foo__V"), MethInfo("LI1", "foo__V")), + `fromAnalyzer`) => + true + } + } + + private def computeAnalysis(classDefs: Seq[ClassDef], + symbolRequirements: SymbolRequirement = reqsFactory.none(), + stdlib: Boolean = true): Analysis = { + + val classesWithEntryPoints0 = classDefs + .map(ir.EntryPointsInfo.forClassDef) + .withFilter(_.hasEntryPoint) + .map(_.encodedName) + + val encodedNameToInfo = + classDefs.map(c => c.name.name -> Infos.generateClassInfo(c)).toMap + + val inputProvider = new Analyzer.InputProvider { + def classesWithEntryPoints(): TraversableOnce[String] = + classesWithEntryPoints0 + + def loadInfo(encodedName: String): Option[Infos.ClassInfo] = { + val own = encodedNameToInfo.get(encodedName) + if (stdlib) own.orElse(TestIRRepo.loadInfo(encodedName)) + else own + } + } + + Analyzer.computeReachability(CommonPhaseConfig(), symbolRequirements, + allowAddingSyntheticMethods = true, inputProvider) + } +} + +object AnalyzerTest { + private def assertNoError(analysis: Analysis): Unit = + assertExactErrors(analysis) + + private def assertExactErrors(analysis: Analysis, + expectedErrors: Error*): Unit = { + val actualErrors = analysis.errors + + for (expectedError <- expectedErrors) { + assertTrue(s"Missing expected error: $expectedError", + actualErrors.contains(expectedError)) + } + + if (actualErrors.size != expectedErrors.size) { + for (actualError <- actualErrors) { + assertTrue(s"Unexpected error: $actualError", + expectedErrors.contains(actualError)) + } + } + } + + private def assertContainsError(msg: String, analysis: Analysis)( + pf: PartialFunction[Error, Boolean]): Unit = { + val fullMessage = s"Expected $msg, got ${analysis.errors}" + assertTrue(fullMessage, analysis.errors.exists { + e => pf.applyOrElse(e, (_: Error) => false) + }) + } + + object ClsInfo { + def unapply(classInfo: Analysis.ClassInfo): Some[String] = + Some(classInfo.encodedName) + } + + object MethInfo { + def unapply(methodInfo: Analysis.MethodInfo): Some[(String, String)] = + Some((methodInfo.owner.encodedName, methodInfo.encodedName)) + } +} diff --git a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/testutils/TestIRRepo.scala b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/testutils/TestIRRepo.scala new file mode 100644 index 0000000000..220b8636d3 --- /dev/null +++ b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/testutils/TestIRRepo.scala @@ -0,0 +1,31 @@ +package org.scalajs.core.tools.linker.testutils + +import scala.collection.mutable + +import org.scalajs.core.tools.linker.analyzer.Infos._ +import org.scalajs.core.tools.io._ + +object TestIRRepo { + private val stdlibPath = + System.getProperty("org.scalajs.core.tools.linker.stdlibjar") + + private val globalIRCache = new IRFileCache + + val stdlibIRFiles: Seq[VirtualScalaJSIRFile with RelativeVirtualFile] = + globalIRCache.newCache.cached(Seq(Platform.loadJar(stdlibPath))) + + private val stdlibEncodedNameToFile = + stdlibIRFiles.map(f => f.entryPointsInfo.encodedName -> f).toMap + + private val infosCache = mutable.Map.empty[String, ClassInfo] + + def loadInfo(encodedName: String): Option[ClassInfo] = { + infosCache.synchronized { + infosCache.get(encodedName).orElse { + stdlibEncodedNameToFile.get(encodedName).map { f => + generateClassInfo(f.tree) + } + } + } + } +} From 73e7f732bcd8789457e64e9df8d6251f10df3215 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 30 Aug 2017 17:02:40 +0200 Subject: [PATCH 0481/2665] Filter `scala.Dynamic` out of the interfaces of JS types. JS types cannot implement Scala interfaces, so this is not valid. For other Scala interfaces, the front-end has checks to prevent this from happening. However, for `scala.Dynamic`, there is an explicit loophole, necessary to be able to define dynamically typed JS types. The loophole is definitely unsound, though. Since we do not want our IR to be unsound, we have to filter `scala.Dynamic` out from the list of interfaces implemented by JS types in the codegen. --- .../org/scalajs/core/compiler/GenJSCode.scala | 14 ++++++++------ .../scalajs/testsuite/jsinterop/DynamicTest.scala | 8 ++++++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 176a1ebfd1..29e1754475 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -464,7 +464,7 @@ abstract class GenJSCode extends plugins.PluginComponent classIdent, kind, Some(encodeClassFullNameIdent(sym.superClass)), - genClassInterfaces(sym), + genClassInterfaces(sym, forJSClass = false), None, hashedMemberDefs, topLevelExportDefs)( @@ -580,7 +580,7 @@ abstract class GenJSCode extends plugins.PluginComponent classIdent, kind, Some(encodeClassFullNameIdent(sym.superClass)), - genClassInterfaces(sym), + genClassInterfaces(sym, forJSClass = true), None, hashedMemberDefs, topLevelExports)( @@ -779,8 +779,9 @@ abstract class GenJSCode extends plugins.PluginComponent else Some(jsNativeLoadSpecOf(sym)) } - js.ClassDef(classIdent, kind, superClass, genClassInterfaces(sym), - jsNativeLoadSpec, Nil, Nil)( + js.ClassDef(classIdent, kind, superClass, + genClassInterfaces(sym, forJSClass = true), jsNativeLoadSpec, Nil, + Nil)( OptimizerHints.empty) } @@ -808,7 +809,7 @@ abstract class GenJSCode extends plugins.PluginComponent } } val generatedMethods = gen(cd.impl) - val interfaces = genClassInterfaces(sym) + val interfaces = genClassInterfaces(sym, forJSClass = false) // Hashed definitions of the interface val hashedMemberDefs = @@ -855,13 +856,14 @@ abstract class GenJSCode extends plugins.PluginComponent hashedMemberDefs, Nil)(OptimizerHints.empty) } - private def genClassInterfaces(sym: Symbol)( + private def genClassInterfaces(sym: Symbol, forJSClass: Boolean)( implicit pos: Position): List[js.Ident] = { for { parent <- sym.info.parents typeSym = parent.typeSymbol _ = assert(typeSym != NoSymbol, "parent needs symbol") if typeSym.isTraitOrInterface + if !forJSClass || typeSym != definitions.DynamicClass } yield { encodeClassFullNameIdent(typeSym) } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DynamicTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DynamicTest.scala index 92483c2404..a948edc799 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DynamicTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DynamicTest.scala @@ -321,6 +321,14 @@ class DynamicTest { val b: js.Object = obj("theValue" -> 2) assertTrue(b.hasOwnProperty("theValue")) assertFalse(b.hasOwnProperty("noValue")) + } + @Test def shouldNotListScalaDynamicAsSuperIntf(): Unit = { + /* We test the arrays of the classes, as it is the only reliable way to + * ensure that interfaces listed in the IR are what they should be. + */ + assertFalse( + "scala.Dynamic must not be a super interface of js.Dynamic", + classOf[Array[scala.Dynamic]].isAssignableFrom(classOf[Array[js.Dynamic]])) } } From 417bfe8126b94066494c66670996b31c1068418b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 30 Aug 2017 17:09:05 +0200 Subject: [PATCH 0482/2665] Fix #3076: Validate inheritance relationships in the Analyzer. --- .../core/tools/linker/analyzer/Analysis.scala | 23 +++ .../core/tools/linker/analyzer/Analyzer.scala | 108 +++++++++++++- .../core/tools/linker/AnalyzerTest.scala | 136 ++++++++++++++++++ 3 files changed, 265 insertions(+), 2 deletions(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala index 0836e7c5f9..a7c112d470 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala @@ -157,6 +157,18 @@ object Analysis { final case class InvalidJavaLangObjectClass(from: From) extends Error final case class CycleInInheritanceChain(cycle: List[ClassInfo], from: From) extends Error final case class MissingClass(info: ClassInfo, from: From) extends Error + + final case class MissingSuperClass(subClassInfo: ClassInfo, from: From) + extends Error + + final case class InvalidSuperClass(superClassInfo: ClassInfo, + subClassInfo: ClassInfo, from: From) + extends Error + + final case class InvalidImplementedInterface(superIntfInfo: ClassInfo, + subClassInfo: ClassInfo, from: From) + extends Error + final case class NotAModule(info: ClassInfo, from: From) extends Error final case class MissingMethod(info: MethodInfo, from: From) extends Error final case class ConflictingDefaultMethods(infos: List[MethodInfo], from: From) extends Error @@ -179,6 +191,17 @@ object Analysis { cycle.map(_.displayName).mkString(", ")) case MissingClass(info, _) => s"Referring to non-existent class ${info.displayName}" + case MissingSuperClass(subClassInfo, _) => + s"${subClassInfo.displayName} (of kind ${subClassInfo.kind}) is " + + "missing a super class" + case InvalidSuperClass(superClassInfo, subClassInfo, _) => + s"${superClassInfo.displayName} (of kind ${superClassInfo.kind}) is " + + s"not a valid super class of ${subClassInfo.displayName} (of kind " + + s"${subClassInfo.kind})" + case InvalidImplementedInterface(superIntfInfo, subClassInfo, _) => + s"${superIntfInfo.displayName} (of kind ${superIntfInfo.kind}) is " + + s"not a valid interface implemented by ${subClassInfo.displayName} " + + s"(of kind ${subClassInfo.kind})" case NotAModule(info, _) => s"Cannot access module for non-module ${info.displayName}" case MissingMethod(info, _) => diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala index 9cf8bbb6b2..d9bcb9ac24 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala @@ -31,6 +31,7 @@ private final class Analyzer(config: CommonPhaseConfig, import Analyzer._ import ClassInfo.newClassInfo + private var objectClassInfo: ClassInfo = _ private[this] val _classInfos = mutable.Map.empty[String, ClassInfo] private[this] val _errors = mutable.Buffer.empty[Error] @@ -53,7 +54,7 @@ private final class Analyzer(config: CommonPhaseConfig, data.interfaces.nonEmpty) { _errors += InvalidJavaLangObjectClass(fromAnalyzer) } else { - newClassInfo(data, nonExistent = false) + objectClassInfo = newClassInfo(data, nonExistent = false) } } @@ -62,6 +63,8 @@ private final class Analyzer(config: CommonPhaseConfig, * cannot continue. */ } else { + assert(objectClassInfo != null) + try { /* Hijacked classes are always instantiated, because values of primitive * types are their instances. @@ -279,12 +282,113 @@ private final class Analyzer(config: CommonPhaseConfig, superClass = data.superClass.map(lookupClassAndCheckCycles) interfaces = data.interfaces.map(lookupClassAndCheckCycles) - // TODO #3076: Validate the super class and implemented interfaces + // j.l.Object is special and is validated upfront + if (encodedName != ObjectClass) { + validateSuperClass() + validateInterfaces() + } val parents = superClass ++: interfaces ancestors = this +: parents.flatMap(_.ancestors).distinct } + private[this] def validateSuperClass(): Unit = { + implicit def from = FromClass(this) + + kind match { + case ClassKind.Class | ClassKind.ModuleClass | ClassKind.HijackedClass => + superClass.fold[Unit] { + _errors += MissingSuperClass(this, from) + superClass = Some(objectClassInfo) + } { superCl => + if (superCl.kind != ClassKind.Class) { + _errors += InvalidSuperClass(superCl, this, from) + superClass = Some(objectClassInfo) + } + } + + case ClassKind.Interface => + superClass.foreach { superCl => + _errors += InvalidSuperClass(superCl, this, from) + superClass = None + } + + case ClassKind.JSClass | ClassKind.JSModuleClass => + /* There is no correct fallback in case of error, here. The logical + * thing to do would be to pick `js.Object`, but we cannot be sure + * that `js.Object` and its inheritance chain are valid themselves. + * So we just say superClass = None in invalid cases, and make sure + * this does not blow up the rest of the analysis. + */ + superClass.fold[Unit] { + _errors += MissingSuperClass(this, from) + } { superCl => + superCl.kind match { + case ClassKind.JSClass | ClassKind.NativeJSClass => + // ok + case _ => + _errors += InvalidSuperClass(superCl, this, from) + superClass = None + } + } + + case ClassKind.NativeJSClass | ClassKind.NativeJSModuleClass => + superClass.fold[Unit] { + _errors += MissingSuperClass(this, from) + superClass = Some(objectClassInfo) + } { superCl => + superCl.kind match { + case ClassKind.JSClass | ClassKind.NativeJSClass => + // ok + case _ if superCl eq objectClassInfo => + // ok + case _ => + _errors += InvalidSuperClass(superCl, this, from) + superClass = Some(objectClassInfo) + } + } + + case ClassKind.AbstractJSType => + superClass.foreach { superCl => + superCl.kind match { + case ClassKind.JSClass | ClassKind.NativeJSClass => + // ok + case _ if superCl eq objectClassInfo => + // ok + case _ => + _errors += InvalidSuperClass(superCl, this, from) + superClass = None + } + } + } + } + + private[this] def validateInterfaces(): Unit = { + implicit def from = FromClass(this) + + val validSuperIntfKind = kind match { + case ClassKind.Class | ClassKind.ModuleClass | + ClassKind.HijackedClass | ClassKind.Interface => + ClassKind.Interface + case ClassKind.JSClass | ClassKind.JSModuleClass | + ClassKind.NativeJSClass | ClassKind.NativeJSModuleClass | + ClassKind.AbstractJSType => + ClassKind.AbstractJSType + } + + interfaces = interfaces.filter { superIntf => + if (superIntf.nonExistent) { + // Remove it but do not report an additional error message + false + } else if (superIntf.kind != validSuperIntfKind) { + _errors += InvalidImplementedInterface(superIntf, this, from) + false + } else { + true + } + } + } + var isInstantiated: Boolean = false var isAnySubclassInstantiated: Boolean = false var isModuleAccessed: Boolean = false diff --git a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/AnalyzerTest.scala b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/AnalyzerTest.scala index 2730514d64..bdacd41162 100644 --- a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/AnalyzerTest.scala +++ b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/AnalyzerTest.scala @@ -137,6 +137,129 @@ class AnalyzerTest { } } + @Test + def missingSuperClass(): Unit = { + val kinds = Seq( + ClassKind.Class, + ClassKind.ModuleClass, + ClassKind.HijackedClass, + ClassKind.JSClass, + ClassKind.JSModuleClass, + ClassKind.NativeJSClass, + ClassKind.NativeJSModuleClass + ) + + for (kind <- kinds) { + val classDefs = Seq( + classDef("LA", kind = kind, memberDefs = List(trivialCtor("LA"))) + ) + + val analysis = computeAnalysis(classDefs, + reqsFactory.instantiateClass("LA", "init___")) + + assertContainsError("MissingSuperClass(LA)", analysis) { + case MissingSuperClass(ClsInfo("LA"), FromClass(ClsInfo("LA"))) => true + } + } + } + + @Test + def invalidSuperClass(): Unit = { + val kindsSub = Seq( + ClassKind.Class, + ClassKind.ModuleClass, + ClassKind.HijackedClass, + ClassKind.Interface, + ClassKind.JSClass, + ClassKind.JSModuleClass, + ClassKind.NativeJSClass, + ClassKind.NativeJSModuleClass, + ClassKind.AbstractJSType + ) + + def kindsBaseFor(kindSub: ClassKind): Seq[ClassKind] = { + import ClassKind._ + kindSub match { + case Class | ModuleClass | HijackedClass => + Seq(Interface, ModuleClass, JSClass, NativeJSClass) + case Interface => + Seq(Class, Interface) + case JSClass | JSModuleClass | NativeJSClass | NativeJSModuleClass | + AbstractJSType => + Seq(Class, Interface, AbstractJSType, JSModuleClass) + } + } + + for { + kindSub <- kindsSub + kindBase <- kindsBaseFor(kindSub) + } { + val classDefs = Seq( + classDef("LA", kind = kindSub, superClass = Some("LB")), + classDef("LB", kind = kindBase, + superClass = validParentForKind(kindBase)) + ) + + val analysis = computeAnalysis(classDefs, + reqsFactory.instantiateClass("LA", "init___")) + + assertContainsError("InvalidSuperClass(LB, LA)", analysis) { + case InvalidSuperClass(ClsInfo("LB"), ClsInfo("LA"), + FromClass(ClsInfo("LA"))) => + true + } + } + } + + @Test + def invalidImplementedInterface(): Unit = { + val kindsCls = Seq( + ClassKind.Class, + ClassKind.ModuleClass, + ClassKind.HijackedClass, + ClassKind.Interface, + ClassKind.JSClass, + ClassKind.JSModuleClass, + ClassKind.NativeJSClass, + ClassKind.NativeJSModuleClass, + ClassKind.AbstractJSType + ) + + def kindsIntfFor(kindCls: ClassKind): Seq[ClassKind] = { + import ClassKind._ + kindCls match { + case Class | ModuleClass | HijackedClass | Interface => + Seq(Class, ModuleClass, JSClass, NativeJSClass, AbstractJSType) + case JSClass | JSModuleClass | NativeJSClass | NativeJSModuleClass | + AbstractJSType => + Seq(Class, ModuleClass, HijackedClass, Interface, JSClass, + JSModuleClass, NativeJSClass, NativeJSModuleClass) + } + } + + for { + kindCls <- kindsCls + kindIntf <- kindsIntfFor(kindCls) + } { + val classDefs = Seq( + classDef("LA", kind = kindCls, + superClass = validParentForKind(kindCls), + interfaces = List("LB")), + classDef("LB", kind = kindIntf, + superClass = validParentForKind(kindIntf)) + ) + + val analysis = computeAnalysis(classDefs, + reqsFactory.instantiateClass("LA", "init___")) + + assertContainsError("InvalidImplementedInterface(LB, LA)", analysis) { + case InvalidImplementedInterface(ClsInfo("LB"), ClsInfo("LA"), + FromClass(ClsInfo("LA"))) => + true + } + } + } + @Test def notAModule(): Unit = { val classDefs = Seq( @@ -198,6 +321,19 @@ class AnalyzerTest { } } + private def validParentForKind(kind: ClassKind): Option[String] = { + import ClassKind._ + kind match { + case Class | ModuleClass | HijackedClass | NativeJSClass | + NativeJSModuleClass => + Some(ObjectClass) + case JSClass | JSModuleClass => + Some("sjs_js_Object") + case Interface | AbstractJSType => + None + } + } + private def computeAnalysis(classDefs: Seq[ClassDef], symbolRequirements: SymbolRequirement = reqsFactory.none(), stdlib: Boolean = true): Analysis = { From 4d8f39a3c7dd304a07cada51bd908f57d99eafbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 9 Sep 2017 14:29:21 +0200 Subject: [PATCH 0483/2665] [no-master] Fix #3135: Relativize source map URIs against the .js file. Instead of the parent directory of the .js file. This solves the issue that the parent directory did not have a trailing `/` in some cases. --- .../scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 676c491860..f41707a1fe 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -208,7 +208,7 @@ object ScalaJSPluginInternal { */ val oldConfigRelSourceMapBase = { if ((relativeSourceMaps in key).value) - Some((artifactPath in key).value.getParentFile.toURI()) + Some((artifactPath in key).value.toURI()) else None } From e722745bea0d1362574ff667043aac6c01c0af9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 9 Sep 2017 17:18:55 +0200 Subject: [PATCH 0484/2665] [no-master] Further reduce the pressure on PhantomJS in the test suite. Once again, we are forced to reduce the test suite on PhantomJS, as we initially did in 8166c6c782a13ea117c01b9d0761418671b69c9b. This time, we remove the tests for charset encoders and decoders, as well as all tests that require specific versions of Scala or of the JDK. Those should also not be sensitive to their environment. --- project/Build.scala | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 1cb00adbc4..99397eabd2 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1610,9 +1610,13 @@ object Build { val sourceFiles = (sources in Test).value if ((jsEnv in Test).?.value.exists(isPhantomJS)) { sourceFiles.filter { f => - !f.getAbsolutePath - .replace('\\', '/') - .contains("/org/scalajs/testsuite/javalib/math/") + val path = f.getAbsolutePath.replace('\\', '/') + + { + !path.contains("/org/scalajs/testsuite/javalib/math/") && + !path.contains("/org/scalajs/testsuite/niocharset/") && + !path.contains("/src/test/require-") + } } } else { sourceFiles From a487545249ebb91f61260425a073f6dd27df4b66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 5 Sep 2017 21:35:30 +0200 Subject: [PATCH 0485/2665] Rewrite and complete j.l.String{Builder,Buffer}. This is a complete rewrite of `java.lang.StringBuilder`, with the complete set of methods from JDK 8. This includes `delete()`, which fixes #3124. The test suite has also been rewritten. `java.lang.StringBuffer` is also rewritten, but delegates all its operations to an underlying `StringBuilder`. Since this class is rarely used, due to its bad reputation (synchronization), it is not worth making it fast. A few methods of `java.lang.String` are also added, if they were necessary to implement the corresponding ones in `StringBuilder`. No effort was made to complete the set of methods of `String` in this commit. --- ci/checksizes.sh | 6 +- .../src/main/scala/java/lang/Character.scala | 32 +- .../main/scala/java/lang/StringBuffer.scala | 285 ++++--- .../main/scala/java/lang/StringBuilder.scala | 300 +++---- .../scala/scalajs/runtime/RuntimeString.scala | 79 +- .../javalib/lang/StringBufferTest.scala | 734 +++++++++++++----- .../javalib/lang/StringBuilderTest.scala | 643 +++++++++++++++ .../testsuite/javalib/lang/StringTest.scala | 68 ++ .../lang/WrappedStringCharSequence.scala | 30 + 9 files changed, 1688 insertions(+), 489 deletions(-) create mode 100644 test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringBuilderTest.scala create mode 100644 test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/WrappedStringCharSequence.scala diff --git a/ci/checksizes.sh b/ci/checksizes.sh index 3d5baecf83..fa1e2fbf35 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -43,19 +43,19 @@ case $FULLVER in REVERSI_OPT_GZ_EXPECTEDSIZE=31000 ;; 2.11.11) - REVERSI_PREOPT_EXPECTEDSIZE=527000 + REVERSI_PREOPT_EXPECTEDSIZE=529000 REVERSI_OPT_EXPECTEDSIZE=124000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=71000 REVERSI_OPT_GZ_EXPECTEDSIZE=32000 ;; 2.12.3) - REVERSI_PREOPT_EXPECTEDSIZE=629000 + REVERSI_PREOPT_EXPECTEDSIZE=630000 REVERSI_OPT_EXPECTEDSIZE=147000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=76000 REVERSI_OPT_GZ_EXPECTEDSIZE=33000 ;; 2.13.0-M2) - REVERSI_PREOPT_EXPECTEDSIZE=627000 + REVERSI_PREOPT_EXPECTEDSIZE=628000 REVERSI_OPT_EXPECTEDSIZE=147000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=76000 REVERSI_OPT_GZ_EXPECTEDSIZE=33000 diff --git a/javalanglib/src/main/scala/java/lang/Character.scala b/javalanglib/src/main/scala/java/lang/Character.scala index 6d8bf062e4..50e56f0dd1 100644 --- a/javalanglib/src/main/scala/java/lang/Character.scala +++ b/javalanglib/src/main/scala/java/lang/Character.scala @@ -529,13 +529,10 @@ object Character { if (!isValidCodePoint(codePoint)) throw new IllegalArgumentException() - if (isSupplementaryCodePoint(codePoint)) { - val dst = new Array[Char](2) - toSurrogate(codePoint, dst, 0) - dst - } else { + if (isSupplementaryCodePoint(codePoint)) + Array(highSurrogateOf(codePoint), lowSurrogateOf(codePoint)) + else Array(codePoint.toChar) - } } def toChars(codePoint: Int, dst: Array[Char], dstIndex: Int): Int = { @@ -543,7 +540,8 @@ object Character { throw new IllegalArgumentException() if (isSupplementaryCodePoint(codePoint)) { - toSurrogate(codePoint, dst, dstIndex) + dst(dstIndex) = highSurrogateOf(codePoint) + dst(dstIndex + 1) = lowSurrogateOf(codePoint) 2 } else { dst(dstIndex) = codePoint.toChar @@ -551,14 +549,22 @@ object Character { } } - @inline private[this] def toSurrogate(codePoint: Int, dst: Array[Char], dstIndex: Int): Unit = { - val cpPrime = codePoint - 0x10000 - val high = 0xD800 | ((cpPrime >> 10) & 0x3FF) - val low = 0xDC00 | (cpPrime & 0x3FF) - dst(dstIndex) = high.toChar - dst(dstIndex + 1) = low.toChar + private[lang] def codePointToString(codePoint: Int): String = { + if (!isValidCodePoint(codePoint)) + throw new IllegalArgumentException() + + if (isSupplementaryCodePoint(codePoint)) + highSurrogateOf(codePoint).toString + lowSurrogateOf(codePoint).toString + else + codePoint.toChar.toString } + @inline private def highSurrogateOf(codePoint: Int): Char = + (0xd800 | ((codePoint >> 10) - (0x10000 >> 10))).toChar + + @inline private def lowSurrogateOf(codePoint: Int): Char = + (0xdc00 | (codePoint & 0x3ff)).toChar + @inline def toString(c: scala.Char): String = js.Dynamic.global.String.fromCharCode(c.toInt).asInstanceOf[String] diff --git a/javalanglib/src/main/scala/java/lang/StringBuffer.scala b/javalanglib/src/main/scala/java/lang/StringBuffer.scala index 16db542b86..023b8775f5 100644 --- a/javalanglib/src/main/scala/java/lang/StringBuffer.scala +++ b/javalanglib/src/main/scala/java/lang/StringBuffer.scala @@ -1,177 +1,166 @@ package java.lang -class StringBuffer(private var content: String) extends CharSequence - with Appendable - with java.io.Serializable { - def this() = this("") - def this(initialCapacity: Int) = this("") - def this(csq: CharSequence) = this(csq.toString) - - def append(s: String): StringBuffer = { - content += { if (s == null) "null" else s } - this - } +/* Given the rare usefulness of StringBuffer in the context of Scala.js, and + * its general bad reputation, we do not make any effort towards performance. + * We simply delegate all operations to an underlying j.l.StringBuilder, which + * shares the specifications of StringBuffer except for the synchronization + * part, which is irrelevant in Scala.js anyway. + */ +class StringBuffer private (builder: StringBuilder) + extends AnyRef with CharSequence with Appendable with java.io.Serializable { - def append(b: scala.Boolean): StringBuffer = append(b.toString()) - def append(c: scala.Char): StringBuffer = append(c.toString()) + def this() = this(new StringBuilder()) + def this(str: String) = this(new StringBuilder(str)) + def this(capacity: Int) = this(new StringBuilder(capacity)) + def this(seq: CharSequence) = this(seq.toString) - def append(str: Array[scala.Char]): StringBuffer = - append(str, 0, str.length) + /** A helper so that we can write stuff like `withThisResult(append(obj))`. */ + @inline + private def withThisResult(op: StringBuilder): StringBuffer = this - def append(str: Array[scala.Char], offset: Int, len: Int): StringBuffer = { - var i = 0 - while (i < len) { - content += str(i + offset) - i += 1 - } - this - } + def length(): Int = builder.length() - def append(b: scala.Byte): StringBuffer = append(b.toString()) - def append(s: scala.Short): StringBuffer = append(s.toString()) - def append(i: scala.Int): StringBuffer = append(i.toString()) - def append(lng: scala.Long): StringBuffer = append(lng.toString()) - def append(f: scala.Float): StringBuffer = append(f.toString()) - def append(d: scala.Double): StringBuffer = append(d.toString()) + def capacity(): Int = builder.capacity() - def append(obj: AnyRef): StringBuffer = { - if (obj == null) append(null: String) - else append(obj.toString()) - } + def ensureCapacity(minimumCapacity: Int): Unit = + builder.ensureCapacity(minimumCapacity) + + def trimToSize(): Unit = builder.trimToSize() + + def setLength(newLength: Int): Unit = builder.setLength(newLength) + + def charAt(index: Int): Char = builder.charAt(index) - def append(csq: CharSequence): StringBuffer = append(csq: AnyRef) - def append(csq: CharSequence, start: Int, end: Int): StringBuffer = { - if (csq == null) append("null", start, end) - else append(csq.subSequence(start, end).toString()) + def codePointAt(index: Int): Int = builder.codePointAt(index) + + def codePointBefore(index: Int): Int = builder.codePointBefore(index) + + def codePointCount(beginIndex: Int, endIndex: Int): Int = + builder.codePointCount(beginIndex, endIndex) + + def offsetByCodePoints(index: Int, codePointOffset: Int): Int = + builder.offsetByCodePoints(index, codePointOffset) + + def getChars(srcBegin: Int, srcEnd: Int, dst: Array[Char], + dstBegin: Int): Unit = { + builder.getChars(srcBegin, srcEnd, dst, dstBegin) } + def setCharAt(index: Int, ch: Char): Unit = + builder.setCharAt(index, ch) + + def append(obj: AnyRef): StringBuffer = + withThisResult(builder.append(obj)) + + def append(str: String): StringBuffer = + withThisResult(builder.append(str)) + + def append(sb: StringBuffer): StringBuffer = + withThisResult(builder.append(sb)) + + def append(s: CharSequence): StringBuffer = + withThisResult(builder.append(s)) + + def append(s: CharSequence, start: Int, end: Int): StringBuffer = + withThisResult(builder.append(s, start, end)) + + def append(str: Array[Char]): StringBuffer = + withThisResult(builder.append(str)) + + def append(str: Array[Char], offset: Int, len: Int): StringBuffer = + withThisResult(builder.append(str, offset, len)) + + def append(b: scala.Boolean): StringBuffer = + withThisResult(builder.append(b)) + + def append(c: Char): StringBuffer = + withThisResult(builder.append(c)) + + def append(i: Int): StringBuffer = + withThisResult(builder.append(i)) + def appendCodePoint(codePoint: Int): StringBuffer = - append(Character.toChars(codePoint)) + withThisResult(builder.appendCodePoint(codePoint)) - override def toString(): String = content + def append(lng: scala.Long): StringBuffer = + withThisResult(builder.append(lng)) - def length(): Int = content.length() + def append(f: scala.Float): StringBuffer = + withThisResult(builder.append(f)) - def charAt(index: Int): Char = content.charAt(index) - def codePointAt(index: Int): Int = content.codePointAt(index) + def append(d: scala.Double): StringBuffer = + withThisResult(builder.append(d)) - def indexOf(str: String): Int = content.indexOf(str) + def delete(start: Int, end: Int): StringBuffer = + withThisResult(builder.delete(start, end)) - def indexOf(str: String, fromIndex: Int): Int = - content.indexOf(str, fromIndex) + def deleteCharAt(index: Int): StringBuffer = + withThisResult(builder.deleteCharAt(index)) - def lastIndexOf(str: String): Int = content.lastIndexOf(str) + def replace(start: Int, end: Int, str: String): StringBuffer = + withThisResult(builder.replace(start, end, str)) - def lastIndexOf(str: String, fromIndex: Int): Int = - content.lastIndexOf(str, fromIndex) + def substring(start: Int): String = + builder.substring(start) - def subSequence(start: Int, end: Int): CharSequence = substring(start, end) - def substring(start: Int): String = content.substring(start) - def substring(start: Int, end: Int): String = content.substring(start, end) + def subSequence(start: Int, end: Int): CharSequence = + builder.subSequence(start, end) - def reverse(): StringBuffer = { - content = new StringBuilder(content).reverse().toString() - this - } + def substring(start: Int, end: Int): String = builder.substring(start, end) - def deleteCharAt(index: Int): StringBuffer = { - if (index < 0 || index >= content.length) - throw new StringIndexOutOfBoundsException("String index out of range: " + index) - content = content.substring(0, index) + content.substring(index+1) - this - } + def insert(index: Int, str: Array[Char], offset: Int, len: Int): StringBuffer = + withThisResult(builder.insert(index, str, offset, len)) - def ensureCapacity(minimumCapacity: Int): Unit = { - // Do nothing - } + def insert(offset: Int, obj: AnyRef): StringBuffer = + withThisResult(builder.insert(offset, obj)) - /** - * @param start The beginning index, inclusive. - * @param end The ending index, exclusive. - * @param str String that will replace previous contents. - * @return This StringBuilder. - */ - def replace(start: Int, end: Int, str: String): StringBuffer = { - val length = content.length - if (start < 0 || start > end || start > length) { - throw new StringIndexOutOfBoundsException( - s"Illegal to replace substring at [$start - $end] in string of length $length") - } - - val realEnd = if (end > length) length else end // java api convention - content = content.substring(0, start) + str + content.substring(realEnd) - this - } + def insert(offset: Int, str: String): StringBuffer = + withThisResult(builder.insert(offset, str)) - def setCharAt(index: Int, ch: scala.Char): Unit = { - if (index < 0 || index >= content.length) { - throw new StringIndexOutOfBoundsException( - "String index out of range: " + index) - } - content = content.substring(0, index) + ch + content.substring(index + 1) - } + def insert(offset: Int, str: Array[Char]): StringBuffer = + withThisResult(builder.insert(offset, str)) - def setLength(newLength: Int): Unit = { - if (newLength < 0) { - throw new StringIndexOutOfBoundsException( - "String index out of range: " + newLength) - } - - val len = length() - if (len == newLength) { - } else if (len < newLength) { - var index = len - while (index < newLength) { - append("\u0000") - index += 1 - } - } else { - content = substring(0, newLength) - } - } + def insert(dstOffset: Int, s: CharSequence): StringBuffer = + withThisResult(builder.insert(dstOffset, s)) - def insert(index: Int, b: scala.Boolean): StringBuffer = insert(index, b.toString) - def insert(index: Int, b: scala.Byte): StringBuffer = insert(index, b.toString) - def insert(index: Int, s: scala.Short): StringBuffer = insert(index, s.toString) - def insert(index: Int, i: scala.Int): StringBuffer = insert(index, i.toString) - def insert(index: Int, l: scala.Long): StringBuffer = insert(index, l.toString) - def insert(index: Int, f: scala.Float): StringBuffer = insert(index, f.toString) - def insert(index: Int, d: scala.Double): StringBuffer = insert(index, d.toString) - def insert(index: Int, c: scala.Char): StringBuffer = insert(index, c.toString) - def insert(index: Int, csq: CharSequence): StringBuffer = insert(index: Int, csq: AnyRef) - def insert(index: Int, arr: Array[scala.Char]): StringBuffer = insert(index, arr, 0, arr.length) - - def insert(index: Int, ref: AnyRef): StringBuffer = - if (ref == null) - insert(index, null: String) - else - insert(index, ref.toString) - - def insert(index: Int, csq: CharSequence, start: Int, end: Int): StringBuffer = - if (csq == null) - insert(index, "null", start, end) - else - insert(index, csq.subSequence(start, end).toString) - - - def insert(index: Int, arr: Array[scala.Char], offset: Int, len: Int): StringBuffer = { - var str = "" - var i = 0 - while (i < len) { - str += arr(i + offset) - i += 1 - } - insert(index, str) + def insert(dstOffset: Int, s: CharSequence, start: Int, + end: Int): StringBuffer = { + withThisResult(builder.insert(dstOffset, s, start, end)) } - def insert(index: Int, str: String): StringBuffer = { - val thisLength = length() - if (index < 0 || index > thisLength) - throw new StringIndexOutOfBoundsException(index) - else if (index == thisLength) - append(str) - else - content = content.substring(0, index) + Option(str).getOrElse("null") + content.substring(index) - this - } + def insert(offset: Int, b: scala.Boolean): StringBuffer = + withThisResult(builder.insert(offset, b)) + + def insert(offset: Int, c: Char): StringBuffer = + withThisResult(builder.insert(offset, c)) + + def insert(offset: Int, i: Int): StringBuffer = + withThisResult(builder.insert(offset, i)) + + def insert(offset: Int, l: scala.Long): StringBuffer = + withThisResult(builder.insert(offset, l)) + + def insert(offset: Int, f: scala.Float): StringBuffer = + withThisResult(builder.insert(offset, f)) + + def insert(offset: Int, d: scala.Double): StringBuffer = + withThisResult(builder.insert(offset, d)) + + def indexOf(str: String): Int = + builder.indexOf(str) + + def indexOf(str: String, fromIndex: Int): Int = + builder.indexOf(str, fromIndex) + + def lastIndexOf(str: String): Int = + builder.lastIndexOf(str) + + def lastIndexOf(str: String, fromIndex: Int): Int = + builder.lastIndexOf(str, fromIndex) + + def reverse(): StringBuffer = + withThisResult(builder.reverse()) + + override def toString(): String = + builder.toString() } diff --git a/javalanglib/src/main/scala/java/lang/StringBuilder.scala b/javalanglib/src/main/scala/java/lang/StringBuilder.scala index 28af223d0a..58d5cac810 100644 --- a/javalanglib/src/main/scala/java/lang/StringBuilder.scala +++ b/javalanglib/src/main/scala/java/lang/StringBuilder.scala @@ -1,59 +1,132 @@ package java.lang -class StringBuilder(private var content: String) extends CharSequence - with Appendable - with java.io.Serializable { - def this() = this("") - def this(initialCapacity: Int) = this("") - def this(csq: CharSequence) = this(csq.toString) - - def append(s: String): StringBuilder = { - content += { if (s == null) "null" else s } - this +class StringBuilder + extends AnyRef with CharSequence with Appendable with java.io.Serializable { + + private[this] var content: String = "" + + def this(str: String) = { + this() + if (str eq null) + throw new NullPointerException + content = str } - def append(b: scala.Boolean): StringBuilder = append(b.toString()) - def append(c: scala.Char): StringBuilder = append(c.toString()) + def this(initialCapacity: Int) = { + this() + if (initialCapacity < 0) + throw new NegativeArraySizeException() + } - def append(str: Array[scala.Char]): StringBuilder = - append(str, 0, str.length) + def this(seq: CharSequence) = this(seq.toString) - def append(str: Array[scala.Char], offset: Int, len: Int): StringBuilder = { - var i = 0 - while (i < len) { - content += str(i + offset) - i += 1 - } + @inline + def append(obj: AnyRef): StringBuilder = { + // If (obj eq null), this appends "null", otherwise obj.toString() + content += obj + this + } + + @inline + def append(str: String): StringBuilder = { + content += str // if (str eq null), this appends "null" this } - def append(b: scala.Byte): StringBuilder = append(b.toString()) - def append(s: scala.Short): StringBuilder = append(s.toString()) + def append(sb: StringBuffer): StringBuilder = append(sb: AnyRef) + + def append(s: CharSequence): StringBuilder = append(s: AnyRef) + + def append(s: CharSequence, start: Int, end: Int): StringBuilder = + append((if (s == null) "null" else s).subSequence(start, end)) + + def append(str: Array[scala.Char]): StringBuilder = + append(String.valueOf(str)) + + def append(str: Array[scala.Char], offset: Int, len: Int): StringBuilder = + append(String.valueOf(str, offset, len)) + + def append(b: scala.Boolean): StringBuilder = append(b.toString()) + def append(c: scala.Char): StringBuilder = append(c.toString()) def append(i: scala.Int): StringBuilder = append(i.toString()) def append(lng: scala.Long): StringBuilder = append(lng.toString()) def append(f: scala.Float): StringBuilder = append(f.toString()) def append(d: scala.Double): StringBuilder = append(d.toString()) - def append(obj: AnyRef): StringBuilder = { - if (obj == null) append(null: String) - else append(obj.toString()) + def appendCodePoint(codePoint: Int): StringBuilder = + append(Character.codePointToString(codePoint)) + + def delete(start: Int, end: Int): StringBuilder = + replace(start, end, "") + + def deleteCharAt(index: Int): StringBuilder = { + /* This is not equivalent to `delete(index, index + 1)` when + * `index == length`. + */ + val oldContent = content + if (index < 0 || index >= oldContent.length) + throw new StringIndexOutOfBoundsException(index) + content = oldContent.substring(0, index) + oldContent.substring(index + 1) + this } - def append(csq: CharSequence): StringBuilder = append(csq: AnyRef) - def append(csq: CharSequence, start: Int, end: Int): StringBuilder = { - if (csq == null) append("null", start, end) - else append(csq.subSequence(start, end).toString()) + def replace(start: Int, end: Int, str: String): StringBuilder = { + val oldContent = content + val length = oldContent.length + if (start < 0 || start > length || start > end) + throw new StringIndexOutOfBoundsException(start) + val firstPart = oldContent.substring(0, start) + str + content = + if (end >= length) firstPart + else firstPart + oldContent.substring(end) + this } - def appendCodePoint(codePoint: Int): StringBuilder = - append(Character.toChars(codePoint)) + def insert(index: Int, str: Array[scala.Char], offset: Int, + len: Int): StringBuilder = { + insert(index, String.valueOf(str, offset, len)) + } - override def toString(): String = content + @inline def insert(offset: Int, obj: AnyRef): StringBuilder = + insert(offset, String.valueOf(obj)) - def length(): Int = content.length() + def insert(offset: Int, str: String): StringBuilder = { + val oldContent = content + if (offset < 0 || offset > oldContent.length) + throw new StringIndexOutOfBoundsException(offset) + content = + oldContent.substring(0, offset) + str + oldContent.substring(offset) + this + } - def charAt(index: Int): Char = content.charAt(index) - def codePointAt(index: Int): Int = content.codePointAt(index) + def insert(offset: Int, str: Array[scala.Char]): StringBuilder = + insert(offset, String.valueOf(str)) + + def insert(dstOffset: Int, s: CharSequence): StringBuilder = + insert(dstOffset, s: AnyRef) + + def insert(dstOffset: Int, s: CharSequence, start: Int, + end: Int): StringBuilder = { + insert(dstOffset, (if (s == null) "null" else s).subSequence(start, end)) + } + + def insert(offset: Int, b: scala.Boolean): StringBuilder = + insert(offset, b.toString) + + def insert(offset: Int, c: scala.Char): StringBuilder = + insert(offset, c.toString) + + def insert(offset: Int, i: scala.Int): StringBuilder = + insert(offset, i.toString) + + def insert(offset: Int, l: scala.Long): StringBuilder = + insert(offset, l.toString) + + def insert(offset: Int, f: scala.Float): StringBuilder = + insert(offset, f.toString) + + def insert(offset: Int, d: scala.Double): StringBuilder = + insert(offset, d.toString) def indexOf(str: String): Int = content.indexOf(str) @@ -65,132 +138,87 @@ class StringBuilder(private var content: String) extends CharSequence def lastIndexOf(str: String, fromIndex: Int): Int = content.lastIndexOf(str, fromIndex) - def subSequence(start: Int, end: Int): CharSequence = substring(start, end) - def substring(start: Int): String = content.substring(start) - def substring(start: Int, end: Int): String = content.substring(start, end) - def reverse(): StringBuilder = { val original = content var result = "" - var i = 0 - while (i < original.length) { + var i = original.length - 1 + while (i > 0) { val c = original.charAt(i) - if (Character.isHighSurrogate(c) && (i+1 < original.length)) { - val c2 = original.charAt(i+1) - if (Character.isLowSurrogate(c2)) { - result = c.toString + c2.toString + result - i += 2 + if (Character.isLowSurrogate(c)) { + val c2 = original.charAt(i - 1) + if (Character.isHighSurrogate(c2)) { + result = result + c2.toString + c.toString + i -= 2 } else { - result = c.toString + result - i += 1 + result += c.toString + i -= 1 } } else { - result = c.toString + result - i += 1 + result += c.toString + i -= 1 } } + if (i == 0) + result += original.charAt(0).toString content = result this } - def deleteCharAt(index: Int): StringBuilder = { - if (index < 0 || index >= content.length) - throw new StringIndexOutOfBoundsException("String index out of range: " + index) - content = content.substring(0, index) + content.substring(index+1) - this - } + override def toString(): String = content - def ensureCapacity(minimumCapacity: Int): Unit = { - // Do nothing - } + def length(): Int = content.length() - /** - * @param start The beginning index, inclusive. - * @param end The ending index, exclusive. - * @param str String that will replace previous contents. - * @return This StringBuilder. - */ - def replace(start: Int, end: Int, str: String): StringBuilder = { - val length = content.length - if (start < 0 || start > end || start > length) { - throw new StringIndexOutOfBoundsException( - s"Illegal to replace substring at [$start - $end] in string of length $length") - } + def capacity(): Int = length() - val realEnd = if (end > length) length else end // java api convention - content = content.substring(0, start) + str + content.substring(realEnd) - this - } + def ensureCapacity(minimumCapacity: Int): Unit = () - def setCharAt(index: Int, ch: scala.Char): Unit = { - if (index < 0 || index >= content.length) { - throw new StringIndexOutOfBoundsException( - "String index out of range: " + index) - } - content = content.substring(0, index) + ch + content.substring(index + 1) - } + def trimToSize(): Unit = () def setLength(newLength: Int): Unit = { - if (newLength < 0) { - throw new StringIndexOutOfBoundsException( - "String index out of range: " + newLength) - } - - val len = length() - if (len == newLength) { - } else if (len < newLength) { - var index = len - while (index < newLength) { - append("\u0000") - index += 1 - } + if (newLength < 0) + throw new StringIndexOutOfBoundsException(newLength) + var newContent = content + val additional = newLength - newContent.length // cannot overflow + if (additional < 0) { + newContent = newContent.substring(0, newLength) } else { - content = substring(0, newLength) + var i = 0 + while (i != additional) { + newContent += "\u0000" + i += 1 + } } + content = newContent } - def insert(index: Int, b: scala.Boolean): StringBuilder = insert(index, b.toString) - def insert(index: Int, b: scala.Byte): StringBuilder = insert(index, b.toString) - def insert(index: Int, s: scala.Short): StringBuilder = insert(index, s.toString) - def insert(index: Int, i: scala.Int): StringBuilder = insert(index, i.toString) - def insert(index: Int, l: scala.Long): StringBuilder = insert(index, l.toString) - def insert(index: Int, f: scala.Float): StringBuilder = insert(index, f.toString) - def insert(index: Int, d: scala.Double): StringBuilder = insert(index, d.toString) - def insert(index: Int, c: scala.Char): StringBuilder = insert(index, c.toString) - def insert(index: Int, csq: CharSequence): StringBuilder = insert(index: Int, csq: AnyRef) - def insert(index: Int, arr: Array[scala.Char]): StringBuilder = insert(index, arr, 0, arr.length) - - def insert(index: Int, ref: AnyRef): StringBuilder = - if (ref == null) - insert(index, null: String) - else - insert(index, ref.toString) - - def insert(index: Int, csq: CharSequence, start: Int, end: Int): StringBuilder = - if (csq == null) - insert(index, "null", start, end) - else - insert(index, csq.subSequence(start, end).toString) - - - def insert(index: Int, arr: Array[scala.Char], offset: Int, len: Int): StringBuilder = { - var str = "" - var i = 0 - while (i < len) { - str += arr(i + offset) - i += 1 - } - insert(index, str) + def charAt(index: Int): Char = content.charAt(index) + + def codePointAt(index: Int): Int = content.codePointAt(index) + + def codePointBefore(index: Int): Int = content.codePointBefore(index) + + def codePointCount(beginIndex: Int, endIndex: Int): Int = + content.codePointCount(beginIndex, endIndex) + + def offsetByCodePoints(index: Int, codePointOffset: Int): Int = + content.offsetByCodePoints(index, codePointOffset) + + def getChars(srcBegin: Int, srcEnd: Int, dst: Array[scala.Char], + dstBegin: Int): Unit = { + content.getChars(srcBegin, srcEnd, dst, dstBegin) } - def insert(index: Int, str: String): StringBuilder = { - val thisLength = length() - if (index < 0 || index > thisLength) + def setCharAt(index: Int, ch: scala.Char): Unit = { + val oldContent = content + if (index < 0 || index >= oldContent.length) throw new StringIndexOutOfBoundsException(index) - else if (index == thisLength) - append(str) - else - content = content.substring(0, index) + Option(str).getOrElse("null") + content.substring(index) - this + content = + oldContent.substring(0, index) + ch + oldContent.substring(index + 1) } + + def substring(start: Int): String = content.substring(start) + + def subSequence(start: Int, end: Int): CharSequence = substring(start, end) + + def substring(start: Int, end: Int): String = content.substring(start, end) } diff --git a/library/src/main/scala/scala/scalajs/runtime/RuntimeString.scala b/library/src/main/scala/scala/scalajs/runtime/RuntimeString.scala index 354553c278..2e8fc6d828 100644 --- a/library/src/main/scala/scala/scalajs/runtime/RuntimeString.scala +++ b/library/src/main/scala/scala/scalajs/runtime/RuntimeString.scala @@ -58,6 +58,19 @@ private[runtime] object RuntimeString { } } + def codePointBefore(thiz: String, index: Int): Int = { + val low = thiz.charAt(index - 1) + if (index > 1) { + val high = thiz.charAt(index - 2) + if (Character.isSurrogatePair(high, low)) + Character.toCodePoint(high, low) + else + low.toInt + } else { + low.toInt + } + } + def codePointCount(thiz: String, beginIndex: Int, endIndex: Int): Int = { if (endIndex > thiz.length || beginIndex < 0 || endIndex < beginIndex) throw new IndexOutOfBoundsException @@ -72,6 +85,46 @@ private[runtime] object RuntimeString { res } + def offsetByCodePoints(thiz: String, index: Int, + codePointOffset: Int): Int = { + val len = thiz.length + if (index < 0 || index > len) + throw new StringIndexOutOfBoundsException(index) + + if (codePointOffset >= 0) { + var i = 0 + var result = index + while (i != codePointOffset) { + if (result >= len) + throw new StringIndexOutOfBoundsException + if ((result < len - 1) && + Character.isHighSurrogate(thiz.charAt(result)) && + Character.isLowSurrogate(thiz.charAt(result + 1))) { + result += 2 + } else { + result += 1 + } + i += 1 + } + result + } else { + var i = 0 + var result = index + while (i != codePointOffset) { + if (result <= 0) + throw new StringIndexOutOfBoundsException + if ((result > 1) && Character.isLowSurrogate(thiz.charAt(result - 1)) && + Character.isHighSurrogate(thiz.charAt(result - 2))) { + result -= 2 + } else { + result -= 1 + } + i -= 1 + } + result + } + } + def hashCode(thiz: String): Int = { var res = 0 var mul = 1 // holds pow(31, length-i-1) @@ -355,17 +408,21 @@ private[runtime] object RuntimeString { // Static methods (aka methods on the companion object) - def valueOf(value: Boolean): String = value.toString() - def valueOf(value: Char): String = value.toString() - def valueOf(value: Byte): String = value.toString() - def valueOf(value: Short): String = value.toString() - def valueOf(value: Int): String = value.toString() - def valueOf(value: Long): String = value.toString() - def valueOf(value: Float): String = value.toString() - def valueOf(value: Double): String = value.toString() - - def valueOf(value: Object): String = - if (value eq null) "null" else value.toString() + @deprecated("Not part of the JDK API", "0.6.21") + def valueOf(b: Byte): String = b.toString() + + @deprecated("Not part of the JDK API", "0.6.21") + def valueOf(s: Short): String = s.toString() + + def valueOf(b: Boolean): String = b.toString() + def valueOf(c: Char): String = c.toString() + def valueOf(i: Int): String = i.toString() + def valueOf(l: Long): String = l.toString() + def valueOf(f: Float): String = f.toString() + def valueOf(d: Double): String = d.toString() + + @inline def valueOf(obj: Object): String = + "" + obj // if (obj eq null), returns "null" def valueOf(data: Array[Char]): String = valueOf(data, 0, data.length) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringBufferTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringBufferTest.scala index 8d9f302a63..31efd0e179 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringBufferTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringBufferTest.scala @@ -1,6 +1,6 @@ /* __ *\ ** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** ** /____/\___/_/ |_/____/_/ | |__/ /____/ ** ** |/____/ ** @@ -13,242 +13,620 @@ import org.junit.Assert._ import org.scalajs.testsuite.utils.AssertThrows._ import org.scalajs.testsuite.utils.Platform.executingInJVM +import WrappedStringCharSequence.charSequence + +/* !!! This test class is basically a copy-paste of StringBuilderTest. + * Make sure to always update them in sync. + */ class StringBufferTest { - def newBuf: java.lang.StringBuffer = - new java.lang.StringBuffer - - def initBuf(str: String): java.lang.StringBuffer = - new java.lang.StringBuffer(str) - - @Test def append(): Unit = { - assertEquals("asdf", newBuf.append("asdf").toString) - assertEquals("null", newBuf.append(null: AnyRef).toString) - assertEquals("null", newBuf.append(null: String).toString) - assertEquals("nu", newBuf.append(null: CharSequence,0,2).toString) - assertEquals("true", newBuf.append(true).toString) - assertEquals("a", newBuf.append('a').toString) - assertEquals("abcd", newBuf.append(Array('a','b','c','d')).toString) - assertEquals("bc", newBuf.append(Array('a','b','c','d'), 1, 2).toString) - assertEquals("4", newBuf.append(4.toByte).toString) - assertEquals("304", newBuf.append(304.toShort).toString) - assertEquals("100000", newBuf.append(100000).toString) - assertEquals("2.5", newBuf.append(2.5f).toString) - assertEquals("3.5", newBuf.append(3.5).toString) - } - - @Test def insert(): Unit = { - assertEquals("asdf", newBuf.insert(0, "asdf").toString) - assertEquals("null", newBuf.insert(0, null: AnyRef).toString) - assertEquals("null", newBuf.insert(0, null: String).toString) - assertEquals("nu", newBuf.insert(0, null: CharSequence,0,2).toString) - assertEquals("true", newBuf.insert(0, true).toString) - assertEquals("a", newBuf.insert(0, 'a').toString) - assertEquals("abcd", newBuf.insert(0, Array('a','b','c','d')).toString) - assertEquals("bc", newBuf.insert(0, Array('a','b','c','d'), 1, 2).toString) - assertEquals("4", newBuf.insert(0, 4.toByte).toString) - assertEquals("304", newBuf.insert(0, 304.toShort).toString) - assertEquals("100000", newBuf.insert(0, 100000).toString) - assertEquals("2.5", newBuf.insert(0, 2.5f).toString) - assertEquals("3.5", newBuf.insert(0, 3.5).toString) - - assertEquals("abcdef", initBuf("adef").insert(1, "bc").toString) - assertEquals("abcdef", initBuf("abcd").insert(4, "ef").toString) - assertEquals("abcdef", initBuf("adef").insert(1, Array('b','c')).toString) - assertEquals("abcdef", initBuf("adef").insert(1, initBuf("bc")).toString) - assertEquals("abcdef", initBuf("abef").insert(2, Array('a','b','c','d','e'), 2, 2).toString) - assertEquals("abcdef", initBuf("abef").insert(2, initBuf("abcde"), 2, 4).toString) - - expectThrows(classOf[StringIndexOutOfBoundsException], - initBuf("abcd").insert(5, "whatever")) - expectThrows(classOf[StringIndexOutOfBoundsException], - initBuf("abcd").insert(-1, "whatever")) + def newBuffer: StringBuffer = + new StringBuffer + + def initBuffer(str: String): StringBuffer = + new StringBuffer(str) + + @Test def init(): Unit = { + assertEquals("", new StringBuffer().toString()) + } + + @Test def initInt(): Unit = { + assertEquals("", new StringBuffer(5).toString()) + } + + @Test def initString(): Unit = { + assertEquals("hello", new StringBuffer("hello").toString()) + + if (executingInJVM) { + expectThrows(classOf[NullPointerException], + new StringBuffer(null: String)) + } + } + + @Test def initCharSequence(): Unit = { + assertEquals("hello", new StringBuffer(charSequence("hello")).toString()) + + if (executingInJVM) { + expectThrows(classOf[NullPointerException], + new StringBuffer(null: CharSequence)) + } + } + + @Test def appendAnyRef(): Unit = { + def resultFor(x: AnyRef): String = newBuffer.append(x).toString() + + assertEquals("null", resultFor(null)) + assertEquals("None", resultFor(None)) + assertEquals("hello", resultFor("hello")) + assertEquals("foobar", resultFor(charSequence("foobar"))) + } + + @Test def appendString(): Unit = { + def resultFor(x: String): String = newBuffer.append(x).toString() + + assertEquals("null", resultFor(null)) + assertEquals("hello", resultFor("hello")) + } + + @Test def appendStringBuffer(): Unit = { + def resultFor(x: StringBuffer): String = newBuffer.append(x).toString() + + assertEquals("null", resultFor(null)) + assertEquals("", resultFor(new StringBuffer())) + assertEquals("hello", resultFor(new StringBuffer("hello"))) + } + + @Test def appendCharSequence(): Unit = { + def resultFor(x: CharSequence): String = newBuffer.append(x).toString() + + assertEquals("null", resultFor(null)) + assertEquals("hello", resultFor("hello")) + assertEquals("", resultFor(charSequence(""))) + assertEquals("foobar", resultFor(charSequence("foobar"))) + } + + @Test def appendCharSequenceStartEnd(): Unit = { + def resultFor(x: CharSequence, start: Int, end: Int): String = + newBuffer.append(x, start, end).toString() + + assertEquals("ul", resultFor(null, 1, 3)) + assertEquals("null", resultFor(null, 0, 4)) + assertEquals("ello", resultFor("hello", 1, 5)) + assertEquals("ob", resultFor(charSequence("foobar"), 2, 4)) + + expectThrows(classOf[IndexOutOfBoundsException], + resultFor(charSequence("he"), 1, 3)) + expectThrows(classOf[IndexOutOfBoundsException], + resultFor(charSequence("he"), -1, 2)) + expectThrows(classOf[IndexOutOfBoundsException], + resultFor(charSequence("he"), 2, 1)) + } + + @Test def appendCharArray(): Unit = { + def resultFor(x: Array[Char]): String = newBuffer.append(x).toString() + + assertEquals("hello", resultFor(Array('h', 'e', 'l', 'l', 'o'))) + + if (executingInJVM) + expectThrows(classOf[NullPointerException], resultFor(null)) + } + + @Test def appendCharArrayOffsetLen(): Unit = { + def resultFor(x: Array[Char], offset: Int, len: Int): String = + newBuffer.append(x, offset, len).toString() + + val arr = Array('h', 'e', 'l', 'l', 'o') + assertEquals("hello", resultFor(arr, 0, 5)) + assertEquals("ell", resultFor(arr, 1, 3)) + + if (executingInJVM) + expectThrows(classOf[NullPointerException], resultFor(null, 0, 0)) + + expectThrows(classOf[IndexOutOfBoundsException], resultFor(arr, -1, 2)) + expectThrows(classOf[IndexOutOfBoundsException], resultFor(arr, 3, 3)) + expectThrows(classOf[IndexOutOfBoundsException], resultFor(arr, 3, -2)) + } + + @Test def appendPrimitive(): Unit = { + assertEquals("true", newBuffer.append(true).toString) + assertEquals("a", newBuffer.append('a').toString) + assertEquals("100000", newBuffer.append(100000).toString) + assertEquals("12345678910", newBuffer.append(12345678910L).toString) + assertEquals("2.5", newBuffer.append(2.5f).toString) + assertEquals("3.5", newBuffer.append(3.5).toString) + + // There is no overload for Byte nor Short; these call the Int version + assertEquals("4", newBuffer.append(4.toByte).toString) + assertEquals("304", newBuffer.append(304.toShort).toString) + } + + @Test def appendCodePoint(): Unit = { + def resultFor(codePoint: Int): String = + newBuffer.appendCodePoint(codePoint).toString() + + assertEquals("a", resultFor(0x61)) + assertEquals("\ud800\udc00", resultFor(0x10000)) + assertEquals("\ud800\udc01", resultFor(0x10001)) + assertEquals("\ud801\udc01", resultFor(0x10401)) + assertEquals("\udbff\udfff", resultFor(0x10ffff)) + + expectThrows(classOf[IllegalArgumentException], resultFor(0x111111)) + expectThrows(classOf[IllegalArgumentException], resultFor(-1)) + } + + @Test def delete(): Unit = { + def resultFor(input: String, start: Int, end: Int): String = + initBuffer(input).delete(start, end).toString() + + assertEquals("heo", resultFor("hello", 2, 4)) + assertEquals("foo\ud800r", resultFor("foo\ud800\udc00bar", 4, 7)) + assertEquals("hello", resultFor("hello", 0, 0)) + assertEquals("hello", resultFor("hello", 5, 5)) + assertEquals("hel", resultFor("hello", 3, 8)) + + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("hello", -1, 2)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("hello", 3, 2)) } @Test def deleteCharAt(): Unit = { - assertEquals("023", initBuf("0123").deleteCharAt(1).toString) - assertEquals("123", initBuf("0123").deleteCharAt(0).toString) - assertEquals("012", initBuf("0123").deleteCharAt(3).toString) + def resultFor(input: String, index: Int): String = + initBuffer(input).deleteCharAt(index).toString() + + assertEquals("023", resultFor("0123", 1)) + assertEquals("123", resultFor("0123", 0)) + assertEquals("012", resultFor("0123", 3)) + expectThrows(classOf[StringIndexOutOfBoundsException], - initBuf("0123").deleteCharAt(-1)) + resultFor("0123", -1)) expectThrows(classOf[StringIndexOutOfBoundsException], - initBuf("0123").deleteCharAt(4)) + resultFor("0123", 4)) } @Test def replace(): Unit = { - assertEquals("0bc3", initBuf("0123").replace(1,3,"bc").toString) - assertEquals("abcd", initBuf("0123").replace(0,4,"abcd").toString) - assertEquals("abcd", initBuf("0123").replace(0,10,"abcd").toString) - assertEquals("012defg", initBuf("0123").replace(3,10,"defg").toString) - assertEquals("xxxx123", initBuf("0123").replace(0,1,"xxxx").toString) - assertEquals("0xxxx123", initBuf("0123").replace(1,1,"xxxx").toString) - assertEquals("0123x", initBuf("0123").replace(4, 5, "x").toString) + def resultFor(input: String, start: Int, end: Int, str: String): String = + initBuffer(input).replace(start, end, str).toString() + assertEquals("0bc3", resultFor("0123", 1, 3, "bc")) + assertEquals("abcd", resultFor("0123", 0, 4, "abcd")) + assertEquals("abcd", resultFor("0123", 0, 10, "abcd")) + assertEquals("012defg", resultFor("0123", 3, 10, "defg")) + assertEquals("xxxx123", resultFor("0123", 0, 1, "xxxx")) + assertEquals("0xxxx123", resultFor("0123", 1, 1, "xxxx")) + assertEquals("0123x", resultFor("0123", 4, 5, "x")) + + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("0123", -1, 3, "x")) expectThrows(classOf[StringIndexOutOfBoundsException], - initBuf("0123").replace(-1,3,"x")) + resultFor("0123", 4, 3, "x")) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("0123", 5, 8, "x")) + + if (executingInJVM) + expectThrows(classOf[NullPointerException], resultFor("0123", 1, 3, null)) } - @Test def setCharAt(): Unit = { - val buf = newBuf - buf.append("foobar") + @Test def insertCharArrayOffsetLen(): Unit = { + def resultFor(input: String, index: Int, str: Array[Char], offset: Int, + len: Int): String = { + initBuffer(input).insert(index, str, offset, len).toString() + } - buf.setCharAt(2, 'x') - assertEquals("foxbar", buf.toString) + val arr = Array('a', 'b', 'c', 'd', 'e') - buf.setCharAt(5, 'h') - assertEquals("foxbah", buf.toString) + assertEquals("0bc12", resultFor("012", 1, arr, 1, 2)) + assertEquals("abcdef", resultFor("abef", 2, arr, 2, 2)) expectThrows(classOf[StringIndexOutOfBoundsException], - buf.setCharAt(-1, 'h')) + resultFor("1234", -1, arr, 1, 2)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("1234", 6, arr, 1, 2)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("1234", 1, arr, -1, 2)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("1234", 1, arr, 1, -2)) expectThrows(classOf[StringIndexOutOfBoundsException], - buf.setCharAt(6, 'h')) + resultFor("1234", 1, arr, 4, 3)) + + if (executingInJVM) { + expectThrows(classOf[NullPointerException], + resultFor("1234", 1, null, 0, 0)) + } } - @Test def ensureCapacity(): Unit = { - // test that ensureCapacity is linking - newBuf.ensureCapacity(10) + @Test def insertAnyRef(): Unit = { + def resultFor(input: String, index: Int, x: AnyRef): String = + initBuffer(input).insert(index, x).toString() + + assertEquals("01null234", resultFor("01234", 2, null)) + assertEquals("01None234", resultFor("01234", 2, None)) + assertEquals("01hello234", resultFor("01234", 2, "hello")) + assertEquals("01foobar234", resultFor("01234", 2, charSequence("foobar"))) + + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("1234", -1, "foo")) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("1234", 6, "foo")) } - @Test def should_properly_setLength(): Unit = { - val buf = newBuf - buf.append("foobar") + @Test def insertString(): Unit = { + def resultFor(input: String, index: Int, x: String): String = + initBuffer(input).insert(index, x).toString() - expectThrows(classOf[StringIndexOutOfBoundsException], buf.setLength(-3)) + assertEquals("01null234", resultFor("01234", 2, null)) + assertEquals("01hello234", resultFor("01234", 2, "hello")) - assertEquals("foo", { buf.setLength(3); buf.toString }) - assertEquals("foo\u0000\u0000\u0000", { buf.setLength(6); buf.toString }) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("1234", -1, "foo")) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("1234", 6, "foo")) } - @Test def appendCodePoint(): Unit = { - val buf = newBuf - buf.appendCodePoint(0x61) - assertEquals("a", buf.toString) - buf.appendCodePoint(0x10000) - assertEquals("a\uD800\uDC00", buf.toString) - buf.append("fixture") - buf.appendCodePoint(0x00010FFFF) - assertEquals("a\uD800\uDC00fixture\uDBFF\uDFFF", buf.toString) + @Test def insertCharArray(): Unit = { + def resultFor(input: String, index: Int, str: Array[Char]): String = + initBuffer(input).insert(index, str).toString() + + val arr = Array('a', 'b', 'c', 'd', 'e') + + assertEquals("0abcde12", resultFor("012", 1, arr)) + assertEquals("ababcdeef", resultFor("abef", 2, arr)) + + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("1234", -1, arr)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("1234", 6, arr)) + + if (executingInJVM) + expectThrows(classOf[NullPointerException], resultFor("1234", 1, null)) } -} -class StringBuilderTest { + @Test def insertCharSequence(): Unit = { + def resultFor(input: String, index: Int, x: CharSequence): String = + initBuffer(input).insert(index, x).toString() - def newBuilder: java.lang.StringBuilder = - new java.lang.StringBuilder + assertEquals("01null234", resultFor("01234", 2, null)) + assertEquals("01hello234", resultFor("01234", 2, "hello")) + assertEquals("01foobar234", resultFor("01234", 2, charSequence("foobar"))) - def initBuilder(str: String): java.lang.StringBuilder = - new java.lang.StringBuilder(str) + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("1234", -1, "foo")) + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("1234", 6, "foo")) + } - @Test def append(): Unit = { - assertEquals("asdf", newBuilder.append("asdf").toString) - assertEquals("null", newBuilder.append(null: AnyRef).toString) - assertEquals("null", newBuilder.append(null: String).toString) - assertEquals("nu", newBuilder.append(null: CharSequence,0,2).toString) - assertEquals("true", newBuilder.append(true).toString) - assertEquals("a", newBuilder.append('a').toString) - assertEquals("abcd", newBuilder.append(Array('a','b','c','d')).toString) - assertEquals("bc", newBuilder.append(Array('a','b','c','d'), 1, 2).toString) - assertEquals("4", newBuilder.append(4.toByte).toString) - assertEquals("304", newBuilder.append(304.toShort).toString) - assertEquals("100000", newBuilder.append(100000).toString) - assertEquals("2.5", newBuilder.append(2.5f).toString) - assertEquals("3.5", newBuilder.append(3.5).toString) + @Test def insertCharSequenceStartEnd(): Unit = { + def resultFor(input: String, index: Int, x: CharSequence, start: Int, + end: Int): String = { + initBuffer(input).insert(index, x, start, end).toString() + } + + assertEquals("01ul234", resultFor("01234", 2, null, 1, 3)) + assertEquals("01ello234", resultFor("01234", 2, "hello", 1, 5)) + assertEquals("01ba234", resultFor("01234", 2, charSequence("foobar"), 3, 5)) + + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("1234", -1, charSequence("foobar"), 1, 3)) + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("1234", 6, charSequence("foobar"), 1, 3)) + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("1234", 1, charSequence("foobar"), -1, 3)) + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("1234", 1, charSequence("foobar"), 2, -1)) + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("1234", 1, charSequence("foobar"), 3, 1)) + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("1234", 1, charSequence("foobar"), 7, 8)) + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("1234", 1, charSequence("foobar"), 2, 8)) } - @Test def insert(): Unit = { - assertEquals("asdf", newBuilder.insert(0, "asdf").toString) - assertEquals("null", newBuilder.insert(0, null: AnyRef).toString) - assertEquals("null", newBuilder.insert(0, null: String).toString) - assertEquals("nu", newBuilder.insert(0, null: CharSequence,0,2).toString) - assertEquals("true", newBuilder.insert(0, true).toString) - assertEquals("a", newBuilder.insert(0, 'a').toString) - assertEquals("abcd", newBuilder.insert(0, Array('a','b','c','d')).toString) - assertEquals("bc", newBuilder.insert(0, Array('a','b','c','d'), 1, 2).toString) - assertEquals("4", newBuilder.insert(0, 4.toByte).toString) - assertEquals("304", newBuilder.insert(0, 304.toShort).toString) - assertEquals("100000", newBuilder.insert(0, 100000).toString) - assertEquals("2.5", newBuilder.insert(0, 2.5f).toString) - assertEquals("3.5", newBuilder.insert(0, 3.5).toString) + @Test def insertPrimitive(): Unit = { + assertEquals("atruebcd", initBuffer("abcd").insert(1, true).toString) + assertEquals("axbcd", initBuffer("abcd").insert(1, 'x').toString) + assertEquals("a100000bcd", initBuffer("abcd").insert(1, 100000).toString) + assertEquals("a12345678910bcd", + initBuffer("abcd").insert(1, 12345678910L).toString) + assertEquals("a2.5bcd", initBuffer("abcd").insert(1, 2.5f).toString) + assertEquals("a3.5bcd", initBuffer("abcd").insert(1, 3.5).toString) - assertEquals("abcdef", initBuilder("adef").insert(1, "bc").toString) - assertEquals("abcdef", initBuilder("abcd").insert(4, "ef").toString) - assertEquals("abcdef", initBuilder("adef").insert(1, Array('b','c')).toString) - assertEquals("abcdef", initBuilder("adef").insert(1, initBuilder("bc")).toString) - assertEquals("abcdef", initBuilder("abef").insert(2, Array('a','b','c','d','e'), 2, 2).toString) - assertEquals("abcdef", initBuilder("abef").insert(2, initBuilder("abcde"), 2, 4).toString) + // There is no overload for Byte nor Short; these call the Int version + assertEquals("a4bcd", initBuffer("abcd").insert(1, 4.toByte).toString) + assertEquals("a304bcd", initBuffer("abcd").insert(1, 304.toShort).toString) expectThrows(classOf[StringIndexOutOfBoundsException], - initBuilder("abcd").insert(5, "whatever")) + initBuffer("abcd").insert(5, 56)) expectThrows(classOf[StringIndexOutOfBoundsException], - initBuilder("abcd").insert(-1, "whatever")) + initBuffer("abcd").insert(-1, 56)) } - @Test def should_allow_string_interpolation_to_survive_null_and_undefined(): Unit = { - assertEquals("null", s"${null}") + @Test def indexOfString(): Unit = { + def resultFor(input: String, str: String): Int = + initBuffer(input).indexOf(str) + + assertEquals(2, resultFor("ababcdeabcf", "abc")) + assertEquals(-1, resultFor("ababcdeabcf", "acb")) } - @Test def deleteCharAt(): Unit = { - assertEquals("023", initBuilder("0123").deleteCharAt(1).toString) - assertEquals("123", initBuilder("0123").deleteCharAt(0).toString) - assertEquals("012", initBuilder("0123").deleteCharAt(3).toString) - expectThrows(classOf[StringIndexOutOfBoundsException], - initBuilder("0123").deleteCharAt(-1)) - expectThrows(classOf[StringIndexOutOfBoundsException], - initBuilder("0123").deleteCharAt(4)) + @Test def indexOfStringInt(): Unit = { + def resultFor(input: String, str: String, fromIndex: Int): Int = + initBuffer(input).indexOf(str, fromIndex) + + assertEquals(7, resultFor("ababcdeabcf", "abc", 4)) + assertEquals(2, resultFor("ababcdeabcf", "abc", 2)) + assertEquals(2, resultFor("ababcdeabcf", "abc", -5)) + assertEquals(-1, resultFor("ababcdeabcf", "abc", 10)) + assertEquals(-1, resultFor("ababcdeabcf", "abc", 20)) + assertEquals(-1, resultFor("ababcdeabcf", "acb", 2)) } - @Test def replace(): Unit = { - assertEquals("0bc3", initBuilder("0123").replace(1,3,"bc").toString) - assertEquals("abcd", initBuilder("0123").replace(0,4,"abcd").toString) - assertEquals("abcd", initBuilder("0123").replace(0,10,"abcd").toString) - assertEquals("012defg", initBuilder("0123").replace(3,10,"defg").toString) - assertEquals("xxxx123", initBuilder("0123").replace(0,1,"xxxx").toString) - assertEquals("0xxxx123", initBuilder("0123").replace(1,1,"xxxx").toString) - assertEquals("0123x", initBuilder("0123").replace(4, 5, "x").toString) + @Test def lastIndexOfString(): Unit = { + def resultFor(input: String, str: String): Int = + initBuffer(input).lastIndexOf(str) - expectThrows(classOf[StringIndexOutOfBoundsException], - initBuilder("0123").replace(-1,3,"x")) + assertEquals(7, resultFor("ababcdeabcf", "abc")) + assertEquals(-1, resultFor("ababcdeabcf", "acb")) } - @Test def setCharAt(): Unit = { - val b = newBuilder - b.append("foobar") + @Test def lastIndexOfStringInt(): Unit = { + def resultFor(input: String, str: String, fromIndex: Int): Int = + initBuffer(input).lastIndexOf(str, fromIndex) + + assertEquals(2, resultFor("ababcdeabcf", "abc", 2)) + assertEquals(2, resultFor("ababcdeabcf", "abc", 6)) + assertEquals(7, resultFor("ababcdeabcf", "abc", 8)) + assertEquals(7, resultFor("ababcdeabcf", "abc", 20)) + assertEquals(-1, resultFor("ababcdeabcf", "abc", 1)) + assertEquals(-1, resultFor("ababcdeabcf", "abc", -5)) + assertEquals(-1, resultFor("ababcdeabcf", "acb", 10)) + } - b.setCharAt(2, 'x') - assertEquals("foxbar", b.toString) + @Test def reverse(): Unit = { + def resultFor(input: String): String = + initBuffer(input).reverse().toString() - b.setCharAt(5, 'h') - assertEquals("foxbah", b.toString) + assertEquals("987654321", resultFor("123456789")) + assertEquals("dc\ud801\udc02ba", resultFor("ab\ud801\udc02cd")) + assertEquals("dc\ud802\ud801ba", resultFor("ab\ud801\ud802cd")) + assertEquals("dc\udc02\udc01ba", resultFor("ab\udc01\udc02cd")) + assertEquals("\ud801ba", resultFor("ab\ud801")) + assertEquals("dc\udc02", resultFor("\udc02cd")) + } - expectThrows(classOf[StringIndexOutOfBoundsException], - b.setCharAt(-1, 'h')) - expectThrows(classOf[StringIndexOutOfBoundsException], - b.setCharAt(6, 'h')) + @Test def length(): Unit = { + assertEquals(5, initBuffer("hello").length()) + assertEquals(6, initBuffer("ab\ud801\udc02cd").length()) + } + + @Test def capacity(): Unit = { + assertTrue(initBuffer("hello").capacity() >= 5) + assertTrue(initBuffer("ab\ud801\udc02cd").capacity() >= 6) } @Test def ensureCapacity(): Unit = { - // test that ensureCapacity is linking - newBuilder.ensureCapacity(10) + // Just make sure it links + newBuffer.ensureCapacity(10) + } + + @Test def trimToSize(): Unit = { + // Just make sure it links + initBuffer("hello").trimToSize() } - @Test def should_properly_setLength(): Unit = { - val b = newBuilder - b.append("foobar") + @Test def setLength(): Unit = { + val b = initBuffer("foobar") expectThrows(classOf[StringIndexOutOfBoundsException], b.setLength(-3)) - assertEquals("foo", { b.setLength(3); b.toString }) - assertEquals("foo\u0000\u0000\u0000", { b.setLength(6); b.toString }) + b.setLength(3) + assertEquals("foo", b.toString) + b.setLength(6) + assertEquals("foo\u0000\u0000\u0000", b.toString) } - @Test def appendCodePoint(): Unit = { - val b = newBuilder - b.appendCodePoint(0x61) - assertEquals("a", b.toString) - b.appendCodePoint(0x10000) - assertEquals("a\uD800\uDC00", b.toString) - b.append("fixture") - b.appendCodePoint(0x00010FFFF) - assertEquals("a\uD800\uDC00fixture\uDBFF\uDFFF", b.toString) + @Test def charAt(): Unit = { + def resultFor(input: String, index: Int): Char = + initBuffer(input).charAt(index) + + assertEquals('e', resultFor("hello", 1)) + assertEquals('\ud801', resultFor("ab\ud801\udc02cd", 2)) + assertEquals('\udc02', resultFor("ab\ud801\udc02cd", 3)) + + if (executingInJVM) { + expectThrows(classOf[IndexOutOfBoundsException], resultFor("hello", -1)) + expectThrows(classOf[IndexOutOfBoundsException], resultFor("hello", 5)) + expectThrows(classOf[IndexOutOfBoundsException], resultFor("hello", 6)) + } + } + + @Test def codePointAt(): Unit = { + def resultFor(input: String, index: Int): Int = + initBuffer(input).codePointAt(index) + + assertEquals(0x61, resultFor("abc\ud834\udf06def", 0)) + assertEquals(0x1d306, resultFor("abc\ud834\udf06def", 3)) + assertEquals(0xdf06, resultFor("abc\ud834\udf06def", 4)) + assertEquals(0x64, resultFor("abc\ud834\udf06def", 5)) + assertEquals(0x1d306, resultFor("\ud834\udf06def", 0)) + assertEquals(0xdf06, resultFor("\ud834\udf06def", 1)) + assertEquals(0xd834, resultFor("\ud834abc", 0)) + assertEquals(0xdf06, resultFor("\udf06abc", 0)) + assertEquals(0xd834, resultFor("abc\ud834", 3)) + + if (executingInJVM) { + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("abc\ud834\udf06def", -1)) + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("abc\ud834\udf06def", 15)) + } + } + + @Test def codePointBefore(): Unit = { + def resultFor(input: String, index: Int): Int = + initBuffer(input).codePointBefore(index) + + assertEquals(0x61, resultFor("abc\ud834\udf06def", 1)) + assertEquals(0x1d306, resultFor("abc\ud834\udf06def", 5)) + assertEquals(0xd834, resultFor("abc\ud834\udf06def", 4)) + assertEquals(0x64, resultFor("abc\ud834\udf06def", 6)) + assertEquals(0x1d306, resultFor("\ud834\udf06def", 2)) + assertEquals(0xd834, resultFor("\ud834\udf06def", 1)) + assertEquals(0xd834, resultFor("\ud834abc", 1)) + assertEquals(0xdf06, resultFor("\udf06abc", 1)) + + if (executingInJVM) { + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("abc\ud834\udf06def", 0)) + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("abc\ud834\udf06def", 15)) + } + } + + @Test def codePointCount(): Unit = { + val sb = initBuffer( + "abc\uD834\uDF06de\uD834\uDF06fgh\uD834ij\uDF06\uD834kl\uDF06") + + assertEquals(18, sb.codePointCount(0, sb.length)) + assertEquals(1, sb.codePointCount(3, 5)) + assertEquals(1, sb.codePointCount(2, 3)) + assertEquals(2, sb.codePointCount(2, 4)) + assertEquals(2, sb.codePointCount(2, 5)) + assertEquals(3, sb.codePointCount(2, 6)) + assertEquals(5, sb.codePointCount(12, 17)) + assertEquals(2, sb.codePointCount(8, 10)) + assertEquals(2, sb.codePointCount(7, 10)) + assertEquals(0, sb.codePointCount(7, 7)) + assertEquals(1, sb.codePointCount(sb.length - 1, sb.length)) + assertEquals(0, sb.codePointCount(sb.length - 1, sb.length - 1)) + assertEquals(0, sb.codePointCount(sb.length, sb.length)) + + expectThrows(classOf[IndexOutOfBoundsException], sb.codePointCount(-3, 4)) + expectThrows(classOf[IndexOutOfBoundsException], sb.codePointCount(6, 2)) + expectThrows(classOf[IndexOutOfBoundsException], sb.codePointCount(10, 30)) + } + + @Test def offsetByCodePoints(): Unit = { + val sb = initBuffer( + "abc\uD834\uDF06de\uD834\uDF06fgh\uD834ij\uDF06\uD834kl\uDF06") + + assertEquals(sb.length, sb.offsetByCodePoints(0, 18)) + assertEquals(5, sb.offsetByCodePoints(3, 1)) + assertEquals(3, sb.offsetByCodePoints(2, 1)) + assertEquals(5, sb.offsetByCodePoints(2, 2)) + assertEquals(6, sb.offsetByCodePoints(2, 3)) + assertEquals(17, sb.offsetByCodePoints(12, 5)) + assertEquals(10, sb.offsetByCodePoints(8, 2)) + assertEquals(10, sb.offsetByCodePoints(7, 2)) + assertEquals(7, sb.offsetByCodePoints(7, 0)) + assertEquals(sb.length, sb.offsetByCodePoints(sb.length - 1, 1)) + assertEquals(sb.length - 1, sb.offsetByCodePoints(sb.length - 1, 0)) + assertEquals(sb.length, sb.offsetByCodePoints(sb.length, 0)) + + expectThrows(classOf[IndexOutOfBoundsException], sb.offsetByCodePoints(-3, 4)) + expectThrows(classOf[IndexOutOfBoundsException], sb.offsetByCodePoints(6, 18)) + expectThrows(classOf[IndexOutOfBoundsException], sb.offsetByCodePoints(30, 2)) + } + + @Test def offsetByCodePointsBackwards(): Unit = { + val sb = initBuffer( + "abc\uD834\uDF06de\uD834\uDF06fgh\uD834ij\uDF06\uD834kl\uDF06") + + assertEquals(0, sb.offsetByCodePoints(sb.length, -18)) + assertEquals(3, sb.offsetByCodePoints(5, -1)) + assertEquals(2, sb.offsetByCodePoints(3, -1)) + assertEquals(2, sb.offsetByCodePoints(4, -2)) + assertEquals(2, sb.offsetByCodePoints(5, -2)) + assertEquals(2, sb.offsetByCodePoints(6, -3)) + assertEquals(12, sb.offsetByCodePoints(17, -5)) + assertEquals(7, sb.offsetByCodePoints(10, -2)) + assertEquals(7, sb.offsetByCodePoints(7, -0)) + assertEquals(sb.length - 1, sb.offsetByCodePoints(sb.length, -1)) + assertEquals(sb.length - 1, sb.offsetByCodePoints(sb.length - 1, -0)) + assertEquals(sb.length, sb.offsetByCodePoints(sb.length, -0)) + + expectThrows(classOf[IndexOutOfBoundsException], sb.offsetByCodePoints(-3, 4)) + expectThrows(classOf[IndexOutOfBoundsException], sb.offsetByCodePoints(6, 18)) + expectThrows(classOf[IndexOutOfBoundsException], sb.offsetByCodePoints(30, 2)) + } + + @Test def getChars(): Unit = { + val dst = new Array[Char](10) + initBuffer("asdf_foo").getChars(2, 6, dst, 3) + assertArrayEquals(Array[Char](0, 0, 0, 'd', 'f', '_', 'f', 0, 0, 0), dst) + } + + @Test def setCharAt(): Unit = { + def resultFor(input: String, index: Int, ch: Char): String = { + val sb = initBuffer(input) + sb.setCharAt(index, ch) + sb.toString() + } + + assertEquals("foxbar", resultFor("foobar", 2, 'x')) + assertEquals("foobah", resultFor("foobar", 5, 'h')) + + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("foobar", -1, 'h')) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("foobar", 6, 'h')) + } + + @Test def substringStart(): Unit = { + def resultFor(input: String, start: Int): String = + initBuffer(input).substring(start) + + assertEquals("llo", resultFor("hello", 2)) + assertEquals("", resultFor("hello", 5)) + + if (executingInJVM) { + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("hello", -1)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("hello", 8)) + } + } + + @Test def subSequence(): Unit = { + def resultFor(input: String, start: Int, end: Int): CharSequence = + initBuffer(input).subSequence(start, end) + + /* Note that the spec of subSequence says that it behaves exactly like + * substring. Therefore, the returned CharSequence must necessarily be a + * String. + */ + assertEquals("ll", resultFor("hello", 2, 4)) + assertEquals("", resultFor("hello", 5, 5)) + assertEquals("hel", resultFor("hello", 0, 3)) + + if (executingInJVM) { + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("hello", -1, 3)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("hello", 8, 8)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("hello", 3, 2)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("hello", 3, 8)) + } + } + + @Test def substringStartEnd(): Unit = { + def resultFor(input: String, start: Int, end: Int): String = + initBuffer(input).substring(start, end) + + assertEquals("ll", resultFor("hello", 2, 4)) + assertEquals("", resultFor("hello", 5, 5)) + assertEquals("hel", resultFor("hello", 0, 3)) + + if (executingInJVM) { + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("hello", -1, 3)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("hello", 8, 8)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("hello", 3, 2)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("hello", 3, 8)) + } } } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringBuilderTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringBuilderTest.scala new file mode 100644 index 0000000000..e290847825 --- /dev/null +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringBuilderTest.scala @@ -0,0 +1,643 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.javalib.lang + +import java.lang.StringBuilder + +import org.junit.Test +import org.junit.Assert._ + +import org.scalajs.testsuite.utils.AssertThrows._ +import org.scalajs.testsuite.utils.Platform.executingInJVM + +import WrappedStringCharSequence.charSequence + +/* !!! This test class is basically copy-pasted in StringBufferTest. + * Make sure to always update them in sync. + */ +class StringBuilderTest { + + private def newBuilder: StringBuilder = + new StringBuilder + + private def initBuilder(str: String): StringBuilder = + new StringBuilder(str) + + @Test def init(): Unit = { + assertEquals("", new StringBuilder().toString()) + } + + @Test def initInt(): Unit = { + assertEquals("", new StringBuilder(5).toString()) + } + + @Test def initString(): Unit = { + assertEquals("hello", new StringBuilder("hello").toString()) + + if (executingInJVM) { + expectThrows(classOf[NullPointerException], + new StringBuilder(null: String)) + } + } + + @Test def initCharSequence(): Unit = { + assertEquals("hello", new StringBuilder(charSequence("hello")).toString()) + + if (executingInJVM) { + expectThrows(classOf[NullPointerException], + new StringBuilder(null: CharSequence)) + } + } + + @Test def appendAnyRef(): Unit = { + def resultFor(x: AnyRef): String = newBuilder.append(x).toString() + + assertEquals("null", resultFor(null)) + assertEquals("None", resultFor(None)) + assertEquals("hello", resultFor("hello")) + assertEquals("foobar", resultFor(charSequence("foobar"))) + } + + @Test def appendString(): Unit = { + def resultFor(x: String): String = newBuilder.append(x).toString() + + assertEquals("null", resultFor(null)) + assertEquals("hello", resultFor("hello")) + } + + @Test def appendStringBuffer(): Unit = { + def resultFor(x: StringBuffer): String = newBuilder.append(x).toString() + + assertEquals("null", resultFor(null)) + assertEquals("", resultFor(new StringBuffer())) + assertEquals("hello", resultFor(new StringBuffer("hello"))) + } + + @Test def appendCharSequence(): Unit = { + def resultFor(x: CharSequence): String = newBuilder.append(x).toString() + + assertEquals("null", resultFor(null)) + assertEquals("hello", resultFor("hello")) + assertEquals("", resultFor(charSequence(""))) + assertEquals("foobar", resultFor(charSequence("foobar"))) + } + + @Test def appendCharSequenceStartEnd(): Unit = { + def resultFor(x: CharSequence, start: Int, end: Int): String = + newBuilder.append(x, start, end).toString() + + assertEquals("ul", resultFor(null, 1, 3)) + assertEquals("null", resultFor(null, 0, 4)) + assertEquals("ello", resultFor("hello", 1, 5)) + assertEquals("ob", resultFor(charSequence("foobar"), 2, 4)) + + expectThrows(classOf[IndexOutOfBoundsException], + resultFor(charSequence("he"), 1, 3)) + expectThrows(classOf[IndexOutOfBoundsException], + resultFor(charSequence("he"), -1, 2)) + expectThrows(classOf[IndexOutOfBoundsException], + resultFor(charSequence("he"), 2, 1)) + } + + @Test def appendCharArray(): Unit = { + def resultFor(x: Array[Char]): String = newBuilder.append(x).toString() + + assertEquals("hello", resultFor(Array('h', 'e', 'l', 'l', 'o'))) + + if (executingInJVM) + expectThrows(classOf[NullPointerException], resultFor(null)) + } + + @Test def appendCharArrayOffsetLen(): Unit = { + def resultFor(x: Array[Char], offset: Int, len: Int): String = + newBuilder.append(x, offset, len).toString() + + val arr = Array('h', 'e', 'l', 'l', 'o') + assertEquals("hello", resultFor(arr, 0, 5)) + assertEquals("ell", resultFor(arr, 1, 3)) + + if (executingInJVM) + expectThrows(classOf[NullPointerException], resultFor(null, 0, 0)) + + expectThrows(classOf[IndexOutOfBoundsException], resultFor(arr, -1, 2)) + expectThrows(classOf[IndexOutOfBoundsException], resultFor(arr, 3, 3)) + expectThrows(classOf[IndexOutOfBoundsException], resultFor(arr, 3, -2)) + } + + @Test def appendPrimitive(): Unit = { + assertEquals("true", newBuilder.append(true).toString) + assertEquals("a", newBuilder.append('a').toString) + assertEquals("100000", newBuilder.append(100000).toString) + assertEquals("12345678910", newBuilder.append(12345678910L).toString) + assertEquals("2.5", newBuilder.append(2.5f).toString) + assertEquals("3.5", newBuilder.append(3.5).toString) + + // There is no overload for Byte nor Short; these call the Int version + assertEquals("4", newBuilder.append(4.toByte).toString) + assertEquals("304", newBuilder.append(304.toShort).toString) + } + + @Test def appendCodePoint(): Unit = { + def resultFor(codePoint: Int): String = + newBuilder.appendCodePoint(codePoint).toString() + + assertEquals("a", resultFor(0x61)) + assertEquals("\ud800\udc00", resultFor(0x10000)) + assertEquals("\ud800\udc01", resultFor(0x10001)) + assertEquals("\ud801\udc01", resultFor(0x10401)) + assertEquals("\udbff\udfff", resultFor(0x10ffff)) + + expectThrows(classOf[IllegalArgumentException], resultFor(0x111111)) + expectThrows(classOf[IllegalArgumentException], resultFor(-1)) + } + + @Test def delete(): Unit = { + def resultFor(input: String, start: Int, end: Int): String = + initBuilder(input).delete(start, end).toString() + + assertEquals("heo", resultFor("hello", 2, 4)) + assertEquals("foo\ud800r", resultFor("foo\ud800\udc00bar", 4, 7)) + assertEquals("hello", resultFor("hello", 0, 0)) + assertEquals("hello", resultFor("hello", 5, 5)) + assertEquals("hel", resultFor("hello", 3, 8)) + + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("hello", -1, 2)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("hello", 3, 2)) + } + + @Test def deleteCharAt(): Unit = { + def resultFor(input: String, index: Int): String = + initBuilder(input).deleteCharAt(index).toString() + + assertEquals("023", resultFor("0123", 1)) + assertEquals("123", resultFor("0123", 0)) + assertEquals("012", resultFor("0123", 3)) + + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("0123", -1)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("0123", 4)) + } + + @Test def replace(): Unit = { + def resultFor(input: String, start: Int, end: Int, str: String): String = + initBuilder(input).replace(start, end, str).toString() + + assertEquals("0bc3", resultFor("0123", 1, 3, "bc")) + assertEquals("abcd", resultFor("0123", 0, 4, "abcd")) + assertEquals("abcd", resultFor("0123", 0, 10, "abcd")) + assertEquals("012defg", resultFor("0123", 3, 10, "defg")) + assertEquals("xxxx123", resultFor("0123", 0, 1, "xxxx")) + assertEquals("0xxxx123", resultFor("0123", 1, 1, "xxxx")) + assertEquals("0123x", resultFor("0123", 4, 5, "x")) + + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("0123", -1, 3, "x")) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("0123", 4, 3, "x")) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("0123", 5, 8, "x")) + + if (executingInJVM) + expectThrows(classOf[NullPointerException], resultFor("0123", 1, 3, null)) + } + + @Test def insertCharArrayOffsetLen(): Unit = { + def resultFor(input: String, index: Int, str: Array[Char], offset: Int, + len: Int): String = { + initBuilder(input).insert(index, str, offset, len).toString() + } + + val arr = Array('a', 'b', 'c', 'd', 'e') + + assertEquals("0bc12", resultFor("012", 1, arr, 1, 2)) + assertEquals("abcdef", resultFor("abef", 2, arr, 2, 2)) + + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("1234", -1, arr, 1, 2)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("1234", 6, arr, 1, 2)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("1234", 1, arr, -1, 2)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("1234", 1, arr, 1, -2)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("1234", 1, arr, 4, 3)) + + if (executingInJVM) { + expectThrows(classOf[NullPointerException], + resultFor("1234", 1, null, 0, 0)) + } + } + + @Test def insertAnyRef(): Unit = { + def resultFor(input: String, index: Int, x: AnyRef): String = + initBuilder(input).insert(index, x).toString() + + assertEquals("01null234", resultFor("01234", 2, null)) + assertEquals("01None234", resultFor("01234", 2, None)) + assertEquals("01hello234", resultFor("01234", 2, "hello")) + assertEquals("01foobar234", resultFor("01234", 2, charSequence("foobar"))) + + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("1234", -1, "foo")) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("1234", 6, "foo")) + } + + @Test def insertString(): Unit = { + def resultFor(input: String, index: Int, x: String): String = + initBuilder(input).insert(index, x).toString() + + assertEquals("01null234", resultFor("01234", 2, null)) + assertEquals("01hello234", resultFor("01234", 2, "hello")) + + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("1234", -1, "foo")) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("1234", 6, "foo")) + } + + @Test def insertCharArray(): Unit = { + def resultFor(input: String, index: Int, str: Array[Char]): String = + initBuilder(input).insert(index, str).toString() + + val arr = Array('a', 'b', 'c', 'd', 'e') + + assertEquals("0abcde12", resultFor("012", 1, arr)) + assertEquals("ababcdeef", resultFor("abef", 2, arr)) + + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("1234", -1, arr)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("1234", 6, arr)) + + if (executingInJVM) + expectThrows(classOf[NullPointerException], resultFor("1234", 1, null)) + } + + @Test def insertCharSequence(): Unit = { + def resultFor(input: String, index: Int, x: CharSequence): String = + initBuilder(input).insert(index, x).toString() + + assertEquals("01null234", resultFor("01234", 2, null)) + assertEquals("01hello234", resultFor("01234", 2, "hello")) + assertEquals("01foobar234", resultFor("01234", 2, charSequence("foobar"))) + + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("1234", -1, "foo")) + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("1234", 6, "foo")) + } + + @Test def insertCharSequenceStartEnd(): Unit = { + def resultFor(input: String, index: Int, x: CharSequence, start: Int, + end: Int): String = { + initBuilder(input).insert(index, x, start, end).toString() + } + + assertEquals("01ul234", resultFor("01234", 2, null, 1, 3)) + assertEquals("01ello234", resultFor("01234", 2, "hello", 1, 5)) + assertEquals("01ba234", resultFor("01234", 2, charSequence("foobar"), 3, 5)) + + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("1234", -1, charSequence("foobar"), 1, 3)) + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("1234", 6, charSequence("foobar"), 1, 3)) + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("1234", 1, charSequence("foobar"), -1, 3)) + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("1234", 1, charSequence("foobar"), 2, -1)) + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("1234", 1, charSequence("foobar"), 3, 1)) + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("1234", 1, charSequence("foobar"), 7, 8)) + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("1234", 1, charSequence("foobar"), 2, 8)) + } + + @Test def insertPrimitive(): Unit = { + assertEquals("atruebcd", initBuilder("abcd").insert(1, true).toString) + assertEquals("axbcd", initBuilder("abcd").insert(1, 'x').toString) + assertEquals("a100000bcd", initBuilder("abcd").insert(1, 100000).toString) + assertEquals("a12345678910bcd", + initBuilder("abcd").insert(1, 12345678910L).toString) + assertEquals("a2.5bcd", initBuilder("abcd").insert(1, 2.5f).toString) + assertEquals("a3.5bcd", initBuilder("abcd").insert(1, 3.5).toString) + + // There is no overload for Byte nor Short; these call the Int version + assertEquals("a4bcd", initBuilder("abcd").insert(1, 4.toByte).toString) + assertEquals("a304bcd", initBuilder("abcd").insert(1, 304.toShort).toString) + + expectThrows(classOf[StringIndexOutOfBoundsException], + initBuilder("abcd").insert(5, 56)) + expectThrows(classOf[StringIndexOutOfBoundsException], + initBuilder("abcd").insert(-1, 56)) + } + + @Test def indexOfString(): Unit = { + def resultFor(input: String, str: String): Int = + initBuilder(input).indexOf(str) + + assertEquals(2, resultFor("ababcdeabcf", "abc")) + assertEquals(-1, resultFor("ababcdeabcf", "acb")) + } + + @Test def indexOfStringInt(): Unit = { + def resultFor(input: String, str: String, fromIndex: Int): Int = + initBuilder(input).indexOf(str, fromIndex) + + assertEquals(7, resultFor("ababcdeabcf", "abc", 4)) + assertEquals(2, resultFor("ababcdeabcf", "abc", 2)) + assertEquals(2, resultFor("ababcdeabcf", "abc", -5)) + assertEquals(-1, resultFor("ababcdeabcf", "abc", 10)) + assertEquals(-1, resultFor("ababcdeabcf", "abc", 20)) + assertEquals(-1, resultFor("ababcdeabcf", "acb", 2)) + } + + @Test def lastIndexOfString(): Unit = { + def resultFor(input: String, str: String): Int = + initBuilder(input).lastIndexOf(str) + + assertEquals(7, resultFor("ababcdeabcf", "abc")) + assertEquals(-1, resultFor("ababcdeabcf", "acb")) + } + + @Test def lastIndexOfStringInt(): Unit = { + def resultFor(input: String, str: String, fromIndex: Int): Int = + initBuilder(input).lastIndexOf(str, fromIndex) + + assertEquals(2, resultFor("ababcdeabcf", "abc", 2)) + assertEquals(2, resultFor("ababcdeabcf", "abc", 6)) + assertEquals(7, resultFor("ababcdeabcf", "abc", 8)) + assertEquals(7, resultFor("ababcdeabcf", "abc", 20)) + assertEquals(-1, resultFor("ababcdeabcf", "abc", 1)) + assertEquals(-1, resultFor("ababcdeabcf", "abc", -5)) + assertEquals(-1, resultFor("ababcdeabcf", "acb", 10)) + } + + @Test def reverse(): Unit = { + def resultFor(input: String): String = + initBuilder(input).reverse().toString() + + assertEquals("987654321", resultFor("123456789")) + assertEquals("dc\ud801\udc02ba", resultFor("ab\ud801\udc02cd")) + assertEquals("dc\ud802\ud801ba", resultFor("ab\ud801\ud802cd")) + assertEquals("dc\udc02\udc01ba", resultFor("ab\udc01\udc02cd")) + assertEquals("\ud801ba", resultFor("ab\ud801")) + assertEquals("dc\udc02", resultFor("\udc02cd")) + } + + @Test def length(): Unit = { + assertEquals(5, initBuilder("hello").length()) + assertEquals(6, initBuilder("ab\ud801\udc02cd").length()) + } + + @Test def capacity(): Unit = { + assertTrue(initBuilder("hello").capacity() >= 5) + assertTrue(initBuilder("ab\ud801\udc02cd").capacity() >= 6) + } + + @Test def ensureCapacity(): Unit = { + // Just make sure it links + newBuilder.ensureCapacity(10) + } + + @Test def trimToSize(): Unit = { + // Just make sure it links + initBuilder("hello").trimToSize() + } + + @Test def setLength(): Unit = { + val b = initBuilder("foobar") + + expectThrows(classOf[StringIndexOutOfBoundsException], b.setLength(-3)) + + b.setLength(3) + assertEquals("foo", b.toString) + b.setLength(6) + assertEquals("foo\u0000\u0000\u0000", b.toString) + } + + @Test def charAt(): Unit = { + def resultFor(input: String, index: Int): Char = + initBuilder(input).charAt(index) + + assertEquals('e', resultFor("hello", 1)) + assertEquals('\ud801', resultFor("ab\ud801\udc02cd", 2)) + assertEquals('\udc02', resultFor("ab\ud801\udc02cd", 3)) + + if (executingInJVM) { + expectThrows(classOf[IndexOutOfBoundsException], resultFor("hello", -1)) + expectThrows(classOf[IndexOutOfBoundsException], resultFor("hello", 5)) + expectThrows(classOf[IndexOutOfBoundsException], resultFor("hello", 6)) + } + } + + @Test def codePointAt(): Unit = { + def resultFor(input: String, index: Int): Int = + initBuilder(input).codePointAt(index) + + assertEquals(0x61, resultFor("abc\ud834\udf06def", 0)) + assertEquals(0x1d306, resultFor("abc\ud834\udf06def", 3)) + assertEquals(0xdf06, resultFor("abc\ud834\udf06def", 4)) + assertEquals(0x64, resultFor("abc\ud834\udf06def", 5)) + assertEquals(0x1d306, resultFor("\ud834\udf06def", 0)) + assertEquals(0xdf06, resultFor("\ud834\udf06def", 1)) + assertEquals(0xd834, resultFor("\ud834abc", 0)) + assertEquals(0xdf06, resultFor("\udf06abc", 0)) + assertEquals(0xd834, resultFor("abc\ud834", 3)) + + if (executingInJVM) { + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("abc\ud834\udf06def", -1)) + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("abc\ud834\udf06def", 15)) + } + } + + @Test def codePointBefore(): Unit = { + def resultFor(input: String, index: Int): Int = + initBuilder(input).codePointBefore(index) + + assertEquals(0x61, resultFor("abc\ud834\udf06def", 1)) + assertEquals(0x1d306, resultFor("abc\ud834\udf06def", 5)) + assertEquals(0xd834, resultFor("abc\ud834\udf06def", 4)) + assertEquals(0x64, resultFor("abc\ud834\udf06def", 6)) + assertEquals(0x1d306, resultFor("\ud834\udf06def", 2)) + assertEquals(0xd834, resultFor("\ud834\udf06def", 1)) + assertEquals(0xd834, resultFor("\ud834abc", 1)) + assertEquals(0xdf06, resultFor("\udf06abc", 1)) + + if (executingInJVM) { + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("abc\ud834\udf06def", 0)) + expectThrows(classOf[IndexOutOfBoundsException], + resultFor("abc\ud834\udf06def", 15)) + } + } + + @Test def codePointCount(): Unit = { + val sb = initBuilder( + "abc\uD834\uDF06de\uD834\uDF06fgh\uD834ij\uDF06\uD834kl\uDF06") + + assertEquals(18, sb.codePointCount(0, sb.length)) + assertEquals(1, sb.codePointCount(3, 5)) + assertEquals(1, sb.codePointCount(2, 3)) + assertEquals(2, sb.codePointCount(2, 4)) + assertEquals(2, sb.codePointCount(2, 5)) + assertEquals(3, sb.codePointCount(2, 6)) + assertEquals(5, sb.codePointCount(12, 17)) + assertEquals(2, sb.codePointCount(8, 10)) + assertEquals(2, sb.codePointCount(7, 10)) + assertEquals(0, sb.codePointCount(7, 7)) + assertEquals(1, sb.codePointCount(sb.length - 1, sb.length)) + assertEquals(0, sb.codePointCount(sb.length - 1, sb.length - 1)) + assertEquals(0, sb.codePointCount(sb.length, sb.length)) + + expectThrows(classOf[IndexOutOfBoundsException], sb.codePointCount(-3, 4)) + expectThrows(classOf[IndexOutOfBoundsException], sb.codePointCount(6, 2)) + expectThrows(classOf[IndexOutOfBoundsException], sb.codePointCount(10, 30)) + } + + @Test def offsetByCodePoints(): Unit = { + val sb = initBuilder( + "abc\uD834\uDF06de\uD834\uDF06fgh\uD834ij\uDF06\uD834kl\uDF06") + + assertEquals(sb.length, sb.offsetByCodePoints(0, 18)) + assertEquals(5, sb.offsetByCodePoints(3, 1)) + assertEquals(3, sb.offsetByCodePoints(2, 1)) + assertEquals(5, sb.offsetByCodePoints(2, 2)) + assertEquals(6, sb.offsetByCodePoints(2, 3)) + assertEquals(17, sb.offsetByCodePoints(12, 5)) + assertEquals(10, sb.offsetByCodePoints(8, 2)) + assertEquals(10, sb.offsetByCodePoints(7, 2)) + assertEquals(7, sb.offsetByCodePoints(7, 0)) + assertEquals(sb.length, sb.offsetByCodePoints(sb.length - 1, 1)) + assertEquals(sb.length - 1, sb.offsetByCodePoints(sb.length - 1, 0)) + assertEquals(sb.length, sb.offsetByCodePoints(sb.length, 0)) + + expectThrows(classOf[IndexOutOfBoundsException], sb.offsetByCodePoints(-3, 4)) + expectThrows(classOf[IndexOutOfBoundsException], sb.offsetByCodePoints(6, 18)) + expectThrows(classOf[IndexOutOfBoundsException], sb.offsetByCodePoints(30, 2)) + } + + @Test def offsetByCodePointsBackwards(): Unit = { + val sb = initBuilder( + "abc\uD834\uDF06de\uD834\uDF06fgh\uD834ij\uDF06\uD834kl\uDF06") + + assertEquals(0, sb.offsetByCodePoints(sb.length, -18)) + assertEquals(3, sb.offsetByCodePoints(5, -1)) + assertEquals(2, sb.offsetByCodePoints(3, -1)) + assertEquals(2, sb.offsetByCodePoints(4, -2)) + assertEquals(2, sb.offsetByCodePoints(5, -2)) + assertEquals(2, sb.offsetByCodePoints(6, -3)) + assertEquals(12, sb.offsetByCodePoints(17, -5)) + assertEquals(7, sb.offsetByCodePoints(10, -2)) + assertEquals(7, sb.offsetByCodePoints(7, -0)) + assertEquals(sb.length - 1, sb.offsetByCodePoints(sb.length, -1)) + assertEquals(sb.length - 1, sb.offsetByCodePoints(sb.length - 1, -0)) + assertEquals(sb.length, sb.offsetByCodePoints(sb.length, -0)) + + expectThrows(classOf[IndexOutOfBoundsException], sb.offsetByCodePoints(-3, 4)) + expectThrows(classOf[IndexOutOfBoundsException], sb.offsetByCodePoints(6, 18)) + expectThrows(classOf[IndexOutOfBoundsException], sb.offsetByCodePoints(30, 2)) + } + + @Test def getChars(): Unit = { + val dst = new Array[Char](10) + initBuilder("asdf_foo").getChars(2, 6, dst, 3) + assertArrayEquals(Array[Char](0, 0, 0, 'd', 'f', '_', 'f', 0, 0, 0), dst) + } + + @Test def setCharAt(): Unit = { + def resultFor(input: String, index: Int, ch: Char): String = { + val sb = initBuilder(input) + sb.setCharAt(index, ch) + sb.toString() + } + + assertEquals("foxbar", resultFor("foobar", 2, 'x')) + assertEquals("foobah", resultFor("foobar", 5, 'h')) + + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("foobar", -1, 'h')) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("foobar", 6, 'h')) + } + + @Test def substringStart(): Unit = { + def resultFor(input: String, start: Int): String = + initBuilder(input).substring(start) + + assertEquals("llo", resultFor("hello", 2)) + assertEquals("", resultFor("hello", 5)) + + if (executingInJVM) { + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("hello", -1)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("hello", 8)) + } + } + + @Test def subSequence(): Unit = { + def resultFor(input: String, start: Int, end: Int): CharSequence = + initBuilder(input).subSequence(start, end) + + /* Note that the spec of subSequence says that it behaves exactly like + * substring. Therefore, the returned CharSequence must necessarily be a + * String. + */ + assertEquals("ll", resultFor("hello", 2, 4)) + assertEquals("", resultFor("hello", 5, 5)) + assertEquals("hel", resultFor("hello", 0, 3)) + + if (executingInJVM) { + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("hello", -1, 3)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("hello", 8, 8)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("hello", 3, 2)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("hello", 3, 8)) + } + } + + @Test def substringStartEnd(): Unit = { + def resultFor(input: String, start: Int, end: Int): String = + initBuilder(input).substring(start, end) + + assertEquals("ll", resultFor("hello", 2, 4)) + assertEquals("", resultFor("hello", 5, 5)) + assertEquals("hel", resultFor("hello", 0, 3)) + + if (executingInJVM) { + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("hello", -1, 3)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("hello", 8, 8)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("hello", 3, 2)) + expectThrows(classOf[StringIndexOutOfBoundsException], + resultFor("hello", 3, 8)) + } + } + + @Test def should_allow_string_interpolation_to_survive_null_and_undefined(): Unit = { + assertEquals("anullb", s"a${null}b") + + if (executingInJVM) + assertEquals("a()b", s"a${()}b") + else + assertEquals("aundefinedb", s"a${()}b") + } +} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringTest.scala index 0a59631758..b6220fd2b0 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringTest.scala @@ -140,6 +140,32 @@ class StringTest { // Lone low surrogates assertEquals(0xDF06, "\uDF06abc".codePointAt(0)) + assertEquals(0xD834, "abc\uD834".codePointAt(3)) + + if (executingInJVM) { + expectThrows(classOf[IndexOutOfBoundsException], + "abc\ud834\udf06def".codePointAt(-1)) + expectThrows(classOf[IndexOutOfBoundsException], + "abc\ud834\udf06def".codePointAt(15)) + } + } + + @Test def codePointBefore(): Unit = { + assertEquals(0x61, "abc\ud834\udf06def".codePointBefore(1)) + assertEquals(0x1d306, "abc\ud834\udf06def".codePointBefore(5)) + assertEquals(0xd834, "abc\ud834\udf06def".codePointBefore(4)) + assertEquals(0x64, "abc\ud834\udf06def".codePointBefore(6)) + assertEquals(0x1d306, "\ud834\udf06def".codePointBefore(2)) + assertEquals(0xd834, "\ud834\udf06def".codePointBefore(1)) + assertEquals(0xd834, "\ud834abc".codePointBefore(1)) + assertEquals(0xdf06, "\udf06abc".codePointBefore(1)) + + if (executingInJVM) { + expectThrows(classOf[IndexOutOfBoundsException], + "abc\ud834\udf06def".codePointBefore(0)) + expectThrows(classOf[IndexOutOfBoundsException], + "abc\ud834\udf06def".codePointBefore(15)) + } } @Test def codePointCount(): Unit = { @@ -163,6 +189,48 @@ class StringTest { expectThrows(classOf[IndexOutOfBoundsException], s.codePointCount(10, 30)) } + @Test def offsetByCodePoints(): Unit = { + val s = "abc\uD834\uDF06de\uD834\uDF06fgh\uD834ij\uDF06\uD834kl\uDF06" + + assertEquals(s.length, s.offsetByCodePoints(0, 18)) + assertEquals(5, s.offsetByCodePoints(3, 1)) + assertEquals(3, s.offsetByCodePoints(2, 1)) + assertEquals(5, s.offsetByCodePoints(2, 2)) + assertEquals(6, s.offsetByCodePoints(2, 3)) + assertEquals(17, s.offsetByCodePoints(12, 5)) + assertEquals(10, s.offsetByCodePoints(8, 2)) + assertEquals(10, s.offsetByCodePoints(7, 2)) + assertEquals(7, s.offsetByCodePoints(7, 0)) + assertEquals(s.length, s.offsetByCodePoints(s.length - 1, 1)) + assertEquals(s.length - 1, s.offsetByCodePoints(s.length - 1, 0)) + assertEquals(s.length, s.offsetByCodePoints(s.length, 0)) + + expectThrows(classOf[IndexOutOfBoundsException], s.offsetByCodePoints(-3, 4)) + expectThrows(classOf[IndexOutOfBoundsException], s.offsetByCodePoints(6, 18)) + expectThrows(classOf[IndexOutOfBoundsException], s.offsetByCodePoints(30, 2)) + } + + @Test def offsetByCodePointsBackwards(): Unit = { + val s = "abc\uD834\uDF06de\uD834\uDF06fgh\uD834ij\uDF06\uD834kl\uDF06" + + assertEquals(0, s.offsetByCodePoints(s.length, -18)) + assertEquals(3, s.offsetByCodePoints(5, -1)) + assertEquals(2, s.offsetByCodePoints(3, -1)) + assertEquals(2, s.offsetByCodePoints(4, -2)) + assertEquals(2, s.offsetByCodePoints(5, -2)) + assertEquals(2, s.offsetByCodePoints(6, -3)) + assertEquals(12, s.offsetByCodePoints(17, -5)) + assertEquals(7, s.offsetByCodePoints(10, -2)) + assertEquals(7, s.offsetByCodePoints(7, -0)) + assertEquals(s.length - 1, s.offsetByCodePoints(s.length, -1)) + assertEquals(s.length - 1, s.offsetByCodePoints(s.length - 1, -0)) + assertEquals(s.length, s.offsetByCodePoints(s.length, -0)) + + expectThrows(classOf[IndexOutOfBoundsException], s.offsetByCodePoints(-3, 4)) + expectThrows(classOf[IndexOutOfBoundsException], s.offsetByCodePoints(6, 18)) + expectThrows(classOf[IndexOutOfBoundsException], s.offsetByCodePoints(30, 2)) + } + @Test def subSequence(): Unit = { assertEquals("Scala", "Scala.js".subSequence(0, 5)) assertEquals("js", "Scala.js".subSequence(6, 8)) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/WrappedStringCharSequence.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/WrappedStringCharSequence.scala new file mode 100644 index 0000000000..068125c733 --- /dev/null +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/WrappedStringCharSequence.scala @@ -0,0 +1,30 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.javalib.lang + +object WrappedStringCharSequence { + def charSequence(content: String): CharSequence = new CharSequence { + require(content != null) + + def length(): Int = content.length() + + def charAt(index: Int): Char = { + if (index < 0 || index >= length()) + throw new StringIndexOutOfBoundsException(index) + content.charAt(index) + } + + def subSequence(start: Int, end: Int): CharSequence = { + if (start < 0 || start > end || end > length()) + throw new StringIndexOutOfBoundsException() + charSequence(content.substring(start, end)) + } + + override def toString(): String = content + } +} From e2099ee2c223012e5f5ed3e14edb856ae400d25e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 12 Sep 2017 20:29:07 +0200 Subject: [PATCH 0486/2665] Avoid calling the super JS constructors in Scala classes. With the exception of "inlined inits", the job of the JS constructor in a Scala class is to create the fields, initialized to the zero of their types. Previously, the JS constructor of some class `A` extending `B` created its fields as follows: 1. call the super constructor to create all inherited fields, 2. create the fields directly declared in `A`. function $c_A() { $c_B.call(this); this.aField1 = 0; this.aField2 = 0; } This was however non-optimal, as calling the super constructor is pretty expensive. Instead, we now make the JS constructor of `A` directly create all its fields, including inherited ones: function $c_A() { this.bField1 = 0; this.bField2 = 0; this.aField1 = 0; this.aField2 = 0; } This optimization is only performed in ECMAScript 5.1, since with ES 2015 classes, calling the super constructor is mandatory. This optimization is ridiculously effective, as shown by our benchmark suite: * Tracer is 25% faster * DeltaBlue is 37% faster * SHA-512 is 14% faster --- ci/checksizes.sh | 14 +- .../linker/backend/emitter/ClassEmitter.scala | 71 +++++----- .../backend/emitter/GlobalKnowledge.scala | 7 + .../backend/emitter/KnowledgeGuardian.scala | 122 +++++++++--------- 4 files changed, 115 insertions(+), 99 deletions(-) diff --git a/ci/checksizes.sh b/ci/checksizes.sh index 8595b76dab..6cbb7d43c1 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -37,28 +37,28 @@ REVERSI_OPT_GZ_SIZE=$(stat '-c%s' "$REVERSI_OPT.gz") case $FULLVER in 2.10.2) - REVERSI_PREOPT_EXPECTEDSIZE=512000 - REVERSI_OPT_EXPECTEDSIZE=114000 + REVERSI_PREOPT_EXPECTEDSIZE=508000 + REVERSI_OPT_EXPECTEDSIZE=115000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=69000 REVERSI_OPT_GZ_EXPECTEDSIZE=30000 ;; 2.11.11) - REVERSI_PREOPT_EXPECTEDSIZE=509000 + REVERSI_PREOPT_EXPECTEDSIZE=505000 REVERSI_OPT_EXPECTEDSIZE=116000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=69000 REVERSI_OPT_GZ_EXPECTEDSIZE=30000 ;; 2.12.3) - REVERSI_PREOPT_EXPECTEDSIZE=608000 + REVERSI_PREOPT_EXPECTEDSIZE=603000 REVERSI_OPT_EXPECTEDSIZE=138000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=74000 REVERSI_OPT_GZ_EXPECTEDSIZE=32000 ;; 2.13.0-M2) - REVERSI_PREOPT_EXPECTEDSIZE=606000 + REVERSI_PREOPT_EXPECTEDSIZE=601000 REVERSI_OPT_EXPECTEDSIZE=138000 - REVERSI_PREOPT_GZ_EXPECTEDSIZE=75000 - REVERSI_OPT_GZ_EXPECTEDSIZE=32000 + REVERSI_PREOPT_GZ_EXPECTEDSIZE=74000 + REVERSI_OPT_GZ_EXPECTEDSIZE=31000 ;; esac diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index ccc1b28f19..8ba6b38707 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -189,18 +189,9 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { ) } - val ctorFunWithGlobals = if (!isJSClass) { - val superCtorCall = tree.superClass.fold[js.Tree] { - js.Skip() - } { parentIdent => - js.Apply( - js.DotSelect(encodeClassVar(parentIdent.name), js.Ident("call")), - List(js.This())) - } - genJSConstructorFun(tree, superCtorCall, initToInline) - } else { - genConstructorFunForJSClass(tree) - } + val ctorFunWithGlobals = + if (!isJSClass) genJSConstructorFun(tree, initToInline) + else genConstructorFunForJSClass(tree) val chainProtoWithGlobals = tree.superClass.fold[WithGlobals[js.Tree]] { WithGlobals(js.Skip()) @@ -250,18 +241,19 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { fun.body) } } else { - val superCtorCall = tree.superClass.fold[js.Tree] { - js.Skip()(tree.pos) - } { parentIdent => - js.Apply(js.Super(), Nil) - } - val jsConstructorFunWithGlobals = - genJSConstructorFun(tree, superCtorCall, initToInline) + genJSConstructorFun(tree, initToInline) for (jsConstructorFun <- jsConstructorFunWithGlobals) yield { val js.Function(args, body) = jsConstructorFun - if (args.isEmpty && (body eq superCtorCall)) + + def isTrivialCtorBody: Boolean = body match { + case js.Skip() => true + case js.Apply(js.Super(), Nil) => true + case _ => false + } + + if (args.isEmpty && isTrivialCtorBody) js.Skip() else js.MethodDef(static = false, js.Ident("constructor"), args, body) @@ -276,31 +268,47 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { * * The generated function performs the following steps: * - * - Call the super constructor, as specified by `superCtorCall` * - Create the fields of the current class, initialized to the zero of * their respective types + * - In ECMAScript 5.1, all the fields in the parent chain are directly + * created, avoiding expensive super calls + * - In ECMAScript 2015, calling the super constructor is mandatory, so we + * first call it then create the fields directly declared in this class * - Executes the body of the `init` method to inline, if any * + * Note that we know that a super JS constructor never contains an inlined + * init (which the above ES 5.1 treatment would throw away), because classes + * that have instantiated subclasses are not eligible for the inlined init + * optimization. + * * @param tree * The `LinkedClass` for which we generate a JS constructor. * - * @param superCtorCall - * The call to the super JS constructor. This will be different depending - * on the output mode. - * * @param initToInline * The `init` method to inline in the JS constructor, if any. */ - private def genJSConstructorFun(tree: LinkedClass, superCtorCall: js.Tree, + private def genJSConstructorFun(tree: LinkedClass, initToInline: Option[MethodDef])( implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Function] = { implicit val pos = tree.pos - val fieldDefs = genFieldDefsOfScalaClass(tree) + val superCtorCallAndFieldDefs = outputMode match { + case OutputMode.ECMAScript51Isolated => + val allFields = + globalKnowledge.getAllScalaClassFieldDefs(tree.encodedName) + genFieldDefsOfScalaClass(allFields) + + case OutputMode.ECMAScript2015 => + val fieldDefs = genFieldDefsOfScalaClass(tree.fields) + if (tree.superClass.isEmpty) + fieldDefs + else + js.Apply(js.Super(), Nil) :: fieldDefs + } initToInline.fold { - WithGlobals(js.Function(Nil, js.Block(superCtorCall :: fieldDefs))) + WithGlobals(js.Function(Nil, js.Block(superCtorCallAndFieldDefs))) } { initMethodDef => val generatedInitMethodFunWithGlobals = { implicit val pos = initMethodDef.pos @@ -316,7 +324,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { for (generatedInitMethodFun <- generatedInitMethodFunWithGlobals) yield { val js.Function(args, initMethodFunBody) = generatedInitMethodFun js.Function(args, - js.Block(superCtorCall :: fieldDefs ::: initMethodFunBody :: Nil)) + js.Block(superCtorCallAndFieldDefs ::: initMethodFunBody :: Nil)) } } } @@ -337,11 +345,10 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { } /** Generates the creation of fields for a Scala class. */ - private def genFieldDefsOfScalaClass(tree: LinkedClass)( + private def genFieldDefsOfScalaClass(fields: List[FieldDef])( implicit globalKnowledge: GlobalKnowledge): List[js.Tree] = { - val tpe = ClassType(tree.encodedName) for { - field @ FieldDef(false, name, ftpe, mutable) <- tree.fields + field @ FieldDef(false, name, ftpe, mutable) <- fields } yield { implicit val pos = field.pos val jsIdent = (name: @unchecked) match { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala index dad8f4ce6e..a0133456c8 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala @@ -18,6 +18,13 @@ private[emitter] trait GlobalKnowledge { /** Tests whether the specified class name refers to an `Interface`. */ def isInterface(className: String): Boolean + /** All the `FieldDef`s, included inherited ones, of a Scala class. + * + * It is invalid to call this method with anything but a `Class` or + * `ModuleClass`. + */ + def getAllScalaClassFieldDefs(className: String): List[FieldDef] + /** Tests whether the specified class uses an inlineable init. * * When it does, its (only) `init___` method is inlined inside the JS diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala index c1a9f83feb..eec3c38004 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala @@ -141,6 +141,9 @@ private[emitter] final class KnowledgeGuardian { def isInterface(className: String): Boolean = classes(className).askIsInterface(this) + def getAllScalaClassFieldDefs(className: String): List[FieldDef] = + classes(className).askAllScalaClassFieldDefs(this) + def hasInlineableInit(className: String): Boolean = classes(className).askHasInlineableInit(this) @@ -153,31 +156,6 @@ private[emitter] final class KnowledgeGuardian { def getJSClassFieldDefs(className: String): List[FieldDef] = classes(className).askJSClassFieldDefs(this) } -} - -private[emitter] object KnowledgeGuardian { - private[KnowledgeGuardian] trait Unregisterable { - def unregister(invalidatable: Invalidatable): Unit - } - - trait Invalidatable { - private val _registeredTo = mutable.Set.empty[Unregisterable] - - private[KnowledgeGuardian] def registeredTo( - unregisterable: Unregisterable): Unit = { - _registeredTo += unregisterable - } - - /** To be overridden to perform subclass-specific invalidation. - * - * All overrides should call the default implementation with `super` so - * that this `Invalidatable` is unregistered from the dependency graph. - */ - def invalidate(): Unit = { - _registeredTo.foreach(_.unregister(this)) - _registeredTo.clear() - } - } private class Class(initClass: LinkedClass, initHasInlineableInit: Boolean) @@ -188,14 +166,14 @@ private[emitter] object KnowledgeGuardian { private var isInterface = computeIsInterface(initClass) private var hasInlineableInit = initHasInlineableInit private var jsNativeLoadSpec = computeJSNativeLoadSpec(initClass) - private var jsSuperClass = computeJSSuperClass(initClass) - private var jsClassFieldDefs = computeJSClassFieldDefs(initClass) + private var superClass = computeSuperClass(initClass) + private var fieldDefs = computeFieldDefs(initClass) private val isInterfaceAskers = mutable.Set.empty[Invalidatable] private val hasInlineableInitAskers = mutable.Set.empty[Invalidatable] private val jsNativeLoadSpecAskers = mutable.Set.empty[Invalidatable] - private val jsSuperClassAskers = mutable.Set.empty[Invalidatable] - private val jsClassFieldDefsAskers = mutable.Set.empty[Invalidatable] + private val superClassAskers = mutable.Set.empty[Invalidatable] + private val fieldDefsAskers = mutable.Set.empty[Invalidatable] def update(linkedClass: LinkedClass, newHasInlineableInit: Boolean): Unit = { isAlive = true @@ -217,16 +195,16 @@ private[emitter] object KnowledgeGuardian { invalidateAskers(jsNativeLoadSpecAskers) } - val newJSSuperClass = computeJSSuperClass(linkedClass) - if (newJSSuperClass != jsSuperClass) { - jsSuperClass = newJSSuperClass - invalidateAskers(jsSuperClassAskers) + val newSuperClass = computeSuperClass(linkedClass) + if (newSuperClass != superClass) { + superClass = newSuperClass + invalidateAskers(superClassAskers) } - val newJSClassFieldDefs = computeJSClassFieldDefs(linkedClass) - if (newJSClassFieldDefs != jsClassFieldDefs) { - jsClassFieldDefs = newJSClassFieldDefs - invalidateAskers(jsClassFieldDefsAskers) + val newFieldDefs = computeFieldDefs(linkedClass) + if (newFieldDefs != fieldDefs) { + fieldDefs = newFieldDefs + invalidateAskers(fieldDefsAskers) } } @@ -236,22 +214,11 @@ private[emitter] object KnowledgeGuardian { private def computeJSNativeLoadSpec(linkedClass: LinkedClass): Option[JSNativeLoadSpec] = linkedClass.jsNativeLoadSpec - private def computeJSSuperClass(linkedClass: LinkedClass): String = { - linkedClass.kind match { - case ClassKind.JSClass | ClassKind.JSModuleClass => - linkedClass.superClass.get.name - case _ => - null - } - } + private def computeSuperClass(linkedClass: LinkedClass): String = + linkedClass.superClass.fold[String](null)(_.name) - private def computeJSClassFieldDefs( - linkedClass: LinkedClass): List[FieldDef] = { - if (linkedClass.kind == ClassKind.JSClass) - linkedClass.fields - else - Nil - } + private def computeFieldDefs(linkedClass: LinkedClass): List[FieldDef] = + linkedClass.fields private def invalidateAskers(askers: mutable.Set[Invalidatable]): Unit = { /* Calling `invalidateAndUnregisterFromAll()` will cause the @@ -276,6 +243,16 @@ private[emitter] object KnowledgeGuardian { isInterface } + def askAllScalaClassFieldDefs(invalidatable: Invalidatable): List[FieldDef] = { + invalidatable.registeredTo(this) + superClassAskers += invalidatable + fieldDefsAskers += invalidatable + val inheritedFieldDefs = + if (superClass == null) Nil + else classes(superClass).askAllScalaClassFieldDefs(invalidatable) + inheritedFieldDefs ::: fieldDefs + } + def askHasInlineableInit(invalidatable: Invalidatable): Boolean = { invalidatable.registeredTo(this) hasInlineableInitAskers += invalidatable @@ -290,22 +267,22 @@ private[emitter] object KnowledgeGuardian { def askJSSuperClass(invalidatable: Invalidatable): String = { invalidatable.registeredTo(this) - jsSuperClassAskers += invalidatable - jsSuperClass + superClassAskers += invalidatable + superClass } def askJSClassFieldDefs(invalidatable: Invalidatable): List[FieldDef] = { invalidatable.registeredTo(this) - jsClassFieldDefsAskers += invalidatable - jsClassFieldDefs + fieldDefsAskers += invalidatable + fieldDefs } def unregister(invalidatable: Invalidatable): Unit = { isInterfaceAskers -= invalidatable hasInlineableInitAskers -= invalidatable jsNativeLoadSpecAskers -= invalidatable - jsSuperClassAskers -= invalidatable - jsClassFieldDefsAskers -= invalidatable + superClassAskers -= invalidatable + fieldDefsAskers -= invalidatable } /** Call this when we invalidate all caches. */ @@ -313,8 +290,33 @@ private[emitter] object KnowledgeGuardian { isInterfaceAskers.clear() hasInlineableInitAskers.clear() jsNativeLoadSpecAskers.clear() - jsSuperClassAskers.clear() - jsClassFieldDefsAskers.clear() + superClassAskers.clear() + fieldDefsAskers.clear() + } + } +} + +private[emitter] object KnowledgeGuardian { + private trait Unregisterable { + def unregister(invalidatable: Invalidatable): Unit + } + + trait Invalidatable { + private val _registeredTo = mutable.Set.empty[Unregisterable] + + private[KnowledgeGuardian] def registeredTo( + unregisterable: Unregisterable): Unit = { + _registeredTo += unregisterable + } + + /** To be overridden to perform subclass-specific invalidation. + * + * All overrides should call the default implementation with `super` so + * that this `Invalidatable` is unregistered from the dependency graph. + */ + def invalidate(): Unit = { + _registeredTo.foreach(_.unregister(this)) + _registeredTo.clear() } } } From d1b8804624db79ae675ae1e04d3d88f15c6a9b4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 11 Sep 2017 17:25:22 +0200 Subject: [PATCH 0487/2665] Get rid of `RuntimeLong.Zero`. Instead, the `Emitter` instantiates `new RuntimeLong(0, 0)` explicitly and stores it in a global variable `$L0`. This allows the `RuntimeLong` module to have a pure constructor, which can therefore be elided when it is not needed after inlining. --- .../scala/scalajs/runtime/RuntimeLong.scala | 3 -- tools/scalajsenv.js | 16 ++++---- .../linker/backend/emitter/Emitter.scala | 40 ++++++++++++++----- .../tools/linker/backend/emitter/JSGen.scala | 5 +-- .../linker/backend/emitter/LongImpl.scala | 4 +- 5 files changed, 41 insertions(+), 27 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala b/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala index 037b95f8fd..a9916da4d4 100644 --- a/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala +++ b/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala @@ -551,9 +551,6 @@ object RuntimeLong { /** The hi part of a (lo, hi) return value. */ private[this] var hiReturn: Int = _ - /** The instance of 0L, which is used by the `Emitter` in various places. */ - val Zero = new RuntimeLong(0, 0) - private def toString(lo: Int, hi: Int): String = { if (isInt32(lo, hi)) { lo.toString() diff --git a/tools/scalajsenv.js b/tools/scalajsenv.js index 18c8bc0aaa..f5b1d0130f 100644 --- a/tools/scalajsenv.js +++ b/tools/scalajsenv.js @@ -114,6 +114,9 @@ const $clz32 = Math["clz32"] || (function(i) { }); //!endif +// Cached instance of RuntimeLong for 0L +let $L0; + // identityHashCode support let $lastIDHash = 0; // last value attributed to an id hash code //!if outputMode == ECMAScript6 @@ -708,8 +711,7 @@ function $uI(value) { return $asInt(value) | 0; }; function $uJ(value) { - return null === value ? $m_sjsr_RuntimeLong$().Zero$1 - : $as_sjsr_RuntimeLong(value); + return null === value ? $L0 : $as_sjsr_RuntimeLong(value); }; function $uF(value) { /* Here, it is fine to use + instead of fround, because asFloat already @@ -725,7 +727,7 @@ function $uC(value) { return null === value ? 0 : value.c; } function $uJ(value) { - return null === value ? $m_sjsr_RuntimeLong$().Zero$1 : value; + return null === value ? $L0 : value; }; //!endif @@ -860,10 +862,8 @@ initArray( // The zero for the Long runtime representation // is a special case here, since the class has not - // been defined yet, when this file is read - const componentZero = (componentZero0 == "longZero") - ? $m_sjsr_RuntimeLong$().Zero$1 - : componentZero0; + // been defined yet when this constructor is called. + const componentZero = (componentZero0 == "longZero") ? $L0 : componentZero0; //!if outputMode != ECMAScript6 /** @constructor */ @@ -1015,7 +1015,7 @@ $TypeData.prototype["getFakeInstance"] = function() { this === $d_jl_Double) return 0; else if (this === $d_jl_Long) - return $m_sjsr_RuntimeLong$().Zero$1; + return $L0; else if (this === $d_sr_BoxedUnit) return void 0; else diff --git 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 index ae074f97de..be02213240 100644 --- 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 @@ -147,16 +147,18 @@ final class Emitter private (config: CommonPhaseConfig, /* Emit all the classes, in the appropriate order: * - * - First, all class definitions, which depend on nothing but their - * superclasses. - * - Second, all static field definitions, which depend on nothing, - * except those of type Long which need to instantiate RuntimeLong. - * - Third, all static initializers, which in the worst case can observe - * some "zero" state of other static field definitions, but must not - * observe a *non-initialized* (undefined) state. - * - Finally, all the exports, during which some JS class creation can - * happen, causing JS static initializers to run. Those also must not - * observe a non-initialized state of other static fields. + * 1. All class definitions, which depend on nothing but their + * superclasses. + * 2. The initialization of $L0, the Long zero, which depends on the + * definition of the RuntimeLong class. + * 3. All static field definitions, which depend on nothing, except those + * of type Long which need $L0. + * 4. All static initializers, which in the worst case can observe some + * "zero" state of other static field definitions, but must not + * observe a *non-initialized* (undefined) state. + * 5. All the exports, during which some JS class creation can happen, + * causing JS static initializers to run. Those also must not observe + * a non-initialized state of other static fields. */ def emitJSTrees(trees: List[js.Tree]): Unit = @@ -165,6 +167,8 @@ final class Emitter private (config: CommonPhaseConfig, for (generatedClass <- generatedClasses) emitJSTrees(generatedClass.main) + builder.addJSTree(emitInitializeL0()) + for (generatedClass <- generatedClasses) emitJSTrees(generatedClass.staticFields) @@ -242,6 +246,22 @@ final class Emitter private (config: CommonPhaseConfig, } } + /** Emits the initialization of the global variable `$L0`, which holds the + * zero of type `Long`. + */ + private def emitInitializeL0(): js.Tree = { + import TreeDSL._ + implicit val pos = Position.NoPosition + + // $L0 = new RuntimeLong(0, 0) + js.Assign( + jsGen.envField("L0"), + js.Apply( + js.New(jsGen.encodeClassVar(LongImpl.RuntimeLongClass), Nil) DOT LongImpl.initFromParts, + List(js.IntLiteral(0), js.IntLiteral(0))) + ) + } + private def compareClasses(lhs: LinkedClass, rhs: LinkedClass) = { val lhsAC = lhs.ancestors.size val rhsAC = rhs.ancestors.size diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala index 959114a15e..c5b6a5627e 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala @@ -50,9 +50,8 @@ private[emitter] final class JSGen(val semantics: Semantics, } } - def genLongZero()(implicit pos: Position): Tree = { - genLongModuleApply(LongImpl.Zero) - } + def genLongZero()(implicit pos: Position): Tree = + envField("L0") def genLongModuleApply(methodName: String, args: Tree*)( implicit pos: Position): Tree = { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/LongImpl.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/LongImpl.scala index d5b1b4f7eb..aa799a45c7 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/LongImpl.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/LongImpl.scala @@ -90,10 +90,8 @@ private[linker] object LongImpl { final val fromDouble = "fromDouble__D__sjsr_RuntimeLong" - final val Zero = "Zero__sjsr_RuntimeLong" - val AllModuleMethods = Set( - fromDouble, Zero) + fromDouble) // Extract the parts to give to the initFromParts constructor From e903f71244c4d02feb18395ee5b8aa22298b0cc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 11 Sep 2017 17:42:19 +0200 Subject: [PATCH 0488/2665] Move the Int to Long conversion to `RuntimeLong.fromInt(x)`. Previously, it was an overloaded constructor `new RuntimeLong(x)`. This made sense in order to avoid loading the module instance of `RuntimeLong`. However, now that `RuntimeLong` has an elidable module accessor, this optimization is not necessary anymore. With this change, `RuntimeLong` always has exactly one constructor, and it can therefore benefit from the "inlined constructor" optimization. --- .../scala/scalajs/runtime/RuntimeLong.scala | 7 ++++--- .../testsuite/jsinterop/RuntimeLongTest.scala | 2 +- .../linker/backend/emitter/Emitter.scala | 4 +--- .../backend/emitter/FunctionEmitter.scala | 14 +++---------- .../linker/backend/emitter/LongImpl.scala | 6 +++--- .../frontend/optimizer/OptimizerCore.scala | 20 ++++++++++--------- 6 files changed, 23 insertions(+), 30 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala b/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala index a9916da4d4..4033727da8 100644 --- a/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala +++ b/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala @@ -39,9 +39,6 @@ final class RuntimeLong(val lo: Int, val hi: Int) import RuntimeLong._ import Utils._ - /** Constructs a Long from an Int. */ - def this(value: Int) = this(value, value >> 31) - // Universal equality @inline @@ -596,6 +593,10 @@ object RuntimeLong { } } + @inline + def fromInt(value: Int): RuntimeLong = + new RuntimeLong(value, value >> 31) + @inline def fromDouble(value: Double): RuntimeLong = { val lo = fromDoubleImpl(value) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/RuntimeLongTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/RuntimeLongTest.scala index fb574c23df..cab9c2e02f 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/RuntimeLongTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/RuntimeLongTest.scala @@ -28,7 +28,7 @@ class RuntimeLongTest { // Short builders def lg(lo: Int, hi: Int): RuntimeLong = new RuntimeLong(lo, hi) - def lg(i: Int): RuntimeLong = new RuntimeLong(i) + def lg(i: Int): RuntimeLong = RuntimeLong.fromInt(i) // Common values val MaxVal = lg(0xffffffff, 0x7fffffff) diff --git 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 index be02213240..15e3e64d69 100644 --- 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 @@ -250,14 +250,12 @@ final class Emitter private (config: CommonPhaseConfig, * zero of type `Long`. */ private def emitInitializeL0(): js.Tree = { - import TreeDSL._ implicit val pos = Position.NoPosition // $L0 = new RuntimeLong(0, 0) js.Assign( jsGen.envField("L0"), - js.Apply( - js.New(jsGen.encodeClassVar(LongImpl.RuntimeLongClass), Nil) DOT LongImpl.initFromParts, + js.New(jsGen.encodeClassVar(LongImpl.RuntimeLongClass), List(js.IntLiteral(0), js.IntLiteral(0))) ) } diff --git 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 index e8038b5c71..5e5e82cfd8 100644 --- 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 @@ -1955,7 +1955,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { FloatToDouble => newLhs case IntToLong => - genNewLong(LongImpl.initFromInt, newLhs) + genLongModuleApply(LongImpl.fromInt, newLhs) // Narrowing conversions case IntToChar => @@ -2267,8 +2267,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { genLongZero() case LongLiteral(value) => val (lo, hi) = LongImpl.extractParts(value) - genNewLong(LongImpl.initFromParts, - js.IntLiteral(lo), js.IntLiteral(hi)) + js.New(encodeClassVar(LongImpl.RuntimeLongClass), + List(js.IntLiteral(lo), js.IntLiteral(hi))) case ClassOf(cls) => js.Apply(js.DotSelect(genClassDataOf(cls), js.Ident("getClassOf")), @@ -2410,14 +2410,6 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { genCallHelper("fround", arg) } - private def genNewLong(ctor: String, args: js.Tree*)( - implicit pos: Position): js.Tree = { - import TreeDSL._ - js.Apply( - js.New(encodeClassVar(LongImpl.RuntimeLongClass), Nil) DOT ctor, - args.toList) - } - private def genLongMethodApply(receiver: js.Tree, methodName: String, args: js.Tree*)(implicit pos: Position): js.Tree = { import TreeDSL._ diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/LongImpl.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/LongImpl.scala index aa799a45c7..d2b29f30a5 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/LongImpl.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/LongImpl.scala @@ -81,17 +81,17 @@ private[linker] object LongImpl { // Constructors final val initFromParts = "init___I__I" - final val initFromInt = "init___I" val AllConstructors = Set( - initFromParts, initFromInt) + initFromParts) // Methods on the companion + final val fromInt = "fromInt__I__sjsr_RuntimeLong" final val fromDouble = "fromDouble__D__sjsr_RuntimeLong" val AllModuleMethods = Set( - fromDouble) + fromInt, fromDouble) // Extract the parts to give to the initFromParts constructor diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index fbd3669818..d6fbbcb632 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -2458,6 +2458,15 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { def rtLongModuleClassType = ClassType(LongImpl.RuntimeLongModuleClass) + def expandLongModuleOp(methodName: String, + arg: PreTransform): TailRec[Tree] = { + val receiver = LoadModule(rtLongModuleClassType).toPreTransform + pretransformApply(receiver, Ident(methodName), + arg :: Nil, rtLongClassType, isStat = false, + usePreTransform = true)( + cont) + } + def expandUnaryOp(methodName: String, arg: PreTransform, resultType: Type = rtLongClassType): TailRec[Tree] = { pretransformApply(arg, Ident(methodName), Nil, @@ -2479,10 +2488,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { (op: @switch) match { case IntToLong => - pretransformNew(AllocationSite.Anonymous, rtLongClassType, - Ident(LongImpl.initFromInt), - arg :: Nil)( - cont) + expandLongModuleOp(LongImpl.fromInt, arg) case LongToInt => expandUnaryOp(LongImpl.toInt, arg, IntType) @@ -2491,11 +2497,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { expandUnaryOp(LongImpl.toDouble, arg, DoubleType) case DoubleToLong => - val receiver = LoadModule(rtLongModuleClassType).toPreTransform - pretransformApply(receiver, Ident(LongImpl.fromDouble), - arg :: Nil, rtLongClassType, isStat = false, - usePreTransform = true)( - cont) + expandLongModuleOp(LongImpl.fromDouble, arg) case _ => cont(pretrans) From 57fa8c4ed953fb397536cb809e4c8aec11e5f2bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 2 Oct 2017 12:55:08 +0200 Subject: [PATCH 0489/2665] Bump checksizes to account for a different gzip version. The version of gzip on the CI servers was changed, which causes some differences in the resulting file sizes. --- ci/checksizes.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/checksizes.sh b/ci/checksizes.sh index 6cbb7d43c1..15f33664d4 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -58,7 +58,7 @@ case $FULLVER in REVERSI_PREOPT_EXPECTEDSIZE=601000 REVERSI_OPT_EXPECTEDSIZE=138000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=74000 - REVERSI_OPT_GZ_EXPECTEDSIZE=31000 + REVERSI_OPT_GZ_EXPECTEDSIZE=32000 ;; esac From 240aca3863bd3f28537e8bbce8788be62d5b5bdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 1 Oct 2017 10:27:39 +0200 Subject: [PATCH 0490/2665] Re-remove the definition of `isScalaJSProject`. It had been removed in ac428d8ab2d9ad9857e9f1c21d9abf3efba36500, but it made its way back into master through an erroneous merge conflict resolution in 5aa5ff4bbd0121a2eb8dcfb0660f57df9015fe56. --- .../src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 3eb8cffd50..4cf3a70348 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -60,11 +60,6 @@ object ScalaJSPlugin extends AutoPlugin { // All our public-facing keys - val isScalaJSProject = SettingKey[Boolean]("isScalaJSProject", - "Tests whether the current project is a Scala.js project. " + - "Do not set the value of this setting (only use it as read-only).", - BSetting) - val scalaJSIRCache = SettingKey[IRFileCache#Cache]( "scalaJSIRCache", "Scala.js internal: Task to access a cache.", KeyRanks.Invisible) From a9d2ce39d6b9bf11a07746b22a892db027dd4ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 1 Oct 2017 10:36:27 +0200 Subject: [PATCH 0491/2665] Do not define `scalaJSLinker`/`usesScalaJSLinkerTag` without stage. The settings `scalaJSLinker` and `usesScalaJSLinkerTag`, not scoped per stage key, were not used by our own plugin, and I do not think it is sane to rely on them. Any sbt task or setting using them should properly scope them per stage key instead. --- .../org/scalajs/sbtplugin/ScalaJSPluginInternal.scala | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 8199fcf4a2..ba6edaf59f 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -191,13 +191,6 @@ private[sbtplugin] object ScalaJSPluginInternal { scalaJSLinkedFile in key := new FileVirtualJSFile(key.value.data) ) - private def dispatchSettingKeySettings[T](key: SettingKey[T]) = Seq( - key := Def.settingDyn { - val stageKey = stageKeys(scalaJSStage.value) - Def.setting { (key in stageKey).value } - }.value - ) - private def dispatchTaskKeySettings[T](key: TaskKey[T]) = Seq( key := Def.settingDyn { val stageKey = stageKeys(scalaJSStage.value) @@ -284,9 +277,7 @@ private[sbtplugin] object ScalaJSPluginInternal { ) ++ ( scalajspSettings ++ stageKeys.flatMap((scalaJSStageSettings _).tupled) ++ - dispatchTaskKeySettings(scalaJSLinkedFile) ++ - dispatchSettingKeySettings(scalaJSLinker) ++ - dispatchSettingKeySettings(usesScalaJSLinkerTag) + dispatchTaskKeySettings(scalaJSLinkedFile) ) ++ ( Seq(fastOptJS, fullOptJS).map { key => moduleName in key := { From 00722a54d494ac4ead00ea609aa9c313333bd0c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 1 Oct 2017 10:47:19 +0200 Subject: [PATCH 0492/2665] Make `scalaJSLinkedFile` a direct alias of `{fast,full}OptJS`. This means that it becomes an `Attributed[File]`, like `fastOptJS` and `fullOptJS`, instead of a `VirtualJSFile`. Once we do that, it makes little sense to specifically define `scalaJSLinkedFile in fastOptJS`, so instead we directly dispatch `scalaJSLinkedFile` to either `fastOptJS` or `fullOptJS`. --- project/Build.scala | 6 +++--- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 2 +- .../sbtplugin/ScalaJSPluginInternal.scala | 21 +++++++------------ 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 71893d6ebd..456a3fc6f6 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -668,9 +668,9 @@ object Build { /* 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 toolsTestModulePath = scalaJSLinkedFile.value.data.getPath val executionFiles = - jsExecutionFiles.value.filter(_ ne toolsTestModule) + jsExecutionFiles.value.filter(_.path != toolsTestModulePath) /* Collect relevant IR files from the classpath of the test suite. * We assume here that the classpath is valid. This is checked by the @@ -721,7 +721,7 @@ object Build { val code = { s""" - var toolsTestModule = require("${escapeJS(toolsTestModule.path)}"); + var toolsTestModule = require("${escapeJS(toolsTestModulePath)}"); var linker = toolsTestModule.scalajs.QuickLinker; var lib = linker.linkTestSuiteNode($irPaths, $mainMethods); diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 4cf3a70348..9e5cac1741 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -136,7 +136,7 @@ object ScalaJSPlugin extends AutoPlugin { val scalaJSStage = SettingKey[Stage]("scalaJSStage", "The optimization stage at which run and test are executed", APlusSetting) - val scalaJSLinkedFile = TaskKey[VirtualJSFile]("scalaJSLinkedFile", + val scalaJSLinkedFile = TaskKey[Attributed[File]]("scalaJSLinkedFile", "Linked Scala.js file. This is the result of fastOptJS or fullOptJS, " + "depending on the stage.", DTask) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index ba6edaf59f..f946b41cf0 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -186,15 +186,6 @@ private[sbtplugin] object ScalaJSPluginInternal { val sourceMapFile = FileVirtualJSFile(output).sourceMapFile Attributed.blank(output).put(scalaJSSourceMap, sourceMapFile) }.tag(usesLinkerTag) - }.value, - - scalaJSLinkedFile in key := new FileVirtualJSFile(key.value.data) - ) - - private def dispatchTaskKeySettings[T](key: TaskKey[T]) = Seq( - key := Def.settingDyn { - val stageKey = stageKeys(scalaJSStage.value) - Def.task { (key in stageKey).value } }.value ) @@ -276,8 +267,7 @@ private[sbtplugin] object ScalaJSPluginInternal { incOptions ~= scalaJSPatchIncOptions ) ++ ( scalajspSettings ++ - stageKeys.flatMap((scalaJSStageSettings _).tupled) ++ - dispatchTaskKeySettings(scalaJSLinkedFile) + stageKeys.flatMap((scalaJSStageSettings _).tupled) ) ++ ( Seq(fastOptJS, fullOptJS).map { key => moduleName in key := { @@ -315,6 +305,10 @@ private[sbtplugin] object ScalaJSPluginInternal { .withClosureCompiler(prevConfig.outputMode == OutputMode.ECMAScript51Isolated) }, + scalaJSLinkedFile := Def.settingDyn { + stageKeys(scalaJSStage.value) + }.value, + 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.") @@ -356,7 +350,8 @@ private[sbtplugin] object ScalaJSPluginInternal { }, // Crucially, add the Scala.js linked file to the JS files - jsExecutionFiles += scalaJSLinkedFile.value, + jsExecutionFiles += + new FileVirtualJSFile(scalaJSLinkedFile.value.data), scalaJSMainModuleInitializer := { mainClass.value.map { mainCl => @@ -433,7 +428,7 @@ private[sbtplugin] object ScalaJSPluginInternal { val moduleKind = scalaJSLinkerConfig.value.moduleKind val moduleIdentifier = moduleKind match { case ModuleKind.NoModule => None - case ModuleKind.CommonJSModule => Some(scalaJSLinkedFile.value.path) + case ModuleKind.CommonJSModule => Some(scalaJSLinkedFile.value.data.getPath) } val frameworksAndTheirImplNames = From 4a38da852b54ab45ad82e946030c79acf661d428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 1 Oct 2017 11:02:25 +0200 Subject: [PATCH 0493/2665] Remove `ScalaJSPlugin.stageKeys`. It had very little use in our own sbt plugin, and the usages I found in the wild can be advantageously replaced by direct references to `fastOptJS` and `fullOptJS`. --- .../scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala | 10 ---------- .../org/scalajs/sbtplugin/ScalaJSPluginInternal.scala | 10 +++++++--- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 9e5cac1741..91aef45cb8 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -175,16 +175,6 @@ object ScalaJSPlugin extends AutoPlugin { import autoImport._ - /** Maps a [[Stage]] to the corresponding `TaskKey`. - * - * For example, [[Stage.FastOpt]] (aka `FastOptStage`) is mapped to - * [[autoImport.fastOptJS fastOptJS]]. - */ - val stageKeys: Map[Stage, TaskKey[Attributed[File]]] = Map( - Stage.FastOpt -> fastOptJS, - Stage.FullOpt -> fullOptJS - ) - /** Logs the current statistics about the global IR cache. */ def logIRCacheStats(logger: Logger): Unit = { import ScalaJSPluginInternal.globalIRCache diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index f946b41cf0..4999076ad4 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -41,7 +41,7 @@ import java.nio.charset.Charset private[sbtplugin] object ScalaJSPluginInternal { import ScalaJSPlugin.autoImport.{ModuleKind => _, _} - import ScalaJSPlugin.{logIRCacheStats, stageKeys} + import ScalaJSPlugin.logIRCacheStats /** The global Scala.js IR cache */ val globalIRCache: IRFileCache = new IRFileCache() @@ -267,7 +267,8 @@ private[sbtplugin] object ScalaJSPluginInternal { incOptions ~= scalaJSPatchIncOptions ) ++ ( scalajspSettings ++ - stageKeys.flatMap((scalaJSStageSettings _).tupled) + scalaJSStageSettings(Stage.FastOpt, fastOptJS) ++ + scalaJSStageSettings(Stage.FullOpt, fullOptJS) ) ++ ( Seq(fastOptJS, fullOptJS).map { key => moduleName in key := { @@ -306,7 +307,10 @@ private[sbtplugin] object ScalaJSPluginInternal { }, scalaJSLinkedFile := Def.settingDyn { - stageKeys(scalaJSStage.value) + scalaJSStage.value match { + case Stage.FastOpt => fastOptJS + case Stage.FullOpt => fullOptJS + } }.value, console := console.dependsOn(Def.task { From dcf283d7c4cc68b0b75d0e6ac4250335e8781940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 1 Oct 2017 11:08:25 +0200 Subject: [PATCH 0494/2665] Do not error out for unknown `javaOptions`. There could be other sbt plugins who do something meaningful with other options, and we don't want to prevent them from doing so just because we refuse to let them through. --- sbt-plugin-test/build.sbt | 3 ++- .../scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala | 6 +----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index 2ef2a811c8..67a3c25b5b 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -36,7 +36,8 @@ lazy val noDOM = project.settings(baseSettings: _*). enablePlugins(ScalaJSJUnitPlugin). settings( name := "Scala.js sbt test w/o DOM", - scalaJSUseMainModuleInitializer := true + scalaJSUseMainModuleInitializer := true, + javaOptions += "-Xmx512M" // test that this is ignored without error ). /* This hopefully exposes concurrent uses of the linker. If it fails/gets * flaky, there is a bug somewhere - #2202 diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 4999076ad4..2bd7d325c5 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -326,12 +326,8 @@ private[sbtplugin] object ScalaJSPluginInternal { scalaJSJavaSystemProperties ++= { val javaSysPropsPattern = "-D([^=]*)=(.*)".r - javaOptions.value.map { + javaOptions.value.collect { case javaSysPropsPattern(propName, propValue) => (propName, propValue) - case opt => - throw new MessageOnlyException( - "Scala.js javaOptions can only be \"-D=\"," + - " but received: " + opt) }.toMap }, From 00cb3ef24132f269c97a0a7b5a2b243301708f4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 1 Oct 2017 11:19:59 +0200 Subject: [PATCH 0495/2665] Remove `scalaJSJavaSystemProperties`. Instead, we directly derive them inside the addition to `jsExecutionFiles`. Getting rid of that setting makes the public API of the sbt plugin a bit nicer. The only use case seemed to be in our own build, which patches the Java system properties for `testHtml`. So that part needs to duplicate a tiny bit more code from the sbt plugin to compensate. --- project/Build.scala | 26 +++++++++---------- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 5 ---- .../sbtplugin/ScalaJSPluginInternal.scala | 11 +++----- 3 files changed, 16 insertions(+), 26 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 456a3fc6f6..36734a8e0f 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1413,22 +1413,22 @@ object Build { def testSuiteTestHtmlSetting = Def.settings( // We need to patch the system properties. - scalaJSJavaSystemProperties in Test in testHtml ~= { base => - val unsupported = - Seq("nodejs", "source-maps") - val supported = - Seq("typedarray", "browser") - - base -- unsupported.map("scalajs." + _) ++ - supported.map("scalajs." + _ -> "true") - }, - - // And we need to actually use those patched system properties. jsExecutionFiles in (Test, testHtml) := { val previousFiles = (jsExecutionFiles in (Test, testHtml)).value - val patchedSystemProperties = - (scalaJSJavaSystemProperties in (Test, testHtml)).value + val patchedSystemProperties = { + // Fetch the defaults + val javaSysPropsPattern = "-D([^=]*)=(.*)".r + val base = (javaOptions in Test).value.collect { + case javaSysPropsPattern(propName, propValue) => (propName, propValue) + }.toMap + + // Patch + val unsupported = Seq("nodejs", "source-maps") + val supported = Seq("typedarray", "browser") + base -- unsupported.map("scalajs." + _) ++ + supported.map("scalajs." + _ -> "true") + } val formattedProps = patchedSystemProperties.map { case (propName, propValue) => diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 91aef45cb8..d7df7df44a 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -159,11 +159,6 @@ object ScalaJSPlugin extends AutoPlugin { "All the JS files given to JS environments on `run`, `test`, etc.", BTask) - val scalaJSJavaSystemProperties = TaskKey[Map[String, String]]( - "scalaJSJavaSystemProperties", - "List of arguments to pass to the Scala.js Java System.properties.", - CTask) - val scalaJSSourceFiles = AttributeKey[Seq[File]]("scalaJSSourceFiles", "Files used to compute this value (can be used in FileFunctions later).", KeyRanks.Invisible) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 2bd7d325c5..d8d66d1fc1 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -324,16 +324,13 @@ private[sbtplugin] object ScalaJSPluginInternal { */ jsExecutionFiles := (jsExecutionFiles in (This, Zero, This)).value, - scalaJSJavaSystemProperties ++= { + // Optionally add a JS file defining Java system properties + jsExecutionFiles ++= { val javaSysPropsPattern = "-D([^=]*)=(.*)".r - javaOptions.value.collect { + val javaSystemProperties = javaOptions.value.collect { case javaSysPropsPattern(propName, propValue) => (propName, propValue) }.toMap - }, - // Optionally add a JS file defining Java system properties - jsExecutionFiles ++= { - val javaSystemProperties = scalaJSJavaSystemProperties.value if (javaSystemProperties.isEmpty) { Nil } else { @@ -513,8 +510,6 @@ private[sbtplugin] object ScalaJSPluginInternal { jsExecutionFiles := Nil, - scalaJSJavaSystemProperties := Map.empty, - // you will need the Scala.js compiler plugin autoCompilerPlugins := true, addCompilerPlugin( From 323b8d28e53c565270dbe5c4a41dc8bf0c522d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 1 Oct 2017 11:26:43 +0200 Subject: [PATCH 0496/2665] Do not explicitly set `autoCompilerPlugins := true`. It is the default in sbt, so no need to repeat it. --- .../main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index d8d66d1fc1..54fa5a2b7d 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -511,7 +511,6 @@ private[sbtplugin] object ScalaJSPluginInternal { jsExecutionFiles := Nil, // you will need the Scala.js compiler plugin - autoCompilerPlugins := true, addCompilerPlugin( "org.scala-js" % "scalajs-compiler" % scalaJSVersion cross CrossVersion.full), From e5e89c7a066f51d669de27fd7b84a306964e55fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 1 Oct 2017 11:34:53 +0200 Subject: [PATCH 0497/2665] Remove the private `scalaJSTestBuildSettings`. We just inline its content at use site. --- .../scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 54fa5a2b7d..f37401d728 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -445,10 +445,6 @@ private[sbtplugin] object ScalaJSPluginInternal { } ) - private val scalaJSTestBuildSettings = ( - scalaJSConfigSettings - ) - private val scalaJSTestHtmlSettings = Seq( artifactPath in testHtml := { val stageSuffix = scalaJSStage.value match { @@ -485,7 +481,7 @@ private[sbtplugin] object ScalaJSPluginInternal { ) val scalaJSTestSettings: Seq[Setting[_]] = ( - scalaJSTestBuildSettings ++ + scalaJSConfigSettings ++ scalaJSTestFrameworkSettings ++ scalaJSTestHtmlSettings ) ++ Seq( From 9f7dcda7fc8c05c6105c73788240098c539bab2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 1 Oct 2017 11:59:09 +0200 Subject: [PATCH 0498/2665] Simplify somewhat the definition of `scalajsp`. Mostly so that we avoid the addition `scalajspSettings`, which disrupts the flow when reading the sbt plugin source. --- .../sbtplugin/ScalaJSPluginInternal.scala | 62 ++++++++----------- 1 file changed, 25 insertions(+), 37 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index f37401d728..093c1e325a 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -7,7 +7,6 @@ import java.util.concurrent.atomic.AtomicReference import sbt._ import Keys._ -import complete.Parser import complete.DefaultParsers._ import sbtcrossproject.CrossPlugin.autoImport._ @@ -94,6 +93,13 @@ private[sbtplugin] object ScalaJSPluginInternal { } } + private val scalajspParser = { + loadForParser(sjsirFilesOnClasspath) { (_, relPaths) => + val examples = ScalajspUtils.relPathsExamples(relPaths.getOrElse(Nil)) + OptSpace ~> StringBasic.examples(examples) + } + } + /** Patches the IncOptions so that .sjsir files are pruned as needed. */ def scalaJSPatchIncOptions(incOptions: IncOptions): IncOptions = SBTCompat.scalaJSPatchIncOptions(incOptions) @@ -189,41 +195,6 @@ private[sbtplugin] object ScalaJSPluginInternal { }.value ) - private def scalajspSettings: Seq[Setting[_]] = { - def sjsirFileOnClasspathParser( - relPaths: Seq[String]): Parser[String] = { - OptSpace ~> StringBasic - .examples(ScalajspUtils.relPathsExamples(relPaths)) - } - - def scalajspParser(state: State, relPaths: Seq[String]): Parser[String] = - sjsirFileOnClasspathParser(relPaths) - - val parser = loadForParser(sjsirFilesOnClasspath) { (state, relPaths) => - scalajspParser(state, relPaths.getOrElse(Nil)) - } - - Seq( - sjsirFilesOnClasspath := Def.task { - scalaJSIR.value.data.map(_.relativePath).toSeq - }.storeAs(sjsirFilesOnClasspath).triggeredBy(scalaJSIR).value, - - scalajsp := { - val relPath = parser.parsed - - val vfile = scalaJSIR.value.data - .find(_.relativePath == relPath) - .getOrElse(throw new FileNotFoundException(relPath)) - - val stdout = new java.io.PrintWriter(System.out) - new IRTreePrinter(stdout).print(vfile.tree) - stdout.flush() - - logIRCacheStats(streams.value.log) - } - ) - } - /** Collect certain file types from a classpath. * * @param cp Classpath to collect from @@ -266,7 +237,6 @@ private[sbtplugin] object ScalaJSPluginInternal { val scalaJSConfigSettings: Seq[Setting[_]] = Seq( incOptions ~= scalaJSPatchIncOptions ) ++ ( - scalajspSettings ++ scalaJSStageSettings(Stage.FastOpt, fastOptJS) ++ scalaJSStageSettings(Stage.FullOpt, fullOptJS) ) ++ ( @@ -292,6 +262,24 @@ private[sbtplugin] object ScalaJSPluginInternal { rawIR.map(cache.cached) }, + sjsirFilesOnClasspath := Def.task { + scalaJSIR.value.data.map(_.relativePath).toSeq + }.storeAs(sjsirFilesOnClasspath).triggeredBy(scalaJSIR).value, + + scalajsp := { + val relPath = scalajspParser.parsed + + val vfile = scalaJSIR.value.data + .find(_.relativePath == relPath) + .getOrElse(throw new FileNotFoundException(relPath)) + + val stdout = new java.io.PrintWriter(System.out) + new IRTreePrinter(stdout).print(vfile.tree) + stdout.flush() + + logIRCacheStats(streams.value.log) + }, + artifactPath in fastOptJS := ((crossTarget in fastOptJS).value / ((moduleName in fastOptJS).value + "-fastopt.js")), From 0fc0ff99e3071696f49d01d20a83dfbf07e44da9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 1 Oct 2017 12:08:56 +0200 Subject: [PATCH 0499/2665] Cleanup imports in the sbt plugin. --- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 1 - .../sbtplugin/ScalaJSPluginInternal.scala | 23 +++++++------------ 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index d7df7df44a..e350076ff5 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -20,7 +20,6 @@ import org.scalajs.core.ir.ScalaJSVersions import org.scalajs.core.tools.io._ import org.scalajs.core.tools.linker._ -import org.scalajs.core.tools.linker.standard._ import org.scalajs.jsenv.JSEnv diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 093c1e325a..f18cce9fe5 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -2,20 +2,16 @@ package org.scalajs.sbtplugin import scala.annotation.tailrec -import java.util.IllegalFormatException +import java.io.FileNotFoundException + import java.util.concurrent.atomic.AtomicReference import sbt._ -import Keys._ -import complete.DefaultParsers._ +import sbt.Keys._ +import sbt.complete.DefaultParsers._ import sbtcrossproject.CrossPlugin.autoImport._ -import Loggers._ -import SBTCompat._ -import SBTCompat.formatImplicits._ -import SBTCompat.formatImplicits.seqFormat - import org.scalajs.core.tools.io.{IO => _, _} import org.scalajs.core.tools.linker._ import org.scalajs.core.tools.linker.standard._ @@ -23,18 +19,15 @@ import org.scalajs.core.tools.linker.standard._ import org.scalajs.jsenv._ import org.scalajs.jsenv.nodejs.NodeJSEnv -import org.scalajs.core.ir import org.scalajs.core.ir.Utils.escapeJS -import org.scalajs.core.ir.ScalaJSVersions import org.scalajs.core.ir.Printers.IRTreePrinter import org.scalajs.testadapter.{FrameworkDetector, HTMLRunnerBuilder} -import scala.util.Try -import scala.collection.mutable - -import java.io.FileNotFoundException -import java.nio.charset.Charset +import Loggers._ +import SBTCompat._ +import SBTCompat.formatImplicits._ +import SBTCompat.formatImplicits.seqFormat /** Implementation details of `ScalaJSPlugin`. */ private[sbtplugin] object ScalaJSPluginInternal { From d8f387d76aa3d8de7485d339259ca140c460d581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 1 Oct 2017 18:04:54 +0200 Subject: [PATCH 0500/2665] Use `FileScalaJSIRContainer.fromClasspath` to compute `scalaJSIR`. This required to strengthen it a bit first: * Specialize its result type so that the caller statically knows that all the returned containers are backed by a `File`. * Fix the relative paths computed by `fromClasspath` on Windows. This allows `scalaJSIR` to directly reuse that method, which means we get rid of `collectFromClasspath`. --- .../sbtplugin/ScalaJSPluginInternal.scala | 50 +++---------------- .../core/tools/io/FileVirtualFiles.scala | 13 +++-- 2 files changed, 15 insertions(+), 48 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index f18cce9fe5..3bc9db6f5d 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -188,45 +188,6 @@ private[sbtplugin] object ScalaJSPluginInternal { }.value ) - /** Collect certain file types from a classpath. - * - * @param cp Classpath to collect from - * @param filter Filter for (real) files of interest (not in jars) - * @param collectJar Collect elements from a jar (called for all jars) - * @param collectFile Collect a single file. Params are the file and the - * relative path of the file (to its classpath entry root). - * @return Collected elements attributed with physical files they originated - * from (key: scalaJSSourceFiles). - */ - private def collectFromClasspath[T](cp: Def.Classpath, filter: FileFilter, - collectJar: VirtualJarFile => Seq[T], - collectFile: (File, String) => T): Attributed[Seq[T]] = { - - val realFiles = Seq.newBuilder[File] - val results = Seq.newBuilder[T] - - for (cpEntry <- Attributed.data(cp) if cpEntry.exists) { - if (cpEntry.isFile && cpEntry.getName.endsWith(".jar")) { - realFiles += cpEntry - val vf = new FileVirtualBinaryFile(cpEntry) with VirtualJarFile - results ++= collectJar(vf) - } else if (cpEntry.isDirectory) { - for { - (file, relPath0) <- Path.selectSubpaths(cpEntry, filter) - } { - val relPath = relPath0.replace(java.io.File.separatorChar, '/') - realFiles += file - results += collectFile(file, relPath) - } - } else { - throw new IllegalArgumentException( - "Illegal classpath entry: " + cpEntry.getPath) - } - } - - Attributed.blank(results.result()).put(scalaJSSourceFiles, realFiles.result()) - } - val scalaJSConfigSettings: Seq[Setting[_]] = Seq( incOptions ~= scalaJSPatchIncOptions ) ++ ( @@ -247,12 +208,13 @@ private[sbtplugin] object ScalaJSPluginInternal { scalaJSIRCache := newIRCache, scalaJSIR := { - val rawIR = collectFromClasspath(fullClasspath.value, "*.sjsir", - collectJar = Seq(_), - collectFile = FileVirtualScalaJSIRFile.relative) - val cache = scalaJSIRCache.value - rawIR.map(cache.cached) + val classpath = Attributed.data(fullClasspath.value) + val irContainers = FileScalaJSIRContainer.fromClasspath(classpath) + val irFiles = cache.cached(irContainers) + Attributed + .blank[Seq[VirtualScalaJSIRFile with RelativeVirtualFile]](irFiles) + .put(scalaJSSourceFiles, irContainers.map(_.file)) }, sjsirFilesOnClasspath := Def.task { diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala index 8fec5ca1fd..608604ae60 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala @@ -181,7 +181,8 @@ object FileVirtualScalaJSIRFile extends (File => FileVirtualScalaJSIRFile) { } object FileScalaJSIRContainer { - def fromClasspath(classpath: Seq[File]): Seq[ScalaJSIRContainer] = { + def fromClasspath( + classpath: Seq[File]): Seq[ScalaJSIRContainer with FileVirtualFile] = { classpath flatMap { entry => if (!entry.exists) Nil @@ -194,7 +195,8 @@ object FileScalaJSIRContainer { } } - private def fromDirectory(dir: File): Seq[ScalaJSIRContainer] = { + private def fromDirectory( + dir: File): Seq[ScalaJSIRContainer with FileVirtualFile] = { require(dir.isDirectory) val baseDir = dir.getAbsoluteFile @@ -205,8 +207,11 @@ object FileScalaJSIRContainer { } for (ir <- walkForIR(baseDir)) yield { - val relDir = ir.getPath.stripPrefix(baseDir.getPath) - FileVirtualScalaJSIRFile.relative(ir, relDir) + val relPath = ir.getPath + .stripPrefix(baseDir.getPath) + .replace(java.io.File.separatorChar, '/') + .stripPrefix("/") + FileVirtualScalaJSIRFile.relative(ir, relPath) } } } From 4b42ad7d538fc8703126aec4abe82afe06a0970f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 6 Oct 2017 14:20:14 +0200 Subject: [PATCH 0501/2665] Fix #3148: Make our test suite pass on Node.js 8. This commit adapts two classes of exceptions, namely `j.u.IllegalFormatConversionException` and `org.junit.internal.ArrayComparisonFailure`, so that their `toString()` does not crash if it is called before their respective constructors have finished executing. --- .../src/main/scala/java/util/Throwables.scala | 15 ++++++------- .../internal/ArrayComparisonFailure.scala | 22 ++++++++++--------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/javalib/src/main/scala/java/util/Throwables.scala b/javalib/src/main/scala/java/util/Throwables.scala index 919738b6f8..b8340126c7 100644 --- a/javalib/src/main/scala/java/util/Throwables.scala +++ b/javalib/src/main/scala/java/util/Throwables.scala @@ -42,16 +42,15 @@ class IllegalFormatCodePointException(private val c: Int) extends IllegalFormatE override def getMessage(): String = s"Code point = $c" } -class IllegalFormatConversionException private(private val c: Char) extends IllegalFormatException { - private var arg: Class[_] = null - def this(c: Char, arg: Class[_]) = { - this(c) - if (arg == null) - throw new NullPointerException() - this.arg = arg - } +class IllegalFormatConversionException(c: Char, arg: Class[_]) + extends IllegalFormatException { + + if (arg == null) + throw new NullPointerException() + def getConversion(): Char = c def getArgumentClass(): Class[_] = arg + override def getMessage(): String = s"$c != ${arg.getName()}" } diff --git a/junit-runtime/src/main/scala/org/junit/internal/ArrayComparisonFailure.scala b/junit-runtime/src/main/scala/org/junit/internal/ArrayComparisonFailure.scala index 62f6a6b634..58b6d4c0ac 100644 --- a/junit-runtime/src/main/scala/org/junit/internal/ArrayComparisonFailure.scala +++ b/junit-runtime/src/main/scala/org/junit/internal/ArrayComparisonFailure.scala @@ -5,24 +5,26 @@ package org.junit.internal object ArrayComparisonFailure -class ArrayComparisonFailure(fMessage: String) extends AssertionError { - private var fIndices: List[Int] = Nil +class ArrayComparisonFailure(message: String, cause: AssertionError, index: Int) + extends AssertionError(message, cause) { - def this(message: String, cause: AssertionError, index: Int) = { - this(message) - initCause(cause) - addDimension(index) - } + private var fIndices: List[Int] = index :: Nil + + @deprecated("This constructor is not used and will be removed", "0.6.21") + def this(fMessage: String) = + this(fMessage, new AssertionError, 0) def addDimension(index: Int): Unit = { fIndices = index :: fIndices } override def getMessage(): String = { - val message = if (fMessage != null) fMessage else "" - val indices = fIndices.map(index => s"[$index]").mkString + val msg = if (message != null) message else "" + val indices = + if (fIndices == null) s"[$index]" // see #3148 + else fIndices.map(index => s"[$index]").mkString val causeMessage = getCause.getMessage - s"${message}arrays first differed at element $indices; $causeMessage" + s"${msg}arrays first differed at element $indices; $causeMessage" } override def toString(): String = getMessage From 4aecb56a7ca5c29d03a8ef7464e82f8d6a77f1b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20Mayer?= Date: Sat, 9 Sep 2017 01:23:31 +0200 Subject: [PATCH 0502/2665] Fix #3134: Make regex.Matcher report correct group positions. To compute the correct group positions (which are not computed by javascript), GroupStartMap modifies the regular expression so that every part of the regex belongs to a group. Based on the length of every group, we can recover the start position of the original group. Example: If the regex /A(B)\1/ matches a string at a given index, then /(A)(B)\2/ matches the same string at the same index. However, in the second regex, we can use the length of the first group (A) to retrieve the start position of the second group (B). Note that the back-references in the second regex are shifted, but this does not change the matched strings. --- .../scala/java/util/regex/GroupStartMap.scala | 576 ++++++++++++++++++ .../main/scala/java/util/regex/Matcher.scala | 42 +- .../javalib/util/regex/RegexMatcherTest.scala | 149 ++++- 3 files changed, 722 insertions(+), 45 deletions(-) create mode 100644 javalib/src/main/scala/java/util/regex/GroupStartMap.scala diff --git a/javalib/src/main/scala/java/util/regex/GroupStartMap.scala b/javalib/src/main/scala/java/util/regex/GroupStartMap.scala new file mode 100644 index 0000000000..159f794063 --- /dev/null +++ b/javalib/src/main/scala/java/util/regex/GroupStartMap.scala @@ -0,0 +1,576 @@ +package java.util.regex + +import scala.annotation.{tailrec, switch} + +import scala.scalajs.js + +/** The goal of a `GroupStartMap` is to retrieve the start position of each + * group of a matching regular expression where only the strings of the + * matched groups are known. + * For that, we use the following observation: + * If the regex /A(B)\1/ matches a string at a given index, + * then /(A)(B)\2/ matches the same string at the same index. + * However, in the second regex, we can use the length of the first group (A) + * to retrieve the start position of the second group (B). + * Note that the back-references in the second regex are shifted, but this + * does not change the matched strings. + * + * Implementation details: + * - It parses the regular expression into a tree of type `Node` that contains: + * + Either modifiers (e.g. +, *, (?=....)), or an original group number + * + Either a raw regular expression, or a list of children Node + * - It converts this Node to a regex string, such that every sub-part of the + * regex which was not yet in a group now belongs to a group + * - The new regex matches the original string at the original position + * - It propagates the matched strings of all groups into the Node + * - It computes the start of every group thanks to the groups before it + * - It builds and returns the mapping of previous group number -> start + * + * @author Mikaël Mayer + */ +private[regex] object GroupStartMap { + def apply(string: String, start: Int, pattern: Pattern): Int => Int = + new GroupStartMap(string, start, pattern).mapping + + /** Parentheses aspect of the regex. */ + private sealed trait OriginalRegex { + @inline + def fold[A](numberF: Int => A, leftRightF: (String, String) => A): A = { + this match { + case OriginallyGroupped(number) => numberF(number) + case OriginallyWrapped(left, right) => leftRightF(left, right) + } + } + } + + /** The regex had originally a group number. + * + * That is, with simple parentheses non-grouping parentheses (?: ...) are + * always added. + */ + private final case class OriginallyGroupped(number: Int) extends OriginalRegex + + /** The regex was not originally grouped with parentheses. + * + * In that case, `left` and `right` are modifiers (e.g., `*`, `+`, `*?`, + * `+?`, `?`, `(?= ...)`, `(?! ...)`). + */ + private final case class OriginallyWrapped(left: String, right: String) + extends OriginalRegex + + private object OriginallyWrapped { + def isRepeatModifier(modifier: String): Boolean = { + modifier == "?" || modifier == "??" || modifier == "*" || + modifier == "+" || modifier == "*?" || modifier == "+?" || + modifier.startsWith("{") + } + + object Repeater { + def unapply(e: OriginallyWrapped): Option[String] = + if (e.left == "" && isRepeatModifier(e.right)) Some(e.right) + else None + } + + object Absolute { + def unapply(e: OriginallyWrapped): Boolean = + (e.left == "(?!" || e.left == "(?=") && e.right == ")" + } + } + + /** Type of the node, a regex or a sequence of nodes. */ + private sealed trait NodeType { + @inline + def fold[A](regexF: String => A, childrenF: Seq[Node] => A, + childrenD: Seq[Node] => A): A = { + this match { + case RegexLeaf(regex) => regexF(regex) + case ParentNode(children) => childrenF(children) + case DisjunctNode(children) => childrenD(children) + } + } + } + + /** A leaf regex, without any subgroups/ */ + private final case class RegexLeaf(regex: String) extends NodeType + + /** A parent grouping, with children nodes. + * + * Modifiers to this group, such as star or plus, can be added using the + * field of `Node` `originalGroup`. + */ + private final case class ParentNode(children: Seq[Node]) extends NodeType + + /** A parent grouping with children nodes which are in a disjunction. */ + private final case class DisjunctNode(children: Seq[Node]) extends NodeType + + /** Creates a ParentNode, but in the presence of disjunctions, split at the + * disjunctions to create a DisjunctNode. + */ + private object CreateParentNode { + @tailrec + private def splitWhereAux[A](in: List[A], splitter: A => Boolean, + res: List[List[A]], acc: List[A]): List[List[A]] = { + in match { + case Nil => + (acc.reverse :: res).reverse + case head :: tail => + if (splitter(head)) + splitWhereAux(tail, splitter, acc.reverse :: res, Nil) + else + splitWhereAux(tail, splitter, res, head :: acc) + } + } + + def splitWhere[A](in: List[A], splitter: A => Boolean): List[List[A]] = + splitWhereAux(in, splitter, Nil, Nil) + + def apply(children: Seq[Node]): NodeType = { + val disjuncts = splitWhere(children.toList, + (c: Node) => c.nodeType == RegexLeaf("|")) + if (disjuncts.length == 1) + ParentNode(children) + else + DisjunctNode(disjuncts.map(Node(_))) + } + } + + private def isBackReference(r: String): Boolean = + r.length >= 2 && r(0) == '\\' && r.tail.forall(_.isDigit) + + private object BackReferenceLeaf { + def unapply(leaf: RegexLeaf): Option[Int] = { + val r = leaf.regex + if (isBackReference(r)) Some(r.substring(1).toInt) + else None + } + } + + private object Node { + def apply(originalGroup: OriginalRegex, nodeType: NodeType): Node = + new Node(originalGroup, nodeType) + + def apply(regex: String): Node = + new Node(OriginallyWrapped("", ""), RegexLeaf(regex)) + + def apply(nodes: Seq[Node]): Node = + new Node(OriginallyWrapped("", ""), CreateParentNode(nodes)) + + def disjunct(nodes: Seq[Node]): Node = + new Node(OriginallyWrapped("", ""), DisjunctNode(nodes)) + + def unapply(n: Node): Option[(OriginalRegex, NodeType)] = + Some((n.originalGroup, n.nodeType)) + } + + private object UnwrappedRegexLeaf { + def unapply(n: Node): Option[String] = n match { + case Node(OriginallyWrapped("", ""), RegexLeaf(r)) => Some(r) + case _ => None + } + } + + /** Node of the regex tree. + * + * @param originalGroup + * Either the 1-based index of the original group that this node encloses, + * or the modifiers which are present before and after (ex: `?`, `*?`, + * `(?=...)`, `(?!..)`). + * @param nodeType + * The type of the node (Regexleaf, or ParentNode). + * This is a var because we need to shift the backreference groups. + */ + private final class Node(val originalGroup: OriginalRegex, + var nodeType: NodeType) { + + var newGroup: Int = 0 // Assigned later after the tree of nodes is built + var matched: String = "" // Assigned later after the new regexp matches + var start: Int = 0 // Assigned later after recovering the tree matches + + override def toString(): String = + "Node(" + originalGroup + ", " + nodeType + ")" + + def transformGroupNumber(mapping: Map[Int, Int]): this.type = { + nodeType match { + case BackReferenceLeaf(reference) => + nodeType = RegexLeaf("\\" + mapping.get(reference).getOrElse(0)) + case RegexLeaf(regex) => + // do nothing + case ParentNode(children) => + children.foreach(_.transformGroupNumber(mapping)) + case DisjunctNode(children) => + children.foreach(_.transformGroupNumber(mapping)) + } + this + } + + /** Assigns consecutive group numbers starting from newGroupIndex to the + * nodes in this subtree, in a pre-order walk. + * + * @return 1 plus the largest assigned group number. + */ + def setNewGroup(index: Int): Int = { + newGroup = index + nodeType.fold( + r => index + 1, + children => children.foldLeft(index + 1) { + case (newIndex, child) => child.setNewGroup(newIndex) + }, + children => children.foldLeft(index + 1) { + case (newIndex, child) => child.setNewGroup(newIndex) + } + ) + } + + /** Recursively matched groups from a match of this regular expression to + * the field matched of each node. + * + * If a group did not match, stringForGroupNumber can return null. + * This is consistent with JVM regexs. + */ + def setMatch(stringForGroupNumber: Int => String): Unit = { + this.matched = stringForGroupNumber(newGroup) + nodeType.fold( + r => (), + children => children.foreach(_.setMatch(stringForGroupNumber)), + children => children.foreach(_.setMatch(stringForGroupNumber)) + ) + } + + /* When assigning group positions. I could not choose between assigning + * group numbers from left to right or from right to left, because there + * both failed in one case each. Normally, both directions give the same + * result. But there are corner cases. + * + * Consider the following regex matching `abbbbbbc` + * + * (?=ab*(c))ab + * + * After conversion, this becomes: + * + * (?=(ab*)(c))(ab) + * + * To recover the position of the group (c), we cannot do anything but + * compute it from the length of (ab*), that is, propagate the start, + * compute the length, and return the end, and this, recursively. This is + * what we need to do in a forward-matching regex. + * + * However, consider the following regex matching `abcbdbe` + * + * a(b.)* + * + * After conversion, it is transformed to: + * + * (a)((b.)*) + * + * The semantics of group matching under a star are that the last match is + * kept. Therefore, we cannot obtain the start position of (b.) from + * propagating lengths from left to right. What we first do is to get the + * start, then the end, of the group `((b.)*)`, and then we propagate this + * end to the inner group. + * + * Note that when javascript will support back-matching `(?<= )` and + * `(? (), + children => children.foldLeft(start) { + case (newStart, child) => child.setStartReturnEnd(newStart) + }, + children => children.foreach { + case child => child.setStartReturnEnd(start) + } + ) + } + + /** Propagates the end position of this node to its descendants. */ + def propagateEnd(): Unit = { + nodeType.fold( + regex => (), + children => children.foldRight(end) { + case (child, newEnd) => child.setEndReturnStart(newEnd) + }, + children => children.foreach { + case child => child.setEndReturnStart(end) + } + ) + } + + def setEndReturnStart(newEnd: Int): Int = { + start = originalGroup match { + case OriginallyWrapped.Absolute() => + newEnd + case _ => + if (matched == null) -1 + else newEnd - matched.length + } + propagateStart() + start + } + + def setStartReturnEnd(offset: Int): Int = { + start = + if (matched == null) -1 + else offset + + originalGroup match { + case OriginallyWrapped.Repeater(_) => propagateEnd() + case _ => propagateStart() + } + originalGroup match { + case OriginallyWrapped.Absolute() => offset + case _ => end + } + } + + def end: Int = start + (if (matched == null) 0 else matched.length) + + def buildRegex: String = { + val leftRegex = originalGroup.fold( + groupNum => "(", + (left: String, right: String) => "((?:" + left + ) + val middleRegex = nodeType.fold( + regex => regex, + children => "(?:" + children.map(_.buildRegex).mkString + ")", + children => "(?:" + children.map(_.buildRegex).mkString("|") + ")" + ) + val rightRegex = originalGroup.fold( + groupNum => ")", + (left: String, right: String) => ")" + right + ")" + ) + leftRegex + middleRegex + rightRegex + } + + def getGroupNodeMap: Map[Int, Node] = { + val thisGroupNodeMap = originalGroup.fold( + groupNum => Map(groupNum -> this), + (_, _) => Map[Int, Node]() + ) + val childGroupNodeMap = nodeType.fold( + regex => Map[Int, Node](), + children => children.foldLeft(Map[Int, Node]()) { + case (mapping, child) => mapping ++ child.getGroupNodeMap + }, + children => children.foldLeft(Map[Int, Node]()) { + case (mapping, child) => mapping ++ child.getGroupNodeMap + } + ) + thisGroupNodeMap ++ childGroupNodeMap + } + + def simplify: Node = { + this match { + case Node(OriginallyGroupped(nextGroupIndex), + ParentNode(Seq(UnwrappedRegexLeaf(regex)))) => + Node(OriginallyGroupped(nextGroupIndex), RegexLeaf(regex)) + case _ => + this + } + } + } +} + +private[regex] class GroupStartMap(string: String, start: Int, pattern: Pattern) { + import GroupStartMap._ + import Pattern.{CASE_INSENSITIVE, MULTILINE} + + val mapping: Int => Int = { + val node = parseRegex(pattern.pattern()) + val flags = { + "g" + + (if ((pattern.flags() & CASE_INSENSITIVE) != 0) "i" else "") + + (if ((pattern.flags() & MULTILINE) != 0) "m" else "") + } + node.setNewGroup(1) + val groupNodeMap = node.getGroupNodeMap + node.transformGroupNumber(groupNodeMap.mapValues(_.newGroup)) + val allMatchingRegexStr = node.buildRegex + val allMatchingRegex = new js.RegExp(allMatchingRegexStr, flags) + allMatchingRegex.lastIndex = start + val allMatchResult = allMatchingRegex.exec(string) + if (allMatchResult == null) { + throw new Exception( + s"[Internal error] Executed '$allMatchingRegex' on " + + s"'$string' at position $start, got an error.\n" + + s"Original pattern '${pattern}' did match however.") + } + node.setMatch((x: Int) => allMatchResult(x).getOrElse(null)) + node.setStartReturnEnd(start) + groupNodeMap.mapValues(_.start) + } + + /** Wraps every consecutive chars and simple expressions in the regexp in a + * group to find the intermediate positions. + * + * Same for subgroups. + * + * Input example: (?:AB)C + * Output example: A node roughly representing (?:(AB))(?:(C)) + * Input example: (A(B))C(D) + * Output example: A node roughly representing (((A)(B))(C)(D)) + */ + private def parseRegex(pattern: String): Node = { + def parseClosingParenthesis(pIndex: Int) = pIndex + 1 + + // Returns the position just after the next ending brace + @tailrec def positionEndNextBrace(pIndex: Int): Int = { + if (pattern.length <= pIndex) pIndex + else if (pattern(pIndex) == '}') pIndex + 1 + else positionEndNextBrace(pIndex + 1) + } + + // Returns the position just after the next ending square bracket + @tailrec def positionEndSquareBracket(pIndex: Int): Int = { + if (pattern.length <= pIndex) + pIndex + else if (pattern(pIndex) == '\\' && pattern.length > 1) + positionEndSquareBracket(pIndex + 2) + else if (pattern(pIndex) == ']') + pIndex + 1 + else + positionEndSquareBracket(pIndex + 1) + } + + @tailrec def positionAfterLastDigit(pIndex: Int): Int = { + if (pIndex < pattern.length && pattern(pIndex).isDigit) + positionAfterLastDigit(pIndex + 1) + else + pIndex + } + + /* Returns a sequence of nodes, the remaining non-parsed, and the next + * group index. + * - Takes care of escaped parentheses \( and \). + * - Takes care of non-group parenthesis (?:). + */ + def parse(pIndex: Int, nextGroupIndex: Int): (Seq[Node], Int, Int) = { + if (pIndex >= pattern.length) { + (Seq(), pIndex, nextGroupIndex) + } else { + def simplify(nodes: Seq[Node]): Seq[Node] = nodes match { + case UnwrappedRegexLeaf(r1) +: UnwrappedRegexLeaf(r2) +: tail + if !isBackReference(r1) && r1 != "|" && !isBackReference(r2) && r2 != "|" => + simplify(Node(r1 + r2) +: tail) + + case n +: Node(OriginallyWrapped.Repeater(modifier), RegexLeaf("")) +: tail => + n match { + case Node(OriginallyWrapped(left, right), m) => + simplify(Node(OriginallyWrapped(left, right + modifier), m) +: tail) + case n @ Node(OriginallyGroupped(_), m) => + simplify(Node(OriginallyWrapped("", modifier), ParentNode(Seq(n))) +: tail) + } + + case _ => + nodes + } + + def addSiblings(node: Node, remaining: Int, + nextGroupIndex: Int): (Seq[Node], Int, Int) = { + val (siblings, finalRemaining, finalGroupIndex) = + parse(remaining, nextGroupIndex) + (simplify(node +: siblings), finalRemaining, finalGroupIndex) + } + + def default = { + val e = pattern(pIndex) + addSiblings(Node(e + ""), pIndex + 1, nextGroupIndex) + } + + (pattern(pIndex): @switch) match { + case '(' => + if (pattern.length >= pIndex + 3 && pattern(pIndex + 1) == '?' && + (pattern(pIndex + 2) == '=' || pattern(pIndex + 2) == '!')) { + // Non-capturing test group + val (parsed, remaining, newNextGroupIndex) = + parse(pIndex + 3, nextGroupIndex) + val remaining1 = parseClosingParenthesis(remaining) + addSiblings( + Node(OriginallyWrapped("(?" + pattern(pIndex + 2), ")"), + CreateParentNode(parsed)), + remaining1, newNextGroupIndex) + } else if (pattern.length < pIndex + 3 || + pattern(pIndex + 1) != '?' ||pattern(pIndex + 2) != ':') { + // Capturing group + val (parsed, remaining, newNextGroupIndex) = + parse(pIndex + 1, nextGroupIndex + 1) + val remaining1 = parseClosingParenthesis(remaining) + addSiblings( + Node(OriginallyGroupped(nextGroupIndex), + CreateParentNode(parsed)).simplify, + remaining1, newNextGroupIndex) + } else if (pattern.length >= pIndex + 3 && + pattern(pIndex + 1) == '?' && pattern(pIndex + 2) == ':') { + // Non-capturing group + val (parsedNodes, remaining, newNextGroupIndex) = + parse(pIndex + 3, nextGroupIndex) + val remaining1 = parseClosingParenthesis(remaining) + addSiblings(Node(parsedNodes).simplify, remaining1, + newNextGroupIndex) + } else { + // Should not happen + default + } + + case ')' => + (Seq(), pIndex, nextGroupIndex) + + case '\\' => + if (pattern.length >= pIndex + 2) { + val nextIndex = + if (pattern(pIndex + 1).isDigit) positionAfterLastDigit(pIndex + 1) + else pIndex + 2 + val regexPart = pattern.substring(pIndex, nextIndex) + addSiblings(Node(regexPart), nextIndex, nextGroupIndex) + } else { + // No escaped char, but this should not be called + default + } + + case '+' | '*' | '?' => // greedy or not greedy + val nextIndex = + if (pattern.length >= pIndex + 2 && pattern(pIndex + 1) == '?') pIndex + 2 + else pIndex + 1 + val repeater = pattern.substring(pIndex, nextIndex) + addSiblings( + Node(OriginallyWrapped("", repeater), RegexLeaf("")), + nextIndex, nextGroupIndex) + + case '{' => + // parse until end of occurrence + val nextIndex = positionEndNextBrace(pIndex + 1) + val repeater = pattern.substring(pIndex, nextIndex) + addSiblings( + Node(OriginallyWrapped("", repeater), RegexLeaf("")), + nextIndex, nextGroupIndex) + + case '[' => + val remaining = positionEndSquareBracket(pIndex + 1) + val inside = pattern.substring(pIndex, remaining) + addSiblings(Node(inside), remaining, nextGroupIndex) + + case _ => + default + } + } + } + + parse(0, 1)._1 match { + case Nil => Node("") + case Seq(n) => n + case children => Node(children) + } + } +} diff --git a/javalib/src/main/scala/java/util/regex/Matcher.scala b/javalib/src/main/scala/java/util/regex/Matcher.scala index f1b9127ad3..53f4c3a45d 100644 --- a/javalib/src/main/scala/java/util/regex/Matcher.scala +++ b/javalib/src/main/scala/java/util/regex/Matcher.scala @@ -58,6 +58,7 @@ final class Matcher private[regex] ( } else { canStillFind = false } + startOfGroupCache = None lastMatch ne null } else false @@ -141,6 +142,7 @@ final class Matcher private[regex] ( lastMatchIsValid = false canStillFind = true appendPos = 0 + startOfGroupCache = None this } @@ -158,6 +160,7 @@ final class Matcher private[regex] ( regexp = pattern.newJSRegExp() regexp.lastIndex = prevLastIndex lastMatch = null + startOfGroupCache = None this } @@ -177,14 +180,7 @@ final class Matcher private[regex] ( def start(group: Int): Int = { if (group == 0) start() - else { - val last = ensureLastMatch - // not provided by JS RegExp, so we make up something that at least - // will have some sound behavior from scala.util.matching.Regex - last(group).fold(-1) { - groupStr => inputstr.indexOf(groupStr, last.index) - } - } + else startOfGroup(group) } def end(group: Int): Int = { @@ -202,7 +198,7 @@ final class Matcher private[regex] ( // Seal the state - def toMatchResult(): MatchResult = new SealedResult(inputstr, lastMatch) + def toMatchResult(): MatchResult = new SealedResult(inputstr, lastMatch, pattern()) // Other query state methods @@ -223,6 +219,18 @@ final class Matcher private[regex] ( def hasAnchoringBounds(): Boolean = true //def useAnchoringBounds(b: Boolean): Matcher + + // Lazily computed by `startOfGroup`, reset every time `lastMatch` changes + private var startOfGroupCache: Option[Int => Int] = None + + /** Returns a mapping from the group number to the respective start position. */ + private def startOfGroup: Int => Int = { + startOfGroupCache.getOrElse { + val mapping = GroupStartMap(inputstr, start, pattern0) + startOfGroupCache = Some(mapping) + mapping + } + } } object Matcher { @@ -241,7 +249,8 @@ object Matcher { } private final class SealedResult(inputstr: String, - lastMatch: js.RegExp.ExecResult) extends MatchResult { + lastMatch: js.RegExp.ExecResult, pattern: Pattern) + extends MatchResult { def groupCount(): Int = ensureLastMatch.length-1 @@ -249,17 +258,12 @@ object Matcher { def end(): Int = start() + group().length def group(): String = ensureLastMatch(0).get + private lazy val startOfGroup = + GroupStartMap(inputstr, ensureLastMatch.index, pattern) + def start(group: Int): Int = { if (group == 0) start() - else { - val last = ensureLastMatch - - // not provided by JS RegExp, so we make up something that at least - // will have some sound behavior from scala.util.matching.Regex - last(group).fold(-1) { - groupStr => inputstr.indexOf(groupStr, last.index) - } - } + else startOfGroup(group) } def end(group: Int): Int = { diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexMatcherTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexMatcherTest.scala index a437a57dea..37cbc4cb34 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexMatcherTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexMatcherTest.scala @@ -33,42 +33,139 @@ class RegexMatcherTest { } @Test def start_end_group_and_toMatchResult(): Unit = { - val matcher = Pattern.compile("\\s(([A-Za-z]{5}(hum)?).js)\\s").matcher("Write Scala.js everyday!") + val matcher = Pattern + .compile("\\s(([A-Za-z]{5}(hum)?).js)\\s") + .matcher("Write Scala.js everyday!") + checkGroups(matcher, + (5, 15, " Scala.js "), + (6, 14, "Scala.js"), + (6, 11, "Scala"), + (-1, -1, null) + ) + } - def checkGroup0(start: Int, end: Int, group: String): Unit = - checkGroup(start, 5, end, 15, group, " Scala.js ") + @Test def start_end_group_tricky_and_toMatchResult(): Unit = { + val matcher = Pattern + .compile("(Scala\\.js).*(Scala)$") + .matcher("Scala.js is a Scalable javascript compiler based on Scala") + checkGroups(matcher, + (0, 57, "Scala.js is a Scalable javascript compiler based on Scala"), + (0, 8, "Scala.js"), + (52, 57, "Scala") + ) + } - def checkGroup1(start: Int, end: Int, group: String): Unit = - checkGroup(start, 6, end, 14, group, "Scala.js") + @Test def start_end_group_matchnot_and_toMatchResult(): Unit = { + val matcher = Pattern + .compile("(?!Scala\\.js)(Scala)") + .matcher("There is a difference between Scala.js and Scala, but both are Scalable") + checkGroups(matcher, + (43, 48, "Scala"), + (43, 48, "Scala") + ) + checkGroups(matcher, + (63, 68, "Scala"), + (63, 68, "Scala") + ) + } + + @Test def start_end_group_multiple_and_toMatchResult(): Unit = { + val matcher = Pattern + .compile("(?=Scala\\.js is (nice|awesome))(Scala)\\.js") + .matcher("Scala.js is nice, Scala.js is awesome") + checkGroups(matcher, + (0, 8, "Scala.js"), + (12, 16, "nice"), + (0, 5, "Scala") + ) + checkGroups(matcher, + (18, 26, "Scala.js"), + (30, 37, "awesome"), + (18, 23, "Scala") + ) + } + + def parseExpect(regex: String, str: String, pos: (Int, Int)*): Unit = { + val matcher = Pattern.compile(regex).matcher(str) + assertTrue(matcher.find()) + assertEquals(pos.length - 1, matcher.groupCount) + var i = 0 + val tmp = pos.iterator + while (tmp.hasNext) { + assertEquals(tmp.next, (matcher.start(i), matcher.end(i))) + i += 1 + } + } - def checkGroup2(start: Int, end: Int, group: String): Unit = - checkGroup(start, 6, end, 11, group, "Scala") + @Test def parseRegex_test(): Unit = { + parseExpect("aa", "aa", 0 -> 2) + parseExpect("a(a)", "aa", 0 -> 2, 1 -> 2) + parseExpect("ABC(A(B))(C)", "ABCABC", 0 -> 6, 3 -> 5, 4 -> 5, 5 -> 6) + parseExpect("A(?:A)", "AA", 0 -> 2) + parseExpect("A(?:(\\d))", "A1", 0 -> 2, 1 -> 2) + parseExpect("A((?:A))", "AA", 0 -> 2, 1 -> 2) + parseExpect("ab((ab))", "abab", 0 -> 4, 2 -> 4, 2 -> 4) + parseExpect("hum(hum)?", "humhum", 0 -> 6, 3 -> 6) + parseExpect("hum(hum)?", "hum", 0 -> 3, -1 -> -1) + parseExpect("hum(?=hum)", "humhum", 0 -> 3) + parseExpect("hum(?!hum)", "humhumhuf", 3 -> 6) + parseExpect("hum(?=h(um))", "humhum", 0 -> 3, 4 -> 6) + parseExpect("abab(ab){1,2}", "abababab", 0 -> 8, 6 -> 8) + parseExpect("abab(ab){1,2}(abc){1,2}", "abababababcabc", 0 -> 14, 6 -> 8, 11 -> 14) + parseExpect("ab(ab)?ab(?=aba)(ab)*", "abababababa", 0 -> 10, 2 -> 4, 8 -> 10) + parseExpect("ab(?=aba)ab(aba)?(ab)*", "abababababa", 0 -> 7, 4 -> 7, -1 -> -1) + parseExpect("ab(?=aba)ab(aba)??(ab)*","abababababa", 0 -> 10, -1 -> -1, 8 -> 10) + parseExpect("abab(ab){1,2}?", "abababab", 0 -> 6, 4 -> 6) + parseExpect("ab(?:ab)*", "abababab", 0 -> 8) + if (!executingInJVM) { + parseExpect("ab(?:a(c))*ac", "abacacac", 0 -> 8, 5 -> 6) + parseExpect("ab(?:a(c))+ac", "abacacac", 0 -> 8, 5 -> 6) + } + parseExpect("ab(?:ac)*?ac", "abacacac", 0 -> 4) + parseExpect("ab(?:ac)+?ac", "abacacac", 0 -> 6) + parseExpect("ab((?=abab(ab))a(b))*a", "abababab", 0 -> 5, 2 -> 4, 6 -> 8, 3 -> 4) + } - def checkGroup3(start: Int, end: Int, group: String): Unit = - checkGroup(start, -1, end, -1, group, null) + @Test def parseRegex_backgroups_test(): Unit = { + parseExpect("bc(.c).c(\\1)", "bczcxczc", 0 -> 8, 2 -> 4, 6 -> 8) + parseExpect("(bc(.c).c)(\\2)", "bczcxczc", 0 -> 8, 0 -> 6, 2 -> 4, 6 -> 8) + } - def checkGroup(start: Int, startExpected: Int, end: Int, endExpected: Int, - group: String, groupExpected: String): Unit = { - assertEquals(startExpected, start) - assertEquals(endExpected, end) - assertEquals(groupExpected, group) + @Test def parseRegex_disjunctions_test(): Unit = { + parseExpect("a(b)|b(c)", "ab", 0 -> 2, 1 -> 2, -1 -> -1) + parseExpect("a(b)|b(c)", "bc", 0 -> 2, -1 -> -1, 1 -> 2) + if (!executingInJVM) { + parseExpect("az(a(.)|b(.))+aw", "aza1b2b3aw", + 0 -> 10, 6 -> 8, -1 -> -1, 7 -> 8) + } else { + parseExpect("az(a(.)|b(.))+aw", "aza1b2b3aw", + 0 -> 10, 6 -> 8, 3 -> 4, 7 -> 8) } + } + def checkGroups(matcher: Matcher, startEndMatch: (Int, Int, String)*): Unit = { assertTrue(matcher.find()) - assertEquals(3, matcher.groupCount) - checkGroup0(matcher.start, matcher.end, matcher.group) - checkGroup0(matcher.start(0), matcher.end(0), matcher.group(0)) - checkGroup1(matcher.start(1), matcher.end(1), matcher.group(1)) - checkGroup2(matcher.start(2), matcher.end(2), matcher.group(2)) - checkGroup3(matcher.start(3), matcher.end(3), matcher.group(3)) + + assertEquals(startEndMatch(0)._1, matcher.start) + assertEquals(startEndMatch(0)._2, matcher.end) + assertEquals(startEndMatch(0)._3, matcher.group) + assertEquals(startEndMatch.size - 1, matcher.groupCount) + for (((start, end, mtch), i) <- startEndMatch.zipWithIndex) { + assertEquals(start, matcher.start(i)) + assertEquals(end, matcher.end(i)) + assertEquals(mtch, matcher.group(i)) + } val matchResult = matcher.toMatchResult - assertEquals(3, matchResult.groupCount) - checkGroup0(matchResult.start, matchResult.end, matchResult.group) - checkGroup0(matchResult.start(0), matchResult.end(0), matchResult.group(0)) - checkGroup1(matchResult.start(1), matchResult.end(1), matchResult.group(1)) - checkGroup2(matchResult.start(2), matchResult.end(2), matchResult.group(2)) - checkGroup3(matchResult.start(3), matchResult.end(3), matchResult.group(3)) + assertEquals(startEndMatch.size - 1, matchResult.groupCount) + assertEquals(startEndMatch(0)._1, matchResult.start) + assertEquals(startEndMatch(0)._2, matchResult.end) + assertEquals(startEndMatch(0)._3, matchResult.group) + for (((start, end, mtch), i) <- startEndMatch.zipWithIndex) { + assertEquals(start, matchResult.start(i)) + assertEquals(end, matchResult.end(i)) + assertEquals(mtch, matchResult.group(i)) + } } @Test def matches(): Unit = { From 7e8433b58fbbdf11f344cf2ed23e4a957f57b728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 10 Oct 2017 12:07:44 +0200 Subject: [PATCH 0503/2665] Allow to load the build on JDK 9. We put all our build-level `.scala` files in a `package build`, rather than in the default package, to work around https://github.com/scala/scala-dev/issues/304. This does not yet allow to build the test suite. --- build.sbt | 2 ++ project/BinaryIncompatibilities.scala | 2 ++ project/Build.scala | 16 ++++++---------- project/ExternalCompile.scala | 2 ++ project/JavaLangObject.scala | 2 ++ project/JavaLangString.scala | 2 ++ project/build.sbt | 2 +- project/project/ScalaJSEnvGenerator.scala | 2 ++ 8 files changed, 19 insertions(+), 11 deletions(-) diff --git a/build.sbt b/build.sbt index 85e48571c7..9ba9e248fa 100644 --- a/build.sbt +++ b/build.sbt @@ -1,3 +1,5 @@ +import build.Build + val scalajs = Build.root val ir = Build.irProject val irJS = Build.irProjectJS diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index c77318b933..2984c20d1b 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -1,3 +1,5 @@ +package build + import com.typesafe.tools.mima.core._ import com.typesafe.tools.mima.core.ProblemFilters._ diff --git a/project/Build.scala b/project/Build.scala index 99397eabd2..3ec3530a20 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1,3 +1,5 @@ +package build + import sbt._ import Keys._ @@ -436,16 +438,10 @@ object Build { ), // JDK version we are running with javaVersion in Global := { - val v = System.getProperty("java.version") - v.substring(0, 3) match { - case "1.8" => 8 - case "1.7" => 7 - case "1.6" => 6 - - case _ => - sLog.value.warn(s"Unknown JDK version $v. Assuming max compat.") - Int.MaxValue - } + val fullVersion = System.getProperty("java.version") + val v = fullVersion.stripPrefix("1.").takeWhile(_.isDigit).toInt + sLog.value.info(s"Detected JDK version $v") + v } ) diff --git a/project/ExternalCompile.scala b/project/ExternalCompile.scala index 4c9018d341..006673e1d4 100644 --- a/project/ExternalCompile.scala +++ b/project/ExternalCompile.scala @@ -1,3 +1,5 @@ +package build + import sbt._ import Keys._ diff --git a/project/JavaLangObject.scala b/project/JavaLangObject.scala index 954cd4bb94..980344ef62 100644 --- a/project/JavaLangObject.scala +++ b/project/JavaLangObject.scala @@ -1,3 +1,5 @@ +package build + /* * Hard-coded IR for java.lang.Object. */ diff --git a/project/JavaLangString.scala b/project/JavaLangString.scala index b0509ec40a..12fad6f1aa 100644 --- a/project/JavaLangString.scala +++ b/project/JavaLangString.scala @@ -1,3 +1,5 @@ +package build + /* * Hard-coded IR for java.lang.String. */ diff --git a/project/build.sbt b/project/build.sbt index 01a80cd7c6..c617bd52e6 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -38,7 +38,7 @@ sources in Compile += baseDirectory.value / "project" / "ScalaJSEnvGenerator.scala" sourceGenerators in Compile += Def.task { - ScalaJSEnvGenerator.generateEnvHolder( + build.ScalaJSEnvGenerator.generateEnvHolder( baseDirectory.value.getParentFile / "tools", (sourceManaged in Compile).value) }.taskValue diff --git a/project/project/ScalaJSEnvGenerator.scala b/project/project/ScalaJSEnvGenerator.scala index c73e7e7301..a8457c0be2 100644 --- a/project/project/ScalaJSEnvGenerator.scala +++ b/project/project/ScalaJSEnvGenerator.scala @@ -1,3 +1,5 @@ +package build + import sbt._ object ScalaJSEnvGenerator { From 157add373fffd856da504e8674ff7b3e3c8c45f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 10 Oct 2017 16:51:34 +0200 Subject: [PATCH 0504/2665] Adapt the codebase to changes in nio Buffers in Java 9. First, several methods of `nio.Buffer` are now overridden in specific subclasses so that they return a more specific type. For example, `Buffer.position(int)` is overridden in `ByteBuffer` to return a `ByteBuffer`, allowing chained invocations. This obviously means we had to add those overrides in our javalib, so that they can link. Indeed, the overrides have a different binary signature. In addition, because of https://github.com/scala/bug/issues/10418, we also have to call `position()` and `limit()` instead of `position` and `limit`, respectively. Lastly, the methods `slice()` and `duplicate()` now have an abstract definition in `Buffer`, which broken source compatibility of the `BufferAdapter`s in our test suite. We fix this by renaming the methods to `sliceChain()` and `duplicateChain()` in the adapters. --- .../scala/java/io/InputStreamReader.scala | 18 +- .../scala/java/io/OutputStreamWriter.scala | 4 +- javalib/src/main/scala/java/io/Reader.scala | 4 +- javalib/src/main/scala/java/nio/Buffer.scala | 14 +- .../src/main/scala/java/nio/ByteBuffer.scala | 35 ++++ .../src/main/scala/java/nio/CharBuffer.scala | 43 ++++- .../scala/java/nio/DataViewCharBuffer.scala | 2 +- .../main/scala/java/nio/DoubleBuffer.scala | 35 ++++ .../src/main/scala/java/nio/FloatBuffer.scala | 35 ++++ .../scala/java/nio/GenDataViewBuffer.scala | 4 +- .../scala/java/nio/GenHeapBufferView.scala | 4 +- .../scala/java/nio/GenTypedArrayBuffer.scala | 4 +- .../java/nio/HeapByteBufferCharView.scala | 2 +- .../main/scala/java/nio/HeapCharBuffer.scala | 2 +- .../src/main/scala/java/nio/IntBuffer.scala | 35 ++++ .../src/main/scala/java/nio/LongBuffer.scala | 35 ++++ .../src/main/scala/java/nio/ShortBuffer.scala | 35 ++++ .../scala/java/nio/StringCharBuffer.scala | 6 +- .../scala/java/nio/TypedArrayByteBuffer.scala | 10 +- .../scala/java/nio/TypedArrayCharBuffer.scala | 2 +- .../java/nio/charset/CharsetDecoder.scala | 4 +- .../java/nio/charset/CharsetEncoder.scala | 4 +- .../ISO_8859_1_And_US_ASCII_Common.scala | 18 +- .../scalajs/niocharset/UTF_16_Common.scala | 20 +-- .../scala/scalajs/niocharset/UTF_8.scala | 20 +-- .../testsuite/niobuffer/BaseBufferTest.scala | 4 +- .../testsuite/niobuffer/BufferAdapter.scala | 39 ++-- .../testsuite/niobuffer/BufferFactory.scala | 4 +- .../testsuite/niobuffer/ByteBufferTest.scala | 168 +++++++++--------- .../testsuite/niocharset/UTF16Test.scala | 2 +- 30 files changed, 432 insertions(+), 180 deletions(-) diff --git a/javalib/src/main/scala/java/io/InputStreamReader.scala b/javalib/src/main/scala/java/io/InputStreamReader.scala index f55ebe21a0..86710021f5 100644 --- a/javalib/src/main/scala/java/io/InputStreamReader.scala +++ b/javalib/src/main/scala/java/io/InputStreamReader.scala @@ -127,10 +127,10 @@ class InputStreamReader(private[this] var in: InputStream, @tailrec private def readImpl(out: CharBuffer): Int = { - val initPos = out.position + val initPos = out.position() val result = decoder.decode(inBuf, out, endOfInput) - if (out.position != initPos) { + if (out.position() != initPos) { /* Good, we made progress, so we can return. * Note that the `result` does not matter. Whether it's an underflow, * an overflow, or even an error, if we read *something*, we can return @@ -139,7 +139,7 @@ class InputStreamReader(private[this] var in: InputStream, * which will necessarily return the same result (but without advancing * at all), which will cause one of the following cases to be handled. */ - out.position - initPos + out.position() - initPos } else if (result.isUnderflow) { if (endOfInput) { assert(!inBuf.hasRemaining, @@ -151,12 +151,12 @@ class InputStreamReader(private[this] var in: InputStream, InputStreamReader.Overflow } else { // Done - if (out.position == initPos) -1 - else out.position - initPos + if (out.position() == initPos) -1 + else out.position() - initPos } } else { // We need to read more from the underlying input stream - if (inBuf.limit == inBuf.capacity) { + if (inBuf.limit() == inBuf.capacity) { inBuf.compact() if (!inBuf.hasRemaining) { throw new AssertionError( @@ -165,7 +165,7 @@ class InputStreamReader(private[this] var in: InputStream, getEncoding + " to decode a single code point. " + "Please report this as a bug.") } - inBuf.limit(inBuf.position) + inBuf.limit(inBuf.position()) inBuf.position(0) } @@ -174,12 +174,12 @@ class InputStreamReader(private[this] var in: InputStream, * according to the specification of InputStreamReader. */ val bytesRead = - in.read(inBuf.array, inBuf.limit, inBuf.capacity - inBuf.limit) + in.read(inBuf.array, inBuf.limit, inBuf.capacity - inBuf.limit()) if (bytesRead == -1) endOfInput = true else - inBuf.limit(inBuf.limit + bytesRead) + inBuf.limit(inBuf.limit() + bytesRead) readImpl(out) } diff --git a/javalib/src/main/scala/java/io/OutputStreamWriter.scala b/javalib/src/main/scala/java/io/OutputStreamWriter.scala index 6b93fdd9f9..0ca43531d8 100644 --- a/javalib/src/main/scala/java/io/OutputStreamWriter.scala +++ b/javalib/src/main/scala/java/io/OutputStreamWriter.scala @@ -134,7 +134,7 @@ class OutputStreamWriter(private[this] var out: OutputStream, } private def makeRoomInOutBuf(): Unit = { - if (outBuf.position != 0) { + if (outBuf.position() != 0) { flushBuffer() } else { // Very unlikely (outBuf.capacity is not enough to encode a single code point) @@ -153,7 +153,7 @@ class OutputStreamWriter(private[this] var out: OutputStream, // Don't use outBuf.flip() first, in case out.write() throws // Hence, use 0 instead of position, and position instead of limit - out.write(outBuf.array, outBuf.arrayOffset, outBuf.position) + out.write(outBuf.array, outBuf.arrayOffset, outBuf.position()) outBuf.clear() } diff --git a/javalib/src/main/scala/java/io/Reader.scala b/javalib/src/main/scala/java/io/Reader.scala index 97be140884..cdef02b25e 100644 --- a/javalib/src/main/scala/java/io/Reader.scala +++ b/javalib/src/main/scala/java/io/Reader.scala @@ -14,9 +14,9 @@ abstract class Reader private[this] (_lock: Option[Object]) if (!target.hasRemaining) 0 else if (target.hasArray) { val charsRead = read(target.array, - target.position + target.arrayOffset, target.remaining) + target.position() + target.arrayOffset, target.remaining) if (charsRead != -1) - target.position(target.position + charsRead) + target.position(target.position() + charsRead) charsRead } else { val buf = new Array[Char](target.remaining) diff --git a/javalib/src/main/scala/java/nio/Buffer.scala b/javalib/src/main/scala/java/nio/Buffer.scala index 15c556df70..6634324e34 100644 --- a/javalib/src/main/scala/java/nio/Buffer.scala +++ b/javalib/src/main/scala/java/nio/Buffer.scala @@ -21,7 +21,7 @@ abstract class Buffer private[nio] (val _capacity: Int) { final def position(): Int = _position - final def position(newPosition: Int): Buffer = { + def position(newPosition: Int): Buffer = { if (newPosition < 0 || newPosition > limit()) throw new IllegalArgumentException _position = newPosition @@ -32,7 +32,7 @@ abstract class Buffer private[nio] (val _capacity: Int) { final def limit(): Int = _limit - final def limit(newLimit: Int): Buffer = { + def limit(newLimit: Int): Buffer = { if (newLimit < 0 || newLimit > capacity()) throw new IllegalArgumentException _limit = newLimit @@ -44,33 +44,33 @@ abstract class Buffer private[nio] (val _capacity: Int) { this } - final def mark(): Buffer = { + def mark(): Buffer = { _mark = _position this } - final def reset(): Buffer = { + def reset(): Buffer = { if (_mark == -1) throw new InvalidMarkException _position = _mark this } - final def clear(): Buffer = { + def clear(): Buffer = { _mark = -1 _position = 0 _limit = capacity this } - final def flip(): Buffer = { + def flip(): Buffer = { _mark = -1 _limit = _position _position = 0 this } - final def rewind(): Buffer = { + def rewind(): Buffer = { _mark = -1 _position = 0 this diff --git a/javalib/src/main/scala/java/nio/ByteBuffer.scala b/javalib/src/main/scala/java/nio/ByteBuffer.scala index 65f11ee9b2..d2a65130ab 100644 --- a/javalib/src/main/scala/java/nio/ByteBuffer.scala +++ b/javalib/src/main/scala/java/nio/ByteBuffer.scala @@ -83,6 +83,41 @@ abstract class ByteBuffer private[nio] ( @inline final def arrayOffset(): Int = GenBuffer(this).generic_arrayOffset() + @inline override def position(newPosition: Int): ByteBuffer = { + super.position(newPosition) + this + } + + @inline override def limit(newLimit: Int): ByteBuffer = { + super.limit(newLimit) + this + } + + @inline override def mark(): ByteBuffer = { + super.mark() + this + } + + @inline override def reset(): ByteBuffer = { + super.reset() + this + } + + @inline override def clear(): ByteBuffer = { + super.clear() + this + } + + @inline override def flip(): ByteBuffer = { + super.flip() + this + } + + @inline override def rewind(): ByteBuffer = { + super.rewind() + this + } + def compact(): ByteBuffer def isDirect(): Boolean diff --git a/javalib/src/main/scala/java/nio/CharBuffer.scala b/javalib/src/main/scala/java/nio/CharBuffer.scala index ba6228ab3b..3a8be3af24 100644 --- a/javalib/src/main/scala/java/nio/CharBuffer.scala +++ b/javalib/src/main/scala/java/nio/CharBuffer.scala @@ -46,7 +46,7 @@ abstract class CharBuffer private[nio] ( target.put(_array, _arrayOffset, n) n } else { - val savedPos = position + val savedPos = position() target.put(this) position(savedPos) n @@ -100,6 +100,41 @@ abstract class CharBuffer private[nio] ( @inline final def arrayOffset(): Int = GenBuffer(this).generic_arrayOffset() + @inline override def position(newPosition: Int): CharBuffer = { + super.position(newPosition) + this + } + + @inline override def limit(newLimit: Int): CharBuffer = { + super.limit(newLimit) + this + } + + @inline override def mark(): CharBuffer = { + super.mark() + this + } + + @inline override def reset(): CharBuffer = { + super.reset() + this + } + + @inline override def clear(): CharBuffer = { + super.clear() + this + } + + @inline override def flip(): CharBuffer = { + super.flip() + this + } + + @inline override def rewind(): CharBuffer = { + super.rewind() + this + } + def compact(): CharBuffer def isDirect(): Boolean @@ -119,10 +154,10 @@ abstract class CharBuffer private[nio] ( override def toString(): String = { if (_array != null) { // even if read-only - new String(_array, position + _arrayOffset, remaining) + new String(_array, position() + _arrayOffset, remaining) } else { val chars = new Array[Char](remaining) - val savedPos = position + val savedPos = position() get(chars) position(savedPos) new String(chars) @@ -131,7 +166,7 @@ abstract class CharBuffer private[nio] ( final def length(): Int = remaining - final def charAt(index: Int): Char = get(position + index) + final def charAt(index: Int): Char = get(position() + index) def subSequence(start: Int, end: Int): CharSequence diff --git a/javalib/src/main/scala/java/nio/DataViewCharBuffer.scala b/javalib/src/main/scala/java/nio/DataViewCharBuffer.scala index ef029a9a1e..90641d2ed5 100644 --- a/javalib/src/main/scala/java/nio/DataViewCharBuffer.scala +++ b/javalib/src/main/scala/java/nio/DataViewCharBuffer.scala @@ -34,7 +34,7 @@ private[nio] final class DataViewCharBuffer private ( if (start < 0 || end < start || end > remaining) throw new IndexOutOfBoundsException new DataViewCharBuffer(_dataView, - position + start, position + end, isReadOnly, isBigEndian) + position() + start, position() + end, isReadOnly, isBigEndian) } @noinline diff --git a/javalib/src/main/scala/java/nio/DoubleBuffer.scala b/javalib/src/main/scala/java/nio/DoubleBuffer.scala index cf017248f7..a36939d322 100644 --- a/javalib/src/main/scala/java/nio/DoubleBuffer.scala +++ b/javalib/src/main/scala/java/nio/DoubleBuffer.scala @@ -72,6 +72,41 @@ abstract class DoubleBuffer private[nio] ( @inline final def arrayOffset(): Int = GenBuffer(this).generic_arrayOffset() + @inline override def position(newPosition: Int): DoubleBuffer = { + super.position(newPosition) + this + } + + @inline override def limit(newLimit: Int): DoubleBuffer = { + super.limit(newLimit) + this + } + + @inline override def mark(): DoubleBuffer = { + super.mark() + this + } + + @inline override def reset(): DoubleBuffer = { + super.reset() + this + } + + @inline override def clear(): DoubleBuffer = { + super.clear() + this + } + + @inline override def flip(): DoubleBuffer = { + super.flip() + this + } + + @inline override def rewind(): DoubleBuffer = { + super.rewind() + this + } + def compact(): DoubleBuffer def isDirect(): Boolean diff --git a/javalib/src/main/scala/java/nio/FloatBuffer.scala b/javalib/src/main/scala/java/nio/FloatBuffer.scala index 4bcfe6d3f0..8f319b6f9c 100644 --- a/javalib/src/main/scala/java/nio/FloatBuffer.scala +++ b/javalib/src/main/scala/java/nio/FloatBuffer.scala @@ -72,6 +72,41 @@ abstract class FloatBuffer private[nio] ( @inline final def arrayOffset(): Int = GenBuffer(this).generic_arrayOffset() + @inline override def position(newPosition: Int): FloatBuffer = { + super.position(newPosition) + this + } + + @inline override def limit(newLimit: Int): FloatBuffer = { + super.limit(newLimit) + this + } + + @inline override def mark(): FloatBuffer = { + super.mark() + this + } + + @inline override def reset(): FloatBuffer = { + super.reset() + this + } + + @inline override def clear(): FloatBuffer = { + super.clear() + this + } + + @inline override def flip(): FloatBuffer = { + super.flip() + this + } + + @inline override def rewind(): FloatBuffer = { + super.rewind() + this + } + def compact(): FloatBuffer def isDirect(): Boolean diff --git a/javalib/src/main/scala/java/nio/GenDataViewBuffer.scala b/javalib/src/main/scala/java/nio/GenDataViewBuffer.scala index fd7e0f6b22..172ea8fdc0 100644 --- a/javalib/src/main/scala/java/nio/GenDataViewBuffer.scala +++ b/javalib/src/main/scala/java/nio/GenDataViewBuffer.scala @@ -20,8 +20,8 @@ private[nio] object GenDataViewBuffer { byteBuffer: TypedArrayByteBuffer)( implicit newDataViewBuffer: NewDataViewBuffer[BufferType]): BufferType = { val byteArray = byteBuffer._typedArray - val byteBufferPos = byteBuffer.position - val byteBufferLimit = byteBuffer.limit + val byteBufferPos = byteBuffer.position() + val byteBufferLimit = byteBuffer.limit() val viewCapacity = (byteBufferLimit - byteBufferPos) / newDataViewBuffer.bytesPerElem val byteLength = viewCapacity * newDataViewBuffer.bytesPerElem diff --git a/javalib/src/main/scala/java/nio/GenHeapBufferView.scala b/javalib/src/main/scala/java/nio/GenHeapBufferView.scala index fb1eb5f392..8ef7206087 100644 --- a/javalib/src/main/scala/java/nio/GenHeapBufferView.scala +++ b/javalib/src/main/scala/java/nio/GenHeapBufferView.scala @@ -16,9 +16,9 @@ private[nio] object GenHeapBufferView { def generic_fromHeapByteBuffer[BufferType <: Buffer]( byteBuffer: HeapByteBuffer)( implicit newHeapBufferView: NewHeapBufferView[BufferType]): BufferType = { - val byteBufferPos = byteBuffer.position + val byteBufferPos = byteBuffer.position() val viewCapacity = - (byteBuffer.limit - byteBufferPos) / newHeapBufferView.bytesPerElem + (byteBuffer.limit() - byteBufferPos) / newHeapBufferView.bytesPerElem newHeapBufferView(viewCapacity, byteBuffer._array, byteBuffer._arrayOffset + byteBufferPos, 0, viewCapacity, byteBuffer.isReadOnly, byteBuffer.isBigEndian) diff --git a/javalib/src/main/scala/java/nio/GenTypedArrayBuffer.scala b/javalib/src/main/scala/java/nio/GenTypedArrayBuffer.scala index 00693a6f6b..347fbccd5f 100644 --- a/javalib/src/main/scala/java/nio/GenTypedArrayBuffer.scala +++ b/javalib/src/main/scala/java/nio/GenTypedArrayBuffer.scala @@ -21,8 +21,8 @@ private[nio] object GenTypedArrayBuffer { byteBuffer: TypedArrayByteBuffer)( implicit newTypedArrayBuffer: NewTypedArrayBuffer[BufferType]): BufferType = { val byteArray = byteBuffer._typedArray - val byteBufferPos = byteBuffer.position - val byteBufferLimit = byteBuffer.limit + val byteBufferPos = byteBuffer.position() + val byteBufferLimit = byteBuffer.limit() val viewCapacity = (byteBufferLimit - byteBufferPos) / newTypedArrayBuffer.bytesPerElem val viewTypedArray = newTypedArrayBuffer.newTypedArray( diff --git a/javalib/src/main/scala/java/nio/HeapByteBufferCharView.scala b/javalib/src/main/scala/java/nio/HeapByteBufferCharView.scala index ee14c4502b..9b44994a6f 100644 --- a/javalib/src/main/scala/java/nio/HeapByteBufferCharView.scala +++ b/javalib/src/main/scala/java/nio/HeapByteBufferCharView.scala @@ -34,7 +34,7 @@ private[nio] final class HeapByteBufferCharView private ( if (start < 0 || end < start || end > remaining) throw new IndexOutOfBoundsException new HeapByteBufferCharView(capacity, _byteArray, _byteArrayOffset, - position + start, position + end, isReadOnly, isBigEndian) + position() + start, position() + end, isReadOnly, isBigEndian) } @noinline diff --git a/javalib/src/main/scala/java/nio/HeapCharBuffer.scala b/javalib/src/main/scala/java/nio/HeapCharBuffer.scala index eab8729841..a6b9882daf 100644 --- a/javalib/src/main/scala/java/nio/HeapCharBuffer.scala +++ b/javalib/src/main/scala/java/nio/HeapCharBuffer.scala @@ -30,7 +30,7 @@ private[nio] final class HeapCharBuffer private ( if (start < 0 || end < start || end > remaining) throw new IndexOutOfBoundsException new HeapCharBuffer(capacity, _array, _arrayOffset, - position + start, position + end, isReadOnly) + position() + start, position() + end, isReadOnly) } @noinline diff --git a/javalib/src/main/scala/java/nio/IntBuffer.scala b/javalib/src/main/scala/java/nio/IntBuffer.scala index 7bfdb34179..4f7249c137 100644 --- a/javalib/src/main/scala/java/nio/IntBuffer.scala +++ b/javalib/src/main/scala/java/nio/IntBuffer.scala @@ -72,6 +72,41 @@ abstract class IntBuffer private[nio] ( @inline final def arrayOffset(): Int = GenBuffer(this).generic_arrayOffset() + @inline override def position(newPosition: Int): IntBuffer = { + super.position(newPosition) + this + } + + @inline override def limit(newLimit: Int): IntBuffer = { + super.limit(newLimit) + this + } + + @inline override def mark(): IntBuffer = { + super.mark() + this + } + + @inline override def reset(): IntBuffer = { + super.reset() + this + } + + @inline override def clear(): IntBuffer = { + super.clear() + this + } + + @inline override def flip(): IntBuffer = { + super.flip() + this + } + + @inline override def rewind(): IntBuffer = { + super.rewind() + this + } + def compact(): IntBuffer def isDirect(): Boolean diff --git a/javalib/src/main/scala/java/nio/LongBuffer.scala b/javalib/src/main/scala/java/nio/LongBuffer.scala index fc5c7430fe..e6eb2c4200 100644 --- a/javalib/src/main/scala/java/nio/LongBuffer.scala +++ b/javalib/src/main/scala/java/nio/LongBuffer.scala @@ -65,6 +65,41 @@ abstract class LongBuffer private[nio] ( @inline final def arrayOffset(): Int = GenBuffer(this).generic_arrayOffset() + @inline override def position(newPosition: Int): LongBuffer = { + super.position(newPosition) + this + } + + @inline override def limit(newLimit: Int): LongBuffer = { + super.limit(newLimit) + this + } + + @inline override def mark(): LongBuffer = { + super.mark() + this + } + + @inline override def reset(): LongBuffer = { + super.reset() + this + } + + @inline override def clear(): LongBuffer = { + super.clear() + this + } + + @inline override def flip(): LongBuffer = { + super.flip() + this + } + + @inline override def rewind(): LongBuffer = { + super.rewind() + this + } + def compact(): LongBuffer def isDirect(): Boolean diff --git a/javalib/src/main/scala/java/nio/ShortBuffer.scala b/javalib/src/main/scala/java/nio/ShortBuffer.scala index c787e39c6d..b560b231c2 100644 --- a/javalib/src/main/scala/java/nio/ShortBuffer.scala +++ b/javalib/src/main/scala/java/nio/ShortBuffer.scala @@ -72,6 +72,41 @@ abstract class ShortBuffer private[nio] ( @inline final def arrayOffset(): Int = GenBuffer(this).generic_arrayOffset() + @inline override def position(newPosition: Int): ShortBuffer = { + super.position(newPosition) + this + } + + @inline override def limit(newLimit: Int): ShortBuffer = { + super.limit(newLimit) + this + } + + @inline override def mark(): ShortBuffer = { + super.mark() + this + } + + @inline override def reset(): ShortBuffer = { + super.reset() + this + } + + @inline override def clear(): ShortBuffer = { + super.clear() + this + } + + @inline override def flip(): ShortBuffer = { + super.flip() + this + } + + @inline override def rewind(): ShortBuffer = { + super.rewind() + this + } + def compact(): ShortBuffer def isDirect(): Boolean diff --git a/javalib/src/main/scala/java/nio/StringCharBuffer.scala b/javalib/src/main/scala/java/nio/StringCharBuffer.scala index b15e9fda0b..5a7c507ce2 100644 --- a/javalib/src/main/scala/java/nio/StringCharBuffer.scala +++ b/javalib/src/main/scala/java/nio/StringCharBuffer.scala @@ -14,7 +14,7 @@ private[nio] final class StringCharBuffer private ( def slice(): CharBuffer = { val cap = remaining - new StringCharBuffer(cap, _csq, _csqOffset + position, 0, cap) + new StringCharBuffer(cap, _csq, _csqOffset + position(), 0, cap) } def duplicate(): CharBuffer = { @@ -30,7 +30,7 @@ private[nio] final class StringCharBuffer private ( if (start < 0 || end < start || end > remaining) throw new IndexOutOfBoundsException new StringCharBuffer(capacity, _csq, _csqOffset, - position + start, position + end) + position() + start, position() + end) } @noinline @@ -59,7 +59,7 @@ private[nio] final class StringCharBuffer private ( override def toString(): String = { val offset = _csqOffset - _csq.subSequence(position + offset, limit + offset).toString() + _csq.subSequence(position() + offset, limit() + offset).toString() } def order(): ByteOrder = ByteOrder.nativeOrder() diff --git a/javalib/src/main/scala/java/nio/TypedArrayByteBuffer.scala b/javalib/src/main/scala/java/nio/TypedArrayByteBuffer.scala index 30093defc6..c9fc816fed 100644 --- a/javalib/src/main/scala/java/nio/TypedArrayByteBuffer.scala +++ b/javalib/src/main/scala/java/nio/TypedArrayByteBuffer.scala @@ -77,7 +77,7 @@ private[nio] final class TypedArrayByteBuffer private ( { ensureNotReadOnly(); _dataView.setUint16(validateIndex(index, 2), value, !isBigEndian); this } def asCharBuffer(): CharBuffer = { - if (hasNativeOrder && (_arrayBufferOffset + position) % 2 == 0) + if (hasNativeOrder && (_arrayBufferOffset + position()) % 2 == 0) TypedArrayCharBuffer.fromTypedArrayByteBuffer(this) else DataViewCharBuffer.fromTypedArrayByteBuffer(this) @@ -93,7 +93,7 @@ private[nio] final class TypedArrayByteBuffer private ( { ensureNotReadOnly(); _dataView.setInt16(validateIndex(index, 2), value, !isBigEndian); this } def asShortBuffer(): ShortBuffer = { - if (hasNativeOrder && (_arrayBufferOffset + position) % 2 == 0) + if (hasNativeOrder && (_arrayBufferOffset + position()) % 2 == 0) TypedArrayShortBuffer.fromTypedArrayByteBuffer(this) else DataViewShortBuffer.fromTypedArrayByteBuffer(this) @@ -109,7 +109,7 @@ private[nio] final class TypedArrayByteBuffer private ( { ensureNotReadOnly(); _dataView.setInt32(validateIndex(index, 4), value, !isBigEndian); this } def asIntBuffer(): IntBuffer = { - if (hasNativeOrder && (_arrayBufferOffset + position) % 4 == 0) + if (hasNativeOrder && (_arrayBufferOffset + position()) % 4 == 0) TypedArrayIntBuffer.fromTypedArrayByteBuffer(this) else DataViewIntBuffer.fromTypedArrayByteBuffer(this) @@ -137,7 +137,7 @@ private[nio] final class TypedArrayByteBuffer private ( { ensureNotReadOnly(); _dataView.setFloat32(validateIndex(index, 4), value, !isBigEndian); this } def asFloatBuffer(): FloatBuffer = { - if (hasNativeOrder && (_arrayBufferOffset + position) % 4 == 0) + if (hasNativeOrder && (_arrayBufferOffset + position()) % 4 == 0) TypedArrayFloatBuffer.fromTypedArrayByteBuffer(this) else DataViewFloatBuffer.fromTypedArrayByteBuffer(this) @@ -153,7 +153,7 @@ private[nio] final class TypedArrayByteBuffer private ( { ensureNotReadOnly(); _dataView.setFloat64(validateIndex(index, 8), value, !isBigEndian); this } def asDoubleBuffer(): DoubleBuffer = { - if (hasNativeOrder && (_arrayBufferOffset + position) % 8 == 0) + if (hasNativeOrder && (_arrayBufferOffset + position()) % 8 == 0) TypedArrayDoubleBuffer.fromTypedArrayByteBuffer(this) else DataViewDoubleBuffer.fromTypedArrayByteBuffer(this) diff --git a/javalib/src/main/scala/java/nio/TypedArrayCharBuffer.scala b/javalib/src/main/scala/java/nio/TypedArrayCharBuffer.scala index 50232d9265..49b463f48d 100644 --- a/javalib/src/main/scala/java/nio/TypedArrayCharBuffer.scala +++ b/javalib/src/main/scala/java/nio/TypedArrayCharBuffer.scala @@ -33,7 +33,7 @@ private[nio] final class TypedArrayCharBuffer private ( if (start < 0 || end < start || end > remaining) throw new IndexOutOfBoundsException new TypedArrayCharBuffer(_typedArray, - position + start, position + end, isReadOnly) + position() + start, position() + end, isReadOnly) } @noinline diff --git a/javalib/src/main/scala/java/nio/charset/CharsetDecoder.scala b/javalib/src/main/scala/java/nio/charset/CharsetDecoder.scala index a3532baf14..bc41bdb850 100644 --- a/javalib/src/main/scala/java/nio/charset/CharsetDecoder.scala +++ b/javalib/src/main/scala/java/nio/charset/CharsetDecoder.scala @@ -110,13 +110,13 @@ abstract class CharsetDecoder protected (cs: Charset, CoderResult.OVERFLOW } else { out.put(replacement) - in.position(in.position + result2.length) + in.position(in.position() + result2.length) loop() } case CodingErrorAction.REPORT => result2 case CodingErrorAction.IGNORE => - in.position(in.position + result2.length) + in.position(in.position() + result2.length) loop() } } diff --git a/javalib/src/main/scala/java/nio/charset/CharsetEncoder.scala b/javalib/src/main/scala/java/nio/charset/CharsetEncoder.scala index 37d229637b..74ca083794 100644 --- a/javalib/src/main/scala/java/nio/charset/CharsetEncoder.scala +++ b/javalib/src/main/scala/java/nio/charset/CharsetEncoder.scala @@ -132,13 +132,13 @@ abstract class CharsetEncoder protected (cs: Charset, CoderResult.OVERFLOW } else { out.put(replacement) - in.position(in.position + result2.length) + in.position(in.position() + result2.length) loop() } case CodingErrorAction.REPORT => result2 case CodingErrorAction.IGNORE => - in.position(in.position + result2.length) + in.position(in.position() + result2.length) loop() } } diff --git a/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1_And_US_ASCII_Common.scala b/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1_And_US_ASCII_Common.scala index d2b1aba2b6..2d4937f628 100644 --- a/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1_And_US_ASCII_Common.scala +++ b/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1_And_US_ASCII_Common.scala @@ -48,12 +48,12 @@ private[niocharset] abstract class ISO_8859_1_And_US_ASCII_Common protected ( if (in.hasArray && out.hasArray) { val inArr = in.array val inOffset = in.arrayOffset - val inStart = in.position + inOffset + val inStart = in.position() + inOffset val inEnd = inStart + rem val outArr = out.array val outOffset = out.arrayOffset - val outStart = out.position + outOffset + val outStart = out.position() + outOffset var inPos = inStart var outPos = outStart @@ -114,12 +114,12 @@ private[niocharset] abstract class ISO_8859_1_And_US_ASCII_Common protected ( val inArr = in.array val inOffset = in.arrayOffset - val inStart = in.position + inOffset + val inStart = in.position() + inOffset val inEnd = inStart + rem val outArr = out.array val outOffset = out.arrayOffset - val outStart = out.position + outOffset + val outStart = out.position() + outOffset @inline @tailrec @@ -146,7 +146,7 @@ private[niocharset] abstract class ISO_8859_1_And_US_ASCII_Common protected ( if (Character.isLowSurrogate(c)) { CoderResult.malformedForLength(1) } else if (Character.isHighSurrogate(c)) { - if (inPos + 1 < in.limit) { + if (inPos + 1 < in.limit()) { val c2 = inArr(inPos+1) if (Character.isLowSurrogate(c2)) CoderResult.unmappableForLength(2) @@ -180,23 +180,23 @@ private[niocharset] abstract class ISO_8859_1_And_US_ASCII_Common protected ( loop() } else { if (Character.isLowSurrogate(c)) { - in.position(in.position - 1) + in.position(in.position() - 1) CoderResult.malformedForLength(1) } else if (Character.isHighSurrogate(c)) { if (in.hasRemaining) { val c2 = in.get() - in.position(in.position - 2) + in.position(in.position() - 2) if (Character.isLowSurrogate(c2)) { CoderResult.unmappableForLength(2) } else { CoderResult.malformedForLength(1) } } else { - in.position(in.position - 1) + in.position(in.position() - 1) CoderResult.UNDERFLOW } } else { - in.position(in.position - 1) + in.position(in.position() - 1) CoderResult.unmappableForLength(1) } } diff --git a/library/src/main/scala/scala/scalajs/niocharset/UTF_16_Common.scala b/library/src/main/scala/scala/scalajs/niocharset/UTF_16_Common.scala index 10d8a0e3ec..5bac2120bb 100644 --- a/library/src/main/scala/scala/scalajs/niocharset/UTF_16_Common.scala +++ b/library/src/main/scala/scala/scalajs/niocharset/UTF_16_Common.scala @@ -71,11 +71,11 @@ private[niocharset] abstract class UTF_16_Common protected ( val c1 = bytes2char(b1, b2) if (Character.isLowSurrogate(c1)) { - in.position(in.position - 2) + in.position(in.position() - 2) CoderResult.malformedForLength(2) } else if (!Character.isHighSurrogate(c1)) { if (out.remaining == 0) { - in.position(in.position - 2) + in.position(in.position() - 2) CoderResult.OVERFLOW } else { out.put(c1) @@ -83,7 +83,7 @@ private[niocharset] abstract class UTF_16_Common protected ( } } else { if (in.remaining < 2) { - in.position(in.position - 2) + in.position(in.position() - 2) CoderResult.UNDERFLOW } else { val b3 = in.get() & 0xff @@ -91,11 +91,11 @@ private[niocharset] abstract class UTF_16_Common protected ( val c2 = bytes2char(b3, b4) if (!Character.isLowSurrogate(c2)) { - in.position(in.position - 4) + in.position(in.position() - 4) CoderResult.malformedForLength(2) } else { if (out.remaining < 2) { - in.position(in.position - 4) + in.position(in.position() - 4) CoderResult.OVERFLOW } else { out.put(c1) @@ -158,11 +158,11 @@ private[niocharset] abstract class UTF_16_Common protected ( val c1 = in.get() if (Character.isLowSurrogate(c1)) { - in.position(in.position - 1) + in.position(in.position() - 1) CoderResult.malformedForLength(1) } else if (!Character.isHighSurrogate(c1)) { if (out.remaining < 2) { - in.position(in.position - 1) + in.position(in.position() - 1) CoderResult.OVERFLOW } else { putChar(c1) @@ -170,17 +170,17 @@ private[niocharset] abstract class UTF_16_Common protected ( } } else { if (in.remaining < 1) { - in.position(in.position - 1) + in.position(in.position() - 1) CoderResult.UNDERFLOW } else { val c2 = in.get() if (!Character.isLowSurrogate(c2)) { - in.position(in.position - 2) + in.position(in.position() - 2) CoderResult.malformedForLength(1) } else { if (out.remaining < 4) { - in.position(in.position - 2) + in.position(in.position() - 2) CoderResult.OVERFLOW } else { putChar(c1) diff --git a/library/src/main/scala/scala/scalajs/niocharset/UTF_8.scala b/library/src/main/scala/scala/scalajs/niocharset/UTF_8.scala index 6fc26b61c7..bf19bb02f8 100644 --- a/library/src/main/scala/scala/scalajs/niocharset/UTF_8.scala +++ b/library/src/main/scala/scala/scalajs/niocharset/UTF_8.scala @@ -80,13 +80,13 @@ private[niocharset] object UTF_8 extends Charset("UTF-8", Array( private def decodeLoopArray(in: ByteBuffer, out: CharBuffer): CoderResult = { val inArray = in.array val inOffset = in.arrayOffset - val inStart = in.position + inOffset - val inEnd = in.limit + inOffset + val inStart = in.position() + inOffset + val inEnd = in.limit() + inOffset val outArray = out.array val outOffset = out.arrayOffset - val outStart = out.position + outOffset - val outEnd = out.limit + outOffset + val outStart = out.position() + outOffset + val outEnd = out.limit() + outOffset @inline @tailrec @@ -162,7 +162,7 @@ private[niocharset] object UTF_8 extends Charset("UTF-8", Array( def loop(): CoderResult = { @inline def finalize(read: Int, result: CoderResult): CoderResult = { - in.position(in.position - read) + in.position(in.position() - read) result } @@ -300,13 +300,13 @@ private[niocharset] object UTF_8 extends Charset("UTF-8", Array( private def encodeLoopArray(in: CharBuffer, out: ByteBuffer): CoderResult = { val inArray = in.array val inOffset = in.arrayOffset - val inStart = in.position + inOffset - val inEnd = in.limit + inOffset + val inStart = in.position() + inOffset + val inEnd = in.limit() + inOffset val outArray = out.array val outOffset = out.arrayOffset - val outStart = out.position + outOffset - val outEnd = out.limit + outOffset + val outStart = out.position() + outOffset + val outEnd = out.limit() + outOffset @inline @tailrec @@ -387,7 +387,7 @@ private[niocharset] object UTF_8 extends Charset("UTF-8", Array( def loop(): CoderResult = { @inline def finalize(read: Int, result: CoderResult): CoderResult = { - in.position(in.position - read) + in.position(in.position() - read) result } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BaseBufferTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BaseBufferTest.scala index d8f286eb2d..f8e6cb89c1 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BaseBufferTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BaseBufferTest.scala @@ -321,7 +321,7 @@ abstract class BaseBufferTest { buf1.position(3) buf1.limit(7) buf1.mark() - val buf2 = buf1.slice() + val buf2 = buf1.sliceChain() assertEquals(0, buf2.position()) assertEquals(4, buf2.limit()) assertEquals(4, buf2.capacity()) @@ -357,7 +357,7 @@ abstract class BaseBufferTest { buf1.position(3) buf1.limit(7) buf1.mark() - val buf2 = buf1.duplicate() + val buf2 = buf1.duplicateChain() assertEquals(3, buf2.position()) assertEquals(7, buf2.limit()) assertEquals(10, buf2.capacity()) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BufferAdapter.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BufferAdapter.scala index 8b029ed545..87112d78ab 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BufferAdapter.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BufferAdapter.scala @@ -6,8 +6,15 @@ sealed abstract class BufferAdapter[BT <: Buffer, ET] { type BufferType = BT type ElementType = ET - def slice(): BufferType - def duplicate(): BufferType + /* Some methods have a Chain suffix because they are declared as abstract in + * java.nio.Buffer since Java 9, but with a result type of `Buffer` instead + * of the more specific `BufferType`. We use the `Chain` variant to be able + * to chain their application with further operations on the specific + * `BufferType`. + */ + + def sliceChain(): BufferType + def duplicateChain(): BufferType def asReadOnlyBuffer(): BufferType def get(): ElementType def put(e: ElementType): BufferType @@ -28,8 +35,8 @@ sealed abstract class BufferAdapter[BT <: Buffer, ET] { object BufferAdapter { class ByteBufferAdapater(val buffer: ByteBuffer) extends BufferAdapter[ByteBuffer, Byte] { - def slice(): BufferType = buffer.slice() - def duplicate(): BufferType = buffer.duplicate() + def sliceChain(): BufferType = buffer.slice() + def duplicateChain(): BufferType = buffer.duplicate() def asReadOnlyBuffer(): BufferType = buffer.asReadOnlyBuffer() def get(): ElementType = buffer.get() def put(e: ElementType): BufferType = buffer.put(e) @@ -52,8 +59,8 @@ object BufferAdapter { class CharBufferAdapater(val buffer: CharBuffer) extends BufferAdapter[CharBuffer, Char] { - def slice(): BufferType = buffer.slice() - def duplicate(): BufferType = buffer.duplicate() + def sliceChain(): BufferType = buffer.slice() + def duplicateChain(): BufferType = buffer.duplicate() def asReadOnlyBuffer(): BufferType = buffer.asReadOnlyBuffer() def get(): ElementType = buffer.get() def put(e: ElementType): BufferType = buffer.put(e) @@ -76,8 +83,8 @@ object BufferAdapter { class ShortBufferAdapater(val buffer: ShortBuffer) extends BufferAdapter[ShortBuffer, Short] { - def slice(): BufferType = buffer.slice() - def duplicate(): BufferType = buffer.duplicate() + def sliceChain(): BufferType = buffer.slice() + def duplicateChain(): BufferType = buffer.duplicate() def asReadOnlyBuffer(): BufferType = buffer.asReadOnlyBuffer() def get(): ElementType = buffer.get() def put(e: ElementType): BufferType = buffer.put(e) @@ -100,8 +107,8 @@ object BufferAdapter { class IntBufferAdapater(val buffer: IntBuffer) extends BufferAdapter[IntBuffer, Int] { - def slice(): BufferType = buffer.slice() - def duplicate(): BufferType = buffer.duplicate() + def sliceChain(): BufferType = buffer.slice() + def duplicateChain(): BufferType = buffer.duplicate() def asReadOnlyBuffer(): BufferType = buffer.asReadOnlyBuffer() def get(): ElementType = buffer.get() def put(e: ElementType): BufferType = buffer.put(e) @@ -124,8 +131,8 @@ object BufferAdapter { class LongBufferAdapater(val buffer: LongBuffer) extends BufferAdapter[LongBuffer, Long] { - def slice(): BufferType = buffer.slice() - def duplicate(): BufferType = buffer.duplicate() + def sliceChain(): BufferType = buffer.slice() + def duplicateChain(): BufferType = buffer.duplicate() def asReadOnlyBuffer(): BufferType = buffer.asReadOnlyBuffer() def get(): ElementType = buffer.get() def put(e: ElementType): BufferType = buffer.put(e) @@ -148,8 +155,8 @@ object BufferAdapter { class FloatBufferAdapater(val buffer: FloatBuffer) extends BufferAdapter[FloatBuffer, Float] { - def slice(): BufferType = buffer.slice() - def duplicate(): BufferType = buffer.duplicate() + def sliceChain(): BufferType = buffer.slice() + def duplicateChain(): BufferType = buffer.duplicate() def asReadOnlyBuffer(): BufferType = buffer.asReadOnlyBuffer() def get(): ElementType = buffer.get() def put(e: ElementType): BufferType = buffer.put(e) @@ -172,8 +179,8 @@ object BufferAdapter { class DoubleBufferAdapater(val buffer: DoubleBuffer) extends BufferAdapter[DoubleBuffer, Double] { - def slice(): BufferType = buffer.slice() - def duplicate(): BufferType = buffer.duplicate() + def sliceChain(): BufferType = buffer.slice() + def duplicateChain(): BufferType = buffer.duplicate() def asReadOnlyBuffer(): BufferType = buffer.asReadOnlyBuffer() def get(): ElementType = buffer.get() def put(e: ElementType): BufferType = buffer.put(e) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BufferFactory.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BufferFactory.scala index 99fb571899..2a41c6675c 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BufferFactory.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BufferFactory.scala @@ -208,7 +208,7 @@ object BufferFactory { val buf = super.allocBuffer(capacity+25) buf.position(17) buf.limit(17+capacity) - buf.slice() + buf.sliceChain() } override def withContent(pos: Int, limit: Int, capacity: Int, @@ -220,7 +220,7 @@ object BufferFactory { buf.put(content.toArray) buf.position(9) buf.limit(9+capacity) - val buf2 = buf.slice() + val buf2 = buf.sliceChain() buf2.position(pos) buf2.limit(limit) buf2 diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/ByteBufferTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/ByteBufferTest.scala index 2f813689e4..7c86ea19d2 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/ByteBufferTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/ByteBufferTest.scala @@ -34,7 +34,7 @@ abstract class ByteBufferTest extends BaseBufferTest { buf.order(ByteOrder.BIG_ENDIAN) assertEquals(0x7b7c, buf.getChar().toInt) - assertEquals(2, buf.position) + assertEquals(2, buf.position()) assertEquals(0x7d7e, buf.getChar().toInt) buf.order(ByteOrder.LITTLE_ENDIAN) @@ -77,7 +77,7 @@ abstract class ByteBufferTest extends BaseBufferTest { buf.order(ByteOrder.BIG_ENDIAN) assertEquals(0x7e7f, buf.getChar(3).toInt) - assertEquals(0, buf.position) + assertEquals(0, buf.position()) assertEquals(0x7f80, buf.getChar(4).toInt) buf.order(ByteOrder.LITTLE_ENDIAN) @@ -126,25 +126,25 @@ abstract class ByteBufferTest extends BaseBufferTest { val charBuf1 = buf.asCharBuffer() assertEquals(createsReadOnly, charBuf1.isReadOnly) assertEquals(3, charBuf1.capacity) - assertEquals(0, charBuf1.position) - assertEquals(3, charBuf1.limit) + assertEquals(0, charBuf1.position()) + assertEquals(3, charBuf1.limit()) assertEquals(ByteOrder.BIG_ENDIAN, charBuf1.order) assertEquals(0x7e7f, charBuf1.get(1).toInt) - assertEquals(0, charBuf1.position) + assertEquals(0, charBuf1.position()) assertEquals(0x7c7d, charBuf1.get().toInt) - assertEquals(1, charBuf1.position) + assertEquals(1, charBuf1.position()) buf.order(ByteOrder.LITTLE_ENDIAN) val charBuf2 = buf.asCharBuffer() assertEquals(createsReadOnly, charBuf2.isReadOnly) assertEquals(3, charBuf2.capacity) - assertEquals(0, charBuf2.position) - assertEquals(3, charBuf2.limit) + assertEquals(0, charBuf2.position()) + assertEquals(3, charBuf2.limit()) assertEquals(ByteOrder.LITTLE_ENDIAN, charBuf2.order) assertEquals(0x7f7e, charBuf2.get(1).toInt) - assertEquals(0, charBuf2.position) + assertEquals(0, charBuf2.position()) assertEquals(0x7d7c, charBuf2.get().toInt) - assertEquals(1, charBuf2.position) + assertEquals(1, charBuf2.position()) } @Test def asCharBuffer_Chars_to_Bytes(): Unit = { @@ -157,22 +157,22 @@ abstract class ByteBufferTest extends BaseBufferTest { charBuf1.put(1, 0x7e7f) assertEquals(0x7e, buf.get(3)) assertEquals(0x7f, buf.get(4)) - assertEquals(0, charBuf1.position) + assertEquals(0, charBuf1.position()) charBuf1.put(0x7c7d.toChar) assertEquals(0x7c, buf.get(1)) assertEquals(0x7d, buf.get(2)) - assertEquals(1, charBuf1.position) + assertEquals(1, charBuf1.position()) buf.order(ByteOrder.LITTLE_ENDIAN) val charBuf2 = buf.asCharBuffer() charBuf2.put(1, 0x7e7f) assertEquals(0x7f, buf.get(3)) assertEquals(0x7e, buf.get(4)) - assertEquals(0, charBuf2.position) + assertEquals(0, charBuf2.position()) charBuf2.put(0x7c7d.toChar) assertEquals(0x7d, buf.get(1)) assertEquals(0x7c, buf.get(2)) - assertEquals(1, charBuf2.position) + assertEquals(1, charBuf2.position()) } else { val buf = allocBuffer(10) buf.limit(8).position(1) @@ -187,7 +187,7 @@ abstract class ByteBufferTest extends BaseBufferTest { buf.order(ByteOrder.BIG_ENDIAN) assertEquals(0x7b7c, buf.getShort()) - assertEquals(2, buf.position) + assertEquals(2, buf.position()) assertEquals(0x7d7e, buf.getShort()) buf.order(ByteOrder.LITTLE_ENDIAN) @@ -231,7 +231,7 @@ abstract class ByteBufferTest extends BaseBufferTest { buf.order(ByteOrder.BIG_ENDIAN) assertEquals(0x7e7f, buf.getShort(3)) - assertEquals(0, buf.position) + assertEquals(0, buf.position()) assertEquals(0x7f80, buf.getShort(4)) buf.order(ByteOrder.LITTLE_ENDIAN) @@ -280,25 +280,25 @@ abstract class ByteBufferTest extends BaseBufferTest { val shortBuf1 = buf.asShortBuffer() assertEquals(createsReadOnly, shortBuf1.isReadOnly) assertEquals(3, shortBuf1.capacity) - assertEquals(0, shortBuf1.position) - assertEquals(3, shortBuf1.limit) + assertEquals(0, shortBuf1.position()) + assertEquals(3, shortBuf1.limit()) assertEquals(ByteOrder.BIG_ENDIAN, shortBuf1.order) assertEquals(0x7e7f, shortBuf1.get(1)) - assertEquals(0, shortBuf1.position) + assertEquals(0, shortBuf1.position()) assertEquals(0x7c7d, shortBuf1.get()) - assertEquals(1, shortBuf1.position) + assertEquals(1, shortBuf1.position()) buf.order(ByteOrder.LITTLE_ENDIAN) val shortBuf2 = buf.asShortBuffer() assertEquals(createsReadOnly, shortBuf2.isReadOnly) assertEquals(3, shortBuf2.capacity) - assertEquals(0, shortBuf2.position) - assertEquals(3, shortBuf2.limit) + assertEquals(0, shortBuf2.position()) + assertEquals(3, shortBuf2.limit()) assertEquals(ByteOrder.LITTLE_ENDIAN, shortBuf2.order) assertEquals(0x7f7e, shortBuf2.get(1)) - assertEquals(0, shortBuf2.position) + assertEquals(0, shortBuf2.position()) assertEquals(0x7d7c, shortBuf2.get()) - assertEquals(1, shortBuf2.position) + assertEquals(1, shortBuf2.position()) } @Test def asShortBuffer_Shorts_to_Bytes(): Unit = { @@ -311,22 +311,22 @@ abstract class ByteBufferTest extends BaseBufferTest { shortBuf1.put(1, 0x7e7f) assertEquals(0x7e, buf.get(3)) assertEquals(0x7f, buf.get(4)) - assertEquals(0, shortBuf1.position) + assertEquals(0, shortBuf1.position()) shortBuf1.put(0x7c7d.toShort) assertEquals(0x7c, buf.get(1)) assertEquals(0x7d, buf.get(2)) - assertEquals(1, shortBuf1.position) + assertEquals(1, shortBuf1.position()) buf.order(ByteOrder.LITTLE_ENDIAN) val shortBuf2 = buf.asShortBuffer() shortBuf2.put(1, 0x7e7f) assertEquals(0x7f, buf.get(3)) assertEquals(0x7e, buf.get(4)) - assertEquals(0, shortBuf2.position) + assertEquals(0, shortBuf2.position()) shortBuf2.put(0x7c7d.toShort) assertEquals(0x7d, buf.get(1)) assertEquals(0x7c, buf.get(2)) - assertEquals(1, shortBuf2.position) + assertEquals(1, shortBuf2.position()) } else { val buf = allocBuffer(10) buf.limit(8).position(1) @@ -341,7 +341,7 @@ abstract class ByteBufferTest extends BaseBufferTest { buf.order(ByteOrder.BIG_ENDIAN) assertEquals(0x7b7c7d7e, buf.getInt()) - assertEquals(4, buf.position) + assertEquals(4, buf.position()) assertEquals(0x7f808182, buf.getInt()) buf.order(ByteOrder.LITTLE_ENDIAN) @@ -390,7 +390,7 @@ abstract class ByteBufferTest extends BaseBufferTest { buf.order(ByteOrder.BIG_ENDIAN) assertEquals(0x7e7f8081, buf.getInt(3)) - assertEquals(0, buf.position) + assertEquals(0, buf.position()) assertEquals(0x7f808182, buf.getInt(4)) buf.order(ByteOrder.LITTLE_ENDIAN) @@ -445,25 +445,25 @@ abstract class ByteBufferTest extends BaseBufferTest { val intBuf1 = buf.asIntBuffer() assertEquals(createsReadOnly, intBuf1.isReadOnly) assertEquals(2, intBuf1.capacity) - assertEquals(0, intBuf1.position) - assertEquals(2, intBuf1.limit) + assertEquals(0, intBuf1.position()) + assertEquals(2, intBuf1.limit()) assertEquals(ByteOrder.BIG_ENDIAN, intBuf1.order) assertEquals(0x80818283, intBuf1.get(1)) - assertEquals(0, intBuf1.position) + assertEquals(0, intBuf1.position()) assertEquals(0x7c7d7e7f, intBuf1.get()) - assertEquals(1, intBuf1.position) + assertEquals(1, intBuf1.position()) buf.order(ByteOrder.LITTLE_ENDIAN) val intBuf2 = buf.asIntBuffer() assertEquals(createsReadOnly, intBuf2.isReadOnly) assertEquals(2, intBuf2.capacity) - assertEquals(0, intBuf2.position) - assertEquals(2, intBuf2.limit) + assertEquals(0, intBuf2.position()) + assertEquals(2, intBuf2.limit()) assertEquals(ByteOrder.LITTLE_ENDIAN, intBuf2.order) assertEquals(0x83828180, intBuf2.get(1)) - assertEquals(0, intBuf2.position) + assertEquals(0, intBuf2.position()) assertEquals(0x7f7e7d7c, intBuf2.get()) - assertEquals(1, intBuf2.position) + assertEquals(1, intBuf2.position()) } @Test def asIntBuffer_Ints_to_Bytes(): Unit = { @@ -478,13 +478,13 @@ abstract class ByteBufferTest extends BaseBufferTest { assertEquals(0x82.toByte, buf.get(6)) assertEquals(0x83.toByte, buf.get(7)) assertEquals(0x84.toByte, buf.get(8)) - assertEquals(0, intBuf1.position) + assertEquals(0, intBuf1.position()) intBuf1.put(0x7c7d7e7f) assertEquals(0x7c, buf.get(1)) assertEquals(0x7d, buf.get(2)) assertEquals(0x7e, buf.get(3)) assertEquals(0x7f, buf.get(4)) - assertEquals(1, intBuf1.position) + assertEquals(1, intBuf1.position()) buf.order(ByteOrder.LITTLE_ENDIAN) val intBuf2 = buf.asIntBuffer() @@ -493,13 +493,13 @@ abstract class ByteBufferTest extends BaseBufferTest { assertEquals(0x83.toByte, buf.get(6)) assertEquals(0x82.toByte, buf.get(7)) assertEquals(0x81.toByte, buf.get(8)) - assertEquals(0, intBuf2.position) + assertEquals(0, intBuf2.position()) intBuf2.put(0x7c7d7e7f) assertEquals(0x7f, buf.get(1)) assertEquals(0x7e, buf.get(2)) assertEquals(0x7d, buf.get(3)) assertEquals(0x7c, buf.get(4)) - assertEquals(1, intBuf2.position) + assertEquals(1, intBuf2.position()) } else { val buf = allocBuffer(14) buf.limit(10).position(1) @@ -514,7 +514,7 @@ abstract class ByteBufferTest extends BaseBufferTest { buf.order(ByteOrder.BIG_ENDIAN) assertEquals(0x767778797a7b7c7dL, buf.getLong()) - assertEquals(8, buf.position) + assertEquals(8, buf.position()) assertEquals(0x7e7f808182838485L, buf.getLong()) buf.order(ByteOrder.LITTLE_ENDIAN) @@ -575,7 +575,7 @@ abstract class ByteBufferTest extends BaseBufferTest { buf.order(ByteOrder.BIG_ENDIAN) assertEquals(0x797a7b7c7d7e7f80L, buf.getLong(3)) - assertEquals(0, buf.position) + assertEquals(0, buf.position()) assertEquals(0x7c7d7e7f80818283L, buf.getLong(6)) buf.order(ByteOrder.LITTLE_ENDIAN) @@ -642,25 +642,25 @@ abstract class ByteBufferTest extends BaseBufferTest { val longBuf1 = buf.asLongBuffer() assertEquals(createsReadOnly, longBuf1.isReadOnly) assertEquals(2, longBuf1.capacity) - assertEquals(0, longBuf1.position) - assertEquals(2, longBuf1.limit) + assertEquals(0, longBuf1.position()) + assertEquals(2, longBuf1.limit()) assertEquals(ByteOrder.BIG_ENDIAN, longBuf1.order) assertEquals(0x8182838485868788L, longBuf1.get(1)) - assertEquals(0, longBuf1.position) + assertEquals(0, longBuf1.position()) assertEquals(0x797a7b7c7d7e7f80L, longBuf1.get()) - assertEquals(1, longBuf1.position) + assertEquals(1, longBuf1.position()) buf.order(ByteOrder.LITTLE_ENDIAN) val longBuf2 = buf.asLongBuffer() assertEquals(createsReadOnly, longBuf2.isReadOnly) assertEquals(2, longBuf2.capacity) - assertEquals(0, longBuf2.position) - assertEquals(2, longBuf2.limit) + assertEquals(0, longBuf2.position()) + assertEquals(2, longBuf2.limit()) assertEquals(ByteOrder.LITTLE_ENDIAN, longBuf2.order) assertEquals(0x8887868584838281L, longBuf2.get(1)) - assertEquals(0, longBuf2.position) + assertEquals(0, longBuf2.position()) assertEquals(0x807f7e7d7c7b7a79L, longBuf2.get()) - assertEquals(1, longBuf2.position) + assertEquals(1, longBuf2.position()) } @Test def asLongBuffer_Longs_to_Bytes(): Unit = { @@ -679,7 +679,7 @@ abstract class ByteBufferTest extends BaseBufferTest { assertEquals(0x86.toByte, buf.get(16)) assertEquals(0x87.toByte, buf.get(17)) assertEquals(0x88.toByte, buf.get(18)) - assertEquals(0, longBuf1.position) + assertEquals(0, longBuf1.position()) longBuf1.put(0x797a7b7c7d7e7f80L) assertEquals(0x79, buf.get(3)) assertEquals(0x7a, buf.get(4)) @@ -689,7 +689,7 @@ abstract class ByteBufferTest extends BaseBufferTest { assertEquals(0x7e, buf.get(8)) assertEquals(0x7f, buf.get(9)) assertEquals(0x80.toByte, buf.get(10)) - assertEquals(1, longBuf1.position) + assertEquals(1, longBuf1.position()) buf.order(ByteOrder.LITTLE_ENDIAN) val longBuf2 = buf.asLongBuffer() @@ -702,7 +702,7 @@ abstract class ByteBufferTest extends BaseBufferTest { assertEquals(0x83.toByte, buf.get(16)) assertEquals(0x82.toByte, buf.get(17)) assertEquals(0x81.toByte, buf.get(18)) - assertEquals(0, longBuf2.position) + assertEquals(0, longBuf2.position()) longBuf2.put(0x797a7b7c7d7e7f80L) assertEquals(0x80.toByte, buf.get(3)) assertEquals(0x7f, buf.get(4)) @@ -712,7 +712,7 @@ abstract class ByteBufferTest extends BaseBufferTest { assertEquals(0x7b, buf.get(8)) assertEquals(0x7a, buf.get(9)) assertEquals(0x79, buf.get(10)) - assertEquals(1, longBuf2.position) + assertEquals(1, longBuf2.position()) } else { val buf = allocBuffer(20) buf.limit(19).position(3) @@ -728,7 +728,7 @@ abstract class ByteBufferTest extends BaseBufferTest { buf.order(ByteOrder.BIG_ENDIAN) assertEquals(3.141592f, buf.getFloat(), 0.0f) - assertEquals(4, buf.position) + assertEquals(4, buf.position()) assertEquals(151.189f, buf.getFloat(), 0.0f) buf.order(ByteOrder.LITTLE_ENDIAN) @@ -778,7 +778,7 @@ abstract class ByteBufferTest extends BaseBufferTest { buf.order(ByteOrder.BIG_ENDIAN) assertEquals(3.141592f, buf.getFloat(0), 0.0f) - assertEquals(0, buf.position) + assertEquals(0, buf.position()) assertEquals(151.189f, buf.getFloat(4), 0.0f) buf.order(ByteOrder.LITTLE_ENDIAN) @@ -835,25 +835,25 @@ abstract class ByteBufferTest extends BaseBufferTest { val floatBuf1 = buf.asFloatBuffer() assertEquals(createsReadOnly, floatBuf1.isReadOnly) assertEquals(2, floatBuf1.capacity) - assertEquals(0, floatBuf1.position) - assertEquals(2, floatBuf1.limit) + assertEquals(0, floatBuf1.position()) + assertEquals(2, floatBuf1.limit()) assertEquals(ByteOrder.BIG_ENDIAN, floatBuf1.order) assertEquals(8.120758e20f, floatBuf1.get(1), 0.0f) - assertEquals(0, floatBuf1.position) + assertEquals(0, floatBuf1.position()) assertEquals(3.141592f, floatBuf1.get(), 0.0f) - assertEquals(1, floatBuf1.position) + assertEquals(1, floatBuf1.position()) buf.order(ByteOrder.LITTLE_ENDIAN) val floatBuf2 = buf.asFloatBuffer() assertEquals(createsReadOnly, floatBuf2.isReadOnly) assertEquals(2, floatBuf2.capacity) - assertEquals(0, floatBuf2.position) - assertEquals(2, floatBuf2.limit) + assertEquals(0, floatBuf2.position()) + assertEquals(2, floatBuf2.limit()) assertEquals(ByteOrder.LITTLE_ENDIAN, floatBuf2.order) assertEquals(151.189f, floatBuf2.get(1), 0.0f) - assertEquals(0, floatBuf2.position) + assertEquals(0, floatBuf2.position()) assertEquals(-6.3017908e14f, floatBuf2.get(), 0.0f) - assertEquals(1, floatBuf2.position) + assertEquals(1, floatBuf2.position()) } @Test def asFloatBuffer_Floats_to_Bytes(): Unit = { @@ -868,13 +868,13 @@ abstract class ByteBufferTest extends BaseBufferTest { assertEquals(0x49, buf.get(6)) assertEquals(0x0f, buf.get(7)) assertEquals(0xd8.toByte, buf.get(8)) - assertEquals(0, floatBuf1.position) + assertEquals(0, floatBuf1.position()) floatBuf1.put(151.189f) assertEquals(0x43, buf.get(1)) assertEquals(0x17, buf.get(2)) assertEquals(0x30, buf.get(3)) assertEquals(0x62, buf.get(4)) - assertEquals(1, floatBuf1.position) + assertEquals(1, floatBuf1.position()) buf.order(ByteOrder.LITTLE_ENDIAN) val floatBuf2 = buf.asFloatBuffer() @@ -883,13 +883,13 @@ abstract class ByteBufferTest extends BaseBufferTest { assertEquals(0x0f, buf.get(6)) assertEquals(0x49, buf.get(7)) assertEquals(0x40, buf.get(8)) - assertEquals(0, floatBuf2.position) + assertEquals(0, floatBuf2.position()) floatBuf2.put(151.189f) assertEquals(0x62, buf.get(1)) assertEquals(0x30, buf.get(2)) assertEquals(0x17, buf.get(3)) assertEquals(0x43, buf.get(4)) - assertEquals(1, floatBuf2.position) + assertEquals(1, floatBuf2.position()) } else { val buf = allocBuffer(14) buf.limit(10).position(1) @@ -907,7 +907,7 @@ abstract class ByteBufferTest extends BaseBufferTest { buf.order(ByteOrder.BIG_ENDIAN) assertEquals(Math.PI, buf.getDouble(), 0.0) - assertEquals(8, buf.position) + assertEquals(8, buf.position()) assertEquals(1511.1989, buf.getDouble(), 0.0) buf.order(ByteOrder.LITTLE_ENDIAN) @@ -971,7 +971,7 @@ abstract class ByteBufferTest extends BaseBufferTest { buf.order(ByteOrder.BIG_ENDIAN) assertEquals(Math.PI, buf.getDouble(0), 0.0) - assertEquals(0, buf.position) + assertEquals(0, buf.position()) assertEquals(1511.1989, buf.getDouble(8), 0.0) buf.order(ByteOrder.LITTLE_ENDIAN) @@ -1041,25 +1041,25 @@ abstract class ByteBufferTest extends BaseBufferTest { val doubleBuf1 = buf.asDoubleBuffer() assertEquals(createsReadOnly, doubleBuf1.isReadOnly) assertEquals(2, doubleBuf1.capacity) - assertEquals(0, doubleBuf1.position) - assertEquals(2, doubleBuf1.limit) + assertEquals(0, doubleBuf1.position()) + assertEquals(2, doubleBuf1.limit()) assertEquals(ByteOrder.BIG_ENDIAN, doubleBuf1.order) assertEquals(-8.642954761616149e-63, doubleBuf1.get(1), 0.0) - assertEquals(0, doubleBuf1.position) + assertEquals(0, doubleBuf1.position()) assertEquals(Math.PI, doubleBuf1.get(), 0.0) - assertEquals(1, doubleBuf1.position) + assertEquals(1, doubleBuf1.position()) buf.order(ByteOrder.LITTLE_ENDIAN) val doubleBuf2 = buf.asDoubleBuffer() assertEquals(createsReadOnly, doubleBuf2.isReadOnly) assertEquals(2, doubleBuf2.capacity) - assertEquals(0, doubleBuf2.position) - assertEquals(2, doubleBuf2.limit) + assertEquals(0, doubleBuf2.position()) + assertEquals(2, doubleBuf2.limit()) assertEquals(ByteOrder.LITTLE_ENDIAN, doubleBuf2.order) assertEquals(1511.1989, doubleBuf2.get(1), 0.0) - assertEquals(0, doubleBuf2.position) + assertEquals(0, doubleBuf2.position()) assertEquals(3.207375630676366e-192, doubleBuf2.get(), 0.0) - assertEquals(1, doubleBuf2.position) + assertEquals(1, doubleBuf2.position()) } @Test def asDoubleBuffer_Doubles_to_Bytes(): Unit = { @@ -1078,7 +1078,7 @@ abstract class ByteBufferTest extends BaseBufferTest { assertEquals(0x44, buf.get(16)) assertEquals(0x2d, buf.get(17)) assertEquals(0x18, buf.get(18)) - assertEquals(0, doubleBuf1.position) + assertEquals(0, doubleBuf1.position()) doubleBuf1.put(1511.1989) assertEquals(0x40, buf.get(3)) assertEquals(0x97.toByte, buf.get(4)) @@ -1088,7 +1088,7 @@ abstract class ByteBufferTest extends BaseBufferTest { assertEquals(0x71, buf.get(8)) assertEquals(0x0c, buf.get(9)) assertEquals(0xb3.toByte, buf.get(10)) - assertEquals(1, doubleBuf1.position) + assertEquals(1, doubleBuf1.position()) buf.order(ByteOrder.LITTLE_ENDIAN) val doubleBuf2 = buf.asDoubleBuffer() @@ -1101,7 +1101,7 @@ abstract class ByteBufferTest extends BaseBufferTest { assertEquals(0x21, buf.get(16)) assertEquals(0x09, buf.get(17)) assertEquals(0x40, buf.get(18)) - assertEquals(0, doubleBuf2.position) + assertEquals(0, doubleBuf2.position()) doubleBuf2.put(1511.1989) assertEquals(0xb3.toByte, buf.get(3)) assertEquals(0x0c, buf.get(4)) @@ -1111,7 +1111,7 @@ abstract class ByteBufferTest extends BaseBufferTest { assertEquals(0x9c.toByte, buf.get(8)) assertEquals(0x97.toByte, buf.get(9)) assertEquals(0x40, buf.get(10)) - assertEquals(1, doubleBuf2.position) + assertEquals(1, doubleBuf2.position()) } else { val buf = allocBuffer(20) buf.limit(19).position(3) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/UTF16Test.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/UTF16Test.scala index 8ef1af7dc0..6321c4b960 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/UTF16Test.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/UTF16Test.scala @@ -127,7 +127,7 @@ object UTF16LETest { while (buf.remaining() >= 2) { val high = buf.get() val low = buf.get() - buf.position(buf.position - 2) + buf.position(buf.position() - 2) buf.put(low) buf.put(high) } From 41544fcc61d4902e8af9f4d6c6b6f75fdf04927c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 10 Oct 2017 17:00:40 +0200 Subject: [PATCH 0505/2665] Use `valueOf` instead of constructors for boxed classes. The constructors of boxed classes are deprecated in Java 9. --- .../scala/scalajs/runtime/BooleanReflectiveCall.scala | 4 ++-- .../scala/scalajs/runtime/LongReflectiveCall.scala | 4 ++-- .../scala/scalajs/runtime/NumberReflectiveCall.scala | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/runtime/BooleanReflectiveCall.scala b/library/src/main/scala/scala/scalajs/runtime/BooleanReflectiveCall.scala index 9da5dc342b..979fca981b 100644 --- a/library/src/main/scala/scala/scalajs/runtime/BooleanReflectiveCall.scala +++ b/library/src/main/scala/scala/scalajs/runtime/BooleanReflectiveCall.scala @@ -13,9 +13,9 @@ class BooleanReflectiveCall(value: Boolean) { def booleanValue(): Boolean = value def compareTo(that: JBoolean): Int = - new JBoolean(value).compareTo(that) + JBoolean.valueOf(value).compareTo(that) def compareTo(that: AnyRef): Int = - new JBoolean(value).compareTo(that.asInstanceOf[JBoolean]) + JBoolean.valueOf(value).compareTo(that.asInstanceOf[JBoolean]) // Methods of scala.Boolean diff --git a/library/src/main/scala/scala/scalajs/runtime/LongReflectiveCall.scala b/library/src/main/scala/scala/scalajs/runtime/LongReflectiveCall.scala index 70a2228b2c..ec7505a998 100644 --- a/library/src/main/scala/scala/scalajs/runtime/LongReflectiveCall.scala +++ b/library/src/main/scala/scala/scalajs/runtime/LongReflectiveCall.scala @@ -18,9 +18,9 @@ class LongReflectiveCall(value: Long) { def doubleValue(): Double = value.toDouble def compareTo(that: JLong): Int = - new JLong(value).compareTo(that) + JLong.valueOf(value).compareTo(that) def compareTo(that: AnyRef): Int = - new JLong(value).compareTo(that.asInstanceOf[JLong]) + JLong.valueOf(value).compareTo(that.asInstanceOf[JLong]) // Methods of scala.Long diff --git a/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala b/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala index f09a5d3182..93cea6dec7 100644 --- a/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala +++ b/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala @@ -18,14 +18,14 @@ class NumberReflectiveCall(value: Double) { def doubleValue(): Double = value def compareTo(that: JDouble): Int = - new JDouble(value).compareTo(that) + JDouble.valueOf(value).compareTo(that) def compareTo(that: JInteger): Int = - new JDouble(value).compareTo(new JDouble(that.doubleValue())) + JDouble.valueOf(value).compareTo(JDouble.valueOf(that.doubleValue())) def compareTo(that: AnyRef): Int = - new JDouble(value).compareTo(that.asInstanceOf[JDouble]) + JDouble.valueOf(value).compareTo(that.asInstanceOf[JDouble]) - def isNaN(): scala.Boolean = new JDouble(value).isNaN() - def isInfinite(): scala.Boolean = new JDouble(value).isInfinite() + def isNaN(): scala.Boolean = JDouble.valueOf(value).isNaN() + def isInfinite(): scala.Boolean = JDouble.valueOf(value).isInfinite() // Methods of scala.Double From bfb4b16c059f53e18e86b6074665e870c6df3d7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 10 Oct 2017 17:11:55 +0200 Subject: [PATCH 0506/2665] Add new overloads of existing methods of Math in Java 9. They are needed so that existing code still links when compiled on JDK 9. --- javalanglib/src/main/scala/java/lang/Math.scala | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/javalanglib/src/main/scala/java/lang/Math.scala b/javalanglib/src/main/scala/java/lang/Math.scala index b7e944a236..fef949112c 100644 --- a/javalanglib/src/main/scala/java/lang/Math.scala +++ b/javalanglib/src/main/scala/java/lang/Math.scala @@ -323,6 +323,10 @@ object Math { else throw new ArithmeticException("Integer overflow") } + @inline + def multiplyExact(a: scala.Long, b: scala.Int): scala.Long = + multiplyExact(a, b.toLong) + def multiplyExact(a: scala.Long, b: scala.Long): scala.Long = { val overflow = { if (b > 0) @@ -372,6 +376,10 @@ object Math { else quot - 1 } + @inline + def floorDiv(a: scala.Long, b: scala.Int): scala.Long = + floorDiv(a, b.toLong) + def floorDiv(a: scala.Long, b: scala.Long): scala.Long = { val quot = a / b if ((a < 0) == (b < 0) || quot * b == a) quot @@ -384,6 +392,10 @@ object Math { else rem + b } + @inline + def floorMod(a: scala.Long, b: scala.Int): scala.Int = + floorMod(a, b.toLong).toInt + def floorMod(a: scala.Long, b: scala.Long): scala.Long = { val rem = a % b if ((a < 0) == (b < 0) || rem == 0) rem From 98973d4a4ee6e0039a6f27f472f1a7be622394e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 11 Oct 2017 11:47:29 +0200 Subject: [PATCH 0507/2665] Correctly setup `apiMappings` on JDK 9. This includes two things: * Look up `rt.jar` in `scala.ext.dirs` for versions of Scala that do not understand the `jrt:/` file system. * Add another mapping working with the `jrt:/` file system for versions of Scala that understand it. --- project/Build.scala | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 3ec3530a20..e90dee659c 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -160,19 +160,33 @@ object Build { // Add Java Scaladoc mapping apiMappings += { val rtJar = { - val jars = - System.getProperty("sun.boot.class.path") - .split(java.io.File.pathSeparator) - def matches(path: String, name: String): Boolean = - path.endsWith(s"${java.io.File.separator}$name.jar") - jars.find(matches(_, "rt")) // most JREs - .orElse(jars.find(matches(_, "classes"))) // Java 6 on Mac OS X - .get + val bootClasspath = System.getProperty("sun.boot.class.path") + if (bootClasspath != null) { + // JDK <= 8, there is an rt.jar (or classes.jar) on the boot classpath + val jars = bootClasspath.split(java.io.File.pathSeparator) + def matches(path: String, name: String): Boolean = + path.endsWith(s"${java.io.File.separator}$name.jar") + val jar = jars.find(matches(_, "rt")) // most JREs + .orElse(jars.find(matches(_, "classes"))) // Java 6 on Mac OS X + .get + file(jar) + } else { + // JDK >= 9, sbt gives us a fake rt.jar in `scala.ext.dirs` + val scalaExtDirs = System.getProperty("scala.ext.dirs") + file(scalaExtDirs) / "rt.jar" + } } - file(rtJar) -> url(javaDocBaseURL) + assert(rtJar.exists, s"$rtJar does not exist") + rtJar -> url(javaDocBaseURL) }, + /* Add a second Java Scaladoc mapping for cases where Scala actually + * understands the jrt:/ filesystem of Java 9. + */ + apiMappings += + file("/modules/java.base") -> url(javaDocBaseURL), + /* Patch the ScalaDoc we generate. * * After executing the normal doc command, copy everything to the From 9ebbf6d11fd00581b46da73816defb87cf3e4069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 11 Oct 2017 13:10:05 +0200 Subject: [PATCH 0508/2665] Do not call `super.finalize()` because it is deprecated in JDK 9. `Object.finalize()` anyway is a no-op, so calling it is redundant. --- .../src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala index d2b3f36afa..ec1c20d8dd 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala @@ -117,7 +117,6 @@ final class IRFileCache { protected override def finalize(): Unit = { free() - super.finalize() } } From 16c7866d0edca270279543b562cd611c32666d42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 11 Oct 2017 13:30:39 +0200 Subject: [PATCH 0509/2665] Forward the system property `scala.ext.dirs` in `ExternalCompile`. This allows to build on JDK 9 with Scala 2.10 and 2.11. --- project/ExternalCompile.scala | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/project/ExternalCompile.scala b/project/ExternalCompile.scala index 006673e1d4..2f63ea8d81 100644 --- a/project/ExternalCompile.scala +++ b/project/ExternalCompile.scala @@ -18,6 +18,14 @@ object ExternalCompile { trapExit in compile := true, javaOptions in compile += "-Xmx512M", + javaOptions in compile ++= { + val scalaExtDirs = System.getProperty("scala.ext.dirs") + if (scalaExtDirs != null && (fork in compile).value) + Seq("-Dscala.ext.dirs=" + scalaExtDirs) + else + Nil + }, + compile := { val inputs = (compileInputs in compile).value import inputs.config._ From e285985bfd2ff198c74546ad81f957404bec03f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 11 Oct 2017 15:42:09 +0200 Subject: [PATCH 0510/2665] Work around #3152: disable Scaladoc generation for `library` on JDK 9. --- project/Build.scala | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index e90dee659c..459b7ed5d8 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1076,21 +1076,31 @@ object Build { // Filter doc sources to remove implementation details from doc. sources in doc := { - def containsFileFilter(s: String): FileFilter = new FileFilter { - override def accept(f: File): Boolean = { - val path = f.getAbsolutePath.replace('\\', '/') - path.contains(s) + val prev = (sources in doc).value + + if (javaVersion.value < 9) { + def containsFileFilter(s: String): FileFilter = new FileFilter { + override def accept(f: File): Boolean = { + val path = f.getAbsolutePath.replace('\\', '/') + path.contains(s) + } } - } - val filter: FileFilter = ( - AllPassFilter - -- containsFileFilter("/scala/scalajs/runtime/") - -- containsFileFilter("/scala/scalajs/js/annotation/internal/") - -- "*.nodoc.scala" - ) + val filter: FileFilter = ( + AllPassFilter + -- containsFileFilter("/scala/scalajs/runtime/") + -- containsFileFilter("/scala/scalajs/js/annotation/internal/") + -- "*.nodoc.scala" + ) - (sources in doc).value.filter(filter.accept) + (sources in doc).value.filter(filter.accept) + } else { + /* Work around #3152: library/doc crashes with + * + * on JDK 9. + */ + Nil + } }, /* Add compiled .class files to doc dependencyClasspath, so we can From 9428b684197cea946467f9caeaefab616546d356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 16 Oct 2017 15:37:56 +0200 Subject: [PATCH 0511/2665] Fix #3154: Avoid calling `AssertionError(String, Throwable)`. That constructor was only added in JDK 7, causing auto-tupling to do the wrong thing when we build on JDK 6. --- .../org/junit/internal/ArrayComparisonFailure.scala | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/junit-runtime/src/main/scala/org/junit/internal/ArrayComparisonFailure.scala b/junit-runtime/src/main/scala/org/junit/internal/ArrayComparisonFailure.scala index 58b6d4c0ac..0b72a3ca83 100644 --- a/junit-runtime/src/main/scala/org/junit/internal/ArrayComparisonFailure.scala +++ b/junit-runtime/src/main/scala/org/junit/internal/ArrayComparisonFailure.scala @@ -5,8 +5,14 @@ package org.junit.internal object ArrayComparisonFailure +/* Attention: AssertionError does not have a (String, Throwable) constructor + * in JDK 6. If we try to call that one, compilation *succeeds* because of + * auto-boxing, but it does not do the right thing. See #3154. + */ class ArrayComparisonFailure(message: String, cause: AssertionError, index: Int) - extends AssertionError(message, cause) { + extends AssertionError(message) { + + initCause(cause) private var fIndices: List[Int] = index :: Nil @@ -23,7 +29,7 @@ class ArrayComparisonFailure(message: String, cause: AssertionError, index: Int) val indices = if (fIndices == null) s"[$index]" // see #3148 else fIndices.map(index => s"[$index]").mkString - val causeMessage = getCause.getMessage + val causeMessage = cause.getMessage // do not use getCause(), see #3148 s"${msg}arrays first differed at element $indices; $causeMessage" } From e4e0cb28f69abacb8f1954f9f31ed911a010f9a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 16 Oct 2017 15:56:13 +0200 Subject: [PATCH 0512/2665] Fix #3155: Add the constructor `AssertionError(String, Throwable)`. It was introduced in JDK 7. In the process, fix the constructor taking `Object`, which is supposed to a) turn `null` into `"null"` and b) initialize the cause if the parameter is an instance of `Throwable`. --- .../src/main/scala/java/lang/Throwables.scala | 30 +++++++++++++------ .../javalib/lang/ThrowablesTestOnJDK7.scala | 6 ++++ .../javalib/lang/ThrowablesTest.scala | 26 ++++++++++++++++ 3 files changed, 53 insertions(+), 9 deletions(-) diff --git a/javalanglib/src/main/scala/java/lang/Throwables.scala b/javalanglib/src/main/scala/java/lang/Throwables.scala index bd3ece8c5d..d3e3e3eb59 100644 --- a/javalanglib/src/main/scala/java/lang/Throwables.scala +++ b/javalanglib/src/main/scala/java/lang/Throwables.scala @@ -128,15 +128,27 @@ class AbstractMethodError(s: String) extends IncompatibleClassChangeError(s) { def this() = this(null) } -class AssertionError private (s: String) extends Error(s) { - def this() = this(null) - def this(o: Object) = this(o.toString) - def this(b: scala.Boolean) = this(b.toString) - def this(c: scala.Char) = this(c.toString) - def this(i: scala.Int) = this(i.toString) - def this(l: scala.Long) = this(l.toString) - def this(f: scala.Float) = this(f.toString) - def this(d: scala.Double) = this(d.toString) +class AssertionError(message: String, cause: Throwable) + extends Error(message, cause) { + + def this() = this(null, null) + + def this(detailMessage: Object) = { + this( + String.valueOf(detailMessage), + detailMessage match { + case cause: Throwable => cause + case _ => null + } + ) + } + + def this(detailMessage: scala.Boolean) = this(String.valueOf(detailMessage), null) + def this(detailMessage: scala.Char) = this(String.valueOf(detailMessage), null) + def this(detailMessage: scala.Int) = this(String.valueOf(detailMessage), null) + def this(detailMessage: scala.Long) = this(String.valueOf(detailMessage), null) + def this(detailMessage: scala.Float) = this(String.valueOf(detailMessage), null) + def this(detailMessage: scala.Double) = this(String.valueOf(detailMessage), null) } class BootstrapMethodError(s: String, e: Throwable) extends LinkageError(s) { diff --git a/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/lang/ThrowablesTestOnJDK7.scala b/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/lang/ThrowablesTestOnJDK7.scala index b406ea7e36..341103a391 100644 --- a/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/lang/ThrowablesTestOnJDK7.scala +++ b/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/lang/ThrowablesTestOnJDK7.scala @@ -47,6 +47,12 @@ class ThrowablesTestOnJDK7 { test1(new ReflectiveOperationException(_)) test2(new ReflectiveOperationException(_)) test3(new ReflectiveOperationException(_, _)) + } + @Test def assertionErrorCtorWithStringThrowable(): Unit = { + val th = new RuntimeException("kaboom") + val e = new AssertionError("boom", th) + assertEquals("boom", e.getMessage) + assertSame(th, e.getCause) } } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ThrowablesTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ThrowablesTest.scala index 2bca575f02..3ecb32d2be 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ThrowablesTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ThrowablesTest.scala @@ -143,4 +143,30 @@ class ThrowablesTest { test2(new ExecutionException(_)) test3(new ExecutionException(_, _)) } + + @Test def assertionErrorsPeculiarConstructors(): Unit = { + def assertMessageNoCause(expectedMessage: String, e: AssertionError): Unit = { + assertEquals(expectedMessage, e.getMessage) + assertNull(e.getCause) + } + + assertMessageNoCause(null, new AssertionError()) + + assertMessageNoCause("boom", new AssertionError("boom")) + assertMessageNoCause("Some(5)", new AssertionError(Some(5))) + assertMessageNoCause("null", new AssertionError(null: Object)) + + assertMessageNoCause("true", new AssertionError(true)) + assertMessageNoCause("5", new AssertionError(5.toByte)) + assertMessageNoCause("6", new AssertionError(6.toShort)) + assertMessageNoCause("7", new AssertionError(7)) + assertMessageNoCause("8", new AssertionError(8L)) + assertMessageNoCause("1.5", new AssertionError(1.5f)) + assertMessageNoCause("2.5", new AssertionError(2.5)) + + val th = new RuntimeException("kaboom") + val e = new AssertionError(th) + assertEquals(th.toString, e.getMessage) + assertSame(th, e.getCause) + } } From 9e4007faee94190a93066c64cd55929a8af27384 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 21 Aug 2017 11:30:42 +0200 Subject: [PATCH 0513/2665] Turn `ClassDef` into a non-case class. This class has a bunch of fields, and it's likely that we'll still want to change them in the future. We can only do that if it is not a case class. The very small amount of changes shows that it was not used as a case class anyway. --- .../scala/org/scalajs/core/ir/Hashers.scala | 7 ++-- .../scala/org/scalajs/core/ir/Printers.scala | 3 +- .../org/scalajs/core/ir/Serializers.scala | 7 ++-- .../org/scalajs/core/ir/Transformers.scala | 5 ++- .../scala/org/scalajs/core/ir/Trees.scala | 33 ++++++++++++++++--- 5 files changed, 39 insertions(+), 16 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala index c726dfc416..67b9940417 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala @@ -39,8 +39,11 @@ object Hashers { /** Hash the definitions in a ClassDef (where applicable) */ def hashClassDef(classDef: ClassDef): ClassDef = { - classDef.copy(memberDefs = hashMemberDefs(classDef.memberDefs))( - classDef.optimizerHints)(classDef.pos) + import classDef._ + val newMemberDefs = hashMemberDefs(memberDefs) + ClassDef(name, kind, superClass, interfaces, jsNativeLoadSpec, + newMemberDefs, topLevelExportDefs)( + optimizerHints) } def hashesEqual(x: TreeHash, y: TreeHash): Boolean = diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index d65f3074df..c365777fdf 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -814,8 +814,7 @@ object Printers { } def print(classDef: ClassDef): Unit = { - val ClassDef(name, kind, superClass, interfaces, jsNativeLoadSpec, - memberDefs, topLevelExportDefs) = classDef + import classDef._ print(classDef.optimizerHints) kind match { case ClassKind.Class => print("class ") diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index 801ff69733..6765f1bb28 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -456,18 +456,17 @@ object Serializers { def writeClassDef(classDef: ClassDef): Unit = { import buffer._ + import classDef._ - val ClassDef(name, kind, superClass, parents, jsNativeLoadSpec, - memberDefs, topLevelExportDefs) = classDef writePosition(classDef.pos) writeIdent(name) writeByte(ClassKind.toByte(kind)) writeOptIdent(superClass) - writeIdents(parents) + writeIdents(interfaces) writeJSNativeLoadSpec(jsNativeLoadSpec) writeMemberDefs(memberDefs) writeTopLevelExportDefs(topLevelExportDefs) - writeInt(classDef.optimizerHints.bits) + writeInt(optimizerHints.bits) } def writeMemberDef(memberDef: MemberDef): Unit = { diff --git a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala index 99e0d05f04..a687e43701 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala @@ -204,9 +204,8 @@ object Transformers { abstract class ClassTransformer extends Transformer { def transformClassDef(tree: ClassDef): ClassDef = { - val ClassDef(name, kind, superClass, parents, jsName, memberDefs, - topLevelExportDefs) = tree - ClassDef(name, kind, superClass, parents, jsName, + import tree._ + ClassDef(name, kind, superClass, interfaces, jsNativeLoadSpec, memberDefs.map(transformMemberDef), topLevelExportDefs.map(transformTopLevelExportDef))( tree.optimizerHints)(tree.pos) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index a29fccea45..49d557c5a2 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -855,11 +855,34 @@ object Trees { // Classes - case class ClassDef(name: Ident, kind: ClassKind, superClass: Option[Ident], - interfaces: List[Ident], jsNativeLoadSpec: Option[JSNativeLoadSpec], - memberDefs: List[MemberDef], topLevelExportDefs: List[TopLevelExportDef])( - val optimizerHints: OptimizerHints)( - implicit val pos: Position) extends IRNode + final class ClassDef( + val name: Ident, + val kind: ClassKind, + val superClass: Option[Ident], + val interfaces: List[Ident], + val jsNativeLoadSpec: Option[JSNativeLoadSpec], + val memberDefs: List[MemberDef], + val topLevelExportDefs: List[TopLevelExportDef] + )( + val optimizerHints: OptimizerHints + )(implicit val pos: Position) extends IRNode + + object ClassDef { + def apply( + name: Ident, + kind: ClassKind, + superClass: Option[Ident], + interfaces: List[Ident], + jsNativeLoadSpec: Option[JSNativeLoadSpec], + memberDefs: List[MemberDef], + topLevelExportDefs: List[TopLevelExportDef])( + optimizerHints: OptimizerHints)( + implicit pos: Position): ClassDef = { + new ClassDef(name, kind, superClass, interfaces, jsNativeLoadSpec, + memberDefs, topLevelExportDefs)( + optimizerHints) + } + } // Class members From 3e1240a7ef6a45db6962bc488571fec77e3a799d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 18 Oct 2017 11:55:25 +0200 Subject: [PATCH 0514/2665] Redefine `JSSuperBracketSelect` and `JSSuperBracketCall`. Previously, they took as argument a `ClassType` of the enclosing class. It was up to the emitter to look up the super class, and load its class value. Now, they take the class value of the super class. For example, if `Foo` extends `Bar`, they now take `LoadJSConstructor(ClassType(Bar))` instead of `ClassType(Foo)`. This notably allows to unify the way super selects and super calls are handled in anonymous JS classes. The new encoding will also be necessary for proper support of nested JS classes. --- .../org/scalajs/core/compiler/GenJSCode.scala | 49 +++---------------- .../scalajs/core/compiler/GenJSExports.scala | 9 ++-- .../scalajs/core/compiler/JSDefinitions.scala | 2 - .../scala/org/scalajs/core/ir/Hashers.scala | 8 +-- .../scala/org/scalajs/core/ir/Printers.scala | 18 ++++--- .../org/scalajs/core/ir/Serializers.scala | 12 ++--- .../org/scalajs/core/ir/Transformers.scala | 8 +-- .../org/scalajs/core/ir/Traversers.scala | 6 ++- .../scala/org/scalajs/core/ir/Trees.scala | 27 +++++----- .../org/scalajs/core/ir/PrintersTest.scala | 8 +-- .../scala/scala/scalajs/runtime/package.scala | 49 ------------------- tools/scalajsenv.js | 12 ++--- .../backend/emitter/FunctionEmitter.scala | 33 ++++++------- .../core/tools/linker/checker/IRChecker.scala | 10 ++-- .../frontend/optimizer/OptimizerCore.scala | 11 +++-- 15 files changed, 91 insertions(+), 171 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 29e1754475..d4fd0e348f 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -4341,58 +4341,25 @@ abstract class GenJSCode extends plugins.PluginComponent genJSBracketSelectOrGlobalRef(receiver, propName) } { superInSym => js.JSSuperBracketSelect( - jstpe.ClassType(encodeClassFullName(superInSym)), + genPrimitiveJSClass(superInSym.superClass), ruleOutGlobalScope(receiver), propName) } } - def genSelectGet(propName: js.Tree): js.Tree = { - if (superIn.exists(isAnonJSClass(_))) { - // #3055 - genApplyMethod( - genLoadModule(RuntimePackageModule), - Runtime_jsObjectSuperGet, - List(ruleOutGlobalScope(receiver), propName)) - } else { - genSuperReference(propName) - } - } + def genSelectGet(propName: js.Tree): js.Tree = + genSuperReference(propName) - def genSelectSet(propName: js.Tree, value: js.Tree): js.Tree = { - if (superIn.exists(isAnonJSClass(_))) { - // #3055 - genApplyMethod( - genLoadModule(RuntimePackageModule), - Runtime_jsObjectSuperSet, - List(ruleOutGlobalScope(receiver), propName, value)) - } else { - js.Assign(genSuperReference(propName), value) - } - } + def genSelectSet(propName: js.Tree, value: js.Tree): js.Tree = + js.Assign(genSuperReference(propName), value) def genCall(methodName: js.Tree, args: List[js.Tree]): js.Tree = { superIn.fold[js.Tree] { genJSBracketMethodApplyOrGlobalRefApply( receiver, methodName, args) } { superInSym => - if (isAnonJSClass(superInSym)) { - // #3055 - val superClassType = - jstpe.ClassType(encodeClassFullName(superInSym.superClass)) - val superProto = js.JSBracketSelect( - js.LoadJSConstructor(superClassType), - js.StringLiteral("prototype")) - val superMethod = - js.JSBracketSelect(superProto, methodName) - js.JSBracketMethodApply( - superMethod, - js.StringLiteral("call"), - ruleOutGlobalScope(receiver) :: args) - } else { - js.JSSuperBracketCall( - jstpe.ClassType(encodeClassFullName(superInSym)), - ruleOutGlobalScope(receiver), methodName, args) - } + js.JSSuperBracketCall( + genPrimitiveJSClass(superInSym.superClass), + ruleOutGlobalScope(receiver), methodName, args) } } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index c7f8bd8321..032d8e71da 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -652,19 +652,20 @@ trait GenJSExports extends SubComponent { self: GenJSCode => val allArgs = (1 to minArgc).map(genFormalArgRef(_, minArgc)) ++: restArg - val cls = jstpe.ClassType(encodeClassFullName(currentClassSym)) + val superClass = js.LoadJSConstructor( + jstpe.ClassType(encodeClassFullName(currentClassSym.superClass))) val receiver = js.This()(jstpe.AnyType) val nameString = genExpr(jsNameOf(sym)) if (jsInterop.isJSGetter(sym)) { assert(allArgs.isEmpty) - js.JSSuperBracketSelect(cls, receiver, nameString) + js.JSSuperBracketSelect(superClass, receiver, nameString) } else if (jsInterop.isJSSetter(sym)) { assert(allArgs.size == 1 && !allArgs.head.isInstanceOf[js.JSSpread]) - js.Assign(js.JSSuperBracketSelect(cls, receiver, nameString), + js.Assign(js.JSSuperBracketSelect(superClass, receiver, nameString), allArgs.head) } else { - js.JSSuperBracketCall(cls, receiver, nameString, allArgs) + js.JSSuperBracketCall(superClass, receiver, nameString, allArgs) } } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index ef01ea0e67..6e873c0cf8 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -113,8 +113,6 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val RuntimePackageModule = getPackageObject("scala.scalajs.runtime") lazy val Runtime_wrapJavaScriptException = getMemberMethod(RuntimePackageModule, newTermName("wrapJavaScriptException")) lazy val Runtime_unwrapJavaScriptException = getMemberMethod(RuntimePackageModule, newTermName("unwrapJavaScriptException")) - lazy val Runtime_jsObjectSuperGet = getMemberMethod(RuntimePackageModule, newTermName("jsObjectSuperGet")) - lazy val Runtime_jsObjectSuperSet = getMemberMethod(RuntimePackageModule, newTermName("jsObjectSuperSet")) lazy val Runtime_genTraversableOnce2jsArray = getMemberMethod(RuntimePackageModule, newTermName("genTraversableOnce2jsArray")) lazy val Runtime_jsTupleArray2jsObject = getMemberMethod(RuntimePackageModule, newTermName("jsTupleArray2jsObject")) lazy val Runtime_constructorOf = getMemberMethod(RuntimePackageModule, newTermName("constructorOf")) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala index 67b9940417..8d00bb329a 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala @@ -317,15 +317,15 @@ object Hashers { mixTree(method) mixTrees(args) - case JSSuperBracketSelect(cls, qualifier, item) => + case JSSuperBracketSelect(superClass, qualifier, item) => mixTag(TagJSSuperBracketSelect) - mixType(cls) + mixTree(superClass) mixTree(qualifier) mixTree(item) - case JSSuperBracketCall(cls, receiver, method, args) => + case JSSuperBracketCall(superClass, receiver, method, args) => mixTag(TagJSSuperBracketCall) - mixType(cls) + mixTree(superClass) mixTree(receiver) mixTree(method) mixTrees(args) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index c365777fdf..dcd9db29b5 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -578,19 +578,21 @@ object Printers { print(']') printArgs(args) - case JSSuperBracketSelect(cls, qualifier, item) => + case JSSuperBracketSelect(superClass, qualifier, item) => + print("super(") + print(superClass) + print(")::") print(qualifier) - print('.') - print(cls) - print("::super[") + print('[') print(item) print(']') - case JSSuperBracketCall(cls, receiver, method, args) => + case JSSuperBracketCall(superClass, receiver, method, args) => + print("super(") + print(superClass) + print(")::") print(receiver) - print('.') - print(cls) - print("::super[") + print('[') print(method) print(']') printArgs(args) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index 6765f1bb28..8b0b03d552 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -311,13 +311,13 @@ object Serializers { writeByte(TagJSBracketMethodApply) writeTree(receiver); writeTree(method); writeTrees(args) - case JSSuperBracketSelect(cls, qualifier, item) => + case JSSuperBracketSelect(superClass, qualifier, item) => writeByte(TagJSSuperBracketSelect) - writeClassType(cls); writeTree(qualifier); writeTree(item) + writeTree(superClass); writeTree(qualifier); writeTree(item) - case JSSuperBracketCall(cls, receiver, method, args) => + case JSSuperBracketCall(superClass, receiver, method, args) => writeByte(TagJSSuperBracketCall) - writeClassType(cls); writeTree(receiver); writeTree(method); writeTrees(args) + writeTree(superClass); writeTree(receiver); writeTree(method); writeTrees(args) case JSSuperConstructorCall(args) => writeByte(TagJSSuperConstructorCall) @@ -858,9 +858,9 @@ object Serializers { case TagJSFunctionApply => JSFunctionApply(readTree(), readTrees()) case TagJSDotMethodApply => JSDotMethodApply(readTree(), readIdent(), readTrees()) case TagJSBracketMethodApply => JSBracketMethodApply(readTree(), readTree(), readTrees()) - case TagJSSuperBracketSelect => JSSuperBracketSelect(readClassType(), readTree(), readTree()) + case TagJSSuperBracketSelect => JSSuperBracketSelect(readTree(), readTree(), readTree()) case TagJSSuperBracketCall => - JSSuperBracketCall(readClassType(), readTree(), readTree(), readTrees()) + JSSuperBracketCall(readTree(), readTree(), readTree(), readTrees()) case TagJSSuperConstructorCall => JSSuperConstructorCall(readTrees()) case TagLoadJSConstructor => LoadJSConstructor(readClassType()) case TagLoadJSModule => LoadJSModule(readClassType()) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala index a687e43701..ea6043a671 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala @@ -148,12 +148,12 @@ object Transformers { JSBracketMethodApply(transformExpr(receiver), transformExpr(method), args map transformExpr) - case JSSuperBracketSelect(cls, qualifier, item) => - JSSuperBracketSelect(cls, transformExpr(qualifier), + case JSSuperBracketSelect(superClass, qualifier, item) => + JSSuperBracketSelect(superClass, transformExpr(qualifier), transformExpr(item)) - case JSSuperBracketCall(cls, receiver, method, args) => - JSSuperBracketCall(cls, transformExpr(receiver), + case JSSuperBracketCall(superClass, receiver, method, args) => + JSSuperBracketCall(superClass, transformExpr(receiver), transformExpr(method), args map transformExpr) case JSSuperConstructorCall(args) => diff --git a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala index 7605be38f5..d47588de6f 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala @@ -150,11 +150,13 @@ object Traversers { traverse(method) args foreach traverse - case JSSuperBracketSelect(cls, qualifier, item) => + case JSSuperBracketSelect(superClass, qualifier, item) => + traverse(superClass) traverse(qualifier) traverse(item) - case JSSuperBracketCall(cls, receiver, method, args) => + case JSSuperBracketCall(superClass, receiver, method, args) => + traverse(superClass) traverse(receiver) traverse(method) args foreach traverse diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 49d557c5a2..59bf661a48 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -507,9 +507,7 @@ object Trees { val tpe = AnyType } - /** Selects a property inherited from the parent class of `cls` on `receiver`. - * - * `cls` must be a non-native JS class. + /** Selects a property inherited from the given `superClass` on `receiver`. * * Given the non-native JS classes * @@ -521,13 +519,13 @@ object Trees { * The node * * {{{ - * JSSuperBrackerSelect(ClassType(Foo), qualifier, item) + * JSSuperBrackerSelect(LoadJSConstructor(ClassType(Bar)), qualifier, item) * }}} * * which is printed as * * {{{ - * qualifier.Foo::super[item] + * super(constructorOf[Bar])::qualifier[item] * }}} * * has the semantics of an ES6 super reference @@ -539,14 +537,21 @@ object Trees { * as if it were in an instance method of `Foo` with `qualifier` as the * `this` value. */ - case class JSSuperBracketSelect(cls: ClassType, receiver: Tree, item: Tree)( + case class JSSuperBracketSelect(superClass: Tree, receiver: Tree, item: Tree)( implicit val pos: Position) extends Tree { val tpe = AnyType } - /** Calls a method inherited from the parent class of `cls` on `receiver`. + /** Calls a method inherited from the given `superClass` on `receiver`. + * + * Intuitively, this corresponds to + * + * {{{ + * superClass.prototype[method].call(receiver, ...args) + * }}} * - * `cls` must be a non-native JS class. + * but retains more structure at the IR level than using an explicit + * encoding of the above expression. * * Given the non-native JS classes * @@ -558,13 +563,13 @@ object Trees { * The node * * {{{ - * JSSuperBrackerCall(ClassType(Foo), receiver, method, args) + * JSSuperBrackerCall(LoadJSConstructor(ClassType(Bar)), receiver, method, args) * }}} * * which is printed as * * {{{ - * receiver.Foo::super[method](...args) + * super(constructorOf[Bar])::receiver[method](...args) * }}} * * has the following semantics: @@ -581,7 +586,7 @@ object Trees { * super[method](...args) * }}} */ - case class JSSuperBracketCall(cls: ClassType, receiver: Tree, method: Tree, + case class JSSuperBracketCall(superClass: Tree, receiver: Tree, method: Tree, args: List[Tree])(implicit val pos: Position) extends Tree { val tpe = AnyType } diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala index 9deacf9e1e..8cf7633624 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala @@ -625,13 +625,13 @@ class PrintersTest { } @Test def printJSSuperBracketSelect(): Unit = { - assertPrintEquals("""x.LTest::super["f"]""", - JSSuperBracketSelect("LTest", ref("x", AnyType), StringLiteral("f"))) + assertPrintEquals("""super(sc)::x["f"]""", + JSSuperBracketSelect(ref("sc", AnyType), ref("x", AnyType), StringLiteral("f"))) } @Test def printJSSuperBracketCall(): Unit = { - assertPrintEquals("""x.LTest::super["f"]()""", - JSSuperBracketCall("LTest", ref("x", AnyType), StringLiteral("f"), Nil)) + assertPrintEquals("""super(sc)::x["f"]()""", + JSSuperBracketCall(ref("sc", AnyType), ref("x", AnyType), StringLiteral("f"), Nil)) } @Test def printJSSuperConstructorCall(): Unit = { diff --git a/library/src/main/scala/scala/scalajs/runtime/package.scala b/library/src/main/scala/scala/scalajs/runtime/package.scala index 991064641b..8a7e1e81ea 100644 --- a/library/src/main/scala/scala/scalajs/runtime/package.scala +++ b/library/src/main/scala/scala/scalajs/runtime/package.scala @@ -26,55 +26,6 @@ package object runtime { result } - private final def resolveSuperRef(self: Any, - propName: Any): js.Dynamic = { - // !!! Duplicate code with the $resolveSuperRef helper - // scalastyle:off return - val getPrototypeOf = js.constructorOf[js.Object].getPrototypeOf - val getOwnPropertyDescriptor = js.constructorOf[js.Object].getOwnPropertyDescriptor - - var superProto = getPrototypeOf(self.asInstanceOf[js.Any]) - while (superProto != null) { - val desc = getOwnPropertyDescriptor(superProto, propName.asInstanceOf[js.Any]) - if (!js.isUndefined(desc)) - return desc - superProto = getPrototypeOf(superProto) - } - - js.undefined.asInstanceOf[js.Dynamic] - // scalastyle:on return - } - - final def jsObjectSuperGet(self: Any, propName: Any): Any = { - // !!! Duplicate code with the $superGet helper - val desc = resolveSuperRef(self, propName) - if (!js.isUndefined(desc)) { - val getter = desc.get - if (!js.isUndefined(getter)) - getter.call(self.asInstanceOf[js.Any]) - else - desc.value - } else { - js.undefined - } - } - - final def jsObjectSuperSet(self: Any, propName: Any, value: Any): Unit = { - // !!! Duplicate code with the $superSet helper - // scalastyle:off return - val desc = resolveSuperRef(self, propName) - if (!js.isUndefined(desc)) { - val setter = desc.set - if (!js.isUndefined(setter)) { - setter.call(self.asInstanceOf[js.Any], value.asInstanceOf[js.Any]) - return - } - } - throw js.JavaScriptException( - new js.TypeError("super has no setter '" + propName + "'.")) - // scalastyle:on return - } - @inline final def genTraversableOnce2jsArray[A]( col: GenTraversableOnce[A]): js.Array[A] = { col match { diff --git a/tools/scalajsenv.js b/tools/scalajsenv.js index f5b1d0130f..a965bbbadf 100644 --- a/tools/scalajsenv.js +++ b/tools/scalajsenv.js @@ -484,11 +484,11 @@ function $newJSObjectWithVarargs(ctor, args) { } }; -function $resolveSuperRef(initialProto, propName) { +function $resolveSuperRef(superClass, propName) { const getPrototypeOf = Object["getPrototypeOf"]; const getOwnPropertyDescriptor = Object["getOwnPropertyDescriptor"]; - let superProto = getPrototypeOf(initialProto); + let superProto = superClass.prototype; while (superProto !== null) { const desc = getOwnPropertyDescriptor(superProto, propName); if (desc !== void 0) @@ -499,8 +499,8 @@ function $resolveSuperRef(initialProto, propName) { return void 0; }; -function $superGet(initialProto, self, propName) { - const desc = $resolveSuperRef(initialProto, propName); +function $superGet(superClass, self, propName) { + const desc = $resolveSuperRef(superClass, propName); if (desc !== void 0) { const getter = desc["get"]; if (getter !== void 0) @@ -511,8 +511,8 @@ function $superGet(initialProto, self, propName) { return void 0; }; -function $superSet(initialProto, self, propName, value) { - const desc = $resolveSuperRef(initialProto, propName); +function $superSet(superClass, self, propName, value) { + const desc = $resolveSuperRef(superClass, propName); if (desc !== void 0) { const setter = desc["set"]; if (setter !== void 0) { diff --git 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 index 5e5e82cfd8..87bb0754f7 100644 --- 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 @@ -536,13 +536,11 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { transformExprNoChar(newRhs)) } - case Assign(select @ JSSuperBracketSelect(cls, qualifier, item), rhs) => - unnest(List(qualifier, item, rhs)) { - case (List(newQualifier, newItem, newRhs), env0) => + case Assign(select @ JSSuperBracketSelect(superClass, qualifier, item), rhs) => + unnest(List(superClass, qualifier, item, rhs)) { + case (List(newSuperClass, newQualifier, newItem, newRhs), env0) => implicit val env = env0 - val ctor = - extractWithGlobals(genRawJSClassConstructor(cls.className)) - genCallHelper("superSet", ctor DOT "prototype", + genCallHelper("superSet", transformExprNoChar(newSuperClass), transformExprNoChar(newQualifier), transformExprNoChar(item), transformExprNoChar(rhs)) } @@ -1154,8 +1152,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { allowSideEffects && test(receiver) && (args forall test) case JSBracketMethodApply(receiver, method, args) => allowSideEffects && test(receiver) && test(method) && (args forall test) - case JSSuperBracketSelect(_, qualifier, item) => - allowSideEffects && test(qualifier) && test(item) + case JSSuperBracketSelect(superClass, qualifier, item) => + allowSideEffects && test(superClass) && test(qualifier) && test(item) case LoadJSModule(_) => allowSideEffects case JSGlobalRef(_) => @@ -1609,19 +1607,17 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { } } - case JSSuperBracketSelect(cls, qualifier, item) => - unnest(qualifier, item) { (newQualifier, newItem, env) => - redo(JSSuperBracketSelect(cls, newQualifier, newItem))(env) + case JSSuperBracketSelect(superClass, qualifier, item) => + unnest(List(superClass, qualifier, item)) { + case (List(newSuperClass, newQualifier, newItem), env) => + redo(JSSuperBracketSelect(newSuperClass, newQualifier, newItem))(env) } - case JSSuperBracketCall(cls, receiver, method, args) => - val superClass = globalKnowledge.getSuperClassOfJSClass(cls.className) - val superCtor = LoadJSConstructor(ClassType(superClass)) - + case JSSuperBracketCall(superClass, receiver, method, args) => redo { JSBracketMethodApply( JSBracketSelect( - JSBracketSelect(superCtor, StringLiteral("prototype")), + JSBracketSelect(superClass, StringLiteral("prototype")), method), StringLiteral("call"), receiver :: args) @@ -2206,9 +2202,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { js.Apply(genBracketSelect(transformExprNoChar(receiver), transformExprNoChar(method)), args.map(transformExprNoChar)) - case JSSuperBracketSelect(cls, qualifier, item) => - val ctor = extractWithGlobals(genRawJSClassConstructor(cls.className)) - genCallHelper("superGet", ctor DOT "prototype", + case JSSuperBracketSelect(superClass, qualifier, item) => + genCallHelper("superGet", transformExprNoChar(superClass), transformExprNoChar(qualifier), transformExprNoChar(item)) case LoadJSConstructor(cls) => diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index c0e812c7bd..2805957d41 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -936,15 +936,13 @@ private final class IRChecker(unit: LinkingUnit, for (arg <- args) typecheckExprOrSpread(arg, env) - case JSSuperBracketSelect(cls, qualifier, item) => - if (!lookupClass(cls).kind.isJSClass) - reportError(s"JS class type expected but $cls found") + case JSSuperBracketSelect(superClass, qualifier, item) => + typecheckExpr(superClass, env) typecheckExpr(qualifier, env) typecheckExpr(item, env) - case JSSuperBracketCall(cls, receiver, method, args) => - if (!lookupClass(cls).kind.isJSClass) - reportError(s"JS class type expected but $cls found") + case JSSuperBracketCall(superClass, receiver, method, args) => + typecheckExpr(superClass, env) typecheckExpr(receiver, env) typecheckExpr(method, env) for (arg <- args) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index d6fbbcb632..0a24b02295 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -596,12 +596,13 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { JSBracketMethodApply(transformExpr(receiver), transformExpr(method), transformExprsOrSpreads(args)) - case JSSuperBracketSelect(cls, qualifier, item) => - JSSuperBracketSelect(cls, transformExpr(qualifier), transformExpr(item)) + case JSSuperBracketSelect(superClass, qualifier, item) => + JSSuperBracketSelect(transformExpr(superClass), transformExpr(qualifier), + transformExpr(item)) - case JSSuperBracketCall(cls, receiver, method, args) => - JSSuperBracketCall(cls, transformExpr(receiver), transformExpr(method), - transformExprsOrSpreads(args)) + case JSSuperBracketCall(superClass, receiver, method, args) => + JSSuperBracketCall(transformExpr(superClass), transformExpr(receiver), + transformExpr(method), transformExprsOrSpreads(args)) case JSSuperConstructorCall(args) => JSSuperConstructorCall(transformExprsOrSpreads(args)) From a068e5dbdce8863428f79484c7f44bffa7a6bccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 19 Oct 2017 15:46:49 +0200 Subject: [PATCH 0515/2665] Add `js.special.instanceof(a, b)` for `a instanceof b`. Previously, we had no way to write code equivalent to `a instanceof b` where `b` is a dynamic value (rather than something directly available as `js.constructorOf[C]` for some `C`). Adding this method fills up a hole in our interoperability features. This will also be necessary to desugar `.isInstanceOf`s on nested JS classes. --- .../org/scalajs/core/compiler/GenJSCode.scala | 4 +++ .../scalajs/core/compiler/JSDefinitions.scala | 1 + .../scalajs/core/compiler/JSPrimitives.scala | 6 +++-- .../scala/scalajs/js/special/package.scala | 19 ++++++++++++++ .../testsuite/jsinterop/SpecialTest.scala | 25 +++++++++++++++++++ 5 files changed, 53 insertions(+), 2 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index d4fd0e348f..37f7a0bd6a 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -4230,6 +4230,10 @@ abstract class GenJSCode extends plugins.PluginComponent js.Unbox(js.JSBinaryOp(js.JSBinaryOp.in, arg2, js.VarRef(temp)(jstpe.AnyType)), 'Z')) + case INSTANCEOF => + // js.special.instanceof(arg1, arg2) + js.Unbox(js.JSBinaryOp(js.JSBinaryOp.instanceof, arg1, arg2), 'Z') + case DELETE => // js.special.delete(arg1, arg2) js.JSDelete(js.JSBracketSelect(arg1, arg2)) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 6e873c0cf8..4afe813e02 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -98,6 +98,7 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val JSConstructorTag_materialize = getMemberMethod(JSConstructorTagModule, newTermName("materialize")) lazy val SpecialPackageModule = getPackageObject("scala.scalajs.js.special") + lazy val Special_instanceof = getMemberMethod(SpecialPackageModule, newTermName("instanceof")) lazy val Special_delete = getMemberMethod(SpecialPackageModule, newTermName("delete")) lazy val Special_debugger = getMemberMethod(SpecialPackageModule, newTermName("debugger")) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala index d156c71260..9e12eecf06 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala @@ -48,8 +48,9 @@ abstract class JSPrimitives { val CONSTRUCTOROF = 352 // runtime.constructorOf(clazz) val LINKING_INFO = 354 // $linkingInfo - val DELETE = 355 // js.special.delete - val DEBUGGER = 356 // js.special.debugger + val INSTANCEOF = 355 // js.special.instanceof + val DELETE = 356 // js.special.delete + val DEBUGGER = 357 // js.special.debugger /** Initialize the map of primitive methods (for GenJSCode) */ def init(): Unit = initWithPrimitives(addPrimitive) @@ -103,6 +104,7 @@ abstract class JSPrimitives { addPrimitive(Runtime_constructorOf, CONSTRUCTOROF) addPrimitive(Runtime_linkingInfo, LINKING_INFO) + addPrimitive(Special_instanceof, INSTANCEOF) addPrimitive(Special_delete, DELETE) addPrimitive(Special_debugger, DEBUGGER) } diff --git a/library/src/main/scala/scala/scalajs/js/special/package.scala b/library/src/main/scala/scala/scalajs/js/special/package.scala index d1073c3ec7..06c87be579 100644 --- a/library/src/main/scala/scala/scalajs/js/special/package.scala +++ b/library/src/main/scala/scala/scalajs/js/special/package.scala @@ -22,6 +22,25 @@ package scala.scalajs.js */ package object special { + /** Dynamically tests whether a value is an instance of a JavaScript class. + * + * This method is the exact equivalent of `x instanceof clazz` in + * JavaScript. + * + * Using this method is only necessary when `clazz` is only known at + * run-time. In most cases, you should use + * {{{ + * x.isInstanceOf[C] + * }}} + * instead, where `C` is the statically defined class corresponding to + * `clazz`. In particular, the following identity holds for all `x` and `C`: + * {{{ + * x.isInstanceOf[C] == js.special.instanceof(x, js.constructorOf[C]) + * }}} + */ + def instanceof(x: scala.Any, clazz: scala.Any): Boolean = + throw new java.lang.Error("stub") + /** Deletes a property of an object. * * This method is the exact equivalent of the `delete obj[key]` statement diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala index f4db5e3bc9..d71ccfa427 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala @@ -17,6 +17,31 @@ import org.scalajs.testsuite.utils.AssertThrows._ class SpecialTest { import SpecialTest._ + // scala.scalajs.js.special.instanceof + + @Test def instanceofTest(): Unit = { + import js.special.instanceof + + val ObjectCtor = js.constructorOf[js.Object] + val DateCtor = js.constructorOf[js.Date] + + val obj = new js.Object + assertTrue(instanceof(obj, ObjectCtor)) + assertFalse(instanceof(obj, DateCtor)) + + val date = new js.Date + assertTrue(instanceof(date, ObjectCtor)) + assertTrue(instanceof(date, DateCtor)) + + val functionCtor: js.ThisFunction0[js.Dynamic, Unit] = { + (thiz: js.Dynamic) => + thiz.foo = 5 + } + assertFalse(instanceof(obj, functionCtor)) + val bar = js.Dynamic.newInstance(functionCtor.asInstanceOf[js.Dynamic])() + assertTrue(instanceof(bar, functionCtor)) + } + // scala.scalajs.js.special.delete @Test def should_provide_an_equivalent_of_the_JS_delete_keyword_issue_255(): Unit = { From 26c69103b3a14bbd18cc74f39d93ae4f747f22be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 23 Oct 2017 13:53:27 +0200 Subject: [PATCH 0516/2665] Make the lexical Env of FunctionEmitter more robust. The lexical `Env` of `FunctionEmitter` was previously not always complete. It was not a big deal, because it is only used to avoid spilling expressions into temporaris if they are known to be immutable. However, handling class captures in nested JS classes will require the `Env` to be complete, so that we can distinguish local variables from class captures. It is also internally nicer to have complete `Env`s. --- .../backend/emitter/FunctionEmitter.scala | 63 ++++++++++++------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git 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 index 87bb0754f7..ea0f73f2ea 100644 --- 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 @@ -879,10 +879,17 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { arg match { case Block(stats :+ expr) => val (jsStats, newEnv) = transformBlockStats(stats) - innerEnv = newEnv - val result = rec(expr)(newEnv) // right-to-left, remember? + val result = rec(expr)(newEnv) // Put the stats in a Block because ++=: is not smart js.Block(jsStats) +=: extractedStatements + innerEnv = stats.foldLeft(innerEnv) { (prev, stat) => + stat match { + case VarDef(name, tpe, mutable, _) => + prev.withDef(name, tpe, mutable) + case _ => + prev + } + } result case UnaryOp(op, lhs) => @@ -957,12 +964,11 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case _ => val temp = newSyntheticVar() - val newEnv = env.withDef(temp, arg.tpe, false) - innerEnv = newEnv val computeTemp = pushLhsInto( Lhs.VarDef(temp, arg.tpe, mutable = false), arg, Set.empty) computeTemp +=: extractedStatements + innerEnv = innerEnv.withDef(temp, arg.tpe, false) VarRef(temp)(arg.tpe) } } @@ -1267,18 +1273,20 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { * its scope. * This only matters in ECMAScript 6, because we emit Lets. */ - def extractLet(inner: Lhs => js.Tree): js.Tree = { + def extractLet(inner: (Lhs, Env) => js.Tree)( + implicit env: Env): js.Tree = { outputMode match { case OutputMode.ECMAScript51Isolated => - inner(lhs) + inner(lhs, env) case OutputMode.ECMAScript6 => lhs match { case Lhs.VarDef(name, tpe, mutable) => + val innerEnv = env.withDef(name, tpe, true) js.Block( doEmptyVarDef(name, tpe), - inner(Lhs.Assign(VarRef(name)(tpe)))) + inner(Lhs.Assign(VarRef(name)(tpe)), innerEnv)) case _ => - inner(lhs) + inner(lhs, env) } } } @@ -1360,10 +1368,11 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { unnest(elems) { (newElems, env0) => implicit val env = env0 val temp = newSyntheticVar() - js.Block( - doVarDef(temp, recTpe, mutable = false, - RecordValue(recTpe, newElems)), - doAssign(lhs, VarRef(temp)(recTpe))) + val varDef = doVarDef(temp, recTpe, mutable = false, + RecordValue(recTpe, newElems)) + val assign = doAssign(lhs, VarRef(temp)(recTpe))( + env.withDef(temp, recTpe, false)) + js.Block(varDef, assign) } case Lhs.Return(None) => @@ -1376,7 +1385,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { // Control flow constructs case Labeled(label, tpe, body) => - extractLet { newLhs => + extractLet { (newLhs, env) => val bodyEnv = env.withLabeledExprLHS(label, newLhs) val newBody = pushLhsInto(newLhs, body, tailPosLabels + label.name)(bodyEnv) @@ -1395,23 +1404,24 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case If(cond, thenp, elsep) => unnest(cond) { (newCond, env0) => implicit val env = env0 - extractLet { newLhs => + extractLet { (newLhs, branchesEnv) => js.If(transformExprNoChar(newCond), - pushLhsInto(newLhs, thenp, tailPosLabels), - pushLhsInto(newLhs, elsep, tailPosLabels)) + pushLhsInto(newLhs, thenp, tailPosLabels)(branchesEnv), + pushLhsInto(newLhs, elsep, tailPosLabels)(branchesEnv)) } } case TryCatch(block, errVar, handler) => - extractLet { newLhs => - val newBlock = pushLhsInto(newLhs, block, tailPosLabels) - val newHandler = pushLhsInto(newLhs, handler, tailPosLabels) + extractLet { (newLhs, env) => + val newBlock = pushLhsInto(newLhs, block, tailPosLabels)(env) + val newHandler = pushLhsInto(newLhs, handler, tailPosLabels)( + env.withDef(errVar, mutable = false)) js.TryCatch(newBlock, transformLocalVarIdent(errVar), newHandler) } case TryFinally(block, finalizer) => - extractLet { newLhs => - val newBlock = pushLhsInto(newLhs, block, tailPosLabels) + extractLet { (newLhs, blockEnv) => + val newBlock = pushLhsInto(newLhs, block, tailPosLabels)(blockEnv) val newFinalizer = transformStat(finalizer, Set.empty) js.TryFinally(newBlock, newFinalizer) } @@ -1436,14 +1446,14 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case Match(selector, cases, default) => unnest(selector) { (newSelector, env0) => implicit val env = env0.withDefaultBreakTargets(tailPosLabels) - extractLet { newLhs => + extractLet { (newLhs, branchesEnv) => val newCases = { for { (values, body) <- cases newValues = values.map(transformExpr(_, preserveChar = true)) // add the break statement newBody = js.Block( - pushLhsInto(newLhs, body, tailPosLabels), + pushLhsInto(newLhs, body, tailPosLabels)(branchesEnv), js.Break()) // desugar alternatives into several cases falling through caze <- (newValues.init map (v => (v, js.Skip()))) :+ (newValues.last, newBody) @@ -1451,7 +1461,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { caze } } - val newDefault = pushLhsInto(newLhs, default, tailPosLabels) + val newDefault = pushLhsInto(newLhs, default, tailPosLabels)( + branchesEnv) js.Switch(transformExpr(newSelector, preserveChar = true), newCases, newDefault) } @@ -1891,6 +1902,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { genLoadModule(cls.className) case RecordFieldVarRef(VarRef(name)) => + assert(env.isLocalVar(name), name.name) js.VarRef(transformLocalVarIdent(name)) case Select(qualifier, item) => @@ -2272,6 +2284,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { // Atomic expressions case VarRef(name) => + assert(env.isLocalVar(name), name.name) js.VarRef(transformLocalVarIdent(name)) case This() => @@ -2459,6 +2472,8 @@ private object FunctionEmitter { labeledExprLHSes: Map[String, Lhs], defaultBreakTargets: Set[String] ) { + def isLocalVar(ident: Ident): Boolean = vars.contains(ident.name) + def isLocalMutable(ident: Ident): Boolean = vars(ident.name) def lhsForLabeledExpr(label: Ident): Lhs = labeledExprLHSes(label.name) From 0c9ad5c82551eae8900fd15c5a4c81d45f0071ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 26 Oct 2017 16:57:16 +0200 Subject: [PATCH 0517/2665] Extract some JS constructor dispatch-related code in separate def. This is a purely cosmetic change. --- .../org/scalajs/core/compiler/GenJSCode.scala | 56 +++++++++++-------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 37f7a0bd6a..52569d6c4a 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -1056,38 +1056,46 @@ abstract class GenJSCode extends plugins.PluginComponent val dispatch = genJSConstructorExport(constructorTrees.map(_.symbol)) - val js.MethodDef(_, dispatchName, dispatchArgs, dispatchResultType, - Some(dispatchResolution)) = dispatch + buildJSConstructorDef(dispatch, ctors) + } + } + } - val jsConstructorBuilder = mkJSConstructorBuilder(ctors) + private def buildJSConstructorDef(dispatch: js.MethodDef, + ctors: List[js.MethodDef])( + implicit pos: Position): js.MethodDef = { - val overloadIdent = freshLocalIdent("overload") + val js.MethodDef(_, dispatchName, dispatchArgs, dispatchResultType, + Some(dispatchResolution)) = dispatch - // Section containing the overload resolution and casts of parameters - val overloadSelection = mkOverloadSelection(jsConstructorBuilder, - overloadIdent, dispatchResolution) + val jsConstructorBuilder = mkJSConstructorBuilder(ctors) - /* Section containing all the code executed before the call to `this` - * for every secondary constructor. - */ - val prePrimaryCtorBody = - jsConstructorBuilder.mkPrePrimaryCtorBody(overloadIdent) + val overloadIdent = freshLocalIdent("overload") - val primaryCtorBody = jsConstructorBuilder.primaryCtorBody + // Section containing the overload resolution and casts of parameters + val overloadSelection = mkOverloadSelection(jsConstructorBuilder, + overloadIdent, dispatchResolution) - /* Section containing all the code executed after the call to this for - * every secondary constructor. - */ - val postPrimaryCtorBody = - jsConstructorBuilder.mkPostPrimaryCtorBody(overloadIdent) + /* Section containing all the code executed before the call to `this` + * for every secondary constructor. + */ + val prePrimaryCtorBody = + jsConstructorBuilder.mkPrePrimaryCtorBody(overloadIdent) - val newBody = js.Block(overloadSelection ::: prePrimaryCtorBody :: - primaryCtorBody :: postPrimaryCtorBody :: Nil) + val primaryCtorBody = jsConstructorBuilder.primaryCtorBody - js.MethodDef(static = false, dispatchName, dispatchArgs, jstpe.NoType, - Some(newBody))(dispatch.optimizerHints, None) - } - } + /* Section containing all the code executed after the call to this for + * every secondary constructor. + */ + val postPrimaryCtorBody = + jsConstructorBuilder.mkPostPrimaryCtorBody(overloadIdent) + + val newBody = js.Block(overloadSelection ::: prePrimaryCtorBody :: + primaryCtorBody :: postPrimaryCtorBody :: Nil) + + js.MethodDef(static = false, dispatchName, dispatchArgs, + jstpe.NoType, Some(newBody))( + dispatch.optimizerHints, None) } private class ConstructorTree(val overrideNum: Int, val method: js.MethodDef, From 645fa78179665d3b6279a9391b9cc8c5d4686d40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 26 Oct 2017 16:58:34 +0200 Subject: [PATCH 0518/2665] Factor out some code inside `mkOverloadSelection`. This reduces code duplication, while making the code more generic and less dependent on the precise shape of trees that are received. --- .../org/scalajs/core/compiler/GenJSCode.scala | 79 +++++++++---------- 1 file changed, 36 insertions(+), 43 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 52569d6c4a..60374715ff 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -1265,28 +1265,32 @@ abstract class GenJSCode extends plugins.PluginComponent */ private def mkOverloadSelection(jsConstructorBuilder: JSConstructorBuilder, overloadIdent: js.Ident, dispatchResolution: js.Tree)( - implicit pos: Position): List[js.Tree]= { + implicit pos: Position): List[js.Tree] = { + + def deconstructApplyCtor(body: js.Tree): (List[js.Tree], String, List[js.Tree]) = { + val (prepStats, applyCtor) = body match { + case applyCtor: js.ApplyStatic => + (Nil, applyCtor) + case js.Block(prepStats :+ (applyCtor: js.ApplyStatic)) => + (prepStats, applyCtor) + } + val js.ApplyStatic(_, js.Ident(ctorName, _), js.This() :: ctorArgs) = + applyCtor + assert(ir.Definitions.isConstructorName(ctorName)) + (prepStats, ctorName, ctorArgs) + } + if (!jsConstructorBuilder.hasSubConstructors) { - dispatchResolution match { - /* Dispatch to constructor with no arguments. - * Contains trivial parameterless call to the constructor. - */ - case js.ApplyStatic(_, mtd, js.This() :: Nil) - if ir.Definitions.isConstructorName(mtd.name) => - Nil + val (prepStats, ctorName, ctorArgs) = + deconstructApplyCtor(dispatchResolution) - /* Dispatch to constructor with at least one argument. - * Where js.Block's stats.init corresponds to the parameter casts and - * js.Block's stats.last contains the call to the constructor. - */ - case js.Block(stats) => - val js.ApplyStatic(_, method, _) = stats.last - val refs = jsConstructorBuilder.getParamRefsFor(method.name) - val paramCasts = stats.init.map(_.asInstanceOf[js.VarDef]) - zipMap(refs, paramCasts) { (ref, paramCast) => - js.VarDef(ref.ident, ref.tpe, mutable = false, paramCast.rhs) - } + val refs = jsConstructorBuilder.getParamRefsFor(ctorName) + assert(refs.size == ctorArgs.size, currentClassSym.fullName) + val assignCtorParams = zipMap(refs, ctorArgs) { (ref, ctorArg) => + js.VarDef(ref.ident, ref.tpe, mutable = false, ctorArg) } + + prepStats ::: assignCtorParams } else { val overloadRef = js.VarRef(overloadIdent)(jstpe.IntType) @@ -1294,30 +1298,6 @@ abstract class GenJSCode extends plugins.PluginComponent * `genJSConstructorExport` and transform it recursively. */ def transformDispatch(tree: js.Tree): js.Tree = tree match { - /* Dispatch to constructor with no arguments. - * Contains trivial parameterless call to the constructor. - */ - case js.ApplyStatic(_, method, js.This() :: Nil) - if ir.Definitions.isConstructorName(method.name) => - js.Assign(overloadRef, - js.IntLiteral(jsConstructorBuilder.getOverrideNum(method.name))) - - /* Dispatch to constructor with at least one argument. - * Where js.Block's stats.init corresponds to the parameter casts and - * js.Block's stats.last contains the call to the constructor. - */ - case js.Block(stats) => - val js.ApplyStatic(_, method, _) = stats.last - - val num = jsConstructorBuilder.getOverrideNum(method.name) - val overloadAssign = js.Assign(overloadRef, js.IntLiteral(num)) - - val refs = jsConstructorBuilder.getParamRefsFor(method.name) - val paramCasts = stats.init.map(_.asInstanceOf[js.VarDef].rhs) - val parameterAssigns = zipMap(refs, paramCasts)(js.Assign(_, _)) - - js.Block(overloadAssign :: parameterAssigns) - // Parameter count resolution case js.Match(selector, cases, default) => val newCases = cases.map { @@ -1334,6 +1314,19 @@ abstract class GenJSCode extends plugins.PluginComponent // Throw(StringLiteral(No matching overload)) case tree: js.Throw => tree + + // Overload resolution done, apply the constructor + case _ => + val (prepStats, ctorName, ctorArgs) = deconstructApplyCtor(tree) + + val num = jsConstructorBuilder.getOverrideNum(ctorName) + val overloadAssign = js.Assign(overloadRef, js.IntLiteral(num)) + + val refs = jsConstructorBuilder.getParamRefsFor(ctorName) + assert(refs.size == ctorArgs.size, currentClassSym.fullName) + val assignCtorParams = zipMap(refs, ctorArgs)(js.Assign(_, _)) + + js.Block(overloadAssign :: prepStats ::: assignCtorParams) } val newDispatchResolution = transformDispatch(dispatchResolution) From 8f0a3e25a32c53973a4d9d1748eb181251853da7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 26 Oct 2017 17:00:01 +0200 Subject: [PATCH 0519/2665] Extract the inspection of a constant `classOf` in a separate def. This slightly changes some compile error messages if the user tries to manually call `runtime.constructorOf` with an invalid argument. Other than that, it is a purely cosmetic change. --- .../org/scalajs/core/compiler/GenJSCode.scala | 46 +++++++++++-------- .../compiler/test/DiverseErrorsTest.scala | 14 +++--- 2 files changed, 34 insertions(+), 26 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 60374715ff..2508e3f982 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -4003,6 +4003,29 @@ abstract class GenJSCode extends plugins.PluginComponent def receiver = genExpr(receiver0) def genArgs = genPrimitiveJSArgs(tree.symbol, args) + def resolveReifiedJSClassSym(arg: Tree): Symbol = { + def fail(): Symbol = { + reporter.error(pos, + tree.symbol.nameString + " must be called with a constant " + + "classOf[T] representing a class extending js.Any " + + "(not a trait nor an object)") + NoSymbol + } + arg match { + case Literal(value) if value.tag == ClazzTag => + val kind = toTypeKind(value.typeValue) + kind match { + case REFERENCE(classSym) if isJSType(classSym) && + !classSym.isTrait && !classSym.isModuleClass => + classSym + case _ => + fail() + } + case _ => + fail() + } + } + if (code == DYNNEW) { // js.Dynamic.newInstance(clazz)(actualArgs:_*) val (jsClass, actualArgs) = extractFirstArg(genArgs) @@ -4113,26 +4136,11 @@ abstract class GenJSCode extends plugins.PluginComponent // js.Array.create(elements: _*) js.JSArrayConstr(genArgs) } else if (code == CONSTRUCTOROF) { - def fail() = { - reporter.error(pos, - "runtime.constructorOf() must be called with a constant " + - "classOf[T] representing a class extending js.Any " + - "(not a trait nor an object)") + val classSym = resolveReifiedJSClassSym(args.head) + if (classSym == NoSymbol) js.Undefined() - } - args match { - case List(Literal(value)) if value.tag == ClazzTag => - val kind = toTypeKind(value.typeValue) - kind match { - case REFERENCE(classSym) if isJSType(classSym) && - !classSym.isTrait && !classSym.isModuleClass => - genPrimitiveJSClass(classSym) - case _ => - fail() - } - case _ => - fail() - } + else + genPrimitiveJSClass(classSym) } else (genArgs match { case Nil => code match { diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/DiverseErrorsTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/DiverseErrorsTest.scala index b71e6aedb6..7f5c0db9ab 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/DiverseErrorsTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/DiverseErrorsTest.scala @@ -262,25 +262,25 @@ class DiverseErrorsTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:17: error: runtime.constructorOf() must be called with a constant classOf[T] representing a class extending js.Any (not a trait nor an object) + |newSource1.scala:17: error: constructorOf must be called with a constant classOf[T] representing a class extending js.Any (not a trait nor an object) | val a = runtime.constructorOf(classOf[ScalaClass].asInstanceOf[Class[_ <: js.Any]]) | ^ - |newSource1.scala:18: error: runtime.constructorOf() must be called with a constant classOf[T] representing a class extending js.Any (not a trait nor an object) + |newSource1.scala:18: error: constructorOf must be called with a constant classOf[T] representing a class extending js.Any (not a trait nor an object) | val b = runtime.constructorOf(classOf[ScalaTrait].asInstanceOf[Class[_ <: js.Any]]) | ^ - |newSource1.scala:20: error: runtime.constructorOf() must be called with a constant classOf[T] representing a class extending js.Any (not a trait nor an object) + |newSource1.scala:20: error: constructorOf must be called with a constant classOf[T] representing a class extending js.Any (not a trait nor an object) | val c = runtime.constructorOf(classOf[NativeJSTrait]) | ^ - |newSource1.scala:21: error: runtime.constructorOf() must be called with a constant classOf[T] representing a class extending js.Any (not a trait nor an object) + |newSource1.scala:21: error: constructorOf must be called with a constant classOf[T] representing a class extending js.Any (not a trait nor an object) | val d = runtime.constructorOf(classOf[JSTrait]) | ^ - |newSource1.scala:24: error: runtime.constructorOf() must be called with a constant classOf[T] representing a class extending js.Any (not a trait nor an object) + |newSource1.scala:24: error: constructorOf must be called with a constant classOf[T] representing a class extending js.Any (not a trait nor an object) | val e = runtime.constructorOf(jsClassClass) | ^ - |newSource1.scala:26: error: runtime.constructorOf() must be called with a constant classOf[T] representing a class extending js.Any (not a trait nor an object) + |newSource1.scala:26: error: constructorOf must be called with a constant classOf[T] representing a class extending js.Any (not a trait nor an object) | val f = runtime.constructorOf(NativeJSObject.getClass) | ^ - |newSource1.scala:27: error: runtime.constructorOf() must be called with a constant classOf[T] representing a class extending js.Any (not a trait nor an object) + |newSource1.scala:27: error: constructorOf must be called with a constant classOf[T] representing a class extending js.Any (not a trait nor an object) | val g = runtime.constructorOf(JSObject.getClass) | ^ """ From e88b07dcf93b2eceaa972509c422d5fee5037d02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 26 Oct 2017 17:14:30 +0200 Subject: [PATCH 0520/2665] Extract the logic of calling a default getter out of genPrepareArgs. This is a purely cosmetic change. --- .../scalajs/core/compiler/GenJSExports.scala | 91 ++++++++++--------- 1 file changed, 50 insertions(+), 41 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index 032d8e71da..8e08d38af8 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -731,47 +731,8 @@ trait GenJSExports extends SubComponent { self: GenJSCode => // If argument is undefined and there is a default getter, call it val verifiedOrDefault = if (param.hasFlag(Flags.DEFAULTPARAM)) { js.If(js.BinaryOp(js.BinaryOp.===, jsArg, js.Undefined()), { - val trgSym = { - if (sym.isClassConstructor) { - /* Get the companion module class. - * For inner classes the sym.owner.companionModule can be broken, - * therefore companionModule is fetched at uncurryPhase. - */ - val companionModule = enteringPhase(currentRun.namerPhase) { - sym.owner.companionModule - } - companionModule.moduleClass - } else { - sym.owner - } - } - val defaultGetter = trgSym.tpe.member( - nme.defaultGetterName(sym.name, i+1)) - - assert(defaultGetter.exists, - s"need default getter for method ${sym.fullName}") - assert(!defaultGetter.isOverloaded) - - val trgTree = { - if (sym.isClassConstructor) genLoadModule(trgSym) - else js.This()(encodeClassType(trgSym)) - } - - // Pass previous arguments to defaultGetter - val defaultGetterArgs = - result.take(defaultGetter.tpe.params.size).toList.map(_.ref) - - if (isJSType(trgSym)) { - if (isNonNativeJSClass(defaultGetter.owner)) { - genApplyJSClassMethod(trgTree, defaultGetter, defaultGetterArgs) - } else { - reporter.error(param.pos, "When overriding a native method " + - "with default arguments, the overriding method must " + - "explicitly repeat the default arguments.") - js.Undefined() - } - } else { - genApplyMethod(trgTree, defaultGetter, defaultGetterArgs) + genCallDefaultGetter(sym, i, param.pos) { + prevArgsCount => result.take(prevArgsCount).toList.map(_.ref) } }, { // Otherwise, unbox the argument @@ -790,6 +751,54 @@ trait GenJSExports extends SubComponent { self: GenJSCode => result.toList } + private def genCallDefaultGetter(sym: Symbol, paramIndex: Int, + paramPos: Position)( + previousArgsValues: Int => List[js.Tree])( + implicit pos: Position): js.Tree = { + + val trgSym = { + if (sym.isClassConstructor) { + /* Get the companion module class. + * For inner classes the sym.owner.companionModule can be broken, + * therefore companionModule is fetched at uncurryPhase. + */ + val companionModule = enteringPhase(currentRun.namerPhase) { + sym.owner.companionModule + } + companionModule.moduleClass + } else { + sym.owner + } + } + val defaultGetter = trgSym.tpe.member( + nme.defaultGetterName(sym.name, paramIndex + 1)) + + assert(defaultGetter.exists, + s"need default getter for method ${sym.fullName}") + assert(!defaultGetter.isOverloaded) + + val trgTree = { + if (sym.isClassConstructor) genLoadModule(trgSym) + else js.This()(encodeClassType(trgSym)) + } + + // Pass previous arguments to defaultGetter + val defaultGetterArgs = previousArgsValues(defaultGetter.tpe.params.size) + + if (isJSType(trgSym)) { + if (isNonNativeJSClass(defaultGetter.owner)) { + genApplyJSClassMethod(trgTree, defaultGetter, defaultGetterArgs) + } else { + reporter.error(paramPos, "When overriding a native method " + + "with default arguments, the overriding method must " + + "explicitly repeat the default arguments.") + js.Undefined() + } + } else { + genApplyMethod(trgTree, defaultGetter, defaultGetterArgs) + } + } + /** Generate the final forwarding call to the exported method. * Attention: This method casts the arguments to the right type. The IR * checker will not detect if you pass in a wrongly typed argument. From e41ac6488dd3184f2b14e762c94fcf332da806da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 26 Oct 2017 17:17:45 +0200 Subject: [PATCH 0521/2665] Precompute information about the params of an `Exported`. Previously, in `GenJSExports`, the effective type of parameters, taking entering-uncurry and entering-posterasure into account, was recomputed several times within `genExportSameArgc`, through `computeExportArgType`. In this commit, `ExportedSymbol` itself is responsible for computing all the required information about its parameters, once. This can slightly speedup the generation of overloaded exports, but is mostly useful as a cleanup, as it gathers the relevant logic in a single place. --- .../org/scalajs/core/compiler/GenJSCode.scala | 2 +- .../scalajs/core/compiler/GenJSExports.scala | 261 ++++++++++-------- 2 files changed, 146 insertions(+), 117 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 2508e3f982..6b767aa5e3 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -114,7 +114,7 @@ abstract class GenJSCode extends plugins.PluginComponent override def newPhase(p: Phase): StdPhase = new JSCodePhase(p) - private object jsnme { + object jsnme { val anyHash = newTermName("anyHash") val arg_outer = newTermName("arg$outer") val newString = newTermName("newString") diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index 8e08d38af8..680f1b8856 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -5,7 +5,7 @@ package org.scalajs.core.compiler -import scala.collection.mutable +import scala.collection.{immutable, mutable} import scala.tools.nsc._ import scala.math.PartialOrdering @@ -323,8 +323,10 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } } - val getterBody = getter.headOption.map(genApplyForSym(minArgc = 0, - hasRestParam = false, _, static)) + val getterBody = getter.headOption.map { getterSym => + genApplyForSym(minArgc = 0, hasRestParam = false, + ExportedSymbol(getterSym), static) + } val setterArgAndBody = { if (setters.isEmpty) { @@ -376,13 +378,12 @@ trait GenJSExports extends SubComponent { self: GenJSCode => ).max // Calculates possible arg counts for normal method - def argCounts(ex: Exported) = ex match { - case ExportedSymbol(sym) => - val params = sym.tpe.params - // Find default param - val dParam = params.indexWhere { _.hasFlag(Flags.DEFAULTPARAM) } - if (dParam == -1) Seq(params.size) - else dParam to params.size + def argCounts(ex: Exported) = { + val params = ex.params + // Find default param + val dParam = params.indexWhere(_.hasDefault) + if (dParam == -1) Seq(params.size) + else dParam to params.size } // Generate tuples (argc, method) @@ -497,9 +498,8 @@ trait GenJSExports extends SubComponent { self: GenJSCode => reportCannotDisambiguateError(alts) js.Undefined() } else { - val altsByTypeTest = groupByWithoutHashCode(alts) { - case ExportedSymbol(alt) => - typeTestForTpe(computeExportArgType(alt, paramIndex)) + val altsByTypeTest = groupByWithoutHashCode(alts) { exported => + typeTestForTpe(exported.exportArgTypeAt(paramIndex)) } if (altsByTypeTest.size == 1) { @@ -522,11 +522,10 @@ trait GenJSExports extends SubComponent { self: GenJSCode => val genSubAlts = genExportSameArgc(minArgc, hasRestParam, subAlts, paramIndex+1, static, maxArgc) - def hasDefaultParam = subAlts.exists { - case ExportedSymbol(p) => - val params = p.tpe.params - params.size > paramIndex && - params(paramIndex).hasFlag(Flags.DEFAULTPARAM) + def hasDefaultParam = subAlts.exists { exported => + val params = exported.params + params.size > paramIndex && + params(paramIndex).hasDefault } val optCond = typeTest match { @@ -559,11 +558,8 @@ trait GenJSExports extends SubComponent { self: GenJSCode => val currentClass = currentClassSym.get // Find a position that is in the current class for decent error reporting - val pos = alts.collectFirst { - case ExportedSymbol(sym) if sym.owner == currentClass => sym.pos - }.getOrElse { - currentClass.pos - } + val pos = + alts.find(_.sym.owner == currentClass).fold(currentClass.pos)(_.pos) val kind = if (isNonNativeJSClass(currentClass)) "method" @@ -577,73 +573,30 @@ trait GenJSExports extends SubComponent { self: GenJSCode => s" $altsTypesInfo") } - private def computeExportArgType(alt: Symbol, paramIndex: Int): Type = { - // See the comment in genPrimitiveJSArgs for a rationale about this - enteringPhase(currentRun.uncurryPhase) { - - lazy val paramsUncurry = alt.paramss.flatten - lazy val paramsTypesUncurry = paramsUncurry.map(_.tpe) - lazy val isRepeatedUncurry = paramsUncurry.map(isRepeated) - - lazy val paramsPosterasure = enteringPhase(currentRun.posterasurePhase) { - alt.paramss.flatten - } - def paramTypePosterasure = enteringPhase(currentRun.posterasurePhase) { - paramsPosterasure.apply(paramIndex).tpe - } - - if (!alt.isClassConstructor) { - // get parameter type while resolving repeated params - if (paramsTypesUncurry.size <= paramIndex || isRepeatedUncurry(paramIndex)) { - assert(isRepeatedUncurry.last) - repeatedToSingle(paramsTypesUncurry.last) - } else { - paramTypePosterasure - } - } else { - // Compute the number of captured parameters that are added to the front - val paramsNamesUncurry = paramsUncurry.map(_.name) - val numCapturesFront = enteringPhase(currentRun.posterasurePhase) { - if (paramsNamesUncurry.isEmpty) paramsPosterasure.size - else paramsPosterasure.map(_.name).indexOfSlice(paramsNamesUncurry) - } - // get parameter type while resolving repeated params - if (paramIndex < numCapturesFront) { - // Type of a parameter that represents a captured outer context - paramTypePosterasure - } else { - val paramIndexNoCaptures = paramIndex - numCapturesFront - if (paramsTypesUncurry.size <= paramIndexNoCaptures || - isRepeatedUncurry(paramIndexNoCaptures)) { - assert(isRepeatedUncurry.last) - repeatedToSingle(paramsTypesUncurry.last) - } else { - paramsTypesUncurry(paramIndexNoCaptures) - } - } - } - } - } - /** * Generate a call to the method [[sym]] while using the formalArguments * and potentially the argument array. Also inserts default parameters if * required. */ private def genApplyForSym(minArgc: Int, hasRestParam: Boolean, - sym: Symbol, static: Boolean): js.Tree = { + exported: Exported, static: Boolean): js.Tree = { if (isNonNativeJSClass(currentClassSym) && - sym.owner != currentClassSym.get) { + exported.sym.owner != currentClassSym.get) { assert(!static) - genApplyForSymJSSuperCall(minArgc, hasRestParam, sym) + genApplyForSymJSSuperCall(minArgc, hasRestParam, exported) } else { - genApplyForSymNonJSSuperCall(minArgc, sym, static) + genApplyForSymNonJSSuperCall(minArgc, exported, static) } } private def genApplyForSymJSSuperCall(minArgc: Int, hasRestParam: Boolean, - sym: Symbol): js.Tree = { - implicit val pos = sym.pos + exported: Exported): js.Tree = { + implicit val pos = exported.pos + + val sym = exported.sym + assert(!sym.isClassConstructor, + "Trying to genApplyForSymJSSuperCall for the constructor " + + sym.fullName) val restArg = if (hasRestParam) js.JSSpread(genRestArgRef()) :: Nil @@ -670,18 +623,14 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } private def genApplyForSymNonJSSuperCall(minArgc: Int, - sym: Symbol, static: Boolean): js.Tree = { - implicit val pos = sym.pos + exported: Exported, static: Boolean): js.Tree = { + implicit val pos = exported.pos // the (single) type of the repeated parameter if any - val repeatedTpe = enteringPhase(currentRun.uncurryPhase) { - for { - param <- sym.paramss.flatten.lastOption - if isRepeated(param) - } yield repeatedToSingle(param.tpe) - } + val repeatedTpe = + exported.params.lastOption.withFilter(_.isRepeated).map(_.tpe) - val normalArgc = sym.tpe.params.size - + val normalArgc = exported.params.size - (if (repeatedTpe.isDefined) 1 else 0) // optional repeated parameter list @@ -697,8 +646,8 @@ trait GenJSExports extends SubComponent { self: GenJSCode => i => genFormalArgRef(i, minArgc)) // Generate JS code to prepare arguments (default getters and unboxes) - val jsArgPrep = genPrepareArgs(jsArgRefs, sym) ++ jsVarArgPrep - val jsResult = genResult(sym, jsArgPrep.map(_.ref), static) + val jsArgPrep = genPrepareArgs(jsArgRefs, exported) ++ jsVarArgPrep + val jsResult = genResult(exported, jsArgPrep.map(_.ref), static) js.Block(jsArgPrep :+ jsResult) } @@ -706,32 +655,21 @@ trait GenJSExports extends SubComponent { self: GenJSCode => /** Generate the necessary JavaScript code to prepare the arguments of an * exported method (unboxing and default parameter handling) */ - private def genPrepareArgs(jsArgs: List[js.Tree], sym: Symbol)( + private def genPrepareArgs(jsArgs: List[js.Tree], exported: Exported)( implicit pos: Position): List[js.VarDef] = { val result = new mutable.ListBuffer[js.VarDef] - val paramsPosterasure = - enteringPhase(currentRun.posterasurePhase)(sym.tpe).params - val paramsNow = sym.tpe.params - - /* The parameters that existed at posterasurePhase are taken from that - * phase. The parameters that where added after posterasurePhase are taken - * from the current parameter list. - */ - val params = paramsPosterasure ++ paramsNow.drop(paramsPosterasure.size) - for { - (jsArg, (param, i)) <- jsArgs zip params.zipWithIndex + (jsArg, (param, i)) <- jsArgs.zip(exported.params.zipWithIndex) } yield { // Unboxed argument (if it is defined) - val unboxedArg = fromAny(jsArg, - enteringPhase(currentRun.posterasurePhase)(param.tpe)) + val unboxedArg = fromAny(jsArg, param.tpe) // If argument is undefined and there is a default getter, call it - val verifiedOrDefault = if (param.hasFlag(Flags.DEFAULTPARAM)) { + val verifiedOrDefault = if (param.hasDefault) { js.If(js.BinaryOp(js.BinaryOp.===, jsArg, js.Undefined()), { - genCallDefaultGetter(sym, i, param.pos) { + genCallDefaultGetter(exported.sym, i, param.sym.pos) { prevArgsCount => result.take(prevArgsCount).toList.map(_.ref) } }, { @@ -743,9 +681,8 @@ trait GenJSExports extends SubComponent { self: GenJSCode => unboxedArg } - result += - js.VarDef(js.Ident("prep"+i), - verifiedOrDefault.tpe, mutable = false, verifiedOrDefault) + result += js.VarDef(js.Ident("prep" + i), + verifiedOrDefault.tpe, mutable = false, verifiedOrDefault) } result.toList @@ -799,12 +736,10 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } } - /** Generate the final forwarding call to the exported method. - * Attention: This method casts the arguments to the right type. The IR - * checker will not detect if you pass in a wrongly typed argument. - */ - private def genResult(sym: Symbol, args: List[js.Tree], + /** Generate the final forwarding call to the exported method. */ + private def genResult(exported: Exported, args: List[js.Tree], static: Boolean)(implicit pos: Position) = { + val sym = exported.sym val thisType = if (sym.owner == ObjectClass) jstpe.ClassType(ir.Definitions.ObjectClass) else encodeClassType(sym.owner) @@ -826,9 +761,26 @@ trait GenJSExports extends SubComponent { self: GenJSCode => enteringPhase(currentRun.posterasurePhase)(sym.tpe.resultType)) } + private final class ParamSpec(val sym: Symbol, val tpe: Type, + val isRepeated: Boolean, val hasDefault: Boolean) { + override def toString(): String = + s"ParamSpec(${sym.name}, $tpe, $isRepeated, $hasDefault)" + } + + private object ParamSpec extends (Symbol => ParamSpec) { + def apply(sym: Symbol): ParamSpec = { + val hasDefault = sym.hasFlag(Flags.DEFAULTPARAM) + val repeated = isRepeated(sym) + val tpe = if (repeated) repeatedToSingle(sym.tpe) else sym.tpe + new ParamSpec(sym, tpe, repeated, hasDefault) + } + } + private sealed abstract class Exported { + def sym: Symbol def pos: Position - def params: List[Type] + def params: immutable.IndexedSeq[ParamSpec] + def exportArgTypeAt(paramIndex: Int): Type def genBody(minArgc: Int, hasRestParam: Boolean, static: Boolean): js.Tree def name: String def typeInfo: String @@ -836,18 +788,95 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } private case class ExportedSymbol(sym: Symbol) extends Exported { + val params = { + val allParamsUncurry = + enteringPhase(currentRun.uncurryPhase)(sym.paramss.flatten.map(ParamSpec)) + val allParamsPosterasure = + enteringPhase(currentRun.posterasurePhase)(sym.paramss.flatten.map(ParamSpec)) + val allParamsNow = sym.paramss.flatten.map(ParamSpec) + + def mergeUncurryPosterasure(paramsUncurry: List[ParamSpec], + paramsPosterasure: List[ParamSpec]): List[ParamSpec] = { + for { + (paramUncurry, paramPosterasure) <- paramsUncurry.zip(paramsPosterasure) + } yield { + if (paramUncurry.isRepeated) paramUncurry + else paramPosterasure + } + } + + if (!sym.isClassConstructor) { + /* Easy case: all params are formal params, and we only need to + * travel back before uncurry to handle repeated params, or before + * posterasure for other params. + */ + assert(allParamsUncurry.size == allParamsPosterasure.size, + s"Found ${allParamsUncurry.size} params entering uncurry but " + + s"${allParamsPosterasure.size} params entering posterasure for " + + s"non-lifted symbol ${sym.fullName}") + val formalParams = + mergeUncurryPosterasure(allParamsUncurry, allParamsPosterasure) + formalParams.toIndexedSeq + } else { + /* The `arg$outer` param is added by explicitouter (between uncurry + * and posterasure) while the other capture params are added by + * lambdalift (between posterasure and now). + * + * Note that lambdalift creates new symbols even for parameters that + * are not the result of lambda lifting, but it preserves their + * `name`s. + */ + + val hasOuterParam = { + allParamsPosterasure.size == allParamsUncurry.size + 1 && + allParamsPosterasure.head.sym.name == jsnme.arg_outer + } + assert( + hasOuterParam || + allParamsPosterasure.size == allParamsUncurry.size, + s"Found ${allParamsUncurry.size} params entering uncurry but " + + s"${allParamsPosterasure.size} params entering posterasure for " + + s"lifted constructor symbol ${sym.fullName}") + + val nonOuterParamsPosterasure = + if (hasOuterParam) allParamsPosterasure.tail + else allParamsPosterasure + val formalParams = + mergeUncurryPosterasure(allParamsUncurry, nonOuterParamsPosterasure) + + val startOfRealParams = + allParamsNow.map(_.sym.name).indexOfSlice(allParamsUncurry.map(_.sym.name)) + val (captureParamsFront, restOfParamsNow) = + allParamsNow.splitAt(startOfRealParams) + val captureParamsBack = restOfParamsNow.drop(formalParams.size) + + val allFormalParams = + captureParamsFront ::: formalParams ::: captureParamsBack + allFormalParams.toIndexedSeq + } + } + + val hasRepeatedParam = params.nonEmpty && params.last.isRepeated + def pos: Position = sym.pos - def params: List[Type] = sym.tpe.params.map(_.tpe) + + def exportArgTypeAt(paramIndex: Int): Type = { + if (paramIndex < params.length) { + params(paramIndex).tpe + } else { + assert(hasRepeatedParam) + params.last.tpe + } + } def genBody(minArgc: Int, hasRestParam: Boolean, static: Boolean): js.Tree = - genApplyForSym(minArgc, hasRestParam, sym, static) + genApplyForSym(minArgc, hasRestParam, this, static) def name: String = if (isNonNativeJSClass(sym.owner)) jsNameOf(sym).displayName else sym.name.toString def typeInfo: String = sym.tpe.toString - def hasRepeatedParam: Boolean = GenJSExports.this.hasRepeatedParam(sym) } } From 4a8ea4d19c227bddd82ecd727438ff22af3b72da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 1 Nov 2017 15:16:15 +0100 Subject: [PATCH 0522/2665] Bump checksizes to account for a different gzip version. The version of gzip on the CI servers was changed, which causes some differences in the resulting file sizes. --- ci/checksizes.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/checksizes.sh b/ci/checksizes.sh index fa1e2fbf35..4fd0b89396 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -57,7 +57,7 @@ case $FULLVER in 2.13.0-M2) REVERSI_PREOPT_EXPECTEDSIZE=628000 REVERSI_OPT_EXPECTEDSIZE=147000 - REVERSI_PREOPT_GZ_EXPECTEDSIZE=76000 + REVERSI_PREOPT_GZ_EXPECTEDSIZE=77000 REVERSI_OPT_GZ_EXPECTEDSIZE=33000 ;; esac From b481f83a3cc38cac0da8de706469ed8f15bf0859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 1 Nov 2017 11:10:55 +0100 Subject: [PATCH 0523/2665] Remove the `crossScalaVersions` setting from the build. Due to the high variance about which projects build with what versions, we can never reasonably use the `+` command of sbt. Therefore, this setting is not actually used, and is only something we need to update when upgrading versions, for no benefit. --- project/Build.scala | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 459b7ed5d8..661b55c2c6 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -428,28 +428,6 @@ object Build { val thisBuildSettings = ( inScope(Global)(ScalaJSPlugin.globalSettings) ) ++ Seq( - // Most of the projects cross-compile - crossScalaVersions := Seq( - "2.10.2", - "2.10.3", - "2.10.4", - "2.10.5", - "2.10.6", - "2.11.0", - "2.11.1", - "2.11.2", - "2.11.4", - "2.11.5", - "2.11.6", - "2.11.7", - "2.11.8", - "2.11.11", - "2.12.0", - "2.12.1", - "2.12.2", - "2.12.3", - "2.13.0-M2" - ), // JDK version we are running with javaVersion in Global := { val fullVersion = System.getProperty("java.version") From ba9a8f78d953f292d9992f8fa3b3c45d8c96b8dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 1 Nov 2017 11:13:58 +0100 Subject: [PATCH 0524/2665] Remove the `scripts/build-all-js.sh` script. The large number of Scala versions to support, combined with the size of the test suite and the memory-hungry linker and optimizer means that this script cannot reasonably be used anymore. It is easier to do things by hand. Therefore, this script is just another thing we need to update each time we upgrade to a new Scala version, for no benefit. --- scripts/build-all-js.sh | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100755 scripts/build-all-js.sh diff --git a/scripts/build-all-js.sh b/scripts/build-all-js.sh deleted file mode 100755 index d35327a904..0000000000 --- a/scripts/build-all-js.sh +++ /dev/null @@ -1,15 +0,0 @@ -#! /bin/sh - -tasks="fastOptJS fullOptJS" -projects="helloworld/ reversi/ testingExample/test: testSuite/test:" - -for v in 2.11.11 2.10.6 2.12.3 2.13.0-M2; do - echo "++$v" - echo "package" - - for p in $projects; do - for t in $tasks; do - echo "$p$t" - done - done -done | sbt From f4a587bf33c03b82cc021ad7d2a0206296f21bba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 1 Nov 2017 11:31:45 +0100 Subject: [PATCH 0525/2665] Avoid assignments that look like named parameters. They are deprecated in Scala 2.12.4. Instead braces should be used. --- .../scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala index aac2a07c82..6c37382b27 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala @@ -56,7 +56,9 @@ final class ScalaJSFramework( new ScalaJSRunner(this, args, remoteArgs) } - private[testadapter] def runDone(): Unit = synchronized(_isRunning = false) + private[testadapter] def runDone(): Unit = synchronized { + _isRunning = false + } private def fetchFrameworkInfo() = { val runner = libEnv.comRunner(frameworkInfoLauncher) From f1f946416d28836a52445839e9b82dc08f0f7041 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 1 Nov 2017 15:20:19 +0100 Subject: [PATCH 0526/2665] Avoid eta-expansion of zero-argument methods in the reversi. Such eta-expansions are deprecated in Scala 2.12.4. --- examples/reversi/Reversi.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/reversi/Reversi.scala b/examples/reversi/Reversi.scala index 77b1e08f5a..14cd819440 100644 --- a/examples/reversi/Reversi.scala +++ b/examples/reversi/Reversi.scala @@ -66,13 +66,13 @@ class Reversi(jQuery: JQueryStatic, playground: JQuery) { def createResetButton() = { jQuery("", js.Dynamic.literal( `type` = "button", value = "Reset" - )).click(reset _) + )).click(() => reset()) } def createPassButton() = { jQuery("", js.Dynamic.literal( `type` = "button", value = "Pass" - )).click(pass _) + )).click(() => pass()) } def createStatus() = { From 0fa8ec669405c040fa7a6c545500d8dc8c310399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 1 Nov 2017 11:56:53 +0100 Subject: [PATCH 0527/2665] Fix #3157: Upgrade to Scala 2.12.4. --- ci/checksizes.sh | 6 +- ci/matrix.xml | 38 +- .../scalajs/2.12.4/BlacklistedTests.txt | 1056 +++++ .../partest/scalajs/2.12.4/BuglistedTests.txt | 7 + .../scalajs/2.12.4/WhitelistedTests.txt | 3404 +++++++++++++++++ .../scalajs/2.12.4/neg/t6446-additional.check | 30 + .../scalajs/2.12.4/neg/t6446-list.check | 2 + .../scalajs/2.12.4/neg/t6446-missing.check | 30 + .../2.12.4/neg/t6446-show-phases.check | 29 + .../scalajs/2.12.4/neg/t7494-no-options.check | 31 + .../scalajs/2.12.4/run/Course-2002-01.check | 37 + .../scalajs/2.12.4/run/Course-2002-02.check | 187 + .../scalajs/2.12.4/run/Course-2002-04.check | 64 + .../scalajs/2.12.4/run/Course-2002-08.check | 171 + .../scalajs/2.12.4/run/Course-2002-09.check | 50 + .../scalajs/2.12.4/run/Course-2002-10.check | 46 + .../partest/scalajs/2.12.4/run/Meter.check | 16 + .../scalajs/2.12.4/run/MeterCaseClass.check | 16 + .../scalajs/2.12.4/run/anyval-box-types.check | 52 + .../tools/partest/scalajs/2.12.4/run/bugs.sem | 1 + .../scalajs/2.12.4/run/caseClassHash.check | 9 + .../partest/scalajs/2.12.4/run/deeps.check | 87 + .../scalajs/2.12.4/run/dynamic-anyval.check | 4 + .../scalajs/2.12.4/run/impconvtimes.check | 1 + .../partest/scalajs/2.12.4/run/imports.check | 21 + .../scalajs/2.12.4/run/interpolation.check | 32 + .../2.12.4/run/interpolationMultiline1.check | 26 + .../partest/scalajs/2.12.4/run/issue192.sem | 1 + .../2.12.4/run/macro-bundle-static.check | 6 + .../2.12.4/run/macro-bundle-toplevel.check | 6 + .../run/macro-bundle-whitebox-decl.check | 6 + .../partest/scalajs/2.12.4/run/misc.check | 62 + .../scalajs/2.12.4/run/promotion.check | 4 + .../partest/scalajs/2.12.4/run/runtime.check | 70 + .../scalajs/2.12.4/run/spec-self.check | 2 + .../scalajs/2.12.4/run/structural.check | 37 + .../scalajs/2.12.4/run/t0421-new.check | 3 + .../scalajs/2.12.4/run/t0421-old.check | 3 + .../partest/scalajs/2.12.4/run/t1503.sem | 1 + .../partest/scalajs/2.12.4/run/t3702.check | 2 + .../partest/scalajs/2.12.4/run/t4148.sem | 1 + .../partest/scalajs/2.12.4/run/t4617.check | 1 + .../partest/scalajs/2.12.4/run/t5356.check | 6 + .../partest/scalajs/2.12.4/run/t5552.check | 6 + .../partest/scalajs/2.12.4/run/t5568.check | 9 + .../partest/scalajs/2.12.4/run/t5629b.check | 10 + .../partest/scalajs/2.12.4/run/t5680.check | 3 + .../partest/scalajs/2.12.4/run/t5866.check | 2 + .../scalajs/2.12.4/run/t6318_primitives.check | 54 + .../partest/scalajs/2.12.4/run/t6662.check | 1 + .../partest/scalajs/2.12.4/run/t7657.check | 3 + .../partest/scalajs/2.12.4/run/t7763.sem | 1 + .../partest/scalajs/2.12.4/run/t8570a.check | 1 + .../partest/scalajs/2.12.4/run/t8764.check | 5 + .../partest/scalajs/2.12.4/run/t9387b.check | 1 + .../partest/scalajs/2.12.4/run/t9656.check | 14 + .../scalajs/2.12.4/run/try-catch-unify.check | 4 + .../2.12.4/run/virtpatmat_switch.check | 7 + .../2.12.4/run/virtpatmat_typetag.check | 10 + project/Build.scala | 2 +- .../resources/2.12.4/BlacklistedTests.txt | 135 + .../resources/2.12.4/WhitelistedTests.txt | 41 + scripts/assemble-cli.sh | 4 +- scripts/publish.sh | 8 +- 64 files changed, 5964 insertions(+), 21 deletions(-) create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/BlacklistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/BuglistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/WhitelistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-additional.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-list.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-missing.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-show-phases.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t7494-no-options.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Course-2002-01.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Course-2002-02.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Course-2002-04.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Course-2002-08.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Course-2002-09.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Course-2002-10.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Meter.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/MeterCaseClass.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/anyval-box-types.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/bugs.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/caseClassHash.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/deeps.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/dynamic-anyval.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/impconvtimes.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/imports.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/interpolation.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/interpolationMultiline1.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/issue192.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/macro-bundle-static.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/macro-bundle-toplevel.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/macro-bundle-whitebox-decl.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/misc.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/promotion.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/runtime.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/spec-self.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/structural.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t0421-new.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t0421-old.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t1503.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t3702.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t4148.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t4617.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t5356.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t5552.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t5568.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t5629b.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t5680.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t5866.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t6318_primitives.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t6662.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t7657.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t7763.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t8570a.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t8764.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t9387b.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t9656.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/try-catch-unify.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/virtpatmat_switch.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/virtpatmat_typetag.check create mode 100644 scala-test-suite/src/test/resources/2.12.4/BlacklistedTests.txt create mode 100644 scala-test-suite/src/test/resources/2.12.4/WhitelistedTests.txt diff --git a/ci/checksizes.sh b/ci/checksizes.sh index 4fd0b89396..63d8ebea80 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -11,13 +11,13 @@ case $FULLVER in 2.11.11) VER=2.11 ;; - 2.12.3) + 2.12.4) VER=2.12 ;; 2.13.0-M2) VER=2.13.0-M2 ;; - 2.10.3|2.10.4|2.10.5|2.10.6|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7|2.11.8|2.12.0|2.12.1|2.12.2) + 2.10.3|2.10.4|2.10.5|2.10.6|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7|2.11.8|2.12.0|2.12.1|2.12.2|2.12.3) echo "Ignoring checksizes for Scala $FULLVER" exit 0 ;; @@ -48,7 +48,7 @@ case $FULLVER in REVERSI_PREOPT_GZ_EXPECTEDSIZE=71000 REVERSI_OPT_GZ_EXPECTEDSIZE=32000 ;; - 2.12.3) + 2.12.4) REVERSI_PREOPT_EXPECTEDSIZE=630000 REVERSI_OPT_EXPECTEDSIZE=147000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=76000 diff --git a/ci/matrix.xml b/ci/matrix.xml index 1313d44507..e7361d793f 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -327,7 +327,7 @@ 1.8 - 2.12.3 + 2.12.4 1.8 @@ -347,7 +347,7 @@ testSuite - 2.12.3 + 2.12.4 1.8 testSuite @@ -364,7 +364,7 @@ scalaTestSuite - 2.12.3 + 2.12.4 1.8 scalaTestSuite @@ -386,7 +386,7 @@ testSuite - 2.12.3 + 2.12.4 1.8 testSuite @@ -403,7 +403,7 @@ scalaTestSuite - 2.12.3 + 2.12.4 1.8 scalaTestSuite @@ -423,7 +423,7 @@ 1.8 - 2.12.3 + 2.12.4 1.8 @@ -454,7 +454,7 @@ 1.8 - 2.12.3 + 2.12.4 1.8 @@ -470,7 +470,7 @@ 1.7 - 2.12.3 + 2.12.4 1.8 @@ -486,7 +486,7 @@ 1.8 - 2.12.3 + 2.12.4 1.0.0 @@ -555,6 +555,10 @@ 2.12.2 1.8 + + 2.12.3 + 1.8 + @@ -610,11 +614,11 @@ 1.7 - 2.12.3 + 2.12.4 1.8 - 2.12.3 + 2.12.4 1.8 @@ -775,6 +779,18 @@ 2.12.2 1.8 + + 2.12.3 + 1.8 + + + 2.12.3 + 1.8 + + + 2.12.3 + 1.8 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/BlacklistedTests.txt new file mode 100644 index 0000000000..eba6a18f65 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/BlacklistedTests.txt @@ -0,0 +1,1056 @@ +# +# POS +# + +# Using Jsoup, what's that? +pos/cycle-jsoup.scala + +# Kills our IR serializer, it's an artificially super-deep if/else if +pos/t9181.scala + +# +# NEG +# + +# Screws up, but not really our problem (error: None.get instead of +# phase ordering error) +neg/t7494-multi-right-after +neg/t7494-right-after-before +neg/t7622-multi-followers +neg/t7622-cyclic-dependency + +# Uses some strange macro cross compile mechanism. +neg/macro-incompatible-macro-engine-c.scala + +# Spurious failures +neg/patmatexhaust-huge.scala + +# Uses .java files +run/t9200 +run/noInlineUnknownIndy + +# +# RUN +# + +# Relies on the exact toString() representation of Floats/Doubles +run/t2378.scala + +# Uses ClassTags on existentials which are broken in Scala (see #251) +run/valueclasses-classtag-existential.scala + +# Relies on a particular execution speed +run/t5857.scala + +# Using parts of the javalib we don't plan to support + +run/t5018.scala +run/t2417.scala +run/t4813.scala +run/lazy-concurrent.scala +run/t3667.scala +run/t3038d.scala +run/shutdownhooks.scala +run/t5590.scala +run/t3895b.scala +run/t5974.scala +run/hashset.scala +run/t5262.scala +run/serialize-stream.scala +run/sysprops.scala +run/lambda-serialization-gc.scala +run/t9390.scala +run/t9390b.scala +run/t9390c.scala +run/trait-defaults-super.scala + +run/t2849.scala +run/t1360.scala +run/t3199b.scala +run/t8690.scala + +run/various-flat-classpath-types.scala + +# Uses java.util.Collections +run/t2250.scala + +# Uses java.math.BigDecimal / BigInteger : but failures not due to them +run/hashhash.scala +run/is-valid-num.scala + +# Documented semantic difference on String.split(x: Array[Char]) +run/t0325.scala + +# Using Threads +run/t6969.scala +run/inner-obj-auto.scala +run/predef-cycle.scala +run/synchronized.scala +run/sd409.scala + +# Uses java.security +run/t2318.scala + +# Tries to catch java.lang.StackOverflowError +run/t6154.scala + +# Tries to catch java.lang.OutOfMemoryError +run/t7880.scala + +# Taking too much time, because JavaScript is not as fast as the JVM + +run/collections.scala +run/t3989.scala +run/adding-growing-set.scala +run/t3242.scala +run/hashCodeDistribution.scala +run/t408.scala +run/t6584.scala +run/t6853.scala +run/UnrolledBuffer.scala +run/t6253a.scala +run/t6253b.scala +run/t6253c.scala +run/numbereq.scala +run/t4658.scala + +# Crashes Rhino + +run/bridges.scala +run/patmat-exprs.scala + +# Using partest properties + +run/tailcalls.scala +run/t4294.scala +run/t6331b.scala + +# Using IO + +run/t6488.scala +run/t6988.scala + +# Object{Output|Input}Streams +run/t6935.scala +run/t8188.scala +run/t9375.scala +run/t9365.scala +run/inlineAddDeserializeLambda.scala +run/sammy_seriazable.scala +run/lambda-serialization-security.scala +run/t10232.scala +run/t10233.scala +run/t10244.scala +run/t10522.scala + +# Using System.getProperties + +run/t4426.scala + +# Using Await + +run/t7336.scala +run/t7775.scala +run/future-flatmap-exec-count.scala + +# Using detailed stack trace + +run/t6308.scala + +# Using reflection + +run/t6063 + +run/mixin-bridge-methods.scala +run/t5125.scala +run/outertest.scala +run/t6223.scala +run/t5652b +run/elidable-opt.scala +run/nullable-lazyvals.scala +run/t4794.scala +run/t5652 +run/t5652c +run/getClassTest-old.scala +run/t8960.scala +run/t7965.scala +run/t8087.scala +run/t8931.scala +run/t8445.scala +run/lambda-serialization.scala + +run/reflection-repl-classes.scala +run/t5256e.scala +run/typetags_core.scala +run/reflection-constructormirror-toplevel-badpath.scala +run/t5276_1b.scala +run/reflection-sorted-decls.scala +run/toolbox_typecheck_implicitsdisabled.scala +run/t5418b.scala +run/toolbox_typecheck_macrosdisabled2.scala +run/abstypetags_serialize.scala +run/all-overridden.scala +run/showraw_tree_kinds.scala +run/showraw_tree_types_ids.scala +run/showraw_tree_types_typed.scala +run/showraw_tree_ids.scala +run/showraw_tree_ultimate.scala +run/t5266_2.scala +run/t5274_1.scala +run/t5224.scala +run/reflection-sanitychecks.scala +run/t6086-vanilla.scala +run/t5277_2.scala +run/reflection-methodsymbol-params.scala +run/reflection-valueclasses-standard.scala +run/t5274_2.scala +run/t5423.scala +run/reflection-modulemirror-toplevel-good.scala +run/t5419.scala +run/t5271_3.scala +run/reflection-enclosed-nested-basic.scala +run/reflection-enclosed-nested-nested-basic.scala +run/fail-non-value-types.scala +run/exprs_serialize.scala +run/t5258a.scala +run/typetags_without_scala_reflect_manifest_lookup.scala +run/t4110-new.scala +run/t5273_2b_newpatmat.scala +run/t6277.scala +run/t5335.scala +run/toolbox_typecheck_macrosdisabled.scala +run/reflection-modulemirror-inner-good.scala +run/t5229_2.scala +run/typetags_multi.scala +run/typetags_without_scala_reflect_typetag_manifest_interop.scala +run/reflection-constructormirror-toplevel-good.scala +run/reflection-magicsymbols-invoke.scala +run/t6392b.scala +run/t5229_1.scala +run/reflection-magicsymbols-vanilla.scala +run/t5225_2.scala +run/runtimeEval1.scala +run/reflection-enclosed-nested-inner-basic.scala +run/reflection-fieldmirror-ctorparam.scala +run/t6181.scala +run/reflection-magicsymbols-repl.scala +run/t5272_2_newpatmat.scala +run/t5270.scala +run/t5418a.scala +run/t5276_2b.scala +run/t5256f.scala +run/reflection-enclosed-basic.scala +run/reflection-constructormirror-inner-badpath.scala +run/interop_typetags_are_manifests.scala +run/newTags.scala +run/t5273_1_newpatmat.scala +run/reflection-constructormirror-nested-good.scala +run/t2236-new.scala +run/existentials3-new.scala +run/t6323b.scala +run/t5943a1.scala +run/reflection-fieldmirror-getsetval.scala +run/t5272_1_oldpatmat.scala +run/t5256h.scala +run/t1195-new.scala +run/t5840.scala +run/reflection-methodsymbol-returntype.scala +run/reflection-fieldmirror-accessorsareokay.scala +run/reflection-sorted-members.scala +run/reflection-allmirrors-tostring.scala +run/valueclasses-typetag-existential.scala +run/toolbox_console_reporter.scala +run/reflection-enclosed-inner-inner-basic.scala +run/t5256b.scala +run/bytecodecs.scala +run/elidable.scala +run/freetypes_false_alarm1.scala +run/freetypes_false_alarm2.scala +run/getClassTest-new.scala +run/idempotency-extractors.scala +run/idempotency-case-classes.scala +run/idempotency-this.scala +run/idempotency-labels.scala +run/idempotency-lazy-vals.scala +run/interop_manifests_are_abstypetags.scala +run/interop_manifests_are_typetags.scala +run/abstypetags_core.scala +run/macro-reify-abstypetag-notypeparams +run/macro-reify-abstypetag-typeparams-tags +run/macro-reify-abstypetag-typeparams-notags +run/macro-reify-abstypetag-usetypetag +run/macro-reify-freevars +run/macro-reify-splice-outside-reify +run/macro-reify-tagless-a +run/macro-reify-type +run/macro-reify-typetag-typeparams-tags +run/macro-reify-typetag-notypeparams +run/macro-undetparams-implicitval +run/manifests-new.scala +run/manifests-old.scala +run/no-pickle-skolems +run/position-val-def.scala +run/reflect-priv-ctor.scala +run/primitive-sigs-2-new.scala +run/primitive-sigs-2-old.scala +run/reflection-enclosed-inner-basic.scala +run/reflection-enclosed-inner-nested-basic.scala +run/reflection-constructormirror-inner-good.scala +run/reflection-constructormirror-nested-badpath.scala +run/reflection-fancy-java-classes +run/reflection-fieldsymbol-navigation.scala +run/reflection-fieldmirror-nmelocalsuffixstring.scala +run/reflection-fieldmirror-getsetvar.scala +run/reflection-fieldmirror-privatethis.scala +run/reflection-implicit.scala +run/reflection-mem-glbs.scala +run/reflection-mem-tags.scala +run/reflection-java-annotations +run/reflection-java-crtp +run/reflection-methodsymbol-typeparams.scala +run/reflection-modulemirror-nested-badpath.scala +run/reflection-modulemirror-inner-badpath.scala +run/reflection-modulemirror-nested-good.scala +run/reflection-modulemirror-toplevel-badpath.scala +run/reflection-sync-subtypes.scala +run/reflinit.scala +run/reflection-valueclasses-derived.scala +run/reflection-valueclasses-magic.scala +run/resetattrs-this.scala +run/runtimeEval2.scala +run/showraw_aliases.scala +run/showraw_mods.scala +run/shortClass.scala +run/showraw_nosymbol.scala +run/showraw_tree.scala +run/showraw_tree_types_untyped.scala +run/t1167.scala +run/t2577.scala +run/t2873.scala +run/t2886.scala +run/t2251b.scala +run/t3346j.scala +run/t3507-new.scala +run/t3569.scala +run/t5125b.scala +run/t5225_1.scala +run/t3425b +run/t5256a.scala +run/t5230.scala +run/t5256c.scala +run/t5256g.scala +run/t5266_1.scala +run/t5269.scala +run/t5271_1.scala +run/t5271_2.scala +run/t5271_4.scala +run/t5272_1_newpatmat.scala +run/t5272_2_oldpatmat.scala +run/t5273_1_oldpatmat.scala +run/t5273_2a_newpatmat.scala +run/t5273_2a_oldpatmat.scala +run/t5275.scala +run/t5276_1a.scala +run/t5276_2a.scala +run/t5277_1.scala +run/t5279.scala +run/t5334_1.scala +run/t5334_2.scala +run/t5415.scala +run/t5418.scala +run/t5676.scala +run/t5704.scala +run/t5710-1.scala +run/t5710-2.scala +run/t5770.scala +run/t5894.scala +run/t5816.scala +run/t5824.scala +run/t5912.scala +run/t5942.scala +run/t5943a2.scala +run/t6023.scala +run/t6113.scala +run/t6175.scala +run/t6178.scala +run/t6199-mirror.scala +run/t6199-toolbox.scala +run/t6240-universe-code-gen.scala +run/t6221 +run/t6260b.scala +run/t6259.scala +run/t6287.scala +run/t6344.scala +run/t6392a.scala +run/t6591_1.scala +run/t6591_2.scala +run/t6591_3.scala +run/t6591_5.scala +run/t6591_6.scala +run/t6591_7.scala +run/t6608.scala +run/t6677.scala +run/t6687.scala +run/t6715.scala +run/t6719.scala +run/t6793.scala +run/t6860.scala +run/t6793b.scala +run/t6793c.scala +run/t7045.scala +run/t7046.scala +run/t7008-scala-defined +run/t7120b.scala +run/t7151.scala +run/t7214.scala +run/t7235.scala +run/t7331a.scala +run/t7331b.scala +run/t7331c.scala +run/t7558.scala +run/t7556 +run/t7779.scala +run/t7868b.scala +run/toolbox_current_run_compiles.scala +run/toolbox_default_reporter_is_silent.scala +run/toolbox_parse_package.scala +run/toolbox_silent_reporter.scala +run/toolbox_typecheck_inferimplicitvalue.scala +run/typetags_serialize.scala +run/valueclasses-typetag-basic.scala +run/WeakHashSetTest.scala +run/valueclasses-typetag-generic.scala +run/t4023.scala +run/t4024.scala +run/t6380.scala +run/t5273_2b_oldpatmat.scala +run/t8104 +run/t8047.scala +run/t6992 +run/var-arity-class-symbol.scala +run/typetags_symbolof_x.scala +run/typecheck +run/t8190.scala +run/t8192 +run/t8177f.scala +run/t8199.scala +run/t7932.scala +run/t7700.scala +run/t7570c.scala +run/t7570b.scala +run/t7533.scala +run/t7570a.scala +run/t7044 +run/t7328.scala +run/t6733.scala +run/t6554.scala +run/t6732.scala +run/t6379 +run/t6411b.scala +run/t6411a.scala +run/t6260c.scala +run/t6260-delambdafy.scala +run/showdecl +run/reflection-sync-potpourri.scala +run/reflection-tags.scala +run/reflection-companiontype.scala +run/reflection-scala-annotations.scala +run/reflection-idtc.scala +run/macro-reify-nested-b2 +run/mixin-signatures.scala +run/reflection-companion.scala +run/macro-reify-nested-b1 +run/macro-reify-nested-a2 +run/macro-reify-nested-a1 +run/macro-reify-chained2 +run/macro-reify-chained1 +run/inferred-type-constructors.scala +run/mirror_symbolof_x.scala +run/t8196.scala +run/t8549b.scala +run/t8574.scala +run/t8549.scala +run/t8637.scala +run/t8253.scala +run/t9027.scala +run/t6622.scala +run/toolbox_expand_macro.scala +run/toolbox-varargs +run/t9252.scala +run/t9182.scala +run/t9102.scala +run/t720.scala +run/t9408.scala +run/trait-default-specialize.scala +run/lazy-locals-2.scala +run/t5294.scala +run/trait_fields_final.scala +run/trait_fields_bytecode.scala +run/trait_fields_volatile.scala +run/junitForwarders + +run/reify_newimpl_29.scala +run/reify_magicsymbols.scala +run/reify_inheritance.scala +run/reify_newimpl_12.scala +run/reify_typerefs_2b.scala +run/reify_csv.scala +run/reify_inner2.scala +run/reify_maps_oldpatmat.scala +run/reify_newimpl_43.scala +run/reify_nested_inner_refers_to_local.scala +run/reify_closure7.scala +run/reify_closure8b.scala +run/reify_typerefs_3b.scala +run/reify_newimpl_44.scala +run/reify_newimpl_06.scala +run/reify_newimpl_05.scala +run/reify_newimpl_20.scala +run/reify_newimpl_23.scala +run/reify_metalevel_breach_-1_refers_to_1.scala +run/reify_newimpl_41.scala +run/reify-repl-fail-gracefully.scala +run/reify_fors_oldpatmat.scala +run/reify_inner3.scala +run/reify_closure8a.scala +run/reify_closures10.scala +run/reify_ann2a.scala +run/reify_newimpl_51.scala +run/reify_newimpl_47.scala +run/reify_extendbuiltins.scala +run/reify_newimpl_30.scala +run/reify_newimpl_38.scala +run/reify_closure2a.scala +run/reify_newimpl_45.scala +run/reify_closure1.scala +run/reify_generic2.scala +run/reify_printf.scala +run/reify_closure6.scala +run/reify_newimpl_37.scala +run/reify_newimpl_35.scala +run/reify_typerefs_3a.scala +run/reify_newimpl_25.scala +run/reify_ann4.scala +run/reify_typerefs_1b.scala +run/reify_newimpl_22.scala +run/reify_this.scala +run/reify_typerefs_2a.scala +run/reify_newimpl_03.scala +run/reify_newimpl_48.scala +run/reify_varargs.scala +run/reify_newimpl_42.scala +run/reify_newimpl_15.scala +run/reify_nested_inner_refers_to_global.scala +run/reify_newimpl_02.scala +run/reify_newimpl_01.scala +run/reify_fors_newpatmat.scala +run/reify_classfileann_a.scala +run/reify_nested_outer_refers_to_local.scala +run/reify_newimpl_13.scala +run/reify_closure5a.scala +run/reify_inner4.scala +run/reify_sort.scala +run/reify_ann1a.scala +run/reify_classfileann_b.scala +run/reify_closure4a.scala +run/reify_newimpl_33.scala +run/reify_sort1.scala +run/reify_properties.scala +run/reify_generic.scala +run/reify_newimpl_27.scala +run/reify-aliases.scala +run/reify_ann3.scala +run/reify-staticXXX.scala +run/reify_ann1b.scala +run/reify_ann5.scala +run/reify_anonymous.scala +run/reify-each-node-type.scala +run/reify_copypaste2.scala +run/reify_closure3a.scala +run/reify_copypaste1.scala +run/reify_complex.scala +run/reify_for1.scala +run/reify_getter.scala +run/reify_implicits-new.scala +run/reify_inner1.scala +run/reify_implicits-old.scala +run/reify_lazyunit.scala +run/reify_lazyevaluation.scala +run/reify_maps_newpatmat.scala +run/reify_metalevel_breach_+0_refers_to_1.scala +run/reify_metalevel_breach_-1_refers_to_0_a.scala +run/reify_metalevel_breach_-1_refers_to_0_b.scala +run/reify_nested_outer_refers_to_global.scala +run/reify_newimpl_04.scala +run/reify_newimpl_14.scala +run/reify_newimpl_11.scala +run/reify_newimpl_18.scala +run/reify_newimpl_19.scala +run/reify_newimpl_31.scala +run/reify_newimpl_21.scala +run/reify_newimpl_36.scala +run/reify_newimpl_39.scala +run/reify_newimpl_40.scala +run/reify_newimpl_49.scala +run/reify_newimpl_50.scala +run/reify_newimpl_52.scala +run/reify_renamed_term_basic.scala +run/reify_renamed_term_local_to_reifee.scala +run/reify_renamed_term_overloaded_method.scala +run/reify_renamed_type_basic.scala +run/reify_renamed_type_local_to_reifee.scala +run/reify_renamed_type_spliceable.scala +run/reify_typerefs_1a.scala +run/reify_timeofday.scala +run/reify_renamed_term_t5841.scala + +run/t7521b.scala +run/t8575b.scala +run/t8575c.scala +run/t8944c.scala +run/t9535.scala +run/t9437a +run/t9437b +run/t9814.scala +run/t10009.scala +run/t10075.scala +run/t10075b + +run/t8756.scala +run/inferred-type-constructors-hou.scala +run/trait-static-forwarder +run/SD-235.scala +run/t10026.scala +run/checkinit.scala +run/reflection-clinit +run/reflection-clinit-nested + +# Uses refletction indirectly through +# scala.runtime.ScalaRunTime.replStringOf +run/t6634.scala + +# Using reflection to invoke macros. These tests actually don't require +# or test reflection, but use it to separate compilation units nicely. +# It's a pity we cannot use them + +run/macro-abort-fresh +run/macro-expand-varargs-explicit-over-nonvarargs-bad +run/macro-invalidret-doesnt-conform-to-def-rettype +run/macro-invalidret-nontypeable +run/macro-invalidusage-badret +run/macro-invalidusage-partialapplication +run/macro-invalidusage-partialapplication-with-tparams +run/macro-reflective-ma-normal-mdmi +run/macro-reflective-mamd-normal-mi + +# Using macros, but indirectly creating calls to reflection +run/macro-reify-unreify + +# Using Enumeration in a way we cannot fix + +run/enums.scala +run/t3719.scala +run/t8611b.scala + +# Exceptions that become JavaScriptException + +run/pf-catch.scala +run/exceptions-2.scala +run/exceptions-nest.scala +run/t8601c.scala +run/t8601b.scala +run/inlineHandlers.scala + +# Expecting unsupported exceptions (e.g. ArrayIndexOutOfBounds) +run/optimizer-array-load.scala +run/t6827.scala +run/t8601.scala + +# Expecting exceptions that are linking errors in Scala.js (e.g. NoSuchMethodException) +run/t10334.scala + +# Playing with classfile format + +run/classfile-format-51.scala +run/classfile-format-52.scala + +# Concurrent collections (TrieMap) +# has too much stuff implemented in *.java, so no support +run/triemap-hash.scala + +# Using parallel collections + +run/t5375.scala +run/t4894.scala +run/ctries-new +run/collection-conversions.scala +run/concurrent-map-conversions.scala +run/t4761.scala +run/t7498.scala +run/t6448.scala +run/ctries-old +run/map_java_conversions.scala +run/parmap-ops.scala +run/pc-conversions.scala +run/t4459.scala +run/t4608.scala +run/t4723.scala +run/t4895.scala +run/t6052.scala +run/t6410.scala +run/t6467.scala +run/t6908.scala +run/t8955.scala + +# Using scala.xml + +run/t4124.scala + +# Using Swing + +run/t3613.scala + +# Using the REPL + +run/t4285.scala +run/constant-type.scala +run/repl-bare-expr.scala +run/repl-parens.scala +run/repl-assign.scala +run/t5583.scala +run/treePrint.scala +run/constrained-types.scala +run/repl-power.scala +run/t4710.scala +run/repl-paste.scala +run/repl-reset.scala +run/repl-paste-3.scala +run/t6329_repl.scala +run/t6273.scala +run/repl-paste-2.scala +run/t5655.scala +run/t5072.scala +run/repl-colon-type.scala +run/repl-trim-stack-trace.scala +run/t4594-repl-settings.scala +run/repl-save.scala +run/repl-paste-raw.scala +run/repl-paste-4.scala +run/t7801.scala +run/repl-backticks.scala +run/t6633.scala +run/repl-inline.scala + +# Using the Repl (scala.tools.partest.ReplTest) +run/class-symbol-contravariant.scala +run/lub-visibility.scala +run/macro-bundle-repl.scala +run/macro-repl-basic.scala +run/macro-repl-dontexpand.scala +run/macro-system-properties.scala +run/reflection-equality.scala +run/reflection-repl-elementary.scala +run/reify_newimpl_26.scala +run/repl-out-dir.scala +run/repl-term-macros.scala +run/repl-transcript.scala +run/repl-type-verbose.scala +run/t3376.scala +run/t4025.scala +run/t4172.scala +run/t4216.scala +run/t4542.scala +run/t4671.scala +run/t5256d.scala +run/t5535.scala +run/t5537.scala +run/t5789.scala +run/t6086-repl.scala +run/t6146b.scala +run/t6187.scala +run/t6320.scala +run/t6381.scala +run/t6434.scala +run/t6439.scala +run/t6507.scala +run/t6549.scala +run/t6937.scala +run/t7185.scala +run/t7319.scala +run/t7482a.scala +run/t7634.scala +run/t7747-repl.scala +run/t7805-repl-i.scala +run/tpeCache-tyconCache.scala +run/repl-empty-package +run/repl-javap-def.scala +run/repl-javap-mem.scala +run/repl-javap-outdir +run/repl-javap.scala +run/t6329_repl_bug.scala +run/t4950.scala +run/xMigration.scala +run/t6541-option.scala +run/repl-serialization.scala +run/t9174.scala +run/repl-paste-5.scala +run/repl-no-uescape.scala +run/repl-no-imports-no-predef-classbased.scala +run/repl-implicits-nopredef.scala +run/repl-classbased.scala +run/repl-no-imports-no-predef-power.scala +run/repl-paste-b.scala +run/repl-paste-6.scala +run/repl-implicits.scala +run/repl-no-imports-no-predef.scala +run/repl-paste-raw-b.scala +run/repl-paste-raw-c.scala +run/t9749-repl-dot.scala +run/trait_fields_repl.scala +run/t7139 +run/t9689 +run/trailing-commas.scala +run/t4700.scala +run/t9880-9881.scala +run/repl-kind.scala +run/t10284.scala +run/t9016.scala + +# Using Scala Script (partest.ScriptTest) + +run/t7711-script-args.scala +run/t4625.scala +run/t4625c.scala +run/t4625b.scala + +# Using the compiler API + +run/t2512.scala +run/analyzerPlugins.scala +run/compiler-asSeenFrom.scala +run/t5603.scala +run/t6440.scala +run/t5545.scala +run/existentials-in-compiler.scala +run/global-showdef.scala +run/stream_length.scala +run/annotatedRetyping.scala +run/imain.scala +run/existential-rangepos.scala +run/delambdafy_uncurry_byname_inline.scala +run/delambdafy_uncurry_byname_method.scala +run/delambdafy_uncurry_inline.scala +run/delambdafy_t6555.scala +run/delambdafy_uncurry_method.scala +run/delambdafy_t6028.scala +run/memberpos.scala +run/programmatic-main.scala +run/reflection-names.scala +run/settings-parse.scala +run/sm-interpolator.scala +run/t1501.scala +run/t1500.scala +run/sammy_java8.scala +run/t1618.scala +run/t2464 +run/t4072.scala +run/t5064.scala +run/t5385.scala +run/t5699.scala +run/t5717.scala +run/t5940.scala +run/t6028.scala +run/t6194.scala +run/t6669.scala +run/t6745-2.scala +run/t7096.scala +run/t7271.scala +run/t7337.scala +run/t7398.scala +run/t7569.scala +run/t7852.scala +run/t7817-tree-gen.scala +run/t7825.scala + +# partest.ParserTest +run/t3368.scala +run/t3368-b.scala +run/t3368-c.scala +run/t3368-d.scala +run/t9944.scala + +# partest.DirectTest +run/t6288.scala +run/t6331.scala +run/t6440b.scala +run/t6555.scala +run/t7876.scala +run/typetags_without_scala_reflect_typetag_lookup.scala +run/dynamic-updateDynamic.scala +run/dynamic-selectDynamic.scala +run/dynamic-applyDynamic.scala +run/dynamic-applyDynamicNamed.scala +run/t4841-isolate-plugins +run/large_code.scala +run/macroPlugins-namerHooks.scala +run/t4841-no-plugin.scala +run/t4332.scala +run/t8029.scala +run/t8046 +run/t5905-features.scala +run/t5905b-features.scala +run/large_class.scala +run/t8708_b +run/icode-reader-dead-code.scala +run/t5938.scala +run/t8502.scala +run/t6502.scala +run/t8907.scala +run/t9097.scala +run/macroPlugins-enterStats.scala +run/sbt-icode-interface.scala +run/t8502b.scala +run/t9437c +run/repl-paste-parse.scala +run/t5463.scala +run/t8433.scala +run/sd275.scala +run/sd275-java +run/t10471.scala +run/t6130.scala + +# Using partest.StoreReporterDirectTest +run/t10171 + +# partest.StubErrorMessageTest +run/StubErrorBInheritsFromA.scala +run/StubErrorComplexInnerClass.scala +run/StubErrorHK.scala +run/StubErrorReturnTypeFunction.scala +run/StubErrorReturnTypeFunction2.scala +run/StubErrorReturnTypePolyFunction.scala +run/StubErrorSubclasses.scala +run/StubErrorTypeclass.scala +run/StubErrorTypeDef.scala + +# partest.CompilerTest +run/t8852a.scala + +# partest.ASMConverters +run/t9403 + +# partest.BytecodeTest +run/t7106 +run/t7974 +run/t8601-closure-elim.scala +run/t4788 +run/t4788-separate-compilation + +# partest.SessionTest +run/t8843-repl-xlat.scala +run/t9206.scala +run/t9170.scala +run/t8918-unary-ids.scala +run/t1931.scala +run/t8935-class.scala +run/t8935-object.scala + +# partest.JavapTest +run/t8608-no-format.scala + +# Using .java source files + +run/t4317 +run/t4238 +run/t2296c +run/t4119 +run/t4283 +run/t4891 +run/t6168 +run/t6168b +run/t6240a +run/t6240b +run/t6548 +run/t6989 +run/t7008 +run/t7246 +run/t7246b +run/t7359 +run/t7439 +run/t7455 +run/t7510 +run/t7582-private-within +run/t7582 +run/t7582b +run/t3897 +run/t7374 +run/t3452e +run/t3452g +run/t3452d +run/t3452b +run/t3452a +run/t1430 +run/t4729 +run/t8442 +run/t8601e +run/t9298 +run/t9298b +run/t9359 +run/t7741a +run/t7741b +run/bcodeInlinerMixed +run/t9268 +run/t9489 +run/t9915 +run/t10059 +run/t1459 +run/t1459generic +run/t3236 +run/t9013 +run/t10231 +run/t10067 +run/t10249 +run/sd143 +run/t4283b +run/t7936 +run/t7936b +run/t9937 +run/t10368 +run/t10334b +run/sd304 +run/t10450 +run/t10042 + +# Using scala-script +run/t7791-script-linenums.scala + +# Suffers from bug in Node.js (https://github.com/joyent/node/issues/7528) +run/range-unit.scala + +# Using scalap +run/scalapInvokedynamic.scala + +# Using Manifests (which use Class.getInterfaces) +run/valueclasses-manifest-existential.scala +run/existentials3-old.scala +run/t2236-old.scala +run/interop_manifests_are_classtags.scala +run/valueclasses-manifest-generic.scala +run/valueclasses-manifest-basic.scala +run/t1195-old.scala +run/t3758-old.scala +run/t4110-old.scala +run/t6246.scala + +# Using ScalaRunTime.stringOf +run/value-class-extractor-seq.scala +run/t3493.scala + +# Custom invoke dynamic node +run/indy-via-macro +run/indy-via-macro-with-dynamic-args + +### Incorrect partests ### +# Badly uses constract of Console.print (no flush) +run/t429.scala +run/t6102.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/BuglistedTests.txt new file mode 100644 index 0000000000..273cb2c2d4 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/BuglistedTests.txt @@ -0,0 +1,7 @@ +# The tests in this file should pass but have never passed so far +# use scala.tools.partest.scalajs.testunknownonly to only run tests +# which are neither in BuglistedTests.txt, WhitelistedTests.txt or +# BlacklistedTests.txt + +# Broken by GCC, filed as #2815 +run/Predef.readLine.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/WhitelistedTests.txt new file mode 100644 index 0000000000..5d92152350 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/WhitelistedTests.txt @@ -0,0 +1,3404 @@ +pos/spec-super.scala +pos/t1035.scala +pos/t5897.scala +pos/irrefutable.scala +pos/spec-partialmap.scala +pos/tcpoly_seq.scala +pos/partialfun.scala +pos/t2795-new.scala +pos/clsrefine.scala +pos/t0774 +pos/t1070.scala +pos/t5957 +pos/looping-jsig.scala +pos/t3274.scala +pos/spec-fields-old.scala +pos/t262.scala +pos/t7486.scala +pos/t2261.scala +pos/t6600.scala +pos/t4786.scala +pos/t5406.scala +pos/tcpoly_late_method_params.scala +pos/t2726 +pos/pos-bug1210.scala +pos/t3312.scala +pos/manifest1-old.scala +pos/gadt-gilles.scala +pos/t4842.scala +pos/ted.scala +pos/NoCyclicReference.scala +pos/t3568.scala +pos/t0030.scala +pos/t2635.scala +pos/t7232b +pos/t0017.scala +pos/t812.scala +pos/t2179.scala +pos/t651.scala +pos/spurious-overload.scala +pos/t758.scala +pos/t4760.scala +pos/t1672.scala +pos/mixins.scala +pos/patterns.scala +pos/t1260.scala +pos/t6551.scala +pos/t2060.scala +pos/t6575a.scala +pos/t1318.scala +pos/t4266.scala +pos/t0695 +pos/protected-static +pos/t5738.scala +pos/t1226.scala +pos/t5013 +pos/t6215.scala +pos/t5692b +pos/traits.scala +pos/t2994a.scala +pos/t3371.scala +pos/t613.scala +pos/t6499.scala +pos/xlint1.scala +pos/t1150 +pos/test4a.scala +pos/t2664.scala +pos/t3528.scala +pos/t3174.scala +pos/t6994.scala +pos/t4812.scala +pos/t5777.scala +pos/t5223.scala +pos/t439.scala +pos/t3079.scala +pos/t5829.scala +pos/t0036.scala +pos/scoping2.scala +pos/t4717.scala +pos/t4257.scala +pos/t1210a.scala +pos/getClassType.scala +pos/t5330.scala +pos/t4524.scala +pos/t2945.scala +pos/t6562.scala +pos/t0273.scala +pos/override-object-yes.scala +pos/t7426.scala +pos/t6601 +pos/t3076 +pos/seq-ordering.scala +pos/spec-groups.scala +pos/t296.scala +pos/t5545 +pos/spec-multiplectors.scala +pos/t1789.scala +pos/t2569 +pos/ksbug1.scala +pos/t0599.scala +pos/local-objects.scala +pos/t0081.scala +pos/t5756.scala +pos/t7126.scala +pos/t7716.scala +pos/t2797.scala +pos/t5399.scala +pos/t1101 +pos/t767.scala +pos/contrib467.scala +pos/t7532b +pos/self-type-override.scala +pos/t4853.scala +pos/t839.scala +pos/t5644 +pos/t5853.scala +pos/t5178.scala +pos/unapplyNeedsMemberType.scala +pos/t5390.scala +pos/t6575b.scala +pos/t151.scala +pos/t2665.scala +pos/t5120.scala +pos/erasure-nsquared.scala +pos/arrays3.scala +pos/t3136.scala +pos/inline-access-levels +pos/t3972.scala +pos/t2591.scala +pos/t3486 +pos/variances-flip.scala +pos/annotated-original +pos/typesafecons.scala +pos/stable.scala +pos/t1996.scala +pos/t3037.scala +pos/t1711 +pos/t3374.scala +pos/t0029.scala +pos/t3278.scala +pos/matthias3.scala +pos/t5546.scala +pos/t4020.scala +pos/matthias4.scala +pos/value-class-override-spec.scala +pos/arrays2.scala +pos/t5119.scala +pos/t2613.scala +pos/t4070b.scala +pos/virtpatmat_exist_uncurry.scala +pos/modules1.scala +pos/spec-constr-new.scala +pos/t6335.scala +pos/t675.scala +pos/t0644.scala +pos/t5892.scala +pos/t360.scala +pos/override.scala +pos/t1798.scala +pos/strip-tvars-for-lubbasetypes.scala +pos/hk-infer.scala +pos/t2119.scala +pos/t0231.scala +pos/t1459 +pos/t1381-new.scala +pos/t2610.scala +pos/t2708.scala +pos/t5604b +pos/t3951 +pos/t361.scala +pos/t319.scala +pos/largecasetest.scala +pos/switchUnbox.scala +pos/typetags.scala +pos/java-access-pos +pos/t803.scala +pos/t3898.scala +pos/t5692a +pos/t2421.scala +pos/t1102 +pos/t0654.scala +pos/exhaust_alternatives.scala +pos/t807.scala +pos/t5702-pos-infix-star.scala +pos/t1186 +pos/t1439.scala +pos/t7427.scala +pos/virtpatmat_binding_opt.scala +pos/t247.scala +pos/abstract.scala +pos/gen-traversable-methods.scala +pos/t2795-old.scala +pos/t5639 +pos/t2667.scala +pos/t2405.scala +pos/t1438.scala +pos/t1659.scala +pos/unchecked-a.scala +pos/t3636.scala +pos/t6745.scala +pos/t2809.scala +pos/t7022.scala +pos/t6447.scala +pos/t6367.scala +pos/t5846.scala +pos/lubs.scala +pos/t1987a.scala +pos/spec-arrays.scala +pos/virtpatmat_anonfun_for.scala +pos/listpattern.scala +pos/t5742.scala +pos/test5refine.scala +pos/t5604 +pos/return_thistype.scala +pos/t348plus.scala +pos/t3420.scala +pos/t3440.scala +pos/maxim1.scala +pos/caseClassInMethod.scala +pos/t3833.scala +pos/t6675.scala +pos/t4402 +pos/t5953.scala +pos/t1152 +pos/t0591.scala +pos/t210.scala +pos/t7035.scala +pos/t5769.scala +pos/pmbug.scala +pos/t2331.scala +pos/t5240.scala +pos/t304.scala +pos/annotated-treecopy +pos/t2081.scala +pos/t0904.scala +pos/t7649.scala +pos/t3498-new.scala +pos/contrib701.scala +pos/t6624.scala +pos/t3924.scala +pos/t374.scala +pos/t1642 +pos/t1591_pos.scala +pos/depmet_implicit_oopsla_session_2.scala +pos/t5899.scala +pos/thistype.scala +pos/t4176b.scala +pos/elidable-tparams.scala +pos/lambdalift.scala +pos/nothing_manifest_disambig-old.scala +pos/t372.scala +pos/t5399a.scala +pos/t2782.scala +pos/patmat-extract-tparam.scala +pos/t4114.scala +pos/unapplyVal.scala +pos/t2486.scala +pos/t5877b.scala +pos/t0625.scala +pos/t6358_2.scala +pos/viewtest1.scala +pos/t1237.scala +pos/scala-singleton.scala +pos/t1254 +pos/t5504 +pos/bounds.scala +pos/t3631.scala +pos/t3177.scala +pos/unapplyContexts2.scala +pos/t0438.scala +pos/t1642b.scala +pos/inferbroadtype.scala +pos/t1858.scala +pos/t3731.scala +pos/t6963c.scala +pos/classtag-pos.scala +pos/t6221.scala +pos/t3343.scala +pos/spec-asseenfrom.scala +pos/t604.scala +pos/spec-example1.scala +pos/t0786.scala +pos/annot-inner.scala +pos/t5886.scala +pos/t1056.scala +pos/t294 +pos/spec-Function1.scala +pos/t1836 +pos/spec-private.scala +pos/depmet_implicit_tpbetareduce.scala +pos/exhaust_2.scala +pos/t7532 +pos/t5175.scala +pos/t802.scala +pos/t5809.scala +pos/tcpoly_typesub.scala +pos/t6029.scala +pos/contextbounds-implicits-new.scala +pos/t3480.scala +pos/patterns3.scala +pos/caseaccs.scala +pos/spec-sparsearray-old.scala +pos/patterns1213.scala +pos/spec-traits.scala +pos/t0020.scala +pos/cycle +pos/t5968.scala +pos/typealiases.scala +pos/init.scala +pos/t697.scala +pos/t2693.scala +pos/t2377 +pos/unapplyGeneric.scala +pos/t1385.scala +pos/t3363-old.scala +pos/t1236.scala +pos/t0068.scala +pos/t4052.scala +pos/lambdalift1.scala +pos/z1730.scala +pos/variances-local.scala +pos/virtpatmat_gadt_array.scala +pos/t2421_delitedsl.scala +pos/t5626.scala +pos/t690.scala +pos/t711.scala +pos/t1937 +pos/t3999 +pos/t2305.scala +pos/t2168.scala +pos/t2660.scala +pos/t1693.scala +pos/t2799.scala +pos/t6966.scala +pos/t1001.scala +pos/S5.scala +pos/t0301.scala +pos/t1048.scala +pos/t415.scala +pos/t6386.scala +pos/t2187.scala +pos/hashhash-overloads.scala +pos/t6921.scala +pos/t0227.scala +pos/t6556.scala +pos/t3946 +pos/t1053.scala +pos/t1000.scala +pos/t0586.scala +pos/t7011.scala +pos/t7329.scala +pos/t4975.scala +pos/t1131.scala +pos/t1027.scala +pos/t2913.scala +pos/t3494.scala +pos/t5606.scala +pos/t4716.scala +pos/tcpoly_gm.scala +pos/t4859.scala +pos/t514.scala +pos/lexical.scala +pos/t2624.scala +pos/t4036.scala +pos/t2741 +pos/t703.scala +pos/five-dot-f.scala +pos/t805.scala +pos/strings.scala +pos/t2433 +pos/t6925.scala +pos/t1085.scala +pos/t7461 +pos/t1942 +pos/spec-lists.scala +pos/t3349 +pos/tcpoly_infer_ticket474.scala +pos/t1614 +pos/virtpatmat_reach_const.scala +pos/t2194.scala +pos/t6976 +pos/t1560.scala +pos/t6891.scala +pos/t3883.scala +pos/infersingle.scala +pos/gui.scala +pos/t1164.scala +pos/t3175-pos.scala +pos/t4336.scala +pos/annotations2.scala +pos/proj-rec-test.scala +pos/t2973.scala +pos/t1123.scala +pos/t6205.scala +pos/t5727.scala +pos/t6537.scala +pos/t6712.scala +pos/t3866.scala +pos/t4831.scala +pos/selftails.scala +pos/t397.scala +pos/spec-vector.scala +pos/t7233b.scala +pos/t1391.scala +pos/spec.scala +pos/t3106.scala +pos/contextbounds-implicits-old.scala +pos/packageobjs.scala +pos/michel3.scala +pos/t628.scala +pos/collections.scala +pos/tcpoly_boundedmonad.scala +pos/t7668.scala +pos/t0032.scala +pos/t0069.scala +pos/t4345.scala +pos/t3521 +pos/t3071.scala +pos/tcpoly_infer_easy.scala +pos/t289.scala +pos/t4365 +pos/rangepos-anonapply.scala +pos/t5033.scala +pos/lambda.scala +pos/S8.scala +pos/t6014.scala +pos/t1785.scala +pos/t6034.scala +pos/t7433.scala +pos/imp2-pos.scala +pos/t0504.scala +pos/t1272.scala +pos/t0612 +pos/value-class-override-no-spec.scala +pos/overloaded-unapply.scala +pos/t5859.scala +pos/chang +pos/localmodules.scala +pos/t4237.scala +pos/rangepos-patmat.scala +pos/t1974.scala +pos/t0054.scala +pos/michel2.scala +pos/t0770.scala +pos/t1146.scala +pos/t2441pos.scala +pos/t5099.scala +pos/tcpoly_seq_typealias.scala +pos/t946.scala +pos/tcpoly_infer_ticket1864.scala +pos/t4737 +pos/t7377b.scala +pos/t616.scala +pos/t201.scala +pos/t6355pos.scala +pos/escapes2.scala +pos/t1675.scala +pos/t3890.scala +pos/t6040.scala +pos/spec-tailcall.scala +pos/existentials.scala +pos/t5317.scala +pos/t7782b.scala +pos/t4758.scala +pos/t7296.scala +pos/t6896.scala +pos/cls1.scala +pos/t402.scala +pos/gosh.scala +pos/t2619.scala +pos/javaConversions-2.10-regression.scala +pos/t759.scala +pos/t5259.scala +pos/t5130.scala +pos/t5156.scala +pos/t0905.scala +pos/package-implicit +pos/t2669.scala +pos/trait-parents.scala +pos/virtpatmat_exhaust.scala +pos/patterns1.scala +pos/t1231 +pos/t1751 +pos/t7233.scala +pos/t6022.scala +pos/tcpoly_checkkinds_mix.scala +pos/depmet_implicit_norm_ret.scala +pos/package-case.scala +pos/philippe4.scala +pos/michel6.scala +pos/t4188.scala +pos/t3936 +pos/t1280.scala +pos/t6722.scala +pos/t796.scala +pos/t5542.scala +pos/t3927.scala +pos/t2293.scala +pos/t3800.scala +pos/t7285a.scala +pos/t927.scala +pos/t4494.scala +pos/t3864 +pos/ilya2 +pos/t2940 +pos/S1.scala +pos/tcpoly_wildcards.scala +pos/tryexpr.scala +pos/t6089b.scala +pos/depmet_implicit_oopsla_zipwith.scala +pos/t245.scala +pos/t6146.scala +pos/t1782 +pos/t851.scala +pos/spec-thistype.scala +pos/tcpoly_poly.scala +pos/t6815_import.scala +pos/t4649.scala +pos/t0453.scala +pos/t5020.scala +pos/ilya +pos/t2435.scala +pos/t1279a.scala +pos/t1957.scala +pos/gadts2.scala +pos/t3567 +pos/Z.scala +pos/t1203b +pos/nested2.scala +pos/t1896 +pos/viewtest2.scala +pos/t5541.scala +pos/existentials-harmful.scala +pos/t4063.scala +pos/t6485a +pos/t1208.scala +pos/t5041.scala +pos/unapplyComplex.scala +pos/t3384.scala +pos/t4112.scala +pos/t788.scala +pos/hklub0.scala +pos/t757.scala +pos/t1197 +pos/t359.scala +pos/t5667.scala +pos/t1107a.scala +pos/virtpatmat_castbinder.scala +pos/t267.scala +pos/t3419 +pos/t3861.scala +pos/t6797.scala +pos/spec-localdefs.scala +pos/t3404 +pos/t4457_1.scala +pos/matthias5.scala +pos/spec-polymeth.scala +pos/kinds.scala +pos/t2310.scala +pos/t6552.scala +pos/valdefs.scala +pos/hkarray.scala +pos/homonym.scala +pos/t1235 +pos/t3429 +pos/t0053.scala +pos/depmet_implicit_chaining_zw.scala +pos/virtpatmat_partialfun_nsdnho.scala +pos/t6664.scala +pos/ticket2251.scala +pos/t3495.scala +pos/super +pos/t121.scala +pos/javaConversions-2.10-ambiguity.scala +pos/t1803.scala +pos/t5877.scala +pos/t0085.scala +pos/t3582.scala +pos/t2939.scala +pos/t1422_pos.scala +pos/manifest1-new.scala +pos/t7505.scala +pos/t5720-ownerous.scala +pos/misc-unapply_pos.scala +pos/tcpoly_variance_pos.scala +pos/t5127.scala +pos/t6123-explaintypes-implicits.scala +pos/t2764 +pos/presuperContext.scala +pos/spec-simple.scala +pos/t3120 +pos/tcpoly_infer_ticket716.scala +pos/tcpoly_bounds1.scala +pos/t7369.scala +pos/imports-pos.scala +pos/t5654.scala +pos/t0123.scala +pos/raw-map +pos/t5330b.scala +pos/t6485b +pos/t6072.scala +pos/t5692c.scala +pos/tcpoly_param_scoping.scala +pos/t6204-b.scala +pos/attachments-typed-another-ident +pos/t5359.scala +pos/ticket2197.scala +pos/t720.scala +pos/t2130-2.scala +pos/t2260.scala +pos/t0304.scala +pos/t464.scala +pos/spec-maps.scala +pos/annotDepMethType.scala +pos/t6117.scala +pos/t911.scala +pos/t757a.scala +pos/t2504.scala +pos/t1381-old.scala +pos/t1232 +pos/needstypeearly.scala +pos/moduletrans.scala +pos/t4957.scala +pos/kinzer.scala +pos/t318.scala +pos/widen-existential.scala +pos/t0095.scala +pos/t566.scala +pos/tcpoly_overloaded.scala +pos/t7516 +pos/t7232 +pos/t698.scala +pos/t0002.scala +pos/t0288 +pos/t2994b.scala +pos/cls.scala +pos/t3622 +pos/t3671.scala +pos/tcpoly_subst.scala +pos/t5703 +pos/depmet_implicit_oopsla_session_simpler.scala +pos/t5022.scala +pos/builders.scala +pos/spec-foo.scala +pos/t756.scala +pos/t1569.scala +pos/implicit-unwrap-tc.scala +pos/t3688.scala +pos/t5198.scala +pos/t432.scala +pos/t6022b.scala +pos/channels.scala +pos/t1075.scala +pos/null.scala +pos/t1840 +pos/t6479.scala +pos/t6311.scala +pos/t0039.scala +pos/t1119.scala +pos/t573.scala +pos/t1136.scala +pos/t3938 +pos/spec-sealed.scala +pos/tcpoly_return_overriding.scala +pos/t3582b.scala +pos/t229.scala +pos/t3498-old.scala +pos/t531.scala +pos/t4545.scala +pos/t6651.scala +pos/t2133.scala +pos/tinondefcons.scala +pos/t6358.scala +pos/t7690.scala +pos/t5779-numeq-warn.scala +pos/list-extractor.scala +pos/t892.scala +pos/t2127.scala +pos/t7180.scala +pos/nullary_poly.scala +pos/virtpatmat_exist3.scala +pos/t1176 +pos/spec-funs.scala +pos/specialize10.scala +pos/t6514.scala +pos/exhaustive_heuristics.scala +pos/t0066.scala +pos/t460.scala +pos/t2130-1.scala +pos/t124.scala +pos/annotations.scala +pos/pat_gilles.scala +pos/array-interfaces.scala +pos/t6210.scala +pos/t3792.scala +pos/implicits-old.scala +pos/t389.scala +pos/t115.scala +pos/virtpatmat_exhaust_unchecked.scala +pos/scoping3.scala +pos/t6033.scala +pos/depmet_implicit_oopsla_session.scala +pos/t602.scala +pos/test5.scala +pos/t611.scala +pos/t5932.scala +pos/t4910.scala +pos/unapplySeq.scala +pos/t344.scala +pos/t3363-new.scala +pos/t4018.scala +pos/t4553.scala +pos/t5082.scala +pos/t3869.scala +pos/t3836.scala +pos/tcpoly_typeapp.scala +pos/t1409 +pos/nonlocal-unchecked.scala +pos/t0082.scala +pos/z1720.scala +pos/t7232c +pos/t2018.scala +pos/t3943 +pos/t2187-2.scala +pos/unicode-decode.scala +pos/t4757 +pos/t0710.scala +pos/t0305.scala +pos/t160.scala +pos/t7591 +pos/simplelists.scala +pos/List1.scala +pos/t516.scala +pos/t6648.scala +pos/t5165 +pos/t0055.scala +pos/t4744 +pos/t7377 +pos/t5726.scala +pos/t0091.scala +pos/t6595.scala +pos/compile.scala +pos/depmet_1_pos.scala +pos/t7364 +pos/philippe3.scala +pos/spec-doubledef-old.scala +pos/t4651.scala +pos/tcpoly_infer_implicit_tuple_wrapper.scala +pos/t6274.scala +pos/tcpoly_infer_explicit_tuple_wrapper.scala +pos/ticket2201.scala +pos/spec-fields-new.scala +pos/optmatch.scala +pos/t7517.scala +pos/t3560.scala +pos/t0165.scala +pos/t0872.scala +pos/t522.scala +pos/t2234.scala +pos/t5031_2.scala +pos/tcpoly_method.scala +pos/t6482.scala +pos/pos-bug1241.scala +pos/implicits-new.scala +pos/t2484.scala +pos/t2425.scala +pos/t1049.scala +pos/michel4.scala +pos/t5958.scala +pos/virtpatmat_instof_valuetype.scala +pos/spec-t6286.scala +pos/t873.scala +pos/t3137.scala +pos/Transactions.scala +pos/t0064.scala +pos/t7486-named.scala +pos/t5444.scala +pos/simple-exceptions.scala +pos/t1006.scala +pos/t7200b.scala +pos/t3777.scala +pos/t4840.scala +pos/t211.scala +pos/nullary.scala +pos/michel1.scala +pos/t5031_3 +pos/typealias_dubious.scala +pos/spec-doubledef-new.scala +pos/philippe1.scala +pos/thistypes.scala +pos/t3570.scala +pos/t6516.scala +pos/context.scala +pos/t3808.scala +pos/philippe2.scala +pos/constfold.scala +pos/t1292.scala +pos/t1147.scala +pos/t404.scala +pos/t4430.scala +pos/A.scala +pos/spec-partially.scala +pos/t5796.scala +pos/t2409 +pos/t284-pos.scala +pos/t5313.scala +pos/t2464 +pos/t1591b.scala +pos/hk-match +pos/t595.scala +pos/t6846.scala +pos/t6162-inheritance.scala +pos/relax_implicit_divergence.scala +pos/patterns2.scala +pos/t4692.scala +pos/t3837.scala +pos/t661.scala +pos/t2810.scala +pos/depexists.scala +pos/virtpatmat_exist4.scala +pos/t5245.scala +pos/t7190.scala +pos/isApplicableSafe.scala +pos/t6204-a.scala +pos/t0076.scala +pos/t1756.scala +pos/t1745 +pos/t6091.scala +pos/t0154.scala +pos/t530.scala +pos/t2094.scala +pos/t1034.scala +pos/t6084.scala +pos/t2454.scala +pos/t2956 +pos/tcpoly_ticket2096.scala +pos/attachments-typed-ident +pos/polymorphic-case-class.scala +pos/t252.scala +pos/spec-constr-old.scala +pos/t2421c.scala +pos/t122.scala +pos/t6574.scala +pos/t3859.scala +pos/spec-params-old.scala +pos/t1196 +pos/t4593.scala +pos/t596.scala +pos/t615.scala +pos/t7689.scala +pos/t3960.scala +pos/t3986.scala +pos/exbound.scala +pos/t2545.scala +pos/t1722 +pos/t159.scala +pos/t3272.scala +pos/t6301.scala +pos/t2794.scala +pos/t3048.scala +pos/t4970.scala +pos/t607.scala +pos/FPTest.scala +pos/test1.scala +pos/t4176.scala +pos/t112606A.scala +pos/t2183.scala +pos/t430-feb09.scala +pos/t6275.scala +pos/t1832.scala +pos/t8965.scala +pos/t7596b +pos/t8900.scala +pos/t9008.scala +pos/t7704.scala +pos/t7459c.scala +pos/sammy_override.scala +pos/t8828.scala +pos/t8868c +pos/t7459d.scala +pos/t8267.scala +pos/t8844.scala +pos/t8868a +pos/t8894.scala +pos/t7459a.scala +pos/t7596c +pos/t8498.scala +pos/t8868b +pos/t5413.scala +pos/t8781 +pos/t8934a +pos/t8310.scala +pos/t3439.scala +pos/t6582_exhaust_big.scala +pos/t8954 +pos/t5217.scala +pos/t7459b.scala +pos/t9018.scala +pos/sammy_exist.scala +pos/t8893.scala +pos/t7596 +pos/t8793.scala +pos/sammy_overload.scala +pos/t6051.scala +pos/t7683-stop-after-parser +pos/t7750.scala +pos/t5454.scala +pos/t8962.scala +pos/t8947 +pos/t8719 +pos/t8410.scala +pos/patmat-suppress.scala +pos/t8999.scala +pos/t8743.scala +pos/t9157.scala +pos/t8801.scala +pos/t9086.scala +pos/t9050.scala +pos/t9135.scala +pos/t9116.scala +pos/t5154.scala +pos/t3368.scala +pos/t9321.scala +pos/t9285.scala +pos/t8861.scala +pos/t9020.scala +pos/jesper.scala +pos/t9356 +pos/virtpatmat_exhaust_big.scala +pos/t9239 +pos/t9111-inliner-workaround + +neg/volatile_no_override.scala +neg/t800.scala +neg/t5426.scala +neg/t2462a.scala +neg/t2641.scala +neg/classtags_dont_use_typetags.scala +neg/t5031 +neg/t2275b.scala +neg/macro-qmarkqmarkqmark.scala +neg/t4879.scala +neg/t5956.scala +neg/t4196.scala +neg/reify_ann2b.scala +neg/t6666b.scala +neg/warn-unused-privates.scala +neg/t6928.scala +neg/t6337.scala +neg/sealed-java-enums.scala +neg/t563.scala +neg/t900.scala +neg/deadline-inf-illegal.scala +neg/t766.scala +neg/t5429.scala +neg/overloaded-implicit.scala +neg/t875.scala +neg/abstract-class-error +neg/unchecked2.scala +neg/predef-masking.scala +neg/viewtest.scala +neg/macro-noexpand +neg/varargs.scala +neg/t963b.scala +neg/t909.scala +neg/sensitive2.scala +neg/t5390b.scala +neg/abstraction-from-volatile-type-error.scala +neg/macro-exception +neg/t4431.scala +neg/t5689.scala +neg/valueclasses.scala +neg/overload.scala +neg/t0204.scala +neg/t908.scala +neg/t750 +neg/patmatexhaust.scala +neg/macro-invalidusage-badtargs +neg/t1168.scala +neg/t5761.scala +neg/t0503.scala +neg/t7235.scala +neg/t1215.scala +neg/primitive-sigs-1 +neg/t5578.scala +neg/names-defaults-neg-warn.scala +neg/t6436b.scala +neg/t3098 +neg/t910.scala +neg/parstar.scala +neg/t4568.scala +neg/newpat_unreachable.scala +neg/t1181.scala +neg/t5903c +neg/t7294.scala +neg/t4091.scala +neg/t5452-old.scala +neg/t5696.scala +neg/t0209.scala +neg/t2910.scala +neg/t7388.scala +neg/noMember2.scala +neg/no-predef.scala +neg/t6952.scala +neg/t1909b.scala +neg/abstract-report2.scala +neg/t5318.scala +neg/t6074.scala +neg/t7171.scala +neg/abstract-vars.scala +neg/unchecked-impossible.scala +neg/variances-refinement.scala +neg/t3453.scala +neg/t5189.scala +neg/t4302.scala +neg/xmltruncated7.scala +neg/t8217-local-alias-requires-rhs.scala +neg/t7602.scala +neg/t8869.scala +neg/t9008.scala +neg/sammy_error_exist_no_crash.scala +neg/t2866.scala +neg/t8597b.scala +neg/t5691.scala +neg/t8534b.scala +neg/t5091.scala +neg/literals.scala +neg/t8534.scala +neg/t8890.scala +neg/t9008b.scala +neg/t8731.scala +neg/t8291.scala +neg/t8597.scala +neg/t5639b +neg/t6582_exhaust_big.scala +neg/t8841.scala +neg/t9041.scala +neg/t9093.scala +neg/t7623.scala +neg/t9231.scala +neg/t9286b.scala +neg/t9273.scala +neg/t9127.scala +neg/t9286c.scala +neg/t9286a.scala +neg/virtpatmat_exhaust_big.scala +neg/inlineMaxSize.scala + +run/t7249.scala +run/t3563.scala +run/t6111.scala +run/classtags_multi.scala +run/t5201.scala +run/checked.scala +run/valueclasses-classtag-basic.scala +run/t7171.scala +run/t5053.scala +run/t4535.scala +run/t5923d +run/t7291.scala +run/partialfun.scala +run/macro-term-declared-in-package-object +run/mapValues.scala +run/gadts.scala +run/t2386-new.scala +run/virtpatmat_stringinterp.scala +run/t657.scala +run/t0017.scala +run/t5713 +run/t576.scala +run/t3580.scala +run/virtpatmat_partial.scala +run/t6646.scala +run/mixins.scala +run/t1672.scala +run/macro-expand-implicit-macro-has-implicit +run/tuple-match.scala +run/t7039.scala +run/virtpatmat_opt_sharing.scala +run/virtpatmat_casting.scala +run/t2176.scala +run/macro-impl-relaxed +run/intmap.scala +run/t751.scala +run/t1591.scala +run/macro-typecheck-implicitsdisabled +run/t6911.scala +run/t5604.scala +run/macro-term-declared-in-default-param +run/collection-stacks.scala +run/multi-array.scala +run/t4560b.scala +run/buffer-slice.scala +run/t5629.scala +run/t6690.scala +run/matchonstream.scala +run/t3603.scala +run/lazy-exprs.scala +run/macro-quasiquotes +run/Course-2002-13.scala +run/t6337a.scala +run/exoticnames.scala +run/t0936.scala +run/runtime-richChar.scala +run/t6272.scala +run/t7215.scala +run/t1939.scala +run/ReverseSeqView.scala +run/lazy-leaks.scala +run/t0048.scala +run/t3994.scala +run/t2241.scala +run/t627.scala +run/t5966.scala +run/getClassTest-valueClass.scala +run/t3619.scala +run/t1300.scala +run/t2177.scala +run/t3760.scala +run/t1829.scala +run/macro-expand-implicit-macro-is-view +run/t889.scala +run/QueueTest.scala +run/t4537 +run/t3699.scala +run/t1192.scala +run/macro-expand-tparams-bounds +run/macro-expand-nullary-generic +run/t1434.scala +run/t6443-varargs.scala +run/macro-term-declared-in-trait +run/t4080.scala +run/matcharraytail.scala +run/infiniteloop.scala +run/t5733.scala +run/virtpatmat_nested_lists.scala +run/t5158.scala +run/t6695.scala +run/t6070.scala +run/t4558.scala +run/exc2.scala +run/patmat-behavior-2.scala +run/overloads.scala +run/t6957.scala +run/transform.scala +run/t5500.scala +run/t6663.scala +run/castsingleton.scala +run/t4147.scala +run/virtpatmat_staging.scala +run/t4565_1.scala +run/t5588.scala +run/run-bug4840.scala +run/t3496.scala +run/t5867.scala +run/search.scala +run/t3112.scala +run/hashsetremove.scala +run/t6443.scala +run/macro-expand-tparams-prefix +run/contrib674.scala +run/t3508.scala +run/t4300.scala +run/virtpatmat_typed.scala +run/macro-term-declared-in-class-object +run/map_test.scala +run/t5040.scala +run/t4827b.scala +run/lift-and-unlift.scala +run/t6574b.scala +run/t7240 +run/t3984.scala +run/virtpatmat_tailcalls_verifyerror.scala +run/macro-term-declared-in-class-class +run/emptypf.scala +run/t6104.scala +run/t2818.scala +run/t3761-overload-byname.scala +run/t2526.scala +run/phantomValueClass.scala +run/t3126.scala +run/arybufgrow.scala +run/t3980.scala +run/t7375b +run/t6077_patmat_cse_irrefutable.scala +run/classmanifests_new_core.scala +run/t3395.scala +run/name-based-patmat.scala +run/inliner-infer.scala +run/t5171.scala +run/t3726.scala +run/null-hash.scala +run/t4027.scala +run/t2544.scala +run/patmatnew.scala +run/t5923b +run/t7242.scala +run/classtags_core.scala +run/streamWithFilter.scala +run/t3038b.scala +run/macro-expand-varargs-explicit-over-nonvarargs-good +run/macro-divergence-spurious +run/macro-duplicate +run/t2958.scala +run/patch-boundary.scala +run/t2333.scala +run/lazy-override-run.scala +run/macro-quasiinvalidbody-c +run/t5037.scala +run/takeAndDrop.scala +run/t6126.scala +run/t0883.scala +run/t7617a +run/t4171.scala +run/empty-array.scala +run/t7198.scala +run/t493.scala +run/genericValueClass.scala +run/t0677-old.scala +run/t1373.scala +run/t4461.scala +run/t6011b.scala +run/t7584.scala +run/t3935.scala +run/t6928-run.scala +run/t744.scala +run/t3241.scala +run/blame_eye_triple_eee-double.scala +run/t3829.scala +run/t5577.scala +run/t5914.scala +run/t601.scala +run/t5610.scala +run/macro-basic-mamd-mi +run/t6150.scala +run/stringbuilder.scala +run/t7290.scala +run/t6888.scala +run/t6327.scala +run/virtpatmat_unapplyseq.scala +run/t4656.scala +run/macro-term-declared-in-method +run/macro-expand-implicit-macro-is-implicit +run/blame_eye_triple_eee-float.scala +run/t4482.scala +run/t5488.scala +run/matchemptyarray.scala +run/t3714.scala +run/richWrapperEquals.scala +run/t5328.scala +run/stream_flatmap_odds.scala +run/implicitclasses.scala +run/t6394b +run/complicatedmatch.scala +run/valueclasses-classmanifest-basic.scala +run/unreachable.scala +run/caseclasses.scala +run/withIndex.scala +run/exc1.scala +run/amp.scala +run/t1423.scala +run/t594.scala +run/t6353.scala +run/byname.scala +run/vector1.scala +run/t5879.scala +run/t1048.scala +run/t5080.scala +run/t4190.scala +run/caseClassEquality.scala +run/macro-enclosures +run/collections-toSelf.scala +run/implicits.scala +run/finalvar.scala +run/lazy-locals.scala +run/t7231.scala +run/t0508.scala +run/t6628.scala +run/t6406-regextract.scala +run/t0911.scala +run/t4013c.scala +run/t3502.scala +run/t5648.scala +run/retclosure.scala +run/t2857.scala +run/t4859.scala +run/t5162.scala +run/t3038.scala +run/classof.scala +run/t4062.scala +run/unapplyArray.scala +run/t4297.scala +run/t5923a +run/t1537.scala +run/boolexprs.scala +run/valueclasses-classtag-generic.scala +run/macro-term-declared-in-anonymous +run/tcpoly_monads.scala +run/t5407.scala +run/scan.scala +run/forvaleq.scala +run/null-and-intersect.scala +run/t7047 +run/t0607.scala +run/sequenceComparisons.scala +run/t4396.scala +run/macro-undetparams-consfromsls +run/t2029.scala +run/t1220.scala +run/option-fold.scala +run/t5284c.scala +run/macro-auto-duplicate +run/t3529.scala +run/t4697.scala +run/t2251.scala +run/t5300.scala +run/virtpatmat_valdef.scala +run/t2147.scala +run/virtpatmat_extends_product.scala +run/list_map.scala +run/t1333.scala +run/matchbytes.scala +run/valueclasses-classmanifest-existential.scala +run/records.scala +run/t3088.scala +run/macro-def-path-dependent +run/t6443-by-name.scala +run/t1044.scala +run/delay-good.scala +run/case-class-23.scala +run/weakconform.scala +run/patmat-bind-typed.scala +run/t4835.scala +run/t3097.scala +run/t405.scala +run/existentials.scala +run/t2876.scala +run/t4809.scala +run/t1427.scala +run/t6135.scala +run/t3575.scala +run/t5688.scala +run/t6900.scala +run/macro-expand-unapply-a +run/t6677b.scala +run/t7375a.scala +run/t7300.scala +run/typed-annotated +run/elidable-noflags.scala +run/t0042.scala +run/t3050.scala +run/t4536.scala +run/NestedClasses.scala +run/t3877.scala +run/seqlike-kmp.scala +run/t5907.scala +run/t266.scala +run/missingparams.scala +run/t2255.scala +run/t3488.scala +run/t3950.scala +run/typealias_overriding.scala +run/constant-optimization.scala +run/t7507.scala +run/t6090.scala +run/t4582.scala +run/macro-term-declared-in-class +run/macro-typecheck-macrosdisabled2 +run/t3425.scala +run/t4935.scala +run/t3326.scala +run/boolord.scala +run/t1141.scala +run/virtpatmat_unapply.scala +run/t5971.scala +run/t3651.scala +run/macro-sip19-revised +run/pure-args-byname-noinline.scala +run/preinits.scala +run/t5532.scala +run/concat-two-strings.scala +run/t3269.scala +run/macro-impl-default-params +run/t2162.scala +run/matchonseq.scala +run/t5428.scala +run/macro-expand-overload +run/t4660.scala +run/enrich-gentraversable.scala +run/macro-expand-override +run/t4054.scala +run/t4753.scala +run/macro-typecheck-macrosdisabled +run/t2308a.scala +run/duplicate-meth.scala +run/interop_classtags_are_classmanifests.scala +run/t3232.scala +run/t2075.scala +run/virtpatmat_partial_backquoted.scala +run/try-2.scala +run/macro-openmacros +run/macro-undetparams-macroitself +run/t6318_derived.scala +run/deprecate-early-type-defs.scala +run/dead-code-elimination.scala +run/t4827.scala +run/Course-2002-07.scala +run/slice-strings.scala +run/t6292.scala +run/t6206.scala +run/t1042.scala +run/t1718.scala +run/t2074_2.scala +run/arraycopy.scala +run/indexedSeq.scala +run/macro-term-declared-in-implicit-class +run/t3511.scala +run/t6290.scala +run/distinct.scala +run/virtpatmat_alts.scala +run/valueclasses-pavlov.scala +run/exceptions.scala +run/t1368.scala +run/t5856.scala +run/t6968.scala +run/names-defaults.scala +run/macro-expand-tparams-implicit +run/t5881.scala +run/t3540.scala +run/virtpatmat_try.scala +run/t7181.scala +run/value-class-extractor.scala +run/value-class-extractor-2.scala +run/t3150.scala +run/exc.scala +run/delay-bad.scala +run/infix.scala +run/t1309.scala +run/t6370.scala +run/t6725-2.scala +run/macro-impl-tparam-typetag-is-optional +run/macro-term-declared-in-block +run/matchnull.scala +run/t2127.scala +run/t7325.scala +run/groupby.scala +run/t3932.scala +run/t4871.scala +run/longmap.scala +run/t1524.scala +run/t6187b.scala +run/kmpSliceSearch.scala +run/t7088.scala +run/t5804.scala +run/stringbuilder-drop.scala +run/t5753_1 +run/t9223.scala +run/function-null-unbox.scala +run/t9223b.scala +run/disable-assertions.scala +run/valueClassSelfType.scala +run/indylambda-boxing +run/t9219.scala + +pos/cyclics-pos.scala +pos/cfcrash.scala +pos/tcpoly_higherorder_bound_method.scala +pos/t5084.scala +pos/macro-qmarkqmarkqmark.scala +pos/t7785.scala +pos/nested.scala +pos/t3152.scala +pos/t5031 +pos/t6925b.scala +pos/t1107b +pos/t5012.scala +pos/virtpatmat_obj_in_case.scala +pos/t4938.scala +pos/t3856.scala +pos/spec-cyclic.scala +pos/aliases.scala +pos/typerep_pos.scala +pos/t119.scala +pos/t1050.scala +pos/t3670.scala +pos/t6145.scala +pos/t7315.scala +pos/t5930.scala +pos/t789.scala +pos/t5071.scala +pos/t4731.scala +pos/t4547.scala +pos/t2038.scala +pos/testCoercionThis.scala +pos/t2444.scala +pos/t5744 +pos/t780.scala +pos/t1722-A.scala +pos/virtpatmat_exist1.scala +pos/t6225.scala +pos/t762.scala +pos/t0204.scala +pos/rebind.scala +pos/spec-short.scala +pos/comp-rec-test.scala +pos/lub-dealias-widen.scala +pos/t1168.scala +pos/modules.scala +pos/t4220.scala +pos/t4070.scala +pos/t175.scala +pos/t2500.scala +pos/t5029.scala +pos/itay.scala +pos/t4202.scala +pos/t1987b +pos/t3534.scala +pos/infer2-pos.scala +pos/spec-sparsearray-new.scala +pos/t7091.scala +pos/ticket0137.scala +pos/collectGenericCC.scala +pos/t640.scala +pos/t4305.scala +pos/extractor-types.scala +pos/t3880.scala +pos/spec-annotations.scala +pos/t3577.scala +pos/compile1.scala +pos/spec-t3497.scala +pos/hkrange.scala +pos/t287.scala +pos/t6008.scala +pos/t4432.scala +pos/CustomGlobal.scala +pos/patmat.scala +pos/t2413 +pos/t2910.scala +pos/t592.scala +pos/t6245 +pos/infer.scala +pos/t7228.scala +pos/compound.scala +pos/attributes.scala +pos/t6771.scala +pos/t1090.scala +pos/t684.scala +pos/t577.scala +pos/t4273.scala +pos/t6278-synth-def.scala +pos/t6184.scala +neg/t0214.scala +neg/t4842.scala +neg/t6214.scala +neg/reify_nested_inner_refers_to_local.scala +neg/t576.scala +neg/t5969.scala +neg/tcpoly_variance.scala +neg/t7509.scala +neg/mixins.scala +neg/parent-inherited-twice-error.scala +neg/macro-abort +neg/constructor-init-order.scala +neg/t6042.scala +neg/t0590.scala +neg/t4221.scala +neg/t6263.scala +neg/t783.scala +neg/t5554.scala +neg/macro-invalidsig-params-badtype +neg/multi-array.scala +neg/raw-types-stubs +neg/spec-overrides.scala +neg/t836.scala +neg/t7289_status_quo.scala +neg/t5675.scala +neg/macro-quasiquotes +neg/t6667.scala +neg/t6597.scala +neg/t6264.scala +neg/t0345.scala +neg/t7294b.scala +neg/t5340.scala +neg/t2144.scala +neg/t1010.scala +neg/t1838.scala +neg/t5189b.scala +neg/reify_metalevel_breach_-1_refers_to_1.scala +neg/t6601 +neg/wellkinded_wrongarity.scala +neg/t3909.scala +neg/t876.scala +neg/t5390.scala +neg/unit2anyref.scala +neg/t0351.scala +neg/t5120.scala +neg/t1038.scala +neg/t5878.scala +neg/qualifying-class-error-2.scala +neg/t3816.scala +neg/tailrec.scala +neg/volatile.scala +neg/t944.scala +neg/t1705.scala +neg/t3977.scala +neg/t5553_2.scala +neg/t5318c.scala +neg/overload-msg.scala +neg/t5440.scala +neg/t6335.scala +neg/compile-time-only-b.scala +neg/t501.scala +neg/override.scala +neg/t663.scala +neg/t5892.scala +neg/t1980.scala +neg/macro-false-deprecation-warning +neg/t585.scala +neg/t3776.scala +neg/interop_classtags_arenot_manifests.scala +neg/t4044.scala +neg/macro-invalidusage-nontypeable +neg/t500.scala +neg/t4877.scala +neg/t5357.scala +neg/interop_abstypetags_arenot_manifests.scala +neg/t4460a.scala +neg/t5318b.scala +neg/t4440.scala +neg/t6663.scala +neg/t6357.scala +neg/gadts1.scala +neg/cyclics.scala +neg/t5060.scala +neg/scopes.scala +run/t4013.scala +run/macro-expand-tparams-explicit +run/tuples.scala +run/t5753_2 +run/t0528.scala +run/t5105.scala +run/t7341.scala +run/t3670.scala +run/t2594_tcpoly.scala +run/t3895.scala +run/t0668.scala +run/slices.scala +run/t6666a.scala +run/valueclasses-classmanifest-generic.scala +run/t2316_run.scala +run/t3004.scala +run/viewtest.scala +run/t6481.scala +run/t0005.scala +run/t4766.scala +run/t5500b.scala +run/t7407b.scala +run/backreferences.scala +run/arrayview.scala +run/t629.scala +run/t5903c +run/unittest_collection.scala +run/spec-nlreturn.scala +run/macro-term-declared-in-object-object +run/triple-quoted-expr.scala +run/t5937.scala +run/t6011c.scala +run/macro-expand-implicit-argument +run/try.scala +run/t1987b +run/t6089.scala +run/macro-range +run/t2524.scala +run/t4770.scala +run/virtpatmat_unapplyprod.scala +run/t1535.scala +run/ctor-order.scala +pos/t5210.scala +pos/t5384.scala +pos/rangepos.scala +pos/t443.scala +pos/t1480.scala +pos/t116.scala +pos/seqtest2.scala +pos/scoping1.scala +pos/t4269.scala +pos/lookupswitch.scala +pos/t3642 +pos/t5706.scala +pos/t7264 +pos/t0031.scala +pos/macro-deprecate-dont-touch-backquotedidents.scala +pos/t6815.scala +pos/test4refine.scala +pos/michel5.scala +pos/t0851.scala +pos/t1185.scala +pos/sudoku.scala +pos/t7520.scala +pos/t6208.scala +pos/t3411.scala +pos/t295.scala +pos/S3.scala +pos/t0674.scala +pos/t6664b.scala +pos/variances_pos.scala +pos/liftcode_polymorphic.scala +pos/t3174b.scala +pos/t7232d +pos/t578.scala +pos/implicit-infix-ops.scala +pos/t4363.scala +pos/t532.scala +pos/exponential-spec.scala +pos/t599.scala +pos/t5862.scala +pos/t4603 +pos/t3676.scala +pos/t1357.scala +pos/native-warning.scala +pos/t1230 +pos/t6028 +pos/t4275.scala +pos/overloaded_extractor_and_regular_def.scala +pos/t4205 +pos/matthias1.scala +pos/testcast.scala +pos/generic-sigs.scala +pos/t0093.scala +pos/specializes-sym-crash.scala +pos/t0061.scala +pos/t2429.scala +pos/t694.scala +pos/javaReadsSigs +pos/t2023.scala +pos/t704.scala +pos/t2208_pos.scala +pos/t5137.scala +pos/t2683.scala +pos/t0049.scala +pos/t1029 +pos/t4243.scala +pos/typerep-stephane.scala +pos/t177.scala +pos/t5967.scala +pos/t430.scala +pos/virtpatmat_infer_single_1.scala +pos/pat_iuli.scala +pos/t1071.scala +pos/t7226.scala +pos/t1843.scala +pos/t419.scala +pos/t7364b +pos/t1159.scala +pos/t5305.scala +pos/t7694.scala +pos/t6047.scala +pos/t3578.scala +pos/t2082.scala +pos/setter-not-implicit.scala +pos/t1133.scala +pos/t3862.scala +pos/t942 +pos/nothing_manifest_disambig-new.scala +pos/iterator-traversable-mix.scala +pos/eta.scala +pos/test4.scala +pos/t2691.scala +pos/t4502.scala +pos/t7183.scala +pos/protected-t1010.scala +pos/X.scala +pos/virtpatmat_exist2.scala +pos/t4911.scala +pos/t3477.scala +pos/t4173.scala +pos/t7782.scala +pos/t2399.scala +pos/virtpatmat_alts_subst.scala +pos/propagate.scala +pos/t2421b_pos.scala +pos/t183.scala +pos/t7033.scala +pos/t3612.scala +pos/t5330c.scala +pos/t3020.scala +pos/t4869.scala +pos/t3373.scala +pos/spec-params-new.scala +pos/t3672.scala +pos/t4501.scala +pos/t1565.scala +pos/t3774.scala +pos/t6942 +pos/t845.scala +pos/t3240.scala + +neg/t3275.scala +neg/t421.scala +neg/t5702-neg-bad-brace.scala +neg/t3663 +neg/badtok-1.scala +neg/t677.scala +neg/t7756b.scala +neg/t6534.scala +neg/t6276.scala +neg/t5762.scala +neg/abstract.scala +neg/t2405.scala +neg/t0418.scala +neg/t5390c.scala +neg/lazyvals.scala +neg/lubs.scala +neg/abstract-report.scala +neg/t4163.scala +neg/t5702-neg-bad-and-wild.scala +neg/macro-invalidret +neg/t6728.scala +neg/t5152.scala +neg/t1432.scala +neg/abstract-inaccessible.scala +neg/import-precedence.scala +neg/t2462b.scala +neg/macro-invalidusage-presuper +neg/specification-scopes +neg/t6048.scala +neg/t4079 +neg/macro-basic-mamdmi +neg/t7020.scala +neg/t3015.scala +neg/t0207.scala +neg/t2296b +neg/t0673 +neg/t3761-overload-byname.scala +neg/t6675.scala +neg/t5529.scala +neg/sensitive.scala +neg/t742.scala +neg/t5067.scala +neg/t6162-overriding.scala +neg/variances.scala +neg/t5728.scala +neg/t6323a.scala +neg/compile-time-only-a.scala +neg/t6795.scala +neg/t2494.scala +neg/t3649.scala +neg/macro-invalidsig +neg/t2796.scala +neg/t112706A.scala +neg/t0764.scala +neg/t3757 +neg/t1431.scala +neg/exhausting.scala +neg/t1523.scala +neg/t779.scala +neg/xmltruncated1.scala +neg/t2208.scala +neg/t2078.scala +neg/t521.scala +neg/null-unsoundness.scala +neg/stmt-expr-discard.scala +neg/t0513.scala +neg/unchecked-abstract.scala +neg/t4460c.scala +neg/divergent-implicit.scala +neg/t5078.scala +neg/t1701.scala +neg/t0816.scala +neg/t1672b.scala +neg/macro-invalidusage-badbounds +neg/tailrec-2.scala +neg/t4064.scala +neg/t5510.scala +neg/t3873.scala +neg/tailrec-3.scala +neg/t0226.scala +neg/t2031.scala +neg/t633.scala +neg/constrs.scala +neg/anyval-anyref-parent.scala +neg/t7290.scala +neg/t1041.scala +neg/patternalts.scala +neg/error_tooManyArgsPattern.scala +neg/checksensibleUnit.scala +neg/t6539 +neg/t4417.scala +neg/wellkinded_app.scala +neg/for-comprehension-old.scala +neg/t2779.scala +neg/object-not-a-value.scala +neg/t2968b.scala +neg/t6483.scala +neg/t6902.scala +neg/t6963a.scala +neg/t3399.scala +neg/t0015.scala +neg/t3995.scala +neg/t276.scala +neg/t6758.scala +neg/t2441.scala +neg/cycle-bounds.scala +neg/t1241.scala +neg/t4137.scala +neg/unicode-unterminated-quote.scala +neg/t4762.scala +neg/typeerror.scala +neg/implicits.scala +neg/t961.scala +neg/ambiguous-float-dots2.scala +neg/t2416.scala +neg/t5799.scala +neg/t7285.scala +neg/implicit-shadow.scala +neg/t2388.scala +neg/java-access-neg +neg/found-req-variance.scala +neg/hk-bad-bounds.scala +neg/t3224.scala +neg/t1033.scala +neg/t7385.scala +neg/t5882.scala +neg/t4541.scala +neg/t2973.scala +neg/t6406-regextract.scala +neg/t6666.scala +neg/t4831.scala +neg/t425.scala +neg/t1845.scala +neg/t3683b.scala +neg/t2801.scala +neg/t6083.scala +neg/t0528neg.scala +neg/stringinterpolation_macro-neg.scala +neg/t668.scala +neg/t5666.scala +neg/t4271.scala +neg/interop_typetags_arenot_classmanifests.scala +neg/t1355.scala +neg/t715.scala +neg/t7238.scala +neg/t7473.scala +neg/t7292-removal.scala +neg/tcpoly_infer_ticket1162.scala +neg/t4098.scala +neg/t6013 +neg/t6227.scala +neg/t464-neg.scala +neg/badtok-3.scala +neg/t6082.scala +neg/anytrait.scala +neg/valueclasses-doubledefs.scala +neg/t7519.scala +neg/overloaded-unapply.scala +neg/t1163.scala +neg/wellkinded_bounds.scala +neg/t7292-deprecation.scala +neg/t5044.scala +neg/t0842.scala +neg/t6436.scala +neg/interop_typetags_arenot_classtags.scala +neg/t3653.scala +neg/higherkind_novalue.scala +neg/t935.scala +neg/t6040.scala +neg/annot-nonconst.scala +neg/macro-deprecate-idents.scala +neg/illegal-stmt-start.scala +neg/t565.scala +neg/case-collision.scala +neg/t3209.scala +neg/t5821.scala +neg/abstract-class-2.scala +neg/t846.scala +neg/quasiquotes-syntax-error-position.scala +neg/t3987.scala +neg/t877.scala +neg/t0117.scala +neg/t692.scala +neg/t5702-neg-ugly-xbrace.scala +neg/t7752.scala +neg/case-collision2.scala +neg/t6526.scala +neg/t2213.scala +neg/t7756a.scala +neg/macro-override-macro-overrides-abstract-method-a +neg/tcpoly_ticket2101.scala +neg/delayed-init-ref.scala +neg/caseinherit.scala +neg/t3189.scala +neg/unchecked-suppress.scala +neg/t2180.scala +neg/t1371.scala +neg/macro-cyclic +neg/t6123-explaintypes-macros +neg/t4134.scala +neg/t691.scala +neg/t2421b.scala +neg/t4691_exhaust_extractor.scala +neg/t4419.scala +neg/t5801.scala +neg/t650.scala +neg/t5735.scala +neg/t696.scala +neg/t882.scala +neg/t2968.scala +neg/t7507.scala +neg/macro-invalidusage-badargs +neg/macro-reify-typetag-typeparams-notags +neg/wellkinded_app2.scala +neg/t4425b.scala +neg/t2296a +neg/t1878.scala +neg/t649.scala +neg/override-object-no.scala +neg/t4174.scala +neg/t2070.scala +neg/sabin2.scala +neg/t5903e +neg/t6566a.scala +neg/finitary-error.scala +neg/t4818.scala +neg/t3614.scala +neg/t6666c.scala +neg/ticket513.scala +neg/suggest-similar.scala +neg/t4457_1.scala +neg/t6666e.scala +neg/tcpoly_bounds.scala +neg/t4727.scala +neg/t4425.scala +neg/macro-invalidusage-methodvaluesyntax +neg/t3854.scala +neg/t3006.scala +neg/t5580b.scala +neg/t5378.scala +neg/t639.scala +neg/wrong-args-for-none.scala +neg/t7171b.scala +neg/t5361.scala +neg/unreachablechar.scala +neg/t5572.scala +neg/t7757a.scala +neg/macro-invalidimpl +neg/t2773.scala +neg/t6359.scala +neg/saito.scala +neg/xmltruncated2.scala +neg/t667.scala +neg/t3934.scala +neg/t6771b.scala +neg/t4584.scala +neg/wellkinded_wrongarity2.scala +neg/t7369.scala +neg/t1477.scala +neg/t5617.scala +neg/t7299.scala +neg/faculty.scala +neg/virtpatmat_reach_null.scala +neg/macro-reify-typetag-hktypeparams-notags +neg/t1224.scala +neg/xmltruncated3.scala +neg/t1872.scala +neg/t558.scala +neg/t7110.scala +neg/any-vs-anyref.scala +neg/t6340.scala +neg/t4166.scala +neg/t2918.scala +neg/t5856.scala +neg/t4989.scala +neg/t0003.scala +neg/t1183.scala +neg/t963.scala +neg/t4515.scala +neg/valueclasses-pavlov.scala +neg/t608.scala +neg/choices.scala +neg/patmat-type-check.scala +neg/valueclasses-impl-restrictions.scala +neg/imp2.scala +neg/protected-constructors.scala +neg/t6788.scala +neg/nullary-override.scala +neg/t200.scala +neg/t343.scala +neg/names-defaults-neg-ref.scala +neg/tcpoly_typealias.scala +neg/classtags_contextbound_b.scala +neg/t729.scala +neg/t5683.scala +neg/t4928.scala +neg/t700.scala +neg/t7669.scala +neg/macro-invalidshape +neg/t6011.scala +neg/t7325.scala +neg/check-dead.scala +neg/t550.scala +neg/t5663-badwarneq.scala +neg/t0699 +neg/nopredefs.scala +neg/t3507-old.scala +neg/t5352.scala +neg/t6336.scala +neg/interop_classmanifests_arenot_typetags.scala +neg/sealed-final-neg.scala +neg/t2102.scala +neg/t7636.scala +neg/t5031b +neg/t798.scala +neg/t5702-neg-bad-xbrace.scala +neg/t0899.scala +neg/cyclics-import.scala +neg/badtok-2.scala +neg/t473.scala +neg/t3160ambiguous.scala +neg/t5106.scala +neg/t1286 +neg/macro-override-macro-overrides-abstract-method-b +neg/t0259.scala +neg/t510.scala +neg/t3836.scala +neg/t5830.scala +neg/t1548 +neg/t5580a.scala +neg/forward.scala +neg/t591.scala +neg/t6558b.scala +neg/t556.scala +neg/xmltruncated4.scala +neg/t5497.scala +neg/t409.scala +neg/t6283.scala +neg/override-object-flag.scala +neg/constructor-prefix-error.scala +neg/eta-expand-star.scala +neg/t3392.scala +neg/t1275.scala +neg/nested-fn-print.scala +neg/t7330.scala +neg/t2275a.scala +neg/t630.scala +neg/t4270.scala +neg/t2775.scala +neg/pat_unreachable.scala +neg/t4158.scala +neg/unit-returns-value.scala +neg/t1422.scala +neg/reify_metalevel_breach_-1_refers_to_0_b.scala +neg/reassignment.scala +neg/t3683a.scala +neg/noMember1.scala +neg/macro-without-xmacros-b +neg/t1106.scala +neg/t5182.scala +neg/t6889.scala +neg/t4217.scala +neg/t7501 +neg/t5063.scala +neg/t1009.scala +neg/t997.scala +neg/unchecked.scala +neg/classtags_contextbound_c.scala +neg/applydynamic_sip.scala +neg/t7715.scala +neg/t588.scala +neg/t6667b.scala +neg/t7757b.scala +neg/t4069.scala +neg/t515.scala +neg/variances2.scala +neg/t1049.scala +neg/t7289.scala +neg/t1623.scala +neg/permanent-blindness.scala +neg/t5803.scala +neg/super-cast-or-test.scala +neg/nonlocal-warning.scala +neg/t5687.scala +neg/t5903a +neg/t6566b.scala +neg/unchecked-knowable.scala +neg/t5093.scala +neg/protected-static-fail +neg/type-diagnostics.scala +neg/forgot-interpolator.scala +neg/interop_abstypetags_arenot_classmanifests.scala +neg/t5376.scala +neg/t545.scala +neg/xmlcorner.scala +neg/switch.scala +neg/depmet_1.scala +neg/abstract-concrete-methods.scala +neg/t4987.scala +neg/t5452-new.scala +neg/t750b +neg/unchecked-refinement.scala +neg/t418.scala +neg/t5354.scala +neg/t3736.scala +neg/t631.scala +neg/t6829.scala +neg/t0218.scala +neg/volatile-intersection.scala +neg/t412.scala +neg/t693.scala +neg/t4882.scala +neg/t1960.scala +neg/macro-divergence-controlled +neg/t712.scala +neg/t5544 +neg/t3222.scala +neg/t3604.scala +neg/t1112.scala +neg/t7157 +neg/accesses.scala +neg/t452.scala +neg/t6162-inheritance +neg/t2442 +neg/t6567.scala +neg/lazy-override.scala +neg/abstract-explaintypes.scala +neg/nested-annotation.scala +neg/t5753 +neg/t3691.scala +neg/infix-op-positions.scala +neg/t3403.scala +neg/t4851 +neg/structural.scala +neg/error_dependentMethodTpeConversionToFunction.scala +neg/t5839.scala +neg/t5553_1.scala +neg/reify_metalevel_breach_+0_refers_to_1.scala +neg/t752.scala +neg/t6574.scala +neg/t3714-neg.scala +neg/t4457_2.scala +neg/t2148.scala +neg/t1364.scala +neg/saferJavaConversions.scala +neg/t414.scala +neg/t5493.scala +neg/classtags_contextbound_a.scala +neg/reify_metalevel_breach_-1_refers_to_0_a.scala +neg/t3118.scala +neg/t512.scala +neg/t2336.scala +neg/t856.scala +neg/xmltruncated6.scala +neg/t2206.scala +neg/virtpatmat_unreach_select.scala +neg/t6258.scala +neg/t6815.scala +neg/not-possible-cause.scala +neg/dbldef.scala +neg/qualifying-class-error-1.scala +neg/t835.scala +neg/t5455.scala +neg/t6558.scala +neg/t708.scala +neg/macro-nontypeablebody +neg/t0565.scala +neg/xmltruncated5.scala +neg/t5390d.scala +neg/t520.scala +neg/t6138.scala +neg/macro-without-xmacros-a +neg/t7214neg.scala +neg/t2870.scala +neg/t593.scala +neg/t4541b.scala +neg/t4460b.scala +neg/t284.scala +neg/t2488.scala +neg/macro-override-method-overrides-macro +neg/interop_abstypetags_arenot_classtags.scala +neg/t3769.scala +neg/warn-inferred-any.scala +neg/t664.scala +neg/t5903d +neg/t562.scala +neg/t2316.scala +neg/t0152.scala +neg/migration28.scala +neg/t6443c.scala +neg/tcpoly_override.scala +neg/t7324.scala +neg/t987.scala +neg/t5903b +neg/t3481.scala +neg/t6912.scala +neg/tcpoly_variance_enforce.scala +neg/t3913.scala +neg/names-defaults-neg.scala +neg/t765.scala +neg/t5358.scala +neg/t391.scala +neg/serialversionuid-not-const.scala +neg/t771.scala +neg/t0903.scala +neg/catch-all.scala +neg/classmanifests_new_deprecations.scala +neg/t0606.scala +neg/t5189_inferred.scala +neg/macro-reify-typetag-useabstypetag +neg/t5543.scala +neg/logImplicits.scala +neg/interop_typetags_without_classtags_arenot_manifests.scala +neg/t6535.scala +neg/t7259.scala +neg/t2139.scala +neg/t278.scala +neg/t5564.scala +neg/unchecked3.scala +neg/virtpatmat_reach_sealed_unsealed.scala +neg/checksensible.scala +neg/t7721.scala +run/t3798.scala +run/macro-expand-varargs-explicit-over-varargs +run/t3888.scala +run/t0677-new.scala +run/t3273.scala +run/t3763.scala +run/t2755.scala +run/t920.scala +run/t5610a.scala +run/literals.scala +run/proxy.scala +run/unapply.scala +run/t5830.scala +run/array-addition.scala +run/macro-expand-nullary-nongeneric +run/macro-basic-ma-mdmi +run/valueclasses-constr.scala +run/t1247.scala +run/t3487.scala +run/rawstrings.scala +run/patmat-seqs.scala +run/eta-expand-star.scala +run/t7436.scala +run/t3996.scala +run/constructors.scala +run/t498.scala +run/t3835.scala +run/t298.scala +run/t2867.scala +run/t7120 +run/virtpatmat_literal.scala +run/t2175.scala +run/t2503.scala +run/t3026.scala +run/t603.scala +run/t0091.scala +run/t6394a +run/macro-expand-varargs-implicit-over-varargs +run/t7407.scala +run/t2552.scala +run/virtpatmat_npe.scala +run/macro-sip19 +run/t6644.scala +run/t6614.scala +run/t2005.scala +run/t4680.scala +run/t5903a +run/classtags_contextbound.scala +run/Course-2002-05.scala +run/applydynamic_sip.scala +run/t1766.scala +run/retsynch.scala +run/t7715.scala +run/t102.scala +run/nonlocalreturn.scala +run/macro-reify-staticXXX +run/Course-2002-06.scala +run/t6863.scala +run/t6500.scala +run/macro-impl-rename-context +run/t4351.scala +run/t5009.scala +run/macro-term-declared-in-annotation +run/t6271.scala +run/array-existential-bound.scala +run/t6443b.scala +run/t1987.scala +run/MutableListTest.scala +run/t7571.scala +run/t5488-fn.scala +run/macro-bodyexpandstoimpl +run/macro-reify-ref-to-packageless +run/t2212.scala +run/macro-expand-varargs-implicit-over-nonvarargs +run/t0807.scala +run/patmat-behavior.scala +run/t2446.scala +run/breakout.scala +run/t4122.scala +run/macro-settings +run/t7157 +run/t1323.scala +run/t4013b.scala +run/t6309.scala +run/t4047.scala +run/t5544 +run/t978.scala +run/t3361.scala +run/t6611.scala +run/t5387.scala +run/t5656.scala +run/t4897.scala +run/numeric-range.scala +run/t4777.scala +run/Course-2002-03.scala +run/string-extractor.scala +run/view-headoption.scala +run/patmat_unapp_abstype-new.scala +run/stream-stack-overflow-filter-map.scala +run/macro-impl-tparam-only-in-impl +run/t6559.scala +run/macro-reify-tagful-a +run/macro-expand-multiple-arglists +run/t4709.scala +run/t3509.scala +run/t5284b.scala +run/t7617b +run/t3923.scala +run/virtpatmat_apply.scala +run/t363.scala +run/manifests-undeprecated-in-2.10.0.scala +run/matchintasany.scala +run/t3970.scala +run/t4996.scala +run/t5530.scala +run/macro-term-declared-in-object-class +run/t3242b.scala +run/indexedSeq-apply.scala +run/t107.scala +run/t2337.scala +run/t2754.scala +run/flat-flat-flat.scala +run/t6673.scala +run/interpolationMultiline2.scala +run/t0631.scala +run/t2800.scala +run/t6506.scala +run/t6260.scala +run/t2418.scala +run/t4415.scala +run/classmanifests_new_alias.scala +run/t5380.scala +run/tcpoly_parseridioms.scala +run/t1747.scala +run/t5903d +run/t3530.scala +run/t216.scala +run/macro-term-declared-in-refinement +run/t4592.scala +run/t2488.scala +run/t3327.scala +run/t5614.scala +run/t5903b +run/iterables.scala +run/t3964.scala +run/t6329_vanilla.scala +run/t3038c +run/t1697.scala +run/t2030.scala +run/t3397.scala +run/t1005.scala +run/t3353.scala +run/t1466.scala +run/t3186.scala +run/tcpoly_overriding.scala +run/t5394.scala +run/t5284.scala +run/unboxingBug.scala +run/t7200.scala +run/macro-reify-basic +run/t153.scala +run/iterator3444.scala +run/macro-expand-implicit-macro-is-val +run/macro-basic-ma-md-mi +run/interpolationArgs.scala +run/t4954.scala +run/t3645.scala +run/transpose.scala +run/t3887.scala +run/t4288.scala +run/unittest_iterator.scala +run/t5543.scala +run/macro-term-declared-in-object +run/iq.scala +run/t2788.scala +run/t2027.scala +run/macro-expand-recursive +run/t949.scala +run/t1909b.scala +run/delambdafy-nested-by-name.scala +run/delambdafy-two-lambdas.scala +run/macro-blackbox-materialization +run/lists-run.scala +run/macro-parse-position +run/macro-parse-position-malformed +run/macro-whitebox-dynamic-materialization +run/macro-whitebox-extractor +run/macro-vampire-false-warning +run/macro-whitebox-fundep-materialization +run/macro-whitebox-structural +run/mutable-treeset.scala +run/static-module-method.scala +run/sort.scala +run/t1909.scala +run/t1909c.scala +run/t3346a.scala +run/t3346d.scala +run/t3346f.scala +run/t3346h.scala +run/t3346g.scala +run/t3832.scala +run/t4742.scala +run/t5377.scala +run/t5923c.scala +run/t6188.scala +run/t6333.scala +run/t6385.scala +run/t7899.scala +run/t7584b.scala +run/t7223.scala +run/t7859 +run/t7868.scala +run/t7871 +run/arrayclone-new.scala +run/arrayclone-old.scala +run/bitsets.scala +run/comparable-comparator.scala +run/colltest1.scala +run/t2106.scala +run/t5986.scala +run/view-iterator-stream.scala +run/array-charSeq.scala +pos/signatures +pos/t1263 +pos/t3249 +neg/t4749.scala +neg/main1.scala +neg/t7251 +neg/t7494-after-terminal +neg/t7494-before-parser +neg/t7494-right-after-terminal +run/lazy-traits.scala +run/OrderingTest.scala +run/ReplacementMatching.scala +run/patmat-finally.scala +run/t3158.scala +run/t3346e.scala +run/t4398.scala +run/t4930.scala +run/t6534.scala +pos/sammy_scope.scala +pos/delambdafy-patterns.scala +pos/private-types-after-typer.scala +pos/delambdafy-lambdalift.scala +pos/sammy_poly.scala +pos/sammy_single.scala +pos/sammy_twice.scala +pos/t3160.scala +pos/t1014.scala +pos/t4970b.scala +pos/t2698.scala +pos/t5845.scala +pos/t6201.scala +pos/t6260a.scala +pos/t7688.scala +pos/t7818.scala +pos/t1203a.scala +pos/t7834.scala +pos/t7853.scala +pos/t7815.scala +pos/t7853-partial-function.scala +pos/t7864.scala +pos/t7928.scala +pos/t7902.scala +pos/t7944.scala +pos/t7847 +neg/accesses2.scala +neg/bad-advice.scala +neg/gadts2.scala +neg/gadts2-strict.scala +neg/macro-bundle-abstract.scala +neg/macro-bundle-object.scala +neg/macro-bundle-trait.scala +neg/macro-blackbox-dynamic-materialization +neg/macro-blackbox-extractor +neg/run-gadts-strict.scala +neg/macro-blackbox-structural +neg/sammy_restrictions.scala +neg/sammy_wrong_arity.scala +neg/t2462c.scala +neg/t3346b.scala +neg/t1909-object.scala +neg/macro-blackbox-fundep-materialization +neg/t3346c.scala +neg/t3871.scala +neg/t3871b.scala +neg/t3971.scala +neg/t3346i.scala +neg/t6120.scala +neg/t6260c.scala +neg/t6680a.scala +neg/t7239.scala +neg/t7007.scala +neg/t7605-deprecation.scala +neg/t7622-missing-required.scala +neg/t7629-view-bounds-deprecation.scala +neg/t7834neg.scala +neg/t7783.scala +neg/t7848-interp-warn.scala +neg/t7519-b +neg/t7622-missing-dependency +neg/t7870.scala +neg/t7877.scala +neg/t7895.scala +neg/t7895b.scala +neg/t7899.scala +neg/t7895c.scala +neg/t7859 +run/t4752.scala +run/t2087-and-2400.scala +run/t3855.scala +run/t6637.scala +run/t6731.scala +pos/t3999b.scala +run/t0432.scala +run/t2514.scala +run/t7817.scala +run/t874.scala +run/type-currying.scala +run/t3616.scala +run/t3687.scala +run/t4570.scala +run/t5612.scala +run/t1110.scala +run/t2636.scala +run/verify-ctor.scala +run/t3647.scala +run/t4560.scala +run/t6632.scala +run/richs.scala +run/t6725-1.scala +pos/t7776.scala +run/fors.scala +run/t6706.scala +run/t3175.scala +run/delambdafy-dependent-on-param-subst.scala +run/t4332b.scala +run/t8048a +run/t8017 +run/t7985b.scala +run/t8100.scala +run/patmat-mix-case-extractor.scala +run/t4750.scala +run/t7912.scala +run/delambdafy-dependent-on-param-subst-2.scala +run/t8048b +run/t8091.scala +run/macroPlugins-macroRuntime +run/macro-default-params +run/t6355.scala +run/t7777 +run/t8002.scala +run/t8015-ffc.scala +run/macro-subpatterns +run/t7985.scala +run/macroPlugins-macroArgs +run/t7326.scala +run/t5045.scala +run/value-class-partial-func-depmet.scala +run/t6329_vanilla_bug.scala +run/macroPlugins-macroExpand +run/t8010.scala +run/macroPlugins-typedMacroBody +run/t7406.scala +pos/t8146a.scala +pos/t8046c.scala +pos/t8132.scala +pos/t8045.scala +pos/overzealous-assert-genbcode.scala +pos/t8128.scala +pos/t8013 +pos/t8064b +pos/t6780.scala +pos/t7987 +pos/bcode_throw_null +pos/t8064 +pos/t8046.scala +pos/t6231.scala +pos/t7983.scala +pos/t5508.scala +pos/t5508-min.scala +pos/t8023b.scala +pos/t6231b.scala +pos/debug-reset-local-attrs.scala +pos/t8054.scala +pos/t2066.scala +pos/dotless-targs.scala +pos/t8120.scala +pos/t5508-min-okay.scala +pos/t8060.scala +pos/t8001 +pos/t8138.scala +pos/t8111.scala +pos/t8011.scala +pos/t8146b.scala +pos/t8046b.scala +pos/t8023.scala +pos/t5508-min-okay2.scala +pos/macro-implicit-invalidate-on-error.scala +neg/t6563.scala +neg/missing-param-type-tuple.scala +neg/not-a-legal-formal-parameter-tuple.scala +neg/t7897.scala +neg/t8015-ffa.scala +neg/quasiquotes-unliftable-not-found.scala +neg/t2066b.scala +neg/dotless-targs.scala +neg/patmat-classtag-compound.scala +neg/t2066.scala +neg/t8035-deprecated.scala +neg/t6675b.scala +neg/t8104 +neg/t7872.scala +neg/t7850.scala +neg/t7967.scala +neg/macro-bundle-overloaded.scala +neg/t6355a.scala +neg/class-of-double-targs.scala +neg/t6355b.scala +neg/macro-reify-splice-splice +neg/macro-bundle-noncontext.scala +neg/t8015-ffb.scala +neg/t8035-removed.scala +neg/t7984.scala +neg/t8024.scala +neg/t8024b.scala +neg/t8157.scala +neg/t8146-non-finitary-2.scala +neg/t8006.scala +neg/t7872c.scala +neg/t8146-non-finitary.scala +neg/t7872b.scala +neg/t6920.scala +run/t6200.scala +run/t6196.scala +run/macro-bundle-context-refinement +run/macro-enclosingowner-detectvar +run/macro-enclosingowner-sbt +run/macro-bundle-context-alias +run/macro-bundle-whitebox-use-refined +run/macro-bundle-whitebox-use-raw +neg/name-lookup-stable.scala +neg/t0764b.scala +neg/no-implicit-to-anyref-any-val.scala +neg/t1503.scala +neg/t4728.scala +neg/t6455.scala +neg/t6260-named.scala +neg/t6844.scala +neg/t7475c.scala +neg/t7475e.scala +neg/t7475f.scala +neg/macro-bundle-whitebox-use-raw +neg/macro-bundle-whitebox-use-refined +neg/macro-incompatible-macro-engine-b +neg/t7980.scala +neg/macro-incompatible-macro-engine-a +neg/t8143a.scala +neg/t8072.scala +neg/t8207.scala +neg/t8182.scala +neg/t8219-any-any-ref-equals.scala +neg/t8177a.scala +neg/t8228.scala +neg/t8229.scala +neg/t8237-default.scala +neg/t8244b.scala +neg/t8244e +neg/t8244c.scala +neg/t8265.scala +neg/t8266-invalid-interp.scala +neg/t6931 +neg/t8376 +neg/t8372.scala +neg/t8300-overloading.scala +neg/t8244 +neg/t8158 +neg/t8431.scala +pos/implicit-anyval-2.10.scala +pos/delambdafy_t6260_method.scala +pos/macro-bundle-disambiguate-bundle.scala +pos/macro-bundle-disambiguate-nonbundle.scala +pos/package-ob-case +pos/t1786-counter.scala +pos/reflection-compat-api-universe.scala +pos/existential-java-case-class +pos/t1786-cycle.scala +pos/reflection-compat-c.scala +pos/t3452f.scala +pos/reflection-compat-ru.scala +pos/t2066-2.10-compat.scala +pos/reflection-compat-macro-universe.scala +pos/t5900a.scala +pos/t5760-pkgobj-warn +pos/t5954a +pos/t5954b +pos/t5954d +pos/t6260.scala +pos/t5165b +pos/t5954c +pos/t6260b.scala +pos/t7475b.scala +pos/t7475a.scala +pos/t7753.scala +pos/t7322.scala +pos/t6948.scala +pos/t7475d.scala +pos/t7475e.scala +pos/t6169 +pos/t7788.scala +pos/t7919.scala +pos/t8177a.scala +pos/t8177.scala +pos/t8170.scala +pos/t8170b.scala +pos/t8177d.scala +pos/t8177b.scala +pos/t8177e.scala +pos/t8134 +pos/t8177h.scala +pos/t8177g.scala +pos/t8207.scala +pos/t8187.scala +pos/t8219.scala +pos/t8219b.scala +pos/t8224.scala +pos/t8237.scala +pos/t8223.scala +pos/t8237b.scala +pos/t8300-conversions-a.scala +pos/t8300-conversions-b.scala +pos/t8209a +pos/t8209b +pos/t8244d +pos/t8300-overloading.scala +pos/t8300-patmat-a.scala +pos/t8300-patmat-b.scala +pos/t8301.scala +pos/t8324.scala +pos/t8301b.scala +pos/t8363.scala +pos/t8367.scala +pos/t8369a.scala +pos/t8369b.scala +pos/t8403.scala +pos/t8364.scala +pos/t8352 +pos/t8376 +neg/macro-bundle-nonpublic-c.scala +neg/literate_existentials.scala +neg/macro-bundle-nonpublic-impl.scala +neg/macro-bundle-ambiguous.scala +neg/macro-bundle-priority-bundle.scala +neg/macro-bundle-need-qualifier.scala +neg/macro-bundle-nonstatic.scala +neg/macro-bundle-polymorphic.scala +neg/macro-bundle-priority-nonbundle.scala +neg/macro-bundle-wrongcontext-a.scala +neg/macro-bundle-wrongcontext-b.scala +run/t8425 +run/t8245.scala +run/t8266-octal-interp.scala +run/t8280.scala +run/t8395.scala +run/t8321 +run/t8153.scala +run/t8197.scala +run/t8197b.scala +run/t8233.scala +run/t8133 +run/t8133b +run/t7475b.scala +run/t6814 +run/t4577.scala +run/t5134.scala +run/t3452f.scala +run/t3452h.scala +run/t3452c.scala +run/t3452.scala +run/t261.scala +run/t3235-minimal.scala +run/t1503_future.scala +run/t5565.scala +pos/t8411 +pos/t8460.scala +run/t8428.scala +run/t8437 +run/absoverride.scala +run/arrays.scala +run/duration-coarsest.scala +run/iterator-from.scala +run/SymbolsTest.scala +run/t1074.scala +run/t1505.scala +run/streams.scala +run/t2111.scala +run/t4601.scala +neg/t3692-new.scala +run/t7015.scala +run/t7992b.scala +run/t7992.scala +run/t8570.scala +pos/t8157-2.10.scala +pos/t8325.scala +pos/t8523.scala +pos/t8578.scala +pos/t8329.scala +pos/t8497 +pos/t8546.scala +pos/t8531 +neg/t8325-c.scala +neg/t8325-b.scala +neg/t8325.scala +neg/t6988.scala +neg/t8463.scala +neg/t8450.scala +neg/t8430.scala +run/finally.scala +neg/t8630.scala +neg/t8035-no-adapted-args.scala +neg/t8675b.scala +neg/t8610-arg.scala +neg/t8736-c.scala +neg/tailrec-4.scala +neg/double-def-top-level +neg/t8610.scala +neg/aladdin1055 +neg/virtpatmat_exhaust_compound.scala +neg/t8675.scala +neg/t8525.scala +pos/t8736.scala +pos/t8625.scala +pos/t8596.scala +pos/t8617.scala +pos/t8736-b.scala +pos/t8708 +pos/macro-attachments +run/t8611a.scala +run/t8738.scala +run/macro-rangepos-args +run/t8610.scala +run/macro-rangepos-subpatterns +run/t8611c.scala +run/macroPlugins-isBlackbox +run/t8601d.scala +run/t8607.scala +run/bugs.scala +run/t1503.scala +run/t4148.scala +run/t7763.scala +run/issue192.scala +run/t8893b.scala +run/t8845.scala +run/t8933 +run/t7459c.scala +run/t9003.scala +run/t7459f.scala +run/t8933c.scala +run/t1994.scala +run/t2866.scala +run/t5665.scala +run/t7459d.scala +run/t8933b +run/t8888.scala +run/t7459b-optimize.scala +run/t7459a.scala +run/t7019.scala +run/t8893.scala +run/t8803.scala +run/t7459b.scala +run/t8823.scala +run/t6541.scala +run/nothingTypeDce.scala +run/t8680.scala +run/t8925.scala +run/nothingTypeNoOpt.scala +run/t9030.scala +run/bigDecimalTest.scala +run/bigDecimalCache.scala +run/range.scala +run/t6064.scala +run/t7521 +run/t8710.scala +run/t8575.scala +run/t8944 +run/t8944b.scala +run/t9387.scala +run/t9387b.scala +pos/t7784.scala +pos/t8862a.scala +pos/t9074.scala +pos/t8462.scala +pos/t8862b.scala +pos/alladin763.scala +pos/t6778.scala +pos/t9074b.scala +pos/t9326a.scala +pos/t9131.scala +pos/t9393 +pos/t9392 +neg/missing-arg-list.scala +neg/deprecated-target.scala +neg/t6895.scala +neg/beanInfoDeprecation.scala +neg/t8777.scala +neg/t6895b.scala +neg/t8892.scala +neg/t8849.scala +neg/inlineIndyLambdaPrivate +run/t9029.scala +run/t7850c.scala +run/t7850d.scala +run/t8334.scala +run/t9029c.scala +run/t9029b.scala +run/t9422.scala +run/t9425.scala +pos/t9475.scala +pos/t9498.scala +pos/t9479.scala +pos/t9479b.scala +pos/t9442.scala +pos/t9369.scala +pos/t6666d.scala +pos/t9370 +neg/t6810.scala +neg/t8127a.scala +neg/t8989.scala +neg/t9401.scala +neg/implicit-ambiguous.scala +neg/implicit-ambiguous-2.scala +neg/implicit-ambiguous-invalid.scala +neg/warn-unused-imports +run/t7269.scala +run/equality.scala +run/number-parsing.scala +run/t6220.scala +run/mapConserve.scala +run/colltest.scala +run/t0412.scala +run/t6261.scala +run/java-erasure.scala +run/t5880.scala +run/t6197.scala +run/t4201.scala +run/t5608.scala +run/t3518.scala +run/t6198.scala +run/t2813.2.scala +pos/java-type-annotations +pos/sammy_infer_argtype_subtypes.scala +pos/sammy_ctor_arg.scala +pos/fun_undo_eta.scala +pos/sammy_inferargs.scala +pos/existental-slow-compile2.scala +pos/existential-slow-compile1.scala +pos/sammy_implicit.scala +pos/t9178b.scala +pos/t9449.scala +pos/t3234.scala +pos/t9542.scala +pos/t8429.scala +pos/t9658.scala +pos/t9630 +pos/t9399.scala +pos/t9411a.scala +pos/t9411b.scala +neg/partestInvalidFlag.scala +neg/sammy_error.scala +neg/sammy_disabled.scala +neg/sammy_overload.scala +neg/sammy_expected.scala +neg/t8700a +neg/t9527b.scala +neg/t9527a.scala +neg/t9572.scala +neg/t9535.scala +neg/t9629.scala +neg/optimiseDeprecated.scala +neg/t9398 +neg/outer-ref-checks.scala +neg/t8685.scala +neg/t8700b +run/t9349 +run/t9178a.scala +run/t9110.scala +run/sammy_cbn.scala +run/sammy_erasure_cce.scala +run/sammy_after_implicit_view.scala +run/sammy_restrictions_LMF.scala +run/sammy_vararg_cbn.scala +run/t7807.scala +run/sammy_return.scala +run/t9546.scala +run/t9546b.scala +run/lisp.scala +run/t9546c.scala +run/t9546d.scala +run/t9546e.scala +run/t9567.scala +run/t9567b.scala +run/trait-clonable.scala +run/t9567c.scala +run/trait-defaults-modules.scala +run/trait-defaults-modules3.scala +run/trait-defaults-modules2 +pos/functions.scala +pos/MailBox.scala +neg/t6289 +run/t6114.scala +pos/constant-warning.scala +pos/t2712-5.scala +pos/t2712-2.scala +pos/t2712-4.scala +pos/t2712-1.scala +pos/t2712-3.scala +pos/t2712-6.scala +pos/t6895b.scala +pos/t5683.scala +pos/hkgadt.scala +pos/t2712-7.scala +pos/t9245.scala +pos/t7088.scala +pos/t8044.scala +pos/t9665.scala +pos/t9397.scala +pos/t5183.scala +pos/t8449 +neg/t8044-b.scala +neg/t8044.scala +neg/t2712-3.scala +neg/t2712-2.scala +neg/t2712-1.scala +neg/t9045.scala +neg/t8667.scala +neg/t9361.scala +neg/t9781.scala +neg/trait-no-native.scala +neg/hkgadt.scala +neg/t9684b.scala +neg/t9382.scala +neg/trait-defaults-super.scala +neg/t9684.scala +run/hashCodeStatics.scala +run/t9390d.scala +run/trait-static-clash.scala +run/t5568.scala +run/t6318_primitives.scala +pos/fields_widen_trait_var.scala +pos/sammy_extends_function.scala +pos/infer_override_def_args.scala +pos/t482.scala +pos/t8079b.scala +pos/t6161b.scala +pos/t5294b.scala +pos/t5294c.scala +pos/overloaded_ho_fun.scala +pos/t4914.scala +pos/trait_fields_dependent_conflict.scala +pos/t2377b +pos/trait_fields_dependent_rebind.scala +pos/t9855b.scala +pos/trait_fields_inherit_double_def.scala +pos/t9855.scala +pos/t8873.scala +pos/trait_fields_nested_private_object.scala +pos/trait_fields_nested_public_object.scala +pos/trait_fields_private_this.scala +pos/trait_fields_var_override_deferred.scala +pos/trait_fields_static_fwd.scala +pos/trait_fields_owners.scala +pos/trait_fields_volatile.scala +pos/trait_lazy_accessboundary.scala +pos/trait_fields_lambdalift.scala +pos/typevar-in-prefix.scala +pos/val_infer.scala +pos/lub-from-hell.scala +neg/t8079a.scala +neg/sd128 +neg/t9849.scala +neg/trait_fields_var_override.scala +neg/val_infer.scala +neg/val_sig_infer_match.scala +neg/t7187.scala +neg/trait_fields_deprecated_overriding.scala +neg/t9847.scala +neg/val_sig_infer_struct.scala +neg/trait_fields_conflicts.scala +neg/lub-from-hell-2.scala +run/t2946 +run/lazy_local_labels.scala +run/sd167.scala +run/t9841.scala +run/trait-fields-override-lazy.scala +run/trait_fields_init.scala +run/trait_fields_three_layer_overrides.scala +run/t9516.scala +run/t10032.scala +pos/sam_erasure_boundedwild.scala +pos/t10154.scala +pos/t10066.scala +pos/t10154b.scala +pos/t10093.scala +pos/t8040.scala +pos/t3772.scala +pos/t10206.scala +pos/t9331.scala +pos/userdefined_apply_poly_overload.scala +pos/userdefined_apply.scala +pos/trailing-commas.scala +neg/t10097.scala +neg/t10068.scala +neg/ambiguous-same.scala +neg/maxerrs.scala +neg/maxwarns.scala +neg/t10207.scala +neg/t10066.scala +neg/t3236-neg +neg/t3772.scala +neg/t8704.scala +neg/t8002-nested-scope.scala +neg/t10097b.scala +neg/trailing-commas.scala +neg/t9834.scala +neg/userdefined_apply.scala +neg/t8417.scala +neg/warn-unused-implicits.scala +neg/t7860.scala +neg/t8763.scala +neg/t9636.scala +neg/warn-unused-params.scala +neg/t9675.scala +neg/warn-unused-patvars.scala +run/t10069.scala +run/SD-290.scala +run/sd329.scala +run/t10097.scala +run/t10072.scala +run/t10261 +run/t9114.scala +run/t10069b.scala +pos/t10205.scala +pos/t7100.scala +pos/t5788.scala +pos/t4012-b.scala +pos/t7638.scala +pos/t4012-a.scala +pos/dotless-targs-ranged.scala +neg/t5355.scala +neg/badtok-1-212.scala +neg/t6714.scala +neg/t10249 +run/macro-implicit-decorator +run/t10290.scala +run/t10298.scala +run/t10389.scala +run/t10423 +run/t6714.scala +run/t9146.scala +run/wacky-value-classes.scala +pos/t10088.scala +pos/t10213.scala +pos/t10195b.scala +pos/t10195.scala +pos/t10197.scala +pos/t10185.scala +pos/patmat-hk.scala +pos/t10159 +pos/t10372.scala +pos/t10238.scala +pos/t10288.scala +pos/t5818.scala +pos/t6895b-2.scala +pos/t10296-before +pos/warn-unused-params-not-implicits.scala +pos/t10296 +pos/t9122.scala +pos/t10270 +pos/t9647.scala +neg/t10279.scala +neg/hk-typevar-unification.scala +neg/t10260 +neg/names-defaults-neg-213.scala +neg/t6934 +neg/t9138.scala +neg/t7187-2.13.scala +neg/t10296-after +neg/t10296-warn +neg/t10270 +neg/t10296-both +run/implicit-caching.scala +run/abstype_implicits.scala +run/sd336.scala +run/hk-typevar-unification.scala +run/t10283.scala +run/t10291.scala +run/t10439.scala +run/t10454-1 +run/t10454-2 +run/t7187-2.13.scala + +# Adapt checkfiles for (1.0).toString == "1" +run/Course-2002-01.scala +run/t0421-new.scala +run/runtime.scala +run/t0421-old.scala +run/spec-self.scala +run/t5552.scala +run/Course-2002-02.scala +run/Course-2002-04.scala +run/promotion.scala +run/t4617.scala +run/Course-2002-09.scala +run/t5866.scala +run/try-catch-unify.scala +run/impconvtimes.scala +run/Course-2002-10.scala +run/Course-2002-08.scala +run/MeterCaseClass.scala +run/Meter.scala +run/deeps.scala +run/caseClassHash.scala +run/interpolation.scala +run/interpolationMultiline1.scala +run/t9656.scala +pos/sd219.scala +pos/t9918 +pos/shapeless-regression.scala +pos/issue244.scala +pos/t9920.scala +pos/t9943.scala +neg/t5148.scala +run/sd242.scala +run/local_obj.scala +run/t9697.scala +run/t9920.scala +run/t9920c.scala +run/t9920d.scala +run/t9920b.scala +run/t9946a.scala +run/t9946c.scala +run/t9946b.scala +run/trait-super-calls.scala +pos/sd268.scala +pos/sd248 +pos/t6734.scala +pos/t10009.scala +pos/t7551 +pos/t6978 +pos/t7046-2 +neg/t9953.scala +neg/t7014 +neg/t7046-2 +neg/t7046 +run/t7046-1 +run/t7046-2 + +# Adapt checkfiles for ().toString == "undefined" +run/t5680.scala +run/dynamic-anyval.scala +run/macro-bundle-toplevel +run/macro-bundle-whitebox-decl +run/t6662 +run/t8570a.scala +run/t3702.scala +run/t7657 +run/macro-bundle-static +run/structural.scala + +# Adapt checkfiles for print & flush (which we cannot 100% emulate) +run/imports.scala +run/misc.scala + +# Adapt checkfiles for compiler phase list +neg/t7494-no-options +neg/t6446-list +neg/t6446-missing +neg/t6446-show-phases.scala +neg/t6446-additional + +# Adapt checkfiles for different behavior with boxed types +run/virtpatmat_typetag.scala +run/virtpatmat_switch.scala +run/t5629b.scala +run/t5356.scala +run/anyval-box-types.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-additional.check new file mode 100644 index 0000000000..b7ce23da2f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-additional.check @@ -0,0 +1,30 @@ + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + ploogin 27 A sample phase that does so many things it's kind of hard... + terminal 28 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-list.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-list.check new file mode 100644 index 0000000000..95883c8c81 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-list.check @@ -0,0 +1,2 @@ +ploogin - A sample plugin for testing. +scalajs - Compile to JavaScript diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-missing.check new file mode 100644 index 0000000000..56b74a3128 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-missing.check @@ -0,0 +1,30 @@ +Error: unable to load class: t6446.Ploogin + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + terminal 27 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-show-phases.check new file mode 100644 index 0000000000..cde255e3b1 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-show-phases.check @@ -0,0 +1,29 @@ + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + terminal 27 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t7494-no-options.check new file mode 100644 index 0000000000..d8be421e5e --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t7494-no-options.check @@ -0,0 +1,31 @@ +error: Error: ploogin takes no options + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + ploogin 27 A sample phase that does so many things it's kind of hard... + terminal 28 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Course-2002-01.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Course-2002-01.check new file mode 100644 index 0000000000..fcda9433de --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Course-2002-01.check @@ -0,0 +1,37 @@ +Course-2002-01.scala:41: warning: method loop in object M0 does nothing other than call itself recursively + def loop: Int = loop; + ^ +232 +667 +11 +10 +62.8318 +62.8318 +62.8318 +4 +81 +256 +25 +1 +737 +1 +0 +1 +76 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +sqrt(2) = 1.4142135623746899 +sqrt(2) = 1.4142135623746899 +cbrt(2) = 1.2599210500177698 +1 +1 1 +1 2 1 +1 3 3 1 +1 4 6 4 1 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Course-2002-02.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Course-2002-02.check new file mode 100644 index 0000000000..ab75cfdb61 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Course-2002-02.check @@ -0,0 +1,187 @@ +7 +120 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +pi = 3.181104885577714 +pi = 3.181104885577714 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 +pi = 3.181104885577714 +pi = 3.181104885577714 + +1.5 +1.4166666666666665 +1.4142156862745097 +1.4142135623746899 +sqrt(2) = 1.4142135623746899 + +1.5 +1.4166666666666665 +1.4142156862745097 +1.4142135623746899 +sqrt(2) = 1.4142135623746899 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +power(0,0) = 1 +power(0,1) = 0 +power(0,2) = 0 +power(0,3) = 0 +power(0,4) = 0 +power(0,5) = 0 +power(0,6) = 0 +power(0,7) = 0 +power(0,8) = 0 + +power(1,0) = 1 +power(1,1) = 1 +power(1,2) = 1 +power(1,3) = 1 +power(1,4) = 1 +power(1,5) = 1 +power(1,6) = 1 +power(1,7) = 1 +power(1,8) = 1 + +power(2,0) = 1 +power(2,1) = 2 +power(2,2) = 4 +power(2,3) = 8 +power(2,4) = 16 +power(2,5) = 32 +power(2,6) = 64 +power(2,7) = 128 +power(2,8) = 256 + +power(3,0) = 1 +power(3,1) = 3 +power(3,2) = 9 +power(3,3) = 27 +power(3,4) = 81 +power(3,5) = 243 +power(3,6) = 729 +power(3,7) = 2187 +power(3,8) = 6561 + +power(4,0) = 1 +power(4,1) = 4 +power(4,2) = 16 +power(4,3) = 64 +power(4,4) = 256 +power(4,5) = 1024 +power(4,6) = 4096 +power(4,7) = 16384 +power(4,8) = 65536 + +power(5,0) = 1 +power(5,1) = 5 +power(5,2) = 25 +power(5,3) = 125 +power(5,4) = 625 +power(5,5) = 3125 +power(5,6) = 15625 +power(5,7) = 78125 +power(5,8) = 390625 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Course-2002-04.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Course-2002-04.check new file mode 100644 index 0000000000..fc6ad96eed --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Course-2002-04.check @@ -0,0 +1,64 @@ +list0 = List(6, 3, 1, 8, 7, 1, 2, 5, 8, 4, 3, 4, 8) +list1 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list2 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list3 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list4 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list5 = List(8, 8, 8, 7, 6, 5, 4, 4, 3, 3, 2, 1, 1) +list6 = List(8, 8, 8, 7, 6, 5, 4, 4, 3, 3, 2, 1, 1) + +list0: List() -> List() +list1: List(0) -> List(0) +list2: List(0, 1) -> List(0, 1) +list3: List(1, 0) -> List(0, 1) +list4: List(0, 1, 2) -> List(0, 1, 2) +list5: List(1, 0, 2) -> List(0, 1, 2) +list6: List(0, 1, 2) -> List(0, 1, 2) +list7: List(1, 0, 2) -> List(0, 1, 2) +list8: List(2, 0, 1) -> List(0, 1, 2) +list9: List(2, 1, 0) -> List(0, 1, 2) +listA: List(6, 3, 1, 8, 7, 1, 2, 5, 8, 4) -> List(1, 1, 2, 3, 4, 5, 6, 7, 8, 8) + +f(x) = 5x^3+7x^2+5x+9 +f(0) = 9 +f(1) = 26 +f(2) = 87 +f(3) = 222 + +v1 = List(2, 3, 4) +v2 = List(6, 7, 8) + +id = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +m1 = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m2 = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) + +v1 * v1 = 29 +v1 * v2 = 65 +v2 * v1 = 65 +v1 * v2 = 65 + +id * v1 = List(2, 3, 4) +m1 * v1 = List(4, 6, 8) +m2 * v1 = List(20, 47, 74) + +trn(id) = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +trn(m1) = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +trn(m2) = List(List(1, 4, 7), List(2, 5, 8), List(3, 6, 9)) + +List(v1) * id = List(List(2, 3, 4)) +List(v1) * m1 = List(List(4, 6, 8)) +List(v1) * m2 = List(List(42, 51, 60)) + +id * List(v1) = List(List(2, 3, 4), List(0, 0, 0), List(0, 0, 0)) +m1 * List(v1) = List(List(4, 6, 8), List(0, 0, 0), List(0, 0, 0)) +m2 * List(v1) = List(List(2, 3, 4), List(8, 12, 16), List(14, 21, 28)) + +id * id = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +id * m1 = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m1 * id = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m1 * m1 = List(List(4, 0, 0), List(0, 4, 0), List(0, 0, 4)) +id * m2 = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) +m2 * id = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) +m1 * m2 = List(List(2, 4, 6), List(8, 10, 12), List(14, 16, 18)) +m2 * m1 = List(List(2, 4, 6), List(8, 10, 12), List(14, 16, 18)) +m2 * m2 = List(List(30, 36, 42), List(66, 81, 96), List(102, 126, 150)) + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Course-2002-08.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Course-2002-08.check new file mode 100644 index 0000000000..0585d5b44f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Course-2002-08.check @@ -0,0 +1,171 @@ +x = abc +count = 111 +x = hello +count = 112 + +account deposit 50 -> undefined +account withdraw 20 -> 30 +account withdraw 20 -> 10 +account withdraw 15 -> + +x deposit 30 -> undefined +y withdraw 20 -> + +x deposit 30 -> undefined +x withdraw 20 -> 10 + +x deposit 30 -> undefined +y withdraw 20 -> 10 + +2^0 = 1 +2^1 = 2 +2^2 = 4 +2^3 = 8 + +2^0 = 1 +2^1 = 2 +2^2 = 4 +2^3 = 8 + +1 2 3 +List(1, 2, 3) + +out 0 new-value = false +*** simulation started *** +out 1 new-value = true +!0 = 1 + +*** simulation started *** +out 2 new-value = false +!1 = 0 + +out 2 new-value = false + +*** simulation started *** +0 & 0 = 0 + +*** simulation started *** +0 & 1 = 0 + +*** simulation started *** +out 11 new-value = true +out 11 new-value = false +1 & 0 = 0 + +*** simulation started *** +out 14 new-value = true +1 & 1 = 1 + +out 14 new-value = false + +*** simulation started *** +0 | 0 = 0 + +*** simulation started *** +out 24 new-value = true +0 | 1 = 1 + +*** simulation started *** +1 | 0 = 1 + +*** simulation started *** +1 | 1 = 1 + +sum 34 new-value = false +carry 34 new-value = false + +*** simulation started *** +0 + 0 = 0 + +*** simulation started *** +sum 47 new-value = true +0 + 1 = 1 + +*** simulation started *** +carry 50 new-value = true +carry 50 new-value = false +sum 54 new-value = false +sum 54 new-value = true +1 + 0 = 1 + +*** simulation started *** +carry 57 new-value = true +sum 61 new-value = false +1 + 1 = 2 + +sum 61 new-value = false +carry 61 new-value = false + +*** simulation started *** +0 + 0 + 0 = 0 + +*** simulation started *** +sum 82 new-value = true +0 + 0 + 1 = 1 + +*** simulation started *** +sum 89 new-value = false +carry 90 new-value = true +sum 97 new-value = true +carry 98 new-value = false +0 + 1 + 0 = 1 + +*** simulation started *** +sum 113 new-value = false +carry 114 new-value = true +0 + 1 + 1 = 2 + +*** simulation started *** +sum 121 new-value = true +carry 122 new-value = false +sum 129 new-value = false +sum 129 new-value = true +1 + 0 + 0 = 1 + +*** simulation started *** +carry 137 new-value = true +sum 144 new-value = false +1 + 0 + 1 = 2 + +*** simulation started *** +carry 152 new-value = false +sum 152 new-value = true +sum 158 new-value = false +carry 159 new-value = true +1 + 1 + 0 = 2 + +*** simulation started *** +sum 173 new-value = true +1 + 1 + 1 = 3 + +in 0 new-value = false +ctrl0 0 new-value = false +ctrl1 0 new-value = false +ctrl2 0 new-value = false +out0 0 new-value = false +out1 0 new-value = false +out2 0 new-value = false +out3 0 new-value = false +out4 0 new-value = false +out5 0 new-value = false +out6 0 new-value = false +out7 0 new-value = false +in 0 new-value = true +*** simulation started *** +out0 10 new-value = true +ctrl0 10 new-value = true +*** simulation started *** +out1 13 new-value = true +out0 14 new-value = false +ctrl1 14 new-value = true +*** simulation started *** +out3 20 new-value = true +out1 21 new-value = false +ctrl2 21 new-value = true +*** simulation started *** +out7 30 new-value = true +out3 31 new-value = false +ctrl0 31 new-value = false +*** simulation started *** +out7 34 new-value = false +out6 35 new-value = true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Course-2002-09.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Course-2002-09.check new file mode 100644 index 0000000000..c921361db7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Course-2002-09.check @@ -0,0 +1,50 @@ +Probe: f = 32 +Probe: c = 0 +Probe: f = ? +Probe: c = ? + +Probe: f = 212 +Probe: c = 100 +Probe: f = ? +Probe: c = ? + +Probe: c = 0 +Probe: f = 32 +Probe: c = ? +Probe: f = ? + +Probe: c = 100 +Probe: f = 212 +Probe: c = ? +Probe: f = ? + +0 Celsius -> 32 Fahrenheits +100 Celsius -> 212 Fahrenheits +32 Fahrenheits -> 0 Celsius +212 Fahrenheits -> 100 Celsius + +a = ?, b = ?, c = ? => ? * ? = ? +a = 2, b = ?, c = ? => 2 * ? = ? +a = ?, b = 3, c = ? => ? * 3 = ? +a = ?, b = ?, c = 6 => ? * ? = 6 +a = 2, b = 3, c = ? => 2 * 3 = 6 +a = 2, b = ?, c = 6 => 2 * 3 = 6 +a = ?, b = 3, c = 6 => 2 * 3 = 6 +a = 2, b = 3, c = 6 => 2 * 3 = 6 + +a = 0, b = ?, c = ? => 0 * ? = 0 +a = ?, b = 0, c = ? => ? * 0 = 0 +a = ?, b = ?, c = 0 => ? * ? = 0 +a = 0, b = 7, c = ? => 0 * 7 = 0 +a = 7, b = 0, c = ? => 7 * 0 = 0 +a = 0, b = 0, c = ? => 0 * 0 = 0 +a = 0, b = ?, c = 0 => 0 * ? = 0 +a = ?, b = 0, c = 0 => ? * 0 = 0 +a = 0, b = 7, c = 0 => 0 * 7 = 0 +a = 7, b = 0, c = 0 => 7 * 0 = 0 +a = 0, b = 0, c = 0 => 0 * 0 = 0 + +a = 3, b = 4 => c = 5 +a = 3, c = 5 => b = 4 +b = 4, c = 5 => a = 3 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Course-2002-10.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Course-2002-10.check new file mode 100644 index 0000000000..847f0fa703 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Course-2002-10.check @@ -0,0 +1,46 @@ +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +fib(10) = 55 +fib(11) = 89 +fib(12) = 144 +fib(13) = 233 +fib(14) = 377 +fib(15) = 610 +fib(16) = 987 +fib(17) = 1597 +fib(18) = 2584 +fib(19) = 4181 + +pi(0) = 4 , 3.166666666666667 , 4 +pi(1) = 2.666666666666667 , 3.1333333333333337, 3.166666666666667 +pi(2) = 3.466666666666667 , 3.1452380952380956, 3.142105263157895 +pi(3) = 2.8952380952380956, 3.1396825396825396, 3.1415993573190044 +pi(4) = 3.33968253968254 , 3.142712842712843 , 3.141592714033778 +pi(5) = 2.976046176046176 , 3.140881340881341 , 3.1415926539752923 +pi(6) = 3.283738483738484 , 3.142071817071817 , 3.141592653591176 +pi(7) = 3.017071817071817 , 3.1412548236077646, 3.141592653589777 +pi(8) = 3.252365934718876 , 3.1418396189294024, 3.141592653589794 +pi(9) = 3.0418396189294024, 3.141406718496502 , 3.1415926535897936 +pi = 3.141592653589793 , 3.141592653589793 , 3.141592653589793 + +ln(0) = 1 , 0.7 , 1 +ln(1) = 0.5 , 0.6904761904761905, 0.7 +ln(2) = 0.8333333333333333, 0.6944444444444444, 0.6932773109243697 +ln(3) = 0.5833333333333333, 0.6924242424242424, 0.6931488693329254 +ln(4) = 0.7833333333333333, 0.6935897435897436, 0.6931471960735491 +ln(5) = 0.6166666666666667, 0.6928571428571428, 0.6931471806635636 +ln(6) = 0.7595238095238095, 0.6933473389355742, 0.6931471805604038 +ln(7) = 0.6345238095238095, 0.6930033416875522, 0.6931471805599444 +ln(8) = 0.7456349206349207, 0.6932539682539682, 0.6931471805599426 +ln(9) = 0.6456349206349206, 0.6930657506744463, 0.6931471805599453 +ln = 0.6931471805599453, 0.6931471805599453, 0.6931471805599453 + +prime numbers: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Meter.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Meter.check new file mode 100644 index 0000000000..f46fd557c8 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/Meter.check @@ -0,0 +1,16 @@ +Meter.scala:72: warning: a.Meter and Int are unrelated: they will never compare equal + println("x == 1: "+(x == 1)) + ^ +2 +4m +false +x.isInstanceOf[Meter]: true +x.hashCode: 1 +x == 1: false +x == y: true +a == b: true +testing native arrays +Array(1m, 2m) +1m +>>>1m<<< 1m +>>>2m<<< 2m diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/MeterCaseClass.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/MeterCaseClass.check new file mode 100644 index 0000000000..ac538d240f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/MeterCaseClass.check @@ -0,0 +1,16 @@ +MeterCaseClass.scala:69: warning: comparing values of types a.Meter and Int using `==' will always yield false + println("x == 1: "+(x == 1)) + ^ +2 +Meter(4) +false +x.isInstanceOf[Meter]: true +x.hashCode: 1 +x == 1: false +x == y: true +a == b: true +testing native arrays +Array(Meter(1), Meter(2)) +Meter(1) +>>>Meter(1)<<< Meter(1) +>>>Meter(2)<<< Meter(2) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/anyval-box-types.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/anyval-box-types.check new file mode 100644 index 0000000000..b2d758c906 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/anyval-box-types.check @@ -0,0 +1,52 @@ +true +1 +true +1 +true +-1 +true +1 +true +false +true +true +false +false + +true +2 +true +2 +true +-1 +true +2 +true +false +false +false +false + +true +true +false +true +1 +true +true +true +false +false +false + +true +つ +false +true +true +true +つ +true +false +false +false diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/bugs.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/bugs.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/bugs.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/caseClassHash.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/caseClassHash.check new file mode 100644 index 0000000000..f975151e9c --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/caseClassHash.check @@ -0,0 +1,9 @@ +Foo(true,-1,-1,d,-5,-10,500,500,List(),5) +Foo(true,-1,-1,d,-5,-10,500,500,List(),5) +1383698062 +1383698062 +true +## method 1: 1383698062 +## method 2: 1383698062 + Murmur 1: 1383698062 + Murmur 2: 1383698062 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/deeps.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/deeps.check new file mode 100644 index 0000000000..e533b87dc5 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/deeps.check @@ -0,0 +1,87 @@ +testEquals1 +false +false +true + +testEquals2 +false +false +true + +testEquals3 +x=Array(1) +y=Array(1) +false +false +true + +x=Array(Array(1), Array(1)) +y=Array(Array(1), Array(1)) +false +false +true + +x=Array(Array(Array(1), Array(1)), Array(Array(1), Array(1))) +y=Array(Array(Array(1), Array(1)), Array(Array(1), Array(1))) +false +false +true + +testEquals4 +false +false +true +false +false +true +Array(true, false) +Array(true, false) +[true;false] +true;false + +Array(Array(true, false), Array(true, false)) +Array(Array(true, false), Array(true, false)) +[Array(true, false);Array(true, false)] +Array(true, false);Array(true, false) + +Array(Array(Array(true, false), Array(true, false)), Array(Array(true, false), Array(true, false))) +Array(Array(Array(true, false), Array(true, false)), Array(Array(true, false), Array(true, false))) +[Array(Array(true, false), Array(true, false));Array(Array(true, false), Array(true, false))] +Array(Array(true, false), Array(true, false));Array(Array(true, false), Array(true, false)) + +Array(1, 0) +Array(1, 0) +[1;0] +1;0 + +Array(Array(1, 0), Array(1, 0)) +Array(Array(1, 0), Array(1, 0)) +[Array(1, 0);Array(1, 0)] +Array(1, 0);Array(1, 0) + +Array(Array(Array(1, 0), Array(1, 0)), Array(Array(1, 0), Array(1, 0))) +Array(Array(Array(1, 0), Array(1, 0)), Array(Array(1, 0), Array(1, 0))) +[Array(Array(1, 0), Array(1, 0));Array(Array(1, 0), Array(1, 0))] +Array(Array(1, 0), Array(1, 0));Array(Array(1, 0), Array(1, 0)) + +Array(a, b) +Array(a, b) +[a;b] +a;b + +Array(Array(a, b), Array(a, b)) +Array(Array(a, b), Array(a, b)) +[Array(a, b);Array(a, b)] +Array(a, b);Array(a, b) + +Array(Array(Array(a, b), Array(a, b)), Array(Array(a, b), Array(a, b))) +Array(Array(Array(a, b), Array(a, b)), Array(Array(a, b), Array(a, b))) +[Array(Array(a, b), Array(a, b));Array(Array(a, b), Array(a, b))] +Array(Array(a, b), Array(a, b));Array(Array(a, b), Array(a, b)) + +[Array(true, false); Array(false)] +[Array(1, 2); Array(3)] +[Array(1, 2); Array(3)] + +Array(boo, and, foo) +Array(a) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/dynamic-anyval.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/dynamic-anyval.check new file mode 100644 index 0000000000..c125372c9a --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/dynamic-anyval.check @@ -0,0 +1,4 @@ +undefined.dingo(bippy, 5) +List(1, 2, 3).dingo(bippy, 5) +undefined.dingo(bippy, 5) +List(1, 2, 3).dingo(bippy, 5) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/impconvtimes.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/impconvtimes.check new file mode 100644 index 0000000000..082377e474 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/impconvtimes.check @@ -0,0 +1 @@ +3.0 * Hour = Measure(3,Hour) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/imports.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/imports.check new file mode 100644 index 0000000000..1aad598062 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/imports.check @@ -0,0 +1,21 @@ +In C_ico, v_ico .toString() returns ↩ +↪C_ico -> ok +In C_ico, field .toString() returns ↩ +↪C_ico -> ok +In C_ico, method.toString() returns ↩ +↪C_ico -> ok + +In C_ioc, v_ioc .toString() returns ↩ +↪C_ioc -> ok +In C_ioc, field .toString() returns ↩ +↪C_ioc -> ok +In C_ioc, method.toString() returns ↩ +↪C_ioc -> ok + +In C_oic, v_oic .toString() returns ↩ +↪C_oic -> ok +In C_oic, field .toString() returns ↩ +↪C_oic -> ok +In C_oic, method.toString() returns ↩ +↪C_oic -> ok + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/interpolation.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/interpolation.check new file mode 100644 index 0000000000..9c4a77715b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/interpolation.check @@ -0,0 +1,32 @@ +Bob is 1 years old +Bob is 1 years old +Bob will be 2 years old +Bob will be 2 years old +1+1 = 2 +1+1 = 2 +Bob is 12 years old +Bob is 12 years old +Bob will be 13 years old +Bob will be 13 years old +12+1 = 13 +12+1 = 13 +Bob is 123 years old +Bob is 123 years old +Bob will be 124 years old +Bob will be 124 years old +123+1 = 124 +123+1 = 124 +Best price: 10 +Best price: 10.00 +10% discount included +10.00% discount included +Best price: 13.345000267028809 +Best price: 13.35 +13.345000267028809% discount included +13.35% discount included + +0 +00 + +0 +00 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/interpolationMultiline1.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/interpolationMultiline1.check new file mode 100644 index 0000000000..1b6e140c13 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/interpolationMultiline1.check @@ -0,0 +1,26 @@ +Bob is 1 years old +Bob is 1 years old +Bob will be 2 years old +Bob will be 2 years old +1+1 = 2 +1+1 = 2 +Bob is 12 years old +Bob is 12 years old +Bob will be 13 years old +Bob will be 13 years old +12+1 = 13 +12+1 = 13 +Bob is 123 years old +Bob is 123 years old +Bob will be 124 years old +Bob will be 124 years old +123+1 = 124 +123+1 = 124 +Best price: 10 +Best price: 10.00 +10% discount included +10.00% discount included +Best price: 13.345000267028809 +Best price: 13.35 +13.345000267028809% discount included +13.35% discount included diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/issue192.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/issue192.sem new file mode 100644 index 0000000000..10abbf7f3b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/issue192.sem @@ -0,0 +1 @@ +strictFloats diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/macro-bundle-static.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/macro-bundle-static.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/macro-bundle-static.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/macro-bundle-toplevel.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/macro-bundle-toplevel.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/macro-bundle-toplevel.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/macro-bundle-whitebox-decl.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/macro-bundle-whitebox-decl.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/macro-bundle-whitebox-decl.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/misc.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/misc.check new file mode 100644 index 0000000000..85f37c51d7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/misc.check @@ -0,0 +1,62 @@ +misc.scala:46: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 42; + ^ +misc.scala:47: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 42l; + ^ +misc.scala:48: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 23.5f; + ^ +misc.scala:49: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 23.5; + ^ +misc.scala:50: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + "Hello"; + ^ +misc.scala:51: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 32 + 45; + ^ +misc.scala:62: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + x; + ^ +misc.scala:74: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 1 < 2; + ^ +### Hello +### 17 +### Bye + +### fib(0) = ↩ +↪1 +### fib(1) = ↩ +↪1 +### fib(2) = ↩ +↪2 +### fib(3) = ↩ +↪3 +### fib(4) = ↩ +↪5 +=== MyClass::toString === +=== MySubclass::toString === +=== MyClass::test === + +identity + +A.a = 1 +B.a = 5 +B.b = 2 + +X.a = 4 +Y.a = 11 +Y.b = 5 +Y.b = 5 + +X::foo + +Y::foo +X::foo + +3 +3 + +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/promotion.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/promotion.check new file mode 100644 index 0000000000..41e36c369d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/promotion.check @@ -0,0 +1,4 @@ +2 +6 +20 +30 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/runtime.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/runtime.check new file mode 100644 index 0000000000..0450b9498a --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/runtime.check @@ -0,0 +1,70 @@ +runtime.scala:141: warning: comparing values of types Null and Null using `eq' will always yield true + check(true , null eq null, null ne null); + ^ +runtime.scala:141: warning: comparing values of types Null and Null using `ne' will always yield false + check(true , null eq null, null ne null); + ^ +<<< Test0 +[false,true] +[0,1,2] +[3,4,5] +[a,b,c] +[6,7,8] +[9,10,11] +[12,13] +[14,15] +[string] +>>> Test0 + +<<< Test1 +10 +14 +15 +16 +20 +23 +24 +25 +26 +>>> Test1 + +<<< Test2 +A +M0 +N0 + +A +N0 +M0 + +A +M0 +M1 +N0 + +A +N0 +N1 +M0 + +>>> Test2 + +<<< Test3 +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +>>> Test3 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/spec-self.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/spec-self.check new file mode 100644 index 0000000000..fd3c81a4d7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/spec-self.check @@ -0,0 +1,2 @@ +5 +5 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/structural.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/structural.check new file mode 100644 index 0000000000..2fec112a87 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/structural.check @@ -0,0 +1,37 @@ + 1. hey + 2. 11 + 3. dee + 4. iei + 5. 6 + 6. 51 + 7. 2 + 8. 11 +10. 12 +11. eitch +12. 1 +13. ohone +14. 1 +15. undefined +16. one +17. tieone +18. 2 +19. true +20. 1 +21. undefined +22. one +23. oy +24. 1 +25. null +26. iei +31. 4 +32. undefined +33. iei +33. tieone +1 +2 +3 +4 +5 +caught +3 +2 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t0421-new.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t0421-new.check new file mode 100644 index 0000000000..00d29b7e5b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t0421-new.check @@ -0,0 +1,3 @@ +[Array(0, 1),Array(2, 3),Array(4, 5)] +[Array(31)] +[Array(24, 32)] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t0421-old.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t0421-old.check new file mode 100644 index 0000000000..00d29b7e5b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t0421-old.check @@ -0,0 +1,3 @@ +[Array(0, 1),Array(2, 3),Array(4, 5)] +[Array(31)] +[Array(24, 32)] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t1503.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t1503.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t1503.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t3702.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t3702.check new file mode 100644 index 0000000000..3fce98715c --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t3702.check @@ -0,0 +1,2 @@ +undefined +6 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t4148.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t4148.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t4148.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t4617.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t4617.check new file mode 100644 index 0000000000..a6790f16f7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t4617.check @@ -0,0 +1 @@ +Str 8 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t5356.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t5356.check new file mode 100644 index 0000000000..870c901131 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t5356.check @@ -0,0 +1,6 @@ +1 java.lang.Byte +1 java.lang.Byte +1 scala.math.BigInt +1 java.lang.Byte +1 java.lang.Byte +1 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t5552.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t5552.check new file mode 100644 index 0000000000..9e767b6d7b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t5552.check @@ -0,0 +1,6 @@ +lazy: 3 +(3,3) +(3,3) +lazy: 3 +(3,3) +(3,3) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t5568.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t5568.check new file mode 100644 index 0000000000..6f30cc5070 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t5568.check @@ -0,0 +1,9 @@ +void +int +class scala.runtime.BoxedUnit +class scala.runtime.BoxedUnit +class java.lang.Byte +class java.lang.Byte +5 +5 +5 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t5629b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t5629b.check new file mode 100644 index 0000000000..c65298a6ce --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t5629b.check @@ -0,0 +1,10 @@ +=== pf(1): +MySmartPF.apply entered... +newPF.applyOrElse entered... +default +scala.MatchError: 1 (of class java.lang.Byte) +=== pf(42): +MySmartPF.apply entered... +newPF.applyOrElse entered... +ok +=== done diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t5680.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t5680.check new file mode 100644 index 0000000000..a3b8b64a43 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t5680.check @@ -0,0 +1,3 @@ +[Lscala.runtime.BoxedUnit +undefined +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t5866.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t5866.check new file mode 100644 index 0000000000..64df1cec7f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t5866.check @@ -0,0 +1,2 @@ +0 +Foo(0) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t6318_primitives.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t6318_primitives.check new file mode 100644 index 0000000000..654ef1beec --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t6318_primitives.check @@ -0,0 +1,54 @@ +Checking if byte matches byte +Some(1) +Checking if byte matches short +Some(1) +Checking if class java.lang.Byte matches byte +Some(1) +Checking if short matches short +Some(1) +Checking if short matches char +None +Checking if class java.lang.Byte matches short +Some(1) +Checking if char matches char +Some() +Checking if char matches int +None +Checking if class java.lang.Character matches char +Some() +Checking if int matches int +Some(1) +Checking if int matches long +None +Checking if class java.lang.Byte matches int +Some(1) +Checking if long matches long +Some(1) +Checking if long matches float +None +Checking if class java.lang.Long matches long +Some(1) +Checking if float matches float +Some(1) +Checking if float matches double +Some(1) +Checking if class java.lang.Byte matches float +Some(1) +Checking if double matches double +Some(1) +Checking if double matches boolean +None +Checking if class java.lang.Byte matches double +Some(1) +Checking if boolean matches boolean +Some(true) +Checking if boolean matches void +None +Checking if class java.lang.Boolean matches boolean +Some(true) +Checking if void matches void +Some(undefined) +Checking if void matches byte +None +Checking if class scala.runtime.BoxedUnit matches void +Some(undefined) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t6662.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t6662.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t6662.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t7657.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t7657.check new file mode 100644 index 0000000000..1a87c1e866 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t7657.check @@ -0,0 +1,3 @@ +undefined +undefined +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t7763.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t7763.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t7763.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t8570a.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t8570a.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t8570a.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t8764.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t8764.check new file mode 100644 index 0000000000..121120217e --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t8764.check @@ -0,0 +1,5 @@ +IntOnly: should return an unboxed int +Int: int +IntAndDouble: should just box and return Anyval +Double: class java.lang.Byte +Int: class java.lang.Byte diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t9387b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t9387b.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t9387b.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t9656.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t9656.check new file mode 100644 index 0000000000..a16c04eaad --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/t9656.check @@ -0,0 +1,14 @@ +Range 1 to 10 +Range 1 to 10 +inexact Range 1 to 10 by 2 +Range 1 to 10 by 3 +inexact Range 1 until 10 by 2 +Range 100 to 100 +empty Range 100 until 100 +NumericRange 1 to 10 +NumericRange 1 to 10 by 2 +NumericRange 0.1 until 1 by 0.1 +NumericRange 0.1 until 1.0 by 0.1 +NumericRange 0.1 until 1 by 0.1 (using NumericRange 0.1 until 1 by 0.1 of BigDecimal) +NumericRange 0 days until 10 seconds by 1 second +empty NumericRange 0 days until 0 days by 1 second diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/try-catch-unify.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/try-catch-unify.check new file mode 100644 index 0000000000..813f01166d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/try-catch-unify.check @@ -0,0 +1,4 @@ +Failure(java.lang.NumberFormatException: For input string: "Hi") +Success(5) +O NOES +Failure(java.lang.NumberFormatException: For input string: "Hi") diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/virtpatmat_switch.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/virtpatmat_switch.check new file mode 100644 index 0000000000..0900a9ca32 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/virtpatmat_switch.check @@ -0,0 +1,7 @@ +zero +one +many +got a +got b +got some letter +scala.MatchError: 5 (of class java.lang.Byte) \ No newline at end of file diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/virtpatmat_typetag.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/virtpatmat_typetag.check new file mode 100644 index 0000000000..048c3aeed0 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/run/virtpatmat_typetag.check @@ -0,0 +1,10 @@ +1 is a Int +1 is a java.lang.Integer +1 is not a java.lang.String; it's a class java.lang.Byte +true is a Any +woele is a java.lang.String +1 is a Int +1 is a java.lang.Integer +1 is not a java.lang.String; it's a class java.lang.Byte +true is a Any +woele is a java.lang.String diff --git a/project/Build.scala b/project/Build.scala index 661b55c2c6..a3eb2048b3 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -65,7 +65,7 @@ object Build { CrossVersion.binaryMapped(v => s"sjs${previousSJSBinaryVersion}_$v") val scalaVersionsUsedForPublishing: Set[String] = - Set("2.10.6", "2.11.11", "2.12.3", "2.13.0-M2") + Set("2.10.6", "2.11.11", "2.12.4", "2.13.0-M2") val newScalaBinaryVersionsInThisRelease: Set[String] = Set() diff --git a/scala-test-suite/src/test/resources/2.12.4/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.12.4/BlacklistedTests.txt new file mode 100644 index 0000000000..bd6ef4f6ca --- /dev/null +++ b/scala-test-suite/src/test/resources/2.12.4/BlacklistedTests.txt @@ -0,0 +1,135 @@ +## Do not compile +scala/lang/annotations/BytecodeTest.scala +scala/lang/annotations/RunTest.scala +scala/lang/traits/BytecodeTest.scala +scala/lang/traits/RunTest.scala +scala/lang/primitives/NaNTest.scala +scala/lang/primitives/BoxUnboxTest.scala +scala/reflect/ClassOfTest.scala +scala/reflect/QTest.scala +scala/reflect/io/ZipArchiveTest.scala +scala/reflect/internal/util/AbstractFileClassLoaderTest.scala +scala/reflect/internal/util/SourceFileTest.scala +scala/reflect/internal/util/StringOpsTest.scala +scala/reflect/internal/PrintersTest.scala +scala/reflect/internal/ScopeTest.scala +scala/reflect/internal/TreeGenTest.scala +scala/reflect/internal/TypesTest.scala +scala/reflect/internal/util/WeakHashSetTest.scala +scala/reflect/internal/MirrorsTest.scala +scala/reflect/internal/NamesTest.scala +scala/tools/nsc/backend/jvm/BTypesTest.scala +scala/tools/nsc/backend/jvm/BytecodeTest.scala +scala/tools/nsc/backend/jvm/DefaultMethodTest.scala +scala/tools/nsc/backend/jvm/DirectCompileTest.scala +scala/tools/nsc/backend/jvm/GenericSignaturesTest.scala +scala/tools/nsc/backend/jvm/IndyLambdaTest.scala +scala/tools/nsc/backend/jvm/IndySammyTest.scala +scala/tools/nsc/backend/jvm/InnerClassAttributeTest.scala +scala/tools/nsc/backend/jvm/NestedClassesCollectorTest.scala +scala/tools/nsc/backend/jvm/OptimizedBytecodeTest.scala +scala/tools/nsc/backend/jvm/StringConcatTest.scala +scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala +scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala +scala/tools/nsc/backend/jvm/opt/AnalyzerTest.scala +scala/tools/nsc/backend/jvm/opt/BoxUnboxTest.scala +scala/tools/nsc/backend/jvm/opt/BTypesFromClassfileTest.scala +scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala +scala/tools/nsc/backend/jvm/opt/ClosureOptimizerTest.scala +scala/tools/nsc/backend/jvm/opt/CompactLocalVariablesTest.scala +scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala +scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala +scala/tools/nsc/backend/jvm/opt/InlineInfoTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerIllegalAccessTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerTest.scala +scala/tools/nsc/backend/jvm/opt/InlineSourceMatcherTest.scala +scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala +scala/tools/nsc/backend/jvm/opt/MethodLevelOptsTest.scala +scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala +scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala +scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala +scala/tools/nsc/backend/jvm/opt/UnusedLocalVariablesTest.scala +scala/tools/nsc/ScriptRunnerTest.scala +scala/tools/nsc/classpath/AggregateClassPathTest.scala +scala/tools/nsc/classpath/JrtClassPathTest.scala +scala/tools/nsc/classpath/PathResolverBaseTest.scala +scala/tools/nsc/classpath/VirtualDirectoryClassPathTest.scala +scala/tools/nsc/classpath/ZipAndJarFileLookupFactoryTest.scala +scala/tools/nsc/doc/html/HtmlDocletTest.scala +scala/tools/nsc/interpreter/CompletionTest.scala +scala/tools/nsc/interpreter/ScriptedTest.scala +scala/tools/nsc/interpreter/TabulatorTest.scala +scala/tools/nsc/reporters/ConsoleReporterTest.scala +scala/tools/nsc/settings/ScalaVersionTest.scala +scala/tools/nsc/settings/SettingsTest.scala +scala/tools/nsc/symtab/CannotHaveAttrsTest.scala +scala/tools/nsc/symtab/FlagsTest.scala +scala/tools/nsc/symtab/FreshNameExtractorTest.scala +scala/tools/nsc/symtab/StdNamesTest.scala +scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala +scala/tools/nsc/symtab/SymbolTableTest.scala +scala/tools/nsc/transform/delambdafy/DelambdafyTest.scala +scala/tools/nsc/transform/patmat/SolvingTest.scala +scala/tools/nsc/transform/patmat/PatmatBytecodeTest.scala +scala/tools/nsc/typechecker/Implicits.scala +scala/tools/nsc/util/StackTraceTest.scala +scala/tools/testing/BytecodeTesting.scala +scala/tools/testing/RunTesting.scala + +## Do not link +scala/MatchErrorSerializationTest.scala +scala/PartialFunctionSerializationTest.scala +scala/lang/stringinterpol/StringContextTest.scala +scala/collection/IteratorTest.scala +scala/collection/NewBuilderTest.scala +scala/collection/ParallelConsistencyTest.scala +scala/collection/SeqViewTest.scala +scala/collection/SetMapConsistencyTest.scala +scala/collection/concurrent/TrieMapTest.scala +scala/collection/convert/WrapperSerializationTest.scala +scala/collection/immutable/ListTest.scala +scala/collection/immutable/StreamTest.scala +scala/collection/immutable/StringLikeTest.scala +scala/collection/mutable/ArrayBufferTest.scala +scala/collection/mutable/MutableListTest.scala +scala/collection/mutable/OpenHashMapTest.scala +scala/collection/mutable/PriorityQueueTest.scala +scala/collection/parallel/immutable/ParRangeTest.scala +scala/concurrent/duration/SerializationTest.scala +scala/concurrent/impl/DefaultPromiseTest.scala +scala/io/SourceTest.scala +scala/runtime/ScalaRunTimeTest.scala +scala/sys/process/PipedProcessTest.scala +scala/sys/process/ProcessTest.scala +scala/tools/testing/AssertUtilTest.scala +scala/tools/testing/AssertThrowsTest.scala +scala/util/SpecVersionTest.scala +scala/util/SystemPropertiesTest.scala + +## Tests fail + +# Reflection +scala/reflect/ClassTagTest.scala + +# Regex +scala/util/matching/CharRegexTest.scala +scala/util/matching/RegexTest.scala + +# Require strict-floats +scala/math/BigDecimalTest.scala + +# Difference of getClass() on primitive values +scala/collection/immutable/RangeTest.scala + +# Test fails only some times with +# 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' +# and' 'set scalaJSUseRhino in Global := false' +scala/collection/immutable/PagedSeqTest.scala + +# Bugs +scala/collection/convert/MapWrapperTest.scala + +# Tests passed but are too slow (timeouts) +scala/collection/immutable/ListSetTest.scala +scala/util/SortingTest.scala diff --git a/scala-test-suite/src/test/resources/2.12.4/WhitelistedTests.txt b/scala-test-suite/src/test/resources/2.12.4/WhitelistedTests.txt new file mode 100644 index 0000000000..05cb17f701 --- /dev/null +++ b/scala-test-suite/src/test/resources/2.12.4/WhitelistedTests.txt @@ -0,0 +1,41 @@ +scala/collection/IndexedSeqOptimizedTest.scala +scala/collection/IndexedSeqTest.scala +scala/collection/IterableViewLikeTest.scala +scala/collection/LinearSeqOptimizedTest.scala +scala/collection/ReusableBuildersTest.scala +scala/collection/SearchingTest.scala +scala/collection/SeqLikeTest.scala +scala/collection/TraversableLikeTest.scala +scala/collection/TraversableOnceTest.scala +scala/collection/convert/NullSafetyToJavaTest.scala +scala/collection/convert/NullSafetyToScalaTest.scala +scala/collection/immutable/HashMapTest.scala +scala/collection/immutable/ListMapTest.scala +scala/collection/immutable/QueueTest.scala +scala/collection/immutable/RangeConsistencyTest.scala +scala/collection/immutable/SetTest.scala +scala/collection/immutable/TreeMapTest.scala +scala/collection/immutable/TreeSetTest.scala +scala/collection/immutable/VectorTest.scala +scala/collection/mutable/AnyRefMapTest.scala +scala/collection/mutable/ArraySortingTest.scala +scala/collection/mutable/BitSetTest.scala +scala/collection/mutable/HashMapTest.scala +scala/collection/mutable/LinkedHashMapTest.scala +scala/collection/mutable/LinkedHashSetTest.scala +scala/collection/mutable/SetLikeTest.scala +scala/collection/mutable/TreeMapTest.scala +scala/collection/mutable/TreeSetTest.scala +scala/collection/mutable/UnrolledBufferTest.scala +scala/collection/mutable/VectorTest.scala +scala/lang/primitives/PredefAutoboxingTest.scala +scala/math/BigIntTest.scala +scala/math/NumericTest.scala +scala/math/OrderingTest.scala +scala/runtime/ZippedTest.scala +scala/tools/nsc/SampleTest.scala +scala/tools/testing/AssertUtil.scala +scala/tools/testing/TempDir.scala +scala/util/RandomTest.scala +scala/util/TryTest.scala +scala/util/control/ExceptionTest.scala diff --git a/scripts/assemble-cli.sh b/scripts/assemble-cli.sh index f1092e07b7..86856f0086 100755 --- a/scripts/assemble-cli.sh +++ b/scripts/assemble-cli.sh @@ -20,8 +20,8 @@ case $BINVER in BASEVER="2.11.11" ;; 2.12) - FULLVERS="2.12.0 2.12.1 2.12.2 2.12.3" - BASEVER="2.12.3" + FULLVERS="2.12.0 2.12.1 2.12.2 2.12.3 2.12.4" + BASEVER="2.12.4" ;; *) echo "Invalid Scala version $BINVER" >&2 diff --git a/scripts/publish.sh b/scripts/publish.sh index b0795043b2..677a4f24ec 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -7,11 +7,11 @@ else CMD="echo sbt" fi -FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0-M2" -BIN_VERSIONS="2.10.6 2.11.11 2.12.3 2.13.0-M2" -CLI_VERSIONS="2.10.6 2.11.11 2.12.3" +FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.12.0 2.12.1 2.12.2 2.12.3 2.12.4 2.13.0-M2" +BIN_VERSIONS="2.10.6 2.11.11 2.12.4 2.13.0-M2" +CLI_VERSIONS="2.10.6 2.11.11 2.12.4" SBT_VERSION="2.10.6" -SBT1_VERSION="2.12.3" +SBT1_VERSION="2.12.4" SBT1_SBTVERSION="1.0.0" COMPILER="compiler jUnitPlugin" From fb87ef4dedc8a48daa8eb4b160f5886ff46a43b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 1 Nov 2017 21:15:59 +0100 Subject: [PATCH 0528/2665] Version 0.6.21. --- ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index d9f10f9265..60ff12cbbb 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.21-SNAPSHOT" + val current: String = "0.6.21" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" From ebdd7b9f1569488fec2d6f2d428b627814d03990 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 3 Nov 2017 13:44:15 +0100 Subject: [PATCH 0529/2665] Towards 0.6.22. --- ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- project/Build.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index 60ff12cbbb..a9431d7a3e 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.21" + val current: String = "0.6.22-SNAPSHOT" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" diff --git a/project/Build.scala b/project/Build.scala index a3eb2048b3..e02a303e79 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -58,7 +58,7 @@ object Build { val shouldPartest = settingKey[Boolean]( "Whether we should partest the current scala version (and fail if we can't)") - val previousVersion = "0.6.20" + val previousVersion = "0.6.21" val previousSJSBinaryVersion = ScalaJSCrossVersion.binaryScalaJSVersion(previousVersion) val previousBinaryCrossVersion = From ee4d441cefca7f27f4a60fe0b5ebb6d3cf5c7f1d Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 5 Nov 2017 18:57:12 +0100 Subject: [PATCH 0530/2665] Add missing string interpolation. --- .../src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala index 6ae6f67a7e..be70a19aca 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala @@ -173,7 +173,7 @@ trait VirtualSerializedScalaJSIRFile } catch { case e: ir.IRVersionNotSupportedException => throw new ir.IRVersionNotSupportedException(e.version, e.supported, - "Failed to deserialize a file compiled with Scala.js ${e.version}" + + s"Failed to deserialize a file compiled with Scala.js ${e.version}" + s" (supported: ${e.supported.mkString(", ")}): $path", e) case e: IOException => From 7f4e9955aa5ff571c77e9af36cdec358350005dd Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 5 Nov 2017 19:05:09 +0100 Subject: [PATCH 0531/2665] Fix #2528: Check top-level export conflicts in analyzer --- .../core/tools/linker/LinkedClass.scala | 4 --- .../core/tools/linker/analyzer/Analysis.scala | 6 ++++ .../core/tools/linker/analyzer/Analyzer.scala | 20 +++++++++++ .../core/tools/linker/analyzer/Infos.scala | 19 ++++++++--- .../tools/linker/frontend/BaseLinker.scala | 29 ---------------- .../core/tools/linker/AnalyzerTest.scala | 34 +++++++++++++++++++ 6 files changed, 75 insertions(+), 37 deletions(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala index 7afa1ec464..5db371cfe4 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala @@ -64,10 +64,6 @@ final class LinkedClass( } } - /** Names of all top-level exports in this class. */ - def topLevelExportNames: List[String] = - topLevelExports.map(_.value.topLevelExportName) - def fullName: String = Definitions.decodeClassName(encodedName) def copy( diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala index a7c112d470..11895edb31 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala @@ -172,6 +172,9 @@ object Analysis { final case class NotAModule(info: ClassInfo, from: From) extends Error final case class MissingMethod(info: MethodInfo, from: From) extends Error final case class ConflictingDefaultMethods(infos: List[MethodInfo], from: From) extends Error + final case class ConflictingTopLevelExport(name: String, infos: List[ClassInfo]) extends Error { + def from: From = FromExports + } sealed trait From final case class FromMethod(methodInfo: MethodInfo) extends From @@ -208,6 +211,9 @@ object Analysis { s"Referring to non-existent method ${info.fullDisplayName}" case ConflictingDefaultMethods(infos, _) => s"Conflicting default methods: ${infos.map(_.fullDisplayName).mkString(" ")}" + case ConflictingTopLevelExport(name, infos) => + s"Conflicting top level export for name $name involving " + + infos.map(_.displayName).mkString(", ") } logger.log(level, headMsg) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala index d9bcb9ac24..508c87d348 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala @@ -81,6 +81,9 @@ private final class Analyzer(config: CommonPhaseConfig, // Reach additional data, based on reflection methods used reachDataThroughReflection() + + // Make sure top-level export names do not conflict + checkConflictingExports() } catch { case CyclicDependencyException(chain, from) => _errors += CycleInInheritanceChain(chain, from) @@ -184,6 +187,22 @@ private final class Analyzer(config: CommonPhaseConfig, } } + private def checkConflictingExports(): Unit = { + val namesAndInfos = for { + info <- _classInfos.values + name <- info.topLevelExportNames + } yield { + name -> info + } + + for { + (name, targets) <- namesAndInfos.groupBy(_._1) + if targets.size > 1 + } { + _errors += ConflictingTopLevelExport(name, targets.map(_._2).toList) + } + } + private def tryLookupClass(encodedName: String)( implicit from: From): Option[ClassInfo] = { /* There is a significant amount of duplication with lookupClass, but it @@ -251,6 +270,7 @@ private final class Analyzer(config: CommonPhaseConfig, val isJSType = data.kind.isJSType val isAnyClass = isScalaClass || isJSClass val isExported = data.isExported + val topLevelExportNames = data.topLevelExportNames var superClass: Option[ClassInfo] = _ var interfaces: List[ClassInfo] = _ diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala index 8b1a9eff35..0642f076da 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala @@ -27,7 +27,8 @@ object Infos { val kind: ClassKind, val superClass: Option[String], // always None for interfaces val interfaces: List[String], // direct parent interfaces only - val methods: List[MethodInfo] + val methods: List[MethodInfo], + val topLevelExportNames: List[String] ) object ClassInfo { @@ -37,9 +38,10 @@ object Infos { kind: ClassKind = ClassKind.Class, superClass: Option[String] = None, interfaces: List[String] = Nil, - methods: List[MethodInfo] = Nil): ClassInfo = { + methods: List[MethodInfo] = Nil, + topLevelExportNames: List[String] = Nil): ClassInfo = { new ClassInfo(encodedName, isExported, kind, superClass, - interfaces, methods) + interfaces, methods, topLevelExportNames) } } @@ -92,6 +94,7 @@ object Infos { private var superClass: Option[String] = None private val interfaces = mutable.ListBuffer.empty[String] private val methods = mutable.ListBuffer.empty[MethodInfo] + private var topLevelExportNames: List[String] = Nil def setEncodedName(encodedName: String): this.type = { this.encodedName = encodedName @@ -128,9 +131,14 @@ object Infos { this } + def setTopLevelExportNames(names: List[String]): this.type = { + topLevelExportNames = names + this + } + def result(): ClassInfo = { ClassInfo(encodedName, isExported, kind, superClass, - interfaces.toList, methods.toList) + interfaces.toList, methods.toList, topLevelExportNames) } } @@ -304,6 +312,9 @@ object Infos { val optInfo = generateTopLevelExportsInfo(classDef.name.name, classDef.topLevelExportDefs) optInfo.foreach(builder.addMethod(_)) + + val names = classDef.topLevelExportDefs.map(_.topLevelExportName) + builder.setTopLevelExportNames(names) } builder.result() diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index dfe2be9a75..247f18b9c8 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -77,9 +77,6 @@ final class BaseLinker(config: CommonPhaseConfig) { assemble(moduleInitializers, analysis) } - // Make sure we don't export to the same name twice. - checkConflictingExports(linkResult, logger) - if (checkIR) { logger.time("Linker: Check IR") { val errorCount = IRChecker.check(linkResult, inputProvider, logger) @@ -314,32 +311,6 @@ final class BaseLinker(config: CommonPhaseConfig) { s"Cannot find $methodName in ${classInfo.encodedName}") } } - - private def checkConflictingExports(unit: LinkingUnit, - logger: Logger): Unit = { - val namesAndClasses = for { - classDef <- unit.classDefs - name <- classDef.topLevelExportNames - } yield { - name -> classDef - } - - val errors = for { - (name, namesAndClasses) <- namesAndClasses.groupBy(_._1) - if namesAndClasses.size > 1 - } yield { - logger.log(Level.Error, - s"Conflicting top-level exports to $name from the following classes:") - for ((_, linkedClass) <- namesAndClasses) { - logger.log(Level.Error, s"- ${linkedClass.fullName}") - } - - () - } - - if (errors.nonEmpty) - throw new LinkingException("There were conflicting exports.") - } } private object BaseLinker { diff --git a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/AnalyzerTest.scala b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/AnalyzerTest.scala index bdacd41162..d393e4dfba 100644 --- a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/AnalyzerTest.scala +++ b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/AnalyzerTest.scala @@ -321,6 +321,40 @@ class AnalyzerTest { } } + @Test + def conflictingTopLevelExports(): Unit = { + def singleDef(name: String) = { + classDef(name, + kind = ClassKind.ModuleClass, superClass = Some(ObjectClass), + memberDefs = List(trivialCtor(name)), + topLevelExportDefs = List(TopLevelModuleExportDef("foo"))) + } + + val classDefs = Seq(singleDef("LA"), singleDef("LB")) + val analysis = computeAnalysis(classDefs) + assertContainsError("ConflictingTopLevelExport(foo, LA, LB)", analysis) { + case ConflictingTopLevelExport("foo", List(ClsInfo("LA"), ClsInfo("LB"))) => + true + case ConflictingTopLevelExport("foo", List(ClsInfo("LB"), ClsInfo("LA"))) => + true + } + } + + @Test + def degenerateConflictingTopLevelExports(): Unit = { + val classDefs = Seq(classDef("LA", + kind = ClassKind.ModuleClass, superClass = Some(ObjectClass), + memberDefs = List(trivialCtor("LA")), + topLevelExportDefs = List( + TopLevelModuleExportDef("foo"), + TopLevelModuleExportDef("foo")))) + + val analysis = computeAnalysis(classDefs) + assertContainsError("ConflictingTopLevelExport(foo, )", analysis) { + case ConflictingTopLevelExport("foo", _) => true + } + } + private def validParentForKind(kind: ClassKind): Option[String] = { import ClassKind._ kind match { From 22a8d7dc52669c537154f21519752a8b6680a174 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 12 Aug 2017 13:30:40 +0200 Subject: [PATCH 0532/2665] Fix #2645: Use less JSEnv runners in TestAdapter Instead of spawning 1 + (2 + P) * F runners per test run, where P: level of parallelism F: number of testing frameworks we will only spawn P runners. The fundamental change that allows us to do so, is that the JS side of the test adapter is not tied to a purpose anymore: Before, the JVM side could either start a master or a slave for a given tesing framework (or a special purpose short-lived piece of code). We change the JS side ("bridge") to not have any initial state and be able to do everything as requested via RPC. Notably, after this change the bridge - can detect frameworks, - is not tied to a specific framework - can create an arbitrary type (master/slave) of runner. - can hold runners for multiple frameworks at the same time. As a consequence, multiple frameworks can share the JS bridges and the JS VM that has been used for test detection can be reused. Note that as a side-effect, this also fixes #3143 by abolishing all timeouts. --- project/BinaryIncompatibilities.scala | 123 ++++++++++- .../scalajs/sbtplugin/FrameworkDetector.scala | 93 +-------- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 1 + .../sbtplugin/ScalaJSPluginInternal.scala | 59 +++--- .../sbttestadapter/FrameworkAdapter.scala | 28 +++ .../sbttestadapter/RunnerAdapter.scala | 106 ++++++++++ .../sbttestadapter/ScalaJSFramework.scala | 80 ++------ .../sbttestadapter/ScalaJSRunner.scala | 188 +---------------- .../scalajs/sbttestadapter/ScalaJSTask.scala | 82 +------- .../scalajs/sbttestadapter/TaskAdapter.scala | 55 +++++ .../scalajs/sbttestadapter/TestAdapter.scala | 191 ++++++++++++++++++ .../org/scalajs/sbttestadapter/package.scala | 5 +- .../scalajs/testcommon/FrameworkInfo.scala | 10 +- .../org/scalajs/testcommon/FutureUtil.scala | 19 ++ .../org/scalajs/testcommon/JSEndpoints.scala | 29 +++ .../testcommon/JSMasterEndpoints.scala | 16 -- .../scalajs/testcommon/JSSlaveEndpoints.scala | 16 -- .../org/scalajs/testcommon/JVMEndpoints.scala | 27 +++ .../testcommon/JVMMasterEndpoints.scala | 7 - .../testcommon/JVMSlaveEndpoints.scala | 24 --- .../org/scalajs/testcommon/RPCCore.scala | 8 +- .../scala/org/scalajs/testcommon/RunMux.scala | 20 ++ .../org/scalajs/testcommon/RunMuxRPC.scala | 93 +++++++++ .../org/scalajs/testcommon/RunnerArgs.scala | 13 +- .../scalajs/testcommon/RunMuxRPCTest.scala | 88 ++++++++ .../testinterface/internal/Bridge.scala | 135 +++++++++++++ .../scalajs/testinterface/internal/Com.scala | 12 -- .../internal/FrameworkDetector.scala | 39 ---- .../internal/FrameworkLoader.scala | 27 +++ .../testinterface/internal/InfoSender.scala | 23 --- .../testinterface/internal/JSRPC.scala | 8 + .../testinterface/internal/Master.scala | 63 ------ .../testinterface/internal/Slave.scala | 116 ----------- 33 files changed, 1043 insertions(+), 761 deletions(-) create mode 100644 test-adapter/src/main/scala/org/scalajs/sbttestadapter/FrameworkAdapter.scala create mode 100644 test-adapter/src/main/scala/org/scalajs/sbttestadapter/RunnerAdapter.scala create mode 100644 test-adapter/src/main/scala/org/scalajs/sbttestadapter/TaskAdapter.scala create mode 100644 test-adapter/src/main/scala/org/scalajs/sbttestadapter/TestAdapter.scala create mode 100644 test-common/src/main/scala/org/scalajs/testcommon/FutureUtil.scala create mode 100644 test-common/src/main/scala/org/scalajs/testcommon/JSEndpoints.scala delete mode 100644 test-common/src/main/scala/org/scalajs/testcommon/JSMasterEndpoints.scala delete mode 100644 test-common/src/main/scala/org/scalajs/testcommon/JSSlaveEndpoints.scala create mode 100644 test-common/src/main/scala/org/scalajs/testcommon/JVMEndpoints.scala delete mode 100644 test-common/src/main/scala/org/scalajs/testcommon/JVMMasterEndpoints.scala delete mode 100644 test-common/src/main/scala/org/scalajs/testcommon/JVMSlaveEndpoints.scala create mode 100644 test-common/src/main/scala/org/scalajs/testcommon/RunMux.scala create mode 100644 test-common/src/main/scala/org/scalajs/testcommon/RunMuxRPC.scala create mode 100644 test-common/src/test/scala/org/scalajs/testcommon/RunMuxRPCTest.scala create mode 100644 test-interface/src/main/scala/org/scalajs/testinterface/internal/Bridge.scala delete mode 100644 test-interface/src/main/scala/org/scalajs/testinterface/internal/Com.scala delete mode 100644 test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkDetector.scala delete mode 100644 test-interface/src/main/scala/org/scalajs/testinterface/internal/InfoSender.scala delete mode 100644 test-interface/src/main/scala/org/scalajs/testinterface/internal/Master.scala delete mode 100644 test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 2984c20d1b..0686367c52 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -17,9 +17,91 @@ object BinaryIncompatibilities { ) val SbtPlugin = Seq( + // private[sbtplugin], not an issue. + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.sbtplugin.FrameworkDetector"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.sbtplugin.FrameworkDetector.detect"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.sbtplugin.FrameworkDetector.this"), + + // private, not an issue. + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.sbtplugin.FrameworkDetector$StoreConsole") + ) + + val TestCommon = Seq( + // private[scalajs], not an issue. + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.testcommon.FrameworkInfo.name"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.testcommon.FrameworkInfo.this"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.testcommon.RunnerArgs.this"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testcommon.JSMasterEndpoints"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testcommon.JSMasterEndpoints$"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testcommon.JSSlaveEndpoints"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testcommon.JSSlaveEndpoints$"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testcommon.JVMMasterEndpoints"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testcommon.JVMMasterEndpoints$"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testcommon.JVMSlaveEndpoints"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testcommon.JVMSlaveEndpoints$"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.testcommon.RPCCore#lambda#@tach#1.this") ) - val TestAdapter = Seq( + val TestAdapter = TestCommon ++ Seq( + // breaking in theory + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testadapter.package"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testadapter.package$"), + + // private[testadapter], not an issue. + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.testadapter.package.VMTermTimeout"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.testadapter.ScalaJSRunner.this"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.testadapter.ScalaJSTask.this"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.testadapter.ScalaJSFramework.runDone"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.testadapter.ScalaJSFramework.frameworkName"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.testadapter.ScalaJSFramework.optionalExportsNamespacePrefix"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.testadapter.ScalaJSFramework.moduleKind"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.testadapter.ScalaJSFramework.moduleIdentifier"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.testadapter.ScalaJSFramework.libEnv"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.testadapter.ScalaJSFramework.jsConsole"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.testadapter.ScalaJSFramework.logger"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.testadapter.ScalaJSRunner.getSlave"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.testadapter.ScalaJSRunner.loggerLock"), + + // private, not an issue. + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testadapter.ScalaJSRunner$"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testadapter.ScalaJSRunner$RichFuture"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testadapter.ScalaJSRunner$RichFuture$"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testadapter.ScalaJSTask$LogElement") ) val CLI = Seq( @@ -28,6 +110,43 @@ object BinaryIncompatibilities { val Library = Seq( ) - val TestInterface = Seq( + val TestInterface = TestCommon ++ Seq( + // internal, not an issue. + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testinterface.internal.Com"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testinterface.internal.Com$"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testinterface.internal.FrameworkDetector"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testinterface.internal.FrameworkDetector$"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testinterface.internal.InfoSender"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testinterface.internal.Master"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testinterface.internal.Master$lambda$1"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testinterface.internal.Master$lambda$2"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testinterface.internal.Master$lambda$3"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testinterface.internal.Master$lambda$4"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testinterface.internal.Slave"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testinterface.internal.Slave$Invalidatable"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testinterface.internal.Slave$RemoteEventHandler"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testinterface.internal.Slave$RemoteLogger"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testinterface.internal.Slave$lambda$1"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testinterface.internal.Slave$lambda$2"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testinterface.internal.Slave$lambda$3"), + ProblemFilters.exclude[MissingClassProblem]( + "org.scalajs.testinterface.internal.Slave$lambda$4") ) } diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala index e88764e396..8571eccaf8 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala @@ -1,93 +1,4 @@ package org.scalajs.sbtplugin -import sbt._ - -import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.json._ -import org.scalajs.core.tools.logging.Logger -import org.scalajs.core.tools.linker.backend.ModuleKind - -import org.scalajs.jsenv._ - -import scala.collection.mutable - -private[sbtplugin] final class FrameworkDetector(jsEnv: JSEnv, - moduleKind: ModuleKind, moduleIdentifier: Option[String]) { - - import FrameworkDetector._ - - /** - * Detects which of the test frameworks in `frameworks` exists on - * the classpath. - * - * Each potential name in each [[sbt.TestFramework TestFramework]] is checked - * for existance (on the JavaScript global namespace, using nested bracket select). - * - * Returns a map with found frameworks and the first name with an existing - * definition on the classpath. - * - * Note: No JavaScript type tests are performed by this method - */ - def detect(frameworks: Seq[TestFramework], - logger: Logger): Map[TestFramework, String] = { - val data = frameworks.map(_.implClassNames.toList).toList.toJSON - - val exportsNamespaceExpr = - ScalaJSPluginInternal.makeExportsNamespaceExpr(moduleKind, moduleIdentifier) - - val code = s""" - (function(exportsNamespace) { - "use strict"; - - /* #2752: if there is no testing framework at all on the classpath, - * the testing interface will not be there, and therefore the - * `detectFrameworks` function will not exist. We must therefore be - * careful when selecting it. - */ - var namespace = exportsNamespace; - namespace = namespace.org || {}; - namespace = namespace.scalajs || {}; - namespace = namespace.testinterface || {}; - namespace = namespace.internal || {}; - var detectFrameworksFun = namespace.detectFrameworks || (function(data) { - var results = []; - for (var i = 0; i < data.length; ++i) - results.push(void 0); - return results; - }); - - var data = ${jsonToString(data)}; - var results = detectFrameworksFun(data); - for (var i = 0; i < results.length; ++i) { - console.log("$ConsoleFrameworkPrefix" + (results[i] || "")); - } - })($exportsNamespaceExpr); - """ - - val vf = new MemVirtualJSFile("frameworkDetector.js").withContent(code) - val console = new StoreConsole - - val runner = jsEnv.jsRunner(vf) - runner.run(logger, console) - - // Filter jsDependencies unexpected output - val results = console.buf collect { - case s if s.startsWith(ConsoleFrameworkPrefix) => - s.stripPrefix(ConsoleFrameworkPrefix) - } - - assert(results.size == frameworks.size) - - (frameworks zip results).filter(_._2.nonEmpty).toMap - } - -} - -object FrameworkDetector { - private class StoreConsole extends JSConsole { - val buf = mutable.Buffer.empty[String] - def log(msg: Any): Unit = buf += msg.toString - } - - private val ConsoleFrameworkPrefix = "@scalajs-test-framework-detector:" -} +@deprecated("Empty. Will be removed.", "0.6.22") +object FrameworkDetector diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index fcf94dfb53..21957d61bf 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -522,6 +522,7 @@ object ScalaJSPlugin extends AutoPlugin { { () => prev() + ScalaJSPluginInternal.closeAllTestAdapters() ScalaJSPluginInternal.globalIRCache.clearStats() } }, diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index f41707a1fe..b6af444350 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -30,7 +30,7 @@ import org.scalajs.core.ir.Utils.escapeJS import org.scalajs.core.ir.ScalaJSVersions import org.scalajs.core.ir.Printers.{InfoPrinter, IRTreePrinter} -import org.scalajs.testadapter.ScalaJSFramework +import org.scalajs.testadapter.TestAdapter import scala.util.Try import scala.collection.mutable @@ -49,6 +49,14 @@ object ScalaJSPluginInternal { /** The global Scala.js IR cache */ val globalIRCache: IRFileCache = new IRFileCache() + @tailrec + final private def registerResource[T <: AnyRef]( + l: AtomicReference[List[T]], r: T): r.type = { + val prev = l.get() + if (l.compareAndSet(prev, r :: prev)) r + else registerResource(l, r) + } + private val allocatedIRCaches = new AtomicReference[List[globalIRCache.Cache]](Nil) @@ -57,25 +65,20 @@ object ScalaJSPluginInternal { * The allocated IR cache will automatically be freed when the build is * unloaded. */ - private def newIRCache: globalIRCache.Cache = { - val cache = globalIRCache.newCache - - @tailrec - def registerLoop(): Unit = { - val prevValue = allocatedIRCaches.get() - if (!allocatedIRCaches.compareAndSet(prevValue, cache :: prevValue)) - registerLoop() - } - registerLoop() + private def newIRCache: globalIRCache.Cache = + registerResource(allocatedIRCaches, globalIRCache.newCache) - cache - } + private[sbtplugin] def freeAllIRCaches(): Unit = + allocatedIRCaches.getAndSet(Nil).foreach(_.free()) - private[sbtplugin] def freeAllIRCaches(): Unit = { - val allCaches = allocatedIRCaches.getAndSet(Nil) - for (cache <- allCaches) - cache.free() - } + private val createdTestAdapters = + new AtomicReference[List[TestAdapter]](Nil) + + private def newTestAdapter(jsEnv: ComJSEnv, config: TestAdapter.Config): TestAdapter = + registerResource(createdTestAdapters, new TestAdapter(jsEnv, config)) + + private[sbtplugin] def closeAllTestAdapters(): Unit = + createdTestAdapters.getAndSet(Nil).foreach(_.close()) /** Non-deprecated alias of `scalaJSClearCacheStats` for internal use. */ private[sbtplugin] val scalaJSClearCacheStatsInternal = TaskKey[Unit]( @@ -797,7 +800,7 @@ object ScalaJSPluginInternal { private[sbtplugin] def makeExportsNamespaceExpr(moduleKind: ModuleKind, moduleIdentifier: Option[String]): String = { - // !!! DUPLICATE code with ScalaJSFramework.optionalExportsNamespacePrefix + // !!! DUPLICATE code with TestAdpater.startManagedRunner moduleKind match { case ModuleKind.NoModule => jsGlobalExpr @@ -984,7 +987,6 @@ object ScalaJSPluginInternal { val console = scalaJSConsole.value val logger = streams.value.log - val toolsLogger = sbtLogger2ToolsLogger(logger) val frameworks = testFrameworks.value val jsEnv = loadedJSEnv.value match { @@ -997,14 +999,19 @@ object ScalaJSPluginInternal { val moduleKind = scalaJSModuleKind.value val moduleIdentifier = scalaJSModuleIdentifier.value + val frameworkNames = frameworks.map(_.implClassNames.toList).toList - val detector = - new FrameworkDetector(jsEnv, moduleKind, moduleIdentifier) + val config = TestAdapter.Config() + .withLogger(sbtLogger2ToolsLogger(logger)) + .withJSConsole(console) + .withModuleSettings(moduleKind, moduleIdentifier) - detector.detect(frameworks, toolsLogger) map { case (tf, name) => - (tf, new ScalaJSFramework(name, jsEnv, moduleKind, moduleIdentifier, - toolsLogger, console)) - } + val adapter = newTestAdapter(jsEnv, config) + val frameworkAdapters = adapter.loadFrameworks(frameworkNames) + + frameworks.zip(frameworkAdapters).collect { + case (tf, Some(adapter)) => (tf, adapter) + }.toMap }, // Override default to avoid triggering a test:fastOptJS in a test:compile // without loosing autocompletion. diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/FrameworkAdapter.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/FrameworkAdapter.scala new file mode 100644 index 0000000000..e11654af35 --- /dev/null +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/FrameworkAdapter.scala @@ -0,0 +1,28 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package org.scalajs.testadapter + +import org.scalajs.testcommon._ +import sbt.testing._ + +private[testadapter] final class FrameworkAdapter(info: FrameworkInfo, + testAdapter: TestAdapter) extends Framework { + + val name: String = info.displayName + + def fingerprints: Array[Fingerprint] = info.fingerprints.toArray + + def runner(args: Array[String], remoteArgs: Array[String], + testClassLoader: ClassLoader): Runner = { + RunnerAdapter(testAdapter, info.implName, args, remoteArgs) + } + + override def toString(): String = s"FrameworkAdapter($name)" +} diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/RunnerAdapter.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/RunnerAdapter.scala new file mode 100644 index 0000000000..77af6533ff --- /dev/null +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/RunnerAdapter.scala @@ -0,0 +1,106 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js test adapter ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package org.scalajs.testadapter + +import scala.collection.concurrent.TrieMap + +import scala.concurrent._ +import scala.concurrent.ExecutionContext.Implicits.global +import scala.concurrent.duration._ + +import scala.util._ + +import org.scalajs.testcommon._ + +import sbt.testing._ + +import FutureUtil._ +import TestAdapter.ManagedRunner + +private final class RunnerAdapter private (runnerArgs: RunnerArgs, + master: ManagedRunner, testAdapter: TestAdapter) extends Runner { + + private val runID = runnerArgs.runID + private val rpcGetter = () => getRunnerRPC() + + private val slaves = TrieMap.empty[Long, ManagedRunner] + + // Route master messages to slaves. + master.mux.attach(JVMEndpoints.msgMaster, runID) { msg => + slaves(msg.slaveId).mux.send(JSEndpoints.msgSlave, runID)(msg.msg) + } + + def args(): Array[String] = runnerArgs.args.toArray + + def remoteArgs(): Array[String] = runnerArgs.remoteArgs.toArray + + def tasks(taskDefs: Array[TaskDef]): Array[Task] = { + getRunnerRPC() + .call(JSEndpoints.tasks, runID)(taskDefs.toList) + .await() + .map(new TaskAdapter(_, runID, rpcGetter)) + .toArray + } + + def done(): String = synchronized { + val slaves = this.slaves.values.toList // .toList to make it strict. + + try { + slaves.map(_.mux.call(JSEndpoints.done, runID)(())).foreach(_.await()) + master.mux.call(JSEndpoints.done, runID)(()).await() + } finally { + slaves.foreach(_.mux.detach(JVMEndpoints.msgSlave, runID)) + master.mux.detach(JVMEndpoints.msgMaster, runID) + + this.slaves.clear() + testAdapter.runDone(runID) + } + } + + private def getRunnerRPC(): RunMuxRPC = { + val mRunner = testAdapter.getRunnerForThread() + + if (mRunner != master && !slaves.contains(mRunner.id)) { + // Put the slave in the map so messages can be routed. + slaves.put(mRunner.id, mRunner) + + // Attach message endpoint. + mRunner.mux.attach(JVMEndpoints.msgSlave, runID) { msg => + master.mux.send(JSEndpoints.msgMaster, runID)( + new FrameworkMessage(mRunner.id, msg)) + } + + // Start slave. + mRunner.com.call(JSEndpoints.createSlaveRunner)(runnerArgs).await() + } + + mRunner.mux + } +} + +private[testadapter] object RunnerAdapter { + def apply(testAdapter: TestAdapter, frameworkImplName: String, + args: Array[String], remoteArgs: Array[String]): Runner = { + val runID = testAdapter.runStarting() + + try { + val runnerArgs = new RunnerArgs(runID, frameworkImplName, + args.toList, remoteArgs.toList) + val mRunner = testAdapter.getRunnerForThread() + mRunner.com.call(JSEndpoints.createMasterRunner)(runnerArgs).await() + + new RunnerAdapter(runnerArgs, mRunner, testAdapter) + } catch { + case t: Throwable => + testAdapter.runDone(runID) + throw t + } + } +} diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala index 6c37382b27..7f19b800b7 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala @@ -21,13 +21,15 @@ import org.scalajs.testcommon._ import sbt.testing.{Logger => _, _} +/** A shim over [[TestAdapter]] for compatiblity. */ +@deprecated("Use TestAdapter instead.", "0.6.22") final class ScalaJSFramework( - private[testadapter] val frameworkName: String, - private[testadapter] val libEnv: ComJSEnv, - private[testadapter] val moduleKind: ModuleKind, - private[testadapter] val moduleIdentifier: Option[String], - private[testadapter] val logger: Logger, - private[testadapter] val jsConsole: JSConsole + frameworkName: String, + libEnv: ComJSEnv, + moduleKind: ModuleKind, + moduleIdentifier: Option[String], + logger: Logger, + jsConsole: JSConsole ) extends Framework { def this(frameworkName: String, libEnv: ComJSEnv, logger: Logger, @@ -35,64 +37,26 @@ final class ScalaJSFramework( this(frameworkName, libEnv, ModuleKind.NoModule, None, logger, jsConsole) } - private[this] val frameworkInfo = fetchFrameworkInfo() + private[this] val adapter = { + val config = TestAdapter.Config() + .withLogger(logger) + .withJSConsole(jsConsole) + .withModuleSettings(moduleKind, moduleIdentifier) - private[this] var _isRunning = false - - val name: String = frameworkInfo.name - - def fingerprints: Array[Fingerprint] = frameworkInfo.fingerprints.toArray - - def runner(args: Array[String], remoteArgs: Array[String], - testClassLoader: ClassLoader): Runner = synchronized { - - if (_isRunning) { - throw new IllegalStateException( - "Scala.js test frameworks do not support concurrent runs") - } - - _isRunning = true - - new ScalaJSRunner(this, args, remoteArgs) + new TestAdapter(libEnv, config) } - private[testadapter] def runDone(): Unit = synchronized { - _isRunning = false - } + private[this] val realFramework = + adapter.loadFrameworks(List(List(frameworkName))).head.get - private def fetchFrameworkInfo() = { - val runner = libEnv.comRunner(frameworkInfoLauncher) - runner.start(logger, jsConsole) + def name: String = realFramework.name - try { - Serializer.deserialize[FrameworkInfo](runner.receive()) - } finally { - runner.close() - runner.await(VMTermTimeout) - } - } + def fingerprints: Array[Fingerprint] = realFramework.fingerprints - private def frameworkInfoLauncher = { - val prefix = optionalExportsNamespacePrefix - val name = jsonToString(frameworkName.toJSON) - val code = s""" - new ${prefix}org.scalajs.testinterface.internal.InfoSender($name).initAndSend(); - """ - new MemVirtualJSFile(s"testFrameworkInfo.js").withContent(code) + def runner(args: Array[String], remoteArgs: Array[String], + testClassLoader: ClassLoader): Runner = { + realFramework.runner(args, remoteArgs, testClassLoader) } - private[testadapter] def optionalExportsNamespacePrefix: String = { - // !!! DUPLICATE code with ScalaJSPlugin.makeExportsNamespaceExpr - moduleKind match { - case ModuleKind.NoModule => - "" - - case ModuleKind.CommonJSModule => - val moduleIdent = moduleIdentifier.getOrElse { - throw new IllegalArgumentException( - "The module identifier must be specified for CommonJS modules") - } - s"""require("${escapeJS(moduleIdent)}").""" // note the final '.' - } - } + override protected def finalize(): Unit = adapter.close() } diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala index 2b2c6bf0ff..781d034a8e 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala @@ -9,187 +9,13 @@ package org.scalajs.testadapter -import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.json._ -import org.scalajs.jsenv._ -import org.scalajs.testcommon._ - -import scala.collection.concurrent.TrieMap - -import scala.concurrent.{Await, Future} -import scala.concurrent.duration._ -import scala.concurrent.ExecutionContext.Implicits.global - -import scala.util.{Try, Failure, Success} - -import java.util.concurrent.atomic.AtomicInteger - import sbt.testing._ -final class ScalaJSRunner private[testadapter] ( - framework: ScalaJSFramework, - val args: Array[String], - val remoteArgs: Array[String] -) extends Runner { - import ScalaJSRunner._ - - // State and simple vals - - private[this] var master: ComJSEnvRPC = null - - /** Map of ThreadId -> Slave */ - private[this] val slaves = TrieMap.empty[Long, ComJSEnvRPC] - - /** An object used as lock for the loggers. Ensures output does not get - * interleaved. - */ - private[testadapter] val loggerLock = new Object - - // Constructor body - - createRemoteRunner() - - // Public API - - def tasks(taskDefs: Array[TaskDef]): Array[Task] = synchronized { - ensureNotDone() - - val taskInfos = Await.result( - master.call(JSMasterEndpoints.tasks)(taskDefs.toList), 1.minutes) - - taskInfos.map(new ScalaJSTask(this, _)).toArray - } - - def done(): String = synchronized { - ensureNotDone() - - val slaves = this.slaves.values.toList // .toList to make it strict. - - def waitAndClose[T](v: Future[T], r: ComJSEnvRPC): Future[Try[T]] = - v.liftToTry.map { x => r.close(); x }.liftToTry.map(_.flatten) - - def stopSlave(slave: ComJSEnvRPC): Future[Try[Unit]] = - waitAndClose(slave.call(JSSlaveEndpoints.stopSlave)(()), slave) - - def stopMaster(): Future[Try[String]] = - waitAndClose(master.call(JSMasterEndpoints.runnerDone)(()), master) - - val futureSummary = for { - // First we run the stopping sequence of the slaves - slaveTries <- Future.sequence(slaves.map(stopSlave)) - - // Once all slaves are closing, we can schedule termination of the master. - summaryTry <- stopMaster() - - // Now wait for termination of the VMs - doneTries <- Future.sequence(master.runner.future.liftToTry :: - slaves.map(_.runner.future.liftToTry)) - } yield { - // Now that everything is done, we can throw any exception. - (slaveTries ::: summaryTry :: doneTries).foreach(_.get) - - // Get the summary. - summaryTry.get - } - - try { - /* We need to double the VMTermTimeout since we wait for the slaves and - * the master in sequence. - */ - Await.result(futureSummary, VMTermTimeout * 2) - } finally { - // Do the best we can to stop the VMs. - master.runner.stop() - slaves.foreach(_.runner.stop()) - - master = null - this.slaves.clear() - - framework.runDone() - } - } - - // Slave Management - - private[testadapter] def getSlave(): ComJSEnvRPC = { - val threadId = Thread.currentThread().getId() - - // Note that this is thread safe, since each thread can only operate on - // the value associated to its thread id. - slaves.getOrElse(threadId, createSlave(threadId)) - } - - private def createSlave(threadId: Long): ComJSEnvRPC = { - // We don't want to create new slaves when we're closing/closed - ensureNotDone() - - // Launch the slave - val slave = framework.libEnv.comRunner(slaveLauncher) - slave.start(framework.logger, framework.jsConsole) - - // Setup RPC - val com = new ComJSEnvRPC(slave) - com.attach(JVMSlaveEndpoints.msg) { msg => - master.send(JSMasterEndpoints.msg)(new FrameworkMessage(threadId, msg)) - } - - // Put the slave into the map, so replies from the master can be routed. - slaves.put(threadId, com) - - // Create a runner on the slave - Await.result(com.call(JSSlaveEndpoints.newRunner)(()), 1.minutes) - - com - } - - // Helpers - - private def slaveLauncher = { - val prefix = framework.optionalExportsNamespacePrefix - val frameworkJS = jsonToString(framework.frameworkName.toJSON) - val argsJS = jsonToString(args.toList.toJSON) - val remoteArgsJS = jsonToString(remoteArgs.toList.toJSON) - val code = s""" - new ${prefix}org.scalajs.testinterface.internal.Slave($frameworkJS, - $argsJS, $remoteArgsJS); - """ - new MemVirtualJSFile("testSlave.js").withContent(code) - } - - private def masterLauncher = { - val prefix = framework.optionalExportsNamespacePrefix - val name = jsonToString(framework.frameworkName.toJSON) - val code = s""" - new ${prefix}org.scalajs.testinterface.internal.Master($name); - """ - new MemVirtualJSFile(s"testMaster.js").withContent(code) - } - - private def ensureNotDone(): Unit = synchronized { - if (master == null) - throw new IllegalStateException("Runner is already done") - } - - private def createRemoteRunner(): Unit = { - assert(master == null) - - val runner = framework.libEnv.comRunner(masterLauncher) - runner.start(framework.logger, framework.jsConsole) - - master = new ComJSEnvRPC(runner) - - master.attach(JVMMasterEndpoints.msg) { msg => - slaves(msg.slaveId).send(JSSlaveEndpoints.msg)(msg.msg) - } - - val req = new RunnerArgs(args.toList, remoteArgs.toList) - Await.result(master.call(JSMasterEndpoints.newRunner)(req), 1.minute) - } -} - -private object ScalaJSRunner { - implicit class RichFuture[T](val __self: Future[T]) extends AnyVal { - def liftToTry: Future[Try[T]] = - __self.map(Success(_)).recover(PartialFunction(Failure(_))) - } +/** Binary compat only. */ +@deprecated("Unused, use TestAdapter instead", "0.6.22") +final class ScalaJSRunner private () extends Runner { + def args(): Array[String] = ??? + def done(): String = ??? + def remoteArgs(): Array[String] = ??? + def tasks(x: Array[TaskDef]): Array[Task] = ??? } diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSTask.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSTask.scala index e8bb1fc111..60f7cd5fe1 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSTask.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSTask.scala @@ -9,80 +9,16 @@ package org.scalajs.testadapter -import org.scalajs.jsenv._ -import org.scalajs.testcommon._ - -import scala.concurrent.Await -import scala.concurrent.duration.Duration -import scala.collection.mutable -import scala.util.Try - import sbt.testing._ -final class ScalaJSTask private[testadapter] ( - runner: ScalaJSRunner, - taskInfo: TaskInfo -) extends Task { - - def taskDef: TaskDef = taskInfo.taskDef - def tags: Array[String] = taskInfo.tags.toArray - - def execute(handler: EventHandler, loggers: Array[Logger]): Array[Task] = { - val slave = runner.getSlave() - - // Prepare result handler - // TODO rip this out once we know it doesn't garble the logs. - val shouldBufferLog = { - val propName = "org.scalajs.testadapter.bufferlog" - Try(System.getProperty(propName, "false").toBoolean).getOrElse(false) - } - - val logBuffer = mutable.Buffer.empty[ScalaJSTask.LogElement[_]] - - def log[T](level: Logger => (T => Unit))(log: LogElement[T]): Unit = { - if (shouldBufferLog) { - logBuffer += new ScalaJSTask.LogElement(log.index, level, log.x) - } else { - level(loggers(log.index))(log.x) - } - } - - slave.attach(JVMSlaveEndpoints.event)(handler.handle _) - slave.attach(JVMSlaveEndpoints.logError)(log(_.error)) - slave.attach(JVMSlaveEndpoints.logWarn)(log(_.warn)) - slave.attach(JVMSlaveEndpoints.logInfo)(log(_.info)) - slave.attach(JVMSlaveEndpoints.logDebug)(log(_.debug)) - slave.attach(JVMSlaveEndpoints.logTrace)(log(_.trace)) - - try { - // Execute task. No (!) timeout. - val req = - new ExecuteRequest(taskInfo, loggers.map(_.ansiCodesSupported).toList) - val taskInfos = Await.result( - slave.call(JSSlaveEndpoints.execute)(req), Duration.Inf) - - // Flush log buffer - if (shouldBufferLog) { - runner.loggerLock.synchronized { - logBuffer.foreach(_.call(loggers)) - } - } - - taskInfos.map(new ScalaJSTask(runner, _)).toArray - } finally { - slave.detach(JVMSlaveEndpoints.event) - slave.detach(JVMSlaveEndpoints.logError) - slave.detach(JVMSlaveEndpoints.logWarn) - slave.detach(JVMSlaveEndpoints.logInfo) - slave.detach(JVMSlaveEndpoints.logDebug) - slave.detach(JVMSlaveEndpoints.logTrace) - } - } +/** Binary compat only. */ +@deprecated("Unused, use TestAdapter instead", "0.6.22") +final class ScalaJSTask private () extends Task { + def execute(x: EventHandler,y: Array[Logger]): Array[Task] = ??? + def tags(): Array[String] = ??? + def taskDef(): TaskDef = ??? } -object ScalaJSTask { - private final class LogElement[T](index: Int, - log: Logger => (T => Unit), data: T) { - def call(arr: Array[Logger]): Unit = log(arr(index))(data) - } -} +/** Binary compat only. */ +@deprecated("Unused, use TestAdapter instead", "0.6.22") +object ScalaJSTask diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TaskAdapter.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TaskAdapter.scala new file mode 100644 index 0000000000..b67735e542 --- /dev/null +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TaskAdapter.scala @@ -0,0 +1,55 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js test adapter ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package org.scalajs.testadapter + +import scala.concurrent.Await +import scala.concurrent.duration.Duration + +import org.scalajs.testcommon._ + +import sbt.testing._ + +private[testadapter] final class TaskAdapter(taskInfo: TaskInfo, runID: RunMux.RunID, + runnerGetter: () => RunMuxRPC) extends Task { + + def taskDef: TaskDef = taskInfo.taskDef + def tags: Array[String] = taskInfo.tags.toArray + + def execute(handler: EventHandler, loggers: Array[Logger]): Array[Task] = { + val runner = runnerGetter() + + def log[T](level: Logger => (T => Unit))(log: LogElement[T]) = + level(loggers(log.index))(log.x) + + runner.attach(JVMEndpoints.event, runID)(handler.handle _) + runner.attach(JVMEndpoints.logError, runID)(log(_.error)) + runner.attach(JVMEndpoints.logWarn, runID)(log(_.warn)) + runner.attach(JVMEndpoints.logInfo, runID)(log(_.info)) + runner.attach(JVMEndpoints.logDebug, runID)(log(_.debug)) + runner.attach(JVMEndpoints.logTrace, runID)(log(_.trace)) + + try { + val colorSupport = loggers.map(_.ansiCodesSupported).toList + val req = new ExecuteRequest(taskInfo, colorSupport) + + runner.call(JSEndpoints.execute, runID)(req) + .await() + .map(new TaskAdapter(_, runID, runnerGetter)) + .toArray + } finally { + runner.detach(JVMEndpoints.event, runID) + runner.detach(JVMEndpoints.logError, runID) + runner.detach(JVMEndpoints.logWarn, runID) + runner.detach(JVMEndpoints.logInfo, runID) + runner.detach(JVMEndpoints.logDebug, runID) + runner.detach(JVMEndpoints.logTrace, runID) + } + } +} diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TestAdapter.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TestAdapter.scala new file mode 100644 index 0000000000..6056fc4674 --- /dev/null +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TestAdapter.scala @@ -0,0 +1,191 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js test adapter ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package org.scalajs.testadapter + +import scala.concurrent._ +import scala.concurrent.duration._ +import scala.concurrent.ExecutionContext.Implicits.global +import scala.collection.concurrent.TrieMap + +import java.util.concurrent.atomic.{AtomicInteger, AtomicBoolean} + +import org.scalajs.core.ir.Utils.escapeJS +import org.scalajs.core.tools.io._ +import org.scalajs.core.tools.logging._ +import org.scalajs.core.tools.linker.ModuleKind + +import org.scalajs.jsenv._ +import org.scalajs.testcommon._ + +import sbt.testing.Framework + +final class TestAdapter(jsEnv: ComJSEnv, config: TestAdapter.Config) { + + import TestAdapter.ManagedRunner + + /** Map of ThreadId -> ManagedRunner */ + private[this] val runners = TrieMap.empty[Long, ManagedRunner] + + private[this] val closing = new AtomicBoolean(false) + + private[this] val nextRunID = new AtomicInteger(0) + private[this] val runs = TrieMap.empty[RunMux.RunID, Unit] + + /** Creates an `sbt.testing.Framework` for each framework that can be found. + * + * The returned Frameworks bind to this TestAdapter and are only valid until + * [[close]] is called. + */ + def loadFrameworks(frameworkNames: List[List[String]]): List[Option[Framework]] = { + val runner = getRunnerForThread() + + val frameworks = runner.com + .call(JSEndpoints.detectFrameworks)(frameworkNames) + .map(_.map(_.map(info => new FrameworkAdapter(info, this)))) + + // If there is no testing framework loaded, nothing will reply. + val fallback: Future[List[Option[Framework]]] = + runner.runner.future.map(_ => frameworkNames.map(_ => None)) + + Future.firstCompletedOf(List(frameworks, fallback)).await() + } + + /** Releases all resources. All associated runs must be done. */ + def close(): Unit = { + if (!closing.getAndSet(true)) { + // Snapshot runs. + val seenRuns = runs.keySet + + runners.values.foreach(_.com.close()) + runners.values.foreach(_.runner.stop()) + runners.clear() + + runs.clear() + if (seenRuns.nonEmpty) { + throw new IllegalStateException( + s"close() called with incomplete runs: $seenRuns") + } + } + } + + private[testadapter] def runStarting(): RunMux.RunID = { + require(!closing.get(), "We are closing. Cannot create new run.") + val runID = nextRunID.getAndIncrement() + runs.put(runID, ()) + runID + } + + /** Called by [[RunnerAdapter]] when the run is completed. */ + private[testadapter] def runDone(runID: RunMux.RunID): Unit = { + val old = runs.remove(runID) + require(old.nonEmpty, s"Tried to remove nonexistent run $runID") + } + + private[testadapter] def getRunnerForThread(): ManagedRunner = { + // Prevent runners from being started after closing started. + // Otherwise we might leak runners. + require(!closing.get(), "We are closing. Cannot create new runner.") + + val threadId = Thread.currentThread().getId() + + // Note that this is thread safe, since each thread can only operate on + // the value associated to its thread id. + runners.getOrElseUpdate(threadId, startManagedRunner(threadId)) + } + + private def startManagedRunner(threadId: Long): ManagedRunner = { + // !!! DUPLICATE code with ScalaJSPlugin.makeExportsNamespaceExpr + val orgExpr = config.moduleKind match { + case ModuleKind.NoModule => + "typeof(org) != 'undefined' ? org : {}" + + case ModuleKind.CommonJSModule => + val moduleIdent = config.moduleIdentifier.getOrElse { + throw new IllegalArgumentException( + "The module identifier must be specified for CommonJS modules") + } + s"""require("${escapeJS(moduleIdent)}").org || {}""" + } + + /* #2752: if there is no testing framework at all on the classpath, + * the testing interface will not be there, and therefore the + * `startBridge` function will not exist. We must therefore be + * careful when selecting it. + * If it is not present, we will simply exit; `loadFrameworks` is prepared + * to deal with this case. + */ + val code = s""" + (function() { + "use strict"; + var namespace = $orgExpr; + namespace = namespace.scalajs || {}; + namespace = namespace.testinterface || {}; + namespace = namespace.internal || {}; + var bridge = namespace.startBridge || function() {}; + bridge(); + })(); + """ + + val launcher = new MemVirtualJSFile("startTestBridge.js").withContent(code) + val runner = jsEnv.comRunner(launcher) + runner.start(config.logger, config.console) + new ManagedRunner(threadId, runner) + } +} + +object TestAdapter { + final class Config private ( + val logger: Logger, + val console: JSConsole, + val moduleKind: ModuleKind, + val moduleIdentifier: Option[String] + ) { + private def this() = { + this( + logger = NullLogger, + console = ConsoleJSConsole, + moduleKind = ModuleKind.NoModule, + moduleIdentifier = None + ) + } + + def withLogger(logger: Logger): Config = + copy(logger = logger) + + def withJSConsole(console: JSConsole): Config = + copy(console = console) + + def withModuleSettings(moduleKind: ModuleKind, + moduleIdentifier: Option[String]): Config = { + require((moduleKind == ModuleKind.NoModule) != moduleIdentifier.nonEmpty, + "Need a module identifier with modules") + copy(moduleKind = moduleKind, moduleIdentifier = moduleIdentifier) + } + + private def copy( + logger: Logger = logger, + console: JSConsole = console, + moduleKind: ModuleKind = moduleKind, + moduleIdentifier: Option[String] = moduleIdentifier + ): Config = { + new Config(logger, console, moduleKind, moduleIdentifier) + } + } + + object Config { + def apply(): Config = new Config() + } + + private[testadapter] final class ManagedRunner( + val id: Long, val runner: ComJSRunner) { + val com = new ComJSEnvRPC(runner) + val mux = new RunMuxRPC(com) + } +} diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/package.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/package.scala index bc32e810e5..275ae8afd3 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/package.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/package.scala @@ -9,8 +9,11 @@ package org.scalajs +import scala.concurrent.{Await, Future} import scala.concurrent.duration._ package object testadapter { - private[testadapter] final val VMTermTimeout = 1.minute + private[testadapter] implicit class AwaitFuture[T](val t: Future[T]) extends AnyVal { + def await(): T = Await.result(t, Duration.Inf) + } } diff --git a/test-common/src/main/scala/org/scalajs/testcommon/FrameworkInfo.scala b/test-common/src/main/scala/org/scalajs/testcommon/FrameworkInfo.scala index 3a3775110d..2e8dc645d3 100644 --- a/test-common/src/main/scala/org/scalajs/testcommon/FrameworkInfo.scala +++ b/test-common/src/main/scala/org/scalajs/testcommon/FrameworkInfo.scala @@ -3,17 +3,21 @@ package org.scalajs.testcommon import sbt.testing._ private[scalajs] final class FrameworkInfo( - val name: String, val fingerprints: List[Fingerprint]) + val implName: String, + val displayName: String, + val fingerprints: List[Fingerprint]) private[scalajs] object FrameworkInfo { implicit object FrameworkInfoSerializer extends Serializer[FrameworkInfo] { def serialize(x: FrameworkInfo, out: Serializer.SerializeState): Unit = { - out.write(x.name) + out.write(x.implName) + out.write(x.displayName) out.write(x.fingerprints) } def deserialize(in: Serializer.DeserializeState): FrameworkInfo = { - new FrameworkInfo(in.read[String](), in.read[List[Fingerprint]]()) + new FrameworkInfo(in.read[String](), + in.read[String](), in.read[List[Fingerprint]]()) } } } diff --git a/test-common/src/main/scala/org/scalajs/testcommon/FutureUtil.scala b/test-common/src/main/scala/org/scalajs/testcommon/FutureUtil.scala new file mode 100644 index 0000000000..01eb579769 --- /dev/null +++ b/test-common/src/main/scala/org/scalajs/testcommon/FutureUtil.scala @@ -0,0 +1,19 @@ +package org.scalajs.testcommon + +import scala.util._ +import scala.concurrent._ +import scala.concurrent.ExecutionContext.Implicits.global + +private[scalajs] object FutureUtil { + /** Same as Future.fromTry(x) but works in 2.10 */ + def futureFromTry[T](x: Try[T]): Future[T] = { + val promise = Promise[T] + promise.complete(x) + promise.future + } + + implicit class RichFuture[T](val __self: Future[T]) extends AnyVal { + def liftToTry: Future[Try[T]] = + __self.map(Success(_)).recover(PartialFunction(Failure(_))) + } +} diff --git a/test-common/src/main/scala/org/scalajs/testcommon/JSEndpoints.scala b/test-common/src/main/scala/org/scalajs/testcommon/JSEndpoints.scala new file mode 100644 index 0000000000..ba010ba951 --- /dev/null +++ b/test-common/src/main/scala/org/scalajs/testcommon/JSEndpoints.scala @@ -0,0 +1,29 @@ +package org.scalajs.testcommon + +import sbt.testing.TaskDef + +private[scalajs] object JSEndpoints { + val detectFrameworks: RPCEndpoint.EP[List[List[String]], List[Option[FrameworkInfo]]] = + RPCEndpoint[List[List[String]], List[Option[FrameworkInfo]]](2) + + val createMasterRunner: RPCEndpoint.EP[RunnerArgs, Unit] = + RPCEndpoint[RunnerArgs, Unit](3) + + val createSlaveRunner: RPCEndpoint.EP[RunnerArgs, Unit] = + RPCEndpoint[RunnerArgs, Unit](4) + + val msgSlave: MsgEndpoint.EP[RunMux[String]] = + MsgEndpoint[RunMux[String]](5) + + val msgMaster: MsgEndpoint.EP[RunMux[FrameworkMessage]] = + MsgEndpoint[RunMux[FrameworkMessage]](6) + + val tasks: RPCEndpoint.EP[RunMux[List[TaskDef]], List[TaskInfo]] = + RPCEndpoint[RunMux[List[TaskDef]], List[TaskInfo]](7) + + val execute: RPCEndpoint.EP[RunMux[ExecuteRequest], List[TaskInfo]] = + RPCEndpoint[RunMux[ExecuteRequest], List[TaskInfo]](8) + + val done: RPCEndpoint.EP[RunMux[Unit], String] = + RPCEndpoint[RunMux[Unit], String](9) +} diff --git a/test-common/src/main/scala/org/scalajs/testcommon/JSMasterEndpoints.scala b/test-common/src/main/scala/org/scalajs/testcommon/JSMasterEndpoints.scala deleted file mode 100644 index 1d168702f8..0000000000 --- a/test-common/src/main/scala/org/scalajs/testcommon/JSMasterEndpoints.scala +++ /dev/null @@ -1,16 +0,0 @@ -package org.scalajs.testcommon - -import sbt.testing._ - -private[scalajs] object JSMasterEndpoints { - val newRunner: RPCEndpoint.EP[RunnerArgs, Unit] = - RPCEndpoint[RunnerArgs, Unit](2) - - val runnerDone: RPCEndpoint.EP[Unit, String] = - RPCEndpoint[Unit, String](3) - - val tasks: RPCEndpoint.EP[List[TaskDef], List[TaskInfo]] = - RPCEndpoint[List[TaskDef], List[TaskInfo]](4) - - val msg: MsgEndpoint.EP[FrameworkMessage] = MsgEndpoint[FrameworkMessage](5) -} diff --git a/test-common/src/main/scala/org/scalajs/testcommon/JSSlaveEndpoints.scala b/test-common/src/main/scala/org/scalajs/testcommon/JSSlaveEndpoints.scala deleted file mode 100644 index 774c32e59a..0000000000 --- a/test-common/src/main/scala/org/scalajs/testcommon/JSSlaveEndpoints.scala +++ /dev/null @@ -1,16 +0,0 @@ -package org.scalajs.testcommon - -import sbt.testing._ - -private[scalajs] object JSSlaveEndpoints { - val newRunner: RPCEndpoint.EP[Unit, Unit] = - RPCEndpoint[Unit, Unit](2) - - val execute: RPCEndpoint.EP[ExecuteRequest, List[TaskInfo]] = - RPCEndpoint[ExecuteRequest, List[TaskInfo]](3) - - val stopSlave: RPCEndpoint.EP[Unit, Unit] = - RPCEndpoint[Unit, Unit](4) - - val msg: MsgEndpoint.EP[String] = MsgEndpoint[String](5) -} diff --git a/test-common/src/main/scala/org/scalajs/testcommon/JVMEndpoints.scala b/test-common/src/main/scala/org/scalajs/testcommon/JVMEndpoints.scala new file mode 100644 index 0000000000..c72c18715f --- /dev/null +++ b/test-common/src/main/scala/org/scalajs/testcommon/JVMEndpoints.scala @@ -0,0 +1,27 @@ +package org.scalajs.testcommon + +import sbt.testing.Event + +private[scalajs] object JVMEndpoints { + val msgSlave: MsgEndpoint.EP[RunMux[String]] = MsgEndpoint[RunMux[String]](2) + + val msgMaster: MsgEndpoint.EP[RunMux[FrameworkMessage]] = + MsgEndpoint[RunMux[FrameworkMessage]](3) + + val event: MsgEndpoint.EP[RunMux[Event]] = MsgEndpoint[RunMux[Event]](4) + + val logError: MsgEndpoint.EP[RunMux[LogElement[String]]] = + MsgEndpoint[RunMux[LogElement[String]]](5) + + val logWarn: MsgEndpoint.EP[RunMux[LogElement[String]]] = + MsgEndpoint[RunMux[LogElement[String]]](6) + + val logInfo: MsgEndpoint.EP[RunMux[LogElement[String]]] = + MsgEndpoint[RunMux[LogElement[String]]](7) + + val logDebug: MsgEndpoint.EP[RunMux[LogElement[String]]] = + MsgEndpoint[RunMux[LogElement[String]]](8) + + val logTrace: MsgEndpoint.EP[RunMux[LogElement[Throwable]]] = + MsgEndpoint[RunMux[LogElement[Throwable]]](9) +} diff --git a/test-common/src/main/scala/org/scalajs/testcommon/JVMMasterEndpoints.scala b/test-common/src/main/scala/org/scalajs/testcommon/JVMMasterEndpoints.scala deleted file mode 100644 index d0cb4e65c8..0000000000 --- a/test-common/src/main/scala/org/scalajs/testcommon/JVMMasterEndpoints.scala +++ /dev/null @@ -1,7 +0,0 @@ -package org.scalajs.testcommon - -import sbt.testing._ - -private[scalajs] object JVMMasterEndpoints { - val msg: MsgEndpoint.EP[FrameworkMessage] = MsgEndpoint[FrameworkMessage](2) -} diff --git a/test-common/src/main/scala/org/scalajs/testcommon/JVMSlaveEndpoints.scala b/test-common/src/main/scala/org/scalajs/testcommon/JVMSlaveEndpoints.scala deleted file mode 100644 index a011b4cd70..0000000000 --- a/test-common/src/main/scala/org/scalajs/testcommon/JVMSlaveEndpoints.scala +++ /dev/null @@ -1,24 +0,0 @@ -package org.scalajs.testcommon - -import sbt.testing._ - -private[scalajs] object JVMSlaveEndpoints { - val msg: MsgEndpoint.EP[String] = MsgEndpoint[String](2) - - val event: MsgEndpoint.EP[Event] = MsgEndpoint[Event](3) - - val logError: MsgEndpoint.EP[LogElement[String]] = - MsgEndpoint[LogElement[String]](4) - - val logWarn: MsgEndpoint.EP[LogElement[String]] = - MsgEndpoint[LogElement[String]](5) - - val logInfo: MsgEndpoint.EP[LogElement[String]] = - MsgEndpoint[LogElement[String]](6) - - val logDebug: MsgEndpoint.EP[LogElement[String]] = - MsgEndpoint[LogElement[String]](7) - - val logTrace: MsgEndpoint.EP[LogElement[Throwable]] = - MsgEndpoint[LogElement[Throwable]](8) -} diff --git a/test-common/src/main/scala/org/scalajs/testcommon/RPCCore.scala b/test-common/src/main/scala/org/scalajs/testcommon/RPCCore.scala index b07671c2ea..143b6469fe 100644 --- a/test-common/src/main/scala/org/scalajs/testcommon/RPCCore.scala +++ b/test-common/src/main/scala/org/scalajs/testcommon/RPCCore.scala @@ -11,6 +11,7 @@ import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.atomic.AtomicLong import Serializer.{serialize, deserialize} +import FutureUtil._ private[scalajs] abstract class RPCCore { import RPCCore._ @@ -186,13 +187,6 @@ private[scalajs] abstract class RPCCore { serialize(payload, out) } } - - /** Same as Future.fromTry(x) but works in 2.10 */ - private def futureFromTry[T](x: Try[T]): Future[T] = { - val promise = Promise[T] - promise.complete(x) - promise.future - } } private[scalajs] object RPCCore { diff --git a/test-common/src/main/scala/org/scalajs/testcommon/RunMux.scala b/test-common/src/main/scala/org/scalajs/testcommon/RunMux.scala new file mode 100644 index 0000000000..9cb909c102 --- /dev/null +++ b/test-common/src/main/scala/org/scalajs/testcommon/RunMux.scala @@ -0,0 +1,20 @@ +package org.scalajs.testcommon + +private[scalajs] final class RunMux[+T](val runId: RunMux.RunID, val value: T) + +private[scalajs] object RunMux { + type RunID = Int + + implicit def runMuxSerializer[T: Serializer]: Serializer[RunMux[T]] = { + new Serializer[RunMux[T]] { + def serialize(x: RunMux[T], out: Serializer.SerializeState): Unit = { + out.write(x.runId) + out.write(x.value) + } + + def deserialize(in: Serializer.DeserializeState): RunMux[T] = { + new RunMux(in.read[Int](), in.read[T]()) + } + } + } +} diff --git a/test-common/src/main/scala/org/scalajs/testcommon/RunMuxRPC.scala b/test-common/src/main/scala/org/scalajs/testcommon/RunMuxRPC.scala new file mode 100644 index 0000000000..5f59fdbda1 --- /dev/null +++ b/test-common/src/main/scala/org/scalajs/testcommon/RunMuxRPC.scala @@ -0,0 +1,93 @@ +package org.scalajs.testcommon + +import scala.language.higherKinds + +import scala.collection.mutable +import scala.concurrent.Future +import scala.util.Try + +import java.util.concurrent.ConcurrentHashMap + +import FutureUtil.futureFromTry + +/** Helper above an [[RPCCore]] that allows to multiplex between runs. + * + * Instead of registering/calling a single endpoint, it supports + * registering/calling the same endpoint once per run. + * + * This is useful for functionality that needs to be dispatched to a specific + * runner. + */ +private[scalajs] final class RunMuxRPC(rpc: RPCCore) { + import RunMux.RunID + import RunMuxRPC._ + + /** Multiplexer map. + * + * Access to the outer map needs to synchronized. + * Access to the inner map only needs to be synchronize for writing. + */ + private[this] val mux = mutable.Map.empty[RPCCore.OpCode, ConcurrentHashMap[RunID, _]] + + def call[Req](ep: MuxRPCEndpoint[Req], runId: RunID)(req: Req): Future[ep.Resp] = + rpc.call(ep)(new RunMux(runId, req)) + + def send[Msg](ep: MuxMsgEndpoint[Msg], runId: RunID)(msg: Msg): Unit = + rpc.send(ep)(new RunMux(runId, msg)) + + def attach[Msg](ep: MuxMsgEndpoint[Msg], runId: RunID)(ex: Msg => Unit): Unit = + attachMux(ep.opCode, runId, ex)(rpc.attach(ep)) + + def attach[Req](ep: MuxRPCEndpoint[Req], runId: RunID)(ex: Req => ep.Resp): Unit = + attachAsync(ep, runId)(x => futureFromTry(Try(ex(x)))) + + def attachAsync[Req](ep: MuxRPCEndpoint[Req], runId: RunID)( + ex: Req => Future[ep.Resp]): Unit = { + attachMux(ep.opCode, runId, ex)(rpc.attachAsync(ep)) + } + + private def attachMux[Req, Resp]( + opCode: RPCCore.OpCode, runId: RunID, ex: Req => Resp)( + attach: (RunMux[Req] => Resp) => Unit): Unit = synchronized { + type DispatchMap = ConcurrentHashMap[RunID, Req => Resp] + + def newDispatchMap() = { + val dispatch = new DispatchMap + + attach { r => + Option(dispatch.get(r.runId)).fold { + throw new IllegalArgumentException(s"Unknown run ${r.runId}") + } { f => + f(r.value) + } + } + + dispatch + } + + val dispatch = mux.getOrElseUpdate(opCode, newDispatchMap()) + val old = dispatch.asInstanceOf[DispatchMap].put(runId, ex) + require(old == null, s"Duplicate endpoint for opcode $opCode run $runId") + } + + def detach(ep: Endpoint, runId: RunID): Unit = synchronized { + val opCode = ep.opCode + + val dispatch = mux.getOrElse(opCode, throw new IllegalArgumentException( + s"No endpoint attached for opCode $opCode")) + + val old = dispatch.remove(runId) + require(old != null, s"No endpoint attached for opCode $opCode run $runId") + + if (dispatch.isEmpty) { + rpc.detach(ep) + mux -= opCode + } + } +} + +private[scalajs] object RunMuxRPC { + // Helper types + type MuxRPCEndpoint[T] = RPCEndpoint { type Req = RunMux[T] } + type MuxMsgEndpoint[T] = MsgEndpoint { type Msg = RunMux[T] } +} diff --git a/test-common/src/main/scala/org/scalajs/testcommon/RunnerArgs.scala b/test-common/src/main/scala/org/scalajs/testcommon/RunnerArgs.scala index 6fac5bce6a..8dcb462614 100644 --- a/test-common/src/main/scala/org/scalajs/testcommon/RunnerArgs.scala +++ b/test-common/src/main/scala/org/scalajs/testcommon/RunnerArgs.scala @@ -1,16 +1,23 @@ package org.scalajs.testcommon private[scalajs] final class RunnerArgs( - val args: List[String], val remoteArgs: List[String]) + val runID: RunMux.RunID, + val frameworkImpl: String, + val args: List[String], + val remoteArgs: List[String]) private[scalajs] object RunnerArgs { implicit object RunnerArgsSerializer extends Serializer[RunnerArgs] { def serialize(x: RunnerArgs, out: Serializer.SerializeState): Unit = { + out.write(x.runID) + out.write(x.frameworkImpl) out.write(x.args) out.write(x.remoteArgs) } - def deserialize(in: Serializer.DeserializeState): RunnerArgs = - new RunnerArgs(in.read[List[String]](), in.read[List[String]]()) + def deserialize(in: Serializer.DeserializeState): RunnerArgs = { + new RunnerArgs(in.read[Int](), in.read[String](), + in.read[List[String]](), in.read[List[String]]()) + } } } diff --git a/test-common/src/test/scala/org/scalajs/testcommon/RunMuxRPCTest.scala b/test-common/src/test/scala/org/scalajs/testcommon/RunMuxRPCTest.scala new file mode 100644 index 0000000000..211d40578e --- /dev/null +++ b/test-common/src/test/scala/org/scalajs/testcommon/RunMuxRPCTest.scala @@ -0,0 +1,88 @@ +package org.scalajs.testcommon + +import scala.concurrent._ +import scala.concurrent.duration._ +import scala.concurrent.ExecutionContext.Implicits.global + +import java.util.concurrent.atomic.AtomicInteger + +import org.junit.Test +import org.junit.Assert._ + +class RunMuxRPCTest { + import RPCCoreTest._ + + lazy val baseX: TestRPC = new TestRPC(baseY) + lazy val baseY: TestRPC = new TestRPC(baseX) + + val x: RunMuxRPC = new RunMuxRPC(baseX) + val y: RunMuxRPC = new RunMuxRPC(baseY) + + object eps { + val call: RPCEndpoint.EP[RunMux[Unit], Unit] = RPCEndpoint[RunMux[Unit], Unit](2) + val msg: MsgEndpoint.EP[RunMux[Unit]] = MsgEndpoint[RunMux[Unit]](3) + } + + private def fail(msg: String): Nothing = { + org.junit.Assert.fail(msg) + throw new AssertionError("Shouldn't reach here") + } + + @Test + def muxedCall: Unit = { + val called = Array.fill(10)(false) + + for (i <- called.indices) + x.attach(eps.call, i)(_ => called(i) = true) + + for (i <- called.indices) { + Await.result(y.call(eps.call, i)(()), atMost = 1.second) + val (needTrue, needFalse) = called.splitAt(i + 1) + needTrue.foreach(assertTrue _) + needFalse.foreach(assertFalse _) + } + } + + @Test + def muxedMsg: Unit = { + val got = Array.fill(10)(false) + + for (i <- got.indices) + x.attach(eps.msg, i)(_ => got(i) = true) + + for (i <- got.indices) { + y.send(eps.msg, i)(()) + val (needTrue, needFalse) = got.splitAt(i + 1) + needTrue.foreach(assertTrue _) + needFalse.foreach(assertFalse _) + } + } + + @Test + def badRunId: Unit = { + x.attach(eps.call, 0)(_ => ()) + + try { + Await.result(y.call(eps.call, 1)(()), atMost = 1.second) + fail("Expected exception") + } catch { + case e: RPCCore.RPCException => + val cause = e.getCause() + assertNotNull(s"Did not get cause: $e", cause) + assertEquals("Unknown run 1", cause.getMessage()) + } + } + + @Test + def detach: Unit = { + for (i <- 1 to 10) + x.attach(eps.call, i)(_ => ()) + + for (i <- (1 to 10).reverse) + x.detach(eps.call, i) + + // Attaching now should work again. + baseX.attach(eps.call)(_ => ()) + baseX.detach(eps.call) + } +} diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Bridge.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/Bridge.scala new file mode 100644 index 0000000000..daec33d8db --- /dev/null +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/Bridge.scala @@ -0,0 +1,135 @@ +package org.scalajs.testinterface.internal + +import scala.scalajs.js.annotation._ +import scala.scalajs.reflect.Reflect + +import scala.concurrent.{Future, Promise} + +import scala.util.control.NonFatal +import scala.util.Try + +import org.scalajs.testcommon._ +import org.scalajs.testinterface.ScalaJSClassLoader + +import sbt.testing._ + +private object Bridge { + + private[this] val mux = new RunMuxRPC(JSRPC) + + @JSExportTopLevel("org.scalajs.testinterface.internal.startBridge") + def start(): Unit = { + import JSEndpoints._ + + JSRPC.attach(detectFrameworks)(detectFrameworksFun) + JSRPC.attach(createMasterRunner)(createRunnerFun(isMaster = true)) + JSRPC.attach(createSlaveRunner)(createRunnerFun(isMaster = false)) + } + + private def detectFrameworksFun = { names: List[List[String]] => + FrameworkLoader.detectFrameworkNames(names).map { maybeName => + maybeName.map { name => + val framework = FrameworkLoader.loadFramework(name) + new FrameworkInfo(name, framework.name, framework.fingerprints.toList) + } + } + } + + private def createRunnerFun(isMaster: Boolean) = { args: RunnerArgs => + val framework = FrameworkLoader.loadFramework(args.frameworkImpl) + val loader = new ScalaJSClassLoader( + scala.scalajs.runtime.environmentInfo.exportsNamespace) + + val runID = args.runID + + val runner = { + if (isMaster) { + framework.runner(args.args.toArray, args.remoteArgs.toArray, loader) + } else { + framework.slaveRunner(args.args.toArray, args.remoteArgs.toArray, loader, + mux.send(JVMEndpoints.msgSlave, runID)) + } + } + + mux.attach(JSEndpoints.tasks, runID)(tasksFun(runner)) + mux.attachAsync(JSEndpoints.execute, runID)(executeFun(runID, runner)) + mux.attach(JSEndpoints.done, runID)(doneFun(runID, runner, isMaster)) + + if (isMaster) { + mux.attach(JSEndpoints.msgMaster, runID)(msgMasterFun(runID, runner)) + } else { + mux.attach(JSEndpoints.msgSlave, runID)(runner.receiveMessage _) + } + } + + private def detachRunnerCommands(runID: RunMux.RunID, isMaster: Boolean) = { + mux.detach(JSEndpoints.tasks, runID) + mux.detach(JSEndpoints.execute, runID) + mux.detach(JSEndpoints.done, runID) + + if (isMaster) + mux.detach(JSEndpoints.msgMaster, runID) + else + mux.detach(JSEndpoints.msgSlave, runID) + } + + private def tasksFun(runner: Runner) = { taskDefs: List[TaskDef] => + val tasks = runner.tasks(taskDefs.toArray) + tasks.map(TaskInfoBuilder.detachTask(_, runner)).toList + } + + private def executeFun(runID: RunMux.RunID, runner: Runner) = { req: ExecuteRequest => + val task = TaskInfoBuilder.attachTask(req.taskInfo, runner) + val eventHandler = new RemoteEventHandler(runID) + + val loggers = for { + (withColor, i) <- req.loggerColorSupport.zipWithIndex + } yield new RemoteLogger(runID, i, withColor) + + val promise = Promise[List[TaskInfo]] + + def cont(tasks: Array[Task]) = { + val result = Try(tasks.map(TaskInfoBuilder.detachTask(_, runner)).toList) + promise.complete(result) + } + + try { + task.execute(eventHandler, loggers.toArray, cont) + } catch { + case NonFatal(t) => + promise.tryFailure(t) + } + + promise.future + } + + private def doneFun(runID: RunMux.RunID, runner: Runner, isMaster: Boolean) = { _: Unit => + try runner.done() + finally detachRunnerCommands(runID, isMaster) + } + + private def msgMasterFun(runID: RunMux.RunID, runner: Runner) = { msg: FrameworkMessage => + for (reply <- runner.receiveMessage(msg.msg)) { + val fm = new FrameworkMessage(msg.slaveId, reply) + mux.send(JVMEndpoints.msgMaster, runID)(fm) + } + } + + private class RemoteEventHandler(runID: RunMux.RunID) extends EventHandler { + def handle(event: Event): Unit = mux.send(JVMEndpoints.event, runID)(event) + } + + private class RemoteLogger(runID: RunMux.RunID, index: Int, + val ansiCodesSupported: Boolean) extends Logger { + + import JVMEndpoints._ + + private def l[T](x: T) = new LogElement(index, x) + + def error(msg: String): Unit = mux.send(logError, runID)(l(msg)) + def warn(msg: String): Unit = mux.send(logWarn, runID)(l(msg)) + def info(msg: String): Unit = mux.send(logInfo, runID)(l(msg)) + def debug(msg: String): Unit = mux.send(logDebug, runID)(l(msg)) + def trace(t: Throwable): Unit = mux.send(logTrace, runID)(l(t)) + } +} diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Com.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/Com.scala deleted file mode 100644 index c0ed78c634..0000000000 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Com.scala +++ /dev/null @@ -1,12 +0,0 @@ -package org.scalajs.testinterface.internal - -import scala.scalajs.js -import scala.scalajs.js.annotation._ - -@js.native -@JSGlobal("scalajsCom") -object Com extends js.Object { - def init(onReceive: js.Function1[String, Unit]): Unit = js.native - def send(msg: String): Unit = js.native - def close(): Unit = js.native -} diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkDetector.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkDetector.scala deleted file mode 100644 index f9dfe0c3ec..0000000000 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkDetector.scala +++ /dev/null @@ -1,39 +0,0 @@ -package org.scalajs.testinterface.internal - -import scala.scalajs.js -import scala.scalajs.js.annotation._ -import scala.scalajs.js.JSConverters._ -import scala.scalajs.reflect.Reflect - -private[internal] object FrameworkDetector { - @JSExportTopLevel("org.scalajs.testinterface.internal.detectFrameworks") - def detectFrameworks( - frameworksData: js.Array[js.Array[String]]): js.Array[js.UndefOr[String]] = { - - def frameworkExistsInReflect(name: String): Boolean = { - Reflect.lookupInstantiatableClass(name).exists { clazz => - classOf[sbt.testing.Framework].isAssignableFrom(clazz.runtimeClass) - } - } - - def frameworkExistsInExportsNamespace(name: String): Boolean = { - /* This happens for testing frameworks developed before 0.6.15 that have - * not yet updated to using reflective instantiation, and are still - * using exports. - * Note that here, we have to assume that whatever we find is indeed a - * proper class export for a class extending sbt.testing.Framework. - */ - val exportsNamespace = - scala.scalajs.runtime.environmentInfo.exportsNamespace - name.split('.').foldLeft[js.UndefOr[js.Dynamic]](exportsNamespace) { - (prev, part) => prev.map(_.selectDynamic(part)) - }.isDefined - } - - def frameworkExists(name: String): Boolean = - frameworkExistsInReflect(name) || frameworkExistsInExportsNamespace(name) - - for (frameworkNames <- frameworksData) - yield frameworkNames.find(frameworkExists(_)).orUndefined - } -} diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkLoader.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkLoader.scala index 3ca64d85fb..10e8556bf6 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkLoader.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkLoader.scala @@ -19,4 +19,31 @@ private[internal] object FrameworkLoader { } } + def detectFrameworkNames(names: List[List[String]]): List[Option[String]] = { + def frameworkExistsInReflect(name: String): Boolean = { + Reflect.lookupInstantiatableClass(name).exists { clazz => + classOf[sbt.testing.Framework].isAssignableFrom(clazz.runtimeClass) + } + } + + def frameworkExistsInExportsNamespace(name: String): Boolean = { + /* This happens for testing frameworks developed before 0.6.15 that have + * not yet updated to using reflective instantiation, and are still + * using exports. + * Note that here, we have to assume that whatever we find is indeed a + * proper class export for a class extending sbt.testing.Framework. + */ + val exportsNamespace = + scala.scalajs.runtime.environmentInfo.exportsNamespace + name.split('.').foldLeft[js.UndefOr[js.Dynamic]](exportsNamespace) { + (prev, part) => prev.map(_.selectDynamic(part)) + }.isDefined + } + + def frameworkExists(name: String): Boolean = + frameworkExistsInReflect(name) || frameworkExistsInExportsNamespace(name) + + for (frameworkNames <- names) + yield frameworkNames.find(frameworkExists(_)) + } } diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/InfoSender.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/InfoSender.scala deleted file mode 100644 index 6a3c745613..0000000000 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/InfoSender.scala +++ /dev/null @@ -1,23 +0,0 @@ -package org.scalajs.testinterface.internal - -import scala.scalajs.js.annotation._ - -import java.io._ - -import org.scalajs.testcommon._ - -@JSExportTopLevel("org.scalajs.testinterface.internal.InfoSender") -final class InfoSender(frameworkName: String) { - @JSExport - def initAndSend(): Unit = { - Com.init((_: String) => ()) - sendFrameworkInfo() - Com.close() - } - - private def sendFrameworkInfo(): Unit = { - val framework = FrameworkLoader.loadFramework(frameworkName) - val info = new FrameworkInfo(framework.name, framework.fingerprints.toList) - Com.send(Serializer.serialize(info)) - } -} diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/JSRPC.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/JSRPC.scala index 2c20abc256..c5b2e84537 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/JSRPC.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/JSRPC.scala @@ -17,4 +17,12 @@ private[internal] final object JSRPC extends RPCCore { super.close() Com.close() } + + @js.native + @JSGlobal("scalajsCom") + private object Com extends js.Object { + def init(onReceive: js.Function1[String, Unit]): Unit = js.native + def send(msg: String): Unit = js.native + def close(): Unit = js.native + } } diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Master.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/Master.scala deleted file mode 100644 index eea474d450..0000000000 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Master.scala +++ /dev/null @@ -1,63 +0,0 @@ -package org.scalajs.testinterface.internal - -import scala.scalajs.js -import js.Dynamic.{literal => lit} -import js.annotation._ - -import sbt.testing._ - -import scala.concurrent.Future -import scala.util.Try - -import org.scalajs.testcommon._ -import org.scalajs.testinterface.ScalaJSClassLoader - -@JSExportTopLevel("org.scalajs.testinterface.internal.Master") -final class Master(frameworkName: String) { - - private[this] var runner: Runner = _ - - JSRPC.attach(JSMasterEndpoints.newRunner)(newRunner _) - JSRPC.attach(JSMasterEndpoints.runnerDone)(runnerDone _) - JSRPC.attach(JSMasterEndpoints.tasks)(tasks _) - JSRPC.attach(JSMasterEndpoints.msg)(inboundMessage _) - - // Message handler methods - - private def newRunner(req: RunnerArgs): Unit = { - val framework = FrameworkLoader.loadFramework(frameworkName) - val loader = new ScalaJSClassLoader( - scala.scalajs.runtime.environmentInfo.exportsNamespace) - runner = framework.runner(req.args.toArray, req.remoteArgs.toArray, loader) - } - - private def runnerDone(req: Unit): String = { - ensureRunnerExists() - - try runner.done() - finally runner = null - } - - private def tasks(taskDefs: List[TaskDef]): List[TaskInfo] = { - ensureRunnerExists() - - val tasks = runner.tasks(taskDefs.toArray) - tasks.map(TaskInfoBuilder.detachTask(_, runner)).toList - } - - private def inboundMessage(msg: FrameworkMessage): Unit = { - ensureRunnerExists() - for (reply <- runner.receiveMessage(msg.msg)) { - JSRPC.send(JVMMasterEndpoints.msg)( - new FrameworkMessage(msg.slaveId, reply)) - } - } - - // Utility methods - - private def ensureRunnerExists(): Unit = { - if (runner == null) - throw new IllegalStateException("No runner created") - } - -} diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala deleted file mode 100644 index fbd355af85..0000000000 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala +++ /dev/null @@ -1,116 +0,0 @@ -package org.scalajs.testinterface.internal - -import scala.scalajs.js -import js.annotation._ - -import sbt.testing._ - -import scala.concurrent.{Future, Promise} -import scala.concurrent.duration._ -import scala.concurrent.ExecutionContext.Implicits.global - -import scala.util.control.NonFatal -import scala.util.Try - -import org.scalajs.testcommon._ -import org.scalajs.testinterface.ScalaJSClassLoader - -@JSExportTopLevel("org.scalajs.testinterface.internal.Slave") -final class Slave(frameworkName: String, args: js.Array[String], - remoteArgs: js.Array[String]) { - - private[this] var runner: Runner = _ - - JSRPC.attach(JSSlaveEndpoints.newRunner)(newRunner _) - JSRPC.attachAsync(JSSlaveEndpoints.execute)(execute _) - JSRPC.attach(JSSlaveEndpoints.stopSlave)(stopSlave _) - JSRPC.attach(JSSlaveEndpoints.msg)(receiveMessage _) - - // Message handler methods - - private def newRunner(req: Unit): Unit = { - val framework = FrameworkLoader.loadFramework(frameworkName) - val loader = new ScalaJSClassLoader( - scala.scalajs.runtime.environmentInfo.exportsNamespace) - runner = framework.slaveRunner(args.toArray, remoteArgs.toArray, - loader, JSRPC.send(JVMSlaveEndpoints.msg)) - } - - private def execute(req: ExecuteRequest): Future[List[TaskInfo]] = { - ensureRunnerExists() - - val task = TaskInfoBuilder.attachTask(req.taskInfo, runner) - val eventHandler = new RemoteEventHandler - - val loggers = for { - (withColor, i) <- req.loggerColorSupport.zipWithIndex - } yield new RemoteLogger(i, withColor) - - val promise = Promise[List[TaskInfo]] - - def cont(tasks: Array[Task]) = { - val result = Try(tasks.map(TaskInfoBuilder.detachTask(_, runner)).toList) - eventHandler.invalidate() - loggers.foreach(_.invalidate()) - promise.complete(result) - } - - try { - task.execute(eventHandler, loggers.toArray, cont) - } catch { - case NonFatal(t) => - promise.tryFailure(t) - } - - promise.future - } - - private def stopSlave(req: Unit): Unit = { - ensureRunnerExists() - try runner.done() - finally runner = null - } - - private def receiveMessage(msg: String): Unit = - runner.receiveMessage(msg) - - // Private helper classes - - private abstract class Invalidatable { - private[this] var valid = true - - private[Slave] def invalidate(): Unit = valid = false - - protected def ensureValid(): Unit = - if (!valid) throw new IllegalStateException(s"$this has been invalidated") - } - - private class RemoteEventHandler extends Invalidatable with EventHandler { - def handle(event: Event): Unit = { - ensureValid() - JSRPC.send(JVMSlaveEndpoints.event)(event) - } - } - - private class RemoteLogger(index: Int, - val ansiCodesSupported: Boolean) extends Invalidatable with Logger { - - import JVMSlaveEndpoints._ - - private def l[T](x: T) = new LogElement(index, x) - - def error(msg: String): Unit = JSRPC.send(logError)(l(msg)) - def warn(msg: String): Unit = JSRPC.send(logWarn)(l(msg)) - def info(msg: String): Unit = JSRPC.send(logInfo)(l(msg)) - def debug(msg: String): Unit = JSRPC.send(logDebug)(l(msg)) - def trace(t: Throwable): Unit = JSRPC.send(logTrace)(l(t)) - } - - // Utility methods - - private def ensureRunnerExists(): Unit = { - if (runner == null) - throw new IllegalStateException("No runner created") - } - -} From ecfbaf88068bf6a86ae2b4567607325728521ebb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 11 Nov 2017 15:44:03 +0100 Subject: [PATCH 0533/2665] Fix #2263: Implement `js.Object.properties` in user-space. It is pimped on `js.Object.type` using an implicit class in the companion object of `js.Any`. This removes one more primitive. --- .../org/scalajs/core/compiler/GenJSCode.scala | 7 ------ .../scalajs/core/compiler/JSDefinitions.scala | 1 - .../scalajs/core/compiler/JSPrimitives.scala | 2 -- .../src/main/scala/scala/scalajs/js/Any.scala | 16 ++++++++++++++ .../main/scala/scala/scalajs/js/Object.scala | 22 +++++-------------- 5 files changed, 21 insertions(+), 27 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 6b767aa5e3..88d88713cd 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -4214,13 +4214,6 @@ abstract class GenJSCode extends plugins.PluginComponent // js.typeOf(arg) genAsInstanceOf(js.JSUnaryOp(js.JSUnaryOp.typeof, arg), StringClass.tpe) - - case OBJPROPS => - // js.Object.properties(arg) - genApplyMethod( - genLoadModule(RuntimePackageModule), - Runtime_propertiesOf, - List(arg)) } case List(arg1, arg2) => diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 4afe813e02..4a859a6891 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -86,7 +86,6 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val JSObjectModule = JSObjectClass.companionModule lazy val JSObject_hasProperty = getMemberMethod(JSObjectModule, newTermName("hasProperty")) - lazy val JSObject_properties = getMemberMethod(JSObjectModule, newTermName("properties")) lazy val JSArrayModule = JSArrayClass.companionModule lazy val JSArray_create = getMemberMethod(JSArrayModule, newTermName("apply")) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala index 9e12eecf06..6fa98c2b7f 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala @@ -40,7 +40,6 @@ abstract class JSPrimitives { val TYPEOF = 344 // typeof x val HASPROP = 346 // js.Object.hasProperty(o, p), equiv to `p in o` in JS - val OBJPROPS = 347 // js.Object.properties(o), equiv to `for (p in o)` in JS val JS_NATIVE = 348 // js.native. Marker method. Fails if tried to be emitted. val UNITVAL = 349 // () value, which is undefined @@ -97,7 +96,6 @@ abstract class JSPrimitives { addPrimitive(JSPackage_native, JS_NATIVE) addPrimitive(JSObject_hasProperty, HASPROP) - addPrimitive(JSObject_properties, OBJPROPS) addPrimitive(BoxedUnit_UNIT, UNITVAL) diff --git a/library/src/main/scala/scala/scalajs/js/Any.scala b/library/src/main/scala/scala/scalajs/js/Any.scala index 1005dbec9a..03e4d8be2f 100644 --- a/library/src/main/scala/scala/scalajs/js/Any.scala +++ b/library/src/main/scala/scala/scalajs/js/Any.scala @@ -193,6 +193,22 @@ object Any extends js.LowPrioAnyImplicits { value.asInstanceOf[js.Any] @inline implicit def fromJDouble(value: java.lang.Double): js.Any = value.asInstanceOf[js.Any] + + implicit class ObjectCompanionOps(val __self: js.Object.type) extends AnyVal { + /** Returns the names of all the enumerable properties of the specified + * object `o`, including properties in its prototype chain. + * + * This method returns the same set of names that would be enumerated by + * a for-in loop in JavaScript, but not necessarily in the same order. + * + * If the underlying implementation guarantees an order for for-in loops, + * then this is guaranteed to be consistent with [[js.Object.keys]], in + * the sense that the list returned by [[js.Object.keys]] is a sublist of + * the list returned by this method (not just a subset). + */ + def properties(o: js.Any): js.Array[String] = + scala.scalajs.runtime.propertiesOf(o) + } } sealed trait LowPrioAnyImplicits extends js.LowestPrioAnyImplicits { diff --git a/library/src/main/scala/scala/scalajs/js/Object.scala b/library/src/main/scala/scala/scalajs/js/Object.scala index fb578e005d..fe31e9948b 100644 --- a/library/src/main/scala/scala/scalajs/js/Object.scala +++ b/library/src/main/scala/scala/scalajs/js/Object.scala @@ -39,9 +39,11 @@ class Object extends js.Any { def isPrototypeOf(v: Object): Boolean = js.native /** Tests whether the specified property in an object can be enumerated by a - * call to [[js.Object.properties]], with the exception of properties - * inherited through the prototype chain. If the object does not have the - * specified property, this method returns false. + * call to [[js.Any.ObjectCompanionOps.properties js.Object.properties]], + * with the exception of properties inherited through the prototype chain. + * + * If the object does not have the specified property, this method returns + * false. * * MDN */ @@ -212,18 +214,4 @@ object Object extends js.Object { * MDN */ def keys(o: js.Object): js.Array[String] = js.native - - /** Returns the names of all the enumerable properties of this object, - * including properties in its prototype chain. - * - * This method returns the same set of names that would be enumerated by - * a for-in loop in JavaScript, but not necessarily in the same order. - * - * If the underlying implementation guarantees an order for for-in loops, - * then this is guaranteed to be consistent with [[keys]], in the sense - * that the list returned by [[keys]] is a sublist of the list returned by - * this method (not just a subset). - */ - def properties(o: js.Any): js.Array[String] = - throw new java.lang.Error("stub") } From fd6c3827cc2ea111a3674904f42407a0ca9040d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 11 Nov 2017 16:45:28 +0100 Subject: [PATCH 0534/2665] Move the primitive `js.Object.hasProperty` to `js.special.in`. The main reason is that `js.Object` is a JS type, and JS type should not contain primitives, as the semantics of such primitives is at odds with the more general semantics of JS types. It is also more consistent with `instanceof`, the other alphabetic binary operator of JavaScript. As a nice benefit, we sidestep the issue with the evaluation order of the arguments, and get support for symbols. The method `js.Object.hasProperty` is preserved as a user-defined implicit pimp on `js.Object.type`. --- .../org/scalajs/core/compiler/GenJSCode.scala | 16 +++------------- .../scalajs/core/compiler/JSDefinitions.scala | 4 +--- .../org/scalajs/core/compiler/JSPrimitives.scala | 7 +++---- .../src/main/scala/scala/scalajs/js/Any.scala | 8 ++++++++ .../src/main/scala/scala/scalajs/js/Object.scala | 10 ++-------- .../scala/scala/scalajs/js/special/package.scala | 11 +++++++++++ .../testsuite/jsinterop/JSSymbolTest.scala | 7 +++++++ .../testsuite/jsinterop/MiscInteropTest.scala | 14 ++++++-------- .../testsuite/jsinterop/SpecialTest.scala | 9 +++++++++ 9 files changed, 50 insertions(+), 36 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 88d88713cd..190032d5a5 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -4218,19 +4218,9 @@ abstract class GenJSCode extends plugins.PluginComponent case List(arg1, arg2) => code match { - case HASPROP => - // js.Object.hasProperty(arg1, arg2) - /* Here we have an issue with evaluation order of arg1 and arg2, - * since the obvious translation is `arg2 in arg1`, but then - * arg2 is evaluated before arg1. Since this is not a commonly - * used operator, we don't try to avoid unnecessary temp vars, and - * simply always evaluate arg1 in a temp before doing the `in`. - */ - val temp = freshLocalIdent() - js.Block( - js.VarDef(temp, jstpe.AnyType, mutable = false, arg1), - js.Unbox(js.JSBinaryOp(js.JSBinaryOp.in, arg2, - js.VarRef(temp)(jstpe.AnyType)), 'Z')) + case IN => + // js.special.in(arg1, arg2) + js.Unbox(js.JSBinaryOp(js.JSBinaryOp.in, arg1, arg2), 'Z') case INSTANCEOF => // js.special.instanceof(arg1, arg2) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 4a859a6891..a9091a681f 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -84,9 +84,6 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val JSDynamicLiteral_applyDynamicNamed = getMemberMethod(JSDynamicLiteral, newTermName("applyDynamicNamed")) lazy val JSDynamicLiteral_applyDynamic = getMemberMethod(JSDynamicLiteral, newTermName("applyDynamic")) - lazy val JSObjectModule = JSObjectClass.companionModule - lazy val JSObject_hasProperty = getMemberMethod(JSObjectModule, newTermName("hasProperty")) - lazy val JSArrayModule = JSArrayClass.companionModule lazy val JSArray_create = getMemberMethod(JSArrayModule, newTermName("apply")) @@ -97,6 +94,7 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val JSConstructorTag_materialize = getMemberMethod(JSConstructorTagModule, newTermName("materialize")) lazy val SpecialPackageModule = getPackageObject("scala.scalajs.js.special") + lazy val Special_in = getMemberMethod(SpecialPackageModule, newTermName("in")) lazy val Special_instanceof = getMemberMethod(SpecialPackageModule, newTermName("instanceof")) lazy val Special_delete = getMemberMethod(SpecialPackageModule, newTermName("delete")) lazy val Special_debugger = getMemberMethod(SpecialPackageModule, newTermName("debugger")) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala index 6fa98c2b7f..36a9ddd278 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala @@ -39,14 +39,14 @@ abstract class JSPrimitives { val ARR_CREATE = 337 // js.Array.apply (array literal syntax) val TYPEOF = 344 // typeof x - val HASPROP = 346 // js.Object.hasProperty(o, p), equiv to `p in o` in JS val JS_NATIVE = 348 // js.native. Marker method. Fails if tried to be emitted. val UNITVAL = 349 // () value, which is undefined val CONSTRUCTOROF = 352 // runtime.constructorOf(clazz) - val LINKING_INFO = 354 // $linkingInfo + val LINKING_INFO = 353 // $linkingInfo + val IN = 354 // js.special.in val INSTANCEOF = 355 // js.special.instanceof val DELETE = 356 // js.special.delete val DEBUGGER = 357 // js.special.debugger @@ -95,13 +95,12 @@ abstract class JSPrimitives { addPrimitive(JSPackage_typeOf, TYPEOF) addPrimitive(JSPackage_native, JS_NATIVE) - addPrimitive(JSObject_hasProperty, HASPROP) - addPrimitive(BoxedUnit_UNIT, UNITVAL) addPrimitive(Runtime_constructorOf, CONSTRUCTOROF) addPrimitive(Runtime_linkingInfo, LINKING_INFO) + addPrimitive(Special_in, IN) addPrimitive(Special_instanceof, INSTANCEOF) addPrimitive(Special_delete, DELETE) addPrimitive(Special_debugger, DEBUGGER) diff --git a/library/src/main/scala/scala/scalajs/js/Any.scala b/library/src/main/scala/scala/scalajs/js/Any.scala index 03e4d8be2f..2f33fa7b93 100644 --- a/library/src/main/scala/scala/scalajs/js/Any.scala +++ b/library/src/main/scala/scala/scalajs/js/Any.scala @@ -195,6 +195,14 @@ object Any extends js.LowPrioAnyImplicits { value.asInstanceOf[js.Any] implicit class ObjectCompanionOps(val __self: js.Object.type) extends AnyVal { + /** Tests whether the specified object `o` has a property `p` on itself or + * in its prototype chain. + * + * This method is the equivalent of `p in o` in JavaScript. + */ + def hasProperty(o: js.Object, p: String): Boolean = + js.special.in(p, o) + /** Returns the names of all the enumerable properties of the specified * object `o`, including properties in its prototype chain. * diff --git a/library/src/main/scala/scala/scalajs/js/Object.scala b/library/src/main/scala/scala/scalajs/js/Object.scala index fe31e9948b..985decfa0f 100644 --- a/library/src/main/scala/scala/scalajs/js/Object.scala +++ b/library/src/main/scala/scala/scalajs/js/Object.scala @@ -28,8 +28,8 @@ class Object extends js.Any { /** Tests whether this object has the specified property as a direct property. * - * Unlike [[js.Object.hasProperty]], this method does not check down the - * object's prototype chain. + * Unlike [[js.Any.ObjectCompanionOps.hasProperty js.Object.hasProperty]], + * this method does not check down the object's prototype chain. * * MDN */ @@ -57,12 +57,6 @@ object Object extends js.Object { def apply(): js.Object = js.native def apply(value: scala.Any): js.Object = js.native - /** Tests whether the object has a property on itself or in its prototype - * chain. This method is the equivalent of `p in o` in JavaScript. - */ - def hasProperty(o: js.Object, p: String): Boolean = - throw new java.lang.Error("stub") - /** * The Object.getPrototypeOf() method returns the prototype (i.e. the * internal `Prototype`) of the specified object. diff --git a/library/src/main/scala/scala/scalajs/js/special/package.scala b/library/src/main/scala/scala/scalajs/js/special/package.scala index 06c87be579..26c4fc3ca4 100644 --- a/library/src/main/scala/scala/scalajs/js/special/package.scala +++ b/library/src/main/scala/scala/scalajs/js/special/package.scala @@ -22,6 +22,17 @@ package scala.scalajs.js */ package object special { + /** Tests whether an object has a given enumerable property in its prototype + * chain. + * + * This method is the exact equivalent of `p in o` in JavaScript. + * + * The recommended surface syntax to perform `p in o` is to use + * `js.Object.hasProperty(o, p)`. + */ + def in(p: scala.Any, o: scala.Any): Boolean = + throw new java.lang.Error("stub") + /** Dynamically tests whether a value is an instance of a JavaScript class. * * This method is the exact equivalent of `x instanceof clazz` in diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala index 0cb33c224b..a549283e2f 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala @@ -245,6 +245,13 @@ class JSSymbolTest { iterateIterable(obj)(content += _) assertArrayEquals(Array(532), content.result()) } + + @Test def inOperatorWithSymbols(): Unit = { + val obj = mkObject(sym1 -> "foo") + + assertTrue(js.special.in(sym1, obj)) + assertFalse(js.special.in(sym2, obj)) + } } object JSSymbolTest { diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala index 7b9f397122..2cb9be3f23 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala @@ -109,25 +109,23 @@ class MiscInteropTest { // scala.scalajs.js.Object @Test def should_provide_an_equivalent_to_p_in_o(): Unit = { - import js.Object.{hasProperty => hasProp} - val o = js.Dynamic.literal(foo = 5, bar = "foobar").asInstanceOf[js.Object] - assertTrue(hasProp(o, "foo")) - assertFalse(hasProp(o, "foobar")) - assertTrue(hasProp(o, "toString")) // in prototype + val o = js.Dynamic.literal(foo = 5, bar = "foobar") + assertTrue(js.Object.hasProperty(o, "foo")) + assertFalse(js.Object.hasProperty(o, "foobar")) + assertTrue(js.Object.hasProperty(o, "toString")) // in prototype } @Test def should_respect_evaluation_order_for_hasProperty(): Unit = { - import js.Object.{hasProperty => hasProp} var indicator = 3 def o(): js.Object = { indicator += 4 - js.Dynamic.literal(x = 5).asInstanceOf[js.Object] + js.Dynamic.literal(x = 5) } def p(): String = { indicator *= 2 "x" } - assertTrue(hasProp(o(), p())) + assertTrue(js.Object.hasProperty(o(), p())) assertEquals(14, indicator) } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala index d71ccfa427..c3249b1f43 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala @@ -17,6 +17,15 @@ import org.scalajs.testsuite.utils.AssertThrows._ class SpecialTest { import SpecialTest._ + // scala.scalajs.js.special.in + + @Test def inTest(): Unit = { + val o = js.Dynamic.literal(foo = 5, bar = "foobar") + assertTrue(js.special.in("foo", o)) + assertFalse(js.special.in("foobar", o)) + assertTrue(js.special.in("toString", o)) // in prototype + } + // scala.scalajs.js.special.instanceof @Test def instanceofTest(): Unit = { From 0aa528b150da80cc2b56b83c06a52b6ab9358ded Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 11 Nov 2017 16:59:10 +0100 Subject: [PATCH 0535/2665] Make `js.Array` a Scala object instead of a native JS object. The main reason is that its `apply` method is a primitive, and JS types should not contain primitive methods. Additionally, this opens the door to add more Scala collection-like methods on that object, such as an `empty` method. --- .../src/main/scala/scala/scalajs/js/Array.scala | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/js/Array.scala b/library/src/main/scala/scala/scalajs/js/Array.scala index be2046193c..abb43d52e6 100644 --- a/library/src/main/scala/scala/scalajs/js/Array.scala +++ b/library/src/main/scala/scala/scalajs/js/Array.scala @@ -170,15 +170,17 @@ class Array[A] extends js.Object with js.Iterable[A] { } /** Factory for [[js.Array]] objects. */ -@js.native -@JSGlobal -object Array extends js.Object { - // Do not expose this one - use new js.Array(len) instead - // def apply[A](arrayLength: Int): js.Array[A] = js.native +object Array { + @js.native + @JSGlobal("Array") + private object NativeArray extends js.Object { + def isArray(arg: scala.Any): Boolean = js.native + } /** Creates a new array with the given items. */ def apply[A](items: A*): js.Array[A] = throw new java.lang.Error("stub") /** Returns true if the given value is an array. */ - def isArray(arg: scala.Any): Boolean = js.native + @inline + def isArray(arg: scala.Any): Boolean = NativeArray.isArray(arg) } From 9c1fb6162e21db4151054ee6f836c459db956888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 13 Nov 2017 23:50:21 +0100 Subject: [PATCH 0536/2665] Move the compile-time checks for `js.Dynamic.literal` to `PrepJSInterop`. This allows for better positions of the duplicate key warnings. It will also allow to otherwise implement the methods in user-space in the future, assuming they are correctly optimized via an intrinsic. --- .../org/scalajs/core/compiler/GenJSCode.scala | 45 ++------- .../scalajs/core/compiler/JSDefinitions.scala | 2 + .../core/compiler/JSTreeExtractors.scala | 11 --- .../scalajs/core/compiler/PrepJSInterop.scala | 65 +++++++++++++ .../compiler/test/JSDynamicLiteralTest.scala | 93 +++++++++++-------- 5 files changed, 130 insertions(+), 86 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 190032d5a5..6a0b7aa261 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -4048,34 +4048,17 @@ abstract class GenJSCode extends plugins.PluginComponent * {name1: arg1, name2: arg2, ... } */ - def warnIfDuplicatedKey(keys: List[js.StringLiteral]): Unit = { - val keyNames = keys.map(_.value) - val keyCounts = - keyNames.distinct.map(key => key -> keyNames.count(_ == key)) - val duplicateKeyCounts = keyCounts.filter(1 < _._2) - if (duplicateKeyCounts.nonEmpty) { - reporter.warning(pos, - "Duplicate keys in object literal: " + - duplicateKeyCounts.map { - case (keyName, count) => s""""$keyName" defined $count times""" - }.mkString(", ") + - ". Only the last occurrence is assigned." - ) - } - } - def keyToPropName(key: js.Tree, index: Int): js.PropertyName = key match { case key: js.StringLiteral => key case _ => js.ComputedName(key, "local" + index) } - // Extract first arg to future proof against varargs - extractFirstArg(genArgs) match { + /* Extract the first arg and discard it, since it has been checked by + * the front-end to be a constant string "apply". + */ + extractFirstArg(genArgs)._2 match { // case js.Dynamic.literal("name1" -> ..., nameExpr2 -> ...) - case (js.StringLiteral("apply"), jse.Tuple2List(pairs)) => - warnIfDuplicatedKey(pairs.collect { - case (key: js.StringLiteral, _) => key - }) + case jse.Tuple2List(pairs) => js.JSObjectConstr(pairs.zipWithIndex.map { case ((key, value), index) => (keyToPropName(key, index), value) }) @@ -4085,8 +4068,7 @@ abstract class GenJSCode extends plugins.PluginComponent * possible to write its expansion by hand: * js.Dynamic.literal.applyDynamic("apply")(x: _*) */ - case (js.StringLiteral("apply"), tups) - if tups.exists(_.isInstanceOf[js.JSSpread]) => + case tups if tups.exists(_.isInstanceOf[js.JSSpread]) => // Delegate to a runtime method val tupsArray = tups match { case List(js.JSSpread(tupsArray)) => tupsArray @@ -4098,10 +4080,7 @@ abstract class GenJSCode extends plugins.PluginComponent List(tupsArray)) // case js.Dynamic.literal(x, y) - case (js.StringLiteral("apply"), tups) => - // Check for duplicated explicit keys - warnIfDuplicatedKey(jse.extractLiteralKeysFrom(tups)) - + case tups => // Evaluate all tuples first val tuple2Type = encodeClassType(TupleClass(2)) val evalTuples = tups.map { tup => @@ -4121,16 +4100,6 @@ abstract class GenJSCode extends plugins.PluginComponent }) js.Block(evalTuples :+ result) - - // case where another method is called - case (js.StringLiteral(name), _) if name != "apply" => - reporter.error(pos, - s"js.Dynamic.literal does not have a method named $name") - js.Undefined() - case _ => - reporter.error(pos, - s"js.Dynamic.literal.${tree.symbol.name} may not be called directly") - js.Undefined() } } else if (code == ARR_CREATE) { // js.Array.create(elements: _*) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index a9091a681f..772bed6b20 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -121,6 +121,8 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val WrappedArrayClass = getRequiredClass("scala.scalajs.js.WrappedArray") lazy val WrappedArray_ctor = WrappedArrayClass.primaryConstructor + lazy val Tuple2_apply = getMemberMethod(TupleClass(2).companionModule, nme.apply) + // This is a def, since similar symbols (arrayUpdateMethod, etc.) are in runDefinitions // (rather than definitions) and we weren't sure if it is safe to make this a lazy val def ScalaRunTime_isArray: Symbol = getMemberMethod(ScalaRunTimeModule, newTermName("isArray")).suchThat(_.tpe.params.size == 2) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSTreeExtractors.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSTreeExtractors.scala index 9a574da858..785f6fe3d2 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSTreeExtractors.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSTreeExtractors.scala @@ -22,17 +22,6 @@ object JSTreeExtractors { }) } - /** Extracts the literal strings in "key" position of a sequence of Tuple2. - * - * Non-Tuple2 constructors are silently ignored, as well as non-literal - * keys. - */ - def extractLiteralKeysFrom(exprs: List[Tree]): List[StringLiteral] = { - exprs.collect { - case Tuple2(key: StringLiteral, _) => key - } - } - /** A list of Tuple2, for example used as a list of key/value pairs * (like in a call to applyDynamicNamed). * diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 2d3665953b..117d051548 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -69,6 +69,15 @@ abstract class PrepJSInterop extends plugins.PluginComponent val x = newTermName("x") val Value = newTermName("Value") val Val = newTermName("Val") + + val ArrowAssoc = { + if (scala.util.Properties.versionNumberString.startsWith("2.10.")) + newTermName("any2ArrowAssoc") + else + newTermName("ArrowAssoc") + } + + val MINGT = encode("->") // not defined in nme in 2.10 } private object jstpnme { @@ -364,6 +373,62 @@ abstract class PrepJSInterop extends plugins.PluginComponent } typer.typed(newTree, Mode.FUNmode, tree.tpe) + // Compile-time errors and warnings for js.Dynamic.literal + case Apply(Apply(fun, nameArgs), args) + if fun.symbol == JSDynamicLiteral_applyDynamic || + fun.symbol == JSDynamicLiteral_applyDynamicNamed => + // Check that the first argument list is a constant string "apply" + nameArgs match { + case List(Literal(Constant(s: String))) => + if (s != "apply") { + reporter.error(tree.pos, + s"js.Dynamic.literal does not have a method named $s") + } + case _ => + reporter.error(tree.pos, + s"js.Dynamic.literal.${tree.symbol.name} may not be " + + "called directly") + } + + // Warn for known duplicate property names + val knownPropNames = mutable.Set.empty[String] + for (arg <- args) { + def processPropName(propNameTree: Tree): Unit = { + propNameTree match { + case Literal(Constant(propName: String)) => + if (!knownPropNames.add(propName)) { + val pos = + if (propNameTree.pos.isDefined) propNameTree.pos + else tree.pos // this happens in 2.10 + reporter.warning(pos, + s"""Duplicate property "$propName" shadows a """ + + "previously defined one") + } + case _ => + // ignore + } + } + arg match { + case Apply(fun, List(propNameTree, _)) + if fun.symbol == Tuple2_apply => + processPropName(propNameTree) + case Apply(fun @ TypeApply(Select(receiver, jsnme.MINGT), _), _) + if currentRun.runDefinitions.isArrowAssoc(fun.symbol) => + receiver match { + case Apply(TypeApply(Select(predef, jsnme.ArrowAssoc), _), + List(propNameTree)) + if predef.symbol == PredefModule => + processPropName(propNameTree) + case _ => + // ignore + } + case _ => + // ignore + } + } + + super.transform(tree) + case _ => super.transform(tree) } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSDynamicLiteralTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSDynamicLiteralTest.scala index bf93352cf5..1227fd30f6 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSDynamicLiteralTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSDynamicLiteralTest.scala @@ -103,69 +103,92 @@ class JSDynamicLiteralTest extends DirectTest with TestHelpers { @Test def keyDuplicationWarning: Unit = { + val version = scala.util.Properties.versionNumberString + val hasSuboptimalPositions = version.startsWith("2.10.") + + implicit class MyHasWarnsOps(val code: CompileTests) { + def hasWarnsForByName(expected: String): Unit = { + if (hasSuboptimalPositions) + code.warns() + else + code.hasWarns(expected) + } + } // detects duplicate named keys expr""" lit(a = "1", b = "2", a = "3") - """ hasWarns + """ hasWarnsForByName """ - |newSource1.scala:3: warning: Duplicate keys in object literal: "a" defined 2 times. Only the last occurrence is assigned. + |newSource1.scala:3: warning: Duplicate property "a" shadows a previously defined one | lit(a = "1", b = "2", a = "3") - | ^ + | ^ """ - // detects duplicate named keys (check the arrow indentation) + // detects duplicate named keys expr""" lit(aaa = "1", b = "2", aaa = "3") - """ hasWarns + """ hasWarnsForByName """ - |newSource1.scala:3: warning: Duplicate keys in object literal: "aaa" defined 2 times. Only the last occurrence is assigned. + |newSource1.scala:3: warning: Duplicate property "aaa" shadows a previously defined one | lit(aaa = "1", b = "2", aaa = "3") - | ^ + | ^ """ - // detects duplicate named keys (check the arrow indentation) + // detects duplicate named keys expr""" lit(aaa = "1", bb = "2", bb = "3") - """ hasWarns + """ hasWarnsForByName """ - |newSource1.scala:3: warning: Duplicate keys in object literal: "bb" defined 2 times. Only the last occurrence is assigned. - | lit(aaa = "1", - | ^ + |newSource1.scala:5: warning: Duplicate property "bb" shadows a previously defined one + | bb = "3") + | ^ """ - // detects duplicate named keys (check the arrow indentation) + // detects duplicate named keys expr""" lit(aaa = "1", b = "2", aaa = "3") - """ hasWarns + """ hasWarnsForByName """ - |newSource1.scala:3: warning: Duplicate keys in object literal: "aaa" defined 2 times. Only the last occurrence is assigned. - | lit(aaa = "1", - | ^ + |newSource1.scala:5: warning: Duplicate property "aaa" shadows a previously defined one + | aaa = "3") + | ^ """ // detects triplicated named keys expr""" lit(a = "1", a = "2", a = "3") - """ hasWarns + """ hasWarnsForByName """ - |newSource1.scala:3: warning: Duplicate keys in object literal: "a" defined 3 times. Only the last occurrence is assigned. + |newSource1.scala:3: warning: Duplicate property "a" shadows a previously defined one | lit(a = "1", a = "2", a = "3") - | ^ + | ^ + |newSource1.scala:3: warning: Duplicate property "a" shadows a previously defined one + | lit(a = "1", a = "2", a = "3") + | ^ """ // detects two different duplicates named keys expr""" lit(a = "1", b = "2", a = "3", b = "4", c = "5", c = "6", c = "7") - """ hasWarns + """ hasWarnsForByName """ - |newSource1.scala:3: warning: Duplicate keys in object literal: "a" defined 2 times, "b" defined 2 times, "c" defined 3 times. Only the last occurrence is assigned. + |newSource1.scala:3: warning: Duplicate property "a" shadows a previously defined one | lit(a = "1", b = "2", a = "3", b = "4", c = "5", c = "6", c = "7") - | ^ + | ^ + |newSource1.scala:3: warning: Duplicate property "b" shadows a previously defined one + | lit(a = "1", b = "2", a = "3", b = "4", c = "5", c = "6", c = "7") + | ^ + |newSource1.scala:3: warning: Duplicate property "c" shadows a previously defined one + | lit(a = "1", b = "2", a = "3", b = "4", c = "5", c = "6", c = "7") + | ^ + |newSource1.scala:3: warning: Duplicate property "c" shadows a previously defined one + | lit(a = "1", b = "2", a = "3", b = "4", c = "5", c = "6", c = "7") + | ^ """ // detects duplicate keys when represented with arrows @@ -173,9 +196,9 @@ class JSDynamicLiteralTest extends DirectTest with TestHelpers { lit("a" -> "1", "b" -> "2", "a" -> "3") """ hasWarns """ - |newSource1.scala:3: warning: Duplicate keys in object literal: "a" defined 2 times. Only the last occurrence is assigned. + |newSource1.scala:3: warning: Duplicate property "a" shadows a previously defined one | lit("a" -> "1", "b" -> "2", "a" -> "3") - | ^ + | ^ """ // detects duplicate keys when represented with tuples @@ -183,9 +206,9 @@ class JSDynamicLiteralTest extends DirectTest with TestHelpers { lit(("a", "1"), ("b", "2"), ("a", "3")) """ hasWarns """ - |newSource1.scala:3: warning: Duplicate keys in object literal: "a" defined 2 times. Only the last occurrence is assigned. + |newSource1.scala:3: warning: Duplicate property "a" shadows a previously defined one | lit(("a", "1"), ("b", "2"), ("a", "3")) - | ^ + | ^ """ // detects duplicate keys when represented with mixed tuples and arrows @@ -193,18 +216,16 @@ class JSDynamicLiteralTest extends DirectTest with TestHelpers { lit("a" -> "1", ("b", "2"), ("a", "3")) """ hasWarns """ - |newSource1.scala:3: warning: Duplicate keys in object literal: "a" defined 2 times. Only the last occurrence is assigned. + |newSource1.scala:3: warning: Duplicate property "a" shadows a previously defined one | lit("a" -> "1", ("b", "2"), ("a", "3")) - | ^ + | ^ """ // should not warn if the key is not literal expr""" val a = "x" lit("a" -> "1", a -> "2", a -> "3") - """ hasWarns - """ - """ + """.hasNoWarns // should not warn if the key/value pairs are not literal """ @@ -212,9 +233,7 @@ class JSDynamicLiteralTest extends DirectTest with TestHelpers { val tup = "x" -> lit() def foo = lit(tup, tup) } - """ hasWarns - """ - """ + """.hasNoWarns // should warn only for the literal keys when in // the presence of non literal keys @@ -226,9 +245,9 @@ class JSDynamicLiteralTest extends DirectTest with TestHelpers { } """ hasWarns """ - |newSource1.scala:6: warning: Duplicate keys in object literal: "a" defined 2 times. Only the last occurrence is assigned. + |newSource1.scala:6: warning: Duplicate property "a" shadows a previously defined one | lit("a" -> "2", tup, ("a", "3"), b -> "5", tup, b -> "6") - | ^ + | ^ """ } From dec5c945dd0aabf03bb5d071007d9e21563f8d98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 14 Nov 2017 11:02:05 +0100 Subject: [PATCH 0537/2665] Don't fix #3180: Blacklist run/t3877.scala and run/t6272.scala. Those partests are affected by #3180, which we decided not to fix, given that the root cause in scalac also affects Scala/JVM and produces invalid bytecode in some cases. --- .../scala/tools/partest/scalajs/2.11.0/BlacklistedTests.txt | 4 ++++ .../scala/tools/partest/scalajs/2.11.0/WhitelistedTests.txt | 2 -- .../scala/tools/partest/scalajs/2.11.1/BlacklistedTests.txt | 4 ++++ .../scala/tools/partest/scalajs/2.11.1/WhitelistedTests.txt | 2 -- .../scala/tools/partest/scalajs/2.11.11/BlacklistedTests.txt | 4 ++++ .../scala/tools/partest/scalajs/2.11.11/WhitelistedTests.txt | 2 -- .../scala/tools/partest/scalajs/2.11.2/BlacklistedTests.txt | 4 ++++ .../scala/tools/partest/scalajs/2.11.2/WhitelistedTests.txt | 2 -- .../scala/tools/partest/scalajs/2.11.5/BlacklistedTests.txt | 4 ++++ .../scala/tools/partest/scalajs/2.11.5/WhitelistedTests.txt | 2 -- .../scala/tools/partest/scalajs/2.11.6/BlacklistedTests.txt | 4 ++++ .../scala/tools/partest/scalajs/2.11.6/WhitelistedTests.txt | 2 -- .../scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt | 4 ++++ .../scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt | 2 -- .../scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt | 4 ++++ .../scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt | 2 -- 16 files changed, 32 insertions(+), 16 deletions(-) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/BlacklistedTests.txt index cfd6fc4af6..2b541138b4 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/BlacklistedTests.txt @@ -870,6 +870,10 @@ run/t3493.scala # Using Class.forName run/private-inline.scala +# Suffers from #3180 +run/t3877.scala +run/t6272.scala + ### Incorrect partests ### # Badly uses constract of Console.print (no flush) run/t429.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/WhitelistedTests.txt index 576bf96b5f..94dcbc26c3 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/WhitelistedTests.txt @@ -1025,7 +1025,6 @@ run/t6337a.scala run/exoticnames.scala run/t0936.scala run/runtime-richChar.scala -run/t6272.scala run/t7215.scala run/t1939.scala run/ReverseSeqView.scala @@ -1278,7 +1277,6 @@ run/t0042.scala run/t3050.scala run/t4536.scala run/NestedClasses.scala -run/t3877.scala run/seqlike-kmp.scala run/t5907.scala run/t266.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/BlacklistedTests.txt index 01c1d8b0f4..53b6eeb242 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/BlacklistedTests.txt @@ -878,6 +878,10 @@ run/t3493.scala # Using Class.forName run/private-inline.scala +# Suffers from #3180 +run/t3877.scala +run/t6272.scala + ### Incorrect partests ### # Badly uses constract of Console.print (no flush) run/t429.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/WhitelistedTests.txt index fd45587491..e058d1c199 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/WhitelistedTests.txt @@ -1025,7 +1025,6 @@ run/t6337a.scala run/exoticnames.scala run/t0936.scala run/runtime-richChar.scala -run/t6272.scala run/t7215.scala run/t1939.scala run/ReverseSeqView.scala @@ -1278,7 +1277,6 @@ run/t0042.scala run/t3050.scala run/t4536.scala run/NestedClasses.scala -run/t3877.scala run/seqlike-kmp.scala run/t5907.scala run/t266.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/BlacklistedTests.txt index b941f5e8fe..2c73dd357c 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/BlacklistedTests.txt @@ -988,6 +988,10 @@ run/t3493.scala # Using Class.forName run/private-inline.scala +# Suffers from #3180 +run/t3877.scala +run/t6272.scala + ### Incorrect partests ### # Badly uses constract of Console.print (no flush) run/t429.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/WhitelistedTests.txt index 7e25d4af5e..6623e6ee00 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/WhitelistedTests.txt @@ -1118,7 +1118,6 @@ run/t6337a.scala run/exoticnames.scala run/t0936.scala run/runtime-richChar.scala -run/t6272.scala run/t7215.scala run/t1939.scala run/ReverseSeqView.scala @@ -1368,7 +1367,6 @@ run/t0042.scala run/t3050.scala run/t4536.scala run/NestedClasses.scala -run/t3877.scala run/seqlike-kmp.scala run/t5907.scala run/t266.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/BlacklistedTests.txt index dbc5e1f732..fe690e179b 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/BlacklistedTests.txt @@ -892,6 +892,10 @@ run/t3493.scala # Using Class.forName run/private-inline.scala +# Suffers from #3180 +run/t3877.scala +run/t6272.scala + ### Incorrect partests ### # Badly uses constract of Console.print (no flush) run/t429.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/WhitelistedTests.txt index a2fdef5743..2608983356 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/WhitelistedTests.txt @@ -1025,7 +1025,6 @@ run/t6337a.scala run/exoticnames.scala run/t0936.scala run/runtime-richChar.scala -run/t6272.scala run/t7215.scala run/t1939.scala run/ReverseSeqView.scala @@ -1278,7 +1277,6 @@ run/t0042.scala run/t3050.scala run/t4536.scala run/NestedClasses.scala -run/t3877.scala run/seqlike-kmp.scala run/t5907.scala run/t266.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/BlacklistedTests.txt index 387b5a622d..ce8ee48a61 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/BlacklistedTests.txt @@ -919,6 +919,10 @@ run/t3493.scala # Using Class.forName run/private-inline.scala +# Suffers from #3180 +run/t3877.scala +run/t6272.scala + ### Incorrect partests ### # Badly uses constract of Console.print (no flush) run/t429.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/WhitelistedTests.txt index 08a68a3d82..87ccfd8006 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/WhitelistedTests.txt @@ -1088,7 +1088,6 @@ run/t6337a.scala run/exoticnames.scala run/t0936.scala run/runtime-richChar.scala -run/t6272.scala run/t7215.scala run/t1939.scala run/ReverseSeqView.scala @@ -1338,7 +1337,6 @@ run/t0042.scala run/t3050.scala run/t4536.scala run/NestedClasses.scala -run/t3877.scala run/seqlike-kmp.scala run/t5907.scala run/t266.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/BlacklistedTests.txt index cfa245fc6e..9a1d2ff293 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/BlacklistedTests.txt @@ -921,6 +921,10 @@ run/t3493.scala # Using Class.forName run/private-inline.scala +# Suffers from #3180 +run/t3877.scala +run/t6272.scala + ### Incorrect partests ### # Badly uses constract of Console.print (no flush) run/t429.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/WhitelistedTests.txt index 62cac931f3..30061a4560 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/WhitelistedTests.txt @@ -1100,7 +1100,6 @@ run/t6337a.scala run/exoticnames.scala run/t0936.scala run/runtime-richChar.scala -run/t6272.scala run/t7215.scala run/t1939.scala run/ReverseSeqView.scala @@ -1350,7 +1349,6 @@ run/t0042.scala run/t3050.scala run/t4536.scala run/NestedClasses.scala -run/t3877.scala run/seqlike-kmp.scala run/t5907.scala run/t266.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt index a68e758890..c11845627c 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt @@ -949,6 +949,10 @@ run/t3493.scala # Using Class.forName run/private-inline.scala +# Suffers from #3180 +run/t3877.scala +run/t6272.scala + ### Incorrect partests ### # Badly uses constract of Console.print (no flush) run/t429.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt index 633a87bcea..2a4c9b4069 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt @@ -1119,7 +1119,6 @@ run/t6337a.scala run/exoticnames.scala run/t0936.scala run/runtime-richChar.scala -run/t6272.scala run/t7215.scala run/t1939.scala run/ReverseSeqView.scala @@ -1369,7 +1368,6 @@ run/t0042.scala run/t3050.scala run/t4536.scala run/NestedClasses.scala -run/t3877.scala run/seqlike-kmp.scala run/t5907.scala run/t266.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt index 070ed8ea6c..3b27c63398 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt @@ -966,6 +966,10 @@ run/t3493.scala # Using Class.forName run/private-inline.scala +# Suffers from #3180 +run/t3877.scala +run/t6272.scala + ### Incorrect partests ### # Badly uses constract of Console.print (no flush) run/t429.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt index a8c54466bf..0352fc503c 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt @@ -1118,7 +1118,6 @@ run/t6337a.scala run/exoticnames.scala run/t0936.scala run/runtime-richChar.scala -run/t6272.scala run/t7215.scala run/t1939.scala run/ReverseSeqView.scala @@ -1368,7 +1367,6 @@ run/t0042.scala run/t3050.scala run/t4536.scala run/NestedClasses.scala -run/t3877.scala run/seqlike-kmp.scala run/t5907.scala run/t266.scala From 47d9fa7c6e56b3686b645e1db611c8041a61264b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 14 Nov 2017 11:06:29 +0100 Subject: [PATCH 0538/2665] Enable IR checking in partest. --- partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala index 9ac74d4df0..8e11838a9b 100644 --- a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala +++ b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala @@ -65,6 +65,7 @@ class MainGenericRunner { command.thingToRun, "main", command.arguments)) val linkerConfig = StandardLinker.Config() + .withCheckIR(true) .withSemantics(semantics) .withSourceMap(false) .withOptimizer(optMode != NoOpt) From d0e56ed65d9d762c04f32175e0860d8fc024d1c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 14 Nov 2017 11:18:20 +0100 Subject: [PATCH 0539/2665] Fix #3172: Upgrade to Scala 2.10.7. --- ci/checksizes.sh | 2 +- ci/matrix.xml | 12 ++++++++---- project/Build.scala | 2 +- scripts/assemble-cli.sh | 4 ++-- scripts/publish.sh | 8 ++++---- .../testsuite/compiler/DefaultMethodsTest.scala | 6 ++++++ 6 files changed, 22 insertions(+), 12 deletions(-) diff --git a/ci/checksizes.sh b/ci/checksizes.sh index 63d8ebea80..16817a7d9b 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -17,7 +17,7 @@ case $FULLVER in 2.13.0-M2) VER=2.13.0-M2 ;; - 2.10.3|2.10.4|2.10.5|2.10.6|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7|2.11.8|2.12.0|2.12.1|2.12.2|2.12.3) + 2.10.3|2.10.4|2.10.5|2.10.6|2.10.7|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7|2.11.8|2.12.0|2.12.1|2.12.2|2.12.3) echo "Ignoring checksizes for Scala $FULLVER" exit 0 ;; diff --git a/ci/matrix.xml b/ci/matrix.xml index e7361d793f..276716c955 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -433,15 +433,15 @@ - 2.10.6 + 2.10.7 1.6 - 2.10.6 + 2.10.7 1.7 - 2.10.6 + 2.10.7 1.8 @@ -481,7 +481,7 @@ 1.7 - 2.10.6 + 2.10.7 @@ -511,6 +511,10 @@ 2.10.6 1.8 + + 2.10.7 + 1.8 + 2.11.0 1.8 diff --git a/project/Build.scala b/project/Build.scala index e02a303e79..4f421e07a1 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -65,7 +65,7 @@ object Build { CrossVersion.binaryMapped(v => s"sjs${previousSJSBinaryVersion}_$v") val scalaVersionsUsedForPublishing: Set[String] = - Set("2.10.6", "2.11.11", "2.12.4", "2.13.0-M2") + Set("2.10.7", "2.11.11", "2.12.4", "2.13.0-M2") val newScalaBinaryVersionsInThisRelease: Set[String] = Set() diff --git a/scripts/assemble-cli.sh b/scripts/assemble-cli.sh index 86856f0086..f1f61d3594 100755 --- a/scripts/assemble-cli.sh +++ b/scripts/assemble-cli.sh @@ -12,8 +12,8 @@ fi BINVER=$1 case $BINVER in 2.10) - FULLVERS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6" - BASEVER="2.10.6" + FULLVERS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.10.7" + BASEVER="2.10.7" ;; 2.11) FULLVERS="2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11" diff --git a/scripts/publish.sh b/scripts/publish.sh index 677a4f24ec..4752403097 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -7,10 +7,10 @@ else CMD="echo sbt" fi -FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.12.0 2.12.1 2.12.2 2.12.3 2.12.4 2.13.0-M2" -BIN_VERSIONS="2.10.6 2.11.11 2.12.4 2.13.0-M2" -CLI_VERSIONS="2.10.6 2.11.11 2.12.4" -SBT_VERSION="2.10.6" +FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.10.7 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.12.0 2.12.1 2.12.2 2.12.3 2.12.4 2.13.0-M2" +BIN_VERSIONS="2.10.7 2.11.11 2.12.4 2.13.0-M2" +CLI_VERSIONS="2.10.7 2.11.11 2.12.4" +SBT_VERSION="2.10.7" SBT1_VERSION="2.12.4" SBT1_SBTVERSION="1.0.0" diff --git a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/compiler/DefaultMethodsTest.scala b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/compiler/DefaultMethodsTest.scala index ee922c0402..7e881b21ef 100644 --- a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/compiler/DefaultMethodsTest.scala +++ b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/compiler/DefaultMethodsTest.scala @@ -9,12 +9,18 @@ package org.scalajs.testsuite.compiler import org.junit.Test import org.junit.Assert._ +import org.junit.Assume._ import java.{util => ju} +import org.scalajs.testsuite.utils.Platform._ + class DefaultMethodsTest { @Test def canOverrideDefaultMethod(): Unit = { + assumeFalse("Affected by https://github.com/scala/bug/issues/10609", + executingInJVM && scalaVersion == "2.10.7") + var counter = 0 class SpecialIntComparator extends ju.Comparator[Int] { From e00ec5577b309c32bbce10cd0b9fe21c28a92789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 14 Nov 2017 11:38:26 +0100 Subject: [PATCH 0540/2665] Fix #3173: Upgrade to Scala 2.11.12. --- ci/checksizes.sh | 6 +- ci/matrix.xml | 52 +- .../scalajs/2.11.12/BlacklistedTests.txt | 996 +++++ .../scalajs/2.11.12/BuglistedTests.txt | 7 + .../scalajs/2.11.12/WhitelistedTests.txt | 3188 +++++++++++++++++ .../2.11.12/neg/t6446-additional.check | 31 + .../scalajs/2.11.12/neg/t6446-list.check | 2 + .../scalajs/2.11.12/neg/t6446-missing.check | 31 + .../2.11.12/neg/t6446-show-phases.check | 30 + .../2.11.12/neg/t7494-no-options.check | 32 + .../scalajs/2.11.12/run/Course-2002-01.check | 37 + .../scalajs/2.11.12/run/Course-2002-02.check | 187 + .../scalajs/2.11.12/run/Course-2002-04.check | 64 + .../scalajs/2.11.12/run/Course-2002-08.check | 171 + .../scalajs/2.11.12/run/Course-2002-09.check | 50 + .../scalajs/2.11.12/run/Course-2002-10.check | 46 + .../partest/scalajs/2.11.12/run/Meter.check | 16 + .../scalajs/2.11.12/run/MeterCaseClass.check | 16 + .../partest/scalajs/2.11.12/run/bugs.sem | 1 + .../scalajs/2.11.12/run/caseClassHash.check | 9 + .../partest/scalajs/2.11.12/run/deeps.check | 87 + .../2.11.12/run/delambdafy-specialized.check | 1 + .../scalajs/2.11.12/run/dynamic-anyval.check | 4 + .../scalajs/2.11.12/run/impconvtimes.check | 1 + .../partest/scalajs/2.11.12/run/imports.check | 21 + .../scalajs/2.11.12/run/interpolation.check | 32 + .../2.11.12/run/interpolationMultiline1.check | 26 + .../partest/scalajs/2.11.12/run/issue192.sem | 1 + .../2.11.12/run/macro-bundle-static.check | 6 + .../2.11.12/run/macro-bundle-toplevel.check | 6 + .../run/macro-bundle-whitebox-decl.check | 6 + .../partest/scalajs/2.11.12/run/misc.check | 62 + .../scalajs/2.11.12/run/promotion.check | 4 + .../partest/scalajs/2.11.12/run/runtime.check | 70 + .../scalajs/2.11.12/run/spec-self.check | 2 + .../scalajs/2.11.12/run/structural.check | 37 + .../scalajs/2.11.12/run/t0421-new.check | 3 + .../scalajs/2.11.12/run/t0421-old.check | 3 + .../partest/scalajs/2.11.12/run/t1503.sem | 1 + .../partest/scalajs/2.11.12/run/t3702.check | 2 + .../partest/scalajs/2.11.12/run/t4148.sem | 1 + .../partest/scalajs/2.11.12/run/t4617.check | 1 + .../partest/scalajs/2.11.12/run/t5356.check | 6 + .../partest/scalajs/2.11.12/run/t5552.check | 2 + .../partest/scalajs/2.11.12/run/t5568.check | 9 + .../partest/scalajs/2.11.12/run/t5629b.check | 10 + .../partest/scalajs/2.11.12/run/t5680.check | 3 + .../partest/scalajs/2.11.12/run/t5866.check | 2 + .../partest/scalajs/2.11.12/run/t6102.check | 28 + .../2.11.12/run/t6318_primitives.check | 54 + .../partest/scalajs/2.11.12/run/t6662.check | 1 + .../partest/scalajs/2.11.12/run/t7657.check | 3 + .../partest/scalajs/2.11.12/run/t7763.sem | 1 + .../partest/scalajs/2.11.12/run/t8570a.check | 1 + .../partest/scalajs/2.11.12/run/t8764.check | 5 + .../partest/scalajs/2.11.12/run/t9387b.check | 1 + .../scalajs/2.11.12/run/try-catch-unify.check | 4 + .../2.11.12/run/virtpatmat_switch.check | 7 + .../2.11.12/run/virtpatmat_typetag.check | 10 + project/Build.scala | 4 +- sbt-plugin-test/build.sbt | 2 +- .../referencedCrossProject/build.sbt | 2 +- .../resources/2.11.12/BlacklistedTests.txt | 93 + .../resources/2.11.12/WhitelistedTests.txt | 29 + scripts/assemble-cli.sh | 4 +- scripts/publish.sh | 6 +- .../compiler/DefaultMethodsTest.scala | 2 +- 67 files changed, 5607 insertions(+), 31 deletions(-) create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/BlacklistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/BuglistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/WhitelistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-additional.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-list.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-missing.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-show-phases.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t7494-no-options.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Course-2002-01.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Course-2002-02.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Course-2002-04.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Course-2002-08.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Course-2002-09.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Course-2002-10.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Meter.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/MeterCaseClass.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/bugs.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/caseClassHash.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/deeps.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/delambdafy-specialized.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/dynamic-anyval.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/impconvtimes.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/imports.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/interpolation.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/interpolationMultiline1.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/issue192.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/macro-bundle-static.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/macro-bundle-toplevel.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/macro-bundle-whitebox-decl.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/misc.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/promotion.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/runtime.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/spec-self.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/structural.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t0421-new.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t0421-old.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t1503.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t3702.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t4148.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t4617.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t5356.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t5552.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t5568.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t5629b.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t5680.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t5866.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t6102.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t6318_primitives.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t6662.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t7657.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t7763.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t8570a.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t8764.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t9387b.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/try-catch-unify.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/virtpatmat_switch.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/virtpatmat_typetag.check create mode 100644 scala-test-suite/src/test/resources/2.11.12/BlacklistedTests.txt create mode 100644 scala-test-suite/src/test/resources/2.11.12/WhitelistedTests.txt diff --git a/ci/checksizes.sh b/ci/checksizes.sh index 16817a7d9b..429b3bde85 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -8,7 +8,7 @@ case $FULLVER in 2.10.2) VER=2.10 ;; - 2.11.11) + 2.11.12) VER=2.11 ;; 2.12.4) @@ -17,7 +17,7 @@ case $FULLVER in 2.13.0-M2) VER=2.13.0-M2 ;; - 2.10.3|2.10.4|2.10.5|2.10.6|2.10.7|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7|2.11.8|2.12.0|2.12.1|2.12.2|2.12.3) + 2.10.3|2.10.4|2.10.5|2.10.6|2.10.7|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7|2.11.8|2.11.11|2.12.0|2.12.1|2.12.2|2.12.3) echo "Ignoring checksizes for Scala $FULLVER" exit 0 ;; @@ -42,7 +42,7 @@ case $FULLVER in REVERSI_PREOPT_GZ_EXPECTEDSIZE=71000 REVERSI_OPT_GZ_EXPECTEDSIZE=31000 ;; - 2.11.11) + 2.11.12) REVERSI_PREOPT_EXPECTEDSIZE=529000 REVERSI_OPT_EXPECTEDSIZE=124000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=71000 diff --git a/ci/matrix.xml b/ci/matrix.xml index 276716c955..da0cab46d9 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -264,7 +264,7 @@ SBT_VER_OVERRIDE=$sbt_version_override # Publish Scala.js artifacts locally # Then go into standalone project and test - sbt ++2.11.11 compiler/publishLocal library/publishLocal javalibEx/publishLocal \ + sbt ++2.11.12 compiler/publishLocal library/publishLocal javalibEx/publishLocal \ testInterface/publishLocal stubs/publishLocal \ jUnitPlugin/publishLocal jUnitRuntime/publishLocal && sbt ++$toolsscala ${SBT_VER_OVERRIDE:+^^$SBT_VER_OVERRIDE} \ @@ -315,15 +315,15 @@ 1.8 - 2.11.11 + 2.11.12 1.6 - 2.11.11 + 2.11.12 1.7 - 2.11.11 + 2.11.12 1.8 @@ -342,7 +342,7 @@ testSuite - 2.11.11 + 2.11.12 1.8 testSuite @@ -359,7 +359,7 @@ - 2.11.11 + 2.11.12 1.8 scalaTestSuite @@ -381,7 +381,7 @@ testSuite - 2.11.11 + 2.11.12 1.8 testSuite @@ -398,7 +398,7 @@ - 2.11.11 + 2.11.12 1.8 scalaTestSuite @@ -419,7 +419,7 @@ 1.8 - 2.11.11 + 2.11.12 1.8 @@ -446,11 +446,11 @@ - 2.11.11 + 2.11.12 1.7 - 2.11.11 + 2.11.12 1.8 @@ -466,7 +466,7 @@ - 2.11.11 + 2.11.12 1.7 @@ -547,6 +547,10 @@ 2.11.8 1.8 + + 2.11.11 + 1.8 + 2.12.0 1.8 @@ -576,12 +580,12 @@ testSuite - 2.11.11 + 2.11.12 1.6 testSuite - 2.11.11 + 2.11.12 1.7 testSuite @@ -598,23 +602,23 @@ testSuite - 2.11.11 + 2.11.12 1.6 testSuite - 2.11.11 + 2.11.12 1.7 testSuite - 2.11.11 + 2.11.12 1.7 - 2.11.11 + 2.11.12 1.7 @@ -747,6 +751,18 @@ 2.11.11 1.8 + + 2.11.12 + 1.8 + + + 2.11.12 + 1.8 + + + 2.11.12 + 1.8 + 2.12.0 1.8 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/BlacklistedTests.txt new file mode 100644 index 0000000000..4abda64d47 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/BlacklistedTests.txt @@ -0,0 +1,996 @@ +# +# POS +# + +# Using Jsoup, what's that? +pos/cycle-jsoup.scala + +# Using scala.actors +pos/t533.scala +pos/functions.scala +pos/MailBox.scala + +# Kills our IR serializer, it's an artificially super-deep if/else if +pos/t9181.scala + +# +# NEG +# + +# Screws up, but not really our problem (error: None.get instead of +# phase ordering error) +neg/t7494-multi-right-after +neg/t7494-right-after-before +neg/t7622-multi-followers +neg/t7622-cyclic-dependency + +# Uses some strange macro cross compile mechanism. +neg/macro-incompatible-macro-engine-c.scala + +# Spurious failures +neg/patmatexhaust-huge.scala + +# Uses .java files +neg/t6289 + +# +# RUN +# + +# Relies on the exact toString() representation of Floats/Doubles +run/t2378.scala + +# Uses ClassTags on existentials which are broken in Scala (see #251) +run/valueclasses-classtag-existential.scala + +# Relies on a particular execution speed +run/t5857.scala + +# Using parts of the javalib we don't plan to support + +run/t5018.scala +run/t2417.scala +run/t4813.scala +run/lazy-concurrent.scala +run/t3667.scala +run/t3038d.scala +run/shutdownhooks.scala +run/t5590.scala +run/t3895b.scala +run/t5974.scala +run/hashset.scala +run/t5262.scala +run/serialize-stream.scala +run/sysprops.scala +run/lambda-serialization-gc.scala + +run/t2849.scala +run/t1360.scala +run/t6114.scala +run/t3199b.scala +run/t8690.scala + +run/various-flat-classpath-types.scala + +# Uses java.util.Collections +run/t2250.scala + +# Used java.io.ObjectInputStream +run/t9365.scala +run/t9375.scala + +# Uses java.math.BigDecimal / BigInteger : but failures not due to them +run/hashhash.scala +run/is-valid-num.scala +run/stringinterpolation_macro-run.scala + +# Documented semantic difference on String.split(x: Array[Char]) +run/t0325.scala + +# Using Threads +run/t6969.scala +run/inner-obj-auto.scala +run/predef-cycle.scala +run/synchronized.scala + +# Uses java.security +run/t2318.scala + +# Tries to catch java.lang.StackOverflowError +run/t6154.scala +run/t9841.scala + +# Tries to catch java.lang.OutOfMemoryError +run/t7880.scala + +# Taking too much time, because JavaScript is not as fast as the JVM + +run/t3822.scala +run/collections.scala +run/t3989.scala +run/adding-growing-set.scala +run/t3242.scala +run/hashCodeDistribution.scala +run/t408.scala +run/t6584.scala +run/t6853.scala +run/UnrolledBuffer.scala +run/t6253a.scala +run/t6253b.scala +run/t6253c.scala +run/numbereq.scala +run/t4658.scala + +# Crashes Rhino + +run/bridges.scala +run/patmat-exprs.scala + +# Using partest properties + +run/tailcalls.scala +run/t4294.scala +run/t6331b.scala + +# Using IO + +run/t6488.scala +run/t6988.scala + +# Object{Output|Input}Streams +run/t6935.scala +run/t8188.scala + +# Using System.getProperties + +run/t4426.scala + +# Using Await + +run/t7336.scala +run/t7775.scala +run/future-flatmap-exec-count.scala + +# Using detailed stack trace + +run/t6308.scala + +# Using reflection + +run/t720.scala +run/t6063 + +run/mixin-bridge-methods.scala +run/t5125.scala +run/outertest.scala +run/t6223.scala +run/t5652b +run/elidable-opt.scala +run/nullable-lazyvals.scala +run/t4794.scala +run/t5652 +run/t5652c +run/getClassTest-old.scala +run/t8960.scala +run/t7965.scala +run/t8087.scala +run/t8931.scala +run/delambdafyLambdaClassNames +run/t8445.scala +run/lambda-serialization.scala + +run/reflection-repl-classes.scala +run/t5256e.scala +run/typetags_core.scala +run/reflection-constructormirror-toplevel-badpath.scala +run/t5276_1b.scala +run/reflection-sorted-decls.scala +run/toolbox_typecheck_implicitsdisabled.scala +run/t5418b.scala +run/toolbox_typecheck_macrosdisabled2.scala +run/abstypetags_serialize.scala +run/all-overridden.scala +run/showraw_tree_kinds.scala +run/showraw_tree_types_ids.scala +run/showraw_tree_types_typed.scala +run/showraw_tree_ids.scala +run/showraw_tree_ultimate.scala +run/t5266_2.scala +run/t5274_1.scala +run/t5224.scala +run/reflection-sanitychecks.scala +run/t6086-vanilla.scala +run/t5277_2.scala +run/reflection-methodsymbol-params.scala +run/reflection-valueclasses-standard.scala +run/t5274_2.scala +run/t5423.scala +run/reflection-modulemirror-toplevel-good.scala +run/t5419.scala +run/t5271_3.scala +run/reflection-enclosed-nested-basic.scala +run/reflection-enclosed-nested-nested-basic.scala +run/fail-non-value-types.scala +run/exprs_serialize.scala +run/t5258a.scala +run/typetags_without_scala_reflect_manifest_lookup.scala +run/t4110-new.scala +run/t5273_2b_newpatmat.scala +run/t6277.scala +run/t5335.scala +run/toolbox_typecheck_macrosdisabled.scala +run/reflection-modulemirror-inner-good.scala +run/t5229_2.scala +run/typetags_multi.scala +run/typetags_without_scala_reflect_typetag_manifest_interop.scala +run/reflection-constructormirror-toplevel-good.scala +run/reflection-magicsymbols-invoke.scala +run/t6392b.scala +run/t5229_1.scala +run/reflection-magicsymbols-vanilla.scala +run/t5225_2.scala +run/origins.scala +run/runtimeEval1.scala +run/reflection-implClass.scala +run/reflection-enclosed-nested-inner-basic.scala +run/reflection-fieldmirror-ctorparam.scala +run/t6181.scala +run/reflection-magicsymbols-repl.scala +run/t5272_2_newpatmat.scala +run/t5270.scala +run/t5418a.scala +run/t5276_2b.scala +run/t5256f.scala +run/reflection-enclosed-basic.scala +run/reflection-constructormirror-inner-badpath.scala +run/interop_typetags_are_manifests.scala +run/newTags.scala +run/t5273_1_newpatmat.scala +run/reflection-constructormirror-nested-good.scala +run/t2236-new.scala +run/existentials3-new.scala +run/t6323b.scala +run/t5943a1.scala +run/reflection-fieldmirror-getsetval.scala +run/t5272_1_oldpatmat.scala +run/t5256h.scala +run/t1195-new.scala +run/t5840.scala +run/reflection-methodsymbol-returntype.scala +run/reflection-fieldmirror-accessorsareokay.scala +run/reflection-sorted-members.scala +run/reflection-allmirrors-tostring.scala +run/valueclasses-typetag-existential.scala +run/toolbox_console_reporter.scala +run/reflection-enclosed-inner-inner-basic.scala +run/t5256b.scala +run/bytecodecs.scala +run/elidable.scala +run/freetypes_false_alarm1.scala +run/freetypes_false_alarm2.scala +run/getClassTest-new.scala +run/idempotency-extractors.scala +run/idempotency-case-classes.scala +run/idempotency-this.scala +run/idempotency-labels.scala +run/idempotency-lazy-vals.scala +run/interop_manifests_are_abstypetags.scala +run/interop_manifests_are_typetags.scala +run/abstypetags_core.scala +run/macro-reify-abstypetag-notypeparams +run/macro-reify-abstypetag-typeparams-tags +run/macro-reify-abstypetag-typeparams-notags +run/macro-reify-abstypetag-usetypetag +run/macro-reify-freevars +run/macro-reify-splice-outside-reify +run/macro-reify-tagless-a +run/macro-reify-type +run/macro-reify-typetag-typeparams-tags +run/macro-reify-typetag-notypeparams +run/macro-undetparams-implicitval +run/manifests-new.scala +run/manifests-old.scala +run/no-pickle-skolems +run/position-val-def.scala +run/reflect-priv-ctor.scala +run/primitive-sigs-2-new.scala +run/primitive-sigs-2-old.scala +run/reflection-enclosed-inner-basic.scala +run/reflection-enclosed-inner-nested-basic.scala +run/reflection-constructormirror-inner-good.scala +run/reflection-constructormirror-nested-badpath.scala +run/reflection-fancy-java-classes +run/reflection-fieldsymbol-navigation.scala +run/reflection-fieldmirror-nmelocalsuffixstring.scala +run/reflection-fieldmirror-getsetvar.scala +run/reflection-fieldmirror-privatethis.scala +run/reflection-implicit.scala +run/reflection-mem-glbs.scala +run/reflection-mem-tags.scala +run/reflection-java-annotations +run/reflection-java-crtp +run/reflection-methodsymbol-typeparams.scala +run/reflection-modulemirror-nested-badpath.scala +run/reflection-modulemirror-inner-badpath.scala +run/reflection-modulemirror-nested-good.scala +run/reflection-modulemirror-toplevel-badpath.scala +run/reflection-sync-subtypes.scala +run/reflinit.scala +run/reflection-valueclasses-derived.scala +run/reflection-valueclasses-magic.scala +run/resetattrs-this.scala +run/runtimeEval2.scala +run/showraw_aliases.scala +run/showraw_mods.scala +run/shortClass.scala +run/showraw_nosymbol.scala +run/showraw_tree.scala +run/showraw_tree_types_untyped.scala +run/t1167.scala +run/t2577.scala +run/t2873.scala +run/t2886.scala +run/t2251b.scala +run/t3346j.scala +run/t3507-new.scala +run/t3569.scala +run/t5125b.scala +run/t5225_1.scala +run/t3425b +run/t5256a.scala +run/t5230.scala +run/t5256c.scala +run/t5256g.scala +run/t5266_1.scala +run/t5269.scala +run/t5271_1.scala +run/t5271_2.scala +run/t5271_4.scala +run/t5272_1_newpatmat.scala +run/t5272_2_oldpatmat.scala +run/t5273_1_oldpatmat.scala +run/t5273_2a_newpatmat.scala +run/t5273_2a_oldpatmat.scala +run/t5275.scala +run/t5276_1a.scala +run/t5276_2a.scala +run/t5277_1.scala +run/t5279.scala +run/t5334_1.scala +run/t5334_2.scala +run/t5415.scala +run/t5418.scala +run/t5676.scala +run/t5704.scala +run/t5710-1.scala +run/t5710-2.scala +run/t5770.scala +run/t5894.scala +run/t5816.scala +run/t5824.scala +run/t5912.scala +run/t5942.scala +run/t5943a2.scala +run/t6023.scala +run/t6113.scala +run/t6175.scala +run/t6178.scala +run/t6199-mirror.scala +run/t6199-toolbox.scala +run/t6240-universe-code-gen.scala +run/t6221 +run/t6260b.scala +run/t6259.scala +run/t6287.scala +run/t6344.scala +run/t6392a.scala +run/t6591_1.scala +run/t6591_2.scala +run/t6591_3.scala +run/t6591_5.scala +run/t6591_6.scala +run/t6591_7.scala +run/t6608.scala +run/t6677.scala +run/t6687.scala +run/t6715.scala +run/t6719.scala +run/t6793.scala +run/t6860.scala +run/t6793b.scala +run/t6793c.scala +run/t7045.scala +run/t7046.scala +run/t7008-scala-defined +run/t7120b.scala +run/t7151.scala +run/t7214.scala +run/t7235.scala +run/t7331a.scala +run/t7331b.scala +run/t7331c.scala +run/t7558.scala +run/t7556 +run/t7779.scala +run/t7868b.scala +run/toolbox_current_run_compiles.scala +run/toolbox_default_reporter_is_silent.scala +run/toolbox_expand_macro.scala +run/toolbox_parse_package.scala +run/toolbox_silent_reporter.scala +run/toolbox_typecheck_inferimplicitvalue.scala +run/trait-renaming +run/typetags_serialize.scala +run/valueclasses-typetag-basic.scala +run/WeakHashSetTest.scala +run/valueclasses-typetag-generic.scala +run/t4023.scala +run/t4024.scala +run/t6380.scala +run/t5273_2b_oldpatmat.scala +run/t8104 +run/t8047.scala +run/t6992 +run/var-arity-class-symbol.scala +run/typetags_symbolof_x.scala +run/typecheck +run/t8190.scala +run/t8192 +run/t8177f.scala +run/t8199.scala +run/t7932.scala +run/t7700.scala +run/t7570c.scala +run/t7570b.scala +run/t7533.scala +run/t7570a.scala +run/t7044 +run/t7328.scala +run/t6733.scala +run/t6554.scala +run/t6732.scala +run/t6379 +run/t6411b.scala +run/t6411a.scala +run/t6260c.scala +run/t6260-delambdafy.scala +run/showdecl +run/reflection-sync-potpourri.scala +run/reflection-tags.scala +run/reflection-companiontype.scala +run/reflection-scala-annotations.scala +run/reflection-idtc.scala +run/macro-reify-nested-b2 +run/mixin-signatures.scala +run/reflection-companion.scala +run/macro-reify-nested-b1 +run/macro-reify-nested-a2 +run/macro-reify-nested-a1 +run/macro-reify-chained2 +run/macro-reify-chained1 +run/inferred-type-constructors.scala +run/mirror_symbolof_x.scala +run/t8196.scala +run/t8549b.scala +run/t8574.scala +run/t8549.scala +run/t8637.scala +run/t8253.scala +run/t9027.scala +run/t6622.scala +run/toolbox-varargs +run/t9252.scala +run/t9182.scala +run/t9102.scala +run/t9388-bin-compat.scala + +run/reify_newimpl_29.scala +run/reify_magicsymbols.scala +run/reify_inheritance.scala +run/reify_newimpl_12.scala +run/reify_typerefs_2b.scala +run/reify_csv.scala +run/reify_inner2.scala +run/reify_maps_oldpatmat.scala +run/reify_newimpl_43.scala +run/reify_nested_inner_refers_to_local.scala +run/reify_closure7.scala +run/reify_closure8b.scala +run/reify_typerefs_3b.scala +run/reify_newimpl_44.scala +run/reify_newimpl_06.scala +run/reify_newimpl_05.scala +run/reify_newimpl_20.scala +run/reify_newimpl_23.scala +run/reify_metalevel_breach_-1_refers_to_1.scala +run/reify_newimpl_41.scala +run/reify-repl-fail-gracefully.scala +run/reify_fors_oldpatmat.scala +run/reify_inner3.scala +run/reify_closure8a.scala +run/reify_closures10.scala +run/reify_ann2a.scala +run/reify_newimpl_51.scala +run/reify_newimpl_47.scala +run/reify_extendbuiltins.scala +run/reify_newimpl_30.scala +run/reify_newimpl_38.scala +run/reify_closure2a.scala +run/reify_newimpl_45.scala +run/reify_closure1.scala +run/reify_generic2.scala +run/reify_printf.scala +run/reify_closure6.scala +run/reify_newimpl_37.scala +run/reify_newimpl_35.scala +run/reify_typerefs_3a.scala +run/reify_newimpl_25.scala +run/reify_ann4.scala +run/reify_typerefs_1b.scala +run/reify_newimpl_22.scala +run/reify_this.scala +run/reify_typerefs_2a.scala +run/reify_newimpl_03.scala +run/reify_newimpl_48.scala +run/reify_varargs.scala +run/reify_newimpl_42.scala +run/reify_newimpl_15.scala +run/reify_nested_inner_refers_to_global.scala +run/reify_newimpl_02.scala +run/reify_newimpl_01.scala +run/reify_fors_newpatmat.scala +run/reify_classfileann_a.scala +run/reify_nested_outer_refers_to_local.scala +run/reify_newimpl_13.scala +run/reify_closure5a.scala +run/reify_inner4.scala +run/reify_sort.scala +run/reify_ann1a.scala +run/reify_classfileann_b.scala +run/reify_closure4a.scala +run/reify_newimpl_33.scala +run/reify_sort1.scala +run/reify_properties.scala +run/reify_generic.scala +run/reify_newimpl_27.scala +run/reify-aliases.scala +run/reify_ann3.scala +run/reify-staticXXX.scala +run/reify_ann1b.scala +run/reify_ann5.scala +run/reify_anonymous.scala +run/reify-each-node-type.scala +run/reify_copypaste2.scala +run/reify_closure3a.scala +run/reify_copypaste1.scala +run/reify_complex.scala +run/reify_for1.scala +run/reify_getter.scala +run/reify_implicits-new.scala +run/reify_inner1.scala +run/reify_implicits-old.scala +run/reify_lazyunit.scala +run/reify_lazyevaluation.scala +run/reify_maps_newpatmat.scala +run/reify_metalevel_breach_+0_refers_to_1.scala +run/reify_metalevel_breach_-1_refers_to_0_a.scala +run/reify_metalevel_breach_-1_refers_to_0_b.scala +run/reify_nested_outer_refers_to_global.scala +run/reify_newimpl_04.scala +run/reify_newimpl_14.scala +run/reify_newimpl_11.scala +run/reify_newimpl_18.scala +run/reify_newimpl_19.scala +run/reify_newimpl_31.scala +run/reify_newimpl_21.scala +run/reify_newimpl_36.scala +run/reify_newimpl_39.scala +run/reify_newimpl_40.scala +run/reify_newimpl_49.scala +run/reify_newimpl_50.scala +run/reify_newimpl_52.scala +run/reify_renamed_term_basic.scala +run/reify_renamed_term_local_to_reifee.scala +run/reify_renamed_term_overloaded_method.scala +run/reify_renamed_type_basic.scala +run/reify_renamed_type_local_to_reifee.scala +run/reify_renamed_type_spliceable.scala +run/reify_typerefs_1a.scala +run/reify_timeofday.scala +run/reify_renamed_term_t5841.scala + +run/inferred-type-constructors-hou.scala + +# Uses refletction indirectly through +# scala.runtime.ScalaRunTime.replStringOf +run/t6634.scala + +# Using reflection to invoke macros. These tests actually don't require +# or test reflection, but use it to separate compilation units nicely. +# It's a pity we cannot use them + +run/macro-abort-fresh +run/macro-expand-varargs-explicit-over-nonvarargs-bad +run/macro-invalidret-doesnt-conform-to-def-rettype +run/macro-invalidret-nontypeable +run/macro-invalidusage-badret +run/macro-invalidusage-partialapplication +run/macro-invalidusage-partialapplication-with-tparams +run/macro-reflective-ma-normal-mdmi +run/macro-reflective-mamd-normal-mi + +# Using macros, but indirectly creating calls to reflection +run/macro-reify-unreify + +# Using Enumeration in a way we cannot fix + +run/enums.scala +run/t3719.scala +run/t8611b.scala + +# Exceptions that become JavaScriptException + +run/pf-catch.scala +run/exceptions-2.scala +run/exceptions-nest.scala +run/t8601c.scala +run/t8601b.scala + +# Expecting unsupported exceptions (e.g. ArrayIndexOutOfBounds) +run/optimizer-array-load.scala +run/t8601.scala + +# Playing with classfile format + +run/classfile-format-51.scala +run/classfile-format-52.scala + +# Concurrent collections (TrieMap) +# has too much stuff implemented in *.java, so no support +run/triemap-hash.scala + +# Using parallel collections + +run/t5375.scala +run/t4894.scala +run/ctries-new +run/collection-conversions.scala +run/concurrent-map-conversions.scala +run/t4761.scala +run/concurrent-stream.scala +run/t7498.scala +run/t6448.scala +run/ctries-old +run/map_java_conversions.scala +run/parmap-ops.scala +run/pc-conversions.scala +run/t4459.scala +run/t4608.scala +run/t4723.scala +run/t4895.scala +run/t6052.scala +run/t6410.scala +run/t6467.scala +run/t6908.scala + +# Using scala.xml + +run/t4124.scala + +# Using Swing + +run/t3613.scala + +# Using the REPL + +run/t4285.scala +run/constant-type.scala +run/repl-bare-expr.scala +run/repl-parens.scala +run/repl-assign.scala +run/t5583.scala +run/treePrint.scala +run/constrained-types.scala +run/repl-power.scala +run/t4710.scala +run/repl-paste.scala +run/repl-reset.scala +run/repl-paste-3.scala +run/t6329_repl.scala +run/t6273.scala +run/repl-paste-2.scala +run/t5655.scala +run/t5072.scala +run/repl-colon-type.scala +run/kind-repl-command.scala +run/repl-trim-stack-trace.scala +run/t4594-repl-settings.scala +run/repl-save.scala +run/repl-paste-raw.scala +run/repl-paste-4.scala +run/repl-paste-5.scala +run/t7801.scala +run/repl-backticks.scala +run/t6633.scala + +# Using the Repl (scala.tools.partest.ReplTest) +run/class-symbol-contravariant.scala +run/lub-visibility.scala +run/macro-bundle-repl.scala +run/macro-repl-basic.scala +run/macro-repl-dontexpand.scala +run/macro-system-properties.scala +run/reflection-equality.scala +run/reflection-repl-elementary.scala +run/reify_newimpl_26.scala +run/repl-javap-app.scala +run/repl-out-dir.scala +run/repl-term-macros.scala +run/repl-transcript.scala +run/repl-type-verbose.scala +run/t3376.scala +run/t4025.scala +run/t4172.scala +run/t4216.scala +run/t4542.scala +run/t4671.scala +run/t5256d.scala +run/t5535.scala +run/t5537.scala +run/t5789.scala +run/t6086-repl.scala +run/t6146b.scala +run/t6187.scala +run/t6320.scala +run/t6381.scala +run/t6434.scala +run/t6439.scala +run/t6507.scala +run/t6549.scala +run/t6937.scala +run/t7185.scala +run/t7319.scala +run/t7482a.scala +run/t7634.scala +run/t7747-repl.scala +run/t7805-repl-i.scala +run/tpeCache-tyconCache.scala +run/repl-empty-package +run/repl-javap-def.scala +run/repl-javap-fun.scala +run/repl-javap-mem.scala +run/repl-javap-memfun.scala +run/repl-javap-more-fun.scala +run/repl-javap-outdir +run/repl-javap.scala +run/repl-javap-outdir-funs +run/t6329_repl_bug.scala +run/t4950.scala +run/xMigration.scala +run/t6541-option.scala +run/repl-serialization.scala +run/repl-paste-6.scala +run/repl-no-uescape.scala +run/repl-classbased.scala +run/repl-paste-parse.scala + +# Using Scala Script (partest.ScriptTest) + +run/t7711-script-args.scala +run/t4625.scala +run/t4625b.scala +run/t4625c.scala + +# Using the compiler API + +run/t2512.scala +run/analyzerPlugins.scala +run/test-cpp.scala +run/compiler-asSeenFrom.scala +run/t5603.scala +run/t6440.scala +run/t5545.scala +run/existentials-in-compiler.scala +run/global-showdef.scala +run/inline-ex-handlers.scala +run/stream_length.scala +run/annotatedRetyping.scala +run/imain.scala +run/existential-rangepos.scala +run/delambdafy_uncurry_byname_inline.scala +run/delambdafy_uncurry_byname_method.scala +run/delambdafy_uncurry_inline.scala +run/delambdafy_t6555.scala +run/delambdafy_uncurry_method.scala +run/delambdafy_t6028.scala +run/memberpos.scala +run/programmatic-main.scala +run/reflection-names.scala +run/settings-parse.scala +run/sm-interpolator.scala +run/t1501.scala +run/t1500.scala +run/sammy_java8.scala +run/t1618.scala +run/t2464 +run/t4072.scala +run/t5064.scala +run/t5313.scala +run/t5385.scala +run/t5699.scala +run/t5717.scala +run/t5940.scala +run/t6028.scala +run/t6194.scala +run/t6288b-jump-position.scala +run/t6669.scala +run/t6745-2.scala +run/t6955.scala +run/t6956.scala +run/t7096.scala +run/t7271.scala +run/t7337.scala +run/t7398.scala +run/t7569.scala +run/t7852.scala +run/t7817-tree-gen.scala +run/t7825.scala + +# partest.ParserTest +run/t3368.scala +run/t3368-b.scala +run/t3368-c.scala +run/t3368-d.scala + +# partest.DirectTest +run/t6288.scala +run/t6331.scala +run/t6440b.scala +run/t6555.scala +run/t7876.scala +run/typetags_without_scala_reflect_typetag_lookup.scala +run/dynamic-updateDynamic.scala +run/dynamic-selectDynamic.scala +run/dynamic-applyDynamic.scala +run/dynamic-applyDynamicNamed.scala +run/t4841-isolate-plugins +run/large_code.scala +run/macroPlugins-namerHooks.scala +run/t4287inferredMethodTypes.scala +run/t4841-no-plugin.scala +run/t4332.scala +run/t8029.scala +run/t8046 +run/t5905-features.scala +run/t5905b-features.scala +run/large_class.scala +run/t8708_b +run/icode-reader-dead-code.scala +run/t5938.scala +run/t8502.scala +run/t6502.scala +run/t8907.scala +run/t9097.scala +run/macroPlugins-enterStats.scala +run/sbt-icode-interface.scala + +# Using partest.StoreReporterDirectTest +run/t8502b.scala + +# partest.StubErrorMessageTest +run/StubErrorBInheritsFromA.scala +run/StubErrorComplexInnerClass.scala +run/StubErrorHK.scala +run/StubErrorReturnTypeFunction.scala +run/StubErrorReturnTypeFunction2.scala +run/StubErrorReturnTypePolyFunction.scala +run/StubErrorSubclasses.scala +run/StubErrorTypeclass.scala +run/StubErrorTypeDef.scala + +# partest.CompilerTest +run/t8852a.scala + +# partest.BytecodeTest +run/t6546 +run/t7106 +run/t7974 +run/t8601-closure-elim.scala +run/t4788 +run/t4788-separate-compilation +run/t9403 + +# partest.SessionTest +run/t1931.scala +run/t8843-repl-xlat.scala +run/t9206.scala +run/t9170.scala + +# partest.JavapTest +run/t8608-no-format.scala +run/repl-javap-lambdas.scala + +# Using .java source files + +run/t4317 +run/t4238 +run/t2296c +run/t4119 +run/t4283 +run/t4891 +run/t6168 +run/t6168b +run/t6240a +run/t6240b +run/t6548 +run/t6989 +run/t7008 +run/t7246 +run/t7246b +run/t7359 +run/t7439 +run/t7455 +run/t7510 +run/t7582-private-within +run/t7582 +run/t7582b +run/t3897 +run/t7374 +run/t3452e +run/t3452g +run/t3452d +run/t3452b-bcode +run/t3452b +run/t3452a +run/t1430 +run/t4729 +run/t8442 +run/t8601e +run/t9298 +run/t9298b +run/t9359 +run/t7741a +run/t7741b +run/bcodeInlinerMixed +run/t9268 +run/t1459 +run/t1459generic +run/t3236 +run/t9013 +run/sd304 + +# Using scalap +run/scalapInvokedynamic.scala + +# Using scala-script +run/t7791-script-linenums.scala + +# Suffers from bug in Node.js (https://github.com/joyent/node/issues/7528) +run/range-unit.scala + +# Using Manifests (which use Class.getInterfaces) +run/valueclasses-manifest-existential.scala +run/existentials3-old.scala +run/t2236-old.scala +run/interop_manifests_are_classtags.scala +run/valueclasses-manifest-generic.scala +run/valueclasses-manifest-basic.scala +run/t1195-old.scala +run/t3758-old.scala +run/t4110-old.scala +run/t6246.scala + +# Using ScalaRunTime.stringOf +run/value-class-extractor-seq.scala +run/t3493.scala + +# Using Class.forName +run/private-inline.scala + +# Suffers from #3180 +run/t3877.scala +run/t6272.scala + +### Incorrect partests ### +# Badly uses constract of Console.print (no flush) +run/t429.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/BuglistedTests.txt new file mode 100644 index 0000000000..273cb2c2d4 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/BuglistedTests.txt @@ -0,0 +1,7 @@ +# The tests in this file should pass but have never passed so far +# use scala.tools.partest.scalajs.testunknownonly to only run tests +# which are neither in BuglistedTests.txt, WhitelistedTests.txt or +# BlacklistedTests.txt + +# Broken by GCC, filed as #2815 +run/Predef.readLine.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/WhitelistedTests.txt new file mode 100644 index 0000000000..6623e6ee00 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/WhitelistedTests.txt @@ -0,0 +1,3188 @@ +pos/spec-super.scala +pos/t1035.scala +pos/t5897.scala +pos/irrefutable.scala +pos/spec-partialmap.scala +pos/tcpoly_seq.scala +pos/partialfun.scala +pos/t2795-new.scala +pos/clsrefine.scala +pos/t0774 +pos/t1070.scala +pos/t5957 +pos/looping-jsig.scala +pos/t3274.scala +pos/spec-fields-old.scala +pos/t262.scala +pos/t7486.scala +pos/t2261.scala +pos/t6600.scala +pos/t4786.scala +pos/t5406.scala +pos/tcpoly_late_method_params.scala +pos/t2726 +pos/pos-bug1210.scala +pos/t3312.scala +pos/manifest1-old.scala +pos/gadt-gilles.scala +pos/t4842.scala +pos/ted.scala +pos/NoCyclicReference.scala +pos/t3568.scala +pos/t0030.scala +pos/t2635.scala +pos/t7232b +pos/t0017.scala +pos/t812.scala +pos/t2179.scala +pos/t651.scala +pos/spurious-overload.scala +pos/t758.scala +pos/t4760.scala +pos/t1672.scala +pos/mixins.scala +pos/patterns.scala +pos/t1260.scala +pos/t6551.scala +pos/t2060.scala +pos/t6575a.scala +pos/t1318.scala +pos/t4266.scala +pos/t0695 +pos/protected-static +pos/t5738.scala +pos/t1226.scala +pos/t5013 +pos/t6215.scala +pos/t5692b +pos/traits.scala +pos/t2994a.scala +pos/t3371.scala +pos/t613.scala +pos/t6499.scala +pos/xlint1.scala +pos/t1150 +pos/sealed-final.scala +pos/test4a.scala +pos/t2664.scala +pos/t3528.scala +pos/t3174.scala +pos/t6994.scala +pos/t4812.scala +pos/t5777.scala +pos/t5223.scala +pos/t439.scala +pos/t3079.scala +pos/t5829.scala +pos/t0036.scala +pos/scoping2.scala +pos/t4717.scala +pos/t4257.scala +pos/t1210a.scala +pos/getClassType.scala +pos/t5330.scala +pos/t4524.scala +pos/t2945.scala +pos/t6562.scala +pos/t0273.scala +pos/override-object-yes.scala +pos/t7426.scala +pos/t6601 +pos/t3076 +pos/seq-ordering.scala +pos/spec-groups.scala +pos/t296.scala +pos/t5545 +pos/spec-multiplectors.scala +pos/t1789.scala +pos/t2569 +pos/ksbug1.scala +pos/t0599.scala +pos/local-objects.scala +pos/t0081.scala +pos/t5756.scala +pos/t7126.scala +pos/t7716.scala +pos/t2797.scala +pos/t5399.scala +pos/t1101 +pos/t767.scala +pos/contrib467.scala +pos/t7532b +pos/self-type-override.scala +pos/t4853.scala +pos/t839.scala +pos/t5644 +pos/t5853.scala +pos/t5178.scala +pos/unapplyNeedsMemberType.scala +pos/t5390.scala +pos/t6575b.scala +pos/t151.scala +pos/t2665.scala +pos/t5120.scala +pos/erasure-nsquared.scala +pos/arrays3.scala +pos/t3136.scala +pos/inline-access-levels +pos/t3972.scala +pos/t2591.scala +pos/t3486 +pos/variances-flip.scala +pos/annotated-original +pos/typesafecons.scala +pos/stable.scala +pos/t1996.scala +pos/t3037.scala +pos/t1711 +pos/t3374.scala +pos/t0029.scala +pos/t3278.scala +pos/matthias3.scala +pos/t5546.scala +pos/t4020.scala +pos/matthias4.scala +pos/value-class-override-spec.scala +pos/arrays2.scala +pos/t5119.scala +pos/t2613.scala +pos/t4070b.scala +pos/virtpatmat_exist_uncurry.scala +pos/modules1.scala +pos/spec-constr-new.scala +pos/t6335.scala +pos/t675.scala +pos/t0644.scala +pos/t5892.scala +pos/t360.scala +pos/override.scala +pos/t1798.scala +pos/strip-tvars-for-lubbasetypes.scala +pos/hk-infer.scala +pos/t2119.scala +pos/t0231.scala +pos/t1459 +pos/t1381-new.scala +pos/t2610.scala +pos/t2708.scala +pos/t5604b +pos/t3951 +pos/t361.scala +pos/t319.scala +pos/largecasetest.scala +pos/switchUnbox.scala +pos/typetags.scala +pos/java-access-pos +pos/t803.scala +pos/t3898.scala +pos/t5692a +pos/t2421.scala +pos/t1102 +pos/t0654.scala +pos/exhaust_alternatives.scala +pos/t807.scala +pos/t5702-pos-infix-star.scala +pos/t1186 +pos/t1439.scala +pos/t7427.scala +pos/virtpatmat_binding_opt.scala +pos/t247.scala +pos/abstract.scala +pos/gen-traversable-methods.scala +pos/t2795-old.scala +pos/t5639 +pos/t2667.scala +pos/t2405.scala +pos/t1438.scala +pos/SI-7100.scala +pos/t1659.scala +pos/unchecked-a.scala +pos/t3636.scala +pos/t6745.scala +pos/t2809.scala +pos/t7022.scala +pos/t6447.scala +pos/t6367.scala +pos/t5846.scala +pos/lubs.scala +pos/t1987a.scala +pos/spec-arrays.scala +pos/virtpatmat_anonfun_for.scala +pos/listpattern.scala +pos/t5742.scala +pos/test5refine.scala +pos/t5604 +pos/return_thistype.scala +pos/t348plus.scala +pos/t3420.scala +pos/t3440.scala +pos/maxim1.scala +pos/caseClassInMethod.scala +pos/t7239.scala +pos/t3833.scala +pos/t6675.scala +pos/t4402 +pos/t5953.scala +pos/t1152 +pos/t0591.scala +pos/t210.scala +pos/t7035.scala +pos/t5769.scala +pos/pmbug.scala +pos/t2331.scala +pos/t5240.scala +pos/t304.scala +pos/annotated-treecopy +pos/t2081.scala +pos/t0904.scala +pos/t7649.scala +pos/t3498-new.scala +pos/contrib701.scala +pos/t6624.scala +pos/t3924.scala +pos/t374.scala +pos/t1642 +pos/t1591_pos.scala +pos/depmet_implicit_oopsla_session_2.scala +pos/t5899.scala +pos/thistype.scala +pos/t4176b.scala +pos/elidable-tparams.scala +pos/lambdalift.scala +pos/nothing_manifest_disambig-old.scala +pos/t372.scala +pos/t5399a.scala +pos/t2782.scala +pos/patmat-extract-tparam.scala +pos/t4114.scala +pos/unapplyVal.scala +pos/t2486.scala +pos/t5877b.scala +pos/t0625.scala +pos/t6358_2.scala +pos/viewtest1.scala +pos/t1237.scala +pos/scala-singleton.scala +pos/t1254 +pos/t5504 +pos/bounds.scala +pos/t3631.scala +pos/t3177.scala +pos/unapplyContexts2.scala +pos/t0438.scala +pos/t1642b.scala +pos/inferbroadtype.scala +pos/t1858.scala +pos/t3731.scala +pos/t6963c.scala +pos/classtag-pos.scala +pos/t6221.scala +pos/t3343.scala +pos/spec-asseenfrom.scala +pos/t604.scala +pos/spec-example1.scala +pos/t0786.scala +pos/annot-inner.scala +pos/t5886.scala +pos/t1056.scala +pos/t294 +pos/spec-Function1.scala +pos/t1836 +pos/spec-private.scala +pos/depmet_implicit_tpbetareduce.scala +pos/exhaust_2.scala +pos/t7532 +pos/t5175.scala +pos/t802.scala +pos/t5809.scala +pos/tcpoly_typesub.scala +pos/t6029.scala +pos/contextbounds-implicits-new.scala +pos/t3480.scala +pos/patterns3.scala +pos/caseaccs.scala +pos/spec-sparsearray-old.scala +pos/patterns1213.scala +pos/spec-traits.scala +pos/t0020.scala +pos/cycle +pos/t5968.scala +pos/typealiases.scala +pos/init.scala +pos/t697.scala +pos/t2693.scala +pos/t2377 +pos/unapplyGeneric.scala +pos/t1385.scala +pos/t3363-old.scala +pos/t1236.scala +pos/t0068.scala +pos/t4052.scala +pos/lambdalift1.scala +pos/z1730.scala +pos/variances-local.scala +pos/virtpatmat_gadt_array.scala +pos/t2421_delitedsl.scala +pos/t5626.scala +pos/t690.scala +pos/t711.scala +pos/t6547.scala +pos/t1937 +pos/t3999 +pos/SI-7060.scala +pos/t2305.scala +pos/t2168.scala +pos/t2660.scala +pos/t1693.scala +pos/inliner2.scala +pos/t2799.scala +pos/t6966.scala +pos/t1001.scala +pos/S5.scala +pos/t0301.scala +pos/t1048.scala +pos/t415.scala +pos/t6386.scala +pos/t2187.scala +pos/hashhash-overloads.scala +pos/t6921.scala +pos/t0227.scala +pos/t6556.scala +pos/t3946 +pos/t1053.scala +pos/t1000.scala +pos/t0586.scala +pos/t7011.scala +pos/t7329.scala +pos/t4975.scala +pos/t1131.scala +pos/t1027.scala +pos/t2913.scala +pos/t3494.scala +pos/t5606.scala +pos/t4716.scala +pos/tcpoly_gm.scala +pos/t4859.scala +pos/t514.scala +pos/lexical.scala +pos/t2624.scala +pos/t4036.scala +pos/t2741 +pos/t703.scala +pos/five-dot-f.scala +pos/t805.scala +pos/strings.scala +pos/t2433 +pos/t6925.scala +pos/t1085.scala +pos/t7461 +pos/t1942 +pos/spec-lists.scala +pos/t3349 +pos/tcpoly_infer_ticket474.scala +pos/t1614 +pos/virtpatmat_reach_const.scala +pos/t2194.scala +pos/t6976 +pos/t1560.scala +pos/t6891.scala +pos/t3883.scala +pos/infersingle.scala +pos/gui.scala +pos/t1164.scala +pos/t3175-pos.scala +pos/t4336.scala +pos/annotations2.scala +pos/proj-rec-test.scala +pos/t2973.scala +pos/t1123.scala +pos/t6205.scala +pos/t5727.scala +pos/t6537.scala +pos/t6712.scala +pos/t3866.scala +pos/t4831.scala +pos/selftails.scala +pos/t397.scala +pos/spec-vector.scala +pos/t7233b.scala +pos/t1391.scala +pos/spec.scala +pos/t3106.scala +pos/contextbounds-implicits-old.scala +pos/packageobjs.scala +pos/michel3.scala +pos/t628.scala +pos/collections.scala +pos/tcpoly_boundedmonad.scala +pos/t7668.scala +pos/t0032.scala +pos/t0069.scala +pos/t4345.scala +pos/t3521 +pos/t3071.scala +pos/tcpoly_infer_easy.scala +pos/t289.scala +pos/t4365 +pos/rangepos-anonapply.scala +pos/t5033.scala +pos/lambda.scala +pos/S8.scala +pos/t6014.scala +pos/t1785.scala +pos/t6034.scala +pos/t7433.scala +pos/imp2-pos.scala +pos/t0504.scala +pos/t1272.scala +pos/t0612 +pos/value-class-override-no-spec.scala +pos/overloaded-unapply.scala +pos/t5859.scala +pos/chang +pos/localmodules.scala +pos/t4237.scala +pos/rangepos-patmat.scala +pos/t1974.scala +pos/t0054.scala +pos/michel2.scala +pos/t0770.scala +pos/t1146.scala +pos/t2441pos.scala +pos/t5099.scala +pos/tcpoly_seq_typealias.scala +pos/t946.scala +pos/tcpoly_infer_ticket1864.scala +pos/t4579.scala +pos/t4737 +pos/t7377b.scala +pos/t616.scala +pos/t201.scala +pos/t6355pos.scala +pos/escapes2.scala +pos/t1675.scala +pos/t3890.scala +pos/t6040.scala +pos/spec-tailcall.scala +pos/existentials.scala +pos/t5317.scala +pos/t7782b.scala +pos/t4758.scala +pos/t7296.scala +pos/t6896.scala +pos/cls1.scala +pos/t402.scala +pos/gosh.scala +pos/t2619.scala +pos/javaConversions-2.10-regression.scala +pos/t759.scala +pos/t5259.scala +pos/t5130.scala +pos/t5156.scala +pos/t0905.scala +pos/package-implicit +pos/t2669.scala +pos/trait-parents.scala +pos/virtpatmat_exhaust.scala +pos/patterns1.scala +pos/t7014 +pos/t1231 +pos/t1751 +pos/t7233.scala +pos/t6022.scala +pos/tcpoly_checkkinds_mix.scala +pos/depmet_implicit_norm_ret.scala +pos/package-case.scala +pos/philippe4.scala +pos/michel6.scala +pos/t4188.scala +pos/t3936 +pos/t1280.scala +pos/t6722.scala +pos/t796.scala +pos/t5542.scala +pos/t3927.scala +pos/t2293.scala +pos/t3800.scala +pos/t7285a.scala +pos/t927.scala +pos/t4494.scala +pos/t3864 +pos/ilya2 +pos/t2940 +pos/S1.scala +pos/tcpoly_wildcards.scala +pos/tryexpr.scala +pos/t6089b.scala +pos/depmet_implicit_oopsla_zipwith.scala +pos/t245.scala +pos/t6146.scala +pos/t1782 +pos/t851.scala +pos/spec-thistype.scala +pos/tcpoly_poly.scala +pos/t6815_import.scala +pos/t4649.scala +pos/t0453.scala +pos/t5020.scala +pos/ilya +pos/t2435.scala +pos/t1279a.scala +pos/t2171.scala +pos/t1957.scala +pos/gadts2.scala +pos/t3567 +pos/Z.scala +pos/t1203b +pos/nested2.scala +pos/t1896 +pos/viewtest2.scala +pos/t5541.scala +pos/existentials-harmful.scala +pos/t4063.scala +pos/t6485a +pos/t1208.scala +pos/t5041.scala +pos/unapplyComplex.scala +pos/t3384.scala +pos/t4112.scala +pos/t788.scala +pos/hklub0.scala +pos/t757.scala +pos/t1197 +pos/t359.scala +pos/t5667.scala +pos/t1107a.scala +pos/virtpatmat_castbinder.scala +pos/t267.scala +pos/t3419 +pos/t3861.scala +pos/t6797.scala +pos/spec-localdefs.scala +pos/t3404 +pos/t4457_1.scala +pos/matthias5.scala +pos/spec-polymeth.scala +pos/kinds.scala +pos/t2310.scala +pos/t6552.scala +pos/valdefs.scala +pos/hkarray.scala +pos/homonym.scala +pos/t1235 +pos/t3429 +pos/t0053.scala +pos/depmet_implicit_chaining_zw.scala +pos/virtpatmat_partialfun_nsdnho.scala +pos/t6664.scala +pos/ticket2251.scala +pos/t3495.scala +pos/super +pos/t121.scala +pos/javaConversions-2.10-ambiguity.scala +pos/t1803.scala +pos/t5877.scala +pos/t0085.scala +pos/t3582.scala +pos/t2939.scala +pos/t1422_pos.scala +pos/manifest1-new.scala +pos/t7505.scala +pos/t5720-ownerous.scala +pos/misc-unapply_pos.scala +pos/tcpoly_variance_pos.scala +pos/t5127.scala +pos/t6123-explaintypes-implicits.scala +pos/t2764 +pos/presuperContext.scala +pos/spec-simple.scala +pos/t3120 +pos/t5729.scala +pos/tcpoly_infer_ticket716.scala +pos/tcpoly_bounds1.scala +pos/t7369.scala +pos/imports-pos.scala +pos/t5654.scala +pos/t0123.scala +pos/raw-map +pos/t5330b.scala +pos/t6485b +pos/t6072.scala +pos/t5692c.scala +pos/t3430.scala +pos/tcpoly_param_scoping.scala +pos/t6204-b.scala +pos/attachments-typed-another-ident +pos/t5359.scala +pos/ticket2197.scala +pos/t720.scala +pos/t2130-2.scala +pos/t2260.scala +pos/t0304.scala +pos/t464.scala +pos/spec-maps.scala +pos/annotDepMethType.scala +pos/t6117.scala +pos/t911.scala +pos/t757a.scala +pos/t2504.scala +pos/t1381-old.scala +pos/t1232 +pos/needstypeearly.scala +pos/moduletrans.scala +pos/t4957.scala +pos/kinzer.scala +pos/t318.scala +pos/widen-existential.scala +pos/t0095.scala +pos/t566.scala +pos/tcpoly_overloaded.scala +pos/t7516 +pos/t7232 +pos/t698.scala +pos/t0002.scala +pos/t0288 +pos/t2994b.scala +pos/cls.scala +pos/t3622 +pos/t3671.scala +pos/tcpoly_subst.scala +pos/t5703 +pos/depmet_implicit_oopsla_session_simpler.scala +pos/t5022.scala +pos/builders.scala +pos/spec-foo.scala +pos/t756.scala +pos/t1569.scala +pos/implicit-unwrap-tc.scala +pos/t3688.scala +pos/t5198.scala +pos/t432.scala +pos/t6022b.scala +pos/channels.scala +pos/t1075.scala +pos/null.scala +pos/t1840 +pos/t6479.scala +pos/t6311.scala +pos/t0039.scala +pos/t1119.scala +pos/t573.scala +pos/t1136.scala +pos/t3938 +pos/spec-sealed.scala +pos/tcpoly_return_overriding.scala +pos/t3582b.scala +pos/t229.scala +pos/t3498-old.scala +pos/t531.scala +pos/t4545.scala +pos/t6651.scala +pos/t2133.scala +pos/tinondefcons.scala +pos/t6157.scala +pos/t6358.scala +pos/t7690.scala +pos/t5779-numeq-warn.scala +pos/list-extractor.scala +pos/t892.scala +pos/t2127.scala +pos/t7180.scala +pos/nullary_poly.scala +pos/virtpatmat_exist3.scala +pos/t1176 +pos/spec-funs.scala +pos/specialize10.scala +pos/t6514.scala +pos/exhaustive_heuristics.scala +pos/t0066.scala +pos/t460.scala +pos/t2130-1.scala +pos/t124.scala +pos/annotations.scala +pos/pat_gilles.scala +pos/array-interfaces.scala +pos/t6210.scala +pos/t3792.scala +pos/implicits-old.scala +pos/t389.scala +pos/t115.scala +pos/virtpatmat_exhaust_unchecked.scala +pos/scoping3.scala +pos/t6033.scala +pos/depmet_implicit_oopsla_session.scala +pos/t602.scala +pos/test5.scala +pos/t611.scala +pos/t5932.scala +pos/t4910.scala +pos/unapplySeq.scala +pos/t344.scala +pos/t3363-new.scala +pos/t4018.scala +pos/t4553.scala +pos/t5082.scala +pos/t3869.scala +pos/t3836.scala +pos/tcpoly_typeapp.scala +pos/t1409 +pos/nonlocal-unchecked.scala +pos/t0082.scala +pos/z1720.scala +pos/t7232c +pos/t2018.scala +pos/t3943 +pos/t2187-2.scala +pos/unicode-decode.scala +pos/t4757 +pos/t0710.scala +pos/t0305.scala +pos/t160.scala +pos/t7591 +pos/simplelists.scala +pos/List1.scala +pos/t516.scala +pos/t6648.scala +pos/t5165 +pos/t0055.scala +pos/t4744 +pos/t7377 +pos/t5726.scala +pos/t0091.scala +pos/t6595.scala +pos/compile.scala +pos/depmet_1_pos.scala +pos/t7364 +pos/philippe3.scala +pos/spec-doubledef-old.scala +pos/t4651.scala +pos/tcpoly_infer_implicit_tuple_wrapper.scala +pos/t6274.scala +pos/tcpoly_infer_explicit_tuple_wrapper.scala +pos/ticket2201.scala +pos/spec-fields-new.scala +pos/optmatch.scala +pos/t7517.scala +pos/t3560.scala +pos/t0165.scala +pos/t0872.scala +pos/t522.scala +pos/t2234.scala +pos/t5031_2.scala +pos/tcpoly_method.scala +pos/t6482.scala +pos/pos-bug1241.scala +pos/implicits-new.scala +pos/t2484.scala +pos/t2425.scala +pos/t1049.scala +pos/michel4.scala +pos/t5958.scala +pos/virtpatmat_instof_valuetype.scala +pos/spec-t6286.scala +pos/t873.scala +pos/t3137.scala +pos/Transactions.scala +pos/t0064.scala +pos/t7486-named.scala +pos/t5444.scala +pos/simple-exceptions.scala +pos/t1006.scala +pos/t7200b.scala +pos/t3777.scala +pos/t4840.scala +pos/t211.scala +pos/nullary.scala +pos/michel1.scala +pos/t5031_3 +pos/typealias_dubious.scala +pos/spec-doubledef-new.scala +pos/philippe1.scala +pos/thistypes.scala +pos/t3570.scala +pos/t6516.scala +pos/context.scala +pos/t3808.scala +pos/philippe2.scala +pos/constfold.scala +pos/t1292.scala +pos/t1147.scala +pos/t404.scala +pos/t4430.scala +pos/A.scala +pos/spec-partially.scala +pos/t5796.scala +pos/t2409 +pos/t284-pos.scala +pos/t5313.scala +pos/t2464 +pos/t1591b.scala +pos/hk-match +pos/t595.scala +pos/t6846.scala +pos/t6162-inheritance.scala +pos/relax_implicit_divergence.scala +pos/patterns2.scala +pos/t4692.scala +pos/t3837.scala +pos/t661.scala +pos/t2810.scala +pos/depexists.scala +pos/virtpatmat_exist4.scala +pos/t5245.scala +pos/t7190.scala +pos/isApplicableSafe.scala +pos/t6204-a.scala +pos/t0076.scala +pos/t1756.scala +pos/t1745 +pos/t6091.scala +pos/t0154.scala +pos/t530.scala +pos/t2094.scala +pos/t1034.scala +pos/t6084.scala +pos/t2454.scala +pos/t2956 +pos/tcpoly_ticket2096.scala +pos/attachments-typed-ident +pos/polymorphic-case-class.scala +pos/t252.scala +pos/spec-constr-old.scala +pos/t2421c.scala +pos/t122.scala +pos/t6574.scala +pos/t3859.scala +pos/spec-params-old.scala +pos/t1196 +pos/t4593.scala +pos/t596.scala +pos/t615.scala +pos/t7689.scala +pos/t3960.scala +pos/t3986.scala +pos/exbound.scala +pos/t2545.scala +pos/t1722 +pos/t159.scala +pos/t3272.scala +pos/t6301.scala +pos/t2794.scala +pos/t3048.scala +pos/t4970.scala +pos/t607.scala +pos/FPTest.scala +pos/test1.scala +pos/t3252.scala +pos/t4176.scala +pos/t112606A.scala +pos/t2183.scala +pos/t430-feb09.scala +pos/t6275.scala +pos/t1832.scala +pos/t8965.scala +pos/t7596b +pos/t8900.scala +pos/t9008.scala +pos/t7704.scala +pos/t7459c.scala +pos/sammy_override.scala +pos/t8828.scala +pos/t8868c +pos/t7459d.scala +pos/t8267.scala +pos/t8844.scala +pos/t8868a +pos/t8894.scala +pos/t7459a.scala +pos/t7596c +pos/t8498.scala +pos/t8868b +pos/t5413.scala +pos/t8781 +pos/t8934a +pos/t8310.scala +pos/t3439.scala +pos/t6582_exhaust_big.scala +pos/t8954 +pos/t5217.scala +pos/t7459b.scala +pos/t9018.scala +pos/sammy_exist.scala +pos/t8893.scala +pos/t7596 +pos/t8793.scala +pos/sammy_overload.scala +pos/t6051.scala +pos/t7683-stop-after-parser +pos/t7750.scala +pos/t5454.scala +pos/t8962.scala +pos/t8947 +pos/t8719 +pos/t8410.scala +pos/patmat-suppress.scala +pos/t8999.scala +pos/t8743.scala +pos/t9157.scala +pos/t8801.scala +pos/t9086.scala +pos/t9050.scala +pos/t9135.scala +pos/t9116.scala +pos/t5154.scala +pos/t9123.scala +pos/t3368.scala +pos/t9321.scala +pos/t9285.scala +pos/t8861.scala +pos/t8359-closelim-crash.scala +pos/t9020.scala +pos/jesper.scala +pos/t9356 +pos/virtpatmat_exhaust_big.scala +pos/t9239 +pos/t9111-inliner-workaround + +neg/volatile_no_override.scala +neg/t800.scala +neg/t5426.scala +neg/t2462a.scala +neg/t2641.scala +neg/classtags_dont_use_typetags.scala +neg/t5031 +neg/t2275b.scala +neg/macro-qmarkqmarkqmark.scala +neg/t4879.scala +neg/t5956.scala +neg/t4196.scala +neg/reify_ann2b.scala +neg/t6666b.scala +neg/warn-unused-privates.scala +neg/t6928.scala +neg/t6337.scala +neg/sealed-java-enums.scala +neg/t563.scala +neg/t900.scala +neg/deadline-inf-illegal.scala +neg/t766.scala +neg/t5429.scala +neg/overloaded-implicit.scala +neg/t875.scala +neg/abstract-class-error +neg/unchecked2.scala +neg/predef-masking.scala +neg/viewtest.scala +neg/macro-noexpand +neg/varargs.scala +neg/t963b.scala +neg/t909.scala +neg/sensitive2.scala +neg/t5390b.scala +neg/abstraction-from-volatile-type-error.scala +neg/macro-exception +neg/t4431.scala +neg/t5689.scala +neg/valueclasses.scala +neg/overload.scala +neg/t0204.scala +neg/t908.scala +neg/t750 +neg/patmatexhaust.scala +neg/macro-invalidusage-badtargs +neg/t1168.scala +neg/t5761.scala +neg/t0503.scala +neg/t7235.scala +neg/t1215.scala +neg/primitive-sigs-1 +neg/t5578.scala +neg/names-defaults-neg-warn.scala +neg/t6436b.scala +neg/t3098 +neg/t910.scala +neg/parstar.scala +neg/t4568.scala +neg/newpat_unreachable.scala +neg/t1181.scala +neg/t5903c +neg/t7294.scala +neg/t4091.scala +neg/t5452-old.scala +neg/t5696.scala +neg/t0209.scala +neg/t2910.scala +neg/t7388.scala +neg/noMember2.scala +neg/no-predef.scala +neg/t6952.scala +neg/t1909b.scala +neg/abstract-report2.scala +neg/t5318.scala +neg/t6074.scala +neg/t7171.scala +neg/abstract-vars.scala +neg/unchecked-impossible.scala +neg/variances-refinement.scala +neg/t3453.scala +neg/t5189.scala +neg/t4302.scala +neg/xmltruncated7.scala +neg/t8217-local-alias-requires-rhs.scala +neg/t7602.scala +neg/t8869.scala +neg/t9008.scala +neg/sammy_error_exist_no_crash.scala +neg/t2866.scala +neg/t8597b.scala +neg/t5691.scala +neg/t8534b.scala +neg/t5091.scala +neg/literals.scala +neg/t8534.scala +neg/t8890.scala +neg/t8764.scala +neg/t9008b.scala +neg/t8731.scala +neg/t8291.scala +neg/t8597.scala +neg/t5639b +neg/t6582_exhaust_big.scala +neg/t8841.scala +neg/t9041.scala +neg/t9093.scala +neg/t7623.scala +neg/t9231.scala +neg/t9286b.scala +neg/t9273.scala +neg/t9127.scala +neg/t9286c.scala +neg/t9286a.scala +neg/virtpatmat_exhaust_big.scala +neg/inlineMaxSize.scala + +run/t7249.scala +run/t3563.scala +run/t6111.scala +run/classtags_multi.scala +run/t5201.scala +run/checked.scala +run/valueclasses-classtag-basic.scala +run/t7171.scala +run/t5053.scala +run/t4535.scala +run/t5923d +run/t7291.scala +run/partialfun.scala +run/macro-term-declared-in-package-object +run/mapValues.scala +run/gadts.scala +run/t2386-new.scala +run/virtpatmat_stringinterp.scala +run/t657.scala +run/t0017.scala +run/t5713 +run/t576.scala +run/t3580.scala +run/virtpatmat_partial.scala +run/t6646.scala +run/mixins.scala +run/t1672.scala +run/macro-expand-implicit-macro-has-implicit +run/tuple-match.scala +run/t7039.scala +run/virtpatmat_opt_sharing.scala +run/virtpatmat_casting.scala +run/t2176.scala +run/eta-expand-star2.scala +run/macro-impl-relaxed +run/intmap.scala +run/t751.scala +run/t1591.scala +run/macro-typecheck-implicitsdisabled +run/t6911.scala +run/t5604.scala +run/macro-term-declared-in-default-param +run/collection-stacks.scala +run/multi-array.scala +run/t4560b.scala +run/buffer-slice.scala +run/t5629.scala +run/t6690.scala +run/matchonstream.scala +run/t3603.scala +run/lazy-exprs.scala +run/macro-quasiquotes +run/Course-2002-13.scala +run/t6337a.scala +run/exoticnames.scala +run/t0936.scala +run/runtime-richChar.scala +run/t7215.scala +run/t1939.scala +run/ReverseSeqView.scala +run/lazy-leaks.scala +run/t0048.scala +run/t3994.scala +run/t2241.scala +run/t627.scala +run/t5966.scala +run/getClassTest-valueClass.scala +run/t3619.scala +run/t1300.scala +run/t2177.scala +run/t3760.scala +run/t1829.scala +run/macro-expand-implicit-macro-is-view +run/t889.scala +run/QueueTest.scala +run/t4537 +run/t3699.scala +run/t1192.scala +run/macro-expand-tparams-bounds +run/macro-expand-nullary-generic +run/t1434.scala +run/t6443-varargs.scala +run/macro-term-declared-in-trait +run/t4080.scala +run/matcharraytail.scala +run/infiniteloop.scala +run/t5733.scala +run/virtpatmat_nested_lists.scala +run/t5158.scala +run/t6695.scala +run/t6070.scala +run/t4558.scala +run/exc2.scala +run/patmat-behavior-2.scala +run/overloads.scala +run/t6957.scala +run/transform.scala +run/t5500.scala +run/t6663.scala +run/castsingleton.scala +run/t4147.scala +run/virtpatmat_staging.scala +run/t4565_1.scala +run/t5588.scala +run/run-bug4840.scala +run/t3496.scala +run/t5867.scala +run/search.scala +run/t3112.scala +run/hashsetremove.scala +run/t6443.scala +run/macro-expand-tparams-prefix +run/contrib674.scala +run/t3508.scala +run/t4300.scala +run/virtpatmat_typed.scala +run/macro-term-declared-in-class-object +run/map_test.scala +run/t5040.scala +run/t4827b.scala +run/lift-and-unlift.scala +run/t6574b.scala +run/t7240 +run/t3984.scala +run/virtpatmat_tailcalls_verifyerror.scala +run/macro-term-declared-in-class-class +run/emptypf.scala +run/t6104.scala +run/t2818.scala +run/t3761-overload-byname.scala +run/t2526.scala +run/phantomValueClass.scala +run/t3126.scala +run/arybufgrow.scala +run/t3980.scala +run/t7375b +run/t6077_patmat_cse_irrefutable.scala +run/classmanifests_new_core.scala +run/t3395.scala +run/name-based-patmat.scala +run/inliner-infer.scala +run/t5171.scala +run/t3726.scala +run/null-hash.scala +run/t4027.scala +run/t2544.scala +run/patmatnew.scala +run/t5923b +run/t7242.scala +run/classtags_core.scala +run/streamWithFilter.scala +run/t3038b.scala +run/macro-expand-varargs-explicit-over-nonvarargs-good +run/macro-divergence-spurious +run/macro-duplicate +run/t2958.scala +run/patch-boundary.scala +run/t2333.scala +run/lazy-override-run.scala +run/macro-quasiinvalidbody-c +run/t5037.scala +run/takeAndDrop.scala +run/t6126.scala +run/t0883.scala +run/t7617a +run/t4171.scala +run/empty-array.scala +run/t7198.scala +run/t493.scala +run/genericValueClass.scala +run/t0677-old.scala +run/t1373.scala +run/t4461.scala +run/t6011b.scala +run/t7584.scala +run/t3935.scala +run/t6928-run.scala +run/t744.scala +run/t3241.scala +run/blame_eye_triple_eee-double.scala +run/t3829.scala +run/t5577.scala +run/t5914.scala +run/t601.scala +run/t5610.scala +run/macro-basic-mamd-mi +run/t6150.scala +run/stringbuilder.scala +run/t7290.scala +run/t6888.scala +run/t6327.scala +run/virtpatmat_unapplyseq.scala +run/t4656.scala +run/macro-term-declared-in-method +run/macro-expand-implicit-macro-is-implicit +run/blame_eye_triple_eee-float.scala +run/t4482.scala +run/t5488.scala +run/matchemptyarray.scala +run/t3714.scala +run/richWrapperEquals.scala +run/t5328.scala +run/stream_flatmap_odds.scala +run/implicitclasses.scala +run/t6827.scala +run/t6394b +run/complicatedmatch.scala +run/valueclasses-classmanifest-basic.scala +run/unreachable.scala +run/caseclasses.scala +run/withIndex.scala +run/exc1.scala +run/amp.scala +run/t1423.scala +run/t594.scala +run/t6353.scala +run/byname.scala +run/vector1.scala +run/t5879.scala +run/t1048.scala +run/t5080.scala +run/t4190.scala +run/caseClassEquality.scala +run/macro-enclosures +run/collections-toSelf.scala +run/implicits.scala +run/finalvar.scala +run/lazy-locals.scala +run/t7231.scala +run/t0508.scala +run/t6628.scala +run/t6406-regextract.scala +run/t0911.scala +run/t4013c.scala +run/t3502.scala +run/t5648.scala +run/retclosure.scala +run/t2857.scala +run/t4859.scala +run/t5162.scala +run/t3038.scala +run/classof.scala +run/t4062.scala +run/unapplyArray.scala +run/t4297.scala +run/t5923a +run/t1537.scala +run/boolexprs.scala +run/valueclasses-classtag-generic.scala +run/macro-term-declared-in-anonymous +run/tcpoly_monads.scala +run/t5407.scala +run/scan.scala +run/forvaleq.scala +run/null-and-intersect.scala +run/t7047 +run/t0607.scala +run/sequenceComparisons.scala +run/t4396.scala +run/macro-undetparams-consfromsls +run/t2029.scala +run/t1220.scala +run/option-fold.scala +run/t5284c.scala +run/macro-auto-duplicate +run/t3529.scala +run/t4697.scala +run/t2251.scala +run/t5300.scala +run/virtpatmat_valdef.scala +run/t2147.scala +run/virtpatmat_extends_product.scala +run/list_map.scala +run/t1333.scala +run/matchbytes.scala +run/valueclasses-classmanifest-existential.scala +run/records.scala +run/t3088.scala +run/macro-def-path-dependent +run/t6443-by-name.scala +run/t1044.scala +run/delay-good.scala +run/case-class-23.scala +run/weakconform.scala +run/patmat-bind-typed.scala +run/t4835.scala +run/t3097.scala +run/t405.scala +run/existentials.scala +run/t2876.scala +run/t4809.scala +run/t1427.scala +run/t6135.scala +run/t3575.scala +run/t5688.scala +run/t6900.scala +run/macro-expand-unapply-a +run/t6677b.scala +run/t7375a.scala +run/t7300.scala +run/typed-annotated +run/elidable-noflags.scala +run/t0042.scala +run/t3050.scala +run/t4536.scala +run/NestedClasses.scala +run/seqlike-kmp.scala +run/t5907.scala +run/t266.scala +run/missingparams.scala +run/t2255.scala +run/t3488.scala +run/t3950.scala +run/typealias_overriding.scala +run/constant-optimization.scala +run/t7507.scala +run/t6090.scala +run/t4582.scala +run/macro-term-declared-in-class +run/macro-typecheck-macrosdisabled2 +run/t3425.scala +run/t4935.scala +run/t3326.scala +run/boolord.scala +run/t1141.scala +run/virtpatmat_unapply.scala +run/t5971.scala +run/t3651.scala +run/macro-sip19-revised +run/pure-args-byname-noinline.scala +run/preinits.scala +run/t5532.scala +run/concat-two-strings.scala +run/t3269.scala +run/macro-impl-default-params +run/t2162.scala +run/matchonseq.scala +run/t5428.scala +run/macro-expand-overload +run/t4660.scala +run/enrich-gentraversable.scala +run/macro-expand-override +run/t4054.scala +run/t4753.scala +run/macro-typecheck-macrosdisabled +run/t2308a.scala +run/duplicate-meth.scala +run/interop_classtags_are_classmanifests.scala +run/t3232.scala +run/t2075.scala +run/virtpatmat_partial_backquoted.scala +run/try-2.scala +run/macro-openmacros +run/macro-undetparams-macroitself +run/t6318_derived.scala +run/deprecate-early-type-defs.scala +run/dead-code-elimination.scala +run/t4827.scala +run/Course-2002-07.scala +run/slice-strings.scala +run/t6292.scala +run/t6206.scala +run/t1042.scala +run/t1718.scala +run/t2074_2.scala +run/arraycopy.scala +run/indexedSeq.scala +run/macro-term-declared-in-implicit-class +run/t3511.scala +run/t6290.scala +run/distinct.scala +run/virtpatmat_alts.scala +run/valueclasses-pavlov.scala +run/exceptions.scala +run/t1368.scala +run/t5856.scala +run/t6968.scala +run/names-defaults.scala +run/macro-expand-tparams-implicit +run/t5881.scala +run/t3540.scala +run/virtpatmat_try.scala +run/t7181.scala +run/value-class-extractor.scala +run/value-class-extractor-2.scala +run/t3150.scala +run/exc.scala +run/delay-bad.scala +run/infix.scala +run/t1309.scala +run/t6370.scala +run/t6725-2.scala +run/macro-impl-tparam-typetag-is-optional +run/macro-term-declared-in-block +run/matchnull.scala +run/t2127.scala +run/t7325.scala +run/groupby.scala +run/t3932.scala +run/t4871.scala +run/longmap.scala +run/t1524.scala +run/t6187b.scala +run/kmpSliceSearch.scala +run/t7088.scala +run/t5804.scala +run/stringbuilder-drop.scala +run/t5753_1 +run/t9223.scala +run/function-null-unbox.scala +run/t9223b.scala +run/disable-assertions.scala +run/valueClassSelfType.scala +run/indylambda-boxing +run/t9219.scala + +pos/cyclics-pos.scala +pos/cfcrash.scala +pos/tcpoly_higherorder_bound_method.scala +pos/t5084.scala +pos/trait-force-info.scala +pos/macro-qmarkqmarkqmark.scala +pos/t7785.scala +pos/nested.scala +pos/t3152.scala +pos/t5031 +pos/t6925b.scala +pos/t1107b +pos/t5012.scala +pos/virtpatmat_obj_in_case.scala +pos/t4938.scala +pos/t3856.scala +pos/spec-cyclic.scala +pos/aliases.scala +pos/typerep_pos.scala +pos/t119.scala +pos/t1050.scala +pos/t3670.scala +pos/t6145.scala +pos/t7315.scala +pos/t5930.scala +pos/t789.scala +pos/t5071.scala +pos/t4731.scala +pos/t4547.scala +pos/t2038.scala +pos/testCoercionThis.scala +pos/t2444.scala +pos/t5744 +pos/t780.scala +pos/t1722-A.scala +pos/virtpatmat_exist1.scala +pos/t6225.scala +pos/t762.scala +pos/t0204.scala +pos/rebind.scala +pos/spec-short.scala +pos/comp-rec-test.scala +pos/lub-dealias-widen.scala +pos/t1168.scala +pos/modules.scala +pos/t4220.scala +pos/t4070.scala +pos/t175.scala +pos/t2500.scala +pos/t5029.scala +pos/itay.scala +pos/t4202.scala +pos/t1987b +pos/t3534.scala +pos/infer2-pos.scala +pos/spec-sparsearray-new.scala +pos/t7091.scala +pos/ticket0137.scala +pos/collectGenericCC.scala +pos/t640.scala +pos/t4305.scala +pos/extractor-types.scala +pos/t3880.scala +pos/spec-annotations.scala +pos/t3577.scala +pos/compile1.scala +pos/spec-t3497.scala +pos/hkrange.scala +pos/t287.scala +pos/t7294.scala +pos/t6008.scala +pos/t4432.scala +pos/CustomGlobal.scala +pos/patmat.scala +pos/t2413 +pos/t2910.scala +pos/t592.scala +pos/t6245 +pos/infer.scala +pos/t7228.scala +pos/compound.scala +pos/attributes.scala +pos/t6771.scala +pos/t1090.scala +pos/t684.scala +pos/t577.scala +pos/t4273.scala +pos/t6278-synth-def.scala +pos/t6184.scala +neg/t0214.scala +neg/t4842.scala +neg/t6214.scala +neg/reify_nested_inner_refers_to_local.scala +neg/t576.scala +neg/t5969.scala +neg/tcpoly_variance.scala +neg/t7509.scala +neg/mixins.scala +neg/parent-inherited-twice-error.scala +neg/macro-abort +neg/constructor-init-order.scala +neg/t6042.scala +neg/t0590.scala +neg/eta-expand-star-deprecation.scala +neg/t4221.scala +neg/t6263.scala +neg/t783.scala +neg/t5554.scala +neg/macro-invalidsig-params-badtype +neg/multi-array.scala +neg/raw-types-stubs +neg/spec-overrides.scala +neg/t836.scala +neg/t7289_status_quo.scala +neg/t5675.scala +neg/macro-quasiquotes +neg/t6667.scala +neg/t6597.scala +neg/t6264.scala +neg/t0345.scala +neg/t7294b.scala +neg/t5340.scala +neg/t2144.scala +neg/t1010.scala +neg/t1838.scala +neg/t5189b.scala +neg/reify_metalevel_breach_-1_refers_to_1.scala +neg/t6601 +neg/wellkinded_wrongarity.scala +neg/t3909.scala +neg/t876.scala +neg/t5390.scala +neg/unit2anyref.scala +neg/t0351.scala +neg/t5120.scala +neg/t1038.scala +neg/t5878.scala +neg/qualifying-class-error-2.scala +neg/t3816.scala +neg/tailrec.scala +neg/volatile.scala +neg/t944.scala +neg/t1705.scala +neg/t3977.scala +neg/t5553_2.scala +neg/t5318c.scala +neg/overload-msg.scala +neg/t5440.scala +neg/t6335.scala +neg/compile-time-only-b.scala +neg/t501.scala +neg/override.scala +neg/t663.scala +neg/t5892.scala +neg/t1980.scala +neg/macro-false-deprecation-warning +neg/t5148.scala +neg/t585.scala +neg/t3776.scala +neg/interop_classtags_arenot_manifests.scala +neg/t4044.scala +neg/macro-invalidusage-nontypeable +neg/t6375.scala +neg/t500.scala +neg/t4877.scala +neg/t5357.scala +neg/interop_abstypetags_arenot_manifests.scala +neg/t4460a.scala +neg/t5318b.scala +neg/t3234.scala +neg/t4440.scala +neg/t6663.scala +neg/t6357.scala +neg/gadts1.scala +neg/cyclics.scala +neg/t5060.scala +neg/scopes.scala +run/t4013.scala +run/macro-expand-tparams-explicit +run/tuples.scala +run/t5753_2 +run/t0528.scala +run/t5105.scala +run/t7341.scala +run/t3670.scala +run/t2594_tcpoly.scala +run/t3895.scala +run/t0668.scala +run/slices.scala +run/t6666a.scala +run/valueclasses-classmanifest-generic.scala +run/t2316_run.scala +run/t3004.scala +run/viewtest.scala +run/t6481.scala +run/t0005.scala +run/t4766.scala +run/t5500b.scala +run/t7407b.scala +run/backreferences.scala +run/arrayview.scala +run/t629.scala +run/t5903c +run/unittest_collection.scala +run/spec-nlreturn.scala +run/macro-term-declared-in-object-object +run/triple-quoted-expr.scala +run/t5937.scala +run/t6011c.scala +run/macro-expand-implicit-argument +run/try.scala +run/t1987b +run/t6089.scala +run/macro-range +run/t2524.scala +run/t4770.scala +run/virtpatmat_unapplyprod.scala +run/t1535.scala +run/ctor-order.scala +pos/t5210.scala +pos/t5384.scala +pos/rangepos.scala +pos/t443.scala +pos/t1480.scala +pos/t116.scala +pos/seqtest2.scala +pos/scoping1.scala +pos/t4269.scala +pos/lookupswitch.scala +pos/t3642 +pos/t5706.scala +pos/SI-5788.scala +pos/t7264 +pos/t0031.scala +pos/macro-deprecate-dont-touch-backquotedidents.scala +pos/t6815.scala +pos/test4refine.scala +pos/michel5.scala +pos/t0851.scala +pos/t1185.scala +pos/sudoku.scala +pos/t7520.scala +pos/t6208.scala +pos/t3411.scala +pos/t295.scala +pos/S3.scala +pos/t0674.scala +pos/t6664b.scala +pos/variances_pos.scala +pos/liftcode_polymorphic.scala +pos/t3174b.scala +pos/t7232d +pos/t578.scala +pos/implicit-infix-ops.scala +pos/t4363.scala +pos/t532.scala +pos/exponential-spec.scala +pos/t599.scala +pos/t5862.scala +pos/t4603 +pos/t3676.scala +pos/t1357.scala +pos/native-warning.scala +pos/t1230 +pos/t6028 +pos/t4275.scala +pos/overloaded_extractor_and_regular_def.scala +pos/t4205 +pos/matthias1.scala +pos/testcast.scala +pos/generic-sigs.scala +pos/t0093.scala +pos/specializes-sym-crash.scala +pos/t0061.scala +pos/t2429.scala +pos/t694.scala +pos/javaReadsSigs +pos/t2023.scala +pos/t704.scala +pos/t2208_pos.scala +pos/t5137.scala +pos/t2683.scala +pos/t0049.scala +pos/t1029 +pos/t4243.scala +pos/typerep-stephane.scala +pos/t177.scala +pos/t5967.scala +pos/t430.scala +pos/virtpatmat_infer_single_1.scala +pos/pat_iuli.scala +pos/t1071.scala +pos/t7226.scala +pos/t1843.scala +pos/t419.scala +pos/t7364b +pos/t1159.scala +pos/t5305.scala +pos/t7694.scala +pos/t6047.scala +pos/t3578.scala +pos/t2082.scala +pos/setter-not-implicit.scala +pos/t1133.scala +pos/t3862.scala +pos/t942 +pos/nothing_manifest_disambig-new.scala +pos/iterator-traversable-mix.scala +pos/eta.scala +pos/test4.scala +pos/t2691.scala +pos/t4502.scala +pos/t7183.scala +pos/protected-t1010.scala +pos/X.scala +pos/virtpatmat_exist2.scala +pos/t4911.scala +pos/t3477.scala +pos/t4173.scala +pos/t7782.scala +pos/t2399.scala +pos/virtpatmat_alts_subst.scala +pos/propagate.scala +pos/t2421b_pos.scala +pos/t183.scala +pos/t7033.scala +pos/t3612.scala +pos/t5330c.scala +pos/t3020.scala +pos/t4869.scala +pos/t3373.scala +pos/spec-params-new.scala +pos/t3672.scala +pos/t4501.scala +pos/t1565.scala +pos/t3774.scala +pos/t6942 +pos/t845.scala +pos/t3240.scala + +neg/t3275.scala +neg/t421.scala +neg/t5702-neg-bad-brace.scala +neg/t3663 +neg/badtok-1.scala +neg/t677.scala +neg/t7756b.scala +neg/t6534.scala +neg/t6276.scala +neg/t5762.scala +neg/abstract.scala +neg/t2405.scala +neg/t0418.scala +neg/t5390c.scala +neg/lazyvals.scala +neg/lubs.scala +neg/abstract-report.scala +neg/t4163.scala +neg/t5702-neg-bad-and-wild.scala +neg/macro-invalidret +neg/t6728.scala +neg/t5152.scala +neg/t1432.scala +neg/abstract-inaccessible.scala +neg/import-precedence.scala +neg/t2462b.scala +neg/macro-invalidusage-presuper +neg/specification-scopes +neg/t6048.scala +neg/t4079 +neg/macro-basic-mamdmi +neg/t7020.scala +neg/t3015.scala +neg/t0207.scala +neg/t2296b +neg/t0673 +neg/t3761-overload-byname.scala +neg/t6675.scala +neg/t5529.scala +neg/sensitive.scala +neg/t742.scala +neg/t5067.scala +neg/t6162-overriding.scala +neg/variances.scala +neg/t5728.scala +neg/t6323a.scala +neg/compile-time-only-a.scala +neg/t6795.scala +neg/t2494.scala +neg/t3649.scala +neg/macro-invalidsig +neg/t2796.scala +neg/t112706A.scala +neg/t0764.scala +neg/t3757 +neg/t1431.scala +neg/exhausting.scala +neg/t1523.scala +neg/t779.scala +neg/xmltruncated1.scala +neg/t2208.scala +neg/t2078.scala +neg/t521.scala +neg/null-unsoundness.scala +neg/stmt-expr-discard.scala +neg/t0513.scala +neg/unchecked-abstract.scala +neg/t4460c.scala +neg/divergent-implicit.scala +neg/t5078.scala +neg/t1701.scala +neg/t0816.scala +neg/t1672b.scala +neg/macro-invalidusage-badbounds +neg/tailrec-2.scala +neg/t4064.scala +neg/t5510.scala +neg/t3873.scala +neg/tailrec-3.scala +neg/t0226.scala +neg/t2031.scala +neg/t633.scala +neg/constrs.scala +neg/anyval-anyref-parent.scala +neg/t7290.scala +neg/t1041.scala +neg/patternalts.scala +neg/error_tooManyArgsPattern.scala +neg/checksensibleUnit.scala +neg/t6539 +neg/t4417.scala +neg/wellkinded_app.scala +neg/for-comprehension-old.scala +neg/t2779.scala +neg/object-not-a-value.scala +neg/t2968b.scala +neg/t6483.scala +neg/t6902.scala +neg/t6963a.scala +neg/t3399.scala +neg/t0015.scala +neg/t3995.scala +neg/t276.scala +neg/t6758.scala +neg/t2441.scala +neg/cycle-bounds.scala +neg/t1241.scala +neg/t4137.scala +neg/unicode-unterminated-quote.scala +neg/t4762.scala +neg/typeerror.scala +neg/implicits.scala +neg/t961.scala +neg/ambiguous-float-dots2.scala +neg/t2416.scala +neg/t5799.scala +neg/t7285.scala +neg/implicit-shadow.scala +neg/t2388.scala +neg/java-access-neg +neg/found-req-variance.scala +neg/hk-bad-bounds.scala +neg/t3224.scala +neg/t1033.scala +neg/t7385.scala +neg/t5882.scala +neg/t4541.scala +neg/t2973.scala +neg/t6406-regextract.scala +neg/t6666.scala +neg/t4831.scala +neg/t425.scala +neg/t1845.scala +neg/t3683b.scala +neg/t2801.scala +neg/t6083.scala +neg/t0528neg.scala +neg/stringinterpolation_macro-neg.scala +neg/t668.scala +neg/t5666.scala +neg/t4271.scala +neg/interop_typetags_arenot_classmanifests.scala +neg/t1355.scala +neg/t715.scala +neg/t7238.scala +neg/t7473.scala +neg/t7292-removal.scala +neg/tcpoly_infer_ticket1162.scala +neg/t4098.scala +neg/t6013 +neg/t6227.scala +neg/t464-neg.scala +neg/badtok-3.scala +neg/t6082.scala +neg/anytrait.scala +neg/valueclasses-doubledefs.scala +neg/t7519.scala +neg/overloaded-unapply.scala +neg/t1163.scala +neg/wellkinded_bounds.scala +neg/t7292-deprecation.scala +neg/t5044.scala +neg/t0842.scala +neg/t6436.scala +neg/interop_typetags_arenot_classtags.scala +neg/t3653.scala +neg/higherkind_novalue.scala +neg/t935.scala +neg/t6040.scala +neg/annot-nonconst.scala +neg/macro-deprecate-idents.scala +neg/illegal-stmt-start.scala +neg/t565.scala +neg/case-collision.scala +neg/t3209.scala +neg/t5821.scala +neg/abstract-class-2.scala +neg/t846.scala +neg/quasiquotes-syntax-error-position.scala +neg/t3987.scala +neg/t877.scala +neg/t0117.scala +neg/t692.scala +neg/t5702-neg-ugly-xbrace.scala +neg/t7752.scala +neg/case-collision2.scala +neg/t6526.scala +neg/t2213.scala +neg/t7756a.scala +neg/macro-override-macro-overrides-abstract-method-a +neg/tcpoly_ticket2101.scala +neg/delayed-init-ref.scala +neg/caseinherit.scala +neg/t3189.scala +neg/unchecked-suppress.scala +neg/t2180.scala +neg/t1371.scala +neg/macro-cyclic +neg/t6123-explaintypes-macros +neg/t4134.scala +neg/t691.scala +neg/t2421b.scala +neg/t4691_exhaust_extractor.scala +neg/t4419.scala +neg/t5801.scala +neg/t650.scala +neg/t5735.scala +neg/t696.scala +neg/t882.scala +neg/t2968.scala +neg/t7507.scala +neg/macro-invalidusage-badargs +neg/macro-reify-typetag-typeparams-notags +neg/wellkinded_app2.scala +neg/t4425b.scala +neg/t2296a +neg/t1878.scala +neg/t649.scala +neg/override-object-no.scala +neg/t4174.scala +neg/t2070.scala +neg/sabin2.scala +neg/t5903e +neg/t6566a.scala +neg/finitary-error.scala +neg/t4818.scala +neg/t3614.scala +neg/t6666c.scala +neg/ticket513.scala +neg/suggest-similar.scala +neg/t4457_1.scala +neg/t6666e.scala +neg/tcpoly_bounds.scala +neg/t4727.scala +neg/t4425.scala +neg/macro-invalidusage-methodvaluesyntax +neg/t3854.scala +neg/t3006.scala +neg/t5580b.scala +neg/t5378.scala +neg/t639.scala +neg/wrong-args-for-none.scala +neg/t7171b.scala +neg/t5361.scala +neg/unreachablechar.scala +neg/t5572.scala +neg/t7757a.scala +neg/macro-invalidimpl +neg/t2773.scala +neg/t6359.scala +neg/saito.scala +neg/xmltruncated2.scala +neg/t667.scala +neg/t3934.scala +neg/t6771b.scala +neg/t4584.scala +neg/wellkinded_wrongarity2.scala +neg/t7369.scala +neg/t1477.scala +neg/t5617.scala +neg/t7299.scala +neg/faculty.scala +neg/virtpatmat_reach_null.scala +neg/macro-reify-typetag-hktypeparams-notags +neg/t1224.scala +neg/xmltruncated3.scala +neg/t1872.scala +neg/t558.scala +neg/t7110.scala +neg/any-vs-anyref.scala +neg/t6340.scala +neg/t4166.scala +neg/t2918.scala +neg/t5856.scala +neg/t4989.scala +neg/t0003.scala +neg/t1183.scala +neg/t963.scala +neg/t4515.scala +neg/valueclasses-pavlov.scala +neg/t608.scala +neg/choices.scala +neg/patmat-type-check.scala +neg/valueclasses-impl-restrictions.scala +neg/imp2.scala +neg/protected-constructors.scala +neg/t6788.scala +neg/nullary-override.scala +neg/t200.scala +neg/t343.scala +neg/names-defaults-neg-ref.scala +neg/tcpoly_typealias.scala +neg/classtags_contextbound_b.scala +neg/t729.scala +neg/t5683.scala +neg/t4928.scala +neg/t700.scala +neg/t7669.scala +neg/macro-invalidshape +neg/t6011.scala +neg/t7325.scala +neg/check-dead.scala +neg/t550.scala +neg/t5663-badwarneq.scala +neg/t0699 +neg/nopredefs.scala +neg/t3507-old.scala +neg/t5352.scala +neg/t6336.scala +neg/interop_classmanifests_arenot_typetags.scala +neg/sealed-final-neg.scala +neg/t2102.scala +neg/t7636.scala +neg/t5031b +neg/t798.scala +neg/t5702-neg-bad-xbrace.scala +neg/t0899.scala +neg/cyclics-import.scala +neg/badtok-2.scala +neg/t473.scala +neg/t3160ambiguous.scala +neg/t5106.scala +neg/t1286 +neg/macro-override-macro-overrides-abstract-method-b +neg/t0259.scala +neg/t510.scala +neg/t3836.scala +neg/t5830.scala +neg/t1548 +neg/t5580a.scala +neg/forward.scala +neg/t591.scala +neg/t6558b.scala +neg/t556.scala +neg/xmltruncated4.scala +neg/t5497.scala +neg/t409.scala +neg/t6283.scala +neg/override-object-flag.scala +neg/constructor-prefix-error.scala +neg/eta-expand-star.scala +neg/t3392.scala +neg/t1275.scala +neg/nested-fn-print.scala +neg/t7330.scala +neg/t2275a.scala +neg/t630.scala +neg/t4270.scala +neg/t2775.scala +neg/pat_unreachable.scala +neg/t4158.scala +neg/unit-returns-value.scala +neg/t1422.scala +neg/reify_metalevel_breach_-1_refers_to_0_b.scala +neg/reassignment.scala +neg/t3683a.scala +neg/noMember1.scala +neg/macro-without-xmacros-b +neg/t1106.scala +neg/t5182.scala +neg/t6889.scala +neg/t4217.scala +neg/t7501 +neg/t5063.scala +neg/t1009.scala +neg/t997.scala +neg/unchecked.scala +neg/classtags_contextbound_c.scala +neg/applydynamic_sip.scala +neg/t7715.scala +neg/t588.scala +neg/t6667b.scala +neg/t7757b.scala +neg/t4069.scala +neg/t515.scala +neg/variances2.scala +neg/t1049.scala +neg/t7289.scala +neg/t1623.scala +neg/permanent-blindness.scala +neg/t5803.scala +neg/super-cast-or-test.scala +neg/nonlocal-warning.scala +neg/t5687.scala +neg/t5903a +neg/t6566b.scala +neg/unchecked-knowable.scala +neg/t5093.scala +neg/protected-static-fail +neg/type-diagnostics.scala +neg/forgot-interpolator.scala +neg/interop_abstypetags_arenot_classmanifests.scala +neg/t5376.scala +neg/t545.scala +neg/xmlcorner.scala +neg/switch.scala +neg/depmet_1.scala +neg/abstract-concrete-methods.scala +neg/t4987.scala +neg/t5452-new.scala +neg/t750b +neg/unchecked-refinement.scala +neg/t418.scala +neg/t5354.scala +neg/t3736.scala +neg/t631.scala +neg/t6829.scala +neg/t0218.scala +neg/volatile-intersection.scala +neg/t412.scala +neg/t693.scala +neg/t4882.scala +neg/t1960.scala +neg/macro-divergence-controlled +neg/t712.scala +neg/t5544 +neg/t3222.scala +neg/t3604.scala +neg/t1112.scala +neg/t7157 +neg/accesses.scala +neg/t452.scala +neg/t6162-inheritance +neg/t2442 +neg/t6567.scala +neg/lazy-override.scala +neg/abstract-explaintypes.scala +neg/nested-annotation.scala +neg/t5753 +neg/t4283b +neg/t3691.scala +neg/infix-op-positions.scala +neg/t3403.scala +neg/t4851 +neg/structural.scala +neg/error_dependentMethodTpeConversionToFunction.scala +neg/t5839.scala +neg/t5553_1.scala +neg/reify_metalevel_breach_+0_refers_to_1.scala +neg/t752.scala +neg/t6574.scala +neg/t3714-neg.scala +neg/t4457_2.scala +neg/t2148.scala +neg/t1364.scala +neg/saferJavaConversions.scala +neg/t414.scala +neg/t5493.scala +neg/classtags_contextbound_a.scala +neg/reify_metalevel_breach_-1_refers_to_0_a.scala +neg/t3118.scala +neg/t512.scala +neg/t2336.scala +neg/t856.scala +neg/xmltruncated6.scala +neg/t2206.scala +neg/virtpatmat_unreach_select.scala +neg/t6258.scala +neg/t6815.scala +neg/not-possible-cause.scala +neg/dbldef.scala +neg/qualifying-class-error-1.scala +neg/t835.scala +neg/t5455.scala +neg/t6558.scala +neg/t708.scala +neg/macro-nontypeablebody +neg/t0565.scala +neg/xmltruncated5.scala +neg/t5390d.scala +neg/t520.scala +neg/t6138.scala +neg/macro-without-xmacros-a +neg/t7214neg.scala +neg/t2870.scala +neg/t593.scala +neg/t4541b.scala +neg/t4460b.scala +neg/t284.scala +neg/t2488.scala +neg/macro-override-method-overrides-macro +neg/interop_abstypetags_arenot_classtags.scala +neg/t3769.scala +neg/warn-inferred-any.scala +neg/t664.scala +neg/t5903d +neg/t562.scala +neg/t2316.scala +neg/t0152.scala +neg/migration28.scala +neg/t6443c.scala +neg/tcpoly_override.scala +neg/t7324.scala +neg/t987.scala +neg/t5903b +neg/t3481.scala +neg/t6912.scala +neg/tcpoly_variance_enforce.scala +neg/t3913.scala +neg/names-defaults-neg.scala +neg/t765.scala +neg/t5358.scala +neg/t391.scala +neg/serialversionuid-not-const.scala +neg/t771.scala +neg/t0903.scala +neg/catch-all.scala +neg/classmanifests_new_deprecations.scala +neg/t0606.scala +neg/t5189_inferred.scala +neg/macro-reify-typetag-useabstypetag +neg/t5543.scala +neg/logImplicits.scala +neg/interop_typetags_without_classtags_arenot_manifests.scala +neg/t6535.scala +neg/t7259.scala +neg/t2139.scala +neg/t278.scala +neg/t5564.scala +neg/unchecked3.scala +neg/virtpatmat_reach_sealed_unsealed.scala +neg/checksensible.scala +neg/t7721.scala +run/t3798.scala +run/macro-expand-varargs-explicit-over-varargs +run/t3888.scala +run/t0677-new.scala +run/t3273.scala +run/t3763.scala +run/t2755.scala +run/t920.scala +run/t5610a.scala +run/literals.scala +run/proxy.scala +run/unapply.scala +run/t5830.scala +run/array-addition.scala +run/macro-expand-nullary-nongeneric +run/macro-basic-ma-mdmi +run/valueclasses-constr.scala +run/t1247.scala +run/t3487.scala +run/rawstrings.scala +run/patmat-seqs.scala +run/eta-expand-star.scala +run/t7436.scala +run/t3996.scala +run/constructors.scala +run/t498.scala +run/t3835.scala +run/t298.scala +run/t2867.scala +run/t7120 +run/virtpatmat_literal.scala +run/t2175.scala +run/t2503.scala +run/t3026.scala +run/t603.scala +run/t0091.scala +run/t6394a +run/macro-expand-varargs-implicit-over-varargs +run/t7407.scala +run/t2552.scala +run/virtpatmat_npe.scala +run/macro-sip19 +run/t6644.scala +run/t6614.scala +run/t2005.scala +run/t4680.scala +run/t5903a +run/classtags_contextbound.scala +run/Course-2002-05.scala +run/applydynamic_sip.scala +run/t1766.scala +run/retsynch.scala +run/t7715.scala +run/t102.scala +run/nonlocalreturn.scala +run/macro-reify-staticXXX +run/Course-2002-06.scala +run/t6863.scala +run/t6500.scala +run/macro-impl-rename-context +run/t4351.scala +run/t5009.scala +run/macro-term-declared-in-annotation +run/t6271.scala +run/array-existential-bound.scala +run/t6443b.scala +run/t1987.scala +run/MutableListTest.scala +run/t7571.scala +run/t5488-fn.scala +run/macro-bodyexpandstoimpl +run/macro-reify-ref-to-packageless +run/t2212.scala +run/macro-expand-varargs-implicit-over-nonvarargs +run/t0807.scala +run/patmat-behavior.scala +run/t2446.scala +run/tuple-zipped.scala +run/breakout.scala +run/t4122.scala +run/macro-settings +run/t7157 +run/t1323.scala +run/t4013b.scala +run/t6309.scala +run/t4047.scala +run/t5544 +run/t978.scala +run/t3361.scala +run/t6611.scala +run/t5387.scala +run/t5656.scala +run/t4897.scala +run/numeric-range.scala +run/t4777.scala +run/Course-2002-03.scala +run/string-extractor.scala +run/view-headoption.scala +run/patmat_unapp_abstype-new.scala +run/stream-stack-overflow-filter-map.scala +run/macro-impl-tparam-only-in-impl +run/t6559.scala +run/macro-reify-tagful-a +run/macro-expand-multiple-arglists +run/t4709.scala +run/t3509.scala +run/t5284b.scala +run/t7617b +run/t3923.scala +run/virtpatmat_apply.scala +run/t363.scala +run/manifests-undeprecated-in-2.10.0.scala +run/matchintasany.scala +run/t3970.scala +run/t4996.scala +run/t5530.scala +run/macro-term-declared-in-object-class +run/t3242b.scala +run/indexedSeq-apply.scala +run/t107.scala +run/t2337.scala +run/t2754.scala +run/flat-flat-flat.scala +run/t6673.scala +run/interpolationMultiline2.scala +run/t0631.scala +run/t2800.scala +run/t6506.scala +run/t6260.scala +run/t2418.scala +run/t4415.scala +run/classmanifests_new_alias.scala +run/t5380.scala +run/tcpoly_parseridioms.scala +run/t1747.scala +run/t5903d +run/t3530.scala +run/t216.scala +run/macro-term-declared-in-refinement +run/t4592.scala +run/t2488.scala +run/t3327.scala +run/t5614.scala +run/t5903b +run/iterables.scala +run/t3964.scala +run/t6329_vanilla.scala +run/t3038c +run/t1697.scala +run/t2030.scala +run/t3397.scala +run/t1005.scala +run/t3353.scala +run/t1466.scala +run/t3186.scala +run/tcpoly_overriding.scala +run/t5394.scala +run/t5284.scala +run/unboxingBug.scala +run/t7200.scala +run/macro-reify-basic +run/t153.scala +run/iterator3444.scala +run/macro-expand-implicit-macro-is-val +run/macro-basic-ma-md-mi +run/interpolationArgs.scala +run/t4954.scala +run/t3645.scala +run/transpose.scala +run/t3887.scala +run/t4288.scala +run/unittest_iterator.scala +run/t5543.scala +run/macro-term-declared-in-object +run/iq.scala +run/t2788.scala +run/t2027.scala +run/macro-expand-recursive +run/t949.scala +run/t1909b.scala +run/delambdafy-nested-by-name.scala +run/delambdafy-two-lambdas.scala +run/macro-blackbox-materialization +run/lists-run.scala +run/macro-parse-position +run/macro-parse-position-malformed +run/macro-whitebox-dynamic-materialization +run/macro-whitebox-extractor +run/macro-vampire-false-warning +run/macro-whitebox-fundep-materialization +run/macro-whitebox-structural +run/mutable-treeset.scala +run/static-module-method.scala +run/sort.scala +run/t1909.scala +run/t1909c.scala +run/t3346a.scala +run/t3346d.scala +run/t3346f.scala +run/t3346h.scala +run/t3346g.scala +run/t3832.scala +run/t4742.scala +run/t5377.scala +run/t5923c.scala +run/t6188.scala +run/t6333.scala +run/t6385.scala +run/t7899.scala +run/t7899-regression.scala +run/t7584b.scala +run/t7223.scala +run/t7859 +run/t7868.scala +run/t7871 +run/arrayclone-new.scala +run/arrayclone-old.scala +run/bitsets.scala +run/comparable-comparator.scala +run/colltest1.scala +run/t2106.scala +run/t5986.scala +run/view-iterator-stream.scala +run/array-charSeq.scala +pos/signatures +pos/t1263 +pos/t3249 +neg/t4749.scala +neg/main1.scala +neg/t7251 +neg/t7494-after-terminal +neg/t7494-before-parser +neg/t7494-right-after-terminal +run/lazy-traits.scala +run/OrderingTest.scala +run/ReplacementMatching.scala +run/patmat-finally.scala +run/t3158.scala +run/t3346e.scala +run/t4398.scala +run/t4930.scala +run/t6534.scala +pos/sammy_scope.scala +pos/delambdafy-patterns.scala +pos/private-types-after-typer.scala +pos/delambdafy-lambdalift.scala +pos/sammy_poly.scala +pos/sammy_single.scala +pos/SI-4012-b.scala +pos/sammy_twice.scala +pos/t3160.scala +pos/t1014.scala +pos/t4970b.scala +pos/t2698.scala +pos/t5845.scala +pos/t6201.scala +pos/t6260a.scala +pos/t7688.scala +pos/t7818.scala +pos/t1203a.scala +pos/t7834.scala +pos/t7853.scala +pos/t7815.scala +pos/t7853-partial-function.scala +pos/t7864.scala +pos/t7928.scala +pos/t7902.scala +pos/t7944.scala +pos/t7847 +neg/accesses2.scala +neg/bad-advice.scala +neg/gadts2.scala +neg/gadts2-strict.scala +neg/macro-bundle-abstract.scala +neg/macro-bundle-object.scala +neg/macro-bundle-trait.scala +neg/macro-blackbox-dynamic-materialization +neg/macro-blackbox-extractor +neg/run-gadts-strict.scala +neg/macro-blackbox-structural +neg/sammy_restrictions.scala +neg/sammy_wrong_arity.scala +neg/t2462c.scala +neg/t3346b.scala +neg/t1909-object.scala +neg/macro-blackbox-fundep-materialization +neg/t3346c.scala +neg/t3871.scala +neg/t3871b.scala +neg/t3971.scala +neg/t3346i.scala +neg/t6120.scala +neg/t6260c.scala +neg/t6680a.scala +neg/t7239.scala +neg/t7007.scala +neg/t7605-deprecation.scala +neg/t7622-missing-required.scala +neg/t7629-view-bounds-deprecation.scala +neg/t7834neg.scala +neg/t7783.scala +neg/t7848-interp-warn.scala +neg/t7519-b +neg/t7622-missing-dependency +neg/t7870.scala +neg/t7877.scala +neg/t7895.scala +neg/t7895b.scala +neg/t7899.scala +neg/t7895c.scala +neg/t7859 +run/t4752.scala +run/t2087-and-2400.scala +run/t3855.scala +run/t6637.scala +run/t6731.scala +pos/t3999b.scala +run/t0432.scala +run/t2514.scala +run/t7817.scala +run/t874.scala +run/type-currying.scala +run/t3616.scala +run/t3687.scala +run/t4570.scala +run/t5612.scala +run/t1110.scala +run/t2636.scala +run/verify-ctor.scala +run/t3647.scala +run/t4560.scala +run/t6632.scala +run/hashCodeBoxesRunTime.scala +run/richs.scala +run/t6725-1.scala +pos/t7776.scala +run/fors.scala +run/t6706.scala +run/t3175.scala +run/delambdafy-dependent-on-param-subst.scala +run/t4332b.scala +run/t8048a +run/t8017 +run/t7985b.scala +run/t8100.scala +run/patmat-mix-case-extractor.scala +run/t4750.scala +run/t7912.scala +run/delambdafy-dependent-on-param-subst-2.scala +run/t8048b +run/t8091.scala +run/macroPlugins-macroRuntime +run/macro-default-params +run/t6355.scala +run/t7777 +run/t8002.scala +run/t8015-ffc.scala +run/macro-subpatterns +run/t7985.scala +run/macroPlugins-macroArgs +run/t7326.scala +run/t5045.scala +run/value-class-partial-func-depmet.scala +run/t6329_vanilla_bug.scala +run/macroPlugins-macroExpand +run/t8010.scala +run/macroPlugins-typedMacroBody +run/t7406.scala +pos/t8146a.scala +pos/t8046c.scala +pos/t8002-nested-scope.scala +pos/t8132.scala +pos/t8045.scala +pos/overzealous-assert-genbcode.scala +pos/t8128.scala +pos/t8013 +pos/t8064b +pos/t6780.scala +pos/t7987 +pos/bcode_throw_null +pos/t8064 +pos/t8046.scala +pos/t6231.scala +pos/t7983.scala +pos/t5508.scala +pos/t5508-min.scala +pos/t8023b.scala +pos/t6231b.scala +pos/debug-reset-local-attrs.scala +pos/t8054.scala +pos/t2066.scala +pos/dotless-targs.scala +pos/t8120.scala +pos/t5508-min-okay.scala +pos/t8060.scala +pos/t8001 +pos/t8138.scala +pos/t8111.scala +pos/t8062 +pos/t8011.scala +pos/t8146b.scala +pos/t8046b.scala +pos/t8023.scala +pos/t5508-min-okay2.scala +pos/macro-implicit-invalidate-on-error.scala +neg/t6563.scala +neg/missing-param-type-tuple.scala +neg/not-a-legal-formal-parameter-tuple.scala +neg/t7897.scala +neg/t8015-ffa.scala +neg/quasiquotes-unliftable-not-found.scala +neg/t2066b.scala +neg/dotless-targs.scala +neg/patmat-classtag-compound.scala +neg/t2066.scala +neg/t8035-deprecated.scala +neg/t6675b.scala +neg/t8104 +neg/t7872.scala +neg/t7850.scala +neg/t7967.scala +neg/macro-bundle-overloaded.scala +neg/t6355a.scala +neg/class-of-double-targs.scala +neg/t6355b.scala +neg/macro-reify-splice-splice +neg/macro-bundle-noncontext.scala +neg/t8015-ffb.scala +neg/t8035-removed.scala +neg/t7984.scala +neg/t8024.scala +neg/t8024b.scala +neg/t8157.scala +neg/t8146-non-finitary-2.scala +neg/t8006.scala +neg/t7872c.scala +neg/t8146-non-finitary.scala +neg/t7872b.scala +neg/t6920.scala +run/t6200.scala +run/t6196.scala +run/macro-bundle-context-refinement +run/macro-enclosingowner-detectvar +run/macro-enclosingowner-sbt +run/macro-bundle-context-alias +run/macro-bundle-whitebox-use-refined +run/macro-bundle-whitebox-use-raw +neg/name-lookup-stable.scala +neg/t0764b.scala +neg/no-implicit-to-anyref-any-val.scala +neg/t1503.scala +neg/t4728.scala +neg/t6455.scala +neg/t6260-named.scala +neg/t6844.scala +neg/t7475c.scala +neg/t7475e.scala +neg/t7475f.scala +neg/macro-bundle-whitebox-use-raw +neg/macro-bundle-whitebox-use-refined +neg/macro-incompatible-macro-engine-b +neg/t7980.scala +neg/macro-incompatible-macro-engine-a +neg/t8143a.scala +neg/t8072.scala +neg/t8207.scala +neg/t8182.scala +neg/t8219-any-any-ref-equals.scala +neg/t8177a.scala +neg/t8228.scala +neg/t8229.scala +neg/t8237-default.scala +neg/t8244b.scala +neg/t8244e +neg/t8244c.scala +neg/t8265.scala +neg/t8266-invalid-interp.scala +neg/t6931 +neg/t8376 +neg/t8372.scala +neg/t8300-overloading.scala +neg/t8244 +neg/t8158 +neg/t8431.scala +pos/implicit-anyval-2.10.scala +pos/delambdafy_t6260_method.scala +pos/macro-bundle-disambiguate-bundle.scala +pos/macro-bundle-disambiguate-nonbundle.scala +pos/package-ob-case +pos/t1786-counter.scala +pos/reflection-compat-api-universe.scala +pos/list-optim-check.scala +pos/existential-java-case-class +pos/t1786-cycle.scala +pos/reflection-compat-c.scala +pos/t3452f.scala +pos/reflection-compat-ru.scala +pos/t2066-2.10-compat.scala +pos/reflection-compat-macro-universe.scala +pos/t5900a.scala +pos/t5760-pkgobj-warn +pos/t5954a +pos/t5954b +pos/t5954d +pos/t6260.scala +pos/t5165b +pos/t5954c +pos/t6260b.scala +pos/t7475b.scala +pos/t7475a.scala +pos/t7753.scala +pos/t7322.scala +pos/t6948.scala +pos/t7475d.scala +pos/t7475e.scala +pos/t6169 +pos/t7788.scala +pos/t7919.scala +pos/t8177a.scala +pos/t8177.scala +pos/t8170.scala +pos/t8170b.scala +pos/t8177d.scala +pos/t8177b.scala +pos/t8177e.scala +pos/t8134 +pos/t8177h.scala +pos/t8177g.scala +pos/t8207.scala +pos/t8187.scala +pos/t8219.scala +pos/t8219b.scala +pos/t8224.scala +pos/t8237.scala +pos/t8223.scala +pos/t8237b.scala +pos/t8300-conversions-a.scala +pos/t8300-conversions-b.scala +pos/t8209a +pos/t8209b +pos/t8244d +pos/t8300-overloading.scala +pos/t8300-patmat-a.scala +pos/t8300-patmat-b.scala +pos/t8315b.scala +pos/t8306.scala +pos/t8301.scala +pos/t8324.scala +pos/t8315.scala +pos/t8301b.scala +pos/t8363.scala +pos/t8367.scala +pos/t8369a.scala +pos/t8369b.scala +pos/t8403.scala +pos/t8364.scala +pos/t8352 +pos/t8376 +neg/macro-bundle-nonpublic-c.scala +neg/literate_existentials.scala +neg/macro-bundle-nonpublic-impl.scala +neg/macro-bundle-ambiguous.scala +neg/macro-bundle-priority-bundle.scala +neg/macro-bundle-need-qualifier.scala +neg/macro-bundle-nonstatic.scala +neg/macro-bundle-polymorphic.scala +neg/macro-bundle-priority-nonbundle.scala +neg/macro-bundle-wrongcontext-a.scala +neg/macro-bundle-wrongcontext-b.scala +run/t8425 +run/t8245.scala +run/t8266-octal-interp.scala +run/t8280.scala +run/t8395.scala +run/t8321 +run/t8153.scala +run/t8233-bcode.scala +run/t8197.scala +run/t8197b.scala +run/t8233.scala +run/t8133 +run/t8133b +run/t7475b.scala +run/t7445.scala +run/t6814 +run/t4577.scala +run/t5134.scala +run/t3452f.scala +run/t3452h.scala +run/t3452c.scala +run/t3452.scala +run/t261.scala +run/t3235-minimal.scala +run/t1503_future.scala +run/t5565.scala +pos/t8411 +pos/t8460.scala +run/t8428.scala +run/t8437 +run/absoverride.scala +run/arrays.scala +run/duration-coarsest.scala +run/iterator-from.scala +run/SymbolsTest.scala +run/t1074.scala +run/t1505.scala +run/streams.scala +run/t2111.scala +run/t4601.scala +pos/SI-4012-a.scala +pos/SI-7638.scala +neg/t3692-new.scala +run/t7015.scala +run/t7992b.scala +run/t7992.scala +run/t8570.scala +pos/t8157-2.10.scala +pos/t8325.scala +pos/t8523.scala +pos/t8578.scala +pos/t8329.scala +pos/t8497 +pos/t8546.scala +pos/t8531 +neg/t8325-c.scala +neg/t8325-b.scala +neg/t8325.scala +neg/t6988.scala +neg/t8463.scala +neg/t8450.scala +neg/t8430.scala +run/finally.scala +neg/t8630.scala +neg/t8035-no-adapted-args.scala +neg/t8675b.scala +neg/t8610-arg.scala +neg/t8736-c.scala +neg/tailrec-4.scala +neg/double-def-top-level +neg/t8610.scala +neg/aladdin1055 +neg/virtpatmat_exhaust_compound.scala +neg/t8675.scala +neg/t8525.scala +pos/t8736.scala +pos/t8625.scala +pos/t8596.scala +pos/t8617.scala +pos/t8736-b.scala +pos/t8708 +pos/macro-attachments +run/t8611a.scala +run/t8738.scala +run/macro-rangepos-args +run/t8610.scala +run/macro-rangepos-subpatterns +run/t8611c.scala +run/macroPlugins-isBlackbox +run/t8601d.scala +run/t8607.scala +run/bugs.scala +run/t1503.scala +run/t4148.scala +run/t7763.scala +run/issue192.scala +run/t8893b.scala +run/t8845.scala +run/t8933 +run/t7459c.scala +run/t9003.scala +run/t7459f.scala +run/t8933c.scala +run/t1994.scala +run/t2866.scala +run/t5665.scala +run/t7459d.scala +run/t8933b +run/t8888.scala +run/t7459b-optimize.scala +run/t7459a.scala +run/t7019.scala +run/t8893.scala +run/t8803.scala +run/t7459b.scala +run/nothingTypeNoFramesNoDce.scala +run/t8823.scala +run/sammy_repeated.scala +run/t6541.scala +run/nothingTypeDce.scala +run/t8680.scala +run/t8925.scala +run/nothingTypeNoOpt.scala +run/t9030.scala +run/bigDecimalTest.scala +run/bigDecimalCache.scala +run/range.scala +run/t6064.scala +run/t7269.scala +run/equality.scala +run/number-parsing.scala +run/t6220.scala +run/mapConserve.scala +run/colltest.scala +run/t0412.scala +run/t6261.scala +run/java-erasure.scala +run/t5880.scala +run/t6197.scala +run/t4201.scala +run/t5608.scala +run/t3518.scala +run/t6198.scala +run/t2813.2.scala +run/t9029b.scala +run/t9029c.scala +run/t7850c.scala +run/t7850d.scala +run/t9029.scala +run/t9387.scala +run/t9387b.scala +run/t9422.scala +run/t9425.scala +run/t9546.scala +run/t9546b.scala +run/t9546c.scala +run/t9546e.scala +run/t9546d.scala +run/t9567.scala +run/t9567b.scala +run/t9567c.scala +pos/t9442.scala +pos/t9369.scala +pos/existential-slow-compile1.scala +pos/t6666d.scala +pos/existental-slow-compile2.scala +pos/t9475.scala +pos/t9370 +pos/t9392 +pos/t9393 +neg/t8989.scala +neg/t8127a.scala +neg/t6895.scala +neg/t8892.scala +neg/missing-arg-list.scala +neg/t8777.scala +neg/t6895b.scala +neg/t9401.scala +neg/t9572.scala +neg/warn-unused-imports +neg/partestInvalidFlag.scala +pos/t2712-1.scala +pos/t2712-2.scala +pos/t2712-3.scala +pos/t2712-4.scala +pos/t2712-5.scala +pos/t2712-6.scala +pos/t2712-7.scala +pos/t10206.scala +pos/hkgadt.scala +pos/t9331.scala +pos/t6895b.scala +pos/t9245.scala +pos/t5683.scala +pos/t9630 +pos/userdefined_apply_poly_overload.scala +pos/t9399.scala +pos/t9411a.scala +pos/t8449 +pos/userdefined_apply.scala +pos/t9411b.scala +pos/t7046-2 +neg/t3236-neg +neg/t2712-1.scala +neg/t2712-2.scala +neg/t2712-3.scala +neg/t9834.scala +neg/t8763.scala +neg/userdefined_apply.scala +neg/t7046 +neg/t7046-2 +run/t10261 +run/t10037 +run/t7046-1 +run/t9806.scala +run/t9114.scala +run/t7046-2 + +# Adapt checkfiles for (1.0).toString == "1" +run/Course-2002-01.scala +run/t0421-new.scala +run/runtime.scala +run/t0421-old.scala +run/spec-self.scala +run/t5552.scala +run/Course-2002-02.scala +run/Course-2002-04.scala +run/promotion.scala +run/t4617.scala +run/Course-2002-09.scala +run/t5866.scala +run/try-catch-unify.scala +run/impconvtimes.scala +run/Course-2002-10.scala +run/Course-2002-08.scala +run/MeterCaseClass.scala +run/Meter.scala +run/deeps.scala +run/caseClassHash.scala +run/interpolation.scala +run/interpolationMultiline1.scala + +# Adapt checkfiles for ().toString == "undefined" +run/t5680.scala +run/dynamic-anyval.scala +run/macro-bundle-toplevel +run/macro-bundle-whitebox-decl +run/t6662 +run/t8570a.scala +run/t3702.scala +run/t7657 +run/macro-bundle-static +run/structural.scala + +# Adapt checkfiles for print & flush (which we cannot 100% emulate) +run/imports.scala +run/misc.scala + +# Adapt checkfiles for compiler phase list +run/t6102.scala +neg/t7494-no-options +neg/t6446-list +neg/t6446-missing +neg/t6446-show-phases.scala +neg/t6446-additional + +# Adapt checkfiles for different behavior with boxed types +run/t5568.scala +run/virtpatmat_typetag.scala +run/virtpatmat_switch.scala +run/t5629b.scala +run/t6318_primitives.scala +run/t8764.scala +run/t5356.scala + +# Difference in function specialization +run/delambdafy-specialized.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-additional.check new file mode 100644 index 0000000000..3c72fe21c0 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-additional.check @@ -0,0 +1,31 @@ + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + tailcalls 13 replace tail calls by jumps + specialize 14 @specialized-driven class and method specialization + explicitouter 15 this refs to outer pointers + erasure 16 erase types, add interfaces for traits + posterasure 17 clean up erased inline classes + lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + icode 26 generate portable intermediate code + jvm 27 generate JVM bytecode + ploogin 28 A sample phase that does so many things it's kind of hard... + terminal 29 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-list.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-list.check new file mode 100644 index 0000000000..95883c8c81 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-list.check @@ -0,0 +1,2 @@ +ploogin - A sample plugin for testing. +scalajs - Compile to JavaScript diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-missing.check new file mode 100644 index 0000000000..4761e1f032 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-missing.check @@ -0,0 +1,31 @@ +Error: unable to load class: t6446.Ploogin + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + tailcalls 13 replace tail calls by jumps + specialize 14 @specialized-driven class and method specialization + explicitouter 15 this refs to outer pointers + erasure 16 erase types, add interfaces for traits + posterasure 17 clean up erased inline classes + lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + icode 26 generate portable intermediate code + jvm 27 generate JVM bytecode + terminal 28 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-show-phases.check new file mode 100644 index 0000000000..28b57055a3 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-show-phases.check @@ -0,0 +1,30 @@ + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + tailcalls 13 replace tail calls by jumps + specialize 14 @specialized-driven class and method specialization + explicitouter 15 this refs to outer pointers + erasure 16 erase types, add interfaces for traits + posterasure 17 clean up erased inline classes + lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + icode 26 generate portable intermediate code + jvm 27 generate JVM bytecode + terminal 28 the last phase during a compilation run \ No newline at end of file diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t7494-no-options.check new file mode 100644 index 0000000000..fa3cdc9193 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t7494-no-options.check @@ -0,0 +1,32 @@ +error: Error: ploogin takes no options + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + tailcalls 13 replace tail calls by jumps + specialize 14 @specialized-driven class and method specialization + explicitouter 15 this refs to outer pointers + erasure 16 erase types, add interfaces for traits + posterasure 17 clean up erased inline classes + lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + icode 26 generate portable intermediate code + jvm 27 generate JVM bytecode + ploogin 28 A sample phase that does so many things it's kind of hard... + terminal 29 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Course-2002-01.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Course-2002-01.check new file mode 100644 index 0000000000..fcda9433de --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Course-2002-01.check @@ -0,0 +1,37 @@ +Course-2002-01.scala:41: warning: method loop in object M0 does nothing other than call itself recursively + def loop: Int = loop; + ^ +232 +667 +11 +10 +62.8318 +62.8318 +62.8318 +4 +81 +256 +25 +1 +737 +1 +0 +1 +76 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +sqrt(2) = 1.4142135623746899 +sqrt(2) = 1.4142135623746899 +cbrt(2) = 1.2599210500177698 +1 +1 1 +1 2 1 +1 3 3 1 +1 4 6 4 1 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Course-2002-02.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Course-2002-02.check new file mode 100644 index 0000000000..ab75cfdb61 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Course-2002-02.check @@ -0,0 +1,187 @@ +7 +120 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +pi = 3.181104885577714 +pi = 3.181104885577714 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 +pi = 3.181104885577714 +pi = 3.181104885577714 + +1.5 +1.4166666666666665 +1.4142156862745097 +1.4142135623746899 +sqrt(2) = 1.4142135623746899 + +1.5 +1.4166666666666665 +1.4142156862745097 +1.4142135623746899 +sqrt(2) = 1.4142135623746899 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +power(0,0) = 1 +power(0,1) = 0 +power(0,2) = 0 +power(0,3) = 0 +power(0,4) = 0 +power(0,5) = 0 +power(0,6) = 0 +power(0,7) = 0 +power(0,8) = 0 + +power(1,0) = 1 +power(1,1) = 1 +power(1,2) = 1 +power(1,3) = 1 +power(1,4) = 1 +power(1,5) = 1 +power(1,6) = 1 +power(1,7) = 1 +power(1,8) = 1 + +power(2,0) = 1 +power(2,1) = 2 +power(2,2) = 4 +power(2,3) = 8 +power(2,4) = 16 +power(2,5) = 32 +power(2,6) = 64 +power(2,7) = 128 +power(2,8) = 256 + +power(3,0) = 1 +power(3,1) = 3 +power(3,2) = 9 +power(3,3) = 27 +power(3,4) = 81 +power(3,5) = 243 +power(3,6) = 729 +power(3,7) = 2187 +power(3,8) = 6561 + +power(4,0) = 1 +power(4,1) = 4 +power(4,2) = 16 +power(4,3) = 64 +power(4,4) = 256 +power(4,5) = 1024 +power(4,6) = 4096 +power(4,7) = 16384 +power(4,8) = 65536 + +power(5,0) = 1 +power(5,1) = 5 +power(5,2) = 25 +power(5,3) = 125 +power(5,4) = 625 +power(5,5) = 3125 +power(5,6) = 15625 +power(5,7) = 78125 +power(5,8) = 390625 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Course-2002-04.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Course-2002-04.check new file mode 100644 index 0000000000..fc6ad96eed --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Course-2002-04.check @@ -0,0 +1,64 @@ +list0 = List(6, 3, 1, 8, 7, 1, 2, 5, 8, 4, 3, 4, 8) +list1 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list2 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list3 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list4 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list5 = List(8, 8, 8, 7, 6, 5, 4, 4, 3, 3, 2, 1, 1) +list6 = List(8, 8, 8, 7, 6, 5, 4, 4, 3, 3, 2, 1, 1) + +list0: List() -> List() +list1: List(0) -> List(0) +list2: List(0, 1) -> List(0, 1) +list3: List(1, 0) -> List(0, 1) +list4: List(0, 1, 2) -> List(0, 1, 2) +list5: List(1, 0, 2) -> List(0, 1, 2) +list6: List(0, 1, 2) -> List(0, 1, 2) +list7: List(1, 0, 2) -> List(0, 1, 2) +list8: List(2, 0, 1) -> List(0, 1, 2) +list9: List(2, 1, 0) -> List(0, 1, 2) +listA: List(6, 3, 1, 8, 7, 1, 2, 5, 8, 4) -> List(1, 1, 2, 3, 4, 5, 6, 7, 8, 8) + +f(x) = 5x^3+7x^2+5x+9 +f(0) = 9 +f(1) = 26 +f(2) = 87 +f(3) = 222 + +v1 = List(2, 3, 4) +v2 = List(6, 7, 8) + +id = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +m1 = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m2 = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) + +v1 * v1 = 29 +v1 * v2 = 65 +v2 * v1 = 65 +v1 * v2 = 65 + +id * v1 = List(2, 3, 4) +m1 * v1 = List(4, 6, 8) +m2 * v1 = List(20, 47, 74) + +trn(id) = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +trn(m1) = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +trn(m2) = List(List(1, 4, 7), List(2, 5, 8), List(3, 6, 9)) + +List(v1) * id = List(List(2, 3, 4)) +List(v1) * m1 = List(List(4, 6, 8)) +List(v1) * m2 = List(List(42, 51, 60)) + +id * List(v1) = List(List(2, 3, 4), List(0, 0, 0), List(0, 0, 0)) +m1 * List(v1) = List(List(4, 6, 8), List(0, 0, 0), List(0, 0, 0)) +m2 * List(v1) = List(List(2, 3, 4), List(8, 12, 16), List(14, 21, 28)) + +id * id = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +id * m1 = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m1 * id = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m1 * m1 = List(List(4, 0, 0), List(0, 4, 0), List(0, 0, 4)) +id * m2 = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) +m2 * id = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) +m1 * m2 = List(List(2, 4, 6), List(8, 10, 12), List(14, 16, 18)) +m2 * m1 = List(List(2, 4, 6), List(8, 10, 12), List(14, 16, 18)) +m2 * m2 = List(List(30, 36, 42), List(66, 81, 96), List(102, 126, 150)) + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Course-2002-08.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Course-2002-08.check new file mode 100644 index 0000000000..0585d5b44f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Course-2002-08.check @@ -0,0 +1,171 @@ +x = abc +count = 111 +x = hello +count = 112 + +account deposit 50 -> undefined +account withdraw 20 -> 30 +account withdraw 20 -> 10 +account withdraw 15 -> + +x deposit 30 -> undefined +y withdraw 20 -> + +x deposit 30 -> undefined +x withdraw 20 -> 10 + +x deposit 30 -> undefined +y withdraw 20 -> 10 + +2^0 = 1 +2^1 = 2 +2^2 = 4 +2^3 = 8 + +2^0 = 1 +2^1 = 2 +2^2 = 4 +2^3 = 8 + +1 2 3 +List(1, 2, 3) + +out 0 new-value = false +*** simulation started *** +out 1 new-value = true +!0 = 1 + +*** simulation started *** +out 2 new-value = false +!1 = 0 + +out 2 new-value = false + +*** simulation started *** +0 & 0 = 0 + +*** simulation started *** +0 & 1 = 0 + +*** simulation started *** +out 11 new-value = true +out 11 new-value = false +1 & 0 = 0 + +*** simulation started *** +out 14 new-value = true +1 & 1 = 1 + +out 14 new-value = false + +*** simulation started *** +0 | 0 = 0 + +*** simulation started *** +out 24 new-value = true +0 | 1 = 1 + +*** simulation started *** +1 | 0 = 1 + +*** simulation started *** +1 | 1 = 1 + +sum 34 new-value = false +carry 34 new-value = false + +*** simulation started *** +0 + 0 = 0 + +*** simulation started *** +sum 47 new-value = true +0 + 1 = 1 + +*** simulation started *** +carry 50 new-value = true +carry 50 new-value = false +sum 54 new-value = false +sum 54 new-value = true +1 + 0 = 1 + +*** simulation started *** +carry 57 new-value = true +sum 61 new-value = false +1 + 1 = 2 + +sum 61 new-value = false +carry 61 new-value = false + +*** simulation started *** +0 + 0 + 0 = 0 + +*** simulation started *** +sum 82 new-value = true +0 + 0 + 1 = 1 + +*** simulation started *** +sum 89 new-value = false +carry 90 new-value = true +sum 97 new-value = true +carry 98 new-value = false +0 + 1 + 0 = 1 + +*** simulation started *** +sum 113 new-value = false +carry 114 new-value = true +0 + 1 + 1 = 2 + +*** simulation started *** +sum 121 new-value = true +carry 122 new-value = false +sum 129 new-value = false +sum 129 new-value = true +1 + 0 + 0 = 1 + +*** simulation started *** +carry 137 new-value = true +sum 144 new-value = false +1 + 0 + 1 = 2 + +*** simulation started *** +carry 152 new-value = false +sum 152 new-value = true +sum 158 new-value = false +carry 159 new-value = true +1 + 1 + 0 = 2 + +*** simulation started *** +sum 173 new-value = true +1 + 1 + 1 = 3 + +in 0 new-value = false +ctrl0 0 new-value = false +ctrl1 0 new-value = false +ctrl2 0 new-value = false +out0 0 new-value = false +out1 0 new-value = false +out2 0 new-value = false +out3 0 new-value = false +out4 0 new-value = false +out5 0 new-value = false +out6 0 new-value = false +out7 0 new-value = false +in 0 new-value = true +*** simulation started *** +out0 10 new-value = true +ctrl0 10 new-value = true +*** simulation started *** +out1 13 new-value = true +out0 14 new-value = false +ctrl1 14 new-value = true +*** simulation started *** +out3 20 new-value = true +out1 21 new-value = false +ctrl2 21 new-value = true +*** simulation started *** +out7 30 new-value = true +out3 31 new-value = false +ctrl0 31 new-value = false +*** simulation started *** +out7 34 new-value = false +out6 35 new-value = true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Course-2002-09.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Course-2002-09.check new file mode 100644 index 0000000000..c921361db7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Course-2002-09.check @@ -0,0 +1,50 @@ +Probe: f = 32 +Probe: c = 0 +Probe: f = ? +Probe: c = ? + +Probe: f = 212 +Probe: c = 100 +Probe: f = ? +Probe: c = ? + +Probe: c = 0 +Probe: f = 32 +Probe: c = ? +Probe: f = ? + +Probe: c = 100 +Probe: f = 212 +Probe: c = ? +Probe: f = ? + +0 Celsius -> 32 Fahrenheits +100 Celsius -> 212 Fahrenheits +32 Fahrenheits -> 0 Celsius +212 Fahrenheits -> 100 Celsius + +a = ?, b = ?, c = ? => ? * ? = ? +a = 2, b = ?, c = ? => 2 * ? = ? +a = ?, b = 3, c = ? => ? * 3 = ? +a = ?, b = ?, c = 6 => ? * ? = 6 +a = 2, b = 3, c = ? => 2 * 3 = 6 +a = 2, b = ?, c = 6 => 2 * 3 = 6 +a = ?, b = 3, c = 6 => 2 * 3 = 6 +a = 2, b = 3, c = 6 => 2 * 3 = 6 + +a = 0, b = ?, c = ? => 0 * ? = 0 +a = ?, b = 0, c = ? => ? * 0 = 0 +a = ?, b = ?, c = 0 => ? * ? = 0 +a = 0, b = 7, c = ? => 0 * 7 = 0 +a = 7, b = 0, c = ? => 7 * 0 = 0 +a = 0, b = 0, c = ? => 0 * 0 = 0 +a = 0, b = ?, c = 0 => 0 * ? = 0 +a = ?, b = 0, c = 0 => ? * 0 = 0 +a = 0, b = 7, c = 0 => 0 * 7 = 0 +a = 7, b = 0, c = 0 => 7 * 0 = 0 +a = 0, b = 0, c = 0 => 0 * 0 = 0 + +a = 3, b = 4 => c = 5 +a = 3, c = 5 => b = 4 +b = 4, c = 5 => a = 3 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Course-2002-10.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Course-2002-10.check new file mode 100644 index 0000000000..847f0fa703 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Course-2002-10.check @@ -0,0 +1,46 @@ +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +fib(10) = 55 +fib(11) = 89 +fib(12) = 144 +fib(13) = 233 +fib(14) = 377 +fib(15) = 610 +fib(16) = 987 +fib(17) = 1597 +fib(18) = 2584 +fib(19) = 4181 + +pi(0) = 4 , 3.166666666666667 , 4 +pi(1) = 2.666666666666667 , 3.1333333333333337, 3.166666666666667 +pi(2) = 3.466666666666667 , 3.1452380952380956, 3.142105263157895 +pi(3) = 2.8952380952380956, 3.1396825396825396, 3.1415993573190044 +pi(4) = 3.33968253968254 , 3.142712842712843 , 3.141592714033778 +pi(5) = 2.976046176046176 , 3.140881340881341 , 3.1415926539752923 +pi(6) = 3.283738483738484 , 3.142071817071817 , 3.141592653591176 +pi(7) = 3.017071817071817 , 3.1412548236077646, 3.141592653589777 +pi(8) = 3.252365934718876 , 3.1418396189294024, 3.141592653589794 +pi(9) = 3.0418396189294024, 3.141406718496502 , 3.1415926535897936 +pi = 3.141592653589793 , 3.141592653589793 , 3.141592653589793 + +ln(0) = 1 , 0.7 , 1 +ln(1) = 0.5 , 0.6904761904761905, 0.7 +ln(2) = 0.8333333333333333, 0.6944444444444444, 0.6932773109243697 +ln(3) = 0.5833333333333333, 0.6924242424242424, 0.6931488693329254 +ln(4) = 0.7833333333333333, 0.6935897435897436, 0.6931471960735491 +ln(5) = 0.6166666666666667, 0.6928571428571428, 0.6931471806635636 +ln(6) = 0.7595238095238095, 0.6933473389355742, 0.6931471805604038 +ln(7) = 0.6345238095238095, 0.6930033416875522, 0.6931471805599444 +ln(8) = 0.7456349206349207, 0.6932539682539682, 0.6931471805599426 +ln(9) = 0.6456349206349206, 0.6930657506744463, 0.6931471805599453 +ln = 0.6931471805599453, 0.6931471805599453, 0.6931471805599453 + +prime numbers: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Meter.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Meter.check new file mode 100644 index 0000000000..f46fd557c8 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/Meter.check @@ -0,0 +1,16 @@ +Meter.scala:72: warning: a.Meter and Int are unrelated: they will never compare equal + println("x == 1: "+(x == 1)) + ^ +2 +4m +false +x.isInstanceOf[Meter]: true +x.hashCode: 1 +x == 1: false +x == y: true +a == b: true +testing native arrays +Array(1m, 2m) +1m +>>>1m<<< 1m +>>>2m<<< 2m diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/MeterCaseClass.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/MeterCaseClass.check new file mode 100644 index 0000000000..ac538d240f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/MeterCaseClass.check @@ -0,0 +1,16 @@ +MeterCaseClass.scala:69: warning: comparing values of types a.Meter and Int using `==' will always yield false + println("x == 1: "+(x == 1)) + ^ +2 +Meter(4) +false +x.isInstanceOf[Meter]: true +x.hashCode: 1 +x == 1: false +x == y: true +a == b: true +testing native arrays +Array(Meter(1), Meter(2)) +Meter(1) +>>>Meter(1)<<< Meter(1) +>>>Meter(2)<<< Meter(2) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/bugs.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/bugs.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/bugs.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/caseClassHash.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/caseClassHash.check new file mode 100644 index 0000000000..f975151e9c --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/caseClassHash.check @@ -0,0 +1,9 @@ +Foo(true,-1,-1,d,-5,-10,500,500,List(),5) +Foo(true,-1,-1,d,-5,-10,500,500,List(),5) +1383698062 +1383698062 +true +## method 1: 1383698062 +## method 2: 1383698062 + Murmur 1: 1383698062 + Murmur 2: 1383698062 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/deeps.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/deeps.check new file mode 100644 index 0000000000..e533b87dc5 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/deeps.check @@ -0,0 +1,87 @@ +testEquals1 +false +false +true + +testEquals2 +false +false +true + +testEquals3 +x=Array(1) +y=Array(1) +false +false +true + +x=Array(Array(1), Array(1)) +y=Array(Array(1), Array(1)) +false +false +true + +x=Array(Array(Array(1), Array(1)), Array(Array(1), Array(1))) +y=Array(Array(Array(1), Array(1)), Array(Array(1), Array(1))) +false +false +true + +testEquals4 +false +false +true +false +false +true +Array(true, false) +Array(true, false) +[true;false] +true;false + +Array(Array(true, false), Array(true, false)) +Array(Array(true, false), Array(true, false)) +[Array(true, false);Array(true, false)] +Array(true, false);Array(true, false) + +Array(Array(Array(true, false), Array(true, false)), Array(Array(true, false), Array(true, false))) +Array(Array(Array(true, false), Array(true, false)), Array(Array(true, false), Array(true, false))) +[Array(Array(true, false), Array(true, false));Array(Array(true, false), Array(true, false))] +Array(Array(true, false), Array(true, false));Array(Array(true, false), Array(true, false)) + +Array(1, 0) +Array(1, 0) +[1;0] +1;0 + +Array(Array(1, 0), Array(1, 0)) +Array(Array(1, 0), Array(1, 0)) +[Array(1, 0);Array(1, 0)] +Array(1, 0);Array(1, 0) + +Array(Array(Array(1, 0), Array(1, 0)), Array(Array(1, 0), Array(1, 0))) +Array(Array(Array(1, 0), Array(1, 0)), Array(Array(1, 0), Array(1, 0))) +[Array(Array(1, 0), Array(1, 0));Array(Array(1, 0), Array(1, 0))] +Array(Array(1, 0), Array(1, 0));Array(Array(1, 0), Array(1, 0)) + +Array(a, b) +Array(a, b) +[a;b] +a;b + +Array(Array(a, b), Array(a, b)) +Array(Array(a, b), Array(a, b)) +[Array(a, b);Array(a, b)] +Array(a, b);Array(a, b) + +Array(Array(Array(a, b), Array(a, b)), Array(Array(a, b), Array(a, b))) +Array(Array(Array(a, b), Array(a, b)), Array(Array(a, b), Array(a, b))) +[Array(Array(a, b), Array(a, b));Array(Array(a, b), Array(a, b))] +Array(Array(a, b), Array(a, b));Array(Array(a, b), Array(a, b)) + +[Array(true, false); Array(false)] +[Array(1, 2); Array(3)] +[Array(1, 2); Array(3)] + +Array(boo, and, foo) +Array(a) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/delambdafy-specialized.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/delambdafy-specialized.check new file mode 100644 index 0000000000..a20ad22303 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/delambdafy-specialized.check @@ -0,0 +1 @@ +scala.runtime.AbstractFunction1 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/dynamic-anyval.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/dynamic-anyval.check new file mode 100644 index 0000000000..c125372c9a --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/dynamic-anyval.check @@ -0,0 +1,4 @@ +undefined.dingo(bippy, 5) +List(1, 2, 3).dingo(bippy, 5) +undefined.dingo(bippy, 5) +List(1, 2, 3).dingo(bippy, 5) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/impconvtimes.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/impconvtimes.check new file mode 100644 index 0000000000..082377e474 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/impconvtimes.check @@ -0,0 +1 @@ +3.0 * Hour = Measure(3,Hour) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/imports.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/imports.check new file mode 100644 index 0000000000..1aad598062 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/imports.check @@ -0,0 +1,21 @@ +In C_ico, v_ico .toString() returns ↩ +↪C_ico -> ok +In C_ico, field .toString() returns ↩ +↪C_ico -> ok +In C_ico, method.toString() returns ↩ +↪C_ico -> ok + +In C_ioc, v_ioc .toString() returns ↩ +↪C_ioc -> ok +In C_ioc, field .toString() returns ↩ +↪C_ioc -> ok +In C_ioc, method.toString() returns ↩ +↪C_ioc -> ok + +In C_oic, v_oic .toString() returns ↩ +↪C_oic -> ok +In C_oic, field .toString() returns ↩ +↪C_oic -> ok +In C_oic, method.toString() returns ↩ +↪C_oic -> ok + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/interpolation.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/interpolation.check new file mode 100644 index 0000000000..9c4a77715b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/interpolation.check @@ -0,0 +1,32 @@ +Bob is 1 years old +Bob is 1 years old +Bob will be 2 years old +Bob will be 2 years old +1+1 = 2 +1+1 = 2 +Bob is 12 years old +Bob is 12 years old +Bob will be 13 years old +Bob will be 13 years old +12+1 = 13 +12+1 = 13 +Bob is 123 years old +Bob is 123 years old +Bob will be 124 years old +Bob will be 124 years old +123+1 = 124 +123+1 = 124 +Best price: 10 +Best price: 10.00 +10% discount included +10.00% discount included +Best price: 13.345000267028809 +Best price: 13.35 +13.345000267028809% discount included +13.35% discount included + +0 +00 + +0 +00 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/interpolationMultiline1.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/interpolationMultiline1.check new file mode 100644 index 0000000000..1b6e140c13 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/interpolationMultiline1.check @@ -0,0 +1,26 @@ +Bob is 1 years old +Bob is 1 years old +Bob will be 2 years old +Bob will be 2 years old +1+1 = 2 +1+1 = 2 +Bob is 12 years old +Bob is 12 years old +Bob will be 13 years old +Bob will be 13 years old +12+1 = 13 +12+1 = 13 +Bob is 123 years old +Bob is 123 years old +Bob will be 124 years old +Bob will be 124 years old +123+1 = 124 +123+1 = 124 +Best price: 10 +Best price: 10.00 +10% discount included +10.00% discount included +Best price: 13.345000267028809 +Best price: 13.35 +13.345000267028809% discount included +13.35% discount included diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/issue192.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/issue192.sem new file mode 100644 index 0000000000..10abbf7f3b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/issue192.sem @@ -0,0 +1 @@ +strictFloats diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/macro-bundle-static.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/macro-bundle-static.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/macro-bundle-static.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/macro-bundle-toplevel.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/macro-bundle-toplevel.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/macro-bundle-toplevel.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/macro-bundle-whitebox-decl.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/macro-bundle-whitebox-decl.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/macro-bundle-whitebox-decl.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/misc.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/misc.check new file mode 100644 index 0000000000..6043817dbc --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/misc.check @@ -0,0 +1,62 @@ +misc.scala:46: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses + 42; + ^ +misc.scala:47: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses + 42l; + ^ +misc.scala:48: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses + 23.5f; + ^ +misc.scala:49: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses + 23.5; + ^ +misc.scala:50: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses + "Hello"; + ^ +misc.scala:51: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses + 32 + 45; + ^ +misc.scala:62: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses + x; + ^ +misc.scala:74: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses + 1 < 2; + ^ +### Hello +### 17 +### Bye + +### fib(0) = ↩ +↪1 +### fib(1) = ↩ +↪1 +### fib(2) = ↩ +↪2 +### fib(3) = ↩ +↪3 +### fib(4) = ↩ +↪5 +=== MyClass::toString === +=== MySubclass::toString === +=== MyClass::test === + +identity + +A.a = 1 +B.a = 5 +B.b = 2 + +X.a = 4 +Y.a = 11 +Y.b = 5 +Y.b = 5 + +X::foo + +Y::foo +X::foo + +3 +3 + +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/promotion.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/promotion.check new file mode 100644 index 0000000000..41e36c369d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/promotion.check @@ -0,0 +1,4 @@ +2 +6 +20 +30 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/runtime.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/runtime.check new file mode 100644 index 0000000000..0450b9498a --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/runtime.check @@ -0,0 +1,70 @@ +runtime.scala:141: warning: comparing values of types Null and Null using `eq' will always yield true + check(true , null eq null, null ne null); + ^ +runtime.scala:141: warning: comparing values of types Null and Null using `ne' will always yield false + check(true , null eq null, null ne null); + ^ +<<< Test0 +[false,true] +[0,1,2] +[3,4,5] +[a,b,c] +[6,7,8] +[9,10,11] +[12,13] +[14,15] +[string] +>>> Test0 + +<<< Test1 +10 +14 +15 +16 +20 +23 +24 +25 +26 +>>> Test1 + +<<< Test2 +A +M0 +N0 + +A +N0 +M0 + +A +M0 +M1 +N0 + +A +N0 +N1 +M0 + +>>> Test2 + +<<< Test3 +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +>>> Test3 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/spec-self.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/spec-self.check new file mode 100644 index 0000000000..fd3c81a4d7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/spec-self.check @@ -0,0 +1,2 @@ +5 +5 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/structural.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/structural.check new file mode 100644 index 0000000000..2fec112a87 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/structural.check @@ -0,0 +1,37 @@ + 1. hey + 2. 11 + 3. dee + 4. iei + 5. 6 + 6. 51 + 7. 2 + 8. 11 +10. 12 +11. eitch +12. 1 +13. ohone +14. 1 +15. undefined +16. one +17. tieone +18. 2 +19. true +20. 1 +21. undefined +22. one +23. oy +24. 1 +25. null +26. iei +31. 4 +32. undefined +33. iei +33. tieone +1 +2 +3 +4 +5 +caught +3 +2 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t0421-new.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t0421-new.check new file mode 100644 index 0000000000..00d29b7e5b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t0421-new.check @@ -0,0 +1,3 @@ +[Array(0, 1),Array(2, 3),Array(4, 5)] +[Array(31)] +[Array(24, 32)] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t0421-old.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t0421-old.check new file mode 100644 index 0000000000..00d29b7e5b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t0421-old.check @@ -0,0 +1,3 @@ +[Array(0, 1),Array(2, 3),Array(4, 5)] +[Array(31)] +[Array(24, 32)] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t1503.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t1503.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t1503.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t3702.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t3702.check new file mode 100644 index 0000000000..3fce98715c --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t3702.check @@ -0,0 +1,2 @@ +undefined +6 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t4148.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t4148.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t4148.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t4617.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t4617.check new file mode 100644 index 0000000000..a6790f16f7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t4617.check @@ -0,0 +1 @@ +Str 8 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t5356.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t5356.check new file mode 100644 index 0000000000..870c901131 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t5356.check @@ -0,0 +1,6 @@ +1 java.lang.Byte +1 java.lang.Byte +1 scala.math.BigInt +1 java.lang.Byte +1 java.lang.Byte +1 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t5552.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t5552.check new file mode 100644 index 0000000000..4704611116 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t5552.check @@ -0,0 +1,2 @@ +(3,3) +(3,3) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t5568.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t5568.check new file mode 100644 index 0000000000..6f30cc5070 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t5568.check @@ -0,0 +1,9 @@ +void +int +class scala.runtime.BoxedUnit +class scala.runtime.BoxedUnit +class java.lang.Byte +class java.lang.Byte +5 +5 +5 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t5629b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t5629b.check new file mode 100644 index 0000000000..c65298a6ce --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t5629b.check @@ -0,0 +1,10 @@ +=== pf(1): +MySmartPF.apply entered... +newPF.applyOrElse entered... +default +scala.MatchError: 1 (of class java.lang.Byte) +=== pf(42): +MySmartPF.apply entered... +newPF.applyOrElse entered... +ok +=== done diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t5680.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t5680.check new file mode 100644 index 0000000000..a3b8b64a43 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t5680.check @@ -0,0 +1,3 @@ +[Lscala.runtime.BoxedUnit +undefined +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t5866.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t5866.check new file mode 100644 index 0000000000..64df1cec7f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t5866.check @@ -0,0 +1,2 @@ +0 +Foo(0) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t6102.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t6102.check new file mode 100644 index 0000000000..3082267832 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t6102.check @@ -0,0 +1,28 @@ +[running phase parser on t6102.scala] +[running phase jspretyper on t6102.scala] +[running phase namer on t6102.scala] +[running phase packageobjects on t6102.scala] +[running phase typer on t6102.scala] +[running phase jsinterop on t6102.scala] +[running phase patmat on t6102.scala] +[running phase superaccessors on t6102.scala] +[running phase extmethods on t6102.scala] +[running phase pickler on t6102.scala] +[running phase refchecks on t6102.scala] +[running phase uncurry on t6102.scala] +[running phase tailcalls on t6102.scala] +[running phase specialize on t6102.scala] +[running phase explicitouter on t6102.scala] +[running phase erasure on t6102.scala] +[running phase posterasure on t6102.scala] +[running phase lazyvals on t6102.scala] +[running phase lambdalift on t6102.scala] +[running phase constructors on t6102.scala] +[running phase flatten on t6102.scala] +[running phase mixin on t6102.scala] +[running phase jscode on t6102.scala] +[running phase cleanup on t6102.scala] +[running phase delambdafy on t6102.scala] +[running phase icode on t6102.scala] +[running phase dce on t6102.scala] +[running phase jvm on icode] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t6318_primitives.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t6318_primitives.check new file mode 100644 index 0000000000..654ef1beec --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t6318_primitives.check @@ -0,0 +1,54 @@ +Checking if byte matches byte +Some(1) +Checking if byte matches short +Some(1) +Checking if class java.lang.Byte matches byte +Some(1) +Checking if short matches short +Some(1) +Checking if short matches char +None +Checking if class java.lang.Byte matches short +Some(1) +Checking if char matches char +Some() +Checking if char matches int +None +Checking if class java.lang.Character matches char +Some() +Checking if int matches int +Some(1) +Checking if int matches long +None +Checking if class java.lang.Byte matches int +Some(1) +Checking if long matches long +Some(1) +Checking if long matches float +None +Checking if class java.lang.Long matches long +Some(1) +Checking if float matches float +Some(1) +Checking if float matches double +Some(1) +Checking if class java.lang.Byte matches float +Some(1) +Checking if double matches double +Some(1) +Checking if double matches boolean +None +Checking if class java.lang.Byte matches double +Some(1) +Checking if boolean matches boolean +Some(true) +Checking if boolean matches void +None +Checking if class java.lang.Boolean matches boolean +Some(true) +Checking if void matches void +Some(undefined) +Checking if void matches byte +None +Checking if class scala.runtime.BoxedUnit matches void +Some(undefined) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t6662.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t6662.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t6662.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t7657.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t7657.check new file mode 100644 index 0000000000..1a87c1e866 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t7657.check @@ -0,0 +1,3 @@ +undefined +undefined +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t7763.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t7763.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t7763.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t8570a.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t8570a.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t8570a.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t8764.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t8764.check new file mode 100644 index 0000000000..121120217e --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t8764.check @@ -0,0 +1,5 @@ +IntOnly: should return an unboxed int +Int: int +IntAndDouble: should just box and return Anyval +Double: class java.lang.Byte +Int: class java.lang.Byte diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t9387b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t9387b.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t9387b.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/try-catch-unify.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/try-catch-unify.check new file mode 100644 index 0000000000..813f01166d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/try-catch-unify.check @@ -0,0 +1,4 @@ +Failure(java.lang.NumberFormatException: For input string: "Hi") +Success(5) +O NOES +Failure(java.lang.NumberFormatException: For input string: "Hi") diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/virtpatmat_switch.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/virtpatmat_switch.check new file mode 100644 index 0000000000..0900a9ca32 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/virtpatmat_switch.check @@ -0,0 +1,7 @@ +zero +one +many +got a +got b +got some letter +scala.MatchError: 5 (of class java.lang.Byte) \ No newline at end of file diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/virtpatmat_typetag.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/virtpatmat_typetag.check new file mode 100644 index 0000000000..048c3aeed0 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/virtpatmat_typetag.check @@ -0,0 +1,10 @@ +1 is a Int +1 is a java.lang.Integer +1 is not a java.lang.String; it's a class java.lang.Byte +true is a Any +woele is a java.lang.String +1 is a Int +1 is a java.lang.Integer +1 is not a java.lang.String; it's a class java.lang.Byte +true is a Any +woele is a java.lang.String diff --git a/project/Build.scala b/project/Build.scala index 4f421e07a1..3a13d3be86 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -65,7 +65,7 @@ object Build { CrossVersion.binaryMapped(v => s"sjs${previousSJSBinaryVersion}_$v") val scalaVersionsUsedForPublishing: Set[String] = - Set("2.10.7", "2.11.11", "2.12.4", "2.13.0-M2") + Set("2.10.7", "2.11.12", "2.12.4", "2.13.0-M2") val newScalaBinaryVersionsInThisRelease: Set[String] = Set() @@ -119,7 +119,7 @@ object Build { } val commonSettings = Seq( - scalaVersion := "2.11.11", + scalaVersion := "2.11.12", organization := "org.scala-js", version := scalaJSVersion, diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index b522f85f15..810f45eb35 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -6,7 +6,7 @@ version := scalaJSVersion val versionSettings = Seq( version := scalaJSVersion, - scalaVersion := "2.11.11" + scalaVersion := "2.11.12" ) val baseSettings = versionSettings ++ Seq( diff --git a/sbt-plugin-test/referencedCrossProject/build.sbt b/sbt-plugin-test/referencedCrossProject/build.sbt index 4539fcc61a..0183a472dc 100644 --- a/sbt-plugin-test/referencedCrossProject/build.sbt +++ b/sbt-plugin-test/referencedCrossProject/build.sbt @@ -1,7 +1,7 @@ lazy val referencedCrossProject = crossProject. crossType(CrossType.Pure). in(file(".")). - settings(scalaVersion := "2.11.11") + settings(scalaVersion := "2.11.12") lazy val referencedCrossProjectJS = referencedCrossProject.js lazy val referencedCrossProjectJVM = referencedCrossProject.jvm diff --git a/scala-test-suite/src/test/resources/2.11.12/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.11.12/BlacklistedTests.txt new file mode 100644 index 0000000000..67ab88dc99 --- /dev/null +++ b/scala-test-suite/src/test/resources/2.11.12/BlacklistedTests.txt @@ -0,0 +1,93 @@ +# Do not compile +scala/issues/BytecodeTests.scala +scala/reflect/QTest.scala +scala/reflect/io/ZipArchiveTest.scala +scala/reflect/internal/util/AbstractFileClassLoaderTest.scala +scala/reflect/internal/util/SourceFileTest.scala +scala/reflect/internal/util/StringOpsTest.scala +scala/reflect/internal/PrintersTest.scala +scala/reflect/internal/ScopeTest.scala +scala/reflect/internal/TypesTest.scala +scala/reflect/internal/util/WeakHashSetTest.scala +scala/reflect/internal/MirrorsTest.scala +scala/reflect/internal/NamesTest.scala +scala/tools/nsc/ScriptRunnerTest.scala +scala/tools/nsc/backend/jvm/BTypesTest.scala +scala/tools/nsc/backend/jvm/CodeGenTools.scala +scala/tools/nsc/backend/jvm/DirectCompileTest.scala +scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala +scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala +scala/tools/nsc/backend/jvm/opt/BTypesFromClassfileTest.scala +scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala +scala/tools/nsc/backend/jvm/opt/CompactLocalVariablesTest.scala +scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala +scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala +scala/tools/nsc/backend/jvm/opt/InlineInfoTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerIllegalAccessTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerTest.scala +scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala +scala/tools/nsc/backend/jvm/opt/MethodLevelOpts.scala +scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala +scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala +scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala +scala/tools/nsc/backend/jvm/opt/UnusedLocalVariablesTest.scala +scala/tools/nsc/classpath/AggregateFlatClassPathTest.scala +scala/tools/nsc/classpath/FlatClassPathResolverTest.scala +scala/tools/nsc/doc/html/HtmlDocletTest.scala +scala/tools/nsc/interpreter/CompletionTest.scala +scala/tools/nsc/interpreter/TabulatorTest.scala +scala/tools/nsc/settings/ScalaVersionTest.scala +scala/tools/nsc/settings/SettingsTest.scala +scala/tools/nsc/symtab/CannotHaveAttrsTest.scala +scala/tools/nsc/symtab/FlagsTest.scala +scala/tools/nsc/symtab/FreshNameExtractorTest.scala +scala/tools/nsc/symtab/StdNamesTest.scala +scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala +scala/tools/nsc/symtab/SymbolTableTest.scala +scala/tools/nsc/transform/delambdafy/DelambdafyTest.scala +scala/tools/nsc/transform/patmat/SolvingTest.scala +scala/tools/nsc/util/ClassPathImplComparator.scala +scala/tools/nsc/util/StackTraceTest.scala + +## Do not link +scala/StringContextTest.scala +scala/collection/IteratorTest.scala +scala/collection/ParallelConsistencyTest.scala +scala/collection/immutable/ListTest.scala +scala/collection/immutable/StringLikeTest.scala +scala/collection/mutable/ArrayBufferTest.scala +scala/collection/mutable/MutableListTest.scala +scala/collection/mutable/OpenHashMapTest.scala +scala/collection/mutable/PriorityQueueTest.scala +scala/concurrent/duration/SerializationTest.scala +scala/concurrent/impl/DefaultPromiseTest.scala +scala/io/SourceTest.scala +scala/runtime/ScalaRunTimeTest.scala +scala/tools/testing/AssertUtilTest.scala + +## Tests fail + +# Reflection +scala/reflect/ClassTag.scala +scala/tools/testing/AssertThrowsTest.scala + +# Regex +scala/util/matching/CharRegexTest.scala +scala/util/matching/RegexTest.scala + +# Require strict-floats +scala/math/BigDecimalTest.scala + +# Tests passed but are too slow (timeouts) +scala/collection/immutable/RangeConsistencyTest.scala +scala/collection/SetMapConsistencyTest.scala +scala/util/SortingTest.scala + +# Bugs +scala/collection/convert/MapWrapperTest.scala + +# Test fails only some times with +# 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' +# and' 'set scalaJSUseRhino in Global := false' +scala/collection/immutable/PagedSeqTest.scala diff --git a/scala-test-suite/src/test/resources/2.11.12/WhitelistedTests.txt b/scala-test-suite/src/test/resources/2.11.12/WhitelistedTests.txt new file mode 100644 index 0000000000..f958bfbfb8 --- /dev/null +++ b/scala-test-suite/src/test/resources/2.11.12/WhitelistedTests.txt @@ -0,0 +1,29 @@ +scala/collection/IndexedSeqOptimizedTest.scala +scala/collection/IndexedSeqTest.scala +scala/collection/IterableViewLikeTest.scala +scala/collection/SearchingTest.scala +scala/collection/TraversableOnceTest.scala +scala/collection/immutable/HashMapTest.scala +scala/collection/immutable/QueueTest.scala +scala/collection/immutable/SetTests.scala +scala/collection/immutable/TreeMapTest.scala +scala/collection/immutable/TreeSetTest.scala +scala/collection/immutable/VectorTest.scala +scala/collection/mutable/AnyRefMapTest.scala +scala/collection/mutable/ArrayBuilderTest.scala +scala/collection/mutable/ArraySortingTest.scala +scala/collection/mutable/BitSetTest.scala +scala/collection/mutable/LinkedHashMapTest.scala +scala/collection/mutable/LinkedHashSetTest.scala +scala/collection/mutable/SetLikeTest.scala +scala/collection/mutable/UnrolledBufferTest.scala +scala/collection/mutable/VectorTest.scala +scala/collection/mutable/WrappedArrayBuilderTest.scala +scala/math/NumericTest.scala +scala/math/OrderingTest.scala +scala/tools/nsc/SampleTest.scala +scala/tools/testing/AssertUtil.scala +scala/tools/testing/TempDir.scala +scala/util/RandomTest.scala +scala/util/SpecVersionTest.scala +scala/util/TryTest.scala diff --git a/scripts/assemble-cli.sh b/scripts/assemble-cli.sh index f1f61d3594..e4daf4e32f 100755 --- a/scripts/assemble-cli.sh +++ b/scripts/assemble-cli.sh @@ -16,8 +16,8 @@ case $BINVER in BASEVER="2.10.7" ;; 2.11) - FULLVERS="2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11" - BASEVER="2.11.11" + FULLVERS="2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.11.12" + BASEVER="2.11.12" ;; 2.12) FULLVERS="2.12.0 2.12.1 2.12.2 2.12.3 2.12.4" diff --git a/scripts/publish.sh b/scripts/publish.sh index 4752403097..42d8ec52b6 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -7,9 +7,9 @@ else CMD="echo sbt" fi -FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.10.7 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.12.0 2.12.1 2.12.2 2.12.3 2.12.4 2.13.0-M2" -BIN_VERSIONS="2.10.7 2.11.11 2.12.4 2.13.0-M2" -CLI_VERSIONS="2.10.7 2.11.11 2.12.4" +FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.10.7 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.11.12 2.12.0 2.12.1 2.12.2 2.12.3 2.12.4 2.13.0-M2" +BIN_VERSIONS="2.10.7 2.11.12 2.12.4 2.13.0-M2" +CLI_VERSIONS="2.10.7 2.11.12 2.12.4" SBT_VERSION="2.10.7" SBT1_VERSION="2.12.4" SBT1_SBTVERSION="1.0.0" diff --git a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/compiler/DefaultMethodsTest.scala b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/compiler/DefaultMethodsTest.scala index 7e881b21ef..0610f03a21 100644 --- a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/compiler/DefaultMethodsTest.scala +++ b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/compiler/DefaultMethodsTest.scala @@ -19,7 +19,7 @@ class DefaultMethodsTest { @Test def canOverrideDefaultMethod(): Unit = { assumeFalse("Affected by https://github.com/scala/bug/issues/10609", - executingInJVM && scalaVersion == "2.10.7") + executingInJVM && (scalaVersion == "2.10.7" || scalaVersion == "2.11.12")) var counter = 0 From ae504a46ef721a4018ba7f1fd90f10733af6821d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 14 Nov 2017 15:36:26 +0100 Subject: [PATCH 0541/2665] Fix #1265: Intrinsify `js.Dictionary.apply` and `js.Dynamic.literal`. To be more exact, they are both written in user-space as forwarders to a new method `js.special.objectLiteral`, which is itself an intrinsic. This improves the generated code for calls to `js.Dictionary.apply` with known variadic arguments. It will also improve the generated code for user-defined helpers that forward themselves to `js.Dictionary.apply` or `js.Dynamic.literal`. --- .../org/scalajs/core/compiler/GenJSCode.scala | 71 ----------------- .../scalajs/core/compiler/JSDefinitions.scala | 1 - .../scalajs/core/compiler/JSPrimitives.scala | 5 -- .../core/compiler/JSTreeExtractors.scala | 49 ------------ .../scala/scala/scalajs/js/Dictionary.scala | 9 +-- .../main/scala/scala/scalajs/js/Dynamic.scala | 4 +- .../scala/scalajs/js/special/package.scala | 25 ++++++ .../scala/scala/scalajs/runtime/package.scala | 8 -- .../frontend/optimizer/OptimizerCore.scala | 76 ++++++++++++++++++- 9 files changed, 105 insertions(+), 143 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 6a0b7aa261..7e15dce325 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -4030,77 +4030,6 @@ abstract class GenJSCode extends plugins.PluginComponent // js.Dynamic.newInstance(clazz)(actualArgs:_*) val (jsClass, actualArgs) = extractFirstArg(genArgs) js.JSNew(jsClass, actualArgs) - } else if (code == DYNLIT) { - /* We have a call of the form: - * js.Dynamic.literal(name1 = arg1, name2 = arg2, ...) - * or - * js.Dynamic.literal(name1 -> arg1, name2 -> arg2, ...) - * or in general - * js.Dynamic.literal(tup1, tup2, ...) - * - * Translate to: - * var obj = {}; - * obj[name1] = arg1; - * obj[name2] = arg2; - * ... - * obj - * or, if possible, to: - * {name1: arg1, name2: arg2, ... } - */ - - def keyToPropName(key: js.Tree, index: Int): js.PropertyName = key match { - case key: js.StringLiteral => key - case _ => js.ComputedName(key, "local" + index) - } - - /* Extract the first arg and discard it, since it has been checked by - * the front-end to be a constant string "apply". - */ - extractFirstArg(genArgs)._2 match { - // case js.Dynamic.literal("name1" -> ..., nameExpr2 -> ...) - case jse.Tuple2List(pairs) => - js.JSObjectConstr(pairs.zipWithIndex.map { - case ((key, value), index) => (keyToPropName(key, index), value) - }) - - /* case js.Dynamic.literal(x: _*) - * Even though scalac does not support this notation, it is still - * possible to write its expansion by hand: - * js.Dynamic.literal.applyDynamic("apply")(x: _*) - */ - case tups if tups.exists(_.isInstanceOf[js.JSSpread]) => - // Delegate to a runtime method - val tupsArray = tups match { - case List(js.JSSpread(tupsArray)) => tupsArray - case _ => js.JSArrayConstr(tups) - } - genApplyMethod( - genLoadModule(RuntimePackageModule), - Runtime_jsTupleArray2jsObject, - List(tupsArray)) - - // case js.Dynamic.literal(x, y) - case tups => - // Evaluate all tuples first - val tuple2Type = encodeClassType(TupleClass(2)) - val evalTuples = tups.map { tup => - js.VarDef(freshLocalIdent("tup"), tuple2Type, mutable = false, - tup)(tup.pos) - } - - // Build the resulting object - val result = js.JSObjectConstr(evalTuples.zipWithIndex.map { - case (evalTuple, index) => - val tupRef = evalTuple.ref - val key = genApplyMethod(tupRef, js.Ident("$$und1__O"), Nil, - jstpe.AnyType) - val value = genApplyMethod(tupRef, js.Ident("$$und2__O"), Nil, - jstpe.AnyType) - keyToPropName(key, index) -> value - }) - - js.Block(evalTuples :+ result) - } } else if (code == ARR_CREATE) { // js.Array.create(elements: _*) js.JSArrayConstr(genArgs) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 772bed6b20..07e4cc81f4 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -112,7 +112,6 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val Runtime_wrapJavaScriptException = getMemberMethod(RuntimePackageModule, newTermName("wrapJavaScriptException")) lazy val Runtime_unwrapJavaScriptException = getMemberMethod(RuntimePackageModule, newTermName("unwrapJavaScriptException")) lazy val Runtime_genTraversableOnce2jsArray = getMemberMethod(RuntimePackageModule, newTermName("genTraversableOnce2jsArray")) - lazy val Runtime_jsTupleArray2jsObject = getMemberMethod(RuntimePackageModule, newTermName("jsTupleArray2jsObject")) lazy val Runtime_constructorOf = getMemberMethod(RuntimePackageModule, newTermName("constructorOf")) lazy val Runtime_newConstructorTag = getMemberMethod(RuntimePackageModule, newTermName("newConstructorTag")) lazy val Runtime_propertiesOf = getMemberMethod(RuntimePackageModule, newTermName("propertiesOf")) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala index 36a9ddd278..6705d4bcd9 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala @@ -34,8 +34,6 @@ abstract class JSPrimitives { val DYNNEW = 321 // Instantiate a new JavaScript object - val DYNLIT = 334 // js.Dynamic.literal.applyDynamic{,Named} - val ARR_CREATE = 337 // js.Array.apply (array literal syntax) val TYPEOF = 344 // typeof x @@ -87,9 +85,6 @@ abstract class JSPrimitives { addPrimitive(JSDynamic_newInstance, DYNNEW) - addPrimitive(JSDynamicLiteral_applyDynamicNamed, DYNLIT) - addPrimitive(JSDynamicLiteral_applyDynamic, DYNLIT) - addPrimitive(JSArray_create, ARR_CREATE) addPrimitive(JSPackage_typeOf, TYPEOF) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSTreeExtractors.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSTreeExtractors.scala index 785f6fe3d2..0642d8e944 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSTreeExtractors.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSTreeExtractors.scala @@ -22,55 +22,6 @@ object JSTreeExtractors { }) } - /** A list of Tuple2, for example used as a list of key/value pairs - * (like in a call to applyDynamicNamed). - * - * Examples (Scala): - * {{{ - * method(("name1", x), ("name2", y)) - * method("name1" -> x, "name2" -> y) - * method(nameExpr1 -> x, (nameExpr2, y)) - * }}} - */ - object Tuple2List { - def unapply(exprs: List[Tree]): Option[List[(Tree, Tree)]] = { - val tuples = exprs.collect { - case Tuple2(key, value) => (key, value) - } - if (tuples.size == exprs.size) - Some(tuples) - else - None - } - } - - /** - * A literal Tuple2 - * - * Example (Scala): (x, y) - * But also (Scala): x -> y - */ - object Tuple2 { - def unapply(tree: Tree): Option[(Tree, Tree)] = tree match { - // case (x, y) - case New(ClassType("T2"), Ident("init___O__O", _), - List(_1, _2)) => - Some((_1, _2)) - // case x -> y - case Apply( - LoadModule(ClassType("s_Predef$ArrowAssoc$")), - Ident("$$minus$greater$extension__O__O__T2", _), - List( - Apply( - LoadModule(ClassType("s_Predef$")), - Ident("any2ArrowAssoc__O__O" | "ArrowAssoc__O__O", _), - List(_1)), - _2)) => - Some((_1, _2)) - case _ => - None - } - } } } diff --git a/library/src/main/scala/scala/scalajs/js/Dictionary.scala b/library/src/main/scala/scala/scalajs/js/Dictionary.scala index 2e951a185f..f031fea652 100644 --- a/library/src/main/scala/scala/scalajs/js/Dictionary.scala +++ b/library/src/main/scala/scala/scalajs/js/Dictionary.scala @@ -56,10 +56,7 @@ object Dictionary { @inline def empty[A]: js.Dictionary[A] = (new js.Object).asInstanceOf[js.Dictionary[A]] - def apply[A](properties: (String, A)*): js.Dictionary[A] = { - val result = empty[A] - for ((key, value) <- properties) - result(key) = value - result - } + @inline + def apply[A](properties: (String, A)*): js.Dictionary[A] = + js.special.objectLiteral(properties: _*).asInstanceOf[js.Dictionary[A]] } diff --git a/library/src/main/scala/scala/scalajs/js/Dynamic.scala b/library/src/main/scala/scala/scalajs/js/Dynamic.scala index 7fd9c5a166..e23774a4ad 100644 --- a/library/src/main/scala/scala/scalajs/js/Dynamic.scala +++ b/library/src/main/scala/scala/scalajs/js/Dynamic.scala @@ -131,7 +131,7 @@ object Dynamic { */ def applyDynamicNamed(name: String)( fields: (String, js.Any)*): js.Object with js.Dynamic = { - throw new java.lang.Error("stub") + js.special.objectLiteral(fields: _*).asInstanceOf[js.Object with js.Dynamic] } /* Note that the `def applyDynamic` could simply be `def apply`, but this @@ -149,7 +149,7 @@ object Dynamic { */ def applyDynamic(name: String)( fields: (String, js.Any)*): js.Object with js.Dynamic = { - throw new java.lang.Error("stub") + js.special.objectLiteral(fields: _*).asInstanceOf[js.Object with js.Dynamic] } } } diff --git a/library/src/main/scala/scala/scalajs/js/special/package.scala b/library/src/main/scala/scala/scalajs/js/special/package.scala index 26c4fc3ca4..d2917bbcc6 100644 --- a/library/src/main/scala/scala/scalajs/js/special/package.scala +++ b/library/src/main/scala/scala/scalajs/js/special/package.scala @@ -8,6 +8,9 @@ package scala.scalajs.js +import scala.scalajs.js +import scala.scalajs.js.annotation._ + /** Contains special primitives of interoperability with JavaScript which are * of limited importance or rare usefulness. * @@ -22,6 +25,28 @@ package scala.scalajs.js */ package object special { + @js.native + private trait FullyDynamicProps extends js.Object { + @JSBracketAccess + def update(prop: scala.Any, value: scala.Any): Unit = js.native + } + + /** Constructs a new object with the specified properties. + * + * This method is the exact equivalent of an object initializer in + * JavaScript (aka an object literal). + * + * In most cases, you should use a new anonymous JS class if you have a + * typed API, or [[js.Dynamic.literal]] in a dynamically typed setting. + */ + // intrinsic + def objectLiteral(properties: (scala.Any, scala.Any)*): js.Object = { + val result = new js.Object().asInstanceOf[FullyDynamicProps] + for (pair <- properties) + result(pair._1) = pair._2 + result + } + /** Tests whether an object has a given enumerable property in its prototype * chain. * diff --git a/library/src/main/scala/scala/scalajs/runtime/package.scala b/library/src/main/scala/scala/scalajs/runtime/package.scala index 8a7e1e81ea..76708ff355 100644 --- a/library/src/main/scala/scala/scalajs/runtime/package.scala +++ b/library/src/main/scala/scala/scalajs/runtime/package.scala @@ -38,14 +38,6 @@ package object runtime { } } - final def jsTupleArray2jsObject( - tuples: js.Array[(String, js.Any)]): js.Object with js.Dynamic = { - val result = js.Dynamic.literal() - for ((name, value) <- tuples) - result.updateDynamic(name)(value) - result - } - /** Dummy method used to preserve the type parameter of * `js.constructorOf[T]` through erasure. * diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index 0a24b02295..1a4d4ad580 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -2101,6 +2101,65 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { defaultApply("newInstance__jl_Class__I__O", AnyType) } + // js.special + + case ObjectLiteral => + def default = + defaultApply("objectLiteral__sc_Seq__sjs_js_Object", AnyType) + + val List(tprops) = targs + tprops match { + case PreTransMaybeBlock(bindingsAndStats, + PreTransLocalDef(LocalDef( + RefinedType(ClassType("sjs_js_WrappedArray"), _, _), + false, + InlineClassInstanceReplacement(_, wrappedArrayFields, _)))) => + assert(wrappedArrayFields.size == 1) + val jsArray = wrappedArrayFields.head._2 + jsArray.replacement match { + case InlineJSArrayReplacement(elemLocalDefs, _) + if elemLocalDefs.forall(e => isSubtype(e.tpe.base, ClassType("T2"))) => + val fields: List[(PropertyName, Tree)] = for { + (elemLocalDef, idx) <- elemLocalDefs.toList.zipWithIndex + } yield { + elemLocalDef match { + case LocalDef(RefinedType(ClassType("T2"), _, _), false, + InlineClassInstanceReplacement(recType, tupleFields, _)) => + val List(key, value) = + recType.fields.map(f => tupleFields(f.name)) + val keyProp = key.newReplacement match { + case keyProp: StringLiteral => + keyProp + case keyTree => + ComputedName(keyTree, "local" + idx) + } + (keyProp, value.newReplacement) + + case _ => + val key = Apply(elemLocalDef.newReplacement, "$$und1__O", Nil)(AnyType) + val value = Apply(elemLocalDef.newReplacement, "$$und2__O", Nil)(AnyType) + (ComputedName(key, "local" + idx), value) + } + } + + val resultTree = JSObjectConstr(fields) + + contTree(Block(finishTransformStat(optTReceiver.get), + finishTransformBindings(bindingsAndStats, resultTree))) + + case _ => + default + } + + case _ => + tprops.tpe match { + case RefinedType(ClassType("sci_Nil$"), _, false) => + contTree(Block(finishTransformStat(tprops), JSObjectConstr(Nil))) + case _ => + default + } + } + // TypedArray conversions case ByteArrayToInt8Array => @@ -4651,6 +4710,17 @@ private[optimizer] object OptimizerCore { Some(preTrans.bindingsAndStats, preTrans.result) } + private object PreTransMaybeBlock { + def unapply(preTrans: PreTransform): Some[(List[BindingOrStat], PreTransform)] = { + preTrans match { + case PreTransBlock(bindingsAndStats, result) => + Some((bindingsAndStats, result)) + case _ => + Some((Nil, preTrans)) + } + } + } + /** A `PreTransform` that can be the result of a `PreTransBlock`. * * This is basically any `PreTransform` except: @@ -4838,7 +4908,9 @@ private[optimizer] object OptimizerCore { final val ArrayNewInstance = ClassGetComponentType + 1 - final val ByteArrayToInt8Array = ArrayNewInstance + 1 + final val ObjectLiteral = ArrayNewInstance + 1 + + final val ByteArrayToInt8Array = ObjectLiteral + 1 final val ShortArrayToInt16Array = ByteArrayToInt8Array + 1 final val CharArrayToUint16Array = ShortArrayToInt16Array + 1 final val IntArrayToInt32Array = CharArrayToUint16Array + 1 @@ -4877,6 +4949,8 @@ private[optimizer] object OptimizerCore { "jl_reflect_Array$.newInstance__jl_Class__I__O" -> ArrayNewInstance, + "sjs_js_special_package$.objectLiteral__sc_Seq__sjs_js_Object" -> ObjectLiteral, + "sjs_js_typedarray_package$.byteArray2Int8Array__AB__sjs_js_typedarray_Int8Array" -> ByteArrayToInt8Array, "sjs_js_typedarray_package$.shortArray2Int16Array__AS__sjs_js_typedarray_Int16Array" -> ShortArrayToInt16Array, "sjs_js_typedarray_package$.charArray2Uint16Array__AC__sjs_js_typedarray_Uint16Array" -> CharArrayToUint16Array, From bc37c93cf5541c9dcbb8ec3b09abb585566d6c14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 14 Nov 2017 15:51:34 +0100 Subject: [PATCH 0542/2665] Use `js.special.objectLiteral` in `JSSymbolTest.mkObject`. In addition to producing nicer code for those tests, this change provides free tests for `objectLiteral` with symbols. --- .../testsuite/jsinterop/JSSymbolTest.scala | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala index a549283e2f..d0551048eb 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala @@ -274,13 +274,9 @@ object JSSymbolTest { import SJSDefinedWithSyms._ - def mkObject(members: (js.Symbol, js.Any)*): js.Object = { - val obj = (new js.Object).asInstanceOf[ObjectCreator] - for ((sym, member) <- members) { - obj(sym) = member - } - obj - } + @inline + def mkObject(members: (js.Symbol, js.Any)*): js.Object = + js.special.objectLiteral(members: _*) private def selectSymbol(obj: js.Any, sym: js.Symbol): Any = obj.asInstanceOf[SymDynamic].selectSymbol(sym) @@ -334,12 +330,6 @@ object JSSymbolTest { loop() } - @js.native - private trait ObjectCreator extends js.Object { - @JSBracketAccess - def update(s: js.Symbol, v: js.Any): Unit = js.native - } - trait PropDefTrait extends js.Any { @JSName(sym1) def internalDef: Int From edf9e9383c1a537f3575a462e44d47fa64610fbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 11 Nov 2017 15:25:22 +0100 Subject: [PATCH 0543/2665] Fix #3072: Enable the IR checker by default. This will help catching potential internal bugs during the Milestones and RC cycles. --- .../scala/org/scalajs/core/tools/linker/StandardLinker.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 ad0caa4662..03d6514bde 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 @@ -91,7 +91,7 @@ object StandardLinker { this( semantics = Semantics.Defaults, moduleKind = ModuleKind.NoModule, - checkIR = false, + checkIR = true, optimizer = true, parallel = true, sourceMap = true, @@ -191,7 +191,7 @@ object StandardLinker { * * - `semantics`: [[Semantics.Defaults]] * - `moduleKind`: [[ModuleKind.NoModule]] - * - `checkIR`: `false` + * - `checkIR`: `true` * - `optimizer`: `true` * - `parallel`: `true` * - `sourceMap`: `true` From 7c7670ed9f3f2da846a70b2d823501cee27d8d38 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 11 Nov 2017 20:24:11 +0100 Subject: [PATCH 0544/2665] Factor JS parameter checking in separate method --- .../core/tools/linker/checker/IRChecker.scala | 63 +++++++------------ 1 file changed, 21 insertions(+), 42 deletions(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 2805957d41..d2a6c651e5 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -313,21 +313,7 @@ private final class IRChecker(unit: LinkingUnit, reportError("Top level export must be static") checkExportedPropertyName(pName, classDef, isTopLevel) - - for (ParamDef(name, tpe, _, _) <- params) { - if (tpe == NoType) - reportError(s"Parameter $name has type NoType") - else if (tpe != AnyType) - reportError(s"Parameter $name of exported method def has type $tpe, "+ - "but must be Any") - } - - if (params.nonEmpty) { - for (ParamDef(name, _, _, rest) <- params.init) { - if (rest) - reportError(s"Non-last rest parameter $name is illegal") - } - } + checkJSParamDefs(params) def isJSConstructor = { !static && (pName match { @@ -468,20 +454,7 @@ private final class IRChecker(unit: LinkingUnit, return } - for (ParamDef(name, tpe, _, _) <- params) { - if (tpe == NoType) - reportError(s"Parameter $name has type NoType") - else if (tpe != AnyType) - reportError(s"Parameter $name of exported constructor def has type "+ - s"$tpe, but must be Any") - } - - if (params.nonEmpty) { - for (ParamDef(name, _, _, rest) <- params.init) { - if (rest) - reportError(s"Non-last rest parameter $name is illegal") - } - } + checkJSParamDefs(params) val thisType = ClassType(classDef.name.name) val bodyEnv = Env.fromSignature(thisType, params, NoType) @@ -1030,19 +1003,7 @@ private final class IRChecker(unit: LinkingUnit, reportError(s"Parameter $name has type NoType") } - for (ParamDef(name, ptpe, mutable, rest) <- params) { - if (ptpe == NoType) - reportError(s"Parameter $name has type NoType") - else if (ptpe != AnyType) - reportError(s"Closure parameter $name has type $ptpe instead of any") - } - - if (params.nonEmpty) { - for (ParamDef(name, _, _, rest) <- params.init) { - if (rest) - reportError(s"Non-last rest parameter $name is illegal") - } - } + checkJSParamDefs(params) val bodyEnv = Env.fromSignature( AnyType, captureParams ++ params, AnyType) @@ -1056,6 +1017,24 @@ private final class IRChecker(unit: LinkingUnit, tree.tpe } + /** Check the parameters for a method with JS calling conventions. */ + private def checkJSParamDefs(params: List[ParamDef])( + implicit ctx: ErrorContext): Unit = { + for (ParamDef(name, ptpe, mutable, rest) <- params) { + if (ptpe == NoType) + reportError(s"Parameter $name has type NoType") + else if (ptpe != AnyType) + reportError(s"Parameter $name has type $ptpe but must be any") + } + + if (params.nonEmpty) { + for (ParamDef(name, _, _, rest) <- params.init) { + if (rest) + reportError(s"Non-last rest parameter $name is illegal") + } + } + } + private def checkDeclareLabel(label: Ident)( implicit ctx: ErrorContext): Unit = { if (!declaredLabelNamesPerMethod.add(label.name)) From 83adae7208b34d71d8dec2cfe55a037c3a19772b Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 5 Nov 2017 19:48:01 +0100 Subject: [PATCH 0545/2665] Fix #2506: No duplicate vars in export dispatcher We rely on freshLocalIdent to avoid naming conflicts. As a consequence, we can change the IR checker to enforce local var uniqueness in method scope (not just block scope). --- .../scalajs/core/compiler/GenJSExports.scala | 5 ++- .../core/tools/linker/checker/IRChecker.scala | 37 ++++++++++--------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index 680f1b8856..329783518d 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -638,7 +638,8 @@ trait GenJSExports extends SubComponent { self: GenJSCode => // new WrappedArray(varargs) val rhs = genNew(WrappedArrayClass, WrappedArray_ctor, List( genVarargRef(normalArgc, minArgc))) - js.VarDef(js.Ident("prep" + normalArgc), rhs.tpe, mutable = false, rhs) + val ident = freshLocalIdent("prep" + normalArgc) + js.VarDef(ident, rhs.tpe, mutable = false, rhs) } // normal arguments @@ -681,7 +682,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => unboxedArg } - result += js.VarDef(js.Ident("prep" + i), + result += js.VarDef(freshLocalIdent("prep" + i), verifiedOrDefault.tpe, mutable = false, verifiedOrDefault) } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index d2a6c651e5..d2b8ff3408 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -38,14 +38,18 @@ private final class IRChecker(unit: LinkingUnit, /* Per-method state (setup with withPerMethodState). * This state is reset per-Closure as well. */ + private var declaredLocalVarNamesPerMethod: mutable.Set[String] = _ private var declaredLabelNamesPerMethod: mutable.Set[String] = _ private def withPerMethodState[A](body: => A): A = { + val savedDeclaredLocalVarNamesPerMethod = declaredLocalVarNamesPerMethod val savedDeclaredLabelNamesPerMethod = declaredLabelNamesPerMethod try { + declaredLocalVarNamesPerMethod = mutable.Set.empty declaredLabelNamesPerMethod = mutable.Set.empty body } finally { + declaredLocalVarNamesPerMethod = savedDeclaredLocalVarNamesPerMethod declaredLabelNamesPerMethod = savedDeclaredLabelNamesPerMethod } } @@ -256,6 +260,7 @@ private final class IRChecker(unit: LinkingUnit, } for (ParamDef(name, tpe, _, rest) <- params) { + checkDeclareLocalVar(name) if (tpe == NoType) reportError(s"Parameter $name has type NoType") if (rest) @@ -414,6 +419,7 @@ private final class IRChecker(unit: LinkingUnit, } setterArgAndBody.foreach { case (setterArg, setterBody) => + checkDeclareLocalVar(setterArg.name) if (setterArg.ptpe != AnyType) reportError("Setter argument of exported property def has type "+ s"${setterArg.ptpe}, but must be Any") @@ -485,6 +491,7 @@ private final class IRChecker(unit: LinkingUnit, tree match { case VarDef(ident, vtpe, mutable, rhs) => + checkDeclareLocalVar(ident) typecheckExpect(rhs, env, vtpe) env.withLocal(LocalDef(ident.name, vtpe, mutable)(tree.pos)) @@ -995,6 +1002,7 @@ private final class IRChecker(unit: LinkingUnit, // Then check the closure params and body in its own per-method state withPerMethodState { for (ParamDef(name, ctpe, mutable, rest) <- captureParams) { + checkDeclareLocalVar(name) if (mutable) reportError(s"Capture parameter $name cannot be mutable") if (rest) @@ -1020,7 +1028,8 @@ private final class IRChecker(unit: LinkingUnit, /** Check the parameters for a method with JS calling conventions. */ private def checkJSParamDefs(params: List[ParamDef])( implicit ctx: ErrorContext): Unit = { - for (ParamDef(name, ptpe, mutable, rest) <- params) { + for (ParamDef(name, ptpe, _, _) <- params) { + checkDeclareLocalVar(name) if (ptpe == NoType) reportError(s"Parameter $name has type NoType") else if (ptpe != AnyType) @@ -1035,6 +1044,12 @@ private final class IRChecker(unit: LinkingUnit, } } + private def checkDeclareLocalVar(ident: Ident)( + implicit ctx: ErrorContext): Unit = { + if (!declaredLocalVarNamesPerMethod.add(ident.name)) + reportError(s"Duplicate local variable name ${ident.name}.") + } + private def checkDeclareLabel(label: Ident)( implicit ctx: ErrorContext): Unit = { if (!declaredLabelNamesPerMethod.add(label.name)) @@ -1186,8 +1201,6 @@ private final class IRChecker(unit: LinkingUnit, new Env(thisTpe, this.locals, this.returnTypes, this.inConstructor) def withLocal(localDef: LocalDef)(implicit ctx: ErrorContext): Env = { - if (locals.contains(localDef.name)) - reportDuplicateLocalVarName(localDef.name) new Env(thisTpe, locals + (localDef.name -> localDef), returnTypes, this.inConstructor) } @@ -1209,23 +1222,13 @@ private final class IRChecker(unit: LinkingUnit, def fromSignature(thisType: Type, params: List[ParamDef], resultType: Type, isConstructor: Boolean = false): Env = { - val paramLocalDefs = params.foldLeft(Map.empty[String, LocalDef]) { - case (prevParams, p @ ParamDef(ident, tpe, mutable, _)) => - implicit val ctx = ErrorContext(p) - val name = ident.name - if (prevParams.contains(name)) - reportDuplicateLocalVarName(name) - prevParams + (name -> LocalDef(name, tpe, mutable)(p.pos)) - } - new Env(thisType, paramLocalDefs, + val paramLocalDefs = + for (p @ ParamDef(ident, tpe, mutable, _) <- params) + yield ident.name -> LocalDef(ident.name, tpe, mutable)(p.pos) + new Env(thisType, paramLocalDefs.toMap, Map(None -> (if (resultType == NoType) AnyType else resultType)), isConstructor) } - - private def reportDuplicateLocalVarName(name: String)( - implicit ctx: ErrorContext): Unit = { - reportError(s"Duplicate local variable name $name.") - } } private class CheckedClass( From 6a7a940976ba5f72785f15f74dbbb21b9d6a2d4c Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Thu, 16 Nov 2017 20:55:44 +0100 Subject: [PATCH 0546/2665] Replace last usage of json package in HTMLRunner --- .../scalajs/testadapter/HTMLRunnerBuilder.scala | 10 ++++------ .../org/scalajs/testinterface/TestDetector.scala | 14 ++++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala index af8f3fa5ae..cc31d78ec6 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala @@ -19,7 +19,6 @@ import org.scalajs.core.tools.io._ import org.scalajs.jsenv.VirtualFileMaterializer -import org.scalajs.testadapter.json._ import org.scalajs.testcommon.Serializer /** Template for the HTML runner. */ @@ -89,12 +88,11 @@ object HTMLRunnerBuilder { frameworkImplClassNames: List[List[String]], taskDefs: List[TaskDef]): String = { - val taskDefsString = Serializer.serialize(taskDefs) + def mkVar[T: Serializer](name: String, value: T) = + s"""var $name = "${Utils.escapeJS(Serializer.serialize(value))}";\n""" - s""" - var definedTests = ${jsonToString(taskDefsString.toJSON)}; - var testFrameworkNames = ${jsonToString(frameworkImplClassNames.toJSON)}; - """ + mkVar("definedTests", taskDefs) + + mkVar("testFrameworkNames", frameworkImplClassNames) } private def htmlEscaped(str: String): String = str.flatMap { diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala b/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala index e4447eff24..db4f12c17f 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala @@ -13,13 +13,15 @@ import sbt.testing._ /** Fetches test definitions and frameworks. */ private[scalajs] object TestDetector { def detectTests(): Seq[(Framework, Seq[TaskDef])] = { - import RawDefinitions._ + val taskDefs = Serializer.deserialize[List[TaskDef]]( + RawDefinitions.definedTests) - val taskDefs = Serializer.deserialize[List[TaskDef]](definedTests) - val frameworks = testFrameworkNames.flatMap(tryLoadFramework).toList + val frameworkNames = Serializer.deserialize[List[List[String]]]( + RawDefinitions.testFrameworkNames) for { - framework <- frameworks + nameAlternatives <- frameworkNames + framework <- tryLoadFramework(nameAlternatives).toList } yield { val fingerprints = framework.fingerprints() val eligibleTaskDefs = taskDefs.filter(taskDef => @@ -28,7 +30,7 @@ private[scalajs] object TestDetector { } } - private def tryLoadFramework(names: js.Array[String]): Option[Framework] = { + private def tryLoadFramework(names: List[String]): Option[Framework] = { def tryLoad(name: String): Option[Framework] = { Reflect.lookupInstantiatableClass(name).collect { case clazz if classOf[Framework].isAssignableFrom(clazz.runtimeClass) => @@ -56,6 +58,6 @@ private[scalajs] object TestDetector { @JSGlobalScope private object RawDefinitions extends js.Object { val definedTests: String = js.native - val testFrameworkNames: js.Array[js.Array[String]] = js.native + val testFrameworkNames: String = js.native } } From 674098dea528a625d33e3be1de50b704fc57b7b5 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Thu, 16 Nov 2017 18:31:06 +0100 Subject: [PATCH 0547/2665] Remove unneeded artifacts from old test interface This fixes #3084: Remove json package entirely --- project/Build.scala | 1 - project/build.sbt | 3 - .../scalajs/testadapter/RemoteException.scala | 50 --------------- .../testadapter/ScalaJSFramework.scala | 61 ------------------- .../scalajs/testadapter/ScalaJSRunner.scala | 21 ------- .../org/scalajs/testadapter/ScalaJSTask.scala | 24 -------- .../org/scalajs/testadapter/json/Impl.scala | 38 ------------ .../testadapter/json/JSONDeserializer.scala | 34 ----------- .../testadapter/json/JSONObjBuilder.scala | 20 ------ .../testadapter/json/JSONObjExtractor.scala | 13 ---- .../testadapter/json/JSONSerializer.scala | 34 ----------- .../scalajs/testadapter/json/package.scala | 33 ---------- 12 files changed, 332 deletions(-) delete mode 100644 test-adapter/src/main/scala/org/scalajs/testadapter/RemoteException.scala delete mode 100644 test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSFramework.scala delete mode 100644 test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSRunner.scala delete mode 100644 test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSTask.scala delete mode 100644 test-adapter/src/main/scala/org/scalajs/testadapter/json/Impl.scala delete mode 100644 test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONDeserializer.scala delete mode 100644 test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONObjBuilder.scala delete mode 100644 test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONObjExtractor.scala delete mode 100644 test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONSerializer.scala delete mode 100644 test-adapter/src/main/scala/org/scalajs/testadapter/json/package.scala diff --git a/project/Build.scala b/project/Build.scala index a58f721502..fb9d9556cb 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -602,7 +602,6 @@ object Build { commonToolsSettings, libraryDependencies ++= Seq( "org.scala-js" % "closure-compiler-java-6" % "v20160517", - "com.googlecode.json-simple" % "json-simple" % "1.1.1" exclude("junit", "junit"), "com.novocode" % "junit-interface" % "0.9" % "test" ) ++ ( parallelCollectionsDependencies(scalaVersion.value) diff --git a/project/build.sbt b/project/build.sbt index 6542180b73..d433bf0545 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -10,9 +10,6 @@ libraryDependencies += "org.scala-js" % "closure-compiler-java-6" % "v20160517" libraryDependencies += "org.eclipse.jgit" % "org.eclipse.jgit.pgm" % "3.2.0.201312181205-r" -libraryDependencies += "com.googlecode.json-simple" % "json-simple" % "1.1.1" exclude("junit", "junit") - - unmanagedSourceDirectories in Compile ++= { val root = baseDirectory.value.getParentFile Seq( diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/RemoteException.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/RemoteException.scala deleted file mode 100644 index 803a9f97f3..0000000000 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/RemoteException.scala +++ /dev/null @@ -1,50 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.testadapter - -import sbt.testing._ - -import org.scalajs.testadapter.json._ - -@deprecated("Unused. Is going to be removed.", "0.6.20.") -final class RemoteException private (msg: String, _toString: String, - cause: Throwable, val originalClass: String) extends Exception(msg, cause) { - override def toString(): String = _toString -} - -@deprecated("Unused. Is going to be removed.", "0.6.20.") -private[testadapter] object RemoteException { - implicit object StackTraceDeserializer extends JSONDeserializer[StackTraceElement] { - def deserialize(x: JSON): StackTraceElement = { - val obj = new JSONObjExtractor(x) - new StackTraceElement( - obj.fld[String]("className"), - obj.fld[String]("methodName"), - obj.fld[String]("fileName"), - obj.fld[Int]("lineNumber")) - } - } - - implicit object Deserializer extends JSONDeserializer[RemoteException] { - def deserialize(x: JSON): RemoteException = { - val obj = new JSONObjExtractor(x) - - val e = new RemoteException( - obj.fld[String]("message"), - obj.fld[String]("toString"), - obj.opt[RemoteException]("cause").orNull, - obj.fld[String]("class")) - - e.setStackTrace(obj.fld[List[StackTraceElement]]("stackTrace").toArray) - - e - } - } -} diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSFramework.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSFramework.scala deleted file mode 100644 index 0a7fcb17bc..0000000000 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSFramework.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.testadapter - -import org.scalajs.core.ir.Utils.escapeJS - -import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.logging._ -import org.scalajs.core.tools.linker.ModuleKind - -import org.scalajs.testadapter.json._ -import org.scalajs.jsenv._ -import org.scalajs.testcommon._ - -import sbt.testing.{Logger => _, _} - -/** A shim over [[TestAdapter]] for compatiblity. */ -@deprecated("Use TestAdapter instead.", "0.6.22") -final class ScalaJSFramework( - frameworkName: String, - jsEnv: ComJSEnv, - jsFiles: Seq[VirtualJSFile], - moduleKind: ModuleKind, - moduleIdentifier: Option[String], - logger: Logger -) extends Framework { - - def this(frameworkName: String, jsEnv: ComJSEnv, jsFiles: Seq[VirtualJSFile], - logger: Logger) = { - this(frameworkName, jsEnv, jsFiles, ModuleKind.NoModule, None, logger) - } - - private[this] val adapter = { - val config = TestAdapter.Config() - .withLogger(logger) - .withModuleSettings(moduleKind, moduleIdentifier) - - new TestAdapter(jsEnv, jsFiles, config) - } - - private[this] val realFramework = - adapter.loadFrameworks(List(List(frameworkName))).head.get - - def name: String = realFramework.name - - def fingerprints: Array[Fingerprint] = realFramework.fingerprints - - def runner(args: Array[String], remoteArgs: Array[String], - testClassLoader: ClassLoader): Runner = { - realFramework.runner(args, remoteArgs, testClassLoader) - } - - override protected def finalize(): Unit = adapter.close() -} diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSRunner.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSRunner.scala deleted file mode 100644 index 781d034a8e..0000000000 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSRunner.scala +++ /dev/null @@ -1,21 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.testadapter - -import sbt.testing._ - -/** Binary compat only. */ -@deprecated("Unused, use TestAdapter instead", "0.6.22") -final class ScalaJSRunner private () extends Runner { - def args(): Array[String] = ??? - def done(): String = ??? - def remoteArgs(): Array[String] = ??? - def tasks(x: Array[TaskDef]): Array[Task] = ??? -} diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSTask.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSTask.scala deleted file mode 100644 index 60f7cd5fe1..0000000000 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/ScalaJSTask.scala +++ /dev/null @@ -1,24 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.testadapter - -import sbt.testing._ - -/** Binary compat only. */ -@deprecated("Unused, use TestAdapter instead", "0.6.22") -final class ScalaJSTask private () extends Task { - def execute(x: EventHandler,y: Array[Logger]): Array[Task] = ??? - def tags(): Array[String] = ??? - def taskDef(): TaskDef = ??? -} - -/** Binary compat only. */ -@deprecated("Unused, use TestAdapter instead", "0.6.22") -object ScalaJSTask diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/json/Impl.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/json/Impl.scala deleted file mode 100644 index 696e59ed1b..0000000000 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/json/Impl.scala +++ /dev/null @@ -1,38 +0,0 @@ -package org.scalajs.testadapter.json - -import org.json.simple.JSONValue - -import scala.collection.JavaConverters._ - -import java.io.{Writer, Reader} - -private[json] object Impl { - - type Repr = Object - - def fromString(x: String): Repr = x - def fromNumber(x: Number): Repr = x - def fromBoolean(x: Boolean): Repr = java.lang.Boolean.valueOf(x) - def fromList(x: List[Repr]): Repr = x.asJava - def fromMap(x: Map[String, Repr]): Repr = x.asJava - - def toString(x: Repr): String = x.asInstanceOf[String] - def toNumber(x: Repr): Number = x.asInstanceOf[Number] - def toBoolean(x: Repr): Boolean = - x.asInstanceOf[java.lang.Boolean].booleanValue() - def toList(x: Repr): List[Repr] = - x.asInstanceOf[java.util.List[Repr]].asScala.toList - def toMap(x: Repr): Map[String, Repr] = - x.asInstanceOf[java.util.Map[String, Repr]].asScala.toMap - - def serialize(x: Repr): String = - JSONValue.toJSONString(x) - - def serialize(x: Repr, writer: Writer): Unit = - JSONValue.writeJSONString(x, writer) - - def deserialize(str: String): Repr = JSONValue.parse(str) - - def deserialize(reader: Reader): Repr = JSONValue.parse(reader) - -} diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONDeserializer.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONDeserializer.scala deleted file mode 100644 index 0daf3080e4..0000000000 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONDeserializer.scala +++ /dev/null @@ -1,34 +0,0 @@ -package org.scalajs.testadapter.json - -private[testadapter] trait JSONDeserializer[T] { - def deserialize(x: JSON): T -} - -private[testadapter] object JSONDeserializer { - - implicit object stringJSON extends JSONDeserializer[String] { - def deserialize(x: JSON): String = Impl.toString(x) - } - - implicit object intJSON extends JSONDeserializer[Int] { - def deserialize(x: JSON): Int = Impl.toNumber(x).intValue() - } - - implicit object booleanJSON extends JSONDeserializer[Boolean] { - def deserialize(x: JSON): Boolean = Impl.toBoolean(x) - } - - implicit def listJSON[T: JSONDeserializer]: JSONDeserializer[List[T]] = { - new JSONDeserializer[List[T]] { - def deserialize(x: JSON): List[T] = Impl.toList(x).map(fromJSON[T] _) - } - } - - implicit def mapJSON[V: JSONDeserializer]: JSONDeserializer[Map[String, V]] = { - new JSONDeserializer[Map[String, V]] { - def deserialize(x: JSON): Map[String, V] = - Impl.toMap(x).mapValues(fromJSON[V] _) - } - } - -} diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONObjBuilder.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONObjBuilder.scala deleted file mode 100644 index b419411347..0000000000 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONObjBuilder.scala +++ /dev/null @@ -1,20 +0,0 @@ -package org.scalajs.testadapter.json - -import scala.collection.mutable - -private[testadapter] class JSONObjBuilder { - - private val flds = mutable.Map.empty[String, JSON] - - def fld[T: JSONSerializer](name: String, v: T): this.type = { - flds.put(name, v.toJSON) - this - } - - def opt[T: JSONSerializer](name: String, v: Option[T]): this.type = { - v.foreach(v => flds.put(name, v.toJSON)) - this - } - - def toJSON: JSON = Impl.fromMap(flds.toMap) -} diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONObjExtractor.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONObjExtractor.scala deleted file mode 100644 index 4fc8e8a117..0000000000 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONObjExtractor.scala +++ /dev/null @@ -1,13 +0,0 @@ -package org.scalajs.testadapter.json - -import scala.collection.mutable - -private[testadapter] class JSONObjExtractor(rawData: JSON) { - private val data = Impl.toMap(rawData) - - def fld[T: JSONDeserializer](name: String): T = - fromJSON[T](data(name)) - - def opt[T: JSONDeserializer](name: String): Option[T] = - data.get(name).map(fromJSON[T] _) -} diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONSerializer.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONSerializer.scala deleted file mode 100644 index 0e3649440c..0000000000 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/json/JSONSerializer.scala +++ /dev/null @@ -1,34 +0,0 @@ -package org.scalajs.testadapter.json - -private[testadapter] trait JSONSerializer[T] { - def serialize(x: T): JSON -} - -private[testadapter] object JSONSerializer { - - implicit object stringJSON extends JSONSerializer[String] { - def serialize(x: String): JSON = Impl.fromString(x) - } - - implicit object intJSON extends JSONSerializer[Int] { - def serialize(x: Int): JSON = Impl.fromNumber(x) - } - - implicit object booleanJSON extends JSONSerializer[Boolean] { - def serialize(x: Boolean): JSON = Impl.fromBoolean(x) - } - - implicit def listJSON[T: JSONSerializer]: JSONSerializer[List[T]] = { - new JSONSerializer[List[T]] { - def serialize(x: List[T]): JSON = Impl.fromList(x.map(_.toJSON)) - } - } - - implicit def mapJSON[V: JSONSerializer]:JSONSerializer[Map[String, V]] = { - new JSONSerializer[Map[String, V]] { - def serialize(x: Map[String, V]): JSON = - Impl.fromMap(x.mapValues(_.toJSON)) - } - } - -} diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/json/package.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/json/package.scala deleted file mode 100644 index f74ef2172c..0000000000 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/json/package.scala +++ /dev/null @@ -1,33 +0,0 @@ -package org.scalajs.testadapter - -import java.io.{Reader, Writer} - -/** Some type-class lightweight wrappers around simple-json. - * - * They allow to write `xyz.toJSON` to obtain classes that can be - * serialized by simple-json and `fromJSON[T](xyz)` to get an - * object back. - */ -package object json { - private[testadapter] type JSON = Impl.Repr - - private[testadapter] implicit class JSONPimp[T: JSONSerializer](x: T) { - def toJSON: JSON = implicitly[JSONSerializer[T]].serialize(x) - } - - private[testadapter] def fromJSON[T](x: JSON)(implicit d: JSONDeserializer[T]): T = - d.deserialize(x) - - private[testadapter] def writeJSON(x: JSON, writer: Writer): Unit = - Impl.serialize(x, writer) - - private[testadapter] def jsonToString(x: JSON): String = - Impl.serialize(x) - - private[testadapter] def readJSON(str: String): JSON = - Impl.deserialize(str) - - private[testadapter] def readJSON(reader: Reader): JSON = - Impl.deserialize(reader) - -} From 282c667063fe71d296b03cdd0c40ad4621413f6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 15 Nov 2017 12:00:18 +0100 Subject: [PATCH 0548/2665] Move the logic of hashCode for JS objects to `identityHashCode`. Previously, it was a bit weird that `$objectHashCode` had to test for the existence of the `$idHashMap` before calling `$systemIdentityHashCode`. It is now entirely the responsibility of the latter. --- ci/checksizes.sh | 2 +- .../src/main/scala/java/lang/System.scala | 10 ++++- tools/scalajsenv.js | 41 ++++++++++--------- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/ci/checksizes.sh b/ci/checksizes.sh index 7d068b29bb..6729dcba00 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -43,7 +43,7 @@ case $FULLVER in REVERSI_OPT_GZ_EXPECTEDSIZE=30000 ;; 2.11.12) - REVERSI_PREOPT_EXPECTEDSIZE=505000 + REVERSI_PREOPT_EXPECTEDSIZE=506000 REVERSI_OPT_EXPECTEDSIZE=116000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=69000 REVERSI_OPT_GZ_EXPECTEDSIZE=30000 diff --git a/javalanglib/src/main/scala/java/lang/System.scala b/javalanglib/src/main/scala/java/lang/System.scala index c978ed3495..59bfe97a0f 100644 --- a/javalanglib/src/main/scala/java/lang/System.scala +++ b/javalanglib/src/main/scala/java/lang/System.scala @@ -162,7 +162,15 @@ object System { case _ => import IDHashCode._ if (x.getClass == null) { - // This is not a Scala.js object: delegate to x.hashCode() + /* x is not a Scala.js object: we have delegate to x.hashCode(). + * This is very important, as we really need to go through + * `$objectHashCode()` in `scalajsenv.js` instead of using our own + * `idHashCodeMap`. That's because `$objectHashCode()` uses the + * intrinsic `$systemIdentityHashCode` for JS objects, regardless of + * whether the optimizer is enabled or not. If we use our own + * `idHashCodeMap`, we will get different hash codes when obtained + * through `System.identityHashCode(x)` than with `x.hashCode()`. + */ x.hashCode() } else if (assumingES6 || idHashCodeMap != null) { // Use the global WeakMap of attributed id hash codes diff --git a/tools/scalajsenv.js b/tools/scalajsenv.js index a965bbbadf..8fb12f6927 100644 --- a/tools/scalajsenv.js +++ b/tools/scalajsenv.js @@ -352,10 +352,6 @@ function $objectHashCode(instance) { return instance.hashCode__I(); else if ($isChar(instance)) return instance.c; -//!if outputMode != ECMAScript6 - else if ($idHashCodeMap === null) - return 42; -//!endif else return $systemIdentityHashCode(instance); } @@ -581,22 +577,27 @@ const $systemIdentityHashCode = //!if outputMode != ECMAScript6 }) : (function(obj) { - if ($isScalaJSObject(obj)) { - let hash = obj["$idHashCode$0"]; - if (hash !== void 0) { - return hash; - } else if (!Object["isSealed"](obj)) { - hash = ($lastIDHash + 1) | 0; - $lastIDHash = hash; - obj["$idHashCode$0"] = hash; - return hash; - } else { - return 42; - } - } else if (obj === null) { - return 0; - } else { - return $objectHashCode(obj); + switch (typeof obj) { + case "string": case "number": case "boolean": case "undefined": + return $objectHashCode(obj); + default: + if ($isScalaJSObject(obj)) { + let hash = obj["$idHashCode$0"]; + if (hash !== void 0) { + return hash; + } else if (!Object["isSealed"](obj)) { + hash = ($lastIDHash + 1) | 0; + $lastIDHash = hash; + obj["$idHashCode$0"] = hash; + return hash; + } else { + return 42; + } + } else if (obj === null) { + return 0; + } else { + return 42; + } } //!endif }); From 51e870d60f10ec2fe97c45643cce5e74ac14b27b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 16 Nov 2017 11:41:12 +0100 Subject: [PATCH 0549/2665] Fix the user-space implementation of java.lang.{Float|Double}.equals. It was broken for the comparison between +0.0 and -0.0. However, that implementation is never actually used, since those two methods were neither inlined by the optimizer nor called at run-time (due to the hijacked class treatment). --- .../src/main/scala/java/lang/Double.scala | 22 +++++++++++++------ .../src/main/scala/java/lang/Float.scala | 10 ++------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/javalanglib/src/main/scala/java/lang/Double.scala b/javalanglib/src/main/scala/java/lang/Double.scala index 31a444c66a..c33e353849 100644 --- a/javalanglib/src/main/scala/java/lang/Double.scala +++ b/javalanglib/src/main/scala/java/lang/Double.scala @@ -19,13 +19,21 @@ final class Double private () extends Number with Comparable[Double] { @inline def longValue(): scala.Long = doubleValue.toLong @inline def floatValue(): scala.Float = doubleValue.toFloat - override def equals(that: Any): scala.Boolean = that match { - case that: Double => - val a = doubleValue - val b = that.doubleValue - (a == b) || (Double.isNaN(a) && Double.isNaN(b)) - case _ => - false + override def equals(that: Any): scala.Boolean = { + /* Since Double is hijacked as primitive numbers, reference equality (eq) + * is equivalent to value equality (==). We use `eq` here as an + * optimization to avoid the type test on the right-hand-side: since we + * know that `this` is a number, if `this eq that`, then so is `that`. And + * in the else branch, `that ne that` is true if and only if `that` is + * `NaN` (hence `false` if it is not a number to begin with). + */ + if (this eq that.asInstanceOf[AnyRef]) { + // 0.0.equals(-0.0) must be false + doubleValue != 0.0 || (1/doubleValue == 1/that.asInstanceOf[scala.Double]) + } else { + // NaN.equals(NaN) must be true + (this ne this) && (that.asInstanceOf[AnyRef] ne that.asInstanceOf[AnyRef]) + } } @inline override def hashCode(): Int = diff --git a/javalanglib/src/main/scala/java/lang/Float.scala b/javalanglib/src/main/scala/java/lang/Float.scala index 791ed35089..b691dc4843 100644 --- a/javalanglib/src/main/scala/java/lang/Float.scala +++ b/javalanglib/src/main/scala/java/lang/Float.scala @@ -17,14 +17,8 @@ final class Float private () extends Number with Comparable[Float] { @inline def longValue(): scala.Long = floatValue.toLong @inline def doubleValue(): scala.Double = floatValue.toDouble - override def equals(that: Any): scala.Boolean = that match { - case that: Double => // yes, Double - val a = doubleValue - val b = that.doubleValue - (a == b) || (Double.isNaN(a) && Double.isNaN(b)) - case _ => - false - } + @inline override def equals(that: Any): scala.Boolean = + doubleValue.equals(that) @inline override def hashCode(): Int = Float.hashCode(floatValue) From 1c12d85dd08fd0cb4c57c4b60a998b7279fb9580 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 16 Nov 2017 17:41:48 +0100 Subject: [PATCH 0550/2665] Actually use the implementations of hijacked classes in the emitter. Previously, the instance methods of hijacked classes were thrown away by the emitter. Instead, we relied on a duplicate implementation of those methods in the form of helpers in `scalajsenv.js`. Those helpers were doing both the dispatch that would normally be done by method calls, and the actual body of the methods. Now, the body of the methods of hijacked classes is generated using normal method emission. They take their `this` argument as an explicit parameter, just like default methods. The helpers in `scalajsenv.js` only do the dispatch, and delegate to those generated "hijacked methods". In addition, for monomorphic calls (when the receiver of an `Apply` is known to be a specific hijacked class), the function emitter generates code that directly calls the hijacked method, bypassing run-time dispatch. This means that the methods that can *only* be called monomorphically, such as `$isNaN`, do not need to be in `scalajsenv.js` at all anymore. The fact that the bodies are not written in `scalajsenv.js` means that the Emitter does not need to explicitly declare symbol requirements for those bodies. This has only marginal effect, but it does allow to get rid of `Double$.compare__D__D__I`. The fastopt.js size does increase because the methods for `toString`, `hashCode` and `equals` of all hijacked classes are emitted, although almost none of them are actually ever called. GCC can get rid of those, though, so it does not impact opt.js. --- ci/checksizes.sh | 6 +- tools/scalajsenv.js | 170 +++++++----------- .../linker/backend/emitter/ClassEmitter.scala | 7 + .../linker/backend/emitter/Emitter.scala | 13 +- .../backend/emitter/FunctionEmitter.scala | 124 ++++++++----- 5 files changed, 160 insertions(+), 160 deletions(-) diff --git a/ci/checksizes.sh b/ci/checksizes.sh index 6729dcba00..63c6c8203f 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -37,7 +37,7 @@ REVERSI_OPT_GZ_SIZE=$(stat '-c%s' "$REVERSI_OPT.gz") case $FULLVER in 2.10.2) - REVERSI_PREOPT_EXPECTEDSIZE=509000 + REVERSI_PREOPT_EXPECTEDSIZE=511000 REVERSI_OPT_EXPECTEDSIZE=115000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=69000 REVERSI_OPT_GZ_EXPECTEDSIZE=30000 @@ -49,13 +49,13 @@ case $FULLVER in REVERSI_OPT_GZ_EXPECTEDSIZE=30000 ;; 2.12.4) - REVERSI_PREOPT_EXPECTEDSIZE=604000 + REVERSI_PREOPT_EXPECTEDSIZE=606000 REVERSI_OPT_EXPECTEDSIZE=138000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=74000 REVERSI_OPT_GZ_EXPECTEDSIZE=32000 ;; 2.13.0-M2) - REVERSI_PREOPT_EXPECTEDSIZE=602000 + REVERSI_PREOPT_EXPECTEDSIZE=604000 REVERSI_OPT_EXPECTEDSIZE=138000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=74000 REVERSI_OPT_GZ_EXPECTEDSIZE=32000 diff --git a/tools/scalajsenv.js b/tools/scalajsenv.js index 8fb12f6927..3571a4b98a 100644 --- a/tools/scalajsenv.js +++ b/tools/scalajsenv.js @@ -246,13 +246,6 @@ function $newArrayObjectInternal(arrayClassData, lengths, lengthIndex) { return result; }; -function $objectToString(instance) { - if (instance === void 0) - return "undefined"; - else - return instance.toString(); -}; - function $objectGetClass(instance) { switch (typeof instance) { case "string": @@ -291,176 +284,145 @@ function $objectGetClass(instance) { } }; -function $objectClone(instance) { +function $dp_toString__T(instance) { + if (instance === void 0) + return "undefined"; + else + return instance.toString(); +}; + +function $dp_getClass__jl_Class(instance) { + return $objectGetClass(instance); +}; + +function $dp_clone__O(instance) { if ($isScalaJSObject(instance) || (instance === null)) return instance.clone__O(); else throw new $c_jl_CloneNotSupportedException().init___(); }; -function $objectNotify(instance) { +function $dp_notify__V(instance) { // final and no-op in java.lang.Object if (instance === null) instance.notify__V(); }; -function $objectNotifyAll(instance) { +function $dp_notifyAll__V(instance) { // final and no-op in java.lang.Object if (instance === null) instance.notifyAll__V(); }; -function $objectFinalize(instance) { +function $dp_finalize__V(instance) { if ($isScalaJSObject(instance) || (instance === null)) instance.finalize__V(); // else no-op }; -function $objectEquals(instance, rhs) { +function $dp_equals__O__Z(instance, rhs) { if ($isScalaJSObject(instance) || (instance === null)) return instance.equals__O__Z(rhs); else if (typeof instance === "number") - return typeof rhs === "number" && $numberEquals(instance, rhs); + return $f_jl_Double__equals__O__Z(instance, rhs); else if ($isChar(instance)) - return $isChar(rhs) && instance.c === rhs.c; + return $f_jl_Character__equals__O__Z(instance, rhs); else return instance === rhs; }; -function $numberEquals(lhs, rhs) { - return (lhs === rhs) ? ( - // 0.0.equals(-0.0) must be false - lhs !== 0 || 1/lhs === 1/rhs - ) : ( - // are they both NaN? - (lhs !== lhs) && (rhs !== rhs) - ); -}; - -function $objectHashCode(instance) { +function $dp_hashCode__I(instance) { switch (typeof instance) { case "string": - return $m_sjsr_RuntimeString$().hashCode__T__I(instance); + return $f_T__hashCode__I(instance); case "number": - return $m_sjsr_Bits$().numberHashCode__D__I(instance); + return $f_jl_Double__hashCode__I(instance); case "boolean": - return instance ? 1231 : 1237; + return $f_jl_Boolean__hashCode__I(instance); case "undefined": - return 0; + return $f_sr_BoxedUnit__hashCode__I(instance); default: if ($isScalaJSObject(instance) || instance === null) return instance.hashCode__I(); else if ($isChar(instance)) - return instance.c; + return $f_jl_Character__hashCode__I(instance); else return $systemIdentityHashCode(instance); } }; -function $comparableCompareTo(instance, rhs) { +function $dp_compareTo__O__I(instance, rhs) { switch (typeof instance) { case "string": -//!if asInstanceOfs != Unchecked - $as_T(rhs); -//!endif - return instance === rhs ? 0 : (instance < rhs ? -1 : 1); + return $f_T__compareTo__O__I(instance, rhs); case "number": -//!if asInstanceOfs != Unchecked - $as_jl_Number(rhs); -//!endif - return $m_jl_Double$().compare__D__D__I(instance, rhs); + return $f_jl_Double__compareTo__O__I(instance, rhs); case "boolean": -//!if asInstanceOfs != Unchecked - $asBoolean(rhs); -//!endif - return instance - rhs; // yes, this gives the right result + return $f_jl_Boolean__compareTo__O__I(instance, rhs); default: - if ($isChar(instance)) { -//!if asInstanceOfs != Unchecked - $asChar(rhs); -//!endif - return instance.c - rhs.c; - } else { + if ($isChar(instance)) + return $f_jl_Character__compareTo__O__I(instance, rhs); + else return instance.compareTo__O__I(rhs); - } } }; -function $charSequenceLength(instance) { +function $dp_length__I(instance) { if (typeof(instance) === "string") -//!if asInstanceOfs != Unchecked - return $uI(instance["length"]); -//!else - return instance["length"] | 0; -//!endif + return $f_T__length__I(instance); else return instance.length__I(); }; -function $charSequenceCharAt(instance, index) { +function $dp_charAt__I__C(instance, index) { if (typeof(instance) === "string") -//!if asInstanceOfs != Unchecked - return $uI(instance["charCodeAt"](index)) & 0xffff; -//!else - return instance["charCodeAt"](index) & 0xffff; -//!endif + return $f_T__charAt__I__C(instance, index); else return instance.charAt__I__C(index); }; -function $charSequenceSubSequence(instance, start, end) { +function $dp_subSequence__I__I__jl_CharSequence(instance, start, end) { if (typeof(instance) === "string") -//!if asInstanceOfs != Unchecked - return $as_T(instance["substring"](start, end)); -//!else - return instance["substring"](start, end); -//!endif + return $f_T__subSequence__I__I__jl_CharSequence(instance, start, end); else return instance.subSequence__I__I__jl_CharSequence(start, end); }; -function $booleanBooleanValue(instance) { - if (typeof instance === "boolean") return instance; - else return instance.booleanValue__Z(); -}; - -function $characterCharValue(instance) { - return instance.c; -} - -function $numberByteValue(instance) { - if (typeof instance === "number") return (instance << 24) >> 24; - else return instance.byteValue__B(); +function $dp_byteValue__B(instance) { + if (typeof instance === "number") + return $f_jl_Double__byteValue__B(instance); + else + return instance.byteValue__B(); }; -function $numberShortValue(instance) { - if (typeof instance === "number") return (instance << 16) >> 16; - else return instance.shortValue__S(); +function $dp_shortValue__S(instance) { + if (typeof instance === "number") + return $f_jl_Double__shortValue__S(instance); + else + return instance.shortValue__S(); }; -function $numberIntValue(instance) { - if (typeof instance === "number") return instance | 0; - else return instance.intValue__I(); +function $dp_intValue__I(instance) { + if (typeof instance === "number") + return $f_jl_Double__intValue__I(instance); + else + return instance.intValue__I(); }; -function $numberLongValue(instance) { +function $dp_longValue__J(instance) { if (typeof instance === "number") - return $m_sjsr_RuntimeLong$().fromDouble__D__sjsr_RuntimeLong(instance); + return $f_jl_Double__longValue__J(instance); else return instance.longValue__J(); }; -function $numberFloatValue(instance) { - if (typeof instance === "number") return $fround(instance); - else return instance.floatValue__F(); -}; -function $numberDoubleValue(instance) { - if (typeof instance === "number") return instance; - else return instance.doubleValue__D(); -}; - -function $isNaN(instance) { - return instance !== instance; +function $dp_floatValue__F(instance) { + if (typeof instance === "number") + return $f_jl_Double__floatValue__F(instance); + else + return instance.floatValue__F(); }; - -function $isInfinite(instance) { - return !isFinite(instance) && !$isNaN(instance); +function $dp_doubleValue__D(instance) { + if (typeof instance === "number") + return $f_jl_Double__doubleValue__D(instance); + else + return instance.doubleValue__D(); }; function $doubleToInt(x) { @@ -560,7 +522,7 @@ const $systemIdentityHashCode = (function(obj) { switch (typeof obj) { case "string": case "number": case "boolean": case "undefined": - return $objectHashCode(obj); + return $dp_hashCode__I(obj); default: if (obj === null) { return 0; @@ -579,7 +541,7 @@ const $systemIdentityHashCode = (function(obj) { switch (typeof obj) { case "string": case "number": case "boolean": case "undefined": - return $objectHashCode(obj); + return $dp_hashCode__I(obj); default: if ($isScalaJSObject(obj)) { let hash = obj["$idHashCode$0"]; diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index 8ba6b38707..07e6d39b8b 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -474,6 +474,13 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { } } + /** Generates an instance method of a hijacked class. */ + def genHijackedMethod(className: String, method: MethodDef)( + implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { + // We abuse `genDefaultMethod` as it does everything the way we want + genDefaultMethod(className, method) + } + /** Generates a property. */ def genProperty(className: String, property: PropertyDef)( implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { diff --git 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 index 15e3e64d69..12f3f1e9ea 100644 --- 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 @@ -398,6 +398,13 @@ final class Emitter private (config: CommonPhaseConfig, addToMain(methodCache.getOrElseUpdate(m.version, classEmitter.genDefaultMethod(className, m.value)(methodCache))) } + } else if (kind == ClassKind.HijackedClass) { + // Hijacked methods + for (m <- linkedClass.memberMethods) yield { + val methodCache = classCache.getMethodCache(m.value.encodedName) + addToMain(methodCache.getOrElseUpdate(m.version, + classEmitter.genHijackedMethod(className, m.value)(methodCache))) + } } if (classEmitter.needInstanceTests(linkedClass)) { @@ -670,9 +677,6 @@ private object Emitter { instantiateClass("jl_Class", "init___jl_ScalaJSClassData"), - callOnModule("jl_Double$", "compare__D__D__I"), - callOnModule("sjsr_RuntimeString$", "hashCode__T__I"), - instanceTests(LongImpl.RuntimeLongClass), instantiateClass(LongImpl.RuntimeLongClass, LongImpl.AllConstructors), callMethods(LongImpl.RuntimeLongClass, LongImpl.AllMethods), @@ -681,8 +685,7 @@ private object Emitter { cond(strictFloats && !assumingES6) { callOnModule("sjsr_package$", "froundPolyfill__D__D") - }, - callOnModule("sjsr_Bits$", "numberHashCode__D__I") + } ) } diff --git 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 index ea0f73f2ea..db1ef4a3cd 100644 --- 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 @@ -1912,21 +1912,64 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { genSelectStatic(cls.className, item) case Apply(receiver, method, args) => + import Definitions._ + + val methodName = method.name val newReceiver = transformExprNoChar(receiver) val newArgs = transformTypedArgs(method.name, args) - /* If the receiver is maybe a hijacked class instance, and there - * exists a hijacked method helper for the method, use it. Methods - * that do not have helpers are - * - Reflective proxies - * - Methods of RuntimeLong that are not also in java.lang.Long - */ + def genNormalApply(): js.Tree = + js.Apply(newReceiver DOT transformPropIdent(method), newArgs) + + def genDispatchApply(): js.Tree = + genCallHelper("dp_" + methodName, newReceiver :: newArgs: _*) + + def genHijackedMethodApply(className: String): js.Tree = { + val fullName = className + "__" + methodName + js.Apply(envField("f", fullName, method.originalName), + newReceiver :: newArgs) + } + if (isMaybeHijackedClass(receiver.tpe) && - hijackedClassMethodToHelperName.contains(method.name)) { - val helperName = hijackedClassMethodToHelperName(method.name) - genCallHelper(helperName, newReceiver :: newArgs: _*) + !isReflProxyName(methodName)) { + receiver.tpe match { + case AnyType => + genDispatchApply() + + case LongType | ClassType(BoxedLongClass) => + // All methods of java.lang.Long are also in RuntimeLong + genNormalApply() + + case _ if hijackedMethodsInheritedFromObject.contains(methodName) => + /* Methods inherited from j.l.Object do not have a dedicated + * hijacked method that we can call, even when we know the + * precise type of the receiver. Therefore, we always have to + * go through the dispatcher in those cases. + * + * Note that when the optimizer is enabled, if the receiver + * had a precise type, the method would have been inlined + * anyway (because all the affected methods are @inline). + * Therefore this roundabout of dealing with this does not + * prevent any optimization. + */ + genDispatchApply() + + case ClassType(cls) if !HijackedClasses.contains(cls) => + /* This is a strict ancestor of a hijacked class. We need to + * use the dispatcher available in the helper method. + */ + genDispatchApply() + + case tpe => + /* This is a concrete hijacked class or its corresponding + * primitive type. Directly call the hijacked method. Note that + * there might not even be a dispatcher for this method, so + * this is important. + */ + genHijackedMethodApply(typeToBoxedHijackedClass(tpe)) + } } else { - js.Apply(newReceiver DOT transformPropIdent(method), newArgs) + genNormalApply() } case ApplyStatically(receiver, cls, method, args) => @@ -2336,44 +2379,29 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { false } - val hijackedClassMethodToHelperName: Map[String, String] = Map( - "getClass__jl_Class" -> "objectGetClass", - "toString__T" -> "objectToString", - "clone__O" -> "objectClone", - "finalize__V" -> "objectFinalize", - "notify__V" -> "objectNotify", - "notifyAll__V" -> "objectNotifyAll", - "equals__O__Z" -> "objectEquals", - "hashCode__I" -> "objectHashCode", - - "length__I" -> "charSequenceLength", - "charAt__I__C" -> "charSequenceCharAt", - "subSequence__I__I__jl_CharSequence" -> "charSequenceSubSequence", - - "compareTo__O__I" -> "comparableCompareTo", - "compareTo__jl_Boolean__I" -> "comparableCompareTo", - "compareTo__jl_Character__I" -> "comparableCompareTo", - "compareTo__jl_Byte__I" -> "comparableCompareTo", - "compareTo__jl_Short__I" -> "comparableCompareTo", - "compareTo__jl_Integer__I" -> "comparableCompareTo", - "compareTo__jl_Long__I" -> "comparableCompareTo", - "compareTo__jl_Float__I" -> "comparableCompareTo", - "compareTo__jl_Double__I" -> "comparableCompareTo", - "compareTo__jl_String__I" -> "comparableCompareTo", - - "booleanValue__Z" -> "booleanBooleanValue", - - "charValue__C" -> "characterCharValue", - - "byteValue__B" -> "numberByteValue", - "shortValue__S" -> "numberShortValue", - "intValue__I" -> "numberIntValue", - "longValue__J" -> "numberLongValue", - "floatValue__F" -> "numberFloatValue", - "doubleValue__D" -> "numberDoubleValue", - - "isNaN__Z" -> "isNaN", - "isInfinite__Z" -> "isInfinite" + def typeToBoxedHijackedClass(tpe: Type): String = (tpe: @unchecked) match { + case ClassType(cls) => cls + case AnyType => Definitions.ObjectClass + case UndefType => Definitions.BoxedUnitClass + case BooleanType => Definitions.BoxedBooleanClass + case CharType => Definitions.BoxedCharacterClass + case ByteType => Definitions.BoxedByteClass + case ShortType => Definitions.BoxedShortClass + case IntType => Definitions.BoxedIntegerClass + case LongType => Definitions.BoxedLongClass + case FloatType => Definitions.BoxedFloatClass + case DoubleType => Definitions.BoxedDoubleClass + case StringType => Definitions.StringClass + } + + /* Ideally, we should dynamically figure out this set. We should test + * whether a particular method is defined in the receiver's hijacked + * class: if not, it must be inherited. However, this would require + * additional global knowledge for no practical reason. + */ + val hijackedMethodsInheritedFromObject: Set[String] = Set( + "getClass__jl_Class", "clone__O", "finalize__V", "notify__V", + "notifyAll__V" ) private def transformParamDef(paramDef: ParamDef): js.ParamDef = { From 12715a4272883c79be72471ef7cf5435a4e15003 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 17 Nov 2017 11:35:58 +0100 Subject: [PATCH 0551/2665] Bye bye RuntimeString: use a complete String class in the IR. Previously, the `String` class in the IR was truncated to a very small subset of its methods. It only had the methods that override or implement methods from its ancestors. Those were critical because the class hierarchy would otherwise be bogus. All other methods, however, were only part of `RuntimeString` (including static methods). It was the compiler's responsibility to rewire calls to those methods to `RuntimeString`. We had done this because all the methods in hijacked classes had to have a duplicated implementation in hand-written JavaScript, in `scalajsenv.js`. It would have been not only tedious to duplicate the large number of methods of `String` in `scalajsenv.js`, but also would have had serious consequences on DCE, given that all the methods in `scalajsenv.js` have to be considered reachable. Now, the parent commit has changed the rules of the game: only methods that are potentially polymorphic need a dispatcher in `scalajsenv.js`. All other methods are generated from the IR. This means that we can implement all these other methods of `String` only once in the IR, and not worry about JavaScript code or DCE. In this commit, we therefore make `String` more like the other hijacked classes, having the implementations of all its methods, written in a proper .scala source file in `javalanglib/` (as opposed to having hard-coded IR in the build). There is a small catch, though: scalac does not like to be given `String` to compile. Therefore, we write the class and its companion object as if they were named `_String`. We add a piece of magic in the compiler to rename `java.lang._String` into `java.lang.String` when generating its IR. One would think this makes the new situation no better than what we had before (special-casing `String` in the compiler) but there is a fundamental difference: we only need this magic when compiling `String.scala` itself, not when compiling clients of `String`. The magic is therefore contained within our build, instead of being specified in the public definition of the IR. --- .../org/scalajs/core/compiler/GenJSCode.scala | 144 ++---- .../scalajs/core/compiler/GenJSFiles.scala | 7 +- .../scalajs/core/compiler/JSDefinitions.scala | 6 +- .../scalajs/core/compiler/JSEncoding.scala | 40 +- .../src/main/scala/java/lang/_String.scala | 461 +++++++++++++++++ .../scala/scalajs/runtime/RuntimeString.scala | 464 ------------------ project/Build.scala | 5 +- project/JavaLangString.scala | 165 ------- .../backend/emitter/FunctionEmitter.scala | 37 ++ 9 files changed, 564 insertions(+), 765 deletions(-) create mode 100644 javalanglib/src/main/scala/java/lang/_String.scala delete mode 100644 library/src/main/scala/scala/scalajs/runtime/RuntimeString.scala delete mode 100644 project/JavaLangString.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 7e15dce325..d7a053fd8e 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -359,7 +359,7 @@ abstract class GenJSCode extends plugins.PluginComponent } val classIdent = encodeClassFullNameIdent(sym) - val isHijacked = isHijackedBoxedClass(sym) + val isHijacked = sym == HackedStringClass || isHijackedBoxedClass(sym) // Optimizer hints @@ -1462,7 +1462,8 @@ abstract class GenJSCode extends plugins.PluginComponent OptimizerHints.empty, None)) } else if (isJSNativeCtorDefaultParam(sym)) { None - } else if (sym.isClassConstructor && isHijackedBoxedClass(sym.owner)) { + } else if (sym.isClassConstructor && + (sym.owner == HackedStringClass || isHijackedBoxedClass(sym.owner))) { None } else if (scalaUsesImplClasses && !sym.owner.isImplClass && sym.hasAnnotation(JavaDefaultMethodAnnotation)) { @@ -2439,7 +2440,7 @@ abstract class GenJSCode extends plugins.PluginComponent assert(ctor.isClassConstructor, "'new' call to non-constructor: " + ctor.name) - if (isStringType(tpe)) { + if (clsSym == StringClass) { genNewString(tree) } else if (isHijackedBoxedClass(clsSym)) { genNewHijackedBoxedClass(clsSym, ctor, args map genExpr) @@ -2579,14 +2580,7 @@ abstract class GenJSCode extends plugins.PluginComponent val Apply(fun @ Select(receiver, _), args) = tree val sym = fun.symbol - def isStringMethodFromObject: Boolean = sym.name match { - case nme.toString_ | nme.equals_ | nme.hashCode_ => true - case _ => false - } - - if (sym.owner == StringClass && !isStringMethodFromObject) { - genStringCall(tree) - } else if (isJSType(receiver.tpe) && sym.owner != ObjectClass) { + if (isJSType(receiver.tpe) && sym.owner != ObjectClass) { if (!isNonNativeJSClass(sym.owner) || isExposed(sym)) genPrimitiveJSCall(tree, isStat) else @@ -3810,56 +3804,45 @@ abstract class GenJSCode extends plugins.PluginComponent })(jstpe.AnyType) } - /* Look for a matching method in String. If we find one, we must - * redirect it to RuntimeString. + /* Add an explicit type test for a hijacked class with a call to a + * hijacked method, if applicable (i.e., if there is a matching method + * in the given hijacked class). This is necessary because hijacked + * classes of the IR do not support reflective proxy calls. + * + * Returns true if this treatment was applicable. */ - val methodInStringClass = matchingSymIn(StringClass) - if (methodInStringClass != NoSymbol && methodInStringClass.isPublic) { - callStatement = js.If(genIsInstanceOf(callTrg, StringClass.tpe), { - if (methodInStringClass.owner == ObjectClass) { - // If the method is defined on Object, we can call it normally. - genApplyMethod(callTrg, methodInStringClass, arguments) - } else { - // Otherwise, we need to call it on RuntimeString - val (rtModuleClass, methodIdent) = - encodeRTStringMethodSym(methodInStringClass) - val retTpe = methodInStringClass.tpe.resultType - val castCallTrg = fromAny(callTrg, StringClass.toTypeConstructor) + def addCallToHijackedMethodIfApplicable(hijackedClass: Symbol): Boolean = { + val hijackedMethod = matchingSymIn(hijackedClass) + val isApplicable = + hijackedMethod != NoSymbol && hijackedMethod.isPublic + if (isApplicable) { + val hijackedClassTpe = hijackedClass.tpe + callStatement = js.If(genIsInstanceOf(callTrg, hijackedClassTpe), { boxIfNeeded( - genApplyMethod( - genLoadModule(rtModuleClass), - methodIdent, - castCallTrg :: arguments, - toIRType(retTpe)), - retTpe) - } - }, { // else - callStatement - })(jstpe.AnyType) + genApplyMethod(genAsInstanceOf(callTrg, hijackedClassTpe), + hijackedMethod, arguments), + hijackedMethod.tpe.resultType) + }, { // else + callStatement + })(jstpe.AnyType) + } + isApplicable } + // String is a hijacked class + addCallToHijackedMethodIfApplicable(StringClass) + /* For primitive types, we need to handle two cases. The method could - * either be defined in the boxed class of the primitive type, or it - * could be defined in the primitive class itself. In the former case, - * we generate a direct call to the actual (hijacked) method. In the - * latter case, we directly generate the primitive operation. + * either be defined in the boxed class of the primitive type (which is + * hijacked), or it could be defined in the primitive class itself. + * If the hijacked class treatment is not applicable, we also try the + * primitive treatment, in which case we directly generate the + * primitive operation. */ def addCallForPrimitive(primitiveClass: Symbol): Boolean = { val boxedClass = definitions.boxedClass(primitiveClass) - val boxedTpe = boxedClass.tpe - val methodInBoxedClass = matchingSymIn(boxedClass) - if (methodInBoxedClass != NoSymbol && methodInBoxedClass.isPublic) { - callStatement = js.If(genIsInstanceOf(callTrg, boxedTpe), { - boxIfNeeded( - genApplyMethod( - genAsInstanceOf(callTrg, boxedTpe), - methodInBoxedClass, - arguments), - methodInBoxedClass.tpe.resultType) - }, { // else - callStatement - })(jstpe.AnyType) + if (addCallToHijackedMethodIfApplicable(boxedClass)) { true } else { val methodInPrimClass = matchingSymIn(primitiveClass) @@ -3878,6 +3861,7 @@ abstract class GenJSCode extends plugins.PluginComponent // Fall through to the Int case that will come next false } else { + val boxedTpe = boxedClass.tpe callStatement = js.If(genIsInstanceOf(callTrg, boxedTpe), { val castCallTrg = makePrimitiveUnbox(callTrg, primitiveClass.tpe) @@ -4356,52 +4340,15 @@ abstract class GenJSCode extends plugins.PluginComponent val ctor = fun.symbol val args = args0 map genExpr - // Filter members of target module for matching member - val compMembers = for { - mem <- RuntimeStringModule.tpe.members - if mem.name == jsnme.newString && ctor.tpe.matches(mem.tpe) - } yield mem - - if (compMembers.isEmpty) { - reporter.error(pos, - s"""Could not find implementation for constructor of java.lang.String - |with type ${ctor.tpe}. Constructors on java.lang.String - |are forwarded to the companion object of - |scala.scalajs.runtime.RuntimeString""".stripMargin) - js.Undefined() - } else { - assert(compMembers.size == 1, - s"""For constructor with type ${ctor.tpe} on java.lang.String, - |found multiple companion module members.""".stripMargin) - - // Emit call to companion object - genApplyMethod( - genLoadModule(RuntimeStringModule), compMembers.head, args) + val js.Ident(initName, origName) = encodeMethodSym(ctor) + val newStringMethodName = initName match { + case "init___" => "newString__T" + case _ => "newString" + initName.stripPrefix("init_") + "__T" } - } - - /** Gen JS code for calling a method on java.lang.String. - * - * Forwards call on java.lang.String to the module - * scala.scalajs.runtime.RuntimeString. - */ - private def genStringCall(tree: Apply): js.Tree = { - implicit val pos = tree.pos - - val sym = tree.symbol - - // Deconstruct tree and create receiver and argument JS expressions - val Apply(Select(receiver0, _), args0) = tree - val receiver = genExpr(receiver0) - val args = args0 map genExpr + val newStringMethodIdent = js.Ident(newStringMethodName, origName) - // Emit call to the RuntimeString module - val (rtModuleClass, methodIdent) = encodeRTStringMethodSym(sym) - genApplyMethod( - genLoadModule(rtModuleClass), - methodIdent, - receiver :: args, - toIRType(tree.tpe)) + genApplyMethod(genLoadModule(StringModule), newStringMethodIdent, args, + jstpe.ClassType(ir.Definitions.StringClass)) } /** Gen JS code for a new of a raw JS class (subclass of js.Any) */ @@ -5235,10 +5182,7 @@ abstract class GenJSCode extends plugins.PluginComponent require(sym0.isModuleOrModuleClass, "genLoadModule called with non-module symbol: " + sym0) - val sym1 = if (sym0.isModule) sym0.moduleClass else sym0 - val sym = // redirect all static methods of String to RuntimeString - if (sym1 == StringModule) RuntimeStringModule.moduleClass - else sym1 + val sym = if (sym0.isModule) sym0.moduleClass else sym0 // Does that module refer to the global scope? if (sym.hasAnnotation(JSGlobalScopeAnnotation)) { diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSFiles.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSFiles.scala index a55db832a2..bb804abb56 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSFiles.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSFiles.scala @@ -34,7 +34,12 @@ trait GenJSFiles extends SubComponent { self: GenJSCode => val baseDir: AbstractFile = settings.outputDirs.outputDirFor(cunit.source.file) - val pathParts = sym.fullName.split("[./]") + val fullName = sym.fullName match { + case "java.lang._String" => "java.lang.String" + case fullName => fullName + } + + val pathParts = fullName.split("[./]") val dir = (baseDir /: pathParts.init)(_.subdirectoryNamed(_)) var filename = pathParts.last diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 07e4cc81f4..899acc8108 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -23,6 +23,9 @@ trait JSDefinitions { self: JSGlobalAddons => class JSDefinitionsClass { + lazy val HackedStringClass = getClassIfDefined("java.lang._String") + lazy val HackedStringModClass = getModuleIfDefined("java.lang._String").moduleClass + lazy val ScalaJSJSPackage = getPackage(newTermNameCached("scala.scalajs.js")) // compat 2.10/2.11 lazy val JSPackage_typeOf = getMemberMethod(ScalaJSJSPackage, newTermName("typeOf")) lazy val JSPackage_constructorOf = getMemberMethod(ScalaJSJSPackage, newTermName("constructorOf")) @@ -99,9 +102,6 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val Special_delete = getMemberMethod(SpecialPackageModule, newTermName("delete")) lazy val Special_debugger = getMemberMethod(SpecialPackageModule, newTermName("debugger")) - lazy val RuntimeStringModule = getRequiredModule("scala.scalajs.runtime.RuntimeString") - lazy val RuntimeStringModuleClass = RuntimeStringModule.moduleClass - lazy val BooleanReflectiveCallClass = getRequiredClass("scala.scalajs.runtime.BooleanReflectiveCall") lazy val CharacterReflectiveCallClass = getRequiredClass("scala.scalajs.runtime.CharacterReflectiveCall") lazy val NumberReflectiveCallClass = getRequiredClass("scala.scalajs.runtime.NumberReflectiveCall") diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala index 1f5d22da54..2061999ecc 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala @@ -137,28 +137,8 @@ trait JSEncoding extends SubComponent { self: GenJSCode => encodedName + paramsString } - /** Encodes a method symbol of java.lang.String for use in RuntimeString. - * - * This basically means adding an initial parameter of type - * java.lang.String, which is the `this` parameter. - */ - def encodeRTStringMethodSym(sym: Symbol)( - implicit pos: Position): (Symbol, js.Ident) = { - require(sym.isMethod, "encodeMethodSym called with non-method symbol: " + sym) - require(sym.owner == definitions.StringClass) - require(!sym.isClassConstructor && !sym.isPrivate) - - val (encodedName, paramsString) = - encodeMethodNameInternal(sym, inRTClass = true) - val methodIdent = js.Ident(encodedName + paramsString, - Some(sym.unexpandedName.decoded + paramsString)) - - (jsDefinitions.RuntimeStringModuleClass, methodIdent) - } - private def encodeMethodNameInternal(sym: Symbol, - reflProxy: Boolean = false, - inRTClass: Boolean = false): (String, String) = { + reflProxy: Boolean): (String, String) = { require(sym.isMethod, "encodeMethodSym called with non-method symbol: " + sym) def name = encodeMemberNameInternal(sym) @@ -176,7 +156,7 @@ trait JSEncoding extends SubComponent { self: GenJSCode => mangleJSName(name) } - val paramsString = makeParamsString(sym, reflProxy, inRTClass) + val paramsString = makeParamsString(sym, reflProxy) (encodedName, paramsString) } @@ -221,8 +201,14 @@ trait JSEncoding extends SubComponent { self: GenJSCode => } def encodeClassFullName(sym: Symbol): String = { - ir.Definitions.encodeClassName( - sym.fullName + (if (needsModuleClassSuffix(sym)) "$" else "")) + if (sym == jsDefinitions.HackedStringClass) { + ir.Definitions.StringClass + } else if (sym == jsDefinitions.HackedStringModClass) { + "jl_String$" + } else { + ir.Definitions.encodeClassName( + sym.fullName + (if (needsModuleClassSuffix(sym)) "$" else "")) + } } def needsModuleClassSuffix(sym: Symbol): Boolean = @@ -238,14 +224,12 @@ trait JSEncoding extends SubComponent { self: GenJSCode => // Encoding of method signatures - private def makeParamsString(sym: Symbol, reflProxy: Boolean, - inRTClass: Boolean): String = { + private def makeParamsString(sym: Symbol, reflProxy: Boolean): String = { val tpe = sym.tpe val paramTypeNames0 = tpe.params map (p => internalName(p.tpe)) - val hasExplicitThisParameter = - inRTClass || isNonNativeJSClass(sym.owner) + val hasExplicitThisParameter = isNonNativeJSClass(sym.owner) val paramTypeNames = if (!hasExplicitThisParameter) paramTypeNames0 else internalName(sym.owner.toTypeConstructor) :: paramTypeNames0 diff --git a/javalanglib/src/main/scala/java/lang/_String.scala b/javalanglib/src/main/scala/java/lang/_String.scala new file mode 100644 index 0000000000..0d8c96d214 --- /dev/null +++ b/javalanglib/src/main/scala/java/lang/_String.scala @@ -0,0 +1,461 @@ +package java.lang + +import java.util.Comparator + +import scala.scalajs.js +import scala.scalajs.js.annotation._ +import js.JSStringOps._ + +import java.nio.ByteBuffer +import java.nio.charset.Charset +import java.util.regex._ + +/* This is the implementation of java.lang.String, which is a hijacked class. + * Its instances are primitive strings. Constructors are not emitted. + * + * It should be declared as `class String`, but scalac really does not like + * being forced to compile java.lang.String, so we call it `_String` instead. + * The Scala.js compiler back-end applies some magic to rename it into `String` + * when emitting the IR. + */ +final class _String private () // scalastyle:ignore + extends AnyRef with java.io.Serializable with Comparable[String] + with CharSequence { + + import _String._ + + @inline + private def thisString: String = + this.asInstanceOf[String] + + @inline + private def thisJSString: SpecialJSStringOps = + this.asInstanceOf[SpecialJSStringOps] + + @inline + def charAt(index: Int): Char = + thisJSString.charCodeAt(index).toChar + + def codePointAt(index: Int): Int = { + val high = charAt(index) + if (index+1 < length) { + val low = charAt(index+1) + if (Character.isSurrogatePair(high, low)) + Character.toCodePoint(high, low) + else + high.toInt + } else { + high.toInt + } + } + + def codePointBefore(index: Int): Int = { + val low = charAt(index - 1) + if (index > 1) { + val high = charAt(index - 2) + if (Character.isSurrogatePair(high, low)) + Character.toCodePoint(high, low) + else + low.toInt + } else { + low.toInt + } + } + + def codePointCount(beginIndex: Int, endIndex: Int): Int = { + if (endIndex > length || beginIndex < 0 || endIndex < beginIndex) + throw new IndexOutOfBoundsException + var res = endIndex - beginIndex + var i = beginIndex + val end = endIndex - 1 + while (i < end) { + if (Character.isSurrogatePair(charAt(i), charAt(i + 1))) + res -= 1 + i += 1 + } + res + } + + def offsetByCodePoints(index: Int, codePointOffset: Int): Int = { + val len = length + if (index < 0 || index > len) + throw new StringIndexOutOfBoundsException(index) + + if (codePointOffset >= 0) { + var i = 0 + var result = index + while (i != codePointOffset) { + if (result >= len) + throw new StringIndexOutOfBoundsException + if ((result < len - 1) && + Character.isHighSurrogate(charAt(result)) && + Character.isLowSurrogate(charAt(result + 1))) { + result += 2 + } else { + result += 1 + } + i += 1 + } + result + } else { + var i = 0 + var result = index + while (i != codePointOffset) { + if (result <= 0) + throw new StringIndexOutOfBoundsException + if ((result > 1) && Character.isLowSurrogate(charAt(result - 1)) && + Character.isHighSurrogate(charAt(result - 2))) { + result -= 2 + } else { + result -= 1 + } + i -= 1 + } + result + } + } + + override def hashCode(): Int = { + var res = 0 + var mul = 1 // holds pow(31, length-i-1) + var i = length-1 + while (i >= 0) { + res += charAt(i) * mul + mul *= 31 + i -= 1 + } + res + } + + @inline + override def equals(that: Any): scala.Boolean = + this eq that.asInstanceOf[AnyRef] + + @inline + def compareTo(anotherString: String): Int = { + if (this.equals(anotherString)) 0 + else if ((this.asInstanceOf[js.Dynamic] < + anotherString.asInstanceOf[js.Dynamic]).asInstanceOf[scala.Boolean]) -1 + else 1 + } + + def compareToIgnoreCase(str: String): Int = + this.toLowerCase().compareTo(str.toLowerCase()) + + @inline + def equalsIgnoreCase(that: String): scala.Boolean = + this.toLowerCase() == (if (that == null) null else that.toLowerCase()) + + @inline + def concat(s: String): String = + thisString + s + + @inline + def contains(s: CharSequence): scala.Boolean = + indexOf(s.toString) != -1 + + def endsWith(suffix: String): scala.Boolean = + thisString.jsSubstring(this.length - suffix.length) == suffix + + def getBytes(): Array[scala.Byte] = + getBytes(Charset.defaultCharset) + + def getBytes(charsetName: String): Array[scala.Byte] = + getBytes(Charset.forName(charsetName)) + + def getBytes(charset: Charset): Array[scala.Byte] = { + val buf = charset.encode(thisString) + val res = new Array[scala.Byte](buf.remaining) + buf.get(res) + res + } + + def getChars(srcBegin: Int, srcEnd: Int, dst: Array[Char], + dstBegin: Int): Unit = { + if (srcEnd > length || srcBegin < 0 || srcEnd < 0 || srcBegin > srcEnd) + throw new StringIndexOutOfBoundsException("Index out of Bound") + + val offset = dstBegin - srcBegin + var i = srcBegin + while (i < srcEnd) { + dst(i + offset) = charAt(i) + i += 1 + } + } + + def indexOf(ch: Int): Int = + indexOf(fromCodePoint(ch)) + + def indexOf(ch: Int, fromIndex: Int): Int = + indexOf(fromCodePoint(ch), fromIndex) + + @inline + def indexOf(str: String): Int = + thisString.jsIndexOf(str) + + @inline + def indexOf(str: String, fromIndex: Int): Int = + thisString.jsIndexOf(str, fromIndex) + + /* Just returning this string is a valid implementation for `intern` in + * JavaScript, since strings are primitive values. Therefore, value equality + * and reference equality is the same. + */ + @inline + def intern(): String = thisString + + @inline + def isEmpty(): scala.Boolean = (this: AnyRef) eq ("": AnyRef) + + def lastIndexOf(ch: Int): Int = + lastIndexOf(fromCodePoint(ch)) + + def lastIndexOf(ch: Int, fromIndex: Int): Int = + if (fromIndex < 0) -1 + else lastIndexOf(fromCodePoint(ch), fromIndex) + + @inline + def lastIndexOf(str: String): Int = + thisString.jsLastIndexOf(str) + + @inline + def lastIndexOf(str: String, fromIndex: Int): Int = + if (fromIndex < 0) -1 + else thisString.jsLastIndexOf(str, fromIndex) + + @inline + def length(): Int = + thisJSString.length + + @inline + def matches(regex: String): scala.Boolean = + Pattern.matches(regex, thisString) + + /* Both regionMatches ported from + * https://github.com/gwtproject/gwt/blob/master/user/super/com/google/gwt/emul/java/lang/String.java + */ + def regionMatches(ignoreCase: scala.Boolean, toffset: Int, other: String, + ooffset: Int, len: Int): scala.Boolean = { + if (other == null) { + throw new NullPointerException() + } else if (toffset < 0 || ooffset < 0 || toffset + len > this.length || + ooffset + len > other.length) { + false + } else if (len <= 0) { + true + } else { + val left = this.substring(toffset, toffset + len) + val right = other.substring(ooffset, ooffset + len) + if (ignoreCase) left.equalsIgnoreCase(right) else left == right + } + } + + @inline + def regionMatches(toffset: Int, other: String, ooffset: Int, + len: Int): scala.Boolean = { + regionMatches(false, toffset, other, ooffset, len) + } + + @inline + def replace(oldChar: Char, newChar: Char): String = + replace(oldChar.toString, newChar.toString) + + @inline + def replace(target: CharSequence, replacement: CharSequence): String = + thisString.jsSplit(target.toString).join(replacement.toString) + + def replaceAll(regex: String, replacement: String): String = + Pattern.compile(regex).matcher(thisString).replaceAll(replacement) + + def replaceFirst(regex: String, replacement: String): String = + Pattern.compile(regex).matcher(thisString).replaceFirst(replacement) + + @inline + def split(regex: String): Array[String] = + split(regex, 0) + + def split(regex: String, limit: Int): Array[String] = + Pattern.compile(regex).split(thisString, limit) + + @inline + def startsWith(prefix: String): scala.Boolean = + startsWith(prefix, 0) + + @inline + def startsWith(prefix: String, toffset: Int): scala.Boolean = { + (toffset <= length && toffset >= 0 && + thisString.jsSubstring(toffset, toffset + prefix.length) == prefix) + } + + @inline + def subSequence(beginIndex: Int, endIndex: Int): CharSequence = + substring(beginIndex, endIndex) + + @inline + def substring(beginIndex: Int): String = + thisString.jsSubstring(beginIndex) + + @inline + def substring(beginIndex: Int, endIndex: Int): String = + thisString.jsSubstring(beginIndex, endIndex) + + def toCharArray(): Array[Char] = { + val len = length + val result = new Array[Char](len) + var i = 0 + while (i < len) { + result(i) = charAt(i) + i += 1 + } + result + } + + @inline + def toLowerCase(): String = + thisJSString.toLowerCase() + + @inline + def toUpperCase(): String = + thisJSString.toUpperCase() + + @inline + def trim(): String = + thisJSString.trim() + + @inline + override def toString(): String = + thisString +} + +object _String { // scalastyle:ignore + /** Operations on a primitive JS string that are shadowed by Scala methods, + * and that we need to implement these very Scala methods. + */ + private trait SpecialJSStringOps extends js.Any { + def length: Int + def charCodeAt(index: Int): Int + + def toLowerCase(): String + def toUpperCase(): String + def trim(): String + } + + final lazy val CASE_INSENSITIVE_ORDER: Comparator[String] = { + new Comparator[String] with Serializable { + def compare(o1: String, o2: String): Int = o1.compareToIgnoreCase(o2) + } + } + + // Constructors + + def newString(): String = "" + + def newString(value: Array[Char]): String = + newString(value, 0, value.length) + + def newString(value: Array[Char], offset: Int, count: Int): String = { + val end = offset + count + if (offset < 0 || end < offset || end > value.length) + throw new StringIndexOutOfBoundsException + + var result = "" + var i = offset + while (i != end) { + result += value(i).toString + i += 1 + } + result + } + + def newString(bytes: Array[scala.Byte]): String = + newString(bytes, Charset.defaultCharset) + + def newString(bytes: Array[scala.Byte], charsetName: String): String = + newString(bytes, Charset.forName(charsetName)) + + def newString(bytes: Array[scala.Byte], charset: Charset): String = + charset.decode(ByteBuffer.wrap(bytes)).toString() + + def newString(bytes: Array[scala.Byte], offset: Int, length: Int): String = + newString(bytes, offset, length, Charset.defaultCharset) + + def newString(bytes: Array[scala.Byte], offset: Int, length: Int, + charsetName: String): String = + newString(bytes, offset, length, Charset.forName(charsetName)) + + def newString(bytes: Array[scala.Byte], offset: Int, length: Int, + charset: Charset): String = + charset.decode(ByteBuffer.wrap(bytes, offset, length)).toString() + + def newString(codePoints: Array[Int], offset: Int, count: Int): String = { + val end = offset + count + if (offset < 0 || end < offset || end > codePoints.length) + throw new StringIndexOutOfBoundsException + + var result = "" + var i = offset + while (i != end) { + result += fromCodePoint(codePoints(i)) + i += 1 + } + result + } + + def newString(original: String): String = { + if (original == null) + throw new NullPointerException + original + } + + def newString(buffer: java.lang.StringBuffer): String = + buffer.toString + + def newString(builder: java.lang.StringBuilder): String = + builder.toString + + // Static methods (aka methods on the companion object) + + def valueOf(b: scala.Boolean): String = b.toString() + def valueOf(c: scala.Char): String = c.toString() + def valueOf(i: scala.Int): String = i.toString() + def valueOf(l: scala.Long): String = l.toString() + def valueOf(f: scala.Float): String = f.toString() + def valueOf(d: scala.Double): String = d.toString() + + @inline def valueOf(obj: Object): String = + "" + obj // if (obj eq null), returns "null" + + def valueOf(data: Array[Char]): String = + valueOf(data, 0, data.length) + + def valueOf(data: Array[Char], offset: Int, count: Int): String = + newString(data, offset, count) + + def format(format: String, args: Array[AnyRef]): String = { + val frm = new java.util.Formatter() + val res = frm.format(format, args: _*).toString() + frm.close() + res + } + + // Helpers + + private def fromCodePoint(codePoint: Int): String = { + if ((codePoint & ~Character.MAX_VALUE) == 0) { + NativeJSString.fromCharCode(codePoint) + } else if (codePoint < 0 || codePoint > Character.MAX_CODE_POINT) { + throw new IllegalArgumentException + } else { + val offsetCp = codePoint - 0x10000 + NativeJSString.fromCharCode( + (offsetCp >> 10) | 0xd800, (offsetCp & 0x3ff) | 0xdc00) + } + } + + @js.native + @JSGlobal("String") + private object NativeJSString extends js.Object { + def fromCharCode(charCodes: Int*): String = js.native + } + +} diff --git a/library/src/main/scala/scala/scalajs/runtime/RuntimeString.scala b/library/src/main/scala/scala/scalajs/runtime/RuntimeString.scala deleted file mode 100644 index e5da34d855..0000000000 --- a/library/src/main/scala/scala/scalajs/runtime/RuntimeString.scala +++ /dev/null @@ -1,464 +0,0 @@ -package scala.scalajs.runtime - -import java.util.Comparator - -import scala.scalajs.js -import scala.scalajs.js.annotation._ -import js.JSStringOps._ - -import java.nio.ByteBuffer -import java.nio.charset.Charset -import java.util.regex._ - -/** Implementation for methods on java.lang.String. - * - * Strings are represented at runtime by JavaScript strings, but they have - * a lot of methods. The compiler forwards methods on java.lang.String to the - * methods in the object, passing `this` as the first argument, that we - * consistently call `thiz` in this object. - */ -private[runtime] object RuntimeString { - - /** Operations on a primitive JS string that are shadowed by Scala methods, - * and that we need to implement these very Scala methods. - */ - private trait SpecialJSStringOps extends js.Any { - def length: Int - def charCodeAt(index: Int): Int - - def toLowerCase(): String - def toUpperCase(): String - def trim(): String - } - - private def specialJSStringOps(s: String): SpecialJSStringOps = - s.asInstanceOf[SpecialJSStringOps] - - @inline - def charAt(thiz: String, index: Int): Char = - specialJSStringOps(thiz).charCodeAt(index).toChar - - final lazy val CASE_INSENSITIVE_ORDER: Comparator[String] = { - new Comparator[String] with Serializable { - def compare(o1: String, o2: String): Int = o1.compareToIgnoreCase(o2) - } - } - - def codePointAt(thiz: String, index: Int): Int = { - val high = thiz.charAt(index) - if (index+1 < thiz.length) { - val low = thiz.charAt(index+1) - if (Character.isSurrogatePair(high, low)) - Character.toCodePoint(high, low) - else - high.toInt - } else { - high.toInt - } - } - - def codePointBefore(thiz: String, index: Int): Int = { - val low = thiz.charAt(index - 1) - if (index > 1) { - val high = thiz.charAt(index - 2) - if (Character.isSurrogatePair(high, low)) - Character.toCodePoint(high, low) - else - low.toInt - } else { - low.toInt - } - } - - def codePointCount(thiz: String, beginIndex: Int, endIndex: Int): Int = { - if (endIndex > thiz.length || beginIndex < 0 || endIndex < beginIndex) - throw new IndexOutOfBoundsException - var res = endIndex - beginIndex - var i = beginIndex - val end = endIndex - 1 - while (i < end) { - if (Character.isSurrogatePair(thiz.charAt(i), thiz.charAt(i + 1))) - res -= 1 - i += 1 - } - res - } - - def offsetByCodePoints(thiz: String, index: Int, - codePointOffset: Int): Int = { - val len = thiz.length - if (index < 0 || index > len) - throw new StringIndexOutOfBoundsException(index) - - if (codePointOffset >= 0) { - var i = 0 - var result = index - while (i != codePointOffset) { - if (result >= len) - throw new StringIndexOutOfBoundsException - if ((result < len - 1) && - Character.isHighSurrogate(thiz.charAt(result)) && - Character.isLowSurrogate(thiz.charAt(result + 1))) { - result += 2 - } else { - result += 1 - } - i += 1 - } - result - } else { - var i = 0 - var result = index - while (i != codePointOffset) { - if (result <= 0) - throw new StringIndexOutOfBoundsException - if ((result > 1) && Character.isLowSurrogate(thiz.charAt(result - 1)) && - Character.isHighSurrogate(thiz.charAt(result - 2))) { - result -= 2 - } else { - result -= 1 - } - i -= 1 - } - result - } - } - - def hashCode(thiz: String): Int = { - var res = 0 - var mul = 1 // holds pow(31, length-i-1) - var i = thiz.length-1 - while (i >= 0) { - res += thiz.charAt(i) * mul - mul *= 31 - i -= 1 - } - res - } - - @inline - def compareTo(thiz: String, anotherString: String): Int = { - if (thiz.equals(anotherString)) 0 - else if ((thiz.asInstanceOf[js.Dynamic] < - anotherString.asInstanceOf[js.Dynamic]).asInstanceOf[Boolean]) -1 - else 1 - } - - def compareToIgnoreCase(thiz: String, str: String): Int = - thiz.toLowerCase().compareTo(str.toLowerCase()) - - @inline - def equalsIgnoreCase(thiz: String, that: String): Boolean = - thiz.toLowerCase() == (if (that == null) null else that.toLowerCase()) - - @inline - def concat(thiz: String, s: String): String = - checkNull(thiz) + s - - @inline - def contains(thiz: String, s: CharSequence): Boolean = - thiz.indexOf(s.toString) != -1 - - def endsWith(thiz: String, suffix: String): Boolean = - thiz.jsSubstring(thiz.length - suffix.length) == suffix - - def getBytes(thiz: String): Array[Byte] = - thiz.getBytes(Charset.defaultCharset) - - def getBytes(thiz: String, charsetName: String): Array[Byte] = - thiz.getBytes(Charset.forName(charsetName)) - - def getBytes(thiz: String, charset: Charset): Array[Byte] = { - val buf = charset.encode(thiz) - val res = new Array[Byte](buf.remaining) - buf.get(res) - res - } - - def getChars(thiz: String, srcBegin: Int, srcEnd: Int, - dst: Array[Char], dstBegin: Int): Unit = { - if (srcEnd > thiz.length || // first test uses thiz - srcBegin < 0 || - srcEnd < 0 || - srcBegin > srcEnd) { - throw new StringIndexOutOfBoundsException("Index out of Bound") - } - - val offset = dstBegin - srcBegin - var i = srcBegin - while (i < srcEnd) { - dst(i+offset) = thiz.charAt(i) - i += 1 - } - } - - def indexOf(thiz: String, ch: Int): Int = - thiz.indexOf(fromCodePoint(ch)) - - def indexOf(thiz: String, ch: Int, fromIndex: Int): Int = - thiz.indexOf(fromCodePoint(ch), fromIndex) - - @inline - def indexOf(thiz: String, str: String): Int = - thiz.jsIndexOf(str) - - @inline - def indexOf(thiz: String, str: String, fromIndex: Int): Int = - thiz.jsIndexOf(str, fromIndex) - - /* Just returning this string is a valid implementation for `intern` in - * JavaScript, since strings are primitive values. Therefore, value equality - * and reference equality is the same. - */ - @inline - def intern(thiz: String): String = - checkNull(thiz) - - @inline - def isEmpty(thiz: String): Boolean = - checkNull(thiz) == "" - - def lastIndexOf(thiz: String, ch: Int): Int = - thiz.lastIndexOf(fromCodePoint(ch)) - - def lastIndexOf(thiz: String, ch: Int, fromIndex: Int): Int = - if (fromIndex < 0) -1 - else thiz.lastIndexOf(fromCodePoint(ch), fromIndex) - - @inline - def lastIndexOf(thiz: String, str: String): Int = - thiz.jsLastIndexOf(str) - - @inline - def lastIndexOf(thiz: String, str: String, fromIndex: Int): Int = - if (fromIndex < 0) -1 - else thiz.jsLastIndexOf(str, fromIndex) - - @inline - def length(thiz: String): Int = - specialJSStringOps(thiz).length - - @inline - def matches(thiz: String, regex: String): Boolean = { - checkNull(thiz) - Pattern.matches(regex, thiz) - } - - /* Both regionMatches ported from - * https://github.com/gwtproject/gwt/blob/master/user/super/com/google/gwt/emul/java/lang/String.java - */ - def regionMatches(thiz: String, ignoreCase: Boolean, - toffset: Int, other: String, ooffset: Int, len: Int): Boolean = { - checkNull(thiz) - if (other == null) { - throw new NullPointerException() - } else if (toffset < 0 || ooffset < 0 || toffset + len > thiz.length || ooffset + len > other.length) { - false - } else if (len <= 0) { - true - } else { - val left = thiz.substring(toffset, toffset + len) - val right = other.substring(ooffset, ooffset + len) - if (ignoreCase) left.equalsIgnoreCase(right) else left == right - } - } - - @inline - def regionMatches(thiz: String, toffset: Int, - other: String, ooffset: Int, len: Int): Boolean = { - regionMatches(thiz, false, toffset, other, ooffset, len) - } - - @inline - def replace(thiz: String, oldChar: Char, newChar: Char): String = - thiz.replace(oldChar.toString, newChar.toString) - - @inline - def replace(thiz: String, target: CharSequence, replacement: CharSequence): String = - thiz.jsSplit(target.toString).join(replacement.toString) - - def replaceAll(thiz: String, regex: String, replacement: String): String = { - checkNull(thiz) - Pattern.compile(regex).matcher(thiz).replaceAll(replacement) - } - - def replaceFirst(thiz: String, regex: String, replacement: String): String = { - checkNull(thiz) - Pattern.compile(regex).matcher(thiz).replaceFirst(replacement) - } - - @inline - def split(thiz: String, regex: String): Array[String] = - thiz.split(regex, 0) - - def split(thiz: String, regex: String, limit: Int): Array[String] = { - checkNull(thiz) - Pattern.compile(regex).split(thiz, limit) - } - - @inline - def startsWith(thiz: String, prefix: String): Boolean = - thiz.startsWith(prefix, 0) - - @inline - def startsWith(thiz: String, prefix: String, toffset: Int): Boolean = { - (toffset <= thiz.length && toffset >= 0 && - thiz.jsSubstring(toffset, toffset + prefix.length) == prefix) - } - - @inline - def subSequence(thiz: String, beginIndex: Int, endIndex: Int): CharSequence = - thiz.substring(beginIndex, endIndex) - - @inline - def substring(thiz: String, beginIndex: Int): String = - thiz.jsSubstring(beginIndex) - - @inline - def substring(thiz: String, beginIndex: Int, endIndex: Int): String = - thiz.jsSubstring(beginIndex, endIndex) - - def toCharArray(thiz: String): Array[Char] = { - val length = thiz.length - val result = new Array[Char](length) - var i = 0 - while (i < length) { - result(i) = thiz.charAt(i) - i += 1 - } - result - } - - @inline - def toLowerCase(thiz: String): String = - specialJSStringOps(thiz).toLowerCase() - - @inline - def toUpperCase(thiz: String): String = - specialJSStringOps(thiz).toUpperCase() - - @inline - def trim(thiz: String): String = - specialJSStringOps(thiz).trim() - - // Constructors - - def newString(): String = "" - - def newString(value: Array[Char]): String = - newString(value, 0, value.length) - - def newString(value: Array[Char], offset: Int, count: Int): String = { - val end = offset + count - if (offset < 0 || end < offset || end > value.length) - throw new StringIndexOutOfBoundsException - - var result = "" - var i = offset - while (i != end) { - result += value(i).toString - i += 1 - } - result - } - - def newString(bytes: Array[Byte]): String = - newString(bytes, Charset.defaultCharset) - - def newString(bytes: Array[Byte], charsetName: String): String = - newString(bytes, Charset.forName(charsetName)) - - def newString(bytes: Array[Byte], charset: Charset): String = - charset.decode(ByteBuffer.wrap(bytes)).toString() - - def newString(bytes: Array[Byte], offset: Int, length: Int): String = - newString(bytes, offset, length, Charset.defaultCharset) - - def newString(bytes: Array[Byte], offset: Int, length: Int, - charsetName: String): String = - newString(bytes, offset, length, Charset.forName(charsetName)) - - def newString(bytes: Array[Byte], offset: Int, length: Int, - charset: Charset): String = - charset.decode(ByteBuffer.wrap(bytes, offset, length)).toString() - - def newString(codePoints: Array[Int], offset: Int, count: Int): String = { - val end = offset + count - if (offset < 0 || end < offset || end > codePoints.length) - throw new StringIndexOutOfBoundsException - - var result = "" - var i = offset - while (i != end) { - result += fromCodePoint(codePoints(i)) - i += 1 - } - result - } - - def newString(original: String): String = - checkNull(original) - - def newString(buffer: java.lang.StringBuffer): String = - buffer.toString - - def newString(builder: java.lang.StringBuilder): String = - builder.toString - - // Static methods (aka methods on the companion object) - - @deprecated("Not part of the JDK API", "0.6.21") - def valueOf(b: Byte): String = b.toString() - - @deprecated("Not part of the JDK API", "0.6.21") - def valueOf(s: Short): String = s.toString() - - def valueOf(b: Boolean): String = b.toString() - def valueOf(c: Char): String = c.toString() - def valueOf(i: Int): String = i.toString() - def valueOf(l: Long): String = l.toString() - def valueOf(f: Float): String = f.toString() - def valueOf(d: Double): String = d.toString() - - @inline def valueOf(obj: Object): String = - "" + obj // if (obj eq null), returns "null" - - def valueOf(data: Array[Char]): String = - valueOf(data, 0, data.length) - - def valueOf(data: Array[Char], offset: Int, count: Int): String = - newString(data, offset, count) - - def format(format: String, args: Array[AnyRef]): String = { - val frm = new java.util.Formatter() - val res = frm.format(format, args: _*).toString() - frm.close() - res - } - - // Helpers - - @inline - private def checkNull(s: String): s.type = - if (s == null) throw new NullPointerException() - else s - - private def fromCodePoint(codePoint: Int): String = { - if ((codePoint & ~Character.MAX_VALUE) == 0) { - NativeJSString.fromCharCode(codePoint) - } else if (codePoint < 0 || codePoint > Character.MAX_CODE_POINT) { - throw new IllegalArgumentException - } else { - val offsetCp = codePoint - 0x10000 - NativeJSString.fromCharCode( - (offsetCp >> 10) | 0xd800, (offsetCp & 0x3ff) | 0xdc00) - } - } - - @js.native - @JSGlobal("String") - private object NativeJSString extends js.Object { - def fromCharCode(charCodes: Int*): String = js.native - } - -} diff --git a/project/Build.scala b/project/Build.scala index fb9d9556cb..b908d1ee7a 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -856,10 +856,7 @@ object Build { resourceGenerators in Compile += Def.task { val base = (resourceManaged in Compile).value - Seq( - serializeHardcodedIR(base, JavaLangObject.TheClassDef), - serializeHardcodedIR(base, JavaLangString.TheClassDef) - ) + Seq(serializeHardcodedIR(base, JavaLangObject.TheClassDef)) }.taskValue, scalaJSExternalCompileSettings ).withScalaJSCompiler.dependsOnLibraryNoJar diff --git a/project/JavaLangString.scala b/project/JavaLangString.scala deleted file mode 100644 index b406c9c3ba..0000000000 --- a/project/JavaLangString.scala +++ /dev/null @@ -1,165 +0,0 @@ -package build - -/* - * Hard-coded IR for java.lang.String. - */ - -import org.scalajs.core.ir -import ir._ -import ir.Definitions._ -import ir.Trees._ -import ir.Types._ -import ir.Position.NoPosition - -/** Hard-coded IR for java.lang.String. - * Unlike for the other hijacked classes, scalac does not like at all to - * compile even a mocked version of java.lang.String. So we have to bypass - * entirely the compiler to define java.lang.String. - */ -object JavaLangString { - - val TheClassDef = { - implicit val DummyPos = NoPosition - - val ThisType = ClassType(StringClass) - - val classDef = ClassDef( - Ident("T", Some("java.lang.String")), - ClassKind.HijackedClass, - Some(Ident("O", Some("java.lang.Object"))), - List( - Ident("Ljava_io_Serializable", Some("java.io.Serializable")), - Ident("jl_CharSequence", Some("java.lang.CharSequence")), - Ident("jl_Comparable", Some("java.lang.Comparable")) - ), - None, - List( - /* def equals(that: Object): Boolean = this eq that */ - MethodDef( - static = false, - Ident("equals__O__Z", Some("equals__O__Z")), - List(ParamDef(Ident("that", Some("that")), AnyType, - mutable = false, rest = false)), - BooleanType, - Some { - BinaryOp(BinaryOp.===, - This()(ThisType), - VarRef(Ident("that", Some("that")))(AnyType)) - })(OptimizerHints.empty.withInline(true), None), - - /* def hashCode(): Int = RuntimeString.hashCode(this) */ - MethodDef( - static = false, - Ident("hashCode__I", Some("hashCode__I")), - Nil, - IntType, - Some { - Apply( - LoadModule(ClassType("sjsr_RuntimeString$")), - Ident("hashCode__T__I", Some("hashCode__T__I")), - List(This()(ThisType)))(IntType) - })(OptimizerHints.empty.withInline(true), None), - - /* def compareTo(that: String): Int = RuntimeString.compareTo(this, that) */ - MethodDef( - static = false, - Ident("compareTo__T__I", Some("compareTo__T__I")), - List(ParamDef(Ident("that", Some("that")), ThisType, - mutable = false, rest = false)), - IntType, - Some { - Apply( - LoadModule(ClassType("sjsr_RuntimeString$")), - Ident("compareTo__T__T__I", Some("compareTo__T__T__I")), - List( - This()(ThisType), - VarRef(Ident("that", Some("that")))(ThisType)))(IntType) - })(OptimizerHints.empty.withInline(true), None), - - /* def compareTo(that: Object): Int = compareTo(that.asInstanceOf[String]) */ - MethodDef( - static = false, - Ident("compareTo__O__I", Some("compareTo__O__I")), - List(ParamDef(Ident("that", Some("that")), AnyType, - mutable = false, rest = false)), - IntType, - Some { - Apply( - This()(ThisType), - Ident("compareTo__T__I", Some("compareTo__T__I")), - List(AsInstanceOf( - VarRef(Ident("that", Some("that")))(AnyType), - ClassRef(StringClass))))(IntType) - })(OptimizerHints.empty.withInline(true), None), - - /* def toString(): String = this */ - MethodDef( - static = false, - Ident("toString__T", Some("toString__T")), - Nil, - ClassType(StringClass), - Some { - This()(ThisType) - })(OptimizerHints.empty.withInline(true), None), - - /* def charAt(i: Int): Char = RuntimeString.charAt(this, i) */ - MethodDef( - static = false, - Ident("charAt__I__C", Some("charAt__I__C")), - List(ParamDef(Ident("i", Some("i")), IntType, - mutable = false, rest = false)), - CharType, - Some { - Apply( - LoadModule(ClassType("sjsr_RuntimeString$")), - Ident("charAt__T__I__C", Some("charAt__T__I__C")), - List( - This()(ThisType), - VarRef(Ident("i", Some("i")))(IntType)))(CharType) - })(OptimizerHints.empty.withInline(true), None), - - /* def length(): Int = RuntimeString.length(this) */ - MethodDef( - static = false, - Ident("length__I", Some("length__I")), - Nil, - IntType, - Some { - Apply( - LoadModule(ClassType("sjsr_RuntimeString$")), - Ident("length__T__I", Some("length__T__I")), - List(This()(ThisType)))(IntType) - })(OptimizerHints.empty.withInline(true), None), - - /* def subSequence(begin: Int, end: Int): CharSequence = - * RuntimeString.subSequence(this, begin, end) - */ - MethodDef( - static = false, - Ident("subSequence__I__I__jl_CharSequence", - Some("subSequence__I__I__jl_CharSequence")), - List( - ParamDef(Ident("begin", Some("begin")), IntType, - mutable = false, rest = false), - ParamDef(Ident("end", Some("end")), IntType, - mutable = false, rest = false) - ), - ClassType("jl_CharSequence"), - Some { - Apply( - LoadModule(ClassType("sjsr_RuntimeString$")), - Ident("subSequence__T__I__I__jl_CharSequence", - Some("subSequence__T__I__I__jl_CharSequence")), - List( - This()(ThisType), - VarRef(Ident("begin", Some("begin")))(IntType), - VarRef(Ident("end", Some("end")))(IntType)))( - ClassType("jl_CharSequence")) - })(OptimizerHints.empty.withInline(true), None) - ), - Nil)(OptimizerHints.empty) - - Hashers.hashClassDef(classDef) - } - -} diff --git 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 index db1ef4a3cd..40479cae5e 100644 --- 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 @@ -1954,6 +1954,28 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { */ genDispatchApply() + case ClassType(CharSequenceClass) + if !hijackedMethodsOfStringWithDispatcher.contains(methodName) => + /* This case is required as a hack around a peculiar behavior + * of the optimizer. In theory, it should never happen, because + * we should always have a dispatcher when the receiver is not + * a concrete hijacked class. However, if the optimizer inlines + * a method of CharSequence from String (because there is no + * other CharSequence in the whole program), we can end up with + * the inlined code calling another method of String although + * its receiver is still declared as a CharSequence. + * + * TODO The proper fix for this would be to improve how the + * optimizer handles inlinings such as those: it should refine + * the type of `this` within the inlined body. + * + * This cannot happen with other ancestors of hijacked classes + * because all the other ones have several hijacked classes + * implementing them, which prevents that form of inlining from + * happening. + */ + genHijackedMethodApply(StringClass) + case ClassType(cls) if !HijackedClasses.contains(cls) => /* This is a strict ancestor of a hijacked class. We need to * use the dispatcher available in the helper method. @@ -2404,6 +2426,21 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { "notifyAll__V" ) + val hijackedMethodsOfStringWithDispatcher: Set[String] = Set( + "getClass__jl_Class", + "clone__O", + "finalize__V", + "notify__V", + "notifyAll__V", + "toString__T", + "equals__O__Z", + "hashCode__I", + "compareTo__O__I", + "length__I", + "charAt__I__C", + "subSequence__I__I__jl_CharSequence" + ) + private def transformParamDef(paramDef: ParamDef): js.ParamDef = { js.ParamDef(transformLocalVarIdent(paramDef.name), paramDef.rest)( paramDef.pos) From bd1ff59665b466e74d645ad495e39b5353633044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 17 Nov 2017 14:21:31 +0100 Subject: [PATCH 0552/2665] Uniformize handling of constructors of hijacked classes. Now the constructors of all hijacked classes are handled in the way `String`'s were, i.e., they each have a corresponding static method in the companion module. That method is called `new` in all hijacked classes, which is a pretty safe name to use as the JDK is unlikely to ever add a method named `new`. --- .../org/scalajs/core/compiler/GenJSCode.scala | 82 ++++++++----------- .../src/main/scala/java/lang/Boolean.scala | 13 +-- .../src/main/scala/java/lang/Byte.scala | 7 +- .../src/main/scala/java/lang/Character.scala | 4 +- .../src/main/scala/java/lang/Double.scala | 7 +- .../src/main/scala/java/lang/Float.scala | 8 +- .../src/main/scala/java/lang/Integer.scala | 7 +- .../src/main/scala/java/lang/Long.scala | 7 +- .../src/main/scala/java/lang/Short.scala | 7 +- .../src/main/scala/java/lang/_String.scala | 38 ++++----- 10 files changed, 97 insertions(+), 83 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index d7a053fd8e..7bdbe3fac5 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -359,7 +359,7 @@ abstract class GenJSCode extends plugins.PluginComponent } val classIdent = encodeClassFullNameIdent(sym) - val isHijacked = sym == HackedStringClass || isHijackedBoxedClass(sym) + val isHijacked = isHijackedClass(sym) // Optimizer hints @@ -1462,8 +1462,7 @@ abstract class GenJSCode extends plugins.PluginComponent OptimizerHints.empty, None)) } else if (isJSNativeCtorDefaultParam(sym)) { None - } else if (sym.isClassConstructor && - (sym.owner == HackedStringClass || isHijackedBoxedClass(sym.owner))) { + } else if (sym.isClassConstructor && isHijackedClass(sym.owner)) { None } else if (scalaUsesImplClasses && !sym.owner.isImplClass && sym.hasAnnotation(JavaDefaultMethodAnnotation)) { @@ -2440,10 +2439,8 @@ abstract class GenJSCode extends plugins.PluginComponent assert(ctor.isClassConstructor, "'new' call to non-constructor: " + ctor.name) - if (clsSym == StringClass) { - genNewString(tree) - } else if (isHijackedBoxedClass(clsSym)) { - genNewHijackedBoxedClass(clsSym, ctor, args map genExpr) + if (isHijackedClass(clsSym)) { + genNewHijackedClass(clsSym, ctor, args.map(genExpr)) } else if (isRawJSFunctionDef(clsSym)) { val classDef = consumeLazilyGeneratedAnonClass(clsSym) genRawJSFunction(classDef, args.map(genExpr)) @@ -2785,25 +2782,27 @@ abstract class GenJSCode extends plugins.PluginComponent js.New(jstpe.ClassType(className), ctorIdent, arguments) } - /** Gen JS code for a call to a constructor of a hijacked boxed class. - * All of these have 2 constructors: one with the primitive - * value, which is erased, and one with a String, which is - * equivalent to BoxedClass.valueOf(arg). + /** Gen JS code for a call to a constructor of a hijacked class. + * Reroute them to the `new` method with the same signature in the + * companion object. */ - private def genNewHijackedBoxedClass(clazz: Symbol, ctor: Symbol, - arguments: List[js.Tree])(implicit pos: Position): js.Tree = { - assert(arguments.size == 1) - if (isStringType(ctor.tpe.params.head.tpe)) { - // BoxedClass.valueOf(arg) - val companion = clazz.companionModule.moduleClass - val valueOf = getMemberMethod(companion, nme.valueOf) suchThat { s => - s.tpe.params.size == 1 && isStringType(s.tpe.params.head.tpe) - } - genApplyMethod(genLoadModule(companion), valueOf, arguments) - } else { - // erased - arguments.head + private def genNewHijackedClass(clazz: Symbol, ctor: Symbol, + args: List[js.Tree])(implicit pos: Position): js.Tree = { + + val encodedName = encodeClassFullName(clazz) + val moduleClass = clazz.companionModule.moduleClass + + val js.Ident(initName, origName) = encodeMethodSym(ctor) + val newMethodName = initName match { + case "init___" => + "$new__" + encodedName + case _ => + "$new" + initName.stripPrefix("init_") + "__" + encodedName } + val newMethodIdent = js.Ident(newMethodName, origName) + + genApplyMethod(genLoadModule(moduleClass), newMethodIdent, args, + jstpe.ClassType(encodedName)) } /** Gen JS code for creating a new Array: new Array[T](length) @@ -4329,28 +4328,6 @@ abstract class GenJSCode extends plugins.PluginComponent (firstArg, args.tail) } - /** Gen JS code for new java.lang.String(...) - * Proxies calls to method newString on object - * scala.scalajs.runtime.RuntimeString with proper arguments - */ - private def genNewString(tree: Apply): js.Tree = { - implicit val pos = tree.pos - val Apply(fun @ Select(_, _), args0) = tree - - val ctor = fun.symbol - val args = args0 map genExpr - - val js.Ident(initName, origName) = encodeMethodSym(ctor) - val newStringMethodName = initName match { - case "init___" => "newString__T" - case _ => "newString" + initName.stripPrefix("init_") + "__T" - } - val newStringMethodIdent = js.Ident(newStringMethodName, origName) - - genApplyMethod(genLoadModule(StringModule), newStringMethodIdent, args, - jstpe.ClassType(ir.Definitions.StringClass)) - } - /** Gen JS code for a new of a raw JS class (subclass of js.Any) */ private def genPrimitiveJSNew(tree: Apply): js.Tree = { implicit val pos = tree.pos @@ -5453,13 +5430,18 @@ abstract class GenJSCode extends plugins.PluginComponent private def isStringType(tpe: Type): Boolean = tpe.typeSymbol == StringClass - protected lazy val isHijackedBoxedClass: Set[Symbol] = { - /* This list is a duplicate of ir.Definitions.HijackedBoxedClasses, but + protected lazy val isHijackedClass: Set[Symbol] = { + /* This list is a duplicate of ir.Definitions.HijackedClasses, but * with global.Symbol's instead of IR encoded names as Strings. + * We also add HackedStringClass if it is defined. */ - Set(BoxedUnitClass, BoxedBooleanClass, BoxedCharacterClass, BoxedByteClass, + val s = Set[Symbol]( + BoxedUnitClass, BoxedBooleanClass, BoxedCharacterClass, BoxedByteClass, BoxedShortClass, BoxedIntClass, BoxedLongClass, BoxedFloatClass, - BoxedDoubleClass) + BoxedDoubleClass, StringClass + ) + if (HackedStringClass == NoSymbol) s + else s + HackedStringClass } private lazy val InlineAnnotationClass = requiredClass[scala.inline] diff --git a/javalanglib/src/main/scala/java/lang/Boolean.scala b/javalanglib/src/main/scala/java/lang/Boolean.scala index 2b4537712f..b3babb795f 100644 --- a/javalanglib/src/main/scala/java/lang/Boolean.scala +++ b/javalanglib/src/main/scala/java/lang/Boolean.scala @@ -41,13 +41,14 @@ object Boolean { * Moreover, preserving the identity of TRUE and FALSE is not an issue * either, since they are primitive booleans in the end. */ - def TRUE: Boolean = new Boolean(true) - def FALSE: Boolean = new Boolean(false) + @inline def TRUE: Boolean = valueOf(true) + @inline def FALSE: Boolean = valueOf(false) - @inline def valueOf(booleanValue: scala.Boolean): Boolean = { - // We don't care about identity, since they end up as primitive booleans - new Boolean(booleanValue) - } + @inline def `new`(value: scala.Boolean): Boolean = valueOf(value) + + @inline def `new`(s: String): Boolean = valueOf(s) + + @inline def valueOf(b: scala.Boolean): Boolean = b.asInstanceOf[Boolean] @inline def valueOf(s: String): Boolean = valueOf(parseBoolean(s)) diff --git a/javalanglib/src/main/scala/java/lang/Byte.scala b/javalanglib/src/main/scala/java/lang/Byte.scala index ad902cd479..21176b4684 100644 --- a/javalanglib/src/main/scala/java/lang/Byte.scala +++ b/javalanglib/src/main/scala/java/lang/Byte.scala @@ -48,7 +48,12 @@ object Byte { def MIN_VALUE: scala.Byte = -128 def MAX_VALUE: scala.Byte = 127 - @inline def valueOf(byteValue: scala.Byte): Byte = new Byte(byteValue) + @inline def `new`(value: scala.Byte): Byte = valueOf(value) + + @inline def `new`(s: String): Byte = valueOf(s) + + @inline def valueOf(b: scala.Byte): Byte = b.asInstanceOf[Byte] + @inline def valueOf(s: String): Byte = valueOf(parseByte(s)) @inline def valueOf(s: String, radix: Int): Byte = diff --git a/javalanglib/src/main/scala/java/lang/Character.scala b/javalanglib/src/main/scala/java/lang/Character.scala index 3a4382b48f..46faf7ff25 100644 --- a/javalanglib/src/main/scala/java/lang/Character.scala +++ b/javalanglib/src/main/scala/java/lang/Character.scala @@ -41,7 +41,9 @@ object Character { final val SIZE = 16 final val BYTES = 2 - def valueOf(charValue: scala.Char): Character = new Character(charValue) + @inline def `new`(value: scala.Char): Character = valueOf(value) + + @inline def valueOf(c: scala.Char): Character = c.asInstanceOf[Character] /* These are supposed to be final vals of type Byte, but that's not possible. * So we implement them as def's, which are binary compatible with final vals. diff --git a/javalanglib/src/main/scala/java/lang/Double.scala b/javalanglib/src/main/scala/java/lang/Double.scala index c33e353849..70bda3fbb3 100644 --- a/javalanglib/src/main/scala/java/lang/Double.scala +++ b/javalanglib/src/main/scala/java/lang/Double.scala @@ -66,8 +66,11 @@ object Double { final val SIZE = 64 final val BYTES = 8 - @inline def valueOf(doubleValue: scala.Double): Double = - new Double(doubleValue) + @inline def `new`(value: scala.Double): Double = valueOf(value) + + @inline def `new`(s: String): Double = valueOf(s) + + @inline def valueOf(d: scala.Double): Double = d.asInstanceOf[Double] @inline def valueOf(s: String): Double = valueOf(parseDouble(s)) diff --git a/javalanglib/src/main/scala/java/lang/Float.scala b/javalanglib/src/main/scala/java/lang/Float.scala index b691dc4843..ed427a1071 100644 --- a/javalanglib/src/main/scala/java/lang/Float.scala +++ b/javalanglib/src/main/scala/java/lang/Float.scala @@ -50,7 +50,13 @@ object Float { final val SIZE = 32 final val BYTES = 4 - @inline def valueOf(floatValue: scala.Float): Float = new Float(floatValue) + @inline def `new`(value: scala.Float): Float = valueOf(value) + + @inline def `new`(value: scala.Double): Float = valueOf(value.toFloat) + + @inline def `new`(s: String): Float = valueOf(s) + + @inline def valueOf(f: scala.Float): Float = f.asInstanceOf[Float] @inline def valueOf(s: String): Float = valueOf(parseFloat(s)) diff --git a/javalanglib/src/main/scala/java/lang/Integer.scala b/javalanglib/src/main/scala/java/lang/Integer.scala index bc14f16dd0..5271c03b77 100644 --- a/javalanglib/src/main/scala/java/lang/Integer.scala +++ b/javalanglib/src/main/scala/java/lang/Integer.scala @@ -39,7 +39,12 @@ object Integer { final val SIZE = 32 final val BYTES = 4 - @inline def valueOf(intValue: scala.Int): Integer = new Integer(intValue) + @inline def `new`(value: scala.Int): Integer = valueOf(value) + + @inline def `new`(s: String): Integer = valueOf(s) + + @inline def valueOf(i: scala.Int): Integer = i.asInstanceOf[Integer] + @inline def valueOf(s: String): Integer = valueOf(parseInt(s)) @inline def valueOf(s: String, radix: Int): Integer = diff --git a/javalanglib/src/main/scala/java/lang/Long.scala b/javalanglib/src/main/scala/java/lang/Long.scala index 1ed00d63b4..4979ef5527 100644 --- a/javalanglib/src/main/scala/java/lang/Long.scala +++ b/javalanglib/src/main/scala/java/lang/Long.scala @@ -296,7 +296,12 @@ object Long { private def parseLongError(s: String): Nothing = throw new NumberFormatException(s"""For input string: "$s"""") - @inline def valueOf(longValue: scala.Long): Long = new Long(longValue) + @inline def `new`(value: scala.Long): Long = valueOf(value) + + @inline def `new`(s: String): Long = valueOf(s) + + @inline def valueOf(l: scala.Long): Long = l.asInstanceOf[Long] + @inline def valueOf(s: String): Long = valueOf(parseLong(s)) @inline def valueOf(s: String, radix: Int): Long = diff --git a/javalanglib/src/main/scala/java/lang/Short.scala b/javalanglib/src/main/scala/java/lang/Short.scala index f7a6e98362..45e250ccdf 100644 --- a/javalanglib/src/main/scala/java/lang/Short.scala +++ b/javalanglib/src/main/scala/java/lang/Short.scala @@ -47,7 +47,12 @@ object Short { def MIN_VALUE: scala.Short = -32768 def MAX_VALUE: scala.Short = 32767 - @inline def valueOf(shortValue: scala.Short): Short = new Short(shortValue) + @inline def `new`(value: scala.Short): Short = valueOf(value) + + @inline def `new`(s: String): Short = valueOf(s) + + @inline def valueOf(s: scala.Short): Short = s.asInstanceOf[Short] + @inline def valueOf(s: String): Short = valueOf(parseShort(s)) @inline def valueOf(s: String, radix: Int): Short = diff --git a/javalanglib/src/main/scala/java/lang/_String.scala b/javalanglib/src/main/scala/java/lang/_String.scala index 0d8c96d214..0484cc228b 100644 --- a/javalanglib/src/main/scala/java/lang/_String.scala +++ b/javalanglib/src/main/scala/java/lang/_String.scala @@ -348,12 +348,12 @@ object _String { // scalastyle:ignore // Constructors - def newString(): String = "" + def `new`(): String = "" - def newString(value: Array[Char]): String = - newString(value, 0, value.length) + def `new`(value: Array[Char]): String = + `new`(value, 0, value.length) - def newString(value: Array[Char], offset: Int, count: Int): String = { + def `new`(value: Array[Char], offset: Int, count: Int): String = { val end = offset + count if (offset < 0 || end < offset || end > value.length) throw new StringIndexOutOfBoundsException @@ -367,27 +367,27 @@ object _String { // scalastyle:ignore result } - def newString(bytes: Array[scala.Byte]): String = - newString(bytes, Charset.defaultCharset) + def `new`(bytes: Array[scala.Byte]): String = + `new`(bytes, Charset.defaultCharset) - def newString(bytes: Array[scala.Byte], charsetName: String): String = - newString(bytes, Charset.forName(charsetName)) + def `new`(bytes: Array[scala.Byte], charsetName: String): String = + `new`(bytes, Charset.forName(charsetName)) - def newString(bytes: Array[scala.Byte], charset: Charset): String = + def `new`(bytes: Array[scala.Byte], charset: Charset): String = charset.decode(ByteBuffer.wrap(bytes)).toString() - def newString(bytes: Array[scala.Byte], offset: Int, length: Int): String = - newString(bytes, offset, length, Charset.defaultCharset) + def `new`(bytes: Array[scala.Byte], offset: Int, length: Int): String = + `new`(bytes, offset, length, Charset.defaultCharset) - def newString(bytes: Array[scala.Byte], offset: Int, length: Int, + def `new`(bytes: Array[scala.Byte], offset: Int, length: Int, charsetName: String): String = - newString(bytes, offset, length, Charset.forName(charsetName)) + `new`(bytes, offset, length, Charset.forName(charsetName)) - def newString(bytes: Array[scala.Byte], offset: Int, length: Int, + def `new`(bytes: Array[scala.Byte], offset: Int, length: Int, charset: Charset): String = charset.decode(ByteBuffer.wrap(bytes, offset, length)).toString() - def newString(codePoints: Array[Int], offset: Int, count: Int): String = { + def `new`(codePoints: Array[Int], offset: Int, count: Int): String = { val end = offset + count if (offset < 0 || end < offset || end > codePoints.length) throw new StringIndexOutOfBoundsException @@ -401,16 +401,16 @@ object _String { // scalastyle:ignore result } - def newString(original: String): String = { + def `new`(original: String): String = { if (original == null) throw new NullPointerException original } - def newString(buffer: java.lang.StringBuffer): String = + def `new`(buffer: java.lang.StringBuffer): String = buffer.toString - def newString(builder: java.lang.StringBuilder): String = + def `new`(builder: java.lang.StringBuilder): String = builder.toString // Static methods (aka methods on the companion object) @@ -429,7 +429,7 @@ object _String { // scalastyle:ignore valueOf(data, 0, data.length) def valueOf(data: Array[Char], offset: Int, count: Int): String = - newString(data, offset, count) + `new`(data, offset, count) def format(format: String, args: Array[AnyRef]): String = { val frm = new java.util.Formatter() From fbe0421aca6e1303912252c95b54ee3359b34a3d Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 18 Nov 2017 15:09:45 +0100 Subject: [PATCH 0553/2665] Fix #3175: Propagate failures in TestAdapter --- project/BinaryIncompatibilities.scala | 16 ++- .../scalajs/sbttestadapter/ComJSEnvRPC.scala | 49 +++++--- .../sbttestadapter/RunnerAdapter.scala | 1 - .../scalajs/sbttestadapter/TestAdapter.scala | 110 ++++++++++++------ .../org/scalajs/testcommon/RPCCore.scala | 70 ++++++++--- .../org/scalajs/testcommon/RPCCoreTest.scala | 7 +- .../testinterface/internal/JSRPC.scala | 9 +- 7 files changed, 178 insertions(+), 84 deletions(-) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 0686367c52..610a504fe3 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -55,7 +55,11 @@ object BinaryIncompatibilities { ProblemFilters.exclude[MissingClassProblem]( "org.scalajs.testcommon.JVMSlaveEndpoints$"), ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testcommon.RPCCore#lambda#@tach#1.this") + "org.scalajs.testcommon.RPCCore#lambda#@tach#1.this"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.testcommon.RPCCore.close"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.testcommon.RPCCore.this") ) val TestAdapter = TestCommon ++ Seq( @@ -92,6 +96,10 @@ object BinaryIncompatibilities { "org.scalajs.testadapter.ScalaJSRunner.getSlave"), ProblemFilters.exclude[DirectMissingMethodProblem]( "org.scalajs.testadapter.ScalaJSRunner.loggerLock"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.testadapter.ComJSEnvRPC.close"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.testadapter.ComJSEnvRPC.this"), // private, not an issue. ProblemFilters.exclude[MissingClassProblem]( @@ -147,6 +155,10 @@ object BinaryIncompatibilities { ProblemFilters.exclude[MissingClassProblem]( "org.scalajs.testinterface.internal.Slave$lambda$3"), ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.Slave$lambda$4") + "org.scalajs.testinterface.internal.Slave$lambda$4"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.testinterface.internal.JSRPC.close"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.testinterface.internal.JSRPC#Com.close") ) } diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ComJSEnvRPC.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ComJSEnvRPC.scala index 6a7c1f618f..f1df78cec1 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ComJSEnvRPC.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ComJSEnvRPC.scala @@ -9,7 +9,7 @@ package org.scalajs.testadapter -import scala.concurrent.TimeoutException +import scala.concurrent.{ExecutionContext, TimeoutException} import org.scalajs.jsenv.{ComJSEnv, ComJSRunner} import org.scalajs.testcommon._ @@ -18,11 +18,8 @@ import org.scalajs.testcommon._ * * @note You may only create one instance of this per [[ComJSRunner]] */ -private[testadapter] final class ComJSEnvRPC( - val runner: ComJSRunner) extends RPCCore { - - @volatile - private[this] var closed = false +private[testadapter] final class ComJSEnvRPC(val runner: ComJSRunner)( + implicit executionContext: ExecutionContext) extends RPCCore { private val receiverThread = new Thread { setName("ComJSEnvRPC receiver") @@ -37,11 +34,29 @@ private[testadapter] final class ComJSEnvRPC( } } } catch { - case _: ComJSEnv.ComClosedException => - case _: InterruptedException => - case _: Exception if closed => - // Some JSEnvs might throw something else if they got closed. - // We are graceful in the 0.6.x branch. + case e: Exception => + /* We got terminated. This might be due to an interruption from a call + * to `close` or due to the JSEnv crashing. + * + * Ensure all still pending calls are failing. + * This can be necessary, if the JSEnv terminates unexpectedly. + * Note: We do not need to give a grace time here, since the reply + * dispatch happens synchronously in `handleMessage`. + * In other words, at this point we'll only see pending calls that + * would require another call to `handleMessage` in order to complete + * successfully. But this is not going to happen since this thread is + * the only one that calls `handleMessage` and it's about to terminate. + */ + ComJSEnvRPC.super.close(e) + + case t: Throwable => + /* Same here, but this is probably a serious VM error condition we + * should propagate. We do not use NonFatal, since it does not catch + * InterruptedException and ControlThrowables which we do not want to + * propagate. + */ + ComJSEnvRPC.super.close(t) + throw t } } } @@ -49,16 +64,14 @@ private[testadapter] final class ComJSEnvRPC( receiverThread.start() override protected def send(msg: String): Unit = synchronized { - if (!closed) - runner.send(msg) + runner.send(msg) } - override def close(): Unit = synchronized { - closed = true - - super.close() + override def close(cause: Throwable): Unit = synchronized { + // First close the RPC layer, so we propagate the right cause. + super.close(cause) - // Close the com first so the receiver thread terminates. + // Close the runner so the receiver thread terminates. runner.close() receiverThread.interrupt() diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/RunnerAdapter.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/RunnerAdapter.scala index 77af6533ff..be4adab53b 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/RunnerAdapter.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/RunnerAdapter.scala @@ -12,7 +12,6 @@ package org.scalajs.testadapter import scala.collection.concurrent.TrieMap import scala.concurrent._ -import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration._ import scala.util._ diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TestAdapter.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TestAdapter.scala index 6056fc4674..1bf13c96dc 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TestAdapter.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TestAdapter.scala @@ -11,11 +11,8 @@ package org.scalajs.testadapter import scala.concurrent._ import scala.concurrent.duration._ -import scala.concurrent.ExecutionContext.Implicits.global import scala.collection.concurrent.TrieMap -import java.util.concurrent.atomic.{AtomicInteger, AtomicBoolean} - import org.scalajs.core.ir.Utils.escapeJS import org.scalajs.core.tools.io._ import org.scalajs.core.tools.logging._ @@ -33,10 +30,16 @@ final class TestAdapter(jsEnv: ComJSEnv, config: TestAdapter.Config) { /** Map of ThreadId -> ManagedRunner */ private[this] val runners = TrieMap.empty[Long, ManagedRunner] - private[this] val closing = new AtomicBoolean(false) + /** State management. May only be accessed under synchronization. */ + private[this] var closed = false + private[this] var nextRunID = 0 + private[this] var runs = Set.empty[RunMux.RunID] - private[this] val nextRunID = new AtomicInteger(0) - private[this] val runs = TrieMap.empty[RunMux.RunID, Unit] + /** A custom execution context that delegates to the global one for execution, + * but handles failures internally. + */ + private implicit val executionContext = + ExecutionContext.fromExecutor(ExecutionContext.global, reportFailure) /** Creates an `sbt.testing.Framework` for each framework that can be found. * @@ -50,49 +53,71 @@ final class TestAdapter(jsEnv: ComJSEnv, config: TestAdapter.Config) { .call(JSEndpoints.detectFrameworks)(frameworkNames) .map(_.map(_.map(info => new FrameworkAdapter(info, this)))) - // If there is no testing framework loaded, nothing will reply. - val fallback: Future[List[Option[Framework]]] = - runner.runner.future.map(_ => frameworkNames.map(_ => None)) + val recovered = frameworks.recoverWith { + // If there is no testing framework loaded, nothing will reply. + case _: RPCCore.ClosedException => + // We reply with no framework at all. + runner.runner.future.map(_ => frameworkNames.map(_ => None)) + } - Future.firstCompletedOf(List(frameworks, fallback)).await() + recovered.await() } /** Releases all resources. All associated runs must be done. */ - def close(): Unit = { - if (!closing.getAndSet(true)) { - // Snapshot runs. - val seenRuns = runs.keySet + def close(): Unit = synchronized { + val runInfo = + if (runs.isEmpty) "All runs have completed." + else s"Incomplete runs: $runs" + + val msg = "TestAdapter.close() was called. " + runInfo + + if (runs.nonEmpty) + config.logger.warn(msg) + + /* This is the exception callers will see if they are still pending. + * That's why it is an IllegalStateException. + */ + val cause = new IllegalStateException(msg) + stopEverything(cause) + } + + /** Called when a throwable bubbles up the execution stack. + * + * We terminate everyting if this happens to make sure nothing hangs waiting + * on an async operation to complete. + */ + private def reportFailure(cause: Throwable): Unit = { + val msg = "Failure in async execution. Aborting all test runs." + val error = new AssertionError(msg, cause) + config.logger.error(msg) + config.logger.trace(error) + stopEverything(error) + } - runners.values.foreach(_.com.close()) + private def stopEverything(cause: Throwable): Unit = synchronized { + if (!closed) { + closed = true + runners.values.foreach(_.com.close(cause)) runners.values.foreach(_.runner.stop()) runners.clear() - - runs.clear() - if (seenRuns.nonEmpty) { - throw new IllegalStateException( - s"close() called with incomplete runs: $seenRuns") - } } } - private[testadapter] def runStarting(): RunMux.RunID = { - require(!closing.get(), "We are closing. Cannot create new run.") - val runID = nextRunID.getAndIncrement() - runs.put(runID, ()) + private[testadapter] def runStarting(): RunMux.RunID = synchronized { + require(!closed, "We are closed. Cannot create new run.") + val runID = nextRunID + nextRunID += 1 + runs += runID runID } /** Called by [[RunnerAdapter]] when the run is completed. */ - private[testadapter] def runDone(runID: RunMux.RunID): Unit = { - val old = runs.remove(runID) - require(old.nonEmpty, s"Tried to remove nonexistent run $runID") + private[testadapter] def runDone(runID: RunMux.RunID): Unit = synchronized { + require(runs.contains(runID), s"Tried to remove nonexistent run $runID") + runs -= runID } private[testadapter] def getRunnerForThread(): ManagedRunner = { - // Prevent runners from being started after closing started. - // Otherwise we might leak runners. - require(!closing.get(), "We are closing. Cannot create new runner.") - val threadId = Thread.currentThread().getId() // Note that this is thread safe, since each thread can only operate on @@ -100,7 +125,11 @@ final class TestAdapter(jsEnv: ComJSEnv, config: TestAdapter.Config) { runners.getOrElseUpdate(threadId, startManagedRunner(threadId)) } - private def startManagedRunner(threadId: Long): ManagedRunner = { + private def startManagedRunner(threadId: Long): ManagedRunner = synchronized { + // Prevent runners from being started after we are closed. + // Otherwise we might leak runners. + require(!closed, "We are closed. Cannot create new runner.") + // !!! DUPLICATE code with ScalaJSPlugin.makeExportsNamespaceExpr val orgExpr = config.moduleKind match { case ModuleKind.NoModule => @@ -135,8 +164,12 @@ final class TestAdapter(jsEnv: ComJSEnv, config: TestAdapter.Config) { val launcher = new MemVirtualJSFile("startTestBridge.js").withContent(code) val runner = jsEnv.comRunner(launcher) + val com = new ComJSEnvRPC(runner) + val mux = new RunMuxRPC(com) + runner.start(config.logger, config.console) - new ManagedRunner(threadId, runner) + + new ManagedRunner(threadId, runner, com, mux) } } @@ -184,8 +217,9 @@ object TestAdapter { } private[testadapter] final class ManagedRunner( - val id: Long, val runner: ComJSRunner) { - val com = new ComJSEnvRPC(runner) - val mux = new RunMuxRPC(com) - } + val id: Long, + val runner: ComJSRunner, + val com: RPCCore, + val mux: RunMuxRPC + ) } diff --git a/test-common/src/main/scala/org/scalajs/testcommon/RPCCore.scala b/test-common/src/main/scala/org/scalajs/testcommon/RPCCore.scala index 143b6469fe..d16d3ade04 100644 --- a/test-common/src/main/scala/org/scalajs/testcommon/RPCCore.scala +++ b/test-common/src/main/scala/org/scalajs/testcommon/RPCCore.scala @@ -13,19 +13,33 @@ import java.util.concurrent.atomic.AtomicLong import Serializer.{serialize, deserialize} import FutureUtil._ -private[scalajs] abstract class RPCCore { + +/** Core RPC dispatcher. + * + * Tracks and assigns call identities on top of a message passing interface. + * + * Note that it does not have timeout handling for calls. Users are expected to + * manage call teardown by calling [[close]] in case of failure. This typically + * means that subclasses need to put an explicit call to [[close]] once they + * are sure to not call [[handleMessage]] anymore. + * + * This class guarantees that dispatch handles synchronously when + * [[handleMessage]] is called, so closing can be performed race-free. + */ +private[scalajs] abstract class RPCCore()(implicit ex: ExecutionContext) { import RPCCore._ - /** Pending calls. - * - * @note We do deliberately not timeout calls in here since there will be - * timeouts on a higher level and a test run is relatively short lived - * (< 10h) and we expect failure ratio to be extremely low. - */ + /** Pending calls. */ private[this] val pending = new ConcurrentHashMap[Long, PendingCall] + /** Reason why we are closing this RPCCore. If non-null, we are closing. */ + @volatile + private[this] var closeReason: Throwable = _ + + /** Next call ID we'll assign. */ private[this] val nextID = new AtomicLong(0L) + /** Currently registered enpoints. */ private[this] val endpoints = new ConcurrentHashMap[OpCode, BoundEndpoint] /** Subclass should call this whenever a new message arrives */ @@ -76,8 +90,6 @@ private[scalajs] abstract class RPCCore { val ep: bep.endpoint.type = bep.endpoint import ep._ - import scala.concurrent.ExecutionContext.Implicits.global - futureFromTry(Try(deserialize[Req](in))) .flatMap(bep.exec) .onComplete(repl => send(makeReply(callID, repl))) @@ -102,7 +114,7 @@ private[scalajs] abstract class RPCCore { // Reserve an id for this call. val id = nextID.incrementAndGet() - // Prepare message. + // Prepare message. We do this early in case it throws. val msg = makeRPCMsg(opCode, id, req) // Register pending call. @@ -110,11 +122,20 @@ private[scalajs] abstract class RPCCore { val oldCall = pending.put(id, PendingCall(promise)) if (oldCall != null) { - throw new AssertionError("Ran out of call ids!") + val error = new AssertionError("Ran out of call ids!") + close(error) + throw error } - // Actually send message. - send(msg) + if (closeReason != null) { + /* In the meantime, someone closed the channel. Help closing. + * We need this check to guard against a race between `call` and `close`. + */ + helpClose() + } else { + // Actually send message. + send(msg) + } promise.future } @@ -150,18 +171,32 @@ private[scalajs] abstract class RPCCore { require(old != null, "Endpoint was not attached.") } - /** Close the communication channel. */ - def close(): Unit = { + /** Close the communication channel. + * + * This only affects the current calls (i.e. the client part of the + * interface). Endpoint attachment is unaffected. + * + * It is permitted to call `close` multiple times. However, if the calls are + * concurrent and have different reasons, which pending calls get cancelled + * with which reasons is unspecified (but all of them will get cancelled). + */ + def close(reason: Throwable): Unit = { + closeReason = reason + helpClose() + } + + private def helpClose(): Unit = { /* Fix for #3128: explicitly upcast to java.util.Map so that the keySet() * method is binary compatible on JDK7. */ val pendingCallIDs = (pending: java.util.Map[Long, _]).keySet() + val exception = new ClosedException(closeReason) for { callID <- pendingCallIDs.asScala failing <- Option(pending.remove(callID)) } { - failing.promise.failure(new IOException("Channel got closed")) + failing.promise.failure(exception) } } @@ -195,6 +230,9 @@ private[scalajs] object RPCCore { /** Exception thrown if a remote invocation fails. */ class RPCException(c: Throwable) extends Exception(null, c) + /** Exception thrown if the channel got closed. */ + class ClosedException(c: Throwable) extends Exception(null, c) + private val ReplyOK: Byte = 0.toByte private val ReplyErr: Byte = 1.toByte diff --git a/test-common/src/test/scala/org/scalajs/testcommon/RPCCoreTest.scala b/test-common/src/test/scala/org/scalajs/testcommon/RPCCoreTest.scala index c943251e4e..d87d4d43fd 100644 --- a/test-common/src/test/scala/org/scalajs/testcommon/RPCCoreTest.scala +++ b/test-common/src/test/scala/org/scalajs/testcommon/RPCCoreTest.scala @@ -149,14 +149,15 @@ class RPCCoreTest { val future = y.call(eps.number)(()) - y.close() + val cause = new Throwable("blah") + y.close(cause) try { Await.result(future, atMost = 1.second) fail("Expected exception") } catch { - case e: java.io.IOException => - assertEquals("Channel got closed", e.getMessage()) + case e: RPCCore.ClosedException => + assertSame(cause, e.getCause()) } } } diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/JSRPC.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/JSRPC.scala index c5b2e84537..b2553d4689 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/JSRPC.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/JSRPC.scala @@ -4,6 +4,7 @@ import scala.scalajs.js import scala.scalajs.js.annotation._ import scala.concurrent.duration._ +import scala.concurrent.ExecutionContext.Implicits.global import org.scalajs.testcommon.RPCCore @@ -13,16 +14,12 @@ private[internal] final object JSRPC extends RPCCore { override protected def send(msg: String): Unit = Com.send(msg) - override def close(): Unit = { - super.close() - Com.close() - } - @js.native @JSGlobal("scalajsCom") private object Com extends js.Object { def init(onReceive: js.Function1[String, Unit]): Unit = js.native def send(msg: String): Unit = js.native - def close(): Unit = js.native + // We support close, but do not use it. The JS side just terminates. + // def close(): Unit = js.native } } From 6c5d89da8dca4a5217f19c15f53f79a34f0574ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 22 Nov 2017 16:39:05 +0100 Subject: [PATCH 0554/2665] Use sbt-platform-deps to provide `%%%` and drop sbt-crossproject. This means that sbt-scalajs does not directly provide `crossProject` nor `JSPlatform` anymore. Those are provided by sbt-scalajs-crossproject 0.3.0 or later. --- project/Build.scala | 2 +- project/build.sbt | 2 +- sbt-plugin-test/build.sbt | 102 +++++++++--------- .../referencedCrossProject/build.sbt | 7 -- .../project/build.properties | 1 - .../referencedCrossProject/project/build.sbt | 2 - .../project/project/build.sbt | 1 - .../org/scalajs/sbtplugin/JSPlatform.scala | 24 ----- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 20 ---- .../sbtplugin/ScalaJSPluginInternal.scala | 4 +- .../sbtplugin/impl/ScalaJSGroupID.scala | 7 ++ 11 files changed, 62 insertions(+), 110 deletions(-) delete mode 100644 sbt-plugin-test/referencedCrossProject/build.sbt delete mode 100644 sbt-plugin-test/referencedCrossProject/project/build.properties delete mode 100644 sbt-plugin-test/referencedCrossProject/project/build.sbt delete mode 100644 sbt-plugin-test/referencedCrossProject/project/project/build.sbt delete mode 100644 sbt-plugin/src/main/scala/org/scalajs/sbtplugin/JSPlatform.scala create mode 100644 sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/ScalaJSGroupID.scala diff --git a/project/Build.scala b/project/Build.scala index b908d1ee7a..35ee737144 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -803,7 +803,7 @@ object Build { else (sbtBinaryVersion in update).value val scalaV = (scalaBinaryVersion in update).value Defaults.sbtPluginExtra( - "org.scala-native" % "sbt-crossproject" % "0.2.1", sbtV, scalaV) + "org.portable-scala" % "sbt-platform-deps" % "1.0.0-M2", sbtV, scalaV) }, // Add API mappings for sbt (seems they don't export their API URL) diff --git a/project/build.sbt b/project/build.sbt index d433bf0545..be4979ac6a 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -4,7 +4,7 @@ addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.18") addSbtPlugin("org.scalastyle" % "scalastyle-sbt-plugin" % "1.0.0") -addSbtPlugin("org.scala-native" % "sbt-crossproject" % "0.2.1") +addSbtPlugin("org.portable-scala" % "sbt-platform-deps" % "1.0.0-M2") libraryDependencies += "org.scala-js" % "closure-compiler-java-6" % "v20160517" diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index f7d1ac7ba0..14b2593b86 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -1,5 +1,6 @@ import org.scalajs.core.tools.io._ import org.scalajs.sbtplugin.Loggers.sbtLogger2ToolsLogger +import org.scalajs.sbtplugin.ScalaJSCrossVersion lazy val concurrentFakeFullOptJS = taskKey[Any]("") lazy val concurrentUseOfLinkerTest = taskKey[Any]("") @@ -25,11 +26,8 @@ val baseSettings = versionSettings ++ Seq( val testScalaJSSourceMapAttribute = TaskKey[Unit]( "testScalaJSSourceMapAttribute", "", KeyRanks.BTask) -lazy val referencedCrossProjectJS = ProjectRef(file("referencedCrossProject"), "referencedCrossProjectJS") -lazy val referencedCrossProjectJVM = ProjectRef(file("referencedCrossProject"), "referencedCrossProjectJVM") - lazy val root = project.in(file(".")). - aggregate(noDOM, multiTestJS, multiTestJVM, referencedCrossProjectJS, referencedCrossProjectJVM) + aggregate(noDOM, multiTestJS, multiTestJVM) lazy val noDOM = project.settings(baseSettings: _*). enablePlugins(ScalaJSPlugin). @@ -69,33 +67,46 @@ lazy val noDOM = project.settings(baseSettings: _*). } ))) -lazy val testFramework = crossProject.crossType(CrossType.Pure). - settings(versionSettings: _*). - settings(name := "Dummy cross JS/JVM test framework"). - jsSettings( +lazy val testFrameworkCommonSettings = Def.settings( + versionSettings, + name := "Dummy cross JS/JVM test framework", + scalaSource in Compile := baseDirectory.value.getParentFile / "src/main/scala" +) + +lazy val testFrameworkJS = project.in(file("testFramework/.js")). + enablePlugins(ScalaJSPlugin). + settings( + testFrameworkCommonSettings, libraryDependencies += "org.scala-js" %% "scalajs-test-interface" % scalaJSVersion - ). - jvmSettings( + ) + +lazy val testFrameworkJVM = project.in(file("testFramework/.jvm")). + settings( + testFrameworkCommonSettings, libraryDependencies ++= Seq( "org.scala-sbt" % "test-interface" % "1.0", "org.scala-js" %% "scalajs-stubs" % scalaJSVersion % "provided" ) ) -lazy val testFrameworkJS = testFramework.js -lazy val testFrameworkJVM = testFramework.jvm +lazy val multiTestCommonSettings = Def.settings( + unmanagedSourceDirectories in Compile += + baseDirectory.value.getParentFile / "shared/src/main/scala", + unmanagedSourceDirectories in Test += + baseDirectory.value.getParentFile / "shared/src/test/scala", + + testFrameworks ++= Seq( + TestFramework("sbttest.framework.DummyFramework"), + TestFramework("inexistent.Foo", "another.strange.Bar") + ) +) -lazy val multiTest = crossProject. - jsConfigure(_.enablePlugins(ScalaJSJUnitPlugin)). +lazy val multiTestJS = project.in(file("multiTest/js")). + enablePlugins(ScalaJSJUnitPlugin). + settings(multiTestCommonSettings). + settings(baseSettings: _*). settings( - testFrameworks ++= Seq( - TestFramework("sbttest.framework.DummyFramework"), - TestFramework("inexistent.Foo", "another.strange.Bar") - ) - ). - jsSettings(baseSettings: _*). - jsSettings( name := "Multi test framework test JS", // Make FrameworkDetector resilient to other output - #1572 @@ -105,10 +116,10 @@ lazy val multiTest = crossProject. consoleWriter +: (jsExecutionFiles in Test).value }, - // Test crossPlatform (as a setting, it's evaluated when loading the build) - crossPlatform ~= { value => - assert(value == JSPlatform, - "crossPlatform should be JSPlatform in multiTestJS") + // Test platformDepsCrossVersion (as a setting, it's evaluated when loading the build) + platformDepsCrossVersion ~= { value => + assert(value eq ScalaJSCrossVersion.binary, + "platformDepsCrossVersion should be ScalaJSCrossVersion.binary in multiTestJS") value }, @@ -125,36 +136,25 @@ lazy val multiTest = crossProject. }, "fullOptJS does not have the correct scalaJSSourceMap attribute") } ). - jvmSettings(versionSettings: _*). - jvmSettings( + dependsOn(testFrameworkJS % "test") + +lazy val multiTestJVM = project.in(file("multiTest/jvm")). + settings(multiTestCommonSettings). + settings(versionSettings: _*). + settings( name := "Multi test framework test JVM", libraryDependencies += "com.novocode" % "junit-interface" % "0.9" % "test", - // Test crossPlatform (as a setting, it's evaluated when loading the build) - crossPlatform ~= { value => - assert(value == JVMPlatform, - "crossPlatform should be JVMPlatform in multiTestJVM") + // Test platformDepsCrossVersion (as a setting, it's evaluated when loading the build) + platformDepsCrossVersion := { + val value = platformDepsCrossVersion.value + if (!sbtVersion.value.startsWith("0.")) { + // In 0.13, CrossVersions do not have a meaningful ==, but they do in 1.0 + assert(value == CrossVersion.binary, + "platformDepsCrossVersion should be CrossVersion.binary in multiTestJVM") + } value } ). - settings( - // Scala cross-version support for shared source directory - #2005 - unmanagedSourceDirectories in Compile := { - val srcDirs = (unmanagedSourceDirectories in Compile).value - val version = scalaBinaryVersion.value - val expected = - (baseDirectory.value.getParentFile / "shared" / "src" / "main" / s"scala-$version").getPath - assert(srcDirs.exists(_.getPath == expected)) - srcDirs - } - ). - dependsOn(testFramework % "test") - -lazy val multiTestJS = multiTest.js -lazy val multiTestJVM = multiTest.jvm - -// Test %%% macro - #1331 -val unusedSettings = Seq( - libraryDependencies += "org.example" %%% "dummy" % "0.1" -) + dependsOn(testFrameworkJVM % "test") diff --git a/sbt-plugin-test/referencedCrossProject/build.sbt b/sbt-plugin-test/referencedCrossProject/build.sbt deleted file mode 100644 index 0183a472dc..0000000000 --- a/sbt-plugin-test/referencedCrossProject/build.sbt +++ /dev/null @@ -1,7 +0,0 @@ -lazy val referencedCrossProject = crossProject. - crossType(CrossType.Pure). - in(file(".")). - settings(scalaVersion := "2.11.12") - -lazy val referencedCrossProjectJS = referencedCrossProject.js -lazy val referencedCrossProjectJVM = referencedCrossProject.jvm diff --git a/sbt-plugin-test/referencedCrossProject/project/build.properties b/sbt-plugin-test/referencedCrossProject/project/build.properties deleted file mode 100644 index 748703f770..0000000000 --- a/sbt-plugin-test/referencedCrossProject/project/build.properties +++ /dev/null @@ -1 +0,0 @@ -sbt.version=0.13.7 diff --git a/sbt-plugin-test/referencedCrossProject/project/build.sbt b/sbt-plugin-test/referencedCrossProject/project/build.sbt deleted file mode 100644 index 6626b7a52e..0000000000 --- a/sbt-plugin-test/referencedCrossProject/project/build.sbt +++ /dev/null @@ -1,2 +0,0 @@ -addSbtPlugin("org.scala-js" % "sbt-scalajs" % - org.scalajs.core.ir.ScalaJSVersions.current) diff --git a/sbt-plugin-test/referencedCrossProject/project/project/build.sbt b/sbt-plugin-test/referencedCrossProject/project/project/build.sbt deleted file mode 100644 index 3364d58f3e..0000000000 --- a/sbt-plugin-test/referencedCrossProject/project/project/build.sbt +++ /dev/null @@ -1 +0,0 @@ -sources in Compile += baseDirectory.value / "../../../../ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala" diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/JSPlatform.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/JSPlatform.scala deleted file mode 100644 index b9a51ec449..0000000000 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/JSPlatform.scala +++ /dev/null @@ -1,24 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - -package org.scalajs.sbtplugin - -import sbt._ - -import sbtcrossproject._ - -case object JSPlatform extends Platform { - val crossBinary: CrossVersion = ScalaJSCrossVersion.binary - val crossFull: CrossVersion = ScalaJSCrossVersion.full - - def identifier: String = "js" - def sbtSuffix: String = "JS" - - def enable(project: Project): Project = - project.enablePlugins(ScalaJSPlugin) -} diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index f29fbaa1ed..3eb9865c86 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -14,8 +14,6 @@ import scala.language.implicitConversions import sbt._ import sbt.Keys._ -import sbtcrossproject._ - import org.scalajs.core.ir.ScalaJSVersions import org.scalajs.core.tools.io._ @@ -32,24 +30,6 @@ object ScalaJSPlugin extends AutoPlugin { /** The current version of the Scala.js sbt plugin and tool chain. */ val scalaJSVersion = ScalaJSVersions.current - // The JS platform for sbt-crossproject - val JSPlatform = org.scalajs.sbtplugin.JSPlatform - - implicit def JSCrossProjectBuilderOps( - builder: CrossProject.Builder): JSCrossProjectOps = { - new JSCrossProjectOps(builder.crossType(CrossType.Full)) - } - - implicit class JSCrossProjectOps(project: CrossProject) { - def js: Project = project.projects(JSPlatform) - - def jsSettings(ss: Def.SettingsDefinition*): CrossProject = - jsConfigure(_.settings(ss: _*)) - - def jsConfigure(transformer: Project => Project): CrossProject = - project.configurePlatform(JSPlatform)(transformer) - } - // Stage values val FastOptStage = Stage.FastOpt val FullOptStage = Stage.FullOpt diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index d6163a7257..c82a8209a6 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -10,7 +10,7 @@ import sbt._ import sbt.Keys._ import sbt.complete.DefaultParsers._ -import sbtcrossproject.CrossPlugin.autoImport._ +import org.portablescala.sbtplatformdeps.PlatformDepsPlugin.autoImport._ import org.scalajs.core.tools.io.{IO => _, _} import org.scalajs.core.tools.linker._ @@ -449,7 +449,7 @@ private[sbtplugin] object ScalaJSPluginInternal { ) private val scalaJSProjectBaseSettings = Seq( - crossPlatform := JSPlatform, + platformDepsCrossVersion := ScalaJSCrossVersion.binary, scalaJSLinkerConfig := { StandardLinker.Config() diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/ScalaJSGroupID.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/ScalaJSGroupID.scala new file mode 100644 index 0000000000..22822181cb --- /dev/null +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/ScalaJSGroupID.scala @@ -0,0 +1,7 @@ +package org.scalajs.sbtplugin.impl + +/** Exclusively for binary compatibility with sbt-scalajs-crossproject. */ +@deprecated( + "Exclusively for binary compatibility with sbt-scalajs-crossproject.", + "forever") +private[impl] class ScalaJSGroupID From 9f598a24c13b2f78b262d95919edb6f43966d7fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 24 Nov 2017 15:40:50 +0100 Subject: [PATCH 0555/2665] Move the implementation of j.l.Object.clone to j.l.ObjectClone. Previously, it was in `scalajs.runtime`, but there is no good reason for this. It is an implementation detail of the `java.lang` package, which can therefore stay as `private[lang]`. --- .../main/scala/java/lang/ObjectClone.scala | 25 +++++++++++++++++++ .../scala/scala/scalajs/runtime/package.scala | 10 -------- project/JavaLangObject.scala | 4 +-- 3 files changed, 27 insertions(+), 12 deletions(-) create mode 100644 javalanglib/src/main/scala/java/lang/ObjectClone.scala diff --git a/javalanglib/src/main/scala/java/lang/ObjectClone.scala b/javalanglib/src/main/scala/java/lang/ObjectClone.scala new file mode 100644 index 0000000000..6a604a2c9b --- /dev/null +++ b/javalanglib/src/main/scala/java/lang/ObjectClone.scala @@ -0,0 +1,25 @@ +package java.lang + +import scala.scalajs.js + +/** Implementation of `java.lang.Object.clone()`. + * + * Called by the hard-coded IR of `java.lang.Object`. + */ +private[lang] object ObjectClone { + /** Returns a new shallow clone of `o`. + * + * This method does not test that `o` is an instance of `Cloneable`. The + * caller should do that themselves, although this `cloneObject` does not + * rely on that property for correctness. + */ + def clone(o: Object): Object = { + val fromDyn = o.asInstanceOf[js.Dynamic] + val result = js.Dynamic.newInstance(fromDyn.constructor)() + val fromDict = o.asInstanceOf[js.Dictionary[js.Any]] + val resultDict = result.asInstanceOf[js.Dictionary[js.Any]] + for (key <- fromDict.keys) + resultDict(key) = fromDict(key) + result + } +} diff --git a/library/src/main/scala/scala/scalajs/runtime/package.scala b/library/src/main/scala/scala/scalajs/runtime/package.scala index 76708ff355..6280606d20 100644 --- a/library/src/main/scala/scala/scalajs/runtime/package.scala +++ b/library/src/main/scala/scala/scalajs/runtime/package.scala @@ -16,16 +16,6 @@ package object runtime { case _ => th } - def cloneObject(from: js.Object): js.Object = { - val fromDyn = from.asInstanceOf[js.Dynamic] - val result = js.Dynamic.newInstance(fromDyn.constructor)() - val fromDict = from.asInstanceOf[js.Dictionary[js.Any]] - val resultDict = result.asInstanceOf[js.Dictionary[js.Any]] - for (key <- fromDict.keys) - resultDict(key) = fromDict(key) - result - } - @inline final def genTraversableOnce2jsArray[A]( col: GenTraversableOnce[A]): js.Array[A] = { col match { diff --git a/project/JavaLangObject.scala b/project/JavaLangObject.scala index bc45f0fa60..74ba0c432b 100644 --- a/project/JavaLangObject.scala +++ b/project/JavaLangObject.scala @@ -87,8 +87,8 @@ object JavaLangObject { AnyType, Some { If(IsInstanceOf(This()(ThisType), ClassRef("jl_Cloneable")), { - Apply(LoadModule(ClassType("sjsr_package$")), - Ident("cloneObject__sjs_js_Object__sjs_js_Object", Some("cloneObject")), + Apply(LoadModule(ClassType("jl_ObjectClone$")), + Ident("clone__O__O", Some("clone")), List(This()(ThisType)))(AnyType) }, { Throw(New(ClassType("jl_CloneNotSupportedException"), From 51bdccf07bb72c8cec08c9e1222eb3b203731c29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 24 Nov 2017 16:27:07 +0100 Subject: [PATCH 0556/2665] Fix #3192: Do not reexecute the constructor in `Object.clone()`. We now use the "official" way to create a shallow copy of a JavaScript object, which uses a combination of `Object.create`, `Object.getPrototypeOf` and `Object.getOwnPropertyDescriptors`. The latter was introduced in ECMAScript 2017, though, so we need to polyfill it, and along with it two other functions from ECMAScript 2015. --- .../main/scala/java/lang/ObjectClone.scala | 79 +++++++++++++++++-- .../testsuite/javalib/lang/ObjectTest.scala | 20 +++++ 2 files changed, 92 insertions(+), 7 deletions(-) diff --git a/javalanglib/src/main/scala/java/lang/ObjectClone.scala b/javalanglib/src/main/scala/java/lang/ObjectClone.scala index 6a604a2c9b..3cf57e2b79 100644 --- a/javalanglib/src/main/scala/java/lang/ObjectClone.scala +++ b/javalanglib/src/main/scala/java/lang/ObjectClone.scala @@ -7,6 +7,76 @@ import scala.scalajs.js * Called by the hard-coded IR of `java.lang.Object`. */ private[lang] object ObjectClone { + private val getOwnPropertyDescriptors: js.Function1[js.Object, js.Object] = { + import js.Dynamic.{global, literal} + + // The val f = ...; f.asInstanceOf's are necessary for 2.10 not to crash + + // Fetch or polyfill Object.getOwnPropertyDescriptors + if (js.typeOf(global.Object.getOwnPropertyDescriptors) == "function") { + val f = global.Object.getOwnPropertyDescriptors + f.asInstanceOf[js.Function1[js.Object, js.Object]] + } else { + // Fetch or polyfill Reflect.ownKeys + type OwnKeysType = js.Function1[js.Object, js.Array[js.Any]] + val ownKeysFun: OwnKeysType = { + if (js.typeOf(global.Reflect) != "undefined" && + js.typeOf(global.Reflect.ownKeys) == "function") { + val f = global.Reflect.ownKeys + f.asInstanceOf[OwnKeysType] + } else { + // Fetch Object.getOwnPropertyNames + val getOwnPropertyNames = { + val f = global.Object.getOwnPropertyNames + f.asInstanceOf[OwnKeysType] + } + + // Fetch or polyfill Object.getOwnPropertySymbols + val getOwnPropertySymbols: OwnKeysType = { + if (js.typeOf(global.Object.getOwnPropertySymbols) == "function") { + val f = global.Object.getOwnPropertySymbols + f.asInstanceOf[OwnKeysType] + } else { + /* Polyfill for Object.getOwnPropertySymbols. + * We assume that if that function does not exist, then symbols + * do not exist at all. Therefore, the result is always an empty + * array. + */ + { (o: js.Object) => + js.Array[js.Any]() + } + } + } + + // Polyfill for Reflect.ownKeys + { (o: js.Object) => + getOwnPropertyNames(o) ++ getOwnPropertySymbols(o) + } + } + } + + // Polyfill for Object.getOwnPropertyDescriptors + { (o: js.Object) => + val ownKeys = ownKeysFun(o) + val descriptors = new js.Object + for (key <- ownKeys) { + /* Almost equivalent to the JavaScript code + * descriptors[key] = Object.getOwnPropertyDescriptor(descriptors, key); + * except that `defineProperty` will by-pass any existing setter for + * the property `key` on `descriptors` or in its prototype chain. + */ + global.Object.defineProperty(descriptors, key, literal( + configurable = true, + enumerable = true, + writable = true, + value = global.Object.getOwnPropertyDescriptor(o, key) + )) + } + descriptors + } + } + } + /** Returns a new shallow clone of `o`. * * This method does not test that `o` is an instance of `Cloneable`. The @@ -14,12 +84,7 @@ private[lang] object ObjectClone { * rely on that property for correctness. */ def clone(o: Object): Object = { - val fromDyn = o.asInstanceOf[js.Dynamic] - val result = js.Dynamic.newInstance(fromDyn.constructor)() - val fromDict = o.asInstanceOf[js.Dictionary[js.Any]] - val resultDict = result.asInstanceOf[js.Dictionary[js.Any]] - for (key <- fromDict.keys) - resultDict(key) = fromDict(key) - result + js.Object.create(js.Object.getPrototypeOf(o.asInstanceOf[js.Object]), + getOwnPropertyDescriptors(o.asInstanceOf[js.Object])) } } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ObjectTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ObjectTest.scala index 075478d5d5..55a070886f 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ObjectTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ObjectTest.scala @@ -74,4 +74,24 @@ class ObjectTest { (Array(Nil) : Any).asInstanceOf[Object] (null : Any).asInstanceOf[Object] } + + @Test def cloneCtorSideEffects_issue_3192(): Unit = { + var ctorInvokeCount = 0 + + // This class has an inlineable init + class CloneCtorSideEffectsBug(val x: Int) extends java.lang.Cloneable { + ctorInvokeCount += 1 + + override def clone(): CloneCtorSideEffectsBug = + super.clone().asInstanceOf[CloneCtorSideEffectsBug] + } + + val o = new CloneCtorSideEffectsBug(54) + assertEquals(54, o.x) + assertEquals(1, ctorInvokeCount) + + val o2 = o.clone() + assertEquals(54, o2.x) + assertEquals(1, ctorInvokeCount) + } } From e40c92c65ad700e28d4555434c9ab86c7bc7a9f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 26 Nov 2017 17:58:21 +0100 Subject: [PATCH 0557/2665] Fix the build: bincompat check fails on JDK 6, Scala 2.10.7. --- project/BinaryIncompatibilities.scala | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 610a504fe3..165b459665 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -100,6 +100,10 @@ object BinaryIncompatibilities { "org.scalajs.testadapter.ComJSEnvRPC.close"), ProblemFilters.exclude[DirectMissingMethodProblem]( "org.scalajs.testadapter.ComJSEnvRPC.this"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.testadapter.TestAdapter#ManagedRunner.this"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "org.scalajs.testadapter.TestAdapter#ManagedRunner.com"), // private, not an issue. ProblemFilters.exclude[MissingClassProblem]( From 9e9883e4eb2f7e76e246d3fcf51e57bbeef45e42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 31 Oct 2017 16:06:47 +0100 Subject: [PATCH 0558/2665] Fix #2805 and #2398: Nested JavaScript classes. This commit dramatically changes the way nested JS classes are compiled, to fix a pervasive issue about their semantics. We call a class "nested" if it either *inner* (defined in the body of a class, trait, or non-static object) or *local* (defined inside a `def`). The semantic issue is that we have always allowed the definition of nested non-native JS classes, but using the normal compilation scheme of scalac, driven by explicitouter and lambdalift. This caused their constructor to be visible to JavaScript (and JS interop within Scala.js) as having more arguments, for the captures. For Scala classes, this is not an issue, as their constructor cannot be manipulated by JavaScript. But for JavaScript classes, it is probablematic. For example, consider: class Enclosing(val x: Int) { class InnerJSClass extends js.Object { def getX(): Int = x } } Because of `explicitouter`, the constructor of `InnerJSClass` takes an additional parameter `$outer` of type `Enclosing`. This means that if we ask for `js.constructor[enclosing.InnerJSClass]`, we receive a class value that is basically unusable. For local classes, lambdalift would add zero to many parameters for captures of local vals and vars. For nested *native* JS classes, there was "no issue" in the sense that they were disallowed as compile errors to begin with. However, this is a limitation, as evidenced by the issue #2398. The new semantics for nested JS classes are the "obvious" ones. If they capture stuff (the outer pointer and/or local vals), they are properly *captured* by the JS class value, and are therefore not visible as constructor parameters. Additionally, and relatedly, this means that for inner JS classes, there is a different JS class value for each enclosing instance. For local JS classes, there is a different JS class value for each time the code "executes" the class declaration. Together, these changes to the semantics address #2805. Given all the infrastructure that is set up for the above, it also becomes trivial (and more consistent) to address #2398 in the same sweep. Indeed, it is virtually only a matter of lifting compile-time checks. Implementing the above semantics is far from being trivial, because erasure tends to destroy a lot of information that we need. In particular, it will destroy the *paths* of inner JS classes (or *prefixes* in scalac terms). flatten will also destroy the identity of nested JS classes, preventing from distinguishing inner classes by their enclosing instance and local classes by their "execution path". We address this with actual code transformations of the scalac trees, something that has no real precedent in our compiler plugin. We actually reify nested JS classes, in two steps, before erasure kicks in and destroys what we need. The first step, in phase `xplicitinnerjs`, creates for every inner JS class, a field in its enclosing class to hold its JS class value. The second step, in phase `xplicitlocaljs`, does something similar with local vals for local JS classes, and transforms all references to preserve identities. Ideally, this would be done in a single phase, but we need to do some work *before* the phase `fields` of Scala 2.12+, and some *after* that phase. In particular, we need to * create the inner JS class fields before `fields`, so that the latter phase will correctly mix them in subclasses of traits, and * desugar references to module classes after `fields`, since it is that phase that reifies modules. Since there can be dependencies of all sorts between *references* to inner- and local JS classes, all references must be processed in the same phase. This is why `xplicitlocaljs` actually desugars all references, including those to inner JS classes. `xplicitinnerjs` only creates the fields that will hold the JS class values. For further information on the implementation, and code snippets before and after the transformations, refer to the long Scaladoc comments of those two phases. --- .../core/compiler/Compat210Component.scala | 17 + .../core/compiler/ExplicitInnerJS.scala | 218 +++++++ .../core/compiler/ExplicitLocalJS.scala | 406 ++++++++++++ .../org/scalajs/core/compiler/GenJSCode.scala | 410 ++++++++---- .../scalajs/core/compiler/GenJSExports.scala | 76 ++- .../scalajs/core/compiler/JSDefinitions.scala | 3 + .../scalajs/core/compiler/JSEncoding.scala | 26 +- .../core/compiler/JSGlobalAddons.scala | 57 ++ .../scalajs/core/compiler/JSPrimitives.scala | 39 +- .../scalajs/core/compiler/PrepJSInterop.scala | 136 ++-- .../scalajs/core/compiler/ScalaJSPlugin.scala | 16 +- .../core/compiler/test/JSInteropTest.scala | 234 +++++-- .../scala/org/scalajs/core/ir/Hashers.scala | 15 +- .../scala/org/scalajs/core/ir/Printers.scala | 17 + .../org/scalajs/core/ir/Serializers.scala | 34 +- .../main/scala/org/scalajs/core/ir/Tags.scala | 1 + .../org/scalajs/core/ir/Transformers.scala | 6 +- .../org/scalajs/core/ir/Traversers.scala | 4 + .../scala/org/scalajs/core/ir/Trees.scala | 51 +- .../org/scalajs/core/ir/PrintersTest.scala | 72 ++- .../scala/scala/scalajs/runtime/package.scala | 39 ++ .../scalajs/2.11.0/neg/t6446-additional.check | 38 +- .../scalajs/2.11.0/neg/t6446-missing.check | 36 +- .../2.11.0/neg/t6446-show-phases.check | 36 +- .../scalajs/2.11.0/neg/t7494-no-options.check | 38 +- .../partest/scalajs/2.11.0/run/t6102.check | 2 + .../scalajs/2.11.1/neg/t6446-additional.check | 38 +- .../scalajs/2.11.1/neg/t6446-missing.check | 36 +- .../2.11.1/neg/t6446-show-phases.check | 36 +- .../scalajs/2.11.1/neg/t7494-no-options.check | 38 +- .../partest/scalajs/2.11.1/run/t6102.check | 2 + .../2.11.11/neg/t6446-additional.check | 38 +- .../scalajs/2.11.11/neg/t6446-missing.check | 36 +- .../2.11.11/neg/t6446-show-phases.check | 36 +- .../2.11.11/neg/t7494-no-options.check | 38 +- .../partest/scalajs/2.11.11/run/t6102.check | 2 + .../2.11.12/neg/t6446-additional.check | 38 +- .../scalajs/2.11.12/neg/t6446-missing.check | 36 +- .../2.11.12/neg/t6446-show-phases.check | 36 +- .../2.11.12/neg/t7494-no-options.check | 38 +- .../partest/scalajs/2.11.12/run/t6102.check | 2 + .../scalajs/2.11.2/neg/t6446-additional.check | 38 +- .../scalajs/2.11.2/neg/t6446-missing.check | 36 +- .../2.11.2/neg/t6446-show-phases.check | 36 +- .../scalajs/2.11.2/neg/t7494-no-options.check | 38 +- .../partest/scalajs/2.11.2/run/t6102.check | 2 + .../scalajs/2.11.5/neg/t6446-additional.check | 38 +- .../scalajs/2.11.5/neg/t6446-missing.check | 36 +- .../2.11.5/neg/t6446-show-phases.check | 36 +- .../scalajs/2.11.5/neg/t7494-no-options.check | 38 +- .../partest/scalajs/2.11.5/run/t6102.check | 2 + .../scalajs/2.11.6/neg/t6446-additional.check | 38 +- .../scalajs/2.11.6/neg/t6446-missing.check | 36 +- .../2.11.6/neg/t6446-show-phases.check | 36 +- .../scalajs/2.11.6/neg/t7494-no-options.check | 38 +- .../partest/scalajs/2.11.6/run/t6102.check | 2 + .../scalajs/2.11.7/neg/t6446-additional.check | 38 +- .../scalajs/2.11.7/neg/t6446-missing.check | 36 +- .../2.11.7/neg/t6446-show-phases.check | 36 +- .../scalajs/2.11.7/neg/t7494-no-options.check | 38 +- .../partest/scalajs/2.11.7/run/t6102.check | 2 + .../scalajs/2.11.8/neg/t6446-additional.check | 38 +- .../scalajs/2.11.8/neg/t6446-missing.check | 36 +- .../2.11.8/neg/t6446-show-phases.check | 36 +- .../scalajs/2.11.8/neg/t7494-no-options.check | 38 +- .../partest/scalajs/2.11.8/run/t6102.check | 2 + .../scalajs/2.12.1/neg/t6446-additional.check | 36 +- .../scalajs/2.12.1/neg/t6446-missing.check | 34 +- .../2.12.1/neg/t6446-show-phases.check | 34 +- .../scalajs/2.12.1/neg/t7494-no-options.check | 36 +- .../scalajs/2.12.2/neg/t6446-additional.check | 36 +- .../scalajs/2.12.2/neg/t6446-missing.check | 34 +- .../2.12.2/neg/t6446-show-phases.check | 34 +- .../scalajs/2.12.2/neg/t7494-no-options.check | 36 +- .../scalajs/2.12.3/neg/t6446-additional.check | 36 +- .../scalajs/2.12.3/neg/t6446-missing.check | 34 +- .../2.12.3/neg/t6446-show-phases.check | 34 +- .../scalajs/2.12.3/neg/t7494-no-options.check | 36 +- .../scalajs/2.12.4/neg/t6446-additional.check | 36 +- .../scalajs/2.12.4/neg/t6446-missing.check | 34 +- .../2.12.4/neg/t6446-show-phases.check | 34 +- .../scalajs/2.12.4/neg/t7494-no-options.check | 36 +- .../2.13.0-M2/neg/t6446-additional.check | 36 +- .../scalajs/2.13.0-M2/neg/t6446-missing.check | 34 +- .../2.13.0-M2/neg/t6446-show-phases.check | 34 +- .../2.13.0-M2/neg/t7494-no-options.check | 36 +- project/JavaLangObject.scala | 2 + .../jsinterop/JSOptionalTest212.scala | 14 +- .../compiler/InteroperabilityTest.scala | 89 +++ .../testsuite/jsinterop/ExportsTest.scala | 6 +- .../testsuite/jsinterop/JSOptionalTest.scala | 14 +- .../jsinterop/NestedJSClassTest.scala | 596 ++++++++++++++++++ .../jsinterop/NonNativeJSTypeTest.scala | 17 + .../core/tools/linker/LinkedClass.scala | 6 + .../core/tools/linker/analyzer/Infos.scala | 3 + .../linker/backend/emitter/ClassEmitter.scala | 99 ++- .../backend/emitter/FunctionEmitter.scala | 58 +- .../backend/emitter/GlobalKnowledge.scala | 9 +- .../tools/linker/backend/emitter/JSGen.scala | 9 +- .../backend/emitter/KnowledgeGuardian.scala | 45 ++ .../core/tools/linker/checker/IRChecker.scala | 95 ++- .../tools/linker/frontend/BaseLinker.scala | 2 + .../frontend/optimizer/OptimizerCore.scala | 3 + .../core/tools/linker/AnalyzerTest.scala | 8 +- 104 files changed, 3669 insertions(+), 1333 deletions(-) create mode 100644 compiler/src/main/scala/org/scalajs/core/compiler/ExplicitInnerJS.scala create mode 100644 compiler/src/main/scala/org/scalajs/core/compiler/ExplicitLocalJS.scala create mode 100644 test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/NestedJSClassTest.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala b/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala index 750fab97f2..feb03c748e 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala @@ -28,12 +28,17 @@ trait Compat210Component { def unexpandedName: Name = self.originalName def originalName: Name = infiniteLoop() + def originalOwner: Symbol = + global.originalOwner.getOrElse(self, self.rawowner) + def isPrivateThis: Boolean = self.hasAllFlags(PRIVATE | LOCAL) def isLocalToBlock: Boolean = self.isLocal def implClass: Symbol = NoSymbol def isTraitOrInterface: Boolean = self.isTrait || self.isInterface + + def tpe_* : Type = self.tpe // scalastyle:ignore } // enteringPhase/exitingPhase replace beforePhase/afterPhase @@ -56,6 +61,18 @@ trait Compat210Component { def afterPhase[T](ph: Phase)(op: => T): T = infiniteLoop() def delambdafy: DelambdafyCompat.type = DelambdafyCompat + + // Copied from internal/Trees.scala + def NewFromConstructor(constructor: Symbol, args: Tree*): Apply = { + assert(constructor.isConstructor, constructor) + val instance = New(TypeTree(constructor.owner.tpe)) + val init = Select(instance, nme.CONSTRUCTOR).setSymbol(constructor) + Apply(init, args.toList) + } + + object originalOwner { + def getOrElse(sym: Symbol, orElse: => Symbol): Symbol = infiniteLoop() + } } object DelambdafyCompat { diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitInnerJS.scala b/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitInnerJS.scala new file mode 100644 index 0000000000..75d1181233 --- /dev/null +++ b/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitInnerJS.scala @@ -0,0 +1,218 @@ +/* Scala.js compiler + * Copyright 2013-2017 LAMP/EPFL + */ + +package org.scalajs.core.compiler + +import scala.reflect.internal.Flags + +import scala.tools.nsc +import nsc._ +import nsc.transform.{InfoTransform, TypingTransformers} + +import scala.collection.immutable.ListMap +import scala.collection.mutable + +/** Makes the references to inner JS class values explicit. + * + * Roughly, for every inner JS class of the form: + * {{{ + * class Outer { + * class Inner extends ParentJSClass + * } + * }}} + * this phase creates a field `Inner$jsclass` in `Outer` to hold the JS class + * value for `Inner`. The rhs of that field is a call to a magic method, used + * to retain information that the back-end will need. + * {{{ + * class Outer { + * val Inner$jsclass: AnyRef = + * createJSClass(classOf[Inner], js.constructorOf[ParentJSClass]) + * + * class Inner extends ParentJSClass + * } + * }}} + * + * These fields will be read by code generated in `ExplicitLocalJS`. + * + * Note that this field must also be added to outer classes and traits coming + * from separate compilation, therefore this phase is an `InfoTransform`. + * Since the `transformInfo` also applies to classes defined in the current + * compilation unit, the tree traversal must not create the field symbols a + * second time when synthesizing the `ValDef`. Instead, it must reuse the same + * symbols that `transformInfo` will create. + * + * It seems the easiest way to do that is to run the entire `transform` "in + * the future", with `exitingPhase(ExplicitInnerJS)`. This design is similar + * to how `explicitouter` works. + */ +abstract class ExplicitInnerJS + extends plugins.PluginComponent with InfoTransform with TypingTransformers + with PluginComponent210Compat { + + val jsAddons: JSGlobalAddons { + val global: ExplicitInnerJS.this.global.type + } + + import global._ + import jsAddons._ + import jsInterop.jsclassAccessorFor + import definitions._ + import rootMirror._ + import jsDefinitions._ + + /* The missing 'e' is intentional so that the name of the phase is not longer + * than the longest standard phase (packageobjects/superaccessors). This + * avoids destroying the nice formatting of `-Xshow-phases`. + */ + val phaseName: String = "xplicitinnerjs" + + override def description: String = + "make references to inner JS classes explicit" + + /** This class does not change linearization. */ + override protected def changesBaseClasses: Boolean = false + + /** Whether vals in traits are represented by their getter. + * This is true in 2.12+, since the addition of the `fields` phase. + * @see https://github.com/scala/scala/pull/5141 + */ + private lazy val traitValsHoldTheirGetterSymbol = { + val v = scala.util.Properties.versionNumberString + !v.startsWith("2.10.") && !v.startsWith("2.11.") + } + + protected def newTransformer(unit: CompilationUnit): Transformer = + new ExplicitInnerJSTransformer(unit) + + /** Is the given clazz an inner JS class? */ + private def isInnerJSClass(clazz: Symbol): Boolean = { + clazz.hasAnnotation(RawJSTypeAnnot) && + !clazz.isPackageClass && !clazz.outerClass.isStaticOwner && + !clazz.isLocalToBlock && !clazz.isModuleClass && !clazz.isTrait + } + + /** Transforms the info of types to add the `Inner$jsclass` fields. + * + * This method was inspired by `ExplicitOuter.transformInfo`. + */ + def transformInfo(sym: Symbol, tp: Type): Type = tp match { + case ClassInfoType(parents, decls, clazz) if !clazz.isJava => + val innerJSClasses = decls.filter(isInnerJSClass) + if (innerJSClasses.isEmpty) { + tp + } else { + val clazzIsJSClass = clazz.hasAnnotation(RawJSTypeAnnot) + + val decls1 = decls.cloneScope + for (innerJSClass <- innerJSClasses) { + def addAnnotsIfInJSClass(sym: Symbol): Unit = { + if (clazzIsJSClass) { + innerJSClass.getAnnotation(JSNameAnnotation).fold { + sym.addAnnotation(JSNameAnnotation, + Literal(Constant(jsInterop.defaultJSNameOf(innerJSClass)))) + } { annot => + sym.addAnnotation(annot) + } + sym.addAnnotation(ExposedJSMemberAnnot) + } + } + + val accessorName = innerJSClass.name.append("$jsclass").toTermName + val accessorFlags = + Flags.SYNTHETIC | Flags.ARTIFACT | Flags.STABLE | Flags.ACCESSOR + val accessor = + clazz.newMethod(accessorName, innerJSClass.pos, accessorFlags) + accessor.setInfo(NullaryMethodType(AnyRefTpe)) + addAnnotsIfInJSClass(accessor) + decls1.enter(accessor) + + if (!clazz.isTrait || !traitValsHoldTheirGetterSymbol) { + val fieldName = accessorName.append(nme.LOCAL_SUFFIX_STRING) + val fieldFlags = + Flags.SYNTHETIC | Flags.ARTIFACT | Flags.PrivateLocal + val field = clazz + .newValue(fieldName, innerJSClass.pos, fieldFlags) + .setInfo(AnyRefTpe) + addAnnotsIfInJSClass(field) + decls1.enter(field) + } + } + ClassInfoType(parents, decls1, clazz) + } + + case PolyType(tparams, restp) => + val restp1 = transformInfo(sym, restp) + if (restp eq restp1) tp else PolyType(tparams, restp1) + + case _ => + tp + } + + class ExplicitInnerJSTransformer(unit: CompilationUnit) + extends TypingTransformer(unit) { + + /** Execute the whole transformation in the future, exiting this phase. */ + override def transformUnit(unit: CompilationUnit): Unit = { + global.exitingPhase(currentRun.phaseNamed(phaseName)) { + super.transformUnit(unit) + } + } + + /** The main transformation method. */ + override def transform(tree: Tree): Tree = { + val sym = tree.symbol + tree match { + // Add the ValDefs for inner JS class values + case Template(parents, self, decls) => + val newDecls = mutable.ListBuffer.empty[Tree] + atOwner(tree, currentOwner) { + for (decl <- decls) { + if ((decl.symbol ne null) && isInnerJSClass(decl.symbol)) { + val clazz = decl.symbol + val jsclassAccessor = jsclassAccessorFor(clazz) + + val rhs = if (sym.hasAnnotation(JSNativeAnnotation)) { + gen.mkAttributedRef(JSPackage_native) + } else { + val clazzValue = gen.mkClassOf(clazz.tpe_*) + val parentTpe = + extractSuperTpeFromImpl(decl.asInstanceOf[ClassDef].impl) + val superClassCtor = gen.mkNullaryCall( + JSPackage_constructorOf, List(parentTpe)) + gen.mkMethodCall(Runtime_createInnerJSClass, + List(clazzValue, superClassCtor)) + } + + if (!currentOwner.isTrait || !traitValsHoldTheirGetterSymbol) { + val jsclassField = jsclassAccessor.accessed + assert(jsclassField != NoSymbol, jsclassAccessor.fullName) + newDecls += localTyper.typedValDef(ValDef(jsclassField, rhs)) + newDecls += localTyper.typed { + val rhs = Select(This(currentClass), jsclassField) + DefDef(jsclassAccessor, rhs) + } + } else { + newDecls += localTyper.typedValDef(ValDef(jsclassAccessor, rhs)) + } + } + + newDecls += decl + } + } + + val newTemplate = + treeCopy.Template(tree, parents, self, newDecls.result()) + super.transform(newTemplate) + + case _ => + // Taken from ExplicitOuter + val x = super.transform(tree) + if (x.tpe eq null) x + else x.setType(transformInfo(currentOwner, x.tpe)) + } + } + + } + +} diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitLocalJS.scala b/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitLocalJS.scala new file mode 100644 index 0000000000..b518bf86c4 --- /dev/null +++ b/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitLocalJS.scala @@ -0,0 +1,406 @@ +/* Scala.js compiler + * Copyright 2013-2017 LAMP/EPFL + */ + +package org.scalajs.core.compiler + +import scala.reflect.internal.Flags + +import scala.tools.nsc +import nsc._ +import nsc.transform.{Transform, TypingTransformers} + +import scala.collection.immutable.ListMap +import scala.collection.mutable + +/** Makes the references to local JS classes explicit and desugars calls to + * `js.constructorOf`. + * + * It also makes explicit all references to inner JS classes, using the + * pointers created by `ExplicitInnerJS`, and otherwise makes sure the + * back-end will receive all the information it needs to translate inner- and + * local JS classes and objects. + * + * Note that in this comment, by "class" we mean *only* `class`es. `trait`s + * and `object`s are not implied. + * + * Similarly to how `ExplicitInnerJS` creates explicit fields in the enclosing + * templates of inner JS classes to hold the JS class values, this phase + * creates local vals for local JS classes in the enclosing statement list. + * + * For every local JS class of the form: + * {{{ + * def outer() = { + * class Local extends ParentJSClass + * } + * }}} + * this phase creates a local `val Local$jslass` in the body of `outer()` to + * hold the JS class value for `Local`. The rhs of that val is a call to a + * magic method, used to retain information that the back-end will need: + * + * - A reified reference to `class Local`, in the form of a `classOf` + * - An explicit reference to the super JS class value, i.e., the desugaring + * of `js.constructorOf[ParentJSClass]` + * - An array of fake `new` expressions for all overloaded constructors. + * + * The latter will be augmented by `lambdalift` with the appropriate actual + * parameters for the captures of `Local`, which will be needed by the + * back-end. In code, this looks like: + * {{{ + * def outer() = { + * class Local extends ParentJSClass + * val Local$jsclass: AnyRef = createLocalJSClass( + * classOf[Local], + * js.constructorOf[ParentJSClass], + * Array[AnyRef](new Local(), ...)) + * } + * }}} + * + * Since we need to insert fake `new Inner()`s, this scheme does not work for + * abstract local classes. We therefore reject them as implementation + * restriction. + * + * If the body of `Local` references itself, then the `val Local$jsclass` is + * instead declared as a `var` to work around the cyclic dependency: + * {{{ + * def outer() = { + * var Local$jsclass: AnyRef = null + * class Local extends ParentJSClass { + * ... + * } + * Local$jsclass = createLocalJSClass(...) + * } + * }}} + * + * In addition to the above, `ExplicitLocalJS` transforms all *call sites* of + * local JS classes *and* inner JS classes, so that they refer to the + * synthesized local vals and fields. + * + * The primary transformation is the desugaring of `js.constructorOf[C]`, + * which depends on the nature of `C`: + * + * - If `C` is a statically accessible class, desugar to + * `runtime.constructorOf(classOf[C])` so that the reified symbol survives + * erasure and reaches the back-end. + * - If `C` is an inner JS class, it must be of the form `path.D` for some + * pair (`path`, `D`), and we desugar it to `path.D$jsclass`, using the + * field created by `ExplicitInnerJS` (it is an error if `C` is of the form + * `Enclosing#D`). + * - If `C` is a local JS class, desugar to `C$jsclass`, using the local val + * created by this phase. + * + * The other transformations build on top of the desugaring of + * `js.constructorOf[C]`, and apply only to inner JS classes and local JS + * classes (not for statically accessible classes): + * + * - `x.isInstanceOf[C]` desugars into + * `js.special.instanceof(x, js.constructorOf[C])`. + * - `new C(...args)` desugars into + * `withContextualJSClassValue(js.constructorOf[C], new C(...args))`, so + * that the back-end receives a reified reference to the JS class value. + * - In the same spirit, for `D extends C`, `D.super.m(...args)` desugars into + * `withContextualJSClassValue(js.constructorOf[C], D.super.m(...args))`. + * + * Finally, for inner- and local JS *objects*, their (only) instantiation + * point of the form `new O.type()` is rewritten as + * `withContextualJSClassValue(js.constructorOf[ParentClassOfO], new O.type())`, + * so that the back-end receives a reified reference to the parent class of + * `O`. A similar treatment is applied on anonymous JS classes, which + * basically define something very similar to an `object`, although without + * its own JS class. + */ +abstract class ExplicitLocalJS + extends plugins.PluginComponent with Transform with TypingTransformers + with PluginComponent210Compat { + + val jsAddons: JSGlobalAddons { + val global: ExplicitLocalJS.this.global.type + } + + import global._ + import jsAddons._ + import jsInterop.jsclassAccessorFor + import definitions._ + import rootMirror._ + import jsDefinitions._ + + /* The missing 'e' is intentional so that the name of the phase is not longer + * than the longest standard phase (packageobjects/superaccessors). This + * avoids destroying the nice formatting of `-Xshow-phases`. + */ + val phaseName: String = "xplicitlocaljs" + + override def description: String = + "make references to local JS classes explicit" + + protected def newTransformer(unit: CompilationUnit): Transformer = + new ExplicitLocalJSTransformer(unit) + + /** Is the gen clazz an inner or local JS class? */ + private def isInnerOrLocalJSClass(sym: Symbol): Boolean = + isInnerJSClass(sym) || isLocalJSClass(sym) + + /** Is the given clazz an inner JS class? */ + private def isInnerJSClass(clazz: Symbol): Boolean = + isInnerJSClassOrObject(clazz) && !clazz.isModuleClass + + /** Is the given clazz a local JS class? */ + private def isLocalJSClass(clazz: Symbol): Boolean = { + isLocalJSClassOrObject(clazz) && + !clazz.isModuleClass && !clazz.isAnonymousClass + } + + /** Is the gen clazz an inner or local JS class or object? */ + private def isInnerOrLocalJSClassOrObject(sym: Symbol): Boolean = + isInnerJSClassOrObject(sym) || isLocalJSClassOrObject(sym) + + /** Is the given clazz an inner JS class or object? */ + private def isInnerJSClassOrObject(clazz: Symbol): Boolean = { + clazz.hasAnnotation(RawJSTypeAnnot) && + !clazz.isPackageClass && !clazz.outerClass.isStaticOwner && + !clazz.isLocalToBlock && !clazz.isTrait + } + + /** Is the given clazz a local JS class or object? */ + private def isLocalJSClassOrObject(clazz: Symbol): Boolean = { + def isJSLambda = + clazz.isAnonymousClass && AllJSFunctionClasses.exists(clazz.isSubClass(_)) + + clazz.isLocalToBlock && + !clazz.isTrait && clazz.hasAnnotation(RawJSTypeAnnot) && + !isJSLambda + } + + class ExplicitLocalJSTransformer(unit: CompilationUnit) + extends TypingTransformer(unit) { + + private val nestedObject2superClassTpe = mutable.Map.empty[Symbol, Type] + private val localClass2jsclassVal = mutable.Map.empty[Symbol, TermSymbol] + private val notYetSelfReferencingLocalClasses = mutable.Set.empty[Symbol] + + override def transformUnit(unit: CompilationUnit): Unit = { + try { + super.transformUnit(unit) + } finally { + nestedObject2superClassTpe.clear() + localClass2jsclassVal.clear() + notYetSelfReferencingLocalClasses.clear() + } + } + + /** The main transformation method. */ + override def transform(tree: Tree): Tree = { + val sym = tree.symbol + tree match { + /* Populate `nestedObject2superClassTpe` for inner objects at the start + * of a `Template`, so that they are visible even before their + * definition (in their enclosing scope). + */ + case Template(_, _, decls) => + for (decl <- decls) { + decl match { + case ClassDef(_, _, _, impl) + if decl.symbol.isModuleClass && isInnerJSClassOrObject(decl.symbol) => + nestedObject2superClassTpe(decl.symbol) = + extractSuperTpeFromImpl(impl) + case _ => + } + } + super.transform(tree) + + // Create local `val`s for local JS classes + case Block(stats, expr) => + val newStats = mutable.ListBuffer.empty[Tree] + for (stat <- stats) { + stat match { + case ClassDef(mods, name, tparams, impl) if isLocalJSClass(stat.symbol) => + val clazz = stat.symbol + val jsclassVal = currentOwner + .newValue(unit.freshTermName(name.toString() + "$jsname"), stat.pos) + .setInfo(AnyRefTpe) + localClass2jsclassVal(clazz) = jsclassVal + notYetSelfReferencingLocalClasses += clazz + val newClassDef = transform(stat) + val rhs = { + val clazzValue = gen.mkClassOf(clazz.tpe_*) + val superClassCtor = + genJSConstructorOf(tree, extractSuperTpeFromImpl(impl)) + val fakeNewInstances = { + val elems = for { + ctor <- clazz.info.decl(nme.CONSTRUCTOR).alternatives + } yield { + assert(ctor.tpe.paramss.nonEmpty, + s"Constructor ${ctor.fullName} has no param list") + val argss = ctor.tpe.paramss.map { params => + List.fill(params.size)(gen.mkAttributedRef(Predef_???)) + } + argss.tail.foldLeft( + global.NewFromConstructor(ctor, argss.head: _*))( + Apply(_, _)) + } + typer.typed(ArrayValue(TypeTree(AnyRefTpe), elems)) + } + gen.mkMethodCall(Runtime_createLocalJSClass, + List(clazzValue, superClassCtor, fakeNewInstances)) + } + if (notYetSelfReferencingLocalClasses.remove(clazz)) { + newStats += newClassDef + newStats += localTyper.typedValDef { + ValDef(jsclassVal, rhs) + } + } else { + /* We are using `jsclassVal` inside the definition of the + * class. We need to declare it as var before and initialize + * it after the class definition. + */ + jsclassVal.setFlag(Flags.MUTABLE) + newStats += localTyper.typedValDef { + ValDef(jsclassVal, Literal(gen.mkConstantZero(AnyRefTpe))) + } + newStats += newClassDef + newStats += localTyper.typed { + Assign(Ident(jsclassVal), rhs) + } + } + + case ClassDef(_, _, _, impl) + if isLocalJSClassOrObject(stat.symbol) => + nestedObject2superClassTpe(stat.symbol) = + extractSuperTpeFromImpl(impl) + newStats += transform(stat) + + case _ => + newStats += transform(stat) + } + } + val newExpr = transform(expr) + treeCopy.Block(tree, newStats.toList, newExpr) + + /* Wrap `new`s to inner and local JS classes and objects with + * `withContextualJSClassValue`, to preserve a reified reference to + * the necessary JS class value (the class itself for classes, or the + * super class for objects). + * Anonymous classes are considered as "objects" for this purpose. + */ + case Apply(sel @ Select(New(tpt), nme.CONSTRUCTOR), args) + if isInnerOrLocalJSClassOrObject(sel.symbol.owner) => + val newCall = super.transform(tree) + val newTpt = transform(tpt) + val classSym = sel.symbol.owner + if (!classSym.isModuleClass && !classSym.isAnonymousClass) { + val jsclassValue = genJSConstructorOf(newTpt, newTpt.tpe) + wrapWithContextualJSClassValue(jsclassValue) { + newCall + } + } else { + wrapWithContextualJSClassValue(nestedObject2superClassTpe(classSym)) { + newCall + } + } + + /* Wrap `super` calls to inner and local JS classes with + * `withContextualJSClassValue`, to preserve a reified reference to the + * necessary JS class value (that of the super class). + */ + case Apply(fun @ Select(sup: Super, _), _) + if !fun.symbol.isConstructor && + isInnerOrLocalJSClass(sup.symbol.superClass) => + wrapWithContextualJSClassValue(sup.symbol.superClass.tpe_*) { + super.transform(tree) + } + + // Same for a super call with type parameters + case Apply(TypeApply(fun @ Select(sup: Super, _), _), _) + if !fun.symbol.isConstructor && + isInnerOrLocalJSClass(sup.symbol.superClass) => + wrapWithContextualJSClassValue(sup.symbol.superClass.tpe_*) { + super.transform(tree) + } + + // Translate js.constructorOf[T] + case Apply(TypeApply(ctorOfTree, List(tpeArg)), Nil) + if ctorOfTree.symbol == JSPackage_constructorOf => + val newTpeArg = transform(tpeArg) + gen.mkAttributedCast(genJSConstructorOf(tree, newTpeArg.tpe), + JSDynamicClass.tpe) + + // Translate x.isInstanceOf[T] for inner and local JS classes + case Apply(TypeApply(fun @ Select(obj, _), List(tpeArg)), Nil) + if fun.symbol == Any_isInstanceOf && + isInnerOrLocalJSClass(tpeArg.tpe.typeSymbol) => + val newObj = transform(obj) + val newTpeArg = transform(tpeArg) + val jsCtorOf = genJSConstructorOf(tree, newTpeArg.tpe) + atPos(tree.pos) { + localTyper.typed { + gen.mkMethodCall(Special_instanceof, List(newObj, jsCtorOf)) + } + } + + case _ => + super.transform(tree) + } + } + + /** Generates the desugared version of `js.constructorOf[tpe]`. + */ + private def genJSConstructorOf(tree: Tree, tpe: Type): Tree = { + val clazz = tpe.typeSymbol + + // This should not have passed the checks in PrepJSInterop + assert(!clazz.isTrait && !clazz.isModuleClass, + s"non-trait class type required but $tpe found for " + + s"genJSConstructorOf at ${tree.pos}") + + localTyper.typed { + atPos(tree.pos) { + if (isInnerJSClass(clazz)) { + // Use the $jsclass field in the outer instance + val prefix = tpe.prefix match { + case NoPrefix => clazz.outerClass.thisType + case x => x + } + if (prefix.isStable) { + val qual = gen.mkAttributedQualifier(prefix) + gen.mkAttributedSelect(qual, jsclassAccessorFor(clazz)) + } else { + reporter.error(tree.pos, + s"stable reference to a JS class required but $tpe found") + gen.mkAttributedRef(Predef_???) + } + } else if (isLocalJSClass(clazz)) { + // Use the local `val` that stores the JS class value + val jsclassVal = localClass2jsclassVal(clazz) + notYetSelfReferencingLocalClasses.remove(clazz) + gen.mkAttributedIdent(jsclassVal) + } else { + // Defer translation to `LoadJSConstructor` to the back-end + val classValue = gen.mkClassOf(tpe) + gen.mkMethodCall(Runtime_constructorOf, List(classValue)) + } + } + } + } + + private def wrapWithContextualJSClassValue(jsClassType: Type)( + tree: Tree): Tree = { + wrapWithContextualJSClassValue(genJSConstructorOf(tree, jsClassType)) { + tree + } + } + + private def wrapWithContextualJSClassValue(jsClassValue: Tree)( + tree: Tree): Tree = { + atPos(tree.pos) { + localTyper.typed { + gen.mkMethodCall( + Runtime_withContextualJSClassValue, + List(tree.tpe), + List(jsClassValue, tree)) + } + } + } + + } + +} diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 7bdbe3fac5..51aceee5cb 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -46,7 +46,7 @@ abstract class GenJSCode extends plugins.PluginComponent import rootMirror._ import definitions._ import jsDefinitions._ - import jsInterop.{jsNameOf, jsNativeLoadSpecOf, JSName} + import jsInterop.{jsNameOf, jsNativeLoadSpecOfOption, JSName} import JSTreeExtractors._ import treeInfo.hasSynthCaseSymbol @@ -152,6 +152,21 @@ abstract class GenJSCode extends plugins.PluginComponent private val tryingToGenMethodAsJSFunction = new ScopedVar[Boolean](false) private val paramAccessorLocals = new ScopedVar(Map.empty[Symbol, js.ParamDef]) + /* Contextual JS class value for some operations of nested JS classes that + * need one. + */ + private val contextualJSClassValue = + new ScopedVar[Option[js.Tree]](None) + + private def acquireContextualJSClassValue[A](f: Option[js.Tree] => A): A = { + val jsClassValue = contextualJSClassValue.get + withScopedVars( + contextualJSClassValue := None + ) { + f(jsClassValue) + } + } + private class CancelGenMethodAsJSFunction(message: String) extends Throwable(message) with scala.util.control.ControlThrowable @@ -463,9 +478,11 @@ abstract class GenJSCode extends plugins.PluginComponent val classDefinition = js.ClassDef( classIdent, kind, + None, Some(encodeClassFullNameIdent(sym.superClass)), genClassInterfaces(sym, forJSClass = false), None, + None, hashedMemberDefs, topLevelExportDefs)( optimizerHints) @@ -558,10 +575,19 @@ abstract class GenJSCode extends plugins.PluginComponent if (isStaticModule(sym)) genModuleAccessorExports(sym) else genJSClassExports(sym) + val (jsClassCaptures, generatedConstructor) = + genJSClassCapturesAndConstructor(sym, constructorTrees.toList) + + /* If there is one, the JS super class value is always the first JS class + * capture. This is a GenJSCode-specific invariant (the IR does not rely + * on this) enforced in genJSClassCapturesAndConstructor. + */ + val jsSuperClass = jsClassCaptures.map(_.head.ref) + // Generate fields (and add to methods + ctors) val generatedMembers = { genClassFields(cd) ::: - genJSClassConstructor(sym, constructorTrees.toList) :: + generatedConstructor :: genJSClassDispatchers(sym, dispatchMethodNames.result().distinct) ::: generatedMethods.toList ::: staticMembers @@ -579,8 +605,10 @@ abstract class GenJSCode extends plugins.PluginComponent val classDefinition = js.ClassDef( classIdent, kind, + jsClassCaptures, Some(encodeClassFullNameIdent(sym.superClass)), genClassInterfaces(sym, forJSClass = true), + jsSuperClass, None, hashedMemberDefs, topLevelExports)( @@ -592,11 +620,12 @@ abstract class GenJSCode extends plugins.PluginComponent /** Generate an instance of an anonymous (non-lambda) JS class inline * * @param sym Class to generate the instance of + * @param jsSuperClassValue JS class value of the super class * @param args Arguments to the constructor * @param pos Position of the original New tree */ - def genAnonJSClassNew(sym: Symbol, args: List[js.Tree], - pos: Position): js.Tree = { + def genAnonJSClassNew(sym: Symbol, jsSuperClassValue: js.Tree, + args: List[js.Tree], pos: Position): js.Tree = { assert(isAnonJSClass(sym), "Generating AnonJSClassNew of non anonymous JS class") @@ -644,9 +673,10 @@ abstract class GenJSCode extends plugins.PluginComponent val newClassDef = { implicit val pos = origJsClass.pos val parent = js.Ident(ir.Definitions.ObjectClass) - js.ClassDef(origJsClass.name, ClassKind.AbstractJSType, - Some(parent), interfaces = Nil, jsNativeLoadSpec = None, - staticMembers.toList, Nil)(origJsClass.optimizerHints) + js.ClassDef(origJsClass.name, ClassKind.AbstractJSType, None, + Some(parent), interfaces = Nil, jsSuperClass = None, + jsNativeLoadSpec = None, staticMembers.toList, Nil)( + origJsClass.optimizerHints) } generatedClasses += ((sym, None, newClassDef)) @@ -655,6 +685,11 @@ abstract class GenJSCode extends plugins.PluginComponent val js.MethodDef(_, _, ctorParams, _, Some(ctorBody)) = constructor.getOrElse(throw new AssertionError("No ctor found")) + val jsSuperClassParam = js.ParamDef(freshLocalIdent("super")(pos), + jstpe.AnyType, mutable = false, rest = false)(pos) + def jsSuperClassRef(implicit pos: ir.Position) = + jsSuperClassParam.ref + val selfName = freshLocalIdent("this")(pos) def selfRef(implicit pos: ir.Position) = js.VarRef(selfName)(jstpe.AnyType) @@ -720,12 +755,10 @@ abstract class GenJSCode extends plugins.PluginComponent val newTree = { val ident = origJsClass.superClass.getOrElse(abort("No superclass")) - if (args.isEmpty && ident.name == "sjs_js_Object") { + if (args.isEmpty && ident.name == "sjs_js_Object") js.JSObjectConstr(Nil) - } else { - val superTpe = jstpe.ClassType(ident.name) - js.JSNew(js.LoadJSConstructor(superTpe), args) - } + else + js.JSNew(jsSuperClassRef, args) } js.Block( @@ -747,10 +780,10 @@ abstract class GenJSCode extends plugins.PluginComponent val invocation = { implicit val invocationPosition = pos - val closure = - js.Closure(Nil, ctorParams, js.Block(inlinedCtorStats, selfRef), Nil) + val closure = js.Closure(Nil, jsSuperClassParam :: ctorParams, + js.Block(inlinedCtorStats, selfRef), Nil) - js.JSFunctionApply(closure, args) + js.JSFunctionApply(closure, jsSuperClassValue :: args) } invocation @@ -773,15 +806,11 @@ abstract class GenJSCode extends plugins.PluginComponent val superClass = if (sym.isTraitOrInterface) None else Some(encodeClassFullNameIdent(sym.superClass)) - val jsNativeLoadSpec = { - if (sym.isTraitOrInterface) None - else if (sym.hasAnnotation(JSGlobalScopeAnnotation)) None - else Some(jsNativeLoadSpecOf(sym)) - } + val jsNativeLoadSpec = jsNativeLoadSpecOfOption(sym) - js.ClassDef(classIdent, kind, superClass, - genClassInterfaces(sym, forJSClass = true), jsNativeLoadSpec, Nil, - Nil)( + js.ClassDef(classIdent, kind, None, superClass, + genClassInterfaces(sym, forJSClass = true), None, jsNativeLoadSpec, + Nil, Nil)( OptimizerHints.empty) } @@ -815,8 +844,8 @@ abstract class GenJSCode extends plugins.PluginComponent val hashedMemberDefs = Hashers.hashMemberDefs(generatedMethods) - js.ClassDef(classIdent, ClassKind.Interface, None, interfaces, None, - hashedMemberDefs, Nil)(OptimizerHints.empty) + js.ClassDef(classIdent, ClassKind.Interface, None, None, interfaces, None, + None, hashedMemberDefs, Nil)(OptimizerHints.empty) } // Generate an implementation class of a trait ----------------------------- @@ -851,8 +880,8 @@ abstract class GenJSCode extends plugins.PluginComponent val hashedMemberDefs = Hashers.hashMemberDefs(generatedMethods) - js.ClassDef(classIdent, ClassKind.Class, - Some(objectClassIdent), Nil, None, + js.ClassDef(classIdent, ClassKind.Class, None, + Some(objectClassIdent), Nil, None, None, hashedMemberDefs, Nil)(OptimizerHints.empty) } @@ -879,6 +908,8 @@ abstract class GenJSCode extends plugins.PluginComponent assert(currentClassSym.get == classSym, "genClassFields called with a ClassDef other than the current one") + val isJSClass = isNonNativeJSClass(classSym) + def isStaticBecauseOfTopLevelExport(f: Symbol): Boolean = jsInterop.registeredExportsOf(f).head.destination == ExportDestination.TopLevel @@ -898,11 +929,11 @@ abstract class GenJSCode extends plugins.PluginComponent } val name = - if (isExposed(f)) genPropertyName(jsNameOf(f)) + if (isJSClass && isExposed(f)) genPropertyName(jsNameOf(f)) else encodeFieldSym(f) val irTpe = { - if (isNonNativeJSClass(classSym)) genExposedFieldIRType(f) + if (isJSClass) genExposedFieldIRType(f) else if (static) jstpe.AnyType else toIRType(f.tpe) } @@ -1036,8 +1067,8 @@ abstract class GenJSCode extends plugins.PluginComponent // Constructor of a non-native JS class ------------------------------ - def genJSClassConstructor(classSym: Symbol, - constructorTrees: List[DefDef]): js.MethodDef = { + def genJSClassCapturesAndConstructor(classSym: Symbol, + constructorTrees: List[DefDef]): (Option[List[js.ParamDef]], js.MethodDef) = { implicit val pos = classSym.pos if (hasDefaultCtorArgsAndRawJSModule(classSym)) { @@ -1045,18 +1076,34 @@ abstract class GenJSCode extends plugins.PluginComponent "Implementation restriction: constructors of " + "non-native JS classes cannot have default parameters " + "if their companion module is JS native.") - js.MethodDef(static = false, js.StringLiteral("constructor"), Nil, - jstpe.AnyType, Some(js.Skip()))( + val ctorDef = js.MethodDef(static = false, + js.StringLiteral("constructor"), Nil, jstpe.AnyType, + Some(js.Skip()))( OptimizerHints.empty, None) + (None, ctorDef) } else { withNewLocalNameScope { + reserveLocalName(JSSuperClassParamName) + val ctors: List[js.MethodDef] = constructorTrees.flatMap { tree => genMethodWithCurrentLocalNameScope(tree) } - val dispatch = + val (captureParams, dispatch) = genJSConstructorExport(constructorTrees.map(_.symbol)) - buildJSConstructorDef(dispatch, ctors) + + /* Ensure that the first JS class capture is a reference to the JS + * super class value. genNonNativeJSClass relies on this. + */ + val captureParamsWithJSSuperClass = captureParams.map { params => + val jsSuperClassParam = js.ParamDef(js.Ident(JSSuperClassParamName), + jstpe.AnyType, mutable = false, rest = false) + jsSuperClassParam :: params + } + + val ctorDef = buildJSConstructorDef(dispatch, ctors) + + (captureParamsWithJSSuperClass, ctorDef) } } } @@ -1699,8 +1746,20 @@ abstract class GenJSCode extends plugins.PluginComponent if (!isNonNativeJSClass(currentClassSym) || isRawJSFunctionDef(currentClassSym)) { - js.MethodDef(static, methodName, jsParams, resultIRType, - Some(genBody()))(optimizerHints, None) + val body = { + if (currentClassSym.isImplClass) { + val thisParam = jsParams.head + withScopedVars( + thisLocalVarInfo := Some((thisParam.name, thisParam.ptpe)) + ) { + genBody() + } + } else { + genBody() + } + } + js.MethodDef(static, methodName, jsParams, resultIRType, Some(body))( + optimizerHints, None) } else { assert(!static, tree.pos) @@ -3234,7 +3293,7 @@ abstract class GenJSCode extends plugins.PluginComponent else if (isCoercion(code)) genCoercion(tree, receiver, code) else if (jsPrimitives.isJavaScriptPrimitive(code)) - genJSPrimitive(tree, receiver, args, code) + genJSPrimitive(tree, receiver, args, code, isStat) else abort("Unknown primitive operation: " + sym.fullName + "(" + fun.symbol.simpleName + ") " + " at: " + (tree.pos)) @@ -3978,7 +4037,7 @@ abstract class GenJSCode extends plugins.PluginComponent /** Gen JS code for a Scala.js-specific primitive method */ private def genJSPrimitive(tree: Apply, receiver0: Tree, - args: List[Tree], code: Int): js.Tree = { + args: List[Tree], code: Int, isStat: Boolean): js.Tree = { import jsPrimitives._ implicit val pos = tree.pos @@ -4019,9 +4078,34 @@ abstract class GenJSCode extends plugins.PluginComponent } else if (code == CONSTRUCTOROF) { val classSym = resolveReifiedJSClassSym(args.head) if (classSym == NoSymbol) - js.Undefined() + js.Undefined() // compile error emitted by resolveReifiedJSClassSym else genPrimitiveJSClass(classSym) + } else if (code == CREATE_INNER_JS_CLASS || code == CREATE_LOCAL_JS_CLASS) { + val classSym = resolveReifiedJSClassSym(args(0)) + val superClassValue = genExpr(args(1)) + if (classSym == NoSymbol) { + js.Undefined() // compile error emitted by resolveReifiedJSClassSym + } else { + val captureValues = { + if (code == CREATE_INNER_JS_CLASS) { + val outer = genThis() + List.fill(classSym.info.decls.count(_.isClassConstructor))(outer) + } else { + val ArrayValue(_, fakeNewInstances) = args(2) + fakeNewInstances.flatMap(genCaptureValuesFromFakeNewInstance(_)) + } + } + js.CreateJSClass(jstpe.ClassRef(encodeClassFullName(classSym)), + superClassValue :: captureValues) + } + } else if (code == WITH_CONTEXTUAL_JS_CLASS_VALUE) { + val jsClassValue = genExpr(args(0)) + withScopedVars( + contextualJSClassValue := Some(jsClassValue) + ) { + genStatOrExpr(args(1), isStat) + } } else (genArgs match { case Nil => code match { @@ -4143,45 +4227,51 @@ abstract class GenJSCode extends plugins.PluginComponent } private def genJSSuperCall(tree: Apply, isStat: Boolean): js.Tree = { - implicit val pos = tree.pos - val Apply(fun @ Select(sup @ Super(qual, _), _), args) = tree - val sym = fun.symbol + acquireContextualJSClassValue { explicitJSSuperClassValue => + implicit val pos = tree.pos + val Apply(fun @ Select(sup @ Super(qual, _), _), args) = tree + val sym = fun.symbol - /* #3013 `qual` can be `this.$outer()` in some cases since Scala 2.12, - * so we call `genExpr(qual)`, not just `genThis()`. - */ - val genReceiver = genExpr(qual) - lazy val genScalaArgs = genActualArgs(sym, args) - lazy val genJSArgs = genPrimitiveJSArgs(sym, args) - - if (sym.owner == ObjectClass) { - // Normal call anyway - assert(!sym.isClassConstructor, - "Trying to call the super constructor of Object in a " + - 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 (isNonNativeJSClass(sym.owner) && !isExposed(sym)) { - // Reroute to the static method - genApplyJSClassMethod(genReceiver, sym, genScalaArgs) - } else { - genJSCallGeneric(sym, MaybeGlobalScope.NotGlobalScope(genReceiver), - genJSArgs, isStat, superIn = Some(currentClassSym)) + /* #3013 `qual` can be `this.$outer()` in some cases since Scala 2.12, + * so we call `genExpr(qual)`, not just `genThis()`. + */ + val genReceiver = genExpr(qual) + lazy val genScalaArgs = genActualArgs(sym, args) + lazy val genJSArgs = genPrimitiveJSArgs(sym, args) + + if (sym.owner == ObjectClass) { + // Normal call anyway + assert(!sym.isClassConstructor, + "Trying to call the super constructor of Object in a " + + 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 (isNonNativeJSClass(sym.owner) && !isExposed(sym)) { + // Reroute to the static method + genApplyJSClassMethod(genReceiver, sym, genScalaArgs) + } else { + val jsSuperClassValue = explicitJSSuperClassValue.orElse { + Some(genPrimitiveJSClass(currentClassSym.superClass)) + } + genJSCallGeneric(sym, MaybeGlobalScope.NotGlobalScope(genReceiver), + genJSArgs, isStat, jsSuperClassValue) + } } } private def genJSCallGeneric(sym: Symbol, receiver: MaybeGlobalScope, - args: List[js.Tree], isStat: Boolean, superIn: Option[Symbol] = None)( + args: List[js.Tree], isStat: Boolean, + jsSuperClassValue: Option[js.Tree] = None)( implicit pos: Position): js.Tree = { def noSpread = !args.exists(_.isInstanceOf[js.JSSpread]) val argc = args.size // meaningful only for methods that don't have varargs def requireNotSuper(): Unit = { - if (superIn.isDefined) { + if (jsSuperClassValue.isDefined) { reporter.error(pos, "Illegal super call in non-native JS class") } @@ -4214,11 +4304,10 @@ abstract class GenJSCode extends plugins.PluginComponent def jsFunName: js.Tree = genExpr(jsNameOf(sym)) def genSuperReference(propName: js.Tree): js.Tree = { - superIn.fold[js.Tree] { + jsSuperClassValue.fold[js.Tree] { genJSBracketSelectOrGlobalRef(receiver, propName) - } { superInSym => - js.JSSuperBracketSelect( - genPrimitiveJSClass(superInSym.superClass), + } { superClassValue => + js.JSSuperBracketSelect(superClassValue, ruleOutGlobalScope(receiver), propName) } } @@ -4230,12 +4319,11 @@ abstract class GenJSCode extends plugins.PluginComponent js.Assign(genSuperReference(propName), value) def genCall(methodName: js.Tree, args: List[js.Tree]): js.Tree = { - superIn.fold[js.Tree] { + jsSuperClassValue.fold[js.Tree] { genJSBracketMethodApplyOrGlobalRefApply( receiver, methodName, args) - } { superInSym => - js.JSSuperBracketCall( - genPrimitiveJSClass(superInSym.superClass), + } { superClassValue => + js.JSSuperBracketCall(superClassValue, ruleOutGlobalScope(receiver), methodName, args) } } @@ -4330,22 +4418,33 @@ abstract class GenJSCode extends plugins.PluginComponent /** Gen JS code for a new of a raw JS class (subclass of js.Any) */ private def genPrimitiveJSNew(tree: Apply): js.Tree = { - implicit val pos = tree.pos - - val Apply(fun @ Select(New(tpt), _), args0) = tree - val cls = tpt.tpe.typeSymbol - val ctor = fun.symbol - - val args = genPrimitiveJSArgs(ctor, args0) - - if (cls == JSObjectClass && args.isEmpty) - js.JSObjectConstr(Nil) - else if (cls == JSArrayClass && args.isEmpty) - js.JSArrayConstr(Nil) - else if (isAnonJSClass(cls)) - genAnonJSClassNew(cls, args, fun.pos) - else - js.JSNew(genPrimitiveJSClass(cls), args) + acquireContextualJSClassValue { jsClassValue => + implicit val pos = tree.pos + + val Apply(fun @ Select(New(tpt), _), args0) = tree + val cls = tpt.tpe.typeSymbol + val ctor = fun.symbol + + val nestedJSClass = isNestedJSClass(cls) + assert(jsClassValue.isDefined == nestedJSClass, + s"$cls at $pos: jsClassValue.isDefined = ${jsClassValue.isDefined} " + + s"but isInnerNonNativeJSClass = $nestedJSClass") + + def args = genPrimitiveJSArgs(ctor, args0) + + if (cls == JSObjectClass && args0.isEmpty) + js.JSObjectConstr(Nil) + else if (cls == JSArrayClass && args0.isEmpty) + js.JSArrayConstr(Nil) + else if (isAnonJSClass(cls)) + genAnonJSClassNew(cls, jsClassValue.get, args, fun.pos) + else if (!nestedJSClass) + js.JSNew(genPrimitiveJSClass(cls), args) + else if (!cls.isModuleClass) + js.JSNew(jsClassValue.get, args) + else + genCreateInnerJSModule(cls, jsClassValue.get, args0.map(genExpr)) + } } /** Gen JS code representing a JS class (subclass of js.Any) */ @@ -4356,6 +4455,14 @@ abstract class GenJSCode extends plugins.PluginComponent js.LoadJSConstructor(jstpe.ClassType(encodeClassFullName(sym))) } + /** Gen JS code to create the JS class of an inner JS module class. */ + private def genCreateInnerJSModule(sym: Symbol, + jsSuperClassValue: js.Tree, args: List[js.Tree])( + implicit pos: Position): js.Tree = { + js.JSNew(js.CreateJSClass(jstpe.ClassRef(encodeClassFullName(sym)), + jsSuperClassValue :: args), Nil) + } + /** Gen actual actual arguments to Scala method call. * Returns a list of the transformed arguments. * @@ -4408,26 +4515,36 @@ abstract class GenJSCode extends plugins.PluginComponent private def genPrimitiveJSArgs(sym: Symbol, args: List[Tree])( implicit pos: Position): List[js.Tree] = { - /* lambdalift might have to introduce some parameters when transforming - * nested non-native JS classes. Hence, the list of parameters - * exiting typer and entering posterasure might not be compatible with - * the list of actual arguments we receive now. + /* For constructors of nested JS classes (*), explicitouter and + * lambdalift have introduced some parameters for the outer parameter and + * captures. We must ignore those, as captures and outer pointers are + * taken care of by `explicitinerjs` for such classes. * - * We therefore need to establish of list of formal parameters based on - * the current signature of `sym`, but have to look back in time to see - * whether they were repeated and what was their type (for those that - * were already present at the time). - * - * Unfortunately, for some reason lambdalift creates new symbol *even - * for parameters originally in the signature* when doing so! That is - * why we use the *names* of the parameters as a link through time, - * rather than the symbols. + * Unfortunately, for some reason lambdalift creates new symbol *even for + * parameters originally in the signature* when doing so! That is why we + * use the *names* of the parameters as a link through time, rather than + * the symbols, to identify which ones already existed at the time of + * explicitinerjs. * * This is pretty fragile, but fortunately we have a huge test suite to * back us up should scalac alter its behavior. + * + * Anonymous JS classes are excluded for this treatment, since they are + * instantiated in a completely different way. + * + * In addition, for actual parameters that we keep, we have to look back + * in time to see whether they were repeated and what was their type. + * + * (*) Note that we are not supposed to receive in genPrimitiveJSArgs a + * method symbol that would have such captures *and* would not be a + * class constructors. Indeed, such methods would have started their + * life as local defs, which are not exposed. */ - val wereRepeated = exitingPhase(currentRun.typerPhase) { + val isAnonJSClassConstructor = + sym.isClassConstructor && isAnonJSClass(sym.owner) + + val wereRepeated = enteringPhase(currentRun.uncurryPhase) { for { params <- sym.tpe.paramss param <- params @@ -4444,20 +4561,33 @@ abstract class GenJSCode extends plugins.PluginComponent var reversedArgs: List[js.Tree] = Nil for ((arg, paramSym) <- args zip sym.tpe.params) { - val wasRepeated = wereRepeated.getOrElse(paramSym.name, false) - if (wasRepeated) { - reversedArgs = - genPrimitiveJSRepeatedParam(arg) reverse_::: reversedArgs - } else { - val unboxedArg = genExpr(arg) - val boxedArg = unboxedArg match { - case js.UndefinedParam() => - unboxedArg - case _ => - val tpe = paramTpes.getOrElse(paramSym.name, paramSym.tpe) - ensureBoxed(unboxedArg, tpe) - } - reversedArgs ::= boxedArg + val wasRepeated = + if (isAnonJSClassConstructor) Some(false) + else wereRepeated.get(paramSym.name) + + wasRepeated match { + case Some(true) => + reversedArgs = + genPrimitiveJSRepeatedParam(arg) reverse_::: reversedArgs + + case Some(false) => + val unboxedArg = genExpr(arg) + val boxedArg = unboxedArg match { + case js.UndefinedParam() => + unboxedArg + case _ => + val tpe = paramTpes.getOrElse(paramSym.name, paramSym.tpe) + ensureBoxed(unboxedArg, tpe) + } + reversedArgs ::= boxedArg + + case None => + /* This is a parameter introduced by explicitouter or lambdalift, + * which we ignore. + */ + assert(sym.isClassConstructor, + s"Found an unknown param ${paramSym.name} in method " + + s"${sym.fullName}, which is not a class constructor, at $pos") } } @@ -4565,6 +4695,39 @@ abstract class GenJSCode extends plugins.PluginComponent } } + /** Gen the actual capture values for a JS constructor based on its fake + * `new` invocation. + */ + private def genCaptureValuesFromFakeNewInstance( + tree: Tree): List[js.Tree] = { + + implicit val pos = tree.pos + + val Apply(fun @ Select(New(_), _), args) = tree + val sym = fun.symbol + + /* We use the same strategy as genPrimitiveJSArgs to detect which + * parameters were introduced by explicitouter or lambdalift (but + * reversed, of course). + */ + + val existedBeforeUncurry = enteringPhase(currentRun.uncurryPhase) { + for { + params <- sym.tpe.paramss + param <- params + } yield { + param.name + } + }.toSet + + for { + (arg, paramSym) <- args.zip(sym.tpe.params) + if !existedBeforeUncurry(paramSym.name) + } yield { + genExpr(arg) + } + } + // Synthesizers for raw JS functions --------------------------------------- /** Try and generate JS code for an anonymous function class. @@ -5034,9 +5197,11 @@ abstract class GenJSCode extends plugins.PluginComponent val classDef = js.ClassDef( js.Ident(generatedClassName), ClassKind.Class, + None, Some(js.Ident(ir.Definitions.ObjectClass)), List(js.Ident(intfName)), None, + None, List(fFieldDef, ctorDef, samMethodDef), Nil)( js.OptimizerHints.empty.withInline(true)) @@ -5339,6 +5504,9 @@ abstract class GenJSCode extends plugins.PluginComponent def isAnonJSClass(sym: Symbol): Boolean = sym.hasAnnotation(AnonymousJSClassAnnotation) + def isNestedJSClass(sym: Symbol): Boolean = + sym.isLifted && !sym.originalOwner.isModuleClass && isJSType(sym) + /** Tests whether the given class is a JS native class. */ private def isJSNativeClass(sym: Symbol): Boolean = sym.hasAnnotation(JSNativeAnnotation) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index 329783518d..6b4a2cfe63 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -296,9 +296,29 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } } - def genJSConstructorExport(alts: List[Symbol]): js.MethodDef = { - genExportMethod(alts.map(ExportedSymbol), JSName.Literal("constructor"), + def genJSConstructorExport( + alts: List[Symbol]): (Option[List[js.ParamDef]], js.MethodDef) = { + val exporteds = alts.map(ExportedSymbol) + + val isLiftedJSCtor = exporteds.head.isLiftedJSConstructor + assert(exporteds.tail.forall(_.isLiftedJSConstructor == isLiftedJSCtor)) + val captureParams = if (!isLiftedJSCtor) { + None + } else { + Some(for { + exported <- exporteds + param <- exported.captureParamsFront ::: exported.captureParamsBack + } yield { + implicit val pos = param.sym.pos + js.ParamDef(encodeLocalSym(param.sym), toIRType(param.tpe), + mutable = false, rest = false) + }) + } + + val ctorDef = genExportMethod(exporteds, JSName.Literal("constructor"), static = false) + + (captureParams, ctorDef) } private def genExportProperty(alts: List[Symbol], jsName: JSName, @@ -605,8 +625,15 @@ trait GenJSExports extends SubComponent { self: GenJSCode => val allArgs = (1 to minArgc).map(genFormalArgRef(_, minArgc)) ++: restArg - val superClass = js.LoadJSConstructor( - jstpe.ClassType(encodeClassFullName(currentClassSym.superClass))) + val superClass = { + val superClassSym = currentClassSym.superClass + if (isNestedJSClass(superClassSym)) { + js.VarRef(js.Ident(JSSuperClassParamName))(jstpe.AnyType) + } else { + js.LoadJSConstructor(jstpe.ClassType(encodeClassFullName(superClassSym))) + } + } + val receiver = js.This()(jstpe.AnyType) val nameString = genExpr(jsNameOf(sym)) @@ -648,7 +675,18 @@ trait GenJSExports extends SubComponent { self: GenJSCode => // Generate JS code to prepare arguments (default getters and unboxes) val jsArgPrep = genPrepareArgs(jsArgRefs, exported) ++ jsVarArgPrep - val jsResult = genResult(exported, jsArgPrep.map(_.ref), static) + val jsArgPrepRefs = jsArgPrep.map(_.ref) + + // Combine prep'ed formal arguments with captures + def varRefForCaptureParam(param: ParamSpec): js.Tree = + js.VarRef(encodeLocalSym(param.sym))(toIRType(param.sym.tpe)) + val allJSArgs = { + exported.captureParamsFront.map(varRefForCaptureParam) ::: + jsArgPrepRefs ::: + exported.captureParamsBack.map(varRefForCaptureParam) + } + + val jsResult = genResult(exported, allJSArgs, static) js.Block(jsArgPrep :+ jsResult) } @@ -780,7 +818,10 @@ trait GenJSExports extends SubComponent { self: GenJSCode => private sealed abstract class Exported { def sym: Symbol def pos: Position + def isLiftedJSConstructor: Boolean def params: immutable.IndexedSeq[ParamSpec] + def captureParamsFront: List[ParamSpec] + def captureParamsBack: List[ParamSpec] def exportArgTypeAt(paramIndex: Int): Type def genBody(minArgc: Int, hasRestParam: Boolean, static: Boolean): js.Tree def name: String @@ -789,7 +830,13 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } private case class ExportedSymbol(sym: Symbol) extends Exported { - val params = { + private val isAnonJSClassConstructor = + sym.isClassConstructor && isAnonJSClass(sym.owner) + + val isLiftedJSConstructor = + sym.isClassConstructor && isNestedJSClass(sym.owner) + + val (params, captureParamsFront, captureParamsBack) = { val allParamsUncurry = enteringPhase(currentRun.uncurryPhase)(sym.paramss.flatten.map(ParamSpec)) val allParamsPosterasure = @@ -806,7 +853,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } } - if (!sym.isClassConstructor) { + if (!isLiftedJSConstructor && !isAnonJSClassConstructor) { /* Easy case: all params are formal params, and we only need to * travel back before uncurry to handle repeated params, or before * posterasure for other params. @@ -817,7 +864,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => s"non-lifted symbol ${sym.fullName}") val formalParams = mergeUncurryPosterasure(allParamsUncurry, allParamsPosterasure) - formalParams.toIndexedSeq + (formalParams.toIndexedSeq, Nil, Nil) } else { /* The `arg$outer` param is added by explicitouter (between uncurry * and posterasure) while the other capture params are added by @@ -851,9 +898,16 @@ trait GenJSExports extends SubComponent { self: GenJSCode => allParamsNow.splitAt(startOfRealParams) val captureParamsBack = restOfParamsNow.drop(formalParams.size) - val allFormalParams = - captureParamsFront ::: formalParams ::: captureParamsBack - allFormalParams.toIndexedSeq + if (isAnonJSClassConstructor) { + /* For an anonymous JS class constructor, we put the capture + * parameters back as formal parameters. + */ + val allFormalParams = + captureParamsFront ::: formalParams ::: captureParamsBack + (allFormalParams.toIndexedSeq, Nil, Nil) + } else { + (formalParams.toIndexedSeq, captureParamsFront, captureParamsBack) + } } } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 899acc8108..d5686967a0 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -114,6 +114,9 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val Runtime_genTraversableOnce2jsArray = getMemberMethod(RuntimePackageModule, newTermName("genTraversableOnce2jsArray")) lazy val Runtime_constructorOf = getMemberMethod(RuntimePackageModule, newTermName("constructorOf")) lazy val Runtime_newConstructorTag = getMemberMethod(RuntimePackageModule, newTermName("newConstructorTag")) + lazy val Runtime_createInnerJSClass = getMemberMethod(RuntimePackageModule, newTermName("createInnerJSClass")) + lazy val Runtime_createLocalJSClass = getMemberMethod(RuntimePackageModule, newTermName("createLocalJSClass")) + lazy val Runtime_withContextualJSClassValue = getMemberMethod(RuntimePackageModule, newTermName("withContextualJSClassValue")) lazy val Runtime_propertiesOf = getMemberMethod(RuntimePackageModule, newTermName("propertiesOf")) lazy val Runtime_linkingInfo = getMemberMethod(RuntimePackageModule, newTermName("linkingInfo")) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala index 2061999ecc..be1540099f 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala @@ -40,6 +40,22 @@ trait JSEncoding extends SubComponent { self: GenJSCode => /** Name given to all exported stuff of a class for DCE */ final val dceExportName = "" + /** Name of the capture param storing the JS super class. + * + * This is used by the dispatchers of exposed JS methods and properties of + * nested JS classes when they need to perform a super call. Other super + * calls (in the actual bodies of the methods, not in the dispatchers) do + * not use this value, since they are implemented as static methods that do + * not have access to it. Instead, they get the JS super class value through + * the magic method inserted by `ExplicitLocalJS`, leveraging `lambdalift` + * to ensure that it is properly captured. + * + * Using this identifier is only allowed if the current local name scope was + * created with [[withNewLocalNameScopeUsingJSSuperClassParamName]]. + * Otherwise, this name can clash with another local identifier. + */ + final val JSSuperClassParamName = "$superClass" + // Fresh local name generator ---------------------------------------------- private val usedLocalNames = new ScopedVar[mutable.Set[String]] @@ -47,11 +63,19 @@ trait JSEncoding extends SubComponent { self: GenJSCode => private val isReserved = Set("arguments", "eval", ScalaJSEnvironmentName) - def withNewLocalNameScope[A](body: => A): A = + def withNewLocalNameScope[A](body: => A): A = { withScopedVars( usedLocalNames := mutable.Set.empty, localSymbolNames := mutable.Map.empty )(body) + } + + def reserveLocalName(name: String): Unit = { + require(usedLocalNames.isEmpty, + s"Trying to reserve the name '$name' but names have already been " + + "allocated") + usedLocalNames += name + } private def freshName(base: String = "x"): String = { var suffix = 1 diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala index 3dad586adc..f1e24ae5db 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala @@ -45,6 +45,50 @@ trait JSGlobalAddons extends JSDefinitions case object Static extends ExportDestination } + /** Extracts the super type of a `Template`, with type parameters reinvented + * so that the type is well-formed outside of the `Template`, i.e., at the + * same level where the corresponding `ImplDef` is defined. + */ + def extractSuperTpeFromImpl(impl: Template): Type = + reinventTypeParams(impl.parents.head.tpe) + + /** Reinvents all the type parameters of a `TypeRef`. + * + * This is done by existentially quantifying over all type parameters of + * the class type referenced by the `TypeRef`. + * + * As a simple example, given the definition + * {{{ + * class C[A, B <: AnyVal] + * }}} + * this transforms + * {{{ + * path.C[A, Int] + * }}} + * into + * {{{ + * path.C[_, _ <: AnyVal] + * }}} + * + * As a complex example, given the definition + * {{{ + * class D[A, B <: List[Seq[A]]] + * }}} + * this method transforms + * {{{ + * path.D[?0, ?1] forSome { type ?0; type ?1 <: List[Seq[?0]] } + * }}} + */ + private def reinventTypeParams(tp: Type): Type = { + tp match { + case TypeRef(pre, sym, _) if sym.isClass && sym.typeParams.nonEmpty => + val eparams = typeParamsToExistentials(sym) + existentialAbstraction(eparams, typeRef(pre, sym, eparams.map(_.tpe))) + case _ => + tp + } + } + /** global javascript interop related helpers */ object jsInterop { import scala.reflect.NameTransformer @@ -131,6 +175,9 @@ trait JSGlobalAddons extends JSDefinitions } } + def jsclassAccessorFor(clazz: Symbol): Symbol = + clazz.owner.info.member(clazz.name.append("$jsclass").toTermName) + def isJSProperty(sym: Symbol): Boolean = isJSGetter(sym) || isJSSetter(sym) @inline private def enteringUncurryIfAtPhaseAfter[A](op: => A): A = { @@ -227,6 +274,16 @@ trait JSGlobalAddons extends JSDefinitions jsNativeLoadSpecs(sym) } + /** Gets the JS native load spec of a symbol in the current compilation run, + * if it has one. + */ + def jsNativeLoadSpecOfOption(sym: Symbol): Option[JSNativeLoadSpec] = { + assert(sym.isClass, + s"jsNativeLoadSpecOfOption called for non-class symbol $sym") + + jsNativeLoadSpecs.get(sym) + } + } } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala index 6705d4bcd9..99701f6928 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala @@ -29,25 +29,32 @@ abstract class JSPrimitives { import jsDefinitions._ import scalaPrimitives._ - val F2JS = 305 // FunctionN to js.FunctionN - val F2JSTHIS = 306 // FunctionN to js.ThisFunction{N-1} + val FirstJSPrimitiveCode = 300 - val DYNNEW = 321 // Instantiate a new JavaScript object + val F2JS = FirstJSPrimitiveCode + 1 // FunctionN to js.FunctionN + val F2JSTHIS = F2JS + 1 // FunctionN to js.ThisFunction{N-1} - val ARR_CREATE = 337 // js.Array.apply (array literal syntax) + val DYNNEW = F2JSTHIS + 1 // Instantiate a new JavaScript object - val TYPEOF = 344 // typeof x - val JS_NATIVE = 348 // js.native. Marker method. Fails if tried to be emitted. + val ARR_CREATE = DYNNEW + 1 // js.Array.apply (array literal syntax) - val UNITVAL = 349 // () value, which is undefined + val TYPEOF = ARR_CREATE + 1 // typeof x + val JS_NATIVE = TYPEOF + 1 // js.native. Marker method. Fails if tried to be emitted. - val CONSTRUCTOROF = 352 // runtime.constructorOf(clazz) - val LINKING_INFO = 353 // $linkingInfo + val UNITVAL = JS_NATIVE + 1 // () value, which is undefined - val IN = 354 // js.special.in - val INSTANCEOF = 355 // js.special.instanceof - val DELETE = 356 // js.special.delete - val DEBUGGER = 357 // js.special.debugger + val CONSTRUCTOROF = UNITVAL + 1 // runtime.constructorOf(clazz) + val CREATE_INNER_JS_CLASS = CONSTRUCTOROF + 1 // runtime.createInnerJSClass + val CREATE_LOCAL_JS_CLASS = CREATE_INNER_JS_CLASS + 1 // runtime.createLocalJSClass + val WITH_CONTEXTUAL_JS_CLASS_VALUE = CREATE_LOCAL_JS_CLASS + 1 // runtime.withContextualJSClassValue + val LINKING_INFO = WITH_CONTEXTUAL_JS_CLASS_VALUE + 1 // runtime.linkingInfo + + val IN = LINKING_INFO + 1 // js.special.in + val INSTANCEOF = IN + 1 // js.special.instanceof + val DELETE = INSTANCEOF + 1 // js.special.delete + val DEBUGGER = DELETE + 1 // js.special.debugger + + val LastJSPrimitiveCode = DEBUGGER /** Initialize the map of primitive methods (for GenJSCode) */ def init(): Unit = initWithPrimitives(addPrimitive) @@ -93,6 +100,10 @@ abstract class JSPrimitives { addPrimitive(BoxedUnit_UNIT, UNITVAL) addPrimitive(Runtime_constructorOf, CONSTRUCTOROF) + addPrimitive(Runtime_createInnerJSClass, CREATE_INNER_JS_CLASS) + addPrimitive(Runtime_createLocalJSClass, CREATE_LOCAL_JS_CLASS) + addPrimitive(Runtime_withContextualJSClassValue, + WITH_CONTEXTUAL_JS_CLASS_VALUE) addPrimitive(Runtime_linkingInfo, LINKING_INFO) addPrimitive(Special_in, IN) @@ -102,5 +113,5 @@ abstract class JSPrimitives { } def isJavaScriptPrimitive(code: Int): Boolean = - code >= 300 && code < 360 + code >= FirstJSPrimitiveCode && code <= LastJSPrimitiveCode } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 117d051548..c07fd09f47 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -157,29 +157,21 @@ abstract class PrepJSInterop extends plugins.PluginComponent checkInternalAnnotations(tree) val preTransformedTree = tree match { - // Nothing is allowed in native JS classes and traits - case idef: ImplDef if enclosingOwner is OwnerKind.JSNativeClass => - reporter.error(idef.pos, "Native JS traits and classes " + - "may not have inner traits, classes or objects") - super.transform(tree) - // Handle js.Anys case idef: ImplDef if isJSAny(idef) => transformJSAny(idef) - /* In native JS objects, only js.Any stuff is allowed. However, synthetic - * companion objects need to be allowed as they get generated, when a - * native class inside a native JS object has default arguments in its - * constructor (see #1891). - */ - case modDef: ModuleDef if (enclosingOwner is OwnerKind.JSNativeMod) && - modDef.symbol.isSynthetic => - super.transform(tree) - - // In native JS objects, only js.Any stuff is allowed - case idef: ImplDef if enclosingOwner is OwnerKind.JSNativeMod => - reporter.error(idef.pos, "Native JS objects cannot contain inner " + - "Scala traits, classes or objects (i.e., not extending js.Any)") + // In native JS things, only js.Any stuff is allowed + case idef: ImplDef if enclosingOwner is OwnerKind.JSNative => + /* We have to allow synthetic companion objects here, as they get + * generated when a nested native JS class has default arguments in + * its constructor (see #1891). + */ + if (!idef.symbol.isSynthetic) { + reporter.error(idef.pos, + "Native JS traits, classes and objects cannot contain inner " + + "Scala traits, classes or objects (i.e., not extending js.Any)") + } super.transform(tree) // Catch the definition of scala.Enumeration itself @@ -294,19 +286,22 @@ abstract class PrepJSInterop extends plugins.PluginComponent |program is unlikely to function properly.""".stripMargin) super.transform(tree) - // Rewrite js.constructorOf[T] into runtime.constructorOf(classOf[T]) + // Validate js.constructorOf[T] case TypeApply(ctorOfTree, List(tpeArg)) if ctorOfTree.symbol == JSPackage_constructorOf => - genConstructorOf(tree, tpeArg) + validateJSConstructorOf(tree, tpeArg) + super.transform(tree) /* Rewrite js.ConstructorTag.materialize[T] into - * runtime.newConstructorTag[T](runtime.constructorOf(classOf[T])) + * runtime.newConstructorTag[T](js.constructorOf[T]) */ case TypeApply(ctorOfTree, List(tpeArg)) if ctorOfTree.symbol == JSConstructorTag_materialize => - val ctorOf = genConstructorOf(tree, tpeArg) + validateJSConstructorOf(tree, tpeArg) typer.typed { atPos(tree.pos) { + val ctorOf = gen.mkTypeApply( + gen.mkAttributedRef(JSPackage_constructorOf), List(tpeArg)) gen.mkMethodCall(Runtime_newConstructorTag, List(tpeArg.tpe), List(ctorOf)) } @@ -435,7 +430,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent postTransform(preTransformedTree) } - private def genConstructorOf(tree: Tree, tpeArg: Tree): Tree = { + private def validateJSConstructorOf(tree: Tree, tpeArg: Tree): Unit = { val classValue = try { typer.typedClassOf(tree, tpeArg) } catch { @@ -448,21 +443,10 @@ abstract class PrepJSInterop extends plugins.PluginComponent val Literal(classConstant) = classValue val tpe = classConstant.typeValue.dealiasWiden val typeSym = tpe.typeSymbol - if (!typeSym.isTrait && !typeSym.isModuleClass) { - typer.typed { - atPos(tree.pos) { - Apply( - Select(Ident(RuntimePackageModule), newTermName("constructorOf")), - List(classValue)) - } - } - } else { + if (typeSym.isTrait || typeSym.isModuleClass) { reporter.error(tpeArg.pos, s"non-trait class type required but $tpe found") - EmptyTree } - } else { - EmptyTree } } @@ -582,6 +566,13 @@ abstract class PrepJSInterop extends plugins.PluginComponent // Checks for non-native JS stuff if (!isJSNative) { + // It cannot be in a native JS class or trait + if (enclosingOwner is OwnerKind.JSNativeClass) { + reporter.error(implDef.pos, + "Native JS classes and traits cannot contain non-native JS " + + "classes, traits or objects") + } + // Unless it is a trait, it cannot be in a native JS object if (!sym.isTrait && (enclosingOwner is OwnerKind.JSNativeMod)) { reporter.error(implDef.pos, @@ -603,6 +594,12 @@ abstract class PrepJSInterop extends plugins.PluginComponent "native JS trait.") } + // Local JS classes cannot be abstract (implementation restriction) + if (!sym.isTrait && sym.isAbstractClass && sym.isLocalToBlock) { + reporter.error(implDef.pos, + "Implementation restriction: local JS classes cannot be abstract") + } + // Check that there is no JS-native-specific annotation checkJSNativeSpecificAnnotsOnNonJSNative(implDef) } @@ -619,12 +616,13 @@ abstract class PrepJSInterop extends plugins.PluginComponent if (sym.isLocalToBlock) { reporter.error(implDef.pos, "Local native JS classes and objects are not allowed") - } else if (anyEnclosingOwner is OwnerKind.AnyClass) { - reporter.error(implDef.pos, "Traits and classes " + - "may not have inner native JS traits, classes or objects") - } else if (enclosingOwner is OwnerKind.JSMod) { - reporter.error(implDef.pos, "non-native JS objects " + - "may not have inner native JS classes or objects") + } else if (anyEnclosingOwner is OwnerKind.ScalaClass) { + reporter.error(implDef.pos, + "Scala traits and classes may not have inner native JS " + + "traits, classes or objects") + } else if (enclosingOwner is OwnerKind.JSNonNative) { + reporter.error(implDef.pos, "non-native JS classes, traits and " + + "objects may not have inner native JS classes, traits or objects") } else if (!sym.isTrait) { /* Compute the loading spec now, before `flatten` destroys the name * and (in 2.10) the original owner chain. We store it in a global @@ -714,40 +712,48 @@ abstract class PrepJSInterop extends plugins.PluginComponent sym: Symbol): Option[JSNativeLoadSpec] = { import JSNativeLoadSpec._ - if (enclosingOwner is OwnerKind.JSNativeMod) { + if (enclosingOwner is OwnerKind.JSNative) { for (annot <- sym.annotations) { val annotSym = annot.symbol if (JSNativeLoadingSpecAnnots.contains(annotSym)) { reporter.error(annot.pos, - "Classes and objects nested in a JS native object cannot " + + "Nested JS classes and objects cannot " + s"have an @${annotSym.nameString} annotation.") - } else if (annotSym == JSNameAnnotation && - annot.args.head.tpe.typeSymbol != StringClass) { - reporter.error(annot.pos, - "Implementation restriction: @JSName with a js.Symbol is not " + - "supported on nested native classes and objects") } } - val jsName = jsInterop.jsNameOf(sym) match { - case JSName.Literal(jsName) => jsName - case JSName.Computed(_) => "" // compile error above - } + if (sym.owner.isStaticOwner) { + for (annot <- sym.annotations) { + if (annot.symbol == JSNameAnnotation && + annot.args.head.tpe.typeSymbol != StringClass) { + reporter.error(annot.pos, + "Implementation restriction: @JSName with a js.Symbol is " + + "not supported on nested native classes and objects") + } + } + + val jsName = jsInterop.jsNameOf(sym) match { + case JSName.Literal(jsName) => jsName + case JSName.Computed(_) => "" // compile error above + } - val ownerLoadSpec = jsInterop.jsNativeLoadSpecOf(sym.owner) - val loadSpec = ownerLoadSpec match { - case Global(globalRef, path) => - Global(globalRef, path :+ jsName) - case Import(module, path) => - Import(module, path :+ jsName) - case ImportWithGlobalFallback( - Import(module, modulePath), Global(globalRef, globalPath)) => - ImportWithGlobalFallback( - Import(module, modulePath :+ jsName), - Global(globalRef, globalPath :+ jsName)) + val ownerLoadSpec = jsInterop.jsNativeLoadSpecOf(sym.owner) + val loadSpec = ownerLoadSpec match { + case Global(globalRef, path) => + Global(globalRef, path :+ jsName) + case Import(module, path) => + Import(module, path :+ jsName) + case ImportWithGlobalFallback( + Import(module, modulePath), Global(globalRef, globalPath)) => + ImportWithGlobalFallback( + Import(module, modulePath :+ jsName), + Global(globalRef, globalPath :+ jsName)) + } + Some(loadSpec) + } else { + None } - Some(loadSpec) } else { def parsePath(pathName: String): List[String] = pathName.split('.').toList diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala index 875d033614..b03a32f1dd 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala @@ -29,7 +29,7 @@ class ScalaJSPlugin(val global: Global) extends NscPlugin { List[NscPluginComponent](PrepInteropComponent) } else { List[NscPluginComponent](PreTyperComponentComponent, PrepInteropComponent, - GenCodeComponent) + ExplicitInnerJSComponent, ExplicitLocalJSComponent, GenCodeComponent) } } @@ -78,6 +78,20 @@ class ScalaJSPlugin(val global: Global) extends NscPlugin { override val runsBefore = List("pickle") } with PrepJSInterop + object ExplicitInnerJSComponent extends { + val global: ScalaJSPlugin.this.global.type = ScalaJSPlugin.this.global + val jsAddons: ScalaJSPlugin.this.jsAddons.type = ScalaJSPlugin.this.jsAddons + override val runsAfter = List("refchecks") + override val runsBefore = List("uncurry") + } with ExplicitInnerJS + + object ExplicitLocalJSComponent extends { + val global: ScalaJSPlugin.this.global.type = ScalaJSPlugin.this.global + val jsAddons: ScalaJSPlugin.this.jsAddons.type = ScalaJSPlugin.this.jsAddons + override val runsAfter = List("specialize") + override val runsBefore = List("explicitouter") + } with ExplicitLocalJS + object GenCodeComponent extends { val global: ScalaJSPlugin.this.global.type = ScalaJSPlugin.this.global val jsAddons: ScalaJSPlugin.this.jsAddons.type = ScalaJSPlugin.this.jsAddons diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index 7b0252ef89..19cbc9ce6e 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -465,29 +465,50 @@ class JSInteropTest extends DirectTest with TestHelpers { } @Test - def noInnerClassTraitObject: Unit = { + def noInnerScalaClassTraitObjectInJSNative: Unit = { for { outer <- Seq("class", "trait") inner <- Seq("class", "trait", "object") - innerIsJSType <- Seq(false, true) } yield { val jsGlobalAnnot = if (outer == "trait") "" else "@JSGlobal" - val innerLine = - if (innerIsJSType) s"$inner A extends js.Object" - else s"$inner A" s""" @js.native $jsGlobalAnnot $outer A extends js.Object { - $innerLine + $inner A + } + """ hasErrors + s""" + |newSource1.scala:7: error: Native JS traits, classes and objects cannot contain inner Scala traits, classes or objects (i.e., not extending js.Any) + | $inner A + | ${" " * inner.length} ^ + """ + } + + } + + @Test + def noInnerNonNativeJSClassTraitObjectInJSNative: Unit = { + + for { + outer <- Seq("class", "trait") + inner <- Seq("class", "trait", "object") + } yield { + val jsGlobalAnnot = + if (outer == "trait") "" + else "@JSGlobal" + s""" + @js.native $jsGlobalAnnot + $outer A extends js.Object { + $inner A extends js.Object } """ hasErrors s""" - |newSource1.scala:7: error: Native JS traits and classes may not have inner traits, classes or objects - | $innerLine - | ${" " * innerLine.indexOf('A')}^ + |newSource1.scala:7: error: Native JS classes and traits cannot contain non-native JS classes, traits or objects + | $inner A extends js.Object + | ${" " * inner.length} ^ """ } @@ -507,7 +528,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } """ hasErrors s""" - |newSource1.scala:8: error: Native JS objects cannot contain inner Scala traits, classes or objects (i.e., not extending js.Any) + |newSource1.scala:8: error: Native JS traits, classes and objects cannot contain inner Scala traits, classes or objects (i.e., not extending js.Any) | $inner A | ${" " * inner.length} ^ """ @@ -528,7 +549,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Native JS objects cannot contain inner Scala traits, classes or objects (i.e., not extending js.Any) + |newSource1.scala:7: error: Native JS traits, classes and objects cannot contain inner Scala traits, classes or objects (i.e., not extending js.Any) | object B | ^ """ @@ -754,7 +775,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } @Test - def notNested: Unit = { + def noNativeJSNestedInScalaClassTrait: Unit = { val outers = List("class", "trait") val inners = List("trait", "class", "object") @@ -762,12 +783,38 @@ class JSInteropTest extends DirectTest with TestHelpers { for { outer <- outers inner <- inners - outerIsJSType <- Seq(false, true) } yield { - val outerLine = - if (outerIsJSType) s"$outer A extends js.Object" - else s"$outer A" + val jsGlobalAnnot = + if (inner == "trait") "" + else "@JSGlobal" + + val errTrg = if (inner == "object") "objects" else "classes" + s""" + $outer A { + @js.native $jsGlobalAnnot + $inner Inner extends js.Object + } + """ hasErrors + s""" + |newSource1.scala:7: error: Scala traits and classes may not have inner native JS traits, classes or objects + | $inner Inner extends js.Object + | ${" " * inner.length}^ + """ + } + + } + + @Test + def noNativeJSNestedInNonNativeJS: Unit = { + + val outers = List("class", "trait", "object") + val inners = List("class", "trait", "object") + + for { + outer <- outers + inner <- inners + } yield { val jsGlobalAnnot = if (inner == "trait") "" else "@JSGlobal" @@ -775,13 +822,13 @@ class JSInteropTest extends DirectTest with TestHelpers { val errTrg = if (inner == "object") "objects" else "classes" s""" - $outerLine { + $outer A extends js.Object { @js.native $jsGlobalAnnot $inner Inner extends js.Object } """ hasErrors s""" - |newSource1.scala:7: error: Traits and classes may not have inner native JS traits, classes or objects + |newSource1.scala:7: error: non-native JS classes, traits and objects may not have inner native JS classes, traits or objects | $inner Inner extends js.Object | ${" " * inner.length}^ """ @@ -1248,28 +1295,6 @@ class JSInteropTest extends DirectTest with TestHelpers { } - @Test - def noNativeClassObjectInsideNonNativeJSObject: Unit = { - - for { - inner <- Seq("class", "object") - } { - s""" - object A extends js.Object { - @js.native - @JSGlobal - $inner B extends js.Object - } - """ hasErrors - s""" - |newSource1.scala:8: error: non-native JS objects may not have inner native JS classes or objects - | $inner B extends js.Object - | ${" " * inner.length} ^ - """ - } - - } - @Test def noNonLiteralJSName: Unit = { @@ -1413,18 +1438,18 @@ class JSInteropTest extends DirectTest with TestHelpers { |newSource1.scala:12: error: Methods and fields cannot be annotated with @JSGlobal. | def bar3: Int = js.native | ^ - |newSource1.scala:16: error: Native JS traits and classes may not have inner traits, classes or objects - | class Inner extends js.Object - | ^ - |newSource1.scala:20: error: Native JS traits and classes may not have inner traits, classes or objects - | object Inner extends js.Object - | ^ - |newSource1.scala:24: error: Native JS traits and classes may not have inner traits, classes or objects - | class InnerImplied extends js.Object - | ^ - |newSource1.scala:28: error: Native JS traits and classes may not have inner traits, classes or objects - | object InnerImplied extends js.Object - | ^ + |newSource1.scala:15: error: Nested JS classes and objects cannot have an @JSGlobal annotation. + | @JSGlobal("Inner") + | ^ + |newSource1.scala:19: error: Nested JS classes and objects cannot have an @JSGlobal annotation. + | @JSGlobal("Inner") + | ^ + |newSource1.scala:23: error: Nested JS classes and objects cannot have an @JSGlobal annotation. + | @JSGlobal + | ^ + |newSource1.scala:27: error: Nested JS classes and objects cannot have an @JSGlobal annotation. + | @JSGlobal + | ^ """ } @@ -1470,16 +1495,16 @@ class JSInteropTest extends DirectTest with TestHelpers { |newSource1.scala:12: error: Methods and fields cannot be annotated with @JSGlobal. | def bar3: Int = js.native | ^ - |newSource1.scala:15: error: Classes and objects nested in a JS native object cannot have an @JSGlobal annotation. + |newSource1.scala:15: error: Nested JS classes and objects cannot have an @JSGlobal annotation. | @JSGlobal("Inner") | ^ - |newSource1.scala:19: error: Classes and objects nested in a JS native object cannot have an @JSGlobal annotation. + |newSource1.scala:19: error: Nested JS classes and objects cannot have an @JSGlobal annotation. | @JSGlobal("Inner") | ^ - |newSource1.scala:23: error: Classes and objects nested in a JS native object cannot have an @JSGlobal annotation. + |newSource1.scala:23: error: Nested JS classes and objects cannot have an @JSGlobal annotation. | @JSGlobal | ^ - |newSource1.scala:27: error: Classes and objects nested in a JS native object cannot have an @JSGlobal annotation. + |newSource1.scala:27: error: Nested JS classes and objects cannot have an @JSGlobal annotation. | @JSGlobal | ^ """ @@ -1512,7 +1537,7 @@ class JSInteropTest extends DirectTest with TestHelpers { object Inner extends js.Object } """ hasErrors - """ + s""" |newSource1.scala:8: error: Methods and fields cannot be annotated with @JSImport. | val bar1: Int = js.native | ^ @@ -1522,12 +1547,12 @@ class JSInteropTest extends DirectTest with TestHelpers { |newSource1.scala:12: error: Methods and fields cannot be annotated with @JSImport. | def bar3: Int = js.native | ^ - |newSource1.scala:16: error: Native JS traits and classes may not have inner traits, classes or objects - | class Inner extends js.Object - | ^ - |newSource1.scala:20: error: Native JS traits and classes may not have inner traits, classes or objects - | object Inner extends js.Object - | ^ + |newSource1.scala:15: error: Nested JS classes and objects cannot have an @JSImport annotation. + | @JSImport("Inner", JSImport.Namespace$fallbackStr) + | ^ + |newSource1.scala:19: error: Nested JS classes and objects cannot have an @JSImport annotation. + | @JSImport("Inner", JSImport.Namespace$fallbackStr) + | ^ """ } @@ -1568,10 +1593,10 @@ class JSInteropTest extends DirectTest with TestHelpers { |newSource1.scala:12: error: Methods and fields cannot be annotated with @JSImport. | def bar3: Int = js.native | ^ - |newSource1.scala:15: error: Classes and objects nested in a JS native object cannot have an @JSImport annotation. + |newSource1.scala:15: error: Nested JS classes and objects cannot have an @JSImport annotation. | @JSImport("Inner", JSImport.Namespace$fallbackStr) | ^ - |newSource1.scala:19: error: Classes and objects nested in a JS native object cannot have an @JSImport annotation. + |newSource1.scala:19: error: Nested JS classes and objects cannot have an @JSImport annotation. | @JSImport("Inner", JSImport.Namespace$fallbackStr) | ^ """ @@ -1979,6 +2004,85 @@ class JSInteropTest extends DirectTest with TestHelpers { } + @Test + def noAbstractLocalJSClass: Unit = { + """ + object Enclosing { + def method(): Unit = { + abstract class AbstractLocalJSClass extends js.Object + } + } + """ hasErrors + """ + |newSource1.scala:7: error: Implementation restriction: local JS classes cannot be abstract + | abstract class AbstractLocalJSClass extends js.Object + | ^ + """ + } + + @Test + def noLoadJSConstructorOfUnstableRef: Unit = { + """ + class Enclosing { + class InnerJSClass extends js.Object + } + + object A { + def method(): Any = + js.constructorOf[Enclosing#InnerJSClass] + } + """ hasErrors + """ + |newSource1.scala:11: error: stable reference to a JS class required but Enclosing#InnerJSClass found + | js.constructorOf[Enclosing#InnerJSClass] + | ^ + """ + + // version-dependent error message due to https://github.com/scala/bug/issues/10619 + """ + class Enclosing { + class InnerJSClass extends js.Object + } + + object A { + def newEnclosing: Enclosing = new Enclosing + + def method(): Any = + js.constructorOf[newEnclosing.InnerJSClass] + } + """.fails() + + """ + class Enclosing { + class InnerJSClass extends js.Object + } + + object A { + def method(a: Any): Boolean = + a.isInstanceOf[Enclosing#InnerJSClass] + } + """ hasErrors + """ + |newSource1.scala:11: error: stable reference to a JS class required but Enclosing#InnerJSClass found + | a.isInstanceOf[Enclosing#InnerJSClass] + | ^ + """ + + // version-dependent error message due to https://github.com/scala/bug/issues/10619 + """ + class Enclosing { + class InnerJSClass extends js.Object + } + + object A { + def newEnclosing: Enclosing = new Enclosing + + def method(a: Any): Boolean = + a.isInstanceOf[newEnclosing.InnerJSClass] + } + """.fails() + } + @Test def noJSSymbolNameOnNestedNativeClassesAndObjects: Unit = { for { diff --git a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala index 8d00bb329a..e9774067ef 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala @@ -41,8 +41,8 @@ object Hashers { def hashClassDef(classDef: ClassDef): ClassDef = { import classDef._ val newMemberDefs = hashMemberDefs(memberDefs) - ClassDef(name, kind, superClass, interfaces, jsNativeLoadSpec, - newMemberDefs, topLevelExportDefs)( + ClassDef(name, kind, jsClassCaptures, superClass, interfaces, jsSuperClass, + jsNativeLoadSpec, newMemberDefs, topLevelExportDefs)( optimizerHints) } @@ -450,12 +450,20 @@ object Hashers { mixTree(body) mixTrees(captureValues) + case CreateJSClass(cls, captureValues) => + mixTag(TagCreateJSClass) + mixClassRef(cls) + mixTrees(captureValues) + case _ => throw new IllegalArgumentException( s"Unable to hash tree of class ${tree.getClass}") } } + def mixOptTree(optTree: Option[Tree]): Unit = + optTree.foreach(mixTree) + def mixTrees(trees: List[Tree]): Unit = trees.foreach(mixTree) @@ -469,6 +477,9 @@ object Hashers { mixInt(dimensions) } + def mixClassRef(classRef: ClassRef): Unit = + mixString(classRef.className) + def mixType(tpe: Type): Unit = tpe match { case AnyType => mixTag(TagAnyType) case NothingType => mixTag(TagNothingType) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index dcd9db29b5..538fa44156 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -812,11 +812,23 @@ object Printers { printRow(params, ">(", ", ", ") = ") printBlock(body) print(')') + + case CreateJSClass(cls, captureValues) => + print("createjsclass[") + print(cls) + printRow(captureValues, "](", ", ", ")") } } def print(classDef: ClassDef): Unit = { import classDef._ + for (jsClassCaptures <- classDef.jsClassCaptures) { + if (jsClassCaptures.isEmpty) + print("captures: none") + else + printRow(jsClassCaptures, "captures: ", ", ", "") + println() + } print(classDef.optimizerHints) kind match { case ClassKind.Class => print("class ") @@ -833,6 +845,11 @@ object Printers { superClass.foreach { cls => print(" extends ") print(cls) + jsSuperClass.foreach { tree => + print(" (via ") + print(tree) + print(")") + } } if (interfaces.nonEmpty) { print(" implements ") diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index 8b0b03d552..7bc36ca7ed 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -435,6 +435,11 @@ object Serializers { writeParamDefs(params) writeTree(body) writeTrees(captureValues) + + case CreateJSClass(cls, captureValues) => + writeByte(TagCreateJSClass) + writeClassRef(cls) + writeTrees(captureValues) } if (UseDebugMagic) writeInt(DebugMagic) @@ -461,8 +466,11 @@ object Serializers { writePosition(classDef.pos) writeIdent(name) writeByte(ClassKind.toByte(kind)) + writeBoolean(jsClassCaptures.isDefined) + jsClassCaptures.foreach(writeParamDefs(_)) writeOptIdent(superClass) writeIdents(interfaces) + writeOptTree(jsSuperClass) writeJSNativeLoadSpec(jsNativeLoadSpec) writeMemberDefs(memberDefs) writeTopLevelExportDefs(topLevelExportDefs) @@ -632,6 +640,9 @@ object Serializers { buffer.writeInt(dimensions) } + def writeClassRef(cls: ClassRef): Unit = + writeString(cls.className) + def writePropertyName(name: PropertyName): Unit = name match { case name: Ident => buffer.writeByte(TagPropertyNameIdent) @@ -887,9 +898,14 @@ object Serializers { case TagStringLiteral => StringLiteral(readString()) case TagClassOf => ClassOf(readTypeRef()) - case TagVarRef => VarRef(readIdent())(readType()) - case TagThis => This()(readType()) - case TagClosure => Closure(readParamDefs(), readParamDefs(), readTree(), readTrees()) + case TagVarRef => + VarRef(readIdent())(readType()) + case TagThis => + This()(readType()) + case TagClosure => + Closure(readParamDefs(), readParamDefs(), readTree(), readTrees()) + case TagCreateJSClass => + CreateJSClass(readClassRef(), readTrees()) } if (UseDebugMagic) { val magic = readInt() @@ -908,14 +924,19 @@ object Serializers { implicit val pos = readPosition() val name = readIdent() val kind = ClassKind.fromByte(readByte()) + val hasJSClassCaptures = readBoolean() + val jsClassCaptures = + if (!hasJSClassCaptures) None + else Some(readParamDefs()) val superClass = readOptIdent() val parents = readIdents() + val jsSuperClass = readOptTree() val jsNativeLoadSpec = readJSNativeLoadSpec() val memberDefs = readMemberDefs() val topLevelExportDefs = readTopLevelExportDefs() val optimizerHints = new OptimizerHints(readInt()) - ClassDef(name, kind, superClass, parents, jsNativeLoadSpec, memberDefs, - topLevelExportDefs)( + ClassDef(name, kind, jsClassCaptures, superClass, parents, jsSuperClass, + jsNativeLoadSpec, memberDefs, topLevelExportDefs)( optimizerHints) } @@ -1048,6 +1069,9 @@ object Serializers { } } + def readClassRef(): ClassRef = + ClassRef(readString()) + def readPropertyName(): PropertyName = { input.readByte() match { case TagPropertyNameIdent => diff --git a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala index ee42d01568..11b2afcc53 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala @@ -91,6 +91,7 @@ private[ir] object Tags { final val TagVarRef = TagClassOf + 1 final val TagThis = TagVarRef + 1 final val TagClosure = TagThis + 1 + final val TagCreateJSClass = TagClosure + 1 // Tags for member defs diff --git a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala index ea6043a671..1f2d411b37 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala @@ -192,6 +192,9 @@ object Transformers { Closure(captureParams, params, transformExpr(body), captureValues.map(transformExpr)) + case CreateJSClass(cls, captureValues) => + CreateJSClass(cls, captureValues.map(transformExpr)) + // Trees that need not be transformed case _:Skip | _:Continue | _:Debugger | _:LoadModule | _:SelectStatic | @@ -205,7 +208,8 @@ object Transformers { abstract class ClassTransformer extends Transformer { def transformClassDef(tree: ClassDef): ClassDef = { import tree._ - ClassDef(name, kind, superClass, interfaces, jsNativeLoadSpec, + ClassDef(name, kind, jsClassCaptures, superClass, interfaces, + jsSuperClass.map(transformExpr), jsNativeLoadSpec, memberDefs.map(transformMemberDef), topLevelExportDefs.map(transformTopLevelExportDef))( tree.optimizerHints)(tree.pos) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala index d47588de6f..526940733b 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala @@ -196,6 +196,9 @@ object Traversers { traverse(body) captureValues.foreach(traverse) + case CreateJSClass(_, captureValues) => + captureValues.foreach(traverse) + // Trees that need not be traversed case _:Skip | _:Continue | _:Debugger | _:LoadModule | _:SelectStatic | @@ -204,6 +207,7 @@ object Traversers { } def traverseClassDef(tree: ClassDef): Unit = { + tree.jsSuperClass.foreach(traverse) tree.memberDefs.foreach(traverseMemberDef) tree.topLevelExportDefs.foreach(traverseTopLevelExportDef) } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 59bf661a48..0ce2d832b0 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -858,13 +858,58 @@ object Trees { val tpe = AnyType } + /** Creates a JavaScript class value. + * + * @param cls + * Reference to the `ClassDef` for the class definition, which must have + * `jsClassCaptures.nonEmpty` + * + * @param captureValues + * Actual values for the captured parameters (in the `ClassDef`'s + * `jsClassCaptures.get`) + */ + case class CreateJSClass(cls: ClassRef, captureValues: List[Tree])( + implicit val pos: Position) + extends Tree { + val tpe = AnyType + } + // Classes final class ClassDef( val name: Ident, val kind: ClassKind, + /** JS class captures. + * + * - If `kind != ClassKind.JSClass`, must be `None`. + * - Otherwise, if `None`, this is a top-level class, whose JS class + * value is unique in the world and can be loaded with + * `LoadJSConstructor`. + * - If `Some(params)`, this is a nested JS class. New class values for + * this class def can be created with `CreateJSClass`. + * `LoadJSConstructor` is not valid for such a class def, since it + * does not have a unique JS class value to load. + * + * Note that `Some(Nil)` is valid and is a nested JS class that happens + * to have no captures. It will still have zero to many JS class values + * created with `CreateJSClass`. + */ + val jsClassCaptures: Option[List[ParamDef]], val superClass: Option[Ident], val interfaces: List[Ident], + /** If defined, an expression returning the JS class value of the super + * class. + * + * If `kind` is neither `ClassKind.JSClass` nor `ClassKind.JSModule`, + * this field must be `None`. + * + * The expression can depend on JS class captures. + * + * If empty for a non-native JS class, the JS super class value is + * implicitly `LoadJSConstructor(superClass.get)`. In that case the + * class def for `superClass` must have `jsClassCaptures.isEmpty`. + */ + val jsSuperClass: Option[Tree], val jsNativeLoadSpec: Option[JSNativeLoadSpec], val memberDefs: List[MemberDef], val topLevelExportDefs: List[TopLevelExportDef] @@ -876,15 +921,17 @@ object Trees { def apply( name: Ident, kind: ClassKind, + jsClassCaptures: Option[List[ParamDef]], superClass: Option[Ident], interfaces: List[Ident], + jsSuperClass: Option[Tree], jsNativeLoadSpec: Option[JSNativeLoadSpec], memberDefs: List[MemberDef], topLevelExportDefs: List[TopLevelExportDef])( optimizerHints: OptimizerHints)( implicit pos: Position): ClassDef = { - new ClassDef(name, kind, superClass, interfaces, jsNativeLoadSpec, - memberDefs, topLevelExportDefs)( + new ClassDef(name, kind, jsClassCaptures, superClass, interfaces, + jsSuperClass, jsNativeLoadSpec, memberDefs, topLevelExportDefs)( optimizerHints) } } diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala index 8cf7633624..cc43bccc6e 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala @@ -851,11 +851,21 @@ class PrintersTest { List(ref("a", IntType), i(6)))) } + @Test def printCreateJSClass(): Unit = { + assertPrintEquals( + """ + |createjsclass[LFoo](x, y) + """, + CreateJSClass("LFoo", List(ref("x", IntType), ref("y", AnyType)))) + } + @Test def printClassDefKinds(): Unit = { import ClassKind._ def makeForKind(kind: ClassKind): ClassDef = { - ClassDef("LTest", kind, Some(ObjectClass), Nil, None, Nil, Nil)(NoOptHints) + ClassDef("LTest", kind, None, Some(ObjectClass), Nil, None, None, Nil, + Nil)( + NoOptHints) } assertPrintEquals( @@ -925,7 +935,8 @@ class PrintersTest { @Test def printClassDefParents(): Unit = { def makeForParents(superClass: Option[Ident], interfaces: List[Ident]): ClassDef = { - ClassDef("LTest", ClassKind.Class, superClass, interfaces, None, Nil, Nil)( + ClassDef("LTest", ClassKind.Class, None, superClass, interfaces, None, + None, Nil, Nil)( NoOptHints) } @@ -957,8 +968,8 @@ class PrintersTest { |native js class LTest extends O loadfrom global:Foo["Bar"] { |} """, - ClassDef("LTest", ClassKind.NativeJSClass, Some(ObjectClass), Nil, - Some(JSNativeLoadSpec.Global("Foo", List("Bar"))), Nil, Nil)( + ClassDef("LTest", ClassKind.NativeJSClass, None, Some(ObjectClass), Nil, + None, Some(JSNativeLoadSpec.Global("Foo", List("Bar"))), Nil, Nil)( NoOptHints)) assertPrintEquals( @@ -966,8 +977,8 @@ class PrintersTest { |native js class LTest extends O loadfrom import(foo)["Bar"] { |} """, - ClassDef("LTest", ClassKind.NativeJSClass, Some(ObjectClass), Nil, - Some(JSNativeLoadSpec.Import("foo", List("Bar"))), Nil, Nil)( + ClassDef("LTest", ClassKind.NativeJSClass, None, Some(ObjectClass), Nil, + None, Some(JSNativeLoadSpec.Import("foo", List("Bar"))), Nil, Nil)( NoOptHints)) assertPrintEquals( @@ -975,21 +986,61 @@ class PrintersTest { |native js class LTest extends O loadfrom import(foo)["Bar"] fallback global:Baz["Foobar"] { |} """, - ClassDef("LTest", ClassKind.NativeJSClass, Some(ObjectClass), Nil, + ClassDef("LTest", ClassKind.NativeJSClass, None, Some(ObjectClass), Nil, + None, Some(JSNativeLoadSpec.ImportWithGlobalFallback( JSNativeLoadSpec.Import("foo", List("Bar")), JSNativeLoadSpec.Global("Baz", List("Foobar")))), Nil, Nil)( NoOptHints)) } + @Test def printClassDefJSClassCaptures(): Unit = { + assertPrintEquals( + """ + |captures: none + |js class LTest extends O { + |} + """, + ClassDef("LTest", ClassKind.JSClass, Some(Nil), Some(ObjectClass), Nil, + None, None, Nil, Nil)( + NoOptHints)) + + assertPrintEquals( + """ + |captures: x: int, y: string + |js class LTest extends O { + |} + """, + ClassDef("LTest", ClassKind.JSClass, + Some(List( + ParamDef("x", IntType, mutable = false, rest = false), + ParamDef("y", StringType, mutable = false, rest = false) + )), + Some(ObjectClass), Nil, None, None, Nil, Nil)( + NoOptHints)) + } + + @Test def printClassDefJSSuperClass(): Unit = { + assertPrintEquals( + """ + |captures: sup: any + |js class LTest extends LBar (via sup) { + |} + """, + ClassDef("LTest", ClassKind.JSClass, + Some(List(ParamDef("sup", AnyType, mutable = false, rest = false))), + Some("LBar"), Nil, Some(ref("sup", AnyType)), None, Nil, Nil)( + NoOptHints)) + } + @Test def printClassDefOptimizerHints(): Unit = { assertPrintEquals( """ |@hints(1) class LTest extends O { |} """, - ClassDef("LTest", ClassKind.Class, Some(ObjectClass), Nil, None, Nil, - Nil)( + ClassDef("LTest", ClassKind.Class, None, Some(ObjectClass), Nil, None, + None, Nil, Nil)( NoOptHints.withInline(true))) } @@ -1002,7 +1053,8 @@ class PrintersTest { | export top module "pkg.Foo" |} """, - ClassDef("LTest", ClassKind.ModuleClass, Some(ObjectClass), Nil, None, + ClassDef("LTest", ClassKind.ModuleClass, None, Some(ObjectClass), Nil, + None, None, List( FieldDef(static = false, "x$1", IntType, mutable = false), FieldDef(static = false, "y$1", IntType, mutable = true)), diff --git a/library/src/main/scala/scala/scalajs/runtime/package.scala b/library/src/main/scala/scala/scalajs/runtime/package.scala index 6280606d20..bef3fe8a6d 100644 --- a/library/src/main/scala/scala/scalajs/runtime/package.scala +++ b/library/src/main/scala/scala/scalajs/runtime/package.scala @@ -46,6 +46,45 @@ package object runtime { def newConstructorTag[T <: js.Any](constructor: js.Dynamic): js.ConstructorTag[T] = new js.ConstructorTag[T](constructor) + /** Dummy method used to preserve where and how an inner JS class should be + * created. + * + * @param clazz `classOf` of the class to be created + * @param superClass JS class value of the super class + */ + def createInnerJSClass(clazz: Class[_], superClass: AnyRef): AnyRef = + throw new Error("stub") + + /** Dummy method used to preserve where and how a local JS class should be + * created. + * + * @param clazz + * `classOf` of the class to be created + * @param superClass + * JavaScript class value of the super class + * @param fakeNewInstances + * Fake `New` instantiations used to retrieve actual capture params + */ + def createLocalJSClass(clazz: Class[_], superClass: AnyRef, + fakeNewInstances: Array[AnyRef]): AnyRef = { + throw new Error("stub") + } + + /** Dummy method used to preserve a JS class value term associated with an + * expression tree. + * + * This is used for: + * - New instances of nested JS classes and objects + * - Super calls in nested JS classes + * + * @param jsclass + * The contextual JS class value + * @param inner + * The original inner tree + */ + def withContextualJSClassValue[A](jsclass: AnyRef, inner: A): A = + throw new Error("stub") + /** Returns an array of the enumerable properties in an object's prototype * chain. * diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/neg/t6446-additional.check index 3c72fe21c0..dd8738b40e 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/neg/t6446-additional.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/neg/t6446-additional.check @@ -11,21 +11,23 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - ploogin 28 A sample phase that does so many things it's kind of hard... - terminal 29 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + ploogin 30 A sample phase that does so many things it's kind of hard... + terminal 31 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/neg/t6446-missing.check index 4761e1f032..0283ab3d47 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/neg/t6446-missing.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/neg/t6446-missing.check @@ -12,20 +12,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - terminal 28 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/neg/t6446-show-phases.check index 28b57055a3..568fd80c8d 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/neg/t6446-show-phases.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/neg/t6446-show-phases.check @@ -11,20 +11,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - terminal 28 the last phase during a compilation run \ No newline at end of file +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/neg/t7494-no-options.check index fa3cdc9193..7b0d01750a 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/neg/t7494-no-options.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/neg/t7494-no-options.check @@ -12,21 +12,23 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - ploogin 28 A sample phase that does so many things it's kind of hard... - terminal 29 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + ploogin 30 A sample phase that does so many things it's kind of hard... + terminal 31 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/run/t6102.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/run/t6102.check index 3082267832..aa342511d0 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/run/t6102.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/run/t6102.check @@ -9,9 +9,11 @@ [running phase extmethods on t6102.scala] [running phase pickler on t6102.scala] [running phase refchecks on t6102.scala] +[running phase xplicitinnerjs on t6102.scala] [running phase uncurry on t6102.scala] [running phase tailcalls on t6102.scala] [running phase specialize on t6102.scala] +[running phase xplicitlocaljs on t6102.scala] [running phase explicitouter on t6102.scala] [running phase erasure on t6102.scala] [running phase posterasure on t6102.scala] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/neg/t6446-additional.check index 3c72fe21c0..dd8738b40e 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/neg/t6446-additional.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/neg/t6446-additional.check @@ -11,21 +11,23 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - ploogin 28 A sample phase that does so many things it's kind of hard... - terminal 29 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + ploogin 30 A sample phase that does so many things it's kind of hard... + terminal 31 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/neg/t6446-missing.check index 4761e1f032..0283ab3d47 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/neg/t6446-missing.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/neg/t6446-missing.check @@ -12,20 +12,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - terminal 28 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/neg/t6446-show-phases.check index 28b57055a3..568fd80c8d 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/neg/t6446-show-phases.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/neg/t6446-show-phases.check @@ -11,20 +11,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - terminal 28 the last phase during a compilation run \ No newline at end of file +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/neg/t7494-no-options.check index fa3cdc9193..7b0d01750a 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/neg/t7494-no-options.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/neg/t7494-no-options.check @@ -12,21 +12,23 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - ploogin 28 A sample phase that does so many things it's kind of hard... - terminal 29 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + ploogin 30 A sample phase that does so many things it's kind of hard... + terminal 31 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/run/t6102.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/run/t6102.check index 3082267832..aa342511d0 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/run/t6102.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/run/t6102.check @@ -9,9 +9,11 @@ [running phase extmethods on t6102.scala] [running phase pickler on t6102.scala] [running phase refchecks on t6102.scala] +[running phase xplicitinnerjs on t6102.scala] [running phase uncurry on t6102.scala] [running phase tailcalls on t6102.scala] [running phase specialize on t6102.scala] +[running phase xplicitlocaljs on t6102.scala] [running phase explicitouter on t6102.scala] [running phase erasure on t6102.scala] [running phase posterasure on t6102.scala] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-additional.check index 3c72fe21c0..dd8738b40e 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-additional.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-additional.check @@ -11,21 +11,23 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - ploogin 28 A sample phase that does so many things it's kind of hard... - terminal 29 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + ploogin 30 A sample phase that does so many things it's kind of hard... + terminal 31 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-missing.check index 4761e1f032..0283ab3d47 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-missing.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-missing.check @@ -12,20 +12,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - terminal 28 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-show-phases.check index 28b57055a3..568fd80c8d 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-show-phases.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t6446-show-phases.check @@ -11,20 +11,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - terminal 28 the last phase during a compilation run \ No newline at end of file +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t7494-no-options.check index fa3cdc9193..7b0d01750a 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t7494-no-options.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/neg/t7494-no-options.check @@ -12,21 +12,23 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - ploogin 28 A sample phase that does so many things it's kind of hard... - terminal 29 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + ploogin 30 A sample phase that does so many things it's kind of hard... + terminal 31 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t6102.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t6102.check index 3082267832..aa342511d0 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t6102.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/run/t6102.check @@ -9,9 +9,11 @@ [running phase extmethods on t6102.scala] [running phase pickler on t6102.scala] [running phase refchecks on t6102.scala] +[running phase xplicitinnerjs on t6102.scala] [running phase uncurry on t6102.scala] [running phase tailcalls on t6102.scala] [running phase specialize on t6102.scala] +[running phase xplicitlocaljs on t6102.scala] [running phase explicitouter on t6102.scala] [running phase erasure on t6102.scala] [running phase posterasure on t6102.scala] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-additional.check index 3c72fe21c0..dd8738b40e 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-additional.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-additional.check @@ -11,21 +11,23 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - ploogin 28 A sample phase that does so many things it's kind of hard... - terminal 29 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + ploogin 30 A sample phase that does so many things it's kind of hard... + terminal 31 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-missing.check index 4761e1f032..0283ab3d47 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-missing.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-missing.check @@ -12,20 +12,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - terminal 28 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-show-phases.check index 28b57055a3..568fd80c8d 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-show-phases.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t6446-show-phases.check @@ -11,20 +11,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - terminal 28 the last phase during a compilation run \ No newline at end of file +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t7494-no-options.check index fa3cdc9193..7b0d01750a 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t7494-no-options.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/neg/t7494-no-options.check @@ -12,21 +12,23 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - ploogin 28 A sample phase that does so many things it's kind of hard... - terminal 29 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + ploogin 30 A sample phase that does so many things it's kind of hard... + terminal 31 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t6102.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t6102.check index 3082267832..aa342511d0 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t6102.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/run/t6102.check @@ -9,9 +9,11 @@ [running phase extmethods on t6102.scala] [running phase pickler on t6102.scala] [running phase refchecks on t6102.scala] +[running phase xplicitinnerjs on t6102.scala] [running phase uncurry on t6102.scala] [running phase tailcalls on t6102.scala] [running phase specialize on t6102.scala] +[running phase xplicitlocaljs on t6102.scala] [running phase explicitouter on t6102.scala] [running phase erasure on t6102.scala] [running phase posterasure on t6102.scala] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/neg/t6446-additional.check index 3c72fe21c0..dd8738b40e 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/neg/t6446-additional.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/neg/t6446-additional.check @@ -11,21 +11,23 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - ploogin 28 A sample phase that does so many things it's kind of hard... - terminal 29 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + ploogin 30 A sample phase that does so many things it's kind of hard... + terminal 31 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/neg/t6446-missing.check index 4761e1f032..0283ab3d47 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/neg/t6446-missing.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/neg/t6446-missing.check @@ -12,20 +12,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - terminal 28 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/neg/t6446-show-phases.check index 28b57055a3..568fd80c8d 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/neg/t6446-show-phases.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/neg/t6446-show-phases.check @@ -11,20 +11,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - terminal 28 the last phase during a compilation run \ No newline at end of file +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/neg/t7494-no-options.check index fa3cdc9193..7b0d01750a 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/neg/t7494-no-options.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/neg/t7494-no-options.check @@ -12,21 +12,23 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - ploogin 28 A sample phase that does so many things it's kind of hard... - terminal 29 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + ploogin 30 A sample phase that does so many things it's kind of hard... + terminal 31 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/run/t6102.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/run/t6102.check index 3082267832..aa342511d0 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/run/t6102.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/run/t6102.check @@ -9,9 +9,11 @@ [running phase extmethods on t6102.scala] [running phase pickler on t6102.scala] [running phase refchecks on t6102.scala] +[running phase xplicitinnerjs on t6102.scala] [running phase uncurry on t6102.scala] [running phase tailcalls on t6102.scala] [running phase specialize on t6102.scala] +[running phase xplicitlocaljs on t6102.scala] [running phase explicitouter on t6102.scala] [running phase erasure on t6102.scala] [running phase posterasure on t6102.scala] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/neg/t6446-additional.check index 3c72fe21c0..dd8738b40e 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/neg/t6446-additional.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/neg/t6446-additional.check @@ -11,21 +11,23 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - ploogin 28 A sample phase that does so many things it's kind of hard... - terminal 29 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + ploogin 30 A sample phase that does so many things it's kind of hard... + terminal 31 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/neg/t6446-missing.check index 4761e1f032..0283ab3d47 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/neg/t6446-missing.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/neg/t6446-missing.check @@ -12,20 +12,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - terminal 28 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/neg/t6446-show-phases.check index 28b57055a3..568fd80c8d 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/neg/t6446-show-phases.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/neg/t6446-show-phases.check @@ -11,20 +11,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - terminal 28 the last phase during a compilation run \ No newline at end of file +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/neg/t7494-no-options.check index fa3cdc9193..7b0d01750a 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/neg/t7494-no-options.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/neg/t7494-no-options.check @@ -12,21 +12,23 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - ploogin 28 A sample phase that does so many things it's kind of hard... - terminal 29 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + ploogin 30 A sample phase that does so many things it's kind of hard... + terminal 31 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/run/t6102.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/run/t6102.check index 3082267832..aa342511d0 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/run/t6102.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/run/t6102.check @@ -9,9 +9,11 @@ [running phase extmethods on t6102.scala] [running phase pickler on t6102.scala] [running phase refchecks on t6102.scala] +[running phase xplicitinnerjs on t6102.scala] [running phase uncurry on t6102.scala] [running phase tailcalls on t6102.scala] [running phase specialize on t6102.scala] +[running phase xplicitlocaljs on t6102.scala] [running phase explicitouter on t6102.scala] [running phase erasure on t6102.scala] [running phase posterasure on t6102.scala] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/neg/t6446-additional.check index 3c72fe21c0..dd8738b40e 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/neg/t6446-additional.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/neg/t6446-additional.check @@ -11,21 +11,23 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - ploogin 28 A sample phase that does so many things it's kind of hard... - terminal 29 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + ploogin 30 A sample phase that does so many things it's kind of hard... + terminal 31 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/neg/t6446-missing.check index 4761e1f032..0283ab3d47 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/neg/t6446-missing.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/neg/t6446-missing.check @@ -12,20 +12,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - terminal 28 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/neg/t6446-show-phases.check index 28b57055a3..568fd80c8d 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/neg/t6446-show-phases.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/neg/t6446-show-phases.check @@ -11,20 +11,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - terminal 28 the last phase during a compilation run \ No newline at end of file +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/neg/t7494-no-options.check index fa3cdc9193..7b0d01750a 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/neg/t7494-no-options.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/neg/t7494-no-options.check @@ -12,21 +12,23 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - ploogin 28 A sample phase that does so many things it's kind of hard... - terminal 29 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + ploogin 30 A sample phase that does so many things it's kind of hard... + terminal 31 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/run/t6102.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/run/t6102.check index 3082267832..aa342511d0 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/run/t6102.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/run/t6102.check @@ -9,9 +9,11 @@ [running phase extmethods on t6102.scala] [running phase pickler on t6102.scala] [running phase refchecks on t6102.scala] +[running phase xplicitinnerjs on t6102.scala] [running phase uncurry on t6102.scala] [running phase tailcalls on t6102.scala] [running phase specialize on t6102.scala] +[running phase xplicitlocaljs on t6102.scala] [running phase explicitouter on t6102.scala] [running phase erasure on t6102.scala] [running phase posterasure on t6102.scala] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/neg/t6446-additional.check index 3c72fe21c0..dd8738b40e 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/neg/t6446-additional.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/neg/t6446-additional.check @@ -11,21 +11,23 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - ploogin 28 A sample phase that does so many things it's kind of hard... - terminal 29 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + ploogin 30 A sample phase that does so many things it's kind of hard... + terminal 31 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/neg/t6446-missing.check index 4761e1f032..0283ab3d47 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/neg/t6446-missing.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/neg/t6446-missing.check @@ -12,20 +12,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - terminal 28 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/neg/t6446-show-phases.check index 28b57055a3..568fd80c8d 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/neg/t6446-show-phases.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/neg/t6446-show-phases.check @@ -11,20 +11,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - terminal 28 the last phase during a compilation run \ No newline at end of file +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/neg/t7494-no-options.check index fa3cdc9193..7b0d01750a 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/neg/t7494-no-options.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/neg/t7494-no-options.check @@ -12,21 +12,23 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - ploogin 28 A sample phase that does so many things it's kind of hard... - terminal 29 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + ploogin 30 A sample phase that does so many things it's kind of hard... + terminal 31 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/run/t6102.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/run/t6102.check index 3082267832..aa342511d0 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/run/t6102.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/run/t6102.check @@ -9,9 +9,11 @@ [running phase extmethods on t6102.scala] [running phase pickler on t6102.scala] [running phase refchecks on t6102.scala] +[running phase xplicitinnerjs on t6102.scala] [running phase uncurry on t6102.scala] [running phase tailcalls on t6102.scala] [running phase specialize on t6102.scala] +[running phase xplicitlocaljs on t6102.scala] [running phase explicitouter on t6102.scala] [running phase erasure on t6102.scala] [running phase posterasure on t6102.scala] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/neg/t6446-additional.check index 3c72fe21c0..dd8738b40e 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/neg/t6446-additional.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/neg/t6446-additional.check @@ -11,21 +11,23 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - ploogin 28 A sample phase that does so many things it's kind of hard... - terminal 29 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + ploogin 30 A sample phase that does so many things it's kind of hard... + terminal 31 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/neg/t6446-missing.check index 4761e1f032..0283ab3d47 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/neg/t6446-missing.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/neg/t6446-missing.check @@ -12,20 +12,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - terminal 28 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/neg/t6446-show-phases.check index 28b57055a3..568fd80c8d 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/neg/t6446-show-phases.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/neg/t6446-show-phases.check @@ -11,20 +11,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - terminal 28 the last phase during a compilation run \ No newline at end of file +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/neg/t7494-no-options.check index fa3cdc9193..7b0d01750a 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/neg/t7494-no-options.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/neg/t7494-no-options.check @@ -12,21 +12,23 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - tailcalls 13 replace tail calls by jumps - specialize 14 @specialized-driven class and method specialization - explicitouter 15 this refs to outer pointers - erasure 16 erase types, add interfaces for traits - posterasure 17 clean up erased inline classes - lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - icode 26 generate portable intermediate code - jvm 27 generate JVM bytecode - ploogin 28 A sample phase that does so many things it's kind of hard... - terminal 29 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization +xplicitlocaljs 16 make references to local JS classes explicit + explicitouter 17 this refs to outer pointers + erasure 18 erase types, add interfaces for traits + posterasure 19 clean up erased inline classes + lazyvals 20 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + icode 28 generate portable intermediate code + jvm 29 generate JVM bytecode + ploogin 30 A sample phase that does so many things it's kind of hard... + terminal 31 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/run/t6102.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/run/t6102.check index 3082267832..aa342511d0 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/run/t6102.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/run/t6102.check @@ -9,9 +9,11 @@ [running phase extmethods on t6102.scala] [running phase pickler on t6102.scala] [running phase refchecks on t6102.scala] +[running phase xplicitinnerjs on t6102.scala] [running phase uncurry on t6102.scala] [running phase tailcalls on t6102.scala] [running phase specialize on t6102.scala] +[running phase xplicitlocaljs on t6102.scala] [running phase explicitouter on t6102.scala] [running phase erasure on t6102.scala] [running phase posterasure on t6102.scala] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-additional.check index b7ce23da2f..3fce708aa6 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-additional.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-additional.check @@ -11,20 +11,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - fields 13 synthesize accessors and fields, add bitmaps for lazy vals - tailcalls 14 replace tail calls by jumps - specialize 15 @specialized-driven class and method specialization - explicitouter 16 this refs to outer pointers - erasure 17 erase types, add interfaces for traits - posterasure 18 clean up erased inline classes - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - jvm 26 generate JVM bytecode - ploogin 27 A sample phase that does so many things it's kind of hard... - terminal 28 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + fields 14 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 15 replace tail calls by jumps + specialize 16 @specialized-driven class and method specialization +xplicitlocaljs 17 make references to local JS classes explicit + explicitouter 18 this refs to outer pointers + erasure 19 erase types, add interfaces for traits + posterasure 20 clean up erased inline classes + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + jvm 28 generate JVM bytecode + ploogin 29 A sample phase that does so many things it's kind of hard... + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-missing.check index 56b74a3128..c12c664813 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-missing.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-missing.check @@ -12,19 +12,21 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - fields 13 synthesize accessors and fields, add bitmaps for lazy vals - tailcalls 14 replace tail calls by jumps - specialize 15 @specialized-driven class and method specialization - explicitouter 16 this refs to outer pointers - erasure 17 erase types, add interfaces for traits - posterasure 18 clean up erased inline classes - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - jvm 26 generate JVM bytecode - terminal 27 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + fields 14 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 15 replace tail calls by jumps + specialize 16 @specialized-driven class and method specialization +xplicitlocaljs 17 make references to local JS classes explicit + explicitouter 18 this refs to outer pointers + erasure 19 erase types, add interfaces for traits + posterasure 20 clean up erased inline classes + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + jvm 28 generate JVM bytecode + terminal 29 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-show-phases.check index cde255e3b1..4bfb4500df 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-show-phases.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t6446-show-phases.check @@ -11,19 +11,21 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - fields 13 synthesize accessors and fields, add bitmaps for lazy vals - tailcalls 14 replace tail calls by jumps - specialize 15 @specialized-driven class and method specialization - explicitouter 16 this refs to outer pointers - erasure 17 erase types, add interfaces for traits - posterasure 18 clean up erased inline classes - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - jvm 26 generate JVM bytecode - terminal 27 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + fields 14 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 15 replace tail calls by jumps + specialize 16 @specialized-driven class and method specialization +xplicitlocaljs 17 make references to local JS classes explicit + explicitouter 18 this refs to outer pointers + erasure 19 erase types, add interfaces for traits + posterasure 20 clean up erased inline classes + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + jvm 28 generate JVM bytecode + terminal 29 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t7494-no-options.check index d8be421e5e..5d521dc8a5 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t7494-no-options.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/neg/t7494-no-options.check @@ -12,20 +12,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - fields 13 synthesize accessors and fields, add bitmaps for lazy vals - tailcalls 14 replace tail calls by jumps - specialize 15 @specialized-driven class and method specialization - explicitouter 16 this refs to outer pointers - erasure 17 erase types, add interfaces for traits - posterasure 18 clean up erased inline classes - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - jvm 26 generate JVM bytecode - ploogin 27 A sample phase that does so many things it's kind of hard... - terminal 28 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + fields 14 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 15 replace tail calls by jumps + specialize 16 @specialized-driven class and method specialization +xplicitlocaljs 17 make references to local JS classes explicit + explicitouter 18 this refs to outer pointers + erasure 19 erase types, add interfaces for traits + posterasure 20 clean up erased inline classes + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + jvm 28 generate JVM bytecode + ploogin 29 A sample phase that does so many things it's kind of hard... + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-additional.check index b7ce23da2f..3fce708aa6 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-additional.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-additional.check @@ -11,20 +11,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - fields 13 synthesize accessors and fields, add bitmaps for lazy vals - tailcalls 14 replace tail calls by jumps - specialize 15 @specialized-driven class and method specialization - explicitouter 16 this refs to outer pointers - erasure 17 erase types, add interfaces for traits - posterasure 18 clean up erased inline classes - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - jvm 26 generate JVM bytecode - ploogin 27 A sample phase that does so many things it's kind of hard... - terminal 28 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + fields 14 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 15 replace tail calls by jumps + specialize 16 @specialized-driven class and method specialization +xplicitlocaljs 17 make references to local JS classes explicit + explicitouter 18 this refs to outer pointers + erasure 19 erase types, add interfaces for traits + posterasure 20 clean up erased inline classes + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + jvm 28 generate JVM bytecode + ploogin 29 A sample phase that does so many things it's kind of hard... + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-missing.check index 56b74a3128..c12c664813 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-missing.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-missing.check @@ -12,19 +12,21 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - fields 13 synthesize accessors and fields, add bitmaps for lazy vals - tailcalls 14 replace tail calls by jumps - specialize 15 @specialized-driven class and method specialization - explicitouter 16 this refs to outer pointers - erasure 17 erase types, add interfaces for traits - posterasure 18 clean up erased inline classes - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - jvm 26 generate JVM bytecode - terminal 27 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + fields 14 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 15 replace tail calls by jumps + specialize 16 @specialized-driven class and method specialization +xplicitlocaljs 17 make references to local JS classes explicit + explicitouter 18 this refs to outer pointers + erasure 19 erase types, add interfaces for traits + posterasure 20 clean up erased inline classes + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + jvm 28 generate JVM bytecode + terminal 29 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-show-phases.check index cde255e3b1..4bfb4500df 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-show-phases.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t6446-show-phases.check @@ -11,19 +11,21 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - fields 13 synthesize accessors and fields, add bitmaps for lazy vals - tailcalls 14 replace tail calls by jumps - specialize 15 @specialized-driven class and method specialization - explicitouter 16 this refs to outer pointers - erasure 17 erase types, add interfaces for traits - posterasure 18 clean up erased inline classes - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - jvm 26 generate JVM bytecode - terminal 27 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + fields 14 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 15 replace tail calls by jumps + specialize 16 @specialized-driven class and method specialization +xplicitlocaljs 17 make references to local JS classes explicit + explicitouter 18 this refs to outer pointers + erasure 19 erase types, add interfaces for traits + posterasure 20 clean up erased inline classes + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + jvm 28 generate JVM bytecode + terminal 29 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t7494-no-options.check index d8be421e5e..5d521dc8a5 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t7494-no-options.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/neg/t7494-no-options.check @@ -12,20 +12,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - fields 13 synthesize accessors and fields, add bitmaps for lazy vals - tailcalls 14 replace tail calls by jumps - specialize 15 @specialized-driven class and method specialization - explicitouter 16 this refs to outer pointers - erasure 17 erase types, add interfaces for traits - posterasure 18 clean up erased inline classes - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - jvm 26 generate JVM bytecode - ploogin 27 A sample phase that does so many things it's kind of hard... - terminal 28 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + fields 14 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 15 replace tail calls by jumps + specialize 16 @specialized-driven class and method specialization +xplicitlocaljs 17 make references to local JS classes explicit + explicitouter 18 this refs to outer pointers + erasure 19 erase types, add interfaces for traits + posterasure 20 clean up erased inline classes + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + jvm 28 generate JVM bytecode + ploogin 29 A sample phase that does so many things it's kind of hard... + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-additional.check index b7ce23da2f..3fce708aa6 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-additional.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-additional.check @@ -11,20 +11,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - fields 13 synthesize accessors and fields, add bitmaps for lazy vals - tailcalls 14 replace tail calls by jumps - specialize 15 @specialized-driven class and method specialization - explicitouter 16 this refs to outer pointers - erasure 17 erase types, add interfaces for traits - posterasure 18 clean up erased inline classes - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - jvm 26 generate JVM bytecode - ploogin 27 A sample phase that does so many things it's kind of hard... - terminal 28 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + fields 14 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 15 replace tail calls by jumps + specialize 16 @specialized-driven class and method specialization +xplicitlocaljs 17 make references to local JS classes explicit + explicitouter 18 this refs to outer pointers + erasure 19 erase types, add interfaces for traits + posterasure 20 clean up erased inline classes + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + jvm 28 generate JVM bytecode + ploogin 29 A sample phase that does so many things it's kind of hard... + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-missing.check index 56b74a3128..c12c664813 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-missing.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-missing.check @@ -12,19 +12,21 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - fields 13 synthesize accessors and fields, add bitmaps for lazy vals - tailcalls 14 replace tail calls by jumps - specialize 15 @specialized-driven class and method specialization - explicitouter 16 this refs to outer pointers - erasure 17 erase types, add interfaces for traits - posterasure 18 clean up erased inline classes - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - jvm 26 generate JVM bytecode - terminal 27 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + fields 14 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 15 replace tail calls by jumps + specialize 16 @specialized-driven class and method specialization +xplicitlocaljs 17 make references to local JS classes explicit + explicitouter 18 this refs to outer pointers + erasure 19 erase types, add interfaces for traits + posterasure 20 clean up erased inline classes + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + jvm 28 generate JVM bytecode + terminal 29 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-show-phases.check index cde255e3b1..4bfb4500df 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-show-phases.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t6446-show-phases.check @@ -11,19 +11,21 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - fields 13 synthesize accessors and fields, add bitmaps for lazy vals - tailcalls 14 replace tail calls by jumps - specialize 15 @specialized-driven class and method specialization - explicitouter 16 this refs to outer pointers - erasure 17 erase types, add interfaces for traits - posterasure 18 clean up erased inline classes - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - jvm 26 generate JVM bytecode - terminal 27 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + fields 14 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 15 replace tail calls by jumps + specialize 16 @specialized-driven class and method specialization +xplicitlocaljs 17 make references to local JS classes explicit + explicitouter 18 this refs to outer pointers + erasure 19 erase types, add interfaces for traits + posterasure 20 clean up erased inline classes + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + jvm 28 generate JVM bytecode + terminal 29 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t7494-no-options.check index d8be421e5e..5d521dc8a5 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t7494-no-options.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/neg/t7494-no-options.check @@ -12,20 +12,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - fields 13 synthesize accessors and fields, add bitmaps for lazy vals - tailcalls 14 replace tail calls by jumps - specialize 15 @specialized-driven class and method specialization - explicitouter 16 this refs to outer pointers - erasure 17 erase types, add interfaces for traits - posterasure 18 clean up erased inline classes - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - jvm 26 generate JVM bytecode - ploogin 27 A sample phase that does so many things it's kind of hard... - terminal 28 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + fields 14 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 15 replace tail calls by jumps + specialize 16 @specialized-driven class and method specialization +xplicitlocaljs 17 make references to local JS classes explicit + explicitouter 18 this refs to outer pointers + erasure 19 erase types, add interfaces for traits + posterasure 20 clean up erased inline classes + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + jvm 28 generate JVM bytecode + ploogin 29 A sample phase that does so many things it's kind of hard... + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-additional.check index b7ce23da2f..3fce708aa6 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-additional.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-additional.check @@ -11,20 +11,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - fields 13 synthesize accessors and fields, add bitmaps for lazy vals - tailcalls 14 replace tail calls by jumps - specialize 15 @specialized-driven class and method specialization - explicitouter 16 this refs to outer pointers - erasure 17 erase types, add interfaces for traits - posterasure 18 clean up erased inline classes - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - jvm 26 generate JVM bytecode - ploogin 27 A sample phase that does so many things it's kind of hard... - terminal 28 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + fields 14 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 15 replace tail calls by jumps + specialize 16 @specialized-driven class and method specialization +xplicitlocaljs 17 make references to local JS classes explicit + explicitouter 18 this refs to outer pointers + erasure 19 erase types, add interfaces for traits + posterasure 20 clean up erased inline classes + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + jvm 28 generate JVM bytecode + ploogin 29 A sample phase that does so many things it's kind of hard... + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-missing.check index 56b74a3128..c12c664813 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-missing.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-missing.check @@ -12,19 +12,21 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - fields 13 synthesize accessors and fields, add bitmaps for lazy vals - tailcalls 14 replace tail calls by jumps - specialize 15 @specialized-driven class and method specialization - explicitouter 16 this refs to outer pointers - erasure 17 erase types, add interfaces for traits - posterasure 18 clean up erased inline classes - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - jvm 26 generate JVM bytecode - terminal 27 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + fields 14 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 15 replace tail calls by jumps + specialize 16 @specialized-driven class and method specialization +xplicitlocaljs 17 make references to local JS classes explicit + explicitouter 18 this refs to outer pointers + erasure 19 erase types, add interfaces for traits + posterasure 20 clean up erased inline classes + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + jvm 28 generate JVM bytecode + terminal 29 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-show-phases.check index cde255e3b1..4bfb4500df 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-show-phases.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t6446-show-phases.check @@ -11,19 +11,21 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - fields 13 synthesize accessors and fields, add bitmaps for lazy vals - tailcalls 14 replace tail calls by jumps - specialize 15 @specialized-driven class and method specialization - explicitouter 16 this refs to outer pointers - erasure 17 erase types, add interfaces for traits - posterasure 18 clean up erased inline classes - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - jvm 26 generate JVM bytecode - terminal 27 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + fields 14 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 15 replace tail calls by jumps + specialize 16 @specialized-driven class and method specialization +xplicitlocaljs 17 make references to local JS classes explicit + explicitouter 18 this refs to outer pointers + erasure 19 erase types, add interfaces for traits + posterasure 20 clean up erased inline classes + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + jvm 28 generate JVM bytecode + terminal 29 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t7494-no-options.check index d8be421e5e..5d521dc8a5 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t7494-no-options.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/neg/t7494-no-options.check @@ -12,20 +12,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - fields 13 synthesize accessors and fields, add bitmaps for lazy vals - tailcalls 14 replace tail calls by jumps - specialize 15 @specialized-driven class and method specialization - explicitouter 16 this refs to outer pointers - erasure 17 erase types, add interfaces for traits - posterasure 18 clean up erased inline classes - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - jvm 26 generate JVM bytecode - ploogin 27 A sample phase that does so many things it's kind of hard... - terminal 28 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + fields 14 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 15 replace tail calls by jumps + specialize 16 @specialized-driven class and method specialization +xplicitlocaljs 17 make references to local JS classes explicit + explicitouter 18 this refs to outer pointers + erasure 19 erase types, add interfaces for traits + posterasure 20 clean up erased inline classes + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + jvm 28 generate JVM bytecode + ploogin 29 A sample phase that does so many things it's kind of hard... + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-additional.check index b7ce23da2f..3fce708aa6 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-additional.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-additional.check @@ -11,20 +11,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - fields 13 synthesize accessors and fields, add bitmaps for lazy vals - tailcalls 14 replace tail calls by jumps - specialize 15 @specialized-driven class and method specialization - explicitouter 16 this refs to outer pointers - erasure 17 erase types, add interfaces for traits - posterasure 18 clean up erased inline classes - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - jvm 26 generate JVM bytecode - ploogin 27 A sample phase that does so many things it's kind of hard... - terminal 28 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + fields 14 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 15 replace tail calls by jumps + specialize 16 @specialized-driven class and method specialization +xplicitlocaljs 17 make references to local JS classes explicit + explicitouter 18 this refs to outer pointers + erasure 19 erase types, add interfaces for traits + posterasure 20 clean up erased inline classes + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + jvm 28 generate JVM bytecode + ploogin 29 A sample phase that does so many things it's kind of hard... + terminal 30 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-missing.check index 56b74a3128..c12c664813 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-missing.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-missing.check @@ -12,19 +12,21 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - fields 13 synthesize accessors and fields, add bitmaps for lazy vals - tailcalls 14 replace tail calls by jumps - specialize 15 @specialized-driven class and method specialization - explicitouter 16 this refs to outer pointers - erasure 17 erase types, add interfaces for traits - posterasure 18 clean up erased inline classes - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - jvm 26 generate JVM bytecode - terminal 27 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + fields 14 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 15 replace tail calls by jumps + specialize 16 @specialized-driven class and method specialization +xplicitlocaljs 17 make references to local JS classes explicit + explicitouter 18 this refs to outer pointers + erasure 19 erase types, add interfaces for traits + posterasure 20 clean up erased inline classes + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + jvm 28 generate JVM bytecode + terminal 29 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-show-phases.check index cde255e3b1..4bfb4500df 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-show-phases.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-show-phases.check @@ -11,19 +11,21 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - fields 13 synthesize accessors and fields, add bitmaps for lazy vals - tailcalls 14 replace tail calls by jumps - specialize 15 @specialized-driven class and method specialization - explicitouter 16 this refs to outer pointers - erasure 17 erase types, add interfaces for traits - posterasure 18 clean up erased inline classes - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - jvm 26 generate JVM bytecode - terminal 27 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + fields 14 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 15 replace tail calls by jumps + specialize 16 @specialized-driven class and method specialization +xplicitlocaljs 17 make references to local JS classes explicit + explicitouter 18 this refs to outer pointers + erasure 19 erase types, add interfaces for traits + posterasure 20 clean up erased inline classes + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + jvm 28 generate JVM bytecode + terminal 29 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t7494-no-options.check index d8be421e5e..5d521dc8a5 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t7494-no-options.check +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t7494-no-options.check @@ -12,20 +12,22 @@ superaccessors 8 add super accessors in traits and nested classes extmethods 9 add extension methods for inline classes pickler 10 serialize symbol tables refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - fields 13 synthesize accessors and fields, add bitmaps for lazy vals - tailcalls 14 replace tail calls by jumps - specialize 15 @specialized-driven class and method specialization - explicitouter 16 this refs to outer pointers - erasure 17 erase types, add interfaces for traits - posterasure 18 clean up erased inline classes - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - jvm 26 generate JVM bytecode - ploogin 27 A sample phase that does so many things it's kind of hard... - terminal 28 the last phase during a compilation run +xplicitinnerjs 12 make references to inner JS classes explicit + uncurry 13 uncurry, translate function values to anonymous classes + fields 14 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 15 replace tail calls by jumps + specialize 16 @specialized-driven class and method specialization +xplicitlocaljs 17 make references to local JS classes explicit + explicitouter 18 this refs to outer pointers + erasure 19 erase types, add interfaces for traits + posterasure 20 clean up erased inline classes + lambdalift 21 move nested functions to top level + constructors 22 move field definitions into constructors + flatten 23 eliminate inner classes + mixin 24 mixin composition + jscode 25 generate JavaScript code from ASTs + cleanup 26 platform-specific cleanups, generate reflective calls + delambdafy 27 remove lambdas + jvm 28 generate JVM bytecode + ploogin 29 A sample phase that does so many things it's kind of hard... + terminal 30 the last phase during a compilation run diff --git a/project/JavaLangObject.scala b/project/JavaLangObject.scala index 74ba0c432b..17e47e7623 100644 --- a/project/JavaLangObject.scala +++ b/project/JavaLangObject.scala @@ -29,8 +29,10 @@ object JavaLangObject { Ident("O", Some("java.lang.Object")), ClassKind.Class, None, + None, Nil, None, + None, List( /* def this() = () */ MethodDef( diff --git a/test-suite/js/src/test/require-2.12/org/scalajs/testsuite/jsinterop/JSOptionalTest212.scala b/test-suite/js/src/test/require-2.12/org/scalajs/testsuite/jsinterop/JSOptionalTest212.scala index 08caa4ee40..b2cde890b1 100644 --- a/test-suite/js/src/test/require-2.12/org/scalajs/testsuite/jsinterop/JSOptionalTest212.scala +++ b/test-suite/js/src/test/require-2.12/org/scalajs/testsuite/jsinterop/JSOptionalTest212.scala @@ -138,13 +138,6 @@ class JSOptionalTest212 { } @Test def overrideClassAbstractWithOptional(): Unit = { - abstract class ClassWithAbstracts extends js.Object { - val x: js.UndefOr[Int] - def y: js.UndefOr[String] - def y2: js.UndefOr[String] - var z: js.UndefOr[Option[Int]] - } - trait OverrideClassAbstractWithOptional extends ClassWithAbstracts { val x = js.undefined def y = js.undefined @@ -243,6 +236,13 @@ object JSOptionalTest212 { z = Some(5) } + abstract class ClassWithAbstracts extends js.Object { + val x: js.UndefOr[Int] + def y: js.UndefOr[String] + def y2: js.UndefOr[String] + var z: js.UndefOr[Option[Int]] + } + trait TraitWithOptionalFunction extends js.Object { val f: js.UndefOr[js.Function1[Int, Int]] = js.undefined } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala index 73833729b6..8668a60fa2 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala @@ -182,6 +182,59 @@ class InteroperabilityTest { assertEquals(10, obj6.x) } + @Test def nestedNativeJSClasses(): Unit = { + js.eval(""" + var InteroperabilityTestContainerClass = (function(a) { + this.ContainedClass = function(x) { + this.x = x; + this.foo = function(s) { return a + s + this.x; }; + }; + this.ContainedObject = { + x: 42, + foo: function(s) { return a + s + this.x; } + }; + this.ContainedClassRenamed = function(x) { + this.x = x * 2; + this.foo = function(s) { return a + s + this.x; }; + }; + this.ContainedObjectRenamed = { + x: 4242, + foo: function(s) { return a + s + this.x; } + }; + this.ContainedClassWithDefaultParam = function(x) { + this.x = x || 42; + this.foo = function(s) { return a + s + this.x; }; + }; + }); + """) + + val enclosing = new InteroperabilityTestContainerClass("abc ") + + val obj1 = new enclosing.ContainedClass(34) + assertEquals(34, obj1.x) + assertEquals("abc def 34", obj1.foo("def ")) + + val obj2 = enclosing.ContainedObject + assertEquals(42, obj2.x) + assertEquals("abc def 42", obj2.foo("def ")) + + val obj3 = new enclosing.ContainedClassWithJSName(65) + assertEquals(130, obj3.x) + assertEquals("abc def 130", obj3.foo("def ")) + + val obj4 = enclosing.ContainedObjectWithJSName + assertEquals(4242, obj4.x) + assertEquals("abc def 4242", obj4.foo("def ")) + + val obj5 = new enclosing.ContainedClassWithDefaultParam() + assertEquals(42, obj5.x) + assertEquals("abc def 42", obj5.foo("def ")) + + val obj6 = new enclosing.ContainedClassWithDefaultParam(10) + assertEquals(10, obj6.x) + assertEquals("abc def 10", obj6.foo("def ")) + } + @Test def should_access_native_JS_classes_and_objects_nested_in_atJSNamed_JS_objects(): Unit = { js.eval(""" var InteroperabilityTestContainerObjectRenamed = { @@ -727,6 +780,42 @@ object InteroperabilityTestContainerObject extends js.Object { } } +@js.native +@JSGlobal +class InteroperabilityTestContainerClass(a: String) extends js.Object { + @js.native + class ContainedClass(_x: Int) extends js.Object { + val x: Int = js.native + def foo(s: String): String = js.native + } + + @js.native + object ContainedObject extends js.Object { + val x: Int = js.native + def foo(s: String): String = js.native + } + + @JSName("ContainedClassRenamed") + @js.native + class ContainedClassWithJSName(_x: Int) extends js.Object { + val x: Int = js.native + def foo(s: String): String = js.native + } + + @JSName("ContainedObjectRenamed") + @js.native + object ContainedObjectWithJSName extends js.Object { + val x: Int = js.native + def foo(s: String): String = js.native + } + + @js.native + class ContainedClassWithDefaultParam(_x: Int = ???) extends js.Object { + val x: Int = js.native + def foo(s: String): String = js.native + } +} + @JSGlobal("InteroperabilityTestContainerObjectRenamed") @js.native object InteroperabilityTestContainerObjectExplicitName extends js.Object { diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index 8e8e214afa..a56523a826 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -1040,6 +1040,8 @@ class ExportsTest { assertThrows(classOf[Exception], foo.doA("a")) } + private abstract class JSAbstractClass extends js.Object + @Test def should_expose_public_members_of_new_js_Object_issue_1899(): Unit = { // Test that the bug is fixed for js.Any classes. @@ -1110,8 +1112,6 @@ class ExportsTest { def checkOriginalY3() = y3 } - abstract class JSAbstractClass extends js.Object - def getJSObj3(): js.Object = new JSAbstractClass { val x1 = "x1" var y1 = "y1" @@ -1127,7 +1127,7 @@ class ExportsTest { def checkOriginalY3() = y3 } - abstract class JSTrait extends js.Object + trait JSTrait extends js.Object def getJSObj4(): js.Object = new JSTrait { val x1 = "x1" diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala index e7948a68fc..630f870772 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala @@ -158,13 +158,6 @@ class JSOptionalTest { } @Test def overrideClassAbstractWithOptional(): Unit = { - abstract class ClassWithAbstracts extends js.Object { - val x: js.UndefOr[Int] - def y: js.UndefOr[String] - def y2: js.UndefOr[String] - var z: js.UndefOr[Option[Int]] - } - trait OverrideClassAbstractWithOptional extends ClassWithAbstracts { val x: js.UndefOr[Int] = js.undefined def y: js.UndefOr[String] = js.undefined @@ -295,6 +288,13 @@ object JSOptionalTest { override def y2 = js.undefined // scalastyle:ignore } + abstract class ClassWithAbstracts extends js.Object { + val x: js.UndefOr[Int] + def y: js.UndefOr[String] + def y2: js.UndefOr[String] + var z: js.UndefOr[Option[Int]] + } + trait TraitWithOptionalFunction extends js.Object { val f: js.UndefOr[js.Function1[Int, Int]] = js.undefined } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/NestedJSClassTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/NestedJSClassTest.scala new file mode 100644 index 0000000000..8db5eeb053 --- /dev/null +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/NestedJSClassTest.scala @@ -0,0 +1,596 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.jsinterop + +import scala.scalajs.js +import scala.scalajs.js.annotation._ + +import org.junit.Assert._ +import org.junit.Test + +class NestedJSClassTest { + import NestedJSClassTest._ + + @Test def innerJSClass_basics(): Unit = { + val container1 = new ScalaClassContainer("hello") + val innerJSClass = container1.getInnerJSClass + assertSame(innerJSClass, container1.getInnerJSClass) + assertSame(innerJSClass, js.constructorOf[container1.InnerJSClass]) + assertEquals("function", js.typeOf(innerJSClass)) + + val inner1 = new container1.InnerJSClass("world1") + assertEquals("helloworld1", inner1.zzz) + assertEquals("helloworld1foo", inner1.foo("foo")) + assertTrue(inner1.isInstanceOf[container1.InnerJSClass]) + assertTrue(js.special.instanceof(inner1, innerJSClass)) + + val inner2 = js.Dynamic.newInstance(innerJSClass)("world2") + assertEquals("helloworld2", inner2.zzz) + assertEquals("helloworld2foo", inner2.foo("foo")) + assertTrue(inner2.isInstanceOf[container1.InnerJSClass]) + assertTrue(js.special.instanceof(inner2, innerJSClass)) + + val container2 = new ScalaClassContainer("hi") + val innerJSClass2 = container2.getInnerJSClass + assertNotSame(innerJSClass, innerJSClass2) + + val inner3 = new container2.InnerJSClass("world3") + assertEquals("hiworld3", inner3.zzz) + assertEquals("hiworld3foo", inner3.foo("foo")) + assertTrue(inner3.isInstanceOf[container2.InnerJSClass]) + assertTrue(js.special.instanceof(inner3, container2.getInnerJSClass)) + + assertFalse(inner3.isInstanceOf[container1.InnerJSClass]) + assertFalse(js.special.instanceof(inner3, innerJSClass)) + } + + @Test def localJSClass_basics(): Unit = { + val container1 = new ScalaClassContainer("hello") + val localJSClass1 = container1.makeLocalJSClass("wide1") + assertEquals("function", js.typeOf(localJSClass1)) + + val inner1 = js.Dynamic.newInstance(localJSClass1)("world1") + assertEquals("hellowide1world1", inner1.zzz) + assertEquals("hellowide1world1foo", inner1.foo("foo")) + assertTrue(js.special.instanceof(inner1, localJSClass1)) + assertFalse(inner1.isInstanceOf[container1.InnerJSClass]) + + val inner2 = js.Dynamic.newInstance(localJSClass1)("world2") + assertEquals("hellowide1world2", inner2.zzz) + assertEquals("hellowide1world2foo", inner2.foo("foo")) + + val localJSClass2 = container1.makeLocalJSClass("wide2") + assertNotSame(localJSClass1, localJSClass2) + + val inner3 = js.Dynamic.newInstance(localJSClass2)("world3") + assertEquals("hellowide2world3", inner3.zzz) + assertEquals("hellowide2world3foo", inner3.foo("foo")) + assertTrue(js.special.instanceof(inner3, localJSClass2)) + assertFalse(js.special.instanceof(inner3, localJSClass1)) + assertFalse(inner3.isInstanceOf[container1.InnerJSClass]) + } + + @Test def innerJSClass_basicsInsideTrait(): Unit = { + val container1 = new ScalaTraitContainerSubclass("hello") + val innerJSClass = container1.getInnerJSClass + assertSame(innerJSClass, container1.getInnerJSClass) + assertSame(innerJSClass, js.constructorOf[container1.InnerJSClass]) + assertEquals("function", js.typeOf(innerJSClass)) + + val inner1 = new container1.InnerJSClass("world1") + assertEquals("helloworld1", inner1.zzz) + assertEquals("helloworld1foo", inner1.foo("foo")) + assertTrue(inner1.isInstanceOf[container1.InnerJSClass]) + assertTrue(js.special.instanceof(inner1, innerJSClass)) + + val inner2 = js.Dynamic.newInstance(innerJSClass)("world2") + assertEquals("helloworld2", inner2.zzz) + assertEquals("helloworld2foo", inner2.foo("foo")) + assertTrue(inner2.isInstanceOf[container1.InnerJSClass]) + assertTrue(js.special.instanceof(inner2, innerJSClass)) + + val container2 = new ScalaTraitContainerSubclass("hi") + val innerJSClass2 = container2.getInnerJSClass + assertNotSame(innerJSClass, innerJSClass2) + + val inner3 = new container2.InnerJSClass("world3") + assertEquals("hiworld3", inner3.zzz) + assertEquals("hiworld3foo", inner3.foo("foo")) + assertTrue(inner3.isInstanceOf[container2.InnerJSClass]) + assertTrue(js.special.instanceof(inner3, container2.getInnerJSClass)) + + assertFalse(inner3.isInstanceOf[container1.InnerJSClass]) + assertFalse(js.special.instanceof(inner3, innerJSClass)) + } + + @Test def localJSClass_basicsInsideTrait(): Unit = { + val container1 = new ScalaTraitContainerSubclass("hello") + val localJSClass1 = container1.makeLocalJSClass("wide1") + assertEquals("function", js.typeOf(localJSClass1)) + + val inner1 = js.Dynamic.newInstance(localJSClass1)("world1") + assertEquals("hellowide1world1", inner1.zzz) + assertEquals("hellowide1world1foo", inner1.foo("foo")) + assertTrue(js.special.instanceof(inner1, localJSClass1)) + assertFalse(inner1.isInstanceOf[container1.InnerJSClass]) + + val inner2 = js.Dynamic.newInstance(localJSClass1)("world2") + assertEquals("hellowide1world2", inner2.zzz) + assertEquals("hellowide1world2foo", inner2.foo("foo")) + + val localJSClass2 = container1.makeLocalJSClass("wide2") + assertNotSame(localJSClass1, localJSClass2) + + val inner3 = js.Dynamic.newInstance(localJSClass2)("world3") + assertEquals("hellowide2world3", inner3.zzz) + assertEquals("hellowide2world3foo", inner3.foo("foo")) + assertTrue(js.special.instanceof(inner3, localJSClass2)) + assertFalse(js.special.instanceof(inner3, localJSClass1)) + assertFalse(inner3.isInstanceOf[container1.InnerJSClass]) + } + + @Test def innerJSObject_basics(): Unit = { + val container1 = new ScalaClassContainerWithObject("hello") + val inner1 = container1.InnerJSObject + assertSame(inner1, container1.InnerJSObject) + assertEquals("object", js.typeOf(inner1)) + + assertEquals("hellozzz", inner1.zzz) + assertEquals("hellozzzfoo", inner1.foo("foo")) + assertTrue(inner1.isInstanceOf[container1.InnerJSObject.type]) + + val container2 = new ScalaClassContainerWithObject("hi") + val inner2 = container2.InnerJSObject + assertNotSame(inner1, inner2) + assertNotSame(inner1.asInstanceOf[js.Dynamic].constructor, + inner2.asInstanceOf[js.Dynamic].constructor) + assertEquals("hizzz", inner2.zzz) + assertEquals("hizzzfoo", inner2.foo("foo")) + + assertFalse(inner2.isInstanceOf[container1.InnerJSObject.type]) + } + + @Test def localJSObject_basics(): Unit = { + val container1 = new ScalaClassContainerWithObject("hello") + val inner1 = container1.makeLocalJSObject("world1") + + assertEquals("helloworld1", inner1.zzz) + assertEquals("helloworld1foo", inner1.foo("foo")) + + val inner2 = container1.makeLocalJSObject("world2") + assertEquals("helloworld2", inner2.zzz) + assertEquals("helloworld2foo", inner2.foo("foo")) + + assertNotSame(inner1, inner2) + assertNotSame(inner1.asInstanceOf[js.Dynamic].constructor, + inner2.asInstanceOf[js.Dynamic].constructor) + } + + @Test def innerJSClassExtendsInnerJSClass(): Unit = { + val parentsContainer = new ScalaClassContainer("hello") + val container1 = + new ScalaClassContainerWithSubclasses("hi", parentsContainer) + val innerJSClass = parentsContainer.getInnerJSClass + val innerJSSubclass = container1.getInnerJSSubclass + + val inner1 = new container1.InnerJSSubclass("world1") + assertEquals("helloworld1", inner1.zzz) + assertEquals("helloworld1foo", inner1.foo("foo")) + assertEquals("hiworld1helloworld1", inner1.foobar()) + + assertTrue(inner1.isInstanceOf[container1.InnerJSSubclass]) + assertTrue(js.special.instanceof(inner1, innerJSSubclass)) + assertTrue(inner1.isInstanceOf[parentsContainer.InnerJSClass]) + assertTrue(js.special.instanceof(inner1, innerJSClass)) + + val container2 = + new ScalaClassContainerWithSubclasses("salut", parentsContainer) + val innerJSSubclass2 = container2.getInnerJSSubclass + + val inner2 = js.Dynamic.newInstance(innerJSSubclass2)("world2") + assertEquals("helloworld2", inner2.zzz) + assertEquals("helloworld2foo", inner2.foo("foo")) + assertEquals("salutworld2helloworld2", inner2.foobar()) + + assertTrue((inner2: Any).isInstanceOf[container2.InnerJSSubclass]) + assertFalse((inner2: Any).isInstanceOf[container1.InnerJSSubclass]) + assertTrue(js.special.instanceof(inner2, innerJSClass)) + + val otherParentsContainer = new ScalaClassContainer("other") + assertFalse(inner1.isInstanceOf[otherParentsContainer.InnerJSClass]) + assertFalse(inner2.isInstanceOf[otherParentsContainer.InnerJSClass]) + } + + @Test def localJSClassExtendsInnerJSClass(): Unit = { + val parentsContainer = new ScalaClassContainer("hello") + val container1 = + new ScalaClassContainerWithSubclasses("hi", parentsContainer) + + val localJSClass1 = container1.makeLocalJSSubclass("wide1") + assertEquals("function", js.typeOf(localJSClass1)) + + val inner1 = js.Dynamic.newInstance(localJSClass1)("world1") + assertEquals("helloworld1", inner1.zzz) + assertEquals("helloworld1foo", inner1.foo("foo")) + assertEquals("hiwide1helloworld1", inner1.foobar()) + assertTrue(js.special.instanceof(inner1, localJSClass1)) + assertTrue(inner1.isInstanceOf[parentsContainer.InnerJSClass]) + assertFalse(inner1.isInstanceOf[container1.InnerJSSubclass]) + + val inner2 = js.Dynamic.newInstance(localJSClass1)("world2") + assertEquals("helloworld2", inner2.zzz) + assertEquals("helloworld2foo", inner2.foo("foo")) + assertEquals("hiwide1helloworld2", inner2.foobar()) + + val localJSClass2 = container1.makeLocalJSSubclass("wide2") + assertNotSame(localJSClass1, localJSClass2) + + val inner3 = js.Dynamic.newInstance(localJSClass2)("world3") + assertEquals("helloworld3", inner3.zzz) + assertEquals("helloworld3foo", inner3.foo("foo")) + assertEquals("hiwide2helloworld3", inner3.foobar()) + assertTrue(js.special.instanceof(inner3, localJSClass2)) + assertTrue(inner3.isInstanceOf[parentsContainer.InnerJSClass]) + assertFalse(js.special.instanceof(inner3, localJSClass1)) + assertFalse(inner3.isInstanceOf[container1.InnerJSSubclass]) + + val otherParentsContainer = new ScalaClassContainer("other") + assertFalse(inner1.isInstanceOf[otherParentsContainer.InnerJSClass]) + assertFalse(inner2.isInstanceOf[otherParentsContainer.InnerJSClass]) + assertFalse(inner3.isInstanceOf[otherParentsContainer.InnerJSClass]) + } + + @Test def innerJSObjectExtendsInnerJSClass(): Unit = { + val parentsContainer = new ScalaClassContainer("hello") + val container1 = new ScalaClassContainerWithSubObjects("hi", + parentsContainer) + val inner1 = container1.InnerJSObject + assertSame(inner1, container1.InnerJSObject) + assertEquals("object", js.typeOf(inner1)) + + assertEquals("hellohi", inner1.zzz) + assertEquals("hellohifoo", inner1.foo("foo")) + assertEquals("hihellohi", inner1.foobar()) + assertTrue(inner1.isInstanceOf[container1.InnerJSObject.type]) + assertTrue(inner1.isInstanceOf[parentsContainer.InnerJSClass]) + + val container2 = new ScalaClassContainerWithSubObjects("hi2", + parentsContainer) + val inner2 = container2.InnerJSObject + assertNotSame(inner1, inner2) + assertNotSame(inner1.asInstanceOf[js.Dynamic].constructor, + inner2.asInstanceOf[js.Dynamic].constructor) + assertEquals("hellohi2", inner2.zzz) + assertEquals("hellohi2foo", inner2.foo("foo")) + assertEquals("hi2hellohi2", inner2.foobar()) + + assertFalse(inner2.isInstanceOf[container1.InnerJSObject.type]) + + val otherParentsContainer = new ScalaClassContainer("other") + assertFalse(inner1.isInstanceOf[otherParentsContainer.InnerJSClass]) + assertFalse(inner2.isInstanceOf[otherParentsContainer.InnerJSClass]) + } + + @Test def localJSObjectExtendsInnerJSClass(): Unit = { + val parentsContainer = new ScalaClassContainer("hello") + val container1 = new ScalaClassContainerWithSubObjects("hi", + parentsContainer) + + val inner1 = container1.makeLocalJSObject("world1") + assertEquals("helloworld1", inner1.zzz) + assertEquals("helloworld1foo", inner1.foo("foo")) + assertEquals("hiworld1helloworld1", inner1.foobar()) + assertTrue(inner1.isInstanceOf[parentsContainer.InnerJSClass]) + + val inner2 = container1.makeLocalJSObject("world2") + assertEquals("helloworld2", inner2.zzz) + assertEquals("helloworld2foo", inner2.foo("foo")) + assertEquals("hiworld2helloworld2", inner2.foobar()) + assertTrue(inner2.isInstanceOf[parentsContainer.InnerJSClass]) + + assertNotSame(inner1, inner2) + assertNotSame(inner1.asInstanceOf[js.Dynamic].constructor, + inner2.asInstanceOf[js.Dynamic].constructor) + + val otherParentsContainer = new ScalaClassContainer("other") + assertFalse(inner1.isInstanceOf[otherParentsContainer.InnerJSClass]) + assertFalse(inner2.isInstanceOf[otherParentsContainer.InnerJSClass]) + } + + @Test def convolutedGenericTypeParametersInSuperClass(): Unit = { + val parentsContainer = new GenericJSSuperClassContainer + val container1 = new ScalaClassContainerWithTypeParameters[Int](5, + parentsContainer) + + type MyB = List[List[Int]] + + val innerJSClass = js.constructorOf[container1.GenericJSInnerClass[MyB]] + assertSame(innerJSClass, + js.constructorOf[container1.GenericJSInnerClass[MyB]]) + assertEquals("function", js.typeOf(innerJSClass)) + val inner: Any = new container1.GenericJSInnerClass[MyB](Nil) + assertTrue(inner.isInstanceOf[parentsContainer.GenericJSSuperClass[_, _]]) + + val localJSClass = container1.makeGenericJSLocalClass() + assertNotSame(localJSClass, container1.makeGenericJSLocalClass()) + assertEquals("function", js.typeOf(localJSClass)) + val local: Any = js.Dynamic.newInstance(localJSClass)(Nil.asInstanceOf[js.Any]) + assertTrue(local.isInstanceOf[parentsContainer.GenericJSSuperClass[_, _]]) + + val innerJSObject = container1.GenericJSInnerObject + assertSame(innerJSObject, container1.GenericJSInnerObject) + assertTrue(innerJSObject.isInstanceOf[parentsContainer.GenericJSSuperClass[_, _]]) + + val localJSObject = container1.makeGenericJSInnerObject(Nil) + assertNotSame(localJSObject, container1.makeGenericJSInnerObject(Nil)) + assertTrue(localJSObject.isInstanceOf[parentsContainer.GenericJSSuperClass[_, _]]) + } + + @Test def innerJSClass_basicsInsideJSClass(): Unit = { + val container1 = new JSClassContainer("hello") + val innerJSClass = container1.getInnerJSClass + assertSame(innerJSClass, container1.getInnerJSClass) + assertSame(innerJSClass, js.constructorOf[container1.InnerJSClass]) + assertEquals("function", js.typeOf(innerJSClass)) + + val inner1 = new container1.InnerJSClass("world1") + assertEquals("helloworld1", inner1.zzz) + assertEquals("helloworld1foo", inner1.foo("foo")) + assertTrue(inner1.isInstanceOf[container1.InnerJSClass]) + assertTrue(js.special.instanceof(inner1, innerJSClass)) + + val inner2 = js.Dynamic.newInstance(innerJSClass)("world2") + assertEquals("helloworld2", inner2.zzz) + assertEquals("helloworld2foo", inner2.foo("foo")) + assertTrue(inner2.isInstanceOf[container1.InnerJSClass]) + assertTrue(js.special.instanceof(inner2, innerJSClass)) + + val container2 = new JSClassContainer("hi") + val innerJSClass2 = container2.getInnerJSClass + assertNotSame(innerJSClass, innerJSClass2) + + val inner3 = new container2.InnerJSClass("world3") + assertEquals("hiworld3", inner3.zzz) + assertEquals("hiworld3foo", inner3.foo("foo")) + assertTrue(inner3.isInstanceOf[container2.InnerJSClass]) + assertTrue(js.special.instanceof(inner3, container2.getInnerJSClass)) + + assertFalse(inner3.isInstanceOf[container1.InnerJSClass]) + assertFalse(js.special.instanceof(inner3, innerJSClass)) + } + + @Test def innerJSClass_accessibleFromJS_ifInsideJSClass(): Unit = { + val container1 = new JSClassContainer("hello") + val innerJSClass = container1.asInstanceOf[js.Dynamic].getInnerJSClass + assertSame(innerJSClass, container1.getInnerJSClass) + assertSame(innerJSClass, js.constructorOf[container1.InnerJSClass]) + assertEquals("function", js.typeOf(innerJSClass)) + + val inner2 = js.Dynamic.newInstance(innerJSClass)("world2") + assertEquals("helloworld2", inner2.zzz) + assertEquals("helloworld2foo", inner2.foo("foo")) + assertTrue(inner2.isInstanceOf[container1.InnerJSClass]) + assertTrue(js.special.instanceof(inner2, innerJSClass)) + + val container2 = new JSClassContainer("hi") + val innerJSClass2 = container2.asInstanceOf[js.Dynamic].getInnerJSClass + assertNotSame(innerJSClass, innerJSClass2) + + val inner3 = js.Dynamic.newInstance(innerJSClass2)("world3") + assertEquals("hiworld3", inner3.zzz) + assertEquals("hiworld3foo", inner3.foo("foo")) + assertTrue(inner3.isInstanceOf[container2.InnerJSClass]) + assertTrue(js.special.instanceof(inner3, container2.getInnerJSClass)) + + assertFalse(inner3.isInstanceOf[container1.InnerJSClass]) + assertFalse(js.special.instanceof(inner3, innerJSClass)) + } + + @Test def localJSClassCapturesCharThatMustBeBoxed(): Unit = { + @inline def makeChar(): Any = 'A' + + val char = makeChar() + + class LocalJSClassWithCharCapture extends js.Object { + def getCharAny(): Any = char + def getCharAsChar(): Char = char.asInstanceOf[Char] + } + + val obj = new LocalJSClassWithCharCapture + val charAny = obj.getCharAny() + assertTrue(charAny.toString(), charAny.isInstanceOf[Char]) + assertEquals('A', charAny) + assertEquals("A", charAny.toString()) + assertEquals('A', obj.getCharAsChar()) + } + + @Test def overloadedConstructorsInLocalJSClass(): Unit = { + val a = 5 + val b = 10 + + class LocalJSClassWithOverloadedConstructors(val x: Int) extends js.Object { + val aa = a + + def this(x: Int, y: Int) = { + this(x + y + b) + } + } + + val obj1 = new LocalJSClassWithOverloadedConstructors(50) + assertEquals(50, obj1.x) + assertEquals(5, obj1.aa) + + val obj2 = new LocalJSClassWithOverloadedConstructors(34, 78) + assertEquals(34 + 78 + 10, obj2.x) + assertEquals(5, obj2.aa) + } + + @Test def selfReferencingLocalJSClass(): Unit = { + class JSCons[+A](val head: A, val tail: JSCons[A]) extends js.Object { + def ::[B >: A](x: B): JSCons[B] = + new JSCons[B](x, this) + + def self: js.Dynamic = js.constructorOf[JSCons[_]] + } + + val threeAndNil = new JSCons(3, null) + val list = "head" :: 2 :: threeAndNil + + assertEquals(js.constructorOf[JSCons[_]], list.self) + assertEquals("head", list.head) + assertEquals(2, list.tail.head) + assertEquals(3, list.tail.tail.head) + assertNull(list.tail.tail.tail) + } + +} + +object NestedJSClassTest { + trait TestInterface extends js.Object { + val zzz: String + + def foo(a: String): String + } + + class ScalaClassContainer(xxx: String) { + class InnerJSClass(yyy: String) extends js.Object with TestInterface { + val zzz: String = xxx + yyy + + def foo(a: String): String = xxx + yyy + a + } + + def getInnerJSClass: js.Dynamic = + js.constructorOf[InnerJSClass] + + def makeLocalJSClass(yyy: String): js.Dynamic = { + class LocalJSClass(abc: String) extends js.Object with TestInterface { + val zzz: String = xxx + yyy + abc + + def foo(a: String): String = xxx + yyy + abc + a + } + + js.constructorOf[LocalJSClass] + } + } + + trait ScalaTraitContainer { + def xxx: String + + class InnerJSClass(yyy: String) extends js.Object with TestInterface { + val zzz: String = xxx + yyy + + def foo(a: String): String = xxx + yyy + a + } + + def getInnerJSClass: js.Dynamic = + js.constructorOf[InnerJSClass] + + def makeLocalJSClass(yyy: String): js.Dynamic = { + class LocalJSClass(abc: String) extends js.Object with TestInterface { + val zzz: String = xxx + yyy + abc + + def foo(a: String): String = xxx + yyy + abc + a + } + + js.constructorOf[LocalJSClass] + } + } + + class ScalaTraitContainerSubclass(val xxx: String) extends ScalaTraitContainer + + class ScalaClassContainerWithObject(xxx: String) { + object InnerJSObject extends js.Object with TestInterface { + val zzz: String = xxx + "zzz" + + def foo(a: String): String = xxx + "zzz" + a + } + + def makeLocalJSObject(yyy: String): TestInterface = { + object LocalJSObject extends js.Object with TestInterface { + val zzz: String = xxx + yyy + + def foo(a: String): String = xxx + yyy + a + } + + LocalJSObject + } + } + + class ScalaClassContainerWithSubclasses(val abc: String, + val parents: ScalaClassContainer) { + + class InnerJSSubclass(yyy: String) extends parents.InnerJSClass(yyy) { + def foobar(): String = abc + yyy + zzz + } + + def getInnerJSSubclass: js.Dynamic = + js.constructorOf[InnerJSSubclass] + + def makeLocalJSSubclass(yyy: String): js.Dynamic = { + class LocalJSSubclass(xyz: String) extends parents.InnerJSClass(xyz) { + def foobar(): String = abc + yyy + zzz + } + js.constructorOf[LocalJSSubclass] + } + } + + class ScalaClassContainerWithSubObjects(val abc: String, + val parents: ScalaClassContainer) { + + object InnerJSObject extends parents.InnerJSClass(abc) { + def foobar(): String = abc + zzz + } + + def makeLocalJSObject(yyy: String): js.Dynamic = { + object LocalJSObject extends parents.InnerJSClass(yyy) { + def foobar(): String = abc + yyy + zzz + } + LocalJSObject.asInstanceOf[js.Dynamic] + } + } + + class GenericJSSuperClassContainer { + class GenericJSSuperClass[A, B <: List[Seq[A]]](val a: A, val b: B) + extends js.Object + } + + class ScalaClassContainerWithTypeParameters[A](val a: A, + val parents: GenericJSSuperClassContainer) { + + class GenericJSInnerClass[B <: List[Seq[A]]](b: B) + extends parents.GenericJSSuperClass[A, B](a, b) + + def makeGenericJSLocalClass(): js.Dynamic = { + class GenericJSLocalClass[B <: List[Seq[A]]](b: B) + extends parents.GenericJSSuperClass[A, B](a, b) + js.constructorOf[GenericJSLocalClass[_]] + } + + object GenericJSInnerObject + extends parents.GenericJSSuperClass[A, List[List[A]]](a, Nil) + + def makeGenericJSInnerObject[B <: List[Seq[A]]](b: B): js.Dynamic = { + object GenericJSInnerObject + extends parents.GenericJSSuperClass[A, B](a, b) + + GenericJSInnerObject.asInstanceOf[js.Dynamic] + } + } + + class JSClassContainer(xxx: String) extends js.Object { + class InnerJSClass(yyy: String) extends js.Object with TestInterface { + val zzz: String = xxx + yyy + + def foo(a: String): String = xxx + yyy + a + } + + def getInnerJSClass: js.Dynamic = + js.constructorOf[InnerJSClass] + } + +} diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/NonNativeJSTypeTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/NonNativeJSTypeTest.scala index e713cf2453..5804627ecf 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/NonNativeJSTypeTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/NonNativeJSTypeTest.scala @@ -1373,6 +1373,23 @@ class NonNativeJSTypeTest { assertEquals(18, foo.bar) } + @Test def add_overload_in_subclass(): Unit = { + class AddOverloadInSubclassParent extends js.Object { + def bar(): Int = 53 + } + class AddOverloadInSubclassChild extends AddOverloadInSubclassParent { + def bar(x: Int): Int = x + 2 + } + + val foo = new AddOverloadInSubclassChild + assertEquals(53, foo.bar()) + assertEquals(7, foo.bar(5)) + + val dyn = foo.asInstanceOf[js.Dynamic] + assertEquals(53, dyn.bar()) + assertEquals(7, dyn.bar(5)) + } + @Test def add_setter_in_subclass(): Unit = { class AddSetterInSubclassParent extends js.Object { var x: Int = 43 diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala index 5db371cfe4..d028674acf 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala @@ -36,8 +36,10 @@ final class LinkedClass( // Stuff from Tree val name: Ident, val kind: ClassKind, + val jsClassCaptures: Option[List[ParamDef]], val superClass: Option[Ident], val interfaces: List[Ident], + val jsSuperClass: Option[Tree], val jsNativeLoadSpec: Option[JSNativeLoadSpec], val fields: List[FieldDef], val staticMethods: List[Versioned[MethodDef]], @@ -69,8 +71,10 @@ final class LinkedClass( def copy( name: Ident = this.name, kind: ClassKind = this.kind, + jsClassCaptures: Option[List[ParamDef]] = this.jsClassCaptures, superClass: Option[Ident] = this.superClass, interfaces: List[Ident] = this.interfaces, + jsSuperClass: Option[Tree] = this.jsSuperClass, jsNativeLoadSpec: Option[JSNativeLoadSpec] = this.jsNativeLoadSpec, fields: List[FieldDef] = this.fields, staticMethods: List[Versioned[MethodDef]] = this.staticMethods, @@ -88,8 +92,10 @@ final class LinkedClass( new LinkedClass( name, kind, + jsClassCaptures, superClass, interfaces, + jsSuperClass, jsNativeLoadSpec, fields, staticMethods, diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala index 0642f076da..429e9f7b6e 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala @@ -469,6 +469,9 @@ object Infos { case LoadJSModule(ClassType(cls)) => builder.addAccessedModule(cls) + case CreateJSClass(cls, _) => + builder.addInstantiatedClass(cls.className) + case _ => } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index 07e6d39b8b..f5a87c4a70 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -70,40 +70,71 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { } if (!tree.kind.isJSClass) { + assert(tree.jsSuperClass.isEmpty, className) entireClassDefWithGlobals } else { // Wrap the entire class def in an accessor function import TreeDSL._ implicit val pos = tree.pos - val createClassValueVar = - envFieldDef("b", className, js.Undefined(), mutable = true) + val genStoreJSSuperClass = tree.jsSuperClass.map { jsSuperClass => + for (rhs <- desugarExpr(jsSuperClass, resultType = AnyType)) yield { + js.VarDef(envField("superClass").ident, Some(rhs)) + } + } for { + optStoreJSSuperClass <- WithGlobals.option(genStoreJSSuperClass) entireClassDef <- entireClassDefWithGlobals createStaticFields <- genCreateStaticFieldsOfJSClass(tree) } yield { - val createAccessor = { - val classValueVar = envField("b", className) + tree.jsClassCaptures.fold { + val createClassValueVar = + envFieldDef("b", className, js.Undefined(), mutable = true) + + val createAccessor = { + val classValueVar = envField("b", className) + + val body = js.Block( + js.If(!classValueVar, { + js.Block( + optStoreJSSuperClass.toList ::: + entireClassDef :: + createStaticFields ::: + (classValueVar := envField("c", className)) :: + genStaticInitialization(tree) + ) + }, { + js.Skip() + }), + js.Return(classValueVar) + ) + + envFieldDef("a", className, js.Function(Nil, body)) + } + + js.Block(createClassValueVar, createAccessor) + } { jsClassCaptures => + val captureParamDefs = for (param <- jsClassCaptures) yield { + implicit val pos = param.pos + val ident = + envFieldIdent("cc", param.name.name, param.name.originalName) + js.ParamDef(ident, rest = false) + } + + assert(!hasStaticInitializer(tree), + s"Found a static initializer in the non-top-level class $className") val body = js.Block( - js.If(!classValueVar, { - js.Block( - entireClassDef :: - createStaticFields ::: - (classValueVar := envField("c", className)) :: - genStaticInitialization(tree) - ) - }, { - js.Skip() - }), - js.Return(classValueVar) + optStoreJSSuperClass.toList ::: + entireClassDef :: + createStaticFields ::: + js.Return(envField("c", className)) :: + Nil ) - envFieldDef("a", className, js.Function(Nil, body)) + envFieldDef("a", className, js.Function(captureParamDefs, body)) } - - js.Block(createClassValueVar, createAccessor) } } } @@ -123,6 +154,8 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { implicit val pos = parentIdent.pos if (!tree.kind.isJSClass) { WithGlobals(encodeClassVar(parentIdent.name)) + } else if (tree.jsSuperClass.isDefined) { + WithGlobals(envField("superClass")) } else { genRawJSClassConstructor(parentIdent.name, keepOnlyDangerousVarNames = true) @@ -199,8 +232,12 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val (inheritedCtorDefWithGlobals, inheritedCtorRef) = if (!isJSClass) { (WithGlobals(js.Skip()), envField("h", parentIdent.name)) } else { - val superCtor = genRawJSClassConstructor(parentIdent.name, - keepOnlyDangerousVarNames = true) + val superCtor = if (tree.jsSuperClass.isDefined) { + WithGlobals(envField("superClass")) + } else { + genRawJSClassConstructor(parentIdent.name, + keepOnlyDangerousVarNames = true) + } (superCtor.map(makeInheritableCtorDef(_)), envField("h", className)) } @@ -390,11 +427,11 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { WithGlobals.list(statsWithGlobals) } - /** Generates the static initializer invocation of a JavaScript class. */ + /** Generates the static initializer invocation of a class. */ def genStaticInitialization(tree: LinkedClass): List[js.Tree] = { import Definitions.StaticInitializerName implicit val pos = tree.pos - if (tree.staticMethods.exists(_.value.encodedName == StaticInitializerName)) { + if (hasStaticInitializer(tree)) { val fullName = tree.encodedName + "__" + StaticInitializerName js.Apply(envField("s", fullName, Some("")), Nil) :: Nil } else { @@ -402,6 +439,11 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { } } + private def hasStaticInitializer(tree: LinkedClass): Boolean = { + import Definitions.StaticInitializerName + tree.staticMethods.exists(_.value.encodedName == StaticInitializerName) + } + /** Generates a method. */ def genMethod(className: String, method: MethodDef)( implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { @@ -621,18 +663,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { case ComputedName(tree, _) => implicit val pos = name.pos - for { - fun <- desugarToFunction(params = Nil, body = tree, resultType = AnyType) - } yield { - val nameTree = fun match { - case js.Function(Nil, js.Return(expr)) => - // no need for an IIFE, we can just use `expr` directly - expr - case _ => - js.Apply(fun, Nil) - } - js.ComputedName(nameTree) - } + desugarExpr(tree, resultType = AnyType).map(js.ComputedName(_)) } } diff --git 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 index 40479cae5e..3258071ada 100644 --- 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 @@ -227,6 +227,21 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { isStat = resultType == NoType, Env.empty(resultType)) } + /** Desugars a class-level expression. */ + def desugarExpr(expr: Tree, resultType: Type)( + implicit globalKnowledge: GlobalKnowledge, + pos: Position): WithGlobals[js.Tree] = { + for (fun <- desugarToFunction(Nil, expr, resultType)) yield { + fun match { + case js.Function(Nil, js.Return(newExpr)) => + // no need for an IIFE, we can just use `newExpr` directly + newExpr + case _ => + js.Apply(fun, Nil) + } + } + } + private class JSDesugar()(implicit globalKnowledge: GlobalKnowledge) { // Name management @@ -625,8 +640,15 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { val superCtorCall = { outputMode match { case OutputMode.ECMAScript51Isolated => - val superCtor = extractWithGlobals(genRawJSClassConstructor( - globalKnowledge.getSuperClassOfJSClass(enclosingClassName))) + val superCtor = { + if (globalKnowledge.hasStoredSuperClass(enclosingClassName)) { + envField("superClass") + } else { + val superClass = + globalKnowledge.getSuperClassOfJSClass(enclosingClassName) + extractWithGlobals(genRawJSClassConstructor(superClass)) + } + } if (containsAnySpread(newArgs)) { val argArray = spreadToArgArray(newArgs) @@ -1164,6 +1186,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { allowSideEffects case JSGlobalRef(_) => allowSideEffects + case CreateJSClass(_, captureValues) => + allowSideEffects && captureValues.forall(test) /* LoadJSConstructor is pure only for non-native JS classes, * which do not have a native load spec. Note that this test makes @@ -1725,6 +1749,11 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { redo(Closure(captureParams, params, body, newCaptureValues))(env) } + case CreateJSClass(cls, captureValues) => + unnest(captureValues) { (newCaptureValues, env) => + redo(CreateJSClass(cls, newCaptureValues))(env) + } + case _ => if (lhs == Lhs.Discard) { /* Go "back" to transformStat() after having dived into @@ -2349,8 +2378,10 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { // Atomic expressions case VarRef(name) => - assert(env.isLocalVar(name), name.name) - js.VarRef(transformLocalVarIdent(name)) + if (env.isLocalVar(name)) + js.VarRef(transformLocalVarIdent(name)) + else + envField("cc", name.name, name.originalName) case This() => env.thisIdent.fold[js.Tree] { @@ -2376,6 +2407,18 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { }) } + case CreateJSClass(cls, captureValues) => + val transformedArgs = if (captureValues.forall(_.tpe != CharType)) { + // Fast path + captureValues.map(transformExpr(_, preserveChar = true)) + } else { + val expectedTypes = + globalKnowledge.getJSClassCaptureTypes(cls.className).get + for ((value, expectedType) <- captureValues.zip(expectedTypes)) + yield transformExpr(value, expectedType) + } + js.Apply(envField("a", cls.className), transformedArgs) + // Invalid trees case _ => @@ -2539,7 +2582,12 @@ private object FunctionEmitter { ) { def isLocalVar(ident: Ident): Boolean = vars.contains(ident.name) - def isLocalMutable(ident: Ident): Boolean = vars(ident.name) + def isLocalMutable(ident: Ident): Boolean = { + /* If we do not know the var, it must be a JS class capture, which must + * be immutable. + */ + vars.getOrElse(ident.name, false) + } def lhsForLabeledExpr(label: Ident): Lhs = labeledExprLHSes(label.name) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala index a0133456c8..d364a09450 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala @@ -10,6 +10,7 @@ package org.scalajs.core.tools.linker.backend.emitter import org.scalajs.core.ir.Trees.{FieldDef, JSNativeLoadSpec} +import org.scalajs.core.ir.Types.Type private[emitter] trait GlobalKnowledge { /** Tests whether the parent class data is accessed in the linking unit. */ @@ -39,11 +40,17 @@ private[emitter] trait GlobalKnowledge { */ def hasInlineableInit(className: String): Boolean + /** Tests whether the specified class locally stores its super class. */ + def hasStoredSuperClass(className: String): Boolean + + /** Gets the types of the `jsClassCaptures` of the given class. */ + def getJSClassCaptureTypes(className: String): Option[List[Type]] + /** `None` for non-native JS classes/objects; `Some(spec)` for native JS * classes/objects. * * It is invalid to call this method with a class that is not a JS class - * or object (native or not). + * or object (native or not), or one that has JS class captures. */ def getJSNativeLoadSpec(className: String): Option[JSNativeLoadSpec] diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala index c5b6a5627e..df3cc1b487 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala @@ -286,8 +286,13 @@ private[emitter] final class JSGen(val semantics: Semantics, def envField(field: String, subField: String, origName: Option[String] = None)( implicit pos: Position): VarRef = { - VarRef(Ident(avoidClashWithGlobalRef("$" + field + "_" + subField), - origName)) + VarRef(envFieldIdent(field, subField, origName)) + } + + def envFieldIdent(field: String, subField: String, + origName: Option[String] = None)( + implicit pos: Position): Ident = { + Ident(avoidClashWithGlobalRef("$" + field + "_" + subField), origName) } def envField(field: String)(implicit pos: Position): VarRef = diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala index eec3c38004..ec459b04ef 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala @@ -13,6 +13,7 @@ import scala.collection.mutable import org.scalajs.core.ir.{ClassKind, Definitions} import org.scalajs.core.ir.Trees._ +import org.scalajs.core.ir.Types.Type import org.scalajs.core.tools.linker._ @@ -147,6 +148,12 @@ private[emitter] final class KnowledgeGuardian { def hasInlineableInit(className: String): Boolean = classes(className).askHasInlineableInit(this) + def hasStoredSuperClass(className: String): Boolean = + classes(className).askHasStoredSuperClass(this) + + def getJSClassCaptureTypes(className: String): Option[List[Type]] = + classes(className).askJSClassCaptureTypes(this) + def getJSNativeLoadSpec(className: String): Option[JSNativeLoadSpec] = classes(className).askJSNativeLoadSpec(this) @@ -165,12 +172,16 @@ private[emitter] final class KnowledgeGuardian { private var isInterface = computeIsInterface(initClass) private var hasInlineableInit = initHasInlineableInit + private var hasStoredSuperClass = computeHasStoredSuperClass(initClass) + private var jsClassCaptureTypes = computeJSClassCaptureTypes(initClass) private var jsNativeLoadSpec = computeJSNativeLoadSpec(initClass) private var superClass = computeSuperClass(initClass) private var fieldDefs = computeFieldDefs(initClass) private val isInterfaceAskers = mutable.Set.empty[Invalidatable] private val hasInlineableInitAskers = mutable.Set.empty[Invalidatable] + private val hasStoredSuperClassAskers = mutable.Set.empty[Invalidatable] + private val jsClassCaptureTypesAskers = mutable.Set.empty[Invalidatable] private val jsNativeLoadSpecAskers = mutable.Set.empty[Invalidatable] private val superClassAskers = mutable.Set.empty[Invalidatable] private val fieldDefsAskers = mutable.Set.empty[Invalidatable] @@ -189,6 +200,18 @@ private[emitter] final class KnowledgeGuardian { invalidateAskers(hasInlineableInitAskers) } + val newHasStoredSuperClass = computeHasStoredSuperClass(linkedClass) + if (newHasStoredSuperClass != hasStoredSuperClass) { + hasStoredSuperClass = newHasStoredSuperClass + invalidateAskers(hasStoredSuperClassAskers) + } + + val newJSClassCaptureTypes = computeJSClassCaptureTypes(linkedClass) + if (newJSClassCaptureTypes != jsClassCaptureTypes) { + jsClassCaptureTypes = newJSClassCaptureTypes + invalidateAskers(jsClassCaptureTypesAskers) + } + val newJSNativeLoadSpec = computeJSNativeLoadSpec(linkedClass) if (newJSNativeLoadSpec != jsNativeLoadSpec) { jsNativeLoadSpec = newJSNativeLoadSpec @@ -211,6 +234,12 @@ private[emitter] final class KnowledgeGuardian { private def computeIsInterface(linkedClass: LinkedClass): Boolean = linkedClass.kind == ClassKind.Interface + private def computeHasStoredSuperClass(linkedClass: LinkedClass): Boolean = + linkedClass.jsSuperClass.isDefined + + private def computeJSClassCaptureTypes(linkedClass: LinkedClass): Option[List[Type]] = + linkedClass.jsClassCaptures.map(_.map(_.ptpe)) + private def computeJSNativeLoadSpec(linkedClass: LinkedClass): Option[JSNativeLoadSpec] = linkedClass.jsNativeLoadSpec @@ -259,6 +288,18 @@ private[emitter] final class KnowledgeGuardian { hasInlineableInit } + def askHasStoredSuperClass(invalidatable: Invalidatable): Boolean = { + invalidatable.registeredTo(this) + hasStoredSuperClassAskers += invalidatable + hasStoredSuperClass + } + + def askJSClassCaptureTypes(invalidatable: Invalidatable): Option[List[Type]] = { + invalidatable.registeredTo(this) + jsClassCaptureTypesAskers += invalidatable + jsClassCaptureTypes + } + def askJSNativeLoadSpec(invalidatable: Invalidatable): Option[JSNativeLoadSpec] = { invalidatable.registeredTo(this) jsNativeLoadSpecAskers += invalidatable @@ -280,6 +321,8 @@ private[emitter] final class KnowledgeGuardian { def unregister(invalidatable: Invalidatable): Unit = { isInterfaceAskers -= invalidatable hasInlineableInitAskers -= invalidatable + hasStoredSuperClassAskers -= invalidatable + jsClassCaptureTypesAskers -= invalidatable jsNativeLoadSpecAskers -= invalidatable superClassAskers -= invalidatable fieldDefsAskers -= invalidatable @@ -289,6 +332,8 @@ private[emitter] final class KnowledgeGuardian { def unregisterAll(): Unit = { isInterfaceAskers.clear() hasInlineableInitAskers.clear() + hasStoredSuperClassAskers.clear() + jsClassCaptureTypesAskers.clear() jsNativeLoadSpecAskers.clear() superClassAskers.clear() fieldDefsAskers.clear() diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index d2b8ff3408..e042b29a39 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -24,7 +24,7 @@ import Trees._ import Types._ import org.scalajs.core.tools.logging._ -import org.scalajs.core.tools.linker.{LinkingUnit, LinkedClass} +import org.scalajs.core.tools.linker.{LinkingUnit, LinkedClass, Versioned} import org.scalajs.core.tools.linker.analyzer.{Analyzer, Infos} /** Checker for the validity of the IR. */ @@ -66,8 +66,11 @@ private final class IRChecker(unit: LinkingUnit, def check(): Int = { for (classDef <- unit.classDefs) { implicit val ctx = ErrorContext(classDef) + + checkJSClassCaptures(classDef) checkJSNativeLoadSpec(classDef) checkStaticMembers(classDef) + classDef.kind match { case ClassKind.AbstractJSType | ClassKind.NativeJSClass | ClassKind.NativeJSModuleClass => @@ -86,6 +89,43 @@ private final class IRChecker(unit: LinkingUnit, errorCount } + private def checkJSClassCaptures(classDef: LinkedClass): Unit = { + implicit val ctx = ErrorContext(classDef) + + for (classCaptures <- classDef.jsClassCaptures) { + if (classDef.kind != ClassKind.JSClass) { + reportError( + s"Class ${classDef.name} which is not a non-native JS class " + + "cannot have class captures") + } + + classCaptures.foldLeft(Set.empty[String]) { + case (alreadyDeclared, p @ ParamDef(ident, tpe, mutable, rest)) => + implicit val ctx = ErrorContext(p) + val name = ident.name + if (alreadyDeclared(name)) + reportError(s"Duplicate JS class capture '$name'") + if (tpe == NoType) + reportError(s"The JS class capture $name cannot have type NoType") + if (mutable) + reportError(s"The JS class capture $name cannot be mutable") + if (rest) + reportError(s"The JS class capture $name cannot be a rest param") + alreadyDeclared + name + } + + def isStaticInit(methodDef: Versioned[MethodDef]): Boolean = + methodDef.value.name.encodedName == StaticInitializerName + + for (staticInit <- classDef.staticMethods.find(isStaticInit)) { + implicit val ctx = ErrorContext(staticInit.value) + reportError( + s"The non-top-level JS class ${classDef.name} cannot have a " + + "static initializer") + } + } + } + private def checkJSNativeLoadSpec(classDef: LinkedClass): Unit = { implicit val ctx = ErrorContext(classDef) @@ -284,7 +324,8 @@ private final class IRChecker(unit: LinkingUnit, val thisType = if (static) NoType else ClassType(classDef.name.name) - val bodyEnv = Env.fromSignature(thisType, params, resultType, isConstructor) + val bodyEnv = Env.fromSignature(thisType, None, params, resultType, + isConstructor) body.fold { // Abstract @@ -344,7 +385,8 @@ private final class IRChecker(unit: LinkingUnit, body.fold { reportError("Exported method cannot be abstract") } { body => - val bodyEnv = Env.fromSignature(thisType, params, resultType) + val bodyEnv = Env.fromSignature(thisType, classDef.jsClassCaptures, + params, resultType) typecheckExpect(body, bodyEnv, resultType) } } @@ -381,8 +423,8 @@ private final class IRChecker(unit: LinkingUnit, (JSSuperConstructorCall(Nil)(methodDef.pos), Nil) } - val initialEnv = Env.fromSignature(NoType, params, NoType, - isConstructor = true) + val initialEnv = Env.fromSignature(NoType, classDef.jsClassCaptures, + params, NoType, isConstructor = true) val preparedEnv = (initialEnv /: prepStats) { (prevEnv, stat) => typecheckStat(stat, prevEnv) @@ -414,7 +456,8 @@ private final class IRChecker(unit: LinkingUnit, else ClassType(classDef.name.name) getterBody.foreach { getterBody => - val getterBodyEnv = Env.fromSignature(thisType, Nil, AnyType) + val getterBodyEnv = Env.fromSignature(thisType, classDef.jsClassCaptures, + Nil, AnyType) typecheckExpect(getterBody, getterBodyEnv, AnyType) } @@ -426,7 +469,8 @@ private final class IRChecker(unit: LinkingUnit, if (setterArg.rest) reportError(s"Rest parameter ${setterArg.name} is illegal in setter") - val setterBodyEnv = Env.fromSignature(thisType, List(setterArg), NoType) + val setterBodyEnv = Env.fromSignature(thisType, classDef.jsClassCaptures, + List(setterArg), NoType) typecheckStat(setterBody, setterBodyEnv) } } @@ -463,7 +507,7 @@ private final class IRChecker(unit: LinkingUnit, checkJSParamDefs(params) val thisType = ClassType(classDef.name.name) - val bodyEnv = Env.fromSignature(thisType, params, NoType) + val bodyEnv = Env.fromSignature(thisType, None, params, NoType) typecheckStat(body, bodyEnv) } @@ -938,6 +982,8 @@ private final class IRChecker(unit: LinkingUnit, } if (!valid) reportError(s"JS class type expected but $cls found") + else if (clazz.jsClassCaptures.nonEmpty) + reportError(s"Cannot load JS constructor of non-top-level class $cls") case LoadJSModule(cls) => val clazz = lookupClass(cls) @@ -1014,10 +1060,24 @@ private final class IRChecker(unit: LinkingUnit, checkJSParamDefs(params) val bodyEnv = Env.fromSignature( - AnyType, captureParams ++ params, AnyType) + AnyType, None, captureParams ++ params, AnyType) typecheckExpect(body, bodyEnv, AnyType) } + case CreateJSClass(cls, captureValues) => + val clazz = lookupClass(cls) + clazz.jsClassCaptures.fold { + reportError(s"Invalid CreateJSClass of top-level class $cls") + } { captureParams => + if (captureParams.size != captureValues.size) { + reportError("Mismatched size for class captures: " + + s"${captureParams.size} params vs ${captureValues.size} values") + } + + for ((ParamDef(_, ctpe, _, _), value) <- captureParams.zip(captureValues)) + typecheckExpect(value, env, ctpe) + } + case _ => reportError(s"Invalid expression tree") } @@ -1160,7 +1220,7 @@ private final class IRChecker(unit: LinkingUnit, implicit ctx: ErrorContext): CheckedClass = { classes.getOrElseUpdate(className, { reportError(s"Cannot find class $className") - new CheckedClass(className, ClassKind.Class, + new CheckedClass(className, ClassKind.Class, None, Some(ObjectClass), Set(ObjectClass), hasInstances = true, None, Nil) }) } @@ -1170,6 +1230,11 @@ private final class IRChecker(unit: LinkingUnit, lookupClass(classType.className) } + private def lookupClass(classRef: ClassRef)( + implicit ctx: ErrorContext): CheckedClass = { + lookupClass(classRef.className) + } + private def isSubclass(lhs: String, rhs: String)( implicit ctx: ErrorContext): Boolean = { tryLookupClass(lhs).fold({ info => @@ -1220,10 +1285,12 @@ private final class IRChecker(unit: LinkingUnit, private object Env { val empty: Env = new Env(NoType, Map.empty, Map.empty, false) - def fromSignature(thisType: Type, params: List[ParamDef], - resultType: Type, isConstructor: Boolean = false): Env = { + def fromSignature(thisType: Type, jsClassCaptures: Option[List[ParamDef]], + params: List[ParamDef], resultType: Type, + isConstructor: Boolean = false): Env = { + val allParams = jsClassCaptures.getOrElse(Nil) ::: params val paramLocalDefs = - for (p @ ParamDef(ident, tpe, mutable, _) <- params) + for (p @ ParamDef(ident, tpe, mutable, _) <- allParams) yield ident.name -> LocalDef(ident.name, tpe, mutable)(p.pos) new Env(thisType, paramLocalDefs.toMap, Map(None -> (if (resultType == NoType) AnyType else resultType)), @@ -1234,6 +1301,7 @@ private final class IRChecker(unit: LinkingUnit, private class CheckedClass( val name: String, val kind: ClassKind, + val jsClassCaptures: Option[List[ParamDef]], val superClassName: Option[String], val ancestors: Set[String], val hasInstances: Boolean, @@ -1248,6 +1316,7 @@ private final class IRChecker(unit: LinkingUnit, def this(classDef: LinkedClass)(implicit ctx: ErrorContext) = { this(classDef.name.name, classDef.kind, + classDef.jsClassCaptures, classDef.superClass.map(_.name), classDef.ancestors.toSet, classDef.hasInstances, diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index 247f18b9c8..dcce2e8321 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -199,8 +199,10 @@ final class BaseLinker(config: CommonPhaseConfig) { new LinkedClass( classDef.name, kind, + classDef.jsClassCaptures, classDef.superClass, classDef.interfaces, + classDef.jsSuperClass, classDef.jsNativeLoadSpec, fields.toList, staticMethods.toList, diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index 1a4d4ad580..a0e871d213 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -650,6 +650,9 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { transformClosureCommon(captureParams, params, body, captureValues.map(transformExpr)) + case CreateJSClass(cls, captureValues) => + CreateJSClass(cls, captureValues.map(transformExpr)) + // Trees that need not be transformed case _:Skip | _:Debugger | _:LoadModule | _:SelectStatic | diff --git a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/AnalyzerTest.scala b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/AnalyzerTest.scala index d393e4dfba..f09c8f13c4 100644 --- a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/AnalyzerTest.scala +++ b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/AnalyzerTest.scala @@ -34,14 +34,16 @@ class AnalyzerTest { private def classDef( encodedName: String, kind: ClassKind = ClassKind.Class, + jsClassCaptures: Option[List[ParamDef]] = None, superClass: Option[String] = None, interfaces: List[String] = Nil, + jsSuperClass: Option[Tree] = None, jsNativeLoadSpec: Option[JSNativeLoadSpec] = None, memberDefs: List[MemberDef] = Nil, topLevelExportDefs: List[TopLevelExportDef] = Nil): ClassDef = { - ClassDef(Ident(encodedName), kind, superClass.map(Ident(_)), - interfaces.map(Ident(_)), jsNativeLoadSpec, memberDefs, - topLevelExportDefs)( + ClassDef(Ident(encodedName), kind, jsClassCaptures, + superClass.map(Ident(_)), interfaces.map(Ident(_)), jsSuperClass, + jsNativeLoadSpec, memberDefs, topLevelExportDefs)( emptyOptHints) } From 303b9928353e3a00990b12cc58dd554c516e9cbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 24 Nov 2017 13:28:41 +0100 Subject: [PATCH 0559/2665] Do not inline `.toJSArray` to prevent code size blowing up. For an explicit `.toJSArray`, it is typically not advantageous to inline the method unless the exact type of collection is known. And in most of those cases, the collection would be stack-allocated, which would force inline anyway. In this commit, we directly implement `.toJSArray` (instead of depending on a method of `runtime`) and mark it as non-inlined. The method `runtime.genTraversableOnce2jsArray`, used by the code gen for JS varargs, is unchanged. --- .../scala/scala/scalajs/js/JSConverters.scala | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/library/src/main/scala/scala/scalajs/js/JSConverters.scala b/library/src/main/scala/scala/scalajs/js/JSConverters.scala index 34ce5c52ba..4dd745ecb5 100644 --- a/library/src/main/scala/scala/scalajs/js/JSConverters.scala +++ b/library/src/main/scala/scala/scalajs/js/JSConverters.scala @@ -39,7 +39,28 @@ object JSConverters extends JSConvertersLowPrioImplicits { implicit class JSRichGenTraversableOnce[T]( val col: GenTraversableOnce[T]) extends AnyVal { - @inline final def toJSArray: Array[T] = genTraversableOnce2jsArray(col) + final def toJSArray: Array[T] = { + /* This is basically a duplicate of `runtime.genTraversableOnce2jsArray`, + * except it is not marked `@inline`. We do not want to inline this + * method every time someone does `.toJSArray`, for code size reasons + * (unlike `genTraversableOnce2jsArray`, which is used by the codegen for + * transferring Scala varargs to JS varargs). + * + * One would think that we could still delegate to + * `genTraversableOnce2jsArray` and mark `toJSArray` with `@noinline` + * instead, but that would prevent `toJSArray` to be inlined even when + * `col` is stack-allocated (and we do want that to happen as in that + * case the entire match disappears and `col` can stay stack-allocated). + */ + col match { + case col: js.ArrayOps[T] => col.repr + case col: js.WrappedArray[T] => col.array + case _ => + val result = new js.Array[T] + col.foreach(x => result.push(x)) + result + } + } } implicit class JSRichGenIterable[T]( From 3d7bff5925d5c3dfd035ed25f6947b34a72b8858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 27 Nov 2017 10:58:27 +0100 Subject: [PATCH 0560/2665] Version 1.0.0-M2. --- ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index f7c6b68c58..9f986e4619 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "1.0.0-SNAPSHOT" + val current: String = "1.0.0-M2" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" From 617c4170fe9844eea0115b6ed59b2816201a70e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 28 Nov 2017 12:40:48 +0100 Subject: [PATCH 0561/2665] Towards 1.0.0 again. --- ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index 9f986e4619..f7c6b68c58 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "1.0.0-M2" + val current: String = "1.0.0-SNAPSHOT" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" From 7fed6dd818b5e22612e8aae326b2b8320bb64f66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 29 Nov 2017 18:54:35 +0100 Subject: [PATCH 0562/2665] Drop support for JDK 6 and 7. We keep the JDK-dependent test directories (`require-jdk7` and `require-jdk8`) as is in order not to complicate future forward merges from 0.6.x. --- ci/matrix.xml | 101 ++++++-------------------------------------- project/Build.scala | 14 +++--- 2 files changed, 20 insertions(+), 95 deletions(-) diff --git a/ci/matrix.xml b/ci/matrix.xml index 71857a3682..fdbec7f6e2 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -240,27 +240,11 @@ ]]> - - - 2.10.2 - 1.6 - - - 2.10.2 - 1.7 - + 2.10.2 1.8 - - 2.11.12 - 1.6 - - - 2.11.12 - 1.7 - 2.11.12 1.8 @@ -274,7 +258,7 @@ 1.8 - + 2.10.2 1.8 @@ -296,7 +280,7 @@ testSuite - + 2.11.12 1.8 @@ -313,7 +297,7 @@ scalaTestSuite - + 2.10.2 1.8 @@ -335,7 +319,7 @@ testSuite - + 2.11.12 1.8 @@ -352,7 +336,7 @@ scalaTestSuite - + 2.10.2 1.8 @@ -370,24 +354,11 @@ 1.8 - - - 2.10.7 - 1.6 - - - 2.10.7 - 1.7 - + 2.10.7 1.8 - - - 2.11.12 - 1.7 - 2.11.12 1.8 @@ -400,13 +371,13 @@ 2.11.0 - 1.7 + 1.8 2.11.12 - 1.7 + 1.8 2.12.4 @@ -417,9 +388,9 @@ 1.8 - + - 1.7 + 1.8 2.10.7 @@ -433,7 +404,7 @@ - + 2.10.3 1.8 @@ -503,58 +474,14 @@ 1.8 - - - 2.10.2 - 1.6 - testSuite - - - 2.10.2 - 1.7 - testSuite - - - 2.11.12 - 1.6 - testSuite - - - 2.11.12 - 1.7 - testSuite - - - - - 2.10.2 - 1.6 - testSuite - - - 2.10.2 - 1.7 - testSuite - - - 2.11.12 - 1.6 - testSuite - - - 2.11.12 - 1.7 - testSuite - - 2.11.12 - 1.7 + 1.8 2.11.12 - 1.7 + 1.8 2.12.4 diff --git a/project/Build.scala b/project/Build.scala index 35ee737144..eb2202af61 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -366,11 +366,8 @@ object Build { scalacOptions in (Compile, doc) := { val baseOptions = (scalacOptions in (Compile, doc)).value - /* - need JDK7 to link the doc to java.nio.charset.StandardCharsets - * - in Scala 2.10, some ScalaDoc links fail - */ - val fatalInDoc = - javaVersion.value >= 7 && scalaBinaryVersion.value != "2.10" + // in Scala 2.10, some ScalaDoc links fail + val fatalInDoc = scalaBinaryVersion.value != "2.10" if (fatalInDoc) baseOptions else baseOptions.filterNot(_ == "-Xfatal-warnings") @@ -460,6 +457,8 @@ object Build { val fullVersion = System.getProperty("java.version") val v = fullVersion.stripPrefix("1.").takeWhile(_.isDigit).toInt sLog.value.info(s"Detected JDK version $v") + if (v < 8) + throw new MessageOnlyException("This build requires JDK 8 or later. Aborting.") v } ) @@ -1375,9 +1374,8 @@ object Build { val isScalaAtLeast212 = !scalaV.startsWith("2.10.") && !scalaV.startsWith("2.11.") - List(sharedTestDir / "scala") ++ - includeIf(sharedTestDir / "require-jdk7", javaVersion.value >= 7) ++ - includeIf(sharedTestDir / "require-jdk8", javaVersion.value >= 8) ++ + List(sharedTestDir / "scala", sharedTestDir / "require-jdk7", + sharedTestDir / "require-jdk8") ++ includeIf(testDir / "require-2.12", isJSTest && isScalaAtLeast212) }, From eeaa76ca6a785ae0b8df01fa6fa09deb1c5559fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 30 Nov 2017 14:46:58 +0100 Subject: [PATCH 0563/2665] Unfork our dependency on the Google Closure Compiler. Now that we do not support JDK 6 anymore, we can go back to using the official artifacts of GCC. --- project/Build.scala | 2 +- project/build.sbt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index eb2202af61..dd1f291504 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -600,7 +600,7 @@ object Build { lazy val tools: Project = (project in file("tools/jvm")).settings( commonToolsSettings, libraryDependencies ++= Seq( - "org.scala-js" % "closure-compiler-java-6" % "v20160517", + "com.google.javascript" % "closure-compiler" % "v20160517", "com.novocode" % "junit-interface" % "0.9" % "test" ) ++ ( parallelCollectionsDependencies(scalaVersion.value) diff --git a/project/build.sbt b/project/build.sbt index be4979ac6a..147636bebe 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -6,7 +6,7 @@ addSbtPlugin("org.scalastyle" % "scalastyle-sbt-plugin" % "1.0.0") addSbtPlugin("org.portable-scala" % "sbt-platform-deps" % "1.0.0-M2") -libraryDependencies += "org.scala-js" % "closure-compiler-java-6" % "v20160517" +libraryDependencies += "com.google.javascript" % "closure-compiler" % "v20160517" libraryDependencies += "org.eclipse.jgit" % "org.eclipse.jgit.pgm" % "3.2.0.201312181205-r" From 2560fd82fcd4ca42abf78e4c84492ed730818463 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 4 Dec 2017 14:05:05 +0100 Subject: [PATCH 0564/2665] Remove dead code in the IR checker. --- .../org/scalajs/core/tools/linker/checker/IRChecker.scala | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index e042b29a39..0772953e87 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -483,7 +483,7 @@ private final class IRChecker(unit: LinkingUnit, throw new AssertionError("Exported method may not have Ident as name") case StringLiteral(name) => - if (name.contains("__") && name != Definitions.TopLevelExportsName) + if (name.contains("__")) reportError("Exported method def name cannot contain __") case ComputedName(tree, _) => @@ -1325,9 +1325,6 @@ private final class IRChecker(unit: LinkingUnit, else classDef.fields.map(CheckedClass.checkedField)) } - def isAncestorOfHijackedClass: Boolean = - AncestorsOfHijackedClasses.contains(name) - def lookupField(name: String): Option[CheckedField] = fields.get(name).orElse(superClass.flatMap(_.lookupField(name))) From 7abedec0d3c0dff3eedba82d333cb7be0c59d1ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 6 Dec 2017 11:31:15 +0100 Subject: [PATCH 0565/2665] [no-master] Turn the compiler crash of #3211 into a linking error. At the very least, the compiler should not crash on any valid Scala code, so this commit makes the situation a bit less bad than it was before. It does not really *solve* the issue, though, as there is still a linking error. That, however, seems difficult if not impossible to properly fix, as explained in #3211, so we do not attempt to address it now. --- .../scalajs/core/compiler/JSEncoding.scala | 1 - .../core/compiler/test/RegressionTest.scala | 35 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 compiler/src/test/scala/org/scalajs/core/compiler/test/RegressionTest.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala index 0c2936c0d7..9a4c9966b9 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala @@ -156,7 +156,6 @@ trait JSEncoding extends SubComponent { self: GenJSCode => def encodeRTStringMethodSym(sym: Symbol)( implicit pos: Position): (Symbol, js.Ident) = { require(sym.isMethod, "encodeMethodSym called with non-method symbol: " + sym) - require(sym.owner == definitions.StringClass) require(!sym.isClassConstructor && !sym.isPrivate) val (encodedName, paramsString) = diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/RegressionTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/RegressionTest.scala new file mode 100644 index 0000000000..842c14f5d2 --- /dev/null +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/RegressionTest.scala @@ -0,0 +1,35 @@ +package org.scalajs.core.compiler.test + +import org.scalajs.core.compiler.test.util._ +import org.junit.Test +import org.junit.Assume._ + +// scalastyle:off line.size.limit + +class RegressionTest extends DirectTest with TestHelpers { + + @Test + def noCrashWhenCallingDefaultMethodsOfCharSequence_issue3211: Unit = { + val javaVersion = System.getProperty("java.specification.version") + assumeTrue(javaVersion.startsWith("1.8") || !javaVersion.startsWith("1.")) + + """ + object LexerUtil { + def reflectiveLongest(data: String): Unit = { + println(data.chars()) + } + } + """.succeeds() + + """ + import scala.language.reflectiveCalls + + object LexerUtil { + def reflectiveLongest(data: Any { def chars: String }): Unit = { + println(data.chars) + } + } + """.succeeds() + } + +} From bb9c6cbee2e5e93bf6ac5f020d74f98444eb009b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 6 Dec 2017 15:59:20 +0100 Subject: [PATCH 0566/2665] Mitigate #3206: Send stderr of Node.js to the `JSConsole`. This way, at least all JS environments agree on what they do with `console.error()`, which is to merge it with `console.log()` and send everything to the `console: JSConsole` (which is the standard output by default). A deeper fix would allow to separately configure stdout and stderr, but that can only be done in Scala.js 1.x in the context of the redesign of `JSEnv`s #3033. --- .../src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala index 858d64db1e..87fff28710 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala @@ -96,13 +96,8 @@ abstract class ExternalJSEnv( try { sendVMStdin(out) } finally { out.close() } - // Pipe stdout to console + // Pipe stdout (and stderr which is merged into it) to console pipeToConsole(vmInst.getInputStream(), console) - - // We are probably done (stdin is closed). Report any errors - val errSrc = Source.fromInputStream(vmInst.getErrorStream(), "UTF-8") - try { errSrc.getLines.foreach(err => logger.error(err)) } - finally { errSrc.close } } /** Wait for the VM to terminate, verify exit code @@ -125,6 +120,7 @@ abstract class ExternalJSEnv( val allArgs = executable +: vmArgs val pBuilder = new ProcessBuilder(allArgs: _*) + pBuilder.redirectErrorStream(true) // merge stderr into stdout pBuilder.environment().clear() for ((name, value) <- vmEnv) From 5627479f3dc8dde191b27ac39dbd3038e2f278ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 7 Dec 2017 11:11:14 +0100 Subject: [PATCH 0567/2665] Reintroduce tests for our EMCAScript 2015 polyfills. When we removed support for Rhino, and moved the support of PhantomJS in a separate repository, we accidently got rid of all the tests in our build checking our polyfills for ES 2015 features. For example, the polyfills for `Math.imul`, or the floating-point bits conversions (including `Double.hashCode`). This commit restores that by introducing in our build a custom `NodeJSEnvForcePolyfills`, which is like `NodeJSEnv` but forcefully `delete`s all the good stuff from ES 2015. This ensures that we do not introduce regressions in our polyfills in the future. --- ci/matrix.xml | 35 ++++++++++++++++++ project/Build.scala | 16 ++++++-- project/NodeJSEnvForcePolyfills.scala | 53 +++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 project/NodeJSEnvForcePolyfills.scala diff --git a/ci/matrix.xml b/ci/matrix.xml index fdbec7f6e2..77149e4a21 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -83,6 +83,34 @@ ++$scala $testSuite/test ]]> + + testSuite + + + 2.12.4 + 1.8 + testSuite + + 2.11.12 diff --git a/project/Build.scala b/project/Build.scala index dd1f291504..a48ceda1e3 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -57,6 +57,8 @@ object ExposedValues extends AutoPlugin { config: StandardLinker.Config): standard.StandardLinkerConfigStandardOps = { standard.StandardLinkerConfigStandardOps(config) } + + type NodeJSEnvForcePolyfills = build.NodeJSEnvForcePolyfills } } @@ -1273,8 +1275,8 @@ object Build { testOptionTags := { def envTagsFor(env: JSEnv): Seq[String] = env match { case env: NodeJSEnv => - val baseArgs = Seq("nodejs", "typedarray") - if (env.wantSourceMap) { + val tags1 = Seq("nodejs") + val tags2 = if (env.wantSourceMap) { if (!env.hasSourceMapSupport) { throw new MessageOnlyException( "You must install Node.js source map support to " + @@ -1283,9 +1285,15 @@ object Build { "tests, do: set jsEnv in " + thisProject.value.id + " := NodeJSEnv().value.withSourceMap(false)") } - baseArgs :+ "source-maps" + tags1 :+ "source-maps" } else { - baseArgs + tags1 + } + env match { + case env: NodeJSEnvForcePolyfills => + tags1 + case _ => + tags1 :+ "typedarray" } case _ => diff --git a/project/NodeJSEnvForcePolyfills.scala b/project/NodeJSEnvForcePolyfills.scala new file mode 100644 index 0000000000..fd43f12d05 --- /dev/null +++ b/project/NodeJSEnvForcePolyfills.scala @@ -0,0 +1,53 @@ +package build + +import org.scalajs.jsenv._ +import org.scalajs.jsenv.nodejs._ + +import org.scalajs.core.tools.io._ + +class NodeJSEnvForcePolyfills(config: NodeJSEnv.Config) + extends NodeJSEnv(config) { + + def this() = this(NodeJSEnv.Config()) + + override protected def vmName: String = "Node.js forcing polyfills" + + /** File(s) to force all our ES 2015 polyfills to be used, by deleting the + * native functions. + */ + protected def forcePolyfills(): Seq[VirtualJSFile] = { + val f = new MemVirtualJSFile("scalaJSEnvInfo.js").withContent( + """ + |delete Math.fround; + |delete Math.imul; + |delete Math.clz32; + |delete Math.log10; + |delete Math.log1p; + |delete Math.cbrt; + |delete Math.hypot; + |delete Math.expm1; + |delete Math.sinh; + |delete Math.cosh; + |delete Math.tanh; + | + |delete global.Promise; + | + |delete global.ArrayBuffer; + |delete global.Int8Array; + |delete global.Int16Array; + |delete global.Int32Array; + |delete global.Uint8Array; + |delete global.Uint16Array; + |delete global.Uint32Array; + |delete global.Float32Array; + |delete global.Float64Array; + """.stripMargin + ) + Seq(f) + } + + /** Custom initialization scripts. */ + override protected def customInitFiles(): Seq[VirtualJSFile] = + super.customInitFiles() ++ forcePolyfills() + +} From 97dba33efdf9acf15872750e69f64253ef455f4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 8 Dec 2017 12:06:33 +0100 Subject: [PATCH 0568/2665] Add explicit tests for `ClassTag`-based pattern matching of primitives. They have some special semantics in Scala.js, which deserve to be specifically tested. --- .../testsuite/scalalib/ClassTagTest.scala | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ClassTagTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ClassTagTest.scala index 066a7d656d..52dc119499 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ClassTagTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ClassTagTest.scala @@ -13,6 +13,9 @@ import scala.reflect._ import org.junit.Test import org.junit.Assert._ +import org.junit.Assume._ + +import org.scalajs.testsuite.utils.Platform._ class ClassTagTest { @@ -97,4 +100,65 @@ class ClassTagTest { assertSame(classOf[Array[Nothing]], ClassTag(classOf[Array[Nothing]]).runtimeClass) assertSame(classOf[Array[Null]], ClassTag(classOf[Array[Null]]).runtimeClass) } + + @Test def classTagBasedPatternMatchingOfPrimitives(): Unit = { + assumeFalse( + "ClassTag.unapply only deals correctly with primitives since 2.11.2", + scalaVersion.startsWith("2.10.") || + (scalaVersion == "2.11.0" || scalaVersion == "2.11.1")) + + def test[A: ClassTag](x: Any): Boolean = x match { + case x: A => true + case _ => false + } + + def testTrue[A: ClassTag](x: Any): Unit = + assertTrue(s"$x must be a ${classTag[A]}", test[A](x)) + + def testFalse[A: ClassTag](x: Any): Unit = + assertFalse(s"$x must not be a ${classTag[A]}", test[A](x)) + + def testTrueOnJS[A: ClassTag](x: Any): Unit = { + if (executingInJVM) + testFalse[A](x) + else + testTrue[A](x) + } + + testTrue[Unit](()) + testTrue[scala.runtime.BoxedUnit](()) + testTrue[Boolean](false) + testTrue[java.lang.Boolean](false) + testTrue[Char]('A') + testTrue[Character]('A') + testTrue[Byte](5.toByte) + testTrue[java.lang.Byte](5.toByte) + testTrue[Int](5) + testTrue[Integer](5) + testTrue[Int](2000000000) + testTrue[Float](1.5f) + testTrue[Double](5.4) + + testTrueOnJS[Byte](5) + testTrueOnJS[java.lang.Byte](5) + testTrueOnJS[Int](5.toByte) + testTrueOnJS[Integer](5.toByte) + testTrueOnJS[Double](5) + testTrueOnJS[Float](1.5) + + testFalse[Unit](5) + testFalse[scala.runtime.BoxedUnit](5) + testFalse[Void](()) + testFalse[Void](5) + testFalse[Boolean](5) + testFalse[java.lang.Boolean](5) + testFalse[Char](5) + testFalse[Character](5) + testFalse[Byte](300) + testFalse[java.lang.Byte](300) + testFalse[Int]('A') + testFalse[Integer]('A') + testFalse[Int](1.5) + testFalse[Double]('A') + } } From 5d285d57c4b8b5a4892c9e2fefd0a2a9f8ebd4d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 8 Dec 2017 13:17:05 +0100 Subject: [PATCH 0569/2665] Backport the latest 2.11.x `ClassTag.scala` down to 2.11.2. That new implementation is functionally equivalent, but does not require `java.lang.Class.isAssignableFrom` to be hacked for primitive types in Scala.js. --- .../scala/reflect/ClassTag.scala | 163 ------------------ .../scala/reflect/ClassTag.scala | 163 ------------------ .../scala/reflect/ClassTag.scala | 163 ------------------ .../scala/reflect/ClassTag.scala | 163 ------------------ .../scala/reflect/ClassTag.scala | 163 ------------------ 5 files changed, 815 deletions(-) delete mode 100644 scalalib/overrides-2.11.11/scala/reflect/ClassTag.scala delete mode 100644 scalalib/overrides-2.11.2/scala/reflect/ClassTag.scala delete mode 100644 scalalib/overrides-2.11.4/scala/reflect/ClassTag.scala delete mode 100644 scalalib/overrides-2.11.5/scala/reflect/ClassTag.scala delete mode 100644 scalalib/overrides-2.11.8/scala/reflect/ClassTag.scala diff --git a/scalalib/overrides-2.11.11/scala/reflect/ClassTag.scala b/scalalib/overrides-2.11.11/scala/reflect/ClassTag.scala deleted file mode 100644 index 3c354a98da..0000000000 --- a/scalalib/overrides-2.11.11/scala/reflect/ClassTag.scala +++ /dev/null @@ -1,163 +0,0 @@ -package scala -package reflect - -import java.lang.{ Class => jClass } -import scala.language.{implicitConversions, existentials} -import scala.runtime.ScalaRunTime.{ arrayClass, arrayElementClass } - -/** - * - * A `ClassTag[T]` stores the erased class of a given type `T`, accessible via the `runtimeClass` - * field. This is particularly useful for instantiating `Array`s whose element types are unknown - * at compile time. - * - * `ClassTag`s are a weaker special case of [[scala.reflect.api.TypeTags#TypeTag]]s, in that they - * wrap only the runtime class of a given type, whereas a `TypeTag` contains all static type - * information. That is, `ClassTag`s are constructed from knowing only the top-level class of a - * type, without necessarily knowing all of its argument types. This runtime information is enough - * for runtime `Array` creation. - * - * For example: - * {{{ - * scala> def mkArray[T : ClassTag](elems: T*) = Array[T](elems: _*) - * mkArray: [T](elems: T*)(implicit evidence$1: scala.reflect.ClassTag[T])Array[T] - * - * scala> mkArray(42, 13) - * res0: Array[Int] = Array(42, 13) - * - * scala> mkArray("Japan","Brazil","Germany") - * res1: Array[String] = Array(Japan, Brazil, Germany) - * }}} - * - * See [[scala.reflect.api.TypeTags]] for more examples, or the - * [[http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html Reflection Guide: TypeTags]] - * for more details. - * - */ -@scala.annotation.implicitNotFound(msg = "No ClassTag available for ${T}") -trait ClassTag[T] extends ClassManifestDeprecatedApis[T] with Equals with Serializable { - // please, don't add any APIs here, like it was with `newWrappedArray` and `newArrayBuilder` - // class tags, and all tags in general, should be as minimalistic as possible - - /** A class representing the type `U` to which `T` would be erased. - * Note that there is no subtyping relationship between `T` and `U`. - */ - def runtimeClass: jClass[_] - - /** Produces a `ClassTag` that knows how to instantiate an `Array[Array[T]]` */ - def wrap: ClassTag[Array[T]] = ClassTag[Array[T]](arrayClass(runtimeClass)) - - /** Produces a new array with element type `T` and length `len` */ - override def newArray(len: Int): Array[T] = - runtimeClass match { - case java.lang.Byte.TYPE => new Array[Byte](len).asInstanceOf[Array[T]] - case java.lang.Short.TYPE => new Array[Short](len).asInstanceOf[Array[T]] - case java.lang.Character.TYPE => new Array[Char](len).asInstanceOf[Array[T]] - case java.lang.Integer.TYPE => new Array[Int](len).asInstanceOf[Array[T]] - case java.lang.Long.TYPE => new Array[Long](len).asInstanceOf[Array[T]] - case java.lang.Float.TYPE => new Array[Float](len).asInstanceOf[Array[T]] - case java.lang.Double.TYPE => new Array[Double](len).asInstanceOf[Array[T]] - case java.lang.Boolean.TYPE => new Array[Boolean](len).asInstanceOf[Array[T]] - case java.lang.Void.TYPE => new Array[Unit](len).asInstanceOf[Array[T]] - case _ => java.lang.reflect.Array.newInstance(runtimeClass, len).asInstanceOf[Array[T]] - } - - /** A ClassTag[T] can serve as an extractor that matches only objects of type T. - * - * The compiler tries to turn unchecked type tests in pattern matches into checked ones - * by wrapping a `(_: T)` type pattern as `ct(_: T)`, where `ct` is the `ClassTag[T]` instance. - * Type tests necessary before calling other extractors are treated similarly. - * `SomeExtractor(...)` is turned into `ct(SomeExtractor(...))` if `T` in `SomeExtractor.unapply(x: T)` - * is uncheckable, but we have an instance of `ClassTag[T]`. - */ - def unapply(x: Any): Option[T] = x match { - case null => None - case b: Byte => unapply(b) - case s: Short => unapply(s) - case c: Char => unapply(c) - case i: Int => unapply(i) - case l: Long => unapply(l) - case f: Float => unapply(f) - case d: Double => unapply(d) - case b: Boolean => unapply(b) - case u: Unit => unapply(u) - case a: Any => unapplyImpl(a) - } - - // TODO: Inline the bodies of these into the Any-accepting unapply overload above and delete them. - // This cannot be done until at least 2.12.0 for reasons of binary compatibility - def unapply(x: Byte) : Option[T] = unapplyImpl(x, classOf[Byte]) - def unapply(x: Short) : Option[T] = unapplyImpl(x, classOf[Short]) - def unapply(x: Char) : Option[T] = unapplyImpl(x, classOf[Char]) - def unapply(x: Int) : Option[T] = unapplyImpl(x, classOf[Int]) - def unapply(x: Long) : Option[T] = unapplyImpl(x, classOf[Long]) - def unapply(x: Float) : Option[T] = unapplyImpl(x, classOf[Float]) - def unapply(x: Double) : Option[T] = unapplyImpl(x, classOf[Double]) - def unapply(x: Boolean) : Option[T] = unapplyImpl(x, classOf[Boolean]) - def unapply(x: Unit) : Option[T] = unapplyImpl(x, classOf[Unit]) - - private[this] def unapplyImpl(x: Any, alternative: jClass[_] = null): Option[T] = { - val conforms = runtimeClass.isInstance(x) || (alternative != null && runtimeClass.isAssignableFrom(alternative)) - if (conforms) Some(x.asInstanceOf[T]) else None - } - - // case class accessories - override def canEqual(x: Any) = x.isInstanceOf[ClassTag[_]] - override def equals(x: Any) = x.isInstanceOf[ClassTag[_]] && this.runtimeClass == x.asInstanceOf[ClassTag[_]].runtimeClass - override def hashCode = scala.runtime.ScalaRunTime.hash(runtimeClass) - override def toString = { - def prettyprint(clazz: jClass[_]): String = - if (clazz.isArray) s"Array[${prettyprint(arrayElementClass(clazz))}]" else - clazz.getName - prettyprint(runtimeClass) - } -} - -/** - * Class tags corresponding to primitive types and constructor/extractor for ClassTags. - */ -object ClassTag { - def Byte : ClassTag[scala.Byte] = ManifestFactory.Byte - def Short : ClassTag[scala.Short] = ManifestFactory.Short - def Char : ClassTag[scala.Char] = ManifestFactory.Char - def Int : ClassTag[scala.Int] = ManifestFactory.Int - def Long : ClassTag[scala.Long] = ManifestFactory.Long - def Float : ClassTag[scala.Float] = ManifestFactory.Float - def Double : ClassTag[scala.Double] = ManifestFactory.Double - def Boolean : ClassTag[scala.Boolean] = ManifestFactory.Boolean - def Unit : ClassTag[scala.Unit] = ManifestFactory.Unit - def Any : ClassTag[scala.Any] = ManifestFactory.Any - def Object : ClassTag[java.lang.Object] = ManifestFactory.Object - def AnyVal : ClassTag[scala.AnyVal] = ManifestFactory.AnyVal - def AnyRef : ClassTag[scala.AnyRef] = ManifestFactory.AnyRef - def Nothing : ClassTag[scala.Nothing] = ManifestFactory.Nothing - def Null : ClassTag[scala.Null] = ManifestFactory.Null - - def apply[T](runtimeClass1: jClass[_]): ClassTag[T] = - runtimeClass1 match { - case java.lang.Byte.TYPE => ClassTag.Byte.asInstanceOf[ClassTag[T]] - case java.lang.Short.TYPE => ClassTag.Short.asInstanceOf[ClassTag[T]] - case java.lang.Character.TYPE => ClassTag.Char.asInstanceOf[ClassTag[T]] - case java.lang.Integer.TYPE => ClassTag.Int.asInstanceOf[ClassTag[T]] - case java.lang.Long.TYPE => ClassTag.Long.asInstanceOf[ClassTag[T]] - case java.lang.Float.TYPE => ClassTag.Float.asInstanceOf[ClassTag[T]] - case java.lang.Double.TYPE => ClassTag.Double.asInstanceOf[ClassTag[T]] - case java.lang.Boolean.TYPE => ClassTag.Boolean.asInstanceOf[ClassTag[T]] - case java.lang.Void.TYPE => ClassTag.Unit.asInstanceOf[ClassTag[T]] - case _ => - if (classOf[java.lang.Object] == runtimeClass1) - ClassTag.Object.asInstanceOf[ClassTag[T]] - else if (classOf[scala.runtime.Nothing$] == runtimeClass1) - ClassTag.Nothing.asInstanceOf[ClassTag[T]] - else if (classOf[scala.runtime.Null$] == runtimeClass1) - ClassTag.Null.asInstanceOf[ClassTag[T]] - else - new ClassClassTag[T](runtimeClass1) - } - - @inline - private final class ClassClassTag[T]( - val runtimeClass: Class[_]) extends ClassTag[T] - - def unapply[T](ctag: ClassTag[T]): Option[Class[_]] = Some(ctag.runtimeClass) -} diff --git a/scalalib/overrides-2.11.2/scala/reflect/ClassTag.scala b/scalalib/overrides-2.11.2/scala/reflect/ClassTag.scala deleted file mode 100644 index 3c354a98da..0000000000 --- a/scalalib/overrides-2.11.2/scala/reflect/ClassTag.scala +++ /dev/null @@ -1,163 +0,0 @@ -package scala -package reflect - -import java.lang.{ Class => jClass } -import scala.language.{implicitConversions, existentials} -import scala.runtime.ScalaRunTime.{ arrayClass, arrayElementClass } - -/** - * - * A `ClassTag[T]` stores the erased class of a given type `T`, accessible via the `runtimeClass` - * field. This is particularly useful for instantiating `Array`s whose element types are unknown - * at compile time. - * - * `ClassTag`s are a weaker special case of [[scala.reflect.api.TypeTags#TypeTag]]s, in that they - * wrap only the runtime class of a given type, whereas a `TypeTag` contains all static type - * information. That is, `ClassTag`s are constructed from knowing only the top-level class of a - * type, without necessarily knowing all of its argument types. This runtime information is enough - * for runtime `Array` creation. - * - * For example: - * {{{ - * scala> def mkArray[T : ClassTag](elems: T*) = Array[T](elems: _*) - * mkArray: [T](elems: T*)(implicit evidence$1: scala.reflect.ClassTag[T])Array[T] - * - * scala> mkArray(42, 13) - * res0: Array[Int] = Array(42, 13) - * - * scala> mkArray("Japan","Brazil","Germany") - * res1: Array[String] = Array(Japan, Brazil, Germany) - * }}} - * - * See [[scala.reflect.api.TypeTags]] for more examples, or the - * [[http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html Reflection Guide: TypeTags]] - * for more details. - * - */ -@scala.annotation.implicitNotFound(msg = "No ClassTag available for ${T}") -trait ClassTag[T] extends ClassManifestDeprecatedApis[T] with Equals with Serializable { - // please, don't add any APIs here, like it was with `newWrappedArray` and `newArrayBuilder` - // class tags, and all tags in general, should be as minimalistic as possible - - /** A class representing the type `U` to which `T` would be erased. - * Note that there is no subtyping relationship between `T` and `U`. - */ - def runtimeClass: jClass[_] - - /** Produces a `ClassTag` that knows how to instantiate an `Array[Array[T]]` */ - def wrap: ClassTag[Array[T]] = ClassTag[Array[T]](arrayClass(runtimeClass)) - - /** Produces a new array with element type `T` and length `len` */ - override def newArray(len: Int): Array[T] = - runtimeClass match { - case java.lang.Byte.TYPE => new Array[Byte](len).asInstanceOf[Array[T]] - case java.lang.Short.TYPE => new Array[Short](len).asInstanceOf[Array[T]] - case java.lang.Character.TYPE => new Array[Char](len).asInstanceOf[Array[T]] - case java.lang.Integer.TYPE => new Array[Int](len).asInstanceOf[Array[T]] - case java.lang.Long.TYPE => new Array[Long](len).asInstanceOf[Array[T]] - case java.lang.Float.TYPE => new Array[Float](len).asInstanceOf[Array[T]] - case java.lang.Double.TYPE => new Array[Double](len).asInstanceOf[Array[T]] - case java.lang.Boolean.TYPE => new Array[Boolean](len).asInstanceOf[Array[T]] - case java.lang.Void.TYPE => new Array[Unit](len).asInstanceOf[Array[T]] - case _ => java.lang.reflect.Array.newInstance(runtimeClass, len).asInstanceOf[Array[T]] - } - - /** A ClassTag[T] can serve as an extractor that matches only objects of type T. - * - * The compiler tries to turn unchecked type tests in pattern matches into checked ones - * by wrapping a `(_: T)` type pattern as `ct(_: T)`, where `ct` is the `ClassTag[T]` instance. - * Type tests necessary before calling other extractors are treated similarly. - * `SomeExtractor(...)` is turned into `ct(SomeExtractor(...))` if `T` in `SomeExtractor.unapply(x: T)` - * is uncheckable, but we have an instance of `ClassTag[T]`. - */ - def unapply(x: Any): Option[T] = x match { - case null => None - case b: Byte => unapply(b) - case s: Short => unapply(s) - case c: Char => unapply(c) - case i: Int => unapply(i) - case l: Long => unapply(l) - case f: Float => unapply(f) - case d: Double => unapply(d) - case b: Boolean => unapply(b) - case u: Unit => unapply(u) - case a: Any => unapplyImpl(a) - } - - // TODO: Inline the bodies of these into the Any-accepting unapply overload above and delete them. - // This cannot be done until at least 2.12.0 for reasons of binary compatibility - def unapply(x: Byte) : Option[T] = unapplyImpl(x, classOf[Byte]) - def unapply(x: Short) : Option[T] = unapplyImpl(x, classOf[Short]) - def unapply(x: Char) : Option[T] = unapplyImpl(x, classOf[Char]) - def unapply(x: Int) : Option[T] = unapplyImpl(x, classOf[Int]) - def unapply(x: Long) : Option[T] = unapplyImpl(x, classOf[Long]) - def unapply(x: Float) : Option[T] = unapplyImpl(x, classOf[Float]) - def unapply(x: Double) : Option[T] = unapplyImpl(x, classOf[Double]) - def unapply(x: Boolean) : Option[T] = unapplyImpl(x, classOf[Boolean]) - def unapply(x: Unit) : Option[T] = unapplyImpl(x, classOf[Unit]) - - private[this] def unapplyImpl(x: Any, alternative: jClass[_] = null): Option[T] = { - val conforms = runtimeClass.isInstance(x) || (alternative != null && runtimeClass.isAssignableFrom(alternative)) - if (conforms) Some(x.asInstanceOf[T]) else None - } - - // case class accessories - override def canEqual(x: Any) = x.isInstanceOf[ClassTag[_]] - override def equals(x: Any) = x.isInstanceOf[ClassTag[_]] && this.runtimeClass == x.asInstanceOf[ClassTag[_]].runtimeClass - override def hashCode = scala.runtime.ScalaRunTime.hash(runtimeClass) - override def toString = { - def prettyprint(clazz: jClass[_]): String = - if (clazz.isArray) s"Array[${prettyprint(arrayElementClass(clazz))}]" else - clazz.getName - prettyprint(runtimeClass) - } -} - -/** - * Class tags corresponding to primitive types and constructor/extractor for ClassTags. - */ -object ClassTag { - def Byte : ClassTag[scala.Byte] = ManifestFactory.Byte - def Short : ClassTag[scala.Short] = ManifestFactory.Short - def Char : ClassTag[scala.Char] = ManifestFactory.Char - def Int : ClassTag[scala.Int] = ManifestFactory.Int - def Long : ClassTag[scala.Long] = ManifestFactory.Long - def Float : ClassTag[scala.Float] = ManifestFactory.Float - def Double : ClassTag[scala.Double] = ManifestFactory.Double - def Boolean : ClassTag[scala.Boolean] = ManifestFactory.Boolean - def Unit : ClassTag[scala.Unit] = ManifestFactory.Unit - def Any : ClassTag[scala.Any] = ManifestFactory.Any - def Object : ClassTag[java.lang.Object] = ManifestFactory.Object - def AnyVal : ClassTag[scala.AnyVal] = ManifestFactory.AnyVal - def AnyRef : ClassTag[scala.AnyRef] = ManifestFactory.AnyRef - def Nothing : ClassTag[scala.Nothing] = ManifestFactory.Nothing - def Null : ClassTag[scala.Null] = ManifestFactory.Null - - def apply[T](runtimeClass1: jClass[_]): ClassTag[T] = - runtimeClass1 match { - case java.lang.Byte.TYPE => ClassTag.Byte.asInstanceOf[ClassTag[T]] - case java.lang.Short.TYPE => ClassTag.Short.asInstanceOf[ClassTag[T]] - case java.lang.Character.TYPE => ClassTag.Char.asInstanceOf[ClassTag[T]] - case java.lang.Integer.TYPE => ClassTag.Int.asInstanceOf[ClassTag[T]] - case java.lang.Long.TYPE => ClassTag.Long.asInstanceOf[ClassTag[T]] - case java.lang.Float.TYPE => ClassTag.Float.asInstanceOf[ClassTag[T]] - case java.lang.Double.TYPE => ClassTag.Double.asInstanceOf[ClassTag[T]] - case java.lang.Boolean.TYPE => ClassTag.Boolean.asInstanceOf[ClassTag[T]] - case java.lang.Void.TYPE => ClassTag.Unit.asInstanceOf[ClassTag[T]] - case _ => - if (classOf[java.lang.Object] == runtimeClass1) - ClassTag.Object.asInstanceOf[ClassTag[T]] - else if (classOf[scala.runtime.Nothing$] == runtimeClass1) - ClassTag.Nothing.asInstanceOf[ClassTag[T]] - else if (classOf[scala.runtime.Null$] == runtimeClass1) - ClassTag.Null.asInstanceOf[ClassTag[T]] - else - new ClassClassTag[T](runtimeClass1) - } - - @inline - private final class ClassClassTag[T]( - val runtimeClass: Class[_]) extends ClassTag[T] - - def unapply[T](ctag: ClassTag[T]): Option[Class[_]] = Some(ctag.runtimeClass) -} diff --git a/scalalib/overrides-2.11.4/scala/reflect/ClassTag.scala b/scalalib/overrides-2.11.4/scala/reflect/ClassTag.scala deleted file mode 100644 index 3c354a98da..0000000000 --- a/scalalib/overrides-2.11.4/scala/reflect/ClassTag.scala +++ /dev/null @@ -1,163 +0,0 @@ -package scala -package reflect - -import java.lang.{ Class => jClass } -import scala.language.{implicitConversions, existentials} -import scala.runtime.ScalaRunTime.{ arrayClass, arrayElementClass } - -/** - * - * A `ClassTag[T]` stores the erased class of a given type `T`, accessible via the `runtimeClass` - * field. This is particularly useful for instantiating `Array`s whose element types are unknown - * at compile time. - * - * `ClassTag`s are a weaker special case of [[scala.reflect.api.TypeTags#TypeTag]]s, in that they - * wrap only the runtime class of a given type, whereas a `TypeTag` contains all static type - * information. That is, `ClassTag`s are constructed from knowing only the top-level class of a - * type, without necessarily knowing all of its argument types. This runtime information is enough - * for runtime `Array` creation. - * - * For example: - * {{{ - * scala> def mkArray[T : ClassTag](elems: T*) = Array[T](elems: _*) - * mkArray: [T](elems: T*)(implicit evidence$1: scala.reflect.ClassTag[T])Array[T] - * - * scala> mkArray(42, 13) - * res0: Array[Int] = Array(42, 13) - * - * scala> mkArray("Japan","Brazil","Germany") - * res1: Array[String] = Array(Japan, Brazil, Germany) - * }}} - * - * See [[scala.reflect.api.TypeTags]] for more examples, or the - * [[http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html Reflection Guide: TypeTags]] - * for more details. - * - */ -@scala.annotation.implicitNotFound(msg = "No ClassTag available for ${T}") -trait ClassTag[T] extends ClassManifestDeprecatedApis[T] with Equals with Serializable { - // please, don't add any APIs here, like it was with `newWrappedArray` and `newArrayBuilder` - // class tags, and all tags in general, should be as minimalistic as possible - - /** A class representing the type `U` to which `T` would be erased. - * Note that there is no subtyping relationship between `T` and `U`. - */ - def runtimeClass: jClass[_] - - /** Produces a `ClassTag` that knows how to instantiate an `Array[Array[T]]` */ - def wrap: ClassTag[Array[T]] = ClassTag[Array[T]](arrayClass(runtimeClass)) - - /** Produces a new array with element type `T` and length `len` */ - override def newArray(len: Int): Array[T] = - runtimeClass match { - case java.lang.Byte.TYPE => new Array[Byte](len).asInstanceOf[Array[T]] - case java.lang.Short.TYPE => new Array[Short](len).asInstanceOf[Array[T]] - case java.lang.Character.TYPE => new Array[Char](len).asInstanceOf[Array[T]] - case java.lang.Integer.TYPE => new Array[Int](len).asInstanceOf[Array[T]] - case java.lang.Long.TYPE => new Array[Long](len).asInstanceOf[Array[T]] - case java.lang.Float.TYPE => new Array[Float](len).asInstanceOf[Array[T]] - case java.lang.Double.TYPE => new Array[Double](len).asInstanceOf[Array[T]] - case java.lang.Boolean.TYPE => new Array[Boolean](len).asInstanceOf[Array[T]] - case java.lang.Void.TYPE => new Array[Unit](len).asInstanceOf[Array[T]] - case _ => java.lang.reflect.Array.newInstance(runtimeClass, len).asInstanceOf[Array[T]] - } - - /** A ClassTag[T] can serve as an extractor that matches only objects of type T. - * - * The compiler tries to turn unchecked type tests in pattern matches into checked ones - * by wrapping a `(_: T)` type pattern as `ct(_: T)`, where `ct` is the `ClassTag[T]` instance. - * Type tests necessary before calling other extractors are treated similarly. - * `SomeExtractor(...)` is turned into `ct(SomeExtractor(...))` if `T` in `SomeExtractor.unapply(x: T)` - * is uncheckable, but we have an instance of `ClassTag[T]`. - */ - def unapply(x: Any): Option[T] = x match { - case null => None - case b: Byte => unapply(b) - case s: Short => unapply(s) - case c: Char => unapply(c) - case i: Int => unapply(i) - case l: Long => unapply(l) - case f: Float => unapply(f) - case d: Double => unapply(d) - case b: Boolean => unapply(b) - case u: Unit => unapply(u) - case a: Any => unapplyImpl(a) - } - - // TODO: Inline the bodies of these into the Any-accepting unapply overload above and delete them. - // This cannot be done until at least 2.12.0 for reasons of binary compatibility - def unapply(x: Byte) : Option[T] = unapplyImpl(x, classOf[Byte]) - def unapply(x: Short) : Option[T] = unapplyImpl(x, classOf[Short]) - def unapply(x: Char) : Option[T] = unapplyImpl(x, classOf[Char]) - def unapply(x: Int) : Option[T] = unapplyImpl(x, classOf[Int]) - def unapply(x: Long) : Option[T] = unapplyImpl(x, classOf[Long]) - def unapply(x: Float) : Option[T] = unapplyImpl(x, classOf[Float]) - def unapply(x: Double) : Option[T] = unapplyImpl(x, classOf[Double]) - def unapply(x: Boolean) : Option[T] = unapplyImpl(x, classOf[Boolean]) - def unapply(x: Unit) : Option[T] = unapplyImpl(x, classOf[Unit]) - - private[this] def unapplyImpl(x: Any, alternative: jClass[_] = null): Option[T] = { - val conforms = runtimeClass.isInstance(x) || (alternative != null && runtimeClass.isAssignableFrom(alternative)) - if (conforms) Some(x.asInstanceOf[T]) else None - } - - // case class accessories - override def canEqual(x: Any) = x.isInstanceOf[ClassTag[_]] - override def equals(x: Any) = x.isInstanceOf[ClassTag[_]] && this.runtimeClass == x.asInstanceOf[ClassTag[_]].runtimeClass - override def hashCode = scala.runtime.ScalaRunTime.hash(runtimeClass) - override def toString = { - def prettyprint(clazz: jClass[_]): String = - if (clazz.isArray) s"Array[${prettyprint(arrayElementClass(clazz))}]" else - clazz.getName - prettyprint(runtimeClass) - } -} - -/** - * Class tags corresponding to primitive types and constructor/extractor for ClassTags. - */ -object ClassTag { - def Byte : ClassTag[scala.Byte] = ManifestFactory.Byte - def Short : ClassTag[scala.Short] = ManifestFactory.Short - def Char : ClassTag[scala.Char] = ManifestFactory.Char - def Int : ClassTag[scala.Int] = ManifestFactory.Int - def Long : ClassTag[scala.Long] = ManifestFactory.Long - def Float : ClassTag[scala.Float] = ManifestFactory.Float - def Double : ClassTag[scala.Double] = ManifestFactory.Double - def Boolean : ClassTag[scala.Boolean] = ManifestFactory.Boolean - def Unit : ClassTag[scala.Unit] = ManifestFactory.Unit - def Any : ClassTag[scala.Any] = ManifestFactory.Any - def Object : ClassTag[java.lang.Object] = ManifestFactory.Object - def AnyVal : ClassTag[scala.AnyVal] = ManifestFactory.AnyVal - def AnyRef : ClassTag[scala.AnyRef] = ManifestFactory.AnyRef - def Nothing : ClassTag[scala.Nothing] = ManifestFactory.Nothing - def Null : ClassTag[scala.Null] = ManifestFactory.Null - - def apply[T](runtimeClass1: jClass[_]): ClassTag[T] = - runtimeClass1 match { - case java.lang.Byte.TYPE => ClassTag.Byte.asInstanceOf[ClassTag[T]] - case java.lang.Short.TYPE => ClassTag.Short.asInstanceOf[ClassTag[T]] - case java.lang.Character.TYPE => ClassTag.Char.asInstanceOf[ClassTag[T]] - case java.lang.Integer.TYPE => ClassTag.Int.asInstanceOf[ClassTag[T]] - case java.lang.Long.TYPE => ClassTag.Long.asInstanceOf[ClassTag[T]] - case java.lang.Float.TYPE => ClassTag.Float.asInstanceOf[ClassTag[T]] - case java.lang.Double.TYPE => ClassTag.Double.asInstanceOf[ClassTag[T]] - case java.lang.Boolean.TYPE => ClassTag.Boolean.asInstanceOf[ClassTag[T]] - case java.lang.Void.TYPE => ClassTag.Unit.asInstanceOf[ClassTag[T]] - case _ => - if (classOf[java.lang.Object] == runtimeClass1) - ClassTag.Object.asInstanceOf[ClassTag[T]] - else if (classOf[scala.runtime.Nothing$] == runtimeClass1) - ClassTag.Nothing.asInstanceOf[ClassTag[T]] - else if (classOf[scala.runtime.Null$] == runtimeClass1) - ClassTag.Null.asInstanceOf[ClassTag[T]] - else - new ClassClassTag[T](runtimeClass1) - } - - @inline - private final class ClassClassTag[T]( - val runtimeClass: Class[_]) extends ClassTag[T] - - def unapply[T](ctag: ClassTag[T]): Option[Class[_]] = Some(ctag.runtimeClass) -} diff --git a/scalalib/overrides-2.11.5/scala/reflect/ClassTag.scala b/scalalib/overrides-2.11.5/scala/reflect/ClassTag.scala deleted file mode 100644 index 3c354a98da..0000000000 --- a/scalalib/overrides-2.11.5/scala/reflect/ClassTag.scala +++ /dev/null @@ -1,163 +0,0 @@ -package scala -package reflect - -import java.lang.{ Class => jClass } -import scala.language.{implicitConversions, existentials} -import scala.runtime.ScalaRunTime.{ arrayClass, arrayElementClass } - -/** - * - * A `ClassTag[T]` stores the erased class of a given type `T`, accessible via the `runtimeClass` - * field. This is particularly useful for instantiating `Array`s whose element types are unknown - * at compile time. - * - * `ClassTag`s are a weaker special case of [[scala.reflect.api.TypeTags#TypeTag]]s, in that they - * wrap only the runtime class of a given type, whereas a `TypeTag` contains all static type - * information. That is, `ClassTag`s are constructed from knowing only the top-level class of a - * type, without necessarily knowing all of its argument types. This runtime information is enough - * for runtime `Array` creation. - * - * For example: - * {{{ - * scala> def mkArray[T : ClassTag](elems: T*) = Array[T](elems: _*) - * mkArray: [T](elems: T*)(implicit evidence$1: scala.reflect.ClassTag[T])Array[T] - * - * scala> mkArray(42, 13) - * res0: Array[Int] = Array(42, 13) - * - * scala> mkArray("Japan","Brazil","Germany") - * res1: Array[String] = Array(Japan, Brazil, Germany) - * }}} - * - * See [[scala.reflect.api.TypeTags]] for more examples, or the - * [[http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html Reflection Guide: TypeTags]] - * for more details. - * - */ -@scala.annotation.implicitNotFound(msg = "No ClassTag available for ${T}") -trait ClassTag[T] extends ClassManifestDeprecatedApis[T] with Equals with Serializable { - // please, don't add any APIs here, like it was with `newWrappedArray` and `newArrayBuilder` - // class tags, and all tags in general, should be as minimalistic as possible - - /** A class representing the type `U` to which `T` would be erased. - * Note that there is no subtyping relationship between `T` and `U`. - */ - def runtimeClass: jClass[_] - - /** Produces a `ClassTag` that knows how to instantiate an `Array[Array[T]]` */ - def wrap: ClassTag[Array[T]] = ClassTag[Array[T]](arrayClass(runtimeClass)) - - /** Produces a new array with element type `T` and length `len` */ - override def newArray(len: Int): Array[T] = - runtimeClass match { - case java.lang.Byte.TYPE => new Array[Byte](len).asInstanceOf[Array[T]] - case java.lang.Short.TYPE => new Array[Short](len).asInstanceOf[Array[T]] - case java.lang.Character.TYPE => new Array[Char](len).asInstanceOf[Array[T]] - case java.lang.Integer.TYPE => new Array[Int](len).asInstanceOf[Array[T]] - case java.lang.Long.TYPE => new Array[Long](len).asInstanceOf[Array[T]] - case java.lang.Float.TYPE => new Array[Float](len).asInstanceOf[Array[T]] - case java.lang.Double.TYPE => new Array[Double](len).asInstanceOf[Array[T]] - case java.lang.Boolean.TYPE => new Array[Boolean](len).asInstanceOf[Array[T]] - case java.lang.Void.TYPE => new Array[Unit](len).asInstanceOf[Array[T]] - case _ => java.lang.reflect.Array.newInstance(runtimeClass, len).asInstanceOf[Array[T]] - } - - /** A ClassTag[T] can serve as an extractor that matches only objects of type T. - * - * The compiler tries to turn unchecked type tests in pattern matches into checked ones - * by wrapping a `(_: T)` type pattern as `ct(_: T)`, where `ct` is the `ClassTag[T]` instance. - * Type tests necessary before calling other extractors are treated similarly. - * `SomeExtractor(...)` is turned into `ct(SomeExtractor(...))` if `T` in `SomeExtractor.unapply(x: T)` - * is uncheckable, but we have an instance of `ClassTag[T]`. - */ - def unapply(x: Any): Option[T] = x match { - case null => None - case b: Byte => unapply(b) - case s: Short => unapply(s) - case c: Char => unapply(c) - case i: Int => unapply(i) - case l: Long => unapply(l) - case f: Float => unapply(f) - case d: Double => unapply(d) - case b: Boolean => unapply(b) - case u: Unit => unapply(u) - case a: Any => unapplyImpl(a) - } - - // TODO: Inline the bodies of these into the Any-accepting unapply overload above and delete them. - // This cannot be done until at least 2.12.0 for reasons of binary compatibility - def unapply(x: Byte) : Option[T] = unapplyImpl(x, classOf[Byte]) - def unapply(x: Short) : Option[T] = unapplyImpl(x, classOf[Short]) - def unapply(x: Char) : Option[T] = unapplyImpl(x, classOf[Char]) - def unapply(x: Int) : Option[T] = unapplyImpl(x, classOf[Int]) - def unapply(x: Long) : Option[T] = unapplyImpl(x, classOf[Long]) - def unapply(x: Float) : Option[T] = unapplyImpl(x, classOf[Float]) - def unapply(x: Double) : Option[T] = unapplyImpl(x, classOf[Double]) - def unapply(x: Boolean) : Option[T] = unapplyImpl(x, classOf[Boolean]) - def unapply(x: Unit) : Option[T] = unapplyImpl(x, classOf[Unit]) - - private[this] def unapplyImpl(x: Any, alternative: jClass[_] = null): Option[T] = { - val conforms = runtimeClass.isInstance(x) || (alternative != null && runtimeClass.isAssignableFrom(alternative)) - if (conforms) Some(x.asInstanceOf[T]) else None - } - - // case class accessories - override def canEqual(x: Any) = x.isInstanceOf[ClassTag[_]] - override def equals(x: Any) = x.isInstanceOf[ClassTag[_]] && this.runtimeClass == x.asInstanceOf[ClassTag[_]].runtimeClass - override def hashCode = scala.runtime.ScalaRunTime.hash(runtimeClass) - override def toString = { - def prettyprint(clazz: jClass[_]): String = - if (clazz.isArray) s"Array[${prettyprint(arrayElementClass(clazz))}]" else - clazz.getName - prettyprint(runtimeClass) - } -} - -/** - * Class tags corresponding to primitive types and constructor/extractor for ClassTags. - */ -object ClassTag { - def Byte : ClassTag[scala.Byte] = ManifestFactory.Byte - def Short : ClassTag[scala.Short] = ManifestFactory.Short - def Char : ClassTag[scala.Char] = ManifestFactory.Char - def Int : ClassTag[scala.Int] = ManifestFactory.Int - def Long : ClassTag[scala.Long] = ManifestFactory.Long - def Float : ClassTag[scala.Float] = ManifestFactory.Float - def Double : ClassTag[scala.Double] = ManifestFactory.Double - def Boolean : ClassTag[scala.Boolean] = ManifestFactory.Boolean - def Unit : ClassTag[scala.Unit] = ManifestFactory.Unit - def Any : ClassTag[scala.Any] = ManifestFactory.Any - def Object : ClassTag[java.lang.Object] = ManifestFactory.Object - def AnyVal : ClassTag[scala.AnyVal] = ManifestFactory.AnyVal - def AnyRef : ClassTag[scala.AnyRef] = ManifestFactory.AnyRef - def Nothing : ClassTag[scala.Nothing] = ManifestFactory.Nothing - def Null : ClassTag[scala.Null] = ManifestFactory.Null - - def apply[T](runtimeClass1: jClass[_]): ClassTag[T] = - runtimeClass1 match { - case java.lang.Byte.TYPE => ClassTag.Byte.asInstanceOf[ClassTag[T]] - case java.lang.Short.TYPE => ClassTag.Short.asInstanceOf[ClassTag[T]] - case java.lang.Character.TYPE => ClassTag.Char.asInstanceOf[ClassTag[T]] - case java.lang.Integer.TYPE => ClassTag.Int.asInstanceOf[ClassTag[T]] - case java.lang.Long.TYPE => ClassTag.Long.asInstanceOf[ClassTag[T]] - case java.lang.Float.TYPE => ClassTag.Float.asInstanceOf[ClassTag[T]] - case java.lang.Double.TYPE => ClassTag.Double.asInstanceOf[ClassTag[T]] - case java.lang.Boolean.TYPE => ClassTag.Boolean.asInstanceOf[ClassTag[T]] - case java.lang.Void.TYPE => ClassTag.Unit.asInstanceOf[ClassTag[T]] - case _ => - if (classOf[java.lang.Object] == runtimeClass1) - ClassTag.Object.asInstanceOf[ClassTag[T]] - else if (classOf[scala.runtime.Nothing$] == runtimeClass1) - ClassTag.Nothing.asInstanceOf[ClassTag[T]] - else if (classOf[scala.runtime.Null$] == runtimeClass1) - ClassTag.Null.asInstanceOf[ClassTag[T]] - else - new ClassClassTag[T](runtimeClass1) - } - - @inline - private final class ClassClassTag[T]( - val runtimeClass: Class[_]) extends ClassTag[T] - - def unapply[T](ctag: ClassTag[T]): Option[Class[_]] = Some(ctag.runtimeClass) -} diff --git a/scalalib/overrides-2.11.8/scala/reflect/ClassTag.scala b/scalalib/overrides-2.11.8/scala/reflect/ClassTag.scala deleted file mode 100644 index 3c354a98da..0000000000 --- a/scalalib/overrides-2.11.8/scala/reflect/ClassTag.scala +++ /dev/null @@ -1,163 +0,0 @@ -package scala -package reflect - -import java.lang.{ Class => jClass } -import scala.language.{implicitConversions, existentials} -import scala.runtime.ScalaRunTime.{ arrayClass, arrayElementClass } - -/** - * - * A `ClassTag[T]` stores the erased class of a given type `T`, accessible via the `runtimeClass` - * field. This is particularly useful for instantiating `Array`s whose element types are unknown - * at compile time. - * - * `ClassTag`s are a weaker special case of [[scala.reflect.api.TypeTags#TypeTag]]s, in that they - * wrap only the runtime class of a given type, whereas a `TypeTag` contains all static type - * information. That is, `ClassTag`s are constructed from knowing only the top-level class of a - * type, without necessarily knowing all of its argument types. This runtime information is enough - * for runtime `Array` creation. - * - * For example: - * {{{ - * scala> def mkArray[T : ClassTag](elems: T*) = Array[T](elems: _*) - * mkArray: [T](elems: T*)(implicit evidence$1: scala.reflect.ClassTag[T])Array[T] - * - * scala> mkArray(42, 13) - * res0: Array[Int] = Array(42, 13) - * - * scala> mkArray("Japan","Brazil","Germany") - * res1: Array[String] = Array(Japan, Brazil, Germany) - * }}} - * - * See [[scala.reflect.api.TypeTags]] for more examples, or the - * [[http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html Reflection Guide: TypeTags]] - * for more details. - * - */ -@scala.annotation.implicitNotFound(msg = "No ClassTag available for ${T}") -trait ClassTag[T] extends ClassManifestDeprecatedApis[T] with Equals with Serializable { - // please, don't add any APIs here, like it was with `newWrappedArray` and `newArrayBuilder` - // class tags, and all tags in general, should be as minimalistic as possible - - /** A class representing the type `U` to which `T` would be erased. - * Note that there is no subtyping relationship between `T` and `U`. - */ - def runtimeClass: jClass[_] - - /** Produces a `ClassTag` that knows how to instantiate an `Array[Array[T]]` */ - def wrap: ClassTag[Array[T]] = ClassTag[Array[T]](arrayClass(runtimeClass)) - - /** Produces a new array with element type `T` and length `len` */ - override def newArray(len: Int): Array[T] = - runtimeClass match { - case java.lang.Byte.TYPE => new Array[Byte](len).asInstanceOf[Array[T]] - case java.lang.Short.TYPE => new Array[Short](len).asInstanceOf[Array[T]] - case java.lang.Character.TYPE => new Array[Char](len).asInstanceOf[Array[T]] - case java.lang.Integer.TYPE => new Array[Int](len).asInstanceOf[Array[T]] - case java.lang.Long.TYPE => new Array[Long](len).asInstanceOf[Array[T]] - case java.lang.Float.TYPE => new Array[Float](len).asInstanceOf[Array[T]] - case java.lang.Double.TYPE => new Array[Double](len).asInstanceOf[Array[T]] - case java.lang.Boolean.TYPE => new Array[Boolean](len).asInstanceOf[Array[T]] - case java.lang.Void.TYPE => new Array[Unit](len).asInstanceOf[Array[T]] - case _ => java.lang.reflect.Array.newInstance(runtimeClass, len).asInstanceOf[Array[T]] - } - - /** A ClassTag[T] can serve as an extractor that matches only objects of type T. - * - * The compiler tries to turn unchecked type tests in pattern matches into checked ones - * by wrapping a `(_: T)` type pattern as `ct(_: T)`, where `ct` is the `ClassTag[T]` instance. - * Type tests necessary before calling other extractors are treated similarly. - * `SomeExtractor(...)` is turned into `ct(SomeExtractor(...))` if `T` in `SomeExtractor.unapply(x: T)` - * is uncheckable, but we have an instance of `ClassTag[T]`. - */ - def unapply(x: Any): Option[T] = x match { - case null => None - case b: Byte => unapply(b) - case s: Short => unapply(s) - case c: Char => unapply(c) - case i: Int => unapply(i) - case l: Long => unapply(l) - case f: Float => unapply(f) - case d: Double => unapply(d) - case b: Boolean => unapply(b) - case u: Unit => unapply(u) - case a: Any => unapplyImpl(a) - } - - // TODO: Inline the bodies of these into the Any-accepting unapply overload above and delete them. - // This cannot be done until at least 2.12.0 for reasons of binary compatibility - def unapply(x: Byte) : Option[T] = unapplyImpl(x, classOf[Byte]) - def unapply(x: Short) : Option[T] = unapplyImpl(x, classOf[Short]) - def unapply(x: Char) : Option[T] = unapplyImpl(x, classOf[Char]) - def unapply(x: Int) : Option[T] = unapplyImpl(x, classOf[Int]) - def unapply(x: Long) : Option[T] = unapplyImpl(x, classOf[Long]) - def unapply(x: Float) : Option[T] = unapplyImpl(x, classOf[Float]) - def unapply(x: Double) : Option[T] = unapplyImpl(x, classOf[Double]) - def unapply(x: Boolean) : Option[T] = unapplyImpl(x, classOf[Boolean]) - def unapply(x: Unit) : Option[T] = unapplyImpl(x, classOf[Unit]) - - private[this] def unapplyImpl(x: Any, alternative: jClass[_] = null): Option[T] = { - val conforms = runtimeClass.isInstance(x) || (alternative != null && runtimeClass.isAssignableFrom(alternative)) - if (conforms) Some(x.asInstanceOf[T]) else None - } - - // case class accessories - override def canEqual(x: Any) = x.isInstanceOf[ClassTag[_]] - override def equals(x: Any) = x.isInstanceOf[ClassTag[_]] && this.runtimeClass == x.asInstanceOf[ClassTag[_]].runtimeClass - override def hashCode = scala.runtime.ScalaRunTime.hash(runtimeClass) - override def toString = { - def prettyprint(clazz: jClass[_]): String = - if (clazz.isArray) s"Array[${prettyprint(arrayElementClass(clazz))}]" else - clazz.getName - prettyprint(runtimeClass) - } -} - -/** - * Class tags corresponding to primitive types and constructor/extractor for ClassTags. - */ -object ClassTag { - def Byte : ClassTag[scala.Byte] = ManifestFactory.Byte - def Short : ClassTag[scala.Short] = ManifestFactory.Short - def Char : ClassTag[scala.Char] = ManifestFactory.Char - def Int : ClassTag[scala.Int] = ManifestFactory.Int - def Long : ClassTag[scala.Long] = ManifestFactory.Long - def Float : ClassTag[scala.Float] = ManifestFactory.Float - def Double : ClassTag[scala.Double] = ManifestFactory.Double - def Boolean : ClassTag[scala.Boolean] = ManifestFactory.Boolean - def Unit : ClassTag[scala.Unit] = ManifestFactory.Unit - def Any : ClassTag[scala.Any] = ManifestFactory.Any - def Object : ClassTag[java.lang.Object] = ManifestFactory.Object - def AnyVal : ClassTag[scala.AnyVal] = ManifestFactory.AnyVal - def AnyRef : ClassTag[scala.AnyRef] = ManifestFactory.AnyRef - def Nothing : ClassTag[scala.Nothing] = ManifestFactory.Nothing - def Null : ClassTag[scala.Null] = ManifestFactory.Null - - def apply[T](runtimeClass1: jClass[_]): ClassTag[T] = - runtimeClass1 match { - case java.lang.Byte.TYPE => ClassTag.Byte.asInstanceOf[ClassTag[T]] - case java.lang.Short.TYPE => ClassTag.Short.asInstanceOf[ClassTag[T]] - case java.lang.Character.TYPE => ClassTag.Char.asInstanceOf[ClassTag[T]] - case java.lang.Integer.TYPE => ClassTag.Int.asInstanceOf[ClassTag[T]] - case java.lang.Long.TYPE => ClassTag.Long.asInstanceOf[ClassTag[T]] - case java.lang.Float.TYPE => ClassTag.Float.asInstanceOf[ClassTag[T]] - case java.lang.Double.TYPE => ClassTag.Double.asInstanceOf[ClassTag[T]] - case java.lang.Boolean.TYPE => ClassTag.Boolean.asInstanceOf[ClassTag[T]] - case java.lang.Void.TYPE => ClassTag.Unit.asInstanceOf[ClassTag[T]] - case _ => - if (classOf[java.lang.Object] == runtimeClass1) - ClassTag.Object.asInstanceOf[ClassTag[T]] - else if (classOf[scala.runtime.Nothing$] == runtimeClass1) - ClassTag.Nothing.asInstanceOf[ClassTag[T]] - else if (classOf[scala.runtime.Null$] == runtimeClass1) - ClassTag.Null.asInstanceOf[ClassTag[T]] - else - new ClassClassTag[T](runtimeClass1) - } - - @inline - private final class ClassClassTag[T]( - val runtimeClass: Class[_]) extends ClassTag[T] - - def unapply[T](ctag: ClassTag[T]): Option[Class[_]] = Some(ctag.runtimeClass) -} From 149d42161bda735ae9067c817826f45657e04c7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 4 Dec 2017 14:05:24 +0100 Subject: [PATCH 0570/2665] Fix #3195: Clean up `ir.Definitions`. We only keep the essentials of the IR as a specification in `ir.Definitions`. Everything that was effectively an implementation detail of the linker was clearly moved there as such. --- .../org/scalajs/core/ir/Definitions.scala | 106 +++++++++--------- .../scala/org/scalajs/core/ir/Types.scala | 5 +- .../core/tools/linker/analyzer/Analyzer.scala | 2 +- .../core/tools/linker/analyzer/Infos.scala | 6 + .../linker/backend/emitter/ClassEmitter.scala | 60 +++++++--- .../backend/emitter/FunctionEmitter.scala | 10 +- .../tools/linker/backend/emitter/JSGen.scala | 2 +- .../core/tools/linker/checker/IRChecker.scala | 2 +- 8 files changed, 117 insertions(+), 76 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala b/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala index 360bfd8a8e..1191a77d89 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala @@ -12,69 +12,73 @@ package org.scalajs.core.ir import Types._ object Definitions { + /** `java.lang.Object`, the root of the class hierarchy. */ val ObjectClass = "O" - val ClassClass = "jl_Class" - val StringClass = "T" - - val PrimitiveClasses = Set("V", "Z", "C", "B", "S", "I", "J", "F", "D") - - def isPrimitiveClass(encodedName: String): Boolean = - PrimitiveClasses.contains(encodedName) + // Primitive "classes" + val VoidClass = "V" + val BooleanClass = "Z" + val CharClass = "C" + val ByteClass = "B" + val ShortClass = "S" + val IntClass = "I" + val LongClass = "J" + val FloatClass = "F" + val DoubleClass = "D" + + /** The set of all primitive classes. */ + val PrimitiveClasses: Set[String] = Set( + VoidClass, + BooleanClass, + CharClass, + ByteClass, + ShortClass, + IntClass, + LongClass, + FloatClass, + DoubleClass + ) - val BoxedUnitClass = "sr_BoxedUnit" - val BoxedBooleanClass = "jl_Boolean" + // Hijacked classes + val BoxedUnitClass = "sr_BoxedUnit" + val BoxedBooleanClass = "jl_Boolean" val BoxedCharacterClass = "jl_Character" - val BoxedByteClass = "jl_Byte" - val BoxedShortClass = "jl_Short" - val BoxedIntegerClass = "jl_Integer" - val BoxedLongClass = "jl_Long" - val BoxedFloatClass = "jl_Float" - val BoxedDoubleClass = "jl_Double" - - val CharSequenceClass = "jl_CharSequence" - val SerializableClass = "Ljava_io_Serializable" - val CloneableClass = "jl_Cloneable" - val ComparableClass = "jl_Comparable" - val NumberClass = "jl_Number" - - val HijackedBoxedClasses = Set( - BoxedUnitClass, BoxedBooleanClass, BoxedCharacterClass, BoxedByteClass, - BoxedShortClass, BoxedIntegerClass, BoxedLongClass, BoxedFloatClass, - BoxedDoubleClass) - val HijackedClasses = - HijackedBoxedClasses + StringClass - - val AncestorsOfStringClass = Set( - CharSequenceClass, ComparableClass, SerializableClass) - val AncestorsOfBoxedCharacterClass = Set( - ComparableClass, SerializableClass) - val AncestorsOfHijackedNumberClasses = Set( - NumberClass, ComparableClass, SerializableClass) - val AncestorsOfBoxedBooleanClass = Set( - ComparableClass, SerializableClass) - val AncestorsOfBoxedUnitClass = Set( - SerializableClass) - - val AncestorsOfHijackedClasses = - AncestorsOfStringClass ++ AncestorsOfHijackedNumberClasses ++ - AncestorsOfBoxedBooleanClass ++ AncestorsOfBoxedUnitClass + val BoxedByteClass = "jl_Byte" + val BoxedShortClass = "jl_Short" + val BoxedIntegerClass = "jl_Integer" + val BoxedLongClass = "jl_Long" + val BoxedFloatClass = "jl_Float" + val BoxedDoubleClass = "jl_Double" + val StringClass = "T" // TODO This should probably be called BoxedStringClass + + /** The set of all hijacked classes. */ + val HijackedClasses: Set[String] = Set( + BoxedUnitClass, + BoxedBooleanClass, + BoxedCharacterClass, + BoxedByteClass, + BoxedShortClass, + BoxedIntegerClass, + BoxedLongClass, + BoxedFloatClass, + BoxedDoubleClass, + StringClass + ) + // TODO Null and Nothing should have the same status as primitives, I think + + /** The class corresponding to `NullType`. */ val RuntimeNullClass = "sr_Null$" - val RuntimeNothingClass = "sr_Nothing$" - val ThrowableClass = "jl_Throwable" + /** The class corresponding to `NothingType`. */ + val RuntimeNothingClass = "sr_Nothing$" - val PseudoArrayClass = "s_Array" - val AncestorsOfPseudoArrayClass = Set( - ObjectClass, SerializableClass, CloneableClass) + /** The class of things returned by `ClassOf` and `GetClass`. */ + val ClassClass = "jl_Class" /** Name of the static initializer method. */ final val StaticInitializerName = "clinit___" - /** Name used for infos of top-level exports. */ - val TopLevelExportsName = "__topLevelExports" - /** Encodes a class name. */ def encodeClassName(fullName: String): String = { val base = fullName.replace("_", "$und").replace(".", "_") diff --git a/ir/src/main/scala/org/scalajs/core/ir/Types.scala b/ir/src/main/scala/org/scalajs/core/ir/Types.scala index 926bd875d0..a5658458a1 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Types.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Types.scala @@ -15,6 +15,9 @@ import Trees._ object Types { + private val AncestorsOfPseudoArrayClass = + Set(Definitions.ObjectClass, "Ljava_io_Serializable", "jl_Cloneable") + /** Type of a term (expression or statement) in the IR. * * There is a many-to-one relationship from [[TypeRef]]s to `Type`s, @@ -237,7 +240,7 @@ object Types { rhsBase == ObjectClass // because Array[Array[A]] <: Array[Object] } else { // lhsDims == rhsDims // lhsBase must be <: rhsBase - if (isPrimitiveClass(lhsBase) || isPrimitiveClass(rhsBase)) { + if (PrimitiveClasses(lhsBase) || PrimitiveClasses(rhsBase)) { lhsBase == rhsBase } else { /* All things must be considered subclasses of Object for this diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala index 508c87d348..18d02411d6 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala @@ -946,7 +946,7 @@ private final class Analyzer(config: CommonPhaseConfig, val methodsCalledIterator = data.methodsCalled.iterator while (methodsCalledIterator.hasNext) { val (className, methods) = methodsCalledIterator.next() - if (className == Definitions.PseudoArrayClass) { + if (className == Infos.PseudoArrayClass) { /* The pseudo Array class is not reified in our analyzer/analysis, * so we need to cheat here. * In the Array[T] class family, only clone__O is defined and diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala index 429e9f7b6e..9e723d95c1 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala @@ -21,6 +21,12 @@ import org.scalajs.core.tools.linker.LinkedClass object Infos { + /** A pseudo class to reify arrays in Infos. */ + val PseudoArrayClass = "s_Array" + + /** Name used for infos of top-level exports. */ + private val TopLevelExportsName = "__topLevelExports" + final class ClassInfo private ( val encodedName: String, val isExported: Boolean, diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index f5a87c4a70..2a85d430cc 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -686,15 +686,15 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val displayName = decodeClassName(className) val isAncestorOfString = - AncestorsOfStringClass.contains(className) + NonObjectAncestorsOfStringClass.contains(className) val isAncestorOfHijackedNumberClass = - AncestorsOfHijackedNumberClasses.contains(className) + NonObjectAncestorsOfHijackedNumberClasses.contains(className) val isAncestorOfBoxedBooleanClass = - AncestorsOfBoxedBooleanClass.contains(className) + NonObjectAncestorsOfBoxedBooleanClass.contains(className) val isAncestorOfBoxedCharacterClass = - AncestorsOfBoxedCharacterClass.contains(className) + NonObjectAncestorsOfBoxedCharacterClass.contains(className) val isAncestorOfBoxedUnitClass = - AncestorsOfBoxedUnitClass.contains(className) + NonObjectAncestorsOfBoxedUnitClass.contains(className) val objParam = js.ParamDef(js.Ident("obj"), rest = false) val obj = objParam.ref @@ -866,8 +866,8 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val isObjectClass = className == ObjectClass - val isHijackedBoxedClass = - HijackedBoxedClasses.contains(className) + val isHijackedClass = + HijackedClasses.contains(className) val isAncestorOfHijackedClass = isObjectClass || AncestorsOfHijackedClasses.contains(className) val isJSType = @@ -892,18 +892,18 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { tree.ancestors.map(ancestor => (js.Ident(ancestor), js.IntLiteral(1)))) val isInstanceFunWithGlobals: WithGlobals[js.Tree] = { - if (isHijackedBoxedClass) { - /* Hijacked boxed classes have a special isInstanceOf test. */ - val xParam = js.ParamDef(js.Ident("x"), rest = false) - WithGlobals(js.Function(List(xParam), js.Return { - genIsInstanceOf(xParam.ref, ClassRef(className)) - })) - } else if (isAncestorOfHijackedClass || className == StringClass) { + if (isAncestorOfHijackedClass || className == StringClass) { /* java.lang.String and ancestors of hijacked classes, including * java.lang.Object, have a normal $is_pack_Class test but with a * non-standard behavior. */ WithGlobals(envField("is", className)) + } else if (isHijackedClass) { + /* Other hijacked classes have a special isInstanceOf test. */ + val xParam = js.ParamDef(js.Ident("x"), rest = false) + WithGlobals(js.Function(List(xParam), js.Return { + genIsInstanceOf(xParam.ref, ClassRef(className)) + })) } else if (isJSType) { /* Native JS classes have an instanceof operator-based isInstanceOf * test dictated by their jsNativeLoadSpec. @@ -1302,8 +1302,32 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { } private object ClassEmitter { - private val ClassesWhoseDataReferToTheirInstanceTests = { - Definitions.AncestorsOfHijackedClasses + - Definitions.ObjectClass + Definitions.StringClass - } + // TODO We should compute all of those from the Class Hierarchy + + private val CharSequenceClass = "jl_CharSequence" + private val SerializableClass = "Ljava_io_Serializable" + private val ComparableClass = "jl_Comparable" + private val NumberClass = "jl_Number" + + private val NonObjectAncestorsOfStringClass = + Set(CharSequenceClass, ComparableClass, SerializableClass) + private val NonObjectAncestorsOfBoxedCharacterClass = + Set(ComparableClass, SerializableClass) + private val NonObjectAncestorsOfHijackedNumberClasses = + Set(NumberClass, ComparableClass, SerializableClass) + private val NonObjectAncestorsOfBoxedBooleanClass = + Set(ComparableClass, SerializableClass) + private val NonObjectAncestorsOfBoxedUnitClass = + Set(SerializableClass) + + private[emitter] val AncestorsOfHijackedClasses = Set( + Definitions.ObjectClass, + CharSequenceClass, + SerializableClass, + ComparableClass, + NumberClass + ) + + private val ClassesWhoseDataReferToTheirInstanceTests = + AncestorsOfHijackedClasses + Definitions.StringClass } diff --git 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 index 3258071ada..f82b5cea9d 100644 --- 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 @@ -1983,7 +1983,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { */ genDispatchApply() - case ClassType(CharSequenceClass) + case ClassType("jl_CharSequence") if !hijackedMethodsOfStringWithDispatcher.contains(methodName) => /* This case is required as a hack around a peculiar behavior * of the optimizer. In theory, it should never happen, because @@ -2435,8 +2435,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { def isMaybeHijackedClass(tpe: Type): Boolean = tpe match { case ClassType(cls) => - Definitions.HijackedClasses.contains(cls) || - Definitions.AncestorsOfHijackedClasses.contains(cls) + MaybeHijackedClasses.contains(cls) case AnyType | UndefType | BooleanType | CharType | ByteType | ShortType | IntType | LongType | FloatType | DoubleType | StringType => true @@ -2553,6 +2552,11 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { } private object FunctionEmitter { + private val MaybeHijackedClasses = { + (Definitions.HijackedClasses ++ ClassEmitter.AncestorsOfHijackedClasses) - + Definitions.ObjectClass + } + /** A left hand side that can be pushed into a right hand side tree. */ sealed abstract class Lhs { def hasNothingType: Boolean = false diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala index df3cc1b487..88f93250af 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala @@ -104,7 +104,7 @@ private[emitter] final class JSGen(val semantics: Semantics, if (className0 == BoxedLongClass) LongImpl.RuntimeLongClass else className0 - if (HijackedBoxedClasses.contains(className)) { + if (HijackedClasses.contains(className) && className != StringClass) { if (test) { className match { case BoxedUnitClass => expr === Undefined() diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 0772953e87..acc9a34d51 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -1120,7 +1120,7 @@ private final class IRChecker(unit: LinkingUnit, implicit ctx: ErrorContext): Unit = { typeRef match { case ClassRef(encodedName) => - if (Definitions.isPrimitiveClass(encodedName)) { + if (Definitions.PrimitiveClasses.contains(encodedName)) { reportError( s"Primitive type $encodedName is not a valid target type for " + "Is/AsInstanceOf") From f17012298e5c3f7a5dd9188f856dcd6388cc7d6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 4 Dec 2017 14:44:09 +0100 Subject: [PATCH 0571/2665] Get rid of `Infos.PseudoArrayClass`. We do this by moving back to `Infos` the "cheat" for the reachability of method calls on Arrays. The existing comment actually makes more sense now, since Arrays are truly not reified in the analyzer/analysis anymore. --- .../core/tools/linker/analyzer/Analyzer.scala | 23 +++---------------- .../core/tools/linker/analyzer/Infos.scala | 17 ++++++++++---- 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala index 18d02411d6..64c1cd3415 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala @@ -946,26 +946,9 @@ private final class Analyzer(config: CommonPhaseConfig, val methodsCalledIterator = data.methodsCalled.iterator while (methodsCalledIterator.hasNext) { val (className, methods) = methodsCalledIterator.next() - if (className == Infos.PseudoArrayClass) { - /* The pseudo Array class is not reified in our analyzer/analysis, - * so we need to cheat here. - * In the Array[T] class family, only clone__O is defined and - * overrides j.l.Object.clone__O. Since this method is implemented - * in scalajsenv.js and always kept, we can ignore it. - * All other methods resolve to their definition in Object, so we - * can model their reachability by calling them statically in the - * Object class. - */ - val objectClass = lookupClass(Definitions.ObjectClass) - for (methodName <- methods) { - if (methodName != "clone__O") - objectClass.callMethodStatically(methodName) - } - } else { - val classInfo = lookupClass(className) - for (methodName <- methods) - classInfo.callMethod(methodName) - } + val classInfo = lookupClass(className) + for (methodName <- methods) + classInfo.callMethod(methodName) } val methodsCalledStaticallyIterator = data.methodsCalledStatically.iterator diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala index 9e723d95c1..cbe844b828 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala @@ -21,9 +21,6 @@ import org.scalajs.core.tools.linker.LinkedClass object Infos { - /** A pseudo class to reify arrays in Infos. */ - val PseudoArrayClass = "s_Array" - /** Name used for infos of top-level exports. */ private val TopLevelExportsName = "__topLevelExports" @@ -208,7 +205,19 @@ object Infos { case FloatType => addMethodCalled(BoxedFloatClass, method) case DoubleType => addMethodCalled(BoxedDoubleClass, method) case StringType => addMethodCalled(StringClass, method) - case ArrayType(_) => addMethodCalled(PseudoArrayClass, method) + + case ArrayType(_) => + /* The pseudo Array class is not reified in our analyzer/analysis, + * so we need to cheat here. + * In the Array[T] class family, only clone__O is defined and + * overrides j.l.Object.clone__O. Since this method is implemented + * in scalajsenv.js and always kept, we can ignore it. + * All other methods resolve to their definition in Object, so we + * can model their reachability by calling them statically in the + * Object class. + */ + if (method != "clone__O") + addMethodCalledStatically(ObjectClass, method) case NullType | NothingType => // Nothing to do From 956b66e08d768ea38c5f90640895515c3c94af2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 4 Dec 2017 22:40:50 +0100 Subject: [PATCH 0572/2665] Rename `ir.Definitions.StringClass` to `BoxedStringClass`. This makes more sense if we consider that `java.lang.String` is the hijacked *boxed* class for the primitive type `StringType`. --- .../org/scalajs/core/compiler/GenJSExports.scala | 2 +- .../scala/org/scalajs/core/compiler/JSEncoding.scala | 2 +- .../main/scala/org/scalajs/core/ir/Definitions.scala | 4 ++-- ir/src/main/scala/org/scalajs/core/ir/Types.scala | 2 +- .../test/scala/org/scalajs/core/ir/PrintersTest.scala | 4 ++-- project/JavaLangObject.scala | 8 ++++---- .../scalajs/core/tools/linker/analyzer/Infos.scala | 2 +- .../tools/linker/backend/emitter/ClassEmitter.scala | 11 ++++++----- .../linker/backend/emitter/FunctionEmitter.scala | 4 ++-- .../core/tools/linker/backend/emitter/JSGen.scala | 2 +- .../scalajs/core/tools/linker/checker/IRChecker.scala | 2 +- .../linker/frontend/optimizer/OptimizerCore.scala | 4 ++-- 12 files changed, 24 insertions(+), 23 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index 6b4a2cfe63..deb6f7d286 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -1023,7 +1023,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => case REFERENCE(cls) => cls match { case BoxedUnitClass => HijackedTypeTest(Defs.BoxedUnitClass, 0) - case StringClass => HijackedTypeTest(Defs.StringClass, 9) + case StringClass => HijackedTypeTest(Defs.BoxedStringClass, 9) case ObjectClass => NoTypeTest case _ => if (isJSType(cls)) NoTypeTest diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala index be1540099f..213eb7fc29 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala @@ -226,7 +226,7 @@ trait JSEncoding extends SubComponent { self: GenJSCode => def encodeClassFullName(sym: Symbol): String = { if (sym == jsDefinitions.HackedStringClass) { - ir.Definitions.StringClass + ir.Definitions.BoxedStringClass } else if (sym == jsDefinitions.HackedStringModClass) { "jl_String$" } else { diff --git a/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala b/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala index 1191a77d89..5519edf744 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala @@ -49,7 +49,7 @@ object Definitions { val BoxedLongClass = "jl_Long" val BoxedFloatClass = "jl_Float" val BoxedDoubleClass = "jl_Double" - val StringClass = "T" // TODO This should probably be called BoxedStringClass + val BoxedStringClass = "T" /** The set of all hijacked classes. */ val HijackedClasses: Set[String] = Set( @@ -62,7 +62,7 @@ object Definitions { BoxedLongClass, BoxedFloatClass, BoxedDoubleClass, - StringClass + BoxedStringClass ) // TODO Null and Nothing should have the same status as primitives, I think diff --git a/ir/src/main/scala/org/scalajs/core/ir/Types.scala b/ir/src/main/scala/org/scalajs/core/ir/Types.scala index a5658458a1..0700aeead3 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Types.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Types.scala @@ -230,7 +230,7 @@ object Types { case (DoubleType, ClassType(cls)) => isSubclass(BoxedDoubleClass, cls) case (StringType, ClassType(cls)) => - isSubclass(StringClass, cls) + isSubclass(BoxedStringClass, cls) case (ArrayType(ArrayTypeRef(lhsBase, lhsDims)), ArrayType(ArrayTypeRef(rhsBase, rhsDims))) => diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala index cc43bccc6e..4e6c020832 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala @@ -550,12 +550,12 @@ class PrintersTest { @Test def printIsInstanceOf(): Unit = { assertPrintEquals("x.isInstanceOf[T]", - IsInstanceOf(ref("x", AnyType), StringClass)) + IsInstanceOf(ref("x", AnyType), BoxedStringClass)) } @Test def printAsInstanceOf(): Unit = { assertPrintEquals("x.asInstanceOf[T]", - AsInstanceOf(ref("x", AnyType), StringClass)) + AsInstanceOf(ref("x", AnyType), BoxedStringClass)) } @Test def printUnbox(): Unit = { diff --git a/project/JavaLangObject.scala b/project/JavaLangObject.scala index 17e47e7623..831a0e4a41 100644 --- a/project/JavaLangObject.scala +++ b/project/JavaLangObject.scala @@ -105,14 +105,14 @@ object JavaLangObject { static = false, Ident("toString__T", Some("toString__T")), Nil, - ClassType(StringClass), + ClassType(BoxedStringClass), Some { BinaryOp(BinaryOp.String_+, BinaryOp(BinaryOp.String_+, Apply( Apply(This()(ThisType), Ident("getClass__jl_Class", Some("getClass__jl_Class")), Nil)( ClassType(ClassClass)), - Ident("getName__T"), Nil)(ClassType(StringClass)), + Ident("getName__T"), Nil)(ClassType(BoxedStringClass)), // + StringLiteral("@")), // + @@ -120,7 +120,7 @@ object JavaLangObject { LoadModule(ClassType("jl_Integer$")), Ident("toHexString__I__T"), List(Apply(This()(ThisType), Ident("hashCode__I"), Nil)(IntType)))( - ClassType(StringClass))) + ClassType(BoxedStringClass))) })(OptimizerHints.empty, None), /* Since wait() is not supported in any way, a correct implementation @@ -162,7 +162,7 @@ object JavaLangObject { Some { Apply(This()(ThisType), Ident("toString__T", Some("toString__T")), - Nil)(ClassType(StringClass)) + Nil)(ClassType(BoxedStringClass)) })(OptimizerHints.empty, None) ), Nil)(OptimizerHints.empty) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala index cbe844b828..1dd10e5060 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala @@ -204,7 +204,7 @@ object Infos { case LongType => addMethodCalled(BoxedLongClass, method) case FloatType => addMethodCalled(BoxedFloatClass, method) case DoubleType => addMethodCalled(BoxedDoubleClass, method) - case StringType => addMethodCalled(StringClass, method) + case StringType => addMethodCalled(BoxedStringClass, method) case ArrayType(_) => /* The pseudo Array class is not reified in our analyzer/analysis, diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index 2a85d430cc..f9caae231d 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -681,7 +681,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { implicit val pos = tree.pos if (tree.kind.isClass || tree.kind == ClassKind.Interface || - tree.name.name == Definitions.StringClass) { + tree.name.name == Definitions.BoxedStringClass) { val className = tree.name.name val displayName = decodeClassName(className) @@ -705,7 +705,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { case Definitions.ObjectClass => js.BinaryOp(JSBinaryOp.!==, obj, js.Null()) - case Definitions.StringClass => + case Definitions.BoxedStringClass => js.UnaryOp(JSUnaryOp.typeof, obj) === js.StringLiteral("string") case Definitions.RuntimeNothingClass => @@ -892,7 +892,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { tree.ancestors.map(ancestor => (js.Ident(ancestor), js.IntLiteral(1)))) val isInstanceFunWithGlobals: WithGlobals[js.Tree] = { - if (isAncestorOfHijackedClass || className == StringClass) { + if (isAncestorOfHijackedClass || className == BoxedStringClass) { /* java.lang.String and ancestors of hijacked classes, including * java.lang.Object, have a normal $is_pack_Class test but with a * non-standard behavior. @@ -1284,6 +1284,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { /** Gen JS code for an [[ModuleInitializer]]. */ def genModuleInitializer(moduleInitializer: ModuleInitializer): js.Tree = { import TreeDSL._ + import Definitions.BoxedStringClass implicit val pos = Position.NoPosition @@ -1293,7 +1294,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { case ModuleInitializer.MainMethodWithArgs(moduleClassName, mainMethodName, args) => - val stringArrayTpe = ArrayType(ArrayTypeRef("T", 1)) + val stringArrayTpe = ArrayType(ArrayTypeRef(BoxedStringClass, 1)) js.Apply(genLoadModule(moduleClassName) DOT mainMethodName, genArrayValue(stringArrayTpe, args.map(js.StringLiteral(_))) :: Nil) } @@ -1329,5 +1330,5 @@ private object ClassEmitter { ) private val ClassesWhoseDataReferToTheirInstanceTests = - AncestorsOfHijackedClasses + Definitions.StringClass + AncestorsOfHijackedClasses + Definitions.BoxedStringClass } diff --git 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 index f82b5cea9d..c5b53e16d0 100644 --- 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 @@ -2003,7 +2003,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { * implementing them, which prevents that form of inlining from * happening. */ - genHijackedMethodApply(StringClass) + genHijackedMethodApply(BoxedStringClass) case ClassType(cls) if !HijackedClasses.contains(cls) => /* This is a strict ancestor of a hijacked class. We need to @@ -2455,7 +2455,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case LongType => Definitions.BoxedLongClass case FloatType => Definitions.BoxedFloatClass case DoubleType => Definitions.BoxedDoubleClass - case StringType => Definitions.StringClass + case StringType => Definitions.BoxedStringClass } /* Ideally, we should dynamically figure out this set. We should test diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala index 88f93250af..66d3b8d1e7 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala @@ -104,7 +104,7 @@ private[emitter] final class JSGen(val semantics: Semantics, if (className0 == BoxedLongClass) LongImpl.RuntimeLongClass else className0 - if (HijackedClasses.contains(className) && className != StringClass) { + if (HijackedClasses.contains(className) && className != BoxedStringClass) { if (test) { className match { case BoxedUnitClass => expr === Undefined() diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index acc9a34d51..603f4411e4 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -1177,7 +1177,7 @@ private final class IRChecker(unit: LinkingUnit, case 'F' => FloatType case 'D' => DoubleType case 'O' => AnyType - case 'T' => ClassType(StringClass) // NOT StringType + case 'T' => ClassType(BoxedStringClass) // NOT StringType } } else if (encodedName == "sr_Nothing$") { NothingType diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index a0e871d213..eb82315424 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -1517,7 +1517,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case LongType => LongImpl.RuntimeLongClass case FloatType => Definitions.BoxedFloatClass case DoubleType => Definitions.BoxedDoubleClass - case StringType => Definitions.StringClass + case StringType => Definitions.BoxedStringClass case ArrayType(_) => Definitions.ObjectClass } @@ -1932,7 +1932,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { @inline def contTree(result: Tree) = cont(result.toPreTransform) - @inline def StringClassType = ClassType(Definitions.StringClass) + @inline def StringClassType = ClassType(Definitions.BoxedStringClass) def defaultApply(methodName: String, resultType: Type): TailRec[Tree] = contTree(Apply(newReceiver, Ident(methodName), newArgs)(resultType)) From 94b5ab997cd39e401f364afc9d218ddbc9795480 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 5 Dec 2017 15:23:39 +0100 Subject: [PATCH 0573/2665] Remove dead code in `ir.Definitions.{encode,decode}ClassName`. By construction, the encoded part either starts with one of the compressed prefixes, or with 'L'. Therefore, it cannot possibly be a reserved word nor start with a digit nor a dollar sign. --- .../org/scalajs/core/ir/Definitions.scala | 25 +++++++------------ .../scala/scalajs/runtime/StackTrace.scala | 15 +++++------ 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala b/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala index 5519edf744..070da5d438 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala @@ -82,35 +82,28 @@ object Definitions { /** Encodes a class name. */ def encodeClassName(fullName: String): String = { val base = fullName.replace("_", "$und").replace(".", "_") - val encoded = compressedClasses.getOrElse(base, { - compressedPrefixes collectFirst { + compressedClasses.getOrElse(base, { + compressedPrefixes.collectFirst { case (prefix, compressed) if base.startsWith(prefix) => compressed + base.substring(prefix.length) } getOrElse { - "L"+base + "L" + base } }) - if (Trees.isKeyword(encoded) || encoded.charAt(0).isDigit || - encoded.charAt(0) == '$') { - "$" + encoded - } else encoded } // !!! Duplicate logic: this code must be in sync with runtime.StackTrace /** Decodes a class name encoded with [[encodeClassName]]. */ def decodeClassName(encodedName: String): String = { - val encoded = - if (encodedName.charAt(0) == '$') encodedName.substring(1) - else encodedName - val base = decompressedClasses.getOrElse(encoded, { - decompressedPrefixes collectFirst { - case (prefix, decompressed) if encoded.startsWith(prefix) => - decompressed + encoded.substring(prefix.length) + val base = decompressedClasses.getOrElse(encodedName, { + decompressedPrefixes.collectFirst { + case (prefix, decompressed) if encodedName.startsWith(prefix) => + decompressed + encodedName.substring(prefix.length) } getOrElse { - assert(!encoded.isEmpty && encoded.charAt(0) == 'L', + assert(!encodedName.isEmpty && encodedName.charAt(0) == 'L', s"Cannot decode invalid encoded name '$encodedName'") - encoded.substring(1) + encodedName.substring(1) } }) base.replace("_", ".").replace("$und", "_") diff --git a/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala b/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala index 91a493ecfb..48427fafc9 100644 --- a/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala +++ b/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala @@ -213,24 +213,21 @@ object StackTrace { // !!! Duplicate logic: this code must be in sync with ir.Definitions private def decodeClassName(encodedName: String): String = { - val encoded = - if (encodedName.charAt(0) == '$') encodedName.substring(1) - else encodedName - val base = if (decompressedClasses.contains(encoded)) { - decompressedClasses(encoded) + val base = if (decompressedClasses.contains(encodedName)) { + decompressedClasses(encodedName) } else { @tailrec def loop(i: Int): String = { if (i < compressedPrefixes.length) { val prefix = compressedPrefixes(i) - if (encoded.startsWith(prefix)) - decompressedPrefixes(prefix) + encoded.substring(prefix.length) + if (encodedName.startsWith(prefix)) + decompressedPrefixes(prefix) + encodedName.substring(prefix.length) else loop(i+1) } else { // no prefix matches - if (encoded.startsWith("L")) encoded.substring(1) - else encoded // just in case + if (encodedName.startsWith("L")) encodedName.substring(1) + else encodedName // just in case } } loop(0) From d3e9ebf6b97ac97a44fee63886566cf611017479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 5 Dec 2017 15:51:12 +0100 Subject: [PATCH 0574/2665] Do not accept primitive types in `ir.{encode,decode}ClassName`. Accepting primitive types was problematic because their decoded form was very tight to Scala as a source language. Now, they only accept *class* names, and primitives must be dealt with separately. --- .../scalajs/core/compiler/JSEncoding.scala | 2 ++ .../org/scalajs/core/compiler/TypeKinds.scala | 16 ++++++++++++---- .../org/scalajs/core/ir/Definitions.scala | 11 +---------- .../scala/scalajs/runtime/StackTrace.scala | 11 +---------- .../core/tools/linker/analyzer/Analysis.scala | 19 +++++++++++++++++-- 5 files changed, 33 insertions(+), 26 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala index 213eb7fc29..7aabf5dfd2 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala @@ -225,6 +225,8 @@ trait JSEncoding extends SubComponent { self: GenJSCode => } def encodeClassFullName(sym: Symbol): String = { + assert(!sym.isPrimitiveValueClass, + s"Illegal encodeClassFullName(${sym.fullName}") if (sym == jsDefinitions.HackedStringClass) { ir.Definitions.BoxedStringClass } else if (sym == jsDefinitions.HackedStringModClass) { diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/TypeKinds.scala b/compiler/src/main/scala/org/scalajs/core/compiler/TypeKinds.scala index 20ee759cf6..e9e8b9adcc 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/TypeKinds.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/TypeKinds.scala @@ -63,14 +63,16 @@ trait TypeKinds extends SubComponent { this: GenJSCode => sealed abstract class TypeKindButArray extends TypeKind { protected def typeSymbol: Symbol - override def toTypeRef: Types.ClassRef = - Types.ClassRef(encodeClassFullName(typeSymbol)) + def toTypeRef: Types.ClassRef } /** The void, for trees that can only appear in statement position. */ case object VOID extends TypeKindButArray { protected def typeSymbol: Symbol = UnitClass def toIRType: Types.NoType.type = Types.NoType + + val toTypeRef: Types.ClassRef = + Types.ClassRef(ir.Definitions.VoidClass) } sealed abstract class ValueTypeKind extends TypeKindButArray { @@ -87,6 +89,9 @@ trait TypeKinds extends SubComponent { this: GenJSCode => case DoubleClass => 'D' case x => abort("Unknown primitive type: " + x.fullName) } + + val toTypeRef: Types.ClassRef = + Types.ClassRef(primitiveCharCode.toString) } /** Integer number (Byte, Short, Char or Int). */ @@ -123,7 +128,7 @@ trait TypeKinds extends SubComponent { this: GenJSCode => case object NOTHING extends TypeKindButArray { protected def typeSymbol: Symbol = definitions.NothingClass def toIRType: Types.NothingType.type = Types.NothingType - override def toTypeRef: Types.ClassRef = + def toTypeRef: Types.ClassRef = Types.ClassRef(Definitions.RuntimeNothingClass) } @@ -131,7 +136,7 @@ trait TypeKinds extends SubComponent { this: GenJSCode => case object NULL extends TypeKindButArray { protected def typeSymbol: Symbol = definitions.NullClass def toIRType: Types.NullType.type = Types.NullType - override def toTypeRef: Types.ClassRef = + def toTypeRef: Types.ClassRef = Types.ClassRef(Definitions.RuntimeNullClass) } @@ -141,6 +146,9 @@ trait TypeKinds extends SubComponent { this: GenJSCode => override def isReferenceType: Boolean = true def toIRType: Types.Type = encodeClassType(typeSymbol) + + def toTypeRef: Types.ClassRef = + Types.ClassRef(encodeClassFullName(typeSymbol)) } /** An array */ diff --git a/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala b/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala index 070da5d438..778c66a850 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala @@ -111,16 +111,7 @@ object Definitions { private val compressedClasses: Map[String, String] = Map( "java_lang_Object" -> "O", - "java_lang_String" -> "T", - "scala_Unit" -> "V", - "scala_Boolean" -> "Z", - "scala_Char" -> "C", - "scala_Byte" -> "B", - "scala_Short" -> "S", - "scala_Int" -> "I", - "scala_Long" -> "J", - "scala_Float" -> "F", - "scala_Double" -> "D" + "java_lang_String" -> "T" ) ++ ( for (index <- 2 to 22) yield s"scala_Tuple$index" -> ("T"+index) diff --git a/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala b/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala index 48427fafc9..d665e92fec 100644 --- a/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala +++ b/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala @@ -238,16 +238,7 @@ object StackTrace { private lazy val decompressedClasses: js.Dictionary[String] = { val dict = js.Dynamic.literal( O = "java_lang_Object", - T = "java_lang_String", - V = "scala_Unit", - Z = "scala_Boolean", - C = "scala_Char", - B = "scala_Byte", - S = "scala_Short", - I = "scala_Int", - J = "scala_Long", - F = "scala_Float", - D = "scala_Double" + T = "java_lang_String" ).asInstanceOf[js.Dictionary[String]] var index = 0 diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala index 11895edb31..f195ba8949 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala @@ -34,6 +34,18 @@ trait Analysis { object Analysis { + private val PrimitiveClassesDisplayNames: Map[String, String] = Map( + "V" -> "void", + "Z" -> "boolean", + "C" -> "char", + "B" -> "byte", + "S" -> "short", + "I" -> "int", + "J" -> "long", + "F" -> "float", + "D" -> "double" + ) + /** Class node in a reachability graph produced by the [[Analyzer]]. * * Warning: this trait is not meant to be extended by third-party libraries @@ -89,9 +101,12 @@ object Analysis { } else { import ir.Types._ + def classDisplayName(cls: String): String = + PrimitiveClassesDisplayNames.getOrElse(cls, decodeClassName(cls)) + def typeDisplayName(tpe: TypeRef): String = tpe match { - case ClassRef(encodedName) => decodeClassName(encodedName) - case ArrayTypeRef(base, dimensions) => "[" * dimensions + decodeClassName(base) + case ClassRef(encodedName) => classDisplayName(encodedName) + case ArrayTypeRef(base, dimensions) => "[" * dimensions + classDisplayName(base) } val (simpleName, paramTypes, resultType) = From 87576136f139565c4593075ac89c17aa8f0eabf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 5 Dec 2017 14:01:56 +0100 Subject: [PATCH 0575/2665] Consolidate `NullType` and `NothingType` as primitive types. They receive the one-letter names `N` for "Null" and `E` for "Empty type" or "throws Exception", respectively. Those letters designate the `ClassRef`s for `NullType` and `NothingType`, and are used in encoded names of methods that take such types as parameters or as result types. They are accessible as `ir.Definitions.NullClass` and `ir.Definitions.NothingClass`. Similarly to `VoidClass`, arrays of `N` or `E` are illegal, and the IR checker now checks that they are not used. Moreover, and unlke `VoidClass`, even `classOf[N]` and `classOf[E]` are illegal. This means that `Array[Null]` and `Array[Nothing]` in Scala source code keep being encoded as `Array[scala.runtime.Null$]` and `Array[s.r.Nothing$]`, and similarly for `classOf[Null]` and `classOf[Nothing]`. This retains compatibility with Scala/JVM. After the changes in this commit, the IR and the Linker do not know about `s.r.Null$` and `s.r.Nothing$` anymore. --- .../org/scalajs/core/compiler/GenJSCode.scala | 27 ++++++++++---- .../scalajs/core/compiler/JSEncoding.scala | 15 ++++++-- .../org/scalajs/core/compiler/TypeKinds.scala | 6 ++- .../org/scalajs/core/ir/Definitions.scala | 14 +++---- .../scala/org/scalajs/core/ir/Trees.scala | 6 +-- .../testsuite/compiler/RuntimeTypesTest.scala | 22 +++-------- .../core/tools/linker/analyzer/Analysis.scala | 4 +- .../linker/backend/emitter/ClassEmitter.scala | 22 +++-------- .../core/tools/linker/checker/IRChecker.scala | 37 ++++++++++++++++--- 9 files changed, 88 insertions(+), 65 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 51aceee5cb..667c1d93d0 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -2416,13 +2416,9 @@ abstract class GenJSCode extends plugins.PluginComponent js.BooleanLiteral(l == r) } } else if (l.isValueType) { - val result = if (cast) { - val ctor = ClassCastExceptionClass.info.member( - nme.CONSTRUCTOR).suchThat(_.tpe.params.isEmpty) - js.Throw(genNew(ClassCastExceptionClass, ctor, Nil)) - } else { - js.BooleanLiteral(false) - } + val result = + if (cast) genThrowClassCastException() + else js.BooleanLiteral(false) js.Block(expr, result) // eval and discard source } else if (r.isValueType) { assert(!cast, s"Unexpected asInstanceOf from ref type to value type") @@ -2435,6 +2431,12 @@ abstract class GenJSCode extends plugins.PluginComponent } } + private def genThrowClassCastException()(implicit pos: Position): js.Tree = { + val ctor = ClassCastExceptionClass.info.member( + nme.CONSTRUCTOR).suchThat(_.tpe.params.isEmpty) + js.Throw(genNew(ClassCastExceptionClass, ctor, Nil)) + } + /** Gen JS code for a super call, of the form Class.super[mix].fun(args). * * This does not include calls defined in mixin traits, as these are @@ -2773,6 +2775,9 @@ abstract class GenJSCode extends plugins.PluginComponent js.JSBinaryOp.instanceof, value, genPrimitiveJSClass(sym)), 'Z') } } else { + // The Scala type system prevents x.isInstanceOf[Null] and ...[Nothing] + assert(sym != NullClass && sym != NothingClass, + s"Found a .isInstanceOf[$sym] at $pos") js.IsInstanceOf(value, toTypeRef(to)) } } @@ -2800,6 +2805,14 @@ abstract class GenJSCode extends plugins.PluginComponent case JSFunctionToScala(fun, _) => value case _ => default } + } else if (sym == NullClass) { + js.If( + js.BinaryOp(js.BinaryOp.===, value, js.Null()), + js.Null(), + genThrowClassCastException())( + jstpe.NullType) + } else if (sym == NothingClass) { + js.Block(value, genThrowClassCastException()) } else { default } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala index 7aabf5dfd2..1732971e43 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala @@ -280,10 +280,19 @@ trait JSEncoding extends SubComponent { self: GenJSCode => private def internalName(kind: TypeKind): String = kind match { case VOID => "V" case kind: ValueTypeKind => kind.primitiveCharCode.toString() - case NOTHING => ir.Definitions.RuntimeNothingClass - case NULL => ir.Definitions.RuntimeNullClass + case NOTHING => ir.Definitions.NothingClass + case NULL => ir.Definitions.NullClass case REFERENCE(cls) => encodeClassFullName(cls) - case ARRAY(elem) => "A"+internalName(elem) + case ARRAY(elem) => "A" + internalArrayElemName(elem) + } + + private def internalArrayElemName(kind: TypeKind): String = kind match { + case VOID => "V" + case kind: ValueTypeKind => kind.primitiveCharCode.toString() + case NOTHING => encodeClassFullName(definitions.RuntimeNothingClass) + case NULL => encodeClassFullName(definitions.RuntimeNullClass) + case REFERENCE(cls) => encodeClassFullName(cls) + case ARRAY(elem) => "A" + internalArrayElemName(elem) } /** mangles names that are illegal in JavaScript by prepending a $ diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/TypeKinds.scala b/compiler/src/main/scala/org/scalajs/core/compiler/TypeKinds.scala index e9e8b9adcc..9bc68a5ba0 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/TypeKinds.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/TypeKinds.scala @@ -128,16 +128,18 @@ trait TypeKinds extends SubComponent { this: GenJSCode => case object NOTHING extends TypeKindButArray { protected def typeSymbol: Symbol = definitions.NothingClass def toIRType: Types.NothingType.type = Types.NothingType + def toTypeRef: Types.ClassRef = - Types.ClassRef(Definitions.RuntimeNothingClass) + Types.ClassRef(encodeClassFullName(definitions.RuntimeNothingClass)) } /** Null */ case object NULL extends TypeKindButArray { protected def typeSymbol: Symbol = definitions.NullClass def toIRType: Types.NullType.type = Types.NullType + def toTypeRef: Types.ClassRef = - Types.ClassRef(Definitions.RuntimeNullClass) + Types.ClassRef(encodeClassFullName(definitions.RuntimeNullClass)) } /** An object */ diff --git a/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala b/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala index 778c66a850..311632a8e9 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala @@ -25,6 +25,8 @@ object Definitions { val LongClass = "J" val FloatClass = "F" val DoubleClass = "D" + val NullClass = "N" + val NothingClass = "E" // think "the Empty type", or "throws an Exception" /** The set of all primitive classes. */ val PrimitiveClasses: Set[String] = Set( @@ -36,7 +38,9 @@ object Definitions { IntClass, LongClass, FloatClass, - DoubleClass + DoubleClass, + NullClass, + NothingClass ) // Hijacked classes @@ -65,14 +69,6 @@ object Definitions { BoxedStringClass ) - // TODO Null and Nothing should have the same status as primitives, I think - - /** The class corresponding to `NullType`. */ - val RuntimeNullClass = "sr_Null$" - - /** The class corresponding to `NothingType`. */ - val RuntimeNothingClass = "sr_Nothing$" - /** The class of things returned by `ClassOf` and `GetClass`. */ val ClassClass = "jl_Class" diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 0ce2d832b0..9d8cbdb3b9 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -440,10 +440,8 @@ object Trees { case class AsInstanceOf(expr: Tree, typeRef: TypeRef)( implicit val pos: Position) extends Tree { val tpe = typeRef match { - case ClassRef(Definitions.RuntimeNullClass) => NullType - case ClassRef(Definitions.RuntimeNothingClass) => NothingType - case ClassRef(className) => ClassType(className) - case typeRef: ArrayTypeRef => ArrayType(typeRef) + case ClassRef(className) => ClassType(className) + case typeRef: ArrayTypeRef => ArrayType(typeRef) } } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RuntimeTypesTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RuntimeTypesTest.scala index de0fd2523c..bf801a955c 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RuntimeTypesTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RuntimeTypesTest.scala @@ -17,6 +17,7 @@ import org.junit.Test import org.junit.Assert._ import org.junit.Assume._ +import org.scalajs.testsuite.utils.AssertThrows._ import org.scalajs.testsuite.utils.Platform._ import scala.util.{ Try, Failure } @@ -40,17 +41,10 @@ class RuntimeTypesTest { @Test def scala_Nothing_casts_to_scala_Nothing_should_fail(): Unit = { assumeTrue("Assumed compliant asInstanceOf", hasCompliantAsInstanceOfs) - def test(x: Any): Unit = { - try { - x.asInstanceOf[Nothing] - fail("casting " + x + " to Nothing did not fail") - } catch { - case th: Throwable => - assertTrue(th.isInstanceOf[ClassCastException]) - assertEquals(x + " is not an instance of scala.runtime.Nothing$", - th.getMessage) - } - } + + def test(x: Any): Unit = + assertThrows(classOf[ClassCastException], x.asInstanceOf[Nothing]) + test("a") test(null) } @@ -86,11 +80,7 @@ class RuntimeTypesTest { @Test def scala_Null_casts_to_scala_Null_should_fail_for_everything_else_but_null(): Unit = { assumeTrue("Assumed compliant asInstanceOf", hasCompliantAsInstanceOfs) - val msg = Try("a".asInstanceOf[Null]) match { - case Failure(thr: ClassCastException) => thr.getMessage - case _ => "not failed" - } - assertEquals("a is not an instance of scala.runtime.Null$", msg) + assertThrows(classOf[ClassCastException], "a".asInstanceOf[Null]) } @Test def scala_Null_classTag_of_scala_Null_should_contain_proper_Class_issue_297(): Unit = { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala index f195ba8949..8664710d84 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala @@ -43,7 +43,9 @@ object Analysis { "I" -> "int", "J" -> "long", "F" -> "float", - "D" -> "double" + "D" -> "double", + "N" -> "null", + "E" -> "nothing" ) /** Class node in a reachability graph produced by the [[Analyzer]]. diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index f9caae231d..176e038709 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -708,10 +708,6 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { case Definitions.BoxedStringClass => js.UnaryOp(JSUnaryOp.typeof, obj) === js.StringLiteral("string") - case Definitions.RuntimeNothingClass => - // Even null is not an instance of Nothing - js.BooleanLiteral(false) - case _ => var test = { genIsScalaJSObject(obj) && @@ -746,21 +742,13 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { obj case _ => - val throwError = { + js.If(js.Apply(envField("is", className), List(obj)) || + (obj === js.Null()), { + obj + }, { genCallHelper("throwClassCastException", obj, js.StringLiteral(displayName)) - } - if (className == RuntimeNothingClass) { - // Always throw for .asInstanceOf[Nothing], even for null - throwError - } else { - js.If(js.Apply(envField("is", className), List(obj)) || - (obj === js.Null()), { - obj - }, { - throwError - }) - } + }) }))) } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 603f4411e4..ec0e616517 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -893,10 +893,12 @@ private final class IRChecker(unit: LinkingUnit, typecheckExpect(rhs, env, expectedRhsType) case NewArray(tpe, lengths) => + checkArrayType(tpe) for (length <- lengths) typecheckExpect(length, env, IntType) case ArrayValue(tpe, elems) => + checkArrayType(tpe) val elemType = arrayElemType(tpe) for (elem <- elems) typecheckExpect(elem, env, elemType) @@ -1016,6 +1018,16 @@ private final class IRChecker(unit: LinkingUnit, // Literals + case ClassOf(typeRef) => + typeRef match { + case ClassRef(cls @ (NullClass | NothingClass)) => + reportError(s"Invalid classOf[$cls]") + case typeRef: ArrayTypeRef => + checkArrayTypeRef(typeRef) + case _ => + // ok + } + case _: Literal => // Atomic expressions @@ -1133,8 +1145,23 @@ private final class IRChecker(unit: LinkingUnit, } } - case ArrayTypeRef(_, _) => - // Nothing to check + case typeRef: ArrayTypeRef => + checkArrayTypeRef(typeRef) + } + } + + private def checkArrayType(tpe: ArrayType)( + implicit ctx: ErrorContext): Unit = { + checkArrayTypeRef(tpe.arrayTypeRef) + } + + private def checkArrayTypeRef(typeRef: ArrayTypeRef)( + implicit ctx: ErrorContext): Unit = { + typeRef.baseClassName match { + case VoidClass | NullClass | NothingClass => + reportError(s"Invalid array type $typeRef") + case _ => + // ok } } @@ -1176,13 +1203,11 @@ private final class IRChecker(unit: LinkingUnit, case 'J' => LongType case 'F' => FloatType case 'D' => DoubleType + case 'N' => NullType + case 'E' => NothingType case 'O' => AnyType case 'T' => ClassType(BoxedStringClass) // NOT StringType } - } else if (encodedName == "sr_Nothing$") { - NothingType - } else if (encodedName == "sr_Null$") { - NullType } else { val kind = tryLookupClass(encodedName).fold(_.kind, _.kind) if (kind.isJSType) AnyType From 508a70b5ec1df70eb6c571f91a803b0967b36c88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 9 Dec 2017 23:14:47 +0100 Subject: [PATCH 0576/2665] Restore the specified behavior of j.l.Class.isAssignableFrom. The implemented behavior used to match the specification, but was changed in 9108b7c96c5b6fd7881c69a738dcc9ab4a7ef1df to fix #879. It turns out that the real culprit for #879 was not `isAssignableFrom`, but the implementation of `ClassTag.unapply`. Now that the latter has a Scala.js-friendly implementation in all versions of Scala for which it is not also broken on the JVM, we do not need `isAssignableFrom` to work around it. This makes sure that the behavior of `java.lang.Class` is not dependent on Scala as a source language. One partest does not pass out-of-the-box in 2.11.x if we do that: `run/t6318_primitives.scala`, but it works in 2.12.x. That happens because 2.12.x removed the overloads taking primitives, so at a source call site of `ct.unapply(5)`, 2.11.x would call `unapply(Int)` but 2.12+ would call `unapply(Any)`. It turns out that the `unapply`s taking primitives are not Scala.js-friendly enough for this partest (which has an overridden check file, btw). We fix this by "backporting" from 2.12 the removal of the `unapply`s taking any. In practice we cannot do that because we need to preserve binary compatibility, but we can implement it anyway by overriding them to delegate to the `unapply` taking `Any`. --- .../src/main/scala/java/lang/Class.scala | 23 +--------- .../scala/reflect/ClassTag.scala | 22 ++++------ .../testsuite/compiler/ReflectionTest.scala | 10 ----- .../testsuite/javalib/lang/ClassTest.scala | 44 +++++++++++++++++++ 4 files changed, 55 insertions(+), 44 deletions(-) diff --git a/javalanglib/src/main/scala/java/lang/Class.scala b/javalanglib/src/main/scala/java/lang/Class.scala index 0a3af26ced..43fadd103a 100644 --- a/javalanglib/src/main/scala/java/lang/Class.scala +++ b/javalanglib/src/main/scala/java/lang/Class.scala @@ -30,27 +30,8 @@ final class Class[A] private (data: ScalaJSClassData[A]) extends Object { data.isInstance(obj) def isAssignableFrom(that: Class[_]): scala.Boolean = - if (this.isPrimitive || that.isPrimitive) { - /* This differs from the JVM specification to mimic the behavior of - * runtime type tests of primitive numeric types. - */ - (this eq that) || { - if (this eq classOf[scala.Short]) - (that eq classOf[scala.Byte]) - else if (this eq classOf[scala.Int]) - (that eq classOf[scala.Byte]) || (that eq classOf[scala.Short]) - else if (this eq classOf[scala.Float]) - (that eq classOf[scala.Byte]) || (that eq classOf[scala.Short]) || - (that eq classOf[scala.Int]) - else if (this eq classOf[scala.Double]) - (that eq classOf[scala.Byte]) || (that eq classOf[scala.Short]) || - (that eq classOf[scala.Int]) || (that eq classOf[scala.Float]) - else - false - } - } else { - this.isInstance(that.getFakeInstance()) - } + if (this.isPrimitive || that.isPrimitive) this eq that + else this.isInstance(that.getFakeInstance()) private def getFakeInstance(): Object = data.getFakeInstance() diff --git a/scalalib/overrides-2.11/scala/reflect/ClassTag.scala b/scalalib/overrides-2.11/scala/reflect/ClassTag.scala index 95f19e180d..1b79bf395e 100644 --- a/scalalib/overrides-2.11/scala/reflect/ClassTag.scala +++ b/scalalib/overrides-2.11/scala/reflect/ClassTag.scala @@ -84,19 +84,15 @@ trait ClassTag[T] extends ClassManifestDeprecatedApis[T] with Equals with Serial else None // TODO: deprecate overloads in 2.12.0, remove in 2.13.0 - def unapply(x: Byte) : Option[T] = unapplyImpl(x, classOf[Byte]) - def unapply(x: Short) : Option[T] = unapplyImpl(x, classOf[Short]) - def unapply(x: Char) : Option[T] = unapplyImpl(x, classOf[Char]) - def unapply(x: Int) : Option[T] = unapplyImpl(x, classOf[Int]) - def unapply(x: Long) : Option[T] = unapplyImpl(x, classOf[Long]) - def unapply(x: Float) : Option[T] = unapplyImpl(x, classOf[Float]) - def unapply(x: Double) : Option[T] = unapplyImpl(x, classOf[Double]) - def unapply(x: Boolean) : Option[T] = unapplyImpl(x, classOf[Boolean]) - def unapply(x: Unit) : Option[T] = unapplyImpl(x, classOf[Unit]) - - private[this] def unapplyImpl(x: Any, primitiveCls: java.lang.Class[_]): Option[T] = - if (runtimeClass.isInstance(x) || runtimeClass.isAssignableFrom(primitiveCls)) Some(x.asInstanceOf[T]) - else None + def unapply(x: Byte) : Option[T] = unapply(x: Any) + def unapply(x: Short) : Option[T] = unapply(x: Any) + def unapply(x: Char) : Option[T] = unapply(x: Any) + def unapply(x: Int) : Option[T] = unapply(x: Any) + def unapply(x: Long) : Option[T] = unapply(x: Any) + def unapply(x: Float) : Option[T] = unapply(x: Any) + def unapply(x: Double) : Option[T] = unapply(x: Any) + def unapply(x: Boolean) : Option[T] = unapply(x: Any) + def unapply(x: Unit) : Option[T] = unapply(x: Any) // case class accessories override def canEqual(x: Any) = x.isInstanceOf[ClassTag[_]] diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectionTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectionTest.scala index a20b80de0a..3c21d8b4f0 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectionTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectionTest.scala @@ -125,16 +125,6 @@ class ReflectionTest { assertEquals(classOf[scala.runtime.BoxedUnit], ((): Any).getClass) } - @Test def class_isAssignableFrom_should_mimic_runtime_type_tests_behavior_issue_879(): Unit = { - assertTrue(classOf[Short].isAssignableFrom(classOf[Byte])) - assertTrue(classOf[Byte].isAssignableFrom(classOf[Byte])) - assertFalse(classOf[Byte].isAssignableFrom(classOf[Short])) - assertTrue(classOf[Int].isAssignableFrom(classOf[Byte])) - assertTrue(classOf[Double].isAssignableFrom(classOf[Int])) - assertFalse(classOf[Int].isAssignableFrom(classOf[Double])) - assertFalse(classOf[Long].isAssignableFrom(classOf[Int])) - } - @Test def getSuperclass_issue_1489(): Unit = { assertEquals(classOf[SomeParentClass], classOf[SomeChildClass].getSuperclass) assertNull(classOf[AnyRef].getSuperclass) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ClassTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ClassTest.scala index 4737466cfd..fd399dba54 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ClassTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ClassTest.scala @@ -14,6 +14,18 @@ import scala.runtime.BoxedUnit class ClassTest { + private val PrimitiveClassOfs = Seq( + classOf[Unit], + classOf[Boolean], + classOf[Char], + classOf[Byte], + classOf[Short], + classOf[Int], + classOf[Long], + classOf[Float], + classOf[Double] + ) + @Test def getPrimitiveTypeName(): Unit = { assertEquals("void", classOf[Unit].getName) assertEquals("boolean", classOf[Boolean].getName) @@ -57,6 +69,38 @@ class ClassTest { assertEquals("InnerClass", classOf[ClassTestClass#InnerClass].getSimpleName()) } + @Test def isAssignableFrom(): Unit = { + val SelectedClassOfs = + PrimitiveClassOfs ++ Seq(classOf[Object], classOf[String]) + + // All Classes are assignable from themselves + for (cls <- SelectedClassOfs) { + assertTrue(s"$cls should be assignable from itself", + cls.isAssignableFrom(cls)) + } + + // Otherwise, if one side is a primitive, the result must be false + for { + left <- SelectedClassOfs + right <- SelectedClassOfs + if (left ne right) && (left.isPrimitive || right.isPrimitive) + } { + assertFalse( + s"$left.isAssignableFrom($right) should be false", + left.isAssignableFrom(right)) + } + + assertTrue(classOf[Object].isAssignableFrom(classOf[String])) + assertTrue(classOf[Seq[_]].isAssignableFrom(classOf[List[_]])) + assertTrue(classOf[Object].isAssignableFrom(classOf[Array[String]])) + assertTrue(classOf[Array[Seq[_]]].isAssignableFrom(classOf[Array[List[_]]])) + + assertFalse(classOf[String].isAssignableFrom(classOf[Object])) + assertFalse(classOf[List[_]].isAssignableFrom(classOf[Seq[_]])) + assertFalse(classOf[Array[String]].isAssignableFrom(classOf[Object])) + assertFalse(classOf[Array[List[_]]].isAssignableFrom(classOf[Array[Seq[_]]])) + } + @Test def getComponentType(): Unit = { @noinline def testNoInline(clazz: Class[_], componentType: Class[_]): Unit = From 566efbe6c25ca7d17365784829a8e20127145c15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 9 Dec 2017 23:31:01 +0100 Subject: [PATCH 0577/2665] Implement `isAssignableFrom` in JS instead of exposing `getFakeInstance`. Creating a fake instance and using it as an argument of `isInstance` is a huge hack. It's OK to do it internally in `scalajsenv.js`, as long as fake instances do not leak. But exposing fake instances to the Scala.js code is extremely dangerous, as it means leaking implementation-specific details at the IR level, which could be (mis-)processed by the optimizer. Since `getFakeInstance` was used only for `isAssignableFrom` anyway, it is much cleaner to directly implement `isAssignableFrom` in `scalajsenv.js`, and not expose `getFakeInstance` at all. --- .../src/main/scala/java/lang/Class.scala | 11 ++--- tools/scalajsenv.js | 42 +++++++++++-------- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/javalanglib/src/main/scala/java/lang/Class.scala b/javalanglib/src/main/scala/java/lang/Class.scala index 43fadd103a..9ab9016705 100644 --- a/javalanglib/src/main/scala/java/lang/Class.scala +++ b/javalanglib/src/main/scala/java/lang/Class.scala @@ -11,7 +11,7 @@ private trait ScalaJSClassData[A] extends js.Object { val isRawJSType: scala.Boolean = js.native def isInstance(obj: Object): scala.Boolean = js.native - def getFakeInstance(): Object = js.native + def isAssignableFrom(that: ScalaJSClassData[_]): scala.Boolean = js.native def getSuperclass(): Class[_ >: A] = js.native def getComponentType(): Class[_] = js.native @@ -19,7 +19,8 @@ private trait ScalaJSClassData[A] extends js.Object { def newArrayOfThisClass(dimensions: js.Array[Int]): AnyRef = js.native } -final class Class[A] private (data: ScalaJSClassData[A]) extends Object { +final class Class[A] private (private val data: ScalaJSClassData[A]) + extends Object { override def toString(): String = { (if (isInterface()) "interface " else @@ -30,11 +31,7 @@ final class Class[A] private (data: ScalaJSClassData[A]) extends Object { data.isInstance(obj) def isAssignableFrom(that: Class[_]): scala.Boolean = - if (this.isPrimitive || that.isPrimitive) this eq that - else this.isInstance(that.getFakeInstance()) - - private def getFakeInstance(): Object = - data.getFakeInstance() + this.data.isAssignableFrom(that.data) def isInterface(): scala.Boolean = data.isInterface diff --git a/tools/scalajsenv.js b/tools/scalajsenv.js index 3571a4b98a..82a23674f2 100644 --- a/tools/scalajsenv.js +++ b/tools/scalajsenv.js @@ -963,26 +963,32 @@ getArrayOf() { // java.lang.Class support //!if outputMode != ECMAScript6 -$TypeData.prototype["getFakeInstance"] = function() { +$TypeData.prototype["isAssignableFrom"] = function(that) { //!else -"getFakeInstance"() { +"isAssignableFrom"(that) { //!endif - if (this === $d_T) - return "some string"; - else if (this === $d_jl_Boolean) - return false; - else if (this === $d_jl_Byte || - this === $d_jl_Short || - this === $d_jl_Integer || - this === $d_jl_Float || - this === $d_jl_Double) - return 0; - else if (this === $d_jl_Long) - return $L0; - else if (this === $d_sr_BoxedUnit) - return void 0; - else - return {$classData: this}; + if (this["isPrimitive"] || that["isPrimitive"]) { + return this === that; + } else { + let thatFakeInstance; + if (that === $d_T) + thatFakeInstance = "some string"; + else if (that === $d_jl_Boolean) + thatFakeInstance = false; + else if (that === $d_jl_Byte || + that === $d_jl_Short || + that === $d_jl_Integer || + that === $d_jl_Float || + that === $d_jl_Double) + thatFakeInstance = 0; + else if (that === $d_jl_Long) + thatFakeInstance = $L0; + else if (that === $d_sr_BoxedUnit) + thatFakeInstance = void 0; + else + thatFakeInstance = {$classData: that}; + return this["isInstance"](thatFakeInstance); + } }; //!if outputMode != ECMAScript6 From 4354594c1ff70ea4813595dce87d9ccddc77b332 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 9 Dec 2017 23:39:48 +0100 Subject: [PATCH 0578/2665] Change the signature of `Class`'s constructor to take an `Object`. This way, the "public" signature of that constructor does not refer to `ScalaJSClassData`, which is an implementation detail of `java.lang.Class`. It is public because it is accessed by the `Emitter`, even though it is declared as private. Note that even though `ScalaJSClassData` as such is an implementation detail, its *structure* must be considered as specified at the interface between the `java.lang` implementation and the linker. If someone wants to write a different linker, or a different `java.lang` library, they must adhere to that structure to ensure interoperability. --- javalanglib/src/main/scala/java/lang/Class.scala | 5 +++-- .../scalajs/core/tools/linker/backend/emitter/Emitter.scala | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/javalanglib/src/main/scala/java/lang/Class.scala b/javalanglib/src/main/scala/java/lang/Class.scala index 9ab9016705..2d14d36ac0 100644 --- a/javalanglib/src/main/scala/java/lang/Class.scala +++ b/javalanglib/src/main/scala/java/lang/Class.scala @@ -19,8 +19,9 @@ private trait ScalaJSClassData[A] extends js.Object { def newArrayOfThisClass(dimensions: js.Array[Int]): AnyRef = js.native } -final class Class[A] private (private val data: ScalaJSClassData[A]) - extends Object { +final class Class[A] private (data0: Object) extends Object { + private val data: ScalaJSClassData[A] = + data0.asInstanceOf[ScalaJSClassData[A]] override def toString(): String = { (if (isInterface()) "interface " else diff --git 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 index 12f3f1e9ea..ba5bf052a2 100644 --- 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 @@ -675,7 +675,7 @@ private object Emitter { instantiateClass("sjsr_UndefinedBehaviorError", "init___T") }, - instantiateClass("jl_Class", "init___jl_ScalaJSClassData"), + instantiateClass("jl_Class", "init___O"), instanceTests(LongImpl.RuntimeLongClass), instantiateClass(LongImpl.RuntimeLongClass, LongImpl.AllConstructors), From 8a9336e75a8967baae39d54d10e0a9b74b1be078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 12 Dec 2017 11:02:43 +0100 Subject: [PATCH 0579/2665] Fix #2949: Remove the CLI. The CLI has been ported over to the separate repository https://github.com/scala-js/scala-js-cli. --- RELEASING.md | 15 +- TESTING | 35 ---- build.sbt | 1 - ci/matrix.xml | 18 +- cli/src/main/resources/scalajsc | 16 -- cli/src/main/resources/scalajsc.bat | 14 -- cli/src/main/resources/scalajsld | 10 - cli/src/main/resources/scalajsld.bat | 8 - cli/src/main/resources/scalajsp | 9 - cli/src/main/resources/scalajsp.bat | 7 - .../scala/org/scalajs/cli/Scalajsld.scala | 184 ------------------ .../main/scala/org/scalajs/cli/Scalajsp.scala | 123 ------------ project/Build.scala | 24 +-- project/build.sbt | 2 - scripts/assemble-cli.sh | 105 ---------- 15 files changed, 17 insertions(+), 554 deletions(-) delete mode 100755 cli/src/main/resources/scalajsc delete mode 100644 cli/src/main/resources/scalajsc.bat delete mode 100755 cli/src/main/resources/scalajsld delete mode 100644 cli/src/main/resources/scalajsld.bat delete mode 100755 cli/src/main/resources/scalajsp delete mode 100644 cli/src/main/resources/scalajsp.bat delete mode 100644 cli/src/main/scala/org/scalajs/cli/Scalajsld.scala delete mode 100644 cli/src/main/scala/org/scalajs/cli/Scalajsp.scala delete mode 100755 scripts/assemble-cli.sh diff --git a/RELEASING.md b/RELEASING.md index f201eef736..f964da787b 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -16,17 +16,15 @@ 1. Perform [manual testing][3] that needs the tagging (source maps). 1. Publish: - Sonatype, bintray (`./script/publish.sh`) - - CLI to website (simple `scp`) + - [Publish the CLI][4] - Docs to website: Use `~/fetchapis.sh ` on the webserver once artifacts are on maven central. 1. Once artifacts are on maven central, create a "Towards x.y.z." commit - ([example][4]). - 1. Create a "DO NOT MERGE" PR for CI and review. + ([example][5]). + 1. Create an "FF ONLY" PR for CI and review. 1. Once you have LGTM, push the commit (do *not* click the merge button) - 1. Remove the "DO NOT MERGE" from the PR title (since it will now show as - merged). -1. Prepare release announcement, taking the last one as model ([example][5]). +1. Prepare release announcement, taking the last one as model ([example][6]). 1. When merging the release announcement PR (after proper review): - Update the latest/ URLs (use `~/setlatestapi.sh ` on webserver) @@ -38,5 +36,6 @@ [1]: https://github.com/scala-js/scala-js/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20no%3Amilestone%20-label%3Ainvalid%20-label%3Aduplicate%20-label%3Aas-designed%20-label%3Aquestion%20-label%3Awontfix%20-label%3A%22can%27t%20reproduce%22%20-label%3A%22separate%20repo%22 [2]: https://github.com/scala-js/scala-js/commit/a09e8cdd92b962e90c83ec124b9764970a4889ff [3]: https://github.com/scala-js/scala-js/blob/master/TESTING -[4]: https://github.com/scala-js/scala-js/commit/c51f8b65d3eca45de84397f7167058c91d6b6aa1 -[5]: https://github.com/scala-js/scala-js-website/commit/8dc9e9d3ee63ec47e6eb154fa7bd5a2ae8d1d42d +[4]: https://github.com/scala-js/scala-js-cli/blob/master/RELEASING.md +[5]: https://github.com/scala-js/scala-js/commit/c51f8b65d3eca45de84397f7167058c91d6b6aa1 +[6]: https://github.com/scala-js/scala-js-website/commit/8dc9e9d3ee63ec47e6eb154fa7bd5a2ae8d1d42d diff --git a/TESTING b/TESTING index af1d74c97b..5ecab96991 100644 --- a/TESTING +++ b/TESTING @@ -1,40 +1,5 @@ This file contains test cases that should be manually executed. -## CLI Distribution - -For each major Scala version on a *NIX distro and a Windows distro: - -1. Download packaged Scala from scala-lang.org -2. Build Scala.js CLI distribution (e.g. `./assemble-cli.sh 2.10`) -3. Unpack Scala and Scala.js distro -4. Add `bin/` directories of both distributions to path (`export PATH=$PATH:/bin:/bin`) -5. Create a temporary directory and do: - - mkdir bin - echo ' - object Foo { - def main(args: Array[String]): Unit = { - println(s"asdf ${1 + 1}") - new A - } - - class A - } - ' > foo.scala - scalajsc -d bin foo.scala - - scalajsp bin/Foo$.sjsir - # Verify output - scalajsp bin/Foo\$A.sjsir - # Verify output - - scalajsld -o test.js -mm Foo.main bin - # Verify output - - node test.js # Or your favorite thing to run JS - - # Expect "asdf 2" - ## HTML-Runners The following HTML-runners must be manually tested: diff --git a/build.sbt b/build.sbt index 9809553411..718fcefa7b 100644 --- a/build.sbt +++ b/build.sbt @@ -17,7 +17,6 @@ val scalalib = Build.scalalib val libraryAux = Build.libraryAux val library = Build.library val stubs = Build.stubs -val cli = Build.cli val testInterface = Build.testInterface val jUnitRuntime = Build.jUnitRuntime val jUnitTestOutputsJS = Build.jUnitTestOutputsJS diff --git a/ci/matrix.xml b/ci/matrix.xml index fdbec7f6e2..9dfeaf4e16 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -141,33 +141,33 @@ ++$scala toolsJS/bootstrapTest ]]> - - - + 2.10.7 1.8 - + 2.11.12 1.8 - + 2.12.4 1.8 diff --git a/cli/src/main/resources/scalajsc b/cli/src/main/resources/scalajsc deleted file mode 100755 index 7fd1100279..0000000000 --- a/cli/src/main/resources/scalajsc +++ /dev/null @@ -1,16 +0,0 @@ -#! /bin/sh - -SCALA_BIN_VER="@SCALA_BIN_VER@" -SCALAJS_VER="@SCALAJS_VER@" -SCALA_VER=$(scalac -version 2>&1 | grep -o '[0-9]\.[0-9][0-9]\.[0-9]') - -if [ "$(echo $SCALA_VER | cut -b 1-4)" != "$SCALA_BIN_VER" ]; then - echo "This bundle of Scala.js CLI is for $SCALA_BIN_VER. Your scala version is $SCALA_VER!" >&2 - exit 1 -fi - -BASE="$(dirname $0)/.." -PLUGIN="$BASE/lib/scalajs-compiler_$SCALA_VER-$SCALAJS_VER.jar" -JSLIB="$BASE/lib/scalajs-library_$SCALA_BIN_VER-$SCALAJS_VER.jar" - -scalac -classpath "$JSLIB" "-Xplugin:$PLUGIN" "$@" diff --git a/cli/src/main/resources/scalajsc.bat b/cli/src/main/resources/scalajsc.bat deleted file mode 100644 index 767c5df9de..0000000000 --- a/cli/src/main/resources/scalajsc.bat +++ /dev/null @@ -1,14 +0,0 @@ -@ECHO OFF -set SCALA_BIN_VER=@SCALA_BIN_VER@ -set SCALAJS_VER=@SCALAJS_VER@ - -for /F "tokens=5" %%i in (' scala -version 2^>^&1 1^>nul ') do set SCALA_VER=%%i - -if NOT "%SCALA_VER:~0,4%" == "%SCALA_BIN_VER%" ( - echo "This bundle of Scala.js CLI is for %SCALA_BIN_VER%. Your scala version is %SCALA_VER%!" 1>&2 -) else ( - set PLUGIN=%~dp0\..\lib\scalajs-compiler_%SCALA_VER%-%SCALAJS_VER%.jar - set JSLIB=%~dp0\..\lib\scalajs-library_%SCALA_BIN_VER%-%SCALAJS_VER%.jar - - scalac -classpath "%JSLIB%" "-Xplugin:%PLUGIN%" %* -) diff --git a/cli/src/main/resources/scalajsld b/cli/src/main/resources/scalajsld deleted file mode 100755 index b194859ef7..0000000000 --- a/cli/src/main/resources/scalajsld +++ /dev/null @@ -1,10 +0,0 @@ -#! /bin/sh - -SCALA_BIN_VER="@SCALA_BIN_VER@" -SCALAJS_VER="@SCALAJS_VER@" - -BASE="$(dirname $0)/.." -CLILIB="$BASE/lib/scalajs-cli-assembly_$SCALA_BIN_VER-$SCALAJS_VER.jar" -JSLIB="$BASE/lib/scalajs-library_$SCALA_BIN_VER-$SCALAJS_VER.jar" - -scala -classpath "$CLILIB" org.scalajs.cli.Scalajsld --stdlib "$JSLIB" "$@" diff --git a/cli/src/main/resources/scalajsld.bat b/cli/src/main/resources/scalajsld.bat deleted file mode 100644 index 0308d559ea..0000000000 --- a/cli/src/main/resources/scalajsld.bat +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO OFF -set SCALA_BIN_VER=@SCALA_BIN_VER@ -set SCALAJS_VER=@SCALAJS_VER@ - -set CLILIB="%~dp0\..\lib\scalajs-cli-assembly_%SCALA_BIN_VER%-%SCALAJS_VER%.jar" -set JSLIB="%~dp0\..\lib\scalajs-library_%SCALA_BIN_VER%-%SCALAJS_VER%.jar" - -scala -classpath %CLILIB% org.scalajs.cli.Scalajsld --stdlib %JSLIB% %* diff --git a/cli/src/main/resources/scalajsp b/cli/src/main/resources/scalajsp deleted file mode 100755 index f98f259355..0000000000 --- a/cli/src/main/resources/scalajsp +++ /dev/null @@ -1,9 +0,0 @@ -#! /bin/sh - -SCALA_BIN_VER="@SCALA_BIN_VER@" -SCALAJS_VER="@SCALAJS_VER@" - -BASE="$(dirname $0)/.." -CLILIB="$BASE/lib/scalajs-cli-assembly_$SCALA_BIN_VER-$SCALAJS_VER.jar" - -scala -classpath "$CLILIB" org.scalajs.cli.Scalajsp "$@" diff --git a/cli/src/main/resources/scalajsp.bat b/cli/src/main/resources/scalajsp.bat deleted file mode 100644 index 1fc4ad6752..0000000000 --- a/cli/src/main/resources/scalajsp.bat +++ /dev/null @@ -1,7 +0,0 @@ -@ECHO OFF -set SCALA_BIN_VER=@SCALA_BIN_VER@ -set SCALAJS_VER=@SCALAJS_VER@ - -set CLILIB="%~dp0\..\lib\scalajs-cli-assembly_%SCALA_BIN_VER%-%SCALAJS_VER%.jar" - -scala -classpath %CLILIB% org.scalajs.cli.Scalajsp %* diff --git a/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala b/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala deleted file mode 100644 index 890ab55d31..0000000000 --- a/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala +++ /dev/null @@ -1,184 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js CLI ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.cli - -import org.scalajs.core.ir.ScalaJSVersions - -import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.logging._ - -import org.scalajs.core.tools.linker._ -import org.scalajs.core.tools.linker.standard._ - -import CheckedBehavior.Compliant - -import scala.collection.immutable.Seq - -import java.io.File -import java.net.URI - -object Scalajsld { - - private case class Options( - cp: Seq[File] = Seq.empty, - moduleInitializers: Seq[ModuleInitializer] = Seq.empty, - output: File = null, - semantics: Semantics = Semantics.Defaults, - outputMode: OutputMode = OutputMode.ECMAScript51Isolated, - moduleKind: ModuleKind = ModuleKind.NoModule, - noOpt: Boolean = false, - fullOpt: Boolean = false, - prettyPrint: Boolean = false, - sourceMap: Boolean = false, - relativizeSourceMap: Option[URI] = None, - checkIR: Boolean = false, - stdLib: Option[File] = None, - logLevel: Level = Level.Info) - - private implicit object MainMethodRead extends scopt.Read[ModuleInitializer] { - val arity = 1 - val reads = { (s: String) => - val lastDot = s.lastIndexOf('.') - if (lastDot < 0) - throw new IllegalArgumentException(s"$s is not a valid main method") - ModuleInitializer.mainMethodWithArgs(s.substring(0, lastDot), - s.substring(lastDot + 1)) - } - } - - private implicit object OutputModeRead extends scopt.Read[OutputMode] { - val arity = 1 - val reads = { (s: String) => - OutputMode.All.find(_.toString() == s).getOrElse( - throw new IllegalArgumentException(s"$s is not a valid output mode")) - } - } - - private implicit object ModuleKindRead extends scopt.Read[ModuleKind] { - val arity = 1 - val reads = { (s: String) => - ModuleKind.All.find(_.toString() == s).getOrElse( - throw new IllegalArgumentException(s"$s is not a valid module kind")) - } - } - - def main(args: Array[String]): Unit = { - val parser = new scopt.OptionParser[Options]("scalajsld") { - head("scalajsld", ScalaJSVersions.current) - arg[File](" ...") - .unbounded() - .action { (x, c) => c.copy(cp = c.cp :+ x) } - .text("Entries of Scala.js classpath to link") - opt[ModuleInitializer]("mainMethod") - .valueName("") - .abbr("mm") - .unbounded() - .action { (x, c) => c.copy(moduleInitializers = c.moduleInitializers :+ x) } - .text("Execute the specified main(Array[String]) method on startup") - opt[File]('o', "output") - .valueName("") - .required() - .action { (x, c) => c.copy(output = x) } - .text("Output file of linker (required)") - opt[Unit]('f', "fastOpt") - .action { (_, c) => c.copy(noOpt = false, fullOpt = false) } - .text("Optimize code (this is the default)") - opt[Unit]('n', "noOpt") - .action { (_, c) => c.copy(noOpt = true, fullOpt = false) } - .text("Don't optimize code") - opt[Unit]('u', "fullOpt") - .action { (_, c) => c.copy(noOpt = false, fullOpt = true) } - .text("Fully optimize code (uses Google Closure Compiler)") - opt[Unit]('p', "prettyPrint") - .action { (_, c) => c.copy(prettyPrint = true) } - .text("Pretty print full opted code (meaningful with -u)") - opt[Unit]('s', "sourceMap") - .action { (_, c) => c.copy(sourceMap = true) } - .text("Produce a source map for the produced code") - opt[Unit]("compliantAsInstanceOfs") - .action { (_, c) => c.copy(semantics = - c.semantics.withAsInstanceOfs(Compliant)) - } - .text("Use compliant asInstanceOfs") - opt[OutputMode]('m', "outputMode") - .action { (mode, c) => c.copy(outputMode = mode) } - .text("Output mode " + OutputMode.All.mkString("(", ", ", ")")) - opt[ModuleKind]('k', "moduleKind") - .action { (kind, c) => c.copy(moduleKind = kind) } - .text("Module kind " + ModuleKind.All.mkString("(", ", ", ")")) - opt[Unit]('c', "checkIR") - .action { (_, c) => c.copy(checkIR = true) } - .text("Check IR before optimizing") - opt[File]('r', "relativizeSourceMap") - .valueName("") - .action { (x, c) => c.copy(relativizeSourceMap = Some(x.toURI)) } - .text("Relativize source map with respect to given path (meaningful with -s)") - opt[Unit]("noStdlib") - .action { (_, c) => c.copy(stdLib = None) } - .text("Don't automatically include Scala.js standard library") - opt[File]("stdlib") - .valueName("") - .hidden() - .action { (x, c) => c.copy(stdLib = Some(x)) } - .text("Location of Scala.js standard libarary. This is set by the " + - "runner script and automatically prepended to the classpath. " + - "Use -n to not include it.") - opt[Unit]('d', "debug") - .action { (_, c) => c.copy(logLevel = Level.Debug) } - .text("Debug mode: Show full log") - opt[Unit]('q', "quiet") - .action { (_, c) => c.copy(logLevel = Level.Warn) } - .text("Only show warnings & errors") - opt[Unit]("really-quiet") - .abbr("qq") - .action { (_, c) => c.copy(logLevel = Level.Error) } - .text("Only show errors") - version("version") - .abbr("v") - .text("Show scalajsld version") - help("help") - .abbr("h") - .text("prints this usage text") - - override def showUsageOnError = true - } - - for (options <- parser.parse(args, Options())) { - val classpath = options.stdLib.toList ++ options.cp - val irContainers = FileScalaJSIRContainer.fromClasspath(classpath) - val moduleInitializers = options.moduleInitializers - - val semantics = - if (options.fullOpt) options.semantics.optimized - else options.semantics - - val config = StandardLinker.Config() - .withSemantics(semantics) - .withModuleKind(options.moduleKind) - .withOutputMode(options.outputMode) - .withCheckIR(options.checkIR) - .withOptimizer(!options.noOpt) - .withParallel(true) - .withSourceMap(options.sourceMap) - .withRelativizeSourceMapBase(options.relativizeSourceMap) - .withClosureCompiler(options.fullOpt) - .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 - - linker.link(cache.cached(irContainers), moduleInitializers, outFile, - logger) - } - } -} diff --git a/cli/src/main/scala/org/scalajs/cli/Scalajsp.scala b/cli/src/main/scala/org/scalajs/cli/Scalajsp.scala deleted file mode 100644 index 786dce8998..0000000000 --- a/cli/src/main/scala/org/scalajs/cli/Scalajsp.scala +++ /dev/null @@ -1,123 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js CLI ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.cli - -import org.scalajs.core.ir -import ir.ScalaJSVersions -import ir.Trees.{Tree, ClassDef} -import ir.Printers.IRTreePrinter - -import org.scalajs.core.tools.io._ -import scala.collection.immutable.Seq - -import java.io.{Console => _, _} -import java.util.zip.{ZipFile, ZipEntry} - -object Scalajsp { - - private case class Options( - jar: Option[File] = None, - fileNames: Seq[String] = Seq.empty) - - def main(args: Array[String]): Unit = { - val parser = new scopt.OptionParser[Options]("scalajsp") { - head("scalajsp", ScalaJSVersions.current) - arg[String](" ...") - .unbounded() - .action { (x, c) => c.copy(fileNames = c.fileNames :+ x) } - .text("*.sjsir file to display content of") - opt[File]('j', "jar") - .valueName("") - .action { (x, c) => c.copy(jar = Some(x)) } - .text("Read *.sjsir file(s) from the given JAR.") - opt[Unit]('s', "supported") - .action { (_,_) => printSupported(); exit(0) } - .text("Show supported Scala.js IR versions") - version("version") - .abbr("v") - .text("Show scalajsp version") - help("help") - .abbr("h") - .text("prints this usage text") - - override def showUsageOnError = true - } - - for { - options <- parser.parse(args, Options()) - fileName <- options.fileNames - } { - val vfile = options.jar map { jar => - readFromJar(jar, fileName) - } getOrElse { - readFromFile(fileName) - } - - displayFileContent(vfile, options) - } - } - - private def printSupported(): Unit = { - import ScalaJSVersions._ - println(s"Emitted Scala.js IR version is: $binaryEmitted") - println("Supported Scala.js IR versions are") - binarySupported.foreach(v => println(s"* $v")) - } - - private def displayFileContent(vfile: VirtualScalaJSIRFile, - opts: Options): Unit = { - new IRTreePrinter(stdout).print(vfile.tree) - stdout.flush() - } - - private def fail(msg: String): Nothing = { - Console.err.println(msg) - exit(1) - } - - private def exit(code: Int): Nothing = { - System.exit(code) - throw new AssertionError("unreachable") - } - - private def readFromFile(fileName: String) = { - val file = new File(fileName) - - if (!file.exists) - fail(s"No such file: $fileName") - else if (!file.canRead) - fail(s"Unable to read file: $fileName") - else - FileVirtualScalaJSIRFile(file) - } - - private def readFromJar(jar: File, name: String) = { - val jarFile = - try { new ZipFile(jar) } - catch { case _: FileNotFoundException => fail(s"No such JAR: $jar") } - try { - val entry = jarFile.getEntry(name) - if (entry == null) - fail(s"No such file in jar: $name") - else { - val name = jarFile.getName + "#" + entry.getName - val content = - IO.readInputStreamToByteArray(jarFile.getInputStream(entry)) - new MemVirtualSerializedScalaJSIRFile(name).withContent(content) - } - } finally { - jarFile.close() - } - } - - private val stdout = - new BufferedWriter(new OutputStreamWriter(Console.out, "UTF-8")) - -} diff --git a/project/Build.scala b/project/Build.scala index dd1f291504..535177277a 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -31,8 +31,6 @@ import Loggers._ import org.scalajs.core.tools.io.{FileVirtualJSFile, MemVirtualJSFile} import org.scalajs.core.tools.linker._ -import sbtassembly.AssemblyPlugin.autoImport._ - /* Things that we want to expose in the sbt command line (and hence also in * `ci/matrix.xml`). */ @@ -476,7 +474,7 @@ object Build { clean in testAdapter, clean in plugin, clean in javalanglib, clean in javalib, clean in scalalib, clean in libraryAux, clean in library, - clean in stubs, clean in cli, + clean in stubs, clean in testInterface, clean in jUnitRuntime, clean in jUnitPlugin, clean in jUnitTestOutputsJS, clean in jUnitTestOutputsJVM, @@ -1131,26 +1129,6 @@ object Build { previousArtifactSetting ) - // Scala.js command line interface - lazy val cli: Project = project.settings( - commonSettings, - publishSettings, - fatalWarningsSettings, - name := "Scala.js CLI", - libraryDependencies ++= Seq( - "com.github.scopt" %% "scopt" % "3.5.0" - ), - - previousArtifactSetting, - mimaBinaryIssueFilters ++= BinaryIncompatibilities.CLI, - - // assembly options - mainClass in assembly := None, // don't want an executable JAR - assemblyOption in assembly ~= { _.copy(includeScala = false) }, - assemblyJarName in assembly := - s"${normalizedName.value}-assembly_${scalaBinaryVersion.value}-${version.value}.jar" - ).dependsOn(tools) - // Test framework lazy val testInterface = (project in file("test-interface")).enablePlugins( MyScalaJSPlugin diff --git a/project/build.sbt b/project/build.sbt index 147636bebe..54d81ecb30 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -1,5 +1,3 @@ -addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.5") - addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.18") addSbtPlugin("org.scalastyle" % "scalastyle-sbt-plugin" % "1.0.0") diff --git a/scripts/assemble-cli.sh b/scripts/assemble-cli.sh deleted file mode 100755 index bbde804d32..0000000000 --- a/scripts/assemble-cli.sh +++ /dev/null @@ -1,105 +0,0 @@ -#! /bin/sh - -set -e - -# Assembles the CLI tools for a given Scala binary version. - -if [ $# -lt 1 ]; then - echo "Usage: $(basename $0) [noclean|nobuild]" >&2 - exit 1 -fi - -BINVER=$1 -case $BINVER in - 2.10) - FULLVERS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.10.7" - BASEVER="2.10.7" - ;; - 2.11) - FULLVERS="2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.11.12" - BASEVER="2.11.12" - ;; - 2.12) - FULLVERS="2.12.1 2.12.2 2.12.3 2.12.4" - BASEVER="2.12.4" - ;; - *) - echo "Invalid Scala version $BINVER" >&2 - exit 2 -esac - -if [ "$2" != "nobuild" ]; then - # Subshell to generate SBT commands - ( - if [ "$2" != "noclean" ]; then - echo "clean" - fi - - # Assemble cli-tools - echo "project cli" - echo "++$BASEVER" - echo "assembly" - - # Package Scala.js library - echo "project library" - echo "++$BASEVER" - echo "package" - - # Package compiler - echo "project compiler" - for i in $FULLVERS; do - echo "++$i" - echo "package" - done - ) | sbt || exit $? -fi - -# Base Scala.js project directory. -BASE="$(dirname $0)/.." - -# Determine Scala.js version. -SCALAJS_VER=$(ls $BASE/cli/target/scala-$BINVER/scalajs-cli-assembly_$BINVER-*.jar | grep -oE '[0-9]+\.[0-9]+\.[0-9]+(-SNAPSHOT|-RC[0-9]+|-M[0-9]+)?') - -# Aritfact name (no extension). -NAME=scalajs_$BINVER-$SCALAJS_VER - -# Target directories -TRG_BASE="$BASE/cli/pack" -TRG_VER="$TRG_BASE/$NAME" -TRG_LIB="$TRG_VER/lib" -TRG_BIN="$TRG_VER/bin" - -rm -rf $TRG_VER -mkdir -p $TRG_LIB -mkdir -p $TRG_BIN - -# Copy buils artifacts. -cp $BASE/cli/target/scala-$BINVER/scalajs-cli-assembly_$BINVER-$SCALAJS_VER.jar $TRG_LIB -cp $BASE/library/target/scala-$BINVER/scalajs-library_$BINVER-$SCALAJS_VER.jar $TRG_LIB - -for i in $FULLVERS; do - cp $BASE/compiler/target/scala-$BINVER/scalajs-compiler_$i-$SCALAJS_VER.jar $TRG_LIB -done - -# Build and copy launcher scripts. -PAT="s/@SCALA_BIN_VER@/$BINVER/; s/@SCALAJS_VER@/$SCALAJS_VER/" -PREF=$BASE/cli/src/main/resources/ -for i in $PREF*; do - out=$TRG_BIN/${i#$PREF} - # Redirect sed output, since in-place edit doesn't work - # cross-platform - sed "$PAT" $i > $out - # Add executable flag if required - if [ -x $i ]; then - chmod +x $out - fi -done - -# Tar and zip the whole thing up -( - cd $TRG_BASE - tar cfz $NAME.tgz --exclude '*~' $NAME - - if [ -f $NAME.zip ]; then rm $NAME.zip; fi - zip -r $NAME.zip -r $NAME -x '*~' -) From ca86e39f0fc22e6a1bedc422c3f65552d243333e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 13 Dec 2017 14:07:50 +0100 Subject: [PATCH 0580/2665] Fix #3222: Emit a .sjsir for anon JS functions in 2.11/-Xexperimental. --- .../org/scalajs/core/compiler/GenJSCode.scala | 28 +++++++++++++++---- .../testsuite/compiler/RegressionJSTest.scala | 10 +++++++ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 502a57b32e..93565f49f6 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -264,7 +264,7 @@ abstract class GenJSCode extends plugins.PluginComponent * Since for all these, we don't know how they inter-depend, we just * store them in a map at this point. */ - val (lazyAnons, fullClassDefs) = allClassDefs.partition { cd => + val (lazyAnons, fullClassDefs0) = allClassDefs.partition { cd => val sym = cd.symbol isRawJSFunctionDef(sym) || sym.isAnonymousFunction || isScalaJSDefinedAnonJSClass(sym) @@ -272,6 +272,16 @@ abstract class GenJSCode extends plugins.PluginComponent lazilyGeneratedAnonClasses ++= lazyAnons.map(cd => cd.symbol -> cd) + /* Under Scala 2.11 with -Xexperimental, anonymous JS function classes + * can be referred to in private method signatures, which means they + * must exist at the IR level, as `AbstractJSType`s. + */ + val fullClassDefs = if (isScala211WithXexperimental) { + lazyAnons.filter(cd => isRawJSFunctionDef(cd.symbol)) ::: fullClassDefs0 + } else { + fullClassDefs0 + } + /* Finally, we emit true code for the remaining class defs. */ for (cd <- fullClassDefs) { val sym = cd.symbol @@ -288,12 +298,12 @@ abstract class GenJSCode extends plugins.PluginComponent generatedSAMWrapperCount := new VarBox(0) ) { val tree = if (isRawJSType(sym.tpe)) { - assert(!isRawJSFunctionDef(sym), - s"Raw JS function def should have been recorded: $cd") - if (!sym.isTraitOrInterface && isScalaJSDefinedJSClass(sym)) + if (!sym.isTraitOrInterface && isScalaJSDefinedJSClass(sym) && + !isRawJSFunctionDef(sym)) { genScalaJSDefinedJSClass(cd) - else + } else { genRawJSClassData(cd) + } } else if (sym.isTraitOrInterface) { genInterface(cd) } else if (sym.isImplClass) { @@ -751,6 +761,7 @@ abstract class GenJSCode extends plugins.PluginComponent val classIdent = encodeClassFullNameIdent(sym) val kind = { if (sym.isTraitOrInterface) ClassKind.AbstractJSType + else if (isRawJSFunctionDef(sym)) ClassKind.AbstractJSType else if (sym.isModuleClass) ClassKind.NativeJSModuleClass else ClassKind.NativeJSClass } @@ -758,7 +769,7 @@ abstract class GenJSCode extends plugins.PluginComponent if (sym.isTraitOrInterface) None else Some(encodeClassFullNameIdent(sym.superClass)) val jsNativeLoadSpec = - if (sym.isTraitOrInterface) None + if (kind == ClassKind.AbstractJSType) None else Some(jsNativeLoadSpecOf(sym)) js.ClassDef(classIdent, kind, superClass, genClassInterfaces(sym), @@ -5349,6 +5360,11 @@ abstract class GenJSCode extends plugins.PluginComponent } } + private lazy val isScala211WithXexperimental = { + scala.util.Properties.versionNumberString.startsWith("2.11.") && + settings.Xexperimental.value + } + /** Tests whether the given type represents a raw JavaScript type, * i.e., whether it extends scala.scalajs.js.Any. */ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala index 8555f145db..42ab841ba0 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala @@ -63,6 +63,16 @@ class RegressionJSTest { assertEquals("B", c.t3()) } + @Test def emit_anon_JS_function_class_data_with_2_11_Xexperimental_issue_3222(): Unit = { + val initSourceMapper: Option[js.Function1[Int, Int]] = None + val sourceMapper: js.Function1[Int, Int] = { + initSourceMapper.getOrElse { + (s: Int) => s + } + } + assertEquals(4, sourceMapper(4)) + } + } object RegressionJSTest { From ce4004ee3caddee9a9622bf44f25a1f19e568720 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 13 Dec 2017 15:45:03 +0100 Subject: [PATCH 0581/2665] Fix #3218: Do not execute `main()` in `Test` twice for `test:run`. Running `test:run` depends on `loadedJSEnv in Test`, which itself triggered the discovery of tests, resulting in an additional instance of the .js file to be executed. This meant that the `main()` was effectively run twice when doing `test:run`. We fix this problem by backporting one change from Scala.js 1.x, which is to trigger test discovery only on `loadedTestFrameworks`, but not on `loadedJSEnv`. --- .../scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index b6af444350..94611062a1 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -1017,7 +1017,7 @@ object ScalaJSPluginInternal { // without loosing autocompletion. definedTestNames := { definedTests.map(_.map(_.name).distinct) - .storeAs(definedTestNames).triggeredBy(loadedJSEnv).value + .storeAs(definedTestNames).triggeredBy(loadedTestFrameworks).value } ) From 1854919e1cc48ddce9198b8fda39d8711169bd77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 18 Nov 2017 00:34:32 +0100 Subject: [PATCH 0582/2665] Move the fround polyfill to an implementation in JavaScript. This move does obfuscate somewhat the implementation, since we have to incorporate the optimized version rather than relying on our optimizer. However, it has three benefits. First, it was awkward that `froundPolyfill` had to return a `Double` whereas it was really returning a `Float`. This was a direct consequence of the fact that a high-level Scala method was used to implement a very low-level primitive operation. Second, the other polyfills for ECMAScript 2015 that our emitter relies on (`imul` and `clz32`) were already implemented in JavaScript. It makes more sense to be consistent in that aspect. Finally, it removes the last accidental dependency of the emitter on a non-JDK class. This means that the emitter is less dependent on Scala as a source language. --- .../scala/scala/scalajs/runtime/package.scala | 69 ------------------- tools/scalajsenv.js | 38 +++++++++- .../linker/backend/emitter/Emitter.scala | 6 +- 3 files changed, 38 insertions(+), 75 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/runtime/package.scala b/library/src/main/scala/scala/scalajs/runtime/package.scala index bef3fe8a6d..1227273857 100644 --- a/library/src/main/scala/scala/scalajs/runtime/package.scala +++ b/library/src/main/scala/scala/scalajs/runtime/package.scala @@ -139,73 +139,4 @@ package object runtime { */ def linkingInfo: LinkingInfo = throw new Error("stub") - /** Polyfill for fround in case we use strict Floats and even Typed Arrays - * are not available. - * Note: this method returns a Double, even though the value is meant - * to be a Float. It cannot return a Float because that would require to - * do `x.toFloat` somewhere in here, which would itself, in turn, call this - * method. - */ - def froundPolyfill(v: Double): Double = { - /* Originally inspired by the Typed Array polyfills written by Joshua Bell: - * https://github.com/inexorabletash/polyfill/blob/a682f42c1092280bb01907c245979fb07219513d/typedarray.js#L150-L255 - * Then simplified quite a lot because - * 1) we do not need to produce the actual bit string that serves as - * storage of the floats, and - * 2) we are only interested in the float32 case. - */ - import Math._ - - // Special cases - if (v.isNaN || v == 0.0 || v.isInfinite) { - v - } else { - val LN2 = 0.6931471805599453 - val ebits = 8 - val fbits = 23 - val bias = (1 << (ebits-1)) - 1 - val twoPowFbits = (1 << fbits).toDouble - val SubnormalThreshold = 1.1754943508222875E-38 // pow(2, 1-bias) - - val isNegative = v < 0 - val av = if (isNegative) -v else v - - val absResult = if (av >= SubnormalThreshold) { - val e0 = floor(log(av) / LN2) - // 1-bias <= e0 <= 1024 - if (e0 > bias) { - // Overflow - Double.PositiveInfinity - } else { - val twoPowE0 = pow(2, e0) - val f0 = Bits.roundToEven(av / twoPowE0 * twoPowFbits) - if (f0 / twoPowFbits >= 2) { - //val e = e0 + 1.0 // not used - val f = 1.0 - if (e0 > bias-1) { // === (e > bias) because e0 is whole - // Overflow - Double.PositiveInfinity - } else { - // Normalized case 1 - val twoPowE = 2*twoPowE0 - twoPowE * (1.0 + (f - twoPowFbits) / twoPowFbits) - } - } else { - // Normalized case 2 - // val e = e0 // not used - val f = f0 - val twoPowE = twoPowE0 - twoPowE * (1.0 + (f - twoPowFbits) / twoPowFbits) - } - } - } else { - // Subnormal - val rounder = Float.MinPositiveValue.toDouble - Bits.roundToEven(av / rounder) * rounder - } - - if (isNegative) -absResult else absResult - } - } - } diff --git a/tools/scalajsenv.js b/tools/scalajsenv.js index 3571a4b98a..c3b3f93b11 100644 --- a/tools/scalajsenv.js +++ b/tools/scalajsenv.js @@ -94,7 +94,43 @@ const $fround = Math["fround"] || array[0] = v; return array[0]; }) : (function(v) { - return $m_sjsr_package$().froundPolyfill__D__D(+v); + /* Originally inspired by the Typed Array polyfills written by Joshua Bell: + * https://github.com/inexorabletash/polyfill/blob/a682f42c1092280bb01907c245979fb07219513d/typedarray.js#L150-L255 + * Then simplified quite a lot because + * 1) we do not need to produce the actual bit string that serves as + * storage of the floats, and + * 2) we are only interested in the float32 case. + */ + if (v !== v || v === 0 || v === Infinity || v === -Infinity) + return v; + const isNegative = v < 0; + const av = isNegative ? -v : v; + let absResult; + if (av >= 1.1754943508222875e-38) { // subnormal threshold + const e0 = Math["floor"](Math["log"](av) / 0.6931471805599453); // LN2 + if (e0 > 127) { // bias + absResult = Infinity; + } else { + const twoPowE0 = Math["pow"](2, e0); + const n1 = 8388608 * (av / twoPowE0); // 2 ** 23 (mantissa bits) + const w1 = Math["floor"](n1); + const d1 = n1 - w1; + const f0 = (d1 < 0.5) ? w1 : ((d1 > 0.5) ? (1 + w1) : (((w1 % 2) !== 0) ? (1 + w1) : w1)); + if ((f0 / 8388608) < 2) + absResult = twoPowE0 * (1 + ((f0-8388608) / 8388608)); + else if (e0 > 126) + absResult = Infinity; + else + absResult = (2 * twoPowE0) * 1.1920928955078125e-7; // (1 + ((1-8388608) / 8388608)) + } + } else { + const rounder = 1.401298464324817e-45; // Float.MinPositiveValue + const n2 = av / rounder; + const w2 = Math["floor"](n2); + const d2 = n2 - w2; + absResult = rounder * ((d2 < 0.5) ? w2 : ((d2 > 0.5) ? (1 + w2) : (((w2 % 2) !== 0) ? (1 + w2) : w2))); + }; + return isNegative ? -absResult : absResult; })); //!else (function(v) { diff --git 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 index 12f3f1e9ea..4241213a0f 100644 --- 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 @@ -681,11 +681,7 @@ private object Emitter { instantiateClass(LongImpl.RuntimeLongClass, LongImpl.AllConstructors), callMethods(LongImpl.RuntimeLongClass, LongImpl.AllMethods), - callOnModule(LongImpl.RuntimeLongModuleClass, LongImpl.AllModuleMethods), - - cond(strictFloats && !assumingES6) { - callOnModule("sjsr_package$", "froundPolyfill__D__D") - } + callOnModule(LongImpl.RuntimeLongModuleClass, LongImpl.AllModuleMethods) ) } From 6d8edb5ed58e45910cccf4fceb55bd1a608f6928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 19 Nov 2017 13:37:57 +0100 Subject: [PATCH 0583/2665] Move EnvironmentInfo and StackTrace to `java.lang`. The only consumers of those two objects, which were previously part of `scala.scalajs.runtime`, were in `java.lang`. We can therefore hide them as `private[lang]`. There were two exceptions, though: the tests for `StackTraceElement`, and `JavaScriptException.fillInStackTrace`. Those were relying on some APIs available in `StackTrace`. However, both usages were (indirectly) accessing some "magic" fields stacked onto `StackTraceElement` and `Throwable` using the JS API. In the case of `Throwable`, it was even relying on undefined behavior (adding a field at run-time). We fix those issues and make the whole thing more reliable by using reflective calls instead of JS APIs. --- ci/checksizes.sh | 6 ++-- .../scala/java/lang}/EnvironmentInfo.scala | 9 +++--- .../src/main/scala/java/lang/Runtime.scala | 2 +- .../main/scala/java/lang}/StackTrace.scala | 30 ++++--------------- .../scala/java/lang/StackTraceElement.scala | 8 +++-- .../src/main/scala/java/lang/System.scala | 2 +- .../src/main/scala/java/lang/Thread.scala | 2 +- .../src/main/scala/java/lang/Throwables.scala | 17 +++++++++-- .../scalajs/js/JavaScriptException.scala | 9 +++++- .../resources/SourceMapTestTemplate.scala | 2 +- .../lang/StackTraceElementJSTest.scala | 29 +++++++++++++++--- 11 files changed, 72 insertions(+), 44 deletions(-) rename {library/src/main/scala/scala/scalajs/runtime => javalanglib/src/main/scala/java/lang}/EnvironmentInfo.scala (89%) rename {library/src/main/scala/scala/scalajs/runtime => javalanglib/src/main/scala/java/lang}/StackTrace.scala (95%) diff --git a/ci/checksizes.sh b/ci/checksizes.sh index 63c6c8203f..9551935f68 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -37,13 +37,13 @@ REVERSI_OPT_GZ_SIZE=$(stat '-c%s' "$REVERSI_OPT.gz") case $FULLVER in 2.10.2) - REVERSI_PREOPT_EXPECTEDSIZE=511000 + REVERSI_PREOPT_EXPECTEDSIZE=512000 REVERSI_OPT_EXPECTEDSIZE=115000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=69000 REVERSI_OPT_GZ_EXPECTEDSIZE=30000 ;; 2.11.12) - REVERSI_PREOPT_EXPECTEDSIZE=506000 + REVERSI_PREOPT_EXPECTEDSIZE=507000 REVERSI_OPT_EXPECTEDSIZE=116000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=69000 REVERSI_OPT_GZ_EXPECTEDSIZE=30000 @@ -55,7 +55,7 @@ case $FULLVER in REVERSI_OPT_GZ_EXPECTEDSIZE=32000 ;; 2.13.0-M2) - REVERSI_PREOPT_EXPECTEDSIZE=604000 + REVERSI_PREOPT_EXPECTEDSIZE=605000 REVERSI_OPT_EXPECTEDSIZE=138000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=74000 REVERSI_OPT_GZ_EXPECTEDSIZE=32000 diff --git a/library/src/main/scala/scala/scalajs/runtime/EnvironmentInfo.scala b/javalanglib/src/main/scala/java/lang/EnvironmentInfo.scala similarity index 89% rename from library/src/main/scala/scala/scalajs/runtime/EnvironmentInfo.scala rename to javalanglib/src/main/scala/java/lang/EnvironmentInfo.scala index 6630e15e21..1825f27e20 100644 --- a/library/src/main/scala/scala/scalajs/runtime/EnvironmentInfo.scala +++ b/javalanglib/src/main/scala/java/lang/EnvironmentInfo.scala @@ -1,4 +1,4 @@ -package scala.scalajs.runtime +package java.lang import scala.scalajs.js @@ -10,7 +10,8 @@ import StackTrace.JSStackTraceElem * directly (could be retrieved via [[EnvironmentInfo.envInfo]]). * * This facade type serves as a documentation on what aspects of the Scala.js - * standard library can be influenced through environment options. + * implementation of `java.lang` can be influenced through environment + * options. * * If there is a variable named `__ScalaJSEnv` in Scala.js' scope (and it * references an object), it is used as the value of @@ -19,7 +20,7 @@ import StackTrace.JSStackTraceElem * @groupname envInfo Scala.js environment configuration * @groupprio envInfo 1 */ -sealed trait EnvironmentInfo extends js.Object { +private[lang] sealed trait EnvironmentInfo extends js.Object { // Can't link to java.lang.Runtime.exit - #1969 /** The function that is called by `java.lang.Runtime.exit` @@ -42,7 +43,7 @@ sealed trait EnvironmentInfo extends js.Object { def javaSystemProperties: js.UndefOr[js.Dictionary[String]] } -object EnvironmentInfo { +private[lang] object EnvironmentInfo { /** The value of the `__ScalaJSEnv` variable, if it exists. */ val envInfo: js.UndefOr[EnvironmentInfo] = { import js.Dynamic.{global => g} diff --git a/javalanglib/src/main/scala/java/lang/Runtime.scala b/javalanglib/src/main/scala/java/lang/Runtime.scala index 0019680b37..ff32547174 100644 --- a/javalanglib/src/main/scala/java/lang/Runtime.scala +++ b/javalanglib/src/main/scala/java/lang/Runtime.scala @@ -10,7 +10,7 @@ class Runtime private { //def removeShutdownHook(hook: Thread): Unit def halt(status: Int): Unit = { - val envInfo = scala.scalajs.runtime.EnvironmentInfo.envInfo + val envInfo = EnvironmentInfo.envInfo envInfo.flatMap(_.exitFunction).fold { // We don't have an exit function. Fail diff --git a/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala b/javalanglib/src/main/scala/java/lang/StackTrace.scala similarity index 95% rename from library/src/main/scala/scala/scalajs/runtime/StackTrace.scala rename to javalanglib/src/main/scala/java/lang/StackTrace.scala index d665e92fec..6618b314dd 100644 --- a/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala +++ b/javalanglib/src/main/scala/java/lang/StackTrace.scala @@ -1,4 +1,4 @@ -package scala.scalajs.runtime +package java.lang import scala.annotation.tailrec @@ -7,7 +7,7 @@ import js.JSStringOps._ /** Conversions of JavaScript stack traces to Java stack traces. */ -object StackTrace { +private[lang] object StackTrace { /* !!! Note that in this unit, we go to great lengths *not* to use anything * from the Scala collections library. @@ -16,8 +16,6 @@ object StackTrace { * errors, which would be very bad if it happened. */ - import Implicits._ - private type SourceMapper = js.Function1[js.Array[JSStackTraceElem], js.Array[JSStackTraceElem]] @@ -69,7 +67,7 @@ object StackTrace { * by `extract()` to create an Array[StackTraceElement]. */ @inline def captureState(throwable: Throwable, e: Any): Unit = - throwable.asInstanceOf[js.Dynamic].stackdata = e.asInstanceOf[js.Any] + throwable.setStackTraceStateInternal(e) /** Tests whether we're running under Rhino (or Nashorn). * @@ -93,15 +91,15 @@ object StackTrace { * empty array is returned. */ def extract(throwable: Throwable): Array[StackTraceElement] = - extract(throwable.asInstanceOf[js.Dynamic].stackdata) + extract(throwable.getStackTraceStateInternal()) /** Extracts a stack trace from captured browser-specific stackdata. * If no stack trace state has been recorded, or if the state cannot be * analyzed in meaningful way (because we don't know the browser), an * empty array is returned. */ - def extract(stackdata: js.Dynamic): Array[StackTraceElement] = { - val lines = normalizeStackTraceLines(stackdata) + private def extract(stackdata: Any): Array[StackTraceElement] = { + val lines = normalizeStackTraceLines(stackdata.asInstanceOf[js.Dynamic]) normalizedLinesToStackTrace(lines) } @@ -530,20 +528,4 @@ object StackTrace { } } - object Implicits { - /** Access to the additional methods `getColumnNumber` and `setColumnNumber` - * of [[java.lang.StackTraceElement StackTraceElement]]. - */ - implicit class StackTraceElementOps( - val ste: StackTraceElement) extends AnyVal { - @inline - def getColumnNumber(): Int = - ste.asInstanceOf[js.Dynamic].getColumnNumber().asInstanceOf[Int] - - @inline - def setColumnNumber(columnNumber: Int): Unit = - ste.asInstanceOf[js.Dynamic].setColumnNumber(columnNumber) - } - } - } diff --git a/javalanglib/src/main/scala/java/lang/StackTraceElement.scala b/javalanglib/src/main/scala/java/lang/StackTraceElement.scala index 92aaba4c36..67d5e99e41 100644 --- a/javalanglib/src/main/scala/java/lang/StackTraceElement.scala +++ b/javalanglib/src/main/scala/java/lang/StackTraceElement.scala @@ -14,10 +14,14 @@ final class StackTraceElement(declaringClass: String, methodName: String, def getMethodName(): String = methodName def isNativeMethod(): scala.Boolean = false - @JSExport + /* Not part of the JDK API, used internally in java.lang and accessible + * through reflection. + */ def getColumnNumber(): Int = columnNumber - @JSExport + /* Not part of the JDK API, used internally in java.lang and accessible + * through reflection. + */ def setColumnNumber(columnNumber: Int): Unit = this.columnNumber = columnNumber diff --git a/javalanglib/src/main/scala/java/lang/System.scala b/javalanglib/src/main/scala/java/lang/System.scala index 59bfe97a0f..5a8d3aac96 100644 --- a/javalanglib/src/main/scala/java/lang/System.scala +++ b/javalanglib/src/main/scala/java/lang/System.scala @@ -241,7 +241,7 @@ object System { sysProp.setProperty("line.separator", "\n") for { - envInfo <- scala.scalajs.runtime.EnvironmentInfo.envInfo + envInfo <- EnvironmentInfo.envInfo jsEnvProperties <- envInfo.javaSystemProperties (key, value) <- jsEnvProperties } { diff --git a/javalanglib/src/main/scala/java/lang/Thread.scala b/javalanglib/src/main/scala/java/lang/Thread.scala index 6a131deaaf..2ec21246da 100644 --- a/javalanglib/src/main/scala/java/lang/Thread.scala +++ b/javalanglib/src/main/scala/java/lang/Thread.scala @@ -24,7 +24,7 @@ class Thread private (dummy: Unit) extends Runnable { this.name def getStackTrace(): Array[StackTraceElement] = - scala.scalajs.runtime.StackTrace.getCurrentStackTrace() + StackTrace.getCurrentStackTrace() def getId(): scala.Long = 1 } diff --git a/javalanglib/src/main/scala/java/lang/Throwables.scala b/javalanglib/src/main/scala/java/lang/Throwables.scala index d3e3e3eb59..201aba21de 100644 --- a/javalanglib/src/main/scala/java/lang/Throwables.scala +++ b/javalanglib/src/main/scala/java/lang/Throwables.scala @@ -7,6 +7,7 @@ class Throwable(s: String, private var e: Throwable) extends Object with java.io def this(s: String) = this(s, null) def this(e: Throwable) = this(if (e == null) null else e.toString, e) + private[this] var stackTraceStateInternal: Any = _ private[this] var stackTrace: Array[StackTraceElement] = _ fillInStackTrace() @@ -21,13 +22,25 @@ class Throwable(s: String, private var e: Throwable) extends Object with java.io def getLocalizedMessage(): String = getMessage() def fillInStackTrace(): Throwable = { - scala.scalajs.runtime.StackTrace.captureState(this) + StackTrace.captureState(this) this } + /* Not part of the JDK API, used internally in java.lang and accessible + * through reflection. + */ + def getStackTraceStateInternal(): Any = + stackTraceStateInternal + + /* Not part of the JDK API, used internally in java.lang and accessible + * through reflection. + */ + def setStackTraceStateInternal(e: Any): Unit = + stackTraceStateInternal = e + def getStackTrace(): Array[StackTraceElement] = { if (stackTrace eq null) - stackTrace = scala.scalajs.runtime.StackTrace.extract(this) + stackTrace = StackTrace.extract(this) stackTrace } diff --git a/library/src/main/scala/scala/scalajs/js/JavaScriptException.scala b/library/src/main/scala/scala/scalajs/js/JavaScriptException.scala index 30034d6484..84f4d6ce58 100644 --- a/library/src/main/scala/scala/scalajs/js/JavaScriptException.scala +++ b/library/src/main/scala/scala/scalajs/js/JavaScriptException.scala @@ -10,13 +10,20 @@ package scala.scalajs.js +import scala.language.reflectiveCalls + +import scala.scalajs.js + final case class JavaScriptException(exception: scala.Any) extends RuntimeException { override def getMessage(): String = exception.toString() override def fillInStackTrace(): Throwable = { - scala.scalajs.runtime.StackTrace.captureState(this, exception) + type JSExceptionEx = JavaScriptException { + def setStackTraceStateInternal(e: scala.Any): Unit + } + this.asInstanceOf[JSExceptionEx].setStackTraceStateInternal(exception) this } } diff --git a/test-suite/js/src/test/resources/SourceMapTestTemplate.scala b/test-suite/js/src/test/resources/SourceMapTestTemplate.scala index 189226833d..e3158191e3 100644 --- a/test-suite/js/src/test/resources/SourceMapTestTemplate.scala +++ b/test-suite/js/src/test/resources/SourceMapTestTemplate.scala @@ -55,7 +55,7 @@ class SourceMapTest { val trace0 = e.getStackTrace.toList val trace1 = trace0.dropWhile( - normFileName(_).endsWith("/scala/scalajs/runtime/StackTrace.scala")) + normFileName(_).endsWith("/java/lang/StackTrace.scala")) val trace2 = trace1.dropWhile( normFileName(_).endsWith("/java/lang/Throwables.scala")) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/StackTraceElementJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/StackTraceElementJSTest.scala index 77557426fc..bff4aa8ef0 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/StackTraceElementJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/StackTraceElementJSTest.scala @@ -7,16 +7,37 @@ \* */ package org.scalajs.testsuite.javalib.lang +import scala.language.reflectiveCalls + +import scala.scalajs.js + import org.junit.Assert._ import org.junit.Test class StackTraceElementJSTest { - import scala.scalajs.runtime.StackTrace.Implicits._ + private type StackTraceElementEx = StackTraceElement { + def getColumnNumber(): Int + def setColumnNumber(columnNumber: Int): Unit + } + + private def getColumnNumber(ste: StackTraceElement): Int = + ste.asInstanceOf[StackTraceElementEx].getColumnNumber() + + private def setColumnNumber(ste: StackTraceElement, columnNumber: Int): Unit = + ste.asInstanceOf[StackTraceElementEx].setColumnNumber(columnNumber) + + @Test def columnNumber(): Unit = { + val ste = new StackTraceElement("MyClass", "myMethod", "myFile.scala", 1) + assertEquals(-1, getColumnNumber(ste)) + setColumnNumber(ste, 5) + assertEquals(5, getColumnNumber(ste)) + } @Test def should_use_the_additional_columnNumber_field_in_its_toString(): Unit = { - val st = new StackTraceElement("MyClass", "myMethod", "myFile.scala", 1) - st.setColumnNumber(5) - assertEquals("MyClass.myMethod(myFile.scala:1:5)", st.toString) + val ste = new StackTraceElement("MyClass", "myMethod", "myFile.scala", 1) + assertEquals("MyClass.myMethod(myFile.scala:1)", ste.toString) + setColumnNumber(ste, 5) + assertEquals("MyClass.myMethod(myFile.scala:1:5)", ste.toString) } } From 7603b44225d2ba7be4c1d78589da7a0d57a7f3c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 19 Nov 2017 17:01:00 +0100 Subject: [PATCH 0584/2665] Move `runtime.Bits` to `java.lang.FloatingPointBits`. The main role of `Bits` is to manipulate the bits of floating-point numbers, and the only consumers of that API were `java.lang.Float` and `java.lang.Double`. Two places (nio Buffers and `testsuite.utils.Platform`) reused some of the detection of typed arrays performed in `Bits`, but it makes more sense that they do it on their own. --- .../src/main/scala/java/lang/Double.scala | 6 +- .../src/main/scala/java/lang/Float.scala | 7 +-- .../scala/java/lang/FloatingPointBits.scala | 55 ++++++++----------- .../src/main/scala/java/nio/ByteOrder.scala | 15 ++++- .../scala/java/nio/TypedArrayByteBuffer.scala | 4 +- .../scalajs/testsuite/utils/Platform.scala | 2 +- 6 files changed, 46 insertions(+), 43 deletions(-) rename library/src/main/scala/scala/scalajs/runtime/Bits.scala => javalanglib/src/main/scala/java/lang/FloatingPointBits.scala (81%) diff --git a/javalanglib/src/main/scala/java/lang/Double.scala b/javalanglib/src/main/scala/java/lang/Double.scala index 70bda3fbb3..1259f714f0 100644 --- a/javalanglib/src/main/scala/java/lang/Double.scala +++ b/javalanglib/src/main/scala/java/lang/Double.scala @@ -185,13 +185,13 @@ object Double { !isNaN(d) && !isInfinite(d) @inline def hashCode(value: scala.Double): Int = - scala.scalajs.runtime.Bits.numberHashCode(value) + FloatingPointBits.numberHashCode(value) @inline def longBitsToDouble(bits: scala.Long): scala.Double = - scala.scalajs.runtime.Bits.longBitsToDouble(bits) + FloatingPointBits.longBitsToDouble(bits) @inline def doubleToLongBits(value: scala.Double): scala.Long = - scala.scalajs.runtime.Bits.doubleToLongBits(value) + FloatingPointBits.doubleToLongBits(value) @inline def sum(a: scala.Double, b: scala.Double): scala.Double = a + b diff --git a/javalanglib/src/main/scala/java/lang/Float.scala b/javalanglib/src/main/scala/java/lang/Float.scala index ed427a1071..867e34052a 100644 --- a/javalanglib/src/main/scala/java/lang/Float.scala +++ b/javalanglib/src/main/scala/java/lang/Float.scala @@ -125,15 +125,14 @@ object Float { @inline def isFinite(f: scala.Float): scala.Boolean = !isNaN(f) && !isInfinite(f) - // Uses the hashCode of Doubles. See Bits.numberHashCode for the rationale. @inline def hashCode(value: scala.Float): Int = - scala.scalajs.runtime.Bits.numberHashCode(value) + FloatingPointBits.numberHashCode(value) @inline def intBitsToFloat(bits: scala.Int): scala.Float = - scala.scalajs.runtime.Bits.intBitsToFloat(bits) + FloatingPointBits.intBitsToFloat(bits) @inline def floatToIntBits(value: scala.Float): scala.Int = - scala.scalajs.runtime.Bits.floatToIntBits(value) + FloatingPointBits.floatToIntBits(value) @inline def sum(a: scala.Float, b: scala.Float): scala.Float = a + b diff --git a/library/src/main/scala/scala/scalajs/runtime/Bits.scala b/javalanglib/src/main/scala/java/lang/FloatingPointBits.scala similarity index 81% rename from library/src/main/scala/scala/scalajs/runtime/Bits.scala rename to javalanglib/src/main/scala/java/lang/FloatingPointBits.scala index eb94a0763a..5f0afcabce 100644 --- a/library/src/main/scala/scala/scalajs/runtime/Bits.scala +++ b/javalanglib/src/main/scala/java/lang/FloatingPointBits.scala @@ -1,20 +1,11 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package scala.scalajs.runtime +package java.lang import scala.scalajs.js import js.Dynamic.global import js.typedarray -/** Low-level stuff. */ -object Bits { +/** Manipulating the bits of floating point numbers. */ +private[lang] object FloatingPointBits { import scala.scalajs.LinkingInfo.assumingES6 @@ -29,7 +20,7 @@ object Bits { } @inline - def areTypedArraysSupported: Boolean = { + private def areTypedArraysSupported: scala.Boolean = { /* We have a forwarder to the internal `val _areTypedArraysSupported` to * be able to inline it. This achieves the following: * * If we emit ES6, dce `|| _areTypedArraysSupported` and replace @@ -57,7 +48,7 @@ object Bits { if (areTypedArraysSupported) new typedarray.Float64Array(arrayBuffer, 0, 1) else null - val areTypedArraysBigEndian = { + private val areTypedArraysBigEndian = { if (areTypedArraysSupported) { int32Array(0) = 0x01020304 (new typedarray.Int8Array(arrayBuffer, 0, 8))(0) == 0x01 @@ -82,13 +73,13 @@ object Bits { * the Double version should typically be faster on VMs without fround * support because we avoid several fround operations. */ - def numberHashCode(value: Double): Int = { + def numberHashCode(value: scala.Double): Int = { val iv = rawToInt(value) - if (iv == value && 1.0/value != Double.NegativeInfinity) iv + if (iv == value && 1.0/value != scala.Double.NegativeInfinity) iv else doubleToLongBits(value).hashCode() } - def intBitsToFloat(bits: Int): Float = { + def intBitsToFloat(bits: Int): scala.Float = { if (areTypedArraysSupported) { int32Array(0) = bits float32Array(0) @@ -97,7 +88,7 @@ object Bits { } } - def floatToIntBits(value: Float): Int = { + def floatToIntBits(value: scala.Float): Int = { if (areTypedArraysSupported) { float32Array(0) = value int32Array(0) @@ -106,7 +97,7 @@ object Bits { } } - def longBitsToDouble(bits: Long): Double = { + def longBitsToDouble(bits: scala.Long): scala.Double = { if (areTypedArraysSupported) { int32Array(highOffset) = (bits >>> 32).toInt int32Array(lowOffset) = bits.toInt @@ -116,7 +107,7 @@ object Bits { } } - def doubleToLongBits(value: Double): Long = { + def doubleToLongBits(value: scala.Double): scala.Long = { if (areTypedArraysSupported) { float64Array(0) = value ((int32Array(highOffset).toLong << 32) | @@ -138,7 +129,7 @@ object Bits { * predictable, since the results do not depend on strict floats semantics. */ - private def intBitsToFloatPolyfill(bits: Int): Double = { + private def intBitsToFloatPolyfill(bits: Int): scala.Double = { val ebits = 8 val fbits = 23 val s = bits < 0 @@ -147,14 +138,14 @@ object Bits { decodeIEEE754(ebits, fbits, s, e, f) } - private def floatToIntBitsPolyfill(value: Double): Int = { + private def floatToIntBitsPolyfill(value: scala.Double): Int = { val ebits = 8 val fbits = 23 val (s, e, f) = encodeIEEE754(ebits, fbits, value) (if (s) 0x80000000 else 0) | (e << fbits) | rawToInt(f) } - private def longBitsToDoublePolyfill(bits: Long): Double = { + private def longBitsToDoublePolyfill(bits: scala.Long): scala.Double = { import js.JSNumberOps._ val ebits = 11 @@ -168,7 +159,7 @@ object Bits { decodeIEEE754(ebits, fbits, s, e, f) } - private def doubleToLongBitsPolyfill(value: Double): Long = { + private def doubleToLongBitsPolyfill(value: scala.Double): scala.Long = { val ebits = 11 val fbits = 52 val hifbits = fbits-32 @@ -180,7 +171,7 @@ object Bits { } @inline private def decodeIEEE754(ebits: Int, fbits: Int, - s: Boolean, e: Int, f: Double): Double = { + s: scala.Boolean, e: Int, f: scala.Double): scala.Double = { import Math.pow @@ -188,9 +179,9 @@ object Bits { if (e == (1 << ebits) - 1) { // Special - if (f != 0.0) Double.NaN - else if (s) Double.NegativeInfinity - else Double.PositiveInfinity + if (f != 0.0) scala.Double.NaN + else if (s) scala.Double.NegativeInfinity + else scala.Double.PositiveInfinity } else if (e > 0) { // Normalized val x = pow(2, e-bias) * (1 + f / pow(2, fbits)) @@ -206,7 +197,7 @@ object Bits { } @inline private def encodeIEEE754(ebits: Int, fbits: Int, - v: Double): (Boolean, Int, Double) = { + v: scala.Double): (scala.Boolean, Int, scala.Double) = { import Math._ @@ -218,7 +209,7 @@ object Bits { } else if (v.isInfinite) { (v < 0, (1 << ebits) - 1, 0.0) } else if (v == 0.0) { - (1 / v == Double.NegativeInfinity, 0, 0.0) + (1 / v == scala.Double.NegativeInfinity, 0, 0.0) } else { val LN2 = 0.6931471805599453 @@ -264,10 +255,10 @@ object Bits { } } - @inline private def rawToInt(x: Double): Int = + @inline private def rawToInt(x: scala.Double): Int = (x.asInstanceOf[js.Dynamic] | 0.asInstanceOf[js.Dynamic]).asInstanceOf[Int] - @inline private[runtime] def roundToEven(n: Double): Double = { + @inline private def roundToEven(n: scala.Double): scala.Double = { val w = Math.floor(n) val f = n - w if (f < 0.5) w diff --git a/javalib/src/main/scala/java/nio/ByteOrder.scala b/javalib/src/main/scala/java/nio/ByteOrder.scala index 20bac6a506..3d5497c936 100644 --- a/javalib/src/main/scala/java/nio/ByteOrder.scala +++ b/javalib/src/main/scala/java/nio/ByteOrder.scala @@ -1,5 +1,8 @@ package java.nio +import scala.scalajs.js +import scala.scalajs.js.typedarray._ + final class ByteOrder private (name: String) { override def toString(): String = name } @@ -8,8 +11,18 @@ object ByteOrder { val BIG_ENDIAN: ByteOrder = new ByteOrder("BIG_ENDIAN") val LITTLE_ENDIAN: ByteOrder = new ByteOrder("LITTLE_ENDIAN") + private[nio] val areTypedArraysBigEndian = { + if (js.typeOf(js.Dynamic.global.Int32Array) != "undefined") { + val arrayBuffer = new ArrayBuffer(4) + (new Int32Array(arrayBuffer))(0) = 0x01020304 + (new Int8Array(arrayBuffer))(0) == 0x01 + } else { + true // as good a value as any + } + } + def nativeOrder(): ByteOrder = { - if (scala.scalajs.runtime.Bits.areTypedArraysBigEndian) BIG_ENDIAN + if (areTypedArraysBigEndian) BIG_ENDIAN else LITTLE_ENDIAN } } diff --git a/javalib/src/main/scala/java/nio/TypedArrayByteBuffer.scala b/javalib/src/main/scala/java/nio/TypedArrayByteBuffer.scala index c9fc816fed..f42f48cc20 100644 --- a/javalib/src/main/scala/java/nio/TypedArrayByteBuffer.scala +++ b/javalib/src/main/scala/java/nio/TypedArrayByteBuffer.scala @@ -65,7 +65,7 @@ private[nio] final class TypedArrayByteBuffer private ( @inline def hasNativeOrder: Boolean = - isBigEndian == scala.scalajs.runtime.Bits.areTypedArraysBigEndian + isBigEndian == ByteOrder.areTypedArraysBigEndian @noinline def getChar(): Char = _dataView.getUint16(getPosAndAdvanceRead(2), !isBigEndian).toChar @@ -221,7 +221,7 @@ private[nio] object TypedArrayByteBuffer { def wrap(typedArray: Int8Array): ByteBuffer = { val buf = new TypedArrayByteBuffer(typedArray, 0, typedArray.length, false) - buf._isBigEndian = scala.scalajs.runtime.Bits.areTypedArraysBigEndian + buf._isBigEndian = ByteOrder.areTypedArraysBigEndian buf } } diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala index a7b8cda5ef..3c32a5308d 100644 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala +++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala @@ -28,7 +28,7 @@ object Platform { // (i.e. do no link on the JVM). def areTypedArraysSupported: Boolean = - runtime.Bits.areTypedArraysSupported + js.typeOf(js.Dynamic.global.Int32Array) != "undefined" def areJSSymbolsSupported: Boolean = js.typeOf(js.Dynamic.global.Symbol) != "undefined" From 5d2e2d2b9967a27c5fb8889ed83063174387a2fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 20 Dec 2017 18:12:25 +0100 Subject: [PATCH 0585/2665] Get rid of the MathJDK8Bridge hack. Now that we only build on JDK8+, we do not need this hack anymore. --- .../main/scala/java/lang/MathJDK8Bridge.scala | 81 ------------------- .../main/scala/java/lang/MathJDK8Bridge.scala | 74 ----------------- .../src/main/scala/java/math/Conversion.scala | 4 +- .../src/main/scala/java/math/Division.scala | 10 +-- project/Build.scala | 9 +-- 5 files changed, 9 insertions(+), 169 deletions(-) delete mode 100644 javalanglib/src/main/scala/java/lang/MathJDK8Bridge.scala delete mode 100644 javalib/src/main/scala/java/lang/MathJDK8Bridge.scala diff --git a/javalanglib/src/main/scala/java/lang/MathJDK8Bridge.scala b/javalanglib/src/main/scala/java/lang/MathJDK8Bridge.scala deleted file mode 100644 index 51f16451e6..0000000000 --- a/javalanglib/src/main/scala/java/lang/MathJDK8Bridge.scala +++ /dev/null @@ -1,81 +0,0 @@ -/* !!!!! - * THIS FILE IS ALMOST COPY-PASTED IN javalanglib/ AND javalib/. - * THEY MUST BE KEPT IN SYNC. - * - * This file acts as a bridge for java.lang.Math to be able to access the - * additional methods introduced in JDK 8 from javalib/ even when compiling - * under JDK 6 or 7. - * - * In javalib/, this file has only the signatures, with stub implementations. - * In javalanglib/, the methods delegate to the corresponding methods in - * java.lang.Math. - * The build only keeps the .sjsir file from javalanglib/. - * This way, we create a bridge between javalanglib and javalib. But that - * means the binary interface of MathJDK8Bridge must be strictly equivalent in - * the two copies. - * - * (Yes, this is a hack.) - * !!!!! - */ - -package java.lang - -private[java] object MathJDK8Bridge { - def addExact(a: scala.Int, b: scala.Int): scala.Int = Math.addExact(a, b) - - def addExact(a: scala.Long, b: scala.Long): scala.Long = Math.addExact(a, b) - - def subtractExact(a: scala.Int, b: scala.Int): scala.Int = - Math.subtractExact(a, b) - - def subtractExact(a: scala.Long, b: scala.Long): scala.Long = - Math.subtractExact(a, b) - - def multiplyExact(a: scala.Int, b: scala.Int): scala.Int = - Math.multiplyExact(a, b) - - def multiplyExact(a: scala.Long, b: scala.Long): scala.Long = - Math.multiplyExact(a, b) - - def incrementExact(a: scala.Int): scala.Int = Math.incrementExact(a) - - def incrementExact(a: scala.Long): scala.Long = Math.incrementExact(a) - - def decrementExact(a: scala.Int): scala.Int = Math.decrementExact(a) - - def decrementExact(a: scala.Long): scala.Long = Math.decrementExact(a) - - def negateExact(a: scala.Int): scala.Int = Math.negateExact(a) - - def negateExact(a: scala.Long): scala.Long = Math.negateExact(a) - - def toIntExact(a: scala.Long): scala.Int = Math.toIntExact(a) - - def floorDiv(a: scala.Int, b: scala.Int): scala.Int = Math.floorDiv(a, b) - - def floorDiv(a: scala.Long, b: scala.Long): scala.Long = Math.floorDiv(a, b) - - def floorMod(a: scala.Int, b: scala.Int): scala.Int = Math.floorMod(a, b) - - def floorMod(a: scala.Long, b: scala.Long): scala.Long = Math.floorMod(a, b) - - // A few other Math-related methods that are not really in Math - - def toUnsignedString(i: scala.Int): String = - Integer.toUnsignedString(i) - - def toUnsignedString(i: scala.Long): String = - Long.toUnsignedString(i) - - def divideUnsigned(a: scala.Int, b: scala.Int): scala.Int = - Integer.divideUnsigned(a, b) - - def divideUnsigned(a: scala.Long, b: scala.Long): scala.Long = - Long.divideUnsigned(a, b) - - def remainderUnsigned(a: scala.Int, b: scala.Int): scala.Int = - Integer.remainderUnsigned(a, b) - - def remainderUnsigned(a: scala.Long, b: scala.Long): scala.Long = - Long.remainderUnsigned(a, b) -} diff --git a/javalib/src/main/scala/java/lang/MathJDK8Bridge.scala b/javalib/src/main/scala/java/lang/MathJDK8Bridge.scala deleted file mode 100644 index d3f081fd93..0000000000 --- a/javalib/src/main/scala/java/lang/MathJDK8Bridge.scala +++ /dev/null @@ -1,74 +0,0 @@ -/* !!!!! - * THIS FILE IS ALMOST COPY-PASTED IN javalanglib/ AND javalib/. - * THEY MUST BE KEPT IN SYNC. - * - * This file acts as a bridge for java.lang.Math to be able to access the - * additional methods introduced in JDK 8 from javalib/ even when compiling - * under JDK 6 or 7. - * - * In javalib/, this file has only the signatures, with stub implementations. - * In javalanglib/, the methods delegate to the corresponding methods in - * java.lang.Math. - * The build only keeps the .sjsir file from javalanglib/. - * This way, we create a bridge between javalanglib and javalib. But that - * means the binary interface of MathJDK8Bridge must be strictly equivalent in - * the two copies. - * - * (Yes, this is a hack.) - * !!!!! - */ - -package java.lang - -private[java] object MathJDK8Bridge { - def addExact(a: scala.Int, b: scala.Int): scala.Int = stub() - - def addExact(a: scala.Long, b: scala.Long): scala.Long = stub() - - def subtractExact(a: scala.Int, b: scala.Int): scala.Int = stub() - - def subtractExact(a: scala.Long, b: scala.Long): scala.Long = stub() - - def multiplyExact(a: scala.Int, b: scala.Int): scala.Int = stub() - - def multiplyExact(a: scala.Long, b: scala.Long): scala.Long = stub() - - def incrementExact(a: scala.Int): scala.Int = stub() - - def incrementExact(a: scala.Long): scala.Long = stub() - - def decrementExact(a: scala.Int): scala.Int = stub() - - def decrementExact(a: scala.Long): scala.Long = stub() - - def negateExact(a: scala.Int): scala.Int = stub() - - def negateExact(a: scala.Long): scala.Long = stub() - - def toIntExact(a: scala.Long): scala.Int = stub() - - def floorDiv(a: scala.Int, b: scala.Int): scala.Int = stub() - - def floorDiv(a: scala.Long, b: scala.Long): scala.Long = stub() - - def floorMod(a: scala.Int, b: scala.Int): scala.Int = stub() - - def floorMod(a: scala.Long, b: scala.Long): scala.Long = stub() - - // A few other Math-related methods that are not really in Math - - def toUnsignedString(i: scala.Int): String = stub() - - def toUnsignedString(i: scala.Long): String = stub() - - def divideUnsigned(a: scala.Int, b: scala.Int): scala.Int = stub() - - def divideUnsigned(a: scala.Long, b: scala.Long): scala.Long = stub() - - def remainderUnsigned(a: scala.Int, b: scala.Int): scala.Int = stub() - - def remainderUnsigned(a: scala.Long, b: scala.Long): scala.Long = stub() - - private def stub(): Nothing = - throw new Error("stub") -} diff --git a/javalib/src/main/scala/java/math/Conversion.scala b/javalib/src/main/scala/java/math/Conversion.scala index a0cef18f02..83214dab13 100644 --- a/javalib/src/main/scala/java/math/Conversion.scala +++ b/javalib/src/main/scala/java/math/Conversion.scala @@ -159,7 +159,7 @@ private[math] object Conversion { if (sign == 0) { "0" } else if (numberLength == 1) { - val absStr = MathJDK8Bridge.toUnsignedString(digits(0)) + val absStr = Integer.toUnsignedString(digits(0)) if (sign < 0) "-" + absStr else absStr } else { @@ -175,7 +175,7 @@ private[math] object Conversion { var i: Int = tempLen - 1 while (i >= 0) { val temp1 = (rem.toLong << 32) + (temp(i) & 0xFFFFFFFFL) - val quot = MathJDK8Bridge.divideUnsigned(temp1, 1000000000L).toInt + val quot = java.lang.Long.divideUnsigned(temp1, 1000000000L).toInt temp(i) = quot rem = (temp1 - quot * 1000000000L).toInt i -= 1 diff --git a/javalib/src/main/scala/java/math/Division.scala b/javalib/src/main/scala/java/math/Division.scala index d1e6344d80..d61e972ade 100644 --- a/javalib/src/main/scala/java/math/Division.scala +++ b/javalib/src/main/scala/java/math/Division.scala @@ -110,7 +110,7 @@ private[math] object Division { ((normA(j) & UINT_MAX) << 32) + (normA(j - 1) & UINT_MAX) val firstDivisorDigitLong = firstDivisorDigit & UINT_MAX val quotient = - MathJDK8Bridge.divideUnsigned(product, firstDivisorDigitLong) + java.lang.Long.divideUnsigned(product, firstDivisorDigitLong) guessDigit = quotient.toInt var rem = (product - quotient * firstDivisorDigitLong).toInt @@ -190,8 +190,8 @@ private[math] object Division { val valSign = bi.sign if (valLen == 1) { val valDigit = valDigits(0) - var quo = MathJDK8Bridge.divideUnsigned(valDigit, divisor) & UINT_MAX - var rem = MathJDK8Bridge.remainderUnsigned(valDigit, divisor) & UINT_MAX + var quo = Integer.divideUnsigned(valDigit, divisor) & UINT_MAX + var rem = Integer.remainderUnsigned(valDigit, divisor) & UINT_MAX if (valSign != divisorSign) quo = -quo if (valSign < 0) @@ -229,7 +229,7 @@ private[math] object Division { var i = srcLength - 1 while (i >= 0) { val temp: Long = (rem.toLong << 32) | (src(i) & UINT_MAX) - val quot = MathJDK8Bridge.divideUnsigned(temp, bLong) + val quot = java.lang.Long.divideUnsigned(temp, bLong) rem = (temp - quot * bLong).toInt dest(i) = quot.toInt i -= 1 @@ -743,7 +743,7 @@ private[math] object Division { var i = srcLength - 1 while (i >= 0) { val temp = (result.toLong << 32) | (src(i).toLong & UINT_MAX) - result = MathJDK8Bridge.remainderUnsigned(temp, longDivisor).toInt + result = java.lang.Long.remainderUnsigned(temp, longDivisor).toInt i -= 1 } result diff --git a/project/Build.scala b/project/Build.scala index e8e77d7aeb..8c44e1047c 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1105,20 +1105,15 @@ object Build { val filter = ("*.sjsir": NameFilter) - val javalibProducts = (products in LocalProject("javalib")).value - val javalibMappings = - javalibProducts.flatMap(base => Path.selectSubpaths(base, filter)) - val javalibFilteredMappings = javalibMappings.filter( - _._2.replace('\\', '/') != "java/lang/MathJDK8Bridge$.sjsir") - val otherProducts = ( (products in LocalProject("javalanglib")).value ++ + (products in LocalProject("javalib")).value ++ (products in LocalProject("scalalib")).value ++ (products in LocalProject("libraryAux")).value) val otherMappings = otherProducts.flatMap(base => Path.selectSubpaths(base, filter)) - libraryMappings ++ otherMappings ++ javalibFilteredMappings + libraryMappings ++ otherMappings } )) ).withScalaJSCompiler From 406299e23c96f0f48083ac3861790a35d4b69773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 20 Dec 2017 18:14:32 +0100 Subject: [PATCH 0586/2665] Move `java.lang.AutoCloseable` to the `javalanglib/`. We used to have it in `javalib/` as a hack to be able to compile the javalib under JDK6. Since we only build on JDK8+ now, this hack is not necessary anymore. --- .../src/main/scala/java/lang/AutoCloseable.scala | 5 +++++ javalib/src/main/scala/java/lang/AutoCloseable.scala | 11 ----------- 2 files changed, 5 insertions(+), 11 deletions(-) create mode 100644 javalanglib/src/main/scala/java/lang/AutoCloseable.scala delete mode 100644 javalib/src/main/scala/java/lang/AutoCloseable.scala diff --git a/javalanglib/src/main/scala/java/lang/AutoCloseable.scala b/javalanglib/src/main/scala/java/lang/AutoCloseable.scala new file mode 100644 index 0000000000..21a3d0fb97 --- /dev/null +++ b/javalanglib/src/main/scala/java/lang/AutoCloseable.scala @@ -0,0 +1,5 @@ +package java.lang + +trait AutoCloseable { + def close(): Unit +} diff --git a/javalib/src/main/scala/java/lang/AutoCloseable.scala b/javalib/src/main/scala/java/lang/AutoCloseable.scala deleted file mode 100644 index 1a079c366e..0000000000 --- a/javalib/src/main/scala/java/lang/AutoCloseable.scala +++ /dev/null @@ -1,11 +0,0 @@ -package java.lang - -/* Even though this trait belongs to the java.lang package, we compile it as - * part of javalib instead of javalanglib, so that classes and interfaces in - * the javalib can inherit from AutoCloseable, even when we compile with JDK 6. - * It turns out that no class in java.lang needs to inherit from this trait, - * fortunately. - */ -trait AutoCloseable { - def close(): Unit -} From 273b2507f85e1afef55688fa039554b9f545e003 Mon Sep 17 00:00:00 2001 From: Carlos Quiroz Date: Sun, 17 Dec 2017 18:44:27 -0300 Subject: [PATCH 0587/2665] Support Charset.aliases() method --- .../main/scala/java/nio/charset/Charset.scala | 9 +++++++- .../testsuite/niocharset/CharsetTest.scala | 23 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/javalib/src/main/scala/java/nio/charset/Charset.scala b/javalib/src/main/scala/java/nio/charset/Charset.scala index de9cf210b7..71396e9eb9 100644 --- a/javalib/src/main/scala/java/nio/charset/Charset.scala +++ b/javalib/src/main/scala/java/nio/charset/Charset.scala @@ -1,13 +1,20 @@ package java.nio.charset import java.nio.{ByteBuffer, CharBuffer} +import java.util.{Collections, HashSet, Arrays} import scala.scalajs.js abstract class Charset protected (canonicalName: String, - aliases: Array[String]) extends AnyRef with Comparable[Charset] { + _aliases: Array[String]) extends AnyRef with Comparable[Charset] { + + private lazy val aliasesSet = + Collections.unmodifiableSet(new HashSet(Arrays.asList(_aliases))) + final def name(): String = canonicalName + final def aliases(): java.util.Set[String] = aliasesSet + override final def equals(that: Any): Boolean = that match { case that: Charset => this.name == that.name case _ => false diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/CharsetTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/CharsetTest.scala index 327bacba49..679bfa43da 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/CharsetTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/CharsetTest.scala @@ -7,6 +7,8 @@ \* */ package org.scalajs.testsuite.niocharset +import scala.collection.JavaConverters._ + import java.nio.charset._ import org.junit.Test @@ -16,6 +18,7 @@ import org.scalajs.testsuite.utils.AssertThrows._ import org.scalajs.testsuite.utils.Platform.executingInJVM class CharsetTest { + def javaSet[A](elems: A*): java.util.Set[A] = Set(elems: _*).asJava @Test def defaultCharset(): Unit = { assertSame("UTF-8", Charset.defaultCharset().name()) @@ -67,4 +70,24 @@ class CharsetTest { assertFalse(Charset.isSupported("this-charset-does-not-exist")) } + + @Test def aliases(): Unit = { + assertEquals(Charset.forName("UTF-8").aliases(), + javaSet("UTF8", "unicode-1-1-utf-8")) + assertEquals(Charset.forName("UTF-16").aliases(), + javaSet("UTF_16", "unicode", "utf16", "UnicodeBig")) + assertEquals(Charset.forName("UTF-16BE").aliases(), + javaSet("X-UTF-16BE", "UTF_16BE", "ISO-10646-UCS-2", + "UnicodeBigUnmarked")) + assertEquals(Charset.forName("UTF-16LE").aliases(), + javaSet("UnicodeLittleUnmarked", "UTF_16LE", "X-UTF-16LE")) + assertEquals(Charset.forName("US-ASCII").aliases(), + javaSet("ANSI_X3.4-1968", "cp367", "csASCII", "iso-ir-6", "ASCII", + "iso_646.irv:1983", "ANSI_X3.4-1986", "ascii7", "default", + "ISO_646.irv:1991", "ISO646-US", "IBM367", "646", "us")) + assertEquals(Charset.forName("ISO-8859-1").aliases(), + javaSet("819", "ISO8859-1", "l1", "ISO_8859-1:1987", "ISO_8859-1", "8859_1", + "iso-ir-100", "latin1", "cp819", "ISO8859_1", "IBM819", "ISO_8859_1", + "IBM-819", "csISOLatin1")) + } } From a4bb751c86af98df3a6d616a708ed34641ad4e8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 20 Dec 2017 21:30:38 +0100 Subject: [PATCH 0588/2665] Use `Integer.{divide,remainder}Unsigned` in `RuntimeLong`. Previously, we could not use those two methods because they were not available in older versions of the JDK. Now that we only build on JDK8+, we can use them. --- .../src/main/scala/scala/scalajs/runtime/RuntimeLong.scala | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala b/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala index 4033727da8..f96dc0d01a 100644 --- a/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala +++ b/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala @@ -724,8 +724,7 @@ object RuntimeLong { if (isUInt32(ahi)) { if (isUInt32(bhi)) { hiReturn = 0 - // Integer.divideUnsigned(alo, blo), inaccessible when compiling on JDK < 8 - rawToInt(alo.toUint / blo.toUint) + Integer.divideUnsigned(alo, blo) } else { // a < b hiReturn = 0 @@ -819,8 +818,7 @@ object RuntimeLong { if (isUInt32(ahi)) { if (isUInt32(bhi)) { hiReturn = 0 - // Integer.remainderUnsigned(alo, blo), inaccessible when compiling on JDK < 8 - rawToInt(alo.toUint % blo.toUint) + Integer.remainderUnsigned(alo, blo) } else { // a < b hiReturn = ahi From f6fb820c9178121f6e362dc4e9ee43858ef9a346 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 20 Dec 2017 21:34:52 +0100 Subject: [PATCH 0589/2665] Revert "Fix #3154: Avoid calling `AssertionError(String, Throwable)`." This reverts commit 9428b684197cea946467f9caeaefab616546d356. That commit was avoiding a constructor not available on JDK6. Now that we only build on JDK8+, we can use the `(String, Throwable)` constructor, which is cleaner. --- .../org/junit/internal/ArrayComparisonFailure.scala | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/junit-runtime/src/main/scala/org/junit/internal/ArrayComparisonFailure.scala b/junit-runtime/src/main/scala/org/junit/internal/ArrayComparisonFailure.scala index 0b72a3ca83..58b6d4c0ac 100644 --- a/junit-runtime/src/main/scala/org/junit/internal/ArrayComparisonFailure.scala +++ b/junit-runtime/src/main/scala/org/junit/internal/ArrayComparisonFailure.scala @@ -5,14 +5,8 @@ package org.junit.internal object ArrayComparisonFailure -/* Attention: AssertionError does not have a (String, Throwable) constructor - * in JDK 6. If we try to call that one, compilation *succeeds* because of - * auto-boxing, but it does not do the right thing. See #3154. - */ class ArrayComparisonFailure(message: String, cause: AssertionError, index: Int) - extends AssertionError(message) { - - initCause(cause) + extends AssertionError(message, cause) { private var fIndices: List[Int] = index :: Nil @@ -29,7 +23,7 @@ class ArrayComparisonFailure(message: String, cause: AssertionError, index: Int) val indices = if (fIndices == null) s"[$index]" // see #3148 else fIndices.map(index => s"[$index]").mkString - val causeMessage = cause.getMessage // do not use getCause(), see #3148 + val causeMessage = getCause.getMessage s"${msg}arrays first differed at element $indices; $causeMessage" } From 3ccfd0282ca9acbed1e3ca1bc33e4d572f4394cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 13 Dec 2017 15:30:10 +0100 Subject: [PATCH 0590/2665] Fix #3219: Correctly recognize exports for `$xyz` in the back-end. We were erroneously using `sym.unexpandedName` when testing whether a method is an export bridge. However, if the export name happens to start with a `$`, then `unexpandedName` considers the whole thing as an expanded name, and removes the whole prefix as if it were the result of an expansion. Simply using the `name` for the test fixes the issue. Note that `jsExportInfo` was already using `name`, and not `unexpandedName`. --- .../core/compiler/JSGlobalAddons.scala | 5 +- .../testsuite/jsinterop/ExportsTest.scala | 48 +++++++++++++++++++ 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala index c9369f90e7..4f461d5026 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala @@ -109,8 +109,7 @@ trait JSGlobalAddons extends JSDefinitions /** checks if the given symbol is a JSExport */ def isExport(sym: Symbol): Boolean = - sym.unexpandedName.startsWith(exportPrefix) && - !sym.hasFlag(Flags.DEFAULTPARAM) + sym.name.startsWith(exportPrefix) && !sym.hasFlag(Flags.DEFAULTPARAM) /** retrieves the originally assigned jsName of this export and whether it * is a property @@ -119,7 +118,7 @@ trait JSGlobalAddons extends JSDefinitions def dropPrefix(prefix: String) ={ if (name.startsWith(prefix)) { // We can't decode right away due to $ separators - val enc = name.encoded.substring(prefix.length) + val enc = name.toString.substring(prefix.length) Some(NameTransformer.decode(enc)) } else None } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index 2946effb70..404ce45b92 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -73,6 +73,30 @@ class ExportsTest { assertEquals(42, foo.myMethod()) } + @Test def exports_for_methods_whose_encodedName_starts_with_dollar_issue_3219(): Unit = { + class ExportsForMethodsWhoseEncodedNameStartsWithDollar { + @JSExport("$a") + def f(x: Int): Int = x + 1 + + @JSExport + def +(x: Int): Int = x + 2 + + @JSExport("-") + def plus(x: Int): Int = x + 3 + + @JSExport("plus") + def ++(x: Int): Int = x + 4 + } + + val fns = new ExportsForMethodsWhoseEncodedNameStartsWithDollar() + .asInstanceOf[js.Dynamic] + + assertEquals(6, fns.applyDynamic("$a")(5)) + assertEquals(7, fns.applyDynamic("+")(5)) + assertEquals(8, fns.applyDynamic("-")(5)) + assertEquals(9, fns.applyDynamic("plus")(5)) + } + @Test def exports_for_protected_methods(): Unit = { class Foo { @JSExport @@ -146,6 +170,30 @@ class ExportsTest { assertEquals("world set get", foo.y) } + @Test def exports_for_properties_whose_encodedName_starts_with_dollar_issue_3219(): Unit = { + class ExportsForPropertiesWhoseEncodedNameStartsWithDollar { + @JSExport("$a") + def f: Int = 6 + + @JSExport + def + : Int = 7 // scalastyle:ignore + + @JSExport("-") + def plus: Int = 8 + + @JSExport("plus") + def ++ : Int = 9 // scalastyle:ignore + } + + val fns = new ExportsForPropertiesWhoseEncodedNameStartsWithDollar() + .asInstanceOf[js.Dynamic] + + assertEquals(6, fns.selectDynamic("$a")) + assertEquals(7, fns.selectDynamic("+")) + assertEquals(8, fns.selectDynamic("-")) + assertEquals(9, fns.selectDynamic("plus")) + } + @Test def exports_for_protected_properties(): Unit = { class Foo { @JSExport From 58f56adc03fcc72533e22d5331253e50e44e140f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 12 Dec 2017 11:45:44 +0100 Subject: [PATCH 0591/2665] Move MiMa checks for `irJS` and `toolJS` to the bootstrap task. This is a cosmetic change in the CI matrix to simplify dropping 2.10 support at the language/library level without dropping it at the (JVM) tools level. --- ci/matrix.xml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/ci/matrix.xml b/ci/matrix.xml index 79d1928982..1d362ff22e 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -166,7 +166,8 @@ sbt ++$scala toolsJS/bootstrapTest && sbt ++$scala testSuite/test:fullOptJS && sbt 'set scalaJSStage in Global := FullOptStage' \ - ++$scala toolsJS/bootstrapTest + ++$scala toolsJS/bootstrapTest && + sbt ++$scala irJS/mimaReportBinaryIssues toolsJS/mimaReportBinaryIssues ]]> Date: Tue, 12 Dec 2017 13:07:42 +0100 Subject: [PATCH 0592/2665] Add HTML runners for the helloworld and reversi with 2.12. --- .../helloworld/helloworld-2.12-fastopt.html | 17 +++++++++++ examples/helloworld/helloworld-2.12.html | 17 +++++++++++ examples/reversi/reversi-2.12-fastopt.html | 30 +++++++++++++++++++ examples/reversi/reversi-2.12.html | 30 +++++++++++++++++++ 4 files changed, 94 insertions(+) create mode 100644 examples/helloworld/helloworld-2.12-fastopt.html create mode 100644 examples/helloworld/helloworld-2.12.html create mode 100644 examples/reversi/reversi-2.12-fastopt.html create mode 100644 examples/reversi/reversi-2.12.html diff --git a/examples/helloworld/helloworld-2.12-fastopt.html b/examples/helloworld/helloworld-2.12-fastopt.html new file mode 100644 index 0000000000..6a71ad21e8 --- /dev/null +++ b/examples/helloworld/helloworld-2.12-fastopt.html @@ -0,0 +1,17 @@ + + + + Hello world - Scala.js example + + + + +

+
+ + + + + + + diff --git a/examples/helloworld/helloworld-2.12.html b/examples/helloworld/helloworld-2.12.html new file mode 100644 index 0000000000..80e6bfbe9a --- /dev/null +++ b/examples/helloworld/helloworld-2.12.html @@ -0,0 +1,17 @@ + + + + Hello world - Scala.js example + + + + +
+
+ + + + + + + diff --git a/examples/reversi/reversi-2.12-fastopt.html b/examples/reversi/reversi-2.12-fastopt.html new file mode 100644 index 0000000000..9690764404 --- /dev/null +++ b/examples/reversi/reversi-2.12-fastopt.html @@ -0,0 +1,30 @@ + + + + Reversi - Scala.js example + + + + +

Reversi - Scala.js example

+ +

Somewhat inspired by +http://davidbau.com/reversi/

+ +
+
+ + + + + + + + + diff --git a/examples/reversi/reversi-2.12.html b/examples/reversi/reversi-2.12.html new file mode 100644 index 0000000000..df61e4c6e1 --- /dev/null +++ b/examples/reversi/reversi-2.12.html @@ -0,0 +1,30 @@ + + + + Reversi - Scala.js example + + + + +

Reversi - Scala.js example

+ +

Somewhat inspired by +http://davidbau.com/reversi/

+ +
+
+ + + + + + + + + From 512486a5006adaf9e26443f5cb4561c58458b052 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 12 Dec 2017 13:11:42 +0100 Subject: [PATCH 0593/2665] Remove references to the CLI in `publish.sh`. Those were forgotten in 8a9336e75a8967baae39d54d10e0a9b74b1be078. --- scripts/publish.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/scripts/publish.sh b/scripts/publish.sh index 1499a3b1cf..e28ab6788e 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -9,7 +9,6 @@ fi FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.10.7 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.11.12 2.12.1 2.12.2 2.12.3 2.12.4 2.13.0-M2" BIN_VERSIONS="2.10.7 2.11.12 2.12.4 2.13.0-M2" -CLI_VERSIONS="2.10.7 2.11.12 2.12.4" SBT_VERSION="2.10.7" SBT1_VERSION="2.12.4" SBT1_SBTVERSION="1.0.0" @@ -35,11 +34,6 @@ for v in $BIN_VERSIONS; do $CMD $ARGS done -# Publish the CLI -for v in $CLI_VERSIONS; do - $CMD "++$v" "cli/publishSigned" -done - # Publish sbt-plugin $CMD "++$SBT_VERSION" "sbtPlugin/publishSigned" $CMD "++$SBT1_VERSION" "^^$SBT1_SBTVERSION" "sbtPlugin/publishSigned" From e407e10e526a01007af020c392e45ed71db9e9c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 12 Dec 2017 13:28:54 +0100 Subject: [PATCH 0594/2665] Rename Compat210Component into CompatComponent. Nowadays, it contains as much compatibility tricks for 2.11/2.12 as for 2.10. --- ...0Component.scala => CompatComponent.scala} | 24 ++++++++++--------- .../core/compiler/ExplicitInnerJS.scala | 2 +- .../core/compiler/ExplicitLocalJS.scala | 2 +- .../org/scalajs/core/compiler/GenJSCode.scala | 2 +- .../core/compiler/JSGlobalAddons.scala | 2 +- .../core/compiler/PreTyperComponent.scala | 2 +- .../scalajs/core/compiler/PrepJSInterop.scala | 2 +- .../scalajs/core/compiler/ScalaJSPlugin.scala | 2 +- 8 files changed, 20 insertions(+), 18 deletions(-) rename compiler/src/main/scala/org/scalajs/core/compiler/{Compat210Component.scala => CompatComponent.scala} (92%) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala b/compiler/src/main/scala/org/scalajs/core/compiler/CompatComponent.scala similarity index 92% rename from compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala rename to compiler/src/main/scala/org/scalajs/core/compiler/CompatComponent.scala index feb03c748e..db607b1a3e 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/CompatComponent.scala @@ -10,13 +10,15 @@ import scala.collection.mutable import scala.reflect.internal.Flags.{LOCAL, PRIVATE} import scala.tools.nsc._ -/** Hacks to have our source code compatible with 2.10 and 2.11. - * It exposes 2.11 API in a 2.10 compiler. +/** Hacks to have our source code compatible with the compiler internals of all + * the versions of Scala that we support. + * + * In general, it tries to provide the newer APIs on top of older APIs. * * @author Sébastien Doeraene */ -trait Compat210Component { - import Compat210Component.{infiniteLoop, noImplClasses} +trait CompatComponent { + import CompatComponent.{infiniteLoop, noImplClasses} val global: Global @@ -52,7 +54,7 @@ trait Compat210Component { } implicit final class GlobalCompat( - self: Compat210Component.this.global.type) { + self: CompatComponent.this.global.type) { def enteringPhase[T](ph: Phase)(op: => T): T = self.beforePhase(ph)(op) def beforePhase[T](ph: Phase)(op: => T): T = infiniteLoop() @@ -224,7 +226,7 @@ trait Compat210Component { global.definitions.isFunctionSymbol(sym) private implicit final class DefinitionsCompat( - self: Compat210Component.this.global.definitions.type) { + self: CompatComponent.this.global.definitions.type) { def repeatedToSingle(t: Type): Type = t match { case TypeRef(_, self.RepeatedParamClass, arg :: Nil) => arg @@ -240,20 +242,20 @@ trait Compat210Component { // that were previously in definitions itself implicit final class RunCompat(self: Run) { - val runDefinitions: Compat210Component.this.global.definitions.type = + val runDefinitions: CompatComponent.this.global.definitions.type = global.definitions } // Mode.FUNmode replaces analyzer.FUNmode object Mode { - import Compat210Component.AnalyzerCompat + import CompatComponent.AnalyzerCompat // No type ascription! Type is different in 2.10 / 2.11 val FUNmode = analyzer.FUNmode } } -object Compat210Component { +object CompatComponent { private object LowPriorityMode { object Mode { def FUNmode: Nothing = infiniteLoop() @@ -262,7 +264,7 @@ object Compat210Component { private implicit final class AnalyzerCompat(self: scala.tools.nsc.typechecker.Analyzer) { def FUNmode = { // scalastyle:ignore - import Compat210Component.LowPriorityMode._ + import CompatComponent.LowPriorityMode._ { import scala.reflect.internal._ Mode.FUNmode @@ -277,7 +279,7 @@ object Compat210Component { throw new AssertionError("No impl classes in this version") } -trait PluginComponent210Compat extends Compat210Component { +trait PluginComponentCompat extends CompatComponent { // Starting 2.11.x, we need to override the default description. def description: String } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitInnerJS.scala b/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitInnerJS.scala index 75d1181233..f6785de3f1 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitInnerJS.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitInnerJS.scala @@ -48,7 +48,7 @@ import scala.collection.mutable */ abstract class ExplicitInnerJS extends plugins.PluginComponent with InfoTransform with TypingTransformers - with PluginComponent210Compat { + with PluginComponentCompat { val jsAddons: JSGlobalAddons { val global: ExplicitInnerJS.this.global.type diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitLocalJS.scala b/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitLocalJS.scala index b518bf86c4..47c8c9af8d 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitLocalJS.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitLocalJS.scala @@ -111,7 +111,7 @@ import scala.collection.mutable */ abstract class ExplicitLocalJS extends plugins.PluginComponent with Transform with TypingTransformers - with PluginComponent210Compat { + with PluginComponentCompat { val jsAddons: JSGlobalAddons { val global: ExplicitLocalJS.this.global.type diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 667c1d93d0..b5c69898fa 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -33,7 +33,7 @@ abstract class GenJSCode extends plugins.PluginComponent with JSEncoding with GenJSExports with GenJSFiles - with PluginComponent210Compat { + with PluginComponentCompat { val jsAddons: JSGlobalAddons { val global: GenJSCode.this.global.type diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala index f1e24ae5db..3c4542ef2d 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala @@ -16,7 +16,7 @@ import org.scalajs.core.ir.Trees.JSNativeLoadSpec * @author Sébastien Doeraene */ trait JSGlobalAddons extends JSDefinitions - with Compat210Component { + with CompatComponent { val global: Global import global._ diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PreTyperComponent.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PreTyperComponent.scala index 7d1b158952..0266ce8e68 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PreTyperComponent.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PreTyperComponent.scala @@ -61,7 +61,7 @@ import nsc._ * @author Nicolas Stucki */ abstract class PreTyperComponent extends plugins.PluginComponent - with transform.Transform with PluginComponent210Compat { + with transform.Transform with PluginComponentCompat { import global._ diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index c07fd09f47..367b4a047a 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -28,7 +28,7 @@ import org.scalajs.core.ir.Trees.{isValidIdentifier, JSNativeLoadSpec} abstract class PrepJSInterop extends plugins.PluginComponent with PrepJSExports with transform.Transform - with PluginComponent210Compat { + with PluginComponentCompat { import PrepJSInterop._ val jsAddons: JSGlobalAddons { diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala index b03a32f1dd..824cfe06a3 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala @@ -39,7 +39,7 @@ class ScalaJSPlugin(val global: Global) extends NscPlugin { /** Addons for JavaScript platform */ object jsAddons extends { val global: ScalaJSPlugin.this.global.type = ScalaJSPlugin.this.global - } with JSGlobalAddons with Compat210Component + } with JSGlobalAddons with CompatComponent object scalaJSOpts extends ScalaJSOptions { import ScalaJSOptions.URIMap From 3edbc71212f4491caf4e521fd0b59f5f6ba7fbfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 12 Dec 2017 16:47:12 +0100 Subject: [PATCH 0595/2665] Drop support for Scala 2.10.x. In this commit, we completely drop support for Scala 2.10.x in Scala.js code. Note that our JVM artifacts are still cross-compiled with 2.10.x, because we still support sbt 0.13.16+ which runs on 2.10. However, it will not be possible to use `enablePlugins(ScalaJSPlugin)` with `scalaVersion := "2.10.x"` anymore. This includes: * Drop CI tasks using 2.10.x with JS artifacts (but not with JVM artifacts). * Remove all workarounds for Scala 2.10 compiler bugs, such as crashes for some usages of `js.Dynamic`. * Remove all 2.10-specific stuff from `CompatComponent` in the compiler. * Remove all 2.10-specific assumptions or branches in the test suite. This commit does not include: * Drop `js.Dynamic.x` and the associated compiler tricks, which work around the 2.10 *library* (not compiler), and deserve a separate commit anyway. * Take advantage of new 2.11 language features, such as making the underlying val of value classes private. Those items are left for further commits. --- TESTING | 8 +- ci/checksizes.sh | 11 +- ci/matrix.xml | 43 +- .../core/compiler/CompatComponent.scala | 180 +---- .../core/compiler/ExplicitInnerJS.scala | 8 +- .../core/compiler/ExplicitLocalJS.scala | 2 +- .../org/scalajs/core/compiler/GenJSCode.scala | 33 +- .../scalajs/core/compiler/JSDefinitions.scala | 2 +- .../scalajs/core/compiler/JSEncoding.scala | 3 +- .../core/compiler/PreTyperComponent.scala | 2 +- .../scalajs/core/compiler/PrepJSInterop.scala | 27 +- .../test/EnumerationInteropTest.scala | 28 +- .../compiler/test/JSDynamicLiteralTest.scala | 24 +- .../core/compiler/test/JSExportTest.scala | 2 +- .../core/compiler/test/JSSAMTest.scala | 2 +- .../helloworld/helloworld-2.10-fastopt.html | 17 - examples/helloworld/helloworld-2.10.html | 17 - examples/reversi/reversi-2.10-fastopt.html | 30 - examples/reversi/reversi-2.10.html | 30 - .../scala/java/lang/EnvironmentInfo.scala | 9 +- .../main/scala/java/lang/ObjectClone.scala | 18 +- .../src/main/scala/java/lang/StackTrace.scala | 37 +- .../src/main/scala/java/lang/System.scala | 12 +- javalib/src/main/scala/java/net/URI.scala | 2 +- .../src/main/scala/java/util/TreeSet.scala | 3 - .../junit/plugin/Compat210Component.scala | 71 -- .../junit/plugin/ScalaJSJUnitPlugin.scala | 2 +- .../main/scala/scala/runtime/Statics.scala | 2 +- .../scala/scalajs/js/DynamicImplicits.scala | 4 - .../scala/scala/scalajs/js/JSConverters.scala | 8 - project/Build.scala | 44 +- scalalib/overrides-2.10/scala/Array.scala | 550 ------------- scalalib/overrides-2.10/scala/Console.scala | 468 ----------- .../scala/collection/JavaConversions.scala | 132 --- .../collection/immutable/NumericRange.scala | 290 ------- .../scala/collection/immutable/Range.scala | 421 ---------- .../collection/immutable/RedBlackTree.scala | 496 ------------ .../collection/mutable/ArrayBuilder.scala | 765 ------------------ .../scala/collection/mutable/Buffer.scala | 50 -- .../scala/compat/Platform.scala | 133 --- .../concurrent/impl/AbstractPromise.scala | 29 - scalalib/overrides-2.10/scala/package.scala | 138 ---- .../scala/reflect/ClassTag.scala | 153 ---- .../scala/reflect/Manifest.scala | 294 ------- .../scala/reflect/NameTransformer.scala | 158 ---- .../scala/runtime/ScalaRunTime.scala | 356 -------- scripts/publish.sh | 17 +- .../org/scalajs/testsuite/Compat210.scala | 30 - .../org/scalajs/testsuite/Typechecking.scala | 5 - .../testsuite/TypecheckingMacros.scala | 8 +- ...nstanceTestsHijackedBoxedClassesTest.scala | 4 +- .../testsuite/compiler/OptimizerTest.scala | 33 - .../testsuite/jsinterop/ArrayTest.scala | 3 +- .../testsuite/jsinterop/JSOptionalTest.scala | 2 +- .../testsuite/jsinterop/JSSymbolTest.scala | 5 +- .../testsuite/jsinterop/SpecialTest.scala | 6 +- .../testsuite/jsinterop/UndefOrTest.scala | 8 +- .../jsinterop/UndefOrTestRequire211.scala | 31 - .../org/scalajs/testsuite/utils/JSUtils.scala | 6 +- .../compiler/DefaultMethodsTest.scala | 2 +- .../scalajs/testsuite/compiler/IntTest.scala | 6 +- .../scalajs/testsuite/compiler/LongTest.scala | 5 +- .../testsuite/compiler/MatchTest.scala | 2 +- .../testsuite/compiler/RegressionTest.scala | 10 +- .../testsuite/scalalib/ClassTagTest.scala | 3 +- .../testsuite/scalalib/RangesTest.scala | 10 +- .../frontend/optimizer/GenIncOptimizer.scala | 4 +- 67 files changed, 149 insertions(+), 5165 deletions(-) delete mode 100644 examples/helloworld/helloworld-2.10-fastopt.html delete mode 100644 examples/helloworld/helloworld-2.10.html delete mode 100644 examples/reversi/reversi-2.10-fastopt.html delete mode 100644 examples/reversi/reversi-2.10.html delete mode 100644 junit-plugin/src/main/scala/org/scalajs/junit/plugin/Compat210Component.scala delete mode 100644 scalalib/overrides-2.10/scala/Array.scala delete mode 100644 scalalib/overrides-2.10/scala/Console.scala delete mode 100644 scalalib/overrides-2.10/scala/collection/JavaConversions.scala delete mode 100644 scalalib/overrides-2.10/scala/collection/immutable/NumericRange.scala delete mode 100644 scalalib/overrides-2.10/scala/collection/immutable/Range.scala delete mode 100644 scalalib/overrides-2.10/scala/collection/immutable/RedBlackTree.scala delete mode 100644 scalalib/overrides-2.10/scala/collection/mutable/ArrayBuilder.scala delete mode 100644 scalalib/overrides-2.10/scala/collection/mutable/Buffer.scala delete mode 100644 scalalib/overrides-2.10/scala/compat/Platform.scala delete mode 100644 scalalib/overrides-2.10/scala/concurrent/impl/AbstractPromise.scala delete mode 100644 scalalib/overrides-2.10/scala/package.scala delete mode 100644 scalalib/overrides-2.10/scala/reflect/ClassTag.scala delete mode 100644 scalalib/overrides-2.10/scala/reflect/Manifest.scala delete mode 100644 scalalib/overrides-2.10/scala/reflect/NameTransformer.scala delete mode 100644 scalalib/overrides-2.10/scala/runtime/ScalaRunTime.scala delete mode 100644 test-suite/js/src/main/scala/org/scalajs/testsuite/Compat210.scala delete mode 100644 test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTestRequire211.scala diff --git a/TESTING b/TESTING index 5ecab96991..14d5d892dd 100644 --- a/TESTING +++ b/TESTING @@ -4,11 +4,11 @@ This file contains test cases that should be manually executed. The following HTML-runners must be manually tested: - examples/helloworld/helloworld-{2.10|2.11}{|-fastopt}.html - examples/reversi/reversi-{2.10|2.11}{|-fastopt}.html + examples/helloworld/helloworld-{2.11|2.12}{|-fastopt}.html + examples/reversi/reversi-{2.11|2.12}{|-fastopt}.html The following sbt-plugin generated test runners must be manually tested (with -Scala 2.10, 2.11 and 2.12, and in `FastOptStage` and `FullOptStage`): +Scala 2.11 and 2.12, and in `FastOptStage` and `FullOptStage`): testingExample/testHtml testSuite/testHtml @@ -17,7 +17,7 @@ Scala 2.10, 2.11 and 2.12, and in `FastOptStage` and `FullOptStage`): To test source maps, do the following on: - examples/reversi/reversi-{2.10|2.11}{|-fastopt}.html + examples/reversi/reversi-{2.11|2.12}{|-fastopt}.html 1. Open the respective file in Google Chrome 2. Set a break-point in the HTML launcher on the `new Reversi` statement diff --git a/ci/checksizes.sh b/ci/checksizes.sh index 9551935f68..7b2e3ef62c 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -5,9 +5,6 @@ BASEDIR="`dirname $0`/.." FULLVER="$1" case $FULLVER in - 2.10.2) - VER=2.10 - ;; 2.11.12) VER=2.11 ;; @@ -17,7 +14,7 @@ case $FULLVER in 2.13.0-M2) VER=2.13.0-M2 ;; - 2.10.3|2.10.4|2.10.5|2.10.6|2.10.7|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7|2.11.8|2.11.11|2.12.1|2.12.2|2.12.3) + 2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7|2.11.8|2.11.11|2.12.1|2.12.2|2.12.3) echo "Ignoring checksizes for Scala $FULLVER" exit 0 ;; @@ -36,12 +33,6 @@ REVERSI_PREOPT_GZ_SIZE=$(stat '-c%s' "$REVERSI_PREOPT.gz") REVERSI_OPT_GZ_SIZE=$(stat '-c%s' "$REVERSI_OPT.gz") case $FULLVER in - 2.10.2) - REVERSI_PREOPT_EXPECTEDSIZE=512000 - REVERSI_OPT_EXPECTEDSIZE=115000 - REVERSI_PREOPT_GZ_EXPECTEDSIZE=69000 - REVERSI_OPT_GZ_EXPECTEDSIZE=30000 - ;; 2.11.12) REVERSI_PREOPT_EXPECTEDSIZE=507000 REVERSI_OPT_EXPECTEDSIZE=116000 diff --git a/ci/matrix.xml b/ci/matrix.xml index 1d362ff22e..251b2b646a 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -159,6 +159,7 @@ - - 2.10.2 - 1.8 - 2.11.12 1.8 @@ -286,11 +283,6 @@ - - 2.10.2 - 1.8 - testSuite - 2.11.12 1.8 @@ -332,11 +324,6 @@ - - 2.10.2 - 1.8 - testSuite - 2.11.12 1.8 @@ -371,10 +358,6 @@ - - 2.10.2 - 1.8 - 2.11.12 1.8 @@ -439,26 +422,6 @@ - - 2.10.3 - 1.8 - - - 2.10.4 - 1.8 - - - 2.10.5 - 1.8 - - - 2.10.6 - 1.8 - - - 2.10.7 - 1.8 - 2.11.0 1.8 diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/CompatComponent.scala b/compiler/src/main/scala/org/scalajs/core/compiler/CompatComponent.scala index db607b1a3e..02aa2bc269 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/CompatComponent.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/CompatComponent.scala @@ -24,70 +24,23 @@ trait CompatComponent { import global._ - // unexpandedName replaces originalName - implicit final class SymbolCompat(self: Symbol) { - def unexpandedName: Name = self.originalName - def originalName: Name = infiniteLoop() - def originalOwner: Symbol = global.originalOwner.getOrElse(self, self.rawowner) - def isPrivateThis: Boolean = self.hasAllFlags(PRIVATE | LOCAL) - def isLocalToBlock: Boolean = self.isLocal - def implClass: Symbol = NoSymbol def isTraitOrInterface: Boolean = self.isTrait || self.isInterface - - def tpe_* : Type = self.tpe // scalastyle:ignore - } - - // enteringPhase/exitingPhase replace beforePhase/afterPhase - - @inline final def enteringPhase[T](ph: Phase)(op: => T): T = { - global.enteringPhase(ph)(op) - } - - @inline final def exitingPhase[T](ph: Phase)(op: => T): T = { - global.exitingPhase(ph)(op) } implicit final class GlobalCompat( self: CompatComponent.this.global.type) { - def enteringPhase[T](ph: Phase)(op: => T): T = self.beforePhase(ph)(op) - def beforePhase[T](ph: Phase)(op: => T): T = infiniteLoop() - - def exitingPhase[T](ph: Phase)(op: => T): T = self.afterPhase(ph)(op) - def afterPhase[T](ph: Phase)(op: => T): T = infiniteLoop() - - def delambdafy: DelambdafyCompat.type = DelambdafyCompat - - // Copied from internal/Trees.scala - def NewFromConstructor(constructor: Symbol, args: Tree*): Apply = { - assert(constructor.isConstructor, constructor) - val instance = New(TypeTree(constructor.owner.tpe)) - val init = Select(instance, nme.CONSTRUCTOR).setSymbol(constructor) - Apply(init, args.toList) - } - object originalOwner { def getOrElse(sym: Symbol, orElse: => Symbol): Symbol = infiniteLoop() } } - object DelambdafyCompat { - object FreeVarTraverser { - def freeVarsOf(function: Function): mutable.LinkedHashSet[Symbol] = { - throw new AssertionError( - "FreeVarTraverser should not be called on 2.10") - } - } - } - - // Impl classes disappeared in 2.12.0-M4 - lazy val scalaUsesImplClasses: Boolean = definitions.SeqClass.implClass != NoSymbol // a trait we know has an impl class @@ -106,10 +59,7 @@ trait CompatComponent { // SAMFunction was introduced in 2.12.0-M4 for LMF-capable SAM types object SAMFunctionAttachCompatDef { - /* Should extend PlainAttachment, but it does not exist in 2.10, and we - * do not actually need this relationship. - */ - case class SAMFunction(samTp: Type, sam: Symbol) + case class SAMFunction(samTp: Type, sam: Symbol) extends PlainAttachment } object SAMFunctionAttachCompat { @@ -129,13 +79,12 @@ trait CompatComponent { /* global.genBCode.bTypes.initializeCoreBTypes() * * This one has a very particular history: - * - in 2.10.x, no genBCode in global - * - in 2.11.{0-1}, there is genBCode but it has no bTypes member + * - in 2.11.{0-1}, genBCode does not have a bTypes member * - In 2.11.{2-5}, there is genBCode.bTypes, but it has no * initializeCoreBTypes (it was actually typo'ed as intializeCoreBTypes!) * - In 2.11.6+, including 2.12, we finally have * genBCode.bTypes.initializeCoreBTypes - * - As of 2.12.0-M4, it is mandatory to call that method from GenJSCode.run() + * - Since 2.12.0-M4, it is mandatory to call that method from GenJSCode.run() */ object LowPrioGenBCodeCompat { @@ -147,139 +96,26 @@ trait CompatComponent { } def initializeCoreBTypesCompat(): Unit = { - import LowPrioGenBCodeCompat._ + import LowPrioGenBCodeCompat.genBCode._ { - import global._ + import genBCode._ - import LowPrioGenBCodeCompat.genBCode._ + import LowPrioGenBCodeCompat.genBCode.bTypes._ { - import genBCode._ + import bTypes._ - import LowPrioGenBCodeCompat.genBCode.bTypes._ - - { - import bTypes._ - - initializeCoreBTypes() - } + initializeCoreBTypes() } } } - - // Compat to support: new overridingPairs.Cursor(sym).iterator - - implicit class OverridingPairsCursor2Iterable(cursor: overridingPairs.Cursor) { - def iterator: Iterator[SymbolPair] = new Iterator[SymbolPair] { - skipIgnoredEntries() - - def hasNext: Boolean = cursor.hasNext - - def next(): SymbolPair = { - val symbolPair = new SymbolPair(cursor.overriding, cursor.overridden) - cursor.next() - skipIgnoredEntries() - symbolPair - } - - private def skipIgnoredEntries(): Unit = { - while (cursor.hasNext && ignoreNextEntry) - cursor.next() - } - - /** In 2.10 the overridingPairs.Cursor returns some false positives - * on overriding members. The known false positives are always trying to - * override the `isInstanceOf` method. - */ - private def ignoreNextEntry: Boolean = - cursor.overriding.name == nme.isInstanceOf_ - } - - class SymbolPair(val low: Symbol, val high: Symbol) - - /** To make this compat code compile in 2.11 as the fields `overriding` and - * `overridden` are only present in 2.10. - */ - private implicit class Cursor210toCursor211(cursor: overridingPairs.Cursor) { - def overriding: Symbol = infiniteLoop() - def overridden: Symbol = infiniteLoop() - } - } - - // ErasedValueType has a different encoding - - implicit final class ErasedValueTypeCompat(self: global.ErasedValueType) { - def valueClazz: Symbol = self.original.typeSymbol - def erasedUnderlying: Type = - enteringPhase(currentRun.erasurePhase)( - erasure.erasedValueClassArg(self.original)) - def original: TypeRef = infiniteLoop() - } - - // Definitions - - @inline final def repeatedToSingle(t: Type): Type = - global.definitions.repeatedToSingle(t) - - final def isFunctionSymbol(sym: Symbol): Boolean = - global.definitions.isFunctionSymbol(sym) - - private implicit final class DefinitionsCompat( - self: CompatComponent.this.global.definitions.type) { - - def repeatedToSingle(t: Type): Type = t match { - case TypeRef(_, self.RepeatedParamClass, arg :: Nil) => arg - case _ => t - } - - def isFunctionSymbol(sym: Symbol): Boolean = - definitions.FunctionClass.seq.contains(definitions.unspecializedSymbol(sym)) - - } - - // run.runDefinitions bundles methods and state related to the run - // that were previously in definitions itself - - implicit final class RunCompat(self: Run) { - val runDefinitions: CompatComponent.this.global.definitions.type = - global.definitions - } - - // Mode.FUNmode replaces analyzer.FUNmode - - object Mode { - import CompatComponent.AnalyzerCompat - // No type ascription! Type is different in 2.10 / 2.11 - val FUNmode = analyzer.FUNmode - } } object CompatComponent { - private object LowPriorityMode { - object Mode { - def FUNmode: Nothing = infiniteLoop() - } - } - - private implicit final class AnalyzerCompat(self: scala.tools.nsc.typechecker.Analyzer) { - def FUNmode = { // scalastyle:ignore - import CompatComponent.LowPriorityMode._ - { - import scala.reflect.internal._ - Mode.FUNmode - } - } - } - private def infiniteLoop(): Nothing = throw new AssertionError("Infinite loop in Compat") private def noImplClasses(): Nothing = throw new AssertionError("No impl classes in this version") } - -trait PluginComponentCompat extends CompatComponent { - // Starting 2.11.x, we need to override the default description. - def description: String -} diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitInnerJS.scala b/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitInnerJS.scala index f6785de3f1..513ded3110 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitInnerJS.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitInnerJS.scala @@ -48,7 +48,7 @@ import scala.collection.mutable */ abstract class ExplicitInnerJS extends plugins.PluginComponent with InfoTransform with TypingTransformers - with PluginComponentCompat { + with CompatComponent { val jsAddons: JSGlobalAddons { val global: ExplicitInnerJS.this.global.type @@ -77,10 +77,8 @@ abstract class ExplicitInnerJS * This is true in 2.12+, since the addition of the `fields` phase. * @see https://github.com/scala/scala/pull/5141 */ - private lazy val traitValsHoldTheirGetterSymbol = { - val v = scala.util.Properties.versionNumberString - !v.startsWith("2.10.") && !v.startsWith("2.11.") - } + private lazy val traitValsHoldTheirGetterSymbol = + !scala.util.Properties.versionNumberString.startsWith("2.11.") protected def newTransformer(unit: CompilationUnit): Transformer = new ExplicitInnerJSTransformer(unit) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitLocalJS.scala b/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitLocalJS.scala index 47c8c9af8d..166942a302 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitLocalJS.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitLocalJS.scala @@ -111,7 +111,7 @@ import scala.collection.mutable */ abstract class ExplicitLocalJS extends plugins.PluginComponent with Transform with TypingTransformers - with PluginComponentCompat { + with CompatComponent { val jsAddons: JSGlobalAddons { val global: ExplicitLocalJS.this.global.type diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index b5c69898fa..017fe10883 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -33,7 +33,7 @@ abstract class GenJSCode extends plugins.PluginComponent with JSEncoding with GenJSExports with GenJSFiles - with PluginComponentCompat { + with CompatComponent { val jsAddons: JSGlobalAddons { val global: GenJSCode.this.global.type @@ -3138,7 +3138,8 @@ abstract class GenJSCode extends plugins.PluginComponent /** Gen JS code for a translated match * * This implementation relies heavily on the patterns of trees emitted - * by the current pattern match phase (as of Scala 2.10). + * by the pattern match phase, including its variants across versions of + * scalac that we support. * * The trees output by the pattern matcher are assumed to follow these * rules: @@ -3552,12 +3553,7 @@ abstract class GenJSCode extends plugins.PluginComponent /** See comment in `genEqEqPrimitive()` about `mustUseAnyComparator`. */ private lazy val shouldPreserveEqEqBugWithJLFloatDouble = { val v = scala.util.Properties.versionNumberString - - { - v.startsWith("2.10.") || - v.startsWith("2.11.") || - v == "2.12.1" - } + v.startsWith("2.11.") || v == "2.12.1" } /** Gen JS code for a call to Any.== */ @@ -3599,12 +3595,11 @@ abstract class GenJSCode extends plugins.PluginComponent if (mustUseAnyComparator) { val equalsMethod: Symbol = { // scalastyle:off line.size.limit - val ptfm = platform.asInstanceOf[backend.JavaPlatform with ThisPlatform] // 2.10 compat if (ltpe <:< BoxedNumberClass.tpe) { - if (rtpe <:< BoxedNumberClass.tpe) ptfm.externalEqualsNumNum - else if (rtpe <:< BoxedCharacterClass.tpe) ptfm.externalEqualsNumObject // will be externalEqualsNumChar in 2.12, SI-9030 - else ptfm.externalEqualsNumObject - } else ptfm.externalEquals + if (rtpe <:< BoxedNumberClass.tpe) platform.externalEqualsNumNum + else if (rtpe <:< BoxedCharacterClass.tpe) platform.externalEqualsNumObject // will be externalEqualsNumChar in 2.12, SI-9030 + else platform.externalEqualsNumObject + } else platform.externalEquals // scalastyle:on line.size.limit } val moduleClass = equalsMethod.owner @@ -4225,13 +4220,7 @@ abstract class GenJSCode extends plugins.PluginComponent val sym = tree.symbol val Apply(fun @ Select(receiver0, _), args0) = tree - /* In 2.10, scalac does not give a position to updateDynamic calls, and - * this causes significantly bad error messages for global scope - * selection. Therefore, we are a bit more careful here. - */ - implicit val pos = - if (tree.pos.isDefined) tree.pos - else fun.pos + implicit val pos = tree.pos val receiver = genExprOrGlobalScope(receiver0) val args = genPrimitiveJSArgs(sym, args0) @@ -5600,12 +5589,10 @@ abstract class GenJSCode extends plugins.PluginComponent * * Mixed-in fields are always mutable, since they will be assigned to in * a trait initializer (rather than a constructor). - * Further, in 2.10.x fields used to implement lazy vals are not marked - * mutable (but assigned to in the accessor). */ private def suspectFieldMutable(sym: Symbol) = { import scala.reflect.internal.Flags - sym.hasFlag(Flags.MIXEDIN) || sym.isMutable || sym.isLazy + sym.hasFlag(Flags.MIXEDIN) || sym.isMutable } private def isStringType(tpe: Type): Boolean = diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index d5686967a0..74f16f8007 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -26,7 +26,7 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val HackedStringClass = getClassIfDefined("java.lang._String") lazy val HackedStringModClass = getModuleIfDefined("java.lang._String").moduleClass - lazy val ScalaJSJSPackage = getPackage(newTermNameCached("scala.scalajs.js")) // compat 2.10/2.11 + lazy val ScalaJSJSPackage = getPackage(newTermNameCached("scala.scalajs.js")) // compat 2.11 lazy val JSPackage_typeOf = getMemberMethod(ScalaJSJSPackage, newTermName("typeOf")) lazy val JSPackage_constructorOf = getMemberMethod(ScalaJSJSPackage, newTermName("constructorOf")) lazy val JSPackage_native = getMemberMethod(ScalaJSJSPackage, newTermName("native")) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala index 1732971e43..c30b18392d 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala @@ -136,8 +136,7 @@ trait JSEncoding extends SubComponent { self: GenJSCode => val usePerClassSuffix = { sym.isPrivate || sym.isJavaDefined || - sym.isOuterField || // Scala 2.11+ - sym.isOuterAccessor // Scala 2.10 workaround + sym.isOuterField } if (usePerClassSuffix) sym.owner.ancestors.count(!_.isTraitOrInterface).toString diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PreTyperComponent.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PreTyperComponent.scala index 0266ce8e68..303a594b3e 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PreTyperComponent.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PreTyperComponent.scala @@ -61,7 +61,7 @@ import nsc._ * @author Nicolas Stucki */ abstract class PreTyperComponent extends plugins.PluginComponent - with transform.Transform with PluginComponentCompat { + with transform.Transform with CompatComponent { import global._ diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 367b4a047a..d9e6ad4633 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -28,7 +28,7 @@ import org.scalajs.core.ir.Trees.{isValidIdentifier, JSNativeLoadSpec} abstract class PrepJSInterop extends plugins.PluginComponent with PrepJSExports with transform.Transform - with PluginComponentCompat { + with CompatComponent { import PrepJSInterop._ val jsAddons: JSGlobalAddons { @@ -70,18 +70,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent val Value = newTermName("Value") val Val = newTermName("Val") - val ArrowAssoc = { - if (scala.util.Properties.versionNumberString.startsWith("2.10.")) - newTermName("any2ArrowAssoc") - else - newTermName("ArrowAssoc") - } - - val MINGT = encode("->") // not defined in nme in 2.10 - } - - private object jstpnme { - val scala_ = newTypeName("scala") // not defined in 2.10's tpnme + val ArrowAssoc = newTermName("ArrowAssoc") } private final val SuppressMissingJSGlobalDeprecationsMsg = { @@ -392,10 +381,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent propNameTree match { case Literal(Constant(propName: String)) => if (!knownPropNames.add(propName)) { - val pos = - if (propNameTree.pos.isDefined) propNameTree.pos - else tree.pos // this happens in 2.10 - reporter.warning(pos, + reporter.warning(propNameTree.pos, s"""Duplicate property "$propName" shadows a """ + "previously defined one") } @@ -407,7 +393,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent case Apply(fun, List(propNameTree, _)) if fun.symbol == Tuple2_apply => processPropName(propNameTree) - case Apply(fun @ TypeApply(Select(receiver, jsnme.MINGT), _), _) + case Apply(fun @ TypeApply(Select(receiver, nme.MINGT), _), _) if currentRun.runDefinitions.isArrowAssoc(fun.symbol) => receiver match { case Apply(TypeApply(Select(predef, jsnme.ArrowAssoc), _), @@ -624,9 +610,8 @@ abstract class PrepJSInterop extends plugins.PluginComponent reporter.error(implDef.pos, "non-native JS classes, traits and " + "objects may not have inner native JS classes, traits or objects") } else if (!sym.isTrait) { - /* Compute the loading spec now, before `flatten` destroys the name - * and (in 2.10) the original owner chain. We store it in a global - * map. + /* Compute the loading spec now, before `flatten` destroys the name. + * We store it in a global map. */ val optLoadSpec = checkAndComputeJSNativeLoadSpecOf(implDef.pos, sym) for (loadSpec <- optLoadSpec) diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/EnumerationInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/EnumerationInteropTest.scala index 5b017aa9d7..257e25c458 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/EnumerationInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/EnumerationInteropTest.scala @@ -116,7 +116,19 @@ class EnumerationInteropTest extends DirectTest with TestHelpers { protected class Val1 extends Val protected class Val2 extends Val(1) } - """ warns() // no message checking: position differs in 2.10 and 2.11 + """ hasWarns + """ + |newSource1.scala:3: warning: Calls to the non-string constructors of Enumeration.Val + |require reflection at runtime. The resulting + |program is unlikely to function properly. + | protected class Val1 extends Val + | ^ + |newSource1.scala:4: warning: Calls to the non-string constructors of Enumeration.Val + |require reflection at runtime. The resulting + |program is unlikely to function properly. + | protected class Val2 extends Val(1) + | ^ + """ } @@ -128,7 +140,19 @@ class EnumerationInteropTest extends DirectTest with TestHelpers { protected class Val1 extends Val(null) protected class Val2 extends Val(1,null) } - """ warns() // no message checking: position differs in 2.10 and 2.11 + """ hasWarns + """ + |newSource1.scala:3: warning: Passing null as name to a constructor of Enumeration.Val + |requires reflection at runtime. The resulting + |program is unlikely to function properly. + | protected class Val1 extends Val(null) + | ^ + |newSource1.scala:4: warning: Passing null as name to a constructor of Enumeration.Val + |requires reflection at runtime. The resulting + |program is unlikely to function properly. + | protected class Val2 extends Val(1,null) + | ^ + """ } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSDynamicLiteralTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSDynamicLiteralTest.scala index 1227fd30f6..bf00ead0b2 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSDynamicLiteralTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSDynamicLiteralTest.scala @@ -103,22 +103,10 @@ class JSDynamicLiteralTest extends DirectTest with TestHelpers { @Test def keyDuplicationWarning: Unit = { - val version = scala.util.Properties.versionNumberString - val hasSuboptimalPositions = version.startsWith("2.10.") - - implicit class MyHasWarnsOps(val code: CompileTests) { - def hasWarnsForByName(expected: String): Unit = { - if (hasSuboptimalPositions) - code.warns() - else - code.hasWarns(expected) - } - } - // detects duplicate named keys expr""" lit(a = "1", b = "2", a = "3") - """ hasWarnsForByName + """ hasWarns """ |newSource1.scala:3: warning: Duplicate property "a" shadows a previously defined one | lit(a = "1", b = "2", a = "3") @@ -128,7 +116,7 @@ class JSDynamicLiteralTest extends DirectTest with TestHelpers { // detects duplicate named keys expr""" lit(aaa = "1", b = "2", aaa = "3") - """ hasWarnsForByName + """ hasWarns """ |newSource1.scala:3: warning: Duplicate property "aaa" shadows a previously defined one | lit(aaa = "1", b = "2", aaa = "3") @@ -140,7 +128,7 @@ class JSDynamicLiteralTest extends DirectTest with TestHelpers { lit(aaa = "1", bb = "2", bb = "3") - """ hasWarnsForByName + """ hasWarns """ |newSource1.scala:5: warning: Duplicate property "bb" shadows a previously defined one | bb = "3") @@ -152,7 +140,7 @@ class JSDynamicLiteralTest extends DirectTest with TestHelpers { lit(aaa = "1", b = "2", aaa = "3") - """ hasWarnsForByName + """ hasWarns """ |newSource1.scala:5: warning: Duplicate property "aaa" shadows a previously defined one | aaa = "3") @@ -162,7 +150,7 @@ class JSDynamicLiteralTest extends DirectTest with TestHelpers { // detects triplicated named keys expr""" lit(a = "1", a = "2", a = "3") - """ hasWarnsForByName + """ hasWarns """ |newSource1.scala:3: warning: Duplicate property "a" shadows a previously defined one | lit(a = "1", a = "2", a = "3") @@ -175,7 +163,7 @@ class JSDynamicLiteralTest extends DirectTest with TestHelpers { // detects two different duplicates named keys expr""" lit(a = "1", b = "2", a = "3", b = "4", c = "5", c = "6", c = "7") - """ hasWarnsForByName + """ hasWarns """ |newSource1.scala:3: warning: Duplicate property "a" shadows a previously defined one | lit(a = "1", b = "2", a = "3", b = "4", c = "5", c = "6", c = "7") diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index 67c694b016..843d982d7a 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -874,7 +874,7 @@ class JSExportTest extends DirectTest with TestHelpers { private def since(v: String): String = { val version = scala.util.Properties.versionNumberString - if (version.startsWith("2.10.") || version.startsWith("2.11.")) "" + if (version.startsWith("2.11.")) "" else s" (since $v)" } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSSAMTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSSAMTest.scala index 6d805ecac1..57afbeecec 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSSAMTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSSAMTest.scala @@ -40,7 +40,7 @@ class JSSAMTest extends DirectTest with TestHelpers { def noSAMAsJSType212: Unit = { val version = scala.util.Properties.versionNumberString - assumeTrue(!version.startsWith("2.10.") && !version.startsWith("2.11.")) + assumeTrue(!version.startsWith("2.11.")) """ @js.native diff --git a/examples/helloworld/helloworld-2.10-fastopt.html b/examples/helloworld/helloworld-2.10-fastopt.html deleted file mode 100644 index b8b413f796..0000000000 --- a/examples/helloworld/helloworld-2.10-fastopt.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - Hello world - Scala.js example - - - - -
-
- - - - - - - diff --git a/examples/helloworld/helloworld-2.10.html b/examples/helloworld/helloworld-2.10.html deleted file mode 100644 index ae117a00f6..0000000000 --- a/examples/helloworld/helloworld-2.10.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - Hello world - Scala.js example - - - - -
-
- - - - - - - diff --git a/examples/reversi/reversi-2.10-fastopt.html b/examples/reversi/reversi-2.10-fastopt.html deleted file mode 100644 index 46cd1c7784..0000000000 --- a/examples/reversi/reversi-2.10-fastopt.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - Reversi - Scala.js example - - - - -

Reversi - Scala.js example

- -

Somewhat inspired by -http://davidbau.com/reversi/

- -
-
- - - - - - - - - diff --git a/examples/reversi/reversi-2.10.html b/examples/reversi/reversi-2.10.html deleted file mode 100644 index 5f7b69602d..0000000000 --- a/examples/reversi/reversi-2.10.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - Reversi - Scala.js example - - - - -

Reversi - Scala.js example

- -

Somewhat inspired by -http://davidbau.com/reversi/

- -
-
- - - - - - - - - diff --git a/javalanglib/src/main/scala/java/lang/EnvironmentInfo.scala b/javalanglib/src/main/scala/java/lang/EnvironmentInfo.scala index 1825f27e20..9629467c0e 100644 --- a/javalanglib/src/main/scala/java/lang/EnvironmentInfo.scala +++ b/javalanglib/src/main/scala/java/lang/EnvironmentInfo.scala @@ -48,12 +48,9 @@ private[lang] object EnvironmentInfo { val envInfo: js.UndefOr[EnvironmentInfo] = { import js.Dynamic.{global => g} - // We've got to use selectDynamic explicitly not to crash Scala 2.10 - if (js.typeOf(g.selectDynamic("__ScalaJSEnv")) == "object" && - g.selectDynamic("__ScalaJSEnv") != null) { - g.selectDynamic("__ScalaJSEnv").asInstanceOf[EnvironmentInfo] - } else { + if (js.typeOf(g.__ScalaJSEnv) == "object" && g.__ScalaJSEnv != null) + g.__ScalaJSEnv.asInstanceOf[EnvironmentInfo] + else js.undefined - } } } diff --git a/javalanglib/src/main/scala/java/lang/ObjectClone.scala b/javalanglib/src/main/scala/java/lang/ObjectClone.scala index 3cf57e2b79..3d3c2628f0 100644 --- a/javalanglib/src/main/scala/java/lang/ObjectClone.scala +++ b/javalanglib/src/main/scala/java/lang/ObjectClone.scala @@ -10,32 +10,26 @@ private[lang] object ObjectClone { private val getOwnPropertyDescriptors: js.Function1[js.Object, js.Object] = { import js.Dynamic.{global, literal} - // The val f = ...; f.asInstanceOf's are necessary for 2.10 not to crash - // Fetch or polyfill Object.getOwnPropertyDescriptors if (js.typeOf(global.Object.getOwnPropertyDescriptors) == "function") { - val f = global.Object.getOwnPropertyDescriptors - f.asInstanceOf[js.Function1[js.Object, js.Object]] + global.Object.getOwnPropertyDescriptors + .asInstanceOf[js.Function1[js.Object, js.Object]] } else { // Fetch or polyfill Reflect.ownKeys type OwnKeysType = js.Function1[js.Object, js.Array[js.Any]] val ownKeysFun: OwnKeysType = { if (js.typeOf(global.Reflect) != "undefined" && js.typeOf(global.Reflect.ownKeys) == "function") { - val f = global.Reflect.ownKeys - f.asInstanceOf[OwnKeysType] + global.Reflect.ownKeys.asInstanceOf[OwnKeysType] } else { // Fetch Object.getOwnPropertyNames - val getOwnPropertyNames = { - val f = global.Object.getOwnPropertyNames - f.asInstanceOf[OwnKeysType] - } + val getOwnPropertyNames = + global.Object.getOwnPropertyNames.asInstanceOf[OwnKeysType] // Fetch or polyfill Object.getOwnPropertySymbols val getOwnPropertySymbols: OwnKeysType = { if (js.typeOf(global.Object.getOwnPropertySymbols) == "function") { - val f = global.Object.getOwnPropertySymbols - f.asInstanceOf[OwnKeysType] + global.Object.getOwnPropertySymbols.asInstanceOf[OwnKeysType] } else { /* Polyfill for Object.getOwnPropertySymbols. * We assume that if that function does not exist, then symbols diff --git a/javalanglib/src/main/scala/java/lang/StackTrace.scala b/javalanglib/src/main/scala/java/lang/StackTrace.scala index 6618b314dd..e2180fb01f 100644 --- a/javalanglib/src/main/scala/java/lang/StackTrace.scala +++ b/javalanglib/src/main/scala/java/lang/StackTrace.scala @@ -302,55 +302,40 @@ private[lang] object StackTrace { * arguments or stack. */ - /* Ideally we would write tests like - * if (e.arguments && e.stack) - * but Scala 2.10 does not like that (too much Dynamic magic, I suppose). - * So we define inlineable defs for the fields we're interested in. - * This way we make the compiler happy - */ - @inline def arguments = e.arguments - @inline def stack = e.stack - @inline def sourceURL = e.sourceURL - @inline def number = e.number - @inline def fileName = e.fileName - @inline def message = e.message - @inline def `opera#sourceloc` = e.`opera#sourceloc` - @inline def stacktrace = e.stacktrace - if (!e) { js.Array[String]() } else if (isRhino) { extractRhino(e) - } else if (arguments && stack) { + } else if (e.arguments && e.stack) { extractChrome(e) - } else if (stack && sourceURL) { + } else if (e.stack && e.sourceURL) { extractSafari(e) - } else if (stack && number) { + } else if (e.stack && e.number) { extractIE(e) - } else if (stack && fileName) { + } else if (e.stack && e.fileName) { extractFirefox(e) - } else if (message && `opera#sourceloc`) { + } else if (e.message && e.`opera#sourceloc`) { // e.message.indexOf("Backtrace:") > -1 -> opera9 // 'opera#sourceloc' in e -> opera9, opera10a // !e.stacktrace -> opera9 @inline def messageIsLongerThanStacktrace = - message.split("\n").length > stacktrace.split("\n").length - if (!stacktrace) { + e.message.split("\n").length > e.stacktrace.split("\n").length + if (!e.stacktrace) { extractOpera9(e) // use e.message - } else if ((message.indexOf("\n") > -1) && messageIsLongerThanStacktrace) { + } else if ((e.message.indexOf("\n") > -1) && messageIsLongerThanStacktrace) { // e.message may have more stack entries than e.stacktrace extractOpera9(e) // use e.message } else { extractOpera10a(e) // use e.stacktrace } - } else if (message && stack && stacktrace) { + } else if (e.message && e.stack && e.stacktrace) { // stacktrace && stack -> opera10b - if (stacktrace.indexOf("called from line") < 0) { + if (e.stacktrace.indexOf("called from line") < 0) { extractOpera10b(e) } else { extractOpera11(e) } - } else if (stack && !fileName) { + } else if (e.stack && !e.fileName) { /* Chrome 27 does not have e.arguments as earlier versions, * but still does not have e.fileName as Firefox */ extractChrome(e) diff --git a/javalanglib/src/main/scala/java/lang/System.scala b/javalanglib/src/main/scala/java/lang/System.scala index 5a8d3aac96..218e604d8d 100644 --- a/javalanglib/src/main/scala/java/lang/System.scala +++ b/javalanglib/src/main/scala/java/lang/System.scala @@ -30,11 +30,10 @@ object System { private[this] val getHighPrecisionTime: js.Function0[scala.Double] = { import js.DynamicImplicits.truthValue - // We've got to use selectDynamic explicitly not to crash Scala 2.10 - if (js.typeOf(global.selectDynamic("performance")) != "undefined") { - if (global.performance.selectDynamic("now")) { + if (js.typeOf(global.performance) != "undefined") { + if (global.performance.now) { () => global.performance.now().asInstanceOf[scala.Double] - } else if (global.performance.selectDynamic("webkitNow")) { + } else if (global.performance.webkitNow) { () => global.performance.webkitNow().asInstanceOf[scala.Double] } else { () => new js.Date().getTime() @@ -369,9 +368,8 @@ private[lang] final class JSConsoleBasedPrintStream(isErr: Boolean) private def doWriteLine(line: String): Unit = { import js.DynamicImplicits.truthValue - // We've got to use selectDynamic explicitly not to crash Scala 2.10 - if (js.typeOf(global.selectDynamic("console")) != "undefined") { - if (isErr && global.console.selectDynamic("error")) + if (js.typeOf(global.console) != "undefined") { + if (isErr && global.console.error) global.console.error(line) else global.console.log(line) diff --git a/javalib/src/main/scala/java/net/URI.scala b/javalib/src/main/scala/java/net/URI.scala index 3ba6a7259d..ba72411f22 100644 --- a/javalib/src/main/scala/java/net/URI.scala +++ b/javalib/src/main/scala/java/net/URI.scala @@ -49,7 +49,7 @@ final class URI(origStr: String) extends Serializable with Comparable[URI] { private val _path = { val useNetPath = fld(AbsAuthority, RelAuthority).isDefined if (useNetPath) - fld(AbsNetPath, RelNetPath) orElse ("": js.UndefOr[String]) // 2.10 wants the type ascription + fld(AbsNetPath, RelNetPath) orElse "" else if (_isAbsolute) fld(AbsAbsPath) else diff --git a/javalib/src/main/scala/java/util/TreeSet.scala b/javalib/src/main/scala/java/util/TreeSet.scala index 3b022d45e3..af5789d877 100644 --- a/javalib/src/main/scala/java/util/TreeSet.scala +++ b/javalib/src/main/scala/java/util/TreeSet.scala @@ -142,7 +142,6 @@ class TreeSet[E] (_comparator: Comparator[_ >: E]) val boxedFrom = Box(fromElement) val boxedTo = Box(toElement) val subSetFun = { () => - // the creation of a new TreeSet is to avoid a mysterious bug with scala 2.10 var base = new mutable.TreeSet[Box[E]] base ++= inner.range(boxedFrom, boxedTo) if (!fromInclusive) @@ -162,7 +161,6 @@ class TreeSet[E] (_comparator: Comparator[_ >: E]) def headSet(toElement: E, inclusive: Boolean): NavigableSet[E] = { val boxed = Box(toElement) val headSetFun = { () => - // the creation of a new TreeSet is to avoid a mysterious bug with scala 2.10 var base = new mutable.TreeSet[Box[E]] if (inclusive) base ++= inner.to(boxed) @@ -180,7 +178,6 @@ class TreeSet[E] (_comparator: Comparator[_ >: E]) def tailSet(fromElement: E, inclusive: Boolean): NavigableSet[E] = { val boxed = Box(fromElement) val tailSetFun = { () => - // the creation of a new TreeSet is to avoid a mysterious bug with scala 2.10 var base = new mutable.TreeSet[Box[E]] base ++= inner.from(boxed) if (!inclusive) diff --git a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/Compat210Component.scala b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/Compat210Component.scala deleted file mode 100644 index 8ed56424a8..0000000000 --- a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/Compat210Component.scala +++ /dev/null @@ -1,71 +0,0 @@ -package org.scalajs.junit.plugin - -import scala.reflect.internal.Flags -import scala.tools.nsc._ - -/** Hacks to have our source code compatible with 2.10 and 2.11. - * It exposes 2.11 API in a 2.10 compiler. - * - * @author Nicolas Stucki - */ -trait Compat210Component { - - val global: Global - - import global._ - - def newValDef(sym: Symbol, rhs: Tree)( - mods: Modifiers = Modifiers(sym.flags), - name: TermName = sym.name.toTermName, - tpt: Tree = TypeTreeMemberType(sym)): ValDef = { - atPos(sym.pos)(ValDef(mods, name, tpt, rhs)) setSymbol sym - } - - def newDefDef(sym: Symbol, rhs: Tree)( - mods: Modifiers = Modifiers(sym.flags), - name: TermName = sym.name.toTermName, - tparams: List[TypeDef] = sym.typeParams.map(sym => - newTypeDef(sym, typeBoundsTree(sym))()), - vparamss: List[List[ValDef]] = mapParamss(sym)(sym => - newValDef(sym, EmptyTree)()), - tpt: Tree = TypeTreeMemberType(sym)): DefDef = { - atPos(sym.pos)(DefDef(mods, name, tparams, vparamss, tpt, rhs)).setSymbol(sym) - } - - def TypeTreeMemberType(sym: Symbol): TypeTree = { - val resType = { - if (sym.owner.isTerm) sym.tpe - else sym.owner.thisType.memberType(sym) - }.finalResultType - atPos(sym.pos.focus)(TypeTree(resType)) - } - - private def newTypeDef(sym: Symbol, rhs: Tree)( - mods: Modifiers = Modifiers(sym.flags), - name: TypeName = sym.name.toTypeName, - tparams: List[TypeDef] = sym.typeParams.map(sym => - newTypeDef(sym, typeBoundsTree(sym))())): TypeDef = { - atPos(sym.pos)(TypeDef(mods, name, tparams, rhs)) setSymbol sym - } - - private def typeBoundsTree(bounds: TypeBounds): TypeBoundsTree = - TypeBoundsTree(TypeTree(bounds.lo), TypeTree(bounds.hi)) - - private def typeBoundsTree(sym: Symbol): TypeBoundsTree = - atPos(sym.pos)(typeBoundsTree(sym.info.bounds)) - - implicit final class GenCompat(self: global.TreeGen) { - def mkClassDef(mods: Modifiers, name: TypeName, - tparams: List[TypeDef], templ: Template): ClassDef = { - val isInterface = - mods.isTrait && templ.body.forall(treeInfo.isInterfaceMember) - val mods1 = if (isInterface) mods | Flags.INTERFACE else mods - ClassDef(mods1, name, tparams, templ) - } - } - - implicit final class DefinitionsCompat( - self: Compat210Component.this.global.definitions.type) { - lazy val StringTpe = definitions.StringClass.tpe - } -} diff --git a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala index 7d52272f25..d60ced87f8 100644 --- a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala +++ b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala @@ -102,7 +102,7 @@ class ScalaJSJUnitPlugin(val global: Global) extends NscPlugin { } object ScalaJSJUnitPluginComponent - extends plugins.PluginComponent with transform.Transform with Compat210Component { + extends plugins.PluginComponent with transform.Transform { val global: Global = ScalaJSJUnitPlugin.this.global import global._ diff --git a/library-aux/src/main/scala/scala/runtime/Statics.scala b/library-aux/src/main/scala/scala/runtime/Statics.scala index bec86b2609..c0790f2ba8 100644 --- a/library-aux/src/main/scala/scala/runtime/Statics.scala +++ b/library-aux/src/main/scala/scala/runtime/Statics.scala @@ -42,7 +42,7 @@ object Statics { def doubleHash(dv: Double): Int = { /* This implementation is based on what 2.12.0-M5+ does on the JVM. - * The 2.10/2.11 implementation on the JVM was not consistent with that of + * The 2.11 implementation on the JVM was not consistent with that of * BoxesRunTime, and most importantly was not consistent with the hash of * Long values. * diff --git a/library/src/main/scala/scala/scalajs/js/DynamicImplicits.scala b/library/src/main/scala/scala/scalajs/js/DynamicImplicits.scala index 0c423eaa65..98948b796c 100644 --- a/library/src/main/scala/scala/scalajs/js/DynamicImplicits.scala +++ b/library/src/main/scala/scala/scalajs/js/DynamicImplicits.scala @@ -24,10 +24,6 @@ object DynamicImplicits { @inline implicit def truthValue(x: js.Dynamic): Boolean = (!(!x)).asInstanceOf[Boolean] - // Useful for Scala 2.10 - implicit def number2dynamic(x: Int): js.Dynamic = - x.asInstanceOf[js.Dynamic] - implicit def number2dynamic(x: Double): js.Dynamic = x.asInstanceOf[js.Dynamic] diff --git a/library/src/main/scala/scala/scalajs/js/JSConverters.scala b/library/src/main/scala/scala/scalajs/js/JSConverters.scala index 8b78321279..f29a087f78 100644 --- a/library/src/main/scala/scala/scalajs/js/JSConverters.scala +++ b/library/src/main/scala/scala/scalajs/js/JSConverters.scala @@ -90,14 +90,6 @@ object JSConverters extends js.JSConvertersLowPrioImplicits { implicit ev: C => GenTraversableOnce[T]): JSRichGenTraversableOnce[T] = new JSRichGenTraversableOnce(coll) - /** Special case for scala.Array of [[genTravConvertible2JSRichGenTrav]]. - * Needed for the 2.10.x series. - */ - @inline - implicit def array2JSRichGenTrav[T]( - arr: scala.Array[T]): JSRichGenTraversableOnce[T] = - new JSRichGenTraversableOnce(arr) - @inline implicit def JSRichFutureThenable[A](f: Future[js.Thenable[A]]): JSRichFuture[A] = new JSRichFuture[A](f) diff --git a/project/Build.scala b/project/Build.scala index 8c44e1047c..cc75b15cec 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -824,7 +824,6 @@ object Build { lazy val delambdafySetting = { scalacOptions ++= ( if (isGeneratingEclipse) Seq() - else if (scalaBinaryVersion.value == "2.10") Seq() else Seq("-Ydelambdafy:method")) } @@ -953,9 +952,9 @@ object Build { // Calculates all prefixes of the current Scala version // (including the empty prefix) to construct override // directories like the following: - // - override-2.10.2-RC1 - // - override-2.10.2 - // - override-2.10 + // - override-2.11.0-RC1 + // - override-2.11.0 + // - override-2.11 // - override-2 // - override val ver = scalaVersion.value @@ -1010,21 +1009,6 @@ object Build { sources.result() }, - // Continuation plugin (when using 2.10.x) - autoCompilerPlugins := true, - libraryDependencies ++= { - val ver = scalaVersion.value - if (ver.startsWith("2.10.")) - Seq(compilerPlugin("org.scala-lang.plugins" % "continuations" % ver)) - else - Nil - }, - scalacOptions ++= { - if (scalaVersion.value.startsWith("2.10.")) - Seq("-P:continuations:enable") - else - Nil - }, scalaJSExternalCompileSettings ).withScalaJSCompiler.dependsOnLibraryNoJar @@ -1352,8 +1336,7 @@ object Build { testDir.getParentFile.getParentFile.getParentFile / "shared/src/test" val scalaV = scalaVersion.value - val isScalaAtLeast212 = - !scalaV.startsWith("2.10.") && !scalaV.startsWith("2.11.") + val isScalaAtLeast212 = !scalaV.startsWith("2.11.") List(sharedTestDir / "scala", sharedTestDir / "require-jdk7", sharedTestDir / "require-jdk8") ++ @@ -1362,7 +1345,6 @@ object Build { sources in Test ++= { val supportsSAM = scalaBinaryVersion.value match { - case "2.10" => false case "2.11" => scalacOptions.value.contains("-Xexperimental") case _ => true } @@ -1520,21 +1502,6 @@ object Build { Seq(outFile) }.taskValue, - // Exclude tests based on version-dependent limitations - sources in Test := { - val sourceFiles = (sources in Test).value - val v = scalaVersion.value - - val sourceFiles1 = { - if (v.startsWith("2.10.")) - sourceFiles.filterNot(_.getName.endsWith("Require211.scala")) - else - sourceFiles - } - - sourceFiles1 - }, - // Module initializers. Duplicated in toolsJS/test scalaJSModuleInitializers += { ModuleInitializer.mainMethod( @@ -1737,9 +1704,6 @@ object Build { testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a", "-s"), unmanagedSources in Test ++= { - assert(scalaBinaryVersion.value != "2.10", - "scalaTestSuite is not supported on Scala 2.10") - def loadList(listName: String): Set[String] = { val listsDir = (resourceDirectory in Test).value / scalaVersion.value val buff = scala.io.Source.fromFile(listsDir / listName) diff --git a/scalalib/overrides-2.10/scala/Array.scala b/scalalib/overrides-2.10/scala/Array.scala deleted file mode 100644 index 93e07028e0..0000000000 --- a/scalalib/overrides-2.10/scala/Array.scala +++ /dev/null @@ -1,550 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala - -import scala.collection.generic._ -import scala.collection.{ mutable, immutable } -import mutable.{ ArrayBuilder, ArraySeq } -import java.lang.System.arraycopy -import scala.reflect.ClassTag -import scala.runtime.ScalaRunTime.{ array_apply, array_update } - -/** Contains a fallback builder for arrays when the element type - * does not have a class tag. In that case a generic array is built. - */ -class FallbackArrayBuilding { - - /** A builder factory that generates a generic array. - * Called instead of `Array.newBuilder` if the element type of an array - * does not have a class tag. Note that fallbackBuilder factory - * needs an implicit parameter (otherwise it would not be dominated in - * implicit search by `Array.canBuildFrom`). We make sure that - * implicit search is always successful. - */ - implicit def fallbackCanBuildFrom[T](implicit m: DummyImplicit): CanBuildFrom[Array[_], T, ArraySeq[T]] = - new CanBuildFrom[Array[_], T, ArraySeq[T]] { - def apply(from: Array[_]) = ArraySeq.newBuilder[T] - def apply() = ArraySeq.newBuilder[T] - } -} - -/** Utility methods for operating on arrays. - * For example: - * {{{ - * val a = Array(1, 2) - * val b = Array.ofDim[Int](2) - * val c = Array.concat(a, b) - * }}} - * where the array objects `a`, `b` and `c` have respectively the values - * `Array(1, 2)`, `Array(0, 0)` and `Array(1, 2, 0, 0)`. - * - * @author Martin Odersky - * @version 1.0 - */ -object Array extends FallbackArrayBuilding { - def emptyBooleanArray = EmptyArrays.emptyBooleanArray - def emptyByteArray = EmptyArrays.emptyByteArray - def emptyCharArray = EmptyArrays.emptyCharArray - def emptyDoubleArray = EmptyArrays.emptyDoubleArray - def emptyFloatArray = EmptyArrays.emptyFloatArray - def emptyIntArray = EmptyArrays.emptyIntArray - def emptyLongArray = EmptyArrays.emptyLongArray - def emptyShortArray = EmptyArrays.emptyShortArray - def emptyObjectArray = EmptyArrays.emptyObjectArray - - private object EmptyArrays { - val emptyBooleanArray = new Array[Boolean](0) - val emptyByteArray = new Array[Byte](0) - val emptyCharArray = new Array[Char](0) - val emptyDoubleArray = new Array[Double](0) - val emptyFloatArray = new Array[Float](0) - val emptyIntArray = new Array[Int](0) - val emptyLongArray = new Array[Long](0) - val emptyShortArray = new Array[Short](0) - val emptyObjectArray = new Array[Object](0) - } - - implicit def canBuildFrom[T](implicit t: ClassTag[T]): CanBuildFrom[Array[_], T, Array[T]] = { - @inline - class ArrayCanBuildFrom extends CanBuildFrom[Array[_], T, Array[T]] { - def apply(from: Array[_]) = ArrayBuilder.make[T]()(t) - def apply() = ArrayBuilder.make[T]()(t) - } - new ArrayCanBuildFrom - } - - /** - * Returns a new [[scala.collection.mutable.ArrayBuilder]]. - */ - def newBuilder[T](implicit t: ClassTag[T]): ArrayBuilder[T] = ArrayBuilder.make[T]()(t) - - private def slowcopy(src : AnyRef, - srcPos : Int, - dest : AnyRef, - destPos : Int, - length : Int) { - var i = srcPos - var j = destPos - val srcUntil = srcPos + length - while (i < srcUntil) { - array_update(dest, j, array_apply(src, i)) - i += 1 - j += 1 - } - } - - /** Copy one array to another. - * Equivalent to Java's - * `System.arraycopy(src, srcPos, dest, destPos, length)`, - * except that this also works for polymorphic and boxed arrays. - * - * Note that the passed-in `dest` array will be modified by this call. - * - * @param src the source array. - * @param srcPos starting position in the source array. - * @param dest destination array. - * @param destPos starting position in the destination array. - * @param length the number of array elements to be copied. - * - * @see `java.lang.System#arraycopy` - */ - def copy(src: AnyRef, srcPos: Int, dest: AnyRef, destPos: Int, length: Int) { - val srcClass = src.getClass - if (srcClass.isArray && dest.getClass.isAssignableFrom(srcClass)) - arraycopy(src, srcPos, dest, destPos, length) - else - slowcopy(src, srcPos, dest, destPos, length) - } - - /** Returns an array of length 0 */ - def empty[T: ClassTag]: Array[T] = new Array[T](0) - - /** Creates an array with given elements. - * - * @param xs the elements to put in the array - * @return an array containing all elements from xs. - */ - // Subject to a compiler optimization in Cleanup. - // Array(e0, ..., en) is translated to { val a = new Array(3); a(i) = ei; a } - def apply[T: ClassTag](xs: T*): Array[T] = { - val array = new Array[T](xs.length) - var i = 0 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Boolean` objects */ - // Subject to a compiler optimization in Cleanup, see above. - def apply(x: Boolean, xs: Boolean*): Array[Boolean] = { - val array = new Array[Boolean](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Byte` objects */ - // Subject to a compiler optimization in Cleanup, see above. - def apply(x: Byte, xs: Byte*): Array[Byte] = { - val array = new Array[Byte](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Short` objects */ - // Subject to a compiler optimization in Cleanup, see above. - def apply(x: Short, xs: Short*): Array[Short] = { - val array = new Array[Short](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Char` objects */ - // Subject to a compiler optimization in Cleanup, see above. - def apply(x: Char, xs: Char*): Array[Char] = { - val array = new Array[Char](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Int` objects */ - // Subject to a compiler optimization in Cleanup, see above. - def apply(x: Int, xs: Int*): Array[Int] = { - val array = new Array[Int](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Long` objects */ - // Subject to a compiler optimization in Cleanup, see above. - def apply(x: Long, xs: Long*): Array[Long] = { - val array = new Array[Long](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Float` objects */ - // Subject to a compiler optimization in Cleanup, see above. - def apply(x: Float, xs: Float*): Array[Float] = { - val array = new Array[Float](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Double` objects */ - // Subject to a compiler optimization in Cleanup, see above. - def apply(x: Double, xs: Double*): Array[Double] = { - val array = new Array[Double](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Unit` objects */ - def apply(x: Unit, xs: Unit*): Array[Unit] = { - val array = new Array[Unit](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates array with given dimensions */ - def ofDim[T: ClassTag](n1: Int): Array[T] = - new Array[T](n1) - /** Creates a 2-dimensional array */ - def ofDim[T: ClassTag](n1: Int, n2: Int): Array[Array[T]] = { - val arr: Array[Array[T]] = (new Array[Array[T]](n1): Array[Array[T]]) - for (i <- 0 until n1) arr(i) = new Array[T](n2) - arr - // tabulate(n1)(_ => ofDim[T](n2)) - } - /** Creates a 3-dimensional array */ - def ofDim[T: ClassTag](n1: Int, n2: Int, n3: Int): Array[Array[Array[T]]] = - tabulate(n1)(_ => ofDim[T](n2, n3)) - /** Creates a 4-dimensional array */ - def ofDim[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int): Array[Array[Array[Array[T]]]] = - tabulate(n1)(_ => ofDim[T](n2, n3, n4)) - /** Creates a 5-dimensional array */ - def ofDim[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int): Array[Array[Array[Array[Array[T]]]]] = - tabulate(n1)(_ => ofDim[T](n2, n3, n4, n5)) - - /** Concatenates all arrays into a single array. - * - * @param xss the given arrays - * @return the array created from concatenating `xss` - */ - def concat[T: ClassTag](xss: Array[T]*): Array[T] = { - val b = newBuilder[T] - b.sizeHint(xss.map(_.size).sum) - for (xs <- xss) b ++= xs - b.result - } - - /** Returns an array that contains the results of some element computation a number - * of times. - * - * Note that this means that `elem` is computed a total of n times: - * {{{ - * scala> Array.fill(3){ math.random } - * res3: Array[Double] = Array(0.365461167592537, 1.550395944913685E-4, 0.7907242137333306) - * }}} - * - * @param n the number of elements desired - * @param elem the element computation - * @return an Array of size n, where each element contains the result of computing - * `elem`. - */ - def fill[T: ClassTag](n: Int)(elem: => T): Array[T] = { - val b = newBuilder[T] - b.sizeHint(n) - var i = 0 - while (i < n) { - b += elem - i += 1 - } - b.result - } - - /** Returns a two-dimensional array that contains the results of some element - * computation a number of times. - * - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param elem the element computation - */ - def fill[T: ClassTag](n1: Int, n2: Int)(elem: => T): Array[Array[T]] = - tabulate(n1)(_ => fill(n2)(elem)) - - /** Returns a three-dimensional array that contains the results of some element - * computation a number of times. - * - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param n3 the number of elements in the 3nd dimension - * @param elem the element computation - */ - def fill[T: ClassTag](n1: Int, n2: Int, n3: Int)(elem: => T): Array[Array[Array[T]]] = - tabulate(n1)(_ => fill(n2, n3)(elem)) - - /** Returns a four-dimensional array that contains the results of some element - * computation a number of times. - * - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param n3 the number of elements in the 3nd dimension - * @param n4 the number of elements in the 4th dimension - * @param elem the element computation - */ - def fill[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int)(elem: => T): Array[Array[Array[Array[T]]]] = - tabulate(n1)(_ => fill(n2, n3, n4)(elem)) - - /** Returns a five-dimensional array that contains the results of some element - * computation a number of times. - * - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param n3 the number of elements in the 3nd dimension - * @param n4 the number of elements in the 4th dimension - * @param n5 the number of elements in the 5th dimension - * @param elem the element computation - */ - def fill[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(elem: => T): Array[Array[Array[Array[Array[T]]]]] = - tabulate(n1)(_ => fill(n2, n3, n4, n5)(elem)) - - /** Returns an array containing values of a given function over a range of integer - * values starting from 0. - * - * @param n The number of elements in the array - * @param f The function computing element values - * @return A traversable consisting of elements `f(0),f(1), ..., f(n - 1)` - */ - def tabulate[T: ClassTag](n: Int)(f: Int => T): Array[T] = { - val b = newBuilder[T] - b.sizeHint(n) - var i = 0 - while (i < n) { - b += f(i) - i += 1 - } - b.result - } - - /** Returns a two-dimensional array containing values of a given function - * over ranges of integer values starting from `0`. - * - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param f The function computing element values - */ - def tabulate[T: ClassTag](n1: Int, n2: Int)(f: (Int, Int) => T): Array[Array[T]] = - tabulate(n1)(i1 => tabulate(n2)(f(i1, _))) - - /** Returns a three-dimensional array containing values of a given function - * over ranges of integer values starting from `0`. - * - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param n3 the number of elements in the 3rd dimension - * @param f The function computing element values - */ - def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int)(f: (Int, Int, Int) => T): Array[Array[Array[T]]] = - tabulate(n1)(i1 => tabulate(n2, n3)(f(i1, _, _))) - - /** Returns a four-dimensional array containing values of a given function - * over ranges of integer values starting from `0`. - * - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param n3 the number of elements in the 3rd dimension - * @param n4 the number of elements in the 4th dimension - * @param f The function computing element values - */ - def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int)(f: (Int, Int, Int, Int) => T): Array[Array[Array[Array[T]]]] = - tabulate(n1)(i1 => tabulate(n2, n3, n4)(f(i1, _, _, _))) - - /** Returns a five-dimensional array containing values of a given function - * over ranges of integer values starting from `0`. - * - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param n3 the number of elements in the 3rd dimension - * @param n4 the number of elements in the 4th dimension - * @param n5 the number of elements in the 5th dimension - * @param f The function computing element values - */ - def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(f: (Int, Int, Int, Int, Int) => T): Array[Array[Array[Array[Array[T]]]]] = - tabulate(n1)(i1 => tabulate(n2, n3, n4, n5)(f(i1, _, _, _, _))) - - /** Returns an array containing a sequence of increasing integers in a range. - * - * @param start the start value of the array - * @param end the end value of the array, exclusive (in other words, this is the first value '''not''' returned) - * @return the array with values in range `start, start + 1, ..., end - 1` - * up to, but excluding, `end`. - */ - def range(start: Int, end: Int): Array[Int] = range(start, end, 1) - - /** Returns an array containing equally spaced values in some integer interval. - * - * @param start the start value of the array - * @param end the end value of the array, exclusive (in other words, this is the first value '''not''' returned) - * @param step the increment value of the array (may not be zero) - * @return the array with values in `start, start + step, ...` up to, but excluding `end` - */ - def range(start: Int, end: Int, step: Int): Array[Int] = { - if (step == 0) throw new IllegalArgumentException("zero step") - val b = newBuilder[Int] - b.sizeHint(immutable.Range.count(start, end, step, false)) - - var i = start - while (if (step < 0) end < i else i < end) { - b += i - i += step - } - b.result - } - - /** Returns an array containing repeated applications of a function to a start value. - * - * @param start the start value of the array - * @param len the number of elements returned by the array - * @param f the function that is repeatedly applied - * @return the array returning `len` values in the sequence `start, f(start), f(f(start)), ...` - */ - def iterate[T: ClassTag](start: T, len: Int)(f: T => T): Array[T] = { - val b = newBuilder[T] - - if (len > 0) { - b.sizeHint(len) - var acc = start - var i = 1 - b += acc - - while (i < len) { - acc = f(acc) - i += 1 - b += acc - } - } - b.result - } - - /** Called in a pattern match like `{ case Array(x,y,z) => println('3 elements')}`. - * - * @param x the selector value - * @return sequence wrapped in a [[scala.Some]], if `x` is a Seq, otherwise `None` - */ - def unapplySeq[T](x: Array[T]): Option[IndexedSeq[T]] = - if (x == null) None else Some(x.toIndexedSeq) - // !!! the null check should to be necessary, but without it 2241 fails. Seems to be a bug - // in pattern matcher. @PP: I noted in #4364 I think the behavior is correct. -} - -/** Arrays are mutable, indexed collections of values. `Array[T]` is Scala's representation - * for Java's `T[]`. - * - * {{{ - * val numbers = Array(1, 2, 3, 4) - * val first = numbers(0) // read the first element - * numbers(3) = 100 // replace the 4th array element with 100 - * val biggerNumbers = numbers.map(_ * 2) // multiply all numbers by two - * }}} - * - * Arrays make use of two common pieces of Scala syntactic sugar, shown on lines 2 and 3 of the above - * example code. - * Line 2 is translated into a call to `apply(Int)`, while line 3 is translated into a call to - * `update(Int, T)`. - * - * Two implicit conversions exist in [[scala.Predef]] that are frequently applied to arrays: a conversion - * to [[scala.collection.mutable.ArrayOps]] (shown on line 4 of the example above) and a conversion - * to [[scala.collection.mutable.WrappedArray]] (a subtype of [[scala.collection.Seq]]). - * Both types make available many of the standard operations found in the Scala collections API. - * The conversion to `ArrayOps` is temporary, as all operations defined on `ArrayOps` return an `Array`, - * while the conversion to `WrappedArray` is permanent as all operations return a `WrappedArray`. - * - * The conversion to `ArrayOps` takes priority over the conversion to `WrappedArray`. For instance, - * consider the following code: - * - * {{{ - * val arr = Array(1, 2, 3) - * val arrReversed = arr.reverse - * val seqReversed : Seq[Int] = arr.reverse - * }}} - * - * Value `arrReversed` will be of type `Array[Int]`, with an implicit conversion to `ArrayOps` occurring - * to perform the `reverse` operation. The value of `seqReversed`, on the other hand, will be computed - * by converting to `WrappedArray` first and invoking the variant of `reverse` that returns another - * `WrappedArray`. - * - * @author Martin Odersky - * @version 1.0 - * @see [[http://www.scala-lang.org/docu/files/ScalaReference.pdf Scala Language Specification]], for in-depth information on the transformations the Scala compiler makes on Arrays (Sections 6.6 and 6.15 respectively.) - * @see [[http://docs.scala-lang.org/sips/completed/scala-2-8-arrays.html "Scala 2.8 Arrays"]] the Scala Improvement Document detailing arrays since Scala 2.8. - * @see [[http://docs.scala-lang.org/overviews/collections/arrays.html "The Scala 2.8 Collections' API"]] section on `Array` by Martin Odersky for more information. - * @define coll array - * @define Coll `Array` - * @define orderDependent - * @define orderDependentFold - * @define mayNotTerminateInf - * @define willNotTerminateInf - * @define collectExample - * @define undefinedorder - * @define thatinfo the class of the returned collection. In the standard library configuration, - * `That` is either `Array[B]` if an ClassTag is available for B or `ArraySeq[B]` otherwise. - * @define zipthatinfo $thatinfo - * @define bfinfo an implicit value of class `CanBuildFrom` which determines the result class `That` from the current - * representation type `Repr` and the new element type `B`. - */ -final class Array[T](_length: Int) extends java.io.Serializable with java.lang.Cloneable { - - /** The length of the array */ - def length: Int = throw new Error() - - /** The element at given index. - * - * Indices start at `0`; `xs.apply(0)` is the first element of array `xs`. - * Note the indexing syntax `xs(i)` is a shorthand for `xs.apply(i)`. - * - * @param i the index - * @return the element at the given index - * @throws ArrayIndexOutOfBoundsException if `i < 0` or `length <= i` - */ - def apply(i: Int): T = throw new Error() - - /** Update the element at given index. - * - * Indices start at `0`; `xs.update(i, x)` replaces the i^th^ element in the array. - * Note the syntax `xs(i) = x` is a shorthand for `xs.update(i, x)`. - * - * @param i the index - * @param x the value to be written at index `i` - * @throws ArrayIndexOutOfBoundsException if `i < 0` or `length <= i` - */ - def update(i: Int, x: T) { throw new Error() } - - /** Clone the Array. - * - * @return A clone of the Array. - */ - override def clone(): Array[T] = throw new Error() -} diff --git a/scalalib/overrides-2.10/scala/Console.scala b/scalalib/overrides-2.10/scala/Console.scala deleted file mode 100644 index 7fc2d50ca5..0000000000 --- a/scalalib/overrides-2.10/scala/Console.scala +++ /dev/null @@ -1,468 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala - -import java.io.{BufferedReader, InputStream, InputStreamReader, - IOException, OutputStream, PrintStream, Reader} -import java.text.MessageFormat -import scala.util.DynamicVariable - - -/** Implements functionality for - * printing Scala values on the terminal as well as reading specific values. - * Also defines constants for marking up text on ANSI terminals. - * - * @author Matthias Zenger - * @version 1.0, 03/09/2003 - */ -object Console { - - /** Foreground color for ANSI black */ - final val BLACK = "\033[30m" - /** Foreground color for ANSI red */ - final val RED = "\033[31m" - /** Foreground color for ANSI green */ - final val GREEN = "\033[32m" - /** Foreground color for ANSI yellow */ - final val YELLOW = "\033[33m" - /** Foreground color for ANSI blue */ - final val BLUE = "\033[34m" - /** Foreground color for ANSI magenta */ - final val MAGENTA = "\033[35m" - /** Foreground color for ANSI cyan */ - final val CYAN = "\033[36m" - /** Foreground color for ANSI white */ - final val WHITE = "\033[37m" - - /** Background color for ANSI black */ - final val BLACK_B = "\033[40m" - /** Background color for ANSI red */ - final val RED_B = "\033[41m" - /** Background color for ANSI green */ - final val GREEN_B = "\033[42m" - /** Background color for ANSI yellow */ - final val YELLOW_B = "\033[43m" - /** Background color for ANSI blue */ - final val BLUE_B = "\033[44m" - /** Background color for ANSI magenta */ - final val MAGENTA_B = "\033[45m" - /** Background color for ANSI cyan */ - final val CYAN_B = "\033[46m" - /** Background color for ANSI white */ - final val WHITE_B = "\033[47m" - - /** Reset ANSI styles */ - final val RESET = "\033[0m" - /** ANSI bold */ - final val BOLD = "\033[1m" - /** ANSI underlines */ - final val UNDERLINED = "\033[4m" - /** ANSI blink */ - final val BLINK = "\033[5m" - /** ANSI reversed */ - final val REVERSED = "\033[7m" - /** ANSI invisible */ - final val INVISIBLE = "\033[8m" - - private val outVar = new DynamicVariable[PrintStream](java.lang.System.out) - private val errVar = new DynamicVariable[PrintStream](java.lang.System.err) - private val inVar = new DynamicVariable[BufferedReader](null) - //new BufferedReader(new InputStreamReader(java.lang.System.in))) - - /** The default output, can be overridden by `setOut` */ - def out = outVar.value - /** The default error, can be overridden by `setErr` */ - def err = errVar.value - /** The default input, can be overridden by `setIn` */ - def in = inVar.value - - /** Sets the default output stream. - * - * @param out the new output stream. - */ - def setOut(out: PrintStream) { outVar.value = out } - - /** Sets the default output stream for the duration - * of execution of one thunk. - * - * @example {{{ - * withOut(Console.err) { println("This goes to default _error_") } - * }}} - * - * @param out the new output stream. - * @param thunk the code to execute with - * the new output stream active - * @return the results of `thunk` - * @see `withOut[T](out:OutputStream)(thunk: => T)` - */ - def withOut[T](out: PrintStream)(thunk: =>T): T = - outVar.withValue(out)(thunk) - - /** Sets the default output stream. - * - * @param out the new output stream. - */ - def setOut(out: OutputStream): Unit = - setOut(new PrintStream(out)) - - /** Sets the default output stream for the duration - * of execution of one thunk. - * - * @param out the new output stream. - * @param thunk the code to execute with - * the new output stream active - * @return the results of `thunk` - * @see `withOut[T](out:PrintStream)(thunk: => T)` - */ - def withOut[T](out: OutputStream)(thunk: =>T): T = - withOut(new PrintStream(out))(thunk) - - - /** Sets the default error stream. - * - * @param err the new error stream. - */ - def setErr(err: PrintStream) { errVar.value = err } - - /** Set the default error stream for the duration - * of execution of one thunk. - * @example {{{ - * withErr(Console.out) { println("This goes to default _out_") } - * }}} - * - * @param err the new error stream. - * @param thunk the code to execute with - * the new error stream active - * @return the results of `thunk` - * @see `withErr[T](err:OutputStream)(thunk: =>T)` - */ - def withErr[T](err: PrintStream)(thunk: =>T): T = - errVar.withValue(err)(thunk) - - /** Sets the default error stream. - * - * @param err the new error stream. - */ - def setErr(err: OutputStream): Unit = - setErr(new PrintStream(err)) - - /** Sets the default error stream for the duration - * of execution of one thunk. - * - * @param err the new error stream. - * @param thunk the code to execute with - * the new error stream active - * @return the results of `thunk` - * @see `withErr[T](err:PrintStream)(thunk: =>T)` - */ - def withErr[T](err: OutputStream)(thunk: =>T): T = - withErr(new PrintStream(err))(thunk) - - - /** Sets the default input stream. - * - * @param reader specifies the new input stream. - */ - def setIn(reader: Reader) { - inVar.value = new BufferedReader(reader) - } - - /** Sets the default input stream for the duration - * of execution of one thunk. - * - * @example {{{ - * val someFile:Reader = openFile("file.txt") - * withIn(someFile) { - * // Reads a line from file.txt instead of default input - * println(readLine) - * } - * }}} - * - * @param thunk the code to execute with - * the new input stream active - * - * @return the results of `thunk` - * @see `withIn[T](in:InputStream)(thunk: =>T)` - */ - def withIn[T](reader: Reader)(thunk: =>T): T = - inVar.withValue(new BufferedReader(reader))(thunk) - - /** Sets the default input stream. - * - * @param in the new input stream. - */ - def setIn(in: InputStream) { - setIn(new InputStreamReader(in)) - } - - /** Sets the default input stream for the duration - * of execution of one thunk. - * - * @param in the new input stream. - * @param thunk the code to execute with - * the new input stream active - * @return the results of `thunk` - * @see `withIn[T](reader:Reader)(thunk: =>T)` - */ - def withIn[T](in: InputStream)(thunk: =>T): T = - withIn(new InputStreamReader(in))(thunk) - - /** Prints an object to `out` using its `toString` method. - * - * @param obj the object to print; may be null. - */ - def print(obj: Any) { - out.print(if (null == obj) "null" else obj.toString()) - } - - /** Flushes the output stream. This function is required when partial - * output (i.e. output not terminated by a newline character) has - * to be made visible on the terminal. - */ - def flush() { out.flush() } - - /** Prints a newline character on the default output. - */ - def println() { out.println() } - - /** Prints out an object to the default output, followed by a newline character. - * - * @param x the object to print. - */ - def println(x: Any) { out.println(x) } - - /** Prints its arguments as a formatted string to the default output, - * based on a string pattern (in a fashion similar to printf in C). - * - * The interpretation of the formatting patterns is described in - * - * `java.util.Formatter`. - * - * @param text the pattern for formatting the arguments. - * @param args the arguments used to instantiating the pattern. - * @throws java.lang.IllegalArgumentException if there was a problem with the format string or arguments - */ - def printf(text: String, args: Any*) { out.print(text format (args : _*)) } - - /** Read a full line from the default input. Returns `null` if the end of the - * input stream has been reached. - * - * @return the string read from the terminal or null if the end of stream was reached. - */ - def readLine(): String = in.readLine() - - /** Print formatted text to the default output and read a full line from the default input. - * Returns `null` if the end of the input stream has been reached. - * - * @param text the format of the text to print out, as in `printf`. - * @param args the parameters used to instantiate the format, as in `printf`. - * @return the string read from the default input - */ - def readLine(text: String, args: Any*): String = { - printf(text, args: _*) - readLine() - } - - /** Reads a boolean value from an entire line of the default input. - * Has a fairly liberal interpretation of the input. - * - * @return the boolean value read, or false if it couldn't be converted to a boolean - * @throws java.io.EOFException if the end of the input stream has been reached. - */ - def readBoolean(): Boolean = { - val s = readLine() - if (s == null) - throw new java.io.EOFException("Console has reached end of input") - else - s.toLowerCase() match { - case "true" => true - case "t" => true - case "yes" => true - case "y" => true - case _ => false - } - } - - /** Reads a byte value from an entire line of the default input. - * - * @return the Byte that was read - * @throws java.io.EOFException if the end of the - * input stream has been reached. - * @throws java.lang.NumberFormatException if the value couldn't be converted to a Byte - */ - def readByte(): Byte = { - val s = readLine() - if (s == null) - throw new java.io.EOFException("Console has reached end of input") - else - s.toByte - } - - /** Reads a short value from an entire line of the default input. - * - * @return the short that was read - * @throws java.io.EOFException if the end of the - * input stream has been reached. - * @throws java.lang.NumberFormatException if the value couldn't be converted to a Short - */ - def readShort(): Short = { - val s = readLine() - if (s == null) - throw new java.io.EOFException("Console has reached end of input") - else - s.toShort - } - - /** Reads a char value from an entire line of the default input. - * - * @return the Char that was read - * @throws java.io.EOFException if the end of the - * input stream has been reached. - * @throws java.lang.StringIndexOutOfBoundsException if the line read from default input was empty - */ - def readChar(): Char = { - val s = readLine() - if (s == null) - throw new java.io.EOFException("Console has reached end of input") - else - s charAt 0 - } - - /** Reads an int value from an entire line of the default input. - * - * @return the Int that was read - * @throws java.io.EOFException if the end of the - * input stream has been reached. - * @throws java.lang.NumberFormatException if the value couldn't be converted to an Int - */ - def readInt(): Int = { - val s = readLine() - if (s == null) - throw new java.io.EOFException("Console has reached end of input") - else - s.toInt - } - - /** Reads an long value from an entire line of the default input. - * - * @return the Long that was read - * @throws java.io.EOFException if the end of the - * input stream has been reached. - * @throws java.lang.NumberFormatException if the value couldn't be converted to a Long - */ - def readLong(): Long = { - val s = readLine() - if (s == null) - throw new java.io.EOFException("Console has reached end of input") - else - s.toLong - } - - /** Reads a float value from an entire line of the default input. - * @return the Float that was read. - * @throws java.io.EOFException if the end of the - * input stream has been reached. - * @throws java.lang.NumberFormatException if the value couldn't be converted to a Float - * - */ - def readFloat(): Float = { - val s = readLine() - if (s == null) - throw new java.io.EOFException("Console has reached end of input") - else - s.toFloat - } - - /** Reads a double value from an entire line of the default input. - * - * @return the Double that was read. - * @throws java.io.EOFException if the end of the - * input stream has been reached. - * @throws java.lang.NumberFormatException if the value couldn't be converted to a Float - */ - def readDouble(): Double = { - val s = readLine() - if (s == null) - throw new java.io.EOFException("Console has reached end of input") - else - s.toDouble - } - - /** Reads in some structured input (from the default input), specified by - * a format specifier. See class `java.text.MessageFormat` for details of - * the format specification. - * - * @param format the format of the input. - * @return a list of all extracted values. - * @throws java.io.EOFException if the end of the input stream has been - * reached. - */ - def readf(format: String): List[Any] = { - val s = readLine() - if (s == null) - throw new java.io.EOFException("Console has reached end of input") - else - textComponents(new MessageFormat(format).parse(s)) - } - - /** Reads in some structured input (from the default input), specified by - * a format specifier, returning only the first value extracted, according - * to the format specification. - * - * @param format format string, as accepted by `readf`. - * @return The first value that was extracted from the input - */ - def readf1(format: String): Any = readf(format).head - - /** Reads in some structured input (from the default input), specified - * by a format specifier, returning only the first two values extracted, - * according to the format specification. - * - * @param format format string, as accepted by `readf`. - * @return A [[scala.Tuple2]] containing the first two values extracted - */ - def readf2(format: String): (Any, Any) = { - val res = readf(format) - (res.head, res.tail.head) - } - - /** Reads in some structured input (from the default input), specified - * by a format specifier, returning only the first three values extracted, - * according to the format specification. - * - * @param format format string, as accepted by `readf`. - * @return A [[scala.Tuple3]] containing the first three values extracted - */ - def readf3(format: String): (Any, Any, Any) = { - val res = readf(format) - (res.head, res.tail.head, res.tail.tail.head) - } - - private def textComponents(a: Array[AnyRef]): List[Any] = { - var i: Int = a.length - 1 - var res: List[Any] = Nil - while (i >= 0) { - res = (a(i) match { - case x: java.lang.Boolean => x.booleanValue() - case x: java.lang.Byte => x.byteValue() - case x: java.lang.Short => x.shortValue() - case x: java.lang.Character => x.charValue() - case x: java.lang.Integer => x.intValue() - case x: java.lang.Long => x.longValue() - case x: java.lang.Float => x.floatValue() - case x: java.lang.Double => x.doubleValue() - case x => x - }) :: res; - i -= 1 - } - res - } -} diff --git a/scalalib/overrides-2.10/scala/collection/JavaConversions.scala b/scalalib/overrides-2.10/scala/collection/JavaConversions.scala deleted file mode 100644 index 9bdc6d3e51..0000000000 --- a/scalalib/overrides-2.10/scala/collection/JavaConversions.scala +++ /dev/null @@ -1,132 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2006-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.collection - -import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc } -import convert._ - -/** A collection of implicit conversions supporting interoperability between - * Scala and Java collections. - * - * The following conversions are supported: - *{{{ - * scala.collection.Iterable <=> java.lang.Iterable - * scala.collection.Iterable <=> java.util.Collection - * scala.collection.Iterator <=> java.util.{ Iterator, Enumeration } - * scala.collection.mutable.Buffer <=> java.util.List - * scala.collection.mutable.Set <=> java.util.Set - * scala.collection.mutable.Map <=> java.util.{ Map, Dictionary } - * scala.collection.mutable.ConcurrentMap (deprecated since 2.10) <=> java.util.concurrent.ConcurrentMap - * scala.collection.concurrent.Map <=> java.util.concurrent.ConcurrentMap - *}}} - * In all cases, converting from a source type to a target type and back - * again will return the original source object, eg. - * - *{{{ - * import scala.collection.JavaConversions._ - * - * val sl = new scala.collection.mutable.ListBuffer[Int] - * val jl : java.util.List[Int] = sl - * val sl2 : scala.collection.mutable.Buffer[Int] = jl - * assert(sl eq sl2) - *}}} - * In addition, the following one way conversions are provided: - * - *{{{ - * scala.collection.Seq => java.util.List - * scala.collection.mutable.Seq => java.util.List - * scala.collection.Set => java.util.Set - * scala.collection.Map => java.util.Map - * java.util.Properties => scala.collection.mutable.Map[String, String] - *}}} - * - * @author Miles Sabin - * @author Martin Odersky - * @since 2.8 - */ -object JavaConversions extends WrapAsScala with WrapAsJava { - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type ConcurrentMapWrapper[A, B] = Wrappers.ConcurrentMapWrapper[A, B] - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type DictionaryWrapper[A, B] = Wrappers.DictionaryWrapper[A, B] - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type IterableWrapper[A] = Wrappers.IterableWrapper[A] - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type IteratorWrapper[A] = Wrappers.IteratorWrapper[A] - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JCollectionWrapper[A] = Wrappers.JCollectionWrapper[A] - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JConcurrentMapWrapper[A, B] = Wrappers.JConcurrentMapWrapper[A, B] - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JDictionaryWrapper[A, B] = Wrappers.JDictionaryWrapper[A, B] - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JEnumerationWrapper[A] = Wrappers.JEnumerationWrapper[A] - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JIterableWrapper[A] = Wrappers.JIterableWrapper[A] - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JIteratorWrapper[A] = Wrappers.JIteratorWrapper[A] - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JListWrapper[A] = Wrappers.JListWrapper[A] - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JMapWrapper[A, B] = Wrappers.JMapWrapper[A, B] - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JPropertiesWrapper = Wrappers.JPropertiesWrapper - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JSetWrapper[A] = Wrappers.JSetWrapper[A] - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type MapWrapper[A, B] = Wrappers.MapWrapper[A, B] - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type MutableBufferWrapper[A] = Wrappers.MutableBufferWrapper[A] - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type MutableMapWrapper[A, B] = Wrappers.MutableMapWrapper[A, B] - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type MutableSeqWrapper[A] = Wrappers.MutableSeqWrapper[A] - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type MutableSetWrapper[A] = Wrappers.MutableSetWrapper[A] - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type SeqWrapper[A] = Wrappers.SeqWrapper[A] - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type SetWrapper[A] = Wrappers.SetWrapper[A] - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type ToIteratorWrapper[A] = Wrappers.ToIteratorWrapper[A] - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") def DictionaryWrapper = Wrappers.DictionaryWrapper - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") def IterableWrapper = Wrappers.IterableWrapper - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") def IteratorWrapper = Wrappers.IteratorWrapper - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") def JCollectionWrapper = Wrappers.JCollectionWrapper - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") def JConcurrentMapWrapper = Wrappers.JConcurrentMapWrapper - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") def JDictionaryWrapper = Wrappers.JDictionaryWrapper - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") def JEnumerationWrapper = Wrappers.JEnumerationWrapper - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") def JIterableWrapper = Wrappers.JIterableWrapper - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") def JIteratorWrapper = Wrappers.JIteratorWrapper - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") def JListWrapper = Wrappers.JListWrapper - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") def JMapWrapper = Wrappers.JMapWrapper - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") def JPropertiesWrapper = Wrappers.JPropertiesWrapper - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") def JSetWrapper = Wrappers.JSetWrapper - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") def MutableBufferWrapper = Wrappers.MutableBufferWrapper - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") def MutableMapWrapper = Wrappers.MutableMapWrapper - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") def MutableSeqWrapper = Wrappers.MutableSeqWrapper - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") def MutableSetWrapper = Wrappers.MutableSetWrapper - @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") def SeqWrapper = Wrappers.SeqWrapper - - // Note to implementors: the cavalcade of deprecated methods herein should - // serve as a warning to any who follow: don't overload implicit methods. - - @deprecated("use bufferAsJavaList instead", "2.9.0") - def asJavaList[A](b : mutable.Buffer[A]): ju.List[A] = bufferAsJavaList[A](b) - - @deprecated("use mutableSeqAsJavaList instead", "2.9.0") - def asJavaList[A](b : mutable.Seq[A]): ju.List[A] = mutableSeqAsJavaList[A](b) - - @deprecated("use seqAsJavaList instead", "2.9.0") - def asJavaList[A](b : Seq[A]): ju.List[A] = seqAsJavaList[A](b) - - @deprecated("use mutableSetAsJavaSet instead", "2.9.0") - def asJavaSet[A](s : mutable.Set[A]): ju.Set[A] = mutableSetAsJavaSet[A](s) - - @deprecated("use setAsJavaSet instead", "2.9.0") - def asJavaSet[A](s: Set[A]): ju.Set[A] = setAsJavaSet[A](s) - - @deprecated("use mutableMapAsJavaMap instead", "2.9.0") - def asJavaMap[A, B](m : mutable.Map[A, B]): ju.Map[A, B] = mutableMapAsJavaMap[A, B](m) - - @deprecated("use mapAsJavaMap instead", "2.9.0") - def asJavaMap[A, B](m : Map[A, B]): ju.Map[A, B] = mapAsJavaMap[A, B](m) - - @deprecated("use iterableAsScalaIterable instead", "2.9.0") - def asScalaIterable[A](i : jl.Iterable[A]): Iterable[A] = iterableAsScalaIterable[A](i) - - @deprecated("use collectionAsScalaIterable instead", "2.9.0") - def asScalaIterable[A](i : ju.Collection[A]): Iterable[A] = collectionAsScalaIterable[A](i) - - @deprecated("use mapAsScalaMap instead", "2.9.0") - def asScalaMap[A, B](m: ju.Map[A, B]): mutable.Map[A, B] = mapAsScalaMap[A, B](m) - - @deprecated("use propertiesAsScalaMap instead", "2.9.0") - def asScalaMap(p: ju.Properties): mutable.Map[String, String] = propertiesAsScalaMap(p) -} - - diff --git a/scalalib/overrides-2.10/scala/collection/immutable/NumericRange.scala b/scalalib/overrides-2.10/scala/collection/immutable/NumericRange.scala deleted file mode 100644 index 95abce3fae..0000000000 --- a/scalalib/overrides-2.10/scala/collection/immutable/NumericRange.scala +++ /dev/null @@ -1,290 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2006-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - -package scala.collection -package immutable - -import mutable.{ Builder, ListBuffer } -import generic._ - -/** `NumericRange` is a more generic version of the - * `Range` class which works with arbitrary types. - * It must be supplied with an `Integral` implementation of the - * range type. - * - * Factories for likely types include `Range.BigInt`, `Range.Long`, - * and `Range.BigDecimal`. `Range.Int` exists for completeness, but - * the `Int`-based `scala.Range` should be more performant. - * - * {{{ - * val r1 = new Range(0, 100, 1) - * val veryBig = Int.MaxValue.toLong + 1 - * val r2 = Range.Long(veryBig, veryBig + 100, 1) - * assert(r1 sameElements r2.map(_ - veryBig)) - * }}} - * - * TODO: Now the specialization exists there is no clear reason to have - * separate classes for Range/NumericRange. Investigate and consolidate. - * - * @author Paul Phillips - * @version 2.8 - * @define Coll `NumericRange` - * @define coll numeric range - * @define mayNotTerminateInf - * @define willNotTerminateInf - */ -abstract class NumericRange[T] - (val start: T, val end: T, val step: T, val isInclusive: Boolean) - (implicit num: Integral[T]) -extends AbstractSeq[T] with IndexedSeq[T] with Serializable { - /** Note that NumericRange must be invariant so that constructs - * such as "1L to 10 by 5" do not infer the range type as AnyVal. - */ - import num._ - - // See comment in Range for why this must be lazy. - private lazy val numRangeElements: Int = - NumericRange.count(start, end, step, isInclusive) - - override def length = numRangeElements - override def isEmpty = length == 0 - override lazy val last: T = - if (length == 0) Nil.last - else locationAfterN(length - 1) - - /** Create a new range with the start and end values of this range and - * a new `step`. - */ - def by(newStep: T): NumericRange[T] = copy(start, end, newStep) - - /** Create a copy of this range. - */ - def copy(start: T, end: T, step: T): NumericRange[T] - - override def foreach[U](f: T => U) { - var count = 0 - var current = start - while (count < length) { - f(current) - current += step - count += 1 - } - } - - // TODO: these private methods are straight copies from Range, duplicated - // to guard against any (most likely illusory) performance drop. They should - // be eliminated one way or another. - - // Counts how many elements from the start meet the given test. - private def skipCount(p: T => Boolean): Int = { - var current = start - var counted = 0 - - while (counted < length && p(current)) { - counted += 1 - current += step - } - counted - } - // Tests whether a number is within the endpoints, without testing - // whether it is a member of the sequence (i.e. when step > 1.) - private def isWithinBoundaries(elem: T) = !isEmpty && ( - (step > zero && start <= elem && elem <= last ) || - (step < zero && last <= elem && elem <= start) - ) - // Methods like apply throw exceptions on invalid n, but methods like take/drop - // are forgiving: therefore the checks are with the methods. - private def locationAfterN(n: Int): T = start + (step * fromInt(n)) - - // When one drops everything. Can't ever have unchecked operations - // like "end + 1" or "end - 1" because ranges involving Int.{ MinValue, MaxValue } - // will overflow. This creates an exclusive range where start == end - // based on the given value. - private def newEmptyRange(value: T) = NumericRange(value, value, step) - - final override def take(n: Int): NumericRange[T] = ( - if (n <= 0 || length == 0) newEmptyRange(start) - else if (n >= length) this - else new NumericRange.Inclusive(start, locationAfterN(n - 1), step) - ) - - final override def drop(n: Int): NumericRange[T] = ( - if (n <= 0 || length == 0) this - else if (n >= length) newEmptyRange(end) - else copy(locationAfterN(n), end, step) - ) - - def apply(idx: Int): T = { - if (idx < 0 || idx >= length) throw new IndexOutOfBoundsException(idx.toString) - else locationAfterN(idx) - } - - import NumericRange.defaultOrdering - - override def min[T1 >: T](implicit ord: Ordering[T1]): T = - // We can take the fast path: - // - If the Integral of this NumericRange is also the requested Ordering - // (Integral <: Ordering). This can happen for custom Integral types. - // - The Ordering is the default Ordering of a well-known Integral type. - if ((ord eq num) || defaultOrdering.get(num).exists(ord eq _)) { - if (num.signum(step) > 0) start - else last - } else super.min(ord) - - override def max[T1 >: T](implicit ord: Ordering[T1]): T = - // See comment for fast path in min(). - if ((ord eq num) || defaultOrdering.get(num).exists(ord eq _)) { - if (num.signum(step) > 0) last - else start - } else super.max(ord) - - // Motivated by the desire for Double ranges with BigDecimal precision, - // we need some way to map a Range and get another Range. This can't be - // done in any fully general way because Ranges are not arbitrary - // sequences but step-valued, so we have a custom method only we can call - // which we promise to use responsibly. - // - // The point of it all is that - // - // 0.0 to 1.0 by 0.1 - // - // should result in - // - // NumericRange[Double](0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0) - // - // and not - // - // NumericRange[Double](0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9) - // - // or perhaps more importantly, - // - // (0.1 to 0.3 by 0.1 contains 0.3) == true - // - private[immutable] def mapRange[A](fm: T => A)(implicit unum: Integral[A]): NumericRange[A] = { - val self = this - - // XXX This may be incomplete. - new NumericRange[A](fm(start), fm(end), fm(step), isInclusive) { - def copy(start: A, end: A, step: A): NumericRange[A] = - if (isInclusive) NumericRange.inclusive(start, end, step) - else NumericRange(start, end, step) - - private lazy val underlyingRange: NumericRange[T] = self - override def foreach[U](f: A => U) { underlyingRange foreach (x => f(fm(x))) } - override def isEmpty = underlyingRange.isEmpty - override def apply(idx: Int): A = fm(underlyingRange(idx)) - override def containsTyped(el: A) = underlyingRange exists (x => fm(x) == el) - } - } - - // a well-typed contains method. - def containsTyped(x: T): Boolean = - isWithinBoundaries(x) && (((x - start) % step) == zero) - - override def contains(x: Any): Boolean = - try containsTyped(x.asInstanceOf[T]) - catch { case _: ClassCastException => false } - - final override def sum[B >: T](implicit num: Numeric[B]): B = { - import num.Ops - if (isEmpty) this.num fromInt 0 - else if (numRangeElements == 1) head - else ((this.num fromInt numRangeElements) * (head + last) / (this.num fromInt 2)) - } - - override lazy val hashCode = super.hashCode() - override def equals(other: Any) = other match { - case x: NumericRange[_] => - (x canEqual this) && (length == x.length) && ( - (length == 0) || // all empty sequences are equal - (start == x.start && last == x.last) // same length and same endpoints implies equality - ) - case _ => - super.equals(other) - } - - override def toString() = { - val endStr = if (length > Range.MAX_PRINT) ", ... )" else ")" - take(Range.MAX_PRINT).mkString("NumericRange(", ", ", endStr) - } -} - -/** A companion object for numeric ranges. - */ -object NumericRange { - - /** Calculates the number of elements in a range given start, end, step, and - * whether or not it is inclusive. Throws an exception if step == 0 or - * the number of elements exceeds the maximum Int. - */ - def count[T](start: T, end: T, step: T, isInclusive: Boolean)(implicit num: Integral[T]): Int = { - val zero = num.zero - val upward = num.lt(start, end) - val posStep = num.gt(step, zero) - - if (step == zero) throw new IllegalArgumentException("step cannot be 0.") - else if (start == end) if (isInclusive) 1 else 0 - else if (upward != posStep) 0 - else { - val diff = num.minus(end, start) - val jumps = num.toLong(num.quot(diff, step)) - val remainder = num.rem(diff, step) - val longCount = jumps + ( - if (!isInclusive && zero == remainder) 0 else 1 - ) - - /** The edge cases keep coming. Since e.g. - * Long.MaxValue + 1 == Long.MinValue - * we do some more improbable seeming checks lest - * overflow turn up as an empty range. - */ - // The second condition contradicts an empty result. - val isOverflow = longCount == 0 && num.lt(num.plus(start, step), end) == upward - - if (longCount > scala.Int.MaxValue || longCount < 0L || isOverflow) { - val word = if (isInclusive) "to" else "until" - val descr = List(start, word, end, "by", step) mkString " " - - throw new IllegalArgumentException(descr + ": seqs cannot contain more than Int.MaxValue elements.") - } - longCount.toInt - } - } - - class Inclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]) - extends NumericRange(start, end, step, true) { - def copy(start: T, end: T, step: T): Inclusive[T] = - NumericRange.inclusive(start, end, step) - - def exclusive: Exclusive[T] = NumericRange(start, end, step) - } - - class Exclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]) - extends NumericRange(start, end, step, false) { - def copy(start: T, end: T, step: T): Exclusive[T] = - NumericRange(start, end, step) - - def inclusive: Inclusive[T] = NumericRange.inclusive(start, end, step) - } - - def apply[T](start: T, end: T, step: T)(implicit num: Integral[T]): Exclusive[T] = - new Exclusive(start, end, step) - def inclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]): Inclusive[T] = - new Inclusive(start, end, step) - - private[collection] val defaultOrdering = Map[Numeric[_], Ordering[_]]( - Numeric.IntIsIntegral -> Ordering.Int, - Numeric.ShortIsIntegral -> Ordering.Short, - Numeric.ByteIsIntegral -> Ordering.Byte, - Numeric.CharIsIntegral -> Ordering.Char, - Numeric.LongIsIntegral -> Ordering.Long - ) - -} - diff --git a/scalalib/overrides-2.10/scala/collection/immutable/Range.scala b/scalalib/overrides-2.10/scala/collection/immutable/Range.scala deleted file mode 100644 index 0aa509e3e2..0000000000 --- a/scalalib/overrides-2.10/scala/collection/immutable/Range.scala +++ /dev/null @@ -1,421 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2006-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - -package scala.collection.immutable - -import scala.collection.parallel.immutable.ParRange - -/** The `Range` class represents integer values in range - * ''[start;end)'' with non-zero step value `step`. - * It's a special case of an indexed sequence. - * For example: - * - * {{{ - * val r1 = 0 until 10 - * val r2 = r1.start until r1.end by r1.step + 1 - * println(r2.length) // = 5 - * }}} - * - * @param start the start of this range. - * @param end the exclusive end of the range. - * @param step the step for the range. - * - * @author Martin Odersky - * @author Paul Phillips - * @version 2.8 - * @since 2.5 - * @see [[http://docs.scala-lang.org/overviews/collections/concrete-immutable-collection-classes.html#ranges "Scala's Collection Library overview"]] - * section on `Ranges` for more information. - * - * @define coll range - * @define mayNotTerminateInf - * @define willNotTerminateInf - * @define doesNotUseBuilders - * '''Note:''' this method does not use builders to construct a new range, - * and its complexity is O(1). - */ -@SerialVersionUID(7618862778670199309L) -@inline -class Range(val start: Int, val end: Int, val step: Int) -extends scala.collection.AbstractSeq[Int] - with IndexedSeq[Int] - with scala.collection.CustomParallelizable[Int, ParRange] - with Serializable -{ - override def par = new ParRange(this) - - private def gap = end.toLong - start.toLong - private def isExact = gap % step == 0 - private def hasStub = isInclusive || !isExact - private def longLength = gap / step + ( if (hasStub) 1 else 0 ) - - // Check cannot be evaluated eagerly because we have a pattern where - // ranges are constructed like: "x to y by z" The "x to y" piece - // should not trigger an exception. So the calculation is delayed, - // which means it will not fail fast for those cases where failing was - // correct. - override final val isEmpty = ( - (start > end && step > 0) - || (start < end && step < 0) - || (start == end && !isInclusive) - ) - final val numRangeElements: Int = { - if (step == 0) throw new IllegalArgumentException("step cannot be 0.") - else if (isEmpty) 0 - else { - val len = longLength - if (len > scala.Int.MaxValue) -1 - else len.toInt - } - } - final val lastElement = start + (numRangeElements - 1) * step - final val terminalElement = start + numRangeElements * step - - override def last = if (isEmpty) Nil.last else lastElement - - override def min[A1 >: Int](implicit ord: Ordering[A1]): Int = - if (ord eq Ordering.Int) { - if (step > 0) start - else last - } else super.min(ord) - - override def max[A1 >: Int](implicit ord: Ordering[A1]): Int = - if (ord eq Ordering.Int) { - if (step > 0) last - else start - } else super.max(ord) - - protected def copy(start: Int, end: Int, step: Int): Range = new Range(start, end, step) - - /** Create a new range with the `start` and `end` values of this range and - * a new `step`. - * - * @return a new range with a different step - */ - def by(step: Int): Range = copy(start, end, step) - - def isInclusive = false - - override def size = length - override def length = if (numRangeElements < 0) fail() else numRangeElements - - private def fail() = Range.fail(start, end, step, isInclusive) - private def validateMaxLength() { - if (numRangeElements < 0) - fail() - } - - def validateRangeBoundaries(f: Int => Any): Boolean = { - validateMaxLength() - - start != Int.MinValue || end != Int.MinValue || { - var count = 0 - var num = start - while (count < numRangeElements) { - f(num) - count += 1 - num += step - } - false - } - } - - final def apply(idx: Int): Int = { - validateMaxLength() - if (idx < 0 || idx >= numRangeElements) throw new IndexOutOfBoundsException(idx.toString) - else start + (step * idx) - } - - // Backported from scala 2.11 commit 00d3f103b3db5530bfbf6b565843d0938a3cef48 - @inline final override def foreach[@specialized(Unit) U](f: Int => U) { - // Implementation chosen on the basis of favorable microbenchmarks - // Note--initialization catches step == 0 so we don't need to here - if (!isEmpty) { - var i = start - while (true) { - f(i) - if (i == lastElement) return - i += step - } - } - } - - /** Creates a new range containing the first `n` elements of this range. - * - * $doesNotUseBuilders - * - * @param n the number of elements to take. - * @return a new range consisting of `n` first elements. - */ - final override def take(n: Int): Range = ( - if (n <= 0 || isEmpty) newEmptyRange(start) - else if (n >= numRangeElements) this - else new Range.Inclusive(start, locationAfterN(n - 1), step) - ) - - /** Creates a new range containing all the elements of this range except the first `n` elements. - * - * $doesNotUseBuilders - * - * @param n the number of elements to drop. - * @return a new range consisting of all the elements of this range except `n` first elements. - */ - final override def drop(n: Int): Range = ( - if (n <= 0 || isEmpty) this - else if (n >= numRangeElements) newEmptyRange(end) - else copy(locationAfterN(n), end, step) - ) - - /** Creates a new range containing all the elements of this range except the last one. - * - * $doesNotUseBuilders - * - * @return a new range consisting of all the elements of this range except the last one. - */ - final override def init: Range = { - if (isEmpty) - Nil.init - - dropRight(1) - } - - /** Creates a new range containing all the elements of this range except the first one. - * - * $doesNotUseBuilders - * - * @return a new range consisting of all the elements of this range except the first one. - */ - final override def tail: Range = { - if (isEmpty) - Nil.tail - - drop(1) - } - - // Counts how many elements from the start meet the given test. - private def skipCount(p: Int => Boolean): Int = { - var current = start - var counted = 0 - - while (counted < numRangeElements && p(current)) { - counted += 1 - current += step - } - counted - } - // Tests whether a number is within the endpoints, without testing - // whether it is a member of the sequence (i.e. when step > 1.) - private def isWithinBoundaries(elem: Int) = !isEmpty && ( - (step > 0 && start <= elem && elem <= last ) || - (step < 0 && last <= elem && elem <= start) - ) - // Methods like apply throw exceptions on invalid n, but methods like take/drop - // are forgiving: therefore the checks are with the methods. - private def locationAfterN(n: Int) = start + (step * n) - - // When one drops everything. Can't ever have unchecked operations - // like "end + 1" or "end - 1" because ranges involving Int.{ MinValue, MaxValue } - // will overflow. This creates an exclusive range where start == end - // based on the given value. - private def newEmptyRange(value: Int) = new Range(value, value, step) - - final override def takeWhile(p: Int => Boolean): Range = take(skipCount(p)) - final override def dropWhile(p: Int => Boolean): Range = drop(skipCount(p)) - final override def span(p: Int => Boolean): (Range, Range) = splitAt(skipCount(p)) - - /** Creates a pair of new ranges, first consisting of elements before `n`, and the second - * of elements after `n`. - * - * $doesNotUseBuilders - */ - final override def splitAt(n: Int) = (take(n), drop(n)) - - /** Creates a new range consisting of the `length - n` last elements of the range. - * - * $doesNotUseBuilders - */ - final override def takeRight(n: Int): Range = drop(numRangeElements - n) - - /** Creates a new range consisting of the initial `length - n` elements of the range. - * - * $doesNotUseBuilders - */ - final override def dropRight(n: Int): Range = take(numRangeElements - n) - - /** Returns the reverse of this range. - * - * $doesNotUseBuilders - */ - final override def reverse: Range = - if (isEmpty) this - else new Range.Inclusive(last, start, -step) - - /** Make range inclusive. - */ - def inclusive = - if (isInclusive) this - else new Range.Inclusive(start, end, step) - - final def contains(x: Int) = isWithinBoundaries(x) && ((x - start) % step == 0) - - final override def sum[B >: Int](implicit num: Numeric[B]): Int = { - if (isEmpty) 0 - else if (numRangeElements == 1) head - else (numRangeElements.toLong * (head + last) / 2).toInt - } - - override def toIterable = this - - override def toSeq = this - - override def equals(other: Any) = other match { - case x: Range => - (x canEqual this) && (length == x.length) && ( - isEmpty || // all empty sequences are equal - (start == x.start && last == x.last) // same length and same endpoints implies equality - ) - case _ => - super.equals(other) - } - /** Note: hashCode can't be overridden without breaking Seq's - * equals contract. - */ - - override def toString() = { - val endStr = if (numRangeElements > Range.MAX_PRINT) ", ... )" else ")" - take(Range.MAX_PRINT).mkString("Range(", ", ", endStr) - } -} - -/** A companion object for the `Range` class. - */ -object Range { - private[immutable] val MAX_PRINT = 512 // some arbitrary value - - private def description(start: Int, end: Int, step: Int, isInclusive: Boolean) = - start + (if (isInclusive) " to " else " until ") + end + " by " + step - - private def fail(start: Int, end: Int, step: Int, isInclusive: Boolean) = - throw new IllegalArgumentException(description(start, end, step, isInclusive) + - ": seqs cannot contain more than Int.MaxValue elements.") - - /** Counts the number of range elements. - * @pre step != 0 - * If the size of the range exceeds Int.MaxValue, the - * result will be negative. - */ - def count(start: Int, end: Int, step: Int, isInclusive: Boolean): Int = { - if (step == 0) - throw new IllegalArgumentException("step cannot be 0.") - - val isEmpty = ( - if (start == end) !isInclusive - else if (start < end) step < 0 - else step > 0 - ) - if (isEmpty) 0 - else { - // Counts with Longs so we can recognize too-large ranges. - val gap: Long = end.toLong - start.toLong - val jumps: Long = gap / step - // Whether the size of this range is one larger than the - // number of full-sized jumps. - val hasStub = isInclusive || (gap % step != 0) - val result: Long = jumps + ( if (hasStub) 1 else 0 ) - - if (result > scala.Int.MaxValue) -1 - else result.toInt - } - } - def count(start: Int, end: Int, step: Int): Int = - count(start, end, step, false) - - @inline - class Inclusive(start: Int, end: Int, step: Int) extends Range(start, end, step) { -// override def par = new ParRange(this) - override def isInclusive = true - override protected def copy(start: Int, end: Int, step: Int): Range = new Inclusive(start, end, step) - } - - /** Make a range from `start` until `end` (exclusive) with given step value. - * @note step != 0 - */ - def apply(start: Int, end: Int, step: Int): Range = new Range(start, end, step) - - /** Make a range from `start` until `end` (exclusive) with step value 1. - */ - def apply(start: Int, end: Int): Range = new Range(start, end, 1) - - /** Make an inclusive range from `start` to `end` with given step value. - * @note step != 0 - */ - def inclusive(start: Int, end: Int, step: Int): Range.Inclusive = new Inclusive(start, end, step) - - /** Make an inclusive range from `start` to `end` with step value 1. - */ - def inclusive(start: Int, end: Int): Range.Inclusive = new Inclusive(start, end, 1) - - // BigInt and Long are straightforward generic ranges. - object BigInt { - def apply(start: BigInt, end: BigInt, step: BigInt) = NumericRange(start, end, step) - def inclusive(start: BigInt, end: BigInt, step: BigInt) = NumericRange.inclusive(start, end, step) - } - - object Long { - def apply(start: Long, end: Long, step: Long) = NumericRange(start, end, step) - def inclusive(start: Long, end: Long, step: Long) = NumericRange.inclusive(start, end, step) - } - - // BigDecimal uses an alternative implementation of Numeric in which - // it pretends to be Integral[T] instead of Fractional[T]. See Numeric for - // details. The intention is for it to throw an exception anytime - // imprecision or surprises might result from anything, although this may - // not yet be fully implemented. - object BigDecimal { - implicit val bigDecAsIntegral = scala.math.Numeric.BigDecimalAsIfIntegral - - def apply(start: BigDecimal, end: BigDecimal, step: BigDecimal) = - NumericRange(start, end, step) - def inclusive(start: BigDecimal, end: BigDecimal, step: BigDecimal) = - NumericRange.inclusive(start, end, step) - } - - // Double works by using a BigDecimal under the hood for precise - // stepping, but mapping the sequence values back to doubles with - // .doubleValue. This constructs the BigDecimals by way of the - // String constructor (valueOf) instead of the Double one, which - // is necessary to keep 0.3d at 0.3 as opposed to - // 0.299999999999999988897769753748434595763683319091796875 or so. - object Double { - implicit val bigDecAsIntegral = scala.math.Numeric.BigDecimalAsIfIntegral - implicit val doubleAsIntegral = scala.math.Numeric.DoubleAsIfIntegral - def toBD(x: Double): BigDecimal = scala.math.BigDecimal valueOf x - - def apply(start: Double, end: Double, step: Double) = - BigDecimal(toBD(start), toBD(end), toBD(step)) mapRange (_.doubleValue) - - def inclusive(start: Double, end: Double, step: Double) = - BigDecimal.inclusive(toBD(start), toBD(end), toBD(step)) mapRange (_.doubleValue) - } - - // As there is no appealing default step size for not-really-integral ranges, - // we offer a partially constructed object. - class Partial[T, U](f: T => U) { - def by(x: T): U = f(x) - } - - // Illustrating genericity with Int Range, which should have the same behavior - // as the original Range class. However we leave the original Range - // indefinitely, for performance and because the compiler seems to bootstrap - // off it and won't do so with our parameterized version without modifications. - object Int { - def apply(start: Int, end: Int, step: Int) = NumericRange(start, end, step) - def inclusive(start: Int, end: Int, step: Int) = NumericRange.inclusive(start, end, step) - } -} diff --git a/scalalib/overrides-2.10/scala/collection/immutable/RedBlackTree.scala b/scalalib/overrides-2.10/scala/collection/immutable/RedBlackTree.scala deleted file mode 100644 index c31931da2f..0000000000 --- a/scalalib/overrides-2.10/scala/collection/immutable/RedBlackTree.scala +++ /dev/null @@ -1,496 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala -package collection -package immutable - -import scala.annotation.tailrec -import scala.annotation.meta.getter - -/** An object containing the RedBlack tree implementation used by for `TreeMaps` and `TreeSets`. - * - * Implementation note: since efficiency is important for data structures this implementation - * uses null to represent empty trees. This also means pattern matching cannot - * easily be used. The API represented by the RedBlackTree object tries to hide these - * optimizations behind a reasonably clean API. - * - * @since 2.10 - */ -private[immutable] -object RedBlackTree { - - def isEmpty(tree: Tree[_, _]): Boolean = tree eq null - - def contains[A](tree: Tree[A, _], x: A)(implicit ordering: Ordering[A]): Boolean = lookup(tree, x) ne null - def get[A, B](tree: Tree[A, B], x: A)(implicit ordering: Ordering[A]): Option[B] = lookup(tree, x) match { - case null => None - case tree => Some(tree.value) - } - - @tailrec - def lookup[A, B](tree: Tree[A, B], x: A)(implicit ordering: Ordering[A]): Tree[A, B] = if (tree eq null) null else { - val cmp = ordering.compare(x, tree.key) - if (cmp < 0) lookup(tree.left, x) - else if (cmp > 0) lookup(tree.right, x) - else tree - } - - def count(tree: Tree[_, _]) = if (tree eq null) 0 else tree.count - def update[A, B, B1 >: B](tree: Tree[A, B], k: A, v: B1, overwrite: Boolean)(implicit ordering: Ordering[A]): Tree[A, B1] = blacken(upd(tree, k, v, overwrite)) - def delete[A, B](tree: Tree[A, B], k: A)(implicit ordering: Ordering[A]): Tree[A, B] = blacken(del(tree, k)) - def rangeImpl[A: Ordering, B](tree: Tree[A, B], from: Option[A], until: Option[A]): Tree[A, B] = (from, until) match { - case (Some(from), Some(until)) => this.range(tree, from, until) - case (Some(from), None) => this.from(tree, from) - case (None, Some(until)) => this.until(tree, until) - case (None, None) => tree - } - def range[A: Ordering, B](tree: Tree[A, B], from: A, until: A): Tree[A, B] = blacken(doRange(tree, from, until)) - def from[A: Ordering, B](tree: Tree[A, B], from: A): Tree[A, B] = blacken(doFrom(tree, from)) - def to[A: Ordering, B](tree: Tree[A, B], to: A): Tree[A, B] = blacken(doTo(tree, to)) - def until[A: Ordering, B](tree: Tree[A, B], key: A): Tree[A, B] = blacken(doUntil(tree, key)) - - def drop[A: Ordering, B](tree: Tree[A, B], n: Int): Tree[A, B] = blacken(doDrop(tree, n)) - def take[A: Ordering, B](tree: Tree[A, B], n: Int): Tree[A, B] = blacken(doTake(tree, n)) - def slice[A: Ordering, B](tree: Tree[A, B], from: Int, until: Int): Tree[A, B] = blacken(doSlice(tree, from, until)) - - def smallest[A, B](tree: Tree[A, B]): Tree[A, B] = { - if (tree eq null) throw new NoSuchElementException("empty map") - var result = tree - while (result.left ne null) result = result.left - result - } - def greatest[A, B](tree: Tree[A, B]): Tree[A, B] = { - if (tree eq null) throw new NoSuchElementException("empty map") - var result = tree - while (result.right ne null) result = result.right - result - } - - def foreach[A, B, U](tree: Tree[A, B], f: ((A, B)) => U): Unit = if (tree ne null) { - if (tree.left ne null) foreach(tree.left, f) - f((tree.key, tree.value)) - if (tree.right ne null) foreach(tree.right, f) - } - def foreachKey[A, U](tree: Tree[A, _], f: A => U): Unit = if (tree ne null) { - if (tree.left ne null) foreachKey(tree.left, f) - f(tree.key) - if (tree.right ne null) foreachKey(tree.right, f) - } - - def iterator[A, B](tree: Tree[A, B]): Iterator[(A, B)] = new EntriesIterator(tree) - def keysIterator[A, _](tree: Tree[A, _]): Iterator[A] = new KeysIterator(tree) - def valuesIterator[_, B](tree: Tree[_, B]): Iterator[B] = new ValuesIterator(tree) - - @tailrec - def nth[A, B](tree: Tree[A, B], n: Int): Tree[A, B] = { - val count = this.count(tree.left) - if (n < count) nth(tree.left, n) - else if (n > count) nth(tree.right, n - count - 1) - else tree - } - - def isBlack(tree: Tree[_, _]) = (tree eq null) || isBlackTree(tree) - - private[this] def isRedTree(tree: Tree[_, _]) = tree.isInstanceOf[RedTree[_, _]] - private[this] def isBlackTree(tree: Tree[_, _]) = tree.isInstanceOf[BlackTree[_, _]] - - private[this] def blacken[A, B](t: Tree[A, B]): Tree[A, B] = if (t eq null) null else t.black - - private[this] def mkTree[A, B](isBlack: Boolean, k: A, v: B, l: Tree[A, B], r: Tree[A, B]) = - if (isBlack) BlackTree(k, v, l, r) else RedTree(k, v, l, r) - - private[this] def balanceLeft[A, B, B1 >: B](isBlack: Boolean, z: A, zv: B, l: Tree[A, B1], d: Tree[A, B1]): Tree[A, B1] = { - if (isRedTree(l) && isRedTree(l.left)) - RedTree(l.key, l.value, BlackTree(l.left.key, l.left.value, l.left.left, l.left.right), BlackTree(z, zv, l.right, d)) - else if (isRedTree(l) && isRedTree(l.right)) - RedTree(l.right.key, l.right.value, BlackTree(l.key, l.value, l.left, l.right.left), BlackTree(z, zv, l.right.right, d)) - else - mkTree(isBlack, z, zv, l, d) - } - private[this] def balanceRight[A, B, B1 >: B](isBlack: Boolean, x: A, xv: B, a: Tree[A, B1], r: Tree[A, B1]): Tree[A, B1] = { - if (isRedTree(r) && isRedTree(r.left)) - RedTree(r.left.key, r.left.value, BlackTree(x, xv, a, r.left.left), BlackTree(r.key, r.value, r.left.right, r.right)) - else if (isRedTree(r) && isRedTree(r.right)) - RedTree(r.key, r.value, BlackTree(x, xv, a, r.left), BlackTree(r.right.key, r.right.value, r.right.left, r.right.right)) - else - mkTree(isBlack, x, xv, a, r) - } - private[this] def upd[A, B, B1 >: B](tree: Tree[A, B], k: A, v: B1, overwrite: Boolean)(implicit ordering: Ordering[A]): Tree[A, B1] = if (tree eq null) { - RedTree(k, v, null, null) - } else { - val cmp = ordering.compare(k, tree.key) - if (cmp < 0) balanceLeft(isBlackTree(tree), tree.key, tree.value, upd(tree.left, k, v, overwrite), tree.right) - else if (cmp > 0) balanceRight(isBlackTree(tree), tree.key, tree.value, tree.left, upd(tree.right, k, v, overwrite)) - else if (overwrite || k != tree.key) mkTree(isBlackTree(tree), k, v, tree.left, tree.right) - else tree - } - private[this] def updNth[A, B, B1 >: B](tree: Tree[A, B], idx: Int, k: A, v: B1, overwrite: Boolean): Tree[A, B1] = if (tree eq null) { - RedTree(k, v, null, null) - } else { - val rank = count(tree.left) + 1 - if (idx < rank) balanceLeft(isBlackTree(tree), tree.key, tree.value, updNth(tree.left, idx, k, v, overwrite), tree.right) - else if (idx > rank) balanceRight(isBlackTree(tree), tree.key, tree.value, tree.left, updNth(tree.right, idx - rank, k, v, overwrite)) - else if (overwrite) mkTree(isBlackTree(tree), k, v, tree.left, tree.right) - else tree - } - - /* Based on Stefan Kahrs' Haskell version of Okasaki's Red&Black Trees - * http://www.cse.unsw.edu.au/~dons/data/RedBlackTree.html */ - private[this] def del[A, B](tree: Tree[A, B], k: A)(implicit ordering: Ordering[A]): Tree[A, B] = if (tree eq null) null else { - def balance(x: A, xv: B, tl: Tree[A, B], tr: Tree[A, B]) = if (isRedTree(tl)) { - if (isRedTree(tr)) { - RedTree(x, xv, tl.black, tr.black) - } else if (isRedTree(tl.left)) { - RedTree(tl.key, tl.value, tl.left.black, BlackTree(x, xv, tl.right, tr)) - } else if (isRedTree(tl.right)) { - RedTree(tl.right.key, tl.right.value, BlackTree(tl.key, tl.value, tl.left, tl.right.left), BlackTree(x, xv, tl.right.right, tr)) - } else { - BlackTree(x, xv, tl, tr) - } - } else if (isRedTree(tr)) { - if (isRedTree(tr.right)) { - RedTree(tr.key, tr.value, BlackTree(x, xv, tl, tr.left), tr.right.black) - } else if (isRedTree(tr.left)) { - RedTree(tr.left.key, tr.left.value, BlackTree(x, xv, tl, tr.left.left), BlackTree(tr.key, tr.value, tr.left.right, tr.right)) - } else { - BlackTree(x, xv, tl, tr) - } - } else { - BlackTree(x, xv, tl, tr) - } - def subl(t: Tree[A, B]) = - if (t.isInstanceOf[BlackTree[_, _]]) t.red - else throw new IllegalStateException("Defect: invariance violation; expected black, got "+t) - - def balLeft(x: A, xv: B, tl: Tree[A, B], tr: Tree[A, B]) = if (isRedTree(tl)) { - RedTree(x, xv, tl.black, tr) - } else if (isBlackTree(tr)) { - balance(x, xv, tl, tr.red) - } else if (isRedTree(tr) && isBlackTree(tr.left)) { - RedTree(tr.left.key, tr.left.value, BlackTree(x, xv, tl, tr.left.left), balance(tr.key, tr.value, tr.left.right, subl(tr.right))) - } else { - throw new IllegalStateException("Defect: invariance violation") - } - def balRight(x: A, xv: B, tl: Tree[A, B], tr: Tree[A, B]) = if (isRedTree(tr)) { - RedTree(x, xv, tl, tr.black) - } else if (isBlackTree(tl)) { - balance(x, xv, tl.red, tr) - } else if (isRedTree(tl) && isBlackTree(tl.right)) { - RedTree(tl.right.key, tl.right.value, balance(tl.key, tl.value, subl(tl.left), tl.right.left), BlackTree(x, xv, tl.right.right, tr)) - } else { - throw new IllegalStateException("Defect: invariance violation") - } - def delLeft = if (isBlackTree(tree.left)) balLeft(tree.key, tree.value, del(tree.left, k), tree.right) else RedTree(tree.key, tree.value, del(tree.left, k), tree.right) - def delRight = if (isBlackTree(tree.right)) balRight(tree.key, tree.value, tree.left, del(tree.right, k)) else RedTree(tree.key, tree.value, tree.left, del(tree.right, k)) - def append(tl: Tree[A, B], tr: Tree[A, B]): Tree[A, B] = if (tl eq null) { - tr - } else if (tr eq null) { - tl - } else if (isRedTree(tl) && isRedTree(tr)) { - val bc = append(tl.right, tr.left) - if (isRedTree(bc)) { - RedTree(bc.key, bc.value, RedTree(tl.key, tl.value, tl.left, bc.left), RedTree(tr.key, tr.value, bc.right, tr.right)) - } else { - RedTree(tl.key, tl.value, tl.left, RedTree(tr.key, tr.value, bc, tr.right)) - } - } else if (isBlackTree(tl) && isBlackTree(tr)) { - val bc = append(tl.right, tr.left) - if (isRedTree(bc)) { - RedTree(bc.key, bc.value, BlackTree(tl.key, tl.value, tl.left, bc.left), BlackTree(tr.key, tr.value, bc.right, tr.right)) - } else { - balLeft(tl.key, tl.value, tl.left, BlackTree(tr.key, tr.value, bc, tr.right)) - } - } else if (isRedTree(tr)) { - RedTree(tr.key, tr.value, append(tl, tr.left), tr.right) - } else if (isRedTree(tl)) { - RedTree(tl.key, tl.value, tl.left, append(tl.right, tr)) - } else { - throw new IllegalStateException("unmatched tree on append: " + tl + ", " + tr) - } - - val cmp = ordering.compare(k, tree.key) - if (cmp < 0) delLeft - else if (cmp > 0) delRight - else append(tree.left, tree.right) - } - - private[this] def doFrom[A, B](tree: Tree[A, B], from: A)(implicit ordering: Ordering[A]): Tree[A, B] = { - if (tree eq null) return null - if (ordering.lt(tree.key, from)) return doFrom(tree.right, from) - val newLeft = doFrom(tree.left, from) - if (newLeft eq tree.left) tree - else if (newLeft eq null) upd(tree.right, tree.key, tree.value, false) - else rebalance(tree, newLeft, tree.right) - } - private[this] def doTo[A, B](tree: Tree[A, B], to: A)(implicit ordering: Ordering[A]): Tree[A, B] = { - if (tree eq null) return null - if (ordering.lt(to, tree.key)) return doTo(tree.left, to) - val newRight = doTo(tree.right, to) - if (newRight eq tree.right) tree - else if (newRight eq null) upd(tree.left, tree.key, tree.value, false) - else rebalance(tree, tree.left, newRight) - } - private[this] def doUntil[A, B](tree: Tree[A, B], until: A)(implicit ordering: Ordering[A]): Tree[A, B] = { - if (tree eq null) return null - if (ordering.lteq(until, tree.key)) return doUntil(tree.left, until) - val newRight = doUntil(tree.right, until) - if (newRight eq tree.right) tree - else if (newRight eq null) upd(tree.left, tree.key, tree.value, false) - else rebalance(tree, tree.left, newRight) - } - private[this] def doRange[A, B](tree: Tree[A, B], from: A, until: A)(implicit ordering: Ordering[A]): Tree[A, B] = { - if (tree eq null) return null - if (ordering.lt(tree.key, from)) return doRange(tree.right, from, until); - if (ordering.lteq(until, tree.key)) return doRange(tree.left, from, until); - val newLeft = doFrom(tree.left, from) - val newRight = doUntil(tree.right, until) - if ((newLeft eq tree.left) && (newRight eq tree.right)) tree - else if (newLeft eq null) upd(newRight, tree.key, tree.value, false); - else if (newRight eq null) upd(newLeft, tree.key, tree.value, false); - else rebalance(tree, newLeft, newRight) - } - - private[this] def doDrop[A, B](tree: Tree[A, B], n: Int): Tree[A, B] = { - if (n <= 0) return tree - if (n >= this.count(tree)) return null - val count = this.count(tree.left) - if (n > count) return doDrop(tree.right, n - count - 1) - val newLeft = doDrop(tree.left, n) - if (newLeft eq tree.left) tree - else if (newLeft eq null) updNth(tree.right, n - count - 1, tree.key, tree.value, false) - else rebalance(tree, newLeft, tree.right) - } - private[this] def doTake[A, B](tree: Tree[A, B], n: Int): Tree[A, B] = { - if (n <= 0) return null - if (n >= this.count(tree)) return tree - val count = this.count(tree.left) - if (n <= count) return doTake(tree.left, n) - val newRight = doTake(tree.right, n - count - 1) - if (newRight eq tree.right) tree - else if (newRight eq null) updNth(tree.left, n, tree.key, tree.value, false) - else rebalance(tree, tree.left, newRight) - } - private[this] def doSlice[A, B](tree: Tree[A, B], from: Int, until: Int): Tree[A, B] = { - if (tree eq null) return null - val count = this.count(tree.left) - if (from > count) return doSlice(tree.right, from - count - 1, until - count - 1) - if (until <= count) return doSlice(tree.left, from, until) - val newLeft = doDrop(tree.left, from) - val newRight = doTake(tree.right, until - count - 1) - if ((newLeft eq tree.left) && (newRight eq tree.right)) tree - else if (newLeft eq null) updNth(newRight, from - count - 1, tree.key, tree.value, false) - else if (newRight eq null) updNth(newLeft, until, tree.key, tree.value, false) - else rebalance(tree, newLeft, newRight) - } - - // The zipper returned might have been traversed left-most (always the left child) - // or right-most (always the right child). Left trees are traversed right-most, - // and right trees are traversed leftmost. - - // Returns the zipper for the side with deepest black nodes depth, a flag - // indicating whether the trees were unbalanced at all, and a flag indicating - // whether the zipper was traversed left-most or right-most. - - // If the trees were balanced, returns an empty zipper - private[this] def compareDepth[A, B](left: Tree[A, B], right: Tree[A, B]): (List[Tree[A, B]], Boolean, Boolean, Int) = { - // Once a side is found to be deeper, unzip it to the bottom - def unzip(zipper: List[Tree[A, B]], leftMost: Boolean): List[Tree[A, B]] = { - val next = if (leftMost) zipper.head.left else zipper.head.right - next match { - case null => zipper - case node => unzip(node :: zipper, leftMost) - } - } - - // Unzip left tree on the rightmost side and right tree on the leftmost side until one is - // found to be deeper, or the bottom is reached - def unzipBoth(left: Tree[A, B], - right: Tree[A, B], - leftZipper: List[Tree[A, B]], - rightZipper: List[Tree[A, B]], - smallerDepth: Int): (List[Tree[A, B]], Boolean, Boolean, Int) = { - if (isBlackTree(left) && isBlackTree(right)) { - unzipBoth(left.right, right.left, left :: leftZipper, right :: rightZipper, smallerDepth + 1) - } else if (isRedTree(left) && isRedTree(right)) { - unzipBoth(left.right, right.left, left :: leftZipper, right :: rightZipper, smallerDepth) - } else if (isRedTree(right)) { - unzipBoth(left, right.left, leftZipper, right :: rightZipper, smallerDepth) - } else if (isRedTree(left)) { - unzipBoth(left.right, right, left :: leftZipper, rightZipper, smallerDepth) - } else if ((left eq null) && (right eq null)) { - (Nil, true, false, smallerDepth) - } else if ((left eq null) && isBlackTree(right)) { - val leftMost = true - (unzip(right :: rightZipper, leftMost), false, leftMost, smallerDepth) - } else if (isBlackTree(left) && (right eq null)) { - val leftMost = false - (unzip(left :: leftZipper, leftMost), false, leftMost, smallerDepth) - } else { - throw new IllegalStateException("unmatched trees in unzip: " + left + ", " + right) - } - } - unzipBoth(left, right, Nil, Nil, 0) - } - - private[this] def rebalance[A, B](tree: Tree[A, B], newLeft: Tree[A, B], newRight: Tree[A, B]) = { - // This is like drop(n-1), but only counting black nodes - def findDepth(zipper: List[Tree[A, B]], depth: Int): List[Tree[A, B]] = zipper match { - case head :: tail if isBlackTree(head) => - if (depth == 1) zipper else findDepth(tail, depth - 1) - case _ :: tail => findDepth(tail, depth) - case Nil => throw new IllegalStateException("Defect: unexpected empty zipper while computing range") - } - - // Blackening the smaller tree avoids balancing problems on union; - // this can't be done later, though, or it would change the result of compareDepth - val blkNewLeft = blacken(newLeft) - val blkNewRight = blacken(newRight) - val (zipper, levelled, leftMost, smallerDepth) = compareDepth(blkNewLeft, blkNewRight) - - if (levelled) { - BlackTree(tree.key, tree.value, blkNewLeft, blkNewRight) - } else { - val zipFrom = findDepth(zipper, smallerDepth) - val union = if (leftMost) { - RedTree(tree.key, tree.value, blkNewLeft, zipFrom.head) - } else { - RedTree(tree.key, tree.value, zipFrom.head, blkNewRight) - } - val zippedTree = zipFrom.tail.foldLeft(union: Tree[A, B]) { (tree, node) => - if (leftMost) - balanceLeft(isBlackTree(node), node.key, node.value, tree, node.right) - else - balanceRight(isBlackTree(node), node.key, node.value, node.left, tree) - } - zippedTree - } - } - - /* - * Forcing direct fields access using the @inline annotation helps speed up - * various operations (especially smallest/greatest and update/delete). - * - * Unfortunately the direct field access is not guaranteed to work (but - * works on the current implementation of the Scala compiler). - * - * An alternative is to implement the these classes using plain old Java code... - */ - sealed abstract class Tree[A, +B]( - @(inline @getter) final val key: A, - @(inline @getter) final val value: B, - @(inline @getter) final val left: Tree[A, B], - @(inline @getter) final val right: Tree[A, B]) - extends Serializable { - @(inline @getter) final val count: Int = 1 + RedBlackTree.count(left) + RedBlackTree.count(right) - def black: Tree[A, B] - def red: Tree[A, B] - } - final class RedTree[A, +B](key: A, - value: B, - left: Tree[A, B], - right: Tree[A, B]) extends Tree[A, B](key, value, left, right) { - override def black: Tree[A, B] = BlackTree(key, value, left, right) - override def red: Tree[A, B] = this - override def toString: String = "RedTree(" + key + ", " + value + ", " + left + ", " + right + ")" - } - final class BlackTree[A, +B](key: A, - value: B, - left: Tree[A, B], - right: Tree[A, B]) extends Tree[A, B](key, value, left, right) { - override def black: Tree[A, B] = this - override def red: Tree[A, B] = RedTree(key, value, left, right) - override def toString: String = "BlackTree(" + key + ", " + value + ", " + left + ", " + right + ")" - } - - object RedTree { - @inline def apply[A, B](key: A, value: B, left: Tree[A, B], right: Tree[A, B]) = new RedTree(key, value, left, right) - def unapply[A, B](t: RedTree[A, B]) = Some((t.key, t.value, t.left, t.right)) - } - object BlackTree { - @inline def apply[A, B](key: A, value: B, left: Tree[A, B], right: Tree[A, B]) = new BlackTree(key, value, left, right) - def unapply[A, B](t: BlackTree[A, B]) = Some((t.key, t.value, t.left, t.right)) - } - - private[this] abstract class TreeIterator[A, B, R](tree: Tree[A, B]) extends Iterator[R] { - protected[this] def nextResult(tree: Tree[A, B]): R - - override def hasNext: Boolean = next ne null - - override def next: R = next match { - case null => - throw new NoSuchElementException("next on empty iterator") - case tree => - next = findNext(tree.right) - nextResult(tree) - } - - @tailrec - private[this] def findNext(tree: Tree[A, B]): Tree[A, B] = { - if (tree eq null) popPath() - else if (tree.left eq null) tree - else { - pushPath(tree) - findNext(tree.left) - } - } - - private[this] def pushPath(tree: Tree[A, B]) { - try { - path(index) = tree - index += 1 - } catch { - case _: ArrayIndexOutOfBoundsException => - /* - * Either the tree became unbalanced or we calculated the maximum height incorrectly. - * To avoid crashing the iterator we expand the path array. Obviously this should never - * happen... - * - * An exception handler is used instead of an if-condition to optimize the normal path. - * This makes a large difference in iteration speed! - */ - assert(index >= path.length) - path :+= null - pushPath(tree) - } - } - private[this] def popPath(): Tree[A, B] = if (index == 0) null else { - index -= 1 - path(index) - } - - private[this] var path = if (tree eq null) null else { - /* - * According to "Ralf Hinze. Constructing red-black trees" [http://www.cs.ox.ac.uk/ralf.hinze/publications/#P5] - * the maximum height of a red-black tree is 2*log_2(n + 2) - 2. - * - * According to {@see Integer#numberOfLeadingZeros} ceil(log_2(n)) = (32 - Integer.numberOfLeadingZeros(n - 1)) - * - * We also don't store the deepest nodes in the path so the maximum path length is further reduced by one. - */ - val maximumHeight = 2 * (32 - Integer.numberOfLeadingZeros(tree.count + 2 - 1)) - 2 - new Array[Tree[A, B]](maximumHeight) - } - private[this] var index = 0 - private[this] var next: Tree[A, B] = findNext(tree) - } - - private[this] class EntriesIterator[A, B](tree: Tree[A, B]) extends TreeIterator[A, B, (A, B)](tree) { - override def nextResult(tree: Tree[A, B]) = (tree.key, tree.value) - } - - private[this] class KeysIterator[A, B](tree: Tree[A, B]) extends TreeIterator[A, B, A](tree) { - override def nextResult(tree: Tree[A, B]) = tree.key - } - - private[this] class ValuesIterator[A, B](tree: Tree[A, B]) extends TreeIterator[A, B, B](tree) { - override def nextResult(tree: Tree[A, B]) = tree.value - } -} diff --git a/scalalib/overrides-2.10/scala/collection/mutable/ArrayBuilder.scala b/scalalib/overrides-2.10/scala/collection/mutable/ArrayBuilder.scala deleted file mode 100644 index 0fc80a54ac..0000000000 --- a/scalalib/overrides-2.10/scala/collection/mutable/ArrayBuilder.scala +++ /dev/null @@ -1,765 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala -package collection -package mutable - -import scala.reflect.ClassTag -import scala.runtime.BoxedUnit - -import scala.scalajs.js - -/** A builder class for arrays. - * - * @since 2.8 - * - * @tparam T the type of the elements for the builder. - */ -abstract class ArrayBuilder[T] extends Builder[T, Array[T]] with Serializable - -/** A companion object for array builders. - * - * @since 2.8 - */ -object ArrayBuilder { - - /** Creates a new arraybuilder of type `T`. - * - * @tparam T type of the elements for the array builder, with a `ClassTag` context bound. - * @return a new empty array builder. - */ - @inline - def make[T: ClassTag](): ArrayBuilder[T] = - new ArrayBuilder.generic[T](implicitly[ClassTag[T]].runtimeClass) - - /** A generic ArrayBuilder optimized for Scala.js. - * - * @tparam T type of elements for the array builder. - * @param elementClass runtime class of the elements in the array. - */ - @inline - private final class generic[T](elementClass: Class[_]) extends ArrayBuilder[T] { - - private val isCharArrayBuilder = classOf[Char] == elementClass - private val elems: js.Array[Any] = js.Array() - - def +=(elem: T): this.type = { - val unboxedElem = - if (isCharArrayBuilder) elem.asInstanceOf[Char].toInt - else if (elem == null) zeroOf(elementClass) - else elem - elems.push(unboxedElem) - this - } - - def clear(): Unit = - elems.length = 0 - - def result(): Array[T] = { - val elemRuntimeClass = - if (classOf[Unit] == elementClass) classOf[BoxedUnit] - else if (classOf[Null] == elementClass || classOf[Nothing] == elementClass) classOf[Object] - else elementClass - genericArrayBuilderResult(elemRuntimeClass, elems) - } - - override def toString(): String = "ArrayBuilder.generic" - } - - // Intrinsic - private def zeroOf(runtimeClass: Class[_]): Any = runtimeClass match { - case java.lang.Byte.TYPE => 0.toByte - case java.lang.Short.TYPE => 0.toShort - case java.lang.Character.TYPE => 0 // yes, as an Int - case java.lang.Integer.TYPE => 0 - case java.lang.Long.TYPE => 0L - case java.lang.Float.TYPE => 0.0f - case java.lang.Double.TYPE => 0.0 - case java.lang.Boolean.TYPE => false - case java.lang.Void.TYPE => () - case _ => null - } - - // Intrinsic - private def genericArrayBuilderResult[T](runtimeClass: Class[_], - a: js.Array[Any]): Array[T] = { - val len = a.length - - if (classOf[Char] == runtimeClass) { - val result = new Array[Char](len) - var i = 0 - while (i != len) { - result(i) = a(i).asInstanceOf[Int].toChar - i += 1 - } - result.asInstanceOf[Array[T]] - } else { - val result: Array[T] = java.lang.reflect.Array.newInstance( - runtimeClass, len).asInstanceOf[Array[T]] - var i = 0 - while (i != len) { - result(i) = a(i).asInstanceOf[T] - i += 1 - } - result - } - } - - /** A class for array builders for arrays of reference types. - * - * @tparam T type of elements for the array builder, subtype of `AnyRef` with a `ClassTag` context bound. - */ - @deprecatedInheritance("ArrayBuilder.ofRef is an internal implementation not intended for subclassing.", "2.11.0") - class ofRef[T <: AnyRef : ClassTag] extends ArrayBuilder[T] { - - private var elems: Array[T] = _ - private var capacity: Int = 0 - private var size: Int = 0 - - private def mkArray(size: Int): Array[T] = { - val newelems = new Array[T](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) - newelems - } - - private def resize(size: Int) { - elems = mkArray(size) - capacity = size - } - - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: T): this.type = { - ensureSize(size + 1) - elems(size) = elem - size += 1 - this - } - - override def ++=(xs: TraversableOnce[T]): this.type = (xs.asInstanceOf[AnyRef]) match { - case xs: WrappedArray.ofRef[_] => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { - size = 0 - } - - def result() = { - if (capacity != 0 && capacity == size) elems - else mkArray(size) - } - - override def equals(other: Any): Boolean = other match { - case x: ofRef[_] => (size == x.size) && (elems == x.elems) - case _ => false - } - - override def toString = "ArrayBuilder.ofRef" - } - - /** A class for array builders for arrays of `byte`s. */ - @deprecatedInheritance("ArrayBuilder.ofByte is an internal implementation not intended for subclassing.", "2.11.0") - class ofByte extends ArrayBuilder[Byte] { - - private var elems: Array[Byte] = _ - private var capacity: Int = 0 - private var size: Int = 0 - - private def mkArray(size: Int): Array[Byte] = { - val newelems = new Array[Byte](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) - newelems - } - - private def resize(size: Int) { - elems = mkArray(size) - capacity = size - } - - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Byte): this.type = { - ensureSize(size + 1) - elems(size) = elem - size += 1 - this - } - - override def ++=(xs: TraversableOnce[Byte]): this.type = xs match { - case xs: WrappedArray.ofByte => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { - size = 0 - } - - def result() = { - if (capacity != 0 && capacity == size) elems - else mkArray(size) - } - - override def equals(other: Any): Boolean = other match { - case x: ofByte => (size == x.size) && (elems == x.elems) - case _ => false - } - - override def toString = "ArrayBuilder.ofByte" - } - - /** A class for array builders for arrays of `short`s. */ - @deprecatedInheritance("ArrayBuilder.ofShort is an internal implementation not intended for subclassing.", "2.11.0") - class ofShort extends ArrayBuilder[Short] { - - private var elems: Array[Short] = _ - private var capacity: Int = 0 - private var size: Int = 0 - - private def mkArray(size: Int): Array[Short] = { - val newelems = new Array[Short](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) - newelems - } - - private def resize(size: Int) { - elems = mkArray(size) - capacity = size - } - - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Short): this.type = { - ensureSize(size + 1) - elems(size) = elem - size += 1 - this - } - - override def ++=(xs: TraversableOnce[Short]): this.type = xs match { - case xs: WrappedArray.ofShort => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { - size = 0 - } - - def result() = { - if (capacity != 0 && capacity == size) elems - else mkArray(size) - } - - override def equals(other: Any): Boolean = other match { - case x: ofShort => (size == x.size) && (elems == x.elems) - case _ => false - } - - override def toString = "ArrayBuilder.ofShort" - } - - /** A class for array builders for arrays of `char`s. */ - @deprecatedInheritance("ArrayBuilder.ofChar is an internal implementation not intended for subclassing.", "2.11.0") - class ofChar extends ArrayBuilder[Char] { - - private var elems: Array[Char] = _ - private var capacity: Int = 0 - private var size: Int = 0 - - private def mkArray(size: Int): Array[Char] = { - val newelems = new Array[Char](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) - newelems - } - - private def resize(size: Int) { - elems = mkArray(size) - capacity = size - } - - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Char): this.type = { - ensureSize(size + 1) - elems(size) = elem - size += 1 - this - } - - override def ++=(xs: TraversableOnce[Char]): this.type = xs match { - case xs: WrappedArray.ofChar => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { - size = 0 - } - - def result() = { - if (capacity != 0 && capacity == size) elems - else mkArray(size) - } - - override def equals(other: Any): Boolean = other match { - case x: ofChar => (size == x.size) && (elems == x.elems) - case _ => false - } - - override def toString = "ArrayBuilder.ofChar" - } - - /** A class for array builders for arrays of `int`s. */ - @deprecatedInheritance("ArrayBuilder.ofInt is an internal implementation not intended for subclassing.", "2.11.0") - class ofInt extends ArrayBuilder[Int] { - - private var elems: Array[Int] = _ - private var capacity: Int = 0 - private var size: Int = 0 - - private def mkArray(size: Int): Array[Int] = { - val newelems = new Array[Int](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) - newelems - } - - private def resize(size: Int) { - elems = mkArray(size) - capacity = size - } - - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Int): this.type = { - ensureSize(size + 1) - elems(size) = elem - size += 1 - this - } - - override def ++=(xs: TraversableOnce[Int]): this.type = xs match { - case xs: WrappedArray.ofInt => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { - size = 0 - } - - def result() = { - if (capacity != 0 && capacity == size) elems - else mkArray(size) - } - - override def equals(other: Any): Boolean = other match { - case x: ofInt => (size == x.size) && (elems == x.elems) - case _ => false - } - - override def toString = "ArrayBuilder.ofInt" - } - - /** A class for array builders for arrays of `long`s. */ - @deprecatedInheritance("ArrayBuilder.ofLong is an internal implementation not intended for subclassing.", "2.11.0") - class ofLong extends ArrayBuilder[Long] { - - private var elems: Array[Long] = _ - private var capacity: Int = 0 - private var size: Int = 0 - - private def mkArray(size: Int): Array[Long] = { - val newelems = new Array[Long](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) - newelems - } - - private def resize(size: Int) { - elems = mkArray(size) - capacity = size - } - - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Long): this.type = { - ensureSize(size + 1) - elems(size) = elem - size += 1 - this - } - - override def ++=(xs: TraversableOnce[Long]): this.type = xs match { - case xs: WrappedArray.ofLong => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { - size = 0 - } - - def result() = { - if (capacity != 0 && capacity == size) elems - else mkArray(size) - } - - override def equals(other: Any): Boolean = other match { - case x: ofLong => (size == x.size) && (elems == x.elems) - case _ => false - } - - override def toString = "ArrayBuilder.ofLong" - } - - /** A class for array builders for arrays of `float`s. */ - @deprecatedInheritance("ArrayBuilder.ofFloat is an internal implementation not intended for subclassing.", "2.11.0") - class ofFloat extends ArrayBuilder[Float] { - - private var elems: Array[Float] = _ - private var capacity: Int = 0 - private var size: Int = 0 - - private def mkArray(size: Int): Array[Float] = { - val newelems = new Array[Float](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) - newelems - } - - private def resize(size: Int) { - elems = mkArray(size) - capacity = size - } - - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Float): this.type = { - ensureSize(size + 1) - elems(size) = elem - size += 1 - this - } - - override def ++=(xs: TraversableOnce[Float]): this.type = xs match { - case xs: WrappedArray.ofFloat => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { - size = 0 - } - - def result() = { - if (capacity != 0 && capacity == size) elems - else mkArray(size) - } - - override def equals(other: Any): Boolean = other match { - case x: ofFloat => (size == x.size) && (elems == x.elems) - case _ => false - } - - override def toString = "ArrayBuilder.ofFloat" - } - - /** A class for array builders for arrays of `double`s. */ - @deprecatedInheritance("ArrayBuilder.ofDouble is an internal implementation not intended for subclassing.", "2.11.0") - class ofDouble extends ArrayBuilder[Double] { - - private var elems: Array[Double] = _ - private var capacity: Int = 0 - private var size: Int = 0 - - private def mkArray(size: Int): Array[Double] = { - val newelems = new Array[Double](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) - newelems - } - - private def resize(size: Int) { - elems = mkArray(size) - capacity = size - } - - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Double): this.type = { - ensureSize(size + 1) - elems(size) = elem - size += 1 - this - } - - override def ++=(xs: TraversableOnce[Double]): this.type = xs match { - case xs: WrappedArray.ofDouble => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { - size = 0 - } - - def result() = { - if (capacity != 0 && capacity == size) elems - else mkArray(size) - } - - override def equals(other: Any): Boolean = other match { - case x: ofDouble => (size == x.size) && (elems == x.elems) - case _ => false - } - - override def toString = "ArrayBuilder.ofDouble" - } - - /** A class for array builders for arrays of `boolean`s. */ - class ofBoolean extends ArrayBuilder[Boolean] { - - private var elems: Array[Boolean] = _ - private var capacity: Int = 0 - private var size: Int = 0 - - private def mkArray(size: Int): Array[Boolean] = { - val newelems = new Array[Boolean](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) - newelems - } - - private def resize(size: Int) { - elems = mkArray(size) - capacity = size - } - - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Boolean): this.type = { - ensureSize(size + 1) - elems(size) = elem - size += 1 - this - } - - override def ++=(xs: TraversableOnce[Boolean]): this.type = xs match { - case xs: WrappedArray.ofBoolean => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { - size = 0 - } - - def result() = { - if (capacity != 0 && capacity == size) elems - else mkArray(size) - } - - override def equals(other: Any): Boolean = other match { - case x: ofBoolean => (size == x.size) && (elems == x.elems) - case _ => false - } - - override def toString = "ArrayBuilder.ofBoolean" - } - - /** A class for array builders for arrays of `Unit` type. */ - @deprecatedInheritance("ArrayBuilder.ofUnit is an internal implementation not intended for subclassing.", "2.11.0") - class ofUnit extends ArrayBuilder[Unit] { - - private var elems: Array[Unit] = _ - private var capacity: Int = 0 - private var size: Int = 0 - - private def mkArray(size: Int): Array[Unit] = { - val newelems = new Array[Unit](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) - newelems - } - - private def resize(size: Int) { - elems = mkArray(size) - capacity = size - } - - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Unit): this.type = { - ensureSize(size + 1) - elems(size) = elem - size += 1 - this - } - - override def ++=(xs: TraversableOnce[Unit]): this.type = xs match { - case xs: WrappedArray.ofUnit => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { - size = 0 - } - - def result() = { - if (capacity != 0 && capacity == size) elems - else mkArray(size) - } - - override def equals(other: Any): Boolean = other match { - case x: ofUnit => (size == x.size) && (elems == x.elems) - case _ => false - } - - override def toString = "ArrayBuilder.ofUnit" - } -} diff --git a/scalalib/overrides-2.10/scala/collection/mutable/Buffer.scala b/scalalib/overrides-2.10/scala/collection/mutable/Buffer.scala deleted file mode 100644 index ec7763b577..0000000000 --- a/scalalib/overrides-2.10/scala/collection/mutable/Buffer.scala +++ /dev/null @@ -1,50 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.collection -package mutable - -import generic._ - -import scala.scalajs.js - -/** Buffers are used to create sequences of elements incrementally by - * appending, prepending, or inserting new elements. It is also - * possible to access and modify elements in a random access fashion - * via the index of the element in the current sequence. - * - * @author Matthias Zenger - * @author Martin Odersky - * @version 2.8 - * @since 1 - * - * @tparam A type of the elements contained in this buffer. - * - * @define Coll `Buffer` - * @define coll buffer - */ -trait Buffer[A] extends Seq[A] - with GenericTraversableTemplate[A, Buffer] - with BufferLike[A, Buffer[A]] - with scala.Cloneable { - override def companion: GenericCompanion[Buffer] = Buffer -} - -/** $factoryInfo - * @define coll buffer - * @define Coll `Buffer` - */ -object Buffer extends SeqFactory[Buffer] { - implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Buffer[A]] = ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]] - def newBuilder[A]: Builder[A, Buffer[A]] = new js.WrappedArray -} - -/** Explicit instantiation of the `Buffer` trait to reduce class file size in subclasses. */ -private[scala] abstract class AbstractBuffer[A] extends AbstractSeq[A] with Buffer[A] diff --git a/scalalib/overrides-2.10/scala/compat/Platform.scala b/scalalib/overrides-2.10/scala/compat/Platform.scala deleted file mode 100644 index 77bf7ded7e..0000000000 --- a/scalalib/overrides-2.10/scala/compat/Platform.scala +++ /dev/null @@ -1,133 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.compat - -import java.lang.System - -object Platform { - - /** Thrown when a stack overflow occurs because a method or function recurses too deeply. - * - * On the JVM, this is a type alias for `java.lang.StackOverflowError`, which itself extends `java.lang.Error`. - * The same rules apply to catching a `java.lang.Error` as for Java, that it indicates a serious problem that a reasonable application should not try and catch. - */ - type StackOverflowError = java.lang.StackOverflowError - - /** This is a type alias for `java.util.ConcurrentModificationException`, - * which may be thrown by methods that detect an invalid modification of an object. - * For example, many common collection types do not allow modifying a collection - * while it is being iterated over. - */ - type ConcurrentModificationException = java.util.ConcurrentModificationException - - /** Copies `length` elements of array `src` starting at position `srcPos` to the - * array `dest` starting at position `destPos`. If `src`==`dest`, the copying will - * behave as if the elements copied from `src` were first copied to a temporary - * array before being copied back into the array at the destination positions. - * - * @param src A non-null array as source for the copy. - * @param srcPos The starting index in the source array. - * @param dest A non-null array as destination for the copy. - * @param destPos The starting index in the destination array. - * @param length The number of elements to be copied. - * @throws java.lang.NullPointerException If either `src` or `dest` are `null`. - * @throws java.lang.ArrayStoreException If either `src` or `dest` are not of type - * [java.lang.Array]; or if the element type of `src` is not - * compatible with that of `dest`. - * @throws java.lang.IndexOutOfBoundsException If either srcPos` or `destPos` are - * outside of the bounds of their respective arrays; or if `length` - * is negative; or if there are less than `length` elements available - * after `srcPos` or `destPos` in `src` and `dest` respectively. - */ - @inline - def arraycopy(src: AnyRef, srcPos: Int, dest: AnyRef, destPos: Int, length: Int) { - System.arraycopy(src, srcPos, dest, destPos, length) - } - - /** Creates a new array of the specified type and given length. - * - * Note that if `elemClass` is a subclass of [[scala.AnyVal]] then the returned value is an Array of the corresponding java primitive type. - * For example, the following code `scala.compat.Platform.createArray(classOf[Int], 4)` returns an array of the java primitive type `int`. - * - * For a [[scala.AnyVal]] array, the values of the array are set to 0 for ''numeric value types'' ([[scala.Double]], [[scala.Float]], [[scala.Long]], [[scala.Int]], [[scala.Char]], - * [[scala.Short]], and [[scala.Byte]]), and `false` for [[scala.Boolean]]. Creation of an array of type [[scala.Unit]] is not possible. - * - * For subclasses of [[scala.AnyRef]], the values of the array are set to `null`. - * - * The caller must cast the returned value to the correct type. - * - * @example {{{ - * val a = scala.compat.Platform.createArray(classOf[Int], 4).asInstanceOf[Array[Int]] // returns Array[Int](0, 0, 0, 0) - * }}} - * - * @param elemClass the `Class` object of the component type of the array - * @param length the length of the new array. - * @return an array of the given component type as an `AnyRef`. - * @throws `java.lang.NullPointerException` If `elemClass` is `null`. - * @throws `java.lang.IllegalArgumentException` if componentType is [[scala.Unit]] or `java.lang.Void.TYPE` - * @throws `java.lang.NegativeArraySizeException` if the specified length is negative - */ - @inline - def createArray(elemClass: Class[_], length: Int): AnyRef = - java.lang.reflect.Array.newInstance(elemClass, length) - - /** Assigns the value of 0 to each element in the array. - * @param arr A non-null Array[Int]. - * @throws `java.lang.NullPointerException` If `arr` is `null`. - */ - @inline - def arrayclear(arr: Array[Int]) { java.util.Arrays.fill(arr, 0) } - - /** Returns the `Class` object associated with the class or interface with the given string name using the current `ClassLoader`. - * On the JVM, invoking this method is equivalent to: `java.lang.Class.forName(name)` - * - * For more information, please see the Java documentation for [[java.lang.Class]]. - * - * @param name the fully qualified name of the desired class. - * @return the `Class` object for the class with the specified name. - * @throws `java.lang.LinkageError` if the linkage fails - * @throws `java.lang.ExceptionInInitializerError` if the initialization provoked by this method fails - * @throws `java.lang.ClassNotFoundException` if the class cannot be located - * @example {{{ - * val a = scala.compat.Platform.getClassForName("java.lang.Integer") // returns the Class[_] for java.lang.Integer - * }}} - */ - @inline - def getClassForName(name: String): Class[_] = java.lang.Class.forName(name) - - /** The default line separator. - * - * On the JavaScript backend, this is always "\n". - */ - val EOL = "\n" - - /** The current time in milliseconds. The time is counted since 1 January 1970 - * UTC. - * - * Note that the operating system timer used to obtain this value may be less - * precise than a millisecond. - */ - @inline - def currentTime: Long = System.currentTimeMillis() - - /** Runs the garbage collector. - * - * This is a request that the underlying JVM runs the garbage collector. - * The results of this call depends heavily on the JVM used. - * The underlying JVM is free to ignore this request. - */ - @inline - def collectGarbage(): Unit = System.gc() - - /** The name of the default character set encoding as a string */ - @inline - def defaultCharsetName: String = java.nio.charset.Charset.defaultCharset.name -} diff --git a/scalalib/overrides-2.10/scala/concurrent/impl/AbstractPromise.scala b/scalalib/overrides-2.10/scala/concurrent/impl/AbstractPromise.scala deleted file mode 100644 index 8ea135e4d7..0000000000 --- a/scalalib/overrides-2.10/scala/concurrent/impl/AbstractPromise.scala +++ /dev/null @@ -1,29 +0,0 @@ -package scala.concurrent.impl - -/** - * JavaScript specific implementation of AbstractPromise - * - * This basically implements a "CAS" in Scala for JavaScript. Its - * implementation is trivial because there is no multi-threading. - * - * @author Tobias Schlatter - */ -abstract class AbstractPromise { - - private var state: AnyRef = _ - - protected final - def updateState(oldState: AnyRef, newState: AnyRef): Boolean = { - if (state eq oldState) { - state = newState - true - } else false - } - - protected final def getState: AnyRef = state - -} - -object AbstractPromise { - protected def updater = ??? -} diff --git a/scalalib/overrides-2.10/scala/package.scala b/scalalib/overrides-2.10/scala/package.scala deleted file mode 100644 index 5aad9a91d8..0000000000 --- a/scalalib/overrides-2.10/scala/package.scala +++ /dev/null @@ -1,138 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - -/** - * Core Scala types. They are always available without an explicit import. - * @contentDiagram hideNodes "scala.Serializable" - */ -package object scala { - type Throwable = java.lang.Throwable - type Exception = java.lang.Exception - type Error = java.lang.Error - - type RuntimeException = java.lang.RuntimeException - type NullPointerException = java.lang.NullPointerException - type ClassCastException = java.lang.ClassCastException - type IndexOutOfBoundsException = java.lang.IndexOutOfBoundsException - type ArrayIndexOutOfBoundsException = java.lang.ArrayIndexOutOfBoundsException - type StringIndexOutOfBoundsException = java.lang.StringIndexOutOfBoundsException - type UnsupportedOperationException = java.lang.UnsupportedOperationException - type IllegalArgumentException = java.lang.IllegalArgumentException - type NoSuchElementException = java.util.NoSuchElementException - type NumberFormatException = java.lang.NumberFormatException - type AbstractMethodError = java.lang.AbstractMethodError - type InterruptedException = java.lang.InterruptedException - - // A dummy used by the specialization annotation. - val AnyRef = new Specializable { - override def toString = "object AnyRef" - } - - @deprecated("instead of `@serializable class C`, use `class C extends Serializable`", "2.9.0") - type serializable = annotation.serializable - - @deprecated("instead of `@cloneable class C`, use `class C extends Cloneable`", "2.10.0") - type cloneable = annotation.cloneable - - type TraversableOnce[+A] = scala.collection.TraversableOnce[A] - - type Traversable[+A] = scala.collection.Traversable[A] - val Traversable = scala.collection.Traversable - - type Iterable[+A] = scala.collection.Iterable[A] - val Iterable = scala.collection.Iterable - - type Seq[+A] = scala.collection.Seq[A] - val Seq = scala.collection.Seq - - type IndexedSeq[+A] = scala.collection.IndexedSeq[A] - val IndexedSeq = scala.collection.IndexedSeq - - type Iterator[+A] = scala.collection.Iterator[A] - val Iterator = scala.collection.Iterator - - type BufferedIterator[+A] = scala.collection.BufferedIterator[A] - - type List[+A] = scala.collection.immutable.List[A] - val List = scala.collection.immutable.List - - val Nil = scala.collection.immutable.Nil - - type ::[A] = scala.collection.immutable.::[A] - val :: = scala.collection.immutable.:: - - val +: = scala.collection.+: - val :+ = scala.collection.:+ - - type Stream[+A] = scala.collection.immutable.Stream[A] - val Stream = scala.collection.immutable.Stream - val #:: = scala.collection.immutable.Stream.#:: - - type Vector[+A] = scala.collection.immutable.Vector[A] - val Vector = scala.collection.immutable.Vector - - type StringBuilder = scala.collection.mutable.StringBuilder - val StringBuilder = scala.collection.mutable.StringBuilder - - type Range = scala.collection.immutable.Range - val Range = scala.collection.immutable.Range - - // Numeric types which were moved into scala.math.* - - type BigDecimal = scala.math.BigDecimal - lazy val BigDecimal = scala.math.BigDecimal - - type BigInt = scala.math.BigInt - lazy val BigInt = scala.math.BigInt - - type Equiv[T] = scala.math.Equiv[T] - val Equiv = scala.math.Equiv - - type Fractional[T] = scala.math.Fractional[T] - type Integral[T] = scala.math.Integral[T] - - type Numeric[T] = scala.math.Numeric[T] - val Numeric = scala.math.Numeric - - type Ordered[T] = scala.math.Ordered[T] - val Ordered = scala.math.Ordered - - type Ordering[T] = scala.math.Ordering[T] - val Ordering = scala.math.Ordering - - type PartialOrdering[T] = scala.math.PartialOrdering[T] - type PartiallyOrdered[T] = scala.math.PartiallyOrdered[T] - - type Either[+A, +B] = scala.util.Either[A, B] - val Either = scala.util.Either - - type Left[+A, +B] = scala.util.Left[A, B] - val Left = scala.util.Left - - type Right[+A, +B] = scala.util.Right[A, B] - val Right = scala.util.Right - - // Annotations which we might move to annotation.* -/* - type SerialVersionUID = annotation.SerialVersionUID - type cloneable = annotation.cloneable - type deprecated = annotation.deprecated - type deprecatedName = annotation.deprecatedName - type inline = annotation.inline - type native = annotation.native - type noinline = noannotation.inline - type remote = annotation.remote - type serializable = annotation.serializable - type specialized = annotation.specialized - type transient = annotation.transient - type throws = annotation.throws - type unchecked = annotation.unchecked.unchecked - type volatile = annotation.volatile - */ -} diff --git a/scalalib/overrides-2.10/scala/reflect/ClassTag.scala b/scalalib/overrides-2.10/scala/reflect/ClassTag.scala deleted file mode 100644 index 4607fb08dd..0000000000 --- a/scalalib/overrides-2.10/scala/reflect/ClassTag.scala +++ /dev/null @@ -1,153 +0,0 @@ -package scala -package reflect - -import java.lang.{ Class => jClass } -import scala.language.{implicitConversions, existentials} -import scala.runtime.ScalaRunTime.{ arrayClass, arrayElementClass } - -/** - * - * A `ClassTag[T]` stores the erased class of a given type `T`, accessible via the `runtimeClass` - * field. This is particularly useful for instantiating `Array`s whose element types are unknown - * at compile time. - * - * `ClassTag`s are a weaker special case of [[scala.reflect.api.TypeTags#TypeTag]]s, in that they - * wrap only the runtime class of a given type, whereas a `TypeTag` contains all static type - * information. That is, `ClassTag`s are constructed from knowing only the top-level class of a - * type, without necessarily knowing all of its argument types. This runtime information is enough - * for runtime `Array` creation. - * - * For example: - * {{{ - * scala> def mkArray[T : ClassTag](elems: T*) = Array[T](elems: _*) - * mkArray: [T](elems: T*)(implicit evidence$1: scala.reflect.ClassTag[T])Array[T] - * - * scala> mkArray(42, 13) - * res0: Array[Int] = Array(42, 13) - * - * scala> mkArray("Japan","Brazil","Germany") - * res1: Array[String] = Array(Japan, Brazil, Germany) - * }}} - * - * See [[scala.reflect.api.TypeTags]] for more examples, or the - * [[http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html Reflection Guide: TypeTags]] - * for more details. - * - */ -@scala.annotation.implicitNotFound(msg = "No ClassTag available for ${T}") -trait ClassTag[T] extends ClassManifestDeprecatedApis[T] with Equals with Serializable { - // please, don't add any APIs here, like it was with `newWrappedArray` and `newArrayBuilder` - // class tags, and all tags in general, should be as minimalistic as possible - - /** A class representing the type `U` to which `T` would be erased. - * Note that there is no subtyping relationship between `T` and `U`. - */ - def runtimeClass: jClass[_] - - /** Produces a `ClassTag` that knows how to instantiate an `Array[Array[T]]` */ - def wrap: ClassTag[Array[T]] = ClassTag[Array[T]](arrayClass(runtimeClass)) - - /** Produces a new array with element type `T` and length `len` */ - override def newArray(len: Int): Array[T] = - runtimeClass match { - case java.lang.Byte.TYPE => new Array[Byte](len).asInstanceOf[Array[T]] - case java.lang.Short.TYPE => new Array[Short](len).asInstanceOf[Array[T]] - case java.lang.Character.TYPE => new Array[Char](len).asInstanceOf[Array[T]] - case java.lang.Integer.TYPE => new Array[Int](len).asInstanceOf[Array[T]] - case java.lang.Long.TYPE => new Array[Long](len).asInstanceOf[Array[T]] - case java.lang.Float.TYPE => new Array[Float](len).asInstanceOf[Array[T]] - case java.lang.Double.TYPE => new Array[Double](len).asInstanceOf[Array[T]] - case java.lang.Boolean.TYPE => new Array[Boolean](len).asInstanceOf[Array[T]] - case java.lang.Void.TYPE => new Array[Unit](len).asInstanceOf[Array[T]] - case _ => java.lang.reflect.Array.newInstance(runtimeClass, len).asInstanceOf[Array[T]] - } - - /** A ClassTag[T] can serve as an extractor that matches only objects of type T. - * - * The compiler tries to turn unchecked type tests in pattern matches into checked ones - * by wrapping a `(_: T)` type pattern as `ct(_: T)`, where `ct` is the `ClassTag[T]` instance. - * Type tests necessary before calling other extractors are treated similarly. - * `SomeExtractor(...)` is turned into `ct(SomeExtractor(...))` if `T` in `SomeExtractor.unapply(x: T)` - * is uncheckable, but we have an instance of `ClassTag[T]`. - */ - def unapply(x: Any): Option[T] = unapply_impl(x) - def unapply(x: Byte): Option[T] = unapply_impl(x) - def unapply(x: Short): Option[T] = unapply_impl(x) - def unapply(x: Char): Option[T] = unapply_impl(x) - def unapply(x: Int): Option[T] = unapply_impl(x) - def unapply(x: Long): Option[T] = unapply_impl(x) - def unapply(x: Float): Option[T] = unapply_impl(x) - def unapply(x: Double): Option[T] = unapply_impl(x) - def unapply(x: Boolean): Option[T] = unapply_impl(x) - def unapply(x: Unit): Option[T] = unapply_impl(x) - - private def unapply_impl[U: ClassTag](x: U): Option[T] = - if (x == null) None - else { - val staticClass = classTag[U].runtimeClass - val conforms = - if (staticClass.isPrimitive) runtimeClass.isAssignableFrom(staticClass) - else runtimeClass.isInstance(x) - if (conforms) Some(x.asInstanceOf[T]) else None - } - - // case class accessories - override def canEqual(x: Any) = x.isInstanceOf[ClassTag[_]] - override def equals(x: Any) = x.isInstanceOf[ClassTag[_]] && this.runtimeClass == x.asInstanceOf[ClassTag[_]].runtimeClass - override def hashCode = scala.runtime.ScalaRunTime.hash(runtimeClass) - override def toString = { - def prettyprint(clazz: jClass[_]): String = - if (clazz.isArray) s"Array[${prettyprint(arrayElementClass(clazz))}]" else - clazz.getName - prettyprint(runtimeClass) - } -} - -/** - * Class tags corresponding to primitive types and constructor/extractor for ClassTags. - */ -object ClassTag { - def Byte : ClassTag[scala.Byte] = ManifestFactory.Byte - def Short : ClassTag[scala.Short] = ManifestFactory.Short - def Char : ClassTag[scala.Char] = ManifestFactory.Char - def Int : ClassTag[scala.Int] = ManifestFactory.Int - def Long : ClassTag[scala.Long] = ManifestFactory.Long - def Float : ClassTag[scala.Float] = ManifestFactory.Float - def Double : ClassTag[scala.Double] = ManifestFactory.Double - def Boolean : ClassTag[scala.Boolean] = ManifestFactory.Boolean - def Unit : ClassTag[scala.Unit] = ManifestFactory.Unit - def Any : ClassTag[scala.Any] = ManifestFactory.Any - def Object : ClassTag[java.lang.Object] = ManifestFactory.Object - def AnyVal : ClassTag[scala.AnyVal] = ManifestFactory.AnyVal - def AnyRef : ClassTag[scala.AnyRef] = ManifestFactory.AnyRef - def Nothing : ClassTag[scala.Nothing] = ManifestFactory.Nothing - def Null : ClassTag[scala.Null] = ManifestFactory.Null - - def apply[T](runtimeClass1: jClass[_]): ClassTag[T] = - runtimeClass1 match { - case java.lang.Byte.TYPE => ClassTag.Byte.asInstanceOf[ClassTag[T]] - case java.lang.Short.TYPE => ClassTag.Short.asInstanceOf[ClassTag[T]] - case java.lang.Character.TYPE => ClassTag.Char.asInstanceOf[ClassTag[T]] - case java.lang.Integer.TYPE => ClassTag.Int.asInstanceOf[ClassTag[T]] - case java.lang.Long.TYPE => ClassTag.Long.asInstanceOf[ClassTag[T]] - case java.lang.Float.TYPE => ClassTag.Float.asInstanceOf[ClassTag[T]] - case java.lang.Double.TYPE => ClassTag.Double.asInstanceOf[ClassTag[T]] - case java.lang.Boolean.TYPE => ClassTag.Boolean.asInstanceOf[ClassTag[T]] - case java.lang.Void.TYPE => ClassTag.Unit.asInstanceOf[ClassTag[T]] - case _ => - if (classOf[java.lang.Object] == runtimeClass1) - ClassTag.Object.asInstanceOf[ClassTag[T]] - else if (classOf[scala.runtime.Nothing$] == runtimeClass1) - ClassTag.Nothing.asInstanceOf[ClassTag[T]] - else if (classOf[scala.runtime.Null$] == runtimeClass1) - ClassTag.Null.asInstanceOf[ClassTag[T]] - else - new ClassClassTag[T](runtimeClass1) - } - - @inline - private final class ClassClassTag[T]( - val runtimeClass: Class[_]) extends ClassTag[T] - - def unapply[T](ctag: ClassTag[T]): Option[Class[_]] = Some(ctag.runtimeClass) -} diff --git a/scalalib/overrides-2.10/scala/reflect/Manifest.scala b/scalalib/overrides-2.10/scala/reflect/Manifest.scala deleted file mode 100644 index 929cb55747..0000000000 --- a/scalalib/overrides-2.10/scala/reflect/Manifest.scala +++ /dev/null @@ -1,294 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.reflect - -import scala.collection.mutable.{ ArrayBuilder, WrappedArray } - -/** A `Manifest[T]` is an opaque descriptor for type T. Its supported use - * is to give access to the erasure of the type as a `Class` instance, as - * is necessary for the creation of native `Arrays` if the class is not - * known at compile time. - * - * The type-relation operators `<:<` and `=:=` should be considered - * approximations only, as there are numerous aspects of type conformance - * which are not yet adequately represented in manifests. - * - * Example usages: -{{{ - def arr[T] = new Array[T](0) // does not compile - def arr[T](implicit m: Manifest[T]) = new Array[T](0) // compiles - def arr[T: Manifest] = new Array[T](0) // shorthand for the preceding - - // Methods manifest, classManifest, and optManifest are in [[scala.Predef]]. - def isApproxSubType[T: Manifest, U: Manifest] = manifest[T] <:< manifest[U] - isApproxSubType[List[String], List[AnyRef]] // true - isApproxSubType[List[String], List[Int]] // false - - def methods[T: ClassManifest] = classManifest[T].erasure.getMethods - def retType[T: ClassManifest](name: String) = - methods[T] find (_.getName == name) map (_.getGenericReturnType) - - retType[Map[_, _]]("values") // Some(scala.collection.Iterable) -}}} - * - */ -@scala.annotation.implicitNotFound(msg = "No Manifest available for ${T}.") -// TODO undeprecated until Scala reflection becomes non-experimental -// @deprecated("Use scala.reflect.ClassTag (to capture erasures) or scala.reflect.runtime.universe.TypeTag (to capture types) or both instead", "2.10.0") -trait Manifest[T] extends ClassManifest[T] with Equals { - override def typeArguments: List[Manifest[_]] = Nil - - override def arrayManifest: Manifest[Array[T]] = - Manifest.classType[Array[T]](arrayClass[T](erasure), this) - - override def canEqual(that: Any): Boolean = that match { - case _: Manifest[_] => true - case _ => false - } - /** Note: testing for erasure here is important, as it is many times - * faster than <:< and rules out most comparisons. - */ - override def equals(that: Any): Boolean = that match { - case m: Manifest[_] => (m canEqual this) && (this.erasure == m.erasure) && (this <:< m) && (m <:< this) - case _ => false - } - override def hashCode = this.erasure.## -} - -// TODO undeprecated until Scala reflection becomes non-experimental -// @deprecated("Use type tags and manually check the corresponding class or type instead", "2.10.0") -abstract class AnyValManifest[T <: AnyVal](override val toString: String) extends Manifest[T] with Equals { - override def <:<(that: ClassManifest[_]): Boolean = - (that eq this) || (that eq Manifest.Any) || (that eq Manifest.AnyVal) - override def canEqual(other: Any) = other match { - case _: AnyValManifest[_] => true - case _ => false - } - override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef] - override def hashCode = System.identityHashCode(this) -} - -/** `ManifestFactory` defines factory methods for manifests. - * It is intended for use by the compiler and should not be used in client code. - * - * Unlike `Manifest`, this factory isn't annotated with a deprecation warning. - * This is done to prevent avalanches of deprecation warnings in the code that calls methods with manifests. - * Why so complicated? Read up the comments for `ClassManifestFactory`. - */ -object ManifestFactory { - def valueManifests: List[AnyValManifest[_]] = - List(Byte, Short, Char, Int, Long, Float, Double, Boolean, Unit) - - def Byte: AnyValManifest[Byte] = ByteManifest - def Short: AnyValManifest[Short] = ShortManifest - def Char: AnyValManifest[Char] = CharManifest - def Int: AnyValManifest[Int] = IntManifest - def Long: AnyValManifest[Long] = LongManifest - def Float: AnyValManifest[Float] = FloatManifest - def Double: AnyValManifest[Double] = DoubleManifest - def Boolean: AnyValManifest[Boolean] = BooleanManifest - def Unit: AnyValManifest[Unit] = UnitManifest - def Any: Manifest[scala.Any] = AnyManifest - def Object: Manifest[java.lang.Object] = ObjectManifest - def AnyRef: Manifest[scala.AnyRef] = Object.asInstanceOf[Manifest[scala.AnyRef]] - def AnyVal: Manifest[scala.AnyVal] = AnyValManifest - def Null: Manifest[scala.Null] = NullManifest - def Nothing: Manifest[scala.Nothing] = NothingManifest - - private object ByteManifest extends AnyValManifest[scala.Byte]("Byte") { - def runtimeClass = java.lang.Byte.TYPE - override def newArray(len: Int): Array[Byte] = new Array[Byte](len) - override def newWrappedArray(len: Int): WrappedArray[Byte] = new WrappedArray.ofByte(new Array[Byte](len)) - override def newArrayBuilder(): ArrayBuilder[Byte] = new ArrayBuilder.ofByte() - private def readResolve(): Any = Manifest.Byte - } - - private object ShortManifest extends AnyValManifest[scala.Short]("Short") { - def runtimeClass = java.lang.Short.TYPE - override def newArray(len: Int): Array[Short] = new Array[Short](len) - override def newWrappedArray(len: Int): WrappedArray[Short] = new WrappedArray.ofShort(new Array[Short](len)) - override def newArrayBuilder(): ArrayBuilder[Short] = new ArrayBuilder.ofShort() - private def readResolve(): Any = Manifest.Short - } - - private object CharManifest extends AnyValManifest[scala.Char]("Char") { - def runtimeClass = java.lang.Character.TYPE - override def newArray(len: Int): Array[Char] = new Array[Char](len) - override def newWrappedArray(len: Int): WrappedArray[Char] = new WrappedArray.ofChar(new Array[Char](len)) - override def newArrayBuilder(): ArrayBuilder[Char] = new ArrayBuilder.ofChar() - private def readResolve(): Any = Manifest.Char - } - - private object IntManifest extends AnyValManifest[scala.Int]("Int") { - def runtimeClass = java.lang.Integer.TYPE - override def newArray(len: Int): Array[Int] = new Array[Int](len) - override def newWrappedArray(len: Int): WrappedArray[Int] = new WrappedArray.ofInt(new Array[Int](len)) - override def newArrayBuilder(): ArrayBuilder[Int] = new ArrayBuilder.ofInt() - private def readResolve(): Any = Manifest.Int - } - - private object LongManifest extends AnyValManifest[scala.Long]("Long") { - def runtimeClass = java.lang.Long.TYPE - override def newArray(len: Int): Array[Long] = new Array[Long](len) - override def newWrappedArray(len: Int): WrappedArray[Long] = new WrappedArray.ofLong(new Array[Long](len)) - override def newArrayBuilder(): ArrayBuilder[Long] = new ArrayBuilder.ofLong() - private def readResolve(): Any = Manifest.Long - } - - private object FloatManifest extends AnyValManifest[scala.Float]("Float") { - def runtimeClass = java.lang.Float.TYPE - override def newArray(len: Int): Array[Float] = new Array[Float](len) - override def newWrappedArray(len: Int): WrappedArray[Float] = new WrappedArray.ofFloat(new Array[Float](len)) - override def newArrayBuilder(): ArrayBuilder[Float] = new ArrayBuilder.ofFloat() - private def readResolve(): Any = Manifest.Float - } - - private object DoubleManifest extends AnyValManifest[scala.Double]("Double") { - def runtimeClass = java.lang.Double.TYPE - override def newArray(len: Int): Array[Double] = new Array[Double](len) - override def newWrappedArray(len: Int): WrappedArray[Double] = new WrappedArray.ofDouble(new Array[Double](len)) - override def newArrayBuilder(): ArrayBuilder[Double] = new ArrayBuilder.ofDouble() - private def readResolve(): Any = Manifest.Double - } - - private object BooleanManifest extends AnyValManifest[scala.Boolean]("Boolean") { - def runtimeClass = java.lang.Boolean.TYPE - override def newArray(len: Int): Array[Boolean] = new Array[Boolean](len) - override def newWrappedArray(len: Int): WrappedArray[Boolean] = new WrappedArray.ofBoolean(new Array[Boolean](len)) - override def newArrayBuilder(): ArrayBuilder[Boolean] = new ArrayBuilder.ofBoolean() - private def readResolve(): Any = Manifest.Boolean - } - - private object UnitManifest extends AnyValManifest[scala.Unit]("Unit") { - def runtimeClass = java.lang.Void.TYPE - override def newArray(len: Int): Array[Unit] = new Array[Unit](len) - override def newWrappedArray(len: Int): WrappedArray[Unit] = new WrappedArray.ofUnit(new Array[Unit](len)) - override def newArrayBuilder(): ArrayBuilder[Unit] = new ArrayBuilder.ofUnit() - private def readResolve(): Any = Manifest.Unit - } - - private val ObjectTYPE = classOf[java.lang.Object] - private val NothingTYPE = classOf[scala.runtime.Nothing$] - private val NullTYPE = classOf[scala.runtime.Null$] - - private object AnyManifest extends PhantomManifest[scala.Any](classOf[java.lang.Object], "Any") { - override def runtimeClass = classOf[java.lang.Object] - override def newArray(len: Int) = new Array[scala.Any](len) - override def <:<(that: ClassManifest[_]): Boolean = (that eq this) - private def readResolve(): Any = Manifest.Any - } - - private object ObjectManifest extends PhantomManifest[java.lang.Object](classOf[java.lang.Object], "Object") { - override def runtimeClass = classOf[java.lang.Object] - override def newArray(len: Int) = new Array[java.lang.Object](len) - override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any) - private def readResolve(): Any = Manifest.Object - } - - private object AnyValManifest extends PhantomManifest[scala.AnyVal](classOf[java.lang.Object], "AnyVal") { - override def runtimeClass = classOf[java.lang.Object] - override def newArray(len: Int) = new Array[scala.AnyVal](len) - override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any) - private def readResolve(): Any = Manifest.AnyVal - } - - private object NullManifest extends PhantomManifest[scala.Null](classOf[scala.runtime.Null$], "Null") { - override def runtimeClass = classOf[scala.runtime.Null$] - override def newArray(len: Int) = new Array[scala.Null](len) - override def <:<(that: ClassManifest[_]): Boolean = - (that ne null) && (that ne Nothing) && !(that <:< AnyVal) - private def readResolve(): Any = Manifest.Null - } - - private object NothingManifest extends PhantomManifest[scala.Nothing](classOf[scala.runtime.Nothing$], "Nothing") { - override def runtimeClass = classOf[scala.runtime.Nothing$] - override def newArray(len: Int) = new Array[scala.Nothing](len) - override def <:<(that: ClassManifest[_]): Boolean = (that ne null) - private def readResolve(): Any = Manifest.Nothing - } - - private class SingletonTypeManifest[T <: AnyRef](value: AnyRef) extends Manifest[T] { - lazy val runtimeClass = value.getClass - override lazy val toString = value.toString + ".type" - } - - /** Manifest for the singleton type `value.type`. */ - def singleType[T <: AnyRef](value: AnyRef): Manifest[T] = - new SingletonTypeManifest[T](value) - - /** Manifest for the class type `clazz[args]`, where `clazz` is - * a top-level or static class. - * @note This no-prefix, no-arguments case is separate because we - * it's called from ScalaRunTime.boxArray itself. If we - * pass varargs as arrays into this, we get an infinitely recursive call - * to boxArray. (Besides, having a separate case is more efficient) - */ - def classType[T](clazz: Predef.Class[_]): Manifest[T] = - new ClassTypeManifest[T](None, clazz, Nil) - - /** Manifest for the class type `clazz`, where `clazz` is - * a top-level or static class and args are its type arguments. */ - def classType[T](clazz: Predef.Class[T], arg1: Manifest[_], args: Manifest[_]*): Manifest[T] = - new ClassTypeManifest[T](None, clazz, arg1 :: args.toList) - - /** Manifest for the class type `clazz[args]`, where `clazz` is - * a class with non-package prefix type `prefix` and type arguments `args`. - */ - def classType[T](prefix: Manifest[_], clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] = - new ClassTypeManifest[T](Some(prefix), clazz, args.toList) - - private abstract class PhantomManifest[T](_runtimeClass: Predef.Class[_], - override val toString: String) extends ClassTypeManifest[T](None, _runtimeClass, Nil) { - override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef] - override def hashCode = System.identityHashCode(this) - } - - /** Manifest for the class type `clazz[args]`, where `clazz` is - * a top-level or static class. */ - private class ClassTypeManifest[T](prefix: Option[Manifest[_]], - runtimeClass1: Predef.Class[_], - override val typeArguments: List[Manifest[_]]) extends Manifest[T] { - def runtimeClass: Predef.Class[_] = runtimeClass1 - override def toString = - (if (prefix.isEmpty) "" else prefix.get.toString+"#") + - (if (erasure.isArray) "Array" else erasure.getName) + - argString - } - - def arrayType[T](arg: Manifest[_]): Manifest[Array[T]] = - arg.asInstanceOf[Manifest[T]].arrayManifest - - /** Manifest for the abstract type `prefix # name'. `upperBound` is not - * strictly necessary as it could be obtained by reflection. It was - * added so that erasure can be calculated without reflection. */ - def abstractType[T](prefix: Manifest[_], name: String, upperBound: Predef.Class[_], args: Manifest[_]*): Manifest[T] = - new Manifest[T] { - def runtimeClass = upperBound - override val typeArguments = args.toList - override def toString = prefix.toString+"#"+name+argString - } - - /** Manifest for the unknown type `_ >: L <: U` in an existential. - */ - def wildcardType[T](lowerBound: Manifest[_], upperBound: Manifest[_]): Manifest[T] = - new Manifest[T] { - def runtimeClass = upperBound.erasure - override def toString = - "_" + - (if (lowerBound eq Nothing) "" else " >: "+lowerBound) + - (if (upperBound eq Nothing) "" else " <: "+upperBound) - } - - /** Manifest for the intersection type `parents_0 with ... with parents_n'. */ - def intersectionType[T](parents: Manifest[_]*): Manifest[T] = - new Manifest[T] { - def runtimeClass = parents.head.erasure - override def toString = parents.mkString(" with ") - } -} diff --git a/scalalib/overrides-2.10/scala/reflect/NameTransformer.scala b/scalalib/overrides-2.10/scala/reflect/NameTransformer.scala deleted file mode 100644 index 8a900d0256..0000000000 --- a/scalalib/overrides-2.10/scala/reflect/NameTransformer.scala +++ /dev/null @@ -1,158 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala -package reflect - -/** Provides functions to encode and decode Scala symbolic names. - * Also provides some constants. - */ -object NameTransformer { - // XXX Short term: providing a way to alter these without having to recompile - // the compiler before recompiling the compiler. - val MODULE_SUFFIX_STRING = "$" - val NAME_JOIN_STRING = "$" - val MODULE_INSTANCE_NAME = "MODULE$" - - private val nops = 128 - private val ncodes = 26 * 26 - - private class OpCodes(val op: Char, val code: String, val next: OpCodes) - - private val op2code = new Array[String](nops) - private val code2op = new Array[OpCodes](ncodes) - private def enterOp(op: Char, code: String) = { - op2code(op) = code - val c = (code.charAt(1) - 'a') * 26 + code.charAt(2) - 'a' - code2op(c) = new OpCodes(op, code, code2op(c)) - } - - /* Note: decoding assumes opcodes are only ever lowercase. */ - enterOp('~', "$tilde") - enterOp('=', "$eq") - enterOp('<', "$less") - enterOp('>', "$greater") - enterOp('!', "$bang") - enterOp('#', "$hash") - enterOp('%', "$percent") - enterOp('^', "$up") - enterOp('&', "$amp") - enterOp('|', "$bar") - enterOp('*', "$times") - enterOp('/', "$div") - enterOp('+', "$plus") - enterOp('-', "$minus") - enterOp(':', "$colon") - enterOp('\\', "$bslash") - enterOp('?', "$qmark") - enterOp('@', "$at") - - /** Replace operator symbols by corresponding `\$opname`. - * - * @param name the string to encode - * @return the string with all recognized opchars replaced with their encoding - */ - def encode(name: String): String = { - var buf: StringBuilder = null - val len = name.length() - var i = 0 - while (i < len) { - val c = name charAt i - if (c < nops && (op2code(c) ne null)) { - if (buf eq null) { - buf = new StringBuilder() - buf.append(name.substring(0, i)) - } - buf.append(op2code(c)) - /* Handle glyphs that are not valid Java/JVM identifiers */ - } - else if (!Character.isJavaIdentifierPart(c)) { - if (buf eq null) { - buf = new StringBuilder() - buf.append(name.substring(0, i)) - } - buf.append("$u%04X".format(c.toInt)) - } - else if (buf ne null) { - buf.append(c) - } - i += 1 - } - if (buf eq null) name else buf.toString() - } - - /** Replace `\$opname` by corresponding operator symbol. - * - * @param name0 the string to decode - * @return the string with all recognized operator symbol encodings replaced with their name - */ - def decode(name0: String): String = { - //System.out.println("decode: " + name);//DEBUG - val name = if (name0.endsWith("")) name0.substring(0, name0.length() - ("").length()) + "this" - else name0; - var buf: StringBuilder = null - val len = name.length() - var i = 0 - while (i < len) { - var ops: OpCodes = null - var unicode = false - val c = name charAt i - if (c == '$' && i + 2 < len) { - val ch1 = name.charAt(i+1) - if ('a' <= ch1 && ch1 <= 'z') { - val ch2 = name.charAt(i+2) - if ('a' <= ch2 && ch2 <= 'z') { - ops = code2op((ch1 - 'a') * 26 + ch2 - 'a') - while ((ops ne null) && !name.startsWith(ops.code, i)) ops = ops.next - if (ops ne null) { - if (buf eq null) { - buf = new StringBuilder() - buf.append(name.substring(0, i)) - } - buf.append(ops.op) - i += ops.code.length() - } - /* Handle the decoding of Unicode glyphs that are - * not valid Java/JVM identifiers */ - } else if ((len - i) >= 6 && // Check that there are enough characters left - ch1 == 'u' && - ((Character.isDigit(ch2)) || - ('A' <= ch2 && ch2 <= 'F'))) { - /* Skip past "$u", next four should be hexadecimal */ - val hex = name.substring(i+2, i+6) - try { - val str = Integer.parseInt(hex, 16).toChar - if (buf eq null) { - buf = new StringBuilder() - buf.append(name.substring(0, i)) - } - buf.append(str) - /* 2 for "$u", 4 for hexadecimal number */ - i += 6 - unicode = true - } catch { - case _:NumberFormatException => - /* `hex` did not decode to a hexadecimal number, so - * do nothing. */ - } - } - } - } - /* If we didn't see an opcode or encoded Unicode glyph, and the - buffer is non-empty, write the current character and advance - one */ - if ((ops eq null) && !unicode) { - if (buf ne null) - buf.append(c) - i += 1 - } - } - //System.out.println("= " + (if (buf == null) name else buf.toString()));//DEBUG - if (buf eq null) name else buf.toString() - } -} diff --git a/scalalib/overrides-2.10/scala/runtime/ScalaRunTime.scala b/scalalib/overrides-2.10/scala/runtime/ScalaRunTime.scala deleted file mode 100644 index 96a141b77a..0000000000 --- a/scalalib/overrides-2.10/scala/runtime/ScalaRunTime.scala +++ /dev/null @@ -1,356 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala -package runtime - -import scala.collection.{ Seq, IndexedSeq, TraversableView, AbstractIterator } -import scala.collection.mutable.WrappedArray -import scala.collection.immutable.{ StringLike, NumericRange, List, Stream, Nil, :: } -import scala.collection.generic.{ Sorted } -import scala.reflect.{ ClassTag, classTag } -import scala.util.control.ControlThrowable -import scala.xml.{ Node, MetaData } -import java.lang.{ Class => jClass } - -import java.lang.Double.doubleToLongBits -import java.lang.reflect.{ Modifier, Method => JMethod } - -/** The object ScalaRunTime provides support methods required by - * the scala runtime. All these methods should be considered - * outside the API and subject to change or removal without notice. - */ -object ScalaRunTime { - def isArray(x: AnyRef): Boolean = isArray(x, 1) - def isArray(x: Any, atLevel: Int): Boolean = - x != null && isArrayClass(x.getClass, atLevel) - - private def isArrayClass(clazz: jClass[_], atLevel: Int): Boolean = - clazz != null && clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) - - def isValueClass(clazz: jClass[_]) = clazz.isPrimitive() - - // includes specialized subclasses and future proofed against hypothetical TupleN (for N > 22) - def isTuple(x: Any) = x != null && x.getClass.getName.startsWith("scala.Tuple") - def isAnyVal(x: Any) = x match { - case _: Byte | _: Short | _: Char | _: Int | _: Long | _: Float | _: Double | _: Boolean | _: Unit => true - case _ => false - } - - /** Return the class object representing an array with element class `clazz`. - */ - def arrayClass(clazz: jClass[_]): jClass[_] = { - // newInstance throws an exception if the erasure is Void.TYPE. see SI-5680 - if (clazz == java.lang.Void.TYPE) classOf[Array[Unit]] - else java.lang.reflect.Array.newInstance(clazz, 0).getClass - } - - /** Return the class object representing elements in arrays described by a given schematic. - */ - def arrayElementClass(schematic: Any): jClass[_] = schematic match { - case cls: jClass[_] => cls.getComponentType - case tag: ClassTag[_] => tag.runtimeClass - case _ => - throw new UnsupportedOperationException(s"unsupported schematic $schematic (${schematic.getClass})") - } - - /** Return the class object representing an unboxed value type, - * e.g. classOf[int], not classOf[java.lang.Integer]. The compiler - * rewrites expressions like 5.getClass to come here. - */ - def anyValClass[T <: AnyVal : ClassTag](value: T): jClass[T] = - classTag[T].runtimeClass.asInstanceOf[jClass[T]] - - /** Retrieve generic array element */ - def array_apply(xs: AnyRef, idx: Int): Any = { - xs match { - case x: Array[AnyRef] => x(idx).asInstanceOf[Any] - case x: Array[Int] => x(idx).asInstanceOf[Any] - case x: Array[Double] => x(idx).asInstanceOf[Any] - case x: Array[Long] => x(idx).asInstanceOf[Any] - case x: Array[Float] => x(idx).asInstanceOf[Any] - case x: Array[Char] => x(idx).asInstanceOf[Any] - case x: Array[Byte] => x(idx).asInstanceOf[Any] - case x: Array[Short] => x(idx).asInstanceOf[Any] - case x: Array[Boolean] => x(idx).asInstanceOf[Any] - case x: Array[Unit] => x(idx).asInstanceOf[Any] - case null => throw new NullPointerException - } - } - - /** update generic array element */ - def array_update(xs: AnyRef, idx: Int, value: Any): Unit = { - xs match { - case x: Array[AnyRef] => x(idx) = value.asInstanceOf[AnyRef] - case x: Array[Int] => x(idx) = value.asInstanceOf[Int] - case x: Array[Double] => x(idx) = value.asInstanceOf[Double] - case x: Array[Long] => x(idx) = value.asInstanceOf[Long] - case x: Array[Float] => x(idx) = value.asInstanceOf[Float] - case x: Array[Char] => x(idx) = value.asInstanceOf[Char] - case x: Array[Byte] => x(idx) = value.asInstanceOf[Byte] - case x: Array[Short] => x(idx) = value.asInstanceOf[Short] - case x: Array[Boolean] => x(idx) = value.asInstanceOf[Boolean] - case x: Array[Unit] => x(idx) = value.asInstanceOf[Unit] - case null => throw new NullPointerException - } - } - - /** Get generic array length */ - def array_length(xs: AnyRef): Int = xs match { - case x: Array[AnyRef] => x.length - case x: Array[Int] => x.length - case x: Array[Double] => x.length - case x: Array[Long] => x.length - case x: Array[Float] => x.length - case x: Array[Char] => x.length - case x: Array[Byte] => x.length - case x: Array[Short] => x.length - case x: Array[Boolean] => x.length - case x: Array[Unit] => x.length - case null => throw new NullPointerException - } - - def array_clone(xs: AnyRef): AnyRef = xs match { - case x: Array[AnyRef] => ArrayRuntime.cloneArray(x) - case x: Array[Int] => ArrayRuntime.cloneArray(x) - case x: Array[Double] => ArrayRuntime.cloneArray(x) - case x: Array[Long] => ArrayRuntime.cloneArray(x) - case x: Array[Float] => ArrayRuntime.cloneArray(x) - case x: Array[Char] => ArrayRuntime.cloneArray(x) - case x: Array[Byte] => ArrayRuntime.cloneArray(x) - case x: Array[Short] => ArrayRuntime.cloneArray(x) - case x: Array[Boolean] => ArrayRuntime.cloneArray(x) - case x: Array[Unit] => x - case null => throw new NullPointerException - } - - /** Convert an array to an object array. - * Needed to deal with vararg arguments of primitive types that are passed - * to a generic Java vararg parameter T ... - */ - def toObjectArray(src: AnyRef): Array[Object] = src match { - case x: Array[AnyRef] => x - case _ => - val length = array_length(src) - val dest = new Array[Object](length) - for (i <- 0 until length) - array_update(dest, i, array_apply(src, i)) - dest - } - - def toArray[T](xs: scala.collection.Seq[T]) = { - val arr = new Array[AnyRef](xs.length) - var i = 0 - for (x <- xs) { - arr(i) = x.asInstanceOf[AnyRef] - i += 1 - } - arr - } - - // Java bug: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4071957 - // More background at ticket #2318. - def ensureAccessible(m: JMethod): JMethod = { - if (!m.isAccessible) { - try m setAccessible true - catch { case _: SecurityException => () } - } - m - } - - def checkInitialized[T <: AnyRef](x: T): T = - if (x == null) throw new UninitializedError else x - - def _toString(x: Product): String = - x.productIterator.mkString(x.productPrefix + "(", ",", ")") - - def _hashCode(x: Product): Int = scala.util.hashing.MurmurHash3.productHash(x) - - /** A helper for case classes. */ - def typedProductIterator[T](x: Product): Iterator[T] = { - new AbstractIterator[T] { - private var c: Int = 0 - private val cmax = x.productArity - def hasNext = c < cmax - def next() = { - val result = x.productElement(c) - c += 1 - result.asInstanceOf[T] - } - } - } - - /** Fast path equality method for inlining; used when -optimise is set. - */ - @inline def inlinedEquals(x: Object, y: Object): Boolean = - if (x eq y) true - else if (x eq null) false - else if (x.isInstanceOf[java.lang.Number]) BoxesRunTime.equalsNumObject(x.asInstanceOf[java.lang.Number], y) - else if (x.isInstanceOf[java.lang.Character]) BoxesRunTime.equalsCharObject(x.asInstanceOf[java.lang.Character], y) - else x.equals(y) - - def _equals(x: Product, y: Any): Boolean = y match { - case y: Product if x.productArity == y.productArity => x.productIterator sameElements y.productIterator - case _ => false - } - - // hashcode ----------------------------------------------------------- - // - // Note that these are the implementations called by ##, so they - // must not call ## themselves. - - def hash(x: Any): Int = - if (x == null) 0 - else if (x.isInstanceOf[java.lang.Number]) BoxesRunTime.hashFromNumber(x.asInstanceOf[java.lang.Number]) - else x.hashCode - - def hash(dv: Double): Int = { - val iv = dv.toInt - if (iv == dv) return iv - - val lv = dv.toLong - if (lv == dv) return lv.hashCode - - val fv = dv.toFloat - if (fv == dv) fv.hashCode else dv.hashCode - } - def hash(fv: Float): Int = { - val iv = fv.toInt - if (iv == fv) return iv - - val lv = fv.toLong - if (lv == fv) return hash(lv) - else fv.hashCode - } - def hash(lv: Long): Int = { - val low = lv.toInt - val lowSign = low >>> 31 - val high = (lv >>> 32).toInt - low ^ (high + lowSign) - } - def hash(x: Number): Int = runtime.BoxesRunTime.hashFromNumber(x) - - // The remaining overloads are here for completeness, but the compiler - // inlines these definitions directly so they're not generally used. - def hash(x: Int): Int = x - def hash(x: Short): Int = x.toInt - def hash(x: Byte): Int = x.toInt - def hash(x: Char): Int = x.toInt - def hash(x: Boolean): Int = if (x) true.hashCode else false.hashCode - def hash(x: Unit): Int = 0 - - /** A helper method for constructing case class equality methods, - * because existential types get in the way of a clean outcome and - * it's performing a series of Any/Any equals comparisons anyway. - * See ticket #2867 for specifics. - */ - def sameElements(xs1: scala.collection.Seq[Any], xs2: scala.collection.Seq[Any]) = xs1 sameElements xs2 - - /** Given any Scala value, convert it to a String. - * - * The primary motivation for this method is to provide a means for - * correctly obtaining a String representation of a value, while - * avoiding the pitfalls of naïvely calling toString on said value. - * In particular, it addresses the fact that (a) toString cannot be - * called on null and (b) depending on the apparent type of an - * array, toString may or may not print it in a human-readable form. - * - * @param arg the value to stringify - * @return a string representation of arg. - */ - def stringOf(arg: Any): String = stringOf(arg, scala.Int.MaxValue) - def stringOf(arg: Any, maxElements: Int): String = { - def packageOf(x: AnyRef) = x.getClass.getPackage match { - case null => "" - case p => p.getName - } - def isScalaClass(x: AnyRef) = packageOf(x) startsWith "scala." - def isScalaCompilerClass(x: AnyRef) = packageOf(x) startsWith "scala.tools.nsc." - - // When doing our own iteration is dangerous - def useOwnToString(x: Any) = x match { - // Node extends NodeSeq extends Seq[Node] and MetaData extends Iterable[MetaData] - case _: Node | _: MetaData => true - // Range/NumericRange have a custom toString to avoid walking a gazillion elements - case _: Range | _: NumericRange[_] => true - // Sorted collections to the wrong thing (for us) on iteration - ticket #3493 - case _: Sorted[_, _] => true - // StringBuilder(a, b, c) and similar not so attractive - case _: StringLike[_] => true - // Don't want to evaluate any elements in a view - case _: TraversableView[_, _] => true - // Don't want to a) traverse infinity or b) be overly helpful with peoples' custom - // collections which may have useful toString methods - ticket #3710 - // or c) print AbstractFiles which are somehow also Iterable[AbstractFile]s. - case x: Traversable[_] => !x.hasDefiniteSize || !isScalaClass(x) || isScalaCompilerClass(x) - // Otherwise, nothing could possibly go wrong - case _ => false - } - - // A variation on inner for maps so they print -> instead of bare tuples - def mapInner(arg: Any): String = arg match { - case (k, v) => inner(k) + " -> " + inner(v) - case _ => inner(arg) - } - - // Special casing Unit arrays, the value class which uses a reference array type. - def arrayToString(x: AnyRef) = { - if (x.getClass.getComponentType == classOf[BoxedUnit]) - 0 until (array_length(x) min maxElements) map (_ => "()") mkString ("Array(", ", ", ")") - else - WrappedArray make x take maxElements map inner mkString ("Array(", ", ", ")") - } - - // The recursively applied attempt to prettify Array printing. - // Note that iterator is used if possible and foreach is used as a - // last resort, because the parallel collections "foreach" in a - // random order even on sequences. - def inner(arg: Any): String = arg match { - case null => "null" - case "" => "\"\"" - case x: String => if (x.head.isWhitespace || x.last.isWhitespace) "\"" + x + "\"" else x - case x if useOwnToString(x) => x.toString - case x: AnyRef if isArray(x) => arrayToString(x) - case x: scala.collection.Map[_, _] => x.iterator take maxElements map mapInner mkString (x.stringPrefix + "(", ", ", ")") - case x: Iterable[_] => x.iterator take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")") - case x: Traversable[_] => x take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")") - case x: Product1[_] if isTuple(x) => "(" + inner(x._1) + ",)" // that special trailing comma - case x: Product if isTuple(x) => x.productIterator map inner mkString ("(", ",", ")") - case x => x.toString - } - - // The try/catch is defense against iterables which aren't actually designed - // to be iterated, such as some scala.tools.nsc.io.AbstractFile derived classes. - try inner(arg) - catch { - case _: StackOverflowError | _: UnsupportedOperationException | _: AssertionError => "" + arg - } - } - - /** stringOf formatted for use in a repl result. */ - def replStringOf(arg: Any, maxElements: Int): String = { - val s = stringOf(arg, maxElements) - val nl = if (s contains "\n") "\n" else "" - - nl + s + "\n" - } - private[scala] def checkZip(what: String, coll1: TraversableOnce[_], coll2: TraversableOnce[_]) { - if (System.getProperty("scala.debug.zip") != null) { - val xs = coll1.toIndexedSeq - val ys = coll2.toIndexedSeq - if (xs.length != ys.length) { - Console.err.println( - "Mismatched zip in " + what + ":\n" + - " this: " + xs.mkString(", ") + "\n" + - " that: " + ys.mkString(", ") - ) - (new Exception).getStackTrace.drop(2).take(10).foreach(println) - } - } - } -} diff --git a/scripts/publish.sh b/scripts/publish.sh index e28ab6788e..946042c45e 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -7,14 +7,16 @@ else CMD="echo sbt" fi -FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.10.7 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.11.12 2.12.1 2.12.2 2.12.3 2.12.4 2.13.0-M2" -BIN_VERSIONS="2.10.7 2.11.12 2.12.4 2.13.0-M2" +FULL_VERSIONS="2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.11.12 2.12.1 2.12.2 2.12.3 2.12.4 2.13.0-M2" +BIN_VERSIONS="2.11.12 2.12.4 2.13.0-M2" +JVM_BIN_VERSIONS="2.10.7 2.11.12 2.12.4 2.13.0-M2" SBT_VERSION="2.10.7" SBT1_VERSION="2.12.4" SBT1_SBTVERSION="1.0.0" COMPILER="compiler jUnitPlugin" -LIBS="library ir irJS tools toolsJS jsEnvs jsEnvsTestKit nodeJSEnv testAdapter stubs testInterface jUnitRuntime" +LIBS="library irJS toolsJS testInterface jUnitRuntime" +JVM_LIBS="ir tools jsEnvs jsEnvsTestKit nodeJSEnv testAdapter stubs" # Publish compiler for v in $FULL_VERSIONS; do @@ -34,6 +36,15 @@ for v in $BIN_VERSIONS; do $CMD $ARGS done +# Publish JVM libraries +for v in $JVM_BIN_VERSIONS; do + ARGS="++$v" + for p in $JVM_LIBS; do + ARGS="$ARGS $p/publishSigned" + done + $CMD $ARGS +done + # Publish sbt-plugin $CMD "++$SBT_VERSION" "sbtPlugin/publishSigned" $CMD "++$SBT1_VERSION" "^^$SBT1_SBTVERSION" "sbtPlugin/publishSigned" diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/Compat210.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/Compat210.scala deleted file mode 100644 index 117be3fbe9..0000000000 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/Compat210.scala +++ /dev/null @@ -1,30 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ -package org.scalajs.testsuite - -private[testsuite] object Compat210 { - object blackbox { - type Context = scala.reflect.macros.Context - } -} - -import Compat210._ - -private[testsuite] trait Compat210Component { - // Import macros only here, otherwise we collide with the above - import scala.reflect.macros._ - import blackbox.Context - - val c: Context - - import c.universe._ - - implicit final class ContextCompat(self: c.type) { - def typecheck(tree: Tree): Tree = c.typeCheck(tree) - } -} diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/Typechecking.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/Typechecking.scala index 326a8b52e8..8cf50a9d1d 100644 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/Typechecking.scala +++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/Typechecking.scala @@ -9,12 +9,7 @@ package org.scalajs.testsuite import scala.language.experimental.macros -import Compat210._ - object Typechecking { - import scala.reflect.macros._ - import blackbox.Context - def typeError(code: String): Unit = macro TypecheckingMacros.typeError def typeErrorWithMsg(code: String, msg: String): Unit = macro TypecheckingMacros.typeErrorWithMsg diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/TypecheckingMacros.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/TypecheckingMacros.scala index 76b8fcf860..1e734620a0 100644 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/TypecheckingMacros.scala +++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/TypecheckingMacros.scala @@ -7,13 +7,11 @@ \* */ package org.scalajs.testsuite -import Compat210._ +import scala.reflect.macros.TypecheckException +import scala.reflect.macros.blackbox.Context object TypecheckingMacros { - import scala.reflect.macros._ - import blackbox.Context - - private class Macros[C <: Context](val c: C) extends Compat210Component { + private class Macros[C <: Context](val c: C) { import c.universe._ def typeError(code: String, expectedMsg: Option[String]): c.Expr[Unit] = { diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InstanceTestsHijackedBoxedClassesTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InstanceTestsHijackedBoxedClassesTest.scala index c40f8e0823..d3e1bf99a4 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InstanceTestsHijackedBoxedClassesTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InstanceTestsHijackedBoxedClassesTest.scala @@ -84,13 +84,13 @@ class InstanceTestsHijackedBoxedClassesTest { swallow((684321L: Any).asInstanceOf[Long]) swallow((3.14f: Any).asInstanceOf[Float]) swallow((3.14: Any).asInstanceOf[Double]) - if (!scalaVersion.startsWith("2.10.") && !scalaVersion.startsWith("2.11.")) + if (!scalaVersion.startsWith("2.11.")) (12345: Any).asInstanceOf[Unit] } @Test def should_support_asInstanceOf_negative(): Unit = { assumeTrue("Assumed compliant asInstanceOf", hasCompliantAsInstanceOfs) - if (scalaVersion.startsWith("2.10.") || scalaVersion.startsWith("2.11.")) + if (scalaVersion.startsWith("2.11.")) assertThrows(classOf[Exception], (12345: Any).asInstanceOf[Unit]) assertThrows(classOf[Exception], (12345: Any).asInstanceOf[Boolean]) assertThrows(classOf[Exception], (12345: Any).asInstanceOf[Char]) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala index f76904be74..0a97286f62 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala @@ -507,39 +507,6 @@ class OptimizerTest { object OptimizerTest { - import scala.collection.mutable.BitSet - - implicit class BitSet210Compat(val self: BitSet) extends AnyVal { - private def assert210(): Unit = - assert(scalaVersion.startsWith("2.10.")) - - def |=(that: BitSet): BitSet = { - assert210() - self ++= that - } - - def &=(that: BitSet): BitSet = { - assert210() - for (elem <- self) { - if (!that.contains(elem)) - self -= elem - } - self - } - - def ^=(that: BitSet): BitSet = { - assert210() - val result = self ^ that - self.clear() - self ++= result - } - - def &~=(that: BitSet): BitSet = { - assert210() - self --= that - } - } - @inline class InlineClassDependentFields(val x: Int) { val b = x > 3 diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ArrayTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ArrayTest.scala index a4b967ab33..b293a3f6df 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ArrayTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ArrayTest.scala @@ -85,8 +85,7 @@ class ArrayTest { assertJSArrayEquals(js.Array(1, 2, 3), Iterator(1, 2, 3).toJSArray) assertJSArrayEquals(js.Array(0.3, 7.3, 8.9), Array(0.3, 7.3, 8.9).toJSArray) assertJSArrayEquals(js.Array(), None.toJSArray) - // The following fails on 2.10.x - //assertJSArrayEquals(js.Array("Hello World"), Some("Hello World").toJSArray) + assertJSArrayEquals(js.Array("Hello World"), Some("Hello World").toJSArray) } } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala index 630f870772..18ed653ac8 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala @@ -276,7 +276,7 @@ object JSOptionalTest { trait OverrideOptionalWithOptionalImplicitType extends TraitWithOptional { /* Unlike cases where the rhs is an Int, String, etc., this compiles even - * in 2.10 and 2.11, because the inferred type is `js.UndefOr[Nothing]` + * in 2.11, because the inferred type is `js.UndefOr[Nothing]` * (the type of `js.undefined`) which is truly a subtype of the inherited * member's type `js.UndefOr[Int/String]`. Note that in this case, it * would be impossible to re-override these fields with a diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala index d0551048eb..5373d8af75 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala @@ -320,9 +320,10 @@ object JSSymbolTest { def iterateIterable[A](iterable: JSIterable[A])(f: A => Any): Unit = { val iterator = iterable.iterator() def loop(): Unit = { + import js.DynamicImplicits.truthValue + val entry = iterator.next() - // 2.10 didn't like the use of DynamicImplicits on the following line - if (!entry.done.asInstanceOf[Boolean]) { + if (!entry.done) { f(entry.value.asInstanceOf[A]) loop() } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala index c3249b1f43..88f5b407db 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala @@ -89,11 +89,9 @@ class SpecialTest { @Test def globalThis_can_be_used_to_detect_the_global_object(): Unit = { val globalObject = { import js.Dynamic.{global => g} - // We've got to use selectDynamic explicitly not to crash Scala 2.10 - if (js.typeOf(g.selectDynamic("global")) != "undefined" && - (g.selectDynamic("global").selectDynamic("Object") eq g.selectDynamic("Object"))) { + if (js.typeOf(g.global) != "undefined" && (g.global.Object eq g.Object)) { // Node.js environment detected - g.selectDynamic("global") + g.global } else { // In all other well-known environment, we can use the global `this` js.special.globalThis.asInstanceOf[js.Dynamic] diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTest.scala index a07db54556..12c8b2d1d9 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTest.scala @@ -171,11 +171,9 @@ class UndefOrTest { assertEquals("yes", none orElse some("yes")) assertJSUndefined(none orElse none) - /* #2095 - * Scala 2.10 requires the type ascriptions (see also UndefOrTestRequire211) - */ - assertEquals("ok", some("ok") orElse ("yes": js.UndefOr[String])) - assertEquals("yes", none orElse ("yes": js.UndefOr[String])) + // #2095 + assertEquals("ok", some("ok") orElse "yes") + assertEquals("yes", none orElse "yes") } @Test def toList(): Unit = { diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTestRequire211.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTestRequire211.scala deleted file mode 100644 index 94d33c6907..0000000000 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTestRequire211.scala +++ /dev/null @@ -1,31 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ -package org.scalajs.testsuite.jsinterop - -import scala.scalajs.js - -import org.junit.Assert._ -import org.junit.Test - -import org.scalajs.testsuite.utils.AssertThrows._ -import org.scalajs.testsuite.utils.JSAssert._ - -class UndefOrTestRequire211 { - - def some[A](v: A): js.UndefOr[A] = v - def none[A]: js.UndefOr[A] = js.undefined - - // scala.scalajs.js.UndefOr[A] - - @Test def orElse(): Unit = { - // #2095 - assertEquals("ok", some("ok") orElse "yes") - assertEquals("yes", none orElse "yes") - } - -} diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/JSUtils.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/JSUtils.scala index 49dc072c6d..3124b11132 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/JSUtils.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/JSUtils.scala @@ -9,11 +9,9 @@ object JSUtils { /** The detected global object. */ val globalObject: js.Dynamic = { import js.Dynamic.{global => g} - // We've got to use selectDynamic explicitly not to crash Scala 2.10 - if (js.typeOf(g.selectDynamic("global")) != "undefined" && - (g.selectDynamic("global").selectDynamic("Object") eq g.selectDynamic("Object"))) { + if (js.typeOf(g.global) != "undefined" && (g.global.Object eq g.Object)) { // Node.js environment detected - g.selectDynamic("global") + g.global } else { // In all other well-known environment, we can use the global `this` js.special.globalThis.asInstanceOf[js.Dynamic] diff --git a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/compiler/DefaultMethodsTest.scala b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/compiler/DefaultMethodsTest.scala index 0610f03a21..5db773265e 100644 --- a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/compiler/DefaultMethodsTest.scala +++ b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/compiler/DefaultMethodsTest.scala @@ -19,7 +19,7 @@ class DefaultMethodsTest { @Test def canOverrideDefaultMethod(): Unit = { assumeFalse("Affected by https://github.com/scala/bug/issues/10609", - executingInJVM && (scalaVersion == "2.10.7" || scalaVersion == "2.11.12")) + executingInJVM && scalaVersion == "2.11.12") var counter = 0 diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/IntTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/IntTest.scala index 70c2e7d13b..137d6c7cf9 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/IntTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/IntTest.scala @@ -336,10 +336,8 @@ class IntTest { test(MaxVal, 1, MaxVal >>> 1) } - private def scalacCorrectlyHandlesIntShiftLong: Boolean = { - import Platform.scalaVersion - !(scalaVersion.startsWith("2.10.") || scalaVersion.startsWith("2.11.")) - } + private def scalacCorrectlyHandlesIntShiftLong: Boolean = + !Platform.scalaVersion.startsWith("2.11.") @Test def intShiftLeftLongConstantFolded(): Unit = { assumeTrue("scalac must correctly handle int shift long", diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/LongTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/LongTest.scala index 6de701d502..27b9b9527e 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/LongTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/LongTest.scala @@ -266,9 +266,8 @@ class LongTest { assertEquals(1910653900, 9863155567412L.##) assertEquals(1735398658, 3632147899696541255L.##) - // These two (correctly) give different results on 2.10 and 2.11 - //assertEquals(-825638905, 613354684553L.##) // xx06 on 2.10 - //assertEquals(-1689438124, 7632147899696541255L.##) // xx25 on 2.10 + assertEquals(-825638905, 613354684553L.##) + assertEquals(-1689438124, 7632147899696541255L.##) } @Test def `should_have_correct_hash_in_case_classes`(): Unit = { diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/MatchTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/MatchTest.scala index 1eb475b16f..dc0dfd3773 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/MatchTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/MatchTest.scala @@ -68,7 +68,7 @@ class MatchTest { val foo: Option[Int] = Some(42) /* This match generates a value class boxing operation in the matchEnd (in - * 2.10 and 2.11). + * 2.11). */ val result = "foo = " ++ (foo match { case Some(0) => "zero" case _ => "unknown" }) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala index 5d9cfa9df2..87f15ed370 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala @@ -485,8 +485,7 @@ class RegressionTest { def getNull(): Any = null val x = getNull().asInstanceOf[Unit]: Any - val scalaVersion = Platform.scalaVersion - if (scalaVersion.startsWith("2.10.") || scalaVersion.startsWith("2.11.")) { + if (Platform.scalaVersion.startsWith("2.11.")) { assertNull(x.asInstanceOf[AnyRef]) } else { // As of Scala 2.12.0-M5, null.asInstanceOf[Unit] (correctly) returns () @@ -529,12 +528,7 @@ class RegressionTest { private val hasEqEqJLFloatDoubleBug: Boolean = { val v = Platform.scalaVersion - - { - v.startsWith("2.10.") || - v.startsWith("2.11.") || - v == "2.12.1" - } + v.startsWith("2.11.") || v == "2.12.1" } def assertTrueUnlessEqEqJLFloatDoubleBug(actual: Boolean): Unit = { diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ClassTagTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ClassTagTest.scala index 52dc119499..df2f9b4485 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ClassTagTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ClassTagTest.scala @@ -104,8 +104,7 @@ class ClassTagTest { @Test def classTagBasedPatternMatchingOfPrimitives(): Unit = { assumeFalse( "ClassTag.unapply only deals correctly with primitives since 2.11.2", - scalaVersion.startsWith("2.10.") || - (scalaVersion == "2.11.0" || scalaVersion == "2.11.1")) + scalaVersion == "2.11.0" || scalaVersion == "2.11.1") def test[A: ClassTag](x: Any): Boolean = x match { case x: A => true diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/RangesTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/RangesTest.scala index cdcd78a3a1..8673d9bc26 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/RangesTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/RangesTest.scala @@ -42,8 +42,6 @@ class RangesTest { } @Test def NumericRange_overflow_issue_2407(): Unit = { - assumeFalse("Assumed not on JVM for 2.10.X", - executingInJVM && scalaVersion.startsWith("2.10.")) assumeFalse("Assumed not on JVM for 2.11.{0-7}", executingInJVM && (0 to 7).map("2.11." + _).contains(scalaVersion)) val nr = NumericRange(Int.MinValue, Int.MaxValue, 1 << 23) @@ -51,8 +49,6 @@ class RangesTest { } @Test def Range_foreach_issue_2409(): Unit = { - assumeFalse("Assumed not on JVM for 2.10.X", - executingInJVM && scalaVersion.startsWith("2.10.")) assumeFalse("Assumed not on JVM for 2.11.{0-7}", executingInJVM && (0 to 7).map("2.11." + _).contains(scalaVersion)) val r = Int.MinValue to Int.MaxValue by (1 << 23) @@ -64,7 +60,7 @@ class RangesTest { } @Test def Range_toString_issue_2412(): Unit = { - if (scalaVersion.startsWith("2.10.") || scalaVersion.startsWith("2.11.")) { + if (scalaVersion.startsWith("2.11.")) { assertEquals("Range(1, 3, 5, 7, 9)", (1 to 10 by 2).toString) assertEquals("Range()", (1 until 1 by 2).toString) assertTrue((0.0 to 1.0).toString.startsWith("scala.collection.immutable.Range$Partial")) @@ -78,7 +74,7 @@ class RangesTest { } @Test def NumericRange_toString_issue_2412(): Unit = { - if (scalaVersion.startsWith("2.10.") || scalaVersion.startsWith("2.11.")) { + if (scalaVersion.startsWith("2.11.")) { assertEquals("NumericRange(0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6, 0.7, " + "0.7999999999999999, 0.8999999999999999, 0.9999999999999999)", (0.1 to 1.0 by 0.1).toString()) @@ -106,8 +102,6 @@ class RangesTest { @Test def NumericRange_with_arbitrary_integral(): Unit = { // This is broken in Scala JVM up to (including) 2.11.8, 2.12.1 (SI-10086). - assumeFalse("Assumed not on JVM for 2.10.X", - executingInJVM && scalaVersion.startsWith("2.10.")) assumeFalse("Assumed not on JVM for 2.11.{0-8}", executingInJVM && (0 to 8).map("2.11." + _).contains(scalaVersion)) assumeFalse("Assumed not on JVM for 2.12.{0-1}", diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala index 774458466a..19c92f37e6 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala @@ -615,14 +615,14 @@ abstract class GenIncOptimizer private[optimizer] (config: CommonPhaseConfig) { case Block(stats) => stats.forall(isElidableStat) case Assign(Select(This(), _), rhs) => isTriviallySideEffectFree(rhs) - // Mixin constructor, 2.10/2.11 + // Mixin constructor, 2.11 case ApplyStatic(ClassType(cls), methodName, List(This())) => statics(cls).methods(methodName.name).originalDef.body.exists { case Skip() => true case _ => false } - // Mixin constructor, 2.12 + // Mixin constructor, 2.12+ case ApplyStatically(This(), ClassType(cls), methodName, Nil) if !classes.contains(cls) => // Since cls is not in classes, it must be a default method call. From 0ae28b1c22bff3a4e0f84a925b835c456bfe24c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 26 Dec 2017 13:33:32 +0100 Subject: [PATCH 0596/2665] Ensure that we have SAM support in our library. We do this by adding the `-Xexperimental` flag when we compile under 2.11. --- .../main/scala/java/util/Collections.scala | 2 +- .../src/main/scala/scala/scalajs/js/Any.scala | 62 +++++++------------ .../scala/scala/scalajs/js/ThisFunction.scala | 47 +++++++------- project/Build.scala | 10 +++ 4 files changed, 56 insertions(+), 65 deletions(-) diff --git a/javalib/src/main/scala/java/util/Collections.scala b/javalib/src/main/scala/java/util/Collections.scala index 40e9934a7f..219b2ac224 100644 --- a/javalib/src/main/scala/java/util/Collections.scala +++ b/javalib/src/main/scala/java/util/Collections.scala @@ -740,7 +740,7 @@ object Collections { private trait WrappedSortedMap[K, V] extends WrappedMap[K, V, SortedMap[K, V]] with SortedMap[K, V] { def comparator(): Comparator[_ >: K] = - inner.comparator + inner.comparator() def subMap(fromKey: K, toKey: K): SortedMap[K, V] = inner.subMap(fromKey, toKey) diff --git a/library/src/main/scala/scala/scalajs/js/Any.scala b/library/src/main/scala/scala/scalajs/js/Any.scala index 2f33fa7b93..daef8d82da 100644 --- a/library/src/main/scala/scala/scalajs/js/Any.scala +++ b/library/src/main/scala/scala/scalajs/js/Any.scala @@ -102,45 +102,29 @@ object Any extends js.LowPrioAnyImplicits { // scalastyle:off line.size.limit - /* identity() is important! It prevents the tail-rec treatment in the absence - * of SAM treatment. - * - * When compiling without SAM treatment, the implicit expansion results in a - * self-recursive call to the implicit conversion. Without `identity()`, this - * recursive call is in tail position, and the tailcalls phase will convert - * it into an infinite loop. - * - * With `identity()`, the recursive call is not in tail position. The - * back-end therefore receives a call to the implicit conversion, *which is - * a primitive*, and therefore applies its primitive treatment, - * short-circuiting the infinite recursion. - * - * With proper SAM treatment, none of this happens, since there is no - * implicit materialization of a recursive call in the first place. - */ - implicit def fromFunction0[R](f: scala.Function0[R]): js.Function0[R] = identity(() => f()) - implicit def fromFunction1[T1, R](f: scala.Function1[T1, R]): js.Function1[T1, R] = identity((x1: T1) => f(x1)) - implicit def fromFunction2[T1, T2, R](f: scala.Function2[T1, T2, R]): js.Function2[T1, T2, R] = identity((x1: T1, x2: T2) => f(x1, x2)) - implicit def fromFunction3[T1, T2, T3, R](f: scala.Function3[T1, T2, T3, R]): js.Function3[T1, T2, T3, R] = identity((x1: T1, x2: T2, x3: T3) => f(x1, x2, x3)) - implicit def fromFunction4[T1, T2, T3, T4, R](f: scala.Function4[T1, T2, T3, T4, R]): js.Function4[T1, T2, T3, T4, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4) => f(x1, x2, x3, x4)) - implicit def fromFunction5[T1, T2, T3, T4, T5, R](f: scala.Function5[T1, T2, T3, T4, T5, R]): js.Function5[T1, T2, T3, T4, T5, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5) => f(x1, x2, x3, x4, x5)) - implicit def fromFunction6[T1, T2, T3, T4, T5, T6, R](f: scala.Function6[T1, T2, T3, T4, T5, T6, R]): js.Function6[T1, T2, T3, T4, T5, T6, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6) => f(x1, x2, x3, x4, x5, x6)) - implicit def fromFunction7[T1, T2, T3, T4, T5, T6, T7, R](f: scala.Function7[T1, T2, T3, T4, T5, T6, T7, R]): js.Function7[T1, T2, T3, T4, T5, T6, T7, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7) => f(x1, x2, x3, x4, x5, x6, x7)) - implicit def fromFunction8[T1, T2, T3, T4, T5, T6, T7, T8, R](f: scala.Function8[T1, T2, T3, T4, T5, T6, T7, T8, R]): js.Function8[T1, T2, T3, T4, T5, T6, T7, T8, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8) => f(x1, x2, x3, x4, x5, x6, x7, x8)) - implicit def fromFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R](f: scala.Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R]): js.Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9)) - implicit def fromFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R](f: scala.Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R]): js.Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)) - implicit def fromFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R](f: scala.Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R]): js.Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)) - implicit def fromFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R](f: scala.Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R]): js.Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12)) - implicit def fromFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R](f: scala.Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R]): js.Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13)) - implicit def fromFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R](f: scala.Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R]): js.Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14)) - implicit def fromFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R](f: scala.Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R]): js.Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15)) - implicit def fromFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R](f: scala.Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R]): js.Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16)) - implicit def fromFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R](f: scala.Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R]): js.Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17)) - implicit def fromFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R](f: scala.Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R]): js.Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18)) - implicit def fromFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R](f: scala.Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R]): js.Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19)) - implicit def fromFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R](f: scala.Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R]): js.Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20)) - implicit def fromFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R](f: scala.Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R]): js.Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20, x21: T21) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21)) - implicit def fromFunction22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R](f: scala.Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R]): js.Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20, x21: T21, x22: T22) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22)) + implicit def fromFunction0[R](f: scala.Function0[R]): js.Function0[R] = () => f() + implicit def fromFunction1[T1, R](f: scala.Function1[T1, R]): js.Function1[T1, R] = (x1: T1) => f(x1) + implicit def fromFunction2[T1, T2, R](f: scala.Function2[T1, T2, R]): js.Function2[T1, T2, R] = (x1: T1, x2: T2) => f(x1, x2) + implicit def fromFunction3[T1, T2, T3, R](f: scala.Function3[T1, T2, T3, R]): js.Function3[T1, T2, T3, R] = (x1: T1, x2: T2, x3: T3) => f(x1, x2, x3) + implicit def fromFunction4[T1, T2, T3, T4, R](f: scala.Function4[T1, T2, T3, T4, R]): js.Function4[T1, T2, T3, T4, R] = (x1: T1, x2: T2, x3: T3, x4: T4) => f(x1, x2, x3, x4) + implicit def fromFunction5[T1, T2, T3, T4, T5, R](f: scala.Function5[T1, T2, T3, T4, T5, R]): js.Function5[T1, T2, T3, T4, T5, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5) => f(x1, x2, x3, x4, x5) + implicit def fromFunction6[T1, T2, T3, T4, T5, T6, R](f: scala.Function6[T1, T2, T3, T4, T5, T6, R]): js.Function6[T1, T2, T3, T4, T5, T6, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6) => f(x1, x2, x3, x4, x5, x6) + implicit def fromFunction7[T1, T2, T3, T4, T5, T6, T7, R](f: scala.Function7[T1, T2, T3, T4, T5, T6, T7, R]): js.Function7[T1, T2, T3, T4, T5, T6, T7, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7) => f(x1, x2, x3, x4, x5, x6, x7) + implicit def fromFunction8[T1, T2, T3, T4, T5, T6, T7, T8, R](f: scala.Function8[T1, T2, T3, T4, T5, T6, T7, T8, R]): js.Function8[T1, T2, T3, T4, T5, T6, T7, T8, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8) => f(x1, x2, x3, x4, x5, x6, x7, x8) + implicit def fromFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R](f: scala.Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R]): js.Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9) + implicit def fromFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R](f: scala.Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R]): js.Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) + implicit def fromFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R](f: scala.Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R]): js.Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11) + implicit def fromFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R](f: scala.Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R]): js.Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12) + implicit def fromFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R](f: scala.Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R]): js.Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13) + implicit def fromFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R](f: scala.Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R]): js.Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14) + implicit def fromFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R](f: scala.Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R]): js.Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) + implicit def fromFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R](f: scala.Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R]): js.Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16) + implicit def fromFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R](f: scala.Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R]): js.Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17) + implicit def fromFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R](f: scala.Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R]): js.Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18) + implicit def fromFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R](f: scala.Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R]): js.Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19) + implicit def fromFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R](f: scala.Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R]): js.Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20) + implicit def fromFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R](f: scala.Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R]): js.Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20, x21: T21) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21) + implicit def fromFunction22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R](f: scala.Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R]): js.Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20, x21: T21, x22: T22) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22) implicit def toFunction0[R](f: js.Function0[R]): scala.Function0[R] = () => f() implicit def toFunction1[T1, R](f: js.Function1[T1, R]): scala.Function1[T1, R] = (x1) => f(x1) diff --git a/library/src/main/scala/scala/scalajs/js/ThisFunction.scala b/library/src/main/scala/scala/scalajs/js/ThisFunction.scala index ecd3d63285..7aca78fee2 100644 --- a/library/src/main/scala/scala/scalajs/js/ThisFunction.scala +++ b/library/src/main/scala/scala/scalajs/js/ThisFunction.scala @@ -27,31 +27,28 @@ trait ThisFunction extends js.Function object ThisFunction { // scalastyle:off line.size.limit - /* identity() is important! It prevents the tail-rec treatment in the absence - * of SAM treatment. See js.Any.fromFunctionN for more details. - */ - implicit def fromFunction1[T1, R](f: scala.Function1[T1, R]): js.ThisFunction0[T1, R] = identity((x1: T1) => f(x1)) - implicit def fromFunction2[T1, T2, R](f: scala.Function2[T1, T2, R]): js.ThisFunction1[T1, T2, R] = identity((x1: T1, x2: T2) => f(x1, x2)) - implicit def fromFunction3[T1, T2, T3, R](f: scala.Function3[T1, T2, T3, R]): js.ThisFunction2[T1, T2, T3, R] = identity((x1: T1, x2: T2, x3: T3) => f(x1, x2, x3)) - implicit def fromFunction4[T1, T2, T3, T4, R](f: scala.Function4[T1, T2, T3, T4, R]): js.ThisFunction3[T1, T2, T3, T4, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4) => f(x1, x2, x3, x4)) - implicit def fromFunction5[T1, T2, T3, T4, T5, R](f: scala.Function5[T1, T2, T3, T4, T5, R]): js.ThisFunction4[T1, T2, T3, T4, T5, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5) => f(x1, x2, x3, x4, x5)) - implicit def fromFunction6[T1, T2, T3, T4, T5, T6, R](f: scala.Function6[T1, T2, T3, T4, T5, T6, R]): js.ThisFunction5[T1, T2, T3, T4, T5, T6, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6) => f(x1, x2, x3, x4, x5, x6)) - implicit def fromFunction7[T1, T2, T3, T4, T5, T6, T7, R](f: scala.Function7[T1, T2, T3, T4, T5, T6, T7, R]): js.ThisFunction6[T1, T2, T3, T4, T5, T6, T7, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7) => f(x1, x2, x3, x4, x5, x6, x7)) - implicit def fromFunction8[T1, T2, T3, T4, T5, T6, T7, T8, R](f: scala.Function8[T1, T2, T3, T4, T5, T6, T7, T8, R]): js.ThisFunction7[T1, T2, T3, T4, T5, T6, T7, T8, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8) => f(x1, x2, x3, x4, x5, x6, x7, x8)) - implicit def fromFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R](f: scala.Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R]): js.ThisFunction8[T1, T2, T3, T4, T5, T6, T7, T8, T9, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9)) - implicit def fromFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R](f: scala.Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R]): js.ThisFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)) - implicit def fromFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R](f: scala.Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R]): js.ThisFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)) - implicit def fromFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R](f: scala.Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R]): js.ThisFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12)) - implicit def fromFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R](f: scala.Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R]): js.ThisFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13)) - implicit def fromFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R](f: scala.Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R]): js.ThisFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14)) - implicit def fromFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R](f: scala.Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R]): js.ThisFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15)) - implicit def fromFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R](f: scala.Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R]): js.ThisFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16)) - implicit def fromFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R](f: scala.Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R]): js.ThisFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17)) - implicit def fromFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R](f: scala.Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R]): js.ThisFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18)) - implicit def fromFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R](f: scala.Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R]): js.ThisFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19)) - implicit def fromFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R](f: scala.Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R]): js.ThisFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20)) - implicit def fromFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R](f: scala.Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R]): js.ThisFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20, x21: T21) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21)) - implicit def fromFunction22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R](f: scala.Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R]): js.ThisFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20, x21: T21, x22: T22) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22)) + implicit def fromFunction1[T1, R](f: scala.Function1[T1, R]): js.ThisFunction0[T1, R] = (x1: T1) => f(x1) + implicit def fromFunction2[T1, T2, R](f: scala.Function2[T1, T2, R]): js.ThisFunction1[T1, T2, R] = (x1: T1, x2: T2) => f(x1, x2) + implicit def fromFunction3[T1, T2, T3, R](f: scala.Function3[T1, T2, T3, R]): js.ThisFunction2[T1, T2, T3, R] = (x1: T1, x2: T2, x3: T3) => f(x1, x2, x3) + implicit def fromFunction4[T1, T2, T3, T4, R](f: scala.Function4[T1, T2, T3, T4, R]): js.ThisFunction3[T1, T2, T3, T4, R] = (x1: T1, x2: T2, x3: T3, x4: T4) => f(x1, x2, x3, x4) + implicit def fromFunction5[T1, T2, T3, T4, T5, R](f: scala.Function5[T1, T2, T3, T4, T5, R]): js.ThisFunction4[T1, T2, T3, T4, T5, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5) => f(x1, x2, x3, x4, x5) + implicit def fromFunction6[T1, T2, T3, T4, T5, T6, R](f: scala.Function6[T1, T2, T3, T4, T5, T6, R]): js.ThisFunction5[T1, T2, T3, T4, T5, T6, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6) => f(x1, x2, x3, x4, x5, x6) + implicit def fromFunction7[T1, T2, T3, T4, T5, T6, T7, R](f: scala.Function7[T1, T2, T3, T4, T5, T6, T7, R]): js.ThisFunction6[T1, T2, T3, T4, T5, T6, T7, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7) => f(x1, x2, x3, x4, x5, x6, x7) + implicit def fromFunction8[T1, T2, T3, T4, T5, T6, T7, T8, R](f: scala.Function8[T1, T2, T3, T4, T5, T6, T7, T8, R]): js.ThisFunction7[T1, T2, T3, T4, T5, T6, T7, T8, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8) => f(x1, x2, x3, x4, x5, x6, x7, x8) + implicit def fromFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R](f: scala.Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R]): js.ThisFunction8[T1, T2, T3, T4, T5, T6, T7, T8, T9, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9) + implicit def fromFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R](f: scala.Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R]): js.ThisFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) + implicit def fromFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R](f: scala.Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R]): js.ThisFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11) + implicit def fromFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R](f: scala.Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R]): js.ThisFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12) + implicit def fromFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R](f: scala.Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R]): js.ThisFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13) + implicit def fromFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R](f: scala.Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R]): js.ThisFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14) + implicit def fromFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R](f: scala.Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R]): js.ThisFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) + implicit def fromFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R](f: scala.Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R]): js.ThisFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16) + implicit def fromFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R](f: scala.Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R]): js.ThisFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17) + implicit def fromFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R](f: scala.Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R]): js.ThisFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18) + implicit def fromFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R](f: scala.Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R]): js.ThisFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19) + implicit def fromFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R](f: scala.Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R]): js.ThisFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20) + implicit def fromFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R](f: scala.Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R]): js.ThisFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20, x21: T21) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21) + implicit def fromFunction22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R](f: scala.Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R]): js.ThisFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R] = (x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20, x21: T21, x22: T22) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22) implicit def toFunction1[T1, R](f: js.ThisFunction0[T1, R]): scala.Function1[T1, R] = (x1) => f(x1) implicit def toFunction2[T1, T2, R](f: js.ThisFunction1[T1, T2, R]): scala.Function2[T1, T2, R] = (x1, x2) => f(x1, x2) diff --git a/project/Build.scala b/project/Build.scala index cc75b15cec..ff1a19c277 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -827,6 +827,13 @@ object Build { else Seq("-Ydelambdafy:method")) } + lazy val ensureSAMSupportSetting: Setting[_] = { + scalacOptions ++= { + if (scalaBinaryVersion.value == "2.11") Seq("-Xexperimental") + else Nil + } + } + private def serializeHardcodedIR(base: File, classDef: ir.Trees.ClassDef): File = { // We assume that there are no weird characters in the full name @@ -850,6 +857,7 @@ object Build { name := "java.lang library for Scala.js", publishArtifact in Compile := false, delambdafySetting, + ensureSAMSupportSetting, noClassFilesSettings, resourceGenerators in Compile += Def.task { @@ -867,6 +875,7 @@ object Build { name := "Java library for Scala.js", publishArtifact in Compile := false, delambdafySetting, + ensureSAMSupportSetting, noClassFilesSettings, scalaJSExternalCompileSettings ).withScalaJSCompiler.dependsOnLibraryNoJar @@ -1032,6 +1041,7 @@ object Build { fatalWarningsSettings, name := "Scala.js library", delambdafySetting, + ensureSAMSupportSetting, exportJars := !isGeneratingEclipse, previousArtifactSetting, mimaBinaryIssueFilters ++= BinaryIncompatibilities.Library, From c714de3e67e1be2e14c3ddff5e00ef8a0c397101 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 26 Dec 2017 20:54:20 +0100 Subject: [PATCH 0597/2665] User-space implementation of `js.{Any,ThisFunction}.fromFunctionN`. Previously, those methods were primitives. They did have a user- space body, but it was not used. This was done because most JS functions were the result of applying those implicit conversions. However, now that we have SAM support in all the versions of Scala for our library, we can get away without them being primitives. If the user's codebase has SAM support, this commit changes virtually nothing. If it doesn't (it uses Scala 2.11 without `-Xexperimental`), then this commit produces slightly worse code than before (there is a useless double-box of functions), but it is still correct. If we assume that most end-user codebases should use Scala 2.12 anyway, we are not losing much. We could also improve the optimizer to remove the double-box in the future, if necessary. This commit does not do that, however. --- ci/checksizes.sh | 2 +- .../org/scalajs/core/compiler/GenJSCode.scala | 88 +------------------ .../scalajs/core/compiler/JSDefinitions.scala | 6 -- .../scalajs/core/compiler/JSPrimitives.scala | 21 +---- .../core/compiler/test/OptimizationTest.scala | 28 ------ 5 files changed, 5 insertions(+), 140 deletions(-) diff --git a/ci/checksizes.sh b/ci/checksizes.sh index 7b2e3ef62c..f9a38671c2 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -34,7 +34,7 @@ REVERSI_OPT_GZ_SIZE=$(stat '-c%s' "$REVERSI_OPT.gz") case $FULLVER in 2.11.12) - REVERSI_PREOPT_EXPECTEDSIZE=507000 + REVERSI_PREOPT_EXPECTEDSIZE=508000 REVERSI_OPT_EXPECTEDSIZE=116000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=69000 REVERSI_OPT_GZ_EXPECTEDSIZE=30000 diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 337e481cfd..c49e51b7f1 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -1491,8 +1491,7 @@ abstract class GenJSCode extends plugins.PluginComponent mutable = false, rest = false) } - if (scalaPrimitives.isPrimitive(sym) && - !jsPrimitives.shouldEmitPrimitiveBody(sym)) { + if (scalaPrimitives.isPrimitive(sym)) { None } else if (isAbstractMethod(dd)) { val body = if (scalaUsesImplClasses && @@ -2807,15 +2806,6 @@ abstract class GenJSCode extends plugins.PluginComponent * asInstanceOf to a raw JS type is completely erased. */ value - } else if (FunctionClass.seq contains to.typeSymbol) { - /* Don't hide a JSFunctionToScala inside a useless cast, otherwise - * the optimization avoiding double-wrapping in genApply() will not - * be able to kick in. - */ - value match { - case JSFunctionToScala(fun, _) => value - case _ => default - } } else if (sym == NullClass) { js.If( js.BinaryOp(js.BinaryOp.===, value, js.Null()), @@ -4137,63 +4127,7 @@ abstract class GenJSCode extends plugins.PluginComponent } case List(arg) => - - /** Factorization of F2JS and F2JSTHIS. */ - def genFunctionToJSFunction(isThisFunction: Boolean): js.Tree = { - val arity = { - val funName = tree.fun.symbol.name.encoded - assert(funName.startsWith("fromFunction")) - funName.stripPrefix("fromFunction").toInt - } - val inputClass = FunctionClass(arity) - val inputIRType = encodeClassType(inputClass) - val applyMeth = getMemberMethod(inputClass, nme.apply) suchThat { s => - val ps = s.paramss - ps.size == 1 && - ps.head.size == arity && - ps.head.forall(_.tpe.typeSymbol == ObjectClass) - } - val fCaptureParam = js.ParamDef(js.Ident("f"), inputIRType, - mutable = false, rest = false) - val jsArity = - if (isThisFunction) arity - 1 - else arity - val jsParams = (1 to jsArity).toList map { - x => js.ParamDef(js.Ident("arg"+x), jstpe.AnyType, - mutable = false, rest = false) - } - js.Closure( - List(fCaptureParam), - jsParams, - genApplyMethod( - fCaptureParam.ref, - applyMeth, - if (isThisFunction) - js.This()(jstpe.AnyType) :: jsParams.map(_.ref) - else - jsParams.map(_.ref)), - List(arg)) - } - code match { - /** Convert a scala.FunctionN f to a js.FunctionN. */ - case F2JS => - arg match { - /* This case will happen every time we have a Scala lambda - * in js.FunctionN position. We remove the JS function to - * Scala function wrapper, instead of adding a Scala function - * to JS function wrapper. - */ - case JSFunctionToScala(fun, arity) => - fun - case _ => - genFunctionToJSFunction(isThisFunction = false) - } - - /** Convert a scala.FunctionN f to a js.ThisFunction{N-1}. */ - case F2JSTHIS => - genFunctionToJSFunction(isThisFunction = true) - case TYPEOF => // js.typeOf(arg) genAsInstanceOf(js.JSUnaryOp(js.JSUnaryOp.typeof, arg), @@ -4807,14 +4741,12 @@ abstract class GenJSCode extends plugins.PluginComponent // scalastyle:on return } - /** Constructor and extractor object for a tree that converts a JavaScript - * function into a Scala function. + /** Constructor object for a tree that converts a JavaScript function into + * a Scala function. */ private object JSFunctionToScala { private val AnonFunPrefScala = "scala.scalajs.runtime.AnonFunction" - private val AnonFunPrefJS = - "sjsr_AnonFunction" def apply(jsFunction: js.Tree, arity: Int)( implicit pos: Position): js.Tree = { @@ -4822,20 +4754,6 @@ abstract class GenJSCode extends plugins.PluginComponent val ctor = clsSym.tpe.member(nme.CONSTRUCTOR) genNew(clsSym, ctor, List(jsFunction)) } - - def unapply(tree: js.New): Option[(js.Tree, Int)] = tree match { - case js.New(jstpe.ClassType(wrapperName), _, List(fun)) - if wrapperName.startsWith(AnonFunPrefJS) => - val arityStr = wrapperName.substring(AnonFunPrefJS.length) - try { - Some((fun, arityStr.toInt)) - } catch { - case e: NumberFormatException => None - } - - case _ => - None - } } /** Gen JS code for a raw JS function class. diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 74f16f8007..5f7fbc5f2a 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -78,9 +78,6 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val JSFunctionTpes = JSFunctionClasses.map(_.toTypeConstructor) - lazy val JSAnyModule = JSAnyClass.companionModule - def JSAny_fromFunction(arity: Int): TermSymbol = getMemberMethod(JSAnyModule, newTermName("fromFunction"+arity)) - lazy val JSDynamicModule = JSDynamicClass.companionModule lazy val JSDynamic_newInstance = getMemberMethod(JSDynamicModule, newTermName("newInstance")) lazy val JSDynamicLiteral = getMemberModule(JSDynamicModule, newTermName("literal")) @@ -90,9 +87,6 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val JSArrayModule = JSArrayClass.companionModule lazy val JSArray_create = getMemberMethod(JSArrayModule, newTermName("apply")) - lazy val JSThisFunctionModule = JSThisFunctionClass.companionModule - def JSThisFunction_fromFunction(arity: Int): TermSymbol = getMemberMethod(JSThisFunctionModule, newTermName("fromFunction"+arity)) - lazy val JSConstructorTagModule = getRequiredModule("scala.scalajs.js.ConstructorTag") lazy val JSConstructorTag_materialize = getMemberMethod(JSConstructorTagModule, newTermName("materialize")) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala index 99701f6928..609db6b5a4 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala @@ -31,10 +31,7 @@ abstract class JSPrimitives { val FirstJSPrimitiveCode = 300 - val F2JS = FirstJSPrimitiveCode + 1 // FunctionN to js.FunctionN - val F2JSTHIS = F2JS + 1 // FunctionN to js.ThisFunction{N-1} - - val DYNNEW = F2JSTHIS + 1 // Instantiate a new JavaScript object + val DYNNEW = FirstJSPrimitiveCode + 1 // Instantiate a new JavaScript object val ARR_CREATE = DYNNEW + 1 // js.Array.apply (array literal syntax) @@ -71,25 +68,9 @@ abstract class JSPrimitives { def isJavaScriptPrimitive(sym: Symbol): Boolean = scalaJSPrimitives.contains(sym) - /** For a primitive, is it one for which we should emit its body anyway? */ - def shouldEmitPrimitiveBody(sym: Symbol): Boolean = { - /* No @switch because some Scala 2.11 versions erroneously report a - * warning for switch matches with less than 3 non-default cases. - */ - scalaPrimitives.getPrimitive(sym) match { - case F2JS | F2JSTHIS => true - case _ => false - } - } - private val scalaJSPrimitives = mutable.Map.empty[Symbol, Int] private def initWithPrimitives(addPrimitive: (Symbol, Int) => Unit): Unit = { - for (i <- 0 to 22) - addPrimitive(JSAny_fromFunction(i), F2JS) - for (i <- 1 to 22) - addPrimitive(JSThisFunction_fromFunction(i), F2JSTHIS) - addPrimitive(JSDynamic_newInstance, DYNNEW) addPrimitive(JSArray_create, ARR_CREATE) diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala index 1acdadd6cc..4f113e2cf3 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala @@ -8,34 +8,6 @@ import org.scalajs.core.ir.{Trees => js, Types => jstpe} class OptimizationTest extends JSASTTest { - @Test - def unwrapScalaFunWrapper: Unit = { - // Make sure we do not wrap and unwrap right away - """ - import scala.scalajs.js - - class A { - val jsFun: js.Function = (x: Int) => x * 2 - } - """. - hasNot("runtime.AnonFunction ctor") { - case js.New(jstpe.ClassType("sjsr_AnonFunction1"), _, _) => - } - - // Make sure our wrapper matcher has the right name - """ - import scala.scalajs.js - - class A { - val scalaFun = (x: Int) => x * 2 - val jsFun: js.Function = scalaFun - } - """. - has("runtime.AnonFunction ctor") { - case js.New(jstpe.ClassType("sjsr_AnonFunction1"), _, _) => - } - } - @Test def testJSArrayApplyOptimization: Unit = { /* Make sure js.Array(...) is optimized away completely for several kinds From 3345591218c251c19be33ec10332e6060c73567f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 26 Dec 2017 22:22:43 +0100 Subject: [PATCH 0598/2665] Remove the `js.Dynamic.x` workaround. The explicit presence of `x` in `js.Dynamic` was a workaround for the implicits in `Predef` that were accidentally providing `x` on `Any`. Since those implicits were removed in 2.11, and we do not support 2.10 anymore, we can remove the workaround. This surfaces a spectacular scalac bug in one of our tests, which I have not been able to minimize. The problem was already visible with `y` or any other field not named `x`, so the explicit `js.Dynamic.x` was hiding another bug. --- .../scalajs/core/compiler/PrepJSInterop.scala | 26 ------------------- .../main/scala/scala/scalajs/js/Dynamic.scala | 4 --- .../jsinterop/NonNativeJSTypeTest.scala | 12 ++++++++- 3 files changed, 11 insertions(+), 31 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index d9e6ad4633..f4657ac826 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -66,7 +66,6 @@ abstract class PrepJSInterop extends plugins.PluginComponent val hasNext = newTermName("hasNext") val next = newTermName("next") val nextName = newTermName("nextName") - val x = newTermName("x") val Value = newTermName("Value") val Val = newTermName("Val") @@ -334,29 +333,6 @@ abstract class PrepJSInterop extends plugins.PluginComponent EmptyTree } - // Fix for issue with calls to js.Dynamic.x() - // Rewrite (obj: js.Dynamic).x(...) to obj.applyDynamic("x")(...) - case Select(Select(trg, jsnme.x), nme.apply) if isJSDynamic(trg) => - val newTree = atPos(tree.pos) { - Apply( - Select(transform(trg), newTermName("applyDynamic")), - List(Literal(Constant("x"))) - ) - } - typer.typed(newTree, Mode.FUNmode, tree.tpe) - - - // Fix for issue with calls to js.Dynamic.x() - // Rewrite (obj: js.Dynamic).x to obj.selectDynamic("x") - case Select(trg, jsnme.x) if isJSDynamic(trg) => - val newTree = atPos(tree.pos) { - Apply( - Select(transform(trg), newTermName("selectDynamic")), - List(Literal(Constant("x"))) - ) - } - typer.typed(newTree, Mode.FUNmode, tree.tpe) - // Compile-time errors and warnings for js.Dynamic.literal case Apply(Apply(fun, nameArgs), args) if fun.symbol == JSDynamicLiteral_applyDynamic || @@ -1176,8 +1152,6 @@ abstract class PrepJSInterop extends plugins.PluginComponent private def isScalaEnum(implDef: ImplDef) = implDef.symbol.tpe.typeSymbol isSubClass ScalaEnumClass - private def isJSDynamic(tree: Tree) = tree.tpe.typeSymbol == JSDynamicClass - /** Tests whether the symbol has `private` in any form, either `private`, * `private[this]` or `private[Enclosing]`. */ diff --git a/library/src/main/scala/scala/scalajs/js/Dynamic.scala b/library/src/main/scala/scala/scalajs/js/Dynamic.scala index e23774a4ad..daf6579d0e 100644 --- a/library/src/main/scala/scala/scalajs/js/Dynamic.scala +++ b/library/src/main/scala/scala/scalajs/js/Dynamic.scala @@ -67,10 +67,6 @@ sealed trait Dynamic extends js.Any with scala.Dynamic { def &&(that: js.Dynamic): js.Dynamic = js.native def ||(that: js.Dynamic): js.Dynamic = js.native - - // Work around the annoying implicits in Predef in Scala 2.10. - def x: js.Dynamic = js.native - def x_=(value: js.Any): Unit = js.native } /** Factory for dynamically typed JavaScript values. */ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/NonNativeJSTypeTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/NonNativeJSTypeTest.scala index 5804627ecf..a1e74a4f27 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/NonNativeJSTypeTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/NonNativeJSTypeTest.scala @@ -1095,7 +1095,17 @@ class NonNativeJSTypeTest { assertJSArrayEquals(js.Array(8, 23), foo.args) val dyn = foo.asInstanceOf[js.Dynamic] - assertEquals(4, dyn.x) + /* Dark magic is at play here: everywhere else in this compilation unit, + * it's fine to do `assertEquals(4, dyn.x)` (for example, in the test + * `override_native_method` below), but right here, it causes scalac to die + * with a completely nonsensical compile error: + * + * > applyDynamic does not support passing a vararg parameter + * + * Extracting it in a separate `val` works around it. + */ + val dynx = dyn.x + assertEquals(4, dynx) val args = dyn.args.asInstanceOf[js.Array[Int]] assertJSArrayEquals(js.Array(8, 23), args) } From 2201ff9b82db54e50b7218384f58cac55c07a49b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 27 Dec 2017 16:07:13 +0100 Subject: [PATCH 0599/2665] Make the constructors and underlying vals of AnyVals private. Now that our JS artifacts do not need to be compiled with 2.10 anymore, we can truly make the underlying `val`s of `AnyVal`s private. In the process, we also ensure that their constructors are private. For implicit classes, the constructor must be `private[Enclosing]` because it is accessed by the automatically generated `implicit def` that comes with them. For our artifacts that still support 2.10, we also standardize on a `val __private_foo` to make it clear that they are not part of the API, even if the language prevents us from marking them as actually private. --- .../scalajs/core/compiler/PrepJSInterop.scala | 4 +- .../scala/org/scalajs/core/ir/Hashers.scala | 2 +- .../scala/org/scalajs/core/ir/Printers.scala | 2 +- .../org/scalajs/core/ir/Serializers.scala | 8 +-- .../scala/org/scalajs/core/ir/Trees.scala | 18 +++++-- .../src/main/scala/java/lang/StackTrace.scala | 2 +- .../src/main/scala/java/math/BigDecimal.scala | 2 +- .../src/main/scala/java/nio/GenBuffer.scala | 8 ++- .../scala/java/nio/GenDataViewBuffer.scala | 8 ++- .../main/scala/java/nio/GenHeapBuffer.scala | 8 ++- .../scala/java/nio/GenHeapBufferView.scala | 7 ++- .../scala/java/nio/GenTypedArrayBuffer.scala | 9 +++- .../src/main/scala/java/util/package.scala | 4 +- .../main/scala/org/scalajs/jsenv/Utils.scala | 6 ++- .../src/main/scala/scala/scalajs/js/Any.scala | 5 +- .../scala/scalajs/js/ConstructorTag.scala | 2 +- .../scala/scala/scalajs/js/Iterator.scala | 7 ++- .../scala/scala/scalajs/js/JSConverters.scala | 46 +++++++++++----- .../scala/scala/scalajs/js/JSNumberOps.scala | 4 +- .../scala/scala/scalajs/js/Thenable.scala | 5 +- .../scala/scala/scalajs/js/UndefOrOps.scala | 4 +- .../main/scala/scala/scalajs/js/Union.scala | 4 +- .../scalajs/js/typedarray/DataViewExt.scala | 5 +- .../js/typedarray/TypedArrayBufferOps.scala | 6 ++- .../scala/scalajs/js/typedarray/package.scala | 54 ++++++++++++++----- .../scalajs/testinterface/HTMLRunner.scala | 4 +- .../testsuite/jsinterop/ArrayTest.scala | 2 +- .../scalajs/testsuite/compiler/SAMTest.scala | 5 +- .../testsuite/compiler/MatchTest.scala | 2 +- .../compiler/ReflectiveCallTest.scala | 2 +- .../math/BigDecimalConstructorsTest.scala | 5 +- .../testsuite/javalib/util/package.scala | 4 +- .../niocharset/BaseCharsetTest.scala | 5 +- .../StandardLinkerPlatformExtensions.scala | 4 +- .../LinkerBackendPlatformExtensions.scala | 4 +- .../StandardLinkerPlatformExtensions.scala | 10 ++-- .../LinkerBackendPlatformExtensions.scala | 10 ++-- .../frontend/optimizer/ConcurrencyUtils.scala | 33 ++++++++---- .../linker/backend/emitter/TreeDSL.scala | 6 ++- .../core/tools/linker/checker/IRChecker.scala | 10 +++- .../core/tools/linker/frontend/Refiner.scala | 2 +- .../frontend/optimizer/OptimizerCore.scala | 15 ++++-- .../core/tools/linker/standard/package.scala | 10 ++-- 43 files changed, 268 insertions(+), 95 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index f4657ac826..2d13098db0 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -1413,7 +1413,9 @@ abstract class PrepJSInterop extends plugins.PluginComponent } object PrepJSInterop { - private final class OwnerKind(val baseKinds: Int) extends AnyVal { + private final class OwnerKind private (private val baseKinds: Int) + extends AnyVal { + import OwnerKind._ @inline def isBaseKind: Boolean = diff --git a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala index e9774067ef..6f5ad84d6f 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala @@ -22,7 +22,7 @@ object Hashers { hasher.mixParamDefs(args) hasher.mixType(resultType) body.foreach(hasher.mixTree) - hasher.mixInt(methodDef.optimizerHints.bits) + hasher.mixInt(OptimizerHints.toBits(methodDef.optimizerHints)) val hash = hasher.finalizeHash() diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index 538fa44156..444dde7833 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -1052,7 +1052,7 @@ object Printers { implicit dummy: DummyImplicit): Unit = { if (optimizerHints != OptimizerHints.empty) { print("@hints(") - print(optimizerHints.bits.toString) + print(OptimizerHints.toBits(optimizerHints).toString) print(") ") } } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index 7bc36ca7ed..8bc4ba429e 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -474,7 +474,7 @@ object Serializers { writeJSNativeLoadSpec(jsNativeLoadSpec) writeMemberDefs(memberDefs) writeTopLevelExportDefs(topLevelExportDefs) - writeInt(optimizerHints.bits) + writeInt(OptimizerHints.toBits(optimizerHints)) } def writeMemberDef(memberDef: MemberDef): Unit = { @@ -501,7 +501,7 @@ object Serializers { // Write out method def writeBoolean(static); writePropertyName(name) writeParamDefs(args); writeType(resultType); writeOptTree(body) - writeInt(methodDef.optimizerHints.bits) + writeInt(OptimizerHints.toBits(methodDef.optimizerHints)) // Jump back and write true length val length = bufferUnderlying.jumpBack() @@ -934,7 +934,7 @@ object Serializers { val jsNativeLoadSpec = readJSNativeLoadSpec() val memberDefs = readMemberDefs() val topLevelExportDefs = readTopLevelExportDefs() - val optimizerHints = new OptimizerHints(readInt()) + val optimizerHints = OptimizerHints.fromBits(readInt()) ClassDef(name, kind, jsClassCaptures, superClass, parents, jsSuperClass, jsNativeLoadSpec, memberDefs, topLevelExportDefs)( optimizerHints) @@ -957,7 +957,7 @@ object Serializers { assert(len >= 0) MethodDef(readBoolean(), readPropertyName(), readParamDefs(), readType(), readOptTree())( - new OptimizerHints(readInt()), optHash) + OptimizerHints.fromBits(readInt()), optHash) case TagPropertyDef => val static = readBoolean() diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 9d8cbdb3b9..74dcc6c877 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -994,9 +994,11 @@ object Trees { // Miscellaneous - final class OptimizerHints(val bits: Int) extends AnyVal { + final class OptimizerHints private (val __private_bits: Int) extends AnyVal { import OptimizerHints._ + @inline private def bits: Int = __private_bits + def inline: Boolean = (bits & InlineMask) != 0 def noinline: Boolean = (bits & NoinlineMask) != 0 @@ -1013,14 +1015,20 @@ object Trees { } object OptimizerHints { - final val InlineShift = 0 - final val InlineMask = 1 << InlineShift + private final val InlineShift = 0 + private final val InlineMask = 1 << InlineShift - final val NoinlineShift = 1 - final val NoinlineMask = 1 << NoinlineShift + private final val NoinlineShift = 1 + private final val NoinlineMask = 1 << NoinlineShift final val empty: OptimizerHints = new OptimizerHints(0) + + private[ir] def fromBits(bits: Int): OptimizerHints = + new OptimizerHints(bits) + + private[ir] def toBits(hints: OptimizerHints): Int = + hints.bits } /** Loading specification for a native JS class or object. */ diff --git a/javalanglib/src/main/scala/java/lang/StackTrace.scala b/javalanglib/src/main/scala/java/lang/StackTrace.scala index e2180fb01f..66f8d898b0 100644 --- a/javalanglib/src/main/scala/java/lang/StackTrace.scala +++ b/javalanglib/src/main/scala/java/lang/StackTrace.scala @@ -278,7 +278,7 @@ private[lang] object StackTrace { } } - private implicit class StringRE(val s: String) extends AnyVal { + private implicit class StringRE(private val s: String) extends AnyVal { def re: js.RegExp = new js.RegExp(s) def re(mods: String): js.RegExp = new js.RegExp(s, mods) } diff --git a/javalib/src/main/scala/java/math/BigDecimal.scala b/javalib/src/main/scala/java/math/BigDecimal.scala index e82430a9fe..3ec394a91c 100644 --- a/javalib/src/main/scala/java/math/BigDecimal.scala +++ b/javalib/src/main/scala/java/math/BigDecimal.scala @@ -281,7 +281,7 @@ object BigDecimal { insertString(s, pos, s2.substring(s2Start, s2Start + s2Len)) } - private implicit class StringOps(val s: String) extends AnyVal { + private implicit class StringOps(private val s: String) extends AnyVal { @inline def insert(pos: Int, s2: String): String = insertString(s, pos, s2) diff --git a/javalib/src/main/scala/java/nio/GenBuffer.scala b/javalib/src/main/scala/java/nio/GenBuffer.scala index 6f7d87f3a0..8c29652938 100644 --- a/javalib/src/main/scala/java/nio/GenBuffer.scala +++ b/javalib/src/main/scala/java/nio/GenBuffer.scala @@ -5,7 +5,13 @@ private[nio] object GenBuffer { new GenBuffer(self) } -private[nio] final class GenBuffer[B <: Buffer](val self: B) extends AnyVal { +/* The underlying `val self` is intentionally public because + * `self.ElementType` and `self.BufferType` appear in signatures. + * It's tolerable because the class is `private[nio]` anyway. + */ +private[nio] final class GenBuffer[B <: Buffer] private (val self: B) + extends AnyVal { + import self._ @inline diff --git a/javalib/src/main/scala/java/nio/GenDataViewBuffer.scala b/javalib/src/main/scala/java/nio/GenDataViewBuffer.scala index 172ea8fdc0..ec23df7cef 100644 --- a/javalib/src/main/scala/java/nio/GenDataViewBuffer.scala +++ b/javalib/src/main/scala/java/nio/GenDataViewBuffer.scala @@ -44,7 +44,13 @@ private[nio] object GenDataViewBuffer { } } -private[nio] final class GenDataViewBuffer[B <: Buffer](val self: B) extends AnyVal { +/* The underlying `val self` is intentionally public because + * `self.BufferType` appears in signatures. + * It's tolerable because the class is `private[nio]` anyway. + */ +private[nio] final class GenDataViewBuffer[B <: Buffer] private (val self: B) + extends AnyVal { + import self._ import GenDataViewBuffer.newDataView diff --git a/javalib/src/main/scala/java/nio/GenHeapBuffer.scala b/javalib/src/main/scala/java/nio/GenHeapBuffer.scala index 0deeacb256..d39ad7c51e 100644 --- a/javalib/src/main/scala/java/nio/GenHeapBuffer.scala +++ b/javalib/src/main/scala/java/nio/GenHeapBuffer.scala @@ -24,7 +24,13 @@ private[nio] object GenHeapBuffer { } } -private[nio] final class GenHeapBuffer[B <: Buffer](val self: B) extends AnyVal { +/* The underlying `val self` is intentionally public because + * `self.ElementType` and `self.BufferType` appear in signatures. + * It's tolerable because the class is `private[nio]` anyway. + */ +private[nio] final class GenHeapBuffer[B <: Buffer] private (val self: B) + extends AnyVal { + import self._ type NewThisHeapBuffer = GenHeapBuffer.NewHeapBuffer[BufferType, ElementType] diff --git a/javalib/src/main/scala/java/nio/GenHeapBufferView.scala b/javalib/src/main/scala/java/nio/GenHeapBufferView.scala index 8ef7206087..6977293cd5 100644 --- a/javalib/src/main/scala/java/nio/GenHeapBufferView.scala +++ b/javalib/src/main/scala/java/nio/GenHeapBufferView.scala @@ -25,7 +25,12 @@ private[nio] object GenHeapBufferView { } } -private[nio] final class GenHeapBufferView[B <: Buffer](val self: B) extends AnyVal { +/* The underlying `val self` is intentionally public because + * `self.BufferType` appears in signatures. + * It's tolerable because the class is `private[nio]` anyway. + */ +private[nio] final class GenHeapBufferView[B <: Buffer] private (val self: B) + extends AnyVal { import self._ type NewThisHeapBufferView = GenHeapBufferView.NewHeapBufferView[BufferType] diff --git a/javalib/src/main/scala/java/nio/GenTypedArrayBuffer.scala b/javalib/src/main/scala/java/nio/GenTypedArrayBuffer.scala index 347fbccd5f..ada8071b73 100644 --- a/javalib/src/main/scala/java/nio/GenTypedArrayBuffer.scala +++ b/javalib/src/main/scala/java/nio/GenTypedArrayBuffer.scala @@ -32,8 +32,13 @@ private[nio] object GenTypedArrayBuffer { } } -private[nio] final class GenTypedArrayBuffer[B <: Buffer]( - val self: B) extends AnyVal { +/* The underlying `val self` is intentionally public because + * `self.BufferType` appears in signatures. + * It's tolerable because the class is `private[nio]` anyway. + */ +private[nio] final class GenTypedArrayBuffer[B <: Buffer] private (val self: B) + extends AnyVal { + import self._ type NewThisTypedArrayBuffer = diff --git a/javalib/src/main/scala/java/util/package.scala b/javalib/src/main/scala/java/util/package.scala index c778fb8804..618e9fbecd 100644 --- a/javalib/src/main/scala/java/util/package.scala +++ b/javalib/src/main/scala/java/util/package.scala @@ -2,7 +2,9 @@ package java package object util { - implicit private[util] class CompareNullablesOps(val self: Any) extends AnyVal { + implicit private[util] class CompareNullablesOps(private val self: Any) + extends AnyVal { + @inline def ===(that: Any): Boolean = if (self.asInstanceOf[AnyRef] eq null) that.asInstanceOf[AnyRef] eq null diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/Utils.scala b/js-envs/src/main/scala/org/scalajs/jsenv/Utils.scala index b2431b44ad..6f921a5dde 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/Utils.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/Utils.scala @@ -13,7 +13,11 @@ import scala.concurrent.duration._ private[jsenv] object Utils { final class OptDeadline private ( - val deadline: Deadline /* nullable */) extends AnyVal { // scalastyle:ignore + val __private_deadline: Deadline /* nullable */) // scalastyle:ignore + extends AnyVal { + + @inline private def deadline: Deadline = __private_deadline + def millisLeft: Long = if (deadline == null) 0 else (deadline.timeLeft.toMillis max 1L) diff --git a/library/src/main/scala/scala/scalajs/js/Any.scala b/library/src/main/scala/scala/scalajs/js/Any.scala index daef8d82da..53d326703c 100644 --- a/library/src/main/scala/scala/scalajs/js/Any.scala +++ b/library/src/main/scala/scala/scalajs/js/Any.scala @@ -178,7 +178,10 @@ object Any extends js.LowPrioAnyImplicits { @inline implicit def fromJDouble(value: java.lang.Double): js.Any = value.asInstanceOf[js.Any] - implicit class ObjectCompanionOps(val __self: js.Object.type) extends AnyVal { + implicit class ObjectCompanionOps private[Any] ( + private val self: js.Object.type) + extends AnyVal { + /** Tests whether the specified object `o` has a property `p` on itself or * in its prototype chain. * diff --git a/library/src/main/scala/scala/scalajs/js/ConstructorTag.scala b/library/src/main/scala/scala/scalajs/js/ConstructorTag.scala index 1f0fec19ab..adb69c9230 100644 --- a/library/src/main/scala/scala/scalajs/js/ConstructorTag.scala +++ b/library/src/main/scala/scala/scalajs/js/ConstructorTag.scala @@ -20,7 +20,7 @@ import scala.scalajs.js * type argument to `js.constructorOf`. */ final class ConstructorTag[T <: js.Any] private[scalajs] ( - val constructor: js.Dynamic) + val constructor: js.Dynamic) // intentionally public extends AnyVal { /** Instantiates the class `T` with the specified arguments. diff --git a/library/src/main/scala/scala/scalajs/js/Iterator.scala b/library/src/main/scala/scala/scalajs/js/Iterator.scala index be17d1ef6a..816323164c 100644 --- a/library/src/main/scala/scala/scalajs/js/Iterator.scala +++ b/library/src/main/scala/scala/scalajs/js/Iterator.scala @@ -45,8 +45,11 @@ object Iterator { } } - final implicit class IteratorOps[A](val __self: js.Iterator[A]) extends AnyVal { + final implicit class IteratorOps[A] private[Iterator] ( + private val self: js.Iterator[A]) + extends AnyVal { + @inline - def toIterator: scala.collection.Iterator[A] = new WrappedIterator(__self) + def toIterator: scala.collection.Iterator[A] = new WrappedIterator(self) } } diff --git a/library/src/main/scala/scala/scalajs/js/JSConverters.scala b/library/src/main/scala/scala/scalajs/js/JSConverters.scala index 56ac3866c6..1f5c0ace52 100644 --- a/library/src/main/scala/scala/scalajs/js/JSConverters.scala +++ b/library/src/main/scala/scala/scalajs/js/JSConverters.scala @@ -24,7 +24,7 @@ sealed abstract class JSConvertersLowPrioImplicits { @inline implicit def JSRichFutureNonThenable[A](f: Future[A]): JSRichFuture[A] = - new JSRichFuture[A](f) + newJSRichFuture[A](f) } @@ -33,13 +33,18 @@ sealed abstract class JSConvertersLowPrioImplicits { */ object JSConverters extends js.JSConvertersLowPrioImplicits { - implicit class JSRichOption[T](val opt: Option[T]) extends AnyVal { + implicit class JSRichOption[T] private[JSConverters] ( + private val opt: Option[T]) + extends AnyVal { + @inline final def orUndefined: js.UndefOr[T] = opt.fold[js.UndefOr[T]](undefined)(v => v) } - implicit class JSRichGenTraversableOnce[T]( - val col: GenTraversableOnce[T]) extends AnyVal { + implicit class JSRichGenTraversableOnce[T] private[JSConverters] ( + private val col: GenTraversableOnce[T]) + extends AnyVal { + final def toJSArray: js.Array[T] = { /* This is basically a duplicate of `runtime.genTraversableOnce2jsArray`, * except it is not marked `@inline`. We do not want to inline this @@ -64,14 +69,18 @@ object JSConverters extends js.JSConvertersLowPrioImplicits { } } - implicit class JSRichGenIterable[T]( - val __self: GenIterable[T]) extends AnyVal { - @inline final def toJSIterable: js.Iterable[T] = new IterableAdapter(__self) + implicit class JSRichGenIterable[T] private[JSConverters] ( + private val self: GenIterable[T]) + extends AnyVal { + + @inline final def toJSIterable: js.Iterable[T] = new IterableAdapter(self) } - implicit class JSRichIterator[T]( - val __self: scala.collection.Iterator[T]) extends AnyVal { - @inline final def toJSIterator: js.Iterator[T] = new IteratorAdapter(__self) + implicit class JSRichIterator[T] private[JSConverters] ( + private val self: scala.collection.Iterator[T]) + extends AnyVal { + + @inline final def toJSIterator: js.Iterator[T] = new IteratorAdapter(self) } private class IterableAdapter[+T](col: GenIterable[T]) extends js.Iterable[T] { @@ -98,7 +107,10 @@ object JSConverters extends js.JSConvertersLowPrioImplicits { } } - implicit class JSRichGenMap[T](val map: GenMap[String, T]) extends AnyVal { + implicit class JSRichGenMap[T] private[JSConverters] ( + private val map: GenMap[String, T]) + extends AnyVal { + @inline final def toJSDictionary: js.Dictionary[T] = { val result = js.Dictionary.empty[T] map.foreach { case (key, value) => result(key) = value } @@ -115,7 +127,17 @@ object JSConverters extends js.JSConvertersLowPrioImplicits { implicit def JSRichFutureThenable[A](f: Future[js.Thenable[A]]): JSRichFuture[A] = new JSRichFuture[A](f) - final class JSRichFuture[A](val self: Future[A | js.Thenable[A]]) extends AnyVal { + // For access in JSConvertersLowPrioImplicits + @inline + protected[this] def newJSRichFuture[A]( + f: Future[A | js.Thenable[A]]): JSRichFuture[A] = { + new JSRichFuture[A](f) + } + + final class JSRichFuture[A] private[JSConverters] ( + private val self: Future[A | js.Thenable[A]]) + extends AnyVal { + /** Converts the Future to a JavaScript [[Promise]]. * * Attention! The nature of the [[Promise]] class, from the ECMAScript diff --git a/library/src/main/scala/scala/scalajs/js/JSNumberOps.scala b/library/src/main/scala/scala/scalajs/js/JSNumberOps.scala index b81f18b0c7..8d9ba66eca 100644 --- a/library/src/main/scala/scala/scalajs/js/JSNumberOps.scala +++ b/library/src/main/scala/scala/scalajs/js/JSNumberOps.scala @@ -82,7 +82,9 @@ object JSNumberOps { implicit def enableJSNumberExtOps(x: Double): ExtOps = new ExtOps(x.asInstanceOf[js.Dynamic]) - final class ExtOps(val self: js.Dynamic) extends AnyVal { + final class ExtOps private[JSNumberOps] (private val self: js.Dynamic) + extends AnyVal { + @inline def toUint: Double = (self >>> 0.asInstanceOf[js.Dynamic]).asInstanceOf[Double] } diff --git a/library/src/main/scala/scala/scalajs/js/Thenable.scala b/library/src/main/scala/scala/scalajs/js/Thenable.scala index 9f92775b16..37f8759012 100644 --- a/library/src/main/scala/scala/scalajs/js/Thenable.scala +++ b/library/src/main/scala/scala/scalajs/js/Thenable.scala @@ -38,7 +38,10 @@ trait Thenable[+A] extends js.Object { } object Thenable { - implicit class ThenableOps[+A](val p: js.Thenable[A]) extends AnyVal { + implicit class ThenableOps[+A] private[Thenable] ( + private val p: js.Thenable[A]) + extends AnyVal { + /** Converts the [[Thenable]] into a Scala [[scala.concurrent.Future Future]]. * * Unlike when calling the `then` methods of [[Thenable]], the resulting diff --git a/library/src/main/scala/scala/scalajs/js/UndefOrOps.scala b/library/src/main/scala/scala/scalajs/js/UndefOrOps.scala index 96d050b133..4dd1151036 100644 --- a/library/src/main/scala/scala/scalajs/js/UndefOrOps.scala +++ b/library/src/main/scala/scala/scalajs/js/UndefOrOps.scala @@ -17,7 +17,9 @@ import scala.scalajs.js.|.Evidence /** @define option [[js.UndefOr]] * @define none [[js.undefined]] */ -final class UndefOrOps[A](val self: js.UndefOr[A]) extends AnyVal { +final class UndefOrOps[A] private[js] (private val self: js.UndefOr[A]) + extends AnyVal { + import UndefOrOps._ /** Returns true if the option is `undefined`, false otherwise. diff --git a/library/src/main/scala/scala/scalajs/js/Union.scala b/library/src/main/scala/scala/scalajs/js/Union.scala index 9acb1db808..2aaf940719 100644 --- a/library/src/main/scala/scala/scalajs/js/Union.scala +++ b/library/src/main/scala/scala/scalajs/js/Union.scala @@ -89,7 +89,9 @@ object | { // scalastyle:ignore a.asInstanceOf[F[B]] /** Operations on union types. */ - implicit class UnionOps[A <: _ | _](val self: A) extends AnyVal { + implicit class UnionOps[A <: _ | _] private[|] (private val self: A) + extends AnyVal { + /** Explicitly merge a union type to a supertype (which might not be a * union type itself). * diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/DataViewExt.scala b/library/src/main/scala/scala/scalajs/js/typedarray/DataViewExt.scala index 7a75e8b346..6f11134a4a 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/DataViewExt.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/DataViewExt.scala @@ -11,7 +11,10 @@ package scala.scalajs.js.typedarray /** Extensions for [[DataView]]. */ object DataViewExt { - implicit class DataViewExtOps(val dataView: DataView) extends AnyVal { + implicit class DataViewExtOps private[DataViewExt] ( + private val dataView: DataView) + extends AnyVal { + /** Reads a 2's complement signed 64-bit integers from the data view. * @param index Starting index * @param littleEndian Whether the number is stored in little endian diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/TypedArrayBufferOps.scala b/library/src/main/scala/scala/scalajs/js/typedarray/TypedArrayBufferOps.scala index 8e436707da..74ae4cc341 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/TypedArrayBufferOps.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/TypedArrayBufferOps.scala @@ -21,8 +21,10 @@ import java.nio._ * elements in the buffer. */ final class TypedArrayBufferOps[ // scalastyle:ignore - TypedArrayType <: TypedArray[_, TypedArrayType]]( - val buffer: Buffer) extends AnyVal { + TypedArrayType <: TypedArray[_, TypedArrayType]] private ( + private val buffer: Buffer) + extends AnyVal { + /** Tests whether this buffer has a valid associated [[ArrayBuffer]]. * * This is true iff the buffer is direct and not read-only. diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/package.scala b/library/src/main/scala/scala/scalajs/js/typedarray/package.scala index b150998c77..9810f041eb 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/package.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/package.scala @@ -14,42 +14,60 @@ package object typedarray { /** ECMAScript 6 * Adds `toTypedArray` conversion to an `Array[Byte]` */ - implicit class AB2TA(val array: scala.Array[Byte]) extends AnyVal { + implicit class AB2TA private[typedarray] ( + private val array: scala.Array[Byte]) + extends AnyVal { + def toTypedArray: Int8Array = byteArray2Int8Array(array) } /** ECMAScript 6 * Adds `toTypedArray` conversion to an `Array[Short]` */ - implicit class AS2TA(val array: scala.Array[Short]) extends AnyVal { + implicit class AS2TA private[typedarray] ( + private val array: scala.Array[Short]) + extends AnyVal { + def toTypedArray: Int16Array = shortArray2Int16Array(array) } /** ECMAScript 6 * Adds `toTypedArray` conversion to an `Array[Char]` */ - implicit class AC2TA(val array: scala.Array[Char]) extends AnyVal { + implicit class AC2TA private[typedarray] ( + private val array: scala.Array[Char]) + extends AnyVal { + def toTypedArray: Uint16Array = charArray2Uint16Array(array) } /** ECMAScript 6 * Adds `toTypedArray` conversion to an `Array[Int]` */ - implicit class AI2TA(val array: scala.Array[Int]) extends AnyVal { + implicit class AI2TA private[typedarray] ( + private val array: scala.Array[Int]) + extends AnyVal { + def toTypedArray: Int32Array = intArray2Int32Array(array) } /** ECMAScript 6 * Adds `toTypedArray` conversion to an `Array[Float]` */ - implicit class AF2TA(val array: scala.Array[Float]) extends AnyVal { + implicit class AF2TA private[typedarray] ( + private val array: scala.Array[Float]) + extends AnyVal { + def toTypedArray: Float32Array = floatArray2Float32Array(array) } /** ECMAScript 6 * Adds `toTypedArray` conversion to an `Array[Double]` */ - implicit class AD2TA(val array: scala.Array[Double]) extends AnyVal { + implicit class AD2TA private[typedarray] ( + private val array: scala.Array[Double]) + extends AnyVal { + def toTypedArray: Float64Array = doubleArray2Float64Array(array) } @@ -58,42 +76,54 @@ package object typedarray { /** ECMAScript 6 * Adds `toArray` conversion to a [[Int8Array]] */ - implicit class TA2AB(val array: Int8Array) extends AnyVal { + implicit class TA2AB private[typedarray] (private val array: Int8Array) + extends AnyVal { + def toArray: scala.Array[Byte] = int8Array2ByteArray(array) } /** ECMAScript 6 * Adds `toArray` conversion to a [[Int16Array]] */ - implicit class TA2AS(val array: Int16Array) extends AnyVal { + implicit class TA2AS private[typedarray] (private val array: Int16Array) + extends AnyVal { + def toArray: scala.Array[Short] = int16Array2ShortArray(array) } /** ECMAScript 6 * Adds `toArray` conversion to a [[Uint16Array]] */ - implicit class TA2AC(val array: Uint16Array) extends AnyVal { + implicit class TA2AC private[typedarray] (private val array: Uint16Array) + extends AnyVal { + def toArray: scala.Array[Char] = uint16Array2CharArray(array) } /** ECMAScript 6 * Adds `toArray` conversion to a [[Int32Array]] */ - implicit class TA2AI(val array: Int32Array) extends AnyVal { + implicit class TA2AI private[typedarray] (private val array: Int32Array) + extends AnyVal { + def toArray: scala.Array[Int] = int32Array2IntArray(array) } /** ECMAScript 6 * Adds `toArray` conversion to a [[Float32Array]] */ - implicit class TA2AF(val array: Float32Array) extends AnyVal { + implicit class TA2AF private[typedarray] (private val array: Float32Array) + extends AnyVal { + def toArray: scala.Array[Float] = float32Array2FloatArray(array) } /** ECMAScript 6 * Adds `toArray` conversion to a [[Float64Array]] */ - implicit class TA2AD(val array: Float64Array) extends AnyVal { + implicit class TA2AD private[typedarray] (private val array: Float64Array) + extends AnyVal { + def toArray: scala.Array[Double] = float64Array2DoubleArray(array) } diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala b/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala index fbd08ecf27..054d556406 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala @@ -473,7 +473,9 @@ protected[testinterface] object HTMLRunner { var search: String = js.native } - implicit class RichElement(val element: Element) extends AnyVal { + implicit class RichElement private[dom] (private val element: Element) + extends AnyVal { + def newElement(clss: String = "", text: String = "", tpe: String = "div"): dom.Element = { val el = document.createElement(tpe) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ArrayTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ArrayTest.scala index b293a3f6df..bb44f10d64 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ArrayTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ArrayTest.scala @@ -91,7 +91,7 @@ class ArrayTest { object ArrayTest { - private class VC(val x: Int) extends AnyVal { + private class VC(private val x: Int) extends AnyVal { override def toString(): String = s"VC($x)" } diff --git a/test-suite/shared/src/test/require-sam/org/scalajs/testsuite/compiler/SAMTest.scala b/test-suite/shared/src/test/require-sam/org/scalajs/testsuite/compiler/SAMTest.scala index 89500c31eb..abfd0b88af 100644 --- a/test-suite/shared/src/test/require-sam/org/scalajs/testsuite/compiler/SAMTest.scala +++ b/test-suite/shared/src/test/require-sam/org/scalajs/testsuite/compiler/SAMTest.scala @@ -110,7 +110,10 @@ object SAMTest { def apply(x: Int): String } - implicit class ComparatorCompat[A](val c: Comparator[A]) extends AnyVal { + implicit class ComparatorCompat[A] private[SAMTest] ( + private val c: Comparator[A]) + extends AnyVal { + def reversed(): Comparator[A] = { assumeTrue("Comparator.reversed() is not available on this JDK", false) ??? diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/MatchTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/MatchTest.scala index dc0dfd3773..fe0dafe7c4 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/MatchTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/MatchTest.scala @@ -95,7 +95,7 @@ object MatchTest { def f(): T } - class ValueClass(val x: Int) extends AnyVal with ValueClassBase[Int] { + class ValueClass(private val x: Int) extends AnyVal with ValueClassBase[Int] { def f(): Int = x * 2 } } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ReflectiveCallTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ReflectiveCallTest.scala index 4f87a8f975..dcd6f65d6a 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ReflectiveCallTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ReflectiveCallTest.scala @@ -463,7 +463,7 @@ class ReflectiveCallTest { } object ReflectiveCallTest { - class AnyValWithAnyRefPrimitiveMethods(val x: Int) extends AnyVal { + class AnyValWithAnyRefPrimitiveMethods(private val x: Int) extends AnyVal { def eq(that: AnyRef): Boolean = (x + 1) == that def ne(that: AnyRef): Boolean = (x + 1) != that def synchronized[T](f: T): Any = f + "there" diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalConstructorsTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalConstructorsTest.scala index cb3ac43474..fdbf6d8bae 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalConstructorsTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalConstructorsTest.scala @@ -479,7 +479,10 @@ class BigDecimalConstructorsTest { object BigDecimalConstructorsTest { // Helper for comparing values within a certain +/- delta - implicit class BigDecimalOps(val actual: BigDecimal) extends AnyVal { + implicit class BigDecimalOps private[BigDecimalConstructorsTest] ( + private val actual: BigDecimal) + extends AnyVal { + def minus(expected: BigDecimal): Double = { val actualDeltaDecimal:BigDecimal = actual.subtract(expected) val actualDelta = actualDeltaDecimal.abs().doubleValue() diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/package.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/package.scala index bb25a6847b..25b42793cd 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/package.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/package.scala @@ -9,7 +9,9 @@ package org.scalajs.testsuite.javalib package object util { - implicit private[util] class CompareNullablesOps(val self: Any) extends AnyVal { + implicit private[util] class CompareNullablesOps(private val self: Any) + extends AnyVal { + @inline def ===(that: Any): Boolean = if (self.asInstanceOf[AnyRef] eq null) that.asInstanceOf[AnyRef] eq null diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/BaseCharsetTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/BaseCharsetTest.scala index 35fcedf7a3..9b8147e74b 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/BaseCharsetTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/BaseCharsetTest.scala @@ -203,7 +203,10 @@ object BaseCharsetTest { BufferPart(buf) } - implicit class Interpolators(val sc: StringContext) extends AnyVal { + implicit class Interpolators private[BaseCharsetTest] ( + private val sc: StringContext) + extends AnyVal { + def bb(args: Any*): ByteBuffer = { val strings = sc.parts.iterator val expressions = args.iterator diff --git a/tools/js/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala b/tools/js/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala index af3e689ef7..32940c7d01 100644 --- a/tools/js/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala +++ b/tools/js/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala @@ -11,7 +11,9 @@ package org.scalajs.core.tools.linker object StandardLinkerPlatformExtensions { import StandardLinker.Config - final class ConfigExt(val config: Config) extends AnyVal { + final class ConfigExt private[linker] (private val self: Config) + extends AnyVal { + /** Whether to actually use the Google Closure Compiler pass. * * On the JavaScript platform, this always returns `false`, as GCC is not diff --git a/tools/js/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatformExtensions.scala b/tools/js/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatformExtensions.scala index 4c64b92d5a..b8359ced34 100644 --- a/tools/js/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatformExtensions.scala +++ b/tools/js/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatformExtensions.scala @@ -11,7 +11,9 @@ package org.scalajs.core.tools.linker.backend object LinkerBackendPlatformExtensions { import LinkerBackend.Config - final class ConfigExt(val config: Config) extends AnyVal { + final class ConfigExt private[backend] (private val self: Config) + extends AnyVal { + /** Whether to actually use the Google Closure Compiler pass. * * On the JavaScript platform, this always returns `false`, as GCC is not diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala index 58c6befd4b..7a130341b4 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala @@ -11,11 +11,15 @@ package org.scalajs.core.tools.linker object StandardLinkerPlatformExtensions { import StandardLinker.Config - final class ConfigExt(val config: Config) extends AnyVal { + final class ConfigExt private[linker] (val __private_self: Config) + extends AnyVal { + + @inline private def self: Config = __private_self + /** Whether to actually use the Google Closure Compiler pass. */ - def closureCompiler: Boolean = config.closureCompilerIfAvailable + def closureCompiler: Boolean = self.closureCompilerIfAvailable def withClosureCompiler(closureCompiler: Boolean): Config = - config.withClosureCompilerIfAvailable(closureCompiler) + self.withClosureCompilerIfAvailable(closureCompiler) } } diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatformExtensions.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatformExtensions.scala index d2578b9b3a..5310187546 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatformExtensions.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatformExtensions.scala @@ -13,11 +13,15 @@ import org.scalajs.core.tools.linker.backend.closure.ClosureLinkerBackend object LinkerBackendPlatformExtensions { import LinkerBackend.Config - final class ConfigExt(val config: Config) extends AnyVal { + final class ConfigExt private[backend] (val __private_self: Config) + extends AnyVal { + + @inline private def self: Config = __private_self + /** Whether to actually use the Google Closure Compiler pass. */ - def closureCompiler: Boolean = config.closureCompilerIfAvailable + def closureCompiler: Boolean = self.closureCompilerIfAvailable def withClosureCompiler(closureCompiler: Boolean): Config = - config.withClosureCompilerIfAvailable(closureCompiler) + self.withClosureCompilerIfAvailable(closureCompiler) } } diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ConcurrencyUtils.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ConcurrencyUtils.scala index c76941e04f..ba9bae6678 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ConcurrencyUtils.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ConcurrencyUtils.scala @@ -28,14 +28,19 @@ private[optimizer] object ConcurrencyUtils { new AtomicReference(l) } - implicit class AtomicAccOps[T](val acc: AtomicAcc[T]) extends AnyVal { - @inline final def size: Int = acc.get.size + implicit class AtomicAccOps[T] private[ConcurrencyUtils] ( + val __private_self: AtomicAcc[T]) + extends AnyVal { + + @inline private def self: AtomicAcc[T] = __private_self + + @inline final def size: Int = self.get.size @inline - final def +=(x: T): Unit = AtomicAccOps.append(acc, x) + final def +=(x: T): Unit = AtomicAccOps.append(self, x) @inline - final def removeAll(): List[T] = AtomicAccOps.removeAll(acc) + final def removeAll(): List[T] = AtomicAccOps.removeAll(self) } object AtomicAccOps { @@ -54,19 +59,29 @@ private[optimizer] object ConcurrencyUtils { type TrieSet[T] = TrieMap[T, Null] - implicit class TrieSetOps[T](val set: TrieSet[T]) extends AnyVal { - @inline final def +=(x: T): Unit = set.put(x, null) + implicit class TrieSetOps[T] private[ConcurrencyUtils] ( + val __private_self: TrieSet[T]) + extends AnyVal { + + @inline private def self: TrieSet[T] = __private_self + + @inline final def +=(x: T): Unit = self.put(x, null) } object TrieSet { @inline final def empty[T]: TrieSet[T] = TrieMap.empty } - implicit class TrieMapOps[K,V](val map: TrieMap[K,V]) extends AnyVal { + implicit class TrieMapOps[K, V] private[ConcurrencyUtils] ( + val __private_self: TrieMap[K, V]) + extends AnyVal { + + @inline private def self: TrieMap[K, V] = __private_self + @inline final def getOrPut(k: K, default: => V): V = { - map.get(k).getOrElse { + self.get(k).getOrElse { val v = default - map.putIfAbsent(k, v).getOrElse(v) + self.putIfAbsent(k, v).getOrElse(v) } } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/TreeDSL.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/TreeDSL.scala index 90a9a68709..da23d58d66 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/TreeDSL.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/TreeDSL.scala @@ -17,7 +17,11 @@ import org.scalajs.core.ir.Position import org.scalajs.core.tools.linker.backend.javascript.Trees._ private[emitter] object TreeDSL { - implicit class TreeOps(val self: Tree) extends AnyVal { + implicit class TreeOps private[TreeDSL] (val __private_self: Tree) + extends AnyVal { + + @inline private def self: Tree = __private_self + /** Select a member */ def DOT(field: Ident)(implicit pos: Position): DotSelect = DotSelect(self, field) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index ec0e616517..e7c1976bad 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -1394,9 +1394,12 @@ object IRChecker { * IR is invalid, so all bets are off and we can be slow and allocate stuff; * we don't care. */ - private final class ErrorContext private (val nodeOrLinkedClass: Any) + private final class ErrorContext private ( + val __private_nodeOrLinkedClass: Any) extends AnyVal { + @inline private def nodeOrLinkedClass: Any = __private_nodeOrLinkedClass + override def toString(): String = { val (pos, name) = nodeOrLinkedClass match { case tree: IRNode => (tree.pos, tree.getClass.getSimpleName) @@ -1421,9 +1424,12 @@ object IRChecker { val pos: Position) /** Enable the right-biased API of Either from 2.12 in earlier versions. */ - private implicit class RightBiasedEither[A, B](val self: Either[A, B]) + private implicit class RightBiasedEither[A, B]( + val __private_self: Either[A, B]) extends AnyVal { + @inline private def self: Either[A, B] = __private_self + def foreach[U](f: B => U): Unit = self match { case Left(_) => case Right(r) => f(r) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala index f91778a949..e771242692 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala @@ -209,7 +209,7 @@ private object Refiner { } } - private final class LinkedMembersInfosCache( + private final class LinkedMembersInfosCache private ( val caches: mutable.Map[(Boolean, String), LinkedMemberInfoCache]) extends AnyVal { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index eb82315424..4058a16374 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -4803,15 +4803,20 @@ private[optimizer] object OptimizerCore { } } - private implicit class OptimizerTreeOps(val selfTree: Tree) extends AnyVal { + private implicit class OptimizerTreeOps private[OptimizerCore] ( + val __private_self: Tree) + extends AnyVal { + + @inline private def self: Tree = __private_self + def toPreTransform: PreTransform = { - selfTree match { + self match { case UnaryOp(op, lhs) => - PreTransUnaryOp(op, lhs.toPreTransform)(selfTree.pos) + PreTransUnaryOp(op, lhs.toPreTransform)(self.pos) case BinaryOp(op, lhs, rhs) => - PreTransBinaryOp(op, lhs.toPreTransform, rhs.toPreTransform)(selfTree.pos) + PreTransBinaryOp(op, lhs.toPreTransform, rhs.toPreTransform)(self.pos) case _ => - PreTransTree(selfTree) + PreTransTree(self) } } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/package.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/package.scala index c2b62642fa..a37ea18ba3 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/package.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/package.scala @@ -9,15 +9,17 @@ package org.scalajs.core.tools.linker package object standard { - implicit class StandardLinkerConfigStandardOps( - val __self: StandardLinker.Config) extends AnyVal { + implicit class StandardLinkerConfigStandardOps private[standard] ( + val __private_self: StandardLinker.Config) extends AnyVal { import StandardLinker.Config + @inline private def self: Config = __private_self + /** Standard output mode. */ - def outputMode: OutputMode = __self.outputMode + def outputMode: OutputMode = self.outputMode def withOutputMode(outputMode: OutputMode): Config = - __self.withOutputMode(outputMode) + self.withOutputMode(outputMode) } } From a5317c3cb3cdaa833e877042453ed2ec0649976f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 29 Dec 2017 13:02:50 +0100 Subject: [PATCH 0600/2665] Remove `abstractMethods` from `LinkedClass`. That field was "dead code" (it was always an empty list), because the Analyzer never marks as reachable an abstract method. So all code paths that were processing reachable abstract methods were dead code. --- .../core/tools/linker/LinkedClass.scala | 8 ++--- .../core/tools/linker/checker/IRChecker.scala | 10 +++--- .../tools/linker/frontend/BaseLinker.scala | 33 ++++++++----------- .../core/tools/linker/frontend/Refiner.scala | 9 ----- 4 files changed, 20 insertions(+), 40 deletions(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala index d028674acf..698f14297f 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala @@ -20,9 +20,8 @@ import ir.Definitions /** A ClassDef after linking. * * Note that the [[version]] in the LinkedClass does not cover - * [[staticMethods]], [[memberMethods]], [[abstractMethods]] and - * [[exportedMembers]] as they have their individual versions. (The collections - * themselves are not versioned). + * [[staticMethods]], [[memberMethods]] and [[exportedMembers]] as they have + * their individual versions. (The collections themselves are not versioned). * * Moreover, the [[version]] is relative to the identity of a LinkedClass. * The definition of identity varies as linked classes progress through the @@ -44,7 +43,6 @@ final class LinkedClass( val fields: List[FieldDef], val staticMethods: List[Versioned[MethodDef]], val memberMethods: List[Versioned[MethodDef]], - val abstractMethods: List[Versioned[MethodDef]], val exportedMembers: List[Versioned[MemberDef]], val topLevelExports: List[Versioned[TopLevelExportDef]], val optimizerHints: OptimizerHints, @@ -79,7 +77,6 @@ final class LinkedClass( fields: List[FieldDef] = this.fields, staticMethods: List[Versioned[MethodDef]] = this.staticMethods, memberMethods: List[Versioned[MethodDef]] = this.memberMethods, - abstractMethods: List[Versioned[MethodDef]] = this.abstractMethods, exportedMembers: List[Versioned[MemberDef]] = this.exportedMembers, topLevelExports: List[Versioned[TopLevelExportDef]] = this.topLevelExports, optimizerHints: OptimizerHints = this.optimizerHints, @@ -100,7 +97,6 @@ final class LinkedClass( fields, staticMethods, memberMethods, - abstractMethods, exportedMembers, topLevelExports, optimizerHints, diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index ec0e616517..955fc38ff6 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -76,7 +76,6 @@ private final class IRChecker(unit: LinkingUnit, ClassKind.NativeJSModuleClass => if (classDef.fields.nonEmpty || classDef.memberMethods.nonEmpty || - classDef.abstractMethods.nonEmpty || classDef.exportedMembers.nonEmpty || classDef.topLevelExports.nonEmpty) { reportError(s"Raw JS type ${classDef.name} cannot "+ @@ -256,7 +255,7 @@ private final class IRChecker(unit: LinkingUnit, } // Check methods - for (method <- classDef.memberMethods ++ classDef.abstractMethods) { + for (method <- classDef.memberMethods) { val tree = method.value implicit val ctx = ErrorContext(tree) @@ -329,10 +328,9 @@ private final class IRChecker(unit: LinkingUnit, body.fold { // Abstract - if (static) - reportError(s"Static method ${classDef.name.name}.$name cannot be abstract") - else if (isConstructor) - reportError(s"Constructor ${classDef.name.name}.$name cannot be abstract") + reportError( + s"The abstract method ${classDef.name.name}.$name survived the " + + "Analyzer (this is a bug)") } { body => // Concrete if (resultType == NoType) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index dcce2e8321..adddb8038f 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -116,7 +116,6 @@ final class BaseLinker(config: CommonPhaseConfig) { val fields = mutable.Buffer.empty[FieldDef] val staticMethods = mutable.Buffer.empty[Versioned[MethodDef]] val memberMethods = mutable.Buffer.empty[Versioned[MethodDef]] - val abstractMethods = mutable.Buffer.empty[Versioned[MethodDef]] val exportedMembers = mutable.Buffer.empty[Versioned[MemberDef]] def linkedMethod(m: MethodDef) = { @@ -134,30 +133,27 @@ final class BaseLinker(config: CommonPhaseConfig) { } classDef.memberDefs.foreach { - // Static methods - case m: MethodDef if m.static => - if (analyzerInfo.staticMethodInfos(m.encodedName).isReachable) { - if (m.name.isInstanceOf[Ident]) - staticMethods += linkedMethod(m) - else - exportedMembers += linkedMethod(m) - } - - // Fields - case field @ FieldDef(_, _, _, _) => + case field: FieldDef => if (analyzerInfo.isAnySubclassInstantiated) fields += field - // Normal methods case m: MethodDef => - if (analyzerInfo.methodInfos(m.encodedName).isReachable) { + val methodInfo = + if (m.static) analyzerInfo.staticMethodInfos(m.encodedName) + else analyzerInfo.methodInfos(m.encodedName) + + if (methodInfo.isReachable) { + assert(m.body.isDefined, + s"The abstract method ${classDef.name.name}.${m.encodedName} " + + "is reachable.") + val linked = linkedMethod(m) if (m.name.isInstanceOf[Ident]) { - if (m.body.isDefined) - memberMethods += linkedMethod(m) + if (m.static) + staticMethods += linked else - abstractMethods += linkedMethod(m) + memberMethods += linked } else { - exportedMembers += linkedMethod(m) + exportedMembers += linked } } @@ -207,7 +203,6 @@ final class BaseLinker(config: CommonPhaseConfig) { fields.toList, staticMethods.toList, memberMethods.toList, - abstractMethods.toList, exportedMembers.toList, topLevelExports, classDef.optimizerHints, diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala index f91778a949..4077e247e5 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala @@ -87,10 +87,6 @@ final class Refiner(config: CommonPhaseConfig) { info.methodInfos(m.value.encodedName).isReachable } - val abstractMethods = classDef.abstractMethods filter { m => - info.methodInfos(m.value.encodedName).isReachable - } - val kind = if (info.isModuleAccessed) classDef.kind else classDef.kind.withoutModuleAccessor @@ -100,7 +96,6 @@ final class Refiner(config: CommonPhaseConfig) { fields = fields, staticMethods = staticMethods, memberMethods = memberMethods, - abstractMethods = abstractMethods, hasInstances = info.isAnySubclassInstantiated, hasInstanceTests = info.areInstanceTestsUsed, hasRuntimeTypeInfo = info.isDataAccessed) @@ -151,7 +146,6 @@ private object Refiner { private var cacheUsed: Boolean = false private val staticMethodsInfoCaches = LinkedMembersInfosCache() private val memberMethodsInfoCaches = LinkedMembersInfosCache() - private val abstractMethodsInfoCaches = LinkedMembersInfosCache() private val exportedMembersInfoCaches = LinkedMembersInfosCache() private var info: Infos.ClassInfo = _ @@ -174,8 +168,6 @@ private object Refiner { builder.addMethod(staticMethodsInfoCaches.getInfo(linkedMethod)) for (linkedMethod <- linkedClass.memberMethods) builder.addMethod(memberMethodsInfoCaches.getInfo(linkedMethod)) - for (linkedMethod <- linkedClass.abstractMethods) - builder.addMethod(abstractMethodsInfoCaches.getInfo(linkedMethod)) for (linkedMember <- linkedClass.exportedMembers) builder.addMethod(exportedMembersInfoCaches.getInfo(linkedMember)) @@ -202,7 +194,6 @@ private object Refiner { // No point in cleaning the inner caches if the whole class disappears staticMethodsInfoCaches.cleanAfterRun() memberMethodsInfoCaches.cleanAfterRun() - abstractMethodsInfoCaches.cleanAfterRun() exportedMembersInfoCaches.cleanAfterRun() } result From a2b11807da92551b1ec09bc1c82f514602fc4df5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 21 Dec 2017 16:22:48 +0100 Subject: [PATCH 0601/2665] Make UndefinedBehaviorError extend VirtualMachineError. `VirtualMachineError`s is the superclass of severe exceptions that indicate the virtual machine has reached a state that is potentially invalid, and cannot be safely recovered from. This is a perfect description for `UndefinedBehaviorError`s. Since `VirtualMachineError`s are considered fatal by Scala (i.e., not `NonFatal`), this allows `UndefinedBehaviorError` not to extend `scala.util.ControlThrowable`, which was a hack to begin with, and therefore not depend on the Scala standard library. In the process, we harmonize the `message` of `UndefinedBehaviorError` with other `VirtualMachineError`s, as mentioning both the class name and the message of the underlying exception. --- .../src/main/scala/java/lang/Throwables.scala | 11 ++++++-- .../runtime/UndefinedBehaviorError.scala | 10 ++----- .../library/UndefinedBehaviorErrorTest.scala | 28 +++++++++++++++++++ 3 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 test-suite/js/src/test/scala/org/scalajs/testsuite/library/UndefinedBehaviorErrorTest.scala diff --git a/javalanglib/src/main/scala/java/lang/Throwables.scala b/javalanglib/src/main/scala/java/lang/Throwables.scala index 201aba21de..e05648d954 100644 --- a/javalanglib/src/main/scala/java/lang/Throwables.scala +++ b/javalanglib/src/main/scala/java/lang/Throwables.scala @@ -248,8 +248,15 @@ class VerifyError(s: String) extends LinkageError(s) { def this() = this(null) } -abstract class VirtualMachineError(s: String) extends Error(s) { - def this() = this(null) +abstract class VirtualMachineError(message: String, cause: Throwable) + extends Error(message, cause) { + + def this() = this(null, null) + + def this(message: String) = this(message, null) + + def this(cause: Throwable) = + this(if (cause == null) null else cause.toString, cause) } diff --git a/library/src/main/scala/scala/scalajs/runtime/UndefinedBehaviorError.scala b/library/src/main/scala/scala/scalajs/runtime/UndefinedBehaviorError.scala index 91e5f2f01e..d2807c81e9 100644 --- a/library/src/main/scala/scala/scalajs/runtime/UndefinedBehaviorError.scala +++ b/library/src/main/scala/scala/scalajs/runtime/UndefinedBehaviorError.scala @@ -1,7 +1,5 @@ package scala.scalajs.runtime -import scala.util.control.ControlThrowable - /** Error thrown when an undefined behavior in Fatal mode has been detected. * This error should never be caught. It indicates a severe programming bug. * In Unchecked mode, the program may behave arbitrarily. @@ -12,14 +10,12 @@ import scala.util.control.ControlThrowable * Note that this will have (potentially major) performance impacts. */ class UndefinedBehaviorError(message: String, cause: Throwable) - extends java.lang.Error(message, cause) with ControlThrowable { + extends java.lang.VirtualMachineError(message, cause) { def this(message: String) = this(message, null) def this(cause: Throwable) = - this("An undefined behavior was detected" + - (if (cause == null) "" else ": "+cause.getMessage), cause) + this(if (cause == null) null else cause.toString, cause) - override def fillInStackTrace(): Throwable = - super[Error].fillInStackTrace() + def this() = this(null, null) } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UndefinedBehaviorErrorTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UndefinedBehaviorErrorTest.scala new file mode 100644 index 0000000000..ea2857b3e8 --- /dev/null +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UndefinedBehaviorErrorTest.scala @@ -0,0 +1,28 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.library + +import scala.util.control.NonFatal + +import org.junit.Assert._ +import org.junit.Test + +import scala.scalajs.runtime.UndefinedBehaviorError + +class UndefinedBehaviorErrorTest { + + @Test def ubeIsAFatalError(): Unit = { + val error: Throwable = new UndefinedBehaviorError("test") + assertFalse(NonFatal(error)) + assertTrue(error match { + case NonFatal(_) => false + case _ => true + }) + } + +} From 32f16658f93aa72dff86eba14cac7521c05dc88a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 21 Dec 2017 18:04:39 +0100 Subject: [PATCH 0602/2665] Tweak `RuntimeLong` not to leave any trace of Scala. We carefully avoid any construct or structure that would leave a trace of the Scala standard library or the Scala.js standard library in the IR generated for `RuntimeLong`. This ensures that `RuntimeLong` can be used with a minimal Java library that does not provide any Scala stuff. --- .../scala/scalajs/runtime/RuntimeLong.scala | 61 +++++++++++-------- 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala b/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala index f96dc0d01a..bec2b8554e 100644 --- a/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala +++ b/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala @@ -2,11 +2,6 @@ package scala.scalajs.runtime import scala.annotation.tailrec -import scala.scalajs.js -import js.| -import js.JSNumberOps._ -import js.JSStringOps._ - /* IMPORTANT NOTICE about this file * * The code of RuntimeLong is code-size- and performance critical. The methods @@ -586,10 +581,11 @@ object RuntimeLong { private def toDouble(lo: Int, hi: Int): Double = { if (hi < 0) { - // We do .toUint on the hi part specifically for MinValue - -(inline_hi_unary_-(lo, hi).toUint * TwoPow32 + inline_lo_unary_-(lo).toUint) + // We do asUint() on the hi part specifically for MinValue + -(asUint(inline_hi_unary_-(lo, hi)) * TwoPow32 + + asUint(inline_lo_unary_-(lo))) } else { - hi * TwoPow32 + lo.toUint + hi * TwoPow32 + asUint(lo) } } @@ -703,10 +699,10 @@ object RuntimeLong { } } } else { - val (aNeg, aAbs) = inline_abs(alo, ahi) - val (bNeg, bAbs) = inline_abs(blo, bhi) + val aAbs = inline_abs(alo, ahi) + val bAbs = inline_abs(blo, bhi) val absRLo = unsigned_/(aAbs.lo, aAbs.hi, bAbs.lo, bAbs.hi) - if (aNeg == bNeg) absRLo + if ((ahi ^ bhi) >= 0) absRLo // a and b have the same sign bit else inline_hiReturn_unary_-(absRLo, hiReturn) } } @@ -797,10 +793,10 @@ object RuntimeLong { } } } else { - val (aNeg, aAbs) = inline_abs(alo, ahi) - val (_, bAbs) = inline_abs(blo, bhi) + val aAbs = inline_abs(alo, ahi) + val bAbs = inline_abs(blo, bhi) val absRLo = unsigned_%(aAbs.lo, aAbs.hi, bAbs.lo, bAbs.hi) - if (aNeg) inline_hiReturn_unary_-(absRLo, hiReturn) + if (ahi < 0) inline_hiReturn_unary_-(absRLo, hiReturn) else absRLo } } @@ -866,7 +862,7 @@ object RuntimeLong { * In this case, `blo` must be 10^9 and `bhi` must be 0. */ private def unsignedDivModHelper(alo: Int, ahi: Int, blo: Int, bhi: Int, - ask: Int): Int | String = { + ask: Int): Any = { var shift = inlineNumberOfLeadingZeros(blo, bhi) - inlineNumberOfLeadingZeros(alo, ahi) @@ -937,7 +933,7 @@ object RuntimeLong { // AskToString (recall that b = 10^9 in this case) val quot = asUnsignedSafeDouble(quotLo, quotHi) // != 0 val remStr = remLo.toString // remHi is always 0 - quot.toString + "000000000".jsSubstring(remStr.length) + remStr + quot.toString + substring("000000000", remStr.length) + remStr } } @@ -947,6 +943,14 @@ object RuntimeLong { inline_lo_unary_-(lo) } + @inline + private def substring(s: String, start: Int): String = { + import scala.scalajs.js + s.asInstanceOf[js.Dynamic] + .substring(start.asInstanceOf[js.Dynamic]) + .asInstanceOf[String] + } + // In a different object so they can be inlined without cost private object Utils { /** Tests whether the long (lo, hi) is 0. */ @@ -975,7 +979,7 @@ object RuntimeLong { /** Converts an unsigned safe double into its Double representation. */ @inline def asUnsignedSafeDouble(lo: Int, hi: Int): Double = - hi * TwoPow32 + lo.toUint + hi * TwoPow32 + asUint(lo) /** Converts an unsigned safe double into its RuntimeLong representation. */ @inline def fromUnsignedSafeDouble(x: Double): RuntimeLong = @@ -989,9 +993,19 @@ object RuntimeLong { @inline def unsignedSafeDoubleHi(x: Double): Int = rawToInt(x / TwoPow32) + /** Interprets an `Int` as an unsigned integer and returns its value as a + * `Double`. + */ + @inline def asUint(x: Int): Double = { + import scala.scalajs.js + (x.asInstanceOf[js.Dynamic] >>> 0.asInstanceOf[js.Dynamic]).asInstanceOf[Double] + } + /** Performs the JavaScript operation `(x | 0)`. */ - @inline def rawToInt(x: Double): Int = + @inline def rawToInt(x: Double): Int = { + import scala.scalajs.js (x.asInstanceOf[js.Dynamic] | 0.asInstanceOf[js.Dynamic]).asInstanceOf[Int] + } /** Tests whether the given non-zero unsigned Int is an exact power of 2. */ @inline def isPowerOfTwo_IKnowItsNot0(i: Int): Boolean = @@ -1033,12 +1047,11 @@ object RuntimeLong { if (lo != 0) ~hi else -hi @inline - def inline_abs(lo: Int, hi: Int): (Boolean, RuntimeLong) = { - val neg = hi < 0 - val abs = - if (neg) new RuntimeLong(inline_lo_unary_-(lo), inline_hi_unary_-(lo, hi)) - else new RuntimeLong(lo, hi) - (neg, abs) + def inline_abs(lo: Int, hi: Int): RuntimeLong = { + if (hi < 0) + new RuntimeLong(inline_lo_unary_-(lo), inline_hi_unary_-(lo, hi)) + else + new RuntimeLong(lo, hi) } } From e28ff5e0444c1410c2b44d4f819ea6b24966c570 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 19 Dec 2017 17:49:58 +0100 Subject: [PATCH 0603/2665] Fix #3228: Disable reflective instantiation for nested modules. We were using `sym.isModuleClass` to identify module classes when generating the reflective instantiation code, but that also matches nested objects. Now, nested objects are not compiled as module classes (only static objects are) because there is one instance per enclosing instance. This caused linking errors as soon as the codebase contained a nested object with `@EnableReflectiveInstantiation`. Since non-static objects are not really *loadable* as per the API of `Reflect` (we would need a reference to the enclosing instance), we fix this issue by not registering non-static objects at all. --- .../org/scalajs/core/compiler/GenJSCode.scala | 4 ++- .../scala/scala/scalajs/reflect/Reflect.scala | 30 +++++++++++++++++++ .../testsuite/library/ReflectTest.scala | 17 +++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 93565f49f6..5b2d3adfab 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -952,8 +952,10 @@ abstract class GenJSCode extends plugins.PluginComponent private def genRegisterReflectiveInstantiation(sym: Symbol)( implicit pos: Position): Option[js.Tree] = { - if (sym.isModuleClass) + if (isStaticModule(sym)) genRegisterReflectiveInstantiationForModuleClass(sym) + else if (sym.isModuleClass) + None // #3228 else genRegisterReflectiveInstantiationForNormalClass(sym) } diff --git a/library/src/main/scala/scala/scalajs/reflect/Reflect.scala b/library/src/main/scala/scala/scalajs/reflect/Reflect.scala index 7dcb217262..45b9c00f09 100644 --- a/library/src/main/scala/scala/scalajs/reflect/Reflect.scala +++ b/library/src/main/scala/scala/scalajs/reflect/Reflect.scala @@ -94,9 +94,39 @@ object Reflect { new InstantiatableClass(runtimeClass, invokableConstructors.toList) } + /** Reflectively looks up a loadable module class. + * + * A module class is the technical term referring to the class of a Scala + * `object`. The object or one of its super types (classes or traits) must + * be annotated with + * [[scala.scalajs.reflect.annotation.EnableReflectiveInstantiation @EnableReflectiveInstantiation]]. + * Moreover, the object must be "static", i.e., declared at the top-level of + * a package or inside a static object. + * + * If the module class cannot be found, either because it does not exist, + * was not `@EnableReflectiveInstantiation` or was not static, this method + * returns `None`. + * + * @param fqcn + * Fully-qualified name of the module class, including its trailing `$` + */ def lookupLoadableModuleClass(fqcn: String): Option[LoadableModuleClass] = loadableModuleClasses.get(fqcn) + /** Reflectively looks up an instantiable class. + * + * The class or one of its super types (classes or traits) must be annotated + * with + * [[scala.scalajs.reflect.annotation.EnableReflectiveInstantiation @EnableReflectiveInstantiation]]. + * Moreover, the class must not be abstract. + * + * If the class cannot be found, either because it does not exist, + * was not `@EnableReflectiveInstantiation` or was abstract, this method + * returns `None`. + * + * @param fqcn + * Fully-qualified name of the class + */ def lookupInstantiatableClass(fqcn: String): Option[InstantiatableClass] = instantiatableClasses.get(fqcn) } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ReflectTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ReflectTest.scala index f0d83d403a..91190dcc3a 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ReflectTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ReflectTest.scala @@ -55,6 +55,11 @@ class ReflectTest { private final val NameTraitDisable = Prefix + "TraitDisable" + private final val NameInnerObject = { + Prefix + "ClassWithInnerObjectWithEnableReflectiveInstantiation$" + + "InnerObjectWithEnableReflectiveInstantiation" + } + @Test def testClassRuntimeClass(): Unit = { for { name <- Seq(NameClassEnableDirect, NameClassEnableDirectNoZeroArgCtor, @@ -187,6 +192,11 @@ class ReflectTest { } } + @Test def testInnerObjectWithEnableReflectiveInstantiation_issue_3228(): Unit = { + assertFalse(Reflect.lookupLoadableModuleClass(NameInnerObject).isDefined) + assertFalse(Reflect.lookupInstantiatableClass(NameInnerObject).isDefined) + } + } object ReflectTest { @@ -307,4 +317,11 @@ object ReflectTest { } trait TraitDisable extends Accessors + + // Regression cases + + class ClassWithInnerObjectWithEnableReflectiveInstantiation { + @EnableReflectiveInstantiation + object InnerObjectWithEnableReflectiveInstantiation + } } From db5701aac371c38ae5d3fe3838b302c662ce8f1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 27 Dec 2017 23:18:08 +0100 Subject: [PATCH 0604/2665] Use a "minilib" for the unit tests of the linker. Instead of using the full `scalajs-library.jar` for the unit tests of the linker, we now use a minimal library. That "minilib" contains things like `Object`, `Integer` and `RuntimeLong`: core classes without which it is not possible to link a hello world. The minilib does not contain `js.Any` nor any of its subtypes, proving that the linker can live without them. That required to tweak a few core methods not to use niceties from our standard library, such as `JSStringOps` and `JSNumberOps`. Instead, we must be careful to only use `js.Dynamic`, and only inside methods, so that even `js.Dynamic` does not leave any trace in method signatures. --- build.sbt | 1 + .../src/main/scala/java/lang/Character.scala | 7 +- .../src/main/scala/java/lang/Integer.scala | 20 ++--- .../src/main/scala/java/lang/Long.scala | 3 +- .../src/main/scala/java/lang/_String.scala | 20 +++-- minilib/src/main/scala/java/lang/Class.scala | 26 +++++++ .../scala/java/lang/FloatingPointBits.scala | 19 +++++ minilib/src/main/scala/java/lang/System.scala | 27 +++++++ .../src/main/scala/java/lang/Throwable.scala | 28 +++++++ project/Build.scala | 27 ++++++- project/MiniLib.scala | 75 +++++++++++++++++++ .../core/tools/linker/AnalyzerTest.scala | 28 +------ .../core/tools/linker/LinkerTest.scala | 58 +++++++++++++- .../linker/testutils/TestIRBuilder.scala | 44 +++++++++++ 14 files changed, 331 insertions(+), 52 deletions(-) create mode 100644 minilib/src/main/scala/java/lang/Class.scala create mode 100644 minilib/src/main/scala/java/lang/FloatingPointBits.scala create mode 100644 minilib/src/main/scala/java/lang/System.scala create mode 100644 minilib/src/main/scala/java/lang/Throwable.scala create mode 100644 project/MiniLib.scala create mode 100644 tools/shared/src/test/scala/org/scalajs/core/tools/linker/testutils/TestIRBuilder.scala diff --git a/build.sbt b/build.sbt index 718fcefa7b..16b253c942 100644 --- a/build.sbt +++ b/build.sbt @@ -16,6 +16,7 @@ val javalib = Build.javalib val scalalib = Build.scalalib val libraryAux = Build.libraryAux val library = Build.library +val minilib = Build.minilib val stubs = Build.stubs val testInterface = Build.testInterface val jUnitRuntime = Build.jUnitRuntime diff --git a/javalanglib/src/main/scala/java/lang/Character.scala b/javalanglib/src/main/scala/java/lang/Character.scala index 46faf7ff25..d3bf1e9108 100644 --- a/javalanglib/src/main/scala/java/lang/Character.scala +++ b/javalanglib/src/main/scala/java/lang/Character.scala @@ -442,8 +442,11 @@ object Character { @inline private def lowSurrogateOf(codePoint: Int): Char = (0xdc00 | (codePoint & 0x3ff)).toChar - @inline def toString(c: scala.Char): String = - js.Dynamic.global.String.fromCharCode(c.toInt).asInstanceOf[String] + @inline def toString(c: scala.Char): String = { + js.Dynamic.global.String + .fromCharCode(c.toInt.asInstanceOf[js.Dynamic]) + .asInstanceOf[String] + } @inline def compare(x: scala.Char, y: scala.Char): Int = x - y diff --git a/javalanglib/src/main/scala/java/lang/Integer.scala b/javalanglib/src/main/scala/java/lang/Integer.scala index 5271c03b77..c17cffa7bb 100644 --- a/javalanglib/src/main/scala/java/lang/Integer.scala +++ b/javalanglib/src/main/scala/java/lang/Integer.scala @@ -136,15 +136,11 @@ object Integer { (((t2 + (t2 >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24 } - @inline def divideUnsigned(dividend: Int, divisor: Int): Int = { - import js.JSNumberOps._ - asInt(dividend.toUint / divisor.toUint) - } + @inline def divideUnsigned(dividend: Int, divisor: Int): Int = + asInt(asUint(dividend) / asUint(divisor)) - @inline def remainderUnsigned(dividend: Int, divisor: Int): Int = { - import js.JSNumberOps._ - asInt(dividend.toUint % divisor.toUint) - } + @inline def remainderUnsigned(dividend: Int, divisor: Int): Int = + asInt(asUint(dividend) % asUint(divisor)) @inline def highestOneBit(i: Int): Int = { /* The natural way of implementing this is: @@ -234,10 +230,14 @@ object Integer { @inline def min(a: Int, b: Int): Int = Math.min(a, b) @inline private[this] def toStringBase(i: scala.Int, base: scala.Int): String = { - import js.JSNumberOps._ - i.toUint.toString(base) + asUint(i).asInstanceOf[js.Dynamic] + .applyDynamic("toString")(base.asInstanceOf[js.Dynamic]) + .asInstanceOf[String] } @inline private def asInt(n: scala.Double): scala.Int = (n.asInstanceOf[js.Dynamic] | 0.asInstanceOf[js.Dynamic]).asInstanceOf[Int] + + @inline private def asUint(n: scala.Int): scala.Double = + (n.asInstanceOf[js.Dynamic] >>> 0.asInstanceOf[js.Dynamic]).asInstanceOf[scala.Double] } diff --git a/javalanglib/src/main/scala/java/lang/Long.scala b/javalanglib/src/main/scala/java/lang/Long.scala index 4979ef5527..4f81973c91 100644 --- a/javalanglib/src/main/scala/java/lang/Long.scala +++ b/javalanglib/src/main/scala/java/lang/Long.scala @@ -111,8 +111,7 @@ object Long { } // Intrinsic - @inline def toString(i: scala.Long): String = - toStringImpl(i, 10) + @inline def toString(i: scala.Long): String = "" + i @inline def toUnsignedString(i: scala.Long): String = toUnsignedStringImpl(i, 10) diff --git a/javalanglib/src/main/scala/java/lang/_String.scala b/javalanglib/src/main/scala/java/lang/_String.scala index 0484cc228b..142f030fd7 100644 --- a/javalanglib/src/main/scala/java/lang/_String.scala +++ b/javalanglib/src/main/scala/java/lang/_String.scala @@ -33,8 +33,12 @@ final class _String private () // scalastyle:ignore this.asInstanceOf[SpecialJSStringOps] @inline - def charAt(index: Int): Char = - thisJSString.charCodeAt(index).toChar + def charAt(index: Int): Char = { + this.asInstanceOf[js.Dynamic] + .charCodeAt(index.asInstanceOf[js.Dynamic]) + .asInstanceOf[Int] + .toChar + } def codePointAt(index: Int): Int = { val high = charAt(index) @@ -225,7 +229,7 @@ final class _String private () // scalastyle:ignore @inline def length(): Int = - thisJSString.length + this.asInstanceOf[js.Dynamic].length.asInstanceOf[Int] @inline def matches(regex: String): scala.Boolean = @@ -296,8 +300,11 @@ final class _String private () // scalastyle:ignore thisString.jsSubstring(beginIndex) @inline - def substring(beginIndex: Int, endIndex: Int): String = - thisString.jsSubstring(beginIndex, endIndex) + def substring(beginIndex: Int, endIndex: Int): String = { + this.asInstanceOf[js.Dynamic] + .substring(beginIndex.asInstanceOf[js.Dynamic], endIndex.asInstanceOf[js.Dynamic]) + .asInstanceOf[String] + } def toCharArray(): Array[Char] = { val len = length @@ -332,9 +339,6 @@ object _String { // scalastyle:ignore * and that we need to implement these very Scala methods. */ private trait SpecialJSStringOps extends js.Any { - def length: Int - def charCodeAt(index: Int): Int - def toLowerCase(): String def toUpperCase(): String def trim(): String diff --git a/minilib/src/main/scala/java/lang/Class.scala b/minilib/src/main/scala/java/lang/Class.scala new file mode 100644 index 0000000000..18940c42a4 --- /dev/null +++ b/minilib/src/main/scala/java/lang/Class.scala @@ -0,0 +1,26 @@ +package java.lang + +import scala.scalajs.js + +/** Stripped down version of `java.lang.Class`, with just the bare minimum to + * support `toString()`. + * + * We cannot use the full `java.lang.Class` out of the box because it + * internally uses a static facade type for its `data`, and the minilib cannot + * contain any JS type. + */ +final class Class[A] private (private val data: Object) extends Object { + override def toString(): String = { + (if (isInterface()) "interface " else + if (isPrimitive()) "" else "class ") + getName() + } + + def isInterface(): scala.Boolean = + data.asInstanceOf[js.Dynamic].isInterface.asInstanceOf[scala.Boolean] + + def isPrimitive(): scala.Boolean = + data.asInstanceOf[js.Dynamic].isPrimitive.asInstanceOf[scala.Boolean] + + def getName(): String = + data.asInstanceOf[js.Dynamic].name.asInstanceOf[String] +} diff --git a/minilib/src/main/scala/java/lang/FloatingPointBits.scala b/minilib/src/main/scala/java/lang/FloatingPointBits.scala new file mode 100644 index 0000000000..e01b5f6cc5 --- /dev/null +++ b/minilib/src/main/scala/java/lang/FloatingPointBits.scala @@ -0,0 +1,19 @@ +package java.lang + +import scala.scalajs.js + +/** Stripped down version of `java.lang.FloatingPointBits` with the bare + * minimum to support a correct `numberHashCode()`. + * + * We cannot use the full `java.lang.FloatingPointBits` out of the box, + * because it internally uses typed arrays (and static facade types thereof) + * to implement a better `numberHashCode()`. + */ +private[lang] object FloatingPointBits { + // Simpler version than the original, technically valid but of lesser quality + def numberHashCode(value: scala.Double): Int = + rawToInt(value) + + @inline private def rawToInt(x: scala.Double): Int = + (x.asInstanceOf[js.Dynamic] | 0.asInstanceOf[js.Dynamic]).asInstanceOf[Int] +} diff --git a/minilib/src/main/scala/java/lang/System.scala b/minilib/src/main/scala/java/lang/System.scala new file mode 100644 index 0000000000..9c8c974dc9 --- /dev/null +++ b/minilib/src/main/scala/java/lang/System.scala @@ -0,0 +1,27 @@ +package java.lang + +/** Stripped down version of `java.lang.System` with the bare minimum to + * support a correct `numberHashCode()`. + * + * We cannot use the full `java.lang.System` out of the box, because its + * constructor initializes `out` and `err`, which require + * `JSConsoleBasedPrintStream` and therefore a large part of `java.io`. We do + * not simply reuse (copy-paste) `identityHashCode` either because it + * internally uses a `WeakMap` typed as `js.Dynamic`. + */ +object System { + // Simpler than the original, technically valid but of lesser quality + def identityHashCode(x: Object): scala.Int = { + (x: Any) match { + case null => 0 + case _:scala.Boolean | _:scala.Double | _:String | () => + x.hashCode() + case _ => + // See the original System.scala for the rationale of this test + if (x.getClass == null) + x.hashCode() + else + 42 + } + } +} diff --git a/minilib/src/main/scala/java/lang/Throwable.scala b/minilib/src/main/scala/java/lang/Throwable.scala new file mode 100644 index 0000000000..4c19a5947e --- /dev/null +++ b/minilib/src/main/scala/java/lang/Throwable.scala @@ -0,0 +1,28 @@ +package java.lang + +/** Stripped down version of `java.lang.Throwable` with the bare minimum to + * support `toString()` and the subclasses. + * + * We cannot use the full `java.lang.Throwable` out of the box, because its + * constructor calls `initStackTrace()`, which uses `StackTrace.scala` and + * therefore a bunch of JS stuff inside to recover stack traces. This stripped + * down `Throwable` does not offer any method to access the stack trace so + * that `initStackTrace()` is not necessary. + */ +class Throwable(s: String, e: Throwable) + extends Object with java.io.Serializable { + + def this() = this(null, null) + def this(s: String) = this(s, null) + def this(e: Throwable) = this(if (e == null) null else e.toString, e) + + def getMessage(): String = s + def getCause(): Throwable = e + + override def toString(): String = { + val className = getClass.getName + val message = getMessage() + if (message eq null) className + else className + ": " + message + } +} diff --git a/project/Build.scala b/project/Build.scala index ff1a19c277..6d3b24c28e 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -475,7 +475,7 @@ object Build { clean in jsEnvs, clean in jsEnvsTestKit, clean in nodeJSEnv, clean in testAdapter, clean in plugin, clean in javalanglib, clean in javalib, clean in scalalib, - clean in libraryAux, clean in library, + clean in libraryAux, clean in library, clean in minilib, clean in stubs, clean in testInterface, clean in jUnitRuntime, clean in jUnitPlugin, @@ -592,7 +592,7 @@ object Build { testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a"), javaOptions in Test += { - val libJar = (packageBin in (LocalProject("library"), Compile)).value + val libJar = (packageBin in (LocalProject("minilib"), Compile)).value "-Dorg.scalajs.core.tools.linker.stdlibjar=" + libJar.getAbsolutePath } ) @@ -1112,6 +1112,29 @@ object Build { )) ).withScalaJSCompiler + lazy val minilib: Project = project.enablePlugins( + MyScalaJSPlugin + ).settings( + commonSettings, + fatalWarningsSettings, + name := "scalajs-minilib", + + noClassFilesSettings, + scalaJSExternalCompileSettings, + inConfig(Compile)(Seq( + mappings in packageBin := { + val superMappings = (mappings in packageBin).value + val libraryMappings = (mappings in (library, packageBin)).value + + val whitelisted = libraryMappings.filter { mapping => + MiniLib.Whitelist.contains(mapping._2.replace('\\', '/')) + } + + whitelisted ++ superMappings + } + )) + ).withScalaJSCompiler.dependsOn(library) + lazy val stubs: Project = project.settings( commonSettings, publishSettings, diff --git a/project/MiniLib.scala b/project/MiniLib.scala new file mode 100644 index 0000000000..d91a81db77 --- /dev/null +++ b/project/MiniLib.scala @@ -0,0 +1,75 @@ +package build + +object MiniLib { + val Whitelist = { + val inJavaLang = List( + "Object", + // "Class" is overridden in minilib/ + // "System" is overridden in minilib/ + + "CharSequence", + "Cloneable", + "Comparable", + "Number", + + "Boolean", + "Character", + "Byte", + "Short", + "Integer", + "Long", + "Float", + "Double", + "String", + + // "FloatingPointBits" is overridden in minilib/ + + // "Throwable" is overridden in minilib/ + "Error", + "VirtualMachineError", + "Exception", + "RuntimeException", + "ArithmeticException", + "ArrayIndexOutOfBoundsException", + "ArrayStoreException", + "ClassCastException", + "CloneNotSupportedException", + "IndexOutOfBoundsException", + "NullPointerException", + "StringIndexOutOfBoundsException" + ).map("java/lang/" + _) + + val inJavaIO = List( + "Serializable" + ).map("java/io/" + _) + + /* TODO Unfortunately, when a class extends java.io.Serializable, scalac + * forces its companion object to extend scala.Serializable (ugh!), which + * means that things like java.lang.Integer$ depend on scala.Serializable. + * However, as far as the linker is concerned, it shouldn't need, so it + * would be nice to get rid of this dependency. + */ + val inScala = List( + "Serializable" + ).map("scala/" + _) + + // TODO We should find a way to get rid of this one + val inScalaRuntime = List( + "BoxedUnit" + ).map("scala/runtime/" + _) + + /* TODO Could we put UndefinedBehaviorError in a neutral namespace? + * RuntimeLong should probably be part of the linker itself, as a resource. + */ + val inScalaJSRuntime = List( + "UndefinedBehaviorError", + "RuntimeLong", + "RuntimeLong$Utils" + ).map("scala/scalajs/runtime/" + _) + + val allBaseNames = + inJavaLang ::: inJavaIO ::: inScala ::: inScalaRuntime ::: inScalaJSRuntime + + allBaseNames.flatMap(name => List(name + ".sjsir", name + "$.sjsir")).toSet + } +} diff --git a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/AnalyzerTest.scala b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/AnalyzerTest.scala index f09c8f13c4..62001ee635 100644 --- a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/AnalyzerTest.scala +++ b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/AnalyzerTest.scala @@ -18,42 +18,16 @@ import org.scalajs.core.tools.linker.standard._ import Analysis._ import org.scalajs.core.tools.linker.testutils._ +import org.scalajs.core.tools.linker.testutils.TestIRBuilder._ class AnalyzerTest { import AnalyzerTest._ private val reqsFactory = SymbolRequirement.factory("unit test") - private val emptyOptHints: OptimizerHints = OptimizerHints.empty - - implicit private val noPosition: ir.Position = ir.Position.NoPosition - private val fromAnalyzer = FromCore("analyzer") private val fromUnitTest = FromCore("unit test") - private def classDef( - encodedName: String, - kind: ClassKind = ClassKind.Class, - jsClassCaptures: Option[List[ParamDef]] = None, - superClass: Option[String] = None, - interfaces: List[String] = Nil, - jsSuperClass: Option[Tree] = None, - jsNativeLoadSpec: Option[JSNativeLoadSpec] = None, - memberDefs: List[MemberDef] = Nil, - topLevelExportDefs: List[TopLevelExportDef] = Nil): ClassDef = { - ClassDef(Ident(encodedName), kind, jsClassCaptures, - superClass.map(Ident(_)), interfaces.map(Ident(_)), jsSuperClass, - jsNativeLoadSpec, memberDefs, topLevelExportDefs)( - emptyOptHints) - } - - private def trivialCtor(enclosingClassName: String): MethodDef = { - MethodDef(static = false, Ident("init___"), Nil, NoType, - Some(ApplyStatically(This()(ClassType(enclosingClassName)), - ClassType(ObjectClass), Ident("init___"), Nil)(NoType)))( - emptyOptHints, None) - } - @Test def trivialOK(): Unit = { val analysis = computeAnalysis(Nil) diff --git a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala index f0b7e5af40..72433d6686 100644 --- a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala +++ b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala @@ -3,11 +3,44 @@ package org.scalajs.core.tools.linker import org.junit.Test import org.junit.Assert._ -import org.scalajs.core.tools.logging.NullLogger +import org.scalajs.core.ir.ClassKind +import org.scalajs.core.ir.Definitions._ +import org.scalajs.core.ir.Trees._ + +import org.scalajs.core.tools.logging._ import org.scalajs.core.tools.io._ import org.scalajs.core.tools.linker._ +import org.scalajs.core.tools.linker.testutils._ +import org.scalajs.core.tools.linker.testutils.TestIRBuilder._ + class LinkerTest { + import LinkerTest._ + + /** Makes sure that the minilib is sufficient to completely link a hello + * world. + */ + @Test + def linkHelloWorld(): Unit = { + val name = "LHelloWorld$" + val mainMethodBody = { + JSBracketMethodApply(JSGlobalRef(Ident("console")), StringLiteral("log"), + List(StringLiteral("Hello world!"))) + } + val classDefs = Seq( + classDef(name, kind = ClassKind.ModuleClass, + superClass = Some(ObjectClass), + memberDefs = List( + trivialCtor(name), + mainMethodDef(mainMethodBody) + ) + ) + ) + val moduleInitializers = List( + ModuleInitializer.mainMethodWithArgs("HelloWorld", "main") + ) + testLink(classDefs, moduleInitializers) + } /** This test exposes a problem where a linker in error state is called * multiple times and ends up thinking it is being used concurrently. @@ -50,3 +83,26 @@ class LinkerTest { } } + +object LinkerTest { + def testLink(classDefs: Seq[ClassDef], + moduleInitializers: List[ModuleInitializer]): Unit = { + + val linker = StandardLinker(StandardLinker.Config()) + + val classDefsFiles = classDefs.map { classDef => + new VirtualScalaJSIRFile { + def exists: Boolean = true + def path: String = "mem://" + classDef.name.name + ".sjsir" + def tree: ClassDef = classDef + } + } + + val allIRFiles = TestIRRepo.stdlibIRFiles ++ classDefsFiles + + val output = WritableMemVirtualJSFile("output.js") + + linker.link(allIRFiles, moduleInitializers, output, + new ScalaConsoleLogger(Level.Error)) + } +} diff --git a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/testutils/TestIRBuilder.scala b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/testutils/TestIRBuilder.scala new file mode 100644 index 0000000000..f9db878f03 --- /dev/null +++ b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/testutils/TestIRBuilder.scala @@ -0,0 +1,44 @@ +package org.scalajs.core.tools.linker.testutils + +import org.scalajs.core.ir +import org.scalajs.core.ir.ClassKind +import org.scalajs.core.ir.Definitions._ +import org.scalajs.core.ir.Trees._ +import org.scalajs.core.ir.Types._ + +object TestIRBuilder { + implicit val noPosition: ir.Position = ir.Position.NoPosition + + val emptyOptHints: OptimizerHints = OptimizerHints.empty + + def classDef( + encodedName: String, + kind: ClassKind = ClassKind.Class, + jsClassCaptures: Option[List[ParamDef]] = None, + superClass: Option[String] = None, + interfaces: List[String] = Nil, + jsSuperClass: Option[Tree] = None, + jsNativeLoadSpec: Option[JSNativeLoadSpec] = None, + memberDefs: List[MemberDef] = Nil, + topLevelExportDefs: List[TopLevelExportDef] = Nil): ClassDef = { + ClassDef(Ident(encodedName), kind, jsClassCaptures, + superClass.map(Ident(_)), interfaces.map(Ident(_)), jsSuperClass, + jsNativeLoadSpec, memberDefs, topLevelExportDefs)( + emptyOptHints) + } + + def trivialCtor(enclosingClassName: String): MethodDef = { + MethodDef(static = false, Ident("init___"), Nil, NoType, + Some(ApplyStatically(This()(ClassType(enclosingClassName)), + ClassType(ObjectClass), Ident("init___"), Nil)(NoType)))( + emptyOptHints, None) + } + + def mainMethodDef(body: Tree): MethodDef = { + val stringArrayType = ArrayType(ArrayTypeRef("T", 1)) + val argsParamDef = ParamDef(Ident("args", Some("args")), stringArrayType, + mutable = false, rest = false) + MethodDef(static = false, Ident("main__AT__V"), List(argsParamDef), + NoType, Some(body))(emptyOptHints, None) + } +} From 52385301666b37f9476db47e78c6ef6337598849 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 8 Jan 2018 22:19:49 +0100 Subject: [PATCH 0605/2665] Tweak the mechanism to translate Scala varargs into JS varargs. Previously, we used an overly general method `genTraversableOnce2jsArray` to convert the `Seq` of Scala varargs into a JS array suitable for the `JSSpread` node. We now specialize that method to only accept `Seq`s and rename it to `toJSVarArgs`. Only handling `Seq`s means we can drop one case of the match, which was indeed not taken in practice for varargs. We also remove the `@inline` annotation from the method. It is only useful that it be inlined when the argument is a known `js.WrappedArray` (to be expanded by the optimizer), and in that case the heuristics of the optimizer will force the inlining anyway. This change reduces the cases of spurious inlining of that method. --- .../scala/org/scalajs/core/compiler/GenJSCode.scala | 7 +++---- .../org/scalajs/core/compiler/JSDefinitions.scala | 2 +- .../main/scala/scala/scalajs/js/JSConverters.scala | 2 -- .../main/scala/scala/scalajs/runtime/package.scala | 11 +++++------ 4 files changed, 9 insertions(+), 13 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index c49e51b7f1..7fb103ba83 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -4565,14 +4565,13 @@ abstract class GenJSCode extends plugins.PluginComponent */ private def genPrimitiveJSRepeatedParam(arg: Tree): List[js.Tree] = { tryGenRepeatedParamAsJSArray(arg, handleNil = true) getOrElse { - /* Fall back to calling runtime.genTraversableOnce2jsArray - * to perform the conversion to js.Array, then wrap in a Spread - * operator. + /* Fall back to calling runtime.toJSVarArgs to perform the conversion + * to js.Array, then wrap in a Spread operator. */ implicit val pos = arg.pos val jsArrayArg = genApplyMethod( genLoadModule(RuntimePackageModule), - Runtime_genTraversableOnce2jsArray, + Runtime_toJSVarArgs, List(genExpr(arg))) List(js.JSSpread(jsArrayArg)) } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index 5f7fbc5f2a..dd53eb73ec 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -105,7 +105,7 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val RuntimePackageModule = getPackageObject("scala.scalajs.runtime") lazy val Runtime_wrapJavaScriptException = getMemberMethod(RuntimePackageModule, newTermName("wrapJavaScriptException")) lazy val Runtime_unwrapJavaScriptException = getMemberMethod(RuntimePackageModule, newTermName("unwrapJavaScriptException")) - lazy val Runtime_genTraversableOnce2jsArray = getMemberMethod(RuntimePackageModule, newTermName("genTraversableOnce2jsArray")) + lazy val Runtime_toJSVarArgs = getMemberMethod(RuntimePackageModule, newTermName("toJSVarArgs")) lazy val Runtime_constructorOf = getMemberMethod(RuntimePackageModule, newTermName("constructorOf")) lazy val Runtime_newConstructorTag = getMemberMethod(RuntimePackageModule, newTermName("newConstructorTag")) lazy val Runtime_createInnerJSClass = getMemberMethod(RuntimePackageModule, newTermName("createInnerJSClass")) diff --git a/library/src/main/scala/scala/scalajs/js/JSConverters.scala b/library/src/main/scala/scala/scalajs/js/JSConverters.scala index 1f5c0ace52..b5d30e79ea 100644 --- a/library/src/main/scala/scala/scalajs/js/JSConverters.scala +++ b/library/src/main/scala/scala/scalajs/js/JSConverters.scala @@ -17,8 +17,6 @@ import scala.scalajs.js.annotation._ import scala.collection._ import scala.concurrent.{ExecutionContext, Future} -import scala.scalajs.runtime.genTraversableOnce2jsArray - sealed abstract class JSConvertersLowPrioImplicits { this: js.JSConverters.type => diff --git a/library/src/main/scala/scala/scalajs/runtime/package.scala b/library/src/main/scala/scala/scalajs/runtime/package.scala index 1227273857..39d41a196e 100644 --- a/library/src/main/scala/scala/scalajs/runtime/package.scala +++ b/library/src/main/scala/scala/scalajs/runtime/package.scala @@ -16,14 +16,13 @@ package object runtime { case _ => th } - @inline final def genTraversableOnce2jsArray[A]( - col: GenTraversableOnce[A]): js.Array[A] = { - col match { - case col: js.ArrayOps[A] => col.result() - case col: js.WrappedArray[A] => col.array + def toJSVarArgs[A](seq: Seq[A]): js.Array[A] = { + seq match { + case seq: js.WrappedArray[A] => + seq.array case _ => val result = new js.Array[A] - col.foreach(x => result.push(x)) + seq.foreach(x => result.push(x)) result } } From ac9e4e41ccc3944afaf219befe9cfff5bf111813 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 8 Jan 2018 23:03:56 +0100 Subject: [PATCH 0606/2665] Remove `scala.scalajs.niocharset.StandardCharsets`. It was useful when Scala.js was supported on JDK 6, but not anymore. Instead, users should always use `java.nio.charset.StandardCharsets`. --- javalib/src/main/scala/java/net/URI.scala | 4 +- .../scala/java/nio/charset/ISO_8859_1.scala | 8 +++ .../ISO_8859_1_And_US_ASCII_Common.scala | 14 +---- .../java/nio/charset/StandardCharsets.scala | 16 +++--- .../scala/java/nio/charset/US_ASCII.scala | 8 +++ .../main/scala/java/nio/charset/UTF_16.scala | 6 +++ .../scala/java/nio/charset/UTF_16BE.scala | 6 +++ .../scala/java/nio/charset/UTF_16LE.scala | 6 +++ .../java/nio/charset}/UTF_16_Common.scala | 16 ++---- .../main/scala/java/nio/charset}/UTF_8.scala | 14 +---- .../scala/scalajs/niocharset/ISO_8859_1.scala | 19 ------- .../scalajs/niocharset/StandardCharsets.scala | 42 --------------- .../scala/scalajs/niocharset/US_ASCII.scala | 19 ------- .../scala/scalajs/niocharset/UTF_16.scala | 17 ------ .../scala/scalajs/niocharset/UTF_16BE.scala | 17 ------ .../scala/scalajs/niocharset/UTF_16LE.scala | 17 ------ .../testsuite/niocharset/CharsetJSTest.scala | 46 ---------------- .../testsuite/niocharset/CharsetTest.scala | 54 ++++++++++--------- 18 files changed, 78 insertions(+), 251 deletions(-) create mode 100644 javalib/src/main/scala/java/nio/charset/ISO_8859_1.scala rename {library/src/main/scala/scala/scalajs/niocharset => javalib/src/main/scala/java/nio/charset}/ISO_8859_1_And_US_ASCII_Common.scala (90%) create mode 100644 javalib/src/main/scala/java/nio/charset/US_ASCII.scala create mode 100644 javalib/src/main/scala/java/nio/charset/UTF_16.scala create mode 100644 javalib/src/main/scala/java/nio/charset/UTF_16BE.scala create mode 100644 javalib/src/main/scala/java/nio/charset/UTF_16LE.scala rename {library/src/main/scala/scala/scalajs/niocharset => javalib/src/main/scala/java/nio/charset}/UTF_16_Common.scala (88%) rename {library/src/main/scala/scala/scalajs/niocharset => javalib/src/main/scala/java/nio/charset}/UTF_8.scala (95%) delete mode 100644 library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1.scala delete mode 100644 library/src/main/scala/scala/scalajs/niocharset/StandardCharsets.scala delete mode 100644 library/src/main/scala/scala/scalajs/niocharset/US_ASCII.scala delete mode 100644 library/src/main/scala/scala/scalajs/niocharset/UTF_16.scala delete mode 100644 library/src/main/scala/scala/scalajs/niocharset/UTF_16BE.scala delete mode 100644 library/src/main/scala/scala/scalajs/niocharset/UTF_16LE.scala delete mode 100644 test-suite/js/src/test/scala/org/scalajs/testsuite/niocharset/CharsetJSTest.scala diff --git a/javalib/src/main/scala/java/net/URI.scala b/javalib/src/main/scala/java/net/URI.scala index ba72411f22..a159d45f93 100644 --- a/javalib/src/main/scala/java/net/URI.scala +++ b/javalib/src/main/scala/java/net/URI.scala @@ -3,12 +3,10 @@ package java.net import scala.scalajs.js.RegExp import scala.scalajs.js -import scala.scalajs.niocharset.StandardCharsets - import scala.annotation.tailrec import java.nio._ -import java.nio.charset.CodingErrorAction +import java.nio.charset.{CodingErrorAction, StandardCharsets} final class URI(origStr: String) extends Serializable with Comparable[URI] { diff --git a/javalib/src/main/scala/java/nio/charset/ISO_8859_1.scala b/javalib/src/main/scala/java/nio/charset/ISO_8859_1.scala new file mode 100644 index 0000000000..1cbf9ab48e --- /dev/null +++ b/javalib/src/main/scala/java/nio/charset/ISO_8859_1.scala @@ -0,0 +1,8 @@ +package java.nio.charset + +private[charset] object ISO_8859_1 extends ISO_8859_1_And_US_ASCII_Common( + "ISO-8859-1", Array( + "csISOLatin1", "IBM-819", "iso-ir-100", "8859_1", "ISO_8859-1", "l1", + "ISO8859-1", "ISO_8859_1", "cp819", "ISO8859_1", "latin1", + "ISO_8859-1:1987", "819", "IBM819"), + maxValue = 0xff) diff --git a/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1_And_US_ASCII_Common.scala b/javalib/src/main/scala/java/nio/charset/ISO_8859_1_And_US_ASCII_Common.scala similarity index 90% rename from library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1_And_US_ASCII_Common.scala rename to javalib/src/main/scala/java/nio/charset/ISO_8859_1_And_US_ASCII_Common.scala index 2d4937f628..6271dec23b 100644 --- a/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1_And_US_ASCII_Common.scala +++ b/javalib/src/main/scala/java/nio/charset/ISO_8859_1_And_US_ASCII_Common.scala @@ -1,18 +1,8 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package scala.scalajs.niocharset +package java.nio.charset import scala.annotation.tailrec import java.nio._ -import java.nio.charset._ /** This is a very specific common implementation for ISO_8859_1 and US_ASCII. * Only a single constant changes between the two algorithms (`maxValue`). @@ -20,7 +10,7 @@ import java.nio.charset._ * * `maxValue` is therefore either 0xff (ISO_8859_1) or 0x7f (US_ASCII). */ -private[niocharset] abstract class ISO_8859_1_And_US_ASCII_Common protected ( +private[charset] abstract class ISO_8859_1_And_US_ASCII_Common protected ( name: String, aliases: Array[String], private val maxValue: Int) extends Charset(name, aliases) { diff --git a/javalib/src/main/scala/java/nio/charset/StandardCharsets.scala b/javalib/src/main/scala/java/nio/charset/StandardCharsets.scala index 62e2c2bad6..6c6372bdbc 100644 --- a/javalib/src/main/scala/java/nio/charset/StandardCharsets.scala +++ b/javalib/src/main/scala/java/nio/charset/StandardCharsets.scala @@ -1,14 +1,14 @@ package java.nio.charset +import java.nio.charset + final class StandardCharsets private () object StandardCharsets { - import scala.scalajs.niocharset.{StandardCharsets => SC} - - def ISO_8859_1: Charset = SC.ISO_8859_1 - def US_ASCII: Charset = SC.US_ASCII - def UTF_8: Charset = SC.UTF_8 - def UTF_16BE: Charset = SC.UTF_16BE - def UTF_16LE: Charset = SC.UTF_16LE - def UTF_16: Charset = SC.UTF_16 + def US_ASCII: Charset = charset.US_ASCII + def ISO_8859_1: Charset = charset.ISO_8859_1 + def UTF_8: Charset = charset.UTF_8 + def UTF_16BE: Charset = charset.UTF_16BE + def UTF_16LE: Charset = charset.UTF_16LE + def UTF_16: Charset = charset.UTF_16 } diff --git a/javalib/src/main/scala/java/nio/charset/US_ASCII.scala b/javalib/src/main/scala/java/nio/charset/US_ASCII.scala new file mode 100644 index 0000000000..d7497e0a4e --- /dev/null +++ b/javalib/src/main/scala/java/nio/charset/US_ASCII.scala @@ -0,0 +1,8 @@ +package java.nio.charset + +private[charset] object US_ASCII extends ISO_8859_1_And_US_ASCII_Common( + "US-ASCII", Array( + "cp367", "ascii7", "ISO646-US", "646", "csASCII", "us", "iso_646.irv:1983", + "ISO_646.irv:1991", "IBM367", "ASCII", "default", "ANSI_X3.4-1986", + "ANSI_X3.4-1968", "iso-ir-6"), + maxValue = 0x7f) diff --git a/javalib/src/main/scala/java/nio/charset/UTF_16.scala b/javalib/src/main/scala/java/nio/charset/UTF_16.scala new file mode 100644 index 0000000000..4b1fbbc49a --- /dev/null +++ b/javalib/src/main/scala/java/nio/charset/UTF_16.scala @@ -0,0 +1,6 @@ +package java.nio.charset + +private[charset] object UTF_16 extends UTF_16_Common( + "UTF-16", Array( + "utf16", "UTF_16", "UnicodeBig", "unicode"), + endianness = UTF_16_Common.AutoEndian) diff --git a/javalib/src/main/scala/java/nio/charset/UTF_16BE.scala b/javalib/src/main/scala/java/nio/charset/UTF_16BE.scala new file mode 100644 index 0000000000..d25f4349ae --- /dev/null +++ b/javalib/src/main/scala/java/nio/charset/UTF_16BE.scala @@ -0,0 +1,6 @@ +package java.nio.charset + +private[charset] object UTF_16BE extends UTF_16_Common( + "UTF-16BE", Array( + "X-UTF-16BE", "UTF_16BE", "ISO-10646-UCS-2", "UnicodeBigUnmarked"), + endianness = UTF_16_Common.BigEndian) diff --git a/javalib/src/main/scala/java/nio/charset/UTF_16LE.scala b/javalib/src/main/scala/java/nio/charset/UTF_16LE.scala new file mode 100644 index 0000000000..dc8d2404d2 --- /dev/null +++ b/javalib/src/main/scala/java/nio/charset/UTF_16LE.scala @@ -0,0 +1,6 @@ +package java.nio.charset + +private[charset] object UTF_16LE extends UTF_16_Common( + "UTF-16LE", Array( + "UnicodeLittleUnmarked", "UTF_16LE", "X-UTF-16LE"), + endianness = UTF_16_Common.LittleEndian) diff --git a/library/src/main/scala/scala/scalajs/niocharset/UTF_16_Common.scala b/javalib/src/main/scala/java/nio/charset/UTF_16_Common.scala similarity index 88% rename from library/src/main/scala/scala/scalajs/niocharset/UTF_16_Common.scala rename to javalib/src/main/scala/java/nio/charset/UTF_16_Common.scala index 5bac2120bb..63f390e2e6 100644 --- a/library/src/main/scala/scala/scalajs/niocharset/UTF_16_Common.scala +++ b/javalib/src/main/scala/java/nio/charset/UTF_16_Common.scala @@ -1,22 +1,12 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package scala.scalajs.niocharset +package java.nio.charset import scala.annotation.tailrec import java.nio._ -import java.nio.charset._ /** This is a very specific common implementation for UTF_16BE and UTF_16LE. */ -private[niocharset] abstract class UTF_16_Common protected ( +private[charset] abstract class UTF_16_Common protected ( name: String, aliases: Array[String], private val endianness: Int) extends Charset(name, aliases) { @@ -198,7 +188,7 @@ private[niocharset] abstract class UTF_16_Common protected ( } } -private[niocharset] object UTF_16_Common { +private[charset] object UTF_16_Common { final val AutoEndian = 0 final val BigEndian = 1 final val LittleEndian = 2 diff --git a/library/src/main/scala/scala/scalajs/niocharset/UTF_8.scala b/javalib/src/main/scala/java/nio/charset/UTF_8.scala similarity index 95% rename from library/src/main/scala/scala/scalajs/niocharset/UTF_8.scala rename to javalib/src/main/scala/java/nio/charset/UTF_8.scala index bf19bb02f8..ac695c3e09 100644 --- a/library/src/main/scala/scala/scalajs/niocharset/UTF_8.scala +++ b/javalib/src/main/scala/java/nio/charset/UTF_8.scala @@ -1,20 +1,10 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package scala.scalajs.niocharset +package java.nio.charset import scala.annotation.{switch, tailrec} import java.nio._ -import java.nio.charset._ -private[niocharset] object UTF_8 extends Charset("UTF-8", Array( +private[charset] object UTF_8 extends Charset("UTF-8", Array( "UTF8", "unicode-1-1-utf-8")) { import java.lang.Character._ diff --git a/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1.scala b/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1.scala deleted file mode 100644 index 7765f0ca36..0000000000 --- a/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1.scala +++ /dev/null @@ -1,19 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package scala.scalajs.niocharset - -import java.nio.charset._ - -private[niocharset] object ISO_8859_1 extends ISO_8859_1_And_US_ASCII_Common( - "ISO-8859-1", Array( - "csISOLatin1", "IBM-819", "iso-ir-100", "8859_1", "ISO_8859-1", "l1", - "ISO8859-1", "ISO_8859_1", "cp819", "ISO8859_1", "latin1", - "ISO_8859-1:1987", "819", "IBM819"), - maxValue = 0xff) diff --git a/library/src/main/scala/scala/scalajs/niocharset/StandardCharsets.scala b/library/src/main/scala/scala/scalajs/niocharset/StandardCharsets.scala deleted file mode 100644 index 38615f6d77..0000000000 --- a/library/src/main/scala/scala/scalajs/niocharset/StandardCharsets.scala +++ /dev/null @@ -1,42 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package scala.scalajs.niocharset - -import java.nio.charset._ - -/** Standard charsets. - * This is basically the same as [[java.nio.charset.StandardCharsets]], but - * it is also available when compiling with a JDK 6. - */ -object StandardCharsets { - import scala.scalajs.niocharset - - /** ISO-8859-1, aka latin1. */ - def ISO_8859_1: Charset = niocharset.ISO_8859_1 - - /** US-ASCII. */ - def US_ASCII: Charset = niocharset.US_ASCII - - /** UTF-8. */ - def UTF_8: Charset = niocharset.UTF_8 - - /** UTF-16 Big Endian without BOM. */ - def UTF_16BE: Charset = niocharset.UTF_16BE - - /** UTF-16 Little Endian without BOM. */ - def UTF_16LE: Charset = niocharset.UTF_16LE - - /** UTF-16 with an optional BOM. - * When encoding, Big Endian is always used. - * When decoding, the BOM specifies what endianness to use. If no BOM is - * found, it defaults to Big Endian. - */ - def UTF_16: Charset = niocharset.UTF_16 -} diff --git a/library/src/main/scala/scala/scalajs/niocharset/US_ASCII.scala b/library/src/main/scala/scala/scalajs/niocharset/US_ASCII.scala deleted file mode 100644 index 746c75b871..0000000000 --- a/library/src/main/scala/scala/scalajs/niocharset/US_ASCII.scala +++ /dev/null @@ -1,19 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package scala.scalajs.niocharset - -import java.nio.charset._ - -private[niocharset] object US_ASCII extends ISO_8859_1_And_US_ASCII_Common( - "US-ASCII", Array( - "cp367", "ascii7", "ISO646-US", "646", "csASCII", "us", "iso_646.irv:1983", - "ISO_646.irv:1991", "IBM367", "ASCII", "default", "ANSI_X3.4-1986", - "ANSI_X3.4-1968", "iso-ir-6"), - maxValue = 0x7f) diff --git a/library/src/main/scala/scala/scalajs/niocharset/UTF_16.scala b/library/src/main/scala/scala/scalajs/niocharset/UTF_16.scala deleted file mode 100644 index 9d1748a7cf..0000000000 --- a/library/src/main/scala/scala/scalajs/niocharset/UTF_16.scala +++ /dev/null @@ -1,17 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package scala.scalajs.niocharset - -import java.nio.charset._ - -private[niocharset] object UTF_16 extends UTF_16_Common( - "UTF-16", Array( - "utf16", "UTF_16", "UnicodeBig", "unicode"), - endianness = UTF_16_Common.AutoEndian) diff --git a/library/src/main/scala/scala/scalajs/niocharset/UTF_16BE.scala b/library/src/main/scala/scala/scalajs/niocharset/UTF_16BE.scala deleted file mode 100644 index dece19161b..0000000000 --- a/library/src/main/scala/scala/scalajs/niocharset/UTF_16BE.scala +++ /dev/null @@ -1,17 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package scala.scalajs.niocharset - -import java.nio.charset._ - -private[niocharset] object UTF_16BE extends UTF_16_Common( - "UTF-16BE", Array( - "X-UTF-16BE", "UTF_16BE", "ISO-10646-UCS-2", "UnicodeBigUnmarked"), - endianness = UTF_16_Common.BigEndian) diff --git a/library/src/main/scala/scala/scalajs/niocharset/UTF_16LE.scala b/library/src/main/scala/scala/scalajs/niocharset/UTF_16LE.scala deleted file mode 100644 index de469c40aa..0000000000 --- a/library/src/main/scala/scala/scalajs/niocharset/UTF_16LE.scala +++ /dev/null @@ -1,17 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package scala.scalajs.niocharset - -import java.nio.charset._ - -private[niocharset] object UTF_16LE extends UTF_16_Common( - "UTF-16LE", Array( - "UnicodeLittleUnmarked", "UTF_16LE", "X-UTF-16LE"), - endianness = UTF_16_Common.LittleEndian) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/niocharset/CharsetJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/niocharset/CharsetJSTest.scala deleted file mode 100644 index 562fe161c2..0000000000 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/niocharset/CharsetJSTest.scala +++ /dev/null @@ -1,46 +0,0 @@ -package org.scalajs.testsuite.niocharset - -import scala.language.implicitConversions - -import scala.scalajs.niocharset.StandardCharsets._ - -import java.nio.charset._ - -import org.junit.Test -import org.junit.Assert._ - -class CharsetJSTest { - - @Test def defaultCharset(): Unit = { - assertSame(UTF_8, Charset.defaultCharset()) - } - - @Test def forName(): Unit = { - assertSame(ISO_8859_1, Charset.forName("ISO-8859-1")) - assertSame(ISO_8859_1, Charset.forName("Iso8859-1")) - assertSame(ISO_8859_1, Charset.forName("iso_8859_1")) - assertSame(ISO_8859_1, Charset.forName("LaTin1")) - assertSame(ISO_8859_1, Charset.forName("l1")) - - assertSame(US_ASCII, Charset.forName("US-ASCII")) - assertSame(US_ASCII, Charset.forName("Default")) - - assertSame(UTF_8, Charset.forName("UTF-8")) - assertSame(UTF_8, Charset.forName("utf-8")) - assertSame(UTF_8, Charset.forName("UtF8")) - assertSame(UTF_8, Charset.forName("UTF-8")) - - assertSame(UTF_16BE, Charset.forName("UTF-16BE")) - assertSame(UTF_16BE, Charset.forName("Utf_16BE")) - assertSame(UTF_16BE, Charset.forName("UnicodeBigUnmarked")) - - assertSame(UTF_16LE, Charset.forName("UTF-16le")) - assertSame(UTF_16LE, Charset.forName("Utf_16le")) - assertSame(UTF_16LE, Charset.forName("UnicodeLittleUnmarked")) - - assertSame(UTF_16, Charset.forName("UTF-16")) - assertSame(UTF_16, Charset.forName("Utf_16")) - assertSame(UTF_16, Charset.forName("unicode")) - assertSame(UTF_16, Charset.forName("UnicodeBig")) - } -} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/CharsetTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/CharsetTest.scala index 679bfa43da..75164c8ae3 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/CharsetTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/CharsetTest.scala @@ -10,6 +10,7 @@ package org.scalajs.testsuite.niocharset import scala.collection.JavaConverters._ import java.nio.charset._ +import java.nio.charset.StandardCharsets._ import org.junit.Test import org.junit.Assert._ @@ -21,35 +22,36 @@ class CharsetTest { def javaSet[A](elems: A*): java.util.Set[A] = Set(elems: _*).asJava @Test def defaultCharset(): Unit = { - assertSame("UTF-8", Charset.defaultCharset().name()) + assertSame(UTF_8, Charset.defaultCharset()) } @Test def forName(): Unit = { - assertEquals("ISO-8859-1", Charset.forName("ISO-8859-1").name()) - assertEquals("ISO-8859-1", Charset.forName("Iso8859-1").name()) - assertEquals("ISO-8859-1", Charset.forName("iso_8859_1").name()) - assertEquals("ISO-8859-1", Charset.forName("LaTin1").name()) - assertEquals("ISO-8859-1", Charset.forName("l1").name()) - - assertEquals("US-ASCII", Charset.forName("US-ASCII").name()) - assertEquals("US-ASCII", Charset.forName("Default").name()) - - assertEquals("UTF-8", Charset.forName("UTF-8").name()) - assertEquals("UTF-8", Charset.forName("utf-8").name()) - assertEquals("UTF-8", Charset.forName("UtF8").name()) - - assertEquals("UTF-16BE", Charset.forName("UTF-16BE").name()) - assertEquals("UTF-16BE", Charset.forName("Utf_16BE").name()) - assertEquals("UTF-16BE", Charset.forName("UnicodeBigUnmarked").name()) - - assertEquals("UTF-16LE", Charset.forName("UTF-16le").name()) - assertEquals("UTF-16LE", Charset.forName("Utf_16le").name()) - assertEquals("UTF-16LE", Charset.forName("UnicodeLittleUnmarked").name()) - - assertEquals("UTF-16", Charset.forName("UTF-16").name()) - assertEquals("UTF-16", Charset.forName("Utf_16").name()) - assertEquals("UTF-16", Charset.forName("unicode").name()) - assertEquals("UTF-16", Charset.forName("UnicodeBig").name()) + assertSame(ISO_8859_1, Charset.forName("ISO-8859-1")) + assertSame(ISO_8859_1, Charset.forName("Iso8859-1")) + assertSame(ISO_8859_1, Charset.forName("iso_8859_1")) + assertSame(ISO_8859_1, Charset.forName("LaTin1")) + assertSame(ISO_8859_1, Charset.forName("l1")) + + assertSame(US_ASCII, Charset.forName("US-ASCII")) + assertSame(US_ASCII, Charset.forName("Default")) + + assertSame(UTF_8, Charset.forName("UTF-8")) + assertSame(UTF_8, Charset.forName("utf-8")) + assertSame(UTF_8, Charset.forName("UtF8")) + assertSame(UTF_8, Charset.forName("UTF-8")) + + assertSame(UTF_16BE, Charset.forName("UTF-16BE")) + assertSame(UTF_16BE, Charset.forName("Utf_16BE")) + assertSame(UTF_16BE, Charset.forName("UnicodeBigUnmarked")) + + assertSame(UTF_16LE, Charset.forName("UTF-16le")) + assertSame(UTF_16LE, Charset.forName("Utf_16le")) + assertSame(UTF_16LE, Charset.forName("UnicodeLittleUnmarked")) + + assertSame(UTF_16, Charset.forName("UTF-16")) + assertSame(UTF_16, Charset.forName("Utf_16")) + assertSame(UTF_16, Charset.forName("unicode")) + assertSame(UTF_16, Charset.forName("UnicodeBig")) // Issue #2040 expectThrows(classOf[UnsupportedCharsetException], Charset.forName("UTF_8")) From d5709ad8796830bfeb3423908196eb18e534162c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 8 Jan 2018 23:19:27 +0100 Subject: [PATCH 0607/2665] Simplify the definition of `Charset.CharsetMap`. It used to duplicate the list of aliases of all the charsets. Instead, we now fetch them from the `_aliases` field of `Charset`. --- .../main/scala/java/nio/charset/Charset.scala | 40 ++++--------------- 1 file changed, 7 insertions(+), 33 deletions(-) diff --git a/javalib/src/main/scala/java/nio/charset/Charset.scala b/javalib/src/main/scala/java/nio/charset/Charset.scala index 71396e9eb9..a90eb35622 100644 --- a/javalib/src/main/scala/java/nio/charset/Charset.scala +++ b/javalib/src/main/scala/java/nio/charset/Charset.scala @@ -6,7 +6,8 @@ import java.util.{Collections, HashSet, Arrays} import scala.scalajs.js abstract class Charset protected (canonicalName: String, - _aliases: Array[String]) extends AnyRef with Comparable[Charset] { + private val _aliases: Array[String]) + extends AnyRef with Comparable[Charset] { private lazy val aliasesSet = Collections.unmodifiableSet(new HashSet(Arrays.asList(_aliases))) @@ -73,38 +74,11 @@ object Charset { private lazy val CharsetMap = { val m = js.Dictionary.empty[Charset] - - // All these lists where obtained by experimentation on the JDK - - for (s <- Seq("iso-8859-1", "iso8859-1", "iso_8859_1", "iso8859_1", - "iso_8859-1", "8859_1", "iso_8859-1:1987", - "latin1", "csisolatin1", "l1", - "ibm-819", "ibm819", "cp819", "819", - "iso-ir-100")) - m(s) = ISO_8859_1 - - for (s <- Seq("us-ascii", "ascii7", "ascii", "csascii", - "default", - "cp367", "ibm367", - "iso646-us", "646", "iso_646.irv:1983", "iso_646.irv:1991", - "ansi_x3.4-1986", "ansi_x3.4-1968", - "iso-ir-6")) - m(s) = US_ASCII - - for (s <- Seq("utf-8", "utf8", "unicode-1-1-utf-8")) - m(s) = UTF_8 - - for (s <- Seq("utf-16be", "utf_16be", "x-utf-16be", - "iso-10646-ucs-2", "unicodebigunmarked")) - m(s) = UTF_16BE - - for (s <- Seq("utf-16le", "utf_16le", "x-utf-16le", - "unicodelittleunmarked")) - m(s) = UTF_16LE - - for (s <- Seq("utf-16", "utf_16", "unicode", "unicodebig")) - m(s) = UTF_16 - + for (c <- js.Array(US_ASCII, ISO_8859_1, UTF_8, UTF_16BE, UTF_16LE, UTF_16)) { + m(c.name.toLowerCase) = c + for (alias <- c._aliases) + m(alias.toLowerCase) = c + } m } } From 3d831209f6d4bbf1aaad1fde83358e416b1a5a56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 11 Jan 2018 00:37:27 +0100 Subject: [PATCH 0608/2665] Stricter typing for `JSSpread`s in the IR. Previously, `JSSpread` extended `Tree` That was nonsense because `Tree`s are supposed to be valid anywhere in statement/expression position (provided they typecheck), although `JSSpread`s are only valid in very specific positions, structurally speaking. We reify those restrictions in the types of the IR nodes, by introducing `TreeOrJSSpread` as a common super type for `Tree` and `JSSpread`. --- .../org/scalajs/core/compiler/GenJSCode.scala | 64 +++++++++++------ .../scalajs/core/compiler/GenJSExports.scala | 4 +- .../scala/org/scalajs/core/ir/Hashers.scala | 31 +++++--- .../scala/org/scalajs/core/ir/Printers.scala | 12 ++-- .../org/scalajs/core/ir/Serializers.scala | 61 +++++++++++----- .../main/scala/org/scalajs/core/ir/Tags.scala | 7 +- .../org/scalajs/core/ir/Transformers.scala | 26 ++++--- .../org/scalajs/core/ir/Traversers.scala | 22 +++--- .../scala/org/scalajs/core/ir/Trees.scala | 27 ++++--- .../backend/emitter/FunctionEmitter.scala | 70 ++++++++++++------- .../core/tools/linker/checker/IRChecker.scala | 5 +- .../frontend/optimizer/OptimizerCore.scala | 18 +++-- 12 files changed, 217 insertions(+), 130 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 7fb103ba83..6e15221f5f 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -635,7 +635,7 @@ abstract class GenJSCode extends plugins.PluginComponent * @param pos Position of the original New tree */ def genAnonJSClassNew(sym: Symbol, jsSuperClassValue: js.Tree, - args: List[js.Tree], pos: Position): js.Tree = { + args: List[js.TreeOrJSSpread], pos: Position): js.Tree = { assert(isAnonJSClass(sym), "Generating AnonJSClassNew of non anonymous JS class") @@ -4051,8 +4051,15 @@ abstract class GenJSCode extends plugins.PluginComponent implicit val pos = tree.pos - def receiver = genExpr(receiver0) - def genArgs = genPrimitiveJSArgs(tree.symbol, args) + def receiver: js.Tree = genExpr(receiver0) + def genArgs: List[js.TreeOrJSSpread] = genPrimitiveJSArgs(tree.symbol, args) + + def genArgsNoSpread: List[js.Tree] = { + val genArgs1 = genArgs + assert(!genArgs1.exists(_.isInstanceOf[js.JSSpread]), + s"Unexpected spread at $pos") + genArgs1.asInstanceOf[List[js.Tree]] + } def resolveReifiedJSClassSym(arg: Tree): Symbol = { def fail(): Symbol = { @@ -4115,7 +4122,7 @@ abstract class GenJSCode extends plugins.PluginComponent ) { genStatOrExpr(args(1), isStat) } - } else (genArgs match { + } else (genArgsNoSpread match { case Nil => code match { case LINKING_INFO => js.JSLinkingInfo() @@ -4211,10 +4218,16 @@ abstract class GenJSCode extends plugins.PluginComponent } private def genJSCallGeneric(sym: Symbol, receiver: MaybeGlobalScope, - args: List[js.Tree], isStat: Boolean, + args: List[js.TreeOrJSSpread], isStat: Boolean, jsSuperClassValue: Option[js.Tree] = None)( implicit pos: Position): js.Tree = { - def noSpread = !args.exists(_.isInstanceOf[js.JSSpread]) + + def argsNoSpread: List[js.Tree] = { + assert(!args.exists(_.isInstanceOf[js.JSSpread]), + s"Unexpected spread at $pos") + args.asInstanceOf[List[js.Tree]] + } + val argc = args.size // meaningful only for methods that don't have varargs def requireNotSuper(): Unit = { @@ -4236,7 +4249,7 @@ abstract class GenJSCode extends plugins.PluginComponent case JSBinaryOpMethodName(code) if argc == 1 => requireNotSuper() - js.JSBinaryOp(code, ruleOutGlobalScope(receiver), args.head) + js.JSBinaryOp(code, ruleOutGlobalScope(receiver), argsNoSpread.head) case nme.apply if sym.owner.isSubClass(JSThisFunctionClass) => requireNotSuper() @@ -4265,7 +4278,8 @@ abstract class GenJSCode extends plugins.PluginComponent def genSelectSet(propName: js.Tree, value: js.Tree): js.Tree = js.Assign(genSuperReference(propName), value) - def genCall(methodName: js.Tree, args: List[js.Tree]): js.Tree = { + def genCall(methodName: js.Tree, + args: List[js.TreeOrJSSpread]): js.Tree = { jsSuperClassValue.fold[js.Tree] { genJSBracketMethodApplyOrGlobalRefApply( receiver, methodName, args) @@ -4276,15 +4290,15 @@ abstract class GenJSCode extends plugins.PluginComponent } if (jsInterop.isJSGetter(sym)) { - assert(noSpread && argc == 0) + assert(argc == 0) genSelectGet(jsFunName) } else if (jsInterop.isJSSetter(sym)) { - assert(noSpread && argc == 1) - genSelectSet(jsFunName, args.head) + assert(argc == 1) + genSelectSet(jsFunName, argsNoSpread.head) } else if (jsInterop.isJSBracketAccess(sym)) { - assert(noSpread && (argc == 1 || argc == 2), + assert(argc == 1 || argc == 2, s"@JSBracketAccess methods should have 1 or 2 non-varargs arguments") - args match { + argsNoSpread match { case List(keyArg) => genSelectGet(keyArg) case List(keyArg, valueArg) => @@ -4353,13 +4367,18 @@ abstract class GenJSCode extends plugins.PluginComponent * This is nothing else than decomposing into head and tail, except that * we assert that the first element is not a JSSpread. */ - private def extractFirstArg(args: List[js.Tree]): (js.Tree, List[js.Tree]) = { + private def extractFirstArg( + args: List[js.TreeOrJSSpread]): (js.Tree, List[js.TreeOrJSSpread]) = { assert(args.nonEmpty, "Trying to extract the first argument of an empty argument list") - val firstArg = args.head - assert(!firstArg.isInstanceOf[js.JSSpread], - "Trying to extract the first argument of an argument list starting " + - "with a Spread argument: " + firstArg) + val firstArg = args.head match { + case firstArg: js.Tree => + firstArg + case firstArg: js.JSSpread => + throw new AssertionError( + "Trying to extract the first argument of an argument list starting " + + "with a Spread argument: " + firstArg) + } (firstArg, args.tail) } @@ -4460,7 +4479,7 @@ abstract class GenJSCode extends plugins.PluginComponent * wrapped in a [[js.JSSpread]] node to be expanded at runtime. */ private def genPrimitiveJSArgs(sym: Symbol, args: List[Tree])( - implicit pos: Position): List[js.Tree] = { + implicit pos: Position): List[js.TreeOrJSSpread] = { /* For constructors of nested JS classes (*), explicitouter and * lambdalift have introduced some parameters for the outer parameter and @@ -4505,7 +4524,7 @@ abstract class GenJSCode extends plugins.PluginComponent yield param.name -> param.tpe }.toMap - var reversedArgs: List[js.Tree] = Nil + var reversedArgs: List[js.TreeOrJSSpread] = Nil for ((arg, paramSym) <- args zip sym.tpe.params) { val wasRepeated = @@ -4563,7 +4582,7 @@ abstract class GenJSCode extends plugins.PluginComponent * compile-time. * Otherwise, it returns a JSSpread with the Seq converted to a js.Array. */ - private def genPrimitiveJSRepeatedParam(arg: Tree): List[js.Tree] = { + private def genPrimitiveJSRepeatedParam(arg: Tree): List[js.TreeOrJSSpread] = { tryGenRepeatedParamAsJSArray(arg, handleNil = true) getOrElse { /* Fall back to calling runtime.toJSVarArgs to perform the conversion * to js.Array, then wrap in a Spread operator. @@ -5355,7 +5374,8 @@ abstract class GenJSCode extends plugins.PluginComponent * Otherwise, report a compile error. */ private def genJSBracketMethodApplyOrGlobalRefApply( - receiver: MaybeGlobalScope, method: js.Tree, args: List[js.Tree])( + receiver: MaybeGlobalScope, method: js.Tree, + args: List[js.TreeOrJSSpread])( implicit pos: Position): js.Tree = { receiver match { case MaybeGlobalScope.NotGlobalScope(receiverTree) => diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index deb6f7d286..d7a33771db 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -641,9 +641,9 @@ trait GenJSExports extends SubComponent { self: GenJSCode => assert(allArgs.isEmpty) js.JSSuperBracketSelect(superClass, receiver, nameString) } else if (jsInterop.isJSSetter(sym)) { - assert(allArgs.size == 1 && !allArgs.head.isInstanceOf[js.JSSpread]) + assert(allArgs.size == 1 && allArgs.head.isInstanceOf[js.Tree]) js.Assign(js.JSSuperBracketSelect(superClass, receiver, nameString), - allArgs.head) + allArgs.head.asInstanceOf[js.Tree]) } else { js.JSSuperBracketCall(superClass, receiver, nameString, allArgs) } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala index 6f5ad84d6f..98b8d58133 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala @@ -288,7 +288,7 @@ object Hashers { case JSNew(ctor, args) => mixTag(TagJSNew) mixTree(ctor) - mixTrees(args) + mixTreeOrJSSpreads(args) case JSDotSelect(qualifier, item) => mixTag(TagJSDotSelect) @@ -303,19 +303,19 @@ object Hashers { case JSFunctionApply(fun, args) => mixTag(TagJSFunctionApply) mixTree(fun) - mixTrees(args) + mixTreeOrJSSpreads(args) case JSDotMethodApply(receiver, method, args) => mixTag(TagJSDotMethodApply) mixTree(receiver) mixIdent(method) - mixTrees(args) + mixTreeOrJSSpreads(args) case JSBracketMethodApply(receiver, method, args) => mixTag(TagJSBracketMethodApply) mixTree(receiver) mixTree(method) - mixTrees(args) + mixTreeOrJSSpreads(args) case JSSuperBracketSelect(superClass, qualifier, item) => mixTag(TagJSSuperBracketSelect) @@ -328,11 +328,11 @@ object Hashers { mixTree(superClass) mixTree(receiver) mixTree(method) - mixTrees(args) + mixTreeOrJSSpreads(args) case JSSuperConstructorCall(args) => mixTag(TagJSSuperConstructorCall) - mixTrees(args) + mixTreeOrJSSpreads(args) case LoadJSConstructor(cls) => mixTag(TagLoadJSConstructor) @@ -342,10 +342,6 @@ object Hashers { mixTag(TagLoadJSModule) mixType(cls) - case JSSpread(items) => - mixTag(TagJSSpread) - mixTree(items) - case JSDelete(prop) => mixTag(TagJSDelete) mixTree(prop) @@ -363,7 +359,7 @@ object Hashers { case JSArrayConstr(items) => mixTag(TagJSArrayConstr) - mixTrees(items) + mixTreeOrJSSpreads(items) case JSObjectConstr(fields) => mixTag(TagJSObjectConstr) @@ -467,6 +463,19 @@ object Hashers { def mixTrees(trees: List[Tree]): Unit = trees.foreach(mixTree) + def mixTreeOrJSSpreads(trees: List[TreeOrJSSpread]): Unit = + trees.foreach(mixTreeOrJSSpread) + + def mixTreeOrJSSpread(tree: TreeOrJSSpread): Unit = { + tree match { + case JSSpread(items) => + mixTag(TagJSSpread) + mixTree(items) + case tree: Tree => + mixTree(tree) + } + } + def mixTypeRef(typeRef: TypeRef): Unit = typeRef match { case ClassRef(className) => mixTag(TagClassRef) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index 444dde7833..a3da382e33 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -96,7 +96,7 @@ object Printers { } } - protected def printArgs(args: List[Tree]): Unit = { + protected def printArgs(args: List[TreeOrJSSpread]): Unit = { printRow(args, "(", ", ", ")") } @@ -106,6 +106,7 @@ object Printers { case node: ComputedName => print(node) case node: ParamDef => print(node) case node: Tree => print(node) + case node: JSSpread => print(node) case node: ClassDef => print(node) case node: MemberDef => print(node) case node: TopLevelExportDef => print(node) @@ -610,10 +611,6 @@ object Printers { print("mod:") print(cls) - case JSSpread(items) => - print("...") - print(items) - case JSDelete(prop) => print("delete ") print(prop) @@ -820,6 +817,11 @@ object Printers { } } + def print(spread: JSSpread): Unit = { + print("...") + print(spread.items) + } + def print(classDef: ClassDef): Unit = { import classDef._ for (jsClassCaptures <- classDef.jsClassCaptures) { diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index 8bc4ba429e..4b57159c03 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -289,7 +289,7 @@ object Serializers { case JSNew(ctor, args) => writeByte(TagJSNew) - writeTree(ctor); writeTrees(args) + writeTree(ctor); writeTreeOrJSSpreads(args) case JSDotSelect(qualifier, item) => writeByte(TagJSDotSelect) @@ -301,15 +301,15 @@ object Serializers { case JSFunctionApply(fun, args) => writeByte(TagJSFunctionApply) - writeTree(fun); writeTrees(args) + writeTree(fun); writeTreeOrJSSpreads(args) case JSDotMethodApply(receiver, method, args) => writeByte(TagJSDotMethodApply) - writeTree(receiver); writeIdent(method); writeTrees(args) + writeTree(receiver); writeIdent(method); writeTreeOrJSSpreads(args) case JSBracketMethodApply(receiver, method, args) => writeByte(TagJSBracketMethodApply) - writeTree(receiver); writeTree(method); writeTrees(args) + writeTree(receiver); writeTree(method); writeTreeOrJSSpreads(args) case JSSuperBracketSelect(superClass, qualifier, item) => writeByte(TagJSSuperBracketSelect) @@ -317,11 +317,11 @@ object Serializers { case JSSuperBracketCall(superClass, receiver, method, args) => writeByte(TagJSSuperBracketCall) - writeTree(superClass); writeTree(receiver); writeTree(method); writeTrees(args) + writeTree(superClass); writeTree(receiver); writeTree(method); writeTreeOrJSSpreads(args) case JSSuperConstructorCall(args) => writeByte(TagJSSuperConstructorCall) - writeTrees(args) + writeTreeOrJSSpreads(args) case LoadJSConstructor(cls) => writeByte(TagLoadJSConstructor) @@ -331,10 +331,6 @@ object Serializers { writeByte(TagLoadJSModule) writeClassType(cls) - case JSSpread(items) => - writeByte(TagJSSpread) - writeTree(items) - case JSDelete(prop) => writeByte(TagJSDelete) writeTree(prop) @@ -349,7 +345,7 @@ object Serializers { case JSArrayConstr(items) => writeByte(TagJSArrayConstr) - writeTrees(items) + writeTreeOrJSSpreads(items) case JSObjectConstr(fields) => writeByte(TagJSObjectConstr) @@ -459,6 +455,22 @@ object Serializers { } } + def writeTreeOrJSSpreads(trees: List[TreeOrJSSpread]): Unit = { + buffer.writeInt(trees.size) + trees.foreach(writeTreeOrJSSpread) + } + + def writeTreeOrJSSpread(tree: TreeOrJSSpread): Unit = { + tree match { + case JSSpread(items) => + writePosition(tree.pos) + buffer.writeByte(TagJSSpread) + writeTree(items) + case tree: Tree => + writeTree(tree) + } + } + def writeClassDef(classDef: ClassDef): Unit = { import buffer._ import classDef._ @@ -812,6 +824,18 @@ object Serializers { else Some(readTreeFromTag(tag)(pos)) } + def readTreeOrJSSpread(): TreeOrJSSpread = { + val pos = readPosition() + val tag = input.readByte() + if (tag == TagJSSpread) + JSSpread(readTree())(pos) + else + readTreeFromTag(tag)(pos) + } + + def readTreeOrJSSpreads(): List[TreeOrJSSpread] = + List.fill(input.readInt())(readTreeOrJSSpread) + private def readTreeFromTag(tag: Byte)(implicit pos: Position): Tree = { import input._ val result = (tag: @switch) match { @@ -863,23 +887,22 @@ object Serializers { case TagGetClass => GetClass(readTree()) case TagCallHelper => CallHelper(readString(), readTrees())(readType()) - case TagJSNew => JSNew(readTree(), readTrees()) + case TagJSNew => JSNew(readTree(), readTreeOrJSSpreads()) case TagJSDotSelect => JSDotSelect(readTree(), readIdent()) case TagJSBracketSelect => JSBracketSelect(readTree(), readTree()) - case TagJSFunctionApply => JSFunctionApply(readTree(), readTrees()) - case TagJSDotMethodApply => JSDotMethodApply(readTree(), readIdent(), readTrees()) - case TagJSBracketMethodApply => JSBracketMethodApply(readTree(), readTree(), readTrees()) + case TagJSFunctionApply => JSFunctionApply(readTree(), readTreeOrJSSpreads()) + case TagJSDotMethodApply => JSDotMethodApply(readTree(), readIdent(), readTreeOrJSSpreads()) + case TagJSBracketMethodApply => JSBracketMethodApply(readTree(), readTree(), readTreeOrJSSpreads()) case TagJSSuperBracketSelect => JSSuperBracketSelect(readTree(), readTree(), readTree()) case TagJSSuperBracketCall => - JSSuperBracketCall(readTree(), readTree(), readTree(), readTrees()) - case TagJSSuperConstructorCall => JSSuperConstructorCall(readTrees()) + JSSuperBracketCall(readTree(), readTree(), readTree(), readTreeOrJSSpreads()) + case TagJSSuperConstructorCall => JSSuperConstructorCall(readTreeOrJSSpreads()) case TagLoadJSConstructor => LoadJSConstructor(readClassType()) case TagLoadJSModule => LoadJSModule(readClassType()) - case TagJSSpread => JSSpread(readTree()) case TagJSDelete => JSDelete(readTree()) case TagJSUnaryOp => JSUnaryOp(readInt(), readTree()) case TagJSBinaryOp => JSBinaryOp(readInt(), readTree(), readTree()) - case TagJSArrayConstr => JSArrayConstr(readTrees()) + case TagJSArrayConstr => JSArrayConstr(readTreeOrJSSpreads()) case TagJSObjectConstr => JSObjectConstr(List.fill(readInt())((readPropertyName(), readTree()))) case TagJSGlobalRef => JSGlobalRef(readIdent()) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala index 11b2afcc53..583e7622fa 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala @@ -17,7 +17,9 @@ private[ir] object Tags { /** Use to denote optional trees. */ final val TagEmptyTree = 1 - final val TagVarDef = TagEmptyTree + 1 + final val TagJSSpread = TagEmptyTree + 1 + + final val TagVarDef = TagJSSpread + 1 final val TagSkip = TagVarDef + 1 final val TagBlock = TagSkip + 1 @@ -66,8 +68,7 @@ private[ir] object Tags { final val TagJSSuperConstructorCall = TagJSSuperBracketCall + 1 final val TagLoadJSConstructor = TagJSSuperConstructorCall + 1 final val TagLoadJSModule = TagLoadJSConstructor + 1 - final val TagJSSpread = TagLoadJSModule + 1 - final val TagJSDelete = TagJSSpread + 1 + final val TagJSDelete = TagLoadJSModule + 1 final val TagJSUnaryOp = TagJSDelete + 1 final val TagJSBinaryOp = TagJSUnaryOp + 1 final val TagJSArrayConstr = TagJSBinaryOp + 1 diff --git a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala index 1f2d411b37..cf22c59c8d 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala @@ -20,6 +20,15 @@ object Transformers { final def transformExpr(tree: Tree): Tree = transform(tree, isStat = false) + def transformExprOrJSSpread(tree: TreeOrJSSpread): TreeOrJSSpread = { + implicit val pos = tree.pos + + tree match { + case JSSpread(items) => JSSpread(transformExpr(items)) + case tree: Tree => transformExpr(tree) + } + } + def transform(tree: Tree, isStat: Boolean): Tree = { implicit val pos = tree.pos @@ -129,7 +138,7 @@ object Transformers { // JavaScript expressions case JSNew(ctor, args) => - JSNew(transformExpr(ctor), args map transformExpr) + JSNew(transformExpr(ctor), args.map(transformExprOrJSSpread)) case JSDotSelect(qualifier, item) => JSDotSelect(transformExpr(qualifier), item) @@ -138,15 +147,15 @@ object Transformers { JSBracketSelect(transformExpr(qualifier), transformExpr(item)) case JSFunctionApply(fun, args) => - JSFunctionApply(transformExpr(fun), args map transformExpr) + JSFunctionApply(transformExpr(fun), args.map(transformExprOrJSSpread)) case JSDotMethodApply(receiver, method, args) => JSDotMethodApply(transformExpr(receiver), method, - args map transformExpr) + args.map(transformExprOrJSSpread)) case JSBracketMethodApply(receiver, method, args) => JSBracketMethodApply(transformExpr(receiver), transformExpr(method), - args map transformExpr) + args.map(transformExprOrJSSpread)) case JSSuperBracketSelect(superClass, qualifier, item) => JSSuperBracketSelect(superClass, transformExpr(qualifier), @@ -154,13 +163,10 @@ object Transformers { case JSSuperBracketCall(superClass, receiver, method, args) => JSSuperBracketCall(superClass, transformExpr(receiver), - transformExpr(method), args map transformExpr) + transformExpr(method), args.map(transformExprOrJSSpread)) case JSSuperConstructorCall(args) => - JSSuperConstructorCall(args map transformExpr) - - case JSSpread(items) => - JSSpread(transformExpr(items)) + JSSuperConstructorCall(args.map(transformExprOrJSSpread)) case JSDelete(prop) => JSDelete(transformExpr(prop)) @@ -172,7 +178,7 @@ object Transformers { JSBinaryOp(op, transformExpr(lhs), transformExpr(rhs)) case JSArrayConstr(items) => - JSArrayConstr(items map transformExpr) + JSArrayConstr(items.map(transformExprOrJSSpread)) case JSObjectConstr(fields) => JSObjectConstr(fields map { diff --git a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala index 526940733b..571fcb6c1e 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala @@ -14,6 +14,11 @@ import Trees._ object Traversers { class Traverser { + def traverseTreeOrJSSpread(tree: TreeOrJSSpread): Unit = tree match { + case JSSpread(items) => traverse(items) + case tree: Tree => traverse(tree) + } + def traverse(tree: Tree): Unit = tree match { // Definitions @@ -128,7 +133,7 @@ object Traversers { case JSNew(ctor, args) => traverse(ctor) - args foreach traverse + args.foreach(traverseTreeOrJSSpread) case JSDotSelect(qualifier, item) => traverse(qualifier) @@ -139,16 +144,16 @@ object Traversers { case JSFunctionApply(fun, args) => traverse(fun) - args foreach traverse + args.foreach(traverseTreeOrJSSpread) case JSDotMethodApply(receiver, method, args) => traverse(receiver) - args foreach traverse + args.foreach(traverseTreeOrJSSpread) case JSBracketMethodApply(receiver, method, args) => traverse(receiver) traverse(method) - args foreach traverse + args.foreach(traverseTreeOrJSSpread) case JSSuperBracketSelect(superClass, qualifier, item) => traverse(superClass) @@ -159,13 +164,10 @@ object Traversers { traverse(superClass) traverse(receiver) traverse(method) - args foreach traverse + args.foreach(traverseTreeOrJSSpread) case JSSuperConstructorCall(args) => - args foreach traverse - - case JSSpread(items) => - traverse(items) + args.foreach(traverseTreeOrJSSpread) case JSDelete(prop) => traverse(prop) @@ -178,7 +180,7 @@ object Traversers { traverse(rhs) case JSArrayConstr(items) => - items foreach traverse + items.foreach(traverseTreeOrJSSpread) case JSObjectConstr(fields) => for ((key, value) <- fields) { diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 74dcc6c877..785a0f3913 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -30,8 +30,14 @@ object Trees { } } + /** Either a `Tree` or a `JSSpread`. + * + * This is the type of actual arguments to JS applications. + */ + sealed trait TreeOrJSSpread extends IRNode + /** Node for a statement or expression in the IR. */ - abstract sealed class Tree extends IRNode { + abstract sealed class Tree extends IRNode with TreeOrJSSpread { val tpe: Type } @@ -475,7 +481,7 @@ object Trees { // JavaScript expressions - case class JSNew(ctor: Tree, args: List[Tree])( + case class JSNew(ctor: Tree, args: List[TreeOrJSSpread])( implicit val pos: Position) extends Tree { val tpe = AnyType } @@ -490,18 +496,18 @@ object Trees { val tpe = AnyType } - case class JSFunctionApply(fun: Tree, args: List[Tree])( + case class JSFunctionApply(fun: Tree, args: List[TreeOrJSSpread])( implicit val pos: Position) extends Tree { val tpe = AnyType } case class JSDotMethodApply(receiver: Tree, method: Ident, - args: List[Tree])(implicit val pos: Position) extends Tree { + args: List[TreeOrJSSpread])(implicit val pos: Position) extends Tree { val tpe = AnyType } case class JSBracketMethodApply(receiver: Tree, method: Tree, - args: List[Tree])(implicit val pos: Position) extends Tree { + args: List[TreeOrJSSpread])(implicit val pos: Position) extends Tree { val tpe = AnyType } @@ -585,7 +591,7 @@ object Trees { * }}} */ case class JSSuperBracketCall(superClass: Tree, receiver: Tree, method: Tree, - args: List[Tree])(implicit val pos: Position) extends Tree { + args: List[TreeOrJSSpread])(implicit val pos: Position) extends Tree { val tpe = AnyType } @@ -626,7 +632,7 @@ object Trees { * } * }}} */ - case class JSSuperConstructorCall(args: List[Tree])( + case class JSSuperConstructorCall(args: List[TreeOrJSSpread])( implicit val pos: Position) extends Tree { val tpe = NoType } @@ -675,9 +681,8 @@ object Trees { * * @param items An Array whose items will be spread (not an arbitrary iterable) */ - case class JSSpread(items: Tree)(implicit val pos: Position) extends Tree { - val tpe = NoType // there is no reasonable type for this tree - } + case class JSSpread(items: Tree)(implicit val pos: Position) + extends IRNode with TreeOrJSSpread case class JSDelete(prop: Tree)(implicit val pos: Position) extends Tree { require(prop match { @@ -752,7 +757,7 @@ object Trees { final val instanceof = 21 } - case class JSArrayConstr(items: List[Tree])( + case class JSArrayConstr(items: List[TreeOrJSSpread])( implicit val pos: Position) extends Tree { val tpe = AnyType } diff --git 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 index c5b53e16d0..1d101a8659 100644 --- 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 @@ -658,11 +658,11 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { } else { js.Apply( genIdentBracketSelect(superCtor, "call"), - js.This() :: newArgs.map(transformExprNoChar)) + js.This() :: newArgs.map(transformJSArg)) } case OutputMode.ECMAScript6 => - js.Apply(js.Super(), newArgs.map(transformExprNoChar)) + js.Apply(js.Super(), newArgs.map(transformJSArg)) } } @@ -838,11 +838,12 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { /** Same as `unnest`, but allows (and preserves) [[JSSpread]]s at the * top-level. */ - def unnestOrSpread(args: List[Tree])(makeStat: (List[Tree], Env) => js.Tree)( + def unnestOrSpread(args: List[TreeOrJSSpread])( + makeStat: (List[TreeOrJSSpread], Env) => js.Tree)( implicit env: Env): js.Tree = { val (argsNoSpread, argsWereSpread) = args.map { case JSSpread(items) => (items, true) - case arg => (arg, false) + case arg: Tree => (arg, false) }.unzip unnest(argsNoSpread) { (newArgsNoSpread, env) => @@ -939,7 +940,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case ArrayValue(tpe, elems) => ArrayValue(tpe, recs(elems)) case JSArrayConstr(items) if !containsAnySpread(items) => - JSArrayConstr(recs(items)) + JSArrayConstr(recs(castNoSpread(items))) case arg @ JSObjectConstr(items) if !doesObjectConstrRequireDesugaring(arg) => @@ -1096,6 +1097,11 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { require(!allowSideEffects || allowUnpure) + def testJSArg(tree: TreeOrJSSpread): Boolean = tree match { + case JSSpread(_) => false + case tree: Tree => test(tree) + } + def test(tree: Tree): Boolean = tree match { // Atomic expressions case _: Literal => true @@ -1132,7 +1138,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case ArraySelect(array, index) => allowUnpure && test(array) && test(index) case JSArrayConstr(items) => - allowUnpure && (items forall test) + allowUnpure && (items.forall(testJSArg)) case tree @ JSObjectConstr(items) => allowUnpure && !doesObjectConstrRequireDesugaring(tree) && @@ -1169,17 +1175,17 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { // JavaScript expressions that can always have side-effects case JSNew(fun, args) => - allowSideEffects && test(fun) && (args forall test) + allowSideEffects && test(fun) && (args.forall(testJSArg)) case JSDotSelect(qualifier, item) => allowSideEffects && test(qualifier) case JSBracketSelect(qualifier, item) => allowSideEffects && test(qualifier) && test(item) case JSFunctionApply(fun, args) => - allowSideEffects && test(fun) && (args forall test) + allowSideEffects && test(fun) && (args.forall(testJSArg)) case JSDotMethodApply(receiver, method, args) => - allowSideEffects && test(receiver) && (args forall test) + allowSideEffects && test(receiver) && (args.forall(testJSArg)) case JSBracketMethodApply(receiver, method, args) => - allowSideEffects && test(receiver) && test(method) && (args forall test) + allowSideEffects && test(receiver) && test(method) && (args.forall(testJSArg)) case JSSuperBracketSelect(superClass, qualifier, item) => allowSideEffects && test(superClass) && test(qualifier) && test(item) case LoadJSModule(_) => @@ -1587,7 +1593,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { List(ctor, spreadToArgArray(args)))(AnyType) } } else { - unnest(ctor :: args) { (newCtorAndArgs, env) => + unnest(ctor :: castNoSpread(args)) { (newCtorAndArgs, env) => val newCtor :: newArgs = newCtorAndArgs redo(JSNew(newCtor, newArgs))(env) } @@ -1600,7 +1606,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { List(Undefined(), spreadToArgArray(args))) } } else { - unnest(fun :: args) { (newFunAndArgs, env) => + unnest(fun :: castNoSpread(args)) { (newFunAndArgs, env) => val newFun :: newArgs = newFunAndArgs redo(JSFunctionApply(newFun, newArgs))(env) } @@ -1618,7 +1624,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { } } } else { - unnest(receiver :: args) { (newReceiverAndArgs, env) => + unnest(receiver :: castNoSpread(args)) { (newReceiverAndArgs, env) => val newReceiver :: newArgs = newReceiverAndArgs redo(JSDotMethodApply(newReceiver, method, newArgs))(env) } @@ -1636,7 +1642,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { } } } else { - unnest(receiver :: method :: args) { (newReceiverAndArgs, env) => + unnest(receiver :: method :: castNoSpread(args)) { (newReceiverAndArgs, env) => val newReceiver :: newMethod :: newArgs = newReceiverAndArgs redo(JSBracketMethodApply(newReceiver, newMethod, newArgs))(env) } @@ -1702,7 +1708,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { spreadToArgArray(items) } } else { - unnest(items) { (newItems, env) => + unnest(castNoSpread(items)) { (newItems, env) => redo(JSArrayConstr(newItems))(env) } } @@ -1780,10 +1786,14 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { }) } - private def containsAnySpread(args: List[Tree]): Boolean = + private def containsAnySpread(args: List[TreeOrJSSpread]): Boolean = args.exists(_.isInstanceOf[JSSpread]) - private def spreadToArgArray(args: List[Tree])( + /** Precondition: `!containsAnySpread(args)`. */ + private def castNoSpread(args: List[TreeOrJSSpread]): List[Tree] = + args.asInstanceOf[List[Tree]] + + private def spreadToArgArray(args: List[TreeOrJSSpread])( implicit env: Env, pos: Position): Tree = { var reversedParts: List[Tree] = Nil var reversedPartUnderConstruction: List[Tree] = Nil @@ -1801,7 +1811,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case JSSpread(spreadArray) => closeReversedPartUnderConstruction() reversedParts ::= spreadArray - case _ => + case arg: Tree => reversedPartUnderConstruction ::= arg } } @@ -1856,6 +1866,16 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { } } + def transformJSArg(tree: TreeOrJSSpread)(implicit env: Env): js.Tree = { + tree match { + case JSSpread(items) => + assert(outputMode == OutputMode.ECMAScript6) + js.Spread(transformExprNoChar(items))(tree.pos) + case tree: Tree => + transformExprNoChar(tree) + } + } + def transformExprNoChar(tree: Tree)(implicit env: Env): js.Tree = transformExpr(tree, preserveChar = false) @@ -2264,7 +2284,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { // JavaScript expressions case JSNew(constr, args) => - js.New(transformExprNoChar(constr), args.map(transformExprNoChar)) + js.New(transformExprNoChar(constr), args.map(transformJSArg)) case JSDotSelect(qualifier, item) => js.DotSelect(transformExprNoChar(qualifier), transformPropIdent(item)) @@ -2296,17 +2316,17 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case _ => transformedFun } - js.Apply(protectedFun, args.map(transformExprNoChar)) + js.Apply(protectedFun, args.map(transformJSArg)) case JSDotMethodApply(receiver, method, args) => js.Apply( js.DotSelect(transformExprNoChar(receiver), transformPropIdent(method)), - args.map(transformExprNoChar)) + args.map(transformJSArg)) case JSBracketMethodApply(receiver, method, args) => js.Apply(genBracketSelect(transformExprNoChar(receiver), - transformExprNoChar(method)), args.map(transformExprNoChar)) + transformExprNoChar(method)), args.map(transformJSArg)) case JSSuperBracketSelect(superClass, qualifier, item) => genCallHelper("superGet", transformExprNoChar(superClass), @@ -2327,10 +2347,6 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { genLoadJSFromSpec(spec, keepOnlyDangerousVarNames = false)) } - case JSSpread(items) => - assert(outputMode == OutputMode.ECMAScript6) - js.Spread(transformExprNoChar(items)) - case JSUnaryOp(op, lhs) => js.UnaryOp(op, transformExprNoChar(lhs)) @@ -2338,7 +2354,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { js.BinaryOp(op, transformExprNoChar(lhs), transformExprNoChar(rhs)) case JSArrayConstr(items) => - js.ArrayConstr(items.map(transformExprNoChar)) + js.ArrayConstr(items.map(transformJSArg)) case JSObjectConstr(fields) => js.ObjectConstr(fields map { case (name, value) => diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index be655f98df..bb0550c6c9 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -663,12 +663,11 @@ private final class IRChecker(unit: LinkingUnit, typecheck(tree, env) } - private def typecheckExprOrSpread(tree: Tree, env: Env): Type = { + private def typecheckExprOrSpread(tree: TreeOrJSSpread, env: Env): Unit = { tree match { case JSSpread(items) => typecheckExpr(items, env) - AnyType - case _ => + case tree: Tree => typecheckExpr(tree, env) } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index 4058a16374..44ed878e9e 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -851,7 +851,9 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { */ cont(JSArrayConstr(transformExprsOrSpreads(items)).toPreTransform) } else { - pretransformExprs(items) { titems => + val itemsNoSpread = items.asInstanceOf[List[Tree]] + + pretransformExprs(itemsNoSpread) { titems => tryOrRollback { cancelFun => val itemBindings = for { (titem, index) <- titems.zipWithIndex @@ -1696,6 +1698,8 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { cont(JSFunctionApply(transformExpr(fun), transformExprsOrSpreads(args)).toPreTransform) } else { + val argsNoSpread = args.asInstanceOf[List[Tree]] + pretransformExpr(fun) { tfun => tfun match { case PreTransLocalDef(LocalDef(_, false, @@ -1703,7 +1707,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { captureParams, params, body, captureLocalDefs, alreadyUsed, cancelFun))) if !alreadyUsed.value => alreadyUsed.value = true - pretransformExprs(args) { targs => + pretransformExprs(argsNoSpread) { targs => inlineBody( Some(PreTransLit(Undefined())), // `this` is `undefined` captureParams ++ params, AnyType, body, @@ -1713,14 +1717,14 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case _ => cont(JSFunctionApply(finishTransformExpr(tfun), - args.map(transformExpr)).toPreTransform) + argsNoSpread.map(transformExpr)).toPreTransform) } } } } - private def transformExprsOrSpreads(trees: List[Tree])( - implicit scope: Scope): List[Tree] = { + private def transformExprsOrSpreads(trees: List[TreeOrJSSpread])( + implicit scope: Scope): List[TreeOrJSSpread] = { /* This is basically a flatMap, but we do it manually because flatMap would * generate many garbage intermediate lists, when in fact the case JSSpread @@ -1728,7 +1732,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { * OptimizerCore. */ - val builder = List.newBuilder[Tree] + val builder = List.newBuilder[TreeOrJSSpread] trees.foreach { case spread: JSSpread => @@ -1755,7 +1759,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case _ => builder += JSSpread(newSpreadItems) } - case tree => + case tree: Tree => builder += transformExpr(tree) } From e59b15f0fb6736a0bfd9c87b0fb2d97e23b90bb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 13 Jan 2018 12:49:10 +0100 Subject: [PATCH 0609/2665] Harden neg tests with specific error messages. Most neg tests that were not testing a specific error message did so because of Scala 2.10. Now that 2.10 is gone, we can harden those tests. --- .../compiler/test/JSDynamicLiteralTest.scala | 38 ++++++++++-- .../core/compiler/test/JSExportTest.scala | 60 ++++++++++++++++--- 2 files changed, 85 insertions(+), 13 deletions(-) diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSDynamicLiteralTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSDynamicLiteralTest.scala index bf00ead0b2..9e586c7ada 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSDynamicLiteralTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSDynamicLiteralTest.scala @@ -17,7 +17,14 @@ class JSDynamicLiteralTest extends DirectTest with TestHelpers { // selectDynamic (with any name) expr""" lit.helloWorld - """.fails() // Scala error, no string checking due to versions + """ hasErrors + """ + |newSource1.scala:3: error: value selectDynamic is not a member of object scalajs.js.Dynamic.literal + |error after rewriting to scala.scalajs.js.Dynamic.literal.("helloWorld") + |possible cause: maybe a wrong Dynamic method signature? + | lit.helloWorld + | ^ + """ // applyDynamicNamed with wrong method name expr""" @@ -50,7 +57,14 @@ class JSDynamicLiteralTest extends DirectTest with TestHelpers { val x = new Object() def foo = lit("a" -> x) } - """.fails() + """ hasErrors + """ + |newSource1.scala:5: error: type mismatch; + | found : Object + | required: scala.scalajs.js.Any + | def foo = lit("a" -> x) + | ^ + """ // Bad key type (applyDynamic) """ @@ -58,7 +72,14 @@ class JSDynamicLiteralTest extends DirectTest with TestHelpers { val x = Seq() def foo = lit(x -> "a") } - """.fails() + """ hasErrors + """ + |newSource1.scala:5: error: type mismatch; + | found : (Seq[Nothing], String) + | required: (String, scala.scalajs.js.Any) + | def foo = lit(x -> "a") + | ^ + """ // Bad value type (applyDynamicNamed) """ @@ -66,7 +87,16 @@ class JSDynamicLiteralTest extends DirectTest with TestHelpers { val x = new Object() def foo = lit(a = x) } - """.fails() + """ hasErrors + """ + |newSource1.scala:5: error: type mismatch; + | found : Object + | required: scala.scalajs.js.Any + |error after rewriting to scala.scalajs.js.Dynamic.literal.applyDynamicNamed("apply")(scala.Tuple2("a", x)) + |possible cause: maybe a wrong Dynamic method signature? + | def foo = lit(a = x) + | ^ + """ } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index 843d982d7a..3d48f10d43 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -98,7 +98,15 @@ class JSExportTest extends DirectTest with TestHelpers { @JSExport("value") def world = "bar" } - """ fails() // No error test, Scala version dependent error messages + """ hasErrors + """ + |newSource1.scala:7: error: double definition: + |def $js$exported$prop$value: Any at line 4 and + |def $js$exported$prop$value: Any at line 7 + |have same type + | @JSExport("value") + | ^ + """ """ class Confl { @@ -109,17 +117,32 @@ class JSExportTest extends DirectTest with TestHelpers { @JSExport def ub(x: Box[Int]): Int = x.x } - """ fails() // No error test, Scala version dependent error messages + """ hasErrors + """ + |newSource1.scala:8: error: double definition: + |def $js$exported$meth$ub(x: Confl.this.Box[String]): Any at line 6 and + |def $js$exported$meth$ub(x: Confl.this.Box[Int]): Any at line 8 + |have same type after erasure: (x: Confl#Box)Object + | @JSExport + | ^ + """ """ class Confl { @JSExport - def rtType(x: scala.scalajs.js.prim.Number) = x + def rtType(x: js.Any) = x @JSExport - def rtType(x: Double) = x + def rtType(x: js.Dynamic) = x } - """ fails() // Error message depends on Scala version + """ hasErrors + """ + |newSource1.scala:7: error: Cannot disambiguate overloads for exported method $js$exported$meth$rtType with types + | (x: scala.scalajs.js.Dynamic)Object + | (x: scala.scalajs.js.Any)Object + | @JSExport + | ^ + """ """ class Confl { @@ -157,11 +180,18 @@ class JSExportTest extends DirectTest with TestHelpers { """ class Confl { @JSExport - def foo(x: scala.scalajs.js.prim.Number, y: String)(z: Int = 1) = x + def foo(x: Double, y: String)(z: Int = 1) = x @JSExport def foo(x: Double, y: String)(z: String*) = x } - """ fails() // Error message depends on Scala version + """ hasErrors + """ + |newSource1.scala:4: error: Cannot disambiguate overloads for exported method $js$exported$meth$foo with types + | (x: Double, y: String, z: Int)Object + | (x: Double, y: String, z: Seq)Object + | @JSExport + | ^ + """ """ class A { @@ -171,7 +201,14 @@ class JSExportTest extends DirectTest with TestHelpers { @JSExport def a(x: Any) = 2 } - """ fails() // Error message depends on Scala version + """ hasErrors + """ + |newSource1.scala:7: error: Cannot disambiguate overloads for exported method $js$exported$meth$a with types + | (x: Object)Object + | (x: scala.scalajs.js.Any)Object + | @JSExport + | ^ + """ } @@ -785,7 +822,12 @@ class JSExportTest extends DirectTest with TestHelpers { def foo(x: String, y: String = "hello") = x def foo(x: Int, y: String = "bar") = x } - """ fails() + """ hasErrors + """ + |newSource1.scala:3: error: in class A, multiple overloaded alternatives of method foo define default arguments. + | class A { + | ^ + """ } @Test From 42938046efe0f7ac4978da9227ea7b3b7e38519b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 14 Jan 2018 12:49:27 +0100 Subject: [PATCH 0610/2665] Fix #3252: Filter `scala.Serializable` out of the interfaces of JS types. `scala.Serializable` is added automatically by scalac on all SAM-generated classes, which includes JS function types. Since ca86e39f0fc22e6a1bedc422c3f65552d243333e, we generate a actual .sjsir file for JS function types in Scala 2.11 with `-Xexperimental`, which are invalid if they extend `scala.Serializable`. Therefore, this commit explicitly filters out `scala.Serializable`, the same way we filter out `scala.Dynamic`. --- .../scala/org/scalajs/core/compiler/GenJSCode.scala | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 7fb103ba83..01e39c284e 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -896,14 +896,21 @@ abstract class GenJSCode extends plugins.PluginComponent hashedMemberDefs, Nil)(OptimizerHints.empty) } + private lazy val jsTypeInterfacesBlacklist: Set[Symbol] = + Set(DynamicClass, SerializableClass) // #3118, #3252 + private def genClassInterfaces(sym: Symbol, forJSClass: Boolean)( implicit pos: Position): List[js.Ident] = { + + val blacklist = + if (forJSClass) jsTypeInterfacesBlacklist + else Set.empty[Symbol] + for { parent <- sym.info.parents typeSym = parent.typeSymbol _ = assert(typeSym != NoSymbol, "parent needs symbol") - if typeSym.isTraitOrInterface - if !forJSClass || typeSym != definitions.DynamicClass + if typeSym.isTraitOrInterface && !blacklist.contains(typeSym) } yield { encodeClassFullNameIdent(typeSym) } From 4a2a96ef120cca488f9aedb62bc32182bfdebe1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 10 Jan 2018 18:08:34 +0100 Subject: [PATCH 0611/2665] Make `js.FunctionN`s map to arrow functions in ECMAScript 2015. Arrow functions have some distinct semantics besides not capturing `this`: they cannot be *constructed* (i.e., called with `new`) and they do not have a `prototype` property. Therefore, they also cannot be used as "parent classes". As such, we need an interop feature to create true arrow functions when targeting ES 2015+. The existing `js.FunctionN`s are actually a perfect fit for this, since they already do not have access to their `this` parameter. This is, in theory, a breaking change, as someone could have relied on calling a `js.FunctionN` with `new` (which succeeded before, and now throws). However, without access to the `this` value, there is no non-contrived use case for that, so it is unlikely to be noticeable. --- .../org/scalajs/core/compiler/GenJSCode.scala | 28 +++++--- .../scala/org/scalajs/core/ir/Hashers.scala | 3 +- .../scala/org/scalajs/core/ir/Printers.scala | 7 +- .../org/scalajs/core/ir/Serializers.scala | 6 +- .../org/scalajs/core/ir/Transformers.scala | 4 +- .../org/scalajs/core/ir/Traversers.scala | 2 +- .../scala/org/scalajs/core/ir/Trees.scala | 10 ++- .../org/scalajs/core/ir/PrintersTest.scala | 5 +- .../testsuite/jsinterop/FunctionTest.scala | 26 +++++++ .../jsinterop/ThisFunctionTest.scala | 32 +++++++++ .../closure/ClosureAstTransformer.scala | 2 +- .../linker/backend/emitter/ClassEmitter.scala | 68 +++++++++++-------- .../backend/emitter/FunctionEmitter.scala | 36 +++++----- .../tools/linker/backend/emitter/JSGen.scala | 12 ++++ .../linker/backend/javascript/Printers.scala | 23 +++++-- .../linker/backend/javascript/Trees.scala | 3 +- .../core/tools/linker/checker/IRChecker.scala | 5 +- .../frontend/optimizer/OptimizerCore.scala | 29 ++++---- 18 files changed, 213 insertions(+), 88 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 5795ca6f7e..781a89b071 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -704,9 +704,10 @@ abstract class GenJSCode extends plugins.PluginComponent def selfRef(implicit pos: ir.Position) = js.VarRef(selfName)(jstpe.AnyType) - def lambda(params: List[js.ParamDef], body: js.Tree)( + def memberLambda(params: List[js.ParamDef], body: js.Tree)( implicit pos: ir.Position) = { - js.Closure(captureParams = Nil, params, body, captureValues = Nil) + js.Closure(arrow = false, captureParams = Nil, params, body, + captureValues = Nil) } val memberDefinitions = classMembers.toList.map { @@ -722,7 +723,7 @@ abstract class GenJSCode extends plugins.PluginComponent case mdef: js.MethodDef => implicit val pos = mdef.pos val name = mdef.name.asInstanceOf[js.StringLiteral] - val impl = lambda(mdef.args, mdef.body.getOrElse( + val impl = memberLambda(mdef.args, mdef.body.getOrElse( throw new AssertionError("Got anon SJS class with abstract method"))) js.Assign(js.JSBracketSelect(selfRef, name), impl) @@ -735,11 +736,11 @@ abstract class GenJSCode extends plugins.PluginComponent List(js.StringLiteral(name) -> value) val optGetter = pdef.getterBody map { body => - js.StringLiteral("get") -> lambda(params = Nil, body) + js.StringLiteral("get") -> memberLambda(params = Nil, body) } val optSetter = pdef.setterArgAndBody map { case (arg, body) => - js.StringLiteral("set") -> lambda(params = arg :: Nil, body) + js.StringLiteral("set") -> memberLambda(params = arg :: Nil, body) } val descriptor = js.JSObjectConstr( @@ -790,7 +791,8 @@ abstract class GenJSCode extends plugins.PluginComponent val invocation = { implicit val invocationPosition = pos - val closure = js.Closure(Nil, jsSuperClassParam :: ctorParams, + val closure = js.Closure(arrow = true, Nil, + jsSuperClassParam :: ctorParams, js.Block(inlinedCtorStats, selfRef), Nil) js.JSFunctionApply(closure, jsSuperClassValue :: args) @@ -1011,7 +1013,8 @@ abstract class GenJSCode extends plugins.PluginComponent implicit pos: Position): Option[js.Tree] = { val fqcnArg = js.StringLiteral(sym.fullName + "$") val runtimeClassArg = js.ClassOf(toTypeRef(sym.info)) - val loadModuleFunArg = js.Closure(Nil, Nil, genLoadModule(sym), Nil) + val loadModuleFunArg = + js.Closure(arrow = true, Nil, Nil, genLoadModule(sym), Nil) val stat = genApplyMethod( genLoadModule(ReflectModule), @@ -1062,7 +1065,7 @@ abstract class GenJSCode extends plugins.PluginComponent val paramTypesArray = js.JSArrayConstr(parameterTypes) - val newInstanceFun = js.Closure(Nil, formalParams, { + val newInstanceFun = js.Closure(arrow = true, Nil, formalParams, { genNew(sym, ctor, actualParams) }, Nil) @@ -1644,8 +1647,8 @@ abstract class GenJSCode extends plugins.PluginComponent assert(isStat) super.transform(js.VarDef( name, vtpe, newMutable(name.name, mutable), rhs)(tree.pos), isStat) - case js.Closure(captureParams, params, body, captureValues) => - js.Closure(captureParams, params, body, + case js.Closure(arrow, captureParams, params, body, captureValues) => + js.Closure(arrow, captureParams, params, body, captureValues.map(transformExpr))(tree.pos) case _ => super.transform(tree, isStat) @@ -4942,6 +4945,7 @@ abstract class GenJSCode extends plugins.PluginComponent if (isThisFunction) { val thisParam :: actualParams = patchedParams js.Closure( + arrow = false, ctorParamDefs, actualParams, js.Block( @@ -4950,7 +4954,8 @@ abstract class GenJSCode extends plugins.PluginComponent patchedBody), capturedArgs) } else { - js.Closure(ctorParamDefs, patchedParams, patchedBody, capturedArgs) + js.Closure(arrow = true, ctorParamDefs, patchedParams, patchedBody, + capturedArgs) } } @@ -5059,6 +5064,7 @@ abstract class GenJSCode extends plugins.PluginComponent } val closure = js.Closure( + arrow = true, allFormalCaptures, patchedFormalArgs, patchedBody, diff --git a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala index 98b8d58133..f628753970 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala @@ -439,8 +439,9 @@ object Hashers { mixTag(TagThis) mixType(tree.tpe) - case Closure(captureParams, params, body, captureValues) => + case Closure(arrow, captureParams, params, body, captureValues) => mixTag(TagClosure) + mixBoolean(arrow) mixParamDefs(captureParams) mixParamDefs(params) mixTree(body) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index a3da382e33..7dc013c319 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -794,8 +794,11 @@ object Printers { case This() => print("this") - case Closure(captureParams, params, body, captureValues) => - print("(lambda<") + case Closure(arrow, captureParams, params, body, captureValues) => + if (arrow) + print("(arrow-lambda<") + else + print("(lambda<") var first = true for ((param, value) <- captureParams.zip(captureValues)) { if (first) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index 4b57159c03..96d5d893d7 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -425,8 +425,9 @@ object Serializers { writeByte(TagThis) writeType(tree.tpe) - case Closure(captureParams, params, body, captureValues) => + case Closure(arrow, captureParams, params, body, captureValues) => writeByte(TagClosure) + writeBoolean(arrow) writeParamDefs(captureParams) writeParamDefs(params) writeTree(body) @@ -926,7 +927,8 @@ object Serializers { case TagThis => This()(readType()) case TagClosure => - Closure(readParamDefs(), readParamDefs(), readTree(), readTrees()) + Closure(readBoolean(), readParamDefs(), readParamDefs(), readTree(), + readTrees()) case TagCreateJSClass => CreateJSClass(readClassRef(), readTrees()) } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala index cf22c59c8d..480f002106 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala @@ -194,8 +194,8 @@ object Transformers { // Atomic expressions - case Closure(captureParams, params, body, captureValues) => - Closure(captureParams, params, transformExpr(body), + case Closure(arrow, captureParams, params, body, captureValues) => + Closure(arrow, captureParams, params, transformExpr(body), captureValues.map(transformExpr)) case CreateJSClass(cls, captureValues) => diff --git a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala index 571fcb6c1e..19578d4ca3 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala @@ -194,7 +194,7 @@ object Traversers { // Atomic expressions - case Closure(captureParams, params, body, captureValues) => + case Closure(arrow, captureParams, params, body, captureValues) => traverse(body) captureValues.foreach(traverse) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 785a0f3913..e685505578 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -853,10 +853,14 @@ object Trees { case class This()(val tpe: Type)(implicit val pos: Position) extends Tree /** Closure with explicit captures. - * The n captures map to the n first formal arguments. + * + * @param arrow + * If `true`, the closure is an Arrow Function (`=>`), which does not have + * an `this` parameter, and cannot be constructed (called with `new`). + * If `false`, it is a regular Function (`function`). */ - case class Closure(captureParams: List[ParamDef], params: List[ParamDef], - body: Tree, captureValues: List[Tree])( + case class Closure(arrow: Boolean, captureParams: List[ParamDef], + params: List[ParamDef], body: Tree, captureValues: List[Tree])( implicit val pos: Position) extends Tree { val tpe = AnyType } diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala index 4e6c020832..126e41ab97 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala @@ -834,15 +834,16 @@ class PrintersTest { | 5 |}) """, - Closure(Nil, Nil, i(5), Nil)) + Closure(false, Nil, Nil, i(5), Nil)) assertPrintEquals( """ - |(lambda(z: any) = { + |(arrow-lambda(z: any) = { | z |}) """, Closure( + true, List( ParamDef("x", AnyType, mutable = false, rest = false), ParamDef("y", IntType, mutable = false, rest = false)), diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/FunctionTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/FunctionTest.scala index c731ed9453..6cfc8dd68e 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/FunctionTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/FunctionTest.scala @@ -8,8 +8,10 @@ package org.scalajs.testsuite.jsinterop import scala.scalajs.js +import scala.scalajs.LinkingInfo.assumingES6 import org.junit.Assert._ +import org.junit.Assume._ import org.junit.Test import org.scalajs.testsuite.utils.AssertThrows._ @@ -39,4 +41,28 @@ class FunctionTest { assertFalse(res.contains("2")) } + @Test def functionWithConversionIsAnArrowFunction(): Unit = { + assumeTrue("In ES 5.1, arrow functions do not exist", assumingES6) + + val ctor: js.Function = (x: js.Any) => x + val ctorDyn = ctor.asInstanceOf[js.Dynamic] + + assertEquals(js.undefined, ctorDyn.prototype) + + assertThrows(classOf[js.JavaScriptException], + js.Dynamic.newInstance(ctorDyn)("foo")) + } + + @Test def functionWithSAMIsAnArrowFunction(): Unit = { + assumeTrue("In ES 5.1, arrow functions do not exist", assumingES6) + + val ctor: js.Function1[js.Any, Any] = (x: js.Any) => x + val ctorDyn = ctor.asInstanceOf[js.Dynamic] + + assertEquals(js.undefined, ctorDyn.prototype) + + assertThrows(classOf[js.JavaScriptException], + js.Dynamic.newInstance(ctorDyn)("foo")) + } + } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ThisFunctionTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ThisFunctionTest.scala index 3a4c2be60a..e99e821613 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ThisFunctionTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ThisFunctionTest.scala @@ -98,4 +98,36 @@ class ThisFunctionTest { assertSame(thisValue, obj.foobar.call(thisValue)) } + @Test def thisFunctionWithConversionCanBeConstructed(): Unit = { + val ctor: js.ThisFunction = { + (thiz: js.Dynamic, x: js.Any) => + thiz.x = x + thiz.y = 42 + } + val ctorDyn = ctor.asInstanceOf[js.Dynamic] + + assertEquals("object", js.typeOf(ctorDyn.prototype)) + + val obj = js.Dynamic.newInstance(ctorDyn)("foo") + assertEquals("foo", obj.x) + assertEquals(42, obj.y) + assertSame(ctor, obj.constructor) + } + + @Test def thisFunctionWithSAMCanBeConstructed(): Unit = { + val ctor: js.ThisFunction1[js.Dynamic, js.Any, Any] = { + (thiz: js.Dynamic, x: js.Any) => + thiz.x = x + thiz.y = 42 + } + val ctorDyn = ctor.asInstanceOf[js.Dynamic] + + assertEquals("object", js.typeOf(ctorDyn.prototype)) + + val obj = js.Dynamic.newInstance(ctorDyn)("foo") + assertEquals("foo", obj.x) + assertEquals(42, obj.y) + assertSame(ctor, obj.constructor) + } + } diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala index 217f5fe52d..0d8cb80710 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala @@ -202,7 +202,7 @@ private[closure] class ClosureAstTransformer(relativizeBaseURI: Option[URI]) { case This() => new Node(Token.THIS) - case Function(args, body) => + case Function(false, args, body) => genFunction("", args, body) case FunctionDef(name, args, body) => genFunction(name.name, args, body) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index 176e038709..50eadb59fd 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -110,7 +110,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { js.Return(classValueVar) ) - envFieldDef("a", className, js.Function(Nil, body)) + envFunctionDef("a", className, Nil, body) } js.Block(createClassValueVar, createAccessor) @@ -133,7 +133,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { Nil ) - envFieldDef("a", className, js.Function(captureParamDefs, body)) + envFunctionDef("a", className, captureParamDefs, body) } } } @@ -216,7 +216,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { def makeInheritableCtorDef(ctorToMimic: js.Tree) = { js.Block( js.DocComment("@constructor"), - envFieldDef("h", className, js.Function(Nil, js.Skip()), + envFieldDef("h", className, js.Function(false, Nil, js.Skip()), keepFunctionExpression = isJSClass), envField("h", className).prototype := ctorToMimic.prototype ) @@ -282,7 +282,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { genJSConstructorFun(tree, initToInline) for (jsConstructorFun <- jsConstructorFunWithGlobals) yield { - val js.Function(args, body) = jsConstructorFun + val js.Function(_, args, body) = jsConstructorFun def isTrivialCtorBody: Boolean = body match { case js.Skip() => true @@ -345,7 +345,8 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { } initToInline.fold { - WithGlobals(js.Function(Nil, js.Block(superCtorCallAndFieldDefs))) + WithGlobals( + js.Function(arrow = false, Nil, js.Block(superCtorCallAndFieldDefs))) } { initMethodDef => val generatedInitMethodFunWithGlobals = { implicit val pos = initMethodDef.pos @@ -359,8 +360,8 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { } for (generatedInitMethodFun <- generatedInitMethodFunWithGlobals) yield { - val js.Function(args, initMethodFunBody) = generatedInitMethodFun - js.Function(args, + val js.Function(arrow, args, initMethodFunBody) = generatedInitMethodFun + js.Function(arrow, args, js.Block(superCtorCallAndFieldDefs ::: initMethodFunBody :: Nil)) } } @@ -458,7 +459,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { methodFun0WithGlobals.flatMap { methodFun0 => val methodFun = if (Definitions.isConstructorName(method.encodedName)) { // init methods have to return `this` so that we can chain them to `new` - js.Function(methodFun0.args, { + js.Function(arrow = false, methodFun0.args, { implicit val pos = methodFun0.body.pos js.Block( methodFun0.body, @@ -700,8 +701,8 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val obj = objParam.ref val createIsStat = { - envFieldDef("is", className, - js.Function(List(objParam), js.Return(className match { + envFunctionDef("is", className, List(objParam), js.Return { + className match { case Definitions.ObjectClass => js.BinaryOp(JSBinaryOp.!==, obj, js.Null()) @@ -730,14 +731,15 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { test = test || (obj === js.Undefined()) !(!test) - }))) + } + }) } val createAsStat = if (semantics.asInstanceOfs == Unchecked) { js.Skip() } else { - envFieldDef("as", className, - js.Function(List(objParam), js.Return(className match { + envFunctionDef("as", className, List(objParam), js.Return { + className match { case Definitions.ObjectClass => obj @@ -749,7 +751,8 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { genCallHelper("throwClassCastException", obj, js.StringLiteral(displayName)) }) - }))) + } + }) } js.Block(createIsStat, createAsStat) @@ -774,8 +777,8 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val depth = depthParam.ref val createIsArrayOfStat = { - envFieldDef("isArrayOf", className, - js.Function(List(objParam, depthParam), className match { + envFunctionDef("isArrayOf", className, List(objParam, depthParam), { + className match { case Definitions.ObjectClass => val dataVarDef = genLet(js.Ident("data"), mutable = false, { obj && (obj DOT "$classData") @@ -810,14 +813,15 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { genIsClassNameInAncestors(className, obj DOT "$classData" DOT "arrayBase" DOT "ancestors") }))) - })) + } + }) } val createAsArrayOfStat = if (semantics.asInstanceOfs == Unchecked) { js.Skip() } else { - envFieldDef("asArrayOf", className, - js.Function(List(objParam, depthParam), js.Return { + envFunctionDef("asArrayOf", className, List(objParam, depthParam), { + js.Return { js.If(js.Apply(envField("isArrayOf", className), List(obj, depth)) || (obj === js.Null()), { obj @@ -825,7 +829,8 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { genCallHelper("throwArrayCastException", obj, js.StringLiteral("L"+displayName+";"), depth) }) - })) + } + }) } js.Block(createIsArrayOfStat, createAsArrayOfStat) @@ -889,7 +894,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { } else if (isHijackedClass) { /* Other hijacked classes have a special isInstanceOf test. */ val xParam = js.ParamDef(js.Ident("x"), rest = false) - WithGlobals(js.Function(List(xParam), js.Return { + WithGlobals(genArrowFunction(List(xParam), js.Return { genIsInstanceOf(xParam.ref, ClassRef(className)) })) } else if (isJSType) { @@ -907,7 +912,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { jsCtor <- genRawJSClassConstructor(className, tree.jsNativeLoadSpec, keepOnlyDangerousVarNames = true) } yield { - js.Function(List(js.ParamDef(js.Ident("x"), rest = false)), js.Return { + genArrowFunction(List(js.ParamDef(js.Ident("x"), rest = false)), js.Return { js.BinaryOp(JSBinaryOp.instanceof, js.VarRef(js.Ident("x")), jsCtor) }) } @@ -1021,7 +1026,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val body = js.Block(initBlock, js.Return(moduleInstanceVar)) - envFieldDef("m", className, js.Function(Nil, body)) + envFunctionDef("m", className, Nil, body) } js.Block(createModuleInstanceField, createAccessor) @@ -1083,10 +1088,10 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { cd.encodedName, args, body, resultType = NoType) for (generatedFun <- generatedFunWithGlobals) yield { - val js.Function(thisParam :: ctorParams, ctorBody) = generatedFun + val js.Function(arrow, thisParam :: ctorParams, ctorBody) = generatedFun val thisIdent = thisParam.name - val exportedCtor = js.Function(ctorParams, js.Block( + val exportedCtor = js.Function(arrow, ctorParams, js.Block( genLet(thisIdent, mutable = false, js.New(baseCtor, Nil)), ctorBody, js.Return(js.VarRef(thisIdent)) @@ -1182,7 +1187,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { // optional getter definition val getterDef = { - js.StringLiteral("get") -> js.Function(Nil, { + js.StringLiteral("get") -> js.Function(arrow = false, Nil, { js.Return(genSelectStatic(cd.encodedName, field)) }) } @@ -1202,6 +1207,15 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { // Helpers + private def envFunctionDef(field: String, subField: String, + args: List[js.ParamDef], body: js.Tree, origName: Option[String] = None)( + implicit pos: Position): js.FunctionDef = { + + val globalVar = envField(field, subField, origName) + val globalVarIdent = globalVar.ident + js.FunctionDef(globalVarIdent, args, body) + } + private def envFieldDef(field: String, subField: String, value: js.Tree, origName: Option[String] = None, mutable: Boolean = false, keepFunctionExpression: Boolean = false)( @@ -1212,7 +1226,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { outputMode match { case OutputMode.ECMAScript51Isolated => value match { - case js.Function(args, body) => + case js.Function(false, args, body) => // Make sure the function has a meaningful `name` property val functionExpr = js.FunctionDef(globalVarIdent, args, body) if (keepFunctionExpression) diff --git 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 index 1d101a8659..190dfc6e1f 100644 --- 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 @@ -233,7 +233,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { pos: Position): WithGlobals[js.Tree] = { for (fun <- desugarToFunction(Nil, expr, resultType)) yield { fun match { - case js.Function(Nil, js.Return(newExpr)) => + case js.Function(_, Nil, js.Return(newExpr)) => // no need for an IIFE, we can just use `newExpr` directly newExpr case _ => @@ -391,9 +391,10 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { */ val thisIdent = js.Ident("$thiz", Some("this")) val env = env0.withThisIdent(Some(thisIdent)) - val js.Function(jsParams, jsBody) = - desugarToFunctionInternal(params, body, isStat, env) - js.Function(js.ParamDef(thisIdent, rest = false) :: jsParams, jsBody) + val js.Function(jsArrow, jsParams, jsBody) = + desugarToFunctionInternal(arrow = false, params, body, isStat, env) + js.Function(jsArrow, js.ParamDef(thisIdent, rest = false) :: jsParams, + jsBody) } } @@ -403,13 +404,13 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { params: List[ParamDef], body: Tree, isStat: Boolean, env0: Env)( implicit pos: Position): WithGlobals[js.Function] = { performOptimisticThenPessimisticRuns { - desugarToFunctionInternal(params, body, isStat, env0) + desugarToFunctionInternal(arrow = false, params, body, isStat, env0) } } /** Desugars parameters and body to a JS function. */ - private def desugarToFunctionInternal( + private def desugarToFunctionInternal(arrow: Boolean, params: List[ParamDef], body: Tree, isStat: Boolean, env0: Env)( implicit pos: Position): js.Function = { @@ -438,7 +439,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case other => other } - js.Function(newParams, js.Block(extractRestParam, newBody)) + js.Function(arrow && useArrowFunctions, newParams, + js.Block(extractRestParam, newBody)) } private def makeExtractRestParam(params: List[ParamDef])( @@ -958,8 +960,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { } JSObjectConstr(newItems) - case Closure(captureParams, params, body, captureValues) => - Closure(captureParams, params, body, recs(captureValues)) + case Closure(arrow, captureParams, params, body, captureValues) => + Closure(arrow, captureParams, params, body, recs(captureValues)) case New(cls, constr, args) if noExtractYet => New(cls, constr, recs(args)) @@ -1148,7 +1150,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case _ => true }) } - case Closure(captureParams, params, body, captureValues) => + case Closure(arrow, captureParams, params, body, captureValues) => allowUnpure && (captureValues forall test) // Scala expressions that can always have side-effects @@ -1750,9 +1752,10 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { // Closures - case Closure(captureParams, params, body, captureValues) => + case Closure(arrow, captureParams, params, body, captureValues) => unnest(captureValues) { (newCaptureValues, env) => - redo(Closure(captureParams, params, body, newCaptureValues))(env) + redo(Closure(arrow, captureParams, params, body, newCaptureValues))( + env) } case CreateJSClass(cls, captureValues) => @@ -2406,16 +2409,17 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { js.VarRef(ident) } - case Closure(captureParams, params, body, captureValues) => - val innerFunction = - desugarToFunctionInternal(params, body, isStat = false, + case Closure(arrow, captureParams, params, body, captureValues) => + val innerFunction = { + desugarToFunctionInternal(arrow, params, body, isStat = false, Env.empty(AnyType).withParams(captureParams ++ params)) + } if (captureParams.isEmpty) { innerFunction } else { js.Apply( - js.Function(captureParams.map(transformParamDef), { + genArrowFunction(captureParams.map(transformParamDef), { js.Return(innerFunction) }), captureValues.zip(captureParams).map { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala index 66d3b8d1e7..7da67c26be 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala @@ -34,6 +34,13 @@ private[emitter] final class JSGen(val semantics: Semantics, import JSGen._ + val useArrowFunctions = { + outputMode match { + case OutputMode.ECMAScript51Isolated => false + case OutputMode.ECMAScript6 => true + } + } + def genZeroOf(tpe: Type)(implicit pos: Position): Tree = { tpe match { case BooleanType => BooleanLiteral(false) @@ -355,6 +362,11 @@ private[emitter] final class JSGen(val semantics: Semantics, else BracketSelect(qual, StringLiteral(item)) } + + def genArrowFunction(args: List[ParamDef], body: Tree)( + implicit pos: Position): Function = { + Function(useArrowFunctions, args, body) + } } private object JSGen { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Printers.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Printers.scala index f75a21dc98..0b88e424ff 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Printers.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Printers.scala @@ -481,11 +481,24 @@ object Printers { case This() => print("this") - case Function(args, body) => - print("(function") - printSig(args) - printBlock(body) - print(')') + case Function(arrow, args, body) => + if (arrow) { + print('(') + printSig(args) + print("=> ") + body match { + case Return(expr) => + print(expr) + case _ => + printBlock(body) + } + print(')') + } else { + print("(function") + printSig(args) + printBlock(body) + print(')') + } // Named function definition diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Trees.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Trees.scala index 0bc9292ea3..07dea99d6e 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Trees.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Trees.scala @@ -216,7 +216,8 @@ object Trees { case class This()(implicit val pos: Position) extends Tree - case class Function(args: List[ParamDef], body: Tree)(implicit val pos: Position) extends Tree + case class Function(arrow: Boolean, args: List[ParamDef], body: Tree)( + implicit val pos: Position) extends Tree // Named function definition diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index bb0550c6c9..49a65415a4 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -1042,7 +1042,7 @@ private final class IRChecker(unit: LinkingUnit, if (!isSubtype(env.thisTpe, tree.tpe)) reportError(s"this of type ${env.thisTpe} typed as ${tree.tpe}") - case Closure(captureParams, params, body, captureValues) => + case Closure(arrow, captureParams, params, body, captureValues) => /* Check compliance of captureValues wrt. captureParams in the current * method state, i.e., outside `withPerMethodState`. */ @@ -1068,8 +1068,9 @@ private final class IRChecker(unit: LinkingUnit, checkJSParamDefs(params) + val thisType = if (arrow) NoType else AnyType val bodyEnv = Env.fromSignature( - AnyType, None, captureParams ++ params, AnyType) + thisType, None, captureParams ++ params, AnyType) typecheckExpect(body, bodyEnv, AnyType) } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index 44ed878e9e..5a0b11ac9a 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -646,8 +646,8 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { pretransformExpr(tree)(finishTransform(isStat)) } - case Closure(captureParams, params, body, captureValues) => - transformClosureCommon(captureParams, params, body, + case Closure(arrow, captureParams, params, body, captureValues) => + transformClosureCommon(arrow, captureParams, params, body, captureValues.map(transformExpr)) case CreateJSClass(cls, captureValues) => @@ -669,16 +669,18 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { else result } - private def transformClosureCommon(captureParams: List[ParamDef], - params: List[ParamDef], body: Tree, newCaptureValues: List[Tree])( + private def transformClosureCommon(arrow: Boolean, + captureParams: List[ParamDef], params: List[ParamDef], body: Tree, + newCaptureValues: List[Tree])( implicit pos: Position): Closure = { + val thisType = if (arrow) NoType else AnyType val (allNewParams, newBody) = - transformIsolatedBody(None, AnyType, captureParams ++ params, AnyType, body) + transformIsolatedBody(None, thisType, captureParams ++ params, AnyType, body) val (newCaptureParams, newParams) = allNewParams.splitAt(captureParams.size) - Closure(newCaptureParams, newParams, newBody, newCaptureValues) + Closure(arrow, newCaptureParams, newParams, newBody, newCaptureValues) } private def transformBlock(tree: Block, isStat: Boolean)( @@ -891,20 +893,23 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { } } - case Closure(captureParams, params, body, captureValues) => + case Closure(arrow, captureParams, params, body, captureValues) => pretransformExprs(captureValues) { tcaptureValues => def default(): TailRec[Tree] = { - val newClosure = transformClosureCommon(captureParams, params, body, - tcaptureValues.map(finishTransformExpr)) + val newClosure = transformClosureCommon(arrow, captureParams, + params, body, tcaptureValues.map(finishTransformExpr)) cont(PreTransTree( newClosure, RefinedType(AnyType, isExact = false, isNullable = false))) } - if (params.exists(_.rest)) { + if (!arrow && params.exists(_.rest)) { /* TentativeClosureReplacement assumes there are no rest * parameters, because that would not be inlineable anyway. - * So we never try to inline a Closure with a rest parameter. + * Likewise, it assumes that there is no binding for `this`, which + * is only true for arrow functions. + * So we never try to inline non-arrow Closures, nor Closures with + * a rest parameter. There are few use cases for either anyway. */ default() } else { @@ -1373,7 +1378,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { Block(lengths.map(keepOnlySideEffects))(stat.pos) case Select(qualifier, _) => keepOnlySideEffects(qualifier) - case Closure(_, _, _, captureValues) => + case Closure(_, _, _, _, captureValues) => Block(captureValues.map(keepOnlySideEffects))(stat.pos) case UnaryOp(_, arg) => keepOnlySideEffects(arg) From 83a18e372d3511fc3da5c406cede2eaca6a4f55b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 10 Jan 2018 15:52:23 +0100 Subject: [PATCH 0612/2665] Introduce a true for-in loop in the IR. This commit adds first-class support for the general `for-in` loop. It can be produced with `js.special.forin`, which is now used to implement `js.Object.properties`. This is important because `js.Object.properties` cannot encode all uses of `for-in` loops. While it can encode most of the semantics applying to ordinary JS objects, it is not enough for exotic objects, notably proxies. Only exposing `js.Object.properties` was therefore a hole in our interoperability features. In addition, if another language wants to compile to the IR, they should have a way to encode an efficient `for-in` loop, which was previously not possible, as the only efficient `for-in` loop was based on intrinsifying a method from the Scala.js standard library. --- .../org/scalajs/core/compiler/GenJSCode.scala | 27 +++++++++++ .../scalajs/core/compiler/JSDefinitions.scala | 2 +- .../scalajs/core/compiler/JSPrimitives.scala | 4 +- .../scala/org/scalajs/core/ir/Hashers.scala | 6 +++ .../scala/org/scalajs/core/ir/Printers.scala | 8 ++++ .../org/scalajs/core/ir/Serializers.scala | 5 ++ .../main/scala/org/scalajs/core/ir/Tags.scala | 3 +- .../org/scalajs/core/ir/Transformers.scala | 3 ++ .../org/scalajs/core/ir/Traversers.scala | 4 ++ .../scala/org/scalajs/core/ir/Trees.scala | 5 ++ .../org/scalajs/core/ir/PrintersTest.scala | 10 ++++ .../src/main/scala/scala/scalajs/js/Any.scala | 33 ++++++++++--- .../scala/scalajs/js/special/package.scala | 25 ++++++++++ .../scala/scala/scalajs/runtime/package.scala | 48 ------------------- .../closure/ClosureAstTransformer.scala | 3 ++ tools/scalajsenv.js | 7 --- .../backend/emitter/FunctionEmitter.scala | 11 +++++ .../tools/linker/backend/emitter/JSGen.scala | 11 ++++- .../linker/backend/javascript/Printers.scala | 8 ++++ .../linker/backend/javascript/Trees.scala | 2 + .../core/tools/linker/checker/IRChecker.scala | 7 +++ .../frontend/optimizer/OptimizerCore.scala | 23 +++++---- 22 files changed, 178 insertions(+), 77 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 5795ca6f7e..66ee234368 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -4161,6 +4161,33 @@ abstract class GenJSCode extends plugins.PluginComponent case DELETE => // js.special.delete(arg1, arg2) js.JSDelete(js.JSBracketSelect(arg1, arg2)) + + case FORIN => + /* js.special.forin(arg1, arg2) + * + * We must generate: + * + * val obj = arg1 + * val f = arg2 + * for (val key in obj) { + * f(key) + * } + * + * with temporary vals, because `arg2` must be evaluated only + * once, and after `arg1`. + */ + val objVarDef = js.VarDef(freshLocalIdent("obj"), jstpe.AnyType, + mutable = false, arg1) + val fVarDef = js.VarDef(freshLocalIdent("f"), jstpe.AnyType, + mutable = false, arg2) + val keyVarIdent = freshLocalIdent("key") + val keyVarRef = js.VarRef(keyVarIdent)(jstpe.AnyType) + js.Block( + objVarDef, + fVarDef, + js.ForIn(objVarDef.ref, keyVarIdent, { + js.JSFunctionApply(fVarDef.ref, List(keyVarRef)) + })) } }) } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index dd53eb73ec..1411ba7572 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -94,6 +94,7 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val Special_in = getMemberMethod(SpecialPackageModule, newTermName("in")) lazy val Special_instanceof = getMemberMethod(SpecialPackageModule, newTermName("instanceof")) lazy val Special_delete = getMemberMethod(SpecialPackageModule, newTermName("delete")) + lazy val Special_forin = getMemberMethod(SpecialPackageModule, newTermName("forin")) lazy val Special_debugger = getMemberMethod(SpecialPackageModule, newTermName("debugger")) lazy val BooleanReflectiveCallClass = getRequiredClass("scala.scalajs.runtime.BooleanReflectiveCall") @@ -111,7 +112,6 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val Runtime_createInnerJSClass = getMemberMethod(RuntimePackageModule, newTermName("createInnerJSClass")) lazy val Runtime_createLocalJSClass = getMemberMethod(RuntimePackageModule, newTermName("createLocalJSClass")) lazy val Runtime_withContextualJSClassValue = getMemberMethod(RuntimePackageModule, newTermName("withContextualJSClassValue")) - lazy val Runtime_propertiesOf = getMemberMethod(RuntimePackageModule, newTermName("propertiesOf")) lazy val Runtime_linkingInfo = getMemberMethod(RuntimePackageModule, newTermName("linkingInfo")) lazy val WrappedArrayClass = getRequiredClass("scala.scalajs.js.WrappedArray") diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala index 609db6b5a4..88f103f60b 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala @@ -49,7 +49,8 @@ abstract class JSPrimitives { val IN = LINKING_INFO + 1 // js.special.in val INSTANCEOF = IN + 1 // js.special.instanceof val DELETE = INSTANCEOF + 1 // js.special.delete - val DEBUGGER = DELETE + 1 // js.special.debugger + val FORIN = DELETE + 1 // js.special.forin + val DEBUGGER = FORIN + 1 // js.special.debugger val LastJSPrimitiveCode = DEBUGGER @@ -90,6 +91,7 @@ abstract class JSPrimitives { addPrimitive(Special_in, IN) addPrimitive(Special_instanceof, INSTANCEOF) addPrimitive(Special_delete, DELETE) + addPrimitive(Special_forin, FORIN) addPrimitive(Special_debugger, DEBUGGER) } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala index 98b8d58133..237e02c3b5 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala @@ -141,6 +141,12 @@ object Hashers { mixTree(cond) mixOptIdent(label) + case ForIn(obj, keyVar, body) => + mixTag(TagForIn) + mixTree(obj) + mixIdent(keyVar) + mixTree(body) + case TryCatch(block, errVar, handler) => mixTag(TagTryCatch) mixTree(block) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index a3da382e33..e170933532 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -221,6 +221,14 @@ object Printers { print(cond) print(')') + case ForIn(obj, keyVar, body) => + print("for (val ") + print(keyVar) + print(" in ") + print(obj) + print(") ") + printBlock(body) + case TryFinally(TryCatch(block, errVar, handler), finalizer) => print("try ") printBlock(block) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index 4b57159c03..d68fc9f65f 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -170,6 +170,10 @@ object Serializers { writeByte(TagDoWhile) writeTree(body); writeTree(cond); writeOptIdent(label) + case ForIn(obj, keyVar, body) => + writeByte(TagForIn) + writeTree(obj); writeIdent(keyVar); writeTree(body) + case TryCatch(block, errVar, handler) => writeByte(TagTryCatch) writeTree(block); writeIdent(errVar); writeTree(handler) @@ -851,6 +855,7 @@ object Serializers { case TagIf => If(readTree(), readTree(), readTree())(readType()) case TagWhile => While(readTree(), readTree(), readOptIdent()) case TagDoWhile => DoWhile(readTree(), readTree(), readOptIdent()) + case TagForIn => ForIn(readTree(), readIdent(), readTree()) case TagTryCatch => TryCatch(readTree(), readIdent(), readTree())(readType()) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala index 583e7622fa..56438e2669 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala @@ -29,7 +29,8 @@ private[ir] object Tags { final val TagIf = TagReturn + 1 final val TagWhile = TagIf + 1 final val TagDoWhile = TagWhile + 1 - final val TagTryCatch = TagDoWhile + 1 + final val TagForIn = TagDoWhile + 1 + final val TagTryCatch = TagForIn + 1 final val TagTryFinally = TagTryCatch + 1 final val TagThrow = TagTryFinally + 1 final val TagContinue = TagThrow + 1 diff --git a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala index cf22c59c8d..be86b6e48d 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala @@ -62,6 +62,9 @@ object Transformers { case DoWhile(body, cond, label) => DoWhile(transformStat(body), transformExpr(cond), label) + case ForIn(obj, keyVar, body) => + ForIn(transformExpr(obj), keyVar, transformStat(body)) + case TryCatch(block, errVar, handler) => TryCatch(transform(block, isStat), errVar, transform(handler, isStat))(tree.tpe) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala index 571fcb6c1e..e52c0e6962 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala @@ -53,6 +53,10 @@ object Traversers { traverse(body) traverse(cond) + case ForIn(obj, keyVar, body) => + traverse(obj) + traverse(body) + case TryCatch(block, errVar, handler) => traverse(block) traverse(handler) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 785a0f3913..d4baf01576 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -199,6 +199,11 @@ object Trees { val tpe = NoType // cannot be in expression position } + case class ForIn(obj: Tree, keyVar: Ident, body: Tree)( + implicit val pos: Position) extends Tree { + val tpe = NoType + } + case class TryCatch(block: Tree, errVar: Ident, handler: Tree)( val tpe: Type)(implicit val pos: Position) extends Tree diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala index 4e6c020832..b514513c58 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala @@ -225,6 +225,16 @@ class PrintersTest { DoWhile(i(5), b(true), Some("lab"))) } + @Test def printForIn(): Unit = { + assertPrintEquals( + """ + |for (val x in o) { + | 5 + |} + """, + ForIn(ref("o", AnyType), "x", i(5))) + } + @Test def printTry(): Unit = { assertPrintEquals( """ diff --git a/library/src/main/scala/scala/scalajs/js/Any.scala b/library/src/main/scala/scala/scalajs/js/Any.scala index 53d326703c..3610dbf5ad 100644 --- a/library/src/main/scala/scala/scalajs/js/Any.scala +++ b/library/src/main/scala/scala/scalajs/js/Any.scala @@ -194,15 +194,34 @@ object Any extends js.LowPrioAnyImplicits { * object `o`, including properties in its prototype chain. * * This method returns the same set of names that would be enumerated by - * a for-in loop in JavaScript, but not necessarily in the same order. + * a for-in loop in JavaScript, in the same order. * - * If the underlying implementation guarantees an order for for-in loops, - * then this is guaranteed to be consistent with [[js.Object.keys]], in - * the sense that the list returned by [[js.Object.keys]] is a sublist of - * the list returned by this method (not just a subset). + * This method assumes that all keys enumerated by a for-in loop are + * strings. If this is not the case, calling this method is an undefined + * behavior of kind `ClassCastException`. Note that for all *ordinary* + * objects, the ECMAScript 2015 guarantees that this is the case. It might + * be false if `o` is a proxy object or another exotic object. + * + * For ordinary objects, if the underlying implementation guarantees an + * order for for-in loops, then this is guaranteed to be consistent with + * [[js.Object.keys]], in the sense that the list returned by + * [[js.Object.keys]] is a sublist of the list returned by this method + * (not just a subset). */ - def properties(o: js.Any): js.Array[String] = - scala.scalajs.runtime.propertiesOf(o) + @noinline + def properties(o: js.Any): js.Array[String] = { + /* DO NOT touch this code without double-checking the optimized code. + * + * This implementation is carefully crafted so that the optimizer turns + * the code into a pattern known not to fall off the performance cliffs. + */ + val result = js.Array[scala.Any]() + @inline def appendProp(p: scala.Any): Unit = result.push(p) + js.special.forin(o) { p => + appendProp(p) + } + result.asInstanceOf[js.Array[String]] + } } } diff --git a/library/src/main/scala/scala/scalajs/js/special/package.scala b/library/src/main/scala/scala/scalajs/js/special/package.scala index d2917bbcc6..b0f625cc02 100644 --- a/library/src/main/scala/scala/scalajs/js/special/package.scala +++ b/library/src/main/scala/scala/scalajs/js/special/package.scala @@ -92,6 +92,31 @@ package object special { def delete(obj: scala.Any, key: scala.Any): Unit = throw new java.lang.Error("stub") + /** Enumerates the keys of an object. + * + * This method is the exact equivalent of the `for (a in o) {}` statement of + * JavaScript. A call of the form + * {{{ + * forin(obj)(f) + * }}} + * corresponds to the JavaScript statement + * {{{ + * const objTemp = obj; + * const fTemp = f; + * for (const x in objTemp) { + * fTemp(x) + * } + * }}} + * + * `for..in` loops exhibit performance cliffs in most JavaScript engines, + * which means their performance is very dependent on their surroundings. + * Therefore, it is recommended to avoid this method and use + * [[js.Any.ObjectCompanionOps.properties js.Object.properties]] instead, if + * possible. + */ + def forin(obj: scala.Any)(f: js.Function1[scala.Any, scala.Any]): Unit = + throw new java.lang.Error("stub") + /** The value of the global JavaScript `this`. * * This returns the value that would be obtained by writing `this` at the diff --git a/library/src/main/scala/scala/scalajs/runtime/package.scala b/library/src/main/scala/scala/scalajs/runtime/package.scala index 39d41a196e..3e05310a4a 100644 --- a/library/src/main/scala/scala/scalajs/runtime/package.scala +++ b/library/src/main/scala/scala/scalajs/runtime/package.scala @@ -84,54 +84,6 @@ package object runtime { def withContextualJSClassValue[A](jsclass: AnyRef, inner: A): A = throw new Error("stub") - /** Returns an array of the enumerable properties in an object's prototype - * chain. - * - * This is the implementation of [[js.Object.properties]]. - */ - def propertiesOf(obj: js.Any): js.Array[String] = { - // See http://stackoverflow.com/questions/26445248/ - if (obj == null || js.isUndefined(obj)) { - js.Array() - } else { - val result = new js.Array[String] - val alreadySeen = js.Dictionary.empty[Boolean] - - @tailrec - def loop(obj: js.Object): Unit = { - if (obj != null) { - // Add own enumerable properties that have not been seen yet - val enumProps = js.Object.keys(obj) - val enumPropsLen = enumProps.length - var i = 0 - while (i < enumPropsLen) { - val prop = enumProps(i) - if (!alreadySeen.get(prop).isDefined) - result.push(prop) - i += 1 - } - - /* Add all own properties to the alreadySeen set, including - * non-enumerable ones. - */ - val allProps = js.Object.getOwnPropertyNames(obj) - val allPropsLen = allProps.length - var j = 0 - while (j < allPropsLen) { - alreadySeen(allProps(j)) = true - j += 1 - } - - // Continue with the next object in the prototype chain - loop(js.Object.getPrototypeOf(obj)) - } - } - loop(js.Object(obj)) - - result - } - } - /** Information known at link-time, given the output configuration. * * See [[LinkingInfo]] for details. diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala index 217f5fe52d..09d1d1491c 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala @@ -60,6 +60,9 @@ private[closure] class ClosureAstTransformer(relativizeBaseURI: Option[URI]) { new Node(Token.DO, transformBlock(body), transformExpr(cond)) new Node(Token.LABEL, transformLabel(label), setNodePosition(doNode, pos)) + case ForIn(lhs, obj, body) => + new Node(Token.FOR, transformStat(lhs), transformExpr(obj), + transformBlock(body)) case TryFinally(TryCatch(block, errVar, handler), finalizer) => val catchPos = handler.pos orElse pos val catchNode = diff --git a/tools/scalajsenv.js b/tools/scalajsenv.js index 5312b54a9b..ad3c7c2bc0 100644 --- a/tools/scalajsenv.js +++ b/tools/scalajsenv.js @@ -523,13 +523,6 @@ function $moduleDefault(m) { }; //!endif -function $propertiesOf(obj) { - const result = []; - for (const prop in obj) - result["push"](prop); - return result; -}; - function $systemArraycopy(src, srcPos, dest, destPos, length) { const srcu = src.u; const destu = dest.u; diff --git 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 index 1d101a8659..eb7b091e60 100644 --- 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 @@ -625,6 +625,17 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { }, newLabel) } + case ForIn(obj, keyVar, body) => + unnest(obj) { (newObj, env0) => + implicit val env = env0 + + val lhs = genEmptyImmutableLet(transformLocalVarIdent(keyVar)) + js.ForIn(lhs, transformExprNoChar(newObj), { + transformStat(body, Set.empty)( + env.withDef(keyVar, mutable = false)) + }) + } + case Debugger() => js.Debugger() diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala index 66d3b8d1e7..15ba9dd9e0 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala @@ -71,12 +71,19 @@ private[emitter] final class JSGen(val semantics: Semantics, } } - def genEmptyMutableLet(name: Ident)(implicit pos: Position): LocalDef = { + def genEmptyMutableLet(name: Ident)(implicit pos: Position): LocalDef = + genEmptyLet(name, mutable = true) + + def genEmptyImmutableLet(name: Ident)(implicit pos: Position): LocalDef = + genEmptyLet(name, mutable = false) + + private def genEmptyLet(name: Ident, mutable: Boolean)( + implicit pos: Position): LocalDef = { outputMode match { case OutputMode.ECMAScript51Isolated => VarDef(name, rhs = None) case OutputMode.ECMAScript6 => - Let(name, mutable = true, rhs = None) + Let(name, mutable, rhs = None) } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Printers.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Printers.scala index f75a21dc98..d444e1a1a0 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Printers.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Printers.scala @@ -223,6 +223,14 @@ object Printers { print(cond) print(')') + case ForIn(lhs, obj, body) => + print("for (") + print(lhs) + print(" in ") + print(obj) + print(") ") + printBlock(body) + case TryFinally(TryCatch(block, errVar, handler), finalizer) => print("try ") printBlock(block) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Trees.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Trees.scala index 0bc9292ea3..8911c60700 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Trees.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Trees.scala @@ -120,6 +120,8 @@ object Trees { case class DoWhile(body: Tree, cond: Tree, label: Option[Ident] = None)(implicit val pos: Position) extends Tree + case class ForIn(lhs: Tree, obj: Tree, body: Tree)(implicit val pos: Position) extends Tree + case class TryCatch(block: Tree, errVar: Ident, handler: Tree)(implicit val pos: Position) extends Tree case class TryFinally(block: Tree, finalizer: Tree)(implicit val pos: Position) extends Tree diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index bb0550c6c9..a2554a1045 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -609,6 +609,13 @@ private final class IRChecker(unit: LinkingUnit, typecheckExpect(cond, env, BooleanType) env + case ForIn(obj, keyVar, body) => + typecheckExpr(obj, env) + val bodyEnv = + env.withLocal(LocalDef(keyVar.name, AnyType, false)(keyVar.pos)) + typecheckStat(body, bodyEnv) + env + case TryCatch(block, errVar, handler) => typecheckStat(block, env) val handlerEnv = diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index 44ed878e9e..e42373126d 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -408,6 +408,18 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case _ => DoWhile(newBody, newCond, None) } + case ForIn(obj, keyVar @ Ident(name, originalName), body) => + val newObj = transformExpr(obj) + val newName = freshLocalName(name, mutable = false) + val newOriginalName = originalName.orElse(Some(name)) + val localDef = LocalDef(RefinedType(AnyType), mutable = false, + ReplaceWithVarRef(newName, newOriginalName, newSimpleState(true), None)) + val newBody = { + val bodyScope = scope.withEnv(scope.env.withLocalDef(name, localDef)) + transformStat(body)(bodyScope) + } + ForIn(newObj, Ident(newName, newOriginalName)(keyVar.pos), newBody) + case TryCatch(block, errVar @ Ident(name, originalName), handler) => val newBlock = transform(block, isStat) @@ -2006,11 +2018,6 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { defaultApply("array$undlength__O__I", IntType) } - // scala.scalajs.runtime package object - - case PropertiesOf => - contTree(CallHelper("propertiesOf", newArgs)(AnyType)) - // java.lang.Integer case IntegerNLZ => @@ -4904,9 +4911,7 @@ private[optimizer] object OptimizerCore { final val ArrayUpdate = ArrayApply + 1 final val ArrayLength = ArrayUpdate + 1 - final val PropertiesOf = ArrayLength + 1 - - final val IntegerNLZ = PropertiesOf + 1 + final val IntegerNLZ = ArrayLength + 1 final val LongToString = IntegerNLZ + 1 final val LongCompare = LongToString + 1 @@ -4945,8 +4950,6 @@ private[optimizer] object OptimizerCore { "sr_ScalaRunTime$.array$undupdate__O__I__O__V" -> ArrayUpdate, "sr_ScalaRunTime$.array$undlength__O__I" -> ArrayLength, - "sjsr_package$.propertiesOf__sjs_js_Any__sjs_js_Array" -> PropertiesOf, - "jl_Integer$.numberOfLeadingZeros__I__I" -> IntegerNLZ, "jl_Long$.toString__J__T" -> LongToString, From ba2c84458a9ef548c6817fa4bbe0f341ff8edbdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 10 Jan 2018 21:36:22 +0100 Subject: [PATCH 0613/2665] Consolidate the notion of transient node in the IR. Previously, we had two kinds of nodes in the IR used for internal purposes: `UndefinedParam` and `CallHelper`. Those nodes should not be part of the public IR definition. We get rid of that public display by introducing a unique, generic `Transient` node, which can be used by internal phases for custom purposes. The scalac plugin uses it for `UndefinedParam`, and the optimizer+emitter use it for `CallHelper`. Transient nodes could be used by any other phase, including user-defined tools manipulating IR trees. --- .../org/scalajs/core/compiler/GenJSCode.scala | 32 ++++++++---- .../scala/org/scalajs/core/ir/Hashers.scala | 20 ++------ .../scala/org/scalajs/core/ir/Printers.scala | 26 +++++----- .../org/scalajs/core/ir/Serializers.scala | 20 ++------ .../main/scala/org/scalajs/core/ir/Tags.scala | 7 ++- .../org/scalajs/core/ir/Transformers.scala | 5 +- .../org/scalajs/core/ir/Traversers.scala | 5 +- .../scala/org/scalajs/core/ir/Trees.scala | 46 +++++++++++------ .../org/scalajs/core/ir/PrintersTest.scala | 22 +++++---- .../core/tools/linker/analyzer/Infos.scala | 5 ++ .../backend/emitter/FunctionEmitter.scala | 18 ++++--- .../linker/backend/emitter/Transients.scala | 30 ++++++++++++ .../frontend/optimizer/OptimizerCore.scala | 49 ++++++++++++------- 13 files changed, 169 insertions(+), 116 deletions(-) create mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/Transients.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 48aa6d6be9..a3286a981a 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -331,7 +331,7 @@ abstract class GenJSCode extends plugins.PluginComponent } catch { case e: ir.InvalidIRException => e.tree match { - case ir.Trees.UndefinedParam() => + case ir.Trees.Transient(UndefinedParam) => reporter.error(sym.pos, "Found a dangling UndefinedParam at " + s"${e.tree.pos}. This is likely due to a bad " + @@ -1879,7 +1879,7 @@ abstract class GenJSCode extends plugins.PluginComponent else genExpr(rhs) rhsTree match { - case js.UndefinedParam() => + case js.Transient(UndefinedParam) => // This is an intermediate assignment for default params on a // js.Any. Add the symbol to the corresponding set to inform // the Ident resolver how to replace it and don't emit the symbol @@ -1974,7 +1974,7 @@ abstract class GenJSCode extends plugins.PluginComponent } else if (undefinedDefaultParams contains sym) { // This is a default parameter whose assignment was moved to // a local variable. Put a literal undefined param again - js.UndefinedParam()(toIRType(sym.tpe)) + js.Transient(UndefinedParam)(toIRType(sym.tpe)) } else { js.VarRef(encodeLocalSym(sym))(toIRType(sym.tpe)) } @@ -2359,7 +2359,7 @@ abstract class GenJSCode extends plugins.PluginComponent genApplyTypeApply(tree, isStat) case _ if isRawJSDefaultParam => - js.UndefinedParam()(toIRType(sym.tpe.resultType)) + js.Transient(UndefinedParam)(toIRType(sym.tpe.resultType)) case Select(Super(_, _), _) => genSuperCall(tree, isStat) @@ -4576,7 +4576,7 @@ abstract class GenJSCode extends plugins.PluginComponent case Some(false) => val unboxedArg = genExpr(arg) val boxedArg = unboxedArg match { - case js.UndefinedParam() => + case js.Transient(UndefinedParam) => unboxedArg case _ => val tpe = paramTpes.getOrElse(paramSym.name, paramSym.tpe) @@ -4594,17 +4594,20 @@ abstract class GenJSCode extends plugins.PluginComponent } } - /* Remove all consecutive js.UndefinedParam's at the end of the argument + /* Remove all consecutive UndefinedParam's at the end of the argument * list. No check is performed whether they may be there, since they will * only be placed where default arguments can be anyway. */ - reversedArgs = reversedArgs.dropWhile(_.isInstanceOf[js.UndefinedParam]) + reversedArgs = reversedArgs.dropWhile { + case js.Transient(UndefinedParam) => true + case _ => false + } - // Find remaining js.UndefinedParam and replace by js.Undefined. This can + // Find remaining UndefinedParam's and replace by js.Undefined. This can // happen with named arguments or when multiple argument lists are present reversedArgs = reversedArgs map { - case js.UndefinedParam() => js.Undefined() - case arg => arg + case js.Transient(UndefinedParam) => js.Undefined() + case arg => arg } reversedArgs.reverse @@ -5633,4 +5636,13 @@ abstract class GenJSCode extends plugins.PluginComponent case class GlobalScope(pos: Position) extends MaybeGlobalScope } + + /** Marker object for undefined parameters in JavaScript semantic calls. + * + * To be used inside a `js.Transient` node. + */ + case object UndefinedParam extends js.Transient.Value { + def printIR(out: ir.Printers.IRTreePrinter): Unit = + out.print("") + } } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala index 7e8ffb7412..b922eb51d2 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala @@ -285,12 +285,6 @@ object Hashers { mixTag(TagGetClass) mixTree(expr) - case CallHelper(helper, args) => - mixTag(TagCallHelper) - mixString(helper) - mixTrees(args) - mixType(tree.tpe) - case JSNew(ctor, args) => mixTag(TagJSNew) mixTree(ctor) @@ -384,15 +378,6 @@ object Hashers { case Undefined() => mixTag(TagUndefined) - case UndefinedParam() => - /* UndefinedParam is a "transient" IR node, and cannot be hashed. - * TODO At the moment, this is quite ad hoc to support dangling - * UndefinedParam detection in the compiler back-end. This should be - * generalized for custom transient nodes. - */ - throw new InvalidIRException(tree, - "Cannot hash a transient IR node of type UndefinedParam") - case Null() => mixTag(TagNull) @@ -458,6 +443,11 @@ object Hashers { mixClassRef(cls) mixTrees(captureValues) + case Transient(value) => + throw new InvalidIRException(tree, + "Cannot hash a transient IR node (its value is of class " + + s"${value.getClass})") + case _ => throw new IllegalArgumentException( s"Unable to hash tree of class ${tree.getClass}") diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index d75bbb4ea9..ed9c71e413 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -527,10 +527,6 @@ object Printers { print(expr) print(".getClass()") - case CallHelper(helper, args) => - print(helper) - printArgs(args) - // JavaScript expressions case JSNew(ctor, args) => @@ -789,11 +785,6 @@ object Printers { print(typeRef) print(']') - // Specials - - case UndefinedParam() => - print("") - // Atomic expressions case VarRef(ident) => @@ -825,6 +816,11 @@ object Printers { print("createjsclass[") print(cls) printRow(captureValues, "](", ", ", ")") + + // Transient + + case Transient(value) => + value.printIR(this) } } @@ -1012,10 +1008,10 @@ object Printers { print(')') } - protected def print(ident: Ident): Unit = + def print(ident: Ident): Unit = printEscapeJS(ident.name, out) - private final def print(propName: PropertyName): Unit = propName match { + def print(propName: PropertyName): Unit = propName match { case lit: StringLiteral => print(lit: Tree) case ident: Ident => print(ident) @@ -1027,7 +1023,7 @@ object Printers { print(")") } - private def print(spec: JSNativeLoadSpec): Unit = { + def print(spec: JSNativeLoadSpec): Unit = { def printPath(path: List[String]): Unit = { for (propName <- path) { print("[\"") @@ -1055,13 +1051,13 @@ object Printers { } } - protected def print(s: String): Unit = + def print(s: String): Unit = out.write(s) - protected def print(c: Int): Unit = + def print(c: Int): Unit = out.write(c) - protected def print(optimizerHints: OptimizerHints)( + def print(optimizerHints: OptimizerHints)( implicit dummy: DummyImplicit): Unit = { if (optimizerHints != OptimizerHints.empty) { print("@hints(") diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index 848efc9729..0a0517db71 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -286,11 +286,6 @@ object Serializers { writeByte(TagGetClass) writeTree(expr) - case CallHelper(helper, args) => - writeByte(TagCallHelper) - writeString(helper); writeTrees(args) - writeType(tree.tpe) - case JSNew(ctor, args) => writeByte(TagJSNew) writeTree(ctor); writeTreeOrJSSpreads(args) @@ -411,15 +406,6 @@ object Serializers { writeByte(TagClassOf) writeTypeRef(typeRef) - case UndefinedParam() => - /* UndefinedParam is a "transient" IR node, and cannot be serialized. - * TODO At the moment, this is quite ad hoc to support dangling - * UndefinedParam detection in the compiler back-end. This should be - * generalized for custom transient nodes. - */ - throw new InvalidIRException(tree, - "Cannot serialize a transient IR node of type UndefinedParam") - case VarRef(ident) => writeByte(TagVarRef) writeIdent(ident) @@ -441,6 +427,11 @@ object Serializers { writeByte(TagCreateJSClass) writeClassRef(cls) writeTrees(captureValues) + + case Transient(value) => + throw new InvalidIRException(tree, + "Cannot serialize a transient IR node (its value is of class " + + s"${value.getClass})") } if (UseDebugMagic) writeInt(DebugMagic) @@ -891,7 +882,6 @@ object Serializers { case TagAsInstanceOf => AsInstanceOf(readTree(), readTypeRef()) case TagUnbox => Unbox(readTree(), readByte().toChar) case TagGetClass => GetClass(readTree()) - case TagCallHelper => CallHelper(readString(), readTrees())(readType()) case TagJSNew => JSNew(readTree(), readTreeOrJSSpreads()) case TagJSDotSelect => JSDotSelect(readTree(), readIdent()) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala index 56438e2669..7a02c2b6f4 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala @@ -56,9 +56,8 @@ private[ir] object Tags { final val TagAsInstanceOf = TagIsInstanceOf + 1 final val TagUnbox = TagAsInstanceOf + 1 final val TagGetClass = TagUnbox + 1 - final val TagCallHelper = TagGetClass + 1 - final val TagJSNew = TagCallHelper + 1 + final val TagJSNew = TagGetClass + 1 final val TagJSDotSelect = TagJSNew + 1 final val TagJSBracketSelect = TagJSDotSelect + 1 final val TagJSFunctionApply = TagJSBracketSelect + 1 @@ -95,6 +94,10 @@ private[ir] object Tags { final val TagClosure = TagThis + 1 final val TagCreateJSClass = TagClosure + 1 + /* Note that there is no TagTransient, since transient nodes are never + * serialized nor hashed. + */ + // Tags for member defs final val TagFieldDef = 1 diff --git a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala index dfd0d6045a..c13d8d8104 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala @@ -135,9 +135,6 @@ object Transformers { case GetClass(expr) => GetClass(transformExpr(expr)) - case CallHelper(helper, args) => - CallHelper(helper, args map transformExpr)(tree.tpe) - // JavaScript expressions case JSNew(ctor, args) => @@ -208,7 +205,7 @@ object Transformers { case _:Skip | _:Continue | _:Debugger | _:LoadModule | _:SelectStatic | _:LoadJSConstructor | _:LoadJSModule | _:JSLinkingInfo | - _:Literal | _:UndefinedParam | _:VarRef | _:This | _:JSGlobalRef => + _:Literal | _:VarRef | _:This | _:JSGlobalRef | _:Transient => tree } } diff --git a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala index 9adf191bf9..359809f829 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala @@ -130,9 +130,6 @@ object Traversers { case GetClass(expr) => traverse(expr) - case CallHelper(helper, args) => - args foreach traverse - // JavaScript expressions case JSNew(ctor, args) => @@ -209,7 +206,7 @@ object Traversers { case _:Skip | _:Continue | _:Debugger | _:LoadModule | _:SelectStatic | _:LoadJSConstructor | _:LoadJSModule | _:JSLinkingInfo | _:Literal | - _:UndefinedParam | _:VarRef | _:This | _:JSGlobalRef => + _:VarRef | _:This | _:JSGlobalRef | _:Transient => } def traverseClassDef(tree: ClassDef): Unit = { diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 2617967946..ebaba19984 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -474,16 +474,6 @@ object Trees { val tpe = ClassType(Definitions.ClassClass) } - case class CallHelper(helper: String, args: List[Tree])(val tpe: Type)( - implicit val pos: Position) extends Tree - - object CallHelper { - def apply(helper: String, args: Tree*)(tpe: Type)( - implicit pos: Position): CallHelper = { - CallHelper(helper, args.toList)(tpe) - } - } - // JavaScript expressions case class JSNew(ctor: Tree, args: List[TreeOrJSSpread])( @@ -845,11 +835,6 @@ object Trees { val tpe = ClassType(Definitions.ClassClass) } - // Specials - - case class UndefinedParam()(val tpe: Type)( - implicit val pos: Position) extends Tree - // Atomic expressions case class VarRef(ident: Ident)(val tpe: Type)( @@ -886,6 +871,37 @@ object Trees { val tpe = AnyType } + // Transient, a special one + + /** A transient node for custom purposes. + * + * A transient node is never a valid input to the [[Serializers]] nor to the + * linker, but can be used in a transient state for internal purposes. + * + * @param value + * The payload of the transient node, without any specified meaning. + */ + case class Transient(value: Transient.Value)(val tpe: Type)( + implicit val pos: Position) + extends Tree + + object Transient { + /** Common interface for the values that can be stored in [[Transient]] + * nodes. + */ + trait Value { + /** Prints the IR representation of this transient node. + * This method is called by the IR printers when encountering a + * [[Transient]] node. + * + * @param out + * The [[Printers.IRTreePrinter]] to which the transient node must be + * printed. It can be used to print raw strings or nested IR nodes. + */ + def printIR(out: Printers.IRTreePrinter): Unit + } + } + // Classes final class ClassDef( diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala index ef145740fd..360a235471 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala @@ -576,11 +576,6 @@ class PrintersTest { assertPrintEquals("x.getClass()", GetClass(ref("x", AnyType))) } - @Test def printCallHelper(): Unit = { - assertPrintEquals("help(x, y)", - CallHelper("help", List(ref("x", AnyType), ref("y", AnyType)))(IntType)) - } - @Test def printJSNew(): Unit = { assertPrintEquals("new C()", JSNew(ref("C", AnyType), Nil)) assertPrintEquals("new C(4, 5)", JSNew(ref("C", AnyType), List(i(4), i(5)))) @@ -825,10 +820,6 @@ class PrintersTest { assertPrintEquals("classOf[LTest]", ClassOf("LTest")) } - @Test def printUndefinedParam(): Unit = { - assertPrintEquals("", UndefinedParam()(IntType)) - } - @Test def printVarRef(): Unit = { assertPrintEquals("x", VarRef("x")(IntType)) } @@ -870,6 +861,19 @@ class PrintersTest { CreateJSClass("LFoo", List(ref("x", IntType), ref("y", AnyType)))) } + @Test def printTransient(): Unit = { + class MyTransient(expr: Tree) extends Transient.Value { + def printIR(out: Printers.IRTreePrinter): Unit = { + out.print("mytransient(") + out.print(expr) + out.print(")") + } + } + + assertPrintEquals("mytransient(5)", + Transient(new MyTransient(i(5)))(AnyType)) + } + @Test def printClassDefKinds(): Unit = { import ClassKind._ diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala index 1dd10e5060..9a4c7e7ef1 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala @@ -18,6 +18,7 @@ import org.scalajs.core.ir.Trees._ import org.scalajs.core.ir.Types._ import org.scalajs.core.tools.linker.LinkedClass +import org.scalajs.core.tools.linker.backend.emitter.Transients._ object Infos { @@ -487,6 +488,10 @@ object Infos { case CreateJSClass(cls, _) => builder.addInstantiatedClass(cls.className) + case Transient(CallHelper(_, args)) => + // This should only happen when called from the Refiner + args.foreach(traverse) + case _ => } diff --git 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 index f5b8fdf514..178c7e33c8 100644 --- 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 @@ -27,6 +27,8 @@ import org.scalajs.core.tools.linker.backend.javascript.{Trees => js} import java.io.StringWriter +import Transients._ + /** Desugaring of the IR to JavaScript functions. * * The general shape and compliance to standards is chosen with an @@ -991,8 +993,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case ArraySelect(array, index) if noExtractYet => val newIndex = rec(index) ArraySelect(rec(array), newIndex)(arg.tpe) - case CallHelper(helper, args) if noExtractYet => - CallHelper(helper, recs(args))(arg.tpe) + case Transient(CallHelper(helper, args)) if noExtractYet => + Transient(CallHelper(helper, recs(args)))(arg.tpe) case If(cond, thenp, elsep) if noExtractYet && isExpression(thenp) && isExpression(elsep) => @@ -1177,7 +1179,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { allowSideEffects && (args forall test) case GetClass(arg) => allowSideEffects && test(arg) - case CallHelper(helper, args) => + case Transient(CallHelper(helper, args)) => allowSideEffects && (args forall test) // Casts @@ -1592,9 +1594,9 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { redo(GetClass(newExpr))(env) } - case CallHelper(helper, args) => + case Transient(CallHelper(helper, args)) => unnest(args) { (newArgs, env) => - redo(CallHelper(helper, newArgs)(rhs.tpe))(env) + redo(Transient(CallHelper(helper, newArgs))(rhs.tpe))(env) } // JavaScript expressions (if we reach here their arguments are not expressions) @@ -1602,8 +1604,8 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case JSNew(ctor, args) => if (containsAnySpread(args)) { redo { - CallHelper("newJSObjectWithVarargs", - List(ctor, spreadToArgArray(args)))(AnyType) + Transient(CallHelper("newJSObjectWithVarargs", + List(ctor, spreadToArgArray(args))))(AnyType) } } else { unnest(ctor :: castNoSpread(args)) { (newCtorAndArgs, env) => @@ -2274,7 +2276,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case GetClass(expr) => genCallHelper("objectGetClass", transformExprNoChar(expr)) - case CallHelper(helper, args) => + case Transient(CallHelper(helper, args)) => helper match { case "classDataOf" => args.head match { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/Transients.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/Transients.scala new file mode 100644 index 0000000000..94e68eade8 --- /dev/null +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/Transients.scala @@ -0,0 +1,30 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2018, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.core.tools.linker.backend.emitter + +import org.scalajs.core.ir.Trees._ +import org.scalajs.core.ir.Printers._ + +object Transients { + + final case class CallHelper(helper: String, args: List[Tree]) + extends Transient.Value { + + def printIR(out: IRTreePrinter): Unit = { + out.print("$callHelper(") + out.print(helper) + for (arg <- args) { + out.print(", ") + out.print(arg) + } + out.print(")") + } + } + +} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index b76e687a9f..e72c550908 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -27,6 +27,7 @@ import org.scalajs.core.tools.logging._ import org.scalajs.core.tools.linker._ import org.scalajs.core.tools.linker.standard._ import org.scalajs.core.tools.linker.backend.emitter.LongImpl +import org.scalajs.core.tools.linker.backend.emitter.Transients.CallHelper /** Optimizer core. * Designed to be "mixed in" [[IncOptimizer#MethodImpl#Optimizer]]. @@ -1977,9 +1978,9 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case ArrayCopy => assert(isStat, "System.arraycopy must be used in statement position") - contTree(CallHelper("systemArraycopy", newArgs)(NoType)) + contTree(callHelper("systemArraycopy", newArgs)(NoType)) case IdentityHashCode => - contTree(CallHelper("systemIdentityHashCode", newArgs)(IntType)) + contTree(callHelper("systemIdentityHashCode", newArgs)(IntType)) // scala.runtime.ScalaRunTime object @@ -2028,7 +2029,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case IntegerNLZ => contTree(newArgs.head match { case IntLiteral(value) => IntLiteral(Integer.numberOfLeadingZeros(value)) - case newArg => CallHelper("clz32", newArg)(IntType) + case newArg => callHelper("clz32", newArg)(IntType) }) // java.lang.Long @@ -2060,9 +2061,9 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case ClassOf(elemTypeRef) => (ArrayType(ArrayTypeRef.of(elemTypeRef)), true) case _ => (AnyType, false) } - cont(PreTransTree(CallHelper("makeNativeArrayWrapper", - CallHelper("arrayDataOf", - CallHelper("classDataOf", runtimeClass)(AnyType))(AnyType), + cont(PreTransTree(callHelper("makeNativeArrayWrapper", + callHelper("arrayDataOf", + callHelper("classDataOf", runtimeClass)(AnyType))(AnyType), array)(resultType), RefinedType(resultType, isExact = isExact, isNullable = false))) @@ -2091,7 +2092,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case ClassOf(_) => Null() case runtimeClass => - CallHelper("zeroOf", runtimeClass)(AnyType) + callHelper("zeroOf", runtimeClass)(AnyType) }) // java.lang.Class @@ -2182,33 +2183,43 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { // TypedArray conversions case ByteArrayToInt8Array => - contTree(CallHelper("byteArray2TypedArray", newArgs)(AnyType)) + contTree(callHelper("byteArray2TypedArray", newArgs)(AnyType)) case ShortArrayToInt16Array => - contTree(CallHelper("shortArray2TypedArray", newArgs)(AnyType)) + contTree(callHelper("shortArray2TypedArray", newArgs)(AnyType)) case CharArrayToUint16Array => - contTree(CallHelper("charArray2TypedArray", newArgs)(AnyType)) + contTree(callHelper("charArray2TypedArray", newArgs)(AnyType)) case IntArrayToInt32Array => - contTree(CallHelper("intArray2TypedArray", newArgs)(AnyType)) + contTree(callHelper("intArray2TypedArray", newArgs)(AnyType)) case FloatArrayToFloat32Array => - contTree(CallHelper("floatArray2TypedArray", newArgs)(AnyType)) + contTree(callHelper("floatArray2TypedArray", newArgs)(AnyType)) case DoubleArrayToFloat64Array => - contTree(CallHelper("doubleArray2TypedArray", newArgs)(AnyType)) + contTree(callHelper("doubleArray2TypedArray", newArgs)(AnyType)) case Int8ArrayToByteArray => - contTree(CallHelper("typedArray2ByteArray", newArgs)(AnyType)) + contTree(callHelper("typedArray2ByteArray", newArgs)(AnyType)) case Int16ArrayToShortArray => - contTree(CallHelper("typedArray2ShortArray", newArgs)(AnyType)) + contTree(callHelper("typedArray2ShortArray", newArgs)(AnyType)) case Uint16ArrayToCharArray => - contTree(CallHelper("typedArray2CharArray", newArgs)(AnyType)) + contTree(callHelper("typedArray2CharArray", newArgs)(AnyType)) case Int32ArrayToIntArray => - contTree(CallHelper("typedArray2IntArray", newArgs)(AnyType)) + contTree(callHelper("typedArray2IntArray", newArgs)(AnyType)) case Float32ArrayToFloatArray => - contTree(CallHelper("typedArray2FloatArray", newArgs)(AnyType)) + contTree(callHelper("typedArray2FloatArray", newArgs)(AnyType)) case Float64ArrayToDoubleArray => - contTree(CallHelper("typedArray2DoubleArray", newArgs)(AnyType)) + contTree(callHelper("typedArray2DoubleArray", newArgs)(AnyType)) } } + private def callHelper(helper: String, args: List[Tree])(tpe: Type)( + implicit pos: Position): Tree = { + Transient(CallHelper(helper, args))(tpe) + } + + private def callHelper(helper: String, args: Tree*)(tpe: Type)( + implicit pos: Position): Tree = { + callHelper(helper, args.toList)(tpe) + } + private def inlineClassConstructor(allocationSite: AllocationSite, cls: ClassType, initialValue: RecordValue, ctor: Ident, args: List[PreTransform], cancelFun: CancelFun)( From 097c45c9b2d4e634ab1f2c9f48f080595a67fc9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 8 Jan 2018 15:39:28 +0100 Subject: [PATCH 0614/2665] Decouple VirtualFileContainer from ScalaJSIRContainer. `VirtualFileContainer` and its subclasses, such as `VirtualJarFile`, are now independent of `ScalaJSIRContainer` and hence of virtual IR-related files in general. --- .../linker/testutils/NodeVirtualJarFile.scala | 7 ++ .../tools/linker/testutils/Platform.scala | 2 +- .../core/tools/io/FileVirtualFiles.scala | 14 +++- .../tools/linker/testutils/Platform.scala | 2 +- .../scalajs/core/tools/io/VirtualFiles.scala | 66 +++++++------------ 5 files changed, 43 insertions(+), 48 deletions(-) diff --git a/tools/js/src/test/scala/org/scalajs/core/tools/linker/testutils/NodeVirtualJarFile.scala b/tools/js/src/test/scala/org/scalajs/core/tools/linker/testutils/NodeVirtualJarFile.scala index d78146488a..f4b8ceb731 100644 --- a/tools/js/src/test/scala/org/scalajs/core/tools/linker/testutils/NodeVirtualJarFile.scala +++ b/tools/js/src/test/scala/org/scalajs/core/tools/linker/testutils/NodeVirtualJarFile.scala @@ -66,3 +66,10 @@ object NodeVirtualJarFile { def asArrayBuffer(): ArrayBuffer } } + +class NodeVirtualJarScalaJSIRContainer(file: String) + extends NodeVirtualJarFile(file) with ScalaJSIRContainer { + + def sjsirFiles: List[VirtualRelativeScalaJSIRFile] = + ScalaJSIRContainer.sjsirFilesIn(this) +} diff --git a/tools/js/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala b/tools/js/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala index 5a7f19068c..3e76697364 100644 --- a/tools/js/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala +++ b/tools/js/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala @@ -4,5 +4,5 @@ import org.scalajs.core.tools.io._ object Platform { def loadJar(path: String): ScalaJSIRContainer = - new NodeVirtualJarFile(path) + new NodeVirtualJarScalaJSIRContainer(path) } diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala index 608604ae60..a0ccf4234e 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala @@ -183,13 +183,13 @@ object FileVirtualScalaJSIRFile extends (File => FileVirtualScalaJSIRFile) { object FileScalaJSIRContainer { def fromClasspath( classpath: Seq[File]): Seq[ScalaJSIRContainer with FileVirtualFile] = { - classpath flatMap { entry => + classpath.flatMap { entry => if (!entry.exists) Nil else if (entry.isDirectory) fromDirectory(entry) else if (entry.getName.endsWith(".jar")) - List(new FileVirtualBinaryFile(entry) with VirtualJarFile) + List(new FileVirtualJarScalaJSIRContainer(entry)) else throw new IllegalArgumentException("Illegal classpath entry " + entry) } @@ -215,3 +215,13 @@ object FileScalaJSIRContainer { } } } + +class FileVirtualJarFile(file: File) + extends FileVirtualBinaryFile(file) with VirtualJarFile + +class FileVirtualJarScalaJSIRContainer(file: File) + extends FileVirtualJarFile(file) with ScalaJSIRContainer { + + def sjsirFiles: List[VirtualRelativeScalaJSIRFile] = + ScalaJSIRContainer.sjsirFilesIn(this) +} diff --git a/tools/jvm/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala b/tools/jvm/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala index 67c1f6d95d..382faaa743 100644 --- a/tools/jvm/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala +++ b/tools/jvm/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala @@ -6,5 +6,5 @@ import org.scalajs.core.tools.io._ object Platform { def loadJar(path: String): ScalaJSIRContainer = - new FileVirtualBinaryFile(new File(path)) with VirtualJarFile + new FileVirtualJarScalaJSIRContainer(new File(path)) } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala index be70a19aca..c7bb13f99d 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala @@ -122,9 +122,6 @@ trait WritableVirtualJSFile extends WritableVirtualTextFile with VirtualJSFile { } /** A virtual file containing Scala.js IR. - * - * This can be a [[VirtualScalaJSIRFile]] (with [[RelativeVirtualFile]]) or a - * [[VirtualFileContainer]]. * * The main difference compared to using individual files * (that are extracted beforehand) is that the fileset can be versioned at a @@ -132,9 +129,29 @@ trait WritableVirtualJSFile extends WritableVirtualTextFile with VirtualJSFile { * files change. Therefore, the entire extraction process can be cached. */ trait ScalaJSIRContainer extends VirtualFile { + /** All the `*.sjsir` files in this container. + * + * It is up to the implementation whether these files are read lazily or not. + */ def sjsirFiles: List[VirtualRelativeScalaJSIRFile] } +object ScalaJSIRContainer { + def sjsirFilesIn( + container: VirtualFileContainer): List[VirtualRelativeScalaJSIRFile] = { + container.listEntries(_.endsWith(".sjsir")) { (relPath, stream) => + val file = new EntryIRFile(container.path, relPath) + file.content = IO.readInputStreamToByteArray(stream) + file.version = container.version + file + } + } + + private class EntryIRFile(outerPath: String, val relativePath: String) + extends MemVirtualSerializedScalaJSIRFile(s"$outerPath:$relativePath") + with VirtualRelativeScalaJSIRFile +} + /** A virtual Scala.js IR file. * It contains the class info and the IR tree. */ @@ -187,11 +204,9 @@ trait VirtualSerializedScalaJSIRFile /** A virtual file container. * * This is a generic virtual container for embedded virtual files, especially - * one found on a classpath such as a jar, and containing `.sjsir` files. + * one found on a classpath such as a jar. */ -trait VirtualFileContainer extends ScalaJSIRContainer { - import VirtualFileContainer._ - +trait VirtualFileContainer extends VirtualFile { /** Lists the entries of this container that satisfy a given predicate. * * @param p @@ -204,43 +219,6 @@ trait VirtualFileContainer extends ScalaJSIRContainer { */ def listEntries[T](p: String => Boolean)( makeResult: (String, InputStream) => T): List[T] - - /** All the `*.sjsir` files in this container. - * - * It is up to the implementation whether these files are read lazily or not. - * The default implementation reads them into memory. - * - * Depending on the implementation, calling `sjsirFiles` might be more - * efficient than using `listEntries` with a predicate - * `_.endsWith(".sjsir")`. - */ - def sjsirFiles: List[VirtualRelativeScalaJSIRFile] = { - listEntries(_.endsWith(".sjsir")) { (relPath, stream) => - val file = new EntryIRFile(path, relPath) - file.content = IO.readInputStreamToByteArray(stream) - file.version = version - file - } - } - - def jsFiles: List[VirtualJSFile with RelativeVirtualFile] = { - listEntries(_.endsWith(".js")) { (relPath, stream) => - val file = new EntryJSFile(path, relPath) - file.content = IO.readInputStreamToString(stream) - file.version = version - file - } - } -} - -private object VirtualFileContainer { - private class EntryIRFile(outerPath: String, val relativePath: String) - extends MemVirtualSerializedScalaJSIRFile(s"$outerPath:$relativePath") - with VirtualRelativeScalaJSIRFile - - private class EntryJSFile(outerPath: String, val relativePath: String) - extends MemVirtualJSFile(s"$outerPath:$relativePath") - with RelativeVirtualFile } /** A virtual jar file. */ From 38e8e0a9017355c9510034daaa6aeac3fb5d886d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 8 Jan 2018 16:12:43 +0100 Subject: [PATCH 0615/2665] Extract IR-related virtual files in separate files. This commit is just cut-and-paste. The intent is to be able to move the extracted files in separate artifacts. --- .../core/tools/io/NodeVirtualFiles.scala | 3 - .../core/tools/io/NodeVirtualIRFiles.scala | 12 +++ .../core/tools/io/FileVirtualFiles.scala | 63 ------------- .../core/tools/io/FileVirtualIRFiles.scala | 74 +++++++++++++++ .../org/scalajs/core/tools/io/MemFiles.scala | 4 - .../scalajs/core/tools/io/MemIRFiles.scala | 13 +++ .../scalajs/core/tools/io/VirtualFiles.scala | 82 ---------------- .../core/tools/io/VirtualIRFiles.scala | 93 +++++++++++++++++++ 8 files changed, 192 insertions(+), 152 deletions(-) create mode 100644 tools/js/src/main/scala/org/scalajs/core/tools/io/NodeVirtualIRFiles.scala create mode 100644 tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualIRFiles.scala create mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/io/MemIRFiles.scala create mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualIRFiles.scala diff --git a/tools/js/src/main/scala/org/scalajs/core/tools/io/NodeVirtualFiles.scala b/tools/js/src/main/scala/org/scalajs/core/tools/io/NodeVirtualFiles.scala index 1bcfb21d55..b5d3c02891 100644 --- a/tools/js/src/main/scala/org/scalajs/core/tools/io/NodeVirtualFiles.scala +++ b/tools/js/src/main/scala/org/scalajs/core/tools/io/NodeVirtualFiles.scala @@ -54,9 +54,6 @@ class NodeVirtualJSFile(p: String) extends NodeVirtualTextFile(p) override def sourceMap: Option[String] = None } -class NodeVirtualScalaJSIRFile(p: String) - extends NodeVirtualBinaryFile(p) with VirtualSerializedScalaJSIRFile - private[io] object NodeFS { val fs = js.Dynamic.global.require("fs") } diff --git a/tools/js/src/main/scala/org/scalajs/core/tools/io/NodeVirtualIRFiles.scala b/tools/js/src/main/scala/org/scalajs/core/tools/io/NodeVirtualIRFiles.scala new file mode 100644 index 0000000000..68ed62b677 --- /dev/null +++ b/tools/js/src/main/scala/org/scalajs/core/tools/io/NodeVirtualIRFiles.scala @@ -0,0 +1,12 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2018, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.core.tools.io + +class NodeVirtualScalaJSIRFile(p: String) + extends NodeVirtualBinaryFile(p) with VirtualSerializedScalaJSIRFile diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala index a0ccf4234e..e471504252 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala @@ -160,68 +160,5 @@ object WritableFileVirtualJSFile { new FileVirtualJSFile(f) with WritableFileVirtualJSFile } -class FileVirtualScalaJSIRFile(f: File) - extends FileVirtualBinaryFile(f) with VirtualSerializedScalaJSIRFile - -object FileVirtualScalaJSIRFile extends (File => FileVirtualScalaJSIRFile) { - import FileVirtualFile._ - - def apply(f: File): FileVirtualScalaJSIRFile = - new FileVirtualScalaJSIRFile(f) - - def relative(f: File, relPath: String): FileVirtualScalaJSIRFile - with VirtualRelativeScalaJSIRFile = { - new FileVirtualScalaJSIRFile(f) with VirtualRelativeScalaJSIRFile { - def relativePath: String = relPath - } - } - - def isScalaJSIRFile(file: File): Boolean = - hasExtension(file, ".sjsir") -} - -object FileScalaJSIRContainer { - def fromClasspath( - classpath: Seq[File]): Seq[ScalaJSIRContainer with FileVirtualFile] = { - classpath.flatMap { entry => - if (!entry.exists) - Nil - else if (entry.isDirectory) - fromDirectory(entry) - else if (entry.getName.endsWith(".jar")) - List(new FileVirtualJarScalaJSIRContainer(entry)) - else - throw new IllegalArgumentException("Illegal classpath entry " + entry) - } - } - - private def fromDirectory( - dir: File): Seq[ScalaJSIRContainer with FileVirtualFile] = { - require(dir.isDirectory) - - val baseDir = dir.getAbsoluteFile - - def walkForIR(dir: File): Seq[File] = { - val (subdirs, files) = dir.listFiles().partition(_.isDirectory) - subdirs.flatMap(walkForIR) ++ files.filter(_.getName.endsWith(".sjsir")) - } - - for (ir <- walkForIR(baseDir)) yield { - val relPath = ir.getPath - .stripPrefix(baseDir.getPath) - .replace(java.io.File.separatorChar, '/') - .stripPrefix("/") - FileVirtualScalaJSIRFile.relative(ir, relPath) - } - } -} - class FileVirtualJarFile(file: File) extends FileVirtualBinaryFile(file) with VirtualJarFile - -class FileVirtualJarScalaJSIRContainer(file: File) - extends FileVirtualJarFile(file) with ScalaJSIRContainer { - - def sjsirFiles: List[VirtualRelativeScalaJSIRFile] = - ScalaJSIRContainer.sjsirFilesIn(this) -} diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualIRFiles.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualIRFiles.scala new file mode 100644 index 0000000000..c5ca401a63 --- /dev/null +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualIRFiles.scala @@ -0,0 +1,74 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2018, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.core.tools.io + +import java.io._ + +class FileVirtualScalaJSIRFile(f: File) + extends FileVirtualBinaryFile(f) with VirtualSerializedScalaJSIRFile + +object FileVirtualScalaJSIRFile extends (File => FileVirtualScalaJSIRFile) { + import FileVirtualFile._ + + def apply(f: File): FileVirtualScalaJSIRFile = + new FileVirtualScalaJSIRFile(f) + + def relative(f: File, relPath: String): FileVirtualScalaJSIRFile + with VirtualRelativeScalaJSIRFile = { + new FileVirtualScalaJSIRFile(f) with VirtualRelativeScalaJSIRFile { + def relativePath: String = relPath + } + } + + def isScalaJSIRFile(file: File): Boolean = + hasExtension(file, ".sjsir") +} + +object FileScalaJSIRContainer { + def fromClasspath( + classpath: Seq[File]): Seq[ScalaJSIRContainer with FileVirtualFile] = { + classpath.flatMap { entry => + if (!entry.exists) + Nil + else if (entry.isDirectory) + fromDirectory(entry) + else if (entry.getName.endsWith(".jar")) + List(new FileVirtualJarScalaJSIRContainer(entry)) + else + throw new IllegalArgumentException("Illegal classpath entry " + entry) + } + } + + private def fromDirectory( + dir: File): Seq[ScalaJSIRContainer with FileVirtualFile] = { + require(dir.isDirectory) + + val baseDir = dir.getAbsoluteFile + + def walkForIR(dir: File): Seq[File] = { + val (subdirs, files) = dir.listFiles().partition(_.isDirectory) + subdirs.flatMap(walkForIR) ++ files.filter(_.getName.endsWith(".sjsir")) + } + + for (ir <- walkForIR(baseDir)) yield { + val relPath = ir.getPath + .stripPrefix(baseDir.getPath) + .replace(java.io.File.separatorChar, '/') + .stripPrefix("/") + FileVirtualScalaJSIRFile.relative(ir, relPath) + } + } +} + +class FileVirtualJarScalaJSIRContainer(file: File) + extends FileVirtualJarFile(file) with ScalaJSIRContainer { + + def sjsirFiles: List[VirtualRelativeScalaJSIRFile] = + ScalaJSIRContainer.sjsirFilesIn(this) +} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/MemFiles.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/MemFiles.scala index 3075058fd9..68cb3bddb8 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/MemFiles.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/MemFiles.scala @@ -99,7 +99,3 @@ object WritableMemVirtualJSFile { def apply(path: String): WritableMemVirtualJSFile = new MemVirtualJSFile(path) with WritableMemVirtualJSFile } - -/** A simple in-memory mutable virtual serialized Scala.js IR file. */ -class MemVirtualSerializedScalaJSIRFile(p: String) extends MemVirtualBinaryFile(p) - with VirtualSerializedScalaJSIRFile diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/MemIRFiles.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/MemIRFiles.scala new file mode 100644 index 0000000000..2aeb91b66b --- /dev/null +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/MemIRFiles.scala @@ -0,0 +1,13 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2018, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.core.tools.io + +/** A simple in-memory mutable virtual serialized Scala.js IR file. */ +class MemVirtualSerializedScalaJSIRFile(p: String) + extends MemVirtualBinaryFile(p) with VirtualSerializedScalaJSIRFile diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala index c7bb13f99d..77355d1c55 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala @@ -4,8 +4,6 @@ import java.io._ import java.net.URI import java.util.zip.{ZipInputStream, ZipEntry} -import org.scalajs.core.ir - /** A virtual input file. */ trait VirtualFile { @@ -121,86 +119,6 @@ trait WritableVirtualJSFile extends WritableVirtualTextFile with VirtualJSFile { def sourceMapWriter: Writer } -/** A virtual file containing Scala.js IR. - * - * The main difference compared to using individual files - * (that are extracted beforehand) is that the fileset can be versioned at a - * higher level: the container needs to change its version when any of the - * files change. Therefore, the entire extraction process can be cached. - */ -trait ScalaJSIRContainer extends VirtualFile { - /** All the `*.sjsir` files in this container. - * - * It is up to the implementation whether these files are read lazily or not. - */ - def sjsirFiles: List[VirtualRelativeScalaJSIRFile] -} - -object ScalaJSIRContainer { - def sjsirFilesIn( - container: VirtualFileContainer): List[VirtualRelativeScalaJSIRFile] = { - container.listEntries(_.endsWith(".sjsir")) { (relPath, stream) => - val file = new EntryIRFile(container.path, relPath) - file.content = IO.readInputStreamToByteArray(stream) - file.version = container.version - file - } - } - - private class EntryIRFile(outerPath: String, val relativePath: String) - extends MemVirtualSerializedScalaJSIRFile(s"$outerPath:$relativePath") - with VirtualRelativeScalaJSIRFile -} - -/** A virtual Scala.js IR file. - * It contains the class info and the IR tree. - */ -trait VirtualScalaJSIRFile extends VirtualFile { - /** Entry points information for this file. */ - def entryPointsInfo: ir.EntryPointsInfo = - ir.EntryPointsInfo.forClassDef(tree) - - /** IR Tree of this file. */ - def tree: ir.Trees.ClassDef -} - -trait VirtualRelativeScalaJSIRFile extends VirtualScalaJSIRFile - with RelativeVirtualFile with ScalaJSIRContainer { - def sjsirFiles: List[VirtualRelativeScalaJSIRFile] = this :: Nil -} - -/** Base trait for virtual Scala.js IR files that are serialized as binary file. - */ -trait VirtualSerializedScalaJSIRFile - extends VirtualBinaryFile with VirtualScalaJSIRFile { - - override def entryPointsInfo: ir.EntryPointsInfo = { - // Overridden to read only the necessary parts - withInputStream(ir.Serializers.deserializeEntryPointsInfo) - } - - override def tree: ir.Trees.ClassDef = - withInputStream(ir.Serializers.deserialize) - - @inline - private def withInputStream[A](f: InputStream => A): A = { - val stream = inputStream - try { - f(stream) - } catch { - case e: ir.IRVersionNotSupportedException => - throw new ir.IRVersionNotSupportedException(e.version, e.supported, - s"Failed to deserialize a file compiled with Scala.js ${e.version}" + - s" (supported: ${e.supported.mkString(", ")}): $path", e) - - case e: IOException => - throw new IOException(s"Failed to deserialize $path", e) - } finally { - stream.close() - } - } -} - /** A virtual file container. * * This is a generic virtual container for embedded virtual files, especially diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualIRFiles.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualIRFiles.scala new file mode 100644 index 0000000000..0eac36a3a6 --- /dev/null +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualIRFiles.scala @@ -0,0 +1,93 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2018, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.core.tools.io + +import java.io._ + +import org.scalajs.core.ir + +/** A virtual file containing Scala.js IR. + * + * The main difference compared to using individual files + * (that are extracted beforehand) is that the fileset can be versioned at a + * higher level: the container needs to change its version when any of the + * files change. Therefore, the entire extraction process can be cached. + */ +trait ScalaJSIRContainer extends VirtualFile { + /** All the `*.sjsir` files in this container. + * + * It is up to the implementation whether these files are read lazily or not. + */ + def sjsirFiles: List[VirtualRelativeScalaJSIRFile] +} + +object ScalaJSIRContainer { + def sjsirFilesIn( + container: VirtualFileContainer): List[VirtualRelativeScalaJSIRFile] = { + container.listEntries(_.endsWith(".sjsir")) { (relPath, stream) => + val file = new EntryIRFile(container.path, relPath) + file.content = IO.readInputStreamToByteArray(stream) + file.version = container.version + file + } + } + + private class EntryIRFile(outerPath: String, val relativePath: String) + extends MemVirtualSerializedScalaJSIRFile(s"$outerPath:$relativePath") + with VirtualRelativeScalaJSIRFile +} + +/** A virtual Scala.js IR file. + * It contains the class info and the IR tree. + */ +trait VirtualScalaJSIRFile extends VirtualFile { + /** Entry points information for this file. */ + def entryPointsInfo: ir.EntryPointsInfo = + ir.EntryPointsInfo.forClassDef(tree) + + /** IR Tree of this file. */ + def tree: ir.Trees.ClassDef +} + +trait VirtualRelativeScalaJSIRFile extends VirtualScalaJSIRFile + with RelativeVirtualFile with ScalaJSIRContainer { + def sjsirFiles: List[VirtualRelativeScalaJSIRFile] = this :: Nil +} + +/** Base trait for virtual Scala.js IR files that are serialized as binary file. + */ +trait VirtualSerializedScalaJSIRFile + extends VirtualBinaryFile with VirtualScalaJSIRFile { + + override def entryPointsInfo: ir.EntryPointsInfo = { + // Overridden to read only the necessary parts + withInputStream(ir.Serializers.deserializeEntryPointsInfo) + } + + override def tree: ir.Trees.ClassDef = + withInputStream(ir.Serializers.deserialize) + + @inline + private def withInputStream[A](f: InputStream => A): A = { + val stream = inputStream + try { + f(stream) + } catch { + case e: ir.IRVersionNotSupportedException => + throw new ir.IRVersionNotSupportedException(e.version, e.supported, + s"Failed to deserialize a file compiled with Scala.js ${e.version}" + + s" (supported: ${e.supported.mkString(", ")}): $path", e) + + case e: IOException => + throw new IOException(s"Failed to deserialize $path", e) + } finally { + stream.close() + } + } +} From 296477db650493fb965303498c002bef941a400e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 9 Jan 2018 13:36:18 +0100 Subject: [PATCH 0616/2665] Move IR-related virtual files to `linker.ioir.*`. In addition, make sure that all files in the `tools` belong to one of the three subpackages `io`, `logging` and `linker`. --- .../scala/scala/tools/nsc/MainGenericRunner.scala | 9 ++++++--- .../scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala | 2 ++ .../org/scalajs/sbtplugin/ScalaJSPluginInternal.scala | 2 ++ .../{io => linker/irio}/NodeVirtualIRFiles.scala | 4 +++- .../tools/{test/js => linker/test}/QuickLinker.scala | 11 +++++++---- .../tools/linker/testutils/NodeVirtualJarFile.scala | 2 ++ .../core/tools/linker/testutils/Platform.scala | 2 +- .../{io => linker/irio}/FileVirtualIRFiles.scala | 4 +++- .../core/tools/linker/testutils/Platform.scala | 2 +- .../scalajs/core/tools/linker/ClearableLinker.scala | 1 + .../org/scalajs/core/tools/linker/GenLinker.scala | 1 + .../scala/org/scalajs/core/tools/linker/Linker.scala | 1 + .../core/tools/linker/frontend/BaseLinker.scala | 3 ++- .../core/tools/linker/frontend/LinkerFrontend.scala | 2 +- .../core/tools/{io => linker/irio}/IRFileCache.scala | 4 +++- .../core/tools/{io => linker/irio}/MemIRFiles.scala | 4 +++- .../tools/{io => linker/irio}/VirtualIRFiles.scala | 4 +++- .../org/scalajs/core/tools/linker/LinkerTest.scala | 2 ++ .../core/tools/linker/testutils/TestIRRepo.scala | 4 +++- 19 files changed, 47 insertions(+), 17 deletions(-) rename tools/js/src/main/scala/org/scalajs/core/tools/{io => linker/irio}/NodeVirtualIRFiles.scala (89%) rename tools/js/src/test/scala/org/scalajs/core/tools/{test/js => linker/test}/QuickLinker.scala (97%) rename tools/jvm/src/main/scala/org/scalajs/core/tools/{io => linker/irio}/FileVirtualIRFiles.scala (96%) rename tools/shared/src/main/scala/org/scalajs/core/tools/{io => linker/irio}/IRFileCache.scala (99%) rename tools/shared/src/main/scala/org/scalajs/core/tools/{io => linker/irio}/MemIRFiles.scala (90%) rename tools/shared/src/main/scala/org/scalajs/core/tools/{io => linker/irio}/VirtualIRFiles.scala (97%) diff --git a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala index 9e9fa93dea..0310e3f4a4 100644 --- a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala +++ b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala @@ -2,11 +2,14 @@ package scala.tools.nsc /* Super hacky overriding of the MainGenericRunner used by partest */ -import org.scalajs.core.tools.logging._ +import org.scalajs.core.ir + import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.linker._ -import org.scalajs.core.ir +import org.scalajs.core.tools.logging._ + +import org.scalajs.core.tools.linker._ +import org.scalajs.core.tools.linker.irio._ import org.scalajs.jsenv.JSConsole import org.scalajs.jsenv.nodejs.NodeJSEnv diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 3eb9865c86..76882a505f 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -17,7 +17,9 @@ import sbt.Keys._ import org.scalajs.core.ir.ScalaJSVersions import org.scalajs.core.tools.io._ + import org.scalajs.core.tools.linker._ +import org.scalajs.core.tools.linker.irio._ import org.scalajs.jsenv.JSEnv diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index c82a8209a6..8a7490ae9d 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -13,7 +13,9 @@ import sbt.complete.DefaultParsers._ import org.portablescala.sbtplatformdeps.PlatformDepsPlugin.autoImport._ import org.scalajs.core.tools.io.{IO => _, _} + import org.scalajs.core.tools.linker._ +import org.scalajs.core.tools.linker.irio._ import org.scalajs.core.tools.linker.standard._ import org.scalajs.jsenv._ diff --git a/tools/js/src/main/scala/org/scalajs/core/tools/io/NodeVirtualIRFiles.scala b/tools/js/src/main/scala/org/scalajs/core/tools/linker/irio/NodeVirtualIRFiles.scala similarity index 89% rename from tools/js/src/main/scala/org/scalajs/core/tools/io/NodeVirtualIRFiles.scala rename to tools/js/src/main/scala/org/scalajs/core/tools/linker/irio/NodeVirtualIRFiles.scala index 68ed62b677..ad7ed0102c 100644 --- a/tools/js/src/main/scala/org/scalajs/core/tools/io/NodeVirtualIRFiles.scala +++ b/tools/js/src/main/scala/org/scalajs/core/tools/linker/irio/NodeVirtualIRFiles.scala @@ -6,7 +6,9 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.io +package org.scalajs.core.tools.linker.irio + +import org.scalajs.core.tools.io._ class NodeVirtualScalaJSIRFile(p: String) extends NodeVirtualBinaryFile(p) with VirtualSerializedScalaJSIRFile diff --git a/tools/js/src/test/scala/org/scalajs/core/tools/test/js/QuickLinker.scala b/tools/js/src/test/scala/org/scalajs/core/tools/linker/test/QuickLinker.scala similarity index 97% rename from tools/js/src/test/scala/org/scalajs/core/tools/test/js/QuickLinker.scala rename to tools/js/src/test/scala/org/scalajs/core/tools/linker/test/QuickLinker.scala index 87ef468e1f..81cb6784f5 100644 --- a/tools/js/src/test/scala/org/scalajs/core/tools/test/js/QuickLinker.scala +++ b/tools/js/src/test/scala/org/scalajs/core/tools/linker/test/QuickLinker.scala @@ -1,11 +1,14 @@ -package org.scalajs.core.tools.test.js +package org.scalajs.core.tools.linker.test + +import scala.scalajs.js +import scala.scalajs.js.annotation._ import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.linker._ + import org.scalajs.core.tools.logging._ -import scala.scalajs.js -import scala.scalajs.js.annotation._ +import org.scalajs.core.tools.linker._ +import org.scalajs.core.tools.linker.irio._ import org.scalajs.core.tools.linker.testutils.Platform diff --git a/tools/js/src/test/scala/org/scalajs/core/tools/linker/testutils/NodeVirtualJarFile.scala b/tools/js/src/test/scala/org/scalajs/core/tools/linker/testutils/NodeVirtualJarFile.scala index f4b8ceb731..a73ee59bd0 100644 --- a/tools/js/src/test/scala/org/scalajs/core/tools/linker/testutils/NodeVirtualJarFile.scala +++ b/tools/js/src/test/scala/org/scalajs/core/tools/linker/testutils/NodeVirtualJarFile.scala @@ -8,6 +8,8 @@ import scala.scalajs.js.typedarray._ import org.scalajs.core.tools.io._ +import org.scalajs.core.tools.linker.irio._ + class NodeVirtualJarFile(file: String) extends NodeVirtualBinaryFile(file) with VirtualFileContainer { diff --git a/tools/js/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala b/tools/js/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala index 3e76697364..90832d919e 100644 --- a/tools/js/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala +++ b/tools/js/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala @@ -1,6 +1,6 @@ package org.scalajs.core.tools.linker.testutils -import org.scalajs.core.tools.io._ +import org.scalajs.core.tools.linker.irio._ object Platform { def loadJar(path: String): ScalaJSIRContainer = diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualIRFiles.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/irio/FileVirtualIRFiles.scala similarity index 96% rename from tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualIRFiles.scala rename to tools/jvm/src/main/scala/org/scalajs/core/tools/linker/irio/FileVirtualIRFiles.scala index c5ca401a63..c94231f548 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualIRFiles.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/irio/FileVirtualIRFiles.scala @@ -6,10 +6,12 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.io +package org.scalajs.core.tools.linker.irio import java.io._ +import org.scalajs.core.tools.io._ + class FileVirtualScalaJSIRFile(f: File) extends FileVirtualBinaryFile(f) with VirtualSerializedScalaJSIRFile diff --git a/tools/jvm/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala b/tools/jvm/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala index 382faaa743..7b6f8d47a2 100644 --- a/tools/jvm/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala +++ b/tools/jvm/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala @@ -2,7 +2,7 @@ package org.scalajs.core.tools.linker.testutils import java.io.File -import org.scalajs.core.tools.io._ +import org.scalajs.core.tools.linker.irio._ object Platform { def loadJar(path: String): ScalaJSIRContainer = diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ClearableLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ClearableLinker.scala index 695c50f711..4858fcf35a 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ClearableLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ClearableLinker.scala @@ -13,6 +13,7 @@ import org.scalajs.core.tools.logging.Logger import org.scalajs.core.tools.io._ import org.scalajs.core.tools.linker.analyzer.SymbolRequirement +import org.scalajs.core.tools.linker.irio._ /** A box around a [[GenLinker]] to support clearing. * diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala index 19822d5bbf..5e7b0d764f 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala @@ -13,6 +13,7 @@ import org.scalajs.core.tools.logging.Logger import org.scalajs.core.tools.io._ import org.scalajs.core.tools.linker.analyzer.SymbolRequirement +import org.scalajs.core.tools.linker.irio._ /** Common supertrait of [[Linker]] and [[ClearableLinker]]. * diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala index e1cccb5046..08fdee8a85 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala @@ -21,6 +21,7 @@ import org.scalajs.core.tools.linker.analyzer.SymbolRequirement import org.scalajs.core.tools.linker.frontend.LinkerFrontend import org.scalajs.core.tools.linker.frontend.optimizer.IncOptimizer import org.scalajs.core.tools.linker.backend.{LinkerBackend, BasicLinkerBackend} +import org.scalajs.core.tools.linker.irio._ /** The Scala.js linker */ final class Linker private (frontend: LinkerFrontend, backend: LinkerBackend) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index adddb8038f..ca1b4e08e2 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -21,6 +21,7 @@ import org.scalajs.core.tools.linker._ import org.scalajs.core.tools.linker.standard._ import org.scalajs.core.tools.linker.checker._ import org.scalajs.core.tools.linker.analyzer._ +import org.scalajs.core.tools.linker.irio._ import org.scalajs.core.ir import ir.Trees._ @@ -32,7 +33,7 @@ import ir.Definitions import Analysis._ -/** Links the information from [[io.VirtualScalaJSIRFile]]s into +/** Links the information from [[irio.VirtualScalaJSIRFile]]s into * [[LinkedClass]]es. Does a dead code elimination pass. */ final class BaseLinker(config: CommonPhaseConfig) { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala index 06fbeab9f8..ec7fbbafb4 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala @@ -10,12 +10,12 @@ package org.scalajs.core.tools.linker.frontend import org.scalajs.core.tools.logging.Logger -import org.scalajs.core.tools.io.VirtualScalaJSIRFile import org.scalajs.core.tools.linker._ import org.scalajs.core.tools.linker.standard._ import org.scalajs.core.tools.linker.analyzer.SymbolRequirement import org.scalajs.core.tools.linker.frontend.optimizer.{GenIncOptimizer, IncOptimizer} +import org.scalajs.core.tools.linker.irio._ /** The frontend of the Scala.js linker. Produces a [[LinkingUnit]] * diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/irio/IRFileCache.scala similarity index 99% rename from tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala rename to tools/shared/src/main/scala/org/scalajs/core/tools/linker/irio/IRFileCache.scala index 51c72f7b9b..e6499ba0a1 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/irio/IRFileCache.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.io +package org.scalajs.core.tools.linker.irio import scala.annotation.tailrec @@ -19,6 +19,8 @@ import java.util.concurrent.atomic.AtomicInteger import org.scalajs.core.ir.EntryPointsInfo import org.scalajs.core.ir.Trees.ClassDef +import org.scalajs.core.tools.io._ + /** Centralized Scala.js IR cache. * * Caches all Scala.js IR used in a given JVM. It supports creating of multiple diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/MemIRFiles.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/irio/MemIRFiles.scala similarity index 90% rename from tools/shared/src/main/scala/org/scalajs/core/tools/io/MemIRFiles.scala rename to tools/shared/src/main/scala/org/scalajs/core/tools/linker/irio/MemIRFiles.scala index 2aeb91b66b..74a9678df2 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/MemIRFiles.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/irio/MemIRFiles.scala @@ -6,7 +6,9 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.io +package org.scalajs.core.tools.linker.irio + +import org.scalajs.core.tools.io._ /** A simple in-memory mutable virtual serialized Scala.js IR file. */ class MemVirtualSerializedScalaJSIRFile(p: String) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualIRFiles.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/irio/VirtualIRFiles.scala similarity index 97% rename from tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualIRFiles.scala rename to tools/shared/src/main/scala/org/scalajs/core/tools/linker/irio/VirtualIRFiles.scala index 0eac36a3a6..b34db49041 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualIRFiles.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/irio/VirtualIRFiles.scala @@ -6,12 +6,14 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.io +package org.scalajs.core.tools.linker.irio import java.io._ import org.scalajs.core.ir +import org.scalajs.core.tools.io._ + /** A virtual file containing Scala.js IR. * * The main difference compared to using individual files diff --git a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala index 72433d6686..dc7fb56e4c 100644 --- a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala +++ b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala @@ -9,7 +9,9 @@ import org.scalajs.core.ir.Trees._ import org.scalajs.core.tools.logging._ import org.scalajs.core.tools.io._ + import org.scalajs.core.tools.linker._ +import org.scalajs.core.tools.linker.irio._ import org.scalajs.core.tools.linker.testutils._ import org.scalajs.core.tools.linker.testutils.TestIRBuilder._ diff --git a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/testutils/TestIRRepo.scala b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/testutils/TestIRRepo.scala index 220b8636d3..137e0e9cab 100644 --- a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/testutils/TestIRRepo.scala +++ b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/testutils/TestIRRepo.scala @@ -2,9 +2,11 @@ package org.scalajs.core.tools.linker.testutils import scala.collection.mutable -import org.scalajs.core.tools.linker.analyzer.Infos._ import org.scalajs.core.tools.io._ +import org.scalajs.core.tools.linker.analyzer.Infos._ +import org.scalajs.core.tools.linker.irio._ + object TestIRRepo { private val stdlibPath = System.getProperty("org.scalajs.core.tools.linker.stdlibjar") From 41db324f3c868a74453a04b8cc30e088dd566b37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 9 Jan 2018 14:42:59 +0100 Subject: [PATCH 0617/2665] Move `ir.Utils.escapeJS` to `io.JSUtils`. This makes `js-envs/` independent of `ir.*`. However, we have to keep a `private[ir]` duplicate of `printEscapeJS` in `ir.Utils`, because it is used by `ir.Printers`. --- .../scala/org/scalajs/core/ir/Utils.scala | 27 +----- .../jsenv/nodejs/AbstractNodeJSEnv.scala | 3 +- project/Build.scala | 2 +- .../sbtplugin/ScalaJSPluginInternal.scala | 2 +- .../testadapter/HTMLRunnerBuilder.scala | 3 +- .../org/scalajs/testadapter/TestAdapter.scala | 3 +- .../org/scalajs/core/tools/io/JSUtils.scala | 91 +++++++++++++++++++ .../linker/backend/javascript/Printers.scala | 6 +- .../backend/javascript/SourceMapWriter.scala | 4 +- 9 files changed, 111 insertions(+), 30 deletions(-) create mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/io/JSUtils.scala diff --git a/ir/src/main/scala/org/scalajs/core/ir/Utils.scala b/ir/src/main/scala/org/scalajs/core/ir/Utils.scala index d6083139cd..dd3bd23154 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Utils.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Utils.scala @@ -16,8 +16,6 @@ import scala.annotation.switch object Utils { - private final val EscapeJSChars = "\\b\\t\\n\\v\\f\\r\\\"\\\\" - /** Relativize target URI w.r.t. base URI */ def relativize(base0: URI, trgt0: URI): URI = { val base = base0.normalize @@ -54,28 +52,11 @@ object Utils { if (uri.getScheme() != "file" || uri.getAuthority() != null) uri else new URI("file", "", uri.getPath(), uri.getQuery(), uri.getFragment()) - def escapeJS(str: String): String = { - // scalastyle:off return - val end = str.length - var i = 0 - while (i != end) { - val c = str.charAt(i) - if (c >= 32 && c <= 126 && c != '\\' && c != '"') - i += 1 - else - return createEscapeJSString(str) - } - str - // scalastyle:on return - } + // !!! BEGIN COPY-PASTED CODE with tools/.../JSUtils.scala - private def createEscapeJSString(str: String): String = { - val sb = new java.lang.StringBuilder(2 * str.length) - printEscapeJS(str, sb) - sb.toString - } + private final val EscapeJSChars = "\\b\\t\\n\\v\\f\\r\\\"\\\\" - def printEscapeJS(str: String, out: java.lang.Appendable): Int = { + private[ir] def printEscapeJS(str: String, out: java.lang.Appendable): Int = { /* Note that Java and JavaScript happen to use the same encoding for * Unicode, namely UTF-16, which means that 1 char from Java always equals * 1 char in JavaScript. */ @@ -126,6 +107,8 @@ object Utils { writtenChars } + // !!! END COPY-PASTED CODE with tools/.../JSUtils.scala + /** A ByteArrayOutput stream that allows to jump back to a given * position and complete some bytes. Methods must be called in the * following order only: diff --git a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala index d12abe867a..3961c1d980 100644 --- a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala +++ b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala @@ -12,9 +12,10 @@ package org.scalajs.jsenv.nodejs import java.io.{Console => _, _} import java.net._ -import org.scalajs.core.ir.Utils.escapeJS import org.scalajs.core.tools.io._ +import org.scalajs.core.tools.io.JSUtils.escapeJS import org.scalajs.core.tools.logging.NullLogger + import org.scalajs.jsenv._ import org.scalajs.jsenv.Utils.OptDeadline diff --git a/project/Build.scala b/project/Build.scala index 6d3b24c28e..f505e153b9 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -18,7 +18,6 @@ import scala.collection.mutable import scala.util.Properties import org.scalajs.core.ir -import org.scalajs.core.ir.Utils.escapeJS import org.scalajs.sbtplugin._ import org.scalajs.jsenv.{ConsoleJSConsole, JSEnv} @@ -29,6 +28,7 @@ import ExternalCompile.scalaJSExternalCompileSettings import Loggers._ import org.scalajs.core.tools.io.{FileVirtualJSFile, MemVirtualJSFile} +import org.scalajs.core.tools.io.JSUtils.escapeJS import org.scalajs.core.tools.linker._ /* Things that we want to expose in the sbt command line (and hence also in diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 8a7490ae9d..c245ddb783 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -13,6 +13,7 @@ import sbt.complete.DefaultParsers._ import org.portablescala.sbtplatformdeps.PlatformDepsPlugin.autoImport._ import org.scalajs.core.tools.io.{IO => _, _} +import org.scalajs.core.tools.io.JSUtils.escapeJS import org.scalajs.core.tools.linker._ import org.scalajs.core.tools.linker.irio._ @@ -21,7 +22,6 @@ import org.scalajs.core.tools.linker.standard._ import org.scalajs.jsenv._ import org.scalajs.jsenv.nodejs.NodeJSEnv -import org.scalajs.core.ir.Utils.escapeJS import org.scalajs.core.ir.Printers.IRTreePrinter import org.scalajs.testadapter.{TestAdapter, HTMLRunnerBuilder} diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala index cc31d78ec6..25bd48cdf9 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala @@ -16,6 +16,7 @@ import sbt.testing.{Framework, TaskDef} import org.scalajs.core.ir.Utils import org.scalajs.core.tools.io._ +import org.scalajs.core.tools.io.JSUtils.escapeJS import org.scalajs.jsenv.VirtualFileMaterializer @@ -89,7 +90,7 @@ object HTMLRunnerBuilder { taskDefs: List[TaskDef]): String = { def mkVar[T: Serializer](name: String, value: T) = - s"""var $name = "${Utils.escapeJS(Serializer.serialize(value))}";\n""" + s"""var $name = "${escapeJS(Serializer.serialize(value))}";\n""" mkVar("definedTests", taskDefs) + mkVar("testFrameworkNames", frameworkImplClassNames) diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapter.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapter.scala index 87465b3e7d..47ca10a107 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapter.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapter.scala @@ -13,12 +13,13 @@ import scala.concurrent._ import scala.concurrent.duration._ import scala.collection.concurrent.TrieMap -import org.scalajs.core.ir.Utils.escapeJS import org.scalajs.core.tools.io._ +import org.scalajs.core.tools.io.JSUtils.escapeJS import org.scalajs.core.tools.logging._ import org.scalajs.core.tools.linker.ModuleKind import org.scalajs.jsenv._ + import org.scalajs.testcommon._ import sbt.testing.Framework diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/JSUtils.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/JSUtils.scala new file mode 100644 index 0000000000..38ad78935d --- /dev/null +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/JSUtils.scala @@ -0,0 +1,91 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2018, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.core.tools.io + +object JSUtils { + + def escapeJS(str: String): String = { + // scalastyle:off return + val end = str.length + var i = 0 + while (i != end) { + val c = str.charAt(i) + if (c >= 32 && c <= 126 && c != '\\' && c != '"') + i += 1 + else + return createEscapeJSString(str) + } + str + // scalastyle:on return + } + + private def createEscapeJSString(str: String): String = { + val sb = new java.lang.StringBuilder(2 * str.length) + printEscapeJS(str, sb) + sb.toString + } + + // !!! BEGIN COPY-PASTED CODE with ir/.../Utils.scala + + private final val EscapeJSChars = "\\b\\t\\n\\v\\f\\r\\\"\\\\" + + def printEscapeJS(str: String, out: java.lang.Appendable): Int = { + /* Note that Java and JavaScript happen to use the same encoding for + * Unicode, namely UTF-16, which means that 1 char from Java always equals + * 1 char in JavaScript. */ + val end = str.length() + var i = 0 + var writtenChars = 0 + /* Loop prints all consecutive ASCII printable characters starting + * from current i and one non ASCII printable character (if it exists). + * The new i is set at the end of the appended characters. + */ + while (i != end) { + val start = i + var c: Int = str.charAt(i) + // Find all consecutive ASCII printable characters from `start` + while (i != end && c >= 32 && c <= 126 && c != 34 && c != 92) { + i += 1 + if (i != end) + c = str.charAt(i) + } + // Print ASCII printable characters from `start` + if (start != i) { + out.append(str, start, i) + writtenChars += i + } + + // Print next non ASCII printable character + if (i != end) { + def escapeJSEncoded(c: Int): Unit = { + if (7 < c && c < 14) { + val i = 2 * (c - 8) + out.append(EscapeJSChars, i, i + 2) + writtenChars += 2 + } else if (c == 34) { + out.append(EscapeJSChars, 12, 14) + writtenChars += 2 + } else if (c == 92) { + out.append(EscapeJSChars, 14, 16) + writtenChars += 2 + } else { + out.append(f"\\u$c%04x") + writtenChars += 6 + } + } + escapeJSEncoded(c) + i += 1 + } + } + writtenChars + } + + // !!! END COPY-PASTED CODE with ir/.../Utils.scala + +} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Printers.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Printers.scala index e2d31ddfee..22b8746216 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Printers.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Printers.scala @@ -23,6 +23,8 @@ import ir.Position import ir.Position.NoPosition import ir.Printers.IndentationManager +import org.scalajs.core.tools.io.JSUtils + import Trees._ /* Printers code was hand-optimized with raw performance in mind. @@ -576,7 +578,7 @@ object Printers { } protected def printEscapeJS(s: String): Unit = - ir.Utils.printEscapeJS(s, out) + JSUtils.printEscapeJS(s, out) protected def print(ident: Ident): Unit = printEscapeJS(ident.name) @@ -620,7 +622,7 @@ object Printers { } override protected def printEscapeJS(s: String): Unit = - column += ir.Utils.printEscapeJS(s, out) + column += JSUtils.printEscapeJS(s, out) override protected def print(ident: Ident): Unit = { if (ident.pos.isDefined) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/SourceMapWriter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/SourceMapWriter.scala index 3ecdb4549a..757f7ed8c6 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/SourceMapWriter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/SourceMapWriter.scala @@ -20,6 +20,8 @@ import ir.Position import ir.Position._ import ir.Utils +import org.scalajs.core.tools.io.JSUtils + private object SourceMapWriter { private val Base64Map = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + @@ -35,7 +37,7 @@ private object SourceMapWriter { private def printJSONString(s: String, out: Writer) = { out.write('\"') - Utils.printEscapeJS(s, out) + JSUtils.printEscapeJS(s, out) out.write('\"') } From 9b6f464b8a0ccdb306458e36569c09c1b14ca92d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 9 Jan 2018 15:06:27 +0100 Subject: [PATCH 0618/2665] Move `ir.Utils.{relativize,fixFileURI}` to `io.URIUtils`. There was no need for those functions to be in the `ir` module. Besides, this removes the dependency of the `test-adapter` on the `ir` package. --- .../scala/org/scalajs/core/ir/Utils.scala | 39 +------------- .../testadapter/HTMLRunnerBuilder.scala | 3 +- .../closure/ClosureAstTransformer.scala | 6 ++- .../org/scalajs/core/tools/io/URIUtils.scala | 51 +++++++++++++++++++ .../backend/javascript/SourceMapWriter.scala | 7 +-- .../scalajs/core/tools/io/URIUtilsTest.scala | 6 +-- 6 files changed, 64 insertions(+), 48 deletions(-) create mode 100644 tools/shared/src/main/scala/org/scalajs/core/tools/io/URIUtils.scala rename ir/src/test/scala/org/scalajs/core/ir/UtilsTest.scala => tools/shared/src/test/scala/org/scalajs/core/tools/io/URIUtilsTest.scala (90%) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Utils.scala b/ir/src/main/scala/org/scalajs/core/ir/Utils.scala index dd3bd23154..f4bdcae342 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Utils.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Utils.scala @@ -10,47 +10,10 @@ package org.scalajs.core.ir import java.io.StringWriter -import java.net.URI import scala.annotation.switch -object Utils { - - /** Relativize target URI w.r.t. base URI */ - def relativize(base0: URI, trgt0: URI): URI = { - val base = base0.normalize - val trgt = trgt0.normalize - - if (base.isOpaque || !base.isAbsolute || base.getRawPath == null || - trgt.isOpaque || !trgt.isAbsolute || trgt.getRawPath == null || - base.getScheme != trgt.getScheme || - base.getRawAuthority != trgt.getRawAuthority) - trgt - else { - val trgtCmps = trgt.getRawPath.split("/", -1) - - // Disregard the last element, since it is the filename - // (or empty string for a directory). - val baseCmps = base.getRawPath.split("/", -1).init - - val prefixLen = (trgtCmps zip baseCmps).takeWhile(t => t._1 == t._2).size - - val newPathCmps = - List.fill(baseCmps.size - prefixLen)("..") ++ trgtCmps.drop(prefixLen) - - val newPath = newPathCmps.mkString("/") - - // Relative URI does not have scheme or authority - new URI(null, null, newPath, trgt.getRawQuery, trgt.getRawFragment) - } - } - - /** Adds an empty authority to URIs with the "file" scheme without authority. - * Some browsers don't fetch URIs without authority correctly. - */ - def fixFileURI(uri: URI): URI = - if (uri.getScheme() != "file" || uri.getAuthority() != null) uri - else new URI("file", "", uri.getPath(), uri.getQuery(), uri.getFragment()) +private[ir] object Utils { // !!! BEGIN COPY-PASTED CODE with tools/.../JSUtils.scala diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala index 25bd48cdf9..1c1bd0c24e 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala @@ -14,7 +14,6 @@ import java.net.URI import sbt.testing.{Framework, TaskDef} -import org.scalajs.core.ir.Utils import org.scalajs.core.tools.io._ import org.scalajs.core.tools.io.JSUtils.escapeJS @@ -62,7 +61,7 @@ object HTMLRunnerBuilder { css: URI, frameworkImplClassNames: List[List[String]], taskDefs: List[TaskDef]): String = { def relURI(uri: URI) = - htmlEscaped(Utils.relativize(baseURI, uri).toASCIIString) + htmlEscaped(URIUtils.relativize(baseURI, uri).toASCIIString) s""" diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala index 426a8d543d..cfc6f674c0 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala @@ -343,8 +343,10 @@ private[closure] class ClosureAstTransformer(relativizeBaseURI: Option[URI]) { } private def sourceUriToString(uri: URI): String = { - val relURI = relativizeBaseURI.fold(uri)(ir.Utils.relativize(_, uri)) - ir.Utils.fixFileURI(relURI).toASCIIString + import org.scalajs.core.tools.io.URIUtils._ + + val relURI = relativizeBaseURI.fold(uri)(relativize(_, uri)) + fixFileURI(relURI).toASCIIString } // Helpers for IR diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/URIUtils.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/URIUtils.scala new file mode 100644 index 0000000000..58529dd937 --- /dev/null +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/URIUtils.scala @@ -0,0 +1,51 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js tools ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2018, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.core.tools.io + +import java.net.URI + +object URIUtils { + + /** Relativize target URI w.r.t. base URI */ + def relativize(base0: URI, trgt0: URI): URI = { + val base = base0.normalize + val trgt = trgt0.normalize + + if (base.isOpaque || !base.isAbsolute || base.getRawPath == null || + trgt.isOpaque || !trgt.isAbsolute || trgt.getRawPath == null || + base.getScheme != trgt.getScheme || + base.getRawAuthority != trgt.getRawAuthority) { + trgt + } else { + val trgtCmps = trgt.getRawPath.split("/", -1) + + // Disregard the last element, since it is the filename + // (or empty string for a directory). + val baseCmps = base.getRawPath.split("/", -1).init + + val prefixLen = (trgtCmps zip baseCmps).takeWhile(t => t._1 == t._2).size + + val newPathCmps = + List.fill(baseCmps.size - prefixLen)("..") ++ trgtCmps.drop(prefixLen) + + val newPath = newPathCmps.mkString("/") + + // Relative URI does not have scheme or authority + new URI(null, null, newPath, trgt.getRawQuery, trgt.getRawFragment) + } + } + + /** Adds an empty authority to URIs with the "file" scheme without authority. + * Some browsers don't fetch URIs without authority correctly. + */ + def fixFileURI(uri: URI): URI = + if (uri.getScheme() != "file" || uri.getAuthority() != null) uri + else new URI("file", "", uri.getPath(), uri.getQuery(), uri.getFragment()) + +} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/SourceMapWriter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/SourceMapWriter.scala index 757f7ed8c6..39c8d16536 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/SourceMapWriter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/SourceMapWriter.scala @@ -118,10 +118,11 @@ class SourceMapWriter( /** Relatively hacky way to get a Web-friendly URI to the source file */ private def sourceToURI(source: SourceFile): String = { - val uri = source - val relURI = relativizeBaseURI.fold(uri)(Utils.relativize(_, uri)) + import org.scalajs.core.tools.io.URIUtils._ - Utils.fixFileURI(relURI).toASCIIString + val uri = source + val relURI = relativizeBaseURI.fold(uri)(relativize(_, uri)) + fixFileURI(relURI).toASCIIString } private def nameToIndex(name: String): Int = { diff --git a/ir/src/test/scala/org/scalajs/core/ir/UtilsTest.scala b/tools/shared/src/test/scala/org/scalajs/core/tools/io/URIUtilsTest.scala similarity index 90% rename from ir/src/test/scala/org/scalajs/core/ir/UtilsTest.scala rename to tools/shared/src/test/scala/org/scalajs/core/tools/io/URIUtilsTest.scala index 2f0bf59888..efdb4204ff 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/UtilsTest.scala +++ b/tools/shared/src/test/scala/org/scalajs/core/tools/io/URIUtilsTest.scala @@ -1,17 +1,17 @@ -package org.scalajs.core.ir +package org.scalajs.core.tools.io import java.net.URI import org.junit.Test import org.junit.Assert._ -class UtilsTest { +class URIUtilsTest { @Test def relativizeURI(): Unit = { def test(base: String, trgt: String, rel: String) = { val baseURI = new URI(base) val trgtURI = new URI(trgt) - val relURI = Utils.relativize(baseURI, trgtURI) + val relURI = URIUtils.relativize(baseURI, trgtURI) assertEquals(rel, relURI.toString) assertEquals(trgtURI, baseURI.resolve(relURI)) } From a3a7b0cf5db2f77b14cfd27950c796d96a03e8de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 9 Jan 2018 18:26:53 +0100 Subject: [PATCH 0619/2665] Remove the dependency of `TestAdapter` on `ModuleKind`. It used `ModuleKind`, combined with a `moduleIdentifier: String`, to know where to load the exports namespace of Scala.js from. Instead, it now uses a dedicated ADT `ModuleIdentifier`. This removes the dependency of the test adapter on the linker. --- .../sbtplugin/ScalaJSPluginInternal.scala | 12 ++-- .../org/scalajs/testadapter/TestAdapter.scala | 60 +++++++++++-------- 2 files changed, 43 insertions(+), 29 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index c245ddb783..d6b045c938 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -25,6 +25,7 @@ import org.scalajs.jsenv.nodejs.NodeJSEnv import org.scalajs.core.ir.Printers.IRTreePrinter import org.scalajs.testadapter.{TestAdapter, HTMLRunnerBuilder} +import org.scalajs.testadapter.TestAdapter.ModuleIdentifier import Loggers._ import SBTCompat._ @@ -375,10 +376,11 @@ private[sbtplugin] object ScalaJSPluginInternal { val files = jsExecutionFiles.value - val moduleKind = scalaJSLinkerConfig.value.moduleKind - val moduleIdentifier = moduleKind match { - case ModuleKind.NoModule => None - case ModuleKind.CommonJSModule => Some(scalaJSLinkedFile.value.data.getPath) + val moduleIdentifier = scalaJSLinkerConfig.value.moduleKind match { + case ModuleKind.NoModule => + ModuleIdentifier.NoModule + case ModuleKind.CommonJSModule => + ModuleIdentifier.CommonJSModule(scalaJSLinkedFile.value.data.getPath) } val frameworkNames = frameworks.map(_.implClassNames.toList).toList @@ -386,7 +388,7 @@ private[sbtplugin] object ScalaJSPluginInternal { val logger = sbtLogger2ToolsLogger(streams.value.log) val config = TestAdapter.Config() .withLogger(logger) - .withModuleSettings(moduleKind, moduleIdentifier) + .withModuleIdentifier(moduleIdentifier) val adapter = newTestAdapter(env, files, config) val frameworkAdapters = adapter.loadFrameworks(frameworkNames) diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapter.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapter.scala index 47ca10a107..bad8e33141 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapter.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapter.scala @@ -16,7 +16,6 @@ import scala.collection.concurrent.TrieMap import org.scalajs.core.tools.io._ import org.scalajs.core.tools.io.JSUtils.escapeJS import org.scalajs.core.tools.logging._ -import org.scalajs.core.tools.linker.ModuleKind import org.scalajs.jsenv._ @@ -27,7 +26,7 @@ import sbt.testing.Framework final class TestAdapter(jsEnv: ComJSEnv, jsFiles: Seq[VirtualJSFile], config: TestAdapter.Config) { - import TestAdapter.ManagedRunner + import TestAdapter._ /** Map of ThreadId -> ManagedRunner */ private[this] val runners = TrieMap.empty[Long, ManagedRunner] @@ -132,17 +131,12 @@ final class TestAdapter(jsEnv: ComJSEnv, jsFiles: Seq[VirtualJSFile], // Otherwise we might leak runners. require(!closed, "We are closed. Cannot create new runner.") - // !!! DUPLICATE code with ScalaJSPlugin.makeExportsNamespaceExpr - val orgExpr = config.moduleKind match { - case ModuleKind.NoModule => + val orgExpr = config.moduleIdentifier match { + case ModuleIdentifier.NoModule => "typeof(org) != 'undefined' ? org : {}" - case ModuleKind.CommonJSModule => - val moduleIdent = config.moduleIdentifier.getOrElse { - throw new IllegalArgumentException( - "The module identifier must be specified for CommonJS modules") - } - s"""require("${escapeJS(moduleIdent)}").org || {}""" + case ModuleIdentifier.CommonJSModule(moduleName) => + s"""require("${escapeJS(moduleName)}").org || {}""" } /* #2752: if there is no testing framework at all on the classpath, @@ -176,18 +170,41 @@ final class TestAdapter(jsEnv: ComJSEnv, jsFiles: Seq[VirtualJSFile], } object TestAdapter { + /** An identifier for the Scala.js module, which specifies where its exports + * can be loaded from. + * + * @note + * Although this class looks like an ADT and is not extensible from the + * outside, it is not `sealed`. Future versions may have more subclasses, + * which means that `match`es covering all existing cases may fail with + * `MatchError` in the future. + */ + abstract class ModuleIdentifier private () + + object ModuleIdentifier { + /** The Scala.js code is not a module; its exports are in the global scope. + */ + case object NoModule extends ModuleIdentifier + + /** The Scala.js module is a CommonJS module. + * + * @param moduleName + * The module name such that `require(moduleName)` returns the exports + * of the Scala.js module. + */ + final case class CommonJSModule(moduleName: String) extends ModuleIdentifier + } + final class Config private ( val logger: Logger, val console: JSConsole, - val moduleKind: ModuleKind, - val moduleIdentifier: Option[String] + val moduleIdentifier: ModuleIdentifier ) { private def this() = { this( logger = NullLogger, console = ConsoleJSConsole, - moduleKind = ModuleKind.NoModule, - moduleIdentifier = None + moduleIdentifier = ModuleIdentifier.NoModule ) } @@ -197,20 +214,15 @@ object TestAdapter { def withJSConsole(console: JSConsole): Config = copy(console = console) - def withModuleSettings(moduleKind: ModuleKind, - moduleIdentifier: Option[String]): Config = { - require((moduleKind == ModuleKind.NoModule) != moduleIdentifier.nonEmpty, - "Need a module identifier with modules") - copy(moduleKind = moduleKind, moduleIdentifier = moduleIdentifier) - } + def withModuleIdentifier(moduleIdentifier: ModuleIdentifier): Config = + copy(moduleIdentifier = moduleIdentifier) private def copy( logger: Logger = logger, console: JSConsole = console, - moduleKind: ModuleKind = moduleKind, - moduleIdentifier: Option[String] = moduleIdentifier + moduleIdentifier: ModuleIdentifier = moduleIdentifier ): Config = { - new Config(logger, console, moduleKind, moduleIdentifier) + new Config(logger, console, moduleIdentifier) } } From 46666c5a48c77903443a42b51fa475c8c6eacd7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 9 Jan 2018 18:40:58 +0100 Subject: [PATCH 0620/2665] Separate `tools` into `io`, `logging` and `linker`. They define the packages `tools.io`, `tools.logging` and `tools.linker`, respectively. This allows `js-envs` and related artifacts, as well as `test-adapter`, not to depend on the `linker` nor `ir` anymore. Therefore, those artifacts can be used without bringing the linker and IR into the classpath, which can be very important for build tools that want to load the linkers of various Scala.js versions in separate class loaders. --- build.sbt | 8 +- ci/matrix.xml | 36 +++++--- .../core/tools/io/NodeVirtualFiles.scala | 0 .../tools/io/AtomicFileOutputStream.scala | 0 .../io/AtomicWritableFileVirtualFiles.scala | 0 .../core/tools/io/FileVirtualFiles.scala | 0 .../scala/org/scalajs/core/tools/io/IO.scala | 0 .../org/scalajs/core/tools/io/JSUtils.scala | 0 .../org/scalajs/core/tools/io/MemFiles.scala | 0 .../org/scalajs/core/tools/io/URIUtils.scala | 0 .../scalajs/core/tools/io/VirtualFiles.scala | 0 .../scalajs/core/tools/io/URIUtilsTest.scala | 0 .../StandardLinkerPlatformExtensions.scala | 0 .../backend/LinkerBackendPlatform.scala | 0 .../LinkerBackendPlatformExtensions.scala | 0 .../frontend/LinkerFrontendPlatform.scala | 0 .../linker/irio/NodeVirtualIRFiles.scala | 0 .../core/tools/linker/test/QuickLinker.scala | 0 .../linker/testutils/NodeVirtualJarFile.scala | 0 .../tools/linker/testutils/Platform.scala | 0 .../StandardLinkerPlatformExtensions.scala | 0 .../backend/LinkerBackendPlatform.scala | 0 .../LinkerBackendPlatformExtensions.scala | 0 .../backend/closure/ClosureAstBuilder.scala | 0 .../closure/ClosureAstTransformer.scala | 0 .../closure/ClosureLinkerBackend.scala | 0 .../backend/closure/LoggerErrorManager.scala | 0 .../frontend/LinkerFrontendPlatform.scala | 0 .../frontend/optimizer/ConcurrencyUtils.scala | 0 .../frontend/optimizer/ParIncOptimizer.scala | 0 .../linker/irio/FileVirtualIRFiles.scala | 0 .../tools/linker/testutils/Platform.scala | 0 {tools => linker}/scalajsenv.js | 0 .../core/tools/linker/CheckedBehavior.scala | 0 .../core/tools/linker/ClearableLinker.scala | 0 .../scalajs/core/tools/linker/GenLinker.scala | 0 .../core/tools/linker/LinkedClass.scala | 0 .../scalajs/core/tools/linker/Linker.scala | 0 .../core/tools/linker/LinkingException.scala | 0 .../core/tools/linker/LinkingUnit.scala | 0 .../core/tools/linker/ModuleInitializer.scala | 0 .../core/tools/linker/ModuleKind.scala | 0 .../scalajs/core/tools/linker/Semantics.scala | 0 .../core/tools/linker/StandardLinker.scala | 0 .../scalajs/core/tools/linker/Versioned.scala | 0 .../core/tools/linker/analyzer/Analysis.scala | 0 .../core/tools/linker/analyzer/Analyzer.scala | 0 .../core/tools/linker/analyzer/Infos.scala | 0 .../linker/analyzer/SymbolRequirement.scala | 0 .../linker/backend/BasicLinkerBackend.scala | 0 .../tools/linker/backend/LinkerBackend.scala | 0 .../linker/backend/emitter/ClassEmitter.scala | 0 .../linker/backend/emitter/CoreJSLibs.scala | 0 .../linker/backend/emitter/Emitter.scala | 0 .../backend/emitter/FunctionEmitter.scala | 0 .../backend/emitter/GlobalKnowledge.scala | 0 .../backend/emitter/GlobalRefUtils.scala | 0 .../backend/emitter/InternalOptions.scala | 0 .../tools/linker/backend/emitter/JSGen.scala | 0 .../backend/emitter/KnowledgeGuardian.scala | 0 .../linker/backend/emitter/LongImpl.scala | 0 .../linker/backend/emitter/Transients.scala | 0 .../linker/backend/emitter/TreeDSL.scala | 0 .../linker/backend/emitter/WithGlobals.scala | 0 .../backend/javascript/JSBuilders.scala | 0 .../linker/backend/javascript/Printers.scala | 0 .../backend/javascript/SourceMapWriter.scala | 0 .../linker/backend/javascript/Trees.scala | 0 .../core/tools/linker/checker/IRChecker.scala | 0 .../tools/linker/frontend/BaseLinker.scala | 0 .../linker/frontend/LinkerFrontend.scala | 0 .../core/tools/linker/frontend/Refiner.scala | 0 .../frontend/optimizer/GenIncOptimizer.scala | 0 .../frontend/optimizer/IncOptimizer.scala | 0 .../frontend/optimizer/OptimizerCore.scala | 0 .../core/tools/linker/irio/IRFileCache.scala | 0 .../core/tools/linker/irio/MemIRFiles.scala | 0 .../tools/linker/irio/VirtualIRFiles.scala | 0 .../linker/standard/CommonPhaseConfig.scala | 0 .../core/tools/linker/standard/CoreSpec.scala | 0 .../tools/linker/standard/OutputMode.scala | 0 .../core/tools/linker/standard/package.scala | 0 .../core/tools/linker/AnalyzerTest.scala | 0 .../core/tools/linker/LinkerTest.scala | 0 .../linker/testutils/TestIRBuilder.scala | 0 .../tools/linker/testutils/TestIRRepo.scala | 0 .../scalajs/core/tools/logging/Level.scala | 0 .../scalajs/core/tools/logging/Logger.scala | 0 .../core/tools/logging/NullLogger.scala | 0 .../tools/logging/ScalaConsoleLogger.scala | 0 project/BinaryIncompatibilities.scala | 8 +- project/Build.scala | 87 ++++++++++++++++--- project/build.sbt | 10 ++- scripts/publish.sh | 4 +- 94 files changed, 117 insertions(+), 36 deletions(-) rename {tools => io}/js/src/main/scala/org/scalajs/core/tools/io/NodeVirtualFiles.scala (100%) rename {tools => io}/jvm/src/main/scala/org/scalajs/core/tools/io/AtomicFileOutputStream.scala (100%) rename {tools => io}/jvm/src/main/scala/org/scalajs/core/tools/io/AtomicWritableFileVirtualFiles.scala (100%) rename {tools => io}/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala (100%) rename {tools => io}/shared/src/main/scala/org/scalajs/core/tools/io/IO.scala (100%) rename {tools => io}/shared/src/main/scala/org/scalajs/core/tools/io/JSUtils.scala (100%) rename {tools => io}/shared/src/main/scala/org/scalajs/core/tools/io/MemFiles.scala (100%) rename {tools => io}/shared/src/main/scala/org/scalajs/core/tools/io/URIUtils.scala (100%) rename {tools => io}/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala (100%) rename {tools => io}/shared/src/test/scala/org/scalajs/core/tools/io/URIUtilsTest.scala (100%) rename {tools => linker}/js/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala (100%) rename {tools => linker}/js/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatform.scala (100%) rename {tools => linker}/js/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatformExtensions.scala (100%) rename {tools => linker}/js/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontendPlatform.scala (100%) rename {tools => linker}/js/src/main/scala/org/scalajs/core/tools/linker/irio/NodeVirtualIRFiles.scala (100%) rename {tools => linker}/js/src/test/scala/org/scalajs/core/tools/linker/test/QuickLinker.scala (100%) rename {tools => linker}/js/src/test/scala/org/scalajs/core/tools/linker/testutils/NodeVirtualJarFile.scala (100%) rename {tools => linker}/js/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala (100%) rename {tools => linker}/jvm/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala (100%) rename {tools => linker}/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatform.scala (100%) rename {tools => linker}/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatformExtensions.scala (100%) rename {tools => linker}/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstBuilder.scala (100%) rename {tools => linker}/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala (100%) rename {tools => linker}/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala (100%) rename {tools => linker}/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/LoggerErrorManager.scala (100%) rename {tools => linker}/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontendPlatform.scala (100%) rename {tools => linker}/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ConcurrencyUtils.scala (100%) rename {tools => linker}/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ParIncOptimizer.scala (100%) rename {tools => linker}/jvm/src/main/scala/org/scalajs/core/tools/linker/irio/FileVirtualIRFiles.scala (100%) rename {tools => linker}/jvm/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala (100%) rename {tools => linker}/scalajsenv.js (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/CheckedBehavior.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/ClearableLinker.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingException.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/ModuleInitializer.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/ModuleKind.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/Semantics.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/StandardLinker.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/Versioned.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/SymbolRequirement.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/Emitter.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/FunctionEmitter.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalRefUtils.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/InternalOptions.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/LongImpl.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/Transients.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/TreeDSL.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/WithGlobals.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/JSBuilders.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Printers.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/SourceMapWriter.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Trees.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/IncOptimizer.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/irio/IRFileCache.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/irio/MemIRFiles.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/irio/VirtualIRFiles.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/standard/CommonPhaseConfig.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/standard/CoreSpec.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/standard/OutputMode.scala (100%) rename {tools => linker}/shared/src/main/scala/org/scalajs/core/tools/linker/standard/package.scala (100%) rename {tools => linker}/shared/src/test/scala/org/scalajs/core/tools/linker/AnalyzerTest.scala (100%) rename {tools => linker}/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala (100%) rename {tools => linker}/shared/src/test/scala/org/scalajs/core/tools/linker/testutils/TestIRBuilder.scala (100%) rename {tools => linker}/shared/src/test/scala/org/scalajs/core/tools/linker/testutils/TestIRRepo.scala (100%) rename {tools => logging}/shared/src/main/scala/org/scalajs/core/tools/logging/Level.scala (100%) rename {tools => logging}/shared/src/main/scala/org/scalajs/core/tools/logging/Logger.scala (100%) rename {tools => logging}/shared/src/main/scala/org/scalajs/core/tools/logging/NullLogger.scala (100%) rename {tools => logging}/shared/src/main/scala/org/scalajs/core/tools/logging/ScalaConsoleLogger.scala (100%) diff --git a/build.sbt b/build.sbt index 16b253c942..4167d0f2ab 100644 --- a/build.sbt +++ b/build.sbt @@ -4,8 +4,12 @@ val scalajs = Build.root val ir = Build.irProject val irJS = Build.irProjectJS val compiler = Build.compiler -val tools = Build.tools -val toolsJS = Build.toolsJS +val io = Build.io +val ioJS = Build.ioJS +val logging = Build.logging +val loggingJS = Build.loggingJS +val linker = Build.linker +val linkerJS = Build.linkerJS val jsEnvs = Build.jsEnvs val jsEnvsTestKit = Build.jsEnvsTestKit val nodeJSEnv = Build.nodeJSEnv diff --git a/ci/matrix.xml b/ci/matrix.xml index 251b2b646a..ff06e222cc 100644 --- a/ci/matrix.xml +++ b/ci/matrix.xml @@ -159,29 +159,32 @@ @@ -189,10 +192,11 @@ docUrl).toMap } - ).dependsOn(tools, jsEnvs, nodeJSEnv, testAdapter) + ).dependsOn(linker, jsEnvs, nodeJSEnv, testAdapter) lazy val delambdafySetting = { scalacOptions ++= ( @@ -1689,7 +1748,7 @@ object Build { else Nil } - ).dependsOn(compiler, tools, nodeJSEnv) + ).dependsOn(compiler, linker, nodeJSEnv) lazy val partestSuite: Project = (project in file("partest-suite")).settings( commonSettings, diff --git a/project/build.sbt b/project/build.sbt index 54d81ecb30..11549314c6 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -12,8 +12,12 @@ unmanagedSourceDirectories in Compile ++= { val root = baseDirectory.value.getParentFile Seq( root / "ir/src/main/scala", - root / "tools/shared/src/main/scala", - root / "tools/jvm/src/main/scala", + root / "io/shared/src/main/scala", + root / "io/jvm/src/main/scala", + root / "logging/shared/src/main/scala", + root / "logging/jvm/src/main/scala", + root / "linker/shared/src/main/scala", + root / "linker/jvm/src/main/scala", root / "js-envs/src/main/scala", root / "nodejs-env/src/main/scala", root / "test-adapter/src/main/scala", @@ -29,7 +33,7 @@ sources in Compile += sourceGenerators in Compile += Def.task { build.ScalaJSEnvGenerator.generateEnvHolder( - baseDirectory.value.getParentFile / "tools", + baseDirectory.value.getParentFile / "linker", (sourceManaged in Compile).value) }.taskValue diff --git a/scripts/publish.sh b/scripts/publish.sh index 946042c45e..a34688054e 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -15,8 +15,8 @@ SBT1_VERSION="2.12.4" SBT1_SBTVERSION="1.0.0" COMPILER="compiler jUnitPlugin" -LIBS="library irJS toolsJS testInterface jUnitRuntime" -JVM_LIBS="ir tools jsEnvs jsEnvsTestKit nodeJSEnv testAdapter stubs" +LIBS="library irJS ioJS loggingJS linkerJS testInterface jUnitRuntime" +JVM_LIBS="ir io logging linker jsEnvs jsEnvsTestKit nodeJSEnv testAdapter stubs" # Publish compiler for v in $FULL_VERSIONS; do From 563e3096c2bd85aa9c2b55da00e3f917f3d71d97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 17 Jan 2018 13:15:56 +0100 Subject: [PATCH 0621/2665] Avoid `PartialFunction.apply` because it is deprecated in 2.12.5. --- .../src/main/scala/org/scalajs/testcommon/FutureUtil.scala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test-common/src/main/scala/org/scalajs/testcommon/FutureUtil.scala b/test-common/src/main/scala/org/scalajs/testcommon/FutureUtil.scala index 01eb579769..377cf6620c 100644 --- a/test-common/src/main/scala/org/scalajs/testcommon/FutureUtil.scala +++ b/test-common/src/main/scala/org/scalajs/testcommon/FutureUtil.scala @@ -14,6 +14,10 @@ private[scalajs] object FutureUtil { implicit class RichFuture[T](val __self: Future[T]) extends AnyVal { def liftToTry: Future[Try[T]] = - __self.map(Success(_)).recover(PartialFunction(Failure(_))) + __self.map(Success(_)).recover(pf(Failure(_))) + } + + private def pf[A, B](f: A => B): PartialFunction[A, B] = { + case x => f(x) } } From f2746b6d5bceccb317a814e93bfeb5036297959c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 17 Jan 2018 13:16:32 +0100 Subject: [PATCH 0622/2665] Ignore bridges when computing JUnit-annotated methods. Starting with Scala 2.12.5, annotations on methods are copied to the bridges that are generated for them. This sometimes includes JUnit-annotated methods. We must ignore such bridges when detecting the set of methods relevant for the JUnit compiler plugin. --- .../scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala index 202692ff75..a435ed42a0 100644 --- a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala +++ b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala @@ -248,7 +248,7 @@ class ScalaJSJUnitPlugin(val global: Global) extends NscPlugin { def jUnitAnnotatedMethods(sym: Symbol): List[MethodSymbol] = { sym.selfType.members.collect { - case m: MethodSymbol if hasJUnitMethodAnnotation(m) => m + case m: MethodSymbol if !m.isBridge && hasJUnitMethodAnnotation(m) => m }.toList } From 7b5296f8b1b430424c015b3587a2ef69e50e5e73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 17 Jan 2018 13:18:03 +0100 Subject: [PATCH 0623/2665] Do not crash the compiler after "Conflicting properties and methods". When there are conflicting properties and methods in a non-native JS class, `GenJSExports` returns a `js.Skip()` after reporting the error. This `js.Skip()` previously caused `genAnonSJSDefinedNew` to crash with an "Unexpected tree". We now ignore `js.Skip`s at that point so that compile errors are not followed by crashes. --- .../src/main/scala/org/scalajs/core/compiler/GenJSCode.scala | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 5b2d3adfab..a306a004be 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -629,6 +629,9 @@ abstract class GenJSCode extends plugins.PluginComponent case property: js.PropertyDef => classMembers += property + case _: js.Skip => + // This can happen in cases of earlier errors. Don't crash. + case tree => abort("Unexpected tree: " + tree) } From dfb2a2cf94a751562103c0b57af2d95c7cb0d6e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 17 Jan 2018 13:51:44 +0100 Subject: [PATCH 0624/2665] Do not consider bridges as exposed. Before Scala 2.12.5, bridges did not receive any annotation, so the existing test was enough not to consider them as bridges. --- .../src/main/scala/org/scalajs/core/compiler/GenJSCode.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index a306a004be..ab361729d3 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -5397,7 +5397,7 @@ abstract class GenJSCode extends plugins.PluginComponent * originally a public or protected member of a Scala.js-defined JS class. */ private def isExposed(sym: Symbol): Boolean = - sym.hasAnnotation(ExposedJSMemberAnnot) + !sym.isBridge && sym.hasAnnotation(ExposedJSMemberAnnot) /** Test whether `sym` is the symbol of a raw JS function definition */ private def isRawJSFunctionDef(sym: Symbol): Boolean = From b6be9081b8afd185960de0328a602516587c4000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 17 Jan 2018 16:48:54 +0100 Subject: [PATCH 0625/2665] Fix #3259: Generate overriding bridges in synthesized SAM wrappers. Just like Scala/JVM needs to instruct the `LambdaMetaFactory` to generate bridges for methods overridden by the SAM, we need to directly generate appropriate bridges in our synthesized SAM wrappers. Instead of generating actual *bridges*, in the sense that they call the canonical implementation of the method, we generate bodies for all the bridges just like for the canonical method. This is fine because the bodies are just calling the closure stored in a field of the instance anyway. --- .../core/compiler/Compat210Component.scala | 7 +- .../org/scalajs/core/compiler/GenJSCode.scala | 40 +++++- project/Build.scala | 16 ++- .../SAMWithOverridingBridgesTest.scala | 132 ++++++++++++++++++ 4 files changed, 186 insertions(+), 9 deletions(-) create mode 100644 test-suite/shared/src/test/require-sam/org/scalajs/testsuite/compiler/SAMWithOverridingBridgesTest.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala b/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala index 750fab97f2..7335319b9b 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala @@ -90,7 +90,7 @@ trait Compat210Component { /* Should extend PlainAttachment, but it does not exist in 2.10, and we * do not actually need this relationship. */ - case class SAMFunction(samTp: Type, sam: Symbol) + case class SAMFunction(samTp: Type, sam: Symbol, synthCls: Symbol) } object SAMFunctionAttachCompat { @@ -107,6 +107,11 @@ trait Compat210Component { type SAMFunctionCompat = SAMFunctionAttachCompat.Inner.SAMFunctionAlias lazy val SAMFunctionCompat = SAMFunctionAttachCompat.Inner.SAMFunctionAlias + implicit final class SAMFunctionCompatOps(self: SAMFunctionCompat) { + // Introduced in 2.12.5 to synthesize bridges in LMF classes + def synthCls: Symbol = NoSymbol + } + /* global.genBCode.bTypes.initializeCoreBTypes() * * This one has a very particular history: diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index ab361729d3..6a980d7020 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -5107,10 +5107,8 @@ abstract class GenJSCode extends plugins.PluginComponent * We have to synthesize a class like LambdaMetaFactory would do on * the JVM. */ - val sam = originalFunction.attachments.get[SAMFunctionCompat].fold[Symbol] { + val sam = originalFunction.attachments.get[SAMFunctionCompat].getOrElse { abort(s"Cannot find the SAMFunction attachment on $originalFunction at $pos") - } { - _.sam } val samWrapperClassName = synthesizeSAMWrapper(funSym, sam) @@ -5119,7 +5117,7 @@ abstract class GenJSCode extends plugins.PluginComponent } } - private def synthesizeSAMWrapper(funSym: Symbol, sam: Symbol)( + private def synthesizeSAMWrapper(funSym: Symbol, samInfo: SAMFunctionCompat)( implicit pos: Position): String = { val intfName = encodeClassFullName(funSym) @@ -5154,8 +5152,38 @@ abstract class GenJSCode extends plugins.PluginComponent js.OptimizerHints.empty, None) } + // Compute the set of method symbols that we need to implement + val sams = { + val samsBuilder = List.newBuilder[Symbol] + val seenEncodedNames = mutable.Set.empty[String] + + /* scala/bug#10512: any methods which `samInfo.sam` overrides need + * bridges made for them. + * On Scala < 2.12.5, `synthCls` is polyfilled to `NoSymbol` and hence + * `samBridges` will always be empty. This causes our compiler to be + * bug-compatible on these versions. + */ + val synthCls = samInfo.synthCls + val samBridges = if (synthCls == NoSymbol) { + Nil + } else { + import scala.reflect.internal.Flags.BRIDGE + synthCls.info.findMembers(excludedFlags = 0L, requiredFlags = BRIDGE).toList + } + + for (sam <- samInfo.sam :: samBridges) { + /* Remove duplicates, e.g., if we override the same method declared + * in two super traits. + */ + if (seenEncodedNames.add(encodeMethodSym(sam).name)) + samsBuilder += sam + } + + samsBuilder.result() + } + // def samMethod(...params): resultType = this.f$f(...params) - val samMethodDef = { + val samMethodDefs = for (sam <- sams) yield { val jsParams = for (param <- sam.tpe.params) yield { js.ParamDef(encodeLocalSym(param), toIRType(param.tpe), mutable = false, rest = false) @@ -5187,7 +5215,7 @@ abstract class GenJSCode extends plugins.PluginComponent Some(js.Ident(ir.Definitions.ObjectClass)), List(js.Ident(intfName)), None, - List(fFieldDef, ctorDef, samMethodDef))( + fFieldDef :: ctorDef :: samMethodDefs)( js.OptimizerHints.empty.withInline(true)) generatedClasses += ((currentClassSym.get, Some(suffix), classDef)) diff --git a/project/Build.scala b/project/Build.scala index 3a13d3be86..25cfbf45da 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1437,6 +1437,8 @@ object Build { case _ => true } + val scalaV = scalaVersion.value + /* Can't add require-sam as unmanagedSourceDirectories because of the use * of scalacOptions. Hence sources are added individually. * Note that a testSuite/test will not trigger a compile when sources are @@ -1447,8 +1449,18 @@ object Build { val sharedTestDir = testDir.getParentFile.getParentFile.getParentFile / "shared/src/test" - ((sharedTestDir / "require-sam") ** "*.scala").get ++ - (if (isJSTest) ((testDir / "require-sam") ** "*.scala").get else Nil) + val allSAMSources = { + ((sharedTestDir / "require-sam") ** "*.scala").get ++ + (if (isJSTest) ((testDir / "require-sam") ** "*.scala").get else Nil) + } + + val hasBugWithOverriddenMethods = + Set("2.12.0", "2.12.1", "2.12.2", "2.12.3", "2.12.4", "2.13.0-M2").contains(scalaV) + + if (hasBugWithOverriddenMethods) + allSAMSources.filter(_.getName != "SAMWithOverridingBridgesTest.scala") + else + allSAMSources } else { Nil } diff --git a/test-suite/shared/src/test/require-sam/org/scalajs/testsuite/compiler/SAMWithOverridingBridgesTest.scala b/test-suite/shared/src/test/require-sam/org/scalajs/testsuite/compiler/SAMWithOverridingBridgesTest.scala new file mode 100644 index 0000000000..51f654cead --- /dev/null +++ b/test-suite/shared/src/test/require-sam/org/scalajs/testsuite/compiler/SAMWithOverridingBridgesTest.scala @@ -0,0 +1,132 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2018, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.testsuite.compiler + +import org.junit.Test +import org.junit.Assert._ + +/* Issue: https://github.com/scala/bug/issues/10512 + * Test cases taken from: https://github.com/scala/scala/pull/6087 + */ +class SAMWithOverridingBridgesTest { + import SAMWithOverridingBridgesTest._ + + @Test def testVariantA(): Unit = { + import VariantA._ + import JsonEncoderInstances._ + + implicitly[JsonEncoder[List[String]]].encode("" :: Nil) + } + + @Test def testVariantB(): Unit = { + import VariantB._ + + val s1: SAM_A = () => it + val s2: SAM_A1 = () => it + val s3: SAM_B = () => it + val s4: SAM_B1 = () => it + val s5: SAM_B2 = () => it + val s6: SAM_C = () => it + val s7: SAM_F = () => it + val s8: SAM_F1 = () => it + + (s1(): A) + + (s2(): A) + + (s3(): B) + (s3(): A) + + (s4(): B) + (s4(): A) + + (s5(): B) + (s5(): A) + + (s6(): C) + (s6(): B) + (s6(): A) + + (s7(): C) + (s7(): B) + (s7(): A) + + (s8(): C) + (s8(): B) + (s8(): A) + } +} + +object SAMWithOverridingBridgesTest { + object VariantA { + trait JsonValue + class JsonObject extends JsonValue + class JsonString extends JsonValue + + trait JsonEncoder[A] { + def encode(value: A): JsonValue + } + + trait JsonObjectEncoder[A] extends JsonEncoder[A] { + def encode(value: A): JsonObject + } + + object JsonEncoderInstances { + implicit val stringEncoder: JsonEncoder[String] = { + s => new JsonString + // new JsonEncoder[String] { + // def encode(value: String): JsonString = new JsonString + // } + } + + implicit def listEncoder[A]( + implicit encoder: JsonEncoder[A]): JsonObjectEncoder[List[A]] = { + l => new JsonObject + // new JsonObjectEncoder[List[A]] { + // def encode(value: List[A]): JsonObject = new JsonObject + // } + } + } + } + + object VariantB { + trait A + trait B extends A + trait C extends B + object it extends C + + /* try as many weird diamondy things as I can think of */ + + trait SAM_A { + def apply(): A + } + + trait SAM_A1 extends SAM_A { + def apply(): A + } + + trait SAM_B extends SAM_A1 { + def apply(): B + } + + trait SAM_B1 extends SAM_A1 { + def apply(): B + } + + trait SAM_B2 extends SAM_B with SAM_B1 + + trait SAM_C extends SAM_B2 { + def apply(): C + } + + trait SAM_F extends (() => A) with SAM_C + + trait SAM_F1 extends (() => C) with SAM_F + } +} From 097d1a6d785d8c0c6451c50dd686305991bc2aa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 19 Jan 2018 16:52:44 +0100 Subject: [PATCH 0626/2665] Get rid of the `core` and `tools` package namespaces. Since the split into `io`, `logging` and `linker`, the `tools` namespaces does not mean anything anymore, so we lift its three components one level up. This is also a good opportunity to more generally get rid of the `core` namespace. That namespace does not convey any useful meaning, and only make our packages longer for our users and ourselves. Finally, we also rename `compiler` into `nscplugin`, since nsc is not the only Scala compiler anymore, and there will come a time when compiler plugins for other compilers will exist. Concretely, this commit introduces the following renamings: * `org.scalajs.core.ir` -> `org.scalajs.ir` * `org.scalajs.core.compiler` -> `org.scalajs.nscplugin` * `org.scalajs.core.tools.io` -> `org.scalajs.io` * `org.scalajs.core.tools.logging` -> `org.scalajs.logging` * `org.scalajs.core.tools.linker` -> `org.scalajs.linker` --- CODINGSTYLE.md | 4 +-- compiler/src/main/resources/scalac-plugin.xml | 2 +- .../CompatComponent.scala | 2 +- .../ExplicitInnerJS.scala | 2 +- .../ExplicitLocalJS.scala | 2 +- .../compiler => nscplugin}/GenJSCode.scala | 4 +-- .../compiler => nscplugin}/GenJSExports.scala | 4 +-- .../compiler => nscplugin}/GenJSFiles.scala | 4 +-- .../JSDefinitions.scala | 2 +- .../compiler => nscplugin}/JSEncoding.scala | 4 +-- .../JSGlobalAddons.scala | 4 +-- .../compiler => nscplugin}/JSPrimitives.scala | 2 +- .../JSTreeExtractors.scala | 6 ++--- .../PreTyperComponent.scala | 2 +- .../PrepJSExports.scala | 4 +-- .../PrepJSInterop.scala | 4 +-- .../ScalaJSOptions.scala | 2 +- .../ScalaJSPlugin.scala | 4 +-- .../compiler => nscplugin}/TypeKinds.scala | 4 +-- .../util/ScopedVar.scala | 2 +- .../compiler => nscplugin}/util/VarBox.scala | 2 +- .../test/DiverseErrorsTest.scala | 4 +-- .../test/EnumerationInteropTest.scala | 4 +-- .../test/InternalAnnotationsTest.scala | 4 +-- .../test/JSDynamicLiteralTest.scala | 4 +-- .../test/JSExportASTTest.scala | 4 +-- .../test/JSExportTest.scala | 4 +-- .../test/JSGlobalScopeTest.scala | 4 +-- .../test/JSInteropTest.scala | 4 +-- .../test/JSOptionalTest.scala | 4 +-- .../test/JSSAMTest.scala | 4 +-- .../test/JSUndefinedParamTest.scala | 4 +-- .../test/MatchASTTest.scala | 4 +-- .../test/NonNativeJSTypeTest.scala | 4 +-- .../test/OptimizationTest.scala | 4 +-- .../test/PositionTest.scala | 4 +-- .../test/ReflectTest.scala | 4 +-- .../test/util/DirectTest.scala | 8 +++--- .../test/util/JSASTTest.scala | 6 ++--- .../test/util/TestHelpers.scala | 2 +- .../tools => }/io/NodeVirtualFiles.scala | 2 +- .../io/AtomicFileOutputStream.scala | 2 +- .../io/AtomicWritableFileVirtualFiles.scala | 2 +- .../tools => }/io/FileVirtualFiles.scala | 2 +- .../org/scalajs/{core/tools => }/io/IO.scala | 2 +- .../scalajs/{core/tools => }/io/JSUtils.scala | 2 +- .../{core/tools => }/io/MemFiles.scala | 2 +- .../{core/tools => }/io/URIUtils.scala | 2 +- .../{core/tools => }/io/VirtualFiles.scala | 2 +- .../{core/tools => }/io/URIUtilsTest.scala | 2 +- .../org/scalajs/{core => }/ir/ClassKind.scala | 2 +- .../scalajs/{core => }/ir/Definitions.scala | 2 +- .../{core => }/ir/EntryPointsInfo.scala | 2 +- .../org/scalajs/{core => }/ir/Hashers.scala | 2 +- .../ir/IRVersionNotSupportedException.scala | 2 +- .../{core => }/ir/InvalidIRException.scala | 2 +- .../org/scalajs/{core => }/ir/Position.scala | 2 +- .../org/scalajs/{core => }/ir/Printers.scala | 2 +- .../{core => }/ir/ScalaJSVersions.scala | 2 +- .../scalajs/{core => }/ir/Serializers.scala | 2 +- .../org/scalajs/{core => }/ir/Tags.scala | 2 +- .../scalajs/{core => }/ir/Transformers.scala | 2 +- .../scalajs/{core => }/ir/Traversers.scala | 2 +- .../org/scalajs/{core => }/ir/Trees.scala | 2 +- .../org/scalajs/{core => }/ir/Types.scala | 2 +- .../org/scalajs/{core => }/ir/Utils.scala | 2 +- .../scalajs/{core => }/ir/PrintersTest.scala | 2 +- .../org/scalajs/jsenv/test/AsyncTests.scala | 4 +-- .../org/scalajs/jsenv/test/ComTests.scala | 2 +- .../jsenv/test/CustomInitFilesTest.scala | 2 +- .../org/scalajs/jsenv/test/JSEnvTest.scala | 4 +-- .../org/scalajs/jsenv/test/StoreLogger.scala | 2 +- .../scala/org/scalajs/jsenv/AsyncJSEnv.scala | 2 +- .../org/scalajs/jsenv/AsyncJSRunner.scala | 2 +- .../scala/org/scalajs/jsenv/ComJSEnv.scala | 2 +- .../org/scalajs/jsenv/ExternalJSEnv.scala | 4 +-- .../main/scala/org/scalajs/jsenv/JSEnv.scala | 2 +- .../scala/org/scalajs/jsenv/JSInitFiles.scala | 2 +- .../scala/org/scalajs/jsenv/JSRunner.scala | 2 +- .../jsenv/VirtualFileMaterializer.scala | 2 +- .../junit/plugin/ScalaJSJUnitPlugin.scala | 2 +- .../StandardLinkerPlatformExtensions.scala | 2 +- .../backend/LinkerBackendPlatform.scala | 2 +- .../LinkerBackendPlatformExtensions.scala | 2 +- .../frontend/LinkerFrontendPlatform.scala | 4 +-- .../linker/irio/NodeVirtualIRFiles.scala | 4 +-- .../tools => }/linker/test/QuickLinker.scala | 12 ++++----- .../linker/testutils/NodeVirtualJarFile.scala | 6 ++--- .../linker/testutils/Platform.scala | 4 +-- .../StandardLinkerPlatformExtensions.scala | 2 +- .../backend/LinkerBackendPlatform.scala | 4 +-- .../LinkerBackendPlatformExtensions.scala | 4 +-- .../backend/closure/ClosureAstBuilder.scala | 8 +++--- .../closure/ClosureAstTransformer.scala | 8 +++--- .../closure/ClosureLinkerBackend.scala | 18 ++++++------- .../backend/closure/LoggerErrorManager.scala | 4 +-- .../frontend/LinkerFrontendPlatform.scala | 4 +-- .../frontend/optimizer/ConcurrencyUtils.scala | 2 +- .../frontend/optimizer/ParIncOptimizer.scala | 4 +-- .../linker/irio/FileVirtualIRFiles.scala | 4 +-- .../linker/testutils/Platform.scala | 4 +-- .../tools => }/linker/CheckedBehavior.scala | 2 +- .../tools => }/linker/ClearableLinker.scala | 10 +++---- .../{core/tools => }/linker/GenLinker.scala | 10 +++---- .../{core/tools => }/linker/LinkedClass.scala | 4 +-- .../{core/tools => }/linker/Linker.scala | 18 ++++++------- .../tools => }/linker/LinkingException.scala | 2 +- .../{core/tools => }/linker/LinkingUnit.scala | 4 +-- .../tools => }/linker/ModuleInitializer.scala | 8 +++--- .../{core/tools => }/linker/ModuleKind.scala | 2 +- .../{core/tools => }/linker/Semantics.scala | 4 +-- .../tools => }/linker/StandardLinker.scala | 12 ++++----- .../{core/tools => }/linker/Versioned.scala | 4 +-- .../tools => }/linker/analyzer/Analysis.scala | 6 ++--- .../tools => }/linker/analyzer/Analyzer.scala | 8 +++--- .../tools => }/linker/analyzer/Infos.scala | 22 ++++++++-------- .../linker/analyzer/SymbolRequirement.scala | 2 +- .../linker/backend/BasicLinkerBackend.scala | 14 +++++----- .../linker/backend/LinkerBackend.scala | 14 +++++----- .../linker/backend/emitter/ClassEmitter.scala | 14 +++++----- .../linker/backend/emitter/CoreJSLibs.scala | 10 +++---- .../linker/backend/emitter/Emitter.scala | 20 +++++++------- .../backend/emitter/FunctionEmitter.scala | 12 ++++----- .../backend/emitter/GlobalKnowledge.scala | 6 ++--- .../backend/emitter/GlobalRefUtils.scala | 4 +-- .../backend/emitter/InternalOptions.scala | 2 +- .../linker/backend/emitter/JSGen.scala | 10 +++---- .../backend/emitter/KnowledgeGuardian.scala | 10 +++---- .../linker/backend/emitter/LongImpl.scala | 2 +- .../linker/backend/emitter/Transients.scala | 6 ++--- .../linker/backend/emitter/TreeDSL.scala | 8 +++--- .../linker/backend/emitter/WithGlobals.scala | 2 +- .../backend/javascript/JSBuilders.scala | 6 ++--- .../linker/backend/javascript/Printers.scala | 6 ++--- .../backend/javascript/SourceMapWriter.scala | 8 +++--- .../linker/backend/javascript/Trees.scala | 4 +-- .../tools => }/linker/checker/IRChecker.scala | 10 +++---- .../linker/frontend/BaseLinker.scala | 20 +++++++------- .../linker/frontend/LinkerFrontend.scala | 14 +++++----- .../tools => }/linker/frontend/Refiner.scala | 12 ++++----- .../frontend/optimizer/GenIncOptimizer.scala | 16 ++++++------ .../frontend/optimizer/IncOptimizer.scala | 4 +-- .../frontend/optimizer/OptimizerCore.scala | 14 +++++----- .../tools => }/linker/irio/IRFileCache.scala | 8 +++--- .../tools => }/linker/irio/MemIRFiles.scala | 4 +-- .../linker/irio/VirtualIRFiles.scala | 6 ++--- .../linker/standard/CommonPhaseConfig.scala | 4 +-- .../tools => }/linker/standard/CoreSpec.scala | 4 +-- .../linker/standard/OutputMode.scala | 2 +- .../tools => }/linker/standard/package.scala | 2 +- .../tools => }/linker/AnalyzerTest.scala | 26 +++++++++---------- .../{core/tools => }/linker/LinkerTest.scala | 20 +++++++------- .../linker/testutils/TestIRBuilder.scala | 12 ++++----- .../linker/testutils/TestIRRepo.scala | 10 +++---- .../{core/tools => }/logging/Level.scala | 2 +- .../{core/tools => }/logging/Logger.scala | 2 +- .../{core/tools => }/logging/NullLogger.scala | 2 +- .../logging/ScalaConsoleLogger.scala | 2 +- .../jsenv/nodejs/AbstractNodeJSEnv.scala | 6 ++--- .../org/scalajs/jsenv/nodejs/NodeJSEnv.scala | 4 +-- .../partest/scalajs/ScalaJSPartest.scala | 4 +-- .../partest/scalajs/ScalaJSPartest.scala | 4 +-- .../scala/tools/nsc/MainGenericRunner.scala | 12 ++++----- project/Build.scala | 14 +++++----- project/JavaLangObject.scala | 2 +- project/NodeJSEnvForcePolyfills.scala | 2 +- project/project/ScalaJSEnvGenerator.scala | 2 +- sbt-plugin-test/build.sbt | 2 +- sbt-plugin-test/project/build.sbt | 2 +- sbt-plugin-test/project/project/build.sbt | 2 +- .../org/scalajs/sbtplugin/SBTCompat.scala | 2 +- .../org/scalajs/sbtplugin/SBTCompat.scala | 2 +- .../scala/org/scalajs/sbtplugin/Loggers.scala | 2 +- .../sbtplugin/ScalaJSCrossVersion.scala | 2 +- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 10 +++---- .../sbtplugin/ScalaJSPluginInternal.scala | 12 ++++----- .../org/scalajs/sbtplugin/ScalajspUtils.scala | 2 +- .../testadapter/HTMLRunnerBuilder.scala | 4 +-- .../org/scalajs/testadapter/TestAdapter.scala | 6 ++--- 179 files changed, 453 insertions(+), 453 deletions(-) rename compiler/src/main/scala/org/scalajs/{core/compiler => nscplugin}/CompatComponent.scala (99%) rename compiler/src/main/scala/org/scalajs/{core/compiler => nscplugin}/ExplicitInnerJS.scala (99%) rename compiler/src/main/scala/org/scalajs/{core/compiler => nscplugin}/ExplicitLocalJS.scala (99%) rename compiler/src/main/scala/org/scalajs/{core/compiler => nscplugin}/GenJSCode.scala (99%) rename compiler/src/main/scala/org/scalajs/{core/compiler => nscplugin}/GenJSExports.scala (99%) rename compiler/src/main/scala/org/scalajs/{core/compiler => nscplugin}/GenJSFiles.scala (95%) rename compiler/src/main/scala/org/scalajs/{core/compiler => nscplugin}/JSDefinitions.scala (99%) rename compiler/src/main/scala/org/scalajs/{core/compiler => nscplugin}/JSEncoding.scala (99%) rename compiler/src/main/scala/org/scalajs/{core/compiler => nscplugin}/JSGlobalAddons.scala (99%) rename compiler/src/main/scala/org/scalajs/{core/compiler => nscplugin}/JSPrimitives.scala (98%) rename compiler/src/main/scala/org/scalajs/{core/compiler => nscplugin}/JSTreeExtractors.scala (80%) rename compiler/src/main/scala/org/scalajs/{core/compiler => nscplugin}/PreTyperComponent.scala (99%) rename compiler/src/main/scala/org/scalajs/{core/compiler => nscplugin}/PrepJSExports.scala (99%) rename compiler/src/main/scala/org/scalajs/{core/compiler => nscplugin}/PrepJSInterop.scala (99%) rename compiler/src/main/scala/org/scalajs/{core/compiler => nscplugin}/ScalaJSOptions.scala (95%) rename compiler/src/main/scala/org/scalajs/{core/compiler => nscplugin}/ScalaJSPlugin.scala (99%) rename compiler/src/main/scala/org/scalajs/{core/compiler => nscplugin}/TypeKinds.scala (99%) rename compiler/src/main/scala/org/scalajs/{core/compiler => nscplugin}/util/ScopedVar.scala (95%) rename compiler/src/main/scala/org/scalajs/{core/compiler => nscplugin}/util/VarBox.scala (63%) rename compiler/src/test/scala/org/scalajs/{core/compiler => nscplugin}/test/DiverseErrorsTest.scala (99%) rename compiler/src/test/scala/org/scalajs/{core/compiler => nscplugin}/test/EnumerationInteropTest.scala (98%) rename compiler/src/test/scala/org/scalajs/{core/compiler => nscplugin}/test/InternalAnnotationsTest.scala (96%) rename compiler/src/test/scala/org/scalajs/{core/compiler => nscplugin}/test/JSDynamicLiteralTest.scala (98%) rename compiler/src/test/scala/org/scalajs/{core/compiler => nscplugin}/test/JSExportASTTest.scala (85%) rename compiler/src/test/scala/org/scalajs/{core/compiler => nscplugin}/test/JSExportTest.scala (99%) rename compiler/src/test/scala/org/scalajs/{core/compiler => nscplugin}/test/JSGlobalScopeTest.scala (99%) rename compiler/src/test/scala/org/scalajs/{core/compiler => nscplugin}/test/JSInteropTest.scala (99%) rename compiler/src/test/scala/org/scalajs/{core/compiler => nscplugin}/test/JSOptionalTest.scala (98%) rename compiler/src/test/scala/org/scalajs/{core/compiler => nscplugin}/test/JSSAMTest.scala (94%) rename compiler/src/test/scala/org/scalajs/{core/compiler => nscplugin}/test/JSUndefinedParamTest.scala (96%) rename compiler/src/test/scala/org/scalajs/{core/compiler => nscplugin}/test/MatchASTTest.scala (88%) rename compiler/src/test/scala/org/scalajs/{core/compiler => nscplugin}/test/NonNativeJSTypeTest.scala (99%) rename compiler/src/test/scala/org/scalajs/{core/compiler => nscplugin}/test/OptimizationTest.scala (98%) rename compiler/src/test/scala/org/scalajs/{core/compiler => nscplugin}/test/PositionTest.scala (91%) rename compiler/src/test/scala/org/scalajs/{core/compiler => nscplugin}/test/ReflectTest.scala (95%) rename compiler/src/test/scala/org/scalajs/{core/compiler => nscplugin}/test/util/DirectTest.scala (93%) rename compiler/src/test/scala/org/scalajs/{core/compiler => nscplugin}/test/util/JSASTTest.scala (95%) rename compiler/src/test/scala/org/scalajs/{core/compiler => nscplugin}/test/util/TestHelpers.scala (98%) rename io/js/src/main/scala/org/scalajs/{core/tools => }/io/NodeVirtualFiles.scala (97%) rename io/jvm/src/main/scala/org/scalajs/{core/tools => }/io/AtomicFileOutputStream.scala (97%) rename io/jvm/src/main/scala/org/scalajs/{core/tools => }/io/AtomicWritableFileVirtualFiles.scala (97%) rename io/jvm/src/main/scala/org/scalajs/{core/tools => }/io/FileVirtualFiles.scala (99%) rename io/shared/src/main/scala/org/scalajs/{core/tools => }/io/IO.scala (98%) rename io/shared/src/main/scala/org/scalajs/{core/tools => }/io/JSUtils.scala (98%) rename io/shared/src/main/scala/org/scalajs/{core/tools => }/io/MemFiles.scala (98%) rename io/shared/src/main/scala/org/scalajs/{core/tools => }/io/URIUtils.scala (98%) rename io/shared/src/main/scala/org/scalajs/{core/tools => }/io/VirtualFiles.scala (99%) rename io/shared/src/test/scala/org/scalajs/{core/tools => }/io/URIUtilsTest.scala (97%) rename ir/src/main/scala/org/scalajs/{core => }/ir/ClassKind.scala (99%) rename ir/src/main/scala/org/scalajs/{core => }/ir/Definitions.scala (99%) rename ir/src/main/scala/org/scalajs/{core => }/ir/EntryPointsInfo.scala (97%) rename ir/src/main/scala/org/scalajs/{core => }/ir/Hashers.scala (99%) rename ir/src/main/scala/org/scalajs/{core => }/ir/IRVersionNotSupportedException.scala (92%) rename ir/src/main/scala/org/scalajs/{core => }/ir/InvalidIRException.scala (77%) rename ir/src/main/scala/org/scalajs/{core => }/ir/Position.scala (98%) rename ir/src/main/scala/org/scalajs/{core => }/ir/Printers.scala (99%) rename ir/src/main/scala/org/scalajs/{core => }/ir/ScalaJSVersions.scala (97%) rename ir/src/main/scala/org/scalajs/{core => }/ir/Serializers.scala (99%) rename ir/src/main/scala/org/scalajs/{core => }/ir/Tags.scala (99%) rename ir/src/main/scala/org/scalajs/{core => }/ir/Transformers.scala (99%) rename ir/src/main/scala/org/scalajs/{core => }/ir/Traversers.scala (99%) rename ir/src/main/scala/org/scalajs/{core => }/ir/Trees.scala (99%) rename ir/src/main/scala/org/scalajs/{core => }/ir/Types.scala (99%) rename ir/src/main/scala/org/scalajs/{core => }/ir/Utils.scala (99%) rename ir/src/test/scala/org/scalajs/{core => }/ir/PrintersTest.scala (99%) rename linker/js/src/main/scala/org/scalajs/{core/tools => }/linker/StandardLinkerPlatformExtensions.scala (96%) rename linker/js/src/main/scala/org/scalajs/{core/tools => }/linker/backend/LinkerBackendPlatform.scala (93%) rename linker/js/src/main/scala/org/scalajs/{core/tools => }/linker/backend/LinkerBackendPlatformExtensions.scala (95%) rename linker/js/src/main/scala/org/scalajs/{core/tools => }/linker/frontend/LinkerFrontendPlatform.scala (88%) rename linker/js/src/main/scala/org/scalajs/{core/tools => }/linker/irio/NodeVirtualIRFiles.scala (89%) rename linker/js/src/test/scala/org/scalajs/{core/tools => }/linker/test/QuickLinker.scala (93%) rename linker/js/src/test/scala/org/scalajs/{core/tools => }/linker/testutils/NodeVirtualJarFile.scala (94%) rename linker/js/src/test/scala/org/scalajs/{core/tools => }/linker/testutils/Platform.scala (56%) rename linker/jvm/src/main/scala/org/scalajs/{core/tools => }/linker/StandardLinkerPlatformExtensions.scala (96%) rename linker/jvm/src/main/scala/org/scalajs/{core/tools => }/linker/backend/LinkerBackendPlatform.scala (86%) rename linker/jvm/src/main/scala/org/scalajs/{core/tools => }/linker/backend/LinkerBackendPlatformExtensions.scala (89%) rename linker/jvm/src/main/scala/org/scalajs/{core/tools => }/linker/backend/closure/ClosureAstBuilder.scala (84%) rename linker/jvm/src/main/scala/org/scalajs/{core/tools => }/linker/backend/closure/ClosureAstTransformer.scala (98%) rename linker/jvm/src/main/scala/org/scalajs/{core/tools => }/linker/backend/closure/ClosureLinkerBackend.scala (93%) rename linker/jvm/src/main/scala/org/scalajs/{core/tools => }/linker/backend/closure/LoggerErrorManager.scala (92%) rename linker/jvm/src/main/scala/org/scalajs/{core/tools => }/linker/frontend/LinkerFrontendPlatform.scala (89%) rename linker/jvm/src/main/scala/org/scalajs/{core/tools => }/linker/frontend/optimizer/ConcurrencyUtils.scala (97%) rename linker/jvm/src/main/scala/org/scalajs/{core/tools => }/linker/frontend/optimizer/ParIncOptimizer.scala (98%) rename linker/jvm/src/main/scala/org/scalajs/{core/tools => }/linker/irio/FileVirtualIRFiles.scala (96%) rename linker/jvm/src/test/scala/org/scalajs/{core/tools => }/linker/testutils/Platform.scala (61%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/CheckedBehavior.scala (95%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/ClearableLinker.scala (89%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/GenLinker.scala (81%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/LinkedClass.scala (98%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/Linker.scala (81%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/LinkingException.scala (95%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/LinkingUnit.scala (65%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/ModuleInitializer.scala (95%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/ModuleKind.scala (97%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/Semantics.scala (98%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/StandardLinker.scala (95%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/Versioned.scala (94%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/analyzer/Analysis.scala (98%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/analyzer/Analyzer.scala (99%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/analyzer/Infos.scala (96%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/analyzer/SymbolRequirement.scala (98%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/backend/BasicLinkerBackend.scala (82%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/backend/LinkerBackend.scala (92%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/backend/emitter/ClassEmitter.scala (99%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/backend/emitter/CoreJSLibs.scala (95%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/backend/emitter/Emitter.scala (97%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/backend/emitter/FunctionEmitter.scala (99%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/backend/emitter/GlobalKnowledge.scala (94%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/backend/emitter/GlobalRefUtils.scala (96%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/backend/emitter/InternalOptions.scala (95%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/backend/emitter/JSGen.scala (98%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/backend/emitter/KnowledgeGuardian.scala (98%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/backend/emitter/LongImpl.scala (98%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/backend/emitter/Transients.scala (87%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/backend/emitter/TreeDSL.scala (91%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/backend/emitter/WithGlobals.scala (98%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/backend/javascript/JSBuilders.scala (97%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/backend/javascript/Printers.scala (99%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/backend/javascript/SourceMapWriter.scala (98%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/backend/javascript/Trees.scala (98%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/checker/IRChecker.scala (99%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/frontend/BaseLinker.scala (96%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/frontend/LinkerFrontend.scala (90%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/frontend/Refiner.scala (97%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/frontend/optimizer/GenIncOptimizer.scala (98%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/frontend/optimizer/IncOptimizer.scala (98%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/frontend/optimizer/OptimizerCore.scala (99%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/irio/IRFileCache.scala (98%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/irio/MemIRFiles.scala (90%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/irio/VirtualIRFiles.scala (96%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/standard/CommonPhaseConfig.scala (96%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/standard/CoreSpec.scala (95%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/standard/OutputMode.scala (97%) rename linker/shared/src/main/scala/org/scalajs/{core/tools => }/linker/standard/package.scala (96%) rename linker/shared/src/test/scala/org/scalajs/{core/tools => }/linker/AnalyzerTest.scala (95%) rename linker/shared/src/test/scala/org/scalajs/{core/tools => }/linker/LinkerTest.scala (86%) rename linker/shared/src/test/scala/org/scalajs/{core/tools => }/linker/testutils/TestIRBuilder.scala (86%) rename linker/shared/src/test/scala/org/scalajs/{core/tools => }/linker/testutils/TestIRRepo.scala (74%) rename logging/shared/src/main/scala/org/scalajs/{core/tools => }/logging/Level.scala (96%) rename logging/shared/src/main/scala/org/scalajs/{core/tools => }/logging/Logger.scala (97%) rename logging/shared/src/main/scala/org/scalajs/{core/tools => }/logging/NullLogger.scala (82%) rename logging/shared/src/main/scala/org/scalajs/{core/tools => }/logging/ScalaConsoleLogger.scala (92%) diff --git a/CODINGSTYLE.md b/CODINGSTYLE.md index 518b7e269e..a3f8567203 100644 --- a/CODINGSTYLE.md +++ b/CODINGSTYLE.md @@ -268,8 +268,8 @@ import scala.collection.mutable import java.{util => ju} -import org.scalajs.core.tools.linker._ -import org.scalajs.core.tools.linker.standard._ +import org.scalajs.linker._ +import org.scalajs.linker.standard._ ``` Language imports must always come first, and must always be at the top of the file (right after the `package` declaration). diff --git a/compiler/src/main/resources/scalac-plugin.xml b/compiler/src/main/resources/scalac-plugin.xml index b3f8bba348..6f133869fa 100644 --- a/compiler/src/main/resources/scalac-plugin.xml +++ b/compiler/src/main/resources/scalac-plugin.xml @@ -1,4 +1,4 @@ scalajs - org.scalajs.core.compiler.ScalaJSPlugin + org.scalajs.nscplugin.ScalaJSPlugin diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/CompatComponent.scala b/compiler/src/main/scala/org/scalajs/nscplugin/CompatComponent.scala similarity index 99% rename from compiler/src/main/scala/org/scalajs/core/compiler/CompatComponent.scala rename to compiler/src/main/scala/org/scalajs/nscplugin/CompatComponent.scala index bb91228fb4..23b869d05a 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/CompatComponent.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/CompatComponent.scala @@ -3,7 +3,7 @@ * @author Sébastien Doeraene */ -package org.scalajs.core.compiler +package org.scalajs.nscplugin import scala.collection.mutable diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitInnerJS.scala b/compiler/src/main/scala/org/scalajs/nscplugin/ExplicitInnerJS.scala similarity index 99% rename from compiler/src/main/scala/org/scalajs/core/compiler/ExplicitInnerJS.scala rename to compiler/src/main/scala/org/scalajs/nscplugin/ExplicitInnerJS.scala index 513ded3110..c151d1f762 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitInnerJS.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/ExplicitInnerJS.scala @@ -2,7 +2,7 @@ * Copyright 2013-2017 LAMP/EPFL */ -package org.scalajs.core.compiler +package org.scalajs.nscplugin import scala.reflect.internal.Flags diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitLocalJS.scala b/compiler/src/main/scala/org/scalajs/nscplugin/ExplicitLocalJS.scala similarity index 99% rename from compiler/src/main/scala/org/scalajs/core/compiler/ExplicitLocalJS.scala rename to compiler/src/main/scala/org/scalajs/nscplugin/ExplicitLocalJS.scala index 166942a302..36ce5abb58 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ExplicitLocalJS.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/ExplicitLocalJS.scala @@ -2,7 +2,7 @@ * Copyright 2013-2017 LAMP/EPFL */ -package org.scalajs.core.compiler +package org.scalajs.nscplugin import scala.reflect.internal.Flags diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala similarity index 99% rename from compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala rename to compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala index 4abb53ab08..f38380b025 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala @@ -3,7 +3,7 @@ * @author Sébastien Doeraene */ -package org.scalajs.core.compiler +package org.scalajs.nscplugin import scala.language.implicitConversions @@ -16,7 +16,7 @@ import scala.tools.nsc._ import scala.annotation.tailrec -import org.scalajs.core.ir +import org.scalajs.ir import ir.{Trees => js, Types => jstpe, ClassKind, Hashers} import ir.Trees.OptimizerHints diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/nscplugin/GenJSExports.scala similarity index 99% rename from compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala rename to compiler/src/main/scala/org/scalajs/nscplugin/GenJSExports.scala index d7a33771db..6d258c9c3a 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/GenJSExports.scala @@ -3,7 +3,7 @@ * @author Sébastien Doeraene */ -package org.scalajs.core.compiler +package org.scalajs.nscplugin import scala.collection.{immutable, mutable} @@ -12,7 +12,7 @@ import scala.math.PartialOrdering import scala.reflect.{ClassTag, classTag} import scala.reflect.internal.Flags -import org.scalajs.core.ir +import org.scalajs.ir import ir.{Trees => js, Types => jstpe} import ir.Trees.OptimizerHints diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSFiles.scala b/compiler/src/main/scala/org/scalajs/nscplugin/GenJSFiles.scala similarity index 95% rename from compiler/src/main/scala/org/scalajs/core/compiler/GenJSFiles.scala rename to compiler/src/main/scala/org/scalajs/nscplugin/GenJSFiles.scala index bb804abb56..ce61db546c 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSFiles.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/GenJSFiles.scala @@ -3,7 +3,7 @@ * @author Sébastien Doeraene */ -package org.scalajs.core.compiler +package org.scalajs.nscplugin import scala.tools.nsc._ import scala.tools.nsc.io.AbstractFile @@ -11,7 +11,7 @@ import scala.reflect.internal.pickling.PickleBuffer import java.io._ -import org.scalajs.core.ir +import org.scalajs.ir /** Send JS ASTs to files * diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/nscplugin/JSDefinitions.scala similarity index 99% rename from compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala rename to compiler/src/main/scala/org/scalajs/nscplugin/JSDefinitions.scala index 1411ba7572..51fd52ed85 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/JSDefinitions.scala @@ -3,7 +3,7 @@ * @author Sébastien Doeraene */ -package org.scalajs.core.compiler +package org.scalajs.nscplugin import scala.tools.nsc._ diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala b/compiler/src/main/scala/org/scalajs/nscplugin/JSEncoding.scala similarity index 99% rename from compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala rename to compiler/src/main/scala/org/scalajs/nscplugin/JSEncoding.scala index c30b18392d..6527c9a79d 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/JSEncoding.scala @@ -3,13 +3,13 @@ * @author Sébastien Doeraene */ -package org.scalajs.core.compiler +package org.scalajs.nscplugin import scala.collection.mutable import scala.tools.nsc._ -import org.scalajs.core.ir +import org.scalajs.ir import ir.{Trees => js, Types => jstpe} import util.ScopedVar diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala b/compiler/src/main/scala/org/scalajs/nscplugin/JSGlobalAddons.scala similarity index 99% rename from compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala rename to compiler/src/main/scala/org/scalajs/nscplugin/JSGlobalAddons.scala index ca60869d61..68c54b5e11 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/JSGlobalAddons.scala @@ -3,13 +3,13 @@ * @author Sébastien Doeraene */ -package org.scalajs.core.compiler +package org.scalajs.nscplugin import scala.tools.nsc._ import scala.collection.mutable -import org.scalajs.core.ir.Trees.JSNativeLoadSpec +import org.scalajs.ir.Trees.JSNativeLoadSpec /** Additions to Global meaningful for the JavaScript backend * diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala b/compiler/src/main/scala/org/scalajs/nscplugin/JSPrimitives.scala similarity index 98% rename from compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala rename to compiler/src/main/scala/org/scalajs/nscplugin/JSPrimitives.scala index 88f103f60b..4699dc5d2e 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/JSPrimitives.scala @@ -3,7 +3,7 @@ * @author Sébastien Doeraene */ -package org.scalajs.core.compiler +package org.scalajs.nscplugin import scala.tools.nsc._ diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSTreeExtractors.scala b/compiler/src/main/scala/org/scalajs/nscplugin/JSTreeExtractors.scala similarity index 80% rename from compiler/src/main/scala/org/scalajs/core/compiler/JSTreeExtractors.scala rename to compiler/src/main/scala/org/scalajs/nscplugin/JSTreeExtractors.scala index 0642d8e944..4d446831aa 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSTreeExtractors.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/JSTreeExtractors.scala @@ -3,12 +3,12 @@ * @author Tobias Schlatter */ -package org.scalajs.core.compiler +package org.scalajs.nscplugin import scala.annotation.tailrec -import org.scalajs.core.ir.Trees._ -import org.scalajs.core.ir.Types._ +import org.scalajs.ir.Trees._ +import org.scalajs.ir.Types._ /** Useful extractors for JavaScript trees */ object JSTreeExtractors { diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PreTyperComponent.scala b/compiler/src/main/scala/org/scalajs/nscplugin/PreTyperComponent.scala similarity index 99% rename from compiler/src/main/scala/org/scalajs/core/compiler/PreTyperComponent.scala rename to compiler/src/main/scala/org/scalajs/nscplugin/PreTyperComponent.scala index 303a594b3e..51a83f1bb1 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PreTyperComponent.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/PreTyperComponent.scala @@ -3,7 +3,7 @@ * @author Nicolas Stucki */ -package org.scalajs.core.compiler +package org.scalajs.nscplugin import scala.tools.nsc import nsc._ diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/nscplugin/PrepJSExports.scala similarity index 99% rename from compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala rename to compiler/src/main/scala/org/scalajs/nscplugin/PrepJSExports.scala index 7d9df2ffd3..c211a1d5c6 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/PrepJSExports.scala @@ -3,11 +3,11 @@ * @author Tobias Schlatter */ -package org.scalajs.core.compiler +package org.scalajs.nscplugin import scala.collection.mutable -import org.scalajs.core.ir.Trees.isValidIdentifier +import org.scalajs.ir.Trees.isValidIdentifier /** * Prepare export generation diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/nscplugin/PrepJSInterop.scala similarity index 99% rename from compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala rename to compiler/src/main/scala/org/scalajs/nscplugin/PrepJSInterop.scala index 2d13098db0..243a86fda2 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/PrepJSInterop.scala @@ -3,7 +3,7 @@ * @author Tobias Schlatter */ -package org.scalajs.core.compiler +package org.scalajs.nscplugin import scala.tools.nsc import nsc._ @@ -11,7 +11,7 @@ import nsc._ import scala.collection.immutable.ListMap import scala.collection.mutable -import org.scalajs.core.ir.Trees.{isValidIdentifier, JSNativeLoadSpec} +import org.scalajs.ir.Trees.{isValidIdentifier, JSNativeLoadSpec} /** Prepares classes extending js.Any for JavaScript interop * diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala b/compiler/src/main/scala/org/scalajs/nscplugin/ScalaJSOptions.scala similarity index 95% rename from compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala rename to compiler/src/main/scala/org/scalajs/nscplugin/ScalaJSOptions.scala index aa7f91a245..a3b0fc88f4 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/ScalaJSOptions.scala @@ -3,7 +3,7 @@ * @author Tobias Schlatter */ -package org.scalajs.core.compiler +package org.scalajs.nscplugin import java.net.URI diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala b/compiler/src/main/scala/org/scalajs/nscplugin/ScalaJSPlugin.scala similarity index 99% rename from compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala rename to compiler/src/main/scala/org/scalajs/nscplugin/ScalaJSPlugin.scala index 824cfe06a3..a04559f440 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/ScalaJSPlugin.scala @@ -3,7 +3,7 @@ * @author Sébastien Doeraene */ -package org.scalajs.core.compiler +package org.scalajs.nscplugin import scala.tools.nsc._ import scala.tools.nsc.plugins.{ @@ -13,7 +13,7 @@ import scala.collection.{ mutable, immutable } import java.net.{ URI, URISyntaxException } -import org.scalajs.core.ir.Trees +import org.scalajs.ir.Trees /** Main entry point for the Scala.js compiler plugin * diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/TypeKinds.scala b/compiler/src/main/scala/org/scalajs/nscplugin/TypeKinds.scala similarity index 99% rename from compiler/src/main/scala/org/scalajs/core/compiler/TypeKinds.scala rename to compiler/src/main/scala/org/scalajs/nscplugin/TypeKinds.scala index 9bc68a5ba0..232ee99065 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/TypeKinds.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/TypeKinds.scala @@ -3,11 +3,11 @@ * @author Sébastien Doeraene */ -package org.scalajs.core.compiler +package org.scalajs.nscplugin import scala.tools.nsc._ -import org.scalajs.core.ir +import org.scalajs.ir import ir.{Definitions, Types} /** Glue representation of types as seen from the IR but still with a diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/util/ScopedVar.scala b/compiler/src/main/scala/org/scalajs/nscplugin/util/ScopedVar.scala similarity index 95% rename from compiler/src/main/scala/org/scalajs/core/compiler/util/ScopedVar.scala rename to compiler/src/main/scala/org/scalajs/nscplugin/util/ScopedVar.scala index 225529217d..a74f431815 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/util/ScopedVar.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/util/ScopedVar.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.compiler.util +package org.scalajs.nscplugin.util import language.implicitConversions diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/util/VarBox.scala b/compiler/src/main/scala/org/scalajs/nscplugin/util/VarBox.scala similarity index 63% rename from compiler/src/main/scala/org/scalajs/core/compiler/util/VarBox.scala rename to compiler/src/main/scala/org/scalajs/nscplugin/util/VarBox.scala index 1f0274e9b1..bf7145c603 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/util/VarBox.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/util/VarBox.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.compiler.util +package org.scalajs.nscplugin.util import language.implicitConversions diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/DiverseErrorsTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/DiverseErrorsTest.scala similarity index 99% rename from compiler/src/test/scala/org/scalajs/core/compiler/test/DiverseErrorsTest.scala rename to compiler/src/test/scala/org/scalajs/nscplugin/test/DiverseErrorsTest.scala index 7f5c0db9ab..0cdea4bddc 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/DiverseErrorsTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/DiverseErrorsTest.scala @@ -1,6 +1,6 @@ -package org.scalajs.core.compiler.test +package org.scalajs.nscplugin.test -import org.scalajs.core.compiler.test.util._ +import org.scalajs.nscplugin.test.util._ import org.junit.Test // scalastyle:off line.size.limit diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/EnumerationInteropTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/EnumerationInteropTest.scala similarity index 98% rename from compiler/src/test/scala/org/scalajs/core/compiler/test/EnumerationInteropTest.scala rename to compiler/src/test/scala/org/scalajs/nscplugin/test/EnumerationInteropTest.scala index 257e25c458..8790fb0502 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/EnumerationInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/EnumerationInteropTest.scala @@ -1,6 +1,6 @@ -package org.scalajs.core.compiler.test +package org.scalajs.nscplugin.test -import org.scalajs.core.compiler.test.util._ +import org.scalajs.nscplugin.test.util._ import org.junit.Test diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/InternalAnnotationsTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/InternalAnnotationsTest.scala similarity index 96% rename from compiler/src/test/scala/org/scalajs/core/compiler/test/InternalAnnotationsTest.scala rename to compiler/src/test/scala/org/scalajs/nscplugin/test/InternalAnnotationsTest.scala index 145481baa0..51d52c83b5 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/InternalAnnotationsTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/InternalAnnotationsTest.scala @@ -1,6 +1,6 @@ -package org.scalajs.core.compiler.test +package org.scalajs.nscplugin.test -import org.scalajs.core.compiler.test.util._ +import org.scalajs.nscplugin.test.util._ import org.junit._ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSDynamicLiteralTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/JSDynamicLiteralTest.scala similarity index 98% rename from compiler/src/test/scala/org/scalajs/core/compiler/test/JSDynamicLiteralTest.scala rename to compiler/src/test/scala/org/scalajs/nscplugin/test/JSDynamicLiteralTest.scala index 9e586c7ada..58a3807598 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSDynamicLiteralTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/JSDynamicLiteralTest.scala @@ -1,6 +1,6 @@ -package org.scalajs.core.compiler.test +package org.scalajs.nscplugin.test -import org.scalajs.core.compiler.test.util._ +import org.scalajs.nscplugin.test.util._ import org.junit.Test // scalastyle:off line.size.limit diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportASTTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/JSExportASTTest.scala similarity index 85% rename from compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportASTTest.scala rename to compiler/src/test/scala/org/scalajs/nscplugin/test/JSExportASTTest.scala index 102eaa03a4..ba94b0e5b6 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportASTTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/JSExportASTTest.scala @@ -1,11 +1,11 @@ -package org.scalajs.core.compiler.test +package org.scalajs.nscplugin.test import util._ import org.junit.Test import org.junit.Assert._ -import org.scalajs.core.ir.{Trees => js} +import org.scalajs.ir.{Trees => js} class JSExportASTTest extends JSASTTest { diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/JSExportTest.scala similarity index 99% rename from compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala rename to compiler/src/test/scala/org/scalajs/nscplugin/test/JSExportTest.scala index 3d48f10d43..c4c0e1b4e0 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/JSExportTest.scala @@ -1,6 +1,6 @@ -package org.scalajs.core.compiler.test +package org.scalajs.nscplugin.test -import org.scalajs.core.compiler.test.util._ +import org.scalajs.nscplugin.test.util._ import org.junit.Test import org.junit.Assume._ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSGlobalScopeTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/JSGlobalScopeTest.scala similarity index 99% rename from compiler/src/test/scala/org/scalajs/core/compiler/test/JSGlobalScopeTest.scala rename to compiler/src/test/scala/org/scalajs/nscplugin/test/JSGlobalScopeTest.scala index 0157172d9e..482ae45dc5 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSGlobalScopeTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/JSGlobalScopeTest.scala @@ -1,6 +1,6 @@ -package org.scalajs.core.compiler.test +package org.scalajs.nscplugin.test -import org.scalajs.core.compiler.test.util._ +import org.scalajs.nscplugin.test.util._ import org.junit.Test import org.junit.Ignore diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/JSInteropTest.scala similarity index 99% rename from compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala rename to compiler/src/test/scala/org/scalajs/nscplugin/test/JSInteropTest.scala index 19cbc9ce6e..468b9cd4e2 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/JSInteropTest.scala @@ -1,6 +1,6 @@ -package org.scalajs.core.compiler.test +package org.scalajs.nscplugin.test -import org.scalajs.core.compiler.test.util._ +import org.scalajs.nscplugin.test.util._ import org.junit.Test import org.junit.Ignore diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/JSOptionalTest.scala similarity index 98% rename from compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala rename to compiler/src/test/scala/org/scalajs/nscplugin/test/JSOptionalTest.scala index 1ddbccca17..bbb2f5800f 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/JSOptionalTest.scala @@ -1,6 +1,6 @@ -package org.scalajs.core.compiler.test +package org.scalajs.nscplugin.test -import org.scalajs.core.compiler.test.util._ +import org.scalajs.nscplugin.test.util._ import org.junit.Test import org.junit.Ignore diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSSAMTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/JSSAMTest.scala similarity index 94% rename from compiler/src/test/scala/org/scalajs/core/compiler/test/JSSAMTest.scala rename to compiler/src/test/scala/org/scalajs/nscplugin/test/JSSAMTest.scala index 57afbeecec..d901d45a48 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSSAMTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/JSSAMTest.scala @@ -1,6 +1,6 @@ -package org.scalajs.core.compiler.test +package org.scalajs.nscplugin.test -import org.scalajs.core.compiler.test.util._ +import org.scalajs.nscplugin.test.util._ import org.junit.Assume._ import org.junit.Test diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSUndefinedParamTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/JSUndefinedParamTest.scala similarity index 96% rename from compiler/src/test/scala/org/scalajs/core/compiler/test/JSUndefinedParamTest.scala rename to compiler/src/test/scala/org/scalajs/nscplugin/test/JSUndefinedParamTest.scala index b3c4a20e68..bc4febbe98 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSUndefinedParamTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/JSUndefinedParamTest.scala @@ -1,6 +1,6 @@ -package org.scalajs.core.compiler.test +package org.scalajs.nscplugin.test -import org.scalajs.core.compiler.test.util._ +import org.scalajs.nscplugin.test.util._ import org.junit.Test // scalastyle:off line.size.limit diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/MatchASTTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/MatchASTTest.scala similarity index 88% rename from compiler/src/test/scala/org/scalajs/core/compiler/test/MatchASTTest.scala rename to compiler/src/test/scala/org/scalajs/nscplugin/test/MatchASTTest.scala index c6676d5d2d..5d36496675 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/MatchASTTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/MatchASTTest.scala @@ -1,11 +1,11 @@ -package org.scalajs.core.compiler.test +package org.scalajs.nscplugin.test import util._ import org.junit.Test import org.junit.Assert._ -import org.scalajs.core.ir.{Trees => js} +import org.scalajs.ir.{Trees => js} class MatchASTTest extends JSASTTest { diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/NonNativeJSTypeTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/NonNativeJSTypeTest.scala similarity index 99% rename from compiler/src/test/scala/org/scalajs/core/compiler/test/NonNativeJSTypeTest.scala rename to compiler/src/test/scala/org/scalajs/nscplugin/test/NonNativeJSTypeTest.scala index 47d7e25396..27fbaec1f9 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/NonNativeJSTypeTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/NonNativeJSTypeTest.scala @@ -1,6 +1,6 @@ -package org.scalajs.core.compiler.test +package org.scalajs.nscplugin.test -import org.scalajs.core.compiler.test.util._ +import org.scalajs.nscplugin.test.util._ import org.junit.Test import org.junit.Ignore diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/OptimizationTest.scala similarity index 98% rename from compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala rename to compiler/src/test/scala/org/scalajs/nscplugin/test/OptimizationTest.scala index 4f113e2cf3..fc709313ae 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/OptimizationTest.scala @@ -1,10 +1,10 @@ -package org.scalajs.core.compiler.test +package org.scalajs.nscplugin.test import util._ import org.junit.Test -import org.scalajs.core.ir.{Trees => js, Types => jstpe} +import org.scalajs.ir.{Trees => js, Types => jstpe} class OptimizationTest extends JSASTTest { diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/PositionTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/PositionTest.scala similarity index 91% rename from compiler/src/test/scala/org/scalajs/core/compiler/test/PositionTest.scala rename to compiler/src/test/scala/org/scalajs/nscplugin/test/PositionTest.scala index b5d02af3ef..73e720fb05 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/PositionTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/PositionTest.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.compiler.test +package org.scalajs.nscplugin.test import util.JSASTTest @@ -7,7 +7,7 @@ import org.junit.Assert._ import scala.reflect.internal.util.BatchSourceFile -import org.scalajs.core.ir.{Trees => js} +import org.scalajs.ir.{Trees => js} class PositionTest extends JSASTTest { diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/ReflectTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/ReflectTest.scala similarity index 95% rename from compiler/src/test/scala/org/scalajs/core/compiler/test/ReflectTest.scala rename to compiler/src/test/scala/org/scalajs/nscplugin/test/ReflectTest.scala index 93859def11..8fa0372bba 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/ReflectTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/ReflectTest.scala @@ -1,6 +1,6 @@ -package org.scalajs.core.compiler.test +package org.scalajs.nscplugin.test -import org.scalajs.core.compiler.test.util._ +import org.scalajs.nscplugin.test.util._ import org.junit.Test // scalastyle:off line.size.limit diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/util/DirectTest.scala similarity index 93% rename from compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala rename to compiler/src/test/scala/org/scalajs/nscplugin/test/util/DirectTest.scala index fbdcdc2803..2d6d3c602a 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/util/DirectTest.scala @@ -1,11 +1,11 @@ -package org.scalajs.core.compiler.test.util +package org.scalajs.nscplugin.test.util import scala.tools.nsc._ import scala.tools.nsc.plugins.Plugin import reporters.{Reporter, ConsoleReporter} import scala.reflect.internal.util.{ SourceFile, BatchSourceFile } -import org.scalajs.core.compiler.ScalaJSPlugin +import org.scalajs.nscplugin.ScalaJSPlugin import scala.collection.mutable @@ -83,8 +83,8 @@ abstract class DirectTest { // Cannot reuse global, otherwise compiler crashes with Scala >= 2.11.5 // on following tests: - // - org.scalajs.core.compiler.test.JSExportTest - // - org.scalajs.core.compiler.test.JSDynamicLiteralTest + // - org.scalajs.nscplugin.test.JSExportTest + // - org.scalajs.nscplugin.test.JSDynamicLiteralTest // Filed as #1443 def defaultGlobal: Global = newScalaJSCompiler() diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/JSASTTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/util/JSASTTest.scala similarity index 95% rename from compiler/src/test/scala/org/scalajs/core/compiler/test/util/JSASTTest.scala rename to compiler/src/test/scala/org/scalajs/nscplugin/test/util/JSASTTest.scala index d5de443ec9..b140edfeef 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/JSASTTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/util/JSASTTest.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.compiler.test.util +package org.scalajs.nscplugin.test.util import language.implicitConversions @@ -9,9 +9,9 @@ import scala.util.control.ControlThrowable import org.junit.Assert._ -import org.scalajs.core.compiler.{ScalaJSPlugin, JSTreeExtractors} +import org.scalajs.nscplugin.{ScalaJSPlugin, JSTreeExtractors} import JSTreeExtractors.jse -import org.scalajs.core.ir +import org.scalajs.ir import ir.{Trees => js} abstract class JSASTTest extends DirectTest { diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/TestHelpers.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/util/TestHelpers.scala similarity index 98% rename from compiler/src/test/scala/org/scalajs/core/compiler/test/util/TestHelpers.scala rename to compiler/src/test/scala/org/scalajs/nscplugin/test/util/TestHelpers.scala index 644ab93abc..ec24abfdd8 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/TestHelpers.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/util/TestHelpers.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.compiler.test.util +package org.scalajs.nscplugin.test.util import java.io._ import scala.tools.nsc._ diff --git a/io/js/src/main/scala/org/scalajs/core/tools/io/NodeVirtualFiles.scala b/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala similarity index 97% rename from io/js/src/main/scala/org/scalajs/core/tools/io/NodeVirtualFiles.scala rename to io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala index b5d3c02891..e5edfd9847 100644 --- a/io/js/src/main/scala/org/scalajs/core/tools/io/NodeVirtualFiles.scala +++ b/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.tools.io +package org.scalajs.io import scala.scalajs.js import scala.scalajs.js.typedarray._ diff --git a/io/jvm/src/main/scala/org/scalajs/core/tools/io/AtomicFileOutputStream.scala b/io/jvm/src/main/scala/org/scalajs/io/AtomicFileOutputStream.scala similarity index 97% rename from io/jvm/src/main/scala/org/scalajs/core/tools/io/AtomicFileOutputStream.scala rename to io/jvm/src/main/scala/org/scalajs/io/AtomicFileOutputStream.scala index 0eb7c9c278..8d7237857e 100644 --- a/io/jvm/src/main/scala/org/scalajs/core/tools/io/AtomicFileOutputStream.scala +++ b/io/jvm/src/main/scala/org/scalajs/io/AtomicFileOutputStream.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.tools.io +package org.scalajs.io import java.io._ import java.net.URI diff --git a/io/jvm/src/main/scala/org/scalajs/core/tools/io/AtomicWritableFileVirtualFiles.scala b/io/jvm/src/main/scala/org/scalajs/io/AtomicWritableFileVirtualFiles.scala similarity index 97% rename from io/jvm/src/main/scala/org/scalajs/core/tools/io/AtomicWritableFileVirtualFiles.scala rename to io/jvm/src/main/scala/org/scalajs/io/AtomicWritableFileVirtualFiles.scala index 8adc439215..7b0c842f54 100644 --- a/io/jvm/src/main/scala/org/scalajs/core/tools/io/AtomicWritableFileVirtualFiles.scala +++ b/io/jvm/src/main/scala/org/scalajs/io/AtomicWritableFileVirtualFiles.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.tools.io +package org.scalajs.io import java.io._ import java.net.URI diff --git a/io/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala b/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala similarity index 99% rename from io/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala rename to io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala index e471504252..0c459e3cbf 100644 --- a/io/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala +++ b/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.tools.io +package org.scalajs.io import java.io._ import java.net.URI diff --git a/io/shared/src/main/scala/org/scalajs/core/tools/io/IO.scala b/io/shared/src/main/scala/org/scalajs/io/IO.scala similarity index 98% rename from io/shared/src/main/scala/org/scalajs/core/tools/io/IO.scala rename to io/shared/src/main/scala/org/scalajs/io/IO.scala index 7ae98e44ab..60b40a207a 100644 --- a/io/shared/src/main/scala/org/scalajs/core/tools/io/IO.scala +++ b/io/shared/src/main/scala/org/scalajs/io/IO.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.tools.io +package org.scalajs.io import scala.annotation.tailrec diff --git a/io/shared/src/main/scala/org/scalajs/core/tools/io/JSUtils.scala b/io/shared/src/main/scala/org/scalajs/io/JSUtils.scala similarity index 98% rename from io/shared/src/main/scala/org/scalajs/core/tools/io/JSUtils.scala rename to io/shared/src/main/scala/org/scalajs/io/JSUtils.scala index 38ad78935d..a57f3da8d3 100644 --- a/io/shared/src/main/scala/org/scalajs/core/tools/io/JSUtils.scala +++ b/io/shared/src/main/scala/org/scalajs/io/JSUtils.scala @@ -6,7 +6,7 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.io +package org.scalajs.io object JSUtils { diff --git a/io/shared/src/main/scala/org/scalajs/core/tools/io/MemFiles.scala b/io/shared/src/main/scala/org/scalajs/io/MemFiles.scala similarity index 98% rename from io/shared/src/main/scala/org/scalajs/core/tools/io/MemFiles.scala rename to io/shared/src/main/scala/org/scalajs/io/MemFiles.scala index 68cb3bddb8..8cc2398540 100644 --- a/io/shared/src/main/scala/org/scalajs/core/tools/io/MemFiles.scala +++ b/io/shared/src/main/scala/org/scalajs/io/MemFiles.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.io +package org.scalajs.io import java.io._ diff --git a/io/shared/src/main/scala/org/scalajs/core/tools/io/URIUtils.scala b/io/shared/src/main/scala/org/scalajs/io/URIUtils.scala similarity index 98% rename from io/shared/src/main/scala/org/scalajs/core/tools/io/URIUtils.scala rename to io/shared/src/main/scala/org/scalajs/io/URIUtils.scala index 58529dd937..a1f9380682 100644 --- a/io/shared/src/main/scala/org/scalajs/core/tools/io/URIUtils.scala +++ b/io/shared/src/main/scala/org/scalajs/io/URIUtils.scala @@ -6,7 +6,7 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.io +package org.scalajs.io import java.net.URI diff --git a/io/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala b/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala similarity index 99% rename from io/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala rename to io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala index 77355d1c55..c2707c7cec 100644 --- a/io/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala +++ b/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.tools.io +package org.scalajs.io import java.io._ import java.net.URI diff --git a/io/shared/src/test/scala/org/scalajs/core/tools/io/URIUtilsTest.scala b/io/shared/src/test/scala/org/scalajs/io/URIUtilsTest.scala similarity index 97% rename from io/shared/src/test/scala/org/scalajs/core/tools/io/URIUtilsTest.scala rename to io/shared/src/test/scala/org/scalajs/io/URIUtilsTest.scala index efdb4204ff..6fa9f67af7 100644 --- a/io/shared/src/test/scala/org/scalajs/core/tools/io/URIUtilsTest.scala +++ b/io/shared/src/test/scala/org/scalajs/io/URIUtilsTest.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.tools.io +package org.scalajs.io import java.net.URI diff --git a/ir/src/main/scala/org/scalajs/core/ir/ClassKind.scala b/ir/src/main/scala/org/scalajs/ir/ClassKind.scala similarity index 99% rename from ir/src/main/scala/org/scalajs/core/ir/ClassKind.scala rename to ir/src/main/scala/org/scalajs/ir/ClassKind.scala index 473ea47789..4daa6cf71d 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ClassKind.scala +++ b/ir/src/main/scala/org/scalajs/ir/ClassKind.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.ir +package org.scalajs.ir import scala.annotation.switch diff --git a/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala b/ir/src/main/scala/org/scalajs/ir/Definitions.scala similarity index 99% rename from ir/src/main/scala/org/scalajs/core/ir/Definitions.scala rename to ir/src/main/scala/org/scalajs/ir/Definitions.scala index 311632a8e9..25c93addf3 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala +++ b/ir/src/main/scala/org/scalajs/ir/Definitions.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.ir +package org.scalajs.ir import Types._ diff --git a/ir/src/main/scala/org/scalajs/core/ir/EntryPointsInfo.scala b/ir/src/main/scala/org/scalajs/ir/EntryPointsInfo.scala similarity index 97% rename from ir/src/main/scala/org/scalajs/core/ir/EntryPointsInfo.scala rename to ir/src/main/scala/org/scalajs/ir/EntryPointsInfo.scala index 16a7eb37d3..0f95e21560 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/EntryPointsInfo.scala +++ b/ir/src/main/scala/org/scalajs/ir/EntryPointsInfo.scala @@ -6,7 +6,7 @@ ** |/____/ ** \* */ -package org.scalajs.core.ir +package org.scalajs.ir import Trees._ diff --git a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala b/ir/src/main/scala/org/scalajs/ir/Hashers.scala similarity index 99% rename from ir/src/main/scala/org/scalajs/core/ir/Hashers.scala rename to ir/src/main/scala/org/scalajs/ir/Hashers.scala index b922eb51d2..d463ae2873 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala +++ b/ir/src/main/scala/org/scalajs/ir/Hashers.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.ir +package org.scalajs.ir import java.security.{MessageDigest, DigestOutputStream} import java.io.{OutputStream, DataOutputStream} diff --git a/ir/src/main/scala/org/scalajs/core/ir/IRVersionNotSupportedException.scala b/ir/src/main/scala/org/scalajs/ir/IRVersionNotSupportedException.scala similarity index 92% rename from ir/src/main/scala/org/scalajs/core/ir/IRVersionNotSupportedException.scala rename to ir/src/main/scala/org/scalajs/ir/IRVersionNotSupportedException.scala index 5f44836906..c282e91dfd 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/IRVersionNotSupportedException.scala +++ b/ir/src/main/scala/org/scalajs/ir/IRVersionNotSupportedException.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.ir +package org.scalajs.ir import java.io.IOException diff --git a/ir/src/main/scala/org/scalajs/core/ir/InvalidIRException.scala b/ir/src/main/scala/org/scalajs/ir/InvalidIRException.scala similarity index 77% rename from ir/src/main/scala/org/scalajs/core/ir/InvalidIRException.scala rename to ir/src/main/scala/org/scalajs/ir/InvalidIRException.scala index 9805565300..211d4276cb 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/InvalidIRException.scala +++ b/ir/src/main/scala/org/scalajs/ir/InvalidIRException.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.ir +package org.scalajs.ir class InvalidIRException(val tree: Trees.Tree, message: String) extends Exception(message) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Position.scala b/ir/src/main/scala/org/scalajs/ir/Position.scala similarity index 98% rename from ir/src/main/scala/org/scalajs/core/ir/Position.scala rename to ir/src/main/scala/org/scalajs/ir/Position.scala index 4275b93cda..5953c134eb 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Position.scala +++ b/ir/src/main/scala/org/scalajs/ir/Position.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.ir +package org.scalajs.ir final case class Position( /** Source file. */ diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/ir/Printers.scala similarity index 99% rename from ir/src/main/scala/org/scalajs/core/ir/Printers.scala rename to ir/src/main/scala/org/scalajs/ir/Printers.scala index ed9c71e413..e3a2602cfa 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/ir/Printers.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.ir +package org.scalajs.ir import scala.annotation.switch diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala similarity index 97% rename from ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala rename to ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala index f7c6b68c58..73a88b396c 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.ir +package org.scalajs.ir object ScalaJSVersions { diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/ir/Serializers.scala similarity index 99% rename from ir/src/main/scala/org/scalajs/core/ir/Serializers.scala rename to ir/src/main/scala/org/scalajs/ir/Serializers.scala index 0a0517db71..e535bd13e8 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/ir/Serializers.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.ir +package org.scalajs.ir import scala.annotation.switch diff --git a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala b/ir/src/main/scala/org/scalajs/ir/Tags.scala similarity index 99% rename from ir/src/main/scala/org/scalajs/core/ir/Tags.scala rename to ir/src/main/scala/org/scalajs/ir/Tags.scala index 7a02c2b6f4..5bc24f0a11 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/ir/Tags.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.ir +package org.scalajs.ir /** Serialization and hashing tags for trees and types */ private[ir] object Tags { diff --git a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala b/ir/src/main/scala/org/scalajs/ir/Transformers.scala similarity index 99% rename from ir/src/main/scala/org/scalajs/core/ir/Transformers.scala rename to ir/src/main/scala/org/scalajs/ir/Transformers.scala index c13d8d8104..f29eff9902 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala +++ b/ir/src/main/scala/org/scalajs/ir/Transformers.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.ir +package org.scalajs.ir import Trees._ diff --git a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala b/ir/src/main/scala/org/scalajs/ir/Traversers.scala similarity index 99% rename from ir/src/main/scala/org/scalajs/core/ir/Traversers.scala rename to ir/src/main/scala/org/scalajs/ir/Traversers.scala index 359809f829..8ea7eee6fb 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala +++ b/ir/src/main/scala/org/scalajs/ir/Traversers.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.ir +package org.scalajs.ir import Trees._ diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/ir/Trees.scala similarity index 99% rename from ir/src/main/scala/org/scalajs/core/ir/Trees.scala rename to ir/src/main/scala/org/scalajs/ir/Trees.scala index ebaba19984..b0c605acda 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/ir/Trees.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.ir +package org.scalajs.ir import scala.annotation.switch diff --git a/ir/src/main/scala/org/scalajs/core/ir/Types.scala b/ir/src/main/scala/org/scalajs/ir/Types.scala similarity index 99% rename from ir/src/main/scala/org/scalajs/core/ir/Types.scala rename to ir/src/main/scala/org/scalajs/ir/Types.scala index 0700aeead3..43365da493 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Types.scala +++ b/ir/src/main/scala/org/scalajs/ir/Types.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.ir +package org.scalajs.ir import scala.annotation.tailrec diff --git a/ir/src/main/scala/org/scalajs/core/ir/Utils.scala b/ir/src/main/scala/org/scalajs/ir/Utils.scala similarity index 99% rename from ir/src/main/scala/org/scalajs/core/ir/Utils.scala rename to ir/src/main/scala/org/scalajs/ir/Utils.scala index f4bdcae342..4294bb32d5 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Utils.scala +++ b/ir/src/main/scala/org/scalajs/ir/Utils.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.ir +package org.scalajs.ir import java.io.StringWriter diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/ir/PrintersTest.scala similarity index 99% rename from ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala rename to ir/src/test/scala/org/scalajs/ir/PrintersTest.scala index 360a235471..b32ccf02aa 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/ir/PrintersTest.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.ir +package org.scalajs.ir import scala.language.implicitConversions diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/AsyncTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/AsyncTests.scala index a571573d5b..f3dc0bb650 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/AsyncTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/AsyncTests.scala @@ -2,8 +2,8 @@ package org.scalajs.jsenv.test import org.scalajs.jsenv._ -import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.logging._ +import org.scalajs.io._ +import org.scalajs.logging._ import org.junit.Test import org.junit.Assert._ diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala index 5959156b76..b8f7d442dc 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala @@ -2,7 +2,7 @@ package org.scalajs.jsenv.test import org.scalajs.jsenv._ -import org.scalajs.core.tools.io._ +import org.scalajs.io._ import org.junit.Test import org.junit.Assert._ diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/CustomInitFilesTest.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/CustomInitFilesTest.scala index 9e2e5e0b62..2055dee32d 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/CustomInitFilesTest.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/CustomInitFilesTest.scala @@ -1,6 +1,6 @@ package org.scalajs.jsenv.test -import org.scalajs.core.tools.io._ +import org.scalajs.io._ import org.junit.Test diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvTest.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvTest.scala index 7d6adb78fd..61c6ce781f 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvTest.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvTest.scala @@ -2,8 +2,8 @@ package org.scalajs.jsenv.test import org.scalajs.jsenv._ -import org.scalajs.core.tools.io.MemVirtualJSFile -import org.scalajs.core.tools.logging._ +import org.scalajs.io.MemVirtualJSFile +import org.scalajs.logging._ import org.junit.Assert._ diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/StoreLogger.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/StoreLogger.scala index 5d97dc314e..254703f91f 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/StoreLogger.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/StoreLogger.scala @@ -1,6 +1,6 @@ package org.scalajs.jsenv.test -import org.scalajs.core.tools.logging._ +import org.scalajs.logging._ import scala.collection.mutable.ListBuffer diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSEnv.scala index d3893851ea..4777c4600e 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSEnv.scala @@ -9,7 +9,7 @@ package org.scalajs.jsenv -import org.scalajs.core.tools.io.VirtualJSFile +import org.scalajs.io.VirtualJSFile trait AsyncJSEnv extends JSEnv { def asyncRunner(files: Seq[VirtualJSFile]): AsyncJSRunner diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSRunner.scala b/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSRunner.scala index 06619bd8e3..37d45e4523 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSRunner.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSRunner.scala @@ -3,7 +3,7 @@ package org.scalajs.jsenv import scala.concurrent.{Future, Await} import scala.concurrent.duration.Duration -import org.scalajs.core.tools.logging.Logger +import org.scalajs.logging.Logger trait AsyncJSRunner { diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/ComJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/ComJSEnv.scala index b0fb295730..3aeeed2b19 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/ComJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/ComJSEnv.scala @@ -9,7 +9,7 @@ package org.scalajs.jsenv -import org.scalajs.core.tools.io.VirtualJSFile +import org.scalajs.io.VirtualJSFile /** An [[AsyncJSEnv]] that provides communication to and from the JS VM. * diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala index d8132bab3d..064ced475c 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala @@ -2,8 +2,8 @@ package org.scalajs.jsenv import scala.collection.immutable -import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.logging.Logger +import org.scalajs.io._ +import org.scalajs.logging.Logger import java.io.{ Console => _, _ } import scala.io.Source diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala index 9d86183fcf..c7fb0c5412 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala @@ -9,7 +9,7 @@ package org.scalajs.jsenv -import org.scalajs.core.tools.io.VirtualJSFile +import org.scalajs.io.VirtualJSFile trait JSEnv { /** Human-readable name for this [[JSEnv]] */ diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/JSInitFiles.scala b/js-envs/src/main/scala/org/scalajs/jsenv/JSInitFiles.scala index fad9e12066..118ce43251 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/JSInitFiles.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/JSInitFiles.scala @@ -1,6 +1,6 @@ package org.scalajs.jsenv -import org.scalajs.core.tools.io.VirtualJSFile +import org.scalajs.io.VirtualJSFile trait JSInitFiles { /** JS files used to setup VM */ diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/JSRunner.scala b/js-envs/src/main/scala/org/scalajs/jsenv/JSRunner.scala index 7d2b5b6fc2..8981947ba9 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/JSRunner.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/JSRunner.scala @@ -9,7 +9,7 @@ package org.scalajs.jsenv -import org.scalajs.core.tools.logging.Logger +import org.scalajs.logging.Logger trait JSRunner { /** Run the associated JS code. Throw if an error occurs. */ diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/VirtualFileMaterializer.scala b/js-envs/src/main/scala/org/scalajs/jsenv/VirtualFileMaterializer.scala index 1f25a92044..604f2dff30 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/VirtualFileMaterializer.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/VirtualFileMaterializer.scala @@ -2,7 +2,7 @@ package org.scalajs.jsenv import scala.annotation.tailrec -import org.scalajs.core.tools.io._ +import org.scalajs.io._ import java.io.File diff --git a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala index a461565c39..89f838a7c6 100644 --- a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala +++ b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala @@ -93,7 +93,7 @@ class ScalaJSJUnitPlugin(val global: Global) extends NscPlugin { def registerModuleExports(sym: ScalaJSJUnitPluginComponent.global.Symbol): Unit } global.plugins.collectFirst { - case pl if pl.getClass.getName == "org.scalajs.core.compiler.ScalaJSPlugin" => + case pl if pl.getClass.getName == "org.scalajs.nscplugin.ScalaJSPlugin" => pl.asInstanceOf[ScalaJSPlugin] }.getOrElse { throw new Exception( diff --git a/linker/js/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala b/linker/js/src/main/scala/org/scalajs/linker/StandardLinkerPlatformExtensions.scala similarity index 96% rename from linker/js/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala rename to linker/js/src/main/scala/org/scalajs/linker/StandardLinkerPlatformExtensions.scala index 32940c7d01..3c53e70da2 100644 --- a/linker/js/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala +++ b/linker/js/src/main/scala/org/scalajs/linker/StandardLinkerPlatformExtensions.scala @@ -6,7 +6,7 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.linker +package org.scalajs.linker object StandardLinkerPlatformExtensions { import StandardLinker.Config diff --git a/linker/js/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatform.scala b/linker/js/src/main/scala/org/scalajs/linker/backend/LinkerBackendPlatform.scala similarity index 93% rename from linker/js/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatform.scala rename to linker/js/src/main/scala/org/scalajs/linker/backend/LinkerBackendPlatform.scala index 51c713e218..8e42009e9c 100644 --- a/linker/js/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatform.scala +++ b/linker/js/src/main/scala/org/scalajs/linker/backend/LinkerBackendPlatform.scala @@ -6,7 +6,7 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.linker.backend +package org.scalajs.linker.backend private[backend] object LinkerBackendPlatform { import LinkerBackend.Config diff --git a/linker/js/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatformExtensions.scala b/linker/js/src/main/scala/org/scalajs/linker/backend/LinkerBackendPlatformExtensions.scala similarity index 95% rename from linker/js/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatformExtensions.scala rename to linker/js/src/main/scala/org/scalajs/linker/backend/LinkerBackendPlatformExtensions.scala index b8359ced34..6b73f6b927 100644 --- a/linker/js/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatformExtensions.scala +++ b/linker/js/src/main/scala/org/scalajs/linker/backend/LinkerBackendPlatformExtensions.scala @@ -6,7 +6,7 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.linker.backend +package org.scalajs.linker.backend object LinkerBackendPlatformExtensions { import LinkerBackend.Config diff --git a/linker/js/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontendPlatform.scala b/linker/js/src/main/scala/org/scalajs/linker/frontend/LinkerFrontendPlatform.scala similarity index 88% rename from linker/js/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontendPlatform.scala rename to linker/js/src/main/scala/org/scalajs/linker/frontend/LinkerFrontendPlatform.scala index eded409bd7..d59142760b 100644 --- a/linker/js/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontendPlatform.scala +++ b/linker/js/src/main/scala/org/scalajs/linker/frontend/LinkerFrontendPlatform.scala @@ -6,9 +6,9 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.linker.frontend +package org.scalajs.linker.frontend -import org.scalajs.core.tools.linker.frontend.optimizer._ +import org.scalajs.linker.frontend.optimizer._ private[frontend] object LinkerFrontendPlatform { import LinkerFrontend.Config diff --git a/linker/js/src/main/scala/org/scalajs/core/tools/linker/irio/NodeVirtualIRFiles.scala b/linker/js/src/main/scala/org/scalajs/linker/irio/NodeVirtualIRFiles.scala similarity index 89% rename from linker/js/src/main/scala/org/scalajs/core/tools/linker/irio/NodeVirtualIRFiles.scala rename to linker/js/src/main/scala/org/scalajs/linker/irio/NodeVirtualIRFiles.scala index ad7ed0102c..944633f4fc 100644 --- a/linker/js/src/main/scala/org/scalajs/core/tools/linker/irio/NodeVirtualIRFiles.scala +++ b/linker/js/src/main/scala/org/scalajs/linker/irio/NodeVirtualIRFiles.scala @@ -6,9 +6,9 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.linker.irio +package org.scalajs.linker.irio -import org.scalajs.core.tools.io._ +import org.scalajs.io._ class NodeVirtualScalaJSIRFile(p: String) extends NodeVirtualBinaryFile(p) with VirtualSerializedScalaJSIRFile diff --git a/linker/js/src/test/scala/org/scalajs/core/tools/linker/test/QuickLinker.scala b/linker/js/src/test/scala/org/scalajs/linker/test/QuickLinker.scala similarity index 93% rename from linker/js/src/test/scala/org/scalajs/core/tools/linker/test/QuickLinker.scala rename to linker/js/src/test/scala/org/scalajs/linker/test/QuickLinker.scala index 81cb6784f5..5e5b34c955 100644 --- a/linker/js/src/test/scala/org/scalajs/core/tools/linker/test/QuickLinker.scala +++ b/linker/js/src/test/scala/org/scalajs/linker/test/QuickLinker.scala @@ -1,16 +1,16 @@ -package org.scalajs.core.tools.linker.test +package org.scalajs.linker.test import scala.scalajs.js import scala.scalajs.js.annotation._ -import org.scalajs.core.tools.io._ +import org.scalajs.io._ -import org.scalajs.core.tools.logging._ +import org.scalajs.logging._ -import org.scalajs.core.tools.linker._ -import org.scalajs.core.tools.linker.irio._ +import org.scalajs.linker._ +import org.scalajs.linker.irio._ -import org.scalajs.core.tools.linker.testutils.Platform +import org.scalajs.linker.testutils.Platform @JSExportTopLevel("scalajs.QuickLinker") object QuickLinker { diff --git a/linker/js/src/test/scala/org/scalajs/core/tools/linker/testutils/NodeVirtualJarFile.scala b/linker/js/src/test/scala/org/scalajs/linker/testutils/NodeVirtualJarFile.scala similarity index 94% rename from linker/js/src/test/scala/org/scalajs/core/tools/linker/testutils/NodeVirtualJarFile.scala rename to linker/js/src/test/scala/org/scalajs/linker/testutils/NodeVirtualJarFile.scala index a73ee59bd0..60d107a7da 100644 --- a/linker/js/src/test/scala/org/scalajs/core/tools/linker/testutils/NodeVirtualJarFile.scala +++ b/linker/js/src/test/scala/org/scalajs/linker/testutils/NodeVirtualJarFile.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.tools.linker.testutils +package org.scalajs.linker.testutils import java.io.InputStream @@ -6,9 +6,9 @@ import scala.scalajs.js import scala.scalajs.js.annotation._ import scala.scalajs.js.typedarray._ -import org.scalajs.core.tools.io._ +import org.scalajs.io._ -import org.scalajs.core.tools.linker.irio._ +import org.scalajs.linker.irio._ class NodeVirtualJarFile(file: String) extends NodeVirtualBinaryFile(file) with VirtualFileContainer { diff --git a/linker/js/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala b/linker/js/src/test/scala/org/scalajs/linker/testutils/Platform.scala similarity index 56% rename from linker/js/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala rename to linker/js/src/test/scala/org/scalajs/linker/testutils/Platform.scala index 90832d919e..cc08544fa2 100644 --- a/linker/js/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala +++ b/linker/js/src/test/scala/org/scalajs/linker/testutils/Platform.scala @@ -1,6 +1,6 @@ -package org.scalajs.core.tools.linker.testutils +package org.scalajs.linker.testutils -import org.scalajs.core.tools.linker.irio._ +import org.scalajs.linker.irio._ object Platform { def loadJar(path: String): ScalaJSIRContainer = diff --git a/linker/jvm/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala b/linker/jvm/src/main/scala/org/scalajs/linker/StandardLinkerPlatformExtensions.scala similarity index 96% rename from linker/jvm/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala rename to linker/jvm/src/main/scala/org/scalajs/linker/StandardLinkerPlatformExtensions.scala index 7a130341b4..d2e335cd64 100644 --- a/linker/jvm/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/StandardLinkerPlatformExtensions.scala @@ -6,7 +6,7 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.linker +package org.scalajs.linker object StandardLinkerPlatformExtensions { import StandardLinker.Config diff --git a/linker/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatform.scala b/linker/jvm/src/main/scala/org/scalajs/linker/backend/LinkerBackendPlatform.scala similarity index 86% rename from linker/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatform.scala rename to linker/jvm/src/main/scala/org/scalajs/linker/backend/LinkerBackendPlatform.scala index b44d9a34c4..c2aa7a7f56 100644 --- a/linker/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatform.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/backend/LinkerBackendPlatform.scala @@ -6,9 +6,9 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.linker.backend +package org.scalajs.linker.backend -import org.scalajs.core.tools.linker.backend.closure.ClosureLinkerBackend +import org.scalajs.linker.backend.closure.ClosureLinkerBackend private[backend] object LinkerBackendPlatform { import LinkerBackend.Config diff --git a/linker/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatformExtensions.scala b/linker/jvm/src/main/scala/org/scalajs/linker/backend/LinkerBackendPlatformExtensions.scala similarity index 89% rename from linker/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatformExtensions.scala rename to linker/jvm/src/main/scala/org/scalajs/linker/backend/LinkerBackendPlatformExtensions.scala index 5310187546..3f9c5edd7e 100644 --- a/linker/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackendPlatformExtensions.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/backend/LinkerBackendPlatformExtensions.scala @@ -6,9 +6,9 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.linker.backend +package org.scalajs.linker.backend -import org.scalajs.core.tools.linker.backend.closure.ClosureLinkerBackend +import org.scalajs.linker.backend.closure.ClosureLinkerBackend object LinkerBackendPlatformExtensions { import LinkerBackend.Config diff --git a/linker/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstBuilder.scala b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureAstBuilder.scala similarity index 84% rename from linker/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstBuilder.scala rename to linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureAstBuilder.scala index f48077bdb4..ff9e04b875 100644 --- a/linker/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstBuilder.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureAstBuilder.scala @@ -1,10 +1,10 @@ -package org.scalajs.core.tools.linker.backend.closure +package org.scalajs.linker.backend.closure -import org.scalajs.core.ir +import org.scalajs.ir import ir.Position.NoPosition -import org.scalajs.core.tools.linker.backend.javascript.Trees.Tree -import org.scalajs.core.tools.linker.backend.javascript.JSTreeBuilder +import org.scalajs.linker.backend.javascript.Trees.Tree +import org.scalajs.linker.backend.javascript.JSTreeBuilder import com.google.javascript.rhino._ import com.google.javascript.jscomp._ diff --git a/linker/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureAstTransformer.scala similarity index 98% rename from linker/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala rename to linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureAstTransformer.scala index cfc6f674c0..921e69f788 100644 --- a/linker/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureAstTransformer.scala @@ -1,12 +1,12 @@ -package org.scalajs.core.tools.linker.backend.closure +package org.scalajs.linker.backend.closure import scala.annotation.switch -import org.scalajs.core.ir +import org.scalajs.ir import ir.Position import ir.Position.NoPosition -import org.scalajs.core.tools.linker.backend.javascript.Trees._ +import org.scalajs.linker.backend.javascript.Trees._ import com.google.javascript.rhino._ import com.google.javascript.jscomp._ @@ -343,7 +343,7 @@ private[closure] class ClosureAstTransformer(relativizeBaseURI: Option[URI]) { } private def sourceUriToString(uri: URI): String = { - import org.scalajs.core.tools.io.URIUtils._ + import org.scalajs.io.URIUtils._ val relURI = relativizeBaseURI.fold(uri)(relativize(_, uri)) fixFileURI(relURI).toASCIIString diff --git a/linker/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala similarity index 93% rename from linker/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala rename to linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala index 1abac71f7b..71585dcf82 100644 --- a/linker/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.linker.backend.closure +package org.scalajs.linker.backend.closure import scala.collection.JavaConverters._ @@ -18,14 +18,14 @@ import com.google.javascript.jscomp.{ _ } -import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.logging.Logger +import org.scalajs.io._ +import org.scalajs.logging.Logger -import org.scalajs.core.tools.linker._ -import org.scalajs.core.tools.linker.standard._ -import org.scalajs.core.tools.linker.analyzer.SymbolRequirement -import org.scalajs.core.tools.linker.backend._ -import org.scalajs.core.tools.linker.backend.emitter.Emitter +import org.scalajs.linker._ +import org.scalajs.linker.standard._ +import org.scalajs.linker.analyzer.SymbolRequirement +import org.scalajs.linker.backend._ +import org.scalajs.linker.backend.emitter.Emitter /** The Closure backend of the Scala.js linker. * @@ -102,7 +102,7 @@ final class ClosureLinkerBackend(config: LinkerBackend.Config) * This is necessary to avoid name clashes with renamed properties (#2491). */ private def makeExternsForExports(linkingUnit: LinkingUnit): VirtualJSFile = { - import org.scalajs.core.ir.Trees._ + import org.scalajs.ir.Trees._ def exportName(memberDef: MemberDef): Option[String] = memberDef match { case MethodDef(_, StringLiteral(name), _, _, _) => Some(name) diff --git a/linker/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/LoggerErrorManager.scala b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/LoggerErrorManager.scala similarity index 92% rename from linker/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/LoggerErrorManager.scala rename to linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/LoggerErrorManager.scala index ba25453aff..3891e0de2f 100644 --- a/linker/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/LoggerErrorManager.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/LoggerErrorManager.scala @@ -1,8 +1,8 @@ -package org.scalajs.core.tools.linker.backend.closure +package org.scalajs.linker.backend.closure import com.google.javascript.jscomp.{ BasicErrorManager, CheckLevel, JSError } -import org.scalajs.core.tools.logging.Logger +import org.scalajs.logging.Logger /** A Google Closure Error Manager that forwards to a tools.logging.Logger */ private[closure] class LoggerErrorManager(private val log: Logger) diff --git a/linker/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontendPlatform.scala b/linker/jvm/src/main/scala/org/scalajs/linker/frontend/LinkerFrontendPlatform.scala similarity index 89% rename from linker/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontendPlatform.scala rename to linker/jvm/src/main/scala/org/scalajs/linker/frontend/LinkerFrontendPlatform.scala index ba4c3ecaa4..8115ea8710 100644 --- a/linker/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontendPlatform.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/frontend/LinkerFrontendPlatform.scala @@ -6,9 +6,9 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.linker.frontend +package org.scalajs.linker.frontend -import org.scalajs.core.tools.linker.frontend.optimizer._ +import org.scalajs.linker.frontend.optimizer._ private[frontend] object LinkerFrontendPlatform { import LinkerFrontend.Config diff --git a/linker/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ConcurrencyUtils.scala b/linker/jvm/src/main/scala/org/scalajs/linker/frontend/optimizer/ConcurrencyUtils.scala similarity index 97% rename from linker/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ConcurrencyUtils.scala rename to linker/jvm/src/main/scala/org/scalajs/linker/frontend/optimizer/ConcurrencyUtils.scala index ba9bae6678..1a8aba088f 100644 --- a/linker/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ConcurrencyUtils.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/frontend/optimizer/ConcurrencyUtils.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.linker.frontend.optimizer +package org.scalajs.linker.frontend.optimizer import scala.annotation.tailrec diff --git a/linker/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ParIncOptimizer.scala b/linker/jvm/src/main/scala/org/scalajs/linker/frontend/optimizer/ParIncOptimizer.scala similarity index 98% rename from linker/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ParIncOptimizer.scala rename to linker/jvm/src/main/scala/org/scalajs/linker/frontend/optimizer/ParIncOptimizer.scala index ec1614d938..996c283e3c 100644 --- a/linker/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ParIncOptimizer.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/frontend/optimizer/ParIncOptimizer.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.linker.frontend.optimizer +package org.scalajs.linker.frontend.optimizer import scala.collection.{GenTraversableOnce, GenIterable} import scala.collection.concurrent.TrieMap @@ -16,7 +16,7 @@ import scala.collection.parallel._ import java.util.concurrent.atomic._ -import org.scalajs.core.tools.linker.standard._ +import org.scalajs.linker.standard._ import ConcurrencyUtils._ diff --git a/linker/jvm/src/main/scala/org/scalajs/core/tools/linker/irio/FileVirtualIRFiles.scala b/linker/jvm/src/main/scala/org/scalajs/linker/irio/FileVirtualIRFiles.scala similarity index 96% rename from linker/jvm/src/main/scala/org/scalajs/core/tools/linker/irio/FileVirtualIRFiles.scala rename to linker/jvm/src/main/scala/org/scalajs/linker/irio/FileVirtualIRFiles.scala index c94231f548..d6feb0a944 100644 --- a/linker/jvm/src/main/scala/org/scalajs/core/tools/linker/irio/FileVirtualIRFiles.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/irio/FileVirtualIRFiles.scala @@ -6,11 +6,11 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.linker.irio +package org.scalajs.linker.irio import java.io._ -import org.scalajs.core.tools.io._ +import org.scalajs.io._ class FileVirtualScalaJSIRFile(f: File) extends FileVirtualBinaryFile(f) with VirtualSerializedScalaJSIRFile diff --git a/linker/jvm/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala b/linker/jvm/src/test/scala/org/scalajs/linker/testutils/Platform.scala similarity index 61% rename from linker/jvm/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala rename to linker/jvm/src/test/scala/org/scalajs/linker/testutils/Platform.scala index 7b6f8d47a2..b23c23ff1c 100644 --- a/linker/jvm/src/test/scala/org/scalajs/core/tools/linker/testutils/Platform.scala +++ b/linker/jvm/src/test/scala/org/scalajs/linker/testutils/Platform.scala @@ -1,8 +1,8 @@ -package org.scalajs.core.tools.linker.testutils +package org.scalajs.linker.testutils import java.io.File -import org.scalajs.core.tools.linker.irio._ +import org.scalajs.linker.irio._ object Platform { def loadJar(path: String): ScalaJSIRContainer = diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/CheckedBehavior.scala b/linker/shared/src/main/scala/org/scalajs/linker/CheckedBehavior.scala similarity index 95% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/CheckedBehavior.scala rename to linker/shared/src/main/scala/org/scalajs/linker/CheckedBehavior.scala index c813603f66..7473f17c06 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/CheckedBehavior.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/CheckedBehavior.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.linker +package org.scalajs.linker sealed abstract class CheckedBehavior { import CheckedBehavior._ diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/ClearableLinker.scala b/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala similarity index 89% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/ClearableLinker.scala rename to linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala index 4858fcf35a..319c49344a 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/ClearableLinker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala @@ -7,13 +7,13 @@ \* */ -package org.scalajs.core.tools.linker +package org.scalajs.linker -import org.scalajs.core.tools.logging.Logger -import org.scalajs.core.tools.io._ +import org.scalajs.logging.Logger +import org.scalajs.io._ -import org.scalajs.core.tools.linker.analyzer.SymbolRequirement -import org.scalajs.core.tools.linker.irio._ +import org.scalajs.linker.analyzer.SymbolRequirement +import org.scalajs.linker.irio._ /** A box around a [[GenLinker]] to support clearing. * diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala b/linker/shared/src/main/scala/org/scalajs/linker/GenLinker.scala similarity index 81% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala rename to linker/shared/src/main/scala/org/scalajs/linker/GenLinker.scala index 5e7b0d764f..ce477ae2c4 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/GenLinker.scala @@ -7,13 +7,13 @@ \* */ -package org.scalajs.core.tools.linker +package org.scalajs.linker -import org.scalajs.core.tools.logging.Logger -import org.scalajs.core.tools.io._ +import org.scalajs.logging.Logger +import org.scalajs.io._ -import org.scalajs.core.tools.linker.analyzer.SymbolRequirement -import org.scalajs.core.tools.linker.irio._ +import org.scalajs.linker.analyzer.SymbolRequirement +import org.scalajs.linker.irio._ /** Common supertrait of [[Linker]] and [[ClearableLinker]]. * diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala b/linker/shared/src/main/scala/org/scalajs/linker/LinkedClass.scala similarity index 98% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala rename to linker/shared/src/main/scala/org/scalajs/linker/LinkedClass.scala index 698f14297f..9ebbf4112e 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/LinkedClass.scala @@ -7,11 +7,11 @@ \* */ -package org.scalajs.core.tools.linker +package org.scalajs.linker import scala.collection.mutable -import org.scalajs.core.ir +import org.scalajs.ir import ir.Trees._ import ir.Position import ir.ClassKind diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala b/linker/shared/src/main/scala/org/scalajs/linker/Linker.scala similarity index 81% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala rename to linker/shared/src/main/scala/org/scalajs/linker/Linker.scala index 08fdee8a85..1ad0ff3869 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/Linker.scala @@ -7,21 +7,21 @@ \* */ -package org.scalajs.core.tools.linker +package org.scalajs.linker import scala.language.implicitConversions import java.util.concurrent.atomic.AtomicBoolean -import org.scalajs.core.tools.logging.Logger -import org.scalajs.core.tools.io._ +import org.scalajs.logging.Logger +import org.scalajs.io._ -import org.scalajs.core.tools.linker.standard._ -import org.scalajs.core.tools.linker.analyzer.SymbolRequirement -import org.scalajs.core.tools.linker.frontend.LinkerFrontend -import org.scalajs.core.tools.linker.frontend.optimizer.IncOptimizer -import org.scalajs.core.tools.linker.backend.{LinkerBackend, BasicLinkerBackend} -import org.scalajs.core.tools.linker.irio._ +import org.scalajs.linker.standard._ +import org.scalajs.linker.analyzer.SymbolRequirement +import org.scalajs.linker.frontend.LinkerFrontend +import org.scalajs.linker.frontend.optimizer.IncOptimizer +import org.scalajs.linker.backend.{LinkerBackend, BasicLinkerBackend} +import org.scalajs.linker.irio._ /** The Scala.js linker */ final class Linker private (frontend: LinkerFrontend, backend: LinkerBackend) diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingException.scala b/linker/shared/src/main/scala/org/scalajs/linker/LinkingException.scala similarity index 95% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingException.scala rename to linker/shared/src/main/scala/org/scalajs/linker/LinkingException.scala index 4d6e8a93a7..9513b4b58b 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingException.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/LinkingException.scala @@ -6,7 +6,7 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.linker +package org.scalajs.linker /** Thrown by the linker when linking cannot be performed. */ class LinkingException(message: String, cause: Throwable) diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala b/linker/shared/src/main/scala/org/scalajs/linker/LinkingUnit.scala similarity index 65% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala rename to linker/shared/src/main/scala/org/scalajs/linker/LinkingUnit.scala index 6db0dbd0ce..f96855ed79 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/LinkingUnit.scala @@ -1,6 +1,6 @@ -package org.scalajs.core.tools.linker +package org.scalajs.linker -import org.scalajs.core.tools.linker.standard._ +import org.scalajs.linker.standard._ final class LinkingUnit private[linker] ( val coreSpec: CoreSpec, diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/ModuleInitializer.scala b/linker/shared/src/main/scala/org/scalajs/linker/ModuleInitializer.scala similarity index 95% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/ModuleInitializer.scala rename to linker/shared/src/main/scala/org/scalajs/linker/ModuleInitializer.scala index 7189519f01..77395006e0 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/ModuleInitializer.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/ModuleInitializer.scala @@ -6,12 +6,12 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.linker +package org.scalajs.linker -import org.scalajs.core.ir.Definitions._ -import org.scalajs.core.ir.Types.ClassType +import org.scalajs.ir.Definitions._ +import org.scalajs.ir.Types.ClassType -import org.scalajs.core.tools.linker.analyzer.SymbolRequirement +import org.scalajs.linker.analyzer.SymbolRequirement /** A module initializer for a Scala.js application. * diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/ModuleKind.scala b/linker/shared/src/main/scala/org/scalajs/linker/ModuleKind.scala similarity index 97% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/ModuleKind.scala rename to linker/shared/src/main/scala/org/scalajs/linker/ModuleKind.scala index e6d3d21d0e..459c89078f 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/ModuleKind.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/ModuleKind.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.linker +package org.scalajs.linker /** Kind of module structure emitted for the Scala.js output. */ sealed abstract class ModuleKind diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/Semantics.scala b/linker/shared/src/main/scala/org/scalajs/linker/Semantics.scala similarity index 98% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/Semantics.scala rename to linker/shared/src/main/scala/org/scalajs/linker/Semantics.scala index a554803e8c..453197075d 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/Semantics.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/Semantics.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.linker +package org.scalajs.linker import scala.collection.immutable.Traversable @@ -112,7 +112,7 @@ object Semantics { def andThen(that: RuntimeClassNameMapper): RuntimeClassNameMapper = AndThen(this, that) - private[tools] def apply(linkedClass: LinkedClass): String = { + private[linker] def apply(linkedClass: LinkedClass): String = { def rec(mapper: RuntimeClassNameMapper, className: String): String = { mapper match { case KeepAll => diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/StandardLinker.scala b/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala similarity index 95% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/StandardLinker.scala rename to linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala index 03d6514bde..c0f737668b 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/StandardLinker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala @@ -6,15 +6,15 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.linker +package org.scalajs.linker import scala.language.implicitConversions import java.net.URI -import org.scalajs.core.tools.linker.standard._ -import org.scalajs.core.tools.linker.frontend.LinkerFrontend -import org.scalajs.core.tools.linker.backend.LinkerBackend +import org.scalajs.linker.standard._ +import org.scalajs.linker.frontend.LinkerFrontend +import org.scalajs.linker.backend.LinkerBackend object StandardLinker { import StandardLinkerPlatformExtensions._ @@ -202,10 +202,10 @@ object StandardLinker { * * The following additional options are configurable through * {{{ - * import org.scalajs.core.tools.linker.standard._ + * import org.scalajs.linker.standard._ * }}} * - * - `outputMode`: [[org.scalajs.core.tools.linker.standard.OutputMode.Default OutputMode.Default]] + * - `outputMode`: [[org.scalajs.linker.standard.OutputMode.Default OutputMode.Default]] */ def apply(): Config = new Config() } diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/Versioned.scala b/linker/shared/src/main/scala/org/scalajs/linker/Versioned.scala similarity index 94% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/Versioned.scala rename to linker/shared/src/main/scala/org/scalajs/linker/Versioned.scala index b084af24f3..8ada27bf5e 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/Versioned.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/Versioned.scala @@ -6,9 +6,9 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.linker +package org.scalajs.linker -import org.scalajs.core.ir +import org.scalajs.ir import ir.Trees._ /** A versioned thing, accompanied by its version. diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala b/linker/shared/src/main/scala/org/scalajs/linker/analyzer/Analysis.scala similarity index 98% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala rename to linker/shared/src/main/scala/org/scalajs/linker/analyzer/Analysis.scala index 8664710d84..e54469f808 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/analyzer/Analysis.scala @@ -7,15 +7,15 @@ \* */ -package org.scalajs.core.tools.linker.analyzer +package org.scalajs.linker.analyzer import scala.annotation.tailrec import scala.collection.mutable -import org.scalajs.core.tools.logging._ +import org.scalajs.logging._ -import org.scalajs.core.ir +import org.scalajs.ir import ir.ClassKind import ir.Definitions.{decodeClassName, decodeMethodName} diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala b/linker/shared/src/main/scala/org/scalajs/linker/analyzer/Analyzer.scala similarity index 99% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala rename to linker/shared/src/main/scala/org/scalajs/linker/analyzer/Analyzer.scala index 64c1cd3415..74d210294d 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/analyzer/Analyzer.scala @@ -7,18 +7,18 @@ \* */ -package org.scalajs.core.tools.linker.analyzer +package org.scalajs.linker.analyzer import scala.annotation.tailrec import scala.collection.mutable -import org.scalajs.core.ir +import org.scalajs.ir import ir.{ClassKind, Definitions} import Definitions._ -import org.scalajs.core.tools.linker._ -import org.scalajs.core.tools.linker.standard._ +import org.scalajs.linker._ +import org.scalajs.linker.standard._ import Analysis._ diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala b/linker/shared/src/main/scala/org/scalajs/linker/analyzer/Infos.scala similarity index 96% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala rename to linker/shared/src/main/scala/org/scalajs/linker/analyzer/Infos.scala index 9a4c7e7ef1..c1d725f36a 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Infos.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/analyzer/Infos.scala @@ -7,18 +7,18 @@ \* */ -package org.scalajs.core.tools.linker.analyzer +package org.scalajs.linker.analyzer import scala.collection.mutable -import org.scalajs.core.ir.ClassKind -import org.scalajs.core.ir.Definitions._ -import org.scalajs.core.ir.Traversers._ -import org.scalajs.core.ir.Trees._ -import org.scalajs.core.ir.Types._ +import org.scalajs.ir.ClassKind +import org.scalajs.ir.Definitions._ +import org.scalajs.ir.Traversers._ +import org.scalajs.ir.Trees._ +import org.scalajs.ir.Types._ -import org.scalajs.core.tools.linker.LinkedClass -import org.scalajs.core.tools.linker.backend.emitter.Transients._ +import org.scalajs.linker.LinkedClass +import org.scalajs.linker.backend.emitter.Transients._ object Infos { @@ -305,7 +305,7 @@ object Infos { } /** Generates the [[ClassInfo]] of a - * [[org.scalajs.core.ir.Trees.ClassDef Trees.ClassDef]]. + * [[org.scalajs.ir.Trees.ClassDef Trees.ClassDef]]. */ def generateClassInfo(classDef: ClassDef): ClassInfo = { val builder = new ClassInfoBuilder() @@ -337,13 +337,13 @@ object Infos { } /** Generates the [[MethodInfo]] of a - * [[org.scalajs.core.ir.Trees.MethodDef Trees.MethodDef]]. + * [[org.scalajs.ir.Trees.MethodDef Trees.MethodDef]]. */ def generateMethodInfo(methodDef: MethodDef): MethodInfo = new GenInfoTraverser().generateMethodInfo(methodDef) /** Generates the [[MethodInfo]] of a - * [[org.scalajs.core.ir.Trees.PropertyDef Trees.PropertyDef]]. + * [[org.scalajs.ir.Trees.PropertyDef Trees.PropertyDef]]. */ def generatePropertyInfo(propertyDef: PropertyDef): MethodInfo = new GenInfoTraverser().generatePropertyInfo(propertyDef) diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/SymbolRequirement.scala b/linker/shared/src/main/scala/org/scalajs/linker/analyzer/SymbolRequirement.scala similarity index 98% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/SymbolRequirement.scala rename to linker/shared/src/main/scala/org/scalajs/linker/analyzer/SymbolRequirement.scala index 03244da15c..6ac326fad1 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/SymbolRequirement.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/analyzer/SymbolRequirement.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.linker.analyzer +package org.scalajs.linker.analyzer sealed trait SymbolRequirement { final def ++(that: SymbolRequirement): SymbolRequirement = diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/BasicLinkerBackend.scala similarity index 82% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala rename to linker/shared/src/main/scala/org/scalajs/linker/backend/BasicLinkerBackend.scala index 77e8778479..b614b457e7 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/BasicLinkerBackend.scala @@ -7,16 +7,16 @@ \* */ -package org.scalajs.core.tools.linker.backend +package org.scalajs.linker.backend -import org.scalajs.core.tools.logging.Logger -import org.scalajs.core.tools.io.WritableVirtualJSFile +import org.scalajs.logging.Logger +import org.scalajs.io.WritableVirtualJSFile -import org.scalajs.core.tools.linker.LinkingUnit -import org.scalajs.core.tools.linker.analyzer.SymbolRequirement -import org.scalajs.core.tools.linker.backend.emitter.Emitter +import org.scalajs.linker.LinkingUnit +import org.scalajs.linker.analyzer.SymbolRequirement +import org.scalajs.linker.backend.emitter.Emitter -import org.scalajs.core.tools.linker.backend.javascript.{ +import org.scalajs.linker.backend.javascript.{ JSFileBuilder, JSFileBuilderWithSourceMap } diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/LinkerBackend.scala similarity index 92% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala rename to linker/shared/src/main/scala/org/scalajs/linker/backend/LinkerBackend.scala index b0bbbf8079..e004abc747 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/LinkerBackend.scala @@ -7,21 +7,21 @@ \* */ -package org.scalajs.core.tools.linker.backend +package org.scalajs.linker.backend import scala.language.implicitConversions import java.net.URI -import org.scalajs.core.tools.io.WritableVirtualJSFile -import org.scalajs.core.tools.logging.Logger +import org.scalajs.io.WritableVirtualJSFile +import org.scalajs.logging.Logger -import org.scalajs.core.tools.linker._ -import org.scalajs.core.tools.linker.standard._ -import org.scalajs.core.tools.linker.analyzer.SymbolRequirement +import org.scalajs.linker._ +import org.scalajs.linker.standard._ +import org.scalajs.linker.analyzer.SymbolRequirement /** A backend of the Scala.js linker. Produces a - * [[org.scalajs.core.tools.io.VirtualJSFile VirtualJSFile]]. + * [[org.scalajs.io.VirtualJSFile VirtualJSFile]]. * * You probably want to use an instance of [[linker.Linker]], rather than this * low-level class. diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala similarity index 99% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala rename to linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala index 50eadb59fd..6c24e59fd3 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala @@ -7,17 +7,17 @@ \* */ -package org.scalajs.core.tools.linker.backend.emitter +package org.scalajs.linker.backend.emitter -import org.scalajs.core.ir._ +import org.scalajs.ir._ import Position._ import Transformers._ -import org.scalajs.core.ir.Trees._ +import org.scalajs.ir.Trees._ import Types._ -import org.scalajs.core.tools.linker._ -import org.scalajs.core.tools.linker.standard.OutputMode -import org.scalajs.core.tools.linker.backend.javascript.{Trees => js} +import org.scalajs.linker._ +import org.scalajs.linker.standard.OutputMode +import org.scalajs.linker.backend.javascript.{Trees => js} import CheckedBehavior.Unchecked @@ -668,7 +668,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { } } - private[tools] def needInstanceTests(tree: LinkedClass): Boolean = { + def needInstanceTests(tree: LinkedClass): Boolean = { tree.hasInstanceTests || { tree.hasRuntimeTypeInfo && ClassesWhoseDataReferToTheirInstanceTests.contains(tree.encodedName) diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLibs.scala similarity index 95% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala rename to linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLibs.scala index 499d80ba94..96c39c11e9 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLibs.scala @@ -7,15 +7,15 @@ \* */ -package org.scalajs.core.tools.linker.backend.emitter +package org.scalajs.linker.backend.emitter import java.net.URI -import org.scalajs.core.ir.ScalaJSVersions -import org.scalajs.core.tools.io._ +import org.scalajs.ir.ScalaJSVersions +import org.scalajs.io._ -import org.scalajs.core.tools.linker._ -import org.scalajs.core.tools.linker.standard._ +import org.scalajs.linker._ +import org.scalajs.linker.standard._ import scala.collection.immutable.Seq import scala.collection.mutable diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/Emitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala similarity index 97% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/Emitter.scala rename to linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala index 39913ea396..d044621f71 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/Emitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala @@ -7,23 +7,23 @@ \* */ -package org.scalajs.core.tools.linker.backend.emitter +package org.scalajs.linker.backend.emitter import scala.annotation.tailrec import scala.collection.mutable -import org.scalajs.core.ir.{ClassKind, Position} -import org.scalajs.core.ir.Trees.JSNativeLoadSpec -import org.scalajs.core.ir.Definitions.decodeClassName +import org.scalajs.ir.{ClassKind, Position} +import org.scalajs.ir.Trees.JSNativeLoadSpec +import org.scalajs.ir.Definitions.decodeClassName -import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.logging._ +import org.scalajs.io._ +import org.scalajs.logging._ -import org.scalajs.core.tools.linker._ -import org.scalajs.core.tools.linker.standard._ -import org.scalajs.core.tools.linker.analyzer.SymbolRequirement -import org.scalajs.core.tools.linker.backend.javascript.{Trees => js, _} +import org.scalajs.linker._ +import org.scalajs.linker.standard._ +import org.scalajs.linker.analyzer.SymbolRequirement +import org.scalajs.linker.backend.javascript.{Trees => js, _} import GlobalRefUtils._ diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/FunctionEmitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala similarity index 99% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/FunctionEmitter.scala rename to linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala index 178c7e33c8..b68ab2c950 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/FunctionEmitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala @@ -7,23 +7,23 @@ \* */ -package org.scalajs.core.tools.linker.backend.emitter +package org.scalajs.linker.backend.emitter import scala.annotation.{switch, tailrec} import scala.collection.mutable -import org.scalajs.core.ir +import org.scalajs.ir import ir._ import ir.Position._ import ir.Transformers._ import ir.Trees._ import ir.Types._ -import org.scalajs.core.tools.linker._ -import org.scalajs.core.tools.linker.CheckedBehavior._ -import org.scalajs.core.tools.linker.standard.OutputMode -import org.scalajs.core.tools.linker.backend.javascript.{Trees => js} +import org.scalajs.linker._ +import org.scalajs.linker.CheckedBehavior._ +import org.scalajs.linker.standard.OutputMode +import org.scalajs.linker.backend.javascript.{Trees => js} import java.io.StringWriter diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/GlobalKnowledge.scala similarity index 94% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala rename to linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/GlobalKnowledge.scala index d364a09450..ee85291eab 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/GlobalKnowledge.scala @@ -7,10 +7,10 @@ \* */ -package org.scalajs.core.tools.linker.backend.emitter +package org.scalajs.linker.backend.emitter -import org.scalajs.core.ir.Trees.{FieldDef, JSNativeLoadSpec} -import org.scalajs.core.ir.Types.Type +import org.scalajs.ir.Trees.{FieldDef, JSNativeLoadSpec} +import org.scalajs.ir.Types.Type private[emitter] trait GlobalKnowledge { /** Tests whether the parent class data is accessed in the linking unit. */ diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalRefUtils.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/GlobalRefUtils.scala similarity index 96% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalRefUtils.scala rename to linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/GlobalRefUtils.scala index 5a81217f1a..1702c36822 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalRefUtils.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/GlobalRefUtils.scala @@ -6,9 +6,9 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.linker.backend.emitter +package org.scalajs.linker.backend.emitter -import org.scalajs.core.tools.linker.standard.OutputMode +import org.scalajs.linker.standard.OutputMode /** Utilities related to global refs mentioned in the program. * diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/InternalOptions.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/InternalOptions.scala similarity index 95% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/InternalOptions.scala rename to linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/InternalOptions.scala index 995a1664af..6c134f13b3 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/InternalOptions.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/InternalOptions.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.linker.backend.emitter +package org.scalajs.linker.backend.emitter private[emitter] class InternalOptions private ( val optimizeBracketSelects: Boolean) { diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/JSGen.scala similarity index 98% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala rename to linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/JSGen.scala index 382fbca959..90098daffe 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/JSGen.scala @@ -7,20 +7,20 @@ \* */ -package org.scalajs.core.tools.linker.backend.emitter +package org.scalajs.linker.backend.emitter import scala.language.implicitConversions import scala.annotation.tailrec -import org.scalajs.core.ir +import org.scalajs.ir import ir._ import ir.Types._ import ir.{Trees => irt} -import org.scalajs.core.tools.linker._ -import org.scalajs.core.tools.linker.standard.OutputMode -import org.scalajs.core.tools.linker.backend.javascript.Trees._ +import org.scalajs.linker._ +import org.scalajs.linker.standard.OutputMode +import org.scalajs.linker.backend.javascript.Trees._ /** Collection of tree generators that are used accross the board. * This class is fully stateless. diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/KnowledgeGuardian.scala similarity index 98% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala rename to linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/KnowledgeGuardian.scala index ec459b04ef..938e1b9a1a 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/KnowledgeGuardian.scala @@ -7,15 +7,15 @@ \* */ -package org.scalajs.core.tools.linker.backend.emitter +package org.scalajs.linker.backend.emitter import scala.collection.mutable -import org.scalajs.core.ir.{ClassKind, Definitions} -import org.scalajs.core.ir.Trees._ -import org.scalajs.core.ir.Types.Type +import org.scalajs.ir.{ClassKind, Definitions} +import org.scalajs.ir.Trees._ +import org.scalajs.ir.Types.Type -import org.scalajs.core.tools.linker._ +import org.scalajs.linker._ private[emitter] final class KnowledgeGuardian { import KnowledgeGuardian._ diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/LongImpl.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/LongImpl.scala similarity index 98% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/LongImpl.scala rename to linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/LongImpl.scala index d2b29f30a5..b1d3661d58 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/LongImpl.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/LongImpl.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.linker.backend.emitter +package org.scalajs.linker.backend.emitter private[linker] object LongImpl { final val RuntimeLongClass = "sjsr_RuntimeLong" diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/Transients.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Transients.scala similarity index 87% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/Transients.scala rename to linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Transients.scala index 94e68eade8..5e09cbd316 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/Transients.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Transients.scala @@ -6,10 +6,10 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.linker.backend.emitter +package org.scalajs.linker.backend.emitter -import org.scalajs.core.ir.Trees._ -import org.scalajs.core.ir.Printers._ +import org.scalajs.ir.Trees._ +import org.scalajs.ir.Printers._ object Transients { diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/TreeDSL.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/TreeDSL.scala similarity index 91% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/TreeDSL.scala rename to linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/TreeDSL.scala index da23d58d66..c69560dcda 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/TreeDSL.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/TreeDSL.scala @@ -7,14 +7,14 @@ \* */ -package org.scalajs.core.tools.linker.backend.emitter +package org.scalajs.linker.backend.emitter import scala.language.implicitConversions -import org.scalajs.core.ir -import org.scalajs.core.ir.Position +import org.scalajs.ir +import org.scalajs.ir.Position -import org.scalajs.core.tools.linker.backend.javascript.Trees._ +import org.scalajs.linker.backend.javascript.Trees._ private[emitter] object TreeDSL { implicit class TreeOps private[TreeDSL] (val __private_self: Tree) diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/WithGlobals.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/WithGlobals.scala similarity index 98% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/WithGlobals.scala rename to linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/WithGlobals.scala index ecac8ab68d..eeec1caec8 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/WithGlobals.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/WithGlobals.scala @@ -6,7 +6,7 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.linker.backend.emitter +package org.scalajs.linker.backend.emitter import GlobalRefUtils.unionPreserveEmpty diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/JSBuilders.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/JSBuilders.scala similarity index 97% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/JSBuilders.scala rename to linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/JSBuilders.scala index 269bba78d4..c4ff12d419 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/JSBuilders.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/JSBuilders.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.linker.backend.javascript +package org.scalajs.linker.backend.javascript import scala.annotation.tailrec @@ -17,8 +17,8 @@ import java.io._ import java.util.regex.Pattern import java.net.{ URI, URISyntaxException } -import org.scalajs.core.ir.Position -import org.scalajs.core.tools.io._ +import org.scalajs.ir.Position +import org.scalajs.io._ /** An abstract builder taking IR or JSTrees */ trait JSTreeBuilder { diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Printers.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/Printers.scala similarity index 99% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Printers.scala rename to linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/Printers.scala index 22b8746216..f844192a56 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Printers.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/Printers.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.linker.backend.javascript +package org.scalajs.linker.backend.javascript import scala.annotation.switch @@ -18,12 +18,12 @@ import scala.util.control.Breaks import java.io.Writer -import org.scalajs.core.ir +import org.scalajs.ir import ir.Position import ir.Position.NoPosition import ir.Printers.IndentationManager -import org.scalajs.core.tools.io.JSUtils +import org.scalajs.io.JSUtils import Trees._ diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/SourceMapWriter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/SourceMapWriter.scala similarity index 98% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/SourceMapWriter.scala rename to linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/SourceMapWriter.scala index 39c8d16536..906bad4083 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/SourceMapWriter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/SourceMapWriter.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.linker.backend.javascript +package org.scalajs.linker.backend.javascript import java.io.Writer import java.net.URI @@ -15,12 +15,12 @@ import java.{util => ju} import scala.collection.mutable.{ ListBuffer, HashMap, Stack, StringBuilder } -import org.scalajs.core.ir +import org.scalajs.ir import ir.Position import ir.Position._ import ir.Utils -import org.scalajs.core.tools.io.JSUtils +import org.scalajs.io.JSUtils private object SourceMapWriter { private val Base64Map = @@ -118,7 +118,7 @@ class SourceMapWriter( /** Relatively hacky way to get a Web-friendly URI to the source file */ private def sourceToURI(source: SourceFile): String = { - import org.scalajs.core.tools.io.URIUtils._ + import org.scalajs.io.URIUtils._ val uri = source val relURI = relativizeBaseURI.fold(uri)(relativize(_, uri)) diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Trees.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/Trees.scala similarity index 98% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Trees.scala rename to linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/Trees.scala index d80c004f20..2151ad44ad 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/backend/javascript/Trees.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/Trees.scala @@ -7,11 +7,11 @@ \* */ -package org.scalajs.core.tools.linker.backend.javascript +package org.scalajs.linker.backend.javascript import scala.annotation.switch -import org.scalajs.core.ir +import org.scalajs.ir import ir.Position import ir.Position.NoPosition diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala similarity index 99% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala rename to linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala index be9cac401a..58a9fb600b 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.linker.checker +package org.scalajs.linker.checker // In the IR checker, we allow early returns for improved readability // scalastyle:off return @@ -18,14 +18,14 @@ import scala.annotation.switch import scala.collection.mutable -import org.scalajs.core.ir._ +import org.scalajs.ir._ import Definitions._ import Trees._ import Types._ -import org.scalajs.core.tools.logging._ -import org.scalajs.core.tools.linker.{LinkingUnit, LinkedClass, Versioned} -import org.scalajs.core.tools.linker.analyzer.{Analyzer, Infos} +import org.scalajs.logging._ +import org.scalajs.linker.{LinkingUnit, LinkedClass, Versioned} +import org.scalajs.linker.analyzer.{Analyzer, Infos} /** Checker for the validity of the IR. */ private final class IRChecker(unit: LinkingUnit, diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/linker/shared/src/main/scala/org/scalajs/linker/frontend/BaseLinker.scala similarity index 96% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala rename to linker/shared/src/main/scala/org/scalajs/linker/frontend/BaseLinker.scala index ca1b4e08e2..3b98e75f99 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/frontend/BaseLinker.scala @@ -7,23 +7,23 @@ \* */ -package org.scalajs.core.tools.linker.frontend +package org.scalajs.linker.frontend import scala.annotation.tailrec import scala.collection.mutable import scala.util.Try -import org.scalajs.core.tools.logging._ -import org.scalajs.core.tools.io._ +import org.scalajs.logging._ +import org.scalajs.io._ -import org.scalajs.core.tools.linker._ -import org.scalajs.core.tools.linker.standard._ -import org.scalajs.core.tools.linker.checker._ -import org.scalajs.core.tools.linker.analyzer._ -import org.scalajs.core.tools.linker.irio._ +import org.scalajs.linker._ +import org.scalajs.linker.standard._ +import org.scalajs.linker.checker._ +import org.scalajs.linker.analyzer._ +import org.scalajs.linker.irio._ -import org.scalajs.core.ir +import org.scalajs.ir import ir.Trees._ import ir.Types._ import ir.ClassKind @@ -59,7 +59,7 @@ final class BaseLinker(config: CommonPhaseConfig) { if (analysis.errors.nonEmpty) { val maxDisplayErrors = { - val propName = "org.scalajs.core.tools.linker.maxlinkingerrors" + val propName = "org.scalajs.linker.maxlinkingerrors" Try(System.getProperty(propName, "20").toInt).getOrElse(20).max(1) } diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala b/linker/shared/src/main/scala/org/scalajs/linker/frontend/LinkerFrontend.scala similarity index 90% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala rename to linker/shared/src/main/scala/org/scalajs/linker/frontend/LinkerFrontend.scala index ec7fbbafb4..713763fde0 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/frontend/LinkerFrontend.scala @@ -7,15 +7,15 @@ \* */ -package org.scalajs.core.tools.linker.frontend +package org.scalajs.linker.frontend -import org.scalajs.core.tools.logging.Logger +import org.scalajs.logging.Logger -import org.scalajs.core.tools.linker._ -import org.scalajs.core.tools.linker.standard._ -import org.scalajs.core.tools.linker.analyzer.SymbolRequirement -import org.scalajs.core.tools.linker.frontend.optimizer.{GenIncOptimizer, IncOptimizer} -import org.scalajs.core.tools.linker.irio._ +import org.scalajs.linker._ +import org.scalajs.linker.standard._ +import org.scalajs.linker.analyzer.SymbolRequirement +import org.scalajs.linker.frontend.optimizer.{GenIncOptimizer, IncOptimizer} +import org.scalajs.linker.irio._ /** The frontend of the Scala.js linker. Produces a [[LinkingUnit]] * diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala b/linker/shared/src/main/scala/org/scalajs/linker/frontend/Refiner.scala similarity index 97% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala rename to linker/shared/src/main/scala/org/scalajs/linker/frontend/Refiner.scala index b36e1abb10..5b909717ee 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/frontend/Refiner.scala @@ -7,17 +7,17 @@ \* */ -package org.scalajs.core.tools.linker.frontend +package org.scalajs.linker.frontend import scala.collection.mutable -import org.scalajs.core.ir.Trees._ +import org.scalajs.ir.Trees._ -import org.scalajs.core.tools.logging._ +import org.scalajs.logging._ -import org.scalajs.core.tools.linker._ -import org.scalajs.core.tools.linker.standard._ -import org.scalajs.core.tools.linker.analyzer._ +import org.scalajs.linker._ +import org.scalajs.linker.standard._ +import org.scalajs.linker.analyzer._ /** Does a dead code elimination pass on [[LinkedClass]]es */ final class Refiner(config: CommonPhaseConfig) { diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala b/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/GenIncOptimizer.scala similarity index 98% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala rename to linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/GenIncOptimizer.scala index 19c92f37e6..9a5720e321 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/GenIncOptimizer.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.linker.frontend.optimizer +package org.scalajs.linker.frontend.optimizer import language.higherKinds @@ -16,17 +16,17 @@ import scala.annotation.{switch, tailrec} import scala.collection.{GenMap, GenTraversableOnce, GenIterable, GenIterableLike} import scala.collection.mutable -import org.scalajs.core.ir._ +import org.scalajs.ir._ import Definitions.isConstructorName import Trees._ import Types._ -import org.scalajs.core.tools.logging._ +import org.scalajs.logging._ -import org.scalajs.core.tools.linker._ -import org.scalajs.core.tools.linker.analyzer.SymbolRequirement -import org.scalajs.core.tools.linker.backend.emitter.LongImpl -import org.scalajs.core.tools.linker.standard._ +import org.scalajs.linker._ +import org.scalajs.linker.analyzer.SymbolRequirement +import org.scalajs.linker.backend.emitter.LongImpl +import org.scalajs.linker.standard._ /** Incremental optimizer. * An incremental optimizer optimizes a [[LinkingUnit]] in an incremental way. @@ -706,7 +706,7 @@ abstract class GenIncOptimizer private[optimizer] (config: CommonPhaseConfig) { /** Type of a class or interface. * Types are created on demand when a method is called on a given - * [[org.scalajs.core.ir.Types.ClassType ClassType]]. + * [[org.scalajs.ir.Types.ClassType ClassType]]. * * Fully concurrency safe unless otherwise noted. */ diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/IncOptimizer.scala b/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/IncOptimizer.scala similarity index 98% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/IncOptimizer.scala rename to linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/IncOptimizer.scala index 8321a728ad..3773c5072d 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/IncOptimizer.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/IncOptimizer.scala @@ -7,12 +7,12 @@ \* */ -package org.scalajs.core.tools.linker.frontend.optimizer +package org.scalajs.linker.frontend.optimizer import scala.collection.{GenTraversableOnce, GenIterable} import scala.collection.mutable -import org.scalajs.core.tools.linker.standard._ +import org.scalajs.linker.standard._ final class IncOptimizer(config: CommonPhaseConfig) extends GenIncOptimizer(config) { diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala similarity index 99% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala rename to linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala index e72c550908..ce20aa6169 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.linker.frontend.optimizer +package org.scalajs.linker.frontend.optimizer import scala.language.implicitConversions @@ -18,16 +18,16 @@ import scala.collection.mutable import scala.util.control.{NonFatal, ControlThrowable, TailCalls} import scala.util.control.TailCalls.{done => _, _} // done is a too generic term -import org.scalajs.core.ir._ +import org.scalajs.ir._ import Definitions.{ObjectClass, isConstructorName, isReflProxyName} import Trees._ import Types._ -import org.scalajs.core.tools.logging._ -import org.scalajs.core.tools.linker._ -import org.scalajs.core.tools.linker.standard._ -import org.scalajs.core.tools.linker.backend.emitter.LongImpl -import org.scalajs.core.tools.linker.backend.emitter.Transients.CallHelper +import org.scalajs.logging._ +import org.scalajs.linker._ +import org.scalajs.linker.standard._ +import org.scalajs.linker.backend.emitter.LongImpl +import org.scalajs.linker.backend.emitter.Transients.CallHelper /** Optimizer core. * Designed to be "mixed in" [[IncOptimizer#MethodImpl#Optimizer]]. diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/irio/IRFileCache.scala b/linker/shared/src/main/scala/org/scalajs/linker/irio/IRFileCache.scala similarity index 98% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/irio/IRFileCache.scala rename to linker/shared/src/main/scala/org/scalajs/linker/irio/IRFileCache.scala index e6499ba0a1..f2c0d068db 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/irio/IRFileCache.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/irio/IRFileCache.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.linker.irio +package org.scalajs.linker.irio import scala.annotation.tailrec @@ -16,10 +16,10 @@ import java.net.URI import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.atomic.AtomicInteger -import org.scalajs.core.ir.EntryPointsInfo -import org.scalajs.core.ir.Trees.ClassDef +import org.scalajs.ir.EntryPointsInfo +import org.scalajs.ir.Trees.ClassDef -import org.scalajs.core.tools.io._ +import org.scalajs.io._ /** Centralized Scala.js IR cache. * diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/irio/MemIRFiles.scala b/linker/shared/src/main/scala/org/scalajs/linker/irio/MemIRFiles.scala similarity index 90% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/irio/MemIRFiles.scala rename to linker/shared/src/main/scala/org/scalajs/linker/irio/MemIRFiles.scala index 74a9678df2..d1793007f6 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/irio/MemIRFiles.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/irio/MemIRFiles.scala @@ -6,9 +6,9 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.linker.irio +package org.scalajs.linker.irio -import org.scalajs.core.tools.io._ +import org.scalajs.io._ /** A simple in-memory mutable virtual serialized Scala.js IR file. */ class MemVirtualSerializedScalaJSIRFile(p: String) diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/irio/VirtualIRFiles.scala b/linker/shared/src/main/scala/org/scalajs/linker/irio/VirtualIRFiles.scala similarity index 96% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/irio/VirtualIRFiles.scala rename to linker/shared/src/main/scala/org/scalajs/linker/irio/VirtualIRFiles.scala index b34db49041..b6b9e31e39 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/irio/VirtualIRFiles.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/irio/VirtualIRFiles.scala @@ -6,13 +6,13 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.linker.irio +package org.scalajs.linker.irio import java.io._ -import org.scalajs.core.ir +import org.scalajs.ir -import org.scalajs.core.tools.io._ +import org.scalajs.io._ /** A virtual file containing Scala.js IR. * diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/standard/CommonPhaseConfig.scala b/linker/shared/src/main/scala/org/scalajs/linker/standard/CommonPhaseConfig.scala similarity index 96% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/standard/CommonPhaseConfig.scala rename to linker/shared/src/main/scala/org/scalajs/linker/standard/CommonPhaseConfig.scala index 24db67c71f..0092bc422e 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/standard/CommonPhaseConfig.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/standard/CommonPhaseConfig.scala @@ -6,9 +6,9 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.linker.standard +package org.scalajs.linker.standard -import org.scalajs.core.tools.linker._ +import org.scalajs.linker._ /** Common configuration given to all phases of the linker. */ final class CommonPhaseConfig private ( diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/standard/CoreSpec.scala b/linker/shared/src/main/scala/org/scalajs/linker/standard/CoreSpec.scala similarity index 95% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/standard/CoreSpec.scala rename to linker/shared/src/main/scala/org/scalajs/linker/standard/CoreSpec.scala index e9ced4848b..479e43809a 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/standard/CoreSpec.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/standard/CoreSpec.scala @@ -6,9 +6,9 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.linker.standard +package org.scalajs.linker.standard -import org.scalajs.core.tools.linker._ +import org.scalajs.linker._ /** Core specification for the Scala.js code. */ final class CoreSpec private ( diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/standard/OutputMode.scala b/linker/shared/src/main/scala/org/scalajs/linker/standard/OutputMode.scala similarity index 97% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/standard/OutputMode.scala rename to linker/shared/src/main/scala/org/scalajs/linker/standard/OutputMode.scala index 5d66315c3a..1e2cf57860 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/standard/OutputMode.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/standard/OutputMode.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.linker.standard +package org.scalajs.linker.standard /** JavaScript output mode. */ sealed abstract class OutputMode diff --git a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/standard/package.scala b/linker/shared/src/main/scala/org/scalajs/linker/standard/package.scala similarity index 96% rename from linker/shared/src/main/scala/org/scalajs/core/tools/linker/standard/package.scala rename to linker/shared/src/main/scala/org/scalajs/linker/standard/package.scala index a37ea18ba3..5972ea3dbf 100644 --- a/linker/shared/src/main/scala/org/scalajs/core/tools/linker/standard/package.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/standard/package.scala @@ -6,7 +6,7 @@ ** |/____/ ** \* */ -package org.scalajs.core.tools.linker +package org.scalajs.linker package object standard { implicit class StandardLinkerConfigStandardOps private[standard] ( diff --git a/linker/shared/src/test/scala/org/scalajs/core/tools/linker/AnalyzerTest.scala b/linker/shared/src/test/scala/org/scalajs/linker/AnalyzerTest.scala similarity index 95% rename from linker/shared/src/test/scala/org/scalajs/core/tools/linker/AnalyzerTest.scala rename to linker/shared/src/test/scala/org/scalajs/linker/AnalyzerTest.scala index 62001ee635..fea8d4abcf 100644 --- a/linker/shared/src/test/scala/org/scalajs/core/tools/linker/AnalyzerTest.scala +++ b/linker/shared/src/test/scala/org/scalajs/linker/AnalyzerTest.scala @@ -1,24 +1,24 @@ -package org.scalajs.core.tools.linker +package org.scalajs.linker import org.junit.Test import org.junit.Assert._ -import org.scalajs.core.ir -import org.scalajs.core.ir.ClassKind -import org.scalajs.core.ir.Definitions._ -import org.scalajs.core.ir.Trees._ -import org.scalajs.core.ir.Types._ +import org.scalajs.ir +import org.scalajs.ir.ClassKind +import org.scalajs.ir.Definitions._ +import org.scalajs.ir.Trees._ +import org.scalajs.ir.Types._ -import org.scalajs.core.tools.logging.NullLogger -import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.linker._ -import org.scalajs.core.tools.linker.analyzer._ -import org.scalajs.core.tools.linker.standard._ +import org.scalajs.logging.NullLogger +import org.scalajs.io._ +import org.scalajs.linker._ +import org.scalajs.linker.analyzer._ +import org.scalajs.linker.standard._ import Analysis._ -import org.scalajs.core.tools.linker.testutils._ -import org.scalajs.core.tools.linker.testutils.TestIRBuilder._ +import org.scalajs.linker.testutils._ +import org.scalajs.linker.testutils.TestIRBuilder._ class AnalyzerTest { import AnalyzerTest._ diff --git a/linker/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala b/linker/shared/src/test/scala/org/scalajs/linker/LinkerTest.scala similarity index 86% rename from linker/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala rename to linker/shared/src/test/scala/org/scalajs/linker/LinkerTest.scala index dc7fb56e4c..ac82c0841d 100644 --- a/linker/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala +++ b/linker/shared/src/test/scala/org/scalajs/linker/LinkerTest.scala @@ -1,20 +1,20 @@ -package org.scalajs.core.tools.linker +package org.scalajs.linker import org.junit.Test import org.junit.Assert._ -import org.scalajs.core.ir.ClassKind -import org.scalajs.core.ir.Definitions._ -import org.scalajs.core.ir.Trees._ +import org.scalajs.ir.ClassKind +import org.scalajs.ir.Definitions._ +import org.scalajs.ir.Trees._ -import org.scalajs.core.tools.logging._ -import org.scalajs.core.tools.io._ +import org.scalajs.logging._ +import org.scalajs.io._ -import org.scalajs.core.tools.linker._ -import org.scalajs.core.tools.linker.irio._ +import org.scalajs.linker._ +import org.scalajs.linker.irio._ -import org.scalajs.core.tools.linker.testutils._ -import org.scalajs.core.tools.linker.testutils.TestIRBuilder._ +import org.scalajs.linker.testutils._ +import org.scalajs.linker.testutils.TestIRBuilder._ class LinkerTest { import LinkerTest._ diff --git a/linker/shared/src/test/scala/org/scalajs/core/tools/linker/testutils/TestIRBuilder.scala b/linker/shared/src/test/scala/org/scalajs/linker/testutils/TestIRBuilder.scala similarity index 86% rename from linker/shared/src/test/scala/org/scalajs/core/tools/linker/testutils/TestIRBuilder.scala rename to linker/shared/src/test/scala/org/scalajs/linker/testutils/TestIRBuilder.scala index f9db878f03..0e68a2a9fd 100644 --- a/linker/shared/src/test/scala/org/scalajs/core/tools/linker/testutils/TestIRBuilder.scala +++ b/linker/shared/src/test/scala/org/scalajs/linker/testutils/TestIRBuilder.scala @@ -1,10 +1,10 @@ -package org.scalajs.core.tools.linker.testutils +package org.scalajs.linker.testutils -import org.scalajs.core.ir -import org.scalajs.core.ir.ClassKind -import org.scalajs.core.ir.Definitions._ -import org.scalajs.core.ir.Trees._ -import org.scalajs.core.ir.Types._ +import org.scalajs.ir +import org.scalajs.ir.ClassKind +import org.scalajs.ir.Definitions._ +import org.scalajs.ir.Trees._ +import org.scalajs.ir.Types._ object TestIRBuilder { implicit val noPosition: ir.Position = ir.Position.NoPosition diff --git a/linker/shared/src/test/scala/org/scalajs/core/tools/linker/testutils/TestIRRepo.scala b/linker/shared/src/test/scala/org/scalajs/linker/testutils/TestIRRepo.scala similarity index 74% rename from linker/shared/src/test/scala/org/scalajs/core/tools/linker/testutils/TestIRRepo.scala rename to linker/shared/src/test/scala/org/scalajs/linker/testutils/TestIRRepo.scala index 137e0e9cab..7c2ead1cd6 100644 --- a/linker/shared/src/test/scala/org/scalajs/core/tools/linker/testutils/TestIRRepo.scala +++ b/linker/shared/src/test/scala/org/scalajs/linker/testutils/TestIRRepo.scala @@ -1,15 +1,15 @@ -package org.scalajs.core.tools.linker.testutils +package org.scalajs.linker.testutils import scala.collection.mutable -import org.scalajs.core.tools.io._ +import org.scalajs.io._ -import org.scalajs.core.tools.linker.analyzer.Infos._ -import org.scalajs.core.tools.linker.irio._ +import org.scalajs.linker.analyzer.Infos._ +import org.scalajs.linker.irio._ object TestIRRepo { private val stdlibPath = - System.getProperty("org.scalajs.core.tools.linker.stdlibjar") + System.getProperty("org.scalajs.linker.stdlibjar") private val globalIRCache = new IRFileCache diff --git a/logging/shared/src/main/scala/org/scalajs/core/tools/logging/Level.scala b/logging/shared/src/main/scala/org/scalajs/logging/Level.scala similarity index 96% rename from logging/shared/src/main/scala/org/scalajs/core/tools/logging/Level.scala rename to logging/shared/src/main/scala/org/scalajs/logging/Level.scala index 196b9809c5..9c7a10ea86 100644 --- a/logging/shared/src/main/scala/org/scalajs/core/tools/logging/Level.scala +++ b/logging/shared/src/main/scala/org/scalajs/logging/Level.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.logging +package org.scalajs.logging import scala.math.Ordered diff --git a/logging/shared/src/main/scala/org/scalajs/core/tools/logging/Logger.scala b/logging/shared/src/main/scala/org/scalajs/logging/Logger.scala similarity index 97% rename from logging/shared/src/main/scala/org/scalajs/core/tools/logging/Logger.scala rename to logging/shared/src/main/scala/org/scalajs/logging/Logger.scala index 8277ae91ca..777a9c01cb 100644 --- a/logging/shared/src/main/scala/org/scalajs/core/tools/logging/Logger.scala +++ b/logging/shared/src/main/scala/org/scalajs/logging/Logger.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.core.tools.logging +package org.scalajs.logging /** Abstract logger for our tools. Designed after sbt's Loggers. */ trait Logger { diff --git a/logging/shared/src/main/scala/org/scalajs/core/tools/logging/NullLogger.scala b/logging/shared/src/main/scala/org/scalajs/logging/NullLogger.scala similarity index 82% rename from logging/shared/src/main/scala/org/scalajs/core/tools/logging/NullLogger.scala rename to logging/shared/src/main/scala/org/scalajs/logging/NullLogger.scala index 15a911acb0..073d3870ec 100644 --- a/logging/shared/src/main/scala/org/scalajs/core/tools/logging/NullLogger.scala +++ b/logging/shared/src/main/scala/org/scalajs/logging/NullLogger.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.tools.logging +package org.scalajs.logging object NullLogger extends Logger { def log(level: Level, message: => String): Unit = {} diff --git a/logging/shared/src/main/scala/org/scalajs/core/tools/logging/ScalaConsoleLogger.scala b/logging/shared/src/main/scala/org/scalajs/logging/ScalaConsoleLogger.scala similarity index 92% rename from logging/shared/src/main/scala/org/scalajs/core/tools/logging/ScalaConsoleLogger.scala rename to logging/shared/src/main/scala/org/scalajs/logging/ScalaConsoleLogger.scala index 36619040b7..8f146a58a3 100644 --- a/logging/shared/src/main/scala/org/scalajs/core/tools/logging/ScalaConsoleLogger.scala +++ b/logging/shared/src/main/scala/org/scalajs/logging/ScalaConsoleLogger.scala @@ -1,4 +1,4 @@ -package org.scalajs.core.tools.logging +package org.scalajs.logging class ScalaConsoleLogger(minLevel: Level = Level.Debug) extends Logger { diff --git a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala index 3961c1d980..818ac44d91 100644 --- a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala +++ b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala @@ -12,9 +12,9 @@ package org.scalajs.jsenv.nodejs import java.io.{Console => _, _} import java.net._ -import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.io.JSUtils.escapeJS -import org.scalajs.core.tools.logging.NullLogger +import org.scalajs.io._ +import org.scalajs.io.JSUtils.escapeJS +import org.scalajs.logging.NullLogger import org.scalajs.jsenv._ import org.scalajs.jsenv.Utils.OptDeadline diff --git a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala index 25392c0fe1..9ff544e3bf 100644 --- a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala +++ b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala @@ -13,8 +13,8 @@ import scala.collection.immutable import org.scalajs.jsenv._ -import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.logging._ +import org.scalajs.io._ +import org.scalajs.logging._ import java.io.{ Console => _, _ } diff --git a/partest/src/main-partest-1.0.13/scala/tools/partest/scalajs/ScalaJSPartest.scala b/partest/src/main-partest-1.0.13/scala/tools/partest/scalajs/ScalaJSPartest.scala index da418ec3f0..52394f0ca1 100644 --- a/partest/src/main-partest-1.0.13/scala/tools/partest/scalajs/ScalaJSPartest.scala +++ b/partest/src/main-partest-1.0.13/scala/tools/partest/scalajs/ScalaJSPartest.scala @@ -13,7 +13,7 @@ import scala.tools.nsc.{ Global, Settings } import scala.tools.nsc.reporters.{ Reporter } import scala.tools.nsc.plugins.Plugin -import org.scalajs.core.compiler.ScalaJSPlugin +import org.scalajs.nscplugin.ScalaJSPlugin import scala.io.Source @@ -76,7 +76,7 @@ trait ScalaJSSuiteRunner extends SuiteRunner { // Stuff we provide override def banner: String = { - import org.scalajs.core.ir.ScalaJSVersions.{ current => currentVersion } + import org.scalajs.ir.ScalaJSVersions.{ current => currentVersion } super.banner.trim + s""" |Scala.js version is: $currentVersion diff --git a/partest/src/main-partest-1.0.16/scala/tools/partest/scalajs/ScalaJSPartest.scala b/partest/src/main-partest-1.0.16/scala/tools/partest/scalajs/ScalaJSPartest.scala index 84b38c0013..d180fa2752 100644 --- a/partest/src/main-partest-1.0.16/scala/tools/partest/scalajs/ScalaJSPartest.scala +++ b/partest/src/main-partest-1.0.16/scala/tools/partest/scalajs/ScalaJSPartest.scala @@ -15,7 +15,7 @@ import scala.tools.nsc.plugins.Plugin import scala.tools.partest.sbt.SBTRunner -import org.scalajs.core.compiler.ScalaJSPlugin +import org.scalajs.nscplugin.ScalaJSPlugin import scala.io.Source @@ -78,7 +78,7 @@ trait ScalaJSSuiteRunner extends SuiteRunner { // Stuff we provide override def banner: String = { - import org.scalajs.core.ir.ScalaJSVersions.{ current => currentVersion } + import org.scalajs.ir.ScalaJSVersions.{ current => currentVersion } super.banner.trim + s""" |Scala.js version is: $currentVersion diff --git a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala index 0310e3f4a4..cde982ca64 100644 --- a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala +++ b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala @@ -2,14 +2,14 @@ package scala.tools.nsc /* Super hacky overriding of the MainGenericRunner used by partest */ -import org.scalajs.core.ir +import org.scalajs.ir -import org.scalajs.core.tools.io._ +import org.scalajs.io._ -import org.scalajs.core.tools.logging._ +import org.scalajs.logging._ -import org.scalajs.core.tools.linker._ -import org.scalajs.core.tools.linker.irio._ +import org.scalajs.linker._ +import org.scalajs.linker.irio._ import org.scalajs.jsenv.JSConsole import org.scalajs.jsenv.nodejs.NodeJSEnv @@ -40,7 +40,7 @@ class MainGenericRunner { val optMode = OptMode.fromId(System.getProperty("scalajs.partest.optMode")) def readSemantics() = { - import org.scalajs.core.tools.linker.CheckedBehavior.Compliant + import org.scalajs.linker.CheckedBehavior.Compliant val opt = Option(System.getProperty("scalajs.partest.compliantSems")) val compliantSems = diff --git a/project/Build.scala b/project/Build.scala index a48e8fdf4c..34e0627038 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -17,7 +17,7 @@ import java.io.{ import scala.collection.mutable import scala.util.Properties -import org.scalajs.core.ir +import org.scalajs.ir import org.scalajs.sbtplugin._ import org.scalajs.jsenv.{ConsoleJSConsole, JSEnv} @@ -27,9 +27,9 @@ import ScalaJSPlugin.autoImport.{ModuleKind => _, _} import ExternalCompile.scalaJSExternalCompileSettings import Loggers._ -import org.scalajs.core.tools.io.{FileVirtualJSFile, MemVirtualJSFile} -import org.scalajs.core.tools.io.JSUtils.escapeJS -import org.scalajs.core.tools.linker._ +import org.scalajs.io.{FileVirtualJSFile, MemVirtualJSFile} +import org.scalajs.io.JSUtils.escapeJS +import org.scalajs.linker._ /* Things that we want to expose in the sbt command line (and hence also in * `ci/matrix.xml`). @@ -47,9 +47,9 @@ object ExposedValues extends AutoPlugin { } } - val CheckedBehavior = org.scalajs.core.tools.linker.CheckedBehavior + val CheckedBehavior = org.scalajs.linker.CheckedBehavior - val OutputMode = org.scalajs.core.tools.linker.standard.OutputMode + val OutputMode = org.scalajs.linker.standard.OutputMode implicit def StandardLinkerConfigStandardOps( config: StandardLinker.Config): standard.StandardLinkerConfigStandardOps = { @@ -652,7 +652,7 @@ object Build { testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a"), javaOptions in Test += { val libJar = (packageBin in (LocalProject("minilib"), Compile)).value - "-Dorg.scalajs.core.tools.linker.stdlibjar=" + libJar.getAbsolutePath + "-Dorg.scalajs.linker.stdlibjar=" + libJar.getAbsolutePath } ) diff --git a/project/JavaLangObject.scala b/project/JavaLangObject.scala index 831a0e4a41..ae483c4310 100644 --- a/project/JavaLangObject.scala +++ b/project/JavaLangObject.scala @@ -4,7 +4,7 @@ package build * Hard-coded IR for java.lang.Object. */ -import org.scalajs.core.ir +import org.scalajs.ir import ir._ import ir.Definitions._ import ir.Trees._ diff --git a/project/NodeJSEnvForcePolyfills.scala b/project/NodeJSEnvForcePolyfills.scala index fd43f12d05..b087f6804e 100644 --- a/project/NodeJSEnvForcePolyfills.scala +++ b/project/NodeJSEnvForcePolyfills.scala @@ -3,7 +3,7 @@ package build import org.scalajs.jsenv._ import org.scalajs.jsenv.nodejs._ -import org.scalajs.core.tools.io._ +import org.scalajs.io._ class NodeJSEnvForcePolyfills(config: NodeJSEnv.Config) extends NodeJSEnv(config) { diff --git a/project/project/ScalaJSEnvGenerator.scala b/project/project/ScalaJSEnvGenerator.scala index a8457c0be2..c561ad7b48 100644 --- a/project/project/ScalaJSEnvGenerator.scala +++ b/project/project/ScalaJSEnvGenerator.scala @@ -17,7 +17,7 @@ object ScalaJSEnvGenerator { val scalaCode = s""" - package org.scalajs.core.tools.linker.backend.emitter + package org.scalajs.linker.backend.emitter private[emitter] object ScalaJSEnvHolder { final val scalajsenv = raw\"\"\"$scalajsenv\"\"\" diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index 14b2593b86..bc4d423f8e 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -1,4 +1,4 @@ -import org.scalajs.core.tools.io._ +import org.scalajs.io._ import org.scalajs.sbtplugin.Loggers.sbtLogger2ToolsLogger import org.scalajs.sbtplugin.ScalaJSCrossVersion diff --git a/sbt-plugin-test/project/build.sbt b/sbt-plugin-test/project/build.sbt index 6626b7a52e..357ff8afb6 100644 --- a/sbt-plugin-test/project/build.sbt +++ b/sbt-plugin-test/project/build.sbt @@ -1,2 +1,2 @@ addSbtPlugin("org.scala-js" % "sbt-scalajs" % - org.scalajs.core.ir.ScalaJSVersions.current) + org.scalajs.ir.ScalaJSVersions.current) diff --git a/sbt-plugin-test/project/project/build.sbt b/sbt-plugin-test/project/project/build.sbt index 4bd98076ce..bd679594ed 100644 --- a/sbt-plugin-test/project/project/build.sbt +++ b/sbt-plugin-test/project/project/build.sbt @@ -1 +1 @@ -sources in Compile += baseDirectory.value / "../../../ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala" +sources in Compile += baseDirectory.value / "../../../ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala" diff --git a/sbt-plugin/src/main/scala-sbt-0.13/org/scalajs/sbtplugin/SBTCompat.scala b/sbt-plugin/src/main/scala-sbt-0.13/org/scalajs/sbtplugin/SBTCompat.scala index 513bd0faae..55d44b6457 100644 --- a/sbt-plugin/src/main/scala-sbt-0.13/org/scalajs/sbtplugin/SBTCompat.scala +++ b/sbt-plugin/src/main/scala-sbt-0.13/org/scalajs/sbtplugin/SBTCompat.scala @@ -2,7 +2,7 @@ package org.scalajs.sbtplugin import sbt._ -import org.scalajs.core.tools.io.FileVirtualFile +import org.scalajs.io.FileVirtualFile private[sbtplugin] object SBTCompat { type IncOptions = sbt.inc.IncOptions diff --git a/sbt-plugin/src/main/scala-sbt-1.0/org/scalajs/sbtplugin/SBTCompat.scala b/sbt-plugin/src/main/scala-sbt-1.0/org/scalajs/sbtplugin/SBTCompat.scala index 6b7f2a7eea..8e5a130936 100644 --- a/sbt-plugin/src/main/scala-sbt-1.0/org/scalajs/sbtplugin/SBTCompat.scala +++ b/sbt-plugin/src/main/scala-sbt-1.0/org/scalajs/sbtplugin/SBTCompat.scala @@ -2,7 +2,7 @@ package org.scalajs.sbtplugin import sbt._ -import org.scalajs.core.tools.io.FileVirtualFile +import org.scalajs.io.FileVirtualFile private[sbtplugin] object SBTCompat { type IncOptions = xsbti.compile.IncOptions diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Loggers.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Loggers.scala index 0bfcaca6e7..a057020d52 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Loggers.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Loggers.scala @@ -1,6 +1,6 @@ package org.scalajs.sbtplugin -import org.scalajs.core.tools.logging._ +import org.scalajs.logging._ import sbt.{Level => SbtLevel, Logger => SbtLogger} object Loggers { diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSCrossVersion.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSCrossVersion.scala index 19a73cd670..b016a6fd36 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSCrossVersion.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSCrossVersion.scala @@ -11,7 +11,7 @@ package org.scalajs.sbtplugin import sbt._ -import org.scalajs.core.ir.ScalaJSVersions +import org.scalajs.ir.ScalaJSVersions import SBTCompat._ diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 76882a505f..3b29efd77a 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -14,12 +14,12 @@ import scala.language.implicitConversions import sbt._ import sbt.Keys._ -import org.scalajs.core.ir.ScalaJSVersions +import org.scalajs.ir.ScalaJSVersions -import org.scalajs.core.tools.io._ +import org.scalajs.io._ -import org.scalajs.core.tools.linker._ -import org.scalajs.core.tools.linker.irio._ +import org.scalajs.linker._ +import org.scalajs.linker.irio._ import org.scalajs.jsenv.JSEnv @@ -37,7 +37,7 @@ object ScalaJSPlugin extends AutoPlugin { val FullOptStage = Stage.FullOpt // ModuleKind - val ModuleKind = org.scalajs.core.tools.linker.ModuleKind + val ModuleKind = org.scalajs.linker.ModuleKind // All our public-facing keys diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index d6b045c938..83190994e0 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -12,17 +12,17 @@ import sbt.complete.DefaultParsers._ import org.portablescala.sbtplatformdeps.PlatformDepsPlugin.autoImport._ -import org.scalajs.core.tools.io.{IO => _, _} -import org.scalajs.core.tools.io.JSUtils.escapeJS +import org.scalajs.io.{IO => _, _} +import org.scalajs.io.JSUtils.escapeJS -import org.scalajs.core.tools.linker._ -import org.scalajs.core.tools.linker.irio._ -import org.scalajs.core.tools.linker.standard._ +import org.scalajs.linker._ +import org.scalajs.linker.irio._ +import org.scalajs.linker.standard._ import org.scalajs.jsenv._ import org.scalajs.jsenv.nodejs.NodeJSEnv -import org.scalajs.core.ir.Printers.IRTreePrinter +import org.scalajs.ir.Printers.IRTreePrinter import org.scalajs.testadapter.{TestAdapter, HTMLRunnerBuilder} import org.scalajs.testadapter.TestAdapter.ModuleIdentifier diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalajspUtils.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalajspUtils.scala index 0281478ec8..a3a3eb117c 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalajspUtils.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalajspUtils.scala @@ -14,7 +14,7 @@ import scala.collection.mutable import sbt._ import sbt.complete._ -import org.scalajs.core.tools.io._ +import org.scalajs.io._ private[sbtplugin] object ScalajspUtils { diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala index 1c1bd0c24e..61a7860075 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala @@ -14,8 +14,8 @@ import java.net.URI import sbt.testing.{Framework, TaskDef} -import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.io.JSUtils.escapeJS +import org.scalajs.io._ +import org.scalajs.io.JSUtils.escapeJS import org.scalajs.jsenv.VirtualFileMaterializer diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapter.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapter.scala index bad8e33141..f0dda59198 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapter.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapter.scala @@ -13,9 +13,9 @@ import scala.concurrent._ import scala.concurrent.duration._ import scala.collection.concurrent.TrieMap -import org.scalajs.core.tools.io._ -import org.scalajs.core.tools.io.JSUtils.escapeJS -import org.scalajs.core.tools.logging._ +import org.scalajs.io._ +import org.scalajs.io.JSUtils.escapeJS +import org.scalajs.logging._ import org.scalajs.jsenv._ From b5e6e62fd19ec6771b3003ad1f7eed9c3bce70ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 21 Jan 2018 13:35:40 +0100 Subject: [PATCH 0627/2665] Fix #3264: Reset generatedSAMWrapperCount to 0 for nested classes. When generating nested classes through `nestedGenerateClass`, the scoped var `generatedSAMWrapperCount` was reset to `null`, whereas it is set to `new VarBox(0)` for top-level classes. This could cause NPEs in `synthesizeSAMWrapper` if an LMF-capable SAM function was nested in the body of an anonymous JS class. This commit fixes the issue by resetting `generatedSAMWrapperCount` to `new VarBox(0)`. --- .../org/scalajs/core/compiler/GenJSCode.scala | 2 +- .../testsuite/jsinterop/SAMJSTest.scala | 43 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 test-suite/js/src/test/require-sam/org/scalajs/testsuite/jsinterop/SAMJSTest.scala diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 6a980d7020..7856c4f003 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -166,7 +166,7 @@ abstract class GenJSCode extends plugins.PluginComponent withScopedVars( currentClassSym := clsSym, unexpectedMutatedFields := mutable.Set.empty, - generatedSAMWrapperCount := null, + generatedSAMWrapperCount := new VarBox(0), currentMethodSym := null, thisLocalVarInfo := null, fakeTailJumpParamRepl := null, diff --git a/test-suite/js/src/test/require-sam/org/scalajs/testsuite/jsinterop/SAMJSTest.scala b/test-suite/js/src/test/require-sam/org/scalajs/testsuite/jsinterop/SAMJSTest.scala new file mode 100644 index 0000000000..442a1a10af --- /dev/null +++ b/test-suite/js/src/test/require-sam/org/scalajs/testsuite/jsinterop/SAMJSTest.scala @@ -0,0 +1,43 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2018, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.testsuite.jsinterop + +import scala.scalajs.js + +import org.junit.Assert._ +import org.junit.Test + +import org.scalajs.testsuite.utils.JSAssert._ + +class SAMJSTest { + + import SAMJSTest._ + + @Test def samNestedInAnonJSClass_issue3264(): Unit = { + val outer = new SAMInAnonJSClass_ParentJSClass { + def foo(x: Int): Int = { + val innerSAM: SAMInAnonJSClass_MySAM = _ * 2 + innerSAM.bar(x + 3) + } + } + + assertEquals(16, outer.foo(5)) + } + +} + +object SAMJSTest { + abstract class SAMInAnonJSClass_ParentJSClass extends js.Object { + def foo(x: Int): Int + } + + trait SAMInAnonJSClass_MySAM { + def bar(x: Int): Int + } +} From 7258a8ba0c8d0198eed184e51a71dc0c9d6aa9fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 22 Jan 2018 09:12:24 +0100 Subject: [PATCH 0628/2665] Version 0.6.22. --- ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index a9431d7a3e..646b934f96 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.22-SNAPSHOT" + val current: String = "0.6.22" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" From 6cea4c43f44b4d955bdaf2918c380c303d456ac0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 23 Jan 2018 23:04:34 +0100 Subject: [PATCH 0629/2665] Towards 0.6.23. --- .../org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- project/BinaryIncompatibilities.scala | 132 ------------------ project/Build.scala | 2 +- 3 files changed, 2 insertions(+), 134 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index 646b934f96..c17b235be2 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.22" + val current: String = "0.6.23-SNAPSHOT" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 165b459665..553c491612 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -17,103 +17,12 @@ object BinaryIncompatibilities { ) val SbtPlugin = Seq( - // private[sbtplugin], not an issue. - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.sbtplugin.FrameworkDetector"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.sbtplugin.FrameworkDetector.detect"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.sbtplugin.FrameworkDetector.this"), - - // private, not an issue. - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.sbtplugin.FrameworkDetector$StoreConsole") ) val TestCommon = Seq( - // private[scalajs], not an issue. - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testcommon.FrameworkInfo.name"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testcommon.FrameworkInfo.this"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testcommon.RunnerArgs.this"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testcommon.JSMasterEndpoints"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testcommon.JSMasterEndpoints$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testcommon.JSSlaveEndpoints"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testcommon.JSSlaveEndpoints$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testcommon.JVMMasterEndpoints"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testcommon.JVMMasterEndpoints$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testcommon.JVMSlaveEndpoints"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testcommon.JVMSlaveEndpoints$"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testcommon.RPCCore#lambda#@tach#1.this"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testcommon.RPCCore.close"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testcommon.RPCCore.this") ) val TestAdapter = TestCommon ++ Seq( - // breaking in theory - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.package"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.package$"), - - // private[testadapter], not an issue. - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testadapter.package.VMTermTimeout"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testadapter.ScalaJSRunner.this"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testadapter.ScalaJSTask.this"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testadapter.ScalaJSFramework.runDone"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testadapter.ScalaJSFramework.frameworkName"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testadapter.ScalaJSFramework.optionalExportsNamespacePrefix"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testadapter.ScalaJSFramework.moduleKind"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testadapter.ScalaJSFramework.moduleIdentifier"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testadapter.ScalaJSFramework.libEnv"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testadapter.ScalaJSFramework.jsConsole"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testadapter.ScalaJSFramework.logger"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testadapter.ScalaJSRunner.getSlave"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testadapter.ScalaJSRunner.loggerLock"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testadapter.ComJSEnvRPC.close"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testadapter.ComJSEnvRPC.this"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testadapter.TestAdapter#ManagedRunner.this"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]( - "org.scalajs.testadapter.TestAdapter#ManagedRunner.com"), - - // private, not an issue. - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.ScalaJSRunner$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.ScalaJSRunner$RichFuture"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.ScalaJSRunner$RichFuture$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testadapter.ScalaJSTask$LogElement") ) val CLI = Seq( @@ -123,46 +32,5 @@ object BinaryIncompatibilities { ) val TestInterface = TestCommon ++ Seq( - // internal, not an issue. - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.Com"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.Com$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.FrameworkDetector"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.FrameworkDetector$"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.InfoSender"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.Master"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.Master$lambda$1"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.Master$lambda$2"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.Master$lambda$3"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.Master$lambda$4"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.Slave"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.Slave$Invalidatable"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.Slave$RemoteEventHandler"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.Slave$RemoteLogger"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.Slave$lambda$1"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.Slave$lambda$2"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.Slave$lambda$3"), - ProblemFilters.exclude[MissingClassProblem]( - "org.scalajs.testinterface.internal.Slave$lambda$4"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testinterface.internal.JSRPC.close"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.testinterface.internal.JSRPC#Com.close") ) } diff --git a/project/Build.scala b/project/Build.scala index 25cfbf45da..c7c9f93ea0 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -58,7 +58,7 @@ object Build { val shouldPartest = settingKey[Boolean]( "Whether we should partest the current scala version (and fail if we can't)") - val previousVersion = "0.6.21" + val previousVersion = "0.6.22" val previousSJSBinaryVersion = ScalaJSCrossVersion.binaryScalaJSVersion(previousVersion) val previousBinaryCrossVersion = From 1a634f01fcde6274d6ef9b216f2ab8c16cf0687d Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Tue, 23 Jan 2018 16:42:20 -0800 Subject: [PATCH 0630/2665] eta-expand explicitly, for compatibility with Scala 2.13 the code in question still compiles as-is in 2.13.0-M2, but no longer compiles in 2.13.0-M3, as discovered by the 2.13 community build --- .../javalib/util/CollectionsOnCheckedListTest.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedListTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedListTest.scala index 1df9dd2da8..96b6aebd36 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedListTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedListTest.scala @@ -47,9 +47,9 @@ trait CollectionsCheckedListTest @Test def testCheckedList(): Unit = { superList().add(0, new C) assertTrue(superList().addAll(0, Seq(new C))) - testOnFirstPositionOfIterator[ju.ListIterator[A]](superList().listIterator, + testOnFirstPositionOfIterator[ju.ListIterator[A]](superList().listIterator _, _.add(new C), None) - testOnFirstPositionOfIterator[ju.ListIterator[A]](superList().listIterator, + testOnFirstPositionOfIterator[ju.ListIterator[A]](superList().listIterator _, _.set(new C), None) } @@ -60,10 +60,10 @@ trait CollectionsCheckedListTest expectThrows(classOf[ClassCastException], superList().addAll(0, Seq(new A))) testOnFirstPositionOfIterator[ju.ListIterator[A]]( - superList().listIterator, + superList().listIterator _, _.add(new A), Some(classOf[ClassCastException])) testOnFirstPositionOfIterator[ju.ListIterator[A]]( - superList().listIterator, + superList().listIterator _, _.set(new A), Some(classOf[ClassCastException])) } From 3600312561f2d861eee4829f7e3b499e7e0fbdf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 25 Jan 2018 16:46:30 +0100 Subject: [PATCH 0631/2665] Explain why the special-case for Ident in `genMethodDef()` is needed. --- .../scala/org/scalajs/core/compiler/GenJSCode.scala | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 7856c4f003..a1dba51369 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -1664,7 +1664,16 @@ abstract class GenJSCode extends plugins.PluginComponent initialThis match { case Ident(_) => - // TODO Is this special-case really needed? + /* This case happens in trait implementation classes, until + * Scala 2.11. In the method, all usages of `this` have been + * replaced by the method's formal parameter `$this`. However, + * there is still a declaration of the pseudo local variable + * `_$this`, which is used in the param list of the label. We + * need to remember it now, so that when we build the JS version + * of the formal params for the label, we can redirect the + * assignment to `$this` instead of the otherwise unused + * `_$this`. + */ withScopedVars( fakeTailJumpParamRepl := (thisDef.symbol, initialThis.symbol) ) { From a0802f444de87f021f0828997caa0786a8abc289 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 25 Jan 2018 16:18:12 +0100 Subject: [PATCH 0632/2665] Fix #3267: Always use the enclosing class type for this local vars. The fix for #3058 in 1518b704802ea95c3521831d91610905f022ca25 was wrong. It made things worse for cases where the self type S of the enclosing class C is not a subtype of C. It turns out that, although scalac *declares* the `_$this` local variable with the self type S, it is in fact *used* everywhere as if had the type C. This is not very surprising, given that it compiles it down to `this` in the bytecode (yes, it *reassigns* `this` for tailrec methods). In this commit, we therefore ignore the declared type of `_$this` and always patch it up to C, the enclosing class type. This means we need to adapt the right-hand-side of the initial declaration, and of reassignments in calls to the tailrec label. Everywhere else, a `This()` is used, which naturally translates to having the type C. --- .../org/scalajs/core/compiler/GenJSCode.scala | 124 ++++++++++++++---- .../testsuite/compiler/RegressionTest.scala | 50 +++++++ 2 files changed, 148 insertions(+), 26 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index a1dba51369..364d70fb41 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -136,7 +136,7 @@ abstract class GenJSCode extends plugins.PluginComponent // Per method body private val currentMethodSym = new ScopedVar[Symbol] - private val thisLocalVarInfo = new ScopedVar[Option[(js.Ident, jstpe.Type)]] + private val thisLocalVarIdent = new ScopedVar[Option[js.Ident]] private val fakeTailJumpParamRepl = new ScopedVar[(Symbol, Symbol)] private val enclosingLabelDefParams = new ScopedVar[Map[Symbol, List[Symbol]]] private val isModuleInitialized = new ScopedVar[VarBox[Boolean]] @@ -168,7 +168,7 @@ abstract class GenJSCode extends plugins.PluginComponent unexpectedMutatedFields := mutable.Set.empty, generatedSAMWrapperCount := new VarBox(0), currentMethodSym := null, - thisLocalVarInfo := null, + thisLocalVarIdent := null, fakeTailJumpParamRepl := null, enclosingLabelDefParams := null, isModuleInitialized := null, @@ -1413,7 +1413,7 @@ abstract class GenJSCode extends plugins.PluginComponent withScopedVars( currentMethodSym := sym, - thisLocalVarInfo := None, + thisLocalVarIdent := None, fakeTailJumpParamRepl := (NoSymbol, NoSymbol), enclosingLabelDefParams := Map.empty, isModuleInitialized := new VarBox(false), @@ -1686,15 +1686,33 @@ abstract class GenJSCode extends plugins.PluginComponent mutableLocalVars += thisSym val thisLocalIdent = encodeLocalSym(thisSym) - val thisLocalType = toIRType(thisSym.tpe) + val thisLocalType = currentClassType + + val genRhs = { + /* #3267 In default methods, scalac will type its _$this + * pseudo-variable as the *self-type* of the enclosing class, + * instead of the enclosing class type itself. However, it then + * considers *usages* of _$this as if its type were the + * enclosing class type. The latter makes sense, since it is + * compiled as `this` in the bytecode, which necessarily needs + * to be the enclosing class type. Only the declared type of + * _$this is wrong. + * + * In our case, since we generate an actual local variable for + * _$this, we must make sure to type it correctly, as the + * enclosing class type. However, this means the rhs of the + * ValDef does not match, which is why we have to adapt it + * here. + */ + forceAdapt(genExpr(initialThis), thisLocalType) + } - val genRhs = genExpr(initialThis) val thisLocalVarDef = js.VarDef(thisLocalIdent, thisLocalType, thisSym.isMutable, genRhs) val innerBody = { withScopedVars( - thisLocalVarInfo := Some((thisLocalIdent, thisLocalType)) + thisLocalVarIdent := Some(thisLocalIdent) ) { genInnerBody() } @@ -1716,7 +1734,7 @@ abstract class GenJSCode extends plugins.PluginComponent val thisLocalIdent = freshLocalIdent("this") withScopedVars( - thisLocalVarInfo := Some((thisLocalIdent, jstpe.AnyType)) + thisLocalVarIdent := Some(thisLocalIdent) ) { val thisParamDef = js.ParamDef(thisLocalIdent, jstpe.AnyType, mutable = false, rest = false) @@ -1728,6 +1746,31 @@ abstract class GenJSCode extends plugins.PluginComponent } } + /** Forces the given `tree` to a given type by adapting it. + * + * @param tree + * The tree to adapt. + * @param tpe + * The target type, which must be either `AnyType` or `ClassType(_)`. + */ + private def forceAdapt(tree: js.Tree, tpe: jstpe.Type): js.Tree = { + if (tree.tpe == tpe || tpe == jstpe.AnyType) { + tree + } else { + /* Remove the useless cast that scalac's erasure had to introduce to + * work around their own ill-typed _$this. Note that the optimizer will + * not be able to do that, since it won't be able to prove that the + * underlying expression is indeed an instance of `tpe`. + */ + tree match { + case js.AsInstanceOf(underlying, _) if underlying.tpe == tpe => + underlying + case _ => + js.AsInstanceOf(tree, tpe.asInstanceOf[jstpe.ClassType])(tree.pos) + } + } + } + /** Gen JS code for a tree in statement position (in the IR). */ def genStat(tree: Tree): js.Tree = { @@ -1772,7 +1815,10 @@ abstract class GenJSCode extends plugins.PluginComponent /** Local val or var declaration */ case ValDef(_, name, _, rhs) => /* Must have been eliminated by the tail call transform performed - * by genMethodDef(). */ + * by genMethodDef(). + * If you ever change/remove this assertion, you need to update + * genEnclosingLabelApply() regarding `nme.THIS`. + */ assert(name != nme.THIS, s"ValDef(_, nme.THIS, _, _) found at ${tree.pos}") @@ -1987,15 +2033,15 @@ abstract class GenJSCode extends plugins.PluginComponent * is one. */ private def genThis()(implicit pos: Position): js.Tree = { - thisLocalVarInfo.fold[js.Tree] { + thisLocalVarIdent.fold[js.Tree] { if (tryingToGenMethodAsJSFunction) { throw new CancelGenMethodAsJSFunction( "Trying to generate `this` inside the body") } js.This()(currentClassType) - } { case (thisLocalVarIdent, thisLocalVarTpe) => + } { thisLocalIdent => // .copy() to get the correct position - js.VarRef(thisLocalVarIdent.copy())(thisLocalVarTpe) + js.VarRef(thisLocalIdent.copy())(currentClassType) } } @@ -2493,23 +2539,49 @@ abstract class GenJSCode extends plugins.PluginComponent // Prepare quadruplets of (formalArg, irType, tempVar, actualArg) // Do not include trivial assignments (when actualArg == formalArg) - val formalArgs = enclosingLabelDefParams(sym) - val actualArgs = args map genExpr val quadruplets = { - for { - (formalArgSym, actualArg) <- formalArgs zip actualArgs - formalArg = encodeLocalSym(formalArgSym) - if (actualArg match { - case js.VarRef(`formalArg`) => false - case _ => true - }) - } yield { - mutatedLocalVars += formalArgSym - val tpe = toIRType(formalArgSym.tpe) - (js.VarRef(formalArg)(tpe), tpe, - freshLocalIdent("temp$" + formalArg.name), - actualArg) + val formalArgs = enclosingLabelDefParams(sym) + val quadruplets = + List.newBuilder[(js.VarRef, jstpe.Type, js.Ident, js.Tree)] + + for ((formalArgSym, arg) <- formalArgs.zip(args)) { + val formalArg = encodeLocalSym(formalArgSym) + val actualArg = genExpr(arg) + + /* #3267 The formal argument representing the special `this` of a + * tailrec method can have the wrong type in the scalac symbol table. + * We need to patch it up, along with the actual argument, to be the + * enclosing class type. + * See the longer comment in genMethodDef() for more details. + * + * Note that only testing the `name` against `nme.THIS` is safe, + * given that `genStatOrExpr()` for `ValDef` asserts that no local + * variable named `nme.THIS` can happen, other than the ones + * generated for tailrec methods. + */ + val isTailJumpThisLocalVar = formalArgSym.name == nme.THIS + + val tpe = + if (isTailJumpThisLocalVar) currentClassType + else toIRType(formalArgSym.tpe) + + val fixedActualArg = + if (isTailJumpThisLocalVar) forceAdapt(actualArg, tpe) + else actualArg + + actualArg match { + case js.VarRef(`formalArg`) => + // This is trivial assignment, we don't need it + + case _ => + mutatedLocalVars += formalArgSym + quadruplets += ((js.VarRef(formalArg)(tpe), tpe, + freshLocalIdent("temp$" + formalArg.name), + fixedActualArg)) + } } + + quadruplets.result() } // The actual jump (continue labelDefIdent;) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala index 282393fa9b..97c2ba4a6e 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala @@ -698,6 +698,56 @@ class RegressionTest { assertEquals(15, new Child().bar(1, 0)) } + @Test def tailrec_in_trait_with_self_type_scala_2_12_issue_3267(): Unit = { + class Parser { + def c(): Int = 65 + } + + trait Helpers { this: Parser => + @tailrec + final def rec(i: Int): Int = { + if (i == 0) b() + c() + else rec(i - 1) + } + + def b(): Int = 42 + } + + class ParserWithoutHelpers extends Parser { + def foo(): Int = 5 + } + + class ParserWithHelpers extends Parser with Helpers + + assertEquals(5, new ParserWithoutHelpers().foo()) + assertEquals(107, new ParserWithHelpers().rec(3)) + } + + @Test def tailrec_in_class_with_self_type_scala_2_12_issue_3267(): Unit = { + trait Parser { + def c(): Int = 65 + } + + class Helpers { this: Parser => + @tailrec + final def rec(i: Int): Int = { + if (i == 0) b() + c() + else rec(i - 1) + } + + def b(): Int = 42 + } + + class ParserWithoutHelpers extends Parser { + def foo(): Int = 5 + } + + class ParserWithHelpers extends Helpers with Parser + + assertEquals(5, new ParserWithoutHelpers().foo()) + assertEquals(107, new ParserWithHelpers().rec(3)) + } + } object RegressionTest { From d2635e70ad274344cfbe3f147576c05690613565 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 31 Jan 2018 11:49:35 +0100 Subject: [PATCH 0633/2665] Version 1.0.0-M3. --- ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala index 73a88b396c..94afbc9d24 100644 --- a/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "1.0.0-SNAPSHOT" + val current: String = "1.0.0-M3" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" From ec5b328330276b9feb20cccadd75e19d27e887d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 31 Jan 2018 20:12:02 +0100 Subject: [PATCH 0634/2665] Towards 1.0.0 again. --- ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala index 94afbc9d24..73a88b396c 100644 --- a/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "1.0.0-M3" + val current: String = "1.0.0-SNAPSHOT" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" From 5925e2887f9e28aec020c58781e762b64fd3615d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 8 Mar 2018 09:56:27 +0100 Subject: [PATCH 0635/2665] Migrate to the Pipeline feature of Jenkins 2. We replace our makeshift `matrix.xml` + Groovy scripts inside the Jenkins config by a single `Jenkinsfile` script. It defines both the matrix, and how to use to create a pipeline of jobs. This `Jenkinsfile` is intended to be used with a Multibranch Pipeline (https://jenkins.io/doc/book/pipeline/multibranch/). It contains the logic to run a subset of the configurations for PRs (and push'es to branches), compared to the nightly builds. Since it is unclear how to distinguish "nightly" from "weekly" builds using this system, we take the opportunity to go back to building both the former 'nightly' and 'weekly' matrices as one 'full' matrix. We also rename the 'pr' matrix into 'quick'. Lately, weekly builds have been faster nightly builds anyway. Using a groovy script instead of XML to define the matrix allows to do it programmatically, avoiding some repetitions and improving readability. --- ci/matrix.xml => Jenkinsfile | 803 ++++++------------- ci/jenkins-track/README.md | 11 - ci/jenkins-track/scalajs-matrix-build.groovy | 59 -- ci/jenkins-track/scalajs-task-worker.sh | 67 -- 4 files changed, 251 insertions(+), 689 deletions(-) rename ci/matrix.xml => Jenkinsfile (52%) delete mode 100644 ci/jenkins-track/README.md delete mode 100644 ci/jenkins-track/scalajs-matrix-build.groovy delete mode 100644 ci/jenkins-track/scalajs-task-worker.sh diff --git a/ci/matrix.xml b/Jenkinsfile similarity index 52% rename from ci/matrix.xml rename to Jenkinsfile index da0cab46d9..0bf8971386 100644 --- a/ci/matrix.xml +++ b/Jenkinsfile @@ -1,19 +1,101 @@ - - - - - - - - - - - -]> - - - + ''', - + ''', - + ''', - + ''', - + ''', - + ''', - + ''', - + ''', - + ''', - + ''', - - - - - - 2.10.2 - 1.6 - - - 2.10.2 - 1.7 - - - 2.10.2 - 1.8 - - - 2.11.12 - 1.6 - - - 2.11.12 - 1.7 - - - 2.11.12 - 1.8 - - - 2.12.4 - 1.8 - - - 2.13.0-M2 - 1.8 - - - - - 2.10.2 - 1.8 - testSuite - - - 2.11.12 - 1.8 - testSuite - - - 2.12.4 - 1.8 - testSuite - - - 2.13.0-M2 - 1.8 - testSuite - - - - - 2.11.12 - 1.8 - scalaTestSuite - - - 2.12.4 - 1.8 - scalaTestSuite - - - 2.13.0-M2 - 1.8 - scalaTestSuite - - - - - 2.10.2 - 1.8 - testSuite - - - 2.11.12 - 1.8 - testSuite - - - 2.12.4 - 1.8 - testSuite - - - 2.13.0-M2 - 1.8 - testSuite - - - - - 2.11.12 - 1.8 - scalaTestSuite - - - 2.12.4 - 1.8 - scalaTestSuite - - - 2.13.0-M2 - 1.8 - scalaTestSuite - - - - - 2.10.2 - 1.8 - - - 2.11.12 - 1.8 - - - 2.12.4 - 1.8 - - - 2.13.0-M2 - 1.8 - - - - - 2.10.7 - 1.6 - - - 2.10.7 - 1.7 - - - 2.10.7 - 1.8 - - - - 2.11.12 - 1.7 - - - 2.11.12 - 1.8 - - - 2.12.4 - 1.8 - - - - - 2.11.0 - 1.7 - - - - - 2.11.12 - 1.7 - - - 2.12.4 - 1.8 - - - 2.13.0-M2 - 1.8 - - - - - 1.7 - 2.10.7 - - - - 1.8 - 2.12.4 - 1.0.0 - - - - - - - - - 2.10.3 - 1.8 - - - 2.10.4 - 1.8 - - - 2.10.5 - 1.8 - - - 2.10.6 - 1.8 - - - 2.10.7 - 1.8 - - - 2.11.0 - 1.8 - - - 2.11.1 - 1.8 - - - 2.11.2 - 1.8 - - - 2.11.4 - 1.8 - - - 2.11.5 - 1.8 - - - 2.11.6 - 1.8 - - - 2.11.7 - 1.8 - - - 2.11.8 - 1.8 - - - 2.11.11 - 1.8 - - - 2.12.0 - 1.8 - - - 2.12.1 - 1.8 - - - 2.12.2 - 1.8 - - - 2.12.3 - 1.8 - - - - - 2.10.2 - 1.6 - testSuite - - - 2.10.2 - 1.7 - testSuite - - - 2.11.12 - 1.6 - testSuite - - - 2.11.12 - 1.7 - testSuite - - - - - 2.10.2 - 1.6 - testSuite - - - 2.10.2 - 1.7 - testSuite - - - 2.11.12 - 1.6 - testSuite - - - 2.11.12 - 1.7 - testSuite - - - - - 2.11.12 - 1.7 - - - 2.11.12 - 1.7 - - - 2.12.4 - 1.8 - - - 2.12.4 - 1.8 - - - 2.13.0-M2 - 1.8 - - - 2.13.0-M2 - 1.8 - - - - - - - - 2.11.0 - 1.8 - - - 2.11.0 - 1.8 - - - 2.11.0 - 1.8 - - - 2.11.1 - 1.8 - - - 2.11.1 - 1.8 - - - 2.11.1 - 1.8 - - - 2.11.2 - 1.8 - - - 2.11.2 - 1.8 - - - 2.11.2 - 1.8 - - - - 2.11.5 - 1.8 - - - 2.11.5 - 1.8 - - - 2.11.5 - 1.8 - - - 2.11.6 - 1.8 - - - 2.11.6 - 1.8 - - - 2.11.6 - 1.8 - - - 2.11.6 - 1.8 - - - 2.11.6 - 1.8 - - - 2.11.6 - 1.8 - - - 2.11.7 - 1.8 - - - 2.11.7 - 1.8 - - - 2.11.7 - 1.8 - - - 2.11.8 - 1.8 - - - 2.11.8 - 1.8 - - - 2.11.8 - 1.8 - - - 2.11.11 - 1.8 - - - 2.11.11 - 1.8 - - - 2.11.11 - 1.8 - - - 2.11.12 - 1.8 - - - 2.11.12 - 1.8 - - - 2.11.12 - 1.8 - - - 2.12.0 - 1.8 - - - 2.12.0 - 1.8 - - - 2.12.0 - 1.8 - - - 2.12.1 - 1.8 - - - 2.12.1 - 1.8 - - - 2.12.1 - 1.8 - - - 2.12.2 - 1.8 - - - 2.12.2 - 1.8 - - - 2.12.2 - 1.8 - - - 2.12.3 - 1.8 - - - 2.12.3 - 1.8 - - - 2.12.3 - 1.8 - - - - + ''' +] + +def mainJavaVersion = "1.8" +def otherJavaVersions = [] // should be ["1.6", "1.7"] but that's broken (see #3293) +def allJavaVersions = otherJavaVersions.clone() +allJavaVersions << mainJavaVersion + +def mainScalaVersion = "2.12.4" +def mainScalaVersions = ["2.10.2", "2.11.12", "2.12.4", "2.13.0-M2"] +def otherScalaVersions = [ + "2.10.3", + "2.10.4", + "2.10.5", + "2.10.6", + "2.10.7", + "2.11.0", + "2.11.1", + "2.11.2", + "2.11.4", + "2.11.5", + "2.11.6", + "2.11.7", + "2.11.8", + "2.11.11", + "2.11.12", + "2.12.0", + "2.12.1", + "2.12.2", + "2.12.3" +] + +// The 'quick' matrix +def quickMatrix = [] +mainScalaVersions.each { scalaVersion -> + allJavaVersions.each { javaVersion -> + quickMatrix.add([task: "main", scala: scalaVersion, java: javaVersion]) + } + quickMatrix.add([task: "test-suite-ecma-script5", scala: scalaVersion, java: mainJavaVersion, testSuite: "testSuite"]) + quickMatrix.add([task: "test-suite-ecma-script6", scala: scalaVersion, java: mainJavaVersion, testSuite: "testSuite"]) + if (!scalaVersion.startsWith("2.10.")) { + quickMatrix.add([task: "test-suite-ecma-script5", scala: scalaVersion, java: mainJavaVersion, testSuite: "scalaTestSuite"]) + quickMatrix.add([task: "test-suite-ecma-script6", scala: scalaVersion, java: mainJavaVersion, testSuite: "scalaTestSuite"]) + } + quickMatrix.add([task: "bootstrap", scala: scalaVersion, java: mainJavaVersion]) + if (!scalaVersion.startsWith("2.10.")) { + // #3293, should be: def javaVersion = scalaVersion.startsWith("2.11.") ? "1.7" : mainJavaVersion + def javaVersion = "1.8" + quickMatrix.add([task: "partest-fastopt", scala: scalaVersion, java: javaVersion]) + } +} +allJavaVersions.each { javaVersion -> + quickMatrix.add([task: "tools-cli-stubs-sbtplugin", scala: "2.10.7", java: javaVersion]) + if (javaVersion != "1.6") { + // Tools do not compile on JDK6, Scala 2.11.x (see #1235) + quickMatrix.add([task: "tools-cli-stubs", scala: "2.11.12", java: javaVersion]) + } +} +quickMatrix.add([task: "tools-cli-stubs", scala: "2.12.4", java: mainJavaVersion]) +quickMatrix.add([task: "partestc", scala: "2.11.0", java: "1.8"]) // #3293, should be: 1.7 +quickMatrix.add([task: "sbtplugin-test", toolsscala: "2.10.7", sbt_version_override: "", java: "1.7"]) +quickMatrix.add([task: "sbtplugin-test", toolsscala: "2.12.4", sbt_version_override: "1.0.0", java: mainJavaVersion]) + +// The 'full' matrix +def fullMatrix = quickMatrix.clone() +otherScalaVersions.each { scalaVersion -> + fullMatrix.add([task: "main", scala: scalaVersion, java: mainJavaVersion]) +} +mainScalaVersions.each { scalaVersion -> + otherJavaVersions.each { javaVersion -> + quickMatrix.add([task: "test-suite-ecma-script5", scala: scalaVersion, java: javaVersion, testSuite: "testSuite"]) + quickMatrix.add([task: "test-suite-ecma-script6", scala: scalaVersion, java: javaVersion, testSuite: "testSuite"]) + } + if (!scalaVersion.startsWith("2.10.")) { + def javaVersion = scalaVersion.startsWith("2.11.") ? "1.7" : mainJavaVersion + fullMatrix.add([task: "partest-noopt", scala: scalaVersion, java: mainJavaVersion]) + fullMatrix.add([task: "partest-fullopt", scala: scalaVersion, java: mainJavaVersion]) + } +} +otherScalaVersions.each { scalaVersion -> + // Partest does not compile on Scala 2.11.4 (see #1215). + if (!scalaVersion.startsWith("2.10.") && scalaVersion != "2.11.4") { + fullMatrix.add([task: "partest-noopt", scala: scalaVersion, java: mainJavaVersion]) + fullMatrix.add([task: "partest-fastopt", scala: scalaVersion, java: mainJavaVersion]) + fullMatrix.add([task: "partest-fullopt", scala: scalaVersion, java: mainJavaVersion]) + } +} + +def Matrices = [ + quick: quickMatrix, + full: fullMatrix +] + +if (!Matrices.containsKey(selectedMatrix)) { + error("Nonexistent matrix '$selectedMatrix'") +} +def matrix = Matrices[selectedMatrix] + +buildDefs = [:] +matrix.each { taskDef -> + def taskName = taskDef.task + if (!Tasks.containsKey(taskName)) { + error("Nonexistent task '$taskName'") + } + def taskStr = Tasks[taskName] + def fullTaskName = taskName + + taskDef.each { name, value -> + if (name != 'task') { + taskStr = taskStr.replace('$' + name, value) + fullTaskName += " $name=$value" + } + } + + def ciScript = CIScriptPrelude + taskStr + + buildDefs.put(fullTaskName, { + node('linuxworker') { + checkout scm + sh "git clean -fdx" + writeFile file: 'ciscript.sh', text: ciScript, encoding: 'UTF-8' + retry(2) { + sh "echo '$fullTaskName' && cat ciscript.sh && sh ciscript.sh" + } + } + }) +} + +ansiColor('xterm') { + stage('Test') { + parallel(buildDefs) + } +} diff --git a/ci/jenkins-track/README.md b/ci/jenkins-track/README.md deleted file mode 100644 index 57438862ec..0000000000 --- a/ci/jenkins-track/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Scala.js Continuous Integration Jenkins tracking - -These files track execution scripts in our Jenkins installation. They -are only here to track changes we make to our Jenkins configuration. - -Unlike the files in the parent directory, any CI build should always -run with the configuration corresponding to the files on the master -branch. They specify how to run the tests (exact Jenkins -environment). - -The files in the parent directory specify what to run. diff --git a/ci/jenkins-track/scalajs-matrix-build.groovy b/ci/jenkins-track/scalajs-matrix-build.groovy deleted file mode 100644 index 53374b86c7..0000000000 --- a/ci/jenkins-track/scalajs-matrix-build.groovy +++ /dev/null @@ -1,59 +0,0 @@ -out.println("Trying to run matrix ${params.matrix}") - -out.println("Loading ci/matrix.xml") - -def matrixFile = build.properties.moduleRoot.child("ci/matrix.xml") -def fact = javax.xml.parsers.DocumentBuilderFactory.newInstance() -def builder = fact.newDocumentBuilder() - -ciMatrix = builder.parse(matrixFile.read()) - -out.println("Loading relevant definitions") - -buildDefs = [] - -fetchMatrix(params.matrix) - -def fetchMatrix(matrixName) { - def matrix = ciMatrix.getElementById(matrixName) - def list = matrix.getElementsByTagName("run") - for (int i = 0; i < list.getLength(); ++i) { - handleRun(list.item(i)) - } -} - -def handleRun(run) { - def attrs = run.getAttributes() - def matrixAttr = attrs.getNamedItem("matrix") - def taskAttr = attrs.getNamedItem("task") - if (matrixAttr != null) - fetchMatrix(matrixAttr.getValue()) - else if (taskAttr != null) - fetchTask(taskAttr.getValue(), run) -} - -def fetchTask(taskName, runElem) { - def taskElem = ciMatrix.getElementById(taskName) - def taskStr = taskElem.getTextContent() - def fullTaskName = taskName - - runElem.getElementsByTagName("v").each { v -> - def name = v.getAttribute("n") - def value = v.getTextContent() - taskStr = taskStr.replace('$' + name, value) - fullTaskName += " $name=$value" - } - - out.println("Found task: $fullTaskName") - - buildDefs.add({ - retry(2) { - build("scalajs-task-worker", - refspec: params.refspec, - sha1: params.sha1, - taskCommand: taskStr) - } - }) -} - -parallel(buildDefs) diff --git a/ci/jenkins-track/scalajs-task-worker.sh b/ci/jenkins-track/scalajs-task-worker.sh deleted file mode 100644 index b1b968092f..0000000000 --- a/ci/jenkins-track/scalajs-task-worker.sh +++ /dev/null @@ -1,67 +0,0 @@ -# Launcher script for task worker (dispatched by matrix-build) - -# Setup sbt home dirs - -LOC_SBT_BASE=/localhome/jenkins/scala-js-sbt-homes -LOC_SBT_BOOT=$LOC_SBT_BASE/sbt-boot -LOC_SBT_HOME=$LOC_SBT_BASE/sbt-home - -mkdir -p $LOC_SBT_BOOT -mkdir -p $LOC_SBT_HOME - -### Create tmp.sh ### - -# Node module path - -echo 'export NODE_PATH="$HOME/node_modules/"' > tmp.sh - -# sbt options - -echo 'SBT_OPTS="' \ - "-J-Xmx3G -J-XX:MaxPermSize=512M" \ - "-Djline.terminal=jline.UnsupportedTerminal" \ - "-Dsbt.boot.directory=$LOC_SBT_BOOT" \ - "-Dsbt.ivy.home=$LOC_SBT_HOME" \ - "-Divy.home=$LOC_SBT_HOME" \ - "-Dsbt.global.base=$LOC_SBT_BASE" \ - '"' >> tmp.sh - -# Define setJavaVersion - -echo 'setJavaVersion() {' >> tmp.sh -echo ' export JAVA_HOME=$HOME/apps/java-$1' >> tmp.sh -echo '}' >> tmp.sh - -# Define sbt and sbtretry - -echo 'sbtretry() {' >> tmp.sh -echo ' local TIMEOUT=35m' >> tmp.sh -echo ' echo "RUNNING timeout -k 5 $TIMEOUT sbt" "$@"' >> tmp.sh -echo ' timeout -k 5 $TIMEOUT sbt $SBT_OPTS "$@"' >> tmp.sh -echo ' local CODE=$?' >> tmp.sh -echo ' if [ "$CODE" -eq 124 ]; then' >> tmp.sh -echo ' echo "TIMEOUT after" $TIMEOUT' >> tmp.sh -echo ' fi' >> tmp.sh -echo ' if [ "$CODE" -ne 0 ]; then' >> tmp.sh -echo ' echo "RETRYING timeout -k 5 $TIMEOUT sbt" "$@"' >> tmp.sh -echo ' timeout -k 5 $TIMEOUT sbt $SBT_OPTS "$@"' >> tmp.sh -echo ' CODE=$?' >> tmp.sh -echo ' if [ "$CODE" -eq 124 ]; then' >> tmp.sh -echo ' echo "TIMEOUT after" $TIMEOUT' >> tmp.sh -echo ' fi' >> tmp.sh -echo ' if [ "$CODE" -ne 0 ]; then' >> tmp.sh -echo ' echo "FAILED TWICE"' >> tmp.sh -echo ' return $CODE' >> tmp.sh -echo ' fi' >> tmp.sh -echo ' fi' >> tmp.sh -echo '}' >> tmp.sh - -echo 'alias sbt="sbt $SBT_OPTS"' >> tmp.sh - -# Add the actual command - -echo "$taskCommand" >> tmp.sh - -# Run - -sh tmp.sh From 45a50bd37a32d36e63a1cc9f35e3a7d39951146c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 14 Mar 2018 10:00:29 +0100 Subject: [PATCH 0636/2665] Remove 2.12.0 from the CI matrix. Its support was dropped in 9e5cc2d5487a64367ba3830062790c8b017b32b2 but it was erroneously reintroduced in the CI matrix with the migration to Jenkins 2 in 9133751b4fb139712b744523ddd2a0ff36ddeac2. --- Jenkinsfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 4016549128..369b002399 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -376,7 +376,6 @@ def otherScalaVersions = [ "2.11.8", "2.11.11", "2.11.12", - "2.12.0", "2.12.1", "2.12.2", "2.12.3" From 6149bfdc41786a6e331746420375b14e0db2f890 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 14 Mar 2018 10:08:10 +0100 Subject: [PATCH 0637/2665] Fix typo: in cron syntax, 6 means Saturday, not Sunday. --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 0bf8971386..ea3405e1b5 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,7 +1,7 @@ // If not a PR, this is a long-lived branch, which should have a nightly build def triggers = [] if (!env.CHANGE_ID) { - // This is the 0.6.x series: run weekly on Sunday + // This is the 0.6.x series: run weekly on Saturday triggers << cron('H H(0-2) * * 6') } From b78d588c6ffc883ba48f00a29a378b7e0e36f987 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 14 Mar 2018 10:09:06 +0100 Subject: [PATCH 0638/2665] Only run partest in fastOpt mode for "other" Scala versions. It is highly unlikely that a bug would surface only in a non-main Scala version, only in noOpt or fullOpt. The potential rare benefit is not worth the CPU hours necessary for those builds. --- Jenkinsfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index ea3405e1b5..b98f453cfc 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -462,9 +462,7 @@ mainScalaVersions.each { scalaVersion -> otherScalaVersions.each { scalaVersion -> // Partest does not compile on Scala 2.11.4 (see #1215). if (!scalaVersion.startsWith("2.10.") && scalaVersion != "2.11.4") { - fullMatrix.add([task: "partest-noopt", scala: scalaVersion, java: mainJavaVersion]) fullMatrix.add([task: "partest-fastopt", scala: scalaVersion, java: mainJavaVersion]) - fullMatrix.add([task: "partest-fullopt", scala: scalaVersion, java: mainJavaVersion]) } } From 7b101b0d2b5de2c6f0e53385e7b86b79f7d276de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 14 Mar 2018 10:11:55 +0100 Subject: [PATCH 0639/2665] Give one more GB of memory to sbt on the CI. The bootstrap job in 2.10.2 almost consistently runs out of memory. --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index b98f453cfc..a03d0f5538 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -58,7 +58,7 @@ LOC_SBT_BASE="$LOCAL_HOME/scala-js-sbt-homes" LOC_SBT_BOOT="$LOC_SBT_BASE/sbt-boot" LOC_SBT_HOME="$LOC_SBT_BASE/sbt-home" -export SBT_OPTS="-J-Xmx4G -J-XX:MaxPermSize=512M -Dsbt.boot.directory=$LOC_SBT_BOOT -Dsbt.ivy.home=$LOC_SBT_HOME -Divy.home=$LOC_SBT_HOME -Dsbt.global.base=$LOC_SBT_BASE" +export SBT_OPTS="-J-Xmx5G -J-XX:MaxPermSize=512M -Dsbt.boot.directory=$LOC_SBT_BOOT -Dsbt.ivy.home=$LOC_SBT_HOME -Divy.home=$LOC_SBT_HOME -Dsbt.global.base=$LOC_SBT_BASE" export NODE_PATH="$HOME/node_modules/" From 05aac3ffbd0bd54a712412662c5a13d7674ebd1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 16 Mar 2018 22:47:08 +0100 Subject: [PATCH 0640/2665] Fix #3295: Do not set __ScalaJSEnv.javaSystemProperties in the sbt plugin. Instead, we set it up in our own build. That feature was initially included in the sbt plugin because our build needed it, but it has always been a bit hacky. In particular, it requires the sbt plugin to know too much about how JS files are executed, notably whether they are scripts or modules. Moreover, that feature was the only reason left that the sbt plugin needed to know about `__ScalaJSEnv` at all. --- project/Build.scala | 36 +++++++++++++++++-- .../sbtplugin/ScalaJSPluginInternal.scala | 24 +------------ 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index cd981732d2..072ac8a7c7 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -66,7 +66,36 @@ object MyScalaJSPlugin extends AutoPlugin { val isGeneratingEclipse = Properties.envOrElse("GENERATING_ECLIPSE", "false").toBoolean - override def projectSettings: Seq[Setting[_]] = Seq( + private val configSettings: Seq[Setting[_]] = Def.settings( + // Add a JS file defining Java system properties + jsExecutionFiles := { + val prev = jsExecutionFiles.value + + val javaSysPropsPattern = "-D([^=]*)=(.*)".r + val javaSystemProperties = javaOptions.value.collect { + case javaSysPropsPattern(propName, propValue) => (propName, propValue) + }.toMap + + if (javaSystemProperties.isEmpty) { + prev + } else { + val formattedProps = javaSystemProperties.map { + case (propName, propValue) => + "\"" + escapeJS(propName) + "\": \"" + escapeJS(propValue) + "\"" + } + val code = { + "var __ScalaJSEnv = (typeof __ScalaJSEnv === \"object\" && __ScalaJSEnv) ? __ScalaJSEnv : {};\n" + + "__ScalaJSEnv.javaSystemProperties = {" + formattedProps.mkString(", ") + "};\n" + } + val javaSysPropsFile = + new MemVirtualJSFile("setJavaSystemProperties.js").withContent(code) + + javaSysPropsFile +: prev + } + } + ) + + override def projectSettings: Seq[Setting[_]] = Def.settings( /* Remove libraryDependencies on ourselves; we use .dependsOn() instead * inside this build. */ @@ -94,7 +123,10 @@ object MyScalaJSPlugin extends AutoPlugin { "->https://raw.githubusercontent.com/scala-js/scala-js/v" + scalaJSVersion + "/" ) - } + }, + + inConfig(Compile)(configSettings), + inConfig(Test)(configSettings) ) } diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 83190994e0..a62608b45f 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -276,29 +276,7 @@ private[sbtplugin] object ScalaJSPluginInternal { */ jsExecutionFiles := (jsExecutionFiles in (This, Zero, This)).value, - // Optionally add a JS file defining Java system properties - jsExecutionFiles ++= { - val javaSysPropsPattern = "-D([^=]*)=(.*)".r - val javaSystemProperties = javaOptions.value.collect { - case javaSysPropsPattern(propName, propValue) => (propName, propValue) - }.toMap - - if (javaSystemProperties.isEmpty) { - Nil - } else { - val formattedProps = javaSystemProperties.map { - case (propName, propValue) => - "\"" + escapeJS(propName) + "\": \"" + escapeJS(propValue) + "\"" - } - val code = { - "var __ScalaJSEnv = (typeof __ScalaJSEnv === \"object\" && __ScalaJSEnv) ? __ScalaJSEnv : {};\n" + - "__ScalaJSEnv.javaSystemProperties = {" + formattedProps.mkString(", ") + "};\n" - } - Seq(new MemVirtualJSFile("setJavaSystemProperties.js").withContent(code)) - } - }, - - // Crucially, add the Scala.js linked file to the JS files + // Add the Scala.js linked file to the JS files (by default, the only one) jsExecutionFiles += new FileVirtualJSFile(scalaJSLinkedFile.value.data), From 4b5ca4826c3aeb0cd21a23f328786b86f2c55bd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 17 Mar 2018 10:44:35 +0100 Subject: [PATCH 0641/2665] Remove `WhitelistedTests.txt.orig` that should not have been there. This file was committed by mistake in 9f5e7a41f39d0f9dc7f7723799b9b19d37fed8fc. --- .../scalajs/2.11.5/WhitelistedTests.txt.orig | 3052 ----------------- 1 file changed, 3052 deletions(-) delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/WhitelistedTests.txt.orig diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/WhitelistedTests.txt.orig b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/WhitelistedTests.txt.orig deleted file mode 100644 index 176f364e46..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/WhitelistedTests.txt.orig +++ /dev/null @@ -1,3052 +0,0 @@ -pos/spec-super.scala -pos/t1035.scala -pos/t5897.scala -pos/irrefutable.scala -pos/spec-partialmap.scala -pos/tcpoly_seq.scala -pos/partialfun.scala -pos/t2795-new.scala -pos/clsrefine.scala -pos/t0774 -pos/t1070.scala -pos/t5957 -pos/looping-jsig.scala -pos/t3274.scala -pos/spec-fields-old.scala -pos/t262.scala -pos/t7486.scala -pos/t2261.scala -pos/t6600.scala -pos/t4786.scala -pos/t5406.scala -pos/tcpoly_late_method_params.scala -pos/t2726 -pos/pos-bug1210.scala -pos/t3312.scala -pos/manifest1-old.scala -pos/gadt-gilles.scala -pos/t4842.scala -pos/ted.scala -pos/NoCyclicReference.scala -pos/t3568.scala -pos/t0030.scala -pos/t2635.scala -pos/t7232b -pos/t0017.scala -pos/t812.scala -pos/t2179.scala -pos/t651.scala -pos/spurious-overload.scala -pos/t758.scala -pos/t4760.scala -pos/t1672.scala -pos/mixins.scala -pos/patterns.scala -pos/t1260.scala -pos/t6551.scala -pos/t2060.scala -pos/t6575a.scala -pos/t1318.scala -pos/t4266.scala -pos/t0695 -pos/protected-static -pos/t5738.scala -pos/t1226.scala -pos/t5013 -pos/t6215.scala -pos/t5692b -pos/traits.scala -pos/t2994a.scala -pos/t3371.scala -pos/t613.scala -pos/t6499.scala -pos/xlint1.scala -pos/t1150 -pos/sealed-final.scala -pos/test4a.scala -pos/t2664.scala -pos/t3528.scala -pos/t3174.scala -pos/t6994.scala -pos/t4812.scala -pos/t5777.scala -pos/t5223.scala -pos/t439.scala -pos/t3079.scala -pos/t5829.scala -pos/t0036.scala -pos/scoping2.scala -pos/t4717.scala -pos/t4257.scala -pos/t1210a.scala -pos/getClassType.scala -pos/t5330.scala -pos/t4524.scala -pos/t2945.scala -pos/t6562.scala -pos/t0273.scala -pos/override-object-yes.scala -pos/t7426.scala -pos/t6601 -pos/t3076 -pos/seq-ordering.scala -pos/spec-groups.scala -pos/t296.scala -pos/t5545 -pos/spec-multiplectors.scala -pos/t1789.scala -pos/t2569 -pos/ksbug1.scala -pos/t0599.scala -pos/local-objects.scala -pos/t0081.scala -pos/t5756.scala -pos/t7126.scala -pos/t7716.scala -pos/t2797.scala -pos/t5399.scala -pos/t1101 -pos/t767.scala -pos/contrib467.scala -pos/t7532b -pos/self-type-override.scala -pos/t4853.scala -pos/t839.scala -pos/t5644 -pos/t5853.scala -pos/t5178.scala -pos/unapplyNeedsMemberType.scala -pos/t5390.scala -pos/t6575b.scala -pos/t151.scala -pos/t2665.scala -pos/t5120.scala -pos/erasure-nsquared.scala -pos/arrays3.scala -pos/t3136.scala -pos/inline-access-levels -pos/t3972.scala -pos/t2591.scala -pos/t3486 -pos/variances-flip.scala -pos/annotated-original -pos/typesafecons.scala -pos/stable.scala -pos/t1996.scala -pos/t3037.scala -pos/t1711 -pos/t3374.scala -pos/t0029.scala -pos/t3278.scala -pos/matthias3.scala -pos/t5546.scala -pos/t4020.scala -pos/matthias4.scala -pos/value-class-override-spec.scala -pos/arrays2.scala -pos/t5119.scala -pos/t2613.scala -pos/t4070b.scala -pos/virtpatmat_exist_uncurry.scala -pos/modules1.scala -pos/spec-constr-new.scala -pos/t6335.scala -pos/t675.scala -pos/t0644.scala -pos/t5892.scala -pos/t360.scala -pos/override.scala -pos/t1798.scala -pos/strip-tvars-for-lubbasetypes.scala -pos/hk-infer.scala -pos/t2119.scala -pos/t0231.scala -pos/t1459 -pos/t1381-new.scala -pos/t2610.scala -pos/t2708.scala -pos/t5604b -pos/t3951 -pos/t361.scala -pos/t319.scala -pos/largecasetest.scala -pos/switchUnbox.scala -pos/typetags.scala -pos/java-access-pos -pos/t803.scala -pos/t3898.scala -pos/t5692a -pos/t2421.scala -pos/t1102 -pos/t0654.scala -pos/exhaust_alternatives.scala -pos/t807.scala -pos/t5702-pos-infix-star.scala -pos/t1186 -pos/t1439.scala -pos/t7427.scala -pos/virtpatmat_binding_opt.scala -pos/t247.scala -pos/abstract.scala -pos/gen-traversable-methods.scala -pos/t2795-old.scala -pos/t5639 -pos/t2667.scala -pos/t2405.scala -pos/t1438.scala -pos/SI-7100.scala -pos/t1659.scala -pos/unchecked-a.scala -pos/t3636.scala -pos/t6745.scala -pos/t2809.scala -pos/t7022.scala -pos/t6447.scala -pos/t6367.scala -pos/t5846.scala -pos/lubs.scala -pos/t1987a.scala -pos/spec-arrays.scala -pos/virtpatmat_anonfun_for.scala -pos/listpattern.scala -pos/t5742.scala -pos/test5refine.scala -pos/t5604 -pos/return_thistype.scala -pos/t348plus.scala -pos/t3420.scala -pos/t3440.scala -pos/maxim1.scala -pos/caseClassInMethod.scala -pos/t7239.scala -pos/t3833.scala -pos/t6675.scala -pos/t4402 -pos/t5953.scala -pos/t1152 -pos/t0591.scala -pos/t210.scala -pos/t7035.scala -pos/t5769.scala -pos/pmbug.scala -pos/t2331.scala -pos/t5240.scala -pos/t304.scala -pos/annotated-treecopy -pos/t2081.scala -pos/t0904.scala -pos/t7649.scala -pos/t3498-new.scala -pos/contrib701.scala -pos/t6624.scala -pos/t3924.scala -pos/t374.scala -pos/t1642 -pos/t1591_pos.scala -pos/depmet_implicit_oopsla_session_2.scala -pos/t5899.scala -pos/thistype.scala -pos/t4176b.scala -pos/elidable-tparams.scala -pos/lambdalift.scala -pos/nothing_manifest_disambig-old.scala -pos/t372.scala -pos/t5399a.scala -pos/t2782.scala -pos/patmat-extract-tparam.scala -pos/t4114.scala -pos/unapplyVal.scala -pos/t2486.scala -pos/t5877b.scala -pos/t0625.scala -pos/t6358_2.scala -pos/viewtest1.scala -pos/t1237.scala -pos/scala-singleton.scala -pos/t1254 -pos/t5504 -pos/bounds.scala -pos/t3631.scala -pos/t3177.scala -pos/unapplyContexts2.scala -pos/t0438.scala -pos/t1642b.scala -pos/inferbroadtype.scala -pos/t1858.scala -pos/t3731.scala -pos/t6963c.scala -pos/classtag-pos.scala -pos/t6221.scala -pos/t3343.scala -pos/spec-asseenfrom.scala -pos/t604.scala -pos/spec-example1.scala -pos/t0786.scala -pos/annot-inner.scala -pos/t5886.scala -pos/t1056.scala -pos/t294 -pos/spec-Function1.scala -pos/t1836 -pos/spec-private.scala -pos/depmet_implicit_tpbetareduce.scala -pos/exhaust_2.scala -pos/t7532 -pos/t5175.scala -pos/t802.scala -pos/t5809.scala -pos/tcpoly_typesub.scala -pos/t6029.scala -pos/contextbounds-implicits-new.scala -pos/t3480.scala -pos/patterns3.scala -pos/caseaccs.scala -pos/spec-sparsearray-old.scala -pos/patterns1213.scala -pos/spec-traits.scala -pos/t0020.scala -pos/cycle -pos/t5968.scala -pos/typealiases.scala -pos/init.scala -pos/t697.scala -pos/t2693.scala -pos/t2377 -pos/unapplyGeneric.scala -pos/t1385.scala -pos/t3363-old.scala -pos/t1236.scala -pos/t0068.scala -pos/t4052.scala -pos/lambdalift1.scala -pos/z1730.scala -pos/variances-local.scala -pos/virtpatmat_gadt_array.scala -pos/t2421_delitedsl.scala -pos/t5626.scala -pos/t690.scala -pos/t711.scala -pos/t6547.scala -pos/t1937 -pos/t3999 -pos/SI-7060.scala -pos/t2305.scala -pos/t2168.scala -pos/t2660.scala -pos/t1693.scala -pos/inliner2.scala -pos/t2799.scala -pos/t6966.scala -pos/t1001.scala -pos/S5.scala -pos/t0301.scala -pos/t1048.scala -pos/t415.scala -pos/t6386.scala -pos/t2187.scala -pos/hashhash-overloads.scala -pos/t6921.scala -pos/t0227.scala -pos/t6556.scala -pos/t3946 -pos/t1053.scala -pos/t1000.scala -pos/t0586.scala -pos/t7011.scala -pos/t7329.scala -pos/t4975.scala -pos/t1131.scala -pos/t1027.scala -pos/t2913.scala -pos/t3494.scala -pos/t5606.scala -pos/t4716.scala -pos/tcpoly_gm.scala -pos/t4859.scala -pos/t514.scala -pos/lexical.scala -pos/t2624.scala -pos/t4036.scala -pos/t2741 -pos/t703.scala -pos/five-dot-f.scala -pos/t805.scala -pos/strings.scala -pos/t2433 -pos/t6925.scala -pos/t1085.scala -pos/t7461 -pos/t1942 -pos/spec-lists.scala -pos/t3349 -pos/tcpoly_infer_ticket474.scala -pos/t1614 -pos/virtpatmat_reach_const.scala -pos/t2194.scala -pos/t6976 -pos/t1560.scala -pos/t6891.scala -pos/t3883.scala -pos/infersingle.scala -pos/gui.scala -pos/t1164.scala -pos/t3175-pos.scala -pos/t4336.scala -pos/annotations2.scala -pos/proj-rec-test.scala -pos/t2973.scala -pos/t1123.scala -pos/t6205.scala -pos/t5727.scala -pos/t6537.scala -pos/t6712.scala -pos/t3866.scala -pos/t4831.scala -pos/selftails.scala -pos/t397.scala -pos/spec-vector.scala -pos/t7233b.scala -pos/t1391.scala -pos/spec.scala -pos/t3106.scala -pos/contextbounds-implicits-old.scala -pos/packageobjs.scala -pos/michel3.scala -pos/t628.scala -pos/collections.scala -pos/tcpoly_boundedmonad.scala -pos/t7668.scala -pos/t0032.scala -pos/t0069.scala -pos/t4345.scala -pos/t3521 -pos/t3071.scala -pos/tcpoly_infer_easy.scala -pos/t289.scala -pos/t4365 -pos/rangepos-anonapply.scala -pos/t5033.scala -pos/lambda.scala -pos/S8.scala -pos/t6014.scala -pos/t1785.scala -pos/t6034.scala -pos/t7433.scala -pos/imp2-pos.scala -pos/t0504.scala -pos/t1272.scala -pos/t0612 -pos/value-class-override-no-spec.scala -pos/overloaded-unapply.scala -pos/t5859.scala -pos/chang -pos/localmodules.scala -pos/t4237.scala -pos/rangepos-patmat.scala -pos/t1974.scala -pos/t0054.scala -pos/michel2.scala -pos/t0770.scala -pos/t1146.scala -pos/t2441pos.scala -pos/t5099.scala -pos/tcpoly_seq_typealias.scala -pos/t946.scala -pos/tcpoly_infer_ticket1864.scala -pos/t4579.scala -pos/t4737 -pos/t7377b.scala -pos/t616.scala -pos/t201.scala -pos/t6355pos.scala -pos/escapes2.scala -pos/t1675.scala -pos/t3890.scala -pos/t6040.scala -pos/spec-tailcall.scala -pos/existentials.scala -pos/t5317.scala -pos/t7782b.scala -pos/t4758.scala -pos/t7296.scala -pos/t6896.scala -pos/cls1.scala -pos/t402.scala -pos/gosh.scala -pos/t2619.scala -pos/javaConversions-2.10-regression.scala -pos/t759.scala -pos/t5259.scala -pos/t5130.scala -pos/t5156.scala -pos/t0905.scala -pos/package-implicit -pos/t2669.scala -pos/trait-parents.scala -pos/virtpatmat_exhaust.scala -pos/patterns1.scala -pos/t7014 -pos/t1231 -pos/t1751 -pos/t7233.scala -pos/t6022.scala -pos/tcpoly_checkkinds_mix.scala -pos/depmet_implicit_norm_ret.scala -pos/package-case.scala -pos/philippe4.scala -pos/michel6.scala -pos/t4188.scala -pos/t3936 -pos/t1280.scala -pos/t6722.scala -pos/t796.scala -pos/t5542.scala -pos/t3927.scala -pos/t2293.scala -pos/t3800.scala -pos/t7285a.scala -pos/t927.scala -pos/t4494.scala -pos/t3864 -pos/ilya2 -pos/t2940 -pos/S1.scala -pos/tcpoly_wildcards.scala -pos/tryexpr.scala -pos/t6089b.scala -pos/depmet_implicit_oopsla_zipwith.scala -pos/t245.scala -pos/t6146.scala -pos/t1782 -pos/t851.scala -pos/spec-thistype.scala -pos/tcpoly_poly.scala -pos/t6815_import.scala -pos/t4649.scala -pos/t0453.scala -pos/t5020.scala -pos/ilya -pos/t2435.scala -pos/t1279a.scala -pos/t2171.scala -pos/t1957.scala -pos/gadts2.scala -pos/t3567 -pos/Z.scala -pos/t1203b -pos/nested2.scala -pos/t1896 -pos/viewtest2.scala -pos/t5541.scala -pos/existentials-harmful.scala -pos/t4063.scala -pos/t6485a -pos/t1208.scala -pos/t5041.scala -pos/unapplyComplex.scala -pos/t3384.scala -pos/t4112.scala -pos/t788.scala -pos/hklub0.scala -pos/t757.scala -pos/t1197 -pos/t359.scala -pos/t5667.scala -pos/t1107a.scala -pos/virtpatmat_castbinder.scala -pos/t267.scala -pos/t3419 -pos/t3861.scala -pos/t6797.scala -pos/spec-localdefs.scala -pos/t3404 -pos/t4457_1.scala -pos/matthias5.scala -pos/spec-polymeth.scala -pos/kinds.scala -pos/t2310.scala -pos/t6552.scala -pos/valdefs.scala -pos/hkarray.scala -pos/homonym.scala -pos/t1235 -pos/t3429 -pos/t0053.scala -pos/depmet_implicit_chaining_zw.scala -pos/virtpatmat_partialfun_nsdnho.scala -pos/t6664.scala -pos/ticket2251.scala -pos/t3495.scala -pos/super -pos/t121.scala -pos/javaConversions-2.10-ambiguity.scala -pos/t1803.scala -pos/t5877.scala -pos/t0085.scala -pos/t3582.scala -pos/t2939.scala -pos/t1422_pos.scala -pos/manifest1-new.scala -pos/t7505.scala -pos/t5720-ownerous.scala -pos/misc-unapply_pos.scala -pos/tcpoly_variance_pos.scala -pos/t5127.scala -pos/t6123-explaintypes-implicits.scala -pos/t2764 -pos/presuperContext.scala -pos/spec-simple.scala -pos/t3120 -pos/t5729.scala -pos/tcpoly_infer_ticket716.scala -pos/tcpoly_bounds1.scala -pos/t7369.scala -pos/imports-pos.scala -pos/t5654.scala -pos/t0123.scala -pos/raw-map -pos/t5330b.scala -pos/t6485b -pos/t6072.scala -pos/t5692c.scala -pos/t3430.scala -pos/tcpoly_param_scoping.scala -pos/t6204-b.scala -pos/attachments-typed-another-ident -pos/t5359.scala -pos/ticket2197.scala -pos/t720.scala -pos/t2130-2.scala -pos/t2260.scala -pos/t0304.scala -pos/t464.scala -pos/spec-maps.scala -pos/annotDepMethType.scala -pos/t6117.scala -pos/t911.scala -pos/t757a.scala -pos/t2504.scala -pos/t1381-old.scala -pos/t1232 -pos/needstypeearly.scala -pos/moduletrans.scala -pos/t4957.scala -pos/kinzer.scala -pos/t318.scala -pos/widen-existential.scala -pos/t0095.scala -pos/t566.scala -pos/tcpoly_overloaded.scala -pos/t7516 -pos/t7232 -pos/t698.scala -pos/t0002.scala -pos/t0288 -pos/t2994b.scala -pos/cls.scala -pos/t3622 -pos/t3671.scala -pos/tcpoly_subst.scala -pos/t5703 -pos/depmet_implicit_oopsla_session_simpler.scala -pos/t5022.scala -pos/builders.scala -pos/spec-foo.scala -pos/t756.scala -pos/t1569.scala -pos/implicit-unwrap-tc.scala -pos/t3688.scala -pos/t5198.scala -pos/t432.scala -pos/t6022b.scala -pos/channels.scala -pos/t1075.scala -pos/null.scala -pos/t1840 -pos/t6479.scala -pos/t6311.scala -pos/t0039.scala -pos/t1119.scala -pos/t573.scala -pos/t1136.scala -pos/t3938 -pos/spec-sealed.scala -pos/tcpoly_return_overriding.scala -pos/t3582b.scala -pos/t229.scala -pos/t3498-old.scala -pos/t531.scala -pos/t4545.scala -pos/t6651.scala -pos/t2133.scala -pos/tinondefcons.scala -pos/t6157.scala -pos/t6358.scala -pos/t7690.scala -pos/t5779-numeq-warn.scala -pos/list-extractor.scala -pos/t892.scala -pos/t2127.scala -pos/t7180.scala -pos/nullary_poly.scala -pos/virtpatmat_exist3.scala -pos/t1176 -pos/spec-funs.scala -pos/specialize10.scala -pos/t6514.scala -pos/exhaustive_heuristics.scala -pos/t0066.scala -pos/t460.scala -pos/t2130-1.scala -pos/t124.scala -pos/annotations.scala -pos/pat_gilles.scala -pos/array-interfaces.scala -pos/t6210.scala -pos/t3792.scala -pos/implicits-old.scala -pos/t389.scala -pos/t115.scala -pos/virtpatmat_exhaust_unchecked.scala -pos/scoping3.scala -pos/t6033.scala -pos/depmet_implicit_oopsla_session.scala -pos/t602.scala -pos/test5.scala -pos/t611.scala -pos/t5932.scala -pos/t4910.scala -pos/unapplySeq.scala -pos/t344.scala -pos/t3363-new.scala -pos/t4018.scala -pos/t4553.scala -pos/t5082.scala -pos/t3869.scala -pos/t3836.scala -pos/tcpoly_typeapp.scala -pos/t1409 -pos/nonlocal-unchecked.scala -pos/t0082.scala -pos/z1720.scala -pos/t7232c -pos/t2018.scala -pos/t3943 -pos/t2187-2.scala -pos/unicode-decode.scala -pos/t4757 -pos/t0710.scala -pos/t0305.scala -pos/t160.scala -pos/t7591 -pos/simplelists.scala -pos/List1.scala -pos/t516.scala -pos/t6648.scala -pos/t5165 -pos/t0055.scala -pos/t4744 -pos/t7377 -pos/t5726.scala -pos/t0091.scala -pos/t6595.scala -pos/compile.scala -pos/depmet_1_pos.scala -pos/t7364 -pos/philippe3.scala -pos/spec-doubledef-old.scala -pos/t4651.scala -pos/tcpoly_infer_implicit_tuple_wrapper.scala -pos/t6274.scala -pos/tcpoly_infer_explicit_tuple_wrapper.scala -pos/ticket2201.scala -pos/spec-fields-new.scala -pos/optmatch.scala -pos/t7517.scala -pos/t3560.scala -pos/t0165.scala -pos/t0872.scala -pos/t522.scala -pos/t2234.scala -pos/t5031_2.scala -pos/tcpoly_method.scala -pos/t6482.scala -pos/pos-bug1241.scala -pos/implicits-new.scala -pos/t2484.scala -pos/t2425.scala -pos/t1049.scala -pos/michel4.scala -pos/t5958.scala -pos/virtpatmat_instof_valuetype.scala -pos/spec-t6286.scala -pos/t873.scala -pos/t3137.scala -pos/Transactions.scala -pos/t0064.scala -pos/t7486-named.scala -pos/t5444.scala -pos/simple-exceptions.scala -pos/t1006.scala -pos/t7200b.scala -pos/t3777.scala -pos/t4840.scala -pos/t211.scala -pos/nullary.scala -pos/michel1.scala -pos/t5031_3 -pos/typealias_dubious.scala -pos/spec-doubledef-new.scala -pos/philippe1.scala -pos/thistypes.scala -pos/t3570.scala -pos/t6516.scala -pos/context.scala -pos/t3808.scala -pos/philippe2.scala -pos/constfold.scala -pos/t1292.scala -pos/t1147.scala -pos/t404.scala -pos/t4430.scala -pos/A.scala -pos/spec-partially.scala -pos/t5796.scala -pos/t2409 -pos/t284-pos.scala -pos/t5313.scala -pos/t2464 -pos/t1591b.scala -pos/hk-match -pos/t595.scala -pos/t6846.scala -pos/t6162-inheritance.scala -pos/relax_implicit_divergence.scala -pos/patterns2.scala -pos/t4692.scala -pos/t3837.scala -pos/t661.scala -pos/t2810.scala -pos/depexists.scala -pos/virtpatmat_exist4.scala -pos/t5245.scala -pos/t7190.scala -pos/isApplicableSafe.scala -pos/t6204-a.scala -pos/t0076.scala -pos/t1756.scala -pos/t1745 -pos/t6091.scala -pos/t0154.scala -pos/t530.scala -pos/t2094.scala -pos/t1034.scala -pos/t6084.scala -pos/t2454.scala -pos/t2956 -pos/tcpoly_ticket2096.scala -pos/attachments-typed-ident -pos/polymorphic-case-class.scala -pos/t252.scala -pos/spec-constr-old.scala -pos/t2421c.scala -pos/t122.scala -pos/t6574.scala -pos/t3859.scala -pos/spec-params-old.scala -pos/t1196 -pos/t4593.scala -pos/t596.scala -pos/t615.scala -pos/t7689.scala -pos/t3960.scala -pos/t3986.scala -pos/exbound.scala -pos/t2545.scala -pos/t1722 -pos/t159.scala -pos/t3272.scala -pos/t6301.scala -pos/t2794.scala -pos/t3048.scala -pos/t4970.scala -pos/t607.scala -pos/FPTest.scala -pos/test1.scala -pos/t3252.scala -pos/t4176.scala -pos/t112606A.scala -pos/t2183.scala -pos/t430-feb09.scala -pos/t6275.scala -pos/t1832.scala -pos/t8965.scala -pos/t7596b -pos/t8900.scala -pos/t9008.scala -pos/t7704.scala -pos/t7459c.scala -pos/sammy_override.scala -pos/t8828.scala -pos/t8868c -pos/t7459d.scala -pos/t8267.scala -pos/t8844.scala -pos/t8868a -pos/t8894.scala -pos/t7459a.scala -pos/t7596c -pos/t8498.scala -pos/t8868b -pos/t5413.scala -pos/t8781 -pos/t8934a -pos/t8310.scala -pos/t3439.scala -pos/t6582_exhaust_big.scala -pos/t8954 -pos/t5217.scala -pos/t7459b.scala -pos/t9018.scala -pos/sammy_exist.scala -pos/t8893.scala -pos/t7596 -pos/t8793.scala -pos/sammy_overload.scala -pos/t6051.scala -pos/t7683-stop-after-parser -pos/t7750.scala -pos/t5454.scala -pos/t8962.scala -pos/t8947 -pos/t8719 -pos/t8410.scala -pos/patmat-suppress.scala -pos/t8999.scala -pos/t8743.scala - -neg/volatile_no_override.scala -neg/t800.scala -neg/t5426.scala -neg/t2462a.scala -neg/t2641.scala -neg/classtags_dont_use_typetags.scala -neg/t5031 -neg/t2275b.scala -neg/macro-qmarkqmarkqmark.scala -neg/t4879.scala -neg/t5956.scala -neg/t4196.scala -neg/reify_ann2b.scala -neg/t6666b.scala -neg/warn-unused-privates.scala -neg/t6928.scala -neg/t6337.scala -neg/sealed-java-enums.scala -neg/t563.scala -neg/t900.scala -neg/deadline-inf-illegal.scala -neg/t766.scala -neg/t5429.scala -neg/overloaded-implicit.scala -neg/t875.scala -neg/abstract-class-error -neg/unchecked2.scala -neg/predef-masking.scala -neg/viewtest.scala -neg/macro-noexpand -neg/varargs.scala -neg/t963b.scala -neg/t909.scala -neg/sensitive2.scala -neg/t5390b.scala -neg/abstraction-from-volatile-type-error.scala -neg/macro-exception -neg/t4431.scala -neg/t5689.scala -neg/valueclasses.scala -neg/overload.scala -neg/t0204.scala -neg/t908.scala -neg/t750 -neg/patmatexhaust.scala -neg/macro-invalidusage-badtargs -neg/t1168.scala -neg/t5761.scala -neg/t0503.scala -neg/t7235.scala -neg/t1215.scala -neg/primitive-sigs-1 -neg/t5578.scala -neg/names-defaults-neg-warn.scala -neg/t6436b.scala -neg/t3098 -neg/t910.scala -neg/parstar.scala -neg/t4568.scala -neg/newpat_unreachable.scala -neg/warn-unused-imports.scala -neg/t1181.scala -neg/t5903c -neg/t7294.scala -neg/t4091.scala -neg/t5452-old.scala -neg/t5696.scala -neg/t0209.scala -neg/t2910.scala -neg/t7388.scala -neg/noMember2.scala -neg/no-predef.scala -neg/t6952.scala -neg/t1909b.scala -neg/abstract-report2.scala -neg/t5318.scala -neg/t6074.scala -neg/t7171.scala -neg/abstract-vars.scala -neg/unchecked-impossible.scala -neg/variances-refinement.scala -neg/t3453.scala -neg/t5189.scala -neg/t4302.scala -neg/xmltruncated7.scala -neg/t8217-local-alias-requires-rhs.scala -neg/t7602.scala -neg/t8869.scala -neg/t9008.scala -neg/sammy_error_exist_no_crash.scala -neg/t2866.scala -neg/t8597b.scala -neg/t5691.scala -neg/t8534b.scala -neg/t5091.scala -neg/literals.scala -neg/t8534.scala -neg/t8890.scala -neg/t8764.scala -neg/t9008b.scala -neg/t8731.scala -neg/t8291.scala -neg/t8597.scala -neg/t5639b -neg/t6582_exhaust_big.scala - -run/t7249.scala -run/t3563.scala -run/t6111.scala -run/classtags_multi.scala -run/t5201.scala -run/checked.scala -run/valueclasses-classtag-basic.scala -run/t7171.scala -run/t5053.scala -run/t4535.scala -run/t5923d -run/t7291.scala -run/partialfun.scala -run/macro-term-declared-in-package-object -run/mapValues.scala -run/gadts.scala -run/t2386-new.scala -run/virtpatmat_stringinterp.scala -run/t657.scala -run/t0017.scala -run/t5713 -run/t576.scala -run/t3580.scala -run/virtpatmat_partial.scala -run/t6646.scala -run/mixins.scala -run/t1672.scala -run/macro-expand-implicit-macro-has-implicit -run/tuple-match.scala -run/t7039.scala -run/virtpatmat_opt_sharing.scala -run/virtpatmat_casting.scala -run/t2176.scala -run/eta-expand-star2.scala -run/macro-impl-relaxed -run/intmap.scala -run/t751.scala -run/t1591.scala -run/macro-typecheck-implicitsdisabled -run/t6911.scala -run/t5604.scala -run/macro-term-declared-in-default-param -run/collection-stacks.scala -run/multi-array.scala -run/t4560b.scala -run/buffer-slice.scala -run/t5629.scala -run/t6690.scala -run/matchonstream.scala -run/t3603.scala -run/lazy-exprs.scala -run/macro-quasiquotes -run/Course-2002-13.scala -run/t6337a.scala -run/exoticnames.scala -run/t0936.scala -run/runtime-richChar.scala -run/t6272.scala -run/t7215.scala -run/t1939.scala -run/ReverseSeqView.scala -run/lazy-leaks.scala -run/t0048.scala -run/t3994.scala -run/t2241.scala -run/t627.scala -run/t5966.scala -run/getClassTest-valueClass.scala -run/t3619.scala -run/t1300.scala -run/t2177.scala -run/t3760.scala -run/t1829.scala -run/macro-expand-implicit-macro-is-view -run/t889.scala -run/QueueTest.scala -run/t4537 -run/t3699.scala -run/t1192.scala -run/macro-expand-tparams-bounds -run/macro-expand-nullary-generic -run/t1434.scala -run/t6443-varargs.scala -run/macro-term-declared-in-trait -run/t4080.scala -run/matcharraytail.scala -run/infiniteloop.scala -run/t5733.scala -run/virtpatmat_nested_lists.scala -run/t5158.scala -run/t6695.scala -run/t6070.scala -run/t4558.scala -run/exc2.scala -run/patmat-behavior-2.scala -run/overloads.scala -run/t6957.scala -run/transform.scala -run/t5500.scala -run/t6663.scala -run/castsingleton.scala -run/t4147.scala -run/virtpatmat_staging.scala -run/t4565_1.scala -run/t5588.scala -run/run-bug4840.scala -run/t3496.scala -run/t5867.scala -run/search.scala -run/t3112.scala -run/hashsetremove.scala -run/t6443.scala -run/macro-expand-tparams-prefix -run/contrib674.scala -run/t3508.scala -run/t4300.scala -run/virtpatmat_typed.scala -run/macro-term-declared-in-class-object -run/map_test.scala -run/t5040.scala -run/t4827b.scala -run/lift-and-unlift.scala -run/t6574b.scala -run/t7240 -run/t3984.scala -run/virtpatmat_tailcalls_verifyerror.scala -run/macro-term-declared-in-class-class -run/emptypf.scala -run/t6104.scala -run/t2818.scala -run/t3761-overload-byname.scala -run/t2526.scala -run/phantomValueClass.scala -run/t3126.scala -run/arybufgrow.scala -run/t3980.scala -run/t7375b -run/t6077_patmat_cse_irrefutable.scala -run/classmanifests_new_core.scala -run/t3395.scala -run/name-based-patmat.scala -run/inliner-infer.scala -run/t5171.scala -run/t3726.scala -run/null-hash.scala -run/t4027.scala -run/t2544.scala -run/patmatnew.scala -run/t5923b -run/t7242.scala -run/classtags_core.scala -run/streamWithFilter.scala -run/t3038b.scala -run/macro-expand-varargs-explicit-over-nonvarargs-good -run/macro-divergence-spurious -run/macro-duplicate -run/t2958.scala -run/patch-boundary.scala -run/t2333.scala -run/lazy-override-run.scala -run/macro-quasiinvalidbody-c -run/t5037.scala -run/takeAndDrop.scala -run/t6126.scala -run/t0883.scala -run/t7617a -run/t4171.scala -run/empty-array.scala -run/t7198.scala -run/t493.scala -run/genericValueClass.scala -run/t0677-old.scala -run/t1373.scala -run/t4461.scala -run/t6011b.scala -run/t7584.scala -run/t3935.scala -run/t6928-run.scala -run/t744.scala -run/t3241.scala -run/blame_eye_triple_eee-double.scala -run/t3829.scala -run/t5577.scala -run/t5914.scala -run/t601.scala -run/t5610.scala -run/macro-basic-mamd-mi -run/t6150.scala -run/stringbuilder.scala -run/t7290.scala -run/t6888.scala -run/t6327.scala -run/virtpatmat_unapplyseq.scala -run/t4656.scala -run/macro-term-declared-in-method -run/macro-expand-implicit-macro-is-implicit -run/blame_eye_triple_eee-float.scala -run/t4482.scala -run/t5488.scala -run/matchemptyarray.scala -run/t3714.scala -run/richWrapperEquals.scala -run/t5328.scala -run/stream_flatmap_odds.scala -run/implicitclasses.scala -run/t6827.scala -run/t6394b -run/complicatedmatch.scala -run/valueclasses-classmanifest-basic.scala -run/unreachable.scala -run/caseclasses.scala -run/withIndex.scala -run/exc1.scala -run/amp.scala -run/t1423.scala -run/t594.scala -run/t6353.scala -run/byname.scala -run/vector1.scala -run/t5879.scala -run/t1048.scala -run/t5080.scala -run/t4190.scala -run/caseClassEquality.scala -run/macro-enclosures -run/collections-toSelf.scala -run/implicits.scala -run/finalvar.scala -run/lazy-locals.scala -run/t7231.scala -run/t0508.scala -run/t6628.scala -run/t6406-regextract.scala -run/t0911.scala -run/t4013c.scala -run/t3502.scala -run/t5648.scala -run/retclosure.scala -run/t2857.scala -run/t4859.scala -run/t5162.scala -run/t3038.scala -run/classof.scala -run/t4062.scala -run/unapplyArray.scala -run/t4297.scala -run/t5923a -run/t1537.scala -run/boolexprs.scala -run/valueclasses-classtag-generic.scala -run/macro-term-declared-in-anonymous -run/tcpoly_monads.scala -run/t5407.scala -run/scan.scala -run/forvaleq.scala -run/null-and-intersect.scala -run/t7047 -run/t0607.scala -run/sequenceComparisons.scala -run/t4396.scala -run/macro-undetparams-consfromsls -run/t2029.scala -run/t1220.scala -run/option-fold.scala -run/t5284c.scala -run/macro-auto-duplicate -run/t3529.scala -run/t4697.scala -run/t2251.scala -run/t5300.scala -run/virtpatmat_valdef.scala -run/t2147.scala -run/virtpatmat_extends_product.scala -run/list_map.scala -run/t1333.scala -run/matchbytes.scala -run/valueclasses-classmanifest-existential.scala -run/records.scala -run/t3088.scala -run/macro-def-path-dependent -run/t6443-by-name.scala -run/t1044.scala -run/delay-good.scala -run/case-class-23.scala -run/weakconform.scala -run/patmat-bind-typed.scala -run/t4835.scala -run/t3097.scala -run/t405.scala -run/existentials.scala -run/t2876.scala -run/t4809.scala -run/t1427.scala -run/t6135.scala -run/t3575.scala -run/t5688.scala -run/t6900.scala -run/macro-expand-unapply-a -run/t6677b.scala -run/t7375a.scala -run/t7300.scala -run/t6246.scala -run/typed-annotated -run/elidable-noflags.scala -run/t0042.scala -run/t3050.scala -run/t4536.scala -run/NestedClasses.scala -run/t3877.scala -run/seqlike-kmp.scala -run/t5907.scala -run/t266.scala -run/missingparams.scala -run/t2255.scala -run/t3488.scala -run/t3950.scala -run/typealias_overriding.scala -run/constant-optimization.scala -run/t7507.scala -run/t6090.scala -run/t4582.scala -run/macro-term-declared-in-class -run/macro-typecheck-macrosdisabled2 -run/t3425.scala -run/t4935.scala -run/t3326.scala -run/boolord.scala -run/t1141.scala -run/virtpatmat_unapply.scala -run/t5971.scala -run/t3651.scala -run/macro-sip19-revised -run/pure-args-byname-noinline.scala -run/preinits.scala -run/t5532.scala -run/concat-two-strings.scala -run/t3269.scala -run/macro-impl-default-params -run/t2162.scala -run/matchonseq.scala -run/t5428.scala -run/macro-expand-overload -run/t4660.scala -run/enrich-gentraversable.scala -run/macro-expand-override -run/t4054.scala -run/t4753.scala -run/macro-typecheck-macrosdisabled -run/t2308a.scala -run/duplicate-meth.scala -run/interop_classtags_are_classmanifests.scala -run/t3232.scala -run/t2075.scala -run/virtpatmat_partial_backquoted.scala -run/try-2.scala -run/macro-openmacros -run/macro-undetparams-macroitself -run/t6318_derived.scala -run/deprecate-early-type-defs.scala -run/dead-code-elimination.scala -run/t4827.scala -run/Course-2002-07.scala -run/slice-strings.scala -run/t6292.scala -run/t6206.scala -run/t1042.scala -run/t1718.scala -run/t2074_2.scala -run/arraycopy.scala -run/indexedSeq.scala -run/macro-term-declared-in-implicit-class -run/t3511.scala -run/t6290.scala -run/distinct.scala -run/virtpatmat_alts.scala -run/valueclasses-pavlov.scala -run/exceptions.scala -run/t1368.scala -run/t5856.scala -run/t6968.scala -run/names-defaults.scala -run/macro-expand-tparams-implicit -run/t5881.scala -run/t3540.scala -run/virtpatmat_try.scala -run/t7181.scala -run/value-class-extractor.scala -run/value-class-extractor-2.scala -run/t3150.scala -run/exc.scala -run/delay-bad.scala -run/infix.scala -run/t1309.scala -run/t6370.scala -run/t6725-2.scala -run/macro-impl-tparam-typetag-is-optional -run/macro-term-declared-in-block -run/matchnull.scala -run/t2127.scala -run/t7325.scala -run/groupby.scala -run/t3932.scala -run/t4871.scala -run/longmap.scala -run/t1524.scala -run/t6187b.scala -run/kmpSliceSearch.scala -run/t7088.scala -run/t5804.scala -run/stringbuilder-drop.scala -run/t5753_1 -pos/cyclics-pos.scala -pos/cfcrash.scala -pos/tcpoly_higherorder_bound_method.scala -pos/t5084.scala -pos/trait-force-info.scala -pos/macro-qmarkqmarkqmark.scala -pos/t7785.scala -pos/nested.scala -pos/t3152.scala -pos/t5031 -pos/t6925b.scala -pos/t1107b -pos/t5012.scala -pos/virtpatmat_obj_in_case.scala -pos/t4938.scala -pos/t3856.scala -pos/spec-cyclic.scala -pos/aliases.scala -pos/typerep_pos.scala -pos/t119.scala -pos/t1050.scala -pos/t3670.scala -pos/t6145.scala -pos/t7315.scala -pos/t5930.scala -pos/t789.scala -pos/t5071.scala -pos/t4731.scala -pos/t4547.scala -pos/t2038.scala -pos/testCoercionThis.scala -pos/t2444.scala -pos/t5744 -pos/t780.scala -pos/t1722-A.scala -pos/virtpatmat_exist1.scala -pos/t6225.scala -pos/t762.scala -pos/t0204.scala -pos/rebind.scala -pos/spec-short.scala -pos/comp-rec-test.scala -pos/lub-dealias-widen.scala -pos/t1168.scala -pos/modules.scala -pos/t4220.scala -pos/t4070.scala -pos/t175.scala -pos/t2500.scala -pos/t5029.scala -pos/itay.scala -pos/t4202.scala -pos/t1987b -pos/t3534.scala -pos/infer2-pos.scala -pos/spec-sparsearray-new.scala -pos/t7091.scala -pos/ticket0137.scala -pos/collectGenericCC.scala -pos/t640.scala -pos/t4305.scala -pos/extractor-types.scala -pos/t3880.scala -pos/spec-annotations.scala -pos/t3577.scala -pos/compile1.scala -pos/spec-t3497.scala -pos/hkrange.scala -pos/t287.scala -pos/t7294.scala -pos/t6008.scala -pos/t4432.scala -pos/CustomGlobal.scala -pos/patmat.scala -pos/t2413 -pos/t2910.scala -pos/t592.scala -pos/t6245 -pos/infer.scala -pos/t7228.scala -pos/compound.scala -pos/attributes.scala -pos/t6771.scala -pos/t1090.scala -pos/t684.scala -pos/t577.scala -pos/t4273.scala -pos/t6278-synth-def.scala -pos/t6184.scala -neg/t0214.scala -neg/t4842.scala -neg/t6214.scala -neg/reify_nested_inner_refers_to_local.scala -neg/t576.scala -neg/t5969.scala -neg/tcpoly_variance.scala -neg/t7509.scala -neg/mixins.scala -neg/parent-inherited-twice-error.scala -neg/macro-abort -neg/constructor-init-order.scala -neg/t6042.scala -neg/t0590.scala -neg/eta-expand-star-deprecation.scala -neg/t4221.scala -neg/t6263.scala -neg/t783.scala -neg/t5554.scala -neg/macro-invalidsig-params-badtype -neg/multi-array.scala -neg/raw-types-stubs -neg/spec-overrides.scala -neg/t836.scala -neg/t7289_status_quo.scala -neg/t5675.scala -neg/macro-quasiquotes -neg/t6667.scala -neg/t6597.scala -neg/t6264.scala -neg/t0345.scala -neg/t7294b.scala -neg/t5340.scala -neg/t2144.scala -neg/t1010.scala -neg/t1838.scala -neg/t5189b.scala -neg/reify_metalevel_breach_-1_refers_to_1.scala -neg/t6601 -neg/wellkinded_wrongarity.scala -neg/t3909.scala -neg/t876.scala -neg/t5390.scala -neg/unit2anyref.scala -neg/t0351.scala -neg/t5120.scala -neg/t1038.scala -neg/t5878.scala -neg/qualifying-class-error-2.scala -neg/t3816.scala -neg/tailrec.scala -neg/volatile.scala -neg/t944.scala -neg/t1705.scala -neg/t3977.scala -neg/t5553_2.scala -neg/t5318c.scala -neg/overload-msg.scala -neg/t5440.scala -neg/t6335.scala -neg/compile-time-only-b.scala -neg/t501.scala -neg/override.scala -neg/t663.scala -neg/t5892.scala -neg/t1980.scala -neg/macro-false-deprecation-warning -neg/t5148.scala -neg/t585.scala -neg/t3776.scala -neg/interop_classtags_arenot_manifests.scala -neg/t4044.scala -neg/macro-invalidusage-nontypeable -neg/t6375.scala -neg/t500.scala -neg/t4877.scala -neg/t5357.scala -neg/interop_abstypetags_arenot_manifests.scala -neg/t4460a.scala -neg/t5318b.scala -neg/t3234.scala -neg/t4440.scala -neg/t6663.scala -neg/t6357.scala -neg/gadts1.scala -neg/cyclics.scala -neg/t5060.scala -neg/scopes.scala -run/t4013.scala -run/macro-expand-tparams-explicit -run/tuples.scala -run/t5753_2 -run/t0528.scala -run/t5105.scala -run/t7341.scala -run/t3670.scala -run/t2594_tcpoly.scala -run/t3895.scala -run/t0668.scala -run/slices.scala -run/t6666a.scala -run/valueclasses-classmanifest-generic.scala -run/t2316_run.scala -run/t3004.scala -run/viewtest.scala -run/t6481.scala -run/t0005.scala -run/t4766.scala -run/t5500b.scala -run/t7407b.scala -run/backreferences.scala -run/arrayview.scala -run/t629.scala -run/t5903c -run/unittest_collection.scala -run/spec-nlreturn.scala -run/macro-term-declared-in-object-object -run/triple-quoted-expr.scala -run/t5937.scala -run/t6011c.scala -run/macro-expand-implicit-argument -run/try.scala -run/t1987b -run/t6089.scala -run/macro-range -run/t2524.scala -run/t4770.scala -run/virtpatmat_unapplyprod.scala -run/t1535.scala -run/ctor-order.scala -pos/t5210.scala -pos/t5384.scala -pos/rangepos.scala -pos/t443.scala -pos/t1480.scala -pos/t116.scala -pos/seqtest2.scala -pos/scoping1.scala -pos/t4269.scala -pos/lookupswitch.scala -pos/t3642 -pos/t5706.scala -pos/SI-5788.scala -pos/t7264 -pos/t0031.scala -pos/macro-deprecate-dont-touch-backquotedidents.scala -pos/t6815.scala -pos/test4refine.scala -pos/michel5.scala -pos/t0851.scala -pos/t1185.scala -pos/sudoku.scala -pos/t7520.scala -pos/t6208.scala -pos/t3411.scala -pos/t295.scala -pos/S3.scala -pos/t0674.scala -pos/t6664b.scala -pos/variances_pos.scala -pos/liftcode_polymorphic.scala -pos/t3174b.scala -pos/t7232d -pos/t578.scala -pos/implicit-infix-ops.scala -pos/t4363.scala -pos/t532.scala -pos/exponential-spec.scala -pos/t599.scala -pos/t5862.scala -pos/t4603 -pos/t3676.scala -pos/t1357.scala -pos/native-warning.scala -pos/t1230 -pos/t6028 -pos/t4275.scala -pos/overloaded_extractor_and_regular_def.scala -pos/t4205 -pos/matthias1.scala -pos/testcast.scala -pos/generic-sigs.scala -pos/t0093.scala -pos/specializes-sym-crash.scala -pos/t0061.scala -pos/t2429.scala -pos/t694.scala -pos/javaReadsSigs -pos/t2023.scala -pos/t704.scala -pos/t2208_pos.scala -pos/t5137.scala -pos/t2683.scala -pos/t0049.scala -pos/t1029 -pos/t4243.scala -pos/typerep-stephane.scala -pos/t177.scala -pos/t5967.scala -pos/t430.scala -pos/virtpatmat_infer_single_1.scala -pos/pat_iuli.scala -pos/t1071.scala -pos/t7226.scala -pos/t1843.scala -pos/t419.scala -pos/t7364b -pos/t1159.scala -pos/t5305.scala -pos/t7694.scala -pos/t6047.scala -pos/t3578.scala -pos/t2082.scala -pos/setter-not-implicit.scala -pos/t1133.scala -pos/t3862.scala -pos/t942 -pos/nothing_manifest_disambig-new.scala -pos/iterator-traversable-mix.scala -pos/eta.scala -pos/test4.scala -pos/t2691.scala -pos/t4502.scala -pos/t7183.scala -pos/protected-t1010.scala -pos/X.scala -pos/virtpatmat_exist2.scala -pos/t4911.scala -pos/t3477.scala -pos/t4173.scala -pos/t7782.scala -pos/t2399.scala -pos/virtpatmat_alts_subst.scala -pos/propagate.scala -pos/t2421b_pos.scala -pos/t183.scala -pos/t7033.scala -pos/t3612.scala -pos/t5330c.scala -pos/t3020.scala -pos/t4869.scala -pos/t3373.scala -pos/spec-params-new.scala -pos/t3672.scala -pos/t4501.scala -pos/t1565.scala -pos/t3774.scala -pos/t6942 -pos/t845.scala -pos/t3240.scala - -neg/t3275.scala -neg/t421.scala -neg/t5702-neg-bad-brace.scala -neg/t3663 -neg/badtok-1.scala -neg/t677.scala -neg/t7756b.scala -neg/t6534.scala -neg/t6276.scala -neg/t5762.scala -neg/abstract.scala -neg/t2405.scala -neg/t0418.scala -neg/t5390c.scala -neg/lazyvals.scala -neg/lubs.scala -neg/abstract-report.scala -neg/t4163.scala -neg/t5702-neg-bad-and-wild.scala -neg/macro-invalidret -neg/t6728.scala -neg/t5152.scala -neg/t1432.scala -neg/abstract-inaccessible.scala -neg/import-precedence.scala -neg/t2462b.scala -neg/macro-invalidusage-presuper -neg/specification-scopes -neg/t6048.scala -neg/t4079 -neg/macro-basic-mamdmi -neg/t7020.scala -neg/t3015.scala -neg/t0207.scala -neg/t2296b -neg/t0673 -neg/t3761-overload-byname.scala -neg/t6675.scala -neg/t5529.scala -neg/sensitive.scala -neg/t742.scala -neg/t5067.scala -neg/t6162-overriding.scala -neg/variances.scala -neg/t5728.scala -neg/t6323a.scala -neg/compile-time-only-a.scala -neg/t6795.scala -neg/t2494.scala -neg/t3649.scala -neg/macro-invalidsig -neg/t2796.scala -neg/t112706A.scala -neg/t0764.scala -neg/t3757 -neg/t1431.scala -neg/exhausting.scala -neg/t1523.scala -neg/t779.scala -neg/xmltruncated1.scala -neg/t2208.scala -neg/t2078.scala -neg/t521.scala -neg/null-unsoundness.scala -neg/stmt-expr-discard.scala -neg/t0513.scala -neg/unchecked-abstract.scala -neg/t4460c.scala -neg/divergent-implicit.scala -neg/t5078.scala -neg/t1701.scala -neg/t0816.scala -neg/t1672b.scala -neg/macro-invalidusage-badbounds -neg/tailrec-2.scala -neg/t4064.scala -neg/reflection-names-neg.scala -neg/t5510.scala -neg/t3873.scala -neg/tailrec-3.scala -neg/t0226.scala -neg/t2031.scala -neg/t633.scala -neg/constrs.scala -neg/anyval-anyref-parent.scala -neg/t7290.scala -neg/t1041.scala -neg/patternalts.scala -neg/error_tooManyArgsPattern.scala -neg/checksensibleUnit.scala -neg/t6539 -neg/t4417.scala -neg/wellkinded_app.scala -neg/for-comprehension-old.scala -neg/t2779.scala -neg/object-not-a-value.scala -neg/t2968b.scala -neg/t6483.scala -neg/t6902.scala -neg/t6963a.scala -neg/t3399.scala -neg/t0015.scala -neg/t3995.scala -neg/t276.scala -neg/t6758.scala -neg/t2441.scala -neg/cycle-bounds.scala -neg/t1241.scala -neg/t4137.scala -neg/unicode-unterminated-quote.scala -neg/t4762.scala -neg/typeerror.scala -neg/implicits.scala -neg/t961.scala -neg/ambiguous-float-dots2.scala -neg/t2416.scala -neg/t5799.scala -neg/t7285.scala -neg/implicit-shadow.scala -neg/t2388.scala -neg/java-access-neg -neg/found-req-variance.scala -neg/hk-bad-bounds.scala -neg/t3224.scala -neg/t1033.scala -neg/t7385.scala -neg/t5882.scala -neg/t4541.scala -neg/t2973.scala -neg/t6406-regextract.scala -neg/t6666.scala -neg/t4831.scala -neg/t425.scala -neg/t1845.scala -neg/t3683b.scala -neg/t2801.scala -neg/t6083.scala -neg/t0528neg.scala -neg/stringinterpolation_macro-neg.scala -neg/t668.scala -neg/t5666.scala -neg/t4271.scala -neg/interop_typetags_arenot_classmanifests.scala -neg/t1355.scala -neg/t715.scala -neg/t7238.scala -neg/t7473.scala -neg/t7292-removal.scala -neg/tcpoly_infer_ticket1162.scala -neg/t4098.scala -neg/t6013 -neg/t6227.scala -neg/t464-neg.scala -neg/badtok-3.scala -neg/t6082.scala -neg/anytrait.scala -neg/valueclasses-doubledefs.scala -neg/t7519.scala -neg/overloaded-unapply.scala -neg/t1163.scala -neg/wellkinded_bounds.scala -neg/t7292-deprecation.scala -neg/t5044.scala -neg/t0842.scala -neg/t6436.scala -neg/interop_typetags_arenot_classtags.scala -neg/t3653.scala -neg/higherkind_novalue.scala -neg/t935.scala -neg/t6040.scala -neg/annot-nonconst.scala -neg/macro-deprecate-idents.scala -neg/illegal-stmt-start.scala -neg/t565.scala -neg/case-collision.scala -neg/t3209.scala -neg/t5821.scala -neg/abstract-class-2.scala -neg/t846.scala -neg/quasiquotes-syntax-error-position.scala -neg/t3987.scala -neg/t877.scala -neg/t0117.scala -neg/t692.scala -neg/t6666d.scala -neg/t5702-neg-ugly-xbrace.scala -neg/t7752.scala -neg/case-collision2.scala -neg/t6526.scala -neg/t2213.scala -neg/t7756a.scala -neg/macro-override-macro-overrides-abstract-method-a -neg/tcpoly_ticket2101.scala -neg/delayed-init-ref.scala -neg/caseinherit.scala -neg/t3189.scala -neg/unchecked-suppress.scala -neg/t2180.scala -neg/t1371.scala -neg/macro-cyclic -neg/t6123-explaintypes-macros -neg/t4134.scala -neg/t691.scala -neg/t2421b.scala -neg/t4691_exhaust_extractor.scala -neg/t4419.scala -neg/t5801.scala -neg/t650.scala -neg/t5735.scala -neg/t696.scala -neg/t882.scala -neg/t2968.scala -neg/t7507.scala -neg/macro-invalidusage-badargs -neg/macro-reify-typetag-typeparams-notags -neg/wellkinded_app2.scala -neg/t4425b.scala -neg/t2296a -neg/t1878.scala -neg/t649.scala -neg/override-object-no.scala -neg/t4174.scala -neg/t2070.scala -neg/sabin2.scala -neg/t5903e -neg/t6566a.scala -neg/finitary-error.scala -neg/t4818.scala -neg/t3614.scala -neg/t6666c.scala -neg/ticket513.scala -neg/suggest-similar.scala -neg/t4457_1.scala -neg/t6666e.scala -neg/tcpoly_bounds.scala -neg/t4727.scala -neg/t4425.scala -neg/macro-invalidusage-methodvaluesyntax -neg/t3854.scala -neg/t3006.scala -neg/t5580b.scala -neg/t5378.scala -neg/t639.scala -neg/wrong-args-for-none.scala -neg/t7171b.scala -neg/t5361.scala -neg/unreachablechar.scala -neg/t5572.scala -neg/t7757a.scala -neg/macro-invalidimpl -neg/t2773.scala -neg/t6359.scala -neg/saito.scala -neg/xmltruncated2.scala -neg/t667.scala -neg/t3934.scala -neg/t6771b.scala -neg/t4584.scala -neg/wellkinded_wrongarity2.scala -neg/t7369.scala -neg/t1477.scala -neg/t5617.scala -neg/t7299.scala -neg/faculty.scala -neg/virtpatmat_reach_null.scala -neg/macro-reify-typetag-hktypeparams-notags -neg/t1224.scala -neg/xmltruncated3.scala -neg/t1872.scala -neg/t558.scala -neg/t7110.scala -neg/any-vs-anyref.scala -neg/t6340.scala -neg/t4166.scala -neg/t2918.scala -neg/t5856.scala -neg/t4989.scala -neg/t0003.scala -neg/t1183.scala -neg/t963.scala -neg/t4515.scala -neg/valueclasses-pavlov.scala -neg/t608.scala -neg/choices.scala -neg/patmat-type-check.scala -neg/valueclasses-impl-restrictions.scala -neg/imp2.scala -neg/protected-constructors.scala -neg/t6788.scala -neg/nullary-override.scala -neg/t200.scala -neg/t343.scala -neg/names-defaults-neg-ref.scala -neg/tcpoly_typealias.scala -neg/classtags_contextbound_b.scala -neg/t729.scala -neg/t5683.scala -neg/t4928.scala -neg/t700.scala -neg/t7669.scala -neg/macro-invalidshape -neg/t6011.scala -neg/t7325.scala -neg/check-dead.scala -neg/t550.scala -neg/t5663-badwarneq.scala -neg/t0699 -neg/nopredefs.scala -neg/t3507-old.scala -neg/t5352.scala -neg/t6336.scala -neg/interop_classmanifests_arenot_typetags.scala -neg/sealed-final-neg.scala -neg/t2102.scala -neg/t7636.scala -neg/t5031b -neg/t798.scala -neg/t5702-neg-bad-xbrace.scala -neg/t0899.scala -neg/cyclics-import.scala -neg/badtok-2.scala -neg/t473.scala -neg/t3160ambiguous.scala -neg/t5106.scala -neg/t1286 -neg/macro-override-macro-overrides-abstract-method-b -neg/t0259.scala -neg/t510.scala -neg/t3836.scala -neg/t5830.scala -neg/t1548 -neg/t5580a.scala -neg/forward.scala -neg/t591.scala -neg/t6558b.scala -neg/t556.scala -neg/xmltruncated4.scala -neg/t5497.scala -neg/t409.scala -neg/t6283.scala -neg/override-object-flag.scala -neg/constructor-prefix-error.scala -neg/eta-expand-star.scala -neg/t3392.scala -neg/t1275.scala -neg/nested-fn-print.scala -neg/t7330.scala -neg/t2275a.scala -neg/t630.scala -neg/t4270.scala -neg/t2775.scala -neg/pat_unreachable.scala -neg/t4158.scala -neg/unit-returns-value.scala -neg/t1422.scala -neg/reify_metalevel_breach_-1_refers_to_0_b.scala -neg/reassignment.scala -neg/t3683a.scala -neg/noMember1.scala -neg/macro-without-xmacros-b -neg/t1106.scala -neg/t5182.scala -neg/t6889.scala -neg/t4217.scala -neg/t7501 -neg/t5063.scala -neg/t1009.scala -neg/t997.scala -neg/unchecked.scala -neg/classtags_contextbound_c.scala -neg/applydynamic_sip.scala -neg/t7715.scala -neg/t588.scala -neg/t6667b.scala -neg/t7757b.scala -neg/t4069.scala -neg/t515.scala -neg/variances2.scala -neg/t1049.scala -neg/t7289.scala -neg/t1623.scala -neg/permanent-blindness.scala -neg/t5803.scala -neg/super-cast-or-test.scala -neg/nonlocal-warning.scala -neg/t5687.scala -neg/t5903a -neg/t6566b.scala -neg/unchecked-knowable.scala -neg/t5093.scala -neg/protected-static-fail -neg/type-diagnostics.scala -neg/forgot-interpolator.scala -neg/interop_abstypetags_arenot_classmanifests.scala -neg/t5376.scala -neg/t545.scala -neg/xmlcorner.scala -neg/switch.scala -neg/depmet_1.scala -neg/abstract-concrete-methods.scala -neg/t4987.scala -neg/t5452-new.scala -neg/t750b -neg/unchecked-refinement.scala -neg/t418.scala -neg/t5354.scala -neg/t3736.scala -neg/t631.scala -neg/t6829.scala -neg/t0218.scala -neg/volatile-intersection.scala -neg/t412.scala -neg/t693.scala -neg/t4882.scala -neg/t1960.scala -neg/macro-divergence-controlled -neg/t712.scala -neg/t5544 -neg/t3222.scala -neg/t3604.scala -neg/t1112.scala -neg/t7157 -neg/accesses.scala -neg/t452.scala -neg/t6162-inheritance -neg/t2442 -neg/t6567.scala -neg/lazy-override.scala -neg/abstract-explaintypes.scala -neg/nested-annotation.scala -neg/t5753 -neg/t4283b -neg/t3691.scala -neg/infix-op-positions.scala -neg/t3403.scala -neg/t4851 -neg/structural.scala -neg/error_dependentMethodTpeConversionToFunction.scala -neg/t5839.scala -neg/t5553_1.scala -neg/reify_metalevel_breach_+0_refers_to_1.scala -neg/t752.scala -neg/t6574.scala -neg/t3714-neg.scala -neg/t4457_2.scala -neg/t2148.scala -neg/t1364.scala -neg/saferJavaConversions.scala -neg/t414.scala -neg/t5493.scala -neg/classtags_contextbound_a.scala -neg/reify_metalevel_breach_-1_refers_to_0_a.scala -neg/t3118.scala -neg/t512.scala -neg/t2336.scala -neg/t856.scala -neg/xmltruncated6.scala -neg/t2206.scala -neg/virtpatmat_unreach_select.scala -neg/t6258.scala -neg/t6815.scala -neg/not-possible-cause.scala -neg/dbldef.scala -neg/qualifying-class-error-1.scala -neg/t835.scala -neg/t5455.scala -neg/t6558.scala -neg/t708.scala -neg/macro-nontypeablebody -neg/t0565.scala -neg/xmltruncated5.scala -neg/t5390d.scala -neg/t520.scala -neg/t6138.scala -neg/macro-without-xmacros-a -neg/t7214neg.scala -neg/t2870.scala -neg/t593.scala -neg/t4541b.scala -neg/t4460b.scala -neg/t284.scala -neg/t2488.scala -neg/macro-override-method-overrides-macro -neg/interop_abstypetags_arenot_classtags.scala -neg/t3769.scala -neg/warn-inferred-any.scala -neg/t664.scala -neg/t5903d -neg/t562.scala -neg/t2316.scala -neg/t0152.scala -neg/migration28.scala -neg/t6443c.scala -neg/tcpoly_override.scala -neg/t7324.scala -neg/t987.scala -neg/t5903b -neg/t3481.scala -neg/t6912.scala -neg/tcpoly_variance_enforce.scala -neg/t3913.scala -neg/names-defaults-neg.scala -neg/t765.scala -neg/t5358.scala -neg/t391.scala -neg/serialversionuid-not-const.scala -neg/t771.scala -neg/t0903.scala -neg/catch-all.scala -neg/classmanifests_new_deprecations.scala -neg/t0606.scala -neg/t5189_inferred.scala -neg/macro-reify-typetag-useabstypetag -neg/t5543.scala -neg/logImplicits.scala -neg/interop_typetags_without_classtags_arenot_manifests.scala -neg/t6535.scala -neg/t7259.scala -neg/t2139.scala -neg/t278.scala -neg/t5564.scala -neg/unchecked3.scala -neg/virtpatmat_reach_sealed_unsealed.scala -neg/checksensible.scala -neg/t7721.scala -run/t3798.scala -run/macro-expand-varargs-explicit-over-varargs -run/t3888.scala -run/t0677-new.scala -run/t3273.scala -run/t3763.scala -run/t2755.scala -run/t920.scala -run/t5610a.scala -run/literals.scala -run/proxy.scala -run/unapply.scala -run/t5830.scala -run/array-addition.scala -run/macro-expand-nullary-nongeneric -run/macro-basic-ma-mdmi -run/valueclasses-constr.scala -run/t1247.scala -run/t3487.scala -run/rawstrings.scala -run/patmat-seqs.scala -run/eta-expand-star.scala -run/t7436.scala -run/t3996.scala -run/constructors.scala -run/t498.scala -run/t3835.scala -run/t298.scala -run/t2867.scala -run/t7120 -run/virtpatmat_literal.scala -run/t2175.scala -run/t2503.scala -run/t3026.scala -run/t603.scala -run/t0091.scala -run/t6394a -run/macro-expand-varargs-implicit-over-varargs -run/t7407.scala -run/t2552.scala -run/virtpatmat_npe.scala -run/macro-sip19 -run/t6644.scala -run/t6614.scala -run/t2005.scala -run/t4680.scala -run/t5903a -run/classtags_contextbound.scala -run/Course-2002-05.scala -run/applydynamic_sip.scala -run/t1766.scala -run/retsynch.scala -run/t7715.scala -run/t102.scala -run/nonlocalreturn.scala -run/macro-reify-staticXXX -run/Course-2002-06.scala -run/t6863.scala -run/t6500.scala -run/macro-impl-rename-context -run/t4351.scala -run/t5009.scala -run/macro-term-declared-in-annotation -run/t6271.scala -run/array-existential-bound.scala -run/t6443b.scala -run/t1987.scala -run/MutableListTest.scala -run/t7571.scala -run/t5488-fn.scala -run/macro-bodyexpandstoimpl -run/macro-reify-ref-to-packageless -run/t2212.scala -run/macro-expand-varargs-implicit-over-nonvarargs -run/t0807.scala -run/patmat-behavior.scala -run/t2446.scala -run/tuple-zipped.scala -run/breakout.scala -run/t4122.scala -run/macro-settings -run/t7157 -run/t1323.scala -run/t4013b.scala -run/t6309.scala -run/t4047.scala -run/t5544 -run/t978.scala -run/t3361.scala -run/t6611.scala -run/t5387.scala -run/t5656.scala -run/t4897.scala -run/numeric-range.scala -run/t4777.scala -run/Course-2002-03.scala -run/string-extractor.scala -run/view-headoption.scala -run/patmat_unapp_abstype-new.scala -run/stream-stack-overflow-filter-map.scala -run/macro-impl-tparam-only-in-impl -run/t6559.scala -run/macro-reify-tagful-a -run/macro-expand-multiple-arglists -run/t4709.scala -run/t3509.scala -run/t5284b.scala -run/t7617b -run/t3923.scala -run/virtpatmat_apply.scala -run/t363.scala -run/manifests-undeprecated-in-2.10.0.scala -run/matchintasany.scala -run/t3970.scala -run/t4996.scala -run/t5530.scala -run/macro-term-declared-in-object-class -run/t3242b.scala -run/indexedSeq-apply.scala -run/t107.scala -run/t2337.scala -run/t2754.scala -run/flat-flat-flat.scala -run/t6673.scala -run/interpolationMultiline2.scala -run/t0631.scala -run/t2800.scala -run/t6506.scala -run/t6260.scala -run/t2418.scala -run/t4415.scala -run/classmanifests_new_alias.scala -run/t5380.scala -run/tcpoly_parseridioms.scala -run/t1747.scala -run/t5903d -run/t3530.scala -run/t216.scala -run/macro-term-declared-in-refinement -run/t4592.scala -run/t2488.scala -run/t3327.scala -run/t5614.scala -run/t5903b -run/iterables.scala -run/t3964.scala -run/t6329_vanilla.scala -run/t3038c -run/t1697.scala -run/t2030.scala -run/t3397.scala -run/t1005.scala -run/t3353.scala -run/t1466.scala -run/t3186.scala -run/tcpoly_overriding.scala -run/t5394.scala -run/t5284.scala -run/unboxingBug.scala -run/t7200.scala -run/macro-reify-basic -run/t153.scala -run/iterator3444.scala -run/macro-expand-implicit-macro-is-val -run/macro-basic-ma-md-mi -run/interpolationArgs.scala -run/t4954.scala -run/t3645.scala -run/transpose.scala -run/t3887.scala -run/t4288.scala -run/unittest_iterator.scala -run/t5543.scala -run/macro-term-declared-in-object -run/iq.scala -run/t2788.scala -run/t2027.scala -run/macro-expand-recursive -run/t949.scala -run/t1909b.scala -run/delambdafy-nested-by-name.scala -run/delambdafy-two-lambdas.scala -run/macro-blackbox-materialization -run/lists-run.scala -run/macro-parse-position -run/macro-parse-position-malformed -run/macro-whitebox-dynamic-materialization -run/macro-whitebox-extractor -run/macro-vampire-false-warning -run/macro-whitebox-fundep-materialization -run/macro-whitebox-structural -run/mutable-treeset.scala -run/static-module-method.scala -run/sort.scala -run/t1909.scala -run/t1909c.scala -run/t3346a.scala -run/t3346d.scala -run/t3346f.scala -run/t3346h.scala -run/t3346g.scala -run/t3832.scala -run/t4742.scala -run/t5377.scala -run/t5923c.scala -run/t6188.scala -run/t6333.scala -run/t6385.scala -run/t7899.scala -run/t7899-regression.scala -run/t7584b.scala -run/t7223.scala -run/t7859 -run/t7868.scala -run/t7871 -run/arrayclone-new.scala -run/arrayclone-old.scala -run/bitsets.scala -run/comparable-comparator.scala -run/colltest1.scala -run/t2106.scala -run/t5986.scala -run/view-iterator-stream.scala -run/array-charSeq.scala -pos/signatures -pos/t1263 -pos/t3249 -neg/t4749.scala -neg/main1.scala -neg/t7251 -neg/t7494-after-terminal -neg/t7494-before-parser -neg/t7494-right-after-terminal -run/lazy-traits.scala -run/OrderingTest.scala -run/ReplacementMatching.scala -run/patmat-finally.scala -run/t3158.scala -run/t3346e.scala -run/t4398.scala -run/t4930.scala -run/t6534.scala -pos/sammy_scope.scala -pos/delambdafy-patterns.scala -pos/private-types-after-typer.scala -pos/delambdafy-lambdalift.scala -pos/sammy_poly.scala -pos/sammy_single.scala -pos/SI-4012-b.scala -pos/sammy_twice.scala -pos/t3160.scala -pos/t1014.scala -pos/t4970b.scala -pos/t2698.scala -pos/t5845.scala -pos/t6201.scala -pos/t6260a.scala -pos/t7688.scala -pos/t7818.scala -pos/t1203a.scala -pos/t7834.scala -pos/t7853.scala -pos/t7815.scala -pos/t7853-partial-function.scala -pos/t7864.scala -pos/t7928.scala -pos/t7902.scala -pos/t7944.scala -pos/t7847 -neg/accesses2.scala -neg/bad-advice.scala -neg/gadts2.scala -neg/gadts2-strict.scala -neg/macro-bundle-abstract.scala -neg/macro-bundle-object.scala -neg/macro-bundle-trait.scala -neg/macro-blackbox-dynamic-materialization -neg/macro-blackbox-extractor -neg/run-gadts-strict.scala -neg/macro-blackbox-structural -neg/sammy_restrictions.scala -neg/sammy_wrong_arity.scala -neg/t2462c.scala -neg/t3346b.scala -neg/t1909-object.scala -neg/macro-blackbox-fundep-materialization -neg/t3346c.scala -neg/t3871.scala -neg/t3871b.scala -neg/t3971.scala -neg/t3346i.scala -neg/t6120.scala -neg/t6260c.scala -neg/t6680a.scala -neg/t7239.scala -neg/t7007.scala -neg/t7605-deprecation.scala -neg/t7622-missing-required.scala -neg/t7629-view-bounds-deprecation.scala -neg/t7834neg.scala -neg/t7783.scala -neg/t7848-interp-warn.scala -neg/t7519-b -neg/t7622-missing-dependency -neg/t7870.scala -neg/t7877.scala -neg/t7895.scala -neg/t7895b.scala -neg/t7899.scala -neg/t7895c.scala -neg/t7859 -run/t4752.scala -run/t2087-and-2400.scala -run/t3855.scala -run/t6637.scala -run/t6731.scala -pos/t3999b.scala -run/t0432.scala -run/t2514.scala -run/t7817.scala -run/t874.scala -run/type-currying.scala -run/t3616.scala -run/t3687.scala -run/t4570.scala -run/t5612.scala -run/t1110.scala -run/t2636.scala -run/verify-ctor.scala -run/t3647.scala -run/t4560.scala -run/t6632.scala -run/hashCodeBoxesRunTime.scala -run/richs.scala -run/t6725-1.scala -pos/t7776.scala -run/fors.scala -run/t6706.scala -run/t3175.scala -run/delambdafy-dependent-on-param-subst.scala -run/t4332b.scala -run/t8048a -run/t8017 -run/t7985b.scala -run/t8100.scala -run/patmat-mix-case-extractor.scala -run/t4750.scala -run/t7912.scala -run/delambdafy-dependent-on-param-subst-2.scala -run/t8048b -run/t8091.scala -run/macroPlugins-macroRuntime -run/macro-default-params -run/t6355.scala -run/t7777 -run/t8002.scala -run/t8015-ffc.scala -run/macro-subpatterns -run/t7985.scala -run/macroPlugins-macroArgs -run/t7326.scala -run/t5045.scala -run/value-class-partial-func-depmet.scala -run/t6329_vanilla_bug.scala -run/macroPlugins-macroExpand -run/t8010.scala -run/macroPlugins-typedMacroBody -run/t7406.scala -pos/t8146a.scala -pos/t8046c.scala -pos/t8002-nested-scope.scala -pos/t8132.scala -pos/t8045.scala -pos/overzealous-assert-genbcode.scala -pos/t8128.scala -pos/t8013 -pos/t8064b -pos/t6780.scala -pos/t7987 -pos/bcode_throw_null -pos/t8064 -pos/t8046.scala -pos/t6231.scala -pos/t7983.scala -pos/t5508.scala -pos/t5508-min.scala -pos/t8023b.scala -pos/t6231b.scala -pos/debug-reset-local-attrs.scala -pos/t8054.scala -pos/t2066.scala -pos/dotless-targs.scala -pos/t8120.scala -pos/t5508-min-okay.scala -pos/t8060.scala -pos/t8001 -pos/t8138.scala -pos/t8111.scala -pos/t8062 -pos/t8011.scala -pos/t8146b.scala -pos/t8046b.scala -pos/t8023.scala -pos/t5508-min-okay2.scala -pos/macro-implicit-invalidate-on-error.scala -neg/t6563.scala -neg/missing-param-type-tuple.scala -neg/not-a-legal-formal-parameter-tuple.scala -neg/t7897.scala -neg/t8015-ffa.scala -neg/quasiquotes-unliftable-not-found.scala -neg/t2066b.scala -neg/dotless-targs.scala -neg/patmat-classtag-compound.scala -neg/t2066.scala -neg/t8035-deprecated.scala -neg/t6675b.scala -neg/t8104 -neg/t7872.scala -neg/t7850.scala -neg/t7967.scala -neg/macro-bundle-overloaded.scala -neg/t6355a.scala -neg/class-of-double-targs.scala -neg/t6355b.scala -neg/macro-reify-splice-splice -neg/macro-bundle-noncontext.scala -neg/t8015-ffb.scala -neg/t8035-removed.scala -neg/t7984.scala -neg/t8024.scala -neg/t8024b.scala -neg/t8157.scala -neg/t8146-non-finitary-2.scala -neg/t8006.scala -neg/t7872c.scala -neg/t8146-non-finitary.scala -neg/t7872b.scala -neg/t6920.scala -run/t6200.scala -run/t6196.scala -run/macro-bundle-context-refinement -run/macro-enclosingowner-detectvar -run/macro-enclosingowner-sbt -run/macro-bundle-context-alias -run/macro-bundle-whitebox-use-refined -run/macro-bundle-whitebox-use-raw -neg/name-lookup-stable.scala -neg/t0764b.scala -neg/no-implicit-to-anyref-any-val.scala -neg/t1503.scala -neg/t4728.scala -neg/t6455.scala -neg/t6260-named.scala -neg/t6844.scala -neg/t7475c.scala -neg/t7475e.scala -neg/t7475f.scala -neg/macro-bundle-whitebox-use-raw -neg/macro-bundle-whitebox-use-refined -neg/macro-incompatible-macro-engine-b -neg/t7980.scala -neg/macro-incompatible-macro-engine-a -neg/t8143a.scala -neg/t8072.scala -neg/t8207.scala -neg/t8182.scala -neg/t8219-any-any-ref-equals.scala -neg/t8177a.scala -neg/t8228.scala -neg/t8229.scala -neg/t8237-default.scala -neg/t8244b.scala -neg/t8244e -neg/t8244c.scala -neg/t8265.scala -neg/t8266-invalid-interp.scala -neg/t6931 -neg/t8376 -neg/t8372.scala -neg/t8300-overloading.scala -neg/t8244 -neg/t8158 -neg/t8431.scala -pos/implicit-anyval-2.10.scala -pos/delambdafy_t6260_method.scala -pos/macro-bundle-disambiguate-bundle.scala -pos/macro-bundle-disambiguate-nonbundle.scala -pos/package-ob-case -pos/t1786-counter.scala -pos/reflection-compat-api-universe.scala -pos/list-optim-check.scala -pos/existential-java-case-class -pos/t1786-cycle.scala -pos/reflection-compat-c.scala -pos/t3452f.scala -pos/reflection-compat-ru.scala -pos/t2066-2.10-compat.scala -pos/reflection-compat-macro-universe.scala -pos/t5900a.scala -pos/t5760-pkgobj-warn -pos/t5954a -pos/t5954b -pos/t5954d -pos/t6260.scala -pos/t5165b -pos/t5954c -pos/t6260b.scala -pos/t7475b.scala -pos/t7475a.scala -pos/t7753.scala -pos/t7322.scala -pos/t6948.scala -pos/t7475d.scala -pos/t7475e.scala -pos/t6169 -pos/t7788.scala -pos/t7919.scala -pos/t8177a.scala -pos/t8177.scala -pos/t8170.scala -pos/t8170b.scala -pos/t8177d.scala -pos/t8177b.scala -pos/t8177e.scala -pos/t8134 -pos/t8177h.scala -pos/t8177g.scala -pos/t8207.scala -pos/t8187.scala -pos/t8219.scala -pos/t8219b.scala -pos/t8224.scala -pos/t8237.scala -pos/t8223.scala -pos/t8237b.scala -pos/t8300-conversions-a.scala -pos/t8300-conversions-b.scala -pos/t8209a -pos/t8209b -pos/t8244d -pos/t8300-overloading.scala -pos/t8300-patmat-a.scala -pos/t8300-patmat-b.scala -pos/t8315b.scala -pos/t8306.scala -pos/t8301.scala -pos/t8324.scala -pos/t8315.scala -pos/t8301b.scala -pos/t8363.scala -pos/t8367.scala -pos/t8369a.scala -pos/t8369b.scala -pos/t8403.scala -pos/t8364.scala -pos/t8352 -pos/t8376 -neg/macro-bundle-nonpublic-c.scala -neg/literate_existentials.scala -neg/macro-bundle-nonpublic-impl.scala -neg/macro-bundle-ambiguous.scala -neg/macro-bundle-priority-bundle.scala -neg/macro-bundle-need-qualifier.scala -neg/macro-bundle-nonstatic.scala -neg/macro-bundle-polymorphic.scala -neg/macro-bundle-priority-nonbundle.scala -neg/macro-bundle-wrongcontext-a.scala -neg/macro-bundle-wrongcontext-b.scala -run/t8425 -run/t8245.scala -run/t8266-octal-interp.scala -run/t8280.scala -run/t8395.scala -run/t8321 -run/t8153.scala -run/t8233-bcode.scala -run/t8197.scala -run/t8197b.scala -run/t8233.scala -run/t8133 -run/t8133b -run/t7475b.scala -run/t7445.scala -run/t6814 -run/t4577.scala -run/t5134.scala -run/t3452f.scala -run/t3452h.scala -run/t3452c.scala -run/t3452.scala -run/t261.scala -run/t3235-minimal.scala -run/t1503_future.scala -run/t5565.scala -pos/t8411 -pos/t8460.scala -run/t8428.scala -run/t8437 -run/absoverride.scala -run/arrays.scala -run/duration-coarsest.scala -run/iterator-from.scala -run/SymbolsTest.scala -run/t1074.scala -run/t1505.scala -run/streams.scala -run/t2111.scala -run/t4601.scala -pos/SI-4012-a.scala -pos/SI-7638.scala -neg/t3692-new.scala -run/t7015.scala -run/t7992b.scala -run/t7992.scala -run/t8570.scala -pos/t8157-2.10.scala -pos/t8325.scala -pos/t8523.scala -pos/t8578.scala -pos/t8329.scala -pos/t8497 -pos/t8546.scala -pos/t8531 -neg/t8325-c.scala -neg/t8325-b.scala -neg/t8325.scala -neg/t6988.scala -neg/t8463.scala -neg/t8450.scala -neg/t8430.scala -run/finally.scala -neg/t8630.scala -neg/t8035-no-adapted-args.scala -neg/t8675b.scala -neg/t8610-arg.scala -neg/t8736-c.scala -neg/tailrec-4.scala -neg/double-def-top-level -neg/t8610.scala -neg/aladdin1055 -neg/virtpatmat_exhaust_compound.scala -neg/t8675.scala -neg/t8525.scala -pos/t8736.scala -pos/t8625.scala -pos/t8596.scala -pos/t8617.scala -pos/t8736-b.scala -pos/t8708 -pos/macro-attachments -run/t8611a.scala -run/t8738.scala -run/macro-rangepos-args -run/t8610.scala -run/macro-rangepos-subpatterns -run/t8611c.scala -run/macroPlugins-isBlackbox -run/t8601d.scala -run/t8607.scala -run/bugs.scala -run/t1503.scala -run/t4148.scala -run/t7763.scala -run/issue192.scala -run/t8893b.scala -run/t8845.scala -run/t8933 -run/t7459c.scala -run/t9003.scala -run/t7459f.scala -run/t8933c.scala -run/t1994.scala -run/t2866.scala -run/t5665.scala -run/t7459d.scala -run/t8933b -run/t8888.scala -run/t7459b-optimize.scala -run/t7459a.scala -run/t7019.scala -run/t8893.scala -run/t8803.scala -run/t7459b.scala -run/nothingTypeNoFramesNoDce.scala -run/t8823.scala -run/sammy_repeated.scala -run/t6541.scala -run/nothingTypeDce.scala -run/t8680.scala -run/t8925.scala -run/nothingTypeNoOpt.scala -run/t9030.scala -run/bigDecimalTest.scala -run/bigDecimalCache.scala -run/range.scala -run/t6064.scala - -# Adapt checkfiles for (1.0).toString == "1" -run/Course-2002-01.scala -run/t0421-new.scala -run/runtime.scala -run/t0421-old.scala -run/spec-self.scala -run/t5552.scala -run/Course-2002-02.scala -run/Course-2002-04.scala -run/promotion.scala -run/t4617.scala -run/Course-2002-09.scala -run/t5866.scala -run/try-catch-unify.scala -run/impconvtimes.scala -run/Course-2002-10.scala -run/Course-2002-08.scala - -# Adapt checkfiles for ().toString == "undefined" -run/t5680.scala -run/dynamic-anyval.scala -run/macro-bundle-toplevel -run/macro-bundle-whitebox-decl -run/t6662 -run/t8570a.scala -run/t3702.scala -run/t7657 -run/macro-bundle-static -run/structural.scala - -# Adapt checkfiles for print & flush (which we cannot 100% emulate) -run/imports.scala -run/misc.scala - -# Adapt checkfiles for compiler phase list -run/t6102.scala -neg/t7494-no-options - -# Adapt checkfiles for different behavior with boxed types -run/t5568.scala -run/virtpatmat_typetag.scala -run/virtpatmat_switch.scala -run/t5629b.scala -run/t6318_primitives.scala -run/t8764.scala From 37665fef840fd398a6c6ee030bf37134c87c9a63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 17 Mar 2018 10:48:36 +0100 Subject: [PATCH 0642/2665] Blacklist pos/t6367.scala, because it spuriously fails too often. This test stress-tests the type checker by design. On our CI, this fails too often with weird errors (out of memory?). Moreover, it is so bad that it seems to cause other tests running concurrently to also mysteriously fail every once in a while. Blacklisting that test should significantly reduce spurious failures of partest runs. --- .../scala/tools/partest/scalajs/2.11.0/BlacklistedTests.txt | 4 ++++ .../scala/tools/partest/scalajs/2.11.0/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.11.1/BlacklistedTests.txt | 4 ++++ .../scala/tools/partest/scalajs/2.11.1/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.11.11/BlacklistedTests.txt | 4 ++++ .../scala/tools/partest/scalajs/2.11.11/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.11.12/BlacklistedTests.txt | 4 ++++ .../scala/tools/partest/scalajs/2.11.12/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.11.2/BlacklistedTests.txt | 4 ++++ .../scala/tools/partest/scalajs/2.11.2/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.11.5/BlacklistedTests.txt | 4 ++++ .../scala/tools/partest/scalajs/2.11.5/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.11.6/BlacklistedTests.txt | 4 ++++ .../scala/tools/partest/scalajs/2.11.6/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt | 4 ++++ .../scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt | 4 ++++ .../scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt | 4 ++++ .../scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt | 4 ++++ .../scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.12.2/BlacklistedTests.txt | 4 ++++ .../scala/tools/partest/scalajs/2.12.2/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.12.3/BlacklistedTests.txt | 4 ++++ .../scala/tools/partest/scalajs/2.12.3/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.12.4/BlacklistedTests.txt | 4 ++++ .../scala/tools/partest/scalajs/2.12.4/WhitelistedTests.txt | 1 - .../tools/partest/scalajs/2.13.0-M2/BlacklistedTests.txt | 4 ++++ .../tools/partest/scalajs/2.13.0-M2/WhitelistedTests.txt | 1 - 30 files changed, 60 insertions(+), 15 deletions(-) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/BlacklistedTests.txt index 2b541138b4..75df9130dd 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/BlacklistedTests.txt @@ -10,6 +10,10 @@ pos/t533.scala pos/functions.scala pos/MailBox.scala +# Spuriously fails too often, and causes other subsequent tests to fail too +# Note that this test, by design, stress-tests type checking +pos/t6367.scala + # # NEG # diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/WhitelistedTests.txt index 94dcbc26c3..d802ede452 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.0/WhitelistedTests.txt @@ -202,7 +202,6 @@ pos/t6745.scala pos/t2809.scala pos/t7022.scala pos/t6447.scala -pos/t6367.scala pos/t5846.scala pos/lubs.scala pos/t1987a.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/BlacklistedTests.txt index 53b6eeb242..6bc44c120e 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/BlacklistedTests.txt @@ -10,6 +10,10 @@ pos/t533.scala pos/functions.scala pos/MailBox.scala +# Spuriously fails too often, and causes other subsequent tests to fail too +# Note that this test, by design, stress-tests type checking +pos/t6367.scala + # # NEG # diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/WhitelistedTests.txt index e058d1c199..4a5e3df91d 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.1/WhitelistedTests.txt @@ -202,7 +202,6 @@ pos/t6745.scala pos/t2809.scala pos/t7022.scala pos/t6447.scala -pos/t6367.scala pos/t5846.scala pos/lubs.scala pos/t1987a.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/BlacklistedTests.txt index 2c73dd357c..e266529020 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/BlacklistedTests.txt @@ -10,6 +10,10 @@ pos/t533.scala pos/functions.scala pos/MailBox.scala +# Spuriously fails too often, and causes other subsequent tests to fail too +# Note that this test, by design, stress-tests type checking +pos/t6367.scala + # Kills our IR serializer, it's an artificially super-deep if/else if pos/t9181.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/WhitelistedTests.txt index 6623e6ee00..d423eabc3b 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/WhitelistedTests.txt @@ -202,7 +202,6 @@ pos/t6745.scala pos/t2809.scala pos/t7022.scala pos/t6447.scala -pos/t6367.scala pos/t5846.scala pos/lubs.scala pos/t1987a.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/BlacklistedTests.txt index 4abda64d47..5e0cbe6935 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/BlacklistedTests.txt @@ -10,6 +10,10 @@ pos/t533.scala pos/functions.scala pos/MailBox.scala +# Spuriously fails too often, and causes other subsequent tests to fail too +# Note that this test, by design, stress-tests type checking +pos/t6367.scala + # Kills our IR serializer, it's an artificially super-deep if/else if pos/t9181.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/WhitelistedTests.txt index 6623e6ee00..d423eabc3b 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/WhitelistedTests.txt @@ -202,7 +202,6 @@ pos/t6745.scala pos/t2809.scala pos/t7022.scala pos/t6447.scala -pos/t6367.scala pos/t5846.scala pos/lubs.scala pos/t1987a.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/BlacklistedTests.txt index fe690e179b..486dfdf557 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/BlacklistedTests.txt @@ -10,6 +10,10 @@ pos/t533.scala pos/functions.scala pos/MailBox.scala +# Spuriously fails too often, and causes other subsequent tests to fail too +# Note that this test, by design, stress-tests type checking +pos/t6367.scala + # # NEG # diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/WhitelistedTests.txt index 2608983356..9dd3160118 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.2/WhitelistedTests.txt @@ -202,7 +202,6 @@ pos/t6745.scala pos/t2809.scala pos/t7022.scala pos/t6447.scala -pos/t6367.scala pos/t5846.scala pos/lubs.scala pos/t1987a.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/BlacklistedTests.txt index ce8ee48a61..74c50b770d 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/BlacklistedTests.txt @@ -10,6 +10,10 @@ pos/t533.scala pos/functions.scala pos/MailBox.scala +# Spuriously fails too often, and causes other subsequent tests to fail too +# Note that this test, by design, stress-tests type checking +pos/t6367.scala + # # NEG # diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/WhitelistedTests.txt index 87ccfd8006..1505ef85aa 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.5/WhitelistedTests.txt @@ -202,7 +202,6 @@ pos/t6745.scala pos/t2809.scala pos/t7022.scala pos/t6447.scala -pos/t6367.scala pos/t5846.scala pos/lubs.scala pos/t1987a.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/BlacklistedTests.txt index 9a1d2ff293..5c515f5f16 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/BlacklistedTests.txt @@ -10,6 +10,10 @@ pos/t533.scala pos/functions.scala pos/MailBox.scala +# Spuriously fails too often, and causes other subsequent tests to fail too +# Note that this test, by design, stress-tests type checking +pos/t6367.scala + # # NEG # diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/WhitelistedTests.txt index 30061a4560..c477a6990d 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.6/WhitelistedTests.txt @@ -202,7 +202,6 @@ pos/t6745.scala pos/t2809.scala pos/t7022.scala pos/t6447.scala -pos/t6367.scala pos/t5846.scala pos/lubs.scala pos/t1987a.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt index c11845627c..6c023264e6 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt @@ -10,6 +10,10 @@ pos/t533.scala pos/functions.scala pos/MailBox.scala +# Spuriously fails too often, and causes other subsequent tests to fail too +# Note that this test, by design, stress-tests type checking +pos/t6367.scala + # Kills our IR serializer, it's an artificially super-deep if/else if pos/t9181.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt index 2a4c9b4069..83b53ca360 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt @@ -202,7 +202,6 @@ pos/t6745.scala pos/t2809.scala pos/t7022.scala pos/t6447.scala -pos/t6367.scala pos/t5846.scala pos/lubs.scala pos/t1987a.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt index 3b27c63398..b501e896a4 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt @@ -10,6 +10,10 @@ pos/t533.scala pos/functions.scala pos/MailBox.scala +# Spuriously fails too often, and causes other subsequent tests to fail too +# Note that this test, by design, stress-tests type checking +pos/t6367.scala + # Kills our IR serializer, it's an artificially super-deep if/else if pos/t9181.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt index 0352fc503c..b299356869 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt @@ -202,7 +202,6 @@ pos/t6745.scala pos/t2809.scala pos/t7022.scala pos/t6447.scala -pos/t6367.scala pos/t5846.scala pos/lubs.scala pos/t1987a.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt index 7c4d820a68..c76169b0af 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt @@ -5,6 +5,10 @@ # Using Jsoup, what's that? pos/cycle-jsoup.scala +# Spuriously fails too often, and causes other subsequent tests to fail too +# Note that this test, by design, stress-tests type checking +pos/t6367.scala + # Kills our IR serializer, it's an artificially super-deep if/else if pos/t9181.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt index 0b00e3852d..eb90bc94bd 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt @@ -201,7 +201,6 @@ pos/t6745.scala pos/t2809.scala pos/t7022.scala pos/t6447.scala -pos/t6367.scala pos/t5846.scala pos/lubs.scala pos/t1987a.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt index 31621c01a7..d74ed2e038 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt @@ -5,6 +5,10 @@ # Using Jsoup, what's that? pos/cycle-jsoup.scala +# Spuriously fails too often, and causes other subsequent tests to fail too +# Note that this test, by design, stress-tests type checking +pos/t6367.scala + # Kills our IR serializer, it's an artificially super-deep if/else if pos/t9181.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt index 28cddc79fe..5fd2ca4d19 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt @@ -201,7 +201,6 @@ pos/t6745.scala pos/t2809.scala pos/t7022.scala pos/t6447.scala -pos/t6367.scala pos/t5846.scala pos/lubs.scala pos/t1987a.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/BlacklistedTests.txt index e39a983628..c51f107799 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/BlacklistedTests.txt @@ -5,6 +5,10 @@ # Using Jsoup, what's that? pos/cycle-jsoup.scala +# Spuriously fails too often, and causes other subsequent tests to fail too +# Note that this test, by design, stress-tests type checking +pos/t6367.scala + # Kills our IR serializer, it's an artificially super-deep if/else if pos/t9181.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/WhitelistedTests.txt index d388af436d..66fe31b24c 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/WhitelistedTests.txt @@ -201,7 +201,6 @@ pos/t6745.scala pos/t2809.scala pos/t7022.scala pos/t6447.scala -pos/t6367.scala pos/t5846.scala pos/lubs.scala pos/t1987a.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/BlacklistedTests.txt index b87c684414..b1742b3e61 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/BlacklistedTests.txt @@ -5,6 +5,10 @@ # Using Jsoup, what's that? pos/cycle-jsoup.scala +# Spuriously fails too often, and causes other subsequent tests to fail too +# Note that this test, by design, stress-tests type checking +pos/t6367.scala + # Kills our IR serializer, it's an artificially super-deep if/else if pos/t9181.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/WhitelistedTests.txt index 96dd9d2926..cf60cfbd13 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/WhitelistedTests.txt @@ -200,7 +200,6 @@ pos/t6745.scala pos/t2809.scala pos/t7022.scala pos/t6447.scala -pos/t6367.scala pos/t5846.scala pos/lubs.scala pos/t1987a.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/BlacklistedTests.txt index eba6a18f65..b4719299ac 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/BlacklistedTests.txt @@ -5,6 +5,10 @@ # Using Jsoup, what's that? pos/cycle-jsoup.scala +# Spuriously fails too often, and causes other subsequent tests to fail too +# Note that this test, by design, stress-tests type checking +pos/t6367.scala + # Kills our IR serializer, it's an artificially super-deep if/else if pos/t9181.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/WhitelistedTests.txt index 5d92152350..c3618e96f3 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/WhitelistedTests.txt @@ -200,7 +200,6 @@ pos/t6745.scala pos/t2809.scala pos/t7022.scala pos/t6447.scala -pos/t6367.scala pos/t5846.scala pos/lubs.scala pos/t1987a.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/BlacklistedTests.txt index bfcaacc440..1d884878ed 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/BlacklistedTests.txt @@ -5,6 +5,10 @@ # Using Jsoup, what's that? pos/cycle-jsoup.scala +# Spuriously fails too often, and causes other subsequent tests to fail too +# Note that this test, by design, stress-tests type checking +pos/t6367.scala + # Kills our IR serializer, it's an artificially super-deep if/else if pos/t9181.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/WhitelistedTests.txt index 68440d3843..4d385bfd0c 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/WhitelistedTests.txt @@ -200,7 +200,6 @@ pos/t6745.scala pos/t2809.scala pos/t7022.scala pos/t6447.scala -pos/t6367.scala pos/t5846.scala pos/lubs.scala pos/t1987a.scala From 3c9540c02419d2be240dc356b0a98c2b0e7c5d89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 17 Mar 2018 10:53:01 +0100 Subject: [PATCH 0643/2665] Delete `partest/fetchedSources/` before starting a CI job. `git clean -fdx` is not enough to remove this particular directory, because it contains nested git repositories (automatically fetched by the sbt task `partest/fetchSources`). --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index a03d0f5538..8b1a818a21 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -497,7 +497,7 @@ matrix.each { taskDef -> buildDefs.put(fullTaskName, { node('linuxworker') { checkout scm - sh "git clean -fdx" + sh "git clean -fdx && rm -rf partest/fetchedSources/" writeFile file: 'ciscript.sh', text: ciScript, encoding: 'UTF-8' retry(2) { sh "echo '$fullTaskName' && cat ciscript.sh && sh ciscript.sh" From 54a15a35d0b2ae940464dbe5e1e5751570d16e24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 17 Mar 2018 14:30:20 +0100 Subject: [PATCH 0644/2665] Add a 3-hour timeout to every job. In the old CI, this was enforced through configuration in the Jenkins UI. --- Jenkinsfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 8b1a818a21..869be2e152 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -500,7 +500,9 @@ matrix.each { taskDef -> sh "git clean -fdx && rm -rf partest/fetchedSources/" writeFile file: 'ciscript.sh', text: ciScript, encoding: 'UTF-8' retry(2) { - sh "echo '$fullTaskName' && cat ciscript.sh && sh ciscript.sh" + timeout(time: 3, unit: 'HOURS') { + sh "echo '$fullTaskName' && cat ciscript.sh && sh ciscript.sh" + } } } }) From d1c5b4a9b1c4bc824910c38f76001ec6d4879b29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 18 Mar 2018 15:47:36 +0100 Subject: [PATCH 0645/2665] Introduce the new API of ESFeatures instead of OutputMode. This is done in a backward source and binary compatible way, so `OutputMode` remains as the "source of truth" while `ESFeatures` builds on top of it to provide the new API. Whereas `OutputMode` was a sealed abstract class with case objects, `ESFeatures` is an option bag of individual ECMAScript features. Unlike the `OutputMode` API, it will be possible to evolve the new API in backward compatible ways, which allows to lift it to the stable API in `linker`, instead of `linker.standard`. --- Jenkinsfile | 18 +++---- .../scala/org/scalajs/cli/Scalajsld.scala | 11 ++-- project/BinaryIncompatibilities.scala | 5 ++ project/Build.scala | 1 - .../sbtplugin/ScalaJSPluginInternal.scala | 4 +- .../linker/LinkerPlatformExtensions.scala | 2 +- .../linker/LinkerPlatformExtensions.scala | 2 +- .../core/tools/linker/StandardLinker.scala | 39 +++++++-------- .../tools/linker/backend/OutputMode.scala | 50 +++++++++++++++++-- .../scalajs/core/tools/linker/package.scala | 5 ++ .../core/tools/linker/standard/package.scala | 6 ++- 11 files changed, 98 insertions(+), 45 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 869be2e152..7cbbde79d6 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -237,46 +237,46 @@ def Tasks = [ "test-suite-ecma-script6": ''' setJavaVersion $java - sbtretry 'set scalaJSOutputMode in $testSuite := org.scalajs.core.tools.linker.backend.OutputMode.ECMAScript6' \ + sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true)))' \ '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' \ + sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true)))' \ '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' \ + sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true)))' \ '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 && - sbtretry 'set scalaJSOutputMode in $testSuite := org.scalajs.core.tools.linker.backend.OutputMode.ECMAScript6' \ + sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true)))' \ 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withSourceMap(false))' \ 'set scalaJSSemantics in $testSuite ~= makeCompliant' \ ++$scala $testSuite/test \ $testSuite/clean && - sbtretry 'set scalaJSOutputMode in $testSuite := org.scalajs.core.tools.linker.backend.OutputMode.ECMAScript6' \ + sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true)))' \ 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withSourceMap(false))' \ 'set scalaJSSemantics in $testSuite ~= makeCompliant' \ 'set scalaJSOptimizerOptions in $testSuite ~= (_.withDisableOptimizer(true))' \ ++$scala $testSuite/test \ $testSuite/clean && - sbtretry 'set scalaJSOutputMode in $testSuite := org.scalajs.core.tools.linker.backend.OutputMode.ECMAScript6' \ + sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true)))' \ 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withSourceMap(false))' \ 'set scalaJSStage in Global := FullOptStage' \ ++$scala $testSuite/test \ $testSuite/clean && - sbtretry 'set scalaJSOutputMode in $testSuite := org.scalajs.core.tools.linker.backend.OutputMode.ECMAScript6' \ + sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true)))' \ 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withSourceMap(false))' \ 'set scalaJSStage in Global := FullOptStage' \ 'set scalaJSOptimizerOptions in $testSuite ~= (_.withDisableOptimizer(true))' \ ++$scala $testSuite/test \ $testSuite/clean && - sbtretry 'set scalaJSOutputMode in $testSuite := org.scalajs.core.tools.linker.backend.OutputMode.ECMAScript6' \ + sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true)))' \ 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withSourceMap(false))' \ 'set scalaJSModuleKind in $testSuite := ModuleKind.CommonJSModule' \ ++$scala $testSuite/test && - sbtretry 'set scalaJSOutputMode in $testSuite := org.scalajs.core.tools.linker.backend.OutputMode.ECMAScript6' \ + sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true)))' \ 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withSourceMap(false))' \ 'set scalaJSModuleKind in $testSuite := ModuleKind.CommonJSModule' \ 'set scalaJSStage in Global := FullOptStage' \ diff --git a/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala b/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala index f63f8716e8..85aedc1e90 100644 --- a/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala +++ b/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala @@ -26,6 +26,11 @@ import java.net.URI object Scalajsld { + private val AllOutputModes = List( + OutputMode.ECMAScript51Isolated, + OutputMode.ECMAScript6, + OutputMode.ECMAScript51Global) + private case class Options( cp: Seq[File] = Seq.empty, moduleInitializers: Seq[ModuleInitializer] = Seq.empty, @@ -58,7 +63,7 @@ object Scalajsld { private implicit object OutputModeRead extends scopt.Read[OutputMode] { val arity = 1 val reads = { (s: String) => - OutputMode.All.find(_.toString() == s).getOrElse( + AllOutputModes.find(_.toString() == s).getOrElse( throw new IllegalArgumentException(s"$s is not a valid output mode")) } } @@ -117,7 +122,7 @@ object Scalajsld { .text("Use compliant asInstanceOfs") opt[OutputMode]('m', "outputMode") .action { (mode, c) => c.copy(outputMode = mode) } - .text("Output mode " + OutputMode.All.mkString("(", ", ", ")")) + .text("Output mode " + AllOutputModes.mkString("(", ", ", ")")) opt[ModuleKind]('k', "moduleKind") .action { (kind, c) => c.copy(moduleKind = kind) } .text("Module kind " + ModuleKind.All.mkString("(", ", ", ")")) @@ -189,7 +194,7 @@ object Scalajsld { val config = StandardLinker.Config() .withSemantics(semantics) .withModuleKind(options.moduleKind) - .withOutputMode(options.outputMode) + .withESFeatures(options.outputMode) .withBypassLinkingErrorsInternal(options.bypassLinkingErrors) .withCheckIR(options.checkIR) .withOptimizer(!options.noOpt) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 553c491612..39d88dcc87 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -8,6 +8,11 @@ object BinaryIncompatibilities { ) val Tools = Seq( + // private[linker], not an issue + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.StandardLinker#Config.outputMode"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.StandardLinker#Config.withOutputMode") ) val JSEnvs = Seq( diff --git a/project/Build.scala b/project/Build.scala index c7c9f93ea0..f72c11c848 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -32,7 +32,6 @@ import org.scalajs.core.tools.sem._ import org.scalajs.core.tools.jsdep.ResolvedJSDependency import org.scalajs.core.tools.json._ import org.scalajs.core.tools.linker.ModuleInitializer -import org.scalajs.core.tools.linker.backend.OutputMode import sbtassembly.AssemblyPlugin.autoImport._ diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 94611062a1..e2de6bc456 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -223,7 +223,7 @@ object ScalaJSPluginInternal { StandardLinker.Config() .withSemantics(semantics) .withModuleKind(moduleKind) - .withOutputMode(outputMode) + .withESFeatures(outputMode) .withBypassLinkingErrorsInternal(opts.bypassLinkingErrors) .withCheckIR(opts.checkScalaJSIR) .withOptimizer(!opts.disableOptimizer) @@ -1183,7 +1183,7 @@ object ScalaJSPluginInternal { jsManifestFilter := identity, scalaJSSemantics := scalaJSLinkerConfig.value.semantics, - scalaJSOutputMode := scalaJSLinkerConfig.value.outputMode, + scalaJSOutputMode := scalaJSLinkerConfig.value.esFeatures, scalaJSModuleKind := scalaJSLinkerConfig.value.moduleKind, checkScalaJSSemantics := true, diff --git a/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala b/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala index 8a32965242..2201e8e35e 100644 --- a/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala +++ b/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala @@ -41,7 +41,7 @@ trait LinkerPlatformExtensions { this: Linker.type => @deprecated("Use StandardLinker.apply() instead.", "0.6.13") def apply( semantics: Semantics = Semantics.Defaults, - outputMode: OutputMode = OutputMode.Default, + outputMode: OutputMode = OutputMode.Defaults, withSourceMap: Boolean = true, disableOptimizer: Boolean = false, frontendConfig: LinkerFrontend.Config = LinkerFrontend.Config(), diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala index b15f7ad351..cdc6f1c660 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala @@ -52,7 +52,7 @@ trait LinkerPlatformExtensions { this: Linker.type => @deprecated("Use StandardLinker.apply() instead.", "0.6.13") def apply( semantics: Semantics = Semantics.Defaults, - outputMode: OutputMode = OutputMode.Default, + outputMode: OutputMode = OutputMode.Defaults, withSourceMap: Boolean = true, disableOptimizer: Boolean = false, parallel: Boolean = true, 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 8c9f68e24e..02ce26dff7 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 @@ -36,7 +36,7 @@ object StandardLinker { .withFrontendConfig(frontendConfig) .withBackendConfig(backendConfig) - Linker.applyInternal(config.semantics, config.outputMode, config.moduleKind, + Linker.applyInternal(config.semantics, config.esFeatures, config.moduleKind, oldAPIConfig) } @@ -49,6 +49,8 @@ object StandardLinker { val semantics: Semantics, /** Module kind. */ val moduleKind: ModuleKind, + /** ECMAScript features to use. */ + val esFeatures: ESFeatures, /** Whether to only warn if the linker has errors. */ val bypassLinkingErrors: Boolean, /** If true, performs expensive checks of the IR for the used parts. */ @@ -82,14 +84,13 @@ object StandardLinker { * linker mainly designed for incremental runs may ignore * `batchMode = true`. */ - val batchMode: Boolean, - /** Standard output mode. */ - private[linker] val outputMode: OutputMode + val batchMode: Boolean ) { private def this() = { this( semantics = Semantics.Defaults, moduleKind = ModuleKind.NoModule, + esFeatures = ESFeatures.Defaults, bypassLinkingErrors = false, checkIR = false, optimizer = true, @@ -99,8 +100,7 @@ object StandardLinker { customOutputWrapper = ("", ""), closureCompilerIfAvailable = false, prettyPrint = false, - batchMode = false, - outputMode = OutputMode.Default + batchMode = false ) } @@ -113,6 +113,12 @@ object StandardLinker { def withModuleKind(moduleKind: ModuleKind): Config = copy(moduleKind = moduleKind) + def withESFeatures(esFeatures: ESFeatures): Config = + copy(esFeatures = esFeatures) + + def withESFeatures(f: ESFeatures => ESFeatures): Config = + copy(esFeatures = f(esFeatures)) + @deprecated( "Bypassing linking errors will not be possible in the next major version.", "0.6.6") @@ -163,13 +169,11 @@ object StandardLinker { def withBatchMode(batchMode: Boolean): Config = copy(batchMode = batchMode) - private[linker] def withOutputMode(outputMode: OutputMode): Config = - copy(outputMode = outputMode) - override def toString(): String = { s"""StandardLinker.Config( | semantics = $semantics, | moduleKind = $moduleKind, + | esFeatures = $esFeatures, | bypassLinkingErrors = $bypassLinkingErrors, | checkIR = $checkIR, | optimizer = $optimizer, @@ -180,13 +184,13 @@ object StandardLinker { | closureCompilerIfAvailable = $closureCompilerIfAvailable, | prettyPrint = $prettyPrint, | batchMode = $batchMode, - | outputMode = $outputMode, |)""".stripMargin } private def copy( semantics: Semantics = semantics, moduleKind: ModuleKind = moduleKind, + esFeatures: ESFeatures = esFeatures, bypassLinkingErrors: Boolean = bypassLinkingErrors, checkIR: Boolean = checkIR, optimizer: Boolean = optimizer, @@ -196,12 +200,12 @@ object StandardLinker { customOutputWrapper: (String, String) = customOutputWrapper, closureCompilerIfAvailable: Boolean = closureCompilerIfAvailable, prettyPrint: Boolean = prettyPrint, - batchMode: Boolean = batchMode, - outputMode: OutputMode = outputMode + batchMode: Boolean = batchMode ): Config = { new Config( semantics, moduleKind, + esFeatures, bypassLinkingErrors, checkIR, optimizer, @@ -211,8 +215,7 @@ object StandardLinker { customOutputWrapper, closureCompilerIfAvailable, prettyPrint, - batchMode, - outputMode + batchMode ) } } @@ -224,6 +227,7 @@ object StandardLinker { * * - `semantics`: [[org.scalajs.core.tools.sem.Semantics.Defaults Semantics.Defaults]] * - `moduleKind`: [[ModuleKind.NoModule]] + * - `esFeatures`: [[org.scalajs.core.tools.linker.backend.OutputMode.Defaults ESFeatures.Defaults]] * - `bypassLinkingErrors`: `false` (deprecated) * - `checkIR`: `false` * - `optimizer`: `true` @@ -234,13 +238,6 @@ object StandardLinker { * - `closureCompilerIfAvailable`: `false` * - `prettyPrint`: `false` * - `batchMode`: `false` - * - * The following additional options are configurable through - * {{{ - * import org.scalajs.core.tools.linker.standard._ - * }}} - * - * - `outputMode`: [[org.scalajs.core.tools.linker.backend.OutputMode.Default OutputMode.Default]] */ def apply(): Config = new Config() } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala index dd9479c062..53fa36e7b9 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala @@ -11,23 +11,57 @@ package org.scalajs.core.tools.linker.backend import org.scalajs.core.tools.javascript.ESLevel -/** JavaScript output mode. */ +/** JavaScript output mode. + * + * For forward source compatibility with Scala.js 1.x, use the alias + * [[org.scalajs.core.tools.linker.ESFeatures]] instead. + */ sealed abstract class OutputMode { + import OutputMode._ + def esLevel: ESLevel + + /** Whether to use ECMAScript 2015 features, such as classes and arrow + * functions. + */ + def useECMAScript2015: Boolean = this match { + case ECMAScript51Global => false + case ECMAScript51Isolated => false + case ECMAScript6 => true + } + + def withUseECMAScript2015(useECMAScript2015: Boolean): OutputMode = + if (useECMAScript2015) ECMAScript6 + else ECMAScript51Isolated } +/** Factory for `OutputMode`s. + * + * For forward source compatibility with Scala.js 1.x, use the alias + * [[org.scalajs.core.tools.linker.ESFeatures]] instead. + */ object OutputMode { /** All the available output modes. * There are listed in decreasing order of "importance", as judged by * whoever maintains the back-ends. */ + @deprecated( + "The notion that there is a list of existing output modes is going away.", + "0.6.23") val All = List( ECMAScript51Isolated, ECMAScript6, ECMAScript51Global) - /** The default output mode. This is always the first element of [[All]] */ - val Default = All.head + /** Default configuration of the output mode. + * + * - `useECMAScript2015`: false + */ + val Defaults: OutputMode = ECMAScript51Isolated + + /** Default configuration of the output mode. */ + @deprecated("Use Defaults instead.", "0.6.23") + val Default = Defaults /** Legacy output mode where everything is stored in a global ScalaJS variable. * This is suited to the special Rhino interpreter. @@ -39,7 +73,9 @@ object OutputMode { /** Output mode compliant with ECMAScript 5.1 (deprecated alias). * * This value is not annotated with `@deprecated` for technical reasons, but - * it should be considered as such. Use [[ECMAScript51]] instead. + * it should be considered as such. + * + * Use `Defaults` instead. */ case object ECMAScript51Isolated extends OutputMode { val esLevel: ESLevel = ESLevel.ES5 @@ -50,12 +86,15 @@ object OutputMode { * This is the default output mode. It assumes that the target platform * supports ECMAScript 5.1, ideally with correct handling of strict mode. */ + @deprecated("Use Defaults instead.", "0.6.23") val ECMAScript51: ECMAScript51Isolated.type = ECMAScript51Isolated /** Output mode compliant with ECMAScript 2015 (deprecated alias). * * This value is not annotated with `@deprecated` for technical reasons, but - * it should be considered as such. Use [[ECMAScript2015]] instead. + * it should be considered as such. + * + * Use `Defaults.withUseECMAScript2015(true)` instead. */ case object ECMAScript6 extends OutputMode { val esLevel: ESLevel = ESLevel.ES6 @@ -66,6 +105,7 @@ object OutputMode { * This output mode assumes that the target platform supports ECMAScript * 2015 (aka ES 6). */ + @deprecated("Use `Defaults.withUseECMAScript2015(true)` instead.", "0.6.23") val ECMAScript2015: ECMAScript6.type = ECMAScript6 // Not binary compatible, but source compatible with deprecation diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/package.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/package.scala index d23ef0c007..e1e6e78e55 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/package.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/package.scala @@ -23,4 +23,9 @@ package object linker { val ModuleKind: org.scalajs.core.tools.linker.backend.ModuleKind.type = org.scalajs.core.tools.linker.backend.ModuleKind + + type ESFeatures = org.scalajs.core.tools.linker.backend.OutputMode + + val ESFeatures: org.scalajs.core.tools.linker.backend.OutputMode.type = + org.scalajs.core.tools.linker.backend.OutputMode } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/package.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/package.scala index a880b1c5b8..530409962e 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/package.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/package.scala @@ -20,9 +20,11 @@ package object standard { import StandardLinker.Config /** Standard output mode. */ - def outputMode: OutputMode = __self.outputMode + @deprecated("Use esFeatures instead.", "0.6.23") + def outputMode: OutputMode = __self.esFeatures + @deprecated("Use withESFeatures instead.", "0.6.23") def withOutputMode(outputMode: OutputMode): Config = - __self.withOutputMode(outputMode) + __self.withESFeatures(outputMode) } } From beccf6f3fd49b0c91f88f295be9b207c08df991e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 17 Mar 2018 16:01:21 +0100 Subject: [PATCH 0646/2665] Finish the refactoring of `OutputMode` into `ESFeatures`. Instead of having a sealed abstract class with case objects, that wasn't actually sealed, and was prone to breakages, we have a principled options bag for individual features of ECMAScript that the linker is mandated and/or allowed to use. --- .../closure/ClosureLinkerBackend.scala | 6 +- linker/scalajsenv.js | 36 ++--- .../scala/org/scalajs/linker/ESFeatures.scala | 80 +++++++++++ .../scala/org/scalajs/linker/Linker.scala | 1 - .../org/scalajs/linker/StandardLinker.scala | 2 +- .../linker/backend/emitter/ClassEmitter.scala | 130 ++++++++---------- .../linker/backend/emitter/CoreJSLibs.scala | 31 ++--- .../linker/backend/emitter/Emitter.scala | 9 +- .../backend/emitter/FunctionEmitter.scala | 89 ++++++------ .../backend/emitter/GlobalRefUtils.scala | 2 - .../linker/backend/emitter/JSGen.scala | 34 ++--- .../frontend/optimizer/OptimizerCore.scala | 5 +- .../scala/org/scalajs/linker/package.scala | 16 --- .../scalajs/linker/standard/CoreSpec.scala | 16 +-- .../scalajs/linker/standard/OutputMode.scala | 93 ------------- .../org/scalajs/linker/standard/package.scala | 27 ---- project/Build.scala | 7 - .../sbtplugin/ScalaJSPluginInternal.scala | 3 +- 18 files changed, 238 insertions(+), 349 deletions(-) create mode 100644 linker/shared/src/main/scala/org/scalajs/linker/ESFeatures.scala delete mode 100644 linker/shared/src/main/scala/org/scalajs/linker/package.scala delete mode 100644 linker/shared/src/main/scala/org/scalajs/linker/standard/OutputMode.scala delete mode 100644 linker/shared/src/main/scala/org/scalajs/linker/standard/package.scala diff --git a/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala index 71585dcf82..2763f7b671 100644 --- a/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala @@ -22,7 +22,6 @@ import org.scalajs.io._ import org.scalajs.logging.Logger import org.scalajs.linker._ -import org.scalajs.linker.standard._ import org.scalajs.linker.analyzer.SymbolRequirement import org.scalajs.linker.backend._ import org.scalajs.linker.backend.emitter.Emitter @@ -37,8 +36,9 @@ final class ClosureLinkerBackend(config: LinkerBackend.Config) import config.commonConfig.coreSpec._ - require(outputMode == OutputMode.ECMAScript51Isolated, - s"Cannot use output mode $outputMode with the Closure Compiler") + require(!esFeatures.useECMAScript2015, + s"Cannot use features $esFeatures with the Closure Compiler" + + "because they contain ECMAScript 2015 features") private[this] val emitter = { new Emitter(config.commonConfig) diff --git a/linker/scalajsenv.js b/linker/scalajsenv.js index ad3c7c2bc0..0b8c6ec571 100644 --- a/linker/scalajsenv.js +++ b/linker/scalajsenv.js @@ -58,7 +58,7 @@ const $linkingInfo = { "productionMode": false //!endif }, -//!if outputMode == ECMAScript6 +//!if useECMAScript2015 == true "assumingES6": true, //!else "assumingES6": false, @@ -71,7 +71,7 @@ Object["freeze"]($linkingInfo["semantics"]); // Snapshots of builtins and polyfills -//!if outputMode == ECMAScript6 +//!if useECMAScript2015 == true const $imul = Math["imul"]; const $fround = Math["fround"]; const $clz32 = Math["clz32"]; @@ -155,7 +155,7 @@ let $L0; // identityHashCode support let $lastIDHash = 0; // last value attributed to an id hash code -//!if outputMode == ECMAScript6 +//!if useECMAScript2015 == true const $idHashCodeMap = new WeakMap(); //!else const $idHashCodeMap = typeof WeakMap !== "undefined" ? new WeakMap() : null; @@ -198,7 +198,7 @@ function $propertyName(obj) { // Boxed Char -//!if outputMode == ECMAScript6 +//!if useECMAScript2015 == true class $Char { constructor(c) { this.c = c; @@ -545,7 +545,7 @@ function $systemArraycopy(src, srcPos, dest, destPos, length) { }; const $systemIdentityHashCode = -//!if outputMode != ECMAScript6 +//!if useECMAScript2015 == false ($idHashCodeMap !== null) ? //!endif (function(obj) { @@ -565,7 +565,7 @@ const $systemIdentityHashCode = return hash; } } -//!if outputMode != ECMAScript6 +//!if useECMAScript2015 == false }) : (function(obj) { switch (typeof obj) { @@ -759,7 +759,7 @@ function $typedArray2DoubleArray(value) { // TypeData class -//!if outputMode != ECMAScript6 +//!if useECMAScript2015 == false /** @constructor */ function $TypeData() { //!else @@ -788,7 +788,7 @@ constructor() { this["isInstance"] = void 0; }; -//!if outputMode != ECMAScript6 +//!if useECMAScript2015 == false $TypeData.prototype.initPrim = function( //!else initPrim( @@ -809,7 +809,7 @@ initPrim( return this; }; -//!if outputMode != ECMAScript6 +//!if useECMAScript2015 == false $TypeData.prototype.initClass = function( //!else initClass( @@ -842,7 +842,7 @@ initClass( return this; }; -//!if outputMode != ECMAScript6 +//!if useECMAScript2015 == false $TypeData.prototype.initArray = function( //!else initArray( @@ -857,7 +857,7 @@ initArray( // been defined yet when this constructor is called. const componentZero = (componentZero0 == "longZero") ? $L0 : componentZero0; -//!if outputMode != ECMAScript6 +//!if useECMAScript2015 == false /** @constructor */ const ArrayClass = function(arg) { if (typeof(arg) === "number") { @@ -969,7 +969,7 @@ initArray( return this; }; -//!if outputMode != ECMAScript6 +//!if useECMAScript2015 == false $TypeData.prototype.getClassOf = function() { //!else getClassOf() { @@ -979,7 +979,7 @@ getClassOf() { return this._classOf; }; -//!if outputMode != ECMAScript6 +//!if useECMAScript2015 == false $TypeData.prototype.getArrayOf = function() { //!else getArrayOf() { @@ -991,7 +991,7 @@ getArrayOf() { // java.lang.Class support -//!if outputMode != ECMAScript6 +//!if useECMAScript2015 == false $TypeData.prototype["isAssignableFrom"] = function(that) { //!else "isAssignableFrom"(that) { @@ -1020,7 +1020,7 @@ $TypeData.prototype["isAssignableFrom"] = function(that) { } }; -//!if outputMode != ECMAScript6 +//!if useECMAScript2015 == false $TypeData.prototype["getSuperclass"] = function() { //!else "getSuperclass"() { @@ -1028,7 +1028,7 @@ $TypeData.prototype["getSuperclass"] = function() { return this.parentData ? this.parentData.getClassOf() : null; }; -//!if outputMode != ECMAScript6 +//!if useECMAScript2015 == false $TypeData.prototype["getComponentType"] = function() { //!else "getComponentType"() { @@ -1036,7 +1036,7 @@ $TypeData.prototype["getComponentType"] = function() { return this.componentData ? this.componentData.getClassOf() : null; }; -//!if outputMode != ECMAScript6 +//!if useECMAScript2015 == false $TypeData.prototype["newArrayOfThisClass"] = function(lengths) { //!else "newArrayOfThisClass"(lengths) { @@ -1046,7 +1046,7 @@ $TypeData.prototype["newArrayOfThisClass"] = function(lengths) { arrayClassData = arrayClassData.getArrayOf(); return $newArrayObject(arrayClassData, lengths); }; -//!if outputMode == ECMAScript6 +//!if useECMAScript2015 == true }; //!endif diff --git a/linker/shared/src/main/scala/org/scalajs/linker/ESFeatures.scala b/linker/shared/src/main/scala/org/scalajs/linker/ESFeatures.scala new file mode 100644 index 0000000000..3c92eddd0d --- /dev/null +++ b/linker/shared/src/main/scala/org/scalajs/linker/ESFeatures.scala @@ -0,0 +1,80 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js linker ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2018, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package org.scalajs.linker + +/** ECMAScript features to use when linking to JavaScript. + * + * The options in `ESFeatures` specify what features of modern versions of + * JavaScript are used by the Scala.js linker. + * + * - Options whose name is of the form `useX` *force* the linker to use the + * corresponding features, guaranteeing that the specific semantics that + * they provide will be used. + * - Options whose name is of the form `allowX` *allow* the linker to use the + * corresponding features if it supports them. Support for such options can + * be dropped in any subsequent version of the linker, including patch + * versions. + */ +final class ESFeatures private ( + /** Whether to use ECMAScript 2015 features, such as classes and arrow + * functions. + */ + val useECMAScript2015: Boolean +) { + import ESFeatures._ + + private def this() = { + this( + useECMAScript2015 = false + ) + } + + def withUseECMAScript2015(useECMAScript2015: Boolean): ESFeatures = + copy(useECMAScript2015 = useECMAScript2015) + + override def equals(that: Any): Boolean = that match { + case that: ESFeatures => + this.useECMAScript2015 == that.useECMAScript2015 + case _ => + false + } + + override def hashCode(): Int = { + import scala.util.hashing.MurmurHash3._ + var acc = HashSeed + acc = mixLast(acc, useECMAScript2015.##) + finalizeHash(acc, 1) + } + + override def toString(): String = { + s"""ESFeatures( + | useECMAScript2015 = $useECMAScript2015 + |)""".stripMargin + } + + private def copy( + useECMAScript2015: Boolean = this.useECMAScript2015 + ): ESFeatures = { + new ESFeatures( + useECMAScript2015 = useECMAScript2015 + ) + } +} + +object ESFeatures { + private val HashSeed = + scala.util.hashing.MurmurHash3.stringHash(classOf[ESFeatures].getName) + + /** Default configuration of ECMAScript features. + * + * - `useECMAScript2015`: false + */ + val Defaults: ESFeatures = new ESFeatures() +} diff --git a/linker/shared/src/main/scala/org/scalajs/linker/Linker.scala b/linker/shared/src/main/scala/org/scalajs/linker/Linker.scala index 1ad0ff3869..bc66fee66d 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/Linker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/Linker.scala @@ -16,7 +16,6 @@ import java.util.concurrent.atomic.AtomicBoolean import org.scalajs.logging.Logger import org.scalajs.io._ -import org.scalajs.linker.standard._ import org.scalajs.linker.analyzer.SymbolRequirement import org.scalajs.linker.frontend.LinkerFrontend import org.scalajs.linker.frontend.optimizer.IncOptimizer diff --git a/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala b/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala index edf7f62bd9..2b8824c389 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala @@ -194,7 +194,7 @@ object StandardLinker { * * - `semantics`: [[Semantics.Defaults]] * - `moduleKind`: [[ModuleKind.NoModule]] - * - `esFeatures`: [[org.scalajs.linker.standard.OutputMode.Defaults ESFeatures.Defaults]] + * - `esFeatures`: [[ESFeatures.Defaults]] * - `checkIR`: `true` * - `optimizer`: `true` * - `parallel`: `true` diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala index c2cac0d662..9efa48cbda 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala @@ -16,7 +16,6 @@ import org.scalajs.ir.Trees._ import Types._ import org.scalajs.linker._ -import org.scalajs.linker.standard.OutputMode import org.scalajs.linker.backend.javascript.{Trees => js} import CheckedBehavior.Unchecked @@ -56,17 +55,15 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val className = tree.name.name val allDefsBlock = js.Block(allDefs)(tree.pos) - val entireClassDefWithGlobals = outputMode match { - case OutputMode.ECMAScript51Isolated => - WithGlobals(allDefsBlock) - - case OutputMode.ECMAScript6 => - val allDefs = allDefsBlock match { - case js.Block(allDefs) => allDefs - case js.Skip() => Nil - case oneDef => List(oneDef) - } - genES6Class(tree, allDefs) + val entireClassDefWithGlobals = if (useClasses) { + val allDefs = allDefsBlock match { + case js.Block(allDefs) => allDefs + case js.Skip() => Nil + case oneDef => List(oneDef) + } + genES6Class(tree, allDefs) + } else { + WithGlobals(allDefsBlock) } if (!tree.kind.isJSClass) { @@ -144,7 +141,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { def genES6Class(tree: LinkedClass, members: List[js.Tree])( implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { - require(outputMode == OutputMode.ECMAScript6) + require(useClasses) val className = tree.name.name val classIdent = @@ -193,13 +190,10 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { assert(tree.superClass.isDefined || tree.name.name == Definitions.ObjectClass, s"Class ${tree.name.name} is missing a parent class") - outputMode match { - case OutputMode.ECMAScript51Isolated => - genES5Constructor(tree, initToInline) - - case OutputMode.ECMAScript6 => - genES6Constructor(tree, initToInline) - } + if (useClasses) + genES6Constructor(tree, initToInline) + else + genES5Constructor(tree, initToInline) } /** Generates the JS constructor for a class, ES5 style. */ @@ -330,18 +324,16 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { implicit val pos = tree.pos - val superCtorCallAndFieldDefs = outputMode match { - case OutputMode.ECMAScript51Isolated => - val allFields = - globalKnowledge.getAllScalaClassFieldDefs(tree.encodedName) - genFieldDefsOfScalaClass(allFields) - - case OutputMode.ECMAScript6 => - val fieldDefs = genFieldDefsOfScalaClass(tree.fields) - if (tree.superClass.isEmpty) - fieldDefs - else - js.Apply(js.Super(), Nil) :: fieldDefs + val superCtorCallAndFieldDefs = if (useClasses) { + val fieldDefs = genFieldDefsOfScalaClass(tree.fields) + if (tree.superClass.isEmpty) + fieldDefs + else + js.Apply(js.Super(), Nil) :: fieldDefs + } else { + val allFields = + globalKnowledge.getAllScalaClassFieldDefs(tree.encodedName) + genFieldDefsOfScalaClass(allFields) } initToInline.fold { @@ -476,28 +468,24 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { methodFun, origName)) case methodName => - outputMode match { - case OutputMode.ECMAScript51Isolated => - genAddToObject(className, encodeClassVar(className), methodName, - methodFun) - - case OutputMode.ECMAScript6 => - for (propName <- genPropertyName(methodName)) yield { - js.MethodDef(static = true, propName, methodFun.args, - methodFun.body) - } + if (useClasses) { + for (propName <- genPropertyName(methodName)) yield { + js.MethodDef(static = true, propName, methodFun.args, + methodFun.body) + } + } else { + genAddToObject(className, encodeClassVar(className), methodName, + methodFun) } } } else { - outputMode match { - case OutputMode.ECMAScript51Isolated => - genAddToPrototype(className, method.name, methodFun) - - case OutputMode.ECMAScript6 => - for (propName <- genPropertyName(method.name)) yield { - js.MethodDef(static = false, propName, methodFun.args, - methodFun.body) - } + if (useClasses) { + for (propName <- genPropertyName(method.name)) yield { + js.MethodDef(static = false, propName, methodFun.args, + methodFun.body) + } + } else { + genAddToPrototype(className, method.name, methodFun) } } } @@ -527,12 +515,10 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { /** Generates a property. */ def genProperty(className: String, property: PropertyDef)( implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { - outputMode match { - case OutputMode.ECMAScript51Isolated => - genPropertyES5(className, property) - case OutputMode.ECMAScript6 => - genPropertyES6(className, property) - } + if (useClasses) + genPropertyES6(className, property) + else + genPropertyES5(className, property) } private def genPropertyES5(className: String, property: PropertyDef)( @@ -1223,22 +1209,20 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val globalVar = envField(field, subField, origName) val globalVarIdent = globalVar.ident - outputMode match { - case OutputMode.ECMAScript51Isolated => - value match { - case js.Function(false, args, body) => - // Make sure the function has a meaningful `name` property - val functionExpr = js.FunctionDef(globalVarIdent, args, body) - if (keepFunctionExpression) - js.VarDef(globalVarIdent, Some(functionExpr)) - else - functionExpr - case _ => - js.VarDef(globalVarIdent, Some(value)) - } - - case OutputMode.ECMAScript6 => - genLet(globalVarIdent, mutable, value) + if (esFeatures.useECMAScript2015) { + genLet(globalVarIdent, mutable, value) + } else { + value match { + case js.Function(false, args, body) => + // Make sure the function has a meaningful `name` property + val functionExpr = js.FunctionDef(globalVarIdent, args, body) + if (keepFunctionExpression) + js.VarDef(globalVarIdent, Some(functionExpr)) + else + functionExpr + case _ => + js.VarDef(globalVarIdent, Some(value)) + } } } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLibs.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLibs.scala index 96c39c11e9..bcc9c734b3 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLibs.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLibs.scala @@ -15,14 +15,13 @@ import org.scalajs.ir.ScalaJSVersions import org.scalajs.io._ import org.scalajs.linker._ -import org.scalajs.linker.standard._ import scala.collection.immutable.Seq import scala.collection.mutable private[emitter] object CoreJSLibs { - private type Config = (Semantics, OutputMode, ModuleKind) + private type Config = (Semantics, ESFeatures, ModuleKind) private val cachedLibByConfig = mutable.HashMap.empty[Config, VirtualJSFile] @@ -33,21 +32,21 @@ private[emitter] object CoreJSLibs { private val gitHubBaseURI = new URI("https://raw.githubusercontent.com/scala-js/scala-js/") - def lib(semantics: Semantics, outputMode: OutputMode, + def lib(semantics: Semantics, esFeatures: ESFeatures, moduleKind: ModuleKind): VirtualJSFile = { synchronized { cachedLibByConfig.getOrElseUpdate( - (semantics, outputMode, moduleKind), - makeLib(semantics, outputMode, moduleKind)) + (semantics, esFeatures, moduleKind), + makeLib(semantics, esFeatures, moduleKind)) } } - private def makeLib(semantics: Semantics, outputMode: OutputMode, + private def makeLib(semantics: Semantics, esFeatures: ESFeatures, moduleKind: ModuleKind): VirtualJSFile = { - new ScalaJSEnvVirtualJSFile(makeContent(semantics, outputMode, moduleKind)) + new ScalaJSEnvVirtualJSFile(makeContent(semantics, esFeatures, moduleKind)) } - private def makeContent(semantics: Semantics, outputMode: OutputMode, + private def makeContent(semantics: Semantics, esFeatures: ESFeatures, moduleKind: ModuleKind): String = { // This is a basic sort-of-C-style preprocessor @@ -63,8 +62,8 @@ private[emitter] object CoreJSLibs { else "Loose" case "productionMode" => semantics.productionMode.toString() - case "outputMode" => - outputMode.toString() + case "useECMAScript2015" => + esFeatures.useECMAScript2015.toString() case "moduleKind" => moduleKind.toString() } @@ -119,14 +118,10 @@ private[emitter] object CoreJSLibs { val content = lines.mkString("", "\n", "\n").replace( "{{LINKER_VERSION}}", ScalaJSVersions.current) - outputMode match { - case OutputMode.ECMAScript51Isolated => - content - .replaceAll(raw"\b(let|const)\b", "var") - - case OutputMode.ECMAScript6 => - content - } + if (esFeatures.useECMAScript2015) + content + else + content.replaceAll(raw"\b(let|const)\b", "var") } private class ScalaJSEnvVirtualJSFile(override val content: String) extends VirtualJSFile { diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala index d044621f71..5bdb501047 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala @@ -40,11 +40,11 @@ final class Emitter private (config: CommonPhaseConfig, private val knowledgeGuardian = new KnowledgeGuardian - private val baseCoreJSLib = CoreJSLibs.lib(semantics, outputMode, moduleKind) + private val baseCoreJSLib = CoreJSLibs.lib(semantics, esFeatures, moduleKind) private class State(val lastMentionedDangerousGlobalRefs: Set[String]) { val jsGen: JSGen = { - new JSGen(semantics, outputMode, moduleKind, internalOptions, + new JSGen(semantics, esFeatures, moduleKind, internalOptions, lastMentionedDangerousGlobalRefs) } @@ -648,10 +648,7 @@ private object Emitter { def cond(p: Boolean)(v: => SymbolRequirement): SymbolRequirement = if (p) v else none() - def assumingES6: Boolean = coreSpec.outputMode match { - case OutputMode.ECMAScript51Isolated => false - case OutputMode.ECMAScript6 => true - } + def assumingES6: Boolean = coreSpec.esFeatures.useECMAScript2015 multiple( instantiateClass("O", "init___"), diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala index b68ab2c950..b4cceb3045 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala @@ -22,7 +22,6 @@ import ir.Types._ import org.scalajs.linker._ import org.scalajs.linker.CheckedBehavior._ -import org.scalajs.linker.standard.OutputMode import org.scalajs.linker.backend.javascript.{Trees => js} import java.io.StringWriter @@ -31,8 +30,8 @@ import Transients._ /** Desugaring of the IR to JavaScript functions. * - * The general shape and compliance to standards is chosen with an - * [[OutputMode]]. + * The general shape and compliance to standards is chosen with + * [[ESFeatures]]. * * The major difference between the IR and JS is that most constructs can be * used in expression position. The main work of the desugaring is to @@ -422,12 +421,9 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { if (isStat) body else Return(body) - val translateRestParam = outputMode match { - case OutputMode.ECMAScript51Isolated => - params.nonEmpty && params.last.rest - case _ => - false - } + val translateRestParam = + if (esFeatures.useECMAScript2015) false + else params.nonEmpty && params.last.rest val extractRestParam = if (translateRestParam) makeExtractRestParam(params) @@ -652,32 +648,28 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { "Need enclosing class for super constructor call.") } - val superCtorCall = { - outputMode match { - case OutputMode.ECMAScript51Isolated => - val superCtor = { - if (globalKnowledge.hasStoredSuperClass(enclosingClassName)) { - envField("superClass") - } else { - val superClass = - globalKnowledge.getSuperClassOfJSClass(enclosingClassName) - extractWithGlobals(genRawJSClassConstructor(superClass)) - } - } - - if (containsAnySpread(newArgs)) { - val argArray = spreadToArgArray(newArgs) - js.Apply( - genIdentBracketSelect(superCtor, "apply"), - List(js.This(), transformExprNoChar(argArray))) - } else { - js.Apply( - genIdentBracketSelect(superCtor, "call"), - js.This() :: newArgs.map(transformJSArg)) - } + val superCtorCall = if (useClasses) { + js.Apply(js.Super(), newArgs.map(transformJSArg)) + } else { + val superCtor = { + if (globalKnowledge.hasStoredSuperClass(enclosingClassName)) { + envField("superClass") + } else { + val superClass = + globalKnowledge.getSuperClassOfJSClass(enclosingClassName) + extractWithGlobals(genRawJSClassConstructor(superClass)) + } + } - case OutputMode.ECMAScript6 => - js.Apply(js.Super(), newArgs.map(transformJSArg)) + if (containsAnySpread(newArgs)) { + val argArray = spreadToArgArray(newArgs) + js.Apply( + genIdentBracketSelect(superCtor, "apply"), + List(js.This(), transformExprNoChar(argArray))) + } else { + js.Apply( + genIdentBracketSelect(superCtor, "call"), + js.This() :: newArgs.map(transformJSArg)) } } @@ -1320,19 +1312,18 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { */ def extractLet(inner: (Lhs, Env) => js.Tree)( implicit env: Env): js.Tree = { - outputMode match { - case OutputMode.ECMAScript51Isolated => - inner(lhs, env) - case OutputMode.ECMAScript6 => - lhs match { - case Lhs.VarDef(name, tpe, mutable) => - val innerEnv = env.withDef(name, tpe, true) - js.Block( - doEmptyVarDef(name, tpe), - inner(Lhs.Assign(VarRef(name)(tpe)), innerEnv)) - case _ => - inner(lhs, env) - } + if (esFeatures.useECMAScript2015) { + lhs match { + case Lhs.VarDef(name, tpe, mutable) => + val innerEnv = env.withDef(name, tpe, true) + js.Block( + doEmptyVarDef(name, tpe), + inner(Lhs.Assign(VarRef(name)(tpe)), innerEnv)) + case _ => + inner(lhs, env) + } + } else { + inner(lhs, env) } } @@ -1847,7 +1838,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { private def doesObjectConstrRequireDesugaring( tree: JSObjectConstr): Boolean = { def computedNamesAllowed: Boolean = - outputMode == OutputMode.ECMAScript6 + esFeatures.useECMAScript2015 def hasComputedName: Boolean = tree.fields.exists(_._1.isInstanceOf[ComputedName]) @@ -1885,7 +1876,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { def transformJSArg(tree: TreeOrJSSpread)(implicit env: Env): js.Tree = { tree match { case JSSpread(items) => - assert(outputMode == OutputMode.ECMAScript6) + assert(esFeatures.useECMAScript2015) js.Spread(transformExprNoChar(items))(tree.pos) case tree: Tree => transformExprNoChar(tree) diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/GlobalRefUtils.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/GlobalRefUtils.scala index 1702c36822..48c9610e44 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/GlobalRefUtils.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/GlobalRefUtils.scala @@ -8,8 +8,6 @@ package org.scalajs.linker.backend.emitter -import org.scalajs.linker.standard.OutputMode - /** Utilities related to global refs mentioned in the program. * * When a global ref is mentioned somewhere in the program, bad things happen. diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/JSGen.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/JSGen.scala index 90098daffe..83eb6bd224 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/JSGen.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/JSGen.scala @@ -19,27 +19,23 @@ import ir.Types._ import ir.{Trees => irt} import org.scalajs.linker._ -import org.scalajs.linker.standard.OutputMode import org.scalajs.linker.backend.javascript.Trees._ /** Collection of tree generators that are used accross the board. * This class is fully stateless. * - * Also carries around config (semantics and outputMode). + * Also carries around config (semantics and esFeatures). */ private[emitter] final class JSGen(val semantics: Semantics, - val outputMode: OutputMode, val moduleKind: ModuleKind, + val esFeatures: ESFeatures, val moduleKind: ModuleKind, internalOptions: InternalOptions, mentionedDangerousGlobalRefs: Set[String]) { import JSGen._ - val useArrowFunctions = { - outputMode match { - case OutputMode.ECMAScript51Isolated => false - case OutputMode.ECMAScript6 => true - } - } + val useClasses = esFeatures.useECMAScript2015 + + val useArrowFunctions = esFeatures.useECMAScript2015 def genZeroOf(tpe: Type)(implicit pos: Position): Tree = { tpe match { @@ -70,12 +66,10 @@ private[emitter] final class JSGen(val semantics: Semantics, def genLet(name: Ident, mutable: Boolean, rhs: Tree)( implicit pos: Position): LocalDef = { - outputMode match { - case OutputMode.ECMAScript51Isolated => - VarDef(name, Some(rhs)) - case OutputMode.ECMAScript6 => - Let(name, mutable, Some(rhs)) - } + if (esFeatures.useECMAScript2015) + Let(name, mutable, Some(rhs)) + else + VarDef(name, Some(rhs)) } def genEmptyMutableLet(name: Ident)(implicit pos: Position): LocalDef = @@ -86,12 +80,10 @@ private[emitter] final class JSGen(val semantics: Semantics, private def genEmptyLet(name: Ident, mutable: Boolean)( implicit pos: Position): LocalDef = { - outputMode match { - case OutputMode.ECMAScript51Isolated => - VarDef(name, rhs = None) - case OutputMode.ECMAScript6 => - Let(name, mutable, rhs = None) - } + if (esFeatures.useECMAScript2015) + Let(name, mutable, rhs = None) + else + VarDef(name, rhs = None) } def genSelectStatic(className: String, item: irt.Ident)( diff --git a/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala b/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala index ce20aa6169..8142fef768 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala @@ -3909,10 +3909,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { } case (JSLinkingInfo(), StringLiteral("assumingES6")) => - BooleanLiteral(outputMode match { - case OutputMode.ECMAScript51Isolated => false - case OutputMode.ECMAScript6 => true - }) + BooleanLiteral(esFeatures.useECMAScript2015) case (JSLinkingInfo(), StringLiteral("version")) => StringLiteral(ScalaJSVersions.current) diff --git a/linker/shared/src/main/scala/org/scalajs/linker/package.scala b/linker/shared/src/main/scala/org/scalajs/linker/package.scala deleted file mode 100644 index af0422503f..0000000000 --- a/linker/shared/src/main/scala/org/scalajs/linker/package.scala +++ /dev/null @@ -1,16 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - -package org.scalajs - -package object linker { - type ESFeatures = org.scalajs.linker.standard.OutputMode - - val ESFeatures: org.scalajs.linker.standard.OutputMode.type = - org.scalajs.linker.standard.OutputMode -} diff --git a/linker/shared/src/main/scala/org/scalajs/linker/standard/CoreSpec.scala b/linker/shared/src/main/scala/org/scalajs/linker/standard/CoreSpec.scala index 38e650bec8..6c905c71c6 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/standard/CoreSpec.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/standard/CoreSpec.scala @@ -16,8 +16,8 @@ final class CoreSpec private ( val semantics: Semantics, /** Module kind. */ val moduleKind: ModuleKind, - /** Standard output mode. */ - val outputMode: OutputMode + /** ECMAScript features to use. */ + val esFeatures: ESFeatures ) { import CoreSpec._ @@ -25,7 +25,7 @@ final class CoreSpec private ( case that: CoreSpec => this.semantics == that.semantics && this.moduleKind == that.moduleKind && - this.outputMode == that.outputMode + this.esFeatures == that.esFeatures case _ => false } @@ -35,7 +35,7 @@ final class CoreSpec private ( var acc = HashSeed acc = mix(acc, semantics.##) acc = mix(acc, moduleKind.##) - acc = mixLast(acc, outputMode.##) + acc = mixLast(acc, esFeatures.##) finalizeHash(acc, 3) } @@ -43,7 +43,7 @@ final class CoreSpec private ( s"""CoreSpec( | semantics = $semantics, | moduleKind = $moduleKind, - | outputMode = $outputMode + | esFeatures = $esFeatures |)""".stripMargin } } @@ -56,13 +56,13 @@ private[linker] object CoreSpec { new CoreSpec( semantics = Semantics.Defaults, moduleKind = ModuleKind.NoModule, - outputMode = OutputMode.Defaults) + esFeatures = ESFeatures.Defaults) } private[linker] def apply( semantics: Semantics, moduleKind: ModuleKind, - outputMode: OutputMode): CoreSpec = { - new CoreSpec(semantics, moduleKind, outputMode) + esFeatures: ESFeatures): CoreSpec = { + new CoreSpec(semantics, moduleKind, esFeatures) } } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/standard/OutputMode.scala b/linker/shared/src/main/scala/org/scalajs/linker/standard/OutputMode.scala deleted file mode 100644 index d15114fda6..0000000000 --- a/linker/shared/src/main/scala/org/scalajs/linker/standard/OutputMode.scala +++ /dev/null @@ -1,93 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.linker.standard - -/** JavaScript output mode. - * - * For forward source compatibility with Scala.js 1.x, use the alias - * [[org.scalajs.linker.ESFeatures]] instead. - */ -sealed abstract class OutputMode { - import OutputMode._ - - /** Whether to use ECMAScript 2015 features, such as classes and arrow - * functions. - */ - def useECMAScript2015: Boolean = this match { - case ECMAScript51Isolated => false - case ECMAScript6 => true - } - - def withUseECMAScript2015(useECMAScript2015: Boolean): OutputMode = - if (useECMAScript2015) ECMAScript6 - else ECMAScript51Isolated -} - -/** Factory for `OutputMode`s. - * - * For forward source compatibility with Scala.js 1.x, use the alias - * [[org.scalajs.linker.ESFeatures]] instead. - */ -object OutputMode { - /** All the available output modes. - * There are listed in decreasing order of "importance", as judged by - * whoever maintains the back-ends. - */ - @deprecated( - "The notion that there is a list of existing output modes is going away.", - "0.6.23") - val All = List( - ECMAScript51Isolated, - ECMAScript6) - - /** Default configuration of the output mode. - * - * - `useECMAScript2015`: false - */ - val Defaults: OutputMode = ECMAScript51Isolated - - /** Default configuration of the output mode. */ - @deprecated("Use Defaults instead.", "0.6.23") - val Default = Defaults - - /** Output mode compliant with ECMAScript 5.1 (deprecated alias). - * - * This value is not annotated with `@deprecated` for technical reasons, but - * it should be considered as such. - * - * Use `Defaults` instead. - */ - case object ECMAScript51Isolated extends OutputMode - - /** Output mode compliant with ECMAScript 5.1. - * - * This is the default output mode. It assumes that the target platform - * supports ECMAScript 5.1, ideally with correct handling of strict mode. - */ - @deprecated("Use Defaults instead.", "0.6.23") - val ECMAScript51: ECMAScript51Isolated.type = ECMAScript51Isolated - - /** Output mode compliant with ECMAScript 2015 (deprecated alias). - * - * This value is not annotated with `@deprecated` for technical reasons, but - * it should be considered as such. - * - * Use `Defaults.withUseECMAScript2015(true)` instead. - */ - case object ECMAScript6 extends OutputMode - - /** Output mode compliant with ECMAScript 2015. - * - * This output mode assumes that the target platform supports ECMAScript - * 2015 (aka ES 6). - */ - @deprecated("Use `Defaults.withUseECMAScript2015(true)` instead.", "0.6.23") - val ECMAScript2015: ECMAScript6.type = ECMAScript6 -} diff --git a/linker/shared/src/main/scala/org/scalajs/linker/standard/package.scala b/linker/shared/src/main/scala/org/scalajs/linker/standard/package.scala deleted file mode 100644 index 5043bc8966..0000000000 --- a/linker/shared/src/main/scala/org/scalajs/linker/standard/package.scala +++ /dev/null @@ -1,27 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - -package org.scalajs.linker - -package object standard { - implicit class StandardLinkerConfigStandardOps private[standard] ( - val __private_self: StandardLinker.Config) extends AnyVal { - - import StandardLinker.Config - - @inline private def self: Config = __private_self - - /** Standard output mode. */ - @deprecated("Use esFeatures instead.", "0.6.23") - def outputMode: OutputMode = self.esFeatures - - @deprecated("Use withESFeatures instead.", "0.6.23") - def withOutputMode(outputMode: OutputMode): Config = - self.withESFeatures(outputMode) - } -} diff --git a/project/Build.scala b/project/Build.scala index 072ac8a7c7..e9275ed019 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -49,13 +49,6 @@ object ExposedValues extends AutoPlugin { val CheckedBehavior = org.scalajs.linker.CheckedBehavior - val OutputMode = org.scalajs.linker.standard.OutputMode - - implicit def StandardLinkerConfigStandardOps( - config: StandardLinker.Config): standard.StandardLinkerConfigStandardOps = { - standard.StandardLinkerConfigStandardOps(config) - } - type NodeJSEnvForcePolyfills = build.NodeJSEnvForcePolyfills } } diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 504759462a..29a7de3dee 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -17,7 +17,6 @@ import org.scalajs.io.JSUtils.escapeJS import org.scalajs.linker._ import org.scalajs.linker.irio._ -import org.scalajs.linker.standard._ import org.scalajs.jsenv._ import org.scalajs.jsenv.nodejs.NodeJSEnv @@ -255,7 +254,7 @@ private[sbtplugin] object ScalaJSPluginInternal { scalaJSLinkerConfig in fullOptJS ~= { prevConfig => prevConfig .withSemantics(_.optimized) - .withClosureCompiler(prevConfig.esFeatures == OutputMode.ECMAScript51Isolated) + .withClosureCompiler(!prevConfig.esFeatures.useECMAScript2015) }, scalaJSLinkedFile := Def.settingDyn { From d88c428fdedf7828845a90d8e24038537a1122ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 21 Mar 2018 15:42:46 +0100 Subject: [PATCH 0647/2665] Blacklist the partest neg/inlineMaxSize.scala. It often spuriously fails on one of our CI machines, with out-of- memory errors. --- .../scala/tools/partest/scalajs/2.11.11/BlacklistedTests.txt | 1 + .../scala/tools/partest/scalajs/2.11.11/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.11.12/BlacklistedTests.txt | 1 + .../scala/tools/partest/scalajs/2.11.12/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt | 1 + .../scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt | 1 + .../scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt | 1 + .../scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt | 1 + .../scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.12.2/BlacklistedTests.txt | 1 + .../scala/tools/partest/scalajs/2.12.2/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.12.3/BlacklistedTests.txt | 1 + .../scala/tools/partest/scalajs/2.12.3/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.12.4/BlacklistedTests.txt | 1 + .../scala/tools/partest/scalajs/2.12.4/WhitelistedTests.txt | 1 - .../scala/tools/partest/scalajs/2.13.0-M2/BlacklistedTests.txt | 1 + .../scala/tools/partest/scalajs/2.13.0-M2/WhitelistedTests.txt | 1 - 20 files changed, 10 insertions(+), 10 deletions(-) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/BlacklistedTests.txt index e266529020..f8521f6867 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/BlacklistedTests.txt @@ -32,6 +32,7 @@ neg/t7622-cyclic-dependency neg/macro-incompatible-macro-engine-c.scala # Spurious failures +neg/inlineMaxSize.scala neg/patmatexhaust-huge.scala # Uses .java files diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/WhitelistedTests.txt index d423eabc3b..c4c87bd7b0 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.11/WhitelistedTests.txt @@ -1058,7 +1058,6 @@ neg/t9127.scala neg/t9286c.scala neg/t9286a.scala neg/virtpatmat_exhaust_big.scala -neg/inlineMaxSize.scala run/t7249.scala run/t3563.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/BlacklistedTests.txt index 5e0cbe6935..70f00c66ef 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/BlacklistedTests.txt @@ -32,6 +32,7 @@ neg/t7622-cyclic-dependency neg/macro-incompatible-macro-engine-c.scala # Spurious failures +neg/inlineMaxSize.scala neg/patmatexhaust-huge.scala # Uses .java files diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/WhitelistedTests.txt index d423eabc3b..c4c87bd7b0 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.12/WhitelistedTests.txt @@ -1058,7 +1058,6 @@ neg/t9127.scala neg/t9286c.scala neg/t9286a.scala neg/virtpatmat_exhaust_big.scala -neg/inlineMaxSize.scala run/t7249.scala run/t3563.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt index 6c023264e6..63c0d83900 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/BlacklistedTests.txt @@ -32,6 +32,7 @@ neg/t7622-cyclic-dependency neg/macro-incompatible-macro-engine-c.scala # Spurious failures +neg/inlineMaxSize.scala neg/patmatexhaust-huge.scala # Uses .java files diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt index 83b53ca360..bf109f7b58 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.7/WhitelistedTests.txt @@ -1059,7 +1059,6 @@ neg/t9127.scala neg/t9286c.scala neg/t9286a.scala neg/virtpatmat_exhaust_big.scala -neg/inlineMaxSize.scala run/t7249.scala run/t3563.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt index b501e896a4..6a0022b57b 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/BlacklistedTests.txt @@ -32,6 +32,7 @@ neg/t7622-cyclic-dependency neg/macro-incompatible-macro-engine-c.scala # Spurious failures +neg/inlineMaxSize.scala neg/patmatexhaust-huge.scala # Uses .java files diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt index b299356869..01eebfd077 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.11.8/WhitelistedTests.txt @@ -1058,7 +1058,6 @@ neg/t9127.scala neg/t9286c.scala neg/t9286a.scala neg/virtpatmat_exhaust_big.scala -neg/inlineMaxSize.scala run/t7249.scala run/t3563.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt index c76169b0af..5664aec032 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/BlacklistedTests.txt @@ -27,6 +27,7 @@ neg/t7622-cyclic-dependency neg/macro-incompatible-macro-engine-c.scala # Spurious failures +neg/inlineMaxSize.scala neg/patmatexhaust-huge.scala # Uses .java files diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt index eb90bc94bd..581389d85d 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.0/WhitelistedTests.txt @@ -1045,7 +1045,6 @@ neg/t9127.scala neg/t9286c.scala neg/t9286a.scala neg/virtpatmat_exhaust_big.scala -neg/inlineMaxSize.scala run/t7249.scala run/t3563.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt index d74ed2e038..e2f5fc6de3 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/BlacklistedTests.txt @@ -30,6 +30,7 @@ neg/t7014 neg/macro-incompatible-macro-engine-c.scala # Spurious failures +neg/inlineMaxSize.scala neg/patmatexhaust-huge.scala # Uses .java files diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt index 5fd2ca4d19..6a6774f2e2 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.1/WhitelistedTests.txt @@ -1043,7 +1043,6 @@ neg/t9127.scala neg/t9286c.scala neg/t9286a.scala neg/virtpatmat_exhaust_big.scala -neg/inlineMaxSize.scala run/t7249.scala run/t3563.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/BlacklistedTests.txt index c51f107799..ec677cb9dd 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/BlacklistedTests.txt @@ -27,6 +27,7 @@ neg/t7622-cyclic-dependency neg/macro-incompatible-macro-engine-c.scala # Spurious failures +neg/inlineMaxSize.scala neg/patmatexhaust-huge.scala # Uses .java files diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/WhitelistedTests.txt index 66fe31b24c..5d17a645e4 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.2/WhitelistedTests.txt @@ -1043,7 +1043,6 @@ neg/t9127.scala neg/t9286c.scala neg/t9286a.scala neg/virtpatmat_exhaust_big.scala -neg/inlineMaxSize.scala run/t7249.scala run/t3563.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/BlacklistedTests.txt index b1742b3e61..7dd6aa3c9a 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/BlacklistedTests.txt @@ -27,6 +27,7 @@ neg/t7622-cyclic-dependency neg/macro-incompatible-macro-engine-c.scala # Spurious failures +neg/inlineMaxSize.scala neg/patmatexhaust-huge.scala # Uses .java files diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/WhitelistedTests.txt index cf60cfbd13..fdd350307d 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.3/WhitelistedTests.txt @@ -1042,7 +1042,6 @@ neg/t9127.scala neg/t9286c.scala neg/t9286a.scala neg/virtpatmat_exhaust_big.scala -neg/inlineMaxSize.scala run/t7249.scala run/t3563.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/BlacklistedTests.txt index b4719299ac..ab6cb7a640 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/BlacklistedTests.txt @@ -27,6 +27,7 @@ neg/t7622-cyclic-dependency neg/macro-incompatible-macro-engine-c.scala # Spurious failures +neg/inlineMaxSize.scala neg/patmatexhaust-huge.scala # Uses .java files diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/WhitelistedTests.txt index c3618e96f3..7e8c408212 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.4/WhitelistedTests.txt @@ -1042,7 +1042,6 @@ neg/t9127.scala neg/t9286c.scala neg/t9286a.scala neg/virtpatmat_exhaust_big.scala -neg/inlineMaxSize.scala run/t7249.scala run/t3563.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/BlacklistedTests.txt index 1d884878ed..7bc4157c8c 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/BlacklistedTests.txt @@ -27,6 +27,7 @@ neg/t7622-cyclic-dependency neg/macro-incompatible-macro-engine-c.scala # Spurious failures +neg/inlineMaxSize.scala neg/patmatexhaust-huge.scala # Uses .java files diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/WhitelistedTests.txt index 4d385bfd0c..a2aa73a12a 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/WhitelistedTests.txt @@ -1041,7 +1041,6 @@ neg/t9127.scala neg/t9286c.scala neg/t9286a.scala neg/virtpatmat_exhaust_big.scala -neg/inlineMaxSize.scala run/t7249.scala run/t3563.scala From b95a89d8e626103f33174040ec8e2945aede20f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 23 Mar 2018 10:40:38 +0100 Subject: [PATCH 0648/2665] Increase global timeouts in the CI script. * 35m -> 45m for individual sbt invocations * 3h -> 4h for the entire job There have been two many spurious timeouts on the master branch recently. --- Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 315d4c5e83..4933f2e212 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -72,7 +72,7 @@ setJavaVersion() { # Define sbtretry sbtretry() { - local TIMEOUT=35m + local TIMEOUT=45m echo "RUNNING timeout -k 5 $TIMEOUT sbt" "$@" timeout -k 5 $TIMEOUT sbt $SBT_OPTS "$@" local CODE=$? @@ -458,7 +458,7 @@ matrix.each { taskDef -> sh "git clean -fdx && rm -rf partest/fetchedSources/" writeFile file: 'ciscript.sh', text: ciScript, encoding: 'UTF-8' retry(2) { - timeout(time: 3, unit: 'HOURS') { + timeout(time: 4, unit: 'HOURS') { sh "echo '$fullTaskName' && cat ciscript.sh && sh ciscript.sh" } } From 6bc346c9f59580440234bad6f8692d3c61479cea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 6 Feb 2018 18:20:46 +0100 Subject: [PATCH 0649/2665] Allow the test suite to run on unknown JS environments. This is useful when locally testing with an external JS environment which we temporarily source in the build. --- project/Build.scala | 8 ++++++-- .../main/scala/org/scalajs/testsuite/utils/Platform.scala | 1 + .../org/scalajs/testsuite/javalib/lang/SystemJSTest.scala | 8 +++++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index e9275ed019..6c311844f6 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1347,6 +1347,8 @@ object Build { Seq( testOptionTags := { + val s = streams.value + def envTagsFor(env: JSEnv): Seq[String] = env match { case env: NodeJSEnv => val tags1 = Seq("nodejs") @@ -1371,9 +1373,11 @@ object Build { } case _ => - throw new AssertionError( + s.log.warn( s"Unknown JSEnv of class ${env.getClass.getName}: " + - "don't know what tags to specify for the test suite") + "don't know what tags to specify for the test suite, " + + "so I will assume that TypedArrays are supported") + Seq("unknown-jsenv", "typedarray") } val envTags = envTagsFor((jsEnv in Test).value) diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala index 3c32a5308d..ac637295ed 100644 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala +++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala @@ -35,6 +35,7 @@ object Platform { def executingInNodeJS: Boolean = sysProp("nodejs") def executingInBrowser: Boolean = sysProp("browser") + def executingInUnknownJSEnv: Boolean = sysProp("unknown-jsenv") def typedArrays: Boolean = sysProp("typedarray") def sourceMaps: Boolean = sysProp("source-maps") diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala index b5cb513834..1832ca6bf9 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala @@ -105,17 +105,19 @@ class SystemJSTest { val inBrowser = get("scalajs.browser") == "true" val inNode = get("scalajs.nodejs") == "true" + val inUnknownJSEnv = get("scalajs.unknown-jsenv") == "true" if (inBrowser) { assertNotEquals("undefined", js.typeOf(js.Dynamic.global.window)) - assertFalse(inNode) + assertFalse(inNode || inUnknownJSEnv) } else if (inNode) { assertNotEquals("undefined", js.typeOf(js.Dynamic.global.process)) - assertFalse(inBrowser) - } else { + assertFalse(inBrowser || inUnknownJSEnv) + } else if (!inUnknownJSEnv) { fail("No known platform tag found.") } assertEquals(inBrowser, Platform.executingInBrowser) assertEquals(inNode, Platform.executingInNodeJS) + assertEquals(inUnknownJSEnv, Platform.executingInUnknownJSEnv) val typedArrays = get("scalajs.typedarray") == "true" assertEquals(typedArrays, Platform.typedArrays) From 2f81493cb78a56e2880188986fab1bae2c935c13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 7 Feb 2018 13:34:32 +0100 Subject: [PATCH 0650/2665] Remove tests asserting that we cannot create a regex with named groups. Named groups are supported in ECMAScript 2018, which means that creating such regexes will not fail on modern JS VMs. --- .../testsuite/javalib/util/regex/RegexMatcherTest.scala | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexMatcherTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexMatcherTest.scala index 37cbc4cb34..6a0bcbb221 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexMatcherTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexMatcherTest.scala @@ -404,10 +404,5 @@ class RegexMatcherTest { if (!executingInJVM) assertThrows(classOf[Exception], ms group "Ape") assertFalse(ms.hasNext) - - if (!executingInJVM) { - assertThrows(classOf[Exception], new Regex("a(?b*)c")) - assertThrows(classOf[Exception], Pattern.compile("a(?b*)c")) - } } } From 834cc5f23b18eb4841a4008cc55c9bb55bad2630 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 7 Feb 2018 13:40:35 +0100 Subject: [PATCH 0651/2665] Do not test undefined behavior of `Math.floor{Div,Mod}`. Those methods only throw `ArithmeticException`s if the underlying `Long./` throws, but that is undefined behavior, so we should not test for it. Not that the tests of the overloads for `Int`s already omitted similar tests. --- .../org/scalajs/testsuite/javalib/lang/MathTestOnJDK8.scala | 5 ----- 1 file changed, 5 deletions(-) diff --git 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 index 3d0e35676e..8640862cef 100644 --- 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 @@ -252,8 +252,6 @@ class MathTestOnJDK8 { assertEquals(-Long.MaxValue, Math.floorDiv(Long.MaxValue, -1)) assertEquals(Long.MinValue, Math.floorDiv(Long.MinValue, 1)) assertEquals(Long.MinValue, Math.floorDiv(Long.MinValue, -1)) - for (n <- Seq(0L, 1L, -1L, Long.MaxValue, Long.MinValue)) - expectThrows(classOf[ArithmeticException], Math.floorDiv(n, 0)) } @Test def floorMod(): Unit = { @@ -290,9 +288,6 @@ class MathTestOnJDK8 { assertEquals(0L, Math.floorMod(Long.MaxValue, -1L)) assertEquals(0L, Math.floorMod(Long.MinValue, 1L)) assertEquals(0L, Math.floorMod(Long.MinValue, -1L)) - - for (n <- Seq(0L, 1L, -1L, Long.MaxValue, Long.MinValue)) - assertThrows(classOf[ArithmeticException], Math.floorMod(n, 0)) } @Test def nextDown_for_Double(): Unit = { From 1bd2591acb50ab1164429fa98c30e452c166229d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 7 Feb 2018 14:11:09 +0100 Subject: [PATCH 0652/2665] Do not test that `RuntimeLong` divisions by 0 throw. That is basically undefined behavior, so it should not be tested. --- .../testsuite/jsinterop/RuntimeLongTest.scala | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/RuntimeLongTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/RuntimeLongTest.scala index cab9c2e02f..7796b515d1 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/RuntimeLongTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/RuntimeLongTest.scala @@ -1233,12 +1233,6 @@ class RuntimeLongTest { } @Test def divide_/(): Unit = { - expectThrows(classOf[ArithmeticException], lg(0) / lg(0)) - expectThrows(classOf[ArithmeticException], lg(5, 0) / lg(0)) - expectThrows(classOf[ArithmeticException], lg(0, 5) / lg(0)) - expectThrows(classOf[ArithmeticException], lg(-1) / lg(0)) - expectThrows(classOf[ArithmeticException], lg(-1, 0) / lg(0)) - assertEquals(IntMaxValPlus1, IntMinVal / lg(-1)) assertEquals(lg(-1), IntMinVal / IntMaxValPlus1) assertEquals(IntMinVal, IntMaxValPlus1 / lg(-1)) @@ -1598,12 +1592,6 @@ class RuntimeLongTest { } @Test def modulo_%(): Unit = { - expectThrows(classOf[ArithmeticException], lg(0) % lg(0)) - expectThrows(classOf[ArithmeticException], lg(5, 0) % lg(0)) - expectThrows(classOf[ArithmeticException], lg(0, 5) % lg(0)) - expectThrows(classOf[ArithmeticException], lg(-1) % lg(0)) - expectThrows(classOf[ArithmeticException], lg(-1, 0) % lg(0)) - assertEquals(lg(0), IntMinVal % lg(-1)) assertEquals(lg(0), IntMinVal % IntMaxValPlus1) assertEquals(lg(0), IntMaxValPlus1 % lg(-1)) From 48f716c5f6540a384208572f5e96aa6d0929538b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 7 Feb 2018 16:43:13 +0100 Subject: [PATCH 0653/2665] Convert all the RuntimeLong tests to Long tests. `RuntimeLong` is not really part of our public specification, so it does not make much sense to directly test it. In the future, its IR should even be a resource of the linker, in which case the tests would not even compile because `RuntimeLong` would not accessible. Moreover, testing `RuntimeLong` is not sufficient to test alternative implementations of `Long`s, nor to test all the crazy stuff that the optimizer does with `Long`s anyway. In order to prevent the compiler and/or the optimizer to simply constant-fold everything away, all the operations are hidden behind `test` methods that selectively "show" and "hide" constants from the optimizer. Overall, the changes in this commit improve the coverage, since they expose more conditions to the optimizer. --- .../testsuite/jsinterop/RuntimeLongTest.scala | 2078 -------------- .../scalajs/testsuite/compiler/LongTest.scala | 2537 +++++++++++++++-- 2 files changed, 2367 insertions(+), 2248 deletions(-) delete mode 100644 test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/RuntimeLongTest.scala diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/RuntimeLongTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/RuntimeLongTest.scala deleted file mode 100644 index 7796b515d1..0000000000 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/RuntimeLongTest.scala +++ /dev/null @@ -1,2078 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ -package org.scalajs.testsuite.jsinterop - -import scala.language.implicitConversions - -import scala.scalajs.runtime.RuntimeLong - -import org.junit.Assert._ -import org.junit.Assume._ -import org.junit.Test - -import org.scalajs.testsuite.utils.AssertThrows._ -import org.scalajs.testsuite.utils.Platform._ - -import scala.util.Try - -/** - * test the runtime Long implementation directly - * does not depend on magic compiler Long rewriting - */ -class RuntimeLongTest { - - // Short builders - def lg(lo: Int, hi: Int): RuntimeLong = new RuntimeLong(lo, hi) - def lg(i: Int): RuntimeLong = RuntimeLong.fromInt(i) - - // Common values - val MaxVal = lg(0xffffffff, 0x7fffffff) - val MinVal = lg(0, 0x80000000) - val IntMaxVal = lg(Int.MaxValue) - val IntMinVal = lg(Int.MinValue) - val IntMaxValPlus1 = lg(0x80000000, 0) - val IntMinValMinus1 = lg(2147483647, -1) - val MaxSafeDouble = lg(-1, 2097151) - val TwoPow53 = lg(0, 2097152) - val MinSafeDouble = lg(1, -2097152) - val NegTwoPow53 = lg(0, -2097152) - - // scala.scalajs.runtime.RuntimeLong - - @Test def sanity_of_equality_tests(): Unit = { - assertEquals(123L + (456L << 32), lg(123, 456).toLong) - assertEquals(lg(123, 456), lg(123, 456)) - assertEquals(lg(456, 123), lg(456, 123)) - - assertNotEquals(123L + (4L << 32), lg(123, 456).toLong) - assertNotEquals(lg(123, 4), lg(123, 456)) - assertNotEquals(1L + (456L << 32), lg(123, 456).toLong) - assertNotEquals(lg(1, 456), lg(123, 456)) - assertNotEquals(123L, lg(123, 456).toLong) - } - - @Test def equals_Any(): Unit = { - assertFalse(lg(0, 0).equals(0: Any)) - assertFalse(lg(0, 0).equals(null: Any)) - - assertTrue(lg(0, 0).equals(lg(0, 0): Any)) - assertTrue(lg(123, 456).equals(lg(123, 456): Any)) - assertTrue(lg(-123, 456).equals(lg(-123, 456): Any)) - assertTrue(lg(-123, -456).equals(lg(-123, -456): Any)) - - assertFalse(lg(123, 456).equals(lg(-123, 456): Any)) - assertFalse(lg(123, 456).equals(lg(123, -456): Any)) - assertFalse(lg(-123, -456).equals(lg(123, -456): Any)) - assertFalse(lg(-123, -456).equals(lg(-123, 456): Any)) - } - - @Test def hashCode_as_specified_in_j_l_toFloat_strict(): Unit = { - assertEquals(0, lg(0).hashCode()) - assertEquals(0, lg(-1).hashCode()) - assertEquals(55, lg(55).hashCode()) - assertEquals(11, lg(-12).hashCode()) - assertEquals(10006548, lg(10006548).hashCode()) - assertEquals(1098747, lg(-1098748).hashCode()) - - assertEquals(957662195, lg(579906195, 461662560).hashCode()) - assertEquals(-1075860794, lg(-1403218312, 327367870).hashCode()) - assertEquals(1425294575, lg(-1152051636, -274640221).hashCode()) - assertEquals(-1863811248, lg(1026519507, -1379463549).hashCode()) - assertEquals(-881942797, lg(363765329, -557842270).hashCode()) - assertEquals(548587254, lg(21652572, 569942698).hashCode()) - assertEquals(-1328999812, lg(55820229, -1281708615).hashCode()) - assertEquals(-1756412154, lg(-1843678104, 89453422).hashCode()) - assertEquals(-529144798, lg(-1928579430, 1836700344).hashCode()) - assertEquals(-1163319584, lg(-181377900, 1335444084).hashCode()) - assertEquals(2070477069, lg(1189983760, 1032146717).hashCode()) - assertEquals(-1718642695, lg(-1982789145, 274636318).hashCode()) - assertEquals(260982265, lg(-2087901827, -1945935740).hashCode()) - assertEquals(-385578983, lg(-1911332808, 1729620001).hashCode()) - assertEquals(-1362397169, lg(-1920965295, 592125278).hashCode()) - assertEquals(1419211160, lg(2017870028, 751907156).hashCode()) - assertEquals(-1851816270, lg(1506336851, -933796127).hashCode()) - assertEquals(112959880, lg(-1747722429, -1855422773).hashCode()) - assertEquals(1715333902, lg(-2139132623, -431847873).hashCode()) - assertEquals(-453690224, lg(739274932, -924496860).hashCode()) - assertEquals(-1503679197, lg(-1482800071, 29485338).hashCode()) - assertEquals(1950154296, lg(237609240, 2048220960).hashCode()) - assertEquals(2037562473, lg(-431092385, -1623412426).hashCode()) - assertEquals(220707473, lg(2144172772, 1927987317).hashCode()) - assertEquals(1902658020, lg(971459211, 1217334127).hashCode()) - assertEquals(840583449, lg(-530209544, -763367967).hashCode()) - assertEquals(2065572837, lg(-1322671605, -902331922).hashCode()) - assertEquals(407536450, lg(1361976000, 1231329666).hashCode()) - assertEquals(-1678479110, lg(-96547475, 1640676759).hashCode()) - assertEquals(-1558558486, lg(1799144078, -936998300).hashCode()) - assertEquals(-110470482, lg(221720683, -195204411).hashCode()) - assertEquals(992932874, lg(2080474705, 1194291803).hashCode()) - assertEquals(2035378556, lg(-1962255291, -228903623).hashCode()) - assertEquals(542449527, lg(-1961045404, -1421226733).hashCode()) - assertEquals(-1824846728, lg(1762001719, -96661681).hashCode()) - assertEquals(-985103709, lg(568630982, -458482587).hashCode()) - assertEquals(37361715, lg(-1237704639, -1275053966).hashCode()) - assertEquals(-1555729529, lg(936273516, -1802824213).hashCode()) - assertEquals(1534845437, lg(-870754516, -1755138351).hashCode()) - assertEquals(-715250396, lg(964079858, -332884522).hashCode()) - assertEquals(2003953821, lg(1769001167, 503396434).hashCode()) - assertEquals(1631287431, lg(811930233, 1365142270).hashCode()) - assertEquals(-1393125048, lg(-280291442, 1136496326).hashCode()) - assertEquals(926193137, lg(439731659, 755060794).hashCode()) - assertEquals(1141998463, lg(-561661919, -1701561506).hashCode()) - assertEquals(480895538, lg(1556104387, 1080665841).hashCode()) - assertEquals(-849143869, lg(1931061917, -1099252386).hashCode()) - assertEquals(-1840233445, lg(2086961898, -298531087).hashCode()) - assertEquals(47538111, lg(-1148008529, -1186490352).hashCode()) - assertEquals(540301593, lg(807317094, 271251327).hashCode()) - assertEquals(1903332829, lg(1077071399, 826295290).hashCode()) - assertEquals(-1325859168, lg(781949710, -1637653074).hashCode()) - assertEquals(-1476869146, lg(1778433204, -839352494).hashCode()) - assertEquals(84316181, lg(-2038023199, -2088719372).hashCode()) - assertEquals(524038724, lg(-1764916235, -1980649039).hashCode()) - assertEquals(-794988445, lg(-1796682086, 1148567289).hashCode()) - assertEquals(-1285356617, lg(-1606200144, 320886535).hashCode()) - assertEquals(1441713710, lg(755146140, 2028753842).hashCode()) - assertEquals(365800340, lg(-1851453861, -2073516593).hashCode()) - assertEquals(2130603708, lg(-543327214, -1587342674).hashCode()) - assertEquals(-1414171289, lg(506958308, -1249713021).hashCode()) - assertEquals(-262714124, lg(-2097389477, 1923820719).hashCode()) - assertEquals(158195454, lg(-374932306, -523558320).hashCode()) - assertEquals(50128093, lg(-902905695, -925752196).hashCode()) - assertEquals(-825145129, lg(-397013030, 646399757).hashCode()) - assertEquals(-1344834498, lg(1764398539, -956440075).hashCode()) - assertEquals(-103814738, lg(-1750710329, 1852419689).hashCode()) - assertEquals(-1354282241, lg(-1664538473, 864969320).hashCode()) - assertEquals(1408148925, lg(-500471847, -1312439708).hashCode()) - assertEquals(1910019874, lg(14748928, 1899600418).hashCode()) - assertEquals(1877620608, lg(-1985642880, -431011584).hashCode()) - assertEquals(-378358620, lg(494530531, -200582329).hashCode()) - assertEquals(492633155, lg(-2067225228, -1718331081).hashCode()) - assertEquals(-1581166836, lg(-1799546135, 897340901).hashCode()) - assertEquals(174532880, lg(25821759, 200092463).hashCode()) - assertEquals(-629188646, lg(403690141, -1032813241).hashCode()) - assertEquals(2139225425, lg(-1843541251, -308529236).hashCode()) - assertEquals(200043623, lg(1643311840, 1780391559).hashCode()) - assertEquals(1992690082, lg(1531597671, 764172997).hashCode()) - assertEquals(754072038, lg(638938496, 182932582).hashCode()) - assertEquals(-139359279, lg(309356043, -440275494).hashCode()) - assertEquals(-1669264515, lg(-541225182, 1128039519).hashCode()) - assertEquals(25583899, lg(-387355169, -378598204).hashCode()) - assertEquals(1822592670, lg(1787244135, 103129337).hashCode()) - assertEquals(1468680630, lg(-1654639624, -890602930).hashCode()) - assertEquals(2103231504, lg(-1867306675, -303043235).hashCode()) - assertEquals(1159389820, lg(1255224728, 265017316).hashCode()) - assertEquals(776506096, lg(119985367, 695098919).hashCode()) - assertEquals(-1303579924, lg(-332671386, 1583817866).hashCode()) - assertEquals(1108767081, lg(1610629865, 571880320).hashCode()) - assertEquals(-1101969936, lg(727577343, -1794328817).hashCode()) - assertEquals(-1022615009, lg(730759795, -394092436).hashCode()) - assertEquals(-1221218252, lg(-148400203, 1074931585).hashCode()) - assertEquals(410005178, lg(181091802, 314250080).hashCode()) - assertEquals(1180107886, lg(-1934827635, -889463837).hashCode()) - assertEquals(425308062, lg(-1067099255, -650316777).hashCode()) - assertEquals(1727927187, lg(1821917070, 174468125).hashCode()) - assertEquals(-759140792, lg(474121453, -830281051).hashCode()) - assertEquals(1698140938, lg(-402668999, -2100801229).hashCode()) - assertEquals(512144461, lg(-615008378, -976157749).hashCode()) - } - - @Test def toString()(): Unit = { - assertEquals("0", lg(0).toString()) - assertEquals("1", lg(1).toString()) - assertEquals("-1", lg(-1).toString()) - assertEquals(Int.MaxValue.toString(), IntMaxVal.toString()) - assertEquals("2147483648", IntMaxValPlus1.toString()) - assertEquals(Int.MinValue.toString(), IntMinVal.toString()) - assertEquals("-2147483649", IntMinValMinus1.toString()) - assertEquals("999999999", lg(999999999).toString()) - assertEquals("1000000000", lg(1000000000).toString()) - assertEquals("9007199254740991", MaxSafeDouble.toString()) - assertEquals("9007199254740992", TwoPow53.toString()) - assertEquals("-9007199254740991", MinSafeDouble.toString()) - assertEquals("-9007199254740992", NegTwoPow53.toString()) - - assertEquals("-86922", lg(-86922, -1).toString()) - assertEquals("0", lg(0, 0).toString()) - assertEquals("-21874015", lg(-21874015, -1).toString()) - assertEquals("-2098921896914", lg(1317110830, -489).toString()) - assertEquals("80985205273168", lg(-698060208, 18855).toString()) - assertEquals("-12451732102972849", lg(858389071, -2899145).toString()) - assertEquals("3350", lg(3350, 0).toString()) - assertEquals("-92511590195450", lg(2005360390, -21540).toString()) - assertEquals("-2", lg(-2, -1).toString()) - assertEquals("446248293253325286", lg(1492984294, 103900277).toString()) - assertEquals("499596119314678396", lg(116015740, 116321286).toString()) - assertEquals("-3205893", lg(-3205893, -1).toString()) - assertEquals("-88762100292970", lg(1988813462, -20667).toString()) - assertEquals("-1278004", lg(-1278004, -1).toString()) - assertEquals("-1", lg(-1, -1).toString()) - assertEquals("-305393", lg(-305393, -1).toString()) - assertEquals("-2", lg(-2, -1).toString()) - assertEquals("80295210784300943", lg(-1678336113, 18695185).toString()) - assertEquals("5", lg(5, 0).toString()) - assertEquals("21", lg(21, 0).toString()) - assertEquals("64", lg(64, 0).toString()) - assertEquals("39146094", lg(39146094, 0).toString()) - assertEquals("-1725731", lg(-1725731, -1).toString()) - assertEquals("-768047304243556260", lg(-874655652, -178824949).toString()) - assertEquals("-2726923242838", lg(380990122, -635).toString()) - assertEquals("-1781092907033", lg(1318520807, -415).toString()) - assertEquals("-213275", lg(-213275, -1).toString()) - assertEquals("7662405832810", lg(184176746, 1784).toString()) - assertEquals("-154157877107", lg(460945549, -36).toString()) - assertEquals("-929963900939521435", lg(1586508389, -216524094).toString()) - assertEquals("-6872", lg(-6872, -1).toString()) - assertEquals("31842553544728", lg(-333987816, 7413).toString()) - assertEquals("567569520305426", lg(-1817926382, 132147).toString()) - assertEquals("19649016", lg(19649016, 0).toString()) - assertEquals("-1349346", lg(-1349346, -1).toString()) - assertEquals("9479824673588660", lg(-1372338764, 2207193).toString()) - assertEquals("3521781", lg(3521781, 0).toString()) - assertEquals("1740", lg(1740, 0).toString()) - assertEquals("0", lg(0, 0).toString()) - assertEquals("92834698468", lg(-1654582044, 21).toString()) - assertEquals("-80139798970631138", lg(100400158, -18659001).toString()) - assertEquals("30058", lg(30058, 0).toString()) - assertEquals("-611022189550002", lg(1332815438, -142265).toString()) - assertEquals("514941281681226", lg(472694602, 119894).toString()) - assertEquals("2454759250363", lg(-1962042949, 571).toString()) - assertEquals("14860137468144958", lg(1595551038, 3459895).toString()) - assertEquals("-79255", lg(-79255, -1).toString()) - assertEquals("2290122305310796", lg(-1501556660, 533210).toString()) - assertEquals("-755641947927852310", lg(-463451414, -175936602).toString()) - assertEquals("-2621852156570472370", lg(-771329970, -610447526).toString()) - assertEquals("-37956135735", lg(698569929, -9).toString()) - assertEquals("853219", lg(853219, 0).toString()) - assertEquals("901", lg(901, 0).toString()) - assertEquals("4385596303898", lg(434694682, 1021).toString()) - assertEquals("-972597865", lg(-972597865, -1).toString()) - assertEquals("-8057379", lg(-8057379, -1).toString()) - assertEquals("-14968", lg(-14968, -1).toString()) - assertEquals("-98204964", lg(-98204964, -1).toString()) - assertEquals("335479", lg(335479, 0).toString()) - assertEquals("-429441918886", lg(54810714, -100).toString()) - assertEquals("9798741", lg(9798741, 0).toString()) - assertEquals("135908509698671494", lg(-896875642, 31643665).toString()) - assertEquals("-141095409221912371", lg(233027789, -32851335).toString()) - assertEquals("-9040837797787104", lg(-359183840, -2104985).toString()) - assertEquals("-889", lg(-889, -1).toString()) - assertEquals("3222082994", lg(-1072884302, 0).toString()) - assertEquals("-1454853", lg(-1454853, -1).toString()) - assertEquals("547641844425", lg(-2113969463, 127).toString()) - assertEquals("2528132853", lg(-1766834443, 0).toString()) - assertEquals("242", lg(242, 0).toString()) - assertEquals("-1655763891", lg(-1655763891, -1).toString()) - assertEquals("82", lg(82, 0).toString()) - assertEquals("-120254181", lg(-120254181, -1).toString()) - assertEquals("-210088", lg(-210088, -1).toString()) - assertEquals("-2", lg(-2, -1).toString()) - assertEquals("250255458324299", lg(598888267, 58267).toString()) - assertEquals("-100656997", lg(-100656997, -1).toString()) - assertEquals("-24097181761", lg(1672622015, -6).toString()) - assertEquals("206088", lg(206088, 0).toString()) - assertEquals("-593", lg(-593, -1).toString()) - assertEquals("-99542049", lg(-99542049, -1).toString()) - assertEquals("421501", lg(421501, 0).toString()) - assertEquals("-2", lg(-2, -1).toString()) - assertEquals("-101", lg(-101, -1).toString()) - assertEquals("3", lg(3, 0).toString()) - assertEquals("14967492854", lg(2082590966, 3).toString()) - assertEquals("-1528445803513883", lg(-86853659, -355870).toString()) - assertEquals("26760588095306", lg(-1353126070, 6230).toString()) - assertEquals("12452686330472", lg(1576139368, 2899).toString()) - assertEquals("-130630407827875", lg(1022479965, -30415).toString()) - assertEquals("-10281777615", lg(-1691843023, -3).toString()) - assertEquals("-90497242609445", lg(2013284571, -21071).toString()) - assertEquals("-13935178716929", lg(1990158591, -3245).toString()) - assertEquals("-11308540", lg(-11308540, -1).toString()) - assertEquals("545166", lg(545166, 0).toString()) - assertEquals("-1043705339124703", lg(1778574369, -243007).toString()) - assertEquals("510", lg(510, 0).toString()) - assertEquals("-2485453027", lg(1809514269, -1).toString()) - assertEquals("-15103", lg(-15103, -1).toString()) - assertEquals("-168776672025670194", lg(-779514418, -39296382).toString()) - } - - @Test def toByte(): Unit = { - assertEquals(0, lg(0).toByte) - assertEquals(-1, lg(-1).toByte) - assertEquals(0x98.toByte, lg(0xfedcba98, 0x76543210).toByte) - - assertEquals(102, lg(-1755353242, -1245269156).toByte) - assertEquals(77, lg(-359135667, 1391746928).toByte) - assertEquals(-47, lg(-957203503, 1516742479).toByte) - assertEquals(-22, lg(-1928741654, 1162703256).toByte) - assertEquals(-113, lg(-1698228849, 1497186951).toByte) - assertEquals(-84, lg(-68041812, -2115448390).toByte) - assertEquals(33, lg(1534301729, 1468418695).toByte) - assertEquals(113, lg(1101829489, -514588123).toByte) - assertEquals(12, lg(-1437577204, 1896338488).toByte) - assertEquals(86, lg(-857671082, -1304076936).toByte) - assertEquals(-36, lg(-292818212, -1485650549).toByte) - assertEquals(88, lg(1044510040, 147719255).toByte) - assertEquals(107, lg(-1166136469, 78076997).toByte) - assertEquals(61, lg(500131901, 248541787).toByte) - assertEquals(99, lg(1863435363, -1465266670).toByte) - assertEquals(-76, lg(136483252, 1662447178).toByte) - assertEquals(0, lg(1787939584, 1303926235).toByte) - assertEquals(-69, lg(2105657787, 845433223).toByte) - assertEquals(26, lg(-1298285542, -1826340261).toByte) - assertEquals(64, lg(-766959552, -326327606).toByte) - } - - @Test def toShort(): Unit = { - assertEquals(0, lg(0).toShort) - assertEquals(-1, lg(-1).toShort) - assertEquals(0xba98.toShort, lg(0xfedcba98, 0x76543210).toShort) - - assertEquals(-670, lg(1925512546, -812328457).toShort) - assertEquals(-15861, lg(2028716555, -1639243756).toShort) - assertEquals(9963, lg(-1970657557, -1904990267).toShort) - assertEquals(18394, lg(-1012119590, -1704668195).toShort) - assertEquals(-7956, lg(848486636, -810351120).toShort) - assertEquals(21453, lg(2103989197, 955793808).toShort) - assertEquals(22979, lg(-237938237, -703399620).toShort) - assertEquals(8452, lg(666247428, -1109641927).toShort) - assertEquals(-26563, lg(1824561213, -872828437).toShort) - assertEquals(-5754, lg(-10950266, -1779965318).toShort) - assertEquals(11796, lg(1251814932, -491043391).toShort) - assertEquals(18020, lg(-117750172, -366379322).toShort) - assertEquals(3768, lg(-2095575368, 965048164).toShort) - assertEquals(-4579, lg(-177410531, 1454361289).toShort) - assertEquals(-29102, lg(-359035310, -790126871).toShort) - assertEquals(30020, lg(1486058820, 1675509542).toShort) - assertEquals(-13051, lg(268881157, -342358099).toShort) - assertEquals(-2720, lg(-1089211040, 747294820).toShort) - assertEquals(4726, lg(1163661942, 1708185440).toShort) - assertEquals(-16878, lg(-1363821038, -1952481751).toShort) - } - - @Test def toInt(): Unit = { - assertEquals(0, lg(0).toInt) - assertEquals(-1, lg(-1).toInt) - assertEquals(0xfedcba98, lg(0xfedcba98, 0x76543210).toInt) - - assertEquals(-1869423218, lg(-1869423218, -5516698).toInt) - assertEquals(450655357, lg(450655357, -521592408).toInt) - assertEquals(-596464514, lg(-596464514, 629510497).toInt) - assertEquals(1668957409, lg(1668957409, 1231040344).toInt) - assertEquals(-313016061, lg(-313016061, 283507721).toInt) - assertEquals(-406779255, lg(-406779255, 1389322213).toInt) - assertEquals(-1125423893, lg(-1125423893, -436921025).toInt) - assertEquals(1491309031, lg(1491309031, 948401259).toInt) - assertEquals(360542935, lg(360542935, -1033853853).toInt) - assertEquals(178673916, lg(178673916, -2045867551).toInt) - assertEquals(-1167644863, lg(-1167644863, 738699232).toInt) - assertEquals(-1852739075, lg(-1852739075, 950841298).toInt) - assertEquals(-1965326912, lg(-1965326912, 1694989583).toInt) - assertEquals(-141857741, lg(-141857741, -1197558189).toInt) - assertEquals(-938893686, lg(-938893686, 1763555645).toInt) - assertEquals(-1178638558, lg(-1178638558, 299067184).toInt) - assertEquals(-1296424902, lg(-1296424902, -1694453755).toInt) - assertEquals(204387309, lg(204387309, -240738711).toInt) - assertEquals(-942136876, lg(-942136876, -527367452).toInt) - assertEquals(-1703892744, lg(-1703892744, 240186844).toInt) - } - - @Test def toLong(): Unit = { - assertEquals(0L, lg(0).toLong) - assertEquals(-1L, lg(-1).toLong) - assertEquals(0x76543210fedcba98L, lg(0xfedcba98, 0x76543210).toLong) - - assertEquals(6907420169189163269L, lg(-85753595, 1608259083).toLong) - assertEquals(-6558938415102325809L, lg(539593679, -1527121853).toLong) - assertEquals(-7633462319206780754L, lg(-379998034, -1777303946).toLong) - assertEquals(-4051533910437546682L, lg(-655641274, -943321249).toLong) - assertEquals(-3890339056676572253L, lg(1727460259, -905790147).toLong) - assertEquals(-3091543614186826784L, lg(1824805856, -719806090).toLong) - assertEquals(2806266116723834799L, lg(948567983, 653384746).toLong) - assertEquals(-1741184441450532748L, lg(-957910924, -405401095).toLong) - assertEquals(3395924718030703835L, lg(-433042213, 790675337).toLong) - assertEquals(-7712245542997911283L, lg(889526541, -1795647094).toLong) - assertEquals(-2751064647855401745L, lg(1316066543, -640532153).toLong) - assertEquals(5225909624054208018L, lg(1913378322, 1216751901).toLong) - assertEquals(1334025594846136121L, lg(-434813127, 310602037).toLong) - assertEquals(-1574909139329823322L, lg(1689963942, -366687109).toLong) - assertEquals(-9142211941778525044L, lg(754250892, -2128587091).toLong) - assertEquals(-5517402195275269807L, lg(-1817691823, -1284620305).toLong) - assertEquals(7612683537409046411L, lg(-222627957, 1772466007).toLong) - assertEquals(-2955859733488660001L, lg(-1282993697, -688214725).toLong) - assertEquals(462084382441397543L, lg(799857959, 107587404).toLong) - assertEquals(8801656334077465992L, lg(2076251528, 2049295309).toLong) - } - - @Test def toFloat_strict(): Unit = { - assumeTrue("Assumed strict floats", hasStrictFloats) - assertEquals(0, lg(0).toFloat, 0.0) - assertEquals(-1, lg(-1).toFloat, 0.0) - - // Closure seems to incorrectly rewrite the constant on the right :-( - val epsilon = if (isInFullOpt) 1E4f else 0.0f - assertEquals(9.223372E18f, MaxVal.toFloat, epsilon) - assertEquals(-9.223372E18f, MinVal.toFloat, epsilon) - - assertEquals(4.7971489E18f, lg(-1026388143, 1116923232).toFloat, 0.0) - assertEquals(-2.24047663E18f, lg(-1288678667, -521651607).toFloat, 0.0) - assertEquals(4.59211416E18f, lg(1192262605, 1069184891).toFloat, 0.0) - assertEquals(3.38942079E18f, lg(-180353617, 789161022).toFloat, 0.0) - assertEquals(-6.8076878E18f, lg(-1158443188, -1585038363).toFloat, 0.0) - assertEquals(7.4159717E18f, lg(906981906, 1726665521).toFloat, 0.0) - assertEquals(-1.85275997E18f, lg(2042933575, -431379283).toFloat, 0.0) - assertEquals(5.7344188E18f, lg(599900903, 1335148382).toFloat, 0.0) - assertEquals(3.20410168E18f, lg(1458166084, 746013039).toFloat, 0.0) - assertEquals(-7.2310311E18f, lg(1956524672, -1683605603).toFloat, 0.0) - assertEquals(7.7151362E18f, lg(478583639, 1796320118).toFloat, 0.0) - assertEquals(1.41365268E18f, lg(-1645816617, 329141676).toFloat, 0.0) - assertEquals(-3.03197918E18f, lg(184187116, -705937657).toFloat, 0.0) - assertEquals(-4.04287594E18f, lg(659513335, -941305424).toFloat, 0.0) - assertEquals(-7.8204678E18f, lg(770505156, -1820844549).toFloat, 0.0) - assertEquals(-5.9733025E18f, lg(929928858, -1390767911).toFloat, 0.0) - assertEquals(1.1261721E18f, lg(-1475096259, 262207373).toFloat, 0.0) - assertEquals(4.00884963E18f, lg(787691795, 933383012).toFloat, 0.0) - assertEquals(-1.43511611E18f, lg(1189057493, -334139018).toFloat, 0.0) - assertEquals(3.81415059E18f, lg(-618946450, 888051141).toFloat, 0.0) - } - - @Test def toDouble(): Unit = { - assertEquals(0, lg(0).toDouble, 0.0) - assertEquals(-1, lg(-1).toDouble, 0.0) - - // Closure seems to incorrectly rewrite the constant on the right :-( - val epsilon = if (isInFullOpt) 1E4 else 0.0 - assertEquals(9.223372036854776E18, MaxVal.toDouble, epsilon) - assertEquals(-9.223372036854776E18, MinVal.toDouble, epsilon) - - assertEquals(3.4240179834317537E18, lg(-151011088, 797216310).toDouble, 0.0) - assertEquals(8.5596043411285968E16, lg(-508205099, 19929381).toDouble, 0.0) - assertEquals(-3.1630346897289943E18, lg(1249322201, -736451403).toDouble, 0.0) - assertEquals(-4.4847682439933604E18, lg(483575860, -1044191477).toDouble, 0.0) - assertEquals(-6.4014772289576371E17, lg(-1526343930, -149046007).toDouble, 0.0) - assertEquals(-1.76968119148756736E18, lg(531728928, -412036011).toDouble, 0.0) - assertEquals(-8.5606671350959739E18, lg(-734111585, -1993185640).toDouble, 0.0) - assertEquals(-9.0403963253949932E18, lg(-1407864332, -2104881296).toDouble, 0.0) - assertEquals(-6.4988752582247977E18, lg(-1712351423, -1513137310).toDouble, 0.0) - assertEquals(-7.7788492399114394E17, lg(1969244733, -181115448).toDouble, 0.0) - assertEquals(7.6357174849871442E18, lg(-907683842, 1777829016).toDouble, 0.0) - assertEquals(1.25338659134517658E18, lg(-815927209, 291826806).toDouble, 0.0) - assertEquals(-3.1910241505692349E18, lg(463523496, -742968207).toDouble, 0.0) - assertEquals(7.4216510087652332E18, lg(1482622807, 1727987781).toDouble, 0.0) - assertEquals(-8.189046896086654E18, lg(1170040143, -1906661060).toDouble, 0.0) - assertEquals(6.8316272807487539E18, lg(-85609173, 1590612176).toDouble, 0.0) - assertEquals(-8.0611115909320561E18, lg(-1212811257, -1876873801).toDouble, 0.0) - assertEquals(1.7127521901359959E18, lg(-648802816, 398781194).toDouble, 0.0) - assertEquals(-6.4442523492577423E18, lg(-1484519186, -1500419423).toDouble, 0.0) - assertEquals(-1.71264450938175027E18, lg(-2016996893, -398756124).toDouble, 0.0) - } - - @Test def fromDouble(): Unit = { - import RuntimeLong.{fromDouble => fromD} - - val twoPow63 = 9.223372036854776E18 - val twoPow63NextUp = 9.223372036854778E18 - val twoPow63NextDown = 9.2233720368547748E18 - - // Specials - assertEquals(lg(0), fromD(0.0)) - assertEquals(lg(0), fromD(-0.0)) - assertEquals(lg(0), fromD(Double.NaN)) - assertEquals(MaxVal, fromD(Double.PositiveInfinity)) - assertEquals(MinVal, fromD(Double.NegativeInfinity)) - - // Corner cases - assertEquals(lg(0), fromD(Double.MinPositiveValue)) - assertEquals(lg(0), fromD(-Double.MinPositiveValue)) - assertEquals(MaxVal, fromD(twoPow63)) - assertEquals(MaxVal, fromD(twoPow63NextUp)) - if (!isInFullOpt) { - // GCC incorrectly rewrites the Double constants on the rhs - assertEquals(lg(-1024, 2147483647), fromD(twoPow63NextDown)) - assertEquals(MinVal, fromD(-twoPow63)) - } - assertEquals(MinVal, fromD(-twoPow63NextUp)) - assertEquals(lg(1024, -2147483648), fromD(-twoPow63NextDown)) - - // Absolute value too big - assertEquals(MaxVal, fromD(1.5623101234432471E19)) - assertEquals(MaxVal, fromD(1.0425697303244048E19)) - assertEquals(MaxVal, fromD(1.500625248806836E19)) - assertEquals(MinVal, fromD(-1.5623101234432471E19)) - assertEquals(MinVal, fromD(-1.0425697303244048E19)) - assertEquals(MinVal, fromD(-1.500625248806836E19)) - - // Normal cases - assertEquals(lg(-235867169, -1408375), fromD(-6.048920506403873E15)) - assertEquals(lg(-69250108, 1979931), fromD(8.503743119053764E15)) - assertEquals(lg(-305079043, 917242), fromD(3.939528382405885E15)) - assertEquals(lg(687182505, -933310), fromD(-4.008535239847255E15)) - assertEquals(lg(-268193171, -177333), fromD(-7.61635408727443E14)) - assertEquals(lg(-1529111384, 564485), fromD(2.424447379938472E15)) - assertEquals(lg(1128309745, -1082296), fromD(-4.648424796281871E15)) - assertEquals(lg(-418524847, 1986827), fromD(8.533360864252241E15)) - assertEquals(lg(615477490, -646039), fromD(-2.774715761463054E15)) - assertEquals(lg(-1546293262, 815087), fromD(3.500774757068786E15)) - assertEquals(lg(455797153, -1037726), fromD(-4.456998776411743E15)) - assertEquals(lg(587409995, 1185272), fromD(5.090705064274507E15)) - assertEquals(lg(-1405692887, -769407), fromD(-3.304575013039063E15)) - assertEquals(lg(667130924, 412), fromD(1.770193656876E12)) - assertEquals(lg(632602096, -506779), fromD(-2.176598598697488E15)) - assertEquals(lg(1820137888, 955044), fromD(4.101884566378912E15)) - assertEquals(lg(682339811, 951155), fromD(4.085180300766691E15)) - assertEquals(lg(1394139649, -1084392), fromD(-4.657426781904383E15)) - assertEquals(lg(-677499131, 663585), fromD(2.850079490584325E15)) - assertEquals(lg(805667746, 1417318), fromD(6.087335263699874E15)) - assertEquals(lg(990918920, -1563103), fromD(-6.713475274360568E15)) - assertEquals(lg(-1427573595, 969167), fromD(4.162543436756133E15)) - assertEquals(lg(-699306484, -1852353), fromD(-7.955791959986676E15)) - assertEquals(lg(-1807820942, 1218020), fromD(5.231358553020274E15)) - assertEquals(lg(1243383338, 349241), fromD(1.499979916805674E15)) - assertEquals(lg(-479557118, 1183372), fromD(5.08254785441229E15)) - assertEquals(lg(1413560577, 654135), fromD(2.809489845729537E15)) - assertEquals(lg(-2047369879, 1135596), fromD(4.877349929065833E15)) - assertEquals(lg(-741161617, -1594192), fromD(-6.846998949739153E15)) - assertEquals(lg(-2115502919, 1443312), fromD(6.198980017388729E15)) - assertEquals(lg(1015092168, 1152178), fromD(4.948567844262856E15)) - assertEquals(lg(-1340352375, -863152), fromD(-3.707206656862071E15)) - assertEquals(lg(1990353383, -2017544), fromD(-8.665283507887641E15)) - assertEquals(lg(-1683508387, -666397), fromD(-2.862150709693603E15)) - assertEquals(lg(2095665836, 369587), fromD(1.587366173692588E15)) - assertEquals(lg(229204175, 77510), fromD(3.32903144317135E14)) - assertEquals(lg(-1988104885, 1374301), fromD(5.902580156722507E15)) - assertEquals(lg(-1032158224, -233238), fromD(-1.001746319375376E15)) - assertEquals(lg(1321723055, -121058), fromD(-5.19938829196113E14)) - assertEquals(lg(-1959869514, -1892991), fromD(-8.130332101524554E15)) - assertEquals(lg(-1173650161, -412038), fromD(-1.769686613392113E15)) - assertEquals(lg(-1692936735, -1697943), fromD(-7.292607053441567E15)) - assertEquals(lg(-1368921565, 621023), fromD(2.667276401109539E15)) - } - - @Test def comparisons(): Unit = { - def test(x: RuntimeLong, y: RuntimeLong, expected: Int): Unit = { - assertEquals(expected, x.compareTo(y).signum) - assertEquals(expected, x.compareTo(y.toLong: java.lang.Long).signum) - assertEquals(expected == 0, x.equals(y)) - assertEquals(expected != 0, x.notEquals(y)) - assertEquals(expected < 0, x < y) - assertEquals(expected <= 0, x <= y) - assertEquals(expected > 0, x > y) - assertEquals(expected >= 0, x >= y) - } - - test(lg(0), lg(0), 0) - test(lg(0), lg(1), -1) - test(lg(0), lg(-1), 1) - test(MaxVal, MinVal, 1) - test(MinVal, MaxVal, -1) - - // Positive and negative numbers requiring lo to be compared via unsigned - test(lg(0x87654321, 0x654789ab), lg(0x12345678, 0x654789ab), 1) - test(lg(0x87654321, 0x89abcdef), lg(0x12345678, 0x89abcdef), 1) - - // Whitebox corner cases - test(lg(-1, 0), lg(0, 0), 1) - test(lg(0, 0), lg(-1, 0), -1) - - test(lg(173547161, -1884162399), lg(173547161, -1884162399), 0) - test(lg(-1131022787, -472928681), lg(-1131022787, -472928681), 0) - test(lg(-1426164191, 1230100202), lg(-1426164191, 1230100202), 0) - test(lg(-865774626, 1656835920), lg(-865774626, 1656835920), 0) - test(lg(323675568, -725625271), lg(323675568, -725625271), 0) - test(lg(-480943595, -1454872354), lg(-480943595, -1454872354), 0) - test(lg(-626788852, 1037229194), lg(-626788852, 1037229194), 0) - test(lg(-717389653, 232764759), lg(-717389653, 232764759), 0) - test(lg(-861190423, -1233377930), lg(-861190423, -1233377930), 0) - test(lg(-424759090, 2081288998), lg(-424759090, 2081288998), 0) - - test(lg(-1092215366, 753517982), lg(349136582, -103427916), 1) - test(lg(363609757, -1151024787), lg(472951646, -1802702403), 1) - test(lg(604332601, 1869576376), lg(1642523661, 1083165388), 1) - test(lg(309732766, 1349689861), lg(1287300335, 1464464808), -1) - test(lg(-1309668929, -965374553), lg(-1952664258, 53355972), -1) - test(lg(1881957750, 388099413), lg(1843907319, -1819358211), 1) - test(lg(-969542710, 864289013), lg(-1025874755, 1102102911), -1) - test(lg(-1425636748, -220185411), lg(1184140796, 40447497), -1) - test(lg(242386079, 452246653), lg(435337552, -956883630), 1) - test(lg(-1007383056, 344856628), lg(-195994328, 635205577), -1) - test(lg(-1652098619, 2042392045), lg(819672742, -2139008380), 1) - test(lg(1423590080, 1919857862), lg(918443721, 1202178673), 1) - test(lg(-1726296442, 302493002), lg(314727886, 1583734481), -1) - test(lg(-2124336701, 769721099), lg(461146322, -591528218), 1) - test(lg(1544826993, -689540243), lg(-1107003972, -1622786326), 1) - test(lg(2050227802, 951848379), lg(-774454951, 1675192386), -1) - test(lg(251298779, -327163776), lg(767615943, 1531730165), -1) - test(lg(1890888425, 761833495), lg(1870917399, 2027251288), -1) - test(lg(594868313, 126374530), lg(-1567484882, -1199917303), 1) - test(lg(-914360997, -703435655), lg(2049249771, -1581791194), 1) - test(lg(-732484281, -738997306), lg(1445589646, 1910084021), -1) - test(lg(340771740, 1351224018), lg(459324247, 1301544548), 1) - test(lg(-940710332, 1344186742), lg(-1143672211, 1112189558), 1) - test(lg(-804347876, 364046111), lg(-4317439, -1733157379), 1) - test(lg(914214836, -1226397169), lg(-299522125, 1393423940), -1) - test(lg(1244546642, 1821771770), lg(44151604, -1398558064), 1) - test(lg(-2094640323, -1469168677), lg(-263524564, 88152070), -1) - test(lg(-124567753, -93039352), lg(-200449699, -30383890), -1) - test(lg(161119306, -1098626173), lg(-137189625, 1289988889), -1) - test(lg(-2052616761, 846341515), lg(-150583666, 1044666783), -1) - test(lg(-10359669, -1628837253), lg(165345114, 1529503183), -1) - test(lg(1717988228, 1622548180), lg(834798590, -1907713185), 1) - test(lg(-1416372109, -353311343), lg(-722195813, -2060788759), 1) - test(lg(980620531, -300588346), lg(-889348218, 1805452697), -1) - test(lg(-465681479, 556544868), lg(-684386776, 724207906), -1) - test(lg(1720493596, 1118244444), lg(2048914469, -789300492), 1) - test(lg(-1259678249, -1557339417), lg(-1908141376, -468055129), -1) - test(lg(1374750478, 1591281700), lg(1107931774, 1073828802), 1) - test(lg(1307860622, -1769647645), lg(-1521056504, 1476896409), -1) - test(lg(1870719065, -606069057), lg(1219817813, -1063559023), 1) - test(lg(-526519712, 1166848880), lg(-748095992, 59925642), 1) - test(lg(-1011429486, -2053277854), lg(537284118, 1714076830), -1) - test(lg(-669104363, -107157886), lg(1647426475, -1784147450), 1) - test(lg(-389860398, 693324889), lg(1047633230, -1757663140), 1) - test(lg(-200206281, 96771163), lg(613429570, -1206384633), 1) - test(lg(-1436571081, -2050819200), lg(-665572561, 644211697), -1) - test(lg(620796821, -567816428), lg(-109412350, -624638338), 1) - test(lg(858464866, -2104597302), lg(-987329519, 1189618105), -1) - test(lg(-1342634556, -1517778924), lg(-693373055, 142499537), -1) - test(lg(1839280888, -168388422), lg(-1645740821, -1967920957), 1) - } - - @Test def bitwise_not_~(): Unit = { - assertEquals(lg(1664374422, 327449892), ~lg(-1664374423, -327449893)) - assertEquals(lg(-2033180390, -1179462631), ~lg(2033180389, 1179462630)) - assertEquals(lg(-1134559214, 581653069), ~lg(1134559213, -581653070)) - assertEquals(lg(-304074638, -795726117), ~lg(304074637, 795726116)) - assertEquals(lg(-1711832787, 1153070599), ~lg(1711832786, -1153070600)) - assertEquals(lg(-1526506637, 966114536), ~lg(1526506636, -966114537)) - assertEquals(lg(4362923, 1155261397), ~lg(-4362924, -1155261398)) - assertEquals(lg(-1976846289, -68873334), ~lg(1976846288, 68873333)) - assertEquals(lg(-980717878, -1171857118), ~lg(980717877, 1171857117)) - assertEquals(lg(1087568370, 543704246), ~lg(-1087568371, -543704247)) - assertEquals(lg(466027718, 693030605), ~lg(-466027719, -693030606)) - assertEquals(lg(457333958, 1344424074), ~lg(-457333959, -1344424075)) - assertEquals(lg(-1195369388, -1211454825), ~lg(1195369387, 1211454824)) - assertEquals(lg(1637646574, 618600148), ~lg(-1637646575, -618600149)) - assertEquals(lg(1882417448, 81477816), ~lg(-1882417449, -81477817)) - assertEquals(lg(-755550612, -520392566), ~lg(755550611, 520392565)) - assertEquals(lg(-754282895, -1550447287), ~lg(754282894, 1550447286)) - assertEquals(lg(949172349, -708028075), ~lg(-949172350, 708028074)) - assertEquals(lg(1587810906, -1344614950), ~lg(-1587810907, 1344614949)) - assertEquals(lg(-1761617639, -353615615), ~lg(1761617638, 353615614)) - assertEquals(lg(-153730678, 249152220), ~lg(153730677, -249152221)) - assertEquals(lg(-189227914, 2071190797), ~lg(189227913, -2071190798)) - assertEquals(lg(-853867870, 445686068), ~lg(853867869, -445686069)) - assertEquals(lg(-779434875, 417640992), ~lg(779434874, -417640993)) - assertEquals(lg(1997707715, -1100729422), ~lg(-1997707716, 1100729421)) - assertEquals(lg(1171311729, -1236578928), ~lg(-1171311730, 1236578927)) - assertEquals(lg(-833922040, 1773972621), ~lg(833922039, -1773972622)) - assertEquals(lg(1414648869, 1222586075), ~lg(-1414648870, -1222586076)) - assertEquals(lg(1123832582, -1270176018), ~lg(-1123832583, 1270176017)) - assertEquals(lg(1163066309, 237396271), ~lg(-1163066310, -237396272)) - assertEquals(lg(-1826566063, 509270117), ~lg(1826566062, -509270118)) - assertEquals(lg(-450318543, 1650640099), ~lg(450318542, -1650640100)) - assertEquals(lg(1461907704, -27364749), ~lg(-1461907705, 27364748)) - assertEquals(lg(1012261256, 1691289854), ~lg(-1012261257, -1691289855)) - assertEquals(lg(-1929178874, 1804481536), ~lg(1929178873, -1804481537)) - assertEquals(lg(-888719200, -1846455123), ~lg(888719199, 1846455122)) - assertEquals(lg(984231682, -867292444), ~lg(-984231683, 867292443)) - assertEquals(lg(2105026705, -16146223), ~lg(-2105026706, 16146222)) - assertEquals(lg(1742028653, -1648876191), ~lg(-1742028654, 1648876190)) - assertEquals(lg(1922039594, -60702355), ~lg(-1922039595, 60702354)) - assertEquals(lg(264728648, 275960741), ~lg(-264728649, -275960742)) - assertEquals(lg(1237639032, -1761272007), ~lg(-1237639033, 1761272006)) - assertEquals(lg(1118919822, 901486922), ~lg(-1118919823, -901486923)) - assertEquals(lg(18001220, -1121574637), ~lg(-18001221, 1121574636)) - assertEquals(lg(2122002356, -1370943785), ~lg(-2122002357, 1370943784)) - assertEquals(lg(2006182035, -1422441078), ~lg(-2006182036, 1422441077)) - assertEquals(lg(1314896174, 460075839), ~lg(-1314896175, -460075840)) - assertEquals(lg(1829402918, -1031934892), ~lg(-1829402919, 1031934891)) - assertEquals(lg(-2138673173, -107590306), ~lg(2138673172, 107590305)) - assertEquals(lg(1382443514, -56307753), ~lg(-1382443515, 56307752)) - } - - @Test def bitwise_or_|(): Unit = { - assertEquals(lg(1467334397, -608514), lg(1198889513, -170491266) | lg(356560637, 1244673694)) - assertEquals(lg(-1645778056, 796647391), lg(-1930990792, 627822941) | lg(-1849669008, 185716690)) - assertEquals(lg(2121785322, -3735189), lg(711185578, -154795743) | lg(1446469570, -104529814)) - assertEquals(lg(401988479, 1357601567), lg(356565628, 275405582) | lg(380967239, 1356925723)) - assertEquals(lg(-167780425, -167778583), lg(1968397619, -447093015) | lg(-1242708043, 1353146913)) - assertEquals(lg(-34603479, -565777), lg(-2121965024, -76133937) | lg(2104409609, -1365814226)) - assertEquals(lg(-537280529, -10535202), lg(1496398822, -548061626) | lg(-556169301, -245689186)) - assertEquals(lg(2132402169, -1093993487), lg(856203065, -1102382704) | lg(1276763344, 377524977)) - assertEquals(lg(500957183, -5777537), lg(474066920, -215674305) | lg(366737695, 530830706)) - assertEquals(lg(-1077937506, 1876426559), lg(-1543310820, 664058893) | lg(1002387606, 1826081595)) - assertEquals(lg(-2121745, -302649859), lg(1606847457, -857707283) | lg(-82108753, 628476252)) - assertEquals(lg(2113649662, -9748643), lg(703699686, -1218298019) | lg(1575693246, -565500071)) - assertEquals(lg(1845274268, 1608495102), lg(1281663616, 1255777790) | lg(1708663964, 1604300502)) - assertEquals(lg(-174066179, 1861146349), lg(-1315547660, 1726760037) | lg(-442781559, 235328140)) - assertEquals(lg(2139059199, -40115785), lg(2014986997, -1130692301) | lg(124088654, 1637408903)) - assertEquals(lg(-4195861, -679630869), lg(1653153899, 1412277603) | lg(-1615398494, -682581111)) - assertEquals(lg(601802239, 1937620978), lg(551077237, 1349033186) | lg(597575118, 1662855120)) - assertEquals(lg(-1383162189, -1107312899), lg(613289137, -1123701660) | lg(-1383294317, 369006329)) - assertEquals(lg(-141299717, -576585865), lg(-418175046, -593383309) | lg(1468132939, 360734532)) - assertEquals(lg(1998808831, -86066691), lg(1428236018, -1294026291) | lg(572735565, 1213340152)) - assertEquals(lg(-1680360554, -738459673), lg(-1949058688, -1013245209) | lg(416580246, 300148007)) - assertEquals(lg(-1073808964, -183288105), lg(-1746245220, 1427323605) | lg(-1185613404, -469621610)) - assertEquals(lg(1475346349, 1845485055), lg(1445648649, 701317455) | lg(1407661733, 1287118327)) - assertEquals(lg(-33566733, -268503975), lg(-1861500445, 764080137) | lg(-33812527, -411163560)) - assertEquals(lg(-286605413, 1602191341), lg(-1408712806, 393166157) | lg(1323973395, 1580353248)) - assertEquals(lg(-553947394, -2013546505), lg(-2072304578, -2142600249) | lg(-625840402, -2018265417)) - assertEquals(lg(-553746946, -140321), lg(450125308, 1742298015) | lg(-999674466, -89794491)) - assertEquals(lg(-16643, -68193313), lg(1239068904, -68194107) | lg(-1092247939, -639552609)) - assertEquals(lg(-52733444, -1159005505), lg(-2075047684, -1706497393) | lg(-119858776, -1461536706)) - assertEquals(lg(-121509406, 1048526839), lg(-1065293728, 1045575815) | lg(943802850, 4130803)) - assertEquals(lg(1844952571, -1327497834), lg(1688647147, -1327540094) | lg(1767049400, -1609892586)) - assertEquals(lg(-5046291, -1345721876), lg(-207425559, 231270892) | lg(515004644, -1349918716)) - assertEquals(lg(-1075861506, -67698709), lg(781813534, 1274454635) | lg(-1814682890, -1182466103)) - assertEquals(lg(2144796219, -17303617), lg(1792206347, -54265949) | lg(931436592, -625499620)) - assertEquals(lg(-874545153, -1611301156), lg(-1957992337, 421859924) | lg(1138122674, -1896513908)) - assertEquals(lg(-1218644010, -67141891), lg(-1220262128, 1790926509) | lg(-2107837994, -245286664)) - assertEquals(lg(-2555905, 2146160604), lg(-485426246, 2122993116) | lg(-1077361187, 795578180)) - assertEquals(lg(999978447, 2129346287), lg(713580935, 2059541733) | lg(957494730, 1688940106)) - assertEquals(lg(-836113, 1983903423), lg(-181332639, 608154803) | lg(787627150, 1378378253)) - assertEquals(lg(-273220891, -1242040457), lg(-944448827, -1528432780) | lg(-374967708, 364320051)) - assertEquals(lg(-52433921, -1615929419), lg(1822361801, -1626992863) | lg(-1865553026, -1867721804)) - assertEquals(lg(-1646593, -1583649), lg(-333036705, -39743141) | lg(-136127263, -404241201)) - assertEquals(lg(-105959457, -50406273), lg(1342309595, 143297662) | lg(-1448137844, -50933699)) - assertEquals(lg(-480707585, -87100434), lg(-514802766, 718197230) | lg(1113082335, -259890518)) - assertEquals(lg(-73693249, -555903498), lg(-476348284, -1025699402) | lg(1518405435, 1545110880)) - assertEquals(lg(-1646871041, -403194029), lg(-2058311589, 1135057747) | lg(-1664731675, -1535754941)) - assertEquals(lg(-203423937, -34342961), lg(333362997, -34482226) | lg(-205173969, 1754490115)) - assertEquals(lg(2083487743, -159909991), lg(2083354303, -2043490039) | lg(1344953817, -195725679)) - assertEquals(lg(-134268937, -680984614), lg(-942983837, -683124136) | lg(909452980, -1021249590)) - assertEquals(lg(-17107060, -35914117), lg(-402624124, -505696678) | lg(-688199800, 2110291577)) - } - - @Test def bitwise_and_&(): Unit = { - assertEquals(lg(-2012982272, 17896961), lg(-1973652216, 353474049) & lg(-576365513, -1546420349)) - assertEquals(lg(440467456, -805024688), lg(2054268182, -735220496) & lg(-1706223071, -653894309)) - assertEquals(lg(-1073741824, -2144861952), lg(-761230816, -1888512251) & lg(-988806710, -256349768)) - assertEquals(lg(-1977056222, -1878455803), lg(-834874333, -101893315) & lg(-1964333382, -1877225849)) - assertEquals(lg(-1069166300, 304091682), lg(-767041747, 1403541430) & lg(-320482908, 442929698)) - assertEquals(lg(193986570, 67633664), lg(1538292767, 67928849) & lg(261587146, 2097883842)) - assertEquals(lg(167772308, 35669040), lg(448790964, 1852174074) & lg(-284620129, 35804464)) - assertEquals(lg(540801, 554500096), lg(123267521, 1965916169) & lg(-401979731, 588194498)) - assertEquals(lg(-1878826824, 268436097), lg(-1725202754, 324931273) & lg(-1240211271, 948007557)) - assertEquals(lg(306780164, 8388625), lg(1044995460, -1447811559) & lg(1381579300, 378161591)) - assertEquals(lg(29904144, 12096051), lg(1640550232, -1980050765) & lg(-1613988461, 381206391)) - assertEquals(lg(-963297278, 537741320), lg(-810205145, 832395272) & lg(-153237294, -1368559681)) - assertEquals(lg(-2138566639, -1881372656), lg(-2087037677, -539042218) & lg(-1930915595, -1879201391)) - assertEquals(lg(348136448, 1461360), lg(936077102, 1888906741) & lg(-590306112, 153013360)) - assertEquals(lg(-2147459072, 50628864), lg(-1520343420, -480326676) & lg(-1031638712, 463833361)) - assertEquals(lg(-805279656, -972355264), lg(-603625122, -837874740) & lg(-266310439, -433325742)) - assertEquals(lg(1763723264, 1095287337), lg(2101242821, 1363798717) & lg(-337523686, -1007893653)) - assertEquals(lg(1296302405, 1947206722), lg(-849542331, 2084521938) & lg(1866786159, -179258269)) - assertEquals(lg(1275593362, 814484868), lg(1283984114, 1922846117) & lg(-42342754, 948944324)) - assertEquals(lg(1081520, 35397649), lg(18451376, 39592223) & lg(-300891980, 43819665)) - assertEquals(lg(539714600, -1617688304), lg(1772840110, -1611388521) & lg(876572201, -1080057992)) - assertEquals(lg(268660738, 1111507460), lg(-1792575438, 1131693597) & lg(2026108738, -691967420)) - assertEquals(lg(-1977139054, 2393104), lg(-1977130853, 1105495064) & lg(-289941322, 37545108)) - assertEquals(lg(-2145341308, -1333516032), lg(-1590955612, -1330697458) & lg(-924798828, -1177272879)) - assertEquals(lg(-1503395487, -299827136), lg(-285931035, -293654078) & lg(-1486596765, -31342500)) - assertEquals(lg(1233401994, 34091008), lg(1237743775, -1293389691) & lg(1803860874, 1175174664)) - assertEquals(lg(-932558672, 270533826), lg(-839976008, 900736195) & lg(-362132238, -668577850)) - assertEquals(lg(117477888, 473995424), lg(1202887172, 484547048) & lg(793351913, -1622877017)) - assertEquals(lg(302600257, -2030040226), lg(1393155525, -2025583778) & lg(-1164217783, -416769026)) - assertEquals(lg(145293649, 536871648), lg(-658787467, -1534848013) & lg(770509273, 861439716)) - assertEquals(lg(1546608834, 302001248), lg(1550840002, 1588870758) & lg(2084528882, 302148833)) - assertEquals(lg(201606209, -695465177), lg(481609689, -152204489) & lg(1279544421, -561242137)) - assertEquals(lg(608207492, -2112820352), lg(-1529763097, -1978531900) & lg(641783708, -2039026814)) - assertEquals(lg(270672860, -1476361723), lg(887514076, -129985897) & lg(423346174, -1364800691)) - assertEquals(lg(606102544, -503185240), lg(1736270961, -223672071) & lg(748709016, -498985816)) - assertEquals(lg(144970344, 74547586), lg(413438572, 628333003) & lg(-1964689415, -2039117914)) - assertEquals(lg(0, 33646849), lg(-1441786846, -952014445) & lg(1364118108, 582220621)) - assertEquals(lg(886489100, -1836576552), lg(-167845571, -610782244) & lg(920048140, -1832380167)) - assertEquals(lg(181408260, 8425760), lg(1070668735, 1223734716) & lg(1255200260, 310500128)) - assertEquals(lg(18633796, 1494253868), lg(565998918, 2102701486) & lg(1230790357, -651115716)) - assertEquals(lg(1242169472, 1074954242), lg(1259021457, -988117846) & lg(-95497780, 2025257730)) - assertEquals(lg(202639938, 134272082), lg(236334914, 210367602) & lg(-1388488109, 672191707)) - assertEquals(lg(955253125, 1994661641), lg(2029259749, 2012495659) & lg(-1125022313, -17866867)) - assertEquals(lg(134242336, 1377566768), lg(2078335024, -748696528) & lg(-1944488853, 1455161657)) - assertEquals(lg(883214088, 536873986), lg(1962270604, 747650594) & lg(1051641707, -1606005365)) - assertEquals(lg(203000132, 19923458), lg(504991188, 623990339) & lg(-1919047324, 331123498)) - assertEquals(lg(274893395, 1881151488), lg(409659995, 1887189252) & lg(384277491, 1973591160)) - assertEquals(lg(115235, 335685459), lg(872793907, 353626075) & lg(34859627, 1988247415)) - assertEquals(lg(538493100, 441057288), lg(-1407266644, 441386073) & lg(1635378940, -548742904)) - assertEquals(lg(839516176, 671232089), lg(844761371, 1022505085) & lg(1930384912, 688275291)) - } - - @Test def bitwise_xor_^(): Unit = { - assertEquals(lg(1342248740, -313223199), lg(690404572, -1279287229) ^ lg(2032643064, 1592473506)) - assertEquals(lg(-1691405730, 274213753), lg(1880634009, 1433776255) ^ lg(-348716857, 1160616710)) - assertEquals(lg(882329013, -513228751), lg(-958227509, 287282926) ^ lg(-227156354, -260614433)) - assertEquals(lg(1416185065, -1664302164), lg(-266860160, 1815641996) ^ lg(-1536078487, -252396512)) - assertEquals(lg(-1268929640, 1388542260), lg(1278830943, 22194981) ^ lg(-127614265, 1402065425)) - assertEquals(lg(2107251545, -1588280474), lg(-865349911, -84319450) ^ lg(-1309551184, 1538105408)) - assertEquals(lg(-1128180942, 150893828), lg(-1973252863, -1969367363) ^ lg(916708915, -2107399239)) - assertEquals(lg(-721878765, 35051090), lg(2098389933, -3394272) ^ lg(-1444158786, -35986574)) - assertEquals(lg(-1863503396, 535478572), lg(533612062, -1712875225) ^ lg(-1893500990, -2045945845)) - assertEquals(lg(1732708730, -1611595623), lg(799833325, 2072025633) ^ lg(1223390615, -462316872)) - assertEquals(lg(-757432261, -1755342186), lg(570370215, 1665373667) ^ lg(-215635812, -199487627)) - assertEquals(lg(755676969, 926086823), lg(-1440978805, 1756956707) ^ lg(-2028544094, 1603010180)) - assertEquals(lg(1331057947, 1347408402), lg(-1788434031, -203193594) ^ lg(-634323830, -1548988140)) - assertEquals(lg(596183682, -256181831), lg(-1101798994, 1399594232) ^ lg(-1646597332, -1546197695)) - assertEquals(lg(1360009516, 182700672), lg(-1432962218, -1631098948) ^ lg(-75062662, -1809535684)) - assertEquals(lg(594798246, -124892913), lg(699430210, 902448324) ^ lg(180589540, -851178037)) - assertEquals(lg(-1331407219, 1819608371), lg(-1873118605, -20501824) ^ lg(553528574, -1833816077)) - assertEquals(lg(1679931669, 470452622), lg(-693963147, 616673404) ^ lg(-1300017312, 952842738)) - assertEquals(lg(1861159718, -1488989292), lg(1250421224, 1104113895) ^ lg(610853582, -420437133)) - assertEquals(lg(1056597675, -102857583), lg(-611286212, -1550148499) ^ lg(-445979241, 1514412284)) - assertEquals(lg(255992058, 1610836280), lg(1704771515, 1382796179) ^ lg(1792974657, 845718187)) - assertEquals(lg(315376042, 566682776), lg(1042258124, 728098489) ^ lg(752081254, 178455073)) - assertEquals(lg(-185728083, -2076881789), lg(-1887944331, 1039677246) ^ lg(2073445080, -1177715779)) - assertEquals(lg(22829354, 1511361245), lg(1986213921, -1875380784) ^ lg(2000642315, -903708915)) - assertEquals(lg(-1209040105, 1698106233), lg(365179043, -418125319) ^ lg(-1574194252, -2111511936)) - assertEquals(lg(-2034371369, -364230501), lg(-376038790, 1936322298) ^ lg(1865150125, -1725716895)) - assertEquals(lg(-324294323, -1435696355), lg(182372182, -1389399582) ^ lg(-428511717, 121795327)) - assertEquals(lg(-1632322296, 110394084), lg(408417754, -547668779) ^ lg(-2031925038, -640727503)) - assertEquals(lg(1545363539, -418308022), lg(1515701412, 860890032) ^ lg(105620727, -733936646)) - assertEquals(lg(-2124553361, 1571601224), lg(144626057, 2121098703) ^ lg(-1983696154, 599907975)) - assertEquals(lg(-508527758, 679546956), lg(1716685092, -647833300) ^ lg(-2015169962, -236730016)) - assertEquals(lg(-703803607, -1904715404), lg(-2016515438, -1674300757) ^ lg(1371710907, 306998239)) - assertEquals(lg(-1295788899, 1052686696), lg(-547404938, -860356684) ^ lg(1838979051, -234273060)) - assertEquals(lg(-1416482745, -1744821078), lg(1034397763, 1158948099) ^ lg(-1774872572, -585891415)) - assertEquals(lg(-420256974, -1759976200), lg(1755131065, -847055172) ^ lg(-1905373301, 1520046660)) - assertEquals(lg(-1978435977, -1613559541), lg(755114159, 1707687361) ^ lg(-1492035880, -98945846)) - assertEquals(lg(1517584033, -1108617107), lg(1110955283, -394871226) ^ lg(407088050, 1436378667)) - assertEquals(lg(1706214170, -555203143), lg(729918767, -1047522396) ^ lg(1311993397, 527980061)) - assertEquals(lg(-278231087, -1148948163), lg(-1533968339, 1826223468) ^ lg(1274742780, -681737135)) - assertEquals(lg(-204001370, 1220298027), lg(230297309, -219465279) ^ lg(-26402437, -1168671510)) - assertEquals(lg(-1169385448, -2039889677), lg(-1364422220, 1487677662) ^ lg(350226860, -557455315)) - assertEquals(lg(791138554, 668046473), lg(-1049451753, 1883174397) ^ lg(-296389651, 1475305844)) - assertEquals(lg(2103687665, 1121138741), lg(-895088167, 1303802204) ^ lg(-1211781080, 258296169)) - assertEquals(lg(-387978954, 908804328), lg(1409034242, -1162000487) ^ lg(-1155284684, -1936324751)) - assertEquals(lg(1265820840, 1142688859), lg(861082066, -475962819) ^ lg(2015491450, -1480757658)) - assertEquals(lg(1490973918, -277478122), lg(-288714491, 1935424926) ^ lg(-1240144421, -1674954616)) - assertEquals(lg(1839163014, 362842460), lg(-699164585, -731232280) ^ lg(-1144193327, -1043673420)) - assertEquals(lg(634920094, -2001579101), lg(683993930, 248552821) ^ lg(220002260, -2040344874)) - assertEquals(lg(-831642917, -817908795), lg(640417317, 298956382) ^ lg(-398074626, -554826341)) - assertEquals(lg(857398449, 1711937081), lg(-1493347776, 1187436882) ^ lg(-1779986703, 550293355)) - } - - @Test def shift_left_<<(): Unit = { - assertEquals(lg(1065353216, -691528727), lg(-1875389825, 1268606893) << -73329513) - assertEquals(lg(671088640, -1046568266), lg(869553861, -291578632) << -339545061) - assertEquals(lg(0, 0), lg(543726956, -1753066291) << -809014658) - assertEquals(lg(-754974720, -1479892363), lg(-895322669, 847749031) << 1030973528) - assertEquals(lg(0, 1696595968), lg(1598039634, 819660072) << 82069876) - assertEquals(lg(0, -763223040), lg(-151740279, -595601314) << 503039850) - assertEquals(lg(0, -1360527360), lg(-1702267427, 1115684531) << 1171866675) - assertEquals(lg(508125184, -784066052), lg(-807341493, 286689824) << -1938771891) - assertEquals(lg(-551288832, 439734876), lg(-382832750, -2134078182) << 1537970769) - assertEquals(lg(-1409069728, 1129787), lg(-580904341, 939559401) << 1856717061) - assertEquals(lg(1711276032, 1295846454), lg(-198125160, 663832884) << 1561097110) - assertEquals(lg(-1004724328, -940313723), lg(-1199332365, -1728151952) << 858801923) - assertEquals(lg(-1029298112, -1523092059), lg(773140802, -181814355) << 1110910853) - assertEquals(lg(536870912, 200145086), lg(1601160689, 869229832) << -338843811) - assertEquals(lg(0, -1735502848), lg(-1919381932, -201750119) << -813015128) - assertEquals(lg(-1727917056, 2104066035), lg(-52019067, -102802849) << -2122946486) - assertEquals(lg(0, 771751936), lg(-456947922, 1170727731) << 2126487160) - assertEquals(lg(0, -710836224), lg(1756719200, -1702547414) << -32425558) - assertEquals(lg(0, -1073741824), lg(97072750, 409070577) << 1222452733) - assertEquals(lg(0, -1182793728), lg(1177105779, 212324545) << -834196361) - assertEquals(lg(0, 1543503872), lg(1395605166, -1743726419) << -1762017159) - assertEquals(lg(0, -67108864), lg(703808254, 1939941481) << 1042647417) - assertEquals(lg(0, 1207959552), lg(-702184622, -618243162) << -753853766) - assertEquals(lg(-58458112, -1619174179), lg(-1368457662, 1747275710) << 1382741393) - assertEquals(lg(0, -299542812), lg(-74885703, 1342895995) << 1929734882) - assertEquals(lg(0, -1585446912), lg(-61401466, -496528012) << -129147274) - assertEquals(lg(1888485376, 630678170), lg(-660169692, 1479330149) << 289081298) - assertEquals(lg(0, -536870912), lg(-421237721, 1011668330) << 370873533) - assertEquals(lg(0, 102137856), lg(-821818323, -2029348763) << -916638609) - assertEquals(lg(0, -1073741824), lg(-1246065172, -1572087360) << 1493241980) - assertEquals(lg(1156516188, -1812425640), lg(578258094, -906212820) << 2074806145) - assertEquals(lg(0, 1370357760), lg(61151968, -1770168701) << -2062208020) - assertEquals(lg(-402653184, 1642287002), lg(1013576541, 460756940) << -902835237) - assertEquals(lg(-1744830464, 1690731362), lg(-1731171245, 771836652) << 868975579) - assertEquals(lg(-417260032, 563566725), lg(1123258511, 1049676716) << 575477257) - assertEquals(lg(411626816, -1915897795), lg(-779579692, 1222433667) << 1238257604) - assertEquals(lg(0, -2147483648), lg(-1102469156, -543766743) << 553354173) - assertEquals(lg(0, -1909156352), lg(843520587, -517185932) << 1899246569) - assertEquals(lg(0, -487976960), lg(-510775647, -896837143) << 1487779500) - assertEquals(lg(-1148788736, -847308273), lg(-1594115986, -186853391) << -119255604) - assertEquals(lg(0, 1940424228), lg(-588635767, 1047291343) << 2089738146) - assertEquals(lg(1726279680, 2137615428), lg(-1002017201, -986188138) << 800913356) - assertEquals(lg(0, 1650633728), lg(1813551275, -400674286) << -1609938966) - assertEquals(lg(-1207959552, 897838789), lg(-1333929801, 254558182) << -1518372133) - assertEquals(lg(0, -1104224256), lg(834127324, 878312672) << -923142549) - assertEquals(lg(-504160320, 305586753), lg(126340223, -2008491127) << -252023418) - assertEquals(lg(0, 0), lg(510931784, -1313923431) << 1174528765) - assertEquals(lg(-1449390900, -1602240664), lg(711394099, -400560166) << -967606846) - assertEquals(lg(0, 1162928128), lg(1319282800, -1994311032) << 1237159401) - assertEquals(lg(-1749421258, 1809275319), lg(-874710629, -1242845989) << 484063041) - } - - @Test def shift_logical_right_>>>(): Unit = { - assertEquals(lg(1982185809, 4856), lg(88517143, 1273092247) >>> 2099569298) - assertEquals(lg(40, 0), lg(-1987462914, 1361836721) >>> -2053535175) - assertEquals(lg(258, 0), lg(1513792977, 1085974656) >>> -303705162) - assertEquals(lg(-1589724844, 2), lg(-2071249600, 1411897130) >>> 1015183069) - assertEquals(lg(827423626, 419765), lg(-1560865755, 214919778) >>> 1191603401) - assertEquals(lg(376475826, 25773988), lg(944265510, -995896821) >>> 485744647) - assertEquals(lg(291969293, 528), lg(1131824263, -2080089658) >>> -386336938) - assertEquals(lg(185, 0), lg(-827478170, -1185129975) >>> 2048537528) - assertEquals(lg(45022, 0), lg(-916869993, -1344352401) >>> -791372688) - assertEquals(lg(587, 0), lg(588931659, -1830830904) >>> -1259543946) - assertEquals(lg(-684574597, 28915), lg(473794659, 947514265) >>> -1409717873) - assertEquals(lg(3, 0), lg(471518489, -940479957) >>> -847604034) - assertEquals(lg(11, 0), lg(-818287716, 1547586919) >>> -216455813) - assertEquals(lg(266, 0), lg(-2088976011, -2057680935) >>> 787633143) - assertEquals(lg(-800511856, 59336150), lg(306848777, -497453644) >>> 1584315654) - assertEquals(lg(25694, 0), lg(-1689341833, -927188015) >>> 1300572337) - assertEquals(lg(237982231, 3229829), lg(396954515, 413418119) >>> 1180537031) - assertEquals(lg(1319611409, 10188), lg(1478732342, 1335401807) >>> -1668840943) - assertEquals(lg(-530293557, 9), lg(-1326271298, -1643756084) >>> -2118687716) - assertEquals(lg(26, 0), lg(1205635051, 875594107) >>> 350453433) - assertEquals(lg(1698203097, 57089), lg(-2049358216, -553556680) >>> -1203541232) - assertEquals(lg(-308392901, 40188), lg(1278981121, -1661145698) >>> 254766480) - assertEquals(lg(-1667461656, 7259908), lg(1313272948, 929268302) >>> 1175504903) - assertEquals(lg(99018, 0), lg(1982277801, -1050318135) >>> 629735727) - assertEquals(lg(16237, 0), lg(-610510955, 1064153335) >>> 577897264) - assertEquals(lg(689994, 0), lg(1859860682, 1413109554) >>> 243415787) - assertEquals(lg(4088, 0), lg(1757351444, -7991214) >>> -1844808396) - assertEquals(lg(48441534, 0), lg(-1277568919, -1194709070) >>> -2102413146) - assertEquals(lg(42961906, 0), lg(-1768551066, 1342559) >>> 365466523) - assertEquals(lg(1946, 0), lg(1051996382, -213518283) >>> -717261067) - assertEquals(lg(-605712863, 10), lg(451444747, -1380034334) >>> -675522340) - assertEquals(lg(8, 0), lg(605006440, -1956088854) >>> 192236860) - assertEquals(lg(-152492078, 258), lg(-384174131, -2122615661) >>> -1278414057) - assertEquals(lg(-1650335224, 9146646), lg(-1579022332, -1953425763) >>> 2134440904) - assertEquals(lg(175996054, 0), lg(-433112808, -1479030417) >>> -1873327132) - assertEquals(lg(771890457, 0), lg(-1786180708, 385945228) >>> 1526047775) - assertEquals(lg(868056695, -1200391723), lg(868056695, -1200391723) >>> 93595840) - assertEquals(lg(88233, 0), lg(1335240662, -1403745666) >>> 1625850351) - assertEquals(lg(21, 0), lg(-681452715, -1446696044) >>> -742234373) - assertEquals(lg(200097858, 0), lg(301750839, 1600782865) >>> 1678034787) - assertEquals(lg(1, 0), lg(-2077889650, 445749598) >>> 363036476) - assertEquals(lg(-1160719403, 3135), lg(-1633078438, 1644025478) >>> -1297864237) - assertEquals(lg(27660, 0), lg(1159483779, 906375175) >>> -1204888593) - assertEquals(lg(1096217739, 131290637), lg(179807326, 1050325098) >>> -1598422013) - assertEquals(lg(61, 0), lg(952383136, -193355640) >>> 415626042) - assertEquals(lg(12362394, 0), lg(972435428, -1130194211) >>> -1259042456) - assertEquals(lg(-924965860, 8483), lg(605823642, 555993310) >>> 1780437072) - assertEquals(lg(88, 0), lg(665774635, 184915839) >>> 1729784373) - assertEquals(lg(27109, 0), lg(-263808048, -741669613) >>> -204793551) - assertEquals(lg(-5828381, 10), lg(-954198224, 369053217) >>> 768150041) - } - - @Test def shift_arithmetic_right_>>(): Unit = { - assertEquals(lg(144041519, 2813487), lg(-1780076655, 720252680) >> -1316031160) - assertEquals(lg(1519, 0), lg(234061537, 796729805) >> 1452874739) - assertEquals(lg(-935479627, 124), lg(1523206972, 1046748891) >> 1356453463) - assertEquals(lg(-15335, -1), lg(1866043067, -2009962307) >> 393061105) - assertEquals(lg(5, 0), lg(89507691, 183545611) >> -1980770119) - assertEquals(lg(-1283367734, 14309038), lg(-1062312593, 1831556953) >> 1545082311) - assertEquals(lg(523169438, 0), lg(-1568293714, 523169438) >> -2119005984) - assertEquals(lg(-1704853904, -731301), lg(-2013675422, -748851607) >> 511130378) - assertEquals(lg(345569760, -46), lg(-521585277, -770402055) >> -1176556648) - assertEquals(lg(1777038301, 61), lg(-145701849, 257587932) >> -1512809002) - assertEquals(lg(-51, -1), lg(-973180026, -1694110170) >> 2083093369) - assertEquals(lg(-5, -1), lg(1761120319, -539393529) >> -207994821) - assertEquals(lg(-587262921, -3246345), lg(-30904807, -1662128199) >> -638486135) - assertEquals(lg(-10706, -1), lg(1812122560, -701571284) >> 611632432) - assertEquals(lg(7484398, 100362842), lg(119750375, 1605805472) >> 244039684) - assertEquals(lg(1, 0), lg(269986751, 1459449758) >> -439796226) - assertEquals(lg(7, 0), lg(-1969890020, 2011804532) >> -652735044) - assertEquals(lg(-2130588861, 98), lg(-1582649974, 826310885) >> 613066583) - assertEquals(lg(-669931160, -697), lg(756433442, -1459944907) >> -775565931) - assertEquals(lg(933146972, -1), lg(1678061064, -1680910162) >> -531660641) - assertEquals(lg(1601141595, 1298147), lg(1870355258, 332325727) >> -434372344) - assertEquals(lg(-1047936567, -129548), lg(1886551280, -2122502046) >> -763866098) - assertEquals(lg(-72307, -1), lg(-1169141408, -592336405) >> -1841005139) - assertEquals(lg(72262, 0), lg(686282122, 295988927) >> 69079212) - assertEquals(lg(-1582088844, -23862710), lg(1825529126, -1527213400) >> 1371712838) - assertEquals(lg(70395261, 0), lg(633149491, 1126324183) >> 1948323684) - assertEquals(lg(-329, -1), lg(-363762029, -1377253181) >> -1243200330) - assertEquals(lg(1924403917, -21), lg(-1694234908, -689608667) >> 728732313) - assertEquals(lg(-62655, -1), lg(1319661865, -2053067582) >> -777879057) - assertEquals(lg(-1472236443, 19900875), lg(-1472236443, 19900875) >> 373478400) - assertEquals(lg(-1, -1), lg(-1719111010, -1766452468) >> 942391743) - assertEquals(lg(5131, 0), lg(-624682758, 1345231635) >> -813574478) - assertEquals(lg(9, 0), lg(1316519660, 314590421) >> -641829383) - assertEquals(lg(-14492, -1), lg(-1380652891, -474856510) >> -920501329) - assertEquals(lg(40, 0), lg(-2084688189, 1352268039) >> -177471111) - assertEquals(lg(-868447412, 13901269), lg(507881044, 1779362534) >> -508943033) - assertEquals(lg(-37529, -1), lg(1742323077, -1229747072) >> 401183471) - assertEquals(lg(376386, 0), lg(346182810, 770838817) >> 797274667) - assertEquals(lg(-1822, -1), lg(828281422, -477411393) >> 1298272370) - assertEquals(lg(1021967080, -2560), lg(-341778503, -671026265) >> 532386578) - assertEquals(lg(-1683940185, 34921), lg(-1907127360, 1144311248) >> -2131012273) - assertEquals(lg(-121723, -1), lg(756366897, -1994294687) >> -1642432978) - assertEquals(lg(-644688038, 9473), lg(-1363894143, 1241756453) >> 1681307793) - assertEquals(lg(-278047, -1), lg(1708006412, -1138876437) >> 2010442220) - assertEquals(lg(872834, 0), lg(-664430929, 446891142) >> -1707024855) - assertEquals(lg(-1, -1), lg(-1904131429, -938887) >> -829231944) - assertEquals(lg(-2101780246, 11998), lg(-1043053889, 1572668786) >> 309495249) - assertEquals(lg(-11427, -1), lg(563683687, -1497656119) >> -176819791) - assertEquals(lg(201, 0), lg(-627312011, 421917318) >> 2056663541) - assertEquals(lg(-104838948, -3), lg(-904956287, -543423347) >> -617227620) - } - - @Test def negate_-(): Unit = { - assertEquals(lg(0), -lg(0)) - assertEquals(lg(1), -lg(-1)) - assertEquals(lg(-1), -lg(1)) - assertEquals(lg(1, -2147483648), -MaxVal) - assertEquals(MinVal, -MinVal) - assertEquals(lg(0, -1), -lg(0, 1)) - - assertEquals(lg(792771844, -1518464955), -lg(-792771844, 1518464954)) - assertEquals(lg(1313283210, -1172119606), -lg(-1313283210, 1172119605)) - assertEquals(lg(-1034897743, -341494686), -lg(1034897743, 341494685)) - assertEquals(lg(-924881290, 1614058538), -lg(924881290, -1614058539)) - assertEquals(lg(-1636891236, -1405401040), -lg(1636891236, 1405401039)) - assertEquals(lg(2044349674, -477271433), -lg(-2044349674, 477271432)) - assertEquals(lg(1426086684, -1493816436), -lg(-1426086684, 1493816435)) - assertEquals(lg(-2125201680, 1667846199), -lg(2125201680, -1667846200)) - assertEquals(lg(161054645, -1272528725), -lg(-161054645, 1272528724)) - assertEquals(lg(-1013390126, -1323844683), -lg(1013390126, 1323844682)) - assertEquals(lg(-1028806094, -691441881), -lg(1028806094, 691441880)) - assertEquals(lg(1060422114, -11477649), -lg(-1060422114, 11477648)) - assertEquals(lg(1366334123, -2046238761), -lg(-1366334123, 2046238760)) - assertEquals(lg(1307711795, 940346049), -lg(-1307711795, -940346050)) - assertEquals(lg(421687960, -250174762), -lg(-421687960, 250174761)) - assertEquals(lg(379452754, -843386803), -lg(-379452754, 843386802)) - assertEquals(lg(-1251296999, 1144268297), -lg(1251296999, -1144268298)) - assertEquals(lg(-690359429, -1676679602), -lg(690359429, 1676679601)) - assertEquals(lg(1952563749, -882544420), -lg(-1952563749, 882544419)) - assertEquals(lg(-1420900897, -1865273591), -lg(1420900897, 1865273590)) - assertEquals(lg(115947827, -832851217), -lg(-115947827, 832851216)) - assertEquals(lg(-1834973959, -1423776005), -lg(1834973959, 1423776004)) - assertEquals(lg(1376766876, 1519617584), -lg(-1376766876, -1519617585)) - assertEquals(lg(-1845217535, 724725865), -lg(1845217535, -724725866)) - assertEquals(lg(-1133294381, 699400553), -lg(1133294381, -699400554)) - assertEquals(lg(113507585, 615978889), -lg(-113507585, -615978890)) - assertEquals(lg(-1839784424, 1163726652), -lg(1839784424, -1163726653)) - assertEquals(lg(1065777168, 1301742163), -lg(-1065777168, -1301742164)) - assertEquals(lg(334075220, -1058529734), -lg(-334075220, 1058529733)) - assertEquals(lg(1443112398, 1148167880), -lg(-1443112398, -1148167881)) - assertEquals(lg(1647739462, 12310882), -lg(-1647739462, -12310883)) - assertEquals(lg(1461318149, 518941731), -lg(-1461318149, -518941732)) - assertEquals(lg(56833825, -162898592), -lg(-56833825, 162898591)) - assertEquals(lg(-680096727, -1760413869), -lg(680096727, 1760413868)) - assertEquals(lg(461541717, -1103626950), -lg(-461541717, 1103626949)) - assertEquals(lg(1287248387, 1483137214), -lg(-1287248387, -1483137215)) - assertEquals(lg(-1681467124, -1197977023), -lg(1681467124, 1197977022)) - assertEquals(lg(-310946355, 885055747), -lg(310946355, -885055748)) - assertEquals(lg(-717629012, -1299204708), -lg(717629012, 1299204707)) - assertEquals(lg(800584851, 350245993), -lg(-800584851, -350245994)) - assertEquals(lg(1911014238, -441020786), -lg(-1911014238, 441020785)) - assertEquals(lg(-1647080824, -1197295589), -lg(1647080824, 1197295588)) - assertEquals(lg(-925751968, -479541400), -lg(925751968, 479541399)) - assertEquals(lg(-656919119, 1574890072), -lg(656919119, -1574890073)) - assertEquals(lg(-1833364814, 432106462), -lg(1833364814, -432106463)) - assertEquals(lg(-315730911, -1990201785), -lg(315730911, 1990201784)) - assertEquals(lg(1218524771, -572482048), -lg(-1218524771, 572482047)) - assertEquals(lg(276668811, 2002398729), -lg(-276668811, -2002398730)) - assertEquals(lg(1489416833, 834462753), -lg(-1489416833, -834462754)) - assertEquals(lg(2066446588, 688546120), -lg(-2066446588, -688546121)) - } - - @Test def plus_+(): Unit = { - assertEquals(lg(802149732, -566689627), lg(-202981355, -566689628) + lg(1005131087, 0)) - assertEquals(lg(902769101, 1674149440), lg(1153016325, 1674149440) + lg(-250247224, -1)) - assertEquals(lg(1128646485, -1965159800), lg(1701699755, -1965159800) + lg(-573053270, -1)) - assertEquals(lg(66936416, -973893589), lg(-1183294843, -973893590) + lg(1250231259, 0)) - assertEquals(lg(-155818001, 449544496), lg(-2145882999, 449544496) + lg(1990064998, 0)) - assertEquals(lg(-1244599644, -917980205), lg(-528276750, -917980205) + lg(-716322894, -1)) - assertEquals(lg(580594010, 1794016499), lg(-1061043923, 1794016498) + lg(1641637933, 0)) - assertEquals(lg(-1874551871, 1883156001), lg(-315483661, 1883156001) + lg(-1559068210, -1)) - assertEquals(lg(-611587809, 95409025), lg(-1899047326, 95409025) + lg(1287459517, 0)) - assertEquals(lg(-1393747885, 1167571449), lg(-705065818, 1167571449) + lg(-688682067, -1)) - assertEquals(lg(1135734754, -607437553), lg(-192210545, -607437554) + lg(1327945299, 0)) - assertEquals(lg(545472170, -2007097641), lg(11453726, -2007097641) + lg(534018444, 0)) - assertEquals(lg(-1984029353, -1191350400), lg(1809973610, -1191350400) + lg(500964333, 0)) - assertEquals(lg(1031291620, 108684756), lg(972641234, 108684756) + lg(58650386, 0)) - assertEquals(lg(-1375760766, 127758048), lg(-1511325903, 127758048) + lg(135565137, 0)) - assertEquals(lg(640679472, 429508922), lg(-942832491, 429508921) + lg(1583511963, 0)) - assertEquals(lg(-820503583, -594798242), lg(1500842230, -594798242) + lg(1973621483, 0)) - assertEquals(lg(1875301895, 910473912), lg(-1088230684, 910473912) + lg(-1331434717, -1)) - assertEquals(lg(-1755864971, 378724963), lg(798219431, 378724963) + lg(1740882894, 0)) - assertEquals(lg(468052904, -683558197), lg(-1763683665, -683558197) + lg(-2063230727, -1)) - assertEquals(lg(-1488850347, -1636478025), lg(627629519, -1636478024) + lg(-2116479866, -1)) - assertEquals(lg(915882407, -338305025), lg(-526665240, -338305026) + lg(1442547647, 0)) - assertEquals(lg(-950882103, -466473801), lg(-1265295286, -466473801) + lg(314413183, 0)) - assertEquals(lg(-673278223, -1417005301), lg(-1412852606, -1417005301) + lg(739574383, 0)) - assertEquals(lg(-1565299836, -2035157269), lg(708993121, -2035157269) + lg(2020674339, 0)) - assertEquals(lg(638729196, 1182702858), lg(847269791, 1182702858) + lg(-208540595, -1)) - assertEquals(lg(-1453651445, -1902383955), lg(97084677, -1902383954) + lg(-1550736122, -1)) - assertEquals(lg(1116569659, -606967004), lg(-267181534, -606967005) + lg(1383751193, 0)) - assertEquals(lg(529048030, 1063184820), lg(-904322265, 1063184819) + lg(1433370295, 0)) - assertEquals(lg(-499260224, 101142421), lg(1841727454, 101142421) + lg(1953979618, 0)) - assertEquals(lg(1452864874, 1045175929), lg(-1716387490, 1045175929) + lg(-1125714932, -1)) - assertEquals(lg(982736721, 1506316757), lg(-1020814821, 1506316756) + lg(2003551542, 0)) - assertEquals(lg(-1478064805, 1107506955), lg(467820886, 1107506956) + lg(-1945885691, -1)) - assertEquals(lg(1436947166, -57552832), lg(-103701719, -57552833) + lg(1540648885, 0)) - assertEquals(lg(3887456, -414981457), lg(1280780483, -414981457) + lg(-1276893027, -1)) - assertEquals(lg(939083871, 606376864), lg(-1505747919, 606376864) + lg(-1850135506, -1)) - assertEquals(lg(-1161495325, -606274238), lg(-1797917239, -606274238) + lg(636421914, 0)) - assertEquals(lg(2146013782, 52949338), lg(-551974000, 52949338) + lg(-1596979514, -1)) - assertEquals(lg(-159062053, -623553409), lg(484182807, -623553408) + lg(-643244860, -1)) - assertEquals(lg(1680160313, 371486519), lg(1170065239, 371486519) + lg(510095074, 0)) - assertEquals(lg(-2071737549, -251530660), lg(553737773, -251530660) + lg(1669491974, 0)) - assertEquals(lg(793877651, -324566030), lg(1363264202, -324566030) + lg(-569386551, -1)) - assertEquals(lg(1897556965, 1255689015), lg(1461362302, 1255689015) + lg(436194663, 0)) - assertEquals(lg(-540868058, 718534179), lg(-1463314706, 718534179) + lg(922446648, 0)) - assertEquals(lg(2547531, -716998232), lg(-1684072850, -716998233) + lg(1686620381, 0)) - assertEquals(lg(-1709813271, -2086072551), lg(-183257712, -2086072551) + lg(-1526555559, -1)) - assertEquals(lg(-2134341942, -1223154956), lg(-485818523, -1223154956) + lg(-1648523419, -1)) - assertEquals(lg(1634619686, -1934382665), lg(392330048, -1934382665) + lg(1242289638, 0)) - assertEquals(lg(-1409927090, -75135322), lg(1907808353, -75135322) + lg(977231853, 0)) - assertEquals(lg(-1393001322, 1362535802), lg(88305723, 1362535803) + lg(-1481307045, -1)) - } - - @Test def minus_-(): Unit = { - // Whitebox corner case - assertEquals(lg(-1), lg(0) - lg(1)) - - assertEquals(lg(1318078695, 462416044), lg(406229717, 462416044) - lg(-911848978, -1)) - assertEquals(lg(459412414, 466142261), lg(873646396, 466142261) - lg(414233982, 0)) - assertEquals(lg(1749422706, -573388520), lg(-2077914189, -573388520) - lg(467630401, 0)) - assertEquals(lg(855866353, -1980988131), lg(-789253983, -1980988132) - lg(-1645120336, -1)) - assertEquals(lg(1858485462, 1825277273), lg(-482388232, 1825277273) - lg(1954093602, 0)) - assertEquals(lg(1211608504, -1077757379), lg(-1616159373, -1077757379) - lg(1467199419, 0)) - assertEquals(lg(-1391411781, -1825579414), lg(-105778670, -1825579414) - lg(1285633111, 0)) - assertEquals(lg(1573921037, -2018677385), lg(1306759468, -2018677385) - lg(-267161569, -1)) - assertEquals(lg(2075838974, -289291128), lg(618139116, -289291128) - lg(-1457699858, -1)) - assertEquals(lg(600013127, -1980710784), lg(1736445522, -1980710784) - lg(1136432395, 0)) - assertEquals(lg(-558434179, 21136449), lg(-1970971750, 21136449) - lg(-1412537571, -1)) - assertEquals(lg(-343650116, 229693364), lg(-1491842755, 229693364) - lg(-1148192639, -1)) - assertEquals(lg(1686071974, -2064363005), lg(2125082313, -2064363005) - lg(439010339, 0)) - assertEquals(lg(-1587252411, -1887690341), lg(922634658, -1887690341) - lg(-1785080227, -1)) - assertEquals(lg(-992416688, 1754335328), lg(478015362, 1754335329) - lg(1470432050, 0)) - assertEquals(lg(1718268050, -845578935), lg(-1788952896, -845578935) - lg(787746350, 0)) - assertEquals(lg(1316319511, -1479013672), lg(-1177368338, -1479013672) - lg(1801279447, 0)) - assertEquals(lg(1568876561, -2147323821), lg(1761081661, -2147323821) - lg(192205100, 0)) - assertEquals(lg(-1122491731, 1604940224), lg(261772552, 1604940225) - lg(1384264283, 0)) - assertEquals(lg(1556996455, 1018615990), lg(-1441241840, 1018615990) - lg(1296729001, 0)) - assertEquals(lg(-52258673, -155632234), lg(907527568, -155632233) - lg(959786241, 0)) - assertEquals(lg(1911811399, 1534910973), lg(1509034771, 1534910973) - lg(-402776628, -1)) - assertEquals(lg(1234505303, -718856464), lg(-344668006, -718856465) - lg(-1579173309, -1)) - assertEquals(lg(1263823751, 1792314521), lg(-2096618226, 1792314521) - lg(934525319, 0)) - assertEquals(lg(-1901870284, -977488448), lg(1861956484, -977488448) - lg(-531140528, -1)) - assertEquals(lg(170060904, -1532994269), lg(-691455907, -1532994270) - lg(-861516811, -1)) - assertEquals(lg(-417244722, -946809431), lg(-693769914, -946809431) - lg(-276525192, -1)) - assertEquals(lg(1392505816, -834216711), lg(-1698674051, -834216711) - lg(1203787429, 0)) - assertEquals(lg(339105023, -930632047), lg(1453492556, -930632047) - lg(1114387533, 0)) - assertEquals(lg(1588670098, -422836102), lg(-516102112, -422836103) - lg(-2104772210, -1)) - assertEquals(lg(-1793332542, 1839759286), lg(1194707556, 1839759286) - lg(-1306927198, -1)) - assertEquals(lg(-1933743595, -1652840750), lg(1188016800, -1652840750) - lg(-1173206901, -1)) - assertEquals(lg(1172675504, 1790839027), lg(-1268512415, 1790839027) - lg(1853779377, 0)) - assertEquals(lg(-2038245078, 275932678), lg(-777434907, 275932678) - lg(1260810171, 0)) - assertEquals(lg(-640120196, 658575618), lg(607917442, 658575619) - lg(1248037638, 0)) - assertEquals(lg(-939204613, -2089057829), lg(-1490388970, -2089057829) - lg(-551184357, -1)) - assertEquals(lg(-2089897031, 992436418), lg(-1342917439, 992436418) - lg(746979592, 0)) - assertEquals(lg(-767046771, -1192540532), lg(-1045496394, -1192540532) - lg(-278449623, -1)) - assertEquals(lg(735191894, -683257085), lg(1555450000, -683257085) - lg(820258106, 0)) - assertEquals(lg(2026420598, 481753248), lg(1022728181, 481753248) - lg(-1003692417, -1)) - assertEquals(lg(-2132649422, 1411964223), lg(2028304312, 1411964223) - lg(-134013562, -1)) - assertEquals(lg(1346424260, -217374406), lg(704117341, -217374406) - lg(-642306919, -1)) - assertEquals(lg(-692878557, 278237510), lg(313351245, 278237511) - lg(1006229802, 0)) - assertEquals(lg(-1545280043, 2054685372), lg(2076724262, 2054685372) - lg(-672962991, -1)) - assertEquals(lg(1156651977, 261806288), lg(1990098163, 261806288) - lg(833446186, 0)) - assertEquals(lg(-244547539, 1626774417), lg(1425435353, 1626774418) - lg(1669982892, 0)) - assertEquals(lg(-125857115, -1714068645), lg(2084724465, -1714068645) - lg(-2084385716, -1)) - assertEquals(lg(-2124426763, -543675020), lg(-1799809279, -543675020) - lg(324617484, 0)) - assertEquals(lg(-2145169231, -602489858), lg(1972622018, -602489858) - lg(-177176047, -1)) - assertEquals(lg(408960051, 967789979), lg(883147297, 967789979) - lg(474187246, 0)) - } - - @Test def times_*(): Unit = { - assertEquals(lg(-1056314208, 1039912134), lg(-1436299491, 1172705251) * lg(1721031968, 0)) - assertEquals(lg(15417694, -1235494072), lg(-1754547158, 1592794750) * lg(-850659149, -1)) - assertEquals(lg(-1312839754, -486483117), lg(-582562130, 1508550574) * lg(-2054981347, -1)) - assertEquals(lg(-377676239, 1969822597), lg(-517256163, 1107889737) * lg(324089381, 0)) - assertEquals(lg(-1426078720, -1379092277), lg(1862517504, -2146745095) * lg(2043533548, 0)) - assertEquals(lg(-1611894400, 514550890), lg(-1341087062, 93674761) * lg(1272468928, 0)) - assertEquals(lg(88803236, -172420721), lg(-1911825604, 1026411170) * lg(244738503, 0)) - assertEquals(lg(1486387579, 668666773), lg(2102189793, 425022510) * lg(750432219, 0)) - assertEquals(lg(913918418, 2124658288), lg(-1628887094, 2043879870) * lg(-1367964491, -1)) - assertEquals(lg(-1067082241, 864193319), lg(454909009, -1096315634) * lg(-461844145, -1)) - assertEquals(lg(949541055, 403324299), lg(-1346593793, -331776468) * lg(1495188289, 0)) - assertEquals(lg(-232871624, -1943313306), lg(39946028, -363039140) * lg(-1134101206, -1)) - assertEquals(lg(-528828160, -1884969955), lg(769959254, -432157368) * lg(-488368768, -1)) - assertEquals(lg(913322937, -2105457977), lg(1975078475, 1181124823) * lg(-1852476533, -1)) - assertEquals(lg(1594278208, 943829214), lg(-2118478876, -1521449422) * lg(-235907376, -1)) - assertEquals(lg(-50678328, 2146883835), lg(-192590815, -1552754278) * lg(990887112, 0)) - assertEquals(lg(1779498513, -1732099612), lg(-74714605, 386143916) * lg(1634792395, 0)) - assertEquals(lg(982209626, 857499597), lg(1839773441, -590412588) * lg(799604314, 0)) - assertEquals(lg(1806268816, -990479821), lg(1395571130, -1228992407) * lg(1440046952, 0)) - assertEquals(lg(1683728223, -957382628), lg(-1094818235, 1759139279) * lg(-156634285, -1)) - assertEquals(lg(-1590791694, 595489480), lg(853844787, 525523561) * lg(600761926, 0)) - assertEquals(lg(1353714367, 146465211), lg(-903115469, 793487771) * lg(1986597957, 0)) - assertEquals(lg(1421874569, -1462441210), lg(-830036223, 830164681) * lg(-1711884663, -1)) - assertEquals(lg(-962035602, -2086325336), lg(1514898873, 1802395563) * lg(1763957470, 0)) - assertEquals(lg(213232144, -1084932179), lg(-1931885288, 136587512) * lg(-241565738, -1)) - assertEquals(lg(-915935202, 1495104097), lg(571274323, 1264898114) * lg(1823828906, 0)) - assertEquals(lg(1116543789, -1473151538), lg(-15708939, -2105030313) * lg(48280153, 0)) - assertEquals(lg(-1230228445, -570579388), lg(1792017337, -1626094957) * lg(301685947, 0)) - assertEquals(lg(1335719116, 1447187791), lg(-1942632452, -691115342) * lg(-889918259, -1)) - assertEquals(lg(1398640985, -1330552693), lg(-683458011, -1409200935) * lg(-996910555, -1)) - assertEquals(lg(-402621042, 1775759707), lg(562125786, -1303526635) * lg(-1761056509, -1)) - assertEquals(lg(129149596, -78429064), lg(2115902292, -1194658096) * lg(-1549721205, -1)) - assertEquals(lg(1706925885, 1413499189), lg(1852083423, 330104035) * lg(1414822755, 0)) - assertEquals(lg(-722178384, 1850552711), lg(-1623207532, 1442771787) * lg(-948878276, -1)) - assertEquals(lg(545021767, -1389368834), lg(-898643831, 773279296) * lg(1294488911, 0)) - assertEquals(lg(1541594150, 820379725), lg(421823854, 802578424) * lg(1394107269, 0)) - assertEquals(lg(-279324848, 1175391379), lg(1589092022, 237831212) * lg(-763790472, -1)) - assertEquals(lg(2089067814, 975727054), lg(-1247207721, -370556328) * lg(1449901386, 0)) - assertEquals(lg(-1977714127, -377823390), lg(109386811, 368962517) * lg(1406834819, 0)) - assertEquals(lg(1759713497, -312922364), lg(2135299059, -798752868) * lg(-1861488893, -1)) - assertEquals(lg(1030024362, -795941843), lg(-695671854, 1917612060) * lg(2083344781, 0)) - assertEquals(lg(-704748314, 388197332), lg(250669253, -442179349) * lg(-552836178, -1)) - assertEquals(lg(758103782, -158300478), lg(1237744278, 206295616) * lg(-1547545223, -1)) - assertEquals(lg(-629736326, 810097466), lg(492775518, 1691641907) * lg(1172634963, 0)) - assertEquals(lg(610754048, 1997636055), lg(-1549380722, 49835026) * lg(-1645815552, -1)) - assertEquals(lg(1696857284, 1549588995), lg(1850430325, -1942955614) * lg(-295254732, -1)) - assertEquals(lg(-66011146, -376837532), lg(-1276671498, -1984743584) * lg(-1583554303, -1)) - assertEquals(lg(2033040344, -167450557), lg(-2127158934, -2058421178) * lg(1620104636, 0)) - assertEquals(lg(-1886196376, -31345953), lg(69958717, -772556465) * lg(21655944, 0)) - assertEquals(lg(-38147573, -1269583268), lg(406538265, -107036516) * lg(2077087683, 0)) - } - - @Test def divide_/(): Unit = { - assertEquals(IntMaxValPlus1, IntMinVal / lg(-1)) - assertEquals(lg(-1), IntMinVal / IntMaxValPlus1) - assertEquals(IntMinVal, IntMaxValPlus1 / lg(-1)) - assertEquals(lg(-1), IntMaxValPlus1 / IntMinVal) - - assertEquals(lg(1, -2147483648), MaxVal / lg(-1)) - assertEquals(MinVal, MinVal / lg(1)) - assertEquals(MinVal, MinVal / lg(-1)) - - // int32 / int32 - assertEquals(lg(1, 0), lg(-10426835, -1) / lg(-6243356, -1)) - assertEquals(lg(-291, -1), lg(49659080, 0) / lg(-170373, -1)) - assertEquals(lg(3, 0), lg(97420, 0) / lg(27521, 0)) - assertEquals(lg(26998, 0), lg(-9881291, -1) / lg(-366, -1)) - assertEquals(lg(0, 0), lg(-40, -1) / lg(81, 0)) - assertEquals(lg(0, 0), lg(-6007, -1) / lg(-326806, -1)) - assertEquals(lg(-1, -1), lg(202, 0) / lg(-112, -1)) - assertEquals(lg(0, 0), lg(0, 0) / lg(47, 0)) - assertEquals(lg(323816, 0), lg(22667160, 0) / lg(70, 0)) - assertEquals(lg(0, 0), lg(254, 0) / lg(-307349204, -1)) - assertEquals(lg(0, 0), lg(-17, -1) / lg(-44648, -1)) - assertEquals(lg(-40, -1), lg(39646, 0) / lg(-976, -1)) - assertEquals(lg(0, 0), lg(9, 0) / lg(315779722, 0)) - assertEquals(lg(0, 0), lg(-2674, -1) / lg(-3051991, -1)) - assertEquals(lg(0, 0), lg(-37697, -1) / lg(2015928, 0)) - assertEquals(lg(0, 0), lg(-13, -1) / lg(-31, -1)) - assertEquals(lg(0, 0), lg(6, 0) / lg(-334, -1)) - assertEquals(lg(8, 0), lg(-15989, -1) / lg(-1918, -1)) - assertEquals(lg(8746, 0), lg(-113261535, -1) / lg(-12950, -1)) - assertEquals(lg(55322, 0), lg(-6362112, -1) / lg(-115, -1)) - assertEquals(lg(0, 0), lg(455, 0) / lg(13919, 0)) - assertEquals(lg(36190, 0), lg(293468259, 0) / lg(8109, 0)) - assertEquals(lg(1, 0), lg(-48287007, -1) / lg(-27531186, -1)) - assertEquals(lg(349634, 0), lg(1048904, 0) / lg(3, 0)) - assertEquals(lg(0, 0), lg(-34, -1) / lg(3949717, 0)) - assertEquals(lg(-1, -1), lg(1449, 0) / lg(-983, -1)) - assertEquals(lg(-18537151, -1), lg(18537151, 0) / lg(-1, -1)) - assertEquals(lg(0, 0), lg(14037, 0) / lg(23645, 0)) - assertEquals(lg(-4, -1), lg(1785, 0) / lg(-398, -1)) - assertEquals(lg(0, 0), lg(346, 0) / lg(2198158, 0)) - assertEquals(lg(-802, -1), lg(-3517419, -1) / lg(4381, 0)) - assertEquals(lg(-6, -1), lg(6, 0) / lg(-1, -1)) - assertEquals(lg(39, 0), lg(-822, -1) / lg(-21, -1)) - assertEquals(lg(0, 0), lg(3629, 0) / lg(282734, 0)) - assertEquals(lg(-92367, -1), lg(-278856469, -1) / lg(3019, 0)) - assertEquals(lg(0, 0), lg(-13, -1) / lg(37, 0)) - assertEquals(lg(0, 0), lg(-4, -1) / lg(47150459, 0)) - assertEquals(lg(0, 0), lg(-26, -1) / lg(-210691, -1)) - assertEquals(lg(0, 0), lg(-21294, -1) / lg(156839456, 0)) - assertEquals(lg(0, 0), lg(-5, -1) / lg(-25644, -1)) - assertEquals(lg(0, 0), lg(-1009, -1) / lg(28100, 0)) - assertEquals(lg(-857, -1), lg(16282815, 0) / lg(-18989, -1)) - assertEquals(lg(-7, -1), lg(-2201086, -1) / lg(276963, 0)) - assertEquals(lg(-300, -1), lg(11412578, 0) / lg(-37989, -1)) - assertEquals(lg(0, 0), lg(8406900, 0) / lg(239727371, 0)) - assertEquals(lg(0, 0), lg(-1, -1) / lg(-479069, -1)) - assertEquals(lg(0, 0), lg(4, 0) / lg(-21776, -1)) - assertEquals(lg(-16812960, -1), lg(-16812960, -1) / lg(1, 0)) - assertEquals(lg(0, 0), lg(10873, 0) / lg(57145, 0)) - assertEquals(lg(0, 0), lg(-1, -1) / lg(-7, -1)) - - // int32 / int53 - assertEquals(lg(0, 0), lg(-6975858, -1) / lg(42227636, 14)) - assertEquals(lg(0, 0), lg(-1, -1) / lg(370644892, 82735)) - assertEquals(lg(0, 0), lg(43, 0) / lg(-1602218381, 49)) - assertEquals(lg(0, 0), lg(4063968, 0) / lg(973173538, 23810)) - assertEquals(lg(0, 0), lg(-388987094, -1) / lg(-241988155, 1723)) - assertEquals(lg(0, 0), lg(5939808, 0) / lg(-1882484681, 12)) - assertEquals(lg(0, 0), lg(7, 0) / lg(-385609304, 1342)) - assertEquals(lg(0, 0), lg(-1175803932, -1) / lg(297649103, 2408)) - assertEquals(lg(0, 0), lg(464610492, 0) / lg(829919518, 2777)) - assertEquals(lg(0, 0), lg(214483, 0) / lg(1502817270, 8078)) - - // int32 / big - assertEquals(lg(0, 0), lg(211494165, 0) / lg(1365318534, 14804989)) - assertEquals(lg(0, 0), lg(5353, 0) / lg(-1032992082, -394605386)) - assertEquals(lg(0, 0), lg(2926, 0) / lg(26982087, -226814570)) - assertEquals(lg(0, 0), lg(-6, -1) / lg(-1339229562, -580578613)) - assertEquals(lg(0, 0), lg(-8, -1) / lg(-108570365, 4920615)) - assertEquals(lg(0, 0), lg(-585878041, -1) / lg(551925027, -1296114209)) - assertEquals(lg(0, 0), lg(-4, -1) / lg(474545806, 64068407)) - assertEquals(lg(0, 0), lg(34, 0) / lg(-137127086, -18652281)) - assertEquals(lg(0, 0), lg(785315, 0) / lg(-881374655, 29722835)) - assertEquals(lg(0, 0), lg(713146, 0) / lg(1442548271, 2727525)) - - // int53 / int32 - assertEquals(lg(-578207, -1), lg(397755625, 53271) / lg(-395701427, -1)) - assertEquals(lg(-560062154, 0), lg(-1680186460, 2) / lg(3, 0)) - assertEquals(lg(-926675094, 18), lg(1514942014, 56) / lg(3, 0)) - assertEquals(lg(-162400270, -1), lg(713597492, 1154) / lg(-30524, -1)) - assertEquals(lg(-9, -1), lg(2028377478, 1) / lg(-691707459, -1)) - assertEquals(lg(135006, 0), lg(1387175556, 73) / lg(2332622, 0)) - assertEquals(lg(-200274428, -13), lg(1756997282, 1397) / lg(-116, -1)) - assertEquals(lg(1125157, 0), lg(-1655346723, 0) / lg(2346, 0)) - assertEquals(lg(997096, 0), lg(198249458, 5686) / lg(24492497, 0)) - assertEquals(lg(1369365326, -302), lg(873090497, 11162) / lg(-37, -1)) - assertEquals(lg(-2166511, -1), lg(360057887, 3519) / lg(-6976354, -1)) - assertEquals(lg(1680790298, -2), lg(1115898639, 48) / lg(-30, -1)) - assertEquals(lg(92036331, 1), lg(154624251, 955) / lg(935, 0)) - assertEquals(lg(23215066, 0), lg(806830498, 1063) / lg(196698, 0)) - assertEquals(lg(-13221428, -1), lg(-220365267, 21359) / lg(-6938757, -1)) - assertEquals(lg(-973041595, -2009), lg(759822848, 648657) / lg(-323, -1)) - assertEquals(lg(171873494, 1659), lg(-1180673754, 486098) / lg(293, 0)) - assertEquals(lg(1583541189, 785), lg(1387172319, 769661) / lg(980, 0)) - assertEquals(lg(-917576, -1), lg(-305851327, 2) / lg(-13709, -1)) - assertEquals(lg(456092, 0), lg(577374631, 17) / lg(161353, 0)) - assertEquals(lg(404991630, 376), lg(809983260, 752) / lg(2, 0)) - assertEquals(lg(495082175, 39), lg(495082175, 39) / lg(1, 0)) - assertEquals(lg(90893135, 0), lg(1455620681, 30929) / lg(1461502, 0)) - assertEquals(lg(799104733, 0), lg(1388707384, 34362) / lg(184688, 0)) - assertEquals(lg(1094556328, -70011), lg(2105854641, 140021) / lg(-2, -1)) - assertEquals(lg(-1819673734, 1), lg(1310105355, 427420) / lg(271150, 0)) - assertEquals(lg(-119338773, -6), lg(-236557650, 35455) / lg(-7052, -1)) - assertEquals(lg(32825, 0), lg(-1127581476, 0) / lg(96492, 0)) - assertEquals(lg(-57018115, -1), lg(2004387480, 7243) / lg(-545624, -1)) - assertEquals(lg(-5950946, -1), lg(381447319, 2213) / lg(-1597249, -1)) - assertEquals(lg(-811421531, -4249), lg(-1860702702, 12744) / lg(-3, -1)) - assertEquals(lg(4741011, 0), lg(-548164065, 6487) / lg(5877480, 0)) - assertEquals(lg(-1064193809, 45), lg(-476290317, 131491) / lg(2874, 0)) - assertEquals(lg(228327608, 0), lg(499912484, 1) / lg(21, 0)) - assertEquals(lg(99111506, 0), lg(-1509435894, 8467) / lg(366943, 0)) - assertEquals(lg(-1209485521, -1), lg(-1580093356, 5) / lg(-20, -1)) - assertEquals(lg(-319956618, -1), lg(1299112295, 55074) / lg(-739295, -1)) - assertEquals(lg(-62197, -1), lg(-1405948570, 43) / lg(-3015755, -1)) - assertEquals(lg(9087, 0), lg(1405130313, 57) / lg(27093454, 0)) - assertEquals(lg(345582531, 0), lg(-1804200888, 1989226) / lg(24722497, 0)) - assertEquals(lg(-1424974, -1), lg(-1642507127, 886) / lg(-2672324, -1)) - assertEquals(lg(1991351, 0), lg(-1276796892, 35) / lg(77004, 0)) - assertEquals(lg(1193137, 0), lg(-1200759296, 816) / lg(2939970, 0)) - assertEquals(lg(573585390, 0), lg(399171813, 123795) / lg(926969, 0)) - assertEquals(lg(1683063904, -942), lg(1649267984, 229752) / lg(-244, -1)) - assertEquals(lg(-6019138, -1), lg(-387146187, 7364) / lg(-5255245, -1)) - assertEquals(lg(-123416174, 28), lg(149703916, 19121) / lg(660, 0)) - assertEquals(lg(-40732946, -1), lg(-1582312743, 7920) / lg(-835168, -1)) - assertEquals(lg(715821610, 298), lg(1431643220, 596) / lg(2, 0)) - assertEquals(lg(-570078780, -1), lg(-1717918737, 8458) / lg(-63727, -1)) - - // int53 / int53 - assertEquals(lg(1, 0), lg(-1232398900, 28871) / lg(13989713, 22345)) - assertEquals(lg(0, 0), lg(-916994839, 12266) / lg(1713571419, 15301)) - assertEquals(lg(32, 0), lg(1133414946, 229) / lg(256531666, 7)) - assertEquals(lg(368, 0), lg(134792921, 3907) / lg(-1656790262, 10)) - assertEquals(lg(1, 0), lg(1532393452, 52260) / lg(-701373106, 31864)) - assertEquals(lg(0, 0), lg(193990135, 1460) / lg(867607428, 6918)) - assertEquals(lg(0, 0), lg(867672590, 1) / lg(-1315044816, 987593)) - assertEquals(lg(0, 0), lg(-978844610, 2) / lg(720710523, 209)) - assertEquals(lg(0, 0), lg(-297570329, 1) / lg(-2127979750, 195738)) - assertEquals(lg(0, 0), lg(-1035330427, 5) / lg(-2091513925, 70)) - assertEquals(lg(0, 0), lg(1037142987, 15) / lg(-485498951, 30819)) - assertEquals(lg(0, 0), lg(744551901, 15) / lg(-604684037, 1587)) - assertEquals(lg(67766, 0), lg(1341710951, 232724) / lg(1864827988, 3)) - assertEquals(lg(694, 0), lg(-409318148, 157818) / lg(517165426, 227)) - assertEquals(lg(1, 0), lg(1908192460, 110512) / lg(-61974596, 95795)) - assertEquals(lg(0, 0), lg(946490654, 498) / lg(-1889366637, 1163)) - assertEquals(lg(12, 0), lg(1765257877, 34422) / lg(728455544, 2851)) - assertEquals(lg(0, 0), lg(-1725136864, 84) / lg(1122821677, 14720)) - assertEquals(lg(1, 0), lg(1854803780, 2) / lg(-302860117, 1)) - assertEquals(lg(131, 0), lg(380756581, 107) / lg(-806772264, 0)) - assertEquals(lg(0, 0), lg(1868292481, 1134) / lg(691774521, 33775)) - assertEquals(lg(0, 0), lg(-1515810361, 98) / lg(2038289788, 198)) - assertEquals(lg(315, 0), lg(-1943767475, 31777) / lg(-1513506636, 100)) - assertEquals(lg(0, 0), lg(1508904915, 18) / lg(1834666309, 976)) - assertEquals(lg(1, 0), lg(1430753947, 3772) / lg(-1853122145, 3615)) - assertEquals(lg(2340149, 0), lg(-1654852151, 1195820) / lg(-2100231332, 0)) - assertEquals(lg(0, 0), lg(1011710080, 18) / lg(-616681449, 57)) - assertEquals(lg(14, 0), lg(-495370429, 356832) / lg(-34555439, 25233)) - assertEquals(lg(131, 0), lg(744211838, 511) / lg(-475809581, 3)) - assertEquals(lg(0, 0), lg(1135128265, 67) / lg(163864249, 972)) - assertEquals(lg(1, 0), lg(954856869, 5120) / lg(1474096435, 3606)) - assertEquals(lg(0, 0), lg(1544045220, 1) / lg(85376495, 2353)) - assertEquals(lg(8, 0), lg(1367437144, 53) / lg(2010850631, 6)) - assertEquals(lg(0, 0), lg(-1398730804, 13) / lg(-2055007528, 52)) - assertEquals(lg(0, 0), lg(1598156017, 13) / lg(-1006929331, 160)) - assertEquals(lg(0, 0), lg(738323529, 41) / lg(-1508093984, 10361)) - assertEquals(lg(0, 0), lg(-1788797806, 31) / lg(588557582, 575930)) - assertEquals(lg(76, 0), lg(-913009845, 1002) / lg(204577043, 13)) - assertEquals(lg(0, 0), lg(1908599465, 6) / lg(1058868127, 3383)) - assertEquals(lg(0, 0), lg(-634312634, 75) / lg(-850292534, 332928)) - assertEquals(lg(0, 0), lg(-1679695022, 148) / lg(-1395453213, 912)) - assertEquals(lg(0, 0), lg(456310936, 71) / lg(487720864, 1590813)) - assertEquals(lg(0, 0), lg(-1724925398, 0) / lg(-273170277, 38)) - assertEquals(lg(0, 0), lg(-6742076, 15) / lg(192793866, 175)) - assertEquals(lg(50, 0), lg(337939061, 2094205) / lg(880147944, 41142)) - assertEquals(lg(0, 0), lg(-998413092, 0) / lg(-1758700885, 29)) - assertEquals(lg(0, 0), lg(1986052307, 3) / lg(-2092246422, 47)) - assertEquals(lg(0, 0), lg(-109615093, 1) / lg(-2066395387, 20016)) - assertEquals(lg(127, 0), lg(-1147373454, 901) / lg(313439710, 7)) - assertEquals(lg(0, 0), lg(-792716629, 66379) / lg(2017337246, 250513)) - - // int53 / big - assertEquals(lg(0, 0), lg(291278707, 13808) / lg(941639833, -14430466)) - assertEquals(lg(0, 0), lg(-857819626, 204588) / lg(-1909684886, -709519130)) - assertEquals(lg(0, 0), lg(-978105991, 7435) / lg(-306472275, 158306339)) - assertEquals(lg(0, 0), lg(75049741, 248171) / lg(-1574105194, 64879257)) - assertEquals(lg(0, 0), lg(136051120, 621) / lg(-1671784392, 102642869)) - assertEquals(lg(0, 0), lg(-448460356, 2858) / lg(71740423, -16715717)) - assertEquals(lg(0, 0), lg(-1266403435, 2) / lg(-1022999838, 25812014)) - assertEquals(lg(0, 0), lg(552733494, 22) / lg(241731505, -33191170)) - assertEquals(lg(0, 0), lg(1366167794, 115591) / lg(191854687, -2136953)) - assertEquals(lg(0, 0), lg(1329114439, 80951) / lg(-51187101, 1471052997)) - - // big / int32 - assertEquals(lg(422668131, 6), lg(-1495113094, 168518701) / lg(27633219, 0)) - assertEquals(lg(932715295, 204683), lg(-1211847018, -609137255) / lg(-2976, -1)) - assertEquals(lg(189814434, 0), lg(-457166837, -15040808) / lg(-340331202, -1)) - assertEquals(lg(-1116045071, -1131771), lg(-104570473, -117704108) / lg(104, 0)) - assertEquals(lg(-784306379, 14408), lg(453828098, -10187034) / lg(-707, -1)) - assertEquals(lg(-284027201, 2002401), lg(1911518920, 168201762) / lg(84, 0)) - assertEquals(lg(-862273257, -2), lg(610589058, 36481453) / lg(-30381877, -1)) - assertEquals(lg(-761280647, -71), lg(410700182, 503953004) / lg(-7181145, -1)) - assertEquals(lg(-1212582262, -2538), lg(194917334, -8806907) / lg(3471, 0)) - assertEquals(lg(-1201233065, 4), lg(852311155, 9671380) / lg(2048884, 0)) - assertEquals(lg(1324107666, 0), lg(-1028681544, 4163983) / lg(13506586, 0)) - assertEquals(lg(-354367044, 6361111), lg(-708734088, 12722223) / lg(2, 0)) - assertEquals(lg(-292170842, -76359), lg(1693696214, 18402294) / lg(-241, -1)) - assertEquals(lg(2104544550, -41349584), lg(-1932788158, 206747917) / lg(-5, -1)) - assertEquals(lg(-1928473941, -17816), lg(1427262980, -60732866) / lg(3409, 0)) - assertEquals(lg(-1929237164, -681), lg(-677896940, 2512898) / lg(-3693, -1)) - assertEquals(lg(1550060300, -35), lg(-926729663, -9677195) / lg(279372, 0)) - assertEquals(lg(-1706875941, 0), lg(-405257725, -2271799) / lg(-3770075, -1)) - assertEquals(lg(1540708852, 10909), lg(-1893733008, -6491069) / lg(-595, -1)) - assertEquals(lg(-1563665409, -358), lg(-1343018634, -2584815) / lg(7233, 0)) - assertEquals(lg(278715917, -374389), lg(-1224507547, 122799570) / lg(-328, -1)) - assertEquals(lg(1421525100, 0), lg(-2082712791, -15998594) / lg(-48337828, -1)) - assertEquals(lg(1574832373, -2193811), lg(-2147318181, -32907160) / lg(15, 0)) - assertEquals(lg(-1260116915, -61610), lg(1074158039, 118905936) / lg(-1930, -1)) - assertEquals(lg(130856059, -15612), lg(1270835097, -2201288) / lg(141, 0)) - assertEquals(lg(-110248455, 2347), lg(320077861, -446108079) / lg(-189997, -1)) - assertEquals(lg(-1659387265, 122), lg(1075676628, 54005547) / lg(440453, 0)) - assertEquals(lg(-144903831, 18), lg(-1800001035, 54578889) / lg(2877683, 0)) - assertEquals(lg(-1312994937, -23952), lg(-654120591, 33364168) / lg(-1393, -1)) - assertEquals(lg(-178073210, -1), lg(302695822, -2432394) / lg(58667176, 0)) - assertEquals(lg(1316938460, 142), lg(523451067, -54366538) / lg(-382038, -1)) - assertEquals(lg(-1457978633, 17556853), lg(-78968601, 52670560) / lg(3, 0)) - assertEquals(lg(-1760960552, 505129611), lg(-773046192, -1010259224) / lg(-2, -1)) - assertEquals(lg(1210355204, 2314), lg(1515488136, -21874592) / lg(-9452, -1)) - assertEquals(lg(-1625685934, 862807773), lg(-1043595428, -1725615548) / lg(-2, -1)) - assertEquals(lg(184379181, 4), lg(-1217231978, 1516494005) / lg(375097846, 0)) - assertEquals(lg(1243945230, 0), lg(-1873413508, -236381131) / lg(-816152673, -1)) - assertEquals(lg(-1540093941, -876), lg(265593875, 26513736) / lg(-30289, -1)) - assertEquals(lg(-1304692919, 543912), lg(106204837, -839801203) / lg(-1544, -1)) - assertEquals(lg(-806250591, 23), lg(815576040, -55524975) / lg(-2331779, -1)) - assertEquals(lg(-2106907248, -3), lg(-2053929476, -1795047022) / lg(720742474, 0)) - assertEquals(lg(893100234, -124), lg(1552099699, 65024502) / lg(-525272, -1)) - assertEquals(lg(-1109915706, 1255), lg(-194253417, -12405472) / lg(-9879, -1)) - assertEquals(lg(-1177955013, 0), lg(412309016, 112344162) / lg(154800321, 0)) - assertEquals(lg(-1975688052, -51023804), lg(343591192, -102047607) / lg(2, 0)) - assertEquals(lg(-728332094, -309956), lg(1756765281, 8058834) / lg(-26, -1)) - assertEquals(lg(10173004, 1227), lg(1762668787, -960735493) / lg(-782994, -1)) - assertEquals(lg(1157067129, 5766), lg(1523935530, -109345767) / lg(-18963, -1)) - assertEquals(lg(1226263794, 42306948), lg(-1256703941, 1438436241) / lg(34, 0)) - assertEquals(lg(1502167534, -439314), lg(-444491016, -6150392) / lg(14, 0)) - - // big / int53 - assertEquals(lg(88399, 0), lg(-1883357942, 360257606) / lg(1478768728, 4075)) - assertEquals(lg(-45459, -1), lg(-1991900757, -48856999) / lg(-1087694619, 1074)) - assertEquals(lg(4395497, 0), lg(518426119, 218946975) / lg(-808940852, 49)) - assertEquals(lg(3198134, 0), lg(-946567777, 600381050) / lg(-1165957306, 187)) - assertEquals(lg(470, 0), lg(257885254, 845979705) / lg(792779187, 1798424)) - assertEquals(lg(92, 0), lg(1278680372, 6485140) / lg(1376461023, 70263)) - assertEquals(lg(167728, 0), lg(1445602310, 420550818) / lg(1397186900, 2507)) - assertEquals(lg(25700177, 0), lg(1822058703, 522114268) / lg(1355449555, 20)) - assertEquals(lg(-35822646, -1), lg(532749659, -130990067) / lg(-1474774415, 3)) - assertEquals(lg(-348, -1), lg(1329707986, -2121642) / lg(-63366094, 6086)) - assertEquals(lg(-2179, -1), lg(1028585430, -118524228) / lg(1655878874, 54392)) - assertEquals(lg(1187, 0), lg(203502475, 42252914) / lg(36519512, 35581)) - assertEquals(lg(3223, 0), lg(341088508, 35053507) / lg(917391400, 10874)) - assertEquals(lg(23608500, 0), lg(1454135412, 69933847) / lg(-162213744, 2)) - assertEquals(lg(7286803, 0), lg(1674604578, 10565585) / lg(1932570831, 1)) - assertEquals(lg(-137450, -1), lg(-1910257093, -16610962) / lg(-640594227, 120)) - assertEquals(lg(114592, 0), lg(1080864951, 17606069) / lg(-1542196664, 153)) - assertEquals(lg(61, 0), lg(-1419644278, 13937517) / lg(-919779905, 227700)) - assertEquals(lg(-247360, -1), lg(-1958380469, -855713410) / lg(1631833189, 3459)) - assertEquals(lg(-61725, -1), lg(1951473618, -4122677) / lg(-899615165, 66)) - assertEquals(lg(2226, 0), lg(1521276132, 182952467) / lg(346742782, 82171)) - assertEquals(lg(-997, -1), lg(-1003647481, -7808320) / lg(-228453385, 7826)) - assertEquals(lg(36, 0), lg(-875689390, 4467236) / lg(-590010750, 120938)) - assertEquals(lg(56005, 0), lg(1189085620, 611543209) / lg(1619962756, 10919)) - assertEquals(lg(-90057, -1), lg(-1072173311, -18503031) / lg(1971480267, 205)) - assertEquals(lg(-9, -1), lg(767303802, -3407362) / lg(-339044225, 352939)) - assertEquals(lg(62240, 0), lg(427996893, 482974074) / lg(-736462105, 7759)) - assertEquals(lg(-1774, -1), lg(842450255, -4396651) / lg(859272322, 2477)) - assertEquals(lg(-153400, -1), lg(1640433988, -2618618) / lg(302672196, 17)) - assertEquals(lg(2145, 0), lg(-361322518, 63967358) / lg(-1922353888, 29810)) - assertEquals(lg(106042, 0), lg(-1774479550, 43276853) / lg(472456506, 408)) - assertEquals(lg(-381407, -1), lg(-1756338345, -38928780) / lg(283612141, 102)) - assertEquals(lg(1217514, 0), lg(-495049835, 37161263) / lg(-2052025512, 30)) - assertEquals(lg(-17, -1), lg(1606509747, -10876159) / lg(1068727249, 635715)) - assertEquals(lg(4880327, 0), lg(-1857686692, 1918485655) / lg(454913535, 393)) - assertEquals(lg(-1023070, -1), lg(-502107392, -511268482) / lg(-1118977400, 499)) - assertEquals(lg(439, 0), lg(-909192131, 45216813) / lg(1442986382, 102923)) - assertEquals(lg(2171202, 0), lg(259184089, 14858724) / lg(-671961291, 6)) - assertEquals(lg(-5332527, -1), lg(1737846340, -614952982) / lg(1379175047, 115)) - assertEquals(lg(-435180, -1), lg(-406629212, -528407898) / lg(973577032, 1214)) - assertEquals(lg(27837, 0), lg(-597461306, 538945619) / lg(-1867966522, 19360)) - assertEquals(lg(-396, -1), lg(-1906945200, -371170760) / lg(151858506, 936902)) - assertEquals(lg(-115583279, -1), lg(-1366510, -207691415) / lg(-872314548, 1)) - assertEquals(lg(-6783543, -1), lg(-1280665444, -104856505) / lg(1964875665, 15)) - assertEquals(lg(-1464006069, -1), lg(897601097, -1352132581) / lg(-328204224, 0)) - assertEquals(lg(11599107, 0), lg(-496529216, 32992512) / lg(-668292521, 2)) - assertEquals(lg(842, 0), lg(1819966537, 311969505) / lg(-879441284, 370147)) - assertEquals(lg(43514, 0), lg(433235702, 408255734) / lg(573404298, 9382)) - assertEquals(lg(-230, -1), lg(1693350453, -4127304) / lg(-1671879801, 17931)) - assertEquals(lg(249094, 0), lg(-492682302, 64433722) / lg(-1408841594, 258)) - - // big / big - assertEquals(lg(-10, -1), lg(1450795502, -706709103) / lg(742056886, 64843937)) - assertEquals(lg(0, 0), lg(-392893244, 72026637) / lg(1419676270, 875736789)) - assertEquals(lg(-2, -1), lg(-1861146463, 8382761) / lg(-724412724, -3000735)) - assertEquals(lg(0, 0), lg(1373482238, 23344691) / lg(1835527248, -294342355)) - assertEquals(lg(-37, -1), lg(1956796392, 107480459) / lg(-560958184, -2839471)) - assertEquals(lg(3, 0), lg(422228275, 30436377) / lg(-2023395425, 8226201)) - assertEquals(lg(-3, -1), lg(1747624836, -215352612) / lg(-1349940168, 58723974)) - assertEquals(lg(2, 0), lg(-583006891, 16111063) / lg(1853686630, 5479773)) - assertEquals(lg(0, 0), lg(1498104050, 7322401) / lg(-407388940, 2141575618)) - assertEquals(lg(5, 0), lg(1943726712, 869895175) / lg(-627430826, 169278540)) - assertEquals(lg(0, 0), lg(1872895982, 98966340) / lg(1347573135, 529034148)) - assertEquals(lg(-2, -1), lg(16010610, 187913494) / lg(-848952152, -81951424)) - assertEquals(lg(0, 0), lg(830929771, -4393252) / lg(1829525088, 52659897)) - assertEquals(lg(22, 0), lg(-2093526384, 133319293) / lg(-464927151, 6049576)) - assertEquals(lg(0, 0), lg(1056318793, 13467735) / lg(1970348162, -672507521)) - assertEquals(lg(0, 0), lg(-28853693, -169722715) / lg(-83877421, 770900857)) - assertEquals(lg(-27, -1), lg(1743854071, -302158995) / lg(80117835, 11113120)) - assertEquals(lg(-6, -1), lg(635796581, -146765250) / lg(441664676, 23716738)) - assertEquals(lg(0, 0), lg(-1048312948, -37662905) / lg(1319664078, 208772026)) - assertEquals(lg(0, 0), lg(-784292680, -14102823) / lg(2037268040, 744987722)) - assertEquals(lg(176, 0), lg(-1116104092, -2073525743) / lg(1766685765, -11731135)) - assertEquals(lg(0, 0), lg(-1991687284, 19448294) / lg(-1731357606, -202272807)) - assertEquals(lg(6, 0), lg(-2042068328, -52956481) / lg(370482897, -7759903)) - assertEquals(lg(1, 0), lg(334395247, 1906338595) / lg(342095090, 1248830168)) - assertEquals(lg(0, 0), lg(-309616588, 44123460) / lg(2040055580, -476494291)) - assertEquals(lg(0, 0), lg(137178123, 36336421) / lg(-360221107, -515689970)) - assertEquals(lg(0, 0), lg(-422856762, -16760844) / lg(-334268074, -43984484)) - assertEquals(lg(0, 0), lg(-24820293, 25823996) / lg(390711705, 288223876)) - assertEquals(lg(0, 0), lg(1170265006, 2998984) / lg(-134995170, -2123267074)) - assertEquals(lg(0, 0), lg(-1501380980, -6088910) / lg(-1175861016, -56027408)) - assertEquals(lg(-56, -1), lg(307880183, 196786483) / lg(-1107761890, -3480429)) - assertEquals(lg(0, 0), lg(-588606997, -37732967) / lg(-1124435958, -77404915)) - assertEquals(lg(108, 0), lg(90560661, 990295925) / lg(731139348, 9165999)) - assertEquals(lg(0, 0), lg(46312609, -28251908) / lg(1279863155, -519028300)) - assertEquals(lg(0, 0), lg(1123427761, 55212863) / lg(-1081219733, 233090714)) - assertEquals(lg(0, 0), lg(1447869812, -3646400) / lg(-1237950546, -27122943)) - assertEquals(lg(-13, -1), lg(-1399920635, 110072031) / lg(-398678056, -8069387)) - assertEquals(lg(0, 0), lg(513704441, 14319377) / lg(-796719013, 260081997)) - assertEquals(lg(8, 0), lg(166886349, -190148673) / lg(68245235, -21656365)) - assertEquals(lg(0, 0), lg(-1594024534, -144937584) / lg(177399758, 200473672)) - assertEquals(lg(-1, -1), lg(447753993, -23591908) / lg(1399162166, 12505918)) - assertEquals(lg(0, 0), lg(1500283330, 5361180) / lg(348398676, 156400271)) - assertEquals(lg(-1, -1), lg(-216115001, 670826068) / lg(1759253954, -470062110)) - assertEquals(lg(0, 0), lg(-1251659767, 18831569) / lg(-669341445, -34474821)) - assertEquals(lg(31, 0), lg(817032953, 218701872) / lg(-176557210, 6899121)) - assertEquals(lg(-19, -1), lg(1365998269, 613319842) / lg(319204438, -30758748)) - assertEquals(lg(0, 0), lg(-428500325, 6610536) / lg(-46648893, -105360271)) - assertEquals(lg(0, 0), lg(784528299, -6958267) / lg(1370662827, -774132635)) - assertEquals(lg(-2, -1), lg(-769114167, 137614183) / lg(-929091402, -67103082)) - assertEquals(lg(8, 0), lg(1810734914, 124115952) / lg(1149563530, 15197570)) - } - - @Test def modulo_%(): Unit = { - assertEquals(lg(0), IntMinVal % lg(-1)) - assertEquals(lg(0), IntMinVal % IntMaxValPlus1) - assertEquals(lg(0), IntMaxValPlus1 % lg(-1)) - assertEquals(lg(0), IntMaxValPlus1 % IntMinVal) - - assertEquals(lg(0), MaxVal % lg(-1)) - assertEquals(lg(0), MinVal % lg(1)) - assertEquals(lg(0), MinVal % lg(-1)) - - assertEquals(lg(-1, 2147483647), MaxVal % MinVal) - assertEquals(lg(0), MaxVal % MaxVal) - assertEquals(lg(0), MinVal % MinVal) - assertEquals(lg(-1), MinVal % MaxVal) - - // int32 % int32 - assertEquals(lg(880, 0), lg(880, 0) % lg(-219594, -1)) - assertEquals(lg(-27, -1), lg(-49125, -1) % lg(98, 0)) - assertEquals(lg(-1194, -1), lg(-1922504, -1) % lg(4195, 0)) - assertEquals(lg(3, 0), lg(3, 0) % lg(7963, 0)) - assertEquals(lg(-626, -1), lg(-626, -1) % lg(-484628621, -1)) - assertEquals(lg(11315, 0), lg(11315, 0) % lg(-3914076, -1)) - assertEquals(lg(26241, 0), lg(15712341, 0) % lg(-1045740, -1)) - assertEquals(lg(-507, -1), lg(-855439, -1) % lg(5213, 0)) - assertEquals(lg(-259, -1), lg(-101026259, -1) % lg(-500, -1)) - assertEquals(lg(27720977, 0), lg(27720977, 0) % lg(-42317657, -1)) - assertEquals(lg(1, 0), lg(25954, 0) % lg(-3, -1)) - assertEquals(lg(6724180, 0), lg(338447650, 0) % lg(-8505730, -1)) - assertEquals(lg(10488, 0), lg(23967, 0) % lg(-13479, -1)) - assertEquals(lg(1, 0), lg(885202, 0) % lg(-3, -1)) - assertEquals(lg(0, 0), lg(692795590, 0) % lg(-10, -1)) - assertEquals(lg(-1, -1), lg(-1, -1) % lg(156, 0)) - assertEquals(lg(388, 0), lg(388, 0) % lg(189523294, 0)) - assertEquals(lg(352, 0), lg(352, 0) % lg(-3257, -1)) - assertEquals(lg(-9, -1), lg(-9, -1) % lg(14653, 0)) - assertEquals(lg(-1, -1), lg(-258745, -1) % lg(8, 0)) - assertEquals(lg(-21023, -1), lg(-206976653, -1) % lg(34321, 0)) - assertEquals(lg(-1, -1), lg(-1, -1) % lg(-971, -1)) - assertEquals(lg(59, 0), lg(59, 0) % lg(388, 0)) - assertEquals(lg(0, 0), lg(-7, -1) % lg(1, 0)) - assertEquals(lg(12, 0), lg(77, 0) % lg(13, 0)) - assertEquals(lg(224246, 0), lg(224246, 0) % lg(719055, 0)) - assertEquals(lg(-61296, -1), lg(-61296, -1) % lg(-135723660, -1)) - assertEquals(lg(549465, 0), lg(6897809, 0) % lg(793543, 0)) - assertEquals(lg(45, 0), lg(45, 0) % lg(984210147, 0)) - assertEquals(lg(0, 0), lg(-64, -1) % lg(1, 0)) - assertEquals(lg(2, 0), lg(379611734, 0) % lg(4, 0)) - assertEquals(lg(0, 0), lg(0, 0) % lg(-263, -1)) - assertEquals(lg(29, 0), lg(29, 0) % lg(-117, -1)) - assertEquals(lg(24, 0), lg(245094, 0) % lg(-70, -1)) - assertEquals(lg(0, 0), lg(0, 0) % lg(5, 0)) - assertEquals(lg(2, 0), lg(2, 0) % lg(47787927, 0)) - assertEquals(lg(-124, -1), lg(-124, -1) % lg(-22714040, -1)) - assertEquals(lg(412, 0), lg(412, 0) % lg(-17176, -1)) - assertEquals(lg(-11860, -1), lg(-11860, -1) % lg(9506787, 0)) - assertEquals(lg(-31, -1), lg(-31, -1) % lg(-1544676, -1)) - assertEquals(lg(-3, -1), lg(-1990315281, -1) % lg(-7, -1)) - assertEquals(lg(99, 0), lg(99, 0) % lg(-277, -1)) - assertEquals(lg(-86, -1), lg(-29227, -1) % lg(-161, -1)) - assertEquals(lg(106, 0), lg(106, 0) % lg(-47032956, -1)) - assertEquals(lg(18, 0), lg(18, 0) % lg(510836179, 0)) - assertEquals(lg(2, 0), lg(3543112, 0) % lg(10, 0)) - assertEquals(lg(534271, 0), lg(3547603, 0) % lg(-1506666, -1)) - assertEquals(lg(-16361, -1), lg(-16361, -1) % lg(10637613, 0)) - assertEquals(lg(8, 0), lg(606879016, 0) % lg(-16, -1)) - assertEquals(lg(-1, -1), lg(-1, -1) % lg(46424570, 0)) - - // int32 % int53 - assertEquals(lg(-3, -1), lg(-3, -1) % lg(206801065, 1)) - assertEquals(lg(-57756, -1), lg(-57756, -1) % lg(-1211050362, 13)) - assertEquals(lg(0, 0), lg(0, 0) % lg(-475702596, 10040)) - assertEquals(lg(423524, 0), lg(423524, 0) % lg(-2084961556, 16)) - assertEquals(lg(38317, 0), lg(38317, 0) % lg(-1699004544, 24)) - assertEquals(lg(60291, 0), lg(60291, 0) % lg(-458289291, 56)) - assertEquals(lg(1, 0), lg(1, 0) % lg(-1247681936, 1229953)) - assertEquals(lg(296788, 0), lg(296788, 0) % lg(183245860, 52)) - assertEquals(lg(-2005515, -1), lg(-2005515, -1) % lg(331735459, 17)) - assertEquals(lg(-179812, -1), lg(-179812, -1) % lg(-853047550, 5154)) - assertEquals(lg(-3678, -1), lg(-3678, -1) % lg(1751271067, 243605)) - assertEquals(lg(-93867, -1), lg(-93867, -1) % lg(-1925367590, 42)) - assertEquals(lg(7600917, 0), lg(7600917, 0) % lg(-1807424604, 95574)) - assertEquals(lg(300012, 0), lg(300012, 0) % lg(1951216728, 101)) - assertEquals(lg(-6347, -1), lg(-6347, -1) % lg(-438713154, 23)) - assertEquals(lg(-41, -1), lg(-41, -1) % lg(-1211982116, 459)) - assertEquals(lg(3425, 0), lg(3425, 0) % lg(-1580976156, 2)) - assertEquals(lg(-25, -1), lg(-25, -1) % lg(200240265, 25993)) - assertEquals(lg(-8303, -1), lg(-8303, -1) % lg(1353761386, 1921)) - assertEquals(lg(274032571, 0), lg(274032571, 0) % lg(1455543028, 255)) - assertEquals(lg(-3, -1), lg(-3, -1) % lg(1143775281, 729)) - assertEquals(lg(-1124428, -1), lg(-1124428, -1) % lg(-521284400, 339)) - assertEquals(lg(-2, -1), lg(-2, -1) % lg(-303859962, 2524)) - assertEquals(lg(1, 0), lg(1, 0) % lg(-402000545, 1)) - assertEquals(lg(107013504, 0), lg(107013504, 0) % lg(157604607, 3)) - assertEquals(lg(4976822, 0), lg(4976822, 0) % lg(-2046021074, 2230)) - assertEquals(lg(-1, -1), lg(-1, -1) % lg(-306200858, 41)) - assertEquals(lg(80396, 0), lg(80396, 0) % lg(-409002766, 13)) - assertEquals(lg(937638, 0), lg(937638, 0) % lg(-697219650, 26)) - assertEquals(lg(756, 0), lg(756, 0) % lg(-948806692, 1700920)) - assertEquals(lg(5, 0), lg(5, 0) % lg(646021801, 21350)) - assertEquals(lg(262831839, 0), lg(262831839, 0) % lg(1086270794, 10633)) - assertEquals(lg(-2146273993, -1), lg(-2146273993, -1) % lg(-1539129401, 0)) - assertEquals(lg(59799, 0), lg(59799, 0) % lg(1910837623, 102082)) - assertEquals(lg(-5347, -1), lg(-5347, -1) % lg(1965292799, 18)) - assertEquals(lg(926, 0), lg(926, 0) % lg(1939309159, 104206)) - assertEquals(lg(1, 0), lg(1, 0) % lg(1651864405, 1233)) - assertEquals(lg(334, 0), lg(334, 0) % lg(581635234, 20)) - assertEquals(lg(-61747, -1), lg(-61747, -1) % lg(-842193425, 1497)) - assertEquals(lg(-1, -1), lg(-1, -1) % lg(758739794, 79508)) - assertEquals(lg(59605313, 0), lg(59605313, 0) % lg(-1162319751, 0)) - assertEquals(lg(12267518, 0), lg(12267518, 0) % lg(1340161110, 568352)) - assertEquals(lg(19230695, 0), lg(19230695, 0) % lg(1844291137, 21)) - assertEquals(lg(3950296, 0), lg(3950296, 0) % lg(-848670202, 243)) - assertEquals(lg(503276, 0), lg(503276, 0) % lg(-1756374670, 1)) - assertEquals(lg(30880536, 0), lg(30880536, 0) % lg(-1380766565, 51064)) - assertEquals(lg(5659804, 0), lg(5659804, 0) % lg(-725339057, 1)) - assertEquals(lg(11882277, 0), lg(11882277, 0) % lg(243727355, 7)) - assertEquals(lg(371783010, 0), lg(371783010, 0) % lg(630143580, 14001)) - assertEquals(lg(840, 0), lg(840, 0) % lg(-1719362098, 109)) - - // int32 % big - assertEquals(lg(-267334310, -1), lg(-267334310, -1) % lg(1537718115, -134598983)) - assertEquals(lg(57, 0), lg(57, 0) % lg(-1668867109, -10100325)) - assertEquals(lg(30332, 0), lg(30332, 0) % lg(-615310153, -90004876)) - assertEquals(lg(187, 0), lg(187, 0) % lg(-590535223, 8244144)) - assertEquals(lg(-2, -1), lg(-2, -1) % lg(2125719729, 390762530)) - assertEquals(lg(-4252915, -1), lg(-4252915, -1) % lg(2070489053, 23484863)) - assertEquals(lg(-2, -1), lg(-2, -1) % lg(37507428, 96913792)) - assertEquals(lg(10, 0), lg(10, 0) % lg(-533680689, -79923599)) - assertEquals(lg(-14, -1), lg(-14, -1) % lg(-930313329, 2972085)) - assertEquals(lg(-20155233, -1), lg(-20155233, -1) % lg(-49989774, -25498857)) - assertEquals(lg(-406, -1), lg(-406, -1) % lg(2109762544, 126098611)) - assertEquals(lg(43, 0), lg(43, 0) % lg(598811771, 154269509)) - assertEquals(lg(-4830, -1), lg(-4830, -1) % lg(-1043650540, -2874494)) - assertEquals(lg(-4271, -1), lg(-4271, -1) % lg(-950378080, -106126516)) - assertEquals(lg(126, 0), lg(126, 0) % lg(-877412093, -90804729)) - assertEquals(lg(40445345, 0), lg(40445345, 0) % lg(-1461218790, 6749169)) - assertEquals(lg(-1, -1), lg(-1, -1) % lg(1776909778, 28425796)) - assertEquals(lg(-2123811, -1), lg(-2123811, -1) % lg(-51805125, 44153129)) - assertEquals(lg(-25650126, -1), lg(-25650126, -1) % lg(-1317209725, -16141386)) - assertEquals(lg(30, 0), lg(30, 0) % lg(712479950, 158765535)) - assertEquals(lg(2494211, 0), lg(2494211, 0) % lg(-432472367, 21859989)) - assertEquals(lg(100937174, 0), lg(100937174, 0) % lg(212873269, -74778594)) - assertEquals(lg(901687, 0), lg(901687, 0) % lg(-1225225931, -512562107)) - assertEquals(lg(-422854, -1), lg(-422854, -1) % lg(-1361503923, -98826041)) - assertEquals(lg(2, 0), lg(2, 0) % lg(386622050, -9945722)) - assertEquals(lg(-465211, -1), lg(-465211, -1) % lg(-418132599, -160175963)) - assertEquals(lg(63, 0), lg(63, 0) % lg(-1330189832, 180061391)) - assertEquals(lg(47, 0), lg(47, 0) % lg(1439978282, -16520554)) - assertEquals(lg(233450563, 0), lg(233450563, 0) % lg(-328511972, 377539644)) - assertEquals(lg(-134912, -1), lg(-134912, -1) % lg(1349244684, -12612862)) - assertEquals(lg(-95441, -1), lg(-95441, -1) % lg(511120357, 16112596)) - assertEquals(lg(-1160726496, -1), lg(-1160726496, -1) % lg(-913371934, -9441145)) - assertEquals(lg(-502, -1), lg(-502, -1) % lg(-1021329523, -377728463)) - assertEquals(lg(3313324, 0), lg(3313324, 0) % lg(-67454848, 442297818)) - assertEquals(lg(-145, -1), lg(-145, -1) % lg(-1010112762, 29724438)) - assertEquals(lg(-19091, -1), lg(-19091, -1) % lg(-1944488998, -173788926)) - assertEquals(lg(-3331910, -1), lg(-3331910, -1) % lg(2144172121, 73505274)) - assertEquals(lg(56622, 0), lg(56622, 0) % lg(-1451372835, 5219178)) - assertEquals(lg(0, 0), lg(0, 0) % lg(556032035, 32471322)) - assertEquals(lg(800, 0), lg(800, 0) % lg(-1649243607, 2299368)) - assertEquals(lg(86949, 0), lg(86949, 0) % lg(794150820, -1384562176)) - assertEquals(lg(10, 0), lg(10, 0) % lg(-790693444, 1000869239)) - assertEquals(lg(-333236, -1), lg(-333236, -1) % lg(-1020207444, 125043716)) - assertEquals(lg(-598, -1), lg(-598, -1) % lg(-93061561, -329975227)) - assertEquals(lg(-19, -1), lg(-19, -1) % lg(-1096862531, 163621631)) - assertEquals(lg(465328283, 0), lg(465328283, 0) % lg(-21925149, -52057346)) - assertEquals(lg(-25837, -1), lg(-25837, -1) % lg(677002620, 8643698)) - assertEquals(lg(-383633650, -1), lg(-383633650, -1) % lg(1609519787, 8262009)) - assertEquals(lg(-66, -1), lg(-66, -1) % lg(1917139359, 239618524)) - assertEquals(lg(1676620, 0), lg(1676620, 0) % lg(910745834, 82765572)) - - // int53 / int32 - assertEquals(lg(15827410, 0), lg(1244623439, 3) % lg(-231372097, -1)) - assertEquals(lg(15118, 0), lg(-1392787378, 124) % lg(-20252, -1)) - assertEquals(lg(11, 0), lg(578165055, 72) % lg(13, 0)) - assertEquals(lg(42298679, 0), lg(-1836745385, 3) % lg(-95630157, -1)) - assertEquals(lg(17447610, 0), lg(-1766124150, 29) % lg(-45315780, -1)) - assertEquals(lg(0, 0), lg(540281958, 253606) % lg(-11, -1)) - assertEquals(lg(51980, 0), lg(-442404110, 7696) % lg(1489246, 0)) - assertEquals(lg(2, 0), lg(-631827526, 1455) % lg(8, 0)) - assertEquals(lg(5125741, 0), lg(1266390909, 49) % lg(-34627848, -1)) - assertEquals(lg(77691, 0), lg(-453014259, 21413) % lg(149449, 0)) - assertEquals(lg(521867604, 0), lg(1573062436, 653) % lg(671211684, 0)) - assertEquals(lg(14579368, 0), lg(-21113520, 0) % lg(177469767, 0)) - assertEquals(lg(0, 0), lg(-262825676, 31) % lg(1, 0)) - assertEquals(lg(24027362, 0), lg(-163968426, 1) % lg(33341027, 0)) - assertEquals(lg(6792805, 0), lg(668741217, 14380) % lg(-11334498, -1)) - assertEquals(lg(9, 0), lg(808041281, 1818) % lg(-10, -1)) - assertEquals(lg(204, 0), lg(-1601247507, 25) % lg(-235, -1)) - assertEquals(lg(61089, 0), lg(-1577206289, 0) % lg(1618642, 0)) - assertEquals(lg(289305533, 0), lg(863396135, 503) % lg(-321808286, -1)) - assertEquals(lg(7272892, 0), lg(-900149281, 55) % lg(15166197, 0)) - assertEquals(lg(3, 0), lg(1802954050, 3593) % lg(7, 0)) - assertEquals(lg(12036, 0), lg(800669146, 41901) % lg(-20591, -1)) - assertEquals(lg(29, 0), lg(-1055636867, 39) % lg(48, 0)) - assertEquals(lg(0, 0), lg(-491067123, 14) % lg(1, 0)) - assertEquals(lg(260441364, 0), lg(1420289126, 67) % lg(1010219079, 0)) - assertEquals(lg(3936541, 0), lg(1338756461, 32) % lg(-4427443, -1)) - assertEquals(lg(183313645, 0), lg(-820843233, 778) % lg(-273780418, -1)) - assertEquals(lg(91783, 0), lg(-1033566360, 561225) % lg(-156677, -1)) - assertEquals(lg(5, 0), lg(-1567070603, 38) % lg(-8, -1)) - assertEquals(lg(11214823, 0), lg(-1649343541, 185302) % lg(-19368267, -1)) - assertEquals(lg(75719, 0), lg(-591434325, 76351) % lg(94212, 0)) - assertEquals(lg(10941, 0), lg(235794528, 55) % lg(17599, 0)) - assertEquals(lg(5331, 0), lg(-763589741, 116) % lg(-14942, -1)) - assertEquals(lg(1, 0), lg(-1283158225, 237055) % lg(-2, -1)) - assertEquals(lg(24400, 0), lg(1537105400, 29108) % lg(-37848, -1)) - assertEquals(lg(95, 0), lg(-56778611, 994650) % lg(-170, -1)) - assertEquals(lg(9836, 0), lg(-2057746932, 7) % lg(-10100, -1)) - assertEquals(lg(30255783, 0), lg(1365793356, 12) % lg(-38454651, -1)) - assertEquals(lg(417, 0), lg(-2128793438, 4) % lg(6825, 0)) - assertEquals(lg(0, 0), lg(1667515072, 8) % lg(2, 0)) - assertEquals(lg(257, 0), lg(420324337, 980) % lg(-845, -1)) - assertEquals(lg(82991, 0), lg(-771084081, 8204) % lg(105392, 0)) - assertEquals(lg(691256, 0), lg(-332377894, 1) % lg(882238, 0)) - assertEquals(lg(0, 0), lg(1749263284, 11) % lg(-20, -1)) - assertEquals(lg(4, 0), lg(347303218, 1234317) % lg(-13, -1)) - assertEquals(lg(150, 0), lg(1199079324, 17271) % lg(11033, 0)) - assertEquals(lg(14, 0), lg(1196217208, 13) % lg(-23, -1)) - assertEquals(lg(256216433, 0), lg(-1078128939, 0) % lg(740155481, 0)) - assertEquals(lg(45583, 0), lg(-1354463473, 3691) % lg(-63588, -1)) - assertEquals(lg(459, 0), lg(-1255896801, 1469630) % lg(-502, -1)) - - // int53 % int53 - assertEquals(lg(1805177178, 1), lg(1805177178, 1) % lg(-1293833696, 410)) - assertEquals(lg(-583440651, 2), lg(647007072, 1811985) % lg(1091239449, 3)) - assertEquals(lg(1346307032, 1), lg(1346307032, 1) % lg(-672335266, 33)) - assertEquals(lg(858355422, 81), lg(858355422, 81) % lg(1490435172, 162402)) - assertEquals(lg(744276027, 1), lg(-1299053281, 6330) % lg(1042770708, 1)) - assertEquals(lg(29273105, 0), lg(-88774269, 25) % lg(775537355, 1)) - assertEquals(lg(383200445, 2), lg(-962613261, 4309) % lg(-529185362, 5)) - assertEquals(lg(-171009725, 445), lg(-171009725, 445) % lg(-1167557775, 307982)) - assertEquals(lg(8166883, 15498), lg(1848497503, 78519) % lg(1533824479, 15755)) - assertEquals(lg(-1752533311, 17), lg(-1752533311, 17) % lg(1904799096, 73566)) - assertEquals(lg(-1641266817, 46), lg(-1641266817, 46) % lg(-31936789, 751199)) - assertEquals(lg(-350685679, 656), lg(-637954451, 32352) % lg(-10259599, 1131)) - assertEquals(lg(-1671876486, 0), lg(-1657673170, 122149) % lg(-534342412, 0)) - assertEquals(lg(-660565679, 235), lg(-660565679, 235) % lg(-897090894, 14655)) - assertEquals(lg(-1798560222, 612), lg(-1798560222, 612) % lg(-236039758, 2924)) - assertEquals(lg(-28767936, 5704), lg(1010899296, 62798) % lg(-1974205776, 9515)) - assertEquals(lg(-2004786867, 4), lg(1206965517, 91420) % lg(880030876, 7)) - assertEquals(lg(712148070, 3), lg(712148070, 3) % lg(472319826, 2838)) - assertEquals(lg(-1275175525, 44), lg(-1275175525, 44) % lg(162799342, 861329)) - assertEquals(lg(1187224322, 14), lg(-516916094, 191396) % lg(-1920802608, 30)) - assertEquals(lg(-1461747946, 0), lg(-1627551726, 4499) % lg(1200735793, 1)) - assertEquals(lg(453535447, 39039), lg(453535447, 39039) % lg(520791957, 141909)) - assertEquals(lg(216221627, 20), lg(216221627, 20) % lg(-781572865, 8131)) - assertEquals(lg(1611884803, 23), lg(-1999221053, 528) % lg(1107934896, 25)) - assertEquals(lg(1722095012, 0), lg(-701225584, 44) % lg(-1403297482, 0)) - assertEquals(lg(-232837834, 5049), lg(-232837834, 5049) % lg(1000581509, 15836)) - assertEquals(lg(-82376749, 239), lg(-82376749, 239) % lg(-163409376, 7688)) - assertEquals(lg(2063025646, 2), lg(941363778, 110) % lg(336092572, 3)) - assertEquals(lg(721574845, 383), lg(1004884706, 1133) % lg(283309861, 750)) - assertEquals(lg(-2004547354, 47), lg(1436404594, 1595) % lg(1522987410, 70)) - assertEquals(lg(1696970595, 8), lg(1696970595, 8) % lg(-1168832286, 4163)) - assertEquals(lg(-2033329312, 6), lg(-1244970780, 32) % lg(394179266, 13)) - assertEquals(lg(1864629418, 1), lg(1864629418, 1) % lg(528888491, 970677)) - assertEquals(lg(1596298266, 43057), lg(-1763600443, 962032) % lg(1535552275, 102108)) - assertEquals(lg(1181714932, 5), lg(1181714932, 5) % lg(1296434411, 26359)) - assertEquals(lg(-2140209952, 7), lg(1535735456, 276446) % lg(-1930593680, 7)) - assertEquals(lg(-1703068243, 11), lg(2079501385, 97596) % lg(-1803771626, 21)) - assertEquals(lg(-1025858772, 33402), lg(286993796, 174379) % lg(656426284, 70488)) - assertEquals(lg(-578045904, 11724), lg(221015334, 1635766) % lg(-2014306775, 270673)) - assertEquals(lg(-2080784768, 56), lg(-2103734262, 977) % lg(-22949494, 920)) - assertEquals(lg(-922083739, 29), lg(-922083739, 29) % lg(2040148267, 19160)) - assertEquals(lg(-1728890579, 468), lg(-559850131, 11989) % lg(1366001936, 2880)) - assertEquals(lg(1341547600, 13), lg(-1071198220, 2182) % lg(1526886260, 17)) - assertEquals(lg(-896451936, 45), lg(-896451936, 45) % lg(2132477227, 164356)) - assertEquals(lg(-1538011120, 53), lg(-561327714, 1420) % lg(-368698210, 151)) - assertEquals(lg(1880884956, 621), lg(2112956103, 118429) % lg(-374507565, 859)) - assertEquals(lg(902909663, 0), lg(380445410, 8) % lg(-1822479769, 1)) - assertEquals(lg(-652149100, 56), lg(-1867274924, 105813) % lg(175641312, 79)) - assertEquals(lg(-991170416, 37), lg(-991170416, 37) % lg(1740161397, 88122)) - assertEquals(lg(-31602776, 1), lg(-31602776, 1) % lg(-503633567, 241909)) - - // int53 % big - assertEquals(lg(-930109303, 3), lg(-930109303, 3) % lg(1606982787, 925386547)) - assertEquals(lg(-717668907, 16251), lg(-717668907, 16251) % lg(2079100937, 7825426)) - assertEquals(lg(265990345, 3), lg(265990345, 3) % lg(-1140922127, -3108870)) - assertEquals(lg(-1181318422, 1), lg(-1181318422, 1) % lg(1489652251, 75207246)) - assertEquals(lg(380276439, 59), lg(380276439, 59) % lg(-1062351234, -3631372)) - assertEquals(lg(1080382784, 7211), lg(1080382784, 7211) % lg(572850722, -139092025)) - assertEquals(lg(2020323378, 316), lg(2020323378, 316) % lg(1716930349, -16333391)) - assertEquals(lg(1302118364, 5), lg(1302118364, 5) % lg(-442067036, 1941456592)) - assertEquals(lg(-641137972, 602), lg(-641137972, 602) % lg(1134212295, -135713760)) - assertEquals(lg(-761172703, 499), lg(-761172703, 499) % lg(769981236, 12756336)) - assertEquals(lg(1601268090, 610), lg(1601268090, 610) % lg(448513898, -160887452)) - assertEquals(lg(-16483553, 0), lg(-16483553, 0) % lg(-1253549192, -1748027086)) - assertEquals(lg(-1284021361, 241), lg(-1284021361, 241) % lg(13275221, -3818882)) - assertEquals(lg(1499414278, 26), lg(1499414278, 26) % lg(570654893, -17498947)) - assertEquals(lg(-368610421, 5074), lg(-368610421, 5074) % lg(685701351, 31070898)) - assertEquals(lg(1200134796, 70), lg(1200134796, 70) % lg(1230376618, -2490370)) - assertEquals(lg(1537764087, 64483), lg(1537764087, 64483) % lg(-1252591472, 66761881)) - assertEquals(lg(-1981129198, 15), lg(-1981129198, 15) % lg(1937978150, 8201544)) - assertEquals(lg(32422964, 200), lg(32422964, 200) % lg(2051327691, -20319622)) - assertEquals(lg(1404616230, 30), lg(1404616230, 30) % lg(-748420073, -120320053)) - assertEquals(lg(-1860381107, 38), lg(-1860381107, 38) % lg(392948122, 60098039)) - assertEquals(lg(1050519262, 106431), lg(1050519262, 106431) % lg(361773491, -6329760)) - assertEquals(lg(460136491, 1681770), lg(460136491, 1681770) % lg(1399049044, 759923035)) - assertEquals(lg(2065599344, 11089), lg(2065599344, 11089) % lg(-465681057, 3484544)) - assertEquals(lg(1849358428, 418531), lg(1849358428, 418531) % lg(1023666326, 3435570)) - assertEquals(lg(1292603836, 80), lg(1292603836, 80) % lg(-1114872574, 250120091)) - assertEquals(lg(1456627133, 194844), lg(1456627133, 194844) % lg(-1256385160, 59427917)) - assertEquals(lg(-568179858, 160), lg(-568179858, 160) % lg(1142846538, 154324747)) - assertEquals(lg(-2133580755, 203337), lg(-2133580755, 203337) % lg(111334842, 12695612)) - assertEquals(lg(1961218705, 6687), lg(1961218705, 6687) % lg(-245612957, 134017780)) - assertEquals(lg(335350966, 55096), lg(335350966, 55096) % lg(-1815119598, -120983980)) - assertEquals(lg(-767561503, 211), lg(-767561503, 211) % lg(554589640, -7873602)) - assertEquals(lg(1476687067, 3767), lg(1476687067, 3767) % lg(552659809, -753378142)) - assertEquals(lg(-1107393223, 30), lg(-1107393223, 30) % lg(-78383575, -52663801)) - assertEquals(lg(607313614, 2), lg(607313614, 2) % lg(-234099925, 59184919)) - assertEquals(lg(-1542671184, 616882), lg(-1542671184, 616882) % lg(1370026838, -45628731)) - assertEquals(lg(525616384, 1001), lg(525616384, 1001) % lg(1995646126, -11226360)) - assertEquals(lg(2109958916, 21549), lg(2109958916, 21549) % lg(-419960245, -115959896)) - assertEquals(lg(-450913111, 32140), lg(-450913111, 32140) % lg(-99267096, -3640047)) - assertEquals(lg(1515870052, 198), lg(1515870052, 198) % lg(1415757861, -110282301)) - assertEquals(lg(124639649, 865615), lg(124639649, 865615) % lg(-1354782388, 2569606)) - assertEquals(lg(557119825, 7205), lg(557119825, 7205) % lg(683150209, -15864187)) - assertEquals(lg(992846513, 1385110), lg(992846513, 1385110) % lg(1578961851, -8380578)) - assertEquals(lg(1081385155, 4176), lg(1081385155, 4176) % lg(1892231070, 31130825)) - assertEquals(lg(-738492748, 8), lg(-738492748, 8) % lg(-431212066, 687916944)) - assertEquals(lg(-1448153936, 8101), lg(-1448153936, 8101) % lg(-584523654, -4814205)) - assertEquals(lg(-713251055, 243), lg(-713251055, 243) % lg(261411225, 31444708)) - assertEquals(lg(881178812, 47057), lg(881178812, 47057) % lg(823893049, -5940358)) - assertEquals(lg(-506817388, 0), lg(-506817388, 0) % lg(-465610822, 10559551)) - assertEquals(lg(-420315839, 112832), lg(-420315839, 112832) % lg(-686319219, -666166549)) - - // big % int32 - assertEquals(lg(-3, -1), lg(-412174169, -319069709) % lg(-6, -1)) - assertEquals(lg(464005, 0), lg(1634601702, 814446468) % lg(825883, 0)) - assertEquals(lg(34559370, 0), lg(-1005992901, 2694218) % lg(108493743, 0)) - assertEquals(lg(-286379, -1), lg(1534700309, -630528658) % lg(-506616, -1)) - assertEquals(lg(-62, -1), lg(-456613426, -23298167) % lg(-206, -1)) - assertEquals(lg(386945695, 0), lg(857770611, 2618490) % lg(1225551197, 0)) - assertEquals(lg(270232, 0), lg(2127943654, 2768088) % lg(-291653, -1)) - assertEquals(lg(277129, 0), lg(1085973072, 3470797) % lg(-29714535, -1)) - assertEquals(lg(15, 0), lg(1536124828, 1268901218) % lg(-121, -1)) - assertEquals(lg(1, 0), lg(371220141, 34588968) % lg(2, 0)) - assertEquals(lg(46669, 0), lg(-1712997009, 187259899) % lg(129274, 0)) - assertEquals(lg(-1508, -1), lg(586579000, -243530833) % lg(-31235, -1)) - assertEquals(lg(0, 0), lg(1745775262, -400161972) % lg(-1, -1)) - assertEquals(lg(-1680, -1), lg(-1564631310, -56487209) % lg(2626, 0)) - assertEquals(lg(53, 0), lg(-1848745069, 11533547) % lg(59, 0)) - assertEquals(lg(-1699972, -1), lg(-1415791920, -26215621) % lg(-2142359, -1)) - assertEquals(lg(-200041, -1), lg(-481609933, -25891343) % lg(483607, 0)) - assertEquals(lg(-13123232, -1), lg(-889674017, -4084771) % lg(428648085, 0)) - assertEquals(lg(0, 0), lg(1587465684, -367383975) % lg(7, 0)) - assertEquals(lg(-4528, -1), lg(811562260, -335104547) % lg(5502, 0)) - assertEquals(lg(-71, -1), lg(2107357891, -10075787) % lg(110, 0)) - assertEquals(lg(0, 0), lg(-1356326655, 5174156) % lg(-1, -1)) - assertEquals(lg(7872112, 0), lg(-1794856776, 3059124) % lg(-29413816, -1)) - assertEquals(lg(-37, -1), lg(-1118254374, -3629384) % lg(-85, -1)) - assertEquals(lg(14227, 0), lg(288539563, 70814306) % lg(-14561, -1)) - assertEquals(lg(-49, -1), lg(-719069745, -128562664) % lg(-256, -1)) - assertEquals(lg(6101, 0), lg(1530955727, 15829469) % lg(195494, 0)) - assertEquals(lg(-6, -1), lg(2144004402, -5408490) % lg(11, 0)) - assertEquals(lg(-137624717, -1), lg(-1766192560, -17443468) % lg(-168087095, -1)) - assertEquals(lg(-3592, -1), lg(-524619138, -371121095) % lg(4765, 0)) - assertEquals(lg(4335, 0), lg(-1960083221, 176122524) % lg(-5564, -1)) - assertEquals(lg(-271754, -1), lg(1528631102, -597885631) % lg(-413908, -1)) - assertEquals(lg(-361112, -1), lg(-1513123614, -30582360) % lg(-496311, -1)) - assertEquals(lg(-4, -1), lg(-1975522255, -46421733) % lg(29, 0)) - assertEquals(lg(414436, 0), lg(-1715879325, 3072313) % lg(438221, 0)) - assertEquals(lg(0, 0), lg(-1321015849, -300384564) % lg(1, 0)) - assertEquals(lg(-454, -1), lg(-1088390706, -277354665) % lg(-1237, -1)) - assertEquals(lg(586891857, 0), lg(-1012773943, 223943652) % lg(707359548, 0)) - assertEquals(lg(2, 0), lg(1097288344, 26740237) % lg(-3, -1)) - assertEquals(lg(-24053960, -1), lg(-1121404205, -87484234) % lg(80229261, 0)) - assertEquals(lg(-79944815, -1), lg(-1503637931, -163703901) % lg(-983334452, -1)) - assertEquals(lg(2600110, 0), lg(2012820970, 445991475) % lg(1035472980, 0)) - assertEquals(lg(74, 0), lg(2015362538, 2985510) % lg(-148, -1)) - assertEquals(lg(0, 0), lg(1764134228, 50881407) % lg(-1, -1)) - assertEquals(lg(106, 0), lg(-523555853, 77167937) % lg(-563, -1)) - assertEquals(lg(0, 0), lg(1531888651, -2389306) % lg(1, 0)) - assertEquals(lg(659, 0), lg(-181277952, 32599207) % lg(-729, -1)) - assertEquals(lg(968, 0), lg(223126732, 88838488) % lg(13378, 0)) - assertEquals(lg(920991, 0), lg(670834629, 46037187) % lg(922370, 0)) - assertEquals(lg(2462152, 0), lg(1098978850, 6541822) % lg(-8405198, -1)) - - // big % int53 - assertEquals(lg(1057995305, 4748), lg(2008672965, 41566313) % lg(313991275, 18390)) - assertEquals(lg(-1074209653, 18), lg(1922552561, 28139870) % lg(-2083633557, 19)) - assertEquals(lg(1480601143, -11310), lg(843627074, -173776705) % lg(1451117493, 14364)) - assertEquals(lg(-691687452, -38), lg(204865470, -6692402) % lg(-645190286, 413)) - assertEquals(lg(-1218791457, -31), lg(952830559, -214594684) % lg(-1778162360, 378)) - assertEquals(lg(-281609960, -1292), lg(1673740333, -69274846) % lg(-1549261605, 2390)) - assertEquals(lg(-860426348, 1), lg(-1276804811, 367022678) % lg(-678111623, 11)) - assertEquals(lg(-1244563205, -1264), lg(-1331527548, -33013551) % lg(-1975438267, 2961)) - assertEquals(lg(-935830326, 135167), lg(1067523314, 72606174) % lg(-1716982106, 255179)) - assertEquals(lg(-2025081444, -42140), lg(-937134490, -32649070) % lg(-804857990, 57507)) - assertEquals(lg(85696931, 194), lg(108363299, 1224097478) % lg(1137551776, 281)) - assertEquals(lg(-385517902, -5258), lg(-1965834834, -11053948) % lg(-942300324, 6487)) - assertEquals(lg(-755355475, 2268), lg(-3151939, 171473802) % lg(-2071379940, 3914)) - assertEquals(lg(-676865399, -663), lg(1465781759, -970108425) % lg(-1251607207, 3003)) - assertEquals(lg(2042443783, -22321), lg(919308511, -1689158617) % lg(658566728, 36406)) - assertEquals(lg(-903837593, 31415), lg(-418485001, 1000432592) % lg(-1653953022, 31957)) - assertEquals(lg(496274972, -48207), lg(-880302655, -14116770) % lg(913871933, 118223)) - assertEquals(lg(1210119082, -104892), lg(-525597278, -3790314) % lg(2133284776, 127083)) - assertEquals(lg(473810731, -5), lg(-393124913, -28106221) % lg(958070140, 159)) - assertEquals(lg(-1912903061, 25777), lg(6929245, 2749730) % lg(1462129294, 43237)) - assertEquals(lg(1099532724, -19), lg(708024745, -15568245) % lg(1288198049, 56)) - assertEquals(lg(920504149, 6836), lg(487601139, 13603229) % lg(723875593, 45021)) - assertEquals(lg(1778080723, 29), lg(-2070321133, 115478389) % lg(-1799479616, 75)) - assertEquals(lg(-720480381, 2735), lg(-307180735, 3049800) % lg(1043781053, 3319)) - assertEquals(lg(1473972065, -1), lg(-1073877839, -6538577) % lg(-1408649838, 0)) - assertEquals(lg(-1389255096, -200), lg(-1892822171, -1698321438) % lg(96164237, 514)) - assertEquals(lg(857386403, 29656), lg(-674980011, 2764943) % lg(-445529419, 65125)) - assertEquals(lg(-419043446, -22164), lg(2003347800, -46928389) % lg(368897711, 128159)) - assertEquals(lg(-1599543668, -6569), lg(-1929871429, -241628283) % lg(202358381, 7645)) - assertEquals(lg(581185953, 1), lg(419719197, 661188517) % lg(2112360098, 1)) - assertEquals(lg(-1880704128, 171407), lg(1092830824, 1600823129) % lg(-1827462760, 172800)) - assertEquals(lg(1210159480, -13), lg(-836779994, -27475595) % lg(-417527207, 16)) - assertEquals(lg(807846066, 1), lg(-1759597755, 9157722) % lg(-987185779, 1)) - assertEquals(lg(949995673, 1), lg(-1097231525, 20092165) % lg(1106421078, 1)) - assertEquals(lg(-712450167, 7), lg(390678483, 3835040) % lg(1221250555, 14)) - assertEquals(lg(1129531033, -4), lg(-284334384, -18425278) % lg(-1111448031, 6)) - assertEquals(lg(2094997010, 3022), lg(-233961390, 53260849) % lg(-613558136, 3663)) - assertEquals(lg(-496446555, 540290), lg(-3383211, 8039036) % lg(-1668680584, 749874)) - assertEquals(lg(1280740603, -9472), lg(804358887, -189240235) % lg(179665302, 12347)) - assertEquals(lg(2127427912, 6), lg(208769744, 280071599) % lg(-325433064, 14)) - assertEquals(lg(-722136158, -1), lg(-1527711901, -51564742) % lg(-1019145455, 0)) - assertEquals(lg(-1603688570, -2), lg(-159182038, -2145592347) % lg(-483720705, 15)) - assertEquals(lg(-256578646, 177817), lg(1059926378, 477886379) % lg(924988992, 543468)) - assertEquals(lg(1286157765, 80885), lg(-1800046387, 119696078) % lg(436524799, 94037)) - assertEquals(lg(251450065, 19154), lg(-822280387, 44882065) % lg(-940828508, 22947)) - assertEquals(lg(1310986115, 209), lg(1465101985, 269803551) % lg(-1953360551, 334)) - assertEquals(lg(1436855439, -5), lg(-567675197, -8838663) % lg(1903221047, 6)) - assertEquals(lg(296887390, -17), lg(689376065, -22622471) % lg(1534988921, 63)) - assertEquals(lg(1577958450, -39), lg(-2017356377, -57717216) % lg(-1390284125, 42)) - assertEquals(lg(661387374, 344542), lg(-128715878, 982583003) % lg(2004099318, 988167)) - - // big % big - assertEquals(lg(-320078007, 205603273), lg(-320078007, 205603273) % lg(2020227799, -360928021)) - assertEquals(lg(408769930, -2221999), lg(-800732960, -371808530) % lg(744251542, -11199592)) - assertEquals(lg(1575977183, -2441606), lg(-56774921, -32434115) % lg(1413374280, -2726592)) - assertEquals(lg(-1897285736, 18894093), lg(1667937500, 228622683) % lg(-243248020, 69909529)) - assertEquals(lg(-1333815518, 2097776), lg(-1333815518, 2097776) % lg(-1750106076, 18608702)) - assertEquals(lg(-789967161, -4640836), lg(-162800691, -117885498) % lg(-709007774, 8711127)) - assertEquals(lg(-1909427145, -2824029), lg(-1909427145, -2824029) % lg(2028036056, -660713154)) - assertEquals(lg(14077923, 63046905), lg(14077923, 63046905) % lg(-688765214, 375445962)) - assertEquals(lg(272760540, 19525127), lg(272760540, 19525127) % lg(-396955631, 848435537)) - assertEquals(lg(-600396362, 406643261), lg(-600396362, 406643261) % lg(-1533973181, 491661310)) - assertEquals(lg(1801834226, 200420454), lg(1801834226, 200420454) % lg(-1889418050, -328758068)) - assertEquals(lg(361053022, 54544094), lg(1170836790, 510289402) % lg(202445942, 113936327)) - assertEquals(lg(1369752396, -3152427), lg(-378923036, -1036580478) % lg(905093048, 5526353)) - assertEquals(lg(1458911735, 21273958), lg(-2137034353, 1455139814) % lg(1665353214, 27574343)) - assertEquals(lg(-1350216191, -3821167), lg(-1350216191, -3821167) % lg(-1333339390, -4746360)) - assertEquals(lg(1166542449, -1370750), lg(-1289646201, -5193401) % lg(1838778646, -3822651)) - assertEquals(lg(301867174, 5185218), lg(301867174, 5185218) % lg(157012848, -15464466)) - assertEquals(lg(512572633, 48335882), lg(467711834, 155069651) % lg(-44860799, 106733768)) - assertEquals(lg(1624269582, 11007763), lg(1624269582, 11007763) % lg(-158694824, -491219717)) - assertEquals(lg(-1015519521, -163989350), lg(-1015519521, -163989350) % lg(1652525166, 530116116)) - assertEquals(lg(-2127450406, -89864400), lg(2001612518, -452587333) % lg(1115217917, 90680733)) - assertEquals(lg(-761803769, -6085789), lg(1039524645, -86121932) % lg(1131434363, 13339357)) - assertEquals(lg(-1922291990, 6439098), lg(-1922291990, 6439098) % lg(-1083372307, -20634200)) - assertEquals(lg(1508171882, 126457), lg(1408756974, 235847122) % lg(-1813277898, -9066180)) - assertEquals(lg(-496706473, -2657930), lg(1121009342, -1533788016) % lg(-1724900447, -5821788)) - assertEquals(lg(-1626361260, -113469353), lg(-1626361260, -113469353) % lg(1216987736, -817139415)) - assertEquals(lg(-433139577, -182483493), lg(-433139577, -182483493) % lg(1019490766, -595625160)) - assertEquals(lg(-1118452074, 1653764), lg(793542905, 198273616) % lg(-82759497, -2621599)) - assertEquals(lg(-1199275184, 1262327), lg(425605214, 249789222) % lg(392156278, 6716943)) - assertEquals(lg(213473729, 11660532), lg(213473729, 11660532) % lg(-547058106, 894811834)) - assertEquals(lg(-1550227391, 2847368), lg(-1550227391, 2847368) % lg(-1996700003, 689370771)) - assertEquals(lg(-1014778289, -3747071), lg(-144234222, -54239417) % lg(-1102770075, -7213193)) - assertEquals(lg(524484467, 15124083), lg(524484467, 15124083) % lg(-1101379967, -39968226)) - assertEquals(lg(-919997306, 2085072), lg(314758022, 5390195) % lg(-1234755328, -3305123)) - assertEquals(lg(580679232, -10426812), lg(580679232, -10426812) % lg(-1964013803, -1738507605)) - assertEquals(lg(225658926, -4189255), lg(1670083752, -254253193) % lg(722212413, -125031969)) - assertEquals(lg(-495749254, -1833207), lg(-1744001445, -5443198) % lg(1248252191, 3609991)) - assertEquals(lg(-1481543825, 608612), lg(-1786439869, 137339199) % lg(1821158508, 2909161)) - assertEquals(lg(1026706952, -6267613), lg(1273422584, -284542935) % lg(1626032463, -17392208)) - assertEquals(lg(-855876173, -4928311), lg(-513801887, -32580141) % lg(-342074286, 27651829)) - assertEquals(lg(-1027906958, 55543678), lg(-1027906958, 55543678) % lg(-1936394792, 928937151)) - assertEquals(lg(-1793811005, -17787029), lg(251585986, -50474191) % lg(-2045396991, 32687162)) - assertEquals(lg(-356034186, -2235041), lg(66679938, -917589429) % lg(2124767660, -3454168)) - assertEquals(lg(-924611099, -76507846), lg(-599564184, -209788131) % lg(-325046915, 133280284)) - assertEquals(lg(838338995, -12983151), lg(838338995, -12983151) % lg(-842402530, 19411056)) - assertEquals(lg(747658762, 18528439), lg(1444498155, 520850879) % lg(851271837, 23920116)) - assertEquals(lg(-2028924578, -3124146), lg(2096765386, -117024114) % lg(-1726450785, -5694999)) - assertEquals(lg(2056903464, -4954201), lg(-425905039, -180148939) % lg(-1397064581, -15926795)) - assertEquals(lg(-2055992988, 596420), lg(-920215872, 219325473) % lg(1357686103, 54682263)) - assertEquals(lg(1279110660, -10784541), lg(1279110660, -10784541) % lg(278869448, 758126792)) - } - -} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/LongTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/LongTest.scala index 27b9b9527e..0092e077f3 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/LongTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/LongTest.scala @@ -9,15 +9,82 @@ package org.scalajs.testsuite.compiler import org.junit.Test import org.junit.Assert._ +import org.junit.Assume._ + +import org.scalajs.testsuite.utils.Platform._ -/** Tests the compiler re-patching of native longs to - * scala.scalajs.runtime.Long - * see org.scalajs.testsuite.jsinterop.RuntimeLongTest - * for a test of the implementation itself - */ class LongTest { import LongTest._ + /* Short builders, used for historical reasons. + * In practice, they are always called with constants, which ensures that the + * optimizer can constant-fold them away at the IR level, without even + * looking inside RuntimeLong. + */ + + @inline def lg(lo: Int, hi: Int): Long = + (hi.toLong << 32) | (lo.toLong & 0xffffffffL) + + @inline def lg(i: Int): Long = + i.toLong + + // Helpers + + @noinline def hideFromOptimizer(x: Long): Long = x + + @noinline def hideDoubleFromOptimizer(x: Double): Double = x + + @noinline def hideAnyFromOptimizer(x: Any): Any = x + + // Common values + + def MaxVal: Long = lg(0xffffffff, 0x7fffffff) + def MinVal: Long = lg(0, 0x80000000) + def IntMaxVal: Long = lg(Int.MaxValue) + def IntMinVal: Long = lg(Int.MinValue) + def IntMaxValPlus1: Long = lg(0x80000000, 0) + def IntMinValMinus1: Long = lg(2147483647, -1) + def MaxSafeDouble: Long = lg(-1, 2097151) + def TwoPow53: Long = lg(0, 2097152) + def MinSafeDouble: Long = lg(1, -2097152) + def NegTwoPow53: Long = lg(0, -2097152) + + // Tests + + @Test def sanity_of_equality_tests(): Unit = { + assertEquals(1958505087099L, lg(123, 456)) + assertEquals(528280977864L, lg(456, 123)) + + assertNotEquals(17179869307L, lg(123, 456)) + assertNotEquals(lg(123, 4), lg(123, 456)) + assertNotEquals(1958505086977L, lg(123, 456)) + assertNotEquals(lg(1, 456), lg(123, 456)) + assertNotEquals(123L, lg(123, 456)) + } + + @Test def equals_Any(): Unit = { + @inline def test(expected: Boolean, lhs: Long, rhs: Any): Unit = { + assertEquals(expected, lhs.equals(rhs)) + assertEquals(expected, hideFromOptimizer(lhs).equals(rhs)) + assertEquals(expected, lhs.equals(hideAnyFromOptimizer(rhs))) + assertEquals(expected, + hideFromOptimizer(lhs).equals(hideAnyFromOptimizer(rhs))) + } + + test(false, lg(0, 0), 0) + test(false, lg(0, 0), null) + + test(true, lg(0, 0), lg(0, 0)) + test(true, lg(123, 456), lg(123, 456)) + test(true, lg(-123, 456), lg(-123, 456)) + test(true, lg(-123, -456), lg(-123, -456)) + + test(false, lg(123, 456), lg(-123, 456)) + test(false, lg(123, 456), lg(123, -456)) + test(false, lg(-123, -456), lg(123, -456)) + test(false, lg(-123, -456), lg(-123, 456)) + } + @Test def `should_correctly_handle_literals`(): Unit = { assertEquals(105L, 5L + 100L) assertEquals(2147483651L, 2147483649L + 2L) @@ -61,171 +128,6 @@ class LongTest { assertEquals(-5, i(-65) >> 4) } - @Test def times_*(): Unit = { - @inline def test(a: Long, b: Long, expected: Long): Unit = { - @noinline def hideFromOptimizer(x: Long): Long = x - - assertEquals(expected, a * b) - assertEquals(expected, hideFromOptimizer(a) * b) - assertEquals(expected, a * hideFromOptimizer(b)) - assertEquals(expected, hideFromOptimizer(a) * hideFromOptimizer(b)) - } - - // Random tests - test(-304510477859059605L, -504694402761190L, 8433193943336928478L) - test(-253162060478L, 50291L, -12731773183499098L) - test(0L, -13850059L, 0L) - test(-8660470952582643L, -874L, 7569251612557229982L) - test(-1332L, 9L, -11988L) - test(-29568141078178L, 1526544L, -8243580206627053600L) - test(328926390054L, -3638668370L, 2184313243348463060L) - test(205L, 228496L, 46841680L) - test(-19460467868573L, -81306407837343422L, 740594256954004614L) - test(515501176792L, -14676235751610L, 1686350941924289808L) - test(414866483823975467L, 470120246452409879L, 6344118389112076765L) - test(-117L, 97L, -11349L) - test(30L, -513425L, -15402750L) - test(1375729456898L, 623181770548L, -1358824991029065112L) - test(80638733077L, 195L, 15724552950015L) - test(-12740384618206L, -4199L, 53496875011846994L) - test(521743856055513645L, -2105465236503908L, 4976657084923555180L) - test(-8L, -1L, 8L) - test(-34L, -18232708L, 619912072L) - test(-4512416881041611L, 16599101951L, -4326473264912647477L) - test(-2433585405235L, -645367L, 1570555712220296245L) - test(-774590L, -22277506028L, 17255933394228520L) - test(36307900L, -19149614702538L, 5693979142683511208L) - test(22169162314093L, 18534166L, 5058564788733665886L) - test(-3848931303L, 82157326906201261L, -1912529786602316571L) - test(47326191440L, -39094697833L, -5528746562555987920L) - test(-14641542L, -3714491797523081344L, -2254385599727553792L) - test(771303L, 10199L, 7866519297L) - test(0L, -14806105L, 0L) - test(3964448L, 12L, 47573376L) - test(77505454872L, -33668L, -2609453654630496L) - test(14929228532112L, 6555913938L, -3686637842539497440L) - test(431219964946864070L, 1181669L, 4853210716974444062L) - test(2820049084807L, -5L, -14100245424035L) - test(-16830140929953126L, 93975690486771L, 8725676311339308590L) - test(206188838L, 1249841574949634L, 2367313232506909772L) - test(16674057030L, 1104000290638571L, -8124607316971866814L) - test(-64710169253973867L, -23079009995647L, 6446979988520042261L) - test(31096512L, 21048L, 654519384576L) - test(22L, 6963814099146552L, 153203910181224144L) - test(1260318190682L, 1123567398313107L, 1436126772314869678L) - test(-5L, 15132314L, -75661570L) - test(9099845427374L, -126975734L, 6685324216344409292L) - test(5L, -1420058L, -7100290L) - test(-28274L, 68638918056024L, -1940696769116022576L) - test(193355246244L, 36593871833L, -7932625013377175292L) - test(1L, -7L, -7L) - test(66789957775108L, -724L, -48355929429178192L) - test(10521672279471L, -1L, -10521672279471L) - test(-8747667231979L, -105906241L, 4095350372293300139L) - - // Random power of 2 tests - test(100259248L, 1048576L, 105129441230848L) - test(1048576L, 100259248L, 105129441230848L) - test(72L, 18014398509481984L, 1297036692682702848L) - test(18014398509481984L, 72L, 1297036692682702848L) - test(-22253267L, 536870912L, -11947131749269504L) - test(536870912L, -22253267L, -11947131749269504L) - test(23022568162358L, 8388608L, 8659858730206101504L) - test(8388608L, 23022568162358L, 8659858730206101504L) - test(1548271L, 134217728L, 207805415948288L) - test(134217728L, 1548271L, 207805415948288L) - test(-55880L, -9223372036854775808L, 0L) - test(-9223372036854775808L, -55880L, 0L) - test(-1L, 2199023255552L, -2199023255552L) - test(2199023255552L, -1L, -2199023255552L) - test(13L, 65536L, 851968L) - test(65536L, 13L, 851968L) - test(-1L, 17592186044416L, -17592186044416L) - test(17592186044416L, -1L, -17592186044416L) - test(222527207082L, 4398046511104L, -7000097952840548352L) - test(4398046511104L, 222527207082L, -7000097952840548352L) - test(34L, 72057594037927936L, 2449958197289549824L) - test(72057594037927936L, 34L, 2449958197289549824L) - test(-4058427375959L, 4096L, -16623318531928064L) - test(4096L, -4058427375959L, -16623318531928064L) - test(-2214324316485807900L, 281474976710656L, -8006274237557899264L) - test(281474976710656L, -2214324316485807900L, -8006274237557899264L) - test(-14335L, 4294967296L, -61568356188160L) - test(4294967296L, -14335L, -61568356188160L) - test(-48456017090L, 64L, -3101185093760L) - test(64L, -48456017090L, -3101185093760L) - test(-158203838L, 128L, -20250091264L) - test(128L, -158203838L, -20250091264L) - test(-115995L, 1024L, -118778880L) - test(1024L, -115995L, -118778880L) - test(-483041L, 8388608L, -4052041596928L) - test(8388608L, -483041L, -4052041596928L) - test(186114971352L, 35184372088832L, 2511601217189183488L) - test(35184372088832L, 186114971352L, 2511601217189183488L) - test(8064516387533822L, 32L, 258064524401082304L) - test(32L, 8064516387533822L, 258064524401082304L) - test(-816627104025L, 16384L, -13379618472345600L) - test(16384L, -816627104025L, -13379618472345600L) - test(-106L, 536870912L, -56908316672L) - test(536870912L, -106L, -56908316672L) - test(0L, 4096L, 0L) - test(4096L, 0L, 0L) - test(-61230193L, 8388608L, -513636086841344L) - test(8388608L, -61230193L, -513636086841344L) - test(41500264L, 8796093022208L, -3894698884001169408L) - test(8796093022208L, 41500264L, -3894698884001169408L) - test(32992L, 32L, 1055744L) - test(32L, 32992L, 1055744L) - test(65071L, 8589934592L, 558955633836032L) - test(8589934592L, 65071L, 558955633836032L) - test(76048351L, 137438953472L, -7994738298998226944L) - test(137438953472L, 76048351L, -7994738298998226944L) - test(-2L, 2L, -4L) - test(2L, -2L, -4L) - test(-8318677645L, 512L, -4259162954240L) - test(512L, -8318677645L, -4259162954240L) - test(-60717806L, 2251799813685248L, 2922836158163451904L) - test(2251799813685248L, -60717806L, 2922836158163451904L) - test(0L, 8192L, 0L) - test(8192L, 0L, 0L) - test(164844L, 33554432L, 5531246788608L) - test(33554432L, 164844L, 5531246788608L) - test(-678234761L, 72057594037927936L, 8574853690513424384L) - test(72057594037927936L, -678234761L, 8574853690513424384L) - test(-103657850088L, 2251799813685248L, -2828260565988671488L) - test(2251799813685248L, -103657850088L, -2828260565988671488L) - test(138748537820112453L, -9223372036854775808L, -9223372036854775808L) - test(-9223372036854775808L, 138748537820112453L, -9223372036854775808L) - test(0L, 17179869184L, 0L) - test(17179869184L, 0L, 0L) - test(-2489041709915087415L, 2147483648L, 5526109039206858752L) - test(2147483648L, -2489041709915087415L, 5526109039206858752L) - test(9L, 1073741824L, 9663676416L) - test(1073741824L, 9L, 9663676416L) - test(379085341609132041L, 72057594037927936L, 648518346341351424L) - test(72057594037927936L, 379085341609132041L, 648518346341351424L) - test(218625848802439L, 65536L, -4118880446592909312L) - test(65536L, 218625848802439L, -4118880446592909312L) - test(-422887732952L, 16777216L, -7094878839486021632L) - test(16777216L, -422887732952L, -7094878839486021632L) - test(77839L, 268435456L, 20894747459584L) - test(268435456L, 77839L, 20894747459584L) - test(-3953804003778L, 2251799813685248L, -5624995934585749504L) - test(2251799813685248L, -3953804003778L, -5624995934585749504L) - test(141564L, 536870912L, 76001593786368L) - test(536870912L, 141564L, 76001593786368L) - test(11068003L, 536870912L, 5942088864628736L) - test(536870912L, 11068003L, 5942088864628736L) - test(-816398911L, 512L, -417996242432L) - test(512L, -816398911L, -417996242432L) - test(79084L, 128L, 10122752L) - test(128L, 79084L, 10122752L) - test(166L, 4294967296L, 712964571136L) - test(4294967296L, 166L, 712964571136L) - test(-120218862620908531L, 4294967296L, -3013501831155286016L) - test(4294967296L, -120218862620908531L, -3013501831155286016L) - } - @Test def `primitives_should_convert_to_Long`(): Unit = { // Byte assertEquals(112L, 112.toByte.toLong) @@ -317,6 +219,2301 @@ class LongTest { assertTrue(4 != 5L) assertTrue('A' == 65L) } + + @Test def hashCodeTest(): Unit = { + @inline def test(expected: Int, x: Long): Unit = { + assertEquals(expected, x.hashCode()) + assertEquals(expected, hideFromOptimizer(x).hashCode()) + } + + test(0, lg(0)) + test(0, lg(-1)) + test(55, lg(55)) + test(11, lg(-12)) + test(10006548, lg(10006548)) + test(1098747, lg(-1098748)) + + test(957662195, lg(579906195, 461662560)) + test(-1075860794, lg(-1403218312, 327367870)) + test(1425294575, lg(-1152051636, -274640221)) + test(-1863811248, lg(1026519507, -1379463549)) + test(-881942797, lg(363765329, -557842270)) + test(548587254, lg(21652572, 569942698)) + test(-1328999812, lg(55820229, -1281708615)) + test(-1756412154, lg(-1843678104, 89453422)) + test(-529144798, lg(-1928579430, 1836700344)) + test(-1163319584, lg(-181377900, 1335444084)) + test(2070477069, lg(1189983760, 1032146717)) + test(-1718642695, lg(-1982789145, 274636318)) + test(260982265, lg(-2087901827, -1945935740)) + test(-385578983, lg(-1911332808, 1729620001)) + test(-1362397169, lg(-1920965295, 592125278)) + test(1419211160, lg(2017870028, 751907156)) + test(-1851816270, lg(1506336851, -933796127)) + test(112959880, lg(-1747722429, -1855422773)) + test(1715333902, lg(-2139132623, -431847873)) + test(-453690224, lg(739274932, -924496860)) + test(-1503679197, lg(-1482800071, 29485338)) + test(1950154296, lg(237609240, 2048220960)) + test(2037562473, lg(-431092385, -1623412426)) + test(220707473, lg(2144172772, 1927987317)) + test(1902658020, lg(971459211, 1217334127)) + test(840583449, lg(-530209544, -763367967)) + test(2065572837, lg(-1322671605, -902331922)) + test(407536450, lg(1361976000, 1231329666)) + test(-1678479110, lg(-96547475, 1640676759)) + test(-1558558486, lg(1799144078, -936998300)) + test(-110470482, lg(221720683, -195204411)) + test(992932874, lg(2080474705, 1194291803)) + test(2035378556, lg(-1962255291, -228903623)) + test(542449527, lg(-1961045404, -1421226733)) + test(-1824846728, lg(1762001719, -96661681)) + test(-985103709, lg(568630982, -458482587)) + test(37361715, lg(-1237704639, -1275053966)) + test(-1555729529, lg(936273516, -1802824213)) + test(1534845437, lg(-870754516, -1755138351)) + test(-715250396, lg(964079858, -332884522)) + test(2003953821, lg(1769001167, 503396434)) + test(1631287431, lg(811930233, 1365142270)) + test(-1393125048, lg(-280291442, 1136496326)) + test(926193137, lg(439731659, 755060794)) + test(1141998463, lg(-561661919, -1701561506)) + test(480895538, lg(1556104387, 1080665841)) + test(-849143869, lg(1931061917, -1099252386)) + test(-1840233445, lg(2086961898, -298531087)) + test(47538111, lg(-1148008529, -1186490352)) + test(540301593, lg(807317094, 271251327)) + test(1903332829, lg(1077071399, 826295290)) + test(-1325859168, lg(781949710, -1637653074)) + test(-1476869146, lg(1778433204, -839352494)) + test(84316181, lg(-2038023199, -2088719372)) + test(524038724, lg(-1764916235, -1980649039)) + test(-794988445, lg(-1796682086, 1148567289)) + test(-1285356617, lg(-1606200144, 320886535)) + test(1441713710, lg(755146140, 2028753842)) + test(365800340, lg(-1851453861, -2073516593)) + test(2130603708, lg(-543327214, -1587342674)) + test(-1414171289, lg(506958308, -1249713021)) + test(-262714124, lg(-2097389477, 1923820719)) + test(158195454, lg(-374932306, -523558320)) + test(50128093, lg(-902905695, -925752196)) + test(-825145129, lg(-397013030, 646399757)) + test(-1344834498, lg(1764398539, -956440075)) + test(-103814738, lg(-1750710329, 1852419689)) + test(-1354282241, lg(-1664538473, 864969320)) + test(1408148925, lg(-500471847, -1312439708)) + test(1910019874, lg(14748928, 1899600418)) + test(1877620608, lg(-1985642880, -431011584)) + test(-378358620, lg(494530531, -200582329)) + test(492633155, lg(-2067225228, -1718331081)) + test(-1581166836, lg(-1799546135, 897340901)) + test(174532880, lg(25821759, 200092463)) + test(-629188646, lg(403690141, -1032813241)) + test(2139225425, lg(-1843541251, -308529236)) + test(200043623, lg(1643311840, 1780391559)) + test(1992690082, lg(1531597671, 764172997)) + test(754072038, lg(638938496, 182932582)) + test(-139359279, lg(309356043, -440275494)) + test(-1669264515, lg(-541225182, 1128039519)) + test(25583899, lg(-387355169, -378598204)) + test(1822592670, lg(1787244135, 103129337)) + test(1468680630, lg(-1654639624, -890602930)) + test(2103231504, lg(-1867306675, -303043235)) + test(1159389820, lg(1255224728, 265017316)) + test(776506096, lg(119985367, 695098919)) + test(-1303579924, lg(-332671386, 1583817866)) + test(1108767081, lg(1610629865, 571880320)) + test(-1101969936, lg(727577343, -1794328817)) + test(-1022615009, lg(730759795, -394092436)) + test(-1221218252, lg(-148400203, 1074931585)) + test(410005178, lg(181091802, 314250080)) + test(1180107886, lg(-1934827635, -889463837)) + test(425308062, lg(-1067099255, -650316777)) + test(1727927187, lg(1821917070, 174468125)) + test(-759140792, lg(474121453, -830281051)) + test(1698140938, lg(-402668999, -2100801229)) + test(512144461, lg(-615008378, -976157749)) + } + + @Test def toStringTest(): Unit = { + @inline def test(expected: String, x: Long): Unit = { + assertEquals(expected, x.toString()) + assertEquals(expected, hideFromOptimizer(x).toString()) + } + + test("0", lg(0)) + test("1", lg(1)) + test("-1", lg(-1)) + test("2147483647", IntMaxVal) + test("2147483648", IntMaxValPlus1) + test("-2147483648", IntMinVal) + test("-2147483649", IntMinValMinus1) + test("999999999", lg(999999999)) + test("1000000000", lg(1000000000)) + test("9007199254740991", MaxSafeDouble) + test("9007199254740992", TwoPow53) + test("-9007199254740991", MinSafeDouble) + test("-9007199254740992", NegTwoPow53) + + test("-86922", lg(-86922, -1)) + test("0", lg(0, 0)) + test("-21874015", lg(-21874015, -1)) + test("-2098921896914", lg(1317110830, -489)) + test("80985205273168", lg(-698060208, 18855)) + test("-12451732102972849", lg(858389071, -2899145)) + test("3350", lg(3350, 0)) + test("-92511590195450", lg(2005360390, -21540)) + test("-2", lg(-2, -1)) + test("446248293253325286", lg(1492984294, 103900277)) + test("499596119314678396", lg(116015740, 116321286)) + test("-3205893", lg(-3205893, -1)) + test("-88762100292970", lg(1988813462, -20667)) + test("-1278004", lg(-1278004, -1)) + test("-1", lg(-1, -1)) + test("-305393", lg(-305393, -1)) + test("-2", lg(-2, -1)) + test("80295210784300943", lg(-1678336113, 18695185)) + test("5", lg(5, 0)) + test("21", lg(21, 0)) + test("64", lg(64, 0)) + test("39146094", lg(39146094, 0)) + test("-1725731", lg(-1725731, -1)) + test("-768047304243556260", lg(-874655652, -178824949)) + test("-2726923242838", lg(380990122, -635)) + test("-1781092907033", lg(1318520807, -415)) + test("-213275", lg(-213275, -1)) + test("7662405832810", lg(184176746, 1784)) + test("-154157877107", lg(460945549, -36)) + test("-929963900939521435", lg(1586508389, -216524094)) + test("-6872", lg(-6872, -1)) + test("31842553544728", lg(-333987816, 7413)) + test("567569520305426", lg(-1817926382, 132147)) + test("19649016", lg(19649016, 0)) + test("-1349346", lg(-1349346, -1)) + test("9479824673588660", lg(-1372338764, 2207193)) + test("3521781", lg(3521781, 0)) + test("1740", lg(1740, 0)) + test("0", lg(0, 0)) + test("92834698468", lg(-1654582044, 21)) + test("-80139798970631138", lg(100400158, -18659001)) + test("30058", lg(30058, 0)) + test("-611022189550002", lg(1332815438, -142265)) + test("514941281681226", lg(472694602, 119894)) + test("2454759250363", lg(-1962042949, 571)) + test("14860137468144958", lg(1595551038, 3459895)) + test("-79255", lg(-79255, -1)) + test("2290122305310796", lg(-1501556660, 533210)) + test("-755641947927852310", lg(-463451414, -175936602)) + test("-2621852156570472370", lg(-771329970, -610447526)) + test("-37956135735", lg(698569929, -9)) + test("853219", lg(853219, 0)) + test("901", lg(901, 0)) + test("4385596303898", lg(434694682, 1021)) + test("-972597865", lg(-972597865, -1)) + test("-8057379", lg(-8057379, -1)) + test("-14968", lg(-14968, -1)) + test("-98204964", lg(-98204964, -1)) + test("335479", lg(335479, 0)) + test("-429441918886", lg(54810714, -100)) + test("9798741", lg(9798741, 0)) + test("135908509698671494", lg(-896875642, 31643665)) + test("-141095409221912371", lg(233027789, -32851335)) + test("-9040837797787104", lg(-359183840, -2104985)) + test("-889", lg(-889, -1)) + test("3222082994", lg(-1072884302, 0)) + test("-1454853", lg(-1454853, -1)) + test("547641844425", lg(-2113969463, 127)) + test("2528132853", lg(-1766834443, 0)) + test("242", lg(242, 0)) + test("-1655763891", lg(-1655763891, -1)) + test("82", lg(82, 0)) + test("-120254181", lg(-120254181, -1)) + test("-210088", lg(-210088, -1)) + test("-2", lg(-2, -1)) + test("250255458324299", lg(598888267, 58267)) + test("-100656997", lg(-100656997, -1)) + test("-24097181761", lg(1672622015, -6)) + test("206088", lg(206088, 0)) + test("-593", lg(-593, -1)) + test("-99542049", lg(-99542049, -1)) + test("421501", lg(421501, 0)) + test("-2", lg(-2, -1)) + test("-101", lg(-101, -1)) + test("3", lg(3, 0)) + test("14967492854", lg(2082590966, 3)) + test("-1528445803513883", lg(-86853659, -355870)) + test("26760588095306", lg(-1353126070, 6230)) + test("12452686330472", lg(1576139368, 2899)) + test("-130630407827875", lg(1022479965, -30415)) + test("-10281777615", lg(-1691843023, -3)) + test("-90497242609445", lg(2013284571, -21071)) + test("-13935178716929", lg(1990158591, -3245)) + test("-11308540", lg(-11308540, -1)) + test("545166", lg(545166, 0)) + test("-1043705339124703", lg(1778574369, -243007)) + test("510", lg(510, 0)) + test("-2485453027", lg(1809514269, -1)) + test("-15103", lg(-15103, -1)) + test("-168776672025670194", lg(-779514418, -39296382)) + } + + @Test def toByte(): Unit = { + @inline def test(expected: Byte, x: Long): Unit = { + assertEquals(expected, x.toByte) + assertEquals(expected, hideFromOptimizer(x).toByte) + } + + test(0, lg(0)) + test(-1, lg(-1)) + test(0x98.toByte, lg(0xfedcba98, 0x76543210)) + + test(102, lg(-1755353242, -1245269156)) + test(77, lg(-359135667, 1391746928)) + test(-47, lg(-957203503, 1516742479)) + test(-22, lg(-1928741654, 1162703256)) + test(-113, lg(-1698228849, 1497186951)) + test(-84, lg(-68041812, -2115448390)) + test(33, lg(1534301729, 1468418695)) + test(113, lg(1101829489, -514588123)) + test(12, lg(-1437577204, 1896338488)) + test(86, lg(-857671082, -1304076936)) + test(-36, lg(-292818212, -1485650549)) + test(88, lg(1044510040, 147719255)) + test(107, lg(-1166136469, 78076997)) + test(61, lg(500131901, 248541787)) + test(99, lg(1863435363, -1465266670)) + test(-76, lg(136483252, 1662447178)) + test(0, lg(1787939584, 1303926235)) + test(-69, lg(2105657787, 845433223)) + test(26, lg(-1298285542, -1826340261)) + test(64, lg(-766959552, -326327606)) + } + + @Test def toShort(): Unit = { + @inline def test(expected: Short, x: Long): Unit = { + assertEquals(expected, x.toShort) + assertEquals(expected, hideFromOptimizer(x).toShort) + } + + test(0, lg(0)) + test(-1, lg(-1)) + test(0xba98.toShort, lg(0xfedcba98, 0x76543210)) + + test(-670, lg(1925512546, -812328457)) + test(-15861, lg(2028716555, -1639243756)) + test(9963, lg(-1970657557, -1904990267)) + test(18394, lg(-1012119590, -1704668195)) + test(-7956, lg(848486636, -810351120)) + test(21453, lg(2103989197, 955793808)) + test(22979, lg(-237938237, -703399620)) + test(8452, lg(666247428, -1109641927)) + test(-26563, lg(1824561213, -872828437)) + test(-5754, lg(-10950266, -1779965318)) + test(11796, lg(1251814932, -491043391)) + test(18020, lg(-117750172, -366379322)) + test(3768, lg(-2095575368, 965048164)) + test(-4579, lg(-177410531, 1454361289)) + test(-29102, lg(-359035310, -790126871)) + test(30020, lg(1486058820, 1675509542)) + test(-13051, lg(268881157, -342358099)) + test(-2720, lg(-1089211040, 747294820)) + test(4726, lg(1163661942, 1708185440)) + test(-16878, lg(-1363821038, -1952481751)) + } + + @Test def toInt(): Unit = { + @inline def test(expected: Int, x: Long): Unit = { + assertEquals(expected, x.toInt) + assertEquals(expected, hideFromOptimizer(x).toInt) + } + + test(0, lg(0)) + test(-1, lg(-1)) + test(0xfedcba98, lg(0xfedcba98, 0x76543210)) + + test(-1869423218, lg(-1869423218, -5516698)) + test(450655357, lg(450655357, -521592408)) + test(-596464514, lg(-596464514, 629510497)) + test(1668957409, lg(1668957409, 1231040344)) + test(-313016061, lg(-313016061, 283507721)) + test(-406779255, lg(-406779255, 1389322213)) + test(-1125423893, lg(-1125423893, -436921025)) + test(1491309031, lg(1491309031, 948401259)) + test(360542935, lg(360542935, -1033853853)) + test(178673916, lg(178673916, -2045867551)) + test(-1167644863, lg(-1167644863, 738699232)) + test(-1852739075, lg(-1852739075, 950841298)) + test(-1965326912, lg(-1965326912, 1694989583)) + test(-141857741, lg(-141857741, -1197558189)) + test(-938893686, lg(-938893686, 1763555645)) + test(-1178638558, lg(-1178638558, 299067184)) + test(-1296424902, lg(-1296424902, -1694453755)) + test(204387309, lg(204387309, -240738711)) + test(-942136876, lg(-942136876, -527367452)) + test(-1703892744, lg(-1703892744, 240186844)) + } + + @Test def toLong(): Unit = { + @inline def test(expected: Long, x: Long): Unit = { + assertEquals(expected, x.toLong) + assertEquals(expected, hideFromOptimizer(x).toLong) + } + + test(0L, lg(0)) + test(-1L, lg(-1)) + test(0x76543210fedcba98L, lg(0xfedcba98, 0x76543210)) + + test(6907420169189163269L, lg(-85753595, 1608259083)) + test(-6558938415102325809L, lg(539593679, -1527121853)) + test(-7633462319206780754L, lg(-379998034, -1777303946)) + test(-4051533910437546682L, lg(-655641274, -943321249)) + test(-3890339056676572253L, lg(1727460259, -905790147)) + test(-3091543614186826784L, lg(1824805856, -719806090)) + test(2806266116723834799L, lg(948567983, 653384746)) + test(-1741184441450532748L, lg(-957910924, -405401095)) + test(3395924718030703835L, lg(-433042213, 790675337)) + test(-7712245542997911283L, lg(889526541, -1795647094)) + test(-2751064647855401745L, lg(1316066543, -640532153)) + test(5225909624054208018L, lg(1913378322, 1216751901)) + test(1334025594846136121L, lg(-434813127, 310602037)) + test(-1574909139329823322L, lg(1689963942, -366687109)) + test(-9142211941778525044L, lg(754250892, -2128587091)) + test(-5517402195275269807L, lg(-1817691823, -1284620305)) + test(7612683537409046411L, lg(-222627957, 1772466007)) + test(-2955859733488660001L, lg(-1282993697, -688214725)) + test(462084382441397543L, lg(799857959, 107587404)) + test(8801656334077465992L, lg(2076251528, 2049295309)) + } + + @Test def toFloat_strict(): Unit = { + assumeTrue("Assumed strict floats", hasStrictFloats) + + @inline def test(expected: Float, x: Long, epsilon: Float = 0.0f): Unit = { + assertEquals(expected, x.toFloat, epsilon) + assertEquals(expected, hideFromOptimizer(x).toFloat, epsilon) + } + + test(0, lg(0)) + test(-1, lg(-1)) + + // Closure seems to incorrectly rewrite the constant on the right :-( + val epsilon = if (isInFullOpt) 1E4f else 0.0f + test(9.223372E18f, MaxVal, epsilon) + test(-9.223372E18f, MinVal, epsilon) + + test(4.7971489E18f, lg(-1026388143, 1116923232)) + test(-2.24047663E18f, lg(-1288678667, -521651607)) + test(4.59211416E18f, lg(1192262605, 1069184891)) + test(3.38942079E18f, lg(-180353617, 789161022)) + test(-6.8076878E18f, lg(-1158443188, -1585038363)) + test(7.4159717E18f, lg(906981906, 1726665521)) + test(-1.85275997E18f, lg(2042933575, -431379283)) + test(5.7344188E18f, lg(599900903, 1335148382)) + test(3.20410168E18f, lg(1458166084, 746013039)) + test(-7.2310311E18f, lg(1956524672, -1683605603)) + test(7.7151362E18f, lg(478583639, 1796320118)) + test(1.41365268E18f, lg(-1645816617, 329141676)) + test(-3.03197918E18f, lg(184187116, -705937657)) + test(-4.04287594E18f, lg(659513335, -941305424)) + test(-7.8204678E18f, lg(770505156, -1820844549)) + test(-5.9733025E18f, lg(929928858, -1390767911)) + test(1.1261721E18f, lg(-1475096259, 262207373)) + test(4.00884963E18f, lg(787691795, 933383012)) + test(-1.43511611E18f, lg(1189057493, -334139018)) + test(3.81415059E18f, lg(-618946450, 888051141)) + } + + @Test def toDouble(): Unit = { + @inline def test(expected: Double, x: Long, epsilon: Double = 0.0): Unit = { + assertEquals(expected, x.toDouble, epsilon) + assertEquals(expected, hideFromOptimizer(x).toDouble, epsilon) + } + + test(0, lg(0)) + test(-1, lg(-1)) + + // Closure seems to incorrectly rewrite the constant on the right :-( + val epsilon = if (isInFullOpt) 1E4 else 0.0 + test(9.223372036854776E18, MaxVal, epsilon) + test(-9.223372036854776E18, MinVal, epsilon) + + test(3.4240179834317537E18, lg(-151011088, 797216310)) + test(8.5596043411285968E16, lg(-508205099, 19929381)) + test(-3.1630346897289943E18, lg(1249322201, -736451403)) + test(-4.4847682439933604E18, lg(483575860, -1044191477)) + test(-6.4014772289576371E17, lg(-1526343930, -149046007)) + test(-1.76968119148756736E18, lg(531728928, -412036011)) + test(-8.5606671350959739E18, lg(-734111585, -1993185640)) + test(-9.0403963253949932E18, lg(-1407864332, -2104881296)) + test(-6.4988752582247977E18, lg(-1712351423, -1513137310)) + test(-7.7788492399114394E17, lg(1969244733, -181115448)) + test(7.6357174849871442E18, lg(-907683842, 1777829016)) + test(1.25338659134517658E18, lg(-815927209, 291826806)) + test(-3.1910241505692349E18, lg(463523496, -742968207)) + test(7.4216510087652332E18, lg(1482622807, 1727987781)) + test(-8.189046896086654E18, lg(1170040143, -1906661060)) + test(6.8316272807487539E18, lg(-85609173, 1590612176)) + test(-8.0611115909320561E18, lg(-1212811257, -1876873801)) + test(1.7127521901359959E18, lg(-648802816, 398781194)) + test(-6.4442523492577423E18, lg(-1484519186, -1500419423)) + test(-1.71264450938175027E18, lg(-2016996893, -398756124)) + } + + @Test def fromDouble(): Unit = { + @inline def test(expected: Long, x: Double): Unit = { + assertEquals(expected, x.toLong) + assertEquals(expected, hideDoubleFromOptimizer(x).toLong) + } + + val twoPow63 = 9.223372036854776E18 + val twoPow63NextUp = 9.223372036854778E18 + val twoPow63NextDown = 9.2233720368547748E18 + + // Specials + test(lg(0), 0.0) + test(lg(0), -0.0) + test(lg(0), Double.NaN) + test(MaxVal, Double.PositiveInfinity) + test(MinVal, Double.NegativeInfinity) + + // Corner cases + test(lg(0), Double.MinPositiveValue) + test(lg(0), -Double.MinPositiveValue) + test(MaxVal, twoPow63) + test(MaxVal, twoPow63NextUp) + if (!isInFullOpt) { + // GCC incorrectly rewrites the Double constants on the rhs + test(lg(-1024, 2147483647), twoPow63NextDown) + test(MinVal, -twoPow63) + } + test(MinVal, -twoPow63NextUp) + test(lg(1024, -2147483648), -twoPow63NextDown) + + // Absolute value too big + test(MaxVal, 1.5623101234432471E19) + test(MaxVal, 1.0425697303244048E19) + test(MaxVal, 1.500625248806836E19) + test(MinVal, -1.5623101234432471E19) + test(MinVal, -1.0425697303244048E19) + test(MinVal, -1.500625248806836E19) + + // Normal cases + test(lg(-235867169, -1408375), -6.048920506403873E15) + test(lg(-69250108, 1979931), 8.503743119053764E15) + test(lg(-305079043, 917242), 3.939528382405885E15) + test(lg(687182505, -933310), -4.008535239847255E15) + test(lg(-268193171, -177333), -7.61635408727443E14) + test(lg(-1529111384, 564485), 2.424447379938472E15) + test(lg(1128309745, -1082296), -4.648424796281871E15) + test(lg(-418524847, 1986827), 8.533360864252241E15) + test(lg(615477490, -646039), -2.774715761463054E15) + test(lg(-1546293262, 815087), 3.500774757068786E15) + test(lg(455797153, -1037726), -4.456998776411743E15) + test(lg(587409995, 1185272), 5.090705064274507E15) + test(lg(-1405692887, -769407), -3.304575013039063E15) + test(lg(667130924, 412), 1.770193656876E12) + test(lg(632602096, -506779), -2.176598598697488E15) + test(lg(1820137888, 955044), 4.101884566378912E15) + test(lg(682339811, 951155), 4.085180300766691E15) + test(lg(1394139649, -1084392), -4.657426781904383E15) + test(lg(-677499131, 663585), 2.850079490584325E15) + test(lg(805667746, 1417318), 6.087335263699874E15) + test(lg(990918920, -1563103), -6.713475274360568E15) + test(lg(-1427573595, 969167), 4.162543436756133E15) + test(lg(-699306484, -1852353), -7.955791959986676E15) + test(lg(-1807820942, 1218020), 5.231358553020274E15) + test(lg(1243383338, 349241), 1.499979916805674E15) + test(lg(-479557118, 1183372), 5.08254785441229E15) + test(lg(1413560577, 654135), 2.809489845729537E15) + test(lg(-2047369879, 1135596), 4.877349929065833E15) + test(lg(-741161617, -1594192), -6.846998949739153E15) + test(lg(-2115502919, 1443312), 6.198980017388729E15) + test(lg(1015092168, 1152178), 4.948567844262856E15) + test(lg(-1340352375, -863152), -3.707206656862071E15) + test(lg(1990353383, -2017544), -8.665283507887641E15) + test(lg(-1683508387, -666397), -2.862150709693603E15) + test(lg(2095665836, 369587), 1.587366173692588E15) + test(lg(229204175, 77510), 3.32903144317135E14) + test(lg(-1988104885, 1374301), 5.902580156722507E15) + test(lg(-1032158224, -233238), -1.001746319375376E15) + test(lg(1321723055, -121058), -5.19938829196113E14) + test(lg(-1959869514, -1892991), -8.130332101524554E15) + test(lg(-1173650161, -412038), -1.769686613392113E15) + test(lg(-1692936735, -1697943), -7.292607053441567E15) + test(lg(-1368921565, 621023), 2.667276401109539E15) + } + + @Test def comparisons(): Unit = { + @inline def testInner(x: Long, y: Long, expected: Int): Unit = { + assertEquals(expected, x.compareTo(y).signum) + assertEquals(expected, x.compareTo(y: java.lang.Long).signum) + assertEquals(expected == 0, x.equals(y)) + assertEquals(expected != 0, !x.equals(y)) + assertEquals(expected < 0, x < y) + assertEquals(expected <= 0, x <= y) + assertEquals(expected > 0, x > y) + assertEquals(expected >= 0, x >= y) + } + + @inline def test(x: Long, y: Long, expected: Int): Unit = { + testInner(x, y, expected) + testInner(hideFromOptimizer(x), y, expected) + testInner(x, hideFromOptimizer(y), expected) + testInner(hideFromOptimizer(x), hideFromOptimizer(y), expected) + } + + test(lg(0), lg(0), 0) + test(lg(0), lg(1), -1) + test(lg(0), lg(-1), 1) + test(MaxVal, MinVal, 1) + test(MinVal, MaxVal, -1) + + // Positive and negative numbers requiring lo to be compared via unsigned + test(lg(0x87654321, 0x654789ab), lg(0x12345678, 0x654789ab), 1) + test(lg(0x87654321, 0x89abcdef), lg(0x12345678, 0x89abcdef), 1) + + // Whitebox corner cases + test(lg(-1, 0), lg(0, 0), 1) + test(lg(0, 0), lg(-1, 0), -1) + + test(lg(173547161, -1884162399), lg(173547161, -1884162399), 0) + test(lg(-1131022787, -472928681), lg(-1131022787, -472928681), 0) + test(lg(-1426164191, 1230100202), lg(-1426164191, 1230100202), 0) + test(lg(-865774626, 1656835920), lg(-865774626, 1656835920), 0) + test(lg(323675568, -725625271), lg(323675568, -725625271), 0) + test(lg(-480943595, -1454872354), lg(-480943595, -1454872354), 0) + test(lg(-626788852, 1037229194), lg(-626788852, 1037229194), 0) + test(lg(-717389653, 232764759), lg(-717389653, 232764759), 0) + test(lg(-861190423, -1233377930), lg(-861190423, -1233377930), 0) + test(lg(-424759090, 2081288998), lg(-424759090, 2081288998), 0) + + test(lg(-1092215366, 753517982), lg(349136582, -103427916), 1) + test(lg(363609757, -1151024787), lg(472951646, -1802702403), 1) + test(lg(604332601, 1869576376), lg(1642523661, 1083165388), 1) + test(lg(309732766, 1349689861), lg(1287300335, 1464464808), -1) + test(lg(-1309668929, -965374553), lg(-1952664258, 53355972), -1) + test(lg(1881957750, 388099413), lg(1843907319, -1819358211), 1) + test(lg(-969542710, 864289013), lg(-1025874755, 1102102911), -1) + test(lg(-1425636748, -220185411), lg(1184140796, 40447497), -1) + test(lg(242386079, 452246653), lg(435337552, -956883630), 1) + test(lg(-1007383056, 344856628), lg(-195994328, 635205577), -1) + test(lg(-1652098619, 2042392045), lg(819672742, -2139008380), 1) + test(lg(1423590080, 1919857862), lg(918443721, 1202178673), 1) + test(lg(-1726296442, 302493002), lg(314727886, 1583734481), -1) + test(lg(-2124336701, 769721099), lg(461146322, -591528218), 1) + test(lg(1544826993, -689540243), lg(-1107003972, -1622786326), 1) + test(lg(2050227802, 951848379), lg(-774454951, 1675192386), -1) + test(lg(251298779, -327163776), lg(767615943, 1531730165), -1) + test(lg(1890888425, 761833495), lg(1870917399, 2027251288), -1) + test(lg(594868313, 126374530), lg(-1567484882, -1199917303), 1) + test(lg(-914360997, -703435655), lg(2049249771, -1581791194), 1) + test(lg(-732484281, -738997306), lg(1445589646, 1910084021), -1) + test(lg(340771740, 1351224018), lg(459324247, 1301544548), 1) + test(lg(-940710332, 1344186742), lg(-1143672211, 1112189558), 1) + test(lg(-804347876, 364046111), lg(-4317439, -1733157379), 1) + test(lg(914214836, -1226397169), lg(-299522125, 1393423940), -1) + test(lg(1244546642, 1821771770), lg(44151604, -1398558064), 1) + test(lg(-2094640323, -1469168677), lg(-263524564, 88152070), -1) + test(lg(-124567753, -93039352), lg(-200449699, -30383890), -1) + test(lg(161119306, -1098626173), lg(-137189625, 1289988889), -1) + test(lg(-2052616761, 846341515), lg(-150583666, 1044666783), -1) + test(lg(-10359669, -1628837253), lg(165345114, 1529503183), -1) + test(lg(1717988228, 1622548180), lg(834798590, -1907713185), 1) + test(lg(-1416372109, -353311343), lg(-722195813, -2060788759), 1) + test(lg(980620531, -300588346), lg(-889348218, 1805452697), -1) + test(lg(-465681479, 556544868), lg(-684386776, 724207906), -1) + test(lg(1720493596, 1118244444), lg(2048914469, -789300492), 1) + test(lg(-1259678249, -1557339417), lg(-1908141376, -468055129), -1) + test(lg(1374750478, 1591281700), lg(1107931774, 1073828802), 1) + test(lg(1307860622, -1769647645), lg(-1521056504, 1476896409), -1) + test(lg(1870719065, -606069057), lg(1219817813, -1063559023), 1) + test(lg(-526519712, 1166848880), lg(-748095992, 59925642), 1) + test(lg(-1011429486, -2053277854), lg(537284118, 1714076830), -1) + test(lg(-669104363, -107157886), lg(1647426475, -1784147450), 1) + test(lg(-389860398, 693324889), lg(1047633230, -1757663140), 1) + test(lg(-200206281, 96771163), lg(613429570, -1206384633), 1) + test(lg(-1436571081, -2050819200), lg(-665572561, 644211697), -1) + test(lg(620796821, -567816428), lg(-109412350, -624638338), 1) + test(lg(858464866, -2104597302), lg(-987329519, 1189618105), -1) + test(lg(-1342634556, -1517778924), lg(-693373055, 142499537), -1) + test(lg(1839280888, -168388422), lg(-1645740821, -1967920957), 1) + } + + @Test def bitwise_not_~(): Unit = { + @inline def test(expected: Long, x: Long): Unit = { + assertEquals(expected, ~x) + assertEquals(expected, ~hideFromOptimizer(x)) + } + + test(lg(1664374422, 327449892), lg(-1664374423, -327449893)) + test(lg(-2033180390, -1179462631), lg(2033180389, 1179462630)) + test(lg(-1134559214, 581653069), lg(1134559213, -581653070)) + test(lg(-304074638, -795726117), lg(304074637, 795726116)) + test(lg(-1711832787, 1153070599), lg(1711832786, -1153070600)) + test(lg(-1526506637, 966114536), lg(1526506636, -966114537)) + test(lg(4362923, 1155261397), lg(-4362924, -1155261398)) + test(lg(-1976846289, -68873334), lg(1976846288, 68873333)) + test(lg(-980717878, -1171857118), lg(980717877, 1171857117)) + test(lg(1087568370, 543704246), lg(-1087568371, -543704247)) + test(lg(466027718, 693030605), lg(-466027719, -693030606)) + test(lg(457333958, 1344424074), lg(-457333959, -1344424075)) + test(lg(-1195369388, -1211454825), lg(1195369387, 1211454824)) + test(lg(1637646574, 618600148), lg(-1637646575, -618600149)) + test(lg(1882417448, 81477816), lg(-1882417449, -81477817)) + test(lg(-755550612, -520392566), lg(755550611, 520392565)) + test(lg(-754282895, -1550447287), lg(754282894, 1550447286)) + test(lg(949172349, -708028075), lg(-949172350, 708028074)) + test(lg(1587810906, -1344614950), lg(-1587810907, 1344614949)) + test(lg(-1761617639, -353615615), lg(1761617638, 353615614)) + test(lg(-153730678, 249152220), lg(153730677, -249152221)) + test(lg(-189227914, 2071190797), lg(189227913, -2071190798)) + test(lg(-853867870, 445686068), lg(853867869, -445686069)) + test(lg(-779434875, 417640992), lg(779434874, -417640993)) + test(lg(1997707715, -1100729422), lg(-1997707716, 1100729421)) + test(lg(1171311729, -1236578928), lg(-1171311730, 1236578927)) + test(lg(-833922040, 1773972621), lg(833922039, -1773972622)) + test(lg(1414648869, 1222586075), lg(-1414648870, -1222586076)) + test(lg(1123832582, -1270176018), lg(-1123832583, 1270176017)) + test(lg(1163066309, 237396271), lg(-1163066310, -237396272)) + test(lg(-1826566063, 509270117), lg(1826566062, -509270118)) + test(lg(-450318543, 1650640099), lg(450318542, -1650640100)) + test(lg(1461907704, -27364749), lg(-1461907705, 27364748)) + test(lg(1012261256, 1691289854), lg(-1012261257, -1691289855)) + test(lg(-1929178874, 1804481536), lg(1929178873, -1804481537)) + test(lg(-888719200, -1846455123), lg(888719199, 1846455122)) + test(lg(984231682, -867292444), lg(-984231683, 867292443)) + test(lg(2105026705, -16146223), lg(-2105026706, 16146222)) + test(lg(1742028653, -1648876191), lg(-1742028654, 1648876190)) + test(lg(1922039594, -60702355), lg(-1922039595, 60702354)) + test(lg(264728648, 275960741), lg(-264728649, -275960742)) + test(lg(1237639032, -1761272007), lg(-1237639033, 1761272006)) + test(lg(1118919822, 901486922), lg(-1118919823, -901486923)) + test(lg(18001220, -1121574637), lg(-18001221, 1121574636)) + test(lg(2122002356, -1370943785), lg(-2122002357, 1370943784)) + test(lg(2006182035, -1422441078), lg(-2006182036, 1422441077)) + test(lg(1314896174, 460075839), lg(-1314896175, -460075840)) + test(lg(1829402918, -1031934892), lg(-1829402919, 1031934891)) + test(lg(-2138673173, -107590306), lg(2138673172, 107590305)) + test(lg(1382443514, -56307753), lg(-1382443515, 56307752)) + } + + @Test def bitwise_or_|(): Unit = { + @inline def test(expected: Long, x: Long, y: Long): Unit = { + assertEquals(expected, x | y) + assertEquals(expected, hideFromOptimizer(x) | y) + assertEquals(expected, x | hideFromOptimizer(y)) + assertEquals(expected, hideFromOptimizer(x) | hideFromOptimizer(y)) + } + + test(lg(1467334397, -608514), lg(1198889513, -170491266), lg(356560637, 1244673694)) + test(lg(-1645778056, 796647391), lg(-1930990792, 627822941), lg(-1849669008, 185716690)) + test(lg(2121785322, -3735189), lg(711185578, -154795743), lg(1446469570, -104529814)) + test(lg(401988479, 1357601567), lg(356565628, 275405582), lg(380967239, 1356925723)) + test(lg(-167780425, -167778583), lg(1968397619, -447093015), lg(-1242708043, 1353146913)) + test(lg(-34603479, -565777), lg(-2121965024, -76133937), lg(2104409609, -1365814226)) + test(lg(-537280529, -10535202), lg(1496398822, -548061626), lg(-556169301, -245689186)) + test(lg(2132402169, -1093993487), lg(856203065, -1102382704), lg(1276763344, 377524977)) + test(lg(500957183, -5777537), lg(474066920, -215674305), lg(366737695, 530830706)) + test(lg(-1077937506, 1876426559), lg(-1543310820, 664058893), lg(1002387606, 1826081595)) + test(lg(-2121745, -302649859), lg(1606847457, -857707283), lg(-82108753, 628476252)) + test(lg(2113649662, -9748643), lg(703699686, -1218298019), lg(1575693246, -565500071)) + test(lg(1845274268, 1608495102), lg(1281663616, 1255777790), lg(1708663964, 1604300502)) + test(lg(-174066179, 1861146349), lg(-1315547660, 1726760037), lg(-442781559, 235328140)) + test(lg(2139059199, -40115785), lg(2014986997, -1130692301), lg(124088654, 1637408903)) + test(lg(-4195861, -679630869), lg(1653153899, 1412277603), lg(-1615398494, -682581111)) + test(lg(601802239, 1937620978), lg(551077237, 1349033186), lg(597575118, 1662855120)) + test(lg(-1383162189, -1107312899), lg(613289137, -1123701660), lg(-1383294317, 369006329)) + test(lg(-141299717, -576585865), lg(-418175046, -593383309), lg(1468132939, 360734532)) + test(lg(1998808831, -86066691), lg(1428236018, -1294026291), lg(572735565, 1213340152)) + test(lg(-1680360554, -738459673), lg(-1949058688, -1013245209), lg(416580246, 300148007)) + test(lg(-1073808964, -183288105), lg(-1746245220, 1427323605), lg(-1185613404, -469621610)) + test(lg(1475346349, 1845485055), lg(1445648649, 701317455), lg(1407661733, 1287118327)) + test(lg(-33566733, -268503975), lg(-1861500445, 764080137), lg(-33812527, -411163560)) + test(lg(-286605413, 1602191341), lg(-1408712806, 393166157), lg(1323973395, 1580353248)) + test(lg(-553947394, -2013546505), lg(-2072304578, -2142600249), lg(-625840402, -2018265417)) + test(lg(-553746946, -140321), lg(450125308, 1742298015), lg(-999674466, -89794491)) + test(lg(-16643, -68193313), lg(1239068904, -68194107), lg(-1092247939, -639552609)) + test(lg(-52733444, -1159005505), lg(-2075047684, -1706497393), lg(-119858776, -1461536706)) + test(lg(-121509406, 1048526839), lg(-1065293728, 1045575815), lg(943802850, 4130803)) + test(lg(1844952571, -1327497834), lg(1688647147, -1327540094), lg(1767049400, -1609892586)) + test(lg(-5046291, -1345721876), lg(-207425559, 231270892), lg(515004644, -1349918716)) + test(lg(-1075861506, -67698709), lg(781813534, 1274454635), lg(-1814682890, -1182466103)) + test(lg(2144796219, -17303617), lg(1792206347, -54265949), lg(931436592, -625499620)) + test(lg(-874545153, -1611301156), lg(-1957992337, 421859924), lg(1138122674, -1896513908)) + test(lg(-1218644010, -67141891), lg(-1220262128, 1790926509), lg(-2107837994, -245286664)) + test(lg(-2555905, 2146160604), lg(-485426246, 2122993116), lg(-1077361187, 795578180)) + test(lg(999978447, 2129346287), lg(713580935, 2059541733), lg(957494730, 1688940106)) + test(lg(-836113, 1983903423), lg(-181332639, 608154803), lg(787627150, 1378378253)) + test(lg(-273220891, -1242040457), lg(-944448827, -1528432780), lg(-374967708, 364320051)) + test(lg(-52433921, -1615929419), lg(1822361801, -1626992863), lg(-1865553026, -1867721804)) + test(lg(-1646593, -1583649), lg(-333036705, -39743141), lg(-136127263, -404241201)) + test(lg(-105959457, -50406273), lg(1342309595, 143297662), lg(-1448137844, -50933699)) + test(lg(-480707585, -87100434), lg(-514802766, 718197230), lg(1113082335, -259890518)) + test(lg(-73693249, -555903498), lg(-476348284, -1025699402), lg(1518405435, 1545110880)) + test(lg(-1646871041, -403194029), lg(-2058311589, 1135057747), lg(-1664731675, -1535754941)) + test(lg(-203423937, -34342961), lg(333362997, -34482226), lg(-205173969, 1754490115)) + test(lg(2083487743, -159909991), lg(2083354303, -2043490039), lg(1344953817, -195725679)) + test(lg(-134268937, -680984614), lg(-942983837, -683124136), lg(909452980, -1021249590)) + test(lg(-17107060, -35914117), lg(-402624124, -505696678), lg(-688199800, 2110291577)) + } + + @Test def bitwise_and_&(): Unit = { + @inline def test(expected: Long, x: Long, y: Long): Unit = { + assertEquals(expected, x & y) + assertEquals(expected, hideFromOptimizer(x) & y) + assertEquals(expected, x & hideFromOptimizer(y)) + assertEquals(expected, hideFromOptimizer(x) & hideFromOptimizer(y)) + } + + test(lg(-2012982272, 17896961), lg(-1973652216, 353474049), lg(-576365513, -1546420349)) + test(lg(440467456, -805024688), lg(2054268182, -735220496), lg(-1706223071, -653894309)) + test(lg(-1073741824, -2144861952), lg(-761230816, -1888512251), lg(-988806710, -256349768)) + test(lg(-1977056222, -1878455803), lg(-834874333, -101893315), lg(-1964333382, -1877225849)) + test(lg(-1069166300, 304091682), lg(-767041747, 1403541430), lg(-320482908, 442929698)) + test(lg(193986570, 67633664), lg(1538292767, 67928849), lg(261587146, 2097883842)) + test(lg(167772308, 35669040), lg(448790964, 1852174074), lg(-284620129, 35804464)) + test(lg(540801, 554500096), lg(123267521, 1965916169), lg(-401979731, 588194498)) + test(lg(-1878826824, 268436097), lg(-1725202754, 324931273), lg(-1240211271, 948007557)) + test(lg(306780164, 8388625), lg(1044995460, -1447811559), lg(1381579300, 378161591)) + test(lg(29904144, 12096051), lg(1640550232, -1980050765), lg(-1613988461, 381206391)) + test(lg(-963297278, 537741320), lg(-810205145, 832395272), lg(-153237294, -1368559681)) + test(lg(-2138566639, -1881372656), lg(-2087037677, -539042218), lg(-1930915595, -1879201391)) + test(lg(348136448, 1461360), lg(936077102, 1888906741), lg(-590306112, 153013360)) + test(lg(-2147459072, 50628864), lg(-1520343420, -480326676), lg(-1031638712, 463833361)) + test(lg(-805279656, -972355264), lg(-603625122, -837874740), lg(-266310439, -433325742)) + test(lg(1763723264, 1095287337), lg(2101242821, 1363798717), lg(-337523686, -1007893653)) + test(lg(1296302405, 1947206722), lg(-849542331, 2084521938), lg(1866786159, -179258269)) + test(lg(1275593362, 814484868), lg(1283984114, 1922846117), lg(-42342754, 948944324)) + test(lg(1081520, 35397649), lg(18451376, 39592223), lg(-300891980, 43819665)) + test(lg(539714600, -1617688304), lg(1772840110, -1611388521), lg(876572201, -1080057992)) + test(lg(268660738, 1111507460), lg(-1792575438, 1131693597), lg(2026108738, -691967420)) + test(lg(-1977139054, 2393104), lg(-1977130853, 1105495064), lg(-289941322, 37545108)) + test(lg(-2145341308, -1333516032), lg(-1590955612, -1330697458), lg(-924798828, -1177272879)) + test(lg(-1503395487, -299827136), lg(-285931035, -293654078), lg(-1486596765, -31342500)) + test(lg(1233401994, 34091008), lg(1237743775, -1293389691), lg(1803860874, 1175174664)) + test(lg(-932558672, 270533826), lg(-839976008, 900736195), lg(-362132238, -668577850)) + test(lg(117477888, 473995424), lg(1202887172, 484547048), lg(793351913, -1622877017)) + test(lg(302600257, -2030040226), lg(1393155525, -2025583778), lg(-1164217783, -416769026)) + test(lg(145293649, 536871648), lg(-658787467, -1534848013), lg(770509273, 861439716)) + test(lg(1546608834, 302001248), lg(1550840002, 1588870758), lg(2084528882, 302148833)) + test(lg(201606209, -695465177), lg(481609689, -152204489), lg(1279544421, -561242137)) + test(lg(608207492, -2112820352), lg(-1529763097, -1978531900), lg(641783708, -2039026814)) + test(lg(270672860, -1476361723), lg(887514076, -129985897), lg(423346174, -1364800691)) + test(lg(606102544, -503185240), lg(1736270961, -223672071), lg(748709016, -498985816)) + test(lg(144970344, 74547586), lg(413438572, 628333003), lg(-1964689415, -2039117914)) + test(lg(0, 33646849), lg(-1441786846, -952014445), lg(1364118108, 582220621)) + test(lg(886489100, -1836576552), lg(-167845571, -610782244), lg(920048140, -1832380167)) + test(lg(181408260, 8425760), lg(1070668735, 1223734716), lg(1255200260, 310500128)) + test(lg(18633796, 1494253868), lg(565998918, 2102701486), lg(1230790357, -651115716)) + test(lg(1242169472, 1074954242), lg(1259021457, -988117846), lg(-95497780, 2025257730)) + test(lg(202639938, 134272082), lg(236334914, 210367602), lg(-1388488109, 672191707)) + test(lg(955253125, 1994661641), lg(2029259749, 2012495659), lg(-1125022313, -17866867)) + test(lg(134242336, 1377566768), lg(2078335024, -748696528), lg(-1944488853, 1455161657)) + test(lg(883214088, 536873986), lg(1962270604, 747650594), lg(1051641707, -1606005365)) + test(lg(203000132, 19923458), lg(504991188, 623990339), lg(-1919047324, 331123498)) + test(lg(274893395, 1881151488), lg(409659995, 1887189252), lg(384277491, 1973591160)) + test(lg(115235, 335685459), lg(872793907, 353626075), lg(34859627, 1988247415)) + test(lg(538493100, 441057288), lg(-1407266644, 441386073), lg(1635378940, -548742904)) + test(lg(839516176, 671232089), lg(844761371, 1022505085), lg(1930384912, 688275291)) + } + + @Test def bitwise_xor_^(): Unit = { + @inline def test(expected: Long, x: Long, y: Long): Unit = { + assertEquals(expected, x ^ y) + assertEquals(expected, hideFromOptimizer(x) ^ y) + assertEquals(expected, x ^ hideFromOptimizer(y)) + assertEquals(expected, hideFromOptimizer(x) ^ hideFromOptimizer(y)) + } + + test(lg(1342248740, -313223199), lg(690404572, -1279287229), lg(2032643064, 1592473506)) + test(lg(-1691405730, 274213753), lg(1880634009, 1433776255), lg(-348716857, 1160616710)) + test(lg(882329013, -513228751), lg(-958227509, 287282926), lg(-227156354, -260614433)) + test(lg(1416185065, -1664302164), lg(-266860160, 1815641996), lg(-1536078487, -252396512)) + test(lg(-1268929640, 1388542260), lg(1278830943, 22194981), lg(-127614265, 1402065425)) + test(lg(2107251545, -1588280474), lg(-865349911, -84319450), lg(-1309551184, 1538105408)) + test(lg(-1128180942, 150893828), lg(-1973252863, -1969367363), lg(916708915, -2107399239)) + test(lg(-721878765, 35051090), lg(2098389933, -3394272), lg(-1444158786, -35986574)) + test(lg(-1863503396, 535478572), lg(533612062, -1712875225), lg(-1893500990, -2045945845)) + test(lg(1732708730, -1611595623), lg(799833325, 2072025633), lg(1223390615, -462316872)) + test(lg(-757432261, -1755342186), lg(570370215, 1665373667), lg(-215635812, -199487627)) + test(lg(755676969, 926086823), lg(-1440978805, 1756956707), lg(-2028544094, 1603010180)) + test(lg(1331057947, 1347408402), lg(-1788434031, -203193594), lg(-634323830, -1548988140)) + test(lg(596183682, -256181831), lg(-1101798994, 1399594232), lg(-1646597332, -1546197695)) + test(lg(1360009516, 182700672), lg(-1432962218, -1631098948), lg(-75062662, -1809535684)) + test(lg(594798246, -124892913), lg(699430210, 902448324), lg(180589540, -851178037)) + test(lg(-1331407219, 1819608371), lg(-1873118605, -20501824), lg(553528574, -1833816077)) + test(lg(1679931669, 470452622), lg(-693963147, 616673404), lg(-1300017312, 952842738)) + test(lg(1861159718, -1488989292), lg(1250421224, 1104113895), lg(610853582, -420437133)) + test(lg(1056597675, -102857583), lg(-611286212, -1550148499), lg(-445979241, 1514412284)) + test(lg(255992058, 1610836280), lg(1704771515, 1382796179), lg(1792974657, 845718187)) + test(lg(315376042, 566682776), lg(1042258124, 728098489), lg(752081254, 178455073)) + test(lg(-185728083, -2076881789), lg(-1887944331, 1039677246), lg(2073445080, -1177715779)) + test(lg(22829354, 1511361245), lg(1986213921, -1875380784), lg(2000642315, -903708915)) + test(lg(-1209040105, 1698106233), lg(365179043, -418125319), lg(-1574194252, -2111511936)) + test(lg(-2034371369, -364230501), lg(-376038790, 1936322298), lg(1865150125, -1725716895)) + test(lg(-324294323, -1435696355), lg(182372182, -1389399582), lg(-428511717, 121795327)) + test(lg(-1632322296, 110394084), lg(408417754, -547668779), lg(-2031925038, -640727503)) + test(lg(1545363539, -418308022), lg(1515701412, 860890032), lg(105620727, -733936646)) + test(lg(-2124553361, 1571601224), lg(144626057, 2121098703), lg(-1983696154, 599907975)) + test(lg(-508527758, 679546956), lg(1716685092, -647833300), lg(-2015169962, -236730016)) + test(lg(-703803607, -1904715404), lg(-2016515438, -1674300757), lg(1371710907, 306998239)) + test(lg(-1295788899, 1052686696), lg(-547404938, -860356684), lg(1838979051, -234273060)) + test(lg(-1416482745, -1744821078), lg(1034397763, 1158948099), lg(-1774872572, -585891415)) + test(lg(-420256974, -1759976200), lg(1755131065, -847055172), lg(-1905373301, 1520046660)) + test(lg(-1978435977, -1613559541), lg(755114159, 1707687361), lg(-1492035880, -98945846)) + test(lg(1517584033, -1108617107), lg(1110955283, -394871226), lg(407088050, 1436378667)) + test(lg(1706214170, -555203143), lg(729918767, -1047522396), lg(1311993397, 527980061)) + test(lg(-278231087, -1148948163), lg(-1533968339, 1826223468), lg(1274742780, -681737135)) + test(lg(-204001370, 1220298027), lg(230297309, -219465279), lg(-26402437, -1168671510)) + test(lg(-1169385448, -2039889677), lg(-1364422220, 1487677662), lg(350226860, -557455315)) + test(lg(791138554, 668046473), lg(-1049451753, 1883174397), lg(-296389651, 1475305844)) + test(lg(2103687665, 1121138741), lg(-895088167, 1303802204), lg(-1211781080, 258296169)) + test(lg(-387978954, 908804328), lg(1409034242, -1162000487), lg(-1155284684, -1936324751)) + test(lg(1265820840, 1142688859), lg(861082066, -475962819), lg(2015491450, -1480757658)) + test(lg(1490973918, -277478122), lg(-288714491, 1935424926), lg(-1240144421, -1674954616)) + test(lg(1839163014, 362842460), lg(-699164585, -731232280), lg(-1144193327, -1043673420)) + test(lg(634920094, -2001579101), lg(683993930, 248552821), lg(220002260, -2040344874)) + test(lg(-831642917, -817908795), lg(640417317, 298956382), lg(-398074626, -554826341)) + test(lg(857398449, 1711937081), lg(-1493347776, 1187436882), lg(-1779986703, 550293355)) + } + + @Test def shift_left_<<(): Unit = { + @inline def test(expected: Long, x: Long, y: Int): Unit = { + assertEquals(expected, x << y) + assertEquals(expected, hideFromOptimizer(x) << y) + assertEquals(expected, x << hideFromOptimizer(y)) + assertEquals(expected, hideFromOptimizer(x) << hideFromOptimizer(y)) + } + + test(lg(1065353216, -691528727), lg(-1875389825, 1268606893), -73329513) + test(lg(671088640, -1046568266), lg(869553861, -291578632), -339545061) + test(lg(0, 0), lg(543726956, -1753066291), -809014658) + test(lg(-754974720, -1479892363), lg(-895322669, 847749031), 1030973528) + test(lg(0, 1696595968), lg(1598039634, 819660072), 82069876) + test(lg(0, -763223040), lg(-151740279, -595601314), 503039850) + test(lg(0, -1360527360), lg(-1702267427, 1115684531), 1171866675) + test(lg(508125184, -784066052), lg(-807341493, 286689824), -1938771891) + test(lg(-551288832, 439734876), lg(-382832750, -2134078182), 1537970769) + test(lg(-1409069728, 1129787), lg(-580904341, 939559401), 1856717061) + test(lg(1711276032, 1295846454), lg(-198125160, 663832884), 1561097110) + test(lg(-1004724328, -940313723), lg(-1199332365, -1728151952), 858801923) + test(lg(-1029298112, -1523092059), lg(773140802, -181814355), 1110910853) + test(lg(536870912, 200145086), lg(1601160689, 869229832), -338843811) + test(lg(0, -1735502848), lg(-1919381932, -201750119), -813015128) + test(lg(-1727917056, 2104066035), lg(-52019067, -102802849), -2122946486) + test(lg(0, 771751936), lg(-456947922, 1170727731), 2126487160) + test(lg(0, -710836224), lg(1756719200, -1702547414), -32425558) + test(lg(0, -1073741824), lg(97072750, 409070577), 1222452733) + test(lg(0, -1182793728), lg(1177105779, 212324545), -834196361) + test(lg(0, 1543503872), lg(1395605166, -1743726419), -1762017159) + test(lg(0, -67108864), lg(703808254, 1939941481), 1042647417) + test(lg(0, 1207959552), lg(-702184622, -618243162), -753853766) + test(lg(-58458112, -1619174179), lg(-1368457662, 1747275710), 1382741393) + test(lg(0, -299542812), lg(-74885703, 1342895995), 1929734882) + test(lg(0, -1585446912), lg(-61401466, -496528012), -129147274) + test(lg(1888485376, 630678170), lg(-660169692, 1479330149), 289081298) + test(lg(0, -536870912), lg(-421237721, 1011668330), 370873533) + test(lg(0, 102137856), lg(-821818323, -2029348763), -916638609) + test(lg(0, -1073741824), lg(-1246065172, -1572087360), 1493241980) + test(lg(1156516188, -1812425640), lg(578258094, -906212820), 2074806145) + test(lg(0, 1370357760), lg(61151968, -1770168701), -2062208020) + test(lg(-402653184, 1642287002), lg(1013576541, 460756940), -902835237) + test(lg(-1744830464, 1690731362), lg(-1731171245, 771836652), 868975579) + test(lg(-417260032, 563566725), lg(1123258511, 1049676716), 575477257) + test(lg(411626816, -1915897795), lg(-779579692, 1222433667), 1238257604) + test(lg(0, -2147483648), lg(-1102469156, -543766743), 553354173) + test(lg(0, -1909156352), lg(843520587, -517185932), 1899246569) + test(lg(0, -487976960), lg(-510775647, -896837143), 1487779500) + test(lg(-1148788736, -847308273), lg(-1594115986, -186853391), -119255604) + test(lg(0, 1940424228), lg(-588635767, 1047291343), 2089738146) + test(lg(1726279680, 2137615428), lg(-1002017201, -986188138), 800913356) + test(lg(0, 1650633728), lg(1813551275, -400674286), -1609938966) + test(lg(-1207959552, 897838789), lg(-1333929801, 254558182), -1518372133) + test(lg(0, -1104224256), lg(834127324, 878312672), -923142549) + test(lg(-504160320, 305586753), lg(126340223, -2008491127), -252023418) + test(lg(0, 0), lg(510931784, -1313923431), 1174528765) + test(lg(-1449390900, -1602240664), lg(711394099, -400560166), -967606846) + test(lg(0, 1162928128), lg(1319282800, -1994311032), 1237159401) + test(lg(-1749421258, 1809275319), lg(-874710629, -1242845989), 484063041) + } + + @Test def shift_logical_right_>>>(): Unit = { + @inline def test(expected: Long, x: Long, y: Int): Unit = { + assertEquals(expected, x >>> y) + assertEquals(expected, hideFromOptimizer(x) >>> y) + assertEquals(expected, x >>> hideFromOptimizer(y)) + assertEquals(expected, hideFromOptimizer(x) >>> hideFromOptimizer(y)) + } + + test(lg(1982185809, 4856), lg(88517143, 1273092247), 2099569298) + test(lg(40, 0), lg(-1987462914, 1361836721), -2053535175) + test(lg(258, 0), lg(1513792977, 1085974656), -303705162) + test(lg(-1589724844, 2), lg(-2071249600, 1411897130), 1015183069) + test(lg(827423626, 419765), lg(-1560865755, 214919778), 1191603401) + test(lg(376475826, 25773988), lg(944265510, -995896821), 485744647) + test(lg(291969293, 528), lg(1131824263, -2080089658), -386336938) + test(lg(185, 0), lg(-827478170, -1185129975), 2048537528) + test(lg(45022, 0), lg(-916869993, -1344352401), -791372688) + test(lg(587, 0), lg(588931659, -1830830904), -1259543946) + test(lg(-684574597, 28915), lg(473794659, 947514265), -1409717873) + test(lg(3, 0), lg(471518489, -940479957), -847604034) + test(lg(11, 0), lg(-818287716, 1547586919), -216455813) + test(lg(266, 0), lg(-2088976011, -2057680935), 787633143) + test(lg(-800511856, 59336150), lg(306848777, -497453644), 1584315654) + test(lg(25694, 0), lg(-1689341833, -927188015), 1300572337) + test(lg(237982231, 3229829), lg(396954515, 413418119), 1180537031) + test(lg(1319611409, 10188), lg(1478732342, 1335401807), -1668840943) + test(lg(-530293557, 9), lg(-1326271298, -1643756084), -2118687716) + test(lg(26, 0), lg(1205635051, 875594107), 350453433) + test(lg(1698203097, 57089), lg(-2049358216, -553556680), -1203541232) + test(lg(-308392901, 40188), lg(1278981121, -1661145698), 254766480) + test(lg(-1667461656, 7259908), lg(1313272948, 929268302), 1175504903) + test(lg(99018, 0), lg(1982277801, -1050318135), 629735727) + test(lg(16237, 0), lg(-610510955, 1064153335), 577897264) + test(lg(689994, 0), lg(1859860682, 1413109554), 243415787) + test(lg(4088, 0), lg(1757351444, -7991214), -1844808396) + test(lg(48441534, 0), lg(-1277568919, -1194709070), -2102413146) + test(lg(42961906, 0), lg(-1768551066, 1342559), 365466523) + test(lg(1946, 0), lg(1051996382, -213518283), -717261067) + test(lg(-605712863, 10), lg(451444747, -1380034334), -675522340) + test(lg(8, 0), lg(605006440, -1956088854), 192236860) + test(lg(-152492078, 258), lg(-384174131, -2122615661), -1278414057) + test(lg(-1650335224, 9146646), lg(-1579022332, -1953425763), 2134440904) + test(lg(175996054, 0), lg(-433112808, -1479030417), -1873327132) + test(lg(771890457, 0), lg(-1786180708, 385945228), 1526047775) + test(lg(868056695, -1200391723), lg(868056695, -1200391723), 93595840) + test(lg(88233, 0), lg(1335240662, -1403745666), 1625850351) + test(lg(21, 0), lg(-681452715, -1446696044), -742234373) + test(lg(200097858, 0), lg(301750839, 1600782865), 1678034787) + test(lg(1, 0), lg(-2077889650, 445749598), 363036476) + test(lg(-1160719403, 3135), lg(-1633078438, 1644025478), -1297864237) + test(lg(27660, 0), lg(1159483779, 906375175), -1204888593) + test(lg(1096217739, 131290637), lg(179807326, 1050325098), -1598422013) + test(lg(61, 0), lg(952383136, -193355640), 415626042) + test(lg(12362394, 0), lg(972435428, -1130194211), -1259042456) + test(lg(-924965860, 8483), lg(605823642, 555993310), 1780437072) + test(lg(88, 0), lg(665774635, 184915839), 1729784373) + test(lg(27109, 0), lg(-263808048, -741669613), -204793551) + test(lg(-5828381, 10), lg(-954198224, 369053217), 768150041) + } + + @Test def shift_arithmetic_right_>>(): Unit = { + @inline def test(expected: Long, x: Long, y: Int): Unit = { + assertEquals(expected, x >> y) + assertEquals(expected, hideFromOptimizer(x) >> y) + assertEquals(expected, x >> hideFromOptimizer(y)) + assertEquals(expected, hideFromOptimizer(x) >> hideFromOptimizer(y)) + } + + test(lg(144041519, 2813487), lg(-1780076655, 720252680), -1316031160) + test(lg(1519, 0), lg(234061537, 796729805), 1452874739) + test(lg(-935479627, 124), lg(1523206972, 1046748891), 1356453463) + test(lg(-15335, -1), lg(1866043067, -2009962307), 393061105) + test(lg(5, 0), lg(89507691, 183545611), -1980770119) + test(lg(-1283367734, 14309038), lg(-1062312593, 1831556953), 1545082311) + test(lg(523169438, 0), lg(-1568293714, 523169438), -2119005984) + test(lg(-1704853904, -731301), lg(-2013675422, -748851607), 511130378) + test(lg(345569760, -46), lg(-521585277, -770402055), -1176556648) + test(lg(1777038301, 61), lg(-145701849, 257587932), -1512809002) + test(lg(-51, -1), lg(-973180026, -1694110170), 2083093369) + test(lg(-5, -1), lg(1761120319, -539393529), -207994821) + test(lg(-587262921, -3246345), lg(-30904807, -1662128199), -638486135) + test(lg(-10706, -1), lg(1812122560, -701571284), 611632432) + test(lg(7484398, 100362842), lg(119750375, 1605805472), 244039684) + test(lg(1, 0), lg(269986751, 1459449758), -439796226) + test(lg(7, 0), lg(-1969890020, 2011804532), -652735044) + test(lg(-2130588861, 98), lg(-1582649974, 826310885), 613066583) + test(lg(-669931160, -697), lg(756433442, -1459944907), -775565931) + test(lg(933146972, -1), lg(1678061064, -1680910162), -531660641) + test(lg(1601141595, 1298147), lg(1870355258, 332325727), -434372344) + test(lg(-1047936567, -129548), lg(1886551280, -2122502046), -763866098) + test(lg(-72307, -1), lg(-1169141408, -592336405), -1841005139) + test(lg(72262, 0), lg(686282122, 295988927), 69079212) + test(lg(-1582088844, -23862710), lg(1825529126, -1527213400), 1371712838) + test(lg(70395261, 0), lg(633149491, 1126324183), 1948323684) + test(lg(-329, -1), lg(-363762029, -1377253181), -1243200330) + test(lg(1924403917, -21), lg(-1694234908, -689608667), 728732313) + test(lg(-62655, -1), lg(1319661865, -2053067582), -777879057) + test(lg(-1472236443, 19900875), lg(-1472236443, 19900875), 373478400) + test(lg(-1, -1), lg(-1719111010, -1766452468), 942391743) + test(lg(5131, 0), lg(-624682758, 1345231635), -813574478) + test(lg(9, 0), lg(1316519660, 314590421), -641829383) + test(lg(-14492, -1), lg(-1380652891, -474856510), -920501329) + test(lg(40, 0), lg(-2084688189, 1352268039), -177471111) + test(lg(-868447412, 13901269), lg(507881044, 1779362534), -508943033) + test(lg(-37529, -1), lg(1742323077, -1229747072), 401183471) + test(lg(376386, 0), lg(346182810, 770838817), 797274667) + test(lg(-1822, -1), lg(828281422, -477411393), 1298272370) + test(lg(1021967080, -2560), lg(-341778503, -671026265), 532386578) + test(lg(-1683940185, 34921), lg(-1907127360, 1144311248), -2131012273) + test(lg(-121723, -1), lg(756366897, -1994294687), -1642432978) + test(lg(-644688038, 9473), lg(-1363894143, 1241756453), 1681307793) + test(lg(-278047, -1), lg(1708006412, -1138876437), 2010442220) + test(lg(872834, 0), lg(-664430929, 446891142), -1707024855) + test(lg(-1, -1), lg(-1904131429, -938887), -829231944) + test(lg(-2101780246, 11998), lg(-1043053889, 1572668786), 309495249) + test(lg(-11427, -1), lg(563683687, -1497656119), -176819791) + test(lg(201, 0), lg(-627312011, 421917318), 2056663541) + test(lg(-104838948, -3), lg(-904956287, -543423347), -617227620) + } + + @Test def negate_-(): Unit = { + @inline def test(expected: Long, x: Long): Unit = { + assertEquals(expected, -x) + assertEquals(expected, -hideFromOptimizer(x)) + } + + test(lg(0), lg(0)) + test(lg(1), lg(-1)) + test(lg(-1), lg(1)) + test(lg(1, -2147483648), MaxVal) + test(MinVal, MinVal) + test(lg(0, -1), lg(0, 1)) + + test(lg(792771844, -1518464955), lg(-792771844, 1518464954)) + test(lg(1313283210, -1172119606), lg(-1313283210, 1172119605)) + test(lg(-1034897743, -341494686), lg(1034897743, 341494685)) + test(lg(-924881290, 1614058538), lg(924881290, -1614058539)) + test(lg(-1636891236, -1405401040), lg(1636891236, 1405401039)) + test(lg(2044349674, -477271433), lg(-2044349674, 477271432)) + test(lg(1426086684, -1493816436), lg(-1426086684, 1493816435)) + test(lg(-2125201680, 1667846199), lg(2125201680, -1667846200)) + test(lg(161054645, -1272528725), lg(-161054645, 1272528724)) + test(lg(-1013390126, -1323844683), lg(1013390126, 1323844682)) + test(lg(-1028806094, -691441881), lg(1028806094, 691441880)) + test(lg(1060422114, -11477649), lg(-1060422114, 11477648)) + test(lg(1366334123, -2046238761), lg(-1366334123, 2046238760)) + test(lg(1307711795, 940346049), lg(-1307711795, -940346050)) + test(lg(421687960, -250174762), lg(-421687960, 250174761)) + test(lg(379452754, -843386803), lg(-379452754, 843386802)) + test(lg(-1251296999, 1144268297), lg(1251296999, -1144268298)) + test(lg(-690359429, -1676679602), lg(690359429, 1676679601)) + test(lg(1952563749, -882544420), lg(-1952563749, 882544419)) + test(lg(-1420900897, -1865273591), lg(1420900897, 1865273590)) + test(lg(115947827, -832851217), lg(-115947827, 832851216)) + test(lg(-1834973959, -1423776005), lg(1834973959, 1423776004)) + test(lg(1376766876, 1519617584), lg(-1376766876, -1519617585)) + test(lg(-1845217535, 724725865), lg(1845217535, -724725866)) + test(lg(-1133294381, 699400553), lg(1133294381, -699400554)) + test(lg(113507585, 615978889), lg(-113507585, -615978890)) + test(lg(-1839784424, 1163726652), lg(1839784424, -1163726653)) + test(lg(1065777168, 1301742163), lg(-1065777168, -1301742164)) + test(lg(334075220, -1058529734), lg(-334075220, 1058529733)) + test(lg(1443112398, 1148167880), lg(-1443112398, -1148167881)) + test(lg(1647739462, 12310882), lg(-1647739462, -12310883)) + test(lg(1461318149, 518941731), lg(-1461318149, -518941732)) + test(lg(56833825, -162898592), lg(-56833825, 162898591)) + test(lg(-680096727, -1760413869), lg(680096727, 1760413868)) + test(lg(461541717, -1103626950), lg(-461541717, 1103626949)) + test(lg(1287248387, 1483137214), lg(-1287248387, -1483137215)) + test(lg(-1681467124, -1197977023), lg(1681467124, 1197977022)) + test(lg(-310946355, 885055747), lg(310946355, -885055748)) + test(lg(-717629012, -1299204708), lg(717629012, 1299204707)) + test(lg(800584851, 350245993), lg(-800584851, -350245994)) + test(lg(1911014238, -441020786), lg(-1911014238, 441020785)) + test(lg(-1647080824, -1197295589), lg(1647080824, 1197295588)) + test(lg(-925751968, -479541400), lg(925751968, 479541399)) + test(lg(-656919119, 1574890072), lg(656919119, -1574890073)) + test(lg(-1833364814, 432106462), lg(1833364814, -432106463)) + test(lg(-315730911, -1990201785), lg(315730911, 1990201784)) + test(lg(1218524771, -572482048), lg(-1218524771, 572482047)) + test(lg(276668811, 2002398729), lg(-276668811, -2002398730)) + test(lg(1489416833, 834462753), lg(-1489416833, -834462754)) + test(lg(2066446588, 688546120), lg(-2066446588, -688546121)) + } + + @Test def plus_+(): Unit = { + @inline def test(expected: Long, x: Long, y: Long): Unit = { + assertEquals(expected, x + y) + assertEquals(expected, hideFromOptimizer(x) + y) + assertEquals(expected, x + hideFromOptimizer(y)) + assertEquals(expected, hideFromOptimizer(x) + hideFromOptimizer(y)) + } + + test(lg(802149732, -566689627), lg(-202981355, -566689628), lg(1005131087, 0)) + test(lg(902769101, 1674149440), lg(1153016325, 1674149440), lg(-250247224, -1)) + test(lg(1128646485, -1965159800), lg(1701699755, -1965159800), lg(-573053270, -1)) + test(lg(66936416, -973893589), lg(-1183294843, -973893590), lg(1250231259, 0)) + test(lg(-155818001, 449544496), lg(-2145882999, 449544496), lg(1990064998, 0)) + test(lg(-1244599644, -917980205), lg(-528276750, -917980205), lg(-716322894, -1)) + test(lg(580594010, 1794016499), lg(-1061043923, 1794016498), lg(1641637933, 0)) + test(lg(-1874551871, 1883156001), lg(-315483661, 1883156001), lg(-1559068210, -1)) + test(lg(-611587809, 95409025), lg(-1899047326, 95409025), lg(1287459517, 0)) + test(lg(-1393747885, 1167571449), lg(-705065818, 1167571449), lg(-688682067, -1)) + test(lg(1135734754, -607437553), lg(-192210545, -607437554), lg(1327945299, 0)) + test(lg(545472170, -2007097641), lg(11453726, -2007097641), lg(534018444, 0)) + test(lg(-1984029353, -1191350400), lg(1809973610, -1191350400), lg(500964333, 0)) + test(lg(1031291620, 108684756), lg(972641234, 108684756), lg(58650386, 0)) + test(lg(-1375760766, 127758048), lg(-1511325903, 127758048), lg(135565137, 0)) + test(lg(640679472, 429508922), lg(-942832491, 429508921), lg(1583511963, 0)) + test(lg(-820503583, -594798242), lg(1500842230, -594798242), lg(1973621483, 0)) + test(lg(1875301895, 910473912), lg(-1088230684, 910473912), lg(-1331434717, -1)) + test(lg(-1755864971, 378724963), lg(798219431, 378724963), lg(1740882894, 0)) + test(lg(468052904, -683558197), lg(-1763683665, -683558197), lg(-2063230727, -1)) + test(lg(-1488850347, -1636478025), lg(627629519, -1636478024), lg(-2116479866, -1)) + test(lg(915882407, -338305025), lg(-526665240, -338305026), lg(1442547647, 0)) + test(lg(-950882103, -466473801), lg(-1265295286, -466473801), lg(314413183, 0)) + test(lg(-673278223, -1417005301), lg(-1412852606, -1417005301), lg(739574383, 0)) + test(lg(-1565299836, -2035157269), lg(708993121, -2035157269), lg(2020674339, 0)) + test(lg(638729196, 1182702858), lg(847269791, 1182702858), lg(-208540595, -1)) + test(lg(-1453651445, -1902383955), lg(97084677, -1902383954), lg(-1550736122, -1)) + test(lg(1116569659, -606967004), lg(-267181534, -606967005), lg(1383751193, 0)) + test(lg(529048030, 1063184820), lg(-904322265, 1063184819), lg(1433370295, 0)) + test(lg(-499260224, 101142421), lg(1841727454, 101142421), lg(1953979618, 0)) + test(lg(1452864874, 1045175929), lg(-1716387490, 1045175929), lg(-1125714932, -1)) + test(lg(982736721, 1506316757), lg(-1020814821, 1506316756), lg(2003551542, 0)) + test(lg(-1478064805, 1107506955), lg(467820886, 1107506956), lg(-1945885691, -1)) + test(lg(1436947166, -57552832), lg(-103701719, -57552833), lg(1540648885, 0)) + test(lg(3887456, -414981457), lg(1280780483, -414981457), lg(-1276893027, -1)) + test(lg(939083871, 606376864), lg(-1505747919, 606376864), lg(-1850135506, -1)) + test(lg(-1161495325, -606274238), lg(-1797917239, -606274238), lg(636421914, 0)) + test(lg(2146013782, 52949338), lg(-551974000, 52949338), lg(-1596979514, -1)) + test(lg(-159062053, -623553409), lg(484182807, -623553408), lg(-643244860, -1)) + test(lg(1680160313, 371486519), lg(1170065239, 371486519), lg(510095074, 0)) + test(lg(-2071737549, -251530660), lg(553737773, -251530660), lg(1669491974, 0)) + test(lg(793877651, -324566030), lg(1363264202, -324566030), lg(-569386551, -1)) + test(lg(1897556965, 1255689015), lg(1461362302, 1255689015), lg(436194663, 0)) + test(lg(-540868058, 718534179), lg(-1463314706, 718534179), lg(922446648, 0)) + test(lg(2547531, -716998232), lg(-1684072850, -716998233), lg(1686620381, 0)) + test(lg(-1709813271, -2086072551), lg(-183257712, -2086072551), lg(-1526555559, -1)) + test(lg(-2134341942, -1223154956), lg(-485818523, -1223154956), lg(-1648523419, -1)) + test(lg(1634619686, -1934382665), lg(392330048, -1934382665), lg(1242289638, 0)) + test(lg(-1409927090, -75135322), lg(1907808353, -75135322), lg(977231853, 0)) + test(lg(-1393001322, 1362535802), lg(88305723, 1362535803), lg(-1481307045, -1)) + } + + @Test def minus_-(): Unit = { + @inline def test(expected: Long, x: Long, y: Long): Unit = { + assertEquals(expected, x - y) + assertEquals(expected, hideFromOptimizer(x) - y) + assertEquals(expected, x - hideFromOptimizer(y)) + assertEquals(expected, hideFromOptimizer(x) - hideFromOptimizer(y)) + } + + // Whitebox corner case + test(lg(-1), lg(0), lg(1)) + + test(lg(1318078695, 462416044), lg(406229717, 462416044), lg(-911848978, -1)) + test(lg(459412414, 466142261), lg(873646396, 466142261), lg(414233982, 0)) + test(lg(1749422706, -573388520), lg(-2077914189, -573388520), lg(467630401, 0)) + test(lg(855866353, -1980988131), lg(-789253983, -1980988132), lg(-1645120336, -1)) + test(lg(1858485462, 1825277273), lg(-482388232, 1825277273), lg(1954093602, 0)) + test(lg(1211608504, -1077757379), lg(-1616159373, -1077757379), lg(1467199419, 0)) + test(lg(-1391411781, -1825579414), lg(-105778670, -1825579414), lg(1285633111, 0)) + test(lg(1573921037, -2018677385), lg(1306759468, -2018677385), lg(-267161569, -1)) + test(lg(2075838974, -289291128), lg(618139116, -289291128), lg(-1457699858, -1)) + test(lg(600013127, -1980710784), lg(1736445522, -1980710784), lg(1136432395, 0)) + test(lg(-558434179, 21136449), lg(-1970971750, 21136449), lg(-1412537571, -1)) + test(lg(-343650116, 229693364), lg(-1491842755, 229693364), lg(-1148192639, -1)) + test(lg(1686071974, -2064363005), lg(2125082313, -2064363005), lg(439010339, 0)) + test(lg(-1587252411, -1887690341), lg(922634658, -1887690341), lg(-1785080227, -1)) + test(lg(-992416688, 1754335328), lg(478015362, 1754335329), lg(1470432050, 0)) + test(lg(1718268050, -845578935), lg(-1788952896, -845578935), lg(787746350, 0)) + test(lg(1316319511, -1479013672), lg(-1177368338, -1479013672), lg(1801279447, 0)) + test(lg(1568876561, -2147323821), lg(1761081661, -2147323821), lg(192205100, 0)) + test(lg(-1122491731, 1604940224), lg(261772552, 1604940225), lg(1384264283, 0)) + test(lg(1556996455, 1018615990), lg(-1441241840, 1018615990), lg(1296729001, 0)) + test(lg(-52258673, -155632234), lg(907527568, -155632233), lg(959786241, 0)) + test(lg(1911811399, 1534910973), lg(1509034771, 1534910973), lg(-402776628, -1)) + test(lg(1234505303, -718856464), lg(-344668006, -718856465), lg(-1579173309, -1)) + test(lg(1263823751, 1792314521), lg(-2096618226, 1792314521), lg(934525319, 0)) + test(lg(-1901870284, -977488448), lg(1861956484, -977488448), lg(-531140528, -1)) + test(lg(170060904, -1532994269), lg(-691455907, -1532994270), lg(-861516811, -1)) + test(lg(-417244722, -946809431), lg(-693769914, -946809431), lg(-276525192, -1)) + test(lg(1392505816, -834216711), lg(-1698674051, -834216711), lg(1203787429, 0)) + test(lg(339105023, -930632047), lg(1453492556, -930632047), lg(1114387533, 0)) + test(lg(1588670098, -422836102), lg(-516102112, -422836103), lg(-2104772210, -1)) + test(lg(-1793332542, 1839759286), lg(1194707556, 1839759286), lg(-1306927198, -1)) + test(lg(-1933743595, -1652840750), lg(1188016800, -1652840750), lg(-1173206901, -1)) + test(lg(1172675504, 1790839027), lg(-1268512415, 1790839027), lg(1853779377, 0)) + test(lg(-2038245078, 275932678), lg(-777434907, 275932678), lg(1260810171, 0)) + test(lg(-640120196, 658575618), lg(607917442, 658575619), lg(1248037638, 0)) + test(lg(-939204613, -2089057829), lg(-1490388970, -2089057829), lg(-551184357, -1)) + test(lg(-2089897031, 992436418), lg(-1342917439, 992436418), lg(746979592, 0)) + test(lg(-767046771, -1192540532), lg(-1045496394, -1192540532), lg(-278449623, -1)) + test(lg(735191894, -683257085), lg(1555450000, -683257085), lg(820258106, 0)) + test(lg(2026420598, 481753248), lg(1022728181, 481753248), lg(-1003692417, -1)) + test(lg(-2132649422, 1411964223), lg(2028304312, 1411964223), lg(-134013562, -1)) + test(lg(1346424260, -217374406), lg(704117341, -217374406), lg(-642306919, -1)) + test(lg(-692878557, 278237510), lg(313351245, 278237511), lg(1006229802, 0)) + test(lg(-1545280043, 2054685372), lg(2076724262, 2054685372), lg(-672962991, -1)) + test(lg(1156651977, 261806288), lg(1990098163, 261806288), lg(833446186, 0)) + test(lg(-244547539, 1626774417), lg(1425435353, 1626774418), lg(1669982892, 0)) + test(lg(-125857115, -1714068645), lg(2084724465, -1714068645), lg(-2084385716, -1)) + test(lg(-2124426763, -543675020), lg(-1799809279, -543675020), lg(324617484, 0)) + test(lg(-2145169231, -602489858), lg(1972622018, -602489858), lg(-177176047, -1)) + test(lg(408960051, 967789979), lg(883147297, 967789979), lg(474187246, 0)) + } + + @Test def times_*(): Unit = { + @inline def test(expected: Long, x: Long, y: Long): Unit = { + assertEquals(expected, x * y) + assertEquals(expected, hideFromOptimizer(x) * y) + assertEquals(expected, x * hideFromOptimizer(y)) + assertEquals(expected, hideFromOptimizer(x) * hideFromOptimizer(y)) + } + + test(lg(-1056314208, 1039912134), lg(-1436299491, 1172705251), lg(1721031968, 0)) + test(lg(15417694, -1235494072), lg(-1754547158, 1592794750), lg(-850659149, -1)) + test(lg(-1312839754, -486483117), lg(-582562130, 1508550574), lg(-2054981347, -1)) + test(lg(-377676239, 1969822597), lg(-517256163, 1107889737), lg(324089381, 0)) + test(lg(-1426078720, -1379092277), lg(1862517504, -2146745095), lg(2043533548, 0)) + test(lg(-1611894400, 514550890), lg(-1341087062, 93674761), lg(1272468928, 0)) + test(lg(88803236, -172420721), lg(-1911825604, 1026411170), lg(244738503, 0)) + test(lg(1486387579, 668666773), lg(2102189793, 425022510), lg(750432219, 0)) + test(lg(913918418, 2124658288), lg(-1628887094, 2043879870), lg(-1367964491, -1)) + test(lg(-1067082241, 864193319), lg(454909009, -1096315634), lg(-461844145, -1)) + test(lg(949541055, 403324299), lg(-1346593793, -331776468), lg(1495188289, 0)) + test(lg(-232871624, -1943313306), lg(39946028, -363039140), lg(-1134101206, -1)) + test(lg(-528828160, -1884969955), lg(769959254, -432157368), lg(-488368768, -1)) + test(lg(913322937, -2105457977), lg(1975078475, 1181124823), lg(-1852476533, -1)) + test(lg(1594278208, 943829214), lg(-2118478876, -1521449422), lg(-235907376, -1)) + test(lg(-50678328, 2146883835), lg(-192590815, -1552754278), lg(990887112, 0)) + test(lg(1779498513, -1732099612), lg(-74714605, 386143916), lg(1634792395, 0)) + test(lg(982209626, 857499597), lg(1839773441, -590412588), lg(799604314, 0)) + test(lg(1806268816, -990479821), lg(1395571130, -1228992407), lg(1440046952, 0)) + test(lg(1683728223, -957382628), lg(-1094818235, 1759139279), lg(-156634285, -1)) + test(lg(-1590791694, 595489480), lg(853844787, 525523561), lg(600761926, 0)) + test(lg(1353714367, 146465211), lg(-903115469, 793487771), lg(1986597957, 0)) + test(lg(1421874569, -1462441210), lg(-830036223, 830164681), lg(-1711884663, -1)) + test(lg(-962035602, -2086325336), lg(1514898873, 1802395563), lg(1763957470, 0)) + test(lg(213232144, -1084932179), lg(-1931885288, 136587512), lg(-241565738, -1)) + test(lg(-915935202, 1495104097), lg(571274323, 1264898114), lg(1823828906, 0)) + test(lg(1116543789, -1473151538), lg(-15708939, -2105030313), lg(48280153, 0)) + test(lg(-1230228445, -570579388), lg(1792017337, -1626094957), lg(301685947, 0)) + test(lg(1335719116, 1447187791), lg(-1942632452, -691115342), lg(-889918259, -1)) + test(lg(1398640985, -1330552693), lg(-683458011, -1409200935), lg(-996910555, -1)) + test(lg(-402621042, 1775759707), lg(562125786, -1303526635), lg(-1761056509, -1)) + test(lg(129149596, -78429064), lg(2115902292, -1194658096), lg(-1549721205, -1)) + test(lg(1706925885, 1413499189), lg(1852083423, 330104035), lg(1414822755, 0)) + test(lg(-722178384, 1850552711), lg(-1623207532, 1442771787), lg(-948878276, -1)) + test(lg(545021767, -1389368834), lg(-898643831, 773279296), lg(1294488911, 0)) + test(lg(1541594150, 820379725), lg(421823854, 802578424), lg(1394107269, 0)) + test(lg(-279324848, 1175391379), lg(1589092022, 237831212), lg(-763790472, -1)) + test(lg(2089067814, 975727054), lg(-1247207721, -370556328), lg(1449901386, 0)) + test(lg(-1977714127, -377823390), lg(109386811, 368962517), lg(1406834819, 0)) + test(lg(1759713497, -312922364), lg(2135299059, -798752868), lg(-1861488893, -1)) + test(lg(1030024362, -795941843), lg(-695671854, 1917612060), lg(2083344781, 0)) + test(lg(-704748314, 388197332), lg(250669253, -442179349), lg(-552836178, -1)) + test(lg(758103782, -158300478), lg(1237744278, 206295616), lg(-1547545223, -1)) + test(lg(-629736326, 810097466), lg(492775518, 1691641907), lg(1172634963, 0)) + test(lg(610754048, 1997636055), lg(-1549380722, 49835026), lg(-1645815552, -1)) + test(lg(1696857284, 1549588995), lg(1850430325, -1942955614), lg(-295254732, -1)) + test(lg(-66011146, -376837532), lg(-1276671498, -1984743584), lg(-1583554303, -1)) + test(lg(2033040344, -167450557), lg(-2127158934, -2058421178), lg(1620104636, 0)) + test(lg(-1886196376, -31345953), lg(69958717, -772556465), lg(21655944, 0)) + test(lg(-38147573, -1269583268), lg(406538265, -107036516), lg(2077087683, 0)) + + test(8433193943336928478L, -304510477859059605L, -504694402761190L) + test(-12731773183499098L, -253162060478L, 50291L) + test(0L, 0L, -13850059L) + test(7569251612557229982L, -8660470952582643L, -874L) + test(-11988L, -1332L, 9L) + test(-8243580206627053600L, -29568141078178L, 1526544L) + test(2184313243348463060L, 328926390054L, -3638668370L) + test(46841680L, 205L, 228496L) + test(740594256954004614L, -19460467868573L, -81306407837343422L) + test(1686350941924289808L, 515501176792L, -14676235751610L) + test(6344118389112076765L, 414866483823975467L, 470120246452409879L) + test(-11349L, -117L, 97L) + test(-15402750L, 30L, -513425L) + test(-1358824991029065112L, 1375729456898L, 623181770548L) + test(15724552950015L, 80638733077L, 195L) + test(53496875011846994L, -12740384618206L, -4199L) + test(4976657084923555180L, 521743856055513645L, -2105465236503908L) + test(8L, -8L, -1L) + test(619912072L, -34L, -18232708L) + test(-4326473264912647477L, -4512416881041611L, 16599101951L) + test(1570555712220296245L, -2433585405235L, -645367L) + test(17255933394228520L, -774590L, -22277506028L) + test(5693979142683511208L, 36307900L, -19149614702538L) + test(5058564788733665886L, 22169162314093L, 18534166L) + test(-1912529786602316571L, -3848931303L, 82157326906201261L) + test(-5528746562555987920L, 47326191440L, -39094697833L) + test(-2254385599727553792L, -14641542L, -3714491797523081344L) + test(7866519297L, 771303L, 10199L) + test(0L, 0L, -14806105L) + test(47573376L, 3964448L, 12L) + test(-2609453654630496L, 77505454872L, -33668L) + test(-3686637842539497440L, 14929228532112L, 6555913938L) + test(4853210716974444062L, 431219964946864070L, 1181669L) + test(-14100245424035L, 2820049084807L, -5L) + test(8725676311339308590L, -16830140929953126L, 93975690486771L) + test(2367313232506909772L, 206188838L, 1249841574949634L) + test(-8124607316971866814L, 16674057030L, 1104000290638571L) + test(6446979988520042261L, -64710169253973867L, -23079009995647L) + test(654519384576L, 31096512L, 21048L) + test(153203910181224144L, 22L, 6963814099146552L) + test(1436126772314869678L, 1260318190682L, 1123567398313107L) + test(-75661570L, -5L, 15132314L) + test(6685324216344409292L, 9099845427374L, -126975734L) + test(-7100290L, 5L, -1420058L) + test(-1940696769116022576L, -28274L, 68638918056024L) + test(-7932625013377175292L, 193355246244L, 36593871833L) + test(-7L, 1L, -7L) + test(-48355929429178192L, 66789957775108L, -724L) + test(-10521672279471L, 10521672279471L, -1L) + test(4095350372293300139L, -8747667231979L, -105906241L) + + // Random power of 2 tests + test(105129441230848L, 100259248L, 1048576L) + test(105129441230848L, 1048576L, 100259248L) + test(1297036692682702848L, 72L, 18014398509481984L) + test(1297036692682702848L, 18014398509481984L, 72L) + test(-11947131749269504L, -22253267L, 536870912L) + test(-11947131749269504L, 536870912L, -22253267L) + test(8659858730206101504L, 23022568162358L, 8388608L) + test(8659858730206101504L, 8388608L, 23022568162358L) + test(207805415948288L, 1548271L, 134217728L) + test(207805415948288L, 134217728L, 1548271L) + test(0L, -55880L, -9223372036854775808L) + test(0L, -9223372036854775808L, -55880L) + test(-2199023255552L, -1L, 2199023255552L) + test(-2199023255552L, 2199023255552L, -1L) + test(851968L, 13L, 65536L) + test(851968L, 65536L, 13L) + test(-17592186044416L, -1L, 17592186044416L) + test(-17592186044416L, 17592186044416L, -1L) + test(-7000097952840548352L, 222527207082L, 4398046511104L) + test(-7000097952840548352L, 4398046511104L, 222527207082L) + test(2449958197289549824L, 34L, 72057594037927936L) + test(2449958197289549824L, 72057594037927936L, 34L) + test(-16623318531928064L, -4058427375959L, 4096L) + test(-16623318531928064L, 4096L, -4058427375959L) + test(-8006274237557899264L, -2214324316485807900L, 281474976710656L) + test(-8006274237557899264L, 281474976710656L, -2214324316485807900L) + test(-61568356188160L, -14335L, 4294967296L) + test(-61568356188160L, 4294967296L, -14335L) + test(-3101185093760L, -48456017090L, 64L) + test(-3101185093760L, 64L, -48456017090L) + test(-20250091264L, -158203838L, 128L) + test(-20250091264L, 128L, -158203838L) + test(-118778880L, -115995L, 1024L) + test(-118778880L, 1024L, -115995L) + test(-4052041596928L, -483041L, 8388608L) + test(-4052041596928L, 8388608L, -483041L) + test(2511601217189183488L, 186114971352L, 35184372088832L) + test(2511601217189183488L, 35184372088832L, 186114971352L) + test(258064524401082304L, 8064516387533822L, 32L) + test(258064524401082304L, 32L, 8064516387533822L) + test(-13379618472345600L, -816627104025L, 16384L) + test(-13379618472345600L, 16384L, -816627104025L) + test(-56908316672L, -106L, 536870912L) + test(-56908316672L, 536870912L, -106L) + test(0L, 0L, 4096L) + test(0L, 4096L, 0L) + test(-513636086841344L, -61230193L, 8388608L) + test(-513636086841344L, 8388608L, -61230193L) + test(-3894698884001169408L, 41500264L, 8796093022208L) + test(-3894698884001169408L, 8796093022208L, 41500264L) + test(1055744L, 32992L, 32L) + test(1055744L, 32L, 32992L) + test(558955633836032L, 65071L, 8589934592L) + test(558955633836032L, 8589934592L, 65071L) + test(-7994738298998226944L, 76048351L, 137438953472L) + test(-7994738298998226944L, 137438953472L, 76048351L) + test(-4L, -2L, 2L) + test(-4L, 2L, -2L) + test(-4259162954240L, -8318677645L, 512L) + test(-4259162954240L, 512L, -8318677645L) + test(2922836158163451904L, -60717806L, 2251799813685248L) + test(2922836158163451904L, 2251799813685248L, -60717806L) + test(0L, 0L, 8192L) + test(0L, 8192L, 0L) + test(5531246788608L, 164844L, 33554432L) + test(5531246788608L, 33554432L, 164844L) + test(8574853690513424384L, -678234761L, 72057594037927936L) + test(8574853690513424384L, 72057594037927936L, -678234761L) + test(-2828260565988671488L, -103657850088L, 2251799813685248L) + test(-2828260565988671488L, 2251799813685248L, -103657850088L) + test(-9223372036854775808L, 138748537820112453L, -9223372036854775808L) + test(-9223372036854775808L, -9223372036854775808L, 138748537820112453L) + test(0L, 0L, 17179869184L) + test(0L, 17179869184L, 0L) + test(5526109039206858752L, -2489041709915087415L, 2147483648L) + test(5526109039206858752L, 2147483648L, -2489041709915087415L) + test(9663676416L, 9L, 1073741824L) + test(9663676416L, 1073741824L, 9L) + test(648518346341351424L, 379085341609132041L, 72057594037927936L) + test(648518346341351424L, 72057594037927936L, 379085341609132041L) + test(-4118880446592909312L, 218625848802439L, 65536L) + test(-4118880446592909312L, 65536L, 218625848802439L) + test(-7094878839486021632L, -422887732952L, 16777216L) + test(-7094878839486021632L, 16777216L, -422887732952L) + test(20894747459584L, 77839L, 268435456L) + test(20894747459584L, 268435456L, 77839L) + test(-5624995934585749504L, -3953804003778L, 2251799813685248L) + test(-5624995934585749504L, 2251799813685248L, -3953804003778L) + test(76001593786368L, 141564L, 536870912L) + test(76001593786368L, 536870912L, 141564L) + test(5942088864628736L, 11068003L, 536870912L) + test(5942088864628736L, 536870912L, 11068003L) + test(-417996242432L, -816398911L, 512L) + test(-417996242432L, 512L, -816398911L) + test(10122752L, 79084L, 128L) + test(10122752L, 128L, 79084L) + test(712964571136L, 166L, 4294967296L) + test(712964571136L, 4294967296L, 166L) + test(-3013501831155286016L, -120218862620908531L, 4294967296L) + test(-3013501831155286016L, 4294967296L, -120218862620908531L) + } + + @Test def divide_/(): Unit = { + @inline def test(expected: Long, x: Long, y: Long): Unit = { + assertEquals(expected, x / y) + assertEquals(expected, hideFromOptimizer(x) / y) + assertEquals(expected, x / hideFromOptimizer(y)) + assertEquals(expected, hideFromOptimizer(x) / hideFromOptimizer(y)) + } + + test(IntMaxValPlus1, IntMinVal, lg(-1)) + test(lg(-1), IntMinVal, IntMaxValPlus1) + test(IntMinVal, IntMaxValPlus1, lg(-1)) + test(lg(-1), IntMaxValPlus1, IntMinVal) + + test(lg(1, -2147483648), MaxVal, lg(-1)) + test(MinVal, MinVal, lg(1)) + test(MinVal, MinVal, lg(-1)) + + // int32, int32 + test(lg(1, 0), lg(-10426835, -1), lg(-6243356, -1)) + test(lg(-291, -1), lg(49659080, 0), lg(-170373, -1)) + test(lg(3, 0), lg(97420, 0), lg(27521, 0)) + test(lg(26998, 0), lg(-9881291, -1), lg(-366, -1)) + test(lg(0, 0), lg(-40, -1), lg(81, 0)) + test(lg(0, 0), lg(-6007, -1), lg(-326806, -1)) + test(lg(-1, -1), lg(202, 0), lg(-112, -1)) + test(lg(0, 0), lg(0, 0), lg(47, 0)) + test(lg(323816, 0), lg(22667160, 0), lg(70, 0)) + test(lg(0, 0), lg(254, 0), lg(-307349204, -1)) + test(lg(0, 0), lg(-17, -1), lg(-44648, -1)) + test(lg(-40, -1), lg(39646, 0), lg(-976, -1)) + test(lg(0, 0), lg(9, 0), lg(315779722, 0)) + test(lg(0, 0), lg(-2674, -1), lg(-3051991, -1)) + test(lg(0, 0), lg(-37697, -1), lg(2015928, 0)) + test(lg(0, 0), lg(-13, -1), lg(-31, -1)) + test(lg(0, 0), lg(6, 0), lg(-334, -1)) + test(lg(8, 0), lg(-15989, -1), lg(-1918, -1)) + test(lg(8746, 0), lg(-113261535, -1), lg(-12950, -1)) + test(lg(55322, 0), lg(-6362112, -1), lg(-115, -1)) + test(lg(0, 0), lg(455, 0), lg(13919, 0)) + test(lg(36190, 0), lg(293468259, 0), lg(8109, 0)) + test(lg(1, 0), lg(-48287007, -1), lg(-27531186, -1)) + test(lg(349634, 0), lg(1048904, 0), lg(3, 0)) + test(lg(0, 0), lg(-34, -1), lg(3949717, 0)) + test(lg(-1, -1), lg(1449, 0), lg(-983, -1)) + test(lg(-18537151, -1), lg(18537151, 0), lg(-1, -1)) + test(lg(0, 0), lg(14037, 0), lg(23645, 0)) + test(lg(-4, -1), lg(1785, 0), lg(-398, -1)) + test(lg(0, 0), lg(346, 0), lg(2198158, 0)) + test(lg(-802, -1), lg(-3517419, -1), lg(4381, 0)) + test(lg(-6, -1), lg(6, 0), lg(-1, -1)) + test(lg(39, 0), lg(-822, -1), lg(-21, -1)) + test(lg(0, 0), lg(3629, 0), lg(282734, 0)) + test(lg(-92367, -1), lg(-278856469, -1), lg(3019, 0)) + test(lg(0, 0), lg(-13, -1), lg(37, 0)) + test(lg(0, 0), lg(-4, -1), lg(47150459, 0)) + test(lg(0, 0), lg(-26, -1), lg(-210691, -1)) + test(lg(0, 0), lg(-21294, -1), lg(156839456, 0)) + test(lg(0, 0), lg(-5, -1), lg(-25644, -1)) + test(lg(0, 0), lg(-1009, -1), lg(28100, 0)) + test(lg(-857, -1), lg(16282815, 0), lg(-18989, -1)) + test(lg(-7, -1), lg(-2201086, -1), lg(276963, 0)) + test(lg(-300, -1), lg(11412578, 0), lg(-37989, -1)) + test(lg(0, 0), lg(8406900, 0), lg(239727371, 0)) + test(lg(0, 0), lg(-1, -1), lg(-479069, -1)) + test(lg(0, 0), lg(4, 0), lg(-21776, -1)) + test(lg(-16812960, -1), lg(-16812960, -1), lg(1, 0)) + test(lg(0, 0), lg(10873, 0), lg(57145, 0)) + test(lg(0, 0), lg(-1, -1), lg(-7, -1)) + + // int32, int53 + test(lg(0, 0), lg(-6975858, -1), lg(42227636, 14)) + test(lg(0, 0), lg(-1, -1), lg(370644892, 82735)) + test(lg(0, 0), lg(43, 0), lg(-1602218381, 49)) + test(lg(0, 0), lg(4063968, 0), lg(973173538, 23810)) + test(lg(0, 0), lg(-388987094, -1), lg(-241988155, 1723)) + test(lg(0, 0), lg(5939808, 0), lg(-1882484681, 12)) + test(lg(0, 0), lg(7, 0), lg(-385609304, 1342)) + test(lg(0, 0), lg(-1175803932, -1), lg(297649103, 2408)) + test(lg(0, 0), lg(464610492, 0), lg(829919518, 2777)) + test(lg(0, 0), lg(214483, 0), lg(1502817270, 8078)) + + // int32, big + test(lg(0, 0), lg(211494165, 0), lg(1365318534, 14804989)) + test(lg(0, 0), lg(5353, 0), lg(-1032992082, -394605386)) + test(lg(0, 0), lg(2926, 0), lg(26982087, -226814570)) + test(lg(0, 0), lg(-6, -1), lg(-1339229562, -580578613)) + test(lg(0, 0), lg(-8, -1), lg(-108570365, 4920615)) + test(lg(0, 0), lg(-585878041, -1), lg(551925027, -1296114209)) + test(lg(0, 0), lg(-4, -1), lg(474545806, 64068407)) + test(lg(0, 0), lg(34, 0), lg(-137127086, -18652281)) + test(lg(0, 0), lg(785315, 0), lg(-881374655, 29722835)) + test(lg(0, 0), lg(713146, 0), lg(1442548271, 2727525)) + + // int53, int32 + test(lg(-578207, -1), lg(397755625, 53271), lg(-395701427, -1)) + test(lg(-560062154, 0), lg(-1680186460, 2), lg(3, 0)) + test(lg(-926675094, 18), lg(1514942014, 56), lg(3, 0)) + test(lg(-162400270, -1), lg(713597492, 1154), lg(-30524, -1)) + test(lg(-9, -1), lg(2028377478, 1), lg(-691707459, -1)) + test(lg(135006, 0), lg(1387175556, 73), lg(2332622, 0)) + test(lg(-200274428, -13), lg(1756997282, 1397), lg(-116, -1)) + test(lg(1125157, 0), lg(-1655346723, 0), lg(2346, 0)) + test(lg(997096, 0), lg(198249458, 5686), lg(24492497, 0)) + test(lg(1369365326, -302), lg(873090497, 11162), lg(-37, -1)) + test(lg(-2166511, -1), lg(360057887, 3519), lg(-6976354, -1)) + test(lg(1680790298, -2), lg(1115898639, 48), lg(-30, -1)) + test(lg(92036331, 1), lg(154624251, 955), lg(935, 0)) + test(lg(23215066, 0), lg(806830498, 1063), lg(196698, 0)) + test(lg(-13221428, -1), lg(-220365267, 21359), lg(-6938757, -1)) + test(lg(-973041595, -2009), lg(759822848, 648657), lg(-323, -1)) + test(lg(171873494, 1659), lg(-1180673754, 486098), lg(293, 0)) + test(lg(1583541189, 785), lg(1387172319, 769661), lg(980, 0)) + test(lg(-917576, -1), lg(-305851327, 2), lg(-13709, -1)) + test(lg(456092, 0), lg(577374631, 17), lg(161353, 0)) + test(lg(404991630, 376), lg(809983260, 752), lg(2, 0)) + test(lg(495082175, 39), lg(495082175, 39), lg(1, 0)) + test(lg(90893135, 0), lg(1455620681, 30929), lg(1461502, 0)) + test(lg(799104733, 0), lg(1388707384, 34362), lg(184688, 0)) + test(lg(1094556328, -70011), lg(2105854641, 140021), lg(-2, -1)) + test(lg(-1819673734, 1), lg(1310105355, 427420), lg(271150, 0)) + test(lg(-119338773, -6), lg(-236557650, 35455), lg(-7052, -1)) + test(lg(32825, 0), lg(-1127581476, 0), lg(96492, 0)) + test(lg(-57018115, -1), lg(2004387480, 7243), lg(-545624, -1)) + test(lg(-5950946, -1), lg(381447319, 2213), lg(-1597249, -1)) + test(lg(-811421531, -4249), lg(-1860702702, 12744), lg(-3, -1)) + test(lg(4741011, 0), lg(-548164065, 6487), lg(5877480, 0)) + test(lg(-1064193809, 45), lg(-476290317, 131491), lg(2874, 0)) + test(lg(228327608, 0), lg(499912484, 1), lg(21, 0)) + test(lg(99111506, 0), lg(-1509435894, 8467), lg(366943, 0)) + test(lg(-1209485521, -1), lg(-1580093356, 5), lg(-20, -1)) + test(lg(-319956618, -1), lg(1299112295, 55074), lg(-739295, -1)) + test(lg(-62197, -1), lg(-1405948570, 43), lg(-3015755, -1)) + test(lg(9087, 0), lg(1405130313, 57), lg(27093454, 0)) + test(lg(345582531, 0), lg(-1804200888, 1989226), lg(24722497, 0)) + test(lg(-1424974, -1), lg(-1642507127, 886), lg(-2672324, -1)) + test(lg(1991351, 0), lg(-1276796892, 35), lg(77004, 0)) + test(lg(1193137, 0), lg(-1200759296, 816), lg(2939970, 0)) + test(lg(573585390, 0), lg(399171813, 123795), lg(926969, 0)) + test(lg(1683063904, -942), lg(1649267984, 229752), lg(-244, -1)) + test(lg(-6019138, -1), lg(-387146187, 7364), lg(-5255245, -1)) + test(lg(-123416174, 28), lg(149703916, 19121), lg(660, 0)) + test(lg(-40732946, -1), lg(-1582312743, 7920), lg(-835168, -1)) + test(lg(715821610, 298), lg(1431643220, 596), lg(2, 0)) + test(lg(-570078780, -1), lg(-1717918737, 8458), lg(-63727, -1)) + + // int53, int53 + test(lg(1, 0), lg(-1232398900, 28871), lg(13989713, 22345)) + test(lg(0, 0), lg(-916994839, 12266), lg(1713571419, 15301)) + test(lg(32, 0), lg(1133414946, 229), lg(256531666, 7)) + test(lg(368, 0), lg(134792921, 3907), lg(-1656790262, 10)) + test(lg(1, 0), lg(1532393452, 52260), lg(-701373106, 31864)) + test(lg(0, 0), lg(193990135, 1460), lg(867607428, 6918)) + test(lg(0, 0), lg(867672590, 1), lg(-1315044816, 987593)) + test(lg(0, 0), lg(-978844610, 2), lg(720710523, 209)) + test(lg(0, 0), lg(-297570329, 1), lg(-2127979750, 195738)) + test(lg(0, 0), lg(-1035330427, 5), lg(-2091513925, 70)) + test(lg(0, 0), lg(1037142987, 15), lg(-485498951, 30819)) + test(lg(0, 0), lg(744551901, 15), lg(-604684037, 1587)) + test(lg(67766, 0), lg(1341710951, 232724), lg(1864827988, 3)) + test(lg(694, 0), lg(-409318148, 157818), lg(517165426, 227)) + test(lg(1, 0), lg(1908192460, 110512), lg(-61974596, 95795)) + test(lg(0, 0), lg(946490654, 498), lg(-1889366637, 1163)) + test(lg(12, 0), lg(1765257877, 34422), lg(728455544, 2851)) + test(lg(0, 0), lg(-1725136864, 84), lg(1122821677, 14720)) + test(lg(1, 0), lg(1854803780, 2), lg(-302860117, 1)) + test(lg(131, 0), lg(380756581, 107), lg(-806772264, 0)) + test(lg(0, 0), lg(1868292481, 1134), lg(691774521, 33775)) + test(lg(0, 0), lg(-1515810361, 98), lg(2038289788, 198)) + test(lg(315, 0), lg(-1943767475, 31777), lg(-1513506636, 100)) + test(lg(0, 0), lg(1508904915, 18), lg(1834666309, 976)) + test(lg(1, 0), lg(1430753947, 3772), lg(-1853122145, 3615)) + test(lg(2340149, 0), lg(-1654852151, 1195820), lg(-2100231332, 0)) + test(lg(0, 0), lg(1011710080, 18), lg(-616681449, 57)) + test(lg(14, 0), lg(-495370429, 356832), lg(-34555439, 25233)) + test(lg(131, 0), lg(744211838, 511), lg(-475809581, 3)) + test(lg(0, 0), lg(1135128265, 67), lg(163864249, 972)) + test(lg(1, 0), lg(954856869, 5120), lg(1474096435, 3606)) + test(lg(0, 0), lg(1544045220, 1), lg(85376495, 2353)) + test(lg(8, 0), lg(1367437144, 53), lg(2010850631, 6)) + test(lg(0, 0), lg(-1398730804, 13), lg(-2055007528, 52)) + test(lg(0, 0), lg(1598156017, 13), lg(-1006929331, 160)) + test(lg(0, 0), lg(738323529, 41), lg(-1508093984, 10361)) + test(lg(0, 0), lg(-1788797806, 31), lg(588557582, 575930)) + test(lg(76, 0), lg(-913009845, 1002), lg(204577043, 13)) + test(lg(0, 0), lg(1908599465, 6), lg(1058868127, 3383)) + test(lg(0, 0), lg(-634312634, 75), lg(-850292534, 332928)) + test(lg(0, 0), lg(-1679695022, 148), lg(-1395453213, 912)) + test(lg(0, 0), lg(456310936, 71), lg(487720864, 1590813)) + test(lg(0, 0), lg(-1724925398, 0), lg(-273170277, 38)) + test(lg(0, 0), lg(-6742076, 15), lg(192793866, 175)) + test(lg(50, 0), lg(337939061, 2094205), lg(880147944, 41142)) + test(lg(0, 0), lg(-998413092, 0), lg(-1758700885, 29)) + test(lg(0, 0), lg(1986052307, 3), lg(-2092246422, 47)) + test(lg(0, 0), lg(-109615093, 1), lg(-2066395387, 20016)) + test(lg(127, 0), lg(-1147373454, 901), lg(313439710, 7)) + test(lg(0, 0), lg(-792716629, 66379), lg(2017337246, 250513)) + + // int53, big + test(lg(0, 0), lg(291278707, 13808), lg(941639833, -14430466)) + test(lg(0, 0), lg(-857819626, 204588), lg(-1909684886, -709519130)) + test(lg(0, 0), lg(-978105991, 7435), lg(-306472275, 158306339)) + test(lg(0, 0), lg(75049741, 248171), lg(-1574105194, 64879257)) + test(lg(0, 0), lg(136051120, 621), lg(-1671784392, 102642869)) + test(lg(0, 0), lg(-448460356, 2858), lg(71740423, -16715717)) + test(lg(0, 0), lg(-1266403435, 2), lg(-1022999838, 25812014)) + test(lg(0, 0), lg(552733494, 22), lg(241731505, -33191170)) + test(lg(0, 0), lg(1366167794, 115591), lg(191854687, -2136953)) + test(lg(0, 0), lg(1329114439, 80951), lg(-51187101, 1471052997)) + + // big, int32 + test(lg(422668131, 6), lg(-1495113094, 168518701), lg(27633219, 0)) + test(lg(932715295, 204683), lg(-1211847018, -609137255), lg(-2976, -1)) + test(lg(189814434, 0), lg(-457166837, -15040808), lg(-340331202, -1)) + test(lg(-1116045071, -1131771), lg(-104570473, -117704108), lg(104, 0)) + test(lg(-784306379, 14408), lg(453828098, -10187034), lg(-707, -1)) + test(lg(-284027201, 2002401), lg(1911518920, 168201762), lg(84, 0)) + test(lg(-862273257, -2), lg(610589058, 36481453), lg(-30381877, -1)) + test(lg(-761280647, -71), lg(410700182, 503953004), lg(-7181145, -1)) + test(lg(-1212582262, -2538), lg(194917334, -8806907), lg(3471, 0)) + test(lg(-1201233065, 4), lg(852311155, 9671380), lg(2048884, 0)) + test(lg(1324107666, 0), lg(-1028681544, 4163983), lg(13506586, 0)) + test(lg(-354367044, 6361111), lg(-708734088, 12722223), lg(2, 0)) + test(lg(-292170842, -76359), lg(1693696214, 18402294), lg(-241, -1)) + test(lg(2104544550, -41349584), lg(-1932788158, 206747917), lg(-5, -1)) + test(lg(-1928473941, -17816), lg(1427262980, -60732866), lg(3409, 0)) + test(lg(-1929237164, -681), lg(-677896940, 2512898), lg(-3693, -1)) + test(lg(1550060300, -35), lg(-926729663, -9677195), lg(279372, 0)) + test(lg(-1706875941, 0), lg(-405257725, -2271799), lg(-3770075, -1)) + test(lg(1540708852, 10909), lg(-1893733008, -6491069), lg(-595, -1)) + test(lg(-1563665409, -358), lg(-1343018634, -2584815), lg(7233, 0)) + test(lg(278715917, -374389), lg(-1224507547, 122799570), lg(-328, -1)) + test(lg(1421525100, 0), lg(-2082712791, -15998594), lg(-48337828, -1)) + test(lg(1574832373, -2193811), lg(-2147318181, -32907160), lg(15, 0)) + test(lg(-1260116915, -61610), lg(1074158039, 118905936), lg(-1930, -1)) + test(lg(130856059, -15612), lg(1270835097, -2201288), lg(141, 0)) + test(lg(-110248455, 2347), lg(320077861, -446108079), lg(-189997, -1)) + test(lg(-1659387265, 122), lg(1075676628, 54005547), lg(440453, 0)) + test(lg(-144903831, 18), lg(-1800001035, 54578889), lg(2877683, 0)) + test(lg(-1312994937, -23952), lg(-654120591, 33364168), lg(-1393, -1)) + test(lg(-178073210, -1), lg(302695822, -2432394), lg(58667176, 0)) + test(lg(1316938460, 142), lg(523451067, -54366538), lg(-382038, -1)) + test(lg(-1457978633, 17556853), lg(-78968601, 52670560), lg(3, 0)) + test(lg(-1760960552, 505129611), lg(-773046192, -1010259224), lg(-2, -1)) + test(lg(1210355204, 2314), lg(1515488136, -21874592), lg(-9452, -1)) + test(lg(-1625685934, 862807773), lg(-1043595428, -1725615548), lg(-2, -1)) + test(lg(184379181, 4), lg(-1217231978, 1516494005), lg(375097846, 0)) + test(lg(1243945230, 0), lg(-1873413508, -236381131), lg(-816152673, -1)) + test(lg(-1540093941, -876), lg(265593875, 26513736), lg(-30289, -1)) + test(lg(-1304692919, 543912), lg(106204837, -839801203), lg(-1544, -1)) + test(lg(-806250591, 23), lg(815576040, -55524975), lg(-2331779, -1)) + test(lg(-2106907248, -3), lg(-2053929476, -1795047022), lg(720742474, 0)) + test(lg(893100234, -124), lg(1552099699, 65024502), lg(-525272, -1)) + test(lg(-1109915706, 1255), lg(-194253417, -12405472), lg(-9879, -1)) + test(lg(-1177955013, 0), lg(412309016, 112344162), lg(154800321, 0)) + test(lg(-1975688052, -51023804), lg(343591192, -102047607), lg(2, 0)) + test(lg(-728332094, -309956), lg(1756765281, 8058834), lg(-26, -1)) + test(lg(10173004, 1227), lg(1762668787, -960735493), lg(-782994, -1)) + test(lg(1157067129, 5766), lg(1523935530, -109345767), lg(-18963, -1)) + test(lg(1226263794, 42306948), lg(-1256703941, 1438436241), lg(34, 0)) + test(lg(1502167534, -439314), lg(-444491016, -6150392), lg(14, 0)) + + // big, int53 + test(lg(88399, 0), lg(-1883357942, 360257606), lg(1478768728, 4075)) + test(lg(-45459, -1), lg(-1991900757, -48856999), lg(-1087694619, 1074)) + test(lg(4395497, 0), lg(518426119, 218946975), lg(-808940852, 49)) + test(lg(3198134, 0), lg(-946567777, 600381050), lg(-1165957306, 187)) + test(lg(470, 0), lg(257885254, 845979705), lg(792779187, 1798424)) + test(lg(92, 0), lg(1278680372, 6485140), lg(1376461023, 70263)) + test(lg(167728, 0), lg(1445602310, 420550818), lg(1397186900, 2507)) + test(lg(25700177, 0), lg(1822058703, 522114268), lg(1355449555, 20)) + test(lg(-35822646, -1), lg(532749659, -130990067), lg(-1474774415, 3)) + test(lg(-348, -1), lg(1329707986, -2121642), lg(-63366094, 6086)) + test(lg(-2179, -1), lg(1028585430, -118524228), lg(1655878874, 54392)) + test(lg(1187, 0), lg(203502475, 42252914), lg(36519512, 35581)) + test(lg(3223, 0), lg(341088508, 35053507), lg(917391400, 10874)) + test(lg(23608500, 0), lg(1454135412, 69933847), lg(-162213744, 2)) + test(lg(7286803, 0), lg(1674604578, 10565585), lg(1932570831, 1)) + test(lg(-137450, -1), lg(-1910257093, -16610962), lg(-640594227, 120)) + test(lg(114592, 0), lg(1080864951, 17606069), lg(-1542196664, 153)) + test(lg(61, 0), lg(-1419644278, 13937517), lg(-919779905, 227700)) + test(lg(-247360, -1), lg(-1958380469, -855713410), lg(1631833189, 3459)) + test(lg(-61725, -1), lg(1951473618, -4122677), lg(-899615165, 66)) + test(lg(2226, 0), lg(1521276132, 182952467), lg(346742782, 82171)) + test(lg(-997, -1), lg(-1003647481, -7808320), lg(-228453385, 7826)) + test(lg(36, 0), lg(-875689390, 4467236), lg(-590010750, 120938)) + test(lg(56005, 0), lg(1189085620, 611543209), lg(1619962756, 10919)) + test(lg(-90057, -1), lg(-1072173311, -18503031), lg(1971480267, 205)) + test(lg(-9, -1), lg(767303802, -3407362), lg(-339044225, 352939)) + test(lg(62240, 0), lg(427996893, 482974074), lg(-736462105, 7759)) + test(lg(-1774, -1), lg(842450255, -4396651), lg(859272322, 2477)) + test(lg(-153400, -1), lg(1640433988, -2618618), lg(302672196, 17)) + test(lg(2145, 0), lg(-361322518, 63967358), lg(-1922353888, 29810)) + test(lg(106042, 0), lg(-1774479550, 43276853), lg(472456506, 408)) + test(lg(-381407, -1), lg(-1756338345, -38928780), lg(283612141, 102)) + test(lg(1217514, 0), lg(-495049835, 37161263), lg(-2052025512, 30)) + test(lg(-17, -1), lg(1606509747, -10876159), lg(1068727249, 635715)) + test(lg(4880327, 0), lg(-1857686692, 1918485655), lg(454913535, 393)) + test(lg(-1023070, -1), lg(-502107392, -511268482), lg(-1118977400, 499)) + test(lg(439, 0), lg(-909192131, 45216813), lg(1442986382, 102923)) + test(lg(2171202, 0), lg(259184089, 14858724), lg(-671961291, 6)) + test(lg(-5332527, -1), lg(1737846340, -614952982), lg(1379175047, 115)) + test(lg(-435180, -1), lg(-406629212, -528407898), lg(973577032, 1214)) + test(lg(27837, 0), lg(-597461306, 538945619), lg(-1867966522, 19360)) + test(lg(-396, -1), lg(-1906945200, -371170760), lg(151858506, 936902)) + test(lg(-115583279, -1), lg(-1366510, -207691415), lg(-872314548, 1)) + test(lg(-6783543, -1), lg(-1280665444, -104856505), lg(1964875665, 15)) + test(lg(-1464006069, -1), lg(897601097, -1352132581), lg(-328204224, 0)) + test(lg(11599107, 0), lg(-496529216, 32992512), lg(-668292521, 2)) + test(lg(842, 0), lg(1819966537, 311969505), lg(-879441284, 370147)) + test(lg(43514, 0), lg(433235702, 408255734), lg(573404298, 9382)) + test(lg(-230, -1), lg(1693350453, -4127304), lg(-1671879801, 17931)) + test(lg(249094, 0), lg(-492682302, 64433722), lg(-1408841594, 258)) + + // big, big + test(lg(-10, -1), lg(1450795502, -706709103), lg(742056886, 64843937)) + test(lg(0, 0), lg(-392893244, 72026637), lg(1419676270, 875736789)) + test(lg(-2, -1), lg(-1861146463, 8382761), lg(-724412724, -3000735)) + test(lg(0, 0), lg(1373482238, 23344691), lg(1835527248, -294342355)) + test(lg(-37, -1), lg(1956796392, 107480459), lg(-560958184, -2839471)) + test(lg(3, 0), lg(422228275, 30436377), lg(-2023395425, 8226201)) + test(lg(-3, -1), lg(1747624836, -215352612), lg(-1349940168, 58723974)) + test(lg(2, 0), lg(-583006891, 16111063), lg(1853686630, 5479773)) + test(lg(0, 0), lg(1498104050, 7322401), lg(-407388940, 2141575618)) + test(lg(5, 0), lg(1943726712, 869895175), lg(-627430826, 169278540)) + test(lg(0, 0), lg(1872895982, 98966340), lg(1347573135, 529034148)) + test(lg(-2, -1), lg(16010610, 187913494), lg(-848952152, -81951424)) + test(lg(0, 0), lg(830929771, -4393252), lg(1829525088, 52659897)) + test(lg(22, 0), lg(-2093526384, 133319293), lg(-464927151, 6049576)) + test(lg(0, 0), lg(1056318793, 13467735), lg(1970348162, -672507521)) + test(lg(0, 0), lg(-28853693, -169722715), lg(-83877421, 770900857)) + test(lg(-27, -1), lg(1743854071, -302158995), lg(80117835, 11113120)) + test(lg(-6, -1), lg(635796581, -146765250), lg(441664676, 23716738)) + test(lg(0, 0), lg(-1048312948, -37662905), lg(1319664078, 208772026)) + test(lg(0, 0), lg(-784292680, -14102823), lg(2037268040, 744987722)) + test(lg(176, 0), lg(-1116104092, -2073525743), lg(1766685765, -11731135)) + test(lg(0, 0), lg(-1991687284, 19448294), lg(-1731357606, -202272807)) + test(lg(6, 0), lg(-2042068328, -52956481), lg(370482897, -7759903)) + test(lg(1, 0), lg(334395247, 1906338595), lg(342095090, 1248830168)) + test(lg(0, 0), lg(-309616588, 44123460), lg(2040055580, -476494291)) + test(lg(0, 0), lg(137178123, 36336421), lg(-360221107, -515689970)) + test(lg(0, 0), lg(-422856762, -16760844), lg(-334268074, -43984484)) + test(lg(0, 0), lg(-24820293, 25823996), lg(390711705, 288223876)) + test(lg(0, 0), lg(1170265006, 2998984), lg(-134995170, -2123267074)) + test(lg(0, 0), lg(-1501380980, -6088910), lg(-1175861016, -56027408)) + test(lg(-56, -1), lg(307880183, 196786483), lg(-1107761890, -3480429)) + test(lg(0, 0), lg(-588606997, -37732967), lg(-1124435958, -77404915)) + test(lg(108, 0), lg(90560661, 990295925), lg(731139348, 9165999)) + test(lg(0, 0), lg(46312609, -28251908), lg(1279863155, -519028300)) + test(lg(0, 0), lg(1123427761, 55212863), lg(-1081219733, 233090714)) + test(lg(0, 0), lg(1447869812, -3646400), lg(-1237950546, -27122943)) + test(lg(-13, -1), lg(-1399920635, 110072031), lg(-398678056, -8069387)) + test(lg(0, 0), lg(513704441, 14319377), lg(-796719013, 260081997)) + test(lg(8, 0), lg(166886349, -190148673), lg(68245235, -21656365)) + test(lg(0, 0), lg(-1594024534, -144937584), lg(177399758, 200473672)) + test(lg(-1, -1), lg(447753993, -23591908), lg(1399162166, 12505918)) + test(lg(0, 0), lg(1500283330, 5361180), lg(348398676, 156400271)) + test(lg(-1, -1), lg(-216115001, 670826068), lg(1759253954, -470062110)) + test(lg(0, 0), lg(-1251659767, 18831569), lg(-669341445, -34474821)) + test(lg(31, 0), lg(817032953, 218701872), lg(-176557210, 6899121)) + test(lg(-19, -1), lg(1365998269, 613319842), lg(319204438, -30758748)) + test(lg(0, 0), lg(-428500325, 6610536), lg(-46648893, -105360271)) + test(lg(0, 0), lg(784528299, -6958267), lg(1370662827, -774132635)) + test(lg(-2, -1), lg(-769114167, 137614183), lg(-929091402, -67103082)) + test(lg(8, 0), lg(1810734914, 124115952), lg(1149563530, 15197570)) + } + + @Test def modulo_%(): Unit = { + @inline def test(expected: Long, x: Long, y: Long): Unit = { + assertEquals(expected, x % y) + assertEquals(expected, hideFromOptimizer(x) % y) + assertEquals(expected, x % hideFromOptimizer(y)) + assertEquals(expected, hideFromOptimizer(x) % hideFromOptimizer(y)) + } + + test(lg(0), IntMinVal, lg(-1)) + test(lg(0), IntMinVal, IntMaxValPlus1) + test(lg(0), IntMaxValPlus1, lg(-1)) + test(lg(0), IntMaxValPlus1, IntMinVal) + + test(lg(0), MaxVal, lg(-1)) + test(lg(0), MinVal, lg(1)) + test(lg(0), MinVal, lg(-1)) + + test(lg(-1, 2147483647), MaxVal, MinVal) + test(lg(0), MaxVal, MaxVal) + test(lg(0), MinVal, MinVal) + test(lg(-1), MinVal, MaxVal) + + // int32, int32 + test(lg(880, 0), lg(880, 0), lg(-219594, -1)) + test(lg(-27, -1), lg(-49125, -1), lg(98, 0)) + test(lg(-1194, -1), lg(-1922504, -1), lg(4195, 0)) + test(lg(3, 0), lg(3, 0), lg(7963, 0)) + test(lg(-626, -1), lg(-626, -1), lg(-484628621, -1)) + test(lg(11315, 0), lg(11315, 0), lg(-3914076, -1)) + test(lg(26241, 0), lg(15712341, 0), lg(-1045740, -1)) + test(lg(-507, -1), lg(-855439, -1), lg(5213, 0)) + test(lg(-259, -1), lg(-101026259, -1), lg(-500, -1)) + test(lg(27720977, 0), lg(27720977, 0), lg(-42317657, -1)) + test(lg(1, 0), lg(25954, 0), lg(-3, -1)) + test(lg(6724180, 0), lg(338447650, 0), lg(-8505730, -1)) + test(lg(10488, 0), lg(23967, 0), lg(-13479, -1)) + test(lg(1, 0), lg(885202, 0), lg(-3, -1)) + test(lg(0, 0), lg(692795590, 0), lg(-10, -1)) + test(lg(-1, -1), lg(-1, -1), lg(156, 0)) + test(lg(388, 0), lg(388, 0), lg(189523294, 0)) + test(lg(352, 0), lg(352, 0), lg(-3257, -1)) + test(lg(-9, -1), lg(-9, -1), lg(14653, 0)) + test(lg(-1, -1), lg(-258745, -1), lg(8, 0)) + test(lg(-21023, -1), lg(-206976653, -1), lg(34321, 0)) + test(lg(-1, -1), lg(-1, -1), lg(-971, -1)) + test(lg(59, 0), lg(59, 0), lg(388, 0)) + test(lg(0, 0), lg(-7, -1), lg(1, 0)) + test(lg(12, 0), lg(77, 0), lg(13, 0)) + test(lg(224246, 0), lg(224246, 0), lg(719055, 0)) + test(lg(-61296, -1), lg(-61296, -1), lg(-135723660, -1)) + test(lg(549465, 0), lg(6897809, 0), lg(793543, 0)) + test(lg(45, 0), lg(45, 0), lg(984210147, 0)) + test(lg(0, 0), lg(-64, -1), lg(1, 0)) + test(lg(2, 0), lg(379611734, 0), lg(4, 0)) + test(lg(0, 0), lg(0, 0), lg(-263, -1)) + test(lg(29, 0), lg(29, 0), lg(-117, -1)) + test(lg(24, 0), lg(245094, 0), lg(-70, -1)) + test(lg(0, 0), lg(0, 0), lg(5, 0)) + test(lg(2, 0), lg(2, 0), lg(47787927, 0)) + test(lg(-124, -1), lg(-124, -1), lg(-22714040, -1)) + test(lg(412, 0), lg(412, 0), lg(-17176, -1)) + test(lg(-11860, -1), lg(-11860, -1), lg(9506787, 0)) + test(lg(-31, -1), lg(-31, -1), lg(-1544676, -1)) + test(lg(-3, -1), lg(-1990315281, -1), lg(-7, -1)) + test(lg(99, 0), lg(99, 0), lg(-277, -1)) + test(lg(-86, -1), lg(-29227, -1), lg(-161, -1)) + test(lg(106, 0), lg(106, 0), lg(-47032956, -1)) + test(lg(18, 0), lg(18, 0), lg(510836179, 0)) + test(lg(2, 0), lg(3543112, 0), lg(10, 0)) + test(lg(534271, 0), lg(3547603, 0), lg(-1506666, -1)) + test(lg(-16361, -1), lg(-16361, -1), lg(10637613, 0)) + test(lg(8, 0), lg(606879016, 0), lg(-16, -1)) + test(lg(-1, -1), lg(-1, -1), lg(46424570, 0)) + + // int32, int53 + test(lg(-3, -1), lg(-3, -1), lg(206801065, 1)) + test(lg(-57756, -1), lg(-57756, -1), lg(-1211050362, 13)) + test(lg(0, 0), lg(0, 0), lg(-475702596, 10040)) + test(lg(423524, 0), lg(423524, 0), lg(-2084961556, 16)) + test(lg(38317, 0), lg(38317, 0), lg(-1699004544, 24)) + test(lg(60291, 0), lg(60291, 0), lg(-458289291, 56)) + test(lg(1, 0), lg(1, 0), lg(-1247681936, 1229953)) + test(lg(296788, 0), lg(296788, 0), lg(183245860, 52)) + test(lg(-2005515, -1), lg(-2005515, -1), lg(331735459, 17)) + test(lg(-179812, -1), lg(-179812, -1), lg(-853047550, 5154)) + test(lg(-3678, -1), lg(-3678, -1), lg(1751271067, 243605)) + test(lg(-93867, -1), lg(-93867, -1), lg(-1925367590, 42)) + test(lg(7600917, 0), lg(7600917, 0), lg(-1807424604, 95574)) + test(lg(300012, 0), lg(300012, 0), lg(1951216728, 101)) + test(lg(-6347, -1), lg(-6347, -1), lg(-438713154, 23)) + test(lg(-41, -1), lg(-41, -1), lg(-1211982116, 459)) + test(lg(3425, 0), lg(3425, 0), lg(-1580976156, 2)) + test(lg(-25, -1), lg(-25, -1), lg(200240265, 25993)) + test(lg(-8303, -1), lg(-8303, -1), lg(1353761386, 1921)) + test(lg(274032571, 0), lg(274032571, 0), lg(1455543028, 255)) + test(lg(-3, -1), lg(-3, -1), lg(1143775281, 729)) + test(lg(-1124428, -1), lg(-1124428, -1), lg(-521284400, 339)) + test(lg(-2, -1), lg(-2, -1), lg(-303859962, 2524)) + test(lg(1, 0), lg(1, 0), lg(-402000545, 1)) + test(lg(107013504, 0), lg(107013504, 0), lg(157604607, 3)) + test(lg(4976822, 0), lg(4976822, 0), lg(-2046021074, 2230)) + test(lg(-1, -1), lg(-1, -1), lg(-306200858, 41)) + test(lg(80396, 0), lg(80396, 0), lg(-409002766, 13)) + test(lg(937638, 0), lg(937638, 0), lg(-697219650, 26)) + test(lg(756, 0), lg(756, 0), lg(-948806692, 1700920)) + test(lg(5, 0), lg(5, 0), lg(646021801, 21350)) + test(lg(262831839, 0), lg(262831839, 0), lg(1086270794, 10633)) + test(lg(-2146273993, -1), lg(-2146273993, -1), lg(-1539129401, 0)) + test(lg(59799, 0), lg(59799, 0), lg(1910837623, 102082)) + test(lg(-5347, -1), lg(-5347, -1), lg(1965292799, 18)) + test(lg(926, 0), lg(926, 0), lg(1939309159, 104206)) + test(lg(1, 0), lg(1, 0), lg(1651864405, 1233)) + test(lg(334, 0), lg(334, 0), lg(581635234, 20)) + test(lg(-61747, -1), lg(-61747, -1), lg(-842193425, 1497)) + test(lg(-1, -1), lg(-1, -1), lg(758739794, 79508)) + test(lg(59605313, 0), lg(59605313, 0), lg(-1162319751, 0)) + test(lg(12267518, 0), lg(12267518, 0), lg(1340161110, 568352)) + test(lg(19230695, 0), lg(19230695, 0), lg(1844291137, 21)) + test(lg(3950296, 0), lg(3950296, 0), lg(-848670202, 243)) + test(lg(503276, 0), lg(503276, 0), lg(-1756374670, 1)) + test(lg(30880536, 0), lg(30880536, 0), lg(-1380766565, 51064)) + test(lg(5659804, 0), lg(5659804, 0), lg(-725339057, 1)) + test(lg(11882277, 0), lg(11882277, 0), lg(243727355, 7)) + test(lg(371783010, 0), lg(371783010, 0), lg(630143580, 14001)) + test(lg(840, 0), lg(840, 0), lg(-1719362098, 109)) + + // int32, big + test(lg(-267334310, -1), lg(-267334310, -1), lg(1537718115, -134598983)) + test(lg(57, 0), lg(57, 0), lg(-1668867109, -10100325)) + test(lg(30332, 0), lg(30332, 0), lg(-615310153, -90004876)) + test(lg(187, 0), lg(187, 0), lg(-590535223, 8244144)) + test(lg(-2, -1), lg(-2, -1), lg(2125719729, 390762530)) + test(lg(-4252915, -1), lg(-4252915, -1), lg(2070489053, 23484863)) + test(lg(-2, -1), lg(-2, -1), lg(37507428, 96913792)) + test(lg(10, 0), lg(10, 0), lg(-533680689, -79923599)) + test(lg(-14, -1), lg(-14, -1), lg(-930313329, 2972085)) + test(lg(-20155233, -1), lg(-20155233, -1), lg(-49989774, -25498857)) + test(lg(-406, -1), lg(-406, -1), lg(2109762544, 126098611)) + test(lg(43, 0), lg(43, 0), lg(598811771, 154269509)) + test(lg(-4830, -1), lg(-4830, -1), lg(-1043650540, -2874494)) + test(lg(-4271, -1), lg(-4271, -1), lg(-950378080, -106126516)) + test(lg(126, 0), lg(126, 0), lg(-877412093, -90804729)) + test(lg(40445345, 0), lg(40445345, 0), lg(-1461218790, 6749169)) + test(lg(-1, -1), lg(-1, -1), lg(1776909778, 28425796)) + test(lg(-2123811, -1), lg(-2123811, -1), lg(-51805125, 44153129)) + test(lg(-25650126, -1), lg(-25650126, -1), lg(-1317209725, -16141386)) + test(lg(30, 0), lg(30, 0), lg(712479950, 158765535)) + test(lg(2494211, 0), lg(2494211, 0), lg(-432472367, 21859989)) + test(lg(100937174, 0), lg(100937174, 0), lg(212873269, -74778594)) + test(lg(901687, 0), lg(901687, 0), lg(-1225225931, -512562107)) + test(lg(-422854, -1), lg(-422854, -1), lg(-1361503923, -98826041)) + test(lg(2, 0), lg(2, 0), lg(386622050, -9945722)) + test(lg(-465211, -1), lg(-465211, -1), lg(-418132599, -160175963)) + test(lg(63, 0), lg(63, 0), lg(-1330189832, 180061391)) + test(lg(47, 0), lg(47, 0), lg(1439978282, -16520554)) + test(lg(233450563, 0), lg(233450563, 0), lg(-328511972, 377539644)) + test(lg(-134912, -1), lg(-134912, -1), lg(1349244684, -12612862)) + test(lg(-95441, -1), lg(-95441, -1), lg(511120357, 16112596)) + test(lg(-1160726496, -1), lg(-1160726496, -1), lg(-913371934, -9441145)) + test(lg(-502, -1), lg(-502, -1), lg(-1021329523, -377728463)) + test(lg(3313324, 0), lg(3313324, 0), lg(-67454848, 442297818)) + test(lg(-145, -1), lg(-145, -1), lg(-1010112762, 29724438)) + test(lg(-19091, -1), lg(-19091, -1), lg(-1944488998, -173788926)) + test(lg(-3331910, -1), lg(-3331910, -1), lg(2144172121, 73505274)) + test(lg(56622, 0), lg(56622, 0), lg(-1451372835, 5219178)) + test(lg(0, 0), lg(0, 0), lg(556032035, 32471322)) + test(lg(800, 0), lg(800, 0), lg(-1649243607, 2299368)) + test(lg(86949, 0), lg(86949, 0), lg(794150820, -1384562176)) + test(lg(10, 0), lg(10, 0), lg(-790693444, 1000869239)) + test(lg(-333236, -1), lg(-333236, -1), lg(-1020207444, 125043716)) + test(lg(-598, -1), lg(-598, -1), lg(-93061561, -329975227)) + test(lg(-19, -1), lg(-19, -1), lg(-1096862531, 163621631)) + test(lg(465328283, 0), lg(465328283, 0), lg(-21925149, -52057346)) + test(lg(-25837, -1), lg(-25837, -1), lg(677002620, 8643698)) + test(lg(-383633650, -1), lg(-383633650, -1), lg(1609519787, 8262009)) + test(lg(-66, -1), lg(-66, -1), lg(1917139359, 239618524)) + test(lg(1676620, 0), lg(1676620, 0), lg(910745834, 82765572)) + + // int53 / int32 + test(lg(15827410, 0), lg(1244623439, 3), lg(-231372097, -1)) + test(lg(15118, 0), lg(-1392787378, 124), lg(-20252, -1)) + test(lg(11, 0), lg(578165055, 72), lg(13, 0)) + test(lg(42298679, 0), lg(-1836745385, 3), lg(-95630157, -1)) + test(lg(17447610, 0), lg(-1766124150, 29), lg(-45315780, -1)) + test(lg(0, 0), lg(540281958, 253606), lg(-11, -1)) + test(lg(51980, 0), lg(-442404110, 7696), lg(1489246, 0)) + test(lg(2, 0), lg(-631827526, 1455), lg(8, 0)) + test(lg(5125741, 0), lg(1266390909, 49), lg(-34627848, -1)) + test(lg(77691, 0), lg(-453014259, 21413), lg(149449, 0)) + test(lg(521867604, 0), lg(1573062436, 653), lg(671211684, 0)) + test(lg(14579368, 0), lg(-21113520, 0), lg(177469767, 0)) + test(lg(0, 0), lg(-262825676, 31), lg(1, 0)) + test(lg(24027362, 0), lg(-163968426, 1), lg(33341027, 0)) + test(lg(6792805, 0), lg(668741217, 14380), lg(-11334498, -1)) + test(lg(9, 0), lg(808041281, 1818), lg(-10, -1)) + test(lg(204, 0), lg(-1601247507, 25), lg(-235, -1)) + test(lg(61089, 0), lg(-1577206289, 0), lg(1618642, 0)) + test(lg(289305533, 0), lg(863396135, 503), lg(-321808286, -1)) + test(lg(7272892, 0), lg(-900149281, 55), lg(15166197, 0)) + test(lg(3, 0), lg(1802954050, 3593), lg(7, 0)) + test(lg(12036, 0), lg(800669146, 41901), lg(-20591, -1)) + test(lg(29, 0), lg(-1055636867, 39), lg(48, 0)) + test(lg(0, 0), lg(-491067123, 14), lg(1, 0)) + test(lg(260441364, 0), lg(1420289126, 67), lg(1010219079, 0)) + test(lg(3936541, 0), lg(1338756461, 32), lg(-4427443, -1)) + test(lg(183313645, 0), lg(-820843233, 778), lg(-273780418, -1)) + test(lg(91783, 0), lg(-1033566360, 561225), lg(-156677, -1)) + test(lg(5, 0), lg(-1567070603, 38), lg(-8, -1)) + test(lg(11214823, 0), lg(-1649343541, 185302), lg(-19368267, -1)) + test(lg(75719, 0), lg(-591434325, 76351), lg(94212, 0)) + test(lg(10941, 0), lg(235794528, 55), lg(17599, 0)) + test(lg(5331, 0), lg(-763589741, 116), lg(-14942, -1)) + test(lg(1, 0), lg(-1283158225, 237055), lg(-2, -1)) + test(lg(24400, 0), lg(1537105400, 29108), lg(-37848, -1)) + test(lg(95, 0), lg(-56778611, 994650), lg(-170, -1)) + test(lg(9836, 0), lg(-2057746932, 7), lg(-10100, -1)) + test(lg(30255783, 0), lg(1365793356, 12), lg(-38454651, -1)) + test(lg(417, 0), lg(-2128793438, 4), lg(6825, 0)) + test(lg(0, 0), lg(1667515072, 8), lg(2, 0)) + test(lg(257, 0), lg(420324337, 980), lg(-845, -1)) + test(lg(82991, 0), lg(-771084081, 8204), lg(105392, 0)) + test(lg(691256, 0), lg(-332377894, 1), lg(882238, 0)) + test(lg(0, 0), lg(1749263284, 11), lg(-20, -1)) + test(lg(4, 0), lg(347303218, 1234317), lg(-13, -1)) + test(lg(150, 0), lg(1199079324, 17271), lg(11033, 0)) + test(lg(14, 0), lg(1196217208, 13), lg(-23, -1)) + test(lg(256216433, 0), lg(-1078128939, 0), lg(740155481, 0)) + test(lg(45583, 0), lg(-1354463473, 3691), lg(-63588, -1)) + test(lg(459, 0), lg(-1255896801, 1469630), lg(-502, -1)) + + // int53, int53 + test(lg(1805177178, 1), lg(1805177178, 1), lg(-1293833696, 410)) + test(lg(-583440651, 2), lg(647007072, 1811985), lg(1091239449, 3)) + test(lg(1346307032, 1), lg(1346307032, 1), lg(-672335266, 33)) + test(lg(858355422, 81), lg(858355422, 81), lg(1490435172, 162402)) + test(lg(744276027, 1), lg(-1299053281, 6330), lg(1042770708, 1)) + test(lg(29273105, 0), lg(-88774269, 25), lg(775537355, 1)) + test(lg(383200445, 2), lg(-962613261, 4309), lg(-529185362, 5)) + test(lg(-171009725, 445), lg(-171009725, 445), lg(-1167557775, 307982)) + test(lg(8166883, 15498), lg(1848497503, 78519), lg(1533824479, 15755)) + test(lg(-1752533311, 17), lg(-1752533311, 17), lg(1904799096, 73566)) + test(lg(-1641266817, 46), lg(-1641266817, 46), lg(-31936789, 751199)) + test(lg(-350685679, 656), lg(-637954451, 32352), lg(-10259599, 1131)) + test(lg(-1671876486, 0), lg(-1657673170, 122149), lg(-534342412, 0)) + test(lg(-660565679, 235), lg(-660565679, 235), lg(-897090894, 14655)) + test(lg(-1798560222, 612), lg(-1798560222, 612), lg(-236039758, 2924)) + test(lg(-28767936, 5704), lg(1010899296, 62798), lg(-1974205776, 9515)) + test(lg(-2004786867, 4), lg(1206965517, 91420), lg(880030876, 7)) + test(lg(712148070, 3), lg(712148070, 3), lg(472319826, 2838)) + test(lg(-1275175525, 44), lg(-1275175525, 44), lg(162799342, 861329)) + test(lg(1187224322, 14), lg(-516916094, 191396), lg(-1920802608, 30)) + test(lg(-1461747946, 0), lg(-1627551726, 4499), lg(1200735793, 1)) + test(lg(453535447, 39039), lg(453535447, 39039), lg(520791957, 141909)) + test(lg(216221627, 20), lg(216221627, 20), lg(-781572865, 8131)) + test(lg(1611884803, 23), lg(-1999221053, 528), lg(1107934896, 25)) + test(lg(1722095012, 0), lg(-701225584, 44), lg(-1403297482, 0)) + test(lg(-232837834, 5049), lg(-232837834, 5049), lg(1000581509, 15836)) + test(lg(-82376749, 239), lg(-82376749, 239), lg(-163409376, 7688)) + test(lg(2063025646, 2), lg(941363778, 110), lg(336092572, 3)) + test(lg(721574845, 383), lg(1004884706, 1133), lg(283309861, 750)) + test(lg(-2004547354, 47), lg(1436404594, 1595), lg(1522987410, 70)) + test(lg(1696970595, 8), lg(1696970595, 8), lg(-1168832286, 4163)) + test(lg(-2033329312, 6), lg(-1244970780, 32), lg(394179266, 13)) + test(lg(1864629418, 1), lg(1864629418, 1), lg(528888491, 970677)) + test(lg(1596298266, 43057), lg(-1763600443, 962032), lg(1535552275, 102108)) + test(lg(1181714932, 5), lg(1181714932, 5), lg(1296434411, 26359)) + test(lg(-2140209952, 7), lg(1535735456, 276446), lg(-1930593680, 7)) + test(lg(-1703068243, 11), lg(2079501385, 97596), lg(-1803771626, 21)) + test(lg(-1025858772, 33402), lg(286993796, 174379), lg(656426284, 70488)) + test(lg(-578045904, 11724), lg(221015334, 1635766), lg(-2014306775, 270673)) + test(lg(-2080784768, 56), lg(-2103734262, 977), lg(-22949494, 920)) + test(lg(-922083739, 29), lg(-922083739, 29), lg(2040148267, 19160)) + test(lg(-1728890579, 468), lg(-559850131, 11989), lg(1366001936, 2880)) + test(lg(1341547600, 13), lg(-1071198220, 2182), lg(1526886260, 17)) + test(lg(-896451936, 45), lg(-896451936, 45), lg(2132477227, 164356)) + test(lg(-1538011120, 53), lg(-561327714, 1420), lg(-368698210, 151)) + test(lg(1880884956, 621), lg(2112956103, 118429), lg(-374507565, 859)) + test(lg(902909663, 0), lg(380445410, 8), lg(-1822479769, 1)) + test(lg(-652149100, 56), lg(-1867274924, 105813), lg(175641312, 79)) + test(lg(-991170416, 37), lg(-991170416, 37), lg(1740161397, 88122)) + test(lg(-31602776, 1), lg(-31602776, 1), lg(-503633567, 241909)) + + // int53, big + test(lg(-930109303, 3), lg(-930109303, 3), lg(1606982787, 925386547)) + test(lg(-717668907, 16251), lg(-717668907, 16251), lg(2079100937, 7825426)) + test(lg(265990345, 3), lg(265990345, 3), lg(-1140922127, -3108870)) + test(lg(-1181318422, 1), lg(-1181318422, 1), lg(1489652251, 75207246)) + test(lg(380276439, 59), lg(380276439, 59), lg(-1062351234, -3631372)) + test(lg(1080382784, 7211), lg(1080382784, 7211), lg(572850722, -139092025)) + test(lg(2020323378, 316), lg(2020323378, 316), lg(1716930349, -16333391)) + test(lg(1302118364, 5), lg(1302118364, 5), lg(-442067036, 1941456592)) + test(lg(-641137972, 602), lg(-641137972, 602), lg(1134212295, -135713760)) + test(lg(-761172703, 499), lg(-761172703, 499), lg(769981236, 12756336)) + test(lg(1601268090, 610), lg(1601268090, 610), lg(448513898, -160887452)) + test(lg(-16483553, 0), lg(-16483553, 0), lg(-1253549192, -1748027086)) + test(lg(-1284021361, 241), lg(-1284021361, 241), lg(13275221, -3818882)) + test(lg(1499414278, 26), lg(1499414278, 26), lg(570654893, -17498947)) + test(lg(-368610421, 5074), lg(-368610421, 5074), lg(685701351, 31070898)) + test(lg(1200134796, 70), lg(1200134796, 70), lg(1230376618, -2490370)) + test(lg(1537764087, 64483), lg(1537764087, 64483), lg(-1252591472, 66761881)) + test(lg(-1981129198, 15), lg(-1981129198, 15), lg(1937978150, 8201544)) + test(lg(32422964, 200), lg(32422964, 200), lg(2051327691, -20319622)) + test(lg(1404616230, 30), lg(1404616230, 30), lg(-748420073, -120320053)) + test(lg(-1860381107, 38), lg(-1860381107, 38), lg(392948122, 60098039)) + test(lg(1050519262, 106431), lg(1050519262, 106431), lg(361773491, -6329760)) + test(lg(460136491, 1681770), lg(460136491, 1681770), lg(1399049044, 759923035)) + test(lg(2065599344, 11089), lg(2065599344, 11089), lg(-465681057, 3484544)) + test(lg(1849358428, 418531), lg(1849358428, 418531), lg(1023666326, 3435570)) + test(lg(1292603836, 80), lg(1292603836, 80), lg(-1114872574, 250120091)) + test(lg(1456627133, 194844), lg(1456627133, 194844), lg(-1256385160, 59427917)) + test(lg(-568179858, 160), lg(-568179858, 160), lg(1142846538, 154324747)) + test(lg(-2133580755, 203337), lg(-2133580755, 203337), lg(111334842, 12695612)) + test(lg(1961218705, 6687), lg(1961218705, 6687), lg(-245612957, 134017780)) + test(lg(335350966, 55096), lg(335350966, 55096), lg(-1815119598, -120983980)) + test(lg(-767561503, 211), lg(-767561503, 211), lg(554589640, -7873602)) + test(lg(1476687067, 3767), lg(1476687067, 3767), lg(552659809, -753378142)) + test(lg(-1107393223, 30), lg(-1107393223, 30), lg(-78383575, -52663801)) + test(lg(607313614, 2), lg(607313614, 2), lg(-234099925, 59184919)) + test(lg(-1542671184, 616882), lg(-1542671184, 616882), lg(1370026838, -45628731)) + test(lg(525616384, 1001), lg(525616384, 1001), lg(1995646126, -11226360)) + test(lg(2109958916, 21549), lg(2109958916, 21549), lg(-419960245, -115959896)) + test(lg(-450913111, 32140), lg(-450913111, 32140), lg(-99267096, -3640047)) + test(lg(1515870052, 198), lg(1515870052, 198), lg(1415757861, -110282301)) + test(lg(124639649, 865615), lg(124639649, 865615), lg(-1354782388, 2569606)) + test(lg(557119825, 7205), lg(557119825, 7205), lg(683150209, -15864187)) + test(lg(992846513, 1385110), lg(992846513, 1385110), lg(1578961851, -8380578)) + test(lg(1081385155, 4176), lg(1081385155, 4176), lg(1892231070, 31130825)) + test(lg(-738492748, 8), lg(-738492748, 8), lg(-431212066, 687916944)) + test(lg(-1448153936, 8101), lg(-1448153936, 8101), lg(-584523654, -4814205)) + test(lg(-713251055, 243), lg(-713251055, 243), lg(261411225, 31444708)) + test(lg(881178812, 47057), lg(881178812, 47057), lg(823893049, -5940358)) + test(lg(-506817388, 0), lg(-506817388, 0), lg(-465610822, 10559551)) + test(lg(-420315839, 112832), lg(-420315839, 112832), lg(-686319219, -666166549)) + + // big, int32 + test(lg(-3, -1), lg(-412174169, -319069709), lg(-6, -1)) + test(lg(464005, 0), lg(1634601702, 814446468), lg(825883, 0)) + test(lg(34559370, 0), lg(-1005992901, 2694218), lg(108493743, 0)) + test(lg(-286379, -1), lg(1534700309, -630528658), lg(-506616, -1)) + test(lg(-62, -1), lg(-456613426, -23298167), lg(-206, -1)) + test(lg(386945695, 0), lg(857770611, 2618490), lg(1225551197, 0)) + test(lg(270232, 0), lg(2127943654, 2768088), lg(-291653, -1)) + test(lg(277129, 0), lg(1085973072, 3470797), lg(-29714535, -1)) + test(lg(15, 0), lg(1536124828, 1268901218), lg(-121, -1)) + test(lg(1, 0), lg(371220141, 34588968), lg(2, 0)) + test(lg(46669, 0), lg(-1712997009, 187259899), lg(129274, 0)) + test(lg(-1508, -1), lg(586579000, -243530833), lg(-31235, -1)) + test(lg(0, 0), lg(1745775262, -400161972), lg(-1, -1)) + test(lg(-1680, -1), lg(-1564631310, -56487209), lg(2626, 0)) + test(lg(53, 0), lg(-1848745069, 11533547), lg(59, 0)) + test(lg(-1699972, -1), lg(-1415791920, -26215621), lg(-2142359, -1)) + test(lg(-200041, -1), lg(-481609933, -25891343), lg(483607, 0)) + test(lg(-13123232, -1), lg(-889674017, -4084771), lg(428648085, 0)) + test(lg(0, 0), lg(1587465684, -367383975), lg(7, 0)) + test(lg(-4528, -1), lg(811562260, -335104547), lg(5502, 0)) + test(lg(-71, -1), lg(2107357891, -10075787), lg(110, 0)) + test(lg(0, 0), lg(-1356326655, 5174156), lg(-1, -1)) + test(lg(7872112, 0), lg(-1794856776, 3059124), lg(-29413816, -1)) + test(lg(-37, -1), lg(-1118254374, -3629384), lg(-85, -1)) + test(lg(14227, 0), lg(288539563, 70814306), lg(-14561, -1)) + test(lg(-49, -1), lg(-719069745, -128562664), lg(-256, -1)) + test(lg(6101, 0), lg(1530955727, 15829469), lg(195494, 0)) + test(lg(-6, -1), lg(2144004402, -5408490), lg(11, 0)) + test(lg(-137624717, -1), lg(-1766192560, -17443468), lg(-168087095, -1)) + test(lg(-3592, -1), lg(-524619138, -371121095), lg(4765, 0)) + test(lg(4335, 0), lg(-1960083221, 176122524), lg(-5564, -1)) + test(lg(-271754, -1), lg(1528631102, -597885631), lg(-413908, -1)) + test(lg(-361112, -1), lg(-1513123614, -30582360), lg(-496311, -1)) + test(lg(-4, -1), lg(-1975522255, -46421733), lg(29, 0)) + test(lg(414436, 0), lg(-1715879325, 3072313), lg(438221, 0)) + test(lg(0, 0), lg(-1321015849, -300384564), lg(1, 0)) + test(lg(-454, -1), lg(-1088390706, -277354665), lg(-1237, -1)) + test(lg(586891857, 0), lg(-1012773943, 223943652), lg(707359548, 0)) + test(lg(2, 0), lg(1097288344, 26740237), lg(-3, -1)) + test(lg(-24053960, -1), lg(-1121404205, -87484234), lg(80229261, 0)) + test(lg(-79944815, -1), lg(-1503637931, -163703901), lg(-983334452, -1)) + test(lg(2600110, 0), lg(2012820970, 445991475), lg(1035472980, 0)) + test(lg(74, 0), lg(2015362538, 2985510), lg(-148, -1)) + test(lg(0, 0), lg(1764134228, 50881407), lg(-1, -1)) + test(lg(106, 0), lg(-523555853, 77167937), lg(-563, -1)) + test(lg(0, 0), lg(1531888651, -2389306), lg(1, 0)) + test(lg(659, 0), lg(-181277952, 32599207), lg(-729, -1)) + test(lg(968, 0), lg(223126732, 88838488), lg(13378, 0)) + test(lg(920991, 0), lg(670834629, 46037187), lg(922370, 0)) + test(lg(2462152, 0), lg(1098978850, 6541822), lg(-8405198, -1)) + + // big, int53 + test(lg(1057995305, 4748), lg(2008672965, 41566313), lg(313991275, 18390)) + test(lg(-1074209653, 18), lg(1922552561, 28139870), lg(-2083633557, 19)) + test(lg(1480601143, -11310), lg(843627074, -173776705), lg(1451117493, 14364)) + test(lg(-691687452, -38), lg(204865470, -6692402), lg(-645190286, 413)) + test(lg(-1218791457, -31), lg(952830559, -214594684), lg(-1778162360, 378)) + test(lg(-281609960, -1292), lg(1673740333, -69274846), lg(-1549261605, 2390)) + test(lg(-860426348, 1), lg(-1276804811, 367022678), lg(-678111623, 11)) + test(lg(-1244563205, -1264), lg(-1331527548, -33013551), lg(-1975438267, 2961)) + test(lg(-935830326, 135167), lg(1067523314, 72606174), lg(-1716982106, 255179)) + test(lg(-2025081444, -42140), lg(-937134490, -32649070), lg(-804857990, 57507)) + test(lg(85696931, 194), lg(108363299, 1224097478), lg(1137551776, 281)) + test(lg(-385517902, -5258), lg(-1965834834, -11053948), lg(-942300324, 6487)) + test(lg(-755355475, 2268), lg(-3151939, 171473802), lg(-2071379940, 3914)) + test(lg(-676865399, -663), lg(1465781759, -970108425), lg(-1251607207, 3003)) + test(lg(2042443783, -22321), lg(919308511, -1689158617), lg(658566728, 36406)) + test(lg(-903837593, 31415), lg(-418485001, 1000432592), lg(-1653953022, 31957)) + test(lg(496274972, -48207), lg(-880302655, -14116770), lg(913871933, 118223)) + test(lg(1210119082, -104892), lg(-525597278, -3790314), lg(2133284776, 127083)) + test(lg(473810731, -5), lg(-393124913, -28106221), lg(958070140, 159)) + test(lg(-1912903061, 25777), lg(6929245, 2749730), lg(1462129294, 43237)) + test(lg(1099532724, -19), lg(708024745, -15568245), lg(1288198049, 56)) + test(lg(920504149, 6836), lg(487601139, 13603229), lg(723875593, 45021)) + test(lg(1778080723, 29), lg(-2070321133, 115478389), lg(-1799479616, 75)) + test(lg(-720480381, 2735), lg(-307180735, 3049800), lg(1043781053, 3319)) + test(lg(1473972065, -1), lg(-1073877839, -6538577), lg(-1408649838, 0)) + test(lg(-1389255096, -200), lg(-1892822171, -1698321438), lg(96164237, 514)) + test(lg(857386403, 29656), lg(-674980011, 2764943), lg(-445529419, 65125)) + test(lg(-419043446, -22164), lg(2003347800, -46928389), lg(368897711, 128159)) + test(lg(-1599543668, -6569), lg(-1929871429, -241628283), lg(202358381, 7645)) + test(lg(581185953, 1), lg(419719197, 661188517), lg(2112360098, 1)) + test(lg(-1880704128, 171407), lg(1092830824, 1600823129), lg(-1827462760, 172800)) + test(lg(1210159480, -13), lg(-836779994, -27475595), lg(-417527207, 16)) + test(lg(807846066, 1), lg(-1759597755, 9157722), lg(-987185779, 1)) + test(lg(949995673, 1), lg(-1097231525, 20092165), lg(1106421078, 1)) + test(lg(-712450167, 7), lg(390678483, 3835040), lg(1221250555, 14)) + test(lg(1129531033, -4), lg(-284334384, -18425278), lg(-1111448031, 6)) + test(lg(2094997010, 3022), lg(-233961390, 53260849), lg(-613558136, 3663)) + test(lg(-496446555, 540290), lg(-3383211, 8039036), lg(-1668680584, 749874)) + test(lg(1280740603, -9472), lg(804358887, -189240235), lg(179665302, 12347)) + test(lg(2127427912, 6), lg(208769744, 280071599), lg(-325433064, 14)) + test(lg(-722136158, -1), lg(-1527711901, -51564742), lg(-1019145455, 0)) + test(lg(-1603688570, -2), lg(-159182038, -2145592347), lg(-483720705, 15)) + test(lg(-256578646, 177817), lg(1059926378, 477886379), lg(924988992, 543468)) + test(lg(1286157765, 80885), lg(-1800046387, 119696078), lg(436524799, 94037)) + test(lg(251450065, 19154), lg(-822280387, 44882065), lg(-940828508, 22947)) + test(lg(1310986115, 209), lg(1465101985, 269803551), lg(-1953360551, 334)) + test(lg(1436855439, -5), lg(-567675197, -8838663), lg(1903221047, 6)) + test(lg(296887390, -17), lg(689376065, -22622471), lg(1534988921, 63)) + test(lg(1577958450, -39), lg(-2017356377, -57717216), lg(-1390284125, 42)) + test(lg(661387374, 344542), lg(-128715878, 982583003), lg(2004099318, 988167)) + + // big, big + test(lg(-320078007, 205603273), lg(-320078007, 205603273), lg(2020227799, -360928021)) + test(lg(408769930, -2221999), lg(-800732960, -371808530), lg(744251542, -11199592)) + test(lg(1575977183, -2441606), lg(-56774921, -32434115), lg(1413374280, -2726592)) + test(lg(-1897285736, 18894093), lg(1667937500, 228622683), lg(-243248020, 69909529)) + test(lg(-1333815518, 2097776), lg(-1333815518, 2097776), lg(-1750106076, 18608702)) + test(lg(-789967161, -4640836), lg(-162800691, -117885498), lg(-709007774, 8711127)) + test(lg(-1909427145, -2824029), lg(-1909427145, -2824029), lg(2028036056, -660713154)) + test(lg(14077923, 63046905), lg(14077923, 63046905), lg(-688765214, 375445962)) + test(lg(272760540, 19525127), lg(272760540, 19525127), lg(-396955631, 848435537)) + test(lg(-600396362, 406643261), lg(-600396362, 406643261), lg(-1533973181, 491661310)) + test(lg(1801834226, 200420454), lg(1801834226, 200420454), lg(-1889418050, -328758068)) + test(lg(361053022, 54544094), lg(1170836790, 510289402), lg(202445942, 113936327)) + test(lg(1369752396, -3152427), lg(-378923036, -1036580478), lg(905093048, 5526353)) + test(lg(1458911735, 21273958), lg(-2137034353, 1455139814), lg(1665353214, 27574343)) + test(lg(-1350216191, -3821167), lg(-1350216191, -3821167), lg(-1333339390, -4746360)) + test(lg(1166542449, -1370750), lg(-1289646201, -5193401), lg(1838778646, -3822651)) + test(lg(301867174, 5185218), lg(301867174, 5185218), lg(157012848, -15464466)) + test(lg(512572633, 48335882), lg(467711834, 155069651), lg(-44860799, 106733768)) + test(lg(1624269582, 11007763), lg(1624269582, 11007763), lg(-158694824, -491219717)) + test(lg(-1015519521, -163989350), lg(-1015519521, -163989350), lg(1652525166, 530116116)) + test(lg(-2127450406, -89864400), lg(2001612518, -452587333), lg(1115217917, 90680733)) + test(lg(-761803769, -6085789), lg(1039524645, -86121932), lg(1131434363, 13339357)) + test(lg(-1922291990, 6439098), lg(-1922291990, 6439098), lg(-1083372307, -20634200)) + test(lg(1508171882, 126457), lg(1408756974, 235847122), lg(-1813277898, -9066180)) + test(lg(-496706473, -2657930), lg(1121009342, -1533788016), lg(-1724900447, -5821788)) + test(lg(-1626361260, -113469353), lg(-1626361260, -113469353), lg(1216987736, -817139415)) + test(lg(-433139577, -182483493), lg(-433139577, -182483493), lg(1019490766, -595625160)) + test(lg(-1118452074, 1653764), lg(793542905, 198273616), lg(-82759497, -2621599)) + test(lg(-1199275184, 1262327), lg(425605214, 249789222), lg(392156278, 6716943)) + test(lg(213473729, 11660532), lg(213473729, 11660532), lg(-547058106, 894811834)) + test(lg(-1550227391, 2847368), lg(-1550227391, 2847368), lg(-1996700003, 689370771)) + test(lg(-1014778289, -3747071), lg(-144234222, -54239417), lg(-1102770075, -7213193)) + test(lg(524484467, 15124083), lg(524484467, 15124083), lg(-1101379967, -39968226)) + test(lg(-919997306, 2085072), lg(314758022, 5390195), lg(-1234755328, -3305123)) + test(lg(580679232, -10426812), lg(580679232, -10426812), lg(-1964013803, -1738507605)) + test(lg(225658926, -4189255), lg(1670083752, -254253193), lg(722212413, -125031969)) + test(lg(-495749254, -1833207), lg(-1744001445, -5443198), lg(1248252191, 3609991)) + test(lg(-1481543825, 608612), lg(-1786439869, 137339199), lg(1821158508, 2909161)) + test(lg(1026706952, -6267613), lg(1273422584, -284542935), lg(1626032463, -17392208)) + test(lg(-855876173, -4928311), lg(-513801887, -32580141), lg(-342074286, 27651829)) + test(lg(-1027906958, 55543678), lg(-1027906958, 55543678), lg(-1936394792, 928937151)) + test(lg(-1793811005, -17787029), lg(251585986, -50474191), lg(-2045396991, 32687162)) + test(lg(-356034186, -2235041), lg(66679938, -917589429), lg(2124767660, -3454168)) + test(lg(-924611099, -76507846), lg(-599564184, -209788131), lg(-325046915, 133280284)) + test(lg(838338995, -12983151), lg(838338995, -12983151), lg(-842402530, 19411056)) + test(lg(747658762, 18528439), lg(1444498155, 520850879), lg(851271837, 23920116)) + test(lg(-2028924578, -3124146), lg(2096765386, -117024114), lg(-1726450785, -5694999)) + test(lg(2056903464, -4954201), lg(-425905039, -180148939), lg(-1397064581, -15926795)) + test(lg(-2055992988, 596420), lg(-920215872, 219325473), lg(1357686103, 54682263)) + test(lg(1279110660, -10784541), lg(1279110660, -10784541), lg(278869448, 758126792)) + } } object LongTest { From deec9719033f4ce21331eeca864182f17898831b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 7 Feb 2018 17:19:50 +0100 Subject: [PATCH 0654/2665] Alternative implementation of `Long`s on top of ES `BigInt`s. This commit introduces a new way to emit `Long`s in the emitter, using the upcoming ECMAScript `BigInt`s. Although they are arbitrary precision integers, rather than 64-bits, they are designed to allow implementations of 64-bit integers on top of them. The alternative implementation can be selected with the option `allowBigIntsForLongs` of the `ESFeatures`. As of this writing, only a very recent V8 can run the produced .js files, and only with `--harmony-bigint`. Therefore, the present commit does not any automated tests to the CI, which makes this feature even more experimental. The implementation can be locally tested with https://github.com/sjrd/scala-js-env-d8, using a locally built d8 (the V8 debug shell). The general encoding is straightforward: `Long`s values are encoded as `bigint`s whose value fits in the signed 64-bit integer range. The operations translate as follows: * `a + b` -> `BigInt.asIntN(64, a + b)` (similar for most operations) * `a << b` -> `BigInt.asIntN(64, a << BigInt(b & 63))` (similar for `>>`) * `a >>> b` -> `BigInt.asIntN(64, BigInt.asUintN(64, a) >> BigInt(b & 63))` (because `BigInt` does not have logical shift right) --- .../closure/ClosureLinkerBackend.scala | 4 + linker/scalajsenv.js | 103 +++++++++- .../scala/org/scalajs/linker/ESFeatures.scala | 30 ++- .../linker/backend/emitter/ClassEmitter.scala | 17 +- .../linker/backend/emitter/CoreJSLibs.scala | 3 + .../linker/backend/emitter/Emitter.scala | 16 +- .../backend/emitter/FunctionEmitter.scala | 189 +++++++++++++++--- .../linker/backend/emitter/JSGen.scala | 14 +- .../linker/backend/javascript/Printers.scala | 10 + .../linker/backend/javascript/Trees.scala | 3 + .../frontend/optimizer/OptimizerCore.scala | 68 ++++--- 11 files changed, 368 insertions(+), 89 deletions(-) diff --git a/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala index 2763f7b671..6079266d60 100644 --- a/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala @@ -40,6 +40,10 @@ final class ClosureLinkerBackend(config: LinkerBackend.Config) s"Cannot use features $esFeatures with the Closure Compiler" + "because they contain ECMAScript 2015 features") + require(!esFeatures.allowBigIntsForLongs, + s"Cannot use features $esFeatures with the Closure Compiler" + + "because they allow to use BigInts") + private[this] val emitter = { new Emitter(config.commonConfig) .withOptimizeBracketSelects(false) diff --git a/linker/scalajsenv.js b/linker/scalajsenv.js index 0b8c6ec571..3709a121da 100644 --- a/linker/scalajsenv.js +++ b/linker/scalajsenv.js @@ -150,8 +150,10 @@ const $clz32 = Math["clz32"] || (function(i) { }); //!endif +//!if longImpl == RuntimeLong // Cached instance of RuntimeLong for 0L let $L0; +//!endif // identityHashCode support let $lastIDHash = 0; // last value attributed to an id hash code @@ -309,7 +311,11 @@ function $objectGetClass(instance) { default: if (instance === null) return instance.getClass__jl_Class(); +//!if longImpl == RuntimeLong else if ($is_sjsr_RuntimeLong(instance)) +//!else + else if ($isLong(instance)) +//!endif return $d_jl_Long.getClassOf(); else if ($isChar(instance)) return $d_jl_Character.getClassOf(); @@ -361,6 +367,10 @@ function $dp_equals__O__Z(instance, rhs) { return instance.equals__O__Z(rhs); else if (typeof instance === "number") return $f_jl_Double__equals__O__Z(instance, rhs); +//!if longImpl == BigInt + else if ($isLong(instance)) + return $f_jl_Long__equals__O__Z(instance, rhs); +//!endif else if ($isChar(instance)) return $f_jl_Character__equals__O__Z(instance, rhs); else @@ -380,6 +390,10 @@ function $dp_hashCode__I(instance) { default: if ($isScalaJSObject(instance) || instance === null) return instance.hashCode__I(); +//!if longImpl == BigInt + else if ($isLong(instance)) + return $f_jl_Long__hashCode__I(instance); +//!endif else if ($isChar(instance)) return $f_jl_Character__hashCode__I(instance); else @@ -398,6 +412,10 @@ function $dp_compareTo__O__I(instance, rhs) { default: if ($isChar(instance)) return $f_jl_Character__compareTo__O__I(instance, rhs); +//!if longImpl == BigInt + else if ($isLong(instance)) + return $f_jl_Long__compareTo__O__I(instance, rhs); +//!endif else return instance.compareTo__O__I(rhs); } @@ -427,36 +445,60 @@ function $dp_subSequence__I__I__jl_CharSequence(instance, start, end) { function $dp_byteValue__B(instance) { if (typeof instance === "number") return $f_jl_Double__byteValue__B(instance); +//!if longImpl == BigInt + else if ($isLong(instance)) + return $f_jl_Long__byteValue__B(instance); +//!endif else return instance.byteValue__B(); }; function $dp_shortValue__S(instance) { if (typeof instance === "number") return $f_jl_Double__shortValue__S(instance); +//!if longImpl == BigInt + else if ($isLong(instance)) + return $f_jl_Long__shortValue__S(instance); +//!endif else return instance.shortValue__S(); }; function $dp_intValue__I(instance) { if (typeof instance === "number") return $f_jl_Double__intValue__I(instance); +//!if longImpl == BigInt + else if ($isLong(instance)) + return $f_jl_Long__intValue__I(instance); +//!endif else return instance.intValue__I(); }; function $dp_longValue__J(instance) { if (typeof instance === "number") return $f_jl_Double__longValue__J(instance); +//!if longImpl == BigInt + else if ($isLong(instance)) + return $f_jl_Long__longValue__J(instance); +//!endif else return instance.longValue__J(); }; function $dp_floatValue__F(instance) { if (typeof instance === "number") return $f_jl_Double__floatValue__F(instance); +//!if longImpl == BigInt + else if ($isLong(instance)) + return $f_jl_Long__floatValue__F(instance); +//!endif else return instance.floatValue__F(); }; function $dp_doubleValue__D(instance) { if (typeof instance === "number") return $f_jl_Double__doubleValue__D(instance); +//!if longImpl == BigInt + else if ($isLong(instance)) + return $f_jl_Long__doubleValue__D(instance); +//!endif else return instance.doubleValue__D(); }; @@ -465,6 +507,25 @@ function $doubleToInt(x) { return (x > 2147483647) ? (2147483647) : ((x < -2147483648) ? -2147483648 : (x | 0)); }; +//!if longImpl == BigInt +function $doubleToLong(x) { + /* BigInt(x) refuses to work if x is not a "safe integer", i.e., a number + * with an integral x, whose absolute x is < 2^53. Therefore, we basically + * use the same algorithm as in RuntimeLong.fromDouble. + */ + if (x < -9223372036854775808.0) { // -2^63 + return -9223372036854775808n; + } else if (x >= 9223372036854775808.0) { // 2^63 + return 9223372036854775807n; + } else { + const lo = x | 0; + const rawHi = (x / 4294967296.0) | 0; // 2^32 + const hi = (x < 0 && lo != 0) ? (rawHi - 1) | 0 : rawHi; + return (BigInt(hi) << 32n) | BigInt(lo >>> 0); + } +}; +//!endif + /** Instantiates a JS object with variadic arguments to the constructor. */ function $newJSObjectWithVarargs(ctor, args) { // This basically emulates the ECMAScript specification for 'new'. @@ -550,7 +611,7 @@ const $systemIdentityHashCode = //!endif (function(obj) { switch (typeof obj) { - case "string": case "number": case "boolean": case "undefined": + case "string": case "number": case "bigint": case "boolean": case "undefined": return $dp_hashCode__I(obj); default: if (obj === null) { @@ -569,7 +630,7 @@ const $systemIdentityHashCode = }) : (function(obj) { switch (typeof obj) { - case "string": case "number": case "boolean": case "undefined": + case "string": case "number": case "bigint": case "boolean": case "undefined": return $dp_hashCode__I(obj); default: if ($isScalaJSObject(obj)) { @@ -611,6 +672,12 @@ function $isInt(v) { return typeof v === "number" && (v | 0) === v && 1/v !== 1/-0; }; +//!if longImpl == BigInt +function $isLong(v) { + return typeof v === "bigint" && BigInt.asIntN(64, v) === v; +}; +//!endif + function $isFloat(v) { //!if floats == Strict return typeof v === "number" && (v !== v || $fround(v) === v); @@ -662,6 +729,15 @@ function $asInt(v) { $throwClassCastException(v, "java.lang.Integer"); }; +//!if longImpl == BigInt +function $asLong(v) { + if ($isLong(v) || v === null) + return v; + else + $throwClassCastException(v, "java.lang.Long"); +}; +//!endif + function $asFloat(v) { if ($isFloat(v) || v === null) return v; @@ -703,7 +779,11 @@ function $uI(value) { return $asInt(value) | 0; }; function $uJ(value) { +//!if longImpl == BigInt + return null === value ? 0n : $asLong(value); +//!else return null === value ? $L0 : $as_sjsr_RuntimeLong(value); +//!endif }; function $uF(value) { /* Here, it is fine to use + instead of fround, because asFloat already @@ -719,7 +799,11 @@ function $uC(value) { return null === value ? 0 : value.c; } function $uJ(value) { +//!if longImpl == BigInt + return null === value ? 0n : value; +//!else return null === value ? $L0 : value; +//!endif }; //!endif @@ -850,12 +934,15 @@ initArray( componentData) { // The constructor - const componentZero0 = componentData.zero; - +//!if longImpl == BigInt + const componentZero = componentData.zero; +//!else // The zero for the Long runtime representation // is a special case here, since the class has not // been defined yet when this constructor is called. + const componentZero0 = componentData.zero; const componentZero = (componentZero0 == "longZero") ? $L0 : componentZero0; +//!endif //!if useECMAScript2015 == false /** @constructor */ @@ -1011,7 +1098,11 @@ $TypeData.prototype["isAssignableFrom"] = function(that) { that === $d_jl_Double) thatFakeInstance = 0; else if (that === $d_jl_Long) +//!if longImpl == BigInt + thatFakeInstance = 0n; +//!else thatFakeInstance = $L0; +//!endif else if (that === $d_sr_BoxedUnit) thatFakeInstance = void 0; else @@ -1058,7 +1149,11 @@ const $d_C = new $TypeData().initPrim(0, "C", "char"); const $d_B = new $TypeData().initPrim(0, "B", "byte"); const $d_S = new $TypeData().initPrim(0, "S", "short"); const $d_I = new $TypeData().initPrim(0, "I", "int"); +//!if longImpl == BigInt +const $d_J = new $TypeData().initPrim(0n, "J", "long"); +//!else const $d_J = new $TypeData().initPrim("longZero", "J", "long"); +//!endif const $d_F = new $TypeData().initPrim(0.0, "F", "float"); const $d_D = new $TypeData().initPrim(0.0, "D", "double"); diff --git a/linker/shared/src/main/scala/org/scalajs/linker/ESFeatures.scala b/linker/shared/src/main/scala/org/scalajs/linker/ESFeatures.scala index 3c92eddd0d..13bd0ba3af 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/ESFeatures.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/ESFeatures.scala @@ -26,22 +26,31 @@ final class ESFeatures private ( /** Whether to use ECMAScript 2015 features, such as classes and arrow * functions. */ - val useECMAScript2015: Boolean + val useECMAScript2015: Boolean, + /** EXPERIMENTAL: Whether to allow using ECMAScript `BigInt`s to implement + * `Long`s. + */ + val allowBigIntsForLongs: Boolean ) { import ESFeatures._ private def this() = { this( - useECMAScript2015 = false + useECMAScript2015 = false, + allowBigIntsForLongs = false ) } def withUseECMAScript2015(useECMAScript2015: Boolean): ESFeatures = copy(useECMAScript2015 = useECMAScript2015) + def withAllowBigIntsForLongs(allowBigIntsForLongs: Boolean): ESFeatures = + copy(allowBigIntsForLongs = allowBigIntsForLongs) + override def equals(that: Any): Boolean = that match { case that: ESFeatures => - this.useECMAScript2015 == that.useECMAScript2015 + this.useECMAScript2015 == that.useECMAScript2015 && + this.allowBigIntsForLongs == that.allowBigIntsForLongs case _ => false } @@ -49,21 +58,25 @@ final class ESFeatures private ( override def hashCode(): Int = { import scala.util.hashing.MurmurHash3._ var acc = HashSeed - acc = mixLast(acc, useECMAScript2015.##) - finalizeHash(acc, 1) + acc = mix(acc, useECMAScript2015.##) + acc = mixLast(acc, allowBigIntsForLongs.##) + finalizeHash(acc, 2) } override def toString(): String = { s"""ESFeatures( - | useECMAScript2015 = $useECMAScript2015 + | useECMAScript2015 = $useECMAScript2015, + | allowBigIntsForLongs = $allowBigIntsForLongs |)""".stripMargin } private def copy( - useECMAScript2015: Boolean = this.useECMAScript2015 + useECMAScript2015: Boolean = this.useECMAScript2015, + allowBigIntsForLongs: Boolean = this.allowBigIntsForLongs ): ESFeatures = { new ESFeatures( - useECMAScript2015 = useECMAScript2015 + useECMAScript2015 = useECMAScript2015, + allowBigIntsForLongs = allowBigIntsForLongs ) } } @@ -75,6 +88,7 @@ object ESFeatures { /** Default configuration of ECMAScript features. * * - `useECMAScript2015`: false + * - `allowBigIntsForLongs`: false */ val Defaults: ESFeatures = new ESFeatures() } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala index 9efa48cbda..b8683b6b72 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala @@ -702,15 +702,18 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { obj DOT "$classData" DOT "ancestors") } + def typeOfTest(typeString: String): js.Tree = + js.UnaryOp(JSUnaryOp.typeof, obj) === js.StringLiteral(typeString) + if (isAncestorOfString) - test = test || ( - js.UnaryOp(JSUnaryOp.typeof, obj) === js.StringLiteral("string")) - if (isAncestorOfHijackedNumberClass) - test = test || ( - js.UnaryOp(JSUnaryOp.typeof, obj) === js.StringLiteral("number")) + test = test || typeOfTest("string") + if (isAncestorOfHijackedNumberClass) { + test = test || typeOfTest("number") + if (useBigIntForLongs) + test = test || genCallHelper("isLong", obj) + } if (isAncestorOfBoxedBooleanClass) - test = test || ( - js.UnaryOp(JSUnaryOp.typeof, obj) === js.StringLiteral("boolean")) + test = test || typeOfTest("boolean") if (isAncestorOfBoxedCharacterClass) test = test || genCallHelper("isChar", obj) if (isAncestorOfBoxedUnitClass) diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLibs.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLibs.scala index bcc9c734b3..dc45f32484 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLibs.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLibs.scala @@ -66,6 +66,9 @@ private[emitter] object CoreJSLibs { esFeatures.useECMAScript2015.toString() case "moduleKind" => moduleKind.toString() + case "longImpl" => + if (esFeatures.allowBigIntsForLongs) "BigInt" + else "RuntimeLong" } val originalLines = ScalaJSEnvLines diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala index 5bdb501047..dc69de556e 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala @@ -167,7 +167,8 @@ final class Emitter private (config: CommonPhaseConfig, for (generatedClass <- generatedClasses) emitJSTrees(generatedClass.main) - builder.addJSTree(emitInitializeL0()) + if (!jsGen.useBigIntForLongs) + builder.addJSTree(emitInitializeL0()) for (generatedClass <- generatedClasses) emitJSTrees(generatedClass.staticFields) @@ -674,11 +675,14 @@ private object Emitter { instantiateClass("jl_Class", "init___O"), - instanceTests(LongImpl.RuntimeLongClass), - instantiateClass(LongImpl.RuntimeLongClass, LongImpl.AllConstructors), - callMethods(LongImpl.RuntimeLongClass, LongImpl.AllMethods), - - callOnModule(LongImpl.RuntimeLongModuleClass, LongImpl.AllModuleMethods) + cond(!coreSpec.esFeatures.allowBigIntsForLongs) { + multiple( + instanceTests(LongImpl.RuntimeLongClass), + instantiateClass(LongImpl.RuntimeLongClass, LongImpl.AllConstructors), + callMethods(LongImpl.RuntimeLongClass, LongImpl.AllMethods), + callOnModule(LongImpl.RuntimeLongModuleClass, LongImpl.AllModuleMethods) + ) + } ) } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala index b4cceb3045..67e4f26ae0 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala @@ -1920,6 +1920,16 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { def or0(tree: js.Tree): js.Tree = js.BinaryOp(JSBinaryOp.|, tree, js.IntLiteral(0)) + def bigIntShiftRhs(tree: js.Tree): js.Tree = { + tree match { + case js.IntLiteral(v) => + js.BigIntLiteral(v & 63) + case _ => + js.Apply(genGlobalVarRef("BigInt"), + List(js.BinaryOp(JSBinaryOp.&, tree, js.IntLiteral(63)))) + } + } + val baseResult = tree match { // Control flow constructs @@ -2084,7 +2094,10 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { FloatToDouble => newLhs case IntToLong => - genLongModuleApply(LongImpl.fromInt, newLhs) + if (useBigIntForLongs) + js.Apply(genGlobalVarRef("BigInt"), List(newLhs)) + else + genLongModuleApply(LongImpl.fromInt, newLhs) // Narrowing conversions case IntToChar => @@ -2098,15 +2111,26 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { js.BinaryOp(JSBinaryOp.<<, newLhs, js.IntLiteral(16)), js.IntLiteral(16)) case LongToInt => - genLongMethodApply(newLhs, LongImpl.toInt) + if (useBigIntForLongs) + js.Apply(genGlobalVarRef("Number"), List(wrapBigInt32(newLhs))) + else + genLongMethodApply(newLhs, LongImpl.toInt) case DoubleToInt => genCallHelper("doubleToInt", newLhs) case DoubleToFloat => genFround(newLhs) // Long <-> Double (neither widening nor narrowing) - case LongToDouble => genLongMethodApply(newLhs, LongImpl.toDouble) - case DoubleToLong => genLongModuleApply(LongImpl.fromDouble, newLhs) + case LongToDouble => + if (useBigIntForLongs) + js.Apply(genGlobalVarRef("Number"), List(newLhs)) + else + genLongMethodApply(newLhs, LongImpl.toDouble) + case DoubleToLong => + if (useBigIntForLongs) + genCallHelper("doubleToLong", newLhs) + else + genLongModuleApply(LongImpl.fromDouble, newLhs) } case BinaryOp(op, lhs, rhs) => @@ -2154,33 +2178,109 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case Int_> => js.BinaryOp(JSBinaryOp.>, newLhs, newRhs) case Int_>= => js.BinaryOp(JSBinaryOp.>=, newLhs, newRhs) - case Long_+ => genLongMethodApply(newLhs, LongImpl.+, newRhs) + case Long_+ => + if (useBigIntForLongs) + wrapBigInt64(js.BinaryOp(JSBinaryOp.+, newLhs, newRhs)) + else + genLongMethodApply(newLhs, LongImpl.+, newRhs) case Long_- => lhs match { - case LongLiteral(0L) => genLongMethodApply(newRhs, LongImpl.UNARY_-) - case _ => genLongMethodApply(newLhs, LongImpl.-, newRhs) + case LongLiteral(0L) => + if (useBigIntForLongs) + wrapBigInt64(js.UnaryOp(JSUnaryOp.-, newRhs)) + else + genLongMethodApply(newRhs, LongImpl.UNARY_-) + case _ => + if (useBigIntForLongs) + wrapBigInt64(js.BinaryOp(JSBinaryOp.-, newLhs, newRhs)) + else + genLongMethodApply(newLhs, LongImpl.-, newRhs) } - case Long_* => genLongMethodApply(newLhs, LongImpl.*, newRhs) - case Long_/ => genLongMethodApply(newLhs, LongImpl./, newRhs) - case Long_% => genLongMethodApply(newLhs, LongImpl.%, newRhs) - - case Long_| => genLongMethodApply(newLhs, LongImpl.|, newRhs) - case Long_& => genLongMethodApply(newLhs, LongImpl.&, newRhs) - case Long_^ => + case Long_* => + if (useBigIntForLongs) + wrapBigInt64(js.BinaryOp(JSBinaryOp.*, newLhs, newRhs)) + else + genLongMethodApply(newLhs, LongImpl.*, newRhs) + case Long_/ => + if (useBigIntForLongs) + wrapBigInt64(js.BinaryOp(JSBinaryOp./, newLhs, newRhs)) + else + genLongMethodApply(newLhs, LongImpl./, newRhs) + case Long_% => + if (useBigIntForLongs) + wrapBigInt64(js.BinaryOp(JSBinaryOp.%, newLhs, newRhs)) + else + genLongMethodApply(newLhs, LongImpl.%, newRhs) + + case Long_| => + if (useBigIntForLongs) + wrapBigInt64(js.BinaryOp(JSBinaryOp.|, newLhs, newRhs)) + else + genLongMethodApply(newLhs, LongImpl.|, newRhs) + case Long_& => + if (useBigIntForLongs) + wrapBigInt64(js.BinaryOp(JSBinaryOp.&, newLhs, newRhs)) + else + genLongMethodApply(newLhs, LongImpl.&, newRhs) + case Long_^ => lhs match { - case LongLiteral(-1L) => genLongMethodApply(newRhs, LongImpl.UNARY_~) - case _ => genLongMethodApply(newLhs, LongImpl.^, newRhs) + case LongLiteral(-1L) => + if (useBigIntForLongs) + wrapBigInt64(js.UnaryOp(JSUnaryOp.~, newRhs)) + else + genLongMethodApply(newRhs, LongImpl.UNARY_~) + case _ => + if (useBigIntForLongs) + wrapBigInt64(js.BinaryOp(JSBinaryOp.^, newLhs, newRhs)) + else + genLongMethodApply(newLhs, LongImpl.^, newRhs) } - case Long_<< => genLongMethodApply(newLhs, LongImpl.<<, newRhs) - case Long_>>> => genLongMethodApply(newLhs, LongImpl.>>>, newRhs) - case Long_>> => genLongMethodApply(newLhs, LongImpl.>>, newRhs) - - case Long_== => genLongMethodApply(newLhs, LongImpl.===, newRhs) - case Long_!= => genLongMethodApply(newLhs, LongImpl.!==, newRhs) - case Long_< => genLongMethodApply(newLhs, LongImpl.<, newRhs) - case Long_<= => genLongMethodApply(newLhs, LongImpl.<=, newRhs) - case Long_> => genLongMethodApply(newLhs, LongImpl.>, newRhs) - case Long_>= => genLongMethodApply(newLhs, LongImpl.>=, newRhs) + case Long_<< => + if (useBigIntForLongs) + wrapBigInt64(js.BinaryOp(JSBinaryOp.<<, newLhs, bigIntShiftRhs(newRhs))) + else + genLongMethodApply(newLhs, LongImpl.<<, newRhs) + case Long_>>> => + if (useBigIntForLongs) + wrapBigInt64(js.BinaryOp(JSBinaryOp.>>, wrapBigIntU64(newLhs), bigIntShiftRhs(newRhs))) + else + genLongMethodApply(newLhs, LongImpl.>>>, newRhs) + case Long_>> => + if (useBigIntForLongs) + wrapBigInt64(js.BinaryOp(JSBinaryOp.>>, newLhs, bigIntShiftRhs(newRhs))) + else + genLongMethodApply(newLhs, LongImpl.>>, newRhs) + + case Long_== => + if (useBigIntForLongs) + js.BinaryOp(JSBinaryOp.===, newLhs, newRhs) + else + genLongMethodApply(newLhs, LongImpl.===, newRhs) + case Long_!= => + if (useBigIntForLongs) + js.BinaryOp(JSBinaryOp.!==, newLhs, newRhs) + else + genLongMethodApply(newLhs, LongImpl.!==, newRhs) + case Long_< => + if (useBigIntForLongs) + js.BinaryOp(JSBinaryOp.<, newLhs, newRhs) + else + genLongMethodApply(newLhs, LongImpl.<, newRhs) + case Long_<= => + if (useBigIntForLongs) + js.BinaryOp(JSBinaryOp.<=, newLhs, newRhs) + else + genLongMethodApply(newLhs, LongImpl.<=, newRhs) + case Long_> => + if (useBigIntForLongs) + js.BinaryOp(JSBinaryOp.>, newLhs, newRhs) + else + genLongMethodApply(newLhs, LongImpl.>, newRhs) + case Long_>= => + if (useBigIntForLongs) + js.BinaryOp(JSBinaryOp.>=, newLhs, newRhs) + else + genLongMethodApply(newLhs, LongImpl.>=, newRhs) case Float_+ => genFround(js.BinaryOp(JSBinaryOp.+, newLhs, newRhs)) case Float_- => @@ -2390,9 +2490,13 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case LongLiteral(0L) => genLongZero() case LongLiteral(value) => - val (lo, hi) = LongImpl.extractParts(value) - js.New(encodeClassVar(LongImpl.RuntimeLongClass), - List(js.IntLiteral(lo), js.IntLiteral(hi))) + if (useBigIntForLongs) { + js.BigIntLiteral(value) + } else { + val (lo, hi) = LongImpl.extractParts(value) + js.New(encodeClassVar(LongImpl.RuntimeLongClass), + List(js.IntLiteral(lo), js.IntLiteral(hi))) + } case ClassOf(cls) => js.Apply(js.DotSelect(genClassDataOf(cls), js.Ident("getClassOf")), @@ -2536,6 +2640,12 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { js.Ident(ident.name, ident.originalName)(ident.pos) } + private def genGlobalVarRef(name: String)( + implicit pos: Position): js.VarRef = { + referenceGlobalName(name) + js.VarRef(js.Ident(name)) + } + /* In FunctionEmitter, we must always keep all global var names, not only * dangerous ones. This helper makes it less annoying. */ @@ -2549,6 +2659,27 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { genCallHelper("fround", arg) } + private def wrapBigInt32(tree: js.Tree)(implicit pos: Position): js.Tree = + wrapBigIntN(32, tree) + + private def wrapBigInt64(tree: js.Tree)(implicit pos: Position): js.Tree = + wrapBigIntN(64, tree) + + private def wrapBigIntN(n: Int, tree: js.Tree)( + implicit pos: Position): js.Tree = { + js.Apply(genIdentBracketSelect(genGlobalVarRef("BigInt"), "asIntN"), + List(js.IntLiteral(n), tree)) + } + + private def wrapBigIntU64(tree: js.Tree)(implicit pos: Position): js.Tree = + wrapBigIntUN(64, tree) + + private def wrapBigIntUN(n: Int, tree: js.Tree)( + implicit pos: Position): js.Tree = { + js.Apply(genIdentBracketSelect(genGlobalVarRef("BigInt"), "asUintN"), + List(js.IntLiteral(n), tree)) + } + private def genLongMethodApply(receiver: js.Tree, methodName: String, args: js.Tree*)(implicit pos: Position): js.Tree = { import TreeDSL._ diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/JSGen.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/JSGen.scala index 83eb6bd224..b8d097de56 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/JSGen.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/JSGen.scala @@ -37,6 +37,8 @@ private[emitter] final class JSGen(val semantics: Semantics, val useArrowFunctions = esFeatures.useECMAScript2015 + val useBigIntForLongs = esFeatures.allowBigIntsForLongs + def genZeroOf(tpe: Type)(implicit pos: Position): Tree = { tpe match { case BooleanType => BooleanLiteral(false) @@ -53,8 +55,12 @@ private[emitter] final class JSGen(val semantics: Semantics, } } - def genLongZero()(implicit pos: Position): Tree = - envField("L0") + def genLongZero()(implicit pos: Position): Tree = { + if (useBigIntForLongs) + BigIntLiteral(0L) + else + envField("L0") + } def genLongModuleApply(methodName: String, args: Tree*)( implicit pos: Position): Tree = { @@ -107,7 +113,7 @@ private[emitter] final class JSGen(val semantics: Semantics, typeRef match { case ClassRef(className0) => val className = - if (className0 == BoxedLongClass) LongImpl.RuntimeLongClass + if (className0 == BoxedLongClass && !useBigIntForLongs) LongImpl.RuntimeLongClass else className0 if (HijackedClasses.contains(className) && className != BoxedStringClass) { @@ -119,6 +125,7 @@ private[emitter] final class JSGen(val semantics: Semantics, case BoxedByteClass => genCallHelper("isByte", expr) case BoxedShortClass => genCallHelper("isShort", expr) case BoxedIntegerClass => genCallHelper("isInt", expr) + case BoxedLongClass => genCallHelper("isLong", expr) case BoxedFloatClass => genCallHelper("isFloat", expr) case BoxedDoubleClass => typeof(expr) === "number" } @@ -130,6 +137,7 @@ private[emitter] final class JSGen(val semantics: Semantics, case BoxedByteClass => genCallHelper("asByte", expr) case BoxedShortClass => genCallHelper("asShort", expr) case BoxedIntegerClass => genCallHelper("asInt", expr) + case BoxedLongClass => genCallHelper("asLong", expr) case BoxedFloatClass => genCallHelper("asFloat", expr) case BoxedDoubleClass => genCallHelper("asDouble", expr) } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/Printers.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/Printers.scala index f844192a56..c596feadfd 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/Printers.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/Printers.scala @@ -483,6 +483,16 @@ object Printers { printEscapeJS(value) print('\"') + case BigIntLiteral(value) => + if (value >= 0) { + print(value.toString) + print('n') + } else { + print('(') + print(value.toString) + print("n)") + } + // Atomic expressions case VarRef(ident) => diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/Trees.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/Trees.scala index 2151ad44ad..e4e2612285 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/Trees.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/Trees.scala @@ -212,6 +212,9 @@ object Trees { case class StringLiteral(value: String)( implicit val pos: Position) extends Literal with PropertyName + case class BigIntLiteral(value: BigInt)( + implicit val pos: Position) extends Literal + // Atomic expressions case class VarRef(ident: Ident)(implicit val pos: Position) extends Tree diff --git a/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala b/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala index 8142fef768..a598b41305 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala @@ -103,6 +103,8 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { private var curTrampolineId = 0 + private val useRuntimeLong = !config.coreSpec.esFeatures.allowBigIntsForLongs + /** The record type for inlined `RuntimeLong`. */ private lazy val inlinedRTLongRecordType = tryNewInlineableClass(LongImpl.RuntimeLongClass).map(_.tpe).get @@ -115,6 +117,9 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { private lazy val inlinedRTLongHiField = inlinedRTLongRecordType.fields(1).name + private val getIntrinsicCode = + Intrinsics.buildIntrinsicsMap(config.coreSpec.esFeatures) + def optimize(thisType: Type, originalDef: MethodDef): MethodDef = { try { val MethodDef(static, name, params, resultType, optBody) = originalDef @@ -1106,7 +1111,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { } // Select the lo or hi "field" of a Long literal - case PreTransLit(LongLiteral(value)) => + case PreTransLit(LongLiteral(value)) if useRuntimeLong => val itemName = item.name assert(itemName == inlinedRTLongLoField || itemName == inlinedRTLongHiField) @@ -1524,8 +1529,10 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { private def boxedClassForType(tpe: Type): String = (tpe: @unchecked) match { case ClassType(cls) => - if (cls == Definitions.BoxedLongClass) LongImpl.RuntimeLongClass - else cls + if (cls == Definitions.BoxedLongClass && useRuntimeLong) + LongImpl.RuntimeLongClass + else + cls case AnyType => Definitions.ObjectClass case UndefType => Definitions.BoxedUnitClass @@ -1534,7 +1541,9 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case ByteType => Definitions.BoxedByteClass case ShortType => Definitions.BoxedShortClass case IntType => Definitions.BoxedIntegerClass - case LongType => LongImpl.RuntimeLongClass + case LongType => + if (useRuntimeLong) LongImpl.RuntimeLongClass + else Definitions.BoxedLongClass case FloatType => Definitions.BoxedFloatClass case DoubleType => Definitions.BoxedDoubleClass case StringType => Definitions.BoxedStringClass @@ -2519,6 +2528,8 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { private def expandLongValue(value: PreTransform)(cont: PreTransCont)( implicit scope: Scope, pos: Position): TailRec[Tree] = { + assert(useRuntimeLong) + /* To force the expansion, we first store the `value` in a temporary * variable of type `RuntimeLong` (not `Long`, otherwise we would go into * infinite recursion), then we create a `new RuntimeLong` with its lo and @@ -2573,7 +2584,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { } pretrans match { - case PreTransUnaryOp(op, arg) => + case PreTransUnaryOp(op, arg) if useRuntimeLong => import UnaryOp._ (op: @switch) match { @@ -2593,7 +2604,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { cont(pretrans) } - case PreTransBinaryOp(op, lhs, rhs) => + case PreTransBinaryOp(op, lhs, rhs) if useRuntimeLong => import BinaryOp._ (op: @switch) match { @@ -2635,21 +2646,6 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { } } - private def isLiteralOrOptimizableLong(texpr: PreTransform): Boolean = { - texpr match { - case PreTransTree(LongLiteral(_), _) => - true - case PreTransLocalDef(LocalDef(_, _, replacement)) => - replacement match { - case ReplaceWithVarRef(_, _, _, Some(_)) => true - case ReplaceWithConstant(LongLiteral(_)) => true - case _ => false - } - case _ => - false - } - } - private def foldUnaryOp(op: UnaryOp.Code, arg: PreTransform)( implicit pos: Position): PreTransform = { import UnaryOp._ @@ -4153,7 +4149,8 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { def withDedicatedVar(tpe: RefinedType): TailRec[Tree] = { val rtLongClassType = ClassType(LongImpl.RuntimeLongClass) - if (tpe.base == LongType && declaredType != rtLongClassType) { + if (tpe.base == LongType && declaredType != rtLongClassType && + useRuntimeLong) { /* If the value's type is a primitive Long, and the declared type is * not RuntimeLong, we want to force the expansion of the primitive * Long (which we know is in fact a RuntimeLong) into a local variable, @@ -4955,7 +4952,7 @@ private[optimizer] object OptimizerCore { final val Float64ArrayToDoubleArray = Float32ArrayToFloatArray + 1 // scalastyle:off line.size.limit - val intrinsics: Map[String, Int] = Map( + private val baseIntrinsics: Map[String, Int] = Map( "jl_System$.arraycopy__O__I__O__I__I__V" -> ArrayCopy, "jl_System$.identityHashCode__O__I" -> IdentityHashCode, @@ -4965,11 +4962,6 @@ private[optimizer] object OptimizerCore { "jl_Integer$.numberOfLeadingZeros__I__I" -> IntegerNLZ, - "jl_Long$.toString__J__T" -> LongToString, - "jl_Long$.compare__J__J__I" -> LongCompare, - "jl_Long$.divideUnsigned__J__J__J" -> LongDivideUnsigned, - "jl_Long$.remainderUnsigned__J__J__J" -> LongRemainderUnsigned, - "scm_ArrayBuilder$.scala$collection$mutable$ArrayBuilder$$zeroOf__jl_Class__O" -> ArrayBuilderZeroOf, "scm_ArrayBuilder$.scala$collection$mutable$ArrayBuilder$$genericArrayBuilderResult__jl_Class__sjs_js_Array__O" -> GenericArrayBuilderResult, @@ -4992,12 +4984,24 @@ private[optimizer] object OptimizerCore { "sjs_js_typedarray_package$.int32Array2IntArray__sjs_js_typedarray_Int32Array__AI" -> Int32ArrayToIntArray, "sjs_js_typedarray_package$.float32Array2FloatArray__sjs_js_typedarray_Float32Array__AF" -> Float32ArrayToFloatArray, "sjs_js_typedarray_package$.float64Array2DoubleArray__sjs_js_typedarray_Float64Array__AD" -> Float64ArrayToDoubleArray - ).withDefaultValue(-1) + ) + + private val runtimeLongIntrinsics: Map[String, Int] = Map( + "jl_Long$.toString__J__T" -> LongToString, + "jl_Long$.compare__J__J__I" -> LongCompare, + "jl_Long$.divideUnsigned__J__J__J" -> LongDivideUnsigned, + "jl_Long$.remainderUnsigned__J__J__J" -> LongRemainderUnsigned + ) // scalastyle:on line.size.limit - } - private def getIntrinsicCode(target: AbstractMethodID): Int = - Intrinsics.intrinsics(target.toString) + def buildIntrinsicsMap(esFeatures: ESFeatures): AbstractMethodID => Int = { + val intrinsics = + if (esFeatures.allowBigIntsForLongs) baseIntrinsics + else baseIntrinsics ++ runtimeLongIntrinsics + + { target => intrinsics.getOrElse(target.toString, -1) } + } + } private trait StateBackup { def restore(): Unit From b9ec4ee06a26b895f168c3ecdbae5b9724beb447 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 24 Mar 2018 13:15:30 +0100 Subject: [PATCH 0655/2665] Blacklist LongTest.scala in FullOpt. `LongTest.scala` uses optimizer-based generative programming to generate a *lot* of tests. Worse, the way it optimizes `Long`s turns that huge amount of test code into an *insane* amount of .js code within methods. Closure then completely loses it with that much code and all the intra-method optimizations it can do about it. Blacklisting this test when compiling for `FullOpt` dramatically improves the time it takes to fully optimize the test suite (between 4x and 5x on my machine). --- project/Build.scala | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/project/Build.scala b/project/Build.scala index 6c311844f6..87646c12e8 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1635,6 +1635,20 @@ object Build { Seq(outFile) }.taskValue, + /* Blacklist LongTest.scala in FullOpt, because it generates so much + * code, through optimizer-based generative programming, that Closure + * loses it on that code. + */ + sources in Test := { + val prev = (sources in Test).value + scalaJSStage.value match { + case FastOptStage => + prev + case FullOptStage => + prev.filter(!_.getPath.replace('\\', '/').endsWith("compiler/LongTest.scala")) + } + }, + // Module initializers. Duplicated in toolsJS/test scalaJSModuleInitializers += { ModuleInitializer.mainMethod( From 86f84f5eeed12dd164abf2e6f93d0d46c4fdb944 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Mon, 19 Mar 2018 06:32:47 +0100 Subject: [PATCH 0656/2665] Always assume test-inteface is present This removes the fix for #2752 (test-interface not present) as it is a degenerate case that can only happen in the Scala.js build itself (or in a misconfigured build). Instead, we override the library/test task so that we behave well in the community build. --- Jenkinsfile | 3 +- project/Build.scala | 5 +++ .../org/scalajs/testadapter/TestAdapter.scala | 36 +++---------------- 3 files changed, 10 insertions(+), 34 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 4933f2e212..08466c48c2 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -116,13 +116,12 @@ def Tasks = [ sbtretry 'set scalaJSStage in Global := FullOptStage' \ ++$scala testingExample/testHtml \ testingExample/clean && - sbtretry ++$scala library/test && sbtretry ++$scala testSuiteJVM/test testSuiteJVM/clean && sbtretry ++$scala testSuite/test && sbtretry ++$scala testSuiteEx/test && sbtretry 'set scalaJSStage in Global := FullOptStage' \ ++$scala testSuiteEx/test && - sbtretry ++$scala testSuite/test:doc compiler/test reversi/fastOptJS reversi/fullOptJS && + sbtretry ++$scala testSuite/test:doc library/test compiler/test reversi/fastOptJS reversi/fullOptJS && sbtretry ++$scala compiler/compile:doc library/compile:doc \ testInterface/compile:doc && sbtretry ++$scala partest/fetchScalaSource && diff --git a/project/Build.scala b/project/Build.scala index 87646c12e8..62dc043323 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1131,6 +1131,11 @@ object Build { mimaBinaryIssueFilters ++= BinaryIncompatibilities.Library, scalaJSExternalCompileSettings, + + test in Test := { + streams.value.log.warn("Skipping library/test. Run testSuite/test to test library.") + }, + inConfig(Compile)(Seq( scalacOptions in doc ++= Seq("-implicits", "-groups"), diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapter.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapter.scala index f0dda59198..d733f47687 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapter.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapter.scala @@ -48,20 +48,10 @@ final class TestAdapter(jsEnv: ComJSEnv, jsFiles: Seq[VirtualJSFile], * [[close]] is called. */ def loadFrameworks(frameworkNames: List[List[String]]): List[Option[Framework]] = { - val runner = getRunnerForThread() - - val frameworks = runner.com + getRunnerForThread().com .call(JSEndpoints.detectFrameworks)(frameworkNames) .map(_.map(_.map(info => new FrameworkAdapter(info, this)))) - - val recovered = frameworks.recoverWith { - // If there is no testing framework loaded, nothing will reply. - case _: RPCCore.ClosedException => - // We reply with no framework at all. - runner.runner.future.map(_ => frameworkNames.map(_ => None)) - } - - recovered.await() + .await() } /** Releases all resources. All associated runs must be done. */ @@ -139,26 +129,8 @@ final class TestAdapter(jsEnv: ComJSEnv, jsFiles: Seq[VirtualJSFile], s"""require("${escapeJS(moduleName)}").org || {}""" } - /* #2752: if there is no testing framework at all on the classpath, - * the testing interface will not be there, and therefore the - * `startBridge` function will not exist. We must therefore be - * careful when selecting it. - * If it is not present, we will simply exit; `loadFrameworks` is prepared - * to deal with this case. - */ - val code = s""" - (function() { - "use strict"; - var namespace = $orgExpr; - namespace = namespace.scalajs || {}; - namespace = namespace.testinterface || {}; - namespace = namespace.internal || {}; - var bridge = namespace.startBridge || function() {}; - bridge(); - })(); - """ - - val launcher = new MemVirtualJSFile("startTestBridge.js").withContent(code) + val launcher = new MemVirtualJSFile("startTestBridge.js") + .withContent(s"($orgExpr).scalajs.testinterface.internal.startBridge();") val runner = jsEnv.comRunner(jsFiles :+ launcher) val com = new ComJSEnvRPC(runner) val mux = new RunMuxRPC(com) From 891e58330f6484f6f828c685092daa1316221a7a Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Mon, 19 Mar 2018 20:16:06 +0100 Subject: [PATCH 0657/2665] Remove dependency on NodeJSEnv wantSourceMap and hasSourceMapSupport We are not going to support them anymore with the new JSEnvs. --- Jenkinsfile | 8 -------- project/Build.scala | 24 +++++++++++------------- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 08466c48c2..5d275abfc0 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -196,42 +196,34 @@ def Tasks = [ setJavaVersion $java npm install && sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true)))' \ - '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 scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true)))' \ - 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withSourceMap(false))' \ 'set scalaJSLinkerConfig in $testSuite ~= (_.withOptimizer(false))' \ ++$scala $testSuite/test \ $testSuite/clean && sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true)))' \ - 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withSourceMap(false))' \ 'set scalaJSLinkerConfig in $testSuite ~= makeCompliant' \ ++$scala $testSuite/test \ $testSuite/clean && sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true)))' \ - 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withSourceMap(false))' \ 'set scalaJSLinkerConfig in $testSuite ~= makeCompliant' \ 'set scalaJSLinkerConfig in $testSuite ~= (_.withOptimizer(false))' \ ++$scala $testSuite/test \ $testSuite/clean && sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true)))' \ - 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withSourceMap(false))' \ 'set scalaJSStage in Global := FullOptStage' \ ++$scala $testSuite/test \ $testSuite/clean && sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true)))' \ - 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withSourceMap(false))' \ 'set scalaJSStage in Global := FullOptStage' \ 'set scalaJSLinkerConfig in $testSuite ~= (_.withOptimizer(false))' \ ++$scala $testSuite/test \ $testSuite/clean && sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true)))' \ - 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withSourceMap(false))' \ 'set scalaJSLinkerConfig in $testSuite ~= (_.withModuleKind(ModuleKind.CommonJSModule))' \ ++$scala $testSuite/test && sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true)))' \ - 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withSourceMap(false))' \ 'set scalaJSLinkerConfig in $testSuite ~= (_.withModuleKind(ModuleKind.CommonJSModule))' \ 'set scalaJSStage in Global := FullOptStage' \ ++$scala $testSuite/test diff --git a/project/Build.scala b/project/Build.scala index 62dc043323..aafa9a648f 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -59,6 +59,8 @@ object MyScalaJSPlugin extends AutoPlugin { val isGeneratingEclipse = Properties.envOrElse("GENERATING_ECLIPSE", "false").toBoolean + val wantSourceMaps = settingKey[Boolean]("Whether source maps should be used") + private val configSettings: Seq[Setting[_]] = Def.settings( // Add a JS file defining Java system properties jsExecutionFiles := { @@ -105,6 +107,11 @@ object MyScalaJSPlugin extends AutoPlugin { scalaJSLinkerConfig ~= (_.withCheckIR(true)), + wantSourceMaps := !scalaJSLinkerConfig.value.esFeatures.useECMAScript2015, + + jsEnv := new NodeJSEnv( + NodeJSEnv.Config().withSourceMap(wantSourceMaps.value)), + // Link source maps scalacOptions ++= { val base = (baseDirectory in LocalProject("scalajs")).value @@ -1357,19 +1364,10 @@ object Build { def envTagsFor(env: JSEnv): Seq[String] = env match { case env: NodeJSEnv => val tags1 = Seq("nodejs") - val tags2 = if (env.wantSourceMap) { - if (!env.hasSourceMapSupport) { - throw new MessageOnlyException( - "You must install Node.js source map support to " + - "run the full Scala.js test suite (npm install " + - "source-map-support). To deactivate source map " + - "tests, do: set jsEnv in " + thisProject.value.id + - " := NodeJSEnv().value.withSourceMap(false)") - } - tags1 :+ "source-maps" - } else { - tags1 - } + val tags2 = + if (MyScalaJSPlugin.wantSourceMaps.value) tags1 :+ "source-maps" + else tags1 + env match { case env: NodeJSEnvForcePolyfills => tags1 From 1acffde2e96877bc6d7b280e3dc35ded7242129e Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 10 Dec 2017 08:46:04 +0100 Subject: [PATCH 0658/2665] Fix #3033: Rehaul JSEnv API This is a full rehaul of the JSEnv API. Highlights include: - No synchronous interface. - Proper stopping/closing semantics. - Proper message passing semantics. - Removal of JSConsole. - Reduce implementation inheritance. --- Jenkinsfile | 6 +- .../org/scalajs/jsenv/test/AsyncTests.scala | 50 --- .../scalajs/jsenv/test/BasicJSEnvTests.scala | 46 --- .../org/scalajs/jsenv/test/ComTests.scala | 253 +++++--------- .../jsenv/test/CustomInitFilesTest.scala | 24 -- .../org/scalajs/jsenv/test/JSEnvSuite.scala | 64 ++++ .../scalajs/jsenv/test/JSEnvSuiteConfig.scala | 71 ++++ .../org/scalajs/jsenv/test/JSEnvTest.scala | 49 --- .../org/scalajs/jsenv/test/RunTests.scala | 154 +++++++++ .../scalajs/jsenv/test/StoreJSConsole.scala | 14 - .../org/scalajs/jsenv/test/StoreLogger.scala | 29 -- .../org/scalajs/jsenv/test/TestComKit.scala | 65 ++++ .../org/scalajs/jsenv/test/TestKit.scala | 156 +++++++++ .../scalajs/jsenv/test/TimeoutComTests.scala | 165 +++------- ...meoutTests.scala => TimeoutRunTests.scala} | 14 +- .../scala/org/scalajs/jsenv/AsyncJSEnv.scala | 16 - .../org/scalajs/jsenv/AsyncJSRunner.scala | 80 ----- .../scala/org/scalajs/jsenv/ComJSEnv.scala | 42 --- .../scala/org/scalajs/jsenv/ComJSRunner.scala | 41 --- .../org/scalajs/jsenv/ConsoleJSConsole.scala | 17 - .../org/scalajs/jsenv/ExternalJSEnv.scala | 219 ------------ .../org/scalajs/jsenv/ExternalJSRun.scala | 196 +++++++++++ .../main/scala/org/scalajs/jsenv/Input.scala | 34 ++ .../scala/org/scalajs/jsenv/JSConsole.scala | 15 - .../main/scala/org/scalajs/jsenv/JSEnv.scala | 72 +++- .../scala/org/scalajs/jsenv/JSInitFiles.scala | 8 - .../scala/org/scalajs/jsenv/JSRunner.scala | 17 - .../main/scala/org/scalajs/jsenv/JSRuns.scala | 76 +++++ .../org/scalajs/jsenv/NullJSConsole.scala | 5 - .../scala/org/scalajs/jsenv/RunConfig.scala | 160 +++++++++ .../main/scala/org/scalajs/jsenv/Utils.scala | 38 --- .../org/scalajs/jsenv/RunConfigTest.scala | 88 +++++ .../jsenv/nodejs/AbstractNodeJSEnv.scala | 311 ------------------ .../org/scalajs/jsenv/nodejs/ComSupport.scala | 302 +++++++++++++++++ .../org/scalajs/jsenv/nodejs/NodeJSEnv.scala | 105 ++++-- .../org/scalajs/jsenv/nodejs/Support.scala | 44 +++ .../scalajs/jsenv/nodejs/NodeJSSuite.scala | 11 + .../org/scalajs/jsenv/nodejs/NodeJSTest.scala | 79 ----- .../NodeJSWithCustomInitFilesTest.scala | 9 - .../scala/tools/nsc/MainGenericRunner.scala | 19 +- project/Build.scala | 34 +- project/NodeJSEnvForcePolyfills.scala | 32 +- .../scala/org/scalajs/sbtplugin/Run.scala | 46 +++ .../sbtplugin/ScalaJSPluginInternal.scala | 21 +- .../org/scalajs/testadapter/ComJSEnvRPC.scala | 80 ----- .../org/scalajs/testadapter/JSEnvRPC.scala | 54 +++ .../org/scalajs/testadapter/TestAdapter.scala | 24 +- .../org/scalajs/testcommon/RPCCore.scala | 4 +- 48 files changed, 1863 insertions(+), 1596 deletions(-) delete mode 100644 js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/AsyncTests.scala delete mode 100644 js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/BasicJSEnvTests.scala delete mode 100644 js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/CustomInitFilesTest.scala create mode 100644 js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvSuite.scala create mode 100644 js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvSuiteConfig.scala delete mode 100644 js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvTest.scala create mode 100644 js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala delete mode 100644 js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/StoreJSConsole.scala delete mode 100644 js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/StoreLogger.scala create mode 100644 js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestComKit.scala create mode 100644 js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestKit.scala rename js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/{TimeoutTests.scala => TimeoutRunTests.scala} (89%) delete mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSEnv.scala delete mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSRunner.scala delete mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/ComJSEnv.scala delete mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/ComJSRunner.scala delete mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/ConsoleJSConsole.scala delete mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala create mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSRun.scala create mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/Input.scala delete mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/JSConsole.scala delete mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/JSInitFiles.scala delete mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/JSRunner.scala create mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/JSRuns.scala delete mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/NullJSConsole.scala create mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/RunConfig.scala delete mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/Utils.scala create mode 100644 js-envs/src/test/scala/org/scalajs/jsenv/RunConfigTest.scala delete mode 100644 nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala create mode 100644 nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/ComSupport.scala create mode 100644 nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/Support.scala create mode 100644 nodejs-env/src/test/scala/org/scalajs/jsenv/nodejs/NodeJSSuite.scala delete mode 100644 nodejs-env/src/test/scala/org/scalajs/jsenv/nodejs/NodeJSTest.scala delete mode 100644 nodejs-env/src/test/scala/org/scalajs/jsenv/nodejs/NodeJSWithCustomInitFilesTest.scala create mode 100644 sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Run.scala delete mode 100644 test-adapter/src/main/scala/org/scalajs/testadapter/ComJSEnvRPC.scala create mode 100644 test-adapter/src/main/scala/org/scalajs/testadapter/JSEnvRPC.scala diff --git a/Jenkinsfile b/Jenkinsfile index 5d275abfc0..7602e59419 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -249,7 +249,7 @@ def Tasks = [ setJavaVersion $java npm install && sbt ++$scala ir/test io/test logging/compile linker/compile \ - stubs/package nodeJSEnv/test testAdapter/test \ + stubs/package jsEnvs/test nodeJSEnv/test testAdapter/test \ ir/mimaReportBinaryIssues io/mimaReportBinaryIssues \ logging/mimaReportBinaryIssues linker/mimaReportBinaryIssues \ jsEnvs/mimaReportBinaryIssues jsEnvsTestKit/mimaReportBinaryIssues \ @@ -266,7 +266,7 @@ def Tasks = [ setJavaVersion $java npm install && sbt ++$scala ir/test io/test logging/compile linker/compile \ - stubs/package nodeJSEnv/test testAdapter/test \ + stubs/package jsEnvs/test nodeJSEnv/test testAdapter/test \ sbtPlugin/package \ ir/mimaReportBinaryIssues io/mimaReportBinaryIssues \ logging/mimaReportBinaryIssues linker/mimaReportBinaryIssues \ @@ -281,7 +281,7 @@ def Tasks = [ logging/scalastyle logging/test:scalastyle \ linker/scalastyle linker/test:scalastyle \ jsEnvs/scalastyle jsEnvsTestKit/scalastyle nodeJSEnv/scalastyle \ - nodeJSEnv/test:scalastyle testAdapter/scalastyle \ + jsEnvs/test:scalastyle nodeJSEnv/test:scalastyle testAdapter/scalastyle \ sbtPlugin/scalastyle testInterface/scalastyle \ testSuite/scalastyle testSuite/test:scalastyle \ testSuiteJVM/test:scalastyle \ diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/AsyncTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/AsyncTests.scala deleted file mode 100644 index f3dc0bb650..0000000000 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/AsyncTests.scala +++ /dev/null @@ -1,50 +0,0 @@ -package org.scalajs.jsenv.test - -import org.scalajs.jsenv._ - -import org.scalajs.io._ -import org.scalajs.logging._ - -import org.junit.Test -import org.junit.Assert._ - -import scala.concurrent.{Future, Await} -import scala.concurrent.duration._ - -/** A couple of tests that test async runners for mix-in into a test suite */ -trait AsyncTests extends BasicJSEnvTests { - - protected final val DefaultTimeout: Duration = 10.seconds - - protected def newJSEnv: AsyncJSEnv - - protected def asyncRunner(code: String): AsyncJSRunner = { - val codeVF = new MemVirtualJSFile("testScript.js").withContent(code) - newJSEnv.asyncRunner(codeVF :: Nil) - } - - protected def start(runner: AsyncJSRunner): Future[Unit] = { - runner.start(new ScalaConsoleLogger(Level.Warn), ConsoleJSConsole) - } - - @Test - def futureTest: Unit = { - val runner = asyncRunner("") - val fut = start(runner) - - Await.result(fut, DefaultTimeout) - - assertFalse("VM should be terminated", runner.isRunning) - } - - @Test - def stopAfterTerminatedTest: Unit = { - val runner = asyncRunner("") - val fut = start(runner) - - Await.result(fut, DefaultTimeout) - - runner.stop() // should do nothing, and not fail - } - -} diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/BasicJSEnvTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/BasicJSEnvTests.scala deleted file mode 100644 index 4404f18dbd..0000000000 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/BasicJSEnvTests.scala +++ /dev/null @@ -1,46 +0,0 @@ -package org.scalajs.jsenv.test - -import org.junit.Test -import org.junit.Assert._ - -/** Tests that should succeed on any JSEnv */ -trait BasicJSEnvTests extends JSEnvTest { - - @Test - def failureTest: Unit = { - - """ - var a = {}; - a.foo(); - """.fails() - - } - - @Test - def syntaxErrorTest: Unit = { - - """ - { - """.fails() - - } - - @Test // Failed in Phantom - #2053 - def utf8Test: Unit = { - - """ - console.log("\u1234"); - """ hasOutput "\u1234\n"; - - } - - @Test - def allowScriptTags: Unit = { - - """ - console.log(""); - """ hasOutput "\n"; - - } - -} diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala index b8f7d442dc..5eeed6f0ab 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala @@ -2,134 +2,81 @@ package org.scalajs.jsenv.test import org.scalajs.jsenv._ -import org.scalajs.io._ - -import org.junit.Test +import org.junit.{Before, Test} import org.junit.Assert._ +import org.junit.Assume._ import scala.concurrent.Await +import scala.concurrent.ExecutionContext.Implicits.global -/** A couple of tests that test communication for mix-in into a test suite */ -trait ComTests extends AsyncTests { - - protected def newJSEnv: ComJSEnv - - protected def comRunner(code: String): ComJSRunner = { - val codeVF = new MemVirtualJSFile("testScript.js").withContent(code) - newJSEnv.comRunner(codeVF :: Nil) - } - - private def assertThrowClosed(msg: String, body: => Unit): Unit = { - val thrown = try { - body - false - } catch { - case _: ComJSEnv.ComClosedException => - true - } +private[test] class ComTests(config: JSEnvSuiteConfig) { + private val kit = new TestComKit(config) - assertTrue(msg, thrown) + @Before + def before: Unit = { + assumeTrue("JSEnv needs com support", config.supportsCom) } @Test - def comCloseJVMTest: Unit = { - val com = comRunner(s""" + def basicTest: Unit = { + val run = kit.start(""" scalajsCom.init(function(msg) { scalajsCom.send("received: " + msg); }); scalajsCom.send("Hello World"); - """) - - start(com) - - assertEquals("Hello World", com.receive()) + """, RunConfig()) - for (i <- 0 to 10) { - com.send(i.toString) - assertEquals(s"received: $i", com.receive()) + try { + assertEquals("Hello World", run.waitNextMessage()) + + for (i <- 0 to 10) { + run.run.send(i.toString) + assertEquals(s"received: $i", run.waitNextMessage()) + } + } finally { + run.closeAndWait() } - - com.close() - com.await(DefaultTimeout) - - com.stop() // should do nothing, and not fail - } - - def comCloseJSTestCommon(timeout: Long): Unit = { - val com = comRunner(s""" - scalajsCom.init(function(msg) {}); - for (var i = 0; i < 10; ++i) - scalajsCom.send("msg: " + i); - scalajsCom.close(); - """) - - start(com) - - Thread.sleep(timeout) - - for (i <- 0 until 10) - assertEquals(s"msg: $i", com.receive()) - - assertThrowClosed("Expect receive to throw after closing of channel", - com.receive()) - - com.close() - com.await(DefaultTimeout) - - com.stop() // should do nothing, and not fail } @Test - def comCloseJSTest: Unit = comCloseJSTestCommon(0) + def jsExitsOnMessageTest: Unit = { + assumeTrue(config.terminateVMJSCode.isDefined) - @Test - def comCloseJSTestDelayed: Unit = comCloseJSTestCommon(1000) + val run = kit.start(s""" + scalajsCom.init(function(msg) { ${config.terminateVMJSCode.get}; }); + for (var i = 0; i < 10; ++i) + scalajsCom.send("msg: " + i); + """, RunConfig()) - @Test - def doubleCloseTest: Unit = { - val n = 10 - val com = pingPongRunner(n) + try { + for (i <- 0 until 10) + assertEquals(s"msg: $i", run.waitNextMessage()) - start(com) + run.run.send("quit") - for (i <- 0 until n) { - com.send("ping") - assertEquals("pong", com.receive()) + Await.result(run.run.future, config.awaitTimeout) + } finally { + run.run.close() } - - com.close() - com.await(DefaultTimeout) } @Test def multiEnvTest: Unit = { val n = 10 - val envs = List.fill(5)(pingPongRunner(10)) - - envs.foreach(start) - - val ops = List[ComJSRunner => Unit]( - _.send("ping"), - com => assertEquals("pong", com.receive()) - ) - - for { - i <- 0 until n - env <- envs - op <- ops - } op(env) - - envs.foreach(_.close()) - envs.foreach(_.await(DefaultTimeout)) - } - - private def pingPongRunner(count: Int) = { - comRunner(s""" - var seen = 0; + val runs = List.fill(5) { + kit.start(""" scalajsCom.init(function(msg) { scalajsCom.send("pong"); - if (++seen >= $count) - scalajsCom.close(); }); - """) + """, RunConfig()) + } + + try { + for (_ <- 0 until n) { + runs.foreach(_.run.send("ping")) + runs.foreach(r => assertEquals("pong", r.waitNextMessage())) + } + } finally { + runs.foreach(_.closeAndWait()) + } } @Test @@ -141,107 +88,57 @@ trait ComTests extends AsyncTests { // Max message size: 1KB * 2^(2*iters+1) = 1MB val iters = 4 - val com = comRunner(""" + val run = kit.start(""" scalajsCom.init(function(msg) { scalajsCom.send(msg + msg); }); - """) + """, RunConfig()) - start(com) + try { + run.run.send(baseMsg) - com.send(baseMsg) + def resultFactor(iters: Int) = Math.pow(2, 2 * iters + 1).toInt - def resultFactor(iters: Int) = Math.pow(2, 2 * iters + 1).toInt + for (i <- 0 until iters) { + val reply = run.waitNextMessage() - for (i <- 0 until iters) { - val reply = com.receive() + val factor = resultFactor(i) - val factor = resultFactor(i) + assertEquals(baseLen * factor, reply.length) - assertEquals(baseLen * factor, reply.length) + for (j <- 0 until factor) + assertEquals(baseMsg, reply.substring(j * baseLen, (j + 1) * baseLen)) - for (j <- 0 until factor) - assertEquals(baseMsg, reply.substring(j * baseLen, (j + 1) * baseLen)) + run.run.send(reply + reply) + } - com.send(reply + reply) + val lastLen = run.waitNextMessage().length + assertEquals(baseLen * resultFactor(iters), lastLen) + } finally { + run.closeAndWait() } - - val lastLen = com.receive().length - assertEquals(baseLen * resultFactor(iters), lastLen) - - com.close() - com.await(DefaultTimeout) } @Test def highCharTest: Unit = { // #1536 - val com = comRunner(""" - scalajsCom.init(scalajsCom.send); - """) - - start(com) - - val msg = "\uC421\u8F10\u0112\uFF32" - - com.send(msg) - assertEquals(msg, com.receive()) - - com.close() - com.await(DefaultTimeout) - } - - @Test - def noInitTest: Unit = { - val com = comRunner("") - - start(com) - com.send("Dummy") - com.close() - com.await(DefaultTimeout) - } - - @Test - def stopTestCom: Unit = { - val com = comRunner(s"""scalajsCom.init(function(msg) {});""") - - start(com) - - // Make sure the VM doesn't terminate. - Thread.sleep(1000) - - assertTrue("VM should still be running", com.isRunning) - - // Stop VM instead of closing channel - com.stop() + val run = kit.start("scalajsCom.init(scalajsCom.send);", RunConfig()) try { - com.await(DefaultTimeout) - fail("Stopped VM should be in failure state") - } catch { - case _: Throwable => + val msg = "\uC421\u8F10\u0112\uFF32" + run.run.send(msg) + assertEquals(msg, run.waitNextMessage()) + } finally { + run.closeAndWait() } } @Test - def futureStopTest: Unit = { - val com = comRunner(s"""scalajsCom.init(function(msg) {});""") - - val fut = start(com) - - // Make sure the VM doesn't terminate. - Thread.sleep(1000) - - assertTrue("VM should still be running", com.isRunning) - - // Stop VM instead of closing channel - com.stop() - + def noInitTest: Unit = { + val run = kit.start("", RunConfig()) try { - Await.result(fut, DefaultTimeout) - fail("Stopped VM should be in failure state") - } catch { - case _: Throwable => + run.run.send("Dummy") + } finally { + run.closeAndWait() } } - } diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/CustomInitFilesTest.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/CustomInitFilesTest.scala deleted file mode 100644 index 2055dee32d..0000000000 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/CustomInitFilesTest.scala +++ /dev/null @@ -1,24 +0,0 @@ -package org.scalajs.jsenv.test - -import org.scalajs.io._ - -import org.junit.Test - -abstract class CustomInitFilesTest extends JSEnvTest { - def makeCustomInitFiles(): Seq[VirtualJSFile] = { - Seq(new MemVirtualJSFile("custominit.js").withContent(""" - function customPrint(s) { - console.log("custom: " + s); - } - """)) - } - - @Test - def customInitFilesTest: Unit = { - """ - customPrint("hello"); - """ hasOutput - """|custom: hello - |""".stripMargin - } -} diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvSuite.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvSuite.scala new file mode 100644 index 0000000000..e6a76bef75 --- /dev/null +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvSuite.scala @@ -0,0 +1,64 @@ +package org.scalajs.jsenv.test + +import org.scalajs.jsenv.JSEnv + +import scala.collection.JavaConverters._ +import scala.reflect.ClassTag + +import org.junit.runner.Runner +import org.junit.runners.Suite +import org.junit.runners.parameterized.{TestWithParameters, BlockJUnit4ClassRunnerWithParameters} +import org.junit.runners.model.TestClass + +/** Conformance test suite for any [[JSEnv]] implementation. + * + * Use with the [[JSEnvSuiteRunner]]. + * + * Example: + * {{{ + * import org.junit.runner.RunWith + * + * @RunWith(classOf[JSEnvSuiteRunner]) + * class MyJSEnvSuite extends JSEnvSuite(JSEnvSuiteConfig(new MyJSEnv)) + * }}} + * + * @see [[JSEnvSuiteConfig]] for details on the configuration. + */ +abstract class JSEnvSuite(private[test] val config: JSEnvSuiteConfig) + +/** Runner for a [[JSEnvSuite]]. May only be used on subclasses of [[JSEnvSuite]]. */ +final class JSEnvSuiteRunner(root: Class[_], config: JSEnvSuiteConfig) + extends Suite(root, JSEnvSuiteRunner.getRunners(config).asJava) { + + /** Constructor for reflective instantiation via `@RunWith`. */ + def this(suite: Class[_ <: JSEnvSuite]) = this(suite, suite.newInstance().config) + + /** Constructor for instantiation in a user defined Runner. */ + def this(config: JSEnvSuiteConfig) = this(null, config) +} + +private object JSEnvSuiteRunner { + private def r[T](config: JSEnvSuiteConfig, params: (String, AnyRef)*)(implicit t: ClassTag[T]) = { + val name = (("config" -> config.description) +: params) + .map { case (name, value) => s"$name = $value" } + .mkString("[", ", ", "]") + + val paramValues = config +: params.map(_._2) + + new BlockJUnit4ClassRunnerWithParameters( + new TestWithParameters(name, new TestClass(t.runtimeClass), paramValues.asJava)) + } + + private def getRunners(config: JSEnvSuiteConfig): List[Runner] = { + import java.lang.Boolean.{TRUE, FALSE} + + List( + r[RunTests](config, "withCom" -> FALSE), + r[RunTests](config, "withCom" -> TRUE), + r[TimeoutRunTests](config, "withCom" -> FALSE), + r[TimeoutRunTests](config, "withCom" -> TRUE), + r[ComTests](config), + r[TimeoutComTests](config) + ) + } +} diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvSuiteConfig.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvSuiteConfig.scala new file mode 100644 index 0000000000..73323ad097 --- /dev/null +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvSuiteConfig.scala @@ -0,0 +1,71 @@ +package org.scalajs.jsenv.test + +import org.scalajs.jsenv.JSEnv + +import scala.concurrent.duration._ + +/** Configuration for a [[JSEnvSuite]]. + * + * @see [[JSEnvSuite]] for usage. + * + * @param jsEnv [[JSEnv]] under test. + * @param terminateVMJSCode A JavaScript expression that terminates the VM. + * If set, proper handling of VM termination is tested. + * @param supportsCom Whether the [[JSEnv]] under test supports + * [[JSEnv#startWithCom]]. + * @param supportsTimeout Whether the [[JSEnv]] under test supports the + * JavaScript timeout methods (as defined in + * [[http://www.scala-js.org/api/scalajs-library/latest/#scala.scalajs.js.timers.RawTimers$ RawTimers]]). + * @param awaitTimeout Amount of time test cases wait for "things". This is + * deliberately not very well specified. Leave this as the default and + * increase it if your tests fail spuriously due to timeouts. + * @param description A human readable description of this configuration; + * defaults to [[JSEnv#name]]. This is only ever used in the parametrized + * JUnit test name. Can be customized if the same [[JSEnv]] is used with + * different configurations (e.g. Selenium with different browsers). + */ +final class JSEnvSuiteConfig private ( + val jsEnv: JSEnv, + val terminateVMJSCode: Option[String], + val supportsCom: Boolean, + val supportsTimeout: Boolean, + val awaitTimeout: FiniteDuration, + val description: String +) { + private def this(jsEnv: JSEnv) = this( + jsEnv = jsEnv, + terminateVMJSCode = None, + supportsCom = true, + supportsTimeout = true, + awaitTimeout = 1.minute, + description = jsEnv.name + ) + + def withTerminateVMJSCode(code: String): JSEnvSuiteConfig = + copy(terminateVMJSCode = Some(code)) + + def withSupportsCom(supportsCom: Boolean): JSEnvSuiteConfig = + copy(supportsCom = supportsCom) + + def withSupportsTimeout(supportsTimeout: Boolean): JSEnvSuiteConfig = + copy(supportsTimeout = supportsTimeout) + + def withAwaitTimepout(awaitTimeout: FiniteDuration): JSEnvSuiteConfig = + copy(awaitTimeout = awaitTimeout) + + def withDescription(description: String): JSEnvSuiteConfig = + copy(description = description) + + private def copy(terminateVMJSCode: Option[String] = terminateVMJSCode, + supportsCom: Boolean = supportsCom, + supportsTimeout: Boolean = supportsTimeout, + awaitTimeout: FiniteDuration = awaitTimeout, + description: String = description) = { + new JSEnvSuiteConfig(jsEnv, terminateVMJSCode, supportsCom, + supportsTimeout, awaitTimeout, description) + } +} + +object JSEnvSuiteConfig { + def apply(jsEnv: JSEnv): JSEnvSuiteConfig = new JSEnvSuiteConfig(jsEnv) +} diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvTest.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvTest.scala deleted file mode 100644 index 61c6ce781f..0000000000 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvTest.scala +++ /dev/null @@ -1,49 +0,0 @@ -package org.scalajs.jsenv.test - -import org.scalajs.jsenv._ - -import org.scalajs.io.MemVirtualJSFile -import org.scalajs.logging._ - -import org.junit.Assert._ - -import StoreLogger._ - -abstract class JSEnvTest { - - protected def newJSEnv: JSEnv - - implicit class RunMatcher(codeStr: String) { - - val code = new MemVirtualJSFile("testScript.js").withContent(codeStr) - - def hasOutput(expectedOut: String): Unit = { - - val console = new StoreJSConsole() - val logger = new StoreLogger() - - newJSEnv.jsRunner(code :: Nil).run(logger, console) - - val log = logger.getLog - val hasBadLog = log exists { - case Log(level, _) if level >= Level.Warn => true - case Trace(_) => true - case _ => false - } - - assertFalse("VM shouldn't log errors, warnings or traces. Log:\n" + - log.mkString("\n"), hasBadLog) - assertEquals("Output should match", expectedOut, console.getLog) - } - - def fails(): Unit = { - try { - newJSEnv.jsRunner(code :: Nil).run(NullLogger, NullJSConsole) - assertTrue("Code snipped should fail", false) - } catch { - case e: Exception => - } - } - } - -} diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala new file mode 100644 index 0000000000..ce584c62e0 --- /dev/null +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala @@ -0,0 +1,154 @@ +package org.scalajs.jsenv.test + +import scala.concurrent.Await + +import org.scalajs.io.VirtualJSFile +import org.scalajs.jsenv._ + +import org.junit.Assert._ +import org.junit.Assume._ +import org.junit.{Test, Before} + +private[test] class RunTests(config: JSEnvSuiteConfig, withCom: Boolean) { + private val kit = new TestKit(config, withCom) + import kit._ + + @Test + def failureTest: Unit = { + """ + var a = {}; + a.foo(); + """.fails() + } + + @Test + def syntaxErrorTest: Unit = { + """ + { + """.fails() + } + + @Test // Failed in Phantom - #2053 + def utf8Test: Unit = { + """ + console.log("\u1234"); + """ hasOutput "\u1234\n"; + } + + @Test + def allowScriptTags: Unit = { + """ + console.log(""); + """ hasOutput "\n"; + } + + @Test + def jsExitsTest: Unit = { + assumeTrue(config.terminateVMJSCode.isDefined) + + val run = kit.start(config.terminateVMJSCode.get, RunConfig()) + try { + Await.result(run.future, config.awaitTimeout) + } finally { + run.close() + } + } + + @Test // Node.js strips double percentage signs - #500 + def percentageTest: Unit = { + val counts = 1 to 15 + val argcs = 1 to 3 + val strings = counts.map("%" * _) + + val strlists = for { + count <- argcs + string <- strings + } yield List.fill(count)(string) + + val codes = for { + strlist <- strlists + } yield { + val args = strlist.map(s => s""""$s"""").mkString(", ") + s"console.log($args);\n" + } + + val result = strlists.map(_.mkString(" ") + "\n").mkString("") + + codes.mkString("").hasOutput(result) + } + + @Test // Node.js console.log hack didn't allow to log non-Strings - #561 + def nonStringTest: Unit = { + """ + console.log(1); + console.log(undefined); + console.log(null); + console.log({}); + console.log([1,2]); + """ hasOutput + """|1 + |undefined + |null + |[object Object] + |1,2 + |""".stripMargin + } + + @Test + def fastCloseTest: Unit = { + /* This test also tests a failure mode where the ExternalJSRun is still + * piping output while the client calls close. + */ + val run = kit.start("", RunConfig()) + run.close() + awaitAfterClose(run) + } + + @Test + def multiCloseAfterTerminatedTest: Unit = { + val run = kit.start("", RunConfig()) + run.close() + awaitAfterClose(run) + + // Should be noops (and not fail). + run.close() + run.close() + run.close() + } + + @Test + def noThrowOnBadFileTest: Unit = { + val badFile = new VirtualJSFile { + def path: String = ??? + def exists: Boolean = ??? + def content: String = ??? + } + + // `start` may not throw but must fail asynchronously + val run = kit.start(badFile, RunConfig()) + try { + Await.ready(run.future, config.awaitTimeout) + assertTrue("Bad file should have made run fail", + run.future.value.get.isFailure) + } finally { + run.close() + } + } + + /* This test verifies that a [[JSEnv]] properly validates its [[RunConfig]] + * (through [[RunConfig.Validator]]). + * + * If you get here, because the test suite fails on your [[JSEnv]] you are not + * using [[RunConfig.Validator]] properly (or at all). See its documentation + * on how to use it properly. + * + * This test sets a private option on [[RunConfig]] that is only known + * internally. This ensures that [[JSEnv]]s reject options added in the future + * they cannot support. + */ + @Test(expected = classOf[IllegalArgumentException]) + def ensureValidate: Unit = { + val cfg = RunConfig().withEternallyUnsupportedOption(true) + kit.start("", cfg).close() + } +} diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/StoreJSConsole.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/StoreJSConsole.scala deleted file mode 100644 index f4e60da5a4..0000000000 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/StoreJSConsole.scala +++ /dev/null @@ -1,14 +0,0 @@ -package org.scalajs.jsenv.test - -import org.scalajs.jsenv._ - -class StoreJSConsole extends JSConsole { - private[this] val buf = new StringBuilder() - - def log(msg: Any): Unit = { - buf.append(msg.toString) - buf.append('\n') - } - - def getLog: String = buf.toString -} diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/StoreLogger.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/StoreLogger.scala deleted file mode 100644 index 254703f91f..0000000000 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/StoreLogger.scala +++ /dev/null @@ -1,29 +0,0 @@ -package org.scalajs.jsenv.test - -import org.scalajs.logging._ - -import scala.collection.mutable.ListBuffer - -class StoreLogger extends Logger { - import StoreLogger._ - - private[this] val buf = new ListBuffer[LogElem] - - def log(level: Level, message: => String): Unit = - buf += Log(level, message) - def success(message: => String): Unit = - buf += Success(message) - def trace(t: => Throwable): Unit = - buf += Trace(t) - - def getLog: List[LogElem] = buf.toList -} - -object StoreLogger { - - sealed trait LogElem - final case class Log(level: Level, message: String) extends LogElem - final case class Success(message: String) extends LogElem - final case class Trace(t: Throwable) extends LogElem - -} diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestComKit.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestComKit.scala new file mode 100644 index 0000000000..20eecd22b6 --- /dev/null +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestComKit.scala @@ -0,0 +1,65 @@ +package org.scalajs.jsenv.test + +import java.util.concurrent.TimeoutException + +import org.scalajs.io.{VirtualJSFile, MemVirtualJSFile} + +import org.scalajs.jsenv._ + +import org.junit.Assert.fail + +import scala.collection.immutable +import scala.concurrent.Await +import scala.concurrent.duration.Duration + +private[test] final class TestComKit(config: JSEnvSuiteConfig) { + def start(code: String, runConfig: RunConfig): Run = { + val vf = new MemVirtualJSFile("testScript.js").withContent(code) + start(vf, runConfig) + } + + def start(vf: VirtualJSFile, runConfig: RunConfig): Run = { + val input = Input.ScriptsToLoad(List(vf)) + new Run(input, runConfig) + } + + final class Run(input: Input, runConfig: RunConfig) { + val run: JSComRun = config.jsEnv.startWithCom(input, runConfig, onMessage _) + + private var received = immutable.Queue.empty[String] + + def waitNextMessage(): String = synchronized { + val deadline = config.awaitTimeout.fromNow + + while (received.isEmpty) { + val m = deadline.timeLeft.toMillis + if (m > 0) + wait(m) + else + throw new TimeoutException("Timed out waiting for next message") + } + + val (msg, newReceived) = received.dequeue + received = newReceived + msg + } + + def closeAndWait(): Unit = { + run.close() + + // Run must complete successfully. + Await.result(run.future, config.awaitTimeout) + + synchronized { + if (received.nonEmpty) { + fail(s"There were unhandled messages: $received") + } + } + } + + private def onMessage(msg: String) = synchronized { + received = received.enqueue(msg) + notifyAll() + } + } +} diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestKit.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestKit.scala new file mode 100644 index 0000000000..766f8619b1 --- /dev/null +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestKit.scala @@ -0,0 +1,156 @@ +package org.scalajs.jsenv.test + +import java.io._ +import java.nio.CharBuffer +import java.nio.charset.StandardCharsets +import java.util.concurrent.TimeoutException + +import scala.annotation.tailrec +import scala.concurrent.Await +import scala.concurrent.duration.Deadline + +import org.scalajs.io.{VirtualJSFile, MemVirtualJSFile} + +import org.scalajs.jsenv._ + +import org.junit.Assert._ +import org.junit.Assume._ + +private[test] final class TestKit(config: JSEnvSuiteConfig, withCom: Boolean) { + assumeTrue("JSEnv needs com support", config.supportsCom || !withCom) + + def start(code: String, config: RunConfig): JSRun = { + val vf = new MemVirtualJSFile("testScript.js").withContent(code) + start(vf, config) + } + + def start(vf: VirtualJSFile, runConfig: RunConfig): JSRun = { + val input = Input.ScriptsToLoad(List(vf)) + if (withCom) + config.jsEnv.startWithCom(input, runConfig, _ => ()) + else + config.jsEnv.start(input, runConfig) + } + + /** Await a run started with [[start]] after it got closed. + * + * This expects successful termination depending on [[withCom]]: we are + * allowed to expect successful termination with a com. + */ + def awaitAfterClose(run: JSRun): Unit = { + if (withCom) + Await.result(run.future, config.awaitTimeout) + else + Await.ready(run.future, config.awaitTimeout) + } + + implicit final class RunMatcher private[TestKit] (codeStr: String) { + def hasOutput(expectedOut: String): Unit = { + val comparator = new OutputComparator(expectedOut) + val config = comparator.configure(RunConfig()) + val run = start(codeStr, config) + + try { + comparator.compare() + } finally { + run.close() + } + + awaitAfterClose(run) + } + + def fails(): Unit = { + // We do not want to spam the console with error output, so we ignore it. + def ignoreStreams(out: Option[InputStream], err: Option[InputStream]) = { + out.foreach(_.close()) + err.foreach(_.close()) + } + + val runConfig = RunConfig() + .withOnOutputStream(ignoreStreams) + .withInheritOut(false) + .withInheritErr(false) + + val run = start(codeStr, runConfig) + try { + Await.ready(run.future, config.awaitTimeout) + assertTrue("Code snipped should fail", run.future.value.get.isFailure) + } finally { + run.close() + } + } + } + + private class OutputComparator(expectedOut: String) { + private val waiter = new StreamWaiter + + def configure(config: RunConfig): RunConfig = { + config + .withOnOutputStream(waiter.onOutputStream _) + .withInheritOut(false) + .withInheritErr(true) + } + + def compare(): Unit = { + val deadline = config.awaitTimeout.fromNow + val stream = waiter.waitForStream(deadline) + + /* When reading, we use a CharBuffer for easy index tracking. However, we + * back it by an array so we can easily read partial results. + */ + val in = new InputStreamReader(stream, StandardCharsets.UTF_8) + val arr = new Array[Char](expectedOut.length) + val buf = CharBuffer.wrap(arr) + while (buf.hasRemaining && tryRead(in, buf, deadline) != -1) { + val len = buf.position + assertEquals("Partial check", + expectedOut.substring(0, len), + new String(arr, 0, len)) + } + + buf.flip() + assertEquals(expectedOut, buf.toString) + } + } + + @tailrec + private final def tryRead(in: Reader, buf: CharBuffer, deadline: Deadline): Int = { + if (deadline.isOverdue) { + buf.flip() + throw new TimeoutException("Timed out out waiting for output. Got so far: " + buf.toString) + } + + if (in.ready()) { + in.read(buf) + } else { + Thread.sleep(50) + tryRead(in, buf, deadline) + } + } + + private class StreamWaiter { + private[this] var stream: InputStream = _ + + def waitForStream(deadline: Deadline): InputStream = synchronized { + while (stream == null) { + val m = deadline.timeLeft.toMillis + if (m > 0) + wait(m) + else + throw new TimeoutException("Timed out waiting for stdout") + } + + stream + } + + def onOutputStream(out: Option[InputStream], + err: Option[InputStream]): Unit = synchronized { + require(err.isEmpty, "Got error stream, did not request it.") + require(stream == null, "Got called twice") + + stream = out.getOrElse(new ByteArrayInputStream(new Array[Byte](0))) + notifyAll() + } + } +} + diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutComTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutComTests.scala index 57c41c0b3d..a7070177b2 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutComTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutComTests.scala @@ -1,162 +1,89 @@ package org.scalajs.jsenv.test -import org.junit.Test +import org.scalajs.jsenv._ + +import org.junit.{Before, Test} import org.junit.Assert._ +import org.junit.Assume._ -import scala.concurrent.TimeoutException import scala.concurrent.duration._ -trait TimeoutComTests extends TimeoutTests with ComTests { +private[test] class TimeoutComTests(config: JSEnvSuiteConfig) { + private val kit = new TestComKit(config) + + @Before + def before: Unit = { + assumeTrue("JSEnv needs timeout support", config.supportsTimeout) + assumeTrue("JSEnv needs com support", config.supportsCom) + } @Test def delayedInitTest: Unit = { - - val com = comRunner(s""" + val run = kit.start(s""" setTimeout(function() { scalajsCom.init(function(msg) { scalajsCom.send("Got: " + msg); }); }, 100); - """) - - val deadline = 100.millis.fromNow - - start(com) - - com.send("Hello World") + """, RunConfig()) - assertEquals("Got: Hello World", com.receive()) - - assertTrue("Execution took too little time", deadline.isOverdue()) - - com.close() - com.await(DefaultTimeout) - - } - - @Test - def delayedReplyTest: Unit = { - - val com = comRunner(s""" - scalajsCom.init(function(msg) { - setTimeout(scalajsCom.send, 20, "Got: " + msg); - }); - """) - - start(com) + try { + // Deadline only starts now. Execution must happen asynchronously. + val deadline = 100.millis.fromNow - for (i <- 1 to 10) { - val deadline = 19.millis.fromNow // give some slack - com.send(s"Hello World: $i") - assertEquals(s"Got: Hello World: $i", com.receive()) + run.run.send("Hello World") + assertEquals("Got: Hello World", run.waitNextMessage()) assertTrue("Execution took too little time", deadline.isOverdue()) + } finally { + run.closeAndWait() } - - com.close() - com.await(DefaultTimeout) - } @Test - def receiveTimeoutTest: Unit = { - - val com = comRunner(s""" + def delayedReplyTest: Unit = { + val run = kit.start(s""" scalajsCom.init(function(msg) { - setTimeout(scalajsCom.send, 2000, "Got: " + msg); + setTimeout(scalajsCom.send, 200, "Got: " + msg); }); - """) - - start(com) + """, RunConfig()) - for (i <- 1 to 2) { - com.send(s"Hello World: $i") - try { - com.receive(900.millis) - fail("Expected TimeoutException to be thrown") - } catch { - case _: TimeoutException => + try { + for (i <- 1 to 10) { + val deadline = 190.millis.fromNow // give some slack + run.run.send(s"Hello World: $i") + assertEquals(s"Got: Hello World: $i", run.waitNextMessage()) + assertTrue("Execution took too little time", deadline.isOverdue()) } - assertEquals(s"Got: Hello World: $i", com.receive(3000.millis)) + } finally { + run.closeAndWait() } - - com.close() - com.await(DefaultTimeout) - } @Test def intervalSendTest: Unit = { - - val com = comRunner(s""" + val run = kit.start(s""" scalajsCom.init(function(msg) {}); var interval = setInterval(scalajsCom.send, 50, "Hello"); setTimeout(clearInterval, 295, interval); - """) - - val deadline = 245.millis.fromNow - - start(com) - - for (i <- 1 to 5) - assertEquals("Hello", com.receive()) + """, RunConfig()) - com.close() - com.await(DefaultTimeout) - - assertTrue("Execution took too little time", deadline.isOverdue()) + try { + val deadline = 245.millis.fromNow + for (i <- 1 to 5) + assertEquals("Hello", run.waitNextMessage()) + assertTrue("Execution took too little time", deadline.isOverdue()) + } finally { + run.closeAndWait() + } } @Test def noMessageTest: Unit = { - val com = comRunner(s""" + val run = kit.start(s""" // Make sure JVM has already closed when we init setTimeout(scalajsCom.init, 1000, function(msg) {}); - """) - start(com) - com.close() - com.await(DefaultTimeout) + """, RunConfig()) + run.closeAndWait() } - - @Test - def stopTestTimeout: Unit = { - - val async = asyncRunner(s""" - setInterval(function() {}, 0); - """) - - start(async) - async.stop() - - try { - async.await(DefaultTimeout) - fail("Expected await to fail") - } catch { - case t: Throwable => // all is well - } - - async.stop() // should do nothing, and not fail - - } - - @Test - def doubleStopTest: Unit = { - val async = asyncRunner(s""" - setInterval(function() {}, 0); - """) - - start(async) - async.stop() - async.stop() // should do nothing, and not fail - - try { - async.await(DefaultTimeout) - fail("Expected await to fail") - } catch { - case t: Throwable => // all is well - } - - async.stop() // should do nothing, and not fail - } - } diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutRunTests.scala similarity index 89% rename from js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutTests.scala rename to js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutRunTests.scala index 2191ef7a04..3c36b2de7a 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutRunTests.scala @@ -1,11 +1,21 @@ package org.scalajs.jsenv.test -import org.junit.Test +import org.scalajs.jsenv.JSEnv + +import org.junit.{Before, Test} import org.junit.Assert._ +import org.junit.Assume._ import scala.concurrent.duration._ -trait TimeoutTests extends JSEnvTest { +private[test] class TimeoutRunTests(config: JSEnvSuiteConfig, withCom: Boolean) { + private val kit = new TestKit(config, withCom) + import kit._ + + @Before + def before: Unit = { + assumeTrue("JSEnv needs timeout support", config.supportsTimeout) + } @Test def basicTimeoutTest: Unit = { diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSEnv.scala deleted file mode 100644 index 4777c4600e..0000000000 --- a/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSEnv.scala +++ /dev/null @@ -1,16 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.jsenv - -import org.scalajs.io.VirtualJSFile - -trait AsyncJSEnv extends JSEnv { - def asyncRunner(files: Seq[VirtualJSFile]): AsyncJSRunner -} diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSRunner.scala b/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSRunner.scala deleted file mode 100644 index 37d45e4523..0000000000 --- a/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSRunner.scala +++ /dev/null @@ -1,80 +0,0 @@ -package org.scalajs.jsenv - -import scala.concurrent.{Future, Await} -import scala.concurrent.duration.Duration - -import org.scalajs.logging.Logger - -trait AsyncJSRunner { - - /** A future that completes when the associated run has terminated. */ - def future: Future[Unit] - - /** - * Start the associated run and returns a Future that completes - * when the run terminates. The returned Future is equivalent to - * the one returned by [[future]]. - */ - def start(logger: Logger, console: JSConsole): Future[Unit] - - /** Aborts the associated run. - * - * There is no guarantee that the runner will be effectively terminated - * by the time this method returns. If necessary, this call can be followed - * by a call to `await()`. - * - * If the run has already completed, this does nothing. Similarly, - * subsequent calls to `stop()` will do nothing. - * - * This method cannot be called before `start()` has been called. - */ - def stop(): Unit - - /** - * Checks whether this async runner is still running. Strictly - * equivalent to - * - * {{{ - * !future.isCompleted - * }}} - */ - final def isRunning(): Boolean = !future.isCompleted - - /** Await completion of the started Run. Strictly equivalent to - * - * {{{ - * Await.result(future, Duration.Inf) - * }}} - */ - final def await(): Unit = Await.result(future, Duration.Inf) - - /** Await completion of the started Run for the duration specified - * by `atMost`. Strictly equivalent to: - * - * {{{ - * Await.result(future, atMost) - * }}} - * - */ - final def await(atMost: Duration): Unit = Await.result(future, atMost) - - /** Awaits completion of the started Run for the duration specified by - * `atMost`, or force it to stop. - * - * If any exception is thrown while awaiting completion (including a - * [[scala.concurrent.TimeoutException TimeoutException]]), forces the runner - * to stop by calling `stop()` before rethrowing the exception. - * - * Strictly equivalent to: - * - * {{{ - * try await(atMost) - * finally stop() - * }}} - */ - final def awaitOrStop(atMost: Duration): Unit = { - try await(atMost) - finally stop() - } - -} diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/ComJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/ComJSEnv.scala deleted file mode 100644 index 3aeeed2b19..0000000000 --- a/js-envs/src/main/scala/org/scalajs/jsenv/ComJSEnv.scala +++ /dev/null @@ -1,42 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.jsenv - -import org.scalajs.io.VirtualJSFile - -/** An [[AsyncJSEnv]] that provides communication to and from the JS VM. - * - * Inside the VM there is a global JavaScript object named `scalajsCom` that - * can be used to control the message channel. It's operations are: - * {{{ - * // initialize com (with callback) - * scalajsCom.init(function(msg) { console.log("Received: " + msg); }); - * - * // send a message to host system - * scalajsCom.send("my message"); - * - * // close com (releases callback, allowing VM to terminate) - * scalajsCom.close(); - * }}} - */ -trait ComJSEnv extends AsyncJSEnv { - def comRunner(files: Seq[VirtualJSFile]): ComJSRunner -} - -object ComJSEnv { - private final val defaultMsg = "JSCom has been closed" - - class ComClosedException(msg: String, - cause: Throwable) extends Exception(msg, cause) { - def this() = this(defaultMsg, null) - def this(cause: Throwable) = this(defaultMsg, cause) - def this(msg: String) = this(msg, null) - } -} diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/ComJSRunner.scala b/js-envs/src/main/scala/org/scalajs/jsenv/ComJSRunner.scala deleted file mode 100644 index 66d24d7db8..0000000000 --- a/js-envs/src/main/scala/org/scalajs/jsenv/ComJSRunner.scala +++ /dev/null @@ -1,41 +0,0 @@ -package org.scalajs.jsenv - -import scala.concurrent.duration.Duration - -trait ComJSRunner extends AsyncJSRunner { - - /** Send a message to the JS VM. Throws if the message cannot be sent. */ - def send(msg: String): Unit - - /** Blocks until a message is received and returns it. - * - * @throws ComJSEnv.ComClosedException if the channel is closed before a - * message is received - */ - final def receive(): String = receive(Duration.Inf) - - /** Blocks until a message is received and returns it. - * - * @throws ComJSEnv.ComClosedException if the channel is closed before a - * message is received - * @throws scala.concurrent.TimeoutException if the timeout expires - * before a message is received and the channel is still open - */ - def receive(timeout: Duration): String - - /** Close the communication channel. Allows the VM to terminate if it is - * still waiting for callback. The JVM side **must** call close in - * order to be able to expect termination of the VM. - * - * Calling [[stop]] on a [ComJSRunner]] automatically closes the - * channel. - */ - def close(): Unit - - /** Abort the associated run. Also closes the communication channel. */ - abstract override def stop(): Unit = { - close() - super.stop() - } - -} diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/ConsoleJSConsole.scala b/js-envs/src/main/scala/org/scalajs/jsenv/ConsoleJSConsole.scala deleted file mode 100644 index 642635049b..0000000000 --- a/js-envs/src/main/scala/org/scalajs/jsenv/ConsoleJSConsole.scala +++ /dev/null @@ -1,17 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.jsenv - -/** A JS console that prints on the console */ -object ConsoleJSConsole extends JSConsole { - override def log(msg: Any): Unit = { - Console.println(msg) - } -} diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala deleted file mode 100644 index 064ced475c..0000000000 --- a/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala +++ /dev/null @@ -1,219 +0,0 @@ -package org.scalajs.jsenv - -import scala.collection.immutable - -import org.scalajs.io._ -import org.scalajs.logging.Logger - -import java.io.{ Console => _, _ } -import scala.io.Source - -import scala.collection.JavaConverters._ -import scala.concurrent.{Future, Promise} -import scala.util.Try - -abstract class ExternalJSEnv extends AsyncJSEnv { - - import ExternalJSEnv._ - - def name: String = s"ExternalJSEnv for $vmName" - - /** Printable name of this VM */ - protected def vmName: String - - /** Command to execute (on shell) for this VM */ - protected def executable: String - - /** Command-line arguments to give to the external process. */ - protected def args: immutable.Seq[String] = Nil - - /** Environment in which to run the external process. */ - protected def env: Map[String, String] = Map.empty - - /** Custom initialization scripts. */ - protected def customInitFiles(): Seq[VirtualJSFile] = Nil - - protected class AbstractExtRunner( - protected val files: Seq[VirtualJSFile]) extends JSInitFiles { - - private[this] var _logger: Logger = _ - private[this] var _console: JSConsole = _ - - protected def logger: Logger = _logger - protected def console: JSConsole = _console - - protected def setupLoggerAndConsole(logger: Logger, console: JSConsole) = { - require(_logger == null && _console == null) - _logger = logger - _console = console - } - - /** Custom initialization scripts, defined by the environment. */ - final protected def customInitFiles(): Seq[VirtualJSFile] = - ExternalJSEnv.this.customInitFiles() - - /** Sends required data to VM Stdin (can throw) */ - protected def sendVMStdin(out: OutputStream): Unit = {} - - /** VM arguments excluding executable. Override to adapt. - * - * The default value in `ExternalJSEnv` is `args`. - */ - protected def getVMArgs(): Seq[String] = args - - /** VM environment. Override to adapt. - * - * The default value in `ExternalJSEnv` is - * `System.getenv().asScala.toMap ++ env`. - */ - protected def getVMEnv(): Map[String, String] = - System.getenv().asScala.toMap ++ env - - /** All the JS files that are passed to the VM. - * - * This method can overridden to provide custom behavior in subclasses. - * - * The default value in `ExternalJSEnv` is - * `initFiles() ++ customInitFiles() ++ files`. - */ - protected def getJSFiles(): Seq[VirtualJSFile] = - initFiles() ++ customInitFiles() ++ files - - /** write a single JS file to a writer using an include fct if appropriate */ - protected def writeJSFile(file: VirtualJSFile, writer: Writer): Unit = { - // The only platform-independent way to do this in JS is to dump the file. - writer.write(file.content) - writer.write('\n') - } - - /** Pipe stdin and stdout from/to VM */ - final protected def pipeVMData(vmInst: Process): Unit = { - // Send stdin to VM. - val out = vmInst.getOutputStream() - try { sendVMStdin(out) } - finally { out.close() } - - // Pipe stdout (and stderr which is merged into it) to console - pipeToConsole(vmInst.getInputStream(), console) - } - - /** Wait for the VM to terminate, verify exit code - * - * @throws ExternalJSEnv.NonZeroExitException if VM returned a non-zero code - */ - final protected def waitForVM(vmInst: Process): Unit = { - // Make sure we are done. - vmInst.waitFor() - - // Get return value and return - val retVal = vmInst.exitValue - if (retVal != 0) - throw new NonZeroExitException(vmName, retVal) - } - - protected def startVM(): Process = { - val vmArgs = getVMArgs() - val vmEnv = getVMEnv() - - val allArgs = executable +: vmArgs - val pBuilder = new ProcessBuilder(allArgs: _*) - pBuilder.redirectErrorStream(true) // merge stderr into stdout - - pBuilder.environment().clear() - for ((name, value) <- vmEnv) - pBuilder.environment().put(name, value) - - logger.debug("Starting process: " + allArgs.mkString(" ")) - - pBuilder.start() - } - - /** send a bunch of JS files to an output stream */ - final protected def sendJS(files: Seq[VirtualJSFile], - out: OutputStream): Unit = { - val writer = new BufferedWriter(new OutputStreamWriter(out, "UTF-8")) - try sendJS(files, writer) - finally writer.close() - } - - /** send a bunch of JS files to a writer */ - final protected def sendJS(files: Seq[VirtualJSFile], out: Writer): Unit = - files.foreach { writeJSFile(_, out) } - - /** pipe lines from input stream to JSConsole */ - final protected def pipeToConsole(in: InputStream, console: JSConsole) = { - val source = Source.fromInputStream(in, "UTF-8") - try { source.getLines.foreach(console.log _) } - finally { source.close() } - } - - } - - protected class ExtRunner(files: Seq[VirtualJSFile]) - extends AbstractExtRunner(files) with JSRunner { - - def run(logger: Logger, console: JSConsole): Unit = { - setupLoggerAndConsole(logger, console) - - val vmInst = startVM() - - pipeVMData(vmInst) - waitForVM(vmInst) - } - } - - protected class AsyncExtRunner(files: Seq[VirtualJSFile]) - extends AbstractExtRunner(files) with AsyncJSRunner { - - private[this] var vmInst: Process = null - private[this] var ioThreadEx: Throwable = null - private[this] val promise = Promise[Unit] - - private[this] val thread = new Thread { - override def run(): Unit = { - // This thread should not be interrupted, so it is safe to use Trys - val pipeResult = Try(pipeVMData(vmInst)) - val vmComplete = Try(waitForVM(vmInst)) - - // Store IO exception - pipeResult recover { - case e => ioThreadEx = e - } - - // Chain Try's the other way: We want VM failure first, then IO failure - promise.complete(pipeResult orElse vmComplete) - } - } - - def future: Future[Unit] = promise.future - - def start(logger: Logger, console: JSConsole): Future[Unit] = { - setupLoggerAndConsole(logger, console) - startExternalJSEnv() - future - } - - /** Core functionality of [[start]]. - * - * Same as [[start]] but without a call to [[setupLoggerAndConsole]] and - * not returning [[future]]. - * Useful to be called in overrides of [[start]]. - */ - protected def startExternalJSEnv(): Unit = { - require(vmInst == null, "start() may only be called once") - vmInst = startVM() - thread.start() - } - - def stop(): Unit = { - require(vmInst != null, "start() must have been called") - vmInst.destroy() - } - } - -} - -object ExternalJSEnv { - final case class NonZeroExitException(vmName: String, retVal: Int) - extends Exception(s"$vmName exited with code $retVal") -} diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSRun.scala b/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSRun.scala new file mode 100644 index 0000000000..215a188f2e --- /dev/null +++ b/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSRun.scala @@ -0,0 +1,196 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js JS Envs ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package org.scalajs.jsenv + +import java.io.{IOException, OutputStream} + +import scala.concurrent.{Future, Promise} +import scala.util.control.NonFatal + +/** Support for creating a [[JSRun]] via an external process. */ +object ExternalJSRun { + /** Starts a [[JSRun]] in an external process. + * + * [[ExternalJSRun]] redirects the I/O of the external process according to + * [[Config#runConfig]]. + * + * @see [[supports]] for the exact options it currently supports. + * + * @param command Binary to execute including arguments. + * @param config Configuration. + * @param input Function to inform about creation of stdin for the external process. + * `input` should feed the required stdin to the passed + * [[java.io.OutputStream OutputStream]] and close it. + */ + def start(command: List[String], config: Config)( + input: OutputStream => Unit): JSRun = { + require(command.nonEmpty, "command may not be empty") + + try { + val process = startProcess(command, config.env, config.runConfig) + try { + notifyOutputStreams(config.runConfig, process) + + new ExternalJSRun(process, input, config.closingFails) + } catch { + case t: Throwable => + process.destroyForcibly() + throw t + } + } catch { + case NonFatal(t) => JSRun.failed(t) + } + } + + /** Informs the given [[RunConfig.Validator]] about the options an + * [[ExternalJSRun]] supports. + * + * Use this method to automatically benefit from improvements to + * [[ExternalJSRun]] without modifying the client [[JSEnv]]. + * + * Currently, this calls + * - [[RunConfig.Validator#supportsInheritIO supportsInheritIO]] + * - [[RunConfig.Validator#supportsOnOutputStream supportsOnOutputStream]] + * + * Note that in consequence, a [[JSEnv]] ''may not'' handle these options if + * it uses [[ExternalJSRun]]. + */ + def supports(validator: RunConfig.Validator): RunConfig.Validator = { + validator + .supportsInheritIO() + .supportsOnOutputStream() + } + + /** Configuration for a [[ExternalJSRun]] + * + * @param env Additional environment variables. The environment of the host + * JVM is inherited. + * @param runConfig Configuration for the run. See [[ExternalJSRun.supports]] + * for details about the currently supported configuration. + * @param closingFails Whether calling [[JSRun#close]] on a still running + * [[JSRun]] fails the run. While this defaults to true, [[JSEnv]]s that + * do not support automatic termination (and do not expect the JS program + * itself to explicitly terminate) typically want to set this to false + * (at least for non-com runs), since otherwise there is no successful + * way of terminating a [[JSRun]]. + */ + final class Config private ( + val env: Map[String, String], + val runConfig: RunConfig, + val closingFails: Boolean + ) { + private def this() = { + this( + env = Map.empty, + runConfig = RunConfig(), + closingFails = true) + } + + def withEnv(env: Map[String, String]): Config = + copy(env = env) + + def withRunConfig(runConfig: RunConfig): Config = + copy(runConfig = runConfig) + + def withClosingFails(closingFails: Boolean): Config = + copy(closingFails = closingFails) + + private def copy(env: Map[String, String] = env, + runConfig: RunConfig = runConfig, + closingFails: Boolean = closingFails) = { + new Config(env, runConfig, closingFails) + } + } + + object Config { + def apply(): Config = new Config() + } + + private def notifyOutputStreams(config: RunConfig, process: Process) = { + def opt[T](b: Boolean, v: => T) = if (b) Some(v) else None + + val out = opt(!config.inheritOutput, process.getInputStream()) + val err = opt(!config.inheritError, process.getErrorStream()) + + config.onOutputStream.foreach(f => f(out, err)) + } + + private def startProcess(command: List[String], env: Map[String, String], + config: RunConfig) = { + val builder = new ProcessBuilder(command: _*) + + if (config.inheritOutput) + builder.redirectOutput(ProcessBuilder.Redirect.INHERIT) + + if (config.inheritError) + builder.redirectError(ProcessBuilder.Redirect.INHERIT) + + for ((name, value) <- env) + builder.environment().put(name, value) + + config.logger.debug("Starting process: " + command.mkString(" ")) + + builder.start() + } + + final case class NonZeroExitException(retVal: Int) + extends Exception(s"exited with code $retVal") + + final case class ClosedException() + extends Exception("Termination was requested by user") +} + +private final class ExternalJSRun(process: Process, + input: OutputStream => Unit, closingFails: Boolean) extends JSRun { + + private[this] val promise = Promise[Unit]() + + @volatile + private[this] var closing = false + + def future: Future[Unit] = promise.future + + def close(): Unit = { + closing = true + process.destroyForcibly() + } + + private val waiter = new Thread { + setName("ExternalJSRun waiter") + + override def run(): Unit = { + try { + try { + input(process.getOutputStream()) + } catch { + case _: IOException if closing => + // We got closed while writing. Exception is expected. + } + + val retVal = process.waitFor() + if (retVal == 0 || closing && !closingFails) + promise.success(()) + else if (closing) + promise.failure(new ExternalJSRun.ClosedException) + else + promise.failure(new ExternalJSRun.NonZeroExitException(retVal)) + } catch { + case t: Throwable => + process.destroyForcibly() + promise.failure(t) + + if (!NonFatal(t)) + throw t + } + } + } + + waiter.start() +} diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/Input.scala b/js-envs/src/main/scala/org/scalajs/jsenv/Input.scala new file mode 100644 index 0000000000..d76029927e --- /dev/null +++ b/js-envs/src/main/scala/org/scalajs/jsenv/Input.scala @@ -0,0 +1,34 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js JS Envs ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package org.scalajs.jsenv + +import org.scalajs.io._ + +/** Input to a [[JSEnv]]. + * + * Implementors of a [[JSEnv]] are expected to pattern match on this input + * type and handle the ones they support. + * + * Note that this type is not sealed, so future versions of Scala.js may add + * additional input types. Older [[JSEnv]]s are expected to fail in this case + * with an [[UnsupportedInputException]]. + */ +abstract class Input private () + +object Input { + /** All files are to be loaded as scripts into the global scope in the order given. */ + final case class ScriptsToLoad(scripts: List[VirtualJSFile]) extends Input +} + +case class UnsupportedInputException(msg: String, cause: Throwable) + extends IllegalArgumentException(msg, cause) { + def this(msg: String) = this(msg, null) + def this(input: Input) = this(s"Unsupported input: $input") +} diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/JSConsole.scala b/js-envs/src/main/scala/org/scalajs/jsenv/JSConsole.scala deleted file mode 100644 index c671ca1c9c..0000000000 --- a/js-envs/src/main/scala/org/scalajs/jsenv/JSConsole.scala +++ /dev/null @@ -1,15 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.jsenv - -/** Trait representing a JS console */ -trait JSConsole { - def log(msg: Any): Unit -} diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala index c7fb0c5412..7d60af72f4 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala @@ -1,6 +1,6 @@ /* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** +** ________ ___ / / ___ __ ____ Scala.js JS Envs ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2017, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** ** /____/\___/_/ |_/____/_/ | |__/ /____/ ** ** |/____/ ** @@ -11,10 +11,72 @@ package org.scalajs.jsenv import org.scalajs.io.VirtualJSFile +/** A JavaScript execution environment. + * + * This can run and interact with JavaScript code. + * + * Any implementation is expected to be fully thread-safe. + */ trait JSEnv { /** Human-readable name for this [[JSEnv]] */ - def name: String + val name: String - /** Prepare a runner with the specified JavaScript files. */ - def jsRunner(files: Seq[VirtualJSFile]): JSRunner + /** Starts a new (asynchronous) JS run. + * + * This may only throw if value of `input` is unknown or `config` cannot be + * supported. To verify whether a [[RunConfig]] can be supported in a forward + * compatible manner (i.e. when new options are added in later versions) + * implementations of [[JSEnv]]s must use [[RunConfig.Validator]]. + * + * This must not throw if the run cannot be started or there is a problem + * with the input's content (e.g. file does not exist, syntax error, etc.). + * In this case, [[JSRun#future]] should be failed instead. + * + * @throws java.lang.IllegalArgumentException if the value of `input` or + * `config` cannot be supported. + */ + def start(input: Input, config: RunConfig): JSRun + + /** Like [[start]], but initializes a communication channel. + * + * Inside the VM this is to provide a global JavaScript object named + * `scalajsCom` that can be used to interact with the message channel. Its + * operations are: + * {{{ + * // initialize com (with callback). May only be called once. + * scalajsCom.init(function(msg) { console.log("Received: " + msg); }); + * + * // send a message to host system + * scalajsCom.send("my message"); + * }}} + * + * We describe the expected message delivery guarantees by denoting the + * transmitter as `t` and the receiver as `r`. Both the JVM and the JS end + * act once as a transmitter and once as a receiver. These two + * transmitter/receiver pairs (JS/JVM and JVM/JS) are independent. + * + * For a pair `(t,r)`: + *
    + *
  • If `t` calls [[JSComRun#send]] exactly in the sequence + * {{{ + * send(m_1), ..., send(m_n) + * }}} + * + * and `r` observes `onMessage(m_k)` (k <= n) but not `onMessage(m_{k+1})`, + * `r` must observe + * {{{ + * onMessage(m_1), ..., onMessage(m_k) + * }}} + * exactly in this order. + *
  • If `t` and `r` keep running indefinitely and `t` sends n messages, + * `r` receives n messages. + *
+ * + * @param onMessage Callback invoked each time a message is received from the + * JS VM. The implementation may not call this anymore once + * [[JSRun#future]] of the returned [[JSComRun]] is completed. Further, + * [[JSRun#future]] may only complete with no callback in-flight. + */ + def startWithCom(input: Input, config: RunConfig, + onMessage: String => Unit): JSComRun } diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/JSInitFiles.scala b/js-envs/src/main/scala/org/scalajs/jsenv/JSInitFiles.scala deleted file mode 100644 index 118ce43251..0000000000 --- a/js-envs/src/main/scala/org/scalajs/jsenv/JSInitFiles.scala +++ /dev/null @@ -1,8 +0,0 @@ -package org.scalajs.jsenv - -import org.scalajs.io.VirtualJSFile - -trait JSInitFiles { - /** JS files used to setup VM */ - protected def initFiles(): Seq[VirtualJSFile] = Nil -} diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/JSRunner.scala b/js-envs/src/main/scala/org/scalajs/jsenv/JSRunner.scala deleted file mode 100644 index 8981947ba9..0000000000 --- a/js-envs/src/main/scala/org/scalajs/jsenv/JSRunner.scala +++ /dev/null @@ -1,17 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.jsenv - -import org.scalajs.logging.Logger - -trait JSRunner { - /** Run the associated JS code. Throw if an error occurs. */ - def run(logger: Logger, console: JSConsole): Unit -} diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/JSRuns.scala b/js-envs/src/main/scala/org/scalajs/jsenv/JSRuns.scala new file mode 100644 index 0000000000..cbdb1235c5 --- /dev/null +++ b/js-envs/src/main/scala/org/scalajs/jsenv/JSRuns.scala @@ -0,0 +1,76 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js JS Envs ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package org.scalajs.jsenv + +import scala.concurrent.Future + +/** A launched instance of a [[JSEnv]]. + * + * This is the interface to actually running JS code (whether this is in + * process or not depens on the [[JSEnv]] that created the [[JSRun]]). + * + * Any implementation is expected to be fully thread-safe. + */ +trait JSRun extends AutoCloseable { + /** A [[scala.concurrent.Future Future]] that completes if the run completes. + * + * The future is failed if the run fails. + * + * Note that a [[JSRun]] is not required to ever terminate on it's own. That + * means even if all code is executed and the event loop is empty, the run + * may continue to run. As a consequence, it is *not* correct to rely on + * termination of a [[JSRun]] without any external means of stopping it + * (i.e. calling [[close]]). + */ + def future: Future[Unit] + + /** Stops the run and releases all the resources. + * + * This must be called to ensure the run's resources are + * released. + * + * Whether or not this makes the run fail or not is up to the implementation. + * However, in the following cases, calling [[close]] may not fail the run: + *
    + *
  • [[future]] is already completed when [[close]] is called. + *
  • This is a [[JSComRun]] and the event loop inside the VM is empty. + *
+ * + * Idempotent, async, nothrow. + */ + def close(): Unit +} + +object JSRun { + /** Creates a [[JSRun]] that has failed. */ + def failed(cause: Throwable): JSRun = new JSRun { + def close(): Unit = () + val future: Future[Unit] = Future.failed(cause) + } +} + +/** A [[JSRun]] that has a communication channel to the running JS code. */ +trait JSComRun extends JSRun { + /** Sends a message to the JS end. + * + * Async, nothrow. See [[JSEnv#startWithCom]] for expected message delivery + * guarantees. + */ + def send(msg: String): Unit +} + +object JSComRun { + /** Creates a [[JSComRun]] that has failed. */ + def failed(cause: Throwable): JSComRun = new JSComRun { + def close(): Unit = () + val future: Future[Unit] = Future.failed(cause) + def send(msg: String): Unit = () + } +} diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/NullJSConsole.scala b/js-envs/src/main/scala/org/scalajs/jsenv/NullJSConsole.scala deleted file mode 100644 index 24b677d974..0000000000 --- a/js-envs/src/main/scala/org/scalajs/jsenv/NullJSConsole.scala +++ /dev/null @@ -1,5 +0,0 @@ -package org.scalajs.jsenv - -object NullJSConsole extends JSConsole { - def log(msg: Any): Unit = {} -} diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/RunConfig.scala b/js-envs/src/main/scala/org/scalajs/jsenv/RunConfig.scala new file mode 100644 index 0000000000..83d782043e --- /dev/null +++ b/js-envs/src/main/scala/org/scalajs/jsenv/RunConfig.scala @@ -0,0 +1,160 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js JS Envs ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package org.scalajs.jsenv + +import java.io.InputStream + +import org.scalajs.logging._ + +/** Configuration provided when starting a [[JSEnv]]. + * + * @param onOutputStream Callback once output streams of the JS VM run become available. + * + * The callback receives the output and the error stream of the VM if they + * are available. If [[inheritOutput]] or [[inheritError]] are set to true, the + * respective streams must be `None`, in the invocation of + * [[onOutputStream]]. Note however, that if [[onOutputStream]] is present, + * it must be invoked by the JS VM. + * + * @param inheritOutput Whether the output stream of the VM should be inherited. + * + * The implementation may chose to redirect to the actual output stream of + * the parent JVM or simply [[scala.Console#out]]. + * + * If you set this value to `false` you must set [[onOutputStream]]. + * + * @param inheritError Whether the error stream of the VM should be inherited. + * + * The implementation may chose to redirect to the actual error stream of the + * parent JVM or simply [[scala.Console#err]]. + * + * If you set this value to `false` you must set [[onOutputStream]]. + * + * @param logger The logger to use in the run. A [[JSEnv]] is not required to + * log anything. + */ +final class RunConfig private ( + val onOutputStream: Option[RunConfig.OnOutputStream], + val inheritOutput: Boolean, + val inheritError: Boolean, + val logger: Logger, + /** An option that will never be supported by anything because it is not exposed. + * + * This is used to test that [[JSEnv]]s properly validate their configuration. + */ + private[jsenv] val eternallyUnsupportedOption: Boolean +) { + import RunConfig.OnOutputStream + + private def this() = { + this( + onOutputStream = None, + inheritOutput = true, + inheritError = true, + logger = NullLogger, + eternallyUnsupportedOption = false) + } + + def withOnOutputStream(onOutputStream: OnOutputStream): RunConfig = + copy(onOutputStream = Some(onOutputStream)) + + def withInheritOut(inheritOutput: Boolean): RunConfig = + copy(inheritOutput = inheritOutput) + + def withInheritErr(inheritError: Boolean): RunConfig = + copy(inheritError = inheritError) + + def withLogger(logger: Logger): RunConfig = + copy(logger = logger) + + private[jsenv] def withEternallyUnsupportedOption( + eternallyUnsupportedOption: Boolean): RunConfig = + copy(eternallyUnsupportedOption = eternallyUnsupportedOption) + + private def copy(onOutputStream: Option[OnOutputStream] = onOutputStream, + inheritOutput: Boolean = inheritOutput, + inheritError: Boolean = inheritError, + logger: Logger = logger, + eternallyUnsupportedOption: Boolean = eternallyUnsupportedOption + ): RunConfig = { + new RunConfig(onOutputStream, inheritOutput, inheritError, logger, + eternallyUnsupportedOption) + } + + /** Validates constraints on the config itself. */ + private def validate(): Unit = { + if (onOutputStream.isEmpty && (!inheritOutput || !inheritError)) { + throw new IllegalArgumentException("You may not set inheritOutput or " + + "inheritError to false without setting onOutputStream.") + } + } +} + +final object RunConfig { + type OnOutputStream = (Option[InputStream], Option[InputStream]) => Unit + def apply(): RunConfig = new RunConfig() + + /** Support validator for [[RunConfig]]. + * + * Validators allow us to add options to [[RunConfig]] in a forward + * compatible manner. + * + * Every [[JSEnv]] must + * + * 1. create a [[Validator]] + * 1. inform it of the [[JSEnv]]'s capabilities + * 1. invoke [[validate]] with every received [[RunConfig]] + * + * This ensures that enusre that all set config options are supported by the + * [[JSEnv]]. + */ + final class Validator private ( + inheritIO: Boolean, + onOutputStream: Boolean + ) { + private def this() = this(false, false) + + /** The caller supports [[RunConfig#inheritOutput]] and + * [[RunConfig#inheritError]]. + */ + def supportsInheritIO(): Validator = copy(inheritIO = true) + + /** The caller supports [[RunConfig#onOutputStream]]. */ + def supportsOnOutputStream(): Validator = copy(onOutputStream = true) + + /** Validates that `config` is valid and only sets supported options. + * + * @throws java.lang.IllegalArgumentException if there are unsupported options. + */ + def validate(config: RunConfig): Unit = { + def fail(msg: String) = throw new IllegalArgumentException(msg) + + config.validate() + + if (!inheritIO && (config.inheritOutput || config.inheritError)) + fail("inheritOutput / inheritError are not supported.") + + if (!onOutputStream && config.onOutputStream.isDefined) + fail("onOutputStream is not supported.") + + if (config.eternallyUnsupportedOption) + fail("eternallyUnsupportedOption is not supported.") + } + + private def copy(inheritIO: Boolean = inheritIO, + onOutputStream: Boolean = onOutputStream) = { + new Validator(inheritIO, onOutputStream) + } + } + + object Validator { + def apply(): Validator = new Validator() + } +} diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/Utils.scala b/js-envs/src/main/scala/org/scalajs/jsenv/Utils.scala deleted file mode 100644 index 6f921a5dde..0000000000 --- a/js-envs/src/main/scala/org/scalajs/jsenv/Utils.scala +++ /dev/null @@ -1,38 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js JS environments ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.jsenv - -import scala.concurrent.duration._ - -private[jsenv] object Utils { - final class OptDeadline private ( - val __private_deadline: Deadline /* nullable */) // scalastyle:ignore - extends AnyVal { - - @inline private def deadline: Deadline = __private_deadline - - def millisLeft: Long = - if (deadline == null) 0 - else (deadline.timeLeft.toMillis max 1L) - - def isOverdue: Boolean = - if (deadline == null) false - else deadline.isOverdue - } - - object OptDeadline { - def apply(timeout: Duration): OptDeadline = { - new OptDeadline(timeout match { - case timeout: FiniteDuration => timeout.fromNow - case _ => null - }) - } - } -} diff --git a/js-envs/src/test/scala/org/scalajs/jsenv/RunConfigTest.scala b/js-envs/src/test/scala/org/scalajs/jsenv/RunConfigTest.scala new file mode 100644 index 0000000000..a4734aa5b1 --- /dev/null +++ b/js-envs/src/test/scala/org/scalajs/jsenv/RunConfigTest.scala @@ -0,0 +1,88 @@ +package org.scalajs.jsenv + +import org.junit.Test + +class RunConfigTest { + @Test + def supportedInheritIO: Unit = { + val cfg = RunConfig() + .withInheritOut(true) + .withInheritErr(true) + RunConfig.Validator() + .supportsInheritIO() + .validate(cfg) + } + + @Test(expected = classOf[IllegalArgumentException]) + def unsupportedInheritOut: Unit = { + val cfg = RunConfig() + .withInheritOut(true) + .withInheritErr(false) + .withOnOutputStream((_, _) => ()) + RunConfig.Validator() + .supportsOnOutputStream() + .validate(cfg) + } + + @Test(expected = classOf[IllegalArgumentException]) + def unsupportedInheritErr: Unit = { + val cfg = RunConfig() + .withInheritOut(false) + .withInheritErr(true) + .withOnOutputStream((_, _) => ()) + RunConfig.Validator() + .supportsOnOutputStream() + .validate(cfg) + } + + @Test + def supportedOnOutputStream: Unit = { + val cfg = RunConfig() + .withInheritOut(false) + .withInheritErr(false) + .withOnOutputStream((_, _) => ()) + RunConfig.Validator() + .supportsOnOutputStream() + .validate(cfg) + } + + @Test(expected = classOf[IllegalArgumentException]) + def unsupportedOnOutputStream: Unit = { + val cfg = RunConfig() + .withInheritOut(false) + .withInheritErr(false) + .withOnOutputStream((_, _) => ()) + RunConfig.Validator() + .validate(cfg) + } + + @Test(expected = classOf[IllegalArgumentException]) + def missingOnOutputStreamNoInheritOut: Unit = { + val cfg = RunConfig() + .withInheritOut(false) + .withInheritErr(true) + RunConfig.Validator() + .supportsInheritIO() + .supportsOnOutputStream() + .validate(cfg) + } + + @Test(expected = classOf[IllegalArgumentException]) + def missingOnOutputStreamNoInheritErr: Unit = { + val cfg = RunConfig() + .withInheritOut(true) + .withInheritErr(false) + RunConfig.Validator() + .supportsInheritIO() + .supportsOnOutputStream() + .validate(cfg) + } + + @Test(expected = classOf[IllegalArgumentException]) + def failValidationForTest: Unit = { + val cfg = RunConfig() + .withEternallyUnsupportedOption(true) + RunConfig.Validator() + .validate(cfg) + } +} diff --git a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala deleted file mode 100644 index 818ac44d91..0000000000 --- a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala +++ /dev/null @@ -1,311 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.jsenv.nodejs - -import java.io.{Console => _, _} -import java.net._ - -import org.scalajs.io._ -import org.scalajs.io.JSUtils.escapeJS -import org.scalajs.logging.NullLogger - -import org.scalajs.jsenv._ -import org.scalajs.jsenv.Utils.OptDeadline - -import scala.collection.JavaConverters._ -import scala.concurrent.TimeoutException -import scala.concurrent.duration._ - -abstract class AbstractNodeJSEnv extends ExternalJSEnv with ComJSEnv { - - protected def wantSourceMap: Boolean = true - - /** True, if the installed node executable supports source mapping. - * - * Do `npm install source-map-support` if you need source maps. - */ - lazy val hasSourceMapSupport: Boolean = { - val code = new MemVirtualJSFile("source-map-support-probe.js") - .withContent("""require('source-map-support').install();""") - - try { - jsRunner(Seq(code)).run(NullLogger, NullJSConsole) - true - } catch { - case t: ExternalJSEnv.NonZeroExitException => - false - } - } - - /** Retry-timeout to wait for the JS VM to connect */ - protected val acceptTimeout = 5000 - - protected trait AbstractNodeRunner extends AbstractExtRunner with JSInitFiles { - - protected[this] val libCache = new VirtualFileMaterializer(true) - - /** File(s) to automatically install source-map-support. - * Is used by [[initFiles]], override to change/disable. - */ - protected def installSourceMap(): Seq[VirtualJSFile] = { - if (wantSourceMap) { - val content = - """ - |try { - | require('source-map-support').install(); - |} catch (e) {} - """.stripMargin - Seq(new MemVirtualJSFile("sourceMapSupport.js").withContent(content)) - } else { - Seq() - } - } - - /** File(s) to hack console.log to prevent if from changing `%%` to `%`. - * Is used by [[initFiles]], override to change/disable. - */ - protected def fixPercentConsole(): Seq[VirtualJSFile] = Seq( - new MemVirtualJSFile("nodeConsoleHack.js").withContent( - """ - |// Hack console log to duplicate double % signs - |(function() { - | function startsWithAnyOf(s, prefixes) { - | for (var i = 0; i < prefixes.length; i++) { - | // ES5 does not have .startsWith() on strings - | if (s.substring(0, prefixes[i].length) === prefixes[i]) - | return true; - | } - | return false; - | } - | var nodeWillDeduplicateEvenForOneArgument = startsWithAnyOf( - | process.version, ["v0.", "v1.", "v2.0."]); - | var oldLog = console.log; - | var newLog = function() { - | var args = arguments; - | if (args.length >= 1 && args[0] !== void 0 && args[0] !== null) { - | var argStr = args[0].toString(); - | if (args.length > 1 || nodeWillDeduplicateEvenForOneArgument) - | argStr = argStr.replace(/%/g, "%%"); - | args[0] = argStr; - | } - | oldLog.apply(console, args); - | }; - | console.log = newLog; - |})(); - """.stripMargin - ) - ) - - - /** File(s) to define `__ScalaJSEnv`. Defines `exitFunction`. - * Is used by [[initFiles]], override to change/disable. - */ - protected def runtimeEnv(): Seq[VirtualJSFile] = Seq( - new MemVirtualJSFile("scalaJSEnvInfo.js").withContent( - """ - |__ScalaJSEnv = { - | exitFunction: function(status) { process.exit(status); } - |}; - """.stripMargin - ) - ) - - override protected def initFiles(): Seq[VirtualJSFile] = - installSourceMap() ++ fixPercentConsole() ++ runtimeEnv() - - /** write a single JS file to a writer using an include fct if appropriate - * uses `require` if the file exists on the filesystem - */ - override protected def writeJSFile(file: VirtualJSFile, - writer: Writer): Unit = { - file match { - case file: FileVirtualJSFile => - val fname = file.file.getAbsolutePath - writer.write(s"""require("${escapeJS(fname)}");\n""") - case _ => - super.writeJSFile(file, writer) - } - } - - // Node.js specific (system) environment - override protected def getVMEnv(): Map[String, String] = { - val baseNodePath = Option(System.getenv("NODE_PATH")).filter(_.nonEmpty) - val nodePath = libCache.cacheDir.getAbsolutePath + - baseNodePath.fold("")(p => File.pathSeparator + p) - - System.getenv().asScala.toMap ++ Seq( - "NODE_MODULE_CONTEXTS" -> "0", - "NODE_PATH" -> nodePath - ) ++ env - } - } - - protected trait NodeComJSRunner extends ComJSRunner with JSInitFiles { - - private[this] val serverSocket = - new ServerSocket(0, 0, InetAddress.getByName(null)) // Loopback address - private var comSocket: Socket = _ - private var jvm2js: DataOutputStream = _ - private var js2jvm: DataInputStream = _ - - abstract override protected def initFiles(): Seq[VirtualJSFile] = - super.initFiles :+ comSetup - - private def comSetup(): VirtualJSFile = { - new MemVirtualJSFile("comSetup.js").withContent( - s""" - |(function() { - | // The socket for communication - | var socket = null; - | // The callback where received messages go - | var recvCallback = null; - | - | // Buffers received data - | var inBuffer = new Buffer(0); - | - | function onData(data) { - | inBuffer = Buffer.concat([inBuffer, data]); - | tryReadMsg(); - | } - | - | function tryReadMsg() { - | while (inBuffer.length >= 4) { - | var msgLen = inBuffer.readInt32BE(0); - | var byteLen = 4 + msgLen * 2; - | - | if (inBuffer.length < byteLen) return; - | var res = ""; - | - | for (var i = 0; i < msgLen; ++i) - | res += String.fromCharCode(inBuffer.readInt16BE(4 + i * 2)); - | - | inBuffer = inBuffer.slice(byteLen); - | - | recvCallback(res); - | } - | } - | - | global.scalajsCom = { - | init: function(recvCB) { - | if (socket !== null) throw new Error("Com already open"); - | - | var net = require('net'); - | recvCallback = recvCB; - | socket = net.connect(${serverSocket.getLocalPort}); - | socket.on('data', onData); - | socket.on('error', function(err) { - | // Whatever happens, this closes the Com - | socket.end(); - | - | // Expected errors: - | // - EPIPE on write: JVM closes - | // - ECONNREFUSED on connect: JVM closes before JS opens - | var expected = ( - | err.syscall === "write" && err.code === "EPIPE" || - | err.syscall === "connect" && err.code === "ECONNREFUSED" - | ); - | - | if (!expected) { - | console.error("Scala.js Com failed: " + err); - | // We must terminate with an error - | process.exit(-1); - | } - | }); - | }, - | send: function(msg) { - | if (socket === null) throw new Error("Com not open"); - | - | var len = msg.length; - | var buf = new Buffer(4 + len * 2); - | buf.writeInt32BE(len, 0); - | for (var i = 0; i < len; ++i) - | buf.writeUInt16BE(msg.charCodeAt(i), 4 + i * 2); - | socket.write(buf); - | }, - | close: function() { - | if (socket === null) throw new Error("Com not open"); - | socket.end(); - | } - | } - |}).call(this); - """.stripMargin) - } - - def send(msg: String): Unit = { - if (awaitConnection()) { - jvm2js.writeInt(msg.length) - jvm2js.writeChars(msg) - jvm2js.flush() - } - } - - def receive(timeout: Duration): String = { - if (!awaitConnection()) - throw new ComJSEnv.ComClosedException("Node.js isn't connected") - - js2jvm.mark(Int.MaxValue) - val savedSoTimeout = comSocket.getSoTimeout() - try { - val optDeadline = OptDeadline(timeout) - - comSocket.setSoTimeout((optDeadline.millisLeft min Int.MaxValue).toInt) - val len = js2jvm.readInt() - val carr = Array.fill(len) { - comSocket.setSoTimeout((optDeadline.millisLeft min Int.MaxValue).toInt) - js2jvm.readChar() - } - - js2jvm.mark(0) - String.valueOf(carr) - } catch { - case e: EOFException => - throw new ComJSEnv.ComClosedException(e) - case e: SocketTimeoutException => - js2jvm.reset() - throw new TimeoutException("Timeout expired") - } finally { - comSocket.setSoTimeout(savedSoTimeout) - } - } - - def close(): Unit = { - serverSocket.close() - if (jvm2js != null) - jvm2js.close() - if (js2jvm != null) - js2jvm.close() - if (comSocket != null) - comSocket.close() - } - - /** Waits until the JS VM has established a connection or terminates - * - * @return true if the connection was established - */ - private def awaitConnection(): Boolean = { - serverSocket.setSoTimeout(acceptTimeout) - while (comSocket == null && isRunning) { - try { - comSocket = serverSocket.accept() - jvm2js = new DataOutputStream( - new BufferedOutputStream(comSocket.getOutputStream())) - js2jvm = new DataInputStream( - new BufferedInputStream(comSocket.getInputStream())) - } catch { - case to: SocketTimeoutException => - } - } - - comSocket != null - } - - override protected def finalize(): Unit = close() - } -} diff --git a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/ComSupport.scala b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/ComSupport.scala new file mode 100644 index 0000000000..aa03c859f3 --- /dev/null +++ b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/ComSupport.scala @@ -0,0 +1,302 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Node.js env ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package org.scalajs.jsenv.nodejs + +import java.io._ +import java.net._ + +import org.scalajs.io.{VirtualJSFile, MemVirtualJSFile} +import org.scalajs.jsenv._ + +import scala.collection.immutable +import scala.concurrent._ +import scala.util.{Failure, Success} +import scala.util.control.NonFatal + +// TODO Replace this by a better execution context on the RunConfig. +import scala.concurrent.ExecutionContext.Implicits.global + +private final class ComRun(run: JSRun, handleMessage: String => Unit, + serverSocket: ServerSocket) extends JSComRun { + import ComRun._ + + /** Promise that completes once the reciever thread is completed. */ + private[this] val promise = Promise[Unit]() + + @volatile + private[this] var state: State = AwaitingConnection(Nil) + + // If the run completes, make sure we also complete. + run.future.onComplete { + case Failure(t) => forceClose(t) + case Success(_) => onJSTerminated() + } + + // TODO replace this with scheduled tasks on the execution context. + private[this] val receiver = new Thread { + setName("ComRun receiver") + + override def run(): Unit = { + try { + try { + /* We need to await the connection unconditionally. Otherwise the JS end + * might try to connect indefinitely. + */ + awaitConnection() + + while (state != Closing) { + state match { + case s: AwaitingConnection => + throw new IllegalStateException(s"Unexpected state: $s") + + case Closing => + /* We can end up here if there is a race between the two read to + * state. Do nothing, loop will terminate. + */ + + case Connected(_, _, js2jvm) => + try { + val len = js2jvm.readInt() + val carr = Array.fill(len)(js2jvm.readChar()) + handleMessage(String.valueOf(carr)) + } catch { + case _: EOFException => + // JS end terminated gracefully. Close. + close() + } + } + } + } catch { + case _: IOException if state == Closing => + // We got interrupted by a graceful close. + // This is OK. + } + + /* Everything got closed. We wait for the run to terminate. + * We need to wait in order to make sure that closing the + * underlying run does not fail it. + */ + ComRun.this.run.future.foreach { _ => + ComRun.this.run.close() + promise.trySuccess(()) + } + } catch { + case t: Throwable => handleThrowable(t) + } + } + } + + receiver.start() + + def future: Future[Unit] = promise.future + + def send(msg: String): Unit = synchronized { + state match { + case AwaitingConnection(msgs) => + state = AwaitingConnection(msg :: msgs) + + case Connected(_, jvm2js, _) => + try { + writeMsg(jvm2js, msg) + jvm2js.flush() + } catch { + case t: Throwable => handleThrowable(t) + } + + case Closing => // ignore msg. + } + } + + def close(): Unit = synchronized { + val oldState = state + + // Signal receiver thread that it is OK if socket read fails. + state = Closing + + oldState match { + case c: Connected => + // Interrupts the receiver thread and signals the VM to terminate. + closeAll(c) + + case Closing | _:AwaitingConnection => + } + } + + private def onJSTerminated() = { + close() + + /* Interrupt receiver if we are still waiting for connection. + * Should only be relevant if we are still awaiting the connection. + * Note: We cannot do this in close(), otherwise if the JVM side closes + * before the JS side connected, the JS VM will fail instead of terminate + * normally. + */ + serverSocket.close() + } + + private def forceClose(cause: Throwable) = { + promise.tryFailure(cause) + close() + run.close() + serverSocket.close() + } + + private def handleThrowable(cause: Throwable) = { + forceClose(cause) + if (!NonFatal(cause)) + throw cause + } + + private def awaitConnection(): Unit = { + var comSocket: Socket = null + var jvm2js: DataOutputStream = null + var js2jvm: DataInputStream = null + + try { + comSocket = serverSocket.accept() + serverSocket.close() // we don't need it anymore. + jvm2js = new DataOutputStream( + new BufferedOutputStream(comSocket.getOutputStream())) + js2jvm = new DataInputStream( + new BufferedInputStream(comSocket.getInputStream())) + + onConnected(Connected(comSocket, jvm2js, js2jvm)) + } catch { + case t: Throwable => + closeAll(comSocket, jvm2js, js2jvm) + throw t + } + } + + private def onConnected(c: Connected): Unit = synchronized { + state match { + case AwaitingConnection(msgs) => + msgs.reverse.foreach(writeMsg(c.jvm2js, _)) + c.jvm2js.flush() + state = c + + case _: Connected => + throw new IllegalStateException(s"Unexpected state: $state") + + case Closing => + closeAll(c) + } + } +} + +object ComRun { + /** Starts a [[JSComRun]] using the provided [[JSRun]] launcher. + * + * @param config Configuration for the run. + * @param onMessage callback upon message reception. + * @param startRun [[JSRun]] launcher. Gets passed a + * [[org.scalajs.io.VirtualJSFile VirtualJSFile]] that + * initializes `scalaJSCom` on `global`. Requires Node.js libraries. + */ + def start(config: RunConfig, onMessage: String => Unit)( + startRun: VirtualJSFile => JSRun): JSComRun = { + try { + val serverSocket = + new ServerSocket(0, 0, InetAddress.getByName(null)) // Loopback address + + val run = startRun(setupFile(serverSocket.getLocalPort)) + + new ComRun(run, onMessage, serverSocket) + } catch { + case NonFatal(t) => JSComRun.failed(t) + } + } + + private def closeAll(c: Closeable*): Unit = + c.withFilter(_ != null).foreach(_.close()) + + private def closeAll(c: Connected): Unit = + closeAll(c.comSocket, c.jvm2js, c.js2jvm) + + private sealed trait State + + private final case class AwaitingConnection( + sendQueue: List[String]) extends State + + private final case class Connected( + comSocket: Socket, + jvm2js: DataOutputStream, + js2jvm: DataInputStream) extends State + + private final case object Closing extends State + + private def writeMsg(s: DataOutputStream, msg: String): Unit = { + s.writeInt(msg.length) + s.writeChars(msg) + } + + private def setupFile(port: Int): VirtualJSFile = { + new MemVirtualJSFile("comSetup.js").withContent( + s""" + |(function() { + | // The socket for communication + | var socket = require('net').connect($port); + | + | // Buffers received data + | var inBuffer = new Buffer(0); + | + | // Buffers received messages + | var inMessages = []; + | + | // The callback where received messages go + | var recvCallback = function(msg) { inMessages.push(msg); }; + | + | socket.on('data', function(data) { + | inBuffer = Buffer.concat([inBuffer, data]); + | + | while (inBuffer.length >= 4) { + | var msgLen = inBuffer.readInt32BE(0); + | var byteLen = 4 + msgLen * 2; + | + | if (inBuffer.length < byteLen) return; + | var res = ""; + | + | for (var i = 0; i < msgLen; ++i) + | res += String.fromCharCode(inBuffer.readInt16BE(4 + i * 2)); + | + | inBuffer = inBuffer.slice(byteLen); + | + | recvCallback(res); + | } + | }); + | + | socket.on('error', function(err) { + | console.error("Scala.js Com failed: " + err); + | process.exit(-1); + | }); + | + | socket.on('close', function() { process.exit(0); }); + | + | global.scalajsCom = { + | init: function(recvCB) { + | if (inMessages === null) throw new Error("Com already initialized"); + | for (var i = 0; i < inMessages.length; ++i) + | recvCB(inMessages[i]); + | inMessages = null; + | recvCallback = recvCB; + | }, + | send: function(msg) { + | var len = msg.length; + | var buf = new Buffer(4 + len * 2); + | buf.writeInt32BE(len, 0); + | for (var i = 0; i < len; ++i) + | buf.writeUInt16BE(msg.charCodeAt(i), 4 + i * 2); + | socket.write(buf); + | } + | } + |}).call(this); + """.stripMargin) + } +} diff --git a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala index 9ff544e3bf..dfdf3e5dff 100644 --- a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala +++ b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala @@ -1,6 +1,6 @@ /* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** +** ________ ___ / / ___ __ ____ Scala.js Node.js env ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2017, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** ** /____/\___/_/ |_/____/_/ | |__/ /____/ ** ** |/____/ ** @@ -9,63 +9,98 @@ package org.scalajs.jsenv.nodejs +import java.nio.charset.StandardCharsets + import scala.collection.immutable +import scala.collection.JavaConverters._ import org.scalajs.jsenv._ import org.scalajs.io._ +import org.scalajs.io.JSUtils.escapeJS import org.scalajs.logging._ -import java.io.{ Console => _, _ } - -class NodeJSEnv(config: NodeJSEnv.Config) extends AbstractNodeJSEnv { +import java.io._ +final class NodeJSEnv(config: NodeJSEnv.Config) extends JSEnv { def this() = this(NodeJSEnv.Config()) - protected def vmName: String = "Node.js" + val name: String = "Node.js" - protected def executable: String = config.executable - - override protected def args: immutable.Seq[String] = config.args + def start(input: Input, runConfig: RunConfig): JSRun = { + NodeJSEnv.validator.validate(runConfig) + internalStart(initFiles ++ inputFiles(input), runConfig) + } - override protected def env: Map[String, String] = config.env + def startWithCom(input: Input, runConfig: RunConfig, + onMessage: String => Unit): JSComRun = { + NodeJSEnv.validator.validate(runConfig) + ComRun.start(runConfig, onMessage) { comLoader => + val files = initFiles ::: (comLoader :: inputFiles(input)) + internalStart(files, runConfig) + } + } - // TODO Our Build wants this to be public, but it does not seem clean - override def wantSourceMap: Boolean = config.sourceMap + private def internalStart(files: List[VirtualJSFile], + runConfig: RunConfig): JSRun = { + val command = config.executable :: config.args + val externalConfig = ExternalJSRun.Config() + .withEnv(env) + .withRunConfig(runConfig) + ExternalJSRun.start(command, externalConfig)(NodeJSEnv.write(files)) + } - override def jsRunner(files: Seq[VirtualJSFile]): JSRunner = - new NodeRunner(files) + private def initFiles: List[VirtualJSFile] = { + val base = List(NodeJSEnv.runtimeEnv, Support.fixPercentConsole) - override def asyncRunner(files: Seq[VirtualJSFile]): AsyncJSRunner = - new AsyncNodeRunner(files) + if (config.sourceMap) NodeJSEnv.installSourceMap :: base + else base + } - override def comRunner(files: Seq[VirtualJSFile]): ComJSRunner = - new ComNodeRunner(files) + private def inputFiles(input: Input) = input match { + case Input.ScriptsToLoad(scripts) => scripts + case _ => throw new UnsupportedInputException(input) + } - protected class NodeRunner(files: Seq[VirtualJSFile]) - extends ExtRunner(files) with AbstractBasicNodeRunner + private def env: Map[String, String] = + Map("NODE_MODULE_CONTEXTS" -> "0") ++ config.env +} - protected class AsyncNodeRunner(files: Seq[VirtualJSFile]) - extends AsyncExtRunner(files) with AbstractBasicNodeRunner +object NodeJSEnv { + private lazy val validator = ExternalJSRun.supports(RunConfig.Validator()) - protected class ComNodeRunner(files: Seq[VirtualJSFile]) - extends AsyncNodeRunner(files) with NodeComJSRunner + private lazy val installSourceMap = { + new MemVirtualJSFile("sourceMapSupport.js").withContent( + "require('source-map-support').install();") + } - protected trait AbstractBasicNodeRunner extends AbstractNodeRunner { + private lazy val runtimeEnv = { + new MemVirtualJSFile("scalaJSEnvInfo.js").withContent( + """ + |__ScalaJSEnv = { + | exitFunction: function(status) { process.exit(status); } + |}; + """.stripMargin + ) + } - // Send code to Stdin - override protected def sendVMStdin(out: OutputStream): Unit = { - /* Do not factor this method out into AbstractNodeRunner or when mixin in - * the traits it would use AbstractExtRunner.sendVMStdin due to - * linearization order. - */ - sendJS(getJSFiles(), out) + private def write(files: List[VirtualJSFile])(out: OutputStream): Unit = { + val writer = new BufferedWriter( + new OutputStreamWriter(out, StandardCharsets.UTF_8)) + try { + files.foreach { + case file: FileVirtualJSFile => + val fname = file.file.getAbsolutePath + writer.write(s"""require("${escapeJS(fname)}");\n""") + case f => + IO.writeTo(f, writer) + writer.write('\n') + } + } finally { + writer.close() } } -} - -object NodeJSEnv { final class Config private ( val executable: String, val args: List[String], diff --git a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/Support.scala b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/Support.scala new file mode 100644 index 0000000000..f48bac1190 --- /dev/null +++ b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/Support.scala @@ -0,0 +1,44 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Node.js env ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package org.scalajs.jsenv.nodejs + +import org.scalajs.io._ + +object Support { + def fixPercentConsole: VirtualJSFile = { + new MemVirtualJSFile("nodeConsoleHack.js").withContent( + """ + |// Hack console log to duplicate double % signs + |(function() { + | function startsWithAnyOf(s, prefixes) { + | for (var i = 0; i < prefixes.length; i++) { + | // ES5 does not have .startsWith() on strings + | if (s.substring(0, prefixes[i].length) === prefixes[i]) + | return true; + | } + | return false; + | } + | var oldLog = console.log; + | var newLog = function() { + | var args = arguments; + | if (args.length >= 1 && args[0] !== void 0 && args[0] !== null) { + | var argStr = args[0].toString(); + | if (args.length > 1) + | argStr = argStr.replace(/%/g, "%%"); + | args[0] = argStr; + | } + | oldLog.apply(console, args); + | }; + | console.log = newLog; + |})(); + """.stripMargin + ) + } +} diff --git a/nodejs-env/src/test/scala/org/scalajs/jsenv/nodejs/NodeJSSuite.scala b/nodejs-env/src/test/scala/org/scalajs/jsenv/nodejs/NodeJSSuite.scala new file mode 100644 index 0000000000..631044758d --- /dev/null +++ b/nodejs-env/src/test/scala/org/scalajs/jsenv/nodejs/NodeJSSuite.scala @@ -0,0 +1,11 @@ +package org.scalajs.jsenv.nodejs + +import org.scalajs.jsenv.test._ + +import org.junit.runner.RunWith + +@RunWith(classOf[JSEnvSuiteRunner]) +class NodeJSSuite extends JSEnvSuite( + JSEnvSuiteConfig(new NodeJSEnv) + .withTerminateVMJSCode("process.exit(0)") +) diff --git a/nodejs-env/src/test/scala/org/scalajs/jsenv/nodejs/NodeJSTest.scala b/nodejs-env/src/test/scala/org/scalajs/jsenv/nodejs/NodeJSTest.scala deleted file mode 100644 index 764d8ac8ef..0000000000 --- a/nodejs-env/src/test/scala/org/scalajs/jsenv/nodejs/NodeJSTest.scala +++ /dev/null @@ -1,79 +0,0 @@ -package org.scalajs.jsenv.nodejs - -import org.scalajs.jsenv.test._ - -import org.junit.Test -import org.junit.Assert._ - -class NodeJSTest extends TimeoutComTests { - - protected def newJSEnv: NodeJSEnv = new NodeJSEnv - - /** Node.js strips double percentage signs - #500 */ - @Test - def percentageTest: Unit = { - val counts = 1 to 15 - val argcs = 1 to 3 - val strings = counts.map("%" * _) - - val strlists = for { - count <- argcs - string <- strings - } yield List.fill(count)(string) - - val codes = for { - strlist <- strlists - } yield { - val args = strlist.map(s => s""""$s"""").mkString(", ") - s"console.log($args);\n" - } - - val result = strlists.map(_.mkString(" ") + "\n").mkString("") - - codes.mkString("").hasOutput(result) - } - - /** Node.js console.log hack didn't allow to log non-Strings - #561 */ - @Test - def nonStringTest: Unit = { - - """ - console.log(1); - console.log(undefined); - console.log(null); - console.log({}); - console.log([1,2]); - """ hasOutput - """|1 - |undefined - |null - |[object Object] - |1,2 - |""".stripMargin - } - - @Test - def slowJSEnvTest: Unit = { - val com = comRunner(""" - setTimeout(function() { - scalajsCom.init(function(msg) { - scalajsCom.send("pong: " + msg); - }); - }, 1000); - """) - - val n = 20 - - start(com) - - for (_ <- 1 to n) - com.send("ping") - - for (_ <- 1 to n) - assertEquals(com.receive(), "pong: ping") - - com.close() - com.await(DefaultTimeout) - } - -} diff --git a/nodejs-env/src/test/scala/org/scalajs/jsenv/nodejs/NodeJSWithCustomInitFilesTest.scala b/nodejs-env/src/test/scala/org/scalajs/jsenv/nodejs/NodeJSWithCustomInitFilesTest.scala deleted file mode 100644 index d1841bd603..0000000000 --- a/nodejs-env/src/test/scala/org/scalajs/jsenv/nodejs/NodeJSWithCustomInitFilesTest.scala +++ /dev/null @@ -1,9 +0,0 @@ -package org.scalajs.jsenv.nodejs - -import org.scalajs.jsenv.test._ - -class NodeJSWithCustomInitFilesTest extends CustomInitFilesTest { - protected def newJSEnv: NodeJSEnv = new NodeJSEnv { - override def customInitFiles() = makeCustomInitFiles() - } -} diff --git a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala index cde982ca64..be7543275e 100644 --- a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala +++ b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala @@ -11,7 +11,7 @@ import org.scalajs.logging._ import org.scalajs.linker._ import org.scalajs.linker.irio._ -import org.scalajs.jsenv.JSConsole +import org.scalajs.jsenv._ import org.scalajs.jsenv.nodejs.NodeJSEnv import scala.tools.partest.scalajs.ScalaJSPartestOptions._ @@ -19,14 +19,12 @@ import scala.tools.partest.scalajs.ScalaJSPartestOptions._ import java.io.File import java.net.URL import scala.io.Source +import scala.concurrent.Await +import scala.concurrent.duration.Duration import Properties.{ versionString, copyrightString } import GenericRunnerCommand._ -class ScalaConsoleJSConsole extends JSConsole { - def log(msg: Any) = scala.Console.out.println(msg.toString) -} - class MainGenericRunner { def errorFn(ex: Throwable): Boolean = { ex.printStackTrace() @@ -67,7 +65,6 @@ class MainGenericRunner { return errorFn("Scala.js runner can only run an object") val logger = new ScalaConsoleLogger(Level.Warn) - val jsConsole = new ScalaConsoleJSConsole val semantics0 = readSemantics() val semantics = if (optMode == FullOpt) semantics0.optimized else semantics0 val ir = loadIR(command.settings.classpathURLs) @@ -91,7 +88,15 @@ class MainGenericRunner { output } - new NodeJSEnv().jsRunner(sjsCode :: Nil).run(logger, jsConsole) + val input = Input.ScriptsToLoad(sjsCode :: Nil) + val config = RunConfig().withLogger(logger) + + val run = new NodeJSEnv().start(input, config) + try { + Await.result(run.future, Duration.Inf) + } finally { + run.close() + } true } diff --git a/project/Build.scala b/project/Build.scala index aafa9a648f..1ec20742c4 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -15,12 +15,14 @@ import java.io.{ } import scala.collection.mutable +import scala.concurrent.Await +import scala.concurrent.duration.Duration import scala.util.Properties import org.scalajs.ir import org.scalajs.sbtplugin._ -import org.scalajs.jsenv.{ConsoleJSConsole, JSEnv} +import org.scalajs.jsenv.{JSEnv, RunConfig, Input} import org.scalajs.jsenv.nodejs.NodeJSEnv import ScalaJSPlugin.autoImport.{ModuleKind => _, _} @@ -814,9 +816,13 @@ object Build { val launcher = new MemVirtualJSFile("Generated launcher file") .withContent(code) - val runner = jsEnv.value.jsRunner(executionFiles :+ launcher) + val config = RunConfig() + .withLogger(sbtLogger2ToolsLogger(streams.value.log)) - runner.run(sbtLogger2ToolsLogger(streams.value.log), ConsoleJSConsole) + val input = Input.ScriptsToLoad((executionFiles :+ launcher).toList) + + val run = jsEnv.value.start(input, config) + Await.result(run.future, Duration.Inf) } } ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( @@ -828,6 +834,7 @@ object Build { publishSettings, fatalWarningsSettings, name := "Scala.js JS Envs", + libraryDependencies += "com.novocode" % "junit-interface" % "0.9" % "test", previousArtifactSetting, mimaBinaryIssueFilters ++= BinaryIncompatibilities.JSEnvs ).dependsOn(io, logging) @@ -837,8 +844,7 @@ object Build { publishSettings, fatalWarningsSettings, name := "Scala.js JS Envs Test Kit", - libraryDependencies += - "junit" % "junit" % "4.8.2", + libraryDependencies += "junit" % "junit" % "4.12", previousArtifactSetting, mimaBinaryIssueFilters ++= BinaryIncompatibilities.JSEnvsTestKit ).dependsOn(jsEnvs) @@ -1363,17 +1369,13 @@ object Build { def envTagsFor(env: JSEnv): Seq[String] = env match { case env: NodeJSEnv => - val tags1 = Seq("nodejs") - val tags2 = - if (MyScalaJSPlugin.wantSourceMaps.value) tags1 :+ "source-maps" - else tags1 - - env match { - case env: NodeJSEnvForcePolyfills => - tags1 - case _ => - tags1 :+ "typedarray" - } + val tags1 = Seq("nodejs", "typedarray") + + if (MyScalaJSPlugin.wantSourceMaps.value) tags1 :+ "source-maps" + else tags1 + + case env: NodeJSEnvForcePolyfills => + Seq("nodejs", "source-maps") case _ => s.log.warn( diff --git a/project/NodeJSEnvForcePolyfills.scala b/project/NodeJSEnvForcePolyfills.scala index b087f6804e..b5088766c3 100644 --- a/project/NodeJSEnvForcePolyfills.scala +++ b/project/NodeJSEnvForcePolyfills.scala @@ -5,17 +5,30 @@ import org.scalajs.jsenv.nodejs._ import org.scalajs.io._ -class NodeJSEnvForcePolyfills(config: NodeJSEnv.Config) - extends NodeJSEnv(config) { - +final class NodeJSEnvForcePolyfills(config: NodeJSEnv.Config) extends JSEnv { def this() = this(NodeJSEnv.Config()) - override protected def vmName: String = "Node.js forcing polyfills" + val name: String = "Node.js forcing polyfills" + + private val nodeJSEnv = new NodeJSEnv(config) + + def start(input: Input, runConfig: RunConfig): JSRun = + nodeJSEnv.start(patchInput(input), runConfig) + + def startWithCom(input: Input, runConfig: RunConfig, + onMessage: String => Unit): JSComRun = { + nodeJSEnv.startWithCom(patchInput(input), runConfig, onMessage) + } - /** File(s) to force all our ES 2015 polyfills to be used, by deleting the + private def patchInput(input: Input): Input = input match { + case Input.ScriptsToLoad(scripts) => Input.ScriptsToLoad(forcePolyfills +: scripts) + case _ => throw new UnsupportedInputException(input) + } + + /** File to force all our ES 2015 polyfills to be used, by deleting the * native functions. */ - protected def forcePolyfills(): Seq[VirtualJSFile] = { + private def forcePolyfills(): VirtualJSFile = { val f = new MemVirtualJSFile("scalaJSEnvInfo.js").withContent( """ |delete Math.fround; @@ -43,11 +56,6 @@ class NodeJSEnvForcePolyfills(config: NodeJSEnv.Config) |delete global.Float64Array; """.stripMargin ) - Seq(f) + f } - - /** Custom initialization scripts. */ - override protected def customInitFiles(): Seq[VirtualJSFile] = - super.customInitFiles() ++ forcePolyfills() - } diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Run.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Run.scala new file mode 100644 index 0000000000..aa05f90c31 --- /dev/null +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Run.scala @@ -0,0 +1,46 @@ +package org.scalajs.sbtplugin + +import org.scalajs.jsenv._ + +import scala.concurrent._ +import scala.concurrent.duration.Duration +import scala.concurrent.ExecutionContext.Implicits.global + +private[sbtplugin] object Run { + /** Starts and waits for a run on the given [[JSEnv]] interruptibly. + * + * Interruption can be triggered by typing anything into stdin. + */ + def runInterruptible(jsEnv: JSEnv, input: Input, config: RunConfig): Unit = { + val readPromise = Promise[Unit]() + val readThread = new Thread { + override def run(): Unit = { + try { + while (System.in.available() == 0) { + Thread.sleep(50) + } + + System.in.read() + } catch { + case _: InterruptedException => + } finally { + readPromise.success(()) + } + } + } + + val run = jsEnv.start(input, config) + try { + readThread.start() + + val fut = Future.firstCompletedOf(List(readPromise.future, run.future)) + Await.result(fut, Duration.Inf) + } finally { + run.close() + } + + readThread.interrupt() + readThread.join() + Await.result(run.future, Duration.Inf) + } +} diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 29a7de3dee..0b475b9d1a 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -65,7 +65,7 @@ private[sbtplugin] object ScalaJSPluginInternal { private val createdTestAdapters = new AtomicReference[List[TestAdapter]](Nil) - private def newTestAdapter(jsEnv: ComJSEnv, jsFiles: Seq[VirtualJSFile], + private def newTestAdapter(jsEnv: JSEnv, jsFiles: Seq[VirtualJSFile], config: TestAdapter.Config): TestAdapter = { registerResource(createdTestAdapters, new TestAdapter(jsEnv, jsFiles, config)) @@ -316,12 +316,15 @@ private[sbtplugin] object ScalaJSPluginInternal { val log = streams.value.log val env = jsEnv.value - val files = jsExecutionFiles.value - log.info("Running " + mainClass.value.getOrElse("")) + val className = mainClass.value.getOrElse("") + log.info(s"Running $className. Hit any key to interrupt.") log.debug(s"with JSEnv ${env.name}") - env.jsRunner(files).run(sbtLogger2ToolsLogger(log), ConsoleJSConsole) + val input = Input.ScriptsToLoad(jsExecutionFiles.value.toList) + val config = RunConfig().withLogger(sbtLogger2ToolsLogger(log)) + + Run.runInterruptible(env, input, config) }, runMain := { @@ -342,15 +345,7 @@ private[sbtplugin] object ScalaJSPluginInternal { } val frameworks = testFrameworks.value - - val env = jsEnv.value match { - case env: ComJSEnv => env - - case env => - throw new MessageOnlyException( - s"You need a ComJSEnv to test (found ${env.name})") - } - + val env = jsEnv.value val files = jsExecutionFiles.value val moduleIdentifier = scalaJSLinkerConfig.value.moduleKind match { diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/ComJSEnvRPC.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/ComJSEnvRPC.scala deleted file mode 100644 index f1df78cec1..0000000000 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/ComJSEnvRPC.scala +++ /dev/null @@ -1,80 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package org.scalajs.testadapter - -import scala.concurrent.{ExecutionContext, TimeoutException} - -import org.scalajs.jsenv.{ComJSEnv, ComJSRunner} -import org.scalajs.testcommon._ - -/** RPC Core for use with a [[ComJSRunner]]. - * - * @note You may only create one instance of this per [[ComJSRunner]] - */ -private[testadapter] final class ComJSEnvRPC(val runner: ComJSRunner)( - implicit executionContext: ExecutionContext) extends RPCCore { - - private val receiverThread = new Thread { - setName("ComJSEnvRPC receiver") - - override def run(): Unit = { - try { - while (true) { - try { - handleMessage(runner.receive()) - } catch { - case _: TimeoutException => - } - } - } catch { - case e: Exception => - /* We got terminated. This might be due to an interruption from a call - * to `close` or due to the JSEnv crashing. - * - * Ensure all still pending calls are failing. - * This can be necessary, if the JSEnv terminates unexpectedly. - * Note: We do not need to give a grace time here, since the reply - * dispatch happens synchronously in `handleMessage`. - * In other words, at this point we'll only see pending calls that - * would require another call to `handleMessage` in order to complete - * successfully. But this is not going to happen since this thread is - * the only one that calls `handleMessage` and it's about to terminate. - */ - ComJSEnvRPC.super.close(e) - - case t: Throwable => - /* Same here, but this is probably a serious VM error condition we - * should propagate. We do not use NonFatal, since it does not catch - * InterruptedException and ControlThrowables which we do not want to - * propagate. - */ - ComJSEnvRPC.super.close(t) - throw t - } - } - } - - receiverThread.start() - - override protected def send(msg: String): Unit = synchronized { - runner.send(msg) - } - - override def close(cause: Throwable): Unit = synchronized { - // First close the RPC layer, so we propagate the right cause. - super.close(cause) - - // Close the runner so the receiver thread terminates. - runner.close() - - receiverThread.interrupt() - receiverThread.join() - } -} diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/JSEnvRPC.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/JSEnvRPC.scala new file mode 100644 index 0000000000..b38017dfef --- /dev/null +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/JSEnvRPC.scala @@ -0,0 +1,54 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package org.scalajs.testadapter + +import scala.concurrent.ExecutionContext + +import org.scalajs.jsenv._ +import org.scalajs.testcommon._ + +/** RPC Core for use with a [[JSEnv]]. */ +private[testadapter] final class JSEnvRPC( + jsenv: JSEnv, input: Input, config: RunConfig)( + implicit executionContext: ExecutionContext) extends RPCCore { + + private val run = jsenv.startWithCom(input, config, handleMessage) + + /* Once the com closes, ensure all still pending calls are failing. + * This can be necessary, if the JSEnv terminates unexpectedly. + * Note: We do not need to give a grace time here, since the reply + * dispatch happens synchronously in `handleMessage`. + * In other words, at this point we'll only see pending calls that + * would require another call to `handleMessage` in order to complete + * successfully. But this is not going to happen since the com run is + * completed (and it is an explicit guarantee that `handleMessage` is not + * called anymore after that). + */ + run.future.onComplete( + t => close(JSEnvRPC.RunTerminatedException(t.failed.toOption))) + + override protected def send(msg: String): Unit = run.send(msg) + + override def close(cause: Throwable): Unit = { + /* Close the RPC layer and fail all pending calls. + * This needs to happen first so we do not race completion of the run + * itself (to retain the cause given here). + */ + super.close(cause) + + // Now terminate the run itself. + run.close() + } +} + +private[testadapter] object JSEnvRPC { + final case class RunTerminatedException(c: Option[Throwable]) + extends Exception(null, c.orNull) +} diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapter.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapter.scala index d733f47687..d823d227b2 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapter.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapter.scala @@ -23,7 +23,7 @@ import org.scalajs.testcommon._ import sbt.testing.Framework -final class TestAdapter(jsEnv: ComJSEnv, jsFiles: Seq[VirtualJSFile], +final class TestAdapter(jsEnv: JSEnv, jsFiles: Seq[VirtualJSFile], config: TestAdapter.Config) { import TestAdapter._ @@ -89,7 +89,6 @@ final class TestAdapter(jsEnv: ComJSEnv, jsFiles: Seq[VirtualJSFile], if (!closed) { closed = true runners.values.foreach(_.com.close(cause)) - runners.values.foreach(_.runner.stop()) runners.clear() } } @@ -131,13 +130,15 @@ final class TestAdapter(jsEnv: ComJSEnv, jsFiles: Seq[VirtualJSFile], val launcher = new MemVirtualJSFile("startTestBridge.js") .withContent(s"($orgExpr).scalajs.testinterface.internal.startBridge();") - val runner = jsEnv.comRunner(jsFiles :+ launcher) - val com = new ComJSEnvRPC(runner) - val mux = new RunMuxRPC(com) - runner.start(config.logger, config.console) + val input = Input.ScriptsToLoad((jsFiles :+ launcher).toList) + val runConfig = RunConfig() + .withLogger(config.logger) + + val com = new JSEnvRPC(jsEnv, input, runConfig) + val mux = new RunMuxRPC(com) - new ManagedRunner(threadId, runner, com, mux) + new ManagedRunner(threadId, com, mux) } } @@ -169,13 +170,11 @@ object TestAdapter { final class Config private ( val logger: Logger, - val console: JSConsole, val moduleIdentifier: ModuleIdentifier ) { private def this() = { this( logger = NullLogger, - console = ConsoleJSConsole, moduleIdentifier = ModuleIdentifier.NoModule ) } @@ -183,18 +182,14 @@ object TestAdapter { def withLogger(logger: Logger): Config = copy(logger = logger) - def withJSConsole(console: JSConsole): Config = - copy(console = console) - def withModuleIdentifier(moduleIdentifier: ModuleIdentifier): Config = copy(moduleIdentifier = moduleIdentifier) private def copy( logger: Logger = logger, - console: JSConsole = console, moduleIdentifier: ModuleIdentifier = moduleIdentifier ): Config = { - new Config(logger, console, moduleIdentifier) + new Config(logger, moduleIdentifier) } } @@ -204,7 +199,6 @@ object TestAdapter { private[testadapter] final class ManagedRunner( val id: Long, - val runner: ComJSRunner, val com: RPCCore, val mux: RunMuxRPC ) diff --git a/test-common/src/main/scala/org/scalajs/testcommon/RPCCore.scala b/test-common/src/main/scala/org/scalajs/testcommon/RPCCore.scala index d16d3ade04..b864fa306c 100644 --- a/test-common/src/main/scala/org/scalajs/testcommon/RPCCore.scala +++ b/test-common/src/main/scala/org/scalajs/testcommon/RPCCore.scala @@ -228,10 +228,10 @@ private[scalajs] object RPCCore { type OpCode = Byte /** Exception thrown if a remote invocation fails. */ - class RPCException(c: Throwable) extends Exception(null, c) + final case class RPCException(c: Throwable) extends Exception(null, c) /** Exception thrown if the channel got closed. */ - class ClosedException(c: Throwable) extends Exception(null, c) + final case class ClosedException(c: Throwable) extends Exception(null, c) private val ReplyOK: Byte = 0.toByte private val ReplyErr: Byte = 1.toByte From 3eac0e9aac87b64547732212495a69d8e86812d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 21 Jan 2018 14:50:28 +0100 Subject: [PATCH 0659/2665] Remove `GenLinker.linkUnit`. --- .../scala/org/scalajs/linker/ClearableLinker.scala | 6 ------ .../src/main/scala/org/scalajs/linker/GenLinker.scala | 10 ++++------ .../src/main/scala/org/scalajs/linker/Linker.scala | 5 ----- 3 files changed, 4 insertions(+), 17 deletions(-) diff --git a/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala b/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala index 319c49344a..967d711d91 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala @@ -28,12 +28,6 @@ final class ClearableLinker(newLinker: () => GenLinker, batchMode: Boolean) private[this] var _linker: GenLinker = _ - def linkUnit(irFiles: Seq[VirtualScalaJSIRFile], - moduleInitializers: Seq[ModuleInitializer], - symbolRequirements: SymbolRequirement, logger: Logger): LinkingUnit = { - linkerOp(_.linkUnit(irFiles, moduleInitializers, symbolRequirements, logger)) - } - def link(irFiles: Seq[VirtualScalaJSIRFile], moduleInitializers: Seq[ModuleInitializer], output: WritableVirtualJSFile, logger: Logger): Unit = { diff --git a/linker/shared/src/main/scala/org/scalajs/linker/GenLinker.scala b/linker/shared/src/main/scala/org/scalajs/linker/GenLinker.scala index ce477ae2c4..deb0991e0f 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/GenLinker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/GenLinker.scala @@ -15,15 +15,13 @@ import org.scalajs.io._ import org.scalajs.linker.analyzer.SymbolRequirement import org.scalajs.linker.irio._ -/** Common supertrait of [[Linker]] and [[ClearableLinker]]. +/** A Scala.js linker, with its most abstract API. * - * Essentially anything that has the `link` and `linkUnit` methods. + * A linker can take a sequence of virtual .sjsir files and a sequence of + * module initializers, link them together, and write the output to a writable + * .js file. */ trait GenLinker { - def linkUnit(irFiles: Seq[VirtualScalaJSIRFile], - moduleInitializers: Seq[ModuleInitializer], - symbolRequirements: SymbolRequirement, logger: Logger): LinkingUnit - def link(irFiles: Seq[VirtualScalaJSIRFile], moduleInitializers: Seq[ModuleInitializer], output: WritableVirtualJSFile, logger: Logger): Unit diff --git a/linker/shared/src/main/scala/org/scalajs/linker/Linker.scala b/linker/shared/src/main/scala/org/scalajs/linker/Linker.scala index bc66fee66d..c02ed9114a 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/Linker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/Linker.scala @@ -32,11 +32,6 @@ final class Linker private (frontend: LinkerFrontend, backend: LinkerBackend) private[this] var _valid = true private[this] val _linking = new AtomicBoolean(false) - def linkUnit(irFiles: Seq[VirtualScalaJSIRFile], - moduleInitializers: Seq[ModuleInitializer], - symbolRequirements: SymbolRequirement, logger: Logger): LinkingUnit = - guard(frontend.link(irFiles, moduleInitializers, symbolRequirements, logger)) - def link(irFiles: Seq[VirtualScalaJSIRFile], moduleInitializers: Seq[ModuleInitializer], output: WritableVirtualJSFile, logger: Logger): Unit = { From 6e3f744f2cdb0c96208cf16090b962d33cf8ce2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 21 Jan 2018 14:59:24 +0100 Subject: [PATCH 0660/2665] Decouple `RuntimeClassNameMapper` from `LinkedClass`. It now directly takes the `className`, rather than a `LinkedClass`. --- .../shared/src/main/scala/org/scalajs/linker/Semantics.scala | 4 ++-- .../org/scalajs/linker/backend/emitter/ClassEmitter.scala | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/linker/shared/src/main/scala/org/scalajs/linker/Semantics.scala b/linker/shared/src/main/scala/org/scalajs/linker/Semantics.scala index 453197075d..17d92d5ef5 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/Semantics.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/Semantics.scala @@ -112,7 +112,7 @@ object Semantics { def andThen(that: RuntimeClassNameMapper): RuntimeClassNameMapper = AndThen(this, that) - private[linker] def apply(linkedClass: LinkedClass): String = { + private[linker] def apply(className: String): String = { def rec(mapper: RuntimeClassNameMapper, className: String): String = { mapper match { case KeepAll => @@ -126,7 +126,7 @@ object Semantics { } } - rec(this, linkedClass.fullName) + rec(this, className) } } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala index b8683b6b72..efc7775439 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala @@ -926,7 +926,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val allParams = List( js.ObjectConstr(List(js.Ident(className) -> js.IntLiteral(0))), js.BooleanLiteral(kind == ClassKind.Interface), - js.StringLiteral(semantics.runtimeClassNameMapper(tree)), + js.StringLiteral(semantics.runtimeClassNameMapper(tree.fullName)), ancestorsRecord, isRawJSTypeParam, parentData, From 18d86ce7761b0b5269d249c7cff4b26949d62974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 21 Jan 2018 15:56:32 +0100 Subject: [PATCH 0661/2665] Move things from `linker.*` to `linker.standard.*`. We move `Linker`, `LinkedClass`, `LinkingUnit` and `Versioned` to the `standard` subpackage of the linker, since they will not be part of the super-stable API. In addition, we rename `Linker` to `StandardLinkerImpl` and only publicize its companion object. This will be important when we rename `GenLinker` to `Linker`, otherwise the recommended imports of `linker._` and `linker.standard._` would produce an ambiguous import of `Linker`. --- .../backend/closure/ClosureLinkerBackend.scala | 5 +++-- .../scala/org/scalajs/linker/ClearableLinker.scala | 1 - .../main/scala/org/scalajs/linker/GenLinker.scala | 1 - .../main/scala/org/scalajs/linker/Semantics.scala | 2 -- .../scala/org/scalajs/linker/StandardLinker.scala | 5 +++-- .../scala/org/scalajs/linker/analyzer/Infos.scala | 1 - .../linker/backend/BasicLinkerBackend.scala | 6 +++--- .../org/scalajs/linker/backend/LinkerBackend.scala | 7 ++++--- .../linker/backend/emitter/ClassEmitter.scala | 1 + .../linker/backend/emitter/KnowledgeGuardian.scala | 1 + .../org/scalajs/linker/checker/IRChecker.scala | 5 +++-- .../org/scalajs/linker/frontend/BaseLinker.scala | 2 +- .../scalajs/linker/frontend/LinkerFrontend.scala | 12 ++++++++---- .../org/scalajs/linker/frontend/Refiner.scala | 3 ++- .../frontend/optimizer/GenIncOptimizer.scala | 4 +++- .../linker/{ => standard}/LinkedClass.scala | 2 +- .../linker/{ => standard}/LinkingUnit.scala | 4 ++-- .../StandardLinkerImpl.scala} | 14 ++++++++------ .../scalajs/linker/{ => standard}/Versioned.scala | 5 +---- 19 files changed, 44 insertions(+), 37 deletions(-) rename linker/shared/src/main/scala/org/scalajs/linker/{ => standard}/LinkedClass.scala (99%) rename linker/shared/src/main/scala/org/scalajs/linker/{ => standard}/LinkingUnit.scala (71%) rename linker/shared/src/main/scala/org/scalajs/linker/{Linker.scala => standard/StandardLinkerImpl.scala} (84%) rename linker/shared/src/main/scala/org/scalajs/linker/{ => standard}/Versioned.scala (94%) diff --git a/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala index 6079266d60..59ef256e46 100644 --- a/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala @@ -22,6 +22,7 @@ import org.scalajs.io._ import org.scalajs.logging.Logger import org.scalajs.linker._ +import org.scalajs.linker.standard._ import org.scalajs.linker.analyzer.SymbolRequirement import org.scalajs.linker.backend._ import org.scalajs.linker.backend.emitter.Emitter @@ -59,9 +60,9 @@ final class ClosureLinkerBackend(config: LinkerBackend.Config) private def toClosureSource(file: VirtualJSFile) = ClosureSource.fromReader(file.toURI.toString(), file.reader) - /** Emit the given [[LinkingUnit]] to the target output + /** Emit the given [[standard.LinkingUnit LinkingUnit]] to the target output. * - * @param unit [[LinkingUnit]] to emit + * @param unit [[standard.LinkingUnit LinkingUnit]] to emit * @param output File to write to */ def emit(unit: LinkingUnit, output: WritableVirtualJSFile, diff --git a/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala b/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala index 967d711d91..85ba229354 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala @@ -12,7 +12,6 @@ package org.scalajs.linker import org.scalajs.logging.Logger import org.scalajs.io._ -import org.scalajs.linker.analyzer.SymbolRequirement import org.scalajs.linker.irio._ /** A box around a [[GenLinker]] to support clearing. diff --git a/linker/shared/src/main/scala/org/scalajs/linker/GenLinker.scala b/linker/shared/src/main/scala/org/scalajs/linker/GenLinker.scala index deb0991e0f..cbbc8f97b8 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/GenLinker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/GenLinker.scala @@ -12,7 +12,6 @@ package org.scalajs.linker import org.scalajs.logging.Logger import org.scalajs.io._ -import org.scalajs.linker.analyzer.SymbolRequirement import org.scalajs.linker.irio._ /** A Scala.js linker, with its most abstract API. diff --git a/linker/shared/src/main/scala/org/scalajs/linker/Semantics.scala b/linker/shared/src/main/scala/org/scalajs/linker/Semantics.scala index 17d92d5ef5..a02772d0b3 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/Semantics.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/Semantics.scala @@ -9,8 +9,6 @@ package org.scalajs.linker -import scala.collection.immutable.Traversable - import CheckedBehavior._ final class Semantics private ( diff --git a/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala b/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala index 2b8824c389..3f536ee784 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala @@ -19,7 +19,7 @@ import org.scalajs.linker.backend.LinkerBackend object StandardLinker { import StandardLinkerPlatformExtensions._ - def apply(config: Config): Linker = { + def apply(config: Config): GenLinker = { val coreSpec = CoreSpec( config.semantics, config.moduleKind, @@ -42,7 +42,8 @@ object StandardLinker { .withClosureCompilerIfAvailable(config.closureCompilerIfAvailable) .withPrettyPrint(config.prettyPrint) - Linker(LinkerFrontend(frontendConfig), LinkerBackend(backendConfig)) + StandardLinkerImpl(LinkerFrontend(frontendConfig), + LinkerBackend(backendConfig)) } implicit def configExt(config: Config): ConfigExt = diff --git a/linker/shared/src/main/scala/org/scalajs/linker/analyzer/Infos.scala b/linker/shared/src/main/scala/org/scalajs/linker/analyzer/Infos.scala index c1d725f36a..0ab6a45ae6 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/analyzer/Infos.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/analyzer/Infos.scala @@ -17,7 +17,6 @@ import org.scalajs.ir.Traversers._ import org.scalajs.ir.Trees._ import org.scalajs.ir.Types._ -import org.scalajs.linker.LinkedClass import org.scalajs.linker.backend.emitter.Transients._ object Infos { diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/BasicLinkerBackend.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/BasicLinkerBackend.scala index b614b457e7..d7924430e9 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/BasicLinkerBackend.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/BasicLinkerBackend.scala @@ -12,7 +12,7 @@ package org.scalajs.linker.backend import org.scalajs.logging.Logger import org.scalajs.io.WritableVirtualJSFile -import org.scalajs.linker.LinkingUnit +import org.scalajs.linker.standard.LinkingUnit import org.scalajs.linker.analyzer.SymbolRequirement import org.scalajs.linker.backend.emitter.Emitter @@ -31,9 +31,9 @@ final class BasicLinkerBackend(config: LinkerBackend.Config) val symbolRequirements: SymbolRequirement = emitter.symbolRequirements - /** Emit the given [[LinkingUnit]] to the target output + /** Emit the given [[standard.LinkingUnit LinkingUnit]] to the target output. * - * @param unit [[LinkingUnit]] to emit + * @param unit [[standard.LinkingUnit LinkingUnit]] to emit * @param output File to write to */ def emit(unit: LinkingUnit, output: WritableVirtualJSFile, diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/LinkerBackend.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/LinkerBackend.scala index e004abc747..44bfc62020 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/LinkerBackend.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/LinkerBackend.scala @@ -33,21 +33,22 @@ abstract class LinkerBackend(protected val config: LinkerBackend.Config) { /** Symbols this backend needs to be present in the linking unit. */ val symbolRequirements: SymbolRequirement - /** Emit the given [[LinkingUnit]] to the target output. + /** Emit the given [[standard.LinkingUnit LinkingUnit]] to the target output. * * The linking unit given to `emit` must: * * - have the same `coreSpec` as this linker backend, and * - contain the symbols listed in [[symbolRequirements]]. * - * @param unit [[LinkingUnit]] to emit + * @param unit [[standard.LinkingUnit LinkingUnit]] to emit * @param output File to write to * @param logger Logger to use */ def emit(unit: LinkingUnit, output: WritableVirtualJSFile, logger: Logger): Unit - /** Verify that a [[LinkingUnit]] can be processed by this [[LinkerBackend]]. + /** Verify that a [[standard.LinkingUnit LinkingUnit]] can be processed by + * this [[LinkerBackend]]. * * Currently, this only tests that the linking unit core specification * matches [[coreSpec]]. diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala index efc7775439..326736fccb 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala @@ -16,6 +16,7 @@ import org.scalajs.ir.Trees._ import Types._ import org.scalajs.linker._ +import org.scalajs.linker.standard._ import org.scalajs.linker.backend.javascript.{Trees => js} import CheckedBehavior.Unchecked diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/KnowledgeGuardian.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/KnowledgeGuardian.scala index 938e1b9a1a..f1f1c0e5bc 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/KnowledgeGuardian.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/KnowledgeGuardian.scala @@ -16,6 +16,7 @@ import org.scalajs.ir.Trees._ import org.scalajs.ir.Types.Type import org.scalajs.linker._ +import org.scalajs.linker.standard._ private[emitter] final class KnowledgeGuardian { import KnowledgeGuardian._ diff --git a/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala b/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala index 58a9fb600b..1a543b68d0 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala @@ -24,7 +24,8 @@ import Trees._ import Types._ import org.scalajs.logging._ -import org.scalajs.linker.{LinkingUnit, LinkedClass, Versioned} + +import org.scalajs.linker.standard._ import org.scalajs.linker.analyzer.{Analyzer, Infos} /** Checker for the validity of the IR. */ @@ -1374,7 +1375,7 @@ private final class IRChecker(unit: LinkingUnit, } object IRChecker { - /** Checks that the IR in a [[LinkingUnit]] is correct. + /** Checks that the IR in a [[standard.LinkingUnit LinkingUnit]] is correct. * * @return Count of IR checking errors (0 in case of success) */ diff --git a/linker/shared/src/main/scala/org/scalajs/linker/frontend/BaseLinker.scala b/linker/shared/src/main/scala/org/scalajs/linker/frontend/BaseLinker.scala index 3b98e75f99..89de08ea29 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/frontend/BaseLinker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/frontend/BaseLinker.scala @@ -34,7 +34,7 @@ import ir.Definitions import Analysis._ /** Links the information from [[irio.VirtualScalaJSIRFile]]s into - * [[LinkedClass]]es. Does a dead code elimination pass. + * [[standard.LinkedClass LinkedClass]]es. Does a dead code elimination pass. */ final class BaseLinker(config: CommonPhaseConfig) { import BaseLinker._ diff --git a/linker/shared/src/main/scala/org/scalajs/linker/frontend/LinkerFrontend.scala b/linker/shared/src/main/scala/org/scalajs/linker/frontend/LinkerFrontend.scala index 713763fde0..47bacbd74b 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/frontend/LinkerFrontend.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/frontend/LinkerFrontend.scala @@ -17,13 +17,15 @@ import org.scalajs.linker.analyzer.SymbolRequirement import org.scalajs.linker.frontend.optimizer.{GenIncOptimizer, IncOptimizer} import org.scalajs.linker.irio._ -/** The frontend of the Scala.js linker. Produces a [[LinkingUnit]] +/** The frontend of the Scala.js linker. + * + * Produces a [[standard.LinkingUnit LinkingUnit]]. * * You probably want to use an instance of [[linker.Linker]], rather than this * low-level class. * - * Attention: [[LinkerFrontend]] does not cache the IR input. It is advisable to do - * so, unless all IR is already in memory. + * Attention: [[LinkerFrontend]] does not cache the IR input. It is advisable + * to do so, unless all IR is already in memory. */ final class LinkerFrontend private (config: LinkerFrontend.Config) { @@ -38,7 +40,9 @@ final class LinkerFrontend private (config: LinkerFrontend.Config) { private[this] val refiner: Refiner = new Refiner(config.commonConfig) - /** Link and optionally optimize the given IR to a [[LinkingUnit]]. */ + /** Link and optionally optimize the given IR to a + * [[standard.LinkingUnit LinkingUnit]]. + */ def link(irFiles: Seq[VirtualScalaJSIRFile], moduleInitializers: Seq[ModuleInitializer], symbolRequirements: SymbolRequirement, logger: Logger): LinkingUnit = { diff --git a/linker/shared/src/main/scala/org/scalajs/linker/frontend/Refiner.scala b/linker/shared/src/main/scala/org/scalajs/linker/frontend/Refiner.scala index 5b909717ee..40a67f1afa 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/frontend/Refiner.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/frontend/Refiner.scala @@ -19,7 +19,8 @@ import org.scalajs.linker._ import org.scalajs.linker.standard._ import org.scalajs.linker.analyzer._ -/** Does a dead code elimination pass on [[LinkedClass]]es */ +/** Does a dead code elimination pass on a [[standard.LinkingUnit LinkingUnit]]. + */ final class Refiner(config: CommonPhaseConfig) { import Refiner._ diff --git a/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/GenIncOptimizer.scala b/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/GenIncOptimizer.scala index 9a5720e321..923e1b26b4 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/GenIncOptimizer.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/GenIncOptimizer.scala @@ -29,7 +29,9 @@ import org.scalajs.linker.backend.emitter.LongImpl import org.scalajs.linker.standard._ /** Incremental optimizer. - * An incremental optimizer optimizes a [[LinkingUnit]] in an incremental way. + * + * An incremental optimizer optimizes a [[standard.LinkingUnit LinkingUnit]] + * in an incremental way. * * It maintains state between runs to do a minimal amount of work on every * run, based on detecting what parts of the program must be re-optimized, diff --git a/linker/shared/src/main/scala/org/scalajs/linker/LinkedClass.scala b/linker/shared/src/main/scala/org/scalajs/linker/standard/LinkedClass.scala similarity index 99% rename from linker/shared/src/main/scala/org/scalajs/linker/LinkedClass.scala rename to linker/shared/src/main/scala/org/scalajs/linker/standard/LinkedClass.scala index 9ebbf4112e..2ab3adba31 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/LinkedClass.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/standard/LinkedClass.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.linker +package org.scalajs.linker.standard import scala.collection.mutable diff --git a/linker/shared/src/main/scala/org/scalajs/linker/LinkingUnit.scala b/linker/shared/src/main/scala/org/scalajs/linker/standard/LinkingUnit.scala similarity index 71% rename from linker/shared/src/main/scala/org/scalajs/linker/LinkingUnit.scala rename to linker/shared/src/main/scala/org/scalajs/linker/standard/LinkingUnit.scala index f96855ed79..484e82d021 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/LinkingUnit.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/standard/LinkingUnit.scala @@ -1,6 +1,6 @@ -package org.scalajs.linker +package org.scalajs.linker.standard -import org.scalajs.linker.standard._ +import org.scalajs.linker._ final class LinkingUnit private[linker] ( val coreSpec: CoreSpec, diff --git a/linker/shared/src/main/scala/org/scalajs/linker/Linker.scala b/linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerImpl.scala similarity index 84% rename from linker/shared/src/main/scala/org/scalajs/linker/Linker.scala rename to linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerImpl.scala index c02ed9114a..94f361c285 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/Linker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerImpl.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.linker +package org.scalajs.linker.standard import scala.language.implicitConversions @@ -16,14 +16,16 @@ import java.util.concurrent.atomic.AtomicBoolean import org.scalajs.logging.Logger import org.scalajs.io._ +import org.scalajs.linker._ import org.scalajs.linker.analyzer.SymbolRequirement import org.scalajs.linker.frontend.LinkerFrontend import org.scalajs.linker.frontend.optimizer.IncOptimizer import org.scalajs.linker.backend.{LinkerBackend, BasicLinkerBackend} import org.scalajs.linker.irio._ -/** The Scala.js linker */ -final class Linker private (frontend: LinkerFrontend, backend: LinkerBackend) +/** Standard implementation of a Scala.js linker. */ +private final class StandardLinkerImpl private ( + frontend: LinkerFrontend, backend: LinkerBackend) extends GenLinker { require(frontend.coreSpec == backend.coreSpec, @@ -65,7 +67,7 @@ final class Linker private (frontend: LinkerFrontend, backend: LinkerBackend) } } -object Linker { - def apply(frontend: LinkerFrontend, backend: LinkerBackend): Linker = - new Linker(frontend, backend) +object StandardLinkerImpl { + def apply(frontend: LinkerFrontend, backend: LinkerBackend): GenLinker = + new StandardLinkerImpl(frontend, backend) } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/Versioned.scala b/linker/shared/src/main/scala/org/scalajs/linker/standard/Versioned.scala similarity index 94% rename from linker/shared/src/main/scala/org/scalajs/linker/Versioned.scala rename to linker/shared/src/main/scala/org/scalajs/linker/standard/Versioned.scala index 8ada27bf5e..34c72b9429 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/Versioned.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/standard/Versioned.scala @@ -6,10 +6,7 @@ ** |/____/ ** \* */ -package org.scalajs.linker - -import org.scalajs.ir -import ir.Trees._ +package org.scalajs.linker.standard /** A versioned thing, accompanied by its version. * From 4245bebde464357ed8114cf35fde85e588d54cfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 21 Jan 2018 16:08:10 +0100 Subject: [PATCH 0662/2665] Rename `GenLinker` to `Linker`, and make it an abstract class. We make it an abstract class with a package-private constructor so that we can add abstract and concrete methods in the future, while preserving backward binary compatibility. --- .../scala/org/scalajs/linker/ClearableLinker.scala | 10 +++++----- .../scalajs/linker/{GenLinker.scala => Linker.scala} | 2 +- .../main/scala/org/scalajs/linker/StandardLinker.scala | 2 +- .../scalajs/linker/standard/StandardLinkerImpl.scala | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) rename linker/shared/src/main/scala/org/scalajs/linker/{GenLinker.scala => Linker.scala} (96%) diff --git a/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala b/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala index 85ba229354..c5341902fc 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala @@ -14,7 +14,7 @@ import org.scalajs.io._ import org.scalajs.linker.irio._ -/** A box around a [[GenLinker]] to support clearing. +/** A box around a [[Linker]] to support clearing. * * This further supports: * - batch mode (clearing after every operation) @@ -22,10 +22,10 @@ import org.scalajs.linker.irio._ * * This class is not thread-safe. */ -final class ClearableLinker(newLinker: () => GenLinker, batchMode: Boolean) - extends GenLinker { +final class ClearableLinker(newLinker: () => Linker, batchMode: Boolean) + extends Linker { - private[this] var _linker: GenLinker = _ + private[this] var _linker: Linker = _ def link(irFiles: Seq[VirtualScalaJSIRFile], moduleInitializers: Seq[ModuleInitializer], @@ -37,7 +37,7 @@ final class ClearableLinker(newLinker: () => GenLinker, batchMode: Boolean) _linker = null @inline - private[this] def linkerOp[T](op: GenLinker => T): T = { + private[this] def linkerOp[T](op: Linker => T): T = { ensureLinker() try { diff --git a/linker/shared/src/main/scala/org/scalajs/linker/GenLinker.scala b/linker/shared/src/main/scala/org/scalajs/linker/Linker.scala similarity index 96% rename from linker/shared/src/main/scala/org/scalajs/linker/GenLinker.scala rename to linker/shared/src/main/scala/org/scalajs/linker/Linker.scala index cbbc8f97b8..920d900aa6 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/GenLinker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/Linker.scala @@ -20,7 +20,7 @@ import org.scalajs.linker.irio._ * module initializers, link them together, and write the output to a writable * .js file. */ -trait GenLinker { +abstract class Linker private[linker] () { def link(irFiles: Seq[VirtualScalaJSIRFile], moduleInitializers: Seq[ModuleInitializer], output: WritableVirtualJSFile, logger: Logger): Unit diff --git a/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala b/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala index 3f536ee784..ec153463fe 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala @@ -19,7 +19,7 @@ import org.scalajs.linker.backend.LinkerBackend object StandardLinker { import StandardLinkerPlatformExtensions._ - def apply(config: Config): GenLinker = { + def apply(config: Config): Linker = { val coreSpec = CoreSpec( config.semantics, config.moduleKind, diff --git a/linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerImpl.scala b/linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerImpl.scala index 94f361c285..fb241e8878 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerImpl.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerImpl.scala @@ -26,7 +26,7 @@ import org.scalajs.linker.irio._ /** Standard implementation of a Scala.js linker. */ private final class StandardLinkerImpl private ( frontend: LinkerFrontend, backend: LinkerBackend) - extends GenLinker { + extends Linker { require(frontend.coreSpec == backend.coreSpec, "Frontend and backend must implement the same core specification") @@ -68,6 +68,6 @@ private final class StandardLinkerImpl private ( } object StandardLinkerImpl { - def apply(frontend: LinkerFrontend, backend: LinkerBackend): GenLinker = + def apply(frontend: LinkerFrontend, backend: LinkerBackend): Linker = new StandardLinkerImpl(frontend, backend) } From 6a47f7a322f3f458e9fda74acdae837b3d4eeeb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 21 Jan 2018 16:10:50 +0100 Subject: [PATCH 0663/2665] Hide `ModuleInitializer.toSymbolRequirement` as `private[linker]`. This is necessary because `ModuleInitializer` is part of the super-stable API while `SymbolRequirement` isn't. --- .../src/main/scala/org/scalajs/linker/ModuleInitializer.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linker/shared/src/main/scala/org/scalajs/linker/ModuleInitializer.scala b/linker/shared/src/main/scala/org/scalajs/linker/ModuleInitializer.scala index 77395006e0..1e9a486394 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/ModuleInitializer.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/ModuleInitializer.scala @@ -87,7 +87,7 @@ object ModuleInitializer { mainMethodName + "__AT__V", args) } - def toSymbolRequirement( + private[linker] def toSymbolRequirement( entryPoints: Seq[ModuleInitializer]): SymbolRequirement = { val factory = SymbolRequirement.factory("module initializers") val requirements = for (entryPoint <- entryPoints) yield { From 49cabdc305daab53527a886eed3b4ec350e2afe2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 21 Jan 2018 16:17:45 +0100 Subject: [PATCH 0664/2665] Move `SymbolRequirement` to `linker.standard`. --- .../linker/backend/closure/ClosureLinkerBackend.scala | 1 - .../main/scala/org/scalajs/linker/ModuleInitializer.scala | 6 ++---- .../org/scalajs/linker/backend/BasicLinkerBackend.scala | 3 +-- .../scala/org/scalajs/linker/backend/LinkerBackend.scala | 1 - .../scala/org/scalajs/linker/backend/emitter/Emitter.scala | 1 - .../scala/org/scalajs/linker/frontend/LinkerFrontend.scala | 1 - .../scalajs/linker/frontend/optimizer/GenIncOptimizer.scala | 1 - .../org/scalajs/linker/standard/StandardLinkerImpl.scala | 1 - .../linker/{analyzer => standard}/SymbolRequirement.scala | 4 ++-- 9 files changed, 5 insertions(+), 14 deletions(-) rename linker/shared/src/main/scala/org/scalajs/linker/{analyzer => standard}/SymbolRequirement.scala (98%) diff --git a/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala index 59ef256e46..c578c18ce0 100644 --- a/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala @@ -23,7 +23,6 @@ import org.scalajs.logging.Logger import org.scalajs.linker._ import org.scalajs.linker.standard._ -import org.scalajs.linker.analyzer.SymbolRequirement import org.scalajs.linker.backend._ import org.scalajs.linker.backend.emitter.Emitter diff --git a/linker/shared/src/main/scala/org/scalajs/linker/ModuleInitializer.scala b/linker/shared/src/main/scala/org/scalajs/linker/ModuleInitializer.scala index 1e9a486394..a293215b03 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/ModuleInitializer.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/ModuleInitializer.scala @@ -11,8 +11,6 @@ package org.scalajs.linker import org.scalajs.ir.Definitions._ import org.scalajs.ir.Types.ClassType -import org.scalajs.linker.analyzer.SymbolRequirement - /** A module initializer for a Scala.js application. * * When linking a Scala.js application, a sequence of `ModuleInitializer`s can @@ -88,8 +86,8 @@ object ModuleInitializer { } private[linker] def toSymbolRequirement( - entryPoints: Seq[ModuleInitializer]): SymbolRequirement = { - val factory = SymbolRequirement.factory("module initializers") + entryPoints: Seq[ModuleInitializer]): standard.SymbolRequirement = { + val factory = standard.SymbolRequirement.factory("module initializers") val requirements = for (entryPoint <- entryPoints) yield { entryPoint match { case VoidMainMethod(moduleClassName, mainMethodName) => diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/BasicLinkerBackend.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/BasicLinkerBackend.scala index d7924430e9..c1e5d7d160 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/BasicLinkerBackend.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/BasicLinkerBackend.scala @@ -12,8 +12,7 @@ package org.scalajs.linker.backend import org.scalajs.logging.Logger import org.scalajs.io.WritableVirtualJSFile -import org.scalajs.linker.standard.LinkingUnit -import org.scalajs.linker.analyzer.SymbolRequirement +import org.scalajs.linker.standard._ import org.scalajs.linker.backend.emitter.Emitter import org.scalajs.linker.backend.javascript.{ diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/LinkerBackend.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/LinkerBackend.scala index 44bfc62020..a84cf37eec 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/LinkerBackend.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/LinkerBackend.scala @@ -18,7 +18,6 @@ import org.scalajs.logging.Logger import org.scalajs.linker._ import org.scalajs.linker.standard._ -import org.scalajs.linker.analyzer.SymbolRequirement /** A backend of the Scala.js linker. Produces a * [[org.scalajs.io.VirtualJSFile VirtualJSFile]]. diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala index dc69de556e..624e4b9134 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala @@ -22,7 +22,6 @@ import org.scalajs.logging._ import org.scalajs.linker._ import org.scalajs.linker.standard._ -import org.scalajs.linker.analyzer.SymbolRequirement import org.scalajs.linker.backend.javascript.{Trees => js, _} import GlobalRefUtils._ diff --git a/linker/shared/src/main/scala/org/scalajs/linker/frontend/LinkerFrontend.scala b/linker/shared/src/main/scala/org/scalajs/linker/frontend/LinkerFrontend.scala index 47bacbd74b..4861710bad 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/frontend/LinkerFrontend.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/frontend/LinkerFrontend.scala @@ -13,7 +13,6 @@ import org.scalajs.logging.Logger import org.scalajs.linker._ import org.scalajs.linker.standard._ -import org.scalajs.linker.analyzer.SymbolRequirement import org.scalajs.linker.frontend.optimizer.{GenIncOptimizer, IncOptimizer} import org.scalajs.linker.irio._ diff --git a/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/GenIncOptimizer.scala b/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/GenIncOptimizer.scala index 923e1b26b4..ba0a3c349f 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/GenIncOptimizer.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/GenIncOptimizer.scala @@ -24,7 +24,6 @@ import Types._ import org.scalajs.logging._ import org.scalajs.linker._ -import org.scalajs.linker.analyzer.SymbolRequirement import org.scalajs.linker.backend.emitter.LongImpl import org.scalajs.linker.standard._ diff --git a/linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerImpl.scala b/linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerImpl.scala index fb241e8878..b1cf9a8846 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerImpl.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerImpl.scala @@ -17,7 +17,6 @@ import org.scalajs.logging.Logger import org.scalajs.io._ import org.scalajs.linker._ -import org.scalajs.linker.analyzer.SymbolRequirement import org.scalajs.linker.frontend.LinkerFrontend import org.scalajs.linker.frontend.optimizer.IncOptimizer import org.scalajs.linker.backend.{LinkerBackend, BasicLinkerBackend} diff --git a/linker/shared/src/main/scala/org/scalajs/linker/analyzer/SymbolRequirement.scala b/linker/shared/src/main/scala/org/scalajs/linker/standard/SymbolRequirement.scala similarity index 98% rename from linker/shared/src/main/scala/org/scalajs/linker/analyzer/SymbolRequirement.scala rename to linker/shared/src/main/scala/org/scalajs/linker/standard/SymbolRequirement.scala index 6ac326fad1..f6f7d566e7 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/analyzer/SymbolRequirement.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/standard/SymbolRequirement.scala @@ -7,7 +7,7 @@ \* */ -package org.scalajs.linker.analyzer +package org.scalajs.linker.standard sealed trait SymbolRequirement { final def ++(that: SymbolRequirement): SymbolRequirement = @@ -91,7 +91,7 @@ object SymbolRequirement { } } - private[analyzer] object Nodes { + private[linker] object Nodes { case class AccessModule(origin: String, moduleName: String) extends SymbolRequirement case class InstantiateClass(origin: String, className: String, constructor: String) extends SymbolRequirement From 2dc12088b4840ff886eb02791012a6ddaa4e2566 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 21 Jan 2018 17:20:44 +0100 Subject: [PATCH 0665/2665] Make `LinkedClass.copy` private. A `copy` method with lots of default parameters cannot be evolved in binary compatible ways. --- .../org/scalajs/linker/frontend/Refiner.scala | 2 +- .../frontend/optimizer/GenIncOptimizer.scala | 2 +- .../scalajs/linker/standard/LinkedClass.scala | 32 ++++++++++++++++++- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/linker/shared/src/main/scala/org/scalajs/linker/frontend/Refiner.scala b/linker/shared/src/main/scala/org/scalajs/linker/frontend/Refiner.scala index 40a67f1afa..fa7e965790 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/frontend/Refiner.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/frontend/Refiner.scala @@ -92,7 +92,7 @@ final class Refiner(config: CommonPhaseConfig) { if (info.isModuleAccessed) classDef.kind else classDef.kind.withoutModuleAccessor - classDef.copy( + classDef.refined( kind = kind, fields = fields, staticMethods = staticMethods, diff --git a/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/GenIncOptimizer.scala b/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/GenIncOptimizer.scala index ba0a3c349f..1a4f1adbdf 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/GenIncOptimizer.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/GenIncOptimizer.scala @@ -120,7 +120,7 @@ abstract class GenIncOptimizer private[optimizer] (config: CommonPhaseConfig) { if (linkedClass.kind == ClassKind.Interface) getDefaults(encodedName) else getClass(encodedName) - linkedClass.copy( + linkedClass.optimized( staticMethods = defs(getStaticsNamespace(encodedName)), memberMethods = defs(memberNamespace)) } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/standard/LinkedClass.scala b/linker/shared/src/main/scala/org/scalajs/linker/standard/LinkedClass.scala index 2ab3adba31..91e13210ed 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/standard/LinkedClass.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/standard/LinkedClass.scala @@ -66,7 +66,37 @@ final class LinkedClass( def fullName: String = Definitions.decodeClassName(encodedName) - def copy( + private[linker] def refined( + kind: ClassKind, + fields: List[FieldDef], + staticMethods: List[Versioned[MethodDef]], + memberMethods: List[Versioned[MethodDef]], + hasInstances: Boolean, + hasInstanceTests: Boolean, + hasRuntimeTypeInfo: Boolean + ): LinkedClass = { + copy( + kind = kind, + fields = fields, + staticMethods = staticMethods, + memberMethods = memberMethods, + hasInstances = hasInstances, + hasInstanceTests = hasInstanceTests, + hasRuntimeTypeInfo = hasRuntimeTypeInfo + ) + } + + private[linker] def optimized( + staticMethods: List[Versioned[MethodDef]], + memberMethods: List[Versioned[MethodDef]] + ): LinkedClass = { + copy( + staticMethods = staticMethods, + memberMethods = memberMethods + ) + } + + private def copy( name: Ident = this.name, kind: ClassKind = this.kind, jsClassCaptures: Option[List[ParamDef]] = this.jsClassCaptures, From ca4e703bb904eeddf6b03962890be551f86b86cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 26 Jan 2018 16:29:40 +0100 Subject: [PATCH 0666/2665] Introduce abstract LinkerFrontend and LinkerBackend in standard.*. Those classes are completely abstract and only expose the minimal API needed by `StandardLinkerImpl. This change ensures that there is no public API in `standard.*` that refers to "private" APIs, from subpackages of `linker` other than `standard` and `irio`. --- ....scala => LinkerBackendImplPlatform.scala} | 6 +- ...LinkerBackendImplPlatformExtensions.scala} | 4 +- ...scala => LinkerFrontendImplPlatform.scala} | 4 +- ....scala => LinkerBackendImplPlatform.scala} | 6 +- ...LinkerBackendImplPlatformExtensions.scala} | 4 +- .../closure/ClosureLinkerBackend.scala | 4 +- ...scala => LinkerFrontendImplPlatform.scala} | 4 +- .../org/scalajs/linker/StandardLinker.scala | 12 ++-- .../linker/backend/BasicLinkerBackend.scala | 4 +- ...rBackend.scala => LinkerBackendImpl.scala} | 46 +++------------ ...rontend.scala => LinkerFrontendImpl.scala} | 15 ++--- .../linker/standard/LinkerBackend.scala | 59 +++++++++++++++++++ .../linker/standard/LinkerFrontend.scala | 34 +++++++++++ .../linker/standard/StandardLinkerImpl.scala | 3 - 14 files changed, 133 insertions(+), 72 deletions(-) rename linker/js/src/main/scala/org/scalajs/linker/backend/{LinkerBackendPlatform.scala => LinkerBackendImplPlatform.scala} (80%) rename linker/js/src/main/scala/org/scalajs/linker/backend/{LinkerBackendPlatformExtensions.scala => LinkerBackendImplPlatformExtensions.scala} (91%) rename linker/js/src/main/scala/org/scalajs/linker/frontend/{LinkerFrontendPlatform.scala => LinkerFrontendImplPlatform.scala} (89%) rename linker/jvm/src/main/scala/org/scalajs/linker/backend/{LinkerBackendPlatform.scala => LinkerBackendImplPlatform.scala} (83%) rename linker/jvm/src/main/scala/org/scalajs/linker/backend/{LinkerBackendPlatformExtensions.scala => LinkerBackendImplPlatformExtensions.scala} (92%) rename linker/jvm/src/main/scala/org/scalajs/linker/frontend/{LinkerFrontendPlatform.scala => LinkerFrontendImplPlatform.scala} (90%) rename linker/shared/src/main/scala/org/scalajs/linker/backend/{LinkerBackend.scala => LinkerBackendImpl.scala} (68%) rename linker/shared/src/main/scala/org/scalajs/linker/frontend/{LinkerFrontend.scala => LinkerFrontendImpl.scala} (89%) create mode 100644 linker/shared/src/main/scala/org/scalajs/linker/standard/LinkerBackend.scala create mode 100644 linker/shared/src/main/scala/org/scalajs/linker/standard/LinkerFrontend.scala diff --git a/linker/js/src/main/scala/org/scalajs/linker/backend/LinkerBackendPlatform.scala b/linker/js/src/main/scala/org/scalajs/linker/backend/LinkerBackendImplPlatform.scala similarity index 80% rename from linker/js/src/main/scala/org/scalajs/linker/backend/LinkerBackendPlatform.scala rename to linker/js/src/main/scala/org/scalajs/linker/backend/LinkerBackendImplPlatform.scala index 8e42009e9c..015e7c606c 100644 --- a/linker/js/src/main/scala/org/scalajs/linker/backend/LinkerBackendPlatform.scala +++ b/linker/js/src/main/scala/org/scalajs/linker/backend/LinkerBackendImplPlatform.scala @@ -8,9 +8,9 @@ package org.scalajs.linker.backend -private[backend] object LinkerBackendPlatform { - import LinkerBackend.Config +private[backend] object LinkerBackendImplPlatform { + import LinkerBackendImpl.Config - def createLinkerBackend(config: Config): LinkerBackend = + def createLinkerBackend(config: Config): LinkerBackendImpl = new BasicLinkerBackend(config) } diff --git a/linker/js/src/main/scala/org/scalajs/linker/backend/LinkerBackendPlatformExtensions.scala b/linker/js/src/main/scala/org/scalajs/linker/backend/LinkerBackendImplPlatformExtensions.scala similarity index 91% rename from linker/js/src/main/scala/org/scalajs/linker/backend/LinkerBackendPlatformExtensions.scala rename to linker/js/src/main/scala/org/scalajs/linker/backend/LinkerBackendImplPlatformExtensions.scala index 6b73f6b927..942b91b180 100644 --- a/linker/js/src/main/scala/org/scalajs/linker/backend/LinkerBackendPlatformExtensions.scala +++ b/linker/js/src/main/scala/org/scalajs/linker/backend/LinkerBackendImplPlatformExtensions.scala @@ -8,8 +8,8 @@ package org.scalajs.linker.backend -object LinkerBackendPlatformExtensions { - import LinkerBackend.Config +object LinkerBackendImplPlatformExtensions { + import LinkerBackendImpl.Config final class ConfigExt private[backend] (private val self: Config) extends AnyVal { diff --git a/linker/js/src/main/scala/org/scalajs/linker/frontend/LinkerFrontendPlatform.scala b/linker/js/src/main/scala/org/scalajs/linker/frontend/LinkerFrontendImplPlatform.scala similarity index 89% rename from linker/js/src/main/scala/org/scalajs/linker/frontend/LinkerFrontendPlatform.scala rename to linker/js/src/main/scala/org/scalajs/linker/frontend/LinkerFrontendImplPlatform.scala index d59142760b..0ee9689c98 100644 --- a/linker/js/src/main/scala/org/scalajs/linker/frontend/LinkerFrontendPlatform.scala +++ b/linker/js/src/main/scala/org/scalajs/linker/frontend/LinkerFrontendImplPlatform.scala @@ -10,8 +10,8 @@ package org.scalajs.linker.frontend import org.scalajs.linker.frontend.optimizer._ -private[frontend] object LinkerFrontendPlatform { - import LinkerFrontend.Config +private[frontend] object LinkerFrontendImplPlatform { + import LinkerFrontendImpl.Config def createOptimizer(config: Config): Option[GenIncOptimizer] = { if (!config.optimizer) diff --git a/linker/jvm/src/main/scala/org/scalajs/linker/backend/LinkerBackendPlatform.scala b/linker/jvm/src/main/scala/org/scalajs/linker/backend/LinkerBackendImplPlatform.scala similarity index 83% rename from linker/jvm/src/main/scala/org/scalajs/linker/backend/LinkerBackendPlatform.scala rename to linker/jvm/src/main/scala/org/scalajs/linker/backend/LinkerBackendImplPlatform.scala index c2aa7a7f56..5b31df6b54 100644 --- a/linker/jvm/src/main/scala/org/scalajs/linker/backend/LinkerBackendPlatform.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/backend/LinkerBackendImplPlatform.scala @@ -10,10 +10,10 @@ package org.scalajs.linker.backend import org.scalajs.linker.backend.closure.ClosureLinkerBackend -private[backend] object LinkerBackendPlatform { - import LinkerBackend.Config +private[backend] object LinkerBackendImplPlatform { + import LinkerBackendImpl.Config - def createLinkerBackend(config: Config): LinkerBackend = { + def createLinkerBackend(config: Config): LinkerBackendImpl = { if (config.closureCompiler) new ClosureLinkerBackend(config) else diff --git a/linker/jvm/src/main/scala/org/scalajs/linker/backend/LinkerBackendPlatformExtensions.scala b/linker/jvm/src/main/scala/org/scalajs/linker/backend/LinkerBackendImplPlatformExtensions.scala similarity index 92% rename from linker/jvm/src/main/scala/org/scalajs/linker/backend/LinkerBackendPlatformExtensions.scala rename to linker/jvm/src/main/scala/org/scalajs/linker/backend/LinkerBackendImplPlatformExtensions.scala index 3f9c5edd7e..e9d28cb922 100644 --- a/linker/jvm/src/main/scala/org/scalajs/linker/backend/LinkerBackendPlatformExtensions.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/backend/LinkerBackendImplPlatformExtensions.scala @@ -10,8 +10,8 @@ package org.scalajs.linker.backend import org.scalajs.linker.backend.closure.ClosureLinkerBackend -object LinkerBackendPlatformExtensions { - import LinkerBackend.Config +object LinkerBackendImplPlatformExtensions { + import LinkerBackendImpl.Config final class ConfigExt private[backend] (val __private_self: Config) extends AnyVal { diff --git a/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala index c578c18ce0..afa6eee3f3 100644 --- a/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala @@ -31,8 +31,8 @@ import org.scalajs.linker.backend.emitter.Emitter * Runs a the Google Closure Compiler in advanced mode on the emitted code. * Use this for production builds. */ -final class ClosureLinkerBackend(config: LinkerBackend.Config) - extends LinkerBackend(config) { +final class ClosureLinkerBackend(config: LinkerBackendImpl.Config) + extends LinkerBackendImpl(config) { import config.commonConfig.coreSpec._ diff --git a/linker/jvm/src/main/scala/org/scalajs/linker/frontend/LinkerFrontendPlatform.scala b/linker/jvm/src/main/scala/org/scalajs/linker/frontend/LinkerFrontendImplPlatform.scala similarity index 90% rename from linker/jvm/src/main/scala/org/scalajs/linker/frontend/LinkerFrontendPlatform.scala rename to linker/jvm/src/main/scala/org/scalajs/linker/frontend/LinkerFrontendImplPlatform.scala index 8115ea8710..735a998829 100644 --- a/linker/jvm/src/main/scala/org/scalajs/linker/frontend/LinkerFrontendPlatform.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/frontend/LinkerFrontendImplPlatform.scala @@ -10,8 +10,8 @@ package org.scalajs.linker.frontend import org.scalajs.linker.frontend.optimizer._ -private[frontend] object LinkerFrontendPlatform { - import LinkerFrontend.Config +private[frontend] object LinkerFrontendImplPlatform { + import LinkerFrontendImpl.Config def createOptimizer(config: Config): Option[GenIncOptimizer] = { import config.commonConfig diff --git a/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala b/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala index ec153463fe..e7576337fa 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala @@ -13,8 +13,8 @@ import scala.language.implicitConversions import java.net.URI import org.scalajs.linker.standard._ -import org.scalajs.linker.frontend.LinkerFrontend -import org.scalajs.linker.backend.LinkerBackend +import org.scalajs.linker.frontend.LinkerFrontendImpl +import org.scalajs.linker.backend.LinkerBackendImpl object StandardLinker { import StandardLinkerPlatformExtensions._ @@ -30,20 +30,20 @@ object StandardLinker { .withParallel(config.parallel) .withBatchMode(config.batchMode) - val frontendConfig = LinkerFrontend.Config() + val frontendConfig = LinkerFrontendImpl.Config() .withCommonConfig(commonConfig) .withCheckIR(config.checkIR) .withOptimizer(config.optimizer) - val backendConfig = LinkerBackend.Config() + val backendConfig = LinkerBackendImpl.Config() .withCommonConfig(commonConfig) .withSourceMap(config.sourceMap) .withRelativizeSourceMapBase(config.relativizeSourceMapBase) .withClosureCompilerIfAvailable(config.closureCompilerIfAvailable) .withPrettyPrint(config.prettyPrint) - StandardLinkerImpl(LinkerFrontend(frontendConfig), - LinkerBackend(backendConfig)) + StandardLinkerImpl(LinkerFrontendImpl(frontendConfig), + LinkerBackendImpl(backendConfig)) } implicit def configExt(config: Config): ConfigExt = diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/BasicLinkerBackend.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/BasicLinkerBackend.scala index c1e5d7d160..421d3a6385 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/BasicLinkerBackend.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/BasicLinkerBackend.scala @@ -23,8 +23,8 @@ import org.scalajs.linker.backend.javascript.{ * * Simply emits the JavaScript without applying any further optimizations. */ -final class BasicLinkerBackend(config: LinkerBackend.Config) - extends LinkerBackend(config) { +final class BasicLinkerBackend(config: LinkerBackendImpl.Config) + extends LinkerBackendImpl(config) { private[this] val emitter = new Emitter(config.commonConfig) diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/LinkerBackend.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/LinkerBackendImpl.scala similarity index 68% rename from linker/shared/src/main/scala/org/scalajs/linker/backend/LinkerBackend.scala rename to linker/shared/src/main/scala/org/scalajs/linker/backend/LinkerBackendImpl.scala index a84cf37eec..98aab1d9b2 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/LinkerBackend.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/LinkerBackendImpl.scala @@ -25,47 +25,17 @@ import org.scalajs.linker.standard._ * You probably want to use an instance of [[linker.Linker]], rather than this * low-level class. */ -abstract class LinkerBackend(protected val config: LinkerBackend.Config) { +abstract class LinkerBackendImpl( + protected val config: LinkerBackendImpl.Config) + extends LinkerBackend { + /** Core specification that this linker backend implements. */ val coreSpec = config.commonConfig.coreSpec - - /** Symbols this backend needs to be present in the linking unit. */ - val symbolRequirements: SymbolRequirement - - /** Emit the given [[standard.LinkingUnit LinkingUnit]] to the target output. - * - * The linking unit given to `emit` must: - * - * - have the same `coreSpec` as this linker backend, and - * - contain the symbols listed in [[symbolRequirements]]. - * - * @param unit [[standard.LinkingUnit LinkingUnit]] to emit - * @param output File to write to - * @param logger Logger to use - */ - def emit(unit: LinkingUnit, output: WritableVirtualJSFile, - logger: Logger): Unit - - /** Verify that a [[standard.LinkingUnit LinkingUnit]] can be processed by - * this [[LinkerBackend]]. - * - * Currently, this only tests that the linking unit core specification - * matches [[coreSpec]]. - * - * In the future, this test could be extended to test [[symbolRequirements]] - * too. - * - * @throws java.lang.IllegalArgumentException if there is a mismatch - */ - protected def verifyUnit(unit: LinkingUnit): Unit = { - require(unit.coreSpec == coreSpec, - "LinkingUnit and LinkerBackend must agree on their core specification") - } } -object LinkerBackend { - def apply(config: Config): LinkerBackend = - LinkerBackendPlatform.createLinkerBackend(config) +object LinkerBackendImpl { + def apply(config: Config): LinkerBackendImpl = + LinkerBackendImplPlatform.createLinkerBackend(config) /** Configurations relevant to the backend */ final class Config private ( @@ -118,7 +88,7 @@ object LinkerBackend { } object Config { - import LinkerBackendPlatformExtensions._ + import LinkerBackendImplPlatformExtensions._ implicit def toPlatformExtensions(config: Config): ConfigExt = new ConfigExt(config) diff --git a/linker/shared/src/main/scala/org/scalajs/linker/frontend/LinkerFrontend.scala b/linker/shared/src/main/scala/org/scalajs/linker/frontend/LinkerFrontendImpl.scala similarity index 89% rename from linker/shared/src/main/scala/org/scalajs/linker/frontend/LinkerFrontend.scala rename to linker/shared/src/main/scala/org/scalajs/linker/frontend/LinkerFrontendImpl.scala index 4861710bad..a6e6aecc35 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/frontend/LinkerFrontend.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/frontend/LinkerFrontendImpl.scala @@ -23,10 +23,11 @@ import org.scalajs.linker.irio._ * You probably want to use an instance of [[linker.Linker]], rather than this * low-level class. * - * Attention: [[LinkerFrontend]] does not cache the IR input. It is advisable - * to do so, unless all IR is already in memory. + * Attention: [[LinkerFrontendImpl]] does not cache the IR input. It is + * advisable to do so, unless all IR is already in memory. */ -final class LinkerFrontend private (config: LinkerFrontend.Config) { +final class LinkerFrontendImpl private (config: LinkerFrontendImpl.Config) + extends LinkerFrontend { /** Core specification that this linker frontend implements. */ val coreSpec = config.commonConfig.coreSpec @@ -35,7 +36,7 @@ final class LinkerFrontend private (config: LinkerFrontend.Config) { new BaseLinker(config.commonConfig) private[this] val optOptimizer: Option[GenIncOptimizer] = - LinkerFrontendPlatform.createOptimizer(config) + LinkerFrontendImplPlatform.createOptimizer(config) private[this] val refiner: Refiner = new Refiner(config.commonConfig) @@ -72,9 +73,9 @@ final class LinkerFrontend private (config: LinkerFrontend.Config) { } } -object LinkerFrontend { - def apply(config: Config): LinkerFrontend = - new LinkerFrontend(config) +object LinkerFrontendImpl { + def apply(config: Config): LinkerFrontendImpl = + new LinkerFrontendImpl(config) /** Configurations relevant to the frontend */ final class Config private ( diff --git a/linker/shared/src/main/scala/org/scalajs/linker/standard/LinkerBackend.scala b/linker/shared/src/main/scala/org/scalajs/linker/standard/LinkerBackend.scala new file mode 100644 index 0000000000..abddb54711 --- /dev/null +++ b/linker/shared/src/main/scala/org/scalajs/linker/standard/LinkerBackend.scala @@ -0,0 +1,59 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js linker ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2018, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.linker.standard + +import org.scalajs.logging._ + +import org.scalajs.io._ + +/** A backend of a standard Scala.js linker. + * + * Produces a [[org.scalajs.io.VirtualJSFile VirtualJSFile]]. + * + * You probably want to use an instance of [[Linker]], rather than this + * low-level class. + */ +abstract class LinkerBackend { + + /** Core specification that this linker backend implements. */ + val coreSpec: CoreSpec + + /** Symbols this backend needs to be present in the linking unit. */ + val symbolRequirements: SymbolRequirement + + /** Emit the given [[LinkingUnit]] to the target output. + * + * The linking unit given to `emit` must: + * + * - have the same `coreSpec` as this linker backend, and + * - contain the symbols listed in [[symbolRequirements]]. + * + * @param unit [[LinkingUnit]] to emit + * @param output File to write to + * @param logger Logger to use + */ + def emit(unit: LinkingUnit, output: WritableVirtualJSFile, + logger: Logger): Unit + + /** Verify that a [[LinkingUnit]] can be processed by this [[LinkerBackend]]. + * + * Currently, this only tests that the linking unit core specification + * matches [[coreSpec]]. + * + * In the future, this test could be extended to test [[symbolRequirements]] + * too. + * + * @throws java.lang.IllegalArgumentException if there is a mismatch + */ + protected def verifyUnit(unit: LinkingUnit): Unit = { + require(unit.coreSpec == coreSpec, + "LinkingUnit and LinkerBackend must agree on their core specification") + } + +} diff --git a/linker/shared/src/main/scala/org/scalajs/linker/standard/LinkerFrontend.scala b/linker/shared/src/main/scala/org/scalajs/linker/standard/LinkerFrontend.scala new file mode 100644 index 0000000000..cf23977d0c --- /dev/null +++ b/linker/shared/src/main/scala/org/scalajs/linker/standard/LinkerFrontend.scala @@ -0,0 +1,34 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js linker ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2018, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.linker.standard + +import org.scalajs.logging._ + +import org.scalajs.linker._ +import org.scalajs.linker.irio._ + +/** A frontend for a standard Scala.js linker. + * + * Produces a [[LinkingUnit]]. + * + * You probably want to use an instance of [[Linker]], rather than this + * low-level class. + * + * Attention: a [[LinkerFrontend]] typically does not cache the IR input. It + * is advisable to do so, unless all IR is already in memory. + */ +abstract class LinkerFrontend { + /** Core specification that this linker frontend implements. */ + val coreSpec: CoreSpec + + /** Link and optionally optimize the given IR to a [[LinkingUnit]]. */ + def link(irFiles: Seq[VirtualScalaJSIRFile], + moduleInitializers: Seq[ModuleInitializer], + symbolRequirements: SymbolRequirement, logger: Logger): LinkingUnit +} diff --git a/linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerImpl.scala b/linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerImpl.scala index b1cf9a8846..10ea8099f7 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerImpl.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerImpl.scala @@ -17,9 +17,6 @@ import org.scalajs.logging.Logger import org.scalajs.io._ import org.scalajs.linker._ -import org.scalajs.linker.frontend.LinkerFrontend -import org.scalajs.linker.frontend.optimizer.IncOptimizer -import org.scalajs.linker.backend.{LinkerBackend, BasicLinkerBackend} import org.scalajs.linker.irio._ /** Standard implementation of a Scala.js linker. */ From 773d175975c749c2a85616864619fdddb3c54385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 30 Jan 2018 13:39:55 +0100 Subject: [PATCH 0667/2665] Unseal `ModuleKind`. We will want to add new module kinds in the future, so that class cannot be sealed. We make its constructor private so that it still cannot be extended from the outside. This means that our own code matching on those will not receive exhaustivity warnings, however, which is a pity, but seems unavoidable. --- .../shared/src/main/scala/org/scalajs/linker/ModuleKind.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linker/shared/src/main/scala/org/scalajs/linker/ModuleKind.scala b/linker/shared/src/main/scala/org/scalajs/linker/ModuleKind.scala index 459c89078f..d72df87503 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/ModuleKind.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/ModuleKind.scala @@ -10,7 +10,7 @@ package org.scalajs.linker /** Kind of module structure emitted for the Scala.js output. */ -sealed abstract class ModuleKind +abstract class ModuleKind private () object ModuleKind { From cbd3358aee118c9b403a6dda48f93abc6dd7d331 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 23 Mar 2018 19:44:52 +0100 Subject: [PATCH 0668/2665] Add a method `StandardLinker.clearable(config)`. It creates a new `ClearableLinker` wrapping a `StandardLinker`, using the `batchMode` of the `config`. --- .../src/main/scala/org/scalajs/linker/StandardLinker.scala | 3 +++ .../scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala b/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala index e7576337fa..44bd2a202d 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala @@ -46,6 +46,9 @@ object StandardLinker { LinkerBackendImpl(backendConfig)) } + def clearable(config: Config): ClearableLinker = + new ClearableLinker(() => apply(config), config.batchMode) + implicit def configExt(config: Config): ConfigExt = new ConfigExt(config) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 0b475b9d1a..5d6f4b6a92 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -123,7 +123,7 @@ private[sbtplugin] object ScalaJSPluginInternal { "Some things will go wrong.") } - new ClearableLinker(() => StandardLinker(config), config.batchMode) + StandardLinker.clearable(config) }, // Have `clean` reset the state of the incremental linker From 19fbe1d0aff57266ebb675f0a37ad5867353db95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 27 Mar 2018 22:57:31 +0200 Subject: [PATCH 0669/2665] Replace the constructor of `ClearableLinker` by an `apply` method. --- .../main/scala/org/scalajs/linker/ClearableLinker.scala | 8 +++++++- .../main/scala/org/scalajs/linker/StandardLinker.scala | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala b/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala index c5341902fc..ca2c1176cf 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala @@ -22,7 +22,8 @@ import org.scalajs.linker.irio._ * * This class is not thread-safe. */ -final class ClearableLinker(newLinker: () => Linker, batchMode: Boolean) +final class ClearableLinker private ( + newLinker: () => Linker, batchMode: Boolean) extends Linker { private[this] var _linker: Linker = _ @@ -60,3 +61,8 @@ final class ClearableLinker(newLinker: () => Linker, batchMode: Boolean) _linker = newLinker() } } + +object ClearableLinker { + def apply(newLinker: () => Linker, batchMode: Boolean): ClearableLinker = + new ClearableLinker(newLinker, batchMode) +} diff --git a/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala b/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala index 44bd2a202d..dd95f8cc15 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala @@ -47,7 +47,7 @@ object StandardLinker { } def clearable(config: Config): ClearableLinker = - new ClearableLinker(() => apply(config), config.batchMode) + ClearableLinker(() => apply(config), config.batchMode) implicit def configExt(config: Config): ConfigExt = new ConfigExt(config) From 7b2a7b256750f94e6c21e49ad58d29bfcc16b95d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 27 Mar 2018 23:17:21 +0200 Subject: [PATCH 0670/2665] Turn `ClearableLinker` into a completely abstract `trait`. --- .../org/scalajs/linker/ClearableLinker.scala | 104 +++++++++++------- 1 file changed, 65 insertions(+), 39 deletions(-) diff --git a/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala b/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala index ca2c1176cf..2d3884b728 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala @@ -16,53 +16,79 @@ import org.scalajs.linker.irio._ /** A box around a [[Linker]] to support clearing. * - * This further supports: - * - batch mode (clearing after every operation) - * - clearing if linker throws + * Calling `clear()` completely resets the state of this `ClearableLinker`, so + * that it can be used again without being affected by previous calls to + * `link`, even of those would have corrupted the internal state. * - * This class is not thread-safe. + * In addition to the contract of [[Linker]], if [[Linker.link]] throws an + * exception, the `ClearableLinker` is automatically `clear()`'ed. + * + * Implementations are allowed to automatically `clear()` in other cases, but + * never while a linking is in progress. + * + * Unless otherwise specified, instances of this trait are not thread-safe. */ -final class ClearableLinker private ( - newLinker: () => Linker, batchMode: Boolean) - extends Linker { +trait ClearableLinker extends Linker { + /** Completely resets the state of this `ClearableLinker`. + * + * After calling this method, this `ClearableLinker`, it can be used again + * without being affected by previous calls to `link`, even of those would + * have corrupted the internal state. + */ + def clear(): Unit +} + +object ClearableLinker { + /** Creates a [[ClearableLinker]] from a function creating a [[Linker]]. + * + * Every time `clear()` is called, a new [[Linker]] is obtained from the + * `newLinker` function to ensure that all the previous state is discarded. + * `newLinker` must returned a new, independent instance of [[Linker]] every + * time it is called. + * + * If `batchMode` is true, the returned `ClearableLinker` clears itself + * after every invocation of `link`. + */ + def apply(newLinker: () => Linker, batchMode: Boolean): ClearableLinker = + new ClearableLinkerImpl(newLinker, batchMode) - private[this] var _linker: Linker = _ + private final class ClearableLinkerImpl( + newLinker: () => Linker, batchMode: Boolean) + extends ClearableLinker { - def link(irFiles: Seq[VirtualScalaJSIRFile], - moduleInitializers: Seq[ModuleInitializer], - output: WritableVirtualJSFile, logger: Logger): Unit = { - linkerOp(_.link(irFiles, moduleInitializers, output, logger)) - } + private[this] var _linker: Linker = _ - def clear(): Unit = - _linker = null + def link(irFiles: Seq[VirtualScalaJSIRFile], + moduleInitializers: Seq[ModuleInitializer], + output: WritableVirtualJSFile, logger: Logger): Unit = { + linkerOp(_.link(irFiles, moduleInitializers, output, logger)) + } - @inline - private[this] def linkerOp[T](op: Linker => T): T = { - ensureLinker() + def clear(): Unit = + _linker = null - try { - op(_linker) - } catch { - // Clear if we throw - case t: Throwable => - clear() - throw t - } finally { - // Clear if we are in batch mode - if (batchMode) - clear() + @inline + private[this] def linkerOp[T](op: Linker => T): T = { + ensureLinker() + + try { + op(_linker) + } catch { + // Clear if we throw + case t: Throwable => + clear() + throw t + } finally { + // Clear if we are in batch mode + if (batchMode) + clear() + } } - } - private def ensureLinker(): Unit = { - // Ensure we have a linker - if (_linker == null) - _linker = newLinker() + private def ensureLinker(): Unit = { + // Ensure we have a linker + if (_linker == null) + _linker = newLinker() + } } } - -object ClearableLinker { - def apply(newLinker: () => Linker, batchMode: Boolean): ClearableLinker = - new ClearableLinker(newLinker, batchMode) -} From 289aae356636935588eb86dd19b04da2d12c230b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 27 Mar 2018 23:47:24 +0200 Subject: [PATCH 0671/2665] Add standard APIs to create standard linker frontends and backends. --- .../org/scalajs/linker/StandardLinker.scala | 36 ++++++------------- .../standard/StandardLinkerBackend.scala | 25 +++++++++++++ .../standard/StandardLinkerFrontend.scala | 23 ++++++++++++ 3 files changed, 58 insertions(+), 26 deletions(-) create mode 100644 linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerBackend.scala create mode 100644 linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerFrontend.scala diff --git a/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala b/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala index dd95f8cc15..d497b9c483 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/StandardLinker.scala @@ -13,37 +13,13 @@ import scala.language.implicitConversions import java.net.URI import org.scalajs.linker.standard._ -import org.scalajs.linker.frontend.LinkerFrontendImpl -import org.scalajs.linker.backend.LinkerBackendImpl object StandardLinker { import StandardLinkerPlatformExtensions._ def apply(config: Config): Linker = { - val coreSpec = CoreSpec( - config.semantics, - config.moduleKind, - config.esFeatures) - - val commonConfig = CommonPhaseConfig() - .withCoreSpec(coreSpec) - .withParallel(config.parallel) - .withBatchMode(config.batchMode) - - val frontendConfig = LinkerFrontendImpl.Config() - .withCommonConfig(commonConfig) - .withCheckIR(config.checkIR) - .withOptimizer(config.optimizer) - - val backendConfig = LinkerBackendImpl.Config() - .withCommonConfig(commonConfig) - .withSourceMap(config.sourceMap) - .withRelativizeSourceMapBase(config.relativizeSourceMapBase) - .withClosureCompilerIfAvailable(config.closureCompilerIfAvailable) - .withPrettyPrint(config.prettyPrint) - - StandardLinkerImpl(LinkerFrontendImpl(frontendConfig), - LinkerBackendImpl(backendConfig)) + StandardLinkerImpl(StandardLinkerFrontend(config), + StandardLinkerBackend(config)) } def clearable(config: Config): ClearableLinker = @@ -162,6 +138,14 @@ object StandardLinker { |)""".stripMargin } + private[linker] lazy val commonPhaseConfig: CommonPhaseConfig = { + val coreSpec = CoreSpec(semantics, moduleKind, esFeatures) + CommonPhaseConfig() + .withCoreSpec(coreSpec) + .withParallel(parallel) + .withBatchMode(batchMode) + } + private def copy( semantics: Semantics = semantics, moduleKind: ModuleKind = moduleKind, diff --git a/linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerBackend.scala b/linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerBackend.scala new file mode 100644 index 0000000000..6098075d4c --- /dev/null +++ b/linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerBackend.scala @@ -0,0 +1,25 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js linker ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2018, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.linker.standard + +import org.scalajs.linker._ +import org.scalajs.linker.backend.LinkerBackendImpl + +object StandardLinkerBackend { + def apply(config: StandardLinker.Config): LinkerBackend = { + val backendConfig = LinkerBackendImpl.Config() + .withCommonConfig(config.commonPhaseConfig) + .withSourceMap(config.sourceMap) + .withRelativizeSourceMapBase(config.relativizeSourceMapBase) + .withClosureCompilerIfAvailable(config.closureCompilerIfAvailable) + .withPrettyPrint(config.prettyPrint) + + LinkerBackendImpl(backendConfig) + } +} diff --git a/linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerFrontend.scala b/linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerFrontend.scala new file mode 100644 index 0000000000..e762038599 --- /dev/null +++ b/linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerFrontend.scala @@ -0,0 +1,23 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js linker ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2018, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.linker.standard + +import org.scalajs.linker._ +import org.scalajs.linker.frontend.LinkerFrontendImpl + +object StandardLinkerFrontend { + def apply(config: StandardLinker.Config): LinkerFrontend = { + val frontendConfig = LinkerFrontendImpl.Config() + .withCommonConfig(config.commonPhaseConfig) + .withCheckIR(config.checkIR) + .withOptimizer(config.optimizer) + + LinkerFrontendImpl(frontendConfig) + } +} From 6e846e62ae200cd8119ce52b32a0281bada2fa86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 28 Mar 2018 23:34:08 +0200 Subject: [PATCH 0672/2665] Upgrade to Scala 2.12.5. Also use that version by default in the build. --- Jenkinsfile | 11 +- ci/checksizes.sh | 6 +- .../scalajs/2.12.5/BlacklistedTests.txt | 1072 +++++ .../partest/scalajs/2.12.5/BuglistedTests.txt | 7 + .../scalajs/2.12.5/WhitelistedTests.txt | 3433 +++++++++++++++++ .../scalajs/2.12.5/neg/t6446-additional.check | 30 + .../scalajs/2.12.5/neg/t6446-list.check | 2 + .../scalajs/2.12.5/neg/t6446-missing.check | 30 + .../2.12.5/neg/t6446-show-phases.check | 29 + .../scalajs/2.12.5/neg/t7494-no-options.check | 31 + .../scalajs/2.12.5/run/Course-2002-01.check | 37 + .../scalajs/2.12.5/run/Course-2002-02.check | 187 + .../scalajs/2.12.5/run/Course-2002-04.check | 64 + .../scalajs/2.12.5/run/Course-2002-08.check | 171 + .../scalajs/2.12.5/run/Course-2002-09.check | 50 + .../scalajs/2.12.5/run/Course-2002-10.check | 46 + .../partest/scalajs/2.12.5/run/Meter.check | 16 + .../scalajs/2.12.5/run/MeterCaseClass.check | 16 + .../scalajs/2.12.5/run/anyval-box-types.check | 52 + .../tools/partest/scalajs/2.12.5/run/bugs.sem | 1 + .../scalajs/2.12.5/run/caseClassHash.check | 9 + .../partest/scalajs/2.12.5/run/deeps.check | 87 + .../scalajs/2.12.5/run/dynamic-anyval.check | 4 + .../scalajs/2.12.5/run/impconvtimes.check | 1 + .../partest/scalajs/2.12.5/run/imports.check | 21 + .../scalajs/2.12.5/run/interpolation.check | 32 + .../2.12.5/run/interpolationMultiline1.check | 26 + .../partest/scalajs/2.12.5/run/issue192.sem | 1 + .../2.12.5/run/macro-bundle-static.check | 6 + .../2.12.5/run/macro-bundle-toplevel.check | 6 + .../run/macro-bundle-whitebox-decl.check | 6 + .../partest/scalajs/2.12.5/run/misc.check | 62 + .../scalajs/2.12.5/run/promotion.check | 4 + .../partest/scalajs/2.12.5/run/runtime.check | 70 + .../scalajs/2.12.5/run/spec-self.check | 2 + .../scalajs/2.12.5/run/structural.check | 37 + .../scalajs/2.12.5/run/t0421-new.check | 3 + .../scalajs/2.12.5/run/t0421-old.check | 3 + .../partest/scalajs/2.12.5/run/t1503.sem | 1 + .../partest/scalajs/2.12.5/run/t3702.check | 2 + .../partest/scalajs/2.12.5/run/t4148.sem | 1 + .../partest/scalajs/2.12.5/run/t4617.check | 1 + .../partest/scalajs/2.12.5/run/t5356.check | 6 + .../partest/scalajs/2.12.5/run/t5552.check | 6 + .../partest/scalajs/2.12.5/run/t5568.check | 9 + .../partest/scalajs/2.12.5/run/t5629b.check | 10 + .../partest/scalajs/2.12.5/run/t5680.check | 3 + .../partest/scalajs/2.12.5/run/t5866.check | 2 + .../scalajs/2.12.5/run/t6318_primitives.check | 54 + .../partest/scalajs/2.12.5/run/t6662.check | 1 + .../partest/scalajs/2.12.5/run/t7657.check | 3 + .../partest/scalajs/2.12.5/run/t7763.sem | 1 + .../partest/scalajs/2.12.5/run/t8570a.check | 1 + .../partest/scalajs/2.12.5/run/t8764.check | 5 + .../partest/scalajs/2.12.5/run/t9387b.check | 1 + .../partest/scalajs/2.12.5/run/t9656.check | 14 + .../scalajs/2.12.5/run/try-catch-unify.check | 4 + .../2.12.5/run/virtpatmat_switch.check | 7 + .../2.12.5/run/virtpatmat_typetag.check | 10 + project/Build.scala | 4 +- .../resources/2.12.5/BlacklistedTests.txt | 142 + .../resources/2.12.5/WhitelistedTests.txt | 40 + scripts/assemble-cli.sh | 4 +- scripts/publish.sh | 8 +- 64 files changed, 5995 insertions(+), 16 deletions(-) create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/BlacklistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/BuglistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/WhitelistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/neg/t6446-additional.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/neg/t6446-list.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/neg/t6446-missing.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/neg/t6446-show-phases.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/neg/t7494-no-options.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Course-2002-01.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Course-2002-02.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Course-2002-04.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Course-2002-08.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Course-2002-09.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Course-2002-10.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Meter.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/MeterCaseClass.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/anyval-box-types.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/bugs.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/caseClassHash.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/deeps.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/dynamic-anyval.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/impconvtimes.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/imports.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/interpolation.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/interpolationMultiline1.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/issue192.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/macro-bundle-static.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/macro-bundle-toplevel.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/macro-bundle-whitebox-decl.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/misc.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/promotion.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/runtime.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/spec-self.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/structural.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t0421-new.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t0421-old.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t1503.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t3702.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t4148.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t4617.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t5356.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t5552.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t5568.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t5629b.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t5680.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t5866.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t6318_primitives.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t6662.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t7657.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t7763.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t8570a.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t8764.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t9387b.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t9656.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/try-catch-unify.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/virtpatmat_switch.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/virtpatmat_typetag.check create mode 100644 scala-test-suite/src/test/resources/2.12.5/BlacklistedTests.txt create mode 100644 scala-test-suite/src/test/resources/2.12.5/WhitelistedTests.txt diff --git a/Jenkinsfile b/Jenkinsfile index 7cbbde79d6..63fbf69c20 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -388,8 +388,8 @@ def otherJavaVersions = [] // should be ["1.6", "1.7"] but that's broken (see #3 def allJavaVersions = otherJavaVersions.clone() allJavaVersions << mainJavaVersion -def mainScalaVersion = "2.12.4" -def mainScalaVersions = ["2.10.2", "2.11.12", "2.12.4", "2.13.0-M2"] +def mainScalaVersion = "2.12.5" +def mainScalaVersions = ["2.10.2", "2.11.12", "2.12.5", "2.13.0-M2"] def otherScalaVersions = [ "2.10.3", "2.10.4", @@ -409,7 +409,8 @@ def otherScalaVersions = [ "2.12.0", "2.12.1", "2.12.2", - "2.12.3" + "2.12.3", + "2.12.4" ] // The 'quick' matrix @@ -438,10 +439,10 @@ allJavaVersions.each { javaVersion -> quickMatrix.add([task: "tools-cli-stubs", scala: "2.11.12", java: javaVersion]) } } -quickMatrix.add([task: "tools-cli-stubs", scala: "2.12.4", java: mainJavaVersion]) +quickMatrix.add([task: "tools-cli-stubs", scala: "2.12.5", java: mainJavaVersion]) quickMatrix.add([task: "partestc", scala: "2.11.0", java: "1.8"]) // #3293, should be: 1.7 quickMatrix.add([task: "sbtplugin-test", toolsscala: "2.10.7", sbt_version_override: "", java: "1.7"]) -quickMatrix.add([task: "sbtplugin-test", toolsscala: "2.12.4", sbt_version_override: "1.0.0", java: mainJavaVersion]) +quickMatrix.add([task: "sbtplugin-test", toolsscala: "2.12.5", sbt_version_override: "1.0.0", java: mainJavaVersion]) // The 'full' matrix def fullMatrix = quickMatrix.clone() diff --git a/ci/checksizes.sh b/ci/checksizes.sh index 429b3bde85..69b7e38b46 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -11,13 +11,13 @@ case $FULLVER in 2.11.12) VER=2.11 ;; - 2.12.4) + 2.12.5) VER=2.12 ;; 2.13.0-M2) VER=2.13.0-M2 ;; - 2.10.3|2.10.4|2.10.5|2.10.6|2.10.7|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7|2.11.8|2.11.11|2.12.0|2.12.1|2.12.2|2.12.3) + 2.10.3|2.10.4|2.10.5|2.10.6|2.10.7|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7|2.11.8|2.11.11|2.12.0|2.12.1|2.12.2|2.12.3|2.12.4) echo "Ignoring checksizes for Scala $FULLVER" exit 0 ;; @@ -48,7 +48,7 @@ case $FULLVER in REVERSI_PREOPT_GZ_EXPECTEDSIZE=71000 REVERSI_OPT_GZ_EXPECTEDSIZE=32000 ;; - 2.12.4) + 2.12.5) REVERSI_PREOPT_EXPECTEDSIZE=630000 REVERSI_OPT_EXPECTEDSIZE=147000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=76000 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/BlacklistedTests.txt new file mode 100644 index 0000000000..534ec3149b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/BlacklistedTests.txt @@ -0,0 +1,1072 @@ +# +# POS +# + +# Using Jsoup, what's that? +pos/cycle-jsoup.scala + +# Spuriously fails too often, and causes other subsequent tests to fail too +# Note that this test, by design, stress-tests type checking +pos/t6367.scala + +# Kills our IR serializer, it's an artificially super-deep if/else if +pos/t9181.scala + +# Resource hungry, does not exist in 2.12.x anymore +pos/t10387.scala + +# +# NEG +# + +# Screws up, but not really our problem (error: None.get instead of +# phase ordering error) +neg/t7494-multi-right-after +neg/t7494-right-after-before +neg/t7622-multi-followers +neg/t7622-cyclic-dependency + +# Uses some strange macro cross compile mechanism. +neg/macro-incompatible-macro-engine-c.scala + +# Spurious failures +neg/inlineMaxSize.scala +neg/patmatexhaust-huge.scala + +# Uses .java files +run/t9200 +run/noInlineUnknownIndy + +# +# RUN +# + +# Relies on the exact toString() representation of Floats/Doubles +run/t2378.scala + +# Uses ClassTags on existentials which are broken in Scala (see #251) +run/valueclasses-classtag-existential.scala + +# Relies on a particular execution speed +run/t5857.scala + +# Using parts of the javalib we don't plan to support + +run/t5018.scala +run/t2417.scala +run/t4813.scala +run/lazy-concurrent.scala +run/t3667.scala +run/t3038d.scala +run/shutdownhooks.scala +run/t5590.scala +run/t3895b.scala +run/t5974.scala +run/hashset.scala +run/t5262.scala +run/serialize-stream.scala +run/sysprops.scala +run/lambda-serialization-gc.scala +run/t9390.scala +run/t9390b.scala +run/t9390c.scala +run/trait-defaults-super.scala +run/t2849.scala +run/t1360.scala +run/t3199b.scala +run/t8690.scala +run/t10488.scala +run/various-flat-classpath-types.scala + +# Uses java.util.Collections +run/t2250.scala + +# Uses java.math.BigDecimal / BigInteger : but failures not due to them +run/hashhash.scala +run/is-valid-num.scala + +# Documented semantic difference on String.split(x: Array[Char]) +run/t0325.scala + +# Using Threads +run/t6969.scala +run/inner-obj-auto.scala +run/predef-cycle.scala +run/synchronized.scala +run/sd409.scala + +# Uses java.security +run/t2318.scala + +# Tries to catch java.lang.StackOverflowError +run/t6154.scala + +# Tries to catch java.lang.OutOfMemoryError +run/t7880.scala + +# Taking too much time, because JavaScript is not as fast as the JVM + +run/collections.scala +run/t3989.scala +run/adding-growing-set.scala +run/t3242.scala +run/hashCodeDistribution.scala +run/t408.scala +run/t6584.scala +run/t6853.scala +run/UnrolledBuffer.scala +run/t6253a.scala +run/t6253b.scala +run/t6253c.scala +run/numbereq.scala +run/t4658.scala + +# Crashes Rhino + +run/bridges.scala +run/patmat-exprs.scala + +# Using partest properties + +run/tailcalls.scala +run/t4294.scala +run/t6331b.scala + +# Using IO + +run/t6488.scala +run/t6988.scala + +# Object{Output|Input}Streams +run/t6935.scala +run/t8188.scala +run/t9375.scala +run/t9365.scala +run/inlineAddDeserializeLambda.scala +run/sammy_seriazable.scala +run/lambda-serialization-security.scala +run/t10232.scala +run/t10233.scala +run/t10244.scala +run/t10522.scala + +# Using System.getProperties + +run/t4426.scala + +# Using Await + +run/t7336.scala +run/t7775.scala +run/t10513.scala +run/future-flatmap-exec-count.scala + +# Using detailed stack trace + +run/t6308.scala + +# Using reflection + +run/t6063 + +run/mixin-bridge-methods.scala +run/t5125.scala +run/outertest.scala +run/t6223.scala +run/t5652b +run/elidable-opt.scala +run/nullable-lazyvals.scala +run/t4794.scala +run/t5652 +run/t5652c +run/getClassTest-old.scala +run/t8960.scala +run/t7965.scala +run/t8087.scala +run/t8931.scala +run/t8445.scala +run/lambda-serialization.scala + +run/reflection-repl-classes.scala +run/t5256e.scala +run/typetags_core.scala +run/reflection-constructormirror-toplevel-badpath.scala +run/t5276_1b.scala +run/reflection-sorted-decls.scala +run/toolbox_typecheck_implicitsdisabled.scala +run/t5418b.scala +run/toolbox_typecheck_macrosdisabled2.scala +run/abstypetags_serialize.scala +run/all-overridden.scala +run/showraw_tree_kinds.scala +run/showraw_tree_types_ids.scala +run/showraw_tree_types_typed.scala +run/showraw_tree_ids.scala +run/showraw_tree_ultimate.scala +run/t5266_2.scala +run/t5274_1.scala +run/t5224.scala +run/reflection-sanitychecks.scala +run/t6086-vanilla.scala +run/t5277_2.scala +run/reflection-methodsymbol-params.scala +run/reflection-valueclasses-standard.scala +run/t5274_2.scala +run/t5423.scala +run/reflection-modulemirror-toplevel-good.scala +run/t5419.scala +run/t5271_3.scala +run/reflection-enclosed-nested-basic.scala +run/reflection-enclosed-nested-nested-basic.scala +run/fail-non-value-types.scala +run/exprs_serialize.scala +run/t5258a.scala +run/typetags_without_scala_reflect_manifest_lookup.scala +run/t4110-new.scala +run/t5273_2b_newpatmat.scala +run/t6277.scala +run/t5335.scala +run/toolbox_typecheck_macrosdisabled.scala +run/reflection-modulemirror-inner-good.scala +run/t5229_2.scala +run/typetags_multi.scala +run/typetags_without_scala_reflect_typetag_manifest_interop.scala +run/reflection-constructormirror-toplevel-good.scala +run/reflection-magicsymbols-invoke.scala +run/t6392b.scala +run/t5229_1.scala +run/reflection-magicsymbols-vanilla.scala +run/t5225_2.scala +run/runtimeEval1.scala +run/reflection-enclosed-nested-inner-basic.scala +run/reflection-fieldmirror-ctorparam.scala +run/t6181.scala +run/reflection-magicsymbols-repl.scala +run/t5272_2_newpatmat.scala +run/t5270.scala +run/t5418a.scala +run/t5276_2b.scala +run/t5256f.scala +run/reflection-enclosed-basic.scala +run/reflection-constructormirror-inner-badpath.scala +run/interop_typetags_are_manifests.scala +run/newTags.scala +run/t5273_1_newpatmat.scala +run/reflection-constructormirror-nested-good.scala +run/t2236-new.scala +run/existentials3-new.scala +run/t6323b.scala +run/t5943a1.scala +run/reflection-fieldmirror-getsetval.scala +run/t5272_1_oldpatmat.scala +run/t5256h.scala +run/t1195-new.scala +run/t5840.scala +run/reflection-methodsymbol-returntype.scala +run/reflection-fieldmirror-accessorsareokay.scala +run/reflection-sorted-members.scala +run/reflection-allmirrors-tostring.scala +run/valueclasses-typetag-existential.scala +run/toolbox_console_reporter.scala +run/reflection-enclosed-inner-inner-basic.scala +run/t5256b.scala +run/bytecodecs.scala +run/elidable.scala +run/freetypes_false_alarm1.scala +run/freetypes_false_alarm2.scala +run/getClassTest-new.scala +run/idempotency-extractors.scala +run/idempotency-case-classes.scala +run/idempotency-this.scala +run/idempotency-labels.scala +run/idempotency-lazy-vals.scala +run/interop_manifests_are_abstypetags.scala +run/interop_manifests_are_typetags.scala +run/abstypetags_core.scala +run/macro-reify-abstypetag-notypeparams +run/macro-reify-abstypetag-typeparams-tags +run/macro-reify-abstypetag-typeparams-notags +run/macro-reify-abstypetag-usetypetag +run/macro-reify-freevars +run/macro-reify-splice-outside-reify +run/macro-reify-tagless-a +run/macro-reify-type +run/macro-reify-typetag-typeparams-tags +run/macro-reify-typetag-notypeparams +run/macro-undetparams-implicitval +run/manifests-new.scala +run/manifests-old.scala +run/no-pickle-skolems +run/position-val-def.scala +run/reflect-priv-ctor.scala +run/primitive-sigs-2-new.scala +run/primitive-sigs-2-old.scala +run/reflection-enclosed-inner-basic.scala +run/reflection-enclosed-inner-nested-basic.scala +run/reflection-constructormirror-inner-good.scala +run/reflection-constructormirror-nested-badpath.scala +run/reflection-fancy-java-classes +run/reflection-fieldsymbol-navigation.scala +run/reflection-fieldmirror-nmelocalsuffixstring.scala +run/reflection-fieldmirror-getsetvar.scala +run/reflection-fieldmirror-privatethis.scala +run/reflection-implicit.scala +run/reflection-mem-glbs.scala +run/reflection-mem-tags.scala +run/reflection-java-annotations +run/reflection-java-crtp +run/reflection-methodsymbol-typeparams.scala +run/reflection-modulemirror-nested-badpath.scala +run/reflection-modulemirror-inner-badpath.scala +run/reflection-modulemirror-nested-good.scala +run/reflection-modulemirror-toplevel-badpath.scala +run/reflection-sync-subtypes.scala +run/reflinit.scala +run/reflection-valueclasses-derived.scala +run/reflection-valueclasses-magic.scala +run/resetattrs-this.scala +run/runtimeEval2.scala +run/showraw_aliases.scala +run/showraw_mods.scala +run/shortClass.scala +run/showraw_nosymbol.scala +run/showraw_tree.scala +run/showraw_tree_types_untyped.scala +run/t1167.scala +run/t2577.scala +run/t2873.scala +run/t2886.scala +run/t2251b.scala +run/t3346j.scala +run/t3507-new.scala +run/t3569.scala +run/t5125b.scala +run/t5225_1.scala +run/t3425b +run/t5256a.scala +run/t5230.scala +run/t5256c.scala +run/t5256g.scala +run/t5266_1.scala +run/t5269.scala +run/t5271_1.scala +run/t5271_2.scala +run/t5271_4.scala +run/t5272_1_newpatmat.scala +run/t5272_2_oldpatmat.scala +run/t5273_1_oldpatmat.scala +run/t5273_2a_newpatmat.scala +run/t5273_2a_oldpatmat.scala +run/t5275.scala +run/t5276_1a.scala +run/t5276_2a.scala +run/t5277_1.scala +run/t5279.scala +run/t5334_1.scala +run/t5334_2.scala +run/t5415.scala +run/t5418.scala +run/t5676.scala +run/t5704.scala +run/t5710-1.scala +run/t5710-2.scala +run/t5770.scala +run/t5894.scala +run/t5816.scala +run/t5824.scala +run/t5912.scala +run/t5942.scala +run/t5943a2.scala +run/t6023.scala +run/t6113.scala +run/t6175.scala +run/t6178.scala +run/t6199-mirror.scala +run/t6199-toolbox.scala +run/t6240-universe-code-gen.scala +run/t6221 +run/t6260b.scala +run/t6259.scala +run/t6287.scala +run/t6344.scala +run/t6392a.scala +run/t6591_1.scala +run/t6591_2.scala +run/t6591_3.scala +run/t6591_5.scala +run/t6591_6.scala +run/t6591_7.scala +run/t6608.scala +run/t6677.scala +run/t6687.scala +run/t6715.scala +run/t6719.scala +run/t6793.scala +run/t6860.scala +run/t6793b.scala +run/t6793c.scala +run/t7045.scala +run/t7046.scala +run/t7008-scala-defined +run/t7120b.scala +run/t7151.scala +run/t7214.scala +run/t7235.scala +run/t7331a.scala +run/t7331b.scala +run/t7331c.scala +run/t7558.scala +run/t7556 +run/t7779.scala +run/t7868b.scala +run/toolbox_current_run_compiles.scala +run/toolbox_default_reporter_is_silent.scala +run/toolbox_parse_package.scala +run/toolbox_silent_reporter.scala +run/toolbox_typecheck_inferimplicitvalue.scala +run/typetags_serialize.scala +run/valueclasses-typetag-basic.scala +run/WeakHashSetTest.scala +run/valueclasses-typetag-generic.scala +run/t4023.scala +run/t4024.scala +run/t6380.scala +run/t5273_2b_oldpatmat.scala +run/t8104 +run/t8047.scala +run/t6992 +run/var-arity-class-symbol.scala +run/typetags_symbolof_x.scala +run/typecheck +run/t8190.scala +run/t8192 +run/t8177f.scala +run/t8199.scala +run/t7932.scala +run/t7700.scala +run/t7570c.scala +run/t7570b.scala +run/t7533.scala +run/t7570a.scala +run/t7044 +run/t7328.scala +run/t6733.scala +run/t6554.scala +run/t6732.scala +run/t6379 +run/t6411b.scala +run/t6411a.scala +run/t6260c.scala +run/t6260-delambdafy.scala +run/showdecl +run/reflection-sync-potpourri.scala +run/reflection-tags.scala +run/reflection-companiontype.scala +run/reflection-scala-annotations.scala +run/reflection-idtc.scala +run/macro-reify-nested-b2 +run/mixin-signatures.scala +run/reflection-companion.scala +run/macro-reify-nested-b1 +run/macro-reify-nested-a2 +run/macro-reify-nested-a1 +run/macro-reify-chained2 +run/macro-reify-chained1 +run/inferred-type-constructors.scala +run/mirror_symbolof_x.scala +run/t8196.scala +run/t8549b.scala +run/t8574.scala +run/t8549.scala +run/t8637.scala +run/t8253.scala +run/t9027.scala +run/t6622.scala +run/toolbox_expand_macro.scala +run/toolbox-varargs +run/t9252.scala +run/t9182.scala +run/t9102.scala +run/t720.scala +run/t9408.scala +run/t10527.scala +run/t10650 +run/trait-default-specialize.scala +run/lazy-locals-2.scala +run/t5294.scala +run/trait_fields_final.scala +run/trait_fields_bytecode.scala +run/trait_fields_volatile.scala +run/junitForwarders +run/reflect-java-param-names + +run/reify_newimpl_29.scala +run/reify_magicsymbols.scala +run/reify_inheritance.scala +run/reify_newimpl_12.scala +run/reify_typerefs_2b.scala +run/reify_csv.scala +run/reify_inner2.scala +run/reify_maps_oldpatmat.scala +run/reify_newimpl_43.scala +run/reify_nested_inner_refers_to_local.scala +run/reify_closure7.scala +run/reify_closure8b.scala +run/reify_typerefs_3b.scala +run/reify_newimpl_44.scala +run/reify_newimpl_06.scala +run/reify_newimpl_05.scala +run/reify_newimpl_20.scala +run/reify_newimpl_23.scala +run/reify_metalevel_breach_-1_refers_to_1.scala +run/reify_newimpl_41.scala +run/reify-repl-fail-gracefully.scala +run/reify_fors_oldpatmat.scala +run/reify_inner3.scala +run/reify_closure8a.scala +run/reify_closures10.scala +run/reify_ann2a.scala +run/reify_newimpl_51.scala +run/reify_newimpl_47.scala +run/reify_extendbuiltins.scala +run/reify_newimpl_30.scala +run/reify_newimpl_38.scala +run/reify_closure2a.scala +run/reify_newimpl_45.scala +run/reify_closure1.scala +run/reify_generic2.scala +run/reify_printf.scala +run/reify_closure6.scala +run/reify_newimpl_37.scala +run/reify_newimpl_35.scala +run/reify_typerefs_3a.scala +run/reify_newimpl_25.scala +run/reify_ann4.scala +run/reify_typerefs_1b.scala +run/reify_newimpl_22.scala +run/reify_this.scala +run/reify_typerefs_2a.scala +run/reify_newimpl_03.scala +run/reify_newimpl_48.scala +run/reify_varargs.scala +run/reify_newimpl_42.scala +run/reify_newimpl_15.scala +run/reify_nested_inner_refers_to_global.scala +run/reify_newimpl_02.scala +run/reify_newimpl_01.scala +run/reify_fors_newpatmat.scala +run/reify_classfileann_a.scala +run/reify_nested_outer_refers_to_local.scala +run/reify_newimpl_13.scala +run/reify_closure5a.scala +run/reify_inner4.scala +run/reify_sort.scala +run/reify_ann1a.scala +run/reify_classfileann_b.scala +run/reify_closure4a.scala +run/reify_newimpl_33.scala +run/reify_sort1.scala +run/reify_properties.scala +run/reify_generic.scala +run/reify_newimpl_27.scala +run/reify-aliases.scala +run/reify_ann3.scala +run/reify-staticXXX.scala +run/reify_ann1b.scala +run/reify_ann5.scala +run/reify_anonymous.scala +run/reify-each-node-type.scala +run/reify_copypaste2.scala +run/reify_closure3a.scala +run/reify_copypaste1.scala +run/reify_complex.scala +run/reify_for1.scala +run/reify_getter.scala +run/reify_implicits-new.scala +run/reify_inner1.scala +run/reify_implicits-old.scala +run/reify_lazyunit.scala +run/reify_lazyevaluation.scala +run/reify_maps_newpatmat.scala +run/reify_metalevel_breach_+0_refers_to_1.scala +run/reify_metalevel_breach_-1_refers_to_0_a.scala +run/reify_metalevel_breach_-1_refers_to_0_b.scala +run/reify_nested_outer_refers_to_global.scala +run/reify_newimpl_04.scala +run/reify_newimpl_14.scala +run/reify_newimpl_11.scala +run/reify_newimpl_18.scala +run/reify_newimpl_19.scala +run/reify_newimpl_31.scala +run/reify_newimpl_21.scala +run/reify_newimpl_36.scala +run/reify_newimpl_39.scala +run/reify_newimpl_40.scala +run/reify_newimpl_49.scala +run/reify_newimpl_50.scala +run/reify_newimpl_52.scala +run/reify_renamed_term_basic.scala +run/reify_renamed_term_local_to_reifee.scala +run/reify_renamed_term_overloaded_method.scala +run/reify_renamed_type_basic.scala +run/reify_renamed_type_local_to_reifee.scala +run/reify_renamed_type_spliceable.scala +run/reify_typerefs_1a.scala +run/reify_timeofday.scala +run/reify_renamed_term_t5841.scala + +run/t7521b.scala +run/t8575b.scala +run/t8575c.scala +run/t8944c.scala +run/t9535.scala +run/t9437a +run/t9814.scala +run/t10009.scala +run/t10075.scala +run/t10075b + +run/t8756.scala +run/inferred-type-constructors-hou.scala +run/trait-static-forwarder +run/SD-235.scala +run/t10026.scala +run/checkinit.scala +run/reflection-clinit +run/reflection-clinit-nested + +# Uses refletction indirectly through +# scala.runtime.ScalaRunTime.replStringOf +run/t6634.scala + +# Using reflection to invoke macros. These tests actually don't require +# or test reflection, but use it to separate compilation units nicely. +# It's a pity we cannot use them + +run/macro-abort-fresh +run/macro-expand-varargs-explicit-over-nonvarargs-bad +run/macro-invalidret-doesnt-conform-to-def-rettype +run/macro-invalidret-nontypeable +run/macro-invalidusage-badret +run/macro-invalidusage-partialapplication +run/macro-invalidusage-partialapplication-with-tparams +run/macro-reflective-ma-normal-mdmi +run/macro-reflective-mamd-normal-mi + +# Using macros, but indirectly creating calls to reflection +run/macro-reify-unreify + +# Using Enumeration in a way we cannot fix + +run/enums.scala +run/t3719.scala +run/t8611b.scala + +# Exceptions that become JavaScriptException + +run/pf-catch.scala +run/exceptions-2.scala +run/exceptions-nest.scala +run/t8601c.scala +run/t8601b.scala +run/inlineHandlers.scala + +# Expecting unsupported exceptions (e.g. ArrayIndexOutOfBounds) +run/optimizer-array-load.scala +run/t6827.scala +run/t8601.scala + +# Expecting exceptions that are linking errors in Scala.js (e.g. NoSuchMethodException) +run/t10334.scala + +# Playing with classfile format + +run/classfile-format-51.scala +run/classfile-format-52.scala + +# Concurrent collections (TrieMap) +# has too much stuff implemented in *.java, so no support +run/triemap-hash.scala + +# Using parallel collections + +run/t5375.scala +run/t4894.scala +run/ctries-new +run/collection-conversions.scala +run/concurrent-map-conversions.scala +run/t4761.scala +run/t7498.scala +run/t6448.scala +run/ctries-old +run/map_java_conversions.scala +run/parmap-ops.scala +run/pc-conversions.scala +run/t4459.scala +run/t4608.scala +run/t4723.scala +run/t4895.scala +run/t6052.scala +run/t6410.scala +run/t6467.scala +run/t6908.scala +run/t8955.scala + +# Using scala.xml + +run/t4124.scala + +# Using Swing + +run/t3613.scala + +# Using the REPL + +run/t4285.scala +run/constant-type.scala +run/repl-bare-expr.scala +run/repl-parens.scala +run/repl-assign.scala +run/t5583.scala +run/treePrint.scala +run/constrained-types.scala +run/repl-power.scala +run/t4710.scala +run/repl-paste.scala +run/repl-reset.scala +run/repl-paste-3.scala +run/t6329_repl.scala +run/t6273.scala +run/repl-paste-2.scala +run/t5655.scala +run/t5072.scala +run/repl-colon-type.scala +run/repl-trim-stack-trace.scala +run/t4594-repl-settings.scala +run/repl-save.scala +run/repl-paste-raw.scala +run/repl-paste-4.scala +run/t7801.scala +run/repl-backticks.scala +run/t6633.scala +run/repl-inline.scala + +# Using the Repl (scala.tools.partest.ReplTest) +run/class-symbol-contravariant.scala +run/lub-visibility.scala +run/macro-bundle-repl.scala +run/macro-repl-basic.scala +run/macro-repl-dontexpand.scala +run/macro-system-properties.scala +run/reflection-equality.scala +run/reflection-repl-elementary.scala +run/reify_newimpl_26.scala +run/repl-out-dir.scala +run/repl-term-macros.scala +run/repl-transcript.scala +run/repl-type-verbose.scala +run/t3376.scala +run/t4025.scala +run/t4172.scala +run/t4216.scala +run/t4542.scala +run/t4671.scala +run/t5256d.scala +run/t5535.scala +run/t5537.scala +run/t5789.scala +run/t6086-repl.scala +run/t6146b.scala +run/t6187.scala +run/t6320.scala +run/t6381.scala +run/t6434.scala +run/t6439.scala +run/t6507.scala +run/t6549.scala +run/t6937.scala +run/t7185.scala +run/t7319.scala +run/t7482a.scala +run/t7634.scala +run/t7747-repl.scala +run/t7805-repl-i.scala +run/tpeCache-tyconCache.scala +run/repl-empty-package +run/repl-javap-def.scala +run/repl-javap-mem.scala +run/repl-javap-outdir +run/repl-javap.scala +run/t6329_repl_bug.scala +run/t4950.scala +run/xMigration.scala +run/t6541-option.scala +run/repl-serialization.scala +run/t9174.scala +run/repl-paste-5.scala +run/repl-no-uescape.scala +run/repl-no-imports-no-predef-classbased.scala +run/repl-implicits-nopredef.scala +run/repl-classbased.scala +run/repl-no-imports-no-predef-power.scala +run/repl-paste-b.scala +run/repl-paste-6.scala +run/repl-implicits.scala +run/repl-no-imports-no-predef.scala +run/repl-paste-raw-b.scala +run/repl-paste-raw-c.scala +run/t9749-repl-dot.scala +run/trait_fields_repl.scala +run/t7139 +run/t9689 +run/trailing-commas.scala +run/t4700.scala +run/t9880-9881.scala +run/repl-kind.scala +run/t10284.scala +run/t9016.scala + +# Using Scala Script (partest.ScriptTest) + +run/t7711-script-args.scala +run/t4625.scala +run/t4625c.scala +run/t4625b.scala + +# Using the compiler API + +run/t2512.scala +run/analyzerPlugins.scala +run/compiler-asSeenFrom.scala +run/t5603.scala +run/t6440.scala +run/t5545.scala +run/existentials-in-compiler.scala +run/global-showdef.scala +run/stream_length.scala +run/annotatedRetyping.scala +run/imain.scala +run/existential-rangepos.scala +run/delambdafy_uncurry_byname_inline.scala +run/delambdafy_uncurry_byname_method.scala +run/delambdafy_uncurry_inline.scala +run/delambdafy_t6555.scala +run/delambdafy_uncurry_method.scala +run/delambdafy_t6028.scala +run/memberpos.scala +run/programmatic-main.scala +run/reflection-names.scala +run/settings-parse.scala +run/sm-interpolator.scala +run/t1501.scala +run/t1500.scala +run/sammy_java8.scala +run/t1618.scala +run/t2464 +run/t4072.scala +run/t5064.scala +run/t5385.scala +run/t5699.scala +run/t5717.scala +run/t5940.scala +run/t6028.scala +run/t6194.scala +run/t6669.scala +run/t6745-2.scala +run/t7096.scala +run/t7271.scala +run/t7337.scala +run/t7398.scala +run/t7569.scala +run/t7852.scala +run/t7817-tree-gen.scala +run/t7825.scala + +# partest.ParserTest +run/t3368.scala +run/t3368-b.scala +run/t3368-c.scala +run/t3368-d.scala +run/t9944.scala + +# partest.DirectTest +run/maxerrs.scala +run/t6288.scala +run/t6331.scala +run/t6440b.scala +run/t6555.scala +run/t7876.scala +run/typetags_without_scala_reflect_typetag_lookup.scala +run/dynamic-updateDynamic.scala +run/dynamic-selectDynamic.scala +run/dynamic-applyDynamic.scala +run/dynamic-applyDynamicNamed.scala +run/t4841-isolate-plugins +run/large_code.scala +run/macroPlugins-namerHooks.scala +run/t4841-no-plugin.scala +run/t4332.scala +run/t8029.scala +run/t8046 +run/t5905-features.scala +run/t5905b-features.scala +run/large_class.scala +run/t8708_b +run/icode-reader-dead-code.scala +run/t5938.scala +run/t8502.scala +run/t6502.scala +run/t8907.scala +run/t9097.scala +run/macroPlugins-enterStats.scala +run/sbt-icode-interface.scala +run/t8502b.scala +run/repl-paste-parse.scala +run/t5463.scala +run/t8433.scala +run/sd275.scala +run/sd275-java +run/t10471.scala +run/t6130.scala +run/t9437b.scala +run/t10552 + +# Using partest.StoreReporterDirectTest +run/t10171 + +# partest.StubErrorMessageTest +run/StubErrorBInheritsFromA.scala +run/StubErrorComplexInnerClass.scala +run/StubErrorHK.scala +run/StubErrorReturnTypeFunction.scala +run/StubErrorReturnTypeFunction2.scala +run/StubErrorReturnTypePolyFunction.scala +run/StubErrorSubclasses.scala +run/StubErrorTypeclass.scala +run/StubErrorTypeDef.scala + +# partest.CompilerTest +run/t8852a.scala + +# partest.ASMConverters +run/t9403 + +# partest.BytecodeTest +run/t7106 +run/t7974 +run/t8601-closure-elim.scala +run/t4788 +run/t4788-separate-compilation + +# partest.SessionTest +run/t8843-repl-xlat.scala +run/t9206.scala +run/t9170.scala +run/t8918-unary-ids.scala +run/t1931.scala +run/t8935-class.scala +run/t8935-object.scala + +# partest.JavapTest +run/t8608-no-format.scala + +# Using .java source files + +run/t4317 +run/t4238 +run/t2296c +run/t4119 +run/t4283 +run/t4891 +run/t6168 +run/t6168b +run/t6240a +run/t6240b +run/t6548 +run/t6989 +run/t7008 +run/t7246 +run/t7246b +run/t7359 +run/t7439 +run/t7455 +run/t7510 +run/t7582-private-within +run/t7582 +run/t7582b +run/t3897 +run/t7374 +run/t3452e +run/t3452g +run/t3452d +run/t3452b +run/t3452a +run/t1430 +run/t4729 +run/t8442 +run/t8601e +run/t9298 +run/t9298b +run/t9359 +run/t7741a +run/t7741b +run/bcodeInlinerMixed +run/t9268 +run/t9489 +run/t9915 +run/t10059 +run/t1459 +run/t1459generic +run/t3236 +run/t9013 +run/t10231 +run/t10067 +run/t10249 +run/sd143 +run/t4283b +run/t7936 +run/t7936b +run/t9937 +run/t10368 +run/t10334b +run/sd304 +run/t10450 +run/t10042 +run/t10699 + +# Using scala-script +run/t7791-script-linenums.scala + +# Suffers from bug in Node.js (https://github.com/joyent/node/issues/7528) +run/range-unit.scala + +# Using scalap +run/scalapInvokedynamic.scala + +# Using Manifests (which use Class.getInterfaces) +run/valueclasses-manifest-existential.scala +run/existentials3-old.scala +run/t2236-old.scala +run/interop_manifests_are_classtags.scala +run/valueclasses-manifest-generic.scala +run/valueclasses-manifest-basic.scala +run/t1195-old.scala +run/t3758-old.scala +run/t4110-old.scala +run/t6246.scala + +# Using ScalaRunTime.stringOf +run/value-class-extractor-seq.scala +run/t3493.scala + +# Custom invoke dynamic node +run/indy-via-macro +run/indy-via-macro-with-dynamic-args + +# Crashes our optimizer because of artificially insane amount of inlining +run/t10594.scala + +### Incorrect partests ### +# Badly uses constract of Console.print (no flush) +run/t429.scala +run/t6102.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/BuglistedTests.txt new file mode 100644 index 0000000000..273cb2c2d4 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/BuglistedTests.txt @@ -0,0 +1,7 @@ +# The tests in this file should pass but have never passed so far +# use scala.tools.partest.scalajs.testunknownonly to only run tests +# which are neither in BuglistedTests.txt, WhitelistedTests.txt or +# BlacklistedTests.txt + +# Broken by GCC, filed as #2815 +run/Predef.readLine.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/WhitelistedTests.txt new file mode 100644 index 0000000000..e763a0f44e --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/WhitelistedTests.txt @@ -0,0 +1,3433 @@ +pos/spec-super.scala +pos/t1035.scala +pos/t5897.scala +pos/irrefutable.scala +pos/spec-partialmap.scala +pos/tcpoly_seq.scala +pos/partialfun.scala +pos/t2795-new.scala +pos/clsrefine.scala +pos/t0774 +pos/t1070.scala +pos/t5957 +pos/looping-jsig.scala +pos/t3274.scala +pos/spec-fields-old.scala +pos/t262.scala +pos/t7486.scala +pos/t2261.scala +pos/t6600.scala +pos/t4786.scala +pos/t5406.scala +pos/tcpoly_late_method_params.scala +pos/t2726 +pos/pos-bug1210.scala +pos/t3312.scala +pos/manifest1-old.scala +pos/gadt-gilles.scala +pos/t4842.scala +pos/ted.scala +pos/NoCyclicReference.scala +pos/t3568.scala +pos/t0030.scala +pos/t2635.scala +pos/t7232b +pos/t0017.scala +pos/t812.scala +pos/t2179.scala +pos/t651.scala +pos/spurious-overload.scala +pos/t758.scala +pos/t4760.scala +pos/t1672.scala +pos/mixins.scala +pos/patterns.scala +pos/t1260.scala +pos/t6551.scala +pos/t2060.scala +pos/t6575a.scala +pos/t1318.scala +pos/t4266.scala +pos/t0695 +pos/protected-static +pos/t5738.scala +pos/t1226.scala +pos/t5013 +pos/t6215.scala +pos/t5692b +pos/traits.scala +pos/t2994a.scala +pos/t3371.scala +pos/t613.scala +pos/t6499.scala +pos/xlint1.scala +pos/t1150 +pos/test4a.scala +pos/t2664.scala +pos/t3528.scala +pos/t3174.scala +pos/t6994.scala +pos/t4812.scala +pos/t5777.scala +pos/t5223.scala +pos/t439.scala +pos/t3079.scala +pos/t5829.scala +pos/t0036.scala +pos/scoping2.scala +pos/t4717.scala +pos/t4257.scala +pos/t1210a.scala +pos/getClassType.scala +pos/t5330.scala +pos/t4524.scala +pos/t2945.scala +pos/t6562.scala +pos/t0273.scala +pos/override-object-yes.scala +pos/t7426.scala +pos/t6601 +pos/t3076 +pos/seq-ordering.scala +pos/spec-groups.scala +pos/t296.scala +pos/t5545 +pos/spec-multiplectors.scala +pos/t1789.scala +pos/t2569 +pos/ksbug1.scala +pos/t0599.scala +pos/local-objects.scala +pos/t0081.scala +pos/t5756.scala +pos/t7126.scala +pos/t7716.scala +pos/t2797.scala +pos/t5399.scala +pos/t1101 +pos/t767.scala +pos/contrib467.scala +pos/t7532b +pos/self-type-override.scala +pos/t4853.scala +pos/t839.scala +pos/t5644 +pos/t5853.scala +pos/t5178.scala +pos/unapplyNeedsMemberType.scala +pos/t5390.scala +pos/t6575b.scala +pos/t151.scala +pos/t2665.scala +pos/t5120.scala +pos/erasure-nsquared.scala +pos/arrays3.scala +pos/t3136.scala +pos/inline-access-levels +pos/t3972.scala +pos/t2591.scala +pos/t3486 +pos/variances-flip.scala +pos/annotated-original +pos/typesafecons.scala +pos/stable.scala +pos/t1996.scala +pos/t3037.scala +pos/t1711 +pos/t3374.scala +pos/t0029.scala +pos/t3278.scala +pos/matthias3.scala +pos/t5546.scala +pos/t4020.scala +pos/matthias4.scala +pos/value-class-override-spec.scala +pos/arrays2.scala +pos/t5119.scala +pos/t2613.scala +pos/t4070b.scala +pos/virtpatmat_exist_uncurry.scala +pos/modules1.scala +pos/spec-constr-new.scala +pos/t6335.scala +pos/t675.scala +pos/t0644.scala +pos/t5892.scala +pos/t360.scala +pos/override.scala +pos/t1798.scala +pos/strip-tvars-for-lubbasetypes.scala +pos/hk-infer.scala +pos/t2119.scala +pos/t0231.scala +pos/t1459 +pos/t1381-new.scala +pos/t2610.scala +pos/t2708.scala +pos/t5604b +pos/t3951 +pos/t361.scala +pos/t319.scala +pos/largecasetest.scala +pos/switchUnbox.scala +pos/typetags.scala +pos/java-access-pos +pos/t803.scala +pos/t3898.scala +pos/t5692a +pos/t2421.scala +pos/t1102 +pos/t0654.scala +pos/exhaust_alternatives.scala +pos/t807.scala +pos/t5702-pos-infix-star.scala +pos/t1186 +pos/t1439.scala +pos/t7427.scala +pos/virtpatmat_binding_opt.scala +pos/t247.scala +pos/abstract.scala +pos/gen-traversable-methods.scala +pos/t2795-old.scala +pos/t5639 +pos/t2667.scala +pos/t2405.scala +pos/t1438.scala +pos/t1659.scala +pos/unchecked-a.scala +pos/t3636.scala +pos/t6745.scala +pos/t2809.scala +pos/t7022.scala +pos/t6447.scala +pos/t5846.scala +pos/lubs.scala +pos/t1987a.scala +pos/spec-arrays.scala +pos/virtpatmat_anonfun_for.scala +pos/listpattern.scala +pos/t5742.scala +pos/test5refine.scala +pos/t5604 +pos/return_thistype.scala +pos/t348plus.scala +pos/t3420.scala +pos/t3440.scala +pos/maxim1.scala +pos/caseClassInMethod.scala +pos/t3833.scala +pos/t6675.scala +pos/t4402 +pos/t5953.scala +pos/t1152 +pos/t0591.scala +pos/t210.scala +pos/t7035.scala +pos/t5769.scala +pos/pmbug.scala +pos/t2331.scala +pos/t5240.scala +pos/t304.scala +pos/annotated-treecopy +pos/t2081.scala +pos/t0904.scala +pos/t7649.scala +pos/t3498-new.scala +pos/contrib701.scala +pos/t6624.scala +pos/t3924.scala +pos/t374.scala +pos/t1642 +pos/t1591_pos.scala +pos/depmet_implicit_oopsla_session_2.scala +pos/t5899.scala +pos/thistype.scala +pos/t4176b.scala +pos/elidable-tparams.scala +pos/lambdalift.scala +pos/nothing_manifest_disambig-old.scala +pos/t372.scala +pos/t5399a.scala +pos/t2782.scala +pos/patmat-extract-tparam.scala +pos/t4114.scala +pos/unapplyVal.scala +pos/t2486.scala +pos/t5877b.scala +pos/t0625.scala +pos/t6358_2.scala +pos/viewtest1.scala +pos/t1237.scala +pos/scala-singleton.scala +pos/t1254 +pos/t5504 +pos/bounds.scala +pos/t3631.scala +pos/t3177.scala +pos/unapplyContexts2.scala +pos/t0438.scala +pos/t1642b.scala +pos/inferbroadtype.scala +pos/t1858.scala +pos/t3731.scala +pos/t6963c.scala +pos/classtag-pos.scala +pos/t6221.scala +pos/t3343.scala +pos/spec-asseenfrom.scala +pos/t604.scala +pos/spec-example1.scala +pos/t0786.scala +pos/annot-inner.scala +pos/t5886.scala +pos/t1056.scala +pos/t294 +pos/spec-Function1.scala +pos/t1836 +pos/spec-private.scala +pos/depmet_implicit_tpbetareduce.scala +pos/exhaust_2.scala +pos/t7532 +pos/t5175.scala +pos/t802.scala +pos/t5809.scala +pos/tcpoly_typesub.scala +pos/t6029.scala +pos/contextbounds-implicits-new.scala +pos/t3480.scala +pos/patterns3.scala +pos/caseaccs.scala +pos/spec-sparsearray-old.scala +pos/patterns1213.scala +pos/spec-traits.scala +pos/t0020.scala +pos/cycle +pos/t5968.scala +pos/typealiases.scala +pos/init.scala +pos/t697.scala +pos/t2693.scala +pos/t2377 +pos/unapplyGeneric.scala +pos/t1385.scala +pos/t3363-old.scala +pos/t1236.scala +pos/t0068.scala +pos/t4052.scala +pos/lambdalift1.scala +pos/z1730.scala +pos/variances-local.scala +pos/virtpatmat_gadt_array.scala +pos/t2421_delitedsl.scala +pos/t5626.scala +pos/t690.scala +pos/t711.scala +pos/t1937 +pos/t3999 +pos/t2305.scala +pos/t2168.scala +pos/t2660.scala +pos/t1693.scala +pos/t2799.scala +pos/t6966.scala +pos/t1001.scala +pos/S5.scala +pos/t0301.scala +pos/t1048.scala +pos/t415.scala +pos/t6386.scala +pos/t2187.scala +pos/hashhash-overloads.scala +pos/t6921.scala +pos/t0227.scala +pos/t6556.scala +pos/t3946 +pos/t1053.scala +pos/t1000.scala +pos/t0586.scala +pos/t7011.scala +pos/t7329.scala +pos/t4975.scala +pos/t1131.scala +pos/t1027.scala +pos/t2913.scala +pos/t3494.scala +pos/t5606.scala +pos/t4716.scala +pos/tcpoly_gm.scala +pos/t4859.scala +pos/t514.scala +pos/lexical.scala +pos/t2624.scala +pos/t4036.scala +pos/t2741 +pos/t703.scala +pos/five-dot-f.scala +pos/t805.scala +pos/strings.scala +pos/t2433 +pos/t6925.scala +pos/t1085.scala +pos/t7461 +pos/t1942 +pos/spec-lists.scala +pos/t3349 +pos/tcpoly_infer_ticket474.scala +pos/t1614 +pos/virtpatmat_reach_const.scala +pos/t2194.scala +pos/t6976 +pos/t1560.scala +pos/t6891.scala +pos/t3883.scala +pos/infersingle.scala +pos/gui.scala +pos/t1164.scala +pos/t3175-pos.scala +pos/t4336.scala +pos/annotations2.scala +pos/proj-rec-test.scala +pos/t2973.scala +pos/t1123.scala +pos/t6205.scala +pos/t5727.scala +pos/t6537.scala +pos/t6712.scala +pos/t3866.scala +pos/t4831.scala +pos/selftails.scala +pos/t397.scala +pos/spec-vector.scala +pos/t7233b.scala +pos/t1391.scala +pos/spec.scala +pos/t3106.scala +pos/contextbounds-implicits-old.scala +pos/packageobjs.scala +pos/michel3.scala +pos/t628.scala +pos/collections.scala +pos/tcpoly_boundedmonad.scala +pos/t7668.scala +pos/t0032.scala +pos/t0069.scala +pos/t4345.scala +pos/t3521 +pos/t3071.scala +pos/tcpoly_infer_easy.scala +pos/t289.scala +pos/t4365 +pos/rangepos-anonapply.scala +pos/t5033.scala +pos/lambda.scala +pos/S8.scala +pos/t6014.scala +pos/t1785.scala +pos/t6034.scala +pos/t7433.scala +pos/imp2-pos.scala +pos/t0504.scala +pos/t1272.scala +pos/t0612 +pos/value-class-override-no-spec.scala +pos/overloaded-unapply.scala +pos/t5859.scala +pos/chang +pos/localmodules.scala +pos/t4237.scala +pos/rangepos-patmat.scala +pos/t1974.scala +pos/t0054.scala +pos/michel2.scala +pos/t0770.scala +pos/t1146.scala +pos/t2441pos.scala +pos/t5099.scala +pos/tcpoly_seq_typealias.scala +pos/t946.scala +pos/tcpoly_infer_ticket1864.scala +pos/t4737 +pos/t7377b.scala +pos/t616.scala +pos/t201.scala +pos/t6355pos.scala +pos/escapes2.scala +pos/t1675.scala +pos/t3890.scala +pos/t6040.scala +pos/spec-tailcall.scala +pos/existentials.scala +pos/t5317.scala +pos/t7782b.scala +pos/t4758.scala +pos/t7296.scala +pos/t6896.scala +pos/cls1.scala +pos/t402.scala +pos/gosh.scala +pos/t2619.scala +pos/javaConversions-2.10-regression.scala +pos/t759.scala +pos/t5259.scala +pos/t5130.scala +pos/t5156.scala +pos/t0905.scala +pos/package-implicit +pos/t2669.scala +pos/trait-parents.scala +pos/virtpatmat_exhaust.scala +pos/patterns1.scala +pos/t1231 +pos/t1751 +pos/t7233.scala +pos/t6022.scala +pos/tcpoly_checkkinds_mix.scala +pos/depmet_implicit_norm_ret.scala +pos/package-case.scala +pos/philippe4.scala +pos/michel6.scala +pos/t4188.scala +pos/t3936 +pos/t1280.scala +pos/t6722.scala +pos/t796.scala +pos/t5542.scala +pos/t3927.scala +pos/t2293.scala +pos/t3800.scala +pos/t7285a.scala +pos/t927.scala +pos/t4494.scala +pos/t3864 +pos/ilya2 +pos/t2940 +pos/S1.scala +pos/tcpoly_wildcards.scala +pos/tryexpr.scala +pos/t6089b.scala +pos/depmet_implicit_oopsla_zipwith.scala +pos/t245.scala +pos/t6146.scala +pos/t1782 +pos/t851.scala +pos/spec-thistype.scala +pos/tcpoly_poly.scala +pos/t6815_import.scala +pos/t4649.scala +pos/t0453.scala +pos/t5020.scala +pos/ilya +pos/t2435.scala +pos/t1279a.scala +pos/t1957.scala +pos/gadts2.scala +pos/t3567 +pos/Z.scala +pos/t1203b +pos/nested2.scala +pos/t1896 +pos/viewtest2.scala +pos/t5541.scala +pos/existentials-harmful.scala +pos/t4063.scala +pos/t6485a +pos/t1208.scala +pos/t5041.scala +pos/unapplyComplex.scala +pos/t3384.scala +pos/t4112.scala +pos/t788.scala +pos/hklub0.scala +pos/t757.scala +pos/t1197 +pos/t359.scala +pos/t5667.scala +pos/t1107a.scala +pos/virtpatmat_castbinder.scala +pos/t267.scala +pos/t3419 +pos/t3861.scala +pos/t6797.scala +pos/spec-localdefs.scala +pos/t3404 +pos/t4457_1.scala +pos/matthias5.scala +pos/spec-polymeth.scala +pos/kinds.scala +pos/t2310.scala +pos/t6552.scala +pos/valdefs.scala +pos/hkarray.scala +pos/homonym.scala +pos/t1235 +pos/t3429 +pos/t0053.scala +pos/depmet_implicit_chaining_zw.scala +pos/virtpatmat_partialfun_nsdnho.scala +pos/t6664.scala +pos/ticket2251.scala +pos/t3495.scala +pos/super +pos/t121.scala +pos/javaConversions-2.10-ambiguity.scala +pos/t1803.scala +pos/t5877.scala +pos/t0085.scala +pos/t3582.scala +pos/t2939.scala +pos/t1422_pos.scala +pos/manifest1-new.scala +pos/t7505.scala +pos/t5720-ownerous.scala +pos/misc-unapply_pos.scala +pos/tcpoly_variance_pos.scala +pos/t5127.scala +pos/t6123-explaintypes-implicits.scala +pos/t2764 +pos/presuperContext.scala +pos/spec-simple.scala +pos/t3120 +pos/tcpoly_infer_ticket716.scala +pos/tcpoly_bounds1.scala +pos/t7369.scala +pos/imports-pos.scala +pos/t5654.scala +pos/t0123.scala +pos/raw-map +pos/t5330b.scala +pos/t6485b +pos/t6072.scala +pos/t5692c.scala +pos/tcpoly_param_scoping.scala +pos/t6204-b.scala +pos/attachments-typed-another-ident +pos/t5359.scala +pos/ticket2197.scala +pos/t720.scala +pos/t2130-2.scala +pos/t2260.scala +pos/t0304.scala +pos/t464.scala +pos/spec-maps.scala +pos/annotDepMethType.scala +pos/t6117.scala +pos/t911.scala +pos/t757a.scala +pos/t2504.scala +pos/t1381-old.scala +pos/t1232 +pos/needstypeearly.scala +pos/moduletrans.scala +pos/t4957.scala +pos/kinzer.scala +pos/t318.scala +pos/widen-existential.scala +pos/t0095.scala +pos/t566.scala +pos/tcpoly_overloaded.scala +pos/t7516 +pos/t7232 +pos/t698.scala +pos/t0002.scala +pos/t0288 +pos/t2994b.scala +pos/cls.scala +pos/t3622 +pos/t3671.scala +pos/tcpoly_subst.scala +pos/t5703 +pos/depmet_implicit_oopsla_session_simpler.scala +pos/t5022.scala +pos/builders.scala +pos/spec-foo.scala +pos/t756.scala +pos/t1569.scala +pos/implicit-unwrap-tc.scala +pos/t3688.scala +pos/t5198.scala +pos/t432.scala +pos/t6022b.scala +pos/channels.scala +pos/t1075.scala +pos/null.scala +pos/t1840 +pos/t6479.scala +pos/t6311.scala +pos/t0039.scala +pos/t1119.scala +pos/t573.scala +pos/t1136.scala +pos/t3938 +pos/spec-sealed.scala +pos/tcpoly_return_overriding.scala +pos/t3582b.scala +pos/t229.scala +pos/t3498-old.scala +pos/t531.scala +pos/t4545.scala +pos/t6651.scala +pos/t2133.scala +pos/tinondefcons.scala +pos/t6358.scala +pos/t7690.scala +pos/t5779-numeq-warn.scala +pos/list-extractor.scala +pos/t892.scala +pos/t2127.scala +pos/t7180.scala +pos/nullary_poly.scala +pos/virtpatmat_exist3.scala +pos/t1176 +pos/spec-funs.scala +pos/specialize10.scala +pos/t6514.scala +pos/exhaustive_heuristics.scala +pos/t0066.scala +pos/t460.scala +pos/t2130-1.scala +pos/t124.scala +pos/annotations.scala +pos/pat_gilles.scala +pos/array-interfaces.scala +pos/t6210.scala +pos/t3792.scala +pos/implicits-old.scala +pos/t389.scala +pos/t115.scala +pos/virtpatmat_exhaust_unchecked.scala +pos/scoping3.scala +pos/t6033.scala +pos/depmet_implicit_oopsla_session.scala +pos/t602.scala +pos/test5.scala +pos/t611.scala +pos/t5932.scala +pos/t4910.scala +pos/unapplySeq.scala +pos/t344.scala +pos/t3363-new.scala +pos/t4018.scala +pos/t4553.scala +pos/t5082.scala +pos/t3869.scala +pos/t3836.scala +pos/tcpoly_typeapp.scala +pos/t1409 +pos/nonlocal-unchecked.scala +pos/t0082.scala +pos/z1720.scala +pos/t7232c +pos/t2018.scala +pos/t3943 +pos/t2187-2.scala +pos/unicode-decode.scala +pos/t4757 +pos/t0710.scala +pos/t0305.scala +pos/t160.scala +pos/t7591 +pos/simplelists.scala +pos/List1.scala +pos/t516.scala +pos/t6648.scala +pos/t5165 +pos/t0055.scala +pos/t4744 +pos/t7377 +pos/t5726.scala +pos/t0091.scala +pos/t6595.scala +pos/compile.scala +pos/depmet_1_pos.scala +pos/t7364 +pos/philippe3.scala +pos/spec-doubledef-old.scala +pos/t4651.scala +pos/tcpoly_infer_implicit_tuple_wrapper.scala +pos/t6274.scala +pos/tcpoly_infer_explicit_tuple_wrapper.scala +pos/ticket2201.scala +pos/spec-fields-new.scala +pos/optmatch.scala +pos/t7517.scala +pos/t3560.scala +pos/t0165.scala +pos/t0872.scala +pos/t522.scala +pos/t2234.scala +pos/t5031_2.scala +pos/tcpoly_method.scala +pos/t6482.scala +pos/pos-bug1241.scala +pos/implicits-new.scala +pos/t2484.scala +pos/t2425.scala +pos/t1049.scala +pos/michel4.scala +pos/t5958.scala +pos/virtpatmat_instof_valuetype.scala +pos/spec-t6286.scala +pos/t873.scala +pos/t3137.scala +pos/Transactions.scala +pos/t0064.scala +pos/t7486-named.scala +pos/t5444.scala +pos/simple-exceptions.scala +pos/t1006.scala +pos/t7200b.scala +pos/t3777.scala +pos/t4840.scala +pos/t211.scala +pos/nullary.scala +pos/michel1.scala +pos/t5031_3 +pos/typealias_dubious.scala +pos/spec-doubledef-new.scala +pos/philippe1.scala +pos/thistypes.scala +pos/t3570.scala +pos/t6516.scala +pos/context.scala +pos/t3808.scala +pos/philippe2.scala +pos/constfold.scala +pos/t1292.scala +pos/t1147.scala +pos/t404.scala +pos/t4430.scala +pos/A.scala +pos/spec-partially.scala +pos/t5796.scala +pos/t2409 +pos/t284-pos.scala +pos/t5313.scala +pos/t2464 +pos/t1591b.scala +pos/hk-match +pos/t595.scala +pos/t6846.scala +pos/t6162-inheritance.scala +pos/relax_implicit_divergence.scala +pos/patterns2.scala +pos/t4692.scala +pos/t3837.scala +pos/t661.scala +pos/t2810.scala +pos/depexists.scala +pos/virtpatmat_exist4.scala +pos/t5245.scala +pos/t7190.scala +pos/isApplicableSafe.scala +pos/t6204-a.scala +pos/t0076.scala +pos/t1756.scala +pos/t1745 +pos/t6091.scala +pos/t0154.scala +pos/t530.scala +pos/t2094.scala +pos/t1034.scala +pos/t6084.scala +pos/t2454.scala +pos/t2956 +pos/tcpoly_ticket2096.scala +pos/attachments-typed-ident +pos/polymorphic-case-class.scala +pos/t252.scala +pos/spec-constr-old.scala +pos/t2421c.scala +pos/t122.scala +pos/t6574.scala +pos/t3859.scala +pos/spec-params-old.scala +pos/t1196 +pos/t4593.scala +pos/t596.scala +pos/t615.scala +pos/t7689.scala +pos/t3960.scala +pos/t3986.scala +pos/exbound.scala +pos/t2545.scala +pos/t1722 +pos/t159.scala +pos/t3272.scala +pos/t6301.scala +pos/t2794.scala +pos/t3048.scala +pos/t4970.scala +pos/t607.scala +pos/FPTest.scala +pos/test1.scala +pos/t4176.scala +pos/t112606A.scala +pos/t2183.scala +pos/t430-feb09.scala +pos/t6275.scala +pos/t1832.scala +pos/t8965.scala +pos/t7596b +pos/t8900.scala +pos/t9008.scala +pos/t7704.scala +pos/t7459c.scala +pos/sammy_override.scala +pos/t8828.scala +pos/t8868c +pos/t7459d.scala +pos/t8267.scala +pos/t8844.scala +pos/t8868a +pos/t8894.scala +pos/t7459a.scala +pos/t7596c +pos/t8498.scala +pos/t8868b +pos/t5413.scala +pos/t8781 +pos/t8934a +pos/t8310.scala +pos/t3439.scala +pos/t6582_exhaust_big.scala +pos/t8954 +pos/t5217.scala +pos/t7459b.scala +pos/t9018.scala +pos/sammy_exist.scala +pos/t8893.scala +pos/t7596 +pos/t8793.scala +pos/sammy_overload.scala +pos/t6051.scala +pos/t7683-stop-after-parser +pos/t7750.scala +pos/t5454.scala +pos/t8962.scala +pos/t8947 +pos/t8719 +pos/t8410.scala +pos/patmat-suppress.scala +pos/t8999.scala +pos/t8743.scala +pos/t9157.scala +pos/t8801.scala +pos/t9086.scala +pos/t9050.scala +pos/t9135.scala +pos/t9116.scala +pos/t5154.scala +pos/t3368.scala +pos/t9321.scala +pos/t9285.scala +pos/t8861.scala +pos/t9020.scala +pos/jesper.scala +pos/t9356 +pos/virtpatmat_exhaust_big.scala +pos/t9239 +pos/t9111-inliner-workaround + +neg/volatile_no_override.scala +neg/t800.scala +neg/t5426.scala +neg/t2462a.scala +neg/t2641.scala +neg/classtags_dont_use_typetags.scala +neg/t5031 +neg/t2275b.scala +neg/macro-qmarkqmarkqmark.scala +neg/t4879.scala +neg/t5956.scala +neg/t4196.scala +neg/reify_ann2b.scala +neg/t6666b.scala +neg/warn-unused-privates.scala +neg/t6928.scala +neg/t6337.scala +neg/sealed-java-enums.scala +neg/t563.scala +neg/t900.scala +neg/deadline-inf-illegal.scala +neg/t766.scala +neg/t5429.scala +neg/overloaded-implicit.scala +neg/t875.scala +neg/abstract-class-error +neg/unchecked2.scala +neg/predef-masking.scala +neg/viewtest.scala +neg/macro-noexpand +neg/varargs.scala +neg/t963b.scala +neg/t909.scala +neg/sensitive2.scala +neg/t5390b.scala +neg/abstraction-from-volatile-type-error.scala +neg/macro-exception +neg/t4431.scala +neg/t5689.scala +neg/valueclasses.scala +neg/overload.scala +neg/t0204.scala +neg/t908.scala +neg/t750 +neg/patmatexhaust.scala +neg/macro-invalidusage-badtargs +neg/t1168.scala +neg/t5761.scala +neg/t0503.scala +neg/t7235.scala +neg/t1215.scala +neg/primitive-sigs-1 +neg/t5578.scala +neg/names-defaults-neg-warn.scala +neg/t6436b.scala +neg/t3098 +neg/t910.scala +neg/parstar.scala +neg/t4568.scala +neg/newpat_unreachable.scala +neg/t1181.scala +neg/t5903c +neg/t7294.scala +neg/t4091.scala +neg/t5452-old.scala +neg/t5696.scala +neg/t0209.scala +neg/t2910.scala +neg/t7388.scala +neg/noMember2.scala +neg/no-predef.scala +neg/t6952.scala +neg/t1909b.scala +neg/abstract-report2.scala +neg/t5318.scala +neg/t6074.scala +neg/t7171.scala +neg/abstract-vars.scala +neg/unchecked-impossible.scala +neg/variances-refinement.scala +neg/t3453.scala +neg/t5189.scala +neg/t4302.scala +neg/xmltruncated7.scala +neg/t8217-local-alias-requires-rhs.scala +neg/t7602.scala +neg/t8869.scala +neg/t9008.scala +neg/sammy_error_exist_no_crash.scala +neg/t2866.scala +neg/t8597b.scala +neg/t5691.scala +neg/t8534b.scala +neg/t5091.scala +neg/literals.scala +neg/t8534.scala +neg/t8890.scala +neg/t9008b.scala +neg/t8731.scala +neg/t8291.scala +neg/t8597.scala +neg/t5639b +neg/t6582_exhaust_big.scala +neg/t8841.scala +neg/t9041.scala +neg/t9093.scala +neg/t7623.scala +neg/t9231.scala +neg/t9286b.scala +neg/t9273.scala +neg/t9127.scala +neg/t9286c.scala +neg/t9286a.scala +neg/virtpatmat_exhaust_big.scala + +run/t7249.scala +run/t3563.scala +run/t6111.scala +run/classtags_multi.scala +run/t5201.scala +run/checked.scala +run/valueclasses-classtag-basic.scala +run/t7171.scala +run/t5053.scala +run/t4535.scala +run/t5923d +run/t7291.scala +run/partialfun.scala +run/macro-term-declared-in-package-object +run/mapValues.scala +run/gadts.scala +run/t2386-new.scala +run/virtpatmat_stringinterp.scala +run/t657.scala +run/t0017.scala +run/t5713 +run/t576.scala +run/t3580.scala +run/virtpatmat_partial.scala +run/t6646.scala +run/mixins.scala +run/t1672.scala +run/macro-expand-implicit-macro-has-implicit +run/tuple-match.scala +run/t7039.scala +run/virtpatmat_opt_sharing.scala +run/virtpatmat_casting.scala +run/t2176.scala +run/macro-impl-relaxed +run/intmap.scala +run/t751.scala +run/t1591.scala +run/macro-typecheck-implicitsdisabled +run/t6911.scala +run/t5604.scala +run/macro-term-declared-in-default-param +run/collection-stacks.scala +run/multi-array.scala +run/t4560b.scala +run/buffer-slice.scala +run/t5629.scala +run/t6690.scala +run/matchonstream.scala +run/t3603.scala +run/lazy-exprs.scala +run/macro-quasiquotes +run/Course-2002-13.scala +run/t6337a.scala +run/exoticnames.scala +run/t0936.scala +run/runtime-richChar.scala +run/t6272.scala +run/t7215.scala +run/t1939.scala +run/ReverseSeqView.scala +run/lazy-leaks.scala +run/t0048.scala +run/t3994.scala +run/t2241.scala +run/t627.scala +run/t5966.scala +run/getClassTest-valueClass.scala +run/t3619.scala +run/t1300.scala +run/t2177.scala +run/t3760.scala +run/t1829.scala +run/macro-expand-implicit-macro-is-view +run/t889.scala +run/QueueTest.scala +run/t4537 +run/t3699.scala +run/t1192.scala +run/macro-expand-tparams-bounds +run/macro-expand-nullary-generic +run/t1434.scala +run/t6443-varargs.scala +run/macro-term-declared-in-trait +run/t4080.scala +run/matcharraytail.scala +run/infiniteloop.scala +run/t5733.scala +run/virtpatmat_nested_lists.scala +run/t5158.scala +run/t6695.scala +run/t6070.scala +run/t4558.scala +run/exc2.scala +run/patmat-behavior-2.scala +run/overloads.scala +run/t6957.scala +run/transform.scala +run/t5500.scala +run/t6663.scala +run/castsingleton.scala +run/t4147.scala +run/virtpatmat_staging.scala +run/t4565_1.scala +run/t5588.scala +run/run-bug4840.scala +run/t3496.scala +run/t5867.scala +run/search.scala +run/t3112.scala +run/hashsetremove.scala +run/t6443.scala +run/macro-expand-tparams-prefix +run/contrib674.scala +run/t3508.scala +run/t4300.scala +run/virtpatmat_typed.scala +run/macro-term-declared-in-class-object +run/map_test.scala +run/t5040.scala +run/t4827b.scala +run/lift-and-unlift.scala +run/t6574b.scala +run/t7240 +run/t3984.scala +run/virtpatmat_tailcalls_verifyerror.scala +run/macro-term-declared-in-class-class +run/emptypf.scala +run/t6104.scala +run/t2818.scala +run/t3761-overload-byname.scala +run/t2526.scala +run/phantomValueClass.scala +run/t3126.scala +run/arybufgrow.scala +run/t3980.scala +run/t7375b +run/t6077_patmat_cse_irrefutable.scala +run/classmanifests_new_core.scala +run/t3395.scala +run/name-based-patmat.scala +run/inliner-infer.scala +run/t5171.scala +run/t3726.scala +run/null-hash.scala +run/t4027.scala +run/t2544.scala +run/patmatnew.scala +run/t5923b +run/t7242.scala +run/classtags_core.scala +run/streamWithFilter.scala +run/t3038b.scala +run/macro-expand-varargs-explicit-over-nonvarargs-good +run/macro-divergence-spurious +run/macro-duplicate +run/t2958.scala +run/patch-boundary.scala +run/t2333.scala +run/lazy-override-run.scala +run/macro-quasiinvalidbody-c +run/t5037.scala +run/takeAndDrop.scala +run/t6126.scala +run/t0883.scala +run/t7617a +run/t4171.scala +run/empty-array.scala +run/t7198.scala +run/t493.scala +run/genericValueClass.scala +run/t0677-old.scala +run/t1373.scala +run/t4461.scala +run/t6011b.scala +run/t7584.scala +run/t3935.scala +run/t6928-run.scala +run/t744.scala +run/t3241.scala +run/blame_eye_triple_eee-double.scala +run/t3829.scala +run/t5577.scala +run/t5914.scala +run/t601.scala +run/t5610.scala +run/macro-basic-mamd-mi +run/t6150.scala +run/stringbuilder.scala +run/t7290.scala +run/t6888.scala +run/t6327.scala +run/virtpatmat_unapplyseq.scala +run/t4656.scala +run/macro-term-declared-in-method +run/macro-expand-implicit-macro-is-implicit +run/blame_eye_triple_eee-float.scala +run/t4482.scala +run/t5488.scala +run/matchemptyarray.scala +run/t3714.scala +run/richWrapperEquals.scala +run/t5328.scala +run/stream_flatmap_odds.scala +run/implicitclasses.scala +run/t6394b +run/complicatedmatch.scala +run/valueclasses-classmanifest-basic.scala +run/unreachable.scala +run/caseclasses.scala +run/withIndex.scala +run/exc1.scala +run/amp.scala +run/t1423.scala +run/t594.scala +run/t6353.scala +run/byname.scala +run/vector1.scala +run/t5879.scala +run/t1048.scala +run/t5080.scala +run/t4190.scala +run/caseClassEquality.scala +run/macro-enclosures +run/collections-toSelf.scala +run/implicits.scala +run/finalvar.scala +run/lazy-locals.scala +run/t7231.scala +run/t0508.scala +run/t6628.scala +run/t6406-regextract.scala +run/t0911.scala +run/t4013c.scala +run/t3502.scala +run/t5648.scala +run/retclosure.scala +run/t2857.scala +run/t4859.scala +run/t5162.scala +run/t3038.scala +run/classof.scala +run/t4062.scala +run/unapplyArray.scala +run/t4297.scala +run/t5923a +run/t1537.scala +run/boolexprs.scala +run/valueclasses-classtag-generic.scala +run/macro-term-declared-in-anonymous +run/tcpoly_monads.scala +run/t5407.scala +run/scan.scala +run/forvaleq.scala +run/null-and-intersect.scala +run/t7047 +run/t0607.scala +run/sequenceComparisons.scala +run/t4396.scala +run/macro-undetparams-consfromsls +run/t2029.scala +run/t1220.scala +run/option-fold.scala +run/t5284c.scala +run/macro-auto-duplicate +run/t3529.scala +run/t4697.scala +run/t2251.scala +run/t5300.scala +run/virtpatmat_valdef.scala +run/t2147.scala +run/virtpatmat_extends_product.scala +run/list_map.scala +run/t1333.scala +run/matchbytes.scala +run/valueclasses-classmanifest-existential.scala +run/records.scala +run/t3088.scala +run/macro-def-path-dependent +run/t6443-by-name.scala +run/t1044.scala +run/delay-good.scala +run/case-class-23.scala +run/weakconform.scala +run/patmat-bind-typed.scala +run/t4835.scala +run/t3097.scala +run/t405.scala +run/existentials.scala +run/t2876.scala +run/t4809.scala +run/t1427.scala +run/t6135.scala +run/t3575.scala +run/t5688.scala +run/t6900.scala +run/macro-expand-unapply-a +run/t6677b.scala +run/t7375a.scala +run/t7300.scala +run/typed-annotated +run/elidable-noflags.scala +run/t0042.scala +run/t3050.scala +run/t4536.scala +run/NestedClasses.scala +run/t3877.scala +run/seqlike-kmp.scala +run/t5907.scala +run/t266.scala +run/missingparams.scala +run/t2255.scala +run/t3488.scala +run/t3950.scala +run/typealias_overriding.scala +run/constant-optimization.scala +run/t7507.scala +run/t6090.scala +run/t4582.scala +run/macro-term-declared-in-class +run/macro-typecheck-macrosdisabled2 +run/t3425.scala +run/t4935.scala +run/t3326.scala +run/boolord.scala +run/t1141.scala +run/virtpatmat_unapply.scala +run/t5971.scala +run/t3651.scala +run/macro-sip19-revised +run/pure-args-byname-noinline.scala +run/preinits.scala +run/t5532.scala +run/concat-two-strings.scala +run/t3269.scala +run/macro-impl-default-params +run/t2162.scala +run/matchonseq.scala +run/t5428.scala +run/macro-expand-overload +run/t4660.scala +run/enrich-gentraversable.scala +run/macro-expand-override +run/t4054.scala +run/t4753.scala +run/macro-typecheck-macrosdisabled +run/t2308a.scala +run/duplicate-meth.scala +run/interop_classtags_are_classmanifests.scala +run/t3232.scala +run/t2075.scala +run/virtpatmat_partial_backquoted.scala +run/try-2.scala +run/macro-openmacros +run/macro-undetparams-macroitself +run/t6318_derived.scala +run/deprecate-early-type-defs.scala +run/dead-code-elimination.scala +run/t4827.scala +run/Course-2002-07.scala +run/slice-strings.scala +run/t6292.scala +run/t6206.scala +run/t1042.scala +run/t1718.scala +run/t2074_2.scala +run/arraycopy.scala +run/indexedSeq.scala +run/macro-term-declared-in-implicit-class +run/t3511.scala +run/t6290.scala +run/distinct.scala +run/virtpatmat_alts.scala +run/valueclasses-pavlov.scala +run/exceptions.scala +run/t1368.scala +run/t5856.scala +run/t6968.scala +run/names-defaults.scala +run/macro-expand-tparams-implicit +run/t5881.scala +run/t3540.scala +run/virtpatmat_try.scala +run/t7181.scala +run/value-class-extractor.scala +run/value-class-extractor-2.scala +run/t3150.scala +run/exc.scala +run/delay-bad.scala +run/infix.scala +run/t1309.scala +run/t6370.scala +run/t6725-2.scala +run/macro-impl-tparam-typetag-is-optional +run/macro-term-declared-in-block +run/matchnull.scala +run/t2127.scala +run/t7325.scala +run/groupby.scala +run/t3932.scala +run/t4871.scala +run/longmap.scala +run/t1524.scala +run/t6187b.scala +run/kmpSliceSearch.scala +run/t7088.scala +run/t5804.scala +run/stringbuilder-drop.scala +run/t5753_1 +run/t9223.scala +run/function-null-unbox.scala +run/t9223b.scala +run/disable-assertions.scala +run/valueClassSelfType.scala +run/indylambda-boxing +run/t9219.scala + +pos/cyclics-pos.scala +pos/cfcrash.scala +pos/tcpoly_higherorder_bound_method.scala +pos/t5084.scala +pos/macro-qmarkqmarkqmark.scala +pos/t7785.scala +pos/nested.scala +pos/t3152.scala +pos/t5031 +pos/t6925b.scala +pos/t1107b +pos/t5012.scala +pos/virtpatmat_obj_in_case.scala +pos/t4938.scala +pos/t3856.scala +pos/spec-cyclic.scala +pos/aliases.scala +pos/typerep_pos.scala +pos/t119.scala +pos/t1050.scala +pos/t3670.scala +pos/t6145.scala +pos/t7315.scala +pos/t5930.scala +pos/t789.scala +pos/t5071.scala +pos/t4731.scala +pos/t4547.scala +pos/t2038.scala +pos/testCoercionThis.scala +pos/t2444.scala +pos/t5744 +pos/t780.scala +pos/t1722-A.scala +pos/virtpatmat_exist1.scala +pos/t6225.scala +pos/t762.scala +pos/t0204.scala +pos/rebind.scala +pos/spec-short.scala +pos/comp-rec-test.scala +pos/lub-dealias-widen.scala +pos/t1168.scala +pos/modules.scala +pos/t4220.scala +pos/t4070.scala +pos/t175.scala +pos/t2500.scala +pos/t5029.scala +pos/itay.scala +pos/t4202.scala +pos/t1987b +pos/t3534.scala +pos/infer2-pos.scala +pos/spec-sparsearray-new.scala +pos/t7091.scala +pos/ticket0137.scala +pos/collectGenericCC.scala +pos/t640.scala +pos/t4305.scala +pos/extractor-types.scala +pos/t3880.scala +pos/spec-annotations.scala +pos/t3577.scala +pos/compile1.scala +pos/spec-t3497.scala +pos/hkrange.scala +pos/t287.scala +pos/t6008.scala +pos/t4432.scala +pos/CustomGlobal.scala +pos/patmat.scala +pos/t2413 +pos/t2910.scala +pos/t592.scala +pos/t6245 +pos/infer.scala +pos/t7228.scala +pos/compound.scala +pos/attributes.scala +pos/t6771.scala +pos/t1090.scala +pos/t684.scala +pos/t577.scala +pos/t4273.scala +pos/t6278-synth-def.scala +pos/t6184.scala +neg/t0214.scala +neg/t4842.scala +neg/t6214.scala +neg/reify_nested_inner_refers_to_local.scala +neg/t576.scala +neg/t5969.scala +neg/tcpoly_variance.scala +neg/t7509.scala +neg/mixins.scala +neg/parent-inherited-twice-error.scala +neg/macro-abort +neg/constructor-init-order.scala +neg/t6042.scala +neg/t0590.scala +neg/t4221.scala +neg/t6263.scala +neg/t783.scala +neg/t5554.scala +neg/macro-invalidsig-params-badtype +neg/multi-array.scala +neg/raw-types-stubs +neg/spec-overrides.scala +neg/t836.scala +neg/t7289_status_quo.scala +neg/t5675.scala +neg/macro-quasiquotes +neg/t6667.scala +neg/t6597.scala +neg/t6264.scala +neg/t0345.scala +neg/t7294b.scala +neg/t5340.scala +neg/t2144.scala +neg/t1010.scala +neg/t1838.scala +neg/t5189b.scala +neg/reify_metalevel_breach_-1_refers_to_1.scala +neg/t6601 +neg/wellkinded_wrongarity.scala +neg/t3909.scala +neg/t876.scala +neg/t5390.scala +neg/unit2anyref.scala +neg/t0351.scala +neg/t5120.scala +neg/t1038.scala +neg/t5878.scala +neg/qualifying-class-error-2.scala +neg/t3816.scala +neg/tailrec.scala +neg/volatile.scala +neg/t944.scala +neg/t1705.scala +neg/t3977.scala +neg/t5553_2.scala +neg/t5318c.scala +neg/overload-msg.scala +neg/t5440.scala +neg/t6335.scala +neg/compile-time-only-b.scala +neg/t501.scala +neg/override.scala +neg/t663.scala +neg/t5892.scala +neg/t1980.scala +neg/macro-false-deprecation-warning +neg/t585.scala +neg/t3776.scala +neg/interop_classtags_arenot_manifests.scala +neg/t4044.scala +neg/macro-invalidusage-nontypeable +neg/t500.scala +neg/t4877.scala +neg/t5357.scala +neg/interop_abstypetags_arenot_manifests.scala +neg/t4460a.scala +neg/t5318b.scala +neg/t4440.scala +neg/t6663.scala +neg/t6357.scala +neg/gadts1.scala +neg/cyclics.scala +neg/t5060.scala +neg/scopes.scala +run/t4013.scala +run/macro-expand-tparams-explicit +run/tuples.scala +run/t5753_2 +run/t0528.scala +run/t5105.scala +run/t7341.scala +run/t3670.scala +run/t2594_tcpoly.scala +run/t3895.scala +run/t0668.scala +run/slices.scala +run/t6666a.scala +run/valueclasses-classmanifest-generic.scala +run/t2316_run.scala +run/t3004.scala +run/viewtest.scala +run/t6481.scala +run/t0005.scala +run/t4766.scala +run/t5500b.scala +run/t7407b.scala +run/backreferences.scala +run/arrayview.scala +run/t629.scala +run/t5903c +run/unittest_collection.scala +run/spec-nlreturn.scala +run/macro-term-declared-in-object-object +run/triple-quoted-expr.scala +run/t5937.scala +run/t6011c.scala +run/macro-expand-implicit-argument +run/try.scala +run/t1987b +run/t6089.scala +run/macro-range +run/t2524.scala +run/t4770.scala +run/virtpatmat_unapplyprod.scala +run/t1535.scala +run/ctor-order.scala +pos/t5210.scala +pos/t5384.scala +pos/rangepos.scala +pos/t443.scala +pos/t1480.scala +pos/t116.scala +pos/seqtest2.scala +pos/scoping1.scala +pos/t4269.scala +pos/lookupswitch.scala +pos/t3642 +pos/t5706.scala +pos/t7264 +pos/t0031.scala +pos/macro-deprecate-dont-touch-backquotedidents.scala +pos/t6815.scala +pos/test4refine.scala +pos/michel5.scala +pos/t0851.scala +pos/t1185.scala +pos/sudoku.scala +pos/t7520.scala +pos/t6208.scala +pos/t3411.scala +pos/t295.scala +pos/S3.scala +pos/t0674.scala +pos/t6664b.scala +pos/variances_pos.scala +pos/liftcode_polymorphic.scala +pos/t3174b.scala +pos/t7232d +pos/t578.scala +pos/implicit-infix-ops.scala +pos/t4363.scala +pos/t532.scala +pos/exponential-spec.scala +pos/t599.scala +pos/t5862.scala +pos/t4603 +pos/t3676.scala +pos/t1357.scala +pos/native-warning.scala +pos/t1230 +pos/t6028 +pos/t4275.scala +pos/overloaded_extractor_and_regular_def.scala +pos/t4205 +pos/matthias1.scala +pos/testcast.scala +pos/generic-sigs.scala +pos/t0093.scala +pos/specializes-sym-crash.scala +pos/t0061.scala +pos/t2429.scala +pos/t694.scala +pos/javaReadsSigs +pos/t2023.scala +pos/t704.scala +pos/t2208_pos.scala +pos/t5137.scala +pos/t2683.scala +pos/t0049.scala +pos/t1029 +pos/t4243.scala +pos/typerep-stephane.scala +pos/t177.scala +pos/t5967.scala +pos/t430.scala +pos/virtpatmat_infer_single_1.scala +pos/pat_iuli.scala +pos/t1071.scala +pos/t7226.scala +pos/t1843.scala +pos/t419.scala +pos/t7364b +pos/t1159.scala +pos/t5305.scala +pos/t7694.scala +pos/t6047.scala +pos/t3578.scala +pos/t2082.scala +pos/setter-not-implicit.scala +pos/t1133.scala +pos/t3862.scala +pos/t942 +pos/nothing_manifest_disambig-new.scala +pos/iterator-traversable-mix.scala +pos/eta.scala +pos/test4.scala +pos/t2691.scala +pos/t4502.scala +pos/t7183.scala +pos/protected-t1010.scala +pos/X.scala +pos/virtpatmat_exist2.scala +pos/t4911.scala +pos/t3477.scala +pos/t4173.scala +pos/t7782.scala +pos/t2399.scala +pos/virtpatmat_alts_subst.scala +pos/propagate.scala +pos/t2421b_pos.scala +pos/t183.scala +pos/t7033.scala +pos/t3612.scala +pos/t5330c.scala +pos/t3020.scala +pos/t4869.scala +pos/t3373.scala +pos/spec-params-new.scala +pos/t3672.scala +pos/t4501.scala +pos/t1565.scala +pos/t3774.scala +pos/t6942 +pos/t845.scala +pos/t3240.scala + +neg/t3275.scala +neg/t421.scala +neg/t5702-neg-bad-brace.scala +neg/t3663 +neg/badtok-1.scala +neg/t677.scala +neg/t7756b.scala +neg/t6534.scala +neg/t6276.scala +neg/t5762.scala +neg/abstract.scala +neg/t2405.scala +neg/t0418.scala +neg/t5390c.scala +neg/lazyvals.scala +neg/lubs.scala +neg/abstract-report.scala +neg/t4163.scala +neg/t5702-neg-bad-and-wild.scala +neg/macro-invalidret +neg/t6728.scala +neg/t5152.scala +neg/t1432.scala +neg/abstract-inaccessible.scala +neg/import-precedence.scala +neg/t2462b.scala +neg/macro-invalidusage-presuper +neg/specification-scopes +neg/t6048.scala +neg/t4079 +neg/macro-basic-mamdmi +neg/t7020.scala +neg/t3015.scala +neg/t0207.scala +neg/t2296b +neg/t0673 +neg/t3761-overload-byname.scala +neg/t6675.scala +neg/t5529.scala +neg/sensitive.scala +neg/t742.scala +neg/t5067.scala +neg/t6162-overriding.scala +neg/variances.scala +neg/t5728.scala +neg/t6323a.scala +neg/compile-time-only-a.scala +neg/t6795.scala +neg/t2494.scala +neg/t3649.scala +neg/macro-invalidsig +neg/t2796.scala +neg/t112706A.scala +neg/t0764.scala +neg/t3757 +neg/t1431.scala +neg/exhausting.scala +neg/t1523.scala +neg/t779.scala +neg/xmltruncated1.scala +neg/t2208.scala +neg/t2078.scala +neg/t521.scala +neg/null-unsoundness.scala +neg/stmt-expr-discard.scala +neg/t0513.scala +neg/unchecked-abstract.scala +neg/t4460c.scala +neg/divergent-implicit.scala +neg/t5078.scala +neg/t1701.scala +neg/t0816.scala +neg/t1672b.scala +neg/macro-invalidusage-badbounds +neg/tailrec-2.scala +neg/t4064.scala +neg/t5510.scala +neg/t3873.scala +neg/tailrec-3.scala +neg/t0226.scala +neg/t2031.scala +neg/t633.scala +neg/constrs.scala +neg/anyval-anyref-parent.scala +neg/t7290.scala +neg/t1041.scala +neg/patternalts.scala +neg/error_tooManyArgsPattern.scala +neg/checksensibleUnit.scala +neg/t6539 +neg/t4417.scala +neg/wellkinded_app.scala +neg/for-comprehension-old.scala +neg/t2779.scala +neg/object-not-a-value.scala +neg/t2968b.scala +neg/t6483.scala +neg/t6902.scala +neg/t6963a.scala +neg/t3399.scala +neg/t0015.scala +neg/t3995.scala +neg/t276.scala +neg/t6758.scala +neg/t2441.scala +neg/cycle-bounds.scala +neg/t1241.scala +neg/t4137.scala +neg/unicode-unterminated-quote.scala +neg/t4762.scala +neg/typeerror.scala +neg/implicits.scala +neg/t961.scala +neg/ambiguous-float-dots2.scala +neg/t2416.scala +neg/t5799.scala +neg/t7285.scala +neg/implicit-shadow.scala +neg/t2388.scala +neg/java-access-neg +neg/found-req-variance.scala +neg/hk-bad-bounds.scala +neg/t3224.scala +neg/t1033.scala +neg/t7385.scala +neg/t5882.scala +neg/t4541.scala +neg/t2973.scala +neg/t6406-regextract.scala +neg/t6666.scala +neg/t4831.scala +neg/t425.scala +neg/t1845.scala +neg/t3683b.scala +neg/t2801.scala +neg/t6083.scala +neg/t0528neg.scala +neg/stringinterpolation_macro-neg.scala +neg/t668.scala +neg/t5666.scala +neg/t4271.scala +neg/interop_typetags_arenot_classmanifests.scala +neg/t1355.scala +neg/t715.scala +neg/t7238.scala +neg/t7473.scala +neg/t7292-removal.scala +neg/tcpoly_infer_ticket1162.scala +neg/t4098.scala +neg/t6013 +neg/t6227.scala +neg/t464-neg.scala +neg/badtok-3.scala +neg/t6082.scala +neg/anytrait.scala +neg/valueclasses-doubledefs.scala +neg/t7519.scala +neg/overloaded-unapply.scala +neg/t1163.scala +neg/wellkinded_bounds.scala +neg/t7292-deprecation.scala +neg/t5044.scala +neg/t0842.scala +neg/t6436.scala +neg/interop_typetags_arenot_classtags.scala +neg/t3653.scala +neg/higherkind_novalue.scala +neg/t935.scala +neg/t6040.scala +neg/annot-nonconst.scala +neg/macro-deprecate-idents.scala +neg/illegal-stmt-start.scala +neg/t565.scala +neg/case-collision.scala +neg/t3209.scala +neg/t5821.scala +neg/abstract-class-2.scala +neg/t846.scala +neg/quasiquotes-syntax-error-position.scala +neg/t3987.scala +neg/t877.scala +neg/t0117.scala +neg/t692.scala +neg/t5702-neg-ugly-xbrace.scala +neg/t7752.scala +neg/t6526.scala +neg/t2213.scala +neg/t7756a.scala +neg/macro-override-macro-overrides-abstract-method-a +neg/tcpoly_ticket2101.scala +neg/delayed-init-ref.scala +neg/caseinherit.scala +neg/t3189.scala +neg/unchecked-suppress.scala +neg/t2180.scala +neg/t1371.scala +neg/macro-cyclic +neg/t6123-explaintypes-macros +neg/t4134.scala +neg/t691.scala +neg/t2421b.scala +neg/t4691_exhaust_extractor.scala +neg/t4419.scala +neg/t5801.scala +neg/t650.scala +neg/t5735.scala +neg/t696.scala +neg/t882.scala +neg/t2968.scala +neg/t7507.scala +neg/macro-invalidusage-badargs +neg/macro-reify-typetag-typeparams-notags +neg/wellkinded_app2.scala +neg/t4425b.scala +neg/t2296a +neg/t1878.scala +neg/t649.scala +neg/override-object-no.scala +neg/t4174.scala +neg/t2070.scala +neg/sabin2.scala +neg/t5903e +neg/t6566a.scala +neg/finitary-error.scala +neg/t4818.scala +neg/t3614.scala +neg/t6666c.scala +neg/ticket513.scala +neg/suggest-similar.scala +neg/t4457_1.scala +neg/t6666e.scala +neg/tcpoly_bounds.scala +neg/t4727.scala +neg/t4425.scala +neg/macro-invalidusage-methodvaluesyntax +neg/t3854.scala +neg/t3006.scala +neg/t5580b.scala +neg/t5378.scala +neg/t639.scala +neg/wrong-args-for-none.scala +neg/t7171b.scala +neg/t5361.scala +neg/unreachablechar.scala +neg/t5572.scala +neg/t7757a.scala +neg/macro-invalidimpl +neg/t2773.scala +neg/t6359.scala +neg/saito.scala +neg/xmltruncated2.scala +neg/t667.scala +neg/t3934.scala +neg/t6771b.scala +neg/t4584.scala +neg/wellkinded_wrongarity2.scala +neg/t7369.scala +neg/t1477.scala +neg/t5617.scala +neg/t7299.scala +neg/faculty.scala +neg/virtpatmat_reach_null.scala +neg/macro-reify-typetag-hktypeparams-notags +neg/t1224.scala +neg/xmltruncated3.scala +neg/t1872.scala +neg/t558.scala +neg/t7110.scala +neg/any-vs-anyref.scala +neg/t6340.scala +neg/t4166.scala +neg/t2918.scala +neg/t5856.scala +neg/t4989.scala +neg/t0003.scala +neg/t1183.scala +neg/t963.scala +neg/t4515.scala +neg/valueclasses-pavlov.scala +neg/t608.scala +neg/choices.scala +neg/patmat-type-check.scala +neg/valueclasses-impl-restrictions.scala +neg/imp2.scala +neg/protected-constructors.scala +neg/t6788.scala +neg/nullary-override.scala +neg/t200.scala +neg/t343.scala +neg/names-defaults-neg-ref.scala +neg/tcpoly_typealias.scala +neg/classtags_contextbound_b.scala +neg/t729.scala +neg/t5683.scala +neg/t4928.scala +neg/t700.scala +neg/t7669.scala +neg/macro-invalidshape +neg/t6011.scala +neg/t7325.scala +neg/check-dead.scala +neg/t550.scala +neg/t5663-badwarneq.scala +neg/t0699 +neg/nopredefs.scala +neg/t3507-old.scala +neg/t5352.scala +neg/t6336.scala +neg/interop_classmanifests_arenot_typetags.scala +neg/sealed-final-neg.scala +neg/t2102.scala +neg/t7636.scala +neg/t5031b +neg/t798.scala +neg/t5702-neg-bad-xbrace.scala +neg/t0899.scala +neg/cyclics-import.scala +neg/badtok-2.scala +neg/t473.scala +neg/t3160ambiguous.scala +neg/t5106.scala +neg/t1286 +neg/macro-override-macro-overrides-abstract-method-b +neg/t0259.scala +neg/t510.scala +neg/t3836.scala +neg/t5830.scala +neg/t1548 +neg/t5580a.scala +neg/forward.scala +neg/t591.scala +neg/t6558b.scala +neg/t556.scala +neg/xmltruncated4.scala +neg/t5497.scala +neg/t409.scala +neg/t6283.scala +neg/override-object-flag.scala +neg/constructor-prefix-error.scala +neg/eta-expand-star.scala +neg/t3392.scala +neg/t1275.scala +neg/nested-fn-print.scala +neg/t7330.scala +neg/t2275a.scala +neg/t630.scala +neg/t4270.scala +neg/t2775.scala +neg/pat_unreachable.scala +neg/t4158.scala +neg/unit-returns-value.scala +neg/t1422.scala +neg/reify_metalevel_breach_-1_refers_to_0_b.scala +neg/reassignment.scala +neg/t3683a.scala +neg/noMember1.scala +neg/macro-without-xmacros-b +neg/t1106.scala +neg/t5182.scala +neg/t6889.scala +neg/t4217.scala +neg/t7501 +neg/t5063.scala +neg/t1009.scala +neg/t997.scala +neg/unchecked.scala +neg/classtags_contextbound_c.scala +neg/applydynamic_sip.scala +neg/t7715.scala +neg/t588.scala +neg/t6667b.scala +neg/t7757b.scala +neg/t4069.scala +neg/t515.scala +neg/variances2.scala +neg/t1049.scala +neg/t7289.scala +neg/t1623.scala +neg/permanent-blindness.scala +neg/t5803.scala +neg/super-cast-or-test.scala +neg/nonlocal-warning.scala +neg/t5687.scala +neg/t5903a +neg/t6566b.scala +neg/unchecked-knowable.scala +neg/t5093.scala +neg/protected-static-fail +neg/type-diagnostics.scala +neg/forgot-interpolator.scala +neg/interop_abstypetags_arenot_classmanifests.scala +neg/t5376.scala +neg/t545.scala +neg/xmlcorner.scala +neg/switch.scala +neg/depmet_1.scala +neg/abstract-concrete-methods.scala +neg/t4987.scala +neg/t5452-new.scala +neg/t750b +neg/unchecked-refinement.scala +neg/t418.scala +neg/t5354.scala +neg/t3736.scala +neg/t631.scala +neg/t6829.scala +neg/t0218.scala +neg/volatile-intersection.scala +neg/t412.scala +neg/t693.scala +neg/t4882.scala +neg/t1960.scala +neg/macro-divergence-controlled +neg/t712.scala +neg/t5544 +neg/t3222.scala +neg/t3604.scala +neg/t1112.scala +neg/t7157 +neg/accesses.scala +neg/t452.scala +neg/t6162-inheritance +neg/t2442 +neg/t6567.scala +neg/lazy-override.scala +neg/abstract-explaintypes.scala +neg/nested-annotation.scala +neg/t5753 +neg/t3691.scala +neg/infix-op-positions.scala +neg/t3403.scala +neg/t4851 +neg/structural.scala +neg/error_dependentMethodTpeConversionToFunction.scala +neg/t5839.scala +neg/t5553_1.scala +neg/reify_metalevel_breach_+0_refers_to_1.scala +neg/t752.scala +neg/t6574.scala +neg/t3714-neg.scala +neg/t4457_2.scala +neg/t2148.scala +neg/t1364.scala +neg/saferJavaConversions.scala +neg/t414.scala +neg/t5493.scala +neg/classtags_contextbound_a.scala +neg/reify_metalevel_breach_-1_refers_to_0_a.scala +neg/t3118.scala +neg/t512.scala +neg/t2336.scala +neg/t856.scala +neg/xmltruncated6.scala +neg/t2206.scala +neg/virtpatmat_unreach_select.scala +neg/t6258.scala +neg/t6815.scala +neg/not-possible-cause.scala +neg/dbldef.scala +neg/qualifying-class-error-1.scala +neg/t835.scala +neg/t5455.scala +neg/t6558.scala +neg/t708.scala +neg/macro-nontypeablebody +neg/t0565.scala +neg/xmltruncated5.scala +neg/t5390d.scala +neg/t520.scala +neg/t6138.scala +neg/macro-without-xmacros-a +neg/t7214neg.scala +neg/t2870.scala +neg/t593.scala +neg/t4541b.scala +neg/t4460b.scala +neg/t284.scala +neg/t2488.scala +neg/macro-override-method-overrides-macro +neg/interop_abstypetags_arenot_classtags.scala +neg/t3769.scala +neg/warn-inferred-any.scala +neg/t664.scala +neg/t5903d +neg/t562.scala +neg/t2316.scala +neg/t0152.scala +neg/migration28.scala +neg/t6443c.scala +neg/tcpoly_override.scala +neg/t7324.scala +neg/t987.scala +neg/t5903b +neg/t3481.scala +neg/t6912.scala +neg/tcpoly_variance_enforce.scala +neg/t3913.scala +neg/names-defaults-neg.scala +neg/t765.scala +neg/t5358.scala +neg/t391.scala +neg/serialversionuid-not-const.scala +neg/t771.scala +neg/t0903.scala +neg/catch-all.scala +neg/classmanifests_new_deprecations.scala +neg/t0606.scala +neg/t5189_inferred.scala +neg/macro-reify-typetag-useabstypetag +neg/t5543.scala +neg/logImplicits.scala +neg/interop_typetags_without_classtags_arenot_manifests.scala +neg/t6535.scala +neg/t7259.scala +neg/t2139.scala +neg/t278.scala +neg/t5564.scala +neg/unchecked3.scala +neg/virtpatmat_reach_sealed_unsealed.scala +neg/checksensible.scala +neg/t7721.scala +run/t3798.scala +run/macro-expand-varargs-explicit-over-varargs +run/t3888.scala +run/t0677-new.scala +run/t3273.scala +run/t3763.scala +run/t2755.scala +run/t920.scala +run/t5610a.scala +run/literals.scala +run/proxy.scala +run/unapply.scala +run/t5830.scala +run/array-addition.scala +run/macro-expand-nullary-nongeneric +run/macro-basic-ma-mdmi +run/valueclasses-constr.scala +run/t1247.scala +run/t3487.scala +run/rawstrings.scala +run/patmat-seqs.scala +run/eta-expand-star.scala +run/t7436.scala +run/t3996.scala +run/constructors.scala +run/t498.scala +run/t3835.scala +run/t298.scala +run/t2867.scala +run/t7120 +run/virtpatmat_literal.scala +run/t2175.scala +run/t2503.scala +run/t3026.scala +run/t603.scala +run/t0091.scala +run/t6394a +run/macro-expand-varargs-implicit-over-varargs +run/t7407.scala +run/t2552.scala +run/virtpatmat_npe.scala +run/macro-sip19 +run/t6644.scala +run/t6614.scala +run/t2005.scala +run/t4680.scala +run/t5903a +run/classtags_contextbound.scala +run/Course-2002-05.scala +run/applydynamic_sip.scala +run/t1766.scala +run/retsynch.scala +run/t7715.scala +run/t102.scala +run/nonlocalreturn.scala +run/macro-reify-staticXXX +run/Course-2002-06.scala +run/t6863.scala +run/t6500.scala +run/macro-impl-rename-context +run/t4351.scala +run/t5009.scala +run/macro-term-declared-in-annotation +run/t6271.scala +run/array-existential-bound.scala +run/t6443b.scala +run/t1987.scala +run/MutableListTest.scala +run/t7571.scala +run/t5488-fn.scala +run/macro-bodyexpandstoimpl +run/macro-reify-ref-to-packageless +run/t2212.scala +run/macro-expand-varargs-implicit-over-nonvarargs +run/t0807.scala +run/patmat-behavior.scala +run/t2446.scala +run/breakout.scala +run/t4122.scala +run/macro-settings +run/t7157 +run/t1323.scala +run/t4013b.scala +run/t6309.scala +run/t4047.scala +run/t5544 +run/t978.scala +run/t3361.scala +run/t6611.scala +run/t5387.scala +run/t5656.scala +run/t4897.scala +run/numeric-range.scala +run/t4777.scala +run/Course-2002-03.scala +run/string-extractor.scala +run/view-headoption.scala +run/patmat_unapp_abstype-new.scala +run/stream-stack-overflow-filter-map.scala +run/macro-impl-tparam-only-in-impl +run/t6559.scala +run/macro-reify-tagful-a +run/macro-expand-multiple-arglists +run/t4709.scala +run/t3509.scala +run/t5284b.scala +run/t7617b +run/t3923.scala +run/virtpatmat_apply.scala +run/t363.scala +run/manifests-undeprecated-in-2.10.0.scala +run/matchintasany.scala +run/t3970.scala +run/t4996.scala +run/t5530.scala +run/macro-term-declared-in-object-class +run/t3242b.scala +run/indexedSeq-apply.scala +run/t107.scala +run/t2337.scala +run/t2754.scala +run/flat-flat-flat.scala +run/t6673.scala +run/interpolationMultiline2.scala +run/t0631.scala +run/t2800.scala +run/t6506.scala +run/t6260.scala +run/t2418.scala +run/t4415.scala +run/classmanifests_new_alias.scala +run/t5380.scala +run/tcpoly_parseridioms.scala +run/t1747.scala +run/t5903d +run/t3530.scala +run/t216.scala +run/macro-term-declared-in-refinement +run/t4592.scala +run/t2488.scala +run/t3327.scala +run/t5614.scala +run/t5903b +run/iterables.scala +run/t3964.scala +run/t6329_vanilla.scala +run/t3038c +run/t1697.scala +run/t2030.scala +run/t3397.scala +run/t1005.scala +run/t3353.scala +run/t1466.scala +run/t3186.scala +run/tcpoly_overriding.scala +run/t5394.scala +run/t5284.scala +run/unboxingBug.scala +run/t7200.scala +run/macro-reify-basic +run/t153.scala +run/iterator3444.scala +run/macro-expand-implicit-macro-is-val +run/macro-basic-ma-md-mi +run/interpolationArgs.scala +run/t4954.scala +run/t3645.scala +run/transpose.scala +run/t3887.scala +run/t4288.scala +run/unittest_iterator.scala +run/t5543.scala +run/macro-term-declared-in-object +run/iq.scala +run/t2788.scala +run/t2027.scala +run/macro-expand-recursive +run/t949.scala +run/t1909b.scala +run/delambdafy-nested-by-name.scala +run/delambdafy-two-lambdas.scala +run/macro-blackbox-materialization +run/lists-run.scala +run/macro-parse-position +run/macro-parse-position-malformed +run/macro-whitebox-dynamic-materialization +run/macro-whitebox-extractor +run/macro-vampire-false-warning +run/macro-whitebox-fundep-materialization +run/macro-whitebox-structural +run/mutable-treeset.scala +run/static-module-method.scala +run/sort.scala +run/t1909.scala +run/t1909c.scala +run/t3346a.scala +run/t3346d.scala +run/t3346f.scala +run/t3346h.scala +run/t3346g.scala +run/t3832.scala +run/t4742.scala +run/t5377.scala +run/t5923c.scala +run/t6188.scala +run/t6333.scala +run/t6385.scala +run/t7899.scala +run/t7584b.scala +run/t7223.scala +run/t7859 +run/t7868.scala +run/t7871 +run/arrayclone-new.scala +run/arrayclone-old.scala +run/bitsets.scala +run/comparable-comparator.scala +run/colltest1.scala +run/t2106.scala +run/t5986.scala +run/view-iterator-stream.scala +run/array-charSeq.scala +pos/signatures +pos/t1263 +pos/t3249 +neg/t4749.scala +neg/main1.scala +neg/t7251 +neg/t7494-after-terminal +neg/t7494-before-parser +neg/t7494-right-after-terminal +run/lazy-traits.scala +run/OrderingTest.scala +run/ReplacementMatching.scala +run/patmat-finally.scala +run/t3158.scala +run/t3346e.scala +run/t4398.scala +run/t4930.scala +run/t6534.scala +pos/sammy_scope.scala +pos/delambdafy-patterns.scala +pos/private-types-after-typer.scala +pos/delambdafy-lambdalift.scala +pos/sammy_poly.scala +pos/sammy_single.scala +pos/sammy_twice.scala +pos/t3160.scala +pos/t1014.scala +pos/t4970b.scala +pos/t2698.scala +pos/t5845.scala +pos/t6201.scala +pos/t6260a.scala +pos/t7688.scala +pos/t7818.scala +pos/t1203a.scala +pos/t7834.scala +pos/t7853.scala +pos/t7815.scala +pos/t7853-partial-function.scala +pos/t7864.scala +pos/t7928.scala +pos/t7902.scala +pos/t7944.scala +pos/t7847 +neg/accesses2.scala +neg/bad-advice.scala +neg/gadts2.scala +neg/gadts2-strict.scala +neg/macro-bundle-abstract.scala +neg/macro-bundle-object.scala +neg/macro-bundle-trait.scala +neg/macro-blackbox-dynamic-materialization +neg/macro-blackbox-extractor +neg/run-gadts-strict.scala +neg/macro-blackbox-structural +neg/sammy_restrictions.scala +neg/sammy_wrong_arity.scala +neg/t2462c.scala +neg/t3346b.scala +neg/t1909-object.scala +neg/macro-blackbox-fundep-materialization +neg/t3346c.scala +neg/t3871.scala +neg/t3871b.scala +neg/t3971.scala +neg/t3346i.scala +neg/t6120.scala +neg/t6260c.scala +neg/t6680a.scala +neg/t7239.scala +neg/t7007.scala +neg/t7605-deprecation.scala +neg/t7622-missing-required.scala +neg/t7629-view-bounds-deprecation.scala +neg/t7834neg.scala +neg/t7783.scala +neg/t7848-interp-warn.scala +neg/t7519-b +neg/t7622-missing-dependency +neg/t7870.scala +neg/t7877.scala +neg/t7895.scala +neg/t7895b.scala +neg/t7899.scala +neg/t7895c.scala +neg/t7859 +run/t4752.scala +run/t2087-and-2400.scala +run/t3855.scala +run/t6637.scala +run/t6731.scala +pos/t3999b.scala +run/t0432.scala +run/t2514.scala +run/t7817.scala +run/t874.scala +run/type-currying.scala +run/t3616.scala +run/t3687.scala +run/t4570.scala +run/t5612.scala +run/t1110.scala +run/t2636.scala +run/verify-ctor.scala +run/t3647.scala +run/t4560.scala +run/t6632.scala +run/richs.scala +run/t6725-1.scala +pos/t7776.scala +run/fors.scala +run/t6706.scala +run/t3175.scala +run/delambdafy-dependent-on-param-subst.scala +run/t4332b.scala +run/t8048a +run/t8017 +run/t7985b.scala +run/t8100.scala +run/patmat-mix-case-extractor.scala +run/t4750.scala +run/t7912.scala +run/delambdafy-dependent-on-param-subst-2.scala +run/t8048b +run/t8091.scala +run/macroPlugins-macroRuntime +run/macro-default-params +run/t6355.scala +run/t7777 +run/t8002.scala +run/t8015-ffc.scala +run/macro-subpatterns +run/t7985.scala +run/macroPlugins-macroArgs +run/t7326.scala +run/t5045.scala +run/value-class-partial-func-depmet.scala +run/t6329_vanilla_bug.scala +run/macroPlugins-macroExpand +run/t8010.scala +run/macroPlugins-typedMacroBody +run/t7406.scala +pos/t8146a.scala +pos/t8046c.scala +pos/t8132.scala +pos/t8045.scala +pos/overzealous-assert-genbcode.scala +pos/t8128.scala +pos/t8013 +pos/t8064b +pos/t6780.scala +pos/t7987 +pos/bcode_throw_null +pos/t8064 +pos/t8046.scala +pos/t6231.scala +pos/t7983.scala +pos/t5508.scala +pos/t5508-min.scala +pos/t8023b.scala +pos/t6231b.scala +pos/debug-reset-local-attrs.scala +pos/t8054.scala +pos/t2066.scala +pos/dotless-targs.scala +pos/t8120.scala +pos/t5508-min-okay.scala +pos/t8060.scala +pos/t8001 +pos/t8138.scala +pos/t8111.scala +pos/t8011.scala +pos/t8146b.scala +pos/t8046b.scala +pos/t8023.scala +pos/t5508-min-okay2.scala +pos/macro-implicit-invalidate-on-error.scala +neg/t6563.scala +neg/missing-param-type-tuple.scala +neg/not-a-legal-formal-parameter-tuple.scala +neg/t7897.scala +neg/t8015-ffa.scala +neg/quasiquotes-unliftable-not-found.scala +neg/t2066b.scala +neg/dotless-targs.scala +neg/patmat-classtag-compound.scala +neg/t2066.scala +neg/t8035-deprecated.scala +neg/t6675b.scala +neg/t8104 +neg/t7872.scala +neg/t7850.scala +neg/t7967.scala +neg/macro-bundle-overloaded.scala +neg/t6355a.scala +neg/class-of-double-targs.scala +neg/t6355b.scala +neg/macro-reify-splice-splice +neg/macro-bundle-noncontext.scala +neg/t8015-ffb.scala +neg/t8035-removed.scala +neg/t7984.scala +neg/t8024.scala +neg/t8024b.scala +neg/t8157.scala +neg/t8146-non-finitary-2.scala +neg/t8006.scala +neg/t7872c.scala +neg/t8146-non-finitary.scala +neg/t7872b.scala +neg/t6920.scala +run/t6200.scala +run/t6196.scala +run/macro-bundle-context-refinement +run/macro-enclosingowner-detectvar +run/macro-enclosingowner-sbt +run/macro-bundle-context-alias +run/macro-bundle-whitebox-use-refined +run/macro-bundle-whitebox-use-raw +neg/name-lookup-stable.scala +neg/t0764b.scala +neg/no-implicit-to-anyref-any-val.scala +neg/t1503.scala +neg/t4728.scala +neg/t6455.scala +neg/t6260-named.scala +neg/t6844.scala +neg/t7475c.scala +neg/t7475e.scala +neg/t7475f.scala +neg/macro-bundle-whitebox-use-raw +neg/macro-bundle-whitebox-use-refined +neg/macro-incompatible-macro-engine-b +neg/t7980.scala +neg/macro-incompatible-macro-engine-a +neg/t8143a.scala +neg/t8072.scala +neg/t8207.scala +neg/t8182.scala +neg/t8219-any-any-ref-equals.scala +neg/t8177a.scala +neg/t8228.scala +neg/t8229.scala +neg/t8237-default.scala +neg/t8244b.scala +neg/t8244e +neg/t8244c.scala +neg/t8265.scala +neg/t8266-invalid-interp.scala +neg/t6931 +neg/t8376 +neg/t8372.scala +neg/t8300-overloading.scala +neg/t8244 +neg/t8158 +neg/t8431.scala +pos/implicit-anyval-2.10.scala +pos/delambdafy_t6260_method.scala +pos/macro-bundle-disambiguate-bundle.scala +pos/macro-bundle-disambiguate-nonbundle.scala +pos/package-ob-case +pos/t1786-counter.scala +pos/reflection-compat-api-universe.scala +pos/existential-java-case-class +pos/t1786-cycle.scala +pos/reflection-compat-c.scala +pos/t3452f.scala +pos/reflection-compat-ru.scala +pos/t2066-2.10-compat.scala +pos/reflection-compat-macro-universe.scala +pos/t5900a.scala +pos/t5760-pkgobj-warn +pos/t5954a +pos/t5954b +pos/t5954d +pos/t6260.scala +pos/t5165b +pos/t5954c +pos/t6260b.scala +pos/t7475b.scala +pos/t7475a.scala +pos/t7753.scala +pos/t7322.scala +pos/t6948.scala +pos/t7475d.scala +pos/t7475e.scala +pos/t6169 +pos/t7788.scala +pos/t7919.scala +pos/t8177a.scala +pos/t8177.scala +pos/t8170.scala +pos/t8170b.scala +pos/t8177d.scala +pos/t8177b.scala +pos/t8177e.scala +pos/t8134 +pos/t8177h.scala +pos/t8177g.scala +pos/t8207.scala +pos/t8187.scala +pos/t8219.scala +pos/t8219b.scala +pos/t8224.scala +pos/t8237.scala +pos/t8223.scala +pos/t8237b.scala +pos/t8300-conversions-a.scala +pos/t8300-conversions-b.scala +pos/t8209a +pos/t8209b +pos/t8244d +pos/t8300-overloading.scala +pos/t8300-patmat-a.scala +pos/t8300-patmat-b.scala +pos/t8301.scala +pos/t8324.scala +pos/t8301b.scala +pos/t8363.scala +pos/t8367.scala +pos/t8369a.scala +pos/t8369b.scala +pos/t8403.scala +pos/t8364.scala +pos/t8352 +pos/t8376 +neg/macro-bundle-nonpublic-c.scala +neg/literate_existentials.scala +neg/macro-bundle-nonpublic-impl.scala +neg/macro-bundle-ambiguous.scala +neg/macro-bundle-priority-bundle.scala +neg/macro-bundle-need-qualifier.scala +neg/macro-bundle-nonstatic.scala +neg/macro-bundle-polymorphic.scala +neg/macro-bundle-priority-nonbundle.scala +neg/macro-bundle-wrongcontext-a.scala +neg/macro-bundle-wrongcontext-b.scala +run/t8425 +run/t8245.scala +run/t8266-octal-interp.scala +run/t8280.scala +run/t8395.scala +run/t8321 +run/t8153.scala +run/t8197.scala +run/t8197b.scala +run/t8233.scala +run/t8133 +run/t8133b +run/t7475b.scala +run/t6814 +run/t4577.scala +run/t5134.scala +run/t3452f.scala +run/t3452h.scala +run/t3452c.scala +run/t3452.scala +run/t261.scala +run/t3235-minimal.scala +run/t1503_future.scala +run/t5565.scala +pos/t8411 +pos/t8460.scala +run/t8428.scala +run/t8437 +run/absoverride.scala +run/arrays.scala +run/duration-coarsest.scala +run/iterator-from.scala +run/SymbolsTest.scala +run/t1074.scala +run/t1505.scala +run/streams.scala +run/t2111.scala +run/t4601.scala +neg/t3692-new.scala +run/t7015.scala +run/t7992b.scala +run/t7992.scala +run/t8570.scala +pos/t8157-2.10.scala +pos/t8325.scala +pos/t8523.scala +pos/t8578.scala +pos/t8329.scala +pos/t8497 +pos/t8546.scala +pos/t8531 +neg/t8325-c.scala +neg/t8325-b.scala +neg/t8325.scala +neg/t6988.scala +neg/t8463.scala +neg/t8450.scala +neg/t8430.scala +run/finally.scala +neg/t8630.scala +neg/t8035-no-adapted-args.scala +neg/t8675b.scala +neg/t8610-arg.scala +neg/t8736-c.scala +neg/tailrec-4.scala +neg/double-def-top-level +neg/t8610.scala +neg/aladdin1055 +neg/virtpatmat_exhaust_compound.scala +neg/t8675.scala +neg/t8525.scala +pos/t8736.scala +pos/t8625.scala +pos/t8596.scala +pos/t8617.scala +pos/t8736-b.scala +pos/t8708 +pos/macro-attachments +run/t8611a.scala +run/t8738.scala +run/macro-rangepos-args +run/t8610.scala +run/macro-rangepos-subpatterns +run/t8611c.scala +run/macroPlugins-isBlackbox +run/t8601d.scala +run/t8607.scala +run/bugs.scala +run/t1503.scala +run/t4148.scala +run/t7763.scala +run/issue192.scala +run/t8893b.scala +run/t8845.scala +run/t8933 +run/t7459c.scala +run/t9003.scala +run/t7459f.scala +run/t8933c.scala +run/t1994.scala +run/t2866.scala +run/t5665.scala +run/t7459d.scala +run/t8933b +run/t8888.scala +run/t7459b-optimize.scala +run/t7459a.scala +run/t7019.scala +run/t8893.scala +run/t8803.scala +run/t7459b.scala +run/t8823.scala +run/t6541.scala +run/nothingTypeDce.scala +run/t8680.scala +run/t8925.scala +run/nothingTypeNoOpt.scala +run/t9030.scala +run/bigDecimalTest.scala +run/bigDecimalCache.scala +run/range.scala +run/t6064.scala +run/t7521 +run/t8710.scala +run/t8575.scala +run/t8944 +run/t8944b.scala +run/t9387.scala +run/t9387b.scala +pos/t7784.scala +pos/t8862a.scala +pos/t9074.scala +pos/t8462.scala +pos/t8862b.scala +pos/alladin763.scala +pos/t6778.scala +pos/t9074b.scala +pos/t9326a.scala +pos/t9131.scala +pos/t9393 +pos/t9392 +neg/missing-arg-list.scala +neg/deprecated-target.scala +neg/t6895.scala +neg/beanInfoDeprecation.scala +neg/t8777.scala +neg/t6895b.scala +neg/t8892.scala +neg/t8849.scala +neg/inlineIndyLambdaPrivate +run/t9029.scala +run/t7850c.scala +run/t7850d.scala +run/t8334.scala +run/t9029c.scala +run/t9029b.scala +run/t9422.scala +run/t9425.scala +pos/t9475.scala +pos/t9498.scala +pos/t9479.scala +pos/t9479b.scala +pos/t9442.scala +pos/t9369.scala +pos/t6666d.scala +pos/t9370 +neg/t6810.scala +neg/t8127a.scala +neg/t8989.scala +neg/t9401.scala +neg/implicit-ambiguous.scala +neg/implicit-ambiguous-2.scala +neg/implicit-ambiguous-invalid.scala +neg/warn-unused-imports +run/t7269.scala +run/equality.scala +run/number-parsing.scala +run/t6220.scala +run/mapConserve.scala +run/colltest.scala +run/t0412.scala +run/t6261.scala +run/java-erasure.scala +run/t6197.scala +run/t4201.scala +run/t5608.scala +run/t3518.scala +run/t6198.scala +run/t2813.2.scala +pos/java-type-annotations +pos/sammy_infer_argtype_subtypes.scala +pos/sammy_ctor_arg.scala +pos/fun_undo_eta.scala +pos/sammy_inferargs.scala +pos/existental-slow-compile2.scala +pos/existential-slow-compile1.scala +pos/sammy_implicit.scala +pos/t9178b.scala +pos/t9449.scala +pos/t3234.scala +pos/t9542.scala +pos/t8429.scala +pos/t9658.scala +pos/t9630 +pos/t9399.scala +pos/t9411a.scala +pos/t9411b.scala +neg/partestInvalidFlag.scala +neg/sammy_error.scala +neg/sammy_disabled.scala +neg/sammy_overload.scala +neg/sammy_expected.scala +neg/t8700a +neg/t9527b.scala +neg/t9527a.scala +neg/t9572.scala +neg/t9535.scala +neg/t9629.scala +neg/optimiseDeprecated.scala +neg/t9398 +neg/outer-ref-checks.scala +neg/t8685.scala +neg/t8700b +run/t9349 +run/t9178a.scala +run/t9110.scala +run/sammy_cbn.scala +run/sammy_erasure_cce.scala +run/sammy_after_implicit_view.scala +run/sammy_restrictions_LMF.scala +run/sammy_vararg_cbn.scala +run/t7807.scala +run/sammy_return.scala +run/t9546.scala +run/t9546b.scala +run/lisp.scala +run/t9546c.scala +run/t9546d.scala +run/t9546e.scala +run/t9567.scala +run/t9567b.scala +run/trait-clonable.scala +run/t9567c.scala +run/trait-defaults-modules.scala +run/trait-defaults-modules3.scala +run/trait-defaults-modules2 +pos/functions.scala +pos/MailBox.scala +neg/t6289 +run/t6114.scala +pos/constant-warning.scala +pos/t2712-5.scala +pos/t2712-2.scala +pos/t2712-4.scala +pos/t2712-1.scala +pos/t2712-3.scala +pos/t2712-6.scala +pos/t6895b.scala +pos/t5683.scala +pos/hkgadt.scala +pos/t2712-7.scala +pos/t9245.scala +pos/t7088.scala +pos/t8044.scala +pos/t9665.scala +pos/t9397.scala +pos/t5183.scala +pos/t8449 +neg/t8044-b.scala +neg/t8044.scala +neg/t2712-3.scala +neg/t2712-2.scala +neg/t2712-1.scala +neg/t9045.scala +neg/t8667.scala +neg/t9361.scala +neg/t9781.scala +neg/trait-no-native.scala +neg/hkgadt.scala +neg/t9684b.scala +neg/t9382.scala +neg/trait-defaults-super.scala +neg/t9684.scala +run/hashCodeStatics.scala +run/t9390d.scala +run/trait-static-clash.scala +run/t5568.scala +run/t6318_primitives.scala +pos/fields_widen_trait_var.scala +pos/sammy_extends_function.scala +pos/infer_override_def_args.scala +pos/t482.scala +pos/t8079b.scala +pos/t6161b.scala +pos/t5294b.scala +pos/t5294c.scala +pos/overloaded_ho_fun.scala +pos/t4914.scala +pos/trait_fields_dependent_conflict.scala +pos/t2377b +pos/trait_fields_dependent_rebind.scala +pos/t9855b.scala +pos/trait_fields_inherit_double_def.scala +pos/t9855.scala +pos/t8873.scala +pos/trait_fields_nested_private_object.scala +pos/trait_fields_nested_public_object.scala +pos/trait_fields_private_this.scala +pos/trait_fields_var_override_deferred.scala +pos/trait_fields_static_fwd.scala +pos/trait_fields_owners.scala +pos/trait_fields_volatile.scala +pos/trait_lazy_accessboundary.scala +pos/trait_fields_lambdalift.scala +pos/typevar-in-prefix.scala +pos/val_infer.scala +pos/lub-from-hell.scala +neg/t8079a.scala +neg/sd128 +neg/t9849.scala +neg/trait_fields_var_override.scala +neg/val_infer.scala +neg/val_sig_infer_match.scala +neg/t7187.scala +neg/trait_fields_deprecated_overriding.scala +neg/t9847.scala +neg/val_sig_infer_struct.scala +neg/trait_fields_conflicts.scala +neg/lub-from-hell-2.scala +run/t2946 +run/lazy_local_labels.scala +run/sd167.scala +run/t9841.scala +run/trait-fields-override-lazy.scala +run/trait_fields_init.scala +run/trait_fields_three_layer_overrides.scala +run/t9516.scala +run/t10032.scala +pos/sam_erasure_boundedwild.scala +pos/t10154.scala +pos/t10066.scala +pos/t10154b.scala +pos/t10093.scala +pos/t8040.scala +pos/t3772.scala +pos/t10206.scala +pos/t9331.scala +pos/userdefined_apply_poly_overload.scala +pos/userdefined_apply.scala +pos/trailing-commas.scala +neg/t10097.scala +neg/t10068.scala +neg/ambiguous-same.scala +neg/maxerrs.scala +neg/maxwarns.scala +neg/t10207.scala +neg/t10066.scala +neg/t3236-neg +neg/t3772.scala +neg/t8704.scala +neg/t8002-nested-scope.scala +neg/t10097b.scala +neg/trailing-commas.scala +neg/t9834.scala +neg/userdefined_apply.scala +neg/t8417.scala +neg/warn-unused-implicits.scala +neg/t7860.scala +neg/t8763.scala +neg/t9636.scala +neg/warn-unused-params.scala +neg/t9675.scala +neg/warn-unused-patvars.scala +run/t10069.scala +run/SD-290.scala +run/sd329.scala +run/t10097.scala +run/t10072.scala +run/t10261 +run/t9114.scala +run/t10069b.scala +pos/t10205.scala +pos/t7100.scala +pos/t5788.scala +pos/t4012-b.scala +pos/t7638.scala +pos/t4012-a.scala +pos/dotless-targs-ranged.scala +neg/t5355.scala +neg/badtok-1-212.scala +neg/t6714.scala +neg/t10249 +run/macro-implicit-decorator +run/t10290.scala +run/t10298.scala +run/t10389.scala +run/t10423 +run/t6714.scala +run/t9146.scala +run/wacky-value-classes.scala +pos/t10088.scala +pos/t10213.scala +pos/t10195b.scala +pos/t10195.scala +pos/t10197.scala +pos/t10185.scala +pos/patmat-hk.scala +pos/t10159 +pos/t10372.scala +pos/t10238.scala +pos/t10288.scala +pos/t5818.scala +pos/t6895b-2.scala +pos/t10296-before +pos/warn-unused-params-not-implicits.scala +pos/t10296 +pos/t9122.scala +pos/t10270 +pos/t9647.scala +neg/t10279.scala +neg/hk-typevar-unification.scala +neg/t10260 +neg/names-defaults-neg-213.scala +neg/t6934 +neg/t9138.scala +neg/t7187-2.13.scala +neg/t10296-after +neg/t10296-warn +neg/t10270 +neg/t10296-both +run/implicit-caching.scala +run/abstype_implicits.scala +run/sd336.scala +run/hk-typevar-unification.scala +run/t10283.scala +run/t10291.scala +run/t10439.scala +run/t10454-1 +run/t10454-2 +run/t7187-2.13.scala +pos/t10406.scala +pos/parallel-classloader.scala +pos/t10375.scala +pos/t10623.scala +pos/t10643.scala +pos/t10394.scala +pos/t8343.scala +pos/t10763.scala +pos/t7420.scala +pos/t10568 +pos/t10684.scala +pos/t10667.scala +pos/t10644 +pos/t9155.scala +pos/t9220.scala +neg/badimport.scala +neg/t10474.scala +neg/string-context-refchecked.scala +neg/t10678.scala +neg/t10661.scala +neg/t10619.scala +neg/t10530.scala +neg/t10731.scala +neg/t10695.scala +neg/t10073.scala +neg/t10073b.scala +neg/case-collision-multifile +neg/implicitly-self.scala +neg/t10701 +run/t10551.scala +run/t10611.scala +run/t10646.scala +run/t10692.scala + +# Adapt checkfiles for (1.0).toString == "1" +run/Course-2002-01.scala +run/t0421-new.scala +run/runtime.scala +run/t0421-old.scala +run/spec-self.scala +run/t5552.scala +run/Course-2002-02.scala +run/Course-2002-04.scala +run/promotion.scala +run/t4617.scala +run/Course-2002-09.scala +run/t5866.scala +run/try-catch-unify.scala +run/impconvtimes.scala +run/Course-2002-10.scala +run/Course-2002-08.scala +run/MeterCaseClass.scala +run/Meter.scala +run/deeps.scala +run/caseClassHash.scala +run/interpolation.scala +run/interpolationMultiline1.scala +run/t9656.scala +pos/sd219.scala +pos/t9918 +pos/shapeless-regression.scala +pos/issue244.scala +pos/t9920.scala +pos/t9943.scala +neg/t5148.scala +run/sd242.scala +run/local_obj.scala +run/t9697.scala +run/t9920.scala +run/t9920c.scala +run/t9920d.scala +run/t9920b.scala +run/t9946a.scala +run/t9946c.scala +run/t9946b.scala +run/trait-super-calls.scala +pos/sd268.scala +pos/sd248 +pos/t6734.scala +pos/t10009.scala +pos/t7551 +pos/t6978 +pos/t7046-2 +neg/t9953.scala +neg/t7014 +neg/t7046-2 +neg/t7046 +run/t7046-1 +run/t7046-2 + +# Adapt checkfiles for ().toString == "undefined" +run/t5680.scala +run/dynamic-anyval.scala +run/macro-bundle-toplevel +run/macro-bundle-whitebox-decl +run/t6662 +run/t8570a.scala +run/t3702.scala +run/t7657 +run/macro-bundle-static +run/structural.scala + +# Adapt checkfiles for print & flush (which we cannot 100% emulate) +run/imports.scala +run/misc.scala + +# Adapt checkfiles for compiler phase list +neg/t7494-no-options +neg/t6446-list +neg/t6446-missing +neg/t6446-show-phases.scala +neg/t6446-additional + +# Adapt checkfiles for different behavior with boxed types +run/virtpatmat_typetag.scala +run/virtpatmat_switch.scala +run/t5629b.scala +run/t5356.scala +run/anyval-box-types.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/neg/t6446-additional.check new file mode 100644 index 0000000000..b7ce23da2f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/neg/t6446-additional.check @@ -0,0 +1,30 @@ + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + ploogin 27 A sample phase that does so many things it's kind of hard... + terminal 28 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/neg/t6446-list.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/neg/t6446-list.check new file mode 100644 index 0000000000..95883c8c81 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/neg/t6446-list.check @@ -0,0 +1,2 @@ +ploogin - A sample plugin for testing. +scalajs - Compile to JavaScript diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/neg/t6446-missing.check new file mode 100644 index 0000000000..56b74a3128 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/neg/t6446-missing.check @@ -0,0 +1,30 @@ +Error: unable to load class: t6446.Ploogin + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + terminal 27 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/neg/t6446-show-phases.check new file mode 100644 index 0000000000..cde255e3b1 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/neg/t6446-show-phases.check @@ -0,0 +1,29 @@ + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + terminal 27 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/neg/t7494-no-options.check new file mode 100644 index 0000000000..d8be421e5e --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/neg/t7494-no-options.check @@ -0,0 +1,31 @@ +error: Error: ploogin takes no options + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + ploogin 27 A sample phase that does so many things it's kind of hard... + terminal 28 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Course-2002-01.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Course-2002-01.check new file mode 100644 index 0000000000..fcda9433de --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Course-2002-01.check @@ -0,0 +1,37 @@ +Course-2002-01.scala:41: warning: method loop in object M0 does nothing other than call itself recursively + def loop: Int = loop; + ^ +232 +667 +11 +10 +62.8318 +62.8318 +62.8318 +4 +81 +256 +25 +1 +737 +1 +0 +1 +76 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +sqrt(2) = 1.4142135623746899 +sqrt(2) = 1.4142135623746899 +cbrt(2) = 1.2599210500177698 +1 +1 1 +1 2 1 +1 3 3 1 +1 4 6 4 1 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Course-2002-02.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Course-2002-02.check new file mode 100644 index 0000000000..ab75cfdb61 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Course-2002-02.check @@ -0,0 +1,187 @@ +7 +120 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +pi = 3.181104885577714 +pi = 3.181104885577714 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 +pi = 3.181104885577714 +pi = 3.181104885577714 + +1.5 +1.4166666666666665 +1.4142156862745097 +1.4142135623746899 +sqrt(2) = 1.4142135623746899 + +1.5 +1.4166666666666665 +1.4142156862745097 +1.4142135623746899 +sqrt(2) = 1.4142135623746899 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +power(0,0) = 1 +power(0,1) = 0 +power(0,2) = 0 +power(0,3) = 0 +power(0,4) = 0 +power(0,5) = 0 +power(0,6) = 0 +power(0,7) = 0 +power(0,8) = 0 + +power(1,0) = 1 +power(1,1) = 1 +power(1,2) = 1 +power(1,3) = 1 +power(1,4) = 1 +power(1,5) = 1 +power(1,6) = 1 +power(1,7) = 1 +power(1,8) = 1 + +power(2,0) = 1 +power(2,1) = 2 +power(2,2) = 4 +power(2,3) = 8 +power(2,4) = 16 +power(2,5) = 32 +power(2,6) = 64 +power(2,7) = 128 +power(2,8) = 256 + +power(3,0) = 1 +power(3,1) = 3 +power(3,2) = 9 +power(3,3) = 27 +power(3,4) = 81 +power(3,5) = 243 +power(3,6) = 729 +power(3,7) = 2187 +power(3,8) = 6561 + +power(4,0) = 1 +power(4,1) = 4 +power(4,2) = 16 +power(4,3) = 64 +power(4,4) = 256 +power(4,5) = 1024 +power(4,6) = 4096 +power(4,7) = 16384 +power(4,8) = 65536 + +power(5,0) = 1 +power(5,1) = 5 +power(5,2) = 25 +power(5,3) = 125 +power(5,4) = 625 +power(5,5) = 3125 +power(5,6) = 15625 +power(5,7) = 78125 +power(5,8) = 390625 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Course-2002-04.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Course-2002-04.check new file mode 100644 index 0000000000..fc6ad96eed --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Course-2002-04.check @@ -0,0 +1,64 @@ +list0 = List(6, 3, 1, 8, 7, 1, 2, 5, 8, 4, 3, 4, 8) +list1 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list2 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list3 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list4 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list5 = List(8, 8, 8, 7, 6, 5, 4, 4, 3, 3, 2, 1, 1) +list6 = List(8, 8, 8, 7, 6, 5, 4, 4, 3, 3, 2, 1, 1) + +list0: List() -> List() +list1: List(0) -> List(0) +list2: List(0, 1) -> List(0, 1) +list3: List(1, 0) -> List(0, 1) +list4: List(0, 1, 2) -> List(0, 1, 2) +list5: List(1, 0, 2) -> List(0, 1, 2) +list6: List(0, 1, 2) -> List(0, 1, 2) +list7: List(1, 0, 2) -> List(0, 1, 2) +list8: List(2, 0, 1) -> List(0, 1, 2) +list9: List(2, 1, 0) -> List(0, 1, 2) +listA: List(6, 3, 1, 8, 7, 1, 2, 5, 8, 4) -> List(1, 1, 2, 3, 4, 5, 6, 7, 8, 8) + +f(x) = 5x^3+7x^2+5x+9 +f(0) = 9 +f(1) = 26 +f(2) = 87 +f(3) = 222 + +v1 = List(2, 3, 4) +v2 = List(6, 7, 8) + +id = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +m1 = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m2 = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) + +v1 * v1 = 29 +v1 * v2 = 65 +v2 * v1 = 65 +v1 * v2 = 65 + +id * v1 = List(2, 3, 4) +m1 * v1 = List(4, 6, 8) +m2 * v1 = List(20, 47, 74) + +trn(id) = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +trn(m1) = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +trn(m2) = List(List(1, 4, 7), List(2, 5, 8), List(3, 6, 9)) + +List(v1) * id = List(List(2, 3, 4)) +List(v1) * m1 = List(List(4, 6, 8)) +List(v1) * m2 = List(List(42, 51, 60)) + +id * List(v1) = List(List(2, 3, 4), List(0, 0, 0), List(0, 0, 0)) +m1 * List(v1) = List(List(4, 6, 8), List(0, 0, 0), List(0, 0, 0)) +m2 * List(v1) = List(List(2, 3, 4), List(8, 12, 16), List(14, 21, 28)) + +id * id = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +id * m1 = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m1 * id = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m1 * m1 = List(List(4, 0, 0), List(0, 4, 0), List(0, 0, 4)) +id * m2 = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) +m2 * id = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) +m1 * m2 = List(List(2, 4, 6), List(8, 10, 12), List(14, 16, 18)) +m2 * m1 = List(List(2, 4, 6), List(8, 10, 12), List(14, 16, 18)) +m2 * m2 = List(List(30, 36, 42), List(66, 81, 96), List(102, 126, 150)) + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Course-2002-08.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Course-2002-08.check new file mode 100644 index 0000000000..0585d5b44f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Course-2002-08.check @@ -0,0 +1,171 @@ +x = abc +count = 111 +x = hello +count = 112 + +account deposit 50 -> undefined +account withdraw 20 -> 30 +account withdraw 20 -> 10 +account withdraw 15 -> + +x deposit 30 -> undefined +y withdraw 20 -> + +x deposit 30 -> undefined +x withdraw 20 -> 10 + +x deposit 30 -> undefined +y withdraw 20 -> 10 + +2^0 = 1 +2^1 = 2 +2^2 = 4 +2^3 = 8 + +2^0 = 1 +2^1 = 2 +2^2 = 4 +2^3 = 8 + +1 2 3 +List(1, 2, 3) + +out 0 new-value = false +*** simulation started *** +out 1 new-value = true +!0 = 1 + +*** simulation started *** +out 2 new-value = false +!1 = 0 + +out 2 new-value = false + +*** simulation started *** +0 & 0 = 0 + +*** simulation started *** +0 & 1 = 0 + +*** simulation started *** +out 11 new-value = true +out 11 new-value = false +1 & 0 = 0 + +*** simulation started *** +out 14 new-value = true +1 & 1 = 1 + +out 14 new-value = false + +*** simulation started *** +0 | 0 = 0 + +*** simulation started *** +out 24 new-value = true +0 | 1 = 1 + +*** simulation started *** +1 | 0 = 1 + +*** simulation started *** +1 | 1 = 1 + +sum 34 new-value = false +carry 34 new-value = false + +*** simulation started *** +0 + 0 = 0 + +*** simulation started *** +sum 47 new-value = true +0 + 1 = 1 + +*** simulation started *** +carry 50 new-value = true +carry 50 new-value = false +sum 54 new-value = false +sum 54 new-value = true +1 + 0 = 1 + +*** simulation started *** +carry 57 new-value = true +sum 61 new-value = false +1 + 1 = 2 + +sum 61 new-value = false +carry 61 new-value = false + +*** simulation started *** +0 + 0 + 0 = 0 + +*** simulation started *** +sum 82 new-value = true +0 + 0 + 1 = 1 + +*** simulation started *** +sum 89 new-value = false +carry 90 new-value = true +sum 97 new-value = true +carry 98 new-value = false +0 + 1 + 0 = 1 + +*** simulation started *** +sum 113 new-value = false +carry 114 new-value = true +0 + 1 + 1 = 2 + +*** simulation started *** +sum 121 new-value = true +carry 122 new-value = false +sum 129 new-value = false +sum 129 new-value = true +1 + 0 + 0 = 1 + +*** simulation started *** +carry 137 new-value = true +sum 144 new-value = false +1 + 0 + 1 = 2 + +*** simulation started *** +carry 152 new-value = false +sum 152 new-value = true +sum 158 new-value = false +carry 159 new-value = true +1 + 1 + 0 = 2 + +*** simulation started *** +sum 173 new-value = true +1 + 1 + 1 = 3 + +in 0 new-value = false +ctrl0 0 new-value = false +ctrl1 0 new-value = false +ctrl2 0 new-value = false +out0 0 new-value = false +out1 0 new-value = false +out2 0 new-value = false +out3 0 new-value = false +out4 0 new-value = false +out5 0 new-value = false +out6 0 new-value = false +out7 0 new-value = false +in 0 new-value = true +*** simulation started *** +out0 10 new-value = true +ctrl0 10 new-value = true +*** simulation started *** +out1 13 new-value = true +out0 14 new-value = false +ctrl1 14 new-value = true +*** simulation started *** +out3 20 new-value = true +out1 21 new-value = false +ctrl2 21 new-value = true +*** simulation started *** +out7 30 new-value = true +out3 31 new-value = false +ctrl0 31 new-value = false +*** simulation started *** +out7 34 new-value = false +out6 35 new-value = true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Course-2002-09.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Course-2002-09.check new file mode 100644 index 0000000000..c921361db7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Course-2002-09.check @@ -0,0 +1,50 @@ +Probe: f = 32 +Probe: c = 0 +Probe: f = ? +Probe: c = ? + +Probe: f = 212 +Probe: c = 100 +Probe: f = ? +Probe: c = ? + +Probe: c = 0 +Probe: f = 32 +Probe: c = ? +Probe: f = ? + +Probe: c = 100 +Probe: f = 212 +Probe: c = ? +Probe: f = ? + +0 Celsius -> 32 Fahrenheits +100 Celsius -> 212 Fahrenheits +32 Fahrenheits -> 0 Celsius +212 Fahrenheits -> 100 Celsius + +a = ?, b = ?, c = ? => ? * ? = ? +a = 2, b = ?, c = ? => 2 * ? = ? +a = ?, b = 3, c = ? => ? * 3 = ? +a = ?, b = ?, c = 6 => ? * ? = 6 +a = 2, b = 3, c = ? => 2 * 3 = 6 +a = 2, b = ?, c = 6 => 2 * 3 = 6 +a = ?, b = 3, c = 6 => 2 * 3 = 6 +a = 2, b = 3, c = 6 => 2 * 3 = 6 + +a = 0, b = ?, c = ? => 0 * ? = 0 +a = ?, b = 0, c = ? => ? * 0 = 0 +a = ?, b = ?, c = 0 => ? * ? = 0 +a = 0, b = 7, c = ? => 0 * 7 = 0 +a = 7, b = 0, c = ? => 7 * 0 = 0 +a = 0, b = 0, c = ? => 0 * 0 = 0 +a = 0, b = ?, c = 0 => 0 * ? = 0 +a = ?, b = 0, c = 0 => ? * 0 = 0 +a = 0, b = 7, c = 0 => 0 * 7 = 0 +a = 7, b = 0, c = 0 => 7 * 0 = 0 +a = 0, b = 0, c = 0 => 0 * 0 = 0 + +a = 3, b = 4 => c = 5 +a = 3, c = 5 => b = 4 +b = 4, c = 5 => a = 3 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Course-2002-10.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Course-2002-10.check new file mode 100644 index 0000000000..847f0fa703 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Course-2002-10.check @@ -0,0 +1,46 @@ +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +fib(10) = 55 +fib(11) = 89 +fib(12) = 144 +fib(13) = 233 +fib(14) = 377 +fib(15) = 610 +fib(16) = 987 +fib(17) = 1597 +fib(18) = 2584 +fib(19) = 4181 + +pi(0) = 4 , 3.166666666666667 , 4 +pi(1) = 2.666666666666667 , 3.1333333333333337, 3.166666666666667 +pi(2) = 3.466666666666667 , 3.1452380952380956, 3.142105263157895 +pi(3) = 2.8952380952380956, 3.1396825396825396, 3.1415993573190044 +pi(4) = 3.33968253968254 , 3.142712842712843 , 3.141592714033778 +pi(5) = 2.976046176046176 , 3.140881340881341 , 3.1415926539752923 +pi(6) = 3.283738483738484 , 3.142071817071817 , 3.141592653591176 +pi(7) = 3.017071817071817 , 3.1412548236077646, 3.141592653589777 +pi(8) = 3.252365934718876 , 3.1418396189294024, 3.141592653589794 +pi(9) = 3.0418396189294024, 3.141406718496502 , 3.1415926535897936 +pi = 3.141592653589793 , 3.141592653589793 , 3.141592653589793 + +ln(0) = 1 , 0.7 , 1 +ln(1) = 0.5 , 0.6904761904761905, 0.7 +ln(2) = 0.8333333333333333, 0.6944444444444444, 0.6932773109243697 +ln(3) = 0.5833333333333333, 0.6924242424242424, 0.6931488693329254 +ln(4) = 0.7833333333333333, 0.6935897435897436, 0.6931471960735491 +ln(5) = 0.6166666666666667, 0.6928571428571428, 0.6931471806635636 +ln(6) = 0.7595238095238095, 0.6933473389355742, 0.6931471805604038 +ln(7) = 0.6345238095238095, 0.6930033416875522, 0.6931471805599444 +ln(8) = 0.7456349206349207, 0.6932539682539682, 0.6931471805599426 +ln(9) = 0.6456349206349206, 0.6930657506744463, 0.6931471805599453 +ln = 0.6931471805599453, 0.6931471805599453, 0.6931471805599453 + +prime numbers: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Meter.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Meter.check new file mode 100644 index 0000000000..f46fd557c8 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/Meter.check @@ -0,0 +1,16 @@ +Meter.scala:72: warning: a.Meter and Int are unrelated: they will never compare equal + println("x == 1: "+(x == 1)) + ^ +2 +4m +false +x.isInstanceOf[Meter]: true +x.hashCode: 1 +x == 1: false +x == y: true +a == b: true +testing native arrays +Array(1m, 2m) +1m +>>>1m<<< 1m +>>>2m<<< 2m diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/MeterCaseClass.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/MeterCaseClass.check new file mode 100644 index 0000000000..ac538d240f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/MeterCaseClass.check @@ -0,0 +1,16 @@ +MeterCaseClass.scala:69: warning: comparing values of types a.Meter and Int using `==' will always yield false + println("x == 1: "+(x == 1)) + ^ +2 +Meter(4) +false +x.isInstanceOf[Meter]: true +x.hashCode: 1 +x == 1: false +x == y: true +a == b: true +testing native arrays +Array(Meter(1), Meter(2)) +Meter(1) +>>>Meter(1)<<< Meter(1) +>>>Meter(2)<<< Meter(2) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/anyval-box-types.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/anyval-box-types.check new file mode 100644 index 0000000000..b2d758c906 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/anyval-box-types.check @@ -0,0 +1,52 @@ +true +1 +true +1 +true +-1 +true +1 +true +false +true +true +false +false + +true +2 +true +2 +true +-1 +true +2 +true +false +false +false +false + +true +true +false +true +1 +true +true +true +false +false +false + +true +つ +false +true +true +true +つ +true +false +false +false diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/bugs.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/bugs.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/bugs.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/caseClassHash.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/caseClassHash.check new file mode 100644 index 0000000000..f975151e9c --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/caseClassHash.check @@ -0,0 +1,9 @@ +Foo(true,-1,-1,d,-5,-10,500,500,List(),5) +Foo(true,-1,-1,d,-5,-10,500,500,List(),5) +1383698062 +1383698062 +true +## method 1: 1383698062 +## method 2: 1383698062 + Murmur 1: 1383698062 + Murmur 2: 1383698062 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/deeps.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/deeps.check new file mode 100644 index 0000000000..e533b87dc5 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/deeps.check @@ -0,0 +1,87 @@ +testEquals1 +false +false +true + +testEquals2 +false +false +true + +testEquals3 +x=Array(1) +y=Array(1) +false +false +true + +x=Array(Array(1), Array(1)) +y=Array(Array(1), Array(1)) +false +false +true + +x=Array(Array(Array(1), Array(1)), Array(Array(1), Array(1))) +y=Array(Array(Array(1), Array(1)), Array(Array(1), Array(1))) +false +false +true + +testEquals4 +false +false +true +false +false +true +Array(true, false) +Array(true, false) +[true;false] +true;false + +Array(Array(true, false), Array(true, false)) +Array(Array(true, false), Array(true, false)) +[Array(true, false);Array(true, false)] +Array(true, false);Array(true, false) + +Array(Array(Array(true, false), Array(true, false)), Array(Array(true, false), Array(true, false))) +Array(Array(Array(true, false), Array(true, false)), Array(Array(true, false), Array(true, false))) +[Array(Array(true, false), Array(true, false));Array(Array(true, false), Array(true, false))] +Array(Array(true, false), Array(true, false));Array(Array(true, false), Array(true, false)) + +Array(1, 0) +Array(1, 0) +[1;0] +1;0 + +Array(Array(1, 0), Array(1, 0)) +Array(Array(1, 0), Array(1, 0)) +[Array(1, 0);Array(1, 0)] +Array(1, 0);Array(1, 0) + +Array(Array(Array(1, 0), Array(1, 0)), Array(Array(1, 0), Array(1, 0))) +Array(Array(Array(1, 0), Array(1, 0)), Array(Array(1, 0), Array(1, 0))) +[Array(Array(1, 0), Array(1, 0));Array(Array(1, 0), Array(1, 0))] +Array(Array(1, 0), Array(1, 0));Array(Array(1, 0), Array(1, 0)) + +Array(a, b) +Array(a, b) +[a;b] +a;b + +Array(Array(a, b), Array(a, b)) +Array(Array(a, b), Array(a, b)) +[Array(a, b);Array(a, b)] +Array(a, b);Array(a, b) + +Array(Array(Array(a, b), Array(a, b)), Array(Array(a, b), Array(a, b))) +Array(Array(Array(a, b), Array(a, b)), Array(Array(a, b), Array(a, b))) +[Array(Array(a, b), Array(a, b));Array(Array(a, b), Array(a, b))] +Array(Array(a, b), Array(a, b));Array(Array(a, b), Array(a, b)) + +[Array(true, false); Array(false)] +[Array(1, 2); Array(3)] +[Array(1, 2); Array(3)] + +Array(boo, and, foo) +Array(a) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/dynamic-anyval.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/dynamic-anyval.check new file mode 100644 index 0000000000..c125372c9a --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/dynamic-anyval.check @@ -0,0 +1,4 @@ +undefined.dingo(bippy, 5) +List(1, 2, 3).dingo(bippy, 5) +undefined.dingo(bippy, 5) +List(1, 2, 3).dingo(bippy, 5) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/impconvtimes.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/impconvtimes.check new file mode 100644 index 0000000000..082377e474 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/impconvtimes.check @@ -0,0 +1 @@ +3.0 * Hour = Measure(3,Hour) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/imports.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/imports.check new file mode 100644 index 0000000000..1aad598062 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/imports.check @@ -0,0 +1,21 @@ +In C_ico, v_ico .toString() returns ↩ +↪C_ico -> ok +In C_ico, field .toString() returns ↩ +↪C_ico -> ok +In C_ico, method.toString() returns ↩ +↪C_ico -> ok + +In C_ioc, v_ioc .toString() returns ↩ +↪C_ioc -> ok +In C_ioc, field .toString() returns ↩ +↪C_ioc -> ok +In C_ioc, method.toString() returns ↩ +↪C_ioc -> ok + +In C_oic, v_oic .toString() returns ↩ +↪C_oic -> ok +In C_oic, field .toString() returns ↩ +↪C_oic -> ok +In C_oic, method.toString() returns ↩ +↪C_oic -> ok + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/interpolation.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/interpolation.check new file mode 100644 index 0000000000..9c4a77715b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/interpolation.check @@ -0,0 +1,32 @@ +Bob is 1 years old +Bob is 1 years old +Bob will be 2 years old +Bob will be 2 years old +1+1 = 2 +1+1 = 2 +Bob is 12 years old +Bob is 12 years old +Bob will be 13 years old +Bob will be 13 years old +12+1 = 13 +12+1 = 13 +Bob is 123 years old +Bob is 123 years old +Bob will be 124 years old +Bob will be 124 years old +123+1 = 124 +123+1 = 124 +Best price: 10 +Best price: 10.00 +10% discount included +10.00% discount included +Best price: 13.345000267028809 +Best price: 13.35 +13.345000267028809% discount included +13.35% discount included + +0 +00 + +0 +00 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/interpolationMultiline1.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/interpolationMultiline1.check new file mode 100644 index 0000000000..1b6e140c13 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/interpolationMultiline1.check @@ -0,0 +1,26 @@ +Bob is 1 years old +Bob is 1 years old +Bob will be 2 years old +Bob will be 2 years old +1+1 = 2 +1+1 = 2 +Bob is 12 years old +Bob is 12 years old +Bob will be 13 years old +Bob will be 13 years old +12+1 = 13 +12+1 = 13 +Bob is 123 years old +Bob is 123 years old +Bob will be 124 years old +Bob will be 124 years old +123+1 = 124 +123+1 = 124 +Best price: 10 +Best price: 10.00 +10% discount included +10.00% discount included +Best price: 13.345000267028809 +Best price: 13.35 +13.345000267028809% discount included +13.35% discount included diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/issue192.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/issue192.sem new file mode 100644 index 0000000000..10abbf7f3b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/issue192.sem @@ -0,0 +1 @@ +strictFloats diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/macro-bundle-static.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/macro-bundle-static.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/macro-bundle-static.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/macro-bundle-toplevel.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/macro-bundle-toplevel.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/macro-bundle-toplevel.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/macro-bundle-whitebox-decl.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/macro-bundle-whitebox-decl.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/macro-bundle-whitebox-decl.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/misc.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/misc.check new file mode 100644 index 0000000000..85f37c51d7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/misc.check @@ -0,0 +1,62 @@ +misc.scala:46: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 42; + ^ +misc.scala:47: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 42l; + ^ +misc.scala:48: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 23.5f; + ^ +misc.scala:49: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 23.5; + ^ +misc.scala:50: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + "Hello"; + ^ +misc.scala:51: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 32 + 45; + ^ +misc.scala:62: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + x; + ^ +misc.scala:74: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 1 < 2; + ^ +### Hello +### 17 +### Bye + +### fib(0) = ↩ +↪1 +### fib(1) = ↩ +↪1 +### fib(2) = ↩ +↪2 +### fib(3) = ↩ +↪3 +### fib(4) = ↩ +↪5 +=== MyClass::toString === +=== MySubclass::toString === +=== MyClass::test === + +identity + +A.a = 1 +B.a = 5 +B.b = 2 + +X.a = 4 +Y.a = 11 +Y.b = 5 +Y.b = 5 + +X::foo + +Y::foo +X::foo + +3 +3 + +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/promotion.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/promotion.check new file mode 100644 index 0000000000..41e36c369d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/promotion.check @@ -0,0 +1,4 @@ +2 +6 +20 +30 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/runtime.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/runtime.check new file mode 100644 index 0000000000..0450b9498a --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/runtime.check @@ -0,0 +1,70 @@ +runtime.scala:141: warning: comparing values of types Null and Null using `eq' will always yield true + check(true , null eq null, null ne null); + ^ +runtime.scala:141: warning: comparing values of types Null and Null using `ne' will always yield false + check(true , null eq null, null ne null); + ^ +<<< Test0 +[false,true] +[0,1,2] +[3,4,5] +[a,b,c] +[6,7,8] +[9,10,11] +[12,13] +[14,15] +[string] +>>> Test0 + +<<< Test1 +10 +14 +15 +16 +20 +23 +24 +25 +26 +>>> Test1 + +<<< Test2 +A +M0 +N0 + +A +N0 +M0 + +A +M0 +M1 +N0 + +A +N0 +N1 +M0 + +>>> Test2 + +<<< Test3 +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +>>> Test3 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/spec-self.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/spec-self.check new file mode 100644 index 0000000000..fd3c81a4d7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/spec-self.check @@ -0,0 +1,2 @@ +5 +5 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/structural.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/structural.check new file mode 100644 index 0000000000..2fec112a87 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/structural.check @@ -0,0 +1,37 @@ + 1. hey + 2. 11 + 3. dee + 4. iei + 5. 6 + 6. 51 + 7. 2 + 8. 11 +10. 12 +11. eitch +12. 1 +13. ohone +14. 1 +15. undefined +16. one +17. tieone +18. 2 +19. true +20. 1 +21. undefined +22. one +23. oy +24. 1 +25. null +26. iei +31. 4 +32. undefined +33. iei +33. tieone +1 +2 +3 +4 +5 +caught +3 +2 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t0421-new.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t0421-new.check new file mode 100644 index 0000000000..00d29b7e5b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t0421-new.check @@ -0,0 +1,3 @@ +[Array(0, 1),Array(2, 3),Array(4, 5)] +[Array(31)] +[Array(24, 32)] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t0421-old.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t0421-old.check new file mode 100644 index 0000000000..00d29b7e5b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t0421-old.check @@ -0,0 +1,3 @@ +[Array(0, 1),Array(2, 3),Array(4, 5)] +[Array(31)] +[Array(24, 32)] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t1503.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t1503.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t1503.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t3702.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t3702.check new file mode 100644 index 0000000000..3fce98715c --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t3702.check @@ -0,0 +1,2 @@ +undefined +6 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t4148.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t4148.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t4148.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t4617.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t4617.check new file mode 100644 index 0000000000..a6790f16f7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t4617.check @@ -0,0 +1 @@ +Str 8 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t5356.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t5356.check new file mode 100644 index 0000000000..870c901131 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t5356.check @@ -0,0 +1,6 @@ +1 java.lang.Byte +1 java.lang.Byte +1 scala.math.BigInt +1 java.lang.Byte +1 java.lang.Byte +1 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t5552.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t5552.check new file mode 100644 index 0000000000..9e767b6d7b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t5552.check @@ -0,0 +1,6 @@ +lazy: 3 +(3,3) +(3,3) +lazy: 3 +(3,3) +(3,3) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t5568.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t5568.check new file mode 100644 index 0000000000..6f30cc5070 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t5568.check @@ -0,0 +1,9 @@ +void +int +class scala.runtime.BoxedUnit +class scala.runtime.BoxedUnit +class java.lang.Byte +class java.lang.Byte +5 +5 +5 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t5629b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t5629b.check new file mode 100644 index 0000000000..c65298a6ce --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t5629b.check @@ -0,0 +1,10 @@ +=== pf(1): +MySmartPF.apply entered... +newPF.applyOrElse entered... +default +scala.MatchError: 1 (of class java.lang.Byte) +=== pf(42): +MySmartPF.apply entered... +newPF.applyOrElse entered... +ok +=== done diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t5680.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t5680.check new file mode 100644 index 0000000000..a3b8b64a43 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t5680.check @@ -0,0 +1,3 @@ +[Lscala.runtime.BoxedUnit +undefined +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t5866.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t5866.check new file mode 100644 index 0000000000..64df1cec7f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t5866.check @@ -0,0 +1,2 @@ +0 +Foo(0) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t6318_primitives.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t6318_primitives.check new file mode 100644 index 0000000000..654ef1beec --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t6318_primitives.check @@ -0,0 +1,54 @@ +Checking if byte matches byte +Some(1) +Checking if byte matches short +Some(1) +Checking if class java.lang.Byte matches byte +Some(1) +Checking if short matches short +Some(1) +Checking if short matches char +None +Checking if class java.lang.Byte matches short +Some(1) +Checking if char matches char +Some() +Checking if char matches int +None +Checking if class java.lang.Character matches char +Some() +Checking if int matches int +Some(1) +Checking if int matches long +None +Checking if class java.lang.Byte matches int +Some(1) +Checking if long matches long +Some(1) +Checking if long matches float +None +Checking if class java.lang.Long matches long +Some(1) +Checking if float matches float +Some(1) +Checking if float matches double +Some(1) +Checking if class java.lang.Byte matches float +Some(1) +Checking if double matches double +Some(1) +Checking if double matches boolean +None +Checking if class java.lang.Byte matches double +Some(1) +Checking if boolean matches boolean +Some(true) +Checking if boolean matches void +None +Checking if class java.lang.Boolean matches boolean +Some(true) +Checking if void matches void +Some(undefined) +Checking if void matches byte +None +Checking if class scala.runtime.BoxedUnit matches void +Some(undefined) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t6662.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t6662.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t6662.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t7657.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t7657.check new file mode 100644 index 0000000000..1a87c1e866 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t7657.check @@ -0,0 +1,3 @@ +undefined +undefined +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t7763.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t7763.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t7763.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t8570a.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t8570a.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t8570a.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t8764.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t8764.check new file mode 100644 index 0000000000..121120217e --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t8764.check @@ -0,0 +1,5 @@ +IntOnly: should return an unboxed int +Int: int +IntAndDouble: should just box and return Anyval +Double: class java.lang.Byte +Int: class java.lang.Byte diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t9387b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t9387b.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t9387b.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t9656.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t9656.check new file mode 100644 index 0000000000..a16c04eaad --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/t9656.check @@ -0,0 +1,14 @@ +Range 1 to 10 +Range 1 to 10 +inexact Range 1 to 10 by 2 +Range 1 to 10 by 3 +inexact Range 1 until 10 by 2 +Range 100 to 100 +empty Range 100 until 100 +NumericRange 1 to 10 +NumericRange 1 to 10 by 2 +NumericRange 0.1 until 1 by 0.1 +NumericRange 0.1 until 1.0 by 0.1 +NumericRange 0.1 until 1 by 0.1 (using NumericRange 0.1 until 1 by 0.1 of BigDecimal) +NumericRange 0 days until 10 seconds by 1 second +empty NumericRange 0 days until 0 days by 1 second diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/try-catch-unify.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/try-catch-unify.check new file mode 100644 index 0000000000..813f01166d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/try-catch-unify.check @@ -0,0 +1,4 @@ +Failure(java.lang.NumberFormatException: For input string: "Hi") +Success(5) +O NOES +Failure(java.lang.NumberFormatException: For input string: "Hi") diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/virtpatmat_switch.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/virtpatmat_switch.check new file mode 100644 index 0000000000..0900a9ca32 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/virtpatmat_switch.check @@ -0,0 +1,7 @@ +zero +one +many +got a +got b +got some letter +scala.MatchError: 5 (of class java.lang.Byte) \ No newline at end of file diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/virtpatmat_typetag.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/virtpatmat_typetag.check new file mode 100644 index 0000000000..048c3aeed0 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.5/run/virtpatmat_typetag.check @@ -0,0 +1,10 @@ +1 is a Int +1 is a java.lang.Integer +1 is not a java.lang.String; it's a class java.lang.Byte +true is a Any +woele is a java.lang.String +1 is a Int +1 is a java.lang.Integer +1 is not a java.lang.String; it's a class java.lang.Byte +true is a Any +woele is a java.lang.String diff --git a/project/Build.scala b/project/Build.scala index f72c11c848..d48ecba5d6 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -64,7 +64,7 @@ object Build { CrossVersion.binaryMapped(v => s"sjs${previousSJSBinaryVersion}_$v") val scalaVersionsUsedForPublishing: Set[String] = - Set("2.10.7", "2.11.12", "2.12.4", "2.13.0-M2") + Set("2.10.7", "2.11.12", "2.12.5", "2.13.0-M2") val newScalaBinaryVersionsInThisRelease: Set[String] = Set() @@ -118,7 +118,7 @@ object Build { } val commonSettings = Seq( - scalaVersion := "2.11.12", + scalaVersion := "2.12.5", organization := "org.scala-js", version := scalaJSVersion, diff --git a/scala-test-suite/src/test/resources/2.12.5/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.12.5/BlacklistedTests.txt new file mode 100644 index 0000000000..9a7be17af0 --- /dev/null +++ b/scala-test-suite/src/test/resources/2.12.5/BlacklistedTests.txt @@ -0,0 +1,142 @@ +## Do not compile +scala/lang/annotations/BytecodeTest.scala +scala/lang/annotations/RunTest.scala +scala/lang/traits/BytecodeTest.scala +scala/lang/traits/RunTest.scala +scala/lang/primitives/NaNTest.scala +scala/lang/primitives/BoxUnboxTest.scala +scala/reflect/ClassOfTest.scala +scala/reflect/QTest.scala +scala/reflect/io/AbstractFileTest.scala +scala/reflect/io/ZipArchiveTest.scala +scala/reflect/internal/util/AbstractFileClassLoaderTest.scala +scala/reflect/internal/util/SourceFileTest.scala +scala/reflect/internal/util/StringOpsTest.scala +scala/reflect/internal/PrintersTest.scala +scala/reflect/internal/ScopeTest.scala +scala/reflect/internal/TreeGenTest.scala +scala/reflect/internal/TypesTest.scala +scala/reflect/internal/util/WeakHashSetTest.scala +scala/reflect/internal/MirrorsTest.scala +scala/reflect/internal/NamesTest.scala +scala/tools/nsc/backend/jvm/BTypesTest.scala +scala/tools/nsc/backend/jvm/BytecodeTest.scala +scala/tools/nsc/backend/jvm/DefaultMethodTest.scala +scala/tools/nsc/backend/jvm/DirectCompileTest.scala +scala/tools/nsc/backend/jvm/GenericSignaturesTest.scala +scala/tools/nsc/backend/jvm/IndyLambdaTest.scala +scala/tools/nsc/backend/jvm/IndySammyTest.scala +scala/tools/nsc/backend/jvm/InnerClassAttributeTest.scala +scala/tools/nsc/backend/jvm/NestedClassesCollectorTest.scala +scala/tools/nsc/backend/jvm/OptimizedBytecodeTest.scala +scala/tools/nsc/backend/jvm/PerRunInitTest.scala +scala/tools/nsc/backend/jvm/StringConcatTest.scala +scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala +scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala +scala/tools/nsc/backend/jvm/opt/AnalyzerTest.scala +scala/tools/nsc/backend/jvm/opt/BoxUnboxTest.scala +scala/tools/nsc/backend/jvm/opt/BTypesFromClassfileTest.scala +scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala +scala/tools/nsc/backend/jvm/opt/ClosureOptimizerTest.scala +scala/tools/nsc/backend/jvm/opt/CompactLocalVariablesTest.scala +scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala +scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala +scala/tools/nsc/backend/jvm/opt/InlineInfoTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerIllegalAccessTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerTest.scala +scala/tools/nsc/backend/jvm/opt/InlineSourceMatcherTest.scala +scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala +scala/tools/nsc/backend/jvm/opt/MethodLevelOptsTest.scala +scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala +scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala +scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala +scala/tools/nsc/backend/jvm/opt/UnusedLocalVariablesTest.scala +scala/tools/nsc/ScriptRunnerTest.scala +scala/tools/nsc/classpath/AggregateClassPathTest.scala +scala/tools/nsc/classpath/JrtClassPathTest.scala +scala/tools/nsc/classpath/MultiReleaseJarTest.scala +scala/tools/nsc/classpath/PathResolverBaseTest.scala +scala/tools/nsc/classpath/VirtualDirectoryClassPathTest.scala +scala/tools/nsc/classpath/ZipAndJarFileLookupFactoryTest.scala +scala/tools/nsc/doc/html/HtmlDocletTest.scala +scala/tools/nsc/interpreter/CompletionTest.scala +scala/tools/nsc/interpreter/ScriptedTest.scala +scala/tools/nsc/interpreter/TabulatorTest.scala +scala/tools/nsc/reporters/ConsoleReporterTest.scala +scala/tools/nsc/settings/ScalaVersionTest.scala +scala/tools/nsc/settings/SettingsTest.scala +scala/tools/nsc/symtab/CannotHaveAttrsTest.scala +scala/tools/nsc/symtab/FlagsTest.scala +scala/tools/nsc/symtab/FreshNameExtractorTest.scala +scala/tools/nsc/symtab/StdNamesTest.scala +scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala +scala/tools/nsc/symtab/SymbolTableTest.scala +scala/tools/nsc/transform/MixinTest.scala +scala/tools/nsc/transform/delambdafy/DelambdafyTest.scala +scala/tools/nsc/transform/patmat/SolvingTest.scala +scala/tools/nsc/transform/patmat/PatmatBytecodeTest.scala +scala/tools/nsc/typechecker/Implicits.scala +scala/tools/nsc/typechecker/TypedTreeTest.scala +scala/tools/nsc/util/StackTraceTest.scala +scala/tools/testing/BytecodeTesting.scala +scala/tools/testing/RunTesting.scala + +## Do not link +scala/MatchErrorSerializationTest.scala +scala/PartialFunctionSerializationTest.scala +scala/lang/stringinterpol/StringContextTest.scala +scala/collection/IteratorTest.scala +scala/collection/NewBuilderTest.scala +scala/collection/ParallelConsistencyTest.scala +scala/collection/SeqViewTest.scala +scala/collection/SetMapConsistencyTest.scala +scala/collection/concurrent/TrieMapTest.scala +scala/collection/convert/WrapperSerializationTest.scala +scala/collection/immutable/ListTest.scala +scala/collection/immutable/StreamTest.scala +scala/collection/immutable/StringLikeTest.scala +scala/collection/mutable/ArrayBufferTest.scala +scala/collection/mutable/MutableListTest.scala +scala/collection/mutable/OpenHashMapTest.scala +scala/collection/mutable/PriorityQueueTest.scala +scala/collection/parallel/TaskTest.scala +scala/collection/parallel/immutable/ParRangeTest.scala +scala/concurrent/FutureTest.scala +scala/concurrent/duration/SerializationTest.scala +scala/concurrent/impl/DefaultPromiseTest.scala +scala/io/SourceTest.scala +scala/runtime/ScalaRunTimeTest.scala +scala/sys/process/PipedProcessTest.scala +scala/sys/process/ProcessTest.scala +scala/tools/testing/AssertUtilTest.scala +scala/tools/testing/AssertThrowsTest.scala +scala/util/SpecVersionTest.scala +scala/util/SystemPropertiesTest.scala + +## Tests fail + +# Reflection +scala/reflect/ClassTagTest.scala + +# Regex +scala/util/matching/CharRegexTest.scala +scala/util/matching/RegexTest.scala + +# Require strict-floats +scala/math/BigDecimalTest.scala + +# Difference of getClass() on primitive values +scala/collection/immutable/RangeTest.scala + +# Test fails only some times with +# 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' +# and' 'set scalaJSUseRhino in Global := false' +scala/collection/immutable/PagedSeqTest.scala + +# Bugs +scala/collection/convert/MapWrapperTest.scala + +# Tests passed but are too slow (timeouts) +scala/collection/immutable/ListSetTest.scala +scala/util/SortingTest.scala diff --git a/scala-test-suite/src/test/resources/2.12.5/WhitelistedTests.txt b/scala-test-suite/src/test/resources/2.12.5/WhitelistedTests.txt new file mode 100644 index 0000000000..9f173d7628 --- /dev/null +++ b/scala-test-suite/src/test/resources/2.12.5/WhitelistedTests.txt @@ -0,0 +1,40 @@ +scala/collection/IndexedSeqOptimizedTest.scala +scala/collection/IndexedSeqTest.scala +scala/collection/IterableViewLikeTest.scala +scala/collection/LinearSeqOptimizedTest.scala +scala/collection/ReusableBuildersTest.scala +scala/collection/SearchingTest.scala +scala/collection/SeqLikeTest.scala +scala/collection/TraversableLikeTest.scala +scala/collection/TraversableOnceTest.scala +scala/collection/convert/NullSafetyToJavaTest.scala +scala/collection/convert/NullSafetyToScalaTest.scala +scala/collection/immutable/HashMapTest.scala +scala/collection/immutable/ListMapTest.scala +scala/collection/immutable/QueueTest.scala +scala/collection/immutable/RangeConsistencyTest.scala +scala/collection/immutable/SetTest.scala +scala/collection/immutable/TreeMapTest.scala +scala/collection/immutable/TreeSetTest.scala +scala/collection/immutable/VectorTest.scala +scala/collection/mutable/AnyRefMapTest.scala +scala/collection/mutable/ArraySortingTest.scala +scala/collection/mutable/BitSetTest.scala +scala/collection/mutable/HashMapTest.scala +scala/collection/mutable/LinkedHashMapTest.scala +scala/collection/mutable/LinkedHashSetTest.scala +scala/collection/mutable/SetLikeTest.scala +scala/collection/mutable/TreeMapTest.scala +scala/collection/mutable/TreeSetTest.scala +scala/collection/mutable/UnrolledBufferTest.scala +scala/collection/mutable/VectorTest.scala +scala/lang/primitives/PredefAutoboxingTest.scala +scala/math/BigIntTest.scala +scala/math/NumericTest.scala +scala/math/OrderingTest.scala +scala/runtime/ZippedTest.scala +scala/tools/testing/AssertUtil.scala +scala/tools/testing/TempDir.scala +scala/util/RandomTest.scala +scala/util/TryTest.scala +scala/util/control/ExceptionTest.scala diff --git a/scripts/assemble-cli.sh b/scripts/assemble-cli.sh index e4daf4e32f..a349cc0128 100755 --- a/scripts/assemble-cli.sh +++ b/scripts/assemble-cli.sh @@ -20,8 +20,8 @@ case $BINVER in BASEVER="2.11.12" ;; 2.12) - FULLVERS="2.12.0 2.12.1 2.12.2 2.12.3 2.12.4" - BASEVER="2.12.4" + FULLVERS="2.12.0 2.12.1 2.12.2 2.12.3 2.12.4 2.12.5" + BASEVER="2.12.5" ;; *) echo "Invalid Scala version $BINVER" >&2 diff --git a/scripts/publish.sh b/scripts/publish.sh index 42d8ec52b6..06d7359e74 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -7,11 +7,11 @@ else CMD="echo sbt" fi -FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.10.7 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.11.12 2.12.0 2.12.1 2.12.2 2.12.3 2.12.4 2.13.0-M2" -BIN_VERSIONS="2.10.7 2.11.12 2.12.4 2.13.0-M2" -CLI_VERSIONS="2.10.7 2.11.12 2.12.4" +FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.10.7 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.11.12 2.12.0 2.12.1 2.12.2 2.12.3 2.12.4 2.12.5 2.13.0-M2" +BIN_VERSIONS="2.10.7 2.11.12 2.12.5 2.13.0-M2" +CLI_VERSIONS="2.10.7 2.11.12 2.12.5" SBT_VERSION="2.10.7" -SBT1_VERSION="2.12.4" +SBT1_VERSION="2.12.5" SBT1_SBTVERSION="1.0.0" COMPILER="compiler jUnitPlugin" From 59e1e9e33234777a01f5d3eb5612225d4caecbdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 29 Mar 2018 23:08:17 +0200 Subject: [PATCH 0673/2665] Avoid `+0: Byte` because Scala 2.13.0-M3 does not like it. See https://github.com/scala/scala-dev/issues/465. --- .../javalib/math/BigIntegerConstructorsTest.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerConstructorsTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerConstructorsTest.scala index ec0fe90cc6..21065e1b6c 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerConstructorsTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerConstructorsTest.scala @@ -121,7 +121,7 @@ class BigIntegerConstructorsTest { } @Test def testConstructorBytesZero(): Unit = { - val aBytes = Array[Byte](0, 0, 0, -0, +0, 0, -0) + val aBytes = Array[Byte](0, 0, 0, -0, 0, 0, -0) val rBytes = Array[Byte](0) val aNumber = new BigInteger(aBytes) var resBytes = Array.ofDim[Byte](rBytes.length) @@ -350,7 +350,7 @@ class BigIntegerConstructorsTest { } @Test def testConstructorSignBytesZero1(): Unit = { - val aBytes = Array[Byte](-0, 0, +0, 0, 0, 0, 0) + val aBytes = Array[Byte](-0, 0, 0, 0, 0, 0, 0) val aSign = -1 val rBytes = Array[Byte](0) val aNumber = new BigInteger(aSign, aBytes) @@ -363,7 +363,7 @@ class BigIntegerConstructorsTest { } @Test def testConstructorSignBytesZero2(): Unit = { - val aBytes = Array[Byte](-0, 0, +0, 0, 0, 0, 0) + val aBytes = Array[Byte](-0, 0, 0, 0, 0, 0, 0) val aSign = 0 val rBytes = Array[Byte](0) val aNumber = new BigInteger(aSign, aBytes) @@ -376,7 +376,7 @@ class BigIntegerConstructorsTest { } @Test def testConstructorSignBytesZero3(): Unit = { - val aBytes = Array[Byte](-0, 0, +0, 0, 0, 0, 0) + val aBytes = Array[Byte](-0, 0, 0, 0, 0, 0, 0) val aSign = 1 val rBytes = Array[Byte](0) val aNumber = new BigInteger(aSign, aBytes) From a1787aa735d6078a29adef4abf517a4a48c87e25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 29 Mar 2018 23:21:33 +0200 Subject: [PATCH 0674/2665] Replace Scala 2.13.0-M2 by 2.13.0-M3. --- Jenkinsfile | 2 +- ci/checksizes.sh | 6 +- .../BlacklistedTests.txt | 24 ++- .../BuglistedTests.txt | 0 .../WhitelistedTests.txt | 149 ++++++++++++++++-- .../neg/t6446-additional.check | 0 .../neg/t6446-list.check | 0 .../neg/t6446-missing.check | 0 .../neg/t6446-show-phases.check | 0 .../neg/t7494-no-options.check | 0 .../run/Course-2002-01.check | 0 .../run/Course-2002-02.check | 0 .../run/Course-2002-04.check | 0 .../run/Course-2002-08.check | 0 .../run/Course-2002-09.check | 0 .../run/Course-2002-10.check | 0 .../{2.13.0-M2 => 2.13.0-M3}/run/Meter.check | 0 .../run/MeterCaseClass.check | 0 .../2.13.0-M3/run/anyval-box-types.check | 52 ++++++ .../{2.13.0-M2 => 2.13.0-M3}/run/bugs.sem | 0 .../run/caseClassHash.check | 0 .../{2.13.0-M2 => 2.13.0-M3}/run/deeps.check | 0 .../run/dynamic-anyval.check | 0 .../run/impconvtimes.check | 0 .../run/imports.check | 0 .../run/interpolation.check | 0 .../run/interpolationMultiline1.check | 0 .../{2.13.0-M2 => 2.13.0-M3}/run/issue192.sem | 0 .../run/macro-bundle-static.check | 0 .../run/macro-bundle-toplevel.check | 0 .../run/macro-bundle-whitebox-decl.check | 0 .../{2.13.0-M2 => 2.13.0-M3}/run/misc.check | 0 .../run/promotion.check | 0 .../run/runtime.check | 0 .../run/spec-self.check | 0 .../run/structural.check | 0 .../run/t0421-new.check | 0 .../run/t0421-old.check | 0 .../{2.13.0-M2 => 2.13.0-M3}/run/t1503.sem | 0 .../{2.13.0-M2 => 2.13.0-M3}/run/t3702.check | 0 .../{2.13.0-M2 => 2.13.0-M3}/run/t4148.sem | 0 .../{2.13.0-M2 => 2.13.0-M3}/run/t4617.check | 0 .../{2.13.0-M2 => 2.13.0-M3}/run/t5356.check | 0 .../{2.13.0-M2 => 2.13.0-M3}/run/t5552.check | 0 .../{2.13.0-M2 => 2.13.0-M3}/run/t5568.check | 0 .../{2.13.0-M2 => 2.13.0-M3}/run/t5629b.check | 0 .../{2.13.0-M2 => 2.13.0-M3}/run/t5680.check | 0 .../{2.13.0-M2 => 2.13.0-M3}/run/t5866.check | 0 .../run/t6318_primitives.check | 0 .../{2.13.0-M2 => 2.13.0-M3}/run/t6662.check | 0 .../{2.13.0-M2 => 2.13.0-M3}/run/t7657.check | 0 .../{2.13.0-M2 => 2.13.0-M3}/run/t7763.sem | 0 .../{2.13.0-M2 => 2.13.0-M3}/run/t8570a.check | 0 .../{2.13.0-M2 => 2.13.0-M3}/run/t8764.check | 0 .../{2.13.0-M2 => 2.13.0-M3}/run/t9387b.check | 0 .../{2.13.0-M2 => 2.13.0-M3}/run/t9656.check | 0 .../run/try-catch-unify.check | 0 .../run/virtpatmat_switch.check | 0 .../run/virtpatmat_typetag.check | 0 project/Build.scala | 6 +- .../BlacklistedTests.txt | 10 +- .../WhitelistedTests.txt | 1 + scripts/publish.sh | 4 +- 63 files changed, 221 insertions(+), 33 deletions(-) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/BlacklistedTests.txt (98%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/BuglistedTests.txt (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/WhitelistedTests.txt (95%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/neg/t6446-additional.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/neg/t6446-list.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/neg/t6446-missing.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/neg/t6446-show-phases.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/neg/t7494-no-options.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/Course-2002-01.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/Course-2002-02.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/Course-2002-04.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/Course-2002-08.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/Course-2002-09.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/Course-2002-10.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/Meter.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/MeterCaseClass.check (100%) create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/anyval-box-types.check rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/bugs.sem (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/caseClassHash.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/deeps.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/dynamic-anyval.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/impconvtimes.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/imports.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/interpolation.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/interpolationMultiline1.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/issue192.sem (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/macro-bundle-static.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/macro-bundle-toplevel.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/macro-bundle-whitebox-decl.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/misc.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/promotion.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/runtime.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/spec-self.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/structural.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/t0421-new.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/t0421-old.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/t1503.sem (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/t3702.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/t4148.sem (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/t4617.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/t5356.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/t5552.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/t5568.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/t5629b.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/t5680.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/t5866.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/t6318_primitives.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/t6662.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/t7657.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/t7763.sem (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/t8570a.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/t8764.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/t9387b.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/t9656.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/try-catch-unify.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/virtpatmat_switch.check (100%) rename partest-suite/src/test/resources/scala/tools/partest/scalajs/{2.13.0-M2 => 2.13.0-M3}/run/virtpatmat_typetag.check (100%) rename scala-test-suite/src/test/resources/{2.13.0-M2 => 2.13.0-M3}/BlacklistedTests.txt (95%) rename scala-test-suite/src/test/resources/{2.13.0-M2 => 2.13.0-M3}/WhitelistedTests.txt (97%) diff --git a/Jenkinsfile b/Jenkinsfile index 63fbf69c20..f8c4961760 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -389,7 +389,7 @@ def allJavaVersions = otherJavaVersions.clone() allJavaVersions << mainJavaVersion def mainScalaVersion = "2.12.5" -def mainScalaVersions = ["2.10.2", "2.11.12", "2.12.5", "2.13.0-M2"] +def mainScalaVersions = ["2.10.2", "2.11.12", "2.12.5", "2.13.0-M3"] def otherScalaVersions = [ "2.10.3", "2.10.4", diff --git a/ci/checksizes.sh b/ci/checksizes.sh index 69b7e38b46..423836b5bc 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -14,8 +14,8 @@ case $FULLVER in 2.12.5) VER=2.12 ;; - 2.13.0-M2) - VER=2.13.0-M2 + 2.13.0-M3) + VER=2.13.0-M3 ;; 2.10.3|2.10.4|2.10.5|2.10.6|2.10.7|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7|2.11.8|2.11.11|2.12.0|2.12.1|2.12.2|2.12.3|2.12.4) echo "Ignoring checksizes for Scala $FULLVER" @@ -54,7 +54,7 @@ case $FULLVER in REVERSI_PREOPT_GZ_EXPECTEDSIZE=76000 REVERSI_OPT_GZ_EXPECTEDSIZE=33000 ;; - 2.13.0-M2) + 2.13.0-M3) REVERSI_PREOPT_EXPECTEDSIZE=628000 REVERSI_OPT_EXPECTEDSIZE=147000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=77000 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/BlacklistedTests.txt similarity index 98% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/BlacklistedTests.txt rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/BlacklistedTests.txt index 7bc4157c8c..157b42eb1d 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/BlacklistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/BlacklistedTests.txt @@ -65,6 +65,8 @@ run/lambda-serialization-gc.scala run/t9390.scala run/t9390b.scala run/t9390c.scala +run/t10527.scala +run/t10650 run/trait-defaults-super.scala run/t2849.scala @@ -89,6 +91,7 @@ run/t6969.scala run/inner-obj-auto.scala run/predef-cycle.scala run/synchronized.scala +run/sd409.scala # Uses java.security run/t2318.scala @@ -143,6 +146,7 @@ run/lambda-serialization-security.scala run/t10232.scala run/t10233.scala run/t10244.scala +run/t10522.scala # Using System.getProperties @@ -152,6 +156,7 @@ run/t4426.scala run/t7336.scala run/t7775.scala +run/t10513.scala run/future-flatmap-exec-count.scala # Using detailed stack trace @@ -488,6 +493,7 @@ run/trait_fields_final.scala run/trait_fields_bytecode.scala run/trait_fields_volatile.scala run/junitForwarders +run/sip23-toolbox-eval.scala run/reify_newimpl_29.scala run/reify_magicsymbols.scala @@ -544,14 +550,12 @@ run/reify_nested_inner_refers_to_global.scala run/reify_newimpl_02.scala run/reify_newimpl_01.scala run/reify_fors_newpatmat.scala -run/reify_classfileann_a.scala run/reify_nested_outer_refers_to_local.scala run/reify_newimpl_13.scala run/reify_closure5a.scala run/reify_inner4.scala run/reify_sort.scala run/reify_ann1a.scala -run/reify_classfileann_b.scala run/reify_closure4a.scala run/reify_newimpl_33.scala run/reify_sort1.scala @@ -603,6 +607,9 @@ run/reify_renamed_type_spliceable.scala run/reify_typerefs_1a.scala run/reify_timeofday.scala run/reify_renamed_term_t5841.scala +run/reify_classfileann_a +run/reify_classfileann_b +run/reify_ann2b.scala run/t7521b.scala run/t8575b.scala @@ -891,12 +898,13 @@ run/t9097.scala run/macroPlugins-enterStats.scala run/sbt-icode-interface.scala run/t8502b.scala -run/t9437c run/repl-paste-parse.scala run/t5463.scala run/t8433.scala run/sd275.scala run/sd275-java +run/t10471.scala +run/t6130.scala # Using partest.StoreReporterDirectTest run/t10171 @@ -994,6 +1002,10 @@ run/t7936b run/t9937 run/t10368 run/t10334b +run/sd304 +run/t10450 +run/t10042 +run/t8348 # Using scala-script run/t7791-script-linenums.scala @@ -1024,6 +1036,12 @@ run/t3493.scala run/indy-via-macro run/indy-via-macro-with-dynamic-args +# Test the class name of LMF-generated lambdas +run/t7187.scala + +# Crashes our optimizer because of artificially insane amount of inlining +run/t10594.scala + ### Incorrect partests ### # Badly uses constract of Console.print (no flush) run/t429.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/BuglistedTests.txt similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/BuglistedTests.txt rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/BuglistedTests.txt diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/WhitelistedTests.txt similarity index 95% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/WhitelistedTests.txt rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/WhitelistedTests.txt index a2aa73a12a..4798d4d61b 100644 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/WhitelistedTests.txt +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/WhitelistedTests.txt @@ -939,14 +939,12 @@ neg/macro-qmarkqmarkqmark.scala neg/t4879.scala neg/t5956.scala neg/t4196.scala -neg/reify_ann2b.scala neg/t6666b.scala neg/warn-unused-privates.scala neg/t6928.scala neg/t6337.scala neg/sealed-java-enums.scala neg/t563.scala -neg/t900.scala neg/deadline-inf-illegal.scala neg/t766.scala neg/t5429.scala @@ -1020,7 +1018,6 @@ neg/t2866.scala neg/t8597b.scala neg/t5691.scala neg/t8534b.scala -neg/t5091.scala neg/literals.scala neg/t8534.scala neg/t8890.scala @@ -1030,7 +1027,6 @@ neg/t8291.scala neg/t8597.scala neg/t5639b neg/t6582_exhaust_big.scala -neg/t8841.scala neg/t9041.scala neg/t9093.scala neg/t7623.scala @@ -1560,7 +1556,6 @@ neg/constructor-init-order.scala neg/t6042.scala neg/t0590.scala neg/t4221.scala -neg/t6263.scala neg/t783.scala neg/t5554.scala neg/macro-invalidsig-params-badtype @@ -1892,7 +1887,6 @@ neg/t6902.scala neg/t6963a.scala neg/t3399.scala neg/t0015.scala -neg/t3995.scala neg/t276.scala neg/t6758.scala neg/t2441.scala @@ -1952,7 +1946,6 @@ neg/overloaded-unapply.scala neg/t1163.scala neg/wellkinded_bounds.scala neg/t7292-deprecation.scala -neg/t5044.scala neg/t0842.scala neg/t6436.scala neg/interop_typetags_arenot_classtags.scala @@ -1960,7 +1953,6 @@ neg/t3653.scala neg/higherkind_novalue.scala neg/t935.scala neg/t6040.scala -neg/annot-nonconst.scala neg/macro-deprecate-idents.scala neg/illegal-stmt-start.scala neg/t565.scala @@ -2249,7 +2241,6 @@ neg/t2206.scala neg/virtpatmat_unreach_select.scala neg/t6258.scala neg/t6815.scala -neg/not-possible-cause.scala neg/dbldef.scala neg/qualifying-class-error-1.scala neg/t835.scala @@ -2639,7 +2630,6 @@ run/t5612.scala run/t1110.scala run/t2636.scala run/verify-ctor.scala -run/t3647.scala run/t4560.scala run/t6632.scala run/richs.scala @@ -3014,10 +3004,7 @@ pos/t9393 pos/t9392 neg/missing-arg-list.scala neg/deprecated-target.scala -neg/t6895.scala -neg/beanInfoDeprecation.scala neg/t8777.scala -neg/t6895b.scala neg/t8892.scala neg/t8849.scala neg/inlineIndyLambdaPrivate @@ -3131,7 +3118,6 @@ pos/t2712-4.scala pos/t2712-1.scala pos/t2712-3.scala pos/t2712-6.scala -pos/t6895b.scala pos/t5683.scala pos/hkgadt.scala pos/t2712-7.scala @@ -3197,7 +3183,6 @@ neg/t9849.scala neg/trait_fields_var_override.scala neg/val_infer.scala neg/val_sig_infer_match.scala -neg/t7187.scala neg/trait_fields_deprecated_overriding.scala neg/t9847.scala neg/val_sig_infer_struct.scala @@ -3250,7 +3235,6 @@ neg/warn-unused-patvars.scala run/t10069.scala run/SD-290.scala run/sd329.scala -run/t10097.scala run/t10072.scala run/t10261 run/t9114.scala @@ -3333,6 +3317,138 @@ neg/t7046-2 neg/t7046 run/t7046-1 run/t7046-2 +pos/parallel-classloader.scala +pos/not-possible-cause.scala +pos/sip23-any.scala +pos/hk-existential-subtype.scala +pos/sip23-bounds.scala +pos/sip23-aliasing.scala +pos/any-vs-anyref.scala +pos/sip23-final.scala +pos/patmat-hk.scala +pos/sip23-folding.scala +pos/sip23-negative-literals.scala +pos/sip23-numeric-lub.scala +pos/sip23-no-widen.scala +pos/sip23-strings.scala +pos/sip23-override.scala +pos/sip23-singleton-sub.scala +pos/sip23-named-default.scala +pos/sip23-symbols.scala +pos/sip23-valueof-alias.scala +pos/sip23-valueof-covariance.scala +pos/sip23-singleton-conv.scala +pos/sip23-valueof-this.scala +pos/sip23-widen.scala +pos/t10088.scala +pos/t10195.scala +pos/t10185.scala +pos/sip23-narrow.scala +pos/sip23-narrow-no-empty-refinements.scala +pos/t10195b.scala +pos/t10238.scala +pos/t10197.scala +pos/t10372.scala +pos/t10159 +pos/t10213.scala +pos/t10296 +pos/t10288.scala +pos/t10296-before +pos/t10375.scala +pos/t10270 +pos/t10425.scala +pos/t10569.scala +pos/t10684.scala +pos/t3995.scala +pos/t10667.scala +pos/t4225b.scala +pos/t10528.scala +pos/t4225c.scala +pos/t5044.scala +pos/t5091.scala +pos/t4947.scala +pos/t5340.scala +pos/t5946.scala +pos/t4225.scala +pos/t5818.scala +pos/t8343.scala +pos/t6263.scala +pos/t8841.scala +pos/t900.scala +pos/t6895.scala +pos/t9122.scala +pos/t9291.scala +pos/warn-unused-params-not-implicits.scala +pos/t9647.scala +pos/t10568 +pos/t9220.scala +pos/t5638 +pos/t10387.scala +neg/names-defaults-neg-213.scala +neg/sip23-override.scala +neg/sip23-no-null-type.scala +neg/sip23-null.scala +neg/hk-typevar-unification.scala +neg/hk-existential-lb.scala +neg/sip23-uninitialized-0.scala +neg/annots-constant-neg +neg/sip23-symbols.scala +neg/sip23-uninitialized-2.scala +neg/sip23-tailrec.scala +neg/t10279.scala +neg/t10260 +neg/sip23-widen.scala +neg/names-defaults-neg-pu.scala +neg/sip23-uninitialized-1.scala +neg/t10530.scala +neg/sip23-uninitialized-3.scala +neg/t10545.scala +neg/t10661.scala +neg/t10678.scala +neg/t2712-8.scala +neg/t6934 +neg/t7187-2.13.scala +neg/t8237-default-pu.scala +neg/t8323.scala +neg/t9138.scala +neg/t10296-after +neg/t10270 +neg/t10296-warn +neg/t10296-both +neg/warn-useless-svuid.scala +run/literal-type-varargs.scala +run/implicit-caching.scala +run/abstype_implicits.scala +run/names-defaults-nest.scala +run/hk-typevar-unification.scala +run/sd455.scala +run/sd336.scala +run/sip23-initialization0.scala +run/sip23-cast-1.scala +run/sip23-implicit-resolution.scala +run/sip23-initialization1.scala +run/sip23-no-constant-folding.scala +run/sip23-macro-eval +run/sip23-rangepos.scala +run/sip23-singleton-isas.scala +run/sip23-patterns.scala +run/sip23-rec-constant.scala +run/sip23-type-equality.scala +run/t10283.scala +run/sip23-valueof.scala +run/sip23-widen2.scala +run/t10291.scala +run/t10423 +run/t10439.scala +run/t10545.scala +run/t10454-1 +run/t10454-2 +run/t10611.scala +run/t4225d.scala +run/t1980.scala +run/t4225e.scala +run/t7187-2.13.scala +run/t8564.scala # Adapt checkfiles for ().toString == "undefined" run/t5680.scala @@ -3362,3 +3478,4 @@ run/virtpatmat_typetag.scala run/virtpatmat_switch.scala run/t5629b.scala run/t5356.scala +run/anyval-box-types.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t6446-additional.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-additional.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t6446-additional.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-list.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t6446-list.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-list.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t6446-list.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t6446-missing.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-missing.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t6446-missing.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t6446-show-phases.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t6446-show-phases.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t6446-show-phases.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t7494-no-options.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/neg/t7494-no-options.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t7494-no-options.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Course-2002-01.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-01.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Course-2002-01.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-01.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Course-2002-02.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-02.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Course-2002-02.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-02.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Course-2002-04.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-04.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Course-2002-04.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-04.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Course-2002-08.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-08.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Course-2002-08.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-08.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Course-2002-09.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-09.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Course-2002-09.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-09.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Course-2002-10.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-10.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Course-2002-10.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-10.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Meter.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Meter.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/Meter.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Meter.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/MeterCaseClass.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/MeterCaseClass.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/MeterCaseClass.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/MeterCaseClass.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/anyval-box-types.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/anyval-box-types.check new file mode 100644 index 0000000000..b2d758c906 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/anyval-box-types.check @@ -0,0 +1,52 @@ +true +1 +true +1 +true +-1 +true +1 +true +false +true +true +false +false + +true +2 +true +2 +true +-1 +true +2 +true +false +false +false +false + +true +true +false +true +1 +true +true +true +false +false +false + +true +つ +false +true +true +true +つ +true +false +false +false diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/bugs.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/bugs.sem similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/bugs.sem rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/bugs.sem diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/caseClassHash.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/caseClassHash.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/caseClassHash.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/caseClassHash.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/deeps.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/deeps.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/deeps.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/deeps.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/dynamic-anyval.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/dynamic-anyval.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/dynamic-anyval.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/dynamic-anyval.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/impconvtimes.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/impconvtimes.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/impconvtimes.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/impconvtimes.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/imports.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/imports.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/imports.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/imports.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/interpolation.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/interpolation.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/interpolation.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/interpolation.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/interpolationMultiline1.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/interpolationMultiline1.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/interpolationMultiline1.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/interpolationMultiline1.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/issue192.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/issue192.sem similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/issue192.sem rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/issue192.sem diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/macro-bundle-static.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/macro-bundle-static.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/macro-bundle-static.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/macro-bundle-static.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/macro-bundle-toplevel.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/macro-bundle-toplevel.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/macro-bundle-toplevel.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/macro-bundle-toplevel.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/macro-bundle-whitebox-decl.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/macro-bundle-whitebox-decl.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/macro-bundle-whitebox-decl.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/macro-bundle-whitebox-decl.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/misc.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/misc.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/misc.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/misc.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/promotion.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/promotion.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/promotion.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/promotion.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/runtime.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/runtime.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/runtime.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/runtime.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/spec-self.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/spec-self.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/spec-self.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/spec-self.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/structural.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/structural.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/structural.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/structural.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t0421-new.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t0421-new.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t0421-new.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t0421-new.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t0421-old.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t0421-old.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t0421-old.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t0421-old.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t1503.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t1503.sem similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t1503.sem rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t1503.sem diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t3702.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t3702.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t3702.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t3702.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t4148.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t4148.sem similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t4148.sem rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t4148.sem diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t4617.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t4617.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t4617.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t4617.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t5356.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5356.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t5356.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5356.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t5552.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5552.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t5552.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5552.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t5568.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5568.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t5568.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5568.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t5629b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5629b.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t5629b.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5629b.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t5680.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5680.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t5680.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5680.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t5866.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5866.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t5866.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5866.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t6318_primitives.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t6318_primitives.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t6318_primitives.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t6318_primitives.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t6662.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t6662.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t6662.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t6662.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t7657.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t7657.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t7657.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t7657.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t7763.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t7763.sem similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t7763.sem rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t7763.sem diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t8570a.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t8570a.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t8570a.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t8570a.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t8764.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t8764.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t8764.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t8764.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t9387b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t9387b.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t9387b.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t9387b.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t9656.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t9656.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/t9656.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t9656.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/try-catch-unify.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/try-catch-unify.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/try-catch-unify.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/try-catch-unify.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/virtpatmat_switch.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/virtpatmat_switch.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/virtpatmat_switch.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/virtpatmat_switch.check diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/virtpatmat_typetag.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/virtpatmat_typetag.check similarity index 100% rename from partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M2/run/virtpatmat_typetag.check rename to partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/virtpatmat_typetag.check diff --git a/project/Build.scala b/project/Build.scala index d48ecba5d6..4848e9d6c3 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -64,7 +64,7 @@ object Build { CrossVersion.binaryMapped(v => s"sjs${previousSJSBinaryVersion}_$v") val scalaVersionsUsedForPublishing: Set[String] = - Set("2.10.7", "2.11.12", "2.12.5", "2.13.0-M2") + Set("2.10.7", "2.11.12", "2.12.5", "2.13.0-M3") val newScalaBinaryVersionsInThisRelease: Set[String] = Set() @@ -1454,7 +1454,7 @@ object Build { } val hasBugWithOverriddenMethods = - Set("2.12.0", "2.12.1", "2.12.2", "2.12.3", "2.12.4", "2.13.0-M2").contains(scalaV) + Set("2.12.0", "2.12.1", "2.12.2", "2.12.3", "2.12.4").contains(scalaV) if (hasBugWithOverriddenMethods) allSAMSources.filter(_.getName != "SAMWithOverridingBridgesTest.scala") @@ -1769,7 +1769,7 @@ object Build { else if (v.startsWith("2.11.")) "org.scala-lang.modules" %% "scala-partest" % "1.0.16" else - "org.scala-lang.modules" %% "scala-partest" % "1.1.1" + "org.scala-lang.modules" %% "scala-partest" % "1.1.4" }, "org.scala-js" % "closure-compiler-java-6" % "v20160517", "io.apigee" % "rhino" % "1.7R5pre4", diff --git a/scala-test-suite/src/test/resources/2.13.0-M2/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.13.0-M3/BlacklistedTests.txt similarity index 95% rename from scala-test-suite/src/test/resources/2.13.0-M2/BlacklistedTests.txt rename to scala-test-suite/src/test/resources/2.13.0-M3/BlacklistedTests.txt index ee24361b6f..d426215689 100644 --- a/scala-test-suite/src/test/resources/2.13.0-M2/BlacklistedTests.txt +++ b/scala-test-suite/src/test/resources/2.13.0-M3/BlacklistedTests.txt @@ -12,6 +12,7 @@ scala/reflect/io/ZipArchiveTest.scala scala/reflect/internal/util/AbstractFileClassLoaderTest.scala scala/reflect/internal/util/SourceFileTest.scala scala/reflect/internal/util/StringOpsTest.scala +scala/reflect/internal/Infer.scala scala/reflect/internal/PrintersTest.scala scala/reflect/internal/ScopeTest.scala scala/reflect/internal/TreeGenTest.scala @@ -29,11 +30,13 @@ scala/tools/nsc/backend/jvm/IndySammyTest.scala scala/tools/nsc/backend/jvm/InnerClassAttributeTest.scala scala/tools/nsc/backend/jvm/NestedClassesCollectorTest.scala scala/tools/nsc/backend/jvm/OptimizedBytecodeTest.scala +scala/tools/nsc/backend/jvm/PerRunInitTest.scala scala/tools/nsc/backend/jvm/StringConcatTest.scala scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala scala/tools/nsc/backend/jvm/opt/AnalyzerTest.scala scala/tools/nsc/backend/jvm/opt/BTypesFromClassfileTest.scala +scala/tools/nsc/backend/jvm/opt/BoxUnboxTest.scala scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala scala/tools/nsc/backend/jvm/opt/ClosureOptimizerTest.scala scala/tools/nsc/backend/jvm/opt/CompactLocalVariablesTest.scala @@ -55,6 +58,7 @@ scala/tools/nsc/classpath/AggregateClassPathTest.scala scala/tools/nsc/classpath/JrtClassPathTest.scala scala/tools/nsc/classpath/PathResolverBaseTest.scala scala/tools/nsc/classpath/VirtualDirectoryClassPathTest.scala +scala/tools/nsc/classpath/ZipAndJarFileLookupFactoryTest.scala scala/tools/nsc/doc/html/HtmlDocletTest.scala scala/tools/nsc/interpreter/CompletionTest.scala scala/tools/nsc/interpreter/ScriptedTest.scala @@ -94,6 +98,7 @@ scala/collection/mutable/ArrayBufferTest.scala scala/collection/mutable/MutableListTest.scala scala/collection/mutable/OpenHashMapTest.scala scala/collection/mutable/PriorityQueueTest.scala +scala/concurrent/FutureTest.scala scala/concurrent/duration/SerializationTest.scala scala/concurrent/impl/DefaultPromiseTest.scala scala/io/SourceTest.scala @@ -120,11 +125,6 @@ scala/math/BigDecimalTest.scala # Difference of getClass() on primitive values scala/collection/immutable/RangeTest.scala -# Test fails only some times with -# 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' -# and' 'set scalaJSUseRhino in Global := false' -scala/collection/immutable/PagedSeqTest.scala - # Bugs scala/collection/convert/MapWrapperTest.scala diff --git a/scala-test-suite/src/test/resources/2.13.0-M2/WhitelistedTests.txt b/scala-test-suite/src/test/resources/2.13.0-M3/WhitelistedTests.txt similarity index 97% rename from scala-test-suite/src/test/resources/2.13.0-M2/WhitelistedTests.txt rename to scala-test-suite/src/test/resources/2.13.0-M3/WhitelistedTests.txt index 0a693b4054..ff1cde1442 100644 --- a/scala-test-suite/src/test/resources/2.13.0-M2/WhitelistedTests.txt +++ b/scala-test-suite/src/test/resources/2.13.0-M3/WhitelistedTests.txt @@ -19,6 +19,7 @@ scala/collection/immutable/SetTest.scala scala/collection/immutable/TreeMapTest.scala scala/collection/immutable/TreeSetTest.scala scala/collection/immutable/VectorTest.scala +scala/collection/mutable/AnyRefMapTest.scala scala/collection/mutable/ArraySortingTest.scala scala/collection/mutable/BitSetTest.scala scala/collection/mutable/HashMapTest.scala diff --git a/scripts/publish.sh b/scripts/publish.sh index 06d7359e74..8b0131a8d8 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -7,8 +7,8 @@ else CMD="echo sbt" fi -FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.10.7 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.11.12 2.12.0 2.12.1 2.12.2 2.12.3 2.12.4 2.12.5 2.13.0-M2" -BIN_VERSIONS="2.10.7 2.11.12 2.12.5 2.13.0-M2" +FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.10.7 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.11.12 2.12.0 2.12.1 2.12.2 2.12.3 2.12.4 2.12.5 2.13.0-M3" +BIN_VERSIONS="2.10.7 2.11.12 2.12.5 2.13.0-M3" CLI_VERSIONS="2.10.7 2.11.12 2.12.5" SBT_VERSION="2.10.7" SBT1_VERSION="2.12.5" From 3050ac70416617602cc6e3ce1d8408c74963020a Mon Sep 17 00:00:00 2001 From: Martijn Hoekstra Date: Thu, 29 Mar 2018 17:30:17 +0200 Subject: [PATCH 0675/2665] Implement java.lang.Character.isSurrogate. --- .../src/main/scala/java/lang/Character.scala | 2 ++ .../javalib/lang/CharacterTestOnJDK7.scala | 28 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/javalanglib/src/main/scala/java/lang/Character.scala b/javalanglib/src/main/scala/java/lang/Character.scala index 50e56f0dd1..8503d518d3 100644 --- a/javalanglib/src/main/scala/java/lang/Character.scala +++ b/javalanglib/src/main/scala/java/lang/Character.scala @@ -314,6 +314,8 @@ object Character { (c & HighSurrogateMask) == HighSurrogateID @inline def isLowSurrogate(c: scala.Char): scala.Boolean = (c & LowSurrogateMask) == LowSurrogateID + @inline def isSurrogate(c: scala.Char): scala.Boolean = + isHighSurrogate(c) || isLowSurrogate(c) @inline def isSurrogatePair(high: scala.Char, low: scala.Char): scala.Boolean = isHighSurrogate(high) && isLowSurrogate(low) diff --git a/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/lang/CharacterTestOnJDK7.scala b/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/lang/CharacterTestOnJDK7.scala index 8c4560d882..2d5c7282bf 100644 --- a/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/lang/CharacterTestOnJDK7.scala +++ b/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/lang/CharacterTestOnJDK7.scala @@ -332,4 +332,32 @@ class CharacterTestOnJDK7 { assertFalse(Character.isIdeographic(958559)) assertFalse(Character.isIdeographic(999076)) } + + @Test + def shouldProvideIsSurrogate(): Unit = { + //non-surrogate + assertFalse(Character.isSurrogate((Character.MIN_SURROGATE - 1).toChar)) + assertFalse(Character.isSurrogate((Character.MAX_SURROGATE + 1).toChar)) + assertFalse(Character.isSurrogate('a')) + assertFalse(Character.isSurrogate('7')) + assertFalse(Character.isSurrogate('ö')) + assertFalse(Character.isSurrogate('\t')) + + //high surrogates + assertTrue(Character.isSurrogate(Character.MIN_SURROGATE)) + assertTrue(Character.isSurrogate('\uD800')) //min + assertTrue(Character.isSurrogate('\uDBFF')) //max + assertTrue(Character.isSurrogate('\uDAAA')) + assertTrue(Character.isSurrogate('\uD999')) + assertTrue(Character.isSurrogate('\uDBFE')) + + //low surrogates + assertTrue(Character.isSurrogate(Character.MAX_SURROGATE)) + assertTrue(Character.isSurrogate('\uDFFF')) //max + assertTrue(Character.isSurrogate('\uDC00')) //min + assertTrue(Character.isSurrogate('\uDDDD')) + assertTrue(Character.isSurrogate('\uDE99')) + assertTrue(Character.isSurrogate('\uDFFE')) + assertTrue(Character.isSurrogate('\uDC01')) + } } From f0f5af10604a0640bf6bdc30e63cbe78796c562c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 30 Mar 2018 11:53:54 +0200 Subject: [PATCH 0676/2665] Fix #3281: Backport the new `genConversion` from 1.x. Starting with Scala 2.13.0-M3, if the typer needs to *adapt* an `Int` to a `Long` inside a `match`, typically after overload resolution has taken place, we end up with a tree of the form `(x: Int).$asInstanceOf[Long]` in the back-end. This kind of node is handled by the `genConversion` method, which was previously buggy for the `Int`-to-`Long` conversion (among others). This commit backports the implementation of `genConversion` from master, which was rewritten in 9890ee769ee55adc0ef0514760d08e3fe3a3c2a0. We needed to adapt the code to rely on `TypeKind`s instead of `jstpe.Type`s, because in 0.6.x the latter do not know the difference between the various sub-`Int` types. --- .../org/scalajs/core/compiler/GenJSCode.scala | 69 +++++++++++++------ .../testsuite/compiler/RegressionTest.scala | 18 +++++ 2 files changed, 66 insertions(+), 21 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 364d70fb41..1b98c0ffa4 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -2687,29 +2687,56 @@ abstract class GenJSCode extends plugins.PluginComponent arguments)(resultType) } - /** Gen JS code for a conversion between primitive value types */ + /* This method corresponds to the method of the same name in + * BCodeBodyBuilder of the JVM back-end. It ends up calling the method + * BCodeIdiomatic.emitT2T, whose logic we replicate here. + */ def genConversion(from: TypeKind, to: TypeKind, value: js.Tree)( implicit pos: Position): js.Tree = { - def int0 = js.IntLiteral(0) - def int1 = js.IntLiteral(1) - def long0 = js.LongLiteral(0L) - def long1 = js.LongLiteral(1L) - def float0 = js.FloatLiteral(0.0f) - def float1 = js.FloatLiteral(1.0f) - - // scalastyle:off disallow.space.before.token - (from, to) match { - case (INT(_), BOOL) => js.BinaryOp(js.BinaryOp.Num_!=, value, int0) - case (LONG, BOOL) => js.BinaryOp(js.BinaryOp.Long_!=, value, long0) - case (FLOAT(_), BOOL) => js.BinaryOp(js.BinaryOp.Num_!=, value, float0) - - case (BOOL, INT(_)) => js.If(value, int1, int0 )(jstpe.IntType) - case (BOOL, LONG) => js.If(value, long1, long0 )(jstpe.LongType) - case (BOOL, FLOAT(_)) => js.If(value, float1, float0)(jstpe.FloatType) - - case _ => value - } - // scalastyle:on disallow.space.before.token + import js.UnaryOp._ + + if (from == to || from == NOTHING) { + value + } else if (from == BOOL || to == BOOL) { + throw new AssertionError(s"Invalid genConversion from $from to $to") + } else { + def intValue = (from: @unchecked) match { + case INT(_) => value + case LONG => js.UnaryOp(LongToInt, value) + case FLOAT(_) => js.UnaryOp(DoubleToInt, value) + } + + def doubleValue = from match { + case FLOAT(_) | INT(_) => value + case LONG => js.UnaryOp(LongToDouble, value) + } + + (to: @unchecked) match { + case CharKind => + js.BinaryOp(js.BinaryOp.Int_&, intValue, js.IntLiteral(0xffff)) + case ByteKind => + js.BinaryOp(js.BinaryOp.Int_>>, + js.BinaryOp(js.BinaryOp.Int_<<, intValue, js.IntLiteral(24)), + js.IntLiteral(24)) + case ShortKind => + js.BinaryOp(js.BinaryOp.Int_>>, + js.BinaryOp(js.BinaryOp.Int_<<, intValue, js.IntLiteral(24)), + js.IntLiteral(24)) + case IntKind => + intValue + case LongKind => + from match { + case FLOAT(_) => + js.UnaryOp(DoubleToLong, doubleValue) + case _ => + js.UnaryOp(IntToLong, intValue) + } + case FloatKind => + js.UnaryOp(js.UnaryOp.DoubleToFloat, doubleValue) + case DoubleKind => + doubleValue + } + } } /** Gen JS code for an isInstanceOf test (for reference types only) */ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala index 97c2ba4a6e..92dbee790d 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala @@ -748,6 +748,16 @@ class RegressionTest { assertEquals(107, new ParserWithHelpers().rec(3)) } + @Test def adaptedIntToLongInMatch_issue_3281(): Unit = { + import Bug3281._ + + val l: Any = 0 :: Nil + val r = overloaded(l match { + case x :: xs => 5 + }) + assertEquals(5L, r) + } + } object RegressionTest { @@ -798,4 +808,12 @@ object RegressionTest { } } } + + object Bug3281 { + def overloaded(x: Long): Any = + x + + def overloaded(x: Any): Unit = + fail("Bug3281.overloaded(x: Any) was called") + } } From 290952995dc9ae0a11d77e762e713848a7d43a03 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 30 Mar 2018 15:30:46 +0200 Subject: [PATCH 0677/2665] Remove unused VirtualFile#exists --- io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala | 3 --- io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala | 2 -- io/shared/src/main/scala/org/scalajs/io/MemFiles.scala | 2 -- io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala | 3 --- .../scala/org/scalajs/linker/backend/emitter/CoreJSLibs.scala | 1 - .../src/main/scala/org/scalajs/linker/irio/IRFileCache.scala | 4 ---- 6 files changed, 15 deletions(-) diff --git a/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala b/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala index e5edfd9847..19f772da29 100644 --- a/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala +++ b/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala @@ -17,9 +17,6 @@ class NodeVirtualFile(override val path: String) extends VirtualFile { Some(stat.mtime.asInstanceOf[js.Date].getTime.toString) } - override def exists: Boolean = - fs.existsSync(path).asInstanceOf[Boolean] - override def toURI: URI = { val abspath = fs.realpathSync(path).asInstanceOf[String] new URI("file", abspath, null) diff --git a/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala b/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala index 0c459e3cbf..ccf17693aa 100644 --- a/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala +++ b/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala @@ -16,8 +16,6 @@ class FileVirtualFile(val file: File) extends VirtualFile { else Some(file.lastModified.toString) } - override def exists: Boolean = file.exists - override def toURI: URI = file.toURI } diff --git a/io/shared/src/main/scala/org/scalajs/io/MemFiles.scala b/io/shared/src/main/scala/org/scalajs/io/MemFiles.scala index 8cc2398540..d539dcc211 100644 --- a/io/shared/src/main/scala/org/scalajs/io/MemFiles.scala +++ b/io/shared/src/main/scala/org/scalajs/io/MemFiles.scala @@ -22,8 +22,6 @@ class MemVirtualFile(val path: String) extends VirtualFile { version = v this } - - override def exists: Boolean = true } /** A simple in-memory mutable virtual text file. */ diff --git a/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala b/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala index c2707c7cec..a09c4c1cfe 100644 --- a/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala +++ b/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala @@ -24,9 +24,6 @@ trait VirtualFile { */ def version: Option[String] = None - /** Whether this file exists. Reading a non-existent file may fail */ - def exists: Boolean - /** URI for this virtual file */ def toURI: URI = { new URI( diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLibs.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLibs.scala index dc45f32484..30e2a5e4cd 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLibs.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLibs.scala @@ -130,7 +130,6 @@ private[emitter] object CoreJSLibs { private class ScalaJSEnvVirtualJSFile(override val content: String) extends VirtualJSFile { override def path: String = "scalajsenv.js" override def version: Option[String] = Some("") - override def exists: Boolean = true override def toURI: URI = { if (!ScalaJSVersions.currentIsSnapshot) diff --git a/linker/shared/src/main/scala/org/scalajs/linker/irio/IRFileCache.scala b/linker/shared/src/main/scala/org/scalajs/linker/irio/IRFileCache.scala index f2c0d068db..16c918468e 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/irio/IRFileCache.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/irio/IRFileCache.scala @@ -237,10 +237,6 @@ final class IRFileCache { override val entryPointsInfo: EntryPointsInfo = _irFile.entryPointsInfo override val relativePath: String = _irFile.relativePath - override def exists: Boolean = { - _tree != null || _irFile.exists - } - override def tree: ClassDef = { if (_tree == null) { synchronized { From 7d54f98a0bbaf9d46697392591a46e4e05202863 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 26 Oct 2017 16:58:34 +0200 Subject: [PATCH 0678/2665] Factor out some code inside `mkOverloadSelection`. This reduces code duplication, while making the code more generic and less dependent on the precise shape of trees that are received. (cherry picked from commit 645fa78179665d3b6279a9391b9cc8c5d4686d40) --- .../org/scalajs/core/compiler/GenJSCode.scala | 79 +++++++++---------- 1 file changed, 36 insertions(+), 43 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 364d70fb41..a8854c112e 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -1260,28 +1260,32 @@ abstract class GenJSCode extends plugins.PluginComponent */ private def mkOverloadSelection(jsConstructorBuilder: JSConstructorBuilder, overloadIdent: js.Ident, dispatchResolution: js.Tree)( - implicit pos: Position): List[js.Tree]= { + implicit pos: Position): List[js.Tree] = { + + def deconstructApplyCtor(body: js.Tree): (List[js.Tree], String, List[js.Tree]) = { + val (prepStats, applyCtor) = body match { + case applyCtor: js.ApplyStatic => + (Nil, applyCtor) + case js.Block(prepStats :+ (applyCtor: js.ApplyStatic)) => + (prepStats, applyCtor) + } + val js.ApplyStatic(_, js.Ident(ctorName, _), js.This() :: ctorArgs) = + applyCtor + assert(ir.Definitions.isConstructorName(ctorName)) + (prepStats, ctorName, ctorArgs) + } + if (!jsConstructorBuilder.hasSubConstructors) { - dispatchResolution match { - /* Dispatch to constructor with no arguments. - * Contains trivial parameterless call to the constructor. - */ - case js.ApplyStatic(_, mtd, js.This() :: Nil) - if ir.Definitions.isConstructorName(mtd.name) => - Nil + val (prepStats, ctorName, ctorArgs) = + deconstructApplyCtor(dispatchResolution) - /* Dispatch to constructor with at least one argument. - * Where js.Block's stats.init corresponds to the parameter casts and - * js.Block's stats.last contains the call to the constructor. - */ - case js.Block(stats) => - val js.ApplyStatic(_, method, _) = stats.last - val refs = jsConstructorBuilder.getParamRefsFor(method.name) - val paramCasts = stats.init.map(_.asInstanceOf[js.VarDef]) - zipMap(refs, paramCasts) { (ref, paramCast) => - js.VarDef(ref.ident, ref.tpe, mutable = false, paramCast.rhs) - } + val refs = jsConstructorBuilder.getParamRefsFor(ctorName) + assert(refs.size == ctorArgs.size, currentClassSym.fullName) + val assignCtorParams = zipMap(refs, ctorArgs) { (ref, ctorArg) => + js.VarDef(ref.ident, ref.tpe, mutable = false, ctorArg) } + + prepStats ::: assignCtorParams } else { val overloadRef = js.VarRef(overloadIdent)(jstpe.IntType) @@ -1289,30 +1293,6 @@ abstract class GenJSCode extends plugins.PluginComponent * `genJSConstructorExport` and transform it recursively. */ def transformDispatch(tree: js.Tree): js.Tree = tree match { - /* Dispatch to constructor with no arguments. - * Contains trivial parameterless call to the constructor. - */ - case js.ApplyStatic(_, method, js.This() :: Nil) - if ir.Definitions.isConstructorName(method.name) => - js.Assign(overloadRef, - js.IntLiteral(jsConstructorBuilder.getOverrideNum(method.name))) - - /* Dispatch to constructor with at least one argument. - * Where js.Block's stats.init corresponds to the parameter casts and - * js.Block's stats.last contains the call to the constructor. - */ - case js.Block(stats) => - val js.ApplyStatic(_, method, _) = stats.last - - val num = jsConstructorBuilder.getOverrideNum(method.name) - val overloadAssign = js.Assign(overloadRef, js.IntLiteral(num)) - - val refs = jsConstructorBuilder.getParamRefsFor(method.name) - val paramCasts = stats.init.map(_.asInstanceOf[js.VarDef].rhs) - val parameterAssigns = zipMap(refs, paramCasts)(js.Assign(_, _)) - - js.Block(overloadAssign :: parameterAssigns) - // Parameter count resolution case js.Match(selector, cases, default) => val newCases = cases.map { @@ -1329,6 +1309,19 @@ abstract class GenJSCode extends plugins.PluginComponent // Throw(StringLiteral(No matching overload)) case tree: js.Throw => tree + + // Overload resolution done, apply the constructor + case _ => + val (prepStats, ctorName, ctorArgs) = deconstructApplyCtor(tree) + + val num = jsConstructorBuilder.getOverrideNum(ctorName) + val overloadAssign = js.Assign(overloadRef, js.IntLiteral(num)) + + val refs = jsConstructorBuilder.getParamRefsFor(ctorName) + assert(refs.size == ctorArgs.size, currentClassSym.fullName) + val assignCtorParams = zipMap(refs, ctorArgs)(js.Assign(_, _)) + + js.Block(overloadAssign :: prepStats ::: assignCtorParams) } val newDispatchResolution = transformDispatch(dispatchResolution) From 1974810ba16a467370145d5247583b0cf998606c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 30 Mar 2018 16:38:53 +0200 Subject: [PATCH 0679/2665] Fix #3285: Test multi-param lists with defaults in JS class ctor. The bug was actually fixed by chance in 645fa78179665d3b6279a9391b9cc8c5d4686d40, which we cherry-picked as the parent commit of this commit. --- .../testsuite/jsinterop/ScalaJSDefinedTest.scala | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala index 64267a016f..47e18328d6 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala @@ -1090,6 +1090,18 @@ class ScalaJSDefinedTest { assertEquals(5, new ConstructorDefaultParamScalaNone(5).foo) } + @Test def constructors_with_default_parameters_in_multi_param_lists(): Unit = { + val foo1 = new ConstructorDefaultParamMultiParamList(5)("foobar") + assertEquals(5, foo1.default) + assertEquals("foobar", foo1.title) + assertEquals("5", foo1.description) + + val foo2 = new ConstructorDefaultParamMultiParamList(56)("babar", "desc") + assertEquals(56, foo2.default) + assertEquals("babar", foo2.title) + assertEquals("desc", foo2.description) + } + @Test def `call_super_constructor_with_:__*`(): Unit = { class CallSuperCtorWithSpread(x: Int, y: Int, z: Int) extends NativeParentClassWithVarargs(x, Seq(y, z): _*) @@ -1731,6 +1743,10 @@ object ScalaJSDefinedTest { // sanity check class ConstructorDefaultParamScalaNone(val foo: Int = -1) + class ConstructorDefaultParamMultiParamList(val default: Int)( + val title: String, val description: js.UndefOr[String] = default.toString) + extends js.Object + class OverloadedConstructorParamNumber(val foo: Int) extends js.Object { def this(x: Int, y: Int) = this(x + y) def this(x: Int, y: Int, z: Int) = this(x + y, z) From dacbcd58e6960d2b25c531666336e1ac459b129f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 30 Mar 2018 17:26:53 +0200 Subject: [PATCH 0680/2665] Add tests for overloaded JS class constructors with default params. In particular, add an explicit check for an implementation restriction: a secondary constructor calling another one must supply all the parameters, even ones with default values. The cost/benefit of adding support for this case seems too high. --- .../org/scalajs/core/compiler/GenJSCode.scala | 37 ++++++++++++++++++- .../compiler/test/ScalaJSDefinedTest.scala | 14 +++++++ .../jsinterop/ScalaJSDefinedTest.scala | 32 ++++++++++++++++ 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index a8854c112e..1e9e7d66c0 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -1170,6 +1170,37 @@ abstract class GenJSCode extends plugins.PluginComponent mkSubPreCalls(constructorTree, overrideNumRef) val preSuperCall = { + def checkForUndefinedParams(args: List[js.Tree]): List[js.Tree] = { + if (!args.exists(_.isInstanceOf[js.UndefinedParam])) { + args + } else { + /* If we find an undefined param here, we're in trouble, because + * the handling of a default param for the target constructor has + * already been done during overload resolution. If we store an + * `undefined` now, it will fall through without being properly + * processed. + * + * Since this seems very tricky to deal with, and a pretty rare + * use case (with a workaround), we emit an "implementation + * restriction" error. + */ + reporter.error(pos, + "Implementation restriction: in a JS class, a secondary " + + "constructor calling another constructor with default " + + "parameters must provide the values of all parameters.") + + /* Replace undefined params by undefined to prevent subsequent + * compiler crashes. + */ + args.map { + case arg: js.UndefinedParam => + js.Undefined()(arg.pos) + case arg => + arg + } + } + } + constructorTree.method.body.get match { case js.Block(stats) => val beforeSuperCall = stats.takeWhile { @@ -1179,14 +1210,16 @@ abstract class GenJSCode extends plugins.PluginComponent val superCallParams = stats.collectFirst { case js.ApplyStatic(_, mtd, js.This() :: args) if ir.Definitions.isConstructorName(mtd.name) => - zipMap(outputParams, args)(js.Assign(_, _)) + val checkedArgs = checkForUndefinedParams(args) + zipMap(outputParams, checkedArgs)(js.Assign(_, _)) }.getOrElse(Nil) beforeSuperCall ::: superCallParams case js.ApplyStatic(_, mtd, js.This() :: args) if ir.Definitions.isConstructorName(mtd.name) => - zipMap(outputParams, args)(js.Assign(_, _)) + val checkedArgs = checkForUndefinedParams(args) + zipMap(outputParams, checkedArgs)(js.Assign(_, _)) case _ => Nil } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala index e2943ba5c3..a16ee23f52 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala @@ -665,4 +665,18 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { """ } + @Test + def noCallOtherConstructorsWithLeftOutDefaultParams: Unit = { + """ + class A(x: Int, y: String = "default") extends js.Object { + def this() = this(12) + } + """ hasErrors + """ + |newSource1.scala:5: error: Implementation restriction: in a JS class, a secondary constructor calling another constructor with default parameters must provide the values of all parameters. + | class A(x: Int, y: String = "default") extends js.Object { + | ^ + """ + } + } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala index 47e18328d6..c07fa0370a 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala @@ -1102,6 +1102,30 @@ class ScalaJSDefinedTest { assertEquals("desc", foo2.description) } + @Test def constructors_with_default_parameters_in_multi_param_lists_and_overloading(): Unit = { + val foo1 = new ConstructorDefaultParamMultiParamListWithOverloading(5)( + "foobar") + assertEquals(5, foo1.default) + assertEquals("foobar", foo1.title) + assertEquals("5", foo1.description) + + val foo2 = new ConstructorDefaultParamMultiParamListWithOverloading(56)( + "babar", "desc") + assertEquals(56, foo2.default) + assertEquals("babar", foo2.title) + assertEquals("desc", foo2.description) + + val foo3 = new ConstructorDefaultParamMultiParamListWithOverloading('A') + assertEquals(65, foo3.default) + assertEquals("char", foo3.title) + assertEquals("a char", foo3.description) + + val foo4 = new ConstructorDefaultParamMultiParamListWithOverloading(123, 456) + assertEquals(123, foo4.default) + assertEquals("456", foo4.title) + assertEquals(js.undefined, foo4.description) + } + @Test def `call_super_constructor_with_:__*`(): Unit = { class CallSuperCtorWithSpread(x: Int, y: Int, z: Int) extends NativeParentClassWithVarargs(x, Seq(y, z): _*) @@ -1747,6 +1771,14 @@ object ScalaJSDefinedTest { val title: String, val description: js.UndefOr[String] = default.toString) extends js.Object + class ConstructorDefaultParamMultiParamListWithOverloading(val default: Int)( + val title: String, val description: js.UndefOr[String] = default.toString) + extends js.Object { + def this(c: Char) = this(c.toInt)("char", "a char") + + def this(x: Int, y: Int) = this(x)(y.toString, js.undefined) + } + class OverloadedConstructorParamNumber(val foo: Int) extends js.Object { def this(x: Int, y: Int) = this(x + y) def this(x: Int, y: Int, z: Int) = this(x + y, z) From c1083f3a011ba2bda62c9ab7860a849acd0494a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 30 Mar 2018 13:36:53 +0200 Subject: [PATCH 0681/2665] Fix #3227: Disable reflective instantiation for local classes. We make sure that reflective instantiation for inner classes is supported, though. Only local classes (inside `def`s) are excluded from the reflective instantiation support. --- .../core/compiler/Compat210Component.scala | 7 +++ .../org/scalajs/core/compiler/GenJSCode.scala | 2 + .../scala/scala/scalajs/reflect/Reflect.scala | 8 +-- .../testsuite/library/ReflectTest.scala | 49 +++++++++++++++++++ 4 files changed, 63 insertions(+), 3 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala b/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala index 7335319b9b..a303f8e1aa 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala @@ -31,6 +31,9 @@ trait Compat210Component { def isPrivateThis: Boolean = self.hasAllFlags(PRIVATE | LOCAL) def isLocalToBlock: Boolean = self.isLocal + def originalOwner: Symbol = + global.originalOwner.getOrElse(self, self.rawowner) + def implClass: Symbol = NoSymbol def isTraitOrInterface: Boolean = self.isTrait || self.isInterface @@ -49,6 +52,10 @@ trait Compat210Component { implicit final class GlobalCompat( self: Compat210Component.this.global.type) { + object originalOwner { + def getOrElse(sym: Symbol, orElse: => Symbol): Symbol = infiniteLoop() + } + def enteringPhase[T](ph: Phase)(op: => T): T = self.beforePhase(ph)(op) def beforePhase[T](ph: Phase)(op: => T): T = infiniteLoop() diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 364d70fb41..a66c93f7c6 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -959,6 +959,8 @@ abstract class GenJSCode extends plugins.PluginComponent genRegisterReflectiveInstantiationForModuleClass(sym) else if (sym.isModuleClass) None // #3228 + else if (sym.isLifted && !sym.originalOwner.isClass) + None // #3227 else genRegisterReflectiveInstantiationForNormalClass(sym) } diff --git a/library/src/main/scala/scala/scalajs/reflect/Reflect.scala b/library/src/main/scala/scala/scalajs/reflect/Reflect.scala index 45b9c00f09..4001d66e5e 100644 --- a/library/src/main/scala/scala/scalajs/reflect/Reflect.scala +++ b/library/src/main/scala/scala/scalajs/reflect/Reflect.scala @@ -118,11 +118,13 @@ object Reflect { * The class or one of its super types (classes or traits) must be annotated * with * [[scala.scalajs.reflect.annotation.EnableReflectiveInstantiation @EnableReflectiveInstantiation]]. - * Moreover, the class must not be abstract. + * Moreover, the class must not be abstract, nor be a local class (i.e., a + * class defined inside a `def`). Inner classes (defined inside another + * class) are supported. * * If the class cannot be found, either because it does not exist, - * was not `@EnableReflectiveInstantiation` or was abstract, this method - * returns `None`. + * was not `@EnableReflectiveInstantiation` or was abstract or local, this + * method returns `None`. * * @param fqcn * Fully-qualified name of the class diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ReflectTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ReflectTest.scala index 91190dcc3a..6063bd677a 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ReflectTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ReflectTest.scala @@ -35,6 +35,11 @@ class ReflectTest { private final val NameClassNoPublicConstructorEnableDirect = Prefix + "ClassNoPublicConstructorEnableDirect" + private final val NameInnerClass = { + Prefix + "ClassWithInnerClassWithEnableReflectiveInstantiation$" + + "InnerClassWithEnableReflectiveInstantiation" + } + private final val NameClassEnableIndirect = Prefix + "ClassEnableIndirect" private final val NameClassEnableIndirectNoZeroArgCtor = @@ -180,6 +185,33 @@ class ReflectTest { } } + @Test def testInnerClass(): Unit = { + import ReflectTest.ClassWithInnerClassWithEnableReflectiveInstantiation + + val outer = new ClassWithInnerClassWithEnableReflectiveInstantiation(15) + + val optClassData = Reflect.lookupInstantiatableClass(NameInnerClass) + assertTrue(optClassData.isDefined) + val classData = optClassData.get + + val optCtorOuterString = + classData.getConstructor(outer.getClass, classOf[String]) + assertTrue(optCtorOuterString.isDefined) + val instanceOuterString = + optCtorOuterString.get.newInstance(outer, "babar").asInstanceOf[Accessors] + assertEquals(15, instanceOuterString.x) + assertEquals("babar", instanceOuterString.y) + } + + @Test def testLocalClass(): Unit = { + @EnableReflectiveInstantiation + class LocalClassWithEnableReflectiveInstantiation + + val fqcn = classOf[LocalClassWithEnableReflectiveInstantiation].getName + assertFalse(s"$fqcn should not be found", + Reflect.lookupInstantiatableClass(fqcn).isDefined) + } + @Test def testObjectLoad(): Unit = { for (name <- Seq(NameObjectEnableDirect, NameObjectEnableIndirect)) { val optClassData = Reflect.lookupLoadableModuleClass(name) @@ -197,6 +229,14 @@ class ReflectTest { assertFalse(Reflect.lookupInstantiatableClass(NameInnerObject).isDefined) } + @Test def testLocalClassWithReflectiveInstantiationInLambda_issue_3227(): Unit = { + // Test that the presence of the following code does not prevent linking + { () => + @EnableReflectiveInstantiation + class Foo + } + } + } object ReflectTest { @@ -257,6 +297,15 @@ object ReflectTest { protected def this(y: String) = this(-5, y) } + class ClassWithInnerClassWithEnableReflectiveInstantiation(_x: Int) { + @EnableReflectiveInstantiation + class InnerClassWithEnableReflectiveInstantiation(_y: String) + extends Accessors { + val x = _x + val y = _y + } + } + // Entities with reflection enabled by inheritance @EnableReflectiveInstantiation From e85e50883c0c9ed307de78c46be84a9dc1f650a1 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 30 Mar 2018 15:57:33 +0200 Subject: [PATCH 0682/2665] Calculate scalajsenv.js source map location in generator This will ensure it doesn't rot if we move the file. --- .../linker/backend/emitter/CoreJSLibs.scala | 8 +------- project/Build.scala | 2 +- project/build.sbt | 2 +- project/project/ScalaJSEnvGenerator.scala | 18 ++++++++++++++++-- project/project/build.sbt | 1 + 5 files changed, 20 insertions(+), 11 deletions(-) create mode 100644 project/project/build.sbt diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLibs.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLibs.scala index 30e2a5e4cd..201b5443ec 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLibs.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLibs.scala @@ -130,13 +130,7 @@ private[emitter] object CoreJSLibs { private class ScalaJSEnvVirtualJSFile(override val content: String) extends VirtualJSFile { override def path: String = "scalajsenv.js" override def version: Option[String] = Some("") - - override def toURI: URI = { - if (!ScalaJSVersions.currentIsSnapshot) - gitHubBaseURI.resolve(s"v${ScalaJSVersions.current}/tools/$path") - else - super.toURI - } + override def toURI: URI = ScalaJSEnvHolder.sourceMapPath } } diff --git a/project/Build.scala b/project/Build.scala index 1ec20742c4..a4c92bdd86 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -675,7 +675,7 @@ object Build { sourceGenerators in Compile += Def.task { ScalaJSEnvGenerator.generateEnvHolder( - baseDirectory.value.getParentFile, + (baseDirectory in LocalProject("scalajs")).value, (sourceManaged in Compile).value) }.taskValue, diff --git a/project/build.sbt b/project/build.sbt index 11549314c6..e3e19ee3ed 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -33,7 +33,7 @@ sources in Compile += sourceGenerators in Compile += Def.task { build.ScalaJSEnvGenerator.generateEnvHolder( - baseDirectory.value.getParentFile / "linker", + baseDirectory.value.getParentFile, (sourceManaged in Compile).value) }.taskValue diff --git a/project/project/ScalaJSEnvGenerator.scala b/project/project/ScalaJSEnvGenerator.scala index c561ad7b48..95dff9a4e5 100644 --- a/project/project/ScalaJSEnvGenerator.scala +++ b/project/project/ScalaJSEnvGenerator.scala @@ -2,15 +2,26 @@ package build import sbt._ +import org.scalajs.ir.ScalaJSVersions + object ScalaJSEnvGenerator { + private final val relPath = "linker/scalajsenv.js" + /** Generate a *.scala file that contains the scalajsenv as literal string * * We need this so the tools don't rely on I/O and/or resources. */ - def generateEnvHolder(baseDir: File, sourceDir: File): Seq[File] = { + def generateEnvHolder(projectRoot: File, sourceDir: File): Seq[File] = { val trg = sourceDir / "ScalaJSEnvHolder.scala" - val env = baseDir / "scalajsenv.js" + val env = projectRoot / relPath + + val sourceMapPath = { + if (!ScalaJSVersions.currentIsSnapshot) + s"https://raw.githubusercontent.com/scala-js/scala-js/v${ScalaJSVersions.current}/$relPath" + else + env.getAbsolutePath + } if (!trg.exists() || trg.lastModified() < env.lastModified()) { val scalajsenv = IO.read(env).replaceAllLiterally("$", "$$") @@ -19,8 +30,11 @@ object ScalaJSEnvGenerator { s""" package org.scalajs.linker.backend.emitter + import java.net.URI + private[emitter] object ScalaJSEnvHolder { final val scalajsenv = raw\"\"\"$scalajsenv\"\"\" + final val sourceMapPath = new URI("$sourceMapPath") } """ diff --git a/project/project/build.sbt b/project/project/build.sbt new file mode 100644 index 0000000000..a2b08eb656 --- /dev/null +++ b/project/project/build.sbt @@ -0,0 +1 @@ +sources in Compile += baseDirectory.value / "../../ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala" From c51d39856378c56642d882c32102d85f978c351c Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 30 Mar 2018 19:56:45 +0200 Subject: [PATCH 0683/2665] Allow to emit code blocks in JSBuilder --- .../closure/ClosureAstTransformer.scala | 9 +- .../closure/ClosureLinkerBackend.scala | 29 +--- ...ilder.scala => ClosureModuleBuilder.scala} | 31 +++-- .../linker/backend/closure/URIUtil.scala | 12 ++ .../linker/backend/BasicLinkerBackend.scala | 11 +- .../linker/backend/emitter/Emitter.scala | 16 +-- .../backend/javascript/JSBuilders.scala | 131 ++++++------------ 7 files changed, 94 insertions(+), 145 deletions(-) rename linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/{ClosureAstBuilder.scala => ClosureModuleBuilder.scala} (53%) create mode 100644 linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/URIUtil.scala diff --git a/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureAstTransformer.scala b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureAstTransformer.scala index 921e69f788..db1b8ad63e 100644 --- a/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureAstTransformer.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureAstTransformer.scala @@ -334,7 +334,7 @@ private[closure] class ClosureAstTransformer(relativizeBaseURI: Option[URI]) { } private def attachSourceFile(node: Node, source: URI): node.type = { - val str = sourceUriToString(source) + val str = URIUtil.sourceURIToString(relativizeBaseURI, source) node.setInputId(inputId) node.setStaticSourceFile(new SourceFile(str)) @@ -342,13 +342,6 @@ private[closure] class ClosureAstTransformer(relativizeBaseURI: Option[URI]) { node } - private def sourceUriToString(uri: URI): String = { - import org.scalajs.io.URIUtils._ - - val relURI = relativizeBaseURI.fold(uri)(relativize(_, uri)) - fixFileURI(relURI).toASCIIString - } - // Helpers for IR @inline private def mkUnaryOp(op: UnaryOp.Code, lhs: Node): Node = { diff --git a/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala index afa6eee3f3..661cc2be76 100644 --- a/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala @@ -56,9 +56,6 @@ final class ClosureLinkerBackend(config: LinkerBackendImpl.Config) case ModuleKind.CommonJSModule => false } - private def toClosureSource(file: VirtualJSFile) = - ClosureSource.fromReader(file.toURI.toString(), file.reader) - /** Emit the given [[standard.LinkingUnit LinkingUnit]] to the target output. * * @param unit [[standard.LinkingUnit LinkingUnit]] to emit @@ -68,25 +65,17 @@ final class ClosureLinkerBackend(config: LinkerBackendImpl.Config) logger: Logger): Unit = { verifyUnit(unit) - val builder = new ClosureAstBuilder(config.relativizeSourceMapBase) - // Build Closure IR - val coreJSLib = logger.time("Emitter (create Closure trees)") { + val module = logger.time("Emitter (create Closure trees)") { + val builder = new ClosureModuleBuilder(config.relativizeSourceMapBase) emitter.emitForClosure(unit, builder, logger) + builder.result() } - // Build a Closure JSModule which includes the core libs - val module = new JSModule("Scala.js") - - module.add(new CompilerInput(toClosureSource(coreJSLib))) - - val ast = builder.closureAST - module.add(new CompilerInput(ast, ast.getInputId(), false)) - // Compile the module val closureExterns = List( - toClosureSource(ClosureLinkerBackend.ScalaJSExternsFile), - toClosureSource(makeExternsForExports(unit))) + ClosureSource.fromCode("ScalaJSExterns.js", ClosureLinkerBackend.ScalaJSExterns), + ClosureSource.fromCode("ScalaJSExportExterns.js", makeExternsForExports(unit))) val options = closureOptions(output.name) val compiler = closureCompiler(logger) @@ -105,7 +94,7 @@ final class ClosureLinkerBackend(config: LinkerBackendImpl.Config) * * This is necessary to avoid name clashes with renamed properties (#2491). */ - private def makeExternsForExports(linkingUnit: LinkingUnit): VirtualJSFile = { + private def makeExternsForExports(linkingUnit: LinkingUnit): String = { import org.scalajs.ir.Trees._ def exportName(memberDef: MemberDef): Option[String] = memberDef match { @@ -127,8 +116,7 @@ final class ClosureLinkerBackend(config: LinkerBackendImpl.Config) for (exportedPropertyName <- exportedPropertyNames.distinct) content.append(s"Object.prototype.$exportedPropertyName = 0;\n") - new MemVirtualJSFile("ScalaJSExportExterns.js") - .withContent(content.toString()) + content.toString() } private def closureCompiler(logger: Logger) = { @@ -206,7 +194,4 @@ private object ClosureLinkerBackend { var exports = {}; var NaN = 0.0/0.0, Infinity = 1.0/0.0, undefined = void 0; """ - - private val ScalaJSExternsFile = new MemVirtualJSFile("ScalaJSExterns.js"). - withContent(ScalaJSExterns) } diff --git a/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureAstBuilder.scala b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureModuleBuilder.scala similarity index 53% rename from linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureAstBuilder.scala rename to linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureModuleBuilder.scala index ff9e04b875..dbefc6fb05 100644 --- a/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureAstBuilder.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureModuleBuilder.scala @@ -4,7 +4,7 @@ import org.scalajs.ir import ir.Position.NoPosition import org.scalajs.linker.backend.javascript.Trees.Tree -import org.scalajs.linker.backend.javascript.JSTreeBuilder +import org.scalajs.linker.backend.javascript.JSBuilder import com.google.javascript.rhino._ import com.google.javascript.jscomp._ @@ -13,26 +13,41 @@ import scala.collection.mutable import java.net.URI -private[closure] class ClosureAstBuilder( - relativizeBaseURI: Option[URI] = None) extends JSTreeBuilder { +private[closure] class ClosureModuleBuilder( + relativizeBaseURI: Option[URI] = None) extends JSBuilder { private val transformer = new ClosureAstTransformer(relativizeBaseURI) private val treeBuf = mutable.ListBuffer.empty[Node] + private val module = new JSModule("Scala.js") def addJSTree(tree: Tree): Unit = treeBuf += transformer.transformStat(tree)(NoPosition) - lazy val closureAST: SourceAst = { - val root = transformer.setNodePosition(IR.script(treeBuf: _*), NoPosition) + def addStatement(originalLocation: URI, code: String): Unit = { + flushTrees() + val path = URIUtil.sourceURIToString(relativizeBaseURI, originalLocation) + module.add(new CompilerInput(SourceFile.fromCode(path, code))) + } - treeBuf.clear() + def complete(): Unit = flushTrees() - new ClosureAstBuilder.ScalaJSSourceAst(root) + def result(): JSModule = { + complete() + module } + private def flushTrees(): Unit = { + if (treeBuf.nonEmpty) { + val root = transformer.setNodePosition(IR.script(treeBuf: _*), NoPosition) + treeBuf.clear() + + val ast = new ClosureModuleBuilder.ScalaJSSourceAst(root) + module.add(new CompilerInput(ast, ast.getInputId(), false)) + } + } } -private object ClosureAstBuilder { +private object ClosureModuleBuilder { // Dummy Source AST class private class ScalaJSSourceAst(root: Node) extends SourceAst { diff --git a/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/URIUtil.scala b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/URIUtil.scala new file mode 100644 index 0000000000..770f96938f --- /dev/null +++ b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/URIUtil.scala @@ -0,0 +1,12 @@ +package org.scalajs.linker.backend.closure + +import java.net.URI + +private[closure] object URIUtil { + def sourceURIToString(relativizeBaseURI: Option[URI], uri: URI): String = { + import org.scalajs.io.URIUtils._ + + val relURI = relativizeBaseURI.fold(uri)(relativize(_, uri)) + fixFileURI(relURI).toASCIIString + } +} diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/BasicLinkerBackend.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/BasicLinkerBackend.scala index 421d3a6385..50c2886870 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/BasicLinkerBackend.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/BasicLinkerBackend.scala @@ -15,9 +15,7 @@ import org.scalajs.io.WritableVirtualJSFile import org.scalajs.linker.standard._ import org.scalajs.linker.backend.emitter.Emitter -import org.scalajs.linker.backend.javascript.{ - JSFileBuilder, JSFileBuilderWithSourceMap -} +import org.scalajs.linker.backend.javascript.{JSLineBuilder, JSFileBuilder, JSFileBuilderWithSourceMap} /** The basic backend for the Scala.js linker. * @@ -40,19 +38,16 @@ final class BasicLinkerBackend(config: LinkerBackendImpl.Config) verifyUnit(unit) val builder = newBuilder(output) - try { logger.time("Emitter (write output)") { emitter.emitAll(unit, builder, logger) } - - builder.complete() } finally { - builder.closeWriters() + builder.complete() } } - private def newBuilder(output: WritableVirtualJSFile): JSFileBuilder = { + private def newBuilder(output: WritableVirtualJSFile): JSLineBuilder = { if (config.sourceMap) { new JSFileBuilderWithSourceMap(output.name, output.contentWriter, output.sourceMapWriter, config.relativizeSourceMapBase) diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala index 624e4b9134..83fda28929 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala @@ -105,14 +105,13 @@ final class Emitter private (config: CommonPhaseConfig, internalOptions.withOptimizeBracketSelects(optimizeBracketSelects)) } - def emitAll(unit: LinkingUnit, builder: JSFileBuilder, + def emitAll(unit: LinkingUnit, builder: JSLineBuilder, logger: Logger): Unit = { emitInternal(unit, builder, logger) { if (needsIIFEWrapper) builder.addLine("(function(){") builder.addLine("'use strict';") - builder.addFile(coreJSLib) } { if (needsIIFEWrapper) builder.addLine("}).call(this);") @@ -124,13 +123,12 @@ final class Emitter private (config: CommonPhaseConfig, * * This is special for the Closure back-end. */ - private[backend] def emitForClosure(unit: LinkingUnit, builder: JSTreeBuilder, - logger: Logger): VirtualJSFile = { + private[backend] def emitForClosure(unit: LinkingUnit, builder: JSBuilder, + logger: Logger): Unit = { emitInternal(unit, builder, logger)(())(()) - coreJSLib } - private def emitInternal(unit: LinkingUnit, builder: JSTreeBuilder, + private def emitInternal(unit: LinkingUnit, builder: JSBuilder, logger: Logger)( emitPrelude: => Unit)( emitPostlude: => Unit): Unit = { @@ -142,6 +140,8 @@ final class Emitter private (config: CommonPhaseConfig, emitPrelude + builder.addStatement(coreJSLib.toURI, coreJSLib.content) + emitModuleImports(orderedClasses, builder, logger) /* Emit all the classes, in the appropriate order: @@ -190,7 +190,7 @@ final class Emitter private (config: CommonPhaseConfig, } private def emitModuleImports(orderedClasses: List[LinkedClass], - builder: JSTreeBuilder, logger: Logger): Unit = { + builder: JSBuilder, logger: Logger): Unit = { moduleKind match { case ModuleKind.NoModule => var importsFound: Boolean = false @@ -474,7 +474,7 @@ final class Emitter private (config: CommonPhaseConfig, * This is done at the very end of the emitted module/script. */ private def emitModuleInitializer(moduleInitializer: ModuleInitializer, - builder: JSTreeBuilder): Unit = { + builder: JSBuilder): Unit = { builder.addJSTree(classEmitter.genModuleInitializer(moduleInitializer)) } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/JSBuilders.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/JSBuilders.scala index c4ff12d419..0f123bacc7 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/JSBuilders.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/JSBuilders.scala @@ -9,45 +9,40 @@ package org.scalajs.linker.backend.javascript -import scala.annotation.tailrec - -import scala.collection.mutable +import org.scalajs.ir.Position import java.io._ -import java.util.regex.Pattern -import java.net.{ URI, URISyntaxException } - -import org.scalajs.ir.Position -import org.scalajs.io._ +import java.net.URI /** An abstract builder taking IR or JSTrees */ -trait JSTreeBuilder { +trait JSBuilder { /** Add a JavaScript tree representing a statement. * The tree must be a valid JavaScript tree (typically obtained by * desugaring a full-fledged IR tree). */ def addJSTree(tree: Trees.Tree): Unit + /** Add a chunk of JavaScript code. */ + def addStatement(originalLocation: URI, code: String): Unit + /** Completes the builder. */ - def complete(): Unit = () + def complete(): Unit +} + +trait JSLineBuilder extends JSBuilder { + def addLine(line: String): Unit } -class JSFileBuilder(val name: String, - protected val outputWriter: Writer) extends JSTreeBuilder { +final class JSFileBuilder(name: String, outputWriter: Writer) extends JSLineBuilder { def addLine(line: String): Unit = { outputWriter.write(line) outputWriter.write('\n') } - def addLines(lines: Seq[String]): Unit = - lines.foreach(addLine) - - def addFile(file: VirtualJSFile): Unit = - addPartsOfFile(file)(!_.startsWith("//# sourceMappingURL=")) - - def addPartsOfFile(file: VirtualJSFile)(selector: String => Boolean): Unit = { - for (line <- file.readLines() if selector(line)) - addLine(line) + def addStatement(originalLocation: URI, code: String): Unit = { + outputWriter.write(code) + if (code.nonEmpty && !code.endsWith("\n")) + outputWriter.write('\n') } /** Add a JavaScript tree representing a statement. @@ -60,95 +55,49 @@ class JSFileBuilder(val name: String, // Do not close the printer: we do not have ownership of the writers } - /** Closes the underlying writer(s). - */ - def closeWriters(): Unit = { + def complete(): Unit = outputWriter.close() - } } -class JSFileBuilderWithSourceMapWriter(n: String, ow: Writer, - protected val sourceMapWriter: SourceMapWriter) - extends JSFileBuilder(n, ow) { +class JSFileBuilderWithSourceMap(name: String, outputWriter: Writer, + sourceMapOutputWriter: Writer, + relativizeSourceMapBasePath: Option[URI]) extends JSLineBuilder { + private val sourceMapWriter = new SourceMapWriter( + sourceMapOutputWriter, name, relativizeSourceMapBasePath) - override def addLine(line: String): Unit = { - super.addLine(line) + def addLine(line: String): Unit = { + outputWriter.write(line) + outputWriter.write('\n') sourceMapWriter.nextLine() } - private final val NotSelected = -1 - - override def addPartsOfFile(file: VirtualJSFile)( - selector: String => Boolean): Unit = { - val br = new BufferedReader(file.reader) - try { - // Select lines, and remember offsets - val offsets = new mutable.ArrayBuffer[Int] // (maybe NotSelected) - val selectedLineLengths = new mutable.ArrayBuffer[Int] - var line: String = br.readLine() - var selectedCount = 0 - while (line != null) { - if (selector(line)) { - super.addLine(line) // super call not to advance line in source map - offsets += selectedCount - selectedLineLengths += line.length - selectedCount += 1 - } else { - offsets += NotSelected - } - line = br.readLine() - } + def addStatement(originalLocation: URI, code: String): Unit = { + if (code.nonEmpty) { + outputWriter.write(code) + + if (!code.endsWith("\n")) + outputWriter.write("\n") - /* We ignore a potential source map. - * This happens typically for corejslib.js and other helper files - * written directly in JS. - * We generate a fake line-by-line source map for these on the fly - */ - val sourceFile = file.toURI - - for (lineNumber <- 0 until offsets.size) { - val offset = offsets(lineNumber) - if (offset != NotSelected) { - val originalPos = Position(sourceFile, lineNumber, 0) - sourceMapWriter.startNode(0, originalPos, None) - sourceMapWriter.endNode(selectedLineLengths(offset)) - sourceMapWriter.nextLine() - } + for ((line, i) <- code.stripSuffix("\n").split("\n", -1).zipWithIndex) { + val originalPos = Position(originalLocation, i, 0) + sourceMapWriter.startNode(0, originalPos, None) + sourceMapWriter.endNode(line.length) + sourceMapWriter.nextLine() } - } finally { - br.close() } } - override def addJSTree(tree: Trees.Tree): Unit = { + def addJSTree(tree: Trees.Tree): Unit = { val printer = new Printers.JSTreePrinterWithSourceMap( outputWriter, sourceMapWriter) printer.printTopLevelTree(tree) // Do not close the printer: we do not have ownership of the writers } - override def complete(): Unit = { - super.complete() - sourceMapWriter.complete() - } - -} - -class JSFileBuilderWithSourceMap(n: String, ow: Writer, - sourceMapOutputWriter: Writer, - relativizeSourceMapBasePath: Option[URI] = None) - extends JSFileBuilderWithSourceMapWriter( - n, ow, - new SourceMapWriter(sourceMapOutputWriter, n, - relativizeSourceMapBasePath)) { - - override def complete(): Unit = { + def complete(): Unit = { addLine("//# sourceMappingURL=" + name + ".map") - super.complete() - } - - override def closeWriters(): Unit = { - super.closeWriters() + outputWriter.close() + sourceMapWriter.complete() sourceMapOutputWriter.close() } } From 9d2cf58fa613233e7abe7ab9ebc3ea026d6ba844 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 30 Mar 2018 20:01:53 +0200 Subject: [PATCH 0684/2665] Do not use a virtual file for the corejslib --- .../linker/backend/emitter/CoreJSLibs.scala | 20 ++++--------------- .../linker/backend/emitter/Emitter.scala | 17 +++++----------- 2 files changed, 9 insertions(+), 28 deletions(-) diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLibs.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLibs.scala index 201b5443ec..aa36e0ea8d 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLibs.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLibs.scala @@ -12,7 +12,6 @@ package org.scalajs.linker.backend.emitter import java.net.URI import org.scalajs.ir.ScalaJSVersions -import org.scalajs.io._ import org.scalajs.linker._ @@ -23,8 +22,7 @@ private[emitter] object CoreJSLibs { private type Config = (Semantics, ESFeatures, ModuleKind) - private val cachedLibByConfig = - mutable.HashMap.empty[Config, VirtualJSFile] + private val cachedLibByConfig = mutable.HashMap.empty[Config, String] private val ScalaJSEnvLines = ScalaJSEnvHolder.scalajsenv.split("\n|\r\n?") @@ -33,7 +31,7 @@ private[emitter] object CoreJSLibs { new URI("https://raw.githubusercontent.com/scala-js/scala-js/") def lib(semantics: Semantics, esFeatures: ESFeatures, - moduleKind: ModuleKind): VirtualJSFile = { + moduleKind: ModuleKind): String = { synchronized { cachedLibByConfig.getOrElseUpdate( (semantics, esFeatures, moduleKind), @@ -41,12 +39,9 @@ private[emitter] object CoreJSLibs { } } - private def makeLib(semantics: Semantics, esFeatures: ESFeatures, - moduleKind: ModuleKind): VirtualJSFile = { - new ScalaJSEnvVirtualJSFile(makeContent(semantics, esFeatures, moduleKind)) - } + def locationForSourceMap: URI = ScalaJSEnvHolder.sourceMapPath - private def makeContent(semantics: Semantics, esFeatures: ESFeatures, + private def makeLib(semantics: Semantics, esFeatures: ESFeatures, moduleKind: ModuleKind): String = { // This is a basic sort-of-C-style preprocessor @@ -126,11 +121,4 @@ private[emitter] object CoreJSLibs { else content.replaceAll(raw"\b(let|const)\b", "var") } - - private class ScalaJSEnvVirtualJSFile(override val content: String) extends VirtualJSFile { - override def path: String = "scalajsenv.js" - override def version: Option[String] = Some("") - override def toURI: URI = ScalaJSEnvHolder.sourceMapPath - } - } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala index 83fda28929..1feb9c8439 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala @@ -49,16 +49,11 @@ final class Emitter private (config: CommonPhaseConfig, val classEmitter: ClassEmitter = new ClassEmitter(jsGen) - val coreJSLib: VirtualJSFile = { + val coreJSLib: String = { if (lastMentionedDangerousGlobalRefs.isEmpty) { baseCoreJSLib } else { - var content = { - val reader = baseCoreJSLib.reader - try IO.readReaderToString(reader) - finally reader.close() - } - + var content = baseCoreJSLib for { globalRef <- lastMentionedDangerousGlobalRefs if !globalRef.startsWith("$$") @@ -68,9 +63,7 @@ final class Emitter private (config: CommonPhaseConfig, java.util.regex.Matcher.quoteReplacement(replacement)) } - val result = new MemVirtualJSFile(baseCoreJSLib.path) - result.content = content - result + content } } } @@ -79,7 +72,7 @@ final class Emitter private (config: CommonPhaseConfig, private def jsGen: JSGen = state.jsGen private def classEmitter: ClassEmitter = state.classEmitter - private def coreJSLib: VirtualJSFile = state.coreJSLib + private def coreJSLib: String = state.coreJSLib private val classCaches = mutable.Map.empty[List[String], ClassCache] @@ -140,7 +133,7 @@ final class Emitter private (config: CommonPhaseConfig, emitPrelude - builder.addStatement(coreJSLib.toURI, coreJSLib.content) + builder.addStatement(CoreJSLibs.locationForSourceMap, coreJSLib) emitModuleImports(orderedClasses, builder, logger) From 74338702cef344cbb7af917f0e93709b88fd06c7 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 30 Mar 2018 19:57:28 +0200 Subject: [PATCH 0685/2665] Remove VirtualFile#toURI --- .../src/main/scala/org/scalajs/io/NodeVirtualFiles.scala | 5 ----- .../src/main/scala/org/scalajs/io/FileVirtualFiles.scala | 2 -- .../src/main/scala/org/scalajs/io/VirtualFiles.scala | 9 --------- .../org/scalajs/testadapter/HTMLRunnerBuilder.scala | 2 +- 4 files changed, 1 insertion(+), 17 deletions(-) diff --git a/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala b/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala index 19f772da29..5b4fd61e95 100644 --- a/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala +++ b/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala @@ -16,11 +16,6 @@ class NodeVirtualFile(override val path: String) extends VirtualFile { else Some(stat.mtime.asInstanceOf[js.Date].getTime.toString) } - - override def toURI: URI = { - val abspath = fs.realpathSync(path).asInstanceOf[String] - new URI("file", abspath, null) - } } class NodeVirtualTextFile(p: String) extends NodeVirtualFile(p) diff --git a/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala b/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala index ccf17693aa..2c263a0e05 100644 --- a/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala +++ b/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala @@ -15,8 +15,6 @@ class FileVirtualFile(val file: File) extends VirtualFile { if (!file.isFile) None else Some(file.lastModified.toString) } - - override def toURI: URI = file.toURI } object FileVirtualFile extends (File => FileVirtualFile) { diff --git a/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala b/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala index a09c4c1cfe..baafdfc994 100644 --- a/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala +++ b/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala @@ -24,15 +24,6 @@ trait VirtualFile { */ def version: Option[String] = None - /** URI for this virtual file */ - def toURI: URI = { - new URI( - "virtualfile", // Pseudo-Scheme - path, // Scheme specific part - null // Fragment - ) - } - override def toString(): String = { val className = getClass.getName val shortClassName = className.substring(className.lastIndexOf('.') + 1) diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala index 61a7860075..f27a268901 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala @@ -41,7 +41,7 @@ object HTMLRunnerBuilder { val jsFileCache = new VirtualFileMaterializer(true) val jsFileURIs = jsFiles.map { - case file: FileVirtualFile => file.toURI + case file: FileVirtualFile => file.file.toURI case file => jsFileCache.materialize(file).toURI } val cssFileURI = jsFileCache.materialize(cssFile).toURI From 0141a740c55c02839d448ffb16d948f0f19e95c5 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Mon, 26 Mar 2018 07:04:06 +0200 Subject: [PATCH 0686/2665] Make VirtualJarFile JVM only VirtualJarFile was already JVM only in practice (since javalib-ex got removed). --- .../scala/org/scalajs/io/VirtualJarFile.scala | 32 +++++++++++++++++++ .../scala/org/scalajs/io/VirtualFiles.scala | 29 ----------------- 2 files changed, 32 insertions(+), 29 deletions(-) create mode 100644 io/jvm/src/main/scala/org/scalajs/io/VirtualJarFile.scala diff --git a/io/jvm/src/main/scala/org/scalajs/io/VirtualJarFile.scala b/io/jvm/src/main/scala/org/scalajs/io/VirtualJarFile.scala new file mode 100644 index 0000000000..e18e91b52f --- /dev/null +++ b/io/jvm/src/main/scala/org/scalajs/io/VirtualJarFile.scala @@ -0,0 +1,32 @@ +package org.scalajs.io + +import java.io._ +import java.util.zip.{ZipInputStream, ZipEntry} + +/** A virtual jar file. */ +trait VirtualJarFile extends VirtualFileContainer with VirtualBinaryFile { + import VirtualJarFile._ + + def listEntries[T](p: String => Boolean)( + makeResult: (String, InputStream) => T): List[T] = { + val stream = new ZipInputStream(inputStream) + try { + val streamIgnoreClose = new IgnoreCloseFilterInputStream(stream) + Iterator.continually(stream.getNextEntry()) + .takeWhile(_ != null) + .filter(entry => p(entry.getName)) + .map(entry => makeResult(entry.getName, streamIgnoreClose)) + .toList + } finally { + stream.close() + } + } +} + +private object VirtualJarFile { + private final class IgnoreCloseFilterInputStream(in: InputStream) + extends FilterInputStream(in) { + + override def close(): Unit = () + } +} diff --git a/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala b/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala index baafdfc994..6a77a5f299 100644 --- a/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala +++ b/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala @@ -2,7 +2,6 @@ package org.scalajs.io import java.io._ import java.net.URI -import java.util.zip.{ZipInputStream, ZipEntry} /** A virtual input file. */ @@ -126,31 +125,3 @@ trait VirtualFileContainer extends VirtualFile { def listEntries[T](p: String => Boolean)( makeResult: (String, InputStream) => T): List[T] } - -/** A virtual jar file. */ -trait VirtualJarFile extends VirtualFileContainer with VirtualBinaryFile { - import VirtualJarFile._ - - def listEntries[T](p: String => Boolean)( - makeResult: (String, InputStream) => T): List[T] = { - val stream = new ZipInputStream(inputStream) - try { - val streamIgnoreClose = new IgnoreCloseFilterInputStream(stream) - Iterator.continually(stream.getNextEntry()) - .takeWhile(_ != null) - .filter(entry => p(entry.getName)) - .map(entry => makeResult(entry.getName, streamIgnoreClose)) - .toList - } finally { - stream.close() - } - } -} - -private object VirtualJarFile { - private final class IgnoreCloseFilterInputStream(in: InputStream) - extends FilterInputStream(in) { - - override def close(): Unit = () - } -} From ba80d65996cb38f81740a039e7af924d441d3603 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Mon, 26 Mar 2018 07:06:51 +0200 Subject: [PATCH 0687/2665] Make URIUtils private[scalajs] It is way too specific to Scala.js to be meaningfully public. --- io/shared/src/main/scala/org/scalajs/io/URIUtils.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/io/shared/src/main/scala/org/scalajs/io/URIUtils.scala b/io/shared/src/main/scala/org/scalajs/io/URIUtils.scala index a1f9380682..d042f22b25 100644 --- a/io/shared/src/main/scala/org/scalajs/io/URIUtils.scala +++ b/io/shared/src/main/scala/org/scalajs/io/URIUtils.scala @@ -10,7 +10,7 @@ package org.scalajs.io import java.net.URI -object URIUtils { +private[scalajs] object URIUtils { /** Relativize target URI w.r.t. base URI */ def relativize(base0: URI, trgt0: URI): URI = { From 0b048cf4304f234117be166c7f90d67dd72a712a Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Mon, 19 Mar 2018 21:03:14 +0100 Subject: [PATCH 0688/2665] Use a proper facade for Node's fs module --- .../org/scalajs/io/NodeVirtualFiles.scala | 43 ++++++++++--------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala b/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala index 5b4fd61e95..3e0efe9150 100644 --- a/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala +++ b/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala @@ -1,39 +1,26 @@ package org.scalajs.io import scala.scalajs.js +import scala.scalajs.js.annotation.JSImport import scala.scalajs.js.typedarray._ import java.io._ import java.net.URI class NodeVirtualFile(override val path: String) extends VirtualFile { - import NodeFS.fs - - override def version: Option[String] = { - val stat = fs.statSync(path) - if (js.isUndefined(stat.mtime)) - None - else - Some(stat.mtime.asInstanceOf[js.Date].getTime.toString) - } + override def version: Option[String] = + NodeFS.statSync(path).mtime.map(_.getTime.toString).toOption } class NodeVirtualTextFile(p: String) extends NodeVirtualFile(p) with VirtualTextFile { - import NodeFS.fs - - override def content: String = { - val options = js.Dynamic.literal(encoding = "UTF-8") - fs.readFileSync(path, options).asInstanceOf[String] - } + override def content: String = NodeFS.readFileSync(path, NodeSupport.utf8enc) } class NodeVirtualBinaryFile(p: String) extends NodeVirtualFile(p) with VirtualBinaryFile { - import NodeFS.fs - private def buf: ArrayBuffer = - new Uint8Array(fs.readFileSync(path).asInstanceOf[js.Array[Int]]).buffer + new Uint8Array(NodeFS.readFileSync(path)).buffer override def content: Array[Byte] = new Int8Array(buf).toArray override def inputStream: InputStream = new ArrayBufferInputStream(buf) @@ -46,6 +33,22 @@ class NodeVirtualJSFile(p: String) extends NodeVirtualTextFile(p) override def sourceMap: Option[String] = None } -private[io] object NodeFS { - val fs = js.Dynamic.global.require("fs") +private[io] object NodeSupport { + val utf8enc: NodeFS.Enc = new NodeFS.Enc { val encoding = "UTF-8" } +} + +@JSImport("fs", JSImport.Namespace) +@js.native +private[io] object NodeFS extends js.Object { + trait Enc extends js.Object { + val encoding: String + } + + trait Stat extends js.Object { + val mtime: js.UndefOr[js.Date] + } + + def readFileSync(path: String): js.Array[Int] = js.native + def readFileSync(path: String, enc: Enc): String = js.native + def statSync(path: String): Stat = js.native } From 585aa14f50b54211a0f684912eaa8310313f6711 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 30 Mar 2018 23:49:53 +0200 Subject: [PATCH 0689/2665] Remove RelativeVirtualFile It was always used in conjuction with ScalaJSIRFile. As a result, we have a bunch of helpers less and a much saner definition of `relativePath`. --- .../org/scalajs/io/FileVirtualFiles.scala | 7 ------- .../scala/org/scalajs/io/VirtualFiles.scala | 10 ---------- .../linker/irio/NodeVirtualIRFiles.scala | 2 +- .../org/scalajs/linker/test/QuickLinker.scala | 7 +++---- .../linker/testutils/NodeVirtualJarFile.scala | 2 +- .../linker/irio/FileVirtualIRFiles.scala | 19 ++++++------------ .../org/scalajs/linker/irio/IRFileCache.scala | 12 +++++------ .../org/scalajs/linker/irio/MemIRFiles.scala | 2 +- .../scalajs/linker/irio/VirtualIRFiles.scala | 20 +++++++++---------- .../scala/org/scalajs/linker/LinkerTest.scala | 1 + .../scalajs/linker/testutils/TestIRRepo.scala | 2 +- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 2 +- .../sbtplugin/ScalaJSPluginInternal.scala | 2 +- 13 files changed, 32 insertions(+), 56 deletions(-) diff --git a/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala b/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala index 2c263a0e05..e48920b9f0 100644 --- a/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala +++ b/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala @@ -132,13 +132,6 @@ class FileVirtualJSFile(f: File) extends FileVirtualTextFile(f) object FileVirtualJSFile extends (File => FileVirtualJSFile) { def apply(f: File): FileVirtualJSFile = new FileVirtualJSFile(f) - - def relative(f: File, - relPath: String): FileVirtualJSFile with RelativeVirtualFile = { - new FileVirtualJSFile(f) with RelativeVirtualFile { - def relativePath: String = relPath - } - } } trait WritableFileVirtualJSFile extends FileVirtualJSFile diff --git a/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala b/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala index 6a77a5f299..dea7bf4201 100644 --- a/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala +++ b/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala @@ -39,16 +39,6 @@ object VirtualFile { } } -trait RelativeVirtualFile extends VirtualFile { - /** Relative path with respect to some container. - * - * The container depends on the context in which this [[RelativeVirtualFile]] - * is retrieved. A good example is the [[VirtualJarFile]] where the relative - * path is the path inside the Jar. - */ - def relativePath: String -} - /** A virtual input file. */ trait VirtualTextFile extends VirtualFile { diff --git a/linker/js/src/main/scala/org/scalajs/linker/irio/NodeVirtualIRFiles.scala b/linker/js/src/main/scala/org/scalajs/linker/irio/NodeVirtualIRFiles.scala index 944633f4fc..4e9e712b72 100644 --- a/linker/js/src/main/scala/org/scalajs/linker/irio/NodeVirtualIRFiles.scala +++ b/linker/js/src/main/scala/org/scalajs/linker/irio/NodeVirtualIRFiles.scala @@ -10,5 +10,5 @@ package org.scalajs.linker.irio import org.scalajs.io._ -class NodeVirtualScalaJSIRFile(p: String) +class NodeVirtualScalaJSIRFile(p: String, val relativePath: String) extends NodeVirtualBinaryFile(p) with VirtualSerializedScalaJSIRFile diff --git a/linker/js/src/test/scala/org/scalajs/linker/test/QuickLinker.scala b/linker/js/src/test/scala/org/scalajs/linker/test/QuickLinker.scala index 5e5b34c955..21ce773988 100644 --- a/linker/js/src/test/scala/org/scalajs/linker/test/QuickLinker.scala +++ b/linker/js/src/test/scala/org/scalajs/linker/test/QuickLinker.scala @@ -61,10 +61,9 @@ object QuickLinker { if (file.endsWith(".jar")) { Platform.loadJar(file) } else if (file.endsWith(".sjsir")) { - new NodeVirtualScalaJSIRFile(file) with VirtualRelativeScalaJSIRFile { - // The compiler should not use this (only scalajsp does) - def relativePath: String = s"" - } + // The compiler should not use this (only scalajsp does) + val relativePath: String = s"" + new NodeVirtualScalaJSIRFile(file, relativePath) } else { throw new IllegalArgumentException("Illegal IR file / Jar: " + file) } diff --git a/linker/js/src/test/scala/org/scalajs/linker/testutils/NodeVirtualJarFile.scala b/linker/js/src/test/scala/org/scalajs/linker/testutils/NodeVirtualJarFile.scala index 60d107a7da..04ed1026eb 100644 --- a/linker/js/src/test/scala/org/scalajs/linker/testutils/NodeVirtualJarFile.scala +++ b/linker/js/src/test/scala/org/scalajs/linker/testutils/NodeVirtualJarFile.scala @@ -72,6 +72,6 @@ object NodeVirtualJarFile { class NodeVirtualJarScalaJSIRContainer(file: String) extends NodeVirtualJarFile(file) with ScalaJSIRContainer { - def sjsirFiles: List[VirtualRelativeScalaJSIRFile] = + def sjsirFiles: List[VirtualScalaJSIRFile] = ScalaJSIRContainer.sjsirFilesIn(this) } diff --git a/linker/jvm/src/main/scala/org/scalajs/linker/irio/FileVirtualIRFiles.scala b/linker/jvm/src/main/scala/org/scalajs/linker/irio/FileVirtualIRFiles.scala index d6feb0a944..cc32c5b237 100644 --- a/linker/jvm/src/main/scala/org/scalajs/linker/irio/FileVirtualIRFiles.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/irio/FileVirtualIRFiles.scala @@ -12,21 +12,14 @@ import java.io._ import org.scalajs.io._ -class FileVirtualScalaJSIRFile(f: File) +class FileVirtualScalaJSIRFile(f: File, val relativePath: String) extends FileVirtualBinaryFile(f) with VirtualSerializedScalaJSIRFile -object FileVirtualScalaJSIRFile extends (File => FileVirtualScalaJSIRFile) { +object FileVirtualScalaJSIRFile { import FileVirtualFile._ - def apply(f: File): FileVirtualScalaJSIRFile = - new FileVirtualScalaJSIRFile(f) - - def relative(f: File, relPath: String): FileVirtualScalaJSIRFile - with VirtualRelativeScalaJSIRFile = { - new FileVirtualScalaJSIRFile(f) with VirtualRelativeScalaJSIRFile { - def relativePath: String = relPath - } - } + def apply(f: File, relPath: String): FileVirtualScalaJSIRFile = + new FileVirtualScalaJSIRFile(f, relPath) def isScalaJSIRFile(file: File): Boolean = hasExtension(file, ".sjsir") @@ -63,7 +56,7 @@ object FileScalaJSIRContainer { .stripPrefix(baseDir.getPath) .replace(java.io.File.separatorChar, '/') .stripPrefix("/") - FileVirtualScalaJSIRFile.relative(ir, relPath) + FileVirtualScalaJSIRFile(ir, relPath) } } } @@ -71,6 +64,6 @@ object FileScalaJSIRContainer { class FileVirtualJarScalaJSIRContainer(file: File) extends FileVirtualJarFile(file) with ScalaJSIRContainer { - def sjsirFiles: List[VirtualRelativeScalaJSIRFile] = + def sjsirFiles: List[VirtualScalaJSIRFile] = ScalaJSIRContainer.sjsirFilesIn(this) } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/irio/IRFileCache.scala b/linker/shared/src/main/scala/org/scalajs/linker/irio/IRFileCache.scala index 16c918468e..8cb247f519 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/irio/IRFileCache.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/irio/IRFileCache.scala @@ -71,10 +71,10 @@ final class IRFileCache { * [[free]]. * * @note Updating any of the underlying files in the container during the - * lifetime of a returned [[VirtualRelativeScalaJSIRFile]] yields + * lifetime of a returned [[VirtualScalaJSIRFile]] yields * unspecified behavior. */ - def cached(files: Seq[ScalaJSIRContainer]): Seq[VirtualRelativeScalaJSIRFile] = { + def cached(files: Seq[ScalaJSIRContainer]): Seq[VirtualScalaJSIRFile] = { update(files) localCache.flatMap(_.files) } @@ -144,9 +144,9 @@ final class IRFileCache { * May only be written under synchronization, except if this is a tombstone */ @volatile - private[this] var _files: Seq[VirtualRelativeScalaJSIRFile] = null + private[this] var _files: Seq[VirtualScalaJSIRFile] = null - def files: Seq[VirtualRelativeScalaJSIRFile] = _files + def files: Seq[VirtualScalaJSIRFile] = _files /** Try to reference this block of files. * @return true if referencing succeeded, false if this is a tombstone @@ -226,8 +226,8 @@ final class IRFileCache { } private final class PersistentIRFile( - private[this] var _irFile: VirtualRelativeScalaJSIRFile) - extends VirtualRelativeScalaJSIRFile { + private[this] var _irFile: VirtualScalaJSIRFile) + extends VirtualScalaJSIRFile { @volatile private[this] var _tree: ClassDef = null diff --git a/linker/shared/src/main/scala/org/scalajs/linker/irio/MemIRFiles.scala b/linker/shared/src/main/scala/org/scalajs/linker/irio/MemIRFiles.scala index d1793007f6..e9b8301354 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/irio/MemIRFiles.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/irio/MemIRFiles.scala @@ -11,5 +11,5 @@ package org.scalajs.linker.irio import org.scalajs.io._ /** A simple in-memory mutable virtual serialized Scala.js IR file. */ -class MemVirtualSerializedScalaJSIRFile(p: String) +class MemVirtualSerializedScalaJSIRFile(p: String, val relativePath: String) extends MemVirtualBinaryFile(p) with VirtualSerializedScalaJSIRFile diff --git a/linker/shared/src/main/scala/org/scalajs/linker/irio/VirtualIRFiles.scala b/linker/shared/src/main/scala/org/scalajs/linker/irio/VirtualIRFiles.scala index b6b9e31e39..abb0537a14 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/irio/VirtualIRFiles.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/irio/VirtualIRFiles.scala @@ -26,12 +26,12 @@ trait ScalaJSIRContainer extends VirtualFile { * * It is up to the implementation whether these files are read lazily or not. */ - def sjsirFiles: List[VirtualRelativeScalaJSIRFile] + def sjsirFiles: List[VirtualScalaJSIRFile] } object ScalaJSIRContainer { def sjsirFilesIn( - container: VirtualFileContainer): List[VirtualRelativeScalaJSIRFile] = { + container: VirtualFileContainer): List[VirtualScalaJSIRFile] = { container.listEntries(_.endsWith(".sjsir")) { (relPath, stream) => val file = new EntryIRFile(container.path, relPath) file.content = IO.readInputStreamToByteArray(stream) @@ -40,26 +40,26 @@ object ScalaJSIRContainer { } } - private class EntryIRFile(outerPath: String, val relativePath: String) - extends MemVirtualSerializedScalaJSIRFile(s"$outerPath:$relativePath") - with VirtualRelativeScalaJSIRFile + private class EntryIRFile(outerPath: String, relativePath: String) + extends MemVirtualSerializedScalaJSIRFile(s"$outerPath:$relativePath", relativePath) + with VirtualScalaJSIRFile } /** A virtual Scala.js IR file. * It contains the class info and the IR tree. */ -trait VirtualScalaJSIRFile extends VirtualFile { +trait VirtualScalaJSIRFile extends VirtualFile with ScalaJSIRContainer { /** Entry points information for this file. */ def entryPointsInfo: ir.EntryPointsInfo = ir.EntryPointsInfo.forClassDef(tree) /** IR Tree of this file. */ def tree: ir.Trees.ClassDef -} -trait VirtualRelativeScalaJSIRFile extends VirtualScalaJSIRFile - with RelativeVirtualFile with ScalaJSIRContainer { - def sjsirFiles: List[VirtualRelativeScalaJSIRFile] = this :: Nil + /** The path of this IR relative to its classpath root. */ + def relativePath: String + + def sjsirFiles: List[VirtualScalaJSIRFile] = this :: Nil } /** Base trait for virtual Scala.js IR files that are serialized as binary file. diff --git a/linker/shared/src/test/scala/org/scalajs/linker/LinkerTest.scala b/linker/shared/src/test/scala/org/scalajs/linker/LinkerTest.scala index ac82c0841d..cfc1fb4ef9 100644 --- a/linker/shared/src/test/scala/org/scalajs/linker/LinkerTest.scala +++ b/linker/shared/src/test/scala/org/scalajs/linker/LinkerTest.scala @@ -97,6 +97,7 @@ object LinkerTest { def exists: Boolean = true def path: String = "mem://" + classDef.name.name + ".sjsir" def tree: ClassDef = classDef + def relativePath: String = classDef.name.name + ".sjsir" } } diff --git a/linker/shared/src/test/scala/org/scalajs/linker/testutils/TestIRRepo.scala b/linker/shared/src/test/scala/org/scalajs/linker/testutils/TestIRRepo.scala index 7c2ead1cd6..40ec305ed4 100644 --- a/linker/shared/src/test/scala/org/scalajs/linker/testutils/TestIRRepo.scala +++ b/linker/shared/src/test/scala/org/scalajs/linker/testutils/TestIRRepo.scala @@ -13,7 +13,7 @@ object TestIRRepo { private val globalIRCache = new IRFileCache - val stdlibIRFiles: Seq[VirtualScalaJSIRFile with RelativeVirtualFile] = + val stdlibIRFiles: Seq[VirtualScalaJSIRFile] = globalIRCache.newCache.cached(Seq(Platform.loadJar(stdlibPath))) private val stdlibEncodedNameToFile = diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 3b29efd77a..a52b4b41e5 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -92,7 +92,7 @@ object ScalaJSPlugin extends AutoPlugin { val testHtml = TaskKey[Attributed[File]]("testHtml", "Create an HTML test runner. Honors `scalaJSStage`.", AMinusTask) - val scalaJSIR = TaskKey[Attributed[Seq[VirtualScalaJSIRFile with RelativeVirtualFile]]]( + val scalaJSIR = TaskKey[Attributed[Seq[VirtualScalaJSIRFile]]]( "scalaJSIR", "All the *.sjsir files on the classpath", CTask) val scalaJSModuleInitializers = TaskKey[Seq[ModuleInitializer]]("scalaJSModuleInitializers", diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 5d6f4b6a92..87c0eceb94 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -221,7 +221,7 @@ private[sbtplugin] object ScalaJSPluginInternal { val irContainers = FileScalaJSIRContainer.fromClasspath(classpath) val irFiles = cache.cached(irContainers) Attributed - .blank[Seq[VirtualScalaJSIRFile with RelativeVirtualFile]](irFiles) + .blank[Seq[VirtualScalaJSIRFile]](irFiles) .put(scalaJSSourceFiles, irContainers.map(_.file)) }, From 8e19fa03a8822ce18e9e249c52749e7bd2dc2c98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 1 Apr 2018 22:22:38 +0200 Subject: [PATCH 0690/2665] Fix #3324: Construct a proper URI for ScalaJSEnvHolder.sourceMapPath. In addition, we fully escape it in the Scala string literal. --- project/project/ScalaJSEnvGenerator.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/project/ScalaJSEnvGenerator.scala b/project/project/ScalaJSEnvGenerator.scala index 95dff9a4e5..6837060b17 100644 --- a/project/project/ScalaJSEnvGenerator.scala +++ b/project/project/ScalaJSEnvGenerator.scala @@ -20,7 +20,7 @@ object ScalaJSEnvGenerator { if (!ScalaJSVersions.currentIsSnapshot) s"https://raw.githubusercontent.com/scala-js/scala-js/v${ScalaJSVersions.current}/$relPath" else - env.getAbsolutePath + env.getAbsoluteFile.toURI.toASCIIString } if (!trg.exists() || trg.lastModified() < env.lastModified()) { @@ -34,7 +34,7 @@ object ScalaJSEnvGenerator { private[emitter] object ScalaJSEnvHolder { final val scalajsenv = raw\"\"\"$scalajsenv\"\"\" - final val sourceMapPath = new URI("$sourceMapPath") + final val sourceMapPath = new URI(raw\"\"\"$sourceMapPath\"\"\") } """ From fe7744c1ed6153588c98b1e4142931d6c4daafa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 1 Apr 2018 22:56:57 +0200 Subject: [PATCH 0691/2665] Add basic AppVeyor configuration. We just test that we can run the test suite with the main Scala version, as a sanity check, so that we don't break the Windows build so easily in the future. --- appveyor.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 appveyor.yml diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000000..d3b7eaf4d8 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,21 @@ +version: '{build}' +image: Visual Studio 2015 +environment: + global: + NODEJS_VERSION: "8" + JAVA_HOME: C:\Program Files\Java\jdk1.8.0 + SCALA_VERSION: 2.12.4 +install: + - ps: Install-Product node $env:NODEJS_VERSION + - npm install + - cmd: choco install sbt --version 1.0.2 -ia "INSTALLDIR=""C:\sbt""" + - cmd: SET PATH=C:\sbt\bin;%JAVA_HOME%\bin;%PATH% + - cmd: SET SBT_OPTS=-Xmx4g +build: off +test_script: + # Very far from testing everything, but at least it is a good sanity check + - cmd: sbt ";clean;++%SCALA_VERSION%;testSuite/test" +cache: + - C:\sbt + - C:\Users\appveyor\.ivy2\cache + - C:\Users\appveyor\.sbt From ec0e32badfc7fcfafb70c0fd5a02f423551155d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 31 Mar 2018 15:50:18 +0200 Subject: [PATCH 0692/2665] Get rid of the `Continue` IR node, as well as labels on loops. Where we previously used `continue` statements in the IR, as in: lab: while (cond) { ... if (c) continue lab; ... } We now use a labeled block inside the loop, as well as a return off that labeled block, instead: while (cond) { lab[void]: { ... if (c) return(lab) undefined; ... } } This allows two important simplifications in the IR: * We do not have the `Continue` IR node anymore. * `While` and `DoWhile` loops do not have labels anymore. With those changes, labels are only used by `Labeled` blocks and their corresponding `Return` statements. To prevent some regressions in the quality of the generated .js code, we recover JS `continue` statements out of the above structure in the `FunctionEmitter`. We also received some *improvements* for free, because the `tailPosLabels` can kick in for those labels. --- .../org/scalajs/nscplugin/GenJSCode.scala | 22 +-- .../main/scala/org/scalajs/ir/Hashers.scala | 10 +- .../main/scala/org/scalajs/ir/Printers.scala | 19 +-- .../scala/org/scalajs/ir/Serializers.scala | 17 +- ir/src/main/scala/org/scalajs/ir/Tags.scala | 3 +- .../scala/org/scalajs/ir/Transformers.scala | 10 +- .../scala/org/scalajs/ir/Traversers.scala | 6 +- ir/src/main/scala/org/scalajs/ir/Trees.scala | 11 +- .../scala/org/scalajs/ir/PrintersTest.scala | 23 +-- .../backend/emitter/FunctionEmitter.scala | 160 ++++++++++++++---- .../scalajs/linker/checker/IRChecker.scala | 16 +- .../frontend/optimizer/OptimizerCore.scala | 28 +-- 12 files changed, 167 insertions(+), 158 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala index 12fe4b5e20..ac22132d63 100644 --- a/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala @@ -1958,7 +1958,7 @@ abstract class GenJSCode extends plugins.PluginComponent js.Return(toIRType(expr.tpe) match { case jstpe.NoType => js.Block(genStat(expr), js.Undefined()) case _ => genExpr(expr) - }) + }, None) case t: Try => genTry(t, isStat) @@ -2265,11 +2265,13 @@ abstract class GenJSCode extends plugins.PluginComponent js.Labeled(blockLabelIdent, bodyType, { js.While(js.BooleanLiteral(true), { - if (bodyType == jstpe.NoType) - js.Block(genStat(rhs), js.Return(js.Undefined(), Some(blockLabelIdent))) - else - js.Return(genExpr(rhs), Some(blockLabelIdent)) - }, Some(labelIdent)) + js.Labeled(labelIdent, jstpe.NoType, { + if (bodyType == jstpe.NoType) + js.Block(genStat(rhs), js.Return(js.Undefined(), Some(blockLabelIdent))) + else + js.Return(genExpr(rhs), Some(blockLabelIdent)) + }) + }) }) } } @@ -2712,8 +2714,8 @@ abstract class GenJSCode extends plugins.PluginComponent quadruplets.result() } - // The actual jump (continue labelDefIdent;) - val jump = js.Continue(Some(encodeLabelSym(sym))) + // The actual jump (return(labelDefIdent) undefined;) + val jump = js.Return(js.Undefined(), Some(encodeLabelSym(sym))) quadruplets match { case Nil => jump @@ -3220,9 +3222,9 @@ abstract class GenJSCode extends plugins.PluginComponent val result = translateMatch(retExpr) if (result.tpe == jstpe.NoType) { // Could not actually reproduce this, but better be safe than sorry - js.Block(result, js.Return(js.Undefined())) + js.Block(result, js.Return(js.Undefined(), None)) } else { - js.Return(result) + js.Return(result, None) } case _ => diff --git a/ir/src/main/scala/org/scalajs/ir/Hashers.scala b/ir/src/main/scala/org/scalajs/ir/Hashers.scala index d463ae2873..12bfc430c0 100644 --- a/ir/src/main/scala/org/scalajs/ir/Hashers.scala +++ b/ir/src/main/scala/org/scalajs/ir/Hashers.scala @@ -129,17 +129,15 @@ object Hashers { mixTree(elsep) mixType(tree.tpe) - case While(cond, body, label) => + case While(cond, body) => mixTag(TagWhile) mixTree(cond) mixTree(body) - mixOptIdent(label) - case DoWhile(body, cond, label) => + case DoWhile(body, cond) => mixTag(TagDoWhile) mixTree(body) mixTree(cond) - mixOptIdent(label) case ForIn(obj, keyVar, body) => mixTag(TagForIn) @@ -164,10 +162,6 @@ object Hashers { mixTag(TagThrow) mixTree(expr) - case Continue(label) => - mixTag(TagContinue) - mixOptIdent(label) - case Match(selector, cases, default) => mixTag(TagMatch) mixTree(selector) diff --git a/ir/src/main/scala/org/scalajs/ir/Printers.scala b/ir/src/main/scala/org/scalajs/ir/Printers.scala index e3a2602cfa..615352695d 100644 --- a/ir/src/main/scala/org/scalajs/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/ir/Printers.scala @@ -200,21 +200,13 @@ object Printers { printBlock(elsep) } - case While(cond, body, label) => - if (label.isDefined) { - print(label.get) - print(": ") - } + case While(cond, body) => print("while (") print(cond) print(") ") printBlock(body) - case DoWhile(body, cond, label) => - if (label.isDefined) { - print(label.get) - print(": ") - } + case DoWhile(body, cond) => print("do ") printBlock(body) print(" while (") @@ -257,13 +249,6 @@ object Printers { print("throw ") print(expr) - case Continue(label) => - print("continue") - if (label.isDefined) { - print(' ') - print(label.get) - } - case Match(selector, cases, default) => print("match (") print(selector) diff --git a/ir/src/main/scala/org/scalajs/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/ir/Serializers.scala index e535bd13e8..f1c32465db 100644 --- a/ir/src/main/scala/org/scalajs/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/ir/Serializers.scala @@ -162,13 +162,13 @@ object Serializers { writeTree(cond); writeTree(thenp); writeTree(elsep) writeType(tree.tpe) - case While(cond, body, label) => + case While(cond, body) => writeByte(TagWhile) - writeTree(cond); writeTree(body); writeOptIdent(label) + writeTree(cond); writeTree(body) - case DoWhile(body, cond, label) => + case DoWhile(body, cond) => writeByte(TagDoWhile) - writeTree(body); writeTree(cond); writeOptIdent(label) + writeTree(body); writeTree(cond) case ForIn(obj, keyVar, body) => writeByte(TagForIn) @@ -187,10 +187,6 @@ object Serializers { writeByte(TagThrow) writeTree(expr) - case Continue(label) => - writeByte(TagContinue) - writeOptIdent(label) - case Match(selector, cases, default) => writeByte(TagMatch) writeTree(selector) @@ -845,8 +841,8 @@ object Serializers { case TagAssign => Assign(readTree(), readTree()) case TagReturn => Return(readTree(), readOptIdent()) case TagIf => If(readTree(), readTree(), readTree())(readType()) - case TagWhile => While(readTree(), readTree(), readOptIdent()) - case TagDoWhile => DoWhile(readTree(), readTree(), readOptIdent()) + case TagWhile => While(readTree(), readTree()) + case TagDoWhile => DoWhile(readTree(), readTree()) case TagForIn => ForIn(readTree(), readIdent(), readTree()) case TagTryCatch => @@ -856,7 +852,6 @@ object Serializers { TryFinally(readTree(), readTree()) case TagThrow => Throw(readTree()) - case TagContinue => Continue(readOptIdent()) case TagMatch => Match(readTree(), List.fill(readInt()) { (readTrees().map(_.asInstanceOf[Literal]), readTree()) diff --git a/ir/src/main/scala/org/scalajs/ir/Tags.scala b/ir/src/main/scala/org/scalajs/ir/Tags.scala index 5bc24f0a11..709cf637f4 100644 --- a/ir/src/main/scala/org/scalajs/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/ir/Tags.scala @@ -33,8 +33,7 @@ private[ir] object Tags { final val TagTryCatch = TagForIn + 1 final val TagTryFinally = TagTryCatch + 1 final val TagThrow = TagTryFinally + 1 - final val TagContinue = TagThrow + 1 - final val TagMatch = TagContinue + 1 + final val TagMatch = TagThrow + 1 final val TagDebugger = TagMatch + 1 final val TagNew = TagDebugger + 1 diff --git a/ir/src/main/scala/org/scalajs/ir/Transformers.scala b/ir/src/main/scala/org/scalajs/ir/Transformers.scala index f29eff9902..67412c5f8f 100644 --- a/ir/src/main/scala/org/scalajs/ir/Transformers.scala +++ b/ir/src/main/scala/org/scalajs/ir/Transformers.scala @@ -56,11 +56,11 @@ object Transformers { If(transformExpr(cond), transform(thenp, isStat), transform(elsep, isStat))(tree.tpe) - case While(cond, body, label) => - While(transformExpr(cond), transformStat(body), label) + case While(cond, body) => + While(transformExpr(cond), transformStat(body)) - case DoWhile(body, cond, label) => - DoWhile(transformStat(body), transformExpr(cond), label) + case DoWhile(body, cond) => + DoWhile(transformStat(body), transformExpr(cond)) case ForIn(obj, keyVar, body) => ForIn(transformExpr(obj), keyVar, transformStat(body)) @@ -203,7 +203,7 @@ object Transformers { // Trees that need not be transformed - case _:Skip | _:Continue | _:Debugger | _:LoadModule | _:SelectStatic | + case _:Skip | _:Debugger | _:LoadModule | _:SelectStatic | _:LoadJSConstructor | _:LoadJSModule | _:JSLinkingInfo | _:Literal | _:VarRef | _:This | _:JSGlobalRef | _:Transient => tree diff --git a/ir/src/main/scala/org/scalajs/ir/Traversers.scala b/ir/src/main/scala/org/scalajs/ir/Traversers.scala index 8ea7eee6fb..69effd6380 100644 --- a/ir/src/main/scala/org/scalajs/ir/Traversers.scala +++ b/ir/src/main/scala/org/scalajs/ir/Traversers.scala @@ -45,11 +45,11 @@ object Traversers { traverse(thenp) traverse(elsep) - case While(cond, body, label) => + case While(cond, body) => traverse(cond) traverse(body) - case DoWhile(body, cond, label) => + case DoWhile(body, cond) => traverse(body) traverse(cond) @@ -204,7 +204,7 @@ object Traversers { // Trees that need not be traversed - case _:Skip | _:Continue | _:Debugger | _:LoadModule | _:SelectStatic | + case _:Skip | _:Debugger | _:LoadModule | _:SelectStatic | _:LoadJSConstructor | _:LoadJSModule | _:JSLinkingInfo | _:Literal | _:VarRef | _:This | _:JSGlobalRef | _:Transient => } diff --git a/ir/src/main/scala/org/scalajs/ir/Trees.scala b/ir/src/main/scala/org/scalajs/ir/Trees.scala index b0c605acda..25725ed15d 100644 --- a/ir/src/main/scala/org/scalajs/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/ir/Trees.scala @@ -177,7 +177,7 @@ object Trees { val tpe = NoType // cannot be in expression position } - case class Return(expr: Tree, label: Option[Ident] = None)( + case class Return(expr: Tree, label: Option[Ident])( implicit val pos: Position) extends Tree { val tpe = NothingType } @@ -185,7 +185,7 @@ object Trees { case class If(cond: Tree, thenp: Tree, elsep: Tree)(val tpe: Type)( implicit val pos: Position) extends Tree - case class While(cond: Tree, body: Tree, label: Option[Ident] = None)( + case class While(cond: Tree, body: Tree)( implicit val pos: Position) extends Tree { // cannot be in expression position, unless it is infinite val tpe = cond match { @@ -194,7 +194,7 @@ object Trees { } } - case class DoWhile(body: Tree, cond: Tree, label: Option[Ident] = None)( + case class DoWhile(body: Tree, cond: Tree)( implicit val pos: Position) extends Tree { val tpe = NoType // cannot be in expression position } @@ -216,11 +216,6 @@ object Trees { val tpe = NothingType } - case class Continue(label: Option[Ident] = None)( - implicit val pos: Position) extends Tree { - val tpe = NothingType - } - /** A break-free switch (without fallthrough behavior). * Unlike a JavaScript switch, it can be used in expression position. * It supports alternatives explicitly (hence the List[Tree] in cases), diff --git a/ir/src/test/scala/org/scalajs/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/ir/PrintersTest.scala index b32ccf02aa..a8e022c26a 100644 --- a/ir/src/test/scala/org/scalajs/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/ir/PrintersTest.scala @@ -147,7 +147,7 @@ class PrintersTest { } @Test def printReturn(): Unit = { - assertPrintEquals("return 5", Return(i(5))) + assertPrintEquals("return 5", Return(i(5), None)) assertPrintEquals("return(lab) 5", Return(i(5), Some("lab"))) } @@ -197,14 +197,6 @@ class PrintersTest { |} """, While(b(true), i(5))) - - assertPrintEquals( - """ - |lab: while (true) { - | 5 - |} - """, - While(b(true), i(5), Some("lab"))) } @Test def printDoWhile(): Unit = { @@ -215,14 +207,6 @@ class PrintersTest { |} while (true) """, DoWhile(i(5), b(true))) - - assertPrintEquals( - """ - |lab: do { - | 5 - |} while (true) - """, - DoWhile(i(5), b(true), Some("lab"))) } @Test def printForIn(): Unit = { @@ -273,11 +257,6 @@ class PrintersTest { assertPrintEquals("throw null", Throw(Null())) } - @Test def printContinue(): Unit = { - assertPrintEquals("continue", Continue()) - assertPrintEquals("continue lab", Continue(Some("lab"))) - } - @Test def printMatch(): Unit = { assertPrintEquals( """ diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala index 67e4f26ae0..0e18dfce1a 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala @@ -190,6 +190,51 @@ import Transients._ * `defaultBreakTargets` is property of the *scope*, and is therefore stored * in the environment. * + * Finally, we also recover JavaScript `continue` statements out of labeled + * blocks that are immediately nested in the body of `while` loops. When we + * have: + * + * {{{ + * while (cond) { + * lab: { + * ... + * if (c) + * return(lab) expr; + * ... + * } + * } + * }}} + * + * we make the `while` loop "acquire" the label as its own, and instruct the + * environment that, should an instruction want to return to that label, it + * should use `continue` instead of `break`. This produces: + * + * {{{ + * lab: while (cond) { + * ... + * if (c) + * { expr; continue lab } + * ... + * } + * }}} + * + * Note that the result of `expr` is always discarded, in that case, since the + * labeled block was in statement position (by construction). + * + * Similarly to the treatment with `defaultBreakTargets`, we keep track of + * `defaultContinueTargets`, the set of labels for which we can simply write + * `continue` instead of `continue lab`. This allows the above code to finally + * become: + * + * {{{ + * while (cond) { + * ... + * if (c) + * { expr; continue } + * ... + * } + * }}} + * * @author Sébastien Doeraene */ private[emitter] class FunctionEmitter(jsGen: JSGen) { @@ -419,7 +464,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { val withReturn = if (isStat) body - else Return(body) + else Return(body, None) val translateRestParam = if (esFeatures.useECMAScript2015) false @@ -575,54 +620,77 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { transformExprNoChar(newValue)) } - case While(cond, body, label) => + case While(cond, body) => + /* If there is a Labeled block immediately enclosed within the body + * of this while loop, acquire its label and use it as the while's + * label, turning it into a `continue` label. + */ + val (optLabel, newBody) = { + body match { + case Labeled(label, _, innerBody) => + val innerBodyEnv = env + .withLabeledExprLHS(label, Lhs.Discard) + .withTurnLabelIntoContinue(label.name) + .withDefaultBreakTargets(tailPosLabels) + .withDefaultContinueTargets(Set(label.name)) + val newBody = + pushLhsInto(Lhs.Discard, innerBody, Set(label.name))(innerBodyEnv) + val optLabel = if (usedLabels.contains(label.name)) + Some(transformLabelIdent(label)) + else + None + (optLabel, newBody) + + case _ => + val bodyEnv = env + .withDefaultBreakTargets(tailPosLabels) + .withDefaultContinueTargets(Set.empty) + val newBody = transformStat(body, Set.empty)(bodyEnv) + (None, newBody) + } + } + /* We cannot simply unnest(cond) here, because that would eject the * evaluation of the condition out of the loop. */ - val newLabel = label.map(transformLabelIdent) - val bodyBreakTargets = tailPosLabels ++ label.map(_.name) if (isExpression(cond)) { - js.While(transformExprNoChar(cond), - transformStat(body, Set.empty)( - env.withDefaultBreakTargets(bodyBreakTargets)), - newLabel) + js.While(transformExprNoChar(cond), newBody, optLabel) } else { js.While(js.BooleanLiteral(true), { unnest(cond) { (newCond, env0) => implicit val env = env0 - js.If(transformExprNoChar(newCond), - transformStat(body, Set.empty)( - env.withDefaultBreakTargets(bodyBreakTargets)), - js.Break()) + js.If(transformExprNoChar(newCond), newBody, js.Break()) } - }, newLabel) + }, optLabel) } - case DoWhile(body, cond, label) => + case DoWhile(body, cond) => /* We cannot simply unnest(cond) here, because that would eject the * evaluation of the condition out of the loop. */ - val newLabel = label.map(transformLabelIdent) - val bodyBreakTargets = tailPosLabels ++ label.map(_.name) + val bodyEnv = env + .withDefaultBreakTargets(tailPosLabels) + .withDefaultContinueTargets(Set.empty) + val newBody = transformStat(body, Set.empty)(bodyEnv) if (isExpression(cond)) { - js.DoWhile( - transformStat(body, Set.empty)( - env.withDefaultBreakTargets(bodyBreakTargets)), - transformExprNoChar(cond), newLabel) + /* Here, we could do the same optimization with `continue` as in + * `While` loops (see above), but no Scala source code produces + * patterns where this happens. Therefore, we do not bother. + */ + js.DoWhile(newBody, transformExprNoChar(cond)) } else { - /* This breaks 'continue' statements for this loop, but we don't - * care because we never emit continue statements for do..while - * loops. + /* Since in this rewriting, the old body is not in tail position of + * the emitted do..while body, we cannot optimize an inner Labeled + * block into using `continue` statements. */ js.While(js.BooleanLiteral(true), { js.Block( - transformStat(body, Set.empty)( - env.withDefaultBreakTargets(bodyBreakTargets)), + newBody, unnest(cond) { (newCond, env0) => implicit val env = env0 js.If(transformExprNoChar(newCond), js.Skip(), js.Break()) }) - }, newLabel) + }) } case ForIn(obj, keyVar, body) => @@ -1340,9 +1408,15 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { body } else if (env.isDefaultBreakTarget(l.name)) { js.Block(body, js.Break(None)) + } else if (env.isDefaultContinueTarget(l.name)) { + js.Block(body, js.Continue(None)) } else { usedLabels += l.name - js.Block(body, js.Break(Some(transformLabelIdent(l)))) + val transformedLabel = Some(transformLabelIdent(l)) + val jump = + if (env.isLabelTurnedIntoContinue(l.name)) js.Continue(transformedLabel) + else js.Break(transformedLabel) + js.Block(body, jump) } } @@ -1434,9 +1508,6 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case Return(expr, label) => pushLhsInto(Lhs.Return(label), expr, tailPosLabels) - case Continue(label) => - js.Continue(label.map(transformLabelIdent)) - case If(cond, thenp, elsep) => unnest(cond) { (newCond, env0) => implicit val env = env0 @@ -2737,7 +2808,9 @@ private object FunctionEmitter { val enclosingClassName: Option[String], vars: Map[String, Boolean], labeledExprLHSes: Map[String, Lhs], - defaultBreakTargets: Set[String] + labelsTurnedIntoContinue: Set[String], + defaultBreakTargets: Set[String], + defaultContinueTargets: Set[String] ) { def isLocalVar(ident: Ident): Boolean = vars.contains(ident.name) @@ -2750,9 +2823,15 @@ private object FunctionEmitter { def lhsForLabeledExpr(label: Ident): Lhs = labeledExprLHSes(label.name) + def isLabelTurnedIntoContinue(label: String): Boolean = + labelsTurnedIntoContinue.contains(label) + def isDefaultBreakTarget(label: String): Boolean = defaultBreakTargets.contains(label) + def isDefaultContinueTarget(label: String): Boolean = + defaultContinueTargets.contains(label) + def withEnclosingClassName(enclosingClassName: Option[String]): Env = copy(enclosingClassName = enclosingClassName) @@ -2773,23 +2852,34 @@ private object FunctionEmitter { def withLabeledExprLHS(label: Ident, lhs: Lhs): Env = copy(labeledExprLHSes = labeledExprLHSes + (label.name -> lhs)) + def withTurnLabelIntoContinue(label: String): Env = + copy(labelsTurnedIntoContinue = labelsTurnedIntoContinue + label) + def withDefaultBreakTargets(targets: Set[String]): Env = copy(defaultBreakTargets = targets) + def withDefaultContinueTargets(targets: Set[String]): Env = + copy(defaultContinueTargets = targets) + private def copy( thisIdent: Option[js.Ident] = this.thisIdent, expectedReturnType: Type = this.expectedReturnType, enclosingClassName: Option[String] = this.enclosingClassName, vars: Map[String, Boolean] = this.vars, labeledExprLHSes: Map[String, Lhs] = this.labeledExprLHSes, - defaultBreakTargets: Set[String] = this.defaultBreakTargets): Env = { + labelsTurnedIntoContinue: Set[String] = this.labelsTurnedIntoContinue, + defaultBreakTargets: Set[String] = this.defaultBreakTargets, + defaultContinueTargets: Set[String] = this.defaultContinueTargets): Env = { new Env(thisIdent, expectedReturnType, enclosingClassName, vars, - labeledExprLHSes, defaultBreakTargets) + labeledExprLHSes, labelsTurnedIntoContinue, defaultBreakTargets, + defaultContinueTargets) } } object Env { - def empty(expectedReturnType: Type): Env = - new Env(None, expectedReturnType, None, Map.empty, Map.empty, Set.empty) + def empty(expectedReturnType: Type): Env = { + new Env(None, expectedReturnType, None, Map.empty, Map.empty, Set.empty, + Set.empty, Set.empty) + } } } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala b/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala index 1a543b68d0..5a24b5441f 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala @@ -598,14 +598,12 @@ private final class IRChecker(unit: LinkingUnit, typecheckStat(elsep, env) env - case While(cond, body, label) => - label.foreach(checkDeclareLabel) + case While(cond, body) => typecheckExpect(cond, env, BooleanType) typecheckStat(body, env) env - case DoWhile(body, cond, label) => - label.foreach(checkDeclareLabel) + case DoWhile(body, cond) => typecheckStat(body, env) typecheckExpect(cond, env, BooleanType) env @@ -725,8 +723,7 @@ private final class IRChecker(unit: LinkingUnit, typecheckExpect(thenp, env, tpe) typecheckExpect(elsep, env, tpe) - case While(BooleanLiteral(true), body, label) if tree.tpe == NothingType => - label.foreach(checkDeclareLabel) + case While(BooleanLiteral(true), body) if tree.tpe == NothingType => typecheckStat(body, env) case TryCatch(block, errVar, handler) => @@ -744,13 +741,6 @@ private final class IRChecker(unit: LinkingUnit, case Throw(expr) => typecheckExpr(expr, env) - case Continue(label) => - /* Here we could check that it is indeed legal to break to the - * specified label. However, if we do anything illegal here, it will - * result in a SyntaxError in JavaScript anyway, so we do not really - * care. - */ - case Match(selector, cases, default) => val tpe = tree.tpe typecheckExpr(selector, env) diff --git a/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala b/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala index a598b41305..21dd59827f 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala @@ -385,33 +385,19 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { foldIf(newCond, newThenp, newElsep)(refinedType) } - case While(cond, body, optLabel) => + case While(cond, body) => val newCond = transformExpr(cond) newCond match { case BooleanLiteral(false) => Skip() - case _ => - optLabel match { - case None => - While(newCond, transformStat(body), None) - - case Some(labelIdent @ Ident(label, _)) => - val newLabel = freshLabelName(label) - val info = new LabelInfo(newLabel, acceptRecords = false, - returnedTypes = newSimpleState(Nil)) - While(newCond, { - val bodyScope = scope.withEnv( - scope.env.withLabelInfo(label, info)) - transformStat(body)(bodyScope) - }, Some(Ident(newLabel, None)(labelIdent.pos))) - } + case _ => While(newCond, transformStat(body)) } - case DoWhile(body, cond, None) => + case DoWhile(body, cond) => val newBody = transformStat(body) val newCond = transformExpr(cond) newCond match { case BooleanLiteral(false) => newBody - case _ => DoWhile(newBody, newCond, None) + case _ => DoWhile(newBody, newCond) } case ForIn(obj, keyVar @ Ident(name, originalName), body) => @@ -450,12 +436,6 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case Throw(expr) => Throw(transformExpr(expr)) - case Continue(optLabel) => - val newOptLabel = optLabel map { label => - Ident(scope.env.labelInfos(label.name).newName, None)(label.pos) - } - Continue(newOptLabel) - case Match(selector, cases, default) => val newSelector = transformExpr(selector) newSelector match { From 387273b276a2589e512dbcba4ca0e50e06e9172c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 1 Apr 2018 23:35:37 +0200 Subject: [PATCH 0693/2665] Fix #2751: Fix the definition of `js.Date` for invalid dates. For invalid dates, created from a string that cannot be parsed, the methods of `js.Date` return `NaN`. Therefore, they must be typed as `Double`s. By extension, this covers up for Firefox returning -0 for some valid date as well, instead of +0 like everyone else. In the process, we fix the behavior of `j.u.Date.parse` for invalid inputs. --- javalib/src/main/scala/java/util/Date.scala | 57 ++++++++----- .../main/scala/scala/scalajs/js/Date.scala | 85 ++++++++++--------- .../testsuite/javalib/util/DateTest.scala | 13 ++- 3 files changed, 91 insertions(+), 64 deletions(-) diff --git a/javalib/src/main/scala/java/util/Date.scala b/javalib/src/main/scala/java/util/Date.scala index 484d32d4f7..c74943ed25 100644 --- a/javalib/src/main/scala/java/util/Date.scala +++ b/javalib/src/main/scala/java/util/Date.scala @@ -32,7 +32,14 @@ class Date private (private val date: js.Date) extends Object def this(date: Long) = this(new js.Date(date)) @Deprecated - def this(date: String) = this(new js.Date(date)) + def this(date: String) = { + this({ + val jsDate = new js.Date(date) + if (jsDate.getTime().isNaN) + throw new IllegalArgumentException + jsDate + }) + } def after(when: Date): Boolean = date.getTime() > when.date.getTime() @@ -51,30 +58,30 @@ class Date private (private val date: js.Date) extends Object override def hashCode(): Int = date.getTime().hashCode() @Deprecated - def getDate(): Int = date.getDate() + def getDate(): Int = date.getDate().toInt @Deprecated - def getDay(): Int = date.getDay() + def getDay(): Int = date.getDay().toInt @Deprecated - def getHours(): Int = date.getHours() + def getHours(): Int = date.getHours().toInt @Deprecated - def getMinutes(): Int = date.getMinutes() + def getMinutes(): Int = date.getMinutes().toInt @Deprecated - def getMonth(): Int = date.getMonth() + def getMonth(): Int = date.getMonth().toInt @Deprecated - def getSeconds(): Int = date.getSeconds() + def getSeconds(): Int = date.getSeconds().toInt def getTime(): Long = date.getTime().toLong @Deprecated - def getTimezoneOffset(): Int = date.getTimezoneOffset() + def getTimezoneOffset(): Int = date.getTimezoneOffset().toInt @Deprecated - def getYear(): Int = date.getFullYear() - 1900 + def getYear(): Int = date.getFullYear().toInt - 1900 @Deprecated def setDate(date: Int): Unit = this.date.setDate(date) @@ -98,28 +105,28 @@ class Date private (private val date: js.Date) extends Object @Deprecated def toGMTString(): String = { - date.getUTCDate() + " " + Months(date.getUTCMonth()) + " " + - date.getUTCFullYear() + " " + pad0(date.getUTCHours()) + ":" + - pad0(date.getUTCMinutes()) + ":" + - pad0(date.getUTCSeconds()) +" GMT" + date.getUTCDate().toInt + " " + Months(date.getUTCMonth().toInt) + " " + + date.getUTCFullYear().toInt + " " + pad0(date.getUTCHours().toInt) + ":" + + pad0(date.getUTCMinutes().toInt) + ":" + + pad0(date.getUTCSeconds().toInt) +" GMT" } @Deprecated def toLocaleString(): String = { - date.getDate() + "-" + Months(date.getMonth()) + "-" + - date.getFullYear() + "-" + pad0(date.getHours()) + ":" + - pad0(date.getMinutes()) + ":" + pad0(date.getSeconds()) + date.getDate().toInt + "-" + Months(date.getMonth().toInt) + "-" + + date.getFullYear().toInt + "-" + pad0(date.getHours().toInt) + ":" + + pad0(date.getMinutes().toInt) + ":" + pad0(date.getSeconds().toInt) } override def toString(): String = { - val offset = -date.getTimezoneOffset() + val offset = -date.getTimezoneOffset().toInt val sign = if (offset < 0) "-" else "+" val hours = pad0(Math.abs(offset) / 60) val mins = pad0(Math.abs(offset) % 60) - Days(date.getDay()) + " "+ Months(date.getMonth()) + " " + - pad0(date.getDate()) + " " + pad0(date.getHours()) + ":" + - pad0(date.getMinutes()) + ":" + pad0(date.getSeconds()) + " GMT" + " " + - date.getFullYear() + Days(date.getDay().toInt) + " "+ Months(date.getMonth().toInt) + " " + + pad0(date.getDate().toInt) + " " + pad0(date.getHours().toInt) + ":" + + pad0(date.getMinutes().toInt) + ":" + pad0(date.getSeconds().toInt) + + " GMT" + " " + date.getFullYear().toInt } } @@ -142,6 +149,10 @@ object Date { js.Date.UTC(year + 1900, month, date, hrs, min, sec).toLong @Deprecated - def parse(string: String): Long = - new Date(new js.Date(string)).getTime.toLong + def parse(string: String): Long = { + val time = new js.Date(string).getTime() + if (time.isNaN) + throw new IllegalArgumentException + time.toLong + } } diff --git a/library/src/main/scala/scala/scalajs/js/Date.scala b/library/src/main/scala/scala/scalajs/js/Date.scala index 1f52f11ec9..c32842d0e2 100644 --- a/library/src/main/scala/scala/scalajs/js/Date.scala +++ b/library/src/main/scala/scala/scalajs/js/Date.scala @@ -23,6 +23,12 @@ import scala.scalajs.js.annotation._ * since 1 January, 1970 UTC. * * MDN + * + * @note + * `js.Date` objects can represent an *invalid date*, for example, if they + * are constructed from a `String` that cannot be parsed as a date. Most + * methods of such a `js.Date` will return `NaN` (for those returning a + * `Double`) or other invalid values. */ @js.native @JSGlobal @@ -48,141 +54,144 @@ class Date extends js.Object { * * MDN */ - def getFullYear(): Int = js.native + def getFullYear(): Double = js.native /** * Returns the year (4 digits for 4-digit years) in the specified date according to universal time. * * MDN */ - def getUTCFullYear(): Int = js.native + def getUTCFullYear(): Double = js.native /** * Returns the month (0-11) in the specified date according to local time. * * MDN */ - def getMonth(): Int = js.native + def getMonth(): Double = js.native /** * Returns the month (0-11) in the specified date according to universal time. * * MDN */ - def getUTCMonth(): Int = js.native + def getUTCMonth(): Double = js.native /** * Returns the day of the month (1-31) for the specified date according to local time. * * MDN */ - def getDate(): Int = js.native + def getDate(): Double = js.native /** * Returns the day (date) of the month (1-31) in the specified date according to universal time. * * MDN */ - def getUTCDate(): Int = js.native + def getUTCDate(): Double = js.native /** * Returns the day of the week (0-6) for the specified date according to local time. * * MDN */ - def getDay(): Int = js.native + def getDay(): Double = js.native /** * Returns the day of the week (0-6) in the specified date according to universal time. * MDN */ - def getUTCDay(): Int = js.native + def getUTCDay(): Double = js.native /** * Returns the hour (0-23) in the specified date according to local time. * * MDN */ - def getHours(): Int = js.native + def getHours(): Double = js.native /** * Returns the hours (0-23) in the specified date according to universal time. * * MDN */ - def getUTCHours(): Int = js.native + def getUTCHours(): Double = js.native /** * Returns the minutes (0-59) in the specified date according to local time. * * MDN */ - def getMinutes(): Int = js.native + def getMinutes(): Double = js.native /** * Returns the minutes (0-59) in the specified date according to universal time. * * MDN */ - def getUTCMinutes(): Int = js.native + def getUTCMinutes(): Double = js.native /** * Returns the seconds (0-59) in the specified date according to local time. * * MDN */ - def getSeconds(): Int = js.native + def getSeconds(): Double = js.native /** * Returns the seconds (0-59) in the specified date according to universal time. * * MDN */ - def getUTCSeconds(): Int = js.native + def getUTCSeconds(): Double = js.native /** * Returns the milliseconds (0-999) in the specified date according to local time. * * MDN */ - def getMilliseconds(): Int = js.native + def getMilliseconds(): Double = js.native /** * Returns the milliseconds (0-999) in the specified date according to universal time. * * MDN */ - def getUTCMilliseconds(): Int = js.native + def getUTCMilliseconds(): Double = js.native /** * Returns the time-zone offset in minutes for the current locale. * * MDN */ - def getTimezoneOffset(): Int = js.native + def getTimezoneOffset(): Double = js.native def setTime(time: Double): Unit = js.native - def setMilliseconds(ms: Int): Unit = js.native - def setUTCMilliseconds(ms: Int): Unit = js.native - def setSeconds(sec: Int, ms: Int = getMilliseconds()): Unit = js.native - def setUTCSeconds(sec: Int, ms: Int = getMilliseconds()): Unit = js.native - def setMinutes(min: Int, sec: Int = getSeconds(), - ms: Int = getMilliseconds()): Unit = js.native - def setUTCMinutes(min: Int, sec: Int = getSeconds(), - ms: Int = getMilliseconds()): Unit = js.native - def setHours(hours: Int, min: Int = getMinutes(), - sec: Int = getSeconds(), ms: Int = getMilliseconds()): Unit = js.native - def setUTCHours(hours: Int, min: Int = getMinutes(), - sec: Int = getSeconds(), ms: Int = getMilliseconds()): Unit = js.native - - def setDate(date: Int): Unit = js.native - def setUTCDate(date: Int): Unit = js.native - def setMonth(month: Int, date: Int = getDate()): Unit = js.native - def setUTCMonth(month: Int, date: Int = getDate()): Unit = js.native - def setFullYear(year: Int, month: Int = getMonth(), - date: Int = getDate()): Unit = js.native - def setUTCFullYear(year: Int, month: Int = getMonth(), - date: Int = getDate()): Unit = js.native + def setMilliseconds(ms: Double): Unit = js.native + def setUTCMilliseconds(ms: Double): Unit = js.native + def setSeconds(sec: Double, ms: Double = getMilliseconds()): Unit = js.native + def setUTCSeconds(sec: Double, + ms: Double = getMilliseconds()): Unit = js.native + def setMinutes(min: Double, sec: Double = getSeconds(), + ms: Double = getMilliseconds()): Unit = js.native + def setUTCMinutes(min: Double, sec: Double = getSeconds(), + ms: Double = getMilliseconds()): Unit = js.native + def setHours(hours: Double, min: Double = getMinutes(), + sec: Double = getSeconds(), + ms: Double = getMilliseconds()): Unit = js.native + def setUTCHours(hours: Double, min: Double = getMinutes(), + sec: Double = getSeconds(), + ms: Double = getMilliseconds()): Unit = js.native + + def setDate(date: Double): Unit = js.native + def setUTCDate(date: Double): Unit = js.native + def setMonth(month: Double, date: Double = getDate()): Unit = js.native + def setUTCMonth(month: Double, date: Double = getDate()): Unit = js.native + def setFullYear(year: Double, month: Double = getMonth(), + date: Double = getDate()): Unit = js.native + def setUTCFullYear(year: Double, month: Double = getMonth(), + date: Double = getDate()): Unit = js.native def toUTCString(): String = js.native def toISOString(): String = js.native diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/DateTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/DateTest.scala index dca8e11a1b..82bffecd45 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/DateTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/DateTest.scala @@ -12,6 +12,8 @@ import java.util.Date import org.junit.Assert._ import org.junit.Test +import org.scalajs.testsuite.utils.AssertThrows._ + /** * tests the implementation of the java standard library Date */ @@ -41,12 +43,17 @@ class DateTest { } @Test def parseStrings(): Unit = { - def test(s: String, v: Date): Unit = + def test(s: String, v: Date): Unit = { assertEquals(0, new Date(s).compareTo(v)) + assertEquals(0, Date.parse(s).compareTo(v.getTime)) + } test("Nov 5 1997 5:23:27 GMT", new Date(Date.UTC(97, 10, 5, 5, 23, 27))) - test("Nov 1 1997 GMT", new Date(Date.UTC(97,10,1, 0, 0, 0))) - test("Jan 1 1970 18:11:01 GMT", new Date(Date.UTC(70,0,1,18,11,1))) + test("Nov 1 1997 GMT", new Date(Date.UTC(97, 10, 1, 0, 0, 0))) + test("Jan 1 1970 18:11:01 GMT", new Date(Date.UTC(70, 0, 1, 18, 11, 1))) + + assertThrows(classOf[IllegalArgumentException], new Date("not a date")) + assertThrows(classOf[IllegalArgumentException], Date.parse("not a date")) } @Test def after(): Unit = { From f6c29e313c2d07d05c049f9f11e790a855bbc6d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 2 Apr 2018 22:05:07 +0200 Subject: [PATCH 0694/2665] Fix the way the bootstrap test prepares `testSuite/test:fastOptJS`. Since b9ec4ee06a26b895f168c3ecdbae5b9724beb447, it is basically invalid to call `testSuite/test:fastOptJS` if `scalaJSStage in testSuite` is `FullOptStage`, and conversely. It didn't cause any hard failure, but was ill-advised since the blacklisting would not be applied appropriately. The bootstrap test was erroneously doing just that. This commit fixes that test, and adds a check in the test suite settings to make sure no one tries to do that anymore. --- Jenkinsfile | 13 +++++++++++-- project/Build.scala | 21 +++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 7602e59419..2fcf43820b 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -229,17 +229,26 @@ def Tasks = [ ++$scala $testSuite/test ''', + /* The reason we do `testSuite/test:fastOptJS` is that the linker tests will + * need the "discovered tests" from the test suite, which means we need to + * fast-optimize the test suite. We explicitly do it beforehand, so that the + * memory necessary to do that is not accumulated with the rest of the tests. + * Moreover, for the bootstrap tests to be able to call + * `testSuite/test:fastOptJS`, `scalaJSStage in testSuite` must be + * `FastOptStage`, even when `scalaJSStage in Global` is `FullOptStage`. + */ "bootstrap": ''' setJavaVersion $java npm install && + sbt ++$scala testSuite/test:fastOptJS && sbt ++$scala linker/test && sbt ++$scala irJS/test ioJS/test linkerJS/test && sbt 'set scalaJSStage in Global := FullOptStage' \ + 'set scalaJSStage in testSuite := FastOptStage' \ ++$scala irJS/test ioJS/test linkerJS/test && - sbt ++$scala testSuite/test:fastOptJS && sbt ++$scala linkerJS/bootstrapTest && - sbt ++$scala testSuite/test:fullOptJS && sbt 'set scalaJSStage in Global := FullOptStage' \ + 'set scalaJSStage in testSuite := FastOptStage' \ ++$scala linkerJS/bootstrapTest && sbt ++$scala irJS/mimaReportBinaryIssues ioJS/mimaReportBinaryIssues \ loggingJS/mimaReportBinaryIssues linkerJS/mimaReportBinaryIssues diff --git a/project/Build.scala b/project/Build.scala index a4c92bdd86..0e9c9e8192 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1654,6 +1654,27 @@ object Build { } }, + /* Because of the above tweak of `sources` depending on the value of + * `scalaJSStage`, it is ill-advised to invoke a linking task that does + * not correspond to the current `scalaJSStage`. + */ + for ((key, stage) <- Seq(fastOptJS -> FastOptStage, fullOptJS -> FullOptStage)) yield { + key in Test := { + /* Note that due to the way dependencies between tasks work, the + * actual linking *will* be computed anyway, but it's not too late to + * prevent the user from doing anything meaningful with it + * afterwards. + */ + val actual = (key in Test).value + if (scalaJSStage.value != stage) { + throw new MessageOnlyException( + s"testSuite/test:${key.key} can only be invoked when " + + s"(scalaJSStage in testSuite).value is $stage") + } + actual + } + }, + // Module initializers. Duplicated in toolsJS/test scalaJSModuleInitializers += { ModuleInitializer.mainMethod( From 94a4ce5142abb101450ee93b28f63ef3da63fe74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 2 Apr 2018 22:27:47 +0200 Subject: [PATCH 0695/2665] Add `logging/clean` and `loggingJS/clean` to the mega `clean`. They were forgotten when those two projects were introduced. --- project/Build.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/project/Build.scala b/project/Build.scala index 0e9c9e8192..c3201d828f 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -506,6 +506,7 @@ object Build { clean in compiler, clean in irProject, clean in irProjectJS, clean in io, clean in ioJS, + clean in logging, clean in loggingJS, clean in linker, clean in linkerJS, clean in jsEnvs, clean in jsEnvsTestKit, clean in nodeJSEnv, clean in testAdapter, clean in plugin, From c61d78daf913174f0e26b7f99a881071cb00d587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 31 Mar 2018 19:25:18 +0200 Subject: [PATCH 0696/2665] Make the label of `Return` nodes mandatory. A `Return` with a `None` label implicitly meant returning from the enclosing `Closure` or `MethodDef`. In the spirit of solving all problems with `Labeled` blocks, we can get rid of this special-case by introducing an explicit function-wide `Labeled` block when necessary. Instead of emitting: def foo__I(): int = { ... if (c) return 5 ... } we would now use def foo__I(): int = { _return[int]: { ... if (c) return@_return 5 ... } } which is equivalent. This complicates somewhat the compiler back-end, since it now needs to take care of adding that label if necessary (it could *always* add one, but that would not be nice, and defeat most of the purpose of this change), and it does not really simplify anything later in the pipeline either. Moreover, we observe a slight regression of quality of generated .js code in some rare cases: when there is a `return` in a `void`-returning method, and that method is not inlined, the `FunctionEmitter` cannot replace the `break _return` by a `return` in JS. This is due to a technicality in `FunctionEmitter`, and this restriction could be lifted in the future. The main benefits are more regular IR, as well as a potential performance improvement in the optimizer. Indeed, previously, every time we inlined a method, we needed to preemptively summon a lot of complicated machinery to introduce a label in case the body contains a `return`. In most cases, it doesn't, and we detect after the fact that the label is useless and can be removed. Instead, we can now straightforwardly process the body without any extra action. In the rare cases where the body did contain a `return`, the optimizer will encounter the `Labeled` block, and spawn the machinery then. In all the other cases, the machinery is completely by-passed. --- .../org/scalajs/nscplugin/GenJSCode.scala | 32 ++++++---- .../org/scalajs/nscplugin/JSEncoding.scala | 28 ++++++++- .../main/scala/org/scalajs/ir/Hashers.scala | 2 +- .../main/scala/org/scalajs/ir/Printers.scala | 13 ++-- .../scala/org/scalajs/ir/Serializers.scala | 4 +- ir/src/main/scala/org/scalajs/ir/Trees.scala | 2 +- .../scala/org/scalajs/ir/PrintersTest.scala | 3 +- .../backend/emitter/FunctionEmitter.scala | 26 ++++---- .../scalajs/linker/checker/IRChecker.scala | 14 ++--- .../frontend/optimizer/OptimizerCore.scala | 61 +++++++++---------- 10 files changed, 103 insertions(+), 82 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala index ac22132d63..e21147e127 100644 --- a/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala @@ -1716,7 +1716,7 @@ abstract class GenJSCode extends plugins.PluginComponent val bodyIsStat = resultIRType == jstpe.NoType - def genBody() = tree match { + def genBodyWithinReturnableScope(): js.Tree = tree match { case Block( (thisDef @ ValDef(_, nme.THIS, _, initialThis)) :: otherStats, rhs) => @@ -1793,6 +1793,12 @@ abstract class GenJSCode extends plugins.PluginComponent else genExpr(tree) } + def genBody(): js.Tree = { + withNewReturnableScope(resultIRType) { + genBodyWithinReturnableScope() + } + } + if (!isNonNativeJSClass(currentClassSym) || isRawJSFunctionDef(currentClassSym)) { val body = { @@ -1958,7 +1964,7 @@ abstract class GenJSCode extends plugins.PluginComponent js.Return(toIRType(expr.tpe) match { case jstpe.NoType => js.Block(genStat(expr), js.Undefined()) case _ => genExpr(expr) - }, None) + }, getEnclosingReturnLabel()) case t: Try => genTry(t, isStat) @@ -2267,9 +2273,9 @@ abstract class GenJSCode extends plugins.PluginComponent js.While(js.BooleanLiteral(true), { js.Labeled(labelIdent, jstpe.NoType, { if (bodyType == jstpe.NoType) - js.Block(genStat(rhs), js.Return(js.Undefined(), Some(blockLabelIdent))) + js.Block(genStat(rhs), js.Return(js.Undefined(), blockLabelIdent)) else - js.Return(genExpr(rhs), Some(blockLabelIdent)) + js.Return(genExpr(rhs), blockLabelIdent) }) }) }) @@ -2634,7 +2640,7 @@ abstract class GenJSCode extends plugins.PluginComponent * labeled block surrounding the match. */ countsOfReturnsToMatchEnd(sym) += 1 - js.Return(genExpr(args.head), Some(encodeLabelSym(sym))) + js.Return(genExpr(args.head), encodeLabelSym(sym)) } else { /* No other label apply should ever happen. If it does, then we * have missed a pattern of LabelDef/LabelApply and some new @@ -2715,7 +2721,7 @@ abstract class GenJSCode extends plugins.PluginComponent } // The actual jump (return(labelDefIdent) undefined;) - val jump = js.Return(js.Undefined(), Some(encodeLabelSym(sym))) + val jump = js.Return(js.Undefined(), encodeLabelSym(sym)) quadruplets match { case Nil => jump @@ -3078,7 +3084,7 @@ abstract class GenJSCode extends plugins.PluginComponent def genJumpToElseClause(implicit pos: ir.Position): js.Tree = { if (optElseClauseLabel.isEmpty) optElseClauseLabel = Some(freshLocalIdent("default")) - js.Return(js.Undefined(), optElseClauseLabel) + js.Return(js.Undefined(), optElseClauseLabel.get) } for (caze @ CaseDef(pat, guard, body) <- cases) { @@ -3160,10 +3166,9 @@ abstract class GenJSCode extends plugins.PluginComponent val matchResultLabel = freshLocalIdent("matchResult") val patchedClauses = for ((alts, body) <- clauses) yield { implicit val pos = body.pos - val lab = Some(matchResultLabel) val newBody = - if (isStat) js.Block(body, js.Return(js.Undefined(), lab)) - else js.Return(body, lab) + if (isStat) js.Block(body, js.Return(js.Undefined(), matchResultLabel)) + else js.Return(body, matchResultLabel) (alts, newBody) } js.Labeled(matchResultLabel, resultType, js.Block(List( @@ -3220,11 +3225,12 @@ abstract class GenJSCode extends plugins.PluginComponent // Peculiar shape generated by `return x match {...}` - #2928 case Return(retExpr: LabelDef) if isCaseLabelDef(retExpr) => val result = translateMatch(retExpr) + val label = getEnclosingReturnLabel() if (result.tpe == jstpe.NoType) { // Could not actually reproduce this, but better be safe than sorry - js.Block(result, js.Return(js.Undefined(), None)) + js.Block(result, js.Return(js.Undefined(), label)) } else { - js.Return(result, None) + js.Return(result, label) } case _ => @@ -3354,7 +3360,7 @@ abstract class GenJSCode extends plugins.PluginComponent if (revAlts.size == returnCount - 1) { def tryDropReturn(body: js.Tree): Option[js.Tree] = body match { - case jse.BlockOrAlone(prep, js.Return(result, Some(`label`))) => + case jse.BlockOrAlone(prep, js.Return(result, `label`)) => Some(js.Block(prep :+ result)(body.pos)) case _ => diff --git a/compiler/src/main/scala/org/scalajs/nscplugin/JSEncoding.scala b/compiler/src/main/scala/org/scalajs/nscplugin/JSEncoding.scala index 6527c9a79d..729971d93a 100644 --- a/compiler/src/main/scala/org/scalajs/nscplugin/JSEncoding.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/JSEncoding.scala @@ -12,7 +12,7 @@ import scala.tools.nsc._ import org.scalajs.ir import ir.{Trees => js, Types => jstpe} -import util.ScopedVar +import util.{ScopedVar, VarBox} import ScopedVar.withScopedVars /** Encoding of symbol names for JavaScript @@ -59,6 +59,7 @@ trait JSEncoding extends SubComponent { self: GenJSCode => // Fresh local name generator ---------------------------------------------- private val usedLocalNames = new ScopedVar[mutable.Set[String]] + private val returnLabelName = new ScopedVar[VarBox[Option[String]]] private val localSymbolNames = new ScopedVar[mutable.Map[Symbol, String]] private val isReserved = Set("arguments", "eval", ScalaJSEnvironmentName) @@ -66,6 +67,7 @@ trait JSEncoding extends SubComponent { self: GenJSCode => def withNewLocalNameScope[A](body: => A): A = { withScopedVars( usedLocalNames := mutable.Set.empty, + returnLabelName := null, localSymbolNames := mutable.Map.empty )(body) } @@ -77,6 +79,21 @@ trait JSEncoding extends SubComponent { self: GenJSCode => usedLocalNames += name } + def withNewReturnableScope(tpe: jstpe.Type)(body: => js.Tree)( + implicit pos: ir.Position): js.Tree = { + withScopedVars( + returnLabelName := new VarBox(None) + ) { + val inner = body + returnLabelName.get.value match { + case None => + inner + case Some(labelName) => + js.Labeled(js.Ident(labelName), tpe, inner) + } + } + } + private def freshName(base: String = "x"): String = { var suffix = 1 var longName = base @@ -97,6 +114,15 @@ trait JSEncoding extends SubComponent { self: GenJSCode => private def localSymbolName(sym: Symbol): String = localSymbolNames.getOrElseUpdate(sym, freshName(sym.name.toString)) + def getEnclosingReturnLabel()(implicit pos: ir.Position): js.Ident = { + val box = returnLabelName.get + if (box == null) + throw new IllegalStateException(s"No enclosing returnable scope at $pos") + if (box.value.isEmpty) + box.value = Some(freshName("_return")) + js.Ident(box.value.get) + } + // Encoding methods ---------------------------------------------------------- def encodeLabelSym(sym: Symbol)(implicit pos: Position): js.Ident = { diff --git a/ir/src/main/scala/org/scalajs/ir/Hashers.scala b/ir/src/main/scala/org/scalajs/ir/Hashers.scala index 12bfc430c0..e655fc04ae 100644 --- a/ir/src/main/scala/org/scalajs/ir/Hashers.scala +++ b/ir/src/main/scala/org/scalajs/ir/Hashers.scala @@ -120,7 +120,7 @@ object Hashers { case Return(expr, label) => mixTag(TagReturn) mixTree(expr) - mixOptIdent(label) + mixIdent(label) case If(cond, thenp, elsep) => mixTag(TagIf) diff --git a/ir/src/main/scala/org/scalajs/ir/Printers.scala b/ir/src/main/scala/org/scalajs/ir/Printers.scala index 615352695d..2eac8f7bfd 100644 --- a/ir/src/main/scala/org/scalajs/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/ir/Printers.scala @@ -164,15 +164,10 @@ object Printers { print(rhs) case Return(expr, label) => - if (label.isEmpty) { - print("return ") - print(expr) - } else { - print("return(") - print(label.get) - print(") ") - print(expr) - } + print("return@") + print(label) + print(" ") + print(expr) case If(cond, BooleanLiteral(true), elsep) => print(cond) diff --git a/ir/src/main/scala/org/scalajs/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/ir/Serializers.scala index f1c32465db..930435e7d6 100644 --- a/ir/src/main/scala/org/scalajs/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/ir/Serializers.scala @@ -155,7 +155,7 @@ object Serializers { case Return(expr, label) => writeByte(TagReturn) - writeTree(expr); writeOptIdent(label) + writeTree(expr); writeIdent(label) case If(cond, thenp, elsep) => writeByte(TagIf) @@ -839,7 +839,7 @@ object Serializers { case TagBlock => Block(readTrees()) case TagLabeled => Labeled(readIdent(), readType(), readTree()) case TagAssign => Assign(readTree(), readTree()) - case TagReturn => Return(readTree(), readOptIdent()) + case TagReturn => Return(readTree(), readIdent()) case TagIf => If(readTree(), readTree(), readTree())(readType()) case TagWhile => While(readTree(), readTree()) case TagDoWhile => DoWhile(readTree(), readTree()) diff --git a/ir/src/main/scala/org/scalajs/ir/Trees.scala b/ir/src/main/scala/org/scalajs/ir/Trees.scala index 25725ed15d..c12d6b8f2d 100644 --- a/ir/src/main/scala/org/scalajs/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/ir/Trees.scala @@ -177,7 +177,7 @@ object Trees { val tpe = NoType // cannot be in expression position } - case class Return(expr: Tree, label: Option[Ident])( + case class Return(expr: Tree, label: Ident)( implicit val pos: Position) extends Tree { val tpe = NothingType } diff --git a/ir/src/test/scala/org/scalajs/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/ir/PrintersTest.scala index a8e022c26a..e7031b1e32 100644 --- a/ir/src/test/scala/org/scalajs/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/ir/PrintersTest.scala @@ -147,8 +147,7 @@ class PrintersTest { } @Test def printReturn(): Unit = { - assertPrintEquals("return 5", Return(i(5), None)) - assertPrintEquals("return(lab) 5", Return(i(5), Some("lab"))) + assertPrintEquals("return@lab 5", Return(i(5), "lab")) } @Test def printIf(): Unit = { diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala index 0e18dfce1a..bbf561d042 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala @@ -462,10 +462,6 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { val env = env0.withParams(params) - val withReturn = - if (isStat) body - else Return(body, None) - val translateRestParam = if (esFeatures.useECMAScript2015) false else params.nonEmpty && params.last.rest @@ -477,13 +473,17 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { val newParams = (if (translateRestParam) params.init else params).map(transformParamDef) - val newBody = transformStat(withReturn, Set.empty)(env) match { + val newBody = + if (isStat) transformStat(body, Set.empty)(env) + else pushLhsInto(Lhs.ReturnFromFunction, body, Set.empty)(env) + + val cleanedNewBody = newBody match { case js.Block(stats :+ js.Return(js.Undefined())) => js.Block(stats) case other => other } js.Function(arrow && useArrowFunctions, newParams, - js.Block(extractRestParam, newBody)) + js.Block(extractRestParam, cleanedNewBody)) } private def makeExtractRestParam(params: List[ParamDef])( @@ -1455,9 +1455,9 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { doVarDef(name, tpe, mutable, rhs) case Lhs.Assign(lhs) => doAssign(lhs, rhs) - case Lhs.Return(None) => + case Lhs.ReturnFromFunction => js.Return(transformExpr(rhs, env.expectedReturnType)) - case Lhs.Return(Some(l)) => + case Lhs.Return(l) => doReturnToLabel(l) } @@ -1485,10 +1485,10 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { js.Block(varDef, assign) } - case Lhs.Return(None) => + case Lhs.ReturnFromFunction => throw new AssertionError("Cannot return a record value.") - case Lhs.Return(Some(l)) => + case Lhs.Return(l) => doReturnToLabel(l) } @@ -2792,7 +2792,11 @@ private object FunctionEmitter { case class Assign(lhs: Tree) extends Lhs case class VarDef(name: Ident, tpe: Type, mutable: Boolean) extends Lhs - case class Return(label: Option[Ident]) extends Lhs { + case object ReturnFromFunction extends Lhs { + override def hasNothingType: Boolean = true + } + + case class Return(label: Ident) extends Lhs { override def hasNothingType: Boolean = true } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala b/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala index 5a24b5441f..b15a140efe 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala @@ -710,7 +710,7 @@ private final class IRChecker(unit: LinkingUnit, typecheckExpect(body, env.withLabeledReturnType(label.name, tpe), tpe) case Return(expr, label) => - env.returnTypes.get(label.map(_.name)).fold[Unit] { + env.returnTypes.get(label.name).fold[Unit] { reportError(s"Cannot return to label $label.") typecheckExpr(expr, env) } { returnType => @@ -1277,7 +1277,7 @@ private final class IRChecker(unit: LinkingUnit, /** Local variables in scope (including through closures). */ val locals: Map[String, LocalDef], /** Return types by label. */ - val returnTypes: Map[Option[String], Type], + val returnTypes: Map[String, Type], /** Whether we're in a constructor of the class */ val inConstructor: Boolean ) { @@ -1291,13 +1291,9 @@ private final class IRChecker(unit: LinkingUnit, this.inConstructor) } - def withReturnType(returnType: Type): Env = - new Env(this.thisTpe, this.locals, - returnTypes + (None -> returnType), this.inConstructor) - def withLabeledReturnType(label: String, returnType: Type): Env = new Env(this.thisTpe, this.locals, - returnTypes + (Some(label) -> returnType), this.inConstructor) + returnTypes + (label -> returnType), this.inConstructor) def withInConstructor(inConstructor: Boolean): Env = new Env(this.thisTpe, this.locals, this.returnTypes, inConstructor) @@ -1313,9 +1309,7 @@ private final class IRChecker(unit: LinkingUnit, val paramLocalDefs = for (p @ ParamDef(ident, tpe, mutable, _) <- allParams) yield ident.name -> LocalDef(ident.name, tpe, mutable)(p.pos) - new Env(thisType, paramLocalDefs.toMap, - Map(None -> (if (resultType == NoType) AnyType else resultType)), - isConstructor) + new Env(thisType, paramLocalDefs.toMap, Map.empty, isConstructor) } } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala b/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala index 21dd59827f..63299c2088 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala @@ -288,7 +288,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case Labeled(ident @ Ident(label, _), tpe, body) => trampoline { - returnable(label, if (isStat) NoType else tpe, body, isStat, + pretransformLabeled(label, if (isStat) NoType else tpe, body, isStat, usePreTransform = false)(finishTransform(isStat)) } @@ -342,31 +342,22 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { } } - case Return(expr, optLabel) => - val optInfo = optLabel match { - case Some(Ident(label, _)) => - Some(scope.env.labelInfos(label)) - case None => - scope.env.labelInfos.get("") - } - optInfo.fold[Tree] { - Return(transformExpr(expr), None) - } { info => - val newOptLabel = Some(Ident(info.newName, None)) - if (!info.acceptRecords) { - val newExpr = transformExpr(expr) - info.returnedTypes.value ::= (newExpr.tpe, RefinedType(newExpr.tpe)) - Return(newExpr, newOptLabel) - } else trampoline { - pretransformNoLocalDef(expr) { texpr => - texpr match { - case PreTransRecordTree(newExpr, origType, cancelFun) => - info.returnedTypes.value ::= (newExpr.tpe, origType) - TailCalls.done(Return(newExpr, newOptLabel)) - case PreTransTree(newExpr, tpe) => - info.returnedTypes.value ::= (newExpr.tpe, tpe) - TailCalls.done(Return(newExpr, newOptLabel)) - } + case Return(expr, label) => + val info = scope.env.labelInfos(label.name) + val newLabel = Ident(info.newName, None) + if (!info.acceptRecords) { + val newExpr = transformExpr(expr) + info.returnedTypes.value ::= (newExpr.tpe, RefinedType(newExpr.tpe)) + Return(newExpr, newLabel) + } else trampoline { + pretransformNoLocalDef(expr) { texpr => + texpr match { + case PreTransRecordTree(newExpr, origType, cancelFun) => + info.returnedTypes.value ::= (newExpr.tpe, origType) + TailCalls.done(Return(newExpr, newLabel)) + case PreTransTree(newExpr, tpe) => + info.returnedTypes.value ::= (newExpr.tpe, tpe) + TailCalls.done(Return(newExpr, newLabel)) } } } @@ -804,7 +795,8 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { } case Labeled(ident @ Ident(label, _), tpe, body) => - returnable(label, tpe, body, isStat = false, usePreTransform = true)(cont) + pretransformLabeled(label, tpe, body, isStat = false, + usePreTransform = true)(cont) case New(cls, ctor, args) => pretransformExprs(args) { targs => @@ -1924,8 +1916,13 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { } withBindings(optReceiverBinding ++: argsBindings) { (bodyScope, cont1) => - returnable("", resultType, body, isStat, usePreTransform)( - cont1)(bodyScope, pos) + implicit val scope = bodyScope + if (usePreTransform) { + assert(!isStat, "Cannot use pretransform in statement position") + pretransformExpr(body)(cont1) + } else { + cont1(PreTransTree(transform(body, isStat))) + } } (cont) (scope.withEnv(OptEnv.Empty)) } @@ -3930,7 +3927,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { (newParamDefs, newBody) } - private def returnable(oldLabelName: String, resultType: Type, + private def pretransformLabeled(oldLabelName: String, resultType: Type, body: Tree, isStat: Boolean, usePreTransform: Boolean)( cont: PreTransCont)( implicit scope: Scope, pos: Position): TailRec[Tree] = tailcall { @@ -3991,7 +3988,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { } } (bodyScope) } { () => - returnable(oldLabelName, resultType, body, isStat, + pretransformLabeled(oldLabelName, resultType, body, isStat, usePreTransform = false)(cont) } } else { @@ -4032,7 +4029,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { if (revAlts.size == returnCount - 1) { def tryDropReturn(body: Tree): Option[Tree] = body match { - case BlockOrAlone(prep, Return(result, Some(_))) => + case BlockOrAlone(prep, Return(result, _)) => val result1 = if (refinedType == NoType) keepOnlySideEffects(result) else result From 4354b0ac968e4d87d56951c7c88de79487aafd1c Mon Sep 17 00:00:00 2001 From: exoego Date: Tue, 3 Apr 2018 22:03:17 +0900 Subject: [PATCH 0697/2665] Add title prefix so that developers recognize the correct tab faster. --- project/Build.scala | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/project/Build.scala b/project/Build.scala index c7c9f93ea0..31665557e7 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1050,7 +1050,12 @@ object Build { ) ++ ( scalaJSExternalCompileSettings ) ++ inConfig(Compile)(Seq( - scalacOptions in doc ++= Seq("-implicits", "-groups"), + scalacOptions in doc ++= Seq( + "-implicits", + "-groups", + "-doc-title", "Scala.js", + "-doc-version", scalaJSVersion + ), // Filter doc sources to remove implementation details from doc. sources in doc := { From ce17362666d2f1fa556c48f236b97b68e8fb1be4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 5 Apr 2018 15:51:45 +0200 Subject: [PATCH 0698/2665] Get rid of `TopLevelConstructorExportDef`s in the IR. Exports of Scala constructors can be directly encoded as top-level static *functions* instead, since what they did was creating a new instance inside of the desugared body anyway. Therefore, this commit gets rid of them at the IR level, by moving their desugaring from the `ClassEmitter` all the way back to the compiler. The only piece of observable semantics we lose by doing so is that a constructor export def did set the `prototype` of the function to `$c_LTheClass.prototype`, indirectly allowing JS code to use `x instanceof ExportedCtor` to perform a Scala instance test. However, this "feature" was never documented, nor tested. --- .../org/scalajs/nscplugin/GenJSExports.scala | 53 ++++++++++--------- .../main/scala/org/scalajs/ir/Printers.scala | 7 --- .../scala/org/scalajs/ir/Serializers.scala | 8 --- ir/src/main/scala/org/scalajs/ir/Tags.scala | 3 +- .../scala/org/scalajs/ir/Transformers.scala | 3 -- .../scala/org/scalajs/ir/Traversers.scala | 3 -- ir/src/main/scala/org/scalajs/ir/Trees.scala | 8 +-- .../scala/org/scalajs/ir/PrintersTest.scala | 12 ----- .../org/scalajs/linker/analyzer/Infos.scala | 12 +---- .../linker/backend/emitter/ClassEmitter.scala | 37 ------------- .../backend/emitter/KnowledgeGuardian.scala | 7 +-- .../scalajs/linker/checker/IRChecker.scala | 21 -------- 12 files changed, 35 insertions(+), 139 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/nscplugin/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/nscplugin/GenJSExports.scala index 6d258c9c3a..f206440b46 100644 --- a/compiler/src/main/scala/org/scalajs/nscplugin/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/GenJSExports.scala @@ -61,7 +61,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } def genConstructorExports( - classSym: Symbol): List[js.TopLevelConstructorExportDef] = { + classSym: Symbol): List[js.TopLevelMethodExportDef] = { val constructors = classSym.tpe.member(nme.CONSTRUCTOR).alternatives @@ -81,11 +81,11 @@ trait GenJSExports extends SubComponent { self: GenJSCode => implicit val pos = ctors.head.pos - val js.MethodDef(_, _, args, _, body) = - withNewLocalNameScope(genExportMethod(ctors, JSName.Literal(jsName), - static = false)) + val methodDef = withNewLocalNameScope { + genExportMethod(ctors, JSName.Literal(jsName), static = true) + } - js.TopLevelConstructorExportDef(jsName, args, body.get) + js.TopLevelMethodExportDef(methodDef) } exports.toList @@ -777,27 +777,32 @@ trait GenJSExports extends SubComponent { self: GenJSCode => /** Generate the final forwarding call to the exported method. */ private def genResult(exported: Exported, args: List[js.Tree], - static: Boolean)(implicit pos: Position) = { + static: Boolean)(implicit pos: Position): js.Tree = { val sym = exported.sym - val thisType = - if (sym.owner == ObjectClass) jstpe.ClassType(ir.Definitions.ObjectClass) - else encodeClassType(sym.owner) - val receiver = - if (static) genLoadModule(sym.owner) - else js.This()(thisType) - val call = { - if (isNonNativeJSClass(currentClassSym)) { - assert(sym.owner == currentClassSym.get, sym.fullName) - genApplyJSClassMethod(receiver, sym, args) - } else { - if (sym.isClassConstructor) - genApplyMethodStatically(receiver, sym, args) - else - genApplyMethod(receiver, sym, args) - } + + def receiver = { + if (static) + genLoadModule(sym.owner) + else if (sym.owner == ObjectClass) + js.This()(jstpe.ClassType(ir.Definitions.ObjectClass)) + else + js.This()(encodeClassType(sym.owner)) + } + + def boxIfNeeded(call: js.Tree): js.Tree = { + ensureBoxed(call, + enteringPhase(currentRun.posterasurePhase)(sym.tpe.resultType)) + } + + if (isNonNativeJSClass(currentClassSym)) { + assert(sym.owner == currentClassSym.get, sym.fullName) + boxIfNeeded(genApplyJSClassMethod(receiver, sym, args)) + } else { + if (sym.isClassConstructor) + genNew(currentClassSym, sym, args) + else + boxIfNeeded(genApplyMethod(receiver, sym, args)) } - ensureBoxed(call, - enteringPhase(currentRun.posterasurePhase)(sym.tpe.resultType)) } private final class ParamSpec(val sym: Symbol, val tpe: Type, diff --git a/ir/src/main/scala/org/scalajs/ir/Printers.scala b/ir/src/main/scala/org/scalajs/ir/Printers.scala index 2eac8f7bfd..bdf9efc9fa 100644 --- a/ir/src/main/scala/org/scalajs/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/ir/Printers.scala @@ -912,13 +912,6 @@ object Printers { def print(topLevelExportDef: TopLevelExportDef): Unit = { topLevelExportDef match { - case TopLevelConstructorExportDef(fullName, args, body) => - print("export top constructor \"") - printEscapeJS(fullName, out) - print('\"') - printSig(args, NoType) // NoType as trick not to display a type - printBlock(body) - case TopLevelJSClassExportDef(fullName) => print("export top class \"") printEscapeJS(fullName, out) diff --git a/ir/src/main/scala/org/scalajs/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/ir/Serializers.scala index 930435e7d6..192165e5a1 100644 --- a/ir/src/main/scala/org/scalajs/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/ir/Serializers.scala @@ -533,10 +533,6 @@ object Serializers { import buffer._ writePosition(topLevelExportDef.pos) topLevelExportDef match { - case TopLevelConstructorExportDef(fullName, args, body) => - writeByte(TagTopLevelConstructorExportDef) - writeString(fullName); writeParamDefs(args); writeTree(body) - case TopLevelJSClassExportDef(fullName) => writeByte(TagTopLevelJSClassExportDef) writeString(fullName) @@ -996,10 +992,6 @@ object Serializers { val tag = input.readByte() (tag: @switch) match { - case TagTopLevelConstructorExportDef => - TopLevelConstructorExportDef(readString(), readParamDefs(), - readTree()) - case TagTopLevelJSClassExportDef => TopLevelJSClassExportDef(readString()) case TagTopLevelModuleExportDef => TopLevelModuleExportDef(readString()) case TagTopLevelMethodExportDef => TopLevelMethodExportDef(readMemberDef().asInstanceOf[MethodDef]) diff --git a/ir/src/main/scala/org/scalajs/ir/Tags.scala b/ir/src/main/scala/org/scalajs/ir/Tags.scala index 709cf637f4..dba551e8da 100644 --- a/ir/src/main/scala/org/scalajs/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/ir/Tags.scala @@ -105,8 +105,7 @@ private[ir] object Tags { // Tags for top-level export defs - final val TagTopLevelConstructorExportDef = 1 - final val TagTopLevelJSClassExportDef = TagTopLevelConstructorExportDef + 1 + final val TagTopLevelJSClassExportDef = 1 final val TagTopLevelModuleExportDef = TagTopLevelJSClassExportDef + 1 final val TagTopLevelMethodExportDef = TagTopLevelModuleExportDef + 1 final val TagTopLevelFieldExportDef = TagTopLevelMethodExportDef + 1 diff --git a/ir/src/main/scala/org/scalajs/ir/Transformers.scala b/ir/src/main/scala/org/scalajs/ir/Transformers.scala index 67412c5f8f..4de53a1453 100644 --- a/ir/src/main/scala/org/scalajs/ir/Transformers.scala +++ b/ir/src/main/scala/org/scalajs/ir/Transformers.scala @@ -250,9 +250,6 @@ object Transformers { implicit val pos = exportDef.pos exportDef match { - case TopLevelConstructorExportDef(fullName, args, body) => - TopLevelConstructorExportDef(fullName, args, transformStat(body)) - case _:TopLevelJSClassExportDef | _:TopLevelModuleExportDef | _:TopLevelFieldExportDef => exportDef diff --git a/ir/src/main/scala/org/scalajs/ir/Traversers.scala b/ir/src/main/scala/org/scalajs/ir/Traversers.scala index 69effd6380..e2aea120df 100644 --- a/ir/src/main/scala/org/scalajs/ir/Traversers.scala +++ b/ir/src/main/scala/org/scalajs/ir/Traversers.scala @@ -230,9 +230,6 @@ object Traversers { def traverseTopLevelExportDef(exportDef: TopLevelExportDef): Unit = { exportDef match { - case TopLevelConstructorExportDef(fullName, args, body) => - traverse(body) - case _:TopLevelJSClassExportDef | _:TopLevelModuleExportDef | _:TopLevelFieldExportDef => diff --git a/ir/src/main/scala/org/scalajs/ir/Trees.scala b/ir/src/main/scala/org/scalajs/ir/Trees.scala index c12d6b8f2d..fc21c3e786 100644 --- a/ir/src/main/scala/org/scalajs/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/ir/Trees.scala @@ -985,9 +985,8 @@ object Trees { sealed abstract class TopLevelExportDef extends IRNode { final def topLevelExportName: String = this match { - case TopLevelConstructorExportDef(name, _, _) => name - case TopLevelModuleExportDef(name) => name - case TopLevelJSClassExportDef(name) => name + case TopLevelModuleExportDef(name) => name + case TopLevelJSClassExportDef(name) => name case TopLevelMethodExportDef(MethodDef(_, propName, _, _, _)) => val StringLiteral(name) = propName @@ -997,9 +996,6 @@ object Trees { } } - case class TopLevelConstructorExportDef(name: String, args: List[ParamDef], - body: Tree)(implicit val pos: Position) extends TopLevelExportDef - case class TopLevelJSClassExportDef(fullName: String)( implicit val pos: Position) extends TopLevelExportDef diff --git a/ir/src/test/scala/org/scalajs/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/ir/PrintersTest.scala index e7031b1e32..8f694af574 100644 --- a/ir/src/test/scala/org/scalajs/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/ir/PrintersTest.scala @@ -1183,18 +1183,6 @@ class PrintersTest { } } - @Test def printConstructorExportDef(): Unit = { - assertPrintEquals( - """ - |export top constructor "pkg.Foo"(x: any) { - | 5 - |} - """, - TopLevelConstructorExportDef("pkg.Foo", - List(ParamDef("x", AnyType, mutable = false, rest = false)), - i(5))) - } - @Test def printJSClassExportDef(): Unit = { assertPrintEquals( """export top class "pkg.Foo"""", diff --git a/linker/shared/src/main/scala/org/scalajs/linker/analyzer/Infos.scala b/linker/shared/src/main/scala/org/scalajs/linker/analyzer/Infos.scala index 0ab6a45ae6..b9ca2d656b 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/analyzer/Infos.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/analyzer/Infos.scala @@ -351,13 +351,10 @@ object Infos { def generateTopLevelExportsInfo(enclosingClass: String, topLevelExportDefs: List[TopLevelExportDef]): Option[MethodInfo] = { - var exportedConstructors: List[TopLevelConstructorExportDef] = Nil var topLevelMethodExports: List[TopLevelMethodExportDef] = Nil var topLevelFieldExports: List[TopLevelFieldExportDef] = Nil topLevelExportDefs.foreach { - case constructorDef: TopLevelConstructorExportDef => - exportedConstructors ::= constructorDef case _:TopLevelJSClassExportDef | _:TopLevelModuleExportDef => case topLevelMethodExport: TopLevelMethodExportDef => topLevelMethodExports ::= topLevelMethodExport @@ -365,10 +362,9 @@ object Infos { topLevelFieldExports ::= topLevelFieldExport } - if (exportedConstructors.nonEmpty || topLevelMethodExports.nonEmpty || - topLevelFieldExports.nonEmpty) { + if (topLevelMethodExports.nonEmpty || topLevelFieldExports.nonEmpty) { Some(new GenInfoTraverser().generateTopLevelExportsInfo(enclosingClass, - exportedConstructors, topLevelMethodExports, topLevelFieldExports)) + topLevelMethodExports, topLevelFieldExports)) } else { None } @@ -416,16 +412,12 @@ object Infos { } def generateTopLevelExportsInfo(enclosingClass: String, - topLevelConstructorDefs: List[TopLevelConstructorExportDef], topLevelMethodExports: List[TopLevelMethodExportDef], topLevelFieldExports: List[TopLevelFieldExportDef]): MethodInfo = { builder .setEncodedName(TopLevelExportsName) .setIsExported(true) - for (topLevelConstructorDef <- topLevelConstructorDefs) - traverse(topLevelConstructorDef.body) - for (topLevelMethodExport <- topLevelMethodExports) topLevelMethodExport.methodDef.body.foreach(traverse(_)) diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala index 326736fccb..78661df31a 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala @@ -1047,8 +1047,6 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { implicit globalKnowledge: GlobalKnowledge): WithGlobals[List[js.Tree]] = { val exportsWithGlobals = tree.topLevelExports.map { topLevelExport => topLevelExport.value match { - case e: TopLevelConstructorExportDef => - genTopLevelConstructorExportDef(tree, e) case e: TopLevelJSClassExportDef => WithGlobals(genTopLevelJSClassExportDef(tree, e)) case e: TopLevelModuleExportDef => @@ -1063,41 +1061,6 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { WithGlobals.list(exportsWithGlobals) } - def genTopLevelConstructorExportDef(cd: LinkedClass, - tree: TopLevelConstructorExportDef)( - implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { - import TreeDSL._ - - implicit val pos = tree.pos - val classType = ClassType(cd.name.name) - val TopLevelConstructorExportDef(fullName, args, body) = tree - - val baseCtor = envField("c", cd.name.name, cd.name.originalName) - - val generatedFunWithGlobals = desugarToFunctionWithExplicitThis( - cd.encodedName, args, body, resultType = NoType) - - for (generatedFun <- generatedFunWithGlobals) yield { - val js.Function(arrow, thisParam :: ctorParams, ctorBody) = generatedFun - val thisIdent = thisParam.name - - val exportedCtor = js.Function(arrow, ctorParams, js.Block( - genLet(thisIdent, mutable = false, js.New(baseCtor, Nil)), - ctorBody, - js.Return(js.VarRef(thisIdent)) - )) - - val (createNamespace, expCtorVar) = - genCreateNamespaceInExports(fullName) - js.Block( - createNamespace, - js.DocComment("@constructor"), - expCtorVar := exportedCtor, - expCtorVar DOT "prototype" := baseCtor DOT "prototype" - ) - } - } - def genTopLevelJSClassExportDef(cd: LinkedClass, tree: TopLevelJSClassExportDef): js.Tree = { import TreeDSL._ diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/KnowledgeGuardian.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/KnowledgeGuardian.scala index f1f1c0e5bc..10a5fb1e4a 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/KnowledgeGuardian.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/KnowledgeGuardian.scala @@ -109,9 +109,7 @@ private[emitter] final class KnowledgeGuardian { /* We can enable inlined init if all of the following apply: * - The class is not blacklisted * - It does not have any instantiated subclass - * - It has exactly one (regular) constructor - * - It does not have any exported constructor (since they are - * effectively secondary constructors) + * - It has exactly one constructor * * By construction, this is always true for module classes. */ @@ -119,9 +117,6 @@ private[emitter] final class KnowledgeGuardian { !classesWithInstantiatedSubclasses(classDef.encodedName) && { classDef.memberMethods.count( x => Definitions.isConstructorName(x.value.encodedName)) == 1 - } && { - !classDef.topLevelExports.exists( - _.value.isInstanceOf[TopLevelConstructorExportDef]) } } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala b/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala index b15a140efe..fb7a4b9e08 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala @@ -219,9 +219,6 @@ private final class IRChecker(unit: LinkingUnit, implicit val ctx = ErrorContext(tree) tree match { - case tree: TopLevelConstructorExportDef => - checkTopLevelConstructorExportDef(tree, classDef) - case tree: TopLevelJSClassExportDef => checkTopLevelJSClassExportDef(tree, classDef) @@ -492,24 +489,6 @@ private final class IRChecker(unit: LinkingUnit, } } - private def checkTopLevelConstructorExportDef( - ctorDef: TopLevelConstructorExportDef, - classDef: LinkedClass): Unit = withPerMethodState { - val TopLevelConstructorExportDef(_, params, body) = ctorDef - implicit val ctx = ErrorContext(ctorDef) - - if (!classDef.kind.isClass) { - reportError(s"Exported constructor def can only appear in a class") - return - } - - checkJSParamDefs(params) - - val thisType = ClassType(classDef.name.name) - val bodyEnv = Env.fromSignature(thisType, None, params, NoType) - typecheckStat(body, bodyEnv) - } - private def checkTopLevelJSClassExportDef( classExportDef: TopLevelJSClassExportDef, classDef: LinkedClass): Unit = { implicit val ctx = ErrorContext(classExportDef) From 955334accca2d2b4d4e2fd9ab01ff002aa85d5fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 6 Apr 2018 19:13:22 +0200 Subject: [PATCH 0699/2665] Move the default value of some sbt settings to the Global scope. We do this for `scalaJSLinkerConfig`, `jsEnv` and `jsExecutionFiles`. It can be convenient to override those settings at the global level in a build, for example to globally enable or disable batch mode, or switch the JS environment. The only Scala.js-specific settings left that we initialize in the project scope are `scalaJSModuleInitializers` and `scalaJSUseMainModuleInitialize`. It does not make sense to set those at the global level, since they depend on the specific codebase being linked. --- .../scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala | 10 ++++++++++ .../scalajs/sbtplugin/ScalaJSPluginInternal.scala | 12 +----------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index a52b4b41e5..4a32dd00fb 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -22,6 +22,7 @@ import org.scalajs.linker._ import org.scalajs.linker.irio._ import org.scalajs.jsenv.JSEnv +import org.scalajs.jsenv.nodejs.NodeJSEnv object ScalaJSPlugin extends AutoPlugin { override def requires: Plugins = plugins.JvmPlugin @@ -161,6 +162,15 @@ object ScalaJSPlugin extends AutoPlugin { Seq( scalaJSStage := Stage.FastOpt, + scalaJSLinkerConfig := { + StandardLinker.Config() + .withParallel(ScalaJSPluginInternal.DefaultParallelLinker) + }, + + jsEnv := new NodeJSEnv(), + + jsExecutionFiles := Nil, + // Clear the IR cache stats every time a sequence of tasks ends onComplete := { val prev = onComplete.value diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 87c0eceb94..857144b4a7 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -19,7 +19,6 @@ import org.scalajs.linker._ import org.scalajs.linker.irio._ import org.scalajs.jsenv._ -import org.scalajs.jsenv.nodejs.NodeJSEnv import org.scalajs.ir.Printers.IRTreePrinter @@ -85,7 +84,7 @@ private[sbtplugin] object ScalaJSPluginInternal { * which uses Scala 2.12. We should get rid of that workaround at that point * for tidiness, though. */ - private val DefaultParallelLinker: Boolean = { + val DefaultParallelLinker: Boolean = { try { scala.util.Properties.isJavaAtLeast("1.8") true @@ -427,18 +426,9 @@ private[sbtplugin] object ScalaJSPluginInternal { private val scalaJSProjectBaseSettings = Seq( platformDepsCrossVersion := ScalaJSCrossVersion.binary, - scalaJSLinkerConfig := { - StandardLinker.Config() - .withParallel(DefaultParallelLinker) - }, - scalaJSModuleInitializers := Seq(), scalaJSUseMainModuleInitializer := false, - jsEnv := new NodeJSEnv(), - - jsExecutionFiles := Nil, - // you will need the Scala.js compiler plugin addCompilerPlugin( "org.scala-js" % "scalajs-compiler" % scalaJSVersion cross CrossVersion.full), From 67ece429fa0de31d61ff3e54fcc743b269936d2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 6 Apr 2018 19:34:48 +0200 Subject: [PATCH 0700/2665] Abstract IRFileCache#Cache into a trait in the companion object. This both removes the public view that it is a class, and removes the need for `#` projections. --- .../org/scalajs/linker/irio/IRFileCache.scala | 49 +++++++++++-------- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 2 +- .../sbtplugin/ScalaJSPluginInternal.scala | 4 +- 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/linker/shared/src/main/scala/org/scalajs/linker/irio/IRFileCache.scala b/linker/shared/src/main/scala/org/scalajs/linker/irio/IRFileCache.scala index 8cb247f519..10dfc7edaa 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/irio/IRFileCache.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/irio/IRFileCache.scala @@ -33,6 +33,8 @@ final class IRFileCache { * that paying the cost for synchronization is lower than I/O. */ + import IRFileCache._ + /** Holds the cached IR */ private[this] val globalCache = new ConcurrentHashMap[String, PersistedFiles] @@ -43,10 +45,10 @@ final class IRFileCache { /** Create a new sub-cache. * - * Users should call [[Cache.free]] once they are done to allow for more - * aggressive GC. + * Users should call [[IRFileCache.Cache.free]] once they are done to allow + * for more aggressive GC. */ - def newCache: Cache = new Cache + def newCache: Cache = new CacheImpl /** Approximate statistics about the cache usage */ def stats: IRFileCache.Stats = { @@ -61,19 +63,9 @@ final class IRFileCache { statsTreesRead.set(0) } - /** A cache to use for individual runs. Not threadsafe */ - final class Cache private[IRFileCache] { + private final class CacheImpl extends Cache { private[this] var localCache: Seq[PersistedFiles] = _ - /** Extract and cache IR. - * - * The returned value is valid until the next invocation of [[cached]] or - * [[free]]. - * - * @note Updating any of the underlying files in the container during the - * lifetime of a returned [[VirtualScalaJSIRFile]] yields - * unspecified behavior. - */ def cached(files: Seq[ScalaJSIRContainer]): Seq[VirtualScalaJSIRFile] = { update(files) localCache.flatMap(_.files) @@ -103,12 +95,6 @@ final class IRFileCache { localCache = result.result() } - /** Should be called if this cache is not used anymore. - * - * Frees resources in the global cache, if they are not used anymore. - * The cache may be reused after calling [[free]] (but this is not any - * faster than calling [[newCache]], modulo the object allocation). - */ def free(): Unit = { if (localCache != null) { localCache.foreach(_.unreference()) @@ -275,6 +261,29 @@ final class IRFileCache { } object IRFileCache { + /** A cache to use for individual runs. Not threadsafe */ + sealed trait Cache { + /** Extract and cache IR. + * + * The returned value is valid until the next invocation of [[cached]] or + * [[free]]. + * + * @note Updating any of the underlying files in the container during the + * lifetime of a returned [[VirtualScalaJSIRFile]] yields + * unspecified behavior. + */ + def cached(files: Seq[ScalaJSIRContainer]): Seq[VirtualScalaJSIRFile] + + /** Should be called if this cache is not used anymore. + * + * Frees resources in the global cache, if they are not used anymore. + * The cache may be reused after calling [[free]] (but this is not any + * faster than calling [[IRFileCache.newCache]], modulo the object + * allocation). + */ + def free(): Unit + } + final class Stats(val reused: Int, val invalidated: Int, val treesRead: Int) { /** Descriptive line to display in logs */ def logLine: String = { diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index a52b4b41e5..6a903a1aa1 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -41,7 +41,7 @@ object ScalaJSPlugin extends AutoPlugin { // All our public-facing keys - val scalaJSIRCache = SettingKey[IRFileCache#Cache]( + val scalaJSIRCache = SettingKey[IRFileCache.Cache]( "scalaJSIRCache", "Scala.js internal: Task to access a cache.", KeyRanks.Invisible) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 87c0eceb94..45446eefe2 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -49,14 +49,14 @@ private[sbtplugin] object ScalaJSPluginInternal { } private val allocatedIRCaches = - new AtomicReference[List[globalIRCache.Cache]](Nil) + new AtomicReference[List[IRFileCache.Cache]](Nil) /** Allocates a new IR cache linked to the [[globalIRCache]]. * * The allocated IR cache will automatically be freed when the build is * unloaded. */ - private def newIRCache: globalIRCache.Cache = + private def newIRCache: IRFileCache.Cache = registerResource(allocatedIRCaches, globalIRCache.newCache) private[sbtplugin] def freeAllIRCaches(): Unit = From a59e8e69146d1975777300cf71d9c6a6a1db05ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 8 Apr 2018 17:33:09 +0200 Subject: [PATCH 0701/2665] Fix #3338: Fix the intrinsic code for `ScalaRunTime.array_apply()`. --- .../scalajs/testsuite/compiler/RegressionTest.scala | 13 +++++++++++++ .../linker/frontend/optimizer/OptimizerCore.scala | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala index 92dbee790d..772debde05 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala @@ -758,6 +758,19 @@ class RegressionTest { assertEquals(5L, r) } + @Test def polymorphicArrayApplyWithArrayOfArrayOfChar_issue_3338(): Unit = { + @inline + def arrayGet[A](a: Array[A], i: Int): Any = a(i) + + val a = Array(Array('a')) + val b = arrayGet(a, 0) + assertTrue(b.isInstanceOf[Array[Char]]) + val c = b.asInstanceOf[Array[Char]] + val d = arrayGet(c, 0) + assertTrue(d.isInstanceOf[Char]) + assertEquals('a', d) + } + } object RegressionTest { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index 83ca4aea79..b9c1ad6115 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -1977,7 +1977,7 @@ private[optimizer] abstract class OptimizerCore( case arrayTpe @ ArrayType(base, depth) => val elemType = cursoryArrayElemType(arrayTpe) val select = ArraySelect(array, index)(elemType) - if (base == "C") + if (base == "C" && depth == 1) boxChar(select)(cont) else contTree(select) From e654d9c22e81033d250d66137771d03eee9eb90c Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 23 Mar 2018 22:14:16 +0100 Subject: [PATCH 0702/2665] Separate module initializer tests for linker and sbt plugin. This will make it easier to consolidate the bootstrap test settings into a single location. --- Jenkinsfile | 1 + project/Build.scala | 44 ++++----------- sbt-plugin-test/build.sbt | 19 ++++++- .../main/scala/sbttest/noDOM/TestApp.scala | 2 + .../test/scala/sbttest/noDOM/InitHolder.scala | 6 ++ .../compiler/ModuleInitializersTest.scala | 56 ++++--------------- 6 files changed, 47 insertions(+), 81 deletions(-) create mode 100644 sbt-plugin-test/noDOM/src/test/scala/sbttest/noDOM/InitHolder.scala diff --git a/Jenkinsfile b/Jenkinsfile index 69f216bf70..5e38122b85 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -333,6 +333,7 @@ def Tasks = [ sbt noDOM/run \ noDOM/testHtml multiTestJS/testHtml \ test \ + noDOM/testScalaJSModuleInitializers \ noDOM/clean noDOM/concurrentUseOfLinkerTest \ multiTestJS/test:testScalaJSSourceMapAttribute && sbt 'set scalaJSStage in Global := FullOptStage' \ diff --git a/project/Build.scala b/project/Build.scala index c6f456b6ef..942b4c2868 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -778,11 +778,9 @@ object Build { * write-only data structure). So we have some duplication. */ val unescapedMainMethods = List( - "org.scalajs.testsuite.compiler.ModuleInitializerInNoConfiguration.main", - "org.scalajs.testsuite.compiler.ModuleInitializerInTestConfiguration.main2", - "org.scalajs.testsuite.compiler.ModuleInitializerInTestConfiguration.main1", - "org.scalajs.testsuite.compiler.ModuleInitializerInTestConfiguration.mainArgs1()", - "org.scalajs.testsuite.compiler.ModuleInitializerInTestConfiguration.mainArgs2(foo,bar)" + "org.scalajs.testsuite.compiler.ModuleInitializers.mainNoArgs", + "org.scalajs.testsuite.compiler.ModuleInitializers.mainWithArgs()", + "org.scalajs.testsuite.compiler.ModuleInitializers.mainWithArgs(foo,bar)" ) seqOfStringsToJSArrayCode(unescapedMainMethods) } @@ -1682,35 +1680,13 @@ object Build { }, // Module initializers. Duplicated in toolsJS/test - scalaJSModuleInitializers += { - ModuleInitializer.mainMethod( - "org.scalajs.testsuite.compiler.ModuleInitializerInNoConfiguration", - "main") - }, - scalaJSModuleInitializers in Compile += { - ModuleInitializer.mainMethod( - "org.scalajs.testsuite.compiler.ModuleInitializerInCompileConfiguration", - "main") - }, - scalaJSModuleInitializers in Test += { - ModuleInitializer.mainMethod( - "org.scalajs.testsuite.compiler.ModuleInitializerInTestConfiguration", - "main2") - }, - scalaJSModuleInitializers in Test += { - ModuleInitializer.mainMethod( - "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")) + scalaJSModuleInitializers in Test ++= { + val module = "org.scalajs.testsuite.compiler.ModuleInitializers" + Seq( + ModuleInitializer.mainMethod(module, "mainNoArgs"), + ModuleInitializer.mainMethodWithArgs(module, "mainWithArgs"), + ModuleInitializer.mainMethodWithArgs(module, "mainWithArgs", List("foo", "bar")) + ) }, testSuiteTestHtmlSetting diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index bc4d423f8e..2eea32a91f 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -1,4 +1,5 @@ import org.scalajs.io._ +import org.scalajs.linker._ import org.scalajs.sbtplugin.Loggers.sbtLogger2ToolsLogger import org.scalajs.sbtplugin.ScalaJSCrossVersion @@ -26,6 +27,9 @@ val baseSettings = versionSettings ++ Seq( val testScalaJSSourceMapAttribute = TaskKey[Unit]( "testScalaJSSourceMapAttribute", "", KeyRanks.BTask) +val testScalaJSModuleInitializers = TaskKey[Unit]( + "testScalaJSModuleInitializers", "", KeyRanks.BTask) + lazy val root = project.in(file(".")). aggregate(noDOM, multiTestJS, multiTestJVM) @@ -35,7 +39,20 @@ lazy val noDOM = project.settings(baseSettings: _*). settings( name := "Scala.js sbt test w/o DOM", scalaJSUseMainModuleInitializer := true, - javaOptions += "-Xmx512M" // test that this is ignored without error + scalaJSModuleInitializers += + ModuleInitializer.mainMethod("sbttest.noDOM.TestApp", "foo"), + scalaJSModuleInitializers in Test += + ModuleInitializer.mainMethod("sbttest.noDOM.InitHolder", "foo"), + + testScalaJSModuleInitializers := { + // Compile should have main module init and TestApp.foo + assert((scalaJSModuleInitializers in Compile).value.size == 2, + "Bad number of scalaJSModuleInitializers in Compile") + + // Test should have InitHolder.foo and TestApp.foo + assert((scalaJSModuleInitializers in Test).value.size == 2, + "Bad number of scalaJSModuleInitializers in Test") + } ). /* This hopefully exposes concurrent uses of the linker. If it fails/gets * flaky, there is a bug somewhere - #2202 diff --git a/sbt-plugin-test/noDOM/src/main/scala/sbttest/noDOM/TestApp.scala b/sbt-plugin-test/noDOM/src/main/scala/sbttest/noDOM/TestApp.scala index 8f62001441..bf783b7ab4 100644 --- a/sbt-plugin-test/noDOM/src/main/scala/sbttest/noDOM/TestApp.scala +++ b/sbt-plugin-test/noDOM/src/main/scala/sbttest/noDOM/TestApp.scala @@ -7,4 +7,6 @@ object TestApp { println(Lib.sq(10)) } + // Used as a manual module initializer. + def foo(): Unit = () } diff --git a/sbt-plugin-test/noDOM/src/test/scala/sbttest/noDOM/InitHolder.scala b/sbt-plugin-test/noDOM/src/test/scala/sbttest/noDOM/InitHolder.scala new file mode 100644 index 0000000000..2d9cb12907 --- /dev/null +++ b/sbt-plugin-test/noDOM/src/test/scala/sbttest/noDOM/InitHolder.scala @@ -0,0 +1,6 @@ +package sbttest.noDOM + +object InitHolder { + // Used as initializer. + def foo(): Unit = () +} diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ModuleInitializersTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ModuleInitializersTest.scala index 8555cdd235..8f44e4ab5b 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ModuleInitializersTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ModuleInitializersTest.scala @@ -16,64 +16,28 @@ class ModuleInitializersTest { @Test def correctInitializers(): Unit = { assertArrayEquals( Array[AnyRef]( - NoConfigMain, - TestConfigMain2, - TestConfigMain1, - TestConfigMainArgs1 + "()", - TestConfigMainArgs2 + "(foo, bar)" + NoArgs, + WithArgs + "()", + WithArgs + "(foo, bar)" ), moduleInitializersEffects.toArray[AnyRef]) } - } object ModuleInitializersTest { - final val NoConfigMain = "ModuleInitializerInNoConfiguration.main" - final val CompileConfigMain = "ModuleInitializerInCompileConfiguration.main" - final val TestConfigMain1 = "ModuleInitializerInTestConfiguration.main1" - final val TestConfigMain2 = "ModuleInitializerInTestConfiguration.main2" - final val TestConfigMainArgs1 = "ModuleInitializerInTestConfiguration.mainArgs1" - final val TestConfigMainArgs2 = "ModuleInitializerInTestConfiguration.mainArgs2" + final val NoArgs = "NoArgs" + final val WithArgs = "WithArgs" val moduleInitializersEffects = new scala.collection.mutable.ListBuffer[String] } -object ModuleInitializerInNoConfiguration { +object ModuleInitializers { import ModuleInitializersTest._ - def main(): Unit = { - moduleInitializersEffects += NoConfigMain - } -} - -object ModuleInitializerInCompileConfiguration { - import ModuleInitializersTest._ + def mainNoArgs(): Unit = + moduleInitializersEffects += NoArgs - def main(): Unit = { - // This is not going to be actually run - moduleInitializersEffects += CompileConfigMain - } -} - -object ModuleInitializerInTestConfiguration { - import ModuleInitializersTest._ - - def main1(): Unit = { - moduleInitializersEffects += TestConfigMain1 - } - - def main2(): Unit = { - moduleInitializersEffects += TestConfigMain2 - } - - def mainArgs1(args: Array[String]): Unit = { - moduleInitializersEffects += - TestConfigMainArgs1 + args.mkString("(", ", ", ")") - } - - def mainArgs2(args: Array[String]): Unit = { - moduleInitializersEffects += - TestConfigMainArgs2 + args.mkString("(", ", ", ")") - } + def mainWithArgs(args: Array[String]): Unit = + moduleInitializersEffects += WithArgs + args.mkString("(", ", ", ")") } From a6e5e41b5c19d299fa6d499aeb0b3410a54ff469 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 25 Mar 2018 00:07:41 +0100 Subject: [PATCH 0703/2665] Move NodeVirtualJarFile (and related) to main packages We make them private[scalajs] for now. We'll follow up in #3330 to either make them all private (in a separate package) or all public. --- .../org/scalajs/io/NodeVirtualFiles.scala | 59 ++++++++++++++ .../linker/irio/NodeVirtualIRFiles.scala | 7 ++ .../linker/testutils/NodeVirtualJarFile.scala | 77 ------------------- 3 files changed, 66 insertions(+), 77 deletions(-) delete mode 100644 linker/js/src/test/scala/org/scalajs/linker/testutils/NodeVirtualJarFile.scala diff --git a/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala b/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala index 3e0efe9150..0c923223a2 100644 --- a/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala +++ b/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala @@ -52,3 +52,62 @@ private[io] object NodeFS extends js.Object { def readFileSync(path: String, enc: Enc): String = js.native def statSync(path: String): Stat = js.native } + +private[scalajs] class NodeVirtualJarFile(file: String) + extends NodeVirtualBinaryFile(file) with VirtualFileContainer { + + import NodeVirtualJarFile._ + + 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() + } + } +} + +private object NodeVirtualJarFile { + @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 --git a/linker/js/src/main/scala/org/scalajs/linker/irio/NodeVirtualIRFiles.scala b/linker/js/src/main/scala/org/scalajs/linker/irio/NodeVirtualIRFiles.scala index 4e9e712b72..53e028f146 100644 --- a/linker/js/src/main/scala/org/scalajs/linker/irio/NodeVirtualIRFiles.scala +++ b/linker/js/src/main/scala/org/scalajs/linker/irio/NodeVirtualIRFiles.scala @@ -12,3 +12,10 @@ import org.scalajs.io._ class NodeVirtualScalaJSIRFile(p: String, val relativePath: String) extends NodeVirtualBinaryFile(p) with VirtualSerializedScalaJSIRFile + +private[scalajs] class NodeVirtualJarScalaJSIRContainer(file: String) + extends NodeVirtualJarFile(file) with ScalaJSIRContainer { + + def sjsirFiles: List[VirtualScalaJSIRFile] = + ScalaJSIRContainer.sjsirFilesIn(this) +} diff --git a/linker/js/src/test/scala/org/scalajs/linker/testutils/NodeVirtualJarFile.scala b/linker/js/src/test/scala/org/scalajs/linker/testutils/NodeVirtualJarFile.scala deleted file mode 100644 index 04ed1026eb..0000000000 --- a/linker/js/src/test/scala/org/scalajs/linker/testutils/NodeVirtualJarFile.scala +++ /dev/null @@ -1,77 +0,0 @@ -package org.scalajs.linker.testutils - -import java.io.InputStream - -import scala.scalajs.js -import scala.scalajs.js.annotation._ -import scala.scalajs.js.typedarray._ - -import org.scalajs.io._ - -import org.scalajs.linker.irio._ - -class NodeVirtualJarFile(file: String) - extends NodeVirtualBinaryFile(file) with VirtualFileContainer { - - import NodeVirtualJarFile._ - - 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() - } - } -} - -object NodeVirtualJarFile { - @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 - } -} - -class NodeVirtualJarScalaJSIRContainer(file: String) - extends NodeVirtualJarFile(file) with ScalaJSIRContainer { - - def sjsirFiles: List[VirtualScalaJSIRFile] = - ScalaJSIRContainer.sjsirFilesIn(this) -} From 48a83eed8a1623fb362d98dcd39d0794a2d07060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 9 Apr 2018 19:06:01 +0200 Subject: [PATCH 0704/2665] Add tests for the behavior of throw/catch across languages. As specified, which is: * If JS throws an instance of `Throwable`, Scala.js catches it as is. * If JS throws any other value, Scala.js catches it as wrapped in a `js.JavaScriptException`. * If Scala throws an instance of `js.JavaScriptException`, JS catches the wrapped value. * If Scala throws any other `Throwable`, JS catches it as is. --- .../jsinterop/ThrowAndCatchTest.scala | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ThrowAndCatchTest.scala diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ThrowAndCatchTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ThrowAndCatchTest.scala new file mode 100644 index 0000000000..82b90443ad --- /dev/null +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ThrowAndCatchTest.scala @@ -0,0 +1,93 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2018, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.testsuite.jsinterop + +import scala.scalajs.js + +import org.junit.Assert._ +import org.junit.Test + +import org.scalajs.testsuite.utils.AssertThrows._ + +class ThrowAndCatchTest { + import ThrowAndCatchTest._ + + @Test def testJSThrowThrowableScalaCatch(): Unit = { + val e = new Exception("boom") + try { + jsThrow(e) + } catch { + case e2: Throwable => + assertSame(e, e2) + } + } + + @Test def testJSThrowTypeErrorScalaCatch(): Unit = { + val e = new js.TypeError("boom") + try { + jsThrow(e) + } catch { + case js.JavaScriptException(e2) => + assertSame(e, e2) + } + } + + @Test def testJSThrowOptionScalaCatch(): Unit = { + val e = Some("boom") + try { + jsThrow(e) + } catch { + case js.JavaScriptException(e2) => + assertSame(e, e2) + } + } + + @Test def testScalaThrowThrowableJSCatch(): Unit = { + val e = new Exception("boom") + val e2 = jsCatch(() => throw e) + assertSame(e, e2) + } + + @Test def testScalaThrowTypeErrorJSCatch(): Unit = { + val e = new js.TypeError("boom") + val e2 = jsCatch(() => throw js.JavaScriptException(e)) + assertSame(e, e2) + } + + @Test def testScalaThrowOptionJSCatch(): Unit = { + val e = Some("boom") + val e2 = jsCatch(() => throw js.JavaScriptException(e)) + assertSame(e, e2) + } + + @Test def testScalaThrowThrowableInJavaScriptExceptionJSCatch(): Unit = { + // This is evil, but spec'ed nevertheless + val e = new Exception("boom") + val e2 = jsCatch(() => throw js.JavaScriptException(e)) + assertSame(e, e2) + } + +} + +object ThrowAndCatchTest { + private val jsThrow: js.Function1[Any, Nothing] = + new js.Function("e", "throw e;").asInstanceOf[js.Function1[Any, Nothing]] + + private val jsCatch: js.Function1[js.Function0[_], Any] = { + new js.Function("f", + """ + |try { + | f(); + |} catch (e) { + | return e; + |} + |throw new Error("Did not catch anything"); + """.stripMargin).asInstanceOf[js.Function1[js.Function0[_], Any]] + } +} From 867230ad5d39367c9be571103b25219e225a7b4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 5 Apr 2018 22:59:14 +0200 Subject: [PATCH 0705/2665] Fix #2383: Rewire Throwable to extend JavaScript's Error. In order for our Throwables to be truly recognized by JavaScript as error classes, they must extend `Error`. With ECMAScript 2015 classes, this is possible (and easy), but with ECMAScript 5.1 functions and prototypes, we cannot *truly* make them errors, because there is no way we can convince ECMAScript to give them an `[[ErrorData]]` internal slot. That is because the `Error` constructor will only do that with a non-undefined `new.target`. To minimize the gap between ES 5.1 and 2015, we still rewire the prototype of `Throwable` to that of `Error`. In both cases, this rewiring means that `Throwable` does not inherit the methods of `j.l.Object` anymore, so we need to explicitly introduce bridges for those in `Throwable`. --- .../src/main/scala/java/lang/StackTrace.scala | 18 +++++++- .../src/main/scala/java/lang/Throwables.scala | 22 +++++++++ .../linker/backend/emitter/ClassEmitter.scala | 32 +++++++++---- .../linker/backend/emitter/Emitter.scala | 45 +++++++++++++++++-- .../javalib/lang/ThrowableJSTest.scala | 35 +++++++++++++++ .../javalib/lang/ThrowablesTest.scala | 28 ++++++++++++ 6 files changed, 166 insertions(+), 14 deletions(-) create mode 100644 test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/ThrowableJSTest.scala diff --git a/javalanglib/src/main/scala/java/lang/StackTrace.scala b/javalanglib/src/main/scala/java/lang/StackTrace.scala index 66f8d898b0..d597fc9b4d 100644 --- a/javalanglib/src/main/scala/java/lang/StackTrace.scala +++ b/javalanglib/src/main/scala/java/lang/StackTrace.scala @@ -37,7 +37,21 @@ private[lang] object StackTrace { * by `extract()` to create an Array[StackTraceElement]. */ @inline def captureState(throwable: Throwable): Unit = { - if (js.isUndefined(js.constructorOf[js.Error].captureStackTrace)) { + val throwableAsJSAny = throwable.asInstanceOf[js.Any] + val identifyingString: Any = { + js.constructorOf[js.Object].prototype + .selectDynamic("toString") + .call(throwableAsJSAny) + } + if ("[object Error]" == identifyingString) { + /* The `throwable` has an `[[ErrorData]]` internal slot, which is as good + * a guarantee as any that it contains stack trace data itself. In + * practice, this happens when we emit ES 2015 classes, and no other + * compiler down the line has compiled them away as ES 5.1 functions and + * prototypes. + */ + captureState(throwable, throwable) + } else if (js.isUndefined(js.constructorOf[js.Error].captureStackTrace)) { captureState(throwable, createException()) } else { /* V8-specific. @@ -47,7 +61,7 @@ private[lang] object StackTrace { * important so that Node.js will show stack traces if the exception * is never caught and reaches the global event queue. */ - js.constructorOf[js.Error].captureStackTrace(throwable.asInstanceOf[js.Any]) + js.constructorOf[js.Error].captureStackTrace(throwableAsJSAny) captureState(throwable, throwable) } } diff --git a/javalanglib/src/main/scala/java/lang/Throwables.scala b/javalanglib/src/main/scala/java/lang/Throwables.scala index e05648d954..efe76e1576 100644 --- a/javalanglib/src/main/scala/java/lang/Throwables.scala +++ b/javalanglib/src/main/scala/java/lang/Throwables.scala @@ -1,6 +1,7 @@ package java.lang import scala.scalajs.js +import scala.scalajs.js.annotation.JSExport class Throwable(s: String, private var e: Throwable) extends Object with java.io.Serializable { def this() = this(null, null) @@ -124,12 +125,33 @@ class Throwable(s: String, private var e: Throwable) extends Object with java.io } } + /* Re-export toString() because Throwable will be disconnected from Object + * to extend js.Error instead, and exports are not transferred. + */ + @JSExport override def toString(): String = { val className = getClass.getName val message = getMessage() if (message eq null) className else className + ": " + message } + + /* A JavaScript Error object should have a `name` property containing a + * string representation of the class of the error. + */ + @JSExport("name") + @inline + protected def js_name: String = getClass.getName + + /* A JavaScript Error object should have a `message` property containing a + * string representation of the message associated with the error. + */ + @JSExport("message") + @inline + protected def js_message: String = { + val m = getMessage() + if (m eq null) "" else m + } } class ThreadDeath() extends Error() diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala index 78661df31a..9df56be3e9 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala @@ -151,7 +151,10 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val parentVarWithGlobals = for (parentIdent <- tree.superClass) yield { implicit val pos = parentIdent.pos if (!tree.kind.isJSClass) { - WithGlobals(encodeClassVar(parentIdent.name)) + if (shouldExtendJSError(tree)) + WithGlobals(js.VarRef(js.Ident("Error"))) + else + WithGlobals(encodeClassVar(parentIdent.name)) } else if (tree.jsSuperClass.isDefined) { WithGlobals(envField("superClass")) } else { @@ -208,12 +211,12 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val isJSClass = tree.kind.isJSClass val typeVar = encodeClassVar(className) - def makeInheritableCtorDef(ctorToMimic: js.Tree) = { + def makeInheritableCtorDef(ctorToMimic: js.Tree, field: String) = { js.Block( js.DocComment("@constructor"), - envFieldDef("h", className, js.Function(false, Nil, js.Skip()), + envFieldDef(field, className, js.Function(false, Nil, js.Skip()), keepFunctionExpression = isJSClass), - envField("h", className).prototype := ctorToMimic.prototype + envField(field, className).prototype := ctorToMimic.prototype ) } @@ -225,7 +228,13 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { WithGlobals(js.Skip()) } { parentIdent => val (inheritedCtorDefWithGlobals, inheritedCtorRef) = if (!isJSClass) { - (WithGlobals(js.Skip()), envField("h", parentIdent.name)) + if (shouldExtendJSError(tree)) { + val inheritableCtorDef = + makeInheritableCtorDef(js.VarRef(js.Ident("Error")), "hh") + (WithGlobals(inheritableCtorDef), envField("hh", className)) + } else { + (WithGlobals(js.Skip()), envField("h", parentIdent.name)) + } } else { val superCtor = if (tree.jsSuperClass.isDefined) { WithGlobals(envField("superClass")) @@ -233,7 +242,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { genRawJSClassConstructor(parentIdent.name, keepOnlyDangerousVarNames = true) } - (superCtor.map(makeInheritableCtorDef(_)), envField("h", className)) + (superCtor.map(makeInheritableCtorDef(_, "h")), envField("h", className)) } for (inheritedCtorDef <- inheritedCtorDefWithGlobals) yield { @@ -255,7 +264,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val inheritableCtorDef = if (isJSClass) js.Skip() - else makeInheritableCtorDef(typeVar) + else makeInheritableCtorDef(typeVar, "h") js.Block(docComment, ctorDef, chainProto, inheritableCtorDef) } @@ -1255,7 +1264,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { } -private object ClassEmitter { +private[emitter] object ClassEmitter { // TODO We should compute all of those from the Class Hierarchy private val CharSequenceClass = "jl_CharSequence" @@ -1284,4 +1293,11 @@ private object ClassEmitter { private val ClassesWhoseDataReferToTheirInstanceTests = AncestorsOfHijackedClasses + Definitions.BoxedStringClass + + private final val ThrowableClass = "jl_Throwable" + + def shouldExtendJSError(linkedClass: LinkedClass): Boolean = { + linkedClass.name.name == ThrowableClass && + linkedClass.superClass.exists(_.name == Definitions.ObjectClass) + } } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala index 1feb9c8439..b588b629ff 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala @@ -15,7 +15,7 @@ import scala.collection.mutable import org.scalajs.ir.{ClassKind, Position} import org.scalajs.ir.Trees.JSNativeLoadSpec -import org.scalajs.ir.Definitions.decodeClassName +import org.scalajs.ir.Definitions.{ObjectClass, decodeClassName, isConstructorName} import org.scalajs.io._ import org.scalajs.logging._ @@ -292,7 +292,9 @@ final class Emitter private (config: CommonPhaseConfig, @tailrec private def genAllClasses(orderedClasses: List[LinkedClass], logger: Logger, secondAttempt: Boolean): List[GeneratedClass] = { - val generatedClasses = orderedClasses.map(genClass) + + val objectClass = orderedClasses.find(_.name.name == ObjectClass).get + val generatedClasses = orderedClasses.map(genClass(_, objectClass)) val mentionedDangerousGlobalRefs = generatedClasses.foldLeft(Set.empty[String]) { (prev, generatedClass) => unionPreserveEmpty(prev, generatedClass.mentionedDangerousGlobalRefs) @@ -315,7 +317,8 @@ final class Emitter private (config: CommonPhaseConfig, } } - private def genClass(linkedClass: LinkedClass): GeneratedClass = { + private def genClass(linkedClass: LinkedClass, + objectClass: LinkedClass): GeneratedClass = { val className = linkedClass.encodedName val classCache = getClassCache(linkedClass.ancestors) val classTreeCache = classCache.getCache(linkedClass.version) @@ -351,7 +354,7 @@ final class Emitter private (config: CommonPhaseConfig, // Class definition if (linkedClass.hasInstances && kind.isAnyNonNativeClass) { - val (linkedInlineableInit, linkedMemberMethods) = + val (linkedInlineableInit, linkedMemberMethods0) = classEmitter.extractInlineableInit(linkedClass)(classCache) // JS constructor @@ -370,6 +373,40 @@ final class Emitter private (config: CommonPhaseConfig, classEmitter.genConstructor(linkedClass, initToInline)(ctorCache)) } + /* Bridges from Throwable to methods of Object, which are necessary + * because Throwable is rewired to extend JavaScript's Error instead of + * j.l.Object. + */ + val linkedMemberMethods = if (ClassEmitter.shouldExtendJSError(linkedClass)) { + val existingMethods = + linkedMemberMethods0.map(_.value.name.encodedName).toSet + + val bridges = for { + m <- objectClass.memberMethods + encodedName = m.value.name.encodedName + if !existingMethods.contains(encodedName) && !isConstructorName(encodedName) + } yield { + import org.scalajs.ir.Trees._ + import org.scalajs.ir.Types._ + + val methodDef = m.value + implicit val pos = methodDef.pos + + val methodName = methodDef.name.asInstanceOf[Ident] + val newBody = ApplyStatically(This()(ClassType(className)), + ClassType(ObjectClass), methodName, methodDef.args.map(_.ref))( + methodDef.resultType) + val newMethodDef = MethodDef(static = false, methodName, + methodDef.args, methodDef.resultType, Some(newBody))( + OptimizerHints.empty, None) + new Versioned(newMethodDef, m.version) + } + + linkedMemberMethods0 ++ bridges + } else { + linkedMemberMethods0 + } + // Normal methods val memberMethods = for (m <- linkedMemberMethods) yield { val methodCache = classCache.getMethodCache(m.value.encodedName) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/ThrowableJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/ThrowableJSTest.scala new file mode 100644 index 0000000000..c12abc29f2 --- /dev/null +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/ThrowableJSTest.scala @@ -0,0 +1,35 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013--2018, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package org.scalajs.testsuite.javalib.lang + +import scala.scalajs.js +import scala.scalajs.LinkingInfo.assumingES6 + +import org.junit.Test +import org.junit.Assert._ +import org.junit.Assume._ + +class ThrowableJSTest { + + @Test def throwablesAreJSErrors(): Unit = { + val t: Any = new Throwable("foo") + assertTrue(t.isInstanceOf[js.Error]) + } + + @Test def throwablesAreTrueErrors(): Unit = { + assumeTrue("Requires ECMAScript 2015", assumingES6) + + val t: Any = new Throwable("foo") + val str = js.constructorOf[js.Object].prototype + .selectDynamic("toString") + .call(t.asInstanceOf[js.Any]) + assertEquals("[object Error]", str) + } + +} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ThrowablesTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ThrowablesTest.scala index 3ecb32d2be..5b90b4c0d8 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ThrowablesTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ThrowablesTest.scala @@ -144,6 +144,34 @@ class ThrowablesTest { test3(new ExecutionException(_, _)) } + @Test def throwableStillHasMethodsOfObject(): Unit = { + @noinline + def callEquals(a: Any, b: Any): Boolean = a.equals(b) + + val t = new Throwable("foo") + assertTrue(callEquals(t, t)) + assertFalse(callEquals(t, new Throwable("foo"))) + assertFalse(callEquals(t, 55)) + } + + @Test def throwableJSToStringCanBeOverridden(): Unit = { + class ThrowableWithCustomToString extends Throwable("the message") { + override def toString(): String = "custom toString" + } + + @noinline + def callToString(a: Any): String = a.toString() + + @noinline + def concat(a: String, b: Any): String = a + b + + val t = new ThrowableWithCustomToString + assertEquals("custom toString", t.toString()) + assertEquals("custom toString", callToString(t)) + assertEquals("my custom toString", "my " + t) + assertEquals("my custom toString", concat("my ", t)) + } + @Test def assertionErrorsPeculiarConstructors(): Unit = { def assertMessageNoCause(expectedMessage: String, e: AssertionError): Unit = { assertEquals(expectedMessage, e.getMessage) From a50c5c5bba62b94ff3b2e5c39265269c47560e01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 10 Apr 2018 15:19:22 +0200 Subject: [PATCH 0706/2665] Upgrade to sbt 0.13.17. Mostly to get the fix to https://github.com/sbt/sbt/issues/3393. --- project/build.properties | 2 +- sbt-plugin-test/project/build.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/project/build.properties b/project/build.properties index c091b86ca4..133a8f197e 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.16 +sbt.version=0.13.17 diff --git a/sbt-plugin-test/project/build.properties b/sbt-plugin-test/project/build.properties index c091b86ca4..133a8f197e 100644 --- a/sbt-plugin-test/project/build.properties +++ b/sbt-plugin-test/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.16 +sbt.version=0.13.17 From 8c219b99b407d33202e095101470d8c7e1085103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 1 Nov 2017 00:32:15 +0100 Subject: [PATCH 0707/2665] [no-master] Migrate to sbt-platform-deps to provide `%%%`. We preserve binary compatibility and source compatibility by simply de-implicit-ify the conversion from `String` to the class providing `%%%`. This means that existing binaries will keep linking, while recompiled sources will resolve to the new implicit provided by sbt-platform-deps. We preserve `%%%!` by introducing *another* implicit conversion to a class that has only `%%%!`, but not `%%%`. That implicit conversion is immediately deprecated, since Scala.js 1.x will not support `%%%!`. --- project/Build.scala | 2 ++ project/build.sbt | 2 ++ .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 15 +++++++++++++++ .../scalajs/sbtplugin/ScalaJSPluginInternal.scala | 3 +++ .../sbtplugin/impl/DependencyBuilders.scala | 13 ++++++++++++- 5 files changed, 34 insertions(+), 1 deletion(-) diff --git a/project/Build.scala b/project/Build.scala index 903ec04502..229b60b59c 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -774,6 +774,8 @@ object Build { previousArtifactSetting, mimaBinaryIssueFilters ++= BinaryIncompatibilities.SbtPlugin, + addSbtPlugin("org.portable-scala" % "sbt-platform-deps" % "1.0.0"), + /* TODO Remove this in 1.x, since there are no macros in sbt-plugin * anymore. */ diff --git a/project/build.sbt b/project/build.sbt index c617bd52e6..b46dc04ee6 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -4,6 +4,8 @@ addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.18") addSbtPlugin("org.scalastyle" % "scalastyle-sbt-plugin" % "1.0.0") +addSbtPlugin("org.portable-scala" % "sbt-platform-deps" % "1.0.0") + libraryDependencies += "org.scala-js" % "closure-compiler-java-6" % "v20160517" libraryDependencies += "io.apigee" % "rhino" % "1.7R5pre4" diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 21957d61bf..08d030e6ba 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -9,6 +9,8 @@ package org.scalajs.sbtplugin +import scala.language.implicitConversions + import sbt._ import sbt.Keys._ @@ -489,6 +491,19 @@ object ScalaJSPlugin extends AutoPlugin { val scalaJSSourceMap = AttributeKey[File]("scalaJSSourceMap", "Source map file attached to an Attributed .js file.", BSetting) + + /* This is here instead of in impl.DependencyBuilders for binary + * compatibility reasons (impl.DependencyBuilders is a non-sealed trait). + */ + @deprecated( + """Use %%% if possible, or '"com.example" % "foo" % "1.0.0" cross """ + + """ScalaJSCrossVersion.binary"'""", + "0.6.23") + final implicit def toScalaJSGroupeIDForce( + groupID: String): impl.ScalaJSGroupIDForce = { + require(groupID.trim.nonEmpty, "Group ID cannot be empty.") + new impl.ScalaJSGroupIDForce(groupID) + } } import autoImport._ diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index e2de6bc456..ee5ed9ae2b 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -15,6 +15,8 @@ import SBTCompat._ import SBTCompat.formatImplicits._ import SBTCompat.formatImplicits.seqFormat +import org.portablescala.sbtplatformdeps.PlatformDepsPlugin.autoImport._ + import org.scalajs.core.tools.sem.Semantics import org.scalajs.core.tools.io.{IO => toolsIO, _} import org.scalajs.core.tools.jsdep._ @@ -1124,6 +1126,7 @@ object ScalaJSPluginInternal { val PhantomJSJetty = config("phantom-js-jetty").hide val scalaJSProjectBaseSettings = Seq( + platformDepsCrossVersion := ScalaJSCrossVersion.binary, isScalaJSProject := true, /* We first define scalaJSLinkerConfig in the project scope, with all diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/DependencyBuilders.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/DependencyBuilders.scala index ab1e29306e..8112b22daf 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/DependencyBuilders.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/DependencyBuilders.scala @@ -16,7 +16,11 @@ import scala.language.experimental.macros import sbt._ trait DependencyBuilders { - final implicit def toScalaJSGroupID(groupID: String): ScalaJSGroupID = { + @deprecated( + "Use org.portablescala.sbtplatformdeps.PlatformDepsPlugin.autoImport." + + "toPlatformDepsGroupID", + "0.6.23") + final def toScalaJSGroupID(groupID: String): ScalaJSGroupID = { require(groupID.trim.nonEmpty, "Group ID cannot be empty.") new ScalaJSGroupID(groupID) } @@ -61,6 +65,13 @@ trait DependencyBuilders { } } +final class ScalaJSGroupIDForce private[sbtplugin] (private val groupID: String) { + def %%%!(artifactID: String): CrossGroupArtifactID = { + require(artifactID.trim.nonEmpty, "Artifact ID cannot be empty.") + new CrossGroupArtifactID(groupID, artifactID, ScalaJSCrossVersion.binary) + } +} + final class ScalaJSGroupID private[sbtplugin] (private val groupID: String) { def %%%(artifactID: String): CrossGroupArtifactID = macro ScalaJSGroupID.auto_impl From d1c1288f78c229ae619475c331796ef7db12df5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 8 Apr 2018 12:52:04 +0200 Subject: [PATCH 0708/2665] [no-master] Deprecate crossProject and friends. Scala.js 1.x does not contain a built-in `crossProject` feature. Instead, users must use the external sbt-plugin https://github.com/portable-scala/sbt-crossproject in addition to sbt-scalajs. Since sbt-crossproject can be used with Scala.js 0.6.x as well, using a shadowing import described in the readme, we can deprecate the built-in cross-project functionality now, so that users are steered towards using sbt-crossproject earlier. --- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 7 +++- .../cross/CrossClasspathDependency.scala | 10 ++++++ .../sbtplugin/cross/CrossProject.scala | 35 +++++++++++++++++++ .../scalajs/sbtplugin/cross/CrossType.scala | 10 ++++++ 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 08d030e6ba..47f6bed71d 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -62,7 +62,12 @@ object ScalaJSPlugin extends AutoPlugin { val FullOptStage = Stage.FullOpt // CrossType - val CrossType = cross.CrossType + @deprecated( + "The built-in cross-project feature of sbt-scalajs is deprecated. " + + "Use the separate sbt plugin sbt-crossproject instead: " + + "https://github.com/portable-scala/sbt-crossproject", + "0.6.23") + lazy val CrossType = cross.CrossType // Factory methods for JSEnvs diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossClasspathDependency.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossClasspathDependency.scala index 91ef49acc5..d2610287a8 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossClasspathDependency.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossClasspathDependency.scala @@ -11,6 +11,11 @@ package org.scalajs.sbtplugin.cross import sbt._ +@deprecated( + "The built-in cross-project feature of sbt-scalajs is deprecated. " + + "Use the separate sbt plugin sbt-crossproject instead: " + + "https://github.com/portable-scala/sbt-crossproject", + "0.6.23") final class CrossClasspathDependency( val project: CrossProject, val configuration: Option[String] @@ -19,6 +24,11 @@ final class CrossClasspathDependency( def js: ClasspathDependency = ClasspathDependency(project.js, configuration) } +@deprecated( + "The built-in cross-project feature of sbt-scalajs is deprecated. " + + "Use the separate sbt plugin sbt-crossproject instead: " + + "https://github.com/portable-scala/sbt-crossproject", + "0.6.23") object CrossClasspathDependency { final class Constructor(crossProject: CrossProject) { def %(conf: Configuration): CrossClasspathDependency = %(conf.name) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossProject.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossProject.scala index ec75bcd707..73cf8cebfb 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossProject.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossProject.scala @@ -206,6 +206,11 @@ import java.io.File * Implement your own subclass (sub-object) of [[CrossType]]. * */ +@deprecated( + "The built-in cross-project feature of sbt-scalajs is deprecated. " + + "Use the separate sbt plugin sbt-crossproject instead: " + + "https://github.com/portable-scala/sbt-crossproject", + "0.6.23") final class CrossProject private ( crossType: CrossType, val jvm: Project, @@ -282,6 +287,11 @@ final class CrossProject private ( } +@deprecated( + "The built-in cross-project feature of sbt-scalajs is deprecated. " + + "Use the separate sbt plugin sbt-crossproject instead: " + + "https://github.com/portable-scala/sbt-crossproject", + "0.6.23") object CrossProject extends CrossProjectExtra { def apply(id: String, base: File, crossType: CrossType): CrossProject = { @@ -343,19 +353,44 @@ object CrossProject extends CrossProjectExtra { } +/** *Deprecated*. + * + * Not marked as `@deprecated` for technical reasons, but should be considered + * as such. All the members are deprecated. + */ trait CrossProjectExtra { + @deprecated( + "The built-in cross-project feature of sbt-scalajs is deprecated. " + + "Use the separate sbt plugin sbt-crossproject instead: " + + "https://github.com/portable-scala/sbt-crossproject", + "0.6.23") def crossProject: CrossProject.Builder = macro CrossProject.crossProject_impl + @deprecated( + "The built-in cross-project feature of sbt-scalajs is deprecated. " + + "Use the separate sbt plugin sbt-crossproject instead: " + + "https://github.com/portable-scala/sbt-crossproject", + "0.6.23") implicit def crossProjectFromBuilder( builder: CrossProject.Builder): CrossProject = { builder.crossType(CrossType.Full) } + @deprecated( + "The built-in cross-project feature of sbt-scalajs is deprecated. " + + "Use the separate sbt plugin sbt-crossproject instead: " + + "https://github.com/portable-scala/sbt-crossproject", + "0.6.23") implicit def crossClasspathDependencyConstructor( cp: CrossProject): CrossClasspathDependency.Constructor = new CrossClasspathDependency.Constructor(cp) + @deprecated( + "The built-in cross-project feature of sbt-scalajs is deprecated. " + + "Use the separate sbt plugin sbt-crossproject instead: " + + "https://github.com/portable-scala/sbt-crossproject", + "0.6.23") implicit def crossClasspathDependency( cp: CrossProject): CrossClasspathDependency = new CrossClasspathDependency(cp, None) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossType.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossType.scala index 643c3c615e..e21df988aa 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossType.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossType.scala @@ -13,6 +13,11 @@ import sbt._ import java.io.File +@deprecated( + "The built-in cross-project feature of sbt-scalajs is deprecated. " + + "Use the separate sbt plugin sbt-crossproject instead: " + + "https://github.com/portable-scala/sbt-crossproject", + "0.6.23") abstract class CrossType { /** The base directory for a (true sbt) Project @@ -36,6 +41,11 @@ abstract class CrossType { } +@deprecated( + "The built-in cross-project feature of sbt-scalajs is deprecated. " + + "Use the separate sbt plugin sbt-crossproject instead: " + + "https://github.com/portable-scala/sbt-crossproject", + "0.6.23") object CrossType { object Full extends CrossType { From f73592f0bad7faf06daf44449a93aab88ac0deee Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 17 Mar 2018 15:07:10 +0100 Subject: [PATCH 0709/2665] Move bootstrap test to its own configuration. This allows us to reuse the test execution machinery. As a result, we can remove ConsoleTestRunner. --- Jenkinsfile | 11 +- build.sbt | 1 + .../org/scalajs/io/NodeVirtualFiles.scala | 29 ++ .../org/scalajs/linker/test/QuickLinker.scala | 111 ----- project/Build.scala | 391 +++++++----------- project/TestSuiteLinkerOptions.scala | 35 ++ .../scalajs/bootstrap/TestSuiteLinker.scala | 51 +++ .../testsuite/utils/ConsoleTestRunner.scala | 72 ---- 8 files changed, 273 insertions(+), 428 deletions(-) delete mode 100644 linker/js/src/test/scala/org/scalajs/linker/test/QuickLinker.scala create mode 100644 project/TestSuiteLinkerOptions.scala create mode 100644 test-suite-linker/src/main/scala/org/scalajs/bootstrap/TestSuiteLinker.scala delete mode 100644 test-suite/js/src/main/scala/org/scalajs/testsuite/utils/ConsoleTestRunner.scala diff --git a/Jenkinsfile b/Jenkinsfile index 5e38122b85..228193b05e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -229,27 +229,22 @@ def Tasks = [ ++$scala $testSuite/test ''', - /* The reason we do `testSuite/test:fastOptJS` is that the linker tests will - * need the "discovered tests" from the test suite, which means we need to - * fast-optimize the test suite. We explicitly do it beforehand, so that the - * memory necessary to do that is not accumulated with the rest of the tests. - * Moreover, for the bootstrap tests to be able to call + /* For the bootstrap tests to be able to call * `testSuite/test:fastOptJS`, `scalaJSStage in testSuite` must be * `FastOptStage`, even when `scalaJSStage in Global` is `FullOptStage`. */ "bootstrap": ''' setJavaVersion $java npm install && - sbt ++$scala testSuite/test:fastOptJS && sbt ++$scala linker/test && sbt ++$scala irJS/test ioJS/test linkerJS/test && sbt 'set scalaJSStage in Global := FullOptStage' \ 'set scalaJSStage in testSuite := FastOptStage' \ ++$scala irJS/test ioJS/test linkerJS/test && - sbt ++$scala linkerJS/bootstrapTest && + sbt ++$scala testSuite/bootstrap:test && sbt 'set scalaJSStage in Global := FullOptStage' \ 'set scalaJSStage in testSuite := FastOptStage' \ - ++$scala linkerJS/bootstrapTest && + ++$scala testSuite/bootstrap:test && sbt ++$scala irJS/mimaReportBinaryIssues ioJS/mimaReportBinaryIssues \ loggingJS/mimaReportBinaryIssues linkerJS/mimaReportBinaryIssues ''', diff --git a/build.sbt b/build.sbt index 4167d0f2ab..99e7a6b897 100644 --- a/build.sbt +++ b/build.sbt @@ -34,6 +34,7 @@ val testingExample = Build.testingExample val testSuite = Build.testSuite val testSuiteJVM = Build.testSuiteJVM val testSuiteEx = Build.testSuiteEx +val testSuiteLinker = Build.testSuiteLinker val partest = Build.partest val partestSuite = Build.partestSuite val scalaTestSuite = Build.scalaTestSuite diff --git a/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala b/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala index 0c923223a2..53b048f22d 100644 --- a/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala +++ b/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala @@ -17,6 +17,16 @@ class NodeVirtualTextFile(p: String) extends NodeVirtualFile(p) override def content: String = NodeFS.readFileSync(path, NodeSupport.utf8enc) } +trait WritableNodeVirtualTextFile extends NodeVirtualTextFile + with WritableVirtualTextFile { + def contentWriter: Writer = new NodeWriter(path) +} + +object WritableNodeVirtualTextFile { + def apply(path: String): WritableNodeVirtualTextFile = + new NodeVirtualTextFile(path) with WritableNodeVirtualTextFile +} + class NodeVirtualBinaryFile(p: String) extends NodeVirtualFile(p) with VirtualBinaryFile { private def buf: ArrayBuffer = @@ -33,6 +43,17 @@ class NodeVirtualJSFile(p: String) extends NodeVirtualTextFile(p) override def sourceMap: Option[String] = None } +trait WritableNodeVirtualJSFile extends NodeVirtualJSFile + with WritableVirtualJSFile + with WritableNodeVirtualTextFile { + def sourceMapWriter: Writer = new NodeWriter(path + ".map") +} + +object WritableNodeVirtualJSFile { + def apply(path: String): WritableNodeVirtualJSFile = + new NodeVirtualJSFile(path) with WritableNodeVirtualJSFile +} + private[io] object NodeSupport { val utf8enc: NodeFS.Enc = new NodeFS.Enc { val encoding = "UTF-8" } } @@ -51,6 +72,7 @@ private[io] object NodeFS extends js.Object { def readFileSync(path: String): js.Array[Int] = js.native def readFileSync(path: String, enc: Enc): String = js.native def statSync(path: String): Stat = js.native + def writeFileSync(path: String, data: String, enc: Enc): Unit = js.native } private[scalajs] class NodeVirtualJarFile(file: String) @@ -111,3 +133,10 @@ private object NodeVirtualJarFile { def asArrayBuffer(): ArrayBuffer } } + +private[io] class NodeWriter(path: String) extends StringWriter { + override def close(): Unit = { + super.close() + NodeFS.writeFileSync(path, this.toString, NodeSupport.utf8enc) + } +} diff --git a/linker/js/src/test/scala/org/scalajs/linker/test/QuickLinker.scala b/linker/js/src/test/scala/org/scalajs/linker/test/QuickLinker.scala deleted file mode 100644 index 21ce773988..0000000000 --- a/linker/js/src/test/scala/org/scalajs/linker/test/QuickLinker.scala +++ /dev/null @@ -1,111 +0,0 @@ -package org.scalajs.linker.test - -import scala.scalajs.js -import scala.scalajs.js.annotation._ - -import org.scalajs.io._ - -import org.scalajs.logging._ - -import org.scalajs.linker._ -import org.scalajs.linker.irio._ - -import org.scalajs.linker.testutils.Platform - -@JSExportTopLevel("scalajs.QuickLinker") -object QuickLinker { - - /** Link a Scala.js application on Node.js */ - @JSExport - def linkNode(irFilesAndJars: js.Array[String], - moduleInitializers: js.Array[String]): String = { - linkNodeInternal(Semantics.Defaults, irFilesAndJars, moduleInitializers) - } - - /** Link the Scala.js test suite on Node.js */ - @JSExport - def linkTestSuiteNode(irFilesAndJars: js.Array[String], - moduleInitializers: js.Array[String]): String = { - import Semantics.RuntimeClassNameMapper - - val semantics = Semantics.Defaults.withRuntimeClassNameMapper( - RuntimeClassNameMapper.keepAll().andThen( - RuntimeClassNameMapper.regexReplace( - raw"""^org\.scalajs\.testsuite\.compiler\.ReflectionTest\$$RenamedTestClass$$""".r, - "renamed.test.Class") - ).andThen( - RuntimeClassNameMapper.regexReplace( - raw"""^org\.scalajs\.testsuite\.compiler\.ReflectionTest\$$Prefix""".r, - "renamed.test.byprefix.") - ).andThen( - RuntimeClassNameMapper.regexReplace( - raw"""^org\.scalajs\.testsuite\.compiler\.ReflectionTest\$$OtherPrefix""".r, - "renamed.test.byotherprefix.") - ) - ) - - linkNodeInternal(semantics, irFilesAndJars, moduleInitializers) - } - - /** Link a Scala.js application on Node.js */ - def linkNodeInternal(semantics: Semantics, - irFilesAndJars: Seq[String], moduleInitializers: Seq[String]): String = { - val cache = (new IRFileCache).newCache - - val config = StandardLinker.Config() - .withSemantics(semantics) - .withBatchMode(true) - val linker = StandardLinker(config) - - val irContainers = irFilesAndJars.map { file => - if (file.endsWith(".jar")) { - Platform.loadJar(file) - } else if (file.endsWith(".sjsir")) { - // The compiler should not use this (only scalajsp does) - val relativePath: String = s"" - new NodeVirtualScalaJSIRFile(file, relativePath) - } else { - throw new IllegalArgumentException("Illegal IR file / Jar: " + file) - } - } - - val ir = cache.cached(irContainers) - - val parsedModuleInitializers = - moduleInitializers.map(parseModuleInitializer) - - val out = WritableMemVirtualJSFile("out.js") - linker.link(ir, parsedModuleInitializers, out, new ScalaConsoleLogger) - - 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) - } - } - -} diff --git a/project/Build.scala b/project/Build.scala index 942b4c2868..27b324cb28 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -32,6 +32,7 @@ import Loggers._ import org.scalajs.io.{FileVirtualJSFile, MemVirtualJSFile} import org.scalajs.io.JSUtils.escapeJS import org.scalajs.linker._ +import org.scalajs.linker.irio._ /* Things that we want to expose in the sbt command line (and hence also in * `ci/matrix.xml`). @@ -63,7 +64,7 @@ object MyScalaJSPlugin extends AutoPlugin { val wantSourceMaps = settingKey[Boolean]("Whether source maps should be used") - private val configSettings: Seq[Setting[_]] = Def.settings( + val configSettings: Seq[Setting[_]] = Def.settings( // Add a JS file defining Java system properties jsExecutionFiles := { val prev = jsExecutionFiles.value @@ -160,8 +161,6 @@ object Build { "The major Java SDK version that should be assumed for compatibility. " + "Defaults to what sbt is running with.") - val bootstrapTest = taskKey[Unit]("Performs the bootstrap test") - val javaDocBaseURL: String = "http://docs.oracle.com/javase/8/docs/api/" private def includeIf(testDir: File, condition: Boolean): List[File] = @@ -707,123 +706,7 @@ object Build { ).settings( commonLinkerSettings, crossVersion := ScalaJSCrossVersion.binary, - - scalaJSLinkerConfig in Test ~= (_.withModuleKind(ModuleKind.CommonJSModule)), - - jsExecutionFiles in Test := { - val frameworks = (loadedTestFrameworks in testSuite in Test).value - val frameworkImplClassNames = - frameworks.toList.map(_._1.implClassNames.toList) - - val taskDefs = for (td <- (definedTests in testSuite in Test).value) yield { - new sbt.testing.TaskDef(td.name, td.fingerprint, - td.explicitlySpecified, td.selectors) - } - - val testDefinitions = { - org.scalajs.build.HTMLRunnerBuilderAccess.renderTestDefinitions( - frameworkImplClassNames, taskDefs.toList) - } - - 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( - NodeJSEnv.Config() - .withArgs(List("--max_old_space_size=3072")) - .withSourceMap(false)) - }, - - inConfig(Test) { - // Definition of the bootstrap test - bootstrapTest := { - /* We'll explicitly `require` our linked file. Find its module, and - * remove it from the `jsExecutionFiles` to give to the runner. - */ - val toolsTestModulePath = scalaJSLinkedFile.value.data.getPath - val executionFiles = - jsExecutionFiles.value.filter(_.path != toolsTestModulePath) - - /* 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. - */ - val cp = Attributed.data((fullClasspath in (testSuite, Test)).value) - - // Files must be Jars, non-files must be dirs - val (jars, dirs) = cp.filter(_.exists).partition(_.isFile) - val irFiles = dirs.flatMap(dir => (dir ** "*.sjsir").get) - - def seqOfStringsToJSArrayCode(strings: Seq[String]): String = - strings.map(s => "\"" + escapeJS(s) + "\"").mkString("[", ", ", "]") - - val irPaths = { - val absolutePaths = (jars ++ irFiles).map(_.getAbsolutePath) - seqOfStringsToJSArrayCode(absolutePaths) - } - - val mainMethods = { - /* Ideally we would read `scalaJSModuleInitializers in (testSuite, Test)`, - * but we cannot convert the ModuleInitializers to strings to be - * passed to the QuickLinker (because ModuleInitializer is a - * write-only data structure). So we have some duplication. - */ - val unescapedMainMethods = List( - "org.scalajs.testsuite.compiler.ModuleInitializers.mainNoArgs", - "org.scalajs.testsuite.compiler.ModuleInitializers.mainWithArgs()", - "org.scalajs.testsuite.compiler.ModuleInitializers.mainWithArgs(foo,bar)" - ) - seqOfStringsToJSArrayCode(unescapedMainMethods) - } - - val scalaJSEnvForTestSuite = { - s""" - {"javaSystemProperties": { - "scalajs.scalaVersion": "${scalaVersion.value}", - "scalajs.testsuite.testtag": "testtag.value", - "scalajs.nodejs": "true", - "scalajs.typedarray": "true", - "scalajs.fastopt-stage": "true", - "scalajs.modulekind-nomodule": "true" - }} - """ - } - - val code = { - s""" - var toolsTestModule = require("${escapeJS(toolsTestModulePath)}"); - var linker = toolsTestModule.scalajs.QuickLinker; - var lib = linker.linkTestSuiteNode($irPaths, $mainMethods); - - var __ScalaJSEnv = $scalaJSEnvForTestSuite; - eval("(function() { 'use strict'; " + - lib + ";" + - "scalajs.ConsoleTestRunner.runTests();" + - "}).call(this);"); - """ - } - - val launcher = new MemVirtualJSFile("Generated launcher file") - .withContent(code) - - val config = RunConfig() - .withLogger(sbtLogger2ToolsLogger(streams.value.log)) - - val input = Input.ScriptsToLoad((executionFiles :+ launcher).toList) - - val run = jsEnv.value.start(input, config) - Await.result(run.future, Duration.Inf) - } - } + scalaJSLinkerConfig in Test ~= (_.withModuleKind(ModuleKind.CommonJSModule)) ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( library, irProjectJS, ioJS, loggingJS, jUnitRuntime % "test" ) @@ -1362,92 +1245,80 @@ object Build { // Testing - val testTagSettings = { - val testOptionTags = TaskKey[Seq[String]]("testOptionTags", - "Task that lists all test options for javaOptions and testOptions.", - KeyRanks.Invisible) + val testTagJavaOptionsSetting = { + javaOptions ++= { + val s = streams.value - Seq( - testOptionTags := { - val s = streams.value - - def envTagsFor(env: JSEnv): Seq[String] = env match { - case env: NodeJSEnv => - val tags1 = Seq("nodejs", "typedarray") + def envTagsFor(env: JSEnv): Seq[String] = env match { + case env: NodeJSEnv => + val tags1 = Seq("nodejs", "typedarray") - if (MyScalaJSPlugin.wantSourceMaps.value) tags1 :+ "source-maps" - else tags1 + if (MyScalaJSPlugin.wantSourceMaps.value) tags1 :+ "source-maps" + else tags1 - case env: NodeJSEnvForcePolyfills => - Seq("nodejs", "source-maps") - - case _ => - s.log.warn( - s"Unknown JSEnv of class ${env.getClass.getName}: " + - "don't know what tags to specify for the test suite, " + - "so I will assume that TypedArrays are supported") - Seq("unknown-jsenv", "typedarray") - } + case env: NodeJSEnvForcePolyfills => + Seq("nodejs", "source-maps") - val envTags = envTagsFor((jsEnv in Test).value) + case _ => + s.log.warn( + s"Unknown JSEnv of class ${env.getClass.getName}: " + + "don't know what tags to specify for the test suite, " + + "so I will assume that TypedArrays are supported") + Seq("unknown-jsenv", "typedarray") + } - val stage = (scalaJSStage in Test).value + val envTags = envTagsFor(jsEnv.value) - val linkerConfig = stage match { - case FastOptStage => (scalaJSLinkerConfig in (Test, fastOptJS)).value - case FullOptStage => (scalaJSLinkerConfig in (Test, fullOptJS)).value - } - val sems = linkerConfig.semantics + val stage = scalaJSStage.value - val semTags = ( - if (sems.asInstanceOfs == CheckedBehavior.Compliant) - Seq("compliant-asinstanceofs") - else - Seq() - ) ++ ( - if (sems.arrayIndexOutOfBounds == CheckedBehavior.Compliant) - Seq("compliant-arrayindexoutofbounds") - else - Seq() - ) ++ ( - if (sems.moduleInit == CheckedBehavior.Compliant) - Seq("compliant-moduleinit") - else - Seq() - ) ++ ( - if (sems.strictFloats) Seq("strict-floats") - else Seq() - ) ++ ( - if (sems.productionMode) Seq("production-mode") - else Seq("development-mode") - ) + val linkerConfig = stage match { + case FastOptStage => (scalaJSLinkerConfig in fastOptJS).value + case FullOptStage => (scalaJSLinkerConfig in fullOptJS).value + } + val sems = linkerConfig.semantics - val stageTag = stage match { - case FastOptStage => "fastopt-stage" - case FullOptStage => "fullopt-stage" - } + val semTags = ( + if (sems.asInstanceOfs == CheckedBehavior.Compliant) + Seq("compliant-asinstanceofs") + else + Seq() + ) ++ ( + if (sems.arrayIndexOutOfBounds == CheckedBehavior.Compliant) + Seq("compliant-arrayindexoutofbounds") + else + Seq() + ) ++ ( + if (sems.moduleInit == CheckedBehavior.Compliant) + Seq("compliant-moduleinit") + else + Seq() + ) ++ ( + if (sems.strictFloats) Seq("strict-floats") + else Seq() + ) ++ ( + if (sems.productionMode) Seq("production-mode") + else Seq("development-mode") + ) - val moduleKindTag = linkerConfig.moduleKind match { - case ModuleKind.NoModule => "modulekind-nomodule" - case ModuleKind.CommonJSModule => "modulekind-commonjs" - } + val stageTag = stage match { + case FastOptStage => "fastopt-stage" + case FullOptStage => "fullopt-stage" + } - envTags ++ (semTags :+ stageTag :+ moduleKindTag) - }, - javaOptions in Test ++= { - def scalaJSProp(name: String): String = - s"-Dscalajs.$name=true" + val moduleKindTag = linkerConfig.moduleKind match { + case ModuleKind.NoModule => "modulekind-nomodule" + case ModuleKind.CommonJSModule => "modulekind-commonjs" + } - testOptionTags.value.map(scalaJSProp) :+ - "-Dscalajs.testsuite.testtag=testtag.value" - }, - testOptions in Test ++= { - def testArgument(arg: String): Tests.Argument = - Tests.Argument("-t" + arg) + def scalaJSProp(name: String): String = + s"-Dscalajs.$name=true" - testOptionTags.value.map(testArgument) - } - ) + val tags = envTags ++ (semTags :+ stageTag :+ moduleKindTag) + tags.map(scalaJSProp) ++ List( + "-Dscalajs.testsuite.testtag=testtag.value", + "-Dscalajs.scalaVersion=" + scalaVersion.value + ) + } } def testSuiteCommonSettings(isJSTest: Boolean): Seq[Setting[_]] = Seq( @@ -1551,20 +1422,87 @@ object Build { } ) + def testSuiteBootstrapSetting = Def.settings( + Defaults.testSettings, + ScalaJSPlugin.testConfigSettings, + MyScalaJSPlugin.configSettings, + + fullOptJS := { + throw new MessageOnlyException("fullOptJS is not supported in Bootstrap") + }, + + fastOptJS := { + val s = streams.value + + val irFiles = { + val cp = Attributed.data(fullClasspath.value) + FileScalaJSIRContainer.fromClasspath(cp).map(_.file) + } + + val out = (artifactPath in fastOptJS).value + + val linkerModule = + (scalaJSLinkedFile in (testSuiteLinker, Compile)).value.data + + FileFunction.cached(s.cacheDirectory, FilesInfo.lastModified, + FilesInfo.exists) { _ => + + val irPaths = irFiles + .map(f => "\"" + escapeJS(f.getAbsolutePath) + "\"") + .mkString("[", ", ", "]") + + val code = { + s""" + var toolsTestModule = require("${escapeJS(linkerModule.getPath)}"); + var linker = toolsTestModule.TestSuiteLinker; + linker.linkTestSuiteNode($irPaths, "${escapeJS(out.getAbsolutePath)}"); + """ + } + + val launcher = + new MemVirtualJSFile("test-suite-linker.js").withContent(code) + + val config = RunConfig().withLogger(sbtLogger2ToolsLogger(s.log)) + val input = Input.ScriptsToLoad(List(launcher)) + + s.log.info(s"Linking test suite with JS linker") + + val jsEnv = new NodeJSEnv( + NodeJSEnv.Config() + .withArgs(List("--max_old_space_size=3072")) + .withSourceMap(false)) + + val run = jsEnv.start(input, config) + Await.result(run.future, Duration.Inf) + Set(out) + } ((irFiles :+ linkerModule).toSet) + + Attributed.blank(out) + }, + + compile := (compile in Test).value, + fullClasspath := (fullClasspath in Test).value, + testTagJavaOptionsSetting, + testSuiteJSExecutionFilesSetting + ) + def testSuiteJSExecutionFilesSetting: Setting[_] = { - jsExecutionFiles in Test := { - val resourceDir = - (resourceDirectory in (LocalProject("testSuite"), Test)).value + jsExecutionFiles := { + val resourceDir = (resourceDirectory in Test).value val f = FileVirtualJSFile(resourceDir / "NonNativeJSTypeTestNatives.js") - f +: (jsExecutionFiles in Test).value + f +: jsExecutionFiles.value } } + lazy val Bootstrap = config("bootstrap") + .describedAs("Configuration that uses a JS linker instead of the JVM") + lazy val testSuite: Project = (project in file("test-suite/js")).enablePlugins( MyScalaJSPlugin - ).settings( + ).configs(Bootstrap).settings( commonSettings, - testTagSettings, + inConfig(Test)(testTagJavaOptionsSetting), + inConfig(Test)(testSuiteJSExecutionFilesSetting), testSuiteCommonSettings(isJSTest = true), name := "Scala.js test suite", @@ -1575,31 +1513,8 @@ object Build { scalaJSLinkerConfig.value.moduleKind != ModuleKind.NoModule) }, - testSuiteJSExecutionFilesSetting, - - scalaJSLinkerConfig ~= { prevConfig => - import Semantics.RuntimeClassNameMapper - - prevConfig.withSemantics { sems => - sems.withRuntimeClassNameMapper( - RuntimeClassNameMapper.keepAll().andThen( - RuntimeClassNameMapper.regexReplace( - raw"""^org\.scalajs\.testsuite\.compiler\.ReflectionTest\$$RenamedTestClass$$""".r, - "renamed.test.Class") - ).andThen( - RuntimeClassNameMapper.regexReplace( - raw"""^org\.scalajs\.testsuite\.compiler\.ReflectionTest\$$Prefix""".r, - "renamed.test.byprefix.") - ).andThen( - RuntimeClassNameMapper.regexReplace( - raw"""^org\.scalajs\.testsuite\.compiler\.ReflectionTest\$$OtherPrefix""".r, - "renamed.test.byotherprefix.") - ) - ) - } - }, - - javaOptions in Test += "-Dscalajs.scalaVersion=" + scalaVersion.value, + scalaJSLinkerConfig ~= { _.withSemantics(TestSuiteLinkerOptions.semantics _) }, + scalaJSModuleInitializers in Test ++= TestSuiteLinkerOptions.moduleInitializers, /* Generate a scala source file that throws exceptions in * various places (while attaching the source line to the @@ -1679,17 +1594,8 @@ object Build { } }, - // Module initializers. Duplicated in toolsJS/test - scalaJSModuleInitializers in Test ++= { - val module = "org.scalajs.testsuite.compiler.ModuleInitializers" - Seq( - ModuleInitializer.mainMethod(module, "mainNoArgs"), - ModuleInitializer.mainMethodWithArgs(module, "mainWithArgs"), - ModuleInitializer.mainMethodWithArgs(module, "mainWithArgs", List("foo", "bar")) - ) - }, - - testSuiteTestHtmlSetting + testSuiteTestHtmlSetting, + inConfig(Bootstrap)(testSuiteBootstrapSetting) ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( library, jUnitRuntime ) @@ -1728,7 +1634,7 @@ object Build { MyScalaJSPlugin ).settings( commonSettings, - testTagSettings, + inConfig(Test)(testTagJavaOptionsSetting), name := "Scala.js test suite ex", publishArtifact in Compile := false, testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a", "-s"), @@ -1737,6 +1643,17 @@ object Build { library, jUnitRuntime, testSuite ) + + lazy val testSuiteLinker = (project in file("test-suite-linker")).enablePlugins( + MyScalaJSPlugin + ).settings( + exampleSettings, + name := "Scala.js test suite linker", + scalaJSLinkerConfig ~= (_.withModuleKind(ModuleKind.CommonJSModule)), + sources in Compile += + baseDirectory.value.getParentFile / "project/TestSuiteLinkerOptions.scala" + ).withScalaJSCompiler.dependsOn(linkerJS) + lazy val partest: Project = project.settings( commonSettings, fatalWarningsSettings, diff --git a/project/TestSuiteLinkerOptions.scala b/project/TestSuiteLinkerOptions.scala new file mode 100644 index 0000000000..dbb5bed3cf --- /dev/null +++ b/project/TestSuiteLinkerOptions.scala @@ -0,0 +1,35 @@ +package build + +import org.scalajs.linker._ + +object TestSuiteLinkerOptions { + + def semantics(s: Semantics): Semantics = { + import Semantics.RuntimeClassNameMapper + + s.withRuntimeClassNameMapper( + RuntimeClassNameMapper.keepAll().andThen( + RuntimeClassNameMapper.regexReplace( + raw"""^org\.scalajs\.testsuite\.compiler\.ReflectionTest\$$RenamedTestClass$$""".r, + "renamed.test.Class") + ).andThen( + RuntimeClassNameMapper.regexReplace( + raw"""^org\.scalajs\.testsuite\.compiler\.ReflectionTest\$$Prefix""".r, + "renamed.test.byprefix.") + ).andThen( + RuntimeClassNameMapper.regexReplace( + raw"""^org\.scalajs\.testsuite\.compiler\.ReflectionTest\$$OtherPrefix""".r, + "renamed.test.byotherprefix.") + ) + ) + } + + def moduleInitializers: List[ModuleInitializer] = { + val module = "org.scalajs.testsuite.compiler.ModuleInitializers" + List( + ModuleInitializer.mainMethod(module, "mainNoArgs"), + ModuleInitializer.mainMethodWithArgs(module, "mainWithArgs"), + ModuleInitializer.mainMethodWithArgs(module, "mainWithArgs", List("foo", "bar")) + ) + } +} diff --git a/test-suite-linker/src/main/scala/org/scalajs/bootstrap/TestSuiteLinker.scala b/test-suite-linker/src/main/scala/org/scalajs/bootstrap/TestSuiteLinker.scala new file mode 100644 index 0000000000..a2ef990ed1 --- /dev/null +++ b/test-suite-linker/src/main/scala/org/scalajs/bootstrap/TestSuiteLinker.scala @@ -0,0 +1,51 @@ +package org.scalajs.linker.test + +import scala.scalajs.js +import scala.scalajs.js.annotation._ + +import org.scalajs.io._ + +import org.scalajs.logging._ + +import org.scalajs.linker._ +import org.scalajs.linker.irio._ + +@JSExportTopLevel("TestSuiteLinker") +object QuickLinker { + /** Link the Scala.js test suite on Node.js */ + @JSExport + def linkTestSuiteNode(irFilesAndJars: js.Array[String], outputPath: String): Unit = { + val config = StandardLinker.Config() + .withSemantics(build.TestSuiteLinkerOptions.semantics _) + .withCheckIR(true) + .withBatchMode(true) + + val linker = StandardLinker(config) + + val moduleInitializers = build.TestSuiteLinkerOptions.moduleInitializers + + val ir = extractIR(irFilesAndJars) + + val out = WritableNodeVirtualJSFile(outputPath) + linker.link(ir, moduleInitializers, out, new ScalaConsoleLogger) + + out.content + } + + private def extractIR(irFilesAndJars: Seq[String]): Seq[VirtualScalaJSIRFile] = { + val cache = (new IRFileCache).newCache + val irContainers = irFilesAndJars.map { file => + if (file.endsWith(".jar")) { + new NodeVirtualJarScalaJSIRContainer(file) + } else if (file.endsWith(".sjsir")) { + // The compiler should not use this (only scalajsp does) + val relativePath: String = s"" + new NodeVirtualScalaJSIRFile(file, relativePath) + } else { + throw new IllegalArgumentException("Illegal IR file / Jar: " + file) + } + } + + cache.cached(irContainers) + } +} 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 deleted file mode 100644 index 04352c4ba7..0000000000 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/ConsoleTestRunner.scala +++ /dev/null @@ -1,72 +0,0 @@ -package org.scalajs.testsuite.utils - -import scala.collection.mutable - -import scala.scalajs.js -import scala.scalajs.js.annotation._ - -import org.scalajs.testinterface.{ScalaJSClassLoader, TestDetector} - -import sbt.testing._ - -@JSExportTopLevel("scalajs.ConsoleTestRunner") -object ConsoleTestRunner { - - @JSExport - def runTests(): Unit = { - try { - val eventHandler = new SimpleEventHandler - val loggers = Array[Logger](new SimpleLogger) - - def taskLoop(tasks: Iterable[Task]): Unit = { - if (tasks.nonEmpty) - tasks.head.execute(eventHandler, loggers, - newTasks => taskLoop(tasks.tail ++ newTasks)) - } - - for { - (framework, taskDefs) <- TestDetector.detectTests() - } { - val runner = framework.runner(Array(), Array(), new ScalaJSClassLoader()) - val tasks = runner.tasks(taskDefs.toArray) - taskLoop(tasks) - } - - val failedEvents = eventHandler.failedEvents - if (failedEvents.nonEmpty) { - System.err.println("The following tests failed:") - for (event <- failedEvents) { - System.err.println("* " + event.fullyQualifiedName()) - if (event.throwable().isDefined()) - event.throwable().get().printStackTrace() - } - throw new AssertionError("Some tests have failed") - } - } catch { - case th: Throwable => - th.printStackTrace() - throw th - } - } - - private class SimpleEventHandler extends EventHandler { - private[this] val _failedEvents = new mutable.ListBuffer[Event] - - def failedEvents: List[Event] = _failedEvents.toList - - def handle(ev: Event): Unit = { - if (ev.status == Status.Error || ev.status == Status.Failure) - _failedEvents += ev - } - } - - private class SimpleLogger extends Logger { - def ansiCodesSupported(): Boolean = false - def error(msg: String): Unit = println(msg) - def warn(msg: String): Unit = println(msg) - def info(msg: String): Unit = println(msg) - def debug(msg: String): Unit = println(msg) - def trace(t: Throwable): Unit = t.printStackTrace - } - -} From eef31797597406bcf66e32f2893042725fd0a313 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 10 Apr 2018 23:34:33 +0200 Subject: [PATCH 0710/2665] Tighten `Match` nodes to only accept selectors of type `IntType`. This corresponds to how switch tables work on the JVM, and hence to how `GenBCode` works in Scala/JVM anyway. This tightening fixes by construction some loopholes that were present with looser `Match`s. For example, `Long`s could not be reliably used anyway, because their `===` compares the *references* to `RuntimeLong` instances rather than the underlying values. --- .../org/scalajs/nscplugin/GenJSCode.scala | 21 +++++++++++++++---- .../scala/org/scalajs/ir/Serializers.scala | 2 +- ir/src/main/scala/org/scalajs/ir/Trees.scala | 6 +++--- .../backend/emitter/FunctionEmitter.scala | 2 +- .../scalajs/linker/checker/IRChecker.scala | 14 ++++++------- .../frontend/optimizer/OptimizerCore.scala | 16 +++++++------- 6 files changed, 36 insertions(+), 25 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala index 7f6f22f113..688377c77e 100644 --- a/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala @@ -3108,7 +3108,16 @@ abstract class GenJSCode extends plugins.PluginComponent implicit val pos = tree.pos val Match(selector, cases) = tree - val expr = genExpr(selector) + /* We adapt the selector to IntType so that we can use it in a js.Match, + * just like GenBCode does for the JVM. This seems to be redundant, + * though, as anything that comes out of the pattern matching has already + * been adapted to an Int (along with the cases). However, since GenBCode + * adapts, we do the same, to be on the safe side (for example, a + * compiler plugin could generate a Match with other types of + * primitives ...). + */ + val expr = adaptPrimitive(genExpr(selector), jstpe.IntType) + val resultType = toIRType(tree.tpe) val defaultLabelSym = cases.collectFirst { @@ -3117,7 +3126,7 @@ abstract class GenJSCode extends plugins.PluginComponent body.symbol }.getOrElse(NoSymbol) - var clauses: List[(List[js.Literal], js.Tree)] = Nil + var clauses: List[(List[js.IntLiteral], js.Tree)] = Nil var optElseClause: Option[js.Tree] = None var optElseClauseLabel: Option[js.Ident] = None @@ -3168,8 +3177,12 @@ abstract class GenJSCode extends plugins.PluginComponent genStatOrExpr(body, isStat) } - def genLiteral(lit: Literal): js.Literal = - genExpr(lit).asInstanceOf[js.Literal] + /* value.intValue implicitly adapts the constant value to an Int. This + * is also what GenBCode for the JVM. See also the comment about + * adaptPrimitive at the beginning of this method. + */ + def genLiteral(lit: Literal): js.IntLiteral = + js.IntLiteral(lit.value.intValue)(lit.pos) pat match { case lit: Literal => diff --git a/ir/src/main/scala/org/scalajs/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/ir/Serializers.scala index 192165e5a1..c927585d7d 100644 --- a/ir/src/main/scala/org/scalajs/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/ir/Serializers.scala @@ -850,7 +850,7 @@ object Serializers { case TagThrow => Throw(readTree()) case TagMatch => Match(readTree(), List.fill(readInt()) { - (readTrees().map(_.asInstanceOf[Literal]), readTree()) + (readTrees().map(_.asInstanceOf[IntLiteral]), readTree()) }, readTree())(readType()) case TagDebugger => Debugger() diff --git a/ir/src/main/scala/org/scalajs/ir/Trees.scala b/ir/src/main/scala/org/scalajs/ir/Trees.scala index fc21c3e786..7b918f6077 100644 --- a/ir/src/main/scala/org/scalajs/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/ir/Trees.scala @@ -218,12 +218,12 @@ object Trees { /** A break-free switch (without fallthrough behavior). * Unlike a JavaScript switch, it can be used in expression position. - * It supports alternatives explicitly (hence the List[Tree] in cases), - * whereas in a switch one would use the fallthrough behavior to + * It supports alternatives explicitly (hence the `List[IntLiteral]` in + * cases), whereas in a switch one would use the fallthrough behavior to * implement alternatives. * (This is not a pattern matching construct like in Scala.) */ - case class Match(selector: Tree, cases: List[(List[Literal], Tree)], + case class Match(selector: Tree, cases: List[(List[IntLiteral], Tree)], default: Tree)(val tpe: Type)(implicit val pos: Position) extends Tree case class Debugger()(implicit val pos: Position) extends Tree { diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala index bbf561d042..ada13c88d4 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala @@ -1557,7 +1557,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { val newCases = { for { (values, body) <- cases - newValues = values.map(transformExpr(_, preserveChar = true)) + newValues = values.map(v => js.IntLiteral(v.value)(v.pos)) // add the break statement newBody = js.Block( pushLhsInto(newLhs, body, tailPosLabels)(branchesEnv), diff --git a/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala b/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala index fb7a4b9e08..e789ead2df 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala @@ -607,11 +607,10 @@ private final class IRChecker(unit: LinkingUnit, env case Match(selector, cases, default) => - typecheckExpr(selector, env) - for ((alts, body) <- cases) { - alts.foreach(typecheckExpr(_, env)) + typecheckExpect(selector, env, IntType) + // The alternatives are IntLiterals, no point typechecking them + for ((_, body) <- cases) typecheckStat(body, env) - } typecheckStat(default, env) env @@ -722,11 +721,10 @@ private final class IRChecker(unit: LinkingUnit, case Match(selector, cases, default) => val tpe = tree.tpe - typecheckExpr(selector, env) - for ((alts, body) <- cases) { - alts.foreach(typecheckExpr(_, env)) + typecheckExpect(selector, env, IntType) + // The alternatives are IntLiterals, no point typechecking them + for ((_, body) <- cases) typecheckExpect(body, env, tpe) - } typecheckExpect(default, env, tpe) // Scala expressions diff --git a/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala b/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala index 63299c2088..e69d9bf0c1 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala @@ -430,10 +430,10 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case Match(selector, cases, default) => val newSelector = transformExpr(selector) newSelector match { - case newSelector: Literal => - val body = cases collectFirst { - case (alts, body) if alts.exists(literal_===(_, newSelector)) => body - } getOrElse default + case IntLiteral(selectorValue) => + val body = cases.collectFirst { + case (alts, body) if alts.exists(_.value == selectorValue) => body + }.getOrElse(default) transform(body, isStat) case _ => Match(newSelector, @@ -783,10 +783,10 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case Match(selector, cases, default) => val newSelector = transformExpr(selector) newSelector match { - case newSelector: Literal => - val body = cases collectFirst { - case (alts, body) if alts.exists(literal_===(_, newSelector)) => body - } getOrElse default + case IntLiteral(selectorValue) => + val body = cases.collectFirst { + case (alts, body) if alts.exists(_.value == selectorValue) => body + }.getOrElse(default) pretransformExpr(body)(cont) case _ => cont(Match(newSelector, From d4126f76ef611be2ae6c817d3dc503aca026ec06 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 17 Mar 2018 10:15:13 +0100 Subject: [PATCH 0711/2665] Merge testinterface.internal to testinterface internal used to exists to make it clear that exports are not to be called anymore. Now that we are about to remove the exports, the package is moot and can be replaced with package-private visibility. --- .../testinterface/{internal => }/FrameworkLoader.scala | 4 ++-- .../org/scalajs/testinterface/{internal => }/JSRPC.scala | 4 ++-- .../testinterface/{internal => }/TaskInfoBuilder.scala | 4 ++-- .../{internal/Bridge.scala => TestAdapterBridge.scala} | 6 ++---- 4 files changed, 8 insertions(+), 10 deletions(-) rename test-interface/src/main/scala/org/scalajs/testinterface/{internal => }/FrameworkLoader.scala (89%) rename test-interface/src/main/scala/org/scalajs/testinterface/{internal => }/JSRPC.scala (86%) rename test-interface/src/main/scala/org/scalajs/testinterface/{internal => }/TaskInfoBuilder.scala (87%) rename test-interface/src/main/scala/org/scalajs/testinterface/{internal/Bridge.scala => TestAdapterBridge.scala} (96%) diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkLoader.scala b/test-interface/src/main/scala/org/scalajs/testinterface/FrameworkLoader.scala similarity index 89% rename from test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkLoader.scala rename to test-interface/src/main/scala/org/scalajs/testinterface/FrameworkLoader.scala index 47ec713ae0..a8c86c8d17 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkLoader.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/FrameworkLoader.scala @@ -1,11 +1,11 @@ -package org.scalajs.testinterface.internal +package org.scalajs.testinterface import scala.scalajs.js import scala.scalajs.reflect.Reflect import sbt.testing.Framework -private[internal] object FrameworkLoader { +private[testinterface] object FrameworkLoader { def loadFramework(frameworkName: String): Framework = { val clazz = Reflect.lookupInstantiatableClass(frameworkName).getOrElse { diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/JSRPC.scala b/test-interface/src/main/scala/org/scalajs/testinterface/JSRPC.scala similarity index 86% rename from test-interface/src/main/scala/org/scalajs/testinterface/internal/JSRPC.scala rename to test-interface/src/main/scala/org/scalajs/testinterface/JSRPC.scala index b2553d4689..72c92545f7 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/JSRPC.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/JSRPC.scala @@ -1,4 +1,4 @@ -package org.scalajs.testinterface.internal +package org.scalajs.testinterface import scala.scalajs.js import scala.scalajs.js.annotation._ @@ -9,7 +9,7 @@ import scala.concurrent.ExecutionContext.Implicits.global import org.scalajs.testcommon.RPCCore /** JS RPC Core. Uses `scalajsCom`. */ -private[internal] final object JSRPC extends RPCCore { +private[testinterface] final object JSRPC extends RPCCore { Com.init(handleMessage _) override protected def send(msg: String): Unit = Com.send(msg) diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/TaskInfoBuilder.scala b/test-interface/src/main/scala/org/scalajs/testinterface/TaskInfoBuilder.scala similarity index 87% rename from test-interface/src/main/scala/org/scalajs/testinterface/internal/TaskInfoBuilder.scala rename to test-interface/src/main/scala/org/scalajs/testinterface/TaskInfoBuilder.scala index 6aded8a49a..c9c7f0d56a 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/TaskInfoBuilder.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/TaskInfoBuilder.scala @@ -1,10 +1,10 @@ -package org.scalajs.testinterface.internal +package org.scalajs.testinterface import sbt.testing._ import org.scalajs.testcommon.{TaskInfo, Serializer} -private[internal] object TaskInfoBuilder { +private[testinterface] object TaskInfoBuilder { def detachTask(task: Task, runner: Runner): TaskInfo = { def optSerializer(t: TaskDef) = if (t == task.taskDef) "" diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Bridge.scala b/test-interface/src/main/scala/org/scalajs/testinterface/TestAdapterBridge.scala similarity index 96% rename from test-interface/src/main/scala/org/scalajs/testinterface/internal/Bridge.scala rename to test-interface/src/main/scala/org/scalajs/testinterface/TestAdapterBridge.scala index 22b7d35752..9a667c2ff4 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Bridge.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/TestAdapterBridge.scala @@ -1,7 +1,6 @@ -package org.scalajs.testinterface.internal +package org.scalajs.testinterface import scala.scalajs.js.annotation._ -import scala.scalajs.reflect.Reflect import scala.concurrent.{Future, Promise} @@ -9,11 +8,10 @@ import scala.util.control.NonFatal import scala.util.Try import org.scalajs.testcommon._ -import org.scalajs.testinterface.ScalaJSClassLoader import sbt.testing._ -private object Bridge { +private[testinterface] object TestAdapterBridge { private[this] val mux = new RunMuxRPC(JSRPC) From 9588002942bd9850ba1ae459e60787416535733c Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Wed, 11 Apr 2018 09:07:50 +0200 Subject: [PATCH 0712/2665] Remove HTMLRunnerBuilderAccess This was one of the main reasons for #3337, but ironically I forgot to do it. --- project/HTMLRunnerBuilderAccess.scala | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 project/HTMLRunnerBuilderAccess.scala diff --git a/project/HTMLRunnerBuilderAccess.scala b/project/HTMLRunnerBuilderAccess.scala deleted file mode 100644 index f33cb718b0..0000000000 --- a/project/HTMLRunnerBuilderAccess.scala +++ /dev/null @@ -1,13 +0,0 @@ -package org.scalajs.build - -import sbt.testing.TaskDef - -/** Accessor for renderTestDefinitions to avoid exposing things. */ -object HTMLRunnerBuilderAccess { - def renderTestDefinitions( - frameworkImplClassNames: List[List[String]], - taskDefs: List[TaskDef]): String = { - org.scalajs.testadapter.HTMLRunnerBuilder.renderTestDefinitions( - frameworkImplClassNames, taskDefs) - } -} From 9454de4d140d2e40650418a7cebc6210d3bc78b5 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 17 Mar 2018 10:17:41 +0100 Subject: [PATCH 0713/2665] Fix #3294: Start testing instrumentation code via module initializer --- sbt-plugin-test/build.sbt | 4 +- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 4 + .../sbtplugin/ScalaJSPluginInternal.scala | 83 +++++++++++-------- .../testadapter/HTMLRunnerBuilder.scala | 34 +++----- .../org/scalajs/testadapter/TestAdapter.scala | 58 ++----------- .../testadapter/TestAdapterInitializer.scala | 15 ++++ .../scalajs/testcommon/IsolatedTestSet.scala | 28 +++++++ .../testcommon/TestInterfaceMode.scala | 28 +++++++ .../org/scalajs/testinterface/Bridge.scala | 24 ++++++ .../testinterface/FrameworkLoader.scala | 11 +++ .../scalajs/testinterface/HTMLRunner.scala | 16 +++- .../testinterface/TestAdapterBridge.scala | 3 - .../scalajs/testinterface/TestDetector.scala | 63 -------------- .../scalajs/testinterface/TestLoader.scala | 38 +++++++++ .../scalajs/bootstrap/TestSuiteLinker.scala | 6 +- 15 files changed, 237 insertions(+), 178 deletions(-) create mode 100644 test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapterInitializer.scala create mode 100644 test-common/src/main/scala/org/scalajs/testcommon/IsolatedTestSet.scala create mode 100644 test-common/src/main/scala/org/scalajs/testcommon/TestInterfaceMode.scala create mode 100644 test-interface/src/main/scala/org/scalajs/testinterface/Bridge.scala delete mode 100644 test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala create mode 100644 test-interface/src/main/scala/org/scalajs/testinterface/TestLoader.scala diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index 2eea32a91f..c22b4f7cab 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -49,8 +49,8 @@ lazy val noDOM = project.settings(baseSettings: _*). assert((scalaJSModuleInitializers in Compile).value.size == 2, "Bad number of scalaJSModuleInitializers in Compile") - // Test should have InitHolder.foo and TestApp.foo - assert((scalaJSModuleInitializers in Test).value.size == 2, + // Test should have test module init, InitHolder.foo and TestApp.foo + assert((scalaJSModuleInitializers in Test).value.size == 3, "Bad number of scalaJSModuleInitializers in Test") } ). diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 1ebb74dbc1..d3d1a62596 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -104,6 +104,10 @@ object ScalaJSPlugin extends AutoPlugin { "If true, adds the `mainClass` as a module initializer of the Scala.js module", APlusSetting) + val scalaJSUseTestModuleInitializer = SettingKey[Boolean]("scalaJSUseTestModuleInitializer", + "If true, adds the module initializer required for testing to the Scala.js module", + BMinusSetting) + val scalaJSMainModuleInitializer = TaskKey[Option[ModuleInitializer]]( "scalaJSMainModuleInitializer", "The main module initializer, used if " + diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 645ea97208..f468e7b353 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -22,8 +22,7 @@ import org.scalajs.jsenv._ import org.scalajs.ir.Printers.IRTreePrinter -import org.scalajs.testadapter.{TestAdapter, HTMLRunnerBuilder} -import org.scalajs.testadapter.TestAdapter.ModuleIdentifier +import org.scalajs.testadapter.{TestAdapter, HTMLRunnerBuilder, TestAdapterInitializer} import Loggers._ import SBTCompat._ @@ -64,10 +63,9 @@ private[sbtplugin] object ScalaJSPluginInternal { private val createdTestAdapters = new AtomicReference[List[TestAdapter]](Nil) - private def newTestAdapter(jsEnv: JSEnv, jsFiles: Seq[VirtualJSFile], + private def newTestAdapter(jsEnv: JSEnv, input: Input, config: TestAdapter.Config): TestAdapter = { - registerResource(createdTestAdapters, - new TestAdapter(jsEnv, jsFiles, config)) + registerResource(createdTestAdapters, new TestAdapter(jsEnv, input, config)) } private[sbtplugin] def closeAllTestAdapters(): Unit = @@ -335,33 +333,65 @@ private[sbtplugin] object ScalaJSPluginInternal { scalaJSConfigSettings ) - private val scalaJSTestFrameworkSettings = Seq( + val scalaJSTestSettings: Seq[Setting[_]] = ( + scalaJSConfigSettings + ) ++ Seq( + /* Always default to false for scalaJSUseMainModuleInitializer in testing + * configurations, even if it is true in the Global configuration scope. + */ + scalaJSUseMainModuleInitializer := false, + + // Use test module initializer by default. + scalaJSUseTestModuleInitializer := true, + + scalaJSModuleInitializers ++= { + val useMain = scalaJSUseMainModuleInitializer.value + val useTest = scalaJSUseTestModuleInitializer.value + val configName = configuration.value.name + + if (useTest) { + if (useMain) { + throw new MessageOnlyException("You may only set one of " + + s"`scalaJSUseMainModuleInitializer in $configName` and " + + s"`scalaJSUseTestModuleInitializer in $configName` to true") + } + + Seq( + ModuleInitializer.mainMethod( + TestAdapterInitializer.ModuleClassName, + TestAdapterInitializer.MainMethodName) + ) + } else { + Seq.empty + } + }, + loadedTestFrameworks := { + val configName = configuration.value.name + if (fork.value) { throw new MessageOnlyException( - "`test` tasks in a Scala.js project require " + - "`fork in Test := false`.") + s"`test in $configName` tasks in a Scala.js project require " + + s"`fork in $configName := false`.") } - val frameworks = testFrameworks.value - val env = jsEnv.value - val files = jsExecutionFiles.value - - val moduleIdentifier = scalaJSLinkerConfig.value.moduleKind match { - case ModuleKind.NoModule => - ModuleIdentifier.NoModule - case ModuleKind.CommonJSModule => - ModuleIdentifier.CommonJSModule(scalaJSLinkedFile.value.data.getPath) + if (!scalaJSUseTestModuleInitializer.value) { + throw new MessageOnlyException( + s"You may only use `test in $configName` tasks in " + + "a Scala.js project if `scalaJSUseTestModuleInitializer in " + + s"$configName := true`") } + val frameworks = testFrameworks.value + val env = jsEnv.value + val input = Input.ScriptsToLoad(jsExecutionFiles.value.toList) val frameworkNames = frameworks.map(_.implClassNames.toList).toList val logger = sbtLogger2ToolsLogger(streams.value.log) val config = TestAdapter.Config() .withLogger(logger) - .withModuleIdentifier(moduleIdentifier) - val adapter = newTestAdapter(env, files, config) + val adapter = newTestAdapter(env, input, config) val frameworkAdapters = adapter.loadFrameworks(frameworkNames) frameworks.zip(frameworkAdapters).collect { @@ -374,10 +404,8 @@ private[sbtplugin] object ScalaJSPluginInternal { definedTestNames := { definedTests.map(_.map(_.name).distinct) .storeAs(definedTestNames).triggeredBy(loadedTestFrameworks).value - } - ) + }, - private val scalaJSTestHtmlSettings = Seq( artifactPath in testHtml := { val stageSuffix = scalaJSStage.value match { case Stage.FastOpt => "fastopt" @@ -412,17 +440,6 @@ private[sbtplugin] object ScalaJSPluginInternal { } ) - val scalaJSTestSettings: Seq[Setting[_]] = ( - scalaJSConfigSettings ++ - scalaJSTestFrameworkSettings ++ - scalaJSTestHtmlSettings - ) ++ Seq( - /* Always default to false for scalaJSUseMainModuleInitializer in testing - * configurations, even if it is true in the Global configuration scope. - */ - scalaJSUseMainModuleInitializer := false - ) - private val scalaJSProjectBaseSettings = Seq( platformDepsCrossVersion := ScalaJSCrossVersion.binary, diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala index f27a268901..5f30b163ae 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala @@ -19,7 +19,7 @@ import org.scalajs.io.JSUtils.escapeJS import org.scalajs.jsenv.VirtualFileMaterializer -import org.scalajs.testcommon.Serializer +import org.scalajs.testcommon._ /** Template for the HTML runner. */ object HTMLRunnerBuilder { @@ -46,8 +46,9 @@ object HTMLRunnerBuilder { } val cssFileURI = jsFileCache.materialize(cssFile).toURI - val htmlContent = render(output.toURI, title, jsFileURIs, cssFileURI, - frameworkImplClassNames, taskDefs) + val tests = new IsolatedTestSet(frameworkImplClassNames, taskDefs) + + val htmlContent = render(output.toURI, title, jsFileURIs, cssFileURI, tests) val outputWriter = WritableFileVirtualTextFile(output).contentWriter try { @@ -58,8 +59,7 @@ object HTMLRunnerBuilder { } private def render(baseURI: URI, title: String, jsFiles: Seq[URI], - css: URI, frameworkImplClassNames: List[List[String]], - taskDefs: List[TaskDef]): String = { + css: URI, tests: IsolatedTestSet): String = { def relURI(uri: URI) = htmlEscaped(URIUtils.relativize(baseURI, uri).toASCIIString) @@ -70,29 +70,21 @@ object HTMLRunnerBuilder { ${htmlEscaped(title)} + ${(for (jsFile <- jsFiles) yield s""" """).mkString("")} - - + """ } - /** Courtesy to our own build. - * This is a hack. The build should take care of its own mess, but oh well. - */ - private[scalajs] def renderTestDefinitions( - frameworkImplClassNames: List[List[String]], - taskDefs: List[TaskDef]): String = { - - def mkVar[T: Serializer](name: String, value: T) = - s"""var $name = "${escapeJS(Serializer.serialize(value))}";\n""" - - mkVar("definedTests", taskDefs) + - mkVar("testFrameworkNames", frameworkImplClassNames) + private def injectInterfaceMode(tests: IsolatedTestSet): String = { + val mode = TestInterfaceMode.HTMLRunner(tests) + val ser = Serializer.serialize[TestInterfaceMode](mode) + s"""var __ScalaJSTestInterfaceMode = "${escapeJS(ser)}";""" } private def htmlEscaped(str: String): String = str.flatMap { diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapter.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapter.scala index d823d227b2..505964e726 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapter.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapter.scala @@ -23,8 +23,7 @@ import org.scalajs.testcommon._ import sbt.testing.Framework -final class TestAdapter(jsEnv: JSEnv, jsFiles: Seq[VirtualJSFile], - config: TestAdapter.Config) { +final class TestAdapter(jsEnv: JSEnv, input: Input, config: TestAdapter.Config) { import TestAdapter._ @@ -120,21 +119,7 @@ final class TestAdapter(jsEnv: JSEnv, jsFiles: Seq[VirtualJSFile], // Otherwise we might leak runners. require(!closed, "We are closed. Cannot create new runner.") - val orgExpr = config.moduleIdentifier match { - case ModuleIdentifier.NoModule => - "typeof(org) != 'undefined' ? org : {}" - - case ModuleIdentifier.CommonJSModule(moduleName) => - s"""require("${escapeJS(moduleName)}").org || {}""" - } - - val launcher = new MemVirtualJSFile("startTestBridge.js") - .withContent(s"($orgExpr).scalajs.testinterface.internal.startBridge();") - - val input = Input.ScriptsToLoad((jsFiles :+ launcher).toList) - val runConfig = RunConfig() - .withLogger(config.logger) - + val runConfig = RunConfig().withLogger(config.logger) val com = new JSEnvRPC(jsEnv, input, runConfig) val mux = new RunMuxRPC(com) @@ -143,53 +128,22 @@ final class TestAdapter(jsEnv: JSEnv, jsFiles: Seq[VirtualJSFile], } object TestAdapter { - /** An identifier for the Scala.js module, which specifies where its exports - * can be loaded from. - * - * @note - * Although this class looks like an ADT and is not extensible from the - * outside, it is not `sealed`. Future versions may have more subclasses, - * which means that `match`es covering all existing cases may fail with - * `MatchError` in the future. - */ - abstract class ModuleIdentifier private () - - object ModuleIdentifier { - /** The Scala.js code is not a module; its exports are in the global scope. - */ - case object NoModule extends ModuleIdentifier - - /** The Scala.js module is a CommonJS module. - * - * @param moduleName - * The module name such that `require(moduleName)` returns the exports - * of the Scala.js module. - */ - final case class CommonJSModule(moduleName: String) extends ModuleIdentifier - } - final class Config private ( - val logger: Logger, - val moduleIdentifier: ModuleIdentifier + val logger: Logger ) { private def this() = { this( - logger = NullLogger, - moduleIdentifier = ModuleIdentifier.NoModule + logger = NullLogger ) } def withLogger(logger: Logger): Config = copy(logger = logger) - def withModuleIdentifier(moduleIdentifier: ModuleIdentifier): Config = - copy(moduleIdentifier = moduleIdentifier) - private def copy( - logger: Logger = logger, - moduleIdentifier: ModuleIdentifier = moduleIdentifier + logger: Logger = logger ): Config = { - new Config(logger, moduleIdentifier) + new Config(logger) } } diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapterInitializer.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapterInitializer.scala new file mode 100644 index 0000000000..e287c25cf9 --- /dev/null +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/TestAdapterInitializer.scala @@ -0,0 +1,15 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js test adapter ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2017, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package org.scalajs.testadapter + +object TestAdapterInitializer { + val ModuleClassName: String = "org.scalajs.testinterface.Bridge" + val MainMethodName: String = "start" +} diff --git a/test-common/src/main/scala/org/scalajs/testcommon/IsolatedTestSet.scala b/test-common/src/main/scala/org/scalajs/testcommon/IsolatedTestSet.scala new file mode 100644 index 0000000000..3fdb0a30f1 --- /dev/null +++ b/test-common/src/main/scala/org/scalajs/testcommon/IsolatedTestSet.scala @@ -0,0 +1,28 @@ +package org.scalajs.testcommon + +import sbt.testing.TaskDef + +/** A set of tests for execution. + * + * This is used by secondary invocation mechanisms (e.g. HTML runner) that do + * not perform test execution "interactively". Instead a full set of frameworks + * and tests is detected upfront (typically by the sbt plugin) and then shipped + * for execution. + */ +private[scalajs] final class IsolatedTestSet( + val testFrameworkNames: List[List[String]], + val definedTests: List[TaskDef] +) + +private[scalajs] object IsolatedTestSet { + implicit object IsolatedTestSetSerializer extends Serializer[IsolatedTestSet] { + def serialize(x: IsolatedTestSet, out: Serializer.SerializeState): Unit = { + out.write(x.testFrameworkNames) + out.write(x.definedTests) + } + + def deserialize(in: Serializer.DeserializeState): IsolatedTestSet = { + new IsolatedTestSet(in.read[List[List[String]]](), in.read[List[TaskDef]]()) + } + } +} diff --git a/test-common/src/main/scala/org/scalajs/testcommon/TestInterfaceMode.scala b/test-common/src/main/scala/org/scalajs/testcommon/TestInterfaceMode.scala new file mode 100644 index 0000000000..416971bba6 --- /dev/null +++ b/test-common/src/main/scala/org/scalajs/testcommon/TestInterfaceMode.scala @@ -0,0 +1,28 @@ +package org.scalajs.testcommon + +/** Mode in which the test interface executes. */ +private[scalajs] sealed abstract class TestInterfaceMode + +private[scalajs] object TestInterfaceMode { + case object FullBridge extends TestInterfaceMode + case class HTMLRunner(tests: IsolatedTestSet) extends TestInterfaceMode + + implicit object TestInterfaceModeSerializer extends Serializer[TestInterfaceMode] { + def serialize(x: TestInterfaceMode, out: Serializer.SerializeState): Unit = x match { + case FullBridge => + out.write(0) + + case HTMLRunner(tests) => + out.write(1) + out.write(tests) + } + + def deserialize(in: Serializer.DeserializeState): TestInterfaceMode = { + in.read[Int]() match { + case 0 => FullBridge + case 1 => HTMLRunner(in.read[IsolatedTestSet]()) + case n => throw new java.io.IOException(s"Unknown interface mode: $n") + } + } + } +} diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/Bridge.scala b/test-interface/src/main/scala/org/scalajs/testinterface/Bridge.scala new file mode 100644 index 0000000000..eb10489f0a --- /dev/null +++ b/test-interface/src/main/scala/org/scalajs/testinterface/Bridge.scala @@ -0,0 +1,24 @@ +package org.scalajs.testinterface + +import scala.scalajs.js +import scala.scalajs.js.annotation.{JSGlobalScope, JSName} + +import org.scalajs.testcommon._ + +private[testinterface] object Bridge { + // Called via org.scalajs.testadapter.testAdapterInitializer + def start(): Unit = mode match { + case TestInterfaceMode.FullBridge => TestAdapterBridge.start() + case TestInterfaceMode.HTMLRunner(tests) => HTMLRunner.start(tests) + } + + private def mode = { + if (js.typeOf(js.Dynamic.global.__ScalaJSTestInterfaceMode) == "undefined") { + TestInterfaceMode.FullBridge + } else { + val modeStr = + js.Dynamic.global.__ScalaJSTestInterfaceMode.asInstanceOf[String] + Serializer.deserialize[TestInterfaceMode](modeStr) + } + } +} diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/FrameworkLoader.scala b/test-interface/src/main/scala/org/scalajs/testinterface/FrameworkLoader.scala index a8c86c8d17..1886039ea1 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/FrameworkLoader.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/FrameworkLoader.scala @@ -24,4 +24,15 @@ private[testinterface] object FrameworkLoader { for (frameworkNames <- names) yield frameworkNames.find(frameworkExists(_)) } + + def tryLoadFramework(names: List[String]): Option[Framework] = { + def tryLoad(name: String): Option[Framework] = { + Reflect.lookupInstantiatableClass(name).collect { + case clazz if classOf[Framework].isAssignableFrom(clazz.runtimeClass) => + clazz.newInstance().asInstanceOf[Framework] + } + } + + names.toStream.map(tryLoad).flatten.headOption + } } diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala b/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala index 054d556406..5de1e62550 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala @@ -19,6 +19,8 @@ import scala.concurrent.ExecutionContext.Implicits.global import scala.util.Try +import org.scalajs.testcommon.IsolatedTestSet + import sbt.testing._ protected[testinterface] object HTMLRunner { @@ -42,8 +44,10 @@ protected[testinterface] object HTMLRunner { } } - @JSExportTopLevel("org.scalajs.testinterface.HTMLRunner.main") - def main(): Unit = { + def start(tests: IsolatedTestSet): Unit = + dom.window.addEventListener("DOMContentLoaded", () => onLoad(tests)) + + private def onLoad(tests: IsolatedTestSet): Unit = { /* Note: Test filtering is currently done based on the fully qualified name * of a test. While this is reasonable in most cases, there could be a test * that is run by multiple test frameworks. @@ -66,7 +70,7 @@ protected[testinterface] object HTMLRunner { } } - val allTests = TestDetector.detectTests() + val allTests = TestLoader.loadTests(tests) val totalTestCount = allTests.map(_._2.size).sum val excludedTests = allTests.flatMap(_._2.filterNot(testFilter)) @@ -433,6 +437,12 @@ protected[testinterface] object HTMLRunner { // Mini dom facade. private object dom { + @JSGlobal("window") + @js.native + object window extends js.Object { + def addEventListener(tpe: String, handler: js.Function0[Unit]): Unit = js.native + } + @JSGlobal("document") @js.native object document extends js.Object { diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/TestAdapterBridge.scala b/test-interface/src/main/scala/org/scalajs/testinterface/TestAdapterBridge.scala index 9a667c2ff4..94a81dc0e8 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/TestAdapterBridge.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/TestAdapterBridge.scala @@ -1,7 +1,5 @@ package org.scalajs.testinterface -import scala.scalajs.js.annotation._ - import scala.concurrent.{Future, Promise} import scala.util.control.NonFatal @@ -15,7 +13,6 @@ private[testinterface] object TestAdapterBridge { private[this] val mux = new RunMuxRPC(JSRPC) - @JSExportTopLevel("org.scalajs.testinterface.internal.startBridge") def start(): Unit = { import JSEndpoints._ diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala b/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala deleted file mode 100644 index db4f12c17f..0000000000 --- a/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala +++ /dev/null @@ -1,63 +0,0 @@ -package org.scalajs.testinterface - -import java.io._ - -import scala.scalajs.js -import scala.scalajs.js.annotation.JSGlobalScope -import scala.scalajs.reflect.Reflect - -import org.scalajs.testcommon.Serializer - -import sbt.testing._ - -/** Fetches test definitions and frameworks. */ -private[scalajs] object TestDetector { - def detectTests(): Seq[(Framework, Seq[TaskDef])] = { - val taskDefs = Serializer.deserialize[List[TaskDef]]( - RawDefinitions.definedTests) - - val frameworkNames = Serializer.deserialize[List[List[String]]]( - RawDefinitions.testFrameworkNames) - - for { - nameAlternatives <- frameworkNames - framework <- tryLoadFramework(nameAlternatives).toList - } yield { - val fingerprints = framework.fingerprints() - val eligibleTaskDefs = taskDefs.filter(taskDef => - fingerprints.exists(fingerprintMatches(_, taskDef.fingerprint))) - (framework, eligibleTaskDefs.toSeq) - } - } - - private def tryLoadFramework(names: List[String]): Option[Framework] = { - def tryLoad(name: String): Option[Framework] = { - Reflect.lookupInstantiatableClass(name).collect { - case clazz if classOf[Framework].isAssignableFrom(clazz.runtimeClass) => - clazz.newInstance().asInstanceOf[Framework] - } - } - - names.toStream.map(tryLoad).flatten.headOption - } - - // Copied from sbt.TestFramework - private def fingerprintMatches(a: Fingerprint, b: Fingerprint): Boolean = { - (a, b) match { - case (a: SubclassFingerprint, b: SubclassFingerprint) => - a.isModule == b.isModule && a.superclassName == b.superclassName - - case (a: AnnotatedFingerprint, b: AnnotatedFingerprint) => - a.isModule == b.isModule && a.annotationName == b.annotationName - - case _ => false - } - } - - @js.native - @JSGlobalScope - private object RawDefinitions extends js.Object { - val definedTests: String = js.native - val testFrameworkNames: String = js.native - } -} diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/TestLoader.scala b/test-interface/src/main/scala/org/scalajs/testinterface/TestLoader.scala new file mode 100644 index 0000000000..9774d4b808 --- /dev/null +++ b/test-interface/src/main/scala/org/scalajs/testinterface/TestLoader.scala @@ -0,0 +1,38 @@ +package org.scalajs.testinterface + +import java.io._ + +import scala.scalajs.js +import scala.scalajs.js.annotation.JSGlobalScope +import scala.scalajs.reflect.Reflect + +import org.scalajs.testcommon.IsolatedTestSet + +import sbt.testing._ + +private[scalajs] object TestLoader { + def loadTests(tests: IsolatedTestSet): Seq[(Framework, Seq[TaskDef])] = { + for { + nameAlternatives <- tests.testFrameworkNames + framework <- FrameworkLoader.tryLoadFramework(nameAlternatives).toList + } yield { + val fingerprints = framework.fingerprints() + val eligibleTaskDefs = tests.definedTests.filter(taskDef => + fingerprints.exists(fingerprintMatches(_, taskDef.fingerprint))) + (framework, eligibleTaskDefs.toSeq) + } + } + + // Copied from sbt.TestFramework + private def fingerprintMatches(a: Fingerprint, b: Fingerprint): Boolean = { + (a, b) match { + case (a: SubclassFingerprint, b: SubclassFingerprint) => + a.isModule == b.isModule && a.superclassName == b.superclassName + + case (a: AnnotatedFingerprint, b: AnnotatedFingerprint) => + a.isModule == b.isModule && a.annotationName == b.annotationName + + case _ => false + } + } +} diff --git a/test-suite-linker/src/main/scala/org/scalajs/bootstrap/TestSuiteLinker.scala b/test-suite-linker/src/main/scala/org/scalajs/bootstrap/TestSuiteLinker.scala index a2ef990ed1..382c5cc21d 100644 --- a/test-suite-linker/src/main/scala/org/scalajs/bootstrap/TestSuiteLinker.scala +++ b/test-suite-linker/src/main/scala/org/scalajs/bootstrap/TestSuiteLinker.scala @@ -22,7 +22,11 @@ object QuickLinker { val linker = StandardLinker(config) - val moduleInitializers = build.TestSuiteLinkerOptions.moduleInitializers + val moduleInitializers = { + build.TestSuiteLinkerOptions.moduleInitializers :+ + // Copied from org.scalajs.testadapter.TestAdapaterInitializer. + ModuleInitializer.mainMethod("org.scalajs.testinterface.Bridge", "start") + } val ir = extractIR(irFilesAndJars) From 59eb62cf85701385a1a73af7a5ee198091a13703 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Mon, 23 Apr 2018 12:02:36 +0200 Subject: [PATCH 0714/2665] Fix reported ambiguous method names and make error pos deterministic. - Fix the type test used to determine whether we should use the jsName or the name of a symbol. - Sort positions of alternative ambiguous overloads and pick the last one to not rely on the arbitrary order of the hashmap implementation used by the underlying compiler. --- .../org/scalajs/core/compiler/GenJSExports.scala | 15 ++++++++++----- .../scalajs/core/compiler/test/JSExportTest.scala | 2 +- .../core/compiler/test/ScalaJSDefinedTest.scala | 2 +- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index 291f6f0d89..2ecf289d78 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -621,13 +621,18 @@ trait GenJSExports extends SubComponent { self: GenJSCode => private def reportCannotDisambiguateError(alts: List[Exported]): Unit = { val currentClass = currentClassSym.get - // Find a position that is in the current class for decent error reporting - val pos = alts.collectFirst { + /* Find a position that is in the current class for decent error reporting. + * If there are more than one, always use the "highest" one (i.e., the + * one coming last in the source text) so that we reliably display the + * same error in all compilers. + */ + val validPositions = alts.collect { case ExportedSymbol(sym) if sym.owner == currentClass => sym.pos case alt: ExportedBody => alt.pos - }.getOrElse { - currentClass.pos } + val pos = + if (validPositions.isEmpty) currentClass.pos + else validPositions.maxBy(_.point) val kind = if (isScalaJSDefinedJSClass(currentClass)) "method" @@ -897,7 +902,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => genApplyForSym(minArgc, hasRestParam, sym, static) def name: String = - if (isScalaJSDefinedJSClass(sym.owner)) jsNameOf(sym).displayName + if (isRawJSType(sym.owner.toTypeConstructor)) jsNameOf(sym).displayName else sym.name.toString def typeInfo: String = sym.tpe.toString diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index 320231a47f..69f27c03a0 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -173,7 +173,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:4: error: Cannot disambiguate overloads for exported method $js$exported$meth$foo with types + |newSource1.scala:6: error: Cannot disambiguate overloads for exported method $js$exported$meth$foo with types | (x: Int)Object | (x: Seq)Object | @JSExport diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala index a16ee23f52..c86443fb90 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala @@ -221,7 +221,7 @@ class ScalaJSDefinedTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:14: error: Cannot disambiguate overloads for method bar with types + |newSource1.scala:14: error: Cannot disambiguate overloads for method foo with types | (x: Int)Int | (x: Int)Int | class Bar extends Foo { From ee66590c28c34ad6858f12caa6cc3e91d879d1f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 25 Apr 2018 19:46:29 +0200 Subject: [PATCH 0715/2665] Do not delete `global.ArrayBuffer` in `NodeJSEnvForcePolyfills`. Because Node.js v10.0.0's `readFileSync`, used by the core module loading mechanism, relies on it being there and working. --- project/NodeJSEnvForcePolyfills.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/project/NodeJSEnvForcePolyfills.scala b/project/NodeJSEnvForcePolyfills.scala index b5088766c3..7edf651cfb 100644 --- a/project/NodeJSEnvForcePolyfills.scala +++ b/project/NodeJSEnvForcePolyfills.scala @@ -45,7 +45,6 @@ final class NodeJSEnvForcePolyfills(config: NodeJSEnv.Config) extends JSEnv { | |delete global.Promise; | - |delete global.ArrayBuffer; |delete global.Int8Array; |delete global.Int16Array; |delete global.Int32Array; From a15382f3991d4ba546a84eeedb67551caccdc463 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 25 Apr 2018 22:21:29 +0200 Subject: [PATCH 0716/2665] Fix #3350: Fix BigInts for Longs without optimizer. There was one issue in the actual linker, and one in the tests. Fixing the issue in the test caused the with-optimizer tests to fail because the optimizer was doing the wrong thing. --- .../scalajs/linker/backend/emitter/FunctionEmitter.scala | 2 +- .../scalajs/linker/frontend/optimizer/OptimizerCore.scala | 4 +++- .../org/scalajs/testsuite/compiler/OptimizerTest.scala | 7 ++++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala index ada13c88d4..8d8387a748 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala @@ -2073,7 +2073,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { case AnyType => genDispatchApply() - case LongType | ClassType(BoxedLongClass) => + case LongType | ClassType(BoxedLongClass) if !useBigIntForLongs => // All methods of java.lang.Long are also in RuntimeLong genNormalApply() diff --git a/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala b/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala index e69d9bf0c1..87248f55c0 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/frontend/optimizer/OptimizerCore.scala @@ -2818,7 +2818,8 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { * `===` comparison, since they all upcast as primitive numbers. * * Chars and Longs, however, never compare as `===`, since they are boxed - * chars and instances of `RuntimeLong`, respectively. + * chars and instances of `RuntimeLong`, respectively---unless we are using + * `BigInt`s for `Long`s, in which case those can be `===`. */ private def literal_===(lhs: Literal, rhs: Literal): Boolean = { object AnyNumLiteral { @@ -2837,6 +2838,7 @@ private[optimizer] abstract class OptimizerCore(config: CommonPhaseConfig) { case (StringLiteral(l), StringLiteral(r)) => l == r case (ClassOf(l), ClassOf(r)) => l == r case (AnyNumLiteral(l), AnyNumLiteral(r)) => l == r + case (LongLiteral(l), LongLiteral(r)) => l == r && !useRuntimeLong case (Undefined(), Undefined()) => true case (Null(), Null()) => true case _ => false diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala index 0a97286f62..447d2e0954 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala @@ -177,11 +177,16 @@ class OptimizerTest { test(false, 5.toByte, 5L) test(false, 5, 5L) test(false, 5L, 6L) - test(false, 5L, 5L) // they're instances of RuntimeLong, so not === test(false, false, 0) test(false, 65, 'A') test(false, classOf[String], classOf[Boolean]) test(false, "hello", "world") + + /* When using BigInts for Longs, equal Longs will be ===, but not when + * using RuntimeLongs since the instances will be different. + */ + val usingBigIntForLongs = js.typeOf(5L) == "bigint" + test(usingBigIntForLongs, 5L, 5L) } @Test def constant_folding_==(): Unit = { From 83b2e7c641ea2bac6253982d0cb01dec528bc6a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 25 Apr 2018 17:12:32 +0200 Subject: [PATCH 0717/2665] Run tests with `withAllowBigIntsForLongs(true)`. Now that Node.js v10.0.0 has been released, with a version of v8 that supports BigInts under the flag `--harmony-bigint`, we can actually test that feature on the CI. --- Jenkinsfile | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index 228193b05e..12acb1dc2a 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -152,6 +152,14 @@ def Tasks = [ 'set scalaJSLinkerConfig in $testSuite ~= (_.withOptimizer(false))' \ ++$scala $testSuite/test \ $testSuite/clean && + sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withAllowBigIntsForLongs(true)))' \ + 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withArgs(List("--harmony-bigint")))' \ + ++$scala $testSuite/test \ + $testSuite/clean && + sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withAllowBigIntsForLongs(true)).withOptimizer(false))' \ + 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withArgs(List("--harmony-bigint")))' \ + ++$scala $testSuite/test \ + $testSuite/clean && sbtretry 'set scalacOptions in $testSuite += "-Xexperimental"' \ ++$scala $testSuite/test && sbtretry 'set scalacOptions in $testSuite += "-Xexperimental"' \ @@ -220,6 +228,14 @@ def Tasks = [ 'set scalaJSLinkerConfig in $testSuite ~= (_.withOptimizer(false))' \ ++$scala $testSuite/test \ $testSuite/clean && + sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true).withAllowBigIntsForLongs(true)))' \ + 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withArgs(List("--harmony-bigint")))' \ + ++$scala $testSuite/test \ + $testSuite/clean && + sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true).withAllowBigIntsForLongs(true)).withOptimizer(false))' \ + 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withArgs(List("--harmony-bigint")))' \ + ++$scala $testSuite/test \ + $testSuite/clean && sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true)))' \ 'set scalaJSLinkerConfig in $testSuite ~= (_.withModuleKind(ModuleKind.CommonJSModule))' \ ++$scala $testSuite/test && From 987e743f8d8b4e7bd8d4c68fa3fa35668f562cf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 7 Feb 2018 13:34:32 +0100 Subject: [PATCH 0718/2665] Remove tests asserting that we cannot create a regex with named groups. Named groups are supported in ECMAScript 2018, which means that creating such regexes will not fail on modern JS VMs. (cherry picked from commit 2f81493cb78a56e2880188986fab1bae2c935c13) --- .../testsuite/javalib/util/regex/RegexMatcherTest.scala | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexMatcherTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexMatcherTest.scala index 37cbc4cb34..6a0bcbb221 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexMatcherTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexMatcherTest.scala @@ -404,10 +404,5 @@ class RegexMatcherTest { if (!executingInJVM) assertThrows(classOf[Exception], ms group "Ape") assertFalse(ms.hasNext) - - if (!executingInJVM) { - assertThrows(classOf[Exception], new Regex("a(?b*)c")) - assertThrows(classOf[Exception], Pattern.compile("a(?b*)c")) - } } } From 5c3e516f64fc5379b36957972eea8e6d7113062a Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Thu, 26 Apr 2018 15:38:51 -0700 Subject: [PATCH 0719/2665] Reduce acceptTimeout I noticed that my tests were very slow to start running. While running with sbt | ts '%H:%M:%.S', I found that there was almost always exactly a 5 second delay between starting the process and the first output being printed. I grepped for 5000 and found this line. Changing this parameter eliminated the delay for me. The parameter seems to only be used in the awaitConnection method, which just loops until serverSocket.accept succeeds (with failure being a socket timeout). This makes me fairly confident that this change won't break anything. I also would expect any additional overhead of the extra thread wake ups to be negligible. --- .../main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala index 9052e1c716..ae6b0fdbf1 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala @@ -51,7 +51,7 @@ abstract class AbstractNodeJSEnv( } /** Retry-timeout to wait for the JS VM to connect */ - protected val acceptTimeout = 5000 + protected val acceptTimeout = 500 protected trait AbstractNodeRunner extends AbstractExtRunner with JSInitFiles { From f5c9461e1228ba22ae65ba3bb7b5000d896cc597 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Thu, 3 May 2018 18:40:39 +0200 Subject: [PATCH 0720/2665] Remove unused helper. --- .../main/scala/org/scalajs/testcommon/FutureUtil.scala | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/test-common/src/main/scala/org/scalajs/testcommon/FutureUtil.scala b/test-common/src/main/scala/org/scalajs/testcommon/FutureUtil.scala index 377cf6620c..c95798cd19 100644 --- a/test-common/src/main/scala/org/scalajs/testcommon/FutureUtil.scala +++ b/test-common/src/main/scala/org/scalajs/testcommon/FutureUtil.scala @@ -2,7 +2,6 @@ package org.scalajs.testcommon import scala.util._ import scala.concurrent._ -import scala.concurrent.ExecutionContext.Implicits.global private[scalajs] object FutureUtil { /** Same as Future.fromTry(x) but works in 2.10 */ @@ -11,13 +10,4 @@ private[scalajs] object FutureUtil { promise.complete(x) promise.future } - - implicit class RichFuture[T](val __self: Future[T]) extends AnyVal { - def liftToTry: Future[Try[T]] = - __self.map(Success(_)).recover(pf(Failure(_))) - } - - private def pf[A, B](f: A => B): PartialFunction[A, B] = { - case x => f(x) - } } From 36ea85c34e647a18894154df852ac774976daada Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 10 May 2018 14:11:34 +0200 Subject: [PATCH 0721/2665] Remove the override for RedBlackTree.scala in 2.13. It hasn't been necessary since 2.13.0-M1, because our fix was merged upstream in that version. --- .../collection/immutable/RedBlackTree.scala | 0 .../collection/immutable/RedBlackTree.scala | 562 ++++++++++++++++++ 2 files changed, 562 insertions(+) rename scalalib/{overrides => overrides-2.11}/scala/collection/immutable/RedBlackTree.scala (100%) create mode 100644 scalalib/overrides-2.12/scala/collection/immutable/RedBlackTree.scala diff --git a/scalalib/overrides/scala/collection/immutable/RedBlackTree.scala b/scalalib/overrides-2.11/scala/collection/immutable/RedBlackTree.scala similarity index 100% rename from scalalib/overrides/scala/collection/immutable/RedBlackTree.scala rename to scalalib/overrides-2.11/scala/collection/immutable/RedBlackTree.scala diff --git a/scalalib/overrides-2.12/scala/collection/immutable/RedBlackTree.scala b/scalalib/overrides-2.12/scala/collection/immutable/RedBlackTree.scala new file mode 100644 index 0000000000..0e678d703e --- /dev/null +++ b/scalalib/overrides-2.12/scala/collection/immutable/RedBlackTree.scala @@ -0,0 +1,562 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + + + +package scala +package collection +package immutable + +import scala.annotation.tailrec +import scala.annotation.meta.getter + +/** An object containing the RedBlack tree implementation used by for `TreeMaps` and `TreeSets`. + * + * Implementation note: since efficiency is important for data structures this implementation + * uses `null` to represent empty trees. This also means pattern matching cannot + * easily be used. The API represented by the RedBlackTree object tries to hide these + * optimizations behind a reasonably clean API. + * + * @since 2.10 + */ +private[collection] +object RedBlackTree { + + def isEmpty(tree: Tree[_, _]): Boolean = tree eq null + + def contains[A: Ordering](tree: Tree[A, _], x: A): Boolean = lookup(tree, x) ne null + def get[A: Ordering, B](tree: Tree[A, B], x: A): Option[B] = lookup(tree, x) match { + case null => None + case tree => Some(tree.value) + } + + @tailrec + def lookup[A, B](tree: Tree[A, B], x: A)(implicit ordering: Ordering[A]): Tree[A, B] = if (tree eq null) null else { + val cmp = ordering.compare(x, tree.key) + if (cmp < 0) lookup(tree.left, x) + else if (cmp > 0) lookup(tree.right, x) + else tree + } + + def count(tree: Tree[_, _]) = if (tree eq null) 0 else tree.count + /** + * Count all the nodes with keys greater than or equal to the lower bound and less than the upper bound. + * The two bounds are optional. + */ + def countInRange[A](tree: Tree[A, _], from: Option[A], to:Option[A])(implicit ordering: Ordering[A]) : Int = + if (tree eq null) 0 else + (from, to) match { + // with no bounds use this node's count + case (None, None) => tree.count + // if node is less than the lower bound, try the tree on the right, it might be in range + case (Some(lb), _) if ordering.lt(tree.key, lb) => countInRange(tree.right, from, to) + // if node is greater than or equal to the upper bound, try the tree on the left, it might be in range + case (_, Some(ub)) if ordering.gteq(tree.key, ub) => countInRange(tree.left, from, to) + // node is in range so the tree on the left will all be less than the upper bound and the tree on the + // right will all be greater than or equal to the lower bound. So 1 for this node plus + // count the subtrees by stripping off the bounds that we don't need any more + case _ => 1 + countInRange(tree.left, from, None) + countInRange(tree.right, None, to) + + } + def update[A: Ordering, B, B1 >: B](tree: Tree[A, B], k: A, v: B1, overwrite: Boolean): Tree[A, B1] = blacken(upd(tree, k, v, overwrite)) + def delete[A: Ordering, B](tree: Tree[A, B], k: A): Tree[A, B] = blacken(del(tree, k)) + def rangeImpl[A: Ordering, B](tree: Tree[A, B], from: Option[A], until: Option[A]): Tree[A, B] = (from, until) match { + case (Some(from), Some(until)) => this.range(tree, from, until) + case (Some(from), None) => this.from(tree, from) + case (None, Some(until)) => this.until(tree, until) + case (None, None) => tree + } + def range[A: Ordering, B](tree: Tree[A, B], from: A, until: A): Tree[A, B] = blacken(doRange(tree, from, until)) + def from[A: Ordering, B](tree: Tree[A, B], from: A): Tree[A, B] = blacken(doFrom(tree, from)) + def to[A: Ordering, B](tree: Tree[A, B], to: A): Tree[A, B] = blacken(doTo(tree, to)) + def until[A: Ordering, B](tree: Tree[A, B], key: A): Tree[A, B] = blacken(doUntil(tree, key)) + + def drop[A: Ordering, B](tree: Tree[A, B], n: Int): Tree[A, B] = blacken(doDrop(tree, n)) + def take[A: Ordering, B](tree: Tree[A, B], n: Int): Tree[A, B] = blacken(doTake(tree, n)) + def slice[A: Ordering, B](tree: Tree[A, B], from: Int, until: Int): Tree[A, B] = blacken(doSlice(tree, from, until)) + + def smallest[A, B](tree: Tree[A, B]): Tree[A, B] = { + if (tree eq null) throw new NoSuchElementException("empty map") + var result = tree + while (result.left ne null) result = result.left + result + } + def greatest[A, B](tree: Tree[A, B]): Tree[A, B] = { + if (tree eq null) throw new NoSuchElementException("empty map") + var result = tree + while (result.right ne null) result = result.right + result + } + + + def foreach[A,B,U](tree:Tree[A,B], f:((A,B)) => U):Unit = if (tree ne null) _foreach(tree,f) + + private[this] def _foreach[A, B, U](tree: Tree[A, B], f: ((A, B)) => U) { + if (tree.left ne null) _foreach(tree.left, f) + f((tree.key, tree.value)) + if (tree.right ne null) _foreach(tree.right, f) + } + + def foreachKey[A, U](tree:Tree[A,_], f: A => U):Unit = if (tree ne null) _foreachKey(tree,f) + + private[this] def _foreachKey[A, U](tree: Tree[A, _], f: A => U) { + if (tree.left ne null) _foreachKey(tree.left, f) + f((tree.key)) + if (tree.right ne null) _foreachKey(tree.right, f) + } + + def iterator[A: Ordering, B](tree: Tree[A, B], start: Option[A] = None): Iterator[(A, B)] = new EntriesIterator(tree, start) + def keysIterator[A: Ordering](tree: Tree[A, _], start: Option[A] = None): Iterator[A] = new KeysIterator(tree, start) + def valuesIterator[A: Ordering, B](tree: Tree[A, B], start: Option[A] = None): Iterator[B] = new ValuesIterator(tree, start) + + @tailrec + def nth[A, B](tree: Tree[A, B], n: Int): Tree[A, B] = { + val count = this.count(tree.left) + if (n < count) nth(tree.left, n) + else if (n > count) nth(tree.right, n - count - 1) + else tree + } + + def isBlack(tree: Tree[_, _]) = (tree eq null) || isBlackTree(tree) + + private[this] def isRedTree(tree: Tree[_, _]) = tree.isInstanceOf[RedTree[_, _]] + private[this] def isBlackTree(tree: Tree[_, _]) = tree.isInstanceOf[BlackTree[_, _]] + + private[this] def blacken[A, B](t: Tree[A, B]): Tree[A, B] = if (t eq null) null else t.black + + private[this] def mkTree[A, B](isBlack: Boolean, k: A, v: B, l: Tree[A, B], r: Tree[A, B]) = + if (isBlack) BlackTree(k, v, l, r) else RedTree(k, v, l, r) + + private[this] def balanceLeft[A, B, B1 >: B](isBlack: Boolean, z: A, zv: B, l: Tree[A, B1], d: Tree[A, B1]): Tree[A, B1] = { + if (isRedTree(l) && isRedTree(l.left)) + RedTree(l.key, l.value, BlackTree(l.left.key, l.left.value, l.left.left, l.left.right), BlackTree(z, zv, l.right, d)) + else if (isRedTree(l) && isRedTree(l.right)) + RedTree(l.right.key, l.right.value, BlackTree(l.key, l.value, l.left, l.right.left), BlackTree(z, zv, l.right.right, d)) + else + mkTree(isBlack, z, zv, l, d) + } + private[this] def balanceRight[A, B, B1 >: B](isBlack: Boolean, x: A, xv: B, a: Tree[A, B1], r: Tree[A, B1]): Tree[A, B1] = { + if (isRedTree(r) && isRedTree(r.left)) + RedTree(r.left.key, r.left.value, BlackTree(x, xv, a, r.left.left), BlackTree(r.key, r.value, r.left.right, r.right)) + else if (isRedTree(r) && isRedTree(r.right)) + RedTree(r.key, r.value, BlackTree(x, xv, a, r.left), BlackTree(r.right.key, r.right.value, r.right.left, r.right.right)) + else + mkTree(isBlack, x, xv, a, r) + } + private[this] def upd[A, B, B1 >: B](tree: Tree[A, B], k: A, v: B1, overwrite: Boolean)(implicit ordering: Ordering[A]): Tree[A, B1] = if (tree eq null) { + RedTree(k, v, null, null) + } else { + val cmp = ordering.compare(k, tree.key) + if (cmp < 0) balanceLeft(isBlackTree(tree), tree.key, tree.value, upd(tree.left, k, v, overwrite), tree.right) + else if (cmp > 0) balanceRight(isBlackTree(tree), tree.key, tree.value, tree.left, upd(tree.right, k, v, overwrite)) + else if (overwrite || k != tree.key) mkTree(isBlackTree(tree), k, v, tree.left, tree.right) + else tree + } + private[this] def updNth[A, B, B1 >: B](tree: Tree[A, B], idx: Int, k: A, v: B1, overwrite: Boolean): Tree[A, B1] = if (tree eq null) { + RedTree(k, v, null, null) + } else { + val rank = count(tree.left) + 1 + if (idx < rank) balanceLeft(isBlackTree(tree), tree.key, tree.value, updNth(tree.left, idx, k, v, overwrite), tree.right) + else if (idx > rank) balanceRight(isBlackTree(tree), tree.key, tree.value, tree.left, updNth(tree.right, idx - rank, k, v, overwrite)) + else if (overwrite) mkTree(isBlackTree(tree), k, v, tree.left, tree.right) + else tree + } + + /* Based on Stefan Kahrs' Haskell version of Okasaki's Red&Black Trees + * Constructing Red-Black Trees, Ralf Hinze: http://www.cs.ox.ac.uk/ralf.hinze/publications/WAAAPL99b.ps.gz + * Red-Black Trees in a Functional Setting, Chris Okasaki: https://wiki.rice.edu/confluence/download/attachments/2761212/Okasaki-Red-Black.pdf */ + private[this] def del[A, B](tree: Tree[A, B], k: A)(implicit ordering: Ordering[A]): Tree[A, B] = if (tree eq null) null else { + def balance(x: A, xv: B, tl: Tree[A, B], tr: Tree[A, B]) = if (isRedTree(tl)) { + if (isRedTree(tr)) { + RedTree(x, xv, tl.black, tr.black) + } else if (isRedTree(tl.left)) { + RedTree(tl.key, tl.value, tl.left.black, BlackTree(x, xv, tl.right, tr)) + } else if (isRedTree(tl.right)) { + RedTree(tl.right.key, tl.right.value, BlackTree(tl.key, tl.value, tl.left, tl.right.left), BlackTree(x, xv, tl.right.right, tr)) + } else { + BlackTree(x, xv, tl, tr) + } + } else if (isRedTree(tr)) { + if (isRedTree(tr.right)) { + RedTree(tr.key, tr.value, BlackTree(x, xv, tl, tr.left), tr.right.black) + } else if (isRedTree(tr.left)) { + RedTree(tr.left.key, tr.left.value, BlackTree(x, xv, tl, tr.left.left), BlackTree(tr.key, tr.value, tr.left.right, tr.right)) + } else { + BlackTree(x, xv, tl, tr) + } + } else { + BlackTree(x, xv, tl, tr) + } + def subl(t: Tree[A, B]) = + if (t.isInstanceOf[BlackTree[_, _]]) t.red + else throw new IllegalStateException("Defect: invariance violation; expected black, got "+t) + + def balLeft(x: A, xv: B, tl: Tree[A, B], tr: Tree[A, B]) = if (isRedTree(tl)) { + RedTree(x, xv, tl.black, tr) + } else if (isBlackTree(tr)) { + balance(x, xv, tl, tr.red) + } else if (isRedTree(tr) && isBlackTree(tr.left)) { + RedTree(tr.left.key, tr.left.value, BlackTree(x, xv, tl, tr.left.left), balance(tr.key, tr.value, tr.left.right, subl(tr.right))) + } else { + throw new IllegalStateException("Defect: invariance violation") + } + def balRight(x: A, xv: B, tl: Tree[A, B], tr: Tree[A, B]) = if (isRedTree(tr)) { + RedTree(x, xv, tl, tr.black) + } else if (isBlackTree(tl)) { + balance(x, xv, tl.red, tr) + } else if (isRedTree(tl) && isBlackTree(tl.right)) { + RedTree(tl.right.key, tl.right.value, balance(tl.key, tl.value, subl(tl.left), tl.right.left), BlackTree(x, xv, tl.right.right, tr)) + } else { + throw new IllegalStateException("Defect: invariance violation") + } + def delLeft = if (isBlackTree(tree.left)) balLeft(tree.key, tree.value, del(tree.left, k), tree.right) else RedTree(tree.key, tree.value, del(tree.left, k), tree.right) + def delRight = if (isBlackTree(tree.right)) balRight(tree.key, tree.value, tree.left, del(tree.right, k)) else RedTree(tree.key, tree.value, tree.left, del(tree.right, k)) + def append(tl: Tree[A, B], tr: Tree[A, B]): Tree[A, B] = if (tl eq null) { + tr + } else if (tr eq null) { + tl + } else if (isRedTree(tl) && isRedTree(tr)) { + val bc = append(tl.right, tr.left) + if (isRedTree(bc)) { + RedTree(bc.key, bc.value, RedTree(tl.key, tl.value, tl.left, bc.left), RedTree(tr.key, tr.value, bc.right, tr.right)) + } else { + RedTree(tl.key, tl.value, tl.left, RedTree(tr.key, tr.value, bc, tr.right)) + } + } else if (isBlackTree(tl) && isBlackTree(tr)) { + val bc = append(tl.right, tr.left) + if (isRedTree(bc)) { + RedTree(bc.key, bc.value, BlackTree(tl.key, tl.value, tl.left, bc.left), BlackTree(tr.key, tr.value, bc.right, tr.right)) + } else { + balLeft(tl.key, tl.value, tl.left, BlackTree(tr.key, tr.value, bc, tr.right)) + } + } else if (isRedTree(tr)) { + RedTree(tr.key, tr.value, append(tl, tr.left), tr.right) + } else if (isRedTree(tl)) { + RedTree(tl.key, tl.value, tl.left, append(tl.right, tr)) + } else { + throw new IllegalStateException("unmatched tree on append: " + tl + ", " + tr) + } + + val cmp = ordering.compare(k, tree.key) + if (cmp < 0) delLeft + else if (cmp > 0) delRight + else append(tree.left, tree.right) + } + + private[this] def doFrom[A, B](tree: Tree[A, B], from: A)(implicit ordering: Ordering[A]): Tree[A, B] = { + if (tree eq null) return null + if (ordering.lt(tree.key, from)) return doFrom(tree.right, from) + val newLeft = doFrom(tree.left, from) + if (newLeft eq tree.left) tree + else if (newLeft eq null) upd(tree.right, tree.key, tree.value, overwrite = false) + else rebalance(tree, newLeft, tree.right) + } + private[this] def doTo[A, B](tree: Tree[A, B], to: A)(implicit ordering: Ordering[A]): Tree[A, B] = { + if (tree eq null) return null + if (ordering.lt(to, tree.key)) return doTo(tree.left, to) + val newRight = doTo(tree.right, to) + if (newRight eq tree.right) tree + else if (newRight eq null) upd(tree.left, tree.key, tree.value, overwrite = false) + else rebalance(tree, tree.left, newRight) + } + private[this] def doUntil[A, B](tree: Tree[A, B], until: A)(implicit ordering: Ordering[A]): Tree[A, B] = { + if (tree eq null) return null + if (ordering.lteq(until, tree.key)) return doUntil(tree.left, until) + val newRight = doUntil(tree.right, until) + if (newRight eq tree.right) tree + else if (newRight eq null) upd(tree.left, tree.key, tree.value, overwrite = false) + else rebalance(tree, tree.left, newRight) + } + private[this] def doRange[A, B](tree: Tree[A, B], from: A, until: A)(implicit ordering: Ordering[A]): Tree[A, B] = { + if (tree eq null) return null + if (ordering.lt(tree.key, from)) return doRange(tree.right, from, until) + if (ordering.lteq(until, tree.key)) return doRange(tree.left, from, until) + val newLeft = doFrom(tree.left, from) + val newRight = doUntil(tree.right, until) + if ((newLeft eq tree.left) && (newRight eq tree.right)) tree + else if (newLeft eq null) upd(newRight, tree.key, tree.value, overwrite = false) + else if (newRight eq null) upd(newLeft, tree.key, tree.value, overwrite = false) + else rebalance(tree, newLeft, newRight) + } + + private[this] def doDrop[A, B](tree: Tree[A, B], n: Int): Tree[A, B] = { + if (n <= 0) return tree + if (n >= this.count(tree)) return null + val count = this.count(tree.left) + if (n > count) return doDrop(tree.right, n - count - 1) + val newLeft = doDrop(tree.left, n) + if (newLeft eq tree.left) tree + else if (newLeft eq null) updNth(tree.right, n - count - 1, tree.key, tree.value, overwrite = false) + else rebalance(tree, newLeft, tree.right) + } + private[this] def doTake[A, B](tree: Tree[A, B], n: Int): Tree[A, B] = { + if (n <= 0) return null + if (n >= this.count(tree)) return tree + val count = this.count(tree.left) + if (n <= count) return doTake(tree.left, n) + val newRight = doTake(tree.right, n - count - 1) + if (newRight eq tree.right) tree + else if (newRight eq null) updNth(tree.left, n, tree.key, tree.value, overwrite = false) + else rebalance(tree, tree.left, newRight) + } + private[this] def doSlice[A, B](tree: Tree[A, B], from: Int, until: Int): Tree[A, B] = { + if (tree eq null) return null + val count = this.count(tree.left) + if (from > count) return doSlice(tree.right, from - count - 1, until - count - 1) + if (until <= count) return doSlice(tree.left, from, until) + val newLeft = doDrop(tree.left, from) + val newRight = doTake(tree.right, until - count - 1) + if ((newLeft eq tree.left) && (newRight eq tree.right)) tree + else if (newLeft eq null) updNth(newRight, from - count - 1, tree.key, tree.value, overwrite = false) + else if (newRight eq null) updNth(newLeft, until, tree.key, tree.value, overwrite = false) + else rebalance(tree, newLeft, newRight) + } + + // The zipper returned might have been traversed left-most (always the left child) + // or right-most (always the right child). Left trees are traversed right-most, + // and right trees are traversed leftmost. + + // Returns the zipper for the side with deepest black nodes depth, a flag + // indicating whether the trees were unbalanced at all, and a flag indicating + // whether the zipper was traversed left-most or right-most. + + // If the trees were balanced, returns an empty zipper + private[this] def compareDepth[A, B](left: Tree[A, B], right: Tree[A, B]): (NList[Tree[A, B]], Boolean, Boolean, Int) = { + import NList.cons + // Once a side is found to be deeper, unzip it to the bottom + def unzip(zipper: NList[Tree[A, B]], leftMost: Boolean): NList[Tree[A, B]] = { + val next = if (leftMost) zipper.head.left else zipper.head.right + if (next eq null) zipper + else unzip(cons(next, zipper), leftMost) + } + + // Unzip left tree on the rightmost side and right tree on the leftmost side until one is + // found to be deeper, or the bottom is reached + def unzipBoth(left: Tree[A, B], + right: Tree[A, B], + leftZipper: NList[Tree[A, B]], + rightZipper: NList[Tree[A, B]], + smallerDepth: Int): (NList[Tree[A, B]], Boolean, Boolean, Int) = { + if (isBlackTree(left) && isBlackTree(right)) { + unzipBoth(left.right, right.left, cons(left, leftZipper), cons(right, rightZipper), smallerDepth + 1) + } else if (isRedTree(left) && isRedTree(right)) { + unzipBoth(left.right, right.left, cons(left, leftZipper), cons(right, rightZipper), smallerDepth) + } else if (isRedTree(right)) { + unzipBoth(left, right.left, leftZipper, cons(right, rightZipper), smallerDepth) + } else if (isRedTree(left)) { + unzipBoth(left.right, right, cons(left, leftZipper), rightZipper, smallerDepth) + } else if ((left eq null) && (right eq null)) { + (null, true, false, smallerDepth) + } else if ((left eq null) && isBlackTree(right)) { + val leftMost = true + (unzip(cons(right, rightZipper), leftMost), false, leftMost, smallerDepth) + } else if (isBlackTree(left) && (right eq null)) { + val leftMost = false + (unzip(cons(left, leftZipper), leftMost), false, leftMost, smallerDepth) + } else { + throw new IllegalStateException("unmatched trees in unzip: " + left + ", " + right) + } + } + unzipBoth(left, right, null, null, 0) + } + + private[this] def rebalance[A, B](tree: Tree[A, B], newLeft: Tree[A, B], newRight: Tree[A, B]) = { + // This is like drop(n-1), but only counting black nodes + @tailrec + def findDepth(zipper: NList[Tree[A, B]], depth: Int): NList[Tree[A, B]] = + if (zipper eq null) { + throw new IllegalStateException("Defect: unexpected empty zipper while computing range") + } else if (isBlackTree(zipper.head)) { + if (depth == 1) zipper else findDepth(zipper.tail, depth - 1) + } else { + findDepth(zipper.tail, depth) + } + + // Blackening the smaller tree avoids balancing problems on union; + // this can't be done later, though, or it would change the result of compareDepth + val blkNewLeft = blacken(newLeft) + val blkNewRight = blacken(newRight) + val (zipper, levelled, leftMost, smallerDepth) = compareDepth(blkNewLeft, blkNewRight) + + if (levelled) { + BlackTree(tree.key, tree.value, blkNewLeft, blkNewRight) + } else { + val zipFrom = findDepth(zipper, smallerDepth) + val union = if (leftMost) { + RedTree(tree.key, tree.value, blkNewLeft, zipFrom.head) + } else { + RedTree(tree.key, tree.value, zipFrom.head, blkNewRight) + } + val zippedTree = NList.foldLeft(zipFrom.tail, union: Tree[A, B]) { (tree, node) => + if (leftMost) + balanceLeft(isBlackTree(node), node.key, node.value, tree, node.right) + else + balanceRight(isBlackTree(node), node.key, node.value, node.left, tree) + } + zippedTree + } + } + + // Null optimized list implementation for tree rebalancing. null presents Nil. + private[this] final class NList[A](val head: A, val tail: NList[A]) + + private[this] final object NList { + + def cons[B](x: B, xs: NList[B]): NList[B] = new NList(x, xs) + + def foldLeft[A, B](xs: NList[A], z: B)(op: (B, A) => B): B = { + var acc = z + var these = xs + while (these ne null) { + acc = op(acc, these.head) + these = these.tail + } + acc + } + + } + + /* + * Forcing direct fields access using the @inline annotation helps speed up + * various operations (especially smallest/greatest and update/delete). + * + * Unfortunately the direct field access is not guaranteed to work (but + * works on the current implementation of the Scala compiler). + * + * An alternative is to implement the these classes using plain old Java code... + */ + sealed abstract class Tree[A, +B]( + @(inline @getter) final val key: A, + @(inline @getter) final val value: B, + @(inline @getter) final val left: Tree[A, B], + @(inline @getter) final val right: Tree[A, B]) + extends Serializable { + @(inline @getter) final val count: Int = 1 + RedBlackTree.count(left) + RedBlackTree.count(right) + def black: Tree[A, B] + def red: Tree[A, B] + } + final class RedTree[A, +B](key: A, + value: B, + left: Tree[A, B], + right: Tree[A, B]) extends Tree[A, B](key, value, left, right) { + override def black: Tree[A, B] = BlackTree(key, value, left, right) + override def red: Tree[A, B] = this + override def toString: String = "RedTree(" + key + ", " + value + ", " + left + ", " + right + ")" + } + final class BlackTree[A, +B](key: A, + value: B, + left: Tree[A, B], + right: Tree[A, B]) extends Tree[A, B](key, value, left, right) { + override def black: Tree[A, B] = this + override def red: Tree[A, B] = RedTree(key, value, left, right) + override def toString: String = "BlackTree(" + key + ", " + value + ", " + left + ", " + right + ")" + } + + object RedTree { + @inline def apply[A, B](key: A, value: B, left: Tree[A, B], right: Tree[A, B]) = new RedTree(key, value, left, right) + def unapply[A, B](t: RedTree[A, B]) = Some((t.key, t.value, t.left, t.right)) + } + object BlackTree { + @inline def apply[A, B](key: A, value: B, left: Tree[A, B], right: Tree[A, B]) = new BlackTree(key, value, left, right) + def unapply[A, B](t: BlackTree[A, B]) = Some((t.key, t.value, t.left, t.right)) + } + + private[this] abstract class TreeIterator[A, B, R](root: Tree[A, B], start: Option[A])(implicit ordering: Ordering[A]) extends Iterator[R] { + protected[this] def nextResult(tree: Tree[A, B]): R + + override def hasNext: Boolean = lookahead ne null + + override def next: R = lookahead match { + case null => + throw new NoSuchElementException("next on empty iterator") + case tree => + lookahead = findLeftMostOrPopOnEmpty(goRight(tree)) + nextResult(tree) + } + + @tailrec + private[this] def findLeftMostOrPopOnEmpty(tree: Tree[A, B]): Tree[A, B] = + if (tree eq null) popNext() + else if (tree.left eq null) tree + else findLeftMostOrPopOnEmpty(goLeft(tree)) + + private[this] def pushNext(tree: Tree[A, B]) { + try { + stackOfNexts(index) = tree + index += 1 + } catch { + case _: ArrayIndexOutOfBoundsException => + /* + * Either the tree became unbalanced or we calculated the maximum height incorrectly. + * To avoid crashing the iterator we expand the path array. Obviously this should never + * happen... + * + * An exception handler is used instead of an if-condition to optimize the normal path. + * This makes a large difference in iteration speed! + */ + assert(index >= stackOfNexts.length) + stackOfNexts :+= null + pushNext(tree) + } + } + private[this] def popNext(): Tree[A, B] = if (index == 0) null else { + index -= 1 + stackOfNexts(index) + } + + private[this] var stackOfNexts = if (root eq null) null else { + /* + * According to "Ralf Hinze. Constructing red-black trees" [http://www.cs.ox.ac.uk/ralf.hinze/publications/#P5] + * the maximum height of a red-black tree is 2*log_2(n + 2) - 2. + * + * According to {@see Integer#numberOfLeadingZeros} ceil(log_2(n)) = (32 - Integer.numberOfLeadingZeros(n - 1)) + * + * We also don't store the deepest nodes in the path so the maximum path length is further reduced by one. + */ + val maximumHeight = 2 * (32 - Integer.numberOfLeadingZeros(root.count + 2 - 1)) - 2 + new Array[Tree[A, B]](maximumHeight) + } + private[this] var index = 0 + private[this] var lookahead: Tree[A, B] = start map startFrom getOrElse findLeftMostOrPopOnEmpty(root) + + /** + * Find the leftmost subtree whose key is equal to the given key, or if no such thing, + * the leftmost subtree with the key that would be "next" after it according + * to the ordering. Along the way build up the iterator's path stack so that "next" + * functionality works. + */ + private[this] def startFrom(key: A) : Tree[A,B] = if (root eq null) null else { + @tailrec def find(tree: Tree[A, B]): Tree[A, B] = + if (tree eq null) popNext() + else find( + if (ordering.lteq(key, tree.key)) goLeft(tree) + else goRight(tree) + ) + find(root) + } + + private[this] def goLeft(tree: Tree[A, B]) = { + pushNext(tree) + tree.left + } + + private[this] def goRight(tree: Tree[A, B]) = tree.right + } + + private[this] class EntriesIterator[A: Ordering, B](tree: Tree[A, B], focus: Option[A]) extends TreeIterator[A, B, (A, B)](tree, focus) { + override def nextResult(tree: Tree[A, B]) = (tree.key, tree.value) + } + + private[this] class KeysIterator[A: Ordering, B](tree: Tree[A, B], focus: Option[A]) extends TreeIterator[A, B, A](tree, focus) { + override def nextResult(tree: Tree[A, B]) = tree.key + } + + private[this] class ValuesIterator[A: Ordering, B](tree: Tree[A, B], focus: Option[A]) extends TreeIterator[A, B, B](tree, focus) { + override def nextResult(tree: Tree[A, B]) = tree.value + } +} From c4a45ddf128f63ad2dc1ea31478dc6a0684ca06e Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Thu, 10 May 2018 15:26:07 +0200 Subject: [PATCH 0722/2665] Stop using the deprecated JavaConversions. There were still a number of uses in the test suite, as well as unused imports. Where it is easy to do so, we simply use the Java operations. Otherwise, we explicitly use JavaConverters. --- .../src/main/scala/java/util/HashMap.scala | 2 - .../concurrent/ConcurrentLinkedQueue.scala | 1 - .../concurrent/ConcurrentSkipListSet.scala | 4 - .../javalib/util/ArrayDequeTest.scala | 10 +- .../javalib/util/CollectionTest.scala | 22 ++--- .../CollectionsOnCheckedCollectionTest.scala | 6 +- .../util/CollectionsOnCheckedListTest.scala | 6 +- .../util/CollectionsOnCheckedMapTest.scala | 6 +- .../util/CollectionsOnCollectionsTest.scala | 20 ++-- .../javalib/util/CollectionsOnListsTest.scala | 96 +++++++++---------- .../javalib/util/CollectionsOnSetsTest.scala | 6 +- .../javalib/util/CollectionsTest.scala | 64 ++++++------- .../javalib/util/HashtableTest.scala | 42 ++++---- .../javalib/util/LinkedHashMapTest.scala | 38 ++++---- .../javalib/util/LinkedHashSetTest.scala | 4 +- .../javalib/util/LinkedListTest.scala | 12 +-- .../testsuite/javalib/util/MapTest.scala | 36 +++---- .../javalib/util/NavigableSetTest.scala | 20 ++-- .../javalib/util/PriorityQueueTest.scala | 12 +-- .../javalib/util/PropertiesTest.scala | 28 +++--- .../testsuite/javalib/util/SetTest.scala | 16 ++-- .../javalib/util/SortedSetTest.scala | 26 ++--- .../testsuite/javalib/util/TreeSetTest.scala | 14 +-- .../concurrent/ConcurrentHashMapTest.scala | 13 +-- .../ConcurrentLinkedQueueTest.scala | 10 +- .../ConcurrentSkipListSetTest.scala | 50 +++++----- .../concurrent/CopyOnWriteArrayListTest.scala | 18 ++-- .../testsuite/utils/CollectionsTestBase.scala | 12 +-- 28 files changed, 294 insertions(+), 300 deletions(-) diff --git a/javalib/src/main/scala/java/util/HashMap.scala b/javalib/src/main/scala/java/util/HashMap.scala index 9ded6629bc..de1d18e9bf 100644 --- a/javalib/src/main/scala/java/util/HashMap.scala +++ b/javalib/src/main/scala/java/util/HashMap.scala @@ -2,8 +2,6 @@ package java.util import scala.collection.mutable -import scala.collection.JavaConversions._ - class HashMap[K, V] protected (inner: mutable.Map[Box[K], V]) extends AbstractMap[K, V] with Serializable with Cloneable { self => diff --git a/javalib/src/main/scala/java/util/concurrent/ConcurrentLinkedQueue.scala b/javalib/src/main/scala/java/util/concurrent/ConcurrentLinkedQueue.scala index 13dc669d84..c3c2a93cc8 100644 --- a/javalib/src/main/scala/java/util/concurrent/ConcurrentLinkedQueue.scala +++ b/javalib/src/main/scala/java/util/concurrent/ConcurrentLinkedQueue.scala @@ -1,7 +1,6 @@ package java.util.concurrent import java.util._ -import scala.collection.JavaConversions._ class ConcurrentLinkedQueue[E]() extends AbstractQueue[E] with Queue[E] with Serializable { diff --git a/javalib/src/main/scala/java/util/concurrent/ConcurrentSkipListSet.scala b/javalib/src/main/scala/java/util/concurrent/ConcurrentSkipListSet.scala index 3d6234d781..29228c012d 100644 --- a/javalib/src/main/scala/java/util/concurrent/ConcurrentSkipListSet.scala +++ b/javalib/src/main/scala/java/util/concurrent/ConcurrentSkipListSet.scala @@ -1,10 +1,6 @@ package java.util.concurrent import java.util._ -import java.lang.Comparable -import scala.math.Ordering - -import scala.collection.JavaConversions._ class ConcurrentSkipListSet[E] private (inner: TreeSet[E]) extends AbstractSet[E] diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ArrayDequeTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ArrayDequeTest.scala index c3f9d58724..0ada3e3a75 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ArrayDequeTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ArrayDequeTest.scala @@ -12,7 +12,7 @@ import java.util import org.junit.Test import org.junit.Assert._ -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ import java.{util => ju} @@ -40,7 +40,7 @@ class ArrayDequeTest extends AbstractCollectionTest with DequeTest { @Test def could_be_instantiated_with_a_prepopulated_Collection(): Unit = { val s = Seq(1, 5, 2, 3, 4) - val l = asJavaCollection(s) + val l = s.asJavaCollection val ad = factory.from[Int](l) assertEquals(ad.size(), 5) @@ -52,7 +52,7 @@ class ArrayDequeTest extends AbstractCollectionTest with DequeTest { } @Test def should_add_multiple_element_in_one_operation(): Unit = { - val l = asJavaCollection(Set(1, 5, 2, 3, 4)) + val l = Set(1, 5, 2, 3, 4).asJavaCollection val ad = factory.empty[Int] assertEquals(ad.size(), 0) @@ -132,7 +132,7 @@ class ArrayDequeTest extends AbstractCollectionTest with DequeTest { } @Test def should_remove_occurrences_of_provided_elements(): Unit = { - val l = asJavaCollection(Seq("one", "two", "three", "two", "one")) + val l = Seq("one", "two", "three", "two", "one").asJavaCollection val ad = factory.from[String](l) assertTrue(ad.removeFirstOccurrence("one")) @@ -146,7 +146,7 @@ class ArrayDequeTest extends AbstractCollectionTest with DequeTest { @Test def should_iterate_over_elements_in_both_directions(): Unit = { val s = Seq("one", "two", "three") - val l = asJavaCollection(s) + val l = s.asJavaCollection val ad = factory.from[String](l) val iter = ad.iterator() diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionTest.scala index 20b00edd62..3b50203d48 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionTest.scala @@ -12,7 +12,7 @@ import java.{util => ju, lang => jl} import org.junit.Test import org.junit.Assert._ -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ import org.scalajs.testsuite.utils.AssertThrows._ @@ -44,14 +44,14 @@ trait CollectionTest { coll.clear() assertEquals(0, coll.size()) - assertFalse(coll.addAll(Seq.empty[String])) + assertFalse(coll.addAll(Seq.empty[String].asJava)) assertEquals(0, coll.size()) - assertTrue(coll.addAll(Seq("one"))) + assertTrue(coll.addAll(Seq("one").asJava)) assertEquals(1, coll.size()) coll.clear() - assertTrue(coll.addAll(Seq("one", "two", "one"))) + assertTrue(coll.addAll(Seq("one", "two", "one").asJava)) assertTrue(coll.size() >= 1) } @@ -64,14 +64,14 @@ trait CollectionTest { coll.clear() assertEquals(0, coll.size()) - assertFalse(coll.addAll(Seq.empty[Int])) + assertFalse(coll.addAll(Seq.empty[Int].asJava)) assertEquals(0, coll.size()) - assertTrue(coll.addAll(Seq(1))) + assertTrue(coll.addAll(Seq(1).asJava)) assertEquals(1, coll.size()) coll.clear() - assertTrue(coll.addAll(Seq(1, 2, 1))) + assertTrue(coll.addAll(Seq(1, 2, 1).asJava)) assertTrue(coll.size() >= 1) } @@ -84,14 +84,14 @@ trait CollectionTest { coll.clear() assertEquals(0, coll.size()) - assertFalse(coll.addAll(Seq.empty[Double])) + assertFalse(coll.addAll(Seq.empty[Double].asJava)) assertEquals(0, coll.size()) - assertTrue(coll.addAll(Seq(1.234))) + assertTrue(coll.addAll(Seq(1.234).asJava)) assertEquals(1, coll.size()) coll.clear() - assertTrue(coll.addAll(Seq(1.234, 2.345, 1.234))) + assertTrue(coll.addAll(Seq(1.234, 2.345, 1.234).asJava)) assertTrue(coll.size() >= 1) coll.clear() @@ -214,7 +214,7 @@ trait CollectionTest { coll.add("three") coll.add("three") - assertEquals(coll.iterator().toSet, Set("one", "two", "three")) + assertEquals(coll.iterator().asScala.toSet, Set("one", "two", "three")) } } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedCollectionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedCollectionTest.scala index e2b089da23..0d6ac3b419 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedCollectionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedCollectionTest.scala @@ -15,7 +15,7 @@ import org.junit.Test import org.scalajs.testsuite.javalib.util.concurrent.CopyOnWriteArrayListFactory -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ import org.scalajs.testsuite.utils.AssertThrows._ import org.scalajs.testsuite.utils.Platform._ @@ -41,7 +41,7 @@ trait CollectionsCheckedCollectionTest @Test def testCheckedCollection(): Unit = { assertTrue(superColl().add(new C)) - assertTrue(superColl().addAll(Seq(new C))) + assertTrue(superColl().addAll(Seq(new C).asJava)) } @Test def testCheckedCollectionBadInputs(): Unit = { @@ -49,7 +49,7 @@ trait CollectionsCheckedCollectionTest expectThrows(classOf[ClassCastException], superColl().add(new A)) expectThrows(classOf[ClassCastException], - superColl().addAll(Seq(new A))) + superColl().addAll(Seq(new A).asJava)) } protected def superColl(): ju.Collection[A] = diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedListTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedListTest.scala index 96b6aebd36..bc5ee36729 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedListTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedListTest.scala @@ -17,7 +17,7 @@ import org.scalajs.testsuite.javalib.util.concurrent.CopyOnWriteArrayListFactory import org.scalajs.testsuite.utils.AssertThrows._ import org.scalajs.testsuite.utils.Platform._ -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ import scala.reflect.ClassTag @@ -46,7 +46,7 @@ trait CollectionsCheckedListTest @Test def testCheckedList(): Unit = { superList().add(0, new C) - assertTrue(superList().addAll(0, Seq(new C))) + assertTrue(superList().addAll(0, Seq(new C).asJava)) testOnFirstPositionOfIterator[ju.ListIterator[A]](superList().listIterator _, _.add(new C), None) testOnFirstPositionOfIterator[ju.ListIterator[A]](superList().listIterator _, @@ -58,7 +58,7 @@ trait CollectionsCheckedListTest expectThrows(classOf[ClassCastException], superList().add(0, new A)) expectThrows(classOf[ClassCastException], - superList().addAll(0, Seq(new A))) + superList().addAll(0, Seq(new A).asJava)) testOnFirstPositionOfIterator[ju.ListIterator[A]]( superList().listIterator _, _.add(new A), Some(classOf[ClassCastException])) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedMapTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedMapTest.scala index 68fb0807dc..254f6211dc 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedMapTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedMapTest.scala @@ -16,7 +16,7 @@ import org.junit.Test import org.scalajs.testsuite.utils.AssertThrows._ import org.scalajs.testsuite.utils.Platform._ -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ import scala.reflect.ClassTag @@ -60,7 +60,7 @@ trait CollectionsOnCheckedMapTest extends CollectionsOnMapsTest { m.asInstanceOf[ju.Map[A, A]] } expectThrows(classOf[ClassCastException], - singletonMap().entrySet().head.setValue(new A)) + singletonMap().entrySet().asScala.head.setValue(new A)) } private def superMap(): ju.Map[A, A] = @@ -107,7 +107,7 @@ trait CollectionsOnCheckedSortedMapTest extends CollectionsOnSortedMapsTest { m.asInstanceOf[ju.Map[A, A]] } expectThrows(classOf[ClassCastException], - singletonMap().entrySet().head.setValue(new A)) + singletonMap().entrySet().asScala.head.setValue(new A)) } private def superMap(): ju.Map[A, A] = diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCollectionsTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCollectionsTest.scala index d880d6ef39..8af87256a2 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCollectionsTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCollectionsTest.scala @@ -15,7 +15,7 @@ import org.junit.Test import org.scalajs.testsuite.utils.CollectionsTestBase -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ import scala.reflect.ClassTag trait CollectionsOnCollectionsTest extends CollectionsTestBase { @@ -25,7 +25,7 @@ trait CollectionsOnCollectionsTest extends CollectionsTestBase { def testMinMax1[T <: AnyRef with Comparable[T]: ClassTag]( factory: CollectionFactory, toElem: Int => T, isMin: Boolean): Unit = { val coll = factory.empty[T] - coll.addAll(range.map(toElem)) + coll.addAll(range.map(toElem).asJava) val minMax = if (isMin) range.head else range.last def getMinMax(): T = @@ -36,9 +36,9 @@ trait CollectionsOnCollectionsTest extends CollectionsTestBase { coll match { case list: List[_] => - ju.Collections.shuffle(list, new ju.Random(42)) + ju.Collections.shuffle(list.asJava, new ju.Random(42)) assertEquals(0, getMinMax().compareTo(toElem(minMax))) - ju.Collections.shuffle(list, new ju.Random(100000)) + ju.Collections.shuffle(list.asJava, new ju.Random(100000)) assertEquals(0, getMinMax().compareTo(toElem(minMax))) case _ => } @@ -47,7 +47,7 @@ trait CollectionsOnCollectionsTest extends CollectionsTestBase { def testMinMax2[T: ClassTag](factory: CollectionFactory, toElem: Int => T, isMin: Boolean, cmp: ju.Comparator[T]): Unit = { val coll = factory.empty[T] - coll.addAll(range.map(toElem)) + coll.addAll(range.map(toElem).asJava) val minMax = if (isMin) range.head else range.last def getMinMax: T = @@ -58,9 +58,9 @@ trait CollectionsOnCollectionsTest extends CollectionsTestBase { coll match { case list: List[_] => - ju.Collections.shuffle(list, new ju.Random(42)) + ju.Collections.shuffle(list.asJava, new ju.Random(42)) assertEquals(0, cmp.compare(getMinMax, toElem(minMax))) - ju.Collections.shuffle(list, new ju.Random(100000)) + ju.Collections.shuffle(list.asJava, new ju.Random(100000)) assertEquals(0, cmp.compare(getMinMax, toElem(minMax))) case _ => } @@ -118,9 +118,9 @@ trait CollectionsOnCollectionsTest extends CollectionsTestBase { } expectAllFrequenciesToBe(0) - coll.addAll(range.map(toElem)) + coll.addAll(range.map(toElem).asJava) expectAllFrequenciesToBe(1) - coll.addAll(range.map(toElem)) + coll.addAll(range.map(toElem).asJava) coll match { case _: ju.Set[_] => expectAllFrequenciesToBe(1) case _: ju.List[_] => expectAllFrequenciesToBe(2) @@ -154,7 +154,7 @@ trait CollectionsOnCollectionsTest extends CollectionsTestBase { val coll = factory.empty[E] testCollectionUnmodifiability(ju.Collections.unmodifiableCollection(coll), toElem(0)) - coll.addAll(range.map(toElem)) + coll.addAll(range.map(toElem).asJava) testCollectionUnmodifiability(ju.Collections.unmodifiableCollection(coll), toElem(0)) } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnListsTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnListsTest.scala index 4a2c6b05c8..c5d3848424 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnListsTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnListsTest.scala @@ -9,7 +9,7 @@ import org.scalajs.testsuite.javalib.util.concurrent.CopyOnWriteArrayListFactory import org.scalajs.testsuite.utils.AssertThrows._ import org.scalajs.testsuite.utils.CollectionsTestBase -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ import scala.reflect.ClassTag object CollectionsOnListTest extends CollectionsTestBase { @@ -46,26 +46,26 @@ object CollectionsOnListTest extends CollectionsTestBase { def testIfSorted(rangeValues: Boolean): Unit = { for (i <- range.init) - assertTrue(list(i).compareTo(list(i + 1)) <= 0) + assertTrue(list.get(i).compareTo(list.get(i + 1)) <= 0) if (absoluteOrder && rangeValues) { for (i <- range) - assertEquals(0, list(i).compareTo(toElem(i))) + assertEquals(0, list.get(i).compareTo(toElem(i))) } } - list.addAll(range.map(toElem)) + list.addAll(range.map(toElem).asJava) ju.Collections.sort(list) testIfSorted(true) list.clear() - list.addAll(range.reverse.map(toElem)) + list.addAll(range.reverse.map(toElem).asJava) ju.Collections.sort(list) testIfSorted(true) for (seed <- List(0, 1, 42, -5432, 2341242)) { val rnd = new scala.util.Random(seed) list.clear() - list.addAll(range.map(_ => toElem(rnd.nextInt()))) + list.addAll(range.map(_ => toElem(rnd.nextInt())).asJava) ju.Collections.sort(list) testIfSorted(false) } @@ -78,10 +78,10 @@ object CollectionsOnListTest extends CollectionsTestBase { def testIfSorted(rangeValues: Boolean): Unit = { for (i <- range.init) - assertTrue(cmpFun(list(i), list(i + 1)) <= 0) + assertTrue(cmpFun(list.get(i), list.get(i + 1)) <= 0) if (absoluteOrder && rangeValues) { for (i <- range) - assertEquals(0, cmpFun(list(i), toElem(i))) + assertEquals(0, cmpFun(list.get(i), toElem(i))) } } @@ -89,19 +89,19 @@ object CollectionsOnListTest extends CollectionsTestBase { override def compare(o1: T, o2: T): Int = cmpFun(o1, o2) } - list.addAll(range.map(toElem)) + list.addAll(range.map(toElem).asJava) ju.Collections.sort(list, cmp) testIfSorted(true) list.clear() - list.addAll(range.reverse.map(toElem)) + list.addAll(range.reverse.map(toElem).asJava) ju.Collections.sort(list, cmp) testIfSorted(true) for (seed <- List(0, 1, 42, -5432, 2341242)) { val rnd = new scala.util.Random(seed) list.clear() - list.addAll(range.map(_ => toElem(rnd.nextInt()))) + list.addAll(range.map(_ => toElem(rnd.nextInt())).asJava) ju.Collections.sort(list, cmp) testIfSorted(false) } @@ -123,7 +123,7 @@ trait CollectionsOnListTest extends CollectionsOnCollectionsTest { def test[T <: AnyRef with Comparable[T]: ClassTag](toElem: Int => T): Unit = { val list = factory.empty[T] - list.addAll(range.map(toElem).sorted) + list.addAll(range.map(toElem).sorted.asJava) for (i <- Seq(range.head, range.last, range(range.size/3), range(range.size/2), range(3*range.size/5))) { @@ -155,7 +155,7 @@ trait CollectionsOnListTest extends CollectionsOnCollectionsTest { override def compare(o1: T, o2: T): Int = cmpFun(o1, o2) } - list.addAll(range.map(toElem).sortWith(cmpFun(_, _) < 0)) + list.addAll(range.map(toElem).sortWith(cmpFun(_, _) < 0).asJava) for (i <- Seq(range.head, range.last, range(range.size/3), range(range.size/2), range(3*range.size/5))) { @@ -183,14 +183,14 @@ trait CollectionsOnListTest extends CollectionsOnCollectionsTest { // Test: reverse(list: List[_]) def test[T: ClassTag](toElem: Int => T): Unit = { val list = factory.empty[T] - list.addAll(range.map(toElem)) + list.addAll(range.map(toElem).asJava) def testIfInOrder(reversed: Boolean): Unit = { for (i <- range) { val expected = if (reversed) range.last - i else i - assertEquals(toElem(expected), list(i)) + assertEquals(toElem(expected), list.get(i)) } } @@ -213,10 +213,10 @@ trait CollectionsOnListTest extends CollectionsOnCollectionsTest { val list = factory.empty[E] ju.Collections.shuffle(list) assertEquals(0, list.size) - list.addAll(range.map(toElem)) + list.addAll(range.map(toElem).asJava) shuffle(list) assertEquals(range.size, list.size) - assertTrue(list.containsAll(range.map(toElem))) + assertTrue(list.containsAll(range.map(toElem).asJava)) } test[jl.Integer](_.toInt) test[jl.Long](_.toLong) @@ -239,7 +239,7 @@ trait CollectionsOnListTest extends CollectionsOnCollectionsTest { // Test: swap(List[_], Int, Int) def test[E: ClassTag](toElem: Int => E): Unit = { val list = factory.empty[E] - list.addAll(range.map(toElem(_))) + list.addAll(range.map(toElem(_)).asJava) ju.Collections.swap(list, 0, 1) assertEquals(toElem(1), list.get(0)) @@ -271,7 +271,7 @@ trait CollectionsOnListTest extends CollectionsOnCollectionsTest { // Test: fill[E](List[E], E) def test[E: ClassTag](toElem: Int => E): Unit = { val list = factory.empty[E] - list.addAll(range.map(toElem(_))) + list.addAll(range.map(toElem(_)).asJava) ju.Collections.fill(list, toElem(0)) for (i <- range) @@ -299,7 +299,7 @@ trait CollectionsOnListTest extends CollectionsOnCollectionsTest { range.foreach(i => dest.add(toElem(-i))) ju.Collections.copy(dest, source) for (i <- range) - assertEquals(toElem(i), dest(i)) + assertEquals(toElem(i), dest.get(i)) // source.size < dest.size source.clear() @@ -308,9 +308,9 @@ trait CollectionsOnListTest extends CollectionsOnCollectionsTest { range.foreach(i => dest.add(toElem(-i))) ju.Collections.copy(dest, source) for (i <- range.take(range.size / 2)) - assertEquals(toElem(i), dest(i)) + assertEquals(toElem(i), dest.get(i)) for (i <- range.drop(range.size / 2)) - assertEquals(toElem(-i), dest(i)) + assertEquals(toElem(-i), dest.get(i)) // source.size > dest.size source.clear() @@ -330,33 +330,33 @@ trait CollectionsOnListTest extends CollectionsOnCollectionsTest { def modulo(a: Int, b: Int): Int = ((a % b) + b) % b def test[E: ClassTag](toElem: Int => E): Unit = { val list = factory.empty[E] - list.addAll(range.map(toElem)) + list.addAll(range.map(toElem).asJava) ju.Collections.rotate(list, 0) for (i <- range) - assertEquals(toElem(i), list(i)) + assertEquals(toElem(i), list.get(i)) ju.Collections.rotate(list, list.size) for (i <- range) - assertEquals(toElem(i), list(i)) + assertEquals(toElem(i), list.get(i)) ju.Collections.rotate(list, 1) for (i <- range) - assertEquals(toElem(modulo(i - 1, range.size)), list(i)) + assertEquals(toElem(modulo(i - 1, range.size)), list.get(i)) ju.Collections.rotate(list, 1) for (i <- range) - assertEquals(toElem(modulo(i - 2, range.size)), list(i)) + assertEquals(toElem(modulo(i - 2, range.size)), list.get(i)) ju.Collections.rotate(list, -5) for (i <- range) - assertEquals(toElem(modulo(i + 3, range.size)), list(i)) + assertEquals(toElem(modulo(i + 3, range.size)), list.get(i)) list.clear() - list.addAll((0 until 6).map(toElem)) + list.addAll((0 until 6).map(toElem).asJava) ju.Collections.rotate(list, 2) for (i <- 0 until 6) - assertEquals(toElem(modulo(i - 2, 6)), list(i)) + assertEquals(toElem(modulo(i - 2, 6)), list.get(i)) } test[jl.Integer](_.toInt) @@ -368,25 +368,25 @@ trait CollectionsOnListTest extends CollectionsOnCollectionsTest { @Test def replaceAll(): Unit = { def test[E: ClassTag](toElem: Int => E): Unit = { val list = factory.empty[E] - list.addAll(range.map(toElem)) + list.addAll(range.map(toElem).asJava) ju.Collections.replaceAll(list, toElem(range.last), toElem(0)) for (i <- range.init) - assertEquals(toElem(i), list(i)) - assertEquals(toElem(0), list.last) + assertEquals(toElem(i), list.get(i)) + assertEquals(toElem(0), list.asScala.last) ju.Collections.replaceAll(list, toElem(range(range.size - 2)), toElem(0)) for (i <- range.dropRight(2)) - assertEquals(toElem(i), list(i)) - assertEquals(toElem(0), list.dropRight(1).last) - assertEquals(toElem(0), list.last) + assertEquals(toElem(i), list.get(i)) + assertEquals(toElem(0), list.asScala.dropRight(1).last) + assertEquals(toElem(0), list.asScala.last) ju.Collections.replaceAll(list, toElem(0), toElem(-1)) for (i <- range.tail.dropRight(2)) - assertEquals(toElem(i), list(i)) - assertEquals(toElem(-1), list.head) - assertEquals(toElem(-1), list.dropRight(1).last) - assertEquals(toElem(-1), list.last) + assertEquals(toElem(i), list.get(i)) + assertEquals(toElem(-1), list.asScala.head) + assertEquals(toElem(-1), list.asScala.dropRight(1).last) + assertEquals(toElem(-1), list.asScala.last) } test[jl.Integer](_.toInt) @@ -402,16 +402,16 @@ trait CollectionsOnListTest extends CollectionsOnCollectionsTest { assertEquals(0, ju.Collections.indexOfSubList(source, target)) - source.addAll(range.map(toElem)) + source.addAll(range.map(toElem).asJava) assertEquals(0, ju.Collections.indexOfSubList(source, target)) - target.addAll(range.map(toElem)) + target.addAll(range.map(toElem).asJava) assertEquals(0, ju.Collections.indexOfSubList(source, target)) - source.addAll(range.map(toElem)) + source.addAll(range.map(toElem).asJava) assertEquals(0, ju.Collections.indexOfSubList(source, target)) - source.addAll(range.map(toElem)) + source.addAll(range.map(toElem).asJava) assertEquals(0, ju.Collections.indexOfSubList(source, target)) source.remove(0) @@ -434,16 +434,16 @@ trait CollectionsOnListTest extends CollectionsOnCollectionsTest { assertEquals(0, ju.Collections.lastIndexOfSubList(source, target)) - source.addAll(range.map(toElem)) + source.addAll(range.map(toElem).asJava) assertEquals(range.size, ju.Collections.lastIndexOfSubList(source, target)) - target.addAll(range.map(toElem)) + target.addAll(range.map(toElem).asJava) assertEquals(0, ju.Collections.lastIndexOfSubList(source, target)) - source.addAll(range.map(toElem)) + source.addAll(range.map(toElem).asJava) assertEquals(range.size, ju.Collections.lastIndexOfSubList(source, target)) - source.addAll(range.map(toElem)) + source.addAll(range.map(toElem).asJava) assertEquals(2 * range.size, ju.Collections.lastIndexOfSubList(source, target)) source.remove(source.size - 1) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSetsTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSetsTest.scala index 7f155b8ce2..087add78a8 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSetsTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSetsTest.scala @@ -4,7 +4,7 @@ import java.{util => ju, lang => jl} import org.junit.Test -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ import scala.reflect.ClassTag trait CollectionsOnSetsTest extends CollectionsOnCollectionsTest { @@ -14,7 +14,7 @@ trait CollectionsOnSetsTest extends CollectionsOnCollectionsTest { def test[E: ClassTag](toElem: Int => E): Unit = { val set = factory.empty[E] testSetUnmodifiability(ju.Collections.unmodifiableSet(set), toElem(0)) - set.addAll(range.map(toElem)) + set.addAll(range.map(toElem).asJava) testSetUnmodifiability(ju.Collections.unmodifiableSet(set), toElem(0)) } @@ -33,7 +33,7 @@ trait CollectionsOnSortedSetsTest extends CollectionsOnSetsTest { val sortedSet = factory.empty[E] testSortedSetUnmodifiability(ju.Collections.unmodifiableSortedSet(sortedSet), toElem(0)) - sortedSet.addAll(range.map(toElem)) + sortedSet.addAll(range.map(toElem).asJava) testSortedSetUnmodifiability(ju.Collections.unmodifiableSortedSet(sortedSet), toElem(0)) } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsTest.scala index 5a816ac561..6df862a77a 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsTest.scala @@ -15,7 +15,7 @@ import org.junit.Test import org.scalajs.testsuite.utils.AssertThrows._ import org.scalajs.testsuite.utils.CollectionsTestBase -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ import scala.reflect.ClassTag class CollectionsTest extends CollectionsTestBase { @@ -23,24 +23,24 @@ class CollectionsTest extends CollectionsTestBase { private def checkImmutablilityOfCollectionApi[E](coll: ju.Collection[E], elem: E): Unit = { expectThrows(classOf[UnsupportedOperationException], coll.add(elem)) - expectThrows(classOf[UnsupportedOperationException], coll.addAll(List(elem))) - assertFalse(coll.addAll(List.empty[E])) + expectThrows(classOf[UnsupportedOperationException], coll.addAll(List(elem).asJava)) + assertFalse(coll.addAll(List.empty[E].asJava)) - if (coll.count(_ == elem) != coll.size) - expectThrows(classOf[Exception], coll.retainAll(List(elem))) + if (coll.asScala.count(_ == elem) != coll.size) + expectThrows(classOf[Exception], coll.retainAll(List(elem).asJava)) else - assertFalse(coll.retainAll(List(elem))) + assertFalse(coll.retainAll(List(elem).asJava)) if (coll.contains(elem)) { expectThrows(classOf[Exception], coll.remove(elem)) - expectThrows(classOf[Exception], coll.removeAll(List(elem))) + expectThrows(classOf[Exception], coll.removeAll(List(elem).asJava)) } else { assertFalse(coll.remove(elem)) - assertFalse(coll.removeAll(List(elem))) + assertFalse(coll.removeAll(List(elem).asJava)) } - assertFalse(coll.removeAll(List.empty[E])) + assertFalse(coll.removeAll(List.empty[E].asJava)) - if (coll.nonEmpty) { + if (coll.asScala.nonEmpty) { expectThrows(classOf[Throwable], coll.clear()) } else { coll.clear() // Should not throw @@ -53,23 +53,23 @@ class CollectionsTest extends CollectionsTestBase { private def checkImmutablilityOfListApi[E](list: ju.List[E], elem: E): Unit = { checkImmutablilityOfCollectionApi(list, elem) expectThrows(classOf[UnsupportedOperationException], list.add(0, elem)) - assertFalse(list.addAll(0, List.empty[E])) - expectThrows(classOf[UnsupportedOperationException], list.addAll(0, List(elem))) + assertFalse(list.addAll(0, List.empty[E].asJava)) + expectThrows(classOf[UnsupportedOperationException], list.addAll(0, List(elem).asJava)) expectThrows(classOf[UnsupportedOperationException], list.remove(0)) } private def checkImmutablilityOfMapApi[K, V](map: ju.Map[K, V], k: K, v: V): Unit = { expectThrows(classOf[UnsupportedOperationException], map.put(k, v)) - expectThrows(classOf[UnsupportedOperationException], map.putAll(Map(k ->v))) - map.putAll(Map.empty[K, V]) // Should not throw + expectThrows(classOf[UnsupportedOperationException], map.putAll(Map(k ->v).asJava)) + map.putAll(Map.empty[K, V].asJava) // Should not throw if (map.containsKey(k)) expectThrows(classOf[Throwable], map.remove(k)) else assertNull(map.remove(k).asInstanceOf[AnyRef]) - if (map.nonEmpty) + if (map.asScala.nonEmpty) expectThrows(classOf[Throwable], map.clear()) else map.clear() // Should not throw @@ -80,7 +80,7 @@ class CollectionsTest extends CollectionsTestBase { val emptySet = ju.Collections.emptySet[E] assertTrue(emptySet.isEmpty) assertEquals(0, emptySet.size) - assertEquals(0, emptySet.iterator.size) + assertEquals(0, emptySet.iterator.asScala.size) checkImmutablilityOfSetApi(emptySet, toElem(0)) } @@ -94,7 +94,7 @@ class CollectionsTest extends CollectionsTestBase { val emptyList = ju.Collections.emptyList[E] assertTrue(emptyList.isEmpty) assertEquals(0, emptyList.size) - assertEquals(0, emptyList.iterator.size) + assertEquals(0, emptyList.iterator.asScala.size) checkImmutablilityOfListApi(emptyList, toElem(0)) } @@ -124,7 +124,7 @@ class CollectionsTest extends CollectionsTestBase { val singletonSet = ju.Collections.singleton[E](toElem(0)) assertTrue(singletonSet.contains(toElem(0))) assertEquals(1, singletonSet.size) - assertEquals(1, singletonSet.iterator.size) + assertEquals(1, singletonSet.iterator.asScala.size) checkImmutablilityOfSetApi(singletonSet, toElem(0)) checkImmutablilityOfSetApi(singletonSet, toElem(1)) } @@ -139,7 +139,7 @@ class CollectionsTest extends CollectionsTestBase { val singletonList = ju.Collections.singletonList[E](toElem(0)) assertTrue(singletonList.contains(toElem(0))) assertEquals(1, singletonList.size) - assertEquals(1, singletonList.iterator.size) + assertEquals(1, singletonList.iterator.asScala.size) checkImmutablilityOfListApi(singletonList, toElem(0)) checkImmutablilityOfListApi(singletonList, toElem(1)) } @@ -154,7 +154,7 @@ class CollectionsTest extends CollectionsTestBase { val singletonMap = ju.Collections.singletonMap[K, V](toKey(0), toValue(1)) assertEquals(toValue(1), singletonMap.get(toKey(0))) assertEquals(1, singletonMap.size) - assertEquals(1, singletonMap.iterator.size) + assertEquals(1, singletonMap.asScala.iterator.size) checkImmutablilityOfMapApi(singletonMap, toKey(0), toValue(0)) checkImmutablilityOfMapApi(singletonMap, toKey(1), toValue(1)) } @@ -169,9 +169,9 @@ class CollectionsTest extends CollectionsTestBase { for (n <- Seq(1, 4, 543)) { val nCopies = ju.Collections.nCopies(n, toElem(0)) assertTrue(nCopies.contains(toElem(0))) - nCopies.forall(_ == toElem(0)) + nCopies.asScala.forall(_ == toElem(0)) assertEquals(n, nCopies.size) - assertEquals(n, nCopies.iterator.size) + assertEquals(n, nCopies.iterator.asScala.size) checkImmutablilityOfListApi(nCopies, toElem(0)) checkImmutablilityOfListApi(nCopies, toElem(1)) } @@ -179,7 +179,7 @@ class CollectionsTest extends CollectionsTestBase { val zeroCopies = ju.Collections.nCopies(0, toElem(0)) assertFalse(zeroCopies.contains(toElem(0))) assertEquals(0, zeroCopies.size) - assertEquals(0, zeroCopies.iterator.size) + assertEquals(0, zeroCopies.iterator.asScala.size) checkImmutablilityOfListApi(zeroCopies, toElem(0)) for (n <- Seq(-1, -4, -543)) { @@ -258,9 +258,9 @@ class CollectionsTest extends CollectionsTestBase { } @Test def enumeration(): Unit = { - val coll = asJavaCollection(range) + val coll = range.asJavaCollection val enum = ju.Collections.enumeration(coll) - for (elem <- coll) { + for (elem <- coll.asScala) { assertTrue(enum.hasMoreElements) assertEquals(elem, enum.nextElement()) } @@ -268,7 +268,7 @@ class CollectionsTest extends CollectionsTestBase { } @Test def list(): Unit = { - val enum = asJavaEnumeration(range.iterator) + val enum = range.iterator.asJavaEnumeration val list = ju.Collections.list(enum) assertEquals(range.size, list.size) for (i <- range) @@ -276,11 +276,11 @@ class CollectionsTest extends CollectionsTestBase { } @Test def disjoint(): Unit = { - assertFalse(ju.Collections.disjoint(0 to 3, 0 to 3)) - assertFalse(ju.Collections.disjoint(0 to 3, 3 to 5)) - assertTrue(ju.Collections.disjoint(0 to 3, 6 to 9)) - assertTrue(ju.Collections.disjoint(0 to -1, 0 to 3)) - assertTrue(ju.Collections.disjoint(0 to 3, 0 to -1)) - assertTrue(ju.Collections.disjoint(0 to -1, 0 to -1)) + assertFalse(ju.Collections.disjoint((0 to 3).asJava, (0 to 3).asJava)) + assertFalse(ju.Collections.disjoint((0 to 3).asJava, (3 to 5).asJava)) + assertTrue(ju.Collections.disjoint((0 to 3).asJava, (6 to 9).asJava)) + assertTrue(ju.Collections.disjoint((0 to -1).asJava, (0 to 3).asJava)) + assertTrue(ju.Collections.disjoint((0 to 3).asJava, (0 to -1).asJava)) + assertTrue(ju.Collections.disjoint((0 to -1).asJava, (0 to -1).asJava)) } } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/HashtableTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/HashtableTest.scala index 72036e61f2..5679a71e1a 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/HashtableTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/HashtableTest.scala @@ -5,7 +5,7 @@ import org.junit.Assert._ import java.{util => ju} -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ class HashtableTest { @@ -36,22 +36,22 @@ class HashtableTest { @Test def keys(): Unit = { val ht = new ju.Hashtable[Int, Int] - assertEquals(Set.empty[Int], ht.keys().toSet) + assertEquals(Set.empty[Int], ht.keys().asScala.toSet) ht.put(1, 4) - assertEquals(Set(1), ht.keys().toSet) + assertEquals(Set(1), ht.keys().asScala.toSet) ht.put(2, 5) ht.put(3, 6) - assertEquals(Set(1, 2, 3), ht.keys().toSet) + assertEquals(Set(1, 2, 3), ht.keys().asScala.toSet) } @Test def elements(): Unit = { val ht = new ju.Hashtable[Int, Int] - assertEquals(Set.empty[Int], ht.elements().toSet) + assertEquals(Set.empty[Int], ht.elements().asScala.toSet) ht.put(1, 4) - assertEquals(Set(4), ht.elements().toSet) + assertEquals(Set(4), ht.elements().asScala.toSet) ht.put(2, 5) ht.put(3, 6) - assertEquals(Set(4, 5, 6), ht.elements().toSet) + assertEquals(Set(4, 5, 6), ht.elements().asScala.toSet) } @Test def contains(): Unit = { @@ -180,37 +180,37 @@ class HashtableTest { @Test def keySet(): Unit = { val ht = new ju.Hashtable[Int, Int] - assertEquals(Set.empty[Int], ht.keySet().toSet) + assertEquals(Set.empty[Int], ht.keySet().asScala.toSet) ht.put(1, 4) - assertEquals(Set(1), ht.keySet().toSet) + assertEquals(Set(1), ht.keySet().asScala.toSet) ht.put(2, 5) - assertEquals(Set(1, 2), ht.keySet().toSet) + assertEquals(Set(1, 2), ht.keySet().asScala.toSet) ht.put(3, 6) - assertEquals(Set(1, 2, 3), ht.keySet().toSet) + assertEquals(Set(1, 2, 3), ht.keySet().asScala.toSet) } @Test def entrySet(): Unit = { val ht = new ju.Hashtable[Int, Int] assertTrue(ht.entrySet().isEmpty) ht.put(1, 4) - assertEquals(Set(1), ht.entrySet().map(_.getKey)) - assertEquals(Set(4), ht.entrySet().map(_.getValue)) + assertEquals(Set(1), ht.entrySet().asScala.map(_.getKey)) + assertEquals(Set(4), ht.entrySet().asScala.map(_.getValue)) ht.put(2, 5) - assertEquals(Set(1, 2), ht.entrySet().map(_.getKey)) - assertEquals(Set(4, 5), ht.entrySet().map(_.getValue)) + assertEquals(Set(1, 2), ht.entrySet().asScala.map(_.getKey)) + assertEquals(Set(4, 5), ht.entrySet().asScala.map(_.getValue)) ht.put(3, 6) - assertEquals(Set(1, 2, 3), ht.entrySet().map(_.getKey)) - assertEquals(Set(4, 5, 6), ht.entrySet().map(_.getValue)) + assertEquals(Set(1, 2, 3), ht.entrySet().asScala.map(_.getKey)) + assertEquals(Set(4, 5, 6), ht.entrySet().asScala.map(_.getValue)) } @Test def values(): Unit = { val ht = new ju.Hashtable[Int, Int] - assertEquals(Set.empty[Int], ht.values().toSet) + assertEquals(Set.empty[Int], ht.values().asScala.toSet) ht.put(1, 4) - assertEquals(Set(4), ht.values().toSet) + assertEquals(Set(4), ht.values().asScala.toSet) ht.put(2, 5) - assertEquals(Set(4, 5), ht.values().toSet) + assertEquals(Set(4, 5), ht.values().asScala.toSet) ht.put(3, 6) - assertEquals(Set(4, 5, 6), ht.values().toSet) + assertEquals(Set(4, 5, 6), ht.values().asScala.toSet) } } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/LinkedHashMapTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/LinkedHashMapTest.scala index f84d675c72..e69a983b1f 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/LinkedHashMapTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/LinkedHashMapTest.scala @@ -10,7 +10,7 @@ package org.scalajs.testsuite.javalib.util import org.junit.Test import org.junit.Assert._ -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ import java.{util => ju, lang => jl} @@ -54,17 +54,17 @@ abstract class LinkedHashMapTest extends HashMapTest { val expectedSize = withSizeLimit.getOrElse(100) assertEquals(expectedSize, lhm.entrySet.size) - for ((entry, index) <- lhm.entrySet.zipWithIndex) { + for ((entry, index) <- lhm.entrySet.asScala.zipWithIndex) { assertEquals(expectedKey(index), entry.getKey) assertEquals(expectedValue(index), entry.getValue) } assertEquals(expectedSize, lhm.keySet.size) - for ((key, index) <- lhm.keySet.zipWithIndex) + for ((key, index) <- lhm.keySet.asScala.zipWithIndex) assertEquals(expectedKey(index), key) assertEquals(expectedSize, lhm.entrySet.size) - for ((value, index) <- lhm.values.zipWithIndex) + for ((value, index) <- lhm.values.asScala.zipWithIndex) assertEquals(expectedValue(index), value) } @@ -83,17 +83,17 @@ abstract class LinkedHashMapTest extends HashMapTest { val expectedSize = if (withSizeLimit.isDefined) 33 else 66 assertEquals(expectedSize, lhm.entrySet.size) - for ((entry, index) <- lhm.entrySet.zipWithIndex) { + for ((entry, index) <- lhm.entrySet.asScala.zipWithIndex) { assertEquals(expectedKey(index), entry.getKey) assertEquals(expectedValue(index), entry.getValue) } assertEquals(expectedSize, lhm.keySet.size) - for ((key, index) <- lhm.keySet.zipWithIndex) + for ((key, index) <- lhm.keySet.asScala.zipWithIndex) assertEquals(expectedKey(index), key) assertEquals(expectedSize, lhm.entrySet.size) - for ((value, index) <- lhm.values.zipWithIndex) + for ((value, index) <- lhm.values.asScala.zipWithIndex) assertEquals(expectedValue(index), value) } @@ -101,12 +101,12 @@ abstract class LinkedHashMapTest extends HashMapTest { val lhm = factory.empty[jl.Integer, String] (0 until 100).foreach(key => lhm.put(key, s"elem $key")) - lhm(0) = "new 0" - lhm(100) = "elem 100" - lhm(42) = "new 42" - lhm(52) = "new 52" - lhm(1) = "new 1" - lhm(98) = "new 98" + lhm.put(0, "new 0") + lhm.put(100, "elem 100") + lhm.put(42, "new 42") + lhm.put(52, "new 52") + lhm.put(1, "new 1") + lhm.put(98, "new 98") val expectedKey = { if (factory.accessOrder) { @@ -131,17 +131,17 @@ abstract class LinkedHashMapTest extends HashMapTest { assertEquals(expectedSize, lhm.entrySet.size) - for ((entry, index) <- lhm.entrySet.zipWithIndex) { + for ((entry, index) <- lhm.entrySet.asScala.zipWithIndex) { assertEquals(expectedKey(index), entry.getKey) assertEquals(expectedElem(index), entry.getValue) } assertEquals(expectedSize, lhm.keySet.size) - for ((key, index) <- lhm.keySet.zipWithIndex) + for ((key, index) <- lhm.keySet.asScala.zipWithIndex) assertEquals(expectedKey(index), key) assertEquals(expectedSize, lhm.entrySet.size) - for ((value, index) <- lhm.values.zipWithIndex) + for ((value, index) <- lhm.values.asScala.zipWithIndex) assertEquals(expectedElem(index), value) } @@ -185,17 +185,17 @@ abstract class LinkedHashMapTest extends HashMapTest { val expectedSize = withSizeLimit.getOrElse(100) assertEquals(expectedSize, lhm.entrySet.size) - for ((entry, index) <- lhm.entrySet.zipWithIndex) { + for ((entry, index) <- lhm.entrySet.asScala.zipWithIndex) { assertEquals(expectedKey(index), entry.getKey) assertEquals(expectedValue(index), entry.getValue) } assertEquals(expectedSize, lhm.keySet.size) - for ((key, index) <- lhm.keySet.zipWithIndex) + for ((key, index) <- lhm.keySet.asScala.zipWithIndex) assertEquals(expectedKey(index), key) assertEquals(expectedSize, lhm.entrySet.size) - for ((value, index) <- lhm.values.zipWithIndex) + for ((value, index) <- lhm.values.asScala.zipWithIndex) assertEquals(expectedValue(index), value) } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/LinkedHashSetTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/LinkedHashSetTest.scala index 5ac74f5240..3cdda88945 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/LinkedHashSetTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/LinkedHashSetTest.scala @@ -12,7 +12,7 @@ import java.{util => ju} import org.junit.Test import org.junit.Assert._ -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ import scala.reflect.ClassTag class LinkedHashSetTest extends HashSetTest { @@ -23,7 +23,7 @@ class LinkedHashSetTest extends HashSetTest { val hs = factory.empty[String] val l1 = List[String]("ONE", "TWO", (null: String)) - assertTrue(hs.addAll(asJavaCollection(l1))) + assertTrue(hs.addAll(l1.asJavaCollection)) assertEquals(3, hs.size) val iter1 = hs.iterator() diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/LinkedListTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/LinkedListTest.scala index 65388db321..87ea50ef94 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/LinkedListTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/LinkedListTest.scala @@ -12,7 +12,7 @@ import scala.language.implicitConversions import org.junit.Test import org.junit.Assert._ -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ import java.util.LinkedList @@ -40,7 +40,7 @@ class LinkedListTest extends AbstractListTest { @Test def could_be_instantiated_with_a_prepopulated_Collection(): Unit = { val s = Seq(1, 5, 2, 3, 4) - val l = asJavaCollection(s) + val l = s.asJavaCollection val ll = new LinkedList[Int](l) assertEquals(5, ll.size()) @@ -52,7 +52,7 @@ class LinkedListTest extends AbstractListTest { } @Test def should_add_multiple_element_in_one_operation(): Unit = { - val l = asJavaCollection(Set(1, 5, 2, 3, 4)) + val l = Set(1, 5, 2, 3, 4).asJavaCollection val ll = new LinkedList[Int]() assertEquals(0, ll.size()) @@ -64,7 +64,7 @@ class LinkedListTest extends AbstractListTest { @Test def `could_be_instantiated_with_a_prepopulated_Collection_-_LinkedListTest`(): Unit = { val s = Seq(1, 5, 2, 3, 4) - val l = asJavaCollection(s) + val l = s.asJavaCollection val ll = new LinkedList[Int](l) assertEquals(5, ll.size()) @@ -145,7 +145,7 @@ class LinkedListTest extends AbstractListTest { } @Test def should_remove_occurrences_of_provided_elements(): Unit = { - val l = asJavaCollection(Seq("one", "two", "three", "two", "one")) + val l = Seq("one", "two", "three", "two", "one").asJavaCollection val ll = new LinkedList[String](l) assertTrue(ll.removeFirstOccurrence("one")) @@ -161,7 +161,7 @@ class LinkedListTest extends AbstractListTest { @Test def should_iterate_over_elements_in_both_directions(): Unit = { val s = Seq("one", "two", "three") - val l = asJavaCollection(s) + val l = s.asJavaCollection val ll = new LinkedList[String](l) val iter = ll.iterator() diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/MapTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/MapTest.scala index 4681d9ac90..81987c50bc 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/MapTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/MapTest.scala @@ -15,7 +15,7 @@ import org.junit.Assert._ import org.scalajs.testsuite.javalib.util.concurrent.ConcurrentMapFactory import org.scalajs.testsuite.utils.AssertThrows._ -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ import scala.collection.{mutable => mu} import scala.reflect.ClassTag @@ -248,7 +248,7 @@ trait MapTest { val m = mu.Map[String, String]( "X" -> "y") - mp.putAll(mutableMapAsJavaMap(m)) + mp.putAll(m.asJava) assertEquals(1, mp.size) assertEquals("y", mp.get("X")) @@ -257,20 +257,20 @@ trait MapTest { "X" -> "y") if (factory.allowsNullKeys) { - mp.putAll(mutableMapAsJavaMap(nullMap)) + mp.putAll(nullMap.asJava) assertEquals("y", mp.get(null)) assertEquals("y", mp.get("X")) } else { - expectThrows(classOf[NullPointerException], mp.putAll(mutableMapAsJavaMap(nullMap))) + expectThrows(classOf[NullPointerException], mp.putAll(nullMap.asJava)) } } class SimpleQueryableMap[K, V](inner: mu.HashMap[K, V]) extends ju.AbstractMap[K, V] { def entrySet(): java.util.Set[java.util.Map.Entry[K, V]] = { - setAsJavaSet(inner.map { + inner.map { case (k, v) => new ju.AbstractMap.SimpleImmutableEntry(k, v) - }.toSet) + }.toSet[java.util.Map.Entry[K, V]].asJava } } @@ -331,19 +331,19 @@ trait MapTest { if (factory.allowsNullValuesQueries) assertFalse(values.contains(null)) else - expectThrows(classOf[Throwable], mp.contains(null)) + expectThrows(classOf[Throwable], mp.asScala.contains(null)) mp.put("THREE", "three") assertTrue(values.contains("three")) - val coll1 = asJavaCollection(Set("one", "two", "three")) + val coll1 = Set("one", "two", "three").asJavaCollection assertTrue(values.containsAll(coll1)) - val coll2 = asJavaCollection(Set("one", "two", "three", "four")) + val coll2 = Set("one", "two", "three", "four").asJavaCollection assertFalse(values.containsAll(coll2)) - val coll3 = asJavaCollection(Set("one", "two", "three", null)) + val coll3 = Set("one", "two", "three", null).asJavaCollection assertFalse(values.containsAll(coll2)) val nummp = factory.empty[Double, Double] @@ -414,7 +414,7 @@ trait MapTest { assertTrue(mp.containsKey("TWO")) assertTrue(mp.containsKey("THREE")) - values.removeAll(asJavaCollection(List("one", "two"))) + values.removeAll(List("one", "two").asJavaCollection) assertFalse(mp.containsKey("ONE")) assertFalse(mp.containsKey("TWO")) @@ -428,7 +428,7 @@ trait MapTest { assertTrue(mp.containsKey("TWO")) assertTrue(mp.containsKey("THREE")) - values.retainAll(asJavaCollection(List("one", "two"))) + values.retainAll(List("one", "two").asJavaCollection) assertTrue(mp.containsKey("ONE")) assertTrue(mp.containsKey("TWO")) @@ -492,22 +492,22 @@ trait MapTest { if (factory.allowsNullKeysQueries) assertFalse(keySet.contains(null)) else - expectThrows(classOf[Throwable], mp.contains(null)) + expectThrows(classOf[Throwable], mp.asScala.contains(null)) mp.put("THREE", "three") assertTrue(keySet.contains("THREE")) val coll1 = - asJavaCollection(Set("ONE", "TWO", "THREE")) + Set("ONE", "TWO", "THREE").asJavaCollection assertTrue(keySet.containsAll(coll1)) val coll2 = - asJavaCollection(Set("ONE", "TWO", "THREE", "FOUR")) + Set("ONE", "TWO", "THREE", "FOUR").asJavaCollection assertFalse(keySet.containsAll(coll2)) val coll3 = - asJavaCollection(Set("ONE", "TWO", "THREE", null)) + Set("ONE", "TWO", "THREE", null).asJavaCollection assertFalse(keySet.containsAll(coll2)) val nummp = factory.empty[Double, Double] @@ -579,7 +579,7 @@ trait MapTest { assertTrue(mp.containsKey("TWO")) assertTrue(mp.containsKey("THREE")) - keySet.removeAll(asJavaCollection(List("ONE", "TWO"))) + keySet.removeAll(List("ONE", "TWO").asJavaCollection) assertFalse(mp.containsKey("ONE")) assertFalse(mp.containsKey("TWO")) @@ -593,7 +593,7 @@ trait MapTest { assertTrue(mp.containsKey("TWO")) assertTrue(mp.containsKey("THREE")) - keySet.retainAll(asJavaCollection(List("ONE", "TWO"))) + keySet.retainAll(List("ONE", "TWO").asJavaCollection) assertTrue(mp.containsKey("ONE")) assertTrue(mp.containsKey("TWO")) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/NavigableSetTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/NavigableSetTest.scala index 64be499840..8b3d112a02 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/NavigableSetTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/NavigableSetTest.scala @@ -14,7 +14,7 @@ import java.{util => ju} import org.scalajs.testsuite.javalib.util.concurrent.ConcurrentSkipListSetFactory -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ import scala.reflect.ClassTag trait NavigableSetTest extends SetTest { @@ -22,7 +22,7 @@ trait NavigableSetTest extends SetTest { def factory: NavigableSetFactory @Test def `should_retrieve_ceiling(ordered)_elements`(): Unit = { - val lInt = asJavaCollection(Set(1, 5, 2, 3, 4)) + val lInt = Set(1, 5, 2, 3, 4).asJavaCollection val nsInt = factory.empty[Int] nsInt.addAll(lInt) @@ -32,7 +32,7 @@ trait NavigableSetTest extends SetTest { assertEquals(1, nsInt.ceiling(1)) assertEquals(5, nsInt.ceiling(5)) - val lString = asJavaCollection(Set("a", "e", "b", "c", "d")) + val lString = Set("a", "e", "b", "c", "d").asJavaCollection val nsString = factory.empty[String] nsString.addAll(lString) @@ -45,7 +45,7 @@ trait NavigableSetTest extends SetTest { } @Test def `should_retrieve_floor(ordered)_elements`(): Unit = { - val lInt = asJavaCollection(Set(1, 5, 2, 3, 4)) + val lInt = Set(1, 5, 2, 3, 4).asJavaCollection val nsInt = factory.empty[Int] nsInt.addAll(lInt) @@ -55,7 +55,7 @@ trait NavigableSetTest extends SetTest { assertEquals(3, nsInt.floor(3)) assertEquals(1, nsInt.floor(1)) - val lString = asJavaCollection(Set("a", "e", "b", "c", "d")) + val lString = Set("a", "e", "b", "c", "d").asJavaCollection val nsString = factory.empty[String] nsString.addAll(lString) @@ -68,7 +68,7 @@ trait NavigableSetTest extends SetTest { } @Test def `should_retrieve_higher(ordered)_elements`(): Unit = { - val lInt = asJavaCollection(Set(1, 5, 2, 3, 4)) + val lInt = Set(1, 5, 2, 3, 4).asJavaCollection val nsInt = factory.empty[Int] nsInt.addAll(lInt) @@ -78,7 +78,7 @@ trait NavigableSetTest extends SetTest { assertEquals(2, nsInt.higher(1)) assertEquals(1, nsInt.higher(-10)) - val lString = asJavaCollection(Set("a", "e", "b", "c", "d")) + val lString = Set("a", "e", "b", "c", "d").asJavaCollection val nsString = factory.empty[String] nsString.addAll(lString) @@ -91,7 +91,7 @@ trait NavigableSetTest extends SetTest { } @Test def `should_retrieve_lower(ordered)_elements`(): Unit = { - val lInt = asJavaCollection(Set(1, 5, 2, 3, 4)) + val lInt = Set(1, 5, 2, 3, 4).asJavaCollection val nsInt = factory.empty[Int] nsInt.addAll(lInt) @@ -101,7 +101,7 @@ trait NavigableSetTest extends SetTest { assertEquals(2, nsInt.lower(3)) assertEquals(5, nsInt.lower(10)) - val lString = asJavaCollection(Set("a", "e", "b", "c", "d")) + val lString = Set("a", "e", "b", "c", "d").asJavaCollection val nsString = factory.empty[String] nsString.addAll(lString) @@ -114,7 +114,7 @@ trait NavigableSetTest extends SetTest { } @Test def should_poll_first_and_last_elements(): Unit = { - val lInt = asJavaCollection(Set(1, 5, 2, 3, 4)) + val lInt = Set(1, 5, 2, 3, 4).asJavaCollection val ns = factory.empty[Int] ns.addAll(lInt) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/PriorityQueueTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/PriorityQueueTest.scala index c55bbc2de0..d0b5c53e09 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/PriorityQueueTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/PriorityQueueTest.scala @@ -9,7 +9,7 @@ package org.scalajs.testsuite.javalib.util import scala.language.implicitConversions -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ import org.junit.Test import org.junit.Assert._ @@ -117,7 +117,7 @@ class PriorityQueueTest { } @Test def could_be_instantiated_with_a_prepopulated_Collection(): Unit = { - val l = asJavaCollection(Set(1, 5, 2, 3, 4)) + val l = Set(1, 5, 2, 3, 4).asJavaCollection val pq = new PriorityQueue[Int](l) assertEquals(5, pq.size()) @@ -128,7 +128,7 @@ class PriorityQueueTest { } @Test def could_be_instantiated_with_a_prepopulated_PriorityQueue(): Unit = { - val l = asJavaCollection(Set(1, 5, 2, 3, 4)) + val l = Set(1, 5, 2, 3, 4).asJavaCollection val pq1 = new PriorityQueue[Int](l) val pq2 = new PriorityQueue[Int](pq1) @@ -142,7 +142,7 @@ class PriorityQueueTest { } @Test def could_be_instantiated_with_a_prepopulated_SortedSet(): Unit = { - val l = asJavaCollection(Set(1, 5, 2, 3, 4)) + val l = Set(1, 5, 2, 3, 4).asJavaCollection val ss = new java.util.concurrent.ConcurrentSkipListSet[Int](l) val pq1 = new PriorityQueue[Int](l) val pq2 = new PriorityQueue[Int](ss) @@ -157,7 +157,7 @@ class PriorityQueueTest { } @Test def should_be_cleared_in_a_single_operation(): Unit = { - val l = asJavaCollection(Set(1, 5, 2, 3, 4)) + val l = Set(1, 5, 2, 3, 4).asJavaCollection val pq = new PriorityQueue[Int](l) assertEquals(5, pq.size()) @@ -166,7 +166,7 @@ class PriorityQueueTest { } @Test def should_add_multiple_elemnt_in_one_operation(): Unit = { - val l = asJavaCollection(Set(1, 5, 2, 3, 4)) + val l = Set(1, 5, 2, 3, 4).asJavaCollection val pq = new PriorityQueue[Int]() assertEquals(0, pq.size()) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/PropertiesTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/PropertiesTest.scala index ecf4d0ade0..3acb0ea20b 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/PropertiesTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/PropertiesTest.scala @@ -9,7 +9,7 @@ import org.junit.Assume._ import org.scalajs.testsuite.utils.AssertThrows._ import org.scalajs.testsuite.utils.Platform._ -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ class PropertiesTest { @@ -51,18 +51,18 @@ class PropertiesTest { @Test def propertyNames(): Unit = { val prop = new Properties() - assertEquals(0, prop.propertyNames().size) + assertEquals(0, prop.propertyNames().asScala.size) prop.setProperty("a", "A") prop.setProperty("b", "B") prop.setProperty("c", "C") - assertEquals(3, prop.propertyNames().size) - assertEquals(Set("a", "b", "c"), prop.propertyNames().toSet) + assertEquals(3, prop.propertyNames().asScala.size) + assertEquals(Set("a", "b", "c"), prop.propertyNames().asScala.toSet) val prop2 = new Properties(prop) prop.setProperty("c", "CC") prop.setProperty("d", "D") - assertEquals(4, prop2.propertyNames().size) - assertEquals(Set("a", "b", "c", "d"), prop2.propertyNames().toSet) + assertEquals(4, prop2.propertyNames().asScala.size) + assertEquals(Set("a", "b", "c", "d"), prop2.propertyNames().asScala.toSet) } @Test def propertyNamesWithBadContents(): Unit = { @@ -78,7 +78,7 @@ class PropertiesTest { prop.remove(1.asInstanceOf[AnyRef]) prop.put("1", 1.asInstanceOf[AnyRef]) - assertEquals(Set("a", "b", "c", "1"), prop.propertyNames().toSet) + assertEquals(Set("a", "b", "c", "1"), prop.propertyNames().asScala.toSet) prop.remove("1") val prop2 = new Properties(prop) @@ -90,7 +90,7 @@ class PropertiesTest { prop2.remove(1.asInstanceOf[AnyRef]) prop2.put("1", 1.asInstanceOf[AnyRef]) - assertEquals(Set("a", "b", "c", "d", "1"), prop2.propertyNames().toSet) + assertEquals(Set("a", "b", "c", "d", "1"), prop2.propertyNames().asScala.toSet) } @Test def stringPropertyNames(): Unit = { @@ -100,13 +100,13 @@ class PropertiesTest { prop.setProperty("b", "B") prop.setProperty("c", "C") assertEquals(3, prop.stringPropertyNames().size) - assertEquals(Set("a", "b", "c"), prop.stringPropertyNames().toSet) + assertEquals(Set("a", "b", "c"), prop.stringPropertyNames().asScala.toSet) val prop2 = new Properties(prop) prop.setProperty("c", "CC") prop.setProperty("d", "D") assertEquals(4, prop2.stringPropertyNames().size) - assertEquals(Set("a", "b", "c", "d"), prop2.stringPropertyNames().toSet) + assertEquals(Set("a", "b", "c", "d"), prop2.stringPropertyNames().asScala.toSet) } @Test def stringPropertyNamesWithBadContents(): Unit = { @@ -118,11 +118,11 @@ class PropertiesTest { prop.setProperty("c", "C") prop.put(1.asInstanceOf[AnyRef], "2") - assertEquals(Set("a", "b", "c"), prop.stringPropertyNames().toSet) + assertEquals(Set("a", "b", "c"), prop.stringPropertyNames().asScala.toSet) prop.remove(1.asInstanceOf[AnyRef]) prop.put("1", 1.asInstanceOf[AnyRef]) - assertEquals(Set("a", "b", "c"), prop.stringPropertyNames().toSet) + assertEquals(Set("a", "b", "c"), prop.stringPropertyNames().asScala.toSet) prop.remove("1") val prop2 = new Properties(prop) @@ -130,10 +130,10 @@ class PropertiesTest { prop.setProperty("d", "D") prop2.put(1.asInstanceOf[AnyRef], "2") - assertEquals(Set("a", "b", "c", "d"), prop2.stringPropertyNames().toSet) + assertEquals(Set("a", "b", "c", "d"), prop2.stringPropertyNames().asScala.toSet) prop2.remove(1.asInstanceOf[AnyRef]) prop2.put("1", 1.asInstanceOf[AnyRef]) - assertEquals(Set("a", "b", "c", "d"), prop2.stringPropertyNames().toSet) + assertEquals(Set("a", "b", "c", "d"), prop2.stringPropertyNames().asScala.toSet) } } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/SetTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/SetTest.scala index 1bac336fd7..2da5a71546 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/SetTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/SetTest.scala @@ -16,7 +16,7 @@ import org.scalajs.testsuite.utils.AssertThrows._ import java.{util => ju, lang => jl} -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ import scala.reflect.ClassTag trait SetTest extends CollectionTest { @@ -140,14 +140,14 @@ trait SetTest extends CollectionTest { assertTrue(hs.add("TWO")) assertEquals(2, hs.size()) val l1 = List[String]("ONE", "TWO") - assertTrue(hs.removeAll(asJavaCollection(l1))) + assertTrue(hs.removeAll(l1.asJavaCollection)) assertEquals(0, hs.size()) assertTrue(hs.add("ONE")) assertTrue(hs.add("TWO")) assertEquals(2, hs.size()) val l2 = List[String]("ONE", "THREE") - assertTrue(hs.retainAll(asJavaCollection(l2))) + assertTrue(hs.retainAll(l2.asJavaCollection)) assertEquals(1, hs.size()) assertTrue(hs.contains("ONE")) assertFalse(hs.contains("TWO")) @@ -185,7 +185,7 @@ trait SetTest extends CollectionTest { if (factory.allowsNullElement) { val l = List[String]("ONE", "TWO", (null: String)) - assertTrue(hs.addAll(asJavaCollection(l))) + assertTrue(hs.addAll(l.asJavaCollection)) assertEquals(3, hs.size) assertTrue(hs.contains("ONE")) assertTrue(hs.contains("TWO")) @@ -193,7 +193,7 @@ trait SetTest extends CollectionTest { } else { expectThrows(classOf[Exception], { val l = List[String]("ONE", "TWO", (null: String)) - hs.addAll(asJavaCollection(l)) + hs.addAll(l.asJavaCollection) }) } } @@ -207,7 +207,7 @@ trait SetTest extends CollectionTest { else List[String]("ONE", "TWO", "THREE") } - assertTrue(hs.addAll(asJavaCollection(l))) + assertTrue(hs.addAll(l.asJavaCollection)) assertEquals(3, hs.size) val iter = hs.iterator() @@ -218,8 +218,8 @@ trait SetTest extends CollectionTest { } } assertFalse(iter.hasNext()) - assertTrue(result.containsAll(l)) - assertTrue(l.containsAll(result)) + assertTrue(result.asJava.containsAll(l.asJava)) + assertTrue(l.asJava.containsAll(result.asJava)) } } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/SortedSetTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/SortedSetTest.scala index bcacac9c9f..c063d1edbe 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/SortedSetTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/SortedSetTest.scala @@ -11,7 +11,7 @@ import org.junit.Test import org.junit.Assert._ import java.{util => ju} -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ import scala.reflect.ClassTag trait SortedSetTest extends SetTest { @@ -67,7 +67,7 @@ trait SortedSetTest extends SetTest { assertEquals(10000.987, ssDouble.last, 0.0) } - val l = asJavaCollection(Set(1, 5, 2, 3, 4)) + val l = Set(1, 5, 2, 3, 4).asJavaCollection @Test def shouldReturnAProperHeadSet(): Unit = { val ss = factory.empty[Int] @@ -75,22 +75,22 @@ trait SortedSetTest extends SetTest { ss.addAll(l) val hs1 = ss.headSet(3) - val l1 = asJavaCollection(Set(1,2)) + val l1 = Set(1,2).asJavaCollection assertTrue(hs1.containsAll(l1)) assertTrue(hs1.removeAll(l1)) assertTrue(hs1.isEmpty) assertEquals(3, ss.size) - assertTrue(ss.containsAll(asJavaCollection(Set(3,4,5)))) + assertTrue(ss.containsAll(Set(3,4,5).asJavaCollection)) ss.addAll(l) val hs2 = ss.headSet(4) - val l2 = asJavaCollection(Set(1,2,3)) + val l2 = Set(1,2,3).asJavaCollection assertTrue(hs2.containsAll(l2)) assertTrue(hs2.removeAll(l2)) assertTrue(hs2.isEmpty) assertEquals(2, ss.size) - assertTrue(ss.containsAll(asJavaCollection(Set(4,5)))) + assertTrue(ss.containsAll(Set(4,5).asJavaCollection)) } @Test def shouldReturnAProperTailSet(): Unit = { @@ -99,22 +99,22 @@ trait SortedSetTest extends SetTest { ss.addAll(l) val ts1 = ss.tailSet(3) - val l3 = asJavaCollection(Set(3,4,5)) + val l3 = Set(3,4,5).asJavaCollection assertTrue(ts1.containsAll(l3)) assertTrue(ts1.removeAll(l3)) assertTrue(ts1.isEmpty) assertEquals(2, ss.size) - assertTrue(ss.containsAll(asJavaCollection(Set(1,2)))) + assertTrue(ss.containsAll(Set(1,2).asJavaCollection)) ss.addAll(l) val ts2 = ss.tailSet(4) - val l4 = asJavaCollection(Set(4,5)) + val l4 = Set(4,5).asJavaCollection assertTrue(ts2.containsAll(l4)) assertTrue(ts2.removeAll(l4)) assertTrue(ts2.isEmpty) assertEquals(3, ss.size) - assertTrue(ss.containsAll(asJavaCollection(Set(1,2,3)))) + assertTrue(ss.containsAll(Set(1,2,3).asJavaCollection)) } @Test def shouldReturnAProperSubSet(): Unit = { @@ -123,12 +123,12 @@ trait SortedSetTest extends SetTest { ss.addAll(l) val ss1 = ss.subSet(2, 4) - val l5 = asJavaCollection(Set(2,3)) + val l5 = Set(2,3).asJavaCollection assertTrue(ss1.containsAll(l5)) assertTrue(ss1.removeAll(l5)) assertTrue(ss1.isEmpty) assertEquals(3, ss.size) - assertTrue(ss.containsAll(asJavaCollection(Set(1,4,5)))) + assertTrue(ss.containsAll(Set(1,4,5).asJavaCollection)) ss.addAll(l) @@ -137,7 +137,7 @@ trait SortedSetTest extends SetTest { assertTrue(ss2.removeAll(l5)) assertFalse(ss2.isEmpty) assertEquals(3, ss.size) - assertTrue(ss.containsAll(asJavaCollection(Set(1,4,5)))) + assertTrue(ss.containsAll(Set(1,4,5).asJavaCollection)) } } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/TreeSetTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/TreeSetTest.scala index 4f8ea8a5d0..65a77f4aa3 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/TreeSetTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/TreeSetTest.scala @@ -11,7 +11,7 @@ import org.junit.Assert._ import scala.language.implicitConversions -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ import org.junit.Test import org.junit.Assert._ @@ -174,7 +174,7 @@ abstract class TreeSetTest(val factory: TreeSetFactory) } @Test def could_be_instantiated_with_a_prepopulated_Collection(): Unit = { - val l = asJavaCollection(Set(1, 5, 2, 3, 4)) + val l = Set(1, 5, 2, 3, 4).asJavaCollection val ts = factory.newFrom(l) assertEquals(5, ts.size()) @@ -186,7 +186,7 @@ abstract class TreeSetTest(val factory: TreeSetFactory) } @Test def should_be_cleared_in_a_single_operation(): Unit = { - val l = asJavaCollection(Set(1, 5, 2, 3, 4)) + val l = Set(1, 5, 2, 3, 4).asJavaCollection val ts = factory.empty[Int] ts.addAll(l) @@ -197,7 +197,7 @@ abstract class TreeSetTest(val factory: TreeSetFactory) } @Test def should_add_multiple_element_in_one_operation(): Unit = { - val l = asJavaCollection(Set(1, 5, 2, 3, 4)) + val l = Set(1, 5, 2, 3, 4).asJavaCollection val ts = factory.empty[Int] assertEquals(0, ts.size()) @@ -262,13 +262,13 @@ abstract class TreeSetTest(val factory: TreeSetFactory) val ts1 = factory.empty[String] if (factory.allowsNullElement) { - assertTrue(ts1.addAll(l)) + assertTrue(ts1.addAll(l.asJava)) assertTrue(ts1.contains(null)) assertTrue(ts1.contains("ONE")) assertFalse(ts1.contains("THREE")) } else { expectThrows(classOf[Exception], { - ts1.addAll(asJavaCollection(l)) + ts1.addAll(l.asJavaCollection) }) } } @@ -287,7 +287,7 @@ abstract class TreeSetTest(val factory: TreeSetFactory) @Test def should_throw_exceptions_on_access_outside_bound_on_views(): Unit = { assumeTrue("Assumed compliant asInstanceOf", hasCompliantAsInstanceOfs) - val l = asJavaCollection(Set(2, 3, 6)) + val l = Set(2, 3, 6).asJavaCollection val ts = factory.empty[Int] ts.addAll(l) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentHashMapTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentHashMapTest.scala index 4227b3e4b1..34aca88d01 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentHashMapTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentHashMapTest.scala @@ -7,17 +7,18 @@ \* */ package org.scalajs.testsuite.javalib.util.concurrent +import scala.language.implicitConversions + +import scala.reflect.ClassTag + import java.{util => ju} import org.junit.Assert._ import org.junit.Test + import org.scalajs.testsuite.javalib.util.MapTest import org.scalajs.testsuite.utils.AssertThrows._ -import scala.collection.JavaConversions._ -import scala.language.implicitConversions -import scala.reflect.ClassTag - class ConcurrentHashMapTest extends MapTest { def factory: ConcurrentHashMapFactory = new ConcurrentHashMapFactory @@ -27,9 +28,9 @@ class ConcurrentHashMapTest extends MapTest { chm.put("ONE", "one") val elements = chm.elements - assertTrue(elements.hasNext) + assertTrue(elements.hasMoreElements) assertEquals("one", elements.nextElement) - assertFalse(elements.hasNext) + assertFalse(elements.hasMoreElements) } @Test def `should replace contained items`(): Unit = { diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentLinkedQueueTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentLinkedQueueTest.scala index efa4dce139..d83669ec68 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentLinkedQueueTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentLinkedQueueTest.scala @@ -14,7 +14,7 @@ import org.junit.Assert._ import org.junit.Test import org.scalajs.testsuite.javalib.util.{AbstractCollectionFactory, AbstractCollectionTest} -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ import scala.language.implicitConversions import scala.reflect.ClassTag @@ -81,18 +81,18 @@ class ConcurrentLinkedQueueTest extends AbstractCollectionTest { } @Test def could_be_instantiated_with_a_prepopulated_Collection(): Unit = { - val l = asJavaCollection(Set(1, 5, 2, 3, 4)) + val l = Set(1, 5, 2, 3, 4).asJavaCollection val pq = factory.newFrom(l) assertEquals(5, pq.size()) - for (i <- l) { + for (i <- l.asScala) { assertEquals(i, pq.poll()) } assertTrue(pq.isEmpty) } @Test def should_be_cleared_in_a_single_operation(): Unit = { - val l = asJavaCollection(Set(1, 5, 2, 3, 4)) + val l = Set(1, 5, 2, 3, 4).asJavaCollection val pq = factory.newFrom(l) assertEquals(5, pq.size()) @@ -101,7 +101,7 @@ class ConcurrentLinkedQueueTest extends AbstractCollectionTest { } @Test def should_add_multiple_elemnt_in_one_operation(): Unit = { - val l = asJavaCollection(Set(1, 5, 2, 3, 4)) + val l = Set(1, 5, 2, 3, 4).asJavaCollection val pq = factory.empty[Int] assertEquals(0, pq.size()) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentSkipListSetTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentSkipListSetTest.scala index 882e992eef..58922a02ee 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentSkipListSetTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentSkipListSetTest.scala @@ -18,7 +18,7 @@ import org.scalajs.testsuite.javalib.util.NavigableSetFactory import org.scalajs.testsuite.utils.AssertThrows._ import org.scalajs.testsuite.utils.Platform._ -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ import scala.language.implicitConversions import scala.reflect.ClassTag @@ -131,7 +131,7 @@ class ConcurrentSkipListSetTest { } @Test def could_be_instantiated_with_a_prepopulated_Collection(): Unit = { - val l = asJavaCollection(Set(1, 5, 2, 3, 4)) + val l = Set(1, 5, 2, 3, 4).asJavaCollection val csls = factory.newFrom(l) assertEquals(5, csls.size()) @@ -143,7 +143,7 @@ class ConcurrentSkipListSetTest { } @Test def should_be_cleared_in_a_single_operation(): Unit = { - val l = asJavaCollection(Set(1, 5, 2, 3, 4)) + val l = Set(1, 5, 2, 3, 4).asJavaCollection val csls = factory.newFrom(l) assertEquals(5, csls.size()) @@ -152,7 +152,7 @@ class ConcurrentSkipListSetTest { } @Test def should_add_multiple_elemnt_in_one_operation(): Unit = { - val l = asJavaCollection(Set(1, 5, 2, 3, 4)) + val l = Set(1, 5, 2, 3, 4).asJavaCollection val csls = factory.empty[Int] assertEquals(0, csls.size()) @@ -238,7 +238,7 @@ class ConcurrentSkipListSetTest { } @Test def `should_retrieve_ceiling(ordered)_elements`(): Unit = { - val lInt = asJavaCollection(Set(1, 5, 2, 3, 4)) + val lInt = Set(1, 5, 2, 3, 4).asJavaCollection val cslsInt = new ConcurrentSkipListSet[Int](lInt) assertEquals(1, cslsInt.ceiling(-10)) @@ -246,7 +246,7 @@ class ConcurrentSkipListSetTest { assertEquals(1, cslsInt.ceiling(1)) assertEquals(5, cslsInt.ceiling(5)) - val lString = asJavaCollection(Set("a", "e", "b", "c", "d")) + val lString = Set("a", "e", "b", "c", "d").asJavaCollection val cslsString = new ConcurrentSkipListSet[String](lString) assertEquals("a", cslsString.ceiling("00000")) @@ -257,7 +257,7 @@ class ConcurrentSkipListSetTest { } @Test def `should_retrieve_floor(ordered)_elements`(): Unit = { - val lInt = asJavaCollection(Set(1, 5, 2, 3, 4)) + val lInt = Set(1, 5, 2, 3, 4).asJavaCollection val cslsInt = new ConcurrentSkipListSet[Int](lInt) assertEquals(5, cslsInt.floor(10)) @@ -265,7 +265,7 @@ class ConcurrentSkipListSetTest { assertEquals(3, cslsInt.floor(3)) assertEquals(1, cslsInt.floor(1)) - val lString = asJavaCollection(Set("a", "e", "b", "c", "d")) + val lString = Set("a", "e", "b", "c", "d").asJavaCollection val cslsString = new ConcurrentSkipListSet[String](lString) assertEquals("e", cslsString.floor("zzzzz")) @@ -276,7 +276,7 @@ class ConcurrentSkipListSetTest { } @Test def `should_retrieve_higher(ordered)_elements`(): Unit = { - val lInt = asJavaCollection(Set(1, 5, 2, 3, 4)) + val lInt = Set(1, 5, 2, 3, 4).asJavaCollection val cslsInt = new ConcurrentSkipListSet[Int](lInt) assertEquals(5, cslsInt.higher(4)) @@ -284,7 +284,7 @@ class ConcurrentSkipListSetTest { assertEquals(2, cslsInt.higher(1)) assertEquals(1, cslsInt.higher(-10)) - val lString = asJavaCollection(Set("a", "e", "b", "c", "d")) + val lString = Set("a", "e", "b", "c", "d").asJavaCollection val cslsString = new ConcurrentSkipListSet[String](lString) assertNull(cslsString.higher("zzzzz")) @@ -295,7 +295,7 @@ class ConcurrentSkipListSetTest { } @Test def `should_retrieve_lower(ordered)_elements`(): Unit = { - val lInt = asJavaCollection(Set(1, 5, 2, 3, 4)) + val lInt = Set(1, 5, 2, 3, 4).asJavaCollection val cslsInt = new ConcurrentSkipListSet[Int](lInt) assertEquals(4, cslsInt.lower(5)) @@ -303,7 +303,7 @@ class ConcurrentSkipListSetTest { assertEquals(2, cslsInt.lower(3)) assertEquals(5, cslsInt.lower(10)) - val lString = asJavaCollection(Set("a", "e", "b", "c", "d")) + val lString = Set("a", "e", "b", "c", "d").asJavaCollection val cslsString = new ConcurrentSkipListSet[String](lString) assertEquals("e", cslsString.lower("zzzzz")) @@ -314,7 +314,7 @@ class ConcurrentSkipListSetTest { } @Test def should_poll_first_and_last_elements(): Unit = { - val l = asJavaCollection(Set(1, 5, 2, 3, 4)) + val l = Set(1, 5, 2, 3, 4).asJavaCollection val csls = new ConcurrentSkipListSet[Int](l) assertTrue(csls.contains(1)) @@ -328,56 +328,56 @@ class ConcurrentSkipListSetTest { } @Test def should_get_partial_views_that_are_backed_on_the_original_list(): Unit = { - val l = asJavaCollection(Set(1, 5, 2, 3, 4)) + val l = Set(1, 5, 2, 3, 4).asJavaCollection val csls = new ConcurrentSkipListSet[Int](l) val hs1 = csls.headSet(3) - val l1 = asJavaCollection(Set(1,2)) + val l1 = Set(1,2).asJavaCollection assertTrue(hs1.containsAll(l1)) assertTrue(hs1.removeAll(l1)) assertTrue(hs1.isEmpty) assertEquals(3, csls.size) - assertTrue(csls.containsAll(asJavaCollection(Set(3,4,5)))) + assertTrue(csls.containsAll(Set(3,4,5).asJavaCollection)) csls.addAll(l) val hs2 = csls.headSet(3, true) - val l2 = asJavaCollection(Set(1,2,3)) + val l2 = Set(1,2,3).asJavaCollection assertTrue(hs2.containsAll(l2)) assertTrue(hs2.removeAll(l2)) assertTrue(hs2.isEmpty) assertEquals(2, csls.size) - assertTrue(csls.containsAll(asJavaCollection(Set(4,5)))) + assertTrue(csls.containsAll(Set(4,5).asJavaCollection)) csls.addAll(l) val ts1 = csls.tailSet(3) - val l3 = asJavaCollection(Set(3,4,5)) + val l3 = Set(3,4,5).asJavaCollection assertTrue(ts1.containsAll(l3)) assertTrue(ts1.removeAll(l3)) assertTrue(ts1.isEmpty) assertEquals(2, csls.size) - assertTrue(csls.containsAll(asJavaCollection(Set(1,2)))) + assertTrue(csls.containsAll(Set(1,2).asJavaCollection)) csls.addAll(l) val ts2 = csls.tailSet(3, false) - val l4 = asJavaCollection(Set(4,5)) + val l4 = Set(4,5).asJavaCollection assertTrue(ts2.containsAll(l4)) assertTrue(ts2.removeAll(l4)) assertTrue(ts2.isEmpty) assertEquals(3, csls.size) - assertTrue(csls.containsAll(asJavaCollection(Set(1,2,3)))) + assertTrue(csls.containsAll(Set(1,2,3).asJavaCollection)) csls.addAll(l) val ss1 = csls.subSet(2, true, 3, true) - val l5 = asJavaCollection(Set(2,3)) + val l5 = Set(2,3).asJavaCollection assertTrue(ss1.containsAll(l5)) assertTrue(ss1.removeAll(l5)) assertTrue(ss1.isEmpty) assertEquals(3, csls.size) - assertTrue(csls.containsAll(asJavaCollection(Set(1,4,5)))) + assertTrue(csls.containsAll(Set(1,4,5).asJavaCollection)) csls.addAll(l) @@ -386,7 +386,7 @@ class ConcurrentSkipListSetTest { assertTrue(ss2.removeAll(l5)) assertTrue(ss2.isEmpty) assertEquals(3, csls.size) - assertTrue(csls.containsAll(asJavaCollection(Set(1,4,5)))) + assertTrue(csls.containsAll(Set(1,4,5).asJavaCollection)) } @Test def should_throw_exception_on_non_comparable_objects(): Unit = { diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/CopyOnWriteArrayListTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/CopyOnWriteArrayListTest.scala index 3e92d22103..b4c58153fd 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/CopyOnWriteArrayListTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/CopyOnWriteArrayListTest.scala @@ -14,7 +14,7 @@ import org.junit.Test import org.scalajs.testsuite.javalib.util.{ListFactory, ListTest} -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ import org.scalajs.testsuite.utils.Platform.executingInJVM @@ -44,27 +44,27 @@ class CopyOnWriteArrayListTest extends ListTest { @Test def should_implement_addAllAbsent(): Unit = { val list = factory.empty[Int] - assertEquals(3, list.addAllAbsent(0 until 3)) + assertEquals(3, list.addAllAbsent((0 until 3).asJava)) assertEquals(3, list.size) for (i <- 0 until 3) assertEquals(i, list.get(i)) - assertEquals(0, list.addAllAbsent(0 until 2)) + assertEquals(0, list.addAllAbsent((0 until 2).asJava)) assertEquals(3, list.size) for (i <- 0 until 3) assertEquals(i, list.get(i)) - assertEquals(3, list.addAllAbsent(3 until 6)) + assertEquals(3, list.addAllAbsent((3 until 6).asJava)) assertEquals(6, list.size) for (i <- 0 until 6) assertEquals(i, list.get(i)) - assertEquals(4, list.addAllAbsent(0 until 10)) + assertEquals(4, list.addAllAbsent((0 until 10).asJava)) assertEquals(10, list.size) for (i <- 0 until 10) assertEquals(i, list.get(i)) - assertEquals(1, list.addAllAbsent(Seq(42, 42, 42))) + assertEquals(1, list.addAllAbsent(Seq(42, 42, 42).asJava)) assertEquals(11, list.size) for (i <- 0 until 10) assertEquals(i, list.get(i)) @@ -73,12 +73,12 @@ class CopyOnWriteArrayListTest extends ListTest { @Test def should_implement_a_snapshot_iterator(): Unit = { val list = factory.empty[Int] - list.addAll(0 to 10) + list.addAll((0 to 10).asJava) val iter = list.iterator() list.clear() val iter2 = list.iterator() - list.addAll(0 to 5) + list.addAll((0 to 5).asJava) for (i <- 0 to 10) { assertTrue(iter.hasNext) @@ -91,7 +91,7 @@ class CopyOnWriteArrayListTest extends ListTest { @Test def `should_have_accessible_array_constructor_-_#2023`(): Unit = { def test[T <: AnyRef](arr: Array[T]): Unit = { val cowal1 = factory.newFrom(arr) - assertEquals(arr.length, cowal1.length) + assertEquals(arr.length, cowal1.size) for (i <- arr.indices) assertEquals(arr(i), cowal1.get(i)) } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/utils/CollectionsTestBase.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/utils/CollectionsTestBase.scala index 44287c68ae..6c28f85e39 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/utils/CollectionsTestBase.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/utils/CollectionsTestBase.scala @@ -4,7 +4,7 @@ import java.{lang => jl, util => ju} import org.scalajs.testsuite.utils.AssertThrows._ -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ trait CollectionsTestBase { @@ -29,13 +29,13 @@ trait CollectionsTestBase { def testCollectionUnmodifiability[E](coll: ju.Collection[E], elem: E): Unit = { expectThrows(classOf[UnsupportedOperationException], coll.add(elem)) expectThrows(classOf[UnsupportedOperationException], - coll.addAll(Seq.empty[E])) + coll.addAll(Seq.empty[E].asJava)) expectThrows(classOf[UnsupportedOperationException], coll.clear()) expectThrows(classOf[UnsupportedOperationException], coll.remove(elem)) expectThrows(classOf[UnsupportedOperationException], - coll.removeAll(Seq.empty[E])) + coll.removeAll(Seq.empty[E].asJava)) expectThrows(classOf[UnsupportedOperationException], - coll.retainAll(Seq.empty[E])) + coll.retainAll(Seq.empty[E].asJava)) testIteratorsUnmodifiability(() => coll.iterator()) } @@ -59,7 +59,7 @@ trait CollectionsTestBase { testCollectionUnmodifiability(list, elem) expectThrows(classOf[UnsupportedOperationException], list.add(0, elem)) expectThrows(classOf[UnsupportedOperationException], - list.addAll(0, Seq.empty[E])) + list.addAll(0, Seq.empty[E].asJava)) expectThrows(classOf[UnsupportedOperationException], list.remove(0)) expectThrows(classOf[UnsupportedOperationException], list.set(0, elem)) def testSublist(sl: ju.List[E]): Unit = { @@ -88,7 +88,7 @@ trait CollectionsTestBase { expectThrows(classOf[UnsupportedOperationException], map.clear()) expectThrows(classOf[UnsupportedOperationException], map.put(key, value)) expectThrows(classOf[UnsupportedOperationException], - map.putAll(Map.empty[K, V])) + map.putAll(Map.empty[K, V].asJava)) testSetUnmodifiability(map.entrySet(), new ju.AbstractMap.SimpleImmutableEntry(key, value)) testSetUnmodifiability(map.keySet(), key) From 28e6429b52871233e658883f484ed309964f7839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 10 May 2018 15:32:15 +0200 Subject: [PATCH 0723/2665] Avoid a few compile warnings in the test suite. --- .../scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala | 6 +++--- .../scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index 404ce45b92..45194913b2 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -433,8 +433,8 @@ class ExportsTest { } val foo = (new Foo).asInstanceOf[js.Dynamic] - assertTrue(foo.foo(true).isInstanceOf[Int]) - assertTrue(foo.foo(false).isInstanceOf[A]) + assertTrue((foo.foo(true): Any).isInstanceOf[Int]) + assertTrue((foo.foo(false): Any).isInstanceOf[A]) } @Test def boxed_value_classes_as_parameter(): Unit = { @@ -481,7 +481,7 @@ class ExportsTest { } val c2 = (new C2).asInstanceOf[js.Dynamic] - assertTrue(c2.x.isInstanceOf[B]) + assertTrue((c2.x: Any).isInstanceOf[B]) } @Test def exports_for_methods_with_refined_types_as_return_type(): Unit = { diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala index c07fa0370a..946f4c8d9d 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala @@ -384,8 +384,10 @@ class ScalaJSDefinedTest { @Test def anonymous_class_field_init_order(): Unit = { val obj = new js.Object { - val x = y + val x = getY val y = "Hello World" + + private def getY: String = y }.asInstanceOf[js.Dynamic] assertNull(obj.x) From d25ac41f650c44f57767c5010676f1963dae8f06 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Thu, 10 May 2018 15:40:52 +0200 Subject: [PATCH 0724/2665] Use '\u0000' instead of '\0' because the latter is deprecated. '\0' is in fact an octal escape, which is deprecated. --- .../scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala | 4 ++-- .../org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala | 2 +- .../testsuite/javalib/lang/reflect/ReflectArrayTest.scala | 2 +- .../org/scalajs/testsuite/junit/JUnitAssertionsTest.scala | 2 +- .../org/scalajs/testsuite/scalalib/ArrayBuilderTest.scala | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index 45194913b2..81dfb87ee3 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -1124,7 +1124,7 @@ class ExportsTest { @JSExportAll class Foo { def doBool(x: Boolean): Unit = assertTrue((x: Any) == false) // scalastyle:ignore - def doChar(x: Char): Unit = assertTrue(x.equals('\0')) + def doChar(x: Char): Unit = assertTrue(x.equals('\u0000')) def doByte(x: Byte): Unit = assertEquals(0, x) def doShort(x: Short): Unit = assertEquals(0, x) def doInt(x: Int): Unit = assertEquals(0, x) @@ -1460,7 +1460,7 @@ class ExportsTest { assertEquals(null, TopLevelFieldExports.uninitializedVarString) assertEquals(null, jsPackage.toplevel.uninitializedVarString) - assertEquals('\0', TopLevelFieldExports.uninitializedVarChar) + assertEquals('\u0000', TopLevelFieldExports.uninitializedVarChar) assertEquals(null, jsPackage.toplevel.uninitializedVarChar) } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala index 1ac2abb4ba..f377e4595a 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala @@ -258,7 +258,7 @@ class JSExportStaticTest { JSExportStaticTest.StaticExportFields.uninitializedVarString) assertEquals(null, statics.uninitializedVarString) - assertEquals('\0', + assertEquals('\u0000', JSExportStaticTest.StaticExportFields.uninitializedVarChar) assertEquals(null, statics.uninitializedVarChar) } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/reflect/ReflectArrayTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/reflect/ReflectArrayTest.scala index 7935c20a6d..eb51d94ba3 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/reflect/ReflectArrayTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/reflect/ReflectArrayTest.scala @@ -44,7 +44,7 @@ class ReflectArrayTest { @Test def newInstance(): Unit = { testNewInstance(classOf[Int], classOf[Array[Int]], 0) - testNewInstance(classOf[Char], classOf[Array[Char]], '\0') + testNewInstance(classOf[Char], classOf[Array[Char]], '\u0000') testNewInstance(classOf[Long], classOf[Array[Long]], 0L) testNewInstance(classOf[Boolean], classOf[Array[Boolean]], false) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/junit/JUnitAssertionsTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/junit/JUnitAssertionsTest.scala index 4aa1d5b015..83d5d82b2d 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/junit/JUnitAssertionsTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/junit/JUnitAssertionsTest.scala @@ -149,7 +149,7 @@ class JUnitAssertionsTest { testCharAssertion('a', 'a') testCharAssertion('@', '@') testCharAssertion('\n', '\n') - testCharAssertion('a', '\0', NotEquals) + testCharAssertion('a', '\u0000', NotEquals) testCharAssertion('a', '@', NotEquals) testCharAssertion('a', '\n', NotEquals) } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ArrayBuilderTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ArrayBuilderTest.scala index afd2943346..8cdfbe244d 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ArrayBuilderTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ArrayBuilderTest.scala @@ -115,7 +115,7 @@ class ArrayBuilderTest { assertSame(classOf[Array[Char]], a.getClass) assertEquals(3, a.length) assertTrue(erase(a(0)).isInstanceOf[Char]) - assertEquals('\0', erase(a(0))) + assertEquals('\u0000', erase(a(0))) } @Test def Char_zeros_noinline(): Unit = { @@ -123,7 +123,7 @@ class ArrayBuilderTest { assertSame(classOf[Array[Char]], a.getClass) assertEquals(3, a.length) assertTrue(erase(a(0)).isInstanceOf[Char]) - assertEquals('\0', erase(a(0))) + assertEquals('\u0000', erase(a(0))) } @Test def Boolean_normal_case_inline(): Unit = { From a5f6bfd5e40c2f987fe1342eb30f9a50bf558a9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 10 May 2018 15:56:19 +0200 Subject: [PATCH 0725/2665] Avoid creating trash arrays in newArrayOfPows. In the process, this makes the code compatible with Scala 2.13.0-M4. --- javalib/src/main/scala/java/math/BigDecimal.scala | 2 +- javalib/src/main/scala/java/math/Multiplication.scala | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/javalib/src/main/scala/java/math/BigDecimal.scala b/javalib/src/main/scala/java/math/BigDecimal.scala index e82430a9fe..d77a101836 100644 --- a/javalib/src/main/scala/java/math/BigDecimal.scala +++ b/javalib/src/main/scala/java/math/BigDecimal.scala @@ -195,7 +195,7 @@ object BigDecimal { } private[math] def newArrayOfPows(len: Int, pow: Int): Array[Long] = - new Array[Long](len - 1).scanLeft[Long, Array[Long]](1)((z, e) => z * pow) + Array.iterate(1L, len)(_ * pow) /** Return an increment that can be -1,0 or 1, depending on {@code roundingMode}. * diff --git a/javalib/src/main/scala/java/math/Multiplication.scala b/javalib/src/main/scala/java/math/Multiplication.scala index 21956ab8e8..d4d2d09af7 100644 --- a/javalib/src/main/scala/java/math/Multiplication.scala +++ b/javalib/src/main/scala/java/math/Multiplication.scala @@ -446,6 +446,6 @@ private[math] object Multiplication { } } - private def newArrayOfPows(len: Int, pow: Int) = - new Array[Int](len - 1).scanLeft[Int, Array[Int]](1)((z, _) => z * pow) + private def newArrayOfPows(len: Int, pow: Int): Array[Int] = + Array.iterate(1, len)(_ * pow) } From 3df745ad8b2f2ffb0f54f75a94671ca8929a91fb Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Thu, 10 May 2018 16:01:12 +0200 Subject: [PATCH 0726/2665] Optimize NavigableView.last(). Going through the Scala view is overkill here. In the process, this makes the code compatible with Scala 2.13.0-M4. --- javalib/src/main/scala/java/util/NavigableView.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/javalib/src/main/scala/java/util/NavigableView.scala b/javalib/src/main/scala/java/util/NavigableView.scala index 9bf5febf2e..774a71f176 100644 --- a/javalib/src/main/scala/java/util/NavigableView.scala +++ b/javalib/src/main/scala/java/util/NavigableView.scala @@ -121,8 +121,10 @@ private[util] class NavigableView[E](original: NavigableSet[E], def last(): E = { val iter = iterator() - if (iter.hasNext) iter.asScala.toTraversable.last - else null.asInstanceOf[E] + var result = null.asInstanceOf[E] + while (iter.hasNext) + result = iter.next() + result } def subSet(fromElement: E, fromInclusive: Boolean, toElement: E, From fa622cad6b3470d35be6224aff395f4c17252977 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Thu, 10 May 2018 16:05:55 +0200 Subject: [PATCH 0727/2665] Remove a useless .toIterator. In the process, this makes the code compatible with Scala 2.13.0-M4. --- javalib/src/main/scala/java/util/Properties.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javalib/src/main/scala/java/util/Properties.scala b/javalib/src/main/scala/java/util/Properties.scala index f07055906a..416a1ebf15 100644 --- a/javalib/src/main/scala/java/util/Properties.scala +++ b/javalib/src/main/scala/java/util/Properties.scala @@ -37,7 +37,7 @@ class Properties(protected val defaults: Properties) def propertyNames(): ju.Enumeration[_] = { val thisSet = keySet().asScala.map(_.asInstanceOf[String]) val defaultsIterator = - if (defaults != null) defaults.propertyNames().asScala.toIterator + if (defaults != null) defaults.propertyNames().asScala else scala.collection.Iterator.empty val filteredDefaults = defaultsIterator.collect { case k: String if !thisSet(k) => k From 19418aa821e80031a4c2470f47b14c2189aaee34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 10 May 2018 16:40:15 +0200 Subject: [PATCH 0728/2665] Better lookup for the first framework that can be loaded. Iterators are lower-overhead than Streams, and their `map` and `collectFirst` methods are well-optimized, so overall this should be better. Streams will be deprecated in 2.13.0-M4, so we need to move away from them anyway. --- .../main/scala/org/scalajs/testinterface/TestDetector.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala b/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala index d9018cdcf6..894085439c 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala @@ -53,7 +53,9 @@ private[scalajs] object TestDetector { def tryLoad(name: String): Option[Framework] = tryLoadFromReflect(name).orElse(tryLoadFromExportsNamespace(name)) - names.toStream.map(tryLoad).flatten.headOption + names.iterator.map(tryLoad).collectFirst { + case Some(framework) => framework + } } // Copied from sbt.TestFramework From 95469e167b70adecee382b75a77ce916e95a34ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 10 May 2018 19:03:22 +0200 Subject: [PATCH 0729/2665] Use `@JSExportStatic` to define the static methods of `MockPromise`. When `MockPromise` was created, `@JSExportStatic` did not exist yet, so we had to resort to imperatively creating its static methods. We can now use `@JSExportStatic` instead, which is so much nicer. In the process, this makes the code compatible with Scala 2.13.0-M4. --- .../testsuite/jsinterop/PromiseMock.scala | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PromiseMock.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PromiseMock.scala index b431ac112c..49631fcd85 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PromiseMock.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PromiseMock.scala @@ -9,8 +9,6 @@ import js.Thenable object PromiseMock { import js.Dynamic.global - MockPromise.initMockPromiseStaticMethods() - @noinline def withMockedPromise[A](body: (() => Unit) => A): A = { val oldPromise = @@ -48,15 +46,8 @@ object PromiseMock { private object MockPromise { private val queue = js.Array[js.Function0[Any]]() - def initMockPromiseStaticMethods(): Unit = { - val ctor = js.constructorOf[MockPromise[_]] - ctor.resolve = resolve _ - ctor.reject = reject _ - // Not implemented: `all` and `race` - } - - // static - private def resolve[A](value: A | js.Thenable[A]): MockPromise[A] = { + @JSExportStatic + def resolve[A](value: A | js.Thenable[A]): MockPromise[A] = { new MockPromise[A]({ (resolve: js.Function1[A | js.Thenable[A], _], reject: js.Function1[Any, _]) => @@ -64,8 +55,8 @@ object PromiseMock { }) } - // static - private def reject(reason: Any): MockPromise[Nothing] = { + @JSExportStatic + def reject(reason: Any): MockPromise[Nothing] = { new MockPromise[Nothing]({ (resolve: js.Function1[Nothing | js.Thenable[Nothing], _], reject: js.Function1[Any, _]) => From 9575e02ef234160c84ca123df3a24d5195d6d98e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 11 May 2018 12:09:24 +0200 Subject: [PATCH 0730/2665] Fix the reported JS names in conflicting overloads messages for good. We were previously guessing the JS name to display based on the symbol's name. We tried fixing it in 59eb62cf85701385a1a73af7a5ee198091a13703, but that was not good enough. In general, for exports, there is no correct answer to be found. This is pretty obvious once we take into account the fact that a method can be exported several times under different names. Therefore, in this commit, we stop trying to guess the name, and instead pass it down from the point where we actually know the JS name for which overload resolution could not be solved. --- .../scalajs/core/compiler/GenJSExports.scala | 37 ++++++++----------- .../core/compiler/test/JSExportTest.scala | 8 ++-- 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index 2ecf289d78..403e697a29 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -388,9 +388,9 @@ trait GenJSExports extends SubComponent { self: GenJSCode => None } else { val arg = genFormalArg(1) - val body = genExportSameArgc(minArgc = 1, hasRestParam = false, - alts = setters.map(ExportedSymbol), paramIndex = 0, - static = static) + val body = genExportSameArgc(jsName, minArgc = 1, + hasRestParam = false, alts = setters.map(ExportedSymbol), + paramIndex = 0, static = static) Some((arg, body)) } } @@ -492,9 +492,8 @@ trait GenJSExports extends SubComponent { self: GenJSCode => if methods != varArgMeths.toSet // body of case to disambiguates methods with current count - caseBody = - genExportSameArgc(minArgc, needsRestParam, - methods.toList, paramIndex = 0, static, Some(argcs.min)) + caseBody = genExportSameArgc(jsName, minArgc, needsRestParam, + methods.toList, paramIndex = 0, static, Some(argcs.min)) // argc in reverse order argcList = argcs.toList.sortBy(- _) @@ -504,7 +503,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => if (!hasVarArg) { genThrowTypeError() } else { - genExportSameArgc(minArgc, needsRestParam, varArgMeths, + genExportSameArgc(jsName, minArgc, needsRestParam, varArgMeths, paramIndex = 0, static = static) } } @@ -538,9 +537,9 @@ trait GenJSExports extends SubComponent { self: GenJSCode => * @param paramIndex Index where to start disambiguation * @param maxArgc only use that many arguments */ - private def genExportSameArgc(minArgc: Int, hasRestParam: Boolean, - alts: List[Exported], paramIndex: Int, static: Boolean, - maxArgc: Option[Int] = None): js.Tree = { + private def genExportSameArgc(jsName: JSName, minArgc: Int, + hasRestParam: Boolean, alts: List[Exported], paramIndex: Int, + static: Boolean, maxArgc: Option[Int] = None): js.Tree = { implicit val pos = alts.head.pos @@ -553,7 +552,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => // 2. The optional argument count restriction has triggered // 3. We only have (more than once) repeated parameters left // Therefore, we should fail - reportCannotDisambiguateError(alts) + reportCannotDisambiguateError(jsName, alts) js.Undefined() } else { val altsByTypeTest = groupByWithoutHashCode(alts) { @@ -566,7 +565,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => if (altsByTypeTest.size == 1) { // Testing this parameter is not doing any us good - genExportSameArgc(minArgc, hasRestParam, alts, + genExportSameArgc(jsName, minArgc, hasRestParam, alts, paramIndex+1, static, maxArgc) } else { // Sort them so that, e.g., isInstanceOf[String] @@ -581,7 +580,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => implicit val pos = subAlts.head.pos val paramRef = genFormalArgRef(paramIndex+1, minArgc) - val genSubAlts = genExportSameArgc(minArgc, hasRestParam, + val genSubAlts = genExportSameArgc(jsName, minArgc, hasRestParam, subAlts, paramIndex+1, static, maxArgc) def hasDefaultParam = subAlts.exists { @@ -618,7 +617,8 @@ trait GenJSExports extends SubComponent { self: GenJSCode => } } - private def reportCannotDisambiguateError(alts: List[Exported]): Unit = { + private def reportCannotDisambiguateError(jsName: JSName, + alts: List[Exported]): Unit = { val currentClass = currentClassSym.get /* Find a position that is in the current class for decent error reporting. @@ -638,11 +638,11 @@ trait GenJSExports extends SubComponent { self: GenJSCode => if (isScalaJSDefinedJSClass(currentClass)) "method" else "exported method" - val name = alts.head.name + val displayName = jsName.displayName val altsTypesInfo = alts.map(_.typeInfo).mkString("\n ") reporter.error(pos, - s"Cannot disambiguate overloads for $kind $name with types\n" + + s"Cannot disambiguate overloads for $kind $displayName with types\n" + s" $altsTypesInfo") } @@ -889,7 +889,6 @@ trait GenJSExports extends SubComponent { self: GenJSCode => def pos: Position def params: List[Type] def genBody(minArgc: Int, hasRestParam: Boolean, static: Boolean): js.Tree - def name: String def typeInfo: String def hasRepeatedParam: Boolean } @@ -901,10 +900,6 @@ trait GenJSExports extends SubComponent { self: GenJSCode => def genBody(minArgc: Int, hasRestParam: Boolean, static: Boolean): js.Tree = genApplyForSym(minArgc, hasRestParam, sym, static) - def name: String = - if (isRawJSType(sym.owner.toTypeConstructor)) jsNameOf(sym).displayName - else sym.name.toString - def typeInfo: String = sym.tpe.toString def hasRepeatedParam: Boolean = GenJSExports.this.hasRepeatedParam(sym) } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index 69f27c03a0..1e0ff24203 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -157,7 +157,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:7: error: Cannot disambiguate overloads for exported method $js$exported$meth$foo with types + |newSource1.scala:7: error: Cannot disambiguate overloads for exported method foo with types | (x: Seq)Object | (x: Int, ys: Seq)Object | @JSExport @@ -173,7 +173,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:6: error: Cannot disambiguate overloads for exported method $js$exported$meth$foo with types + |newSource1.scala:6: error: Cannot disambiguate overloads for exported method foo with types | (x: Int)Object | (x: Seq)Object | @JSExport @@ -1515,7 +1515,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:10: error: Cannot disambiguate overloads for exported method bar with types + |newSource1.scala:10: error: Cannot disambiguate overloads for exported method foo with types | (x: Int)Int | (x: Int)Int | def bar(x: Int): Int = x + 1 @@ -1557,7 +1557,7 @@ class JSExportTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:10: error: Cannot disambiguate overloads for exported method bar_$eq with types + |newSource1.scala:10: error: Cannot disambiguate overloads for exported method foo with types | (v: Int)Unit | (v: Int)Unit | def bar_=(v: Int): Unit = () From bdd162823655a2136898b69fdaf82bc2a089ab86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 11 May 2018 14:11:44 +0200 Subject: [PATCH 0731/2665] Stop using procedure syntax in our examples. Procedure syntax will be deprecated in 2.13.0-M4. We had already stopped using it everywhere else, but not in the examples. --- examples/helloworld/HelloWorld.scala | 10 +++++----- examples/reversi/Reversi.scala | 18 +++++++++--------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/examples/helloworld/HelloWorld.scala b/examples/helloworld/HelloWorld.scala index 2fbf2c4f6f..a79919685c 100644 --- a/examples/helloworld/HelloWorld.scala +++ b/examples/helloworld/HelloWorld.scala @@ -9,7 +9,7 @@ import scala.scalajs.js import js.annotation._ object HelloWorld extends js.JSApp { - def main() { + def main(): Unit = { import js.DynamicImplicits.truthValue if (js.Dynamic.global.document && @@ -23,7 +23,7 @@ object HelloWorld extends js.JSApp { } } - def sayHelloFromDOM() { + def sayHelloFromDOM(): Unit = { val document = js.Dynamic.global.document val playground = document.getElementById("playground") @@ -32,7 +32,7 @@ object HelloWorld extends js.JSApp { playground.appendChild(newP) } - def sayHelloFromTypedDOM() { + def sayHelloFromTypedDOM(): Unit = { val document = window.document val playground = document.getElementById("playground") @@ -41,14 +41,14 @@ object HelloWorld extends js.JSApp { playground.appendChild(newP) } - def sayHelloFromJQuery() { + def sayHelloFromJQuery(): Unit = { // val $ is fine too, but not very recommended in Scala code val jQuery = js.Dynamic.global.jQuery val newP = jQuery("

").html("Hello world! -- jQuery") newP.appendTo(jQuery("#playground")) } - def sayHelloFromTypedJQuery() { + def sayHelloFromTypedJQuery(): Unit = { val jQuery = helloworld.JQuery val newP = jQuery("

").html("Hello world! -- typed jQuery") newP.appendTo(jQuery("#playground")) diff --git a/examples/reversi/Reversi.scala b/examples/reversi/Reversi.scala index 14cd819440..36693de3cd 100644 --- a/examples/reversi/Reversi.scala +++ b/examples/reversi/Reversi.scala @@ -41,7 +41,7 @@ class Reversi(jQuery: JQueryStatic, playground: JQuery) { var onOwnerChange: (OptPlayer, OptPlayer) => Unit = (oldP, newP) => () def owner = _owner - def owner_=(value: OptPlayer) { + def owner_=(value: OptPlayer): Unit = { val previous = _owner if (value != previous) { _owner = value @@ -79,7 +79,7 @@ class Reversi(jQuery: JQueryStatic, playground: JQuery) { jQuery("") } - def buildUI() { + def buildUI(): Unit = { // Some dimensions val SquareSizePx = 48 val HalfSquareSizePx = SquareSizePx/2 @@ -95,7 +95,7 @@ class Reversi(jQuery: JQueryStatic, playground: JQuery) { playground.append(jQuery("

").append(boardCanvas)) /** Draw the specified square on the board canvas */ - def drawSquare(square: Square) { + def drawSquare(square: Square): Unit = { val x = square.x * SquareSizePx val y = square.y * SquareSizePx @@ -147,12 +147,12 @@ class Reversi(jQuery: JQueryStatic, playground: JQuery) { // The Game ------------------------------------------------------------------ - def reset() { + def reset(): Unit = { startGame() } @JSExport - def startGame() { + def startGame(): Unit = { // Set up the board allSquares foreach (_.owner = NoPlayer) board(3)(3).owner = White @@ -167,7 +167,7 @@ class Reversi(jQuery: JQueryStatic, playground: JQuery) { startTurn() } - def startTurn() { + def startTurn(): Unit = { val (scoreWhite, scoreBlack) = computeScore() status.text(currentPlayer+"'s turn -- White: "+scoreWhite+ " -- Black: "+scoreBlack) @@ -194,7 +194,7 @@ class Reversi(jQuery: JQueryStatic, playground: JQuery) { } } - def clickSquare(square: Square) { + def clickSquare(square: Square): Unit = { val toFlip = computeFlips(square) if (!toFlip.isEmpty) { (square :: toFlip) foreach (_.owner = currentPlayer) @@ -202,7 +202,7 @@ class Reversi(jQuery: JQueryStatic, playground: JQuery) { } } - def pass() { + def pass(): Unit = { assert(!existsValidMove()) nextTurn() } @@ -259,7 +259,7 @@ class Reversi(jQuery: JQueryStatic, playground: JQuery) { } } - def nextTurn() { + def nextTurn(): Unit = { currentPlayer = currentPlayer.opponent startTurn() } From 3f88df139e57ffe4f3520c9c4229181612ab7bb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 11 May 2018 18:13:46 +0200 Subject: [PATCH 0732/2665] Sort the signatures in ambiguous overloads for stable error messages. --- .../src/main/scala/org/scalajs/core/compiler/GenJSExports.scala | 2 +- .../scala/org/scalajs/core/compiler/test/JSExportTest.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index 403e697a29..371279f45e 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -639,7 +639,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => else "exported method" val displayName = jsName.displayName - val altsTypesInfo = alts.map(_.typeInfo).mkString("\n ") + val altsTypesInfo = alts.map(_.typeInfo).sorted.mkString("\n ") reporter.error(pos, s"Cannot disambiguate overloads for $kind $displayName with types\n" + diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index 1e0ff24203..57c5e8281c 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -158,8 +158,8 @@ class JSExportTest extends DirectTest with TestHelpers { """ hasErrors """ |newSource1.scala:7: error: Cannot disambiguate overloads for exported method foo with types - | (x: Seq)Object | (x: Int, ys: Seq)Object + | (x: Seq)Object | @JSExport | ^ """ From 4665746f9d42a3f356c731fefef1916c89202a2c Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 31 Mar 2018 09:20:11 +0200 Subject: [PATCH 0733/2665] Remove VirtualFileMaterializer It's usage was minimal and the API is too specific. With NIO's Files, the behavior can be easily replicated if necessary. As a side effect, this removes a usage of VirtualFile#name. --- .../jsenv/VirtualFileMaterializer.scala | 91 ------------------- .../testadapter/HTMLRunnerBuilder.scala | 64 ++++++++----- 2 files changed, 42 insertions(+), 113 deletions(-) delete mode 100644 js-envs/src/main/scala/org/scalajs/jsenv/VirtualFileMaterializer.scala diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/VirtualFileMaterializer.scala b/js-envs/src/main/scala/org/scalajs/jsenv/VirtualFileMaterializer.scala deleted file mode 100644 index 604f2dff30..0000000000 --- a/js-envs/src/main/scala/org/scalajs/jsenv/VirtualFileMaterializer.scala +++ /dev/null @@ -1,91 +0,0 @@ -package org.scalajs.jsenv - -import scala.annotation.tailrec - -import org.scalajs.io._ - -import java.io.File - -/** A helper class to temporarily store virtual files to the filesystem. - * - * Can be used with tools that require real files. - * @param singleDir if true, forces files to be copied into - * [[cacheDir]]. Useful to setup include directories for - * example. - */ -final class VirtualFileMaterializer(singleDir: Boolean = false) { - import VirtualFileMaterializer._ - - val cacheDir = { - val dir = createTempDir() - dir.deleteOnExit() - dir - } - - /** Create a target file to write/copy to. Will also call - * deleteOnExit on the file. - */ - private def trgFile(name: String): File = { - val f = new File(cacheDir, name) - f.deleteOnExit() - f - } - - def materialize(vf: VirtualTextFile): File = vf match { - case vf: FileVirtualFile if !singleDir => - vf.file - case _ => - val trg = trgFile(vf.name) - IO.copyTo(vf, WritableFileVirtualTextFile(trg)) - trg - } - - def materialize(vf: VirtualBinaryFile): File = vf match { - case vf: FileVirtualFile if !singleDir => - vf.file - case _ => - val trg = trgFile(vf.name) - IO.copyTo(vf, WritableFileVirtualBinaryFile(trg)) - trg - } - - /** Removes the cache directory. Any operation on this - * VirtualFileMaterializer is invalid after [[close]] has been - * called. - */ - def close(): Unit = { - cacheDir.listFiles().foreach(_.delete) - cacheDir.delete() - } - - // scalastyle:off line.size.limit - /* Taken from Guava: - * https://github.com/google/guava/blob/1c285fc8d289c43b46aa55e7f90ec0359be5b69a/guava/src/com/google/common/io/Files.java#L413-L426 - */ - // scalastyle:on line.size.limit - private def createTempDir(): File = { - val baseDir = new File(System.getProperty("java.io.tmpdir")) - val baseName = System.currentTimeMillis() + "-" - - @tailrec - def loop(tries: Int): File = { - val tempDir = new File(baseDir, baseName + tries) - if (tempDir.mkdir()) - tempDir - else if (tries < TempDirAttempts) - loop(tries + 1) - else { - throw new IllegalStateException("Failed to create directory within " + - s"$TempDirAttempts attempts (tried ${baseName}0 to " + - s"${baseName}${TempDirAttempts - 1})") - } - } - - loop(0) - } - -} - -private object VirtualFileMaterializer { - private final val TempDirAttempts = 10000 -} diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala index 5f30b163ae..c26bc75473 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala @@ -9,53 +9,73 @@ package org.scalajs.testadapter -import java.io.File +import scala.collection.JavaConverters._ + +import java.io.{File, InputStream} import java.net.URI +import java.nio.charset.StandardCharsets +import java.nio.file.{Files, StandardCopyOption} import sbt.testing.{Framework, TaskDef} import org.scalajs.io._ import org.scalajs.io.JSUtils.escapeJS -import org.scalajs.jsenv.VirtualFileMaterializer - import org.scalajs.testcommon._ /** Template for the HTML runner. */ object HTMLRunnerBuilder { - private val cssFile: MemVirtualTextFile = { + private val tmpSuffixRE = """[a-zA-Z0-9-_.]*$""".r + + private def tmpFile(path: String): File = { + /* - createTempFile requires a prefix of at least 3 chars + * - we use a safe part of the path as suffix so the extension stays (some + * browsers need that) and there is a clue which file it came from. + */ + val suffix = tmpSuffixRE.findFirstIn(path).orNull + + val f = File.createTempFile("tmp-", suffix) + f.deleteOnExit() + f + } + + private def loadCSSURI(): URI = { val name = "test-runner.css" - val inputStream = getClass.getResourceAsStream(name) - val content = try { - IO.readInputStreamToString(inputStream) + val f = tmpFile(name) + + val s = getClass.getResourceAsStream(name) + try { + Files.copy(s, f.toPath(), StandardCopyOption.REPLACE_EXISTING) } finally { - inputStream.close() + s.close() + } + f.toURI() + } + + private def loadJSFiles(jsFiles: Seq[VirtualJSFile]): Seq[URI] = { + jsFiles.map { + case file: FileVirtualFile => file.file.toURI + + case file => + val f = tmpFile(file.path) + IO.copyTo(file, WritableFileVirtualTextFile(f)) + f.toURI } - new MemVirtualTextFile(name).withContent(content) } def writeToFile(output: File, title: String, jsFiles: Seq[VirtualJSFile], frameworkImplClassNames: List[List[String]], taskDefs: List[TaskDef]): Unit = { - val jsFileCache = new VirtualFileMaterializer(true) - val jsFileURIs = jsFiles.map { - case file: FileVirtualFile => file.file.toURI - case file => jsFileCache.materialize(file).toURI - } - val cssFileURI = jsFileCache.materialize(cssFile).toURI + val jsFileURIs = loadJSFiles(jsFiles) + val cssURI = loadCSSURI() val tests = new IsolatedTestSet(frameworkImplClassNames, taskDefs) - val htmlContent = render(output.toURI, title, jsFileURIs, cssFileURI, tests) + val htmlContent = render(output.toURI, title, jsFileURIs, cssURI, tests) - val outputWriter = WritableFileVirtualTextFile(output).contentWriter - try { - outputWriter.write(htmlContent) - } finally { - outputWriter.close() - } + Files.write(output.toPath, List(htmlContent).asJava, StandardCharsets.UTF_8) } private def render(baseURI: URI, title: String, jsFiles: Seq[URI], From a95d9962fa128764fe1e0a1fab7cfbd358d6fb07 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 31 Mar 2018 09:34:20 +0200 Subject: [PATCH 0734/2665] Make SourceMapWriter private[javascript] --- .../org/scalajs/linker/backend/javascript/SourceMapWriter.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/SourceMapWriter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/SourceMapWriter.scala index 906bad4083..e76f1f00a8 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/SourceMapWriter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/SourceMapWriter.scala @@ -72,7 +72,7 @@ private object SourceMapWriter { } } -class SourceMapWriter( +private[javascript] class SourceMapWriter( val out: Writer, val generatedFile: String, val relativizeBaseURI: Option[URI] = None) { From f43094b2c6bc16e722afad9662957c2b614d0898 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Tue, 24 Apr 2018 10:00:03 +0200 Subject: [PATCH 0735/2665] Copy some existing overrides to an overrides-2.13.0-M3 directory. In the next commits, the overrides-2.13 directory will contain overrides for 2.13.0-M4+. This commit copies existing overrides to an overrides-2.13.0-M3 directory so that they have a higher precedence over the overrides of the overrides-2.13 directory. Files scala/Array.scala and scala/Enumeration.scala have been copied without changes from the general overrides/ directory. All the other files have been copied from the overrides-2.13/ directory. --- .../overrides-2.13.0-M3/scala/Array.scala | 550 +++++++++++++ .../scala/Enumeration.scala | 284 +++++++ .../collection/immutable/NumericRange.scala | 375 +++++++++ .../scala/collection/immutable/Range.scala | 527 +++++++++++++ .../collection/mutable/ArrayBuilder.scala | 735 ++++++++++++++++++ .../scala/collection/mutable/Buffer.scala | 51 ++ .../overrides-2.13.0-M3/scala/package.scala | 133 ++++ .../scala/runtime/ScalaRunTime.scala | 268 +++++++ 8 files changed, 2923 insertions(+) create mode 100644 scalalib/overrides-2.13.0-M3/scala/Array.scala create mode 100644 scalalib/overrides-2.13.0-M3/scala/Enumeration.scala create mode 100644 scalalib/overrides-2.13.0-M3/scala/collection/immutable/NumericRange.scala create mode 100644 scalalib/overrides-2.13.0-M3/scala/collection/immutable/Range.scala create mode 100644 scalalib/overrides-2.13.0-M3/scala/collection/mutable/ArrayBuilder.scala create mode 100644 scalalib/overrides-2.13.0-M3/scala/collection/mutable/Buffer.scala create mode 100644 scalalib/overrides-2.13.0-M3/scala/package.scala create mode 100644 scalalib/overrides-2.13.0-M3/scala/runtime/ScalaRunTime.scala diff --git a/scalalib/overrides-2.13.0-M3/scala/Array.scala b/scalalib/overrides-2.13.0-M3/scala/Array.scala new file mode 100644 index 0000000000..22cace2c7a --- /dev/null +++ b/scalalib/overrides-2.13.0-M3/scala/Array.scala @@ -0,0 +1,550 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala + +import scala.collection.generic._ +import scala.collection.{ mutable, immutable } +import mutable.{ ArrayBuilder, ArraySeq } +import java.lang.System.arraycopy +import scala.reflect.ClassTag +import scala.runtime.ScalaRunTime.{ array_apply, array_update } + +/** Contains a fallback builder for arrays when the element type + * does not have a class tag. In that case a generic array is built. + */ +class FallbackArrayBuilding { + + /** A builder factory that generates a generic array. + * Called instead of `Array.newBuilder` if the element type of an array + * does not have a class tag. Note that fallbackBuilder factory + * needs an implicit parameter (otherwise it would not be dominated in + * implicit search by `Array.canBuildFrom`). We make sure that + * implicit search is always successful. + */ + implicit def fallbackCanBuildFrom[T](implicit m: DummyImplicit): CanBuildFrom[Array[_], T, ArraySeq[T]] = + new CanBuildFrom[Array[_], T, ArraySeq[T]] { + def apply(from: Array[_]) = ArraySeq.newBuilder[T] + def apply() = ArraySeq.newBuilder[T] + } +} + +/** Utility methods for operating on arrays. + * For example: + * {{{ + * val a = Array(1, 2) + * val b = Array.ofDim[Int](2) + * val c = Array.concat(a, b) + * }}} + * where the array objects `a`, `b` and `c` have respectively the values + * `Array(1, 2)`, `Array(0, 0)` and `Array(1, 2, 0, 0)`. + * + * @author Martin Odersky + * @version 1.0 + */ +object Array extends FallbackArrayBuilding { + def emptyBooleanArray = EmptyArrays.emptyBooleanArray + def emptyByteArray = EmptyArrays.emptyByteArray + def emptyCharArray = EmptyArrays.emptyCharArray + def emptyDoubleArray = EmptyArrays.emptyDoubleArray + def emptyFloatArray = EmptyArrays.emptyFloatArray + def emptyIntArray = EmptyArrays.emptyIntArray + def emptyLongArray = EmptyArrays.emptyLongArray + def emptyShortArray = EmptyArrays.emptyShortArray + def emptyObjectArray = EmptyArrays.emptyObjectArray + + private object EmptyArrays { + val emptyBooleanArray = new Array[Boolean](0) + val emptyByteArray = new Array[Byte](0) + val emptyCharArray = new Array[Char](0) + val emptyDoubleArray = new Array[Double](0) + val emptyFloatArray = new Array[Float](0) + val emptyIntArray = new Array[Int](0) + val emptyLongArray = new Array[Long](0) + val emptyShortArray = new Array[Short](0) + val emptyObjectArray = new Array[Object](0) + } + + implicit def canBuildFrom[T](implicit t: ClassTag[T]): CanBuildFrom[Array[_], T, Array[T]] = { + @inline + class ArrayCanBuildFrom extends CanBuildFrom[Array[_], T, Array[T]] { + def apply(from: Array[_]) = ArrayBuilder.make[T]()(t) + def apply() = ArrayBuilder.make[T]()(t) + } + new ArrayCanBuildFrom + } + + /** + * Returns a new [[scala.collection.mutable.ArrayBuilder]]. + */ + def newBuilder[T](implicit t: ClassTag[T]): ArrayBuilder[T] = ArrayBuilder.make[T]()(t) + + private def slowcopy(src : AnyRef, + srcPos : Int, + dest : AnyRef, + destPos : Int, + length : Int) { + var i = srcPos + var j = destPos + val srcUntil = srcPos + length + while (i < srcUntil) { + array_update(dest, j, array_apply(src, i)) + i += 1 + j += 1 + } + } + + /** Copy one array to another. + * Equivalent to Java's + * `System.arraycopy(src, srcPos, dest, destPos, length)`, + * except that this also works for polymorphic and boxed arrays. + * + * Note that the passed-in `dest` array will be modified by this call. + * + * @param src the source array. + * @param srcPos starting position in the source array. + * @param dest destination array. + * @param destPos starting position in the destination array. + * @param length the number of array elements to be copied. + * + * @see `java.lang.System#arraycopy` + */ + def copy(src: AnyRef, srcPos: Int, dest: AnyRef, destPos: Int, length: Int) { + val srcClass = src.getClass + if (srcClass.isArray && dest.getClass.isAssignableFrom(srcClass)) + arraycopy(src, srcPos, dest, destPos, length) + else + slowcopy(src, srcPos, dest, destPos, length) + } + + /** Returns an array of length 0 */ + def empty[T: ClassTag]: Array[T] = new Array[T](0) + + /** Creates an array with given elements. + * + * @param xs the elements to put in the array + * @return an array containing all elements from xs. + */ + // Subject to a compiler optimization in Cleanup. + // Array(e0, ..., en) is translated to { val a = new Array(3); a(i) = ei; a } + def apply[T: ClassTag](xs: T*): Array[T] = { + val array = new Array[T](xs.length) + var i = 0 + for (x <- xs.iterator) { array(i) = x; i += 1 } + array + } + + /** Creates an array of `Boolean` objects */ + // Subject to a compiler optimization in Cleanup, see above. + def apply(x: Boolean, xs: Boolean*): Array[Boolean] = { + val array = new Array[Boolean](xs.length + 1) + array(0) = x + var i = 1 + for (x <- xs.iterator) { array(i) = x; i += 1 } + array + } + + /** Creates an array of `Byte` objects */ + // Subject to a compiler optimization in Cleanup, see above. + def apply(x: Byte, xs: Byte*): Array[Byte] = { + val array = new Array[Byte](xs.length + 1) + array(0) = x + var i = 1 + for (x <- xs.iterator) { array(i) = x; i += 1 } + array + } + + /** Creates an array of `Short` objects */ + // Subject to a compiler optimization in Cleanup, see above. + def apply(x: Short, xs: Short*): Array[Short] = { + val array = new Array[Short](xs.length + 1) + array(0) = x + var i = 1 + for (x <- xs.iterator) { array(i) = x; i += 1 } + array + } + + /** Creates an array of `Char` objects */ + // Subject to a compiler optimization in Cleanup, see above. + def apply(x: Char, xs: Char*): Array[Char] = { + val array = new Array[Char](xs.length + 1) + array(0) = x + var i = 1 + for (x <- xs.iterator) { array(i) = x; i += 1 } + array + } + + /** Creates an array of `Int` objects */ + // Subject to a compiler optimization in Cleanup, see above. + def apply(x: Int, xs: Int*): Array[Int] = { + val array = new Array[Int](xs.length + 1) + array(0) = x + var i = 1 + for (x <- xs.iterator) { array(i) = x; i += 1 } + array + } + + /** Creates an array of `Long` objects */ + // Subject to a compiler optimization in Cleanup, see above. + def apply(x: Long, xs: Long*): Array[Long] = { + val array = new Array[Long](xs.length + 1) + array(0) = x + var i = 1 + for (x <- xs.iterator) { array(i) = x; i += 1 } + array + } + + /** Creates an array of `Float` objects */ + // Subject to a compiler optimization in Cleanup, see above. + def apply(x: Float, xs: Float*): Array[Float] = { + val array = new Array[Float](xs.length + 1) + array(0) = x + var i = 1 + for (x <- xs.iterator) { array(i) = x; i += 1 } + array + } + + /** Creates an array of `Double` objects */ + // Subject to a compiler optimization in Cleanup, see above. + def apply(x: Double, xs: Double*): Array[Double] = { + val array = new Array[Double](xs.length + 1) + array(0) = x + var i = 1 + for (x <- xs.iterator) { array(i) = x; i += 1 } + array + } + + /** Creates an array of `Unit` objects */ + def apply(x: Unit, xs: Unit*): Array[Unit] = { + val array = new Array[Unit](xs.length + 1) + array(0) = x + var i = 1 + for (x <- xs.iterator) { array(i) = x; i += 1 } + array + } + + /** Creates array with given dimensions */ + def ofDim[T: ClassTag](n1: Int): Array[T] = + new Array[T](n1) + /** Creates a 2-dimensional array */ + def ofDim[T: ClassTag](n1: Int, n2: Int): Array[Array[T]] = { + val arr: Array[Array[T]] = (new Array[Array[T]](n1): Array[Array[T]]) + for (i <- 0 until n1) arr(i) = new Array[T](n2) + arr + // tabulate(n1)(_ => ofDim[T](n2)) + } + /** Creates a 3-dimensional array */ + def ofDim[T: ClassTag](n1: Int, n2: Int, n3: Int): Array[Array[Array[T]]] = + tabulate(n1)(_ => ofDim[T](n2, n3)) + /** Creates a 4-dimensional array */ + def ofDim[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int): Array[Array[Array[Array[T]]]] = + tabulate(n1)(_ => ofDim[T](n2, n3, n4)) + /** Creates a 5-dimensional array */ + def ofDim[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int): Array[Array[Array[Array[Array[T]]]]] = + tabulate(n1)(_ => ofDim[T](n2, n3, n4, n5)) + + /** Concatenates all arrays into a single array. + * + * @param xss the given arrays + * @return the array created from concatenating `xss` + */ + def concat[T: ClassTag](xss: Array[T]*): Array[T] = { + val b = newBuilder[T] + b.sizeHint(xss.map(_.length).sum) + for (xs <- xss) b ++= xs + b.result() + } + + /** Returns an array that contains the results of some element computation a number + * of times. + * + * Note that this means that `elem` is computed a total of n times: + * {{{ + * scala> Array.fill(3){ math.random } + * res3: Array[Double] = Array(0.365461167592537, 1.550395944913685E-4, 0.7907242137333306) + * }}} + * + * @param n the number of elements desired + * @param elem the element computation + * @return an Array of size n, where each element contains the result of computing + * `elem`. + */ + def fill[T: ClassTag](n: Int)(elem: => T): Array[T] = { + val b = newBuilder[T] + b.sizeHint(n) + var i = 0 + while (i < n) { + b += elem + i += 1 + } + b.result() + } + + /** Returns a two-dimensional array that contains the results of some element + * computation a number of times. + * + * @param n1 the number of elements in the 1st dimension + * @param n2 the number of elements in the 2nd dimension + * @param elem the element computation + */ + def fill[T: ClassTag](n1: Int, n2: Int)(elem: => T): Array[Array[T]] = + tabulate(n1)(_ => fill(n2)(elem)) + + /** Returns a three-dimensional array that contains the results of some element + * computation a number of times. + * + * @param n1 the number of elements in the 1st dimension + * @param n2 the number of elements in the 2nd dimension + * @param n3 the number of elements in the 3nd dimension + * @param elem the element computation + */ + def fill[T: ClassTag](n1: Int, n2: Int, n3: Int)(elem: => T): Array[Array[Array[T]]] = + tabulate(n1)(_ => fill(n2, n3)(elem)) + + /** Returns a four-dimensional array that contains the results of some element + * computation a number of times. + * + * @param n1 the number of elements in the 1st dimension + * @param n2 the number of elements in the 2nd dimension + * @param n3 the number of elements in the 3nd dimension + * @param n4 the number of elements in the 4th dimension + * @param elem the element computation + */ + def fill[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int)(elem: => T): Array[Array[Array[Array[T]]]] = + tabulate(n1)(_ => fill(n2, n3, n4)(elem)) + + /** Returns a five-dimensional array that contains the results of some element + * computation a number of times. + * + * @param n1 the number of elements in the 1st dimension + * @param n2 the number of elements in the 2nd dimension + * @param n3 the number of elements in the 3nd dimension + * @param n4 the number of elements in the 4th dimension + * @param n5 the number of elements in the 5th dimension + * @param elem the element computation + */ + def fill[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(elem: => T): Array[Array[Array[Array[Array[T]]]]] = + tabulate(n1)(_ => fill(n2, n3, n4, n5)(elem)) + + /** Returns an array containing values of a given function over a range of integer + * values starting from 0. + * + * @param n The number of elements in the array + * @param f The function computing element values + * @return A traversable consisting of elements `f(0),f(1), ..., f(n - 1)` + */ + def tabulate[T: ClassTag](n: Int)(f: Int => T): Array[T] = { + val b = newBuilder[T] + b.sizeHint(n) + var i = 0 + while (i < n) { + b += f(i) + i += 1 + } + b.result() + } + + /** Returns a two-dimensional array containing values of a given function + * over ranges of integer values starting from `0`. + * + * @param n1 the number of elements in the 1st dimension + * @param n2 the number of elements in the 2nd dimension + * @param f The function computing element values + */ + def tabulate[T: ClassTag](n1: Int, n2: Int)(f: (Int, Int) => T): Array[Array[T]] = + tabulate(n1)(i1 => tabulate(n2)(f(i1, _))) + + /** Returns a three-dimensional array containing values of a given function + * over ranges of integer values starting from `0`. + * + * @param n1 the number of elements in the 1st dimension + * @param n2 the number of elements in the 2nd dimension + * @param n3 the number of elements in the 3rd dimension + * @param f The function computing element values + */ + def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int)(f: (Int, Int, Int) => T): Array[Array[Array[T]]] = + tabulate(n1)(i1 => tabulate(n2, n3)(f(i1, _, _))) + + /** Returns a four-dimensional array containing values of a given function + * over ranges of integer values starting from `0`. + * + * @param n1 the number of elements in the 1st dimension + * @param n2 the number of elements in the 2nd dimension + * @param n3 the number of elements in the 3rd dimension + * @param n4 the number of elements in the 4th dimension + * @param f The function computing element values + */ + def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int)(f: (Int, Int, Int, Int) => T): Array[Array[Array[Array[T]]]] = + tabulate(n1)(i1 => tabulate(n2, n3, n4)(f(i1, _, _, _))) + + /** Returns a five-dimensional array containing values of a given function + * over ranges of integer values starting from `0`. + * + * @param n1 the number of elements in the 1st dimension + * @param n2 the number of elements in the 2nd dimension + * @param n3 the number of elements in the 3rd dimension + * @param n4 the number of elements in the 4th dimension + * @param n5 the number of elements in the 5th dimension + * @param f The function computing element values + */ + def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(f: (Int, Int, Int, Int, Int) => T): Array[Array[Array[Array[Array[T]]]]] = + tabulate(n1)(i1 => tabulate(n2, n3, n4, n5)(f(i1, _, _, _, _))) + + /** Returns an array containing a sequence of increasing integers in a range. + * + * @param start the start value of the array + * @param end the end value of the array, exclusive (in other words, this is the first value '''not''' returned) + * @return the array with values in range `start, start + 1, ..., end - 1` + * up to, but excluding, `end`. + */ + def range(start: Int, end: Int): Array[Int] = range(start, end, 1) + + /** Returns an array containing equally spaced values in some integer interval. + * + * @param start the start value of the array + * @param end the end value of the array, exclusive (in other words, this is the first value '''not''' returned) + * @param step the increment value of the array (may not be zero) + * @return the array with values in `start, start + step, ...` up to, but excluding `end` + */ + def range(start: Int, end: Int, step: Int): Array[Int] = { + if (step == 0) throw new IllegalArgumentException("zero step") + val b = newBuilder[Int] + b.sizeHint(immutable.Range.count(start, end, step, isInclusive = false)) + + var i = start + while (if (step < 0) end < i else i < end) { + b += i + i += step + } + b.result() + } + + /** Returns an array containing repeated applications of a function to a start value. + * + * @param start the start value of the array + * @param len the number of elements returned by the array + * @param f the function that is repeatedly applied + * @return the array returning `len` values in the sequence `start, f(start), f(f(start)), ...` + */ + def iterate[T: ClassTag](start: T, len: Int)(f: T => T): Array[T] = { + val b = newBuilder[T] + + if (len > 0) { + b.sizeHint(len) + var acc = start + var i = 1 + b += acc + + while (i < len) { + acc = f(acc) + i += 1 + b += acc + } + } + b.result() + } + + /** Called in a pattern match like `{ case Array(x,y,z) => println('3 elements')}`. + * + * @param x the selector value + * @return sequence wrapped in a [[scala.Some]], if `x` is a Seq, otherwise `None` + */ + def unapplySeq[T](x: Array[T]): Option[IndexedSeq[T]] = + if (x == null) None else Some(x.toIndexedSeq) + // !!! the null check should to be necessary, but without it 2241 fails. Seems to be a bug + // in pattern matcher. @PP: I noted in #4364 I think the behavior is correct. +} + +/** Arrays are mutable, indexed collections of values. `Array[T]` is Scala's representation + * for Java's `T[]`. + * + * {{{ + * val numbers = Array(1, 2, 3, 4) + * val first = numbers(0) // read the first element + * numbers(3) = 100 // replace the 4th array element with 100 + * val biggerNumbers = numbers.map(_ * 2) // multiply all numbers by two + * }}} + * + * Arrays make use of two common pieces of Scala syntactic sugar, shown on lines 2 and 3 of the above + * example code. + * Line 2 is translated into a call to `apply(Int)`, while line 3 is translated into a call to + * `update(Int, T)`. + * + * Two implicit conversions exist in [[scala.Predef]] that are frequently applied to arrays: a conversion + * to [[scala.collection.mutable.ArrayOps]] (shown on line 4 of the example above) and a conversion + * to [[scala.collection.mutable.WrappedArray]] (a subtype of [[scala.collection.Seq]]). + * Both types make available many of the standard operations found in the Scala collections API. + * The conversion to `ArrayOps` is temporary, as all operations defined on `ArrayOps` return an `Array`, + * while the conversion to `WrappedArray` is permanent as all operations return a `WrappedArray`. + * + * The conversion to `ArrayOps` takes priority over the conversion to `WrappedArray`. For instance, + * consider the following code: + * + * {{{ + * val arr = Array(1, 2, 3) + * val arrReversed = arr.reverse + * val seqReversed : Seq[Int] = arr.reverse + * }}} + * + * Value `arrReversed` will be of type `Array[Int]`, with an implicit conversion to `ArrayOps` occurring + * to perform the `reverse` operation. The value of `seqReversed`, on the other hand, will be computed + * by converting to `WrappedArray` first and invoking the variant of `reverse` that returns another + * `WrappedArray`. + * + * @author Martin Odersky + * @version 1.0 + * @see [[http://www.scala-lang.org/files/archive/spec/2.11/ Scala Language Specification]], for in-depth information on the transformations the Scala compiler makes on Arrays (Sections 6.6 and 6.15 respectively.) + * @see [[http://docs.scala-lang.org/sips/completed/scala-2-8-arrays.html "Scala 2.8 Arrays"]] the Scala Improvement Document detailing arrays since Scala 2.8. + * @see [[http://docs.scala-lang.org/overviews/collections/arrays.html "The Scala 2.8 Collections' API"]] section on `Array` by Martin Odersky for more information. + * @define coll array + * @define Coll `Array` + * @define orderDependent + * @define orderDependentFold + * @define mayNotTerminateInf + * @define willNotTerminateInf + * @define collectExample + * @define undefinedorder + * @define thatinfo the class of the returned collection. In the standard library configuration, + * `That` is either `Array[B]` if an ClassTag is available for B or `ArraySeq[B]` otherwise. + * @define zipthatinfo $thatinfo + * @define bfinfo an implicit value of class `CanBuildFrom` which determines the result class `That` from the current + * representation type `Repr` and the new element type `B`. + */ +final class Array[T](_length: Int) extends java.io.Serializable with java.lang.Cloneable { + + /** The length of the array */ + def length: Int = throw new Error() + + /** The element at given index. + * + * Indices start at `0`; `xs.apply(0)` is the first element of array `xs`. + * Note the indexing syntax `xs(i)` is a shorthand for `xs.apply(i)`. + * + * @param i the index + * @return the element at the given index + * @throws ArrayIndexOutOfBoundsException if `i < 0` or `length <= i` + */ + def apply(i: Int): T = throw new Error() + + /** Update the element at given index. + * + * Indices start at `0`; `xs.update(i, x)` replaces the i^th^ element in the array. + * Note the syntax `xs(i) = x` is a shorthand for `xs.update(i, x)`. + * + * @param i the index + * @param x the value to be written at index `i` + * @throws ArrayIndexOutOfBoundsException if `i < 0` or `length <= i` + */ + def update(i: Int, x: T) { throw new Error() } + + /** Clone the Array. + * + * @return A clone of the Array. + */ + override def clone(): Array[T] = throw new Error() +} diff --git a/scalalib/overrides-2.13.0-M3/scala/Enumeration.scala b/scalalib/overrides-2.13.0-M3/scala/Enumeration.scala new file mode 100644 index 0000000000..bdc170156a --- /dev/null +++ b/scalalib/overrides-2.13.0-M3/scala/Enumeration.scala @@ -0,0 +1,284 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala + +import scala.collection.{ mutable, immutable, generic, SortedSetLike, AbstractSet } +import java.lang.reflect.{ Modifier, Method => JMethod, Field => JField } +import scala.reflect.NameTransformer._ +import java.util.regex.Pattern + +/** Defines a finite set of values specific to the enumeration. Typically + * these values enumerate all possible forms something can take and provide + * a lightweight alternative to case classes. + * + * Each call to a `Value` method adds a new unique value to the enumeration. + * To be accessible, these values are usually defined as `val` members of + * the evaluation. + * + * All values in an enumeration share a common, unique type defined as the + * `Value` type member of the enumeration (`Value` selected on the stable + * identifier path of the enumeration instance). + * + * @example {{{ + * object Main extends App { + * + * object WeekDay extends Enumeration { + * type WeekDay = Value + * val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value + * } + * import WeekDay._ + * + * def isWorkingDay(d: WeekDay) = ! (d == Sat || d == Sun) + * + * WeekDay.values filter isWorkingDay foreach println + * } + * // output: + * // Mon + * // Tue + * // Wed + * // Thu + * // Fri + * }}} + * + * @param initial The initial value from which to count the integers that + * identifies values at run-time. + * @author Matthias Zenger + */ +@SerialVersionUID(8476000850333817230L) +abstract class Enumeration (initial: Int) extends Serializable { + thisenum => + + def this() = this(0) + + /* Note that `readResolve` cannot be private, since otherwise + the JVM does not invoke it when deserializing subclasses. */ + protected def readResolve(): AnyRef = ??? + + /** The name of this enumeration. + */ + override def toString = + (getClass.getName.stripSuffix("$").split('.')).last.split('$').last + + /** The mapping from the integer used to identify values to the actual + * values. */ + private val vmap: mutable.Map[Int, Value] = new mutable.HashMap + + /** The cache listing all values of this enumeration. */ + @transient private var vset: ValueSet = null + @transient @volatile private var vsetDefined = false + + /** The mapping from the integer used to identify values to their + * names. */ + private val nmap: mutable.Map[Int, String] = new mutable.HashMap + + /** The values of this enumeration as a set. + */ + def values: ValueSet = { + if (!vsetDefined) { + vset = (ValueSet.newBuilder ++= vmap.values).result() + vsetDefined = true + } + vset + } + + /** The integer to use to identify the next created value. */ + protected var nextId: Int = initial + + /** The string to use to name the next created value. */ + protected var nextName: Iterator[String] = _ + + private def nextNameOrNull = + if (nextName != null && nextName.hasNext) nextName.next() else null + + /** The highest integer amongst those used to identify values in this + * enumeration. */ + private var topId = initial + + /** The lowest integer amongst those used to identify values in this + * enumeration, but no higher than 0. */ + private var bottomId = if(initial < 0) initial else 0 + + /** The one higher than the highest integer amongst those used to identify + * values in this enumeration. */ + final def maxId = topId + + /** The value of this enumeration with given id `x` + */ + final def apply(x: Int): Value = vmap(x) + + /** Return a `Value` from this `Enumeration` whose name matches + * the argument `s`. The names are determined automatically via reflection. + * + * @param s an `Enumeration` name + * @return the `Value` of this `Enumeration` if its name matches `s` + * @throws NoSuchElementException if no `Value` with a matching + * name is in this `Enumeration` + */ + final def withName(s: String): Value = { + val (unnamed, named) = values partition { + _.toString().startsWith(" v + // If we have unnamed values, we issue a detailed error message + case None if unnamed.nonEmpty => + throw new NoSuchElementException( + s"""Couldn't find enum field with name $s. + |However, there were the following unnamed fields: + |${unnamed.mkString(" ","\n ","")}""".stripMargin) + // Normal case (no unnamed Values) + case _ => None.get + } + } + + /** Creates a fresh value, part of this enumeration. */ + protected final def Value: Value = Value(nextId) + + /** Creates a fresh value, part of this enumeration, identified by the + * integer `i`. + * + * @param i An integer that identifies this value at run-time. It must be + * unique amongst all values of the enumeration. + * @return Fresh value identified by `i`. + */ + protected final def Value(i: Int): Value = Value(i, nextNameOrNull) + + /** Creates a fresh value, part of this enumeration, called `name`. + * + * @param name A human-readable name for that value. + * @return Fresh value called `name`. + */ + protected final def Value(name: String): Value = Value(nextId, name) + + /** Creates a fresh value, part of this enumeration, called `name` + * and identified by the integer `i`. + * + * @param i An integer that identifies this value at run-time. It must be + * unique amongst all values of the enumeration. + * @param name A human-readable name for that value. + * @return Fresh value with the provided identifier `i` and name `name`. + */ + protected final def Value(i: Int, name: String): Value = new Val(i, name) + + /** The type of the enumerated values. */ + @SerialVersionUID(7091335633555234129L) + abstract class Value extends Ordered[Value] with Serializable { + /** the id and bit location of this enumeration value */ + def id: Int + /** a marker so we can tell whose values belong to whom come reflective-naming time */ + private[Enumeration] val outerEnum = thisenum + + override def compare(that: Value): Int = + if (this.id < that.id) -1 + else if (this.id == that.id) 0 + else 1 + override def equals(other: Any) = other match { + case that: Enumeration#Value => (outerEnum eq that.outerEnum) && (id == that.id) + case _ => false + } + override def hashCode: Int = id.## + + /** Create a ValueSet which contains this value and another one */ + def + (v: Value) = ValueSet(this, v) + } + + /** A class implementing the [[scala.Enumeration.Value]] type. This class + * can be overridden to change the enumeration's naming and integer + * identification behaviour. + */ + @SerialVersionUID(0 - 3501153230598116017L) + protected class Val(i: Int, name: String) + extends Value with Serializable { + + def this(i: Int) = this(i, nextNameOrNull) + def this(name: String) = this(nextId, name) + def this() = this(nextId) + + assert(!vmap.isDefinedAt(i), "Duplicate id: " + i) + vmap(i) = this + vsetDefined = false + nextId = i + 1 + if (nextId > topId) topId = nextId + if (i < bottomId) bottomId = i + def id = i + override def toString() = + if (name != null) name + // Scala.js specific + else s"" + + protected def readResolve(): AnyRef = { + val enum = thisenum.readResolve().asInstanceOf[Enumeration] + if (enum.vmap == null) this + else enum.vmap(i) + } + } + + /** An ordering by id for values of this set */ + object ValueOrdering extends Ordering[Value] { + def compare(x: Value, y: Value): Int = x compare y + } + + /** A class for sets of values. + * Iterating through this set will yield values in increasing order of their ids. + * + * @param nnIds The set of ids of values (adjusted so that the lowest value does + * not fall below zero), organized as a `BitSet`. + */ + class ValueSet private[ValueSet] (private[this] var nnIds: immutable.BitSet) + extends AbstractSet[Value] + with immutable.SortedSet[Value] + with SortedSetLike[Value, ValueSet] + with Serializable { + + implicit def ordering: Ordering[Value] = ValueOrdering + def rangeImpl(from: Option[Value], until: Option[Value]): ValueSet = + new ValueSet(nnIds.rangeImpl(from.map(_.id - bottomId), until.map(_.id - bottomId))) + + override def empty = ValueSet.empty + def contains(v: Value) = nnIds contains (v.id - bottomId) + def + (value: Value) = new ValueSet(nnIds + (value.id - bottomId)) + def - (value: Value) = new ValueSet(nnIds - (value.id - bottomId)) + def iterator = nnIds.iterator map (id => thisenum.apply(bottomId + id)) + // This is only defined in 2.11. We change its implementation so it also + // compiles on 2.10. + def keysIteratorFrom(start: Value) = from(start).keySet.toIterator + //nnIds keysIteratorFrom start.id map (id => thisenum.apply(bottomId + id)) + override def stringPrefix = thisenum + ".ValueSet" + /** Creates a bit mask for the zero-adjusted ids in this set as a + * new array of longs */ + def toBitMask: Array[Long] = nnIds.toBitMask + } + + /** A factory object for value sets */ + object ValueSet { + import generic.CanBuildFrom + + /** The empty value set */ + val empty = new ValueSet(immutable.BitSet.empty) + /** A value set consisting of given elements */ + def apply(elems: Value*): ValueSet = (newBuilder ++= elems).result() + /** A value set containing all the values for the zero-adjusted ids + * corresponding to the bits in an array */ + def fromBitMask(elems: Array[Long]): ValueSet = new ValueSet(immutable.BitSet.fromBitMask(elems)) + /** A builder object for value sets */ + def newBuilder: mutable.Builder[Value, ValueSet] = new mutable.Builder[Value, ValueSet] { + private[this] val b = new mutable.BitSet + def += (x: Value) = { b += (x.id - bottomId); this } + def clear() = b.clear() + def result() = new ValueSet(b.toImmutable) + } + /** The implicit builder for value sets */ + implicit def canBuildFrom: CanBuildFrom[ValueSet, Value, ValueSet] = + new CanBuildFrom[ValueSet, Value, ValueSet] { + def apply(from: ValueSet) = newBuilder + def apply() = newBuilder + } + } +} \ No newline at end of file diff --git a/scalalib/overrides-2.13.0-M3/scala/collection/immutable/NumericRange.scala b/scalalib/overrides-2.13.0-M3/scala/collection/immutable/NumericRange.scala new file mode 100644 index 0000000000..65e703829c --- /dev/null +++ b/scalalib/overrides-2.13.0-M3/scala/collection/immutable/NumericRange.scala @@ -0,0 +1,375 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2006-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala +package collection +package immutable + +// TODO: Now the specialization exists there is no clear reason to have +// separate classes for Range/NumericRange. Investigate and consolidate. + +/** `NumericRange` is a more generic version of the + * `Range` class which works with arbitrary types. + * It must be supplied with an `Integral` implementation of the + * range type. + * + * Factories for likely types include `Range.BigInt`, `Range.Long`, + * and `Range.BigDecimal`. `Range.Int` exists for completeness, but + * the `Int`-based `scala.Range` should be more performant. + * + * {{{ + * val r1 = new Range(0, 100, 1) + * val veryBig = Int.MaxValue.toLong + 1 + * val r2 = Range.Long(veryBig, veryBig + 100, 1) + * assert(r1 sameElements r2.map(_ - veryBig)) + * }}} + * + * @author Paul Phillips + * @version 2.8 + * @define Coll `NumericRange` + * @define coll numeric range + * @define mayNotTerminateInf + * @define willNotTerminateInf + */ +abstract class NumericRange[T] + (val start: T, val end: T, val step: T, val isInclusive: Boolean) + (implicit num: Integral[T]) +extends AbstractSeq[T] with IndexedSeq[T] with Serializable { + /** Note that NumericRange must be invariant so that constructs + * such as "1L to 10 by 5" do not infer the range type as AnyVal. + */ + import num._ + + // See comment in Range for why this must be lazy. + private lazy val numRangeElements: Int = + NumericRange.count(start, end, step, isInclusive) + + override def length = numRangeElements + override def isEmpty = length == 0 + override lazy val last: T = + if (length == 0) Nil.last + else locationAfterN(length - 1) + + /** Create a new range with the start and end values of this range and + * a new `step`. + */ + def by(newStep: T): NumericRange[T] = copy(start, end, newStep) + + /** Create a copy of this range. + */ + def copy(start: T, end: T, step: T): NumericRange[T] + + override def foreach[U](f: T => U) { + var count = 0 + var current = start + while (count < length) { + f(current) + current += step + count += 1 + } + } + + // TODO: these private methods are straight copies from Range, duplicated + // to guard against any (most likely illusory) performance drop. They should + // be eliminated one way or another. + + // Tests whether a number is within the endpoints, without testing + // whether it is a member of the sequence (i.e. when step > 1.) + private def isWithinBoundaries(elem: T) = !isEmpty && ( + (step > zero && start <= elem && elem <= last ) || + (step < zero && last <= elem && elem <= start) + ) + // Methods like apply throw exceptions on invalid n, but methods like take/drop + // are forgiving: therefore the checks are with the methods. + private def locationAfterN(n: Int): T = start + (step * fromInt(n)) + + // When one drops everything. Can't ever have unchecked operations + // like "end + 1" or "end - 1" because ranges involving Int.{ MinValue, MaxValue } + // will overflow. This creates an exclusive range where start == end + // based on the given value. + private def newEmptyRange(value: T) = NumericRange(value, value, step) + + final override def take(n: Int): NumericRange[T] = ( + if (n <= 0 || length == 0) newEmptyRange(start) + else if (n >= length) this + else new NumericRange.Inclusive(start, locationAfterN(n - 1), step) + ) + + final override def drop(n: Int): NumericRange[T] = ( + if (n <= 0 || length == 0) this + else if (n >= length) newEmptyRange(end) + else copy(locationAfterN(n), end, step) + ) + + def apply(idx: Int): T = { + if (idx < 0 || idx >= length) throw new IndexOutOfBoundsException(idx.toString) + else locationAfterN(idx) + } + + import NumericRange.defaultOrdering + + override def min[T1 >: T](implicit ord: Ordering[T1]): T = + // We can take the fast path: + // - If the Integral of this NumericRange is also the requested Ordering + // (Integral <: Ordering). This can happen for custom Integral types. + // - The Ordering is the default Ordering of a well-known Integral type. + if ((ord eq num) || defaultOrdering.get(num).exists(ord eq _)) { + if (num.signum(step) > 0) start + else last + } else super.min(ord) + + override def max[T1 >: T](implicit ord: Ordering[T1]): T = + // See comment for fast path in min(). + if ((ord eq num) || defaultOrdering.get(num).exists(ord eq _)) { + if (num.signum(step) > 0) last + else start + } else super.max(ord) + + // Motivated by the desire for Double ranges with BigDecimal precision, + // we need some way to map a Range and get another Range. This can't be + // done in any fully general way because Ranges are not arbitrary + // sequences but step-valued, so we have a custom method only we can call + // which we promise to use responsibly. + // + // The point of it all is that + // + // 0.0 to 1.0 by 0.1 + // + // should result in + // + // NumericRange[Double](0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0) + // + // and not + // + // NumericRange[Double](0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9) + // + // or perhaps more importantly, + // + // (0.1 to 0.3 by 0.1 contains 0.3) == true + // + private[immutable] def mapRange[A](fm: T => A)(implicit unum: Integral[A]): NumericRange[A] = { + val self = this + + // XXX This may be incomplete. + new NumericRange[A](fm(start), fm(end), fm(step), isInclusive) { + def copy(start: A, end: A, step: A): NumericRange[A] = + if (isInclusive) NumericRange.inclusive(start, end, step) + else NumericRange(start, end, step) + + private lazy val underlyingRange: NumericRange[T] = self + override def foreach[U](f: A => U) { underlyingRange foreach (x => f(fm(x))) } + override def isEmpty = underlyingRange.isEmpty + override def apply(idx: Int): A = fm(underlyingRange(idx)) + override def containsTyped(el: A) = underlyingRange exists (x => fm(x) == el) + + override def toString = { + def simpleOf(x: Any): String = x.getClass.getName.split("\\.").last + val stepped = simpleOf(underlyingRange.step) + s"${super.toString} (using $underlyingRange of $stepped)" + } + } + } + + // a well-typed contains method. + def containsTyped(x: T): Boolean = + isWithinBoundaries(x) && (((x - start) % step) == zero) + + override def contains[A1 >: T](x: A1): Boolean = + try containsTyped(x.asInstanceOf[T]) + catch { case _: ClassCastException => false } + + final override def sum[B >: T](implicit num: Numeric[B]): B = { + if (isEmpty) num.zero + else if (numRangeElements == 1) head + else { + // If there is no overflow, use arithmetic series formula + // a + ... (n terms total) ... + b = n*(a+b)/2 + if ((num eq scala.math.Numeric.IntIsIntegral)|| + (num eq scala.math.Numeric.ShortIsIntegral)|| + (num eq scala.math.Numeric.ByteIsIntegral)|| + (num eq scala.math.Numeric.CharIsIntegral)) { + // We can do math with no overflow in a Long--easy + val exact = (numRangeElements * ((num toLong head) + (num toInt last))) / 2 + num fromInt exact.toInt + } + else if (num eq scala.math.Numeric.LongIsIntegral) { + // Uh-oh, might be overflow, so we have to divide before we overflow. + // Either numRangeElements or (head + last) must be even, so divide the even one before multiplying + val a = head.toLong + val b = last.toLong + val ans = + if ((numRangeElements & 1) == 0) (numRangeElements / 2) * (a + b) + else numRangeElements * { + // Sum is even, but we might overflow it, so divide in pieces and add back remainder + val ha = a/2 + val hb = b/2 + ha + hb + ((a - 2*ha) + (b - 2*hb)) / 2 + } + ans.asInstanceOf[B] + } + else { + // User provided custom Numeric, so we cannot rely on arithmetic series formula (e.g. won't work on something like Z_6) + if (isEmpty) num.zero + else { + var acc = num.zero + var i = head + var idx = 0 + while(idx < length) { + acc = num.plus(acc, i) + i = i + step + idx = idx + 1 + } + acc + } + } + } + } + + override lazy val hashCode = super.hashCode() + override def equals(other: Any) = other match { + case x: NumericRange[_] => + (x canEqual this) && (length == x.length) && ( + (length == 0) || // all empty sequences are equal + (start == x.start && last == x.last) // same length and same endpoints implies equality + ) + case _ => + super.equals(other) + } + + override def toString = { + val empty = if (isEmpty) "empty " else "" + val preposition = if (isInclusive) "to" else "until" + val stepped = if (step == 1) "" else s" by $step" + s"${empty}NumericRange $start $preposition $end$stepped" + } +} + +/** A companion object for numeric ranges. + */ +object NumericRange { + + /** Calculates the number of elements in a range given start, end, step, and + * whether or not it is inclusive. Throws an exception if step == 0 or + * the number of elements exceeds the maximum Int. + */ + def count[T](start: T, end: T, step: T, isInclusive: Boolean)(implicit num: Integral[T]): Int = { + val zero = num.zero + val upward = num.lt(start, end) + val posStep = num.gt(step, zero) + + if (step == zero) throw new IllegalArgumentException("step cannot be 0.") + else if (start == end) if (isInclusive) 1 else 0 + else if (upward != posStep) 0 + else { + /* We have to be frightfully paranoid about running out of range. + * We also can't assume that the numbers will fit in a Long. + * We will assume that if a > 0, -a can be represented, and if + * a < 0, -a+1 can be represented. We also assume that if we + * can't fit in Int, we can represent 2*Int.MaxValue+3 (at least). + * And we assume that numbers wrap rather than cap when they overflow. + */ + // Check whether we can short-circuit by deferring to Int range. + val startint = num.toInt(start) + if (start == num.fromInt(startint)) { + val endint = num.toInt(end) + if (end == num.fromInt(endint)) { + val stepint = num.toInt(step) + if (step == num.fromInt(stepint)) { + return { + if (isInclusive) Range.inclusive(startint, endint, stepint).length + else Range (startint, endint, stepint).length + } + } + } + } + // If we reach this point, deferring to Int failed. + // Numbers may be big. + val one = num.one + val limit = num.fromInt(Int.MaxValue) + def check(t: T): T = + if (num.gt(t, limit)) throw new IllegalArgumentException("More than Int.MaxValue elements.") + else t + // If the range crosses zero, it might overflow when subtracted + val startside = num.signum(start) + val endside = num.signum(end) + num.toInt{ + if (startside*endside >= 0) { + // We're sure we can subtract these numbers. + // Note that we do not use .rem because of different conventions for Long and BigInt + val diff = num.minus(end, start) + val quotient = check(num.quot(diff, step)) + val remainder = num.minus(diff, num.times(quotient, step)) + if (!isInclusive && zero == remainder) quotient else check(num.plus(quotient, one)) + } + else { + // We might not even be able to subtract these numbers. + // Jump in three pieces: + // * start to -1 or 1, whichever is closer (waypointA) + // * one step, which will take us at least to 0 (ends at waypointB) + // * there to the end + val negone = num.fromInt(-1) + val startlim = if (posStep) negone else one + val startdiff = num.minus(startlim, start) + val startq = check(num.quot(startdiff, step)) + val waypointA = if (startq == zero) start else num.plus(start, num.times(startq, step)) + val waypointB = num.plus(waypointA, step) + check { + if (num.lt(waypointB, end) != upward) { + // No last piece + if (isInclusive && waypointB == end) num.plus(startq, num.fromInt(2)) + else num.plus(startq, one) + } + else { + // There is a last piece + val enddiff = num.minus(end,waypointB) + val endq = check(num.quot(enddiff, step)) + val last = if (endq == zero) waypointB else num.plus(waypointB, num.times(endq, step)) + // Now we have to tally up all the pieces + // 1 for the initial value + // startq steps to waypointA + // 1 step to waypointB + // endq steps to the end (one less if !isInclusive and last==end) + num.plus(startq, num.plus(endq, if (!isInclusive && last==end) one else num.fromInt(2))) + } + } + } + } + } + } + + class Inclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]) + extends NumericRange(start, end, step, true) { + def copy(start: T, end: T, step: T): Inclusive[T] = + NumericRange.inclusive(start, end, step) + + def exclusive: Exclusive[T] = NumericRange(start, end, step) + } + + class Exclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]) + extends NumericRange(start, end, step, false) { + def copy(start: T, end: T, step: T): Exclusive[T] = + NumericRange(start, end, step) + + def inclusive: Inclusive[T] = NumericRange.inclusive(start, end, step) + } + + def apply[T](start: T, end: T, step: T)(implicit num: Integral[T]): Exclusive[T] = + new Exclusive(start, end, step) + def inclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]): Inclusive[T] = + new Inclusive(start, end, step) + + private[collection] val defaultOrdering = Map[Numeric[_], Ordering[_]]( + Numeric.IntIsIntegral -> Ordering.Int, + Numeric.ShortIsIntegral -> Ordering.Short, + Numeric.ByteIsIntegral -> Ordering.Byte, + Numeric.CharIsIntegral -> Ordering.Char, + Numeric.LongIsIntegral -> Ordering.Long + ) + +} + diff --git a/scalalib/overrides-2.13.0-M3/scala/collection/immutable/Range.scala b/scalalib/overrides-2.13.0-M3/scala/collection/immutable/Range.scala new file mode 100644 index 0000000000..fb2c34c064 --- /dev/null +++ b/scalalib/overrides-2.13.0-M3/scala/collection/immutable/Range.scala @@ -0,0 +1,527 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2006-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + + +package scala +package collection.immutable + +/** The `Range` class represents integer values in range + * ''[start;end)'' with non-zero step value `step`. + * It's a special case of an indexed sequence. + * For example: + * + * {{{ + * val r1 = 0 until 10 + * val r2 = r1.start until r1.end by r1.step + 1 + * println(r2.length) // = 5 + * }}} + * + * Ranges that contain more than `Int.MaxValue` elements can be created, but + * these overfull ranges have only limited capabilities. Any method that + * could require a collection of over `Int.MaxValue` length to be created, or + * could be asked to index beyond `Int.MaxValue` elements will throw an + * exception. Overfull ranges can safely be reduced in size by changing + * the step size (e.g. `by 3`) or taking/dropping elements. `contains`, + * `equals`, and access to the ends of the range (`head`, `last`, `tail`, + * `init`) are also permitted on overfull ranges. + * + * @param start the start of this range. + * @param end the end of the range. For exclusive ranges, e.g. + * `Range(0,3)` or `(0 until 3)`, this is one + * step past the last one in the range. For inclusive + * ranges, e.g. `Range.inclusive(0,3)` or `(0 to 3)`, + * it may be in the range if it is not skipped by the step size. + * To find the last element inside a non-empty range, + use `last` instead. + * @param step the step for the range. + * + * @author Martin Odersky + * @author Paul Phillips + * @version 2.8 + * @since 2.5 + * @see [[http://docs.scala-lang.org/overviews/collections/concrete-immutable-collection-classes.html#ranges "Scala's Collection Library overview"]] + * section on `Ranges` for more information. + * + * @define coll range + * @define mayNotTerminateInf + * @define willNotTerminateInf + * @define doesNotUseBuilders + * '''Note:''' this method does not use builders to construct a new range, + * and its complexity is O(1). + */ +@SerialVersionUID(7618862778670199309L) +@inline +@deprecatedInheritance("The implementation details of Range makes inheriting from it unwise.", "2.11.0") +class Range(val start: Int, val end: Int, val step: Int) +extends scala.collection.AbstractSeq[Int] + with IndexedSeq[Int] + with Serializable +{ + private def gap = end.toLong - start.toLong + private def isExact = gap % step == 0 + private def hasStub = isInclusive || !isExact + private def longLength = gap / step + ( if (hasStub) 1 else 0 ) + + // Check cannot be evaluated eagerly because we have a pattern where + // ranges are constructed like: "x to y by z" The "x to y" piece + // should not trigger an exception. So the calculation is delayed, + // which means it will not fail fast for those cases where failing was + // correct. + override final val isEmpty = ( + (start > end && step > 0) + || (start < end && step < 0) + || (start == end && !isInclusive) + ) + + private val numRangeElements: Int = { + if (step == 0) throw new IllegalArgumentException("step cannot be 0.") + else if (isEmpty) 0 + else { + val len = longLength + if (len > scala.Int.MaxValue) -1 + else len.toInt + } + } + + // This field has a sensible value only for non-empty ranges + private val lastElement = step match { + case 1 => if (isInclusive) end else end-1 + case -1 => if (isInclusive) end else end+1 + case _ => + val remainder = (gap % step).toInt + if (remainder != 0) end - remainder + else if (isInclusive) end + else end - step + } + + /** The last element of this range. This method will return the correct value + * even if there are too many elements to iterate over. + */ + override def last = if (isEmpty) Nil.last else lastElement + override def head = if (isEmpty) Nil.head else start + + override def min[A1 >: Int](implicit ord: Ordering[A1]): Int = + if (ord eq Ordering.Int) { + if (step > 0) head + else last + } else super.min(ord) + + override def max[A1 >: Int](implicit ord: Ordering[A1]): Int = + if (ord eq Ordering.Int) { + if (step > 0) last + else head + } else super.max(ord) + + protected def copy(start: Int, end: Int, step: Int): Range = new Range(start, end, step) + + /** Create a new range with the `start` and `end` values of this range and + * a new `step`. + * + * @return a new range with a different step + */ + def by(step: Int): Range = copy(start, end, step) + + def isInclusive = false + + override def size = length + override def length = if (numRangeElements < 0) fail() else numRangeElements + + private def fail() = Range.fail(start, end, step, isInclusive) + private def validateMaxLength() { + if (numRangeElements < 0) + fail() + } + + final def apply(idx: Int): Int = { + validateMaxLength() + if (idx < 0 || idx >= numRangeElements) throw new IndexOutOfBoundsException(idx.toString) + else start + (step * idx) + } + + @inline final override def foreach[@specialized(Unit) U](f: Int => U) { + // Implementation chosen on the basis of favorable microbenchmarks + // Note--initialization catches step == 0 so we don't need to here + if (!isEmpty) { + var i = start + while (true) { + f(i) + if (i == lastElement) return + i += step + } + } + } + + /** Creates a new range containing the first `n` elements of this range. + * + * $doesNotUseBuilders + * + * @param n the number of elements to take. + * @return a new range consisting of `n` first elements. + */ + final override def take(n: Int): Range = ( + if (n <= 0 || isEmpty) newEmptyRange(start) + else if (n >= numRangeElements && numRangeElements >= 0) this + else { + // May have more than Int.MaxValue elements in range (numRangeElements < 0) + // but the logic is the same either way: take the first n + new Range.Inclusive(start, locationAfterN(n - 1), step) + } + ) + + /** Creates a new range containing all the elements of this range except the first `n` elements. + * + * $doesNotUseBuilders + * + * @param n the number of elements to drop. + * @return a new range consisting of all the elements of this range except `n` first elements. + */ + final override def drop(n: Int): Range = ( + if (n <= 0 || isEmpty) this + else if (n >= numRangeElements && numRangeElements >= 0) newEmptyRange(end) + else { + // May have more than Int.MaxValue elements (numRangeElements < 0) + // but the logic is the same either way: go forwards n steps, keep the rest + copy(locationAfterN(n), end, step) + } + ) + + /** Creates a new range containing the elements starting at `from` up to but not including `until`. + * + * $doesNotUseBuilders + * + * @param from the element at which to start + * @param until the element at which to end (not included in the range) + * @return a new range consisting of a contiguous interval of values in the old range + */ + override def slice(from: Int, until: Int): Range = + if (from <= 0) take(until) + else if (until >= numRangeElements && numRangeElements >= 0) drop(from) + else { + val fromValue = locationAfterN(from) + if (from >= until) newEmptyRange(fromValue) + else new Range.Inclusive(fromValue, locationAfterN(until-1), step) + } + + /** Creates a new range containing all the elements of this range except the last one. + * + * $doesNotUseBuilders + * + * @return a new range consisting of all the elements of this range except the last one. + */ + final override def init: Range = { + if (isEmpty) + Nil.init + + dropRight(1) + } + + /** Creates a new range containing all the elements of this range except the first one. + * + * $doesNotUseBuilders + * + * @return a new range consisting of all the elements of this range except the first one. + */ + final override def tail: Range = { + if (isEmpty) + Nil.tail + + drop(1) + } + + // Advance from the start while we meet the given test + private def argTakeWhile(p: Int => Boolean): Long = { + if (isEmpty) start + else { + var current = start + val stop = last + while (current != stop && p(current)) current += step + if (current != stop || !p(current)) current + else current.toLong + step + } + } + // Methods like apply throw exceptions on invalid n, but methods like take/drop + // are forgiving: therefore the checks are with the methods. + private def locationAfterN(n: Int) = start + (step * n) + + // When one drops everything. Can't ever have unchecked operations + // like "end + 1" or "end - 1" because ranges involving Int.{ MinValue, MaxValue } + // will overflow. This creates an exclusive range where start == end + // based on the given value. + private def newEmptyRange(value: Int) = new Range(value, value, step) + + final override def takeWhile(p: Int => Boolean): Range = { + val stop = argTakeWhile(p) + if (stop==start) newEmptyRange(start) + else { + val x = (stop - step).toInt + if (x == last) this + else new Range.Inclusive(start, x, step) + } + } + final override def dropWhile(p: Int => Boolean): Range = { + val stop = argTakeWhile(p) + if (stop == start) this + else { + val x = (stop - step).toInt + if (x == last) newEmptyRange(last) + else new Range.Inclusive(x + step, last, step) + } + } + final override def span(p: Int => Boolean): (Range, Range) = { + val border = argTakeWhile(p) + if (border == start) (newEmptyRange(start), this) + else { + val x = (border - step).toInt + if (x == last) (this, newEmptyRange(last)) + else (new Range.Inclusive(start, x, step), new Range.Inclusive(x+step, last, step)) + } + } + + /** Creates a pair of new ranges, first consisting of elements before `n`, and the second + * of elements after `n`. + * + * $doesNotUseBuilders + */ + final override def splitAt(n: Int) = (take(n), drop(n)) + + /** Creates a new range consisting of the last `n` elements of the range. + * + * $doesNotUseBuilders + */ + final override def takeRight(n: Int): Range = { + if (n <= 0) newEmptyRange(start) + else if (numRangeElements >= 0) drop(numRangeElements - n) + else { + // Need to handle over-full range separately + val y = last + val x = y - step.toLong*(n-1) + if ((step > 0 && x < start) || (step < 0 && x > start)) this + else new Range.Inclusive(x.toInt, y, step) + } + } + + /** Creates a new range consisting of the initial `length - n` elements of the range. + * + * $doesNotUseBuilders + */ + final override def dropRight(n: Int): Range = { + if (n <= 0) this + else if (numRangeElements >= 0) take(numRangeElements - n) + else { + // Need to handle over-full range separately + val y = last - step.toInt*n + if ((step > 0 && y < start) || (step < 0 && y > start)) newEmptyRange(start) + else new Range.Inclusive(start, y.toInt, step) + } + } + + /** Returns the reverse of this range. + * + * $doesNotUseBuilders + */ + final override def reverse: Range = + if (isEmpty) this + else new Range.Inclusive(last, start, -step) + + /** Make range inclusive. + */ + def inclusive = + if (isInclusive) this + else new Range.Inclusive(start, end, step) + + final def contains(x: Int) = { + if (x==end && !isInclusive) false + else if (step > 0) { + if (x < start || x > end) false + else (step == 1) || (((x - start) % step) == 0) + } + else { + if (x < end || x > start) false + else (step == -1) || (((x - start) % step) == 0) + } + } + + final override def sum[B >: Int](implicit num: Numeric[B]): Int = { + if (num eq scala.math.Numeric.IntIsIntegral) { + // this is normal integer range with usual addition. arithmetic series formula can be used + if (isEmpty) 0 + else if (numRangeElements == 1) head + else ((numRangeElements * (head.toLong + last)) / 2).toInt + } else { + // user provided custom Numeric, we cannot rely on arithmetic series formula + if (isEmpty) num.toInt(num.zero) + else { + var acc = num.zero + var i = head + while (true) { + acc = num.plus(acc, i) + if (i == lastElement) return num.toInt(acc) + i = i + step + } + 0 // Never hit this--just to satisfy compiler since it doesn't know while(true) has type Nothing + } + } + } + + override def toIterable = this + + override def toSeq = this + + override def equals(other: Any) = other match { + case x: Range => + // Note: this must succeed for overfull ranges (length > Int.MaxValue) + (x canEqual this) && { + if (isEmpty) x.isEmpty // empty sequences are equal + else // this is non-empty... + x.nonEmpty && start == x.start && { // ...so other must contain something and have same start + val l0 = last + (l0 == x.last && ( // And same end + start == l0 || step == x.step // And either the same step, or not take any steps + )) + } + } + case _ => + super.equals(other) + } + + /* Note: hashCode can't be overridden without breaking Seq's equals contract. */ + + override def toString = { + val preposition = if (isInclusive) "to" else "until" + val stepped = if (step == 1) "" else s" by $step" + val prefix = if (isEmpty) "empty " else if (!isExact) "inexact " else "" + s"${prefix}Range $start $preposition $end$stepped" + } +} + +/** A companion object for the `Range` class. + */ +object Range { + private[immutable] val MAX_PRINT = 512 // some arbitrary value + + private def description(start: Int, end: Int, step: Int, isInclusive: Boolean) = + start + (if (isInclusive) " to " else " until ") + end + " by " + step + + private def fail(start: Int, end: Int, step: Int, isInclusive: Boolean) = + throw new IllegalArgumentException(description(start, end, step, isInclusive) + + ": seqs cannot contain more than Int.MaxValue elements.") + + /** Counts the number of range elements. + * @pre step != 0 + * If the size of the range exceeds Int.MaxValue, the + * result will be negative. + */ + def count(start: Int, end: Int, step: Int, isInclusive: Boolean): Int = { + if (step == 0) + throw new IllegalArgumentException("step cannot be 0.") + + val isEmpty = ( + if (start == end) !isInclusive + else if (start < end) step < 0 + else step > 0 + ) + if (isEmpty) 0 + else { + // Counts with Longs so we can recognize too-large ranges. + val gap: Long = end.toLong - start.toLong + val jumps: Long = gap / step + // Whether the size of this range is one larger than the + // number of full-sized jumps. + val hasStub = isInclusive || (gap % step != 0) + val result: Long = jumps + ( if (hasStub) 1 else 0 ) + + if (result > scala.Int.MaxValue) -1 + else result.toInt + } + } + def count(start: Int, end: Int, step: Int): Int = + count(start, end, step, isInclusive = false) + + @inline + class Inclusive(start: Int, end: Int, step: Int) extends Range(start, end, step) { + override def isInclusive = true + override protected def copy(start: Int, end: Int, step: Int): Range = new Inclusive(start, end, step) + } + + /** Make a range from `start` until `end` (exclusive) with given step value. + * @note step != 0 + */ + def apply(start: Int, end: Int, step: Int): Range = new Range(start, end, step) + + /** Make a range from `start` until `end` (exclusive) with step value 1. + */ + def apply(start: Int, end: Int): Range = new Range(start, end, 1) + + /** Make an inclusive range from `start` to `end` with given step value. + * @note step != 0 + */ + def inclusive(start: Int, end: Int, step: Int): Range.Inclusive = new Inclusive(start, end, step) + + /** Make an inclusive range from `start` to `end` with step value 1. + */ + def inclusive(start: Int, end: Int): Range.Inclusive = new Inclusive(start, end, 1) + + // BigInt and Long are straightforward generic ranges. + object BigInt { + def apply(start: BigInt, end: BigInt, step: BigInt) = NumericRange(start, end, step) + def inclusive(start: BigInt, end: BigInt, step: BigInt) = NumericRange.inclusive(start, end, step) + } + + object Long { + def apply(start: Long, end: Long, step: Long) = NumericRange(start, end, step) + def inclusive(start: Long, end: Long, step: Long) = NumericRange.inclusive(start, end, step) + } + + // BigDecimal uses an alternative implementation of Numeric in which + // it pretends to be Integral[T] instead of Fractional[T]. See Numeric for + // details. The intention is for it to throw an exception anytime + // imprecision or surprises might result from anything, although this may + // not yet be fully implemented. + object BigDecimal { + implicit val bigDecAsIntegral = scala.math.Numeric.BigDecimalAsIfIntegral + + def apply(start: BigDecimal, end: BigDecimal, step: BigDecimal) = + NumericRange(start, end, step) + def inclusive(start: BigDecimal, end: BigDecimal, step: BigDecimal) = + NumericRange.inclusive(start, end, step) + } + + // Double works by using a BigDecimal under the hood for precise + // stepping, but mapping the sequence values back to doubles with + // .doubleValue. This constructs the BigDecimals by way of the + // String constructor (valueOf) instead of the Double one, which + // is necessary to keep 0.3d at 0.3 as opposed to + // 0.299999999999999988897769753748434595763683319091796875 or so. + object Double { + implicit val bigDecAsIntegral = scala.math.Numeric.BigDecimalAsIfIntegral + implicit val doubleAsIntegral = scala.math.Numeric.DoubleAsIfIntegral + def toBD(x: Double): BigDecimal = scala.math.BigDecimal valueOf x + + def apply(start: Double, end: Double, step: Double) = + BigDecimal(toBD(start), toBD(end), toBD(step)) mapRange (_.doubleValue) + + def inclusive(start: Double, end: Double, step: Double) = + BigDecimal.inclusive(toBD(start), toBD(end), toBD(step)) mapRange (_.doubleValue) + } + + // As there is no appealing default step size for not-really-integral ranges, + // we offer a partially constructed object. + class Partial[T, U](private val f: T => U) extends AnyVal { + def by(x: T): U = f(x) + override def toString = "Range requires step" + } + + // Illustrating genericity with Int Range, which should have the same behavior + // as the original Range class. However we leave the original Range + // indefinitely, for performance and because the compiler seems to bootstrap + // off it and won't do so with our parameterized version without modifications. + object Int { + def apply(start: Int, end: Int, step: Int) = NumericRange(start, end, step) + def inclusive(start: Int, end: Int, step: Int) = NumericRange.inclusive(start, end, step) + } +} diff --git a/scalalib/overrides-2.13.0-M3/scala/collection/mutable/ArrayBuilder.scala b/scalalib/overrides-2.13.0-M3/scala/collection/mutable/ArrayBuilder.scala new file mode 100644 index 0000000000..ce3a7d5a03 --- /dev/null +++ b/scalalib/overrides-2.13.0-M3/scala/collection/mutable/ArrayBuilder.scala @@ -0,0 +1,735 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala +package collection +package mutable + +import scala.reflect.ClassTag +import scala.runtime.BoxedUnit + +import scala.scalajs.js + +/** A builder class for arrays. + * + * @since 2.8 + * + * @tparam T the type of the elements for the builder. + */ +abstract class ArrayBuilder[T] extends ReusableBuilder[T, Array[T]] with Serializable + +/** A companion object for array builders. + * + * @since 2.8 + */ +object ArrayBuilder { + + /** Creates a new arraybuilder of type `T`. + * + * @tparam T type of the elements for the array builder, with a `ClassTag` context bound. + * @return a new empty array builder. + */ + @inline + def make[T: ClassTag](): ArrayBuilder[T] = + new ArrayBuilder.generic[T](implicitly[ClassTag[T]].runtimeClass) + + /** A generic ArrayBuilder optimized for Scala.js. + * + * @tparam T type of elements for the array builder. + * @param elementClass runtime class of the elements in the array. + */ + @inline + private final class generic[T](elementClass: Class[_]) extends ArrayBuilder[T] { + + private val isCharArrayBuilder = classOf[Char] == elementClass + private var elems: js.Array[Any] = js.Array() + + def +=(elem: T): this.type = { + val unboxedElem = + if (isCharArrayBuilder) elem.asInstanceOf[Char].toInt + else if (elem == null) zeroOf(elementClass) + else elem + elems.push(unboxedElem) + this + } + + def clear(): Unit = + elems = js.Array() + + def result(): Array[T] = { + val elemRuntimeClass = + if (classOf[Unit] == elementClass) classOf[BoxedUnit] + else if (classOf[Null] == elementClass || classOf[Nothing] == elementClass) classOf[Object] + else elementClass + genericArrayBuilderResult(elemRuntimeClass, elems) + } + + override def toString(): String = "ArrayBuilder.generic" + } + + // Intrinsic + private def zeroOf(runtimeClass: Class[_]): Any = runtimeClass match { + case java.lang.Byte.TYPE => 0.toByte + case java.lang.Short.TYPE => 0.toShort + case java.lang.Character.TYPE => 0 // yes, as an Int + case java.lang.Integer.TYPE => 0 + case java.lang.Long.TYPE => 0L + case java.lang.Float.TYPE => 0.0f + case java.lang.Double.TYPE => 0.0 + case java.lang.Boolean.TYPE => false + case java.lang.Void.TYPE => () + case _ => null + } + + // Intrinsic + private def genericArrayBuilderResult[T](runtimeClass: Class[_], + a: js.Array[Any]): Array[T] = { + val len = a.length + + if (classOf[Char] == runtimeClass) { + val result = new Array[Char](len) + var i = 0 + while (i != len) { + result(i) = a(i).asInstanceOf[Int].toChar + i += 1 + } + result.asInstanceOf[Array[T]] + } else { + val result: Array[T] = java.lang.reflect.Array.newInstance( + runtimeClass, len).asInstanceOf[Array[T]] + var i = 0 + while (i != len) { + result(i) = a(i).asInstanceOf[T] + i += 1 + } + result + } + } + + /** A class for array builders for arrays of reference types. + * + * This builder can be reused. + * + * @tparam T type of elements for the array builder, subtype of `AnyRef` with a `ClassTag` context bound. + */ + final class ofRef[T <: AnyRef : ClassTag] extends ArrayBuilder[T] { + + private var elems: Array[T] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[T] = { + val newelems = new Array[T](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: T): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[T]): this.type = (xs.asInstanceOf[AnyRef]) match { + case xs: WrappedArray.ofRef[_] => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { size = 0 } + + def result() = { + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofRef[_] => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofRef" + } + + /** A class for array builders for arrays of `byte`s. It can be reused. */ + final class ofByte extends ArrayBuilder[Byte] { + + private var elems: Array[Byte] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[Byte] = { + val newelems = new Array[Byte](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Byte): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Byte]): this.type = xs match { + case xs: WrappedArray.ofByte => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { size = 0 } + + def result() = { + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofByte => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofByte" + } + + /** A class for array builders for arrays of `short`s. It can be reused. */ + final class ofShort extends ArrayBuilder[Short] { + + private var elems: Array[Short] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[Short] = { + val newelems = new Array[Short](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Short): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Short]): this.type = xs match { + case xs: WrappedArray.ofShort => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { size = 0 } + + def result() = { + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofShort => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofShort" + } + + /** A class for array builders for arrays of `char`s. It can be reused. */ + final class ofChar extends ArrayBuilder[Char] { + + private var elems: Array[Char] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[Char] = { + val newelems = new Array[Char](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Char): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Char]): this.type = xs match { + case xs: WrappedArray.ofChar => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { size = 0 } + + def result() = { + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofChar => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofChar" + } + + /** A class for array builders for arrays of `int`s. It can be reused. */ + final class ofInt extends ArrayBuilder[Int] { + + private var elems: Array[Int] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[Int] = { + val newelems = new Array[Int](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Int): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Int]): this.type = xs match { + case xs: WrappedArray.ofInt => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { size = 0 } + + def result() = { + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofInt => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofInt" + } + + /** A class for array builders for arrays of `long`s. It can be reused. */ + final class ofLong extends ArrayBuilder[Long] { + + private var elems: Array[Long] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[Long] = { + val newelems = new Array[Long](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Long): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Long]): this.type = xs match { + case xs: WrappedArray.ofLong => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { size = 0 } + + def result() = { + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofLong => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofLong" + } + + /** A class for array builders for arrays of `float`s. It can be reused. */ + final class ofFloat extends ArrayBuilder[Float] { + + private var elems: Array[Float] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[Float] = { + val newelems = new Array[Float](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Float): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Float]): this.type = xs match { + case xs: WrappedArray.ofFloat => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { size = 0 } + + def result() = { + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofFloat => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofFloat" + } + + /** A class for array builders for arrays of `double`s. It can be reused. */ + final class ofDouble extends ArrayBuilder[Double] { + + private var elems: Array[Double] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[Double] = { + val newelems = new Array[Double](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Double): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Double]): this.type = xs match { + case xs: WrappedArray.ofDouble => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { size = 0 } + + def result() = { + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofDouble => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofDouble" + } + + /** A class for array builders for arrays of `boolean`s. It can be reused. */ + class ofBoolean extends ArrayBuilder[Boolean] { + + private var elems: Array[Boolean] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def mkArray(size: Int): Array[Boolean] = { + val newelems = new Array[Boolean](size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + newelems + } + + private def resize(size: Int) { + elems = mkArray(size) + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Boolean): this.type = { + ensureSize(size + 1) + elems(size) = elem + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Boolean]): this.type = xs match { + case xs: WrappedArray.ofBoolean => + ensureSize(this.size + xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) + size += xs.length + this + case _ => + super.++=(xs) + } + + def clear() { size = 0 } + + def result() = { + if (capacity != 0 && capacity == size) { + capacity = 0 + elems + } + else mkArray(size) + } + + override def equals(other: Any): Boolean = other match { + case x: ofBoolean => (size == x.size) && (elems == x.elems) + case _ => false + } + + override def toString = "ArrayBuilder.ofBoolean" + } + + /** A class for array builders for arrays of `Unit` type. It can be reused. */ + final class ofUnit extends ArrayBuilder[Unit] { + + private var size: Int = 0 + + def +=(elem: Unit): this.type = { + size += 1 + this + } + + override def ++=(xs: TraversableOnce[Unit]): this.type = { + size += xs.size + this + } + + def clear() { size = 0 } + + def result() = { + val ans = new Array[Unit](size) + var i = 0 + while (i < size) { ans(i) = (); i += 1 } + ans + } + + override def equals(other: Any): Boolean = other match { + case x: ofUnit => (size == x.size) + case _ => false + } + + override def toString = "ArrayBuilder.ofUnit" + } +} diff --git a/scalalib/overrides-2.13.0-M3/scala/collection/mutable/Buffer.scala b/scalalib/overrides-2.13.0-M3/scala/collection/mutable/Buffer.scala new file mode 100644 index 0000000000..2171cb9dea --- /dev/null +++ b/scalalib/overrides-2.13.0-M3/scala/collection/mutable/Buffer.scala @@ -0,0 +1,51 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + + + +package scala +package collection +package mutable + +import generic._ + +import scala.scalajs.js + +/** Buffers are used to create sequences of elements incrementally by + * appending, prepending, or inserting new elements. It is also + * possible to access and modify elements in a random access fashion + * via the index of the element in the current sequence. + * + * @author Matthias Zenger + * @author Martin Odersky + * @version 2.8 + * @since 1 + * + * @tparam A type of the elements contained in this buffer. + * + * @define Coll `Buffer` + * @define coll buffer + */ +trait Buffer[A] extends Seq[A] + with GenericTraversableTemplate[A, Buffer] + with BufferLike[A, Buffer[A]] + with scala.Cloneable { + override def companion: GenericCompanion[Buffer] = Buffer +} + +/** $factoryInfo + * @define coll buffer + * @define Coll `Buffer` + */ +object Buffer extends SeqFactory[Buffer] { + implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Buffer[A]] = ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]] + def newBuilder[A]: Builder[A, Buffer[A]] = new js.WrappedArray +} + +/** Explicit instantiation of the `Buffer` trait to reduce class file size in subclasses. */ +abstract class AbstractBuffer[A] extends AbstractSeq[A] with Buffer[A] diff --git a/scalalib/overrides-2.13.0-M3/scala/package.scala b/scalalib/overrides-2.13.0-M3/scala/package.scala new file mode 100644 index 0000000000..21051d473f --- /dev/null +++ b/scalalib/overrides-2.13.0-M3/scala/package.scala @@ -0,0 +1,133 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + + +/** + * Core Scala types. They are always available without an explicit import. + * @contentDiagram hideNodes "scala.Serializable" + */ +package object scala { + type Throwable = java.lang.Throwable + type Exception = java.lang.Exception + type Error = java.lang.Error + + type RuntimeException = java.lang.RuntimeException + type NullPointerException = java.lang.NullPointerException + type ClassCastException = java.lang.ClassCastException + type IndexOutOfBoundsException = java.lang.IndexOutOfBoundsException + type ArrayIndexOutOfBoundsException = java.lang.ArrayIndexOutOfBoundsException + type StringIndexOutOfBoundsException = java.lang.StringIndexOutOfBoundsException + type UnsupportedOperationException = java.lang.UnsupportedOperationException + type IllegalArgumentException = java.lang.IllegalArgumentException + type NoSuchElementException = java.util.NoSuchElementException + type NumberFormatException = java.lang.NumberFormatException + type AbstractMethodError = java.lang.AbstractMethodError + type InterruptedException = java.lang.InterruptedException + + // A dummy used by the specialization annotation. + val AnyRef = new Specializable { + override def toString = "object AnyRef" + } + + type TraversableOnce[+A] = scala.collection.TraversableOnce[A] + + type Traversable[+A] = scala.collection.Traversable[A] + val Traversable = scala.collection.Traversable + + type Iterable[+A] = scala.collection.Iterable[A] + val Iterable = scala.collection.Iterable + + type Seq[+A] = scala.collection.Seq[A] + val Seq = scala.collection.Seq + + type IndexedSeq[+A] = scala.collection.IndexedSeq[A] + val IndexedSeq = scala.collection.IndexedSeq + + type Iterator[+A] = scala.collection.Iterator[A] + val Iterator = scala.collection.Iterator + + type BufferedIterator[+A] = scala.collection.BufferedIterator[A] + + type List[+A] = scala.collection.immutable.List[A] + val List = scala.collection.immutable.List + + val Nil = scala.collection.immutable.Nil + + type ::[A] = scala.collection.immutable.::[A] + val :: = scala.collection.immutable.:: + + val +: = scala.collection.+: + val :+ = scala.collection.:+ + + type Stream[+A] = scala.collection.immutable.Stream[A] + val Stream = scala.collection.immutable.Stream + val #:: = scala.collection.immutable.Stream.#:: + + type Vector[+A] = scala.collection.immutable.Vector[A] + val Vector = scala.collection.immutable.Vector + + type StringBuilder = scala.collection.mutable.StringBuilder + val StringBuilder = scala.collection.mutable.StringBuilder + + type Range = scala.collection.immutable.Range + val Range = scala.collection.immutable.Range + + // Numeric types which were moved into scala.math.* + + type BigDecimal = scala.math.BigDecimal + lazy val BigDecimal = scala.math.BigDecimal + + type BigInt = scala.math.BigInt + lazy val BigInt = scala.math.BigInt + + type Equiv[T] = scala.math.Equiv[T] + val Equiv = scala.math.Equiv + + type Fractional[T] = scala.math.Fractional[T] + val Fractional = scala.math.Fractional + + type Integral[T] = scala.math.Integral[T] + val Integral = scala.math.Integral + + type Numeric[T] = scala.math.Numeric[T] + val Numeric = scala.math.Numeric + + type Ordered[T] = scala.math.Ordered[T] + val Ordered = scala.math.Ordered + + type Ordering[T] = scala.math.Ordering[T] + val Ordering = scala.math.Ordering + + type PartialOrdering[T] = scala.math.PartialOrdering[T] + type PartiallyOrdered[T] = scala.math.PartiallyOrdered[T] + + type Either[+A, +B] = scala.util.Either[A, B] + val Either = scala.util.Either + + type Left[+A, +B] = scala.util.Left[A, B] + val Left = scala.util.Left + + type Right[+A, +B] = scala.util.Right[A, B] + val Right = scala.util.Right + + // Annotations which we might move to annotation.* +/* + type SerialVersionUID = annotation.SerialVersionUID + type deprecated = annotation.deprecated + type deprecatedName = annotation.deprecatedName + type inline = annotation.inline + type native = annotation.native + type noinline = annotation.noinline + type remote = annotation.remote + type specialized = annotation.specialized + type transient = annotation.transient + type throws = annotation.throws + type unchecked = annotation.unchecked.unchecked + type volatile = annotation.volatile + */ +} diff --git a/scalalib/overrides-2.13.0-M3/scala/runtime/ScalaRunTime.scala b/scalalib/overrides-2.13.0-M3/scala/runtime/ScalaRunTime.scala new file mode 100644 index 0000000000..a536bd5fd6 --- /dev/null +++ b/scalalib/overrides-2.13.0-M3/scala/runtime/ScalaRunTime.scala @@ -0,0 +1,268 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala +package runtime + +import scala.collection.{ TraversableView, AbstractIterator, GenIterable } +import scala.collection.mutable.WrappedArray +import scala.collection.immutable.{ StringLike, NumericRange } +import scala.collection.generic.{ Sorted, IsTraversableLike } +import scala.reflect.{ ClassTag, classTag } +import java.lang.{ Class => jClass } + +import java.lang.reflect.{ Method => JMethod } + +/** The object ScalaRunTime provides support methods required by + * the scala runtime. All these methods should be considered + * outside the API and subject to change or removal without notice. + */ +object ScalaRunTime { + def isArray(x: Any, atLevel: Int = 1): Boolean = + x != null && isArrayClass(x.getClass, atLevel) + + private def isArrayClass(clazz: jClass[_], atLevel: Int): Boolean = + clazz != null && clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) + + // A helper method to make my life in the pattern matcher a lot easier. + def drop[Repr](coll: Repr, num: Int)(implicit traversable: IsTraversableLike[Repr]): Repr = + traversable conversion coll drop num + + /** Return the class object representing an array with element class `clazz`. + */ + def arrayClass(clazz: jClass[_]): jClass[_] = { + // newInstance throws an exception if the erasure is Void.TYPE. see SI-5680 + if (clazz == java.lang.Void.TYPE) classOf[Array[Unit]] + else java.lang.reflect.Array.newInstance(clazz, 0).getClass + } + + /** Return the class object representing an unboxed value type, + * e.g., classOf[int], not classOf[java.lang.Integer]. The compiler + * rewrites expressions like 5.getClass to come here. + */ + def anyValClass[T <: AnyVal : ClassTag](value: T): jClass[T] = + classTag[T].runtimeClass.asInstanceOf[jClass[T]] + + /** Retrieve generic array element */ + def array_apply(xs: AnyRef, idx: Int): Any = { + xs match { + case x: Array[AnyRef] => x(idx).asInstanceOf[Any] + case x: Array[Int] => x(idx).asInstanceOf[Any] + case x: Array[Double] => x(idx).asInstanceOf[Any] + case x: Array[Long] => x(idx).asInstanceOf[Any] + case x: Array[Float] => x(idx).asInstanceOf[Any] + case x: Array[Char] => x(idx).asInstanceOf[Any] + case x: Array[Byte] => x(idx).asInstanceOf[Any] + case x: Array[Short] => x(idx).asInstanceOf[Any] + case x: Array[Boolean] => x(idx).asInstanceOf[Any] + case x: Array[Unit] => x(idx).asInstanceOf[Any] + case null => throw new NullPointerException + } + } + + /** update generic array element */ + def array_update(xs: AnyRef, idx: Int, value: Any): Unit = { + xs match { + case x: Array[AnyRef] => x(idx) = value.asInstanceOf[AnyRef] + case x: Array[Int] => x(idx) = value.asInstanceOf[Int] + case x: Array[Double] => x(idx) = value.asInstanceOf[Double] + case x: Array[Long] => x(idx) = value.asInstanceOf[Long] + case x: Array[Float] => x(idx) = value.asInstanceOf[Float] + case x: Array[Char] => x(idx) = value.asInstanceOf[Char] + case x: Array[Byte] => x(idx) = value.asInstanceOf[Byte] + case x: Array[Short] => x(idx) = value.asInstanceOf[Short] + case x: Array[Boolean] => x(idx) = value.asInstanceOf[Boolean] + case x: Array[Unit] => x(idx) = value.asInstanceOf[Unit] + case null => throw new NullPointerException + } + } + + /** Get generic array length */ + def array_length(xs: AnyRef): Int = xs match { + case x: Array[AnyRef] => x.length + case x: Array[Int] => x.length + case x: Array[Double] => x.length + case x: Array[Long] => x.length + case x: Array[Float] => x.length + case x: Array[Char] => x.length + case x: Array[Byte] => x.length + case x: Array[Short] => x.length + case x: Array[Boolean] => x.length + case x: Array[Unit] => x.length + case null => throw new NullPointerException + } + + def array_clone(xs: AnyRef): AnyRef = xs match { + case x: Array[AnyRef] => x.clone() + case x: Array[Int] => x.clone() + case x: Array[Double] => x.clone() + case x: Array[Long] => x.clone() + case x: Array[Float] => x.clone() + case x: Array[Char] => x.clone() + case x: Array[Byte] => x.clone() + case x: Array[Short] => x.clone() + case x: Array[Boolean] => x.clone() + case x: Array[Unit] => x + case null => throw new NullPointerException + } + + /** Convert an array to an object array. + * Needed to deal with vararg arguments of primitive types that are passed + * to a generic Java vararg parameter T ... + */ + def toObjectArray(src: AnyRef): Array[Object] = src match { + case x: Array[AnyRef] => x + case _ => + val length = array_length(src) + val dest = new Array[Object](length) + for (i <- 0 until length) + array_update(dest, i, array_apply(src, i)) + dest + } + + def toArray[T](xs: scala.collection.Seq[T]) = { + val arr = new Array[AnyRef](xs.length) + var i = 0 + for (x <- xs) { + arr(i) = x.asInstanceOf[AnyRef] + i += 1 + } + arr + } + + // Java bug: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4071957 + // More background at ticket #2318. + def ensureAccessible(m: JMethod): JMethod = scala.reflect.ensureAccessible(m) + + def _toString(x: Product): String = + x.productIterator.mkString(x.productPrefix + "(", ",", ")") + + def _hashCode(x: Product): Int = scala.util.hashing.MurmurHash3.productHash(x) + + /** A helper for case classes. */ + def typedProductIterator[T](x: Product): Iterator[T] = { + new AbstractIterator[T] { + private var c: Int = 0 + private val cmax = x.productArity + def hasNext = c < cmax + def next() = { + val result = x.productElement(c) + c += 1 + result.asInstanceOf[T] + } + } + } + + /** Old implementation of `##`. */ + @deprecated("Use scala.runtime.Statics.anyHash instead.", "2.12.0") + def hash(x: Any): Int = Statics.anyHash(x.asInstanceOf[Object]) + + /** Given any Scala value, convert it to a String. + * + * The primary motivation for this method is to provide a means for + * correctly obtaining a String representation of a value, while + * avoiding the pitfalls of naively calling toString on said value. + * In particular, it addresses the fact that (a) toString cannot be + * called on null and (b) depending on the apparent type of an + * array, toString may or may not print it in a human-readable form. + * + * @param arg the value to stringify + * @return a string representation of arg. + */ + def stringOf(arg: Any): String = stringOf(arg, scala.Int.MaxValue) + def stringOf(arg: Any, maxElements: Int): String = { + def packageOf(x: AnyRef) = x.getClass.getPackage match { + case null => "" + case p => p.getName + } + def isScalaClass(x: AnyRef) = packageOf(x) startsWith "scala." + def isScalaCompilerClass(x: AnyRef) = packageOf(x) startsWith "scala.tools.nsc." + + // includes specialized subclasses and future proofed against hypothetical TupleN (for N > 22) + def isTuple(x: Any) = x != null && x.getClass.getName.startsWith("scala.Tuple") + + // We use reflection because the scala.xml package might not be available + def isSubClassOf(potentialSubClass: Class[_], ofClass: String) = + try { + val classLoader = potentialSubClass.getClassLoader + val clazz = Class.forName(ofClass, /*initialize =*/ false, classLoader) + clazz.isAssignableFrom(potentialSubClass) + } catch { + case cnfe: ClassNotFoundException => false + } + def isXmlNode(potentialSubClass: Class[_]) = isSubClassOf(potentialSubClass, "scala.xml.Node") + def isXmlMetaData(potentialSubClass: Class[_]) = isSubClassOf(potentialSubClass, "scala.xml.MetaData") + + // When doing our own iteration is dangerous + def useOwnToString(x: Any) = x match { + // Range/NumericRange have a custom toString to avoid walking a gazillion elements + case _: Range | _: NumericRange[_] => true + // Sorted collections to the wrong thing (for us) on iteration - ticket #3493 + case _: Sorted[_, _] => true + // StringBuilder(a, b, c) and similar not so attractive + case _: StringLike[_] => true + // Don't want to evaluate any elements in a view + case _: TraversableView[_, _] => true + // Node extends NodeSeq extends Seq[Node] and MetaData extends Iterable[MetaData] + // -> catch those by isXmlNode and isXmlMetaData. + // Don't want to a) traverse infinity or b) be overly helpful with peoples' custom + // collections which may have useful toString methods - ticket #3710 + // or c) print AbstractFiles which are somehow also Iterable[AbstractFile]s. + case x: Traversable[_] => !x.hasDefiniteSize || !isScalaClass(x) || isScalaCompilerClass(x) || isXmlNode(x.getClass) || isXmlMetaData(x.getClass) + // Otherwise, nothing could possibly go wrong + case _ => false + } + + // A variation on inner for maps so they print -> instead of bare tuples + def mapInner(arg: Any): String = arg match { + case (k, v) => inner(k) + " -> " + inner(v) + case _ => inner(arg) + } + + // Special casing Unit arrays, the value class which uses a reference array type. + def arrayToString(x: AnyRef) = { + if (x.getClass.getComponentType == classOf[BoxedUnit]) + 0 until (array_length(x) min maxElements) map (_ => "()") mkString ("Array(", ", ", ")") + else + WrappedArray make x take maxElements map inner mkString ("Array(", ", ", ")") + } + + // The recursively applied attempt to prettify Array printing. + // Note that iterator is used if possible and foreach is used as a + // last resort, because the parallel collections "foreach" in a + // random order even on sequences. + def inner(arg: Any): String = arg match { + case null => "null" + case "" => "\"\"" + case x: String => if (x.head.isWhitespace || x.last.isWhitespace) "\"" + x + "\"" else x + case x if useOwnToString(x) => x.toString + case x: AnyRef if isArray(x) => arrayToString(x) + case x: scala.collection.Map[_, _] => x.iterator take maxElements map mapInner mkString (x.stringPrefix + "(", ", ", ")") + case x: GenIterable[_] => x.iterator take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")") + case x: Traversable[_] => x take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")") + case x: Product1[_] if isTuple(x) => "(" + inner(x._1) + ",)" // that special trailing comma + case x: Product if isTuple(x) => x.productIterator map inner mkString ("(", ",", ")") + case x => x.toString + } + + // The try/catch is defense against iterables which aren't actually designed + // to be iterated, such as some scala.tools.nsc.io.AbstractFile derived classes. + try inner(arg) + catch { + case _: UnsupportedOperationException | _: AssertionError => "" + arg + } + } + + /** stringOf formatted for use in a repl result. */ + def replStringOf(arg: Any, maxElements: Int): String = { + val s = stringOf(arg, maxElements) + val nl = if (s contains "\n") "\n" else "" + + nl + s + "\n" + } +} From 3ff66dabe9334d1fb289eb41a08820b56042d696 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Mon, 26 Mar 2018 10:47:15 +0200 Subject: [PATCH 0736/2665] Remove VirtualFileContainer We inline the implementations for the JVM and Node.js into the respective implementations of ScalaJSIRContainer. This even simplifies their implementation. --- .../org/scalajs/io/NodeVirtualFiles.scala | 61 +------------------ .../org/scalajs/io/FileVirtualFiles.scala | 3 - .../scala/org/scalajs/io/VirtualJarFile.scala | 32 ---------- .../scala/org/scalajs/io/VirtualFiles.scala | 20 ------ .../linker/irio/NodeVirtualIRFiles.scala | 36 +++++++++-- .../linker/irio/FileVirtualIRFiles.scala | 48 +++++++++++++-- .../scalajs/linker/irio/VirtualIRFiles.scala | 16 ----- 7 files changed, 77 insertions(+), 139 deletions(-) delete mode 100644 io/jvm/src/main/scala/org/scalajs/io/VirtualJarFile.scala diff --git a/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala b/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala index 53b048f22d..e69a9a2fd5 100644 --- a/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala +++ b/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala @@ -60,7 +60,7 @@ private[io] object NodeSupport { @JSImport("fs", JSImport.Namespace) @js.native -private[io] object NodeFS extends js.Object { +private[scalajs] object NodeFS extends js.Object { trait Enc extends js.Object { val encoding: String } @@ -75,65 +75,6 @@ private[io] object NodeFS extends js.Object { def writeFileSync(path: String, data: String, enc: Enc): Unit = js.native } -private[scalajs] class NodeVirtualJarFile(file: String) - extends NodeVirtualBinaryFile(file) with VirtualFileContainer { - - import NodeVirtualJarFile._ - - 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() - } - } -} - -private object NodeVirtualJarFile { - @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 - } -} - private[io] class NodeWriter(path: String) extends StringWriter { override def close(): Unit = { super.close() diff --git a/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala b/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala index e48920b9f0..fe33b8b753 100644 --- a/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala +++ b/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala @@ -148,6 +148,3 @@ object WritableFileVirtualJSFile { def apply(f: File): WritableFileVirtualJSFile = new FileVirtualJSFile(f) with WritableFileVirtualJSFile } - -class FileVirtualJarFile(file: File) - extends FileVirtualBinaryFile(file) with VirtualJarFile diff --git a/io/jvm/src/main/scala/org/scalajs/io/VirtualJarFile.scala b/io/jvm/src/main/scala/org/scalajs/io/VirtualJarFile.scala deleted file mode 100644 index e18e91b52f..0000000000 --- a/io/jvm/src/main/scala/org/scalajs/io/VirtualJarFile.scala +++ /dev/null @@ -1,32 +0,0 @@ -package org.scalajs.io - -import java.io._ -import java.util.zip.{ZipInputStream, ZipEntry} - -/** A virtual jar file. */ -trait VirtualJarFile extends VirtualFileContainer with VirtualBinaryFile { - import VirtualJarFile._ - - def listEntries[T](p: String => Boolean)( - makeResult: (String, InputStream) => T): List[T] = { - val stream = new ZipInputStream(inputStream) - try { - val streamIgnoreClose = new IgnoreCloseFilterInputStream(stream) - Iterator.continually(stream.getNextEntry()) - .takeWhile(_ != null) - .filter(entry => p(entry.getName)) - .map(entry => makeResult(entry.getName, streamIgnoreClose)) - .toList - } finally { - stream.close() - } - } -} - -private object VirtualJarFile { - private final class IgnoreCloseFilterInputStream(in: InputStream) - extends FilterInputStream(in) { - - override def close(): Unit = () - } -} diff --git a/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala b/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala index dea7bf4201..14ecad887a 100644 --- a/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala +++ b/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala @@ -95,23 +95,3 @@ object VirtualJSFile { trait WritableVirtualJSFile extends WritableVirtualTextFile with VirtualJSFile { def sourceMapWriter: Writer } - -/** A virtual file container. - * - * This is a generic virtual container for embedded virtual files, especially - * one found on a classpath such as a jar. - */ -trait VirtualFileContainer extends VirtualFile { - /** Lists the entries of this container that satisfy a given predicate. - * - * @param p - * Predicate on the relative path of files to select. - * @param makeResult - * Function building an element of the result list for an entry, given - * its relative path an `InputStream` of the content. `makeResult` may - * `close()` the input stream, but it is not mandatory. In any case, the - * input stream cannot be used after `makeResult` returns. - */ - def listEntries[T](p: String => Boolean)( - makeResult: (String, InputStream) => T): List[T] -} diff --git a/linker/js/src/main/scala/org/scalajs/linker/irio/NodeVirtualIRFiles.scala b/linker/js/src/main/scala/org/scalajs/linker/irio/NodeVirtualIRFiles.scala index 53e028f146..4cd8af2b4f 100644 --- a/linker/js/src/main/scala/org/scalajs/linker/irio/NodeVirtualIRFiles.scala +++ b/linker/js/src/main/scala/org/scalajs/linker/irio/NodeVirtualIRFiles.scala @@ -10,12 +10,40 @@ package org.scalajs.linker.irio import org.scalajs.io._ +import scala.scalajs.js +import scala.scalajs.js.annotation.JSImport +import scala.scalajs.js.typedarray._ + class NodeVirtualScalaJSIRFile(p: String, val relativePath: String) extends NodeVirtualBinaryFile(p) with VirtualSerializedScalaJSIRFile -private[scalajs] class NodeVirtualJarScalaJSIRContainer(file: String) - extends NodeVirtualJarFile(file) with ScalaJSIRContainer { +private[scalajs] class NodeVirtualJarScalaJSIRContainer(path: String) + extends NodeVirtualFile(path) with ScalaJSIRContainer { + import NodeVirtualJarScalaJSIRContainer.JSZip + + def sjsirFiles: List[VirtualScalaJSIRFile] = { + val zip = new JSZip(NodeFS.readFileSync(path)) + + for { + (name, entry) <- zip.files.toList + if name.endsWith(".sjsir") + } yield { + val path = s"${this.path}:$name" + new MemVirtualSerializedScalaJSIRFile(path, name) + .withContent(new Int8Array(entry.asArrayBuffer()).toArray) + .withVersion(this.version) + } + } +} + +private object NodeVirtualJarScalaJSIRContainer { + @js.native + @JSImport("jszip", JSImport.Default) + private class JSZip(data: js.Array[Int]) extends js.Object { + def files: js.Dictionary[JSZipEntry] = js.native + } - def sjsirFiles: List[VirtualScalaJSIRFile] = - ScalaJSIRContainer.sjsirFilesIn(this) + private trait JSZipEntry extends js.Object { + def asArrayBuffer(): ArrayBuffer + } } diff --git a/linker/jvm/src/main/scala/org/scalajs/linker/irio/FileVirtualIRFiles.scala b/linker/jvm/src/main/scala/org/scalajs/linker/irio/FileVirtualIRFiles.scala index cc32c5b237..313902816c 100644 --- a/linker/jvm/src/main/scala/org/scalajs/linker/irio/FileVirtualIRFiles.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/irio/FileVirtualIRFiles.scala @@ -9,6 +9,9 @@ package org.scalajs.linker.irio import java.io._ +import java.util.zip.{ZipInputStream, ZipEntry} + +import scala.annotation.tailrec import org.scalajs.io._ @@ -61,9 +64,46 @@ object FileScalaJSIRContainer { } } -class FileVirtualJarScalaJSIRContainer(file: File) - extends FileVirtualJarFile(file) with ScalaJSIRContainer { +final class FileVirtualJarScalaJSIRContainer(file: File) + extends FileVirtualFile(file) with ScalaJSIRContainer { + def sjsirFiles: List[VirtualScalaJSIRFile] = { + val stream = new ZipInputStream(new BufferedInputStream(new FileInputStream(file))) + try { + val buf = new Array[Byte](4096) + + @tailrec + def readAll(out: OutputStream): Unit = { + val read = stream.read(buf) + if (read != -1) { + out.write(buf, 0, read) + readAll(out) + } + } + + def makeVF(e: ZipEntry) = { + val size = e.getSize + val out = + if (0 <= size && size <= Int.MaxValue) new ByteArrayOutputStream(size.toInt) + else new ByteArrayOutputStream() - def sjsirFiles: List[VirtualScalaJSIRFile] = - ScalaJSIRContainer.sjsirFilesIn(this) + try { + readAll(out) + val path = s"${this.path}:${e.getName}" + new MemVirtualSerializedScalaJSIRFile(path, e.getName) + .withContent(out.toByteArray) + .withVersion(this.version) + } finally { + out.close() + } + } + + Iterator.continually(stream.getNextEntry()) + .takeWhile(_ != null) + .filter(_.getName.endsWith(".sjsir")) + .map(makeVF) + .toList + } finally { + stream.close() + } + } } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/irio/VirtualIRFiles.scala b/linker/shared/src/main/scala/org/scalajs/linker/irio/VirtualIRFiles.scala index abb0537a14..29c69363ae 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/irio/VirtualIRFiles.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/irio/VirtualIRFiles.scala @@ -29,22 +29,6 @@ trait ScalaJSIRContainer extends VirtualFile { def sjsirFiles: List[VirtualScalaJSIRFile] } -object ScalaJSIRContainer { - def sjsirFilesIn( - container: VirtualFileContainer): List[VirtualScalaJSIRFile] = { - container.listEntries(_.endsWith(".sjsir")) { (relPath, stream) => - val file = new EntryIRFile(container.path, relPath) - file.content = IO.readInputStreamToByteArray(stream) - file.version = container.version - file - } - } - - private class EntryIRFile(outerPath: String, relativePath: String) - extends MemVirtualSerializedScalaJSIRFile(s"$outerPath:$relativePath", relativePath) - with VirtualScalaJSIRFile -} - /** A virtual Scala.js IR file. * It contains the class info and the IR tree. */ From 3dd7f2deec7db50455df45d7b8b74dec6c2039e3 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Tue, 24 Apr 2018 10:15:04 +0200 Subject: [PATCH 0737/2665] Add files to amend to the overrides-2.13/ directory. They were taken from the commit a0026305125dcc814097b1fbb798fe925ca9f81f in scala/scala. --- scalalib/overrides-2.13/scala/Array.scala | 624 ++++++++++++++++++ .../overrides-2.13/scala/Enumeration.scala | 314 +++++++++ .../scala/runtime/ScalaRunTime.scala | 282 ++++++++ 3 files changed, 1220 insertions(+) create mode 100644 scalalib/overrides-2.13/scala/Array.scala create mode 100644 scalalib/overrides-2.13/scala/Enumeration.scala create mode 100644 scalalib/overrides-2.13/scala/runtime/ScalaRunTime.scala diff --git a/scalalib/overrides-2.13/scala/Array.scala b/scalalib/overrides-2.13/scala/Array.scala new file mode 100644 index 0000000000..5da40c0e6a --- /dev/null +++ b/scalalib/overrides-2.13/scala/Array.scala @@ -0,0 +1,624 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala + +//import scala.collection.generic._ +import scala.collection.{Factory, immutable, mutable} +import mutable.ArrayBuilder +import immutable.ArraySeq +import scala.language.implicitConversions +import scala.reflect.ClassTag +import scala.runtime.ScalaRunTime +import scala.runtime.ScalaRunTime.{array_apply, array_update} + +/** Utility methods for operating on arrays. + * For example: + * {{{ + * val a = Array(1, 2) + * val b = Array.ofDim[Int](2) + * val c = Array.concat(a, b) + * }}} + * where the array objects `a`, `b` and `c` have respectively the values + * `Array(1, 2)`, `Array(0, 0)` and `Array(1, 2, 0, 0)`. + * + * @author Martin Odersky + * @version 1.0 + */ +object Array { + val emptyBooleanArray = new Array[Boolean](0) + val emptyByteArray = new Array[Byte](0) + val emptyCharArray = new Array[Char](0) + val emptyDoubleArray = new Array[Double](0) + val emptyFloatArray = new Array[Float](0) + val emptyIntArray = new Array[Int](0) + val emptyLongArray = new Array[Long](0) + val emptyShortArray = new Array[Short](0) + val emptyObjectArray = new Array[Object](0) + + /** Provides an implicit conversion from the Array object to a collection Factory */ + implicit def toFactory[A : ClassTag](dummy: Array.type): Factory[A, Array[A]] = + new Factory[A, Array[A]] { + def fromSpecific(it: IterableOnce[A]): Array[A] = Array.from[A](it) + def newBuilder: mutable.Builder[A, Array[A]] = Array.newBuilder[A] + } + + /** + * Returns a new [[scala.collection.mutable.ArrayBuilder]]. + */ + def newBuilder[T](implicit t: ClassTag[T]): ArrayBuilder[T] = ArrayBuilder.make[T](t) + + def from[A : ClassTag](it: IterableOnce[A]): Array[A] = { + val n = it.knownSize + if (n > -1) { + val elements = new Array[A](n) + val iterator = it.iterator + var i = 0 + while (i < n) { + ScalaRunTime.array_update(elements, i, iterator.next()) + i = i + 1 + } + elements + } else { + val b = ArrayBuilder.make[A] + val iterator = it.iterator + while (iterator.hasNext) + b += iterator.next() + b.result() + } + } + + private def slowcopy(src : AnyRef, + srcPos : Int, + dest : AnyRef, + destPos : Int, + length : Int) { + var i = srcPos + var j = destPos + val srcUntil = srcPos + length + while (i < srcUntil) { + array_update(dest, j, array_apply(src, i)) + i += 1 + j += 1 + } + } + + /** Copy one array to another. + * Equivalent to Java's + * `System.arraycopy(src, srcPos, dest, destPos, length)`, + * except that this also works for polymorphic and boxed arrays. + * + * Note that the passed-in `dest` array will be modified by this call. + * + * @param src the source array. + * @param srcPos starting position in the source array. + * @param dest destination array. + * @param destPos starting position in the destination array. + * @param length the number of array elements to be copied. + * + * @see `java.lang.System#arraycopy` + */ + def copy(src: AnyRef, srcPos: Int, dest: AnyRef, destPos: Int, length: Int) { + val srcClass = src.getClass + if (srcClass.isArray && dest.getClass.isAssignableFrom(srcClass)) + java.lang.System.arraycopy(src, srcPos, dest, destPos, length) + else + slowcopy(src, srcPos, dest, destPos, length) + } + + /** Copy one array to another, truncating or padding with default values (if + * necessary) so the copy has the specified length. + * + * Equivalent to Java's + * `java.util.Arrays.copyOf(original, newLength)`, + * except that this works for primitive and object arrays in a single method. + * + * @see `java.util.Arrays#copyOf` + */ + def copyOf[A](original: Array[A], newLength: Int): Array[A] = (original match { + case x: Array[AnyRef] => java.util.Arrays.copyOf(x, newLength) + case x: Array[Int] => java.util.Arrays.copyOf(x, newLength) + case x: Array[Double] => java.util.Arrays.copyOf(x, newLength) + case x: Array[Long] => java.util.Arrays.copyOf(x, newLength) + case x: Array[Float] => java.util.Arrays.copyOf(x, newLength) + case x: Array[Char] => java.util.Arrays.copyOf(x, newLength) + case x: Array[Byte] => java.util.Arrays.copyOf(x, newLength) + case x: Array[Short] => java.util.Arrays.copyOf(x, newLength) + case x: Array[Boolean] => java.util.Arrays.copyOf(x, newLength) + case x: Array[Unit] => + val dest = new Array[Unit](newLength) + Array.copy(original, 0, dest, 0, original.length) + dest + }).asInstanceOf[Array[A]] + + /** Copy one array to another, truncating or padding with default values (if + * necessary) so the copy has the specified length. The new array can have + * a different type than the original one as long as the values are + * assignment-compatible. When copying between primitive and object arrays, + * boxing and unboxing are supported. + * + * Equivalent to Java's + * `java.util.Arrays.copyOf(original, newLength, newType)`, + * except that this works for all combinations of primitive and object arrays + * in a single method. + * + * @see `java.util.Arrays#copyOf` + */ + def copyAs[A](original: Array[_], newLength: Int)(implicit ct: ClassTag[A]): Array[A] = { + val destClass = ct.runtimeClass.asInstanceOf[Class[A]] + if (destClass.isAssignableFrom(original.getClass.getComponentType)) { + if(destClass.isPrimitive) copyOf[A](original.asInstanceOf[Array[A]], newLength) + else java.util.Arrays.copyOf(original.asInstanceOf[Array[AnyRef]], newLength, getArrayClass(destClass).asInstanceOf[Class[Array[AnyRef]]]).asInstanceOf[Array[A]] + } else { + val dest = new Array[A](newLength) + Array.copy(original, 0, dest, 0, original.length) + dest + } + } + + private def getArrayClass[A](c: Class[A]): Class[Array[A]] = { + if(c eq classOf[Int]) classOf[Array[Int]] + else if(c eq classOf[Long]) classOf[Array[Long]] + else if(c eq classOf[Char]) classOf[Array[Char]] + else if(c eq classOf[Boolean]) classOf[Array[Boolean]] + else if(c eq classOf[Double]) classOf[Array[Double]] + else if(c eq classOf[Byte]) classOf[Array[Byte]] + else if(c eq classOf[Float]) classOf[Array[Float]] + else if(c eq classOf[Short]) classOf[Array[Short]] + else Class.forName(if(c.isArray) "["+c.getName else "[L"+c.getName+";", true, c.getClassLoader) + }.asInstanceOf[Class[Array[A]]] + + /** Returns an array of length 0 */ + def empty[T: ClassTag]: Array[T] = new Array[T](0) + + /** Creates an array with given elements. + * + * @param xs the elements to put in the array + * @return an array containing all elements from xs. + */ + // Subject to a compiler optimization in Cleanup. + // Array(e0, ..., en) is translated to { val a = new Array(3); a(i) = ei; a } + def apply[T: ClassTag](xs: T*): Array[T] = { + val array = new Array[T](xs.length) + var i = 0 + for (x <- xs.iterator) { array(i) = x; i += 1 } + array + } + + /** Creates an array of `Boolean` objects */ + // Subject to a compiler optimization in Cleanup, see above. + def apply(x: Boolean, xs: Boolean*): Array[Boolean] = { + val array = new Array[Boolean](xs.length + 1) + array(0) = x + var i = 1 + for (x <- xs.iterator) { array(i) = x; i += 1 } + array + } + + /** Creates an array of `Byte` objects */ + // Subject to a compiler optimization in Cleanup, see above. + def apply(x: Byte, xs: Byte*): Array[Byte] = { + val array = new Array[Byte](xs.length + 1) + array(0) = x + var i = 1 + for (x <- xs.iterator) { array(i) = x; i += 1 } + array + } + + /** Creates an array of `Short` objects */ + // Subject to a compiler optimization in Cleanup, see above. + def apply(x: Short, xs: Short*): Array[Short] = { + val array = new Array[Short](xs.length + 1) + array(0) = x + var i = 1 + for (x <- xs.iterator) { array(i) = x; i += 1 } + array + } + + /** Creates an array of `Char` objects */ + // Subject to a compiler optimization in Cleanup, see above. + def apply(x: Char, xs: Char*): Array[Char] = { + val array = new Array[Char](xs.length + 1) + array(0) = x + var i = 1 + for (x <- xs.iterator) { array(i) = x; i += 1 } + array + } + + /** Creates an array of `Int` objects */ + // Subject to a compiler optimization in Cleanup, see above. + def apply(x: Int, xs: Int*): Array[Int] = { + val array = new Array[Int](xs.length + 1) + array(0) = x + var i = 1 + for (x <- xs.iterator) { array(i) = x; i += 1 } + array + } + + /** Creates an array of `Long` objects */ + // Subject to a compiler optimization in Cleanup, see above. + def apply(x: Long, xs: Long*): Array[Long] = { + val array = new Array[Long](xs.length + 1) + array(0) = x + var i = 1 + for (x <- xs.iterator) { array(i) = x; i += 1 } + array + } + + /** Creates an array of `Float` objects */ + // Subject to a compiler optimization in Cleanup, see above. + def apply(x: Float, xs: Float*): Array[Float] = { + val array = new Array[Float](xs.length + 1) + array(0) = x + var i = 1 + for (x <- xs.iterator) { array(i) = x; i += 1 } + array + } + + /** Creates an array of `Double` objects */ + // Subject to a compiler optimization in Cleanup, see above. + def apply(x: Double, xs: Double*): Array[Double] = { + val array = new Array[Double](xs.length + 1) + array(0) = x + var i = 1 + for (x <- xs.iterator) { array(i) = x; i += 1 } + array + } + + /** Creates an array of `Unit` objects */ + def apply(x: Unit, xs: Unit*): Array[Unit] = { + val array = new Array[Unit](xs.length + 1) + array(0) = x + var i = 1 + for (x <- xs.iterator) { array(i) = x; i += 1 } + array + } + + /** Creates array with given dimensions */ + def ofDim[T: ClassTag](n1: Int): Array[T] = + new Array[T](n1) + /** Creates a 2-dimensional array */ + def ofDim[T: ClassTag](n1: Int, n2: Int): Array[Array[T]] = { + val arr: Array[Array[T]] = (new Array[Array[T]](n1): Array[Array[T]]) + for (i <- 0 until n1) arr(i) = new Array[T](n2) + arr + // tabulate(n1)(_ => ofDim[T](n2)) + } + /** Creates a 3-dimensional array */ + def ofDim[T: ClassTag](n1: Int, n2: Int, n3: Int): Array[Array[Array[T]]] = + tabulate(n1)(_ => ofDim[T](n2, n3)) + /** Creates a 4-dimensional array */ + def ofDim[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int): Array[Array[Array[Array[T]]]] = + tabulate(n1)(_ => ofDim[T](n2, n3, n4)) + /** Creates a 5-dimensional array */ + def ofDim[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int): Array[Array[Array[Array[Array[T]]]]] = + tabulate(n1)(_ => ofDim[T](n2, n3, n4, n5)) + + /** Concatenates all arrays into a single array. + * + * @param xss the given arrays + * @return the array created from concatenating `xss` + */ + def concat[T: ClassTag](xss: Array[T]*): Array[T] = { + val b = newBuilder[T] + b.sizeHint(xss.map(_.length).sum) + for (xs <- xss) b ++= xs + b.result() + } + + /** Returns an array that contains the results of some element computation a number + * of times. + * + * Note that this means that `elem` is computed a total of n times: + * {{{ + * scala> Array.fill(3){ math.random } + * res3: Array[Double] = Array(0.365461167592537, 1.550395944913685E-4, 0.7907242137333306) + * }}} + * + * @param n the number of elements desired + * @param elem the element computation + * @return an Array of size n, where each element contains the result of computing + * `elem`. + */ + def fill[T: ClassTag](n: Int)(elem: => T): Array[T] = { + val b = newBuilder[T] + b.sizeHint(n) + var i = 0 + while (i < n) { + b += elem + i += 1 + } + b.result() + } + + /** Returns a two-dimensional array that contains the results of some element + * computation a number of times. + * + * @param n1 the number of elements in the 1st dimension + * @param n2 the number of elements in the 2nd dimension + * @param elem the element computation + */ + def fill[T: ClassTag](n1: Int, n2: Int)(elem: => T): Array[Array[T]] = + tabulate(n1)(_ => fill(n2)(elem)) + + /** Returns a three-dimensional array that contains the results of some element + * computation a number of times. + * + * @param n1 the number of elements in the 1st dimension + * @param n2 the number of elements in the 2nd dimension + * @param n3 the number of elements in the 3nd dimension + * @param elem the element computation + */ + def fill[T: ClassTag](n1: Int, n2: Int, n3: Int)(elem: => T): Array[Array[Array[T]]] = + tabulate(n1)(_ => fill(n2, n3)(elem)) + + /** Returns a four-dimensional array that contains the results of some element + * computation a number of times. + * + * @param n1 the number of elements in the 1st dimension + * @param n2 the number of elements in the 2nd dimension + * @param n3 the number of elements in the 3nd dimension + * @param n4 the number of elements in the 4th dimension + * @param elem the element computation + */ + def fill[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int)(elem: => T): Array[Array[Array[Array[T]]]] = + tabulate(n1)(_ => fill(n2, n3, n4)(elem)) + + /** Returns a five-dimensional array that contains the results of some element + * computation a number of times. + * + * @param n1 the number of elements in the 1st dimension + * @param n2 the number of elements in the 2nd dimension + * @param n3 the number of elements in the 3nd dimension + * @param n4 the number of elements in the 4th dimension + * @param n5 the number of elements in the 5th dimension + * @param elem the element computation + */ + def fill[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(elem: => T): Array[Array[Array[Array[Array[T]]]]] = + tabulate(n1)(_ => fill(n2, n3, n4, n5)(elem)) + + /** Returns an array containing values of a given function over a range of integer + * values starting from 0. + * + * @param n The number of elements in the array + * @param f The function computing element values + * @return A traversable consisting of elements `f(0),f(1), ..., f(n - 1)` + */ + def tabulate[T: ClassTag](n: Int)(f: Int => T): Array[T] = { + val b = newBuilder[T] + b.sizeHint(n) + var i = 0 + while (i < n) { + b += f(i) + i += 1 + } + b.result() + } + + /** Returns a two-dimensional array containing values of a given function + * over ranges of integer values starting from `0`. + * + * @param n1 the number of elements in the 1st dimension + * @param n2 the number of elements in the 2nd dimension + * @param f The function computing element values + */ + def tabulate[T: ClassTag](n1: Int, n2: Int)(f: (Int, Int) => T): Array[Array[T]] = + tabulate(n1)(i1 => tabulate(n2)(f(i1, _))) + + /** Returns a three-dimensional array containing values of a given function + * over ranges of integer values starting from `0`. + * + * @param n1 the number of elements in the 1st dimension + * @param n2 the number of elements in the 2nd dimension + * @param n3 the number of elements in the 3rd dimension + * @param f The function computing element values + */ + def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int)(f: (Int, Int, Int) => T): Array[Array[Array[T]]] = + tabulate(n1)(i1 => tabulate(n2, n3)(f(i1, _, _))) + + /** Returns a four-dimensional array containing values of a given function + * over ranges of integer values starting from `0`. + * + * @param n1 the number of elements in the 1st dimension + * @param n2 the number of elements in the 2nd dimension + * @param n3 the number of elements in the 3rd dimension + * @param n4 the number of elements in the 4th dimension + * @param f The function computing element values + */ + def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int)(f: (Int, Int, Int, Int) => T): Array[Array[Array[Array[T]]]] = + tabulate(n1)(i1 => tabulate(n2, n3, n4)(f(i1, _, _, _))) + + /** Returns a five-dimensional array containing values of a given function + * over ranges of integer values starting from `0`. + * + * @param n1 the number of elements in the 1st dimension + * @param n2 the number of elements in the 2nd dimension + * @param n3 the number of elements in the 3rd dimension + * @param n4 the number of elements in the 4th dimension + * @param n5 the number of elements in the 5th dimension + * @param f The function computing element values + */ + def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(f: (Int, Int, Int, Int, Int) => T): Array[Array[Array[Array[Array[T]]]]] = + tabulate(n1)(i1 => tabulate(n2, n3, n4, n5)(f(i1, _, _, _, _))) + + /** Returns an array containing a sequence of increasing integers in a range. + * + * @param start the start value of the array + * @param end the end value of the array, exclusive (in other words, this is the first value '''not''' returned) + * @return the array with values in range `start, start + 1, ..., end - 1` + * up to, but excluding, `end`. + */ + def range(start: Int, end: Int): Array[Int] = range(start, end, 1) + + /** Returns an array containing equally spaced values in some integer interval. + * + * @param start the start value of the array + * @param end the end value of the array, exclusive (in other words, this is the first value '''not''' returned) + * @param step the increment value of the array (may not be zero) + * @return the array with values in `start, start + step, ...` up to, but excluding `end` + */ + def range(start: Int, end: Int, step: Int): Array[Int] = { + if (step == 0) throw new IllegalArgumentException("zero step") + val b = newBuilder[Int] + b.sizeHint(immutable.Range.count(start, end, step, isInclusive = false)) + + var i = start + while (if (step < 0) end < i else i < end) { + b += i + i += step + } + b.result() + } + + /** Returns an array containing repeated applications of a function to a start value. + * + * @param start the start value of the array + * @param len the number of elements returned by the array + * @param f the function that is repeatedly applied + * @return the array returning `len` values in the sequence `start, f(start), f(f(start)), ...` + */ + def iterate[T: ClassTag](start: T, len: Int)(f: T => T): Array[T] = { + val b = newBuilder[T] + + if (len > 0) { + b.sizeHint(len) + var acc = start + var i = 1 + b += acc + + while (i < len) { + acc = f(acc) + i += 1 + b += acc + } + } + b.result() + } + + /** Called in a pattern match like `{ case Array(x,y,z) => println('3 elements')}`. + * + * @param x the selector value + * @return sequence wrapped in a [[scala.Some]], if `x` is an Array, otherwise `None` + */ + def unapplySeq[T](x: Array[T]): Option[IndexedSeq[T]] = + if (x == null) None else Some(ArraySeq.unsafeWrapArray[T](x)) + // !!! the null check should to be necessary, but without it 2241 fails. Seems to be a bug + // in pattern matcher. @PP: I noted in #4364 I think the behavior is correct. + // Is ArraySeq safe here? In 2.12 we used to call .toIndexedSeq which copied the array + // instead of wrapping it in a ArraySeq but it appears unnecessary. +} + +/** Arrays are mutable, indexed collections of values. `Array[T]` is Scala's representation + * for Java's `T[]`. + * + * {{{ + * val numbers = Array(1, 2, 3, 4) + * val first = numbers(0) // read the first element + * numbers(3) = 100 // replace the 4th array element with 100 + * val biggerNumbers = numbers.map(_ * 2) // multiply all numbers by two + * }}} + * + * Arrays make use of two common pieces of Scala syntactic sugar, shown on lines 2 and 3 of the above + * example code. + * Line 2 is translated into a call to `apply(Int)`, while line 3 is translated into a call to + * `update(Int, T)`. + * + * Two implicit conversions exist in [[scala.Predef]] that are frequently applied to arrays: a conversion + * to [[scala.collection.mutable.ArrayOps]] (shown on line 4 of the example above) and a conversion + * to [[scala.collection.mutable.ArraySeq]] (a subtype of [[scala.collection.Seq]]). + * Both types make available many of the standard operations found in the Scala collections API. + * The conversion to `ArrayOps` is temporary, as all operations defined on `ArrayOps` return an `Array`, + * while the conversion to `ArraySeq` is permanent as all operations return a `ArraySeq`. + * + * The conversion to `ArrayOps` takes priority over the conversion to `ArraySeq`. For instance, + * consider the following code: + * + * {{{ + * val arr = Array(1, 2, 3) + * val arrReversed = arr.reverse + * val seqReversed : Seq[Int] = arr.reverse + * }}} + * + * Value `arrReversed` will be of type `Array[Int]`, with an implicit conversion to `ArrayOps` occurring + * to perform the `reverse` operation. The value of `seqReversed`, on the other hand, will be computed + * by converting to `ArraySeq` first and invoking the variant of `reverse` that returns another + * `ArraySeq`. + * + * @author Martin Odersky + * @version 1.0 + * @see [[http://www.scala-lang.org/files/archive/spec/2.11/ Scala Language Specification]], for in-depth information on the transformations the Scala compiler makes on Arrays (Sections 6.6 and 6.15 respectively.) + * @see [[http://docs.scala-lang.org/sips/completed/scala-2-8-arrays.html "Scala 2.8 Arrays"]] the Scala Improvement Document detailing arrays since Scala 2.8. + * @see [[http://docs.scala-lang.org/overviews/collections/arrays.html "The Scala 2.8 Collections' API"]] section on `Array` by Martin Odersky for more information. + * @hideImplicitConversion scala.Predef.booleanArrayOps + * @hideImplicitConversion scala.Predef.byteArrayOps + * @hideImplicitConversion scala.Predef.charArrayOps + * @hideImplicitConversion scala.Predef.doubleArrayOps + * @hideImplicitConversion scala.Predef.floatArrayOps + * @hideImplicitConversion scala.Predef.intArrayOps + * @hideImplicitConversion scala.Predef.longArrayOps + * @hideImplicitConversion scala.Predef.refArrayOps + * @hideImplicitConversion scala.Predef.shortArrayOps + * @hideImplicitConversion scala.Predef.unitArrayOps + * @hideImplicitConversion scala.LowPriorityImplicits.wrapRefArray + * @hideImplicitConversion scala.LowPriorityImplicits.wrapIntArray + * @hideImplicitConversion scala.LowPriorityImplicits.wrapDoubleArray + * @hideImplicitConversion scala.LowPriorityImplicits.wrapLongArray + * @hideImplicitConversion scala.LowPriorityImplicits.wrapFloatArray + * @hideImplicitConversion scala.LowPriorityImplicits.wrapCharArray + * @hideImplicitConversion scala.LowPriorityImplicits.wrapByteArray + * @hideImplicitConversion scala.LowPriorityImplicits.wrapShortArray + * @hideImplicitConversion scala.LowPriorityImplicits.wrapBooleanArray + * @hideImplicitConversion scala.LowPriorityImplicits.wrapUnitArray + * @hideImplicitConversion scala.LowPriorityImplicits.genericWrapArray + * @define coll array + * @define Coll `Array` + * @define orderDependent + * @define orderDependentFold + * @define mayNotTerminateInf + * @define willNotTerminateInf + * @define collectExample + * @define undefinedorder + * @define thatinfo the class of the returned collection. In the standard library configuration, + * `That` is either `Array[B]` if an ClassTag is available for B or `ArraySeq[B]` otherwise. + * @define zipthatinfo $thatinfo + * @define bfinfo an implicit value of class `CanBuildFrom` which determines the result class `That` from the current + * representation type `Repr` and the new element type `B`. + */ +final class Array[T](_length: Int) extends java.io.Serializable with java.lang.Cloneable { + + /** The length of the array */ + def length: Int = throw new Error() + + /** The element at given index. + * + * Indices start at `0`; `xs.apply(0)` is the first element of array `xs`. + * Note the indexing syntax `xs(i)` is a shorthand for `xs.apply(i)`. + * + * @param i the index + * @return the element at the given index + * @throws ArrayIndexOutOfBoundsException if `i < 0` or `length <= i` + */ + def apply(i: Int): T = throw new Error() + + /** Update the element at given index. + * + * Indices start at `0`; `xs.update(i, x)` replaces the i^th^ element in the array. + * Note the syntax `xs(i) = x` is a shorthand for `xs.update(i, x)`. + * + * @param i the index + * @param x the value to be written at index `i` + * @throws ArrayIndexOutOfBoundsException if `i < 0` or `length <= i` + */ + def update(i: Int, x: T) { throw new Error() } + + /** Clone the Array. + * + * @return A clone of the Array. + */ + override def clone(): Array[T] = throw new Error() +} diff --git a/scalalib/overrides-2.13/scala/Enumeration.scala b/scalalib/overrides-2.13/scala/Enumeration.scala new file mode 100644 index 0000000000..aaeec73850 --- /dev/null +++ b/scalalib/overrides-2.13/scala/Enumeration.scala @@ -0,0 +1,314 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala + +import scala.collection.{ mutable, immutable, StrictOptimizedIterableOps, SpecificIterableFactory, View } +import java.lang.reflect.{ Method => JMethod, Field => JField } +import scala.reflect.NameTransformer._ +import scala.util.matching.Regex + +/** Defines a finite set of values specific to the enumeration. Typically + * these values enumerate all possible forms something can take and provide + * a lightweight alternative to case classes. + * + * Each call to a `Value` method adds a new unique value to the enumeration. + * To be accessible, these values are usually defined as `val` members of + * the enumeration. + * + * All values in an enumeration share a common, unique type defined as the + * `Value` type member of the enumeration (`Value` selected on the stable + * identifier path of the enumeration instance). + * + * @example {{{ + * // Define a new enumeration with a type alias and work with the full set of enumerated values + * object WeekDay extends Enumeration { + * type WeekDay = Value + * val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value + * } + * import WeekDay._ + * + * def isWorkingDay(d: WeekDay) = ! (d == Sat || d == Sun) + * + * WeekDay.values filter isWorkingDay foreach println + * // output: + * // Mon + * // Tue + * // Wed + * // Thu + * // Fri + * }}} + * + * @example {{{ + * // Example of adding attributes to an enumeration by extending the Enumeration.Val class + * object Planet extends Enumeration { + * protected case class Val(mass: Double, radius: Double) extends super.Val { + * def surfaceGravity: Double = Planet.G * mass / (radius * radius) + * def surfaceWeight(otherMass: Double): Double = otherMass * surfaceGravity + * } + * implicit def valueToPlanetVal(x: Value): Val = x.asInstanceOf[Val] + * + * val G: Double = 6.67300E-11 + * val Mercury = Val(3.303e+23, 2.4397e6) + * val Venus = Val(4.869e+24, 6.0518e6) + * val Earth = Val(5.976e+24, 6.37814e6) + * val Mars = Val(6.421e+23, 3.3972e6) + * val Jupiter = Val(1.9e+27, 7.1492e7) + * val Saturn = Val(5.688e+26, 6.0268e7) + * val Uranus = Val(8.686e+25, 2.5559e7) + * val Neptune = Val(1.024e+26, 2.4746e7) + * } + * + * println(Planet.values.filter(_.radius > 7.0e6)) + * // output: + * // Planet.ValueSet(Jupiter, Saturn, Uranus, Neptune) + * }}} + * + * @param initial The initial value from which to count the integers that + * identifies values at run-time. + * @author Matthias Zenger + */ +@SerialVersionUID(8476000850333817230L) +abstract class Enumeration (initial: Int) extends Serializable { + thisenum => + + def this() = this(0) + + /* Note that `readResolve` cannot be private, since otherwise + the JVM does not invoke it when deserializing subclasses. */ + protected def readResolve(): AnyRef = thisenum.getClass.getField(MODULE_INSTANCE_NAME).get(null) + + /** The name of this enumeration. + */ + override def toString = + ((getClass.getName stripSuffix MODULE_SUFFIX_STRING split '.').last split + Regex.quote(NAME_JOIN_STRING)).last + + /** The mapping from the integer used to identify values to the actual + * values. */ + private val vmap: mutable.Map[Int, Value] = new mutable.HashMap + + /** The cache listing all values of this enumeration. */ + @transient private var vset: ValueSet = null + @transient @volatile private var vsetDefined = false + + /** The mapping from the integer used to identify values to their + * names. */ + private val nmap: mutable.Map[Int, String] = new mutable.HashMap + + /** The values of this enumeration as a set. + */ + def values: ValueSet = { + if (!vsetDefined) { + vset = (ValueSet.newBuilder ++= vmap.values).result() + vsetDefined = true + } + vset + } + + /** The integer to use to identify the next created value. */ + protected var nextId: Int = initial + + /** The string to use to name the next created value. */ + protected var nextName: Iterator[String] = _ + + private def nextNameOrNull = + if (nextName != null && nextName.hasNext) nextName.next() else null + + /** The highest integer amongst those used to identify values in this + * enumeration. */ + private var topId = initial + + /** The lowest integer amongst those used to identify values in this + * enumeration, but no higher than 0. */ + private var bottomId = if(initial < 0) initial else 0 + + /** The one higher than the highest integer amongst those used to identify + * values in this enumeration. */ + final def maxId = topId + + /** The value of this enumeration with given id `x` + */ + final def apply(x: Int): Value = vmap(x) + + /** Return a `Value` from this `Enumeration` whose name matches + * the argument `s`. The names are determined automatically via reflection. + * + * @param s an `Enumeration` name + * @return the `Value` of this `Enumeration` if its name matches `s` + * @throws NoSuchElementException if no `Value` with a matching + * name is in this `Enumeration` + */ + final def withName(s: String): Value = values.find(_.toString == s).getOrElse( + throw new NoSuchElementException(s"No value found for '$s'")) + + /** Creates a fresh value, part of this enumeration. */ + protected final def Value: Value = Value(nextId) + + /** Creates a fresh value, part of this enumeration, identified by the + * integer `i`. + * + * @param i An integer that identifies this value at run-time. It must be + * unique amongst all values of the enumeration. + * @return Fresh value identified by `i`. + */ + protected final def Value(i: Int): Value = Value(i, nextNameOrNull) + + /** Creates a fresh value, part of this enumeration, called `name`. + * + * @param name A human-readable name for that value. + * @return Fresh value called `name`. + */ + protected final def Value(name: String): Value = Value(nextId, name) + + /** Creates a fresh value, part of this enumeration, called `name` + * and identified by the integer `i`. + * + * @param i An integer that identifies this value at run-time. It must be + * unique amongst all values of the enumeration. + * @param name A human-readable name for that value. + * @return Fresh value with the provided identifier `i` and name `name`. + */ + protected final def Value(i: Int, name: String): Value = new Val(i, name) + + private def populateNameMap() { + val fields: Array[JField] = getClass.getDeclaredFields + def isValDef(m: JMethod): Boolean = fields exists (fd => fd.getName == m.getName && fd.getType == m.getReturnType) + + // The list of possible Value methods: 0-args which return a conforming type + val methods: Array[JMethod] = getClass.getMethods filter (m => m.getParameterTypes.isEmpty && + classOf[Value].isAssignableFrom(m.getReturnType) && + m.getDeclaringClass != classOf[Enumeration] && + isValDef(m)) + methods foreach { m => + val name = m.getName + // invoke method to obtain actual `Value` instance + val value = m.invoke(this).asInstanceOf[Value] + // verify that outer points to the correct Enumeration: ticket #3616. + if (value.outerEnum eq thisenum) { + val id = Int.unbox(classOf[Val] getMethod "id" invoke value) + nmap += ((id, name)) + } + } + } + + /* Obtains the name for the value with id `i`. If no name is cached + * in `nmap`, it populates `nmap` using reflection. + */ + private def nameOf(i: Int): String = synchronized { nmap.getOrElse(i, { populateNameMap() ; nmap(i) }) } + + /** The type of the enumerated values. */ + @SerialVersionUID(7091335633555234129L) + abstract class Value extends Ordered[Value] with Serializable { + /** the id and bit location of this enumeration value */ + def id: Int + /** a marker so we can tell whose values belong to whom come reflective-naming time */ + private[Enumeration] val outerEnum = thisenum + + override def compare(that: Value): Int = + if (this.id < that.id) -1 + else if (this.id == that.id) 0 + else 1 + override def equals(other: Any) = other match { + case that: Enumeration#Value => (outerEnum eq that.outerEnum) && (id == that.id) + case _ => false + } + override def hashCode: Int = id.## + + /** Create a ValueSet which contains this value and another one */ + def + (v: Value) = ValueSet(this, v) + } + + /** A class implementing the [[scala.Enumeration.Value]] type. This class + * can be overridden to change the enumeration's naming and integer + * identification behaviour. + */ + @SerialVersionUID(0 - 3501153230598116017L) + protected class Val(i: Int, name: String) extends Value with Serializable { + def this(i: Int) = this(i, nextNameOrNull) + def this(name: String) = this(nextId, name) + def this() = this(nextId) + + assert(!vmap.isDefinedAt(i), "Duplicate id: " + i) + vmap(i) = this + vsetDefined = false + nextId = i + 1 + if (nextId > topId) topId = nextId + if (i < bottomId) bottomId = i + def id = i + override def toString() = + if (name != null) name + else try thisenum.nameOf(i) + catch { case _: NoSuchElementException => "" } + + protected def readResolve(): AnyRef = { + val enum = thisenum.readResolve().asInstanceOf[Enumeration] + if (enum.vmap == null) this + else enum.vmap(i) + } + } + + /** An ordering by id for values of this set */ + object ValueOrdering extends Ordering[Value] { + def compare(x: Value, y: Value): Int = x compare y + } + + /** A class for sets of values. + * Iterating through this set will yield values in increasing order of their ids. + * + * @param nnIds The set of ids of values (adjusted so that the lowest value does + * not fall below zero), organized as a `BitSet`. + * @define Coll `collection.immutable.SortedSet` + */ + class ValueSet private[ValueSet] (private[this] var nnIds: immutable.BitSet) + extends immutable.AbstractSet[Value] + with immutable.SortedSet[Value] + with immutable.SetOps[Value, immutable.Set, ValueSet] + with StrictOptimizedIterableOps[Value, immutable.Set, ValueSet] + with Serializable { + + implicit def ordering: Ordering[Value] = ValueOrdering + def rangeImpl(from: Option[Value], until: Option[Value]): ValueSet = + new ValueSet(nnIds.rangeImpl(from.map(_.id - bottomId), until.map(_.id - bottomId))) + + override def empty = ValueSet.empty + def contains(v: Value) = nnIds contains (v.id - bottomId) + def incl (value: Value) = new ValueSet(nnIds + (value.id - bottomId)) + def excl (value: Value) = new ValueSet(nnIds - (value.id - bottomId)) + def iterator = nnIds.iterator map (id => thisenum.apply(bottomId + id)) + override def iteratorFrom(start: Value) = nnIds iteratorFrom start.id map (id => thisenum.apply(bottomId + id)) + override def className = thisenum + ".ValueSet" + /** Creates a bit mask for the zero-adjusted ids in this set as a + * new array of longs */ + def toBitMask: Array[Long] = nnIds.toBitMask + + override protected def fromSpecificIterable(coll: Iterable[Value]) = ValueSet.fromSpecific(coll) + override protected def newSpecificBuilder = ValueSet.newBuilder + + def map(f: Value => Value): ValueSet = fromSpecificIterable(new View.Map(toIterable, f)) + def flatMap(f: Value => IterableOnce[Value]): ValueSet = fromSpecificIterable(new View.FlatMap(toIterable, f)) + } + + /** A factory object for value sets */ + object ValueSet extends SpecificIterableFactory[Value, ValueSet] { + /** The empty value set */ + val empty = new ValueSet(immutable.BitSet.empty) + /** A value set containing all the values for the zero-adjusted ids + * corresponding to the bits in an array */ + def fromBitMask(elems: Array[Long]): ValueSet = new ValueSet(immutable.BitSet.fromBitMask(elems)) + /** A builder object for value sets */ + def newBuilder: mutable.Builder[Value, ValueSet] = new mutable.Builder[Value, ValueSet] { + private[this] val b = new mutable.BitSet + def addOne (x: Value) = { b += (x.id - bottomId); this } + def clear() = b.clear() + def result() = new ValueSet(b.toImmutable) + } + def fromSpecific(it: IterableOnce[Value]): ValueSet = + newBuilder.addAll(it).result() + } +} diff --git a/scalalib/overrides-2.13/scala/runtime/ScalaRunTime.scala b/scalalib/overrides-2.13/scala/runtime/ScalaRunTime.scala new file mode 100644 index 0000000000..148fb827c5 --- /dev/null +++ b/scalalib/overrides-2.13/scala/runtime/ScalaRunTime.scala @@ -0,0 +1,282 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala +package runtime + +import scala.collection.{ AbstractIterator, AnyConstr, SortedOps, StrictOptimizedIterableOps, StringOps, StringView, View } +import scala.collection.generic.IsIterableLike +import scala.collection.immutable.{ NumericRange, ArraySeq } +import scala.collection.mutable.StringBuilder +import scala.reflect.{ ClassTag, classTag } +import java.lang.{ Class => jClass } + +import java.lang.reflect.{ Method => JMethod } + +/** The object ScalaRunTime provides support methods required by + * the scala runtime. All these methods should be considered + * outside the API and subject to change or removal without notice. + */ +object ScalaRunTime { + def isArray(x: Any, atLevel: Int = 1): Boolean = + x != null && isArrayClass(x.getClass, atLevel) + + private def isArrayClass(clazz: jClass[_], atLevel: Int): Boolean = + clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) + + // A helper method to make my life in the pattern matcher a lot easier. + def drop[Repr](coll: Repr, num: Int)(implicit iterable: IsIterableLike[Repr]): Repr = + iterable conversion coll drop num + + /** Return the class object representing an array with element class `clazz`. + */ + def arrayClass(clazz: jClass[_]): jClass[_] = { + // newInstance throws an exception if the erasure is Void.TYPE. see scala/bug#5680 + if (clazz == java.lang.Void.TYPE) classOf[Array[Unit]] + else java.lang.reflect.Array.newInstance(clazz, 0).getClass + } + + /** Return the class object representing an unboxed value type, + * e.g., classOf[int], not classOf[java.lang.Integer]. The compiler + * rewrites expressions like 5.getClass to come here. + */ + def anyValClass[T <: AnyVal : ClassTag](value: T): jClass[T] = + classTag[T].runtimeClass.asInstanceOf[jClass[T]] + + /** Retrieve generic array element */ + def array_apply(xs: AnyRef, idx: Int): Any = { + xs match { + case x: Array[AnyRef] => x(idx).asInstanceOf[Any] + case x: Array[Int] => x(idx).asInstanceOf[Any] + case x: Array[Double] => x(idx).asInstanceOf[Any] + case x: Array[Long] => x(idx).asInstanceOf[Any] + case x: Array[Float] => x(idx).asInstanceOf[Any] + case x: Array[Char] => x(idx).asInstanceOf[Any] + case x: Array[Byte] => x(idx).asInstanceOf[Any] + case x: Array[Short] => x(idx).asInstanceOf[Any] + case x: Array[Boolean] => x(idx).asInstanceOf[Any] + case x: Array[Unit] => x(idx).asInstanceOf[Any] + case null => throw new NullPointerException + } + } + + /** update generic array element */ + def array_update(xs: AnyRef, idx: Int, value: Any): Unit = { + xs match { + case x: Array[AnyRef] => x(idx) = value.asInstanceOf[AnyRef] + case x: Array[Int] => x(idx) = value.asInstanceOf[Int] + case x: Array[Double] => x(idx) = value.asInstanceOf[Double] + case x: Array[Long] => x(idx) = value.asInstanceOf[Long] + case x: Array[Float] => x(idx) = value.asInstanceOf[Float] + case x: Array[Char] => x(idx) = value.asInstanceOf[Char] + case x: Array[Byte] => x(idx) = value.asInstanceOf[Byte] + case x: Array[Short] => x(idx) = value.asInstanceOf[Short] + case x: Array[Boolean] => x(idx) = value.asInstanceOf[Boolean] + case x: Array[Unit] => x(idx) = value.asInstanceOf[Unit] + case null => throw new NullPointerException + } + } + + /** Get generic array length */ + def array_length(xs: AnyRef): Int = xs match { + case x: Array[AnyRef] => x.length + case x: Array[Int] => x.length + case x: Array[Double] => x.length + case x: Array[Long] => x.length + case x: Array[Float] => x.length + case x: Array[Char] => x.length + case x: Array[Byte] => x.length + case x: Array[Short] => x.length + case x: Array[Boolean] => x.length + case x: Array[Unit] => x.length + case null => throw new NullPointerException + } + + def array_clone(xs: AnyRef): AnyRef = xs match { + case x: Array[AnyRef] => x.clone() + case x: Array[Int] => x.clone() + case x: Array[Double] => x.clone() + case x: Array[Long] => x.clone() + case x: Array[Float] => x.clone() + case x: Array[Char] => x.clone() + case x: Array[Byte] => x.clone() + case x: Array[Short] => x.clone() + case x: Array[Boolean] => x.clone() + case x: Array[Unit] => x + case null => throw new NullPointerException + } + + /** Convert an array to an object array. + * Needed to deal with vararg arguments of primitive types that are passed + * to a generic Java vararg parameter T ... + */ + def toObjectArray(src: AnyRef): Array[Object] = src match { + case x: Array[AnyRef] => x + case _ => + val length = array_length(src) + val dest = new Array[Object](length) + for (i <- 0 until length) + array_update(dest, i, array_apply(src, i)) + dest + } + + def toArray[T](xs: scala.collection.Seq[T]) = { + val arr = new Array[AnyRef](xs.length) + var i = 0 + for (x <- xs) { + arr(i) = x.asInstanceOf[AnyRef] + i += 1 + } + arr + } + + // Java bug: https://bugs.java.com/view_bug.do?bug_id=4071957 + // More background at ticket #2318. + def ensureAccessible(m: JMethod): JMethod = scala.reflect.ensureAccessible(m) + + def _toString(x: Product): String = + x.productIterator.mkString(x.productPrefix + "(", ",", ")") + + def _hashCode(x: Product): Int = scala.util.hashing.MurmurHash3.productHash(x) + + /** A helper for case classes. */ + def typedProductIterator[T](x: Product): Iterator[T] = { + new AbstractIterator[T] { + private var c: Int = 0 + private val cmax = x.productArity + def hasNext = c < cmax + def next() = { + val result = x.productElement(c) + c += 1 + result.asInstanceOf[T] + } + } + } + + /** Given any Scala value, convert it to a String. + * + * The primary motivation for this method is to provide a means for + * correctly obtaining a String representation of a value, while + * avoiding the pitfalls of naively calling toString on said value. + * In particular, it addresses the fact that (a) toString cannot be + * called on null and (b) depending on the apparent type of an + * array, toString may or may not print it in a human-readable form. + * + * @param arg the value to stringify + * @return a string representation of arg. + */ + def stringOf(arg: Any): String = stringOf(arg, scala.Int.MaxValue) + def stringOf(arg: Any, maxElements: Int): String = { + def packageOf(x: AnyRef) = x.getClass.getPackage match { + case null => "" + case p => p.getName + } + def isScalaClass(x: AnyRef) = packageOf(x) startsWith "scala." + def isScalaCompilerClass(x: AnyRef) = packageOf(x) startsWith "scala.tools.nsc." + + // includes specialized subclasses and future proofed against hypothetical TupleN (for N > 22) + def isTuple(x: Any) = x != null && x.getClass.getName.startsWith("scala.Tuple") + + // We use reflection because the scala.xml package might not be available + def isSubClassOf(potentialSubClass: Class[_], ofClass: String) = + try { + val classLoader = potentialSubClass.getClassLoader + val clazz = Class.forName(ofClass, /*initialize =*/ false, classLoader) + clazz.isAssignableFrom(potentialSubClass) + } catch { + case cnfe: ClassNotFoundException => false + } + def isXmlNode(potentialSubClass: Class[_]) = isSubClassOf(potentialSubClass, "scala.xml.Node") + def isXmlMetaData(potentialSubClass: Class[_]) = isSubClassOf(potentialSubClass, "scala.xml.MetaData") + + // When doing our own iteration is dangerous + def useOwnToString(x: Any) = x match { + // Range/NumericRange have a custom toString to avoid walking a gazillion elements + case _: Range | _: NumericRange[_] => true + // Sorted collections to the wrong thing (for us) on iteration - ticket #3493 + case _: SortedOps[_, _] => true + // StringBuilder(a, b, c) and similar not so attractive + case _: StringView | _: StringOps | _: StringBuilder => true + // Don't want to evaluate any elements in a view + case _: View[_] => true + // Node extends NodeSeq extends Seq[Node] and MetaData extends Iterable[MetaData] + // -> catch those by isXmlNode and isXmlMetaData. + // Don't want to a) traverse infinity or b) be overly helpful with peoples' custom + // collections which may have useful toString methods - ticket #3710 + // or c) print AbstractFiles which are somehow also Iterable[AbstractFile]s. + case x: Iterable[_] => (!x.isInstanceOf[StrictOptimizedIterableOps[_, AnyConstr, _]]) || !isScalaClass(x) || isScalaCompilerClass(x) || isXmlNode(x.getClass) || isXmlMetaData(x.getClass) + // Otherwise, nothing could possibly go wrong + case _ => false + } + + // A variation on inner for maps so they print -> instead of bare tuples + def mapInner(arg: Any): String = arg match { + case (k, v) => inner(k) + " -> " + inner(v) + case _ => inner(arg) + } + + // Special casing Unit arrays, the value class which uses a reference array type. + def arrayToString(x: AnyRef) = { + if (x.getClass.getComponentType == classOf[BoxedUnit]) + 0 until (array_length(x) min maxElements) map (_ => "()") mkString ("Array(", ", ", ")") + else + x.asInstanceOf[Array[_]].iterator.take(maxElements).map(inner).mkString("Array(", ", ", ")") + } + + // The recursively applied attempt to prettify Array printing. + // Note that iterator is used if possible and foreach is used as a + // last resort, because the parallel collections "foreach" in a + // random order even on sequences. + def inner(arg: Any): String = arg match { + case null => "null" + case "" => "\"\"" + case x: String => if (x.head.isWhitespace || x.last.isWhitespace) "\"" + x + "\"" else x + case x if useOwnToString(x) => x.toString + case x: AnyRef if isArray(x) => arrayToString(x) + case x: scala.collection.Map[_, _] => x.iterator take maxElements map mapInner mkString (x.className + "(", ", ", ")") + case x: Iterable[_] => x.iterator take maxElements map inner mkString (x.className + "(", ", ", ")") + case x: Product1[_] if isTuple(x) => "(" + inner(x._1) + ",)" // that special trailing comma + case x: Product if isTuple(x) => x.productIterator map inner mkString ("(", ",", ")") + case x => x.toString + } + + // The try/catch is defense against iterables which aren't actually designed + // to be iterated, such as some scala.tools.nsc.io.AbstractFile derived classes. + try inner(arg) + catch { + case _: UnsupportedOperationException | _: AssertionError => "" + arg + } + } + + /** stringOf formatted for use in a repl result. */ + def replStringOf(arg: Any, maxElements: Int): String = { + val s = stringOf(arg, maxElements) + val nl = if (s contains "\n") "\n" else "" + + nl + s + "\n" + } + + // Convert arrays to immutable.ArraySeq for use with Java varargs: + def genericWrapArray[T](xs: Array[T]): ArraySeq[T] = + if (xs eq null) null + else ArraySeq.unsafeWrapArray(xs) + def wrapRefArray[T <: AnyRef](xs: Array[T]): ArraySeq[T] = { + if (xs eq null) null + else if (xs.length == 0) ArraySeq.empty[AnyRef].asInstanceOf[ArraySeq[T]] + else new ArraySeq.ofRef[T](xs) + } + def wrapIntArray(xs: Array[Int]): ArraySeq[Int] = if (xs ne null) new ArraySeq.ofInt(xs) else null + def wrapDoubleArray(xs: Array[Double]): ArraySeq[Double] = if (xs ne null) new ArraySeq.ofDouble(xs) else null + def wrapLongArray(xs: Array[Long]): ArraySeq[Long] = if (xs ne null) new ArraySeq.ofLong(xs) else null + def wrapFloatArray(xs: Array[Float]): ArraySeq[Float] = if (xs ne null) new ArraySeq.ofFloat(xs) else null + def wrapCharArray(xs: Array[Char]): ArraySeq[Char] = if (xs ne null) new ArraySeq.ofChar(xs) else null + def wrapByteArray(xs: Array[Byte]): ArraySeq[Byte] = if (xs ne null) new ArraySeq.ofByte(xs) else null + def wrapShortArray(xs: Array[Short]): ArraySeq[Short] = if (xs ne null) new ArraySeq.ofShort(xs) else null + def wrapBooleanArray(xs: Array[Boolean]): ArraySeq[Boolean] = if (xs ne null) new ArraySeq.ofBoolean(xs) else null + def wrapUnitArray(xs: Array[Unit]): ArraySeq[Unit] = if (xs ne null) new ArraySeq.ofUnit(xs) else null +} From 5ac5168525ef18a9149b9e63c5696db051f42ea3 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Mon, 14 May 2018 11:39:05 +0200 Subject: [PATCH 0738/2665] Support Scala 2.13.0-M4 in all the non-tools artifacts. This commit puts the codebase in a state where we can build the compiler plugins, libraries and test suite with Scala 2.13.0-M4 and its new collections. The tools API and related artifacts are not yet updated. This is the minimal set of changes necessary to be able to build and back-publish for 2.13.0-M4 when it comes out. We will not be able to publish tools artifact for that version, but that is not critical. --- ci/checksizes.sh | 4 +- .../org/scalajs/core/compiler/GenJSCode.scala | 59 +- .../scalajs/core/compiler/GenJSExports.scala | 6 +- .../scalajs/core/compiler/JSDefinitions.scala | 4 +- .../scalajs/core/compiler/PrepJSExports.scala | 8 +- .../core/compiler/test/JSExportTest.scala | 14 +- .../core/compiler/test/OptimizationTest.scala | 64 ++- .../src/main/scala/java/util/ArrayList.scala | 2 +- .../main/scala/java/util/Collections.scala | 2 +- javalib/src/main/scala/java/util/Compat.scala | 47 ++ .../main/scala/java/util/NavigableView.scala | 18 +- .../src/main/scala/java/util/TreeSet.scala | 28 +- .../scala/java/util/regex/GroupStartMap.scala | 2 +- .../junit/plugin/Compat210Component.scala | 9 + .../junit/plugin/ScalaJSJUnitPlugin.scala | 20 +- .../scala/org/hamcrest/BaseDescription.scala | 2 +- .../scala/scalajs/js/Any.scala | 193 +++++++ .../scala/scalajs/js/ArrayOps.scala | 104 ++++ .../scala/scalajs/js/JSConverters.scala | 152 +++++ .../scala/scalajs/js/WrappedArray.scala | 101 ++++ .../scala/scalajs/js/WrappedDictionary.scala | 181 ++++++ .../scala/scalajs/runtime/Compat.scala | 26 + .../scalajs/runtime/WrappedVarArgs.scala | 49 ++ .../scala/scalajs/js/Any.scala | 0 .../scala/scalajs/js/ArrayOps.scala | 62 +-- .../scala/scalajs/js/JSConverters.scala | 0 .../scala/scalajs/js/WrappedArray.scala | 0 .../scala/scalajs/js/WrappedDictionary.scala | 0 .../scala/scalajs/runtime/Compat.scala | 25 + .../scala/scalajs/js/ArrayOpsCommon.scala | 67 +++ .../scala/scala/scalajs/runtime/package.scala | 20 +- project/Build.scala | 19 + scalalib/overrides-2.13/scala/Array.scala | 69 +-- .../overrides-2.13/scala/Enumeration.scala | 54 +- .../collection/immutable/NumericRange.scala | 222 ++++---- .../scala/collection/immutable/Range.scala | 526 +++++++++--------- .../collection/mutable/ArrayBuilder.scala | 409 +++++--------- .../scala/collection/mutable/Buffer.scala | 202 +++++-- scalalib/overrides-2.13/scala/package.scala | 53 +- .../scala/runtime/ScalaRunTime.scala | 2 +- .../scalajs/testinterface/HTMLRunner.scala | 9 +- .../testsuite/library/ArrayOpsToTest.scala | 23 + .../library/WrappedArrayToTest.scala | 23 + .../library/WrappedDictionaryToTest.scala | 23 + .../testsuite/library/ArrayOpsToTest.scala | 23 + .../library/WrappedArrayToTest.scala | 23 + .../library/WrappedDictionaryToTest.scala | 23 + .../testsuite/compiler/OptimizerTest.scala | 2 +- .../testsuite/library/ArrayOpsTest.scala | 5 - .../testsuite/library/UnionTypeTest.scala | 2 +- .../testsuite/library/WrappedArrayTest.scala | 20 +- .../library/WrappedDictionaryTest.scala | 64 ++- .../javalib/util/AbstractCollectionTest.scala | 2 +- .../testsuite/scalalib/ArrayBuilderTest.scala | 43 +- 54 files changed, 2141 insertions(+), 969 deletions(-) create mode 100644 javalib/src/main/scala/java/util/Compat.scala create mode 100644 library/src/main/scala-new-collections/scala/scalajs/js/Any.scala create mode 100644 library/src/main/scala-new-collections/scala/scalajs/js/ArrayOps.scala create mode 100644 library/src/main/scala-new-collections/scala/scalajs/js/JSConverters.scala create mode 100644 library/src/main/scala-new-collections/scala/scalajs/js/WrappedArray.scala create mode 100644 library/src/main/scala-new-collections/scala/scalajs/js/WrappedDictionary.scala create mode 100644 library/src/main/scala-new-collections/scala/scalajs/runtime/Compat.scala create mode 100644 library/src/main/scala-new-collections/scala/scalajs/runtime/WrappedVarArgs.scala rename library/src/main/{scala => scala-old-collections}/scala/scalajs/js/Any.scala (100%) rename library/src/main/{scala => scala-old-collections}/scala/scalajs/js/ArrayOps.scala (56%) rename library/src/main/{scala => scala-old-collections}/scala/scalajs/js/JSConverters.scala (100%) rename library/src/main/{scala => scala-old-collections}/scala/scalajs/js/WrappedArray.scala (100%) rename library/src/main/{scala => scala-old-collections}/scala/scalajs/js/WrappedDictionary.scala (100%) create mode 100644 library/src/main/scala-old-collections/scala/scalajs/runtime/Compat.scala create mode 100644 library/src/main/scala/scala/scalajs/js/ArrayOpsCommon.scala create mode 100644 test-suite/js/src/test/scala-new-collections/org/scalajs/testsuite/library/ArrayOpsToTest.scala create mode 100644 test-suite/js/src/test/scala-new-collections/org/scalajs/testsuite/library/WrappedArrayToTest.scala create mode 100644 test-suite/js/src/test/scala-new-collections/org/scalajs/testsuite/library/WrappedDictionaryToTest.scala create mode 100644 test-suite/js/src/test/scala-old-collections/org/scalajs/testsuite/library/ArrayOpsToTest.scala create mode 100644 test-suite/js/src/test/scala-old-collections/org/scalajs/testsuite/library/WrappedArrayToTest.scala create mode 100644 test-suite/js/src/test/scala-old-collections/org/scalajs/testsuite/library/WrappedDictionaryToTest.scala diff --git a/ci/checksizes.sh b/ci/checksizes.sh index 423836b5bc..e4ab7f1438 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -37,7 +37,7 @@ REVERSI_OPT_GZ_SIZE=$(stat '-c%s' "$REVERSI_OPT.gz") case $FULLVER in 2.10.2) - REVERSI_PREOPT_EXPECTEDSIZE=532000 + REVERSI_PREOPT_EXPECTEDSIZE=533000 REVERSI_OPT_EXPECTEDSIZE=122000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=71000 REVERSI_OPT_GZ_EXPECTEDSIZE=31000 @@ -55,7 +55,7 @@ case $FULLVER in REVERSI_OPT_GZ_EXPECTEDSIZE=33000 ;; 2.13.0-M3) - REVERSI_PREOPT_EXPECTEDSIZE=628000 + REVERSI_PREOPT_EXPECTEDSIZE=629000 REVERSI_OPT_EXPECTEDSIZE=147000 REVERSI_PREOPT_GZ_EXPECTEDSIZE=77000 REVERSI_OPT_GZ_EXPECTEDSIZE=33000 diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index fc6e2b2205..47d7201ef8 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -1395,7 +1395,7 @@ abstract class GenJSCode extends plugins.PluginComponent val ctorToChildren = secondaryCtors.map { ctor => findCtorForwarderCall(ctor.body.get) -> ctor - }.groupBy(_._1).mapValues(_.map(_._2)).withDefaultValue(Nil) + }.groupBy(_._1).mapValues(_.map(_._2)).toMap.withDefaultValue(Nil) var overrideNum = -1 def mkConstructorTree(method: js.MethodDef): ConstructorTree = { @@ -1546,9 +1546,9 @@ abstract class GenJSCode extends plugins.PluginComponent val methodDefWithoutUselessVars = { val unmutatedMutableLocalVars = - (mutableLocalVars -- mutatedLocalVars).toList + (mutableLocalVars.diff(mutatedLocalVars)).toList val mutatedImmutableLocalVals = - (mutatedLocalVars -- mutableLocalVars).toList + (mutatedLocalVars.diff(mutableLocalVars)).toList if (unmutatedMutableLocalVars.isEmpty && mutatedImmutableLocalVals.isEmpty) { // OK, we're good (common case) @@ -4643,10 +4643,12 @@ abstract class GenJSCode extends plugins.PluginComponent } /** Gen actual actual arguments to Scala method call. + * * Returns a list of the transformed arguments. * * This tries to optimize repeated arguments (varargs) by turning them - * into js.WrappedArray instead of Scala wrapped arrays. + * into JS arrays wrapped in the appropriate Seq, rather than Scala + * arrays. */ private def genActualArgs(sym: Symbol, args: List[Tree])( implicit pos: Position): List[js.Tree] = { @@ -4671,8 +4673,7 @@ abstract class GenJSCode extends plugins.PluginComponent tryGenRepeatedParamAsJSArray(arg, handleNil = false).fold { genExpr(arg) } { genArgs => - genNew(WrappedArrayClass, WrappedArray_ctor, - List(js.JSArrayConstr(genArgs))) + genJSArrayToVarArgs(js.JSArrayConstr(genArgs)) } } else { genExpr(arg) @@ -4829,18 +4830,25 @@ abstract class GenJSCode extends plugins.PluginComponent } object WrapArray { - lazy val isWrapArray: Set[Symbol] = Seq( - nme.wrapRefArray, - nme.wrapByteArray, - nme.wrapShortArray, - nme.wrapCharArray, - nme.wrapIntArray, - nme.wrapLongArray, - nme.wrapFloatArray, - nme.wrapDoubleArray, - nme.wrapBooleanArray, - nme.wrapUnitArray, - nme.genericWrapArray).map(getMemberMethod(PredefModule, _)).toSet + private val isWrapArray: Set[Symbol] = { + val wrapArrayModule = + if (hasNewCollections) ScalaRunTimeModule + else PredefModule + + Seq( + nme.wrapRefArray, + nme.wrapByteArray, + nme.wrapShortArray, + nme.wrapCharArray, + nme.wrapIntArray, + nme.wrapLongArray, + nme.wrapFloatArray, + nme.wrapDoubleArray, + nme.wrapBooleanArray, + nme.wrapUnitArray, + nme.genericWrapArray + ).map(getMemberMethod(wrapArrayModule, _)).toSet + } def unapply(tree: Apply): Option[Tree] = tree match { case Apply(wrapArray_?, List(wrapped)) @@ -4851,6 +4859,13 @@ abstract class GenJSCode extends plugins.PluginComponent } } + /** Wraps a `js.Array` to use as varargs. */ + def genJSArrayToVarArgs(arrayRef: js.Tree)( + implicit pos: Position): js.Tree = { + genApplyMethod(genLoadModule(RuntimePackageModule), + Runtime_toScalaVarArgs, List(arrayRef)) + } + // Synthesizers for raw JS functions --------------------------------------- /** Try and generate JS code for an anonymous function class. @@ -5534,6 +5549,14 @@ abstract class GenJSCode extends plugins.PluginComponent settings.Xexperimental.value } + private lazy val hasNewCollections = { + val v = scala.util.Properties.versionNumberString + !v.startsWith("2.10.") && + !v.startsWith("2.11.") && + !v.startsWith("2.12.") && + v != "2.13.0-M3" + } + /** Tests whether the given type represents a raw JavaScript type, * i.e., whether it extends scala.scalajs.js.Any. */ diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index 371279f45e..8be2b13eb1 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -461,7 +461,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => // Create a map: argCount -> methods (methods may appear multiple times) val methodByArgCount = - methodArgCounts.groupBy(_._1).mapValues(_.map(_._2).toSet) + methodArgCounts.groupBy(_._1).mapValues(_.map(_._2).toSet).toMap // Minimum number of arguments that must be given val minArgc = methodByArgCount.keys.min @@ -754,9 +754,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => // optional repeated parameter list val jsVarArgPrep = repeatedTpe map { tpe => - // new WrappedArray(varargs) - val rhs = genNew(WrappedArrayClass, WrappedArray_ctor, List( - genVarargRef(normalArgc, minArgc))) + val rhs = genJSArrayToVarArgs(genVarargRef(normalArgc, minArgc)) js.VarDef(js.Ident("prep" + normalArgc), rhs.tpe, mutable = false, rhs) } diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index f3e237a76f..eb736f2fd5 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -126,6 +126,7 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val Runtime_unwrapJavaScriptException = getMemberMethod(RuntimePackageModule, newTermName("unwrapJavaScriptException")) lazy val Runtime_jsObjectSuperGet = getMemberMethod(RuntimePackageModule, newTermName("jsObjectSuperGet")) lazy val Runtime_jsObjectSuperSet = getMemberMethod(RuntimePackageModule, newTermName("jsObjectSuperSet")) + lazy val Runtime_toScalaVarArgs = getMemberMethod(RuntimePackageModule, newTermName("toScalaVarArgs")) lazy val Runtime_genTraversableOnce2jsArray = getMemberMethod(RuntimePackageModule, newTermName("genTraversableOnce2jsArray")) lazy val Runtime_jsTupleArray2jsObject = getMemberMethod(RuntimePackageModule, newTermName("jsTupleArray2jsObject")) lazy val Runtime_constructorOf = getMemberMethod(RuntimePackageModule, newTermName("constructorOf")) @@ -133,9 +134,6 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val Runtime_propertiesOf = getMemberMethod(RuntimePackageModule, newTermName("propertiesOf")) lazy val Runtime_linkingInfo = getMemberMethod(RuntimePackageModule, newTermName("linkingInfo")) - lazy val WrappedArrayClass = getRequiredClass("scala.scalajs.js.WrappedArray") - lazy val WrappedArray_ctor = WrappedArrayClass.primaryConstructor - // This is a def, since similar symbols (arrayUpdateMethod, etc.) are in runDefinitions // (rather than definitions) and we weren't sure if it is safe to make this a lazy val def ScalaRunTime_isArray: Symbol = getMemberMethod(ScalaRunTimeModule, newTermName("isArray")).suchThat(_.tpe.params.size == 2) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala index e375b2c3ff..993678bf48 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala @@ -641,8 +641,8 @@ trait PrepJSExports { this: PrepJSInterop => def ph = Ident(Predef_???) // Create a call to the forwarded method with ??? as args - val sel: Tree = Select(This(clsSym), defSym) - val call = (sel /: defSym.paramss) { + val sel = Select(This(clsSym), defSym) + val call = defSym.paramss.foldLeft[Tree](sel) { (fun, params) => Apply(fun, List.fill(params.size)(ph)) } @@ -687,8 +687,8 @@ trait PrepJSExports { this: PrepJSInterop => } // Construct proxied function call - val sel: Tree = Select(This(clsSym), trgSym) - val rhs = (sel /: proxySym.paramss) { + val sel = Select(This(clsSym), trgSym) + val rhs = proxySym.paramss.foldLeft[Tree](sel) { (fun,params) => Apply(fun, params map spliceParam) } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index 57c5e8281c..f0d58f6692 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -821,6 +821,18 @@ class JSExportTest extends DirectTest with TestHelpers { @Test def noOverrideNamedExport: Unit = { + val indent = { + val version = scala.util.Properties.versionNumberString + if (version.startsWith("2.10.") || + version.startsWith("2.11.") || + version.startsWith("2.12.") || + version == "2.13.0-M3") { + " " + } else { + " " + } + } + """ class A { @JSExportNamed @@ -840,7 +852,7 @@ class JSExportTest extends DirectTest with TestHelpers { | @JSExportNamed | ^ |newSource1.scala:9: error: overriding method $$js$$exported$$meth$$foo in class A of type (namedArgs: Any)Any; - | method $$js$$exported$$meth$$foo cannot override final member + |${indent}method $$js$$exported$$meth$$foo cannot override final member | @JSExportNamed | ^ |newSource1.scala:10: warning: class JSExportNamed in package annotation is deprecated${since("0.6.11")}: Use @JSExport with an explicit option bag instead. See the Scaladoc for more details. diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala index 1acdadd6cc..1937adcadc 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala @@ -7,6 +7,7 @@ import org.junit.Test import org.scalajs.core.ir.{Trees => js, Types => jstpe} class OptimizationTest extends JSASTTest { + import OptimizationTest._ @Test def unwrapScalaFunWrapper: Unit = { @@ -55,8 +56,7 @@ class OptimizationTest extends JSASTTest { } """. hasNot("any of the wrapArray methods") { - case js.Apply(_, js.Ident(name, _), _) - if name.startsWith("wrap") && name.endsWith("__scm_WrappedArray") => + case WrapArrayCall() => } } @@ -79,8 +79,7 @@ class OptimizationTest extends JSASTTest { } """. hasNot("any of the wrapArray methods") { - case js.Apply(_, js.Ident(name, _), _) - if name.startsWith("wrap") && name.endsWith("__scm_WrappedArray") => + case WrapArrayCall() => } /* #2265 and #2741: @@ -108,21 +107,30 @@ class OptimizationTest extends JSASTTest { } """. hasNot("any of the wrapArray methods") { - case js.Apply(_, js.Ident(name, _), _) - if name.startsWith("wrap") && name.endsWith("__scm_WrappedArray") => + case WrapArrayCall() => } - // Make sure our wrapper matcher has the right name - """ - import scala.scalajs.js - - class A { - val a: Seq[Int] = new Array[Int](5) + /* Make sure our wrapper matcher has the right name. + * With the new collections, only actual varargs will produce a call to the + * methods we optimize, and we would always be able to optimize them in + * that case. So we need to explicitly call the method that the codegen + * would use. + */ + val sanityCheckCode = if (hasOldCollections) { + """ + class A { + val a: Seq[Int] = new Array[Int](5) + } + """ + } else { + """ + class A { + runtime.ScalaRunTime.wrapIntArray(new Array[Int](5)) + } + """ } - """. - has("one of the wrapArray methods") { - case js.Apply(_, js.Ident(name, _), _) - if name.startsWith("wrap") && name.endsWith("__scm_WrappedArray") => + sanityCheckCode.has("one of the wrapArray methods") { + case WrapArrayCall() => } } @@ -258,3 +266,27 @@ class OptimizationTest extends JSASTTest { } } + +object OptimizationTest { + + private val hasOldCollections = { + val version = scala.util.Properties.versionNumberString + + version.startsWith("2.10.") || + version.startsWith("2.11.") || + version.startsWith("2.12.") || + version == "2.13.0-M3" + } + + private object WrapArrayCall { + private val Suffix = + if (hasOldCollections) "__scm_WrappedArray" + else "__sci_ArraySeq" + + def unapply(tree: js.Apply): Boolean = { + val methodName = tree.method.name + methodName.startsWith("wrap") && methodName.endsWith(Suffix) + } + } + +} diff --git a/javalib/src/main/scala/java/util/ArrayList.scala b/javalib/src/main/scala/java/util/ArrayList.scala index 8d600e70f9..1139d23434 100644 --- a/javalib/src/main/scala/java/util/ArrayList.scala +++ b/javalib/src/main/scala/java/util/ArrayList.scala @@ -66,7 +66,7 @@ class ArrayList[E] private (private[ArrayList] val inner: js.Array[E]) override def addAll(index: Int, c: Collection[_ <: E]): Boolean = { c match { case other: ArrayList[_] => - inner.splice(index, 0, other.inner: _*) + inner.splice(index, 0, other.inner.toSeq: _*) other.size > 0 case _ => super.addAll(index, c) } diff --git a/javalib/src/main/scala/java/util/Collections.scala b/javalib/src/main/scala/java/util/Collections.scala index 40e9934a7f..2e0d2482bb 100644 --- a/javalib/src/main/scala/java/util/Collections.scala +++ b/javalib/src/main/scala/java/util/Collections.scala @@ -537,7 +537,7 @@ object Collections { } def addAll[T](c: Collection[_ >: T], elements: Array[AnyRef]): Boolean = - c.addAll((elements.asInstanceOf[Array[T]]: Seq[T]).asJava) + c.addAll(elements.asInstanceOf[Array[T]].toSeq.asJava) def newSetFromMap[E](map: Map[E, java.lang.Boolean]): Set[E] = { if (!map.isEmpty) diff --git a/javalib/src/main/scala/java/util/Compat.scala b/javalib/src/main/scala/java/util/Compat.scala new file mode 100644 index 0000000000..363c1fb043 --- /dev/null +++ b/javalib/src/main/scala/java/util/Compat.scala @@ -0,0 +1,47 @@ +package java.util + +import scala.collection.mutable + +/** Make some Scala 2.13 APIs available in older Scala versions. */ +private[util] object Compat { + + /** Adds methods from 2.13 to `SortedSet`. + * + * The `to` operation has been renamed to `rangeTo` in 2.13, to not + * conflict with the `to` operation in `Iterable`. + */ + implicit class SortedSetCompat[A](val __private_self: mutable.SortedSet[A]) + extends AnyVal { + + @inline private def self: mutable.SortedSet[A] = __private_self + + /* Note: the double implicit conversion trick does not work here because + * there *is* a `to` method in 2.13 (but it takes a `Factory` as parameter) + * so the second implicit conversion is never triggered. + */ + def rangeTo(to: A): mutable.SortedSet[A] = { + // Implementation copied from 2.12's implementation + val i = self.rangeFrom(to).iterator + if (i.isEmpty) { + self + } else { + val next = i.next() + if (self.ordering.compare(next, to) == 0) { + if (i.isEmpty) self + else self.rangeUntil(i.next()) + } else { + self.rangeUntil(next) + } + } + } + + /* Note: the double implicit conversion trick does not work here either + * because the `from` and `until` methods still exist on 2.13 but they + * are deprecated. + */ + def rangeFrom(a: A): mutable.SortedSet[A] = self.rangeImpl(Some(a), None) + def rangeUntil(a: A): mutable.SortedSet[A] = self.rangeImpl(None, Some(a)) + + } + +} diff --git a/javalib/src/main/scala/java/util/NavigableView.scala b/javalib/src/main/scala/java/util/NavigableView.scala index 774a71f176..79e1a351aa 100644 --- a/javalib/src/main/scala/java/util/NavigableView.scala +++ b/javalib/src/main/scala/java/util/NavigableView.scala @@ -5,6 +5,8 @@ import scala.math.Ordering import scala.collection.mutable import scala.collection.JavaConverters._ +import Compat.SortedSetCompat + private[util] class NavigableView[E](original: NavigableSet[E], inner: () => mutable.SortedSet[Box[E]], lowerBound: Option[E], lowerInclusive: Boolean, @@ -135,10 +137,10 @@ private[util] class NavigableView[E](original: NavigableSet[E], val subSetFun = { () => val toTs = - if (toInclusive) innerNow.to(boxedTo) - else innerNow.until(boxedTo) - if (fromInclusive) toTs.from(boxedFrom) - else toTs.from(boxedFrom) - boxedFrom + if (toInclusive) innerNow.rangeTo(boxedTo) + else innerNow.rangeUntil(boxedTo) + if (fromInclusive) toTs.rangeFrom(boxedFrom) + else toTs.rangeFrom(boxedFrom).clone() -= boxedFrom } new NavigableView(this, subSetFun, @@ -151,8 +153,8 @@ private[util] class NavigableView[E](original: NavigableSet[E], val boxed = Box(toElement) val headSetFun = - if (inclusive) () => innerNow.to(boxed) - else () => innerNow.until(boxed) + if (inclusive) () => innerNow.rangeTo(boxed) + else () => innerNow.rangeUntil(boxed) new NavigableView(this, headSetFun, None, true, @@ -164,8 +166,8 @@ private[util] class NavigableView[E](original: NavigableSet[E], val boxed = Box(fromElement) val tailSetFun = - if (inclusive) () => innerNow.from(boxed) - else () => innerNow.from(boxed) - boxed + if (inclusive) () => innerNow.rangeFrom(boxed) + else () => innerNow.rangeFrom(boxed).clone() -= boxed new NavigableView(this, tailSetFun, Some(fromElement), inclusive, diff --git a/javalib/src/main/scala/java/util/TreeSet.scala b/javalib/src/main/scala/java/util/TreeSet.scala index 3b022d45e3..b7c50aae8e 100644 --- a/javalib/src/main/scala/java/util/TreeSet.scala +++ b/javalib/src/main/scala/java/util/TreeSet.scala @@ -7,6 +7,8 @@ import scala.math.Ordering import scala.collection.mutable import scala.collection.JavaConverters._ +import Compat.SortedSetCompat + class TreeSet[E] (_comparator: Comparator[_ >: E]) extends AbstractSet[E] with NavigableSet[E] @@ -141,16 +143,14 @@ class TreeSet[E] (_comparator: Comparator[_ >: E]) toInclusive: Boolean): NavigableSet[E] = { val boxedFrom = Box(fromElement) val boxedTo = Box(toElement) + val subSetFun = { () => - // the creation of a new TreeSet is to avoid a mysterious bug with scala 2.10 - var base = new mutable.TreeSet[Box[E]] + val base = new mutable.TreeSet[Box[E]] base ++= inner.range(boxedFrom, boxedTo) if (!fromInclusive) - base = base - boxedFrom - + base -= boxedFrom if (toInclusive && inner.contains(boxedTo)) - base = base + boxedTo - + base += boxedTo base } @@ -161,14 +161,13 @@ class TreeSet[E] (_comparator: Comparator[_ >: E]) def headSet(toElement: E, inclusive: Boolean): NavigableSet[E] = { val boxed = Box(toElement) + val headSetFun = { () => - // the creation of a new TreeSet is to avoid a mysterious bug with scala 2.10 - var base = new mutable.TreeSet[Box[E]] + val base = new mutable.TreeSet[Box[E]] if (inclusive) - base ++= inner.to(boxed) + base ++= inner.rangeTo(boxed) else - base ++= inner.until(boxed) - + base ++= inner.rangeUntil(boxed) base } @@ -179,13 +178,12 @@ class TreeSet[E] (_comparator: Comparator[_ >: E]) def tailSet(fromElement: E, inclusive: Boolean): NavigableSet[E] = { val boxed = Box(fromElement) + val tailSetFun = { () => - // the creation of a new TreeSet is to avoid a mysterious bug with scala 2.10 - var base = new mutable.TreeSet[Box[E]] - base ++= inner.from(boxed) + val base = new mutable.TreeSet[Box[E]] + base ++= inner.rangeFrom(boxed) if (!inclusive) base -= boxed - base } diff --git a/javalib/src/main/scala/java/util/regex/GroupStartMap.scala b/javalib/src/main/scala/java/util/regex/GroupStartMap.scala index 159f794063..bcf5bca4db 100644 --- a/javalib/src/main/scala/java/util/regex/GroupStartMap.scala +++ b/javalib/src/main/scala/java/util/regex/GroupStartMap.scala @@ -396,7 +396,7 @@ private[regex] class GroupStartMap(string: String, start: Int, pattern: Pattern) } node.setNewGroup(1) val groupNodeMap = node.getGroupNodeMap - node.transformGroupNumber(groupNodeMap.mapValues(_.newGroup)) + node.transformGroupNumber(groupNodeMap.mapValues(_.newGroup).toMap) val allMatchingRegexStr = node.buildRegex val allMatchingRegex = new js.RegExp(allMatchingRegexStr, flags) allMatchingRegex.lastIndex = start diff --git a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/Compat210Component.scala b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/Compat210Component.scala index 8ed56424a8..ca65d09e1a 100644 --- a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/Compat210Component.scala +++ b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/Compat210Component.scala @@ -66,6 +66,15 @@ trait Compat210Component { implicit final class DefinitionsCompat( self: Compat210Component.this.global.definitions.type) { + lazy val StringTpe = definitions.StringClass.tpe + + def wrapVarargsArrayMethodName(elemtp: Type): TermName = + self.wrapArrayMethodName(elemtp) + + def wrapArrayMethodName(elemtp: Type): TermName = infiniteLoop() } + + private def infiniteLoop(): Nothing = + throw new AssertionError("Infinite loop in Compat210Component") } diff --git a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala index a435ed42a0..f1fbaa40fb 100644 --- a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala +++ b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala @@ -182,9 +182,9 @@ class ScalaJSJUnitPlugin(val global: Global) extends NscPlugin { case (_, xs) => None } - val newStats = tree.stats.map(transform) ++ bootstrappers + val newStats = (tree.stats.map(transform).iterator ++ bootstrappers).toList - treeCopy.PackageDef(tree: Tree, tree.pid, newStats.toList) + treeCopy.PackageDef(tree: Tree, tree.pid, newStats) case _ => super.transform(tree) @@ -379,10 +379,14 @@ class ScalaJSJUnitPlugin(val global: Global) extends NscPlugin { } def mkList(elems: List[Tree]): Tree = { + val varargsModule = + if (hasNewCollections) definitions.ScalaRunTimeModule + else definitions.PredefModule + val array = ArrayValue(TypeTree(definitions.ObjectTpe), elems) val wrappedArray = gen.mkMethodCall( - definitions.PredefModule, - definitions.wrapArrayMethodName(definitions.ObjectTpe), + varargsModule, + definitions.wrapVarargsArrayMethodName(definitions.ObjectTpe), Nil, List(array)) gen.mkMethodCall(definitions.List_apply, List(wrappedArray)) } @@ -467,5 +471,13 @@ class ScalaJSJUnitPlugin(val global: Global) extends NscPlugin { Throw(exception) } } + + private lazy val hasNewCollections = { + val v = scala.util.Properties.versionNumberString + !v.startsWith("2.10.") && + !v.startsWith("2.11.") && + !v.startsWith("2.12.") && + v != "2.13.0-M3" + } } } diff --git a/junit-runtime/src/main/scala/org/hamcrest/BaseDescription.scala b/junit-runtime/src/main/scala/org/hamcrest/BaseDescription.scala index ef02a45642..c312c4845f 100644 --- a/junit-runtime/src/main/scala/org/hamcrest/BaseDescription.scala +++ b/junit-runtime/src/main/scala/org/hamcrest/BaseDescription.scala @@ -95,7 +95,7 @@ abstract class BaseDescription extends Description { protected def append(c: Char): Unit private def toJavaSyntax(unformatted: String): String = - s""""${unformatted.map(toJavaSyntax)}"""" // Note the four " + s""""${unformatted.map((ch: Char) => toJavaSyntax(ch))}"""" // Note the four " private def toJavaSyntax(ch: Char): String = { ch match { diff --git a/library/src/main/scala-new-collections/scala/scalajs/js/Any.scala b/library/src/main/scala-new-collections/scala/scalajs/js/Any.scala new file mode 100644 index 0000000000..f94d07ed0c --- /dev/null +++ b/library/src/main/scala-new-collections/scala/scalajs/js/Any.scala @@ -0,0 +1,193 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js API ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +/** + * All doc-comments marked as "MDN" are by Mozilla Contributors, + * distributed under the Creative Commons Attribution-ShareAlike license from + * https://developer.mozilla.org/en-US/docs/Web/Reference/API + */ +package scala.scalajs.js + +import scala.language.implicitConversions + +import scala.collection.BuildFrom +import scala.collection.mutable + +/** Root of the hierarchy of JavaScript types. + * + * Subtypes of [[Any js.Any]] are JavaScript types, which have different + * semantics and guarantees than Scala types (subtypes of [[AnyRef]] and + * [[AnyVal]]). Operations on JavaScript types behave as the corresponding + * operations in the JavaScript language. + * + * By default, JavaScript types are native: they are facade types to APIs + * implemented in JavaScript code. Their implementation is irrelevant and + * never emitted. As such, all members must be defined with their + * right-hand-side being [[native js.native]]. For forward source + * compatibility with the next major version, the class/trait/object itself + * should be annotated with [[native @js.native]]. This becomes mandatory with + * the compiler option `-P:scalajs:sjsDefinedByDefault`. + * + * In most cases, you should not directly extend this trait, but rather extend + * [[Object js.Object]]. + * + * To implement a JavaScript type in Scala.js (therefore non-native), you must + * add `-P:scalajs:sjsDefinedByDefault` to your scalac options. + * Scala.js-defined JS types cannot directly extend native JS traits; and + * Scala.js-defined JS traits cannot declare concrete term members. + * + * It is not possible to define traits or classes that inherit both from this + * trait and a strict subtype of [[AnyRef]]. In fact, you should think of + * [[Any js.Any]] as a third direct subclass of [[scala.Any]], besides + * [[scala.AnyRef]] and [[scala.AnyVal]]. + * + * See the [[http://www.scala-js.org/doc/js-interoperability.html JavaScript + * interoperability guide]] of Scala.js for more details. + */ +trait Any extends scala.AnyRef + +/** Provides implicit conversions from Scala values to JavaScript values. */ +object Any extends LowPrioAnyImplicits { + @inline implicit def fromUnit(value: Unit): Any = + value.asInstanceOf[Any] + @inline implicit def fromBoolean(value: Boolean): Any = + value.asInstanceOf[Any] + @inline implicit def fromByte(value: Byte): Any = + value.asInstanceOf[Any] + @inline implicit def fromShort(value: Short): Any = + value.asInstanceOf[Any] + @inline implicit def fromInt(value: Int): Any = + value.asInstanceOf[Any] + @inline implicit def fromLong(value: Long): Any = + value.toDouble.asInstanceOf[Any] + @inline implicit def fromFloat(value: Float): Any = + value.asInstanceOf[Any] + @inline implicit def fromDouble(value: Double): Any = + value.asInstanceOf[Any] + @inline implicit def fromString(s: String): Any = + s.asInstanceOf[Any] + + implicit def jsArrayOps[A](array: Array[A]): ArrayOps[A] = + new ArrayOps(array) + + implicit def buildFromArray[A]: BuildFrom[Array[_], A, Array[A]] = { + @inline + class BuildFromArray extends BuildFrom[Array[_], A, Array[A]] { + def fromSpecificIterable(from: Array[_])( + it: scala.collection.Iterable[A]): Array[A] = { + val b = newBuilder(from) + b.sizeHint(it) + b ++= it + b.result() + } + + def newBuilder(from: Array[_]): mutable.Builder[A, Array[A]] = + new ArrayOps[A] + } + + new BuildFromArray + } + + // scalastyle:off line.size.limit + + /* identity() is important! It prevents the tail-rec treatment in the absence + * of SAM treatment. + * + * When compiling without SAM treatment, the implicit expansion results in a + * self-recursive call to the implicit conversion. Without `identity()`, this + * recursive call is in tail position, and the tailcalls phase will convert + * it into an infinite loop. + * + * With `identity()`, the recursive call is not in tail position. The + * back-end therefore receives a call to the implicit conversion, *which is + * a primitive*, and therefore applies its primitive treatment, + * short-circuiting the infinite recursion. + * + * With proper SAM treatment, none of this happens, since there is no + * implicit materialization of a recursive call in the first place. + */ + implicit def fromFunction0[R](f: scala.Function0[R]): Function0[R] = identity(() => f()) + implicit def fromFunction1[T1, R](f: scala.Function1[T1, R]): Function1[T1, R] = identity((x1: T1) => f(x1)) + implicit def fromFunction2[T1, T2, R](f: scala.Function2[T1, T2, R]): Function2[T1, T2, R] = identity((x1: T1, x2: T2) => f(x1, x2)) + implicit def fromFunction3[T1, T2, T3, R](f: scala.Function3[T1, T2, T3, R]): Function3[T1, T2, T3, R] = identity((x1: T1, x2: T2, x3: T3) => f(x1, x2, x3)) + implicit def fromFunction4[T1, T2, T3, T4, R](f: scala.Function4[T1, T2, T3, T4, R]): Function4[T1, T2, T3, T4, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4) => f(x1, x2, x3, x4)) + implicit def fromFunction5[T1, T2, T3, T4, T5, R](f: scala.Function5[T1, T2, T3, T4, T5, R]): Function5[T1, T2, T3, T4, T5, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5) => f(x1, x2, x3, x4, x5)) + implicit def fromFunction6[T1, T2, T3, T4, T5, T6, R](f: scala.Function6[T1, T2, T3, T4, T5, T6, R]): Function6[T1, T2, T3, T4, T5, T6, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6) => f(x1, x2, x3, x4, x5, x6)) + implicit def fromFunction7[T1, T2, T3, T4, T5, T6, T7, R](f: scala.Function7[T1, T2, T3, T4, T5, T6, T7, R]): Function7[T1, T2, T3, T4, T5, T6, T7, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7) => f(x1, x2, x3, x4, x5, x6, x7)) + implicit def fromFunction8[T1, T2, T3, T4, T5, T6, T7, T8, R](f: scala.Function8[T1, T2, T3, T4, T5, T6, T7, T8, R]): Function8[T1, T2, T3, T4, T5, T6, T7, T8, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8) => f(x1, x2, x3, x4, x5, x6, x7, x8)) + implicit def fromFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R](f: scala.Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R]): Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9)) + implicit def fromFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R](f: scala.Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R]): Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)) + implicit def fromFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R](f: scala.Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R]): Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)) + implicit def fromFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R](f: scala.Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R]): Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12)) + implicit def fromFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R](f: scala.Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R]): Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13)) + implicit def fromFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R](f: scala.Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R]): Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14)) + implicit def fromFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R](f: scala.Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R]): Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15)) + implicit def fromFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R](f: scala.Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R]): Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16)) + implicit def fromFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R](f: scala.Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R]): Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17)) + implicit def fromFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R](f: scala.Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R]): Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18)) + implicit def fromFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R](f: scala.Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R]): Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19)) + implicit def fromFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R](f: scala.Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R]): Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20)) + implicit def fromFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R](f: scala.Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R]): Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20, x21: T21) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21)) + implicit def fromFunction22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R](f: scala.Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R]): Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R] = identity((x1: T1, x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20, x21: T21, x22: T22) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22)) + + implicit def toFunction0[R](f: Function0[R]): scala.Function0[R] = () => f() + implicit def toFunction1[T1, R](f: Function1[T1, R]): scala.Function1[T1, R] = (x1) => f(x1) + implicit def toFunction2[T1, T2, R](f: Function2[T1, T2, R]): scala.Function2[T1, T2, R] = (x1, x2) => f(x1, x2) + implicit def toFunction3[T1, T2, T3, R](f: Function3[T1, T2, T3, R]): scala.Function3[T1, T2, T3, R] = (x1, x2, x3) => f(x1, x2, x3) + implicit def toFunction4[T1, T2, T3, T4, R](f: Function4[T1, T2, T3, T4, R]): scala.Function4[T1, T2, T3, T4, R] = (x1, x2, x3, x4) => f(x1, x2, x3, x4) + implicit def toFunction5[T1, T2, T3, T4, T5, R](f: Function5[T1, T2, T3, T4, T5, R]): scala.Function5[T1, T2, T3, T4, T5, R] = (x1, x2, x3, x4, x5) => f(x1, x2, x3, x4, x5) + implicit def toFunction6[T1, T2, T3, T4, T5, T6, R](f: Function6[T1, T2, T3, T4, T5, T6, R]): scala.Function6[T1, T2, T3, T4, T5, T6, R] = (x1, x2, x3, x4, x5, x6) => f(x1, x2, x3, x4, x5, x6) + implicit def toFunction7[T1, T2, T3, T4, T5, T6, T7, R](f: Function7[T1, T2, T3, T4, T5, T6, T7, R]): scala.Function7[T1, T2, T3, T4, T5, T6, T7, R] = (x1, x2, x3, x4, x5, x6, x7) => f(x1, x2, x3, x4, x5, x6, x7) + implicit def toFunction8[T1, T2, T3, T4, T5, T6, T7, T8, R](f: Function8[T1, T2, T3, T4, T5, T6, T7, T8, R]): scala.Function8[T1, T2, T3, T4, T5, T6, T7, T8, R] = (x1, x2, x3, x4, x5, x6, x7, x8) => f(x1, x2, x3, x4, x5, x6, x7, x8) + implicit def toFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R](f: Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R]): scala.Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9) + implicit def toFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R](f: Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R]): scala.Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) + implicit def toFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R](f: Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R]): scala.Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11) + implicit def toFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R](f: Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R]): scala.Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12) + implicit def toFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R](f: Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R]): scala.Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13) + implicit def toFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R](f: Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R]): scala.Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14) + implicit def toFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R](f: Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R]): scala.Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) + implicit def toFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R](f: Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R]): scala.Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16) + implicit def toFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R](f: Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R]): scala.Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17) + implicit def toFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R](f: Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R]): scala.Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18) + implicit def toFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R](f: Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R]): scala.Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19) + implicit def toFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R](f: Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R]): scala.Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20) + implicit def toFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R](f: Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R]): scala.Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21) + implicit def toFunction22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R](f: Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R]): scala.Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22) + // scalastyle:on line.size.limit + + @inline implicit def fromJBoolean(value: java.lang.Boolean): Any = + value.asInstanceOf[Any] + @inline implicit def fromJByte(value: java.lang.Byte): Any = + value.asInstanceOf[Any] + @inline implicit def fromJShort(value: java.lang.Short): Any = + value.asInstanceOf[Any] + @inline implicit def fromJInteger(value: java.lang.Integer): Any = + value.asInstanceOf[Any] + + @inline implicit def fromJLong(value: java.lang.Long): Any = + if (value eq null) null + else value.doubleValue.asInstanceOf[Any] + + @inline implicit def fromJFloat(value: java.lang.Float): Any = + value.asInstanceOf[Any] + @inline implicit def fromJDouble(value: java.lang.Double): Any = + value.asInstanceOf[Any] +} + +trait LowPrioAnyImplicits extends LowestPrioAnyImplicits { + implicit def wrapArray[A](array: Array[A]): WrappedArray[A] = + new WrappedArray(array) + implicit def wrapDictionary[A](dict: Dictionary[A]): WrappedDictionary[A] = + new WrappedDictionary(dict) +} + +sealed trait LowestPrioAnyImplicits { + implicit def iterableOps[A](iterable: Iterable[A]): IterableOps[A] = + new IterableOps(iterable) +} diff --git a/library/src/main/scala-new-collections/scala/scalajs/js/ArrayOps.scala b/library/src/main/scala-new-collections/scala/scalajs/js/ArrayOps.scala new file mode 100644 index 0000000000..9ad52d162c --- /dev/null +++ b/library/src/main/scala-new-collections/scala/scalajs/js/ArrayOps.scala @@ -0,0 +1,104 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js API ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2018, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package scala.scalajs.js + +import scala.collection.mutable +import scala.collection.{IterableOnce, SeqFactory, StrictOptimizedSeqOps} + +import scala.scalajs.js + +/** Equivalent of scm.ArrayOps for js.Array */ +@inline +final class ArrayOps[A](private[this] val array: js.Array[A]) + extends StrictOptimizedSeqOps[A, js.Array, js.Array[A]] + with mutable.IndexedSeqOps[A, js.Array, js.Array[A]] + with mutable.Builder[A, js.Array[A]] { + + import ArrayOps._ + + /** Creates a new empty [[ArrayOps]]. */ + def this() = this(js.Array()) + + // Implementation of IndexedSeqOps + + @inline def apply(index: Int): A = array(index) + @inline def length: Int = array.length + @inline def update(index: Int, element: A): Unit = array(index) = element + + def seq: scala.collection.IndexedSeq[A] = new WrappedArray(array) + + def repr: js.Array[A] = array + + def iterableFactory: scala.collection.SeqFactory[js.Array] = ArrayFactory + + protected[this] def coll: js.Array[A] = array + + protected[this] def fromSpecificIterable( + coll: scala.collection.Iterable[A]): js.Array[A] = { + iterableFactory.from(coll) + } + + protected[this] def newSpecificBuilder: mutable.Builder[A, js.Array[A]] = + iterableFactory.newBuilder[A] + + def toIterable: scala.collection.Iterable[A] = js.Any.wrapArray(array) + + // Implementation of Builder + + @inline final def addOne(elem: A): this.type = { + array.push(elem) + this + } + + @inline def clear(): Unit = + array.length = 0 + + @inline def result(): js.Array[A] = array + + // Scala notation for a fast concat() + + @inline def ++[B >: A](that: js.Array[_ <: B]): js.Array[B] = + ArrayOpsCommon.concat(array, that) + + // Methods whose inherited implementations do not play nice with the optimizer + + @inline override def reduceLeft[B >: A](op: (B, A) => B): B = + ArrayOpsCommon.reduceLeft(array, op) + + @inline override def reduceRight[B >: A](op: (A, B) => B): B = + ArrayOpsCommon.reduceRight(array, op) + + // Inspired by mutable.IndexedOptimizedSeq + + def mapInPlace(f: A => A): this.type = { + var i = 0 + val size = this.size + while (i < size) { + this(i) = f(this(i)) + i += 1 + } + this + } + +} + +private object ArrayOps { + private object ArrayFactory extends SeqFactory[js.Array] { + @inline + def empty[A]: js.Array[A] = js.Array() + + @inline + def from[A](source: IterableOnce[A]): js.Array[A] = + (newBuilder[A] ++= source).result() + + @inline + def newBuilder[A]: mutable.Builder[A, js.Array[A]] = + new ArrayOps[A] + } +} diff --git a/library/src/main/scala-new-collections/scala/scalajs/js/JSConverters.scala b/library/src/main/scala-new-collections/scala/scalajs/js/JSConverters.scala new file mode 100644 index 0000000000..b67366830a --- /dev/null +++ b/library/src/main/scala-new-collections/scala/scalajs/js/JSConverters.scala @@ -0,0 +1,152 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js API ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package scala.scalajs.js + +import scala.language.implicitConversions + +import scala.scalajs.js +import scala.scalajs.js.annotation.{JSName, ScalaJSDefined} + +import scala.collection._ +import scala.concurrent.{ExecutionContext, Future} + +import scala.scalajs.runtime.genTraversableOnce2jsArray + +sealed abstract class JSConvertersLowPrioImplicits { this: JSConverters.type => + + @inline + implicit def JSRichFutureNonThenable[A](f: Future[A]): JSRichFuture[A] = + new JSRichFuture[A](f.asInstanceOf[Future[A | Thenable[A]]]) + +} + +/** A collection of decorators that allow converting Scala types to + * corresponding JS facade types + */ +object JSConverters extends JSConvertersLowPrioImplicits { + + implicit class JSRichOption[T](val opt: Option[T]) extends AnyVal { + @inline final def orUndefined: UndefOr[T] = + opt.fold[UndefOr[T]](undefined)(v => v) + } + + implicit class JSRichIterableOnce[T]( + val col: IterableOnce[T]) extends AnyVal { + final def toJSArray: Array[T] = { + /* This is basically a duplicate of `runtime.genTraversableOnce2jsArray`, + * except it is not marked `@inline`. We do not want to inline this + * method every time someone does `.toJSArray`, for code size reasons + * (unlike `genTraversableOnce2jsArray`, which is used by the codegen for + * transferring Scala varargs to JS varargs). + * + * One would think that we could still delegate to + * `genTraversableOnce2jsArray` and mark `toJSArray` with `@noinline` + * instead, but that would prevent `toJSArray` to be inlined even when + * `col` is stack-allocated (and we do want that to happen as in that + * case the entire match disappears and `col` can stay stack-allocated). + */ + col match { + case col: js.ArrayOps[T] => col.repr + case col: js.WrappedArray[T] => col.array + case _ => + val result = new js.Array[T] + col.iterator.foreach(x => result.push(x)) + result + } + } + } + + implicit class JSRichIterable[T]( + val __self: scala.collection.Iterable[T]) extends AnyVal { + @inline final def toJSIterable: Iterable[T] = new IterableAdapter(__self) + } + + implicit class JSRichIterator[T]( + val __self: scala.collection.Iterator[T]) extends AnyVal { + @inline final def toJSIterator: Iterator[T] = new IteratorAdapter(__self) + } + + private class IterableAdapter[+T](col: collection.Iterable[T]) extends Iterable[T] { + @JSName(Symbol.iterator) + final def jsIterator(): Iterator[T] = col.iterator.toJSIterator + } + + private class IteratorAdapter[+T]( + it: scala.collection.Iterator[T]) extends Iterator[T] { + final def next(): Iterator.Entry[T] = { + if (it.hasNext) { + new Iterator.Entry[T] { + val done: Boolean = false + val value: T = it.next() + } + } else { + new Iterator.Entry[T] { + val done: Boolean = true + // Evil cast to work around typing. By specification, reading `value` + // is undefined behavior, so this is ok. + val value: T = js.undefined.asInstanceOf[T] + } + } + } + } + + implicit class JSRichMap[T](val map: Map[String, T]) extends AnyVal { + @inline final def toJSDictionary: Dictionary[T] = { + val result = Dictionary.empty[T] + map.foreach { case (key, value) => result(key) = value } + result + } + } + + @inline + implicit def iterableOnceConvertible2JSRichIterableOnce[T, C](coll: C)( + implicit ev: C => IterableOnce[T]): JSRichIterableOnce[T] = + new JSRichIterableOnce(coll) + + /** Special case for scala.Array of [[iterableOnceConvertible2JSRichIterableOnce]]. + * Needed for the 2.10.x series. + */ + @inline + implicit def array2JSRichIterableOnce[T]( + arr: scala.Array[T]): JSRichIterableOnce[T] = + new JSRichIterableOnce(arr) + + @inline + implicit def JSRichFutureThenable[A](f: Future[Thenable[A]]): JSRichFuture[A] = + new JSRichFuture[A](f.asInstanceOf[Future[A | Thenable[A]]]) + + final class JSRichFuture[A](val self: Future[A | Thenable[A]]) extends AnyVal { + /** Converts the Future to a JavaScript [[Promise]]. + * + * Attention! The nature of the [[Promise]] class, from the ECMAScript + * specification, makes this method inherently un-typeable, because it is + * not type parametric. + * + * The signature of the `toJSPromise` method is only valid + * provided that the values of `A` do not have a `then` method. + */ + def toJSPromise(implicit executor: ExecutionContext): Promise[A] = { + new Promise[A]({ + (resolve: js.Function1[A | Thenable[A], _], reject: js.Function1[scala.Any, _]) => + self onComplete { + case scala.util.Success(value) => + resolve(value) + + case scala.util.Failure(th) => + reject(th match { + case JavaScriptException(e) => e + case _ => th + }) + } + }) + } + } + +} diff --git a/library/src/main/scala-new-collections/scala/scalajs/js/WrappedArray.scala b/library/src/main/scala-new-collections/scala/scalajs/js/WrappedArray.scala new file mode 100644 index 0000000000..a48b720f3d --- /dev/null +++ b/library/src/main/scala-new-collections/scala/scalajs/js/WrappedArray.scala @@ -0,0 +1,101 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js API ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package scala.scalajs.js + +import scala.language.implicitConversions + +import scala.collection.mutable +import scala.collection.{SeqFactory, StrictOptimizedSeqFactory, StrictOptimizedSeqOps} + +import scala.scalajs.js + +/** Equivalent of scm.WrappedArray for js.Array */ +@inline +final class WrappedArray[A](val array: js.Array[A]) + extends mutable.AbstractBuffer[A] + with StrictOptimizedSeqOps[A, WrappedArray, WrappedArray[A]] + with mutable.IndexedSeq[A] + with mutable.IndexedSeqOps[A, WrappedArray, WrappedArray[A]] + with mutable.IndexedOptimizedBuffer[A] + with mutable.Builder[A, WrappedArray[A]] + with Serializable { + + /** Creates a new empty [[WrappedArray]]. */ + def this() = this(js.Array()) + + override def iterableFactory: SeqFactory[WrappedArray] = WrappedArray + + // IndexedSeq interface + + @inline def update(index: Int, elem: A): Unit = array(index) = elem + @inline def apply(index: Int): A = array(index) + @inline def length: Int = array.length + + // Builder interface + + @inline def addOne(elem: A): this.type = { + array.push(elem) + this + } + + @inline def clear(): Unit = + array.length = 0 + + @inline def result(): WrappedArray[A] = this + + // Rest of Buffer interface + + @inline def prepend(elem: A): this.type = { + array.unshift(elem) + this + } + + @inline override def prependAll(xs: IterableOnce[A]): this.type = { + array.unshift(xs.iterator.toSeq: _*) + this + } + + @inline def subtractOne(elem: A): this.type = { + val i = indexOf(elem) + if (i != -1) remove(i) + this + } + + @inline def insert(idx: Int, elem: A): Unit = + array.splice(idx, 0, elem) + + @inline + def insertAll(n: Int, elems: scala.collection.IterableOnce[A]): Unit = + array.splice(n, 0, elems.iterator.toSeq: _*) + + @inline def remove(n: Int): A = + array.splice(n, 1)(0) + + @inline override def remove(n: Int, count: Int): Unit = + array.splice(n, count) + + @inline override def className: String = "WrappedArray" + +} + +/** Factory for [[WrappedArray]]. Provides implicit conversion to [[Array]]. + */ +object WrappedArray extends StrictOptimizedSeqFactory[WrappedArray] { + + def empty[A]: WrappedArray[A] = new WrappedArray[A]() + + def newBuilder[A]: mutable.Builder[A, WrappedArray[A]] = new WrappedArray[A] + + def from[A](source: IterableOnce[A]): WrappedArray[A] = + (newBuilder[A] ++= source).result() + + implicit def toJSArray[A](wrappedArray: WrappedArray[A]): js.Array[A] = + wrappedArray.array + +} diff --git a/library/src/main/scala-new-collections/scala/scalajs/js/WrappedDictionary.scala b/library/src/main/scala-new-collections/scala/scalajs/js/WrappedDictionary.scala new file mode 100644 index 0000000000..ffb6c67443 --- /dev/null +++ b/library/src/main/scala-new-collections/scala/scalajs/js/WrappedDictionary.scala @@ -0,0 +1,181 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js API ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package scala.scalajs.js + +import scala.collection.mutable +import scala.collection.mutable.Builder +import scala.collection.View + +import scala.scalajs.js +import scala.scalajs.js.annotation._ + +/** Wrapper to use a js.Dictionary as a scala.mutable.Map */ +@inline +class WrappedDictionary[A](val dict: js.Dictionary[A]) + extends mutable.AbstractMap[String, A] + with mutable.MapOps[String, A, mutable.Map, WrappedDictionary[A]] { + + import WrappedDictionary._ + + protected[this] override def fromSpecificIterable( + coll: scala.collection.Iterable[(String, A)] + ): WrappedDictionary[A] = { + val d = WrappedDictionary.empty[A] + d ++= coll + d + } + + protected[this] override def newSpecificBuilder: Builder[(String, A), WrappedDictionary[A]] = + new WrappedDictionary.WrappedDictionaryBuilder[A] + + def get(key: String): Option[A] = { + if (contains(key)) + Some(rawApply(key)) + else + None + } + + override def apply(key: String): A = { + if (contains(key)) + rawApply(key) + else + throw new NoSuchElementException("key not found: " + key) + } + + @inline + private def rawApply(key: String): A = + dict.asInstanceOf[DictionaryRawApply[A]].rawApply(key) + + override def contains(key: String): Boolean = { + /* We have to use a safe version of hasOwnProperty, because + * "hasOwnProperty" could be a key of this dictionary. + */ + safeHasOwnProperty(dict, key) + } + + def subtractOne(key: String): this.type = { + if (contains(key)) + js.special.delete(dict, key) + this + } + + override def update(key: String, value: A): Unit = + dict.update(key, value) + + def addOne(kv: (String, A)): this.type = { + dict(kv._1) = kv._2 + this + } + + def clear(): Unit = + keysIterator.foreach(subtractOne) + + def iterator: scala.collection.Iterator[(String, A)] = + new DictionaryIterator(dict) + + @inline + override def keys: scala.collection.Iterable[String] = + js.Object.keys(dict.asInstanceOf[js.Object]) + + override def empty: WrappedDictionary[A] = + new WrappedDictionary(js.Dictionary.empty) + + // Overloads to return more precise types + + def map[B](f: ((String, A)) => (String, B)): WrappedDictionary[B] = { + val b = new WrappedDictionary.WrappedDictionaryBuilder[B] + val it = this.iterator + while (it.hasNext) { + b += f(it.next()) + } + b.result() + } + + def flatMap[B]( + f: ((String, A)) => IterableOnce[(String, B)]): WrappedDictionary[B] = { + val b = new WrappedDictionary.WrappedDictionaryBuilder[B] + val it = this.iterator + while (it.hasNext) { + b ++= f(it.next()) + } + b.result() + } + + def collect[B]( + pf: PartialFunction[(String, A), (String, B)]): WrappedDictionary[B] = { + flatMap { a => + if (pf.isDefinedAt(a)) new View.Single(pf(a)) + else View.Empty + } + } + +} + +object WrappedDictionary { + /* Note: We can't extend MapFactory[WrappedDictionary] since it requires + * support for any type of key. + */ + + private object Cache { + val safeHasOwnProperty = { + js.Dynamic.global.Object.prototype.hasOwnProperty + .asInstanceOf[js.ThisFunction1[js.Dictionary[_], String, Boolean]] + } + } + + @inline + private def safeHasOwnProperty(dict: Dictionary[_], key: String): Boolean = + Cache.safeHasOwnProperty(dict, key) + + @js.native + private trait DictionaryRawApply[A] extends js.Object { + /** Reads a field of this object by its name. + * + * This must not be called if the dictionary does not contain the key. + */ + @JSBracketAccess + def rawApply(key: String): A = native + } + + private final class DictionaryIterator[+A](dict: Dictionary[A]) + extends scala.collection.Iterator[(String, A)] { + + private[this] val keys = js.Object.keys(dict.asInstanceOf[Object]) + private[this] var index: Int = 0 + + def hasNext(): Boolean = index < keys.length + + def next(): (String, A) = { + val key = keys(index) + index += 1 + (key, dict(key)) + } + } + + def empty[A]: WrappedDictionary[A] = + new WrappedDictionary(js.Dictionary.empty) + + private final class WrappedDictionaryBuilder[A] + extends Builder[(String, A), WrappedDictionary[A]] { + + private[this] var dict: js.Dictionary[A] = js.Dictionary.empty + + def addOne(elem: (String, A)): this.type = { + dict(elem._1) = elem._2 + this + } + + def clear(): Unit = + dict = js.Dictionary.empty + + def result(): WrappedDictionary[A] = + new WrappedDictionary(dict) + } + +} diff --git a/library/src/main/scala-new-collections/scala/scalajs/runtime/Compat.scala b/library/src/main/scala-new-collections/scala/scalajs/runtime/Compat.scala new file mode 100644 index 0000000000..fdd82cc41f --- /dev/null +++ b/library/src/main/scala-new-collections/scala/scalajs/runtime/Compat.scala @@ -0,0 +1,26 @@ +package scala.scalajs.runtime + +import scala.collection.IterableOnce + +import scala.scalajs.js + +private[runtime] object Compat { + + type CompatTraversableOnce[+A] = IterableOnce[A] + + @inline def toScalaVarArgsImpl[A](array: js.Array[A]): Seq[A] = + WrappedVarArgs.wrap(array) + + @inline def genTraversableOnce2jsArrayImpl[A]( + col: CompatTraversableOnce[A]): js.Array[A] = { + col match { + case col: js.ArrayOps[A] => col.result() + case col: js.WrappedArray[A] => col.array + case _ => + val result = new js.Array[A] + col.iterator.foreach(x => result.push(x)) + result + } + } + +} diff --git a/library/src/main/scala-new-collections/scala/scalajs/runtime/WrappedVarArgs.scala b/library/src/main/scala-new-collections/scala/scalajs/runtime/WrappedVarArgs.scala new file mode 100644 index 0000000000..044f521f5e --- /dev/null +++ b/library/src/main/scala-new-collections/scala/scalajs/runtime/WrappedVarArgs.scala @@ -0,0 +1,49 @@ +package scala.scalajs.runtime + +import scala.collection.immutable +import scala.collection.mutable +import scala.collection.{IterableOnce, SeqFactory, StrictOptimizedSeqFactory} + +import scala.scalajs.js + +/** An immutable wrapper for `js.Array` to show it as an `s.c.i.Seq`. + * + * TODO Eventually we should expose this in the public API under + * `scala.scalajs.js`, but the naming should be carefully thought through, + * especially wrt. the existing `js.WrappedArray`. + */ +@inline +private[runtime] final class WrappedVarArgs[+A] private (array: js.Array[A]) + extends immutable.IndexedSeq[A] + with immutable.IndexedSeqOps[A, WrappedVarArgs, WrappedVarArgs[A]] + with immutable.StrictOptimizedSeqOps[A, WrappedVarArgs, WrappedVarArgs[A]] + with Serializable { + + /** Creates a new empty [[WrappedVarArgs]]. */ + def this() = this(js.Array()) + + override def iterableFactory: SeqFactory[WrappedVarArgs] = WrappedVarArgs + + def length: Int = array.length + + def apply(idx: Int): A = array(idx) + + @inline override def className: String = "WrappedVarArgs" + +} + +private[runtime] object WrappedVarArgs + extends StrictOptimizedSeqFactory[WrappedVarArgs] { + + // This method must stay private when we make the class itself public. + @inline private[runtime] def wrap[A](array: js.Array[A]): WrappedVarArgs[A] = + new WrappedVarArgs(array) + + def empty[A]: WrappedVarArgs[A] = new WrappedVarArgs[Nothing]() + + def from[A](source: IterableOnce[A]): WrappedVarArgs[A] = + (newBuilder[A] ++= source).result() + + def newBuilder[A]: mutable.Builder[A, WrappedVarArgs[A]] = + js.Array[A]().mapResult(new WrappedVarArgs(_)) +} diff --git a/library/src/main/scala/scala/scalajs/js/Any.scala b/library/src/main/scala-old-collections/scala/scalajs/js/Any.scala similarity index 100% rename from library/src/main/scala/scala/scalajs/js/Any.scala rename to library/src/main/scala-old-collections/scala/scalajs/js/Any.scala diff --git a/library/src/main/scala/scala/scalajs/js/ArrayOps.scala b/library/src/main/scala-old-collections/scala/scalajs/js/ArrayOps.scala similarity index 56% rename from library/src/main/scala/scala/scalajs/js/ArrayOps.scala rename to library/src/main/scala-old-collections/scala/scalajs/js/ArrayOps.scala index f7948ca092..f5cad74030 100644 --- a/library/src/main/scala/scala/scalajs/js/ArrayOps.scala +++ b/library/src/main/scala-old-collections/scala/scalajs/js/ArrayOps.scala @@ -19,8 +19,6 @@ final class ArrayOps[A](private[this] val array: Array[A]) extends mutable.ArrayLike[A, Array[A]] with Builder[A, Array[A]] { - import ArrayOps._ - /** Creates a new empty [[ArrayOps]]. */ def this() = this(Array()) @@ -57,63 +55,17 @@ final class ArrayOps[A](private[this] val array: Array[A]) // Scala notation for a fast concat() @inline def ++[B >: A](that: Array[_ <: B]): Array[B] = - concat(array, that) + ArrayOpsCommon.concat(array, that) // Methods whose inherited implementations do not play nice with the optimizer - override def reduceLeft[B >: A](op: (B, A) => B): B = { - val length = this.length - if (length <= 0) - throwUnsupported("empty.reduceLeft") - - @inline - @tailrec - def loop(start: Int, z: B): B = - if (start == length) z - else loop(start+1, op(z, this(start))) - - loop(1, this(0)) - } - - override def reduceRight[B >: A](op: (A, B) => B): B = { - val length = this.length - if (length <= 0) - throwUnsupported("empty.reduceRight") + override def reduceLeft[B >: A](op: (B, A) => B): B = + ArrayOpsCommon.reduceLeft(array, op) - @inline - @tailrec - def loop(end: Int, z: B): B = - if (end == 0) z - else loop(end-1, op(this(end-1), z)) - - loop(length-1, this(length-1)) - } + override def reduceRight[B >: A](op: (A, B) => B): B = + ArrayOpsCommon.reduceRight(array, op) } -object ArrayOps { - - /** Extract the throw in a separate, non-inlineable method. */ - private def throwUnsupported(msg: String): Nothing = - throw new UnsupportedOperationException(msg) - - /** Non-inlined implementation of [[ArrayOps.++]]. */ - private def concat[A](left: Array[_ <: A], right: Array[_ <: A]): Array[A] = { - val leftLength = left.length - val rightLength = right.length - val result = new Array[A](leftLength + rightLength) - - @inline - @tailrec - def loop(src: Array[_ <: A], i: Int, len: Int, offset: Int): Unit = - if (i != len) { - result(i+offset) = src(i) - loop(src, i+1, len, offset) - } - - loop(left, 0, leftLength, 0) - loop(right, 0, rightLength, leftLength) - result - } - -} +@deprecated("Kept only for binary compatibility", "0.6.23") +object ArrayOps diff --git a/library/src/main/scala/scala/scalajs/js/JSConverters.scala b/library/src/main/scala-old-collections/scala/scalajs/js/JSConverters.scala similarity index 100% rename from library/src/main/scala/scala/scalajs/js/JSConverters.scala rename to library/src/main/scala-old-collections/scala/scalajs/js/JSConverters.scala diff --git a/library/src/main/scala/scala/scalajs/js/WrappedArray.scala b/library/src/main/scala-old-collections/scala/scalajs/js/WrappedArray.scala similarity index 100% rename from library/src/main/scala/scala/scalajs/js/WrappedArray.scala rename to library/src/main/scala-old-collections/scala/scalajs/js/WrappedArray.scala diff --git a/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala b/library/src/main/scala-old-collections/scala/scalajs/js/WrappedDictionary.scala similarity index 100% rename from library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala rename to library/src/main/scala-old-collections/scala/scalajs/js/WrappedDictionary.scala diff --git a/library/src/main/scala-old-collections/scala/scalajs/runtime/Compat.scala b/library/src/main/scala-old-collections/scala/scalajs/runtime/Compat.scala new file mode 100644 index 0000000000..14ba7868c7 --- /dev/null +++ b/library/src/main/scala-old-collections/scala/scalajs/runtime/Compat.scala @@ -0,0 +1,25 @@ +package scala.scalajs.runtime + +import scala.collection.GenTraversableOnce +import scala.scalajs.js + +private[runtime] object Compat { + + type CompatTraversableOnce[+A] = GenTraversableOnce[A] + + @inline def toScalaVarArgsImpl[A](array: js.Array[A]): Seq[A] = + new js.WrappedArray(array) + + @inline def genTraversableOnce2jsArrayImpl[A]( + col: CompatTraversableOnce[A]): js.Array[A] = { + col match { + case col: js.ArrayOps[A] => col.result() + case col: js.WrappedArray[A] => col.array + case _ => + val result = new js.Array[A] + col.foreach(x => result.push(x)) + result + } + } + +} diff --git a/library/src/main/scala/scala/scalajs/js/ArrayOpsCommon.scala b/library/src/main/scala/scala/scalajs/js/ArrayOpsCommon.scala new file mode 100644 index 0000000000..bd75b685e0 --- /dev/null +++ b/library/src/main/scala/scala/scalajs/js/ArrayOpsCommon.scala @@ -0,0 +1,67 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js API ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2018, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + +package scala.scalajs.js + +import scala.annotation.tailrec + +private[js] object ArrayOpsCommon { + + /** Efficient concatenation of two JS arrays. */ + def concat[A](left: Array[_ <: A], right: Array[_ <: A]): Array[A] = { + val leftLength = left.length + val rightLength = right.length + val result = new Array[A](leftLength + rightLength) + + @inline + @tailrec + def loop(src: Array[_ <: A], i: Int, len: Int, offset: Int): Unit = { + if (i != len) { + result(i+offset) = src(i) + loop(src, i+1, len, offset) + } + } + + loop(left, 0, leftLength, 0) + loop(right, 0, rightLength, leftLength) + result + } + + def reduceLeft[A, B >: A](array: Array[A], op: (B, A) => B): B = { + val length = array.length + if (length <= 0) + throwUnsupported("empty.reduceLeft") + + @inline + @tailrec + def loop(start: Int, z: B): B = + if (start == length) z + else loop(start+1, op(z, array(start))) + + loop(1, array(0)) + } + + def reduceRight[A, B >: A](array: Array[A], op: (A, B) => B): B = { + val length = array.length + if (length <= 0) + throwUnsupported("empty.reduceRight") + + @inline + @tailrec + def loop(end: Int, z: B): B = + if (end == 0) z + else loop(end-1, op(array(end-1), z)) + + loop(length-1, array(length-1)) + } + + /** Extract the throw in a separate, non-inlineable method. */ + private def throwUnsupported(msg: String): Nothing = + throw new UnsupportedOperationException(msg) + +} diff --git a/library/src/main/scala/scala/scalajs/runtime/package.scala b/library/src/main/scala/scala/scalajs/runtime/package.scala index 64e530ade7..7380b33f4f 100644 --- a/library/src/main/scala/scala/scalajs/runtime/package.scala +++ b/library/src/main/scala/scala/scalajs/runtime/package.scala @@ -2,10 +2,10 @@ package scala.scalajs import scala.annotation.tailrec -import scala.collection.GenTraversableOnce - package object runtime { + import scala.scalajs.runtime.Compat._ + @deprecated("Use scala.scalajs.LinkingInfo.assumingES6 instead.", "0.6.6") @inline def assumingES6: Boolean = @@ -80,16 +80,12 @@ package object runtime { // scalastyle:on return } + @inline def toScalaVarArgs[A](array: js.Array[A]): Seq[A] = + toScalaVarArgsImpl(array) + @inline final def genTraversableOnce2jsArray[A]( - col: GenTraversableOnce[A]): js.Array[A] = { - col match { - case col: js.ArrayOps[A] => col.result() - case col: js.WrappedArray[A] => col.array - case _ => - val result = new js.Array[A] - col.foreach(x => result.push(x)) - result - } + col: CompatTraversableOnce[A]): js.Array[A] = { + genTraversableOnce2jsArrayImpl(col) } final def jsTupleArray2jsObject( @@ -111,7 +107,7 @@ package object runtime { @deprecated("Use js.Dynamic.newInstance instead.", "0.6.3") @inline def newJSObjectWithVarargs(ctor: js.Dynamic, args: js.Array[_]): js.Any = - js.Dynamic.newInstance(ctor)(args.asInstanceOf[js.Array[js.Any]]: _*) + js.Dynamic.newInstance(ctor)(args.asInstanceOf[js.Array[js.Any]].toSeq: _*) /** Dummy method used to preserve the type parameter of * `js.constructorOf[T]` through erasure. diff --git a/project/Build.scala b/project/Build.scala index 229b60b59c..cfe9b61e2d 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -63,6 +63,20 @@ object Build { val previousBinaryCrossVersion = CrossVersion.binaryMapped(v => s"sjs${previousSJSBinaryVersion}_$v") + def hasNewCollections(version: String): Boolean = { + !version.startsWith("2.10.") && + !version.startsWith("2.11.") && + !version.startsWith("2.12.") && + version != "2.13.0-M3" + } + + /** Returns the appropriate subdirectory of `sourceDir` depending on whether + * the `scalaV` uses the new collections (introduced in 2.13.0-M4) or not. + */ + def collectionsEraDependentDirectory(scalaV: String, sourceDir: File): File = + if (hasNewCollections(scalaV)) sourceDir / "scala-new-collections" + else sourceDir / "scala-old-collections" + val scalaVersionsUsedForPublishing: Set[String] = Set("2.10.7", "2.11.12", "2.12.5", "2.13.0-M3") val newScalaBinaryVersionsInThisRelease: Set[String] = @@ -1051,6 +1065,9 @@ object Build { ) ++ ( scalaJSExternalCompileSettings ) ++ inConfig(Compile)(Seq( + unmanagedSourceDirectories += + collectionsEraDependentDirectory(scalaVersion.value, sourceDirectory.value), + scalacOptions in doc ++= Seq( "-implicits", "-groups", @@ -1514,7 +1531,9 @@ object Build { unmanagedSourceDirectories in Test ++= { val testDir = (sourceDirectory in Test).value + val scalaV = scalaVersion.value + collectionsEraDependentDirectory(scalaV, testDir) :: includeIf(testDir / "require-modules", scalaJSModuleKind.value != ModuleKind.NoModule) }, diff --git a/scalalib/overrides-2.13/scala/Array.scala b/scalalib/overrides-2.13/scala/Array.scala index 5da40c0e6a..66753eac27 100644 --- a/scalalib/overrides-2.13/scala/Array.scala +++ b/scalalib/overrides-2.13/scala/Array.scala @@ -31,15 +31,27 @@ import scala.runtime.ScalaRunTime.{array_apply, array_update} * @version 1.0 */ object Array { - val emptyBooleanArray = new Array[Boolean](0) - val emptyByteArray = new Array[Byte](0) - val emptyCharArray = new Array[Char](0) - val emptyDoubleArray = new Array[Double](0) - val emptyFloatArray = new Array[Float](0) - val emptyIntArray = new Array[Int](0) - val emptyLongArray = new Array[Long](0) - val emptyShortArray = new Array[Short](0) - val emptyObjectArray = new Array[Object](0) + def emptyBooleanArray = EmptyArrays.emptyBooleanArray + def emptyByteArray = EmptyArrays.emptyByteArray + def emptyCharArray = EmptyArrays.emptyCharArray + def emptyDoubleArray = EmptyArrays.emptyDoubleArray + def emptyFloatArray = EmptyArrays.emptyFloatArray + def emptyIntArray = EmptyArrays.emptyIntArray + def emptyLongArray = EmptyArrays.emptyLongArray + def emptyShortArray = EmptyArrays.emptyShortArray + def emptyObjectArray = EmptyArrays.emptyObjectArray + + private object EmptyArrays { + val emptyBooleanArray = new Array[Boolean](0) + val emptyByteArray = new Array[Byte](0) + val emptyCharArray = new Array[Char](0) + val emptyDoubleArray = new Array[Double](0) + val emptyFloatArray = new Array[Float](0) + val emptyIntArray = new Array[Int](0) + val emptyLongArray = new Array[Long](0) + val emptyShortArray = new Array[Short](0) + val emptyObjectArray = new Array[Object](0) + } /** Provides an implicit conversion from the Array object to a collection Factory */ implicit def toFactory[A : ClassTag](dummy: Array.type): Factory[A, Array[A]] = @@ -54,23 +66,11 @@ object Array { def newBuilder[T](implicit t: ClassTag[T]): ArrayBuilder[T] = ArrayBuilder.make[T](t) def from[A : ClassTag](it: IterableOnce[A]): Array[A] = { - val n = it.knownSize - if (n > -1) { - val elements = new Array[A](n) - val iterator = it.iterator - var i = 0 - while (i < n) { - ScalaRunTime.array_update(elements, i, iterator.next()) - i = i + 1 - } - elements - } else { - val b = ArrayBuilder.make[A] - val iterator = it.iterator - while (iterator.hasNext) - b += iterator.next() - b.result() - } + val b = ArrayBuilder.make[A] + val iterator = it.iterator + while (iterator.hasNext) + b += iterator.next() + b.result() } private def slowcopy(src : AnyRef, @@ -153,7 +153,10 @@ object Array { val destClass = ct.runtimeClass.asInstanceOf[Class[A]] if (destClass.isAssignableFrom(original.getClass.getComponentType)) { if(destClass.isPrimitive) copyOf[A](original.asInstanceOf[Array[A]], newLength) - else java.util.Arrays.copyOf(original.asInstanceOf[Array[AnyRef]], newLength, getArrayClass(destClass).asInstanceOf[Class[Array[AnyRef]]]).asInstanceOf[Array[A]] + else { + val destArrayClass = java.lang.reflect.Array.newInstance(destClass, 0).getClass.asInstanceOf[Class[Array[AnyRef]]] + java.util.Arrays.copyOf(original.asInstanceOf[Array[AnyRef]], newLength, destArrayClass).asInstanceOf[Array[A]] + } } else { val dest = new Array[A](newLength) Array.copy(original, 0, dest, 0, original.length) @@ -161,18 +164,6 @@ object Array { } } - private def getArrayClass[A](c: Class[A]): Class[Array[A]] = { - if(c eq classOf[Int]) classOf[Array[Int]] - else if(c eq classOf[Long]) classOf[Array[Long]] - else if(c eq classOf[Char]) classOf[Array[Char]] - else if(c eq classOf[Boolean]) classOf[Array[Boolean]] - else if(c eq classOf[Double]) classOf[Array[Double]] - else if(c eq classOf[Byte]) classOf[Array[Byte]] - else if(c eq classOf[Float]) classOf[Array[Float]] - else if(c eq classOf[Short]) classOf[Array[Short]] - else Class.forName(if(c.isArray) "["+c.getName else "[L"+c.getName+";", true, c.getClassLoader) - }.asInstanceOf[Class[Array[A]]] - /** Returns an array of length 0 */ def empty[T: ClassTag]: Array[T] = new Array[T](0) diff --git a/scalalib/overrides-2.13/scala/Enumeration.scala b/scalalib/overrides-2.13/scala/Enumeration.scala index aaeec73850..cd2469466b 100644 --- a/scalalib/overrides-2.13/scala/Enumeration.scala +++ b/scalalib/overrides-2.13/scala/Enumeration.scala @@ -81,13 +81,12 @@ abstract class Enumeration (initial: Int) extends Serializable { /* Note that `readResolve` cannot be private, since otherwise the JVM does not invoke it when deserializing subclasses. */ - protected def readResolve(): AnyRef = thisenum.getClass.getField(MODULE_INSTANCE_NAME).get(null) + protected def readResolve(): AnyRef = ??? /** The name of this enumeration. */ override def toString = - ((getClass.getName stripSuffix MODULE_SUFFIX_STRING split '.').last split - Regex.quote(NAME_JOIN_STRING)).last + (getClass.getName.stripSuffix("$").split('.')).last.split('$').last /** The mapping from the integer used to identify values to the actual * values. */ @@ -144,8 +143,23 @@ abstract class Enumeration (initial: Int) extends Serializable { * @throws NoSuchElementException if no `Value` with a matching * name is in this `Enumeration` */ - final def withName(s: String): Value = values.find(_.toString == s).getOrElse( - throw new NoSuchElementException(s"No value found for '$s'")) + final def withName(s: String): Value = { + val (unnamed, named) = values partition { + _.toString().startsWith(" v + // If we have unnamed values, we issue a detailed error message + case None if unnamed.nonEmpty => + throw new NoSuchElementException( + s"""Couldn't find enum field with name $s. + |However, there were the following unnamed fields: + |${unnamed.mkString(" ","\n ","")}""".stripMargin) + // Normal case (no unnamed Values) + case _ => None.get + } + } /** Creates a fresh value, part of this enumeration. */ protected final def Value: Value = Value(nextId) @@ -176,32 +190,6 @@ abstract class Enumeration (initial: Int) extends Serializable { */ protected final def Value(i: Int, name: String): Value = new Val(i, name) - private def populateNameMap() { - val fields: Array[JField] = getClass.getDeclaredFields - def isValDef(m: JMethod): Boolean = fields exists (fd => fd.getName == m.getName && fd.getType == m.getReturnType) - - // The list of possible Value methods: 0-args which return a conforming type - val methods: Array[JMethod] = getClass.getMethods filter (m => m.getParameterTypes.isEmpty && - classOf[Value].isAssignableFrom(m.getReturnType) && - m.getDeclaringClass != classOf[Enumeration] && - isValDef(m)) - methods foreach { m => - val name = m.getName - // invoke method to obtain actual `Value` instance - val value = m.invoke(this).asInstanceOf[Value] - // verify that outer points to the correct Enumeration: ticket #3616. - if (value.outerEnum eq thisenum) { - val id = Int.unbox(classOf[Val] getMethod "id" invoke value) - nmap += ((id, name)) - } - } - } - - /* Obtains the name for the value with id `i`. If no name is cached - * in `nmap`, it populates `nmap` using reflection. - */ - private def nameOf(i: Int): String = synchronized { nmap.getOrElse(i, { populateNameMap() ; nmap(i) }) } - /** The type of the enumerated values. */ @SerialVersionUID(7091335633555234129L) abstract class Value extends Ordered[Value] with Serializable { @@ -243,8 +231,8 @@ abstract class Enumeration (initial: Int) extends Serializable { def id = i override def toString() = if (name != null) name - else try thisenum.nameOf(i) - catch { case _: NoSuchElementException => "" } + // Scala.js specific + else s"" protected def readResolve(): AnyRef = { val enum = thisenum.readResolve().asInstanceOf[Enumeration] diff --git a/scalalib/overrides-2.13/scala/collection/immutable/NumericRange.scala b/scalalib/overrides-2.13/scala/collection/immutable/NumericRange.scala index 65e703829c..69f69051c2 100644 --- a/scalalib/overrides-2.13/scala/collection/immutable/NumericRange.scala +++ b/scalalib/overrides-2.13/scala/collection/immutable/NumericRange.scala @@ -1,70 +1,103 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2006-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ +package scala.collection.immutable -package scala -package collection -package immutable +import scala.collection.{SeqFactory, IterableFactory, IterableOnce, Iterator, StrictOptimizedIterableOps} -// TODO: Now the specialization exists there is no clear reason to have -// separate classes for Range/NumericRange. Investigate and consolidate. +import java.lang.String + +import scala.collection.mutable.Builder /** `NumericRange` is a more generic version of the - * `Range` class which works with arbitrary types. - * It must be supplied with an `Integral` implementation of the - * range type. - * - * Factories for likely types include `Range.BigInt`, `Range.Long`, - * and `Range.BigDecimal`. `Range.Int` exists for completeness, but - * the `Int`-based `scala.Range` should be more performant. - * - * {{{ - * val r1 = new Range(0, 100, 1) - * val veryBig = Int.MaxValue.toLong + 1 - * val r2 = Range.Long(veryBig, veryBig + 100, 1) - * assert(r1 sameElements r2.map(_ - veryBig)) - * }}} - * - * @author Paul Phillips - * @version 2.8 - * @define Coll `NumericRange` - * @define coll numeric range - * @define mayNotTerminateInf - * @define willNotTerminateInf - */ -abstract class NumericRange[T] - (val start: T, val end: T, val step: T, val isInclusive: Boolean) - (implicit num: Integral[T]) -extends AbstractSeq[T] with IndexedSeq[T] with Serializable { + * `Range` class which works with arbitrary types. + * It must be supplied with an `Integral` implementation of the + * range type. + * + * Factories for likely types include `Range.BigInt`, `Range.Long`, + * and `Range.BigDecimal`. `Range.Int` exists for completeness, but + * the `Int`-based `scala.Range` should be more performant. + * + * {{{ + * val r1 = new Range(0, 100, 1) + * val veryBig = Int.MaxValue.toLong + 1 + * val r2 = Range.Long(veryBig, veryBig + 100, 1) + * assert(r1 sameElements r2.map(_ - veryBig)) + * }}} + * + * @define Coll `NumericRange` + * @define coll numeric range + * @define mayNotTerminateInf + * @define willNotTerminateInf + */ +@SerialVersionUID(3L) +sealed class NumericRange[T]( + val start: T, + val end: T, + val step: T, + val isInclusive: Boolean +)(implicit + num: Integral[T] +) + extends AbstractSeq[T] + with IndexedSeq[T] + with IndexedSeqOps[T, IndexedSeq, IndexedSeq[T]] + with StrictOptimizedSeqOps[T, IndexedSeq, IndexedSeq[T]] + with Serializable { self => + + override def iterator() = new Iterator[T] { + import num.mkNumericOps + + private var _hasNext = !self.isEmpty + private var _next: T = start + private val lastElement: T = if (_hasNext) last else start + override def knownSize: Int = if (_hasNext) num.toInt((lastElement - _next) / step) + 1 else 0 + def hasNext: Boolean = _hasNext + def next(): T = { + if (!_hasNext) Iterator.empty.next() + val value = _next + _hasNext = value != lastElement + _next = num.plus(value, step) + value + } + } + /** Note that NumericRange must be invariant so that constructs - * such as "1L to 10 by 5" do not infer the range type as AnyVal. - */ + * such as "1L to 10 by 5" do not infer the range type as AnyVal. + */ import num._ // See comment in Range for why this must be lazy. - private lazy val numRangeElements: Int = - NumericRange.count(start, end, step, isInclusive) - - override def length = numRangeElements + override lazy val length: Int = NumericRange.count(start, end, step, isInclusive) override def isEmpty = length == 0 - override lazy val last: T = - if (length == 0) Nil.last + override def last: T = + if (length == 0) Nil.head else locationAfterN(length - 1) + override def init: NumericRange[T] = + if (isEmpty) Nil.init + else new NumericRange(start, end - step, step, isInclusive) + + override def head: T = if (isEmpty) Nil.head else start + override def tail: NumericRange[T] = + if (isEmpty) Nil.tail + else if(isInclusive) new NumericRange.Inclusive(start + step, end, step) + else new NumericRange.Exclusive(start + step, end, step) /** Create a new range with the start and end values of this range and - * a new `step`. - */ + * a new `step`. + */ def by(newStep: T): NumericRange[T] = copy(start, end, newStep) + /** Create a copy of this range. - */ - def copy(start: T, end: T, step: T): NumericRange[T] + */ + def copy(start: T, end: T, step: T): NumericRange[T] = + new NumericRange(start, end, step, isInclusive) + + @throws[IndexOutOfBoundsException] + def apply(idx: Int): T = { + if (idx < 0 || idx >= length) throw new IndexOutOfBoundsException(idx.toString) + else locationAfterN(idx) + } - override def foreach[U](f: T => U) { + override def foreach[@specialized(Unit) U](f: T => U): Unit = { var count = 0 var current = start while (count < length) { @@ -82,8 +115,8 @@ extends AbstractSeq[T] with IndexedSeq[T] with Serializable { // whether it is a member of the sequence (i.e. when step > 1.) private def isWithinBoundaries(elem: T) = !isEmpty && ( (step > zero && start <= elem && elem <= last ) || - (step < zero && last <= elem && elem <= start) - ) + (step < zero && last <= elem && elem <= start) + ) // Methods like apply throw exceptions on invalid n, but methods like take/drop // are forgiving: therefore the checks are with the methods. private def locationAfterN(n: Int): T = start + (step * fromInt(n)) @@ -94,40 +127,40 @@ extends AbstractSeq[T] with IndexedSeq[T] with Serializable { // based on the given value. private def newEmptyRange(value: T) = NumericRange(value, value, step) - final override def take(n: Int): NumericRange[T] = ( + override def take(n: Int): NumericRange[T] = { if (n <= 0 || length == 0) newEmptyRange(start) else if (n >= length) this else new NumericRange.Inclusive(start, locationAfterN(n - 1), step) - ) + } - final override def drop(n: Int): NumericRange[T] = ( + override def drop(n: Int): NumericRange[T] = { if (n <= 0 || length == 0) this else if (n >= length) newEmptyRange(end) else copy(locationAfterN(n), end, step) - ) - - def apply(idx: Int): T = { - if (idx < 0 || idx >= length) throw new IndexOutOfBoundsException(idx.toString) - else locationAfterN(idx) } + override def splitAt(n: Int): (NumericRange[T], NumericRange[T]) = (take(n), drop(n)) + + override def reverse: NumericRange[T] = + if (isEmpty) this else new NumericRange.Inclusive(last, start, -step) + import NumericRange.defaultOrdering override def min[T1 >: T](implicit ord: Ordering[T1]): T = - // We can take the fast path: - // - If the Integral of this NumericRange is also the requested Ordering - // (Integral <: Ordering). This can happen for custom Integral types. - // - The Ordering is the default Ordering of a well-known Integral type. + // We can take the fast path: + // - If the Integral of this NumericRange is also the requested Ordering + // (Integral <: Ordering). This can happen for custom Integral types. + // - The Ordering is the default Ordering of a well-known Integral type. if ((ord eq num) || defaultOrdering.get(num).exists(ord eq _)) { - if (num.signum(step) > 0) start + if (num.signum(step) > 0) head else last } else super.min(ord) override def max[T1 >: T](implicit ord: Ordering[T1]): T = - // See comment for fast path in min(). + // See comment for fast path in min(). if ((ord eq num) || defaultOrdering.get(num).exists(ord eq _)) { if (num.signum(step) > 0) last - else start + else head } else super.max(ord) // Motivated by the desire for Double ranges with BigDecimal precision, @@ -157,12 +190,9 @@ extends AbstractSeq[T] with IndexedSeq[T] with Serializable { // XXX This may be incomplete. new NumericRange[A](fm(start), fm(end), fm(step), isInclusive) { - def copy(start: A, end: A, step: A): NumericRange[A] = - if (isInclusive) NumericRange.inclusive(start, end, step) - else NumericRange(start, end, step) private lazy val underlyingRange: NumericRange[T] = self - override def foreach[U](f: A => U) { underlyingRange foreach (x => f(fm(x))) } + override def foreach[@specialized(Unit) U](f: A => U): Unit = { underlyingRange foreach (x => f(fm(x))) } override def isEmpty = underlyingRange.isEmpty override def apply(idx: Int): A = fm(underlyingRange(idx)) override def containsTyped(el: A) = underlyingRange exists (x => fm(x) == el) @@ -183,18 +213,18 @@ extends AbstractSeq[T] with IndexedSeq[T] with Serializable { try containsTyped(x.asInstanceOf[T]) catch { case _: ClassCastException => false } - final override def sum[B >: T](implicit num: Numeric[B]): B = { + override def sum[B >: T](implicit num: Numeric[B]): B = { if (isEmpty) num.zero - else if (numRangeElements == 1) head + else if (size == 1) head else { // If there is no overflow, use arithmetic series formula // a + ... (n terms total) ... + b = n*(a+b)/2 if ((num eq scala.math.Numeric.IntIsIntegral)|| - (num eq scala.math.Numeric.ShortIsIntegral)|| - (num eq scala.math.Numeric.ByteIsIntegral)|| - (num eq scala.math.Numeric.CharIsIntegral)) { + (num eq scala.math.Numeric.ShortIsIntegral)|| + (num eq scala.math.Numeric.ByteIsIntegral)|| + (num eq scala.math.Numeric.CharIsIntegral)) { // We can do math with no overflow in a Long--easy - val exact = (numRangeElements * ((num toLong head) + (num toInt last))) / 2 + val exact = (size * ((num toLong head) + (num toInt last))) / 2 num fromInt exact.toInt } else if (num eq scala.math.Numeric.LongIsIntegral) { @@ -203,8 +233,8 @@ extends AbstractSeq[T] with IndexedSeq[T] with Serializable { val a = head.toLong val b = last.toLong val ans = - if ((numRangeElements & 1) == 0) (numRangeElements / 2) * (a + b) - else numRangeElements * { + if ((size & 1) == 0) (size / 2) * (a + b) + else size * { // Sum is even, but we might overflow it, so divide in pieces and add back remainder val ha = a/2 val hb = b/2 @@ -230,18 +260,18 @@ extends AbstractSeq[T] with IndexedSeq[T] with Serializable { } } - override lazy val hashCode = super.hashCode() - override def equals(other: Any) = other match { + override lazy val hashCode: Int = super.hashCode() + override def equals(other: Any): Boolean = other match { case x: NumericRange[_] => (x canEqual this) && (length == x.length) && ( (length == 0) || // all empty sequences are equal - (start == x.start && last == x.last) // same length and same endpoints implies equality - ) + (start == x.start && last == x.last) // same length and same endpoints implies equality + ) case _ => super.equals(other) } - override def toString = { + override def toString: String = { val empty = if (isEmpty) "empty " else "" val preposition = if (isInclusive) "to" else "until" val stepped = if (step == 1) "" else s" by $step" @@ -250,13 +280,15 @@ extends AbstractSeq[T] with IndexedSeq[T] with Serializable { } /** A companion object for numeric ranges. - */ + * @define Coll `NumericRange` + * @define coll numeric range + */ object NumericRange { /** Calculates the number of elements in a range given start, end, step, and - * whether or not it is inclusive. Throws an exception if step == 0 or - * the number of elements exceeds the maximum Int. - */ + * whether or not it is inclusive. Throws an exception if step == 0 or + * the number of elements exceeds the maximum Int. + */ def count[T](start: T, end: T, step: T, isInclusive: Boolean)(implicit num: Integral[T]): Int = { val zero = num.zero val upward = num.lt(start, end) @@ -291,7 +323,7 @@ object NumericRange { // Numbers may be big. val one = num.one val limit = num.fromInt(Int.MaxValue) - def check(t: T): T = + def check(t: T): T = if (num.gt(t, limit)) throw new IllegalArgumentException("More than Int.MaxValue elements.") else t // If the range crosses zero, it might overflow when subtracted @@ -342,17 +374,19 @@ object NumericRange { } } + @SerialVersionUID(3L) class Inclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]) - extends NumericRange(start, end, step, true) { - def copy(start: T, end: T, step: T): Inclusive[T] = + extends NumericRange(start, end, step, true) { + override def copy(start: T, end: T, step: T): Inclusive[T] = NumericRange.inclusive(start, end, step) def exclusive: Exclusive[T] = NumericRange(start, end, step) } + @SerialVersionUID(3L) class Exclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]) - extends NumericRange(start, end, step, false) { - def copy(start: T, end: T, step: T): Exclusive[T] = + extends NumericRange(start, end, step, false) { + override def copy(start: T, end: T, step: T): Exclusive[T] = NumericRange(start, end, step) def inclusive: Inclusive[T] = NumericRange.inclusive(start, end, step) diff --git a/scalalib/overrides-2.13/scala/collection/immutable/Range.scala b/scalalib/overrides-2.13/scala/collection/immutable/Range.scala index fb2c34c064..8c89fe0f18 100644 --- a/scalalib/overrides-2.13/scala/collection/immutable/Range.scala +++ b/scalalib/overrides-2.13/scala/collection/immutable/Range.scala @@ -1,82 +1,75 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2006-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - package scala package collection.immutable +import collection.{Iterator, SeqFactory} + +import java.lang.String + +import scala.collection.mutable.Builder + /** The `Range` class represents integer values in range - * ''[start;end)'' with non-zero step value `step`. - * It's a special case of an indexed sequence. - * For example: - * - * {{{ - * val r1 = 0 until 10 - * val r2 = r1.start until r1.end by r1.step + 1 - * println(r2.length) // = 5 - * }}} - * - * Ranges that contain more than `Int.MaxValue` elements can be created, but - * these overfull ranges have only limited capabilities. Any method that - * could require a collection of over `Int.MaxValue` length to be created, or - * could be asked to index beyond `Int.MaxValue` elements will throw an - * exception. Overfull ranges can safely be reduced in size by changing - * the step size (e.g. `by 3`) or taking/dropping elements. `contains`, - * `equals`, and access to the ends of the range (`head`, `last`, `tail`, - * `init`) are also permitted on overfull ranges. - * - * @param start the start of this range. - * @param end the end of the range. For exclusive ranges, e.g. - * `Range(0,3)` or `(0 until 3)`, this is one - * step past the last one in the range. For inclusive - * ranges, e.g. `Range.inclusive(0,3)` or `(0 to 3)`, - * it may be in the range if it is not skipped by the step size. - * To find the last element inside a non-empty range, - use `last` instead. - * @param step the step for the range. - * - * @author Martin Odersky - * @author Paul Phillips - * @version 2.8 - * @since 2.5 - * @see [[http://docs.scala-lang.org/overviews/collections/concrete-immutable-collection-classes.html#ranges "Scala's Collection Library overview"]] - * section on `Ranges` for more information. - * - * @define coll range - * @define mayNotTerminateInf - * @define willNotTerminateInf - * @define doesNotUseBuilders - * '''Note:''' this method does not use builders to construct a new range, - * and its complexity is O(1). - */ -@SerialVersionUID(7618862778670199309L) -@inline -@deprecatedInheritance("The implementation details of Range makes inheriting from it unwise.", "2.11.0") -class Range(val start: Int, val end: Int, val step: Int) -extends scala.collection.AbstractSeq[Int] - with IndexedSeq[Int] - with Serializable -{ + * ''[start;end)'' with non-zero step value `step`. + * It's a special case of an indexed sequence. + * For example: + * + * {{{ + * val r1 = 0 until 10 + * val r2 = r1.start until r1.end by r1.step + 1 + * println(r2.length) // = 5 + * }}} + * + * Ranges that contain more than `Int.MaxValue` elements can be created, but + * these overfull ranges have only limited capabilities. Any method that + * could require a collection of over `Int.MaxValue` length to be created, or + * could be asked to index beyond `Int.MaxValue` elements will throw an + * exception. Overfull ranges can safely be reduced in size by changing + * the step size (e.g. `by 3`) or taking/dropping elements. `contains`, + * `equals`, and access to the ends of the range (`head`, `last`, `tail`, + * `init`) are also permitted on overfull ranges. + * + * @param start the start of this range. + * @param end the end of the range. For exclusive ranges, e.g. + * `Range(0,3)` or `(0 until 3)`, this is one + * step past the last one in the range. For inclusive + * ranges, e.g. `Range.inclusive(0,3)` or `(0 to 3)`, + * it may be in the range if it is not skipped by the step size. + * To find the last element inside a non-empty range, + * use `last` instead. + * @param step the step for the range. + * + * @define coll range + * @define mayNotTerminateInf + * @define willNotTerminateInf + * @define doesNotUseBuilders + * '''Note:''' this method does not use builders to construct a new range, + * and its complexity is O(1). + */ +@SerialVersionUID(3L) +sealed abstract class Range( + val start: Int, + val end: Int, + val step: Int +) + extends AbstractSeq[Int] + with IndexedSeq[Int] + with IndexedSeqOps[Int, IndexedSeq, IndexedSeq[Int]] + with StrictOptimizedSeqOps[Int, IndexedSeq, IndexedSeq[Int]] + with Serializable { range => + + override def iterator(): Iterator[Int] = new RangeIterator(start, step, lastElement, isEmpty) + private def gap = end.toLong - start.toLong private def isExact = gap % step == 0 private def hasStub = isInclusive || !isExact private def longLength = gap / step + ( if (hasStub) 1 else 0 ) - // Check cannot be evaluated eagerly because we have a pattern where - // ranges are constructed like: "x to y by z" The "x to y" piece - // should not trigger an exception. So the calculation is delayed, - // which means it will not fail fast for those cases where failing was - // correct. - override final val isEmpty = ( - (start > end && step > 0) - || (start < end && step < 0) - || (start == end && !isInclusive) - ) + def isInclusive: Boolean + + override val isEmpty: Boolean = ( + (start > end && step > 0) + || (start < end && step < 0) + || (start == end && !isInclusive) + ) private val numRangeElements: Int = { if (step == 0) throw new IllegalArgumentException("step cannot be 0.") @@ -88,6 +81,8 @@ extends scala.collection.AbstractSeq[Int] } } + def length = if (numRangeElements < 0) fail() else numRangeElements + // This field has a sensible value only for non-empty ranges private val lastElement = step match { case 1 => if (isInclusive) end else end-1 @@ -100,50 +95,67 @@ extends scala.collection.AbstractSeq[Int] } /** The last element of this range. This method will return the correct value - * even if there are too many elements to iterate over. - */ - override def last = if (isEmpty) Nil.last else lastElement - override def head = if (isEmpty) Nil.head else start + * even if there are too many elements to iterate over. + */ + override def last: Int = if (isEmpty) Nil.head else lastElement + override def head: Int = if (isEmpty) Nil.head else start - override def min[A1 >: Int](implicit ord: Ordering[A1]): Int = - if (ord eq Ordering.Int) { - if (step > 0) head - else last - } else super.min(ord) + /** Creates a new range containing all the elements of this range except the last one. + * + * $doesNotUseBuilders + * + * @return a new range consisting of all the elements of this range except the last one. + */ + override def init: Range = { + if (isEmpty) + Nil.init - override def max[A1 >: Int](implicit ord: Ordering[A1]): Int = - if (ord eq Ordering.Int) { - if (step > 0) last - else head - } else super.max(ord) + dropRight(1) + } - protected def copy(start: Int, end: Int, step: Int): Range = new Range(start, end, step) + /** Creates a new range containing all the elements of this range except the first one. + * + * $doesNotUseBuilders + * + * @return a new range consisting of all the elements of this range except the first one. + */ + override def tail: Range = { + if (isEmpty) + Nil.tail + if (numRangeElements == 1) newEmptyRange(end) + else if(isInclusive) new Range.Inclusive(start + step, end, step) + else new Range.Exclusive(start + step, end, step) + } + + protected def copy(start: Int = start, end: Int = end, step: Int = step, isInclusive: Boolean = isInclusive): Range = + if(isInclusive) new Range.Inclusive(start, end, step) else new Range.Exclusive(start, end, step) /** Create a new range with the `start` and `end` values of this range and - * a new `step`. - * - * @return a new range with a different step - */ + * a new `step`. + * + * @return a new range with a different step + */ def by(step: Int): Range = copy(start, end, step) - def isInclusive = false - - override def size = length - override def length = if (numRangeElements < 0) fail() else numRangeElements - - private def fail() = Range.fail(start, end, step, isInclusive) - private def validateMaxLength() { + // Check cannot be evaluated eagerly because we have a pattern where + // ranges are constructed like: "x to y by z" The "x to y" piece + // should not trigger an exception. So the calculation is delayed, + // which means it will not fail fast for those cases where failing was + // correct. + private def validateMaxLength(): Unit = { if (numRangeElements < 0) fail() } + private def fail() = Range.fail(start, end, step, isInclusive) - final def apply(idx: Int): Int = { + @throws[IndexOutOfBoundsException] + def apply(idx: Int): Int = { validateMaxLength() if (idx < 0 || idx >= numRangeElements) throw new IndexOutOfBoundsException(idx.toString) else start + (step * idx) } - @inline final override def foreach[@specialized(Unit) U](f: Int => U) { + /*@`inline`*/ override def foreach[@specialized(Unit) U](f: Int => U): Unit = { // Implementation chosen on the basis of favorable microbenchmarks // Note--initialization catches step == 0 so we don't need to here if (!isEmpty) { @@ -157,13 +169,11 @@ extends scala.collection.AbstractSeq[Int] } /** Creates a new range containing the first `n` elements of this range. - * - * $doesNotUseBuilders - * - * @param n the number of elements to take. - * @return a new range consisting of `n` first elements. - */ - final override def take(n: Int): Range = ( + * + * @param n the number of elements to take. + * @return a new range consisting of `n` first elements. + */ + override def take(n: Int): Range = if (n <= 0 || isEmpty) newEmptyRange(start) else if (n >= numRangeElements && numRangeElements >= 0) this else { @@ -171,16 +181,13 @@ extends scala.collection.AbstractSeq[Int] // but the logic is the same either way: take the first n new Range.Inclusive(start, locationAfterN(n - 1), step) } - ) /** Creates a new range containing all the elements of this range except the first `n` elements. - * - * $doesNotUseBuilders - * - * @param n the number of elements to drop. - * @return a new range consisting of all the elements of this range except `n` first elements. - */ - final override def drop(n: Int): Range = ( + * + * @param n the number of elements to drop. + * @return a new range consisting of all the elements of this range except `n` first elements. + */ + override def drop(n: Int): Range = if (n <= 0 || isEmpty) this else if (n >= numRangeElements && numRangeElements >= 0) newEmptyRange(end) else { @@ -188,49 +195,36 @@ extends scala.collection.AbstractSeq[Int] // but the logic is the same either way: go forwards n steps, keep the rest copy(locationAfterN(n), end, step) } - ) - - /** Creates a new range containing the elements starting at `from` up to but not including `until`. - * - * $doesNotUseBuilders - * - * @param from the element at which to start - * @param until the element at which to end (not included in the range) - * @return a new range consisting of a contiguous interval of values in the old range - */ - override def slice(from: Int, until: Int): Range = - if (from <= 0) take(until) - else if (until >= numRangeElements && numRangeElements >= 0) drop(from) + + /** Creates a new range consisting of the last `n` elements of the range. + * + * $doesNotUseBuilders + */ + override def takeRight(n: Int): Range = { + if (n <= 0) newEmptyRange(start) + else if (numRangeElements >= 0) drop(numRangeElements - n) else { - val fromValue = locationAfterN(from) - if (from >= until) newEmptyRange(fromValue) - else new Range.Inclusive(fromValue, locationAfterN(until-1), step) + // Need to handle over-full range separately + val y = last + val x = y - step.toLong*(n-1) + if ((step > 0 && x < start) || (step < 0 && x > start)) this + else Range.inclusive(x.toInt, y, step) } - - /** Creates a new range containing all the elements of this range except the last one. - * - * $doesNotUseBuilders - * - * @return a new range consisting of all the elements of this range except the last one. - */ - final override def init: Range = { - if (isEmpty) - Nil.init - - dropRight(1) } - /** Creates a new range containing all the elements of this range except the first one. - * - * $doesNotUseBuilders - * - * @return a new range consisting of all the elements of this range except the first one. - */ - final override def tail: Range = { - if (isEmpty) - Nil.tail - - drop(1) + /** Creates a new range consisting of the initial `length - n` elements of the range. + * + * $doesNotUseBuilders + */ + override def dropRight(n: Int): Range = { + if (n <= 0) this + else if (numRangeElements >= 0) take(numRangeElements - n) + else { + // Need to handle over-full range separately + val y = last - step.toInt*n + if ((step > 0 && y < start) || (step < 0 && y > start)) newEmptyRange(start) + else Range.inclusive(start, y.toInt, step) + } } // Advance from the start while we meet the given test @@ -244,98 +238,81 @@ extends scala.collection.AbstractSeq[Int] else current.toLong + step } } - // Methods like apply throw exceptions on invalid n, but methods like take/drop - // are forgiving: therefore the checks are with the methods. - private def locationAfterN(n: Int) = start + (step * n) - - // When one drops everything. Can't ever have unchecked operations - // like "end + 1" or "end - 1" because ranges involving Int.{ MinValue, MaxValue } - // will overflow. This creates an exclusive range where start == end - // based on the given value. - private def newEmptyRange(value: Int) = new Range(value, value, step) - final override def takeWhile(p: Int => Boolean): Range = { + override def takeWhile(p: Int => Boolean): Range = { val stop = argTakeWhile(p) if (stop==start) newEmptyRange(start) else { val x = (stop - step).toInt if (x == last) this - else new Range.Inclusive(start, x, step) + else Range.inclusive(start, x, step) } } - final override def dropWhile(p: Int => Boolean): Range = { + + override def dropWhile(p: Int => Boolean): Range = { val stop = argTakeWhile(p) if (stop == start) this else { val x = (stop - step).toInt if (x == last) newEmptyRange(last) - else new Range.Inclusive(x + step, last, step) + else Range.inclusive(x + step, last, step) } } - final override def span(p: Int => Boolean): (Range, Range) = { + + override def span(p: Int => Boolean): (Range, Range) = { val border = argTakeWhile(p) if (border == start) (newEmptyRange(start), this) else { val x = (border - step).toInt if (x == last) (this, newEmptyRange(last)) - else (new Range.Inclusive(start, x, step), new Range.Inclusive(x+step, last, step)) + else (Range.inclusive(start, x, step), Range.inclusive(x+step, last, step)) } } - /** Creates a pair of new ranges, first consisting of elements before `n`, and the second - * of elements after `n`. - * - * $doesNotUseBuilders - */ - final override def splitAt(n: Int) = (take(n), drop(n)) - - /** Creates a new range consisting of the last `n` elements of the range. - * - * $doesNotUseBuilders - */ - final override def takeRight(n: Int): Range = { - if (n <= 0) newEmptyRange(start) - else if (numRangeElements >= 0) drop(numRangeElements - n) + /** Creates a new range containing the elements starting at `from` up to but not including `until`. + * + * $doesNotUseBuilders + * + * @param from the element at which to start + * @param until the element at which to end (not included in the range) + * @return a new range consisting of a contiguous interval of values in the old range + */ + override def slice(from: Int, until: Int): Range = + if (from <= 0) take(until) + else if (until >= numRangeElements && numRangeElements >= 0) drop(from) else { - // Need to handle over-full range separately - val y = last - val x = y - step.toLong*(n-1) - if ((step > 0 && x < start) || (step < 0 && x > start)) this - else new Range.Inclusive(x.toInt, y, step) + val fromValue = locationAfterN(from) + if (from >= until) newEmptyRange(fromValue) + else Range.inclusive(fromValue, locationAfterN(until-1), step) } - } - /** Creates a new range consisting of the initial `length - n` elements of the range. - * - * $doesNotUseBuilders - */ - final override def dropRight(n: Int): Range = { - if (n <= 0) this - else if (numRangeElements >= 0) take(numRangeElements - n) - else { - // Need to handle over-full range separately - val y = last - step.toInt*n - if ((step > 0 && y < start) || (step < 0 && y > start)) newEmptyRange(start) - else new Range.Inclusive(start, y.toInt, step) - } - } + // Overridden only to refine the return type + override def splitAt(n: Int): (Range, Range) = (take(n), drop(n)) + + // Methods like apply throw exceptions on invalid n, but methods like take/drop + // are forgiving: therefore the checks are with the methods. + private def locationAfterN(n: Int) = start + (step * n) + + // When one drops everything. Can't ever have unchecked operations + // like "end + 1" or "end - 1" because ranges involving Int.{ MinValue, MaxValue } + // will overflow. This creates an exclusive range where start == end + // based on the given value. + private def newEmptyRange(value: Int) = new Range.Exclusive(value, value, step) /** Returns the reverse of this range. - * - * $doesNotUseBuilders - */ - final override def reverse: Range = + */ + override def reverse: Range = if (isEmpty) this else new Range.Inclusive(last, start, -step) /** Make range inclusive. - */ - def inclusive = + */ + def inclusive: Range = if (isInclusive) this else new Range.Inclusive(start, end, step) - final def contains(x: Int) = { - if (x==end && !isInclusive) false + def contains(x: Int) = { + if (x == end && !isInclusive) false else if (step > 0) { if (x < start || x > end) false else (step == 1) || (((x - start) % step) == 0) @@ -346,12 +323,12 @@ extends scala.collection.AbstractSeq[Int] } } - final override def sum[B >: Int](implicit num: Numeric[B]): Int = { + override def sum[B >: Int](implicit num: Numeric[B]): Int = { if (num eq scala.math.Numeric.IntIsIntegral) { // this is normal integer range with usual addition. arithmetic series formula can be used if (isEmpty) 0 - else if (numRangeElements == 1) head - else ((numRangeElements * (head.toLong + last)) / 2).toInt + else if (size == 1) head + else ((size * (head.toLong + last)) / 2).toInt } else { // user provided custom Numeric, we cannot rely on arithmetic series formula if (isEmpty) num.toInt(num.zero) @@ -368,41 +345,51 @@ extends scala.collection.AbstractSeq[Int] } } - override def toIterable = this + override def min[A1 >: Int](implicit ord: Ordering[A1]): Int = + if (ord eq Ordering.Int) { + if (step > 0) head + else last + } else super.min(ord) + + override def max[A1 >: Int](implicit ord: Ordering[A1]): Int = + if (ord eq Ordering.Int) { + if (step > 0) last + else head + } else super.max(ord) - override def toSeq = this override def equals(other: Any) = other match { case x: Range => // Note: this must succeed for overfull ranges (length > Int.MaxValue) - (x canEqual this) && { - if (isEmpty) x.isEmpty // empty sequences are equal - else // this is non-empty... - x.nonEmpty && start == x.start && { // ...so other must contain something and have same start - val l0 = last - (l0 == x.last && ( // And same end - start == l0 || step == x.step // And either the same step, or not take any steps - )) - } - } + if (isEmpty) x.isEmpty // empty sequences are equal + else // this is non-empty... + x.nonEmpty && start == x.start && { // ...so other must contain something and have same start + val l0 = last + (l0 == x.last && ( // And same end + start == l0 || step == x.step // And either the same step, or not take any steps + )) + } case _ => super.equals(other) } /* Note: hashCode can't be overridden without breaking Seq's equals contract. */ - override def toString = { + override def toString: String = { val preposition = if (isInclusive) "to" else "until" val stepped = if (step == 1) "" else s" by $step" val prefix = if (isEmpty) "empty " else if (!isExact) "inexact " else "" s"${prefix}Range $start $preposition $end$stepped" } + } -/** A companion object for the `Range` class. - */ +/** + * Companion object for ranges. + * @define Coll `Range` + * @define coll range + */ object Range { - private[immutable] val MAX_PRINT = 512 // some arbitrary value private def description(start: Int, end: Int, step: Int, isInclusive: Boolean) = start + (if (isInclusive) " to " else " until ") + end + " by " + step @@ -412,19 +399,19 @@ object Range { ": seqs cannot contain more than Int.MaxValue elements.") /** Counts the number of range elements. - * @pre step != 0 - * If the size of the range exceeds Int.MaxValue, the - * result will be negative. - */ + * precondition: step != 0 + * If the size of the range exceeds Int.MaxValue, the + * result will be negative. + */ def count(start: Int, end: Int, step: Int, isInclusive: Boolean): Int = { if (step == 0) throw new IllegalArgumentException("step cannot be 0.") - val isEmpty = ( + val isEmpty = if (start == end) !isInclusive else if (start < end) step < 0 else step > 0 - ) + if (isEmpty) 0 else { // Counts with Longs so we can recognize too-large ranges. @@ -442,29 +429,35 @@ object Range { def count(start: Int, end: Int, step: Int): Int = count(start, end, step, isInclusive = false) - @inline - class Inclusive(start: Int, end: Int, step: Int) extends Range(start, end, step) { - override def isInclusive = true - override protected def copy(start: Int, end: Int, step: Int): Range = new Inclusive(start, end, step) - } - /** Make a range from `start` until `end` (exclusive) with given step value. - * @note step != 0 - */ - def apply(start: Int, end: Int, step: Int): Range = new Range(start, end, step) + * @note step != 0 + */ + def apply(start: Int, end: Int, step: Int): Range.Exclusive = new Range.Exclusive(start, end, step) /** Make a range from `start` until `end` (exclusive) with step value 1. - */ - def apply(start: Int, end: Int): Range = new Range(start, end, 1) + */ + def apply(start: Int, end: Int): Range.Exclusive = new Range.Exclusive(start, end, 1) /** Make an inclusive range from `start` to `end` with given step value. - * @note step != 0 - */ - def inclusive(start: Int, end: Int, step: Int): Range.Inclusive = new Inclusive(start, end, step) + * @note step != 0 + */ + def inclusive(start: Int, end: Int, step: Int): Range.Inclusive = new Range.Inclusive(start, end, step) /** Make an inclusive range from `start` to `end` with step value 1. - */ - def inclusive(start: Int, end: Int): Range.Inclusive = new Inclusive(start, end, 1) + */ + def inclusive(start: Int, end: Int): Range.Inclusive = new Range.Inclusive(start, end, 1) + + @SerialVersionUID(3L) + @inline + final class Inclusive(start: Int, end: Int, step: Int) extends Range(start, end, step) { + def isInclusive = true + } + + @SerialVersionUID(3L) + @inline + final class Exclusive(start: Int, end: Int, step: Int) extends Range(start, end, step) { + def isInclusive = false + } // BigInt and Long are straightforward generic ranges. object BigInt { @@ -483,7 +476,7 @@ object Range { // imprecision or surprises might result from anything, although this may // not yet be fully implemented. object BigDecimal { - implicit val bigDecAsIntegral = scala.math.Numeric.BigDecimalAsIfIntegral + implicit val bigDecAsIntegral: Numeric.BigDecimalAsIfIntegral = Numeric.BigDecimalAsIfIntegral def apply(start: BigDecimal, end: BigDecimal, step: BigDecimal) = NumericRange(start, end, step) @@ -498,13 +491,15 @@ object Range { // is necessary to keep 0.3d at 0.3 as opposed to // 0.299999999999999988897769753748434595763683319091796875 or so. object Double { - implicit val bigDecAsIntegral = scala.math.Numeric.BigDecimalAsIfIntegral - implicit val doubleAsIntegral = scala.math.Numeric.DoubleAsIfIntegral + implicit val bigDecAsIntegral: Numeric.BigDecimalAsIfIntegral = Numeric.BigDecimalAsIfIntegral + implicit val doubleAsIntegral: Numeric.DoubleAsIfIntegral = Numeric.DoubleAsIfIntegral def toBD(x: Double): BigDecimal = scala.math.BigDecimal valueOf x + @deprecated("use Range.BigDecimal instead", "2.12.6") def apply(start: Double, end: Double, step: Double) = BigDecimal(toBD(start), toBD(end), toBD(step)) mapRange (_.doubleValue) + @deprecated("use Range.BigDecimal.inclusive instead", "2.12.6") def inclusive(start: Double, end: Double, step: Double) = BigDecimal.inclusive(toBD(start), toBD(end), toBD(step)) mapRange (_.doubleValue) } @@ -524,4 +519,29 @@ object Range { def apply(start: Int, end: Int, step: Int) = NumericRange(start, end, step) def inclusive(start: Int, end: Int, step: Int) = NumericRange.inclusive(start, end, step) } + +} + +/** + * @param lastElement The last element included in the Range + * @param initiallyEmpty Whether the Range was initially empty or not + */ +private class RangeIterator( + start: Int, + step: Int, + lastElement: Int, + initiallyEmpty: Boolean +) extends Iterator[Int] { + private var _hasNext: Boolean = !initiallyEmpty + private var _next: Int = start + override def knownSize: Int = if (_hasNext) (lastElement - _next) / step + 1 else 0 + def hasNext: Boolean = _hasNext + @throws[NoSuchElementException] + def next(): Int = { + if (!_hasNext) Iterator.empty.next() + val value = _next + _hasNext = value != lastElement + _next = value + step + value + } } diff --git a/scalalib/overrides-2.13/scala/collection/mutable/ArrayBuilder.scala b/scalalib/overrides-2.13/scala/collection/mutable/ArrayBuilder.scala index ce3a7d5a03..e8cbdb5c25 100644 --- a/scalalib/overrides-2.13/scala/collection/mutable/ArrayBuilder.scala +++ b/scalalib/overrides-2.13/scala/collection/mutable/ArrayBuilder.scala @@ -1,13 +1,4 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala -package collection +package scala.collection package mutable import scala.reflect.ClassTag @@ -21,7 +12,55 @@ import scala.scalajs.js * * @tparam T the type of the elements for the builder. */ -abstract class ArrayBuilder[T] extends ReusableBuilder[T, Array[T]] with Serializable +@SerialVersionUID(3L) +sealed abstract class ArrayBuilder[T] + extends ReusableBuilder[T, Array[T]] + with Serializable { + protected[this] var capacity: Int = 0 + protected[this] def elems: Array[T] + protected var size: Int = 0 + + def length: Int = size + + protected[this] final def ensureSize(size: Int): Unit = { + if (capacity < size || capacity == 0) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + override final def sizeHint(size: Int): Unit = + if (capacity < size) resize(size) + + def clear(): Unit = size = 0 + + protected[this] def resize(size: Int): Unit + + /** Add all elements of an array */ + def addAll(xs: Array[_ <: T]): this.type = addAll(xs, 0, xs.length) + + /** Add a slice of an array */ + def addAll(xs: Array[_ <: T], offset: Int, length: Int): this.type = { + ensureSize(this.size + length) + Array.copy(xs, offset, elems, this.size, length) + size += length + this + } + + override def addAll(xs: IterableOnce[T]): this.type = { + val k = xs.knownSize + if(k > 0) { + ensureSize(this.size + k) + xs match { + case xs: Iterable[T] => xs.copyToArray(elems, this.size) + case _ => xs.iterator.copyToArray(elems, this.size) + } + size += k + } else if(k < 0) super.addAll(xs) + this + } +} /** A companion object for array builders. * @@ -35,7 +74,7 @@ object ArrayBuilder { * @return a new empty array builder. */ @inline - def make[T: ClassTag](): ArrayBuilder[T] = + def make[T: ClassTag]: ArrayBuilder[T] = new ArrayBuilder.generic[T](implicitly[ClassTag[T]].runtimeClass) /** A generic ArrayBuilder optimized for Scala.js. @@ -47,26 +86,44 @@ object ArrayBuilder { private final class generic[T](elementClass: Class[_]) extends ArrayBuilder[T] { private val isCharArrayBuilder = classOf[Char] == elementClass - private var elems: js.Array[Any] = js.Array() + protected[this] def elems: Array[T] = throw new Error("unreachable") + private var jsElems: js.Array[Any] = js.Array() - def +=(elem: T): this.type = { + def addOne(elem: T): this.type = { val unboxedElem = if (isCharArrayBuilder) elem.asInstanceOf[Char].toInt else if (elem == null) zeroOf(elementClass) else elem - elems.push(unboxedElem) + jsElems.push(unboxedElem) this } - def clear(): Unit = - elems = js.Array() + /** Add a slice of an array */ + override def addAll(xs: Array[_ <: T], offset: Int, length: Int): this.type = { + ensureSize(this.size + length) + addAll(xs.view.slice(offset, length)) + this + } + + override def addAll(xs: IterableOnce[T]): this.type = { + val it = xs.iterator + while (it.hasNext) { + this += it.next() + } + this + } + + override def clear(): Unit = + jsElems = js.Array() + + protected[this] def resize(size: Int): Unit = () def result(): Array[T] = { val elemRuntimeClass = if (classOf[Unit] == elementClass) classOf[BoxedUnit] else if (classOf[Null] == elementClass || classOf[Nothing] == elementClass) classOf[Object] else elementClass - genericArrayBuilderResult(elemRuntimeClass, elems) + genericArrayBuilderResult(elemRuntimeClass, jsElems) } override def toString(): String = "ArrayBuilder.generic" @@ -117,11 +174,11 @@ object ArrayBuilder { * * @tparam T type of elements for the array builder, subtype of `AnyRef` with a `ClassTag` context bound. */ - final class ofRef[T <: AnyRef : ClassTag] extends ArrayBuilder[T] { - private var elems: Array[T] = _ - private var capacity: Int = 0 - private var size: Int = 0 + @SerialVersionUID(3L) + final class ofRef[T <: AnyRef](implicit ct: ClassTag[T]) extends ArrayBuilder[T] { + + protected var elems: Array[T] = _ private def mkArray(size: Int): Array[T] = { val newelems = new Array[T](size) @@ -129,42 +186,18 @@ object ArrayBuilder { newelems } - private def resize(size: Int) { + protected[this] def resize(size: Int): Unit = { elems = mkArray(size) capacity = size } - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: T): this.type = { + def addOne(elem: T): this.type = { ensureSize(size + 1) elems(size) = elem size += 1 this } - override def ++=(xs: TraversableOnce[T]): this.type = (xs.asInstanceOf[AnyRef]) match { - case xs: WrappedArray.ofRef[_] => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { size = 0 } - def result() = { if (capacity != 0 && capacity == size) { capacity = 0 @@ -182,11 +215,10 @@ object ArrayBuilder { } /** A class for array builders for arrays of `byte`s. It can be reused. */ + @SerialVersionUID(3L) final class ofByte extends ArrayBuilder[Byte] { - private var elems: Array[Byte] = _ - private var capacity: Int = 0 - private var size: Int = 0 + protected var elems: Array[Byte] = _ private def mkArray(size: Int): Array[Byte] = { val newelems = new Array[Byte](size) @@ -194,42 +226,18 @@ object ArrayBuilder { newelems } - private def resize(size: Int) { + protected[this] def resize(size: Int): Unit = { elems = mkArray(size) capacity = size } - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Byte): this.type = { + def addOne(elem: Byte): this.type = { ensureSize(size + 1) elems(size) = elem size += 1 this } - override def ++=(xs: TraversableOnce[Byte]): this.type = xs match { - case xs: WrappedArray.ofByte => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { size = 0 } - def result() = { if (capacity != 0 && capacity == size) { capacity = 0 @@ -247,11 +255,10 @@ object ArrayBuilder { } /** A class for array builders for arrays of `short`s. It can be reused. */ + @SerialVersionUID(3L) final class ofShort extends ArrayBuilder[Short] { - private var elems: Array[Short] = _ - private var capacity: Int = 0 - private var size: Int = 0 + protected var elems: Array[Short] = _ private def mkArray(size: Int): Array[Short] = { val newelems = new Array[Short](size) @@ -259,42 +266,18 @@ object ArrayBuilder { newelems } - private def resize(size: Int) { + protected[this] def resize(size: Int): Unit = { elems = mkArray(size) capacity = size } - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Short): this.type = { + def addOne(elem: Short): this.type = { ensureSize(size + 1) elems(size) = elem size += 1 this } - override def ++=(xs: TraversableOnce[Short]): this.type = xs match { - case xs: WrappedArray.ofShort => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { size = 0 } - def result() = { if (capacity != 0 && capacity == size) { capacity = 0 @@ -312,11 +295,10 @@ object ArrayBuilder { } /** A class for array builders for arrays of `char`s. It can be reused. */ + @SerialVersionUID(3L) final class ofChar extends ArrayBuilder[Char] { - private var elems: Array[Char] = _ - private var capacity: Int = 0 - private var size: Int = 0 + protected var elems: Array[Char] = _ private def mkArray(size: Int): Array[Char] = { val newelems = new Array[Char](size) @@ -324,42 +306,18 @@ object ArrayBuilder { newelems } - private def resize(size: Int) { + protected[this] def resize(size: Int): Unit = { elems = mkArray(size) capacity = size } - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Char): this.type = { + def addOne(elem: Char): this.type = { ensureSize(size + 1) elems(size) = elem size += 1 this } - override def ++=(xs: TraversableOnce[Char]): this.type = xs match { - case xs: WrappedArray.ofChar => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { size = 0 } - def result() = { if (capacity != 0 && capacity == size) { capacity = 0 @@ -377,11 +335,10 @@ object ArrayBuilder { } /** A class for array builders for arrays of `int`s. It can be reused. */ + @SerialVersionUID(3L) final class ofInt extends ArrayBuilder[Int] { - private var elems: Array[Int] = _ - private var capacity: Int = 0 - private var size: Int = 0 + protected var elems: Array[Int] = _ private def mkArray(size: Int): Array[Int] = { val newelems = new Array[Int](size) @@ -389,42 +346,18 @@ object ArrayBuilder { newelems } - private def resize(size: Int) { + protected[this] def resize(size: Int): Unit = { elems = mkArray(size) capacity = size } - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Int): this.type = { + def addOne(elem: Int): this.type = { ensureSize(size + 1) elems(size) = elem size += 1 this } - override def ++=(xs: TraversableOnce[Int]): this.type = xs match { - case xs: WrappedArray.ofInt => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { size = 0 } - def result() = { if (capacity != 0 && capacity == size) { capacity = 0 @@ -442,11 +375,10 @@ object ArrayBuilder { } /** A class for array builders for arrays of `long`s. It can be reused. */ + @SerialVersionUID(3L) final class ofLong extends ArrayBuilder[Long] { - private var elems: Array[Long] = _ - private var capacity: Int = 0 - private var size: Int = 0 + protected var elems: Array[Long] = _ private def mkArray(size: Int): Array[Long] = { val newelems = new Array[Long](size) @@ -454,42 +386,18 @@ object ArrayBuilder { newelems } - private def resize(size: Int) { + protected[this] def resize(size: Int): Unit = { elems = mkArray(size) capacity = size } - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Long): this.type = { + def addOne(elem: Long): this.type = { ensureSize(size + 1) elems(size) = elem size += 1 this } - override def ++=(xs: TraversableOnce[Long]): this.type = xs match { - case xs: WrappedArray.ofLong => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { size = 0 } - def result() = { if (capacity != 0 && capacity == size) { capacity = 0 @@ -507,11 +415,10 @@ object ArrayBuilder { } /** A class for array builders for arrays of `float`s. It can be reused. */ + @SerialVersionUID(3L) final class ofFloat extends ArrayBuilder[Float] { - private var elems: Array[Float] = _ - private var capacity: Int = 0 - private var size: Int = 0 + protected var elems: Array[Float] = _ private def mkArray(size: Int): Array[Float] = { val newelems = new Array[Float](size) @@ -519,42 +426,18 @@ object ArrayBuilder { newelems } - private def resize(size: Int) { + protected[this] def resize(size: Int): Unit = { elems = mkArray(size) capacity = size } - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Float): this.type = { + def addOne(elem: Float): this.type = { ensureSize(size + 1) elems(size) = elem size += 1 this } - override def ++=(xs: TraversableOnce[Float]): this.type = xs match { - case xs: WrappedArray.ofFloat => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { size = 0 } - def result() = { if (capacity != 0 && capacity == size) { capacity = 0 @@ -572,11 +455,10 @@ object ArrayBuilder { } /** A class for array builders for arrays of `double`s. It can be reused. */ + @SerialVersionUID(3L) final class ofDouble extends ArrayBuilder[Double] { - private var elems: Array[Double] = _ - private var capacity: Int = 0 - private var size: Int = 0 + protected var elems: Array[Double] = _ private def mkArray(size: Int): Array[Double] = { val newelems = new Array[Double](size) @@ -584,42 +466,18 @@ object ArrayBuilder { newelems } - private def resize(size: Int) { + protected[this] def resize(size: Int): Unit = { elems = mkArray(size) capacity = size } - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Double): this.type = { + def addOne(elem: Double): this.type = { ensureSize(size + 1) elems(size) = elem size += 1 this } - override def ++=(xs: TraversableOnce[Double]): this.type = xs match { - case xs: WrappedArray.ofDouble => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { size = 0 } - def result() = { if (capacity != 0 && capacity == size) { capacity = 0 @@ -637,11 +495,10 @@ object ArrayBuilder { } /** A class for array builders for arrays of `boolean`s. It can be reused. */ + @SerialVersionUID(3L) class ofBoolean extends ArrayBuilder[Boolean] { - private var elems: Array[Boolean] = _ - private var capacity: Int = 0 - private var size: Int = 0 + protected var elems: Array[Boolean] = _ private def mkArray(size: Int): Array[Boolean] = { val newelems = new Array[Boolean](size) @@ -649,42 +506,18 @@ object ArrayBuilder { newelems } - private def resize(size: Int) { + protected[this] def resize(size: Int): Unit = { elems = mkArray(size) capacity = size } - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Boolean): this.type = { + def addOne(elem: Boolean): this.type = { ensureSize(size + 1) elems(size) = elem size += 1 this } - override def ++=(xs: TraversableOnce[Boolean]): this.type = xs match { - case xs: WrappedArray.ofBoolean => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { size = 0 } - def result() = { if (capacity != 0 && capacity == size) { capacity = 0 @@ -702,21 +535,25 @@ object ArrayBuilder { } /** A class for array builders for arrays of `Unit` type. It can be reused. */ + @SerialVersionUID(3L) final class ofUnit extends ArrayBuilder[Unit] { - private var size: Int = 0 + protected def elems: Array[Unit] = throw new UnsupportedOperationException() - def +=(elem: Unit): this.type = { + def addOne(elem: Unit): this.type = { size += 1 this } - override def ++=(xs: TraversableOnce[Unit]): this.type = { - size += xs.size + override def addAll(xs: IterableOnce[Unit]): this.type = { + size += xs.iterator.size this } - def clear() { size = 0 } + override def addAll(xs: Array[_ <: Unit], offset: Int, length: Int): this.type = { + size += length + this + } def result() = { val ans = new Array[Unit](size) @@ -730,6 +567,8 @@ object ArrayBuilder { case _ => false } + protected[this] def resize(size: Int): Unit = () + override def toString = "ArrayBuilder.ofUnit" } } diff --git a/scalalib/overrides-2.13/scala/collection/mutable/Buffer.scala b/scalalib/overrides-2.13/scala/collection/mutable/Buffer.scala index 2171cb9dea..8f58461a83 100644 --- a/scalalib/overrides-2.13/scala/collection/mutable/Buffer.scala +++ b/scalalib/overrides-2.13/scala/collection/mutable/Buffer.scala @@ -1,51 +1,175 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ +package scala.collection +package mutable +import scala.scalajs.js +/** A `Buffer` is a growable and shrinkable `Seq`. */ +trait Buffer[A] + extends Seq[A] + with SeqOps[A, Buffer, Buffer[A]] + with Growable[A] + with Shrinkable[A] { -package scala -package collection -package mutable + override def iterableFactory: SeqFactory[Buffer] = Buffer -import generic._ + //TODO Prepend is a logical choice for a readable name of `+=:` but it conflicts with the renaming of `append` to `add` + /** Prepends a single element at the front of this $coll. + * + * @param elem the element to $add. + * @return the $coll itself + */ + def prepend(elem: A): this.type -import scala.scalajs.js + @deprecated("Use .addOne or += instead of .append", "2.13.0") + @`inline` final def append(elem: A): this.type = addOne(elem) + + /** Alias for `prepend` */ + @`inline` final def +=: (elem: A): this.type = prepend(elem) + + def prependAll(elems: IterableOnce[A]): this.type = { insertAll(0, elems); this } + + /** Inserts a new element at a given index into this buffer. + * + * @param idx the index where the new elements is inserted. + * @param elem the element to insert. + * @throws IndexOutOfBoundsException if the index `idx` is not in the valid range + * `0 <= idx <= length`. + */ + @throws[IndexOutOfBoundsException] + def insert(idx: Int, elem: A): Unit + + /** Inserts new elements at the index `idx`. Opposed to method + * `update`, this method will not replace an element with a new + * one. Instead, it will insert a new element at index `idx`. + * + * @param idx the index where a new element will be inserted. + * @param elems the iterable object providing all elements to insert. + * @throws IndexOutOfBoundsException if `idx` is out of bounds. + */ + @throws[IndexOutOfBoundsException] + def insertAll(idx: Int, elems: IterableOnce[A]): Unit + + /** Removes the element at a given index position. + * + * @param idx the index which refers to the element to delete. + * @return the element that was formerly at index `idx`. + */ + @throws[IndexOutOfBoundsException] + def remove(idx: Int): A + + /** Removes the element on a given index position. It takes time linear in + * the buffer size. + * + * @param idx the index which refers to the first element to remove. + * @param count the number of elements to remove. + * @throws IndexOutOfBoundsException if the index `idx` is not in the valid range + * `0 <= idx <= length - count` (with `count > 0`). + * @throws IllegalArgumentException if `count < 0`. + */ + @throws[IndexOutOfBoundsException] + @throws[IllegalArgumentException] + def remove(idx: Int, count: Int): Unit -/** Buffers are used to create sequences of elements incrementally by - * appending, prepending, or inserting new elements. It is also - * possible to access and modify elements in a random access fashion - * via the index of the element in the current sequence. - * - * @author Matthias Zenger - * @author Martin Odersky - * @version 2.8 - * @since 1 - * - * @tparam A type of the elements contained in this buffer. - * - * @define Coll `Buffer` - * @define coll buffer - */ -trait Buffer[A] extends Seq[A] - with GenericTraversableTemplate[A, Buffer] - with BufferLike[A, Buffer[A]] - with scala.Cloneable { - override def companion: GenericCompanion[Buffer] = Buffer + /** Removes the first ''n'' elements of this buffer. + * + * @param n the number of elements to remove from the beginning + * of this buffer. + */ + def trimStart(n: Int): Unit = remove(0, normalized(n)) + + /** Removes the last ''n'' elements of this buffer. + * + * @param n the number of elements to remove from the end + * of this buffer. + */ + def trimEnd(n: Int): Unit = { + val norm = normalized(n) + remove(length - norm, norm) + } + + def patchInPlace(from: Int, patch: scala.collection.Seq[A], replaced: Int): this.type + + // +=, ++=, clear inherited from Growable + // Per remark of @ichoran, we should preferably not have these: + // + // def +=:(elem: A): this.type = { insert(0, elem); this } + // def +=:(elem1: A, elem2: A, elems: A*): this.type = elem1 +=: elem2 +=: elems ++=: this + // def ++=:(elems: IterableOnce[A]): this.type = { insertAll(0, elems); this } + + def dropInPlace(n: Int): this.type = { remove(0, normalized(n)); this } + def dropRightInPlace(n: Int): this.type = { + val norm = normalized(n) + remove(length - norm, norm) + this + } + def takeInPlace(n: Int): this.type = { + val norm = normalized(n) + remove(norm, length - norm) + this + } + def takeRightInPlace(n: Int): this.type = { remove(0, length - normalized(n)); this } + def sliceInPlace(start: Int, end: Int): this.type = takeInPlace(end).dropInPlace(start) + private def normalized(n: Int): Int = math.min(math.max(n, 0), length) + + def dropWhileInPlace(p: A => Boolean): this.type = { + val idx = indexWhere(!p(_)) + if (idx < 0) { clear(); this } else dropInPlace(idx) + } + def takeWhileInPlace(p: A => Boolean): this.type = { + val idx = indexWhere(!p(_)) + if (idx < 0) this else takeInPlace(idx) + } + def padToInPlace(len: Int, elem: A): this.type = { + while (length < len) +=(elem) + this + } } -/** $factoryInfo - * @define coll buffer - * @define Coll `Buffer` - */ -object Buffer extends SeqFactory[Buffer] { - implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Buffer[A]] = ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]] - def newBuilder[A]: Builder[A, Buffer[A]] = new js.WrappedArray +trait IndexedOptimizedBuffer[A] extends IndexedOptimizedSeq[A] with Buffer[A] { + + def flatMapInPlace(f: A => IterableOnce[A]): this.type = { + // There's scope for a better implementation which copies elements in place. + var i = 0 + val s = size + val newElems = new Array[IterableOnce[A]](s) + while (i < s) { newElems(i) = f(this(i)); i += 1 } + clear() + i = 0 + while (i < s) { ++=(newElems(i)); i += 1 } + this + } + + def filterInPlace(p: A => Boolean): this.type = { + var i, j = 0 + while (i < size) { + if (p(apply(i))) { + if (i != j) { + this(j) = this(i) + } + j += 1 + } + i += 1 + } + + if (i == j) this else takeInPlace(j) + } + + def patchInPlace(from: Int, patch: scala.collection.Seq[A], replaced: Int): this.type = { + val replaced0 = math.min(math.max(replaced, 0), length) + val i = math.min(math.max(from, 0), length) + var j = 0 + val n = math.min(patch.length, replaced0) + while (j < n && i + j < length) { + update(i + j, patch(j)) + j += 1 + } + if (j < patch.length) insertAll(i + j, patch.iterator.drop(j)) + else if (j < replaced0) remove(i + j, replaced0 - j) + this + } } +object Buffer extends SeqFactory.Delegate[Buffer](js.WrappedArray) + /** Explicit instantiation of the `Buffer` trait to reduce class file size in subclasses. */ abstract class AbstractBuffer[A] extends AbstractSeq[A] with Buffer[A] diff --git a/scalalib/overrides-2.13/scala/package.scala b/scalalib/overrides-2.13/scala/package.scala index 21051d473f..39b2190e47 100644 --- a/scalalib/overrides-2.13/scala/package.scala +++ b/scalalib/overrides-2.13/scala/package.scala @@ -1,3 +1,5 @@ +import scala.annotation.migration + /* __ *\ ** ________ ___ / / ___ Scala API ** ** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** @@ -34,23 +36,31 @@ package object scala { override def toString = "object AnyRef" } - type TraversableOnce[+A] = scala.collection.TraversableOnce[A] + @deprecated("Use IterableOnce instead of TraversableOnce", "2.13.0") + type TraversableOnce[+A] = scala.collection.IterableOnce[A] + + type IterableOnce[+A] = scala.collection.IterableOnce[A] - type Traversable[+A] = scala.collection.Traversable[A] - val Traversable = scala.collection.Traversable + @deprecated("Use Iterable instead of Traversable", "2.13.0") + type Traversable[+A] = scala.collection.Iterable[A] + @deprecated("Use Iterable instead of Traversable", "2.13.0") + val Traversable = scala.collection.Iterable type Iterable[+A] = scala.collection.Iterable[A] val Iterable = scala.collection.Iterable - type Seq[+A] = scala.collection.Seq[A] - val Seq = scala.collection.Seq + @migration("scala.Seq is now scala.collection.immutable.Seq instead of scala.collection.Seq", "2.13.0") + type Seq[+A] = scala.collection.immutable.Seq[A] + val Seq = scala.collection.immutable.Seq - type IndexedSeq[+A] = scala.collection.IndexedSeq[A] - val IndexedSeq = scala.collection.IndexedSeq + @migration("scala.IndexedSeq is now scala.collection.immutable.IndexedSeq instead of scala.collection.IndexedSeq", "2.13.0") + type IndexedSeq[+A] = scala.collection.immutable.IndexedSeq[A] + val IndexedSeq = scala.collection.immutable.IndexedSeq type Iterator[+A] = scala.collection.Iterator[A] val Iterator = scala.collection.Iterator + @deprecated("Use scala.collection.BufferedIterator instead of scala.BufferedIterator", "2.13.0") type BufferedIterator[+A] = scala.collection.BufferedIterator[A] type List[+A] = scala.collection.immutable.List[A] @@ -64,9 +74,21 @@ package object scala { val +: = scala.collection.+: val :+ = scala.collection.:+ + @deprecated("Use LazyList instead of Stream", "2.13.0") type Stream[+A] = scala.collection.immutable.Stream[A] + @deprecated("Use LazyList instead of Stream", "2.13.0") val Stream = scala.collection.immutable.Stream - val #:: = scala.collection.immutable.Stream.#:: + + type LazyList[+A] = scala.collection.immutable.LazyList[A] + val LazyList = scala.collection.immutable.LazyList + // This should be an alias to LazyList.#:: but we need to support Stream, too + //val #:: = scala.collection.immutable.LazyList.#:: + object #:: { + def unapply[A](s: LazyList[A]): Option[(A, LazyList[A])] = + if (s.nonEmpty) Some((s.head, s.tail)) else None + def unapply[A](s: Stream[A]): Option[(A, Stream[A])] = + if (s.nonEmpty) Some((s.head, s.tail)) else None + } type Vector[+A] = scala.collection.immutable.Vector[A] val Vector = scala.collection.immutable.Vector @@ -115,19 +137,4 @@ package object scala { type Right[+A, +B] = scala.util.Right[A, B] val Right = scala.util.Right - // Annotations which we might move to annotation.* -/* - type SerialVersionUID = annotation.SerialVersionUID - type deprecated = annotation.deprecated - type deprecatedName = annotation.deprecatedName - type inline = annotation.inline - type native = annotation.native - type noinline = annotation.noinline - type remote = annotation.remote - type specialized = annotation.specialized - type transient = annotation.transient - type throws = annotation.throws - type unchecked = annotation.unchecked.unchecked - type volatile = annotation.volatile - */ } diff --git a/scalalib/overrides-2.13/scala/runtime/ScalaRunTime.scala b/scalalib/overrides-2.13/scala/runtime/ScalaRunTime.scala index 148fb827c5..84d7395106 100644 --- a/scalalib/overrides-2.13/scala/runtime/ScalaRunTime.scala +++ b/scalalib/overrides-2.13/scala/runtime/ScalaRunTime.scala @@ -27,7 +27,7 @@ object ScalaRunTime { x != null && isArrayClass(x.getClass, atLevel) private def isArrayClass(clazz: jClass[_], atLevel: Int): Boolean = - clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) + clazz != null && clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) // A helper method to make my life in the pattern matcher a lot easier. def drop[Repr](coll: Repr, num: Int)(implicit iterable: IsIterableLike[Repr]): Repr = diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala b/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala index c1b230b0fe..b57df0d6ee 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala @@ -91,7 +91,7 @@ protected[testinterface] object HTMLRunner { private def runTests(framework: Framework, taskDefs: Seq[TaskDef], ui: UI): Future[Boolean] = { - def runAllTasks(tasks: Seq[Task]): Future[Boolean] = { + def runAllTasks(tasks: collection.Seq[Task]): Future[Boolean] = { val oks = tasks.map { task => for { (ok, newTasks) <- scheduleTask(task, ui) @@ -413,7 +413,7 @@ protected[testinterface] object HTMLRunner { private def statusClass(ok: Boolean): String = if (ok) "success" else "error" - private def checkboxUpdater(tests: Seq[Test], + private def checkboxUpdater(tests: collection.Seq[Test], checkbox: dom.Checkbox): js.Function0[Boolean] = { () => val all = tests.forall(_.selected) val indet = !all && tests.exists(_.selected) @@ -424,7 +424,7 @@ protected[testinterface] object HTMLRunner { true } - private def testUpdater(tests: Seq[Test], + private def testUpdater(tests: collection.Seq[Test], checkbox: dom.Checkbox): js.Function0[Boolean] = { () => tests.foreach(_.selected = checkbox.checked) true @@ -506,5 +506,6 @@ protected[testinterface] object HTMLRunner { } } - private def and(xs: Seq[Boolean]): Boolean = xs.fold(true)(_ && _) + private def and(xs: collection.Seq[Boolean]): Boolean = + xs.foldLeft(true)(_ && _) } diff --git a/test-suite/js/src/test/scala-new-collections/org/scalajs/testsuite/library/ArrayOpsToTest.scala b/test-suite/js/src/test/scala-new-collections/org/scalajs/testsuite/library/ArrayOpsToTest.scala new file mode 100644 index 0000000000..df17b7228c --- /dev/null +++ b/test-suite/js/src/test/scala-new-collections/org/scalajs/testsuite/library/ArrayOpsToTest.scala @@ -0,0 +1,23 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.library + +import scala.scalajs.js + +import org.junit.Assert._ +import org.junit.Test + +class ArrayOpsToTest { + + @Test def to_T_issue_843(): Unit = { + val array = js.Array(1, 2, 1, 3, 1, 10, 9) + val list = array.to(List) + assertArrayEquals(array.toArray, list.toArray) + } + +} diff --git a/test-suite/js/src/test/scala-new-collections/org/scalajs/testsuite/library/WrappedArrayToTest.scala b/test-suite/js/src/test/scala-new-collections/org/scalajs/testsuite/library/WrappedArrayToTest.scala new file mode 100644 index 0000000000..6e554ed170 --- /dev/null +++ b/test-suite/js/src/test/scala-new-collections/org/scalajs/testsuite/library/WrappedArrayToTest.scala @@ -0,0 +1,23 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.library + +import scala.scalajs.js + +import org.junit.Assert._ +import org.junit.Test + +class WrappedArrayToTest { + + @Test def to_T(): Unit = { + val seq: collection.Seq[Int] = js.Array(1, 2, 1, 3, 1, 10, 9) + val list = seq.to(List) + assertEquals(List(1, 2, 1, 3, 1, 10, 9), list) + } + +} diff --git a/test-suite/js/src/test/scala-new-collections/org/scalajs/testsuite/library/WrappedDictionaryToTest.scala b/test-suite/js/src/test/scala-new-collections/org/scalajs/testsuite/library/WrappedDictionaryToTest.scala new file mode 100644 index 0000000000..9e9f236fde --- /dev/null +++ b/test-suite/js/src/test/scala-new-collections/org/scalajs/testsuite/library/WrappedDictionaryToTest.scala @@ -0,0 +1,23 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.library + +import scala.scalajs.js + +import org.junit.Assert._ +import org.junit.Test + +class WrappedDictionaryToTest { + + @Test def to_T(): Unit = { + val dict = js.Dictionary("a" -> "a", "b" -> 6, "e" -> js.undefined) + val list = dict.to(List) + assertEquals(3, list.size) + } + +} diff --git a/test-suite/js/src/test/scala-old-collections/org/scalajs/testsuite/library/ArrayOpsToTest.scala b/test-suite/js/src/test/scala-old-collections/org/scalajs/testsuite/library/ArrayOpsToTest.scala new file mode 100644 index 0000000000..180312a86a --- /dev/null +++ b/test-suite/js/src/test/scala-old-collections/org/scalajs/testsuite/library/ArrayOpsToTest.scala @@ -0,0 +1,23 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.library + +import scala.scalajs.js + +import org.junit.Assert._ +import org.junit.Test + +class ArrayOpsToTest { + + @Test def to_T_issue_843(): Unit = { + val array = js.Array(1, 2, 1, 3, 1, 10, 9) + val list = array.to[List] + assertArrayEquals(array.toArray, list.toArray) + } + +} diff --git a/test-suite/js/src/test/scala-old-collections/org/scalajs/testsuite/library/WrappedArrayToTest.scala b/test-suite/js/src/test/scala-old-collections/org/scalajs/testsuite/library/WrappedArrayToTest.scala new file mode 100644 index 0000000000..1f0130406c --- /dev/null +++ b/test-suite/js/src/test/scala-old-collections/org/scalajs/testsuite/library/WrappedArrayToTest.scala @@ -0,0 +1,23 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.library + +import scala.scalajs.js + +import org.junit.Assert._ +import org.junit.Test + +class WrappedArrayToTest { + + @Test def to_T(): Unit = { + val seq: collection.Seq[Int] = js.Array(1, 2, 1, 3, 1, 10, 9) + val list = seq.to[List] + assertEquals(List(1, 2, 1, 3, 1, 10, 9), list) + } + +} diff --git a/test-suite/js/src/test/scala-old-collections/org/scalajs/testsuite/library/WrappedDictionaryToTest.scala b/test-suite/js/src/test/scala-old-collections/org/scalajs/testsuite/library/WrappedDictionaryToTest.scala new file mode 100644 index 0000000000..065817408e --- /dev/null +++ b/test-suite/js/src/test/scala-old-collections/org/scalajs/testsuite/library/WrappedDictionaryToTest.scala @@ -0,0 +1,23 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js Test Suite ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ +package org.scalajs.testsuite.library + +import scala.scalajs.js + +import org.junit.Assert._ +import org.junit.Test + +class WrappedDictionaryToTest { + + @Test def to_T(): Unit = { + val dict = js.Dictionary("a" -> "a", "b" -> 6, "e" -> js.undefined) + val list = dict.to[List] + assertEquals(3, list.size) + } + +} diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala index d0a1e395d5..d4fcb54e9f 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala @@ -414,7 +414,7 @@ class OptimizerTest { val a = js.Array[Any]("hello", 42) val foo = new Foo - foo.check(5, "foobar", a: _*) + foo.check(5, "foobar", a.toIndexedSeq: _*) } @Test def must_not_break_virtualized_tuple(): Unit = { diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ArrayOpsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ArrayOpsTest.scala index 63058431c6..7e25d0bc45 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ArrayOpsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ArrayOpsTest.scala @@ -113,9 +113,4 @@ class ArrayOpsTest { assertArrayEquals(array.toArray, list.toArray) } - @Test def to_T_issue_843(): Unit = { - val array = js.Array(1,2,1,3,1,10,9) - val list = array.to[List] - assertArrayEquals(array.toArray, list.toArray) - } } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UnionTypeTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UnionTypeTest.scala index 45db7507c6..1ab3381389 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UnionTypeTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UnionTypeTest.scala @@ -133,7 +133,7 @@ class UnionTypeTest { assertEquals("hello", y3.asInstanceOf[js.Any]) val x4: List[Int] | Vector[Int] | mutable.Buffer[Int] = List(3, 5) - val y4: Seq[Int] = x4.merge + val y4: collection.Seq[Int] = x4.merge assertEquals(Seq(3, 5), y4) } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/WrappedArrayTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/WrappedArrayTest.scala index 4912b41713..18bfb495ba 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/WrappedArrayTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/WrappedArrayTest.scala @@ -20,7 +20,7 @@ class WrappedArrayTest { @Test def apply(): Unit = { val array = js.Array(3,4,5,6,3,4) - val seq: Seq[Int] = array + val seq: collection.Seq[Int] = array assertEquals(3, seq(0)) assertEquals(6, seq(3)) @@ -43,7 +43,7 @@ class WrappedArrayTest { @Test def length(): Unit = { val array = js.Array(3,4,5,6,3,4) - val seq: Seq[Int] = array + val seq: collection.Seq[Int] = array assertEquals(6, seq.length) array.push(1) @@ -56,11 +56,11 @@ class WrappedArrayTest { assertArrayEquals(Array(3, 5, 8, 9), array.toArray) } - @Test def ++=:(): Unit = { + @Test def prependAll(): Unit = { val array = js.Array(5, 8, 9) - js.Array(2, 0) ++=: array + array.prependAll(js.Array(2, 0)) assertArrayEquals(Array(2, 0, 5, 8, 9), array.toArray) - Seq(-3, -45, 1) ++=: array + array.prependAll(Seq(-3, -45, 1)) assertArrayEquals(Array(-3, -45, 1, 2, 0, 5, 8, 9), array.toArray) } @@ -96,21 +96,15 @@ class WrappedArrayTest { } @Test def diff(): Unit = { - val seq: Seq[Int] = js.Array(1,2,1,3,1,10,9) + val seq: collection.Seq[Int] = js.Array(1,2,1,3,1,10,9) val diff = seq.diff(Seq(1,3,9)) assertArrayEquals(Array(2,1,1,10), diff.toArray) } @Test def toList(): Unit = { - val seq: Seq[Int] = js.Array(1,2,1,3,1,10,9) + val seq: collection.Seq[Int] = js.Array(1,2,1,3,1,10,9) val list = seq.toList assertEquals(List(1,2,1,3,1,10,9), list) } - @Test def to[T](): Unit = { - val seq: Seq[Int] = js.Array(1,2,1,3,1,10,9) - val list = seq.to[List] - assertEquals(List(1,2,1,3,1,10,9), list) - } - } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/WrappedDictionaryTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/WrappedDictionaryTest.scala index ef243a85f5..ab0022edb9 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/WrappedDictionaryTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/WrappedDictionaryTest.scala @@ -54,26 +54,68 @@ class WrappedDictionaryTest { assertTrue(map.iterator.toList.sorted.sameElements(elems)) } - // Some arbitrary methods to test the builders + /* Methods that need to be overloaded in 2.13 collections to get the correct + * result type. + */ @Test def map(): Unit = { def ct[A: ClassTag](x: A): ClassTag[A] = implicitly[ClassTag[A]] - val dict = js.Dictionary[Int]() - dict ++= Seq("one" -> 1, "two" -> 2, "three" -> 3) - val mapChr = dict.map { case (k,v) => k(0) -> v * 2 } - val mapStr = dict.map { case (k,v) => k(0).toString -> v * 2 } + val dict = js.Dictionary[Int]("one" -> 1, "two" -> 2, "three" -> 3) + + val mapChr = dict.map { case (k, v) => k(0) -> v * 2 } + val mapStr = dict.map { case (k, v) => k(0).toString -> v * 2 } - assertFalse(ct(mapChr).runtimeClass == classOf[js.WrappedDictionary[_]]) - assertTrue(ct(mapStr).runtimeClass == classOf[js.WrappedDictionary[_]]) + assertNotSame(classOf[js.WrappedDictionary[_]], ct(mapChr).runtimeClass) + assertSame(classOf[js.WrappedDictionary[_]], ct(mapStr).runtimeClass) assertEquals(2, mapChr.size) assertEquals(2, mapStr.size) } + @Test def flatMap(): Unit = { + def ct[A: ClassTag](x: A): ClassTag[A] = implicitly[ClassTag[A]] + + val dict = js.Dictionary[Int]("one" -> 1, "two" -> 2, "three" -> 3) + + val flatMapChr = dict.flatMap { + case (k, v) => List(k(0) -> v * 2, k(1) -> v * 3) + } + val flatMapStr = dict.flatMap { + case (k, v) => List(k(0).toString -> v * 2, k(1).toString -> v * 3) + } + + assertNotSame(classOf[js.WrappedDictionary[_]], ct(flatMapChr).runtimeClass) + assertSame(classOf[js.WrappedDictionary[_]], ct(flatMapStr).runtimeClass) + + assertEquals(5, flatMapChr.size) + assertEquals(5, flatMapStr.size) + } + + @Test def collect(): Unit = { + def ct[A: ClassTag](x: A): ClassTag[A] = implicitly[ClassTag[A]] + + val dict = js.Dictionary[Int]("one" -> 1, "two" -> 2, "three" -> 3) + + val collectChr = dict.collect { + case (k, v) if v > 1 => k(0) -> v * 2 + } + val collectStr = dict.collect { + case (k, v) if v > 1 => k(0).toString -> v * 2 + } + + assertNotSame(classOf[js.WrappedDictionary[_]], ct(collectChr).runtimeClass) + assertSame(classOf[js.WrappedDictionary[_]], ct(collectStr).runtimeClass) + + assertEquals(1, collectChr.size) + assertEquals(1, collectStr.size) + } + + // Some arbitrary methods to test the builders + @Test def withFilter(): Unit = { val dict = js.Dictionary[Int]() - val flt = dict.withFilter { case (k,v) => v > 5 || k == "a" } + val flt = dict.withFilter { case (k, v) => v > 5 || k == "a" } def size: Int = flt.map(x => x).size assertEquals(0, size) @@ -95,10 +137,4 @@ class WrappedDictionaryTest { assertEquals(3, list.size) } - @Test def to_T(): Unit = { - val dict = js.Dictionary("a" -> "a", "b" -> 6, "e" -> js.undefined) - val list = dict.to[List] - assertEquals(3, list.size) - } - } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/AbstractCollectionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/AbstractCollectionTest.scala index 350ba17d5f..17abe98f26 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/AbstractCollectionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/AbstractCollectionTest.scala @@ -38,7 +38,7 @@ class AbstractCollectionFactory extends CollectionFactory { override def iterator(): ju.Iterator[E] = { new ju.Iterator[E] { - val innerIter = inner.seq.iterator + val innerIter = inner.iterator var last: Option[E] = None diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ArrayBuilderTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ArrayBuilderTest.scala index 8cdfbe244d..769a24c999 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ArrayBuilderTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ArrayBuilderTest.scala @@ -24,9 +24,18 @@ class ArrayBuilderTest { def erase(x: Any): Any = x @inline - def makeNoInline[T: ClassTag](): ArrayBuilder[T] = { - @noinline def ct = implicitly[ClassTag[T]] - ArrayBuilder.make[T]()(ct) + def makeNoInline[T](implicit ct: ClassTag[T]): ArrayBuilder[T] = { + /* The dance in this method is to be source compatible with the old and + * new collections. In the new collections, ArrayBuilder.make[T] doesn't + * take an explicit () parameter list, but it does in the old collections. + */ + + @noinline def ctNoInline = ct + + { + implicit val ct = ctNoInline + ArrayBuilder.make[T] + } } @inline @@ -43,7 +52,7 @@ class ArrayBuilderTest { @noinline def someString: String = "world" @Test def Int_normal_case_inline(): Unit = { - val b = ArrayBuilder.make[Int]() + val b = ArrayBuilder.make[Int] b += 42 b += someInt val a = b.result() @@ -56,7 +65,7 @@ class ArrayBuilderTest { } @Test def Int_normal_case_noinline(): Unit = { - val b = makeNoInline[Int]() + val b = makeNoInline[Int] b += 42 b += someInt val a = b.result() @@ -85,7 +94,7 @@ class ArrayBuilderTest { } @Test def Char_normal_case_inline(): Unit = { - val b = ArrayBuilder.make[Char]() + val b = ArrayBuilder.make[Char] b += 'A' b += someChar val a = b.result() @@ -98,7 +107,7 @@ class ArrayBuilderTest { } @Test def Char_normal_case_noinline(): Unit = { - val b = makeNoInline[Char]() + val b = makeNoInline[Char] b += 'A' b += someChar val a = b.result() @@ -127,7 +136,7 @@ class ArrayBuilderTest { } @Test def Boolean_normal_case_inline(): Unit = { - val b = ArrayBuilder.make[Boolean]() + val b = ArrayBuilder.make[Boolean] b += true b += someBoolean val a = b.result() @@ -140,7 +149,7 @@ class ArrayBuilderTest { } @Test def Boolean_normal_case_noinline(): Unit = { - val b = makeNoInline[Boolean]() + val b = makeNoInline[Boolean] b += true b += someBoolean val a = b.result() @@ -169,7 +178,7 @@ class ArrayBuilderTest { } @Test def Unit_normal_case_inline(): Unit = { - val b = ArrayBuilder.make[Unit]() + val b = ArrayBuilder.make[Unit] b += () val a = b.result() @@ -180,7 +189,7 @@ class ArrayBuilderTest { } @Test def Unit_normal_case_noinline(): Unit = { - val b = makeNoInline[Unit]() + val b = makeNoInline[Unit] b += () val a = b.result() @@ -211,7 +220,7 @@ class ArrayBuilderTest { } @Test def String_normal_case_inline(): Unit = { - val b = ArrayBuilder.make[String]() + val b = ArrayBuilder.make[String] b += "hello" b += someString val a = b.result() @@ -224,7 +233,7 @@ class ArrayBuilderTest { } @Test def String_normal_case_noinline(): Unit = { - val b = makeNoInline[String]() + val b = makeNoInline[String] b += "hello" b += someString val a = b.result() @@ -251,10 +260,10 @@ class ArrayBuilderTest { } @Test def Nothing_and_Null(): Unit = { - assertSame(classOf[Array[Nothing]], ArrayBuilder.make[Nothing]().result().getClass) - assertSame(classOf[Array[Null]], ArrayBuilder.make[Null]().result().getClass) + assertSame(classOf[Array[Nothing]], ArrayBuilder.make[Nothing].result().getClass) + assertSame(classOf[Array[Null]], ArrayBuilder.make[Null].result().getClass) - assertSame(classOf[Array[Nothing]], makeNoInline[Nothing]().result().getClass) - assertSame(classOf[Array[Null]], makeNoInline[Null]().result().getClass) + assertSame(classOf[Array[Nothing]], makeNoInline[Nothing].result().getClass) + assertSame(classOf[Array[Null]], makeNoInline[Null].result().getClass) } } From c7a7632fdef17265b783d08c2cb399646bf3a880 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 15 May 2018 12:42:06 +0200 Subject: [PATCH 0739/2665] Version 0.6.23. --- ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index c17b235be2..e4ef4b6b77 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.23-SNAPSHOT" + val current: String = "0.6.23" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" From ef26dc26fbc85451930811da0cdc27dec3f4bb3c Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 14 Apr 2018 07:25:33 +0200 Subject: [PATCH 0740/2665] Use VirtualBinaryFile in jsenv.Input --- .../main/scala/org/scalajs/io/MemFiles.scala | 5 ++++ .../org/scalajs/jsenv/test/RunTests.scala | 6 ++--- .../org/scalajs/jsenv/test/TestComKit.scala | 6 ++--- .../org/scalajs/jsenv/test/TestKit.scala | 6 ++--- .../main/scala/org/scalajs/jsenv/Input.scala | 2 +- .../main/scala/org/scalajs/jsenv/JSEnv.scala | 2 -- .../org/scalajs/jsenv/nodejs/ComSupport.scala | 10 ++++---- .../org/scalajs/jsenv/nodejs/NodeJSEnv.scala | 23 +++++++++---------- .../org/scalajs/jsenv/nodejs/Support.scala | 4 ++-- .../scala/tools/nsc/MainGenericRunner.scala | 6 +++-- project/Build.scala | 10 ++++---- project/NodeJSEnvForcePolyfills.scala | 4 ++-- sbt-plugin-test/build.sbt | 2 +- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 2 +- .../sbtplugin/ScalaJSPluginInternal.scala | 2 +- .../testadapter/HTMLRunnerBuilder.scala | 6 ++--- 16 files changed, 50 insertions(+), 46 deletions(-) diff --git a/io/shared/src/main/scala/org/scalajs/io/MemFiles.scala b/io/shared/src/main/scala/org/scalajs/io/MemFiles.scala index d539dcc211..0c90ba8bec 100644 --- a/io/shared/src/main/scala/org/scalajs/io/MemFiles.scala +++ b/io/shared/src/main/scala/org/scalajs/io/MemFiles.scala @@ -11,6 +11,8 @@ package org.scalajs.io import java.io._ +import java.nio.charset.StandardCharsets + /** A base class for simple in-memory mutable virtual files. */ class MemVirtualFile(val path: String) extends VirtualFile { private[this] var _version: Option[String] = None @@ -65,6 +67,9 @@ class MemVirtualBinaryFile(p: String) extends MemVirtualFile(p) content = v this } + + final def withStringUTF8(v: String): this.type = + withContent(v.getBytes(StandardCharsets.UTF_8)) } /** A simple in-memory mutable virtual JS file. */ diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala index ce584c62e0..69bf851c56 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala @@ -2,7 +2,7 @@ package org.scalajs.jsenv.test import scala.concurrent.Await -import org.scalajs.io.VirtualJSFile +import org.scalajs.io.VirtualBinaryFile import org.scalajs.jsenv._ import org.junit.Assert._ @@ -118,10 +118,10 @@ private[test] class RunTests(config: JSEnvSuiteConfig, withCom: Boolean) { @Test def noThrowOnBadFileTest: Unit = { - val badFile = new VirtualJSFile { + val badFile = new VirtualBinaryFile { def path: String = ??? def exists: Boolean = ??? - def content: String = ??? + def content: Array[Byte] = ??? } // `start` may not throw but must fail asynchronously diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestComKit.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestComKit.scala index 20eecd22b6..c33190bd75 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestComKit.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestComKit.scala @@ -2,7 +2,7 @@ package org.scalajs.jsenv.test import java.util.concurrent.TimeoutException -import org.scalajs.io.{VirtualJSFile, MemVirtualJSFile} +import org.scalajs.io.{VirtualBinaryFile, MemVirtualBinaryFile} import org.scalajs.jsenv._ @@ -14,11 +14,11 @@ import scala.concurrent.duration.Duration private[test] final class TestComKit(config: JSEnvSuiteConfig) { def start(code: String, runConfig: RunConfig): Run = { - val vf = new MemVirtualJSFile("testScript.js").withContent(code) + val vf = new MemVirtualBinaryFile("testScript.js").withStringUTF8(code) start(vf, runConfig) } - def start(vf: VirtualJSFile, runConfig: RunConfig): Run = { + def start(vf: VirtualBinaryFile, runConfig: RunConfig): Run = { val input = Input.ScriptsToLoad(List(vf)) new Run(input, runConfig) } diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestKit.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestKit.scala index 766f8619b1..934eebb879 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestKit.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestKit.scala @@ -9,7 +9,7 @@ import scala.annotation.tailrec import scala.concurrent.Await import scala.concurrent.duration.Deadline -import org.scalajs.io.{VirtualJSFile, MemVirtualJSFile} +import org.scalajs.io.{VirtualBinaryFile, MemVirtualBinaryFile} import org.scalajs.jsenv._ @@ -20,11 +20,11 @@ private[test] final class TestKit(config: JSEnvSuiteConfig, withCom: Boolean) { assumeTrue("JSEnv needs com support", config.supportsCom || !withCom) def start(code: String, config: RunConfig): JSRun = { - val vf = new MemVirtualJSFile("testScript.js").withContent(code) + val vf = new MemVirtualBinaryFile("testScript.js").withStringUTF8(code) start(vf, config) } - def start(vf: VirtualJSFile, runConfig: RunConfig): JSRun = { + def start(vf: VirtualBinaryFile, runConfig: RunConfig): JSRun = { val input = Input.ScriptsToLoad(List(vf)) if (withCom) config.jsEnv.startWithCom(input, runConfig, _ => ()) diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/Input.scala b/js-envs/src/main/scala/org/scalajs/jsenv/Input.scala index d76029927e..7ca7b8344d 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/Input.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/Input.scala @@ -24,7 +24,7 @@ abstract class Input private () object Input { /** All files are to be loaded as scripts into the global scope in the order given. */ - final case class ScriptsToLoad(scripts: List[VirtualJSFile]) extends Input + final case class ScriptsToLoad(scripts: List[VirtualBinaryFile]) extends Input } case class UnsupportedInputException(msg: String, cause: Throwable) diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala index 7d60af72f4..59956f9573 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala @@ -9,8 +9,6 @@ package org.scalajs.jsenv -import org.scalajs.io.VirtualJSFile - /** A JavaScript execution environment. * * This can run and interact with JavaScript code. diff --git a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/ComSupport.scala b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/ComSupport.scala index aa03c859f3..34bb976ddf 100644 --- a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/ComSupport.scala +++ b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/ComSupport.scala @@ -12,7 +12,7 @@ package org.scalajs.jsenv.nodejs import java.io._ import java.net._ -import org.scalajs.io.{VirtualJSFile, MemVirtualJSFile} +import org.scalajs.io.{VirtualBinaryFile, MemVirtualBinaryFile} import org.scalajs.jsenv._ import scala.collection.immutable @@ -197,11 +197,11 @@ object ComRun { * @param config Configuration for the run. * @param onMessage callback upon message reception. * @param startRun [[JSRun]] launcher. Gets passed a - * [[org.scalajs.io.VirtualJSFile VirtualJSFile]] that + * [[org.scalajs.io.VirtualBinaryFile VirtualBinaryFile]] that * initializes `scalaJSCom` on `global`. Requires Node.js libraries. */ def start(config: RunConfig, onMessage: String => Unit)( - startRun: VirtualJSFile => JSRun): JSComRun = { + startRun: VirtualBinaryFile => JSRun): JSComRun = { try { val serverSocket = new ServerSocket(0, 0, InetAddress.getByName(null)) // Loopback address @@ -237,8 +237,8 @@ object ComRun { s.writeChars(msg) } - private def setupFile(port: Int): VirtualJSFile = { - new MemVirtualJSFile("comSetup.js").withContent( + private def setupFile(port: Int): VirtualBinaryFile = { + new MemVirtualBinaryFile("comSetup.js").withStringUTF8( s""" |(function() { | // The socket for communication diff --git a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala index dfdf3e5dff..b7a5f1bd41 100644 --- a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala +++ b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala @@ -41,7 +41,7 @@ final class NodeJSEnv(config: NodeJSEnv.Config) extends JSEnv { } } - private def internalStart(files: List[VirtualJSFile], + private def internalStart(files: List[VirtualBinaryFile], runConfig: RunConfig): JSRun = { val command = config.executable :: config.args val externalConfig = ExternalJSRun.Config() @@ -50,7 +50,7 @@ final class NodeJSEnv(config: NodeJSEnv.Config) extends JSEnv { ExternalJSRun.start(command, externalConfig)(NodeJSEnv.write(files)) } - private def initFiles: List[VirtualJSFile] = { + private def initFiles: List[VirtualBinaryFile] = { val base = List(NodeJSEnv.runtimeEnv, Support.fixPercentConsole) if (config.sourceMap) NodeJSEnv.installSourceMap :: base @@ -70,12 +70,12 @@ object NodeJSEnv { private lazy val validator = ExternalJSRun.supports(RunConfig.Validator()) private lazy val installSourceMap = { - new MemVirtualJSFile("sourceMapSupport.js").withContent( + new MemVirtualBinaryFile("sourceMapSupport.js").withStringUTF8( "require('source-map-support').install();") } private lazy val runtimeEnv = { - new MemVirtualJSFile("scalaJSEnvInfo.js").withContent( + new MemVirtualBinaryFile("scalaJSEnvInfo.js").withStringUTF8( """ |__ScalaJSEnv = { | exitFunction: function(status) { process.exit(status); } @@ -84,20 +84,19 @@ object NodeJSEnv { ) } - private def write(files: List[VirtualJSFile])(out: OutputStream): Unit = { - val writer = new BufferedWriter( - new OutputStreamWriter(out, StandardCharsets.UTF_8)) + private def write(files: List[VirtualBinaryFile])(out: OutputStream): Unit = { + val p = new PrintStream(out, false, "UTF8") try { files.foreach { - case file: FileVirtualJSFile => + case file: FileVirtualBinaryFile => val fname = file.file.getAbsolutePath - writer.write(s"""require("${escapeJS(fname)}");\n""") + p.println(s"""require("${escapeJS(fname)}");""") case f => - IO.writeTo(f, writer) - writer.write('\n') + IO.writeTo(f, p) + p.println() } } finally { - writer.close() + p.close() } } diff --git a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/Support.scala b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/Support.scala index f48bac1190..5c847fa64b 100644 --- a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/Support.scala +++ b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/Support.scala @@ -12,8 +12,8 @@ package org.scalajs.jsenv.nodejs import org.scalajs.io._ object Support { - def fixPercentConsole: VirtualJSFile = { - new MemVirtualJSFile("nodeConsoleHack.js").withContent( + def fixPercentConsole: VirtualBinaryFile = { + new MemVirtualBinaryFile("nodeConsoleHack.js").withStringUTF8( """ |// Hack console log to duplicate double % signs |(function() { diff --git a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala index be7543275e..2362fe84e0 100644 --- a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala +++ b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala @@ -83,8 +83,10 @@ class MainGenericRunner { val linker = StandardLinker(linkerConfig) val sjsCode = { - val output = WritableMemVirtualJSFile("partest.js") - linker.link(ir, moduleInitializers, output, logger) + val code = WritableMemVirtualJSFile("partest.js") + linker.link(ir, moduleInitializers, code, logger) + val output = new MemVirtualBinaryFile("partest.js") + .withStringUTF8(code.content) output } diff --git a/project/Build.scala b/project/Build.scala index 27b324cb28..d1117ce6f7 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -29,7 +29,7 @@ import ScalaJSPlugin.autoImport.{ModuleKind => _, _} import ExternalCompile.scalaJSExternalCompileSettings import Loggers._ -import org.scalajs.io.{FileVirtualJSFile, MemVirtualJSFile} +import org.scalajs.io.{FileVirtualBinaryFile, MemVirtualBinaryFile} import org.scalajs.io.JSUtils.escapeJS import org.scalajs.linker._ import org.scalajs.linker.irio._ @@ -86,7 +86,7 @@ object MyScalaJSPlugin extends AutoPlugin { "__ScalaJSEnv.javaSystemProperties = {" + formattedProps.mkString(", ") + "};\n" } val javaSysPropsFile = - new MemVirtualJSFile("setJavaSystemProperties.js").withContent(code) + new MemVirtualBinaryFile("setJavaSystemProperties.js").withStringUTF8(code) javaSysPropsFile +: prev } @@ -1410,7 +1410,7 @@ object Build { """ val patchedSystemPropertiesFile = - new MemVirtualJSFile("setJavaSystemProperties.js").withContent(code) + new MemVirtualBinaryFile("setJavaSystemProperties.js").withStringUTF8(code) // Replace the normal `setJavaSystemProperties.js` file with the patch for (file <- previousFiles) yield { @@ -1460,7 +1460,7 @@ object Build { } val launcher = - new MemVirtualJSFile("test-suite-linker.js").withContent(code) + new MemVirtualBinaryFile("test-suite-linker.js").withStringUTF8(code) val config = RunConfig().withLogger(sbtLogger2ToolsLogger(s.log)) val input = Input.ScriptsToLoad(List(launcher)) @@ -1489,7 +1489,7 @@ object Build { def testSuiteJSExecutionFilesSetting: Setting[_] = { jsExecutionFiles := { val resourceDir = (resourceDirectory in Test).value - val f = FileVirtualJSFile(resourceDir / "NonNativeJSTypeTestNatives.js") + val f = FileVirtualBinaryFile(resourceDir / "NonNativeJSTypeTestNatives.js") f +: jsExecutionFiles.value } } diff --git a/project/NodeJSEnvForcePolyfills.scala b/project/NodeJSEnvForcePolyfills.scala index 7edf651cfb..18c6884232 100644 --- a/project/NodeJSEnvForcePolyfills.scala +++ b/project/NodeJSEnvForcePolyfills.scala @@ -28,8 +28,8 @@ final class NodeJSEnvForcePolyfills(config: NodeJSEnv.Config) extends JSEnv { /** File to force all our ES 2015 polyfills to be used, by deleting the * native functions. */ - private def forcePolyfills(): VirtualJSFile = { - val f = new MemVirtualJSFile("scalaJSEnvInfo.js").withContent( + private def forcePolyfills(): VirtualBinaryFile = { + val f = new MemVirtualBinaryFile("scalaJSEnvInfo.js").withStringUTF8( """ |delete Math.fround; |delete Math.imul; diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index c22b4f7cab..2103b3ec9e 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -128,7 +128,7 @@ lazy val multiTestJS = project.in(file("multiTest/js")). // Make FrameworkDetector resilient to other output - #1572 jsExecutionFiles in Test := { - val consoleWriter = FileVirtualJSFile( + val consoleWriter = FileVirtualBinaryFile( (resourceDirectory in Test).value / "consoleWriter.js") consoleWriter +: (jsExecutionFiles in Test).value }, diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index d3d1a62596..fc432d7326 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -140,7 +140,7 @@ object ScalaJSPlugin extends AutoPlugin { "Prints the content of a .sjsir file in human readable form.", CTask) - val jsExecutionFiles = TaskKey[Seq[VirtualJSFile]]( + val jsExecutionFiles = TaskKey[Seq[VirtualBinaryFile]]( "jsExecutionFiles", "All the JS files given to JS environments on `run`, `test`, etc.", BTask) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index f468e7b353..392ea2e8b7 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -274,7 +274,7 @@ private[sbtplugin] object ScalaJSPluginInternal { // Add the Scala.js linked file to the JS files (by default, the only one) jsExecutionFiles += - new FileVirtualJSFile(scalaJSLinkedFile.value.data), + new FileVirtualBinaryFile(scalaJSLinkedFile.value.data), scalaJSMainModuleInitializer := { mainClass.value.map { mainCl => diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala index c26bc75473..70209e11c1 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala @@ -53,18 +53,18 @@ object HTMLRunnerBuilder { f.toURI() } - private def loadJSFiles(jsFiles: Seq[VirtualJSFile]): Seq[URI] = { + private def loadJSFiles(jsFiles: Seq[VirtualBinaryFile]): Seq[URI] = { jsFiles.map { case file: FileVirtualFile => file.file.toURI case file => val f = tmpFile(file.path) - IO.copyTo(file, WritableFileVirtualTextFile(f)) + Files.copy(file.inputStream, f.toPath) f.toURI } } - def writeToFile(output: File, title: String, jsFiles: Seq[VirtualJSFile], + def writeToFile(output: File, title: String, jsFiles: Seq[VirtualBinaryFile], frameworkImplClassNames: List[List[String]], taskDefs: List[TaskDef]): Unit = { From fc9f20b1940be7835a98287bd7fe30091d10c4dd Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Tue, 24 Apr 2018 06:46:08 +0200 Subject: [PATCH 0741/2665] Simplify file materialization in HTMLRunnerBuilder --- .../testadapter/HTMLRunnerBuilder.scala | 54 ++++++++----------- 1 file changed, 21 insertions(+), 33 deletions(-) diff --git a/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala b/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala index 70209e11c1..04499c1634 100644 --- a/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala +++ b/test-adapter/src/main/scala/org/scalajs/testadapter/HTMLRunnerBuilder.scala @@ -28,39 +28,20 @@ object HTMLRunnerBuilder { private val tmpSuffixRE = """[a-zA-Z0-9-_.]*$""".r - private def tmpFile(path: String): File = { - /* - createTempFile requires a prefix of at least 3 chars - * - we use a safe part of the path as suffix so the extension stays (some - * browsers need that) and there is a clue which file it came from. - */ - val suffix = tmpSuffixRE.findFirstIn(path).orNull - - val f = File.createTempFile("tmp-", suffix) - f.deleteOnExit() - f - } - - private def loadCSSURI(): URI = { - val name = "test-runner.css" - val f = tmpFile(name) - - val s = getClass.getResourceAsStream(name) + private def tmpFile(path: String, in: InputStream): URI = { try { - Files.copy(s, f.toPath(), StandardCopyOption.REPLACE_EXISTING) + /* - createTempFile requires a prefix of at least 3 chars + * - we use a safe part of the path as suffix so the extension stays (some + * browsers need that) and there is a clue which file it came from. + */ + val suffix = tmpSuffixRE.findFirstIn(path).orNull + + val f = File.createTempFile("tmp-", suffix) + f.deleteOnExit() + Files.copy(in, f.toPath(), StandardCopyOption.REPLACE_EXISTING) + f.toURI() } finally { - s.close() - } - f.toURI() - } - - private def loadJSFiles(jsFiles: Seq[VirtualBinaryFile]): Seq[URI] = { - jsFiles.map { - case file: FileVirtualFile => file.file.toURI - - case file => - val f = tmpFile(file.path) - Files.copy(file.inputStream, f.toPath) - f.toURI + in.close() } } @@ -68,8 +49,15 @@ object HTMLRunnerBuilder { frameworkImplClassNames: List[List[String]], taskDefs: List[TaskDef]): Unit = { - val jsFileURIs = loadJSFiles(jsFiles) - val cssURI = loadCSSURI() + val jsFileURIs = jsFiles.map { + case file: FileVirtualFile => file.file.toURI + case file => tmpFile(file.path, file.inputStream) + } + + val cssURI = { + val name = "test-runner.css" + tmpFile(name, getClass.getResourceAsStream(name)) + } val tests = new IsolatedTestSet(frameworkImplClassNames, taskDefs) From f5f9a515e869ac0a581e6bb5d70e51e95a7b50b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 16 May 2018 01:15:03 +0200 Subject: [PATCH 0742/2665] Towards 0.6.24. --- ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- project/BinaryIncompatibilities.scala | 5 ----- project/Build.scala | 2 +- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index e4ef4b6b77..756104816c 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.23" + val current: String = "0.6.24-SNAPSHOT" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 39d88dcc87..553c491612 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -8,11 +8,6 @@ object BinaryIncompatibilities { ) val Tools = Seq( - // private[linker], not an issue - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.StandardLinker#Config.outputMode"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "org.scalajs.core.tools.linker.StandardLinker#Config.withOutputMode") ) val JSEnvs = Seq( diff --git a/project/Build.scala b/project/Build.scala index cfe9b61e2d..fdcd78e610 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -57,7 +57,7 @@ object Build { val shouldPartest = settingKey[Boolean]( "Whether we should partest the current scala version (and fail if we can't)") - val previousVersion = "0.6.22" + val previousVersion = "0.6.23" val previousSJSBinaryVersion = ScalaJSCrossVersion.binaryScalaJSVersion(previousVersion) val previousBinaryCrossVersion = From dedf978f24e9cb0ff2af06b1874e802e56f3d4d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 21 May 2018 15:26:53 +0200 Subject: [PATCH 0743/2665] Fix #3351: Use Buffer.alloc and Buffer.from instead of new Buffer(). The latter was deprecated a long time ago, and has started printing noisy warnings to the console in Node.js v10. There is still one deprecation inside jszip, but there is nothing we can do about that one. --- .../jsenv/nodejs/AbstractNodeJSEnv.scala | 4 ++-- .../testsuite/jsinterop/ModulesTest.scala | 18 +++++++--------- .../ModulesWithGlobalFallbackTest.scala | 21 ++++++++++--------- 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala index ae6b0fdbf1..83a5b463dd 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala @@ -172,7 +172,7 @@ abstract class AbstractNodeJSEnv( | var recvCallback = null; | | // Buffers received data - | var inBuffer = new Buffer(0); + | var inBuffer = Buffer.alloc(0); | | function onData(data) { | inBuffer = Buffer.concat([inBuffer, data]); @@ -227,7 +227,7 @@ abstract class AbstractNodeJSEnv( | if (socket === null) throw new Error("Com not open"); | | var len = msg.length; - | var buf = new Buffer(4 + len * 2); + | var buf = Buffer.allocUnsafe(4 + len * 2); | buf.writeInt32BE(len, 0); | for (var i = 0; i < len; ++i) | buf.writeUInt16BE(msg.charCodeAt(i), 4 + i * 2); diff --git a/test-suite/js/src/test/require-modules/org/scalajs/testsuite/jsinterop/ModulesTest.scala b/test-suite/js/src/test/require-modules/org/scalajs/testsuite/jsinterop/ModulesTest.scala index fb94b0805f..5228edbcfc 100644 --- a/test-suite/js/src/test/require-modules/org/scalajs/testsuite/jsinterop/ModulesTest.scala +++ b/test-suite/js/src/test/require-modules/org/scalajs/testsuite/jsinterop/ModulesTest.scala @@ -62,7 +62,7 @@ class ModulesTest { } @Test def testImportClassInModule(): Unit = { - val b = new Buffer(5) + val b = Buffer.alloc(5) for (i <- 0 until 5) b(i) = (i * i).toShort @@ -71,8 +71,8 @@ class ModulesTest { } @Test def testImportIntegrated(): Unit = { - val b = new Buffer(js.Array[Short](0xe3, 0x81, 0x93, 0xe3, 0x82, 0x93, 0xe3, - 0x81, 0xab, 0xe3, 0x81, 0xa1, 0xe3, 0x81, 0xaf)) + val b = Buffer.from(js.Array[Short](0xe3, 0x81, 0x93, 0xe3, 0x82, 0x93, + 0xe3, 0x81, 0xab, 0xe3, 0x81, 0xa1, 0xe3, 0x81, 0xaf)) val decoder = new StringDecoder() assertTrue(Buffer.isBuffer(b)) assertFalse(Buffer.isBuffer(decoder)) @@ -105,19 +105,17 @@ object ModulesTest { def end(): String = js.native } - /* To stay compatible with Node.js 4.2.1, we describe and use deprecated - * APIs. - */ @js.native @JSImport("buffer", "Buffer") - class Buffer private[this] () extends js.typedarray.Uint8Array(0) { - def this(size: Int) = this() - def this(array: js.Array[Short]) = this() - } + class Buffer private[this] () extends js.typedarray.Uint8Array(0) + // This API requires Node.js >= v5.10.0 @js.native @JSImport("buffer", "Buffer") object Buffer extends js.Object { + def alloc(size: Int): Buffer = js.native + def from(array: js.Array[Short]): Buffer = js.native + def isBuffer(x: Any): Boolean = js.native } } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala index ea7f088f30..67904b3f13 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala @@ -64,7 +64,7 @@ class ModulesWithGlobalFallbackTest { } @Test def testImportClassInModule(): Unit = { - val b = new Buffer(5) + val b = Buffer.alloc(5) for (i <- 0 until 5) b(i) = (i * i).toShort @@ -73,8 +73,8 @@ class ModulesWithGlobalFallbackTest { } @Test def testImportIntegrated(): Unit = { - val b = new Buffer(js.Array[Short](0xe3, 0x81, 0x93, 0xe3, 0x82, 0x93, 0xe3, - 0x81, 0xab, 0xe3, 0x81, 0xa1, 0xe3, 0x81, 0xaf)) + val b = Buffer.from(js.Array[Short](0xe3, 0x81, 0x93, 0xe3, 0x82, 0x93, + 0xe3, 0x81, 0xab, 0xe3, 0x81, 0xa1, 0xe3, 0x81, 0xaf)) val decoder = new StringDecoder() assertTrue(Buffer.isBuffer(b)) assertFalse(Buffer.isBuffer(decoder)) @@ -139,6 +139,9 @@ object ModulesWithGlobalFallbackTest { } object BufferStaticFallbackImpl extends js.Object { + def alloc(size: Int): Any = new Uint8Array(size) + def from(array: js.Array[Short]): Any = new Uint8Array(array) + def isBuffer(x: Any): Boolean = x.isInstanceOf[Uint8Array] } @@ -184,21 +187,19 @@ object ModulesWithGlobalFallbackTest { def end(): String = js.native } - /* To stay compatible with Node.js 4.2.1, we describe and use deprecated - * APIs. - */ @js.native @JSImport("buffer", "Buffer", globalFallback = "ModulesWithGlobalFallbackTest_Buffer") - class Buffer private[this] () extends js.typedarray.Uint8Array(0) { - def this(size: Int) = this() - def this(array: js.Array[Short]) = this() - } + class Buffer private[this] () extends js.typedarray.Uint8Array(0) + // This API requires Node.js >= v5.10.0 @js.native @JSImport("buffer", "Buffer", globalFallback = "ModulesWithGlobalFallbackTest_BufferStatic") object Buffer extends js.Object { + def alloc(size: Int): Buffer = js.native + def from(array: js.Array[Short]): Buffer = js.native + def isBuffer(x: Any): Boolean = js.native } } From 2175de9e05da2a88cd3a0deb289f09adee7e76dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 22 May 2018 14:23:08 +0200 Subject: [PATCH 0744/2665] Fix #3348: Support hexadecimal notation in Double.parseDouble. Since Float.parseFloat delegates to Double.parseDouble, we trivially get that one for free. --- .../src/main/scala/java/lang/Double.scala | 151 ++++++++++- .../testsuite/javalib/lang/DoubleTest.scala | 256 ++++++++++++++++-- 2 files changed, 371 insertions(+), 36 deletions(-) diff --git a/javalanglib/src/main/scala/java/lang/Double.scala b/javalanglib/src/main/scala/java/lang/Double.scala index 31a444c66a..0a2c4fac5c 100644 --- a/javalanglib/src/main/scala/java/lang/Double.scala +++ b/javalanglib/src/main/scala/java/lang/Double.scala @@ -63,22 +63,149 @@ object Double { @inline def valueOf(s: String): Double = valueOf(parseDouble(s)) - private[this] lazy val doubleStrPat = new js.RegExp("^" + - "[\\x00-\\x20]*" + // optional whitespace - "[+-]?" + // optional sign - "(NaN|Infinity|" + // special cases - "(\\d+\\.?\\d*|" + // literal w/ leading digit - "\\.\\d+)" + // literal w/o leading digit - "([eE][+-]?\\d+)?"+ // optional exponent - ")[fFdD]?" + // optional float / double specifier (ignored) - "[\\x00-\\x20]*" + // optional whitespace + private[this] lazy val doubleStrPat = new js.RegExp( + "^" + + "[\\x00-\\x20]*(" + // optional whitespace + "[+-]?" + // optional sign + "(?:NaN|Infinity|" + // special cases + "(?:\\d+\\.?\\d*|" + // literal w/ leading digit + "\\.\\d+)" + // literal w/o leading digit + "(?:[eE][+-]?\\d+)?" + // optional exponent + ")[fFdD]?" + // optional float / double specifier (ignored) + ")[\\x00-\\x20]*" + // optional whitespace + "$") + + private[this] lazy val doubleStrHexPat = new js.RegExp( + "^" + + "[\\x00-\\x20]*" + // optional whitespace + "([+-]?)" + // optional sign + "0[xX]" + // hex marker + "([0-9A-Fa-f]*)" + // integral part + "\\.?([0-9A-Fa-f]*)" + // fractional part + "[pP]([+-]?\\d+)" + // binary exponent + "[fFdD]?" + // optional float / double specifier (ignored) + "[\\x00-\\x20]*" + // optional whitespace "$") def parseDouble(s: String): scala.Double = { - if (doubleStrPat.test(s)) - js.Dynamic.global.parseFloat(s).asInstanceOf[scala.Double] - else + def fail(): Nothing = throw new NumberFormatException(s"""For input string: "$s"""") + + // (Very) slow path for hexadecimal notation + def parseHexDoubleImpl(match2: js.RegExp.ExecResult): scala.Double = { + // scalastyle:off return + + val signStr = match2(1).asInstanceOf[String] + val integralPartStr = match2(2).asInstanceOf[String] + val fractionalPartStr = match2(3).asInstanceOf[String] + val binaryExpStr = match2(4).asInstanceOf[String] + + if (integralPartStr == "" && fractionalPartStr == "") + fail() + + /* We concatenate the integral part and fractional part together, then + * we parse the result as an integer. This means that we need to remember + * a correction to be applied to the final result, as a diff to the + * binary exponent + */ + val mantissaStr0 = integralPartStr + fractionalPartStr + val correction1 = -(fractionalPartStr.length * 4) // 1 hex == 4 bits + + /* Remove leading 0's in `mantissaStr`, because our algorithm assumes + * that there is none. + */ + var i = 0 + while (i != mantissaStr0.length && mantissaStr0.charAt(i) == '0') + i += 1 + val mantissaStr = mantissaStr0.substring(i) + + /* If the mantissa is empty, it means there were only 0's, and we + * short-cut to directly returning 0.0 or -0.0. This is important because + * the final step of the algorithm (multiplying by `correctingPow`) + * assumes that `mantissa` is non-zero in the case of overflow. + */ + if (mantissaStr == "") { + if (signStr == "-") + return -0.0 + else + return 0.0 + } + + /* If there are more than 15 characters left, we cut them out. They will + * never influence the result because of the limited precision of + * doubles. Note that the 15th character itself gets lost too, but can + * influence the *rounding* applied to the 14th character. + * + * We need to cut them out for corner cases where the full `mantissaStr` + * would parse as Infinity because it is too large, but where the binary + * exponent can "fix it" by being sufficiently under 0. + * + * Of course, we remember that we need to apply a correction to the + * exponent of the final result. + */ + val needsCorrection2 = mantissaStr.length > 15 + val truncatedMantissaStr = + if (needsCorrection2) mantissaStr.substring(0, 15) + else mantissaStr + val correction2 = + if (needsCorrection2) (mantissaStr.length - 15) * 4 // one hex == 4 bits + else 0 + + val fullCorrection = correction1 + correction2 + + /* Note that we do not care too much about overflows and underflows when + * manipulating binary exponents and corrections, because the corrections + * are directly related to the length of the input string, so they cannot + * be *that* big (or we have bigger problems), and the final result needs + * to fit in the [-1074, 1023] range, which can only happen if the + * `binaryExp` (see below) did not stray too far from that range itself. + */ + + val mantissa = + js.Dynamic.global.parseInt(truncatedMantissaStr, 16).asInstanceOf[scala.Double] + assert(mantissa != 0.0 && mantissa != scala.Double.PositiveInfinity) + + val binaryExpDouble = + js.Dynamic.global.parseInt(binaryExpStr, 10).asInstanceOf[scala.Double] + val binaryExp = binaryExpDouble.toInt // caps to [MinValue, MaxValue] + + val binExpAndCorrection = binaryExp + fullCorrection + + /* If `baseExponent` is the IEEE exponent of `mantissa`, then + * `binExpAndCorrection + baseExponent` must be in the valid range of + * IEEE exponents, which is [-1074, 1023]. Therefore, if + * `binExpAndCorrection` is out of twice that range, we will end up with + * an overflow or an underflow anyway. + * + * If it is inside twice that range, then we need to multiply `mantissa` + * by `Math.pow(2, binExpAndCorrection)`. However that `pow` could + * overflow or underflow itself, so we cut it in 3 parts. If that does + * not suffice for it not to overflow or underflow, it's because it + * wasn't in the safe range to begin with. + */ + val binExpAndCorrection_div_3 = binExpAndCorrection / 3 + val correctingPow = Math.pow(2, binExpAndCorrection_div_3) + val correctingPow3 = + Math.pow(2, binExpAndCorrection - 2*binExpAndCorrection_div_3) + + val r = ((mantissa * correctingPow) * correctingPow) * correctingPow3 + + if (signStr == "-") -r + else r + + // scalastyle:on return + } + + val match1 = doubleStrPat.exec(s) + if (match1 != null) { + js.Dynamic.global.parseFloat(match1(1)).asInstanceOf[scala.Double] + } else { + val match2 = doubleStrHexPat.exec(s) + if (match2 != null) + parseHexDoubleImpl(match2) + else + fail() + } } @inline def toString(d: scala.Double): String = diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/DoubleTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/DoubleTest.scala index ac79152660..b97dcc2ebf 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/DoubleTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/DoubleTest.scala @@ -9,13 +9,14 @@ package org.scalajs.testsuite.javalib.lang import org.junit.Test import org.junit.Assert._ +import org.junit.Assume._ import java.lang.{Double => JDouble} import scala.util.Try import org.scalajs.testsuite.utils.AssertThrows._ -import org.scalajs.testsuite.utils.Platform.executingInJVM +import org.scalajs.testsuite.utils.Platform.{executingInJVM, executingInPhantomJS} class DoubleTest { @@ -99,36 +100,243 @@ class DoubleTest { } @Test def should_parse_strings(): Unit = { - assertEquals(0.0, "0.0".toDouble, 0.0) - assertTrue("NaN".toDouble.isNaN) - assertTrue(Try("asdf".toDouble).isFailure) + // scalastyle:off line.size.limit + + /* First, a selection of large categories for which test the combination of + * - paddings + * - entry points to the API + * on a moderate set of test inputs. + */ + + for (padding <- List("", " ", (0 to 0x20).map(x => x.toChar).mkString)) { + def pad(s: String): String = padding + s + padding + + def testFull(s: String, v: Double): Unit = { + val s2 = pad(s) + val r1 = JDouble.parseDouble(s2) + assertTrue(s"""Double.parseDouble("$s2") must be $v, was $r1""", + r1.equals(v)) + val r2 = JDouble.valueOf(s2) + assertTrue(s"""Double.valueOf("$s2") must be $v, was $r2""", + r2.equals(v)) + val r3 = new JDouble(s2) + assertTrue(s"""new Double("$s2") must be $v, was $r3""", + r3.equals(v)) + } + + // Specials + testFull("NaN", Double.NaN) + testFull("Infinity", Double.PositiveInfinity) + testFull("-Infinity", Double.NegativeInfinity) + + // Decimal notation + testFull("0.0", 0.0) + testFull("-0.0", -0.0) + testFull("0", 0.0) + testFull("5.3", 5.3) + testFull("127e2", 12700.0) + testFull("127E-2", 1.27) + testFull("1E+1", 10) + testFull("-123.4", -123.4) + testFull("65432.1", 65432.10) + testFull("-87654.321", -87654.321) + testFull("+.3f", 0.3) + + // Hex notation, with exactly the output of toHexString() + testFull("0x0.0p0", 0.0) + testFull("-0x0.0p0", -0.0) + testFull("0x1.0p0", 1.0) + testFull("-0x1.0p0", -1.0) + testFull("0x1.0p1", 2.0) + testFull("0x1.8p1", 3.0) + testFull("0x1.0p-1", 0.5) + testFull("0x1.0p-2", 0.25) + testFull("0x1.00204p3", 8.003936767578125) + testFull("0x0.00204p-1022", 1.094949828138e-311) + testFull("0x1.fffffffffffffp1023", Double.MaxValue) + testFull("0x1.0p-1022", java.lang.Double.MIN_NORMAL) + testFull("0x0.fffffffffffffp-1022", 2.225073858507201E-308) + testFull("0x0.0000000000001p-1022", Double.MinPositiveValue) + } + + /* Then, a larger set of input strings, which we only test without padding + * and with only one entry point. + */ + + // Here, PhantomJS suffers from precision bugs, so we must discard it + assumeFalse("PhantomJS has precision bugs with Doubles", + executingInPhantomJS) def test(s: String, v: Double): Unit = { - assertEquals(v, JDouble.parseDouble(s), 0.01) - assertEquals(v, JDouble.valueOf(s).doubleValue(), 0.01) - assertEquals(v, new JDouble(s).doubleValue(), 0.01) + val r = JDouble.parseDouble(s) + assertTrue(s"""Double.parseDouble("$s") must be $v, was $r""", + r.equals(v)) } - test("0", 0.0) - test("5.3", 5.3) - test("127e2", 12700.0) - test("127E-2", 1.27) - test("1E+1", 10) - test("-123.4", -123.4) - test("65432.1", 65432.10) - test("-87654.321", -87654.321) - test("+.3f", 0.3) + /* Generated with: + * + * import scala.util.Random + * def randDecDigit(): Char = (Random.nextInt(10) + '0').toChar + * def randHexDigit(): Char = { + * val x = Random.nextInt(16) + * if (x < 10) (x + '0').toChar else (x - 10 + 'a').toChar + * } + * def timesRand(min: Int, max: Int, f: () => Char): String = { + * val count = Random.nextInt(max - min + 1) + min + * Array.fill(count)(f()).mkString + * } + * def randInput(): String = { + * "0x" + timesRand(0, 50, randHexDigit) + "." + + * timesRand(0, 50, randHexDigit) + "p" + + * (if (Random.nextBoolean()) "-" else "") + + * timesRand(1, 4, randDecDigit) + * } + * for (_ <- 0 until 100) { + * val input = randInput() + * println(s""" test("$input", ${java.lang.Double.parseDouble(input)})""") + * } + */ + + test("0x3bcc9c4f57.f9a4f7c38944030572c19c235c9c7fa195p4351", Double.PositiveInfinity) + test("0x5a5e28727048d5fc7a412e24b8d43eb896e97aa35cd3.63511582434bd029b800daf1a050abb7de2p882", Double.PositiveInfinity) + test("0x29087f7ee0bd6aad502b60de6dfd8793.43f94d82f523d1752400e968cap1", 1.090849442407432E38) + test("0x.c22e399bp45", 2.6687973842944E13) + test("0x79b19c420.p-714", 3.790455421249137E-205) + test("0xb0ce07bedeccdee4ea23651efe67375c.dfee4d87p510", 7.877552996709097E191) + test("0xc1bde6a227c610729.18838356d2d80db2bf863b3f8b861faf4p5", 7.147810818070931E21) + test("0x0b87187c64b5b3716.581fc68p3", 1.063244260886767E20) + test("0x18d9a8b51232ac492f546528d14e47cc17d6a5010f2559a474.c27bfadc62e1fe00e23cdeep-74", 8.257905526970714E36) + test("0x020151c74df677121e69301eeb602.76p-9618", 0.0) + test("0xe536c72c7c.993a58b4ca9e979c9p680", 4.938533550967572E216) + test("0xcfd63cf55ba4baae14e00.e25e0e6ad14d0079590d8f3d4a23757ae2dp-41", 7.141220395741147E12) + test("0xcd2bf6a48f5b9a419e911332e103fe2bd75.34774cfd3db6065c14652acc6d45e23228bccd8801p-8451", 0.0) + test("0x58abe6d66a0086f85cbe.7d4p0994", Double.PositiveInfinity) + test("0x007c6c67312cdb3c3303800836c80b62943e836.7b74087bffp-3255", 0.0) + test("0x62263ea3ba241e0bdce84d7d6936861c81.00927d354639e8360ee01edp2", 1.3359403146110964E41) + test("0x49002fa5938.b54da0c70b9e77ef171e402d359ec72cp39", 2.7578894924960133E24) + test("0xdd88d292163fbcf8a089b097f7275b7e5b42303c7c43.2a406a51865909e0a3070b07389b0d0690p-42", 1.8846067860572248E40) + test("0x833163291091d66a87d44b296ba97f8977a32a9a5eda831bae.10796333823419a154ee0d55p7", 1.0540944659455885E62) + test("0x6a7302a49cc8a6773b9dcb87f54179.15eee40f51c953beffc3cdf4e0e412ab793b67f7p-1", 2.7635807675525916E35) + test("0xdf8b942d99aa42a96e9748b9fe5cea8e1.0b9ecaaf5985dd3984b79b38265d7b7e2a7ee7f6ed57b81p-4", 2.9714257773281826E38) + test("0xad82fedb784e34be1b5bf0dc5cca18bdbba36311c1c6636e.fbd56a6f30cf3c943e89ecp8322", Double.PositiveInfinity) + test("0x6328d473cc9bf5bae48aa4e37e3e2660865cdf8d.a9c05efad8b3ddf34134efce48921ffc19b31f4f2bee3p-428", 8.166867110480941E-82) + test("0x3af268e735192f7a3733.90798aa580d3d6504053df967e554760938ea85823eadp9", 1.425248906962734E26) + test("0xa2368682d42e4408e1.7706c0e74aeaba33a0baff87e22e3acd191211e2f9f59p-4738", 0.0) + test("0x783e5869aea0daffecb432b6de1bc40226c3568fd2edc5139.7341a4d9d452e7c8345b023477e6d05919f7689bba1e9a7p-6", 7.370907344617178E56) + test("0xfe5bb4c989c1a259aeda07111f.6cd2be7ef12p60", 2.3234060358298473E49) + test("0xdd33a181f84bf67207cb05998997d54fd1.p06", 4.817346068045414E42) + test("0x77a7f7e2a8.4d3de3b5f195p39", 2.8253003987295953E23) + test("0x5de55cbb5787d.3d66f01p-14", 1.0082000456588264E11) + test("0x67a4b03a69d77f5f66395c.2p8187", Double.PositiveInfinity) + test("0xf28d5c5.42643b02820bf9333e33e60f66p715", 4.3838129311043347E223) + test("0xc30a63276908dbe614c73950569ab952722814fd5d2d.afp-9102", 0.0) + test("0xdc2de1a4e4d938f2652a5262b3b6361937c533.bc81d6feab43adb2dd65c97c466d5d2ef6d263595p231", 1.6944342110198636E115) + test("0x6755.4f9bee8bp95", 1.0479236104077999E33) + test("0xc3be28219dcc00557aaaae8c056e7416f0ed13db4.9e9cb950p-790", 2.745797751832513E-189) + test("0xa39f4cc8c01885613c9c.cfedda7b9278e19a96834742f4bp-6188", 0.0) + test("0x2488f0a650e.38dbf866364d34bfcaf93dd954e9p-03", 3.138325904977778E11) + test("0x19d580936.17db26207be41de75a4d508cfbp3", 5.54780778727455E10) + test("0xcc860b8f.258d4dfc274ee61cf0ae5p6757", Double.PositiveInfinity) + test("0xab.fp64", 3.171687059173436E21) + test("0x412d914b7c98153161f4a600e4da152a.57b5e3d6e2847e670f9ac808c1ef90fee196356p-20", 8.262292863342124E31) + test("0x0112e744ac19b8a158c4712d39f5ae9ff254f9dab9082.67b1e05b429ec492fc873p2628", Double.PositiveInfinity) + test("0x4124a6dc2f89206034099fcad671552f78e6.21351c7e6e8582c60285ap8", 1.452741259747921E45) + test("0x6f6945546e2800a514fc.faabf4c000f4a6fcd089cb925da85a4cc91fcf3e2d6fd81287p7", 6.734394668355518E25) + test("0x36a895940260d6055175338e411db0c.5c5fa36p5", 1.4530730290030868E38) + test("0x322be50cbd1f8130319a61db6d004164f288673bc13c0305.3a77e1de3e9ab9870e8810838fc52a3a1fp-22", 2.9330270580017486E50) + test("0x664cc5afa7473f34fbbcf3.c172e182p-8", 4.830975785903766E23) + test("0xadc638d3d1300cc8f48b9.77ba213b7704311bf91913536df8cce03f9aa8f11e79cc3p-1", 6.565007613676269E24) + test("0xea09c946afe882d2e9ba28f9f3bb8f6.34af0p-6821", 0.0) + test("0xbf476a9c79896b2d0cddd0fdeb8d965e4c56c0348802611f5.6c53c3p-5", 2.3450733549226435E57) + test("0xc59f164c0ee8495143225ce5.268820f13cp3680", Double.PositiveInfinity) + test("0x6d1eaee6d1e5c0251f1885371.764d29da90690a9b78bc45edbp-441", 9.515580739963098E-104) + test("0x7d3419f95aefe95444d4c48.5bd1275ab00b3ac92e217da51542e089ca80c7634ap4224", Double.PositiveInfinity) + test("0x08d4a636.c721dbfbba482d510d1b7366p-053", 1.6448388293384176E-8) + test("0x36beea0aa7cc593a23f47ecd401b38fc5b9bd4ed2.6c14d1c991f72p7", 6.400881277193871E50) + test("0xbafc02016adba217f7d5e10fe938ca2a96bb4e26a38eb8b6.25p0", 4.584844284745914E57) + test("0xe0.76e5af7fb57213c8be7796434496p00", 224.46444222324266) + test("0x6b7334ad12263.90c9a635c2c8208b942fc1913199cp3", 1.5122246293590812E16) + test("0x3.e98c39dd610752033bab414c78p-450", 1.345654750738825E-135) + test("0xc2a17805e94ae.f6ef0a0ffe5703112872a5p-67", 2.3201791960838845E-5) + test("0xd4af.7b7a572f663p-08", 212.68547787312073) + test("0xef7007bab0a3eea.61e7119bd29653a81c31ef1e263d1b9p9", 5.521055574676869E20) + test("0xdbce4587c9c.b77b2c4d92daacd9e393dc98f6bp-0", 1.5104936017052717E13) + test("0xfbbc30cf74818.2fd1f12cc035c03dfca5830d50164cb79b868c87p8", 1.13371419166953267E18) + test("0x149bf7.787b98fd06ee25d8e270518ep-6", 21103.866728686717) + test("0xca2f5e9d6b2f7a391417fc49583eabe7ac309.54f03855fd29b1ef1a0p86", 2.180359130716814E70) + test("0xfbd176f0e5c8e17760821b27.03f0f39433p-10", 7.6107387348123395E25) + test("0xd4e9c94d3ddda786d3f154698d2360fffa8253c805cb.3e75dcf8a2cbb9bd556bbf81c223b3531b9098416f6p-9370", 0.0) + test("0x2b37a4d81db15847db688b5bd807f334de1a2f6d6b9bdc3.70204da9114c1c76c1p979", Double.PositiveInfinity) + test("0x746.8e9f4093d3d737b1b6670p-015", 0.05684073234547659) + test("0xe0afae54cbd689d3e1068.a5ce3ead8c8e9ca3d1c10365da3afeab99dc4f39p-74", 898.7450153341871) + test("0xa83d02b83427292.bd7da68df2p7068", Double.PositiveInfinity) + test("0x643bdb8b5900d5eeb064c89ad09e286.4762c36b028afc237dab44bad9819713ba5c41b0fp-95", 2.102055534184586E8) + test("0x1acf3001c46eb5908cc67d6c87d0192.bca7427dfdf814b6e4a63f54cd51aa3cffa14ad5p-978", 8.718256412074298E-259) + test("0x7657db92eaaa.92902feb89bc1a352e52b917c3b7cfe4dp5", 4.1638309782705465E15) + test("0x575c272512a00bd2f8d1a14f280d0987f7c53e12d21.f30p-9", 3.989898204914359E48) + test("0x30398ddf709b895ce4.1b0ca907d7a1a69061b8c6abcp-86", 1.149769331391146E-5) + test("0xc63f6429eb3f8491854.8060a9d4e97d13c1a0cd68312e82dca5605e2589ef8d720dfep-258", 1.2633067328500596E-55) + test("0x7b1a87c5c9508.d4196605914de3e310df9696ebf99c048929a3efe9e1e4de2p194", 5.437632369872385E73) + test("0xbed724343613.8746f2f7edf13abf35ea02ae381bfd433758f9d8015deee07p-2", 5.245780866189288E13) + test("0x753dde30cf11b0073.f95e0330b0353fd9219d602ccf6p-93", 1.364872693205332E-8) + test("0x0a005b9d1e9b0c8c461900ed564d93c8.5fp8072", Double.PositiveInfinity) + test("0x09fff743267.22ffa43ca933345fd786cd8196cf9e82fb7c49dd5599b5fdp104", 1.3937779918868934E43) + test("0x937255dff8ec78da95ac1d9.1d1e12373360ep19", 1.4952863996276116E33) + test("0xbed0f063058a8370898708f730dac9135a0a0.bd157546ef4701eda08dd55ca9612a94dcep7023", Double.PositiveInfinity) + test("0xa95f3cc152bbcf98.c78d78aec3p800", 8.138005097516387E259) + test("0x5189a6e80fff17ffd7a10bcf873ba90aa684545104.f8p-5905", 0.0) + test("0xd0c23d1d739.14af693c2da7f6272fbba85p3144", Double.PositiveInfinity) + test("0xb904b6c4f518c7.dc2e488212f140253073da2180b7e6b74d6336p-754", 5.495889783734122E-211) + test("0x99826bcb8bfd8a22e0765ee7fcefd57e3.798eefea2dbdadp-44", 1.8558154651252258E26) + test("0xdaa946f53a4e18b6d1b07190aca94ad13374d5134.631e65342f4d6bdc9p-4930", 0.0) + test("0xf15fbca5010a4249d98c5137f214d3d.458d525617f62001db6f2p68", 5.918472578157268E57) + test("0x052cdde16bb8e7a6265046639.a2f897e77aa1a5d03fa5dap-759", 8.451331130505346E-201) + test("0x770a211be78479bf8d942bad9f8fc6ace3.292c025df6b532f961ac48f99e92223p2122", Double.PositiveInfinity) + test("0x07a598b38eb427b3b5433d.ab5912c87465ac2c2a76585ea9dd9bfb38881e72ca0529fp-4", 5.777805031594976E23) + test("0x8698b81c9c16e5a8decab9b6d.b028dc31b3952b24068e3d34e7ca98eb83ccp82", 3.2229472965243904E54) + test("0x662c64a84437ed9cdf306b8a5ffba3ff030c814761ac.037c61e9ad5bec868efp-745", 2.0655247050064035E-172) + test("0xe882d86a9deee6.a63cf9e373467af776ec826bc3800p016", 4.2890730281470667E21) + test("0x3d220eb5a59840.0ebfa1ff6d6951bc9b8b679p-1359", 0.0) + + /* One test where parsing the mantissa on its own would produce + * overflow/underflow, but where the binary exponent "saves" it. + */ + test("0x123456789abcdef" + "0" * 242 + "p0", Double.PositiveInfinity) + test("0x123456789abcdef" + "0" * 242 + "p-1", 1.0226876500550064E308) + test("0x0." + "0" * 268 + "123456789abcdefp0", 0.0) + test("0x0." + "0" * 268 + "123456789abcdefp1", 4.9E-324) + + // Underflow preserves the sign of the 0 + test("-0x0." + "0" * 268 + "123456789abcdefp0", -0.0) + + /* Mantissa of 0 with overflowing/underflowing binary exponent. + * Note that Math.pow(2, 10000 / 3) is Infinity. + */ + test("0x0p10000", 0.0) + test("-0x0p10000", -0.0) + test("0x0p-10000", 0.0) + test("-0x0p-10000", -0.0) + + // scalastyle:on line.size.limit } @Test def should_reject_invalid_strings_when_parsing(): Unit = { - def test(s: String): Unit = - expectThrows(classOf[NumberFormatException], JDouble.parseDouble(s)) - - test("4.3.5") - test("4e3.5") - test("hello world") - test("--4") - test("4E-3.2") + for (padding <- List("", " ", (0 to 0x20).map(x => x.toChar).mkString)) { + def pad(s: String): String = padding + s + padding + + def test(s: String): Unit = + expectThrows(classOf[NumberFormatException], JDouble.parseDouble(pad(s))) + + test("asdf") + test("4.3.5") + test("4e3.5") + test("hello world") + test("--4") + test("4E-3.2") + test("1af") // hex digits without 0x + test("0x.p1") // hex notation with both integral and fractional parts empty + test("0x1.2") // missing 'p' + } } @Test def compareTo(): Unit = { From 7faa32dbfc3589462ada40cdc22a363746736782 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 15 Apr 2018 08:07:28 +0200 Subject: [PATCH 0745/2665] Introduce org.scalajs.linker.LinkerOutput --- .../org/scalajs/io/NodeVirtualFiles.scala | 82 +++++++++++++------ .../main/scala/org/scalajs/io/MemFiles.scala | 15 ++++ .../closure/ClosureLinkerBackend.scala | 40 +++++---- .../org/scalajs/linker/ClearableLinker.scala | 2 +- .../scala/org/scalajs/linker/Linker.scala | 4 +- .../org/scalajs/linker/LinkerOutput.scala | 63 ++++++++++++++ .../linker/backend/BasicLinkerBackend.scala | 14 ++-- .../linker/backend/LinkerBackendImpl.scala | 6 +- .../backend/javascript/JSBuilders.scala | 28 +++++-- .../backend/javascript/SourceMapWriter.scala | 10 ++- .../linker/standard/LinkerBackend.scala | 7 +- .../linker/standard/StandardLinkerImpl.scala | 2 +- .../scala/org/scalajs/linker/LinkerTest.scala | 8 +- .../scala/tools/nsc/MainGenericRunner.scala | 8 +- sbt-plugin-test/build.sbt | 5 +- .../sbtplugin/ScalaJSPluginInternal.scala | 15 ++-- .../scalajs/bootstrap/TestSuiteLinker.scala | 21 ++++- 17 files changed, 241 insertions(+), 89 deletions(-) create mode 100644 linker/shared/src/main/scala/org/scalajs/linker/LinkerOutput.scala diff --git a/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala b/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala index e69a9a2fd5..d6a0c278ff 100644 --- a/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala +++ b/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala @@ -1,5 +1,7 @@ package org.scalajs.io +import scala.annotation.tailrec + import scala.scalajs.js import scala.scalajs.js.annotation.JSImport import scala.scalajs.js.typedarray._ @@ -17,16 +19,6 @@ class NodeVirtualTextFile(p: String) extends NodeVirtualFile(p) override def content: String = NodeFS.readFileSync(path, NodeSupport.utf8enc) } -trait WritableNodeVirtualTextFile extends NodeVirtualTextFile - with WritableVirtualTextFile { - def contentWriter: Writer = new NodeWriter(path) -} - -object WritableNodeVirtualTextFile { - def apply(path: String): WritableNodeVirtualTextFile = - new NodeVirtualTextFile(path) with WritableNodeVirtualTextFile -} - class NodeVirtualBinaryFile(p: String) extends NodeVirtualFile(p) with VirtualBinaryFile { private def buf: ArrayBuffer = @@ -36,6 +28,16 @@ class NodeVirtualBinaryFile(p: String) extends NodeVirtualFile(p) override def inputStream: InputStream = new ArrayBufferInputStream(buf) } +trait WritableNodeVirtualBinaryFile extends NodeVirtualBinaryFile + with WritableVirtualBinaryFile { + def outputStream: OutputStream = new NodeOutputStream(path) +} + +object WritableNodeVirtualBinaryFile { + def apply(path: String): WritableNodeVirtualBinaryFile = + new NodeVirtualBinaryFile(path) with WritableNodeVirtualBinaryFile +} + class NodeVirtualJSFile(p: String) extends NodeVirtualTextFile(p) with VirtualJSFile { @@ -43,17 +45,6 @@ class NodeVirtualJSFile(p: String) extends NodeVirtualTextFile(p) override def sourceMap: Option[String] = None } -trait WritableNodeVirtualJSFile extends NodeVirtualJSFile - with WritableVirtualJSFile - with WritableNodeVirtualTextFile { - def sourceMapWriter: Writer = new NodeWriter(path + ".map") -} - -object WritableNodeVirtualJSFile { - def apply(path: String): WritableNodeVirtualJSFile = - new NodeVirtualJSFile(path) with WritableNodeVirtualJSFile -} - private[io] object NodeSupport { val utf8enc: NodeFS.Enc = new NodeFS.Enc { val encoding = "UTF-8" } } @@ -72,12 +63,53 @@ private[scalajs] object NodeFS extends js.Object { def readFileSync(path: String): js.Array[Int] = js.native def readFileSync(path: String, enc: Enc): String = js.native def statSync(path: String): Stat = js.native - def writeFileSync(path: String, data: String, enc: Enc): Unit = js.native + + def openSync(path: String, flags: String): Int = js.native + def writeSync(fd: Int, buffer: Uint8Array): Int = js.native + def closeSync(fd: Int): Unit = js.native } -private[io] class NodeWriter(path: String) extends StringWriter { +private[io] final class NodeOutputStream(path: String) extends OutputStream { + private[this] val bufsize = 4096 + private[this] val fd = NodeFS.openSync(path, "w") + private[this] val arrBuf = new ArrayBuffer(bufsize) + private[this] val buf = TypedArrayBuffer.wrap(arrBuf) + + @tailrec + override def write(b: Array[Byte], off: Int, len: Int): Unit = { + ensureSpace() + + val ilen = Math.min(len, buf.remaining()) + buf.put(b, off, ilen) + + if (len > ilen) + write(b, off + ilen, ilen - len) + } + + def write(b: Int): Unit = { + ensureSpace() + buf.put(b.toByte) + } + + override def flush(): Unit = performWrite(0) + + private def ensureSpace(): Unit = { + if (!buf.hasRemaining()) + performWrite(bufsize / 4) + } + + private def performWrite(limit: Int): Unit = { + buf.flip() + while (buf.remaining() > limit) { + val pos = buf.position() + val written = NodeFS.writeSync(fd, new Uint8Array(arrBuf, pos, buf.limit() - pos)) + buf.position(pos + written) + } + buf.compact() + } + override def close(): Unit = { - super.close() - NodeFS.writeFileSync(path, this.toString, NodeSupport.utf8enc) + flush() + NodeFS.closeSync(fd) } } diff --git a/io/shared/src/main/scala/org/scalajs/io/MemFiles.scala b/io/shared/src/main/scala/org/scalajs/io/MemFiles.scala index 0c90ba8bec..a986d1480e 100644 --- a/io/shared/src/main/scala/org/scalajs/io/MemFiles.scala +++ b/io/shared/src/main/scala/org/scalajs/io/MemFiles.scala @@ -72,6 +72,21 @@ class MemVirtualBinaryFile(p: String) extends MemVirtualFile(p) withContent(v.getBytes(StandardCharsets.UTF_8)) } +trait WritableMemVirtualBinaryFile extends MemVirtualBinaryFile + with WritableVirtualBinaryFile { + def outputStream: OutputStream = new ByteArrayOutputStream { + override def close(): Unit = { + super.close() + WritableMemVirtualBinaryFile.this.content = this.toByteArray + } + } +} + +object WritableMemVirtualBinaryFile { + def apply(path: String): WritableMemVirtualBinaryFile = + new MemVirtualBinaryFile(path) with WritableMemVirtualBinaryFile +} + /** A simple in-memory mutable virtual JS file. */ class MemVirtualJSFile(p: String) extends MemVirtualTextFile(p) with VirtualJSFile { diff --git a/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala index 661cc2be76..266a9c937b 100644 --- a/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala @@ -11,6 +11,10 @@ package org.scalajs.linker.backend.closure import scala.collection.JavaConverters._ +import java.io._ +import java.net.URI +import java.nio.charset.StandardCharsets + import com.google.javascript.jscomp.{ SourceFile => ClosureSource, Compiler => ClosureCompiler, @@ -61,8 +65,7 @@ final class ClosureLinkerBackend(config: LinkerBackendImpl.Config) * @param unit [[standard.LinkingUnit LinkingUnit]] to emit * @param output File to write to */ - def emit(unit: LinkingUnit, output: WritableVirtualJSFile, - logger: Logger): Unit = { + def emit(unit: LinkingUnit, output: LinkerOutput, logger: Logger): Unit = { verifyUnit(unit) // Build Closure IR @@ -76,7 +79,7 @@ final class ClosureLinkerBackend(config: LinkerBackendImpl.Config) val closureExterns = List( ClosureSource.fromCode("ScalaJSExterns.js", ClosureLinkerBackend.ScalaJSExterns), ClosureSource.fromCode("ScalaJSExportExterns.js", makeExternsForExports(unit))) - val options = closureOptions(output.name) + val options = closureOptions(output) val compiler = closureCompiler(logger) val result = logger.time("Closure: Compiler pass") { @@ -126,7 +129,7 @@ final class ClosureLinkerBackend(config: LinkerBackendImpl.Config) } private def writeResult(result: Result, compiler: ClosureCompiler, - output: WritableVirtualJSFile): Unit = { + output: LinkerOutput): Unit = { def ifIIFE(str: String): String = if (needsIIFEWrapper) str else "" @@ -139,35 +142,44 @@ final class ClosureLinkerBackend(config: LinkerBackendImpl.Config) val sourceMap = Option(compiler.getSourceMap()) + def writer(out: OutputStream) = + new OutputStreamWriter(out, StandardCharsets.UTF_8) + // Write optimized code - val w = output.contentWriter + val w = writer(output.jsFile.outputStream) try { w.write(header) w.write(outputContent) w.write(footer) - if (sourceMap.isDefined) - w.write("//# sourceMappingURL=" + output.name + ".map\n") - } finally w.close() + output.sourceMapURI.foreach(uri => + w.write("//# sourceMappingURL=" + uri.toASCIIString + "\n")) + } finally { + w.close() + } // Write source map (if available) - sourceMap.foreach { sm => + for { + sm <- sourceMap + smf <- output.sourceMap + } yield { sm.setWrapperPrefix(header) - val w = output.sourceMapWriter - try sm.appendTo(w, output.name) + val w = writer(smf.outputStream) + try sm.appendTo(w, output.jsFileURI.fold("")(_.toASCIIString)) finally w.close() } } - private def closureOptions(outputName: String) = { + private def closureOptions(output: LinkerOutput) = { val options = new ClosureOptions options.prettyPrint = config.prettyPrint CompilationLevel.ADVANCED_OPTIMIZATIONS.setOptionsForCompilationLevel(options) options.setLanguageIn(ClosureOptions.LanguageMode.ECMASCRIPT5) options.setCheckGlobalThisLevel(CheckLevel.OFF) - if (config.sourceMap) { - options.setSourceMapOutputPath(outputName + ".map") + if (config.sourceMap && output.sourceMap.isDefined) { options.setSourceMapDetailLevel(SourceMap.DetailLevel.ALL) + output.sourceMapURI.foreach(uri => + options.setSourceMapOutputPath(uri.toASCIIString)) } options diff --git a/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala b/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala index 2d3884b728..763ada904d 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/ClearableLinker.scala @@ -60,7 +60,7 @@ object ClearableLinker { def link(irFiles: Seq[VirtualScalaJSIRFile], moduleInitializers: Seq[ModuleInitializer], - output: WritableVirtualJSFile, logger: Logger): Unit = { + output: LinkerOutput, logger: Logger): Unit = { linkerOp(_.link(irFiles, moduleInitializers, output, logger)) } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/Linker.scala b/linker/shared/src/main/scala/org/scalajs/linker/Linker.scala index 920d900aa6..02a42b1bc9 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/Linker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/Linker.scala @@ -10,8 +10,6 @@ package org.scalajs.linker import org.scalajs.logging.Logger -import org.scalajs.io._ - import org.scalajs.linker.irio._ /** A Scala.js linker, with its most abstract API. @@ -23,5 +21,5 @@ import org.scalajs.linker.irio._ abstract class Linker private[linker] () { def link(irFiles: Seq[VirtualScalaJSIRFile], moduleInitializers: Seq[ModuleInitializer], - output: WritableVirtualJSFile, logger: Logger): Unit + output: LinkerOutput, logger: Logger): Unit } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/LinkerOutput.scala b/linker/shared/src/main/scala/org/scalajs/linker/LinkerOutput.scala new file mode 100644 index 0000000000..93c539f3a1 --- /dev/null +++ b/linker/shared/src/main/scala/org/scalajs/linker/LinkerOutput.scala @@ -0,0 +1,63 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js linker ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2018, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package org.scalajs.linker + +import org.scalajs.io.WritableVirtualBinaryFile + +import java.net.URI + +/** Output specification for a linker run. + * + * @param jsFile The JavaScript file a [[Linker]] writes to. + * + * @param sourceMap The sourceMap file the linker writes to. A [[Linker]] may + * ignore this file. N.b. the [[StandardLinker]] will ignore it if + * [[StandardLinker.Config.sourceMap]] is false. Further, a [[Linker]] must + * not fail if this is not set, but rather not write a source map (even if + * it is configured to write a source map). + * + * @param sourceMapURI URI to reach the source map from the JavaScript file. + * This is typically a relative URI but is not required. A [[Linker]] + * should ignore this, if [[sourceMap]] is not set or source map production + * is disabled. + * + * @param jsFileURI URI to reach the JavaScript file from the source map. This + * is typically a relative URI but is not required. A [[Linker]] may use + * this even if [[sourceMap]] is not set, but it is typically meaningless. + */ +final class LinkerOutput private ( + val jsFile: WritableVirtualBinaryFile, + val sourceMap: Option[WritableVirtualBinaryFile], + val sourceMapURI: Option[URI], + val jsFileURI: Option[URI] +) { + private def this(jsFile: WritableVirtualBinaryFile) = + this(jsFile, None, None, None) + + def withSourceMap(sourceMap: WritableVirtualBinaryFile): LinkerOutput = + copy(sourceMap = Some(sourceMap)) + + def withSourceMapURI(sourceMapURI: URI): LinkerOutput = + copy(sourceMapURI = Some(sourceMapURI)) + + def withJSFileURI(jsFileURI: URI): LinkerOutput = + copy(jsFileURI = Some(jsFileURI)) + + private def copy(jsFile: WritableVirtualBinaryFile = jsFile, + sourceMap: Option[WritableVirtualBinaryFile] = sourceMap, + sourceMapURI: Option[URI] = sourceMapURI, + jsFileURI: Option[URI] = jsFileURI): LinkerOutput = { + new LinkerOutput(jsFile, sourceMap, sourceMapURI, jsFileURI) + } +} + +object LinkerOutput { + def apply(jsFile: WritableVirtualBinaryFile): LinkerOutput = new LinkerOutput(jsFile) +} diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/BasicLinkerBackend.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/BasicLinkerBackend.scala index 50c2886870..94a5cd74e7 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/BasicLinkerBackend.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/BasicLinkerBackend.scala @@ -10,8 +10,8 @@ package org.scalajs.linker.backend import org.scalajs.logging.Logger -import org.scalajs.io.WritableVirtualJSFile +import org.scalajs.linker.LinkerOutput import org.scalajs.linker.standard._ import org.scalajs.linker.backend.emitter.Emitter @@ -33,8 +33,7 @@ final class BasicLinkerBackend(config: LinkerBackendImpl.Config) * @param unit [[standard.LinkingUnit LinkingUnit]] to emit * @param output File to write to */ - def emit(unit: LinkingUnit, output: WritableVirtualJSFile, - logger: Logger): Unit = { + def emit(unit: LinkingUnit, output: LinkerOutput, logger: Logger): Unit = { verifyUnit(unit) val builder = newBuilder(output) @@ -47,12 +46,11 @@ final class BasicLinkerBackend(config: LinkerBackendImpl.Config) } } - private def newBuilder(output: WritableVirtualJSFile): JSLineBuilder = { - if (config.sourceMap) { - new JSFileBuilderWithSourceMap(output.name, output.contentWriter, - output.sourceMapWriter, config.relativizeSourceMapBase) + private def newBuilder(output: LinkerOutput): JSLineBuilder = { + if (config.sourceMap && output.sourceMap.isDefined) { + new JSFileBuilderWithSourceMap(output, config.relativizeSourceMapBase) } else { - new JSFileBuilder(output.name, output.contentWriter) + new JSFileBuilder(output) } } } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/LinkerBackendImpl.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/LinkerBackendImpl.scala index 98aab1d9b2..a7c2d27952 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/LinkerBackendImpl.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/LinkerBackendImpl.scala @@ -13,14 +13,14 @@ import scala.language.implicitConversions import java.net.URI -import org.scalajs.io.WritableVirtualJSFile import org.scalajs.logging.Logger import org.scalajs.linker._ import org.scalajs.linker.standard._ -/** A backend of the Scala.js linker. Produces a - * [[org.scalajs.io.VirtualJSFile VirtualJSFile]]. +/** A backend of the Scala.js linker. + * + * Produces a JavaScript file with an optional source map. * * You probably want to use an instance of [[linker.Linker]], rather than this * low-level class. diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/JSBuilders.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/JSBuilders.scala index 0f123bacc7..2e73b8ce28 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/JSBuilders.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/JSBuilders.scala @@ -11,8 +11,11 @@ package org.scalajs.linker.backend.javascript import org.scalajs.ir.Position +import org.scalajs.linker.LinkerOutput + import java.io._ import java.net.URI +import java.nio.charset.StandardCharsets /** An abstract builder taking IR or JSTrees */ trait JSBuilder { @@ -33,7 +36,10 @@ trait JSLineBuilder extends JSBuilder { def addLine(line: String): Unit } -final class JSFileBuilder(name: String, outputWriter: Writer) extends JSLineBuilder { +final class JSFileBuilder(output: LinkerOutput) extends JSLineBuilder { + private val outputWriter = + new OutputStreamWriter(output.jsFile.outputStream, StandardCharsets.UTF_8) + def addLine(line: String): Unit = { outputWriter.write(line) outputWriter.write('\n') @@ -55,15 +61,21 @@ final class JSFileBuilder(name: String, outputWriter: Writer) extends JSLineBuil // Do not close the printer: we do not have ownership of the writers } - def complete(): Unit = - outputWriter.close() + def complete(): Unit = outputWriter.close() } -class JSFileBuilderWithSourceMap(name: String, outputWriter: Writer, - sourceMapOutputWriter: Writer, +class JSFileBuilderWithSourceMap(output: LinkerOutput, relativizeSourceMapBasePath: Option[URI]) extends JSLineBuilder { + require(output.sourceMap.isDefined) + + private def writer(out: OutputStream) = + new OutputStreamWriter(out, StandardCharsets.UTF_8) + + private val outputWriter = writer(output.jsFile.outputStream) + private val sourceMapWriter = new SourceMapWriter( - sourceMapOutputWriter, name, relativizeSourceMapBasePath) + writer(output.sourceMap.get.outputStream), output.jsFileURI, + relativizeSourceMapBasePath) def addLine(line: String): Unit = { outputWriter.write(line) @@ -95,9 +107,9 @@ class JSFileBuilderWithSourceMap(name: String, outputWriter: Writer, } def complete(): Unit = { - addLine("//# sourceMappingURL=" + name + ".map") + output.sourceMapURI.foreach(uri => + addLine("//# sourceMappingURL=" + uri.toASCIIString())) outputWriter.close() sourceMapWriter.complete() - sourceMapOutputWriter.close() } } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/SourceMapWriter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/SourceMapWriter.scala index e76f1f00a8..8649a621a6 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/SourceMapWriter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/SourceMapWriter.scala @@ -74,7 +74,7 @@ private object SourceMapWriter { private[javascript] class SourceMapWriter( val out: Writer, - val generatedFile: String, + val jsFileURI: Option[URI], val relativizeBaseURI: Option[URI] = None) { import SourceMapWriter._ @@ -137,8 +137,11 @@ private[javascript] class SourceMapWriter( } private def writeHeader(): Unit = { - out.write("{\n\"version\": 3,\n\"file\": ") - printJSONString(generatedFile, out) + out.write("{\n\"version\": 3") + jsFileURI.foreach { uri => + out.write(",\n\"file\": ") + printJSONString(uri.toASCIIString, out) + } out.write(",\n\"mappings\": \"") } @@ -267,6 +270,7 @@ private[javascript] class SourceMapWriter( out.write("],\n\"lineCount\": ") out.write(lineCountInGenerated.toString) out.write("\n}\n") + out.close() } /** Write the Base 64 VLQ of an integer to the mappings diff --git a/linker/shared/src/main/scala/org/scalajs/linker/standard/LinkerBackend.scala b/linker/shared/src/main/scala/org/scalajs/linker/standard/LinkerBackend.scala index abddb54711..02b5411e31 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/standard/LinkerBackend.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/standard/LinkerBackend.scala @@ -10,11 +10,11 @@ package org.scalajs.linker.standard import org.scalajs.logging._ -import org.scalajs.io._ +import org.scalajs.linker.LinkerOutput /** A backend of a standard Scala.js linker. * - * Produces a [[org.scalajs.io.VirtualJSFile VirtualJSFile]]. + * Produces a JavaScript file with an optional source map. * * You probably want to use an instance of [[Linker]], rather than this * low-level class. @@ -38,8 +38,7 @@ abstract class LinkerBackend { * @param output File to write to * @param logger Logger to use */ - def emit(unit: LinkingUnit, output: WritableVirtualJSFile, - logger: Logger): Unit + def emit(unit: LinkingUnit, output: LinkerOutput, logger: Logger): Unit /** Verify that a [[LinkingUnit]] can be processed by this [[LinkerBackend]]. * diff --git a/linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerImpl.scala b/linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerImpl.scala index 10ea8099f7..db2f560d6b 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerImpl.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/standard/StandardLinkerImpl.scala @@ -32,7 +32,7 @@ private final class StandardLinkerImpl private ( def link(irFiles: Seq[VirtualScalaJSIRFile], moduleInitializers: Seq[ModuleInitializer], - output: WritableVirtualJSFile, logger: Logger): Unit = { + output: LinkerOutput, logger: Logger): Unit = { guard { val unit = frontend.link(irFiles, moduleInitializers, backend.symbolRequirements, logger) diff --git a/linker/shared/src/test/scala/org/scalajs/linker/LinkerTest.scala b/linker/shared/src/test/scala/org/scalajs/linker/LinkerTest.scala index cfc1fb4ef9..e0fffc645a 100644 --- a/linker/shared/src/test/scala/org/scalajs/linker/LinkerTest.scala +++ b/linker/shared/src/test/scala/org/scalajs/linker/LinkerTest.scala @@ -58,8 +58,10 @@ class LinkerTest { val linker = StandardLinker(StandardLinker.Config()) - def callLink(): Unit = - linker.link(badSeq, Nil, WritableMemVirtualJSFile("some_file"), NullLogger) + def callLink(): Unit = { + val out = LinkerOutput(WritableMemVirtualBinaryFile("some_file")) + linker.link(badSeq, Nil, out, NullLogger) + } // Call first time. Get exception from badSeq. try { @@ -103,7 +105,7 @@ object LinkerTest { val allIRFiles = TestIRRepo.stdlibIRFiles ++ classDefsFiles - val output = WritableMemVirtualJSFile("output.js") + val output = LinkerOutput(WritableMemVirtualBinaryFile("output.js")) linker.link(allIRFiles, moduleInitializers, output, new ScalaConsoleLogger(Level.Error)) diff --git a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala index 2362fe84e0..206d7d6710 100644 --- a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala +++ b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala @@ -83,11 +83,9 @@ class MainGenericRunner { val linker = StandardLinker(linkerConfig) val sjsCode = { - val code = WritableMemVirtualJSFile("partest.js") - linker.link(ir, moduleInitializers, code, logger) - val output = new MemVirtualBinaryFile("partest.js") - .withStringUTF8(code.content) - output + val out = WritableMemVirtualBinaryFile("partest.js") + linker.link(ir, moduleInitializers, LinkerOutput(out), logger) + out } val input = Input.ScriptsToLoad(sjsCode :: Nil) diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index 2103b3ec9e..ad029b67f2 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -68,9 +68,8 @@ lazy val noDOM = project.settings(baseSettings: _*). Def.task { log.info("Fake full optimizing") val linker = (scalaJSLinker in fullOptJS).value - linker.link(ir, moduleInitializers, - WritableMemVirtualJSFile("fake-fastopt.js"), - sbtLogger2ToolsLogger(log)) + val output = LinkerOutput(WritableMemVirtualBinaryFile("fake-fastopt.js")) + linker.link(ir, moduleInitializers, output, sbtLogger2ToolsLogger(log)) }.tag((usesScalaJSLinkerTag in fullOptJS).value) }.value, diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 392ea2e8b7..e88fe14c94 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -160,6 +160,7 @@ private[sbtplugin] object ScalaJSPluginInternal { val output = (artifactPath in key).value val linker = (scalaJSLinker in key).value val usesLinkerTag = (usesScalaJSLinkerTag in key).value + val sourceMapFile = new File(output.getPath + ".map") Def.task { val log = s.log @@ -178,16 +179,20 @@ private[sbtplugin] object ScalaJSPluginInternal { IO.createDirectory(output.getParentFile) - linker.link(ir, moduleInitializers, - AtomicWritableFileVirtualJSFile(output), - sbtLogger2ToolsLogger(log)) + def relURI(path: String) = new URI(null, null, path, null) + + val out = LinkerOutput(AtomicWritableFileVirtualBinaryFile(output)) + .withSourceMap(AtomicWritableFileVirtualBinaryFile(sourceMapFile)) + .withSourceMapURI(relURI(sourceMapFile.getName)) + .withJSFileURI(relURI(output.getName)) + + linker.link(ir, moduleInitializers, out, sbtLogger2ToolsLogger(log)) logIRCacheStats(log) - Set(output) + Set(output, sourceMapFile) } (realFiles.toSet) - val sourceMapFile = FileVirtualJSFile(output).sourceMapFile Attributed.blank(output).put(scalaJSSourceMap, sourceMapFile) }.tag(usesLinkerTag) }.value diff --git a/test-suite-linker/src/main/scala/org/scalajs/bootstrap/TestSuiteLinker.scala b/test-suite-linker/src/main/scala/org/scalajs/bootstrap/TestSuiteLinker.scala index 382c5cc21d..652190d0d0 100644 --- a/test-suite-linker/src/main/scala/org/scalajs/bootstrap/TestSuiteLinker.scala +++ b/test-suite-linker/src/main/scala/org/scalajs/bootstrap/TestSuiteLinker.scala @@ -3,6 +3,8 @@ package org.scalajs.linker.test import scala.scalajs.js import scala.scalajs.js.annotation._ +import java.net.URI + import org.scalajs.io._ import org.scalajs.logging._ @@ -30,10 +32,17 @@ object QuickLinker { val ir = extractIR(irFilesAndJars) - val out = WritableNodeVirtualJSFile(outputPath) - linker.link(ir, moduleInitializers, out, new ScalaConsoleLogger) + val smPath = outputPath + ".map" + + def relURI(path: String) = + new URI(null, null, NodePath.basename(path), null) + + val out = LinkerOutput(WritableNodeVirtualBinaryFile(outputPath)) + .withSourceMap(WritableNodeVirtualBinaryFile(smPath)) + .withSourceMapURI(relURI(smPath)) + .withJSFileURI(relURI(outputPath)) - out.content + linker.link(ir, moduleInitializers, out, new ScalaConsoleLogger) } private def extractIR(irFilesAndJars: Seq[String]): Seq[VirtualScalaJSIRFile] = { @@ -52,4 +61,10 @@ object QuickLinker { cache.cached(irContainers) } + + @JSImport("path", JSImport.Namespace) + @js.native + private object NodePath extends js.Object { + def basename(str: String): String = js.native + } } From 5d418a682b5745b50903828ff302c236492e00ae Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 11 May 2018 21:25:31 +0200 Subject: [PATCH 0746/2665] Use Files.move in AtomicFileOutputStream --- .../scalajs/io/AtomicFileOutputStream.scala | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/io/jvm/src/main/scala/org/scalajs/io/AtomicFileOutputStream.scala b/io/jvm/src/main/scala/org/scalajs/io/AtomicFileOutputStream.scala index 8d7237857e..3c6e95eb7b 100644 --- a/io/jvm/src/main/scala/org/scalajs/io/AtomicFileOutputStream.scala +++ b/io/jvm/src/main/scala/org/scalajs/io/AtomicFileOutputStream.scala @@ -1,7 +1,9 @@ package org.scalajs.io +import scala.util.control.NonFatal + import java.io._ -import java.net.URI +import java.nio.file._ /** Provides best-effort atomic writing to a file * @@ -40,14 +42,23 @@ private[io] class AtomicFileOutputStream private ( /** Try to atomically replace the baseFile with the tmpFile */ private[this] def atomicReplace(): Unit = { - if (!tmpFile.renameTo(baseFile)) { - // Renaming failed. Fallback to copy - try { - IO.copyTo(FileVirtualBinaryFile(tmpFile), - WritableFileVirtualBinaryFile(baseFile)) - } finally { - tmpFile.delete() - } + try { + // Try atomic move. + Files.move(tmpFile.toPath, baseFile.toPath, StandardCopyOption.ATOMIC_MOVE) + } catch { + case NonFatal(_) => + /* We need to catch all exceptions, because it is platform dependent: + * - whether ATOMIC_MOVE overrides an existing file or not, + * - it throws a FileAlreadyExistsException in this case. + * + * If the atomic move fails, we fall back to a normal copy & delete. + */ + try { + Files.copy(tmpFile.toPath, baseFile.toPath, + StandardCopyOption.REPLACE_EXISTING) + } finally { + tmpFile.delete() + } } } } From 8b9005f8c165c03c89d4f5ac6b543dec87e04c9a Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Mon, 16 Apr 2018 06:58:26 +0200 Subject: [PATCH 0747/2665] Remove most of the VirtualFile API that is now unused. --- .../org/scalajs/io/NodeVirtualFiles.scala | 24 +--- .../io/AtomicWritableFileVirtualFiles.scala | 25 ---- .../org/scalajs/io/FileVirtualFiles.scala | 104 -------------- .../src/main/scala/org/scalajs/io/IO.scala | 129 ------------------ .../main/scala/org/scalajs/io/MemFiles.scala | 64 +-------- .../scala/org/scalajs/io/VirtualFiles.scala | 60 +------- .../org/scalajs/jsenv/test/RunTests.scala | 2 +- .../linker/irio/FileVirtualIRFiles.scala | 3 - .../org/scalajs/jsenv/nodejs/NodeJSEnv.scala | 21 ++- .../org/scalajs/sbtplugin/SBTCompat.scala | 4 +- .../org/scalajs/sbtplugin/SBTCompat.scala | 4 +- .../sbtplugin/ScalaJSPluginInternal.scala | 2 +- 12 files changed, 28 insertions(+), 414 deletions(-) delete mode 100644 io/shared/src/main/scala/org/scalajs/io/IO.scala diff --git a/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala b/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala index d6a0c278ff..300317f8b1 100644 --- a/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala +++ b/io/js/src/main/scala/org/scalajs/io/NodeVirtualFiles.scala @@ -14,18 +14,12 @@ class NodeVirtualFile(override val path: String) extends VirtualFile { NodeFS.statSync(path).mtime.map(_.getTime.toString).toOption } -class NodeVirtualTextFile(p: String) extends NodeVirtualFile(p) - with VirtualTextFile { - override def content: String = NodeFS.readFileSync(path, NodeSupport.utf8enc) -} - class NodeVirtualBinaryFile(p: String) extends NodeVirtualFile(p) with VirtualBinaryFile { private def buf: ArrayBuffer = new Uint8Array(NodeFS.readFileSync(path)).buffer - override def content: Array[Byte] = new Int8Array(buf).toArray - override def inputStream: InputStream = new ArrayBufferInputStream(buf) + def inputStream: InputStream = new ArrayBufferInputStream(buf) } trait WritableNodeVirtualBinaryFile extends NodeVirtualBinaryFile @@ -38,30 +32,14 @@ object WritableNodeVirtualBinaryFile { new NodeVirtualBinaryFile(path) with WritableNodeVirtualBinaryFile } -class NodeVirtualJSFile(p: String) extends NodeVirtualTextFile(p) - with VirtualJSFile { - - /** Always returns None. We can't read them on JS anyway */ - override def sourceMap: Option[String] = None -} - -private[io] object NodeSupport { - val utf8enc: NodeFS.Enc = new NodeFS.Enc { val encoding = "UTF-8" } -} - @JSImport("fs", JSImport.Namespace) @js.native private[scalajs] object NodeFS extends js.Object { - trait Enc extends js.Object { - val encoding: String - } - trait Stat extends js.Object { val mtime: js.UndefOr[js.Date] } def readFileSync(path: String): js.Array[Int] = js.native - def readFileSync(path: String, enc: Enc): String = js.native def statSync(path: String): Stat = js.native def openSync(path: String, flags: String): Int = js.native diff --git a/io/jvm/src/main/scala/org/scalajs/io/AtomicWritableFileVirtualFiles.scala b/io/jvm/src/main/scala/org/scalajs/io/AtomicWritableFileVirtualFiles.scala index 7b0c842f54..a568367755 100644 --- a/io/jvm/src/main/scala/org/scalajs/io/AtomicWritableFileVirtualFiles.scala +++ b/io/jvm/src/main/scala/org/scalajs/io/AtomicWritableFileVirtualFiles.scala @@ -3,18 +3,6 @@ package org.scalajs.io import java.io._ import java.net.URI -trait AtomicWritableFileVirtualTextFile extends WritableFileVirtualTextFile { - override def contentWriter: Writer = { - new BufferedWriter(new OutputStreamWriter( - new AtomicFileOutputStream(file), "UTF-8")) - } -} - -object AtomicWritableFileVirtualTextFile { - def apply(f: File): AtomicWritableFileVirtualTextFile = - new FileVirtualTextFile(f) with AtomicWritableFileVirtualTextFile -} - trait AtomicWritableFileVirtualBinaryFile extends WritableFileVirtualBinaryFile { override def outputStream: OutputStream = new BufferedOutputStream(new AtomicFileOutputStream(file)) @@ -24,16 +12,3 @@ object AtomicWritableFileVirtualBinaryFile { def apply(f: File): AtomicWritableFileVirtualBinaryFile = new FileVirtualBinaryFile(f) with AtomicWritableFileVirtualBinaryFile } - -trait AtomicWritableFileVirtualJSFile extends WritableFileVirtualJSFile - with AtomicWritableFileVirtualTextFile { - override def sourceMapWriter: Writer = { - new BufferedWriter(new OutputStreamWriter( - new AtomicFileOutputStream(sourceMapFile), "UTF-8")) - } -} - -object AtomicWritableFileVirtualJSFile { - def apply(f: File): AtomicWritableFileVirtualJSFile = - new FileVirtualJSFile(f) with AtomicWritableFileVirtualJSFile -} diff --git a/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala b/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala index fe33b8b753..64396e41b4 100644 --- a/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala +++ b/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala @@ -9,8 +9,6 @@ class FileVirtualFile(val file: File) extends VirtualFile { override def path: String = file.getPath - override def name: String = file.getName - override def version: Option[String] = { if (!file.isFile) None else Some(file.lastModified.toString) @@ -20,65 +18,6 @@ class FileVirtualFile(val file: File) extends VirtualFile { object FileVirtualFile extends (File => FileVirtualFile) { def apply(f: File): FileVirtualFile = new FileVirtualFile(f) - - /** Tests whether the given file has the specified extension. - * Extension contain the '.', so a typical value for `ext` would be ".js". - * The comparison is case-sensitive. - */ - def hasExtension(file: File, ext: String): Boolean = - file.getName.endsWith(ext) - - /** Returns a new file with the same parent as the given file but a different - * name. - */ - def withName(file: File, newName: String): File = - new File(file.getParentFile(), newName) - - /** Returns a new file with the same path as the given file but a different - * extension. - * Extension contain the '.', so a typical value for `ext` would be ".js". - * Precondition: hasExtension(file, oldExt) - */ - def withExtension(file: File, oldExt: String, newExt: String): File = { - require(hasExtension(file, oldExt), - s"File $file does not have extension '$oldExt'") - withName(file, file.getName.stripSuffix(oldExt) + newExt) - } -} - -/** A [[VirtualTextFile]] implemented by an actual file on the file system. */ -class FileVirtualTextFile(f: File) extends FileVirtualFile(f) - with VirtualTextFile { - import FileVirtualTextFile._ - - override def content: String = readFileToString(file) - override def reader: Reader = new InputStreamReader( - new BufferedInputStream(new FileInputStream(f)), "UTF-8") -} - -object FileVirtualTextFile extends (File => FileVirtualTextFile) { - def apply(f: File): FileVirtualTextFile = - new FileVirtualTextFile(f) - - /** Reads the entire content of a file as a UTF-8 string. */ - def readFileToString(file: File): String = { - val stream = new FileInputStream(file) - try IO.readInputStreamToString(stream) - finally stream.close() - } -} - -trait WritableFileVirtualTextFile extends FileVirtualTextFile - with WritableVirtualTextFile { - override def contentWriter: Writer = { - new BufferedWriter(new OutputStreamWriter( - new FileOutputStream(file), "UTF-8")) - } -} - -object WritableFileVirtualTextFile { - def apply(f: File): WritableFileVirtualTextFile = - new FileVirtualTextFile(f) with WritableFileVirtualTextFile } /** A [[VirtualBinaryFile]] implemented by an actual file on the file system. */ @@ -88,21 +27,11 @@ class FileVirtualBinaryFile(f: File) extends FileVirtualFile(f) override def inputStream: InputStream = new BufferedInputStream(new FileInputStream(file)) - - override def content: Array[Byte] = - readFileToByteArray(file) } object FileVirtualBinaryFile extends (File => FileVirtualBinaryFile) { def apply(f: File): FileVirtualBinaryFile = new FileVirtualBinaryFile(f) - - /** Reads the entire content of a file as byte array. */ - def readFileToByteArray(file: File): Array[Byte] = { - val stream = new FileInputStream(file) - try IO.readInputStreamToByteArray(stream) - finally stream.close() - } } trait WritableFileVirtualBinaryFile extends FileVirtualBinaryFile @@ -115,36 +44,3 @@ object WritableFileVirtualBinaryFile { def apply(f: File): WritableFileVirtualBinaryFile = new FileVirtualBinaryFile(f) with WritableFileVirtualBinaryFile } - -class FileVirtualJSFile(f: File) extends FileVirtualTextFile(f) - with VirtualJSFile { - import FileVirtualFile._ - import FileVirtualTextFile._ - - val sourceMapFile: File = withExtension(file, ".js", ".js.map") - - override def sourceMap: Option[String] = { - if (sourceMapFile.exists) Some(readFileToString(sourceMapFile)) - else None - } -} - -object FileVirtualJSFile extends (File => FileVirtualJSFile) { - def apply(f: File): FileVirtualJSFile = - new FileVirtualJSFile(f) -} - -trait WritableFileVirtualJSFile extends FileVirtualJSFile - with WritableFileVirtualTextFile - with WritableVirtualJSFile { - - override def sourceMapWriter: Writer = { - new BufferedWriter(new OutputStreamWriter( - new FileOutputStream(sourceMapFile), "UTF-8")) - } -} - -object WritableFileVirtualJSFile { - def apply(f: File): WritableFileVirtualJSFile = - new FileVirtualJSFile(f) with WritableFileVirtualJSFile -} diff --git a/io/shared/src/main/scala/org/scalajs/io/IO.scala b/io/shared/src/main/scala/org/scalajs/io/IO.scala deleted file mode 100644 index 60b40a207a..0000000000 --- a/io/shared/src/main/scala/org/scalajs/io/IO.scala +++ /dev/null @@ -1,129 +0,0 @@ -package org.scalajs.io - -import scala.annotation.tailrec - -import scala.reflect.ClassTag - -import java.io._ - -object IO { - /** Returns the lines in an input stream. - * Lines do not contain the new line characters. - */ - def readLines(stream: InputStream): List[String] = - readLines(new InputStreamReader(stream)) - - /** Returns the lines in a string. - * Lines do not contain the new line characters. - */ - def readLines(content: String): List[String] = - readLines(new StringReader(content)) - - /** Returns the lines in a reader. - * Lines do not contain the new line characters. - */ - def readLines(reader: Reader): List[String] = { - val br = new BufferedReader(reader) - try { - val builder = List.newBuilder[String] - @tailrec - def loop(): Unit = { - val line = br.readLine() - if (line ne null) { - builder += line - loop() - } - } - loop() - builder.result() - } finally { - br.close() - } - } - - /** Reads the entire content of a reader as a string. */ - def readReaderToString(reader: Reader): String = { - val buffer = newBuffer[Char] - val builder = new StringBuilder - @tailrec - def loop(): Unit = { - val len = reader.read(buffer) - if (len > 0) { - builder.appendAll(buffer, 0, len) - loop() - } - } - loop() - builder.toString() - } - - /** Reads the entire content of an input stream as a UTF-8 string. */ - def readInputStreamToString(stream: InputStream): String = { - val reader = new BufferedReader(new InputStreamReader(stream, "UTF-8")) - readReaderToString(reader) - } - - /** Reads the entire content of an input stream as a byte array. */ - def readInputStreamToByteArray(stream: InputStream): Array[Byte] = { - val builder = new ByteArrayOutputStream() - pipe(stream, builder) - builder.toByteArray() - } - - def copyTo(in: VirtualTextFile, out: WritableVirtualTextFile): Unit = { - val writer = out.contentWriter - try writeTo(in, writer) - finally writer.close() - } - - def copyTo(in: VirtualBinaryFile, out: WritableVirtualBinaryFile): Unit = { - val outStream = out.outputStream - try writeTo(in, outStream) - finally outStream.close() - } - - def writeTo(vf: VirtualBinaryFile, out: OutputStream): Unit = { - val in = vf.inputStream - try pipe(in, out) - finally in.close() - } - - def writeTo(vf: VirtualTextFile, writer: Writer): Unit = { - val reader = vf.reader - try pipe(reader, writer) - finally reader.close() - } - - /** Pipes data from `in` to `out` */ - def pipe(in: InputStream, out: OutputStream): Unit = { - val buffer = newBuffer[Byte] - - @tailrec - def loop(): Unit = { - val size = in.read(buffer) - if (size > 0) { - out.write(buffer, 0, size) - loop() - } - } - loop() - } - - /** Pipes data from `in` to `out` */ - def pipe(in: Reader, out: Writer): Unit = { - val buffer = newBuffer[Char] - - @tailrec - def loop(): Unit = { - val size = in.read(buffer) - if (size > 0) { - out.write(buffer, 0, size) - loop() - } - } - loop() - } - - @inline - private def newBuffer[T: ClassTag] = new Array[T](4096) -} diff --git a/io/shared/src/main/scala/org/scalajs/io/MemFiles.scala b/io/shared/src/main/scala/org/scalajs/io/MemFiles.scala index a986d1480e..308bb11190 100644 --- a/io/shared/src/main/scala/org/scalajs/io/MemFiles.scala +++ b/io/shared/src/main/scala/org/scalajs/io/MemFiles.scala @@ -26,43 +26,16 @@ class MemVirtualFile(val path: String) extends VirtualFile { } } -/** A simple in-memory mutable virtual text file. */ -class MemVirtualTextFile(p: String) extends MemVirtualFile(p) - with VirtualTextFile { - private[this] var _content: String = "" - - override def content: String = _content - def content_=(v: String): Unit = _content = v - - final def withContent(v: String): this.type = { - content = v - this - } -} - -trait WritableMemVirtualTextFile extends MemVirtualTextFile - with WritableVirtualTextFile { - def contentWriter: Writer = new StringWriter { - override def close(): Unit = { - super.close() - WritableMemVirtualTextFile.this.content = this.toString - } - } -} - -object WritableMemVirtualTextFile { - def apply(path: String): WritableMemVirtualTextFile = - new MemVirtualTextFile(path) with WritableMemVirtualTextFile -} - /** A simple in-memory mutable virtual binary file. */ class MemVirtualBinaryFile(p: String) extends MemVirtualFile(p) with VirtualBinaryFile { private[this] var _content: Array[Byte] = new Array[Byte](0) - override def content: Array[Byte] = _content + def content: Array[Byte] = _content def content_=(v: Array[Byte]): Unit = _content = v + def inputStream: InputStream = new ByteArrayInputStream(content) + final def withContent(v: Array[Byte]): this.type = { content = v this @@ -86,34 +59,3 @@ object WritableMemVirtualBinaryFile { def apply(path: String): WritableMemVirtualBinaryFile = new MemVirtualBinaryFile(path) with WritableMemVirtualBinaryFile } - -/** A simple in-memory mutable virtual JS file. */ -class MemVirtualJSFile(p: String) extends MemVirtualTextFile(p) - with VirtualJSFile { - private[this] var _sourceMap: Option[String] = None - - override def sourceMap: Option[String] = _sourceMap - def sourceMap_=(v: Option[String]): Unit = _sourceMap = v - - final def withSourceMap(v: Option[String]): this.type = { - sourceMap = v - this - } -} - -trait WritableMemVirtualJSFile extends MemVirtualJSFile - with WritableVirtualJSFile - with WritableMemVirtualTextFile { - - def sourceMapWriter: Writer = new StringWriter { - override def close(): Unit = { - super.close() - WritableMemVirtualJSFile.this.sourceMap = Some(this.toString) - } - } -} - -object WritableMemVirtualJSFile { - def apply(path: String): WritableMemVirtualJSFile = - new MemVirtualJSFile(path) with WritableMemVirtualJSFile -} diff --git a/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala b/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala index 14ecad887a..c5e48238dc 100644 --- a/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala +++ b/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala @@ -10,9 +10,6 @@ trait VirtualFile { * Unique if possible (used for lookup). */ def path: String - /** Name of the file/writer, including extension */ - def name: String = VirtualFile.nameFromPath(path) - /** Optionally returns an implementation-dependent "version" token. * Versions are compared with ==. * If non-empty, a different version must be returned when the content @@ -30,68 +27,13 @@ trait VirtualFile { } } -object VirtualFile { - /** Splits at the last slash and returns remainder */ - def nameFromPath(path: String): String = { - val pos = path.lastIndexOf('/') - if (pos == -1) path - else path.substring(pos + 1) - } -} - -/** A virtual input file. - */ -trait VirtualTextFile extends VirtualFile { - /** Returns the content of the file. */ - def content: String - - /** Returns a new Reader of the file. */ - def reader: Reader = new StringReader(content) - - /** Returns the lines in the content. - * Lines do not contain the new line characters. - */ - def readLines(): List[String] = IO.readLines(reader) -} - -object VirtualTextFile { - def empty(path: String): VirtualTextFile = - new MemVirtualTextFile(path) -} - -trait WritableVirtualTextFile extends VirtualTextFile { - def contentWriter: Writer -} - /** A virtual binary input file. */ trait VirtualBinaryFile extends VirtualFile { - /** Returns the content of the file. */ - def content: Array[Byte] - /** Returns a new InputStream of the file. */ - def inputStream: InputStream = new ByteArrayInputStream(content) + def inputStream: InputStream } trait WritableVirtualBinaryFile extends VirtualBinaryFile { def outputStream: OutputStream } - -/** A virtual input file which contains JavaScript code. - * It may have a source map associated with it. - */ -trait VirtualJSFile extends VirtualTextFile { - /** Optionally, content of the source map file associated with this - * JavaScript source. - */ - def sourceMap: Option[String] = None -} - -object VirtualJSFile { - def empty(path: String): VirtualJSFile = - new MemVirtualJSFile(path).withVersion(Some(path)) -} - -trait WritableVirtualJSFile extends WritableVirtualTextFile with VirtualJSFile { - def sourceMapWriter: Writer -} diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala index 69bf851c56..53c298c903 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala @@ -121,7 +121,7 @@ private[test] class RunTests(config: JSEnvSuiteConfig, withCom: Boolean) { val badFile = new VirtualBinaryFile { def path: String = ??? def exists: Boolean = ??? - def content: Array[Byte] = ??? + def inputStream: java.io.InputStream = ??? } // `start` may not throw but must fail asynchronously diff --git a/linker/jvm/src/main/scala/org/scalajs/linker/irio/FileVirtualIRFiles.scala b/linker/jvm/src/main/scala/org/scalajs/linker/irio/FileVirtualIRFiles.scala index 313902816c..4146b887db 100644 --- a/linker/jvm/src/main/scala/org/scalajs/linker/irio/FileVirtualIRFiles.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/irio/FileVirtualIRFiles.scala @@ -23,9 +23,6 @@ object FileVirtualScalaJSIRFile { def apply(f: File, relPath: String): FileVirtualScalaJSIRFile = new FileVirtualScalaJSIRFile(f, relPath) - - def isScalaJSIRFile(file: File): Boolean = - hasExtension(file, ".sjsir") } object FileScalaJSIRContainer { diff --git a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala index b7a5f1bd41..3b523c79a6 100644 --- a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala +++ b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala @@ -11,7 +11,7 @@ package org.scalajs.jsenv.nodejs import java.nio.charset.StandardCharsets -import scala.collection.immutable +import scala.annotation.tailrec import scala.collection.JavaConverters._ import org.scalajs.jsenv._ @@ -92,7 +92,24 @@ object NodeJSEnv { val fname = file.file.getAbsolutePath p.println(s"""require("${escapeJS(fname)}");""") case f => - IO.writeTo(f, p) + val in = f.inputStream + try { + val buf = new Array[Byte](4096) + + @tailrec + def loop(): Unit = { + val read = in.read(buf) + if (read != -1) { + p.write(buf, 0, read) + loop() + } + } + + loop() + } finally { + in.close() + } + p.println() } } finally { diff --git a/sbt-plugin/src/main/scala-sbt-0.13/org/scalajs/sbtplugin/SBTCompat.scala b/sbt-plugin/src/main/scala-sbt-0.13/org/scalajs/sbtplugin/SBTCompat.scala index 55d44b6457..e7dfcffaaf 100644 --- a/sbt-plugin/src/main/scala-sbt-0.13/org/scalajs/sbtplugin/SBTCompat.scala +++ b/sbt-plugin/src/main/scala-sbt-0.13/org/scalajs/sbtplugin/SBTCompat.scala @@ -2,8 +2,6 @@ package org.scalajs.sbtplugin import sbt._ -import org.scalajs.io.FileVirtualFile - private[sbtplugin] object SBTCompat { type IncOptions = sbt.inc.IncOptions @@ -38,7 +36,7 @@ private[sbtplugin] object SBTCompat { 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") + val f = new File(classFile.getPath.stripSuffix(".class") + ".sjsir") if (f.exists) List(f) else Nil } else Nil diff --git a/sbt-plugin/src/main/scala-sbt-1.0/org/scalajs/sbtplugin/SBTCompat.scala b/sbt-plugin/src/main/scala-sbt-1.0/org/scalajs/sbtplugin/SBTCompat.scala index 8e5a130936..287f917ad7 100644 --- a/sbt-plugin/src/main/scala-sbt-1.0/org/scalajs/sbtplugin/SBTCompat.scala +++ b/sbt-plugin/src/main/scala-sbt-1.0/org/scalajs/sbtplugin/SBTCompat.scala @@ -2,8 +2,6 @@ package org.scalajs.sbtplugin import sbt._ -import org.scalajs.io.FileVirtualFile - private[sbtplugin] object SBTCompat { type IncOptions = xsbti.compile.IncOptions @@ -41,7 +39,7 @@ private[sbtplugin] object SBTCompat { def delete(classes: Array[File]): Unit = { inherited.delete(classes.flatMap { classFile => if (classFile.getPath.endsWith(".class")) { - val f = FileVirtualFile.withExtension(classFile, ".class", ".sjsir") + val f = new File(classFile.getPath.stripSuffix(".class") + ".sjsir") if (f.exists) List(f) else Nil } else { diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index e88fe14c94..67bc15e5aa 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -12,7 +12,7 @@ import sbt.complete.DefaultParsers._ import org.portablescala.sbtplatformdeps.PlatformDepsPlugin.autoImport._ -import org.scalajs.io.{IO => _, _} +import org.scalajs.io._ import org.scalajs.io.JSUtils.escapeJS import org.scalajs.linker._ From 6560eea379857ff7d5ccfc2ae18c5fd32f024c21 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 29 Apr 2018 14:11:20 +0200 Subject: [PATCH 0748/2665] Do not make WritableVirtualBinaryFile a VirtualFile This is a bit strange in theory but matches how we use it in practice: A WritableVirtualBinary file really is only a way to write somewhere. It doesn't even come with path information. --- .../src/main/scala/org/scalajs/io/VirtualFiles.scala | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala b/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala index c5e48238dc..0015709b9b 100644 --- a/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala +++ b/io/shared/src/main/scala/org/scalajs/io/VirtualFiles.scala @@ -34,6 +34,12 @@ trait VirtualBinaryFile extends VirtualFile { def inputStream: InputStream } -trait WritableVirtualBinaryFile extends VirtualBinaryFile { +/** A writable virtual binary file. + * + * @note This does **not** extend [[VirtualBinaryFile]] nor [[VirtualFile]], + * mainly because the Scala.js stack never needs these two things together. + * Implementations are free to provide both interfaces. + */ +trait WritableVirtualBinaryFile { def outputStream: OutputStream } From 59d395c94f586ce25ed5c65d6d5eb339b3fd1f0f Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 29 Apr 2018 17:57:04 +0200 Subject: [PATCH 0749/2665] Make MemVirtualBinaryFile immutable As a consequence we decouple writable from readable files but provide a way to convert them. --- .../main/scala/org/scalajs/io/MemFiles.scala | 65 ++++++++++--------- .../org/scalajs/jsenv/test/TestComKit.scala | 2 +- .../org/scalajs/jsenv/test/TestKit.scala | 2 +- .../linker/irio/NodeVirtualIRFiles.scala | 10 +-- .../linker/irio/FileVirtualIRFiles.scala | 10 +-- .../org/scalajs/linker/irio/MemIRFiles.scala | 6 +- .../scala/org/scalajs/linker/LinkerTest.scala | 4 +- .../org/scalajs/jsenv/nodejs/ComSupport.scala | 2 +- .../org/scalajs/jsenv/nodejs/NodeJSEnv.scala | 4 +- .../org/scalajs/jsenv/nodejs/Support.scala | 2 +- .../scala/tools/nsc/MainGenericRunner.scala | 4 +- project/Build.scala | 6 +- project/NodeJSEnvForcePolyfills.scala | 3 +- sbt-plugin-test/build.sbt | 2 +- 14 files changed, 64 insertions(+), 58 deletions(-) diff --git a/io/shared/src/main/scala/org/scalajs/io/MemFiles.scala b/io/shared/src/main/scala/org/scalajs/io/MemFiles.scala index 308bb11190..03e85a3236 100644 --- a/io/shared/src/main/scala/org/scalajs/io/MemFiles.scala +++ b/io/shared/src/main/scala/org/scalajs/io/MemFiles.scala @@ -10,52 +10,53 @@ package org.scalajs.io import java.io._ - import java.nio.charset.StandardCharsets -/** A base class for simple in-memory mutable virtual files. */ -class MemVirtualFile(val path: String) extends VirtualFile { - private[this] var _version: Option[String] = None - - override def version: Option[String] = _version - def version_=(v: Option[String]): Unit = _version = v - - final def withVersion(v: Option[String]): this.type = { - version = v - this - } +/** A simple in-memory immutable virtual binary file. + * + * Modifying the passed `content` after creation of a [[MemVirtualBinaryFile]] + * yields undefined behavior. + */ +class MemVirtualBinaryFile( + final val path: String, + content: Array[Byte], + final override val version: Option[String] +) extends VirtualBinaryFile { + final def inputStream: InputStream = new ByteArrayInputStream(content) } -/** A simple in-memory mutable virtual binary file. */ -class MemVirtualBinaryFile(p: String) extends MemVirtualFile(p) - with VirtualBinaryFile { - private[this] var _content: Array[Byte] = new Array[Byte](0) +object MemVirtualBinaryFile { + def apply(path: String, content: Array[Byte]): MemVirtualBinaryFile = + apply(path, content, None) - def content: Array[Byte] = _content - def content_=(v: Array[Byte]): Unit = _content = v + def apply(path: String, content: Array[Byte], + version: Option[String]): MemVirtualBinaryFile = { + new MemVirtualBinaryFile(path, content, version) + } - def inputStream: InputStream = new ByteArrayInputStream(content) + def fromStringUTF8(path: String, content: String): MemVirtualBinaryFile = + fromStringUTF8(path, content, None) - final def withContent(v: Array[Byte]): this.type = { - content = v - this + def fromStringUTF8(path: String, content: String, + version: Option[String]): MemVirtualBinaryFile = { + apply(path, content.getBytes(StandardCharsets.UTF_8), version) } - - final def withStringUTF8(v: String): this.type = - withContent(v.getBytes(StandardCharsets.UTF_8)) } -trait WritableMemVirtualBinaryFile extends MemVirtualBinaryFile - with WritableVirtualBinaryFile { +final class WritableMemVirtualBinaryFile extends WritableVirtualBinaryFile { + private var _content: Array[Byte] = _ + + def content: Array[Byte] = _content + def outputStream: OutputStream = new ByteArrayOutputStream { override def close(): Unit = { super.close() - WritableMemVirtualBinaryFile.this.content = this.toByteArray + _content = this.toByteArray } } -} -object WritableMemVirtualBinaryFile { - def apply(path: String): WritableMemVirtualBinaryFile = - new MemVirtualBinaryFile(path) with WritableMemVirtualBinaryFile + def toReadable(path: String): MemVirtualBinaryFile = toReadable(path, None) + + def toReadable(path: String, version: Option[String]): MemVirtualBinaryFile = + new MemVirtualBinaryFile(path, content, version) } diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestComKit.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestComKit.scala index c33190bd75..7ca45b8914 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestComKit.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestComKit.scala @@ -14,7 +14,7 @@ import scala.concurrent.duration.Duration private[test] final class TestComKit(config: JSEnvSuiteConfig) { def start(code: String, runConfig: RunConfig): Run = { - val vf = new MemVirtualBinaryFile("testScript.js").withStringUTF8(code) + val vf = MemVirtualBinaryFile.fromStringUTF8("testScript.js", code) start(vf, runConfig) } diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestKit.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestKit.scala index 934eebb879..0dfb47393d 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestKit.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestKit.scala @@ -20,7 +20,7 @@ private[test] final class TestKit(config: JSEnvSuiteConfig, withCom: Boolean) { assumeTrue("JSEnv needs com support", config.supportsCom || !withCom) def start(code: String, config: RunConfig): JSRun = { - val vf = new MemVirtualBinaryFile("testScript.js").withStringUTF8(code) + val vf = MemVirtualBinaryFile.fromStringUTF8("testScript.js", code) start(vf, config) } diff --git a/linker/js/src/main/scala/org/scalajs/linker/irio/NodeVirtualIRFiles.scala b/linker/js/src/main/scala/org/scalajs/linker/irio/NodeVirtualIRFiles.scala index 4cd8af2b4f..ab26c7276c 100644 --- a/linker/js/src/main/scala/org/scalajs/linker/irio/NodeVirtualIRFiles.scala +++ b/linker/js/src/main/scala/org/scalajs/linker/irio/NodeVirtualIRFiles.scala @@ -28,10 +28,12 @@ private[scalajs] class NodeVirtualJarScalaJSIRContainer(path: String) (name, entry) <- zip.files.toList if name.endsWith(".sjsir") } yield { - val path = s"${this.path}:$name" - new MemVirtualSerializedScalaJSIRFile(path, name) - .withContent(new Int8Array(entry.asArrayBuffer()).toArray) - .withVersion(this.version) + new MemVirtualSerializedScalaJSIRFile( + path = s"${this.path}:$name", + relativePath = name, + content = new Int8Array(entry.asArrayBuffer()).toArray, + version = this.version + ) } } } diff --git a/linker/jvm/src/main/scala/org/scalajs/linker/irio/FileVirtualIRFiles.scala b/linker/jvm/src/main/scala/org/scalajs/linker/irio/FileVirtualIRFiles.scala index 4146b887db..2848830ce7 100644 --- a/linker/jvm/src/main/scala/org/scalajs/linker/irio/FileVirtualIRFiles.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/irio/FileVirtualIRFiles.scala @@ -85,10 +85,12 @@ final class FileVirtualJarScalaJSIRContainer(file: File) try { readAll(out) - val path = s"${this.path}:${e.getName}" - new MemVirtualSerializedScalaJSIRFile(path, e.getName) - .withContent(out.toByteArray) - .withVersion(this.version) + new MemVirtualSerializedScalaJSIRFile( + path = s"${this.path}:${e.getName}", + relativePath = e.getName, + content = out.toByteArray, + version = this.version + ) } finally { out.close() } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/irio/MemIRFiles.scala b/linker/shared/src/main/scala/org/scalajs/linker/irio/MemIRFiles.scala index e9b8301354..f83a0d99cb 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/irio/MemIRFiles.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/irio/MemIRFiles.scala @@ -11,5 +11,7 @@ package org.scalajs.linker.irio import org.scalajs.io._ /** A simple in-memory mutable virtual serialized Scala.js IR file. */ -class MemVirtualSerializedScalaJSIRFile(p: String, val relativePath: String) - extends MemVirtualBinaryFile(p) with VirtualSerializedScalaJSIRFile +class MemVirtualSerializedScalaJSIRFile(path: String, val relativePath: String, + content: Array[Byte], version: Option[String]) + extends MemVirtualBinaryFile(path, content, version) + with VirtualSerializedScalaJSIRFile diff --git a/linker/shared/src/test/scala/org/scalajs/linker/LinkerTest.scala b/linker/shared/src/test/scala/org/scalajs/linker/LinkerTest.scala index e0fffc645a..9c86c6bbff 100644 --- a/linker/shared/src/test/scala/org/scalajs/linker/LinkerTest.scala +++ b/linker/shared/src/test/scala/org/scalajs/linker/LinkerTest.scala @@ -59,7 +59,7 @@ class LinkerTest { val linker = StandardLinker(StandardLinker.Config()) def callLink(): Unit = { - val out = LinkerOutput(WritableMemVirtualBinaryFile("some_file")) + val out = LinkerOutput(new WritableMemVirtualBinaryFile) linker.link(badSeq, Nil, out, NullLogger) } @@ -105,7 +105,7 @@ object LinkerTest { val allIRFiles = TestIRRepo.stdlibIRFiles ++ classDefsFiles - val output = LinkerOutput(WritableMemVirtualBinaryFile("output.js")) + val output = LinkerOutput(new WritableMemVirtualBinaryFile) linker.link(allIRFiles, moduleInitializers, output, new ScalaConsoleLogger(Level.Error)) diff --git a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/ComSupport.scala b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/ComSupport.scala index 34bb976ddf..d48f303203 100644 --- a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/ComSupport.scala +++ b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/ComSupport.scala @@ -238,7 +238,7 @@ object ComRun { } private def setupFile(port: Int): VirtualBinaryFile = { - new MemVirtualBinaryFile("comSetup.js").withStringUTF8( + MemVirtualBinaryFile.fromStringUTF8("comSetup.js", s""" |(function() { | // The socket for communication diff --git a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala index 3b523c79a6..6071dae70b 100644 --- a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala +++ b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala @@ -70,12 +70,12 @@ object NodeJSEnv { private lazy val validator = ExternalJSRun.supports(RunConfig.Validator()) private lazy val installSourceMap = { - new MemVirtualBinaryFile("sourceMapSupport.js").withStringUTF8( + MemVirtualBinaryFile.fromStringUTF8("sourceMapSupport.js", "require('source-map-support').install();") } private lazy val runtimeEnv = { - new MemVirtualBinaryFile("scalaJSEnvInfo.js").withStringUTF8( + MemVirtualBinaryFile.fromStringUTF8("scalaJSEnvInfo.js", """ |__ScalaJSEnv = { | exitFunction: function(status) { process.exit(status); } diff --git a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/Support.scala b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/Support.scala index 5c847fa64b..05c3259074 100644 --- a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/Support.scala +++ b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/Support.scala @@ -13,7 +13,7 @@ import org.scalajs.io._ object Support { def fixPercentConsole: VirtualBinaryFile = { - new MemVirtualBinaryFile("nodeConsoleHack.js").withStringUTF8( + MemVirtualBinaryFile.fromStringUTF8("nodeConsoleHack.js", """ |// Hack console log to duplicate double % signs |(function() { diff --git a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala index 206d7d6710..67cdc28e4c 100644 --- a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala +++ b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala @@ -83,9 +83,9 @@ class MainGenericRunner { val linker = StandardLinker(linkerConfig) val sjsCode = { - val out = WritableMemVirtualBinaryFile("partest.js") + val out = new WritableMemVirtualBinaryFile linker.link(ir, moduleInitializers, LinkerOutput(out), logger) - out + out.toReadable("partest.js") } val input = Input.ScriptsToLoad(sjsCode :: Nil) diff --git a/project/Build.scala b/project/Build.scala index d1117ce6f7..4ca8e42c56 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -86,7 +86,7 @@ object MyScalaJSPlugin extends AutoPlugin { "__ScalaJSEnv.javaSystemProperties = {" + formattedProps.mkString(", ") + "};\n" } val javaSysPropsFile = - new MemVirtualBinaryFile("setJavaSystemProperties.js").withStringUTF8(code) + MemVirtualBinaryFile.fromStringUTF8("setJavaSystemProperties.js", code) javaSysPropsFile +: prev } @@ -1410,7 +1410,7 @@ object Build { """ val patchedSystemPropertiesFile = - new MemVirtualBinaryFile("setJavaSystemProperties.js").withStringUTF8(code) + MemVirtualBinaryFile.fromStringUTF8("setJavaSystemProperties.js", code) // Replace the normal `setJavaSystemProperties.js` file with the patch for (file <- previousFiles) yield { @@ -1460,7 +1460,7 @@ object Build { } val launcher = - new MemVirtualBinaryFile("test-suite-linker.js").withStringUTF8(code) + MemVirtualBinaryFile.fromStringUTF8("test-suite-linker.js", code) val config = RunConfig().withLogger(sbtLogger2ToolsLogger(s.log)) val input = Input.ScriptsToLoad(List(launcher)) diff --git a/project/NodeJSEnvForcePolyfills.scala b/project/NodeJSEnvForcePolyfills.scala index 18c6884232..521b68df8e 100644 --- a/project/NodeJSEnvForcePolyfills.scala +++ b/project/NodeJSEnvForcePolyfills.scala @@ -29,7 +29,7 @@ final class NodeJSEnvForcePolyfills(config: NodeJSEnv.Config) extends JSEnv { * native functions. */ private def forcePolyfills(): VirtualBinaryFile = { - val f = new MemVirtualBinaryFile("scalaJSEnvInfo.js").withStringUTF8( + MemVirtualBinaryFile.fromStringUTF8("scalaJSEnvInfo.js", """ |delete Math.fround; |delete Math.imul; @@ -55,6 +55,5 @@ final class NodeJSEnvForcePolyfills(config: NodeJSEnv.Config) extends JSEnv { |delete global.Float64Array; """.stripMargin ) - f } } diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index ad029b67f2..4f9db4d8b7 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -68,7 +68,7 @@ lazy val noDOM = project.settings(baseSettings: _*). Def.task { log.info("Fake full optimizing") val linker = (scalaJSLinker in fullOptJS).value - val output = LinkerOutput(WritableMemVirtualBinaryFile("fake-fastopt.js")) + val output = LinkerOutput(new WritableMemVirtualBinaryFile) linker.link(ir, moduleInitializers, output, sbtLogger2ToolsLogger(log)) }.tag((usesScalaJSLinkerTag in fullOptJS).value) }.value, From c656fdee8cee1e1c6e2932c9992b0f43dbc94371 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Mon, 30 Apr 2018 07:17:03 +0200 Subject: [PATCH 0750/2665] Clean up FileVirtualFiles This mostly means: - No user-side mixin. - Make things we can final. - Remove unused imports. - Remove factories (which are unnecessary now due to less mixin). --- .../io/AtomicWritableFileVirtualFiles.scala | 9 ++---- .../org/scalajs/io/FileVirtualFiles.scala | 31 ++++--------------- .../linker/irio/FileVirtualIRFiles.scala | 11 ++----- project/Build.scala | 3 +- sbt-plugin-test/build.sbt | 2 +- .../sbtplugin/ScalaJSPluginInternal.scala | 4 +-- 6 files changed, 15 insertions(+), 45 deletions(-) diff --git a/io/jvm/src/main/scala/org/scalajs/io/AtomicWritableFileVirtualFiles.scala b/io/jvm/src/main/scala/org/scalajs/io/AtomicWritableFileVirtualFiles.scala index a568367755..42765b19d0 100644 --- a/io/jvm/src/main/scala/org/scalajs/io/AtomicWritableFileVirtualFiles.scala +++ b/io/jvm/src/main/scala/org/scalajs/io/AtomicWritableFileVirtualFiles.scala @@ -1,14 +1,9 @@ package org.scalajs.io import java.io._ -import java.net.URI -trait AtomicWritableFileVirtualBinaryFile extends WritableFileVirtualBinaryFile { +final class AtomicWritableFileVirtualBinaryFile(f: File) + extends FileVirtualFile(f) with WritableVirtualBinaryFile { override def outputStream: OutputStream = new BufferedOutputStream(new AtomicFileOutputStream(file)) } - -object AtomicWritableFileVirtualBinaryFile { - def apply(f: File): AtomicWritableFileVirtualBinaryFile = - new FileVirtualBinaryFile(f) with AtomicWritableFileVirtualBinaryFile -} diff --git a/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala b/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala index 64396e41b4..69af9f39fa 100644 --- a/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala +++ b/io/jvm/src/main/scala/org/scalajs/io/FileVirtualFiles.scala @@ -5,42 +5,23 @@ import java.net.URI /** A [[VirtualFile]] implemented by an actual file on the file system. */ class FileVirtualFile(val file: File) extends VirtualFile { - import FileVirtualFile._ + final def path: String = file.getPath - override def path: String = file.getPath - - override def version: Option[String] = { + final override def version: Option[String] = { if (!file.isFile) None else Some(file.lastModified.toString) } } -object FileVirtualFile extends (File => FileVirtualFile) { - def apply(f: File): FileVirtualFile = - new FileVirtualFile(f) -} - /** A [[VirtualBinaryFile]] implemented by an actual file on the file system. */ class FileVirtualBinaryFile(f: File) extends FileVirtualFile(f) with VirtualBinaryFile { - import FileVirtualBinaryFile._ - - override def inputStream: InputStream = + final def inputStream: InputStream = new BufferedInputStream(new FileInputStream(file)) } -object FileVirtualBinaryFile extends (File => FileVirtualBinaryFile) { - def apply(f: File): FileVirtualBinaryFile = - new FileVirtualBinaryFile(f) -} - -trait WritableFileVirtualBinaryFile extends FileVirtualBinaryFile - with WritableVirtualBinaryFile { - override def outputStream: OutputStream = +class WritableFileVirtualBinaryFile(f: File) extends FileVirtualBinaryFile(f) + with WritableVirtualBinaryFile { + final def outputStream: OutputStream = new BufferedOutputStream(new FileOutputStream(file)) } - -object WritableFileVirtualBinaryFile { - def apply(f: File): WritableFileVirtualBinaryFile = - new FileVirtualBinaryFile(f) with WritableFileVirtualBinaryFile -} diff --git a/linker/jvm/src/main/scala/org/scalajs/linker/irio/FileVirtualIRFiles.scala b/linker/jvm/src/main/scala/org/scalajs/linker/irio/FileVirtualIRFiles.scala index 2848830ce7..bcb62db2c5 100644 --- a/linker/jvm/src/main/scala/org/scalajs/linker/irio/FileVirtualIRFiles.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/irio/FileVirtualIRFiles.scala @@ -15,16 +15,9 @@ import scala.annotation.tailrec import org.scalajs.io._ -class FileVirtualScalaJSIRFile(f: File, val relativePath: String) +final class FileVirtualScalaJSIRFile(f: File, val relativePath: String) extends FileVirtualBinaryFile(f) with VirtualSerializedScalaJSIRFile -object FileVirtualScalaJSIRFile { - import FileVirtualFile._ - - def apply(f: File, relPath: String): FileVirtualScalaJSIRFile = - new FileVirtualScalaJSIRFile(f, relPath) -} - object FileScalaJSIRContainer { def fromClasspath( classpath: Seq[File]): Seq[ScalaJSIRContainer with FileVirtualFile] = { @@ -56,7 +49,7 @@ object FileScalaJSIRContainer { .stripPrefix(baseDir.getPath) .replace(java.io.File.separatorChar, '/') .stripPrefix("/") - FileVirtualScalaJSIRFile(ir, relPath) + new FileVirtualScalaJSIRFile(ir, relPath) } } } diff --git a/project/Build.scala b/project/Build.scala index 4ca8e42c56..f54cfefe7c 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1489,7 +1489,8 @@ object Build { def testSuiteJSExecutionFilesSetting: Setting[_] = { jsExecutionFiles := { val resourceDir = (resourceDirectory in Test).value - val f = FileVirtualBinaryFile(resourceDir / "NonNativeJSTypeTestNatives.js") + val f = new FileVirtualBinaryFile( + resourceDir / "NonNativeJSTypeTestNatives.js") f +: jsExecutionFiles.value } } diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index 4f9db4d8b7..98568a719f 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -127,7 +127,7 @@ lazy val multiTestJS = project.in(file("multiTest/js")). // Make FrameworkDetector resilient to other output - #1572 jsExecutionFiles in Test := { - val consoleWriter = FileVirtualBinaryFile( + val consoleWriter = new FileVirtualBinaryFile( (resourceDirectory in Test).value / "consoleWriter.js") consoleWriter +: (jsExecutionFiles in Test).value }, diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 67bc15e5aa..dc11811f9f 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -181,8 +181,8 @@ private[sbtplugin] object ScalaJSPluginInternal { def relURI(path: String) = new URI(null, null, path, null) - val out = LinkerOutput(AtomicWritableFileVirtualBinaryFile(output)) - .withSourceMap(AtomicWritableFileVirtualBinaryFile(sourceMapFile)) + val out = LinkerOutput(new AtomicWritableFileVirtualBinaryFile(output)) + .withSourceMap(new AtomicWritableFileVirtualBinaryFile(sourceMapFile)) .withSourceMapURI(relURI(sourceMapFile.getName)) .withJSFileURI(relURI(output.getName)) From 8b94dc751fddd6db4ebf9329f3199bf5e12870bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 24 May 2018 17:50:30 +0200 Subject: [PATCH 0751/2665] Fix #3336: Handle exceptions during JUnit test class constructor. In the process, add a bunch of other tests for exceptions being thrown at various stages of a test's lifetime. Overall, this prompted a major rewrite of the test execution method. --- .../org/scalajs/junit/JUnitExecuteTest.scala | 108 +++++++++++------- .../scalajs/junit/ExceptionInAfterTest.scala | 26 +++++ .../scalajs/junit/ExceptionInBeforeTest.scala | 31 +++++ .../junit/ExceptionInConstructorTest.scala | 32 ++++++ .../org/scalajs/junit/utils/JUnitTest.scala | 12 ++ 5 files changed, 168 insertions(+), 41 deletions(-) create mode 100644 junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInAfterTest.scala create mode 100644 junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInBeforeTest.scala create mode 100644 junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInConstructorTest.scala diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala index ce516c2957..be17f6643c 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala @@ -72,7 +72,6 @@ final class JUnitExecuteTest(taskDef: TaskDef, runner: JUnitBaseRunner, private[this] def executeTestMethod(classMetadata: JUnitTestBootstrapper, method: JUnitMethodMetadata) = { val jUnitMetadata = classMetadata.metadata() - val testClassInstance = classMetadata.newInstance() val methodName = method.name val decodedMethodName = { if (decodeScalaNames) runner.runSettings.decodeName(methodName) @@ -80,29 +79,42 @@ final class JUnitExecuteTest(taskDef: TaskDef, runner: JUnitBaseRunner, } val testAnnotation = method.getTestAnnotation.get + if (verbose) + logFormattedInfo(decodedMethodName, "started") + else + logFormattedDebug(decodedMethodName, "started") + val t0 = System.nanoTime def getTimeInSeconds(): Double = (System.nanoTime - t0).toDouble / 1000000000 - def executeTestMethods(): Unit = { - val expectedException = testAnnotation.expected - try { - if (verbose) logFormattedInfo(decodedMethodName, "started") - else logFormattedDebug(decodedMethodName, "started") + var eventAlreadyEmitted: Boolean = false - classMetadata.invoke(testClassInstance, method.name) - logFormattedDebug(decodedMethodName, - s"finished, took ${getTimeInSeconds()} sec") + def emitTestFailed(): Unit = { + if (eventAlreadyEmitted) { + // Only add to the failed test count, don't emit an event + runner.testFailed() + } else { + testFailed(methodName) + eventAlreadyEmitted = true + } + } + + def execute(expectedException: Class[_] = classOf[org.junit.Test.None])( + body: => Unit): Boolean = { + + try { + body if (expectedException == classOf[org.junit.Test.None]) { - testPassed(methodName) - executeAfterMethods() + true } else { val msg = { s"failed: Expected exception: " + expectedException + s"took ${getTimeInSeconds()} sec" } logFormattedError(decodedMethodName, msg, None) - testFailed(methodName) + emitTestFailed() + false } } catch { case ex: Throwable => @@ -111,9 +123,9 @@ final class JUnitExecuteTest(taskDef: TaskDef, runner: JUnitBaseRunner, ex.isInstanceOf[internal.AssumptionViolatedException]) { logAssertionWarning(decodedMethodName, ex, timeInSeconds) testSkipped() + false } else if (expectedException.isInstance(ex)) { - testPassed(methodName) - executeAfterMethods() + true } else if (expectedException == classOf[org.junit.Test.None]) { val isAssertion = ex.isInstanceOf[AssertionError] val failedMsg = new StringBuilder @@ -134,48 +146,62 @@ final class JUnitExecuteTest(taskDef: TaskDef, runner: JUnitBaseRunner, else None } logFormattedError(decodedMethodName, msg, exOpt) - testFailed(methodName) + emitTestFailed() + false } else { val msg = s"failed: ${ex.getClass}, took $timeInSeconds sec" logFormattedError(decodedMethodName, msg, Some(ex)) - testFailed(methodName) + emitTestFailed() + false } - logFormattedDebug(decodedMethodName, - s"finished, took $timeInSeconds sec") } - runner.testRegisterTotal() } - def executeAfterMethods(): Unit = { - try { - for (method <- jUnitMetadata.afterMethod) + var testClassInstance: AnyRef = null + + val instantiationSucceeded = execute() { + testClassInstance = classMetadata.newInstance() + } + + val success = if (!instantiationSucceeded) { + false + } else { + val beforeSucceeded = execute() { + for (method <- jUnitMetadata.beforeMethod) classMetadata.invoke(testClassInstance, method.name) + } - val timeInSeconds = getTimeInSeconds() - if (testAnnotation.timeout != 0 && testAnnotation.timeout <= timeInSeconds) { - richLogger.warn("Timeout: took " + timeInSeconds + " sec, expected " + - (testAnnotation.timeout.toDouble / 1000) + " sec") + val beforeAndTestSucceeded = if (!beforeSucceeded) { + false + } else { + execute(testAnnotation.expected) { + classMetadata.invoke(testClassInstance, method.name) } - } catch { - case ex: Throwable => - logFormattedError(methodName, "failed: on @AfterClass method", Some(ex)) - val selector = new NestedTestSelector(fullyQualifiedName, methodName) - eventHandler.handle(new JUnitEvent(taskDef, Status.Failure, selector)) } - } - try { - for (method <- jUnitMetadata.beforeMethod) { - classMetadata.invoke(testClassInstance, method.name) + // Whether before and/or test succeeded or not, run the after methods + val afterSucceeded = execute() { + for (method <- jUnitMetadata.afterMethod) + classMetadata.invoke(testClassInstance, method.name) } - executeTestMethods() - } catch { - case ex: AssumptionViolatedException => - logAssertionWarning(methodName, ex, getTimeInSeconds()) - case ex: internal.AssumptionViolatedException => - logAssertionWarning(methodName, ex, getTimeInSeconds()) + beforeAndTestSucceeded && afterSucceeded + } + + logFormattedDebug(decodedMethodName, + s"finished, took ${getTimeInSeconds()} sec") + + // Scala.js-specific: timeouts are warnings only, after the fact + val timeInSeconds = getTimeInSeconds() + if (testAnnotation.timeout != 0 && testAnnotation.timeout <= timeInSeconds) { + richLogger.warn("Timeout: took " + timeInSeconds + " sec, expected " + + (testAnnotation.timeout.toDouble / 1000) + " sec") } + + if (success) + testPassed(methodName) + + runner.testRegisterTotal() } private def ignoreTest(methodName: String) = { diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInAfterTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInAfterTest.scala new file mode 100644 index 0000000000..0f2203f5ac --- /dev/null +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInAfterTest.scala @@ -0,0 +1,26 @@ +package org.scalajs.junit + +import org.junit._ +import org.junit.Assert._ + +import org.scalajs.junit.utils._ + +class ExceptionInAfterTest { + @After def after(): Unit = + throw new UnsupportedOperationException("Exception in after()") + + /* Even if the test method declares expecting the exception thrown by the + * after() method, it must result in an error, not a success. + */ + @Test(expected = classOf[UnsupportedOperationException]) + def test(): Unit = + throw new UnsupportedOperationException("Exception in test()") +} + +class ExceptionInAfterTestAssertions extends JUnitTest { + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = { + builder.exception("test", + "Exception in after()", + "java.lang.UnsupportedOperationException") + } +} diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInBeforeTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInBeforeTest.scala new file mode 100644 index 0000000000..112167a435 --- /dev/null +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInBeforeTest.scala @@ -0,0 +1,31 @@ +package org.scalajs.junit + +import org.junit._ +import org.junit.Assert._ + +import org.scalajs.junit.utils._ + +class ExceptionInBeforeTest { + @Before def before(): Unit = + throw new UnsupportedOperationException("Exception in before()") + + @After def after(): Unit = + throw new IllegalArgumentException("after() must actually be called") + + /* Even if the test method declares expecting the exception thrown by the + * before() method, it must result in an error, not a success. + */ + @Test(expected = classOf[UnsupportedOperationException]) + def test(): Unit = + throw new IllegalStateException("test() must not be called") +} + +class ExceptionInBeforeTestAssertions extends JUnitTest { + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = { + builder.exceptionAndAnotherExceptionInAfter("test", + "Exception in before()", + "java.lang.UnsupportedOperationException", + "after() must actually be called", + "java.lang.IllegalArgumentException") + } +} diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInConstructorTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInConstructorTest.scala new file mode 100644 index 0000000000..594dfef6bf --- /dev/null +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInConstructorTest.scala @@ -0,0 +1,32 @@ +package org.scalajs.junit + +import org.junit._ +import org.junit.Assert._ + +import org.scalajs.junit.utils._ + +class ExceptionInConstructorTest { + throw new UnsupportedOperationException( + "Exception while constructing the test class") + + @Before def before(): Unit = + throw new IllegalStateException("before() must not be called") + + @After def after(): Unit = + throw new IllegalStateException("after() must not be called") + + /* Even if the test method declares expecting the exception thrown by the + * constructor, it must result in an error, not a success. + */ + @Test(expected = classOf[UnsupportedOperationException]) + def test(): Unit = + throw new IllegalStateException("test() must not be called") +} + +class ExceptionInConstructorTestAssertions extends JUnitTest { + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = { + builder.exception("test", + "Exception while constructing the test class", + "java.lang.UnsupportedOperationException") + } +} diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala index bdfebf529e..02b3f55ca7 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala @@ -120,6 +120,18 @@ abstract class JUnitTest { ) } + def exceptionAndAnotherExceptionInAfter(testName: String, msg: String, + clazz: String, afterMsg: String, afterClazz: String): OutputBuilder = { + // Yes, there are 2 failed for 1 total ... + append(1, 0, 2)( + testStartedOutput(testName), + testExceptionMsgOutput(testName, msg, clazz), + failureEvent, + testExceptionMsgOutput(testName, afterMsg, afterClazz), + testFinishedOutput(testName) + ) + } + def assertion(testName: String, message: String): OutputBuilder = { append(1, 0, 1)( testStartedOutput(testName), From fe2b6977e441025377dd270aa2c837789bbbcf4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 24 May 2018 18:20:56 +0200 Subject: [PATCH 0752/2665] Fix #3368: Fix off-by-one error in computation of shared suffix. --- .../scala/org/junit/ComparisonFailure.scala | 10 +++++----- .../junit/AssertStringEqualsTest.scala | 20 +++++++++++++++++++ .../org/scalajs/junit/utils/JUnitTest.scala | 12 ++++++----- 3 files changed, 32 insertions(+), 10 deletions(-) create mode 100644 junit-test/shared/src/test/scala/org/scalajs/junit/AssertStringEqualsTest.scala diff --git a/junit-runtime/src/main/scala/org/junit/ComparisonFailure.scala b/junit-runtime/src/main/scala/org/junit/ComparisonFailure.scala index 3bae9d3c5d..6aea5ce61d 100644 --- a/junit-runtime/src/main/scala/org/junit/ComparisonFailure.scala +++ b/junit-runtime/src/main/scala/org/junit/ComparisonFailure.scala @@ -33,14 +33,14 @@ object ComparisonFailure { } private def sharedSuffix(prefix: String): String = { + def charAtFromEnd(s: String, i: Int): Char = + s.charAt(s.length() - 1 - i) + var suffixLength = 0 var maxSuffixLength = Math.min(expected.length() - prefix.length(), actual.length() - prefix.length()) - 1 - while (suffixLength <= maxSuffixLength) { - if (expected.charAt(expected.length() - 1 - suffixLength) - != actual.charAt(actual.length() - 1 - suffixLength)) { - maxSuffixLength = suffixLength - 1 // break - } + while (suffixLength <= maxSuffixLength && + charAtFromEnd(expected, suffixLength) == charAtFromEnd(actual, suffixLength)) { suffixLength += 1 } expected.substring(expected.length() - suffixLength) diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertStringEqualsTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertStringEqualsTest.scala new file mode 100644 index 0000000000..a5ac0b00c6 --- /dev/null +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertStringEqualsTest.scala @@ -0,0 +1,20 @@ +package org.scalajs.junit + +import org.junit.Assert._ +import org.junit.Test + +import org.scalajs.junit.utils._ + +class AssertStringEqualsTest { + @Test def test(): Unit = { + assertEquals("foobar", "foobbbr") + } +} + +class AssertStringEqualsTestAssertions extends JUnitTest { + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = { + builder.assertion("test", + "expected: but was:", + "org.junit.ComparisonFailure") + } +} diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala index 02b3f55ca7..1bae35c140 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala @@ -132,10 +132,11 @@ abstract class JUnitTest { ) } - def assertion(testName: String, message: String): OutputBuilder = { + def assertion(testName: String, message: String, + exClass: String = "java.lang.AssertionError"): OutputBuilder = { append(1, 0, 1)( testStartedOutput(testName), - testAssertionErrorMsgOutput(testName, message), + testAssertionErrorMsgOutput(testName, message, exClass), failureEvent, testFinishedOutput(testName) ) @@ -253,9 +254,10 @@ abstract class JUnitTest { s"failed: $exClassStr$msg, took $TIME_TAG sec") } - private def testAssertionErrorMsgOutput(method: String, msg: String): Output = { - val assertClass = exceptionClassInfo(show = logExceptionClass && logAssert, - "java.lang.AssertionError") + private def testAssertionErrorMsgOutput(method: String, msg: String, + exClass: String): Output = { + val assertClass = exceptionClassInfo( + show = logExceptionClass && logAssert, exClass) Error(s"Test $formattedTestClass.${red(method)} failed: $assertClass" + s"$msg, took $TIME_TAG sec") } From 2cc2176299a0159c4a2b6549c27b805889dc6066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 25 May 2018 13:27:22 +0200 Subject: [PATCH 0753/2665] Use `Class`es instead of `String`s in `JUnitTest.OutputBuilder`. For more type safety. --- .../junit/AssertStringEqualsTest.scala | 2 +- .../scalajs/junit/ExceptionInAfterTest.scala | 2 +- .../scalajs/junit/ExceptionInBeforeTest.scala | 4 ++-- .../junit/ExceptionInConstructorTest.scala | 2 +- .../org/scalajs/junit/ExceptionTest.scala | 3 ++- .../org/scalajs/junit/utils/JUnitTest.scala | 20 +++++++++++-------- 6 files changed, 19 insertions(+), 14 deletions(-) diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertStringEqualsTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertStringEqualsTest.scala index a5ac0b00c6..89aa58c812 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertStringEqualsTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertStringEqualsTest.scala @@ -15,6 +15,6 @@ class AssertStringEqualsTestAssertions extends JUnitTest { protected def expectedOutput(builder: OutputBuilder): OutputBuilder = { builder.assertion("test", "expected: but was:", - "org.junit.ComparisonFailure") + classOf[org.junit.ComparisonFailure]) } } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInAfterTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInAfterTest.scala index 0f2203f5ac..e696f6dbc1 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInAfterTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInAfterTest.scala @@ -21,6 +21,6 @@ class ExceptionInAfterTestAssertions extends JUnitTest { protected def expectedOutput(builder: OutputBuilder): OutputBuilder = { builder.exception("test", "Exception in after()", - "java.lang.UnsupportedOperationException") + classOf[UnsupportedOperationException]) } } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInBeforeTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInBeforeTest.scala index 112167a435..5df39a9c87 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInBeforeTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInBeforeTest.scala @@ -24,8 +24,8 @@ class ExceptionInBeforeTestAssertions extends JUnitTest { protected def expectedOutput(builder: OutputBuilder): OutputBuilder = { builder.exceptionAndAnotherExceptionInAfter("test", "Exception in before()", - "java.lang.UnsupportedOperationException", + classOf[UnsupportedOperationException], "after() must actually be called", - "java.lang.IllegalArgumentException") + classOf[IllegalArgumentException]) } } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInConstructorTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInConstructorTest.scala index 594dfef6bf..57fac783bb 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInConstructorTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInConstructorTest.scala @@ -27,6 +27,6 @@ class ExceptionInConstructorTestAssertions extends JUnitTest { protected def expectedOutput(builder: OutputBuilder): OutputBuilder = { builder.exception("test", "Exception while constructing the test class", - "java.lang.UnsupportedOperationException") + classOf[UnsupportedOperationException]) } } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionTest.scala index 6bcfc55ec5..7f296d8d42 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionTest.scala @@ -13,6 +13,7 @@ class ExceptionTest { class ExceptionTestAssertions extends JUnitTest { protected def expectedOutput(builder: OutputBuilder): OutputBuilder = { builder.exception("test", - "Exception message", "java.lang.IndexOutOfBoundsException") + "Exception message", + classOf[IndexOutOfBoundsException]) } } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala index 1bae35c140..6fdd894100 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala @@ -8,6 +8,8 @@ import scala.annotation.tailrec abstract class JUnitTest { import JUnitTest._ + type ThrowableClass = Class[_ <: Throwable] + // ANSI colors codes private final val NORMAL = "\u001B[0m" private final val RED = "\u001B[31m" @@ -111,7 +113,8 @@ abstract class JUnitTest { testFinishedOutput(testName) ) - def exception(testName: String, msg: String, clazz: String): OutputBuilder = { + def exception(testName: String, msg: String, + clazz: ThrowableClass): OutputBuilder = { append(1, 0, 1)( testStartedOutput(testName), testExceptionMsgOutput(testName, msg, clazz), @@ -121,7 +124,8 @@ abstract class JUnitTest { } def exceptionAndAnotherExceptionInAfter(testName: String, msg: String, - clazz: String, afterMsg: String, afterClazz: String): OutputBuilder = { + clazz: ThrowableClass, afterMsg: String, + afterClazz: ThrowableClass): OutputBuilder = { // Yes, there are 2 failed for 1 total ... append(1, 0, 2)( testStartedOutput(testName), @@ -133,7 +137,7 @@ abstract class JUnitTest { } def assertion(testName: String, message: String, - exClass: String = "java.lang.AssertionError"): OutputBuilder = { + exClass: ThrowableClass = classOf[AssertionError]): OutputBuilder = { append(1, 0, 1)( testStartedOutput(testName), testAssertionErrorMsgOutput(testName, message, exClass), @@ -248,14 +252,14 @@ abstract class JUnitTest { Info(s"Test $formattedTestClass ignored") private def testExceptionMsgOutput(method: String, msg: String, - exClass: String): Output = { + exClass: ThrowableClass): Output = { val exClassStr = exceptionClassInfo(show = logExceptionClass, exClass) Error(s"Test $formattedTestClass.${red(method)} " + s"failed: $exClassStr$msg, took $TIME_TAG sec") } private def testAssertionErrorMsgOutput(method: String, msg: String, - exClass: String): Output = { + exClass: ThrowableClass): Output = { val assertClass = exceptionClassInfo( show = logExceptionClass && logAssert, exClass) Error(s"Test $formattedTestClass.${red(method)} failed: $assertClass" + @@ -264,7 +268,7 @@ abstract class JUnitTest { private def testAssumptionViolatedOutput(method: String): Output = { val exceptionStr = exceptionClassInfo(logExceptionClass, - "org.junit.internal.AssumptionViolatedException") + classOf[org.junit.internal.AssumptionViolatedException]) Warn(s"Test assumption in test $formattedTestClass.${red(method)}" + s" failed: $exceptionStr" + s"This assume should not pass, took $TIME_TAG sec") @@ -298,8 +302,8 @@ abstract class JUnitTest { private def formattedTestClass: String = formatClass(suiteUnderTestName, yellow) - private def exceptionClassInfo(show: Boolean, fullName: String) = { - if (show) formatClass(fullName, red) + ": " + private def exceptionClassInfo(show: Boolean, clazz: ThrowableClass) = { + if (show) formatClass(clazz.getName, red) + ": " else "" } From e259939196706f9a7d69e909db15e504b25f379d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 28 May 2018 00:11:10 +0200 Subject: [PATCH 0754/2665] Fix #2801: Enable regression test on JVM 2.12.5+ and 2.13.0-M4+. The bug that we were not bug-compatible with was fixed upstream in https://github.com/scala/scala/pull/6131, which is available in 2.12.5+ and 2.13.0-M4+. --- .../scalajs/testsuite/compiler/RegressionTest.scala | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala index 772debde05..3a743d5575 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala @@ -162,8 +162,16 @@ class RegressionTest { } @Test def should_support_class_literals_for_existential_value_types_issue_218(): Unit = { - assumeFalse("Not bug-compatible with the JVM, issue #2801", - Platform.executingInJVM) + import Platform.scalaVersion + + assumeFalse("Affected by https://github.com/scala/bug/issues/10551", + Platform.executingInJVM && { + scalaVersion.startsWith("2.10.") || + scalaVersion.startsWith("2.11.") || + scalaVersion == "2.12.0" || scalaVersion == "2.12.1" || + scalaVersion == "2.12.2" || scalaVersion == "2.12.3" || + scalaVersion == "2.12.4" || scalaVersion == "2.13.0-M3" + }) assertEquals("org.scalajs.testsuite.compiler.RegressionTest$Bug218Foo", scala.reflect.classTag[Bug218Foo[_]].toString) From 07c2c6e07b391858c18cc782bebbc33b035a2f02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 28 May 2018 19:45:07 +0200 Subject: [PATCH 0755/2665] Fix #2192: Enable BaseBufferTest.compact() on the JVM for JDK >= 9. It turns out this test was failing on the JVM due to a bug in the JDK. Although there does not seem to be a public bug report for it, it was fixed in JDK 9. --- .../scalajs/testsuite/utils/Platform.scala | 2 ++ .../scalajs/testsuite/utils/Platform.scala | 4 +++- .../testsuite/niobuffer/BaseBufferTest.scala | 21 +++++++++++-------- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala index bead868114..4a88861f42 100644 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala +++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala @@ -24,6 +24,8 @@ object Platform { final val executingInJVMOnJDK7OrLower = false + final val executingInJVMOnJDK8OrLower = false + // Members that are only accessible from testSuite/js // (i.e. do no link on the JVM). diff --git a/test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala b/test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala index 2382bd18ab..97363a7566 100644 --- a/test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala +++ b/test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala @@ -14,10 +14,12 @@ object Platform { def executingInJVMOnJDK7OrLower: Boolean = jdkVersion <= 7 + def executingInJVMOnJDK8OrLower: Boolean = jdkVersion <= 8 + private lazy val jdkVersion = { val v = System.getProperty("java.version") if (v.startsWith("1.")) Integer.parseInt(v.drop(2).takeWhile(_.isDigit)) - else throw new Exception("Unknown java.version format") + else Integer.parseInt(v.takeWhile(_.isDigit)) } def executingInRhino: Boolean = false diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BaseBufferTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BaseBufferTest.scala index f8e6cb89c1..237672eeb7 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BaseBufferTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BaseBufferTest.scala @@ -11,6 +11,8 @@ import java.nio.{ReadOnlyBufferException, BufferUnderflowException, InvalidMarkE import org.junit.Test import org.junit.Assert._ +import org.junit.Assume._ + import org.scalajs.testsuite.niobuffer.ByteBufferFactories.SlicedAllocByteBufferFactory import org.scalajs.testsuite.utils.AssertThrows._ @@ -295,21 +297,22 @@ abstract class BaseBufferTest { } @Test def compact(): Unit = { + assumeFalse("Affected by a bug in the JDK.", + executingInJVMOnJDK8OrLower && + factory.isInstanceOf[BufferFactory.ByteBufferViewFactory]) + if (!createsReadOnly) { val buf = withContent(10, elemRange(0, 10): _*) buf.position(6) buf.mark() - if (!executingInJVM) { - // throws IllegalArgumentException on JVM when executing compact() - buf.compact() - assertEquals(4, buf.position()) - assertEquals(10, buf.limit()) - expectThrows(classOf[InvalidMarkException], buf.reset()) + buf.compact() + assertEquals(4, buf.position()) + assertEquals(10, buf.limit()) + expectThrows(classOf[InvalidMarkException], buf.reset()) - for (i <- 0 until 4) - assertEquals(elemFromInt(i + 6), buf.get(i)) - } + for (i <- 0 until 4) + assertEquals(elemFromInt(i + 6), buf.get(i)) } else { val buf = allocBuffer(10) expectThrows(classOf[ReadOnlyBufferException], buf.compact()) From 46435b537d9720576862d5cf74263f73b0b9f6ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 28 May 2018 20:35:50 +0200 Subject: [PATCH 0756/2665] Fix #2190: Relax the expected kind of exception in the test. According to the Javadoc, both `ReadOnlyBufferException` and `BufferOverflowException` are valid outcomes. The JVM implementation sometimes throws one and sometimes the other. --- .../scalajs/testsuite/niobuffer/BaseBufferTest.scala | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BaseBufferTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BaseBufferTest.scala index 237672eeb7..52793ce68f 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BaseBufferTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BaseBufferTest.scala @@ -288,9 +288,17 @@ abstract class BaseBufferTest { assertEquals(0, buf.position()) assertEquals(elemFromInt(0), buf.get(0)) + /* Trying to put an array too large into a read-only buffer can either + * throw a ReadOnlyBufferException or a BufferOverflowException. The spec + * does not favor one or the other, and on the JVM, in some cases it is + * one and in some other cases the other. + */ buf.position(8) - if (!executingInJVM) // throws BufferOverflowException on JVM - expectThrows(classOf[ReadOnlyBufferException], buf.put(Array[ElementType](6, 7, 12))) + val exception = + expectThrows(classOf[RuntimeException], buf.put(Array[ElementType](6, 7, 12))) + assertTrue( + exception.isInstanceOf[ReadOnlyBufferException] || + exception.isInstanceOf[BufferOverflowException]) assertEquals(8, buf.position()) assertEquals(elemFromInt(0), buf.get(8)) } From 521e28adf80382387ac4fa19702a55e05fd03b07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 28 May 2018 21:07:04 +0200 Subject: [PATCH 0757/2665] Fix #2064: Disable the failing test only for `CopyOnWriteArrayList`. The Javadoc of `CopyOnWriteArrayList.subList` specifically says that the scenario we were testing there is undefined behavior. We must therefore not even attempt the call for `CopyOnWriteArrayList`s, but it works for other kinds of lists. --- .../org/scalajs/testsuite/javalib/util/ListTest.scala | 9 ++++----- .../util/concurrent/CopyOnWriteArrayListTest.scala | 2 -- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ListTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ListTest.scala index f060c440ae..693fdf50ca 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ListTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ListTest.scala @@ -11,7 +11,6 @@ import org.junit.Test import org.junit.Assert._ import org.scalajs.testsuite.utils.AssertThrows._ -import org.scalajs.testsuite.utils.Platform.executingInJVM import java.{util => ju} @@ -354,10 +353,10 @@ trait ListTest extends CollectionTest { assertEquals("nine", al1.get(0)) for (i <- 0 until 3) { assertEquals(al.get(2 + i), al1.get(i)) - if (!executingInJVM) { - /* CopyOnWriteArrayList throws a ConcurrentModificationException - * on the JVM. - * issue #2064: not solved + if (!al.isInstanceOf[ju.concurrent.CopyOnWriteArrayList[_]]) { + /* For CopyOnWriteArrayList, accessing al0 after al has been modified + * through al1 (i.e., through anything bug al0 itself) is undefined + * behavior. */ assertEquals(al0.get(2 + i), al1.get(i)) } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/CopyOnWriteArrayListTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/CopyOnWriteArrayListTest.scala index b4c58153fd..ead4b20004 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/CopyOnWriteArrayListTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/CopyOnWriteArrayListTest.scala @@ -16,8 +16,6 @@ import org.scalajs.testsuite.javalib.util.{ListFactory, ListTest} import scala.collection.JavaConverters._ -import org.scalajs.testsuite.utils.Platform.executingInJVM - import scala.reflect.ClassTag class CopyOnWriteArrayListTest extends ListTest { From c8c86a9f32a1074fdab724a6b3b74fff60e67ef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 28 May 2018 22:05:53 +0200 Subject: [PATCH 0758/2665] Fix #2050: More accurately test flushing of `OutputStreamWriter`. There is nothing that specifies that `flush()` itself must be called to flush the underlying `OutputStream`. `OutputStreamWriter` can instead rely on the fact that calling `close()` is supposed to effectively flush the underlying stream as well. Instead of testing the `flushed` flag of our `MockByteArrayOutputStream`, which is designed to test whether `flush()` itself has been called, we verify that the bytes have actually made their way to the mock output stream. --- .../testsuite/javalib/io/OutputStreamWriterTest.scala | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/OutputStreamWriterTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/OutputStreamWriterTest.scala index 2f9324ed02..0dff16346b 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/OutputStreamWriterTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/OutputStreamWriterTest.scala @@ -13,7 +13,6 @@ import org.junit.Test import org.junit.Assert._ import org.scalajs.testsuite.utils.AssertThrows._ -import org.scalajs.testsuite.utils.Platform.executingInJVM class OutputStreamWriterTest { private def newOSWriter(): (OutputStreamWriter, MockByteArrayOutputStream) = { @@ -27,8 +26,10 @@ class OutputStreamWriterTest { bos.write(1) osw.write("ABC") assertFalse(bos.flushed) + osw.flush() assertTrue(bos.flushed) + assertArrayEquals(Array[Byte](1, 'A', 'B', 'C'), bos.toByteArray) } @Test def close(): Unit = { @@ -38,9 +39,8 @@ class OutputStreamWriterTest { assertFalse(bos.flushed) osw.close() - if (!executingInJVM) - assertTrue(bos.flushed) assertTrue(bos.closed) + assertArrayEquals(Array[Byte](1, 'A', 'B', 'C'), bos.toByteArray) // can double-close without error osw.close() @@ -64,8 +64,6 @@ class OutputStreamWriterTest { assertEquals(0, bos.size) // write() methods should buffer osw.flush() } - if (!executingInJVM) - assertTrue(bos.flushed) assertArrayEquals(expected.map(_.toByte), bos.toByteArray) } From 902b33ce80f4b6c61f3411804fc6ef1e732a7781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 6 Jun 2018 12:57:40 +0200 Subject: [PATCH 0759/2665] Optimize switch-matches that have 0 or 1 case. They come up in reasonable source code that use `match`es as a convenience for a sequence of `if`s, or with patterns such as someComputation() match { case -1 => doOneThing() case n => doAnotherThing(n) } The simplification is done in the compiler rather than the optimizer, because it helps the optimizer to directly receive the `If`s or `Block`s. Moreover, there is no optimization that the optimizer could do that would turn a non-optimizable match into an optimizable one, so we're not losing any optimization opportunity by doing it only once in the compiler. --- .../org/scalajs/nscplugin/GenJSCode.scala | 42 ++++++++++++++++--- .../scalajs/nscplugin/test/MatchASTTest.scala | 29 +++++++++++++ 2 files changed, 66 insertions(+), 5 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala index ccfebf4625..9285fc2a71 100644 --- a/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala @@ -1911,9 +1911,12 @@ abstract class GenJSCode extends plugins.PluginComponent */ implicit val pos = tree.pos tree match { - case js.Block(stats :+ expr) => js.Block(stats :+ exprToStat(expr)) - case _:js.Literal | js.This() => js.Skip() - case _ => tree + case js.Block(stats :+ expr) => + js.Block(stats :+ exprToStat(expr)) + case _:js.Literal | _:js.This | _:js.VarRef => + js.Skip() + case _ => + tree } } @@ -3213,8 +3216,37 @@ abstract class GenJSCode extends plugins.PluginComponent val elseClause = optElseClause.getOrElse( throw new AssertionError("No elseClause in pattern match")) + /* Builds a `js.Match`, but simplifies it to a `js.If` if there is only + * one case with one alternative, and to a `js.Block` if there is no case + * at all. This happens in practice in the standard library. Having no + * case is a typical product of `match`es that are full of + * `case n if ... =>`, which are used instead of `if` chains for + * convenience and/or readability. + */ + def buildMatch(selector: js.Tree, + cases: List[(List[js.IntLiteral], js.Tree)], + default: js.Tree, tpe: jstpe.Type): js.Tree = { + cases match { + case Nil => + /* Completely remove the Match. Preserve the side-effects of + * `selector`. + */ + js.Block(exprToStat(selector), default) + + case (uniqueAlt :: Nil, caseRhs) :: Nil => + /* Simplify the `match` as an `if`, so that the optimizer has less + * work to do, and we emit less code at the end of the day. + */ + js.If(js.BinaryOp(js.BinaryOp.Int_==, selector, uniqueAlt), + caseRhs, default)(tpe) + + case _ => + js.Match(selector, cases, default)(tpe) + } + } + optElseClauseLabel.fold[js.Tree] { - js.Match(expr, clauses.reverse, elseClause)(resultType) + buildMatch(expr, clauses.reverse, elseClause, resultType) } { elseClauseLabel => val matchResultLabel = freshLocalIdent("matchResult") val patchedClauses = for ((alts, body) <- clauses) yield { @@ -3226,7 +3258,7 @@ abstract class GenJSCode extends plugins.PluginComponent } js.Labeled(matchResultLabel, resultType, js.Block(List( js.Labeled(elseClauseLabel, jstpe.NoType, { - js.Match(expr, patchedClauses.reverse, js.Skip())(jstpe.NoType) + buildMatch(expr, patchedClauses.reverse, js.Skip(), jstpe.NoType) }), elseClause ))) diff --git a/compiler/src/test/scala/org/scalajs/nscplugin/test/MatchASTTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/MatchASTTest.scala index 5d36496675..8ffa6a828d 100644 --- a/compiler/src/test/scala/org/scalajs/nscplugin/test/MatchASTTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/MatchASTTest.scala @@ -37,4 +37,33 @@ class MatchASTTest extends JSASTTest { } } + @Test + def matchWithZeroAlternativeInSwitch: Unit = { + """ + object A { + def foo(x: Int): Int = (x: @scala.annotation.switch) match { + case n if n > 5 => n + case n if n >= 0 => 0 + case n => -n + } + } + """.hasNot("any match") { + case js.Match(_, _, _) => + } + } + + @Test + def matchWithOneAlternativeInSwitch: Unit = { + """ + object A { + def foo(x: Int): Int = (x: @scala.annotation.switch) match { + case -1 => 10 + case n => n + } + } + """.hasNot("any match") { + case js.Match(_, _, _) => + } + } + } From 7d3f191abc1e3bcb1c35430e31f1479c7af4d984 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Mon, 11 Jun 2018 20:50:36 +0200 Subject: [PATCH 0760/2665] Log the time it takes to update the IR cache --- .../scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index dc11811f9f..06ba7dec12 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -221,7 +221,9 @@ private[sbtplugin] object ScalaJSPluginInternal { val cache = scalaJSIRCache.value val classpath = Attributed.data(fullClasspath.value) val irContainers = FileScalaJSIRContainer.fromClasspath(classpath) - val irFiles = cache.cached(irContainers) + val log = sbtLogger2ToolsLogger(streams.value.log) + val irFiles = log.time("Update IR cache")(cache.cached(irContainers)) + Attributed .blank[Seq[VirtualScalaJSIRFile]](irFiles) .put(scalaJSSourceFiles, irContainers.map(_.file)) From d07204e2c1184ddbb43069dce4b7ae2dc0377c42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 12 Jun 2018 16:45:00 +0200 Subject: [PATCH 0761/2665] [no-master] Fix #3373: Upgrade to org.mozilla's Rhino v1.7.6. This is the last version that does not introduce `Math.imul`. The implementation added in Rhino 1.7.7, and still used in 1.7.9, is faulty. See https://github.com/mozilla/rhino/issues/448. --- project/Build.scala | 4 ++-- project/build.sbt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index fdcd78e610..8afa84f79b 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -718,7 +718,7 @@ object Build { ) ++ Seq( name := "Scala.js JS Envs", libraryDependencies ++= Seq( - "io.apigee" % "rhino" % "1.7R5pre4", + "org.mozilla" % "rhino" % "1.7.6", "org.webjars" % "envjs" % "1.2" ) ++ ScalaJSPluginInternal.phantomJSJettyModules.map(_ % "provided"), previousArtifactSetting, @@ -1798,7 +1798,7 @@ object Build { "org.scala-lang.modules" %% "scala-partest" % "1.1.4" }, "org.scala-js" % "closure-compiler-java-6" % "v20160517", - "io.apigee" % "rhino" % "1.7R5pre4", + "org.mozilla" % "rhino" % "1.7.6", "com.googlecode.json-simple" % "json-simple" % "1.1.1" exclude("junit", "junit") ) ++ ( parallelCollectionsDependencies(scalaVersion.value) diff --git a/project/build.sbt b/project/build.sbt index b46dc04ee6..cc4e4884ca 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -8,7 +8,7 @@ addSbtPlugin("org.portable-scala" % "sbt-platform-deps" % "1.0.0") libraryDependencies += "org.scala-js" % "closure-compiler-java-6" % "v20160517" -libraryDependencies += "io.apigee" % "rhino" % "1.7R5pre4" +libraryDependencies += "org.mozilla" % "rhino" % "1.7.6" libraryDependencies += "org.webjars" % "envjs" % "1.2" From 8931830a04bb9f6064bcf87f1184874a05c0a18d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 14 Jun 2018 16:15:26 +0200 Subject: [PATCH 0762/2665] Use WeakHashMap as the non-existent parent in DummyParentsTest. Previously we used `scala.concurrent.forkjoin.ForkJoinWorkerThread`, but that class does not exist in Scala 2.13.0-M4 anymore. --- .../testsuite/noircheck/DummyParentsTest.scala | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/no-ir-check-test/src/test/scala/org/scalajs/testsuite/noircheck/DummyParentsTest.scala b/no-ir-check-test/src/test/scala/org/scalajs/testsuite/noircheck/DummyParentsTest.scala index 588ad4752a..8585a02d04 100644 --- a/no-ir-check-test/src/test/scala/org/scalajs/testsuite/noircheck/DummyParentsTest.scala +++ b/no-ir-check-test/src/test/scala/org/scalajs/testsuite/noircheck/DummyParentsTest.scala @@ -8,23 +8,20 @@ package org.scalajs.testsuite.noircheck import org.junit.Test +import org.junit.Assert._ class DummyParentsTest { @Test def linking_stages_should_provide_dummy_parents_if_required(): Unit = { - import scala.concurrent.forkjoin._ - - // scala.concurrent.forkjoin.ForkJoinWorkerThread is not defined - class DummyFJWorkerThread extends ForkJoinWorkerThread(null) { - override def onStart(): Unit = { /* something */ } - } + // java.util.WeakHashMap is not defined + class DummyWeakHashMap extends java.util.WeakHashMap val x = "1".toInt if (x + x < 0) { - // Ensure DummyFuture is not DCEd, but never instantiated - new DummyFJWorkerThread() + // Ensure DummyWeakHashMap is not DCEd, but never instantiated + assertEquals(0, new DummyWeakHashMap().size()) } } From 5bcd17484fda171d5a85b6419a232f4b57c0aafd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 14 Jun 2018 14:01:03 +0200 Subject: [PATCH 0763/2665] Add a partial CI for Scala 2.13.0-M4. The partial CI avoids everything that would involve compiling the tools with 2.13.0-M4 (including partest), since it is not supported yet. --- Jenkinsfile | 6 ++++++ ci/checksizes.sh | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index f8c4961760..cfa8cea200 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -412,6 +412,7 @@ def otherScalaVersions = [ "2.12.3", "2.12.4" ] +def limitedCIScalaVersions = ["2.13.0-M4"] // The 'quick' matrix def quickMatrix = [] @@ -432,6 +433,11 @@ mainScalaVersions.each { scalaVersion -> quickMatrix.add([task: "partest-fastopt", scala: scalaVersion, java: javaVersion]) } } +limitedCIScalaVersions.each { scalaVersion -> + quickMatrix.add([task: "main", scala: scalaVersion, java: mainJavaVersion]) + quickMatrix.add([task: "test-suite-ecma-script5", scala: scalaVersion, java: mainJavaVersion, testSuite: "testSuite"]) + quickMatrix.add([task: "test-suite-ecma-script6", scala: scalaVersion, java: mainJavaVersion, testSuite: "testSuite"]) +} allJavaVersions.each { javaVersion -> quickMatrix.add([task: "tools-cli-stubs-sbtplugin", scala: "2.10.7", java: javaVersion]) if (javaVersion != "1.6") { diff --git a/ci/checksizes.sh b/ci/checksizes.sh index e4ab7f1438..a57f383dbb 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -17,6 +17,9 @@ case $FULLVER in 2.13.0-M3) VER=2.13.0-M3 ;; + 2.13.0-M4) + VER=2.13.0-M4 + ;; 2.10.3|2.10.4|2.10.5|2.10.6|2.10.7|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7|2.11.8|2.11.11|2.12.0|2.12.1|2.12.2|2.12.3|2.12.4) echo "Ignoring checksizes for Scala $FULLVER" exit 0 @@ -60,6 +63,12 @@ case $FULLVER in REVERSI_PREOPT_GZ_EXPECTEDSIZE=77000 REVERSI_OPT_GZ_EXPECTEDSIZE=33000 ;; + 2.13.0-M4) + REVERSI_PREOPT_EXPECTEDSIZE=580000 + REVERSI_OPT_EXPECTEDSIZE=136000 + REVERSI_PREOPT_GZ_EXPECTEDSIZE=77000 + REVERSI_OPT_GZ_EXPECTEDSIZE=34000 + ;; esac echo "Checksizes: Scala version: $FULLVER" From 8b9fad3b95e694187fda4ccf3a5aca6275b9c319 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 14 Jun 2018 15:52:16 +0200 Subject: [PATCH 0764/2665] Complete review of the readme and developing/contributing guides. --- CONTRIBUTING.md | 14 ++++---- DEVELOPING.md | 92 ++++++++++++++++++++++++++++++++++--------------- README.md | 4 +-- 3 files changed, 73 insertions(+), 37 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index abf92a2e1b..f980a73048 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,19 +17,19 @@ Please consult and follow our [coding style guide](./CODINGSTYLE.md). This the general workflow for contributing to Scala.js. 1. Make sure you have signed the - [Scala CLA](http://typesafe.com/contribute/cla/scala). + [Scala CLA](https://www.lightbend.com/contribute/cla/scala). If not, sign it. 2. You should always perform your work in its own Git branch. The branch should be given a descriptive name that explains its intent. 3. When the feature or fix is completed you should open a - [Pull Request](https://help.github.com/articles/using-pull-requests) on GitHub. + [Pull Request](https://help.github.com/articles/about-pull-requests/) on GitHub. 4. The Pull Request should be reviewed by other maintainers (as many as feasible/practical), among which at least one core developer. Independent contributors can also participate in the review process, and are encouraged to do so. 5. After the review, you should resolve issues brought up by the reviewers as needed (amending or adding commits to address reviewers' comments), iterating until - the reviewers give their thumbs up, the "LGTM" (acronym for "Looks Good To Me"). + the reviewers give their thumbs up by approving the Pull Request. 6. Once the code has passed review the Pull Request can be merged into the distribution. ## Pull Request Requirements @@ -38,8 +38,8 @@ In order for a Pull Request to be considered, it has to meet these requirements: 1. Live up to the current code standard: - Follow the [coding style](./CODINGSTYLE.md) - - Not violate [DRY](http://programmer.97things.oreilly.com/wiki/index.php/Don%27t_Repeat_Yourself). - - [Boy Scout Rule](http://programmer.97things.oreilly.com/wiki/index.php/The_Boy_Scout_Rule) should be applied. + - Not violate [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself). + - The [Boy Scout Rule](https://medium.com/@biratkirat/step-8-the-boy-scout-rule-robert-c-martin-uncle-bob-9ac839778385) should be applied. 2. Be accompanied by appropriate tests. 3. Be issued from a branch *other than master* (PRs coming from master will not be accepted, as we've had trouble in the past with such PRs) @@ -52,7 +52,7 @@ All code contributed to the user-facing standard library (the `library/` directory) should come accompanied with documentation. Pull requests containing undocumented code will not be accepted. -Code contributed to the internals (compiler, tools, JS environments, etc.) +Code contributed to the internals (compiler, IR, linker, JS environments, etc.) should come accompanied by internal documentation if the code is not self-explanatory, e.g., important design decisions that other maintainers should know about. @@ -69,7 +69,7 @@ doing merges/rebases etc.) then please do not commit it all but rewrite the history by squashing the commits into **one commit per useful unit of change**, each accompanied by a detailed commit message. For more info, see the article: -[Git Workflow](http://sandofsky.com/blog/git-workflow.html). +[Git Workflow](https://sandofsky.com/blog/git-workflow.html). Additionally, every commit should be able to be used in isolation--that is, each commit must build and pass all tests. diff --git a/DEVELOPING.md b/DEVELOPING.md index d14dfabd1f..55bc21f622 100644 --- a/DEVELOPING.md +++ b/DEVELOPING.md @@ -10,21 +10,34 @@ source code of the Oracle JDK or OpenJDK!*** This is for license considerations: these JDKs are under a GPL-based license, which is not compatible with our BSD 3-clause license. -The only existing JDK source code that we can look at is the dead Apache -Harmony project. +It is also recommended *not to look at any other JDK implementation* (such as +Apache Harmony), to minimize the chance of copyright debate. ## Building -Scala.js is entirely built with [sbt](http://www.scala-sbt.org/). -To build a local version of the compiler and standard library, run +Scala.js is entirely built with [sbt](https://www.scala-sbt.org/), and also +requires [Node.js](https://nodejs.org/en/) to be installed. For complete +support, Node.js >= 10.0.0 is required. - > library/package +The first time, or in the rare events where `package.json` changes +([history](https://github.com/scala-js/scala-js/commits/master/package.json)), +you need to run -To test your changes, run + $ npm install + +from your shell. If you *really* do not want to do this, you can avoid that +step, but you will need to use +`set MyScalaJSPlugin.wantSourceMaps in testSuite := false` within sbt to +by-pass source-map-related tests. In addition, bootstrap tests will not pass. + +Otherwise, everything happens within sbt. + +Run the normal test suite using the entire Scala.js toolchain using > testSuite/test -or test your tests on the JVM. +In order to test the tests themselves, run the cross-compiling tests on the JVM +with: > testSuiteJVM/test @@ -33,8 +46,9 @@ If you have changed the IR or the compiler, you typically need to > clean before testing anew. -If you have changed the IR, the tools, the JS environments or the sbt plugin, -you typically need to + +If you have changed the IR, the linker, the JS environments, the test adapter +or the sbt plugin, you typically need to > reload @@ -42,12 +56,6 @@ To test in fullOpt stage: > set scalaJSStage in Global := FullOptStage -When running with Node.js, by default, the test suite requires the -`source-map-support` package to be installed in `npm`. You can bypass the -source map tests locally with this setting: - - > set jsEnv in testSuite := NodeJSEnv().value.withSourceMap(false) - There are also a few additional tests in a separate testing project: > testSuiteEx/test @@ -66,6 +74,10 @@ or, more typically, > partestSuite/testOnly -- --fastOpt +The JUnit tests from scala/scala can be run with + + > scalaTestSuite/test + ## Eclipse If you want to develop in Eclipse, use @@ -73,7 +85,7 @@ If you want to develop in Eclipse, use the build by default are not suited for Eclipse. You can create *somewhat* appropriate projects with: - $ sbt tools/sources + $ sbt linker/sources $ GENERATING_ECLIPSE=true sbt "eclipse with-source=true" You will still have to fix a few things: @@ -89,33 +101,56 @@ The repository is organized as follows: * `ir/` The Intermediate Representation, produced by the compiler and consumed by the linker * `compiler/` The scalac compiler plugin -* `tools/` The linker, optimizer, verifier, etc.: everything that happens at link time +* `io/` Virtual I/O abstractions +* `logging/` A tiny logging API +* `linker/` The linker, optimizer, verifier, etc.: everything that happens at link time ### Library * `library/` The Scala.js standard library (everything inside `scala.scalajs.*`) * `javalanglib/` Implementation in Scala.js of the classes in `java.lang.*` * `javalib/` Implementation in Scala.js of other classes in `java.*` -* `javalib-ex/` Some more Java classes with non-standard dependencies * `scalalib/` Almost void project for recompiling the Scala library for Scala.js * `library-aux/` A few files of the Scala library that need to be compiled separately -All of these, except `javalib-ex`, are packaged in `scalajs-library.jar` as part -of `library/package`. +All of these are packaged in `scalajs-library.jar`. -### sbt plugin +### JS environments -Note that the sbt plugin depends on the IR and the tools. +The JS environments are JVM libraries that abstract the details of using a +JavaScript engine to run JS code. * `js-envs/` The generic definitions of JavaScript environments and runners * `nodejs-env/` The Node.js environment + +Other JS environments are developed in separate repositories under the +`scala-js` organization. + +### Testing infrastructure + +There is a generic infrastructure that maps the sbt-testing-interface API +across the JVM/JS boundary, so that Scala.js testing frameworks can be piloted +from JVM processes such as sbt. + +* `test-interface/` JS side of the bridge, as well as the JS definition of the + sbt-testing-interface API +* `test-adapter/` JVM side of the bridge + +This repository also contains a specific implementation of JUnit: + +* `junit-runtime/` The run-time library for JUnit +* `junit-plugin/` The JUnit compiler plugin + +### sbt plugin + * `sbt-plugin/` The sbt plugin itself ### Testing projects * `test-suite/` The main test suite of Scala.js -* `javalib-ex-test-suite/` The test suite for the javalib-ex +* `test-suite-ex/` Additional tests * `partest-suite/` The partest suite of Scala +* `scala-test-suite/` The JUnit suite of Scala ### Example projects/sandboxes @@ -123,14 +158,15 @@ Note that the sbt plugin depends on the IR and the tools. * `examples/reversi/` The historical Reversi demo - we use it to track the impact of changes on the emitted code size * `examples/testing/` A simple project with tests using the DOM, mostly used to test `testHtml` with DOM interaction -These example projects also have HTML pages to run them in real browsers. +The helloworld and reversi also have HTML pages to run them in real browsers. ### The build itself The build itself contains the entire sbt plugin (and all its dependencies) as part of its sources. -If you change any of the IR, the tools, the JS environments or the sbt plugin, -chances are you need to `reload` the build for your changes to take effect. +If you change any of the IR, virtual IO, logging API, linker, JS environments, +test adapter, or the sbt plugin itself, chances are you need to `reload` the +build for your changes to take effect. ## Publish locally @@ -140,5 +176,5 @@ following incantations. > ++SCALA_VERSION > ;compiler/publishLocal;library/publishLocal;testInterface/publishLocal;stubs/publishLocal;jUnitRuntime/publishLocal;jUnitPlugin/publishLocal - > ++2.10.6 - > ;ir/publishLocal;tools/publishLocal;jsEnvs/publishLocal;jsEnvsTestKit/publishLocal;nodeJSEnv/publishLocal;testAdapter/publishLocal;sbtPlugin/publishLocal + > ++2.10.7 + > ;ir/publishLocal;io/publishLocal;logging/publishLocal;linker/publishLocal;jsEnvs/publishLocal;jsEnvsTestKit/publishLocal;nodeJSEnv/publishLocal;testAdapter/publishLocal;sbtPlugin/publishLocal diff --git a/README.md b/README.md index e56fb732be..9de62451e7 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ This is the repository for -[Scala.js, the Scala to JavaScript compiler](http://www.scala-js.org/). +[Scala.js, the Scala to JavaScript compiler](https://www.scala-js.org/). * [Report an issue](https://github.com/scala-js/scala-js/issues) * [Developer documentation](./DEVELOPING.md) @@ -8,4 +8,4 @@ This is the repository for ## License Scala.js is distributed under the -[Scala License](http://www.scala-lang.org/license.html). +[Scala License](https://www.scala-lang.org/license.html). From e365623daa3c3798eaf85bf050464b08172ec8a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 17 Jun 2018 13:07:30 +0200 Subject: [PATCH 0765/2665] Fix malformed input length for lone high surrogate in UTF-16. If a high surrogate is not followed by a low surrogate, our implementation reported a malformed input of length 2 (counted in bytes). On the JVM, this reports a malformed input of length 4, hence also swallowing the next 2 bytes, even if they could be interpreted as the beginning of a valid UTF-16 sequence. This commit is a step towards fixing #2041. --- .../scalajs/niocharset/UTF_16_Common.scala | 2 +- .../testsuite/niocharset/UTF16Test.scala | 24 ++++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/niocharset/UTF_16_Common.scala b/library/src/main/scala/scala/scalajs/niocharset/UTF_16_Common.scala index 5bac2120bb..d1e6681807 100644 --- a/library/src/main/scala/scala/scalajs/niocharset/UTF_16_Common.scala +++ b/library/src/main/scala/scala/scalajs/niocharset/UTF_16_Common.scala @@ -92,7 +92,7 @@ private[niocharset] abstract class UTF_16_Common protected ( if (!Character.isLowSurrogate(c2)) { in.position(in.position() - 4) - CoderResult.malformedForLength(2) + CoderResult.malformedForLength(4) } else { if (out.remaining < 2) { in.position(in.position() - 4) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/UTF16Test.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/UTF16Test.scala index 6321c4b960..412d98c29f 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/UTF16Test.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/UTF16Test.scala @@ -14,8 +14,6 @@ import BaseCharsetTest._ import org.junit.Test -import org.scalajs.testsuite.utils.Platform.executingInJVM - abstract class BaseUTF16Test(charset: Charset) extends BaseCharsetTest(charset) { @Test def decode(): Unit = { // ASCII characters @@ -47,21 +45,25 @@ abstract class BaseUTF16Test(charset: Charset) extends BaseCharsetTest(charset) testDecode(bb"dfff")(Malformed(2)) // High UTF-16 surrogates not followed by low surrogates - if (!executingInJVM) { - testDecode(bb"d800 0041")(Malformed(2), cb"A") - testDecode(bb"d800 d800")(Malformed(2), Malformed(2)) - testDecode(bb"d800 d835 dcd7")(Malformed(2), cb"\ud835\udcd7") - testDecode(bb"dbff 0041")(Malformed(2), cb"A") - testDecode(bb"dbff db8f")(Malformed(2), Malformed(2)) - testDecode(bb"dbff d835 dcd7")(Malformed(2), cb"\ud835\udcd7") - } + testDecode(bb"d800 0041 0042")(Malformed(4), cb"B") + testDecode(bb"d800 d800 0042")(Malformed(4), cb"B") + testDecode(bb"d800 d835 dcd7 0042 0043")(Malformed(4), Malformed(2), cb"BC") + testDecode(bb"dbff 0041 0042")(Malformed(4), cb"B") + testDecode(bb"dbff db8f 0042")(Malformed(4), cb"B") + testDecode(bb"dbff d835 dcd7 0042")(Malformed(4), Malformed(2), cb"B") + testDecode(bb"dbff 0041 d835 dcd7")(Malformed(4), cb"\ud835\udcd7") + + // Low UTF-16 surrogates not preceded by high surrogates + testDecode(bb"0041 dcd7 0042")(cb"A", Malformed(2), cb"B") + testDecode(bb"0041 dcd7 d835 dcd7")(cb"A", Malformed(2), cb"\ud835\udcd7") // Lonely byte at the end testDecode(bb"0041 41")(cb"A", Malformed(1)) + testDecode(bb"d835 41")(Malformed(3)) } @Test def encode(): Unit = { - // ASCII characters + // ASCII characters testEncode(cb"Bonjour")(bb"0042 006f 006e 006a 006f 0075 0072") // Other characters without surrogate pairs From 508200a10dc42fced40b04afeebf94fd91a99823 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 17 Jun 2018 14:23:45 +0200 Subject: [PATCH 0766/2665] Fix malformed input length for too-long sequences in UTF-8. If a multi-byte UTF-8 sequence encodes a code point that could have been encoded using a smaller sequence, it is an error. Our implementation reported a malformed input of length N in that case, where N is the length of the sequence. However, the JVM implementation always reports a malformed input of length 1 for this error. This commit fixes the discrepancy. This fix is the last step to fixing #2041. --- .../scala/scalajs/niocharset/UTF_8.scala | 11 ++- .../testsuite/niocharset/UTF8Test.scala | 98 +++++++++---------- 2 files changed, 51 insertions(+), 58 deletions(-) diff --git a/library/src/main/scala/scala/scalajs/niocharset/UTF_8.scala b/library/src/main/scala/scala/scalajs/niocharset/UTF_8.scala index bf19bb02f8..39106dc3cb 100644 --- a/library/src/main/scala/scala/scalajs/niocharset/UTF_8.scala +++ b/library/src/main/scala/scala/scalajs/niocharset/UTF_8.scala @@ -236,7 +236,7 @@ private[niocharset] object UTF_8 extends Charset("UTF-8", Array( // By construction, 0 <= codePoint <= 0x7ff < MIN_SURROGATE if (codePoint < 0x80) { // Should have been encoded with only 1 byte - DecodedMultiByte(CoderResult.malformedForLength(2)) + DecodedMultiByte(CoderResult.malformedForLength(1)) } else { DecodedMultiByte(codePoint.toChar) } @@ -251,10 +251,11 @@ private[niocharset] object UTF_8 extends Charset("UTF-8", Array( else { val codePoint = (((b1 & 0xf) << 12) | ((b2 & 0x3f) << 6) | (b3 & 0x3f)) // By construction, 0 <= codePoint <= 0xffff < MIN_SUPPLEMENTARY_CODE_POINT - if ((codePoint < 0x800) || - (codePoint >= MIN_SURROGATE && codePoint <= MAX_SURROGATE)) { + if (codePoint < 0x800) { // Should have been encoded with only 1 or 2 bytes - // or it is a surrogate, which is not a valid code point + DecodedMultiByte(CoderResult.malformedForLength(1)) + } else if (codePoint >= MIN_SURROGATE && codePoint <= MAX_SURROGATE) { + // It is a surrogate, which is not a valid code point DecodedMultiByte(CoderResult.malformedForLength(3)) } else { DecodedMultiByte(codePoint.toChar) @@ -276,7 +277,7 @@ private[niocharset] object UTF_8 extends Charset("UTF-8", Array( if (codePoint < 0x10000 || codePoint > MAX_CODE_POINT) { // It should have been encoded with 1, 2, or 3 bytes // or it is not a valid code point - DecodedMultiByte(CoderResult.malformedForLength(4)) + DecodedMultiByte(CoderResult.malformedForLength(1)) } else { // Here, we need to encode the code point as a surrogate pair. // http://en.wikipedia.org/wiki/UTF-16 diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/UTF8Test.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/UTF8Test.scala index 66c8826d12..b40d0acabb 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/UTF8Test.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/UTF8Test.scala @@ -15,8 +15,6 @@ import org.junit.Assert._ import BaseCharsetTest._ -import org.scalajs.testsuite.utils.Platform.executingInJVM - class UTF8Test extends BaseCharsetTest(Charset.forName("UTF-8")) { @Test def decode(): Unit = { def OutSeq(elems: OutPart[CharBuffer]*): Seq[OutPart[CharBuffer]] = @@ -37,7 +35,7 @@ class UTF8Test extends BaseCharsetTest(Charset.forName("UTF-8")) { // 4-byte characters testDecode(bb"f0 9d 93 97 f0 9d 93 ae f0 9d 93 b5 f0 9d 93 b5 f0 9d 93 b8")( - cb"\ud835\udcd7\ud835\udcee\ud835\udcf5\ud835\udcf5\ud835\udcf8") + cb"\ud835\udcd7\ud835\udcee\ud835\udcf5\ud835\udcf5\ud835\udcf8") testDecode(bb"")(cb"") @@ -61,10 +59,8 @@ class UTF8Test extends BaseCharsetTest(Charset.forName("UTF-8")) { // Here begin the sequences with at least one error // Code point too big - if (!executingInJVM) { - testDecode(bb"f4 90 80 80")(Malformed(4)) - testDecode(bb"41 f4 90 80 80 42")(cb"A", Malformed(4), cb"B") - } + testDecode(bb"f4 90 80 80")(Malformed(1), Malformed(1), Malformed(1), Malformed(1)) + testDecode(bb"41 f4 90 80 80 42")(cb"A", Malformed(1), Malformed(1), Malformed(1), Malformed(1), cb"B") // Unexpected continuation bytes (each is reported separately) testDecode(bb"80")(Malformed(1)) @@ -76,10 +72,8 @@ class UTF8Test extends BaseCharsetTest(Charset.forName("UTF-8")) { testDecode(bb"41 80 80 42 80 43")(cb"A", Malformed(1), Malformed(1), cb"B", Malformed(1), cb"C") // Lonely start characters, separated by spaces - if (!executingInJVM) { - testDecode(bb"${(0xc0 to 0xf4).flatMap(c => Seq(c, 32))}")( + testDecode(bb"${(0xc0 to 0xf4).flatMap(c => Seq(c, 32))}")( (0xc0 to 0xf4).flatMap(i => OutSeq(Malformed(1), cb" ")): _*) - } // Sequences with some continuation bytes missing testDecode(bb"c2")(Malformed(1)) @@ -90,60 +84,58 @@ class UTF8Test extends BaseCharsetTest(Charset.forName("UTF-8")) { testDecode(bb"f0 90 80")(Malformed(3)) // at the end of the buffer - #1537 testDecode(bb"c0")(Malformed(1)) - if (!executingInJVM) - testDecode(bb"e1 41")(Malformed(1), cb"A") + testDecode(bb"e1 41")(Malformed(1), cb"A") testDecode(bb"e1 80 42")(Malformed(2), cb"B") // and all of them concatenated testDecode(bb"c2 e0 e0 a0 f0 f0 90 f0 90 80")( - Seq(1, 1, 2, 1, 2, 3).map(Malformed(_)): _*) + Seq(1, 1, 2, 1, 2, 3).map(Malformed(_)): _*) // and with normal sequences interspersed testDecode(bb"c2 41 e0 41 e0 a0 41 f0 41 f0 90 41 f0 90 80 41")( - Seq(1, 1, 2, 1, 2, 3).flatMap(l => Seq[OutPart[CharBuffer]](Malformed(l), cb"A")): _*) + Seq(1, 1, 2, 1, 2, 3).flatMap(l => Seq[OutPart[CharBuffer]](Malformed(l), cb"A")): _*) // Impossible bytes testDecode(bb"fe")(Malformed(1)) testDecode(bb"ff")(Malformed(1)) testDecode(bb"fe fe ff ff")(Malformed(1), Malformed(1), Malformed(1), Malformed(1)) + // Old 5-byte and 6-byte starts - if (!executingInJVM) { - testDecode(bb"f8 80 80 80 af")( - Malformed(1), Malformed(1), Malformed(1), Malformed(1), Malformed(1)) - testDecode(bb"fc 80 80 80 80 af")( - Malformed(1), Malformed(1), Malformed(1), Malformed(1), Malformed(1), Malformed(1)) - - // Overlong sequences (encoded with more bytes than necessary) - // Overlong '/' - testDecode(bb"c0 af")(Malformed(2)) - testDecode(bb"e0 80 af")(Malformed(3)) - testDecode(bb"f0 80 80 af")(Malformed(4)) - // Maximum overlong sequences - testDecode(bb"c1 bf")(Malformed(2)) - testDecode(bb"e0 9f bf")(Malformed(3)) - testDecode(bb"f0 8f bf bf")(Malformed(4)) - // Overlong NUL - testDecode(bb"c0 80")(Malformed(2)) - testDecode(bb"e0 80 80")(Malformed(3)) - testDecode(bb"f0 80 80 80")(Malformed(4)) - - // Single UTF-16 surrogates - testDecode(bb"ed a0 80")(Malformed(3)) - testDecode(bb"ed ad bf")(Malformed(3)) - testDecode(bb"ed ae 80")(Malformed(3)) - testDecode(bb"ed af bf")(Malformed(3)) - testDecode(bb"ed b0 80")(Malformed(3)) - testDecode(bb"ed be 80")(Malformed(3)) - testDecode(bb"ed bf bf")(Malformed(3)) - - // Paired UTF-16 surrogates - testDecode(bb"ed a0 80 ed b0 80")(Malformed(3), Malformed(3)) - testDecode(bb"ed a0 80 ed bf bf")(Malformed(3), Malformed(3)) - testDecode(bb"ed ad bf ed b0 80")(Malformed(3), Malformed(3)) - testDecode(bb"ed ad bf ed bf bf")(Malformed(3), Malformed(3)) - testDecode(bb"ed ae 80 ed b0 80")(Malformed(3), Malformed(3)) - testDecode(bb"ed ae 80 ed bf bf")(Malformed(3), Malformed(3)) - testDecode(bb"ed af bf ed b0 80")(Malformed(3), Malformed(3)) - testDecode(bb"ed af bf ed bf bf")(Malformed(3), Malformed(3)) - } + testDecode(bb"f8 80 80 80 af")( + Malformed(1), Malformed(1), Malformed(1), Malformed(1), Malformed(1)) + testDecode(bb"fc 80 80 80 80 af")( + Malformed(1), Malformed(1), Malformed(1), Malformed(1), Malformed(1), Malformed(1)) + + // Overlong sequences (encoded with more bytes than necessary) + // Overlong '/' + testDecode(bb"c0 af")(Malformed(1), Malformed(1)) + testDecode(bb"e0 80 af")(Malformed(1), Malformed(1), Malformed(1)) + testDecode(bb"f0 80 80 af")(Malformed(1), Malformed(1), Malformed(1), Malformed(1)) + // Maximum overlong sequences + testDecode(bb"c1 bf")(Malformed(1), Malformed(1)) + testDecode(bb"e0 9f bf")(Malformed(1), Malformed(1), Malformed(1)) + testDecode(bb"f0 8f bf bf")(Malformed(1), Malformed(1), Malformed(1), Malformed(1)) + // Overlong NUL + testDecode(bb"c0 80")(Malformed(1), Malformed(1)) + testDecode(bb"e0 80 80")(Malformed(1), Malformed(1), Malformed(1)) + testDecode(bb"f0 80 80 80")(Malformed(1), Malformed(1), Malformed(1), Malformed(1)) + + // Single UTF-16 surrogates + testDecode(bb"ed a0 80")(Malformed(3)) + testDecode(bb"ed ad bf")(Malformed(3)) + testDecode(bb"ed ae 80")(Malformed(3)) + testDecode(bb"ed af bf")(Malformed(3)) + testDecode(bb"ed b0 80")(Malformed(3)) + testDecode(bb"ed be 80")(Malformed(3)) + testDecode(bb"ed bf bf")(Malformed(3)) + + // Paired UTF-16 surrogates + testDecode(bb"ed a0 80 ed b0 80")(Malformed(3), Malformed(3)) + testDecode(bb"ed a0 80 ed bf bf")(Malformed(3), Malformed(3)) + testDecode(bb"ed ad bf ed b0 80")(Malformed(3), Malformed(3)) + testDecode(bb"ed ad bf ed bf bf")(Malformed(3), Malformed(3)) + testDecode(bb"ed ae 80 ed b0 80")(Malformed(3), Malformed(3)) + testDecode(bb"ed ae 80 ed bf bf")(Malformed(3), Malformed(3)) + testDecode(bb"ed af bf ed b0 80")(Malformed(3), Malformed(3)) + testDecode(bb"ed af bf ed bf bf")(Malformed(3), Malformed(3)) } @Test def encode(): Unit = { From fba79d8a3d27a881c7da9e4d3b4ce15032690ca2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 4 Jun 2018 18:44:01 +0200 Subject: [PATCH 0767/2665] Impose the total ordering for Floats and Doubles in j.u.Arrays. Starting from Scala 2.13.0-M5, Floats and Doubles do not have a unique `Ordering` anymore. They have a `TotalOrdering` consistent with `java.lang.{Float,Double}.compare`, and an `IeeeOrdering` consistent with the comparison operators. The one we want in `java.util.Arrays` is the total ordering, according to the Javadoc. Since there is no way to easily get the total ordering across versions of Scala without warning, we simply redefine them as private implicit objects in `Arrays.scala`. The implementation is short and trivial, so that is easy to do. --- javalib/src/main/scala/java/util/Arrays.scala | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/javalib/src/main/scala/java/util/Arrays.scala b/javalib/src/main/scala/java/util/Arrays.scala index 24c74f7e02..84dd394d5b 100644 --- a/javalib/src/main/scala/java/util/Arrays.scala +++ b/javalib/src/main/scala/java/util/Arrays.scala @@ -18,6 +18,16 @@ object Arrays { } } + // Impose the total ordering of java.lang.Float.compare in Arrays + private implicit object FloatTotalOrdering extends Ordering[Float] { + def compare(x: Float, y: Float): Int = java.lang.Float.compare(x, y) + } + + // Impose the total ordering of java.lang.Double.compare in Arrays + private implicit object DoubleTotalOrdering extends Ordering[Double] { + def compare(x: Double, y: Double): Int = java.lang.Double.compare(x, y) + } + @noinline def sort(a: Array[Int]): Unit = sortImpl(a) From 6d6d50e84aa08bb74879e59d4a5916d977a89bcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 4 Jun 2018 19:00:22 +0200 Subject: [PATCH 0768/2665] Copy some overrides from 2.13 to 2.13.0-M4. Namely the overrides for `ScalaRunTime`, `Range`, `NumericRange` and `Enumeration`. So that we can later backport changes coming in 2.13.0-M5 to those two files. --- .../scala/Enumeration.scala | 302 ++++++++++ .../collection/immutable/NumericRange.scala | 409 +++++++++++++ .../scala/collection/immutable/Range.scala | 547 ++++++++++++++++++ .../scala/runtime/ScalaRunTime.scala | 282 +++++++++ 4 files changed, 1540 insertions(+) create mode 100644 scalalib/overrides-2.13.0-M4/scala/Enumeration.scala create mode 100644 scalalib/overrides-2.13.0-M4/scala/collection/immutable/NumericRange.scala create mode 100644 scalalib/overrides-2.13.0-M4/scala/collection/immutable/Range.scala create mode 100644 scalalib/overrides-2.13.0-M4/scala/runtime/ScalaRunTime.scala diff --git a/scalalib/overrides-2.13.0-M4/scala/Enumeration.scala b/scalalib/overrides-2.13.0-M4/scala/Enumeration.scala new file mode 100644 index 0000000000..cd2469466b --- /dev/null +++ b/scalalib/overrides-2.13.0-M4/scala/Enumeration.scala @@ -0,0 +1,302 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala + +import scala.collection.{ mutable, immutable, StrictOptimizedIterableOps, SpecificIterableFactory, View } +import java.lang.reflect.{ Method => JMethod, Field => JField } +import scala.reflect.NameTransformer._ +import scala.util.matching.Regex + +/** Defines a finite set of values specific to the enumeration. Typically + * these values enumerate all possible forms something can take and provide + * a lightweight alternative to case classes. + * + * Each call to a `Value` method adds a new unique value to the enumeration. + * To be accessible, these values are usually defined as `val` members of + * the enumeration. + * + * All values in an enumeration share a common, unique type defined as the + * `Value` type member of the enumeration (`Value` selected on the stable + * identifier path of the enumeration instance). + * + * @example {{{ + * // Define a new enumeration with a type alias and work with the full set of enumerated values + * object WeekDay extends Enumeration { + * type WeekDay = Value + * val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value + * } + * import WeekDay._ + * + * def isWorkingDay(d: WeekDay) = ! (d == Sat || d == Sun) + * + * WeekDay.values filter isWorkingDay foreach println + * // output: + * // Mon + * // Tue + * // Wed + * // Thu + * // Fri + * }}} + * + * @example {{{ + * // Example of adding attributes to an enumeration by extending the Enumeration.Val class + * object Planet extends Enumeration { + * protected case class Val(mass: Double, radius: Double) extends super.Val { + * def surfaceGravity: Double = Planet.G * mass / (radius * radius) + * def surfaceWeight(otherMass: Double): Double = otherMass * surfaceGravity + * } + * implicit def valueToPlanetVal(x: Value): Val = x.asInstanceOf[Val] + * + * val G: Double = 6.67300E-11 + * val Mercury = Val(3.303e+23, 2.4397e6) + * val Venus = Val(4.869e+24, 6.0518e6) + * val Earth = Val(5.976e+24, 6.37814e6) + * val Mars = Val(6.421e+23, 3.3972e6) + * val Jupiter = Val(1.9e+27, 7.1492e7) + * val Saturn = Val(5.688e+26, 6.0268e7) + * val Uranus = Val(8.686e+25, 2.5559e7) + * val Neptune = Val(1.024e+26, 2.4746e7) + * } + * + * println(Planet.values.filter(_.radius > 7.0e6)) + * // output: + * // Planet.ValueSet(Jupiter, Saturn, Uranus, Neptune) + * }}} + * + * @param initial The initial value from which to count the integers that + * identifies values at run-time. + * @author Matthias Zenger + */ +@SerialVersionUID(8476000850333817230L) +abstract class Enumeration (initial: Int) extends Serializable { + thisenum => + + def this() = this(0) + + /* Note that `readResolve` cannot be private, since otherwise + the JVM does not invoke it when deserializing subclasses. */ + protected def readResolve(): AnyRef = ??? + + /** The name of this enumeration. + */ + override def toString = + (getClass.getName.stripSuffix("$").split('.')).last.split('$').last + + /** The mapping from the integer used to identify values to the actual + * values. */ + private val vmap: mutable.Map[Int, Value] = new mutable.HashMap + + /** The cache listing all values of this enumeration. */ + @transient private var vset: ValueSet = null + @transient @volatile private var vsetDefined = false + + /** The mapping from the integer used to identify values to their + * names. */ + private val nmap: mutable.Map[Int, String] = new mutable.HashMap + + /** The values of this enumeration as a set. + */ + def values: ValueSet = { + if (!vsetDefined) { + vset = (ValueSet.newBuilder ++= vmap.values).result() + vsetDefined = true + } + vset + } + + /** The integer to use to identify the next created value. */ + protected var nextId: Int = initial + + /** The string to use to name the next created value. */ + protected var nextName: Iterator[String] = _ + + private def nextNameOrNull = + if (nextName != null && nextName.hasNext) nextName.next() else null + + /** The highest integer amongst those used to identify values in this + * enumeration. */ + private var topId = initial + + /** The lowest integer amongst those used to identify values in this + * enumeration, but no higher than 0. */ + private var bottomId = if(initial < 0) initial else 0 + + /** The one higher than the highest integer amongst those used to identify + * values in this enumeration. */ + final def maxId = topId + + /** The value of this enumeration with given id `x` + */ + final def apply(x: Int): Value = vmap(x) + + /** Return a `Value` from this `Enumeration` whose name matches + * the argument `s`. The names are determined automatically via reflection. + * + * @param s an `Enumeration` name + * @return the `Value` of this `Enumeration` if its name matches `s` + * @throws NoSuchElementException if no `Value` with a matching + * name is in this `Enumeration` + */ + final def withName(s: String): Value = { + val (unnamed, named) = values partition { + _.toString().startsWith(" v + // If we have unnamed values, we issue a detailed error message + case None if unnamed.nonEmpty => + throw new NoSuchElementException( + s"""Couldn't find enum field with name $s. + |However, there were the following unnamed fields: + |${unnamed.mkString(" ","\n ","")}""".stripMargin) + // Normal case (no unnamed Values) + case _ => None.get + } + } + + /** Creates a fresh value, part of this enumeration. */ + protected final def Value: Value = Value(nextId) + + /** Creates a fresh value, part of this enumeration, identified by the + * integer `i`. + * + * @param i An integer that identifies this value at run-time. It must be + * unique amongst all values of the enumeration. + * @return Fresh value identified by `i`. + */ + protected final def Value(i: Int): Value = Value(i, nextNameOrNull) + + /** Creates a fresh value, part of this enumeration, called `name`. + * + * @param name A human-readable name for that value. + * @return Fresh value called `name`. + */ + protected final def Value(name: String): Value = Value(nextId, name) + + /** Creates a fresh value, part of this enumeration, called `name` + * and identified by the integer `i`. + * + * @param i An integer that identifies this value at run-time. It must be + * unique amongst all values of the enumeration. + * @param name A human-readable name for that value. + * @return Fresh value with the provided identifier `i` and name `name`. + */ + protected final def Value(i: Int, name: String): Value = new Val(i, name) + + /** The type of the enumerated values. */ + @SerialVersionUID(7091335633555234129L) + abstract class Value extends Ordered[Value] with Serializable { + /** the id and bit location of this enumeration value */ + def id: Int + /** a marker so we can tell whose values belong to whom come reflective-naming time */ + private[Enumeration] val outerEnum = thisenum + + override def compare(that: Value): Int = + if (this.id < that.id) -1 + else if (this.id == that.id) 0 + else 1 + override def equals(other: Any) = other match { + case that: Enumeration#Value => (outerEnum eq that.outerEnum) && (id == that.id) + case _ => false + } + override def hashCode: Int = id.## + + /** Create a ValueSet which contains this value and another one */ + def + (v: Value) = ValueSet(this, v) + } + + /** A class implementing the [[scala.Enumeration.Value]] type. This class + * can be overridden to change the enumeration's naming and integer + * identification behaviour. + */ + @SerialVersionUID(0 - 3501153230598116017L) + protected class Val(i: Int, name: String) extends Value with Serializable { + def this(i: Int) = this(i, nextNameOrNull) + def this(name: String) = this(nextId, name) + def this() = this(nextId) + + assert(!vmap.isDefinedAt(i), "Duplicate id: " + i) + vmap(i) = this + vsetDefined = false + nextId = i + 1 + if (nextId > topId) topId = nextId + if (i < bottomId) bottomId = i + def id = i + override def toString() = + if (name != null) name + // Scala.js specific + else s"" + + protected def readResolve(): AnyRef = { + val enum = thisenum.readResolve().asInstanceOf[Enumeration] + if (enum.vmap == null) this + else enum.vmap(i) + } + } + + /** An ordering by id for values of this set */ + object ValueOrdering extends Ordering[Value] { + def compare(x: Value, y: Value): Int = x compare y + } + + /** A class for sets of values. + * Iterating through this set will yield values in increasing order of their ids. + * + * @param nnIds The set of ids of values (adjusted so that the lowest value does + * not fall below zero), organized as a `BitSet`. + * @define Coll `collection.immutable.SortedSet` + */ + class ValueSet private[ValueSet] (private[this] var nnIds: immutable.BitSet) + extends immutable.AbstractSet[Value] + with immutable.SortedSet[Value] + with immutable.SetOps[Value, immutable.Set, ValueSet] + with StrictOptimizedIterableOps[Value, immutable.Set, ValueSet] + with Serializable { + + implicit def ordering: Ordering[Value] = ValueOrdering + def rangeImpl(from: Option[Value], until: Option[Value]): ValueSet = + new ValueSet(nnIds.rangeImpl(from.map(_.id - bottomId), until.map(_.id - bottomId))) + + override def empty = ValueSet.empty + def contains(v: Value) = nnIds contains (v.id - bottomId) + def incl (value: Value) = new ValueSet(nnIds + (value.id - bottomId)) + def excl (value: Value) = new ValueSet(nnIds - (value.id - bottomId)) + def iterator = nnIds.iterator map (id => thisenum.apply(bottomId + id)) + override def iteratorFrom(start: Value) = nnIds iteratorFrom start.id map (id => thisenum.apply(bottomId + id)) + override def className = thisenum + ".ValueSet" + /** Creates a bit mask for the zero-adjusted ids in this set as a + * new array of longs */ + def toBitMask: Array[Long] = nnIds.toBitMask + + override protected def fromSpecificIterable(coll: Iterable[Value]) = ValueSet.fromSpecific(coll) + override protected def newSpecificBuilder = ValueSet.newBuilder + + def map(f: Value => Value): ValueSet = fromSpecificIterable(new View.Map(toIterable, f)) + def flatMap(f: Value => IterableOnce[Value]): ValueSet = fromSpecificIterable(new View.FlatMap(toIterable, f)) + } + + /** A factory object for value sets */ + object ValueSet extends SpecificIterableFactory[Value, ValueSet] { + /** The empty value set */ + val empty = new ValueSet(immutable.BitSet.empty) + /** A value set containing all the values for the zero-adjusted ids + * corresponding to the bits in an array */ + def fromBitMask(elems: Array[Long]): ValueSet = new ValueSet(immutable.BitSet.fromBitMask(elems)) + /** A builder object for value sets */ + def newBuilder: mutable.Builder[Value, ValueSet] = new mutable.Builder[Value, ValueSet] { + private[this] val b = new mutable.BitSet + def addOne (x: Value) = { b += (x.id - bottomId); this } + def clear() = b.clear() + def result() = new ValueSet(b.toImmutable) + } + def fromSpecific(it: IterableOnce[Value]): ValueSet = + newBuilder.addAll(it).result() + } +} diff --git a/scalalib/overrides-2.13.0-M4/scala/collection/immutable/NumericRange.scala b/scalalib/overrides-2.13.0-M4/scala/collection/immutable/NumericRange.scala new file mode 100644 index 0000000000..69f69051c2 --- /dev/null +++ b/scalalib/overrides-2.13.0-M4/scala/collection/immutable/NumericRange.scala @@ -0,0 +1,409 @@ +package scala.collection.immutable + +import scala.collection.{SeqFactory, IterableFactory, IterableOnce, Iterator, StrictOptimizedIterableOps} + +import java.lang.String + +import scala.collection.mutable.Builder + +/** `NumericRange` is a more generic version of the + * `Range` class which works with arbitrary types. + * It must be supplied with an `Integral` implementation of the + * range type. + * + * Factories for likely types include `Range.BigInt`, `Range.Long`, + * and `Range.BigDecimal`. `Range.Int` exists for completeness, but + * the `Int`-based `scala.Range` should be more performant. + * + * {{{ + * val r1 = new Range(0, 100, 1) + * val veryBig = Int.MaxValue.toLong + 1 + * val r2 = Range.Long(veryBig, veryBig + 100, 1) + * assert(r1 sameElements r2.map(_ - veryBig)) + * }}} + * + * @define Coll `NumericRange` + * @define coll numeric range + * @define mayNotTerminateInf + * @define willNotTerminateInf + */ +@SerialVersionUID(3L) +sealed class NumericRange[T]( + val start: T, + val end: T, + val step: T, + val isInclusive: Boolean +)(implicit + num: Integral[T] +) + extends AbstractSeq[T] + with IndexedSeq[T] + with IndexedSeqOps[T, IndexedSeq, IndexedSeq[T]] + with StrictOptimizedSeqOps[T, IndexedSeq, IndexedSeq[T]] + with Serializable { self => + + override def iterator() = new Iterator[T] { + import num.mkNumericOps + + private var _hasNext = !self.isEmpty + private var _next: T = start + private val lastElement: T = if (_hasNext) last else start + override def knownSize: Int = if (_hasNext) num.toInt((lastElement - _next) / step) + 1 else 0 + def hasNext: Boolean = _hasNext + def next(): T = { + if (!_hasNext) Iterator.empty.next() + val value = _next + _hasNext = value != lastElement + _next = num.plus(value, step) + value + } + } + + /** Note that NumericRange must be invariant so that constructs + * such as "1L to 10 by 5" do not infer the range type as AnyVal. + */ + import num._ + + // See comment in Range for why this must be lazy. + override lazy val length: Int = NumericRange.count(start, end, step, isInclusive) + override def isEmpty = length == 0 + override def last: T = + if (length == 0) Nil.head + else locationAfterN(length - 1) + override def init: NumericRange[T] = + if (isEmpty) Nil.init + else new NumericRange(start, end - step, step, isInclusive) + + override def head: T = if (isEmpty) Nil.head else start + override def tail: NumericRange[T] = + if (isEmpty) Nil.tail + else if(isInclusive) new NumericRange.Inclusive(start + step, end, step) + else new NumericRange.Exclusive(start + step, end, step) + + /** Create a new range with the start and end values of this range and + * a new `step`. + */ + def by(newStep: T): NumericRange[T] = copy(start, end, newStep) + + + /** Create a copy of this range. + */ + def copy(start: T, end: T, step: T): NumericRange[T] = + new NumericRange(start, end, step, isInclusive) + + @throws[IndexOutOfBoundsException] + def apply(idx: Int): T = { + if (idx < 0 || idx >= length) throw new IndexOutOfBoundsException(idx.toString) + else locationAfterN(idx) + } + + override def foreach[@specialized(Unit) U](f: T => U): Unit = { + var count = 0 + var current = start + while (count < length) { + f(current) + current += step + count += 1 + } + } + + // TODO: these private methods are straight copies from Range, duplicated + // to guard against any (most likely illusory) performance drop. They should + // be eliminated one way or another. + + // Tests whether a number is within the endpoints, without testing + // whether it is a member of the sequence (i.e. when step > 1.) + private def isWithinBoundaries(elem: T) = !isEmpty && ( + (step > zero && start <= elem && elem <= last ) || + (step < zero && last <= elem && elem <= start) + ) + // Methods like apply throw exceptions on invalid n, but methods like take/drop + // are forgiving: therefore the checks are with the methods. + private def locationAfterN(n: Int): T = start + (step * fromInt(n)) + + // When one drops everything. Can't ever have unchecked operations + // like "end + 1" or "end - 1" because ranges involving Int.{ MinValue, MaxValue } + // will overflow. This creates an exclusive range where start == end + // based on the given value. + private def newEmptyRange(value: T) = NumericRange(value, value, step) + + override def take(n: Int): NumericRange[T] = { + if (n <= 0 || length == 0) newEmptyRange(start) + else if (n >= length) this + else new NumericRange.Inclusive(start, locationAfterN(n - 1), step) + } + + override def drop(n: Int): NumericRange[T] = { + if (n <= 0 || length == 0) this + else if (n >= length) newEmptyRange(end) + else copy(locationAfterN(n), end, step) + } + + override def splitAt(n: Int): (NumericRange[T], NumericRange[T]) = (take(n), drop(n)) + + override def reverse: NumericRange[T] = + if (isEmpty) this else new NumericRange.Inclusive(last, start, -step) + + import NumericRange.defaultOrdering + + override def min[T1 >: T](implicit ord: Ordering[T1]): T = + // We can take the fast path: + // - If the Integral of this NumericRange is also the requested Ordering + // (Integral <: Ordering). This can happen for custom Integral types. + // - The Ordering is the default Ordering of a well-known Integral type. + if ((ord eq num) || defaultOrdering.get(num).exists(ord eq _)) { + if (num.signum(step) > 0) head + else last + } else super.min(ord) + + override def max[T1 >: T](implicit ord: Ordering[T1]): T = + // See comment for fast path in min(). + if ((ord eq num) || defaultOrdering.get(num).exists(ord eq _)) { + if (num.signum(step) > 0) last + else head + } else super.max(ord) + + // Motivated by the desire for Double ranges with BigDecimal precision, + // we need some way to map a Range and get another Range. This can't be + // done in any fully general way because Ranges are not arbitrary + // sequences but step-valued, so we have a custom method only we can call + // which we promise to use responsibly. + // + // The point of it all is that + // + // 0.0 to 1.0 by 0.1 + // + // should result in + // + // NumericRange[Double](0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0) + // + // and not + // + // NumericRange[Double](0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9) + // + // or perhaps more importantly, + // + // (0.1 to 0.3 by 0.1 contains 0.3) == true + // + private[immutable] def mapRange[A](fm: T => A)(implicit unum: Integral[A]): NumericRange[A] = { + val self = this + + // XXX This may be incomplete. + new NumericRange[A](fm(start), fm(end), fm(step), isInclusive) { + + private lazy val underlyingRange: NumericRange[T] = self + override def foreach[@specialized(Unit) U](f: A => U): Unit = { underlyingRange foreach (x => f(fm(x))) } + override def isEmpty = underlyingRange.isEmpty + override def apply(idx: Int): A = fm(underlyingRange(idx)) + override def containsTyped(el: A) = underlyingRange exists (x => fm(x) == el) + + override def toString = { + def simpleOf(x: Any): String = x.getClass.getName.split("\\.").last + val stepped = simpleOf(underlyingRange.step) + s"${super.toString} (using $underlyingRange of $stepped)" + } + } + } + + // a well-typed contains method. + def containsTyped(x: T): Boolean = + isWithinBoundaries(x) && (((x - start) % step) == zero) + + override def contains[A1 >: T](x: A1): Boolean = + try containsTyped(x.asInstanceOf[T]) + catch { case _: ClassCastException => false } + + override def sum[B >: T](implicit num: Numeric[B]): B = { + if (isEmpty) num.zero + else if (size == 1) head + else { + // If there is no overflow, use arithmetic series formula + // a + ... (n terms total) ... + b = n*(a+b)/2 + if ((num eq scala.math.Numeric.IntIsIntegral)|| + (num eq scala.math.Numeric.ShortIsIntegral)|| + (num eq scala.math.Numeric.ByteIsIntegral)|| + (num eq scala.math.Numeric.CharIsIntegral)) { + // We can do math with no overflow in a Long--easy + val exact = (size * ((num toLong head) + (num toInt last))) / 2 + num fromInt exact.toInt + } + else if (num eq scala.math.Numeric.LongIsIntegral) { + // Uh-oh, might be overflow, so we have to divide before we overflow. + // Either numRangeElements or (head + last) must be even, so divide the even one before multiplying + val a = head.toLong + val b = last.toLong + val ans = + if ((size & 1) == 0) (size / 2) * (a + b) + else size * { + // Sum is even, but we might overflow it, so divide in pieces and add back remainder + val ha = a/2 + val hb = b/2 + ha + hb + ((a - 2*ha) + (b - 2*hb)) / 2 + } + ans.asInstanceOf[B] + } + else { + // User provided custom Numeric, so we cannot rely on arithmetic series formula (e.g. won't work on something like Z_6) + if (isEmpty) num.zero + else { + var acc = num.zero + var i = head + var idx = 0 + while(idx < length) { + acc = num.plus(acc, i) + i = i + step + idx = idx + 1 + } + acc + } + } + } + } + + override lazy val hashCode: Int = super.hashCode() + override def equals(other: Any): Boolean = other match { + case x: NumericRange[_] => + (x canEqual this) && (length == x.length) && ( + (length == 0) || // all empty sequences are equal + (start == x.start && last == x.last) // same length and same endpoints implies equality + ) + case _ => + super.equals(other) + } + + override def toString: String = { + val empty = if (isEmpty) "empty " else "" + val preposition = if (isInclusive) "to" else "until" + val stepped = if (step == 1) "" else s" by $step" + s"${empty}NumericRange $start $preposition $end$stepped" + } +} + +/** A companion object for numeric ranges. + * @define Coll `NumericRange` + * @define coll numeric range + */ +object NumericRange { + + /** Calculates the number of elements in a range given start, end, step, and + * whether or not it is inclusive. Throws an exception if step == 0 or + * the number of elements exceeds the maximum Int. + */ + def count[T](start: T, end: T, step: T, isInclusive: Boolean)(implicit num: Integral[T]): Int = { + val zero = num.zero + val upward = num.lt(start, end) + val posStep = num.gt(step, zero) + + if (step == zero) throw new IllegalArgumentException("step cannot be 0.") + else if (start == end) if (isInclusive) 1 else 0 + else if (upward != posStep) 0 + else { + /* We have to be frightfully paranoid about running out of range. + * We also can't assume that the numbers will fit in a Long. + * We will assume that if a > 0, -a can be represented, and if + * a < 0, -a+1 can be represented. We also assume that if we + * can't fit in Int, we can represent 2*Int.MaxValue+3 (at least). + * And we assume that numbers wrap rather than cap when they overflow. + */ + // Check whether we can short-circuit by deferring to Int range. + val startint = num.toInt(start) + if (start == num.fromInt(startint)) { + val endint = num.toInt(end) + if (end == num.fromInt(endint)) { + val stepint = num.toInt(step) + if (step == num.fromInt(stepint)) { + return { + if (isInclusive) Range.inclusive(startint, endint, stepint).length + else Range (startint, endint, stepint).length + } + } + } + } + // If we reach this point, deferring to Int failed. + // Numbers may be big. + val one = num.one + val limit = num.fromInt(Int.MaxValue) + def check(t: T): T = + if (num.gt(t, limit)) throw new IllegalArgumentException("More than Int.MaxValue elements.") + else t + // If the range crosses zero, it might overflow when subtracted + val startside = num.signum(start) + val endside = num.signum(end) + num.toInt{ + if (startside*endside >= 0) { + // We're sure we can subtract these numbers. + // Note that we do not use .rem because of different conventions for Long and BigInt + val diff = num.minus(end, start) + val quotient = check(num.quot(diff, step)) + val remainder = num.minus(diff, num.times(quotient, step)) + if (!isInclusive && zero == remainder) quotient else check(num.plus(quotient, one)) + } + else { + // We might not even be able to subtract these numbers. + // Jump in three pieces: + // * start to -1 or 1, whichever is closer (waypointA) + // * one step, which will take us at least to 0 (ends at waypointB) + // * there to the end + val negone = num.fromInt(-1) + val startlim = if (posStep) negone else one + val startdiff = num.minus(startlim, start) + val startq = check(num.quot(startdiff, step)) + val waypointA = if (startq == zero) start else num.plus(start, num.times(startq, step)) + val waypointB = num.plus(waypointA, step) + check { + if (num.lt(waypointB, end) != upward) { + // No last piece + if (isInclusive && waypointB == end) num.plus(startq, num.fromInt(2)) + else num.plus(startq, one) + } + else { + // There is a last piece + val enddiff = num.minus(end,waypointB) + val endq = check(num.quot(enddiff, step)) + val last = if (endq == zero) waypointB else num.plus(waypointB, num.times(endq, step)) + // Now we have to tally up all the pieces + // 1 for the initial value + // startq steps to waypointA + // 1 step to waypointB + // endq steps to the end (one less if !isInclusive and last==end) + num.plus(startq, num.plus(endq, if (!isInclusive && last==end) one else num.fromInt(2))) + } + } + } + } + } + } + + @SerialVersionUID(3L) + class Inclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]) + extends NumericRange(start, end, step, true) { + override def copy(start: T, end: T, step: T): Inclusive[T] = + NumericRange.inclusive(start, end, step) + + def exclusive: Exclusive[T] = NumericRange(start, end, step) + } + + @SerialVersionUID(3L) + class Exclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]) + extends NumericRange(start, end, step, false) { + override def copy(start: T, end: T, step: T): Exclusive[T] = + NumericRange(start, end, step) + + def inclusive: Inclusive[T] = NumericRange.inclusive(start, end, step) + } + + def apply[T](start: T, end: T, step: T)(implicit num: Integral[T]): Exclusive[T] = + new Exclusive(start, end, step) + def inclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]): Inclusive[T] = + new Inclusive(start, end, step) + + private[collection] val defaultOrdering = Map[Numeric[_], Ordering[_]]( + Numeric.IntIsIntegral -> Ordering.Int, + Numeric.ShortIsIntegral -> Ordering.Short, + Numeric.ByteIsIntegral -> Ordering.Byte, + Numeric.CharIsIntegral -> Ordering.Char, + Numeric.LongIsIntegral -> Ordering.Long + ) + +} + diff --git a/scalalib/overrides-2.13.0-M4/scala/collection/immutable/Range.scala b/scalalib/overrides-2.13.0-M4/scala/collection/immutable/Range.scala new file mode 100644 index 0000000000..8c89fe0f18 --- /dev/null +++ b/scalalib/overrides-2.13.0-M4/scala/collection/immutable/Range.scala @@ -0,0 +1,547 @@ +package scala +package collection.immutable + +import collection.{Iterator, SeqFactory} + +import java.lang.String + +import scala.collection.mutable.Builder + +/** The `Range` class represents integer values in range + * ''[start;end)'' with non-zero step value `step`. + * It's a special case of an indexed sequence. + * For example: + * + * {{{ + * val r1 = 0 until 10 + * val r2 = r1.start until r1.end by r1.step + 1 + * println(r2.length) // = 5 + * }}} + * + * Ranges that contain more than `Int.MaxValue` elements can be created, but + * these overfull ranges have only limited capabilities. Any method that + * could require a collection of over `Int.MaxValue` length to be created, or + * could be asked to index beyond `Int.MaxValue` elements will throw an + * exception. Overfull ranges can safely be reduced in size by changing + * the step size (e.g. `by 3`) or taking/dropping elements. `contains`, + * `equals`, and access to the ends of the range (`head`, `last`, `tail`, + * `init`) are also permitted on overfull ranges. + * + * @param start the start of this range. + * @param end the end of the range. For exclusive ranges, e.g. + * `Range(0,3)` or `(0 until 3)`, this is one + * step past the last one in the range. For inclusive + * ranges, e.g. `Range.inclusive(0,3)` or `(0 to 3)`, + * it may be in the range if it is not skipped by the step size. + * To find the last element inside a non-empty range, + * use `last` instead. + * @param step the step for the range. + * + * @define coll range + * @define mayNotTerminateInf + * @define willNotTerminateInf + * @define doesNotUseBuilders + * '''Note:''' this method does not use builders to construct a new range, + * and its complexity is O(1). + */ +@SerialVersionUID(3L) +sealed abstract class Range( + val start: Int, + val end: Int, + val step: Int +) + extends AbstractSeq[Int] + with IndexedSeq[Int] + with IndexedSeqOps[Int, IndexedSeq, IndexedSeq[Int]] + with StrictOptimizedSeqOps[Int, IndexedSeq, IndexedSeq[Int]] + with Serializable { range => + + override def iterator(): Iterator[Int] = new RangeIterator(start, step, lastElement, isEmpty) + + private def gap = end.toLong - start.toLong + private def isExact = gap % step == 0 + private def hasStub = isInclusive || !isExact + private def longLength = gap / step + ( if (hasStub) 1 else 0 ) + + def isInclusive: Boolean + + override val isEmpty: Boolean = ( + (start > end && step > 0) + || (start < end && step < 0) + || (start == end && !isInclusive) + ) + + private val numRangeElements: Int = { + if (step == 0) throw new IllegalArgumentException("step cannot be 0.") + else if (isEmpty) 0 + else { + val len = longLength + if (len > scala.Int.MaxValue) -1 + else len.toInt + } + } + + def length = if (numRangeElements < 0) fail() else numRangeElements + + // This field has a sensible value only for non-empty ranges + private val lastElement = step match { + case 1 => if (isInclusive) end else end-1 + case -1 => if (isInclusive) end else end+1 + case _ => + val remainder = (gap % step).toInt + if (remainder != 0) end - remainder + else if (isInclusive) end + else end - step + } + + /** The last element of this range. This method will return the correct value + * even if there are too many elements to iterate over. + */ + override def last: Int = if (isEmpty) Nil.head else lastElement + override def head: Int = if (isEmpty) Nil.head else start + + /** Creates a new range containing all the elements of this range except the last one. + * + * $doesNotUseBuilders + * + * @return a new range consisting of all the elements of this range except the last one. + */ + override def init: Range = { + if (isEmpty) + Nil.init + + dropRight(1) + } + + /** Creates a new range containing all the elements of this range except the first one. + * + * $doesNotUseBuilders + * + * @return a new range consisting of all the elements of this range except the first one. + */ + override def tail: Range = { + if (isEmpty) + Nil.tail + if (numRangeElements == 1) newEmptyRange(end) + else if(isInclusive) new Range.Inclusive(start + step, end, step) + else new Range.Exclusive(start + step, end, step) + } + + protected def copy(start: Int = start, end: Int = end, step: Int = step, isInclusive: Boolean = isInclusive): Range = + if(isInclusive) new Range.Inclusive(start, end, step) else new Range.Exclusive(start, end, step) + + /** Create a new range with the `start` and `end` values of this range and + * a new `step`. + * + * @return a new range with a different step + */ + def by(step: Int): Range = copy(start, end, step) + + // Check cannot be evaluated eagerly because we have a pattern where + // ranges are constructed like: "x to y by z" The "x to y" piece + // should not trigger an exception. So the calculation is delayed, + // which means it will not fail fast for those cases where failing was + // correct. + private def validateMaxLength(): Unit = { + if (numRangeElements < 0) + fail() + } + private def fail() = Range.fail(start, end, step, isInclusive) + + @throws[IndexOutOfBoundsException] + def apply(idx: Int): Int = { + validateMaxLength() + if (idx < 0 || idx >= numRangeElements) throw new IndexOutOfBoundsException(idx.toString) + else start + (step * idx) + } + + /*@`inline`*/ override def foreach[@specialized(Unit) U](f: Int => U): Unit = { + // Implementation chosen on the basis of favorable microbenchmarks + // Note--initialization catches step == 0 so we don't need to here + if (!isEmpty) { + var i = start + while (true) { + f(i) + if (i == lastElement) return + i += step + } + } + } + + /** Creates a new range containing the first `n` elements of this range. + * + * @param n the number of elements to take. + * @return a new range consisting of `n` first elements. + */ + override def take(n: Int): Range = + if (n <= 0 || isEmpty) newEmptyRange(start) + else if (n >= numRangeElements && numRangeElements >= 0) this + else { + // May have more than Int.MaxValue elements in range (numRangeElements < 0) + // but the logic is the same either way: take the first n + new Range.Inclusive(start, locationAfterN(n - 1), step) + } + + /** Creates a new range containing all the elements of this range except the first `n` elements. + * + * @param n the number of elements to drop. + * @return a new range consisting of all the elements of this range except `n` first elements. + */ + override def drop(n: Int): Range = + if (n <= 0 || isEmpty) this + else if (n >= numRangeElements && numRangeElements >= 0) newEmptyRange(end) + else { + // May have more than Int.MaxValue elements (numRangeElements < 0) + // but the logic is the same either way: go forwards n steps, keep the rest + copy(locationAfterN(n), end, step) + } + + /** Creates a new range consisting of the last `n` elements of the range. + * + * $doesNotUseBuilders + */ + override def takeRight(n: Int): Range = { + if (n <= 0) newEmptyRange(start) + else if (numRangeElements >= 0) drop(numRangeElements - n) + else { + // Need to handle over-full range separately + val y = last + val x = y - step.toLong*(n-1) + if ((step > 0 && x < start) || (step < 0 && x > start)) this + else Range.inclusive(x.toInt, y, step) + } + } + + /** Creates a new range consisting of the initial `length - n` elements of the range. + * + * $doesNotUseBuilders + */ + override def dropRight(n: Int): Range = { + if (n <= 0) this + else if (numRangeElements >= 0) take(numRangeElements - n) + else { + // Need to handle over-full range separately + val y = last - step.toInt*n + if ((step > 0 && y < start) || (step < 0 && y > start)) newEmptyRange(start) + else Range.inclusive(start, y.toInt, step) + } + } + + // Advance from the start while we meet the given test + private def argTakeWhile(p: Int => Boolean): Long = { + if (isEmpty) start + else { + var current = start + val stop = last + while (current != stop && p(current)) current += step + if (current != stop || !p(current)) current + else current.toLong + step + } + } + + override def takeWhile(p: Int => Boolean): Range = { + val stop = argTakeWhile(p) + if (stop==start) newEmptyRange(start) + else { + val x = (stop - step).toInt + if (x == last) this + else Range.inclusive(start, x, step) + } + } + + override def dropWhile(p: Int => Boolean): Range = { + val stop = argTakeWhile(p) + if (stop == start) this + else { + val x = (stop - step).toInt + if (x == last) newEmptyRange(last) + else Range.inclusive(x + step, last, step) + } + } + + override def span(p: Int => Boolean): (Range, Range) = { + val border = argTakeWhile(p) + if (border == start) (newEmptyRange(start), this) + else { + val x = (border - step).toInt + if (x == last) (this, newEmptyRange(last)) + else (Range.inclusive(start, x, step), Range.inclusive(x+step, last, step)) + } + } + + /** Creates a new range containing the elements starting at `from` up to but not including `until`. + * + * $doesNotUseBuilders + * + * @param from the element at which to start + * @param until the element at which to end (not included in the range) + * @return a new range consisting of a contiguous interval of values in the old range + */ + override def slice(from: Int, until: Int): Range = + if (from <= 0) take(until) + else if (until >= numRangeElements && numRangeElements >= 0) drop(from) + else { + val fromValue = locationAfterN(from) + if (from >= until) newEmptyRange(fromValue) + else Range.inclusive(fromValue, locationAfterN(until-1), step) + } + + // Overridden only to refine the return type + override def splitAt(n: Int): (Range, Range) = (take(n), drop(n)) + + // Methods like apply throw exceptions on invalid n, but methods like take/drop + // are forgiving: therefore the checks are with the methods. + private def locationAfterN(n: Int) = start + (step * n) + + // When one drops everything. Can't ever have unchecked operations + // like "end + 1" or "end - 1" because ranges involving Int.{ MinValue, MaxValue } + // will overflow. This creates an exclusive range where start == end + // based on the given value. + private def newEmptyRange(value: Int) = new Range.Exclusive(value, value, step) + + /** Returns the reverse of this range. + */ + override def reverse: Range = + if (isEmpty) this + else new Range.Inclusive(last, start, -step) + + /** Make range inclusive. + */ + def inclusive: Range = + if (isInclusive) this + else new Range.Inclusive(start, end, step) + + def contains(x: Int) = { + if (x == end && !isInclusive) false + else if (step > 0) { + if (x < start || x > end) false + else (step == 1) || (((x - start) % step) == 0) + } + else { + if (x < end || x > start) false + else (step == -1) || (((x - start) % step) == 0) + } + } + + override def sum[B >: Int](implicit num: Numeric[B]): Int = { + if (num eq scala.math.Numeric.IntIsIntegral) { + // this is normal integer range with usual addition. arithmetic series formula can be used + if (isEmpty) 0 + else if (size == 1) head + else ((size * (head.toLong + last)) / 2).toInt + } else { + // user provided custom Numeric, we cannot rely on arithmetic series formula + if (isEmpty) num.toInt(num.zero) + else { + var acc = num.zero + var i = head + while (true) { + acc = num.plus(acc, i) + if (i == lastElement) return num.toInt(acc) + i = i + step + } + 0 // Never hit this--just to satisfy compiler since it doesn't know while(true) has type Nothing + } + } + } + + override def min[A1 >: Int](implicit ord: Ordering[A1]): Int = + if (ord eq Ordering.Int) { + if (step > 0) head + else last + } else super.min(ord) + + override def max[A1 >: Int](implicit ord: Ordering[A1]): Int = + if (ord eq Ordering.Int) { + if (step > 0) last + else head + } else super.max(ord) + + + override def equals(other: Any) = other match { + case x: Range => + // Note: this must succeed for overfull ranges (length > Int.MaxValue) + if (isEmpty) x.isEmpty // empty sequences are equal + else // this is non-empty... + x.nonEmpty && start == x.start && { // ...so other must contain something and have same start + val l0 = last + (l0 == x.last && ( // And same end + start == l0 || step == x.step // And either the same step, or not take any steps + )) + } + case _ => + super.equals(other) + } + + /* Note: hashCode can't be overridden without breaking Seq's equals contract. */ + + override def toString: String = { + val preposition = if (isInclusive) "to" else "until" + val stepped = if (step == 1) "" else s" by $step" + val prefix = if (isEmpty) "empty " else if (!isExact) "inexact " else "" + s"${prefix}Range $start $preposition $end$stepped" + } + +} + +/** + * Companion object for ranges. + * @define Coll `Range` + * @define coll range + */ +object Range { + + private def description(start: Int, end: Int, step: Int, isInclusive: Boolean) = + start + (if (isInclusive) " to " else " until ") + end + " by " + step + + private def fail(start: Int, end: Int, step: Int, isInclusive: Boolean) = + throw new IllegalArgumentException(description(start, end, step, isInclusive) + + ": seqs cannot contain more than Int.MaxValue elements.") + + /** Counts the number of range elements. + * precondition: step != 0 + * If the size of the range exceeds Int.MaxValue, the + * result will be negative. + */ + def count(start: Int, end: Int, step: Int, isInclusive: Boolean): Int = { + if (step == 0) + throw new IllegalArgumentException("step cannot be 0.") + + val isEmpty = + if (start == end) !isInclusive + else if (start < end) step < 0 + else step > 0 + + if (isEmpty) 0 + else { + // Counts with Longs so we can recognize too-large ranges. + val gap: Long = end.toLong - start.toLong + val jumps: Long = gap / step + // Whether the size of this range is one larger than the + // number of full-sized jumps. + val hasStub = isInclusive || (gap % step != 0) + val result: Long = jumps + ( if (hasStub) 1 else 0 ) + + if (result > scala.Int.MaxValue) -1 + else result.toInt + } + } + def count(start: Int, end: Int, step: Int): Int = + count(start, end, step, isInclusive = false) + + /** Make a range from `start` until `end` (exclusive) with given step value. + * @note step != 0 + */ + def apply(start: Int, end: Int, step: Int): Range.Exclusive = new Range.Exclusive(start, end, step) + + /** Make a range from `start` until `end` (exclusive) with step value 1. + */ + def apply(start: Int, end: Int): Range.Exclusive = new Range.Exclusive(start, end, 1) + + /** Make an inclusive range from `start` to `end` with given step value. + * @note step != 0 + */ + def inclusive(start: Int, end: Int, step: Int): Range.Inclusive = new Range.Inclusive(start, end, step) + + /** Make an inclusive range from `start` to `end` with step value 1. + */ + def inclusive(start: Int, end: Int): Range.Inclusive = new Range.Inclusive(start, end, 1) + + @SerialVersionUID(3L) + @inline + final class Inclusive(start: Int, end: Int, step: Int) extends Range(start, end, step) { + def isInclusive = true + } + + @SerialVersionUID(3L) + @inline + final class Exclusive(start: Int, end: Int, step: Int) extends Range(start, end, step) { + def isInclusive = false + } + + // BigInt and Long are straightforward generic ranges. + object BigInt { + def apply(start: BigInt, end: BigInt, step: BigInt) = NumericRange(start, end, step) + def inclusive(start: BigInt, end: BigInt, step: BigInt) = NumericRange.inclusive(start, end, step) + } + + object Long { + def apply(start: Long, end: Long, step: Long) = NumericRange(start, end, step) + def inclusive(start: Long, end: Long, step: Long) = NumericRange.inclusive(start, end, step) + } + + // BigDecimal uses an alternative implementation of Numeric in which + // it pretends to be Integral[T] instead of Fractional[T]. See Numeric for + // details. The intention is for it to throw an exception anytime + // imprecision or surprises might result from anything, although this may + // not yet be fully implemented. + object BigDecimal { + implicit val bigDecAsIntegral: Numeric.BigDecimalAsIfIntegral = Numeric.BigDecimalAsIfIntegral + + def apply(start: BigDecimal, end: BigDecimal, step: BigDecimal) = + NumericRange(start, end, step) + def inclusive(start: BigDecimal, end: BigDecimal, step: BigDecimal) = + NumericRange.inclusive(start, end, step) + } + + // Double works by using a BigDecimal under the hood for precise + // stepping, but mapping the sequence values back to doubles with + // .doubleValue. This constructs the BigDecimals by way of the + // String constructor (valueOf) instead of the Double one, which + // is necessary to keep 0.3d at 0.3 as opposed to + // 0.299999999999999988897769753748434595763683319091796875 or so. + object Double { + implicit val bigDecAsIntegral: Numeric.BigDecimalAsIfIntegral = Numeric.BigDecimalAsIfIntegral + implicit val doubleAsIntegral: Numeric.DoubleAsIfIntegral = Numeric.DoubleAsIfIntegral + def toBD(x: Double): BigDecimal = scala.math.BigDecimal valueOf x + + @deprecated("use Range.BigDecimal instead", "2.12.6") + def apply(start: Double, end: Double, step: Double) = + BigDecimal(toBD(start), toBD(end), toBD(step)) mapRange (_.doubleValue) + + @deprecated("use Range.BigDecimal.inclusive instead", "2.12.6") + def inclusive(start: Double, end: Double, step: Double) = + BigDecimal.inclusive(toBD(start), toBD(end), toBD(step)) mapRange (_.doubleValue) + } + + // As there is no appealing default step size for not-really-integral ranges, + // we offer a partially constructed object. + class Partial[T, U](private val f: T => U) extends AnyVal { + def by(x: T): U = f(x) + override def toString = "Range requires step" + } + + // Illustrating genericity with Int Range, which should have the same behavior + // as the original Range class. However we leave the original Range + // indefinitely, for performance and because the compiler seems to bootstrap + // off it and won't do so with our parameterized version without modifications. + object Int { + def apply(start: Int, end: Int, step: Int) = NumericRange(start, end, step) + def inclusive(start: Int, end: Int, step: Int) = NumericRange.inclusive(start, end, step) + } + +} + +/** + * @param lastElement The last element included in the Range + * @param initiallyEmpty Whether the Range was initially empty or not + */ +private class RangeIterator( + start: Int, + step: Int, + lastElement: Int, + initiallyEmpty: Boolean +) extends Iterator[Int] { + private var _hasNext: Boolean = !initiallyEmpty + private var _next: Int = start + override def knownSize: Int = if (_hasNext) (lastElement - _next) / step + 1 else 0 + def hasNext: Boolean = _hasNext + @throws[NoSuchElementException] + def next(): Int = { + if (!_hasNext) Iterator.empty.next() + val value = _next + _hasNext = value != lastElement + _next = value + step + value + } +} diff --git a/scalalib/overrides-2.13.0-M4/scala/runtime/ScalaRunTime.scala b/scalalib/overrides-2.13.0-M4/scala/runtime/ScalaRunTime.scala new file mode 100644 index 0000000000..84d7395106 --- /dev/null +++ b/scalalib/overrides-2.13.0-M4/scala/runtime/ScalaRunTime.scala @@ -0,0 +1,282 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala +package runtime + +import scala.collection.{ AbstractIterator, AnyConstr, SortedOps, StrictOptimizedIterableOps, StringOps, StringView, View } +import scala.collection.generic.IsIterableLike +import scala.collection.immutable.{ NumericRange, ArraySeq } +import scala.collection.mutable.StringBuilder +import scala.reflect.{ ClassTag, classTag } +import java.lang.{ Class => jClass } + +import java.lang.reflect.{ Method => JMethod } + +/** The object ScalaRunTime provides support methods required by + * the scala runtime. All these methods should be considered + * outside the API and subject to change or removal without notice. + */ +object ScalaRunTime { + def isArray(x: Any, atLevel: Int = 1): Boolean = + x != null && isArrayClass(x.getClass, atLevel) + + private def isArrayClass(clazz: jClass[_], atLevel: Int): Boolean = + clazz != null && clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) + + // A helper method to make my life in the pattern matcher a lot easier. + def drop[Repr](coll: Repr, num: Int)(implicit iterable: IsIterableLike[Repr]): Repr = + iterable conversion coll drop num + + /** Return the class object representing an array with element class `clazz`. + */ + def arrayClass(clazz: jClass[_]): jClass[_] = { + // newInstance throws an exception if the erasure is Void.TYPE. see scala/bug#5680 + if (clazz == java.lang.Void.TYPE) classOf[Array[Unit]] + else java.lang.reflect.Array.newInstance(clazz, 0).getClass + } + + /** Return the class object representing an unboxed value type, + * e.g., classOf[int], not classOf[java.lang.Integer]. The compiler + * rewrites expressions like 5.getClass to come here. + */ + def anyValClass[T <: AnyVal : ClassTag](value: T): jClass[T] = + classTag[T].runtimeClass.asInstanceOf[jClass[T]] + + /** Retrieve generic array element */ + def array_apply(xs: AnyRef, idx: Int): Any = { + xs match { + case x: Array[AnyRef] => x(idx).asInstanceOf[Any] + case x: Array[Int] => x(idx).asInstanceOf[Any] + case x: Array[Double] => x(idx).asInstanceOf[Any] + case x: Array[Long] => x(idx).asInstanceOf[Any] + case x: Array[Float] => x(idx).asInstanceOf[Any] + case x: Array[Char] => x(idx).asInstanceOf[Any] + case x: Array[Byte] => x(idx).asInstanceOf[Any] + case x: Array[Short] => x(idx).asInstanceOf[Any] + case x: Array[Boolean] => x(idx).asInstanceOf[Any] + case x: Array[Unit] => x(idx).asInstanceOf[Any] + case null => throw new NullPointerException + } + } + + /** update generic array element */ + def array_update(xs: AnyRef, idx: Int, value: Any): Unit = { + xs match { + case x: Array[AnyRef] => x(idx) = value.asInstanceOf[AnyRef] + case x: Array[Int] => x(idx) = value.asInstanceOf[Int] + case x: Array[Double] => x(idx) = value.asInstanceOf[Double] + case x: Array[Long] => x(idx) = value.asInstanceOf[Long] + case x: Array[Float] => x(idx) = value.asInstanceOf[Float] + case x: Array[Char] => x(idx) = value.asInstanceOf[Char] + case x: Array[Byte] => x(idx) = value.asInstanceOf[Byte] + case x: Array[Short] => x(idx) = value.asInstanceOf[Short] + case x: Array[Boolean] => x(idx) = value.asInstanceOf[Boolean] + case x: Array[Unit] => x(idx) = value.asInstanceOf[Unit] + case null => throw new NullPointerException + } + } + + /** Get generic array length */ + def array_length(xs: AnyRef): Int = xs match { + case x: Array[AnyRef] => x.length + case x: Array[Int] => x.length + case x: Array[Double] => x.length + case x: Array[Long] => x.length + case x: Array[Float] => x.length + case x: Array[Char] => x.length + case x: Array[Byte] => x.length + case x: Array[Short] => x.length + case x: Array[Boolean] => x.length + case x: Array[Unit] => x.length + case null => throw new NullPointerException + } + + def array_clone(xs: AnyRef): AnyRef = xs match { + case x: Array[AnyRef] => x.clone() + case x: Array[Int] => x.clone() + case x: Array[Double] => x.clone() + case x: Array[Long] => x.clone() + case x: Array[Float] => x.clone() + case x: Array[Char] => x.clone() + case x: Array[Byte] => x.clone() + case x: Array[Short] => x.clone() + case x: Array[Boolean] => x.clone() + case x: Array[Unit] => x + case null => throw new NullPointerException + } + + /** Convert an array to an object array. + * Needed to deal with vararg arguments of primitive types that are passed + * to a generic Java vararg parameter T ... + */ + def toObjectArray(src: AnyRef): Array[Object] = src match { + case x: Array[AnyRef] => x + case _ => + val length = array_length(src) + val dest = new Array[Object](length) + for (i <- 0 until length) + array_update(dest, i, array_apply(src, i)) + dest + } + + def toArray[T](xs: scala.collection.Seq[T]) = { + val arr = new Array[AnyRef](xs.length) + var i = 0 + for (x <- xs) { + arr(i) = x.asInstanceOf[AnyRef] + i += 1 + } + arr + } + + // Java bug: https://bugs.java.com/view_bug.do?bug_id=4071957 + // More background at ticket #2318. + def ensureAccessible(m: JMethod): JMethod = scala.reflect.ensureAccessible(m) + + def _toString(x: Product): String = + x.productIterator.mkString(x.productPrefix + "(", ",", ")") + + def _hashCode(x: Product): Int = scala.util.hashing.MurmurHash3.productHash(x) + + /** A helper for case classes. */ + def typedProductIterator[T](x: Product): Iterator[T] = { + new AbstractIterator[T] { + private var c: Int = 0 + private val cmax = x.productArity + def hasNext = c < cmax + def next() = { + val result = x.productElement(c) + c += 1 + result.asInstanceOf[T] + } + } + } + + /** Given any Scala value, convert it to a String. + * + * The primary motivation for this method is to provide a means for + * correctly obtaining a String representation of a value, while + * avoiding the pitfalls of naively calling toString on said value. + * In particular, it addresses the fact that (a) toString cannot be + * called on null and (b) depending on the apparent type of an + * array, toString may or may not print it in a human-readable form. + * + * @param arg the value to stringify + * @return a string representation of arg. + */ + def stringOf(arg: Any): String = stringOf(arg, scala.Int.MaxValue) + def stringOf(arg: Any, maxElements: Int): String = { + def packageOf(x: AnyRef) = x.getClass.getPackage match { + case null => "" + case p => p.getName + } + def isScalaClass(x: AnyRef) = packageOf(x) startsWith "scala." + def isScalaCompilerClass(x: AnyRef) = packageOf(x) startsWith "scala.tools.nsc." + + // includes specialized subclasses and future proofed against hypothetical TupleN (for N > 22) + def isTuple(x: Any) = x != null && x.getClass.getName.startsWith("scala.Tuple") + + // We use reflection because the scala.xml package might not be available + def isSubClassOf(potentialSubClass: Class[_], ofClass: String) = + try { + val classLoader = potentialSubClass.getClassLoader + val clazz = Class.forName(ofClass, /*initialize =*/ false, classLoader) + clazz.isAssignableFrom(potentialSubClass) + } catch { + case cnfe: ClassNotFoundException => false + } + def isXmlNode(potentialSubClass: Class[_]) = isSubClassOf(potentialSubClass, "scala.xml.Node") + def isXmlMetaData(potentialSubClass: Class[_]) = isSubClassOf(potentialSubClass, "scala.xml.MetaData") + + // When doing our own iteration is dangerous + def useOwnToString(x: Any) = x match { + // Range/NumericRange have a custom toString to avoid walking a gazillion elements + case _: Range | _: NumericRange[_] => true + // Sorted collections to the wrong thing (for us) on iteration - ticket #3493 + case _: SortedOps[_, _] => true + // StringBuilder(a, b, c) and similar not so attractive + case _: StringView | _: StringOps | _: StringBuilder => true + // Don't want to evaluate any elements in a view + case _: View[_] => true + // Node extends NodeSeq extends Seq[Node] and MetaData extends Iterable[MetaData] + // -> catch those by isXmlNode and isXmlMetaData. + // Don't want to a) traverse infinity or b) be overly helpful with peoples' custom + // collections which may have useful toString methods - ticket #3710 + // or c) print AbstractFiles which are somehow also Iterable[AbstractFile]s. + case x: Iterable[_] => (!x.isInstanceOf[StrictOptimizedIterableOps[_, AnyConstr, _]]) || !isScalaClass(x) || isScalaCompilerClass(x) || isXmlNode(x.getClass) || isXmlMetaData(x.getClass) + // Otherwise, nothing could possibly go wrong + case _ => false + } + + // A variation on inner for maps so they print -> instead of bare tuples + def mapInner(arg: Any): String = arg match { + case (k, v) => inner(k) + " -> " + inner(v) + case _ => inner(arg) + } + + // Special casing Unit arrays, the value class which uses a reference array type. + def arrayToString(x: AnyRef) = { + if (x.getClass.getComponentType == classOf[BoxedUnit]) + 0 until (array_length(x) min maxElements) map (_ => "()") mkString ("Array(", ", ", ")") + else + x.asInstanceOf[Array[_]].iterator.take(maxElements).map(inner).mkString("Array(", ", ", ")") + } + + // The recursively applied attempt to prettify Array printing. + // Note that iterator is used if possible and foreach is used as a + // last resort, because the parallel collections "foreach" in a + // random order even on sequences. + def inner(arg: Any): String = arg match { + case null => "null" + case "" => "\"\"" + case x: String => if (x.head.isWhitespace || x.last.isWhitespace) "\"" + x + "\"" else x + case x if useOwnToString(x) => x.toString + case x: AnyRef if isArray(x) => arrayToString(x) + case x: scala.collection.Map[_, _] => x.iterator take maxElements map mapInner mkString (x.className + "(", ", ", ")") + case x: Iterable[_] => x.iterator take maxElements map inner mkString (x.className + "(", ", ", ")") + case x: Product1[_] if isTuple(x) => "(" + inner(x._1) + ",)" // that special trailing comma + case x: Product if isTuple(x) => x.productIterator map inner mkString ("(", ",", ")") + case x => x.toString + } + + // The try/catch is defense against iterables which aren't actually designed + // to be iterated, such as some scala.tools.nsc.io.AbstractFile derived classes. + try inner(arg) + catch { + case _: UnsupportedOperationException | _: AssertionError => "" + arg + } + } + + /** stringOf formatted for use in a repl result. */ + def replStringOf(arg: Any, maxElements: Int): String = { + val s = stringOf(arg, maxElements) + val nl = if (s contains "\n") "\n" else "" + + nl + s + "\n" + } + + // Convert arrays to immutable.ArraySeq for use with Java varargs: + def genericWrapArray[T](xs: Array[T]): ArraySeq[T] = + if (xs eq null) null + else ArraySeq.unsafeWrapArray(xs) + def wrapRefArray[T <: AnyRef](xs: Array[T]): ArraySeq[T] = { + if (xs eq null) null + else if (xs.length == 0) ArraySeq.empty[AnyRef].asInstanceOf[ArraySeq[T]] + else new ArraySeq.ofRef[T](xs) + } + def wrapIntArray(xs: Array[Int]): ArraySeq[Int] = if (xs ne null) new ArraySeq.ofInt(xs) else null + def wrapDoubleArray(xs: Array[Double]): ArraySeq[Double] = if (xs ne null) new ArraySeq.ofDouble(xs) else null + def wrapLongArray(xs: Array[Long]): ArraySeq[Long] = if (xs ne null) new ArraySeq.ofLong(xs) else null + def wrapFloatArray(xs: Array[Float]): ArraySeq[Float] = if (xs ne null) new ArraySeq.ofFloat(xs) else null + def wrapCharArray(xs: Array[Char]): ArraySeq[Char] = if (xs ne null) new ArraySeq.ofChar(xs) else null + def wrapByteArray(xs: Array[Byte]): ArraySeq[Byte] = if (xs ne null) new ArraySeq.ofByte(xs) else null + def wrapShortArray(xs: Array[Short]): ArraySeq[Short] = if (xs ne null) new ArraySeq.ofShort(xs) else null + def wrapBooleanArray(xs: Array[Boolean]): ArraySeq[Boolean] = if (xs ne null) new ArraySeq.ofBoolean(xs) else null + def wrapUnitArray(xs: Array[Unit]): ArraySeq[Unit] = if (xs ne null) new ArraySeq.ofUnit(xs) else null +} From 49a3bf75f0af0b0a774df66b0dde3df1359a2a75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 4 Jun 2018 19:09:50 +0200 Subject: [PATCH 0769/2665] Bring in changes from 16f58a13eeea78ebac98440d44667cf23a1ab766. "Remove Float range and Double range" --- .../scala/collection/immutable/Range.scala | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/scalalib/overrides-2.13/scala/collection/immutable/Range.scala b/scalalib/overrides-2.13/scala/collection/immutable/Range.scala index 8c89fe0f18..fe060cf3bc 100644 --- a/scalalib/overrides-2.13/scala/collection/immutable/Range.scala +++ b/scalalib/overrides-2.13/scala/collection/immutable/Range.scala @@ -484,26 +484,6 @@ object Range { NumericRange.inclusive(start, end, step) } - // Double works by using a BigDecimal under the hood for precise - // stepping, but mapping the sequence values back to doubles with - // .doubleValue. This constructs the BigDecimals by way of the - // String constructor (valueOf) instead of the Double one, which - // is necessary to keep 0.3d at 0.3 as opposed to - // 0.299999999999999988897769753748434595763683319091796875 or so. - object Double { - implicit val bigDecAsIntegral: Numeric.BigDecimalAsIfIntegral = Numeric.BigDecimalAsIfIntegral - implicit val doubleAsIntegral: Numeric.DoubleAsIfIntegral = Numeric.DoubleAsIfIntegral - def toBD(x: Double): BigDecimal = scala.math.BigDecimal valueOf x - - @deprecated("use Range.BigDecimal instead", "2.12.6") - def apply(start: Double, end: Double, step: Double) = - BigDecimal(toBD(start), toBD(end), toBD(step)) mapRange (_.doubleValue) - - @deprecated("use Range.BigDecimal.inclusive instead", "2.12.6") - def inclusive(start: Double, end: Double, step: Double) = - BigDecimal.inclusive(toBD(start), toBD(end), toBD(step)) mapRange (_.doubleValue) - } - // As there is no appealing default step size for not-really-integral ranges, // we offer a partially constructed object. class Partial[T, U](private val f: T => U) extends AnyVal { From ce83df971746fda912c03730f921def067ed952d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 4 Jun 2018 19:13:18 +0200 Subject: [PATCH 0770/2665] Bring in changes from d8f5f34ca7461f38bc2466208bf2a87a4644aace. "Remove () from iterator" --- .../scala/collection/immutable/NumericRange.scala | 2 +- scalalib/overrides-2.13/scala/collection/immutable/Range.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scalalib/overrides-2.13/scala/collection/immutable/NumericRange.scala b/scalalib/overrides-2.13/scala/collection/immutable/NumericRange.scala index 69f69051c2..7ad51d34a1 100644 --- a/scalalib/overrides-2.13/scala/collection/immutable/NumericRange.scala +++ b/scalalib/overrides-2.13/scala/collection/immutable/NumericRange.scala @@ -42,7 +42,7 @@ sealed class NumericRange[T]( with StrictOptimizedSeqOps[T, IndexedSeq, IndexedSeq[T]] with Serializable { self => - override def iterator() = new Iterator[T] { + override def iterator = new Iterator[T] { import num.mkNumericOps private var _hasNext = !self.isEmpty diff --git a/scalalib/overrides-2.13/scala/collection/immutable/Range.scala b/scalalib/overrides-2.13/scala/collection/immutable/Range.scala index fe060cf3bc..e3a54b6951 100644 --- a/scalalib/overrides-2.13/scala/collection/immutable/Range.scala +++ b/scalalib/overrides-2.13/scala/collection/immutable/Range.scala @@ -56,7 +56,7 @@ sealed abstract class Range( with StrictOptimizedSeqOps[Int, IndexedSeq, IndexedSeq[Int]] with Serializable { range => - override def iterator(): Iterator[Int] = new RangeIterator(start, step, lastElement, isEmpty) + override def iterator: Iterator[Int] = new RangeIterator(start, step, lastElement, isEmpty) private def gap = end.toLong - start.toLong private def isExact = gap % step == 0 From 9759146d11c973b17a717b35f17437d14ab2fb83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 13 Jun 2018 14:52:27 +0200 Subject: [PATCH 0771/2665] Bring in changes from d6d874a2cc1bd4809f0761b4336a6c91a3fc9bb7. "use AbstractIterator instead of Iterator" --- .../scala/collection/immutable/NumericRange.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scalalib/overrides-2.13/scala/collection/immutable/NumericRange.scala b/scalalib/overrides-2.13/scala/collection/immutable/NumericRange.scala index 7ad51d34a1..bb11f11d88 100644 --- a/scalalib/overrides-2.13/scala/collection/immutable/NumericRange.scala +++ b/scalalib/overrides-2.13/scala/collection/immutable/NumericRange.scala @@ -1,6 +1,6 @@ package scala.collection.immutable -import scala.collection.{SeqFactory, IterableFactory, IterableOnce, Iterator, StrictOptimizedIterableOps} +import scala.collection.{AbstractIterator, SeqFactory, IterableFactory, IterableOnce, Iterator, StrictOptimizedIterableOps} import java.lang.String @@ -42,7 +42,7 @@ sealed class NumericRange[T]( with StrictOptimizedSeqOps[T, IndexedSeq, IndexedSeq[T]] with Serializable { self => - override def iterator = new Iterator[T] { + override def iterator: Iterator[T] = new AbstractIterator[T] { import num.mkNumericOps private var _hasNext = !self.isEmpty From 8c0a3579a994ecd89de035f028f26d61573f9853 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 13 Jun 2018 12:11:14 +0200 Subject: [PATCH 0772/2665] Bring in changes from 5d56f69ffc07ae96347b5a0a6c1dd5c17cfaa8df. "Proxy-based serialization for all collections" --- .../collection/immutable/NumericRange.scala | 40 ++++++++++--------- .../scala/collection/immutable/Range.scala | 10 ++--- .../scala/collection/mutable/Buffer.scala | 1 + .../scala/reflect/Manifest.scala | 8 ++-- 4 files changed, 32 insertions(+), 27 deletions(-) diff --git a/scalalib/overrides-2.13/scala/collection/immutable/NumericRange.scala b/scalalib/overrides-2.13/scala/collection/immutable/NumericRange.scala index bb11f11d88..c160fa6643 100644 --- a/scalalib/overrides-2.13/scala/collection/immutable/NumericRange.scala +++ b/scalalib/overrides-2.13/scala/collection/immutable/NumericRange.scala @@ -39,25 +39,9 @@ sealed class NumericRange[T]( extends AbstractSeq[T] with IndexedSeq[T] with IndexedSeqOps[T, IndexedSeq, IndexedSeq[T]] - with StrictOptimizedSeqOps[T, IndexedSeq, IndexedSeq[T]] - with Serializable { self => + with StrictOptimizedSeqOps[T, IndexedSeq, IndexedSeq[T]] { self => - override def iterator: Iterator[T] = new AbstractIterator[T] { - import num.mkNumericOps - - private var _hasNext = !self.isEmpty - private var _next: T = start - private val lastElement: T = if (_hasNext) last else start - override def knownSize: Int = if (_hasNext) num.toInt((lastElement - _next) / step) + 1 else 0 - def hasNext: Boolean = _hasNext - def next(): T = { - if (!_hasNext) Iterator.empty.next() - val value = _next - _hasNext = value != lastElement - _next = num.plus(value, step) - value - } - } + override def iterator: Iterator[T] = new NumericRange.NumericRangeIterator(this, num) /** Note that NumericRange must be invariant so that constructs * such as "1L to 10 by 5" do not infer the range type as AnyVal. @@ -277,6 +261,8 @@ sealed class NumericRange[T]( val stepped = if (step == 1) "" else s" by $step" s"${empty}NumericRange $start $preposition $end$stepped" } + + override protected[this] def writeReplace(): AnyRef = this } /** A companion object for numeric ranges. @@ -405,5 +391,21 @@ object NumericRange { Numeric.LongIsIntegral -> Ordering.Long ) -} + @SerialVersionUID(3L) + private final class NumericRangeIterator[T](self: NumericRange[T], num: Integral[T]) extends AbstractIterator[T] with Serializable { + import num.mkNumericOps + private var _hasNext = !self.isEmpty + private var _next: T = self.start + private val lastElement: T = if (_hasNext) self.last else self.start + override def knownSize: Int = if (_hasNext) num.toInt((lastElement - _next) / self.step) + 1 else 0 + def hasNext: Boolean = _hasNext + def next(): T = { + if (!_hasNext) Iterator.empty.next() + val value = _next + _hasNext = value != lastElement + _next = num.plus(value, self.step) + value + } + } +} diff --git a/scalalib/overrides-2.13/scala/collection/immutable/Range.scala b/scalalib/overrides-2.13/scala/collection/immutable/Range.scala index e3a54b6951..b06dfda12e 100644 --- a/scalalib/overrides-2.13/scala/collection/immutable/Range.scala +++ b/scalalib/overrides-2.13/scala/collection/immutable/Range.scala @@ -1,8 +1,7 @@ package scala package collection.immutable -import collection.{Iterator, SeqFactory} - +import collection.{AbstractIterator, Iterator, SeqFactory} import java.lang.String import scala.collection.mutable.Builder @@ -53,8 +52,7 @@ sealed abstract class Range( extends AbstractSeq[Int] with IndexedSeq[Int] with IndexedSeqOps[Int, IndexedSeq, IndexedSeq[Int]] - with StrictOptimizedSeqOps[Int, IndexedSeq, IndexedSeq[Int]] - with Serializable { range => + with StrictOptimizedSeqOps[Int, IndexedSeq, IndexedSeq[Int]] { range => override def iterator: Iterator[Int] = new RangeIterator(start, step, lastElement, isEmpty) @@ -382,6 +380,7 @@ sealed abstract class Range( s"${prefix}Range $start $preposition $end$stepped" } + override protected[this] def writeReplace(): AnyRef = this } /** @@ -506,12 +505,13 @@ object Range { * @param lastElement The last element included in the Range * @param initiallyEmpty Whether the Range was initially empty or not */ +@SerialVersionUID(3L) private class RangeIterator( start: Int, step: Int, lastElement: Int, initiallyEmpty: Boolean -) extends Iterator[Int] { +) extends AbstractIterator[Int] with Serializable { private var _hasNext: Boolean = !initiallyEmpty private var _next: Int = start override def knownSize: Int = if (_hasNext) (lastElement - _next) / step + 1 else 0 diff --git a/scalalib/overrides-2.13/scala/collection/mutable/Buffer.scala b/scalalib/overrides-2.13/scala/collection/mutable/Buffer.scala index 8f58461a83..8c62526e34 100644 --- a/scalalib/overrides-2.13/scala/collection/mutable/Buffer.scala +++ b/scalalib/overrides-2.13/scala/collection/mutable/Buffer.scala @@ -172,4 +172,5 @@ trait IndexedOptimizedBuffer[A] extends IndexedOptimizedSeq[A] with Buffer[A] { object Buffer extends SeqFactory.Delegate[Buffer](js.WrappedArray) /** Explicit instantiation of the `Buffer` trait to reduce class file size in subclasses. */ +@SerialVersionUID(3L) abstract class AbstractBuffer[A] extends AbstractSeq[A] with Buffer[A] diff --git a/scalalib/overrides-2.13/scala/reflect/Manifest.scala b/scalalib/overrides-2.13/scala/reflect/Manifest.scala index f38ce59e4d..48cdda41c7 100644 --- a/scalalib/overrides-2.13/scala/reflect/Manifest.scala +++ b/scalalib/overrides-2.13/scala/reflect/Manifest.scala @@ -289,12 +289,14 @@ object ManifestFactory { def wildcardType[T](lowerBound: Manifest[_], upperBound: Manifest[_]): Manifest[T] = new WildcardManifest[T](lowerBound, upperBound) - private class IntersectionTypeManifest[T](parents: Seq[Manifest[_]]) extends Manifest[T] { - def runtimeClass = parents.head.runtimeClass + private class IntersectionTypeManifest[T](parents: Array[Manifest[_]]) extends Manifest[T] { + // We use an `Array` instead of a `Seq` for `parents` to avoid cyclic dependencies during deserialization + // which can cause serialization proxies to leak and cause a ClassCastException. + def runtimeClass = parents(0).runtimeClass override def toString = parents.mkString(" with ") } /** Manifest for the intersection type `parents_0 with ... with parents_n`. */ def intersectionType[T](parents: Manifest[_]*): Manifest[T] = - new IntersectionTypeManifest[T](parents) + new IntersectionTypeManifest[T](parents.toArray) } From 153d89538c7f7f54faf2022c85c23168e74da3ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 13 Jun 2018 14:32:48 +0200 Subject: [PATCH 0773/2665] Bring in changes from fe536153f1d1e51ee59eb22de1760c00c84b671c. "More restrictive permissions for Range methods" --- .../scala/collection/immutable/Range.scala | 80 +++++++++---------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/scalalib/overrides-2.13/scala/collection/immutable/Range.scala b/scalalib/overrides-2.13/scala/collection/immutable/Range.scala index b06dfda12e..d3ed5d8436 100644 --- a/scalalib/overrides-2.13/scala/collection/immutable/Range.scala +++ b/scalalib/overrides-2.13/scala/collection/immutable/Range.scala @@ -54,22 +54,22 @@ sealed abstract class Range( with IndexedSeqOps[Int, IndexedSeq, IndexedSeq[Int]] with StrictOptimizedSeqOps[Int, IndexedSeq, IndexedSeq[Int]] { range => - override def iterator: Iterator[Int] = new RangeIterator(start, step, lastElement, isEmpty) + final override def iterator: Iterator[Int] = new RangeIterator(start, step, lastElement, isEmpty) - private def gap = end.toLong - start.toLong - private def isExact = gap % step == 0 - private def hasStub = isInclusive || !isExact - private def longLength = gap / step + ( if (hasStub) 1 else 0 ) + private[this] def gap = end.toLong - start.toLong + private[this] def isExact = gap % step == 0 + private[this] def hasStub = isInclusive || !isExact + private[this] def longLength = gap / step + ( if (hasStub) 1 else 0 ) def isInclusive: Boolean - override val isEmpty: Boolean = ( + final override val isEmpty: Boolean = ( (start > end && step > 0) || (start < end && step < 0) || (start == end && !isInclusive) ) - private val numRangeElements: Int = { + private[this] val numRangeElements: Int = { if (step == 0) throw new IllegalArgumentException("step cannot be 0.") else if (isEmpty) 0 else { @@ -79,10 +79,10 @@ sealed abstract class Range( } } - def length = if (numRangeElements < 0) fail() else numRangeElements + final def length = if (numRangeElements < 0) fail() else numRangeElements // This field has a sensible value only for non-empty ranges - private val lastElement = step match { + private[this] val lastElement = step match { case 1 => if (isInclusive) end else end-1 case -1 => if (isInclusive) end else end+1 case _ => @@ -95,8 +95,8 @@ sealed abstract class Range( /** The last element of this range. This method will return the correct value * even if there are too many elements to iterate over. */ - override def last: Int = if (isEmpty) Nil.head else lastElement - override def head: Int = if (isEmpty) Nil.head else start + final override def last: Int = if (isEmpty) Nil.head else lastElement + final override def head: Int = if (isEmpty) Nil.head else start /** Creates a new range containing all the elements of this range except the last one. * @@ -104,7 +104,7 @@ sealed abstract class Range( * * @return a new range consisting of all the elements of this range except the last one. */ - override def init: Range = { + final override def init: Range = { if (isEmpty) Nil.init @@ -117,7 +117,7 @@ sealed abstract class Range( * * @return a new range consisting of all the elements of this range except the first one. */ - override def tail: Range = { + final override def tail: Range = { if (isEmpty) Nil.tail if (numRangeElements == 1) newEmptyRange(end) @@ -125,7 +125,7 @@ sealed abstract class Range( else new Range.Exclusive(start + step, end, step) } - protected def copy(start: Int = start, end: Int = end, step: Int = step, isInclusive: Boolean = isInclusive): Range = + final protected def copy(start: Int = start, end: Int = end, step: Int = step, isInclusive: Boolean = isInclusive): Range = if(isInclusive) new Range.Inclusive(start, end, step) else new Range.Exclusive(start, end, step) /** Create a new range with the `start` and `end` values of this range and @@ -133,27 +133,27 @@ sealed abstract class Range( * * @return a new range with a different step */ - def by(step: Int): Range = copy(start, end, step) + final def by(step: Int): Range = copy(start, end, step) // Check cannot be evaluated eagerly because we have a pattern where // ranges are constructed like: "x to y by z" The "x to y" piece // should not trigger an exception. So the calculation is delayed, // which means it will not fail fast for those cases where failing was // correct. - private def validateMaxLength(): Unit = { + private[this] def validateMaxLength(): Unit = { if (numRangeElements < 0) fail() } - private def fail() = Range.fail(start, end, step, isInclusive) + private[this] def fail() = Range.fail(start, end, step, isInclusive) @throws[IndexOutOfBoundsException] - def apply(idx: Int): Int = { + final def apply(idx: Int): Int = { validateMaxLength() if (idx < 0 || idx >= numRangeElements) throw new IndexOutOfBoundsException(idx.toString) else start + (step * idx) } - /*@`inline`*/ override def foreach[@specialized(Unit) U](f: Int => U): Unit = { + /*@`inline`*/ final override def foreach[@specialized(Unit) U](f: Int => U): Unit = { // Implementation chosen on the basis of favorable microbenchmarks // Note--initialization catches step == 0 so we don't need to here if (!isEmpty) { @@ -171,7 +171,7 @@ sealed abstract class Range( * @param n the number of elements to take. * @return a new range consisting of `n` first elements. */ - override def take(n: Int): Range = + final override def take(n: Int): Range = if (n <= 0 || isEmpty) newEmptyRange(start) else if (n >= numRangeElements && numRangeElements >= 0) this else { @@ -185,7 +185,7 @@ sealed abstract class Range( * @param n the number of elements to drop. * @return a new range consisting of all the elements of this range except `n` first elements. */ - override def drop(n: Int): Range = + final override def drop(n: Int): Range = if (n <= 0 || isEmpty) this else if (n >= numRangeElements && numRangeElements >= 0) newEmptyRange(end) else { @@ -198,7 +198,7 @@ sealed abstract class Range( * * $doesNotUseBuilders */ - override def takeRight(n: Int): Range = { + final override def takeRight(n: Int): Range = { if (n <= 0) newEmptyRange(start) else if (numRangeElements >= 0) drop(numRangeElements - n) else { @@ -214,7 +214,7 @@ sealed abstract class Range( * * $doesNotUseBuilders */ - override def dropRight(n: Int): Range = { + final override def dropRight(n: Int): Range = { if (n <= 0) this else if (numRangeElements >= 0) take(numRangeElements - n) else { @@ -226,7 +226,7 @@ sealed abstract class Range( } // Advance from the start while we meet the given test - private def argTakeWhile(p: Int => Boolean): Long = { + private[this] def argTakeWhile(p: Int => Boolean): Long = { if (isEmpty) start else { var current = start @@ -237,7 +237,7 @@ sealed abstract class Range( } } - override def takeWhile(p: Int => Boolean): Range = { + final override def takeWhile(p: Int => Boolean): Range = { val stop = argTakeWhile(p) if (stop==start) newEmptyRange(start) else { @@ -247,7 +247,7 @@ sealed abstract class Range( } } - override def dropWhile(p: Int => Boolean): Range = { + final override def dropWhile(p: Int => Boolean): Range = { val stop = argTakeWhile(p) if (stop == start) this else { @@ -257,7 +257,7 @@ sealed abstract class Range( } } - override def span(p: Int => Boolean): (Range, Range) = { + final override def span(p: Int => Boolean): (Range, Range) = { val border = argTakeWhile(p) if (border == start) (newEmptyRange(start), this) else { @@ -275,7 +275,7 @@ sealed abstract class Range( * @param until the element at which to end (not included in the range) * @return a new range consisting of a contiguous interval of values in the old range */ - override def slice(from: Int, until: Int): Range = + final override def slice(from: Int, until: Int): Range = if (from <= 0) take(until) else if (until >= numRangeElements && numRangeElements >= 0) drop(from) else { @@ -285,31 +285,31 @@ sealed abstract class Range( } // Overridden only to refine the return type - override def splitAt(n: Int): (Range, Range) = (take(n), drop(n)) + final override def splitAt(n: Int): (Range, Range) = (take(n), drop(n)) // Methods like apply throw exceptions on invalid n, but methods like take/drop // are forgiving: therefore the checks are with the methods. - private def locationAfterN(n: Int) = start + (step * n) + private[this] def locationAfterN(n: Int) = start + (step * n) // When one drops everything. Can't ever have unchecked operations // like "end + 1" or "end - 1" because ranges involving Int.{ MinValue, MaxValue } // will overflow. This creates an exclusive range where start == end // based on the given value. - private def newEmptyRange(value: Int) = new Range.Exclusive(value, value, step) + private[this] def newEmptyRange(value: Int) = new Range.Exclusive(value, value, step) /** Returns the reverse of this range. */ - override def reverse: Range = + final override def reverse: Range = if (isEmpty) this else new Range.Inclusive(last, start, -step) /** Make range inclusive. */ - def inclusive: Range = + final def inclusive: Range = if (isInclusive) this else new Range.Inclusive(start, end, step) - def contains(x: Int) = { + final def contains(x: Int) = { if (x == end && !isInclusive) false else if (step > 0) { if (x < start || x > end) false @@ -321,7 +321,7 @@ sealed abstract class Range( } } - override def sum[B >: Int](implicit num: Numeric[B]): Int = { + final override def sum[B >: Int](implicit num: Numeric[B]): Int = { if (num eq scala.math.Numeric.IntIsIntegral) { // this is normal integer range with usual addition. arithmetic series formula can be used if (isEmpty) 0 @@ -343,20 +343,20 @@ sealed abstract class Range( } } - override def min[A1 >: Int](implicit ord: Ordering[A1]): Int = + final override def min[A1 >: Int](implicit ord: Ordering[A1]): Int = if (ord eq Ordering.Int) { if (step > 0) head else last } else super.min(ord) - override def max[A1 >: Int](implicit ord: Ordering[A1]): Int = + final override def max[A1 >: Int](implicit ord: Ordering[A1]): Int = if (ord eq Ordering.Int) { if (step > 0) last else head } else super.max(ord) - override def equals(other: Any) = other match { + final override def equals(other: Any) = other match { case x: Range => // Note: this must succeed for overfull ranges (length > Int.MaxValue) if (isEmpty) x.isEmpty // empty sequences are equal @@ -373,14 +373,14 @@ sealed abstract class Range( /* Note: hashCode can't be overridden without breaking Seq's equals contract. */ - override def toString: String = { + final override def toString: String = { val preposition = if (isInclusive) "to" else "until" val stepped = if (step == 1) "" else s" by $step" val prefix = if (isEmpty) "empty " else if (!isExact) "inexact " else "" s"${prefix}Range $start $preposition $end$stepped" } - override protected[this] def writeReplace(): AnyRef = this + final override protected[this] def writeReplace(): AnyRef = this } /** From a279837834149067096320856d4c0a1b80e25a82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 13 Jun 2018 14:45:12 +0200 Subject: [PATCH 0774/2665] Bring in changes from 43bf2351ec0f251f4d6cdc5a0fdac75c7ea6ce1e. "make private[this] if possible" --- scalalib/overrides-2.13/scala/Console.scala | 6 +++--- scalalib/overrides-2.13/scala/Enumeration.scala | 6 +++--- .../scala/collection/immutable/NumericRange.scala | 8 ++++---- .../overrides-2.13/scala/collection/immutable/Range.scala | 4 ++-- .../overrides-2.13/scala/reflect/NameTransformer.scala | 8 ++++---- scalalib/overrides-2.13/scala/runtime/ScalaRunTime.scala | 4 ++-- scalalib/overrides/scala/App.scala | 4 ++-- scalalib/overrides/scala/Symbol.scala | 8 ++++---- 8 files changed, 24 insertions(+), 24 deletions(-) diff --git a/scalalib/overrides-2.13/scala/Console.scala b/scalalib/overrides-2.13/scala/Console.scala index b85f8dc3d0..3eb1a55f70 100644 --- a/scalalib/overrides-2.13/scala/Console.scala +++ b/scalalib/overrides-2.13/scala/Console.scala @@ -20,9 +20,9 @@ import scala.util.DynamicVariable * @version 1.0, 03/09/2003 */ object Console extends DeprecatedConsole with AnsiColor { - private val outVar = new DynamicVariable[PrintStream](java.lang.System.out) - private val errVar = new DynamicVariable[PrintStream](java.lang.System.err) - private val inVar = new DynamicVariable[BufferedReader](null) + private[this] val outVar = new DynamicVariable[PrintStream](java.lang.System.out) + private[this] val errVar = new DynamicVariable[PrintStream](java.lang.System.err) + private[this] val inVar = new DynamicVariable[BufferedReader](null) //new BufferedReader(new InputStreamReader(java.lang.System.in))) protected def setOutDirect(out: PrintStream): Unit = outVar.value = out diff --git a/scalalib/overrides-2.13/scala/Enumeration.scala b/scalalib/overrides-2.13/scala/Enumeration.scala index cd2469466b..547cbcd7fd 100644 --- a/scalalib/overrides-2.13/scala/Enumeration.scala +++ b/scalalib/overrides-2.13/scala/Enumeration.scala @@ -98,7 +98,7 @@ abstract class Enumeration (initial: Int) extends Serializable { /** The mapping from the integer used to identify values to their * names. */ - private val nmap: mutable.Map[Int, String] = new mutable.HashMap + private[this] val nmap: mutable.Map[Int, String] = new mutable.HashMap /** The values of this enumeration as a set. */ @@ -121,11 +121,11 @@ abstract class Enumeration (initial: Int) extends Serializable { /** The highest integer amongst those used to identify values in this * enumeration. */ - private var topId = initial + private[this] var topId = initial /** The lowest integer amongst those used to identify values in this * enumeration, but no higher than 0. */ - private var bottomId = if(initial < 0) initial else 0 + private[this] var bottomId = if(initial < 0) initial else 0 /** The one higher than the highest integer amongst those used to identify * values in this enumeration. */ diff --git a/scalalib/overrides-2.13/scala/collection/immutable/NumericRange.scala b/scalalib/overrides-2.13/scala/collection/immutable/NumericRange.scala index c160fa6643..e99c0cc1c5 100644 --- a/scalalib/overrides-2.13/scala/collection/immutable/NumericRange.scala +++ b/scalalib/overrides-2.13/scala/collection/immutable/NumericRange.scala @@ -175,7 +175,7 @@ sealed class NumericRange[T]( // XXX This may be incomplete. new NumericRange[A](fm(start), fm(end), fm(step), isInclusive) { - private lazy val underlyingRange: NumericRange[T] = self + private[this] lazy val underlyingRange: NumericRange[T] = self override def foreach[@specialized(Unit) U](f: A => U): Unit = { underlyingRange foreach (x => f(fm(x))) } override def isEmpty = underlyingRange.isEmpty override def apply(idx: Int): A = fm(underlyingRange(idx)) @@ -395,9 +395,9 @@ object NumericRange { private final class NumericRangeIterator[T](self: NumericRange[T], num: Integral[T]) extends AbstractIterator[T] with Serializable { import num.mkNumericOps - private var _hasNext = !self.isEmpty - private var _next: T = self.start - private val lastElement: T = if (_hasNext) self.last else self.start + private[this] var _hasNext = !self.isEmpty + private[this] var _next: T = self.start + private[this] val lastElement: T = if (_hasNext) self.last else self.start override def knownSize: Int = if (_hasNext) num.toInt((lastElement - _next) / self.step) + 1 else 0 def hasNext: Boolean = _hasNext def next(): T = { diff --git a/scalalib/overrides-2.13/scala/collection/immutable/Range.scala b/scalalib/overrides-2.13/scala/collection/immutable/Range.scala index d3ed5d8436..4401f09bb1 100644 --- a/scalalib/overrides-2.13/scala/collection/immutable/Range.scala +++ b/scalalib/overrides-2.13/scala/collection/immutable/Range.scala @@ -512,8 +512,8 @@ private class RangeIterator( lastElement: Int, initiallyEmpty: Boolean ) extends AbstractIterator[Int] with Serializable { - private var _hasNext: Boolean = !initiallyEmpty - private var _next: Int = start + private[this] var _hasNext: Boolean = !initiallyEmpty + private[this] var _next: Int = start override def knownSize: Int = if (_hasNext) (lastElement - _next) / step + 1 else 0 def hasNext: Boolean = _hasNext @throws[NoSuchElementException] diff --git a/scalalib/overrides-2.13/scala/reflect/NameTransformer.scala b/scalalib/overrides-2.13/scala/reflect/NameTransformer.scala index fcb8bdd1b8..386c4e1208 100644 --- a/scalalib/overrides-2.13/scala/reflect/NameTransformer.scala +++ b/scalalib/overrides-2.13/scala/reflect/NameTransformer.scala @@ -22,13 +22,13 @@ object NameTransformer { val SETTER_SUFFIX_STRING = "_$eq" val TRAIT_SETTER_SEPARATOR_STRING = "$_setter_$" - private val nops = 128 - private val ncodes = 26 * 26 + private[this] val nops = 128 + private[this] val ncodes = 26 * 26 private class OpCodes(val op: Char, val code: String, val next: OpCodes) - private val op2code = new Array[String](nops) - private val code2op = new Array[OpCodes](ncodes) + private[this] val op2code = new Array[String](nops) + private[this] val code2op = new Array[OpCodes](ncodes) private def enterOp(op: Char, code: String) = { op2code(op.toInt) = code val c = (code.charAt(1) - 'a') * 26 + code.charAt(2) - 'a' diff --git a/scalalib/overrides-2.13/scala/runtime/ScalaRunTime.scala b/scalalib/overrides-2.13/scala/runtime/ScalaRunTime.scala index 84d7395106..e96eef6ef9 100644 --- a/scalalib/overrides-2.13/scala/runtime/ScalaRunTime.scala +++ b/scalalib/overrides-2.13/scala/runtime/ScalaRunTime.scala @@ -147,8 +147,8 @@ object ScalaRunTime { /** A helper for case classes. */ def typedProductIterator[T](x: Product): Iterator[T] = { new AbstractIterator[T] { - private var c: Int = 0 - private val cmax = x.productArity + private[this] var c: Int = 0 + private[this] val cmax = x.productArity def hasNext = c < cmax def next() = { val result = x.productElement(c) diff --git a/scalalib/overrides/scala/App.scala b/scalalib/overrides/scala/App.scala index ff5f073f6d..fd378ac8aa 100644 --- a/scalalib/overrides/scala/App.scala +++ b/scalalib/overrides/scala/App.scala @@ -47,9 +47,9 @@ trait App extends DelayedInit { */ protected def args: Array[String] = _args - private var _args: Array[String] = _ + private[this] var _args: Array[String] = _ - private val initCode = new ListBuffer[() => Unit] + private[this] val initCode = new ListBuffer[() => Unit] /** The init hook. This saves all initialization code for execution within `main`. * This method is normally never called directly from user code. diff --git a/scalalib/overrides/scala/Symbol.scala b/scalalib/overrides/scala/Symbol.scala index e1902ab128..f72b36016a 100644 --- a/scalalib/overrides/scala/Symbol.scala +++ b/scalalib/overrides/scala/Symbol.scala @@ -63,10 +63,10 @@ private[scala] abstract class UniquenessCache[K >: js.String, V >: Null] import java.util.WeakHashMap import java.util.concurrent.locks.ReentrantReadWriteLock - private val rwl = new ReentrantReadWriteLock() - private val rlock = rwl.readLock - private val wlock = rwl.writeLock - private val map = new WeakHashMap[K, WeakReference[V]] + private[this] val rwl = new ReentrantReadWriteLock() + private[this] val rlock = rwl.readLock + private[this] val wlock = rwl.writeLock + private[this] val map = new WeakHashMap[K, WeakReference[V]] protected def valueFromKey(k: K): V protected def keyFromValue(v: V): Option[K] From 7b16a2dec465d705dec232069501bb4b40160634 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 13 Jun 2018 14:47:09 +0200 Subject: [PATCH 0775/2665] Bring in changes from 1efde187a9f76722f49454425821d5d2a8dae98d. "Deprecate override of stringPrefix" --- scalalib/overrides-2.13/scala/runtime/ScalaRunTime.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scalalib/overrides-2.13/scala/runtime/ScalaRunTime.scala b/scalalib/overrides-2.13/scala/runtime/ScalaRunTime.scala index e96eef6ef9..7db18f0a53 100644 --- a/scalalib/overrides-2.13/scala/runtime/ScalaRunTime.scala +++ b/scalalib/overrides-2.13/scala/runtime/ScalaRunTime.scala @@ -238,8 +238,8 @@ object ScalaRunTime { case x: String => if (x.head.isWhitespace || x.last.isWhitespace) "\"" + x + "\"" else x case x if useOwnToString(x) => x.toString case x: AnyRef if isArray(x) => arrayToString(x) - case x: scala.collection.Map[_, _] => x.iterator take maxElements map mapInner mkString (x.className + "(", ", ", ")") - case x: Iterable[_] => x.iterator take maxElements map inner mkString (x.className + "(", ", ", ")") + case x: scala.collection.Map[_, _] => x.iterator take maxElements map mapInner mkString (x.collectionClassName + "(", ", ", ")") + case x: Iterable[_] => x.iterator take maxElements map inner mkString (x.collectionClassName + "(", ", ", ")") case x: Product1[_] if isTuple(x) => "(" + inner(x._1) + ",)" // that special trailing comma case x: Product if isTuple(x) => x.productIterator map inner mkString ("(", ",", ")") case x => x.toString From 68d9421c73b886e20c946839f1ab731f4628fd0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 14 Jun 2018 11:57:14 +0200 Subject: [PATCH 0776/2665] Bring in changes from 330fbd6583968101a38f3e9543d63a385fed82e2. "Make more ValueSet operations return a ValueSet" --- scalalib/overrides-2.13/scala/Enumeration.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scalalib/overrides-2.13/scala/Enumeration.scala b/scalalib/overrides-2.13/scala/Enumeration.scala index 547cbcd7fd..7b20dae1c2 100644 --- a/scalalib/overrides-2.13/scala/Enumeration.scala +++ b/scalalib/overrides-2.13/scala/Enumeration.scala @@ -256,7 +256,7 @@ abstract class Enumeration (initial: Int) extends Serializable { class ValueSet private[ValueSet] (private[this] var nnIds: immutable.BitSet) extends immutable.AbstractSet[Value] with immutable.SortedSet[Value] - with immutable.SetOps[Value, immutable.Set, ValueSet] + with immutable.SortedSetOps[Value, immutable.SortedSet, ValueSet] with StrictOptimizedIterableOps[Value, immutable.Set, ValueSet] with Serializable { From 0d9c2f82694c43bd41844594742bbf9d0183e68b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 13 Jun 2018 16:53:54 +0200 Subject: [PATCH 0777/2665] Make the jUnitPlugin support cases where List.apply is inherited. In 2.13.0-M5, `object List` does not define its `apply` method itself anymore. Instead, it is inherited from `StrictOptimizedSeqFactory`. That however exhibits two issues when trying to generate a list from our `jUnitPlugin`: * The symbol `List_apply` is not enough to generate the proper call anymore, since `List_apply.owner` is not the `List$` module class, so we need to give more info to `gen.mkMethodCall`. * The result type of the inherited method is `Object` after erasure, so we need to explicitly cast it to `List`. --- .../org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala index f1fbaa40fb..3cac96a105 100644 --- a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala +++ b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala @@ -388,7 +388,14 @@ class ScalaJSJUnitPlugin(val global: Global) extends NscPlugin { varargsModule, definitions.wrapVarargsArrayMethodName(definitions.ObjectTpe), Nil, List(array)) - gen.mkMethodCall(definitions.List_apply, List(wrappedArray)) + val listApply = typer.typed { + gen.mkMethodCall(definitions.ListModule, nme.apply, Nil, List(wrappedArray)) + } + + if (listApply.tpe.typeSymbol.isSubClass(definitions.ListClass)) + listApply + else + gen.mkCast(listApply, definitions.ListClass.toTypeConstructor) } def mkMethodList(tpe: TypeTree)(testMethods: List[MethodSymbol]): Tree = From 7584ee570dfc942f35132a6532c96294070d29f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 13 Jun 2018 16:57:27 +0200 Subject: [PATCH 0778/2665] Adapt RangesTest not to depend on Double ranges. `NumericRange`s of `Float`s and `Double`s do not exist anymore in Scala 2.13.0-M5. We remove tests that were specifically testing those, and use ranges of `BigDecimal` for tests of `NumericRange`. --- .../testsuite/scalalib/RangesTest.scala | 50 +++++-------------- 1 file changed, 12 insertions(+), 38 deletions(-) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/RangesTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/RangesTest.scala index cdcd78a3a1..e904495ba2 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/RangesTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/RangesTest.scala @@ -12,6 +12,7 @@ import org.junit.Assert._ import org.junit.Assume._ import scala.collection.immutable.NumericRange +import scala.math.BigDecimal import org.scalajs.testsuite.utils.Platform._ @@ -26,21 +27,6 @@ class RangesTest { assertEquals((0 until 10).toList, Iterable.range(0, 10).toList) } - @Test def Iterable_range_bug_on_floating_points_issue_1974(): Unit = { - val range = 0.0 to 6.283 by 1.0 - - assertEquals(0.0, range.start, 0.0) - assertEquals(6.283, range.end, 0.0) - assertEquals(1.0, range.step, 0.0) - assertTrue(range.isInclusive) - - assertEquals(0.0, range.head, 0.0) - assertEquals(6.0, range.last, 0.0) - assertEquals(7, range.length) - - assertEquals(List(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0), range.toList) - } - @Test def NumericRange_overflow_issue_2407(): Unit = { assumeFalse("Assumed not on JVM for 2.10.X", executingInJVM && scalaVersion.startsWith("2.10.")) @@ -67,43 +53,31 @@ class RangesTest { if (scalaVersion.startsWith("2.10.") || scalaVersion.startsWith("2.11.")) { assertEquals("Range(1, 3, 5, 7, 9)", (1 to 10 by 2).toString) assertEquals("Range()", (1 until 1 by 2).toString) - assertTrue((0.0 to 1.0).toString.startsWith("scala.collection.immutable.Range$Partial")) + assertTrue( + (BigDecimal(0.0) to BigDecimal(1.0)).toString.startsWith("scala.collection.immutable.Range$Partial")) assertEquals("Range(0, 1)", (0 to 1).toString) } else { assertEquals("inexact Range 1 to 10 by 2", (1 to 10 by 2).toString) assertEquals("empty Range 1 until 1 by 2", (1 until 1 by 2).toString) - assertEquals("Range requires step", (0.0 to 1.0).toString) + assertEquals("Range requires step", (BigDecimal(0.0) to BigDecimal(1.0)).toString) assertEquals("Range 0 to 1", (0 to 1).toString) } } @Test def NumericRange_toString_issue_2412(): Unit = { if (scalaVersion.startsWith("2.10.") || scalaVersion.startsWith("2.11.")) { - assertEquals("NumericRange(0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6, 0.7, " + - "0.7999999999999999, 0.8999999999999999, 0.9999999999999999)", - (0.1 to 1.0 by 0.1).toString()) - assertEquals( - "NumericRange(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9)", - Range.Double(0.1, 1.0, 0.1).toString) + assertEquals("NumericRange(0, 2, 4, 6, 8, 10)", + NumericRange.inclusive(0, 10, 2).toString()) + assertEquals("NumericRange(0, 2, 4, 6, 8)", + NumericRange(0, 10, 2).toString) } else { - assertEquals(s"NumericRange 0.1 to ${1.0} by 0.1", - (0.1 to 1.0 by 0.1).toString()) - assertEquals( - s"NumericRange 0.1 until ${1.0} by 0.1 (using NumericRange 0.1 until ${1.0} by 0.1 of BigDecimal)", - Range.Double(0.1, 1.0, 0.1).toString) + assertEquals("NumericRange 0 to 10 by 2", + NumericRange.inclusive(0, 10, 2).toString()) + assertEquals("NumericRange 0 until 10 by 2", + NumericRange(0, 10, 2).toString) } } - @Test def NumericRange_min_issue_2655(): Unit = { - val y = 1.0 to 10.0 by 1.0 - assertEquals(1.0, y.min, 0.0) - } - - @Test def NumericRange_max_issue_2655(): Unit = { - val y = 1.0 to 10.0 by 1.0 - assertEquals(10.0, y.max, 0.0) - } - @Test def NumericRange_with_arbitrary_integral(): Unit = { // This is broken in Scala JVM up to (including) 2.11.8, 2.12.1 (SI-10086). assumeFalse("Assumed not on JVM for 2.10.X", From b04e03280f90a3ef9bc1ba4bcd357f2561d8d11f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 13 Jun 2018 16:59:34 +0200 Subject: [PATCH 0779/2665] Adapt some imports after the change of precedence in 2.13.0-M5. Precedence of imports wrt. symbols in the current package (but in a different compilation unit) has been changed in 2.13.0-M5. See https://github.com/scala/scala/pull/6589. This caused some breakages in our codebase, of course, which this commit fixes. --- .../org/scalajs/core/compiler/GenJSCode.scala | 3 +-- .../scalajs/core/compiler/GenJSExports.scala | 2 +- .../org/scalajs/core/compiler/JSEncoding.scala | 2 +- .../scala/scalajs/js/JSConverters.scala | 18 ++++++++++-------- .../scala/scalajs/js/JSConverters.scala | 18 ++++++++++-------- 5 files changed, 23 insertions(+), 20 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 47d7201ef8..4db7e5e219 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -20,8 +20,7 @@ import org.scalajs.core.ir import ir.{Trees => js, Types => jstpe, ClassKind, Hashers} import ir.Trees.OptimizerHints -import util.ScopedVar -import util.VarBox +import org.scalajs.core.compiler.util.{ScopedVar, VarBox} import ScopedVar.withScopedVars /** Generate JavaScript code and output it to disk diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index 8be2b13eb1..23ef7dcac4 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -15,7 +15,7 @@ import org.scalajs.core.ir import ir.{Trees => js, Types => jstpe} import ir.Trees.OptimizerHints -import util.ScopedVar +import org.scalajs.core.compiler.util.ScopedVar import ScopedVar.withScopedVars /** Generation of exports for JavaScript diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala index 9a4c9966b9..66e99560dc 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala @@ -12,7 +12,7 @@ import scala.tools.nsc._ import org.scalajs.core.ir import ir.{Trees => js, Types => jstpe} -import util.ScopedVar +import org.scalajs.core.compiler.util.ScopedVar import ScopedVar.withScopedVars /** Encoding of symbol names for JavaScript diff --git a/library/src/main/scala-new-collections/scala/scalajs/js/JSConverters.scala b/library/src/main/scala-new-collections/scala/scalajs/js/JSConverters.scala index b67366830a..eb1f5a7989 100644 --- a/library/src/main/scala-new-collections/scala/scalajs/js/JSConverters.scala +++ b/library/src/main/scala-new-collections/scala/scalajs/js/JSConverters.scala @@ -65,29 +65,31 @@ object JSConverters extends JSConvertersLowPrioImplicits { implicit class JSRichIterable[T]( val __self: scala.collection.Iterable[T]) extends AnyVal { - @inline final def toJSIterable: Iterable[T] = new IterableAdapter(__self) + @inline final def toJSIterable: js.Iterable[T] = new IterableAdapter(__self) } implicit class JSRichIterator[T]( val __self: scala.collection.Iterator[T]) extends AnyVal { - @inline final def toJSIterator: Iterator[T] = new IteratorAdapter(__self) + @inline final def toJSIterator: js.Iterator[T] = new IteratorAdapter(__self) } - private class IterableAdapter[+T](col: collection.Iterable[T]) extends Iterable[T] { + private class IterableAdapter[+T](col: collection.Iterable[T]) + extends js.Iterable[T] { + @JSName(Symbol.iterator) - final def jsIterator(): Iterator[T] = col.iterator.toJSIterator + final def jsIterator(): js.Iterator[T] = col.iterator.toJSIterator } private class IteratorAdapter[+T]( - it: scala.collection.Iterator[T]) extends Iterator[T] { - final def next(): Iterator.Entry[T] = { + it: scala.collection.Iterator[T]) extends js.Iterator[T] { + final def next(): js.Iterator.Entry[T] = { if (it.hasNext) { - new Iterator.Entry[T] { + new js.Iterator.Entry[T] { val done: Boolean = false val value: T = it.next() } } else { - new Iterator.Entry[T] { + new js.Iterator.Entry[T] { val done: Boolean = true // Evil cast to work around typing. By specification, reading `value` // is undefined behavior, so this is ok. diff --git a/library/src/main/scala-old-collections/scala/scalajs/js/JSConverters.scala b/library/src/main/scala-old-collections/scala/scalajs/js/JSConverters.scala index 4dd745ecb5..9acd65d01e 100644 --- a/library/src/main/scala-old-collections/scala/scalajs/js/JSConverters.scala +++ b/library/src/main/scala-old-collections/scala/scalajs/js/JSConverters.scala @@ -65,29 +65,31 @@ object JSConverters extends JSConvertersLowPrioImplicits { implicit class JSRichGenIterable[T]( val __self: GenIterable[T]) extends AnyVal { - @inline final def toJSIterable: Iterable[T] = new IterableAdapter(__self) + @inline final def toJSIterable: js.Iterable[T] = new IterableAdapter(__self) } implicit class JSRichIterator[T]( val __self: scala.collection.Iterator[T]) extends AnyVal { - @inline final def toJSIterator: Iterator[T] = new IteratorAdapter(__self) + @inline final def toJSIterator: js.Iterator[T] = new IteratorAdapter(__self) } - private class IterableAdapter[+T](col: GenIterable[T]) extends Iterable[T] { + private class IterableAdapter[+T](col: GenIterable[T]) + extends js.Iterable[T] { + @JSName(Symbol.iterator) - final def jsIterator(): Iterator[T] = col.iterator.toJSIterator + final def jsIterator(): js.Iterator[T] = col.iterator.toJSIterator } private class IteratorAdapter[+T]( - it: scala.collection.Iterator[T]) extends Iterator[T] { - final def next(): Iterator.Entry[T] = { + it: scala.collection.Iterator[T]) extends js.Iterator[T] { + final def next(): js.Iterator.Entry[T] = { if (it.hasNext) { - new Iterator.Entry[T] { + new js.Iterator.Entry[T] { val done: Boolean = false val value: T = it.next() } } else { - new Iterator.Entry[T] { + new js.Iterator.Entry[T] { val done: Boolean = true // Evil cast to work around typing. By specification, reading `value` // is undefined behavior, so this is ok. From bb4c651cea04a32ed9775c449e1b51d1606d3203 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 13 Jun 2018 17:03:27 +0200 Subject: [PATCH 0780/2665] Do not refer to the deprecated int-shift-by-long operations. Shifts of non-`Long` lhs'es by `Long` rhs'es are deprecated in Scala 2.13.0-M5. We avoid them while preserving behavior by explicitly calling `.toInt` on the rhs. --- javalanglib/src/main/scala/java/lang/Character.scala | 6 +++--- .../scala/scala/scalajs/runtime/IntegerReflectiveCall.scala | 6 +++--- .../scala/scala/scalajs/runtime/NumberReflectiveCall.scala | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/javalanglib/src/main/scala/java/lang/Character.scala b/javalanglib/src/main/scala/java/lang/Character.scala index 8503d518d3..d13c6477fd 100644 --- a/javalanglib/src/main/scala/java/lang/Character.scala +++ b/javalanglib/src/main/scala/java/lang/Character.scala @@ -45,11 +45,11 @@ class Character(private val value: scala.Char) protected def +(x: String): String = value + x protected def <<(x: scala.Int): scala.Int = value << x - protected def <<(x: scala.Long): scala.Int = value << x + protected def <<(x: scala.Long): scala.Int = value << x.toInt protected def >>>(x: scala.Int): scala.Int = value >>> x - protected def >>>(x: scala.Long): scala.Int = value >>> x + protected def >>>(x: scala.Long): scala.Int = value >>> x.toInt protected def >>(x: scala.Int): scala.Int = value >> x - protected def >>(x: scala.Long): scala.Int = value >> x + protected def >>(x: scala.Long): scala.Int = value >> x.toInt protected def ==(x: scala.Byte): scala.Boolean = value == x protected def ==(x: scala.Short): scala.Boolean = value == x diff --git a/library/src/main/scala/scala/scalajs/runtime/IntegerReflectiveCall.scala b/library/src/main/scala/scala/scalajs/runtime/IntegerReflectiveCall.scala index a2197449fa..e718d69ebc 100644 --- a/library/src/main/scala/scala/scalajs/runtime/IntegerReflectiveCall.scala +++ b/library/src/main/scala/scala/scalajs/runtime/IntegerReflectiveCall.scala @@ -64,11 +64,11 @@ class IntegerReflectiveCall(value: Int) { // scalastyle:on disallow.space.before.token def <<(x: scala.Int): scala.Int = value << x - def <<(x: scala.Long): scala.Int = value << x + def <<(x: scala.Long): scala.Int = value << x.toInt def >>>(x: scala.Int): scala.Int = value >>> x - def >>>(x: scala.Long): scala.Int = value >>> x + def >>>(x: scala.Long): scala.Int = value >>> x.toInt def >>(x: scala.Int): scala.Int = value >> x - def >>(x: scala.Long): scala.Int = value >> x + def >>(x: scala.Long): scala.Int = value >> x.toInt def |(x: scala.Byte): scala.Int = value | x def |(x: scala.Short): scala.Int = value | x diff --git a/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala b/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala index 93cea6dec7..957e8862d5 100644 --- a/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala +++ b/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala @@ -139,11 +139,11 @@ class NumberReflectiveCall(value: Double) { // scalastyle:on disallow.space.before.token def <<(x: scala.Int): scala.Int = value.toInt << x - def <<(x: scala.Long): scala.Int = value.toInt << x + def <<(x: scala.Long): scala.Int = value.toInt << x.toInt def >>>(x: scala.Int): scala.Int = value.toInt >>> x - def >>>(x: scala.Long): scala.Int = value.toInt >>> x + def >>>(x: scala.Long): scala.Int = value.toInt >>> x.toInt def >>(x: scala.Int): scala.Int = value.toInt >> x - def >>(x: scala.Long): scala.Int = value.toInt >> x + def >>(x: scala.Long): scala.Int = value.toInt >> x.toInt def |(x: scala.Byte): scala.Int = value.toInt | x def |(x: scala.Short): scala.Int = value.toInt | x From b939d92f86bf7f2607525784baec9e408bafd8ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 13 Jun 2018 17:04:37 +0200 Subject: [PATCH 0781/2665] Do not rely on any2stringAdd. It has been deprecated in Scala 2.13.0-M5. --- .../src/main/scala/java/lang/Character.scala | 2 +- .../src/main/scala/java/lang/Class.scala | 2 +- .../src/main/scala/java/math/Conversion.scala | 22 +++++++++---------- .../main/scala/java/util/AbstractMap.scala | 4 ++-- javalib/src/main/scala/java/util/Arrays.scala | 2 +- javalib/src/main/scala/java/util/Date.scala | 4 ++-- .../src/main/scala/java/util/Formatter.scala | 2 +- .../src/main/scala/java/util/Hashtable.scala | 2 +- .../scala/java/util/regex/GroupStartMap.scala | 2 +- .../runtime/NumberReflectiveCall.scala | 2 +- 10 files changed, 22 insertions(+), 22 deletions(-) diff --git a/javalanglib/src/main/scala/java/lang/Character.scala b/javalanglib/src/main/scala/java/lang/Character.scala index d13c6477fd..3e99eeaaee 100644 --- a/javalanglib/src/main/scala/java/lang/Character.scala +++ b/javalanglib/src/main/scala/java/lang/Character.scala @@ -42,7 +42,7 @@ class Character(private val value: scala.Char) protected def unary_- : scala.Int = -value // scalastyle:on disallow.space.before.token - protected def +(x: String): String = value + x + protected def +(x: String): String = "" + value + x protected def <<(x: scala.Int): scala.Int = value << x protected def <<(x: scala.Long): scala.Int = value << x.toInt diff --git a/javalanglib/src/main/scala/java/lang/Class.scala b/javalanglib/src/main/scala/java/lang/Class.scala index 0a3af26ced..b59c290d56 100644 --- a/javalanglib/src/main/scala/java/lang/Class.scala +++ b/javalanglib/src/main/scala/java/lang/Class.scala @@ -84,7 +84,7 @@ final class Class[A] private (data: ScalaJSClassData[A]) extends Object { scala.scalajs.runtime.SemanticsUtils.asInstanceOfCheck( (this eq classOf[Nothing]) || (obj != null && !isRawJSType && !isInstance(obj)), - new ClassCastException(obj + " is not an instance of " + getName)) + new ClassCastException("" + obj + " is not an instance of " + getName)) obj.asInstanceOf[A] } diff --git a/javalib/src/main/scala/java/math/Conversion.scala b/javalib/src/main/scala/java/math/Conversion.scala index a0cef18f02..25c042d786 100644 --- a/javalib/src/main/scala/java/math/Conversion.scala +++ b/javalib/src/main/scala/java/math/Conversion.scala @@ -100,7 +100,7 @@ private[math] object Conversion { @tailrec def innerLoop(): Unit = { currentChar -= 1 - result = Character.forDigit(resDigit % radix, radix) + result + result = Character.forDigit(resDigit % radix, radix).toString + result resDigit /= radix if(resDigit != 0 && currentChar != 0) innerLoop() @@ -111,7 +111,7 @@ private[math] object Conversion { var i: Int = 0 while (i < delta && currentChar > 0) { currentChar -= 1 - result = '0' + result + result = "0" + result i += 1 } i = tempLen - 1 @@ -130,14 +130,14 @@ private[math] object Conversion { while (j < 8 && currentChar > 0) { resDigit = digits(i) >> (j << 2) & 0xf currentChar -= 1 - result = java.lang.Character.forDigit(resDigit, 16) + result + result = resDigit.toHexString + result j += 1 } } } // strip leading zero's result = result.dropWhile(_ == '0') - if (sign == -1) '-' + result + if (sign == -1) "-" + result else result } } @@ -192,7 +192,7 @@ private[math] object Conversion { result = dropLeadingZeros(result) - if (sign < 0) '-' + result + if (sign < 0) "-" + result else result } } @@ -241,7 +241,7 @@ private[math] object Conversion { val prev = v v /= 10 currentChar -= 1 - result = (48 + (prev - v * 10)).toChar + result + result = (prev - v * 10).toInt.toString + result } while (v != 0) val exponent = resLengthInChars - currentChar - scale - 1 @@ -254,24 +254,24 @@ private[math] object Conversion { } else { // special case 2 for (j <- 0 until -index) { - result = '0' + result + result = "0" + result } result = "0." + result } } else if (scale !=0) { var result1 = exponent.toString if (exponent > 0) - result1 = '+' + result1 - result1 = 'E' + result1 + result1 = "+" + result1 + result1 = "E" + result1 result = if (resLengthInChars - currentChar > 1) - result(0) + "." + result.substring(1) + result1 + result.substring(0, 1) + "." + result.substring(1) + result1 else result + result1 } - if (negNumber) '-' + result + if (negNumber) "-" + result else result } } diff --git a/javalib/src/main/scala/java/util/AbstractMap.scala b/javalib/src/main/scala/java/util/AbstractMap.scala index 6db60eb327..fea7941b30 100644 --- a/javalib/src/main/scala/java/util/AbstractMap.scala +++ b/javalib/src/main/scala/java/util/AbstractMap.scala @@ -48,7 +48,7 @@ object AbstractMap { entryHashCode(this) override def toString(): String = - getKey + "=" + getValue + "" + getKey + "=" + getValue } class SimpleImmutableEntry[K, V](key: K, value: V) @@ -71,7 +71,7 @@ object AbstractMap { entryHashCode(this) override def toString(): String = - getKey + "=" + getValue + "" + getKey + "=" + getValue } } diff --git a/javalib/src/main/scala/java/util/Arrays.scala b/javalib/src/main/scala/java/util/Arrays.scala index 84dd394d5b..e09ef784c8 100644 --- a/javalib/src/main/scala/java/util/Arrays.scala +++ b/javalib/src/main/scala/java/util/Arrays.scala @@ -593,7 +593,7 @@ object Arrays { @inline private def checkIndicesForCopyOfRange( len: Int, start: Int, end: Int): Unit = { if (start > end) - throw new IllegalArgumentException(start + " > " + end) + throw new IllegalArgumentException("" + start + " > " + end) SemanticsUtils.arrayIndexOutOfBoundsCheck(start < 0 || start > len, new ArrayIndexOutOfBoundsException) } diff --git a/javalib/src/main/scala/java/util/Date.scala b/javalib/src/main/scala/java/util/Date.scala index 484d32d4f7..342745cdb3 100644 --- a/javalib/src/main/scala/java/util/Date.scala +++ b/javalib/src/main/scala/java/util/Date.scala @@ -98,7 +98,7 @@ class Date private (private val date: js.Date) extends Object @Deprecated def toGMTString(): String = { - date.getUTCDate() + " " + Months(date.getUTCMonth()) + " " + + "" + date.getUTCDate() + " " + Months(date.getUTCMonth()) + " " + date.getUTCFullYear() + " " + pad0(date.getUTCHours()) + ":" + pad0(date.getUTCMinutes()) + ":" + pad0(date.getUTCSeconds()) +" GMT" @@ -106,7 +106,7 @@ class Date private (private val date: js.Date) extends Object @Deprecated def toLocaleString(): String = { - date.getDate() + "-" + Months(date.getMonth()) + "-" + + "" + date.getDate() + "-" + Months(date.getMonth()) + "-" + date.getFullYear() + "-" + pad0(date.getHours()) + ":" + pad0(date.getMinutes()) + ":" + pad0(date.getSeconds()) } diff --git a/javalib/src/main/scala/java/util/Formatter.scala b/javalib/src/main/scala/java/util/Formatter.scala index e91ecd6b26..e6acc0c6f0 100644 --- a/javalib/src/main/scala/java/util/Formatter.scala +++ b/javalib/src/main/scala/java/util/Formatter.scala @@ -105,7 +105,7 @@ final class Formatter(private val dest: Appendable) extends Closeable with Flush def padCaptureSign(argStr: String, prefix: String) = { val firstChar = argStr.charAt(0) if (firstChar == '+' || firstChar == '-') - pad(argStr.substring(1), firstChar+prefix) + pad(argStr.substring(1), firstChar.toString + prefix) else pad(argStr, prefix) } diff --git a/javalib/src/main/scala/java/util/Hashtable.scala b/javalib/src/main/scala/java/util/Hashtable.scala index dabff21e9c..3b3f820e39 100644 --- a/javalib/src/main/scala/java/util/Hashtable.scala +++ b/javalib/src/main/scala/java/util/Hashtable.scala @@ -72,7 +72,7 @@ class Hashtable[K, V] private (inner: mutable.HashMap[Box[Any], V]) new ju.Hashtable[K, V](this) override def toString(): String = - inner.iterator.map(kv => kv._1.inner + "=" + kv._2).mkString("{", ", ", "}") + inner.iterator.map(kv => "" + kv._1.inner + "=" + kv._2).mkString("{", ", ", "}") def keySet(): ju.Set[K] = inner.keySet.map(_.inner.asInstanceOf[K]).asJava diff --git a/javalib/src/main/scala/java/util/regex/GroupStartMap.scala b/javalib/src/main/scala/java/util/regex/GroupStartMap.scala index bcf5bca4db..2792c0d0c3 100644 --- a/javalib/src/main/scala/java/util/regex/GroupStartMap.scala +++ b/javalib/src/main/scala/java/util/regex/GroupStartMap.scala @@ -486,7 +486,7 @@ private[regex] class GroupStartMap(string: String, start: Int, pattern: Pattern) def default = { val e = pattern(pIndex) - addSiblings(Node(e + ""), pIndex + 1, nextGroupIndex) + addSiblings(Node("" + e), pIndex + 1, nextGroupIndex) } (pattern(pIndex): @switch) match { diff --git a/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala b/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala index 957e8862d5..cc711925b7 100644 --- a/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala +++ b/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala @@ -42,7 +42,7 @@ class NumberReflectiveCall(value: Double) { def unary_- : scala.Double = -value // scalastyle:on disallow.space.before.token - def +(x: String): String = value + x + def +(x: String): String = "" + value + x def ==(x: scala.Byte): scala.Boolean = value == x def ==(x: scala.Short): scala.Boolean = value == x From 1ea99ad9ad0bbf5987437a1e1ad0b784d28bd7e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 19 Jun 2018 16:17:48 +0200 Subject: [PATCH 0782/2665] Fix #3152: Scaladoc likes Java 9 starting from Scala 2.12.2. Starting from Scala 2.12.2, Scaladoc can deal with Java 9, so we can reenable `library/doc` from that version onwards. However, probably for a related reason, sbt stops giving `scala.ext.dirs` with Scala 2.12.2+, so we need not to crash if it is not there. --- project/Build.scala | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 8afa84f79b..b38ba5b113 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -171,8 +171,8 @@ object Build { autoAPIMappings := true, // Add Java Scaladoc mapping - apiMappings += { - val rtJar = { + apiMappings ++= { + val optRTJar = { val bootClasspath = System.getProperty("sun.boot.class.path") if (bootClasspath != null) { // JDK <= 8, there is an rt.jar (or classes.jar) on the boot classpath @@ -182,16 +182,20 @@ object Build { val jar = jars.find(matches(_, "rt")) // most JREs .orElse(jars.find(matches(_, "classes"))) // Java 6 on Mac OS X .get - file(jar) + Some(file(jar)) } else { - // JDK >= 9, sbt gives us a fake rt.jar in `scala.ext.dirs` - val scalaExtDirs = System.getProperty("scala.ext.dirs") - file(scalaExtDirs) / "rt.jar" + // JDK >= 9, maybe sbt gives us a fake rt.jar in `scala.ext.dirs` + val scalaExtDirs = Option(System.getProperty("scala.ext.dirs")) + scalaExtDirs.map(extDirs => file(extDirs) / "rt.jar") } } - assert(rtJar.exists, s"$rtJar does not exist") - rtJar -> url(javaDocBaseURL) + optRTJar.fold[Map[File, URL]] { + Map.empty + } { rtJar => + assert(rtJar.exists, s"$rtJar does not exist") + Map(rtJar -> url(javaDocBaseURL)) + } }, /* Add a second Java Scaladoc mapping for cases where Scala actually @@ -1078,8 +1082,25 @@ object Build { // Filter doc sources to remove implementation details from doc. sources in doc := { val prev = (sources in doc).value + val javaV = javaVersion.value + val scalaV = scalaVersion.value + + /* On Java 9+, Scaladoc will crash with "bad constant pool tag 20" + * until version 2.12.1 included. The problem seems to have been + * fixed in 2.12.2, perhaps through + * https://github.com/scala/scala/pull/5711. + * See also #3152. + */ + val mustAvoidJavaDoc = { + javaV >= 9 && { + scalaV.startsWith("2.10.") || + scalaV.startsWith("2.11.") || + scalaV == "2.12.0" || + scalaV == "2.12.1" + } + } - if (javaVersion.value < 9) { + if (!mustAvoidJavaDoc) { def containsFileFilter(s: String): FileFilter = new FileFilter { override def accept(f: File): Boolean = { val path = f.getAbsolutePath.replace('\\', '/') @@ -1096,10 +1117,6 @@ object Build { (sources in doc).value.filter(filter.accept) } else { - /* Work around #3152: library/doc crashes with - * - * on JDK 9. - */ Nil } }, From 82e87d973c592e6507788910283273f965bdfc96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 20 Jun 2018 11:09:37 +0200 Subject: [PATCH 0783/2665] Fix #2609: Add the required NOTICE file about the JUnit port's license. --- NOTICE | 6 + .../main/scala/org/junit/LICENSE-junit.txt | 213 ++++++++++++++++++ 2 files changed, 219 insertions(+) create mode 100644 NOTICE create mode 100644 junit-runtime/src/main/scala/org/junit/LICENSE-junit.txt diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000000..937d8d0dde --- /dev/null +++ b/NOTICE @@ -0,0 +1,6 @@ +This project contains a translation of JUnit 4.12 to Scala.js in +junit-runtime/src/main/scala/org/junit/. The original code can be found at +https://github.com/junit-team/junit4/commit/64155f8a9babcfcf4263cf4d08253a1556e75481 +As a translation, it constitutes a derivative work and is therefore licensed +under the Eclipse Public License v1.0, whose full text can be found in +junit-runtime/src/main/scala/org/junit/LICENSE-junit.txt diff --git a/junit-runtime/src/main/scala/org/junit/LICENSE-junit.txt b/junit-runtime/src/main/scala/org/junit/LICENSE-junit.txt new file mode 100644 index 0000000000..7b5e981e7c --- /dev/null +++ b/junit-runtime/src/main/scala/org/junit/LICENSE-junit.txt @@ -0,0 +1,213 @@ +JUnit + +Eclipse Public License - v 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC +LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM +CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + + a) in the case of the initial Contributor, the initial code and + documentation distributed under this Agreement, and + b) in the case of each subsequent Contributor: + + i) changes to the Program, and + + ii) additions to the Program; + + where such changes and/or additions to the Program originate from and are +distributed by that particular Contributor. A Contribution 'originates' from a +Contributor if it was added to the Program by such Contributor itself or anyone +acting on such Contributor's behalf. Contributions do not include additions to +the Program which: (i) are separate modules of software distributed in +conjunction with the Program under their own license agreement, and (ii) are +not derivative works of the Program. + +"Contributor" means any person or entity that distributes the Program. + +"Licensed Patents " mean patent claims licensable by a Contributor which are +necessarily infringed by the use or sale of its Contribution alone or when +combined with the Program. + +"Program" means the Contributions distributed in accordance with this Agreement. + +"Recipient" means anyone who receives the Program under this Agreement, +including all Contributors. + +2. GRANT OF RIGHTS + + a) Subject to the terms of this Agreement, each Contributor hereby grants +Recipient a non-exclusive, worldwide, royalty-free copyright license to +reproduce, prepare derivative works of, publicly display, publicly perform, +distribute and sublicense the Contribution of such Contributor, if any, and +such derivative works, in source code and object code form. + + b) Subject to the terms of this Agreement, each Contributor hereby grants +Recipient a non-exclusive, worldwide, royalty-free patent license under +Licensed Patents to make, use, sell, offer to sell, import and otherwise +transfer the Contribution of such Contributor, if any, in source code and +object code form. This patent license shall apply to the combination of the +Contribution and the Program if, at the time the Contribution is added by the +Contributor, such addition of the Contribution causes such combination to be +covered by the Licensed Patents. The patent license shall not apply to any +other combinations which include the Contribution. No hardware per se is +licensed hereunder. + + c) Recipient understands that although each Contributor grants the +licenses to its Contributions set forth herein, no assurances are provided by +any Contributor that the Program does not infringe the patent or other +intellectual property rights of any other entity. Each Contributor disclaims +any liability to Recipient for claims brought by any other entity based on +infringement of intellectual property rights or otherwise. As a condition to +exercising the rights and licenses granted hereunder, each Recipient hereby +assumes sole responsibility to secure any other intellectual property rights +needed, if any. For example, if a third party patent license is required to +allow Recipient to distribute the Program, it is Recipient's responsibility to +acquire that license before distributing the Program. + + d) Each Contributor represents that to its knowledge it has sufficient +copyright rights in its Contribution, if any, to grant the copyright license +set forth in this Agreement. + +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form under +its own license agreement, provided that: + + a) it complies with the terms and conditions of this Agreement; and + + b) its license agreement: + + i) effectively disclaims on behalf of all Contributors all warranties and +conditions, express and implied, including warranties or conditions of title +and non-infringement, and implied warranties or conditions of merchantability +and fitness for a particular purpose; + + ii) effectively excludes on behalf of all Contributors all liability for +damages, including direct, indirect, special, incidental and consequential +damages, such as lost profits; + + iii) states that any provisions which differ from this Agreement are +offered by that Contributor alone and not by any other party; and + + iv) states that source code for the Program is available from such +Contributor, and informs licensees how to obtain it in a reasonable manner on +or through a medium customarily used for software exchange. + +When the Program is made available in source code form: + + a) it must be made available under this Agreement; and + + b) a copy of this Agreement must be included with each copy of the +Program. + +Contributors may not remove or alter any copyright notices contained within the +Program. + +Each Contributor must identify itself as the originator of its Contribution, if +any, in a manner that reasonably allows subsequent Recipients to identify the +originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities with +respect to end users, business partners and the like. While this license is +intended to facilitate the commercial use of the Program, the Contributor who +includes the Program in a commercial product offering should do so in a manner +which does not create potential liability for other Contributors. Therefore, if +a Contributor includes the Program in a commercial product offering, such +Contributor ("Commercial Contributor") hereby agrees to defend and indemnify +every other Contributor ("Indemnified Contributor") against any losses, damages +and costs (collectively "Losses") arising from claims, lawsuits and other legal +actions brought by a third party against the Indemnified Contributor to the +extent caused by the acts or omissions of such Commercial Contributor in +connection with its distribution of the Program in a commercial product +offering. The obligations in this section do not apply to any claims or Losses +relating to any actual or alleged intellectual property infringement. In order +to qualify, an Indemnified Contributor must: a) promptly notify the Commercial +Contributor in writing of such claim, and b) allow the Commercial Contributor +to control, and cooperate with the Commercial Contributor in, the defense and +any related settlement negotiations. The Indemnified Contributor may +participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial product +offering, Product X. That Contributor is then a Commercial Contributor. If that +Commercial Contributor then makes performance claims, or offers warranties +related to Product X, those performance claims and warranties are such +Commercial Contributor's responsibility alone. Under this section, the +Commercial Contributor would have to defend claims against the other +Contributors related to those performance claims and warranties, and if a court +requires any other Contributor to pay any damages as a result, the Commercial +Contributor must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR +IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, +NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each +Recipient is solely responsible for determining the appropriateness of using +and distributing the Program and assumes all risks associated with its exercise +of rights under this Agreement, including but not limited to the risks and +costs of program errors, compliance with applicable laws, damage to or loss of +data, programs or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY +CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST +PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY +WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS +GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under applicable +law, it shall not affect the validity or enforceability of the remainder of the +terms of this Agreement, and without further action by the parties hereto, such +provision shall be reformed to the minimum extent necessary to make such +provision valid and enforceable. + +If Recipient institutes patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging that the +Program itself (excluding combinations of the Program with other software or +hardware) infringes such Recipient's patent(s), then such Recipient's rights +granted under Section 2(b) shall terminate as of the date such litigation is +filed. + +All Recipient's rights under this Agreement shall terminate if it fails to +comply with any of the material terms or conditions of this Agreement and does +not cure such failure in a reasonable period of time after becoming aware of +such noncompliance. If all Recipient's rights under this Agreement terminate, +Recipient agrees to cease use and distribution of the Program as soon as +reasonably practicable. However, Recipient's obligations under this Agreement +and any licenses granted by Recipient relating to the Program shall continue +and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, but in +order to avoid inconsistency the Agreement is copyrighted and may only be +modified in the following manner. The Agreement Steward reserves the right to +publish new versions (including revisions) of this Agreement from time to time. +No one other than the Agreement Steward has the right to modify this Agreement. +The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to +serve as the Agreement Steward to a suitable separate entity. Each new version +of the Agreement will be given a distinguishing version number. The Program +(including Contributions) may always be distributed subject to the version of +the Agreement under which it was received. In addition, after a new version of +the Agreement is published, Contributor may elect to distribute the Program +(including its Contributions) under the new version. Except as expressly stated +in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to +the intellectual property of any Contributor under this Agreement, whether +expressly, by implication, estoppel or otherwise. All rights in the Program not +expressly granted under this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and the +intellectual property laws of the United States of America. No party to this +Agreement will bring a legal action under this Agreement more than one year +after the cause of action arose. Each party waives its rights to a jury trial +in any resulting litigation. From 99256378fd05e18c1309cf55a202fc4e8cdfea7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 20 Jun 2018 15:23:13 +0200 Subject: [PATCH 0784/2665] Remove the `ScalaJSGroupID` binary compatibility hack. It was kept there for binary compatibility with sbt-crossproject, but since version 0.5.0, sbt-crossproject does not need it anymore. See commit e7b769a95a24df24d777d7a03eb1f3659a9fcc25 in the sbt-crossproject history. --- .../scala/org/scalajs/sbtplugin/impl/ScalaJSGroupID.scala | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/ScalaJSGroupID.scala diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/ScalaJSGroupID.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/ScalaJSGroupID.scala deleted file mode 100644 index 22822181cb..0000000000 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/ScalaJSGroupID.scala +++ /dev/null @@ -1,7 +0,0 @@ -package org.scalajs.sbtplugin.impl - -/** Exclusively for binary compatibility with sbt-scalajs-crossproject. */ -@deprecated( - "Exclusively for binary compatibility with sbt-scalajs-crossproject.", - "forever") -private[impl] class ScalaJSGroupID From 88ed21bff68b7baddbd2ab93b7ed6c026908d957 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 20 Jun 2018 17:12:10 +0200 Subject: [PATCH 0785/2665] Fix #2576: Explain what to do upon an IRVersionNotSupportedException. The sbt plugin now intercepts `IRVersionNotSupportedExceptions` at all the points where they can be thrown, and enhances their error message with "You may need to upgrade the Scala.js sbt plugin to version x.y.z.". There are several places where they can be thrown because of the potentially lazy loading and deserializing of IR files. --- .../sbtplugin/ScalaJSPluginInternal.scala | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 06ba7dec12..53a7a74f44 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -20,6 +20,7 @@ import org.scalajs.linker.irio._ import org.scalajs.jsenv._ +import org.scalajs.ir.IRVersionNotSupportedException import org.scalajs.ir.Printers.IRTreePrinter import org.scalajs.testadapter.{TestAdapter, HTMLRunnerBuilder, TestAdapterInitializer} @@ -91,6 +92,18 @@ private[sbtplugin] object ScalaJSPluginInternal { } } + private def enhanceIRVersionNotSupportedException[A](body: => A): A = { + try { + body + } catch { + case e: IRVersionNotSupportedException => + throw new IRVersionNotSupportedException(e.version, e.supported, + s"${e.getMessage}\nYou may need to upgrade the Scala.js sbt " + + s"plugin to version ${e.version} or later.", + e) + } + } + private val scalajspParser = { loadForParser(sjsirFilesOnClasspath) { (_, relPaths) => val examples = ScalajspUtils.relPathsExamples(relPaths.getOrElse(Nil)) @@ -186,7 +199,9 @@ private[sbtplugin] object ScalaJSPluginInternal { .withSourceMapURI(relURI(sourceMapFile.getName)) .withJSFileURI(relURI(output.getName)) - linker.link(ir, moduleInitializers, out, sbtLogger2ToolsLogger(log)) + enhanceIRVersionNotSupportedException { + linker.link(ir, moduleInitializers, out, sbtLogger2ToolsLogger(log)) + } logIRCacheStats(log) @@ -222,7 +237,10 @@ private[sbtplugin] object ScalaJSPluginInternal { val classpath = Attributed.data(fullClasspath.value) val irContainers = FileScalaJSIRContainer.fromClasspath(classpath) val log = sbtLogger2ToolsLogger(streams.value.log) - val irFiles = log.time("Update IR cache")(cache.cached(irContainers)) + + val irFiles = enhanceIRVersionNotSupportedException { + log.time("Update IR cache")(cache.cached(irContainers)) + } Attributed .blank[Seq[VirtualScalaJSIRFile]](irFiles) @@ -240,9 +258,11 @@ private[sbtplugin] object ScalaJSPluginInternal { .find(_.relativePath == relPath) .getOrElse(throw new FileNotFoundException(relPath)) - val stdout = new java.io.PrintWriter(System.out) - new IRTreePrinter(stdout).print(vfile.tree) - stdout.flush() + enhanceIRVersionNotSupportedException { + val stdout = new java.io.PrintWriter(System.out) + new IRTreePrinter(stdout).print(vfile.tree) + stdout.flush() + } logIRCacheStats(streams.value.log) }, From 396ff7287d06a7690ac12ed906b878e377fba91d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 18 Jun 2018 18:28:11 +0200 Subject: [PATCH 0786/2665] Fix `Character.digit()` for all code points. It was previously not correct for non-ASCII digits mapping to the 0-9 range. In addition, this commit adds the overload taking an `Int`, which covers supplementary characters. --- .../src/main/scala/java/lang/Character.scala | 77 +++++++++++++++---- .../javalib/lang/CharacterTest.scala | 77 +++++++++++++++++-- 2 files changed, 135 insertions(+), 19 deletions(-) diff --git a/javalanglib/src/main/scala/java/lang/Character.scala b/javalanglib/src/main/scala/java/lang/Character.scala index 3e99eeaaee..43db5be2b2 100644 --- a/javalanglib/src/main/scala/java/lang/Character.scala +++ b/javalanglib/src/main/scala/java/lang/Character.scala @@ -236,21 +236,57 @@ object Character { charTypes(Math.abs(idx)) } - def digit(c: scala.Char, radix: Int): Int = { + @inline + def digit(ch: scala.Char, radix: Int): Int = + digit(ch.toInt, radix) + + @inline // because radix is probably constant at call site + def digit(codePoint: Int, radix: Int): Int = { if (radix > MAX_RADIX || radix < MIN_RADIX) -1 - else if (c >= '0' && c <= '9' && c - '0' < radix) - c - '0' - else if (c >= 'A' && c <= 'Z' && c - 'A' < radix - 10) - c - 'A' + 10 - else if (c >= 'a' && c <= 'z' && c - 'a' < radix - 10) - c - 'a' + 10 - else if (c >= '\uFF21' && c <= '\uFF3A' && - c - '\uFF21' < radix - 10) - c - '\uFF21' + 10 - else if (c >= '\uFF41' && c <= '\uFF5A' && - c - '\uFF41' < radix - 10) - c - '\uFF21' + 10 + else + digitWithValidRadix(codePoint, radix) + } + + private def digitWithValidRadix(codePoint: Int, radix: Int): Int = { + val value = if (codePoint < 256) { + // Fast-path for the ASCII repertoire + if (codePoint >= '0' && codePoint <= '9') + codePoint - '0' + else if (codePoint >= 'A' && codePoint <= 'Z') + codePoint - ('A' - 10) + else if (codePoint >= 'a' && codePoint <= 'z') + codePoint - ('a' - 10) + else + -1 + } else { + if (codePoint >= 0xff21 && codePoint <= 0xff3a) { + // Fullwidth uppercase Latin letter + codePoint - (0xff21 - 10) + } else if (codePoint >= 0xff41 && codePoint <= 0xff5a) { + // Fullwidth lowercase Latin letter + codePoint - (0xff41 - 10) + } else { + // Maybe it is a digit in a non-ASCII script + + // Find the position of the 0 digit corresponding to this code point + val p = Arrays.binarySearch(nonASCIIZeroDigitCodePoints, codePoint) + val zeroCodePointIndex = if (p < 0) -2 - p else p + + /* If the index is below 0, it cannot be a digit. Otherwise, the value + * is the difference between the given codePoint and the code point of + * its corresponding 0. We must ensure that it is not bigger than 9. + */ + if (zeroCodePointIndex < 0) { + -1 + } else { + val v = codePoint - nonASCIIZeroDigitCodePoints(zeroCodePointIndex) + if (v > 9) -1 else v + } + } + } + + if (value < radix) value else -1 } @@ -947,4 +983,19 @@ object Character { deltas(i) += deltas(i - 1) deltas } + + /** All the non-ASCII code points that map to the digit 0. + * + * Each of them is directly followed by 9 other code points mapping to the + * digits 1 to 9, in order. Conversely, there are no other non-ASCII code + * point mapping to digits from 0 to 9. + */ + private[this] lazy val nonASCIIZeroDigitCodePoints: Array[Int] = { + Array[Int](0x660, 0x6f0, 0x7c0, 0x966, 0x9e6, 0xa66, 0xae6, 0xb66, 0xbe6, + 0xc66, 0xce6, 0xd66, 0xe50, 0xed0, 0xf20, 0x1040, 0x1090, 0x17e0, + 0x1810, 0x1946, 0x19d0, 0x1a80, 0x1a90, 0x1b50, 0x1bb0, 0x1c40, 0x1c50, + 0xa620, 0xa8d0, 0xa900, 0xa9d0, 0xaa50, 0xabf0, 0xff10, 0x104a0, + 0x11066, 0x110f0, 0x11136, 0x111d0, 0x116c0, 0x1d7ce, 0x1d7d8, 0x1d7e2, + 0x1d7ec, 0x1d7f6) + } } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/CharacterTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/CharacterTest.scala index d72690cf2a..7ccd2b88bd 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/CharacterTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/CharacterTest.scala @@ -29,12 +29,77 @@ class CharacterTest { } @Test def digit(): Unit = { - assertEquals(10, Character.digit('a', 16)) - assertEquals(-1, Character.digit('}', 5)) - assertEquals(-1, Character.digit('1', 50)) - assertEquals(1, Character.digit('1', 36)) - assertEquals(35, Character.digit('Z', 36)) - assertEquals(11, Character.digit('\uFF22', 20)) + import Character.{MAX_RADIX, MIN_RADIX} + + def test(expected: Int, codePoint: Int): Unit = { + assertEquals(expected, Character.digit(codePoint, MAX_RADIX)) + if (codePoint <= Char.MaxValue) + assertEquals(expected, Character.digit(codePoint.toChar, MAX_RADIX)) + + if (expected != -1) { + assertEquals(expected, + Character.digit(codePoint, Math.max(expected + 1, MIN_RADIX))) + + if (expected >= MIN_RADIX) + assertEquals(-1, Character.digit(codePoint, expected)) + } + } + + // Invalid radix + + assertEquals(-1, Character.digit('0', MIN_RADIX - 1)) + assertEquals(-1, Character.digit('0', MAX_RADIX + 1)) + assertEquals(-1, Character.digit('0', -1)) + + assertEquals(-1, Character.digit('0'.toInt, MIN_RADIX - 1)) + assertEquals(-1, Character.digit('0'.toInt, MAX_RADIX + 1)) + assertEquals(-1, Character.digit('0'.toInt, -1)) + + // A few invalid digits + test(-1, '}') + test(-1, -4) + test(-1, 0xffffff) + test(-1, '0' - 1) + test(-1, '9' + 1) + test(-1, 'A' - 1) + test(-1, 'Z' + 1) + test(-1, 'a' - 1) + test(-1, 'z' + 1) + test(-1, 0xff20) + test(-1, 0xff3b) + test(-1, 0xff40) + test(-1, 0xff5b) + test(-1, 0xbe5) + test(-1, 0xbf0) + test(-1, 0x11065) + test(-1, 0x11070) + test(-1, Int.MinValue) + test(-1, Int.MaxValue) + + // Every single valid digit + + val All0s = Array[Int]('0', 0x660, 0x6f0, 0x7c0, 0x966, 0x9e6, 0xa66, + 0xae6, 0xb66, 0xbe6, 0xc66, 0xce6, 0xd66, 0xe50, 0xed0, 0xf20, 0x1040, + 0x1090, 0x17e0, 0x1810, 0x1946, 0x19d0, 0x1a80, 0x1a90, 0x1b50, 0x1bb0, + 0x1c40, 0x1c50, 0xa620, 0xa8d0, 0xa900, 0xa9d0, 0xaa50, 0xabf0, 0xff10, + 0x104a0, 0x11066, 0x110f0, 0x11136, 0x111d0, 0x116c0, 0x1d7ce, 0x1d7d8, + 0x1d7e2, 0x1d7ec, 0x1d7f6) + + for { + zero <- All0s + offset <- 0 to 9 + } { + test(offset, zero + offset) + } + + val AllAs = Array[Int]('A', 'a', 0xff21, 0xff41) + + for { + a <- AllAs + offset <- 0 to 25 + } { + test(10 + offset, a + offset) + } } @Test def forDigit(): Unit = { From 5653e448982654d63f1df3fc186bc53c4bd35ee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 18 Jun 2018 19:23:15 +0200 Subject: [PATCH 0787/2665] Fix #2935: Support non-ASCII scripts in `parseInt` and `parseLong`. In order to do this, we must stop relying on JavaScript's native `parseInt`. Instead, we loop and parse ourselves, based on the result of `Character.digit`. --- .../src/main/scala/java/lang/Character.scala | 6 +- .../src/main/scala/java/lang/Integer.scala | 67 +++++++++-------- .../src/main/scala/java/lang/Long.scala | 29 ++++---- .../testsuite/javalib/lang/IntegerTest.scala | 71 +++++++++++++++++++ .../testsuite/javalib/lang/LongTest.scala | 8 +++ 5 files changed, 136 insertions(+), 45 deletions(-) diff --git a/javalanglib/src/main/scala/java/lang/Character.scala b/javalanglib/src/main/scala/java/lang/Character.scala index 43db5be2b2..73ef37d765 100644 --- a/javalanglib/src/main/scala/java/lang/Character.scala +++ b/javalanglib/src/main/scala/java/lang/Character.scala @@ -248,7 +248,7 @@ object Character { digitWithValidRadix(codePoint, radix) } - private def digitWithValidRadix(codePoint: Int, radix: Int): Int = { + private[lang] def digitWithValidRadix(codePoint: Int, radix: Int): Int = { val value = if (codePoint < 256) { // Fast-path for the ASCII repertoire if (codePoint >= '0' && codePoint <= '9') @@ -290,6 +290,10 @@ object Character { else -1 } + private[lang] def isZeroDigit(ch: Char): scala.Boolean = + if (ch < 256) ch == '0' + else Arrays.binarySearch(nonASCIIZeroDigitCodePoints, ch.toInt) >= 0 + // ported from https://github.com/gwtproject/gwt/blob/master/user/super/com/google/gwt/emul/java/lang/Character.java def forDigit(digit: Int, radix: Int): Char = { if (radix < MIN_RADIX || radix > MAX_RADIX || digit < 0 || digit >= radix) { diff --git a/javalanglib/src/main/scala/java/lang/Integer.scala b/javalanglib/src/main/scala/java/lang/Integer.scala index a550e1b13b..f23b382b0b 100644 --- a/javalanglib/src/main/scala/java/lang/Integer.scala +++ b/javalanglib/src/main/scala/java/lang/Integer.scala @@ -74,38 +74,43 @@ object Integer { @inline private def parseIntImpl(s: String, radix: scala.Int, signed: scala.Boolean): scala.Int = { - def fail = throw new NumberFormatException(s"""For input string: "$s"""") - - if (s == null || s.size == 0 || - radix < Character.MIN_RADIX || - radix > Character.MAX_RADIX) - fail - else { - var i = if ((signed && s(0) == '-') || s(0) == '+') 1 else 0 - // JavaDoc says: We need at least one digit - if (s.size <= i) fail - else { - // Check each character for validity - while (i < s.size) { - if (Character.digit(s(i), radix) < 0) fail - i += 1 - } - val res = js.Dynamic.global.parseInt(s, radix).asInstanceOf[scala.Double] - - @inline def isOutOfBounds: scala.Boolean = { - if (signed) res > MAX_VALUE || res < MIN_VALUE - else res > 0xFFFFFFFFL || res < 0 - } - - if (res.isNaN || isOutOfBounds) { - fail - } else if (signed) { - res.toInt - } else { - asInt(res) - } - } + + def fail(): Nothing = + throw new NumberFormatException(s"""For input string: "$s"""") + + val len = if (s == null) 0 else s.length + + if (len == 0 || radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) + fail() + + val firstChar = s.charAt(0) + val negative = signed && firstChar == '-' + + val maxAbsValue: scala.Double = { + if (!signed) 0xffffffffL.toDouble + else if (negative) 0x80000000L.toDouble + else 0x7fffffffL.toDouble } + + var i = if (negative || firstChar == '+') 1 else 0 + + // We need at least one digit + if (i >= s.length) + fail() + + var result: scala.Double = 0.0 + while (i != len) { + val digit = Character.digitWithValidRadix(s.charAt(i), radix) + result = result * radix + digit + if (digit == -1 || result > maxAbsValue) + fail() + i += 1 + } + + if (negative) + asInt(-result) + else + asInt(result) } @inline def toString(i: scala.Int): String = "" + i diff --git a/javalanglib/src/main/scala/java/lang/Long.scala b/javalanglib/src/main/scala/java/lang/Long.scala index 1ed00d63b4..dc6f0e95ef 100644 --- a/javalanglib/src/main/scala/java/lang/Long.scala +++ b/javalanglib/src/main/scala/java/lang/Long.scala @@ -230,8 +230,10 @@ object Long { * number of chunks that are necessary to parse any string. */ var firstChunkStart = start - while (firstChunkStart < length && s.charAt(firstChunkStart) == '0') + while (firstChunkStart < length && + Character.isZeroDigit(s.charAt(firstChunkStart))) { firstChunkStart += 1 + } /* After that, if more than 3 chunks are necessary, it means the value * is too large, and does not fit in an unsigned Long. @@ -239,20 +241,21 @@ object Long { if (length - firstChunkStart > 3 * chunkLen) parseLongError(s) - // Check each character for validity - var i = firstChunkStart - while (i < length) { - if (Character.digit(s.charAt(i), radix) < 0) - parseLongError(s) - i += 1 + @noinline def parseChunkAsUInt(chunkStart: Int, chunkEnd: Int): Int = { + var result = 0 // This is an *unsigned* integer + var i = chunkStart + while (i != chunkEnd) { + val digit = Character.digitWithValidRadix(s.charAt(i), radix) + if (digit == -1) + parseLongError(s) + result = result * radix + digit // cannot overflow + i += 1 + } + result } - @inline def parseChunk(chunkStart: Int, chunkEnd: Int): scala.Long = { - val chunk = s.jsSubstring(chunkStart, chunkEnd) - val chunkValueDouble = - js.Dynamic.global.parseInt(chunk, radix).asInstanceOf[scala.Double] - Integer.toUnsignedLong(chunkValueDouble.toInt) - } + @inline def parseChunk(chunkStart: Int, chunkEnd: Int): scala.Long = + Integer.toUnsignedLong(parseChunkAsUInt(chunkStart, chunkEnd)) /* The first chunk is sized so that all subsequent chunks are of size * chunkLen. Note also that the first chunk cannot overflow. diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/IntegerTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/IntegerTest.scala index e8c5dbf692..8af8f67d03 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/IntegerTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/IntegerTest.scala @@ -504,6 +504,15 @@ class IntegerTest { test("+42", 42) test("-0", 0) test("-FF", -255, 16) + + test("\u1045\u1043\u1047", 537) + test("\u1040\u1040\u1040\u1040\u1040\u1040\u1040\u1040\u1040159", 159) + if (!executingInJVMOnJDK6) + test("+\u1040\u1040\u1040\u1040\u1040\u1040\u1040\u1040\u1040159", 159) + test("-\u1040\u1040\u1040\u1040\u1040\u1040\u1040\u1040\u1040159", -159) + + test("\uff21\uff34", 389, 36) + test("\uff41\uff54", 389, 36) } @Test def should_reject_invalid_strings_when_parsing(): Unit = { @@ -516,6 +525,68 @@ class IntegerTest { test("99", 8) test("-") test("") + test(null) + + test("0", 1) + test("12", 1) + test("12", 40) + + /* Supplementary characters are not supported by parseInt, even those that + * are valid digits according to Character.digit(int, int). + */ + test("\ud804\udcf0") + } + + @Test def parseUnsignedInt(): Unit = { + def test(s: String, v: Int, radix: Int = 10): Unit = + assertEquals(v, Integer.parseUnsignedInt(s, radix)) + + test("0", 0) + test("5", 5) + test("127", 127) + test("30000", 30000) + test("Kona", 411787, 27) + if (!executingInJVMOnJDK6) + test("+42", 42) + test("FF", 255, 16) + test("4294967295", 0xffffffff) + test("ffFFffFF", 0xffffffff, 16) + + test("\u1045\u1043\u1047", 537) + test("\u1040\u1040\u1040\u1040\u1040\u1040\u1040\u1040\u1040159", 159) + if (!executingInJVMOnJDK6) + test("+\u1040\u1040\u1040\u1040\u1040\u1040\u1040\u1040\u1040159", 159) + + test("\uff21\uff34", 389, 36) + test("\uff41\uff54", 389, 36) + } + + @Test def parseUnsignedIntInvalid(): Unit = { + def test(s: String, radix: Int = 10): Unit = { + expectThrows(classOf[NumberFormatException], + Integer.parseUnsignedInt(s, radix)) + } + + test("abc") + test("5a") + test("4294967296") + test("ffFFffFF", 20) + test("99", 8) + test("-") + test("") + test(null) + + test("-100") + test("-0") + + test("0", 1) + test("12", 1) + test("12", 40) + + /* Supplementary characters are not supported by parseInt, even those that + * are valid digits according to Character.digit(int, int). + */ + test("\ud804\udcf0") } @Test def should_parse_strings_in_base_16(): Unit = { diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/LongTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/LongTest.scala index 48e74665ab..29bc66c262 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/LongTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/LongTest.scala @@ -137,6 +137,11 @@ class LongTest { test("-4", -4L) test("4000000000", 4000000000L) test("-18014398509482040", -18014398509482040L) + + test("\u19d9\u0f24\u0c6f\u1c47\ua623\u19d9\u0f24\u0c6f\u1c47\ua623", + 9497394973L) + test("\u19d0" * 50 + "\u19d9\u0f24\u0c6f\u1c47\ua623\u19d9\u0f24\u0c6f\u1c47\ua623", + 9497394973L) } @Test def should_reject_invalid_strings_when_parsing(): Unit = { @@ -162,6 +167,9 @@ class LongTest { test("-90000", -0x90000L) test("bfc94973", 3217639795L) test("bfc949733", 51482236723L) + + test("\uff22\uff26\uff23\u19d9\u0f24\u0c6f\u1c47\ua623", 3217639795L) + test("\uff42\uff46\uff43\u19d9\u0f24\u0c6f\u1c47\ua6233", 51482236723L) } @Test def should_parse_strings_in_bases_2_to_36(): Unit = { From 48a418a2db2911996102820a3e7d5906a6449e4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 18 Jun 2018 13:42:16 +0200 Subject: [PATCH 0788/2665] Enhance the test suite of `java.util.Formatter`. This commit improves existing tests for readability, and adds new tests. --- .../javalib/util/FormatterTest.scala | 536 ++++++++++++------ 1 file changed, 373 insertions(+), 163 deletions(-) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/FormatterTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/FormatterTest.scala index c2976d6667..94bdbd21da 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/FormatterTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/FormatterTest.scala @@ -15,226 +15,418 @@ import org.scalajs.testsuite.utils.Platform._ import java.util._ -import java.lang.{ -Double => JDouble, -Float => JFloat, -Integer => JInteger, -Long => JLong, -Byte => JByte, -Short => JShort, -Boolean => JBoolean, -String => JString -} - class FormatterTest { + import FormatterTest._ - class HelperClass - class FormattableClass extends Formattable { - var frm: Formatter = _ - var flags: Int = _ - var width: Int = _ - var precision: Int = _ - var calls = 0 - - def formatTo(frm: Formatter, flags: Int, width: Int, precision: Int): Unit = { - this.calls += 1 - this.flags = flags - this.width = width - this.precision = precision - frm.out().append("foobar") - } - - def expectCalled(times: Int, flags: Int, width: Int, precision: Int): Unit = { - assertEquals(times, this.calls) - assertEquals(flags, this.flags) - assertEquals(width, this.width) - assertEquals(precision, this.precision) - } - - } - - def assertF(expected: String, format: String, args: AnyRef*): Unit = { + def assertF(expected: String, format: String, args: Any*): Unit = { val fmt = new Formatter() - val res = fmt.format(format, args:_*).toString() + val res = fmt.format(format, args.asInstanceOf[Seq[AnyRef]]: _*).toString() fmt.close() assertEquals(expected, res) } - def assertFC(expected: String, format: String, flags: Int, width: Int, - precision: Int): Unit = { - val fc = new FormattableClass - assertF(expected, format, fc) - fc.expectCalled(1, flags, width, precision) + def testWithInfinityAndNaN(conversion: Char, + acceptUpperCase: Boolean = true): Unit = { + + import Double.{NaN, PositiveInfinity => PosInf, NegativeInfinity => NegInf} + + assertF("Infinity", "%" + conversion, PosInf) + assertF("-Infinity", "%" + conversion, NegInf) + assertF(" Infinity", "%010" + conversion, PosInf) + assertF(" -Infinity", "%010" + conversion, NegInf) + assertF("Infinity ", "%-10" + conversion, PosInf) + assertF("(Infinity)", "%(" + conversion, NegInf) + assertF(" (Infinity)", "%(15" + conversion, NegInf) + assertF(" (Infinity)", "%(015" + conversion, NegInf) + assertF(" NaN", "%10" + conversion, NaN) + assertF(" NaN", "%010" + conversion, NaN) + + assertF("+Infinity", "%+" + conversion, PosInf) + assertF(" Infinity", "% " + conversion, PosInf) + assertF("-Infinity", "%+" + conversion, NegInf) + assertF("-Infinity", "% " + conversion, NegInf) + + assertF("+Infinity", "%+(" + conversion, PosInf) + assertF(" Infinity", "% (" + conversion, PosInf) + assertF("(Infinity)", "%+(" + conversion, NegInf) + assertF("(Infinity)", "% (" + conversion, NegInf) + + if (acceptUpperCase) { + val upConversion = conversion.toUpper + assertF("INFINITY", "%" + upConversion, PosInf) + assertF("-INFINITY", "%" + upConversion, NegInf) + assertF("NAN", "%" + upConversion, NaN) + } } def expectFormatterThrows[T <: Throwable](exeption: Class[T], format: String, - args: AnyRef*): Unit = { + args: Any*): T = { val fmt = new Formatter() - assertThrows(exeption, fmt.format(format, args:_*)) + expectThrows(exeption, + fmt.format(format, args.asInstanceOf[Seq[AnyRef]]: _*)) } - // Explicitly define these as `var`'s to avoid any compile-time constant folding - var IntMax: Int = Int.MaxValue - var IntMin: Int = Int.MinValue - var ByteMax: Byte = Byte.MaxValue - var ByteMin: Byte = Byte.MinValue - var ShortMax: Short = Short.MaxValue - var ShortMin: Short = Short.MinValue - @Test def `should_provide_b_conversion`(): Unit = { assertF("false", "%b", null) - assertF(JString.valueOf(true), "%b", true: JBoolean) - assertF(JString.valueOf(false), "%b", false: JBoolean) + assertF("true", "%b", true) + assertF("false", "%b", false) assertF("true", "%b", new HelperClass) + + assertF(" false", "%7b", false) + assertF(" true", "%7b", true) + assertF("false ", "%-7b", false) + assertF("true ", "%-7b", true) + + assertF("FALSE", "%B", false) } @Test def `should_provide_h_conversion`(): Unit = { val x = new HelperClass - assertF(Integer.toHexString(x.hashCode()), "%h", x) - assertF(Integer.toHexString(x.hashCode()).toUpperCase(), "%H", x) + assertF("f1e2a3", "%h", x) + assertF("F1E2A3", "%H", x) + + assertF(" f1e2a3", "%8h", x) + assertF("null", "%h", null) } - @Test def `should_provide_s_conversion`(): Unit = { - assertFC("foobar", "%s", 0, -1, -1) - assertFC("foobar", "%-10s", FormattableFlags.LEFT_JUSTIFY, 10, -1) - assertFC("foobar", "%#-10.2s", - FormattableFlags.LEFT_JUSTIFY | FormattableFlags.ALTERNATE, 10, 2) - assertFC("foobar", "%#10.2S", - FormattableFlags.UPPERCASE | FormattableFlags.ALTERNATE, 10, 2) + @Test def sConversionWithNonFormattable(): Unit = { + assertF("abcdef", "ab%sef", "cd") + assertF("true", "%s", true) + assertF("12345", "%s", 12345) + + assertF("ABCDEF", "%S", "aBcdeF") + assertF(" hello", "%10s", "hello") assertF("hello ", "%-10s", "hello") + + assertF("null", "%s", null) + if (!executingInJVMOnJDK6) expectFormatterThrows(classOf[Exception], "%#s", "hello") } - @Test def `should_fail_s_conversions_without_width`(): Unit = { - // Issue #2246 - expectFormatterThrows(classOf[MissingFormatWidthException], "%-s", "abc") + @Test def sConversionWithFormattable(): Unit = { + import FormattableFlags._ + + class FormattableClass extends Formattable { + private var flags: Int = _ + private var width: Int = _ + private var precision: Int = _ + private var calls: Int = 0 + + def formatTo(frm: Formatter, flags: Int, width: Int, precision: Int): Unit = { + this.calls += 1 + this.flags = flags + this.width = width + this.precision = precision + frm.out().append("foobar") + } + + def expectCalled(times: Int, flags: Int, width: Int, precision: Int): Unit = { + assertEquals(times, this.calls) + assertEquals(flags, this.flags) + assertEquals(width, this.width) + assertEquals(precision, this.precision) + } + } + + def test(format: String, flags: Int, width: Int, precision: Int): Unit = { + val fc = new FormattableClass + assertF("foobar", format, fc) + fc.expectCalled(1, flags, width, precision) + } + + test("%s", 0, -1, -1) + test("%-10s", LEFT_JUSTIFY, 10, -1) + test("%#-10.2s", LEFT_JUSTIFY | ALTERNATE, 10, 2) + test("%#10.2S", UPPERCASE | ALTERNATE, 10, 2) } @Test def `should_provide_c_conversion`(): Unit = { - assertF("! ", "%-5c", new Character('!')) + assertF("a", "%c", 'a') + assertF("A", "%C", 'A') + assertF("A", "%c", 65) + + assertF(" !", "%5c", '!') + assertF("! ", "%-5c", '!') } @Test def `should_provide_d_conversion`(): Unit = { - assertF("5", "%d", new Integer(5)) - assertF("00005", "%05d", new Integer(5)) - assertF(" -10", "%5d", new Integer(-10)) - assertF("-0010", "%05d", new Integer(-10)) + assertF("5", "%d", 5) + assertF("-5", "%d", -5) + + assertF("00005", "%05d", 5) + assertF(" -10", "%5d", -10) + assertF("-0010", "%05d", -10) + + assertF("56", "%(d", 56) + assertF("(56)", "%(d", -56) + assertF(" (56)", "%(8d", -56) + assertF("(000056)", "%(08d", -56) + + assertF(" 56", "% d", 56) + assertF("-56", "% d", -56) + assertF("+56", "%+d", 56) + assertF("-56", "%+d", -56) + + assertF(" 00056", "% 0,6d", 56) + assertF("-00056", "% 0,6d", -56) + assertF(" 00056", "% 0,(6d", 56) + assertF("(0056)", "% 0,(6d", -56) + + assertF("56 ", "%-6d", 56) + assertF("-56 ", "%-6d", -56) } @Test def `should_provide_o_conversion`(): Unit = { - assertF("10", "%o", new JInteger(8)) - assertF("00020", "%05o", new JInteger(16)) - assertF("37777777766", "%5o", new JInteger(-10)) - assertF("37777777766", "%05o", new JInteger(-10)) - assertF("10", "%o", new JByte(8.toByte)) - assertF("00020", "%05o", new JByte(16.toByte)) - assertF("10", "%o", new JShort(8.toShort)) - assertF("00020", "%05o", new JShort(16.toShort)) - if (!executingInJVM) { - // expected:< [377777777]66> but was:< [ 3]66> - assertF(" 37777777766", "%14o", new JByte(-10.toByte)) - // expected:<[377777777]66> but was:<[003]66> - assertF("37777777766", "%05o", new JByte(-10.toByte)) - // expected:<[377777]77766> but was:<[1]77766> - assertF("1777777777777777777773", "%05o", new JLong(-5L)) - // expected:<0000[377777]77766> but was:<0000[000001]77766> - assertF("37777777766", "%5o", new JShort(-10.toShort)) - // expected:<0000[377777]77766> but was:<0000[000001]77766> - assertF("000037777777766", "%015o",new JShort(-10.toShort)) - } + assertF("10", "%o", 8) + + assertF("00020", "%05o", 16) + assertF("37777777766", "%5o", -10) + assertF("37777777766", "%05o", -10) + + assertF(" 21", "%5o", 17) + assertF("21 ", "%-5o", 17) + + assertF("10", "%o", 8.toByte) + assertF("00020", "%05o", 16.toByte) + assertF("10", "%o", 8.toShort) + assertF("00020", "%05o", 16.toShort) + + assertF("30071", "%o", 12345L) + assertF("1777777777777777747707", "%o", -12345L) + + assertF(" 30071", "%10o", 12345L) + assertF("1777777777777777747707", "%10o", -12345L) + assertF("0000030071", "%010o", 12345L) + assertF("1777777777777777747707", "%010o", -12345L) + + assertF("0664", "%#o", 436) + assertF(" 0664", "%#8o", 436) + assertF("00000664", "%#08o", 436) + + /* Negative Bytes and Shorts are formatted as if they were Ints. + * This is a consequence of the non-boxing behavior of numbers in Scala.js. + */ + assertF(" 37777777766", "%14o", asIntOnJVM(-10.toByte)) + assertF("37777777766", "%05o", asIntOnJVM(-10.toByte)) + assertF("37777777766", "%5o", asIntOnJVM(-10.toShort)) + assertF("000037777777766", "%015o", asIntOnJVM(-10.toShort)) } @Test def `should_provide_x_conversion`(): Unit = { - assertF("0x005", "%0#5x", new JInteger(5)) - assertF(" 0x5", "%#5x", new JInteger(5)) - assertF(" 0X5", "%#5X", new JInteger(5)) - assertF("fffffffd", "%x", new JInteger(-3)) - if (!executingInJVM) { - // expected: but was: - assertF("fffffffc", "%x", new JByte(-4.toByte)) - } - assertF("0x005", "%0#5x", new JByte(5.toByte)) - assertF(" 0x5", "%#5x", new JByte(5.toByte)) - assertF(" 0X5", "%#5X", new JByte(5.toByte)) - if (!executingInJVM) { - // expected: but was: - assertF("fffffffd", "%x", new JByte(-3.toByte)) - } - assertF("0x005", "%0#5x", new JShort(5.toShort)) - assertF(" 0x5", "%#5x", new JShort(5.toShort)) - assertF(" 0X5", "%#5X", new JShort(5.toShort)) - if (!executingInJVM) { - // expected: but was: - assertF("fffffffd", "%x", new JShort(-3.toShort)) - } - assertF("fffffffffffffffb", "%x", new JLong(-5L)) - assertF("1A", "%X", new JLong(26L)) + assertF("d431", "%x", 54321) + assertF("ffff2bcf", "%x", -54321) + assertF("D431", "%X", 54321) + assertF("FFFF2BCF", "%X", -54321) + + assertF("0xd431", "%#x", 54321) + assertF("0xffff2bcf", "%#x", -54321) + assertF("0XD431", "%#X", 54321) + assertF("0XFFFF2BCF", "%#X", -54321) + + assertF(" d431", "%13x", 54321) + assertF(" ffff2bcf", "%13x", -54321) + assertF(" D431", "%13X", 54321) + assertF(" FFFF2BCF", "%13X", -54321) + assertF(" 0xd431", "%#13x", 54321) + assertF(" 0xffff2bcf", "%#13x", -54321) + + assertF("d431 ", "%-13x", 54321) + assertF("ffff2bcf ", "%-13x", -54321) + assertF("0xd431 ", "%-#13x", 54321) + assertF("0xffff2bcf ", "%-#13x", -54321) + + assertF("000000000d431", "%013x", 54321) + assertF("00000ffff2bcf", "%013x", -54321) + assertF("0x0000000d431", "%0#13x", 54321) + assertF("0x000ffff2bcf", "%0#13x", -54321) + + assertF("fffffffc", "%x", asIntOnJVM(-4.toByte)) + assertF("0x005", "%0#5x", 5.toByte) + assertF(" 0x5", "%#5x", 5.toByte) + assertF(" 0X5", "%#5X", 5.toByte) + assertF("fffffffd", "%x", asIntOnJVM(-3.toByte)) + + assertF("0x005", "%0#5x", 5.toShort) + assertF(" 0x5", "%#5x", 5.toShort) + assertF(" 0X5", "%#5X", 5.toShort) + assertF("fffffffd", "%x", asIntOnJVM(-3.toShort)) + + assertF("ffffffffffff2bcf", "%x", -54321L) + assertF("28EEA4CB1", "%X", 10987654321L) } @Test def `should_provide_e_conversion`(): Unit = { - assertF("1.000000e+03", "%e", new JDouble(1000)) - assertF("1e+100", "%.0e", new JDouble(1.2e100)) - // We use 1.51e100 in this test, since we seem to have a floating - // imprecision at exactly 1.5e100 that yields to a rounding error - // towards (1e+100 instead of 2e+100) - assertF("2e+100", "%.0e", new JDouble(1.51e100)) - assertF(" 1.20e+100", "%10.2e", new JDouble(1.2e100)) - assertF("001.2000e-21", "%012.4e", new JFloat(1.2e-21f)) - assertF("001.2000E-21", "%012.4E", new JFloat(1.2e-21f)) - assertF("(0001.2000e-21)", "%(015.4e", new JFloat(-1.2e-21f)) - - // Tests with infinity and NaN - assertF("Infinity", "%e", new JDouble(Double.PositiveInfinity)) - assertF("-Infinity", "%e", new JDouble(Double.NegativeInfinity)) - assertF(" Infinity", "%010e", new JDouble(Double.PositiveInfinity)) - assertF("Infinity ", "%-10e", new JDouble(Double.PositiveInfinity)) - assertF("(Infinity)", "%(e", new JDouble(Double.NegativeInfinity)) - assertF(" NaN", "%010e", new JDouble(Double.NaN)) + assertF("1.000000e+03", "%e", 1000.0) + assertF("1e+100", "%.0e", 1.2e100) + assertF("0.000e+00", "%.3e", 0.0) + + /* We use 1.51e100 in this test, since we seem to have a floating point + * imprecision at exactly 1.5e100 that yields to a rounding error towards + * 1e+100 instead of 2e+100. + */ + assertF("2e+100", "%.0e", 1.51e100) + + assertF(" 1.20e+100", "%10.2e", 1.2e100) + + // #3202 Corner case of round-half-up (currently non-compliant) + if (executingInJVM) { + assertF("7.6543215e-20 ", "%-17.7e", 7.65432145e-20) + assertF("-7.6543215e-20 ", "%-17.7e", -7.65432145e-20) + assertF("7.6543216e-20 ", "%-17.7e", 7.65432155e-20) + assertF("-7.6543216e-20 ", "%-17.7e", -7.65432155e-20) + } else { + assertF("7.6543214e-20 ", "%-17.7e", 7.65432145e-20) + assertF("-7.6543214e-20 ", "%-17.7e", -7.65432145e-20) + assertF("7.6543215e-20 ", "%-17.7e", 7.65432155e-20) + assertF("-7.6543215e-20 ", "%-17.7e", -7.65432155e-20) + } + + assertF("001.2000e-21", "%012.4e", 1.2e-21f) + assertF("001.2000E-21", "%012.4E", 1.2e-21f) + assertF("(0001.2000e-21)", "%(015.4e", -1.2e-21f) + + assertF("+1.234560e+30", "%+e", 1.23456e30) + assertF("-1.234560e+30", "%+e", -1.23456e30) + assertF(" 1.234560e+30", "% e", 1.23456e30) + assertF("-1.234560e+30", "% e", -1.23456e30) + + testWithInfinityAndNaN('e') } @Test def `should_provide_g_conversion`(): Unit = { - assertF("5.00000e-05", "%g", new JDouble(.5e-4)) - assertF("0.000300000", "%g", new JDouble(3e-4)) - assertF("0.000300", "%.3g", new JDouble(3e-4)) - assertF("10.0000", "%g", new JDouble(10.0)) - assertF("10.00", "%.4g", new JDouble(10.0)) - assertF("0.0010", "%.2g", new JDouble(1e-3)) - assertF("300000", "%g", new JDouble(3e5)) - assertF("3.00e+05", "%.3g", new JDouble(3e5)) - assertF(" NaN", "%04g", new JDouble(Double.NaN)) + assertF("5.00000e-05", "%g", 0.5e-4) + assertF("-5.00000e-05", "%g", -0.5e-4) + assertF("0.000300000", "%g", 3e-4) + assertF("0.000300", "%.3g", 3e-4) + assertF("10.0000", "%g", 10.0) + assertF("10.00", "%.4g", 10.0) + assertF("0.0010", "%.2g", 1e-3) + assertF("300000", "%g", 3e5) + assertF("3.00e+05", "%.3g", 3e5) + + assertF("005.00000e-05", "%013g", 0.5e-4) + assertF("-05.00000e-05", "%013g", -0.5e-4) + assertF("0000000300000", "%013g", 3e5) + assertF("-000000300000", "%013g", -3e5) + + assertF("00003.00e+05", "%012.3g", 3e5) + assertF("-0003.00e+05", "%012.3g", -3e5) + + assertF("5.00000e-05", "%(g", 0.5e-4) + assertF("(5.00000e-05)", "%(g", -0.5e-4) + assertF("300000", "%(g", 3e5) + assertF("(300000)", "%(g", -3e5) + + assertF("+5.00000e-05", "%(+g", 0.5e-4) + assertF("(5.00000e-05)", "%(+g", -0.5e-4) + assertF("+300000", "%(+g", 3e5) + assertF("(300000)", "%(+g", -3e5) + + assertF(" 5.00000e-05", "% g", 0.5e-4) + assertF("-5.00000e-05", "% g", -0.5e-4) + assertF(" 300000", "% g", 3e5) + assertF("-300000", "% g", -3e5) + + assertF(" 5.00000e-05", "%15g", 0.5e-4) + assertF(" -5.00000e-05", "%15g", -0.5e-4) + assertF(" 300000", "%15g", 3e5) + assertF(" -300000", "%15g", -3e5) + + assertF(" 5.00000e-05", "%(15g", 0.5e-4) + assertF(" (5.00000e-05)", "%(15g", -0.5e-4) + assertF(" 300000", "%(15g", 3e5) + assertF(" (300000)", "%(15g", -3e5) + + assertF("5.00000e-05 ", "%-15g", 0.5e-4) + assertF("-5.00000e-05 ", "%-15g", -0.5e-4) + assertF("300000 ", "%-15g", 3e5) + assertF("-300000 ", "%-15g", -3e5) + + testWithInfinityAndNaN('g') } @Test def `should_provide_f_conversion`(): Unit = { - assertF("3.300000", "%f", new JDouble(3.3)) - assertF("(04.6000)", "%0(9.4f", new JDouble(-4.6)) - assertF("30000001024.000000", "%f", new JFloat(3e10f)) - assertF("30000000000.000000", "%f", new JDouble(3e10)) - assertF(" NaN", "%04f", new JDouble(Double.NaN)) + assertF("3.300000", "%f", 3.3) + assertF("(04.6000)", "%0(9.4f", -4.6) + + assertF("30000001024.000000", "%f", 3e10f) + + assertF("30000000000.000000", "%f", 3e10) + + assertF("00000000.000050", "%015f", 0.5e-4) + assertF("-0000000.000050", "%015f", -0.5e-4) + assertF("00300000.000000", "%015f", 3e5) + assertF("-0300000.000000", "%015f", -3e5) + + assertF("00300000.000", "%012.3f", 3e5) + assertF("-0300000.000", "%012.3f", -3e5) + + assertF("0.000050", "%(f", 0.5e-4) + assertF("(0.000050)", "%(f", -0.5e-4) + assertF("300000.000000", "%(f", 3e5) + assertF("(300000.000000)", "%(f", -3e5) + + assertF("+0.000050", "%(+f", 0.5e-4) + assertF("(0.000050)", "%(+f", -0.5e-4) + assertF("+300000.000000", "%(+f", 3e5) + assertF("(300000.000000)", "%(+f", -3e5) + + assertF(" 0.000050", "% f", 0.5e-4) + assertF("-0.000050", "% f", -0.5e-4) + assertF(" 300000.000000", "% f", 3e5) + assertF("-300000.000000", "% f", -3e5) + + assertF(" 0.000050", "%15f", 0.5e-4) + assertF(" -0.000050", "%15f", -0.5e-4) + assertF(" 300000.000000", "%15f", 3e5) + assertF(" -300000.000000", "%15f", -3e5) + + assertF(" 0.000050", "%(15f", 0.5e-4) + assertF(" (0.000050)", "%(15f", -0.5e-4) + assertF(" 300000.000000", "%(15f", 3e5) + assertF("(300000.000000)", "%(15f", -3e5) + + assertF("0.000050 ", "%-15f", 0.5e-4) + assertF("-0.000050 ", "%-15f", -0.5e-4) + assertF("300000.000000 ", "%-15f", 3e5) + assertF("-300000.000000 ", "%-15f", -3e5) + + // #3202 + if (executingInJVM) { + assertF("66380.78812500000", "%.11f", 66380.788125) + } else { + assertF("66380.78812500001", "%.11f", 66380.788125) + } + + testWithInfinityAndNaN('f', acceptUpperCase = false) } @Test def `should_support_%%`(): Unit = { - assertF("1%2", "%d%%%d", new JInteger(1), new JInteger(2)) + assertF("1%2", "%d%%%d", 1, 2) } @Test def `should_support_%n`(): Unit = { - assertF("1\n2", "%d%n%d", new JInteger(1), new JInteger(2)) - } - - @Test def `should_survive_null`(): Unit = { - assertF("null", "%s", null) + assertF("1\n2", "%d%n%d", 1, 2) } - @Test def `should_allow_f_string_interpolation_to_survive_null`(): Unit = { - assertEquals("null", f"${null}%s") + @Test def should_allow_positional_arguments(): Unit = { + assertF("2 1", "%2$d %1$d", 1, 2) + assertF("2 2 1", "%2$d %2$d %d", 1, 2) + assertF("2 2 1", "%2$d % 5.5 + case _ => 5 + } + expectFormatterThrows(classOf[MissingFormatWidthException], fmt, arg) + } } @Test def should_fail_when_called_after_close(): Unit = { @@ -254,8 +446,26 @@ class FormatterTest { @Test def should_fail_with_not_enough_arguments(): Unit = { expectFormatterThrows(classOf[MissingFormatArgumentException], "%f") expectFormatterThrows(classOf[MissingFormatArgumentException], "%d%d%d", - new JInteger(1), new JInteger(1)) - expectFormatterThrows(classOf[MissingFormatArgumentException], "%10$d", - new JInteger(1)) + 1, 1) + expectFormatterThrows(classOf[MissingFormatArgumentException], "%10$d", 1) + } +} + +object FormatterTest { + + def asIntOnJVM(x: Byte): Any = + if (executingInJVM) x.toInt + else x + + def asIntOnJVM(x: Short): Any = + if (executingInJVM) x.toInt + else x + + class HelperClass { + override def hashCode(): Int = 0xf1e2a3 + + // Soothe Scalastyle (equals and hashCode should be declared together) + override def equals(that: Any): Boolean = super.equals(that) } + } From ab1d39777e6e9a9147265dfecbb76f33597ee035 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 15 Jun 2018 16:52:25 +0200 Subject: [PATCH 0789/2665] Complete rewrite of java.util.Formatter. This class was written a very long time ago, when quality standards were not as high as they are now. In this commit, we entirely rewrite it while aiming for: * Readability * Performance * Fidelity in a lot of corner cases wrt. the specification on the JVM, in particular in error cases The corresponding test suite is significantly enhanced. In the process, this commit fixes #1619 (thousands grouping), as well as many other issues, among which: * Formatting of astral characters with `%c`. * Formatting of `null` with all the format specifiers. * Handling of precision in non-numeric strings (basically `substring`). * Capturing `IOException`s thrown by the target `Appendable`. Despite the large number of fixes, the following items are still not addressed: * #3202 and, more generally, various discrepancies between the formatting of floating point numbers wrt. the specification, with `%f`, `%e` and `%g`. * Hexadecimal format for floating point numbers with `%a`. * Formatting of date/times with the `%t.` family. * Formatting of `BigInteger`s and `BigDecimal`s. --- .../src/main/scala/java/lang/Long.scala | 24 +- .../src/main/scala/java/util/Formatter.scala | 915 +++++++++++++----- .../src/main/scala/java/util/Throwables.scala | 112 +-- .../javalib/util/FormatterTest.scala | 234 ++++- 4 files changed, 967 insertions(+), 318 deletions(-) diff --git a/javalanglib/src/main/scala/java/lang/Long.scala b/javalanglib/src/main/scala/java/lang/Long.scala index 1ed00d63b4..9b12203795 100644 --- a/javalanglib/src/main/scala/java/lang/Long.scala +++ b/javalanglib/src/main/scala/java/lang/Long.scala @@ -434,44 +434,44 @@ object Long { else Integer.numberOfTrailingZeros((l >>> 32).toInt) + 32 } - def toBinaryString(l: scala.Long): String = { + @inline def toBinaryString(l: scala.Long): String = + toBinaryString(l.toInt, (l >>> 32).toInt) + + private def toBinaryString(lo: Int, hi: Int): String = { val zeros = "00000000000000000000000000000000" // 32 zeros @inline def padBinary32(i: Int) = { val s = Integer.toBinaryString(i) zeros.substring(s.length) + s } - val lo = l.toInt - val hi = (l >>> 32).toInt - if (hi != 0) Integer.toBinaryString(hi) + padBinary32(lo) else Integer.toBinaryString(lo) } - def toHexString(l: scala.Long): String = { + @inline def toHexString(l: scala.Long): String = + toHexString(l.toInt, (l >>> 32).toInt) + + private def toHexString(lo: Int, hi: Int): String = { val zeros = "00000000" // 8 zeros @inline def padBinary8(i: Int) = { val s = Integer.toHexString(i) zeros.substring(s.length) + s } - val lo = l.toInt - val hi = (l >>> 32).toInt - if (hi != 0) Integer.toHexString(hi) + padBinary8(lo) else Integer.toHexString(lo) } - def toOctalString(l: scala.Long): String = { + @inline def toOctalString(l: scala.Long): String = + toOctalString(l.toInt, (l >>> 32).toInt) + + private def toOctalString(lo: Int, hi: Int): String = { val zeros = "0000000000" // 10 zeros @inline def padOctal10(i: Int) = { val s = Integer.toOctalString(i) zeros.substring(s.length) + s } - val lo = l.toInt - val hi = (l >>> 32).toInt - val lp = lo & 0x3fffffff val mp = ((lo >>> 30) + (hi << 2)) & 0x3fffffff val hp = hi >>> 28 diff --git a/javalib/src/main/scala/java/util/Formatter.scala b/javalib/src/main/scala/java/util/Formatter.scala index e6acc0c6f0..e79b73da12 100644 --- a/javalib/src/main/scala/java/util/Formatter.scala +++ b/javalib/src/main/scala/java/util/Formatter.scala @@ -4,285 +4,744 @@ import scala.annotation.switch import scala.scalajs.js import java.io._ -import java.lang._ -final class Formatter(private val dest: Appendable) extends Closeable with Flushable { +final class Formatter(private[this] var dest: Appendable) + extends Closeable with Flushable { + import Formatter._ + import Flags._ + + /** If `dest == null`, the real content is in `stringOutput`. + * + * A real `StringBuilder` may be created lazily if `out()` is called, which + * will then capture the current content of `stringOutput`. + * + * This allows to bypass the allocation of the `StringBuilder`, the call + * through `dest.append()` and more importantly the `try..catch`es in the + * common case where the `Formatter` is created without a specific + * destination. + */ + private[this] var stringOutput: String = "" + + private[this] var closed: Boolean = false + private[this] var lastIOException: IOException = null + + def this() = this(null: Appendable) + + @inline + private def trapIOExceptions(body: => Unit): Unit = { + try { + body + } catch { + case th: IOException => + lastIOException = th + } + } + + private def sendToDest(s: String): Unit = { + if (dest eq null) + stringOutput += s + else + sendToDestSlowPath(js.Array(s)) + } - var closed = false + private def sendToDest(s1: String, s2: String): Unit = { + if (dest eq null) + stringOutput += s1 + s2 + else + sendToDestSlowPath(js.Array(s1, s2)) + } - def this() = this(new StringBuilder()) + private def sendToDest(s1: String, s2: String, s3: String): Unit = { + if (dest eq null) + stringOutput += s1 + s2 + s3 + else + sendToDestSlowPath(js.Array(s1, s2, s3)) + } + + @noinline + private def sendToDestSlowPath(ss: js.Array[String]): Unit = { + trapIOExceptions { + ss.foreach(dest.append(_)) + } + } def close(): Unit = { - if (!closed) { + if (!closed && (dest ne null)) { dest match { - case cl: Closeable => cl.close() + case cl: Closeable => + trapIOExceptions { + cl.close() + } case _ => } } closed = true } - def flush(): Unit = ifNotClosed { - dest match { - case fl: Flushable => fl.flush() - case _ => + def flush(): Unit = { + checkNotClosed() + if (dest ne null) { + dest match { + case fl: Flushable => + trapIOExceptions { + fl.flush() + } + case _ => + } } } - // Begin implem of format() + def format(format: String, args: Array[AnyRef]): Formatter = { + // scalastyle:off return - def format(format_in: String, args: Array[AnyRef]): Formatter = ifNotClosed { - import js.JSNumberOps._ + checkNotClosed() - var fmt: String = format_in - var lastImplicitIndex: Int = 0 - var lastIndex: Int = 0 // required for < flag + var lastImplicitArgIndex: Int = 0 + var lastArgIndex: Int = 0 // required for < flag - while (!fmt.isEmpty) { - fmt match { - case RegularChunk(matchResult) => - fmt = fmt.substring(matchResult(0).get.length) - dest.append(matchResult(0).get) + val fmtLength = format.length + var fmtIndex: Int = 0 - case DoublePercent(_) => - fmt = fmt.substring(2) - dest.append('%') + while (fmtIndex != fmtLength) { + // Process a portion without '%' + val nextPercentIndex = format.indexOf("%", fmtIndex) + if (nextPercentIndex < 0) { + // No more '%' + sendToDest(format.substring(fmtIndex)) + return this + } + sendToDest(format.substring(fmtIndex, nextPercentIndex)) + + // Process one '%' + + val formatSpecifierIndex = nextPercentIndex + 1 + val re = FormatSpecifier + re.lastIndex = formatSpecifierIndex + val execResult = re.exec(format) + + if (execResult == null || execResult.index != formatSpecifierIndex) { + /* Could not parse a valid format specifier. The reported unknown + * conversion is the character directly following the '%', or '%' + * itself if this is a trailing '%'. This mimics the behavior of the + * JVM. + */ + val conversion = + if (formatSpecifierIndex == fmtLength) "%" + else format.substring(formatSpecifierIndex, formatSpecifierIndex + 1) + throw new UnknownFormatConversionException(conversion) + } - case EOLChunk(_) => - fmt = fmt.substring(2) - dest.append('\n') + fmtIndex = re.lastIndex // position at the end of the match + + val conversion = format.charAt(fmtIndex - 1) + val flags = parseFlags(execResult(2).asInstanceOf[String], conversion) + val width = parsePositiveIntSilent(execResult(3), default = -1) + val precision = parsePositiveIntSilent(execResult(4), default = -1) + + val arg = if (conversion == '%' || conversion == 'n') { + /* No argument. Make sure not to bump `lastImplicitArgIndex` nor to + * affect `lastArgIndex`. + */ + null + } else { + if (flags.leftAlign && width < 0) + throw new MissingFormatWidthException("%" + execResult(0)) + + val argIndex = if (flags.useLastIndex) { + // Explicitly use the last index + lastArgIndex + } else { + val i = parsePositiveIntSilent(execResult(1), default = 0) + if (i == 0) { + // Either there is no explicit index, or the explicit index is 0 + lastImplicitArgIndex += 1 + lastImplicitArgIndex + } else if (i < 0) { + // Cannot be parsed, same as useLastIndex + lastArgIndex + } else { + // Could be parsed, this is the index + i + } + } + + if (argIndex <= 0 || argIndex > args.length) { + val conversionStr = conversion.toString + if ("bBhHsHcCdoxXeEgGfn%".indexOf(conversionStr) < 0) + throw new UnknownFormatConversionException(conversionStr) + else + throw new MissingFormatArgumentException("%" + execResult(0)) + } + + lastArgIndex = argIndex + args(argIndex - 1) + } - case FormattedChunk(matchResult) => - fmt = fmt.substring(matchResult(0).get.length) + formatArg(arg, conversion, flags, width, precision) + } - val flags = matchResult(2).get - def hasFlag(flag: String) = flags.indexOf(flag) >= 0 + this - val indexStr = matchResult(1).getOrElse("") - val index = if (!indexStr.isEmpty) { - Integer.parseInt(indexStr) - } else if (hasFlag("<")) { - lastIndex - } else { - lastImplicitIndex += 1 - lastImplicitIndex - } - lastIndex = index - if (index <= 0 || index > args.length) - throw new MissingFormatArgumentException(matchResult(5).get) - val arg = args(index-1) - - val widthStr = matchResult(3).getOrElse("") - val hasWidth = !widthStr.isEmpty - val width = { - if (hasWidth) Integer.parseInt(widthStr) - else if (hasFlag("-")) throw new MissingFormatWidthException(format_in) - else 0 - } + // scalastyle:on return + } + + /* Should in theory be a method of `object Flags`. See the comment on that + * object about why we keep it here. + */ + private def parseFlags(flags: String, conversion: Char): Flags = { + var bits = if (conversion <= 'Z') UpperCase else 0 + + val len = flags.length + var i = 0 + while (i != len) { + val f = flags.charAt(i) + val bit = (f: @switch) match { + case '-' => LeftAlign + case '#' => AltFormat + case '+' => PositivePlus + case ' ' => PositiveSpace + case '0' => ZeroPad + case ',' => UseGroupingSeps + case '(' => NegativeParen + case '<' => UseLastIndex + } - val precisionStr = matchResult(4).getOrElse("") - val hasPrecision = !precisionStr.isEmpty - val precision = - if (hasPrecision) Integer.parseInt(precisionStr) - else 0 + if ((bits & bit) != 0) + throw new DuplicateFormatFlagsException(f.toString) - val conversion = matchResult(5).get.charAt(0) + bits |= bit + i += 1 + } - // Avoid using conversion.isUpper not to depend on the Unicode database - @inline def isConversionUpperCase: scala.Boolean = - conversion <= 'Z' + new Flags(bits) + } - def intArg: Int = (arg: Any) match { - case arg: Int => arg - case arg: Char => arg.toInt - } - def numberArg: scala.Double = (arg: Any) match { - case arg: Number => arg.doubleValue() - case arg: Char => arg.toDouble - } + private def parsePositiveIntSilent(capture: js.UndefOr[String], + default: Int): Int = { + capture.fold { + default + } { s => + val x = js.Dynamic.global.parseInt(s, 10).asInstanceOf[Double] + if (x <= Int.MaxValue) + x.toInt + else + -1 // Silently ignore and return -1 + } + } - def padCaptureSign(argStr: String, prefix: String) = { - val firstChar = argStr.charAt(0) - if (firstChar == '+' || firstChar == '-') - pad(argStr.substring(1), firstChar.toString + prefix) - else - pad(argStr, prefix) - } + private def formatArg(arg: Any, conversion: Char, flags: Flags, width: Int, + precision: Int): Unit = { - def strRepeat(s: String, times: Int) = { - var result: String = "" - var i = times - while (i > 0) { - result += s - i -= 1 - } - result - } + @inline def rejectPrecision(): Unit = { + if (precision >= 0) + throw new IllegalFormatPrecisionException(precision) + } - def with_+(s: String, preventZero: scala.Boolean = false) = { - if (s.charAt(0) != '-') { - if (hasFlag("+")) - pad(s, "+", preventZero) - else if (hasFlag(" ")) - pad(s, " ", preventZero) - else - pad(s, "", preventZero) - } else { - if (hasFlag("(")) - pad(s.substring(1) + ")", "(", preventZero) - else - pad(s.substring(1), "-", preventZero) - } - } + def formatNullOrThrowIllegalFormatConversion(): Unit = { + if (arg == null) + formatNonNumericString(flags, width, precision, "null") + else + throw new IllegalFormatConversionException(conversion, arg.getClass) + } - def pad(argStr: String, prefix: String = "", - preventZero: Boolean = false) = { - val prePadLen = argStr.length + prefix.length - - val padStr = { - if (width <= prePadLen) { - prefix + argStr - } else { - val padRight = hasFlag("-") - val padZero = hasFlag("0") && !preventZero - val padLength = width - prePadLen - val padChar: String = if (padZero) "0" else " " - val padding = strRepeat(padChar, padLength) - - if (padZero && padRight) - throw new java.util.IllegalFormatFlagsException(flags) - else if (padRight) prefix + argStr + padding - else if (padZero) prefix + padding + argStr - else padding + prefix + argStr - } - } + @inline def precisionWithDefault = + if (precision >= 0) precision + else 6 - val casedStr = - if (isConversionUpperCase) padStr.toUpperCase() - else padStr - dest.append(casedStr) + @inline def efgCommon(notation: (Double, Int, Boolean) => String): Unit = { + arg match { + case arg: Double => + if (arg.isNaN || arg.isInfinite) { + formatNaNOrInfinite(flags, width, arg) + } else { + /* The alternative format # of 'e', 'f' and 'g' is to force a + * decimal separator. + */ + val forceDecimalSep = flags.altFormat + formatNumericString(flags, width, + notation(arg, precisionWithDefault, forceDecimalSep)) } + case _ => + formatNullOrThrowIllegalFormatConversion() + } + } - (conversion: @switch) match { - case 'b' | 'B' => pad { arg match { - case null => "false" - case b: Boolean => String.valueOf(b) - case _ => "true" - } } - case 'h' | 'H' => pad { - if (arg eq null) "null" - else Integer.toHexString(arg.hashCode) + (conversion: @switch) match { + case 'b' | 'B' => + validateFlags(flags, conversion, + invalidFlags = NumericOnlyFlags | AltFormat) + val str = + if ((arg.asInstanceOf[AnyRef] eq false.asInstanceOf[AnyRef]) || arg == null) "false" + else "true" + formatNonNumericString(flags, width, precision, str) + + case 'h' | 'H' => + validateFlags(flags, conversion, + invalidFlags = NumericOnlyFlags | AltFormat) + val str = + if (arg == null) "null" + else Integer.toHexString(arg.hashCode) + formatNonNumericString(flags, width, precision, str) + + case 's' | 'S' => + arg match { + case formattable: Formattable => + validateFlags(flags, conversion, invalidFlags = NumericOnlyFlags) + val formattableFlags = { + (if (flags.leftAlign) FormattableFlags.LEFT_JUSTIFY else 0) | + (if (flags.altFormat) FormattableFlags.ALTERNATE else 0) | + (if (flags.upperCase) FormattableFlags.UPPERCASE else 0) } - case 's' | 'S' => arg match { - case formattable: Formattable => - val flags = { - (if (hasFlag("-")) FormattableFlags.LEFT_JUSTIFY else 0) | - (if (hasFlag("#")) FormattableFlags.ALTERNATE else 0) | - (if (isConversionUpperCase) FormattableFlags.UPPERCASE else 0) - } - formattable.formatTo(this, flags, - if (hasWidth) width else -1, - if (hasPrecision) precision else -1) - None // no further processing - case _ => - if (!hasFlag("#")) - pad(String.valueOf(arg)) - else - throw new FormatFlagsConversionMismatchException("#", 's') + formattable.formatTo(this, formattableFlags, width, precision) + + case _ => + validateFlags(flags, conversion, + invalidFlags = NumericOnlyFlags | AltFormat) + val str = String.valueOf(arg) + formatNonNumericString(flags, width, precision, str) + } + + case 'c' | 'C' => + validateFlags(flags, conversion, + invalidFlags = NumericOnlyFlags | AltFormat) + rejectPrecision() + arg match { + case arg: Char => + formatNonNumericString(flags, width, -1, arg.toString) + case arg: Int => + if (!Character.isValidCodePoint(arg)) + throw new IllegalFormatCodePointException(arg) + val str = if (arg < Character.MIN_SUPPLEMENTARY_CODE_POINT) { + js.Dynamic.global.String.fromCharCode(arg) + } else { + js.Dynamic.global.String.fromCharCode( + 0xd800 | ((arg >> 10) - (0x10000 >> 10)), + 0xdc00 | (arg & 0x3ff)) } - case 'c' | 'C' => - pad(intArg.toChar.toString) - case 'd' => - with_+(numberArg.toString()) - case 'o' => - val str = (arg: Any) match { - case arg: scala.Int => Integer.toOctalString(arg) - case arg: scala.Long => Long.toOctalString(arg) - } - padCaptureSign(str, if (hasFlag("#")) "0" else "") - case 'x' | 'X' => - val str = (arg: Any) match { - case arg: scala.Int => Integer.toHexString(arg) - case arg: scala.Long => Long.toHexString(arg) - } - padCaptureSign(str, if (hasFlag("#")) "0x" else "") - case 'e' | 'E' => - sciNotation(if (hasPrecision) precision else 6) - case 'g' | 'G' => - val m = Math.abs(numberArg) - // precision handling according to JavaDoc - // precision here means number of significant digits - // not digits after decimal point - val p = - if (!hasPrecision) 6 - else if (precision == 0) 1 - else precision - // between 1e-4 and 10e(p): display as fixed - if (m >= 1e-4 && m < Math.pow(10, p)) { - /* First approximation of the smallest power of 10 that is >= m. - * Due to rounding errors in the event of an imprecise `log10` - * function, sig0 could actually be the smallest power of 10 - * that is > m. - */ - val sig0 = Math.ceil(Math.log10(m)).toInt - /* Increment sig0 so that it is always the first power of 10 - * that is > m. - */ - val sig = if (Math.pow(10, sig0) <= m) sig0 + 1 else sig0 - with_+(numberArg.toFixed(Math.max(p - sig, 0))) - } else sciNotation(p - 1) - case 'f' => - with_+({ - // JavaDoc: 6 is default precision - numberArg.toFixed(if (hasPrecision) precision else 6) - }, numberArg.isNaN || numberArg.isInfinite) - } + formatNonNumericString(flags, width, -1, str.asInstanceOf[String]) + case _ => + formatNullOrThrowIllegalFormatConversion() + } + + case 'd' => + validateFlags(flags, conversion, invalidFlags = AltFormat) + rejectPrecision() + arg match { + case arg: Int => + formatNumericString(flags, width, arg.toString()) + case arg: Long => + formatNumericString(flags, width, arg.toString()) + case _ => + formatNullOrThrowIllegalFormatConversion() + } + + case 'o' => + validateFlags(flags, conversion, + invalidFlags = InvalidFlagsForOctalAndHex) + rejectPrecision() + val prefix = + if (flags.altFormat) "0" + else "" + arg match { + case arg: Int => + padAndSendToDest(flags, width, prefix, + java.lang.Integer.toOctalString(arg)) + case arg: Long => + padAndSendToDest(flags, width, prefix, + java.lang.Long.toOctalString(arg)) + case _ => + formatNullOrThrowIllegalFormatConversion() + } + + case 'x' | 'X' => + validateFlags(flags, conversion, + invalidFlags = InvalidFlagsForOctalAndHex) + rejectPrecision() + val prefix = { + if (!flags.altFormat) "" + else if (flags.upperCase) "0X" + else "0x" + } + arg match { + case arg: Int => + padAndSendToDest(flags, width, prefix, + applyUpperCase(flags, java.lang.Integer.toHexString(arg))) + case arg: Long => + padAndSendToDest(flags, width, prefix, + applyUpperCase(flags, java.lang.Long.toHexString(arg))) + case _ => + formatNullOrThrowIllegalFormatConversion() + } + + case 'e' | 'E' => + validateFlags(flags, conversion, invalidFlags = UseGroupingSeps) + efgCommon(computerizedScientificNotation _) + + case 'g' | 'G' => + validateFlags(flags, conversion, invalidFlags = AltFormat) + efgCommon(generalScientificNotation _) + + case 'f' => + validateFlags(flags, conversion, invalidFlags = 0) + efgCommon(decimalNotation _) + + case '%' => + validateFlagsForPercentAndNewline(flags, conversion, + invalidFlags = AllWrittenFlags & ~LeftAlign) + rejectPrecision() + if (flags.leftAlign && width < 0) + throw new MissingFormatWidthException("%-%") + padAndSendToDestNoZeroPad(flags, width, "%") + + case 'n' => + validateFlagsForPercentAndNewline(flags, conversion, + invalidFlags = AllWrittenFlags) + rejectPrecision() + if (width >= 0) + throw new IllegalFormatWidthException(width) + sendToDest("\n") - def sciNotation(precision: Int) = { - val exp = numberArg.toExponential(precision) - with_+({ - // check if we need additional 0 padding in exponent - // JavaDoc: at least 2 digits - if ('e' == exp.charAt(exp.length - 3)) { - exp.substring(0, exp.length - 1) + "0" + - exp.charAt(exp.length - 1) - } else exp - }, numberArg.isNaN || numberArg.isInfinite) - } + case _ => + throw new UnknownFormatConversionException(conversion.toString) + } + } + + @inline private def validateFlags(flags: Flags, conversion: Char, + invalidFlags: Int): Unit = { + + @noinline def flagsConversionMismatch(): Nothing = { + throw new FormatFlagsConversionMismatchException( + flagsToString(new Flags(flags.bits & invalidFlags)), conversion) + } + + if ((flags.bits & invalidFlags) != 0) + flagsConversionMismatch() + + @noinline def illegalFlags(): Nothing = + throw new IllegalFormatFlagsException(flagsToString(flags)) + + /* The test `(invalidFlags & BadCombo) == 0` is redundant, but is + * constant-folded away at called site, and if false it allows to dce the + * test after the `&&`. If both tests are eliminated, the entire `if` + * disappears. + */ + val BadCombo1 = LeftAlign | ZeroPad + val BadCombo2 = PositivePlus | PositiveSpace + if (((invalidFlags & BadCombo1) == 0 && (flags.bits & BadCombo1) == BadCombo1) || + ((invalidFlags & BadCombo2) == 0 && (flags.bits & BadCombo2) == BadCombo2)) { + illegalFlags() + } + } + + @inline private def validateFlagsForPercentAndNewline(flags: Flags, + conversion: Char, invalidFlags: Int): Unit = { + + @noinline def illegalFlags(): Nothing = + throw new IllegalFormatFlagsException(flagsToString(flags)) + + if ((flags.bits & invalidFlags) != 0) + illegalFlags() + } + + /* Should in theory be a method of `Flags`. See the comment on that class + * about why we keep it here. + */ + private def flagsToString(flags: Flags): String = { + (if (flags.leftAlign) "-" else "") + + (if (flags.altFormat) "#" else "") + + (if (flags.positivePlus) "+" else "") + + (if (flags.positiveSpace) " " else "") + + (if (flags.zeroPad) "0" else "") + + (if (flags.useGroupingSeps) "," else "") + + (if (flags.negativeParen) "(" else "") + + (if (flags.useLastIndex) "<" else "") + } + + private def computerizedScientificNotation(x: Double, precision: Int, + forceDecimalSep: Boolean): String = { + import js.JSNumberOps._ + + // First use JavaScript's native toExponential conversion + val s1 = x.toExponential(precision) + + // -0.0 should have a leading '-' + val s2 = + if (x == 0.0 && 1 / x < 0) "-" + s1 + else s1 + + // Then make sure the exponent has at least 2 digits for the JDK spec + val len = s2.length + val s3 = + if ('e' != s2.charAt(len - 3)) s2 + else s2.substring(0, len - 1) + "0" + s2.substring(len - 1) + + // Finally, force the decimal separator, if requested + if (!forceDecimalSep || s3.indexOf(".") >= 0) { + s3 + } else { + val pos = s3.indexOf("e") + s3.substring(0, pos) + "." + s3.substring(pos) + } + } + + private def generalScientificNotation(x: Double, precision: Int, + forceDecimalSep: Boolean): String = { + val m = Math.abs(x) + + val p = + if (precision == 0) 1 + else precision + + // between 1e-4 and 10e(p): display as fixed + if (m >= 1e-4 && m < Math.pow(10, p)) { + /* First approximation of the smallest power of 10 that is >= m. + * Due to rounding errors in the event of an imprecise `log10` + * function, sig0 could actually be the smallest power of 10 + * that is > m. + */ + val sig0 = Math.ceil(Math.log10(m)).toInt + /* Increment sig0 so that it is always the first power of 10 + * that is > m. + */ + val sig = if (Math.pow(10, sig0) <= m) sig0 + 1 else sig0 + decimalNotation(x, Math.max(p - sig, 0), forceDecimalSep) + } else { + computerizedScientificNotation(x, p - 1, forceDecimalSep) + } + } + + private def decimalNotation(x: Double, precision: Int, + forceDecimalSep: Boolean): String = { + + import js.JSNumberOps._ + + // First use JavaScript's native toFixed conversion + val s1 = x.toFixed(precision) + + // -0.0 should have a leading '-' + val s2 = + if (x == 0.0 && 1 / x < 0) "-" + s1 + else s1 + + // Finally, force the decimal separator, if requested + if (forceDecimalSep && s2.indexOf(".") < 0) + s2 + "." + else + s2 + } + + private def formatNonNumericString(flags: Flags, width: Int, precision: Int, + str: String): Unit = { + + val truncatedStr = + if (precision < 0) str + else str.substring(0, precision) + padAndSendToDestNoZeroPad(flags, width, applyUpperCase(flags, truncatedStr)) + } + + private def formatNaNOrInfinite(flags: Flags, width: Int, x: Double): Unit = { + val str = if (x.isNaN) { + "NaN" + } else if (x > 0.0) { + if (flags.positivePlus) "+Infinity" + else if (flags.positiveSpace) " Infinity" + else "Infinity" + } else { + if (flags.negativeParen) "(Infinity)" + else "-Infinity" + } + + padAndSendToDestNoZeroPad(flags, width, applyUpperCase(flags, str)) + } + + private def formatNumericString(flags: Flags, width: Int, str: String): Unit = { + /* Flags for which a numeric string needs to be decomposed and transformed, + * not just padded and/or uppercased. We can write fast-paths in this + * method if none of them are present. + */ + val TransformativeFlags = + PositivePlus | PositiveSpace | UseGroupingSeps | NegativeParen + + if (str.length >= width && !flags.hasAnyOf(TransformativeFlags)) { + // Super-fast-path + sendToDest(applyUpperCase(flags, str)) + } else if (!flags.hasAnyOf(TransformativeFlags | ZeroPad)) { + // Fast-path that does not need to inspect the string + formatNonNumericString(flags, width, -1, str) + } else { + // Extract prefix and rest, based on flags and the presence of a sign + val (prefix, rest0) = if (str.charAt(0) != '-') { + if (flags.positivePlus) + ("+", str) + else if (flags.positiveSpace) + (" ", str) + else + ("", str) + } else { + if (flags.negativeParen) + ("(", str.substring(1) + ")") + else + ("-", str.substring(1)) } + + // Insert grouping separators, if required + val rest = + if (flags.useGroupingSeps) insertGroupingSeps(rest0) + else rest0 + + // Apply uppercase, pad and send + padAndSendToDest(flags, width, prefix, applyUpperCase(flags, rest)) } + } - this + private def insertGroupingSeps(s: String): String = { + val len = s.length + var index = 0 + while (index != len && { val c = s.charAt(index); c >= '0' && c <= '9' }) { + index += 1 + } + + index -= 3 + + if (index <= 0) { + s + } else { + var result = s.substring(index) + while (index > 3) { + val next = index - 3 + result = s.substring(next, index) + "," + result + index = next + } + s.substring(0, index) + "," + result + } } - def ioException(): IOException = null - def locale(): Locale = ifNotClosed { null } - def out(): Appendable = ifNotClosed { dest } + private def applyUpperCase(flags: Flags, str: String): String = + if (flags.upperCase) str.toUpperCase + else str - override def toString(): String = out().toString() + /** This method ignores `flags.zeroPad` and `flags.upperCase`. */ + private def padAndSendToDestNoZeroPad(flags: Flags, width: Int, + str: String): Unit = { - @inline private def ifNotClosed[T](body: => T): T = - if (closed) throwClosedException() - else body + val len = str.length - private def throwClosedException(): Nothing = - throw new FormatterClosedException() + if (len >= width) + sendToDest(str) + else if (flags.leftAlign) + sendToDest(str, strRepeat(" ", width - len)) + else + sendToDest(strRepeat(" ", width - len), str) + } -} + /** This method ignores `flags.upperCase`. */ + private def padAndSendToDest(flags: Flags, width: Int, prefix: String, + str: String): Unit = { -object Formatter { + val len = prefix.length + str.length + + if (len >= width) + sendToDest(prefix, str) + else if (flags.zeroPad) + sendToDest(prefix, strRepeat("0", width - len), str) + else if (flags.leftAlign) + sendToDest(prefix, str, strRepeat(" ", width - len)) + else + sendToDest(strRepeat(" ", width - len), prefix, str) + } + + private def strRepeat(s: String, times: Int): String = { + var result: String = "" + var i = 0 + while (i != times) { + result += s + i += 1 + } + result + } + + def ioException(): IOException = lastIOException + + def locale(): Locale = { + checkNotClosed() + null + } - private class RegExpExtractor(val regexp: js.RegExp) { - def unapply(str: String): Option[js.RegExp.ExecResult] = { - Option(regexp.exec(str)) + def out(): Appendable = { + checkNotClosed() + if (dest eq null) { + dest = new java.lang.StringBuilder(stringOutput) + stringOutput == "" } + dest + } + + override def toString(): String = { + checkNotClosed() + if (dest eq null) + stringOutput + else + dest.toString() } - private val RegularChunk = new RegExpExtractor(new js.RegExp("""^[^\x25]+""")) - private val DoublePercent = new RegExpExtractor(new js.RegExp("""^\x25{2}""")) - private val EOLChunk = new RegExpExtractor(new js.RegExp("""^\x25n""")) - private val FormattedChunk = new RegExpExtractor(new js.RegExp( - """^\x25(?:([1-9]\d*)\$)?([-#+ 0,\(<]*)(\d*)(?:\.(\d+))?([A-Za-z])""")) + @inline private def checkNotClosed(): Unit = { + if (closed) + throw new FormatterClosedException() + } } + +object Formatter { + + private val FormatSpecifier = new js.RegExp( + """(?:(\d+)\$)?([-#+ 0,\(<]*)(\d+)?(?:\.(\d+))?[%A-Za-z]""", "g") + + /* This class is never used in a place where it would box, so it will + * completely disappear at link-time. Make sure to keep it that way. + * + * Also note that methods in this class are moved to the companion object, so + * also take into account the comment on `object Flags`. In particular, do + * not add non-inlineable methods in this class. + */ + private final class Flags(val bits: Int) extends AnyVal { + import Flags._ + + @inline def leftAlign: Boolean = (bits & LeftAlign) != 0 + @inline def altFormat: Boolean = (bits & AltFormat) != 0 + @inline def positivePlus: Boolean = (bits & PositivePlus) != 0 + @inline def positiveSpace: Boolean = (bits & PositiveSpace) != 0 + @inline def zeroPad: Boolean = (bits & ZeroPad) != 0 + @inline def useGroupingSeps: Boolean = (bits & UseGroupingSeps) != 0 + @inline def negativeParen: Boolean = (bits & NegativeParen) != 0 + @inline def useLastIndex: Boolean = (bits & UseLastIndex) != 0 + @inline def upperCase: Boolean = (bits & UpperCase) != 0 + + @inline def hasAnyOf(testBits: Int): Boolean = (bits & testBits) != 0 + } + + /* This object only contains `final val`s and (synthetic) `@inline` + * methods. Therefore, it will completely disappear at link-time. Make sure + * to keep it that way. In particular, do not add non-inlineable methods. + */ + private object Flags { + final val LeftAlign = 0x001 + final val AltFormat = 0x002 + final val PositivePlus = 0x004 + final val PositiveSpace = 0x008 + final val ZeroPad = 0x010 + final val UseGroupingSeps = 0x020 + final val NegativeParen = 0x040 + final val UseLastIndex = 0x080 + final val UpperCase = 0x100 + + final val InvalidFlagsForOctalAndHex = + PositivePlus | PositiveSpace | UseGroupingSeps | NegativeParen + + final val NumericOnlyFlags = + PositivePlus | PositiveSpace | ZeroPad | UseGroupingSeps | NegativeParen + + final val AllWrittenFlags = + LeftAlign | AltFormat | NumericOnlyFlags | UseLastIndex + } +} diff --git a/javalib/src/main/scala/java/util/Throwables.scala b/javalib/src/main/scala/java/util/Throwables.scala index b8340126c7..a0a8f552a1 100644 --- a/javalib/src/main/scala/java/util/Throwables.scala +++ b/javalib/src/main/scala/java/util/Throwables.scala @@ -8,28 +8,22 @@ class ConcurrentModificationException(s: String) extends RuntimeException(s) { def this() = this(null) } -class DuplicateFormatFlagsException private() extends IllegalFormatException { - private var flags: String = null - def this(f: String) = { - this() - if (f == null) - throw new NullPointerException() - flags = f - } - def getFlags(): String = flags - override def getMessage(): String = s"Flags = '$flags'" +class DuplicateFormatFlagsException(f: String) extends IllegalFormatException { + if (f == null) + throw new NullPointerException() + + def getFlags(): String = f + override def getMessage(): String = "Flags = '" + f + "'" } class EmptyStackException extends RuntimeException -class FormatFlagsConversionMismatchException private(private val c: Char) extends IllegalFormatException { - private var f: String = null - def this(f: String, c: Char) = { - this(c) - if (f == null) - throw new NullPointerException() - this.f = f - } +class FormatFlagsConversionMismatchException(f: String, c: Char) + extends IllegalFormatException { + + if (f == null) + throw new NullPointerException() + def getFlags(): String = f def getConversion(): Char = c override def getMessage(): String = "Conversion = " + c + ", Flags = " + f @@ -37,9 +31,9 @@ class FormatFlagsConversionMismatchException private(private val c: Char) extend class FormatterClosedException extends IllegalStateException -class IllegalFormatCodePointException(private val c: Int) extends IllegalFormatException { +class IllegalFormatCodePointException(c: Int) extends IllegalFormatException { def getCodePoint(): Int = c - override def getMessage(): String = s"Code point = $c" + override def getMessage(): String = "Code point = 0x" + Integer.toHexString(c) } class IllegalFormatConversionException(c: Char, arg: Class[_]) @@ -51,29 +45,25 @@ class IllegalFormatConversionException(c: Char, arg: Class[_]) def getConversion(): Char = c def getArgumentClass(): Class[_] = arg - override def getMessage(): String = s"$c != ${arg.getName()}" + override def getMessage(): String = c.toString() + " != " + arg.getName() } class IllegalFormatException private[util] () extends IllegalArgumentException -class IllegalFormatFlagsException private() extends IllegalFormatException { - private var flags: String = null - def this(f: String) = { - this() - if (f == null) - throw new NullPointerException() - this.flags = f - } - def getFlags(): String = flags - override def getMessage(): String = "Flags = '" + flags + "'" +class IllegalFormatFlagsException(f: String) extends IllegalFormatException { + if (f == null) + throw new NullPointerException() + + def getFlags(): String = f + override def getMessage(): String = "Flags = '" + f + "'" } -class IllegalFormatPrecisionException(private val p: Int) extends IllegalFormatException { +class IllegalFormatPrecisionException(p: Int) extends IllegalFormatException { def getPrecision(): Int = p override def getMessage(): String = Integer.toString(p) } -class IllegalFormatWidthException(private val w: Int) extends IllegalFormatException { +class IllegalFormatWidthException(w: Int) extends IllegalFormatException { def getWidth(): Int = w override def getMessage(): String = Integer.toString(w) } @@ -100,26 +90,18 @@ class InvalidPropertiesFormatException(s: String) extends java.io.IOException(s) // throw new java.io.NotSerializableException("Not serializable.") } -class MissingFormatArgumentException private() extends IllegalFormatException { - private var s: String = null - def this(s: String) = { - this() - if (s == null) - throw new NullPointerException() - this.s = s - } +class MissingFormatArgumentException(s: String) extends IllegalFormatException { + if (s == null) + throw new NullPointerException() + def getFormatSpecifier(): String = s override def getMessage(): String = "Format specifier '" + s + "'" } -class MissingFormatWidthException private() extends IllegalFormatException { - private var s: String = null - def this(s: String) = { - this() - if (s == null) - throw new NullPointerException() - this.s = s - } +class MissingFormatWidthException(s: String) extends IllegalFormatException { + if (s == null) + throw new NullPointerException() + def getFormatSpecifier(): String = s override def getMessage(): String = s } @@ -140,26 +122,20 @@ class TooManyListenersException(s: String) extends Exception(s) { def this() = this(null) } -class UnknownFormatConversionException private () extends IllegalFormatException { - private var s: String = null - def this(s: String) = { - this() - if (s == null) - throw new NullPointerException() - this.s = s - } +class UnknownFormatConversionException(s: String) + extends IllegalFormatException { + + if (s == null) + throw new NullPointerException() + def getConversion(): String = s - override def getMessage(): String = s"Conversion = '$s'" + override def getMessage(): String = "Conversion = '" + s + "'" } -class UnknownFormatFlagsException private() extends IllegalFormatException { - private var flags: String = null - def this(f: String) = { - this() - if (f == null) - throw new NullPointerException() - this.flags = f - } - def getFlags(): String = flags - override def getMessage(): String = "Flags = " + flags +class UnknownFormatFlagsException(f: String) extends IllegalFormatException { + if (f == null) + throw new NullPointerException() + + def getFlags(): String = f + override def getMessage(): String = "Flags = " + f } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/FormatterTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/FormatterTest.scala index 94bdbd21da..074f2c4cdf 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/FormatterTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/FormatterTest.scala @@ -25,8 +25,8 @@ class FormatterTest { assertEquals(expected, res) } - def testWithInfinityAndNaN(conversion: Char, - acceptUpperCase: Boolean = true): Unit = { + def testWithInfinityAndNaN(conversion: Char, acceptSharp: Boolean = true, + acceptComma: Boolean = true, acceptUpperCase: Boolean = true): Unit = { import Double.{NaN, PositiveInfinity => PosInf, NegativeInfinity => NegInf} @@ -45,12 +45,20 @@ class FormatterTest { assertF(" Infinity", "% " + conversion, PosInf) assertF("-Infinity", "%+" + conversion, NegInf) assertF("-Infinity", "% " + conversion, NegInf) + assertF("NaN", "%+" + conversion, NaN) + assertF("NaN", "% " + conversion, NaN) assertF("+Infinity", "%+(" + conversion, PosInf) assertF(" Infinity", "% (" + conversion, PosInf) assertF("(Infinity)", "%+(" + conversion, NegInf) assertF("(Infinity)", "% (" + conversion, NegInf) + if (acceptSharp) + assertF("Infinity", "%#" + conversion, PosInf) + + if (acceptComma) + assertF("Infinity", "%," + conversion, PosInf) + if (acceptUpperCase) { val upConversion = conversion.toUpper assertF("INFINITY", "%" + upConversion, PosInf) @@ -59,6 +67,37 @@ class FormatterTest { } } + /* Every conversion accepts `null` as input. Other than `%b`, which formats + * `null` as `"false"`, they all format it as `"null"`. While they reject + * flags and/or precision according to the conversion, they will then all + * handle the width, the `-` flag and the precision as if the conversion were + * `%s`. Notably, the precision truncates the string. + */ + def testWithNull(conversion: Char, flags: String, + acceptPrecision: Boolean = true, + acceptUpperCase: Boolean = true): Unit = { + + assertF("null", "%" + conversion, null) + + for (flag <- flags) + assertF("null", "%" + flag + "1" + conversion, null) + + assertF(" null", "%6" + conversion, null) + assertF("null ", "%-6" + conversion, null) + + if (acceptPrecision) { + assertF("nul", "%.3" + conversion, null) + assertF(" nul", "%5.3" + conversion, null) + assertF("nul ", "%-5.3" + conversion, null) + } + + if (acceptUpperCase) { + val upConversion = conversion.toUpper + assertF("NULL", "%" + upConversion, null) + assertF(" NULL", "%6" + upConversion, null) + } + } + def expectFormatterThrows[T <: Throwable](exeption: Class[T], format: String, args: Any*): T = { val fmt = new Formatter() @@ -66,6 +105,50 @@ class FormatterTest { fmt.format(format, args.asInstanceOf[Seq[AnyRef]]: _*)) } + def expectFormatFlagsConversionMismatch(conversion: Char, + invalidFlags: String, arg: Any): Unit = { + + for (flag <- invalidFlags) { + val e = expectFormatterThrows( + classOf[FormatFlagsConversionMismatchException], + "%" + flag + conversion, arg) + assertEquals(flag.toString, e.getFlags) + assertEquals(conversion, e.getConversion) + } + } + + def expectIllegalFormatFlags(format: String, flags: String, + arg: Any): Unit = { + val e = expectFormatterThrows(classOf[IllegalFormatFlagsException], + format, arg) + assertEquals(flags, e.getFlags) + } + + def expectIllegalFormatPrecision(conversion: Char, arg: Any): Unit = { + val e = expectFormatterThrows(classOf[IllegalFormatPrecisionException], + "%.5" + conversion, arg) + assertEquals(5, e.getPrecision) + } + + def expectIllegalFormatWidth(conversion: Char, arg: Any): Unit = { + val e = expectFormatterThrows(classOf[IllegalFormatWidthException], + "%5" + conversion, arg) + assertEquals(5, e.getWidth) + } + + def expectIllegalFormatConversion(conversion: Char, arg: Any): Unit = { + val e = expectFormatterThrows(classOf[IllegalFormatConversionException], + "%" + conversion, arg) + assertEquals(conversion, e.getConversion) + assertEquals(arg.getClass, e.getArgumentClass) + } + + def expectUnknownFormatConversion(format: String, conversion: Char): Unit = { + val e = expectFormatterThrows(classOf[UnknownFormatConversionException], + format, 1, 2, 3) + assertEquals(conversion.toString, e.getConversion) + } + @Test def `should_provide_b_conversion`(): Unit = { assertF("false", "%b", null) assertF("true", "%b", true) @@ -78,6 +161,13 @@ class FormatterTest { assertF("true ", "%-7b", true) assertF("FALSE", "%B", false) + + assertF("tru", "%.3b", true) + assertF(" tru", "%8.3b", true) + assertF("fal", "%.3b", null) + assertF(" fal", "%8.3b", null) + + expectFormatFlagsConversionMismatch('b', "#+ 0,(", true) } @Test def `should_provide_h_conversion`(): Unit = { @@ -87,7 +177,11 @@ class FormatterTest { assertF(" f1e2a3", "%8h", x) - assertF("null", "%h", null) + assertF("f1e2a", "%.5h", x) + + testWithNull('h', "") + + expectFormatFlagsConversionMismatch('h', "#+ 0,(", x) } @Test def sConversionWithNonFormattable(): Unit = { @@ -100,10 +194,13 @@ class FormatterTest { assertF(" hello", "%10s", "hello") assertF("hello ", "%-10s", "hello") - assertF("null", "%s", null) + assertF("hel", "%.3s", "hello") + assertF(" HEL", "%7.3S", "hello") + + testWithNull('s', "") - if (!executingInJVMOnJDK6) - expectFormatterThrows(classOf[Exception], "%#s", "hello") + expectFormatFlagsConversionMismatch('s', + if (executingInJVMOnJDK6) "+ 0,(" else "#+ 0,(", "hello") } @Test def sConversionWithFormattable(): Unit = { @@ -129,6 +226,9 @@ class FormatterTest { assertEquals(width, this.width) assertEquals(precision, this.precision) } + + def expectNotCalled(): Unit = + assertEquals(0, this.calls) } def test(format: String, flags: Int, width: Int, precision: Int): Unit = { @@ -141,15 +241,29 @@ class FormatterTest { test("%-10s", LEFT_JUSTIFY, 10, -1) test("%#-10.2s", LEFT_JUSTIFY | ALTERNATE, 10, 2) test("%#10.2S", UPPERCASE | ALTERNATE, 10, 2) + + val x = new FormattableClass + expectFormatFlagsConversionMismatch('s', "+ 0,(", x) + x.expectNotCalled() } @Test def `should_provide_c_conversion`(): Unit = { assertF("a", "%c", 'a') assertF("A", "%C", 'A') assertF("A", "%c", 65) + assertF("\ud83d\udca9", "%c", 0x1f4a9) assertF(" !", "%5c", '!') assertF("! ", "%-5c", '!') + + testWithNull('c', "", acceptPrecision = false) + + expectFormatFlagsConversionMismatch('c', "#+ 0,(", 'A') + expectIllegalFormatPrecision('c', 'A') + + val e = expectFormatterThrows(classOf[IllegalFormatCodePointException], + "%c", 0x123456) + assertEquals(0x123456, e.getCodePoint) } @Test def `should_provide_d_conversion`(): Unit = { @@ -160,6 +274,21 @@ class FormatterTest { assertF(" -10", "%5d", -10) assertF("-0010", "%05d", -10) + assertF("345,678", "%,d", 345678) + assertF("-345,678", "%,d", -345678) + assertF("12,345,678", "%,d", 12345678) + assertF(" 12,345,678", "%,14d", 12345678) + assertF("000012,345,678", "%,014d", 12345678) + assertF(" -12,345,678", "%,14d", -12345678) + + assertF("2,345,678", "%,d", 2345678) + assertF("345,678", "%,d", 345678) + assertF("45,678", "%,d", 45678) + assertF("5,678", "%,d", 5678) + assertF("678", "%,d", 678) + assertF("78", "%,d", 78) + assertF("8", "%,d", 8) + assertF("56", "%(d", 56) assertF("(56)", "%(d", -56) assertF(" (56)", "%(8d", -56) @@ -177,6 +306,12 @@ class FormatterTest { assertF("56 ", "%-6d", 56) assertF("-56 ", "%-6d", -56) + + testWithNull('d', "+ (", acceptPrecision = false, acceptUpperCase = false) + + expectIllegalFormatFlags("%+- (5d", "-+ (", 56) + expectIllegalFormatFlags("%+-0(5d", "-+0(", 56) + expectIllegalFormatPrecision('d', 5) } @Test def `should_provide_o_conversion`(): Unit = { @@ -213,6 +348,11 @@ class FormatterTest { assertF("37777777766", "%05o", asIntOnJVM(-10.toByte)) assertF("37777777766", "%5o", asIntOnJVM(-10.toShort)) assertF("000037777777766", "%015o", asIntOnJVM(-10.toShort)) + + testWithNull('o', "#0", acceptPrecision = false, acceptUpperCase = false) + + expectFormatFlagsConversionMismatch('o', "+ ,(", 5) + expectIllegalFormatPrecision('o', 5) } @Test def `should_provide_x_conversion`(): Unit = { @@ -256,12 +396,18 @@ class FormatterTest { assertF("ffffffffffff2bcf", "%x", -54321L) assertF("28EEA4CB1", "%X", 10987654321L) + + testWithNull('x', "#0", acceptPrecision = false) + + expectFormatFlagsConversionMismatch('x', "+ ,(", 5) + expectIllegalFormatPrecision('x', 5) } @Test def `should_provide_e_conversion`(): Unit = { assertF("1.000000e+03", "%e", 1000.0) assertF("1e+100", "%.0e", 1.2e100) assertF("0.000e+00", "%.3e", 0.0) + assertF("-0.000e+00", "%.3e", -0.0) /* We use 1.51e100 in this test, since we seem to have a floating point * imprecision at exactly 1.5e100 that yields to a rounding error towards @@ -288,12 +434,19 @@ class FormatterTest { assertF("001.2000E-21", "%012.4E", 1.2e-21f) assertF("(0001.2000e-21)", "%(015.4e", -1.2e-21f) + assertF("1.e+100", "%#.0e", 1.2e100) + assertF("+1.234560e+30", "%+e", 1.23456e30) assertF("-1.234560e+30", "%+e", -1.23456e30) assertF(" 1.234560e+30", "% e", 1.23456e30) assertF("-1.234560e+30", "% e", -1.23456e30) - testWithInfinityAndNaN('e') + testWithInfinityAndNaN('e', acceptComma = false) + testWithNull('e', "#+ 0(") + + expectFormatFlagsConversionMismatch('e', ",", 5.5) + expectIllegalFormatFlags("%-05e", "-0", 5.5) + expectIllegalFormatFlags("% +e", "+ ", 5.5) } @Test def `should_provide_g_conversion`(): Unit = { @@ -345,7 +498,15 @@ class FormatterTest { assertF("300000 ", "%-15g", 3e5) assertF("-300000 ", "%-15g", -3e5) - testWithInfinityAndNaN('g') + assertF("300,000", "%,g", 3e5) + assertF("00000300,000", "%0,12g", 3e5) + + testWithInfinityAndNaN('g', acceptSharp = false) + testWithNull('g', "+ 0,(") + + expectFormatFlagsConversionMismatch('g', "#", 5.5) + expectIllegalFormatFlags("%-05g", "-0", 5.5) + expectIllegalFormatFlags("% +g", "+ ", 5.5) } @Test def `should_provide_f_conversion`(): Unit = { @@ -356,6 +517,8 @@ class FormatterTest { assertF("30000000000.000000", "%f", 3e10) + assertF("30,000,000,000.000000", "%,f", 3e10) + assertF("00000000.000050", "%015f", 0.5e-4) assertF("-0000000.000050", "%015f", -0.5e-4) assertF("00300000.000000", "%015f", 3e5) @@ -394,6 +557,9 @@ class FormatterTest { assertF("300000.000000 ", "%-15f", 3e5) assertF("-300000.000000 ", "%-15f", -3e5) + assertF("300,000.000000", "%,f", 3e5) + assertF("00000300,000.000000", "%0,19f", 3e5) + // #3202 if (executingInJVM) { assertF("66380.78812500000", "%.11f", 66380.788125) @@ -402,14 +568,33 @@ class FormatterTest { } testWithInfinityAndNaN('f', acceptUpperCase = false) + testWithNull('f', "#+ 0,(", acceptUpperCase = false) + + expectIllegalFormatFlags("%-05f", "-0", 5.5) + expectIllegalFormatFlags("% +f", "+ ", 5.5) } @Test def `should_support_%%`(): Unit = { assertF("1%2", "%d%%%d", 1, 2) + + /* https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8204229 + * 'width' is ignored before JDK 11. + */ + if (!executingInJVM) { + assertF(" %", "%5%") + assertF("% ", "%-5%") + } + + expectIllegalFormatFlags("%0,+< (#%", "#+ 0,(<", null) + expectIllegalFormatPrecision('%', null) } @Test def `should_support_%n`(): Unit = { assertF("1\n2", "%d%n%d", 1, 2) + + expectIllegalFormatFlags("%0-,+< (#n", "-#+ 0,(<", null) + expectIllegalFormatPrecision('%', null) + expectIllegalFormatWidth('n', null) } @Test def should_allow_positional_arguments(): Unit = { @@ -418,17 +603,46 @@ class FormatterTest { assertF("2 2 1", "%2$d % 5.5 case _ => 5 } - expectFormatterThrows(classOf[MissingFormatWidthException], fmt, arg) + val e = + expectFormatterThrows(classOf[MissingFormatWidthException], fmt, arg) + assertEquals(fmt, "%-" + conversion, e.getFormatSpecifier) } } + @Test def indexTooLargeIsLikeUseLastIndex(): Unit = { + expectFormatterThrows(classOf[MissingFormatArgumentException], + "%9876543210$d", 56, 78) + + assertF("56 56", "%d %9876543210$d", 56, 78) + } + + @Test def widthOrPrecisionTooLargeIsIgnored(): Unit = { + assertF("56 78", "%d %9876543210d", 56, 78) + assertF("56 78", "%d %.9876543210d", 56, 78) + } + @Test def should_fail_when_called_after_close(): Unit = { val f = new Formatter() f.close() From 86dcfbc773c9432f6d22edd9ab2e3320149858f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 25 Jun 2018 11:10:29 +0200 Subject: [PATCH 0790/2665] Upgrade to Scala 2.12.6. --- Jenkinsfile | 11 +- ci/checksizes.sh | 14 +- .../scalajs/2.12.6/BlacklistedTests.txt | 1064 +++++ .../partest/scalajs/2.12.6/BuglistedTests.txt | 7 + .../scalajs/2.12.6/WhitelistedTests.txt | 3433 +++++++++++++++++ .../scalajs/2.12.6/neg/t6446-additional.check | 30 + .../scalajs/2.12.6/neg/t6446-list.check | 2 + .../scalajs/2.12.6/neg/t6446-missing.check | 30 + .../2.12.6/neg/t6446-show-phases.check | 29 + .../scalajs/2.12.6/neg/t7494-no-options.check | 31 + .../scalajs/2.12.6/run/Course-2002-01.check | 37 + .../scalajs/2.12.6/run/Course-2002-02.check | 187 + .../scalajs/2.12.6/run/Course-2002-04.check | 64 + .../scalajs/2.12.6/run/Course-2002-08.check | 171 + .../scalajs/2.12.6/run/Course-2002-09.check | 50 + .../scalajs/2.12.6/run/Course-2002-10.check | 46 + .../partest/scalajs/2.12.6/run/Meter.check | 16 + .../scalajs/2.12.6/run/MeterCaseClass.check | 16 + .../scalajs/2.12.6/run/anyval-box-types.check | 52 + .../tools/partest/scalajs/2.12.6/run/bugs.sem | 1 + .../scalajs/2.12.6/run/caseClassHash.check | 9 + .../partest/scalajs/2.12.6/run/deeps.check | 87 + .../scalajs/2.12.6/run/dynamic-anyval.check | 4 + .../scalajs/2.12.6/run/impconvtimes.check | 1 + .../partest/scalajs/2.12.6/run/imports.check | 21 + .../scalajs/2.12.6/run/interpolation.check | 32 + .../2.12.6/run/interpolationMultiline1.check | 26 + .../partest/scalajs/2.12.6/run/issue192.sem | 1 + .../2.12.6/run/macro-bundle-static.check | 6 + .../2.12.6/run/macro-bundle-toplevel.check | 6 + .../run/macro-bundle-whitebox-decl.check | 6 + .../partest/scalajs/2.12.6/run/misc.check | 62 + .../scalajs/2.12.6/run/promotion.check | 4 + .../partest/scalajs/2.12.6/run/runtime.check | 70 + .../scalajs/2.12.6/run/spec-self.check | 2 + .../scalajs/2.12.6/run/structural.check | 37 + .../scalajs/2.12.6/run/t0421-new.check | 3 + .../scalajs/2.12.6/run/t0421-old.check | 3 + .../partest/scalajs/2.12.6/run/t1503.sem | 1 + .../partest/scalajs/2.12.6/run/t3702.check | 2 + .../partest/scalajs/2.12.6/run/t4148.sem | 1 + .../partest/scalajs/2.12.6/run/t4617.check | 1 + .../partest/scalajs/2.12.6/run/t5356.check | 6 + .../partest/scalajs/2.12.6/run/t5552.check | 6 + .../partest/scalajs/2.12.6/run/t5568.check | 9 + .../partest/scalajs/2.12.6/run/t5629b.check | 10 + .../partest/scalajs/2.12.6/run/t5680.check | 3 + .../partest/scalajs/2.12.6/run/t5866.check | 2 + .../scalajs/2.12.6/run/t6318_primitives.check | 54 + .../partest/scalajs/2.12.6/run/t6662.check | 1 + .../partest/scalajs/2.12.6/run/t7657.check | 3 + .../partest/scalajs/2.12.6/run/t7763.sem | 1 + .../partest/scalajs/2.12.6/run/t8570a.check | 1 + .../partest/scalajs/2.12.6/run/t8764.check | 5 + .../partest/scalajs/2.12.6/run/t9387b.check | 1 + .../partest/scalajs/2.12.6/run/t9656.check | 20 + .../scalajs/2.12.6/run/try-catch-unify.check | 4 + .../2.12.6/run/virtpatmat_switch.check | 7 + .../2.12.6/run/virtpatmat_typetag.check | 10 + project/Build.scala | 4 +- .../resources/2.12.6/BlacklistedTests.txt | 142 + .../resources/2.12.6/WhitelistedTests.txt | 40 + scripts/assemble-cli.sh | 4 +- scripts/publish.sh | 8 +- 64 files changed, 5997 insertions(+), 20 deletions(-) create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/BlacklistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/BuglistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/WhitelistedTests.txt create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/neg/t6446-additional.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/neg/t6446-list.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/neg/t6446-missing.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/neg/t6446-show-phases.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/neg/t7494-no-options.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Course-2002-01.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Course-2002-02.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Course-2002-04.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Course-2002-08.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Course-2002-09.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Course-2002-10.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Meter.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/MeterCaseClass.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/anyval-box-types.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/bugs.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/caseClassHash.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/deeps.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/dynamic-anyval.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/impconvtimes.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/imports.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/interpolation.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/interpolationMultiline1.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/issue192.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/macro-bundle-static.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/macro-bundle-toplevel.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/macro-bundle-whitebox-decl.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/misc.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/promotion.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/runtime.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/spec-self.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/structural.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t0421-new.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t0421-old.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t1503.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t3702.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t4148.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t4617.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t5356.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t5552.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t5568.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t5629b.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t5680.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t5866.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t6318_primitives.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t6662.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t7657.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t7763.sem create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t8570a.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t8764.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t9387b.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t9656.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/try-catch-unify.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/virtpatmat_switch.check create mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/virtpatmat_typetag.check create mode 100644 scala-test-suite/src/test/resources/2.12.6/BlacklistedTests.txt create mode 100644 scala-test-suite/src/test/resources/2.12.6/WhitelistedTests.txt diff --git a/Jenkinsfile b/Jenkinsfile index cfa8cea200..f3a727b3b7 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -388,8 +388,8 @@ def otherJavaVersions = [] // should be ["1.6", "1.7"] but that's broken (see #3 def allJavaVersions = otherJavaVersions.clone() allJavaVersions << mainJavaVersion -def mainScalaVersion = "2.12.5" -def mainScalaVersions = ["2.10.2", "2.11.12", "2.12.5", "2.13.0-M3"] +def mainScalaVersion = "2.12.6" +def mainScalaVersions = ["2.10.2", "2.11.12", "2.12.6", "2.13.0-M3"] def otherScalaVersions = [ "2.10.3", "2.10.4", @@ -410,7 +410,8 @@ def otherScalaVersions = [ "2.12.1", "2.12.2", "2.12.3", - "2.12.4" + "2.12.4", + "2.12.5" ] def limitedCIScalaVersions = ["2.13.0-M4"] @@ -445,10 +446,10 @@ allJavaVersions.each { javaVersion -> quickMatrix.add([task: "tools-cli-stubs", scala: "2.11.12", java: javaVersion]) } } -quickMatrix.add([task: "tools-cli-stubs", scala: "2.12.5", java: mainJavaVersion]) +quickMatrix.add([task: "tools-cli-stubs", scala: "2.12.6", java: mainJavaVersion]) quickMatrix.add([task: "partestc", scala: "2.11.0", java: "1.8"]) // #3293, should be: 1.7 quickMatrix.add([task: "sbtplugin-test", toolsscala: "2.10.7", sbt_version_override: "", java: "1.7"]) -quickMatrix.add([task: "sbtplugin-test", toolsscala: "2.12.5", sbt_version_override: "1.0.0", java: mainJavaVersion]) +quickMatrix.add([task: "sbtplugin-test", toolsscala: "2.12.6", sbt_version_override: "1.0.0", java: mainJavaVersion]) // The 'full' matrix def fullMatrix = quickMatrix.clone() diff --git a/ci/checksizes.sh b/ci/checksizes.sh index a57f383dbb..34f968b5c4 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -11,7 +11,7 @@ case $FULLVER in 2.11.12) VER=2.11 ;; - 2.12.5) + 2.12.6) VER=2.12 ;; 2.13.0-M3) @@ -20,7 +20,7 @@ case $FULLVER in 2.13.0-M4) VER=2.13.0-M4 ;; - 2.10.3|2.10.4|2.10.5|2.10.6|2.10.7|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7|2.11.8|2.11.11|2.12.0|2.12.1|2.12.2|2.12.3|2.12.4) + 2.10.3|2.10.4|2.10.5|2.10.6|2.10.7|2.11.0|2.11.1|2.11.2|2.11.4|2.11.5|2.11.6|2.11.7|2.11.8|2.11.11|2.12.0|2.12.1|2.12.2|2.12.3|2.12.4|2.12.5) echo "Ignoring checksizes for Scala $FULLVER" exit 0 ;; @@ -51,11 +51,11 @@ case $FULLVER in REVERSI_PREOPT_GZ_EXPECTEDSIZE=71000 REVERSI_OPT_GZ_EXPECTEDSIZE=32000 ;; - 2.12.5) - REVERSI_PREOPT_EXPECTEDSIZE=630000 - REVERSI_OPT_EXPECTEDSIZE=147000 - REVERSI_PREOPT_GZ_EXPECTEDSIZE=76000 - REVERSI_OPT_GZ_EXPECTEDSIZE=33000 + 2.12.6) + REVERSI_PREOPT_EXPECTEDSIZE=617000 + REVERSI_OPT_EXPECTEDSIZE=144000 + REVERSI_PREOPT_GZ_EXPECTEDSIZE=74000 + REVERSI_OPT_GZ_EXPECTEDSIZE=32000 ;; 2.13.0-M3) REVERSI_PREOPT_EXPECTEDSIZE=629000 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/BlacklistedTests.txt new file mode 100644 index 0000000000..e09e4a0384 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/BlacklistedTests.txt @@ -0,0 +1,1064 @@ +# +# POS +# + +# Using Jsoup, what's that? +pos/cycle-jsoup.scala + +# Spuriously fails too often, and causes other subsequent tests to fail too +# Note that this test, by design, stress-tests type checking +pos/t6367.scala + +# +# NEG +# + +# Screws up, but not really our problem (error: None.get instead of +# phase ordering error) +neg/t7494-multi-right-after +neg/t7494-right-after-before +neg/t7622-multi-followers +neg/t7622-cyclic-dependency + +# Uses some strange macro cross compile mechanism. +neg/macro-incompatible-macro-engine-c.scala + +# Spurious failures +neg/inlineMaxSize.scala + +# Uses .java files +run/t9200 +run/noInlineUnknownIndy + +# +# RUN +# + +# Relies on the exact toString() representation of Floats/Doubles +run/t2378.scala + +# Uses ClassTags on existentials which are broken in Scala (see #251) +run/valueclasses-classtag-existential.scala + +# Relies on a particular execution speed +run/t5857.scala + +# Using parts of the javalib we don't plan to support + +run/t5018.scala +run/t2417.scala +run/t4813.scala +run/lazy-concurrent.scala +run/t3667.scala +run/t3038d.scala +run/shutdownhooks.scala +run/t5590.scala +run/t3895b.scala +run/t5974.scala +run/hashset.scala +run/t5262.scala +run/serialize-stream.scala +run/sysprops.scala +run/lambda-serialization-gc.scala +run/t9390.scala +run/t9390b.scala +run/t9390c.scala +run/trait-defaults-super.scala +run/t2849.scala +run/t1360.scala +run/t3199b.scala +run/t8690.scala +run/t10488.scala +run/various-flat-classpath-types.scala + +# Uses java.util.Collections +run/t2250.scala + +# Uses java.math.BigDecimal / BigInteger : but failures not due to them +run/hashhash.scala +run/is-valid-num.scala + +# Documented semantic difference on String.split(x: Array[Char]) +run/t0325.scala + +# Using Threads +run/inner-obj-auto.scala +run/predef-cycle.scala +run/synchronized.scala +run/sd409.scala + +# Uses java.security +run/t2318.scala + +# Tries to catch java.lang.StackOverflowError +run/t6154.scala + +# Tries to catch java.lang.OutOfMemoryError +run/t7880.scala + +# Taking too much time, because JavaScript is not as fast as the JVM + +run/collections.scala +run/t3989.scala +run/adding-growing-set.scala +run/t3242.scala +run/hashCodeDistribution.scala +run/t408.scala +run/t6584.scala +run/UnrolledBuffer.scala +run/t6253a.scala +run/t6253b.scala +run/t6253c.scala +run/numbereq.scala +run/t4658.scala + +# Crashes Rhino + +run/bridges.scala +run/patmat-exprs.scala + +# Using partest properties + +run/tailcalls.scala +run/t4294.scala +run/t6331b.scala + +# Using IO + +run/t6488.scala +run/t6988.scala + +# Object{Output|Input}Streams +run/t6935.scala +run/t8188.scala +run/t9375.scala +run/t9365.scala +run/inlineAddDeserializeLambda.scala +run/sammy_seriazable.scala +run/lambda-serialization-security.scala +run/t10232.scala +run/t10233.scala +run/t10244.scala +run/t10522.scala + +# Using System.getProperties + +run/t4426.scala + +# Using Await + +run/t7336.scala +run/t7775.scala +run/t10513.scala +run/future-flatmap-exec-count.scala + +# Using detailed stack trace + +run/t6308.scala + +# Using reflection + +run/t6063 + +run/mixin-bridge-methods.scala +run/t5125.scala +run/outertest.scala +run/t6223.scala +run/t5652b +run/elidable-opt.scala +run/nullable-lazyvals.scala +run/t4794.scala +run/t5652 +run/t5652c +run/getClassTest-old.scala +run/t8960.scala +run/t7965.scala +run/t8087.scala +run/t8931.scala +run/t8445.scala +run/lambda-serialization.scala + +run/reflection-repl-classes.scala +run/t5256e.scala +run/typetags_core.scala +run/reflection-constructormirror-toplevel-badpath.scala +run/t5276_1b.scala +run/reflection-sorted-decls.scala +run/toolbox_typecheck_implicitsdisabled.scala +run/t5418b.scala +run/toolbox_typecheck_macrosdisabled2.scala +run/abstypetags_serialize.scala +run/all-overridden.scala +run/showraw_tree_kinds.scala +run/showraw_tree_types_ids.scala +run/showraw_tree_types_typed.scala +run/showraw_tree_ids.scala +run/showraw_tree_ultimate.scala +run/t5266_2.scala +run/t5274_1.scala +run/t5224.scala +run/reflection-sanitychecks.scala +run/t6086-vanilla.scala +run/t5277_2.scala +run/reflection-methodsymbol-params.scala +run/reflection-valueclasses-standard.scala +run/t5274_2.scala +run/t5423.scala +run/reflection-modulemirror-toplevel-good.scala +run/t5419.scala +run/t5271_3.scala +run/reflection-enclosed-nested-basic.scala +run/reflection-enclosed-nested-nested-basic.scala +run/fail-non-value-types.scala +run/exprs_serialize.scala +run/t5258a.scala +run/typetags_without_scala_reflect_manifest_lookup.scala +run/t4110-new.scala +run/t5273_2b_newpatmat.scala +run/t6277.scala +run/t5335.scala +run/toolbox_typecheck_macrosdisabled.scala +run/reflection-modulemirror-inner-good.scala +run/t5229_2.scala +run/typetags_multi.scala +run/typetags_without_scala_reflect_typetag_manifest_interop.scala +run/reflection-constructormirror-toplevel-good.scala +run/reflection-magicsymbols-invoke.scala +run/t6392b.scala +run/t5229_1.scala +run/reflection-magicsymbols-vanilla.scala +run/t5225_2.scala +run/runtimeEval1.scala +run/reflection-enclosed-nested-inner-basic.scala +run/reflection-fieldmirror-ctorparam.scala +run/t6181.scala +run/reflection-magicsymbols-repl.scala +run/t5272_2_newpatmat.scala +run/t5270.scala +run/t5418a.scala +run/t5276_2b.scala +run/t5256f.scala +run/reflection-enclosed-basic.scala +run/reflection-constructormirror-inner-badpath.scala +run/interop_typetags_are_manifests.scala +run/newTags.scala +run/t5273_1_newpatmat.scala +run/reflection-constructormirror-nested-good.scala +run/t2236-new.scala +run/existentials3-new.scala +run/t6323b.scala +run/t5943a1.scala +run/reflection-fieldmirror-getsetval.scala +run/t5272_1_oldpatmat.scala +run/t5256h.scala +run/t1195-new.scala +run/t5840.scala +run/reflection-methodsymbol-returntype.scala +run/reflection-fieldmirror-accessorsareokay.scala +run/reflection-sorted-members.scala +run/reflection-allmirrors-tostring.scala +run/valueclasses-typetag-existential.scala +run/toolbox_console_reporter.scala +run/reflection-enclosed-inner-inner-basic.scala +run/t5256b.scala +run/bytecodecs.scala +run/elidable.scala +run/freetypes_false_alarm1.scala +run/freetypes_false_alarm2.scala +run/getClassTest-new.scala +run/idempotency-extractors.scala +run/idempotency-case-classes.scala +run/idempotency-this.scala +run/idempotency-labels.scala +run/idempotency-lazy-vals.scala +run/interop_manifests_are_abstypetags.scala +run/interop_manifests_are_typetags.scala +run/abstypetags_core.scala +run/macro-reify-abstypetag-notypeparams +run/macro-reify-abstypetag-typeparams-tags +run/macro-reify-abstypetag-typeparams-notags +run/macro-reify-abstypetag-usetypetag +run/macro-reify-freevars +run/macro-reify-splice-outside-reify +run/macro-reify-tagless-a +run/macro-reify-type +run/macro-reify-typetag-typeparams-tags +run/macro-reify-typetag-notypeparams +run/macro-undetparams-implicitval +run/manifests-new.scala +run/manifests-old.scala +run/no-pickle-skolems +run/position-val-def.scala +run/reflect-priv-ctor.scala +run/primitive-sigs-2-new.scala +run/primitive-sigs-2-old.scala +run/reflection-enclosed-inner-basic.scala +run/reflection-enclosed-inner-nested-basic.scala +run/reflection-constructormirror-inner-good.scala +run/reflection-constructormirror-nested-badpath.scala +run/reflection-fancy-java-classes +run/reflection-fieldsymbol-navigation.scala +run/reflection-fieldmirror-nmelocalsuffixstring.scala +run/reflection-fieldmirror-getsetvar.scala +run/reflection-fieldmirror-privatethis.scala +run/reflection-implicit.scala +run/reflection-mem-glbs.scala +run/reflection-mem-tags.scala +run/reflection-java-annotations +run/reflection-java-crtp +run/reflection-methodsymbol-typeparams.scala +run/reflection-modulemirror-nested-badpath.scala +run/reflection-modulemirror-inner-badpath.scala +run/reflection-modulemirror-nested-good.scala +run/reflection-modulemirror-toplevel-badpath.scala +run/reflection-sync-subtypes.scala +run/reflinit.scala +run/reflection-valueclasses-derived.scala +run/reflection-valueclasses-magic.scala +run/resetattrs-this.scala +run/runtimeEval2.scala +run/showraw_aliases.scala +run/showraw_mods.scala +run/shortClass.scala +run/showraw_nosymbol.scala +run/showraw_tree.scala +run/showraw_tree_types_untyped.scala +run/t1167.scala +run/t2577.scala +run/t2873.scala +run/t2886.scala +run/t2251b.scala +run/t3346j.scala +run/t3507-new.scala +run/t3569.scala +run/t5125b.scala +run/t5225_1.scala +run/t3425b +run/t5256a.scala +run/t5230.scala +run/t5256c.scala +run/t5256g.scala +run/t5266_1.scala +run/t5269.scala +run/t5271_1.scala +run/t5271_2.scala +run/t5271_4.scala +run/t5272_1_newpatmat.scala +run/t5272_2_oldpatmat.scala +run/t5273_1_oldpatmat.scala +run/t5273_2a_newpatmat.scala +run/t5273_2a_oldpatmat.scala +run/t5275.scala +run/t5276_1a.scala +run/t5276_2a.scala +run/t5277_1.scala +run/t5279.scala +run/t5334_1.scala +run/t5334_2.scala +run/t5415.scala +run/t5418.scala +run/t5676.scala +run/t5704.scala +run/t5710-1.scala +run/t5710-2.scala +run/t5770.scala +run/t5894.scala +run/t5816.scala +run/t5824.scala +run/t5912.scala +run/t5942.scala +run/t5943a2.scala +run/t6023.scala +run/t6113.scala +run/t6175.scala +run/t6178.scala +run/t6199-mirror.scala +run/t6199-toolbox.scala +run/t6240-universe-code-gen.scala +run/t6221 +run/t6260b.scala +run/t6259.scala +run/t6287.scala +run/t6344.scala +run/t6392a.scala +run/t6591_1.scala +run/t6591_2.scala +run/t6591_3.scala +run/t6591_5.scala +run/t6591_6.scala +run/t6591_7.scala +run/t6608.scala +run/t6677.scala +run/t6687.scala +run/t6715.scala +run/t6719.scala +run/t6793.scala +run/t6860.scala +run/t6793b.scala +run/t6793c.scala +run/t7045.scala +run/t7046.scala +run/t7008-scala-defined +run/t7120b.scala +run/t7151.scala +run/t7214.scala +run/t7235.scala +run/t7331a.scala +run/t7331b.scala +run/t7331c.scala +run/t7558.scala +run/t7556 +run/t7779.scala +run/t7868b.scala +run/toolbox_current_run_compiles.scala +run/toolbox_default_reporter_is_silent.scala +run/toolbox_parse_package.scala +run/toolbox_silent_reporter.scala +run/toolbox_typecheck_inferimplicitvalue.scala +run/typetags_serialize.scala +run/valueclasses-typetag-basic.scala +run/WeakHashSetTest.scala +run/valueclasses-typetag-generic.scala +run/t4023.scala +run/t4024.scala +run/t6380.scala +run/t5273_2b_oldpatmat.scala +run/t8104 +run/t8047.scala +run/t6992 +run/var-arity-class-symbol.scala +run/typetags_symbolof_x.scala +run/typecheck +run/t8190.scala +run/t8192 +run/t8177f.scala +run/t8199.scala +run/t7932.scala +run/t7700.scala +run/t7570c.scala +run/t7570b.scala +run/t7533.scala +run/t7570a.scala +run/t7044 +run/t7328.scala +run/t6733.scala +run/t6554.scala +run/t6732.scala +run/t6379 +run/t6411b.scala +run/t6411a.scala +run/t6260c.scala +run/t6260-delambdafy.scala +run/showdecl +run/reflection-sync-potpourri.scala +run/reflection-tags.scala +run/reflection-companiontype.scala +run/reflection-scala-annotations.scala +run/reflection-idtc.scala +run/macro-reify-nested-b2 +run/mixin-signatures.scala +run/reflection-companion.scala +run/macro-reify-nested-b1 +run/macro-reify-nested-a2 +run/macro-reify-nested-a1 +run/macro-reify-chained2 +run/macro-reify-chained1 +run/inferred-type-constructors.scala +run/mirror_symbolof_x.scala +run/t8196.scala +run/t8549b.scala +run/t8574.scala +run/t8549.scala +run/t8637.scala +run/t8253.scala +run/t9027.scala +run/t6622.scala +run/toolbox_expand_macro.scala +run/toolbox-varargs +run/t9252.scala +run/t9182.scala +run/t9102.scala +run/t720.scala +run/t9408.scala +run/t10527.scala +run/t10650 +run/trait-default-specialize.scala +run/lazy-locals-2.scala +run/t5294.scala +run/trait_fields_final.scala +run/trait_fields_bytecode.scala +run/trait_fields_volatile.scala +run/junitForwarders +run/reflect-java-param-names + +run/reify_newimpl_29.scala +run/reify_magicsymbols.scala +run/reify_inheritance.scala +run/reify_newimpl_12.scala +run/reify_typerefs_2b.scala +run/reify_csv.scala +run/reify_inner2.scala +run/reify_maps_oldpatmat.scala +run/reify_newimpl_43.scala +run/reify_nested_inner_refers_to_local.scala +run/reify_closure7.scala +run/reify_closure8b.scala +run/reify_typerefs_3b.scala +run/reify_newimpl_44.scala +run/reify_newimpl_06.scala +run/reify_newimpl_05.scala +run/reify_newimpl_20.scala +run/reify_newimpl_23.scala +run/reify_metalevel_breach_-1_refers_to_1.scala +run/reify_newimpl_41.scala +run/reify-repl-fail-gracefully.scala +run/reify_fors_oldpatmat.scala +run/reify_inner3.scala +run/reify_closure8a.scala +run/reify_closures10.scala +run/reify_ann2a.scala +run/reify_newimpl_51.scala +run/reify_newimpl_47.scala +run/reify_extendbuiltins.scala +run/reify_newimpl_30.scala +run/reify_newimpl_38.scala +run/reify_closure2a.scala +run/reify_newimpl_45.scala +run/reify_closure1.scala +run/reify_generic2.scala +run/reify_printf.scala +run/reify_closure6.scala +run/reify_newimpl_37.scala +run/reify_newimpl_35.scala +run/reify_typerefs_3a.scala +run/reify_newimpl_25.scala +run/reify_ann4.scala +run/reify_typerefs_1b.scala +run/reify_newimpl_22.scala +run/reify_this.scala +run/reify_typerefs_2a.scala +run/reify_newimpl_03.scala +run/reify_newimpl_48.scala +run/reify_varargs.scala +run/reify_newimpl_42.scala +run/reify_newimpl_15.scala +run/reify_nested_inner_refers_to_global.scala +run/reify_newimpl_02.scala +run/reify_newimpl_01.scala +run/reify_fors_newpatmat.scala +run/reify_classfileann_a.scala +run/reify_nested_outer_refers_to_local.scala +run/reify_newimpl_13.scala +run/reify_closure5a.scala +run/reify_inner4.scala +run/reify_sort.scala +run/reify_ann1a.scala +run/reify_classfileann_b.scala +run/reify_closure4a.scala +run/reify_newimpl_33.scala +run/reify_sort1.scala +run/reify_properties.scala +run/reify_generic.scala +run/reify_newimpl_27.scala +run/reify-aliases.scala +run/reify_ann3.scala +run/reify-staticXXX.scala +run/reify_ann1b.scala +run/reify_ann5.scala +run/reify_anonymous.scala +run/reify-each-node-type.scala +run/reify_copypaste2.scala +run/reify_closure3a.scala +run/reify_copypaste1.scala +run/reify_complex.scala +run/reify_for1.scala +run/reify_getter.scala +run/reify_implicits-new.scala +run/reify_inner1.scala +run/reify_implicits-old.scala +run/reify_lazyunit.scala +run/reify_lazyevaluation.scala +run/reify_maps_newpatmat.scala +run/reify_metalevel_breach_+0_refers_to_1.scala +run/reify_metalevel_breach_-1_refers_to_0_a.scala +run/reify_metalevel_breach_-1_refers_to_0_b.scala +run/reify_nested_outer_refers_to_global.scala +run/reify_newimpl_04.scala +run/reify_newimpl_14.scala +run/reify_newimpl_11.scala +run/reify_newimpl_18.scala +run/reify_newimpl_19.scala +run/reify_newimpl_31.scala +run/reify_newimpl_21.scala +run/reify_newimpl_36.scala +run/reify_newimpl_39.scala +run/reify_newimpl_40.scala +run/reify_newimpl_49.scala +run/reify_newimpl_50.scala +run/reify_newimpl_52.scala +run/reify_renamed_term_basic.scala +run/reify_renamed_term_local_to_reifee.scala +run/reify_renamed_term_overloaded_method.scala +run/reify_renamed_type_basic.scala +run/reify_renamed_type_local_to_reifee.scala +run/reify_renamed_type_spliceable.scala +run/reify_typerefs_1a.scala +run/reify_timeofday.scala +run/reify_renamed_term_t5841.scala + +run/t7521b.scala +run/t8575b.scala +run/t8575c.scala +run/t8944c.scala +run/t9535.scala +run/t9437a +run/t9814.scala +run/t10009.scala +run/t10075.scala +run/t10075b + +run/t8756.scala +run/inferred-type-constructors-hou.scala +run/trait-static-forwarder +run/SD-235.scala +run/t10026.scala +run/checkinit.scala +run/reflection-clinit +run/reflection-clinit-nested + +# Uses refletction indirectly through +# scala.runtime.ScalaRunTime.replStringOf +run/t6634.scala + +# Using reflection to invoke macros. These tests actually don't require +# or test reflection, but use it to separate compilation units nicely. +# It's a pity we cannot use them + +run/macro-abort-fresh +run/macro-expand-varargs-explicit-over-nonvarargs-bad +run/macro-invalidret-doesnt-conform-to-def-rettype +run/macro-invalidret-nontypeable +run/macro-invalidusage-badret +run/macro-invalidusage-partialapplication +run/macro-invalidusage-partialapplication-with-tparams +run/macro-reflective-ma-normal-mdmi +run/macro-reflective-mamd-normal-mi + +# Using macros, but indirectly creating calls to reflection +run/macro-reify-unreify + +# Using Enumeration in a way we cannot fix + +run/enums.scala +run/t3719.scala +run/t8611b.scala + +# Exceptions that become JavaScriptException + +run/pf-catch.scala +run/exceptions-2.scala +run/exceptions-nest.scala +run/t8601c.scala +run/t8601b.scala +run/inlineHandlers.scala + +# Expecting unsupported exceptions (e.g. ArrayIndexOutOfBounds) +run/optimizer-array-load.scala +run/t6827.scala +run/t8601.scala + +# Expecting exceptions that are linking errors in Scala.js (e.g. NoSuchMethodException) +run/t10334.scala + +# Playing with classfile format + +run/classfile-format-51.scala +run/classfile-format-52.scala + +# Concurrent collections (TrieMap) +# has too much stuff implemented in *.java, so no support +run/triemap-hash.scala + +# Using parallel collections + +run/t5375.scala +run/t4894.scala +run/ctries-new +run/collection-conversions.scala +run/concurrent-map-conversions.scala +run/t4761.scala +run/t7498.scala +run/t6448.scala +run/ctries-old +run/map_java_conversions.scala +run/parmap-ops.scala +run/pc-conversions.scala +run/t4459.scala +run/t4608.scala +run/t4723.scala +run/t4895.scala +run/t6052.scala +run/t6410.scala +run/t6467.scala +run/t6908.scala +run/t8955.scala + +# Using scala.xml + +run/t4124.scala + +# Using Swing + +run/t3613.scala + +# Using the REPL + +run/t4285.scala +run/constant-type.scala +run/repl-bare-expr.scala +run/repl-parens.scala +run/repl-assign.scala +run/t5583.scala +run/treePrint.scala +run/constrained-types.scala +run/repl-power.scala +run/t4710.scala +run/repl-paste.scala +run/repl-reset.scala +run/repl-paste-3.scala +run/t6329_repl.scala +run/t6273.scala +run/repl-paste-2.scala +run/t5655.scala +run/t5072.scala +run/repl-colon-type.scala +run/repl-trim-stack-trace.scala +run/t4594-repl-settings.scala +run/repl-save.scala +run/repl-paste-raw.scala +run/repl-paste-4.scala +run/t7801.scala +run/repl-backticks.scala +run/t6633.scala +run/repl-inline.scala + +# Using the Repl (scala.tools.partest.ReplTest) +run/class-symbol-contravariant.scala +run/lub-visibility.scala +run/macro-bundle-repl.scala +run/macro-repl-basic.scala +run/macro-repl-dontexpand.scala +run/macro-system-properties.scala +run/reflection-equality.scala +run/reflection-repl-elementary.scala +run/reify_newimpl_26.scala +run/repl-out-dir.scala +run/repl-term-macros.scala +run/repl-transcript.scala +run/repl-type-verbose.scala +run/t3376.scala +run/t4025.scala +run/t4172.scala +run/t4216.scala +run/t4542.scala +run/t4671.scala +run/t5256d.scala +run/t5535.scala +run/t5537.scala +run/t5789.scala +run/t6086-repl.scala +run/t6146b.scala +run/t6187.scala +run/t6320.scala +run/t6381.scala +run/t6434.scala +run/t6439.scala +run/t6507.scala +run/t6549.scala +run/t6937.scala +run/t7185.scala +run/t7319.scala +run/t7482a.scala +run/t7634.scala +run/t7747-repl.scala +run/t7805-repl-i.scala +run/tpeCache-tyconCache.scala +run/repl-empty-package +run/repl-javap-def.scala +run/repl-javap-mem.scala +run/repl-javap-outdir +run/repl-javap.scala +run/t6329_repl_bug.scala +run/t4950.scala +run/xMigration.scala +run/t6541-option.scala +run/repl-serialization.scala +run/t9174.scala +run/repl-paste-5.scala +run/repl-no-uescape.scala +run/repl-no-imports-no-predef-classbased.scala +run/repl-implicits-nopredef.scala +run/repl-classbased.scala +run/repl-no-imports-no-predef-power.scala +run/repl-paste-b.scala +run/repl-paste-6.scala +run/repl-implicits.scala +run/repl-no-imports-no-predef.scala +run/repl-paste-raw-b.scala +run/repl-paste-raw-c.scala +run/t9749-repl-dot.scala +run/trait_fields_repl.scala +run/t7139 +run/t9689 +run/trailing-commas.scala +run/t4700.scala +run/t9880-9881.scala +run/repl-kind.scala +run/t10284.scala +run/t9016.scala +run/repl-completions.scala + +# Using Scala Script (partest.ScriptTest) + +run/t7711-script-args.scala +run/t4625.scala +run/t4625c.scala +run/t4625b.scala + +# Using the compiler API + +run/t2512.scala +run/analyzerPlugins.scala +run/compiler-asSeenFrom.scala +run/t5603.scala +run/t6440.scala +run/t5545.scala +run/existentials-in-compiler.scala +run/global-showdef.scala +run/stream_length.scala +run/annotatedRetyping.scala +run/imain.scala +run/existential-rangepos.scala +run/delambdafy_uncurry_byname_inline.scala +run/delambdafy_uncurry_byname_method.scala +run/delambdafy_uncurry_inline.scala +run/delambdafy_t6555.scala +run/delambdafy_uncurry_method.scala +run/delambdafy_t6028.scala +run/memberpos.scala +run/programmatic-main.scala +run/reflection-names.scala +run/settings-parse.scala +run/sm-interpolator.scala +run/t1501.scala +run/t1500.scala +run/sammy_java8.scala +run/t1618.scala +run/t2464 +run/t4072.scala +run/t5064.scala +run/t5385.scala +run/t5699.scala +run/t5717.scala +run/t5940.scala +run/t6028.scala +run/t6194.scala +run/t6669.scala +run/t6745-2.scala +run/t7096.scala +run/t7271.scala +run/t7337.scala +run/t7398.scala +run/t7569.scala +run/t7852.scala +run/t7817-tree-gen.scala +run/t7825.scala + +# partest.ParserTest +run/t3368.scala +run/t3368-b.scala +run/t3368-c.scala +run/t3368-d.scala +run/t9944.scala + +# partest.DirectTest +run/maxerrs.scala +run/t6288.scala +run/t6331.scala +run/t6440b.scala +run/t6555.scala +run/t7876.scala +run/typetags_without_scala_reflect_typetag_lookup.scala +run/dynamic-updateDynamic.scala +run/dynamic-selectDynamic.scala +run/dynamic-applyDynamic.scala +run/dynamic-applyDynamicNamed.scala +run/t4841-isolate-plugins +run/large_code.scala +run/macroPlugins-namerHooks.scala +run/t4841-no-plugin.scala +run/t4332.scala +run/t8029.scala +run/t8046 +run/t5905-features.scala +run/t5905b-features.scala +run/large_class.scala +run/t8708_b +run/icode-reader-dead-code.scala +run/t5938.scala +run/t8502.scala +run/t6502.scala +run/t8907.scala +run/t9097.scala +run/macroPlugins-enterStats.scala +run/sbt-icode-interface.scala +run/t8502b.scala +run/repl-paste-parse.scala +run/t5463.scala +run/t8433.scala +run/sd275.scala +run/sd275-java +run/t10471.scala +run/t6130.scala +run/t9437b.scala +run/t10552 + +# Using partest.StoreReporterDirectTest +run/t10171 + +# partest.StubErrorMessageTest +run/StubErrorBInheritsFromA.scala +run/StubErrorComplexInnerClass.scala +run/StubErrorHK.scala +run/StubErrorReturnTypeFunction.scala +run/StubErrorReturnTypeFunction2.scala +run/StubErrorReturnTypePolyFunction.scala +run/StubErrorSubclasses.scala +run/StubErrorTypeclass.scala +run/StubErrorTypeDef.scala + +# partest.CompilerTest +run/t8852a.scala + +# partest.ASMConverters +run/t9403 + +# partest.BytecodeTest +run/t7106 +run/t7974 +run/t8601-closure-elim.scala +run/t4788 +run/t4788-separate-compilation + +# partest.SessionTest +run/t8843-repl-xlat.scala +run/t9206.scala +run/t9170.scala +run/t8918-unary-ids.scala +run/t1931.scala +run/t8935-class.scala +run/t8935-object.scala + +# partest.JavapTest +run/t8608-no-format.scala + +# Using .java source files + +run/t4317 +run/t4238 +run/t2296c +run/t4119 +run/t4283 +run/t4891 +run/t6168 +run/t6168b +run/t6240a +run/t6240b +run/t6548 +run/t6989 +run/t7008 +run/t7246 +run/t7246b +run/t7359 +run/t7439 +run/t7455 +run/t7510 +run/t7582-private-within +run/t7582 +run/t7582b +run/t3897 +run/t7374 +run/t3452e +run/t3452g +run/t3452d +run/t3452b +run/t3452a +run/t1430 +run/t4729 +run/t8442 +run/t8601e +run/t9298 +run/t9298b +run/t9359 +run/t7741a +run/t7741b +run/bcodeInlinerMixed +run/t9268 +run/t9489 +run/t9915 +run/t10059 +run/t1459 +run/t1459generic +run/t3236 +run/t9013 +run/t10231 +run/t10067 +run/t10249 +run/sd143 +run/t4283b +run/t7936 +run/t7936b +run/t9937 +run/t10368 +run/t10334b +run/sd304 +run/t10450 +run/t10042 +run/t10699 + +# Using scala-script +run/t7791-script-linenums.scala + +# Suffers from bug in Node.js (https://github.com/joyent/node/issues/7528) +run/range-unit.scala + +# Using scalap +run/scalapInvokedynamic.scala + +# Using Manifests (which use Class.getInterfaces) +run/valueclasses-manifest-existential.scala +run/existentials3-old.scala +run/t2236-old.scala +run/interop_manifests_are_classtags.scala +run/valueclasses-manifest-generic.scala +run/valueclasses-manifest-basic.scala +run/t1195-old.scala +run/t3758-old.scala +run/t4110-old.scala +run/t6246.scala + +# Using ScalaRunTime.stringOf +run/value-class-extractor-seq.scala +run/t3493.scala + +# Custom invoke dynamic node +run/indy-via-macro +run/indy-via-macro-with-dynamic-args + +# Crashes our optimizer because of artificially insane amount of inlining +run/t10594.scala + +### Incorrect partests ### +# Badly uses constract of Console.print (no flush) +run/t429.scala +run/t6102.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/BuglistedTests.txt new file mode 100644 index 0000000000..273cb2c2d4 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/BuglistedTests.txt @@ -0,0 +1,7 @@ +# The tests in this file should pass but have never passed so far +# use scala.tools.partest.scalajs.testunknownonly to only run tests +# which are neither in BuglistedTests.txt, WhitelistedTests.txt or +# BlacklistedTests.txt + +# Broken by GCC, filed as #2815 +run/Predef.readLine.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/WhitelistedTests.txt new file mode 100644 index 0000000000..e763a0f44e --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/WhitelistedTests.txt @@ -0,0 +1,3433 @@ +pos/spec-super.scala +pos/t1035.scala +pos/t5897.scala +pos/irrefutable.scala +pos/spec-partialmap.scala +pos/tcpoly_seq.scala +pos/partialfun.scala +pos/t2795-new.scala +pos/clsrefine.scala +pos/t0774 +pos/t1070.scala +pos/t5957 +pos/looping-jsig.scala +pos/t3274.scala +pos/spec-fields-old.scala +pos/t262.scala +pos/t7486.scala +pos/t2261.scala +pos/t6600.scala +pos/t4786.scala +pos/t5406.scala +pos/tcpoly_late_method_params.scala +pos/t2726 +pos/pos-bug1210.scala +pos/t3312.scala +pos/manifest1-old.scala +pos/gadt-gilles.scala +pos/t4842.scala +pos/ted.scala +pos/NoCyclicReference.scala +pos/t3568.scala +pos/t0030.scala +pos/t2635.scala +pos/t7232b +pos/t0017.scala +pos/t812.scala +pos/t2179.scala +pos/t651.scala +pos/spurious-overload.scala +pos/t758.scala +pos/t4760.scala +pos/t1672.scala +pos/mixins.scala +pos/patterns.scala +pos/t1260.scala +pos/t6551.scala +pos/t2060.scala +pos/t6575a.scala +pos/t1318.scala +pos/t4266.scala +pos/t0695 +pos/protected-static +pos/t5738.scala +pos/t1226.scala +pos/t5013 +pos/t6215.scala +pos/t5692b +pos/traits.scala +pos/t2994a.scala +pos/t3371.scala +pos/t613.scala +pos/t6499.scala +pos/xlint1.scala +pos/t1150 +pos/test4a.scala +pos/t2664.scala +pos/t3528.scala +pos/t3174.scala +pos/t6994.scala +pos/t4812.scala +pos/t5777.scala +pos/t5223.scala +pos/t439.scala +pos/t3079.scala +pos/t5829.scala +pos/t0036.scala +pos/scoping2.scala +pos/t4717.scala +pos/t4257.scala +pos/t1210a.scala +pos/getClassType.scala +pos/t5330.scala +pos/t4524.scala +pos/t2945.scala +pos/t6562.scala +pos/t0273.scala +pos/override-object-yes.scala +pos/t7426.scala +pos/t6601 +pos/t3076 +pos/seq-ordering.scala +pos/spec-groups.scala +pos/t296.scala +pos/t5545 +pos/spec-multiplectors.scala +pos/t1789.scala +pos/t2569 +pos/ksbug1.scala +pos/t0599.scala +pos/local-objects.scala +pos/t0081.scala +pos/t5756.scala +pos/t7126.scala +pos/t7716.scala +pos/t2797.scala +pos/t5399.scala +pos/t1101 +pos/t767.scala +pos/contrib467.scala +pos/t7532b +pos/self-type-override.scala +pos/t4853.scala +pos/t839.scala +pos/t5644 +pos/t5853.scala +pos/t5178.scala +pos/unapplyNeedsMemberType.scala +pos/t5390.scala +pos/t6575b.scala +pos/t151.scala +pos/t2665.scala +pos/t5120.scala +pos/erasure-nsquared.scala +pos/arrays3.scala +pos/t3136.scala +pos/inline-access-levels +pos/t3972.scala +pos/t2591.scala +pos/t3486 +pos/variances-flip.scala +pos/annotated-original +pos/typesafecons.scala +pos/stable.scala +pos/t1996.scala +pos/t3037.scala +pos/t1711 +pos/t3374.scala +pos/t0029.scala +pos/t3278.scala +pos/matthias3.scala +pos/t5546.scala +pos/t4020.scala +pos/matthias4.scala +pos/value-class-override-spec.scala +pos/arrays2.scala +pos/t5119.scala +pos/t2613.scala +pos/t4070b.scala +pos/virtpatmat_exist_uncurry.scala +pos/modules1.scala +pos/spec-constr-new.scala +pos/t6335.scala +pos/t675.scala +pos/t0644.scala +pos/t5892.scala +pos/t360.scala +pos/override.scala +pos/t1798.scala +pos/strip-tvars-for-lubbasetypes.scala +pos/hk-infer.scala +pos/t2119.scala +pos/t0231.scala +pos/t1459 +pos/t1381-new.scala +pos/t2610.scala +pos/t2708.scala +pos/t5604b +pos/t3951 +pos/t361.scala +pos/t319.scala +pos/largecasetest.scala +pos/switchUnbox.scala +pos/typetags.scala +pos/java-access-pos +pos/t803.scala +pos/t3898.scala +pos/t5692a +pos/t2421.scala +pos/t1102 +pos/t0654.scala +pos/exhaust_alternatives.scala +pos/t807.scala +pos/t5702-pos-infix-star.scala +pos/t1186 +pos/t1439.scala +pos/t7427.scala +pos/virtpatmat_binding_opt.scala +pos/t247.scala +pos/abstract.scala +pos/gen-traversable-methods.scala +pos/t2795-old.scala +pos/t5639 +pos/t2667.scala +pos/t2405.scala +pos/t1438.scala +pos/t1659.scala +pos/unchecked-a.scala +pos/t3636.scala +pos/t6745.scala +pos/t2809.scala +pos/t7022.scala +pos/t6447.scala +pos/t5846.scala +pos/lubs.scala +pos/t1987a.scala +pos/spec-arrays.scala +pos/virtpatmat_anonfun_for.scala +pos/listpattern.scala +pos/t5742.scala +pos/test5refine.scala +pos/t5604 +pos/return_thistype.scala +pos/t348plus.scala +pos/t3420.scala +pos/t3440.scala +pos/maxim1.scala +pos/caseClassInMethod.scala +pos/t3833.scala +pos/t6675.scala +pos/t4402 +pos/t5953.scala +pos/t1152 +pos/t0591.scala +pos/t210.scala +pos/t7035.scala +pos/t5769.scala +pos/pmbug.scala +pos/t2331.scala +pos/t5240.scala +pos/t304.scala +pos/annotated-treecopy +pos/t2081.scala +pos/t0904.scala +pos/t7649.scala +pos/t3498-new.scala +pos/contrib701.scala +pos/t6624.scala +pos/t3924.scala +pos/t374.scala +pos/t1642 +pos/t1591_pos.scala +pos/depmet_implicit_oopsla_session_2.scala +pos/t5899.scala +pos/thistype.scala +pos/t4176b.scala +pos/elidable-tparams.scala +pos/lambdalift.scala +pos/nothing_manifest_disambig-old.scala +pos/t372.scala +pos/t5399a.scala +pos/t2782.scala +pos/patmat-extract-tparam.scala +pos/t4114.scala +pos/unapplyVal.scala +pos/t2486.scala +pos/t5877b.scala +pos/t0625.scala +pos/t6358_2.scala +pos/viewtest1.scala +pos/t1237.scala +pos/scala-singleton.scala +pos/t1254 +pos/t5504 +pos/bounds.scala +pos/t3631.scala +pos/t3177.scala +pos/unapplyContexts2.scala +pos/t0438.scala +pos/t1642b.scala +pos/inferbroadtype.scala +pos/t1858.scala +pos/t3731.scala +pos/t6963c.scala +pos/classtag-pos.scala +pos/t6221.scala +pos/t3343.scala +pos/spec-asseenfrom.scala +pos/t604.scala +pos/spec-example1.scala +pos/t0786.scala +pos/annot-inner.scala +pos/t5886.scala +pos/t1056.scala +pos/t294 +pos/spec-Function1.scala +pos/t1836 +pos/spec-private.scala +pos/depmet_implicit_tpbetareduce.scala +pos/exhaust_2.scala +pos/t7532 +pos/t5175.scala +pos/t802.scala +pos/t5809.scala +pos/tcpoly_typesub.scala +pos/t6029.scala +pos/contextbounds-implicits-new.scala +pos/t3480.scala +pos/patterns3.scala +pos/caseaccs.scala +pos/spec-sparsearray-old.scala +pos/patterns1213.scala +pos/spec-traits.scala +pos/t0020.scala +pos/cycle +pos/t5968.scala +pos/typealiases.scala +pos/init.scala +pos/t697.scala +pos/t2693.scala +pos/t2377 +pos/unapplyGeneric.scala +pos/t1385.scala +pos/t3363-old.scala +pos/t1236.scala +pos/t0068.scala +pos/t4052.scala +pos/lambdalift1.scala +pos/z1730.scala +pos/variances-local.scala +pos/virtpatmat_gadt_array.scala +pos/t2421_delitedsl.scala +pos/t5626.scala +pos/t690.scala +pos/t711.scala +pos/t1937 +pos/t3999 +pos/t2305.scala +pos/t2168.scala +pos/t2660.scala +pos/t1693.scala +pos/t2799.scala +pos/t6966.scala +pos/t1001.scala +pos/S5.scala +pos/t0301.scala +pos/t1048.scala +pos/t415.scala +pos/t6386.scala +pos/t2187.scala +pos/hashhash-overloads.scala +pos/t6921.scala +pos/t0227.scala +pos/t6556.scala +pos/t3946 +pos/t1053.scala +pos/t1000.scala +pos/t0586.scala +pos/t7011.scala +pos/t7329.scala +pos/t4975.scala +pos/t1131.scala +pos/t1027.scala +pos/t2913.scala +pos/t3494.scala +pos/t5606.scala +pos/t4716.scala +pos/tcpoly_gm.scala +pos/t4859.scala +pos/t514.scala +pos/lexical.scala +pos/t2624.scala +pos/t4036.scala +pos/t2741 +pos/t703.scala +pos/five-dot-f.scala +pos/t805.scala +pos/strings.scala +pos/t2433 +pos/t6925.scala +pos/t1085.scala +pos/t7461 +pos/t1942 +pos/spec-lists.scala +pos/t3349 +pos/tcpoly_infer_ticket474.scala +pos/t1614 +pos/virtpatmat_reach_const.scala +pos/t2194.scala +pos/t6976 +pos/t1560.scala +pos/t6891.scala +pos/t3883.scala +pos/infersingle.scala +pos/gui.scala +pos/t1164.scala +pos/t3175-pos.scala +pos/t4336.scala +pos/annotations2.scala +pos/proj-rec-test.scala +pos/t2973.scala +pos/t1123.scala +pos/t6205.scala +pos/t5727.scala +pos/t6537.scala +pos/t6712.scala +pos/t3866.scala +pos/t4831.scala +pos/selftails.scala +pos/t397.scala +pos/spec-vector.scala +pos/t7233b.scala +pos/t1391.scala +pos/spec.scala +pos/t3106.scala +pos/contextbounds-implicits-old.scala +pos/packageobjs.scala +pos/michel3.scala +pos/t628.scala +pos/collections.scala +pos/tcpoly_boundedmonad.scala +pos/t7668.scala +pos/t0032.scala +pos/t0069.scala +pos/t4345.scala +pos/t3521 +pos/t3071.scala +pos/tcpoly_infer_easy.scala +pos/t289.scala +pos/t4365 +pos/rangepos-anonapply.scala +pos/t5033.scala +pos/lambda.scala +pos/S8.scala +pos/t6014.scala +pos/t1785.scala +pos/t6034.scala +pos/t7433.scala +pos/imp2-pos.scala +pos/t0504.scala +pos/t1272.scala +pos/t0612 +pos/value-class-override-no-spec.scala +pos/overloaded-unapply.scala +pos/t5859.scala +pos/chang +pos/localmodules.scala +pos/t4237.scala +pos/rangepos-patmat.scala +pos/t1974.scala +pos/t0054.scala +pos/michel2.scala +pos/t0770.scala +pos/t1146.scala +pos/t2441pos.scala +pos/t5099.scala +pos/tcpoly_seq_typealias.scala +pos/t946.scala +pos/tcpoly_infer_ticket1864.scala +pos/t4737 +pos/t7377b.scala +pos/t616.scala +pos/t201.scala +pos/t6355pos.scala +pos/escapes2.scala +pos/t1675.scala +pos/t3890.scala +pos/t6040.scala +pos/spec-tailcall.scala +pos/existentials.scala +pos/t5317.scala +pos/t7782b.scala +pos/t4758.scala +pos/t7296.scala +pos/t6896.scala +pos/cls1.scala +pos/t402.scala +pos/gosh.scala +pos/t2619.scala +pos/javaConversions-2.10-regression.scala +pos/t759.scala +pos/t5259.scala +pos/t5130.scala +pos/t5156.scala +pos/t0905.scala +pos/package-implicit +pos/t2669.scala +pos/trait-parents.scala +pos/virtpatmat_exhaust.scala +pos/patterns1.scala +pos/t1231 +pos/t1751 +pos/t7233.scala +pos/t6022.scala +pos/tcpoly_checkkinds_mix.scala +pos/depmet_implicit_norm_ret.scala +pos/package-case.scala +pos/philippe4.scala +pos/michel6.scala +pos/t4188.scala +pos/t3936 +pos/t1280.scala +pos/t6722.scala +pos/t796.scala +pos/t5542.scala +pos/t3927.scala +pos/t2293.scala +pos/t3800.scala +pos/t7285a.scala +pos/t927.scala +pos/t4494.scala +pos/t3864 +pos/ilya2 +pos/t2940 +pos/S1.scala +pos/tcpoly_wildcards.scala +pos/tryexpr.scala +pos/t6089b.scala +pos/depmet_implicit_oopsla_zipwith.scala +pos/t245.scala +pos/t6146.scala +pos/t1782 +pos/t851.scala +pos/spec-thistype.scala +pos/tcpoly_poly.scala +pos/t6815_import.scala +pos/t4649.scala +pos/t0453.scala +pos/t5020.scala +pos/ilya +pos/t2435.scala +pos/t1279a.scala +pos/t1957.scala +pos/gadts2.scala +pos/t3567 +pos/Z.scala +pos/t1203b +pos/nested2.scala +pos/t1896 +pos/viewtest2.scala +pos/t5541.scala +pos/existentials-harmful.scala +pos/t4063.scala +pos/t6485a +pos/t1208.scala +pos/t5041.scala +pos/unapplyComplex.scala +pos/t3384.scala +pos/t4112.scala +pos/t788.scala +pos/hklub0.scala +pos/t757.scala +pos/t1197 +pos/t359.scala +pos/t5667.scala +pos/t1107a.scala +pos/virtpatmat_castbinder.scala +pos/t267.scala +pos/t3419 +pos/t3861.scala +pos/t6797.scala +pos/spec-localdefs.scala +pos/t3404 +pos/t4457_1.scala +pos/matthias5.scala +pos/spec-polymeth.scala +pos/kinds.scala +pos/t2310.scala +pos/t6552.scala +pos/valdefs.scala +pos/hkarray.scala +pos/homonym.scala +pos/t1235 +pos/t3429 +pos/t0053.scala +pos/depmet_implicit_chaining_zw.scala +pos/virtpatmat_partialfun_nsdnho.scala +pos/t6664.scala +pos/ticket2251.scala +pos/t3495.scala +pos/super +pos/t121.scala +pos/javaConversions-2.10-ambiguity.scala +pos/t1803.scala +pos/t5877.scala +pos/t0085.scala +pos/t3582.scala +pos/t2939.scala +pos/t1422_pos.scala +pos/manifest1-new.scala +pos/t7505.scala +pos/t5720-ownerous.scala +pos/misc-unapply_pos.scala +pos/tcpoly_variance_pos.scala +pos/t5127.scala +pos/t6123-explaintypes-implicits.scala +pos/t2764 +pos/presuperContext.scala +pos/spec-simple.scala +pos/t3120 +pos/tcpoly_infer_ticket716.scala +pos/tcpoly_bounds1.scala +pos/t7369.scala +pos/imports-pos.scala +pos/t5654.scala +pos/t0123.scala +pos/raw-map +pos/t5330b.scala +pos/t6485b +pos/t6072.scala +pos/t5692c.scala +pos/tcpoly_param_scoping.scala +pos/t6204-b.scala +pos/attachments-typed-another-ident +pos/t5359.scala +pos/ticket2197.scala +pos/t720.scala +pos/t2130-2.scala +pos/t2260.scala +pos/t0304.scala +pos/t464.scala +pos/spec-maps.scala +pos/annotDepMethType.scala +pos/t6117.scala +pos/t911.scala +pos/t757a.scala +pos/t2504.scala +pos/t1381-old.scala +pos/t1232 +pos/needstypeearly.scala +pos/moduletrans.scala +pos/t4957.scala +pos/kinzer.scala +pos/t318.scala +pos/widen-existential.scala +pos/t0095.scala +pos/t566.scala +pos/tcpoly_overloaded.scala +pos/t7516 +pos/t7232 +pos/t698.scala +pos/t0002.scala +pos/t0288 +pos/t2994b.scala +pos/cls.scala +pos/t3622 +pos/t3671.scala +pos/tcpoly_subst.scala +pos/t5703 +pos/depmet_implicit_oopsla_session_simpler.scala +pos/t5022.scala +pos/builders.scala +pos/spec-foo.scala +pos/t756.scala +pos/t1569.scala +pos/implicit-unwrap-tc.scala +pos/t3688.scala +pos/t5198.scala +pos/t432.scala +pos/t6022b.scala +pos/channels.scala +pos/t1075.scala +pos/null.scala +pos/t1840 +pos/t6479.scala +pos/t6311.scala +pos/t0039.scala +pos/t1119.scala +pos/t573.scala +pos/t1136.scala +pos/t3938 +pos/spec-sealed.scala +pos/tcpoly_return_overriding.scala +pos/t3582b.scala +pos/t229.scala +pos/t3498-old.scala +pos/t531.scala +pos/t4545.scala +pos/t6651.scala +pos/t2133.scala +pos/tinondefcons.scala +pos/t6358.scala +pos/t7690.scala +pos/t5779-numeq-warn.scala +pos/list-extractor.scala +pos/t892.scala +pos/t2127.scala +pos/t7180.scala +pos/nullary_poly.scala +pos/virtpatmat_exist3.scala +pos/t1176 +pos/spec-funs.scala +pos/specialize10.scala +pos/t6514.scala +pos/exhaustive_heuristics.scala +pos/t0066.scala +pos/t460.scala +pos/t2130-1.scala +pos/t124.scala +pos/annotations.scala +pos/pat_gilles.scala +pos/array-interfaces.scala +pos/t6210.scala +pos/t3792.scala +pos/implicits-old.scala +pos/t389.scala +pos/t115.scala +pos/virtpatmat_exhaust_unchecked.scala +pos/scoping3.scala +pos/t6033.scala +pos/depmet_implicit_oopsla_session.scala +pos/t602.scala +pos/test5.scala +pos/t611.scala +pos/t5932.scala +pos/t4910.scala +pos/unapplySeq.scala +pos/t344.scala +pos/t3363-new.scala +pos/t4018.scala +pos/t4553.scala +pos/t5082.scala +pos/t3869.scala +pos/t3836.scala +pos/tcpoly_typeapp.scala +pos/t1409 +pos/nonlocal-unchecked.scala +pos/t0082.scala +pos/z1720.scala +pos/t7232c +pos/t2018.scala +pos/t3943 +pos/t2187-2.scala +pos/unicode-decode.scala +pos/t4757 +pos/t0710.scala +pos/t0305.scala +pos/t160.scala +pos/t7591 +pos/simplelists.scala +pos/List1.scala +pos/t516.scala +pos/t6648.scala +pos/t5165 +pos/t0055.scala +pos/t4744 +pos/t7377 +pos/t5726.scala +pos/t0091.scala +pos/t6595.scala +pos/compile.scala +pos/depmet_1_pos.scala +pos/t7364 +pos/philippe3.scala +pos/spec-doubledef-old.scala +pos/t4651.scala +pos/tcpoly_infer_implicit_tuple_wrapper.scala +pos/t6274.scala +pos/tcpoly_infer_explicit_tuple_wrapper.scala +pos/ticket2201.scala +pos/spec-fields-new.scala +pos/optmatch.scala +pos/t7517.scala +pos/t3560.scala +pos/t0165.scala +pos/t0872.scala +pos/t522.scala +pos/t2234.scala +pos/t5031_2.scala +pos/tcpoly_method.scala +pos/t6482.scala +pos/pos-bug1241.scala +pos/implicits-new.scala +pos/t2484.scala +pos/t2425.scala +pos/t1049.scala +pos/michel4.scala +pos/t5958.scala +pos/virtpatmat_instof_valuetype.scala +pos/spec-t6286.scala +pos/t873.scala +pos/t3137.scala +pos/Transactions.scala +pos/t0064.scala +pos/t7486-named.scala +pos/t5444.scala +pos/simple-exceptions.scala +pos/t1006.scala +pos/t7200b.scala +pos/t3777.scala +pos/t4840.scala +pos/t211.scala +pos/nullary.scala +pos/michel1.scala +pos/t5031_3 +pos/typealias_dubious.scala +pos/spec-doubledef-new.scala +pos/philippe1.scala +pos/thistypes.scala +pos/t3570.scala +pos/t6516.scala +pos/context.scala +pos/t3808.scala +pos/philippe2.scala +pos/constfold.scala +pos/t1292.scala +pos/t1147.scala +pos/t404.scala +pos/t4430.scala +pos/A.scala +pos/spec-partially.scala +pos/t5796.scala +pos/t2409 +pos/t284-pos.scala +pos/t5313.scala +pos/t2464 +pos/t1591b.scala +pos/hk-match +pos/t595.scala +pos/t6846.scala +pos/t6162-inheritance.scala +pos/relax_implicit_divergence.scala +pos/patterns2.scala +pos/t4692.scala +pos/t3837.scala +pos/t661.scala +pos/t2810.scala +pos/depexists.scala +pos/virtpatmat_exist4.scala +pos/t5245.scala +pos/t7190.scala +pos/isApplicableSafe.scala +pos/t6204-a.scala +pos/t0076.scala +pos/t1756.scala +pos/t1745 +pos/t6091.scala +pos/t0154.scala +pos/t530.scala +pos/t2094.scala +pos/t1034.scala +pos/t6084.scala +pos/t2454.scala +pos/t2956 +pos/tcpoly_ticket2096.scala +pos/attachments-typed-ident +pos/polymorphic-case-class.scala +pos/t252.scala +pos/spec-constr-old.scala +pos/t2421c.scala +pos/t122.scala +pos/t6574.scala +pos/t3859.scala +pos/spec-params-old.scala +pos/t1196 +pos/t4593.scala +pos/t596.scala +pos/t615.scala +pos/t7689.scala +pos/t3960.scala +pos/t3986.scala +pos/exbound.scala +pos/t2545.scala +pos/t1722 +pos/t159.scala +pos/t3272.scala +pos/t6301.scala +pos/t2794.scala +pos/t3048.scala +pos/t4970.scala +pos/t607.scala +pos/FPTest.scala +pos/test1.scala +pos/t4176.scala +pos/t112606A.scala +pos/t2183.scala +pos/t430-feb09.scala +pos/t6275.scala +pos/t1832.scala +pos/t8965.scala +pos/t7596b +pos/t8900.scala +pos/t9008.scala +pos/t7704.scala +pos/t7459c.scala +pos/sammy_override.scala +pos/t8828.scala +pos/t8868c +pos/t7459d.scala +pos/t8267.scala +pos/t8844.scala +pos/t8868a +pos/t8894.scala +pos/t7459a.scala +pos/t7596c +pos/t8498.scala +pos/t8868b +pos/t5413.scala +pos/t8781 +pos/t8934a +pos/t8310.scala +pos/t3439.scala +pos/t6582_exhaust_big.scala +pos/t8954 +pos/t5217.scala +pos/t7459b.scala +pos/t9018.scala +pos/sammy_exist.scala +pos/t8893.scala +pos/t7596 +pos/t8793.scala +pos/sammy_overload.scala +pos/t6051.scala +pos/t7683-stop-after-parser +pos/t7750.scala +pos/t5454.scala +pos/t8962.scala +pos/t8947 +pos/t8719 +pos/t8410.scala +pos/patmat-suppress.scala +pos/t8999.scala +pos/t8743.scala +pos/t9157.scala +pos/t8801.scala +pos/t9086.scala +pos/t9050.scala +pos/t9135.scala +pos/t9116.scala +pos/t5154.scala +pos/t3368.scala +pos/t9321.scala +pos/t9285.scala +pos/t8861.scala +pos/t9020.scala +pos/jesper.scala +pos/t9356 +pos/virtpatmat_exhaust_big.scala +pos/t9239 +pos/t9111-inliner-workaround + +neg/volatile_no_override.scala +neg/t800.scala +neg/t5426.scala +neg/t2462a.scala +neg/t2641.scala +neg/classtags_dont_use_typetags.scala +neg/t5031 +neg/t2275b.scala +neg/macro-qmarkqmarkqmark.scala +neg/t4879.scala +neg/t5956.scala +neg/t4196.scala +neg/reify_ann2b.scala +neg/t6666b.scala +neg/warn-unused-privates.scala +neg/t6928.scala +neg/t6337.scala +neg/sealed-java-enums.scala +neg/t563.scala +neg/t900.scala +neg/deadline-inf-illegal.scala +neg/t766.scala +neg/t5429.scala +neg/overloaded-implicit.scala +neg/t875.scala +neg/abstract-class-error +neg/unchecked2.scala +neg/predef-masking.scala +neg/viewtest.scala +neg/macro-noexpand +neg/varargs.scala +neg/t963b.scala +neg/t909.scala +neg/sensitive2.scala +neg/t5390b.scala +neg/abstraction-from-volatile-type-error.scala +neg/macro-exception +neg/t4431.scala +neg/t5689.scala +neg/valueclasses.scala +neg/overload.scala +neg/t0204.scala +neg/t908.scala +neg/t750 +neg/patmatexhaust.scala +neg/macro-invalidusage-badtargs +neg/t1168.scala +neg/t5761.scala +neg/t0503.scala +neg/t7235.scala +neg/t1215.scala +neg/primitive-sigs-1 +neg/t5578.scala +neg/names-defaults-neg-warn.scala +neg/t6436b.scala +neg/t3098 +neg/t910.scala +neg/parstar.scala +neg/t4568.scala +neg/newpat_unreachable.scala +neg/t1181.scala +neg/t5903c +neg/t7294.scala +neg/t4091.scala +neg/t5452-old.scala +neg/t5696.scala +neg/t0209.scala +neg/t2910.scala +neg/t7388.scala +neg/noMember2.scala +neg/no-predef.scala +neg/t6952.scala +neg/t1909b.scala +neg/abstract-report2.scala +neg/t5318.scala +neg/t6074.scala +neg/t7171.scala +neg/abstract-vars.scala +neg/unchecked-impossible.scala +neg/variances-refinement.scala +neg/t3453.scala +neg/t5189.scala +neg/t4302.scala +neg/xmltruncated7.scala +neg/t8217-local-alias-requires-rhs.scala +neg/t7602.scala +neg/t8869.scala +neg/t9008.scala +neg/sammy_error_exist_no_crash.scala +neg/t2866.scala +neg/t8597b.scala +neg/t5691.scala +neg/t8534b.scala +neg/t5091.scala +neg/literals.scala +neg/t8534.scala +neg/t8890.scala +neg/t9008b.scala +neg/t8731.scala +neg/t8291.scala +neg/t8597.scala +neg/t5639b +neg/t6582_exhaust_big.scala +neg/t8841.scala +neg/t9041.scala +neg/t9093.scala +neg/t7623.scala +neg/t9231.scala +neg/t9286b.scala +neg/t9273.scala +neg/t9127.scala +neg/t9286c.scala +neg/t9286a.scala +neg/virtpatmat_exhaust_big.scala + +run/t7249.scala +run/t3563.scala +run/t6111.scala +run/classtags_multi.scala +run/t5201.scala +run/checked.scala +run/valueclasses-classtag-basic.scala +run/t7171.scala +run/t5053.scala +run/t4535.scala +run/t5923d +run/t7291.scala +run/partialfun.scala +run/macro-term-declared-in-package-object +run/mapValues.scala +run/gadts.scala +run/t2386-new.scala +run/virtpatmat_stringinterp.scala +run/t657.scala +run/t0017.scala +run/t5713 +run/t576.scala +run/t3580.scala +run/virtpatmat_partial.scala +run/t6646.scala +run/mixins.scala +run/t1672.scala +run/macro-expand-implicit-macro-has-implicit +run/tuple-match.scala +run/t7039.scala +run/virtpatmat_opt_sharing.scala +run/virtpatmat_casting.scala +run/t2176.scala +run/macro-impl-relaxed +run/intmap.scala +run/t751.scala +run/t1591.scala +run/macro-typecheck-implicitsdisabled +run/t6911.scala +run/t5604.scala +run/macro-term-declared-in-default-param +run/collection-stacks.scala +run/multi-array.scala +run/t4560b.scala +run/buffer-slice.scala +run/t5629.scala +run/t6690.scala +run/matchonstream.scala +run/t3603.scala +run/lazy-exprs.scala +run/macro-quasiquotes +run/Course-2002-13.scala +run/t6337a.scala +run/exoticnames.scala +run/t0936.scala +run/runtime-richChar.scala +run/t6272.scala +run/t7215.scala +run/t1939.scala +run/ReverseSeqView.scala +run/lazy-leaks.scala +run/t0048.scala +run/t3994.scala +run/t2241.scala +run/t627.scala +run/t5966.scala +run/getClassTest-valueClass.scala +run/t3619.scala +run/t1300.scala +run/t2177.scala +run/t3760.scala +run/t1829.scala +run/macro-expand-implicit-macro-is-view +run/t889.scala +run/QueueTest.scala +run/t4537 +run/t3699.scala +run/t1192.scala +run/macro-expand-tparams-bounds +run/macro-expand-nullary-generic +run/t1434.scala +run/t6443-varargs.scala +run/macro-term-declared-in-trait +run/t4080.scala +run/matcharraytail.scala +run/infiniteloop.scala +run/t5733.scala +run/virtpatmat_nested_lists.scala +run/t5158.scala +run/t6695.scala +run/t6070.scala +run/t4558.scala +run/exc2.scala +run/patmat-behavior-2.scala +run/overloads.scala +run/t6957.scala +run/transform.scala +run/t5500.scala +run/t6663.scala +run/castsingleton.scala +run/t4147.scala +run/virtpatmat_staging.scala +run/t4565_1.scala +run/t5588.scala +run/run-bug4840.scala +run/t3496.scala +run/t5867.scala +run/search.scala +run/t3112.scala +run/hashsetremove.scala +run/t6443.scala +run/macro-expand-tparams-prefix +run/contrib674.scala +run/t3508.scala +run/t4300.scala +run/virtpatmat_typed.scala +run/macro-term-declared-in-class-object +run/map_test.scala +run/t5040.scala +run/t4827b.scala +run/lift-and-unlift.scala +run/t6574b.scala +run/t7240 +run/t3984.scala +run/virtpatmat_tailcalls_verifyerror.scala +run/macro-term-declared-in-class-class +run/emptypf.scala +run/t6104.scala +run/t2818.scala +run/t3761-overload-byname.scala +run/t2526.scala +run/phantomValueClass.scala +run/t3126.scala +run/arybufgrow.scala +run/t3980.scala +run/t7375b +run/t6077_patmat_cse_irrefutable.scala +run/classmanifests_new_core.scala +run/t3395.scala +run/name-based-patmat.scala +run/inliner-infer.scala +run/t5171.scala +run/t3726.scala +run/null-hash.scala +run/t4027.scala +run/t2544.scala +run/patmatnew.scala +run/t5923b +run/t7242.scala +run/classtags_core.scala +run/streamWithFilter.scala +run/t3038b.scala +run/macro-expand-varargs-explicit-over-nonvarargs-good +run/macro-divergence-spurious +run/macro-duplicate +run/t2958.scala +run/patch-boundary.scala +run/t2333.scala +run/lazy-override-run.scala +run/macro-quasiinvalidbody-c +run/t5037.scala +run/takeAndDrop.scala +run/t6126.scala +run/t0883.scala +run/t7617a +run/t4171.scala +run/empty-array.scala +run/t7198.scala +run/t493.scala +run/genericValueClass.scala +run/t0677-old.scala +run/t1373.scala +run/t4461.scala +run/t6011b.scala +run/t7584.scala +run/t3935.scala +run/t6928-run.scala +run/t744.scala +run/t3241.scala +run/blame_eye_triple_eee-double.scala +run/t3829.scala +run/t5577.scala +run/t5914.scala +run/t601.scala +run/t5610.scala +run/macro-basic-mamd-mi +run/t6150.scala +run/stringbuilder.scala +run/t7290.scala +run/t6888.scala +run/t6327.scala +run/virtpatmat_unapplyseq.scala +run/t4656.scala +run/macro-term-declared-in-method +run/macro-expand-implicit-macro-is-implicit +run/blame_eye_triple_eee-float.scala +run/t4482.scala +run/t5488.scala +run/matchemptyarray.scala +run/t3714.scala +run/richWrapperEquals.scala +run/t5328.scala +run/stream_flatmap_odds.scala +run/implicitclasses.scala +run/t6394b +run/complicatedmatch.scala +run/valueclasses-classmanifest-basic.scala +run/unreachable.scala +run/caseclasses.scala +run/withIndex.scala +run/exc1.scala +run/amp.scala +run/t1423.scala +run/t594.scala +run/t6353.scala +run/byname.scala +run/vector1.scala +run/t5879.scala +run/t1048.scala +run/t5080.scala +run/t4190.scala +run/caseClassEquality.scala +run/macro-enclosures +run/collections-toSelf.scala +run/implicits.scala +run/finalvar.scala +run/lazy-locals.scala +run/t7231.scala +run/t0508.scala +run/t6628.scala +run/t6406-regextract.scala +run/t0911.scala +run/t4013c.scala +run/t3502.scala +run/t5648.scala +run/retclosure.scala +run/t2857.scala +run/t4859.scala +run/t5162.scala +run/t3038.scala +run/classof.scala +run/t4062.scala +run/unapplyArray.scala +run/t4297.scala +run/t5923a +run/t1537.scala +run/boolexprs.scala +run/valueclasses-classtag-generic.scala +run/macro-term-declared-in-anonymous +run/tcpoly_monads.scala +run/t5407.scala +run/scan.scala +run/forvaleq.scala +run/null-and-intersect.scala +run/t7047 +run/t0607.scala +run/sequenceComparisons.scala +run/t4396.scala +run/macro-undetparams-consfromsls +run/t2029.scala +run/t1220.scala +run/option-fold.scala +run/t5284c.scala +run/macro-auto-duplicate +run/t3529.scala +run/t4697.scala +run/t2251.scala +run/t5300.scala +run/virtpatmat_valdef.scala +run/t2147.scala +run/virtpatmat_extends_product.scala +run/list_map.scala +run/t1333.scala +run/matchbytes.scala +run/valueclasses-classmanifest-existential.scala +run/records.scala +run/t3088.scala +run/macro-def-path-dependent +run/t6443-by-name.scala +run/t1044.scala +run/delay-good.scala +run/case-class-23.scala +run/weakconform.scala +run/patmat-bind-typed.scala +run/t4835.scala +run/t3097.scala +run/t405.scala +run/existentials.scala +run/t2876.scala +run/t4809.scala +run/t1427.scala +run/t6135.scala +run/t3575.scala +run/t5688.scala +run/t6900.scala +run/macro-expand-unapply-a +run/t6677b.scala +run/t7375a.scala +run/t7300.scala +run/typed-annotated +run/elidable-noflags.scala +run/t0042.scala +run/t3050.scala +run/t4536.scala +run/NestedClasses.scala +run/t3877.scala +run/seqlike-kmp.scala +run/t5907.scala +run/t266.scala +run/missingparams.scala +run/t2255.scala +run/t3488.scala +run/t3950.scala +run/typealias_overriding.scala +run/constant-optimization.scala +run/t7507.scala +run/t6090.scala +run/t4582.scala +run/macro-term-declared-in-class +run/macro-typecheck-macrosdisabled2 +run/t3425.scala +run/t4935.scala +run/t3326.scala +run/boolord.scala +run/t1141.scala +run/virtpatmat_unapply.scala +run/t5971.scala +run/t3651.scala +run/macro-sip19-revised +run/pure-args-byname-noinline.scala +run/preinits.scala +run/t5532.scala +run/concat-two-strings.scala +run/t3269.scala +run/macro-impl-default-params +run/t2162.scala +run/matchonseq.scala +run/t5428.scala +run/macro-expand-overload +run/t4660.scala +run/enrich-gentraversable.scala +run/macro-expand-override +run/t4054.scala +run/t4753.scala +run/macro-typecheck-macrosdisabled +run/t2308a.scala +run/duplicate-meth.scala +run/interop_classtags_are_classmanifests.scala +run/t3232.scala +run/t2075.scala +run/virtpatmat_partial_backquoted.scala +run/try-2.scala +run/macro-openmacros +run/macro-undetparams-macroitself +run/t6318_derived.scala +run/deprecate-early-type-defs.scala +run/dead-code-elimination.scala +run/t4827.scala +run/Course-2002-07.scala +run/slice-strings.scala +run/t6292.scala +run/t6206.scala +run/t1042.scala +run/t1718.scala +run/t2074_2.scala +run/arraycopy.scala +run/indexedSeq.scala +run/macro-term-declared-in-implicit-class +run/t3511.scala +run/t6290.scala +run/distinct.scala +run/virtpatmat_alts.scala +run/valueclasses-pavlov.scala +run/exceptions.scala +run/t1368.scala +run/t5856.scala +run/t6968.scala +run/names-defaults.scala +run/macro-expand-tparams-implicit +run/t5881.scala +run/t3540.scala +run/virtpatmat_try.scala +run/t7181.scala +run/value-class-extractor.scala +run/value-class-extractor-2.scala +run/t3150.scala +run/exc.scala +run/delay-bad.scala +run/infix.scala +run/t1309.scala +run/t6370.scala +run/t6725-2.scala +run/macro-impl-tparam-typetag-is-optional +run/macro-term-declared-in-block +run/matchnull.scala +run/t2127.scala +run/t7325.scala +run/groupby.scala +run/t3932.scala +run/t4871.scala +run/longmap.scala +run/t1524.scala +run/t6187b.scala +run/kmpSliceSearch.scala +run/t7088.scala +run/t5804.scala +run/stringbuilder-drop.scala +run/t5753_1 +run/t9223.scala +run/function-null-unbox.scala +run/t9223b.scala +run/disable-assertions.scala +run/valueClassSelfType.scala +run/indylambda-boxing +run/t9219.scala + +pos/cyclics-pos.scala +pos/cfcrash.scala +pos/tcpoly_higherorder_bound_method.scala +pos/t5084.scala +pos/macro-qmarkqmarkqmark.scala +pos/t7785.scala +pos/nested.scala +pos/t3152.scala +pos/t5031 +pos/t6925b.scala +pos/t1107b +pos/t5012.scala +pos/virtpatmat_obj_in_case.scala +pos/t4938.scala +pos/t3856.scala +pos/spec-cyclic.scala +pos/aliases.scala +pos/typerep_pos.scala +pos/t119.scala +pos/t1050.scala +pos/t3670.scala +pos/t6145.scala +pos/t7315.scala +pos/t5930.scala +pos/t789.scala +pos/t5071.scala +pos/t4731.scala +pos/t4547.scala +pos/t2038.scala +pos/testCoercionThis.scala +pos/t2444.scala +pos/t5744 +pos/t780.scala +pos/t1722-A.scala +pos/virtpatmat_exist1.scala +pos/t6225.scala +pos/t762.scala +pos/t0204.scala +pos/rebind.scala +pos/spec-short.scala +pos/comp-rec-test.scala +pos/lub-dealias-widen.scala +pos/t1168.scala +pos/modules.scala +pos/t4220.scala +pos/t4070.scala +pos/t175.scala +pos/t2500.scala +pos/t5029.scala +pos/itay.scala +pos/t4202.scala +pos/t1987b +pos/t3534.scala +pos/infer2-pos.scala +pos/spec-sparsearray-new.scala +pos/t7091.scala +pos/ticket0137.scala +pos/collectGenericCC.scala +pos/t640.scala +pos/t4305.scala +pos/extractor-types.scala +pos/t3880.scala +pos/spec-annotations.scala +pos/t3577.scala +pos/compile1.scala +pos/spec-t3497.scala +pos/hkrange.scala +pos/t287.scala +pos/t6008.scala +pos/t4432.scala +pos/CustomGlobal.scala +pos/patmat.scala +pos/t2413 +pos/t2910.scala +pos/t592.scala +pos/t6245 +pos/infer.scala +pos/t7228.scala +pos/compound.scala +pos/attributes.scala +pos/t6771.scala +pos/t1090.scala +pos/t684.scala +pos/t577.scala +pos/t4273.scala +pos/t6278-synth-def.scala +pos/t6184.scala +neg/t0214.scala +neg/t4842.scala +neg/t6214.scala +neg/reify_nested_inner_refers_to_local.scala +neg/t576.scala +neg/t5969.scala +neg/tcpoly_variance.scala +neg/t7509.scala +neg/mixins.scala +neg/parent-inherited-twice-error.scala +neg/macro-abort +neg/constructor-init-order.scala +neg/t6042.scala +neg/t0590.scala +neg/t4221.scala +neg/t6263.scala +neg/t783.scala +neg/t5554.scala +neg/macro-invalidsig-params-badtype +neg/multi-array.scala +neg/raw-types-stubs +neg/spec-overrides.scala +neg/t836.scala +neg/t7289_status_quo.scala +neg/t5675.scala +neg/macro-quasiquotes +neg/t6667.scala +neg/t6597.scala +neg/t6264.scala +neg/t0345.scala +neg/t7294b.scala +neg/t5340.scala +neg/t2144.scala +neg/t1010.scala +neg/t1838.scala +neg/t5189b.scala +neg/reify_metalevel_breach_-1_refers_to_1.scala +neg/t6601 +neg/wellkinded_wrongarity.scala +neg/t3909.scala +neg/t876.scala +neg/t5390.scala +neg/unit2anyref.scala +neg/t0351.scala +neg/t5120.scala +neg/t1038.scala +neg/t5878.scala +neg/qualifying-class-error-2.scala +neg/t3816.scala +neg/tailrec.scala +neg/volatile.scala +neg/t944.scala +neg/t1705.scala +neg/t3977.scala +neg/t5553_2.scala +neg/t5318c.scala +neg/overload-msg.scala +neg/t5440.scala +neg/t6335.scala +neg/compile-time-only-b.scala +neg/t501.scala +neg/override.scala +neg/t663.scala +neg/t5892.scala +neg/t1980.scala +neg/macro-false-deprecation-warning +neg/t585.scala +neg/t3776.scala +neg/interop_classtags_arenot_manifests.scala +neg/t4044.scala +neg/macro-invalidusage-nontypeable +neg/t500.scala +neg/t4877.scala +neg/t5357.scala +neg/interop_abstypetags_arenot_manifests.scala +neg/t4460a.scala +neg/t5318b.scala +neg/t4440.scala +neg/t6663.scala +neg/t6357.scala +neg/gadts1.scala +neg/cyclics.scala +neg/t5060.scala +neg/scopes.scala +run/t4013.scala +run/macro-expand-tparams-explicit +run/tuples.scala +run/t5753_2 +run/t0528.scala +run/t5105.scala +run/t7341.scala +run/t3670.scala +run/t2594_tcpoly.scala +run/t3895.scala +run/t0668.scala +run/slices.scala +run/t6666a.scala +run/valueclasses-classmanifest-generic.scala +run/t2316_run.scala +run/t3004.scala +run/viewtest.scala +run/t6481.scala +run/t0005.scala +run/t4766.scala +run/t5500b.scala +run/t7407b.scala +run/backreferences.scala +run/arrayview.scala +run/t629.scala +run/t5903c +run/unittest_collection.scala +run/spec-nlreturn.scala +run/macro-term-declared-in-object-object +run/triple-quoted-expr.scala +run/t5937.scala +run/t6011c.scala +run/macro-expand-implicit-argument +run/try.scala +run/t1987b +run/t6089.scala +run/macro-range +run/t2524.scala +run/t4770.scala +run/virtpatmat_unapplyprod.scala +run/t1535.scala +run/ctor-order.scala +pos/t5210.scala +pos/t5384.scala +pos/rangepos.scala +pos/t443.scala +pos/t1480.scala +pos/t116.scala +pos/seqtest2.scala +pos/scoping1.scala +pos/t4269.scala +pos/lookupswitch.scala +pos/t3642 +pos/t5706.scala +pos/t7264 +pos/t0031.scala +pos/macro-deprecate-dont-touch-backquotedidents.scala +pos/t6815.scala +pos/test4refine.scala +pos/michel5.scala +pos/t0851.scala +pos/t1185.scala +pos/sudoku.scala +pos/t7520.scala +pos/t6208.scala +pos/t3411.scala +pos/t295.scala +pos/S3.scala +pos/t0674.scala +pos/t6664b.scala +pos/variances_pos.scala +pos/liftcode_polymorphic.scala +pos/t3174b.scala +pos/t7232d +pos/t578.scala +pos/implicit-infix-ops.scala +pos/t4363.scala +pos/t532.scala +pos/exponential-spec.scala +pos/t599.scala +pos/t5862.scala +pos/t4603 +pos/t3676.scala +pos/t1357.scala +pos/native-warning.scala +pos/t1230 +pos/t6028 +pos/t4275.scala +pos/overloaded_extractor_and_regular_def.scala +pos/t4205 +pos/matthias1.scala +pos/testcast.scala +pos/generic-sigs.scala +pos/t0093.scala +pos/specializes-sym-crash.scala +pos/t0061.scala +pos/t2429.scala +pos/t694.scala +pos/javaReadsSigs +pos/t2023.scala +pos/t704.scala +pos/t2208_pos.scala +pos/t5137.scala +pos/t2683.scala +pos/t0049.scala +pos/t1029 +pos/t4243.scala +pos/typerep-stephane.scala +pos/t177.scala +pos/t5967.scala +pos/t430.scala +pos/virtpatmat_infer_single_1.scala +pos/pat_iuli.scala +pos/t1071.scala +pos/t7226.scala +pos/t1843.scala +pos/t419.scala +pos/t7364b +pos/t1159.scala +pos/t5305.scala +pos/t7694.scala +pos/t6047.scala +pos/t3578.scala +pos/t2082.scala +pos/setter-not-implicit.scala +pos/t1133.scala +pos/t3862.scala +pos/t942 +pos/nothing_manifest_disambig-new.scala +pos/iterator-traversable-mix.scala +pos/eta.scala +pos/test4.scala +pos/t2691.scala +pos/t4502.scala +pos/t7183.scala +pos/protected-t1010.scala +pos/X.scala +pos/virtpatmat_exist2.scala +pos/t4911.scala +pos/t3477.scala +pos/t4173.scala +pos/t7782.scala +pos/t2399.scala +pos/virtpatmat_alts_subst.scala +pos/propagate.scala +pos/t2421b_pos.scala +pos/t183.scala +pos/t7033.scala +pos/t3612.scala +pos/t5330c.scala +pos/t3020.scala +pos/t4869.scala +pos/t3373.scala +pos/spec-params-new.scala +pos/t3672.scala +pos/t4501.scala +pos/t1565.scala +pos/t3774.scala +pos/t6942 +pos/t845.scala +pos/t3240.scala + +neg/t3275.scala +neg/t421.scala +neg/t5702-neg-bad-brace.scala +neg/t3663 +neg/badtok-1.scala +neg/t677.scala +neg/t7756b.scala +neg/t6534.scala +neg/t6276.scala +neg/t5762.scala +neg/abstract.scala +neg/t2405.scala +neg/t0418.scala +neg/t5390c.scala +neg/lazyvals.scala +neg/lubs.scala +neg/abstract-report.scala +neg/t4163.scala +neg/t5702-neg-bad-and-wild.scala +neg/macro-invalidret +neg/t6728.scala +neg/t5152.scala +neg/t1432.scala +neg/abstract-inaccessible.scala +neg/import-precedence.scala +neg/t2462b.scala +neg/macro-invalidusage-presuper +neg/specification-scopes +neg/t6048.scala +neg/t4079 +neg/macro-basic-mamdmi +neg/t7020.scala +neg/t3015.scala +neg/t0207.scala +neg/t2296b +neg/t0673 +neg/t3761-overload-byname.scala +neg/t6675.scala +neg/t5529.scala +neg/sensitive.scala +neg/t742.scala +neg/t5067.scala +neg/t6162-overriding.scala +neg/variances.scala +neg/t5728.scala +neg/t6323a.scala +neg/compile-time-only-a.scala +neg/t6795.scala +neg/t2494.scala +neg/t3649.scala +neg/macro-invalidsig +neg/t2796.scala +neg/t112706A.scala +neg/t0764.scala +neg/t3757 +neg/t1431.scala +neg/exhausting.scala +neg/t1523.scala +neg/t779.scala +neg/xmltruncated1.scala +neg/t2208.scala +neg/t2078.scala +neg/t521.scala +neg/null-unsoundness.scala +neg/stmt-expr-discard.scala +neg/t0513.scala +neg/unchecked-abstract.scala +neg/t4460c.scala +neg/divergent-implicit.scala +neg/t5078.scala +neg/t1701.scala +neg/t0816.scala +neg/t1672b.scala +neg/macro-invalidusage-badbounds +neg/tailrec-2.scala +neg/t4064.scala +neg/t5510.scala +neg/t3873.scala +neg/tailrec-3.scala +neg/t0226.scala +neg/t2031.scala +neg/t633.scala +neg/constrs.scala +neg/anyval-anyref-parent.scala +neg/t7290.scala +neg/t1041.scala +neg/patternalts.scala +neg/error_tooManyArgsPattern.scala +neg/checksensibleUnit.scala +neg/t6539 +neg/t4417.scala +neg/wellkinded_app.scala +neg/for-comprehension-old.scala +neg/t2779.scala +neg/object-not-a-value.scala +neg/t2968b.scala +neg/t6483.scala +neg/t6902.scala +neg/t6963a.scala +neg/t3399.scala +neg/t0015.scala +neg/t3995.scala +neg/t276.scala +neg/t6758.scala +neg/t2441.scala +neg/cycle-bounds.scala +neg/t1241.scala +neg/t4137.scala +neg/unicode-unterminated-quote.scala +neg/t4762.scala +neg/typeerror.scala +neg/implicits.scala +neg/t961.scala +neg/ambiguous-float-dots2.scala +neg/t2416.scala +neg/t5799.scala +neg/t7285.scala +neg/implicit-shadow.scala +neg/t2388.scala +neg/java-access-neg +neg/found-req-variance.scala +neg/hk-bad-bounds.scala +neg/t3224.scala +neg/t1033.scala +neg/t7385.scala +neg/t5882.scala +neg/t4541.scala +neg/t2973.scala +neg/t6406-regextract.scala +neg/t6666.scala +neg/t4831.scala +neg/t425.scala +neg/t1845.scala +neg/t3683b.scala +neg/t2801.scala +neg/t6083.scala +neg/t0528neg.scala +neg/stringinterpolation_macro-neg.scala +neg/t668.scala +neg/t5666.scala +neg/t4271.scala +neg/interop_typetags_arenot_classmanifests.scala +neg/t1355.scala +neg/t715.scala +neg/t7238.scala +neg/t7473.scala +neg/t7292-removal.scala +neg/tcpoly_infer_ticket1162.scala +neg/t4098.scala +neg/t6013 +neg/t6227.scala +neg/t464-neg.scala +neg/badtok-3.scala +neg/t6082.scala +neg/anytrait.scala +neg/valueclasses-doubledefs.scala +neg/t7519.scala +neg/overloaded-unapply.scala +neg/t1163.scala +neg/wellkinded_bounds.scala +neg/t7292-deprecation.scala +neg/t5044.scala +neg/t0842.scala +neg/t6436.scala +neg/interop_typetags_arenot_classtags.scala +neg/t3653.scala +neg/higherkind_novalue.scala +neg/t935.scala +neg/t6040.scala +neg/annot-nonconst.scala +neg/macro-deprecate-idents.scala +neg/illegal-stmt-start.scala +neg/t565.scala +neg/case-collision.scala +neg/t3209.scala +neg/t5821.scala +neg/abstract-class-2.scala +neg/t846.scala +neg/quasiquotes-syntax-error-position.scala +neg/t3987.scala +neg/t877.scala +neg/t0117.scala +neg/t692.scala +neg/t5702-neg-ugly-xbrace.scala +neg/t7752.scala +neg/t6526.scala +neg/t2213.scala +neg/t7756a.scala +neg/macro-override-macro-overrides-abstract-method-a +neg/tcpoly_ticket2101.scala +neg/delayed-init-ref.scala +neg/caseinherit.scala +neg/t3189.scala +neg/unchecked-suppress.scala +neg/t2180.scala +neg/t1371.scala +neg/macro-cyclic +neg/t6123-explaintypes-macros +neg/t4134.scala +neg/t691.scala +neg/t2421b.scala +neg/t4691_exhaust_extractor.scala +neg/t4419.scala +neg/t5801.scala +neg/t650.scala +neg/t5735.scala +neg/t696.scala +neg/t882.scala +neg/t2968.scala +neg/t7507.scala +neg/macro-invalidusage-badargs +neg/macro-reify-typetag-typeparams-notags +neg/wellkinded_app2.scala +neg/t4425b.scala +neg/t2296a +neg/t1878.scala +neg/t649.scala +neg/override-object-no.scala +neg/t4174.scala +neg/t2070.scala +neg/sabin2.scala +neg/t5903e +neg/t6566a.scala +neg/finitary-error.scala +neg/t4818.scala +neg/t3614.scala +neg/t6666c.scala +neg/ticket513.scala +neg/suggest-similar.scala +neg/t4457_1.scala +neg/t6666e.scala +neg/tcpoly_bounds.scala +neg/t4727.scala +neg/t4425.scala +neg/macro-invalidusage-methodvaluesyntax +neg/t3854.scala +neg/t3006.scala +neg/t5580b.scala +neg/t5378.scala +neg/t639.scala +neg/wrong-args-for-none.scala +neg/t7171b.scala +neg/t5361.scala +neg/unreachablechar.scala +neg/t5572.scala +neg/t7757a.scala +neg/macro-invalidimpl +neg/t2773.scala +neg/t6359.scala +neg/saito.scala +neg/xmltruncated2.scala +neg/t667.scala +neg/t3934.scala +neg/t6771b.scala +neg/t4584.scala +neg/wellkinded_wrongarity2.scala +neg/t7369.scala +neg/t1477.scala +neg/t5617.scala +neg/t7299.scala +neg/faculty.scala +neg/virtpatmat_reach_null.scala +neg/macro-reify-typetag-hktypeparams-notags +neg/t1224.scala +neg/xmltruncated3.scala +neg/t1872.scala +neg/t558.scala +neg/t7110.scala +neg/any-vs-anyref.scala +neg/t6340.scala +neg/t4166.scala +neg/t2918.scala +neg/t5856.scala +neg/t4989.scala +neg/t0003.scala +neg/t1183.scala +neg/t963.scala +neg/t4515.scala +neg/valueclasses-pavlov.scala +neg/t608.scala +neg/choices.scala +neg/patmat-type-check.scala +neg/valueclasses-impl-restrictions.scala +neg/imp2.scala +neg/protected-constructors.scala +neg/t6788.scala +neg/nullary-override.scala +neg/t200.scala +neg/t343.scala +neg/names-defaults-neg-ref.scala +neg/tcpoly_typealias.scala +neg/classtags_contextbound_b.scala +neg/t729.scala +neg/t5683.scala +neg/t4928.scala +neg/t700.scala +neg/t7669.scala +neg/macro-invalidshape +neg/t6011.scala +neg/t7325.scala +neg/check-dead.scala +neg/t550.scala +neg/t5663-badwarneq.scala +neg/t0699 +neg/nopredefs.scala +neg/t3507-old.scala +neg/t5352.scala +neg/t6336.scala +neg/interop_classmanifests_arenot_typetags.scala +neg/sealed-final-neg.scala +neg/t2102.scala +neg/t7636.scala +neg/t5031b +neg/t798.scala +neg/t5702-neg-bad-xbrace.scala +neg/t0899.scala +neg/cyclics-import.scala +neg/badtok-2.scala +neg/t473.scala +neg/t3160ambiguous.scala +neg/t5106.scala +neg/t1286 +neg/macro-override-macro-overrides-abstract-method-b +neg/t0259.scala +neg/t510.scala +neg/t3836.scala +neg/t5830.scala +neg/t1548 +neg/t5580a.scala +neg/forward.scala +neg/t591.scala +neg/t6558b.scala +neg/t556.scala +neg/xmltruncated4.scala +neg/t5497.scala +neg/t409.scala +neg/t6283.scala +neg/override-object-flag.scala +neg/constructor-prefix-error.scala +neg/eta-expand-star.scala +neg/t3392.scala +neg/t1275.scala +neg/nested-fn-print.scala +neg/t7330.scala +neg/t2275a.scala +neg/t630.scala +neg/t4270.scala +neg/t2775.scala +neg/pat_unreachable.scala +neg/t4158.scala +neg/unit-returns-value.scala +neg/t1422.scala +neg/reify_metalevel_breach_-1_refers_to_0_b.scala +neg/reassignment.scala +neg/t3683a.scala +neg/noMember1.scala +neg/macro-without-xmacros-b +neg/t1106.scala +neg/t5182.scala +neg/t6889.scala +neg/t4217.scala +neg/t7501 +neg/t5063.scala +neg/t1009.scala +neg/t997.scala +neg/unchecked.scala +neg/classtags_contextbound_c.scala +neg/applydynamic_sip.scala +neg/t7715.scala +neg/t588.scala +neg/t6667b.scala +neg/t7757b.scala +neg/t4069.scala +neg/t515.scala +neg/variances2.scala +neg/t1049.scala +neg/t7289.scala +neg/t1623.scala +neg/permanent-blindness.scala +neg/t5803.scala +neg/super-cast-or-test.scala +neg/nonlocal-warning.scala +neg/t5687.scala +neg/t5903a +neg/t6566b.scala +neg/unchecked-knowable.scala +neg/t5093.scala +neg/protected-static-fail +neg/type-diagnostics.scala +neg/forgot-interpolator.scala +neg/interop_abstypetags_arenot_classmanifests.scala +neg/t5376.scala +neg/t545.scala +neg/xmlcorner.scala +neg/switch.scala +neg/depmet_1.scala +neg/abstract-concrete-methods.scala +neg/t4987.scala +neg/t5452-new.scala +neg/t750b +neg/unchecked-refinement.scala +neg/t418.scala +neg/t5354.scala +neg/t3736.scala +neg/t631.scala +neg/t6829.scala +neg/t0218.scala +neg/volatile-intersection.scala +neg/t412.scala +neg/t693.scala +neg/t4882.scala +neg/t1960.scala +neg/macro-divergence-controlled +neg/t712.scala +neg/t5544 +neg/t3222.scala +neg/t3604.scala +neg/t1112.scala +neg/t7157 +neg/accesses.scala +neg/t452.scala +neg/t6162-inheritance +neg/t2442 +neg/t6567.scala +neg/lazy-override.scala +neg/abstract-explaintypes.scala +neg/nested-annotation.scala +neg/t5753 +neg/t3691.scala +neg/infix-op-positions.scala +neg/t3403.scala +neg/t4851 +neg/structural.scala +neg/error_dependentMethodTpeConversionToFunction.scala +neg/t5839.scala +neg/t5553_1.scala +neg/reify_metalevel_breach_+0_refers_to_1.scala +neg/t752.scala +neg/t6574.scala +neg/t3714-neg.scala +neg/t4457_2.scala +neg/t2148.scala +neg/t1364.scala +neg/saferJavaConversions.scala +neg/t414.scala +neg/t5493.scala +neg/classtags_contextbound_a.scala +neg/reify_metalevel_breach_-1_refers_to_0_a.scala +neg/t3118.scala +neg/t512.scala +neg/t2336.scala +neg/t856.scala +neg/xmltruncated6.scala +neg/t2206.scala +neg/virtpatmat_unreach_select.scala +neg/t6258.scala +neg/t6815.scala +neg/not-possible-cause.scala +neg/dbldef.scala +neg/qualifying-class-error-1.scala +neg/t835.scala +neg/t5455.scala +neg/t6558.scala +neg/t708.scala +neg/macro-nontypeablebody +neg/t0565.scala +neg/xmltruncated5.scala +neg/t5390d.scala +neg/t520.scala +neg/t6138.scala +neg/macro-without-xmacros-a +neg/t7214neg.scala +neg/t2870.scala +neg/t593.scala +neg/t4541b.scala +neg/t4460b.scala +neg/t284.scala +neg/t2488.scala +neg/macro-override-method-overrides-macro +neg/interop_abstypetags_arenot_classtags.scala +neg/t3769.scala +neg/warn-inferred-any.scala +neg/t664.scala +neg/t5903d +neg/t562.scala +neg/t2316.scala +neg/t0152.scala +neg/migration28.scala +neg/t6443c.scala +neg/tcpoly_override.scala +neg/t7324.scala +neg/t987.scala +neg/t5903b +neg/t3481.scala +neg/t6912.scala +neg/tcpoly_variance_enforce.scala +neg/t3913.scala +neg/names-defaults-neg.scala +neg/t765.scala +neg/t5358.scala +neg/t391.scala +neg/serialversionuid-not-const.scala +neg/t771.scala +neg/t0903.scala +neg/catch-all.scala +neg/classmanifests_new_deprecations.scala +neg/t0606.scala +neg/t5189_inferred.scala +neg/macro-reify-typetag-useabstypetag +neg/t5543.scala +neg/logImplicits.scala +neg/interop_typetags_without_classtags_arenot_manifests.scala +neg/t6535.scala +neg/t7259.scala +neg/t2139.scala +neg/t278.scala +neg/t5564.scala +neg/unchecked3.scala +neg/virtpatmat_reach_sealed_unsealed.scala +neg/checksensible.scala +neg/t7721.scala +run/t3798.scala +run/macro-expand-varargs-explicit-over-varargs +run/t3888.scala +run/t0677-new.scala +run/t3273.scala +run/t3763.scala +run/t2755.scala +run/t920.scala +run/t5610a.scala +run/literals.scala +run/proxy.scala +run/unapply.scala +run/t5830.scala +run/array-addition.scala +run/macro-expand-nullary-nongeneric +run/macro-basic-ma-mdmi +run/valueclasses-constr.scala +run/t1247.scala +run/t3487.scala +run/rawstrings.scala +run/patmat-seqs.scala +run/eta-expand-star.scala +run/t7436.scala +run/t3996.scala +run/constructors.scala +run/t498.scala +run/t3835.scala +run/t298.scala +run/t2867.scala +run/t7120 +run/virtpatmat_literal.scala +run/t2175.scala +run/t2503.scala +run/t3026.scala +run/t603.scala +run/t0091.scala +run/t6394a +run/macro-expand-varargs-implicit-over-varargs +run/t7407.scala +run/t2552.scala +run/virtpatmat_npe.scala +run/macro-sip19 +run/t6644.scala +run/t6614.scala +run/t2005.scala +run/t4680.scala +run/t5903a +run/classtags_contextbound.scala +run/Course-2002-05.scala +run/applydynamic_sip.scala +run/t1766.scala +run/retsynch.scala +run/t7715.scala +run/t102.scala +run/nonlocalreturn.scala +run/macro-reify-staticXXX +run/Course-2002-06.scala +run/t6863.scala +run/t6500.scala +run/macro-impl-rename-context +run/t4351.scala +run/t5009.scala +run/macro-term-declared-in-annotation +run/t6271.scala +run/array-existential-bound.scala +run/t6443b.scala +run/t1987.scala +run/MutableListTest.scala +run/t7571.scala +run/t5488-fn.scala +run/macro-bodyexpandstoimpl +run/macro-reify-ref-to-packageless +run/t2212.scala +run/macro-expand-varargs-implicit-over-nonvarargs +run/t0807.scala +run/patmat-behavior.scala +run/t2446.scala +run/breakout.scala +run/t4122.scala +run/macro-settings +run/t7157 +run/t1323.scala +run/t4013b.scala +run/t6309.scala +run/t4047.scala +run/t5544 +run/t978.scala +run/t3361.scala +run/t6611.scala +run/t5387.scala +run/t5656.scala +run/t4897.scala +run/numeric-range.scala +run/t4777.scala +run/Course-2002-03.scala +run/string-extractor.scala +run/view-headoption.scala +run/patmat_unapp_abstype-new.scala +run/stream-stack-overflow-filter-map.scala +run/macro-impl-tparam-only-in-impl +run/t6559.scala +run/macro-reify-tagful-a +run/macro-expand-multiple-arglists +run/t4709.scala +run/t3509.scala +run/t5284b.scala +run/t7617b +run/t3923.scala +run/virtpatmat_apply.scala +run/t363.scala +run/manifests-undeprecated-in-2.10.0.scala +run/matchintasany.scala +run/t3970.scala +run/t4996.scala +run/t5530.scala +run/macro-term-declared-in-object-class +run/t3242b.scala +run/indexedSeq-apply.scala +run/t107.scala +run/t2337.scala +run/t2754.scala +run/flat-flat-flat.scala +run/t6673.scala +run/interpolationMultiline2.scala +run/t0631.scala +run/t2800.scala +run/t6506.scala +run/t6260.scala +run/t2418.scala +run/t4415.scala +run/classmanifests_new_alias.scala +run/t5380.scala +run/tcpoly_parseridioms.scala +run/t1747.scala +run/t5903d +run/t3530.scala +run/t216.scala +run/macro-term-declared-in-refinement +run/t4592.scala +run/t2488.scala +run/t3327.scala +run/t5614.scala +run/t5903b +run/iterables.scala +run/t3964.scala +run/t6329_vanilla.scala +run/t3038c +run/t1697.scala +run/t2030.scala +run/t3397.scala +run/t1005.scala +run/t3353.scala +run/t1466.scala +run/t3186.scala +run/tcpoly_overriding.scala +run/t5394.scala +run/t5284.scala +run/unboxingBug.scala +run/t7200.scala +run/macro-reify-basic +run/t153.scala +run/iterator3444.scala +run/macro-expand-implicit-macro-is-val +run/macro-basic-ma-md-mi +run/interpolationArgs.scala +run/t4954.scala +run/t3645.scala +run/transpose.scala +run/t3887.scala +run/t4288.scala +run/unittest_iterator.scala +run/t5543.scala +run/macro-term-declared-in-object +run/iq.scala +run/t2788.scala +run/t2027.scala +run/macro-expand-recursive +run/t949.scala +run/t1909b.scala +run/delambdafy-nested-by-name.scala +run/delambdafy-two-lambdas.scala +run/macro-blackbox-materialization +run/lists-run.scala +run/macro-parse-position +run/macro-parse-position-malformed +run/macro-whitebox-dynamic-materialization +run/macro-whitebox-extractor +run/macro-vampire-false-warning +run/macro-whitebox-fundep-materialization +run/macro-whitebox-structural +run/mutable-treeset.scala +run/static-module-method.scala +run/sort.scala +run/t1909.scala +run/t1909c.scala +run/t3346a.scala +run/t3346d.scala +run/t3346f.scala +run/t3346h.scala +run/t3346g.scala +run/t3832.scala +run/t4742.scala +run/t5377.scala +run/t5923c.scala +run/t6188.scala +run/t6333.scala +run/t6385.scala +run/t7899.scala +run/t7584b.scala +run/t7223.scala +run/t7859 +run/t7868.scala +run/t7871 +run/arrayclone-new.scala +run/arrayclone-old.scala +run/bitsets.scala +run/comparable-comparator.scala +run/colltest1.scala +run/t2106.scala +run/t5986.scala +run/view-iterator-stream.scala +run/array-charSeq.scala +pos/signatures +pos/t1263 +pos/t3249 +neg/t4749.scala +neg/main1.scala +neg/t7251 +neg/t7494-after-terminal +neg/t7494-before-parser +neg/t7494-right-after-terminal +run/lazy-traits.scala +run/OrderingTest.scala +run/ReplacementMatching.scala +run/patmat-finally.scala +run/t3158.scala +run/t3346e.scala +run/t4398.scala +run/t4930.scala +run/t6534.scala +pos/sammy_scope.scala +pos/delambdafy-patterns.scala +pos/private-types-after-typer.scala +pos/delambdafy-lambdalift.scala +pos/sammy_poly.scala +pos/sammy_single.scala +pos/sammy_twice.scala +pos/t3160.scala +pos/t1014.scala +pos/t4970b.scala +pos/t2698.scala +pos/t5845.scala +pos/t6201.scala +pos/t6260a.scala +pos/t7688.scala +pos/t7818.scala +pos/t1203a.scala +pos/t7834.scala +pos/t7853.scala +pos/t7815.scala +pos/t7853-partial-function.scala +pos/t7864.scala +pos/t7928.scala +pos/t7902.scala +pos/t7944.scala +pos/t7847 +neg/accesses2.scala +neg/bad-advice.scala +neg/gadts2.scala +neg/gadts2-strict.scala +neg/macro-bundle-abstract.scala +neg/macro-bundle-object.scala +neg/macro-bundle-trait.scala +neg/macro-blackbox-dynamic-materialization +neg/macro-blackbox-extractor +neg/run-gadts-strict.scala +neg/macro-blackbox-structural +neg/sammy_restrictions.scala +neg/sammy_wrong_arity.scala +neg/t2462c.scala +neg/t3346b.scala +neg/t1909-object.scala +neg/macro-blackbox-fundep-materialization +neg/t3346c.scala +neg/t3871.scala +neg/t3871b.scala +neg/t3971.scala +neg/t3346i.scala +neg/t6120.scala +neg/t6260c.scala +neg/t6680a.scala +neg/t7239.scala +neg/t7007.scala +neg/t7605-deprecation.scala +neg/t7622-missing-required.scala +neg/t7629-view-bounds-deprecation.scala +neg/t7834neg.scala +neg/t7783.scala +neg/t7848-interp-warn.scala +neg/t7519-b +neg/t7622-missing-dependency +neg/t7870.scala +neg/t7877.scala +neg/t7895.scala +neg/t7895b.scala +neg/t7899.scala +neg/t7895c.scala +neg/t7859 +run/t4752.scala +run/t2087-and-2400.scala +run/t3855.scala +run/t6637.scala +run/t6731.scala +pos/t3999b.scala +run/t0432.scala +run/t2514.scala +run/t7817.scala +run/t874.scala +run/type-currying.scala +run/t3616.scala +run/t3687.scala +run/t4570.scala +run/t5612.scala +run/t1110.scala +run/t2636.scala +run/verify-ctor.scala +run/t3647.scala +run/t4560.scala +run/t6632.scala +run/richs.scala +run/t6725-1.scala +pos/t7776.scala +run/fors.scala +run/t6706.scala +run/t3175.scala +run/delambdafy-dependent-on-param-subst.scala +run/t4332b.scala +run/t8048a +run/t8017 +run/t7985b.scala +run/t8100.scala +run/patmat-mix-case-extractor.scala +run/t4750.scala +run/t7912.scala +run/delambdafy-dependent-on-param-subst-2.scala +run/t8048b +run/t8091.scala +run/macroPlugins-macroRuntime +run/macro-default-params +run/t6355.scala +run/t7777 +run/t8002.scala +run/t8015-ffc.scala +run/macro-subpatterns +run/t7985.scala +run/macroPlugins-macroArgs +run/t7326.scala +run/t5045.scala +run/value-class-partial-func-depmet.scala +run/t6329_vanilla_bug.scala +run/macroPlugins-macroExpand +run/t8010.scala +run/macroPlugins-typedMacroBody +run/t7406.scala +pos/t8146a.scala +pos/t8046c.scala +pos/t8132.scala +pos/t8045.scala +pos/overzealous-assert-genbcode.scala +pos/t8128.scala +pos/t8013 +pos/t8064b +pos/t6780.scala +pos/t7987 +pos/bcode_throw_null +pos/t8064 +pos/t8046.scala +pos/t6231.scala +pos/t7983.scala +pos/t5508.scala +pos/t5508-min.scala +pos/t8023b.scala +pos/t6231b.scala +pos/debug-reset-local-attrs.scala +pos/t8054.scala +pos/t2066.scala +pos/dotless-targs.scala +pos/t8120.scala +pos/t5508-min-okay.scala +pos/t8060.scala +pos/t8001 +pos/t8138.scala +pos/t8111.scala +pos/t8011.scala +pos/t8146b.scala +pos/t8046b.scala +pos/t8023.scala +pos/t5508-min-okay2.scala +pos/macro-implicit-invalidate-on-error.scala +neg/t6563.scala +neg/missing-param-type-tuple.scala +neg/not-a-legal-formal-parameter-tuple.scala +neg/t7897.scala +neg/t8015-ffa.scala +neg/quasiquotes-unliftable-not-found.scala +neg/t2066b.scala +neg/dotless-targs.scala +neg/patmat-classtag-compound.scala +neg/t2066.scala +neg/t8035-deprecated.scala +neg/t6675b.scala +neg/t8104 +neg/t7872.scala +neg/t7850.scala +neg/t7967.scala +neg/macro-bundle-overloaded.scala +neg/t6355a.scala +neg/class-of-double-targs.scala +neg/t6355b.scala +neg/macro-reify-splice-splice +neg/macro-bundle-noncontext.scala +neg/t8015-ffb.scala +neg/t8035-removed.scala +neg/t7984.scala +neg/t8024.scala +neg/t8024b.scala +neg/t8157.scala +neg/t8146-non-finitary-2.scala +neg/t8006.scala +neg/t7872c.scala +neg/t8146-non-finitary.scala +neg/t7872b.scala +neg/t6920.scala +run/t6200.scala +run/t6196.scala +run/macro-bundle-context-refinement +run/macro-enclosingowner-detectvar +run/macro-enclosingowner-sbt +run/macro-bundle-context-alias +run/macro-bundle-whitebox-use-refined +run/macro-bundle-whitebox-use-raw +neg/name-lookup-stable.scala +neg/t0764b.scala +neg/no-implicit-to-anyref-any-val.scala +neg/t1503.scala +neg/t4728.scala +neg/t6455.scala +neg/t6260-named.scala +neg/t6844.scala +neg/t7475c.scala +neg/t7475e.scala +neg/t7475f.scala +neg/macro-bundle-whitebox-use-raw +neg/macro-bundle-whitebox-use-refined +neg/macro-incompatible-macro-engine-b +neg/t7980.scala +neg/macro-incompatible-macro-engine-a +neg/t8143a.scala +neg/t8072.scala +neg/t8207.scala +neg/t8182.scala +neg/t8219-any-any-ref-equals.scala +neg/t8177a.scala +neg/t8228.scala +neg/t8229.scala +neg/t8237-default.scala +neg/t8244b.scala +neg/t8244e +neg/t8244c.scala +neg/t8265.scala +neg/t8266-invalid-interp.scala +neg/t6931 +neg/t8376 +neg/t8372.scala +neg/t8300-overloading.scala +neg/t8244 +neg/t8158 +neg/t8431.scala +pos/implicit-anyval-2.10.scala +pos/delambdafy_t6260_method.scala +pos/macro-bundle-disambiguate-bundle.scala +pos/macro-bundle-disambiguate-nonbundle.scala +pos/package-ob-case +pos/t1786-counter.scala +pos/reflection-compat-api-universe.scala +pos/existential-java-case-class +pos/t1786-cycle.scala +pos/reflection-compat-c.scala +pos/t3452f.scala +pos/reflection-compat-ru.scala +pos/t2066-2.10-compat.scala +pos/reflection-compat-macro-universe.scala +pos/t5900a.scala +pos/t5760-pkgobj-warn +pos/t5954a +pos/t5954b +pos/t5954d +pos/t6260.scala +pos/t5165b +pos/t5954c +pos/t6260b.scala +pos/t7475b.scala +pos/t7475a.scala +pos/t7753.scala +pos/t7322.scala +pos/t6948.scala +pos/t7475d.scala +pos/t7475e.scala +pos/t6169 +pos/t7788.scala +pos/t7919.scala +pos/t8177a.scala +pos/t8177.scala +pos/t8170.scala +pos/t8170b.scala +pos/t8177d.scala +pos/t8177b.scala +pos/t8177e.scala +pos/t8134 +pos/t8177h.scala +pos/t8177g.scala +pos/t8207.scala +pos/t8187.scala +pos/t8219.scala +pos/t8219b.scala +pos/t8224.scala +pos/t8237.scala +pos/t8223.scala +pos/t8237b.scala +pos/t8300-conversions-a.scala +pos/t8300-conversions-b.scala +pos/t8209a +pos/t8209b +pos/t8244d +pos/t8300-overloading.scala +pos/t8300-patmat-a.scala +pos/t8300-patmat-b.scala +pos/t8301.scala +pos/t8324.scala +pos/t8301b.scala +pos/t8363.scala +pos/t8367.scala +pos/t8369a.scala +pos/t8369b.scala +pos/t8403.scala +pos/t8364.scala +pos/t8352 +pos/t8376 +neg/macro-bundle-nonpublic-c.scala +neg/literate_existentials.scala +neg/macro-bundle-nonpublic-impl.scala +neg/macro-bundle-ambiguous.scala +neg/macro-bundle-priority-bundle.scala +neg/macro-bundle-need-qualifier.scala +neg/macro-bundle-nonstatic.scala +neg/macro-bundle-polymorphic.scala +neg/macro-bundle-priority-nonbundle.scala +neg/macro-bundle-wrongcontext-a.scala +neg/macro-bundle-wrongcontext-b.scala +run/t8425 +run/t8245.scala +run/t8266-octal-interp.scala +run/t8280.scala +run/t8395.scala +run/t8321 +run/t8153.scala +run/t8197.scala +run/t8197b.scala +run/t8233.scala +run/t8133 +run/t8133b +run/t7475b.scala +run/t6814 +run/t4577.scala +run/t5134.scala +run/t3452f.scala +run/t3452h.scala +run/t3452c.scala +run/t3452.scala +run/t261.scala +run/t3235-minimal.scala +run/t1503_future.scala +run/t5565.scala +pos/t8411 +pos/t8460.scala +run/t8428.scala +run/t8437 +run/absoverride.scala +run/arrays.scala +run/duration-coarsest.scala +run/iterator-from.scala +run/SymbolsTest.scala +run/t1074.scala +run/t1505.scala +run/streams.scala +run/t2111.scala +run/t4601.scala +neg/t3692-new.scala +run/t7015.scala +run/t7992b.scala +run/t7992.scala +run/t8570.scala +pos/t8157-2.10.scala +pos/t8325.scala +pos/t8523.scala +pos/t8578.scala +pos/t8329.scala +pos/t8497 +pos/t8546.scala +pos/t8531 +neg/t8325-c.scala +neg/t8325-b.scala +neg/t8325.scala +neg/t6988.scala +neg/t8463.scala +neg/t8450.scala +neg/t8430.scala +run/finally.scala +neg/t8630.scala +neg/t8035-no-adapted-args.scala +neg/t8675b.scala +neg/t8610-arg.scala +neg/t8736-c.scala +neg/tailrec-4.scala +neg/double-def-top-level +neg/t8610.scala +neg/aladdin1055 +neg/virtpatmat_exhaust_compound.scala +neg/t8675.scala +neg/t8525.scala +pos/t8736.scala +pos/t8625.scala +pos/t8596.scala +pos/t8617.scala +pos/t8736-b.scala +pos/t8708 +pos/macro-attachments +run/t8611a.scala +run/t8738.scala +run/macro-rangepos-args +run/t8610.scala +run/macro-rangepos-subpatterns +run/t8611c.scala +run/macroPlugins-isBlackbox +run/t8601d.scala +run/t8607.scala +run/bugs.scala +run/t1503.scala +run/t4148.scala +run/t7763.scala +run/issue192.scala +run/t8893b.scala +run/t8845.scala +run/t8933 +run/t7459c.scala +run/t9003.scala +run/t7459f.scala +run/t8933c.scala +run/t1994.scala +run/t2866.scala +run/t5665.scala +run/t7459d.scala +run/t8933b +run/t8888.scala +run/t7459b-optimize.scala +run/t7459a.scala +run/t7019.scala +run/t8893.scala +run/t8803.scala +run/t7459b.scala +run/t8823.scala +run/t6541.scala +run/nothingTypeDce.scala +run/t8680.scala +run/t8925.scala +run/nothingTypeNoOpt.scala +run/t9030.scala +run/bigDecimalTest.scala +run/bigDecimalCache.scala +run/range.scala +run/t6064.scala +run/t7521 +run/t8710.scala +run/t8575.scala +run/t8944 +run/t8944b.scala +run/t9387.scala +run/t9387b.scala +pos/t7784.scala +pos/t8862a.scala +pos/t9074.scala +pos/t8462.scala +pos/t8862b.scala +pos/alladin763.scala +pos/t6778.scala +pos/t9074b.scala +pos/t9326a.scala +pos/t9131.scala +pos/t9393 +pos/t9392 +neg/missing-arg-list.scala +neg/deprecated-target.scala +neg/t6895.scala +neg/beanInfoDeprecation.scala +neg/t8777.scala +neg/t6895b.scala +neg/t8892.scala +neg/t8849.scala +neg/inlineIndyLambdaPrivate +run/t9029.scala +run/t7850c.scala +run/t7850d.scala +run/t8334.scala +run/t9029c.scala +run/t9029b.scala +run/t9422.scala +run/t9425.scala +pos/t9475.scala +pos/t9498.scala +pos/t9479.scala +pos/t9479b.scala +pos/t9442.scala +pos/t9369.scala +pos/t6666d.scala +pos/t9370 +neg/t6810.scala +neg/t8127a.scala +neg/t8989.scala +neg/t9401.scala +neg/implicit-ambiguous.scala +neg/implicit-ambiguous-2.scala +neg/implicit-ambiguous-invalid.scala +neg/warn-unused-imports +run/t7269.scala +run/equality.scala +run/number-parsing.scala +run/t6220.scala +run/mapConserve.scala +run/colltest.scala +run/t0412.scala +run/t6261.scala +run/java-erasure.scala +run/t6197.scala +run/t4201.scala +run/t5608.scala +run/t3518.scala +run/t6198.scala +run/t2813.2.scala +pos/java-type-annotations +pos/sammy_infer_argtype_subtypes.scala +pos/sammy_ctor_arg.scala +pos/fun_undo_eta.scala +pos/sammy_inferargs.scala +pos/existental-slow-compile2.scala +pos/existential-slow-compile1.scala +pos/sammy_implicit.scala +pos/t9178b.scala +pos/t9449.scala +pos/t3234.scala +pos/t9542.scala +pos/t8429.scala +pos/t9658.scala +pos/t9630 +pos/t9399.scala +pos/t9411a.scala +pos/t9411b.scala +neg/partestInvalidFlag.scala +neg/sammy_error.scala +neg/sammy_disabled.scala +neg/sammy_overload.scala +neg/sammy_expected.scala +neg/t8700a +neg/t9527b.scala +neg/t9527a.scala +neg/t9572.scala +neg/t9535.scala +neg/t9629.scala +neg/optimiseDeprecated.scala +neg/t9398 +neg/outer-ref-checks.scala +neg/t8685.scala +neg/t8700b +run/t9349 +run/t9178a.scala +run/t9110.scala +run/sammy_cbn.scala +run/sammy_erasure_cce.scala +run/sammy_after_implicit_view.scala +run/sammy_restrictions_LMF.scala +run/sammy_vararg_cbn.scala +run/t7807.scala +run/sammy_return.scala +run/t9546.scala +run/t9546b.scala +run/lisp.scala +run/t9546c.scala +run/t9546d.scala +run/t9546e.scala +run/t9567.scala +run/t9567b.scala +run/trait-clonable.scala +run/t9567c.scala +run/trait-defaults-modules.scala +run/trait-defaults-modules3.scala +run/trait-defaults-modules2 +pos/functions.scala +pos/MailBox.scala +neg/t6289 +run/t6114.scala +pos/constant-warning.scala +pos/t2712-5.scala +pos/t2712-2.scala +pos/t2712-4.scala +pos/t2712-1.scala +pos/t2712-3.scala +pos/t2712-6.scala +pos/t6895b.scala +pos/t5683.scala +pos/hkgadt.scala +pos/t2712-7.scala +pos/t9245.scala +pos/t7088.scala +pos/t8044.scala +pos/t9665.scala +pos/t9397.scala +pos/t5183.scala +pos/t8449 +neg/t8044-b.scala +neg/t8044.scala +neg/t2712-3.scala +neg/t2712-2.scala +neg/t2712-1.scala +neg/t9045.scala +neg/t8667.scala +neg/t9361.scala +neg/t9781.scala +neg/trait-no-native.scala +neg/hkgadt.scala +neg/t9684b.scala +neg/t9382.scala +neg/trait-defaults-super.scala +neg/t9684.scala +run/hashCodeStatics.scala +run/t9390d.scala +run/trait-static-clash.scala +run/t5568.scala +run/t6318_primitives.scala +pos/fields_widen_trait_var.scala +pos/sammy_extends_function.scala +pos/infer_override_def_args.scala +pos/t482.scala +pos/t8079b.scala +pos/t6161b.scala +pos/t5294b.scala +pos/t5294c.scala +pos/overloaded_ho_fun.scala +pos/t4914.scala +pos/trait_fields_dependent_conflict.scala +pos/t2377b +pos/trait_fields_dependent_rebind.scala +pos/t9855b.scala +pos/trait_fields_inherit_double_def.scala +pos/t9855.scala +pos/t8873.scala +pos/trait_fields_nested_private_object.scala +pos/trait_fields_nested_public_object.scala +pos/trait_fields_private_this.scala +pos/trait_fields_var_override_deferred.scala +pos/trait_fields_static_fwd.scala +pos/trait_fields_owners.scala +pos/trait_fields_volatile.scala +pos/trait_lazy_accessboundary.scala +pos/trait_fields_lambdalift.scala +pos/typevar-in-prefix.scala +pos/val_infer.scala +pos/lub-from-hell.scala +neg/t8079a.scala +neg/sd128 +neg/t9849.scala +neg/trait_fields_var_override.scala +neg/val_infer.scala +neg/val_sig_infer_match.scala +neg/t7187.scala +neg/trait_fields_deprecated_overriding.scala +neg/t9847.scala +neg/val_sig_infer_struct.scala +neg/trait_fields_conflicts.scala +neg/lub-from-hell-2.scala +run/t2946 +run/lazy_local_labels.scala +run/sd167.scala +run/t9841.scala +run/trait-fields-override-lazy.scala +run/trait_fields_init.scala +run/trait_fields_three_layer_overrides.scala +run/t9516.scala +run/t10032.scala +pos/sam_erasure_boundedwild.scala +pos/t10154.scala +pos/t10066.scala +pos/t10154b.scala +pos/t10093.scala +pos/t8040.scala +pos/t3772.scala +pos/t10206.scala +pos/t9331.scala +pos/userdefined_apply_poly_overload.scala +pos/userdefined_apply.scala +pos/trailing-commas.scala +neg/t10097.scala +neg/t10068.scala +neg/ambiguous-same.scala +neg/maxerrs.scala +neg/maxwarns.scala +neg/t10207.scala +neg/t10066.scala +neg/t3236-neg +neg/t3772.scala +neg/t8704.scala +neg/t8002-nested-scope.scala +neg/t10097b.scala +neg/trailing-commas.scala +neg/t9834.scala +neg/userdefined_apply.scala +neg/t8417.scala +neg/warn-unused-implicits.scala +neg/t7860.scala +neg/t8763.scala +neg/t9636.scala +neg/warn-unused-params.scala +neg/t9675.scala +neg/warn-unused-patvars.scala +run/t10069.scala +run/SD-290.scala +run/sd329.scala +run/t10097.scala +run/t10072.scala +run/t10261 +run/t9114.scala +run/t10069b.scala +pos/t10205.scala +pos/t7100.scala +pos/t5788.scala +pos/t4012-b.scala +pos/t7638.scala +pos/t4012-a.scala +pos/dotless-targs-ranged.scala +neg/t5355.scala +neg/badtok-1-212.scala +neg/t6714.scala +neg/t10249 +run/macro-implicit-decorator +run/t10290.scala +run/t10298.scala +run/t10389.scala +run/t10423 +run/t6714.scala +run/t9146.scala +run/wacky-value-classes.scala +pos/t10088.scala +pos/t10213.scala +pos/t10195b.scala +pos/t10195.scala +pos/t10197.scala +pos/t10185.scala +pos/patmat-hk.scala +pos/t10159 +pos/t10372.scala +pos/t10238.scala +pos/t10288.scala +pos/t5818.scala +pos/t6895b-2.scala +pos/t10296-before +pos/warn-unused-params-not-implicits.scala +pos/t10296 +pos/t9122.scala +pos/t10270 +pos/t9647.scala +neg/t10279.scala +neg/hk-typevar-unification.scala +neg/t10260 +neg/names-defaults-neg-213.scala +neg/t6934 +neg/t9138.scala +neg/t7187-2.13.scala +neg/t10296-after +neg/t10296-warn +neg/t10270 +neg/t10296-both +run/implicit-caching.scala +run/abstype_implicits.scala +run/sd336.scala +run/hk-typevar-unification.scala +run/t10283.scala +run/t10291.scala +run/t10439.scala +run/t10454-1 +run/t10454-2 +run/t7187-2.13.scala +pos/t10406.scala +pos/parallel-classloader.scala +pos/t10375.scala +pos/t10623.scala +pos/t10643.scala +pos/t10394.scala +pos/t8343.scala +pos/t10763.scala +pos/t7420.scala +pos/t10568 +pos/t10684.scala +pos/t10667.scala +pos/t10644 +pos/t9155.scala +pos/t9220.scala +neg/badimport.scala +neg/t10474.scala +neg/string-context-refchecked.scala +neg/t10678.scala +neg/t10661.scala +neg/t10619.scala +neg/t10530.scala +neg/t10731.scala +neg/t10695.scala +neg/t10073.scala +neg/t10073b.scala +neg/case-collision-multifile +neg/implicitly-self.scala +neg/t10701 +run/t10551.scala +run/t10611.scala +run/t10646.scala +run/t10692.scala + +# Adapt checkfiles for (1.0).toString == "1" +run/Course-2002-01.scala +run/t0421-new.scala +run/runtime.scala +run/t0421-old.scala +run/spec-self.scala +run/t5552.scala +run/Course-2002-02.scala +run/Course-2002-04.scala +run/promotion.scala +run/t4617.scala +run/Course-2002-09.scala +run/t5866.scala +run/try-catch-unify.scala +run/impconvtimes.scala +run/Course-2002-10.scala +run/Course-2002-08.scala +run/MeterCaseClass.scala +run/Meter.scala +run/deeps.scala +run/caseClassHash.scala +run/interpolation.scala +run/interpolationMultiline1.scala +run/t9656.scala +pos/sd219.scala +pos/t9918 +pos/shapeless-regression.scala +pos/issue244.scala +pos/t9920.scala +pos/t9943.scala +neg/t5148.scala +run/sd242.scala +run/local_obj.scala +run/t9697.scala +run/t9920.scala +run/t9920c.scala +run/t9920d.scala +run/t9920b.scala +run/t9946a.scala +run/t9946c.scala +run/t9946b.scala +run/trait-super-calls.scala +pos/sd268.scala +pos/sd248 +pos/t6734.scala +pos/t10009.scala +pos/t7551 +pos/t6978 +pos/t7046-2 +neg/t9953.scala +neg/t7014 +neg/t7046-2 +neg/t7046 +run/t7046-1 +run/t7046-2 + +# Adapt checkfiles for ().toString == "undefined" +run/t5680.scala +run/dynamic-anyval.scala +run/macro-bundle-toplevel +run/macro-bundle-whitebox-decl +run/t6662 +run/t8570a.scala +run/t3702.scala +run/t7657 +run/macro-bundle-static +run/structural.scala + +# Adapt checkfiles for print & flush (which we cannot 100% emulate) +run/imports.scala +run/misc.scala + +# Adapt checkfiles for compiler phase list +neg/t7494-no-options +neg/t6446-list +neg/t6446-missing +neg/t6446-show-phases.scala +neg/t6446-additional + +# Adapt checkfiles for different behavior with boxed types +run/virtpatmat_typetag.scala +run/virtpatmat_switch.scala +run/t5629b.scala +run/t5356.scala +run/anyval-box-types.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/neg/t6446-additional.check new file mode 100644 index 0000000000..b7ce23da2f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/neg/t6446-additional.check @@ -0,0 +1,30 @@ + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + ploogin 27 A sample phase that does so many things it's kind of hard... + terminal 28 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/neg/t6446-list.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/neg/t6446-list.check new file mode 100644 index 0000000000..95883c8c81 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/neg/t6446-list.check @@ -0,0 +1,2 @@ +ploogin - A sample plugin for testing. +scalajs - Compile to JavaScript diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/neg/t6446-missing.check new file mode 100644 index 0000000000..56b74a3128 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/neg/t6446-missing.check @@ -0,0 +1,30 @@ +Error: unable to load class: t6446.Ploogin + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + terminal 27 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/neg/t6446-show-phases.check new file mode 100644 index 0000000000..cde255e3b1 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/neg/t6446-show-phases.check @@ -0,0 +1,29 @@ + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + terminal 27 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/neg/t7494-no-options.check new file mode 100644 index 0000000000..d8be421e5e --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/neg/t7494-no-options.check @@ -0,0 +1,31 @@ +error: Error: ploogin takes no options + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + jspretyper 2 capture pre-typer only tree info (for Scala.js) + namer 3 resolve names, attach symbols to named trees +packageobjects 4 load package objects + typer 5 the meat and potatoes: type the trees + jsinterop 6 prepare ASTs for JavaScript interop + patmat 7 translate match expressions +superaccessors 8 add super accessors in traits and nested classes + extmethods 9 add extension methods for inline classes + pickler 10 serialize symbol tables + refchecks 11 reference/override checking, translate nested objects + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + jscode 23 generate JavaScript code from ASTs + cleanup 24 platform-specific cleanups, generate reflective calls + delambdafy 25 remove lambdas + jvm 26 generate JVM bytecode + ploogin 27 A sample phase that does so many things it's kind of hard... + terminal 28 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Course-2002-01.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Course-2002-01.check new file mode 100644 index 0000000000..fcda9433de --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Course-2002-01.check @@ -0,0 +1,37 @@ +Course-2002-01.scala:41: warning: method loop in object M0 does nothing other than call itself recursively + def loop: Int = loop; + ^ +232 +667 +11 +10 +62.8318 +62.8318 +62.8318 +4 +81 +256 +25 +1 +737 +1 +0 +1 +76 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +1.4142156862745097 +1.7321428571428572 +2.0000000929222947 +sqrt(2) = 1.4142135623746899 +sqrt(2) = 1.4142135623746899 +cbrt(2) = 1.2599210500177698 +1 +1 1 +1 2 1 +1 3 3 1 +1 4 6 4 1 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Course-2002-02.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Course-2002-02.check new file mode 100644 index 0000000000..ab75cfdb61 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Course-2002-02.check @@ -0,0 +1,187 @@ +7 +120 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 + +pi = 3.181104885577714 +pi = 3.181104885577714 + +10 +100 +2.083333333333333 +3025.7687714031754 +pi = 3.1659792728432152 +pi = 3.181104885577714 +pi = 3.181104885577714 + +1.5 +1.4166666666666665 +1.4142156862745097 +1.4142135623746899 +sqrt(2) = 1.4142135623746899 + +1.5 +1.4166666666666665 +1.4142156862745097 +1.4142135623746899 +sqrt(2) = 1.4142135623746899 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +1 + 2 + .. + 5 = 15 +1 * 2 * .. * 5 = 120 + +1^2 + 2^2 + .. + 5^2 = 55 +1^2 * 2^2 * .. * 5^2 = 14400 + +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 + +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +power(0,0) = 1 +power(0,1) = 0 +power(0,2) = 0 +power(0,3) = 0 +power(0,4) = 0 +power(0,5) = 0 +power(0,6) = 0 +power(0,7) = 0 +power(0,8) = 0 + +power(1,0) = 1 +power(1,1) = 1 +power(1,2) = 1 +power(1,3) = 1 +power(1,4) = 1 +power(1,5) = 1 +power(1,6) = 1 +power(1,7) = 1 +power(1,8) = 1 + +power(2,0) = 1 +power(2,1) = 2 +power(2,2) = 4 +power(2,3) = 8 +power(2,4) = 16 +power(2,5) = 32 +power(2,6) = 64 +power(2,7) = 128 +power(2,8) = 256 + +power(3,0) = 1 +power(3,1) = 3 +power(3,2) = 9 +power(3,3) = 27 +power(3,4) = 81 +power(3,5) = 243 +power(3,6) = 729 +power(3,7) = 2187 +power(3,8) = 6561 + +power(4,0) = 1 +power(4,1) = 4 +power(4,2) = 16 +power(4,3) = 64 +power(4,4) = 256 +power(4,5) = 1024 +power(4,6) = 4096 +power(4,7) = 16384 +power(4,8) = 65536 + +power(5,0) = 1 +power(5,1) = 5 +power(5,2) = 25 +power(5,3) = 125 +power(5,4) = 625 +power(5,5) = 3125 +power(5,6) = 15625 +power(5,7) = 78125 +power(5,8) = 390625 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Course-2002-04.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Course-2002-04.check new file mode 100644 index 0000000000..fc6ad96eed --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Course-2002-04.check @@ -0,0 +1,64 @@ +list0 = List(6, 3, 1, 8, 7, 1, 2, 5, 8, 4, 3, 4, 8) +list1 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list2 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list3 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list4 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) +list5 = List(8, 8, 8, 7, 6, 5, 4, 4, 3, 3, 2, 1, 1) +list6 = List(8, 8, 8, 7, 6, 5, 4, 4, 3, 3, 2, 1, 1) + +list0: List() -> List() +list1: List(0) -> List(0) +list2: List(0, 1) -> List(0, 1) +list3: List(1, 0) -> List(0, 1) +list4: List(0, 1, 2) -> List(0, 1, 2) +list5: List(1, 0, 2) -> List(0, 1, 2) +list6: List(0, 1, 2) -> List(0, 1, 2) +list7: List(1, 0, 2) -> List(0, 1, 2) +list8: List(2, 0, 1) -> List(0, 1, 2) +list9: List(2, 1, 0) -> List(0, 1, 2) +listA: List(6, 3, 1, 8, 7, 1, 2, 5, 8, 4) -> List(1, 1, 2, 3, 4, 5, 6, 7, 8, 8) + +f(x) = 5x^3+7x^2+5x+9 +f(0) = 9 +f(1) = 26 +f(2) = 87 +f(3) = 222 + +v1 = List(2, 3, 4) +v2 = List(6, 7, 8) + +id = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +m1 = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m2 = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) + +v1 * v1 = 29 +v1 * v2 = 65 +v2 * v1 = 65 +v1 * v2 = 65 + +id * v1 = List(2, 3, 4) +m1 * v1 = List(4, 6, 8) +m2 * v1 = List(20, 47, 74) + +trn(id) = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +trn(m1) = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +trn(m2) = List(List(1, 4, 7), List(2, 5, 8), List(3, 6, 9)) + +List(v1) * id = List(List(2, 3, 4)) +List(v1) * m1 = List(List(4, 6, 8)) +List(v1) * m2 = List(List(42, 51, 60)) + +id * List(v1) = List(List(2, 3, 4), List(0, 0, 0), List(0, 0, 0)) +m1 * List(v1) = List(List(4, 6, 8), List(0, 0, 0), List(0, 0, 0)) +m2 * List(v1) = List(List(2, 3, 4), List(8, 12, 16), List(14, 21, 28)) + +id * id = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) +id * m1 = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m1 * id = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) +m1 * m1 = List(List(4, 0, 0), List(0, 4, 0), List(0, 0, 4)) +id * m2 = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) +m2 * id = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) +m1 * m2 = List(List(2, 4, 6), List(8, 10, 12), List(14, 16, 18)) +m2 * m1 = List(List(2, 4, 6), List(8, 10, 12), List(14, 16, 18)) +m2 * m2 = List(List(30, 36, 42), List(66, 81, 96), List(102, 126, 150)) + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Course-2002-08.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Course-2002-08.check new file mode 100644 index 0000000000..0585d5b44f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Course-2002-08.check @@ -0,0 +1,171 @@ +x = abc +count = 111 +x = hello +count = 112 + +account deposit 50 -> undefined +account withdraw 20 -> 30 +account withdraw 20 -> 10 +account withdraw 15 -> + +x deposit 30 -> undefined +y withdraw 20 -> + +x deposit 30 -> undefined +x withdraw 20 -> 10 + +x deposit 30 -> undefined +y withdraw 20 -> 10 + +2^0 = 1 +2^1 = 2 +2^2 = 4 +2^3 = 8 + +2^0 = 1 +2^1 = 2 +2^2 = 4 +2^3 = 8 + +1 2 3 +List(1, 2, 3) + +out 0 new-value = false +*** simulation started *** +out 1 new-value = true +!0 = 1 + +*** simulation started *** +out 2 new-value = false +!1 = 0 + +out 2 new-value = false + +*** simulation started *** +0 & 0 = 0 + +*** simulation started *** +0 & 1 = 0 + +*** simulation started *** +out 11 new-value = true +out 11 new-value = false +1 & 0 = 0 + +*** simulation started *** +out 14 new-value = true +1 & 1 = 1 + +out 14 new-value = false + +*** simulation started *** +0 | 0 = 0 + +*** simulation started *** +out 24 new-value = true +0 | 1 = 1 + +*** simulation started *** +1 | 0 = 1 + +*** simulation started *** +1 | 1 = 1 + +sum 34 new-value = false +carry 34 new-value = false + +*** simulation started *** +0 + 0 = 0 + +*** simulation started *** +sum 47 new-value = true +0 + 1 = 1 + +*** simulation started *** +carry 50 new-value = true +carry 50 new-value = false +sum 54 new-value = false +sum 54 new-value = true +1 + 0 = 1 + +*** simulation started *** +carry 57 new-value = true +sum 61 new-value = false +1 + 1 = 2 + +sum 61 new-value = false +carry 61 new-value = false + +*** simulation started *** +0 + 0 + 0 = 0 + +*** simulation started *** +sum 82 new-value = true +0 + 0 + 1 = 1 + +*** simulation started *** +sum 89 new-value = false +carry 90 new-value = true +sum 97 new-value = true +carry 98 new-value = false +0 + 1 + 0 = 1 + +*** simulation started *** +sum 113 new-value = false +carry 114 new-value = true +0 + 1 + 1 = 2 + +*** simulation started *** +sum 121 new-value = true +carry 122 new-value = false +sum 129 new-value = false +sum 129 new-value = true +1 + 0 + 0 = 1 + +*** simulation started *** +carry 137 new-value = true +sum 144 new-value = false +1 + 0 + 1 = 2 + +*** simulation started *** +carry 152 new-value = false +sum 152 new-value = true +sum 158 new-value = false +carry 159 new-value = true +1 + 1 + 0 = 2 + +*** simulation started *** +sum 173 new-value = true +1 + 1 + 1 = 3 + +in 0 new-value = false +ctrl0 0 new-value = false +ctrl1 0 new-value = false +ctrl2 0 new-value = false +out0 0 new-value = false +out1 0 new-value = false +out2 0 new-value = false +out3 0 new-value = false +out4 0 new-value = false +out5 0 new-value = false +out6 0 new-value = false +out7 0 new-value = false +in 0 new-value = true +*** simulation started *** +out0 10 new-value = true +ctrl0 10 new-value = true +*** simulation started *** +out1 13 new-value = true +out0 14 new-value = false +ctrl1 14 new-value = true +*** simulation started *** +out3 20 new-value = true +out1 21 new-value = false +ctrl2 21 new-value = true +*** simulation started *** +out7 30 new-value = true +out3 31 new-value = false +ctrl0 31 new-value = false +*** simulation started *** +out7 34 new-value = false +out6 35 new-value = true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Course-2002-09.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Course-2002-09.check new file mode 100644 index 0000000000..c921361db7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Course-2002-09.check @@ -0,0 +1,50 @@ +Probe: f = 32 +Probe: c = 0 +Probe: f = ? +Probe: c = ? + +Probe: f = 212 +Probe: c = 100 +Probe: f = ? +Probe: c = ? + +Probe: c = 0 +Probe: f = 32 +Probe: c = ? +Probe: f = ? + +Probe: c = 100 +Probe: f = 212 +Probe: c = ? +Probe: f = ? + +0 Celsius -> 32 Fahrenheits +100 Celsius -> 212 Fahrenheits +32 Fahrenheits -> 0 Celsius +212 Fahrenheits -> 100 Celsius + +a = ?, b = ?, c = ? => ? * ? = ? +a = 2, b = ?, c = ? => 2 * ? = ? +a = ?, b = 3, c = ? => ? * 3 = ? +a = ?, b = ?, c = 6 => ? * ? = 6 +a = 2, b = 3, c = ? => 2 * 3 = 6 +a = 2, b = ?, c = 6 => 2 * 3 = 6 +a = ?, b = 3, c = 6 => 2 * 3 = 6 +a = 2, b = 3, c = 6 => 2 * 3 = 6 + +a = 0, b = ?, c = ? => 0 * ? = 0 +a = ?, b = 0, c = ? => ? * 0 = 0 +a = ?, b = ?, c = 0 => ? * ? = 0 +a = 0, b = 7, c = ? => 0 * 7 = 0 +a = 7, b = 0, c = ? => 7 * 0 = 0 +a = 0, b = 0, c = ? => 0 * 0 = 0 +a = 0, b = ?, c = 0 => 0 * ? = 0 +a = ?, b = 0, c = 0 => ? * 0 = 0 +a = 0, b = 7, c = 0 => 0 * 7 = 0 +a = 7, b = 0, c = 0 => 7 * 0 = 0 +a = 0, b = 0, c = 0 => 0 * 0 = 0 + +a = 3, b = 4 => c = 5 +a = 3, c = 5 => b = 4 +b = 4, c = 5 => a = 3 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Course-2002-10.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Course-2002-10.check new file mode 100644 index 0000000000..847f0fa703 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Course-2002-10.check @@ -0,0 +1,46 @@ +fib(0) = 0 +fib(1) = 1 +fib(2) = 1 +fib(3) = 2 +fib(4) = 3 +fib(5) = 5 +fib(6) = 8 +fib(7) = 13 +fib(8) = 21 +fib(9) = 34 +fib(10) = 55 +fib(11) = 89 +fib(12) = 144 +fib(13) = 233 +fib(14) = 377 +fib(15) = 610 +fib(16) = 987 +fib(17) = 1597 +fib(18) = 2584 +fib(19) = 4181 + +pi(0) = 4 , 3.166666666666667 , 4 +pi(1) = 2.666666666666667 , 3.1333333333333337, 3.166666666666667 +pi(2) = 3.466666666666667 , 3.1452380952380956, 3.142105263157895 +pi(3) = 2.8952380952380956, 3.1396825396825396, 3.1415993573190044 +pi(4) = 3.33968253968254 , 3.142712842712843 , 3.141592714033778 +pi(5) = 2.976046176046176 , 3.140881340881341 , 3.1415926539752923 +pi(6) = 3.283738483738484 , 3.142071817071817 , 3.141592653591176 +pi(7) = 3.017071817071817 , 3.1412548236077646, 3.141592653589777 +pi(8) = 3.252365934718876 , 3.1418396189294024, 3.141592653589794 +pi(9) = 3.0418396189294024, 3.141406718496502 , 3.1415926535897936 +pi = 3.141592653589793 , 3.141592653589793 , 3.141592653589793 + +ln(0) = 1 , 0.7 , 1 +ln(1) = 0.5 , 0.6904761904761905, 0.7 +ln(2) = 0.8333333333333333, 0.6944444444444444, 0.6932773109243697 +ln(3) = 0.5833333333333333, 0.6924242424242424, 0.6931488693329254 +ln(4) = 0.7833333333333333, 0.6935897435897436, 0.6931471960735491 +ln(5) = 0.6166666666666667, 0.6928571428571428, 0.6931471806635636 +ln(6) = 0.7595238095238095, 0.6933473389355742, 0.6931471805604038 +ln(7) = 0.6345238095238095, 0.6930033416875522, 0.6931471805599444 +ln(8) = 0.7456349206349207, 0.6932539682539682, 0.6931471805599426 +ln(9) = 0.6456349206349206, 0.6930657506744463, 0.6931471805599453 +ln = 0.6931471805599453, 0.6931471805599453, 0.6931471805599453 + +prime numbers: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Meter.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Meter.check new file mode 100644 index 0000000000..f46fd557c8 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/Meter.check @@ -0,0 +1,16 @@ +Meter.scala:72: warning: a.Meter and Int are unrelated: they will never compare equal + println("x == 1: "+(x == 1)) + ^ +2 +4m +false +x.isInstanceOf[Meter]: true +x.hashCode: 1 +x == 1: false +x == y: true +a == b: true +testing native arrays +Array(1m, 2m) +1m +>>>1m<<< 1m +>>>2m<<< 2m diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/MeterCaseClass.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/MeterCaseClass.check new file mode 100644 index 0000000000..ac538d240f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/MeterCaseClass.check @@ -0,0 +1,16 @@ +MeterCaseClass.scala:69: warning: comparing values of types a.Meter and Int using `==' will always yield false + println("x == 1: "+(x == 1)) + ^ +2 +Meter(4) +false +x.isInstanceOf[Meter]: true +x.hashCode: 1 +x == 1: false +x == y: true +a == b: true +testing native arrays +Array(Meter(1), Meter(2)) +Meter(1) +>>>Meter(1)<<< Meter(1) +>>>Meter(2)<<< Meter(2) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/anyval-box-types.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/anyval-box-types.check new file mode 100644 index 0000000000..b2d758c906 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/anyval-box-types.check @@ -0,0 +1,52 @@ +true +1 +true +1 +true +-1 +true +1 +true +false +true +true +false +false + +true +2 +true +2 +true +-1 +true +2 +true +false +false +false +false + +true +true +false +true +1 +true +true +true +false +false +false + +true +つ +false +true +true +true +つ +true +false +false +false diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/bugs.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/bugs.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/bugs.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/caseClassHash.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/caseClassHash.check new file mode 100644 index 0000000000..f975151e9c --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/caseClassHash.check @@ -0,0 +1,9 @@ +Foo(true,-1,-1,d,-5,-10,500,500,List(),5) +Foo(true,-1,-1,d,-5,-10,500,500,List(),5) +1383698062 +1383698062 +true +## method 1: 1383698062 +## method 2: 1383698062 + Murmur 1: 1383698062 + Murmur 2: 1383698062 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/deeps.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/deeps.check new file mode 100644 index 0000000000..e533b87dc5 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/deeps.check @@ -0,0 +1,87 @@ +testEquals1 +false +false +true + +testEquals2 +false +false +true + +testEquals3 +x=Array(1) +y=Array(1) +false +false +true + +x=Array(Array(1), Array(1)) +y=Array(Array(1), Array(1)) +false +false +true + +x=Array(Array(Array(1), Array(1)), Array(Array(1), Array(1))) +y=Array(Array(Array(1), Array(1)), Array(Array(1), Array(1))) +false +false +true + +testEquals4 +false +false +true +false +false +true +Array(true, false) +Array(true, false) +[true;false] +true;false + +Array(Array(true, false), Array(true, false)) +Array(Array(true, false), Array(true, false)) +[Array(true, false);Array(true, false)] +Array(true, false);Array(true, false) + +Array(Array(Array(true, false), Array(true, false)), Array(Array(true, false), Array(true, false))) +Array(Array(Array(true, false), Array(true, false)), Array(Array(true, false), Array(true, false))) +[Array(Array(true, false), Array(true, false));Array(Array(true, false), Array(true, false))] +Array(Array(true, false), Array(true, false));Array(Array(true, false), Array(true, false)) + +Array(1, 0) +Array(1, 0) +[1;0] +1;0 + +Array(Array(1, 0), Array(1, 0)) +Array(Array(1, 0), Array(1, 0)) +[Array(1, 0);Array(1, 0)] +Array(1, 0);Array(1, 0) + +Array(Array(Array(1, 0), Array(1, 0)), Array(Array(1, 0), Array(1, 0))) +Array(Array(Array(1, 0), Array(1, 0)), Array(Array(1, 0), Array(1, 0))) +[Array(Array(1, 0), Array(1, 0));Array(Array(1, 0), Array(1, 0))] +Array(Array(1, 0), Array(1, 0));Array(Array(1, 0), Array(1, 0)) + +Array(a, b) +Array(a, b) +[a;b] +a;b + +Array(Array(a, b), Array(a, b)) +Array(Array(a, b), Array(a, b)) +[Array(a, b);Array(a, b)] +Array(a, b);Array(a, b) + +Array(Array(Array(a, b), Array(a, b)), Array(Array(a, b), Array(a, b))) +Array(Array(Array(a, b), Array(a, b)), Array(Array(a, b), Array(a, b))) +[Array(Array(a, b), Array(a, b));Array(Array(a, b), Array(a, b))] +Array(Array(a, b), Array(a, b));Array(Array(a, b), Array(a, b)) + +[Array(true, false); Array(false)] +[Array(1, 2); Array(3)] +[Array(1, 2); Array(3)] + +Array(boo, and, foo) +Array(a) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/dynamic-anyval.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/dynamic-anyval.check new file mode 100644 index 0000000000..c125372c9a --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/dynamic-anyval.check @@ -0,0 +1,4 @@ +undefined.dingo(bippy, 5) +List(1, 2, 3).dingo(bippy, 5) +undefined.dingo(bippy, 5) +List(1, 2, 3).dingo(bippy, 5) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/impconvtimes.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/impconvtimes.check new file mode 100644 index 0000000000..082377e474 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/impconvtimes.check @@ -0,0 +1 @@ +3.0 * Hour = Measure(3,Hour) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/imports.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/imports.check new file mode 100644 index 0000000000..1aad598062 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/imports.check @@ -0,0 +1,21 @@ +In C_ico, v_ico .toString() returns ↩ +↪C_ico -> ok +In C_ico, field .toString() returns ↩ +↪C_ico -> ok +In C_ico, method.toString() returns ↩ +↪C_ico -> ok + +In C_ioc, v_ioc .toString() returns ↩ +↪C_ioc -> ok +In C_ioc, field .toString() returns ↩ +↪C_ioc -> ok +In C_ioc, method.toString() returns ↩ +↪C_ioc -> ok + +In C_oic, v_oic .toString() returns ↩ +↪C_oic -> ok +In C_oic, field .toString() returns ↩ +↪C_oic -> ok +In C_oic, method.toString() returns ↩ +↪C_oic -> ok + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/interpolation.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/interpolation.check new file mode 100644 index 0000000000..9c4a77715b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/interpolation.check @@ -0,0 +1,32 @@ +Bob is 1 years old +Bob is 1 years old +Bob will be 2 years old +Bob will be 2 years old +1+1 = 2 +1+1 = 2 +Bob is 12 years old +Bob is 12 years old +Bob will be 13 years old +Bob will be 13 years old +12+1 = 13 +12+1 = 13 +Bob is 123 years old +Bob is 123 years old +Bob will be 124 years old +Bob will be 124 years old +123+1 = 124 +123+1 = 124 +Best price: 10 +Best price: 10.00 +10% discount included +10.00% discount included +Best price: 13.345000267028809 +Best price: 13.35 +13.345000267028809% discount included +13.35% discount included + +0 +00 + +0 +00 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/interpolationMultiline1.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/interpolationMultiline1.check new file mode 100644 index 0000000000..1b6e140c13 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/interpolationMultiline1.check @@ -0,0 +1,26 @@ +Bob is 1 years old +Bob is 1 years old +Bob will be 2 years old +Bob will be 2 years old +1+1 = 2 +1+1 = 2 +Bob is 12 years old +Bob is 12 years old +Bob will be 13 years old +Bob will be 13 years old +12+1 = 13 +12+1 = 13 +Bob is 123 years old +Bob is 123 years old +Bob will be 124 years old +Bob will be 124 years old +123+1 = 124 +123+1 = 124 +Best price: 10 +Best price: 10.00 +10% discount included +10.00% discount included +Best price: 13.345000267028809 +Best price: 13.35 +13.345000267028809% discount included +13.35% discount included diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/issue192.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/issue192.sem new file mode 100644 index 0000000000..10abbf7f3b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/issue192.sem @@ -0,0 +1 @@ +strictFloats diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/macro-bundle-static.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/macro-bundle-static.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/macro-bundle-static.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/macro-bundle-toplevel.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/macro-bundle-toplevel.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/macro-bundle-toplevel.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/macro-bundle-whitebox-decl.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/macro-bundle-whitebox-decl.check new file mode 100644 index 0000000000..e2e7628a0d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/macro-bundle-whitebox-decl.check @@ -0,0 +1,6 @@ +undefined +Int +undefined +true +IntInt +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/misc.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/misc.check new file mode 100644 index 0000000000..85f37c51d7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/misc.check @@ -0,0 +1,62 @@ +misc.scala:46: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 42; + ^ +misc.scala:47: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 42l; + ^ +misc.scala:48: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 23.5f; + ^ +misc.scala:49: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 23.5; + ^ +misc.scala:50: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + "Hello"; + ^ +misc.scala:51: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 32 + 45; + ^ +misc.scala:62: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + x; + ^ +misc.scala:74: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 1 < 2; + ^ +### Hello +### 17 +### Bye + +### fib(0) = ↩ +↪1 +### fib(1) = ↩ +↪1 +### fib(2) = ↩ +↪2 +### fib(3) = ↩ +↪3 +### fib(4) = ↩ +↪5 +=== MyClass::toString === +=== MySubclass::toString === +=== MyClass::test === + +identity + +A.a = 1 +B.a = 5 +B.b = 2 + +X.a = 4 +Y.a = 11 +Y.b = 5 +Y.b = 5 + +X::foo + +Y::foo +X::foo + +3 +3 + +true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/promotion.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/promotion.check new file mode 100644 index 0000000000..41e36c369d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/promotion.check @@ -0,0 +1,4 @@ +2 +6 +20 +30 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/runtime.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/runtime.check new file mode 100644 index 0000000000..0450b9498a --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/runtime.check @@ -0,0 +1,70 @@ +runtime.scala:141: warning: comparing values of types Null and Null using `eq' will always yield true + check(true , null eq null, null ne null); + ^ +runtime.scala:141: warning: comparing values of types Null and Null using `ne' will always yield false + check(true , null eq null, null ne null); + ^ +<<< Test0 +[false,true] +[0,1,2] +[3,4,5] +[a,b,c] +[6,7,8] +[9,10,11] +[12,13] +[14,15] +[string] +>>> Test0 + +<<< Test1 +10 +14 +15 +16 +20 +23 +24 +25 +26 +>>> Test1 + +<<< Test2 +A +M0 +N0 + +A +N0 +M0 + +A +M0 +M1 +N0 + +A +N0 +N1 +M0 + +>>> Test2 + +<<< Test3 +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +>>> Test3 + diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/spec-self.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/spec-self.check new file mode 100644 index 0000000000..fd3c81a4d7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/spec-self.check @@ -0,0 +1,2 @@ +5 +5 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/structural.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/structural.check new file mode 100644 index 0000000000..2fec112a87 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/structural.check @@ -0,0 +1,37 @@ + 1. hey + 2. 11 + 3. dee + 4. iei + 5. 6 + 6. 51 + 7. 2 + 8. 11 +10. 12 +11. eitch +12. 1 +13. ohone +14. 1 +15. undefined +16. one +17. tieone +18. 2 +19. true +20. 1 +21. undefined +22. one +23. oy +24. 1 +25. null +26. iei +31. 4 +32. undefined +33. iei +33. tieone +1 +2 +3 +4 +5 +caught +3 +2 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t0421-new.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t0421-new.check new file mode 100644 index 0000000000..00d29b7e5b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t0421-new.check @@ -0,0 +1,3 @@ +[Array(0, 1),Array(2, 3),Array(4, 5)] +[Array(31)] +[Array(24, 32)] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t0421-old.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t0421-old.check new file mode 100644 index 0000000000..00d29b7e5b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t0421-old.check @@ -0,0 +1,3 @@ +[Array(0, 1),Array(2, 3),Array(4, 5)] +[Array(31)] +[Array(24, 32)] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t1503.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t1503.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t1503.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t3702.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t3702.check new file mode 100644 index 0000000000..3fce98715c --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t3702.check @@ -0,0 +1,2 @@ +undefined +6 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t4148.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t4148.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t4148.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t4617.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t4617.check new file mode 100644 index 0000000000..a6790f16f7 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t4617.check @@ -0,0 +1 @@ +Str 8 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t5356.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t5356.check new file mode 100644 index 0000000000..870c901131 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t5356.check @@ -0,0 +1,6 @@ +1 java.lang.Byte +1 java.lang.Byte +1 scala.math.BigInt +1 java.lang.Byte +1 java.lang.Byte +1 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t5552.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t5552.check new file mode 100644 index 0000000000..9e767b6d7b --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t5552.check @@ -0,0 +1,6 @@ +lazy: 3 +(3,3) +(3,3) +lazy: 3 +(3,3) +(3,3) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t5568.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t5568.check new file mode 100644 index 0000000000..6f30cc5070 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t5568.check @@ -0,0 +1,9 @@ +void +int +class scala.runtime.BoxedUnit +class scala.runtime.BoxedUnit +class java.lang.Byte +class java.lang.Byte +5 +5 +5 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t5629b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t5629b.check new file mode 100644 index 0000000000..c65298a6ce --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t5629b.check @@ -0,0 +1,10 @@ +=== pf(1): +MySmartPF.apply entered... +newPF.applyOrElse entered... +default +scala.MatchError: 1 (of class java.lang.Byte) +=== pf(42): +MySmartPF.apply entered... +newPF.applyOrElse entered... +ok +=== done diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t5680.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t5680.check new file mode 100644 index 0000000000..a3b8b64a43 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t5680.check @@ -0,0 +1,3 @@ +[Lscala.runtime.BoxedUnit +undefined +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t5866.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t5866.check new file mode 100644 index 0000000000..64df1cec7f --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t5866.check @@ -0,0 +1,2 @@ +0 +Foo(0) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t6318_primitives.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t6318_primitives.check new file mode 100644 index 0000000000..654ef1beec --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t6318_primitives.check @@ -0,0 +1,54 @@ +Checking if byte matches byte +Some(1) +Checking if byte matches short +Some(1) +Checking if class java.lang.Byte matches byte +Some(1) +Checking if short matches short +Some(1) +Checking if short matches char +None +Checking if class java.lang.Byte matches short +Some(1) +Checking if char matches char +Some() +Checking if char matches int +None +Checking if class java.lang.Character matches char +Some() +Checking if int matches int +Some(1) +Checking if int matches long +None +Checking if class java.lang.Byte matches int +Some(1) +Checking if long matches long +Some(1) +Checking if long matches float +None +Checking if class java.lang.Long matches long +Some(1) +Checking if float matches float +Some(1) +Checking if float matches double +Some(1) +Checking if class java.lang.Byte matches float +Some(1) +Checking if double matches double +Some(1) +Checking if double matches boolean +None +Checking if class java.lang.Byte matches double +Some(1) +Checking if boolean matches boolean +Some(true) +Checking if boolean matches void +None +Checking if class java.lang.Boolean matches boolean +Some(true) +Checking if void matches void +Some(undefined) +Checking if void matches byte +None +Checking if class scala.runtime.BoxedUnit matches void +Some(undefined) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t6662.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t6662.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t6662.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t7657.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t7657.check new file mode 100644 index 0000000000..1a87c1e866 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t7657.check @@ -0,0 +1,3 @@ +undefined +undefined +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t7763.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t7763.sem new file mode 100644 index 0000000000..d36898b932 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t7763.sem @@ -0,0 +1 @@ +asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t8570a.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t8570a.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t8570a.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t8764.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t8764.check new file mode 100644 index 0000000000..121120217e --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t8764.check @@ -0,0 +1,5 @@ +IntOnly: should return an unboxed int +Int: int +IntAndDouble: should just box and return Anyval +Double: class java.lang.Byte +Int: class java.lang.Byte diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t9387b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t9387b.check new file mode 100644 index 0000000000..417b7b5370 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t9387b.check @@ -0,0 +1 @@ +undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t9656.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t9656.check new file mode 100644 index 0000000000..d023bf9afb --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/t9656.check @@ -0,0 +1,20 @@ +t9656.scala:17: warning: method until in trait FractionalProxy is deprecated (since 2.12.6): use BigDecimal range instead + println(0.1 until 1.0 by 0.1) + ^ +t9656.scala:19: warning: method apply in object Double is deprecated (since 2.12.6): use Range.BigDecimal instead + println(Range.Double(0.1, 1.0, 0.1)) + ^ +Range 1 to 10 +Range 1 to 10 +inexact Range 1 to 10 by 2 +Range 1 to 10 by 3 +inexact Range 1 until 10 by 2 +Range 100 to 100 +empty Range 100 until 100 +NumericRange 1 to 10 +NumericRange 1 to 10 by 2 +NumericRange 0.1 until 1 by 0.1 +NumericRange 0.1 until 1.0 by 0.1 +NumericRange 0.1 until 1 by 0.1 (using NumericRange 0.1 until 1 by 0.1 of BigDecimal) +NumericRange 0 days until 10 seconds by 1 second +empty NumericRange 0 days until 0 days by 1 second diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/try-catch-unify.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/try-catch-unify.check new file mode 100644 index 0000000000..813f01166d --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/try-catch-unify.check @@ -0,0 +1,4 @@ +Failure(java.lang.NumberFormatException: For input string: "Hi") +Success(5) +O NOES +Failure(java.lang.NumberFormatException: For input string: "Hi") diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/virtpatmat_switch.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/virtpatmat_switch.check new file mode 100644 index 0000000000..0900a9ca32 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/virtpatmat_switch.check @@ -0,0 +1,7 @@ +zero +one +many +got a +got b +got some letter +scala.MatchError: 5 (of class java.lang.Byte) \ No newline at end of file diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/virtpatmat_typetag.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/virtpatmat_typetag.check new file mode 100644 index 0000000000..048c3aeed0 --- /dev/null +++ b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.12.6/run/virtpatmat_typetag.check @@ -0,0 +1,10 @@ +1 is a Int +1 is a java.lang.Integer +1 is not a java.lang.String; it's a class java.lang.Byte +true is a Any +woele is a java.lang.String +1 is a Int +1 is a java.lang.Integer +1 is not a java.lang.String; it's a class java.lang.Byte +true is a Any +woele is a java.lang.String diff --git a/project/Build.scala b/project/Build.scala index b38ba5b113..c0771cdbb4 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -78,7 +78,7 @@ object Build { else sourceDir / "scala-old-collections" val scalaVersionsUsedForPublishing: Set[String] = - Set("2.10.7", "2.11.12", "2.12.5", "2.13.0-M3") + Set("2.10.7", "2.11.12", "2.12.6", "2.13.0-M3") val newScalaBinaryVersionsInThisRelease: Set[String] = Set() @@ -132,7 +132,7 @@ object Build { } val commonSettings = Seq( - scalaVersion := "2.12.5", + scalaVersion := "2.12.6", organization := "org.scala-js", version := scalaJSVersion, diff --git a/scala-test-suite/src/test/resources/2.12.6/BlacklistedTests.txt b/scala-test-suite/src/test/resources/2.12.6/BlacklistedTests.txt new file mode 100644 index 0000000000..9a7be17af0 --- /dev/null +++ b/scala-test-suite/src/test/resources/2.12.6/BlacklistedTests.txt @@ -0,0 +1,142 @@ +## Do not compile +scala/lang/annotations/BytecodeTest.scala +scala/lang/annotations/RunTest.scala +scala/lang/traits/BytecodeTest.scala +scala/lang/traits/RunTest.scala +scala/lang/primitives/NaNTest.scala +scala/lang/primitives/BoxUnboxTest.scala +scala/reflect/ClassOfTest.scala +scala/reflect/QTest.scala +scala/reflect/io/AbstractFileTest.scala +scala/reflect/io/ZipArchiveTest.scala +scala/reflect/internal/util/AbstractFileClassLoaderTest.scala +scala/reflect/internal/util/SourceFileTest.scala +scala/reflect/internal/util/StringOpsTest.scala +scala/reflect/internal/PrintersTest.scala +scala/reflect/internal/ScopeTest.scala +scala/reflect/internal/TreeGenTest.scala +scala/reflect/internal/TypesTest.scala +scala/reflect/internal/util/WeakHashSetTest.scala +scala/reflect/internal/MirrorsTest.scala +scala/reflect/internal/NamesTest.scala +scala/tools/nsc/backend/jvm/BTypesTest.scala +scala/tools/nsc/backend/jvm/BytecodeTest.scala +scala/tools/nsc/backend/jvm/DefaultMethodTest.scala +scala/tools/nsc/backend/jvm/DirectCompileTest.scala +scala/tools/nsc/backend/jvm/GenericSignaturesTest.scala +scala/tools/nsc/backend/jvm/IndyLambdaTest.scala +scala/tools/nsc/backend/jvm/IndySammyTest.scala +scala/tools/nsc/backend/jvm/InnerClassAttributeTest.scala +scala/tools/nsc/backend/jvm/NestedClassesCollectorTest.scala +scala/tools/nsc/backend/jvm/OptimizedBytecodeTest.scala +scala/tools/nsc/backend/jvm/PerRunInitTest.scala +scala/tools/nsc/backend/jvm/StringConcatTest.scala +scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala +scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala +scala/tools/nsc/backend/jvm/opt/AnalyzerTest.scala +scala/tools/nsc/backend/jvm/opt/BoxUnboxTest.scala +scala/tools/nsc/backend/jvm/opt/BTypesFromClassfileTest.scala +scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala +scala/tools/nsc/backend/jvm/opt/ClosureOptimizerTest.scala +scala/tools/nsc/backend/jvm/opt/CompactLocalVariablesTest.scala +scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala +scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala +scala/tools/nsc/backend/jvm/opt/InlineInfoTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerIllegalAccessTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala +scala/tools/nsc/backend/jvm/opt/InlinerTest.scala +scala/tools/nsc/backend/jvm/opt/InlineSourceMatcherTest.scala +scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala +scala/tools/nsc/backend/jvm/opt/MethodLevelOptsTest.scala +scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala +scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala +scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala +scala/tools/nsc/backend/jvm/opt/UnusedLocalVariablesTest.scala +scala/tools/nsc/ScriptRunnerTest.scala +scala/tools/nsc/classpath/AggregateClassPathTest.scala +scala/tools/nsc/classpath/JrtClassPathTest.scala +scala/tools/nsc/classpath/MultiReleaseJarTest.scala +scala/tools/nsc/classpath/PathResolverBaseTest.scala +scala/tools/nsc/classpath/VirtualDirectoryClassPathTest.scala +scala/tools/nsc/classpath/ZipAndJarFileLookupFactoryTest.scala +scala/tools/nsc/doc/html/HtmlDocletTest.scala +scala/tools/nsc/interpreter/CompletionTest.scala +scala/tools/nsc/interpreter/ScriptedTest.scala +scala/tools/nsc/interpreter/TabulatorTest.scala +scala/tools/nsc/reporters/ConsoleReporterTest.scala +scala/tools/nsc/settings/ScalaVersionTest.scala +scala/tools/nsc/settings/SettingsTest.scala +scala/tools/nsc/symtab/CannotHaveAttrsTest.scala +scala/tools/nsc/symtab/FlagsTest.scala +scala/tools/nsc/symtab/FreshNameExtractorTest.scala +scala/tools/nsc/symtab/StdNamesTest.scala +scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala +scala/tools/nsc/symtab/SymbolTableTest.scala +scala/tools/nsc/transform/MixinTest.scala +scala/tools/nsc/transform/delambdafy/DelambdafyTest.scala +scala/tools/nsc/transform/patmat/SolvingTest.scala +scala/tools/nsc/transform/patmat/PatmatBytecodeTest.scala +scala/tools/nsc/typechecker/Implicits.scala +scala/tools/nsc/typechecker/TypedTreeTest.scala +scala/tools/nsc/util/StackTraceTest.scala +scala/tools/testing/BytecodeTesting.scala +scala/tools/testing/RunTesting.scala + +## Do not link +scala/MatchErrorSerializationTest.scala +scala/PartialFunctionSerializationTest.scala +scala/lang/stringinterpol/StringContextTest.scala +scala/collection/IteratorTest.scala +scala/collection/NewBuilderTest.scala +scala/collection/ParallelConsistencyTest.scala +scala/collection/SeqViewTest.scala +scala/collection/SetMapConsistencyTest.scala +scala/collection/concurrent/TrieMapTest.scala +scala/collection/convert/WrapperSerializationTest.scala +scala/collection/immutable/ListTest.scala +scala/collection/immutable/StreamTest.scala +scala/collection/immutable/StringLikeTest.scala +scala/collection/mutable/ArrayBufferTest.scala +scala/collection/mutable/MutableListTest.scala +scala/collection/mutable/OpenHashMapTest.scala +scala/collection/mutable/PriorityQueueTest.scala +scala/collection/parallel/TaskTest.scala +scala/collection/parallel/immutable/ParRangeTest.scala +scala/concurrent/FutureTest.scala +scala/concurrent/duration/SerializationTest.scala +scala/concurrent/impl/DefaultPromiseTest.scala +scala/io/SourceTest.scala +scala/runtime/ScalaRunTimeTest.scala +scala/sys/process/PipedProcessTest.scala +scala/sys/process/ProcessTest.scala +scala/tools/testing/AssertUtilTest.scala +scala/tools/testing/AssertThrowsTest.scala +scala/util/SpecVersionTest.scala +scala/util/SystemPropertiesTest.scala + +## Tests fail + +# Reflection +scala/reflect/ClassTagTest.scala + +# Regex +scala/util/matching/CharRegexTest.scala +scala/util/matching/RegexTest.scala + +# Require strict-floats +scala/math/BigDecimalTest.scala + +# Difference of getClass() on primitive values +scala/collection/immutable/RangeTest.scala + +# Test fails only some times with +# 'set scalaJSOptimizerOptions in scalaTestSuite ~= (_.withDisableOptimizer(true))' +# and' 'set scalaJSUseRhino in Global := false' +scala/collection/immutable/PagedSeqTest.scala + +# Bugs +scala/collection/convert/MapWrapperTest.scala + +# Tests passed but are too slow (timeouts) +scala/collection/immutable/ListSetTest.scala +scala/util/SortingTest.scala diff --git a/scala-test-suite/src/test/resources/2.12.6/WhitelistedTests.txt b/scala-test-suite/src/test/resources/2.12.6/WhitelistedTests.txt new file mode 100644 index 0000000000..9f173d7628 --- /dev/null +++ b/scala-test-suite/src/test/resources/2.12.6/WhitelistedTests.txt @@ -0,0 +1,40 @@ +scala/collection/IndexedSeqOptimizedTest.scala +scala/collection/IndexedSeqTest.scala +scala/collection/IterableViewLikeTest.scala +scala/collection/LinearSeqOptimizedTest.scala +scala/collection/ReusableBuildersTest.scala +scala/collection/SearchingTest.scala +scala/collection/SeqLikeTest.scala +scala/collection/TraversableLikeTest.scala +scala/collection/TraversableOnceTest.scala +scala/collection/convert/NullSafetyToJavaTest.scala +scala/collection/convert/NullSafetyToScalaTest.scala +scala/collection/immutable/HashMapTest.scala +scala/collection/immutable/ListMapTest.scala +scala/collection/immutable/QueueTest.scala +scala/collection/immutable/RangeConsistencyTest.scala +scala/collection/immutable/SetTest.scala +scala/collection/immutable/TreeMapTest.scala +scala/collection/immutable/TreeSetTest.scala +scala/collection/immutable/VectorTest.scala +scala/collection/mutable/AnyRefMapTest.scala +scala/collection/mutable/ArraySortingTest.scala +scala/collection/mutable/BitSetTest.scala +scala/collection/mutable/HashMapTest.scala +scala/collection/mutable/LinkedHashMapTest.scala +scala/collection/mutable/LinkedHashSetTest.scala +scala/collection/mutable/SetLikeTest.scala +scala/collection/mutable/TreeMapTest.scala +scala/collection/mutable/TreeSetTest.scala +scala/collection/mutable/UnrolledBufferTest.scala +scala/collection/mutable/VectorTest.scala +scala/lang/primitives/PredefAutoboxingTest.scala +scala/math/BigIntTest.scala +scala/math/NumericTest.scala +scala/math/OrderingTest.scala +scala/runtime/ZippedTest.scala +scala/tools/testing/AssertUtil.scala +scala/tools/testing/TempDir.scala +scala/util/RandomTest.scala +scala/util/TryTest.scala +scala/util/control/ExceptionTest.scala diff --git a/scripts/assemble-cli.sh b/scripts/assemble-cli.sh index a349cc0128..a5f6ef39d5 100755 --- a/scripts/assemble-cli.sh +++ b/scripts/assemble-cli.sh @@ -20,8 +20,8 @@ case $BINVER in BASEVER="2.11.12" ;; 2.12) - FULLVERS="2.12.0 2.12.1 2.12.2 2.12.3 2.12.4 2.12.5" - BASEVER="2.12.5" + FULLVERS="2.12.0 2.12.1 2.12.2 2.12.3 2.12.4 2.12.5 2.12.6" + BASEVER="2.12.6" ;; *) echo "Invalid Scala version $BINVER" >&2 diff --git a/scripts/publish.sh b/scripts/publish.sh index 8b0131a8d8..dcafc4f297 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -7,11 +7,11 @@ else CMD="echo sbt" fi -FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.10.7 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.11.12 2.12.0 2.12.1 2.12.2 2.12.3 2.12.4 2.12.5 2.13.0-M3" -BIN_VERSIONS="2.10.7 2.11.12 2.12.5 2.13.0-M3" -CLI_VERSIONS="2.10.7 2.11.12 2.12.5" +FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.10.7 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.11.12 2.12.0 2.12.1 2.12.2 2.12.3 2.12.4 2.12.5 2.12.6 2.13.0-M3" +BIN_VERSIONS="2.10.7 2.11.12 2.12.6 2.13.0-M3" +CLI_VERSIONS="2.10.7 2.11.12 2.12.6" SBT_VERSION="2.10.7" -SBT1_VERSION="2.12.5" +SBT1_VERSION="2.12.6" SBT1_SBTVERSION="1.0.0" COMPILER="compiler jUnitPlugin" From 0475c5d299ea06f19a1d75b025a467dcfaae1d09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 25 Jun 2018 15:05:45 +0200 Subject: [PATCH 0791/2665] Remove useless call to `registerModuleExports` in the JUnit plugin. The call has been useless since f7e4cf733d3a723437afd848d628ff81d4b98671, when we transitioned from using exports to `@EnableReflectiveInstantiation` for the JUnit bootstrapper objects. We also deprecate the hook, which, although "documented", was not well-specified and was there only for the JUnit plugin. --- .../org/scalajs/core/compiler/ScalaJSPlugin.scala | 10 ++++++---- .../scalajs/junit/plugin/ScalaJSJUnitPlugin.scala | 15 --------------- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala index 6f12f2149d..2d4fde50d5 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala @@ -59,11 +59,13 @@ class ScalaJSPlugin(val global: Global) extends NscPlugin { } /** Checks and registers module exports on the symbol. - * This bridge allows other plugins (such as ScalaJSJUnitPlugin) to register - * new modules for export between jsinterop and jscode phases. It is meant to - * be accessed using reflection. The calling code still must insert the - * `@JSExport` annotation to the module. + * + * This bridge allows other plugins to register new modules for export + * between jsinterop and jscode phases. It is meant to be accessed using + * reflection. The calling code still must insert the `@JSExport` annotation + * to the module. */ + @deprecated("Might be removed at any time, use at your own risk.", "0.6.24") def registerModuleExports(sym: Symbol): Unit = PrepInteropComponent.registerModuleExports(sym) diff --git a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala index 3cac96a105..a4301c66a9 100644 --- a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala +++ b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala @@ -87,20 +87,6 @@ class ScalaJSJUnitPlugin(val global: Global) extends NscPlugin { val description: String = "Makes JUnit test classes invokable in Scala.js" - // `ScalaJSPlugin` instance reference. Only `registerModuleExports` is accessible. - private lazy val scalaJSPlugin = { - type ScalaJSPlugin = NscPlugin { - def registerModuleExports(sym: ScalaJSJUnitPluginComponent.global.Symbol): Unit - } - global.plugins.collectFirst { - case pl if pl.getClass.getName == "org.scalajs.core.compiler.ScalaJSPlugin" => - pl.asInstanceOf[ScalaJSPlugin] - }.getOrElse { - throw new Exception( - "The Scala.js JUnit plugin only works with the Scala.js plugin enabled.") - } - } - object ScalaJSJUnitPluginComponent extends plugins.PluginComponent with transform.Transform with Compat210Component { @@ -238,7 +224,6 @@ class ScalaJSJUnitPlugin(val global: Global) extends NscPlugin { ClassInfoType(newParentsInfo, decls, bootSym.info.typeSymbol) } bootSym.setInfo(newClazzInfo) - scalaJSPlugin.registerModuleExports(bootSym) bootClazz.setSymbol(bootSym) currentRun.symSource(bootSym) = clazz.symbol.sourceFile From 25d4057a1c8195b63fdd50c56bbe171615b834a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 26 Jun 2018 14:02:55 +0200 Subject: [PATCH 0792/2665] Fix #3393: Correctly report VM crashes as failed futures. The line in this commit was supposed to complete the future with a failure if either `vmComplete` or `pipeResult` was failed, giving precedence to `vmComplete`. However that line was bogus, and would complete with a success if `pipeResult` was a success, even if `vmComplete` was a failure. This caused the `TestAdapter` to erroneously interpret a VM failure as a normal exit without spawning the testing interface bridge. --- .../src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala index 87fff28710..d24e19777d 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala @@ -183,8 +183,11 @@ abstract class ExternalJSEnv( case e => ioThreadEx = e } - // Chain Try's the other way: We want VM failure first, then IO failure - promise.complete(pipeResult orElse vmComplete) + /* We want the VM failure to take precedence if there was one, + * otherwise the IO failure if there is one. We complete with a + * successful () only when both vmComplete and pipeResult were successful. + */ + promise.complete(vmComplete.flatMap(_ => pipeResult)) } } From e82edddf568c086c05a1cbf4454c1d8afd81e03f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 26 Jun 2018 21:40:54 +0200 Subject: [PATCH 0793/2665] Version 0.6.24. --- ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index 756104816c..0652b007c6 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.24-SNAPSHOT" + val current: String = "0.6.24" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" From e913ee60aa9413905d7fe01fde0f86b196517d45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 28 Jun 2018 22:56:39 +0200 Subject: [PATCH 0794/2665] Towards 0.6.25. --- ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- project/Build.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index 0652b007c6..ab627acfa9 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.24" + val current: String = "0.6.25-SNAPSHOT" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" diff --git a/project/Build.scala b/project/Build.scala index c0771cdbb4..2995a6f404 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -57,7 +57,7 @@ object Build { val shouldPartest = settingKey[Boolean]( "Whether we should partest the current scala version (and fail if we can't)") - val previousVersion = "0.6.23" + val previousVersion = "0.6.24" val previousSJSBinaryVersion = ScalaJSCrossVersion.binaryScalaJSVersion(previousVersion) val previousBinaryCrossVersion = From dabc947f6f2c8c45e9a26863417ad0b47929dc0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 29 Jun 2018 14:32:37 +0200 Subject: [PATCH 0795/2665] Version 1.0.0-M4. --- ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala index 73a88b396c..dc5d746013 100644 --- a/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "1.0.0-SNAPSHOT" + val current: String = "1.0.0-M4" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" From 7e3ab44a38ab5f70b447b4e5d008dcc1e7074540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 30 Jun 2018 23:46:51 +0200 Subject: [PATCH 0796/2665] Towards 1.0.0 again. --- ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala index dc5d746013..73a88b396c 100644 --- a/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "1.0.0-M4" + val current: String = "1.0.0-SNAPSHOT" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" From 3477a611cad4f2504fba19162c44d091ea199b99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 1 Jul 2018 12:49:56 +0200 Subject: [PATCH 0797/2665] Upgrade to sbt-platform-deps 1.0.0 final. --- project/Build.scala | 12 +----------- project/build.sbt | 2 +- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 7d3769bc01..0529e7185d 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -790,17 +790,7 @@ object Build { previousArtifactSetting, mimaBinaryIssueFilters ++= BinaryIncompatibilities.SbtPlugin, - /* This works around a bug in ^^ from sbt (should be just addSbtPlugin). - * We inline the definition of addSbtPlugin and fix the sbt binary version. - */ - libraryDependencies += { - val sbtV = - if ((sbtVersion in pluginCrossBuild).value.startsWith("1.0.")) "1.0" - else (sbtBinaryVersion in update).value - val scalaV = (scalaBinaryVersion in update).value - Defaults.sbtPluginExtra( - "org.portable-scala" % "sbt-platform-deps" % "1.0.0-M2", sbtV, scalaV) - }, + addSbtPlugin("org.portable-scala" % "sbt-platform-deps" % "1.0.0"), // Add API mappings for sbt (seems they don't export their API URL) apiMappings ++= { diff --git a/project/build.sbt b/project/build.sbt index e3e19ee3ed..eb1be91982 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -2,7 +2,7 @@ addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.18") addSbtPlugin("org.scalastyle" % "scalastyle-sbt-plugin" % "1.0.0") -addSbtPlugin("org.portable-scala" % "sbt-platform-deps" % "1.0.0-M2") +addSbtPlugin("org.portable-scala" % "sbt-platform-deps" % "1.0.0") libraryDependencies += "com.google.javascript" % "closure-compiler" % "v20160517" From f386914fc8c165a84ecf86007e6e303cb47ba865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 2 Jul 2018 13:50:54 +0200 Subject: [PATCH 0798/2665] Fix #3400: Do not crash if source-map-support is unavailable by default. The `sourceMap` option of `NodeJSEnv.Config` is now a tri-state with `Disable`, `EnableIfAvailable` and `Enable`. Only the last one crashes if `source-map-support` is not available. The default is `EnableIfAvailable`, which should be the most appropriate option for many projects. --- .../org/scalajs/jsenv/nodejs/NodeJSEnv.scala | 57 ++++++++++++++++--- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala index 6071dae70b..b59865f270 100644 --- a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala +++ b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala @@ -23,6 +23,8 @@ import org.scalajs.logging._ import java.io._ final class NodeJSEnv(config: NodeJSEnv.Config) extends JSEnv { + import NodeJSEnv._ + def this() = this(NodeJSEnv.Config()) val name: String = "Node.js" @@ -53,8 +55,11 @@ final class NodeJSEnv(config: NodeJSEnv.Config) extends JSEnv { private def initFiles: List[VirtualBinaryFile] = { val base = List(NodeJSEnv.runtimeEnv, Support.fixPercentConsole) - if (config.sourceMap) NodeJSEnv.installSourceMap :: base - else base + config.sourceMap match { + case SourceMap.Disable => base + case SourceMap.EnableIfAvailable => installSourceMapIfAvailable :: base + case SourceMap.Enable => installSourceMap :: base + } } private def inputFiles(input: Input) = input match { @@ -69,6 +74,17 @@ final class NodeJSEnv(config: NodeJSEnv.Config) extends JSEnv { object NodeJSEnv { private lazy val validator = ExternalJSRun.supports(RunConfig.Validator()) + private lazy val installSourceMapIfAvailable = { + MemVirtualBinaryFile.fromStringUTF8("sourceMapSupport.js", + """ + |try { + | require('source-map-support').install(); + |} catch (e) { + |}; + """.stripMargin + ) + } + private lazy val installSourceMap = { MemVirtualBinaryFile.fromStringUTF8("sourceMapSupport.js", "require('source-map-support').install();") @@ -117,18 +133,36 @@ object NodeJSEnv { } } + /** Requirements for source map support. */ + sealed abstract class SourceMap + + object SourceMap { + /** Disable source maps. */ + case object Disable extends SourceMap + + /** Enable source maps if `source-map-support` is available. */ + case object EnableIfAvailable extends SourceMap + + /** Always enable source maps. + * + * If `source-map-support` is not available, loading the .js code will + * fail. + */ + case object Enable extends SourceMap + } + final class Config private ( val executable: String, val args: List[String], val env: Map[String, String], - val sourceMap: Boolean + val sourceMap: SourceMap ) { private def this() = { this( executable = "node", args = Nil, env = Map.empty, - sourceMap = true + sourceMap = SourceMap.EnableIfAvailable ) } @@ -141,14 +175,23 @@ object NodeJSEnv { def withEnv(env: Map[String, String]): Config = copy(env = env) - def withSourceMap(sourceMap: Boolean): Config = + def withSourceMap(sourceMap: SourceMap): Config = copy(sourceMap = sourceMap) + /** Forces enabling (true) or disabling (false) source maps. + * + * `sourceMap = true` maps to [[SourceMap.Enable]]. `sourceMap = false` + * maps to [[SourceMap.Disable]]. [[SourceMap.EnableIfAvailable]] is never + * used by this method. + */ + def withSourceMap(sourceMap: Boolean): Config = + withSourceMap(if (sourceMap) SourceMap.Enable else SourceMap.Disable) + private def copy( executable: String = executable, args: List[String] = args, env: Map[String, String] = env, - sourceMap: Boolean = sourceMap + sourceMap: SourceMap = sourceMap ): Config = { new Config(executable, args, env, sourceMap) } @@ -162,7 +205,7 @@ object NodeJSEnv { * - `executable`: `"node"` * - `args`: `Nil` * - `env`: `Map.empty` - * - `sourceMap`: `true` + * - `sourceMap`: [[SourceMap.EnableIfAvailable]] */ def apply(): Config = new Config() } From caaf3a947ca37ec49447b8b12633de7a1d70fced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 2 Jul 2018 17:02:52 +0200 Subject: [PATCH 0799/2665] Version 1.0.0-M5. --- ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala index 73a88b396c..1b1ebdc6b2 100644 --- a/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "1.0.0-SNAPSHOT" + val current: String = "1.0.0-M5" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" From 9e4ae15954a16e70ee9c859838e1db9557b78780 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 3 Jul 2018 12:04:05 +0200 Subject: [PATCH 0800/2665] Towards 1.0.0 again. --- ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala index 1b1ebdc6b2..73a88b396c 100644 --- a/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala @@ -10,7 +10,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "1.0.0-M5" + val current: String = "1.0.0-SNAPSHOT" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" From ecd52f4dd5c1aeee7fe766605659397dbc30b3a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 13 Jul 2018 11:38:56 +0200 Subject: [PATCH 0801/2665] [no-master] Fix #3408: Survive concurrent calls to `send` and `receive`. --- .../org/scalajs/jsenv/test/NodeJSTest.scala | 31 +++++++ .../jsenv/nodejs/AbstractNodeJSEnv.scala | 82 ++++++++++++++----- 2 files changed, 94 insertions(+), 19 deletions(-) diff --git a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/NodeJSTest.scala b/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/NodeJSTest.scala index f8fe024091..4047286e31 100644 --- a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/NodeJSTest.scala +++ b/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/NodeJSTest.scala @@ -76,4 +76,35 @@ class NodeJSTest extends TimeoutComTests { com.await(DefaultTimeout) } + @Test + def testConcurrentSendReceive_issue3408: Unit = { + for (_ <- 0 until 50) { + val com = comRunner(""" + scalajsCom.init(function(msg) { + scalajsCom.send("pong: " + msg); + }); + """) + + start(com) + + // Try very hard to send and receive at the same time + val lock = new AnyRef + val threadSend = new Thread { + override def run(): Unit = { + lock.synchronized(lock.wait()) + com.send("ping") + } + } + threadSend.start() + + Thread.sleep(200L) + lock.synchronized(lock.notifyAll()) + assertEquals(com.receive(), "pong: ping") + + threadSend.join() + com.close() + com.await(DefaultTimeout) + } + } + } diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala index 83a5b463dd..8fde820763 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala @@ -9,6 +9,8 @@ package org.scalajs.jsenv.nodejs +import scala.annotation.tailrec + import java.io.{Console => _, _} import java.net._ @@ -153,8 +155,17 @@ abstract class AbstractNodeJSEnv( protected trait NodeComJSRunner extends ComJSRunner with JSInitFiles { + /* Manipulation of the socket must be protected by synchronized, except + * calls to `close()`. + */ private[this] val serverSocket = new ServerSocket(0, 0, InetAddress.getByName(null)) // Loopback address + + /* Those 3 fields are assigned *once* under synchronization in + * `awaitConnection()`. + * Read access must be protected by synchronized, or be done after a + * successful call to `awaitConnection()`. + */ private var comSocket: Socket = _ private var jvm2js: DataOutputStream = _ private var js2jvm: DataInputStream = _ @@ -280,34 +291,67 @@ abstract class AbstractNodeJSEnv( } def close(): Unit = { + /* Close the socket first. This will cause any existing and upcoming + * calls to `awaitConnection()` to be canceled and throw a + * `SocketException` (unless it has already successfully completed the + * `accept()` call). + */ serverSocket.close() - if (jvm2js != null) - jvm2js.close() - if (js2jvm != null) - js2jvm.close() - if (comSocket != null) - comSocket.close() + + /* Now wait for a possibly still-successful `awaitConnection()` to + * complete before closing the sockets. + */ + synchronized { + if (comSocket != null) { + jvm2js.close() + js2jvm.close() + comSocket.close() + } + } } /** Waits until the JS VM has established a connection or terminates * * @return true if the connection was established */ - private def awaitConnection(): Boolean = { - serverSocket.setSoTimeout(acceptTimeout) - while (comSocket == null && isRunning) { - try { - comSocket = serverSocket.accept() - jvm2js = new DataOutputStream( - new BufferedOutputStream(comSocket.getOutputStream())) - js2jvm = new DataInputStream( - new BufferedInputStream(comSocket.getInputStream())) - } catch { - case to: SocketTimeoutException => + private def awaitConnection(): Boolean = synchronized { + if (comSocket != null) { + true + } else { + @tailrec + def acceptLoop(): Option[Socket] = { + if (!isRunning) { + None + } else { + try { + Some(serverSocket.accept()) + } catch { + case to: SocketTimeoutException => acceptLoop() + } + } } - } - comSocket != null + serverSocket.setSoTimeout(acceptTimeout) + val optComSocket = acceptLoop() + + optComSocket.fold { + false + } { comSocket0 => + val jvm2js0 = new DataOutputStream( + new BufferedOutputStream(comSocket0.getOutputStream())) + val js2jvm0 = new DataInputStream( + new BufferedInputStream(comSocket0.getInputStream())) + + /* Assign those three fields together, without the possibility of + * an exception happening in the middle (see #3408). + */ + comSocket = comSocket0 + jvm2js = jvm2js0 + js2jvm = js2jvm0 + + true + } + } } override protected def finalize(): Unit = close() From 6746cf3a20d2497bbc6c520666a47f7ec1cd28dd Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 21 Jul 2018 12:00:28 +0200 Subject: [PATCH 0802/2665] Fix #3410: Add supportsExit to JSEnvSuiteConfig. We also remove terminateVMJSCode. This is a source breaking change. However, leaving withTerminateVMJSCode would not relieve any burden of sub-projects as the Suite would fail anyways. --- .../scala/org/scalajs/jsenv/test/ComTests.scala | 6 +++--- .../org/scalajs/jsenv/test/JSEnvSuiteConfig.scala | 13 +++++++------ .../scala/org/scalajs/jsenv/test/RunTests.scala | 4 ++-- .../org/scalajs/jsenv/nodejs/NodeJSSuite.scala | 5 +---- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala index 5eeed6f0ab..4e4e23a1b0 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala @@ -38,10 +38,10 @@ private[test] class ComTests(config: JSEnvSuiteConfig) { @Test def jsExitsOnMessageTest: Unit = { - assumeTrue(config.terminateVMJSCode.isDefined) + assumeTrue(config.supportsExit) - val run = kit.start(s""" - scalajsCom.init(function(msg) { ${config.terminateVMJSCode.get}; }); + val run = kit.start(""" + scalajsCom.init(function(msg) { __ScalaJSEnv.exitFunction(0); }); for (var i = 0; i < 10; ++i) scalajsCom.send("msg: " + i); """, RunConfig()) diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvSuiteConfig.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvSuiteConfig.scala index 73323ad097..9968a4948a 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvSuiteConfig.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvSuiteConfig.scala @@ -26,7 +26,7 @@ import scala.concurrent.duration._ */ final class JSEnvSuiteConfig private ( val jsEnv: JSEnv, - val terminateVMJSCode: Option[String], + val supportsExit: Boolean, val supportsCom: Boolean, val supportsTimeout: Boolean, val awaitTimeout: FiniteDuration, @@ -34,15 +34,15 @@ final class JSEnvSuiteConfig private ( ) { private def this(jsEnv: JSEnv) = this( jsEnv = jsEnv, - terminateVMJSCode = None, + supportsExit = true, supportsCom = true, supportsTimeout = true, awaitTimeout = 1.minute, description = jsEnv.name ) - def withTerminateVMJSCode(code: String): JSEnvSuiteConfig = - copy(terminateVMJSCode = Some(code)) + def withSupportsExit(supportsExit: Boolean): JSEnvSuiteConfig = + copy(supportsExit = supportsExit) def withSupportsCom(supportsCom: Boolean): JSEnvSuiteConfig = copy(supportsCom = supportsCom) @@ -56,12 +56,13 @@ final class JSEnvSuiteConfig private ( def withDescription(description: String): JSEnvSuiteConfig = copy(description = description) - private def copy(terminateVMJSCode: Option[String] = terminateVMJSCode, + private def copy( + supportsExit: Boolean = supportsExit, supportsCom: Boolean = supportsCom, supportsTimeout: Boolean = supportsTimeout, awaitTimeout: FiniteDuration = awaitTimeout, description: String = description) = { - new JSEnvSuiteConfig(jsEnv, terminateVMJSCode, supportsCom, + new JSEnvSuiteConfig(jsEnv, supportsExit, supportsCom, supportsTimeout, awaitTimeout, description) } } diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala index 53c298c903..1876c17728 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala @@ -44,9 +44,9 @@ private[test] class RunTests(config: JSEnvSuiteConfig, withCom: Boolean) { @Test def jsExitsTest: Unit = { - assumeTrue(config.terminateVMJSCode.isDefined) + assumeTrue(config.supportsExit) - val run = kit.start(config.terminateVMJSCode.get, RunConfig()) + val run = kit.start("__ScalaJSEnv.exitFunction(0);", RunConfig()) try { Await.result(run.future, config.awaitTimeout) } finally { diff --git a/nodejs-env/src/test/scala/org/scalajs/jsenv/nodejs/NodeJSSuite.scala b/nodejs-env/src/test/scala/org/scalajs/jsenv/nodejs/NodeJSSuite.scala index 631044758d..34f0994da3 100644 --- a/nodejs-env/src/test/scala/org/scalajs/jsenv/nodejs/NodeJSSuite.scala +++ b/nodejs-env/src/test/scala/org/scalajs/jsenv/nodejs/NodeJSSuite.scala @@ -5,7 +5,4 @@ import org.scalajs.jsenv.test._ import org.junit.runner.RunWith @RunWith(classOf[JSEnvSuiteRunner]) -class NodeJSSuite extends JSEnvSuite( - JSEnvSuiteConfig(new NodeJSEnv) - .withTerminateVMJSCode("process.exit(0)") -) +class NodeJSSuite extends JSEnvSuite(JSEnvSuiteConfig(new NodeJSEnv)) From c99fd917a70fdc7e24e3019a8c261644232d7a32 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 21 Jul 2018 12:05:03 +0200 Subject: [PATCH 0803/2665] Fix #3412: Throw an IOException in noThrowOnBadFileTest This makes sure no Scala version regard the failure as fatal (NotImplementedError was considered fatal in 2.10). Also it simply makes much more sense. --- .../src/main/scala/org/scalajs/jsenv/test/RunTests.scala | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala index 1876c17728..9c1113149d 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala @@ -118,10 +118,12 @@ private[test] class RunTests(config: JSEnvSuiteConfig, withCom: Boolean) { @Test def noThrowOnBadFileTest: Unit = { + def fail() = throw new java.io.IOException("exception for test") + val badFile = new VirtualBinaryFile { - def path: String = ??? - def exists: Boolean = ??? - def inputStream: java.io.InputStream = ??? + def path: String = fail() + def exists: Boolean = fail() + def inputStream: java.io.InputStream = fail() } // `start` may not throw but must fail asynchronously From 0bf8e180524f76a29e602633c6949370d06910cf Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 21 Jul 2018 12:20:52 +0200 Subject: [PATCH 0804/2665] Fix #3411: Do not call onMessage immediately after init This change contains a fix to this in the Node.js Com support and a test in the test suite for this. --- .../scalajs/jsenv/test/TimeoutComTests.scala | 17 +++++++++++++++++ .../org/scalajs/jsenv/nodejs/ComSupport.scala | 19 +++++++++++-------- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutComTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutComTests.scala index a7070177b2..52307ace8d 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutComTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutComTests.scala @@ -86,4 +86,21 @@ private[test] class TimeoutComTests(config: JSEnvSuiteConfig) { """, RunConfig()) run.closeAndWait() } + + @Test // #3411 + def noImmediateCallbackTest: Unit = { + val run = kit.start(s""" + setTimeout(function() { + var gotCalled = false; + scalajsCom.init(function(msg) { gotCalled = true; }); + if (gotCalled) throw "Buffered messages did not get deferred to the event loop"; + }, 100); + """, RunConfig()) + + try { + run.run.send("Hello World") + } finally { + run.closeAndWait() + } + } } diff --git a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/ComSupport.scala b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/ComSupport.scala index 5dadf32dfa..7a5fe3f2d0 100644 --- a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/ComSupport.scala +++ b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/ComSupport.scala @@ -251,7 +251,7 @@ object ComRun { | var inMessages = []; | | // The callback where received messages go - | var recvCallback = function(msg) { inMessages.push(msg); }; + | var onMessage = null; | | socket.on('data', function(data) { | inBuffer = Buffer.concat([inBuffer, data]); @@ -268,7 +268,8 @@ object ComRun { | | inBuffer = inBuffer.slice(byteLen); | - | recvCallback(res); + | if (inMessages !== null) inMessages.push(res); + | else onMessage(res); | } | }); | @@ -280,12 +281,14 @@ object ComRun { | socket.on('close', function() { process.exit(0); }); | | global.scalajsCom = { - | init: function(recvCB) { - | if (inMessages === null) throw new Error("Com already initialized"); - | for (var i = 0; i < inMessages.length; ++i) - | recvCB(inMessages[i]); - | inMessages = null; - | recvCallback = recvCB; + | init: function(onMsg) { + | if (onMessage !== null) throw new Error("Com already initialized"); + | onMessage = onMsg; + | process.nextTick(function() { + | for (var i = 0; i < inMessages.length; ++i) + | onMessage(inMessages[i]); + | inMessages = null; + | }); | }, | send: function(msg) { | var len = msg.length; From 65c123d2a016d08e28637b9796ed0bac7e0b3a60 Mon Sep 17 00:00:00 2001 From: vi-kas Date: Tue, 24 Jul 2018 17:12:57 +0530 Subject: [PATCH 0805/2665] [no-master] Fix #3417: Handle Windows file separator in VirtualFile.nameFromPath. --- .../main/scala/org/scalajs/core/tools/io/VirtualFiles.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala index b0830efade..23849532bc 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala @@ -45,7 +45,10 @@ trait VirtualFile { object VirtualFile { /** Splits at the last slash and returns remainder */ def nameFromPath(path: String): String = { - val pos = path.lastIndexOf('/') + val pos0 = path.lastIndexOf('/') + val pos = + if (pos0 >= 0) pos0 + else path.lastIndexOf('\\') if (pos == -1) path else path.substring(pos + 1) } From 869036da53c59eb997d213ff6b395097ee625478 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 24 Jul 2018 11:06:08 +0200 Subject: [PATCH 0806/2665] Fix #3415: Propagate the being-inlined set inside closures. When optimizing a `Closure` that was not inlined away, we would not propagate the set of methods already being inlined. That means that a lambda calling its enclosing method, if it was not inlined away itself, would cause an infinite recursion in the optimizer. --- project/BinaryIncompatibilities.scala | 3 ++ .../testsuite/compiler/OptimizerTest.scala | 30 ++++++++++++++ .../frontend/optimizer/OptimizerCore.scala | 39 +++++++++++++------ 3 files changed, 60 insertions(+), 12 deletions(-) diff --git a/project/BinaryIncompatibilities.scala b/project/BinaryIncompatibilities.scala index 553c491612..c5f14112cc 100644 --- a/project/BinaryIncompatibilities.scala +++ b/project/BinaryIncompatibilities.scala @@ -8,6 +8,9 @@ object BinaryIncompatibilities { ) val Tools = Seq( + // private[optimizer], not an issue + ProblemFilters.exclude[DirectMissingMethodProblem]( + "org.scalajs.core.tools.linker.frontend.optimizer.OptimizerCore.transformIsolatedBody") ) val JSEnvs = Seq( diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala index d4fcb54e9f..581f405981 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala @@ -436,6 +436,36 @@ class OptimizerTest { assertEquals("hello", escape(a)._1) } + + // Bug #3415 + + @Test def infinite_recursion_inlining_issue3415_original(): Unit = { + assumeTrue("linking only", false) + doWhile1("foo")(f => f(true)) + } + + @inline def doWhile1[Domain2](endDoWhile1: => Domain2)( + condition2: (Boolean => Domain2) => Domain2): Domain2 = { + condition2 { (conditionValue2) => + if (conditionValue2) + doWhile1[Domain2](endDoWhile1)(condition2) + else + endDoWhile1 + } + } + + @Test def infinite_recursion_inlining_issue3415_minimized(): Unit = { + assumeTrue("linking only", false) + doWhile(???) + } + + @inline def doWhile( + condition: js.Function1[js.Function1[Boolean, String], String]): String = { + condition { (conditionValue: Boolean) => + doWhile(condition) + } + } + } object OptimizerTest { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index b9c1ad6115..45a05ae6ee 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -136,7 +136,8 @@ private[optimizer] abstract class OptimizerCore( } val (newParams, newBody1) = try { - transformIsolatedBody(Some(myself), thisType, params, resultType, body) + transformIsolatedBody(Some(myself), thisType, params, resultType, body, + Set.empty) } catch { case _: TooManyRollbacksException => localNameAllocator.clear() @@ -144,7 +145,8 @@ private[optimizer] abstract class OptimizerCore( labelNameAllocator.clear() stateBackupChain = Nil disableOptimisticOptimizations = true - transformIsolatedBody(Some(myself), thisType, params, resultType, body) + transformIsolatedBody(Some(myself), thisType, params, resultType, + body, Set.empty) } val newBody = if (name.encodedName == "init___") tryElimStoreModule(newBody1) @@ -683,10 +685,10 @@ private[optimizer] abstract class OptimizerCore( private def transformClosureCommon(captureParams: List[ParamDef], params: List[ParamDef], body: Tree, newCaptureValues: List[Tree])( - implicit pos: Position): Closure = { + implicit scope: Scope, pos: Position): Closure = { - val (allNewParams, newBody) = - transformIsolatedBody(None, AnyType, captureParams ++ params, AnyType, body) + val (allNewParams, newBody) = transformIsolatedBody(None, AnyType, + captureParams ++ params, AnyType, body, scope.implsBeingInlined) val (newCaptureParams, newParams) = allNewParams.splitAt(captureParams.size) @@ -3766,7 +3768,8 @@ private[optimizer] abstract class OptimizerCore( def transformIsolatedBody(optTarget: Option[MethodID], thisType: Type, params: List[ParamDef], resultType: Type, - body: Tree): (List[ParamDef], Tree) = { + body: Tree, + alreadyInlining: Set[Scope.InliningID]): (List[ParamDef], Tree) = { val (paramLocalDefs, newParamDefs) = (for { p @ ParamDef(ident @ Ident(name, originalName), ptpe, mutable, rest) <- params } yield { @@ -3789,10 +3792,14 @@ private[optimizer] abstract class OptimizerCore( val allLocalDefs = thisLocalDef ++: paramLocalDefs - val allocationSites = List.fill(allLocalDefs.size)(AllocationSite.Anonymous) - val scope0 = optTarget.fold(Scope.Empty)( - target => Scope.Empty.inlining((allocationSites, target))) - val scope = scope0.withEnv(OptEnv.Empty.withLocalDefs(allLocalDefs)) + val inlining = optTarget.fold(alreadyInlining) { target => + val allocationSites = + List.fill(allLocalDefs.size)(AllocationSite.Anonymous) + alreadyInlining + ((allocationSites, target)) + } + val scope = Scope.Empty + .inlining(inlining) + .withEnv(OptEnv.Empty.withLocalDefs(allLocalDefs)) val newBody = transform(body, resultType == NoType)(scope) @@ -4412,17 +4419,25 @@ private[optimizer] object OptimizerCore { } private class Scope(val env: OptEnv, - val implsBeingInlined: Set[(List[AllocationSite], AbstractMethodID)]) { + val implsBeingInlined: Set[Scope.InliningID]) { def withEnv(env: OptEnv): Scope = new Scope(env, implsBeingInlined) - def inlining(impl: (List[AllocationSite], AbstractMethodID)): Scope = { + def inlining(impl: Scope.InliningID): Scope = { assert(!implsBeingInlined(impl), s"Circular inlining of $impl") new Scope(env, implsBeingInlined + impl) } + + def inlining(impls: Set[Scope.InliningID]): Scope = { + val intersection = implsBeingInlined.intersect(impls) + assert(intersection.isEmpty, s"Circular inlining of $intersection") + new Scope(env, implsBeingInlined ++ impls) + } } private object Scope { + type InliningID = (List[AllocationSite], AbstractMethodID) + val Empty: Scope = new Scope(OptEnv.Empty, Set.empty) } From 7dd91d0c36c1c598174f14c039a3ee964cc6ea58 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 22 Jul 2018 16:43:27 +0200 Subject: [PATCH 0807/2665] Backport exception tests from SeleniumJSEnv --- .../org/scalajs/jsenv/test/RunTests.scala | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala index 9c1113149d..4029cff665 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala @@ -28,6 +28,24 @@ private[test] class RunTests(config: JSEnvSuiteConfig, withCom: Boolean) { """.fails() } + @Test + def throwExceptionTest: Unit = { + """ + throw 1; + """.fails() + } + + @Test + def catchExceptionTest: Unit = { + """ + try { + throw "hello world"; + } catch (e) { + console.log(e); + } + """ hasOutput "hello world\n" + } + @Test // Failed in Phantom - #2053 def utf8Test: Unit = { """ From beeed615198b91506f6c4af427b93e7fbb2f8083 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 22 Jul 2018 17:26:54 +0200 Subject: [PATCH 0808/2665] Fix a typo in a method name --- .../main/scala/org/scalajs/jsenv/test/JSEnvSuiteConfig.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvSuiteConfig.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvSuiteConfig.scala index 9968a4948a..707912e837 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvSuiteConfig.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvSuiteConfig.scala @@ -50,7 +50,7 @@ final class JSEnvSuiteConfig private ( def withSupportsTimeout(supportsTimeout: Boolean): JSEnvSuiteConfig = copy(supportsTimeout = supportsTimeout) - def withAwaitTimepout(awaitTimeout: FiniteDuration): JSEnvSuiteConfig = + def withAwaitTimeout(awaitTimeout: FiniteDuration): JSEnvSuiteConfig = copy(awaitTimeout = awaitTimeout) def withDescription(description: String): JSEnvSuiteConfig = From d739fe6ec7d36e0f346381b36b675c25ec07bd69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 14 Aug 2018 21:46:10 +0200 Subject: [PATCH 0809/2665] Fix #3406: Use the JS pattern and flags for group detection. `Pattern` preprocesses the `pattern` string to extract some Java-specific features, such as in-line flags, before giving the patched patterns and flags to a `js.RegExp`. Before this commit, the logic for group recovery in `GroupStartMap` used the original pattern and flags. In this commit, we use the already processed pattern and flags instead, so that this preprocessing carries over to the regexes used for group recovery. --- .../scala/java/util/regex/GroupStartMap.scala | 8 ++----- .../main/scala/java/util/regex/Pattern.scala | 15 +++++++------ .../javalib/util/regex/RegexMatcherTest.scala | 21 ++++++++++++++++--- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/javalib/src/main/scala/java/util/regex/GroupStartMap.scala b/javalib/src/main/scala/java/util/regex/GroupStartMap.scala index 2792c0d0c3..81ca4f4c27 100644 --- a/javalib/src/main/scala/java/util/regex/GroupStartMap.scala +++ b/javalib/src/main/scala/java/util/regex/GroupStartMap.scala @@ -388,12 +388,8 @@ private[regex] class GroupStartMap(string: String, start: Int, pattern: Pattern) import Pattern.{CASE_INSENSITIVE, MULTILINE} val mapping: Int => Int = { - val node = parseRegex(pattern.pattern()) - val flags = { - "g" + - (if ((pattern.flags() & CASE_INSENSITIVE) != 0) "i" else "") + - (if ((pattern.flags() & MULTILINE) != 0) "m" else "") - } + val node = parseRegex(pattern.jsPattern) + val flags = pattern.jsFlags node.setNewGroup(1) val groupNodeMap = node.getGroupNodeMap node.transformGroupNumber(groupNodeMap.mapValues(_.newGroup).toMap) diff --git a/javalib/src/main/scala/java/util/regex/Pattern.scala b/javalib/src/main/scala/java/util/regex/Pattern.scala index f2255cab21..308e14b45f 100644 --- a/javalib/src/main/scala/java/util/regex/Pattern.scala +++ b/javalib/src/main/scala/java/util/regex/Pattern.scala @@ -12,6 +12,14 @@ final class Pattern private (jsRegExp: js.RegExp, _pattern: String, _flags: Int) def pattern(): String = _pattern def flags(): Int = _flags + private[regex] def jsPattern: String = jsRegExp.source + + private[regex] def jsFlags: String = { + (if (jsRegExp.global) "g" else "") + + (if (jsRegExp.ignoreCase) "i" else "") + + (if (jsRegExp.multiline) "m" else "") + } + override def toString(): String = pattern private[regex] def newJSRegExp(): js.RegExp = { @@ -26,12 +34,7 @@ final class Pattern private (jsRegExp: js.RegExp, _pattern: String, _flags: Int) * We therefore reconstruct the pattern and flags used to create * jsRegExp and create a new one from there. */ - val jsFlags = { - (if (jsRegExp.global) "g" else "") + - (if (jsRegExp.ignoreCase) "i" else "") + - (if (jsRegExp.multiline) "m" else "") - } - new js.RegExp(jsRegExp.source, jsFlags) + new js.RegExp(jsPattern, jsFlags) } } diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexMatcherTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexMatcherTest.scala index 6a0bcbb221..fb01d3beb2 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexMatcherTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexMatcherTest.scala @@ -85,6 +85,21 @@ class RegexMatcherTest { ) } + @Test def start_end_group_and_toMatchResult_with_inline_flags_issue3406(): Unit = { + val matcher = Pattern + .compile("(?i)(a).*(aa)") + .matcher("bBaccAaD") + checkGroups(matcher, + (2, 7, "accAa"), + (2, 3, "a"), + (5, 7, "Aa") + ) + + // Test case from the bug report + assertEquals(List("a", "A"), + "(?i)(a)".r.findAllMatchIn("aA").map(_.matched).toList) + } + def parseExpect(regex: String, str: String, pos: (Int, Int)*): Unit = { val matcher = Pattern.compile(regex).matcher(str) assertTrue(matcher.find()) @@ -151,9 +166,9 @@ class RegexMatcherTest { assertEquals(startEndMatch(0)._3, matcher.group) assertEquals(startEndMatch.size - 1, matcher.groupCount) for (((start, end, mtch), i) <- startEndMatch.zipWithIndex) { - assertEquals(start, matcher.start(i)) - assertEquals(end, matcher.end(i)) - assertEquals(mtch, matcher.group(i)) + assertEquals("" + i, start, matcher.start(i)) + assertEquals("" + i, end, matcher.end(i)) + assertEquals("" + i, mtch, matcher.group(i)) } val matchResult = matcher.toMatchResult From eaac45f831a77e25c99b29ed4acadb412396fb82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 13 Aug 2018 16:19:57 +0200 Subject: [PATCH 0810/2665] Fix #3426: Fully support lazy vals in non-native JS classes. This turned out to be relatively simple. There is only a little dance to correctly consider lazy *fields* as non-exposed, but the lazy *def* that accesses it as exposed, both in 2.11- and 2.12+. The commit also includes a better error message when trying to include a `lazy val` in a JS trait. The code previously failed to compile as well but with an obscure error message. --- .../org/scalajs/core/compiler/GenJSCode.scala | 12 ++- .../scalajs/core/compiler/GenJSExports.scala | 2 +- .../scalajs/core/compiler/PrepJSInterop.scala | 3 + .../core/compiler/test/JSOptionalTest.scala | 14 ++++ .../jsinterop/ScalaJSDefinedTest.scala | 84 +++++++++++++++++++ 5 files changed, 111 insertions(+), 4 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 4db7e5e219..8faa504fee 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -498,7 +498,7 @@ abstract class GenJSCode extends plugins.PluginComponent if (sym.isClassConstructor) { constructorTrees += dd - } else if (exposed && sym.isAccessor) { + } else if (exposed && sym.isAccessor && !sym.isLazy) { /* Exposed accessors must not be emitted, since the field they * access is enough. */ @@ -5582,8 +5582,14 @@ abstract class GenJSCode extends plugins.PluginComponent /** Tests whether the given member is exposed, i.e., whether it was * originally a public or protected member of a Scala.js-defined JS class. */ - private def isExposed(sym: Symbol): Boolean = - !sym.isBridge && sym.hasAnnotation(ExposedJSMemberAnnot) + private def isExposed(sym: Symbol): Boolean = { + !sym.isBridge && { + if (sym.isLazy) + sym.isAccessor && sym.accessed.hasAnnotation(ExposedJSMemberAnnot) + else + sym.hasAnnotation(ExposedJSMemberAnnot) + } + } /** Test whether `sym` is the symbol of a raw JS function definition */ private def isRawJSFunctionDef(sym: Symbol): Boolean = diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index 23ef7dcac4..9115cf4e95 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -324,7 +324,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => private def genJSClassDispatcher(classSym: Symbol, name: JSName): js.Tree = { val alts = classSym.info.members.toList.filter { sym => - !sym.isBridge && jsNameOf(sym) == name + sym.isMethod && !sym.isBridge && jsNameOf(sym) == name } assert(!alts.isEmpty, diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 55b3139a62..102a7048d5 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -1057,6 +1057,9 @@ abstract class PrepJSInterop extends plugins.PluginComponent if (sym.isMethod && isPrivateMaybeWithin(sym)) { reporter.error(tree.pos, "A Scala.js-defined JS trait cannot contain private members") + } else if (sym.isLazy) { + reporter.error(tree.pos, + "A Scala.js-defined JS trait cannot contain lazy vals") } else if (!sym.isDeferred) { /* Tell the back-end not emit this thing. In fact, this only * matters for mixed-in members created from this member. diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala index 12f340f3b9..10cf75a938 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala @@ -58,6 +58,20 @@ class JSOptionalTest extends DirectTest with TestHelpers { """ } + @Test + def noOptionalLazyVal: Unit = { + s""" + trait A extends js.Object { + lazy val a1: js.UndefOr[Int] = js.undefined + } + """ hasErrors + s""" + |newSource1.scala:6: error: A Scala.js-defined JS trait cannot contain lazy vals + | lazy val a1: js.UndefOr[Int] = js.undefined + | ^ + """ + } + @Test def noOverrideConcreteNonOptionalWithOptional: Unit = { """ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala index 946f4c8d9d..b8a25a1aca 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala @@ -206,6 +206,69 @@ class ScalaJSDefinedTest { assertNull(obj.asInstanceOf[js.Dynamic].valueClass) } + @Test def lazy_vals(): Unit = { + val obj1 = new LazyValFields() + assertEquals(0, obj1.initCount) + assertEquals(42, obj1.field) + assertEquals(1, obj1.initCount) + assertEquals(42, obj1.field) + assertEquals(1, obj1.initCount) + assertEquals(42, obj1.asInstanceOf[js.Dynamic].field) + assertEquals(1, obj1.initCount) + assertEquals(42, (obj1: LazyValFieldsSuperTrait).field) + assertEquals(1, obj1.initCount) + + val obj2 = new LazyValFields().asInstanceOf[js.Dynamic] + assertEquals(0, obj2.initCount) + assertEquals(42, obj2.field) + assertEquals(1, obj2.initCount) + assertEquals(42, obj2.field) + assertEquals(1, obj2.initCount) + assertEquals(42, obj2.asInstanceOf[LazyValFields].field) + assertEquals(1, obj2.initCount) + assertEquals(42, obj2.asInstanceOf[LazyValFieldsSuperTrait].field) + assertEquals(1, obj2.initCount) + + val obj3: LazyValFieldsSuperTrait = new LazyValFields() + assertEquals(0, obj3.initCount) + assertEquals(42, obj3.field) + assertEquals(1, obj3.initCount) + assertEquals(42, obj3.field) + assertEquals(1, obj3.initCount) + assertEquals(42, obj3.asInstanceOf[LazyValFields].field) + assertEquals(1, obj3.initCount) + assertEquals(42, obj3.asInstanceOf[js.Dynamic].field) + assertEquals(1, obj3.initCount) + } + + @Test def override_lazy_vals(): Unit = { + val obj1 = new OverrideLazyValFields() + assertEquals(0, obj1.initCount) + assertEquals(53, obj1.field) + assertEquals(1, obj1.initCount) + assertEquals(53, obj1.field) + assertEquals(1, obj1.initCount) + assertEquals(53, obj1.asInstanceOf[js.Dynamic].field) + assertEquals(1, obj1.initCount) + assertEquals(53, (obj1: LazyValFieldsSuperTrait).field) + assertEquals(1, obj1.initCount) + assertEquals(53, (obj1: LazyValFields).field) + assertEquals(1, obj1.initCount) + + val obj2 = new OverrideLazyValFields() + assertEquals(0, obj2.initCount) + assertEquals(53, (obj2: LazyValFields).field) + assertEquals(1, obj2.initCount) + assertEquals(53, obj2.field) + assertEquals(1, obj2.initCount) + assertEquals(53, obj2.field) + assertEquals(1, obj2.initCount) + assertEquals(53, obj2.asInstanceOf[js.Dynamic].field) + assertEquals(1, obj2.initCount) + assertEquals(53, (obj2: LazyValFieldsSuperTrait).field) + assertEquals(1, obj2.initCount) + } + @Test def simple_inherited_from_a_native_class(): Unit = { val obj = new SimpleInheritedFromNative(3, 5) assertEquals(3, obj.x) @@ -1826,6 +1889,27 @@ object ScalaJSDefinedTest { var valueClass: SomeValueClass = _ } + trait LazyValFieldsSuperTrait extends js.Object { + def initCount: Int + def field: Int + } + + class LazyValFields extends js.Object with LazyValFieldsSuperTrait { + var initCount: Int = 0 + + lazy val field: Int = { + initCount += 1 + 42 + } + } + + class OverrideLazyValFields extends LazyValFields { + override lazy val field: Int = { + initCount += 1 + 53 + } + } + class SimpleInheritedFromNative( x: Int, val y: Int) extends NativeParentClass(x) From 9d6078af1f6eeadc75101fd8490f32472b79c130 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 13 Aug 2018 11:07:03 +0200 Subject: [PATCH 0811/2665] Fix #3422: Support nulling-out lazy vals in non-native JS classes. We work around the `rhs.tpe eq null` caused by scalac by testing explicitly for this case, when the rhs is a literal `null`. It is decidedly ugly, but it gets the job done. --- .../org/scalajs/core/compiler/GenJSCode.scala | 14 ++++++++++++-- .../testsuite/jsinterop/ScalaJSDefinedTest.scala | 8 ++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 8faa504fee..4b3fbefba9 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -2009,8 +2009,18 @@ abstract class GenJSCode extends plugins.PluginComponent val genQual = genExpr(qualifier) def genBoxedRhs: js.Tree = { - ensureBoxed(genRhs, - enteringPhase(currentRun.posterasurePhase)(rhs.tpe)) + val tpeEnteringPosterasure = + enteringPhase(currentRun.posterasurePhase)(rhs.tpe) + if ((tpeEnteringPosterasure eq null) && genRhs.isInstanceOf[js.Null]) { + // 2.10.x does not yet have `devWarning`, so use `debugwarn` instead. + debugwarn( + "Working around https://github.com/scala-js/scala-js/issues/3422 " + + s"for ${sym.fullName} at ${sym.pos}") + // Fortunately, a literal `null` never needs to be boxed + genRhs + } else { + ensureBoxed(genRhs, tpeEnteringPosterasure) + } } if (isScalaJSDefinedJSClass(sym.owner)) { diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala index b8a25a1aca..ff0515b359 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala @@ -269,6 +269,10 @@ class ScalaJSDefinedTest { assertEquals(1, obj2.initCount) } + @Test def nullingOutLazyValField_issue3422(): Unit = { + assertEquals("foo", new NullingOutLazyValFieldBug3422("foo").str) + } + @Test def simple_inherited_from_a_native_class(): Unit = { val obj = new SimpleInheritedFromNative(3, 5) assertEquals(3, obj.x) @@ -1910,6 +1914,10 @@ object ScalaJSDefinedTest { } } + class NullingOutLazyValFieldBug3422(initStr: String) extends js.Object { + lazy val str: String = initStr + } + class SimpleInheritedFromNative( x: Int, val y: Int) extends NativeParentClass(x) From 3ab897e5866de714a59755db9d535ee95295dd1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 15 Aug 2018 20:20:11 +0200 Subject: [PATCH 0812/2665] [no-master] Preserve backward bincompat of lazy vals in JS classes. We do this at the cost of breaking the semantics of `override lazy val`s. --- .../scala/org/scalajs/core/compiler/GenJSCode.scala | 13 ++++++++++++- .../testsuite/jsinterop/ScalaJSDefinedTest.scala | 4 ++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index 4b3fbefba9..5b530ea153 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -2665,7 +2665,18 @@ abstract class GenJSCode extends plugins.PluginComponent if (sym.owner == StringClass && !isStringMethodFromObject) { genStringCall(tree) } else if (isRawJSType(receiver.tpe) && sym.owner != ObjectClass) { - if (!isScalaJSDefinedJSClass(sym.owner) || isExposed(sym)) + /* The !sym.isLazy test is intentionally bogus, to preserve backward + * binary compatibility at the cost of not correctly handling + * `override lazy val`s. + * + * It will cause the call site to directly access the internal accessor + * with a static call, rather than the JS getter using dynamic + * dispatch. This is necessary for bincompat, because Scala.js 0.6.24 + * and earlier did not generate a getter for the JS access, only a + * field (which does not trigger the initialization of the field when + * it hasn't been done yet). + */ + if (!isScalaJSDefinedJSClass(sym.owner) || (isExposed(sym) && !sym.isLazy)) genPrimitiveJSCall(tree, isStat) else genApplyJSClassMethod(genExpr(receiver), sym, genActualArgs(sym, args)) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala index ff0515b359..d4621cd25e 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala @@ -242,6 +242,10 @@ class ScalaJSDefinedTest { } @Test def override_lazy_vals(): Unit = { + assumeTrue( + "intentionally broken to preserve backward binary compatibility", + false) + val obj1 = new OverrideLazyValFields() assertEquals(0, obj1.initCount) assertEquals(53, obj1.field) From 7b5b58390393c5c0b79fd5c6915ad7610ab3cb5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 18 Aug 2018 17:33:44 +0200 Subject: [PATCH 0813/2665] [no-master] Do not test the test suite in fullOpt with PhantomJS. PhantomJS tests spuriously fail too often, and it seems in particular in fullOpt. This commit removes the fullOpt tests of the test suite with PhantomJS, hopefully reducing spurious failures. --- Jenkinsfile | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index f3a727b3b7..e39a6135cf 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -214,10 +214,6 @@ def Tasks = [ $testSuite/clean && sbtretry 'set inScope(ThisScope in $testSuite)(jsEnv := new org.scalajs.jsenv.RetryingComJSEnv(PhantomJSEnv().value))' \ 'set parallelExecution in ($testSuite, Test) := false' \ - ++$scala $testSuite/test && - sbtretry 'set inScope(ThisScope in $testSuite)(jsEnv := new org.scalajs.jsenv.RetryingComJSEnv(PhantomJSEnv().value))' \ - 'set parallelExecution in ($testSuite, Test) := false' \ - 'set scalaJSStage in Global := FullOptStage' \ ++$scala $testSuite/test \ $testSuite/clean && sbtretry 'set scalacOptions in $testSuite += "-Xexperimental"' \ From d72b454a8fe3d7c9d9f79a25efc853a60d9926eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 18 Aug 2018 13:29:57 +0200 Subject: [PATCH 0814/2665] Deprecate org.scalajs.testinterface.TestUtils and ScalaJSClassLoader. In favor of * `scala.scalajs.reflect.Reflect` for JS-only code, or * `portable-scala-reflect` for portable code. --- .../scala/org/scalajs/junit/JUnitTask.scala | 9 +++++-- sbt-plugin-test/build.sbt | 2 +- .../scala/sbttest/framework/Platform.scala | 17 ++++++++++++ .../scala/sbttest/framework/Platform.scala | 13 ++++++++++ .../scala/sbttest/framework/BaseRunner.scala | 0 .../sbttest/framework/DummyFramework.scala | 0 .../scala/sbttest/framework/DummyTask.scala | 8 +++--- .../sbttest/framework/MasterRunner.scala | 0 .../scala/sbttest/framework/SlaveRunner.scala | 0 .../main/scala/sbttest/framework/Test.scala | 0 .../org/scalajs/testinterface/TestUtils.scala | 3 +++ .../testinterface/ScalaJSClassLoader.scala | 26 ++++++++++++++----- .../org/scalajs/testinterface/TestUtils.scala | 5 ++++ .../scalajs/testsuite/junit/JUnitUtil.scala | 10 ++++--- 14 files changed, 75 insertions(+), 18 deletions(-) create mode 100644 sbt-plugin-test/testFramework/js/src/main/scala/sbttest/framework/Platform.scala create mode 100644 sbt-plugin-test/testFramework/jvm/src/main/scala/sbttest/framework/Platform.scala rename sbt-plugin-test/testFramework/{ => shared}/src/main/scala/sbttest/framework/BaseRunner.scala (100%) rename sbt-plugin-test/testFramework/{ => shared}/src/main/scala/sbttest/framework/DummyFramework.scala (100%) rename sbt-plugin-test/testFramework/{ => shared}/src/main/scala/sbttest/framework/DummyTask.scala (87%) rename sbt-plugin-test/testFramework/{ => shared}/src/main/scala/sbttest/framework/MasterRunner.scala (100%) rename sbt-plugin-test/testFramework/{ => shared}/src/main/scala/sbttest/framework/SlaveRunner.scala (100%) rename sbt-plugin-test/testFramework/{ => shared}/src/main/scala/sbttest/framework/Test.scala (100%) diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTask.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTask.scala index 0f36fd97d5..f087bcfef2 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTask.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTask.scala @@ -3,7 +3,7 @@ package org.scalajs.junit import com.novocode.junit.{Ansi, RichLogger} import Ansi._ import sbt.testing._ -import org.scalajs.testinterface.TestUtils +import scala.scalajs.reflect.Reflect import scala.util.{Try, Success, Failure} final class JUnitTask(val taskDef: TaskDef, runner: JUnitBaseRunner) @@ -41,7 +41,12 @@ final class JUnitTask(val taskDef: TaskDef, runner: JUnitBaseRunner) eventHandler.handle(ev) } - Try(TestUtils.loadModule(bootstrapperName, runner.testClassLoader)) match { + Try { + Reflect + .lookupLoadableModuleClass(bootstrapperName + "$") + .getOrElse(throw new ClassNotFoundException(s"Cannot find $bootstrapperName$$")) + .loadModule() + } match { case Success(classMetadata: JUnitTestBootstrapper) => new JUnitExecuteTest(taskDef, runner, classMetadata, richLogger, eventHandler).executeTests() diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index 810f45eb35..52916b83de 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -89,7 +89,7 @@ lazy val jetty9 = project.settings(baseSettings: _*). Jetty9Test.runSetting ) -lazy val testFramework = crossProject.crossType(CrossType.Pure). +lazy val testFramework = crossProject.crossType(CrossType.Full). settings(versionSettings: _*). settings(name := "Dummy cross JS/JVM test framework"). jsSettings( diff --git a/sbt-plugin-test/testFramework/js/src/main/scala/sbttest/framework/Platform.scala b/sbt-plugin-test/testFramework/js/src/main/scala/sbttest/framework/Platform.scala new file mode 100644 index 0000000000..76447187b5 --- /dev/null +++ b/sbt-plugin-test/testFramework/js/src/main/scala/sbttest/framework/Platform.scala @@ -0,0 +1,17 @@ +package sbttest.framework + +import scala.scalajs.reflect.Reflect + +/** Platform-specific implementations. + * + * A typical testing framework would use portable-scala-reflect instead. + */ +private[framework] object Platform { + def instantiateTestClass(fullName: String, classLoader: ClassLoader): Test = { + val cls = Reflect.lookupInstantiatableClass(fullName).getOrElse { + throw new ClassNotFoundException(s"Cannot find $fullName") + } + assert(classOf[Test].isAssignableFrom(cls.runtimeClass), fullName) + cls.newInstance().asInstanceOf[Test] + } +} diff --git a/sbt-plugin-test/testFramework/jvm/src/main/scala/sbttest/framework/Platform.scala b/sbt-plugin-test/testFramework/jvm/src/main/scala/sbttest/framework/Platform.scala new file mode 100644 index 0000000000..cc0abd82ff --- /dev/null +++ b/sbt-plugin-test/testFramework/jvm/src/main/scala/sbttest/framework/Platform.scala @@ -0,0 +1,13 @@ +package sbttest.framework + +/** Platform-specific implementations. + * + * A typical testing framework would use portable-scala-reflect instead. + */ +private[framework] object Platform { + def instantiateTestClass(fullName: String, classLoader: ClassLoader): Test = { + val cls = Class.forName(fullName, true, classLoader) + assert(classOf[Test].isAssignableFrom(cls), fullName) + cls.newInstance().asInstanceOf[Test] + } +} diff --git a/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/BaseRunner.scala b/sbt-plugin-test/testFramework/shared/src/main/scala/sbttest/framework/BaseRunner.scala similarity index 100% rename from sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/BaseRunner.scala rename to sbt-plugin-test/testFramework/shared/src/main/scala/sbttest/framework/BaseRunner.scala diff --git a/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/DummyFramework.scala b/sbt-plugin-test/testFramework/shared/src/main/scala/sbttest/framework/DummyFramework.scala similarity index 100% rename from sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/DummyFramework.scala rename to sbt-plugin-test/testFramework/shared/src/main/scala/sbttest/framework/DummyFramework.scala diff --git a/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/DummyTask.scala b/sbt-plugin-test/testFramework/shared/src/main/scala/sbttest/framework/DummyTask.scala similarity index 87% rename from sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/DummyTask.scala rename to sbt-plugin-test/testFramework/shared/src/main/scala/sbttest/framework/DummyTask.scala index 0082ada2a8..ad044d1290 100644 --- a/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/DummyTask.scala +++ b/sbt-plugin-test/testFramework/shared/src/main/scala/sbttest/framework/DummyTask.scala @@ -2,8 +2,6 @@ package sbttest.framework import sbt.testing._ -import org.scalajs.testinterface.TestUtils - import scala.concurrent.ExecutionContext.Implicits.global final class DummyTask( @@ -15,9 +13,9 @@ final class DummyTask( def execute(eventHandler: EventHandler, loggers: Array[Logger]): Array[Task] = { try { - // Just create a new instance. - val inst = TestUtils.newInstance(taskDef.fullyQualifiedName, - runner.testClassLoader, Seq())(Seq()) + // Just create a new instance of the test class, for its side effects. + Platform.instantiateTestClass(taskDef.fullyQualifiedName, + runner.testClassLoader) eventHandler.handle(new DummyEvent(taskDef, None)) loggers.foreach(_.info(s"Success: ${taskDef.fullyQualifiedName}")) diff --git a/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/MasterRunner.scala b/sbt-plugin-test/testFramework/shared/src/main/scala/sbttest/framework/MasterRunner.scala similarity index 100% rename from sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/MasterRunner.scala rename to sbt-plugin-test/testFramework/shared/src/main/scala/sbttest/framework/MasterRunner.scala diff --git a/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/SlaveRunner.scala b/sbt-plugin-test/testFramework/shared/src/main/scala/sbttest/framework/SlaveRunner.scala similarity index 100% rename from sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/SlaveRunner.scala rename to sbt-plugin-test/testFramework/shared/src/main/scala/sbttest/framework/SlaveRunner.scala diff --git a/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/Test.scala b/sbt-plugin-test/testFramework/shared/src/main/scala/sbttest/framework/Test.scala similarity index 100% rename from sbt-plugin-test/testFramework/src/main/scala/sbttest/framework/Test.scala rename to sbt-plugin-test/testFramework/shared/src/main/scala/sbttest/framework/Test.scala diff --git a/stubs/src/main/scala/org/scalajs/testinterface/TestUtils.scala b/stubs/src/main/scala/org/scalajs/testinterface/TestUtils.scala index 6ed1561321..cff0081913 100644 --- a/stubs/src/main/scala/org/scalajs/testinterface/TestUtils.scala +++ b/stubs/src/main/scala/org/scalajs/testinterface/TestUtils.scala @@ -11,6 +11,9 @@ private object Compat210 { import Compat210._ +@deprecated( + "Use https://github.com/portable-scala/portable-scala-reflect instead.", + "0.6.25") object TestUtils { import scala.reflect.macros._ // shadows blackbox from above import blackbox.Context diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/ScalaJSClassLoader.scala b/test-interface/src/main/scala/org/scalajs/testinterface/ScalaJSClassLoader.scala index fc30c0f27d..af24f9150d 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/ScalaJSClassLoader.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/ScalaJSClassLoader.scala @@ -6,16 +6,30 @@ import java.net.URL import java.io.InputStream import java.util.Enumeration -/** A dummy [[java.lang.ClassLoader]] that allows to store a JavaScript object - * against which classes are resolved. The only reason it extends - * [[java.lang.ClassLoader]] is typing. +/** DEPRECATED A dummy [[java.lang.ClassLoader]] that allows to store a + * JavaScript object against which classes are resolved. + * + * The only reason it extends [[java.lang.ClassLoader]] is typing. + * + * @note + * `ScalaJSClassLoader` is deprecated, although it is not annotated with + * `@deprecated` for internal reasons. Use the reflection API in + * [[scala.scalajs.reflect.Reflect]] instead of matching against + * `ScalaJSClassLoader`. */ final class ScalaJSClassLoader( + @deprecated( + "Use scala.scalajs.reflect.Reflect instead of ScalaJSClassLoader.", + "0.6.25") val namespace: js.Dynamic) extends ClassLoader(null) { - private def nimp: Nothing = - throw new NotImplementedError("A ScalaJSClassLoader is a dummy. " + - "Use scala.scalajs.testinterface.TestUtils to instantiate things.") + private def nimp: Nothing = { + throw new NotImplementedError( + "A ScalaJSClassLoader is a dummy. " + + "Use scala.scalajs.reflect.Reflect (JS-only) or " + + "https://github.com/portable-scala/portable-scala-reflect (portable) " + + "to instantiate things.") + } override def clearAssertionStatus(): Unit = nimp override def getResource(name: String): URL = nimp diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/TestUtils.scala b/test-interface/src/main/scala/org/scalajs/testinterface/TestUtils.scala index 27a5b62937..d4c0903a1b 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/TestUtils.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/TestUtils.scala @@ -3,6 +3,11 @@ package org.scalajs.testinterface import scala.scalajs.js import scala.scalajs.reflect._ +@deprecated( + "Use scala.scalajs.reflect.Reflect (JS-only) or " + + "https://github.com/portable-scala/portable-scala-reflect (portable) " + + "instead.", + "0.6.25") object TestUtils { /** Instantiates the class given by its fully qualified name. diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala index dfdc3295c5..fb70dba016 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala @@ -3,7 +3,7 @@ package org.scalajs.testsuite.junit import org.scalajs.junit.JUnitTestBootstrapper import org.junit.Assert.fail -import org.scalajs.testinterface._ +import scala.scalajs.reflect.Reflect object JUnitUtil { private final val BootstrapperSuffix = "$scalajs$junit$bootstrapper" @@ -11,9 +11,11 @@ object JUnitUtil { def loadBootstrapper(classFullName: String): JUnitTestBootstrapper = { val fullName = s"$classFullName$BootstrapperSuffix" try { - val loader = new ScalaJSClassLoader( - scala.scalajs.runtime.environmentInfo.exportsNamespace) - TestUtils.loadModule(fullName, loader).asInstanceOf[JUnitTestBootstrapper] + Reflect + .lookupLoadableModuleClass(fullName + "$") + .getOrElse(throw new ClassNotFoundException(s"Cannot find $fullName$$")) + .loadModule() + .asInstanceOf[JUnitTestBootstrapper] } catch { case ex: Throwable => throw new AssertionError(s"could not load $fullName: ${ex.getMessage}") From 2f1197d84ed5cf42022c341787b987028d59d016 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sun, 12 Aug 2018 20:07:33 +0200 Subject: [PATCH 0815/2665] Fix #3420: Make timeout tests less restrictive Originally they were written to test our own implementation of `setTimeout` for Rhino. Now they are just a means to run things after returning to the event loop once, so we can reduce them significantly. --- .../scalajs/jsenv/test/TimeoutComTests.scala | 17 +-- .../scalajs/jsenv/test/TimeoutRunTests.scala | 104 ++---------------- 2 files changed, 18 insertions(+), 103 deletions(-) diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutComTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutComTests.scala index 52307ace8d..6e546e6ef1 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutComTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutComTests.scala @@ -19,6 +19,7 @@ private[test] class TimeoutComTests(config: JSEnvSuiteConfig) { @Test def delayedInitTest: Unit = { + val deadline = 100.millis.fromNow val run = kit.start(s""" setTimeout(function() { scalajsCom.init(function(msg) { @@ -28,9 +29,6 @@ private[test] class TimeoutComTests(config: JSEnvSuiteConfig) { """, RunConfig()) try { - // Deadline only starts now. Execution must happen asynchronously. - val deadline = 100.millis.fromNow - run.run.send("Hello World") assertEquals("Got: Hello World", run.waitNextMessage()) assertTrue("Execution took too little time", deadline.isOverdue()) @@ -49,7 +47,7 @@ private[test] class TimeoutComTests(config: JSEnvSuiteConfig) { try { for (i <- 1 to 10) { - val deadline = 190.millis.fromNow // give some slack + val deadline = 200.millis.fromNow run.run.send(s"Hello World: $i") assertEquals(s"Got: Hello World: $i", run.waitNextMessage()) assertTrue("Execution took too little time", deadline.isOverdue()) @@ -61,14 +59,19 @@ private[test] class TimeoutComTests(config: JSEnvSuiteConfig) { @Test def intervalSendTest: Unit = { + val deadline = 250.millis.fromNow + val run = kit.start(s""" scalajsCom.init(function(msg) {}); - var interval = setInterval(scalajsCom.send, 50, "Hello"); - setTimeout(clearInterval, 295, interval); + var sent = 0 + var interval = setInterval(function () { + scalajsCom.send("Hello"); + sent++; + if (sent >= 5) clearInterval(interval); + }, 50); """, RunConfig()) try { - val deadline = 245.millis.fromNow for (i <- 1 to 5) assertEquals("Hello", run.waitNextMessage()) diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutRunTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutRunTests.scala index 3c36b2de7a..5a3e89e7b1 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutRunTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutRunTests.scala @@ -38,110 +38,22 @@ private[test] class TimeoutRunTests(config: JSEnvSuiteConfig, withCom: Boolean) } - @Test - def clearTimeoutTest: Unit = { - - val deadline = 300.millis.fromNow - - """ - var c = setTimeout(function() { console.log("1"); }, 200); - setTimeout(function() { - console.log("2"); - clearTimeout(c); - }, 100); - setTimeout(function() { console.log("3"); }, 300); - setTimeout(function() { console.log("4"); }, 0); - """ hasOutput - """|4 - |2 - |3 - |""".stripMargin - - assertTrue("Execution took too little time", deadline.isOverdue()) - - } - - @Test // #2368 - def timeoutSingleArgTest: Unit = { - """ - setTimeout(function() { console.log("ok"); }); - """ hasOutput "ok\n" - } - - @Test - def timeoutArgTest: Unit = { - - val deadline = 300.millis.fromNow - - """ - setTimeout(function(a, b) { console.log("1" + a + b); }, 200, "foo", "bar"); - setTimeout(function() { console.log("2"); }, 100); - setTimeout(function(msg) { console.log(msg); }, 300, "Hello World"); - setTimeout(function() { console.log("4"); }, 0); - """ hasOutput - """|4 - |2 - |1foobar - |Hello World - |""".stripMargin - - assertTrue("Execution took too little time", deadline.isOverdue()) - - } - @Test def intervalTest: Unit = { + val deadline = 100.millis.fromNow - val deadline = 1.second.fromNow - + // We rely on the test kit to terminate the test after 5 iterations. """ - var i1 = setInterval(function() { console.log("each 2200"); }, 2200); - var i2 = setInterval(function() { console.log("each 3100"); }, 3100); - var i3 = setInterval(function() { console.log("each 1300"); }, 1300); - - setTimeout(function() { - clearInterval(i1); - clearInterval(i2); - clearInterval(i3); - }, 10000); + setInterval(function() { console.log("tick"); }, 20); """ hasOutput - """|each 1300 - |each 2200 - |each 1300 - |each 3100 - |each 1300 - |each 2200 - |each 1300 - |each 3100 - |each 1300 - |each 2200 - |each 1300 - |each 2200 - |each 1300 - |each 3100 + """|tick + |tick + |tick + |tick + |tick |""".stripMargin assertTrue("Execution took too little time", deadline.isOverdue()) } - - @Test - def intervalSelfClearTest: Unit = { - - val deadline = 100.millis.fromNow - - """ - var c = 0; - var i = setInterval(function() { - c++; - console.log(c.toString()); - if (c >= 10) - clearInterval(i); - }, 10); - """ hasOutput (1 to 10).map(_ + "\n").mkString - - assertTrue("Execution took too little time", deadline.isOverdue()) - - } - } From 9dc0501625fe415bcc391362979ec1854fafd10c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 25 Aug 2018 19:31:21 +0200 Subject: [PATCH 0816/2665] Mark all JUnit assertion and assumption methods as `@noinline`. This produces much better reports, because the JUnit "renderer" highlights stack trace elements that do not belong to JUnit methods. If the entry points to JUnit are inlined, the detection is flawed. --- .../src/main/scala/org/junit/Assert.scala | 54 +++++++++++++++++++ .../src/main/scala/org/junit/Assume.scala | 9 ++++ 2 files changed, 63 insertions(+) diff --git a/junit-runtime/src/main/scala/org/junit/Assert.scala b/junit-runtime/src/main/scala/org/junit/Assert.scala index 7441af78ab..d3c321b303 100644 --- a/junit-runtime/src/main/scala/org/junit/Assert.scala +++ b/junit-runtime/src/main/scala/org/junit/Assert.scala @@ -9,27 +9,34 @@ import org.hamcrest.Matcher import org.hamcrest.MatcherAssert object Assert { + @noinline def assertTrue(message: String, condition: Boolean): Unit = { if (!condition) fail(message) } + @noinline def assertTrue(condition: Boolean): Unit = assertTrue(null, condition) + @noinline def assertFalse(message: String, condition: Boolean): Unit = assertTrue(message, !condition) + @noinline def assertFalse(condition: Boolean): Unit = assertFalse(null, condition) + @noinline def fail(message: String): Unit = if (message eq null) throw new AssertionError() else throw new AssertionError(message) + @noinline def fail(): Unit = fail(null) + @noinline def assertEquals(message: String, expected: Any, actual: Any): Unit = { if (!equalsRegardingNull(expected, actual)) { (expected, actual) match { @@ -52,14 +59,17 @@ object Assert { private def isEquals(expected: Any, actual: Any): Boolean = expected.equals(actual) + @noinline def assertEquals(expected: Any, actual: Any): Unit = assertEquals(null, expected, actual) + @noinline def assertNotEquals(message: String, unexpected: Any, actual: Any): Unit = { if (equalsRegardingNull(unexpected, actual)) failEquals(message, actual) } + @noinline def assertNotEquals(unexpected: Any, actual: Any): Unit = assertNotEquals(null, unexpected, actual) @@ -71,28 +81,34 @@ object Assert { fail(s"$checkedMessage. Actual: $actual") } + @noinline def assertNotEquals(message: String, unexpected: Long, actual: Long): Unit = { if (unexpected == actual) failEquals(message, actual) } + @noinline def assertNotEquals(unexpected: Long, actual: Long): Unit = assertNotEquals(null, unexpected, actual) + @noinline def assertNotEquals(message: String, unexpected: Double, actual: Double, delta: Double): Unit = { if (!doubleIsDifferent(unexpected, actual, delta)) failEquals(message, actual) } + @noinline def assertNotEquals(unexpected: Double, actual: Double, delta: Double): Unit = assertNotEquals(null, unexpected, actual, delta) + @noinline def assertNotEquals(unexpected: Float, actual: Float, delta: Float): Unit = assertNotEquals(null, unexpected, actual, delta) @deprecated("Use assertEquals(double expected, double actual, double " + "epsilon) instead", "") + @noinline def assertEquals(expected: Double, actual: Double): Unit = { fail("Use assertEquals(expected, actual, delta) to compare " + "floating-point numbers") @@ -100,94 +116,115 @@ object Assert { @deprecated("Use assertEquals(String message, double expected, double " + "actual, double epsilon) instead", "") + @noinline def assertEquals(message: String, expected: Double, actual: Double): Unit = { fail("Use assertEquals(expected, actual, delta) to compare " + "floating-point numbers") } + @noinline def assertEquals(expected: Long, actual: Long): Unit = assertEquals(null, expected, actual) + @noinline def assertEquals(message: String, expected: Long, actual: Long): Unit = assertEquals(message, expected: Any, actual: Any) + @noinline def assertArrayEquals(message: String, expecteds: Array[AnyRef], actuals: Array[AnyRef]): Unit = { internalArrayEquals(message, expecteds, actuals) } + @noinline def assertArrayEquals(expecteds: Array[AnyRef], actuals: Array[AnyRef]): Unit = { assertArrayEquals(null, expecteds, actuals) } + @noinline def assertArrayEquals(message: String, expecteds: Array[Boolean], actuals: Array[Boolean]): Unit = { internalArrayEquals(message, expecteds, actuals) } + @noinline def assertArrayEquals(expecteds: Array[Boolean], actuals: Array[Boolean]): Unit = { assertArrayEquals(null, expecteds, actuals) } + @noinline def assertArrayEquals(message: String, expecteds: Array[Byte], actuals: Array[Byte]): Unit = { internalArrayEquals(message, expecteds, actuals) } + @noinline def assertArrayEquals(expecteds: Array[Byte], actuals: Array[Byte]): Unit = assertArrayEquals(null, expecteds, actuals) + @noinline def assertArrayEquals(message: String, expecteds: Array[Char], actuals: Array[Char]): Unit = { internalArrayEquals(message, expecteds, actuals) } + @noinline def assertArrayEquals(expecteds: Array[Char], actuals: Array[Char]): Unit = assertArrayEquals(null, expecteds, actuals) + @noinline def assertArrayEquals(message: String, expecteds: Array[Short], actuals: Array[Short]): Unit = { internalArrayEquals(message, expecteds, actuals) } + @noinline def assertArrayEquals(expecteds: Array[Short], actuals: Array[Short]): Unit = { assertArrayEquals(null, expecteds, actuals) } + @noinline def assertArrayEquals(message: String, expecteds: Array[Int], actuals: Array[Int]): Unit = { internalArrayEquals(message, expecteds, actuals) } + @noinline def assertArrayEquals(expecteds: Array[Int], actuals: Array[Int]): Unit = assertArrayEquals(null, expecteds, actuals) + @noinline def assertArrayEquals(message: String, expecteds: Array[Long], actuals: Array[Long]): Unit = { internalArrayEquals(message, expecteds, actuals) } + @noinline def assertArrayEquals(expecteds: Array[Long], actuals: Array[Long]): Unit = assertArrayEquals(null, expecteds, actuals) + @noinline def assertArrayEquals(message: String, expecteds: Array[Double], actuals: Array[Double], delta: Double): Unit = { new InexactComparisonCriteria(delta).arrayEquals(message, expecteds, actuals) } + @noinline def assertArrayEquals(expecteds: Array[Double], actuals: Array[Double], delta: Double): Unit = { assertArrayEquals(null, expecteds, actuals, delta) } + @noinline def assertArrayEquals(message: String, expecteds: Array[Float], actuals: Array[Float], delta: Float): Unit = { new InexactComparisonCriteria(delta).arrayEquals(message, expecteds, actuals) } + @noinline def assertArrayEquals(expecteds: Array[Float], actuals: Array[Float], delta: Float): Unit = { assertArrayEquals(null, expecteds, actuals, delta) @@ -198,6 +235,7 @@ object Assert { new ExactComparisonCriteria().arrayEquals(message, expecteds, actuals) } + @noinline def assertEquals(message: String, expected: Double, actual: Double, delta: Double): Unit = { if (doubleIsDifferent(expected, actual, delta)) { @@ -205,6 +243,7 @@ object Assert { } } + @noinline def assertEquals(message: String, expected: Float, actual: Float, delta: Float): Unit = { if (floatIsDifferent(expected, actual, delta)) { @@ -212,6 +251,7 @@ object Assert { } } + @noinline def assertNotEquals(message: String, unexpected: Float, actual: Float, delta: Float): Unit = { if (!floatIsDifferent(unexpected, actual, delta)) @@ -226,23 +266,29 @@ object Assert { private def floatIsDifferent(f1: Float, f2: Float, delta: Float): Boolean = java.lang.Float.compare(f1, f2) != 0 && Math.abs(f1 - f2) > delta + @noinline def assertEquals(expected: Double, actual: Double, delta: Double): Unit = assertEquals(null, expected, actual, delta) + @noinline def assertEquals(expected: Float, actual: Float, delta: Float): Unit = assertEquals(null, expected, actual, delta) + @noinline def assertNotNull(message: String, obj: Any): Unit = assertTrue(message, obj != null) + @noinline def assertNotNull(obj: Any): Unit = assertNotNull(null, obj) + @noinline def assertNull(message: String, obj: Any): Unit = { if (obj != null) failNotNull(message, obj) } + @noinline def assertNull(obj: Any): Unit = assertNull(null, obj) @@ -251,19 +297,23 @@ object Assert { fail(s"${formatted}expected null, but was:<$actual}>") } + @noinline def assertSame(message: String, expected: Any, actual: Any): Unit = { if (expected.asInstanceOf[AnyRef] ne actual.asInstanceOf[AnyRef]) failNotSame(message, expected, actual) } + @noinline def assertSame(expected: Any, actual: Any): Unit = assertSame(null, expected, actual) + @noinline def assertNotSame(message: String, unexpected: Any, actual: Any): Unit = { if (unexpected.asInstanceOf[AnyRef] eq actual.asInstanceOf[AnyRef]) failSame(message) } + @noinline def assertNotSame(unexpected: Any, actual: Any): Unit = assertNotSame(null, unexpected, actual) @@ -303,9 +353,11 @@ object Assert { s"$className<$valueString>" } + @noinline def assertThat[T](actual: T, matcher: Matcher[T]): Unit = assertThat("", actual, matcher) + @noinline def assertThat[T](reason: String, actual: T, matcher: Matcher[T]): Unit = MatcherAssert.assertThat(reason, actual, matcher) @@ -313,11 +365,13 @@ object Assert { // is being tested in JUnitAssertionTest until 4.13 is released. /* + @noinline def assertThrows(expectedThrowable: Class[_ <: Throwable], runnable: ThrowingRunnable): Unit = { expectThrows(expectedThrowable, runnable) } + @noinline def expectThrows[T <: Throwable](expectedThrowable: Class[T], runnable: ThrowingRunnable): T = { try { runnable.run() diff --git a/junit-runtime/src/main/scala/org/junit/Assume.scala b/junit-runtime/src/main/scala/org/junit/Assume.scala index 09ae3c6952..ba9bdf8011 100644 --- a/junit-runtime/src/main/scala/org/junit/Assume.scala +++ b/junit-runtime/src/main/scala/org/junit/Assume.scala @@ -10,34 +10,43 @@ import org.hamcrest.Matcher object Assume { + @noinline def assumeTrue(b: Boolean): Unit = assumeThat(b, is(true)) + @noinline def assumeFalse(b: Boolean): Unit = assumeTrue(!b) + @noinline def assumeTrue(message: String, b: Boolean): Unit = if (!b) throw new AssumptionViolatedException(message) + @noinline def assumeFalse(message: String, b: Boolean): Unit = assumeTrue(message, !b) + @noinline def assumeNotNull(objects: AnyRef*): Unit = objects.foreach(assumeThat(_, notNullValue())) + @noinline def assumeThat[T](actual: T, matcher: Matcher[T]): Unit = { if (!matcher.matches(actual.asInstanceOf[AnyRef])) throw new AssumptionViolatedException(actual, matcher) } + @noinline def assumeThat[T](message: String, actual: T, matcher: Matcher[T]): Unit = { if (!matcher.matches(actual.asInstanceOf[AnyRef])) throw new AssumptionViolatedException(message, actual, matcher) } + @noinline def assumeNoException(e: Throwable): Unit = assumeThat(e, nullValue()) + @noinline def assumeNoException(message: String, e: Throwable): Unit = assumeThat(message, e, nullValue()) } From 8d1938b6eaa985c933189f0eaf82edee0b3cb897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 26 Aug 2018 14:54:04 +0200 Subject: [PATCH 0817/2665] [no-master] Fix #3432: Use the new API of jsdom v10 in JSDOMNodeJSEnv. jsdom v12.0.0 dropped support for the "old API" that was legacy from v9. We were still using that old API so that we could support jsdom v9 and v10 (and v11), but this is no longer an option for v12. This commit migrates to using the "new API" introduced in jsdom v10.0.0, which brings support for v12.x. In order to keep supporting v9.x, we use a dynamic fallback to the previous implementation. --- Jenkinsfile | 11 ++ .../scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala | 107 ++++++++++++------ package.json | 8 ++ 3 files changed, 94 insertions(+), 32 deletions(-) create mode 100644 package.json diff --git a/Jenkinsfile b/Jenkinsfile index e39a6135cf..d59c50e812 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -97,6 +97,7 @@ sbtretry() { def Tasks = [ "main": ''' setJavaVersion $java + npm install && sbtretry ++$scala 'set scalaJSUseRhino in Global := true' helloworld/run && sbtretry ++$scala helloworld/run && sbtretry 'set scalaJSStage in Global := FullOptStage' \ @@ -170,6 +171,7 @@ def Tasks = [ "test-suite-ecma-script5": ''' setJavaVersion $java + npm install && sbtretry ++$scala jUnitTestOutputsJVM/test jUnitTestOutputsJS/test \ 'set scalaJSStage in Global := FullOptStage' jUnitTestOutputsJS/test && sbtretry ++$scala 'set scalaJSUseRhino in Global := true' jUnitTestOutputsJS/test && @@ -233,6 +235,7 @@ def Tasks = [ "test-suite-ecma-script6": ''' setJavaVersion $java + npm install && sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true)))' \ 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withSourceMap(false))' \ ++$scala $testSuite/test \ @@ -281,6 +284,7 @@ def Tasks = [ "bootstrap": ''' setJavaVersion $java + npm install && sbt ++$scala irJS/test toolsJS/test && sbt 'set scalaJSStage in Global := FullOptStage' \ ++$scala irJS/test && @@ -291,6 +295,7 @@ def Tasks = [ "tools-cli-stubs": ''' setJavaVersion $java + npm install && sbt ++$scala tools/package ir/test tools/test cli/package cli/assembly \ stubs/package jsEnvsTestSuite/test testAdapter/test \ ir/mimaReportBinaryIssues tools/mimaReportBinaryIssues \ @@ -304,6 +309,7 @@ def Tasks = [ "tools-cli-stubs-sbtplugin": ''' setJavaVersion $java + npm install && sbt ++$scala tools/package ir/test tools/test cli/package cli/assembly \ stubs/package jsEnvsTestSuite/test testAdapter/test \ sbtPlugin/package \ @@ -334,6 +340,7 @@ def Tasks = [ "partestc": ''' setJavaVersion $java + npm install && sbt ++$scala partest/compile ''', @@ -342,6 +349,7 @@ def Tasks = [ SBT_VER_OVERRIDE=$sbt_version_override # Publish Scala.js artifacts locally # Then go into standalone project and test + npm install && sbt ++2.11.12 compiler/publishLocal library/publishLocal javalibEx/publishLocal \ testInterface/publishLocal stubs/publishLocal \ jUnitPlugin/publishLocal jUnitRuntime/publishLocal && @@ -365,16 +373,19 @@ def Tasks = [ "partest-noopt": ''' setJavaVersion $java + npm install && sbt ++$scala package "partestSuite/testOnly -- --showDiff" ''', "partest-fastopt": ''' setJavaVersion $java + npm install && sbt ++$scala package "partestSuite/testOnly -- --fastOpt --showDiff" ''', "partest-fullopt": ''' setJavaVersion $java + npm install && sbt ++$scala package "partestSuite/testOnly -- --fullOpt --showDiff" ''' ] diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala index a19c62a883..f1c698c7bf 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala @@ -65,46 +65,89 @@ class JSDOMNodeJSEnv private[jsenv] ( protected trait AbstractDOMNodeRunner extends AbstractNodeRunner { protected def codeWithJSDOMContext(): Seq[VirtualJSFile] = { - val scriptsJSPaths = getLibJSFiles().map { - case file: FileVirtualFile => file.path - case file => libCache.materialize(file).getAbsolutePath + val scriptsFiles = (getLibJSFiles() :+ code).map { + case file: FileVirtualFile => file.file + case file => libCache.materialize(file) } - val scriptsStringPath = scriptsJSPaths.map('"' + escapeJS(_) + '"') + val scriptsURIsAsJSStrings = scriptsFiles.map { file => + '"' + escapeJS(file.toURI.toASCIIString) + '"' + } + val scriptsURIsJSArray = scriptsURIsAsJSStrings.mkString("[", ", ", "]") + val jsDOMCode = { s""" |(function () { - | var jsdom; - | try { - | jsdom = require("jsdom/lib/old-api.js"); // jsdom >= 10.x - | } catch (e) { - | jsdom = require("jsdom"); // jsdom <= 9.x - | } + | var jsdom = require("jsdom"); | - | var windowKeys = []; - | - | jsdom.env({ - | html: "", - | virtualConsole: jsdom.createVirtualConsole().sendTo(console), - | created: function (error, window) { - | if (error == null) { - | window["__ScalaJSEnv"] = __ScalaJSEnv; - | window["scalajsCom"] = global.scalajsCom; - | windowKeys = Object.keys(window); - | } else { - | console.log(error); - | } - | }, - | scripts: [${scriptsStringPath.mkString(", ")}], - | onload: function (window) { - | jsdom.changeURL(window, "http://localhost"); - | for (var k in window) { - | if (windowKeys.indexOf(k) == -1) - | global[k] = window[k]; + | if (typeof jsdom.JSDOM === "function") { + | // jsdom >= 10.0.0 + | var virtualConsole = new jsdom.VirtualConsole() + | .sendTo(console, { omitJSDOMErrors: true }); + | virtualConsole.on("jsdomError", function (error) { + | try { + | // Display as much info about the error as possible + | if (error.detail && error.detail.stack) { + | console.error("" + error.detail); + | console.error(error.detail.stack); + | } else { + | console.error(error); + | } + | } finally { + | // Whatever happens, kill the process so that the run fails + | process.exit(1); | } + | }); + | + | var dom = new jsdom.JSDOM("", { + | virtualConsole: virtualConsole, + | url: "http://localhost/", | - | ${code.content} + | /* Allow unrestricted "); - """ hasOutput "\n"; + withRun("""console.log("");""") { + _.expectOut("\n") + .closeRun() + } } @Test def jsExitsTest: Unit = { assumeTrue(config.supportsExit) - val run = kit.start("__ScalaJSEnv.exitFunction(0);", RunConfig()) - try { - Await.result(run.future, config.awaitTimeout) - } finally { - run.close() + withRun("__ScalaJSEnv.exitFunction(0);") { + _.succeeds() } } @@ -92,24 +103,28 @@ private[test] class RunTests(config: JSEnvSuiteConfig, withCom: Boolean) { val result = strlists.map(_.mkString(" ") + "\n").mkString("") - codes.mkString("").hasOutput(result) + withRun(codes.mkString("")) { + _.expectOut(result) + .closeRun() + } } @Test // Node.js console.log hack didn't allow to log non-Strings - #561 def nonStringTest: Unit = { - """ - console.log(1); - console.log(undefined); - console.log(null); - console.log({}); - console.log([1,2]); - """ hasOutput - """|1 - |undefined - |null - |[object Object] - |1,2 - |""".stripMargin + withRun(""" + console.log(1); + console.log(undefined); + console.log(null); + console.log({}); + console.log([1,2]); + """) { + _.expectOut("1\n") + .expectOut("undefined\n") + .expectOut("null\n") + .expectOut("[object Object]\n") + .expectOut("1,2\n") + .closeRun() + } } @Test @@ -117,21 +132,21 @@ private[test] class RunTests(config: JSEnvSuiteConfig, withCom: Boolean) { /* This test also tests a failure mode where the ExternalJSRun is still * piping output while the client calls close. */ - val run = kit.start("", RunConfig()) - run.close() - awaitAfterClose(run) + withRun("") { + _.closeRun() + } } @Test def multiCloseAfterTerminatedTest: Unit = { - val run = kit.start("", RunConfig()) - run.close() - awaitAfterClose(run) - - // Should be noops (and not fail). - run.close() - run.close() - run.close() + withRun("") { run => + run.closeRun() + + // Should be noops (and not fail). + run.closeRun() + run.closeRun() + run.closeRun() + } } @Test @@ -145,13 +160,8 @@ private[test] class RunTests(config: JSEnvSuiteConfig, withCom: Boolean) { } // `start` may not throw but must fail asynchronously - val run = kit.start(badFile, RunConfig()) - try { - Await.ready(run.future, config.awaitTimeout) - assertTrue("Bad file should have made run fail", - run.future.value.get.isFailure) - } finally { - run.close() + withRun(Input.ScriptsToLoad(badFile :: Nil)) { + _.fails() } } @@ -169,6 +179,6 @@ private[test] class RunTests(config: JSEnvSuiteConfig, withCom: Boolean) { @Test(expected = classOf[IllegalArgumentException]) def ensureValidate: Unit = { val cfg = RunConfig().withEternallyUnsupportedOption(true) - kit.start("", cfg).close() + withRun("", cfg)(identity) } } diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestComKit.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestComKit.scala deleted file mode 100644 index 7ca45b8914..0000000000 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestComKit.scala +++ /dev/null @@ -1,65 +0,0 @@ -package org.scalajs.jsenv.test - -import java.util.concurrent.TimeoutException - -import org.scalajs.io.{VirtualBinaryFile, MemVirtualBinaryFile} - -import org.scalajs.jsenv._ - -import org.junit.Assert.fail - -import scala.collection.immutable -import scala.concurrent.Await -import scala.concurrent.duration.Duration - -private[test] final class TestComKit(config: JSEnvSuiteConfig) { - def start(code: String, runConfig: RunConfig): Run = { - val vf = MemVirtualBinaryFile.fromStringUTF8("testScript.js", code) - start(vf, runConfig) - } - - def start(vf: VirtualBinaryFile, runConfig: RunConfig): Run = { - val input = Input.ScriptsToLoad(List(vf)) - new Run(input, runConfig) - } - - final class Run(input: Input, runConfig: RunConfig) { - val run: JSComRun = config.jsEnv.startWithCom(input, runConfig, onMessage _) - - private var received = immutable.Queue.empty[String] - - def waitNextMessage(): String = synchronized { - val deadline = config.awaitTimeout.fromNow - - while (received.isEmpty) { - val m = deadline.timeLeft.toMillis - if (m > 0) - wait(m) - else - throw new TimeoutException("Timed out waiting for next message") - } - - val (msg, newReceived) = received.dequeue - received = newReceived - msg - } - - def closeAndWait(): Unit = { - run.close() - - // Run must complete successfully. - Await.result(run.future, config.awaitTimeout) - - synchronized { - if (received.nonEmpty) { - fail(s"There were unhandled messages: $received") - } - } - } - - private def onMessage(msg: String) = synchronized { - received = received.enqueue(msg) - notifyAll() - } - } -} diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestKit.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestKit.scala deleted file mode 100644 index 0dfb47393d..0000000000 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TestKit.scala +++ /dev/null @@ -1,156 +0,0 @@ -package org.scalajs.jsenv.test - -import java.io._ -import java.nio.CharBuffer -import java.nio.charset.StandardCharsets -import java.util.concurrent.TimeoutException - -import scala.annotation.tailrec -import scala.concurrent.Await -import scala.concurrent.duration.Deadline - -import org.scalajs.io.{VirtualBinaryFile, MemVirtualBinaryFile} - -import org.scalajs.jsenv._ - -import org.junit.Assert._ -import org.junit.Assume._ - -private[test] final class TestKit(config: JSEnvSuiteConfig, withCom: Boolean) { - assumeTrue("JSEnv needs com support", config.supportsCom || !withCom) - - def start(code: String, config: RunConfig): JSRun = { - val vf = MemVirtualBinaryFile.fromStringUTF8("testScript.js", code) - start(vf, config) - } - - def start(vf: VirtualBinaryFile, runConfig: RunConfig): JSRun = { - val input = Input.ScriptsToLoad(List(vf)) - if (withCom) - config.jsEnv.startWithCom(input, runConfig, _ => ()) - else - config.jsEnv.start(input, runConfig) - } - - /** Await a run started with [[start]] after it got closed. - * - * This expects successful termination depending on [[withCom]]: we are - * allowed to expect successful termination with a com. - */ - def awaitAfterClose(run: JSRun): Unit = { - if (withCom) - Await.result(run.future, config.awaitTimeout) - else - Await.ready(run.future, config.awaitTimeout) - } - - implicit final class RunMatcher private[TestKit] (codeStr: String) { - def hasOutput(expectedOut: String): Unit = { - val comparator = new OutputComparator(expectedOut) - val config = comparator.configure(RunConfig()) - val run = start(codeStr, config) - - try { - comparator.compare() - } finally { - run.close() - } - - awaitAfterClose(run) - } - - def fails(): Unit = { - // We do not want to spam the console with error output, so we ignore it. - def ignoreStreams(out: Option[InputStream], err: Option[InputStream]) = { - out.foreach(_.close()) - err.foreach(_.close()) - } - - val runConfig = RunConfig() - .withOnOutputStream(ignoreStreams) - .withInheritOut(false) - .withInheritErr(false) - - val run = start(codeStr, runConfig) - try { - Await.ready(run.future, config.awaitTimeout) - assertTrue("Code snipped should fail", run.future.value.get.isFailure) - } finally { - run.close() - } - } - } - - private class OutputComparator(expectedOut: String) { - private val waiter = new StreamWaiter - - def configure(config: RunConfig): RunConfig = { - config - .withOnOutputStream(waiter.onOutputStream _) - .withInheritOut(false) - .withInheritErr(true) - } - - def compare(): Unit = { - val deadline = config.awaitTimeout.fromNow - val stream = waiter.waitForStream(deadline) - - /* When reading, we use a CharBuffer for easy index tracking. However, we - * back it by an array so we can easily read partial results. - */ - val in = new InputStreamReader(stream, StandardCharsets.UTF_8) - val arr = new Array[Char](expectedOut.length) - val buf = CharBuffer.wrap(arr) - while (buf.hasRemaining && tryRead(in, buf, deadline) != -1) { - val len = buf.position - assertEquals("Partial check", - expectedOut.substring(0, len), - new String(arr, 0, len)) - } - - buf.flip() - assertEquals(expectedOut, buf.toString) - } - } - - @tailrec - private final def tryRead(in: Reader, buf: CharBuffer, deadline: Deadline): Int = { - if (deadline.isOverdue) { - buf.flip() - throw new TimeoutException("Timed out out waiting for output. Got so far: " + buf.toString) - } - - if (in.ready()) { - in.read(buf) - } else { - Thread.sleep(50) - tryRead(in, buf, deadline) - } - } - - private class StreamWaiter { - private[this] var stream: InputStream = _ - - def waitForStream(deadline: Deadline): InputStream = synchronized { - while (stream == null) { - val m = deadline.timeLeft.toMillis - if (m > 0) - wait(m) - else - throw new TimeoutException("Timed out waiting for stdout") - } - - stream - } - - def onOutputStream(out: Option[InputStream], - err: Option[InputStream]): Unit = synchronized { - require(err.isEmpty, "Got error stream, did not request it.") - require(stream == null, "Got called twice") - - stream = out.getOrElse(new ByteArrayInputStream(new Array[Byte](0))) - notifyAll() - } - } -} - diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutComTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutComTests.scala index 96d1a8f2d3..83cf46037d 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutComTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutComTests.scala @@ -1,15 +1,16 @@ package org.scalajs.jsenv.test -import org.scalajs.jsenv._ +import scala.concurrent.duration._ import org.junit.{Before, Test} import org.junit.Assert._ import org.junit.Assume._ -import scala.concurrent.duration._ +import org.scalajs.jsenv._ +import org.scalajs.jsenv.test.kit.TestKit private[test] class TimeoutComTests(config: JSEnvSuiteConfig) { - private val kit = new TestComKit(config) + private val kit = new TestKit(config.jsEnv, config.awaitTimeout) @Before def before: Unit = { @@ -27,40 +28,43 @@ private[test] class TimeoutComTests(config: JSEnvSuiteConfig) { @Test def delayedInitTest: Unit = { val deadline = (100.millis - slack).fromNow - val run = kit.start(s""" + kit.withComRun(""" setTimeout(function() { scalajsCom.init(function(msg) { scalajsCom.send("Got: " + msg); }); }, 100); - """, RunConfig()) + """) { run => + run.send("Hello World") + .expectMsg("Got: Hello World") - try { - run.run.send("Hello World") - assertEquals("Got: Hello World", run.waitNextMessage()) assertTrue("Execution took too little time", deadline.isOverdue()) - } finally { - run.closeAndWait() + + run + .expectNoMsgs() + .closeRun() } } @Test def delayedReplyTest: Unit = { - val run = kit.start(s""" + kit.withComRun(""" scalajsCom.init(function(msg) { setTimeout(scalajsCom.send, 200, "Got: " + msg); }); - """, RunConfig()) - - try { + """) { run => for (i <- 1 to 10) { val deadline = (200.millis - slack).fromNow - run.run.send(s"Hello World: $i") - assertEquals(s"Got: Hello World: $i", run.waitNextMessage()) + run + .send(s"Hello World: $i") + .expectMsg(s"Got: Hello World: $i") + assertTrue("Execution took too little time", deadline.isOverdue()) } - } finally { - run.closeAndWait() + + run + .expectNoMsgs() + .closeRun() } } @@ -68,7 +72,7 @@ private[test] class TimeoutComTests(config: JSEnvSuiteConfig) { def intervalSendTest: Unit = { val deadline = (250.millis - slack).fromNow - val run = kit.start(s""" + kit.withComRun(""" scalajsCom.init(function(msg) {}); var sent = 0 var interval = setInterval(function () { @@ -76,41 +80,39 @@ private[test] class TimeoutComTests(config: JSEnvSuiteConfig) { sent++; if (sent >= 5) clearInterval(interval); }, 50); - """, RunConfig()) - - try { + """) { run => for (i <- 1 to 5) - assertEquals("Hello", run.waitNextMessage()) + run.expectMsg("Hello") assertTrue("Execution took too little time", deadline.isOverdue()) - } finally { - run.closeAndWait() + + run + .expectNoMsgs() + .closeRun() } } @Test def noMessageTest: Unit = { - val run = kit.start(s""" + kit.withComRun(s""" // Make sure JVM has already closed when we init setTimeout(scalajsCom.init, 1000, function(msg) {}); - """, RunConfig()) - run.closeAndWait() + """) { + _.closeRun() + } } @Test // #3411 def noImmediateCallbackTest: Unit = { - val run = kit.start(s""" + kit.withComRun(s""" setTimeout(function() { var gotCalled = false; scalajsCom.init(function(msg) { gotCalled = true; }); if (gotCalled) throw "Buffered messages did not get deferred to the event loop"; }, 100); - """, RunConfig()) - - try { - run.run.send("Hello World") - } finally { - run.closeAndWait() + """) { + _.send("Hello World") + .closeRun() } } } diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutRunTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutRunTests.scala index 8832fb5ff6..7b5e69ce72 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutRunTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutRunTests.scala @@ -1,16 +1,21 @@ package org.scalajs.jsenv.test -import org.scalajs.jsenv.JSEnv +import scala.concurrent.duration._ import org.junit.{Before, Test} import org.junit.Assert._ import org.junit.Assume._ -import scala.concurrent.duration._ +import org.scalajs.jsenv._ +import org.scalajs.jsenv.test.kit.{TestKit, Run} private[test] class TimeoutRunTests(config: JSEnvSuiteConfig, withCom: Boolean) { - private val kit = new TestKit(config, withCom) - import kit._ + private val kit = new TestKit(config.jsEnv, config.awaitTimeout) + + private def withRun(input: String)(body: Run => Unit) = { + if (withCom) kit.withComRun(input)(body) + else kit.withRun(input)(body) + } @Before def before: Unit = { @@ -29,38 +34,37 @@ private[test] class TimeoutRunTests(config: JSEnvSuiteConfig, withCom: Boolean) val deadline = (300.millis - slack).fromNow - """ - setTimeout(function() { console.log("1"); }, 200); - setTimeout(function() { console.log("2"); }, 100); - setTimeout(function() { console.log("3"); }, 300); - setTimeout(function() { console.log("4"); }, 0); - """ hasOutput - """|4 - |2 - |1 - |3 - |""".stripMargin + withRun(""" + setTimeout(function() { console.log("1"); }, 200); + setTimeout(function() { console.log("2"); }, 100); + setTimeout(function() { console.log("3"); }, 300); + setTimeout(function() { console.log("4"); }, 0); + """) { + _.expectOut("4\n") + .expectOut("2\n") + .expectOut("1\n") + .expectOut("3\n") + .closeRun() + } assertTrue("Execution took too little time", deadline.isOverdue()) - } @Test def intervalTest: Unit = { val deadline = (100.millis - slack).fromNow - // We rely on the test kit to terminate the test after 5 iterations. - """ - setInterval(function() { console.log("tick"); }, 20); - """ hasOutput - """|tick - |tick - |tick - |tick - |tick - |""".stripMargin + withRun(""" + setInterval(function() { console.log("tick"); }, 20); + """) { + _.expectOut("tick\n") + .expectOut("tick\n") + .expectOut("tick\n") + .expectOut("tick\n") + .expectOut("tick\n") + .closeRun() // Terminate after 5 iterations + } assertTrue("Execution took too little time", deadline.isOverdue()) - } } diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/kit/ComRun.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/kit/ComRun.scala new file mode 100644 index 0000000000..a29d8eef21 --- /dev/null +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/kit/ComRun.scala @@ -0,0 +1,67 @@ +package org.scalajs.jsenv.test.kit + +import scala.concurrent.Await +import scala.concurrent.duration.FiniteDuration + +import org.junit.Assert._ + +import org.scalajs.jsenv._ + +/** A [[JSComRun]] instrumented for testing. + * + * Create an instance of this class through one of the overloads of + * `[[TestKit]].withComRun` or `[[TestKit]].startWithCom`. + */ +class ComRun private[kit] (run: JSComRun, out: IOReader, err: IOReader, + msgs: MsgHandler, timeout: FiniteDuration) + extends Run(run, out, err, timeout) { + private[this] var noMessages = false + + /** Calls [[JSComRun#send]] on the underlying run. */ + final def send(msg: String): this.type = { + run.send(msg) + this + } + + /** Waits until the given message is sent to the JVM. + * + * @throws java.lang.AssertionError if there is another message or the run terminates. + * @throws java.util.concurrent.TimeoutException if there is no message for too long. + */ + final def expectMsg(expected: String): this.type = { + require(!noMessages, "You may not call expectMsg after calling expectNoMsgs") + val actual = msgs.waitOnMessage(timeout.fromNow) + assertEquals("got bad message", expected, actual) + this + } + + /** Marks that no further messages are expected. + * + * This will make the methods [[closeRun]] / [[fails]] / [[succeeds]] fail if + * further messages are received. + * + * @note It is illegal to call [[expectMsg]] after [[expectNoMsgs]] has been + * called. + */ + final def expectNoMsgs(): this.type = { + noMessages = true + this + } + + override protected def postCloseRunWait(): Unit = { + try { + Await.result(run.future, timeout) + } catch { + case t: Throwable => + throw new AssertionError("closing a ComRun failed unexpectedly", t) + } + } + + override protected def postStopChecks(): Unit = { + super.postStopChecks() + if (noMessages) { + val rem = msgs.remainingMessages() + assertTrue(s"unhandled messages: $rem", rem.isEmpty) + } + } +} diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/kit/IOReader.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/kit/IOReader.scala new file mode 100644 index 0000000000..1de46d9565 --- /dev/null +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/kit/IOReader.scala @@ -0,0 +1,123 @@ +package org.scalajs.jsenv.test.kit + +import scala.annotation.tailrec + +import scala.concurrent.Promise +import scala.concurrent.duration.Deadline + +import scala.util.Try + +import java.nio.ByteBuffer +import java.nio.channels.{Channels, ReadableByteChannel} + +import java.io.InputStream + +import java.util.concurrent._ + +private[kit] final class IOReader { + private val executor = Executors.newSingleThreadExecutor() + + private[this] var _closed = false + private[this] var _channel: ReadableByteChannel = _ + private[this] val run = Promise[Unit]() + + def read(len: Int, deadline: Deadline): ByteBuffer = { + val chan = try { + waitOnChannel(deadline) + } catch { + case t: TimeoutException => + throw new TimeoutException("timed out waiting on run to call onOutputStream") + } + + val task = executor.submit( + new Callable[ByteBuffer] { + def call(): ByteBuffer = readLoop(chan, ByteBuffer.allocate(len)) + } + ) + + try { + task.get(millisLeft(deadline), TimeUnit.MILLISECONDS) + } catch { + case e: ExecutionException => + throw e.getCause() + + case e: CancellationException => + throw new AssertionError("unexpected exception while running read task", e) + + case e: InterruptedException => + throw new AssertionError("unexpected exception while running read task", e) + + case e: TimeoutException => + task.cancel(true) + throw new TimeoutException("timed out reading from stream") + } + } + + def onInputStream(in: InputStream): Unit = synchronized { + require(_channel == null, "onInputStream called twice") + + if (_closed) { + in.close() + } else { + _channel = Channels.newChannel(in) + notifyAll() + } + } + + def onRunComplete(t: Try[Unit]): Unit = synchronized { + run.complete(t) + notifyAll() + } + + def close(): Unit = synchronized { + if (_channel != null) + _channel.close() + _closed = true + } + + private def waitOnChannel(deadline: Deadline) = synchronized { + while (_channel == null && !run.isCompleted) + wait(millisLeft(deadline)) + + if (_channel == null) { + throw new AssertionError( + "run completed and did not call onOutputStream", runFailureCause()) + } + + _channel + } + + private def runFailureCause() = { + require(run.isCompleted) + run.future.value.get.failed.getOrElse(null) + } + + @tailrec + private def readLoop(chan: ReadableByteChannel, buf: ByteBuffer): buf.type = { + if (chan.read(buf) == -1) { + // If we have reached the end of the stream, we wait for completion of the + // run so we can report a potential failure as a cause. + synchronized { + while (!run.isCompleted) + wait() + } + + throw new AssertionError("reached end of stream", runFailureCause()) + } else if (buf.hasRemaining()) { + readLoop(chan, buf) + } else { + buf.flip() + buf + } + } + + private def millisLeft(deadline: Deadline): Long = { + val millis = deadline.timeLeft.toMillis + + if (millis <= 0) { + throw new TimeoutException + } + + millis + } +} diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/kit/MsgHandler.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/kit/MsgHandler.scala new file mode 100644 index 0000000000..0e742d9813 --- /dev/null +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/kit/MsgHandler.scala @@ -0,0 +1,57 @@ +package org.scalajs.jsenv.test.kit + +import scala.annotation.tailrec + +import scala.collection.immutable + +import scala.concurrent.Promise +import scala.concurrent.duration.Deadline + +import scala.util.Try + +import java.util.concurrent.TimeoutException + +private[kit] final class MsgHandler { + private[this] var msgs: immutable.Queue[String] = + immutable.Queue.empty[String] + private[this] val run = Promise[Unit] + + def onMessage(msg: String): Unit = synchronized { + if (run.isCompleted) { + throw new IllegalStateException( + "run already completed but still got a message") + } + + msgs = msgs.enqueue(msg) + notifyAll() + } + + def onRunComplete(t: Try[Unit]): Unit = synchronized { + run.complete(t) + notifyAll() + } + + @tailrec + def waitOnMessage(deadline: Deadline): String = synchronized { + if (msgs.nonEmpty) { + val (msg, newMsgs) = msgs.dequeue + msgs = newMsgs + msg + } else if (run.isCompleted) { + val cause = run.future.value.get.failed.getOrElse(null) + throw new AssertionError("no messages left and run has completed", cause) + } else { + val millis = deadline.timeLeft.toMillis + + if (millis <= 0) { + throw new TimeoutException("timed out waiting for next message") + } + + wait(millis) + waitOnMessage(deadline) + } + } + + /** @note may only be called once the run is completed. */ + def remainingMessages(): List[String] = synchronized(msgs.toList) +} diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/kit/Run.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/kit/Run.scala new file mode 100644 index 0000000000..32984b3f3f --- /dev/null +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/kit/Run.scala @@ -0,0 +1,97 @@ +package org.scalajs.jsenv.test.kit + +import scala.concurrent.Await +import scala.concurrent.duration.FiniteDuration + +import java.nio.charset.{CodingErrorAction, StandardCharsets} + +import org.junit.Assert._ + +import org.scalajs.jsenv._ + +/** A [[JSRun]] instrumented for testing. + * + * Create an instance of this class through one of the overloads of + * `[[TestKit]].withRun` or `[[TestKit]].start`. + */ +class Run private[kit] (run: JSRun, out: IOReader, err: IOReader, timeout: FiniteDuration) extends AutoCloseable { + private[this] val utf8decoder = { + StandardCharsets.UTF_8.newDecoder() + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE) + } + + /** Waits until the given string is output to stdout (in UTF8). + * + * @throws java.lang.AssertionError if there is some other output on stdout + * or the run terminates. + * @throws java.util.concurrent.TimeoutException if there is not enough output for too long. + */ + final def expectOut(v: String): this.type = expectIO(out, "stdout", v) + + /** Waits until the given string is output to stderr (in UTF8). + * + * @throws java.lang.AssertionError if there is some other output on stderr + * or the run terminates. + * @throws java.util.concurrent.TimeoutException if there is not enough output for too long. + */ + final def expectErr(v: String): this.type = expectIO(err, "stderr", v) + + /** Waits until the underlying [[JSRun]] terminates and asserts it failed. + * + * @throws java.lang.AssertionError if the [[JSRun]] succeeded. + * @throws java.util.concurrent.TimeoutException if the [[JSRun]] did not terminate in time. + */ + final def fails(): Unit = { + Await.ready(run.future, timeout) + assertTrue("run succeeded unexpectedly", run.future.value.get.isFailure) + postStopChecks() + } + + /** Waits until the underlying [[JSRun]] terminates and asserts it succeeded. + * + * @throws java.lang.AssertionError if the [[JSRun]] failed. + * @throws java.util.concurrent.TimeoutException if the [[JSRun]] did not terminate in time. + */ + final def succeeds(): Unit = { + try { + Await.result(run.future, timeout) + } catch { + case t: Throwable => + throw new AssertionError("run failed unexpectedly", t) + } + postStopChecks() + } + + /** Calls [[JSRun#close]] on the underlying [[JSRun]] and awaits termination. + * + * @throws java.lang.AssertionError if the [[JSRun]] behaves unexpectedly. + * @throws java.util.concurrent.TimeoutException if the [[JSRun]] does not terminate in time. + */ + final def closeRun(): Unit = { + run.close() + postCloseRunWait() + postStopChecks() + } + + /** Must be called to free all resources of this [[Run]]. Does not throw. */ + def close(): Unit = { + out.close() + err.close() + run.close() + } + + protected def postCloseRunWait(): Unit = Await.ready(run.future, timeout) + + protected def postStopChecks(): Unit = () + + private def expectIO(reader: IOReader, name: String, v: String): this.type = { + val len = v.getBytes(StandardCharsets.UTF_8).length + val buf = reader.read(len, timeout.fromNow) + val got = utf8decoder.decode(buf).toString + + assertEquals(s"bad output on $name", v, got) + + this + } +} diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/kit/TestKit.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/kit/TestKit.scala new file mode 100644 index 0000000000..934c5dc4c0 --- /dev/null +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/kit/TestKit.scala @@ -0,0 +1,146 @@ +package org.scalajs.jsenv.test.kit + +import scala.concurrent.ExecutionContext +import scala.concurrent.duration.FiniteDuration + +import java.io.InputStream +import java.util.concurrent.Executors + +import org.scalajs.io.MemVirtualBinaryFile +import org.scalajs.jsenv._ + +/** TestKit is a utility class to simplify testing of [[JSEnv]]s. + * + * It is mostly used by Scala.js' provided [[JSEnv]] test suite but it may be + * used for additional tests specific to a particular [[JSEnv]]. + * + * @example + * {{{ + * import scala.concurrent.duration._ + * + * val kit = new TestKit(new MyEnv, 1.second) + * kit.withRun("""console.log("Hello World");""") { + * _.expectOut("Hello World\n") + * .closeRun() + * } + * }}} + * + * @note Methods in [[TestKit]] allow to take a string instead of an [[Input]]. + * The string is converted into an input form supported by the [[JSEnv]] to + * execute the code therein. + * + * @constructor Create a new [[TestKit]] for the given [[JSEnv]] and timeout. + * @param jsEnv The [[JSEnv]] to be tested. + * @param timeout Timeout for all `expect*` methods on [[Run]] / [[ComRun]]. + */ +final class TestKit(jsEnv: JSEnv, timeout: FiniteDuration) { + import TestKit.codeToInput + + /** Starts a [[Run]] for testing. */ + def start(code: String): Run = + start(codeToInput(code)) + + /** Starts a [[Run]] for testing. */ + def start(input: Input): Run = + start(input, RunConfig()) + + /** Starts a [[Run]] for testing. */ + def start(code: String, config: RunConfig): Run = + start(codeToInput(code), config) + + /** Starts a [[Run]] for testing. */ + def start(input: Input, config: RunConfig): Run = { + val (run, out, err) = io(config)(jsEnv.start(input, _)) + new Run(run, out, err, timeout) + } + + /** Starts a [[ComRun]] for testing. */ + def startWithCom(code: String): ComRun = + startWithCom(codeToInput(code)) + + /** Starts a [[ComRun]] for testing. */ + def startWithCom(input: Input): ComRun = + startWithCom(input, RunConfig()) + + /** Starts a [[ComRun]] for testing. */ + def startWithCom(code: String, config: RunConfig): ComRun = + startWithCom(codeToInput(code), config) + + /** Starts a [[ComRun]] for testing. */ + def startWithCom(input: Input, config: RunConfig): ComRun = { + val msg = new MsgHandler + val (run, out, err) = io(config)(jsEnv.startWithCom(input, _, msg.onMessage _)) + run.future.onComplete(msg.onRunComplete _)(TestKit.completer) + + new ComRun(run, out, err, msg, timeout) + } + + /** Convenience method to start a [[Run]] and close it after usage. */ + def withRun[T](code: String)(body: Run => T): T = + withRun(codeToInput(code))(body) + + /** Convenience method to start a [[Run]] and close it after usage. */ + def withRun[T](input: Input)(body: Run => T): T = + withRun(input, RunConfig())(body) + + /** Convenience method to start a [[Run]] and close it after usage. */ + def withRun[T](code: String, config: RunConfig)(body: Run => T): T = + withRun(codeToInput(code), config)(body) + + /** Convenience method to start a [[Run]] and close it after usage. */ + def withRun[T](input: Input, config: RunConfig)(body: Run => T): T = { + val run = start(input, config) + try body(run) + finally run.close() + } + + /** Convenience method to start a [[ComRun]] and close it after usage. */ + def withComRun[T](code: String)(body: ComRun => T): T = withComRun(codeToInput(code))(body) + + /** Convenience method to start a [[ComRun]] and close it after usage. */ + def withComRun[T](input: Input)(body: ComRun => T): T = withComRun(input, RunConfig())(body) + + /** Convenience method to start a [[ComRun]] and close it after usage. */ + def withComRun[T](code: String, config: RunConfig)(body: ComRun => T): T = + withComRun(codeToInput(code), config)(body) + + /** Convenience method to start a [[ComRun]] and close it after usage. */ + def withComRun[T](input: Input, config: RunConfig)(body: ComRun => T): T = { + val run = startWithCom(input, config) + try body(run) + finally run.close() + } + + private def io[T <: JSRun](config: RunConfig)(start: RunConfig => T): (T, IOReader, IOReader) = { + val out = new IOReader + val err = new IOReader + + def onOutputStream(o: Option[InputStream], e: Option[InputStream]) = { + o.foreach(out.onInputStream _) + e.foreach(err.onInputStream _) + } + + val newConfig = config + .withOnOutputStream(onOutputStream) + .withInheritOut(false) + .withInheritErr(false) + + val run = start(newConfig) + + run.future.onComplete(out.onRunComplete _)(TestKit.completer) + run.future.onComplete(err.onRunComplete _)(TestKit.completer) + + (run, out, err) + } +} + +private object TestKit { + /** Execution context to run completion callbacks from runs under test. */ + private val completer = + ExecutionContext.fromExecutor(Executors.newSingleThreadExecutor()) + + private def codeToInput(code: String): Input = { + val vf = MemVirtualBinaryFile.fromStringUTF8("testScript.js", code) + Input.ScriptsToLoad(List(vf)) + } +} diff --git a/js-envs-test-kit/src/test/scala/org/scalajs/jsenv/test/kit/TestEnv.scala b/js-envs-test-kit/src/test/scala/org/scalajs/jsenv/test/kit/TestEnv.scala new file mode 100644 index 0000000000..5d2ded3449 --- /dev/null +++ b/js-envs-test-kit/src/test/scala/org/scalajs/jsenv/test/kit/TestEnv.scala @@ -0,0 +1,86 @@ +package org.scalajs.jsenv.test.kit + +import scala.concurrent.Future + +import java.io._ +import java.nio.charset.StandardCharsets +import java.util.concurrent.atomic.AtomicInteger + +import org.scalajs.jsenv._ + +private[kit] class TestEnv private ( + result: Future[Unit], + outerr: Option[() => InputStream], + msgs: List[String]) extends JSEnv { + + // Interface for testing. + + def withSuccess(): TestEnv = copy(result = Future.unit) + + def withFailure(t: Throwable): TestEnv = copy(result = Future.failed(t)) + + def withHang(): TestEnv = copy(result = Future.never) + + def withOutErr(s: String): TestEnv = { + val bytes = s.getBytes(StandardCharsets.UTF_8) + copy(outerr = Some(() => new ByteArrayInputStream(bytes))) + } + + def withOutErrHang(): TestEnv = { + def hangStream() = new InputStream { + // read method that hangs indfinitely. + def read(): Int = synchronized { + while (true) wait() + throw new AssertionError("unreachable code") + } + } + + copy(outerr = Some(() => hangStream())) + } + + def withMsgs(msgs: String*): TestEnv = copy(msgs = msgs.toList) + + private def this() = this(Future.unit, None, Nil) + + private def copy( + result: Future[Unit] = result, + outerr: Option[() => InputStream] = outerr, + msgs: List[String] = msgs) = new TestEnv(result, outerr, msgs) + + // JSEnv interface + + val name: String = "TestEnv" + + def start(input: Input, config: RunConfig): JSRun = { + require(msgs.isEmpty) + callOnOutputStream(config) + new TestRun + } + + def startWithCom(input: Input, config: RunConfig, onMessage: String => Unit): JSComRun = { + callOnOutputStream(config) + msgs.foreach(onMessage) + new TestRun with JSComRun { + def send(msg: String): Unit = () + } + } + + private def callOnOutputStream(config: RunConfig): Unit = { + for { + factory <- outerr + onOutputStream <- config.onOutputStream + } { + def mkStream = Some(factory()) + onOutputStream(mkStream, mkStream) + } + } + + private class TestRun extends JSRun { + val future: Future[Unit] = result + def close(): Unit = () + } +} + +object TestEnv { + def apply(): TestEnv = new TestEnv() +} diff --git a/js-envs-test-kit/src/test/scala/org/scalajs/jsenv/test/kit/TestKitTest.scala b/js-envs-test-kit/src/test/scala/org/scalajs/jsenv/test/kit/TestKitTest.scala new file mode 100644 index 0000000000..be3662f24e --- /dev/null +++ b/js-envs-test-kit/src/test/scala/org/scalajs/jsenv/test/kit/TestKitTest.scala @@ -0,0 +1,284 @@ +package org.scalajs.jsenv.test.kit + +import scala.concurrent.duration._ + +import java.util.concurrent._ + +import org.junit.Assert._ +import org.junit.Test + +import org.scalajs.jsenv._ + +class TestKitTest { + import TestKit.codeToInput + import TestKitTest._ + + private def noHangTest(env: TestEnv, msg: String)(body: TestKit => Unit) = { + def test(e: JSEnv, cause: Throwable) = { + val timeout = 1.minute + val kit = new TestKit(e, timeout) + val deadline = timeout.fromNow + + expectAssert(msg, cause)(body(kit)) + + assertFalse("faster than timout", deadline.isOverdue) + } + + test(env.withSuccess(), null) + + val t = new Throwable + test(env.withFailure(t), t) + } + + @Test + def noHangExpectOutNoStream: Unit = { + noHangTest(TestEnv(), "run completed and did not call onOutputStream") { + _.withRun("") { + _.expectOut("a") + .closeRun() + } + } + } + + @Test + def noHangExpectErrNoStream: Unit = { + noHangTest(TestEnv(), "run completed and did not call onOutputStream") { + _.withRun("") { + _.expectErr("a") + .closeRun() + } + } + } + + @Test + def noHangExpectMsgOnFail: Unit = { + noHangTest(TestEnv(), "no messages left and run has completed") { + _.withComRun("") { + _.expectMsg("a") + .closeRun() + } + } + } + + @Test + def noHangExpectOutOnEOF: Unit = { + noHangTest(TestEnv().withOutErr(""), "reached end of stream") { + _.withRun("") { + _.expectOut("a") + .closeRun() + } + } + } + + @Test + def noHangExpectErrOnEOF: Unit = { + noHangTest(TestEnv().withOutErr(""), "reached end of stream") { + _.withRun("") { + _.expectErr("a") + .closeRun() + } + } + } + + @Test + def failOnUnexpectedSuccess: Unit = { + val kit = new TestKit(TestEnv().withSuccess(), 1.second) + expectAssert("run succeeded unexpectedly") { + kit.withRun("")(_.fails()) + } + } + + @Test + def failOnUnexpectedFailure: Unit = { + val t = new Throwable + val kit = new TestKit(TestEnv().withFailure(t), 1.second) + + expectAssert("run failed unexpectedly", t) { + kit.withRun("")(_.succeeds()) + } + } + + @Test + def ignoreRunFailOnClose: Unit = { + val kit = new TestKit(TestEnv().withFailure(new Throwable("dummy for test")), 1.second) + kit.withRun("")(_.closeRun()) + } + + @Test + def enforceSuccessComRunOnClose: Unit = { + val t = new Throwable + val kit = new TestKit(TestEnv().withFailure(t), 1.second) + + expectAssert("closing a ComRun failed unexpectedly", t) { + kit.withComRun("")(_.closeRun()) + } + } + + @Test + def failOnBadOut: Unit = { + val kit = new TestKit(TestEnv().withOutErr("a"), 1.second) + + expectAssert("bad output on stdout expected:<[b]> but was:<[a]>") { + kit.withRun("") { + _.expectOut("b") + .closeRun() + } + } + } + + @Test + def failOnBadErr: Unit = { + val kit = new TestKit(TestEnv().withOutErr("a"), 1.second) + + expectAssert("bad output on stderr expected:<[b]> but was:<[a]>") { + kit.withRun("") { + _.expectErr("b") + .closeRun() + } + } + } + + @Test + def ignoreExcessOut: Unit = { + val kit = new TestKit(TestEnv().withOutErr("abcdefg"), 1.second) + + kit.withRun("") { + _.expectOut("a") + .expectOut("b") + .closeRun() + } + } + + @Test + def ignoreExcessErr: Unit = { + val kit = new TestKit(TestEnv().withOutErr("abcdefg"), 1.second) + + kit.withRun("") { + _.expectErr("a") + .expectErr("b") + .closeRun() + } + } + + @Test + def failOnBadMsgErr: Unit = { + val kit = new TestKit(TestEnv().withMsgs("a"), 1.second) + + expectAssert("got bad message expected:<[b]> but was:<[a]>") { + kit.withComRun("") { + _.expectMsg("b") + .closeRun() + } + } + } + + @Test + def failOnExcessMsgs: Unit = { + val kit = new TestKit(TestEnv().withMsgs("a", "b", "c"), 1.second) + + expectAssert("unhandled messages: List(b, c)") { + kit.withComRun("") { + _.expectMsg("a") + .expectNoMsgs() + .closeRun() + } + } + } + + @Test + def ignoreExcessMsgs: Unit = { + val kit = new TestKit(TestEnv().withMsgs("a", "b", "c"), 1.second) + + kit.withComRun("") { + _.expectMsg("a") + .closeRun() + } + } + + @Test + def timeoutOutOnNoStream: Unit = { + val kit = new TestKit(TestEnv().withHang(), 10.millisecond) + + expectTimeout("timed out waiting on run to call onOutputStream") { + kit.withRun("") { + _.expectOut("b") + .closeRun() + } + } + } + + @Test + def timeoutErrOnNoStream: Unit = { + val kit = new TestKit(TestEnv().withHang(), 10.millisecond) + + expectTimeout("timed out waiting on run to call onOutputStream") { + kit.withRun("") { + _.expectErr("b") + .closeRun() + } + } + } + + @Test + def timeoutExpectMsg: Unit = { + val kit = new TestKit(TestEnv().withHang(), 10.millisecond) + + expectTimeout("timed out waiting for next message") { + kit.withComRun("") { + _.expectMsg("a") + .closeRun() + } + } + } + + @Test + def timeoutExpectOut: Unit = { + val kit = new TestKit(TestEnv().withOutErrHang(), 10.millisecond) + + expectTimeout("timed out reading from stream") { + kit.withRun("") { + _.expectOut("b") + .closeRun() + } + } + } + + @Test + def timeoutExpectErr: Unit = { + val kit = new TestKit(TestEnv().withOutErrHang(), 10.millisecond) + + expectTimeout("timed out reading from stream") { + kit.withRun("") { + _.expectErr("b") + .closeRun() + } + } + } +} + +private object TestKitTest { + def expectAssert(msg: String, cause: Throwable = null)(body: => Unit): Unit = { + val thrown = try { + body + false + } catch { + case e: AssertionError => + assertEquals("bad assertion error message", msg, e.getMessage()) + assertSame("should link cause", cause, e.getCause()) + true + } + + if (!thrown) + throw new AssertionError("expected AssertionError to be thrown") + } + + def expectTimeout(msg: String)(body: => Unit): Unit = { + try { + body + throw new AssertionError("expected TimeoutExeception to be thrown") + } catch { + case e: TimeoutException => + assertEquals("bad timeout error message", msg, e.getMessage()) + } + } +} diff --git a/project/Build.scala b/project/Build.scala index 5d3fa98983..dcfb22408a 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -748,7 +748,10 @@ object Build { publishSettings, fatalWarningsSettings, name := "Scala.js JS Envs Test Kit", - libraryDependencies += "junit" % "junit" % "4.12", + libraryDependencies ++= Seq( + "junit" % "junit" % "4.12", + "com.novocode" % "junit-interface" % "0.9" % "test" + ), previousArtifactSetting, mimaBinaryIssueFilters ++= BinaryIncompatibilities.JSEnvsTestKit ).dependsOn(jsEnvs) From b0cd11f7d9f35afd7924e68f643308010b64a978 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Wed, 10 Oct 2018 16:18:45 +0200 Subject: [PATCH 0839/2665] Replace FrameworkDetector test with JSEnv test This test was originally designed to make sure FrameworkDetector doesn't fail with other `console.log` statements. However, since 22a8d7dc52669c537154f21519752a8b6680a174 FrameworkDetector does not exist anymore. We replace the specific test with a more generalized test that ensures that stdout and the scalajsCom do not interact for JSEnvs in general. --- .../org/scalajs/jsenv/test/ComTests.scala | 22 +++++++++++++++++++ sbt-plugin-test/build.sbt | 7 ------ .../js/src/test/resources/consoleWriter.js | 2 -- 3 files changed, 22 insertions(+), 9 deletions(-) delete mode 100644 sbt-plugin-test/multiTest/js/src/test/resources/consoleWriter.js diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala index 4e6f64090d..b1a99a6ecc 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala @@ -108,4 +108,26 @@ private[test] class ComTests(config: JSEnvSuiteConfig) { .closeRun() } } + + @Test + def separateComStdoutTest: Unit = { + // Make sure that com and stdout do not interfere with each other. + kit.withComRun(""" + scalajsCom.init(function (msg) { + console.log("got: " + msg) + }); + console.log("a"); + scalajsCom.send("b"); + scalajsCom.send("c"); + console.log("d"); + """) { + _.expectOut("a\n") + .expectMsg("b") + .expectMsg("c") + .expectOut("d\n") + .send("foo") + .expectOut("got: foo\n") + .closeRun() + } + } } diff --git a/sbt-plugin-test/build.sbt b/sbt-plugin-test/build.sbt index 8c2c5cefdf..48235466ba 100644 --- a/sbt-plugin-test/build.sbt +++ b/sbt-plugin-test/build.sbt @@ -125,13 +125,6 @@ lazy val multiTestJS = project.in(file("multiTest/js")). settings( name := "Multi test framework test JS", - // Make FrameworkDetector resilient to other output - #1572 - jsExecutionFiles in Test := { - val consoleWriter = new FileVirtualBinaryFile( - (resourceDirectory in Test).value / "consoleWriter.js") - consoleWriter +: (jsExecutionFiles in Test).value - }, - // Test platformDepsCrossVersion (as a setting, it's evaluated when loading the build) platformDepsCrossVersion ~= { value => assert(value eq ScalaJSCrossVersion.binary, diff --git a/sbt-plugin-test/multiTest/js/src/test/resources/consoleWriter.js b/sbt-plugin-test/multiTest/js/src/test/resources/consoleWriter.js deleted file mode 100644 index c5d403adca..0000000000 --- a/sbt-plugin-test/multiTest/js/src/test/resources/consoleWriter.js +++ /dev/null @@ -1,2 +0,0 @@ -// Make FrameworkDetector resilient to other output - #1572 -console.log("Breaking message") From 9dc4d5b36ff2b2a3dfe2e91d5c6b1ef6d10d3e51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 11 Oct 2018 18:24:17 +0200 Subject: [PATCH 0840/2665] Fix #3462: Apache License Version 2.0. This follows from the corresponding change of license in Scala at https://github.com/scala/scala/commit/2d9e6acce8c4246e6cba5a22ff9d965ec3bd117c We use sbt-header to enforce that the proper license header is present in all applicable files. Some files are excluded from the treatment because, as ports from other codebases, they have different licensing terms. --- Jenkinsfile | 1 + LICENSE | 229 +++++++++++++++--- NOTICE | 20 ++ README.md | 2 +- .../scala/org/scalajs/cli/Scalajsld.scala | 19 +- .../main/scala/org/scalajs/cli/Scalajsp.scala | 19 +- .../core/compiler/Compat210Component.scala | 13 +- .../org/scalajs/core/compiler/GenJSCode.scala | 13 +- .../scalajs/core/compiler/GenJSExports.scala | 13 +- .../scalajs/core/compiler/GenJSFiles.scala | 13 +- .../scalajs/core/compiler/JSDefinitions.scala | 13 +- .../scalajs/core/compiler/JSEncoding.scala | 13 +- .../core/compiler/JSGlobalAddons.scala | 13 +- .../scalajs/core/compiler/JSPrimitives.scala | 13 +- .../core/compiler/JSTreeExtractors.scala | 13 +- .../core/compiler/PreTyperComponent.scala | 13 +- .../scalajs/core/compiler/PrepJSExports.scala | 13 +- .../scalajs/core/compiler/PrepJSInterop.scala | 13 +- .../core/compiler/ScalaJSOptions.scala | 13 +- .../scalajs/core/compiler/ScalaJSPlugin.scala | 13 +- .../org/scalajs/core/compiler/TypeKinds.scala | 13 +- .../core/compiler/util/ScopedVar.scala | 12 + .../scalajs/core/compiler/util/VarBox.scala | 12 + .../compiler/test/DiverseErrorsTest.scala | 12 + .../test/EnumerationInteropTest.scala | 12 + .../test/InternalAnnotationsTest.scala | 12 + .../compiler/test/JSDynamicLiteralTest.scala | 12 + .../core/compiler/test/JSExportASTTest.scala | 12 + .../test/JSExportDeprecationsTest.scala | 12 + .../core/compiler/test/JSExportTest.scala | 12 + .../core/compiler/test/JSInteropTest.scala | 12 + .../compiler/test/JSNativeByDefaultTest.scala | 12 + .../core/compiler/test/JSOptionalTest.scala | 12 + .../core/compiler/test/JSSAMTest.scala | 12 + .../compiler/test/JSUndefinedParamTest.scala | 12 + .../core/compiler/test/MatchASTTest.scala | 12 + ...ngJSGlobalDeprecationsSuppressedTest.scala | 12 + .../MissingJSGlobalDeprecationsTest.scala | 12 + .../core/compiler/test/OptimizationTest.scala | 12 + .../core/compiler/test/PositionTest.scala | 12 + .../core/compiler/test/ReflectTest.scala | 12 + .../core/compiler/test/RegressionTest.scala | 12 + .../compiler/test/ScalaJSDefinedTest.scala | 12 + .../core/compiler/test/util/DirectTest.scala | 12 + .../core/compiler/test/util/JSASTTest.scala | 12 + .../core/compiler/test/util/TestHelpers.scala | 12 + .../scala/org/scalajs/core/ir/ClassKind.scala | 19 +- .../org/scalajs/core/ir/Definitions.scala | 19 +- .../scala/org/scalajs/core/ir/Hashers.scala | 12 + .../ir/IRVersionNotSupportedException.scala | 12 + .../org/scalajs/core/ir/InfoSerializers.scala | 19 +- .../scala/org/scalajs/core/ir/Infos.scala | 19 +- .../scalajs/core/ir/InvalidIRException.scala | 12 + .../scala/org/scalajs/core/ir/Position.scala | 19 +- .../scala/org/scalajs/core/ir/Printers.scala | 19 +- .../org/scalajs/core/ir/ScalaJSVersions.scala | 12 + .../org/scalajs/core/ir/Serializers.scala | 19 +- .../main/scala/org/scalajs/core/ir/Tags.scala | 19 +- .../org/scalajs/core/ir/Transformers.scala | 19 +- .../org/scalajs/core/ir/Traversers.scala | 19 +- .../scala/org/scalajs/core/ir/Trees.scala | 19 +- .../scala/org/scalajs/core/ir/Types.scala | 19 +- .../scala/org/scalajs/core/ir/Utils.scala | 19 +- .../org/scalajs/core/ir/PrintersTest.scala | 12 + .../scala/org/scalajs/core/ir/UtilsTest.scala | 12 + .../src/main/scala/java/lang/Appendable.scala | 12 + .../src/main/scala/java/lang/Boolean.scala | 12 + .../src/main/scala/java/lang/Byte.scala | 12 + .../main/scala/java/lang/CharSequence.scala | 12 + .../src/main/scala/java/lang/Character.scala | 12 + .../src/main/scala/java/lang/Class.scala | 12 + .../main/scala/java/lang/ClassLoader.scala | 12 + .../src/main/scala/java/lang/Cloneable.scala | 12 + .../src/main/scala/java/lang/Comparable.scala | 12 + .../src/main/scala/java/lang/Double.scala | 12 + .../src/main/scala/java/lang/Enum.scala | 12 + .../src/main/scala/java/lang/Float.scala | 12 + .../java/lang/InheritableThreadLocal.scala | 12 + .../src/main/scala/java/lang/Integer.scala | 12 + .../src/main/scala/java/lang/Iterable.scala | 12 + .../src/main/scala/java/lang/Long.scala | 12 + .../src/main/scala/java/lang/Math.scala | 12 + .../main/scala/java/lang/MathJDK8Bridge.scala | 12 + .../src/main/scala/java/lang/Number.scala | 12 + .../src/main/scala/java/lang/Readable.scala | 12 + .../src/main/scala/java/lang/Runnable.scala | 12 + .../src/main/scala/java/lang/Runtime.scala | 12 + .../src/main/scala/java/lang/Short.scala | 12 + .../scala/java/lang/StackTraceElement.scala | 12 + .../main/scala/java/lang/StringBuffer.scala | 12 + .../main/scala/java/lang/StringBuilder.scala | 12 + .../src/main/scala/java/lang/System.scala | 12 + .../src/main/scala/java/lang/Thread.scala | 12 + .../main/scala/java/lang/ThreadLocal.scala | 12 + .../src/main/scala/java/lang/Throwables.scala | 12 + .../src/main/scala/java/lang/Void.scala | 12 + .../java/lang/annotation/Annotation.scala | 12 + .../java/lang/ref/PhantomReference.scala | 12 + .../main/scala/java/lang/ref/Reference.scala | 12 + .../scala/java/lang/ref/ReferenceQueue.scala | 12 + .../scala/java/lang/ref/SoftReference.scala | 12 + .../scala/java/lang/ref/WeakReference.scala | 12 + .../main/scala/java/lang/reflect/Array.scala | 12 + .../testsuite/javalib/lang/ObjectTestEx.scala | 19 +- .../javalibex/ZipInputStreamTest.scala | 12 + .../jsinterop/ScalaJSDefinedTestEx.scala | 19 +- .../testsuite/utils/AssertThrows.scala | 12 + .../scalajs/testsuite/utils/Platform.scala | 19 +- .../java/util/zip/InflaterInputStream.scala | 12 + .../main/scala/java/util/zip/ZipEntry.scala | 12 + .../scala/java/util/zip/ZipInputStream.scala | 12 + .../main/scala/java/io/BufferedReader.scala | 12 + .../scala/java/io/ByteArrayInputStream.scala | 12 + .../scala/java/io/ByteArrayOutputStream.scala | 12 + .../src/main/scala/java/io/Closeable.scala | 12 + .../src/main/scala/java/io/DataInput.scala | 12 + .../main/scala/java/io/DataInputStream.scala | 12 + .../src/main/scala/java/io/DataOutput.scala | 12 + .../main/scala/java/io/DataOutputStream.scala | 12 + .../scala/java/io/FilterInputStream.scala | 12 + .../scala/java/io/FilterOutputStream.scala | 12 + .../src/main/scala/java/io/Flushable.scala | 12 + .../src/main/scala/java/io/InputStream.scala | 12 + .../scala/java/io/InputStreamReader.scala | 12 + .../src/main/scala/java/io/OutputStream.scala | 12 + .../scala/java/io/OutputStreamWriter.scala | 12 + .../src/main/scala/java/io/PrintStream.scala | 12 + .../src/main/scala/java/io/PrintWriter.scala | 12 + javalib/src/main/scala/java/io/Reader.scala | 12 + .../src/main/scala/java/io/Serializable.scala | 12 + .../src/main/scala/java/io/StringReader.scala | 12 + .../src/main/scala/java/io/StringWriter.scala | 12 + .../src/main/scala/java/io/Throwables.scala | 12 + javalib/src/main/scala/java/io/Writer.scala | 12 + .../main/scala/java/lang/AutoCloseable.scala | 12 + .../main/scala/java/lang/MathJDK8Bridge.scala | 12 + .../main/scala/java/math/Multiplication.scala | 1 + .../src/main/scala/java/net/Throwables.scala | 12 + javalib/src/main/scala/java/net/URI.scala | 12 + .../src/main/scala/java/net/URLDecoder.scala | 12 + javalib/src/main/scala/java/nio/Buffer.scala | 12 + .../java/nio/BufferOverflowException.scala | 12 + .../java/nio/BufferUnderflowException.scala | 12 + .../main/scala/java/nio/ByteArrayBits.scala | 12 + .../src/main/scala/java/nio/ByteBuffer.scala | 12 + .../src/main/scala/java/nio/ByteOrder.scala | 12 + .../src/main/scala/java/nio/CharBuffer.scala | 12 + .../scala/java/nio/DataViewCharBuffer.scala | 12 + .../scala/java/nio/DataViewDoubleBuffer.scala | 12 + .../scala/java/nio/DataViewFloatBuffer.scala | 12 + .../scala/java/nio/DataViewIntBuffer.scala | 12 + .../scala/java/nio/DataViewLongBuffer.scala | 12 + .../scala/java/nio/DataViewShortBuffer.scala | 12 + .../main/scala/java/nio/DoubleBuffer.scala | 12 + .../src/main/scala/java/nio/FloatBuffer.scala | 12 + .../src/main/scala/java/nio/GenBuffer.scala | 12 + .../scala/java/nio/GenDataViewBuffer.scala | 12 + .../main/scala/java/nio/GenHeapBuffer.scala | 12 + .../scala/java/nio/GenHeapBufferView.scala | 12 + .../scala/java/nio/GenTypedArrayBuffer.scala | 12 + .../main/scala/java/nio/HeapByteBuffer.scala | 12 + .../java/nio/HeapByteBufferCharView.scala | 12 + .../java/nio/HeapByteBufferDoubleView.scala | 12 + .../java/nio/HeapByteBufferFloatView.scala | 12 + .../java/nio/HeapByteBufferIntView.scala | 12 + .../java/nio/HeapByteBufferLongView.scala | 12 + .../java/nio/HeapByteBufferShortView.scala | 12 + .../main/scala/java/nio/HeapCharBuffer.scala | 12 + .../scala/java/nio/HeapDoubleBuffer.scala | 12 + .../main/scala/java/nio/HeapFloatBuffer.scala | 12 + .../main/scala/java/nio/HeapIntBuffer.scala | 12 + .../main/scala/java/nio/HeapLongBuffer.scala | 12 + .../main/scala/java/nio/HeapShortBuffer.scala | 12 + .../src/main/scala/java/nio/IntBuffer.scala | 12 + .../scala/java/nio/InvalidMarkException.scala | 12 + .../src/main/scala/java/nio/LongBuffer.scala | 12 + .../java/nio/ReadOnlyBufferException.scala | 12 + .../src/main/scala/java/nio/ShortBuffer.scala | 12 + .../scala/java/nio/StringCharBuffer.scala | 12 + .../scala/java/nio/TypedArrayByteBuffer.scala | 12 + .../scala/java/nio/TypedArrayCharBuffer.scala | 12 + .../java/nio/TypedArrayDoubleBuffer.scala | 12 + .../java/nio/TypedArrayFloatBuffer.scala | 12 + .../scala/java/nio/TypedArrayIntBuffer.scala | 12 + .../java/nio/TypedArrayShortBuffer.scala | 12 + .../charset/CharacterCodingException.scala | 12 + .../main/scala/java/nio/charset/Charset.scala | 12 + .../java/nio/charset/CharsetDecoder.scala | 12 + .../java/nio/charset/CharsetEncoder.scala | 12 + .../nio/charset/CoderMalfunctionError.scala | 12 + .../scala/java/nio/charset/CoderResult.scala | 12 + .../java/nio/charset/CodingErrorAction.scala | 12 + .../nio/charset/MalformedInputException.scala | 12 + .../java/nio/charset/StandardCharsets.scala | 12 + .../UnmappableCharacterException.scala | 12 + .../charset/UnsupportedCharsetException.scala | 12 + .../src/main/scala/java/security/Guard.scala | 12 + .../main/scala/java/security/Permission.scala | 12 + .../main/scala/java/security/Throwables.scala | 12 + .../scala/java/util/AbstractCollection.scala | 12 + .../main/scala/java/util/AbstractList.scala | 12 + .../main/scala/java/util/AbstractMap.scala | 12 + .../main/scala/java/util/AbstractQueue.scala | 12 + .../AbstractRandomAccessListIterator.scala | 12 + .../java/util/AbstractSequentialList.scala | 12 + .../main/scala/java/util/AbstractSet.scala | 12 + .../src/main/scala/java/util/ArrayDeque.scala | 12 + .../src/main/scala/java/util/ArrayList.scala | 12 + javalib/src/main/scala/java/util/Arrays.scala | 12 + javalib/src/main/scala/java/util/Base64.scala | 12 + .../src/main/scala/java/util/Collection.scala | 12 + .../main/scala/java/util/Collections.scala | 12 + .../src/main/scala/java/util/Comparator.scala | 12 + javalib/src/main/scala/java/util/Compat.scala | 12 + javalib/src/main/scala/java/util/Date.scala | 13 +- javalib/src/main/scala/java/util/Deque.scala | 12 + .../src/main/scala/java/util/Dictionary.scala | 12 + .../main/scala/java/util/Enumeration.scala | 12 + .../main/scala/java/util/EventObject.scala | 12 + .../main/scala/java/util/Formattable.scala | 12 + .../scala/java/util/FormattableFlags.scala | 12 + .../src/main/scala/java/util/Formatter.scala | 12 + .../src/main/scala/java/util/HashMap.scala | 12 + .../src/main/scala/java/util/HashSet.scala | 12 + .../src/main/scala/java/util/Hashtable.scala | 12 + .../src/main/scala/java/util/Iterator.scala | 12 + .../main/scala/java/util/LinkedHashMap.scala | 12 + .../main/scala/java/util/LinkedHashSet.scala | 12 + .../src/main/scala/java/util/LinkedList.scala | 12 + javalib/src/main/scala/java/util/List.scala | 12 + .../main/scala/java/util/ListIterator.scala | 12 + javalib/src/main/scala/java/util/Map.scala | 12 + .../main/scala/java/util/NavigableMap.scala | 12 + .../main/scala/java/util/NavigableSet.scala | 12 + .../main/scala/java/util/NavigableView.scala | 12 + .../src/main/scala/java/util/Objects.scala | 12 + .../src/main/scala/java/util/Optional.scala | 12 + .../main/scala/java/util/PriorityQueue.scala | 12 + .../src/main/scala/java/util/Properties.scala | 12 + javalib/src/main/scala/java/util/Queue.scala | 12 + javalib/src/main/scala/java/util/Random.scala | 12 + .../main/scala/java/util/RandomAccess.scala | 12 + javalib/src/main/scala/java/util/Set.scala | 12 + .../scala/java/util/SizeChangeEvent.scala | 12 + .../src/main/scala/java/util/SortedMap.scala | 12 + .../src/main/scala/java/util/SortedSet.scala | 12 + .../scala/java/util/SplittableRandom.scala | 12 + .../src/main/scala/java/util/Throwables.scala | 12 + javalib/src/main/scala/java/util/Timer.scala | 12 + .../src/main/scala/java/util/TimerTask.scala | 12 + .../src/main/scala/java/util/TreeSet.scala | 12 + javalib/src/main/scala/java/util/UUID.scala | 12 + .../scala/java/util/concurrent/Callable.scala | 12 + .../util/concurrent/ConcurrentHashMap.scala | 12 + .../concurrent/ConcurrentLinkedQueue.scala | 12 + .../java/util/concurrent/ConcurrentMap.scala | 12 + .../concurrent/ConcurrentSkipListSet.scala | 12 + .../concurrent/CopyOnWriteArrayList.scala | 12 + .../scala/java/util/concurrent/Executor.scala | 12 + .../java/util/concurrent/ThreadFactory.scala | 12 + .../java/util/concurrent/Throwables.scala | 12 + .../scala/java/util/concurrent/TimeUnit.scala | 12 + .../concurrent/atomic/AtomicBoolean.scala | 12 + .../concurrent/atomic/AtomicInteger.scala | 12 + .../util/concurrent/atomic/AtomicLong.scala | 12 + .../concurrent/atomic/AtomicLongArray.scala | 12 + .../concurrent/atomic/AtomicReference.scala | 12 + .../atomic/AtomicReferenceArray.scala | 12 + .../java/util/concurrent/locks/Lock.scala | 12 + .../util/concurrent/locks/ReentrantLock.scala | 12 + .../src/main/scala/java/util/package.scala | 12 + .../scala/java/util/regex/GroupStartMap.scala | 12 + .../scala/java/util/regex/MatchResult.scala | 12 + .../main/scala/java/util/regex/Matcher.scala | 12 + .../main/scala/java/util/regex/Pattern.scala | 12 + .../typedarray/TypedArrayBufferBridge.scala | 20 +- .../org/scalajs/jsenv/test/AsyncTests.scala | 12 + .../scalajs/jsenv/test/BasicJSEnvTests.scala | 12 + .../org/scalajs/jsenv/test/ComTests.scala | 12 + .../jsenv/test/CustomInitFilesTest.scala | 12 + .../org/scalajs/jsenv/test/JSEnvTest.scala | 12 + .../scalajs/jsenv/test/StoreJSConsole.scala | 12 + .../org/scalajs/jsenv/test/StoreLogger.scala | 12 + .../scalajs/jsenv/test/TimeoutComTests.scala | 12 + .../org/scalajs/jsenv/test/TimeoutTests.scala | 12 + .../jsenv/test/JSDOMNodeJSEnvTest.scala | 12 + .../org/scalajs/jsenv/test/NodeJSTest.scala | 12 + .../test/NodeJSWithCustomInitFilesTest.scala | 12 + .../scalajs/jsenv/test/PhantomJSTest.scala | 12 + .../PhantomJSWithCustomInitFilesTest.scala | 12 + .../jsenv/test/RetryingComJSEnvTest.scala | 12 + .../scalajs/jsenv/test/RhinoJSEnvTest.scala | 12 + .../scala/org/scalajs/jsenv/AsyncJSEnv.scala | 19 +- .../org/scalajs/jsenv/AsyncJSRunner.scala | 12 + .../scala/org/scalajs/jsenv/ComJSEnv.scala | 19 +- .../scala/org/scalajs/jsenv/ComJSRunner.scala | 12 + .../org/scalajs/jsenv/ConsoleJSConsole.scala | 19 +- .../org/scalajs/jsenv/ExternalJSEnv.scala | 12 + .../scala/org/scalajs/jsenv/JSConsole.scala | 19 +- .../main/scala/org/scalajs/jsenv/JSEnv.scala | 19 +- .../scala/org/scalajs/jsenv/JSInitFiles.scala | 12 + .../scala/org/scalajs/jsenv/JSRunner.scala | 19 +- .../scalajs/jsenv/LinkingUnitAsyncJSEnv.scala | 19 +- .../scalajs/jsenv/LinkingUnitComJSEnv.scala | 19 +- .../org/scalajs/jsenv/LinkingUnitJSEnv.scala | 19 +- .../org/scalajs/jsenv/NullJSConsole.scala | 12 + .../org/scalajs/jsenv/RetryingComJSEnv.scala | 19 +- .../main/scala/org/scalajs/jsenv/Utils.scala | 19 +- .../jsenv/VirtualFileMaterializer.scala | 12 + .../jsenv/jsdomnodejs/JSDOMNodeJSEnv.scala | 18 +- .../jsenv/nodejs/AbstractNodeJSEnv.scala | 19 +- .../scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala | 19 +- .../org/scalajs/jsenv/nodejs/NodeJSEnv.scala | 19 +- .../phantomjs/JettyWebsocketManager.scala | 12 + .../jsenv/phantomjs/PhantomJSEnv.scala | 19 +- .../phantomjs/PhantomJettyClassLoader.scala | 12 + .../jsenv/phantomjs/WebsocketListener.scala | 12 + .../jsenv/phantomjs/WebsocketManager.scala | 12 + .../jsenv/rhino/LazyScalaJSScope.scala | 19 +- .../org/scalajs/jsenv/rhino/RhinoJSEnv.scala | 19 +- .../scalajs/jsenv/rhino/ScalaJSCoreLib.scala | 19 +- .../org/scalajs/jsenv/rhino/package.scala | 19 +- .../junit/plugin/Compat210Component.scala | 12 + .../junit/plugin/ScalaJSJUnitPlugin.scala | 12 + .../main/scala/com/novocode/junit/Ansi.scala | 12 + .../com/novocode/junit/JUnitFramework.scala | 12 + .../scala/com/novocode/junit/RichLogger.scala | 12 + .../com/novocode/junit/RunSettings.scala | 12 + .../scala/org/hamcrest/LICENSE-hamcrest.txt | 27 +++ .../org/scalajs/junit/JUnitBaseRunner.scala | 12 + .../scala/org/scalajs/junit/JUnitEvent.scala | 12 + .../org/scalajs/junit/JUnitExecuteTest.scala | 12 + .../org/scalajs/junit/JUnitMasterRunner.scala | 12 + .../org/scalajs/junit/JUnitSlaveRunner.scala | 12 + .../scala/org/scalajs/junit/JUnitTask.scala | 12 + .../scalajs/junit/JUnitTestBootstrapper.scala | 12 + .../junit/utils/JUnitTestPlatformImpl.scala | 12 + .../junit/utils/JUnitTestPlatformImpl.scala | 12 + .../org/scalajs/junit/AssertEquals2Test.scala | 12 + .../junit/AssertEqualsDoubleTest.scala | 12 + .../org/scalajs/junit/AssertEqualsTest.scala | 12 + .../org/scalajs/junit/AssertFalse2Test.scala | 12 + .../org/scalajs/junit/AssertFalseTest.scala | 12 + .../junit/AssertStringEqualsTest.scala | 12 + .../org/scalajs/junit/AssertTrueTest.scala | 12 + .../scala/org/scalajs/junit/AssumeTest.scala | 12 + .../scalajs/junit/BeforeAndAfterTest.scala | 12 + .../scalajs/junit/BeforeAssumeFailTest.scala | 12 + .../scalajs/junit/ExceptionInAfterTest.scala | 12 + .../scalajs/junit/ExceptionInBeforeTest.scala | 12 + .../junit/ExceptionInConstructorTest.scala | 12 + .../org/scalajs/junit/ExceptionTest.scala | 12 + .../scala/org/scalajs/junit/IgnoreTest.scala | 12 + .../scalajs/junit/MethodNameDecodeTest.scala | 12 + .../scala/org/scalajs/junit/Multi1Test.scala | 12 + .../scala/org/scalajs/junit/Multi2Test.scala | 12 + .../scalajs/junit/MultiAssumeFail1Test.scala | 12 + .../scalajs/junit/MultiAssumeFail2Test.scala | 12 + .../junit/MultiBeforeAssumeFailTest.scala | 12 + .../org/scalajs/junit/MultiIgnore1Test.scala | 12 + .../org/scalajs/junit/MultiIgnore2Test.scala | 12 + .../scalajs/junit/MultiIgnoreAllTest.scala | 12 + .../org/scalajs/junit/utils/JUnitTest.scala | 12 + .../scala/scala/runtime/ArrayRuntime.scala | 12 + .../main/scala/scala/runtime/BoxedUnit.scala | 12 + .../main/scala/scala/runtime/RefTypes.scala | 12 + .../main/scala/scala/runtime/Statics.scala | 12 + .../scala/scalajs/js/Any.scala | 19 +- .../scala/scalajs/js/ArrayOps.scala | 18 +- .../scala/scalajs/js/JSConverters.scala | 19 +- .../scala/scalajs/js/WrappedArray.scala | 18 +- .../scala/scalajs/js/WrappedDictionary.scala | 18 +- .../scala/scalajs/runtime/Compat.scala | 12 + .../scalajs/runtime/WrappedVarArgs.scala | 12 + .../scala/scalajs/js/Any.scala | 19 +- .../scala/scalajs/js/ArrayOps.scala | 18 +- .../scala/scalajs/js/JSConverters.scala | 19 +- .../scala/scalajs/js/WrappedArray.scala | 18 +- .../scala/scalajs/js/WrappedDictionary.scala | 18 +- .../scala/scalajs/runtime/Compat.scala | 12 + .../scalajs/runtime/WrappedVarArgs.scala | 12 + .../scala/scalajs/js/Any.scala | 19 +- .../scala/scalajs/js/ArrayOps.scala | 18 +- .../scala/scalajs/js/JSConverters.scala | 19 +- .../scala/scalajs/js/WrappedArray.scala | 18 +- .../scala/scalajs/js/WrappedDictionary.scala | 18 +- .../scala/scalajs/runtime/Compat.scala | 12 + .../scala/scala/scalajs/LinkingInfo.scala | 19 +- .../concurrent/JSExecutionContext.scala | 12 + .../concurrent/QueueExecutionContext.scala | 12 + .../concurrent/RunNowExcecutionContext.scala | 12 + .../main/scala/scala/scalajs/js/Array.scala | 19 +- .../scala/scalajs/js/ArrayOpsCommon.scala | 18 +- .../scala/scalajs/js/ConstructorTag.scala | 19 +- .../main/scala/scala/scalajs/js/Date.scala | 19 +- .../scala/scala/scalajs/js/Dictionary.scala | 19 +- .../main/scala/scala/scalajs/js/Dynamic.scala | 19 +- .../scala/scalajs/js/DynamicImplicits.scala | 19 +- .../main/scala/scala/scalajs/js/Error.scala | 19 +- .../scala/scalajs/js/Function.nodoc.scala | 18 +- .../scala/scala/scalajs/js/Function.scala | 19 +- .../scala/scala/scalajs/js/GlobalScope.scala | 20 +- .../scala/scala/scalajs/js/Iterable.scala | 19 +- .../scala/scala/scalajs/js/IterableOps.scala | 18 +- .../scala/scala/scalajs/js/Iterator.scala | 19 +- .../main/scala/scala/scalajs/js/JSApp.scala | 12 + .../scala/scala/scalajs/js/JSArrayOps.scala | 19 +- .../scala/scala/scalajs/js/JSNumberOps.scala | 19 +- .../main/scala/scala/scalajs/js/JSON.scala | 19 +- .../scala/scala/scalajs/js/JSStringOps.scala | 19 +- .../scalajs/js/JavaScriptException.scala | 20 +- .../main/scala/scala/scalajs/js/Math.scala | 19 +- .../main/scala/scala/scalajs/js/Object.scala | 19 +- .../main/scala/scala/scalajs/js/Promise.scala | 19 +- .../scala/scalajs/js/PropertyDescriptor.scala | 20 +- .../main/scala/scala/scalajs/js/RegExp.scala | 19 +- .../main/scala/scala/scalajs/js/Symbol.scala | 19 +- .../scala/scala/scalajs/js/Thenable.scala | 19 +- .../scala/scalajs/js/ThisFunction.nodoc.scala | 19 +- .../scala/scala/scalajs/js/ThisFunction.scala | 19 +- .../scala/scala/scalajs/js/Tuple.nodoc.scala | 18 +- .../main/scala/scala/scalajs/js/Tuple.scala | 19 +- .../scala/scala/scalajs/js/URIUtils.scala | 20 +- .../main/scala/scala/scalajs/js/UndefOr.scala | 19 +- .../scalajs/js/UnicodeNormalizationForm.scala | 19 +- .../main/scala/scala/scalajs/js/Union.scala | 19 +- .../main/scala/scala/scalajs/js/Using.scala | 19 +- .../js/annotation/ExposedJSMember.scala | 19 +- .../js/annotation/JSBracketAccess.scala | 20 +- .../scalajs/js/annotation/JSBracketCall.scala | 20 +- .../scalajs/js/annotation/JSExport.scala | 20 +- .../scalajs/js/annotation/JSExportAll.scala | 20 +- .../JSExportDescendentClasses.scala | 20 +- .../JSExportDescendentObjects.scala | 20 +- .../scalajs/js/annotation/JSExportNamed.scala | 20 +- .../js/annotation/JSExportStatic.scala | 18 +- .../js/annotation/JSExportTopLevel.scala | 20 +- .../scalajs/js/annotation/JSFullName.scala | 19 +- .../scalajs/js/annotation/JSGlobal.scala | 18 +- .../scalajs/js/annotation/JSGlobalScope.scala | 19 +- .../scalajs/js/annotation/JSImport.scala | 19 +- .../scala/scalajs/js/annotation/JSName.scala | 20 +- .../js/annotation/JavaDefaultMethod.scala | 19 +- .../scalajs/js/annotation/RawJSType.scala | 20 +- .../annotation/SJSDefinedAnonymousClass.scala | 12 + .../js/annotation/ScalaJSDefined.scala | 19 +- .../js/annotation/WasPublicBeforeTyper.scala | 12 + .../internal/HasJSNativeLoadSpec.scala | 19 +- .../js/annotation/internal/JSOptional.scala | 18 +- .../main/scala/scala/scalajs/js/defined.scala | 18 +- .../main/scala/scala/scalajs/js/package.scala | 20 +- .../scala/scalajs/js/special/package.scala | 18 +- .../scala/scalajs/js/timers/Handles.scala | 19 +- .../scala/scalajs/js/timers/RawTimers.scala | 19 +- .../scala/scalajs/js/timers/package.scala | 19 +- .../scalajs/js/typedarray/ArrayBuffer.scala | 12 + .../typedarray/ArrayBufferInputStream.scala | 12 + .../js/typedarray/ArrayBufferView.scala | 12 + .../scalajs/js/typedarray/DataView.scala | 12 + .../scalajs/js/typedarray/DataViewExt.scala | 19 +- .../scalajs/js/typedarray/Float32Array.scala | 12 + .../scalajs/js/typedarray/Float64Array.scala | 12 + .../scalajs/js/typedarray/Int16Array.scala | 12 + .../scalajs/js/typedarray/Int32Array.scala | 12 + .../scalajs/js/typedarray/Int8Array.scala | 12 + .../scalajs/js/typedarray/TypedArray.scala | 12 + .../js/typedarray/TypedArrayBuffer.scala | 19 +- .../typedarray/TypedArrayBufferBridge.scala | 20 +- .../js/typedarray/TypedArrayBufferOps.scala | 19 +- .../scalajs/js/typedarray/Uint16Array.scala | 12 + .../scalajs/js/typedarray/Uint32Array.scala | 12 + .../scalajs/js/typedarray/Uint8Array.scala | 12 + .../js/typedarray/Uint8ClampedArray.scala | 12 + .../scala/scalajs/js/typedarray/package.scala | 12 + .../scala/scalajs/macroimpls/Compat210.scala | 19 +- .../macroimpls/JSMemberSelection.scala | 19 +- .../scala/scalajs/macroimpls/JSMembers.scala | 19 +- .../scalajs/macroimpls/UseAsMacros.scala | 19 +- .../scala/scalajs/niocharset/ISO_8859_1.scala | 19 +- .../ISO_8859_1_And_US_ASCII_Common.scala | 19 +- .../scalajs/niocharset/StandardCharsets.scala | 19 +- .../scala/scalajs/niocharset/US_ASCII.scala | 19 +- .../scala/scalajs/niocharset/UTF_16.scala | 19 +- .../scala/scalajs/niocharset/UTF_16BE.scala | 19 +- .../scala/scalajs/niocharset/UTF_16LE.scala | 19 +- .../scalajs/niocharset/UTF_16_Common.scala | 19 +- .../scala/scalajs/niocharset/UTF_8.scala | 19 +- .../scala/scala/scalajs/reflect/Reflect.scala | 19 +- .../EnableReflectiveInstantiation.scala | 19 +- .../scala/scalajs/runtime/AnonFunctions.scala | 12 + .../scala/scala/scalajs/runtime/Bits.scala | 19 +- .../runtime/BooleanReflectiveCall.scala | 12 + .../scalajs/runtime/EnvironmentInfo.scala | 12 + .../runtime/IntegerReflectiveCall.scala | 12 + .../scala/scalajs/runtime/LinkingInfo.scala | 12 + .../scalajs/runtime/LongReflectiveCall.scala | 12 + .../runtime/NumberReflectiveCall.scala | 12 + .../scala/scalajs/runtime/RuntimeLong.scala | 12 + .../scala/scalajs/runtime/RuntimeString.scala | 12 + .../scalajs/runtime/SemanticsUtils.scala | 12 + .../scala/scalajs/runtime/StackTrace.scala | 12 + .../runtime/UndefinedBehaviorError.scala | 12 + .../scala/scala/scalajs/runtime/package.scala | 12 + .../noircheck/DummyParentsTest.scala | 19 +- .../partest/scalajs/ScalaJSPartest.scala | 13 +- .../scala/tools/nsc/MainGenericRunner.scala | 12 + .../partest/scalajs/PartestInterface.scala | 12 + .../scalajs/ScalaJSPartestOptions.scala | 12 + project/Build.scala | 109 ++++++--- project/build.sbt | 2 + .../org/scalajs/sbtplugin/SBTCompat.scala | 12 + .../sbtplugin/JSDependenciesPlugin.scala | 18 +- .../scalajs/sbtplugin/AbstractJSDeps.scala | 12 + .../scalajs/sbtplugin/FrameworkDetector.scala | 12 + .../sbtplugin/HTMLRunnerTemplate.scala | 19 +- .../org/scalajs/sbtplugin/Implicits.scala | 12 + .../scalajs/sbtplugin/LoggerJSConsole.scala | 19 +- .../scala/org/scalajs/sbtplugin/Loggers.scala | 12 + .../scalajs/sbtplugin/OptimizerOptions.scala | 19 +- .../sbtplugin/ScalaJSCrossVersion.scala | 19 +- .../sbtplugin/ScalaJSJUnitPlugin.scala | 18 +- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 19 +- .../sbtplugin/ScalaJSPluginInternal.scala | 12 + .../org/scalajs/sbtplugin/ScalajspUtils.scala | 19 +- .../scala/org/scalajs/sbtplugin/Stage.scala | 19 +- .../cross/CrossClasspathDependency.scala | 19 +- .../sbtplugin/cross/CrossProject.scala | 19 +- .../scalajs/sbtplugin/cross/CrossType.scala | 19 +- .../scalajs/sbtplugin/cross/MacroUtils.scala | 19 +- .../sbtplugin/impl/DependencyBuilders.scala | 19 +- .../internal/ScalaJSGlobalPlugin.scala | 18 +- .../org/scalajs/testinterface/TestUtils.scala | 12 + .../js/annotation/ExportAnnotations.scala | 19 +- .../annotation/ReflectAnnotations.scala | 19 +- .../scalajs/sbttestadapter/ComJSEnvRPC.scala | 19 +- .../sbttestadapter/FrameworkAdapter.scala | 19 +- .../sbttestadapter/RemoteException.scala | 19 +- .../sbttestadapter/RunnerAdapter.scala | 19 +- .../sbttestadapter/ScalaJSFramework.scala | 19 +- .../sbttestadapter/ScalaJSRunner.scala | 19 +- .../scalajs/sbttestadapter/ScalaJSTask.scala | 19 +- .../scalajs/sbttestadapter/TaskAdapter.scala | 19 +- .../scalajs/sbttestadapter/TestAdapter.scala | 19 +- .../org/scalajs/sbttestadapter/package.scala | 19 +- .../org/scalajs/testcommon/Endpoints.scala | 12 + .../scalajs/testcommon/ExecuteRequest.scala | 12 + .../scalajs/testcommon/FrameworkInfo.scala | 12 + .../scalajs/testcommon/FrameworkMessage.scala | 12 + .../org/scalajs/testcommon/FutureUtil.scala | 12 + .../org/scalajs/testcommon/JSEndpoints.scala | 12 + .../org/scalajs/testcommon/JVMEndpoints.scala | 12 + .../org/scalajs/testcommon/LogElement.scala | 12 + .../org/scalajs/testcommon/RPCCore.scala | 12 + .../scala/org/scalajs/testcommon/RunMux.scala | 12 + .../org/scalajs/testcommon/RunMuxRPC.scala | 12 + .../org/scalajs/testcommon/RunnerArgs.scala | 12 + .../org/scalajs/testcommon/Serializer.scala | 12 + .../org/scalajs/testcommon/TaskInfo.scala | 12 + .../org/scalajs/testcommon/RPCCoreTest.scala | 12 + .../scalajs/testcommon/RunMuxRPCTest.scala | 12 + .../scalajs/testcommon/SerializerTest.scala | 12 + .../scalajs/testinterface/HTMLRunner.scala | 19 +- .../testinterface/ScalaJSClassLoader.scala | 12 + .../scalajs/testinterface/TestDetector.scala | 12 + .../org/scalajs/testinterface/TestUtils.scala | 12 + .../testinterface/internal/Bridge.scala | 12 + .../internal/FrameworkLoader.scala | 12 + .../testinterface/internal/JSRPC.scala | 12 + .../internal/TaskInfoBuilder.scala | 12 + .../src/main/scala/sbt/testing/Event.scala | 12 + .../main/scala/sbt/testing/EventHandler.scala | 12 + .../main/scala/sbt/testing/Fingerprints.scala | 12 + .../main/scala/sbt/testing/Framework.scala | 12 + .../src/main/scala/sbt/testing/Logger.scala | 12 + .../scala/sbt/testing/OptionalThrowable.scala | 12 + .../src/main/scala/sbt/testing/Runner.scala | 12 + .../main/scala/sbt/testing/Selectors.scala | 12 + .../src/main/scala/sbt/testing/Status.scala | 12 + .../src/main/scala/sbt/testing/Task.scala | 12 + .../src/main/scala/sbt/testing/TaskDef.scala | 12 + .../org/scalajs/testsuite/Compat210.scala | 19 +- .../org/scalajs/testsuite/Typechecking.scala | 19 +- .../testsuite/TypecheckingMacros.scala | 19 +- .../ScalaJSDefinedTestSeparateRun.scala | 19 +- .../junit/MultiCompilationTest.scala | 12 + .../scalajs/testsuite/utils/Platform.scala | 19 +- .../jsinterop/JSOptionalTest212.scala | 19 +- .../resources/SourceMapTestTemplate.scala | 14 +- .../ArrayOpsCollectionEraDependentTest.scala | 19 +- .../library/WrappedArrayToTest.scala | 19 +- .../library/WrappedDictionaryToTest.scala | 19 +- .../ArrayOpsCollectionEraDependentTest.scala | 19 +- .../library/WrappedArrayToTest.scala | 19 +- .../library/WrappedDictionaryToTest.scala | 19 +- .../testsuite/compiler/BooleanJSTest.scala | 19 +- .../compiler/DefaultMethodsJSTest.scala | 19 +- .../testsuite/compiler/FloatJSTest.scala | 19 +- ...nstanceTestsHijackedBoxedClassesTest.scala | 19 +- .../testsuite/compiler/IntJSTest.scala | 19 +- .../compiler/InteroperabilityTest.scala | 19 +- .../testsuite/compiler/LongJSTest.scala | 19 +- .../testsuite/compiler/ModuleInitTest.scala | 19 +- .../compiler/ModuleInitializersTest.scala | 19 +- .../testsuite/compiler/OptimizerTest.scala | 19 +- .../testsuite/compiler/ReflectionTest.scala | 19 +- .../testsuite/compiler/RegressionJSTest.scala | 19 +- .../testsuite/compiler/RuntimeTypesTest.scala | 19 +- .../testsuite/compiler/UnitJSTest.scala | 19 +- .../javalib/io/DataInputStreamJSTest.scala | 12 + .../testsuite/javalib/lang/ClassJSTest.scala | 19 +- .../testsuite/javalib/lang/ObjectJSTest.scala | 19 +- .../lang/StackTraceElementJSTest.scala | 19 +- .../javalib/lang/StringBufferJSTest.scala | 19 +- .../testsuite/javalib/lang/SystemJSTest.scala | 19 +- .../lang/reflect/ReflectArrayJSTest.scala | 19 +- .../javalib/util/FormatterJSTest.scala | 19 +- .../testsuite/javalib/util/TimerTest.scala | 19 +- .../testsuite/jsinterop/ArrayTest.scala | 19 +- .../testsuite/jsinterop/AsyncTest.scala | 19 +- .../testsuite/jsinterop/DictionaryTest.scala | 19 +- .../testsuite/jsinterop/DynamicTest.scala | 19 +- .../testsuite/jsinterop/ExportsTest.scala | 19 +- .../testsuite/jsinterop/FunctionTest.scala | 19 +- .../testsuite/jsinterop/IterableTest.scala | 19 +- .../jsinterop/JSExportStaticTest.scala | 19 +- .../testsuite/jsinterop/JSNameTest.scala | 19 +- .../jsinterop/JSNativeInPackage.scala | 12 + .../testsuite/jsinterop/JSOptionalTest.scala | 19 +- .../testsuite/jsinterop/JSSymbolTest.scala | 19 +- .../testsuite/jsinterop/MiscInteropTest.scala | 19 +- .../ModulesWithGlobalFallbackTest.scala | 19 +- .../testsuite/jsinterop/PrimitivesTest.scala | 19 +- .../testsuite/jsinterop/PromiseMock.scala | 12 + .../testsuite/jsinterop/RuntimeLongTest.scala | 19 +- .../jsinterop/ScalaJSDefinedTest.scala | 19 +- .../testsuite/jsinterop/SpecialTest.scala | 19 +- .../jsinterop/StrangeNamedTests.scala | 19 +- .../testsuite/jsinterop/SymbolTest.scala | 19 +- .../jsinterop/ThisFunctionTest.scala | 19 +- .../testsuite/jsinterop/TimeoutMock.scala | 12 + .../testsuite/jsinterop/TupleTest.scala | 19 +- .../testsuite/jsinterop/UndefOrTest.scala | 19 +- .../junit/JUnitAbstractClassTest.scala | 12 + .../testsuite/junit/JUnitBootstrapTest.scala | 12 + .../testsuite/junit/JUnitMixinTest.scala | 12 + .../testsuite/junit/JUnitNamesTest.scala | 12 + .../testsuite/junit/JUnitPackageTest.scala | 12 + .../testsuite/junit/JUnitSubClassTest.scala | 12 + .../scalajs/testsuite/junit/JUnitUtil.scala | 12 + .../MultiCompilationSecondUnitTest.scala | 12 + .../testsuite/library/ArrayOpsTest.scala | 19 +- .../library/JavaScriptExceptionTest.scala | 19 +- .../testsuite/library/LinkingInfoTest.scala | 19 +- .../testsuite/library/ReflectTest.scala | 19 +- .../testsuite/library/StackTraceTest.scala | 19 +- .../testsuite/library/UnionTypeTest.scala | 19 +- .../scalajs/testsuite/library/UseAsTest.scala | 19 +- .../testsuite/library/WrappedArrayTest.scala | 19 +- .../library/WrappedDictionaryTest.scala | 19 +- .../niobuffer/ByteBufferJSFactories.scala | 12 + .../niobuffer/ByteBufferJSTest.scala | 19 +- .../niobuffer/CharBufferJSTest.scala | 19 +- .../niobuffer/DoubleBufferJSTest.scala | 19 +- .../niobuffer/FloatBufferJSTest.scala | 19 +- .../testsuite/niobuffer/IntBufferJSTest.scala | 19 +- .../niobuffer/LongBufferJSTest.scala | 19 +- .../niobuffer/ShortBufferJSTest.scala | 19 +- .../niobuffer/SupportsTypedArrays.scala | 19 +- .../testsuite/niocharset/CharsetJSTest.scala | 12 + .../scalalib/ScalaRunTimeJSTest.scala | 12 + .../ArrayBufferInputStreamTest.scala | 19 +- .../typedarray/ArrayBufferTest.scala | 19 +- .../testsuite/typedarray/ArraysTest.scala | 19 +- .../testsuite/typedarray/DataViewTest.scala | 19 +- .../typedarray/TypedArrayConversionTest.scala | 19 +- .../testsuite/typedarray/TypedArrayTest.scala | 19 +- .../scalajs/testsuite/utils/JSAssert.scala | 12 + .../org/scalajs/testsuite/utils/JSUtils.scala | 12 + .../testsuite/utils/PlatformTest.scala | 19 +- .../scalajs/testsuite/utils/Requires.scala | 12 + .../scalajs/testsuite/utils/Platform.scala | 12 + .../javalib/io/AutoCloseableTest.scala | 19 +- .../javalib/lang/CharacterTestOnJDK7.scala | 19 +- .../javalib/lang/SystemTestOnJDK7.scala | 19 +- .../javalib/lang/ThrowablesTestOnJDK7.scala | 19 +- .../javalib/util/CollectionsTestOnJDK7.scala | 19 +- .../javalib/util/ObjectsTestOnJDK7.scala | 12 + .../concurrent/ThreadLocalRandomTest.scala | 19 +- .../compiler/DefaultMethodsTest.scala | 19 +- .../javalib/lang/DoubleTestJDK8.scala | 19 +- .../javalib/lang/FloatTestJDK8.scala | 19 +- .../javalib/lang/IntegerTestOnJDK8.scala | 19 +- .../javalib/lang/LongTestOnJDK8.scala | 19 +- .../javalib/lang/MathTestOnJDK8.scala | 12 + .../testsuite/javalib/util/Base64Test.scala | 12 + ...ionsOnCopyOnWriteArrayListTestOnJDK8.scala | 12 + .../javalib/util/ComparatorTestOnJDK8.scala | 19 +- .../javalib/util/ObjectsTestOnJDK8.scala | 12 + .../testsuite/javalib/util/OptionalTest.scala | 19 +- .../javalib/util/SplittableRandom.scala | 19 +- .../testsuite/compiler/ArrayTest.scala | 19 +- .../testsuite/compiler/BooleanTest.scala | 19 +- .../scalajs/testsuite/compiler/ByteTest.scala | 19 +- .../scalajs/testsuite/compiler/CharTest.scala | 19 +- .../testsuite/compiler/DoubleTest.scala | 19 +- .../testsuite/compiler/FloatTest.scala | 19 +- .../scalajs/testsuite/compiler/IntTest.scala | 19 +- .../scalajs/testsuite/compiler/LongTest.scala | 19 +- .../testsuite/compiler/MatchTest.scala | 19 +- .../testsuite/compiler/OuterClassTest.scala | 12 + .../PatMatOuterPointerCheckTest.scala | 12 + .../compiler/ReflectiveCallTest.scala | 19 +- .../testsuite/compiler/RegressionTest.scala | 19 +- .../testsuite/compiler/ShortTest.scala | 19 +- .../scalajs/testsuite/compiler/UnitTest.scala | 19 +- .../javalib/io/ByteArrayInputStreamTest.scala | 19 +- .../io/ByteArrayOutputStreamTest.scala | 19 +- .../javalib/io/CommonStreamsTests.scala | 19 +- .../javalib/io/DataInputStreamTest.scala | 12 + .../javalib/io/DataOutputStreamTest.scala | 12 + .../javalib/io/InputStreamTest.scala | 19 +- .../io/MockByteArrayOutputStream.scala | 19 +- .../javalib/io/OutputStreamWriterTest.scala | 19 +- .../javalib/io/PrintStreamTest.scala | 19 +- .../javalib/io/PrintWriterTest.scala | 19 +- .../testsuite/javalib/io/ReadersTest.scala | 19 +- .../javalib/io/SerializableTest.scala | 12 + .../testsuite/javalib/io/ThrowablesTest.scala | 19 +- .../testsuite/javalib/lang/BooleanTest.scala | 19 +- .../testsuite/javalib/lang/ByteTest.scala | 19 +- .../javalib/lang/CharacterTest.scala | 19 +- .../testsuite/javalib/lang/ClassTest.scala | 19 +- .../testsuite/javalib/lang/DoubleTest.scala | 19 +- .../testsuite/javalib/lang/FloatTest.scala | 19 +- .../testsuite/javalib/lang/IntegerTest.scala | 19 +- .../testsuite/javalib/lang/LongTest.scala | 19 +- .../testsuite/javalib/lang/MathTest.scala | 19 +- .../testsuite/javalib/lang/ObjectTest.scala | 19 +- .../testsuite/javalib/lang/ShortTest.scala | 19 +- .../javalib/lang/StackTraceElementTest.scala | 19 +- .../javalib/lang/StringBufferTest.scala | 19 +- .../javalib/lang/StringBuilderTest.scala | 19 +- .../testsuite/javalib/lang/StringTest.scala | 19 +- .../testsuite/javalib/lang/SystemTest.scala | 19 +- .../testsuite/javalib/lang/ThreadTest.scala | 19 +- .../javalib/lang/ThrowablesTest.scala | 19 +- .../lang/WrappedStringCharSequence.scala | 19 +- .../javalib/lang/ref/ReferenceTest.scala | 19 +- .../lang/reflect/ReflectArrayTest.scala | 19 +- .../math/BigDecimalArithmeticTest.scala | 12 + .../javalib/math/BigDecimalCompareTest.scala | 12 + .../math/BigDecimalConstructorsTest.scala | 12 + .../javalib/math/BigDecimalConvertTest.scala | 12 + .../math/BigDecimalScaleOperationsTest.scala | 12 + .../javalib/math/BigDecimalTest.scala | 19 +- .../javalib/math/BigIntegerAddTest.scala | 12 + .../javalib/math/BigIntegerAndTest.scala | 12 + .../javalib/math/BigIntegerCompareTest.scala | 12 + .../math/BigIntegerConstructorsTest.scala | 12 + .../javalib/math/BigIntegerConvertTest.scala | 12 + .../javalib/math/BigIntegerDivideTest.scala | 12 + .../javalib/math/BigIntegerHashCodeTest.scala | 12 + .../javalib/math/BigIntegerModPowTest.scala | 12 + .../javalib/math/BigIntegerMultiplyTest.scala | 12 + .../javalib/math/BigIntegerNotTest.scala | 12 + .../math/BigIntegerOperateBitsTest.scala | 12 + .../javalib/math/BigIntegerOrTest.scala | 12 + .../javalib/math/BigIntegerSubtractTest.scala | 12 + .../javalib/math/BigIntegerTest.scala | 19 +- .../javalib/math/BigIntegerToStringTest.scala | 12 + .../javalib/math/BigIntegerXorTest.scala | 12 + .../javalib/math/MathContextTest.scala | 12 + .../javalib/math/RoundingModeTest.scala | 12 + .../testsuite/javalib/net/URITest.scala | 19 +- .../javalib/net/URLDecoderTest.scala | 12 + .../javalib/security/ThrowablesTest.scala | 19 +- .../javalib/util/AbstractCollectionTest.scala | 19 +- .../javalib/util/AbstractListTest.scala | 19 +- .../javalib/util/AbstractMapTest.scala | 19 +- .../javalib/util/AbstractSetTest.scala | 19 +- .../javalib/util/ArrayDequeTest.scala | 19 +- .../javalib/util/ArrayListTest.scala | 19 +- .../testsuite/javalib/util/ArraysTest.scala | 19 +- .../javalib/util/CollectionTest.scala | 19 +- .../CollectionsOnCheckedCollectionTest.scala | 19 +- .../util/CollectionsOnCheckedListTest.scala | 19 +- .../util/CollectionsOnCheckedMapTest.scala | 19 +- .../util/CollectionsOnCheckedSetTest.scala | 19 +- .../util/CollectionsOnCollectionsTest.scala | 19 +- .../javalib/util/CollectionsOnListsTest.scala | 12 + .../javalib/util/CollectionsOnMapsTest.scala | 12 + .../util/CollectionsOnSetFromMapTest.scala | 12 + .../javalib/util/CollectionsOnSetsTest.scala | 12 + ...lectionsOnSynchronizedCollectionTest.scala | 19 +- .../CollectionsOnSynchronizedListTest.scala | 19 +- .../CollectionsOnSynchronizedMapTest.scala | 19 +- .../CollectionsOnSynchronizedSetTest.scala | 19 +- .../javalib/util/CollectionsTest.scala | 19 +- .../testsuite/javalib/util/DateTest.scala | 19 +- .../testsuite/javalib/util/DequeTest.scala | 12 + .../javalib/util/EventObjectTest.scala | 19 +- .../javalib/util/FormatterTest.scala | 19 +- .../testsuite/javalib/util/HashMapTest.scala | 19 +- .../testsuite/javalib/util/HashSetTest.scala | 19 +- .../javalib/util/HashtableTest.scala | 12 + .../javalib/util/LinkedHashMapTest.scala | 19 +- .../javalib/util/LinkedHashSetTest.scala | 19 +- .../javalib/util/LinkedListTest.scala | 19 +- .../testsuite/javalib/util/ListTest.scala | 19 +- .../testsuite/javalib/util/MapTest.scala | 19 +- .../javalib/util/NavigableSetTest.scala | 19 +- .../javalib/util/PriorityQueueTest.scala | 19 +- .../javalib/util/PropertiesTest.scala | 12 + .../testsuite/javalib/util/RandomTest.scala | 19 +- .../testsuite/javalib/util/SetTest.scala | 19 +- .../javalib/util/SortedMapTest.scala | 19 +- .../javalib/util/SortedSetTest.scala | 19 +- .../javalib/util/ThrowablesTest.scala | 19 +- .../testsuite/javalib/util/TreeSetTest.scala | 19 +- .../testsuite/javalib/util/UUIDTest.scala | 19 +- .../concurrent/ConcurrentHashMapTest.scala | 19 +- .../ConcurrentLinkedQueueTest.scala | 19 +- .../util/concurrent/ConcurrentMapTest.scala | 19 +- .../ConcurrentSkipListSetTest.scala | 19 +- .../concurrent/CopyOnWriteArrayListTest.scala | 19 +- .../util/concurrent/TimeUnitTest.scala | 19 +- .../util/concurrent/atomic/AtomicTest.scala | 19 +- .../concurrent/locks/ReentrantLockTest.scala | 19 +- .../testsuite/javalib/util/package.scala | 19 +- .../javalib/util/regex/RegexMatcherTest.scala | 19 +- .../javalib/util/regex/RegexPatternTest.scala | 19 +- .../junit/JUnitAnnotationsParamTest.scala | 12 + .../junit/JUnitAnnotationsTest.scala | 12 + .../testsuite/junit/JUnitAssertionsTest.scala | 12 + .../junit/JUnitAssumptionsTest.scala | 12 + .../testsuite/niobuffer/BaseBufferTest.scala | 19 +- .../testsuite/niobuffer/BufferAdapter.scala | 12 + .../testsuite/niobuffer/BufferFactory.scala | 12 + .../niobuffer/ByteBufferFactories.scala | 12 + .../testsuite/niobuffer/ByteBufferTest.scala | 19 +- .../testsuite/niobuffer/CharBufferTest.scala | 19 +- .../niobuffer/DoubleBufferTest.scala | 19 +- .../testsuite/niobuffer/FloatBufferTest.scala | 19 +- .../testsuite/niobuffer/IntBufferTest.scala | 19 +- .../testsuite/niobuffer/LongBufferTest.scala | 19 +- .../testsuite/niobuffer/ShortBufferTest.scala | 19 +- .../niocharset/BaseCharsetTest.scala | 19 +- .../testsuite/niocharset/CharsetTest.scala | 19 +- .../testsuite/niocharset/Latin1Test.scala | 19 +- .../testsuite/niocharset/USASCIITest.scala | 19 +- .../testsuite/niocharset/UTF16Test.scala | 19 +- .../testsuite/niocharset/UTF8Test.scala | 19 +- .../testsuite/scalalib/ArrayBuilderTest.scala | 19 +- .../testsuite/scalalib/ArrayTest.scala | 19 +- .../testsuite/scalalib/ClassTagTest.scala | 19 +- .../testsuite/scalalib/EnumerationTest.scala | 19 +- .../scalalib/NameTransformerTest.scala | 19 +- .../testsuite/scalalib/RangesTest.scala | 19 +- .../testsuite/scalalib/ScalaRunTimeTest.scala | 12 + .../testsuite/scalalib/SymbolTest.scala | 19 +- .../testsuite/utils/AssertThrows.scala | 12 + .../testsuite/utils/CollectionsTestBase.scala | 12 + .../io/IRContainerPlatformExtensions.scala | 19 +- .../core/tools/io/NodeVirtualFiles.scala | 12 + .../org/scalajs/core/tools/json/Impl.scala | 12 + .../linker/LinkerPlatformExtensions.scala | 19 +- .../StandardLinkerPlatformExtensions.scala | 18 +- .../core/tools/test/js/QuickLinker.scala | 12 + .../core/tools/test/js/TestRunner.scala | 12 + .../tools/io/AtomicFileOutputStream.scala | 12 + .../io/AtomicWritableFileVirtualFiles.scala | 12 + .../core/tools/io/FileVirtualFiles.scala | 12 + .../io/IRContainerPlatformExtensions.scala | 19 +- .../org/scalajs/core/tools/json/Impl.scala | 12 + .../linker/LinkerPlatformExtensions.scala | 19 +- .../StandardLinkerPlatformExtensions.scala | 18 +- .../backend/closure/ClosureAstBuilder.scala | 12 + .../closure/ClosureAstTransformer.scala | 12 + .../closure/ClosureLinkerBackend.scala | 19 +- .../backend/closure/LoggerErrorManager.scala | 12 + .../frontend/optimizer/ConcurrencyUtils.scala | 19 +- .../frontend/optimizer/ParIncOptimizer.scala | 19 +- .../scalajs/core/tools/io/CacheUtils.scala | 12 + .../scala/org/scalajs/core/tools/io/IO.scala | 12 + .../scalajs/core/tools/io/IRFileCache.scala | 19 +- .../org/scalajs/core/tools/io/MemFiles.scala | 19 +- .../scalajs/core/tools/io/VirtualFiles.scala | 12 + .../core/tools/javascript/ESLevel.scala | 19 +- .../core/tools/javascript/JSBuilders.scala | 19 +- .../core/tools/javascript/Printers.scala | 19 +- .../tools/javascript/SourceMapWriter.scala | 19 +- .../scalajs/core/tools/javascript/Trees.scala | 19 +- .../core/tools/javascript/package.scala | 12 + .../tools/jsdep/ComplianceRequirement.scala | 12 + .../core/tools/jsdep/DependencyResolver.scala | 12 + .../scalajs/core/tools/jsdep/Exceptions.scala | 12 + .../core/tools/jsdep/FlatJSDependency.scala | 12 + .../core/tools/jsdep/JSDependency.scala | 12 + .../tools/jsdep/JSDependencyManifest.scala | 12 + .../core/tools/jsdep/ManifestFilters.scala | 12 + .../org/scalajs/core/tools/jsdep/Origin.scala | 12 + .../core/tools/jsdep/ResolutionInfo.scala | 12 + .../tools/jsdep/ResolvedJSDependency.scala | 12 + .../core/tools/json/AbstractJSONImpl.scala | 12 + .../core/tools/json/JSONDeserializer.scala | 12 + .../core/tools/json/JSONObjBuilder.scala | 12 + .../core/tools/json/JSONObjExtractor.scala | 12 + .../core/tools/json/JSONSerializer.scala | 12 + .../org/scalajs/core/tools/json/package.scala | 12 + .../core/tools/linker/ClearableLinker.scala | 19 +- .../scalajs/core/tools/linker/GenLinker.scala | 19 +- .../core/tools/linker/LinkedClass.scala | 19 +- .../core/tools/linker/LinkedMember.scala | 19 +- .../scalajs/core/tools/linker/Linker.scala | 19 +- .../core/tools/linker/LinkingException.scala | 18 +- .../core/tools/linker/LinkingUnit.scala | 12 + .../core/tools/linker/ModuleInitializer.scala | 18 +- .../core/tools/linker/StandardLinker.scala | 18 +- .../core/tools/linker/analyzer/Analysis.scala | 19 +- .../core/tools/linker/analyzer/Analyzer.scala | 19 +- .../linker/analyzer/SymbolRequirement.scala | 19 +- .../linker/backend/BasicLinkerBackend.scala | 19 +- .../tools/linker/backend/LinkerBackend.scala | 19 +- .../tools/linker/backend/ModuleKind.scala | 19 +- .../tools/linker/backend/OutputMode.scala | 19 +- .../linker/backend/emitter/ClassEmitter.scala | 19 +- .../linker/backend/emitter/CoreJSLibs.scala | 19 +- .../linker/backend/emitter/Emitter.scala | 19 +- .../backend/emitter/FunctionEmitter.scala | 19 +- .../backend/emitter/GlobalKnowledge.scala | 19 +- .../backend/emitter/InternalOptions.scala | 19 +- .../tools/linker/backend/emitter/JSGen.scala | 19 +- .../backend/emitter/KnowledgeGuardian.scala | 19 +- .../linker/backend/emitter/LongImpl.scala | 19 +- .../linker/backend/emitter/TreeDSL.scala | 19 +- .../core/tools/linker/checker/IRChecker.scala | 19 +- .../tools/linker/checker/InfoChecker.scala | 19 +- .../tools/linker/frontend/BaseLinker.scala | 19 +- .../linker/frontend/LinkerFrontend.scala | 19 +- .../core/tools/linker/frontend/Refiner.scala | 19 +- .../frontend/optimizer/GenIncOptimizer.scala | 19 +- .../frontend/optimizer/IncOptimizer.scala | 19 +- .../frontend/optimizer/OptimizerCore.scala | 19 +- .../scalajs/core/tools/linker/package.scala | 18 +- .../core/tools/linker/standard/package.scala | 18 +- .../scalajs/core/tools/logging/Level.scala | 19 +- .../scalajs/core/tools/logging/Logger.scala | 19 +- .../core/tools/logging/NullLogger.scala | 12 + .../tools/logging/ScalaConsoleLogger.scala | 12 + .../core/tools/sem/CheckedBehavior.scala | 19 +- .../scalajs/core/tools/sem/Semantics.scala | 19 +- .../jsdep/ComplianceRequirementTest.scala | 12 + .../tools/jsdep/ManifestFiltersTest.scala | 12 + .../core/tools/linker/LinkerTest.scala | 12 + 954 files changed, 11441 insertions(+), 3326 deletions(-) create mode 100644 junit-runtime/src/main/scala/org/hamcrest/LICENSE-hamcrest.txt diff --git a/Jenkinsfile b/Jenkinsfile index 185417b4a3..b5dfe4d623 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -163,6 +163,7 @@ def Tasks = [ sbtretry ++$scala testSuite/test:doc compiler/test reversi/fastOptJS reversi/fullOptJS && sbtretry ++$scala compiler/compile:doc library/compile:doc javalibEx/compile:doc \ testInterface/compile:doc && + sbtretry ++$scala headerCheck && sbtretry ++$scala partest/fetchScalaSource && sbtretry ++$scala library/mimaReportBinaryIssues testInterface/mimaReportBinaryIssues && sh ci/checksizes.sh $scala && diff --git a/LICENSE b/LICENSE index 79ec7acb89..9a57ed8100 100644 --- a/LICENSE +++ b/LICENSE @@ -1,27 +1,202 @@ -Copyright (c) 2013-2014 EPFL - -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the EPFL nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright (c) 2013-2018 EPFL + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/NOTICE b/NOTICE index 937d8d0dde..2edf2f73c7 100644 --- a/NOTICE +++ b/NOTICE @@ -1,6 +1,26 @@ +Scala.js +Copyright (c) 2013-2018 EPFL + +Scala.js includes software developed at EPFL (https://lamp.epfl.ch/ and +https://scala.epfl.ch/). + +Licensed under the Apache License, Version 2.0 (the "License"). +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + This project contains a translation of JUnit 4.12 to Scala.js in junit-runtime/src/main/scala/org/junit/. The original code can be found at https://github.com/junit-team/junit4/commit/64155f8a9babcfcf4263cf4d08253a1556e75481 As a translation, it constitutes a derivative work and is therefore licensed under the Eclipse Public License v1.0, whose full text can be found in junit-runtime/src/main/scala/org/junit/LICENSE-junit.txt + +This project contains a translation of Hamcrest 1.3 to Scala.js in +junit-runtime/src/main/scala/org/hamcrest/. The original code can be found at +https://github.com/hamcrest/JavaHamcrest/tree/hamcrest-java-1.3 +As a translation, it constitutes a derivative work and is therefore licensed +under the BSD License, whose full text can be found in +junit-runtime/src/main/scala/org/hamcrest/LICENSE-hamcrest.txt diff --git a/README.md b/README.md index e56fb732be..261cf301b7 100644 --- a/README.md +++ b/README.md @@ -8,4 +8,4 @@ This is the repository for ## License Scala.js is distributed under the -[Scala License](http://www.scala-lang.org/license.html). +[Apache License Version 2.0](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala b/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala index 85aedc1e90..8e049887ee 100644 --- a/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala +++ b/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js CLI ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.cli diff --git a/cli/src/main/scala/org/scalajs/cli/Scalajsp.scala b/cli/src/main/scala/org/scalajs/cli/Scalajsp.scala index 61710580bf..abeff4540d 100644 --- a/cli/src/main/scala/org/scalajs/cli/Scalajsp.scala +++ b/cli/src/main/scala/org/scalajs/cli/Scalajsp.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js CLI ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.cli diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala b/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala index a303f8e1aa..65d30dcd47 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala @@ -1,6 +1,13 @@ -/* Scala.js compiler - * Copyright 2013 LAMP/EPFL - * @author Sébastien Doeraene +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ package org.scalajs.core.compiler diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index e346bffbec..ee760f45e1 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -1,6 +1,13 @@ -/* Scala.js compiler - * Copyright 2013 LAMP/EPFL - * @author Sébastien Doeraene +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ package org.scalajs.core.compiler diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala index 9115cf4e95..85a124abf8 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala @@ -1,6 +1,13 @@ -/* Scala.js compiler - * Copyright 2013 LAMP/EPFL - * @author Sébastien Doeraene +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ package org.scalajs.core.compiler diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSFiles.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSFiles.scala index 8f1101d84e..ee0b6eca9e 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSFiles.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSFiles.scala @@ -1,6 +1,13 @@ -/* Scala.js compiler - * Copyright 2013 LAMP/EPFL - * @author Sébastien Doeraene +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ package org.scalajs.core.compiler diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala index eb736f2fd5..23fe3fd837 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala @@ -1,6 +1,13 @@ -/* Scala.js compiler - * Copyright 2013 LAMP/EPFL - * @author Sébastien Doeraene +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ package org.scalajs.core.compiler diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala index 66e99560dc..34211d487c 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSEncoding.scala @@ -1,6 +1,13 @@ -/* Scala.js compiler - * Copyright 2013 LAMP/EPFL - * @author Sébastien Doeraene +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ package org.scalajs.core.compiler diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala index 4f461d5026..c07597f396 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala @@ -1,6 +1,13 @@ -/* Scala.js compiler - * Copyright 2013 LAMP/EPFL - * @author Sébastien Doeraene +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ package org.scalajs.core.compiler diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala index 7e033df05c..9ecf48a22a 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSPrimitives.scala @@ -1,6 +1,13 @@ -/* Scala.js compiler - * Copyright 2013 LAMP/EPFL - * @author Sébastien Doeraene +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ package org.scalajs.core.compiler diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/JSTreeExtractors.scala b/compiler/src/main/scala/org/scalajs/core/compiler/JSTreeExtractors.scala index 9a574da858..d0fbfff897 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/JSTreeExtractors.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/JSTreeExtractors.scala @@ -1,6 +1,13 @@ -/* Scala.js compiler - * Copyright 2013 LAMP/EPFL - * @author Tobias Schlatter +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ package org.scalajs.core.compiler diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PreTyperComponent.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PreTyperComponent.scala index 126e7e09fd..a42762e57c 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PreTyperComponent.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PreTyperComponent.scala @@ -1,6 +1,13 @@ -/* Scala.js compiler - * Copyright 2013 LAMP/EPFL - * @author Nicolas Stucki +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ package org.scalajs.core.compiler diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala index 993678bf48..22ea67bbe7 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala @@ -1,6 +1,13 @@ -/* Scala.js compiler - * Copyright 2013 LAMP/EPFL - * @author Tobias Schlatter +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ package org.scalajs.core.compiler diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 102a7048d5..211ff8663d 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -1,6 +1,13 @@ -/* Scala.js compiler - * Copyright 2013 LAMP/EPFL - * @author Tobias Schlatter +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ package org.scalajs.core.compiler diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala index b80afd935f..3412c4566d 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSOptions.scala @@ -1,6 +1,13 @@ -/* Scala.js compiler - * Copyright 2013 LAMP/EPFL - * @author Tobias Schlatter +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ package org.scalajs.core.compiler diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala index 2d4fde50d5..174015afdc 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/ScalaJSPlugin.scala @@ -1,6 +1,13 @@ -/* Scala.js compiler - * Copyright 2013 LAMP/EPFL - * @author Sébastien Doeraene +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ package org.scalajs.core.compiler diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/TypeKinds.scala b/compiler/src/main/scala/org/scalajs/core/compiler/TypeKinds.scala index 0766a92281..3f832537e5 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/TypeKinds.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/TypeKinds.scala @@ -1,6 +1,13 @@ -/* Scala.js compiler - * Copyright 2013 LAMP/EPFL - * @author Sébastien Doeraene +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ package org.scalajs.core.compiler diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/util/ScopedVar.scala b/compiler/src/main/scala/org/scalajs/core/compiler/util/ScopedVar.scala index 225529217d..7778b8c351 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/util/ScopedVar.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/util/ScopedVar.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.compiler.util import language.implicitConversions diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/util/VarBox.scala b/compiler/src/main/scala/org/scalajs/core/compiler/util/VarBox.scala index 1f0274e9b1..ccbcfb322d 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/util/VarBox.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/util/VarBox.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.compiler.util import language.implicitConversions diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/DiverseErrorsTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/DiverseErrorsTest.scala index b71e6aedb6..40fc42fea1 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/DiverseErrorsTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/DiverseErrorsTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.compiler.test import org.scalajs.core.compiler.test.util._ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/EnumerationInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/EnumerationInteropTest.scala index 5b017aa9d7..6cb30de593 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/EnumerationInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/EnumerationInteropTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.compiler.test import org.scalajs.core.compiler.test.util._ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/InternalAnnotationsTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/InternalAnnotationsTest.scala index 5e2c061ed7..22cff79e5d 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/InternalAnnotationsTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/InternalAnnotationsTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.compiler.test import org.scalajs.core.compiler.test.util._ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSDynamicLiteralTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSDynamicLiteralTest.scala index bf93352cf5..f1032d5635 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSDynamicLiteralTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSDynamicLiteralTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.compiler.test import org.scalajs.core.compiler.test.util._ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportASTTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportASTTest.scala index 102eaa03a4..5b356970e2 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportASTTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportASTTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.compiler.test import util._ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportDeprecationsTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportDeprecationsTest.scala index 5489d88b47..c6be978961 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportDeprecationsTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportDeprecationsTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.compiler.test import org.scalajs.core.compiler.test.util._ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index f0d58f6692..42a951ff8a 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.compiler.test import org.scalajs.core.compiler.test.util._ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala index 8a811e9894..cb80c346a8 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSInteropTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.compiler.test import org.scalajs.core.compiler.test.util._ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSNativeByDefaultTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSNativeByDefaultTest.scala index 404e38d09b..e2379ffb66 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSNativeByDefaultTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSNativeByDefaultTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.compiler.test import org.scalajs.core.compiler.test.util._ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala index 10cf75a938..fd784eb9bc 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSOptionalTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.compiler.test import org.scalajs.core.compiler.test.util._ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSSAMTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSSAMTest.scala index 6d805ecac1..7144dac0da 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSSAMTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSSAMTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.compiler.test import org.scalajs.core.compiler.test.util._ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSUndefinedParamTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSUndefinedParamTest.scala index b3c4a20e68..5f7e02587b 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSUndefinedParamTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSUndefinedParamTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.compiler.test import org.scalajs.core.compiler.test.util._ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/MatchASTTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/MatchASTTest.scala index c6676d5d2d..cec2e6d6e8 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/MatchASTTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/MatchASTTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.compiler.test import util._ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/MissingJSGlobalDeprecationsSuppressedTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/MissingJSGlobalDeprecationsSuppressedTest.scala index 1835be4059..984760c375 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/MissingJSGlobalDeprecationsSuppressedTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/MissingJSGlobalDeprecationsSuppressedTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.compiler.test import org.scalajs.core.compiler.test.util._ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/MissingJSGlobalDeprecationsTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/MissingJSGlobalDeprecationsTest.scala index c42f4d6401..ab43c8b8c5 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/MissingJSGlobalDeprecationsTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/MissingJSGlobalDeprecationsTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.compiler.test import org.scalajs.core.compiler.test.util._ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala index 1937adcadc..9f0e554ad2 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.compiler.test import util._ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/PositionTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/PositionTest.scala index b5d02af3ef..de73b811ea 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/PositionTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/PositionTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.compiler.test import util.JSASTTest diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/ReflectTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/ReflectTest.scala index 93859def11..799bf5bc8d 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/ReflectTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/ReflectTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.compiler.test import org.scalajs.core.compiler.test.util._ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/RegressionTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/RegressionTest.scala index 842c14f5d2..8e3c88418b 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/RegressionTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/RegressionTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.compiler.test import org.scalajs.core.compiler.test.util._ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala index c86443fb90..151e0b88c3 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/ScalaJSDefinedTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.compiler.test import org.scalajs.core.compiler.test.util._ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala index f899cd024b..737de155d9 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/util/DirectTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.compiler.test.util import scala.tools.nsc._ diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/JSASTTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/util/JSASTTest.scala index f324f2bc2a..422bb58ca9 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/JSASTTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/util/JSASTTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.compiler.test.util import language.implicitConversions diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/TestHelpers.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/util/TestHelpers.scala index 644ab93abc..cf99c9303f 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/util/TestHelpers.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/util/TestHelpers.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.compiler.test.util import java.io._ diff --git a/ir/src/main/scala/org/scalajs/core/ir/ClassKind.scala b/ir/src/main/scala/org/scalajs/core/ir/ClassKind.scala index 2e895212a0..514837ecec 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ClassKind.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ClassKind.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js IR ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.ir diff --git a/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala b/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala index 617bb7b5fc..88c2535c91 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Definitions.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js IR ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.ir diff --git a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala index bf19a39a2b..3c57452544 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Hashers.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.ir import java.security.{MessageDigest, DigestOutputStream} diff --git a/ir/src/main/scala/org/scalajs/core/ir/IRVersionNotSupportedException.scala b/ir/src/main/scala/org/scalajs/core/ir/IRVersionNotSupportedException.scala index 5f44836906..8e62a707f7 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/IRVersionNotSupportedException.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/IRVersionNotSupportedException.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.ir import java.io.IOException diff --git a/ir/src/main/scala/org/scalajs/core/ir/InfoSerializers.scala b/ir/src/main/scala/org/scalajs/core/ir/InfoSerializers.scala index 9d1d7a752d..702675f628 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/InfoSerializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/InfoSerializers.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js IR ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.ir diff --git a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala index 2b8689b961..fcb517c608 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Infos.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Infos.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js IR ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.ir diff --git a/ir/src/main/scala/org/scalajs/core/ir/InvalidIRException.scala b/ir/src/main/scala/org/scalajs/core/ir/InvalidIRException.scala index 9805565300..4c210f4cc5 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/InvalidIRException.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/InvalidIRException.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.ir class InvalidIRException(val tree: Trees.Tree, message: String) diff --git a/ir/src/main/scala/org/scalajs/core/ir/Position.scala b/ir/src/main/scala/org/scalajs/core/ir/Position.scala index 4275b93cda..78dcb5b831 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Position.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Position.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js IR ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.ir diff --git a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala index f62c7ff042..10cb9deebc 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Printers.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js IR ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.ir diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index 921ec7c42d..58797ce453 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.ir object ScalaJSVersions { diff --git a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala index b78b4730a6..bb48157991 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Serializers.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js IR ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.ir diff --git a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala index 68096c6aa2..06ddf414d9 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Tags.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Tags.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js IR ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.ir diff --git a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala index 50141aae07..8dc9f5ab30 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Transformers.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js IR ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.ir diff --git a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala index dfa648ffc7..2918efc3a5 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Traversers.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js IR ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.ir diff --git a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala index 35984cfa8d..f66ea4f89b 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Trees.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js IR ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.ir diff --git a/ir/src/main/scala/org/scalajs/core/ir/Types.scala b/ir/src/main/scala/org/scalajs/core/ir/Types.scala index 8411b69be9..1b9024eeb3 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Types.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Types.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js IR ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.ir diff --git a/ir/src/main/scala/org/scalajs/core/ir/Utils.scala b/ir/src/main/scala/org/scalajs/core/ir/Utils.scala index d6083139cd..4779b9814f 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/Utils.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/Utils.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js IR ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.ir diff --git a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala index 8834c35eac..42756ca9c0 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/PrintersTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.ir import scala.language.implicitConversions diff --git a/ir/src/test/scala/org/scalajs/core/ir/UtilsTest.scala b/ir/src/test/scala/org/scalajs/core/ir/UtilsTest.scala index 2f0bf59888..8ac1377ce4 100644 --- a/ir/src/test/scala/org/scalajs/core/ir/UtilsTest.scala +++ b/ir/src/test/scala/org/scalajs/core/ir/UtilsTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.ir import java.net.URI diff --git a/javalanglib/src/main/scala/java/lang/Appendable.scala b/javalanglib/src/main/scala/java/lang/Appendable.scala index 9cd74ad88c..868dca962a 100644 --- a/javalanglib/src/main/scala/java/lang/Appendable.scala +++ b/javalanglib/src/main/scala/java/lang/Appendable.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang trait Appendable { diff --git a/javalanglib/src/main/scala/java/lang/Boolean.scala b/javalanglib/src/main/scala/java/lang/Boolean.scala index 2b4537712f..680752bf93 100644 --- a/javalanglib/src/main/scala/java/lang/Boolean.scala +++ b/javalanglib/src/main/scala/java/lang/Boolean.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang import scala.scalajs.js diff --git a/javalanglib/src/main/scala/java/lang/Byte.scala b/javalanglib/src/main/scala/java/lang/Byte.scala index ad902cd479..f1be4954e8 100644 --- a/javalanglib/src/main/scala/java/lang/Byte.scala +++ b/javalanglib/src/main/scala/java/lang/Byte.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang import scala.scalajs.js diff --git a/javalanglib/src/main/scala/java/lang/CharSequence.scala b/javalanglib/src/main/scala/java/lang/CharSequence.scala index 5875a2d973..051e445c2c 100644 --- a/javalanglib/src/main/scala/java/lang/CharSequence.scala +++ b/javalanglib/src/main/scala/java/lang/CharSequence.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang trait CharSequence { diff --git a/javalanglib/src/main/scala/java/lang/Character.scala b/javalanglib/src/main/scala/java/lang/Character.scala index 73ef37d765..7ae4e551d1 100644 --- a/javalanglib/src/main/scala/java/lang/Character.scala +++ b/javalanglib/src/main/scala/java/lang/Character.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang import scala.scalajs.js diff --git a/javalanglib/src/main/scala/java/lang/Class.scala b/javalanglib/src/main/scala/java/lang/Class.scala index b59c290d56..9770dca563 100644 --- a/javalanglib/src/main/scala/java/lang/Class.scala +++ b/javalanglib/src/main/scala/java/lang/Class.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang import scala.scalajs.js diff --git a/javalanglib/src/main/scala/java/lang/ClassLoader.scala b/javalanglib/src/main/scala/java/lang/ClassLoader.scala index 80da97097f..15e76d485e 100644 --- a/javalanglib/src/main/scala/java/lang/ClassLoader.scala +++ b/javalanglib/src/main/scala/java/lang/ClassLoader.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang import scala.scalajs.js diff --git a/javalanglib/src/main/scala/java/lang/Cloneable.scala b/javalanglib/src/main/scala/java/lang/Cloneable.scala index 4183bf5311..29495611bd 100644 --- a/javalanglib/src/main/scala/java/lang/Cloneable.scala +++ b/javalanglib/src/main/scala/java/lang/Cloneable.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang trait Cloneable diff --git a/javalanglib/src/main/scala/java/lang/Comparable.scala b/javalanglib/src/main/scala/java/lang/Comparable.scala index 8d17c6f03f..894897e9c4 100644 --- a/javalanglib/src/main/scala/java/lang/Comparable.scala +++ b/javalanglib/src/main/scala/java/lang/Comparable.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang trait Comparable[A] { diff --git a/javalanglib/src/main/scala/java/lang/Double.scala b/javalanglib/src/main/scala/java/lang/Double.scala index 0a2c4fac5c..79ac693dac 100644 --- a/javalanglib/src/main/scala/java/lang/Double.scala +++ b/javalanglib/src/main/scala/java/lang/Double.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang import scala.scalajs.js diff --git a/javalanglib/src/main/scala/java/lang/Enum.scala b/javalanglib/src/main/scala/java/lang/Enum.scala index 064f294a04..d10947e5b0 100644 --- a/javalanglib/src/main/scala/java/lang/Enum.scala +++ b/javalanglib/src/main/scala/java/lang/Enum.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang abstract class Enum[E <: Enum[E]] protected (_name: String, _ordinal: Int) diff --git a/javalanglib/src/main/scala/java/lang/Float.scala b/javalanglib/src/main/scala/java/lang/Float.scala index 791ed35089..a64620e091 100644 --- a/javalanglib/src/main/scala/java/lang/Float.scala +++ b/javalanglib/src/main/scala/java/lang/Float.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang /* This is a hijacked class. Its instances are primitive numbers. diff --git a/javalanglib/src/main/scala/java/lang/InheritableThreadLocal.scala b/javalanglib/src/main/scala/java/lang/InheritableThreadLocal.scala index 92ef07c8a0..83c81e7581 100644 --- a/javalanglib/src/main/scala/java/lang/InheritableThreadLocal.scala +++ b/javalanglib/src/main/scala/java/lang/InheritableThreadLocal.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang class InheritableThreadLocal[T] extends ThreadLocal[T] { diff --git a/javalanglib/src/main/scala/java/lang/Integer.scala b/javalanglib/src/main/scala/java/lang/Integer.scala index f23b382b0b..b2f538b4c7 100644 --- a/javalanglib/src/main/scala/java/lang/Integer.scala +++ b/javalanglib/src/main/scala/java/lang/Integer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang import scala.scalajs.js diff --git a/javalanglib/src/main/scala/java/lang/Iterable.scala b/javalanglib/src/main/scala/java/lang/Iterable.scala index 79c43ca22c..b37d854c6e 100644 --- a/javalanglib/src/main/scala/java/lang/Iterable.scala +++ b/javalanglib/src/main/scala/java/lang/Iterable.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang import java.util.Iterator diff --git a/javalanglib/src/main/scala/java/lang/Long.scala b/javalanglib/src/main/scala/java/lang/Long.scala index b602ca7dbe..66804953e4 100644 --- a/javalanglib/src/main/scala/java/lang/Long.scala +++ b/javalanglib/src/main/scala/java/lang/Long.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang import scala.annotation.{switch, tailrec} diff --git a/javalanglib/src/main/scala/java/lang/Math.scala b/javalanglib/src/main/scala/java/lang/Math.scala index fef949112c..3f42a01ab1 100644 --- a/javalanglib/src/main/scala/java/lang/Math.scala +++ b/javalanglib/src/main/scala/java/lang/Math.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java package lang diff --git a/javalanglib/src/main/scala/java/lang/MathJDK8Bridge.scala b/javalanglib/src/main/scala/java/lang/MathJDK8Bridge.scala index 51f16451e6..1a3d5ae379 100644 --- a/javalanglib/src/main/scala/java/lang/MathJDK8Bridge.scala +++ b/javalanglib/src/main/scala/java/lang/MathJDK8Bridge.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + /* !!!!! * THIS FILE IS ALMOST COPY-PASTED IN javalanglib/ AND javalib/. * THEY MUST BE KEPT IN SYNC. diff --git a/javalanglib/src/main/scala/java/lang/Number.scala b/javalanglib/src/main/scala/java/lang/Number.scala index 67159527eb..757c04673d 100644 --- a/javalanglib/src/main/scala/java/lang/Number.scala +++ b/javalanglib/src/main/scala/java/lang/Number.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang import scala.scalajs.js diff --git a/javalanglib/src/main/scala/java/lang/Readable.scala b/javalanglib/src/main/scala/java/lang/Readable.scala index 53e5689285..18be0ac38b 100644 --- a/javalanglib/src/main/scala/java/lang/Readable.scala +++ b/javalanglib/src/main/scala/java/lang/Readable.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang import java.nio.CharBuffer diff --git a/javalanglib/src/main/scala/java/lang/Runnable.scala b/javalanglib/src/main/scala/java/lang/Runnable.scala index c98cb41652..5874c44936 100644 --- a/javalanglib/src/main/scala/java/lang/Runnable.scala +++ b/javalanglib/src/main/scala/java/lang/Runnable.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang trait Runnable { diff --git a/javalanglib/src/main/scala/java/lang/Runtime.scala b/javalanglib/src/main/scala/java/lang/Runtime.scala index 70fd4cb3eb..8e1acd40a6 100644 --- a/javalanglib/src/main/scala/java/lang/Runtime.scala +++ b/javalanglib/src/main/scala/java/lang/Runtime.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang import scala.scalajs.js diff --git a/javalanglib/src/main/scala/java/lang/Short.scala b/javalanglib/src/main/scala/java/lang/Short.scala index f7a6e98362..54c312f0ba 100644 --- a/javalanglib/src/main/scala/java/lang/Short.scala +++ b/javalanglib/src/main/scala/java/lang/Short.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang /* This is a hijacked class. Its instances are primitive numbers. diff --git a/javalanglib/src/main/scala/java/lang/StackTraceElement.scala b/javalanglib/src/main/scala/java/lang/StackTraceElement.scala index 92aaba4c36..53e46695b0 100644 --- a/javalanglib/src/main/scala/java/lang/StackTraceElement.scala +++ b/javalanglib/src/main/scala/java/lang/StackTraceElement.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang import scala.scalajs.js diff --git a/javalanglib/src/main/scala/java/lang/StringBuffer.scala b/javalanglib/src/main/scala/java/lang/StringBuffer.scala index 023b8775f5..985ee720d8 100644 --- a/javalanglib/src/main/scala/java/lang/StringBuffer.scala +++ b/javalanglib/src/main/scala/java/lang/StringBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang /* Given the rare usefulness of StringBuffer in the context of Scala.js, and diff --git a/javalanglib/src/main/scala/java/lang/StringBuilder.scala b/javalanglib/src/main/scala/java/lang/StringBuilder.scala index 58d5cac810..9623dac31d 100644 --- a/javalanglib/src/main/scala/java/lang/StringBuilder.scala +++ b/javalanglib/src/main/scala/java/lang/StringBuilder.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang class StringBuilder diff --git a/javalanglib/src/main/scala/java/lang/System.scala b/javalanglib/src/main/scala/java/lang/System.scala index de07c62c68..24697f49ba 100644 --- a/javalanglib/src/main/scala/java/lang/System.scala +++ b/javalanglib/src/main/scala/java/lang/System.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang import java.io._ diff --git a/javalanglib/src/main/scala/java/lang/Thread.scala b/javalanglib/src/main/scala/java/lang/Thread.scala index 6a131deaaf..750bbe8190 100644 --- a/javalanglib/src/main/scala/java/lang/Thread.scala +++ b/javalanglib/src/main/scala/java/lang/Thread.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang /* We need a constructor to create SingleThread in the companion object, but diff --git a/javalanglib/src/main/scala/java/lang/ThreadLocal.scala b/javalanglib/src/main/scala/java/lang/ThreadLocal.scala index a36a40c7ed..0582006a66 100644 --- a/javalanglib/src/main/scala/java/lang/ThreadLocal.scala +++ b/javalanglib/src/main/scala/java/lang/ThreadLocal.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang class ThreadLocal[T] { diff --git a/javalanglib/src/main/scala/java/lang/Throwables.scala b/javalanglib/src/main/scala/java/lang/Throwables.scala index b5d737c7e9..70ac104c30 100644 --- a/javalanglib/src/main/scala/java/lang/Throwables.scala +++ b/javalanglib/src/main/scala/java/lang/Throwables.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang import scala.scalajs.js diff --git a/javalanglib/src/main/scala/java/lang/Void.scala b/javalanglib/src/main/scala/java/lang/Void.scala index dc58e3bd2f..6caa81accb 100644 --- a/javalanglib/src/main/scala/java/lang/Void.scala +++ b/javalanglib/src/main/scala/java/lang/Void.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang final class Void private () diff --git a/javalanglib/src/main/scala/java/lang/annotation/Annotation.scala b/javalanglib/src/main/scala/java/lang/annotation/Annotation.scala index f02bf85144..a8847fa692 100644 --- a/javalanglib/src/main/scala/java/lang/annotation/Annotation.scala +++ b/javalanglib/src/main/scala/java/lang/annotation/Annotation.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang.annotation trait Annotation { diff --git a/javalanglib/src/main/scala/java/lang/ref/PhantomReference.scala b/javalanglib/src/main/scala/java/lang/ref/PhantomReference.scala index ecace8accc..926f377989 100644 --- a/javalanglib/src/main/scala/java/lang/ref/PhantomReference.scala +++ b/javalanglib/src/main/scala/java/lang/ref/PhantomReference.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang.ref class PhantomReference[T >: Null <: AnyRef](referent: T, diff --git a/javalanglib/src/main/scala/java/lang/ref/Reference.scala b/javalanglib/src/main/scala/java/lang/ref/Reference.scala index 76909cf4cd..85548801b4 100644 --- a/javalanglib/src/main/scala/java/lang/ref/Reference.scala +++ b/javalanglib/src/main/scala/java/lang/ref/Reference.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang.ref abstract class Reference[T >: Null <: AnyRef](private[this] var referent: T) { diff --git a/javalanglib/src/main/scala/java/lang/ref/ReferenceQueue.scala b/javalanglib/src/main/scala/java/lang/ref/ReferenceQueue.scala index e9c5110b8e..03a653be65 100644 --- a/javalanglib/src/main/scala/java/lang/ref/ReferenceQueue.scala +++ b/javalanglib/src/main/scala/java/lang/ref/ReferenceQueue.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang.ref class ReferenceQueue[T >: Null <: AnyRef] diff --git a/javalanglib/src/main/scala/java/lang/ref/SoftReference.scala b/javalanglib/src/main/scala/java/lang/ref/SoftReference.scala index eb0fdf75e5..565ed8477b 100644 --- a/javalanglib/src/main/scala/java/lang/ref/SoftReference.scala +++ b/javalanglib/src/main/scala/java/lang/ref/SoftReference.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang.ref class SoftReference[T >: Null <: AnyRef](referent: T, diff --git a/javalanglib/src/main/scala/java/lang/ref/WeakReference.scala b/javalanglib/src/main/scala/java/lang/ref/WeakReference.scala index 2a74aa1263..e6865f0473 100644 --- a/javalanglib/src/main/scala/java/lang/ref/WeakReference.scala +++ b/javalanglib/src/main/scala/java/lang/ref/WeakReference.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang.ref class WeakReference[T >: Null <: AnyRef](referent: T, diff --git a/javalanglib/src/main/scala/java/lang/reflect/Array.scala b/javalanglib/src/main/scala/java/lang/reflect/Array.scala index bc3696ebd7..e394e4f912 100644 --- a/javalanglib/src/main/scala/java/lang/reflect/Array.scala +++ b/javalanglib/src/main/scala/java/lang/reflect/Array.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang.reflect import scala.scalajs.js diff --git a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/javalib/lang/ObjectTestEx.scala b/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/javalib/lang/ObjectTestEx.scala index fcdadd3b27..fd4660f176 100644 --- a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/javalib/lang/ObjectTestEx.scala +++ b/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/javalib/lang/ObjectTestEx.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import org.junit.Test diff --git a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/javalibex/ZipInputStreamTest.scala b/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/javalibex/ZipInputStreamTest.scala index 39a89f2dd5..a1c08401df 100644 --- a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/javalibex/ZipInputStreamTest.scala +++ b/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/javalibex/ZipInputStreamTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.testsuite.javalibex import org.junit.Test diff --git a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ScalaJSDefinedTestEx.scala b/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ScalaJSDefinedTestEx.scala index ada3db13b6..e55aec8c65 100644 --- a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ScalaJSDefinedTestEx.scala +++ b/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ScalaJSDefinedTestEx.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.testsuite.jsinterop import org.junit.Test diff --git a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/utils/AssertThrows.scala b/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/utils/AssertThrows.scala index b9f8540c32..22b7c5015a 100644 --- a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/utils/AssertThrows.scala +++ b/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/utils/AssertThrows.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.testsuite.utils /** This is a copy of the implementation in the testSuite */ diff --git a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/utils/Platform.scala b/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/utils/Platform.scala index 10e0041518..be8a1808e3 100644 --- a/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/utils/Platform.scala +++ b/javalib-ex-test-suite/src/test/scala/scala/scalajs/testsuite/utils/Platform.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.testsuite.utils /** This is a partial copy of the implementation in the testSuite */ diff --git a/javalib-ex/src/main/scala/java/util/zip/InflaterInputStream.scala b/javalib-ex/src/main/scala/java/util/zip/InflaterInputStream.scala index d820655137..a9fbd90517 100644 --- a/javalib-ex/src/main/scala/java/util/zip/InflaterInputStream.scala +++ b/javalib-ex/src/main/scala/java/util/zip/InflaterInputStream.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util.zip import java.io._ diff --git a/javalib-ex/src/main/scala/java/util/zip/ZipEntry.scala b/javalib-ex/src/main/scala/java/util/zip/ZipEntry.scala index b9a380adea..c70bd051da 100644 --- a/javalib-ex/src/main/scala/java/util/zip/ZipEntry.scala +++ b/javalib-ex/src/main/scala/java/util/zip/ZipEntry.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util.zip // scalastyle:off equals.hash.code diff --git a/javalib-ex/src/main/scala/java/util/zip/ZipInputStream.scala b/javalib-ex/src/main/scala/java/util/zip/ZipInputStream.scala index d543d79f19..3e03482dc1 100644 --- a/javalib-ex/src/main/scala/java/util/zip/ZipInputStream.scala +++ b/javalib-ex/src/main/scala/java/util/zip/ZipInputStream.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util.zip import java.io._ diff --git a/javalib/src/main/scala/java/io/BufferedReader.scala b/javalib/src/main/scala/java/io/BufferedReader.scala index 62b51a44c5..a880e7611d 100644 --- a/javalib/src/main/scala/java/io/BufferedReader.scala +++ b/javalib/src/main/scala/java/io/BufferedReader.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.io class BufferedReader(in: Reader, sz: Int) extends Reader { diff --git a/javalib/src/main/scala/java/io/ByteArrayInputStream.scala b/javalib/src/main/scala/java/io/ByteArrayInputStream.scala index 697e07b224..11a85ea27c 100644 --- a/javalib/src/main/scala/java/io/ByteArrayInputStream.scala +++ b/javalib/src/main/scala/java/io/ByteArrayInputStream.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.io class ByteArrayInputStream( diff --git a/javalib/src/main/scala/java/io/ByteArrayOutputStream.scala b/javalib/src/main/scala/java/io/ByteArrayOutputStream.scala index 916002d33b..c990ddc190 100644 --- a/javalib/src/main/scala/java/io/ByteArrayOutputStream.scala +++ b/javalib/src/main/scala/java/io/ByteArrayOutputStream.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.io import scala.scalajs.js diff --git a/javalib/src/main/scala/java/io/Closeable.scala b/javalib/src/main/scala/java/io/Closeable.scala index b1aab01e9a..c5f43f92c4 100644 --- a/javalib/src/main/scala/java/io/Closeable.scala +++ b/javalib/src/main/scala/java/io/Closeable.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.io trait Closeable extends AutoCloseable { diff --git a/javalib/src/main/scala/java/io/DataInput.scala b/javalib/src/main/scala/java/io/DataInput.scala index 37913b4dec..704bc582bc 100644 --- a/javalib/src/main/scala/java/io/DataInput.scala +++ b/javalib/src/main/scala/java/io/DataInput.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.io trait DataInput { diff --git a/javalib/src/main/scala/java/io/DataInputStream.scala b/javalib/src/main/scala/java/io/DataInputStream.scala index 6165d8e359..3296a8ef20 100644 --- a/javalib/src/main/scala/java/io/DataInputStream.scala +++ b/javalib/src/main/scala/java/io/DataInputStream.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.io import scala.scalajs.js.typedarray._ diff --git a/javalib/src/main/scala/java/io/DataOutput.scala b/javalib/src/main/scala/java/io/DataOutput.scala index 3794f0eb23..0f46cb335e 100644 --- a/javalib/src/main/scala/java/io/DataOutput.scala +++ b/javalib/src/main/scala/java/io/DataOutput.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.io trait DataOutput { diff --git a/javalib/src/main/scala/java/io/DataOutputStream.scala b/javalib/src/main/scala/java/io/DataOutputStream.scala index b6acc5b561..7490ce53ab 100644 --- a/javalib/src/main/scala/java/io/DataOutputStream.scala +++ b/javalib/src/main/scala/java/io/DataOutputStream.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.io class DataOutputStream(out: OutputStream) diff --git a/javalib/src/main/scala/java/io/FilterInputStream.scala b/javalib/src/main/scala/java/io/FilterInputStream.scala index a85b9f601a..b957b36388 100644 --- a/javalib/src/main/scala/java/io/FilterInputStream.scala +++ b/javalib/src/main/scala/java/io/FilterInputStream.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.io class FilterInputStream protected ( diff --git a/javalib/src/main/scala/java/io/FilterOutputStream.scala b/javalib/src/main/scala/java/io/FilterOutputStream.scala index 299b7b6353..078a881e26 100644 --- a/javalib/src/main/scala/java/io/FilterOutputStream.scala +++ b/javalib/src/main/scala/java/io/FilterOutputStream.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.io class FilterOutputStream(protected val out: OutputStream) extends OutputStream { diff --git a/javalib/src/main/scala/java/io/Flushable.scala b/javalib/src/main/scala/java/io/Flushable.scala index 2879ad24c2..7c5e54452b 100644 --- a/javalib/src/main/scala/java/io/Flushable.scala +++ b/javalib/src/main/scala/java/io/Flushable.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.io trait Flushable { diff --git a/javalib/src/main/scala/java/io/InputStream.scala b/javalib/src/main/scala/java/io/InputStream.scala index 412d84b7b2..4259dc95a8 100644 --- a/javalib/src/main/scala/java/io/InputStream.scala +++ b/javalib/src/main/scala/java/io/InputStream.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.io abstract class InputStream extends Closeable { diff --git a/javalib/src/main/scala/java/io/InputStreamReader.scala b/javalib/src/main/scala/java/io/InputStreamReader.scala index 86710021f5..65f1f0b821 100644 --- a/javalib/src/main/scala/java/io/InputStreamReader.scala +++ b/javalib/src/main/scala/java/io/InputStreamReader.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.io import scala.annotation.tailrec diff --git a/javalib/src/main/scala/java/io/OutputStream.scala b/javalib/src/main/scala/java/io/OutputStream.scala index 729e69bd06..af6c6b370c 100644 --- a/javalib/src/main/scala/java/io/OutputStream.scala +++ b/javalib/src/main/scala/java/io/OutputStream.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.io abstract class OutputStream extends Object with Closeable with Flushable { diff --git a/javalib/src/main/scala/java/io/OutputStreamWriter.scala b/javalib/src/main/scala/java/io/OutputStreamWriter.scala index 0ca43531d8..9762f05d44 100644 --- a/javalib/src/main/scala/java/io/OutputStreamWriter.scala +++ b/javalib/src/main/scala/java/io/OutputStreamWriter.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.io import scala.annotation.tailrec diff --git a/javalib/src/main/scala/java/io/PrintStream.scala b/javalib/src/main/scala/java/io/PrintStream.scala index 68fa041e4d..fc5d2c64e0 100644 --- a/javalib/src/main/scala/java/io/PrintStream.scala +++ b/javalib/src/main/scala/java/io/PrintStream.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.io import java.nio.charset.Charset diff --git a/javalib/src/main/scala/java/io/PrintWriter.scala b/javalib/src/main/scala/java/io/PrintWriter.scala index 4e693e043b..5e3facf333 100644 --- a/javalib/src/main/scala/java/io/PrintWriter.scala +++ b/javalib/src/main/scala/java/io/PrintWriter.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.io import java.util.Formatter diff --git a/javalib/src/main/scala/java/io/Reader.scala b/javalib/src/main/scala/java/io/Reader.scala index cdef02b25e..df45a80c00 100644 --- a/javalib/src/main/scala/java/io/Reader.scala +++ b/javalib/src/main/scala/java/io/Reader.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.io import java.nio.CharBuffer diff --git a/javalib/src/main/scala/java/io/Serializable.scala b/javalib/src/main/scala/java/io/Serializable.scala index 01dd228d5b..2bdde595a7 100644 --- a/javalib/src/main/scala/java/io/Serializable.scala +++ b/javalib/src/main/scala/java/io/Serializable.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.io trait Serializable diff --git a/javalib/src/main/scala/java/io/StringReader.scala b/javalib/src/main/scala/java/io/StringReader.scala index 131bd5f6e6..6aa8755418 100644 --- a/javalib/src/main/scala/java/io/StringReader.scala +++ b/javalib/src/main/scala/java/io/StringReader.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.io class StringReader(s: String) extends Reader { diff --git a/javalib/src/main/scala/java/io/StringWriter.scala b/javalib/src/main/scala/java/io/StringWriter.scala index 13eca0053c..be9e5bd902 100644 --- a/javalib/src/main/scala/java/io/StringWriter.scala +++ b/javalib/src/main/scala/java/io/StringWriter.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.io class StringWriter extends Writer { diff --git a/javalib/src/main/scala/java/io/Throwables.scala b/javalib/src/main/scala/java/io/Throwables.scala index f6e08d9406..133afe4a74 100644 --- a/javalib/src/main/scala/java/io/Throwables.scala +++ b/javalib/src/main/scala/java/io/Throwables.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.io class IOException(s: String, e: Throwable) extends Exception(s, e) { diff --git a/javalib/src/main/scala/java/io/Writer.scala b/javalib/src/main/scala/java/io/Writer.scala index d63b477ccc..92f9de2305 100644 --- a/javalib/src/main/scala/java/io/Writer.scala +++ b/javalib/src/main/scala/java/io/Writer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.io abstract class Writer private[this] (_lock: Option[Object]) extends diff --git a/javalib/src/main/scala/java/lang/AutoCloseable.scala b/javalib/src/main/scala/java/lang/AutoCloseable.scala index 1a079c366e..c7b41d0d87 100644 --- a/javalib/src/main/scala/java/lang/AutoCloseable.scala +++ b/javalib/src/main/scala/java/lang/AutoCloseable.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.lang /* Even though this trait belongs to the java.lang package, we compile it as diff --git a/javalib/src/main/scala/java/lang/MathJDK8Bridge.scala b/javalib/src/main/scala/java/lang/MathJDK8Bridge.scala index d3f081fd93..9c364cf7a8 100644 --- a/javalib/src/main/scala/java/lang/MathJDK8Bridge.scala +++ b/javalib/src/main/scala/java/lang/MathJDK8Bridge.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + /* !!!!! * THIS FILE IS ALMOST COPY-PASTED IN javalanglib/ AND javalib/. * THEY MUST BE KEPT IN SYNC. diff --git a/javalib/src/main/scala/java/math/Multiplication.scala b/javalib/src/main/scala/java/math/Multiplication.scala index d4d2d09af7..5ff7ad01b6 100644 --- a/javalib/src/main/scala/java/math/Multiplication.scala +++ b/javalib/src/main/scala/java/math/Multiplication.scala @@ -1,6 +1,7 @@ /* * Ported by Alistair Johnson from * https://android.googlesource.com/platform/libcore/+/master/luni/src/main/java/java/math/Multiplication.java + * Original license copied below: */ /* diff --git a/javalib/src/main/scala/java/net/Throwables.scala b/javalib/src/main/scala/java/net/Throwables.scala index 0016e8c55d..41d34680f9 100644 --- a/javalib/src/main/scala/java/net/Throwables.scala +++ b/javalib/src/main/scala/java/net/Throwables.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.net import java.io.IOException diff --git a/javalib/src/main/scala/java/net/URI.scala b/javalib/src/main/scala/java/net/URI.scala index ba72411f22..4300203850 100644 --- a/javalib/src/main/scala/java/net/URI.scala +++ b/javalib/src/main/scala/java/net/URI.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.net import scala.scalajs.js.RegExp diff --git a/javalib/src/main/scala/java/net/URLDecoder.scala b/javalib/src/main/scala/java/net/URLDecoder.scala index fbaf1bea2b..64a07837e7 100644 --- a/javalib/src/main/scala/java/net/URLDecoder.scala +++ b/javalib/src/main/scala/java/net/URLDecoder.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.net import java.io.UnsupportedEncodingException diff --git a/javalib/src/main/scala/java/nio/Buffer.scala b/javalib/src/main/scala/java/nio/Buffer.scala index 6634324e34..8ce5babf28 100644 --- a/javalib/src/main/scala/java/nio/Buffer.scala +++ b/javalib/src/main/scala/java/nio/Buffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio import scala.scalajs.js.typedarray._ diff --git a/javalib/src/main/scala/java/nio/BufferOverflowException.scala b/javalib/src/main/scala/java/nio/BufferOverflowException.scala index 03f359ef09..c4bcbc9805 100644 --- a/javalib/src/main/scala/java/nio/BufferOverflowException.scala +++ b/javalib/src/main/scala/java/nio/BufferOverflowException.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio class BufferOverflowException extends RuntimeException diff --git a/javalib/src/main/scala/java/nio/BufferUnderflowException.scala b/javalib/src/main/scala/java/nio/BufferUnderflowException.scala index e28697543f..7b04dee532 100644 --- a/javalib/src/main/scala/java/nio/BufferUnderflowException.scala +++ b/javalib/src/main/scala/java/nio/BufferUnderflowException.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio class BufferUnderflowException extends RuntimeException diff --git a/javalib/src/main/scala/java/nio/ByteArrayBits.scala b/javalib/src/main/scala/java/nio/ByteArrayBits.scala index 5d243e24ef..1b4a326e6c 100644 --- a/javalib/src/main/scala/java/nio/ByteArrayBits.scala +++ b/javalib/src/main/scala/java/nio/ByteArrayBits.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio private[nio] object ByteArrayBits { diff --git a/javalib/src/main/scala/java/nio/ByteBuffer.scala b/javalib/src/main/scala/java/nio/ByteBuffer.scala index d2a65130ab..f95ff88487 100644 --- a/javalib/src/main/scala/java/nio/ByteBuffer.scala +++ b/javalib/src/main/scala/java/nio/ByteBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio import scala.scalajs.js.typedarray._ diff --git a/javalib/src/main/scala/java/nio/ByteOrder.scala b/javalib/src/main/scala/java/nio/ByteOrder.scala index 20bac6a506..b209b3ee5e 100644 --- a/javalib/src/main/scala/java/nio/ByteOrder.scala +++ b/javalib/src/main/scala/java/nio/ByteOrder.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio final class ByteOrder private (name: String) { diff --git a/javalib/src/main/scala/java/nio/CharBuffer.scala b/javalib/src/main/scala/java/nio/CharBuffer.scala index 3a8be3af24..df59cf67cc 100644 --- a/javalib/src/main/scala/java/nio/CharBuffer.scala +++ b/javalib/src/main/scala/java/nio/CharBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio import scala.scalajs.js.typedarray._ diff --git a/javalib/src/main/scala/java/nio/DataViewCharBuffer.scala b/javalib/src/main/scala/java/nio/DataViewCharBuffer.scala index 90641d2ed5..d94624f9d1 100644 --- a/javalib/src/main/scala/java/nio/DataViewCharBuffer.scala +++ b/javalib/src/main/scala/java/nio/DataViewCharBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio import scala.scalajs.js.typedarray._ diff --git a/javalib/src/main/scala/java/nio/DataViewDoubleBuffer.scala b/javalib/src/main/scala/java/nio/DataViewDoubleBuffer.scala index 34bd752504..86bc395395 100644 --- a/javalib/src/main/scala/java/nio/DataViewDoubleBuffer.scala +++ b/javalib/src/main/scala/java/nio/DataViewDoubleBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio import scala.scalajs.js.typedarray._ diff --git a/javalib/src/main/scala/java/nio/DataViewFloatBuffer.scala b/javalib/src/main/scala/java/nio/DataViewFloatBuffer.scala index a1fda77203..6c25ef5e46 100644 --- a/javalib/src/main/scala/java/nio/DataViewFloatBuffer.scala +++ b/javalib/src/main/scala/java/nio/DataViewFloatBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio import scala.scalajs.js.typedarray._ diff --git a/javalib/src/main/scala/java/nio/DataViewIntBuffer.scala b/javalib/src/main/scala/java/nio/DataViewIntBuffer.scala index 3cb836285f..cde35b5937 100644 --- a/javalib/src/main/scala/java/nio/DataViewIntBuffer.scala +++ b/javalib/src/main/scala/java/nio/DataViewIntBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio import scala.scalajs.js.typedarray._ diff --git a/javalib/src/main/scala/java/nio/DataViewLongBuffer.scala b/javalib/src/main/scala/java/nio/DataViewLongBuffer.scala index 858513c020..3ee08fee13 100644 --- a/javalib/src/main/scala/java/nio/DataViewLongBuffer.scala +++ b/javalib/src/main/scala/java/nio/DataViewLongBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio import scala.scalajs.js.typedarray._ diff --git a/javalib/src/main/scala/java/nio/DataViewShortBuffer.scala b/javalib/src/main/scala/java/nio/DataViewShortBuffer.scala index 4d4b7417e0..a60b31cb48 100644 --- a/javalib/src/main/scala/java/nio/DataViewShortBuffer.scala +++ b/javalib/src/main/scala/java/nio/DataViewShortBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio import scala.scalajs.js.typedarray._ diff --git a/javalib/src/main/scala/java/nio/DoubleBuffer.scala b/javalib/src/main/scala/java/nio/DoubleBuffer.scala index a36939d322..4049303011 100644 --- a/javalib/src/main/scala/java/nio/DoubleBuffer.scala +++ b/javalib/src/main/scala/java/nio/DoubleBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio import scala.scalajs.js.typedarray._ diff --git a/javalib/src/main/scala/java/nio/FloatBuffer.scala b/javalib/src/main/scala/java/nio/FloatBuffer.scala index 8f319b6f9c..bbfb143696 100644 --- a/javalib/src/main/scala/java/nio/FloatBuffer.scala +++ b/javalib/src/main/scala/java/nio/FloatBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio import scala.scalajs.js.typedarray._ diff --git a/javalib/src/main/scala/java/nio/GenBuffer.scala b/javalib/src/main/scala/java/nio/GenBuffer.scala index 6f7d87f3a0..86badb53e6 100644 --- a/javalib/src/main/scala/java/nio/GenBuffer.scala +++ b/javalib/src/main/scala/java/nio/GenBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio private[nio] object GenBuffer { diff --git a/javalib/src/main/scala/java/nio/GenDataViewBuffer.scala b/javalib/src/main/scala/java/nio/GenDataViewBuffer.scala index 172ea8fdc0..d73eade50e 100644 --- a/javalib/src/main/scala/java/nio/GenDataViewBuffer.scala +++ b/javalib/src/main/scala/java/nio/GenDataViewBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio import scala.scalajs.js.Dynamic.{literal => lit} diff --git a/javalib/src/main/scala/java/nio/GenHeapBuffer.scala b/javalib/src/main/scala/java/nio/GenHeapBuffer.scala index 0deeacb256..4556f735d6 100644 --- a/javalib/src/main/scala/java/nio/GenHeapBuffer.scala +++ b/javalib/src/main/scala/java/nio/GenHeapBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio private[nio] object GenHeapBuffer { diff --git a/javalib/src/main/scala/java/nio/GenHeapBufferView.scala b/javalib/src/main/scala/java/nio/GenHeapBufferView.scala index 8ef7206087..1222958f55 100644 --- a/javalib/src/main/scala/java/nio/GenHeapBufferView.scala +++ b/javalib/src/main/scala/java/nio/GenHeapBufferView.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio private[nio] object GenHeapBufferView { diff --git a/javalib/src/main/scala/java/nio/GenTypedArrayBuffer.scala b/javalib/src/main/scala/java/nio/GenTypedArrayBuffer.scala index 347fbccd5f..b357db30e7 100644 --- a/javalib/src/main/scala/java/nio/GenTypedArrayBuffer.scala +++ b/javalib/src/main/scala/java/nio/GenTypedArrayBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio import scala.scalajs.js.typedarray._ diff --git a/javalib/src/main/scala/java/nio/HeapByteBuffer.scala b/javalib/src/main/scala/java/nio/HeapByteBuffer.scala index 7ace7c70b9..1adcda56e9 100644 --- a/javalib/src/main/scala/java/nio/HeapByteBuffer.scala +++ b/javalib/src/main/scala/java/nio/HeapByteBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio private[nio] final class HeapByteBuffer private ( diff --git a/javalib/src/main/scala/java/nio/HeapByteBufferCharView.scala b/javalib/src/main/scala/java/nio/HeapByteBufferCharView.scala index 9b44994a6f..fb48c228bc 100644 --- a/javalib/src/main/scala/java/nio/HeapByteBufferCharView.scala +++ b/javalib/src/main/scala/java/nio/HeapByteBufferCharView.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio private[nio] final class HeapByteBufferCharView private ( diff --git a/javalib/src/main/scala/java/nio/HeapByteBufferDoubleView.scala b/javalib/src/main/scala/java/nio/HeapByteBufferDoubleView.scala index 6775829570..fd1cd29cb2 100644 --- a/javalib/src/main/scala/java/nio/HeapByteBufferDoubleView.scala +++ b/javalib/src/main/scala/java/nio/HeapByteBufferDoubleView.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio private[nio] final class HeapByteBufferDoubleView private ( diff --git a/javalib/src/main/scala/java/nio/HeapByteBufferFloatView.scala b/javalib/src/main/scala/java/nio/HeapByteBufferFloatView.scala index c21bf14153..65396404da 100644 --- a/javalib/src/main/scala/java/nio/HeapByteBufferFloatView.scala +++ b/javalib/src/main/scala/java/nio/HeapByteBufferFloatView.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio private[nio] final class HeapByteBufferFloatView private ( diff --git a/javalib/src/main/scala/java/nio/HeapByteBufferIntView.scala b/javalib/src/main/scala/java/nio/HeapByteBufferIntView.scala index 8eeb548a4c..6751d8f730 100644 --- a/javalib/src/main/scala/java/nio/HeapByteBufferIntView.scala +++ b/javalib/src/main/scala/java/nio/HeapByteBufferIntView.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio private[nio] final class HeapByteBufferIntView private ( diff --git a/javalib/src/main/scala/java/nio/HeapByteBufferLongView.scala b/javalib/src/main/scala/java/nio/HeapByteBufferLongView.scala index 423fdd0c36..37edbfef4f 100644 --- a/javalib/src/main/scala/java/nio/HeapByteBufferLongView.scala +++ b/javalib/src/main/scala/java/nio/HeapByteBufferLongView.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio private[nio] final class HeapByteBufferLongView private ( diff --git a/javalib/src/main/scala/java/nio/HeapByteBufferShortView.scala b/javalib/src/main/scala/java/nio/HeapByteBufferShortView.scala index beb6a4fd3a..c0f5c10d8c 100644 --- a/javalib/src/main/scala/java/nio/HeapByteBufferShortView.scala +++ b/javalib/src/main/scala/java/nio/HeapByteBufferShortView.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio private[nio] final class HeapByteBufferShortView private ( diff --git a/javalib/src/main/scala/java/nio/HeapCharBuffer.scala b/javalib/src/main/scala/java/nio/HeapCharBuffer.scala index a6b9882daf..e4c490f8ce 100644 --- a/javalib/src/main/scala/java/nio/HeapCharBuffer.scala +++ b/javalib/src/main/scala/java/nio/HeapCharBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio private[nio] final class HeapCharBuffer private ( diff --git a/javalib/src/main/scala/java/nio/HeapDoubleBuffer.scala b/javalib/src/main/scala/java/nio/HeapDoubleBuffer.scala index 3835d616b8..d3450ed294 100644 --- a/javalib/src/main/scala/java/nio/HeapDoubleBuffer.scala +++ b/javalib/src/main/scala/java/nio/HeapDoubleBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio private[nio] final class HeapDoubleBuffer private ( diff --git a/javalib/src/main/scala/java/nio/HeapFloatBuffer.scala b/javalib/src/main/scala/java/nio/HeapFloatBuffer.scala index 8114fb45e9..0df54d4015 100644 --- a/javalib/src/main/scala/java/nio/HeapFloatBuffer.scala +++ b/javalib/src/main/scala/java/nio/HeapFloatBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio private[nio] final class HeapFloatBuffer private ( diff --git a/javalib/src/main/scala/java/nio/HeapIntBuffer.scala b/javalib/src/main/scala/java/nio/HeapIntBuffer.scala index 6a0513eea6..52f782fd43 100644 --- a/javalib/src/main/scala/java/nio/HeapIntBuffer.scala +++ b/javalib/src/main/scala/java/nio/HeapIntBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio private[nio] final class HeapIntBuffer private ( diff --git a/javalib/src/main/scala/java/nio/HeapLongBuffer.scala b/javalib/src/main/scala/java/nio/HeapLongBuffer.scala index 376bcb5259..0e04acc4a6 100644 --- a/javalib/src/main/scala/java/nio/HeapLongBuffer.scala +++ b/javalib/src/main/scala/java/nio/HeapLongBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio private[nio] final class HeapLongBuffer private ( diff --git a/javalib/src/main/scala/java/nio/HeapShortBuffer.scala b/javalib/src/main/scala/java/nio/HeapShortBuffer.scala index 8848d016da..cc087818cc 100644 --- a/javalib/src/main/scala/java/nio/HeapShortBuffer.scala +++ b/javalib/src/main/scala/java/nio/HeapShortBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio private[nio] final class HeapShortBuffer private ( diff --git a/javalib/src/main/scala/java/nio/IntBuffer.scala b/javalib/src/main/scala/java/nio/IntBuffer.scala index 4f7249c137..5408d41f9b 100644 --- a/javalib/src/main/scala/java/nio/IntBuffer.scala +++ b/javalib/src/main/scala/java/nio/IntBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio import scala.scalajs.js.typedarray._ diff --git a/javalib/src/main/scala/java/nio/InvalidMarkException.scala b/javalib/src/main/scala/java/nio/InvalidMarkException.scala index c2d3714ae5..3b0181f046 100644 --- a/javalib/src/main/scala/java/nio/InvalidMarkException.scala +++ b/javalib/src/main/scala/java/nio/InvalidMarkException.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio class InvalidMarkException extends IllegalStateException diff --git a/javalib/src/main/scala/java/nio/LongBuffer.scala b/javalib/src/main/scala/java/nio/LongBuffer.scala index e6eb2c4200..2f9318d900 100644 --- a/javalib/src/main/scala/java/nio/LongBuffer.scala +++ b/javalib/src/main/scala/java/nio/LongBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio object LongBuffer { diff --git a/javalib/src/main/scala/java/nio/ReadOnlyBufferException.scala b/javalib/src/main/scala/java/nio/ReadOnlyBufferException.scala index ee0868b3ee..be61694796 100644 --- a/javalib/src/main/scala/java/nio/ReadOnlyBufferException.scala +++ b/javalib/src/main/scala/java/nio/ReadOnlyBufferException.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio class ReadOnlyBufferException extends UnsupportedOperationException diff --git a/javalib/src/main/scala/java/nio/ShortBuffer.scala b/javalib/src/main/scala/java/nio/ShortBuffer.scala index b560b231c2..7051ff3663 100644 --- a/javalib/src/main/scala/java/nio/ShortBuffer.scala +++ b/javalib/src/main/scala/java/nio/ShortBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio import scala.scalajs.js.typedarray._ diff --git a/javalib/src/main/scala/java/nio/StringCharBuffer.scala b/javalib/src/main/scala/java/nio/StringCharBuffer.scala index 5a7c507ce2..770fd2a7ff 100644 --- a/javalib/src/main/scala/java/nio/StringCharBuffer.scala +++ b/javalib/src/main/scala/java/nio/StringCharBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio private[nio] final class StringCharBuffer private ( diff --git a/javalib/src/main/scala/java/nio/TypedArrayByteBuffer.scala b/javalib/src/main/scala/java/nio/TypedArrayByteBuffer.scala index c9fc816fed..424fb131be 100644 --- a/javalib/src/main/scala/java/nio/TypedArrayByteBuffer.scala +++ b/javalib/src/main/scala/java/nio/TypedArrayByteBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio import scala.scalajs.js.typedarray._ diff --git a/javalib/src/main/scala/java/nio/TypedArrayCharBuffer.scala b/javalib/src/main/scala/java/nio/TypedArrayCharBuffer.scala index 49b463f48d..b945bd007c 100644 --- a/javalib/src/main/scala/java/nio/TypedArrayCharBuffer.scala +++ b/javalib/src/main/scala/java/nio/TypedArrayCharBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio import scala.scalajs.js.typedarray._ diff --git a/javalib/src/main/scala/java/nio/TypedArrayDoubleBuffer.scala b/javalib/src/main/scala/java/nio/TypedArrayDoubleBuffer.scala index 2d58f06518..5cb48beace 100644 --- a/javalib/src/main/scala/java/nio/TypedArrayDoubleBuffer.scala +++ b/javalib/src/main/scala/java/nio/TypedArrayDoubleBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio import scala.scalajs.js.typedarray._ diff --git a/javalib/src/main/scala/java/nio/TypedArrayFloatBuffer.scala b/javalib/src/main/scala/java/nio/TypedArrayFloatBuffer.scala index 1c966b788d..d485e87054 100644 --- a/javalib/src/main/scala/java/nio/TypedArrayFloatBuffer.scala +++ b/javalib/src/main/scala/java/nio/TypedArrayFloatBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio import scala.scalajs.js.typedarray._ diff --git a/javalib/src/main/scala/java/nio/TypedArrayIntBuffer.scala b/javalib/src/main/scala/java/nio/TypedArrayIntBuffer.scala index b03a9da36b..2d73e5025e 100644 --- a/javalib/src/main/scala/java/nio/TypedArrayIntBuffer.scala +++ b/javalib/src/main/scala/java/nio/TypedArrayIntBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio import scala.scalajs.js.typedarray._ diff --git a/javalib/src/main/scala/java/nio/TypedArrayShortBuffer.scala b/javalib/src/main/scala/java/nio/TypedArrayShortBuffer.scala index fb3fa283ae..0c77246b34 100644 --- a/javalib/src/main/scala/java/nio/TypedArrayShortBuffer.scala +++ b/javalib/src/main/scala/java/nio/TypedArrayShortBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio import scala.scalajs.js.typedarray._ diff --git a/javalib/src/main/scala/java/nio/charset/CharacterCodingException.scala b/javalib/src/main/scala/java/nio/charset/CharacterCodingException.scala index 8017348c83..4bc8d95dfe 100644 --- a/javalib/src/main/scala/java/nio/charset/CharacterCodingException.scala +++ b/javalib/src/main/scala/java/nio/charset/CharacterCodingException.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio.charset class CharacterCodingException extends java.io.IOException diff --git a/javalib/src/main/scala/java/nio/charset/Charset.scala b/javalib/src/main/scala/java/nio/charset/Charset.scala index 71396e9eb9..68d9582a92 100644 --- a/javalib/src/main/scala/java/nio/charset/Charset.scala +++ b/javalib/src/main/scala/java/nio/charset/Charset.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio.charset import java.nio.{ByteBuffer, CharBuffer} diff --git a/javalib/src/main/scala/java/nio/charset/CharsetDecoder.scala b/javalib/src/main/scala/java/nio/charset/CharsetDecoder.scala index bc41bdb850..091c485617 100644 --- a/javalib/src/main/scala/java/nio/charset/CharsetDecoder.scala +++ b/javalib/src/main/scala/java/nio/charset/CharsetDecoder.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio.charset import scala.annotation.{switch, tailrec} diff --git a/javalib/src/main/scala/java/nio/charset/CharsetEncoder.scala b/javalib/src/main/scala/java/nio/charset/CharsetEncoder.scala index 74ca083794..17af6e1437 100644 --- a/javalib/src/main/scala/java/nio/charset/CharsetEncoder.scala +++ b/javalib/src/main/scala/java/nio/charset/CharsetEncoder.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio.charset import scala.annotation.{switch, tailrec} diff --git a/javalib/src/main/scala/java/nio/charset/CoderMalfunctionError.scala b/javalib/src/main/scala/java/nio/charset/CoderMalfunctionError.scala index 33174f3313..027ee1b7dd 100644 --- a/javalib/src/main/scala/java/nio/charset/CoderMalfunctionError.scala +++ b/javalib/src/main/scala/java/nio/charset/CoderMalfunctionError.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio.charset class CoderMalfunctionError(cause: Exception) extends Error(cause) diff --git a/javalib/src/main/scala/java/nio/charset/CoderResult.scala b/javalib/src/main/scala/java/nio/charset/CoderResult.scala index fdc63cc7e6..8cfe677a1b 100644 --- a/javalib/src/main/scala/java/nio/charset/CoderResult.scala +++ b/javalib/src/main/scala/java/nio/charset/CoderResult.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio.charset import scala.annotation.switch diff --git a/javalib/src/main/scala/java/nio/charset/CodingErrorAction.scala b/javalib/src/main/scala/java/nio/charset/CodingErrorAction.scala index 63b48bbd4f..08a4a02a85 100644 --- a/javalib/src/main/scala/java/nio/charset/CodingErrorAction.scala +++ b/javalib/src/main/scala/java/nio/charset/CodingErrorAction.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio.charset class CodingErrorAction private (name: String) { diff --git a/javalib/src/main/scala/java/nio/charset/MalformedInputException.scala b/javalib/src/main/scala/java/nio/charset/MalformedInputException.scala index 4c91c1b931..dd36257434 100644 --- a/javalib/src/main/scala/java/nio/charset/MalformedInputException.scala +++ b/javalib/src/main/scala/java/nio/charset/MalformedInputException.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio.charset class MalformedInputException( diff --git a/javalib/src/main/scala/java/nio/charset/StandardCharsets.scala b/javalib/src/main/scala/java/nio/charset/StandardCharsets.scala index 62e2c2bad6..b198608312 100644 --- a/javalib/src/main/scala/java/nio/charset/StandardCharsets.scala +++ b/javalib/src/main/scala/java/nio/charset/StandardCharsets.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio.charset final class StandardCharsets private () diff --git a/javalib/src/main/scala/java/nio/charset/UnmappableCharacterException.scala b/javalib/src/main/scala/java/nio/charset/UnmappableCharacterException.scala index 5748f703ae..6b6d5220bc 100644 --- a/javalib/src/main/scala/java/nio/charset/UnmappableCharacterException.scala +++ b/javalib/src/main/scala/java/nio/charset/UnmappableCharacterException.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio.charset class UnmappableCharacterException( diff --git a/javalib/src/main/scala/java/nio/charset/UnsupportedCharsetException.scala b/javalib/src/main/scala/java/nio/charset/UnsupportedCharsetException.scala index 97a7a4ed85..25ec9e095e 100644 --- a/javalib/src/main/scala/java/nio/charset/UnsupportedCharsetException.scala +++ b/javalib/src/main/scala/java/nio/charset/UnsupportedCharsetException.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.nio.charset class UnsupportedCharsetException( diff --git a/javalib/src/main/scala/java/security/Guard.scala b/javalib/src/main/scala/java/security/Guard.scala index a3e9be7f80..984d7566c5 100644 --- a/javalib/src/main/scala/java/security/Guard.scala +++ b/javalib/src/main/scala/java/security/Guard.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.security trait Guard { diff --git a/javalib/src/main/scala/java/security/Permission.scala b/javalib/src/main/scala/java/security/Permission.scala index 7318b54063..8cc6a1e9d5 100644 --- a/javalib/src/main/scala/java/security/Permission.scala +++ b/javalib/src/main/scala/java/security/Permission.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.security abstract class Permission(name: String) extends Guard with Serializable { diff --git a/javalib/src/main/scala/java/security/Throwables.scala b/javalib/src/main/scala/java/security/Throwables.scala index 41ec6cc342..84dce9a1ee 100644 --- a/javalib/src/main/scala/java/security/Throwables.scala +++ b/javalib/src/main/scala/java/security/Throwables.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.security import java.lang.SecurityException diff --git a/javalib/src/main/scala/java/util/AbstractCollection.scala b/javalib/src/main/scala/java/util/AbstractCollection.scala index 331b2e8845..cc3442dbd1 100644 --- a/javalib/src/main/scala/java/util/AbstractCollection.scala +++ b/javalib/src/main/scala/java/util/AbstractCollection.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import scala.annotation.tailrec diff --git a/javalib/src/main/scala/java/util/AbstractList.scala b/javalib/src/main/scala/java/util/AbstractList.scala index 79f061fc3d..a9c2ca2055 100644 --- a/javalib/src/main/scala/java/util/AbstractList.scala +++ b/javalib/src/main/scala/java/util/AbstractList.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import scala.annotation.tailrec diff --git a/javalib/src/main/scala/java/util/AbstractMap.scala b/javalib/src/main/scala/java/util/AbstractMap.scala index fea7941b30..520b6f36d1 100644 --- a/javalib/src/main/scala/java/util/AbstractMap.scala +++ b/javalib/src/main/scala/java/util/AbstractMap.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import scala.annotation.tailrec diff --git a/javalib/src/main/scala/java/util/AbstractQueue.scala b/javalib/src/main/scala/java/util/AbstractQueue.scala index 4cb5d7e758..e1eb450d20 100644 --- a/javalib/src/main/scala/java/util/AbstractQueue.scala +++ b/javalib/src/main/scala/java/util/AbstractQueue.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util abstract class AbstractQueue[E] protected () diff --git a/javalib/src/main/scala/java/util/AbstractRandomAccessListIterator.scala b/javalib/src/main/scala/java/util/AbstractRandomAccessListIterator.scala index e61f5ee665..24b9c853e7 100644 --- a/javalib/src/main/scala/java/util/AbstractRandomAccessListIterator.scala +++ b/javalib/src/main/scala/java/util/AbstractRandomAccessListIterator.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util abstract private[util] class AbstractRandomAccessListIterator[E](private var i: Int, diff --git a/javalib/src/main/scala/java/util/AbstractSequentialList.scala b/javalib/src/main/scala/java/util/AbstractSequentialList.scala index 6ebffb478d..37015ecade 100644 --- a/javalib/src/main/scala/java/util/AbstractSequentialList.scala +++ b/javalib/src/main/scala/java/util/AbstractSequentialList.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util abstract class AbstractSequentialList[E] protected () diff --git a/javalib/src/main/scala/java/util/AbstractSet.scala b/javalib/src/main/scala/java/util/AbstractSet.scala index f04714eee5..44687eaa90 100644 --- a/javalib/src/main/scala/java/util/AbstractSet.scala +++ b/javalib/src/main/scala/java/util/AbstractSet.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import scala.annotation.tailrec diff --git a/javalib/src/main/scala/java/util/ArrayDeque.scala b/javalib/src/main/scala/java/util/ArrayDeque.scala index 537607174e..7564bce572 100644 --- a/javalib/src/main/scala/java/util/ArrayDeque.scala +++ b/javalib/src/main/scala/java/util/ArrayDeque.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import scala.scalajs.js diff --git a/javalib/src/main/scala/java/util/ArrayList.scala b/javalib/src/main/scala/java/util/ArrayList.scala index 1139d23434..fbb682736b 100644 --- a/javalib/src/main/scala/java/util/ArrayList.scala +++ b/javalib/src/main/scala/java/util/ArrayList.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import scala.scalajs._ diff --git a/javalib/src/main/scala/java/util/Arrays.scala b/javalib/src/main/scala/java/util/Arrays.scala index e09ef784c8..cc0b8caa49 100644 --- a/javalib/src/main/scala/java/util/Arrays.scala +++ b/javalib/src/main/scala/java/util/Arrays.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import scala.scalajs.js diff --git a/javalib/src/main/scala/java/util/Base64.scala b/javalib/src/main/scala/java/util/Base64.scala index 28b82d7dec..77190b8313 100644 --- a/javalib/src/main/scala/java/util/Base64.scala +++ b/javalib/src/main/scala/java/util/Base64.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import scala.annotation.tailrec diff --git a/javalib/src/main/scala/java/util/Collection.scala b/javalib/src/main/scala/java/util/Collection.scala index 27158cf06c..f8a0b7a556 100644 --- a/javalib/src/main/scala/java/util/Collection.scala +++ b/javalib/src/main/scala/java/util/Collection.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util trait Collection[E] extends java.lang.Iterable[E] { diff --git a/javalib/src/main/scala/java/util/Collections.scala b/javalib/src/main/scala/java/util/Collections.scala index 2e0d2482bb..6941a717c1 100644 --- a/javalib/src/main/scala/java/util/Collections.scala +++ b/javalib/src/main/scala/java/util/Collections.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import java.{lang => jl} diff --git a/javalib/src/main/scala/java/util/Comparator.scala b/javalib/src/main/scala/java/util/Comparator.scala index fe4e2ced95..6edd9b50a3 100644 --- a/javalib/src/main/scala/java/util/Comparator.scala +++ b/javalib/src/main/scala/java/util/Comparator.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import scala.scalajs.js.annotation.JavaDefaultMethod diff --git a/javalib/src/main/scala/java/util/Compat.scala b/javalib/src/main/scala/java/util/Compat.scala index 363c1fb043..dec28971b0 100644 --- a/javalib/src/main/scala/java/util/Compat.scala +++ b/javalib/src/main/scala/java/util/Compat.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import scala.collection.mutable diff --git a/javalib/src/main/scala/java/util/Date.scala b/javalib/src/main/scala/java/util/Date.scala index 342745cdb3..f4f65515c8 100644 --- a/javalib/src/main/scala/java/util/Date.scala +++ b/javalib/src/main/scala/java/util/Date.scala @@ -1,6 +1,13 @@ -/** - * 2014 Matt Seddon - * This code is donated in full to the scala-js project. +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ package java.util diff --git a/javalib/src/main/scala/java/util/Deque.scala b/javalib/src/main/scala/java/util/Deque.scala index 74fdc02d5e..89b70bc615 100644 --- a/javalib/src/main/scala/java/util/Deque.scala +++ b/javalib/src/main/scala/java/util/Deque.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util trait Deque[E] extends Queue[E] { diff --git a/javalib/src/main/scala/java/util/Dictionary.scala b/javalib/src/main/scala/java/util/Dictionary.scala index 21e420e0fd..defa29668d 100644 --- a/javalib/src/main/scala/java/util/Dictionary.scala +++ b/javalib/src/main/scala/java/util/Dictionary.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util abstract class Dictionary[K, V] { diff --git a/javalib/src/main/scala/java/util/Enumeration.scala b/javalib/src/main/scala/java/util/Enumeration.scala index 04aa34edd4..e93b02d203 100644 --- a/javalib/src/main/scala/java/util/Enumeration.scala +++ b/javalib/src/main/scala/java/util/Enumeration.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util trait Enumeration[E] { diff --git a/javalib/src/main/scala/java/util/EventObject.scala b/javalib/src/main/scala/java/util/EventObject.scala index bf5e6e0412..dfed2519ea 100644 --- a/javalib/src/main/scala/java/util/EventObject.scala +++ b/javalib/src/main/scala/java/util/EventObject.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util class EventObject(protected var source: AnyRef) { diff --git a/javalib/src/main/scala/java/util/Formattable.scala b/javalib/src/main/scala/java/util/Formattable.scala index e651fbba24..ae018d5bf3 100644 --- a/javalib/src/main/scala/java/util/Formattable.scala +++ b/javalib/src/main/scala/java/util/Formattable.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util trait Formattable { diff --git a/javalib/src/main/scala/java/util/FormattableFlags.scala b/javalib/src/main/scala/java/util/FormattableFlags.scala index 02f5bce356..e663ab7a4c 100644 --- a/javalib/src/main/scala/java/util/FormattableFlags.scala +++ b/javalib/src/main/scala/java/util/FormattableFlags.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util object FormattableFlags { diff --git a/javalib/src/main/scala/java/util/Formatter.scala b/javalib/src/main/scala/java/util/Formatter.scala index e79b73da12..82819cb241 100644 --- a/javalib/src/main/scala/java/util/Formatter.scala +++ b/javalib/src/main/scala/java/util/Formatter.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import scala.annotation.switch diff --git a/javalib/src/main/scala/java/util/HashMap.scala b/javalib/src/main/scala/java/util/HashMap.scala index de1d18e9bf..3c5be1b7ac 100644 --- a/javalib/src/main/scala/java/util/HashMap.scala +++ b/javalib/src/main/scala/java/util/HashMap.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import scala.collection.mutable diff --git a/javalib/src/main/scala/java/util/HashSet.scala b/javalib/src/main/scala/java/util/HashSet.scala index 8f875d83f4..f6ed360c6a 100644 --- a/javalib/src/main/scala/java/util/HashSet.scala +++ b/javalib/src/main/scala/java/util/HashSet.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import scala.collection.mutable diff --git a/javalib/src/main/scala/java/util/Hashtable.scala b/javalib/src/main/scala/java/util/Hashtable.scala index 3b3f820e39..7cd6e44c20 100644 --- a/javalib/src/main/scala/java/util/Hashtable.scala +++ b/javalib/src/main/scala/java/util/Hashtable.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import java.{util => ju} diff --git a/javalib/src/main/scala/java/util/Iterator.scala b/javalib/src/main/scala/java/util/Iterator.scala index 0d319522d8..4bfbacf46d 100644 --- a/javalib/src/main/scala/java/util/Iterator.scala +++ b/javalib/src/main/scala/java/util/Iterator.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util trait Iterator[E] { diff --git a/javalib/src/main/scala/java/util/LinkedHashMap.scala b/javalib/src/main/scala/java/util/LinkedHashMap.scala index 1563d26ee2..7a85e069de 100644 --- a/javalib/src/main/scala/java/util/LinkedHashMap.scala +++ b/javalib/src/main/scala/java/util/LinkedHashMap.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import scala.collection.mutable diff --git a/javalib/src/main/scala/java/util/LinkedHashSet.scala b/javalib/src/main/scala/java/util/LinkedHashSet.scala index b7be45c936..a305b9f0d9 100644 --- a/javalib/src/main/scala/java/util/LinkedHashSet.scala +++ b/javalib/src/main/scala/java/util/LinkedHashSet.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import scala.collection.mutable diff --git a/javalib/src/main/scala/java/util/LinkedList.scala b/javalib/src/main/scala/java/util/LinkedList.scala index 1dd4aae10f..871bacfd68 100644 --- a/javalib/src/main/scala/java/util/LinkedList.scala +++ b/javalib/src/main/scala/java/util/LinkedList.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import scala.annotation.tailrec diff --git a/javalib/src/main/scala/java/util/List.scala b/javalib/src/main/scala/java/util/List.scala index 17aa6693b2..eb53d13173 100644 --- a/javalib/src/main/scala/java/util/List.scala +++ b/javalib/src/main/scala/java/util/List.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util trait List[E] extends Collection[E] { diff --git a/javalib/src/main/scala/java/util/ListIterator.scala b/javalib/src/main/scala/java/util/ListIterator.scala index 641f9f1b99..88c573583b 100644 --- a/javalib/src/main/scala/java/util/ListIterator.scala +++ b/javalib/src/main/scala/java/util/ListIterator.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util trait ListIterator[E] extends Iterator[E] { diff --git a/javalib/src/main/scala/java/util/Map.scala b/javalib/src/main/scala/java/util/Map.scala index 4e808d3d8e..8d02265fd0 100644 --- a/javalib/src/main/scala/java/util/Map.scala +++ b/javalib/src/main/scala/java/util/Map.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util trait Map[K, V] { diff --git a/javalib/src/main/scala/java/util/NavigableMap.scala b/javalib/src/main/scala/java/util/NavigableMap.scala index e35bed106a..f85b9feee0 100644 --- a/javalib/src/main/scala/java/util/NavigableMap.scala +++ b/javalib/src/main/scala/java/util/NavigableMap.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util trait NavigableMap[K, V] extends SortedMap[K, V] { diff --git a/javalib/src/main/scala/java/util/NavigableSet.scala b/javalib/src/main/scala/java/util/NavigableSet.scala index b8b3d12cef..f19c346805 100644 --- a/javalib/src/main/scala/java/util/NavigableSet.scala +++ b/javalib/src/main/scala/java/util/NavigableSet.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util trait NavigableSet[E] extends SortedSet[E] { diff --git a/javalib/src/main/scala/java/util/NavigableView.scala b/javalib/src/main/scala/java/util/NavigableView.scala index 79e1a351aa..e5b713006a 100644 --- a/javalib/src/main/scala/java/util/NavigableView.scala +++ b/javalib/src/main/scala/java/util/NavigableView.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import scala.math.Ordering diff --git a/javalib/src/main/scala/java/util/Objects.scala b/javalib/src/main/scala/java/util/Objects.scala index f9188334bf..2c0b636288 100644 --- a/javalib/src/main/scala/java/util/Objects.scala +++ b/javalib/src/main/scala/java/util/Objects.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import scala.reflect.ClassTag diff --git a/javalib/src/main/scala/java/util/Optional.scala b/javalib/src/main/scala/java/util/Optional.scala index 14ef0a9c28..c1ca0cd04a 100644 --- a/javalib/src/main/scala/java/util/Optional.scala +++ b/javalib/src/main/scala/java/util/Optional.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util final class Optional[T] private (value: T) { diff --git a/javalib/src/main/scala/java/util/PriorityQueue.scala b/javalib/src/main/scala/java/util/PriorityQueue.scala index 20910b90f2..128be47372 100644 --- a/javalib/src/main/scala/java/util/PriorityQueue.scala +++ b/javalib/src/main/scala/java/util/PriorityQueue.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import java.lang.Comparable diff --git a/javalib/src/main/scala/java/util/Properties.scala b/javalib/src/main/scala/java/util/Properties.scala index 416a1ebf15..356df846e8 100644 --- a/javalib/src/main/scala/java/util/Properties.scala +++ b/javalib/src/main/scala/java/util/Properties.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import java.{util => ju} diff --git a/javalib/src/main/scala/java/util/Queue.scala b/javalib/src/main/scala/java/util/Queue.scala index 981062a1c3..35e5e6da63 100644 --- a/javalib/src/main/scala/java/util/Queue.scala +++ b/javalib/src/main/scala/java/util/Queue.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util trait Queue[E] extends Collection[E] { diff --git a/javalib/src/main/scala/java/util/Random.scala b/javalib/src/main/scala/java/util/Random.scala index 6d346d587a..1a4a1610ed 100644 --- a/javalib/src/main/scala/java/util/Random.scala +++ b/javalib/src/main/scala/java/util/Random.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import scala.annotation.tailrec diff --git a/javalib/src/main/scala/java/util/RandomAccess.scala b/javalib/src/main/scala/java/util/RandomAccess.scala index 33f18608f9..23e6d0bb5c 100644 --- a/javalib/src/main/scala/java/util/RandomAccess.scala +++ b/javalib/src/main/scala/java/util/RandomAccess.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util trait RandomAccess diff --git a/javalib/src/main/scala/java/util/Set.scala b/javalib/src/main/scala/java/util/Set.scala index 5454c8dfc8..d36b0c8059 100644 --- a/javalib/src/main/scala/java/util/Set.scala +++ b/javalib/src/main/scala/java/util/Set.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util trait Set[E] extends Collection[E] diff --git a/javalib/src/main/scala/java/util/SizeChangeEvent.scala b/javalib/src/main/scala/java/util/SizeChangeEvent.scala index 946251e7bb..0d786f3dbc 100644 --- a/javalib/src/main/scala/java/util/SizeChangeEvent.scala +++ b/javalib/src/main/scala/java/util/SizeChangeEvent.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util private[util] trait SizeChangeEvent { diff --git a/javalib/src/main/scala/java/util/SortedMap.scala b/javalib/src/main/scala/java/util/SortedMap.scala index d473ec27a3..e2ac54cfef 100644 --- a/javalib/src/main/scala/java/util/SortedMap.scala +++ b/javalib/src/main/scala/java/util/SortedMap.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util trait SortedMap[K, V] extends Map[K, V] { diff --git a/javalib/src/main/scala/java/util/SortedSet.scala b/javalib/src/main/scala/java/util/SortedSet.scala index 8dc438f60c..b4f6fcc83d 100644 --- a/javalib/src/main/scala/java/util/SortedSet.scala +++ b/javalib/src/main/scala/java/util/SortedSet.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util trait SortedSet[E] extends Set[E] { diff --git a/javalib/src/main/scala/java/util/SplittableRandom.scala b/javalib/src/main/scala/java/util/SplittableRandom.scala index 15cb070b84..3713eb8807 100644 --- a/javalib/src/main/scala/java/util/SplittableRandom.scala +++ b/javalib/src/main/scala/java/util/SplittableRandom.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util /* diff --git a/javalib/src/main/scala/java/util/Throwables.scala b/javalib/src/main/scala/java/util/Throwables.scala index a0a8f552a1..44582c9ecd 100644 --- a/javalib/src/main/scala/java/util/Throwables.scala +++ b/javalib/src/main/scala/java/util/Throwables.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util class ServiceConfigurationError(s: String, e: Throwable) extends Error(s, e) { diff --git a/javalib/src/main/scala/java/util/Timer.scala b/javalib/src/main/scala/java/util/Timer.scala index 78f068cee7..2c79059ac5 100644 --- a/javalib/src/main/scala/java/util/Timer.scala +++ b/javalib/src/main/scala/java/util/Timer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import scala.collection._ diff --git a/javalib/src/main/scala/java/util/TimerTask.scala b/javalib/src/main/scala/java/util/TimerTask.scala index eadbd758e4..c775afa4fe 100644 --- a/javalib/src/main/scala/java/util/TimerTask.scala +++ b/javalib/src/main/scala/java/util/TimerTask.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import scala.concurrent.duration.FiniteDuration diff --git a/javalib/src/main/scala/java/util/TreeSet.scala b/javalib/src/main/scala/java/util/TreeSet.scala index b7c50aae8e..20b3a160e3 100644 --- a/javalib/src/main/scala/java/util/TreeSet.scala +++ b/javalib/src/main/scala/java/util/TreeSet.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import java.lang.Comparable diff --git a/javalib/src/main/scala/java/util/UUID.scala b/javalib/src/main/scala/java/util/UUID.scala index b5c4d48e99..1deb00e0d7 100644 --- a/javalib/src/main/scala/java/util/UUID.scala +++ b/javalib/src/main/scala/java/util/UUID.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util import java.lang.{Long => JLong} diff --git a/javalib/src/main/scala/java/util/concurrent/Callable.scala b/javalib/src/main/scala/java/util/concurrent/Callable.scala index fc522093e7..f25696ef6f 100644 --- a/javalib/src/main/scala/java/util/concurrent/Callable.scala +++ b/javalib/src/main/scala/java/util/concurrent/Callable.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util.concurrent trait Callable[V] { diff --git a/javalib/src/main/scala/java/util/concurrent/ConcurrentHashMap.scala b/javalib/src/main/scala/java/util/concurrent/ConcurrentHashMap.scala index 52e05404db..897dfb1ff0 100644 --- a/javalib/src/main/scala/java/util/concurrent/ConcurrentHashMap.scala +++ b/javalib/src/main/scala/java/util/concurrent/ConcurrentHashMap.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util.concurrent import java.lang.{reflect => jlr} diff --git a/javalib/src/main/scala/java/util/concurrent/ConcurrentLinkedQueue.scala b/javalib/src/main/scala/java/util/concurrent/ConcurrentLinkedQueue.scala index c3c2a93cc8..b0be4e361e 100644 --- a/javalib/src/main/scala/java/util/concurrent/ConcurrentLinkedQueue.scala +++ b/javalib/src/main/scala/java/util/concurrent/ConcurrentLinkedQueue.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util.concurrent import java.util._ diff --git a/javalib/src/main/scala/java/util/concurrent/ConcurrentMap.scala b/javalib/src/main/scala/java/util/concurrent/ConcurrentMap.scala index 6f12a6d703..c333acb27c 100644 --- a/javalib/src/main/scala/java/util/concurrent/ConcurrentMap.scala +++ b/javalib/src/main/scala/java/util/concurrent/ConcurrentMap.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util.concurrent import java.util._ diff --git a/javalib/src/main/scala/java/util/concurrent/ConcurrentSkipListSet.scala b/javalib/src/main/scala/java/util/concurrent/ConcurrentSkipListSet.scala index 29228c012d..e007f472eb 100644 --- a/javalib/src/main/scala/java/util/concurrent/ConcurrentSkipListSet.scala +++ b/javalib/src/main/scala/java/util/concurrent/ConcurrentSkipListSet.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util.concurrent import java.util._ diff --git a/javalib/src/main/scala/java/util/concurrent/CopyOnWriteArrayList.scala b/javalib/src/main/scala/java/util/concurrent/CopyOnWriteArrayList.scala index c69d8901be..e25b86d3e3 100644 --- a/javalib/src/main/scala/java/util/concurrent/CopyOnWriteArrayList.scala +++ b/javalib/src/main/scala/java/util/concurrent/CopyOnWriteArrayList.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util.concurrent import java.lang.{reflect => jlr} diff --git a/javalib/src/main/scala/java/util/concurrent/Executor.scala b/javalib/src/main/scala/java/util/concurrent/Executor.scala index d030551703..7dcc160ebe 100644 --- a/javalib/src/main/scala/java/util/concurrent/Executor.scala +++ b/javalib/src/main/scala/java/util/concurrent/Executor.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util.concurrent trait Executor { diff --git a/javalib/src/main/scala/java/util/concurrent/ThreadFactory.scala b/javalib/src/main/scala/java/util/concurrent/ThreadFactory.scala index 650ea33be4..7fca0cbb79 100644 --- a/javalib/src/main/scala/java/util/concurrent/ThreadFactory.scala +++ b/javalib/src/main/scala/java/util/concurrent/ThreadFactory.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util.concurrent trait ThreadFactory { diff --git a/javalib/src/main/scala/java/util/concurrent/Throwables.scala b/javalib/src/main/scala/java/util/concurrent/Throwables.scala index 2af6669f8f..c41c1c7bf5 100644 --- a/javalib/src/main/scala/java/util/concurrent/Throwables.scala +++ b/javalib/src/main/scala/java/util/concurrent/Throwables.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util.concurrent class ExecutionException(message: String, cause: Throwable) diff --git a/javalib/src/main/scala/java/util/concurrent/TimeUnit.scala b/javalib/src/main/scala/java/util/concurrent/TimeUnit.scala index ef08c69472..fdaa12e89a 100644 --- a/javalib/src/main/scala/java/util/concurrent/TimeUnit.scala +++ b/javalib/src/main/scala/java/util/concurrent/TimeUnit.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util.concurrent abstract class TimeUnit private (name: String, ordinal: Int) diff --git a/javalib/src/main/scala/java/util/concurrent/atomic/AtomicBoolean.scala b/javalib/src/main/scala/java/util/concurrent/atomic/AtomicBoolean.scala index 5675c31927..ffdb0ae276 100644 --- a/javalib/src/main/scala/java/util/concurrent/atomic/AtomicBoolean.scala +++ b/javalib/src/main/scala/java/util/concurrent/atomic/AtomicBoolean.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util.concurrent.atomic class AtomicBoolean(private[this] var value: Boolean) extends Serializable { diff --git a/javalib/src/main/scala/java/util/concurrent/atomic/AtomicInteger.scala b/javalib/src/main/scala/java/util/concurrent/atomic/AtomicInteger.scala index 1f24b7b8f7..0622ba8e10 100644 --- a/javalib/src/main/scala/java/util/concurrent/atomic/AtomicInteger.scala +++ b/javalib/src/main/scala/java/util/concurrent/atomic/AtomicInteger.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util.concurrent.atomic class AtomicInteger(private[this] var value: Int) diff --git a/javalib/src/main/scala/java/util/concurrent/atomic/AtomicLong.scala b/javalib/src/main/scala/java/util/concurrent/atomic/AtomicLong.scala index 5bfecf2eec..01c4c0b98b 100644 --- a/javalib/src/main/scala/java/util/concurrent/atomic/AtomicLong.scala +++ b/javalib/src/main/scala/java/util/concurrent/atomic/AtomicLong.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util.concurrent.atomic class AtomicLong(private[this] var value: Long) extends Number with Serializable { diff --git a/javalib/src/main/scala/java/util/concurrent/atomic/AtomicLongArray.scala b/javalib/src/main/scala/java/util/concurrent/atomic/AtomicLongArray.scala index acb8ec4405..70acbe66a2 100644 --- a/javalib/src/main/scala/java/util/concurrent/atomic/AtomicLongArray.scala +++ b/javalib/src/main/scala/java/util/concurrent/atomic/AtomicLongArray.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util.concurrent.atomic class AtomicLongArray(length: Int) extends Serializable { diff --git a/javalib/src/main/scala/java/util/concurrent/atomic/AtomicReference.scala b/javalib/src/main/scala/java/util/concurrent/atomic/AtomicReference.scala index 650b1e0c42..9a025f4cd5 100644 --- a/javalib/src/main/scala/java/util/concurrent/atomic/AtomicReference.scala +++ b/javalib/src/main/scala/java/util/concurrent/atomic/AtomicReference.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util.concurrent.atomic class AtomicReference[T <: AnyRef]( diff --git a/javalib/src/main/scala/java/util/concurrent/atomic/AtomicReferenceArray.scala b/javalib/src/main/scala/java/util/concurrent/atomic/AtomicReferenceArray.scala index 04d198d736..1494f8c926 100644 --- a/javalib/src/main/scala/java/util/concurrent/atomic/AtomicReferenceArray.scala +++ b/javalib/src/main/scala/java/util/concurrent/atomic/AtomicReferenceArray.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util.concurrent.atomic class AtomicReferenceArray[E <: AnyRef]( diff --git a/javalib/src/main/scala/java/util/concurrent/locks/Lock.scala b/javalib/src/main/scala/java/util/concurrent/locks/Lock.scala index 340e08166e..448b59bd3b 100644 --- a/javalib/src/main/scala/java/util/concurrent/locks/Lock.scala +++ b/javalib/src/main/scala/java/util/concurrent/locks/Lock.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util.concurrent.locks import java.util.concurrent.TimeUnit diff --git a/javalib/src/main/scala/java/util/concurrent/locks/ReentrantLock.scala b/javalib/src/main/scala/java/util/concurrent/locks/ReentrantLock.scala index 1ae0c62485..3aebcd7d85 100644 --- a/javalib/src/main/scala/java/util/concurrent/locks/ReentrantLock.scala +++ b/javalib/src/main/scala/java/util/concurrent/locks/ReentrantLock.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util.concurrent.locks import java.io.Serializable diff --git a/javalib/src/main/scala/java/util/package.scala b/javalib/src/main/scala/java/util/package.scala index c778fb8804..1e0f26fb56 100644 --- a/javalib/src/main/scala/java/util/package.scala +++ b/javalib/src/main/scala/java/util/package.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java package object util { diff --git a/javalib/src/main/scala/java/util/regex/GroupStartMap.scala b/javalib/src/main/scala/java/util/regex/GroupStartMap.scala index 8d6f2bbee1..1c6287ba7d 100644 --- a/javalib/src/main/scala/java/util/regex/GroupStartMap.scala +++ b/javalib/src/main/scala/java/util/regex/GroupStartMap.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util.regex import scala.annotation.{tailrec, switch} diff --git a/javalib/src/main/scala/java/util/regex/MatchResult.scala b/javalib/src/main/scala/java/util/regex/MatchResult.scala index f321c60be5..55ddf7728d 100644 --- a/javalib/src/main/scala/java/util/regex/MatchResult.scala +++ b/javalib/src/main/scala/java/util/regex/MatchResult.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util.regex trait MatchResult { diff --git a/javalib/src/main/scala/java/util/regex/Matcher.scala b/javalib/src/main/scala/java/util/regex/Matcher.scala index 53f4c3a45d..1f3661bc48 100644 --- a/javalib/src/main/scala/java/util/regex/Matcher.scala +++ b/javalib/src/main/scala/java/util/regex/Matcher.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util.regex import scala.language.implicitConversions diff --git a/javalib/src/main/scala/java/util/regex/Pattern.scala b/javalib/src/main/scala/java/util/regex/Pattern.scala index 308e14b45f..660b80c71d 100644 --- a/javalib/src/main/scala/java/util/regex/Pattern.scala +++ b/javalib/src/main/scala/java/util/regex/Pattern.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package java.util.regex import scala.annotation.switch diff --git a/javalib/src/main/scala/scala/scalajs/js/typedarray/TypedArrayBufferBridge.scala b/javalib/src/main/scala/scala/scalajs/js/typedarray/TypedArrayBufferBridge.scala index 62648e7f98..b8440a4c3a 100644 --- a/javalib/src/main/scala/scala/scalajs/js/typedarray/TypedArrayBufferBridge.scala +++ b/javalib/src/main/scala/scala/scalajs/js/typedarray/TypedArrayBufferBridge.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ /* !!!!! * THIS FILE IS ALMOST COPY-PASTED IN javalib/ AND library/. @@ -28,7 +31,6 @@ * !!!!! */ - package scala.scalajs.js.typedarray import java.nio._ diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/AsyncTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/AsyncTests.scala index acb3830f45..076f90f893 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/AsyncTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/AsyncTests.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv.test import org.scalajs.jsenv._ diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/BasicJSEnvTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/BasicJSEnvTests.scala index 4404f18dbd..46600b8996 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/BasicJSEnvTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/BasicJSEnvTests.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv.test import org.junit.Test diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala index cb6415d482..45125ce2a7 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv.test import org.scalajs.jsenv._ diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/CustomInitFilesTest.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/CustomInitFilesTest.scala index 9e2e5e0b62..be4ae138c2 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/CustomInitFilesTest.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/CustomInitFilesTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv.test import org.scalajs.core.tools.io._ diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvTest.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvTest.scala index e48859924d..ca26440833 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvTest.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/JSEnvTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv.test import org.scalajs.jsenv._ diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/StoreJSConsole.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/StoreJSConsole.scala index f4e60da5a4..0de28ed63f 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/StoreJSConsole.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/StoreJSConsole.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv.test import org.scalajs.jsenv._ diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/StoreLogger.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/StoreLogger.scala index 5d97dc314e..9738c93e89 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/StoreLogger.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/StoreLogger.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv.test import org.scalajs.core.tools.logging._ diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutComTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutComTests.scala index 57c41c0b3d..1c2ce2f797 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutComTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutComTests.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv.test import org.junit.Test diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutTests.scala index 2191ef7a04..cbe6dc9d63 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/TimeoutTests.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv.test import org.junit.Test diff --git a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/JSDOMNodeJSEnvTest.scala b/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/JSDOMNodeJSEnvTest.scala index 5be81d5b8b..a47e41b5b9 100644 --- a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/JSDOMNodeJSEnvTest.scala +++ b/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/JSDOMNodeJSEnvTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv.test import org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv diff --git a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/NodeJSTest.scala b/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/NodeJSTest.scala index 4047286e31..73870a2b93 100644 --- a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/NodeJSTest.scala +++ b/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/NodeJSTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv.test import org.scalajs.jsenv.nodejs.NodeJSEnv diff --git a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/NodeJSWithCustomInitFilesTest.scala b/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/NodeJSWithCustomInitFilesTest.scala index 758a919f39..4ad2c68861 100644 --- a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/NodeJSWithCustomInitFilesTest.scala +++ b/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/NodeJSWithCustomInitFilesTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv.test import org.scalajs.jsenv.nodejs.NodeJSEnv diff --git a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/PhantomJSTest.scala b/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/PhantomJSTest.scala index b4fd37df0f..5736183ac4 100644 --- a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/PhantomJSTest.scala +++ b/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/PhantomJSTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv.test import org.scalajs.jsenv.phantomjs.PhantomJSEnv diff --git a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/PhantomJSWithCustomInitFilesTest.scala b/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/PhantomJSWithCustomInitFilesTest.scala index 8c31699b45..b6f7924b5c 100644 --- a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/PhantomJSWithCustomInitFilesTest.scala +++ b/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/PhantomJSWithCustomInitFilesTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv.test import org.scalajs.jsenv.phantomjs.PhantomJSEnv diff --git a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/RetryingComJSEnvTest.scala b/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/RetryingComJSEnvTest.scala index 2e78424893..2aacb198de 100644 --- a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/RetryingComJSEnvTest.scala +++ b/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/RetryingComJSEnvTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv.test import org.scalajs.core.tools.io.VirtualJSFile diff --git a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/RhinoJSEnvTest.scala b/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/RhinoJSEnvTest.scala index d69a07c53f..c098f64c75 100644 --- a/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/RhinoJSEnvTest.scala +++ b/js-envs-test-suite/src/test/scala/org/scalajs/jsenv/test/RhinoJSEnvTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv.test import org.scalajs.core.tools.sem.Semantics diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSEnv.scala index c0ba9aa93a..08214d23ce 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSEnv.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.jsenv diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSRunner.scala b/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSRunner.scala index 06619bd8e3..14779fb32b 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSRunner.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/AsyncJSRunner.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv import scala.concurrent.{Future, Await} diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/ComJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/ComJSEnv.scala index 52c6dcfaa2..c8688dce0d 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/ComJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/ComJSEnv.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.jsenv diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/ComJSRunner.scala b/js-envs/src/main/scala/org/scalajs/jsenv/ComJSRunner.scala index 66d24d7db8..14954db5f8 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/ComJSRunner.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/ComJSRunner.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv import scala.concurrent.duration.Duration diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/ConsoleJSConsole.scala b/js-envs/src/main/scala/org/scalajs/jsenv/ConsoleJSConsole.scala index 642635049b..4185fe09f6 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/ConsoleJSConsole.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/ConsoleJSConsole.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.jsenv diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala index d24e19777d..d23742ed44 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/ExternalJSEnv.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv import org.scalajs.core.tools.io._ diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/JSConsole.scala b/js-envs/src/main/scala/org/scalajs/jsenv/JSConsole.scala index c671ca1c9c..b7f98b9b61 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/JSConsole.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/JSConsole.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.jsenv diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala index aa6c7a5ba9..52870daa09 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.jsenv diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/JSInitFiles.scala b/js-envs/src/main/scala/org/scalajs/jsenv/JSInitFiles.scala index fad9e12066..7ff78d1ec6 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/JSInitFiles.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/JSInitFiles.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv import org.scalajs.core.tools.io.VirtualJSFile diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/JSRunner.scala b/js-envs/src/main/scala/org/scalajs/jsenv/JSRunner.scala index 7d2b5b6fc2..5c9400e89b 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/JSRunner.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/JSRunner.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.jsenv diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/LinkingUnitAsyncJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/LinkingUnitAsyncJSEnv.scala index dc2219252f..e26ec3f1a4 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/LinkingUnitAsyncJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/LinkingUnitAsyncJSEnv.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.jsenv diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/LinkingUnitComJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/LinkingUnitComJSEnv.scala index dc39bbcb73..5761e0e9ff 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/LinkingUnitComJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/LinkingUnitComJSEnv.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.jsenv diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/LinkingUnitJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/LinkingUnitJSEnv.scala index 6ba33e6697..46020ee7f8 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/LinkingUnitJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/LinkingUnitJSEnv.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.jsenv diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/NullJSConsole.scala b/js-envs/src/main/scala/org/scalajs/jsenv/NullJSConsole.scala index 24b677d974..4dbbcf52ca 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/NullJSConsole.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/NullJSConsole.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv object NullJSConsole extends JSConsole { diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/RetryingComJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/RetryingComJSEnv.scala index 9c879332d4..88fb340cda 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/RetryingComJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/RetryingComJSEnv.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.jsenv diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/Utils.scala b/js-envs/src/main/scala/org/scalajs/jsenv/Utils.scala index b2431b44ad..b2d5ff9d12 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/Utils.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/Utils.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js JS environments ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.jsenv diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/VirtualFileMaterializer.scala b/js-envs/src/main/scala/org/scalajs/jsenv/VirtualFileMaterializer.scala index 1f25a92044..de386666a3 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/VirtualFileMaterializer.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/VirtualFileMaterializer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv import scala.annotation.tailrec diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnv.scala index e696fa4141..ab0caefd09 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/jsdomnodejs/JSDOMNodeJSEnv.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js JS envs ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.jsenv.jsdomnodejs diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala index 8fde820763..39de10fa18 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.jsenv.nodejs diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala index f1c698c7bf..5e334102c0 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/JSDOMNodeJSEnv.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.jsenv.nodejs diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala index 5721647679..99e163ef14 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.jsenv.nodejs diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/JettyWebsocketManager.scala b/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/JettyWebsocketManager.scala index 0d5019fca6..36ef23d9b7 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/JettyWebsocketManager.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/JettyWebsocketManager.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv.phantomjs import javax.servlet.http.HttpServletRequest diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala index 4bb8a9dbbe..18d69c13f4 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJSEnv.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.jsenv.phantomjs diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJettyClassLoader.scala b/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJettyClassLoader.scala index 428279e4c7..3fb0bed497 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJettyClassLoader.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/PhantomJettyClassLoader.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv.phantomjs import org.scalajs.core.tools.io.IO diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketListener.scala b/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketListener.scala index b26dc1dcf9..adcad9a9e2 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketListener.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketListener.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv.phantomjs private[phantomjs] trait WebsocketListener { diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketManager.scala b/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketManager.scala index 875393c070..0f4dd90b7c 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketManager.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/phantomjs/WebsocketManager.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.jsenv.phantomjs private[phantomjs] trait WebsocketManager { diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/LazyScalaJSScope.scala b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/LazyScalaJSScope.scala index e26452631d..11a68efa9b 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/LazyScalaJSScope.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/LazyScalaJSScope.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.jsenv.rhino diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/RhinoJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/RhinoJSEnv.scala index 9ed8d0c6cc..7f34ac6b13 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/RhinoJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/RhinoJSEnv.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.jsenv.rhino diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala index 8da714762c..9cb6f0d50f 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/ScalaJSCoreLib.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.jsenv.rhino diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/package.scala b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/package.scala index 3f67cbd34d..9a5422e07a 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/rhino/package.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/rhino/package.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.jsenv diff --git a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/Compat210Component.scala b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/Compat210Component.scala index ca65d09e1a..ff23b72a44 100644 --- a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/Compat210Component.scala +++ b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/Compat210Component.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit.plugin import scala.reflect.internal.Flags diff --git a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala index a4301c66a9..355903ebe7 100644 --- a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala +++ b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit.plugin import scala.language.reflectiveCalls diff --git a/junit-runtime/src/main/scala/com/novocode/junit/Ansi.scala b/junit-runtime/src/main/scala/com/novocode/junit/Ansi.scala index 3e360dfa9a..c64973659f 100644 --- a/junit-runtime/src/main/scala/com/novocode/junit/Ansi.scala +++ b/junit-runtime/src/main/scala/com/novocode/junit/Ansi.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package com.novocode.junit object Ansi { diff --git a/junit-runtime/src/main/scala/com/novocode/junit/JUnitFramework.scala b/junit-runtime/src/main/scala/com/novocode/junit/JUnitFramework.scala index feb5c4ceeb..2b110922bc 100644 --- a/junit-runtime/src/main/scala/com/novocode/junit/JUnitFramework.scala +++ b/junit-runtime/src/main/scala/com/novocode/junit/JUnitFramework.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package com.novocode.junit import org.scalajs.junit.{JUnitMasterRunner, JUnitSlaveRunner} diff --git a/junit-runtime/src/main/scala/com/novocode/junit/RichLogger.scala b/junit-runtime/src/main/scala/com/novocode/junit/RichLogger.scala index 3d6612b2e8..b6cec79069 100644 --- a/junit-runtime/src/main/scala/com/novocode/junit/RichLogger.scala +++ b/junit-runtime/src/main/scala/com/novocode/junit/RichLogger.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package com.novocode.junit import sbt.testing._ diff --git a/junit-runtime/src/main/scala/com/novocode/junit/RunSettings.scala b/junit-runtime/src/main/scala/com/novocode/junit/RunSettings.scala index 19974ea756..2b6cb6f796 100644 --- a/junit-runtime/src/main/scala/com/novocode/junit/RunSettings.scala +++ b/junit-runtime/src/main/scala/com/novocode/junit/RunSettings.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package com.novocode.junit import com.novocode.junit.Ansi._ diff --git a/junit-runtime/src/main/scala/org/hamcrest/LICENSE-hamcrest.txt b/junit-runtime/src/main/scala/org/hamcrest/LICENSE-hamcrest.txt new file mode 100644 index 0000000000..dcdcc42347 --- /dev/null +++ b/junit-runtime/src/main/scala/org/hamcrest/LICENSE-hamcrest.txt @@ -0,0 +1,27 @@ +BSD License + +Copyright (c) 2000-2006, www.hamcrest.org +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of +conditions and the following disclaimer. Redistributions in binary form must reproduce +the above copyright notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the distribution. + +Neither the name of Hamcrest nor the names of its contributors may be used to endorse +or promote products derived from this software without specific prior written +permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY +WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitBaseRunner.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitBaseRunner.scala index d98f213ad0..5d47de28c6 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitBaseRunner.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitBaseRunner.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import com.novocode.junit.RunSettings diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitEvent.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitEvent.scala index eaaad30fcd..d221c2b586 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitEvent.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitEvent.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import sbt.testing._ diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala index be17f6643c..59fd68f086 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import java.io.ByteArrayOutputStream diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitMasterRunner.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitMasterRunner.scala index 1b0e39dfd0..f75f26cc13 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitMasterRunner.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitMasterRunner.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import com.novocode.junit.RunSettings diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitSlaveRunner.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitSlaveRunner.scala index cef385b59a..7f389f235d 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitSlaveRunner.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitSlaveRunner.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import com.novocode.junit.RunSettings diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTask.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTask.scala index f087bcfef2..2ad9e97d7e 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTask.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTask.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import com.novocode.junit.{Ansi, RichLogger} diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTestBootstrapper.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTestBootstrapper.scala index 092e4d15b9..d61b22c9dc 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTestBootstrapper.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTestBootstrapper.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import java.lang.annotation.Annotation diff --git a/junit-test/output-js/src/test/scala/org/scalajs/junit/utils/JUnitTestPlatformImpl.scala b/junit-test/output-js/src/test/scala/org/scalajs/junit/utils/JUnitTestPlatformImpl.scala index 80f4a0c895..0e9cb2d924 100644 --- a/junit-test/output-js/src/test/scala/org/scalajs/junit/utils/JUnitTestPlatformImpl.scala +++ b/junit-test/output-js/src/test/scala/org/scalajs/junit/utils/JUnitTestPlatformImpl.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit.utils import sbt.testing._ diff --git a/junit-test/output-jvm/src/test/scala/org/scalajs/junit/utils/JUnitTestPlatformImpl.scala b/junit-test/output-jvm/src/test/scala/org/scalajs/junit/utils/JUnitTestPlatformImpl.scala index bcbedb7b30..f6c2fdcdd3 100644 --- a/junit-test/output-jvm/src/test/scala/org/scalajs/junit/utils/JUnitTestPlatformImpl.scala +++ b/junit-test/output-jvm/src/test/scala/org/scalajs/junit/utils/JUnitTestPlatformImpl.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit.utils import sbt.testing._ diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertEquals2Test.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertEquals2Test.scala index d398323889..e26dac7901 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertEquals2Test.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertEquals2Test.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import org.junit.Assert._ diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertEqualsDoubleTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertEqualsDoubleTest.scala index 13892ce90b..e5ece56b33 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertEqualsDoubleTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertEqualsDoubleTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import org.junit.Assert._ diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertEqualsTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertEqualsTest.scala index 5683609d3c..ab0f9801ae 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertEqualsTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertEqualsTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import org.junit.Assert._ diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertFalse2Test.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertFalse2Test.scala index 1b0b80efda..be72765923 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertFalse2Test.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertFalse2Test.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import org.junit.Assert._ diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertFalseTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertFalseTest.scala index 41b7bf2b4b..0943af0db0 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertFalseTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertFalseTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import org.junit.Assert._ diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertStringEqualsTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertStringEqualsTest.scala index 89aa58c812..373dd78ceb 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertStringEqualsTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertStringEqualsTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import org.junit.Assert._ diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertTrueTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertTrueTest.scala index d5ea148111..1a17330648 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/AssertTrueTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/AssertTrueTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import org.junit.Assert._ diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/AssumeTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/AssumeTest.scala index 889c75fe44..b39f0d6893 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/AssumeTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/AssumeTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import org.junit.Assume._ diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/BeforeAndAfterTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/BeforeAndAfterTest.scala index e5ff0e147f..79b34a7732 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/BeforeAndAfterTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/BeforeAndAfterTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import org.junit._ diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/BeforeAssumeFailTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/BeforeAssumeFailTest.scala index a6e3aba16a..6849e1ffa7 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/BeforeAssumeFailTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/BeforeAssumeFailTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import org.junit.Assume._ diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInAfterTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInAfterTest.scala index e696f6dbc1..c988d040d5 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInAfterTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInAfterTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import org.junit._ diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInBeforeTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInBeforeTest.scala index 5df39a9c87..ce92c6859f 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInBeforeTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInBeforeTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import org.junit._ diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInConstructorTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInConstructorTest.scala index 57fac783bb..9d17bfa4c0 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInConstructorTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionInConstructorTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import org.junit._ diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionTest.scala index 7f296d8d42..6f37aeb14d 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import org.junit.Test diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/IgnoreTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/IgnoreTest.scala index 5827ad4108..d4e4f5cb6a 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/IgnoreTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/IgnoreTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import org.junit._ diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/MethodNameDecodeTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/MethodNameDecodeTest.scala index 812b2e97e5..33ee308a74 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/MethodNameDecodeTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/MethodNameDecodeTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import org.junit.Test diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/Multi1Test.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/Multi1Test.scala index 0c9f2e2fb8..8515b95b77 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/Multi1Test.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/Multi1Test.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import org.junit.Test diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/Multi2Test.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/Multi2Test.scala index e6c4b95ce8..5118c2ad44 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/Multi2Test.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/Multi2Test.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import org.junit.Test diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiAssumeFail1Test.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiAssumeFail1Test.scala index 3ea020ff62..62296744c2 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiAssumeFail1Test.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiAssumeFail1Test.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import org.junit.Assume._ diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiAssumeFail2Test.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiAssumeFail2Test.scala index d9d2da82e6..ae2a7fdc8f 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiAssumeFail2Test.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiAssumeFail2Test.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import org.junit.Assume._ diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiBeforeAssumeFailTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiBeforeAssumeFailTest.scala index 413297485a..fe8e5de9a4 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiBeforeAssumeFailTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiBeforeAssumeFailTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import org.junit.Assume._ diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiIgnore1Test.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiIgnore1Test.scala index a083ac9f0a..eef8f24243 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiIgnore1Test.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiIgnore1Test.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import org.junit._ diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiIgnore2Test.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiIgnore2Test.scala index 28580e04a7..7f1cc50c91 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiIgnore2Test.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiIgnore2Test.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import org.junit._ diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiIgnoreAllTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiIgnoreAllTest.scala index 90b6a9a3c3..4477431b8f 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/MultiIgnoreAllTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/MultiIgnoreAllTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit import org.junit._ diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala index 6fdd894100..c3c3722195 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.junit.utils import sbt.testing._ diff --git a/library-aux/src/main/scala/scala/runtime/ArrayRuntime.scala b/library-aux/src/main/scala/scala/runtime/ArrayRuntime.scala index ceda199e89..ae7ac8a35e 100644 --- a/library-aux/src/main/scala/scala/runtime/ArrayRuntime.scala +++ b/library-aux/src/main/scala/scala/runtime/ArrayRuntime.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.runtime /** Not for public consumption. Usage by the runtime only. diff --git a/library-aux/src/main/scala/scala/runtime/BoxedUnit.scala b/library-aux/src/main/scala/scala/runtime/BoxedUnit.scala index 1c53c2557e..c6e1b6b9be 100644 --- a/library-aux/src/main/scala/scala/runtime/BoxedUnit.scala +++ b/library-aux/src/main/scala/scala/runtime/BoxedUnit.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.runtime /* This is a hijacked class. Its only instance is the value 'undefined'. diff --git a/library-aux/src/main/scala/scala/runtime/RefTypes.scala b/library-aux/src/main/scala/scala/runtime/RefTypes.scala index 4724d13640..e7a6602c8b 100644 --- a/library-aux/src/main/scala/scala/runtime/RefTypes.scala +++ b/library-aux/src/main/scala/scala/runtime/RefTypes.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.runtime import java.io.Serializable diff --git a/library-aux/src/main/scala/scala/runtime/Statics.scala b/library-aux/src/main/scala/scala/runtime/Statics.scala index f9c62f640c..8aa2a44328 100644 --- a/library-aux/src/main/scala/scala/runtime/Statics.scala +++ b/library-aux/src/main/scala/scala/runtime/Statics.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.runtime /** Not for public consumption. Usage by the runtime only. diff --git a/library/src/main/scala-m4-collections/scala/scalajs/js/Any.scala b/library/src/main/scala-m4-collections/scala/scalajs/js/Any.scala index f94d07ed0c..ea7d303a84 100644 --- a/library/src/main/scala-m4-collections/scala/scalajs/js/Any.scala +++ b/library/src/main/scala-m4-collections/scala/scalajs/js/Any.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ /** * All doc-comments marked as "MDN" are by Mozilla Contributors, diff --git a/library/src/main/scala-m4-collections/scala/scalajs/js/ArrayOps.scala b/library/src/main/scala-m4-collections/scala/scalajs/js/ArrayOps.scala index 9ad52d162c..52702a1a57 100644 --- a/library/src/main/scala-m4-collections/scala/scalajs/js/ArrayOps.scala +++ b/library/src/main/scala-m4-collections/scala/scalajs/js/ArrayOps.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2018, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala-m4-collections/scala/scalajs/js/JSConverters.scala b/library/src/main/scala-m4-collections/scala/scalajs/js/JSConverters.scala index eb1f5a7989..130cbef894 100644 --- a/library/src/main/scala-m4-collections/scala/scalajs/js/JSConverters.scala +++ b/library/src/main/scala-m4-collections/scala/scalajs/js/JSConverters.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala-m4-collections/scala/scalajs/js/WrappedArray.scala b/library/src/main/scala-m4-collections/scala/scalajs/js/WrappedArray.scala index 17fda60ae6..ba2aa6234b 100644 --- a/library/src/main/scala-m4-collections/scala/scalajs/js/WrappedArray.scala +++ b/library/src/main/scala-m4-collections/scala/scalajs/js/WrappedArray.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala-m4-collections/scala/scalajs/js/WrappedDictionary.scala b/library/src/main/scala-m4-collections/scala/scalajs/js/WrappedDictionary.scala index ffb6c67443..4e2159823d 100644 --- a/library/src/main/scala-m4-collections/scala/scalajs/js/WrappedDictionary.scala +++ b/library/src/main/scala-m4-collections/scala/scalajs/js/WrappedDictionary.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala-m4-collections/scala/scalajs/runtime/Compat.scala b/library/src/main/scala-m4-collections/scala/scalajs/runtime/Compat.scala index fdd82cc41f..f21f19d82f 100644 --- a/library/src/main/scala-m4-collections/scala/scalajs/runtime/Compat.scala +++ b/library/src/main/scala-m4-collections/scala/scalajs/runtime/Compat.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.runtime import scala.collection.IterableOnce diff --git a/library/src/main/scala-m4-collections/scala/scalajs/runtime/WrappedVarArgs.scala b/library/src/main/scala-m4-collections/scala/scalajs/runtime/WrappedVarArgs.scala index 044f521f5e..ad89a21da8 100644 --- a/library/src/main/scala-m4-collections/scala/scalajs/runtime/WrappedVarArgs.scala +++ b/library/src/main/scala-m4-collections/scala/scalajs/runtime/WrappedVarArgs.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.runtime import scala.collection.immutable diff --git a/library/src/main/scala-new-collections/scala/scalajs/js/Any.scala b/library/src/main/scala-new-collections/scala/scalajs/js/Any.scala index 56d2af60f9..bbfdc7fb37 100644 --- a/library/src/main/scala-new-collections/scala/scalajs/js/Any.scala +++ b/library/src/main/scala-new-collections/scala/scalajs/js/Any.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ /** * All doc-comments marked as "MDN" are by Mozilla Contributors, diff --git a/library/src/main/scala-new-collections/scala/scalajs/js/ArrayOps.scala b/library/src/main/scala-new-collections/scala/scalajs/js/ArrayOps.scala index 3e52a8806d..3032058bce 100644 --- a/library/src/main/scala-new-collections/scala/scalajs/js/ArrayOps.scala +++ b/library/src/main/scala-new-collections/scala/scalajs/js/ArrayOps.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2018, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala-new-collections/scala/scalajs/js/JSConverters.scala b/library/src/main/scala-new-collections/scala/scalajs/js/JSConverters.scala index c8eefd42db..15a8ad1c31 100644 --- a/library/src/main/scala-new-collections/scala/scalajs/js/JSConverters.scala +++ b/library/src/main/scala-new-collections/scala/scalajs/js/JSConverters.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala-new-collections/scala/scalajs/js/WrappedArray.scala b/library/src/main/scala-new-collections/scala/scalajs/js/WrappedArray.scala index 8043aec310..35f4a7a33f 100644 --- a/library/src/main/scala-new-collections/scala/scalajs/js/WrappedArray.scala +++ b/library/src/main/scala-new-collections/scala/scalajs/js/WrappedArray.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala-new-collections/scala/scalajs/js/WrappedDictionary.scala b/library/src/main/scala-new-collections/scala/scalajs/js/WrappedDictionary.scala index d1925ba002..ceecfa3ea1 100644 --- a/library/src/main/scala-new-collections/scala/scalajs/js/WrappedDictionary.scala +++ b/library/src/main/scala-new-collections/scala/scalajs/js/WrappedDictionary.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala-new-collections/scala/scalajs/runtime/Compat.scala b/library/src/main/scala-new-collections/scala/scalajs/runtime/Compat.scala index 5a3d0d4fa8..50af5d0e6e 100644 --- a/library/src/main/scala-new-collections/scala/scalajs/runtime/Compat.scala +++ b/library/src/main/scala-new-collections/scala/scalajs/runtime/Compat.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.runtime import scala.collection.IterableOnce diff --git a/library/src/main/scala-new-collections/scala/scalajs/runtime/WrappedVarArgs.scala b/library/src/main/scala-new-collections/scala/scalajs/runtime/WrappedVarArgs.scala index 044f521f5e..ad89a21da8 100644 --- a/library/src/main/scala-new-collections/scala/scalajs/runtime/WrappedVarArgs.scala +++ b/library/src/main/scala-new-collections/scala/scalajs/runtime/WrappedVarArgs.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.runtime import scala.collection.immutable diff --git a/library/src/main/scala-old-collections/scala/scalajs/js/Any.scala b/library/src/main/scala-old-collections/scala/scalajs/js/Any.scala index 45ea692756..6a9d0b3236 100644 --- a/library/src/main/scala-old-collections/scala/scalajs/js/Any.scala +++ b/library/src/main/scala-old-collections/scala/scalajs/js/Any.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ /** * All doc-comments marked as "MDN" are by Mozilla Contributors, diff --git a/library/src/main/scala-old-collections/scala/scalajs/js/ArrayOps.scala b/library/src/main/scala-old-collections/scala/scalajs/js/ArrayOps.scala index f5cad74030..b01f6bdd70 100644 --- a/library/src/main/scala-old-collections/scala/scalajs/js/ArrayOps.scala +++ b/library/src/main/scala-old-collections/scala/scalajs/js/ArrayOps.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala-old-collections/scala/scalajs/js/JSConverters.scala b/library/src/main/scala-old-collections/scala/scalajs/js/JSConverters.scala index 9acd65d01e..8432ba6c9b 100644 --- a/library/src/main/scala-old-collections/scala/scalajs/js/JSConverters.scala +++ b/library/src/main/scala-old-collections/scala/scalajs/js/JSConverters.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala-old-collections/scala/scalajs/js/WrappedArray.scala b/library/src/main/scala-old-collections/scala/scalajs/js/WrappedArray.scala index 34dc13b4d1..59cff50711 100644 --- a/library/src/main/scala-old-collections/scala/scalajs/js/WrappedArray.scala +++ b/library/src/main/scala-old-collections/scala/scalajs/js/WrappedArray.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala-old-collections/scala/scalajs/js/WrappedDictionary.scala b/library/src/main/scala-old-collections/scala/scalajs/js/WrappedDictionary.scala index a38ec7ccea..fb34d086bb 100644 --- a/library/src/main/scala-old-collections/scala/scalajs/js/WrappedDictionary.scala +++ b/library/src/main/scala-old-collections/scala/scalajs/js/WrappedDictionary.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala-old-collections/scala/scalajs/runtime/Compat.scala b/library/src/main/scala-old-collections/scala/scalajs/runtime/Compat.scala index 14ba7868c7..b6e08d35c6 100644 --- a/library/src/main/scala-old-collections/scala/scalajs/runtime/Compat.scala +++ b/library/src/main/scala-old-collections/scala/scalajs/runtime/Compat.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.runtime import scala.collection.GenTraversableOnce diff --git a/library/src/main/scala/scala/scalajs/LinkingInfo.scala b/library/src/main/scala/scala/scalajs/LinkingInfo.scala index d14080b2ea..5b646de801 100644 --- a/library/src/main/scala/scala/scalajs/LinkingInfo.scala +++ b/library/src/main/scala/scala/scalajs/LinkingInfo.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs diff --git a/library/src/main/scala/scala/scalajs/concurrent/JSExecutionContext.scala b/library/src/main/scala/scala/scalajs/concurrent/JSExecutionContext.scala index ee5a1f592b..c40e8464fd 100644 --- a/library/src/main/scala/scala/scalajs/concurrent/JSExecutionContext.scala +++ b/library/src/main/scala/scala/scalajs/concurrent/JSExecutionContext.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.concurrent import scala.concurrent.ExecutionContextExecutor diff --git a/library/src/main/scala/scala/scalajs/concurrent/QueueExecutionContext.scala b/library/src/main/scala/scala/scalajs/concurrent/QueueExecutionContext.scala index f3ea14edc6..a4ef4ad125 100644 --- a/library/src/main/scala/scala/scalajs/concurrent/QueueExecutionContext.scala +++ b/library/src/main/scala/scala/scalajs/concurrent/QueueExecutionContext.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.concurrent import scala.concurrent.ExecutionContextExecutor diff --git a/library/src/main/scala/scala/scalajs/concurrent/RunNowExcecutionContext.scala b/library/src/main/scala/scala/scalajs/concurrent/RunNowExcecutionContext.scala index ff793f22c9..2f514befac 100644 --- a/library/src/main/scala/scala/scalajs/concurrent/RunNowExcecutionContext.scala +++ b/library/src/main/scala/scala/scalajs/concurrent/RunNowExcecutionContext.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.concurrent import scala.concurrent.ExecutionContextExecutor diff --git a/library/src/main/scala/scala/scalajs/js/Array.scala b/library/src/main/scala/scala/scalajs/js/Array.scala index 56c9fa25ae..df60a1f84f 100644 --- a/library/src/main/scala/scala/scalajs/js/Array.scala +++ b/library/src/main/scala/scala/scalajs/js/Array.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ /** * All doc-comments marked as "MDN" are by Mozilla Contributors, diff --git a/library/src/main/scala/scala/scalajs/js/ArrayOpsCommon.scala b/library/src/main/scala/scala/scalajs/js/ArrayOpsCommon.scala index bd75b685e0..d717035d7a 100644 --- a/library/src/main/scala/scala/scalajs/js/ArrayOpsCommon.scala +++ b/library/src/main/scala/scala/scalajs/js/ArrayOpsCommon.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2018, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/ConstructorTag.scala b/library/src/main/scala/scala/scalajs/js/ConstructorTag.scala index f4f8c51427..6c70786d49 100644 --- a/library/src/main/scala/scala/scalajs/js/ConstructorTag.scala +++ b/library/src/main/scala/scala/scalajs/js/ConstructorTag.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/Date.scala b/library/src/main/scala/scala/scalajs/js/Date.scala index fbd7c09b70..32f4b11416 100644 --- a/library/src/main/scala/scala/scalajs/js/Date.scala +++ b/library/src/main/scala/scala/scalajs/js/Date.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ /** * All doc-comments marked as "MDN" are by Mozilla Contributors, diff --git a/library/src/main/scala/scala/scalajs/js/Dictionary.scala b/library/src/main/scala/scala/scalajs/js/Dictionary.scala index 821108abd9..cb49db45ee 100644 --- a/library/src/main/scala/scala/scalajs/js/Dictionary.scala +++ b/library/src/main/scala/scala/scalajs/js/Dictionary.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ /** * All doc-comments marked as "MDN" are by Mozilla Contributors, diff --git a/library/src/main/scala/scala/scalajs/js/Dynamic.scala b/library/src/main/scala/scala/scalajs/js/Dynamic.scala index e3742687f2..6329734460 100644 --- a/library/src/main/scala/scala/scalajs/js/Dynamic.scala +++ b/library/src/main/scala/scala/scalajs/js/Dynamic.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ /** * All doc-comments marked as "MDN" are by Mozilla Contributors, diff --git a/library/src/main/scala/scala/scalajs/js/DynamicImplicits.scala b/library/src/main/scala/scala/scalajs/js/DynamicImplicits.scala index 3e69b6d838..188a23fdfd 100644 --- a/library/src/main/scala/scala/scalajs/js/DynamicImplicits.scala +++ b/library/src/main/scala/scala/scalajs/js/DynamicImplicits.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/Error.scala b/library/src/main/scala/scala/scalajs/js/Error.scala index f3f6e09c94..618f77b307 100644 --- a/library/src/main/scala/scala/scalajs/js/Error.scala +++ b/library/src/main/scala/scala/scalajs/js/Error.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ /** * All doc-comments marked as "MDN" are by Mozilla Contributors, diff --git a/library/src/main/scala/scala/scalajs/js/Function.nodoc.scala b/library/src/main/scala/scala/scalajs/js/Function.nodoc.scala index 577d5ee300..6040f27bfa 100644 --- a/library/src/main/scala/scala/scalajs/js/Function.nodoc.scala +++ b/library/src/main/scala/scala/scalajs/js/Function.nodoc.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ /* Definitions for js.Function3 to js.Function22 that do not show in doc */ package scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/Function.scala b/library/src/main/scala/scala/scalajs/js/Function.scala index 3d6e4fec56..af015ee5d8 100644 --- a/library/src/main/scala/scala/scalajs/js/Function.scala +++ b/library/src/main/scala/scala/scalajs/js/Function.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ /** * All doc-comments marked as "MDN" are by Mozilla Contributors, diff --git a/library/src/main/scala/scala/scalajs/js/GlobalScope.scala b/library/src/main/scala/scala/scalajs/js/GlobalScope.scala index d077409d83..c74d7f0c31 100644 --- a/library/src/main/scala/scala/scalajs/js/GlobalScope.scala +++ b/library/src/main/scala/scala/scalajs/js/GlobalScope.scala @@ -1,12 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/Iterable.scala b/library/src/main/scala/scala/scalajs/js/Iterable.scala index 97a898cda0..a2140f38b2 100644 --- a/library/src/main/scala/scala/scalajs/js/Iterable.scala +++ b/library/src/main/scala/scala/scalajs/js/Iterable.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/IterableOps.scala b/library/src/main/scala/scala/scalajs/js/IterableOps.scala index 37b9a79fb0..42a3b8ece0 100644 --- a/library/src/main/scala/scala/scalajs/js/IterableOps.scala +++ b/library/src/main/scala/scala/scalajs/js/IterableOps.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/Iterator.scala b/library/src/main/scala/scala/scalajs/js/Iterator.scala index 086202fcdb..6d190ab18f 100644 --- a/library/src/main/scala/scala/scalajs/js/Iterator.scala +++ b/library/src/main/scala/scala/scalajs/js/Iterator.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/JSApp.scala b/library/src/main/scala/scala/scalajs/js/JSApp.scala index c529863189..3b82df662f 100644 --- a/library/src/main/scala/scala/scalajs/js/JSApp.scala +++ b/library/src/main/scala/scala/scalajs/js/JSApp.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.js import annotation.{JSExport, JSExportDescendentObjects} diff --git a/library/src/main/scala/scala/scalajs/js/JSArrayOps.scala b/library/src/main/scala/scala/scalajs/js/JSArrayOps.scala index 59e02627c7..10b8b2d8e8 100644 --- a/library/src/main/scala/scala/scalajs/js/JSArrayOps.scala +++ b/library/src/main/scala/scala/scalajs/js/JSArrayOps.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ /** * All doc-comments marked as "MDN" are by Mozilla Contributors, diff --git a/library/src/main/scala/scala/scalajs/js/JSNumberOps.scala b/library/src/main/scala/scala/scalajs/js/JSNumberOps.scala index f694a7066a..17332ed72a 100644 --- a/library/src/main/scala/scala/scalajs/js/JSNumberOps.scala +++ b/library/src/main/scala/scala/scalajs/js/JSNumberOps.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ /** * All doc-comments marked as "MDN" are by Mozilla Contributors, diff --git a/library/src/main/scala/scala/scalajs/js/JSON.scala b/library/src/main/scala/scala/scalajs/js/JSON.scala index 2578b84609..7d9c0361f7 100644 --- a/library/src/main/scala/scala/scalajs/js/JSON.scala +++ b/library/src/main/scala/scala/scalajs/js/JSON.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ /** * All doc-comments marked as "MDN" are by Mozilla Contributors, diff --git a/library/src/main/scala/scala/scalajs/js/JSStringOps.scala b/library/src/main/scala/scala/scalajs/js/JSStringOps.scala index e7eace5c57..39ab658aa3 100644 --- a/library/src/main/scala/scala/scalajs/js/JSStringOps.scala +++ b/library/src/main/scala/scala/scalajs/js/JSStringOps.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ /** * All doc-comments marked as "MDN" are by Mozilla Contributors, diff --git a/library/src/main/scala/scala/scalajs/js/JavaScriptException.scala b/library/src/main/scala/scala/scalajs/js/JavaScriptException.scala index 2995efc5ea..9e6e80f7aa 100644 --- a/library/src/main/scala/scala/scalajs/js/JavaScriptException.scala +++ b/library/src/main/scala/scala/scalajs/js/JavaScriptException.scala @@ -1,12 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/Math.scala b/library/src/main/scala/scala/scalajs/js/Math.scala index db9f06b2e7..82f8739350 100644 --- a/library/src/main/scala/scala/scalajs/js/Math.scala +++ b/library/src/main/scala/scala/scalajs/js/Math.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ /** * All doc-comments marked as "MDN" are by Mozilla Contributors, diff --git a/library/src/main/scala/scala/scalajs/js/Object.scala b/library/src/main/scala/scala/scalajs/js/Object.scala index 0fd670439e..9c4fd2a4cf 100644 --- a/library/src/main/scala/scala/scalajs/js/Object.scala +++ b/library/src/main/scala/scala/scalajs/js/Object.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ /** * All doc-comments marked as "MDN" are by Mozilla Contributors, diff --git a/library/src/main/scala/scala/scalajs/js/Promise.scala b/library/src/main/scala/scala/scalajs/js/Promise.scala index e016e35a14..65ab2c75ae 100644 --- a/library/src/main/scala/scala/scalajs/js/Promise.scala +++ b/library/src/main/scala/scala/scalajs/js/Promise.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/PropertyDescriptor.scala b/library/src/main/scala/scala/scalajs/js/PropertyDescriptor.scala index 676ddef976..3b5ad81e76 100644 --- a/library/src/main/scala/scala/scalajs/js/PropertyDescriptor.scala +++ b/library/src/main/scala/scala/scalajs/js/PropertyDescriptor.scala @@ -1,12 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/RegExp.scala b/library/src/main/scala/scala/scalajs/js/RegExp.scala index 3a9281465a..7a079937e1 100644 --- a/library/src/main/scala/scala/scalajs/js/RegExp.scala +++ b/library/src/main/scala/scala/scalajs/js/RegExp.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ /** * All doc-comments marked as "MDN" are by Mozilla Contributors, diff --git a/library/src/main/scala/scala/scalajs/js/Symbol.scala b/library/src/main/scala/scala/scalajs/js/Symbol.scala index c6a8a8bd9f..90891d9116 100644 --- a/library/src/main/scala/scala/scalajs/js/Symbol.scala +++ b/library/src/main/scala/scala/scalajs/js/Symbol.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/Thenable.scala b/library/src/main/scala/scala/scalajs/js/Thenable.scala index 8736ecfd17..df52fe18a7 100644 --- a/library/src/main/scala/scala/scalajs/js/Thenable.scala +++ b/library/src/main/scala/scala/scalajs/js/Thenable.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/ThisFunction.nodoc.scala b/library/src/main/scala/scala/scalajs/js/ThisFunction.nodoc.scala index 2dbc8d2941..636fa22525 100644 --- a/library/src/main/scala/scala/scalajs/js/ThisFunction.nodoc.scala +++ b/library/src/main/scala/scala/scalajs/js/ThisFunction.nodoc.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ /* Definitions for js.ThisFunction3 to js.ThisFunction22 that do not show in doc */ package scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/ThisFunction.scala b/library/src/main/scala/scala/scalajs/js/ThisFunction.scala index ad7532a29f..e23372f358 100644 --- a/library/src/main/scala/scala/scalajs/js/ThisFunction.scala +++ b/library/src/main/scala/scala/scalajs/js/ThisFunction.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ /** * All doc-comments marked as "MDN" are by Mozilla Contributors, diff --git a/library/src/main/scala/scala/scalajs/js/Tuple.nodoc.scala b/library/src/main/scala/scala/scalajs/js/Tuple.nodoc.scala index 89a79da575..ba95605fcc 100644 --- a/library/src/main/scala/scala/scalajs/js/Tuple.nodoc.scala +++ b/library/src/main/scala/scala/scalajs/js/Tuple.nodoc.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ /* Definitions for js.Tuple4 to js.Tuple22 that do not show in doc */ package scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/Tuple.scala b/library/src/main/scala/scala/scalajs/js/Tuple.scala index 255c294eea..76464cd5a7 100644 --- a/library/src/main/scala/scala/scalajs/js/Tuple.scala +++ b/library/src/main/scala/scala/scalajs/js/Tuple.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ /** * All doc-comments marked as "MDN" are by Mozilla Contributors, diff --git a/library/src/main/scala/scala/scalajs/js/URIUtils.scala b/library/src/main/scala/scala/scalajs/js/URIUtils.scala index ec102a3162..4eb56823d7 100644 --- a/library/src/main/scala/scala/scalajs/js/URIUtils.scala +++ b/library/src/main/scala/scala/scalajs/js/URIUtils.scala @@ -1,12 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/UndefOr.scala b/library/src/main/scala/scala/scalajs/js/UndefOr.scala index fcf421bcf4..14cbbbd6f4 100644 --- a/library/src/main/scala/scala/scalajs/js/UndefOr.scala +++ b/library/src/main/scala/scala/scalajs/js/UndefOr.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/UnicodeNormalizationForm.scala b/library/src/main/scala/scala/scalajs/js/UnicodeNormalizationForm.scala index 7770e36d69..1d343982b2 100644 --- a/library/src/main/scala/scala/scalajs/js/UnicodeNormalizationForm.scala +++ b/library/src/main/scala/scala/scalajs/js/UnicodeNormalizationForm.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ /* All doc-comments marked as "MDN" are by Mozilla Contributors, * distributed under the Creative Commons Attribution-ShareAlike license from diff --git a/library/src/main/scala/scala/scalajs/js/Union.scala b/library/src/main/scala/scala/scalajs/js/Union.scala index ad8479105b..8f72abb736 100644 --- a/library/src/main/scala/scala/scalajs/js/Union.scala +++ b/library/src/main/scala/scala/scalajs/js/Union.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/Using.scala b/library/src/main/scala/scala/scalajs/js/Using.scala index cc787ce067..0baac10872 100644 --- a/library/src/main/scala/scala/scalajs/js/Using.scala +++ b/library/src/main/scala/scala/scalajs/js/Using.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/annotation/ExposedJSMember.scala b/library/src/main/scala/scala/scalajs/js/annotation/ExposedJSMember.scala index da830cfad7..9a693122cf 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/ExposedJSMember.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/ExposedJSMember.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.annotation diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSBracketAccess.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSBracketAccess.scala index 596e327a87..2ba7620e0d 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSBracketAccess.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSBracketAccess.scala @@ -1,12 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.annotation diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSBracketCall.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSBracketCall.scala index 93d8312704..c8a3d9e124 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSBracketCall.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSBracketCall.scala @@ -1,12 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.annotation diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSExport.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSExport.scala index c061e60dd6..0a89e23f1f 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSExport.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSExport.scala @@ -1,12 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.annotation diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSExportAll.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSExportAll.scala index 817459564e..1e0ec32910 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSExportAll.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSExportAll.scala @@ -1,12 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.annotation diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSExportDescendentClasses.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSExportDescendentClasses.scala index 297ec78c59..b5737d2d13 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSExportDescendentClasses.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSExportDescendentClasses.scala @@ -1,12 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.annotation diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSExportDescendentObjects.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSExportDescendentObjects.scala index 6932e5f433..30ace34efe 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSExportDescendentObjects.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSExportDescendentObjects.scala @@ -1,12 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.annotation diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSExportNamed.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSExportNamed.scala index bb91787f62..808a655929 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSExportNamed.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSExportNamed.scala @@ -1,12 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.annotation diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSExportStatic.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSExportStatic.scala index 8af0820b4a..aaf6e7c600 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSExportStatic.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSExportStatic.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.annotation diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSExportTopLevel.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSExportTopLevel.scala index f6a04043e4..22b810c45d 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSExportTopLevel.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSExportTopLevel.scala @@ -1,12 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.annotation diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSFullName.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSFullName.scala index 8005276033..8d6f0ec797 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSFullName.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSFullName.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.annotation diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSGlobal.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSGlobal.scala index 7ed693109c..e315bade93 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSGlobal.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSGlobal.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.annotation diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSGlobalScope.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSGlobalScope.scala index 22eb8d4ec3..d23aef7e3c 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSGlobalScope.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSGlobalScope.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.annotation diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSImport.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSImport.scala index d75b99b691..2cb7c991b1 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSImport.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSImport.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.annotation diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSName.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSName.scala index 925c522a05..9bc58689de 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSName.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSName.scala @@ -1,12 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.annotation diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JavaDefaultMethod.scala b/library/src/main/scala/scala/scalajs/js/annotation/JavaDefaultMethod.scala index cbc150f772..db1474fd4e 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/JavaDefaultMethod.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/JavaDefaultMethod.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.annotation diff --git a/library/src/main/scala/scala/scalajs/js/annotation/RawJSType.scala b/library/src/main/scala/scala/scalajs/js/annotation/RawJSType.scala index a5bb77169c..78e8657d5d 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/RawJSType.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/RawJSType.scala @@ -1,12 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.annotation diff --git a/library/src/main/scala/scala/scalajs/js/annotation/SJSDefinedAnonymousClass.scala b/library/src/main/scala/scala/scalajs/js/annotation/SJSDefinedAnonymousClass.scala index dfda86c554..d6634efde3 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/SJSDefinedAnonymousClass.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/SJSDefinedAnonymousClass.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.js.annotation /** IMPLEMENTATION DETAIL: Marks anonymous Scala.js-defined JS classes. diff --git a/library/src/main/scala/scala/scalajs/js/annotation/ScalaJSDefined.scala b/library/src/main/scala/scala/scalajs/js/annotation/ScalaJSDefined.scala index 9387b90d92..d9f7adcf7b 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/ScalaJSDefined.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/ScalaJSDefined.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.annotation diff --git a/library/src/main/scala/scala/scalajs/js/annotation/WasPublicBeforeTyper.scala b/library/src/main/scala/scala/scalajs/js/annotation/WasPublicBeforeTyper.scala index 5fbe18b0a2..cd65cff82a 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/WasPublicBeforeTyper.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/WasPublicBeforeTyper.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.js.annotation /** IMPLEMENTATION DETAIL: Marks public members of anonymous classes before typer. diff --git a/library/src/main/scala/scala/scalajs/js/annotation/internal/HasJSNativeLoadSpec.scala b/library/src/main/scala/scala/scalajs/js/annotation/internal/HasJSNativeLoadSpec.scala index 10d230b5e0..5aa9ea1bc3 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/internal/HasJSNativeLoadSpec.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/internal/HasJSNativeLoadSpec.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.annotation.internal diff --git a/library/src/main/scala/scala/scalajs/js/annotation/internal/JSOptional.scala b/library/src/main/scala/scala/scalajs/js/annotation/internal/JSOptional.scala index 4d4ab3b3fa..bb64c6c4b9 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/internal/JSOptional.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/internal/JSOptional.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.annotation.internal diff --git a/library/src/main/scala/scala/scalajs/js/defined.scala b/library/src/main/scala/scala/scalajs/js/defined.scala index f91048fd41..76e94b0c15 100644 --- a/library/src/main/scala/scala/scalajs/js/defined.scala +++ b/library/src/main/scala/scala/scalajs/js/defined.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/package.scala b/library/src/main/scala/scala/scalajs/js/package.scala index 95350b9720..c4f3f350b9 100644 --- a/library/src/main/scala/scala/scalajs/js/package.scala +++ b/library/src/main/scala/scala/scalajs/js/package.scala @@ -1,12 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs diff --git a/library/src/main/scala/scala/scalajs/js/special/package.scala b/library/src/main/scala/scala/scalajs/js/special/package.scala index d1073c3ec7..6446da98f5 100644 --- a/library/src/main/scala/scala/scalajs/js/special/package.scala +++ b/library/src/main/scala/scala/scalajs/js/special/package.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/timers/Handles.scala b/library/src/main/scala/scala/scalajs/js/timers/Handles.scala index 29813b5c05..c5c20e731a 100644 --- a/library/src/main/scala/scala/scalajs/js/timers/Handles.scala +++ b/library/src/main/scala/scala/scalajs/js/timers/Handles.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.timers diff --git a/library/src/main/scala/scala/scalajs/js/timers/RawTimers.scala b/library/src/main/scala/scala/scalajs/js/timers/RawTimers.scala index 25c53fbfdd..4ba4b3713d 100644 --- a/library/src/main/scala/scala/scalajs/js/timers/RawTimers.scala +++ b/library/src/main/scala/scala/scalajs/js/timers/RawTimers.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.timers diff --git a/library/src/main/scala/scala/scalajs/js/timers/package.scala b/library/src/main/scala/scala/scalajs/js/timers/package.scala index fe1a38fc2c..e064a51350 100644 --- a/library/src/main/scala/scala/scalajs/js/timers/package.scala +++ b/library/src/main/scala/scala/scalajs/js/timers/package.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBuffer.scala b/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBuffer.scala index 4bffa83839..def2ced918 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBuffer.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBuffer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.js.typedarray import scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBufferInputStream.scala b/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBufferInputStream.scala index b59796e100..9f930b4883 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBufferInputStream.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBufferInputStream.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.js.typedarray import java.io.InputStream diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBufferView.scala b/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBufferView.scala index 5e9aafd666..be43783fd2 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBufferView.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBufferView.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.js.typedarray import scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/DataView.scala b/library/src/main/scala/scala/scalajs/js/typedarray/DataView.scala index 82a718f97f..e7dc1119c1 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/DataView.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/DataView.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.js.typedarray import scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/DataViewExt.scala b/library/src/main/scala/scala/scalajs/js/typedarray/DataViewExt.scala index 7a75e8b346..f0330ad2c4 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/DataViewExt.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/DataViewExt.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.typedarray diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Float32Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Float32Array.scala index 4be02de554..910806df03 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Float32Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Float32Array.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.js.typedarray import scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Float64Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Float64Array.scala index b84559a9ac..f4514a8cfe 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Float64Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Float64Array.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.js.typedarray import scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Int16Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Int16Array.scala index 70e924d73b..2db0796390 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Int16Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Int16Array.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.js.typedarray import scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Int32Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Int32Array.scala index 4174c231ca..7eed4c63b8 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Int32Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Int32Array.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.js.typedarray import scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Int8Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Int8Array.scala index 9d238e9814..4d7a3b79dd 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Int8Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Int8Array.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.js.typedarray import scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/TypedArray.scala b/library/src/main/scala/scala/scalajs/js/typedarray/TypedArray.scala index 5adc3d4376..f5f041f6c0 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/TypedArray.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/TypedArray.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.js.typedarray import scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/TypedArrayBuffer.scala b/library/src/main/scala/scala/scalajs/js/typedarray/TypedArrayBuffer.scala index 57df8a82e6..8d5319bc20 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/TypedArrayBuffer.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/TypedArrayBuffer.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.typedarray diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/TypedArrayBufferBridge.scala b/library/src/main/scala/scala/scalajs/js/typedarray/TypedArrayBufferBridge.scala index fb063bf6af..32f89a6136 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/TypedArrayBufferBridge.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/TypedArrayBufferBridge.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ /* !!!!! * THIS FILE IS ALMOST COPY-PASTED IN javalib/ AND library/. @@ -28,7 +31,6 @@ * !!!!! */ - package scala.scalajs.js.typedarray import java.nio._ diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/TypedArrayBufferOps.scala b/library/src/main/scala/scala/scalajs/js/typedarray/TypedArrayBufferOps.scala index 8e436707da..cf123d38c6 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/TypedArrayBufferOps.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/TypedArrayBufferOps.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.typedarray diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Uint16Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Uint16Array.scala index 7a0635eb5c..b14b92007a 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Uint16Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Uint16Array.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.js.typedarray import scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Uint32Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Uint32Array.scala index 20f60a36ff..accf72c806 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Uint32Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Uint32Array.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.js.typedarray import scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Uint8Array.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Uint8Array.scala index 4965aa72ef..0551fa2334 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Uint8Array.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Uint8Array.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.js.typedarray import scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/Uint8ClampedArray.scala b/library/src/main/scala/scala/scalajs/js/typedarray/Uint8ClampedArray.scala index 63e30aeee7..f54a5d442f 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/Uint8ClampedArray.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/Uint8ClampedArray.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.js.typedarray import scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/js/typedarray/package.scala b/library/src/main/scala/scala/scalajs/js/typedarray/package.scala index b150998c77..69cf8bafb9 100644 --- a/library/src/main/scala/scala/scalajs/js/typedarray/package.scala +++ b/library/src/main/scala/scala/scalajs/js/typedarray/package.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.js import JSConverters._ diff --git a/library/src/main/scala/scala/scalajs/macroimpls/Compat210.scala b/library/src/main/scala/scala/scalajs/macroimpls/Compat210.scala index 2d2e52457b..7cf167cd56 100644 --- a/library/src/main/scala/scala/scalajs/macroimpls/Compat210.scala +++ b/library/src/main/scala/scala/scalajs/macroimpls/Compat210.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.macroimpls diff --git a/library/src/main/scala/scala/scalajs/macroimpls/JSMemberSelection.scala b/library/src/main/scala/scala/scalajs/macroimpls/JSMemberSelection.scala index 1243021bc9..555c2f6626 100644 --- a/library/src/main/scala/scala/scalajs/macroimpls/JSMemberSelection.scala +++ b/library/src/main/scala/scala/scalajs/macroimpls/JSMemberSelection.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.macroimpls diff --git a/library/src/main/scala/scala/scalajs/macroimpls/JSMembers.scala b/library/src/main/scala/scala/scalajs/macroimpls/JSMembers.scala index 61094160f1..ce0b23b8c0 100644 --- a/library/src/main/scala/scala/scalajs/macroimpls/JSMembers.scala +++ b/library/src/main/scala/scala/scalajs/macroimpls/JSMembers.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.macroimpls diff --git a/library/src/main/scala/scala/scalajs/macroimpls/UseAsMacros.scala b/library/src/main/scala/scala/scalajs/macroimpls/UseAsMacros.scala index 1156184bf3..44d7add52c 100644 --- a/library/src/main/scala/scala/scalajs/macroimpls/UseAsMacros.scala +++ b/library/src/main/scala/scala/scalajs/macroimpls/UseAsMacros.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.macroimpls diff --git a/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1.scala b/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1.scala index 7765f0ca36..bf6e43398c 100644 --- a/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1.scala +++ b/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.niocharset diff --git a/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1_And_US_ASCII_Common.scala b/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1_And_US_ASCII_Common.scala index 2d4937f628..6473f8727b 100644 --- a/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1_And_US_ASCII_Common.scala +++ b/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1_And_US_ASCII_Common.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.niocharset diff --git a/library/src/main/scala/scala/scalajs/niocharset/StandardCharsets.scala b/library/src/main/scala/scala/scalajs/niocharset/StandardCharsets.scala index 38615f6d77..3b6c5be9c1 100644 --- a/library/src/main/scala/scala/scalajs/niocharset/StandardCharsets.scala +++ b/library/src/main/scala/scala/scalajs/niocharset/StandardCharsets.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.niocharset diff --git a/library/src/main/scala/scala/scalajs/niocharset/US_ASCII.scala b/library/src/main/scala/scala/scalajs/niocharset/US_ASCII.scala index 746c75b871..b3df437b70 100644 --- a/library/src/main/scala/scala/scalajs/niocharset/US_ASCII.scala +++ b/library/src/main/scala/scala/scalajs/niocharset/US_ASCII.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.niocharset diff --git a/library/src/main/scala/scala/scalajs/niocharset/UTF_16.scala b/library/src/main/scala/scala/scalajs/niocharset/UTF_16.scala index 9d1748a7cf..0b201bbe65 100644 --- a/library/src/main/scala/scala/scalajs/niocharset/UTF_16.scala +++ b/library/src/main/scala/scala/scalajs/niocharset/UTF_16.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.niocharset diff --git a/library/src/main/scala/scala/scalajs/niocharset/UTF_16BE.scala b/library/src/main/scala/scala/scalajs/niocharset/UTF_16BE.scala index dece19161b..c76cf67d96 100644 --- a/library/src/main/scala/scala/scalajs/niocharset/UTF_16BE.scala +++ b/library/src/main/scala/scala/scalajs/niocharset/UTF_16BE.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.niocharset diff --git a/library/src/main/scala/scala/scalajs/niocharset/UTF_16LE.scala b/library/src/main/scala/scala/scalajs/niocharset/UTF_16LE.scala index de469c40aa..e0b685efc3 100644 --- a/library/src/main/scala/scala/scalajs/niocharset/UTF_16LE.scala +++ b/library/src/main/scala/scala/scalajs/niocharset/UTF_16LE.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.niocharset diff --git a/library/src/main/scala/scala/scalajs/niocharset/UTF_16_Common.scala b/library/src/main/scala/scala/scalajs/niocharset/UTF_16_Common.scala index d1e6681807..d7313157eb 100644 --- a/library/src/main/scala/scala/scalajs/niocharset/UTF_16_Common.scala +++ b/library/src/main/scala/scala/scalajs/niocharset/UTF_16_Common.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.niocharset diff --git a/library/src/main/scala/scala/scalajs/niocharset/UTF_8.scala b/library/src/main/scala/scala/scalajs/niocharset/UTF_8.scala index 4553bd0219..1576b34802 100644 --- a/library/src/main/scala/scala/scalajs/niocharset/UTF_8.scala +++ b/library/src/main/scala/scala/scalajs/niocharset/UTF_8.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.niocharset diff --git a/library/src/main/scala/scala/scalajs/reflect/Reflect.scala b/library/src/main/scala/scala/scalajs/reflect/Reflect.scala index 4001d66e5e..96e9eaf91e 100644 --- a/library/src/main/scala/scala/scalajs/reflect/Reflect.scala +++ b/library/src/main/scala/scala/scalajs/reflect/Reflect.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.reflect import scala.collection.mutable diff --git a/library/src/main/scala/scala/scalajs/reflect/annotation/EnableReflectiveInstantiation.scala b/library/src/main/scala/scala/scalajs/reflect/annotation/EnableReflectiveInstantiation.scala index adb8a4e157..5634e2c684 100644 --- a/library/src/main/scala/scala/scalajs/reflect/annotation/EnableReflectiveInstantiation.scala +++ b/library/src/main/scala/scala/scalajs/reflect/annotation/EnableReflectiveInstantiation.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.reflect.annotation /** Enables reflective instantiation for the annotated class, trait or object, diff --git a/library/src/main/scala/scala/scalajs/runtime/AnonFunctions.scala b/library/src/main/scala/scala/scalajs/runtime/AnonFunctions.scala index f6c82fce0d..36ebb2c5ff 100644 --- a/library/src/main/scala/scala/scalajs/runtime/AnonFunctions.scala +++ b/library/src/main/scala/scala/scalajs/runtime/AnonFunctions.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.runtime import scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/runtime/Bits.scala b/library/src/main/scala/scala/scalajs/runtime/Bits.scala index a25e69c726..0c4a6e541b 100644 --- a/library/src/main/scala/scala/scalajs/runtime/Bits.scala +++ b/library/src/main/scala/scala/scalajs/runtime/Bits.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.runtime diff --git a/library/src/main/scala/scala/scalajs/runtime/BooleanReflectiveCall.scala b/library/src/main/scala/scala/scalajs/runtime/BooleanReflectiveCall.scala index 979fca981b..c95a52acce 100644 --- a/library/src/main/scala/scala/scalajs/runtime/BooleanReflectiveCall.scala +++ b/library/src/main/scala/scala/scalajs/runtime/BooleanReflectiveCall.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.runtime import java.lang.{Boolean => JBoolean} diff --git a/library/src/main/scala/scala/scalajs/runtime/EnvironmentInfo.scala b/library/src/main/scala/scala/scalajs/runtime/EnvironmentInfo.scala index 9786932403..06afda3c07 100644 --- a/library/src/main/scala/scala/scalajs/runtime/EnvironmentInfo.scala +++ b/library/src/main/scala/scala/scalajs/runtime/EnvironmentInfo.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.runtime import scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/runtime/IntegerReflectiveCall.scala b/library/src/main/scala/scala/scalajs/runtime/IntegerReflectiveCall.scala index e718d69ebc..e80b20790e 100644 --- a/library/src/main/scala/scala/scalajs/runtime/IntegerReflectiveCall.scala +++ b/library/src/main/scala/scala/scalajs/runtime/IntegerReflectiveCall.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.runtime import java.lang.{Double => JDouble, Integer => JInteger} diff --git a/library/src/main/scala/scala/scalajs/runtime/LinkingInfo.scala b/library/src/main/scala/scala/scalajs/runtime/LinkingInfo.scala index d4ea4b4090..8335d8a9bf 100644 --- a/library/src/main/scala/scala/scalajs/runtime/LinkingInfo.scala +++ b/library/src/main/scala/scala/scalajs/runtime/LinkingInfo.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.runtime import scala.scalajs.js diff --git a/library/src/main/scala/scala/scalajs/runtime/LongReflectiveCall.scala b/library/src/main/scala/scala/scalajs/runtime/LongReflectiveCall.scala index ec7505a998..42ad932f41 100644 --- a/library/src/main/scala/scala/scalajs/runtime/LongReflectiveCall.scala +++ b/library/src/main/scala/scala/scalajs/runtime/LongReflectiveCall.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.runtime import java.lang.{Long => JLong} diff --git a/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala b/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala index cc711925b7..9d7c2a71a0 100644 --- a/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala +++ b/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.runtime import java.lang.{Double => JDouble, Integer => JInteger} diff --git a/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala b/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala index 2660cfb74c..b42c8f0372 100644 --- a/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala +++ b/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.runtime import scala.annotation.tailrec diff --git a/library/src/main/scala/scala/scalajs/runtime/RuntimeString.scala b/library/src/main/scala/scala/scalajs/runtime/RuntimeString.scala index 2e8fc6d828..bab8fa9112 100644 --- a/library/src/main/scala/scala/scalajs/runtime/RuntimeString.scala +++ b/library/src/main/scala/scala/scalajs/runtime/RuntimeString.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.runtime import java.util.Comparator diff --git a/library/src/main/scala/scala/scalajs/runtime/SemanticsUtils.scala b/library/src/main/scala/scala/scalajs/runtime/SemanticsUtils.scala index 6d365f26b2..b7928882df 100644 --- a/library/src/main/scala/scala/scalajs/runtime/SemanticsUtils.scala +++ b/library/src/main/scala/scala/scalajs/runtime/SemanticsUtils.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.runtime import scala.annotation.switch diff --git a/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala b/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala index 02e0be8c08..cb2cd9b79a 100644 --- a/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala +++ b/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.runtime import scala.annotation.tailrec diff --git a/library/src/main/scala/scala/scalajs/runtime/UndefinedBehaviorError.scala b/library/src/main/scala/scala/scalajs/runtime/UndefinedBehaviorError.scala index 91e5f2f01e..044a854360 100644 --- a/library/src/main/scala/scala/scalajs/runtime/UndefinedBehaviorError.scala +++ b/library/src/main/scala/scala/scalajs/runtime/UndefinedBehaviorError.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.runtime import scala.util.control.ControlThrowable diff --git a/library/src/main/scala/scala/scalajs/runtime/package.scala b/library/src/main/scala/scala/scalajs/runtime/package.scala index 7380b33f4f..599c0c8d3a 100644 --- a/library/src/main/scala/scala/scalajs/runtime/package.scala +++ b/library/src/main/scala/scala/scalajs/runtime/package.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs import scala.annotation.tailrec diff --git a/no-ir-check-test/src/test/scala/org/scalajs/testsuite/noircheck/DummyParentsTest.scala b/no-ir-check-test/src/test/scala/org/scalajs/testsuite/noircheck/DummyParentsTest.scala index 8585a02d04..e5b67af5e4 100644 --- a/no-ir-check-test/src/test/scala/org/scalajs/testsuite/noircheck/DummyParentsTest.scala +++ b/no-ir-check-test/src/test/scala/org/scalajs/testsuite/noircheck/DummyParentsTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.noircheck import org.junit.Test diff --git a/partest/src/main-partest-1.0.16/scala/tools/partest/scalajs/ScalaJSPartest.scala b/partest/src/main-partest-1.0.16/scala/tools/partest/scalajs/ScalaJSPartest.scala index 84b38c0013..91835c21d6 100644 --- a/partest/src/main-partest-1.0.16/scala/tools/partest/scalajs/ScalaJSPartest.scala +++ b/partest/src/main-partest-1.0.16/scala/tools/partest/scalajs/ScalaJSPartest.scala @@ -1,6 +1,13 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2013 LAMP/EPFL - * @author Sébastien Doeraene +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ package scala.tools.partest diff --git a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala index 8e11838a9b..b456d40760 100644 --- a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala +++ b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.tools.nsc /* Super hacky overriding of the MainGenericRunner used by partest */ diff --git a/partest/src/main/scala/scala/tools/partest/scalajs/PartestInterface.scala b/partest/src/main/scala/scala/tools/partest/scalajs/PartestInterface.scala index b0356e1622..e87e52a434 100644 --- a/partest/src/main/scala/scala/tools/partest/scalajs/PartestInterface.scala +++ b/partest/src/main/scala/scala/tools/partest/scalajs/PartestInterface.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + /* NOTE * Most of this file is copy-pasted from * https://github.com/scala/scala-partest-interface diff --git a/partest/src/main/scala/scala/tools/partest/scalajs/ScalaJSPartestOptions.scala b/partest/src/main/scala/scala/tools/partest/scalajs/ScalaJSPartestOptions.scala index 7b078a9757..4d1bad4cd9 100644 --- a/partest/src/main/scala/scala/tools/partest/scalajs/ScalaJSPartestOptions.scala +++ b/partest/src/main/scala/scala/tools/partest/scalajs/ScalaJSPartestOptions.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.tools.partest.scalajs class ScalaJSPartestOptions private ( diff --git a/project/Build.scala b/project/Build.scala index eab40cfd49..58c9b9cb99 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -6,6 +6,7 @@ import Keys._ import scala.annotation.tailrec import com.typesafe.tools.mima.plugin.MimaPlugin.autoImport._ +import de.heikoseeberger.sbtheader.HeaderPlugin.autoImport._ import java.io.{ BufferedOutputStream, @@ -145,9 +146,21 @@ object Build { _.replace("scala.js", "scalajs").replace("scala-js", "scalajs") }, - homepage := Some(url("http://scala-js.org/")), - licenses += ("BSD New", - url("https://github.com/scala-js/scala-js/blob/master/LICENSE")), + homepage := Some(url("https://www.scala-js.org/")), + startYear := Some(2013), + licenses += (("Apache-2.0", url("https://www.apache.org/licenses/LICENSE-2.0"))), + headerLicense := Some(HeaderLicense.Custom( + s"""Scala.js (${homepage.value.get}) + | + |Copyright EPFL. + | + |Licensed under Apache License 2.0 + |(https://www.apache.org/licenses/LICENSE-2.0). + | + |See the NOTICE file distributed with this work for + |additional information regarding copyright ownership. + |""".stripMargin + )), scmInfo := Some(ScmInfo( url("https://github.com/scala-js/scala-js"), "scm:git:git@github.com:scala-js/scala-js.git", @@ -462,28 +475,42 @@ object Build { lazy val root: Project = Project( id = "scalajs", base = file("."), - settings = commonSettings ++ Seq( + settings = commonSettings ++ Def.settings( name := "Scala.js", publishArtifact in Compile := false, - clean := clean.dependsOn( - clean in compiler, - clean in irProject, clean in irProjectJS, - clean in tools, clean in toolsJS, - clean in jsEnvs, clean in jsEnvsTestKit, clean in jsEnvsTestSuite, - clean in testAdapter, clean in plugin, - clean in javalanglib, clean in javalib, clean in scalalib, - clean in libraryAux, clean in library, clean in javalibEx, - clean in stubs, clean in cli, - clean in testInterface, - clean in jUnitRuntime, clean in jUnitPlugin, - clean in jUnitTestOutputsJS, clean in jUnitTestOutputsJVM, - clean in examples, clean in helloworld, - clean in reversi, clean in testingExample, - clean in testSuite, clean in testSuiteJVM, clean in noIrCheckTest, - clean in javalibExTestSuite, - clean in partest, clean in partestSuite, - clean in scalaTestSuite).value, + { + val allProjects = Seq( + compiler, irProject, irProjectJS, tools, toolsJS, + jsEnvs, jsEnvsTestKit, jsEnvsTestSuite, testAdapter, plugin, + javalanglib, javalib, scalalib, libraryAux, library, javalibEx, + stubs, cli, + testInterface, jUnitRuntime, jUnitPlugin, + jUnitTestOutputsJS, jUnitTestOutputsJVM, + helloworld, reversi, testingExample, testSuite, testSuiteJVM, + noIrCheckTest, javalibExTestSuite, + partest, partestSuite, + scalaTestSuite + ) + + val keys = Seq[TaskKey[_]]( + clean, headerCreate in Compile, headerCreate in Test, + headerCheck in Compile, headerCheck in Test + ) + + for (key <- keys) yield { + /* The match is only used to capture the type parameter `a` of + * each individual TaskKey. + */ + key match { + case key: TaskKey[a] => + key := key.dependsOn(allProjects.map(key in _): _*).value + } + } + }, + + headerCreate := (headerCreate in Test).dependsOn(headerCreate in Compile).value, + headerCheck := (headerCheck in Test).dependsOn(headerCheck in Compile).value, publish := {}, publishLocal := {} @@ -875,13 +902,20 @@ object Build { base = file("javalib"), settings = ( commonSettings ++ myScalaJSSettings ++ fatalWarningsSettings - ) ++ Seq( + ) ++ Def.settings( name := "Java library for Scala.js", publishArtifact in Compile := false, delambdafySetting, - noClassFilesSettings - ) ++ ( - scalaJSExternalCompileSettings + noClassFilesSettings, + scalaJSExternalCompileSettings, + + headerSources in Compile ~= { srcs => + srcs.filter { src => + val path = src.getPath.replace('\\', '/') + !path.contains("/java/math/") && + !path.endsWith("/java/util/concurrent/ThreadLocalRandom.scala") + } + } ) ).withScalaJSCompiler.dependsOnLibraryNoJar @@ -1020,6 +1054,9 @@ object Build { sources.result() }, + headerSources in Compile := Nil, + headerSources in Test := Nil, + // Continuation plugin (when using 2.10.x) autoCompilerPlugins := true, libraryDependencies ++= { @@ -1237,8 +1274,19 @@ object Build { lazy val jUnitRuntime = Project( id = "jUnitRuntime", base = file("junit-runtime"), - settings = commonSettings ++ publishSettings ++ myScalaJSSettings ++ - fatalWarningsSettings ++ Seq(name := "Scala.js JUnit test runtime") + settings = ( + commonSettings ++ publishSettings ++ myScalaJSSettings ++ + fatalWarningsSettings + ) ++ Def.settings( + name := "Scala.js JUnit test runtime", + + headerSources in Compile ~= { srcs => + srcs.filter { src => + val path = src.getPath.replace('\\', '/') + !path.contains("/org/junit/") && !path.contains("/org/hamcrest/") + } + } + ) ).withScalaJSCompiler.dependsOn(testInterface) val commonJUnitTestOutputsSettings = commonSettings ++ Seq( @@ -1296,7 +1344,10 @@ object Build { ) ).aggregate(helloworld, reversi, testingExample) - lazy val exampleSettings = commonSettings ++ myScalaJSSettings ++ fatalWarningsSettings + lazy val exampleSettings = commonSettings ++ myScalaJSSettings ++ fatalWarningsSettings ++ Def.settings( + headerSources in Compile := Nil, + headerSources in Test := Nil + ) lazy val helloworld: Project = Project( id = "helloworld", diff --git a/project/build.sbt b/project/build.sbt index cc4e4884ca..89d6db39a3 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -1,3 +1,5 @@ +addSbtPlugin("de.heikoseeberger" % "sbt-header" % "5.0.0") + addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.5") addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.18") diff --git a/sbt-plugin/src/main/scala-sbt-0.13/org/scalajs/sbtplugin/SBTCompat.scala b/sbt-plugin/src/main/scala-sbt-0.13/org/scalajs/sbtplugin/SBTCompat.scala index 3f5d4acf0c..c4e43a5164 100644 --- a/sbt-plugin/src/main/scala-sbt-0.13/org/scalajs/sbtplugin/SBTCompat.scala +++ b/sbt-plugin/src/main/scala-sbt-0.13/org/scalajs/sbtplugin/SBTCompat.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.sbtplugin import sbt._ diff --git a/sbt-plugin/src/main/scala/org/scalajs/jsdependencies/sbtplugin/JSDependenciesPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/jsdependencies/sbtplugin/JSDependenciesPlugin.scala index e5d97099b9..64d5a67c19 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/jsdependencies/sbtplugin/JSDependenciesPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/jsdependencies/sbtplugin/JSDependenciesPlugin.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.jsdependencies.sbtplugin diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/AbstractJSDeps.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/AbstractJSDeps.scala index 37b365fc30..81ab030b68 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/AbstractJSDeps.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/AbstractJSDeps.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.sbtplugin import sbt._ diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala index 8571eccaf8..2a406557e0 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/FrameworkDetector.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.sbtplugin @deprecated("Empty. Will be removed.", "0.6.22") diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/HTMLRunnerTemplate.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/HTMLRunnerTemplate.scala index b5122648fe..3cc5567db8 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/HTMLRunnerTemplate.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/HTMLRunnerTemplate.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.sbtplugin diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Implicits.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Implicits.scala index 60d4949c69..54adbb5e92 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Implicits.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Implicits.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.sbtplugin import scala.language.implicitConversions diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/LoggerJSConsole.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/LoggerJSConsole.scala index 6342cab434..dfcd4199e3 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/LoggerJSConsole.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/LoggerJSConsole.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.sbtplugin diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Loggers.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Loggers.scala index 0bfcaca6e7..f6768340f6 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Loggers.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Loggers.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.sbtplugin import org.scalajs.core.tools.logging._ diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/OptimizerOptions.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/OptimizerOptions.scala index bfb32a161b..55f4ada1e6 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/OptimizerOptions.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/OptimizerOptions.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.sbtplugin diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSCrossVersion.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSCrossVersion.scala index a93f9ab227..8ec18f09a4 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSCrossVersion.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSCrossVersion.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.sbtplugin diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSJUnitPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSJUnitPlugin.scala index a5eb206ec3..f29af194d9 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSJUnitPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSJUnitPlugin.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.sbtplugin diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 47f6bed71d..4ab8e76cf6 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.sbtplugin diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index ee5ed9ae2b..95a96ff326 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.sbtplugin import scala.annotation.tailrec diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalajspUtils.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalajspUtils.scala index eb8cefefd5..33db06ba04 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalajspUtils.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalajspUtils.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.sbtplugin diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Stage.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Stage.scala index 724695d009..cc83944a5f 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Stage.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/Stage.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.sbtplugin diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossClasspathDependency.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossClasspathDependency.scala index d2610287a8..8a426ddc51 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossClasspathDependency.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossClasspathDependency.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.sbtplugin.cross diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossProject.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossProject.scala index 73cf8cebfb..4474394e12 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossProject.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossProject.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.sbtplugin.cross diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossType.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossType.scala index e21df988aa..b1ee0adc26 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossType.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/CrossType.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.sbtplugin.cross diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/MacroUtils.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/MacroUtils.scala index 1a310ea291..bf7eb24b9b 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/MacroUtils.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/cross/MacroUtils.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.sbtplugin.cross diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/DependencyBuilders.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/DependencyBuilders.scala index 8112b22daf..91f8c0fa51 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/DependencyBuilders.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/impl/DependencyBuilders.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.sbtplugin package impl diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/internal/ScalaJSGlobalPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/internal/ScalaJSGlobalPlugin.scala index 80a7641f1f..c8cee3ee62 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/internal/ScalaJSGlobalPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/internal/ScalaJSGlobalPlugin.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.sbtplugin.internal diff --git a/stubs/src/main/scala/org/scalajs/testinterface/TestUtils.scala b/stubs/src/main/scala/org/scalajs/testinterface/TestUtils.scala index cff0081913..d091c6c659 100644 --- a/stubs/src/main/scala/org/scalajs/testinterface/TestUtils.scala +++ b/stubs/src/main/scala/org/scalajs/testinterface/TestUtils.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testinterface import language.experimental.macros diff --git a/stubs/src/main/scala/scala/scalajs/js/annotation/ExportAnnotations.scala b/stubs/src/main/scala/scala/scalajs/js/annotation/ExportAnnotations.scala index 20281c4963..8c6d697c50 100644 --- a/stubs/src/main/scala/scala/scalajs/js/annotation/ExportAnnotations.scala +++ b/stubs/src/main/scala/scala/scalajs/js/annotation/ExportAnnotations.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package scala.scalajs.js.annotation diff --git a/stubs/src/main/scala/scala/scalajs/reflect/annotation/ReflectAnnotations.scala b/stubs/src/main/scala/scala/scalajs/reflect/annotation/ReflectAnnotations.scala index 56a2a004bc..452248af65 100644 --- a/stubs/src/main/scala/scala/scalajs/reflect/annotation/ReflectAnnotations.scala +++ b/stubs/src/main/scala/scala/scalajs/reflect/annotation/ReflectAnnotations.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js API ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.scalajs.reflect.annotation class EnableReflectiveInstantiation extends scala.annotation.Annotation diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ComJSEnvRPC.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ComJSEnvRPC.scala index f1df78cec1..326e45090e 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ComJSEnvRPC.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ComJSEnvRPC.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.testadapter diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/FrameworkAdapter.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/FrameworkAdapter.scala index e11654af35..15447bff5c 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/FrameworkAdapter.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/FrameworkAdapter.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.testadapter diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/RemoteException.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/RemoteException.scala index 37378d8ff3..92a622efed 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/RemoteException.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/RemoteException.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.testadapter diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/RunnerAdapter.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/RunnerAdapter.scala index be4adab53b..e99aeb0bf5 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/RunnerAdapter.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/RunnerAdapter.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js test adapter ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.testadapter diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala index 7f19b800b7..b2f7619126 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSFramework.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.testadapter diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala index 781d034a8e..a4a354cfd2 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSRunner.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.testadapter diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSTask.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSTask.scala index 60f7cd5fe1..2aa8224e9b 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSTask.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/ScalaJSTask.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.testadapter diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TaskAdapter.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TaskAdapter.scala index b67735e542..71ecc95516 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TaskAdapter.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TaskAdapter.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js test adapter ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.testadapter diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TestAdapter.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TestAdapter.scala index 1bf13c96dc..8150ab0a46 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TestAdapter.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TestAdapter.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js test adapter ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.testadapter diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/package.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/package.scala index 275ae8afd3..dcdb50f193 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/package.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/package.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js sbt plugin ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs diff --git a/test-common/src/main/scala/org/scalajs/testcommon/Endpoints.scala b/test-common/src/main/scala/org/scalajs/testcommon/Endpoints.scala index c6cacebda8..d6303f55af 100644 --- a/test-common/src/main/scala/org/scalajs/testcommon/Endpoints.scala +++ b/test-common/src/main/scala/org/scalajs/testcommon/Endpoints.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testcommon private[scalajs] sealed trait Endpoint { diff --git a/test-common/src/main/scala/org/scalajs/testcommon/ExecuteRequest.scala b/test-common/src/main/scala/org/scalajs/testcommon/ExecuteRequest.scala index c7cf653deb..46ea82ecaa 100644 --- a/test-common/src/main/scala/org/scalajs/testcommon/ExecuteRequest.scala +++ b/test-common/src/main/scala/org/scalajs/testcommon/ExecuteRequest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testcommon private[scalajs] final class ExecuteRequest( diff --git a/test-common/src/main/scala/org/scalajs/testcommon/FrameworkInfo.scala b/test-common/src/main/scala/org/scalajs/testcommon/FrameworkInfo.scala index 2e8dc645d3..aae6d4a4b4 100644 --- a/test-common/src/main/scala/org/scalajs/testcommon/FrameworkInfo.scala +++ b/test-common/src/main/scala/org/scalajs/testcommon/FrameworkInfo.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testcommon import sbt.testing._ diff --git a/test-common/src/main/scala/org/scalajs/testcommon/FrameworkMessage.scala b/test-common/src/main/scala/org/scalajs/testcommon/FrameworkMessage.scala index 5b8a5d27fc..1952b5de56 100644 --- a/test-common/src/main/scala/org/scalajs/testcommon/FrameworkMessage.scala +++ b/test-common/src/main/scala/org/scalajs/testcommon/FrameworkMessage.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testcommon private[scalajs] final class FrameworkMessage(val slaveId: Long, val msg: String) diff --git a/test-common/src/main/scala/org/scalajs/testcommon/FutureUtil.scala b/test-common/src/main/scala/org/scalajs/testcommon/FutureUtil.scala index 377cf6620c..2f95071cc3 100644 --- a/test-common/src/main/scala/org/scalajs/testcommon/FutureUtil.scala +++ b/test-common/src/main/scala/org/scalajs/testcommon/FutureUtil.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testcommon import scala.util._ diff --git a/test-common/src/main/scala/org/scalajs/testcommon/JSEndpoints.scala b/test-common/src/main/scala/org/scalajs/testcommon/JSEndpoints.scala index ba010ba951..34c8ce4794 100644 --- a/test-common/src/main/scala/org/scalajs/testcommon/JSEndpoints.scala +++ b/test-common/src/main/scala/org/scalajs/testcommon/JSEndpoints.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testcommon import sbt.testing.TaskDef diff --git a/test-common/src/main/scala/org/scalajs/testcommon/JVMEndpoints.scala b/test-common/src/main/scala/org/scalajs/testcommon/JVMEndpoints.scala index c72c18715f..8ffebd6402 100644 --- a/test-common/src/main/scala/org/scalajs/testcommon/JVMEndpoints.scala +++ b/test-common/src/main/scala/org/scalajs/testcommon/JVMEndpoints.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testcommon import sbt.testing.Event diff --git a/test-common/src/main/scala/org/scalajs/testcommon/LogElement.scala b/test-common/src/main/scala/org/scalajs/testcommon/LogElement.scala index 29ae677525..ec87991dda 100644 --- a/test-common/src/main/scala/org/scalajs/testcommon/LogElement.scala +++ b/test-common/src/main/scala/org/scalajs/testcommon/LogElement.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testcommon private[scalajs] final class LogElement[T](val index: Int, val x: T) diff --git a/test-common/src/main/scala/org/scalajs/testcommon/RPCCore.scala b/test-common/src/main/scala/org/scalajs/testcommon/RPCCore.scala index 61b4139520..c9748cafea 100644 --- a/test-common/src/main/scala/org/scalajs/testcommon/RPCCore.scala +++ b/test-common/src/main/scala/org/scalajs/testcommon/RPCCore.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testcommon import scala.util.{Try, Failure, Success} diff --git a/test-common/src/main/scala/org/scalajs/testcommon/RunMux.scala b/test-common/src/main/scala/org/scalajs/testcommon/RunMux.scala index 9cb909c102..a660e61011 100644 --- a/test-common/src/main/scala/org/scalajs/testcommon/RunMux.scala +++ b/test-common/src/main/scala/org/scalajs/testcommon/RunMux.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testcommon private[scalajs] final class RunMux[+T](val runId: RunMux.RunID, val value: T) diff --git a/test-common/src/main/scala/org/scalajs/testcommon/RunMuxRPC.scala b/test-common/src/main/scala/org/scalajs/testcommon/RunMuxRPC.scala index 5f59fdbda1..aadf9414e7 100644 --- a/test-common/src/main/scala/org/scalajs/testcommon/RunMuxRPC.scala +++ b/test-common/src/main/scala/org/scalajs/testcommon/RunMuxRPC.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testcommon import scala.language.higherKinds diff --git a/test-common/src/main/scala/org/scalajs/testcommon/RunnerArgs.scala b/test-common/src/main/scala/org/scalajs/testcommon/RunnerArgs.scala index 8dcb462614..1ff5e3ad84 100644 --- a/test-common/src/main/scala/org/scalajs/testcommon/RunnerArgs.scala +++ b/test-common/src/main/scala/org/scalajs/testcommon/RunnerArgs.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testcommon private[scalajs] final class RunnerArgs( diff --git a/test-common/src/main/scala/org/scalajs/testcommon/Serializer.scala b/test-common/src/main/scala/org/scalajs/testcommon/Serializer.scala index 31b7995d8a..d1e021c794 100644 --- a/test-common/src/main/scala/org/scalajs/testcommon/Serializer.scala +++ b/test-common/src/main/scala/org/scalajs/testcommon/Serializer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testcommon import sbt.testing._ diff --git a/test-common/src/main/scala/org/scalajs/testcommon/TaskInfo.scala b/test-common/src/main/scala/org/scalajs/testcommon/TaskInfo.scala index bc98deccf8..f8a2e3d67b 100644 --- a/test-common/src/main/scala/org/scalajs/testcommon/TaskInfo.scala +++ b/test-common/src/main/scala/org/scalajs/testcommon/TaskInfo.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testcommon import sbt.testing._ diff --git a/test-common/src/test/scala/org/scalajs/testcommon/RPCCoreTest.scala b/test-common/src/test/scala/org/scalajs/testcommon/RPCCoreTest.scala index d87d4d43fd..e55d10c33c 100644 --- a/test-common/src/test/scala/org/scalajs/testcommon/RPCCoreTest.scala +++ b/test-common/src/test/scala/org/scalajs/testcommon/RPCCoreTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testcommon import scala.concurrent._ diff --git a/test-common/src/test/scala/org/scalajs/testcommon/RunMuxRPCTest.scala b/test-common/src/test/scala/org/scalajs/testcommon/RunMuxRPCTest.scala index 211d40578e..f07837e0a6 100644 --- a/test-common/src/test/scala/org/scalajs/testcommon/RunMuxRPCTest.scala +++ b/test-common/src/test/scala/org/scalajs/testcommon/RunMuxRPCTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testcommon import scala.concurrent._ diff --git a/test-common/src/test/scala/org/scalajs/testcommon/SerializerTest.scala b/test-common/src/test/scala/org/scalajs/testcommon/SerializerTest.scala index 3663f8affd..2fcac6bab0 100644 --- a/test-common/src/test/scala/org/scalajs/testcommon/SerializerTest.scala +++ b/test-common/src/test/scala/org/scalajs/testcommon/SerializerTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testcommon import org.junit.Test diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala b/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala index b57df0d6ee..4fb57a344d 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/HTMLRunner.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testinterface import scala.scalajs.js diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/ScalaJSClassLoader.scala b/test-interface/src/main/scala/org/scalajs/testinterface/ScalaJSClassLoader.scala index af24f9150d..1d8b5ebfff 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/ScalaJSClassLoader.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/ScalaJSClassLoader.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testinterface import scala.scalajs.js diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala b/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala index 894085439c..a96b7d0a0f 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/TestDetector.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testinterface import java.io._ diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/TestUtils.scala b/test-interface/src/main/scala/org/scalajs/testinterface/TestUtils.scala index d4c0903a1b..411d275f10 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/TestUtils.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/TestUtils.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testinterface import scala.scalajs.js diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Bridge.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/Bridge.scala index daec33d8db..b7089147c2 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/Bridge.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/Bridge.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testinterface.internal import scala.scalajs.js.annotation._ diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkLoader.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkLoader.scala index 10e8556bf6..c9f541daef 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkLoader.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/FrameworkLoader.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testinterface.internal import scala.scalajs.js diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/JSRPC.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/JSRPC.scala index b2553d4689..0cd1930d88 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/JSRPC.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/JSRPC.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testinterface.internal import scala.scalajs.js diff --git a/test-interface/src/main/scala/org/scalajs/testinterface/internal/TaskInfoBuilder.scala b/test-interface/src/main/scala/org/scalajs/testinterface/internal/TaskInfoBuilder.scala index 6aded8a49a..62ad880a41 100644 --- a/test-interface/src/main/scala/org/scalajs/testinterface/internal/TaskInfoBuilder.scala +++ b/test-interface/src/main/scala/org/scalajs/testinterface/internal/TaskInfoBuilder.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testinterface.internal import sbt.testing._ diff --git a/test-interface/src/main/scala/sbt/testing/Event.scala b/test-interface/src/main/scala/sbt/testing/Event.scala index 243d9d172f..201128dc85 100644 --- a/test-interface/src/main/scala/sbt/testing/Event.scala +++ b/test-interface/src/main/scala/sbt/testing/Event.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package sbt.testing /** An event fired by the test framework during a run. */ diff --git a/test-interface/src/main/scala/sbt/testing/EventHandler.scala b/test-interface/src/main/scala/sbt/testing/EventHandler.scala index 87deecb88e..fa2e3c1f00 100644 --- a/test-interface/src/main/scala/sbt/testing/EventHandler.scala +++ b/test-interface/src/main/scala/sbt/testing/EventHandler.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package sbt.testing /** Interface implemented by clients that handle events fired by the test diff --git a/test-interface/src/main/scala/sbt/testing/Fingerprints.scala b/test-interface/src/main/scala/sbt/testing/Fingerprints.scala index 9f7d1d0218..df36bd1b24 100644 --- a/test-interface/src/main/scala/sbt/testing/Fingerprints.scala +++ b/test-interface/src/main/scala/sbt/testing/Fingerprints.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package sbt.testing /** A way to identify test classes and/or modules that should be discovered diff --git a/test-interface/src/main/scala/sbt/testing/Framework.scala b/test-interface/src/main/scala/sbt/testing/Framework.scala index 15f1133ce2..ddbae51047 100644 --- a/test-interface/src/main/scala/sbt/testing/Framework.scala +++ b/test-interface/src/main/scala/sbt/testing/Framework.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package sbt.testing import scala.scalajs.reflect.annotation._ diff --git a/test-interface/src/main/scala/sbt/testing/Logger.scala b/test-interface/src/main/scala/sbt/testing/Logger.scala index 0bec50eb28..fa3eb3ad79 100644 --- a/test-interface/src/main/scala/sbt/testing/Logger.scala +++ b/test-interface/src/main/scala/sbt/testing/Logger.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package sbt.testing /** A logger through which to provide feedback to the user about a run. diff --git a/test-interface/src/main/scala/sbt/testing/OptionalThrowable.scala b/test-interface/src/main/scala/sbt/testing/OptionalThrowable.scala index 6e24ad53e1..eb93b20585 100644 --- a/test-interface/src/main/scala/sbt/testing/OptionalThrowable.scala +++ b/test-interface/src/main/scala/sbt/testing/OptionalThrowable.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package sbt.testing /** An optional Throwable. */ diff --git a/test-interface/src/main/scala/sbt/testing/Runner.scala b/test-interface/src/main/scala/sbt/testing/Runner.scala index 83e527ddc5..0502f3f113 100644 --- a/test-interface/src/main/scala/sbt/testing/Runner.scala +++ b/test-interface/src/main/scala/sbt/testing/Runner.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package sbt.testing /** Represents one run of a suite of tests. diff --git a/test-interface/src/main/scala/sbt/testing/Selectors.scala b/test-interface/src/main/scala/sbt/testing/Selectors.scala index 9a849c64ab..f2c8019865 100644 --- a/test-interface/src/main/scala/sbt/testing/Selectors.scala +++ b/test-interface/src/main/scala/sbt/testing/Selectors.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package sbt.testing /** Information in addition to a test class name that identifies the suite or diff --git a/test-interface/src/main/scala/sbt/testing/Status.scala b/test-interface/src/main/scala/sbt/testing/Status.scala index e9d9a0f893..1188eb10e4 100644 --- a/test-interface/src/main/scala/sbt/testing/Status.scala +++ b/test-interface/src/main/scala/sbt/testing/Status.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package sbt.testing /** Represents the status of running a test. diff --git a/test-interface/src/main/scala/sbt/testing/Task.scala b/test-interface/src/main/scala/sbt/testing/Task.scala index 391d21508f..62261ed10f 100644 --- a/test-interface/src/main/scala/sbt/testing/Task.scala +++ b/test-interface/src/main/scala/sbt/testing/Task.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package sbt.testing /** A task to execute. diff --git a/test-interface/src/main/scala/sbt/testing/TaskDef.scala b/test-interface/src/main/scala/sbt/testing/TaskDef.scala index 0e4f579338..cc870ec677 100644 --- a/test-interface/src/main/scala/sbt/testing/TaskDef.scala +++ b/test-interface/src/main/scala/sbt/testing/TaskDef.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package sbt.testing import java.util.Arrays diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/Compat210.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/Compat210.scala index 117be3fbe9..9526ad6ce1 100644 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/Compat210.scala +++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/Compat210.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite private[testsuite] object Compat210 { diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/Typechecking.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/Typechecking.scala index 326a8b52e8..e58bff2cc1 100644 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/Typechecking.scala +++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/Typechecking.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite import scala.language.experimental.macros diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/TypecheckingMacros.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/TypecheckingMacros.scala index 76b8fcf860..daff042045 100644 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/TypecheckingMacros.scala +++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/TypecheckingMacros.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite import Compat210._ diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTestSeparateRun.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTestSeparateRun.scala index 431bcf3325..cf57e34be9 100644 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTestSeparateRun.scala +++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTestSeparateRun.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import scala.scalajs.js diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/junit/MultiCompilationTest.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/junit/MultiCompilationTest.scala index 50c0b6e72b..03436d3009 100644 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/junit/MultiCompilationTest.scala +++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/junit/MultiCompilationTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.junit import org.junit.Test diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala index 4a88861f42..b2ddb60101 100644 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala +++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.utils import scala.scalajs.js diff --git a/test-suite/js/src/test/require-2.12/org/scalajs/testsuite/jsinterop/JSOptionalTest212.scala b/test-suite/js/src/test/require-2.12/org/scalajs/testsuite/jsinterop/JSOptionalTest212.scala index 08caa4ee40..d4d680cf3c 100644 --- a/test-suite/js/src/test/require-2.12/org/scalajs/testsuite/jsinterop/JSOptionalTest212.scala +++ b/test-suite/js/src/test/require-2.12/org/scalajs/testsuite/jsinterop/JSOptionalTest212.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import scala.scalajs.js diff --git a/test-suite/js/src/test/resources/SourceMapTestTemplate.scala b/test-suite/js/src/test/resources/SourceMapTestTemplate.scala index 189226833d..287d30b819 100644 --- a/test-suite/js/src/test/resources/SourceMapTestTemplate.scala +++ b/test-suite/js/src/test/resources/SourceMapTestTemplate.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import org.junit.Assert._ @@ -62,7 +74,7 @@ class SourceMapTest { val topSte = trace2.head assertTrue(normFileName(topSte).contains("/SourceMapTest.scala")) - val throwSte = if (topSte.getLineNumber == 19) { + val throwSte = if (topSte.getLineNumber == 31) { // line where `case class TestException is written` above val throwSte = trace2.tail.head assertTrue(normFileName(throwSte).contains("/SourceMapTest.scala")) diff --git a/test-suite/js/src/test/scala-new-collections/org/scalajs/testsuite/library/ArrayOpsCollectionEraDependentTest.scala b/test-suite/js/src/test/scala-new-collections/org/scalajs/testsuite/library/ArrayOpsCollectionEraDependentTest.scala index 58094563f5..2b24472b53 100644 --- a/test-suite/js/src/test/scala-new-collections/org/scalajs/testsuite/library/ArrayOpsCollectionEraDependentTest.scala +++ b/test-suite/js/src/test/scala-new-collections/org/scalajs/testsuite/library/ArrayOpsCollectionEraDependentTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.library import scala.scalajs.js diff --git a/test-suite/js/src/test/scala-new-collections/org/scalajs/testsuite/library/WrappedArrayToTest.scala b/test-suite/js/src/test/scala-new-collections/org/scalajs/testsuite/library/WrappedArrayToTest.scala index 6e554ed170..67d7dbc052 100644 --- a/test-suite/js/src/test/scala-new-collections/org/scalajs/testsuite/library/WrappedArrayToTest.scala +++ b/test-suite/js/src/test/scala-new-collections/org/scalajs/testsuite/library/WrappedArrayToTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.library import scala.scalajs.js diff --git a/test-suite/js/src/test/scala-new-collections/org/scalajs/testsuite/library/WrappedDictionaryToTest.scala b/test-suite/js/src/test/scala-new-collections/org/scalajs/testsuite/library/WrappedDictionaryToTest.scala index 9e9f236fde..91a51fc3b4 100644 --- a/test-suite/js/src/test/scala-new-collections/org/scalajs/testsuite/library/WrappedDictionaryToTest.scala +++ b/test-suite/js/src/test/scala-new-collections/org/scalajs/testsuite/library/WrappedDictionaryToTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.library import scala.scalajs.js diff --git a/test-suite/js/src/test/scala-old-collections/org/scalajs/testsuite/library/ArrayOpsCollectionEraDependentTest.scala b/test-suite/js/src/test/scala-old-collections/org/scalajs/testsuite/library/ArrayOpsCollectionEraDependentTest.scala index 35e7e900ac..02e7c74234 100644 --- a/test-suite/js/src/test/scala-old-collections/org/scalajs/testsuite/library/ArrayOpsCollectionEraDependentTest.scala +++ b/test-suite/js/src/test/scala-old-collections/org/scalajs/testsuite/library/ArrayOpsCollectionEraDependentTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.library import scala.scalajs.js diff --git a/test-suite/js/src/test/scala-old-collections/org/scalajs/testsuite/library/WrappedArrayToTest.scala b/test-suite/js/src/test/scala-old-collections/org/scalajs/testsuite/library/WrappedArrayToTest.scala index 1f0130406c..67643bcd92 100644 --- a/test-suite/js/src/test/scala-old-collections/org/scalajs/testsuite/library/WrappedArrayToTest.scala +++ b/test-suite/js/src/test/scala-old-collections/org/scalajs/testsuite/library/WrappedArrayToTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.library import scala.scalajs.js diff --git a/test-suite/js/src/test/scala-old-collections/org/scalajs/testsuite/library/WrappedDictionaryToTest.scala b/test-suite/js/src/test/scala-old-collections/org/scalajs/testsuite/library/WrappedDictionaryToTest.scala index 065817408e..6762d5552c 100644 --- a/test-suite/js/src/test/scala-old-collections/org/scalajs/testsuite/library/WrappedDictionaryToTest.scala +++ b/test-suite/js/src/test/scala-old-collections/org/scalajs/testsuite/library/WrappedDictionaryToTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.library import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/BooleanJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/BooleanJSTest.scala index 56e17e0dd7..3271f873d1 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/BooleanJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/BooleanJSTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import org.junit.Test diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/DefaultMethodsJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/DefaultMethodsJSTest.scala index 1f20007370..52b1d05093 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/DefaultMethodsJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/DefaultMethodsJSTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import org.junit.Test diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/FloatJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/FloatJSTest.scala index 2fe789faa4..ecd3b1ae32 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/FloatJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/FloatJSTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import org.junit.Test diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InstanceTestsHijackedBoxedClassesTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InstanceTestsHijackedBoxedClassesTest.scala index 59f04736d4..8e8fff87c1 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InstanceTestsHijackedBoxedClassesTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InstanceTestsHijackedBoxedClassesTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import org.junit.Test diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/IntJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/IntJSTest.scala index 94c3fcba54..6a6bafa2a1 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/IntJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/IntJSTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import org.junit.Test diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala index de41a44ed5..b8c174e07f 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import scala.language.implicitConversions diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/LongJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/LongJSTest.scala index db71b9c3aa..03497fc674 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/LongJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/LongJSTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ModuleInitTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ModuleInitTest.scala index 0be110d448..4b58bd9f86 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ModuleInitTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ModuleInitTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import org.junit.Test diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ModuleInitializersTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ModuleInitializersTest.scala index 8555cdd235..f292ccc144 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ModuleInitializersTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ModuleInitializersTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import org.junit.Test diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala index 581f405981..e90585e045 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/OptimizerTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectionTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectionTest.scala index 5a5bf487c9..112396eba2 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectionTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectionTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import scala.language.implicitConversions diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala index 42ab841ba0..95107f8927 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RegressionJSTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RuntimeTypesTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RuntimeTypesTest.scala index de0fd2523c..9ac732cdd6 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RuntimeTypesTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RuntimeTypesTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import java.lang.Cloneable diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/UnitJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/UnitJSTest.scala index f8d5ce0d91..fd26c139de 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/UnitJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/UnitJSTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import org.junit.Test diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/io/DataInputStreamJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/io/DataInputStreamJSTest.scala index 3fbe4274c2..b3577548f1 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/io/DataInputStreamJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/io/DataInputStreamJSTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.io import java.io.InputStream diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/ClassJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/ClassJSTest.scala index 188dc98e81..b8f3dc181c 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/ClassJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/ClassJSTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import org.junit.Test diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/ObjectJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/ObjectJSTest.scala index e6f2008bb3..ec920d8f79 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/ObjectJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/ObjectJSTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import org.junit.Test diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/StackTraceElementJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/StackTraceElementJSTest.scala index 77557426fc..c824d1b18d 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/StackTraceElementJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/StackTraceElementJSTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import org.junit.Assert._ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/StringBufferJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/StringBufferJSTest.scala index c56d1b49bf..16c724fc6f 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/StringBufferJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/StringBufferJSTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala index e53fff63c0..4165e78724 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import org.scalajs.testsuite.utils.Platform diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/reflect/ReflectArrayJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/reflect/ReflectArrayJSTest.scala index e02ebda59b..cbccaea865 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/reflect/ReflectArrayJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/reflect/ReflectArrayJSTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang.reflect diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/util/FormatterJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/util/FormatterJSTest.scala index 0eb9983fa3..6cc9f42809 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/util/FormatterJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/util/FormatterJSTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/util/TimerTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/util/TimerTest.scala index 17271c943b..4ddcf645cb 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/util/TimerTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/util/TimerTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import org.junit.Assert._ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ArrayTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ArrayTest.scala index a4b967ab33..99416fc26e 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ArrayTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ArrayTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import scala.language.implicitConversions diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/AsyncTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/AsyncTest.scala index ec9326a912..122049c128 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/AsyncTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/AsyncTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import scala.language.implicitConversions diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DictionaryTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DictionaryTest.scala index 2f0eb28ff8..39e4fd80da 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DictionaryTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DictionaryTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DynamicTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DynamicTest.scala index b9feb9047e..caa6591c21 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DynamicTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/DynamicTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import scala.language.implicitConversions diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index 81dfb87ee3..b88504220b 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/FunctionTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/FunctionTest.scala index c731ed9453..a73f5e4a54 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/FunctionTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/FunctionTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/IterableTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/IterableTest.scala index ec7a95027a..0d93c12285 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/IterableTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/IterableTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala index f377e4595a..04b78a2116 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSExportStaticTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNameTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNameTest.scala index f2e6c791e0..55e45300a1 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNameTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNameTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNativeInPackage.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNativeInPackage.scala index 52ede549c4..b8dd287fc5 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNativeInPackage.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSNativeInPackage.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import org.junit.Test diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala index e7948a68fc..d459361ef4 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSOptionalTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala index 0cb33c224b..5e9e09d92b 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/JSSymbolTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala index e8d6cfbbad..9cae2cbef4 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/MiscInteropTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala index 67904b3f13..58e266a210 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PrimitivesTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PrimitivesTest.scala index 00a309332e..98fccccbf4 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PrimitivesTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PrimitivesTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import org.junit.Assert._ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PromiseMock.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PromiseMock.scala index 49631fcd85..757c08a26f 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PromiseMock.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/PromiseMock.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/RuntimeLongTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/RuntimeLongTest.scala index 2bfb55f54e..644abc3377 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/RuntimeLongTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/RuntimeLongTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import scala.language.implicitConversions diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala index d4621cd25e..ee2aefdbff 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala index ee3f707af6..da58fb489c 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SpecialTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/StrangeNamedTests.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/StrangeNamedTests.scala index d15ac25e95..7f836d5c4d 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/StrangeNamedTests.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/StrangeNamedTests.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import org.junit.Test diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SymbolTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SymbolTest.scala index 7501e5ac7c..81798241be 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SymbolTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/SymbolTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ThisFunctionTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ThisFunctionTest.scala index 3a4c2be60a..5d2cb7ac35 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ThisFunctionTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ThisFunctionTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/TimeoutMock.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/TimeoutMock.scala index d43cf62183..ef9e08fe16 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/TimeoutMock.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/TimeoutMock.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/TupleTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/TupleTest.scala index b7e9e3ac2d..82ed7eae73 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/TupleTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/TupleTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import scala.language.implicitConversions diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTest.scala index 12c8b2d1d9..7992ebe5fd 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/UndefOrTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.jsinterop import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitAbstractClassTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitAbstractClassTest.scala index 0d7c46b9a0..1b62c09dee 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitAbstractClassTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitAbstractClassTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.junit import org.junit.Assert._ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitBootstrapTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitBootstrapTest.scala index ff4e92d318..3c926c4da0 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitBootstrapTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitBootstrapTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.junit import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitMixinTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitMixinTest.scala index ade9bbcaea..a64f532d88 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitMixinTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitMixinTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.junit import org.junit.Assert._ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitNamesTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitNamesTest.scala index 243bd61dad..c5bb92509d 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitNamesTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitNamesTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.junit import org.junit.Test diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitPackageTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitPackageTest.scala index 9a6f5603d0..a8f67ba95b 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitPackageTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitPackageTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.junit import org.junit.Test diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitSubClassTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitSubClassTest.scala index 1af42c2f1d..bc5fb60a83 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitSubClassTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitSubClassTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.junit import org.junit.Assert._ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala index fb70dba016..ff8de01bc8 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.junit import org.scalajs.junit.JUnitTestBootstrapper diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/MultiCompilationSecondUnitTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/MultiCompilationSecondUnitTest.scala index 9d49bfdb56..c4976ea32d 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/MultiCompilationSecondUnitTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/MultiCompilationSecondUnitTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.junit import org.junit.Test diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ArrayOpsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ArrayOpsTest.scala index 90254e72c9..aa8c6130d8 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ArrayOpsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ArrayOpsTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.library import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/JavaScriptExceptionTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/JavaScriptExceptionTest.scala index fc5f2570de..9415819c5b 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/JavaScriptExceptionTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/JavaScriptExceptionTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.library import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/LinkingInfoTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/LinkingInfoTest.scala index 002ffc44eb..f0b48ca929 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/LinkingInfoTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/LinkingInfoTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.library import org.junit.Assert._ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ReflectTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ReflectTest.scala index 6063bd677a..cb16cd26c9 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ReflectTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ReflectTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.library import org.junit.Assert._ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/StackTraceTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/StackTraceTest.scala index 17d322749c..8a12d0bf1d 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/StackTraceTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/StackTraceTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.library import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UnionTypeTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UnionTypeTest.scala index 1ab3381389..3fd8ee0b38 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UnionTypeTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UnionTypeTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.library import scala.language.implicitConversions diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UseAsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UseAsTest.scala index efb63157f9..69223f7c9b 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UseAsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/UseAsTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.library import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/WrappedArrayTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/WrappedArrayTest.scala index 18bfb495ba..5ab494b565 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/WrappedArrayTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/WrappedArrayTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.library import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/WrappedDictionaryTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/WrappedDictionaryTest.scala index ab0022edb9..bda59d03e1 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/WrappedDictionaryTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/WrappedDictionaryTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.library import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/ByteBufferJSFactories.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/ByteBufferJSFactories.scala index 27c4d73a58..f3d80fd9df 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/ByteBufferJSFactories.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/ByteBufferJSFactories.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niobuffer import scala.scalajs.js.JSConverters._ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/ByteBufferJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/ByteBufferJSTest.scala index 0ebca55e37..a3001e4a13 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/ByteBufferJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/ByteBufferJSTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niobuffer import org.scalajs.testsuite.niobuffer.BufferFactory.ByteBufferFactory diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/CharBufferJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/CharBufferJSTest.scala index 8029b55773..7248b7a0e9 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/CharBufferJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/CharBufferJSTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niobuffer import java.nio._ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/DoubleBufferJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/DoubleBufferJSTest.scala index a5b3c7f147..489e4f36c8 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/DoubleBufferJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/DoubleBufferJSTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niobuffer import java.nio._ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/FloatBufferJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/FloatBufferJSTest.scala index f93b795b53..7c41e00ab5 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/FloatBufferJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/FloatBufferJSTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niobuffer import java.nio._ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/IntBufferJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/IntBufferJSTest.scala index d41538081e..656902a75f 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/IntBufferJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/IntBufferJSTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niobuffer import java.nio._ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/LongBufferJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/LongBufferJSTest.scala index 7ec0ec8d53..05a5ce0e1c 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/LongBufferJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/LongBufferJSTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niobuffer import java.nio._ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/ShortBufferJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/ShortBufferJSTest.scala index 6d7babb8e2..e89c3b5648 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/ShortBufferJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/ShortBufferJSTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niobuffer import java.nio._ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/SupportsTypedArrays.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/SupportsTypedArrays.scala index fbde1e1614..159de877f2 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/SupportsTypedArrays.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/niobuffer/SupportsTypedArrays.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niobuffer import org.junit.BeforeClass diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/niocharset/CharsetJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/niocharset/CharsetJSTest.scala index 562fe161c2..bf7a02e696 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/niocharset/CharsetJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/niocharset/CharsetJSTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niocharset import scala.language.implicitConversions diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/scalalib/ScalaRunTimeJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/scalalib/ScalaRunTimeJSTest.scala index c14089d84a..06a9257daa 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/scalalib/ScalaRunTimeJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/scalalib/ScalaRunTimeJSTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.scalalib import org.junit.Test diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/ArrayBufferInputStreamTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/ArrayBufferInputStreamTest.scala index 92ae7fb47e..4f93d394f0 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/ArrayBufferInputStreamTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/ArrayBufferInputStreamTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.typedarray import org.scalajs.testsuite.utils.Requires diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/ArrayBufferTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/ArrayBufferTest.scala index 8996eb0a37..ebbc76d9ea 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/ArrayBufferTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/ArrayBufferTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.typedarray import org.junit.Assert._ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/ArraysTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/ArraysTest.scala index 0335af25ae..2f8abd068a 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/ArraysTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/ArraysTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.typedarray import scala.scalajs.js.typedarray._ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/DataViewTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/DataViewTest.scala index 3981f02632..fa0b059fd0 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/DataViewTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/DataViewTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.typedarray import org.junit.Assert._ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/TypedArrayConversionTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/TypedArrayConversionTest.scala index 9045a644a0..091c09879c 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/TypedArrayConversionTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/TypedArrayConversionTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.typedarray import org.junit.Assert._ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/TypedArrayTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/TypedArrayTest.scala index e829026896..a004d48e14 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/TypedArrayTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/typedarray/TypedArrayTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.typedarray import org.junit.Assert._ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/JSAssert.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/JSAssert.scala index 42ae04633c..589f689200 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/JSAssert.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/JSAssert.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.utils import scala.scalajs.js diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/JSUtils.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/JSUtils.scala index 7c6f95189f..740e19ed9a 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/JSUtils.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/JSUtils.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.utils import scala.language.implicitConversions diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/PlatformTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/PlatformTest.scala index 574b690241..b91923c1e6 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/PlatformTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/PlatformTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.utils import org.junit.Test diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/Requires.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/Requires.scala index 9ed4e6e0c7..c72fed474d 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/Requires.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/utils/Requires.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.utils import org.junit.Assume._ diff --git a/test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala b/test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala index 97363a7566..05bf8c11b9 100644 --- a/test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala +++ b/test-suite/jvm/src/main/scala/org/scalajs/testsuite/utils/Platform.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.utils object Platform { diff --git a/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/io/AutoCloseableTest.scala b/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/io/AutoCloseableTest.scala index 7377732516..82426dd876 100644 --- a/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/io/AutoCloseableTest.scala +++ b/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/io/AutoCloseableTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.io import org.junit.Test diff --git a/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/lang/CharacterTestOnJDK7.scala b/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/lang/CharacterTestOnJDK7.scala index 2d5c7282bf..c73075c074 100644 --- a/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/lang/CharacterTestOnJDK7.scala +++ b/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/lang/CharacterTestOnJDK7.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import org.junit.Test diff --git a/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/lang/SystemTestOnJDK7.scala b/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/lang/SystemTestOnJDK7.scala index 3a6c4332af..5d73c67e37 100644 --- a/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/lang/SystemTestOnJDK7.scala +++ b/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/lang/SystemTestOnJDK7.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import org.scalajs.testsuite.utils.Platform._ diff --git a/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/lang/ThrowablesTestOnJDK7.scala b/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/lang/ThrowablesTestOnJDK7.scala index e3c2d99ece..ca6884fb8b 100644 --- a/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/lang/ThrowablesTestOnJDK7.scala +++ b/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/lang/ThrowablesTestOnJDK7.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import org.junit.Assert._ diff --git a/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/util/CollectionsTestOnJDK7.scala b/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/util/CollectionsTestOnJDK7.scala index 5be095a648..717f22e12d 100644 --- a/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/util/CollectionsTestOnJDK7.scala +++ b/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/util/CollectionsTestOnJDK7.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.{util => ju} diff --git a/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/util/ObjectsTestOnJDK7.scala b/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/util/ObjectsTestOnJDK7.scala index 2689203623..bedbedf7a6 100644 --- a/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/util/ObjectsTestOnJDK7.scala +++ b/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/util/ObjectsTestOnJDK7.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.{util => ju} diff --git a/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/util/concurrent/ThreadLocalRandomTest.scala b/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/util/concurrent/ThreadLocalRandomTest.scala index fe89b5448d..fe60539db0 100644 --- a/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/util/concurrent/ThreadLocalRandomTest.scala +++ b/test-suite/shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/util/concurrent/ThreadLocalRandomTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util.concurrent import org.junit.Test diff --git a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/compiler/DefaultMethodsTest.scala b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/compiler/DefaultMethodsTest.scala index 0610f03a21..436c185c98 100644 --- a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/compiler/DefaultMethodsTest.scala +++ b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/compiler/DefaultMethodsTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import org.junit.Test diff --git a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/DoubleTestJDK8.scala b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/DoubleTestJDK8.scala index cfb996ebd0..87a2c7643a 100644 --- a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/DoubleTestJDK8.scala +++ b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/DoubleTestJDK8.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scalajs.testsuite.javalib.lang import org.junit.Test diff --git a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/FloatTestJDK8.scala b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/FloatTestJDK8.scala index c6307b8da2..7fa9a2a74c 100644 --- a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/FloatTestJDK8.scala +++ b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/FloatTestJDK8.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scalajs.testsuite.javalib.lang import org.junit.Test diff --git a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/IntegerTestOnJDK8.scala b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/IntegerTestOnJDK8.scala index ea1a8c0794..779fa50a51 100644 --- a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/IntegerTestOnJDK8.scala +++ b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/IntegerTestOnJDK8.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import org.junit.Test diff --git a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/LongTestOnJDK8.scala b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/LongTestOnJDK8.scala index b308c93bfb..0f1154c22b 100644 --- a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/LongTestOnJDK8.scala +++ b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/LongTestOnJDK8.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import org.junit.Test diff --git 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 index 267cad65c1..168b5cb240 100644 --- 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 @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import org.junit.Assume._ diff --git a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/Base64Test.scala b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/Base64Test.scala index f4cdf00943..1fdbd8af12 100644 --- a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/Base64Test.scala +++ b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/Base64Test.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.io.{ByteArrayInputStream, ByteArrayOutputStream, IOException} diff --git a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/CollectionsOnCopyOnWriteArrayListTestOnJDK8.scala b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/CollectionsOnCopyOnWriteArrayListTestOnJDK8.scala index 4477ee73c1..841c3925b2 100644 --- a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/CollectionsOnCopyOnWriteArrayListTestOnJDK8.scala +++ b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/CollectionsOnCopyOnWriteArrayListTestOnJDK8.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import org.junit.Test diff --git a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/ComparatorTestOnJDK8.scala b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/ComparatorTestOnJDK8.scala index 70d444e823..7b430013c5 100644 --- a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/ComparatorTestOnJDK8.scala +++ b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/ComparatorTestOnJDK8.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import org.junit.Test diff --git a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/ObjectsTestOnJDK8.scala b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/ObjectsTestOnJDK8.scala index b0aa37a4cf..db69279ce7 100644 --- a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/ObjectsTestOnJDK8.scala +++ b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/ObjectsTestOnJDK8.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import org.junit.Test diff --git a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/OptionalTest.scala b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/OptionalTest.scala index 28fee21548..92a545bd1d 100644 --- a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/OptionalTest.scala +++ b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/OptionalTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import org.junit.Assert._ diff --git a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/SplittableRandom.scala b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/SplittableRandom.scala index 262181750a..e13d27b2ed 100644 --- a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/SplittableRandom.scala +++ b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/util/SplittableRandom.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import org.junit.Assert._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ArrayTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ArrayTest.scala index 52d7e0a343..f1974fd85f 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ArrayTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ArrayTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/BooleanTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/BooleanTest.scala index 7c3524fc91..07e398d891 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/BooleanTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/BooleanTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ByteTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ByteTest.scala index bb202ded97..3f49ee67f0 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ByteTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ByteTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/CharTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/CharTest.scala index 703ddc1aa5..c5de5171d0 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/CharTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/CharTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/DoubleTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/DoubleTest.scala index d76b058c69..fb7b23c0a7 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/DoubleTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/DoubleTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/FloatTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/FloatTest.scala index f870e48301..06ed2ac151 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/FloatTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/FloatTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/IntTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/IntTest.scala index 402f52c04d..7e9ec85d8f 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/IntTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/IntTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/LongTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/LongTest.scala index 6de701d502..aef7820577 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/LongTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/LongTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/MatchTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/MatchTest.scala index 1eb475b16f..861640b087 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/MatchTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/MatchTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import scala.annotation.switch diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/OuterClassTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/OuterClassTest.scala index 2baed6a5ea..97b4578aa2 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/OuterClassTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/OuterClassTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/PatMatOuterPointerCheckTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/PatMatOuterPointerCheckTest.scala index de20928b45..27217935c5 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/PatMatOuterPointerCheckTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/PatMatOuterPointerCheckTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ReflectiveCallTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ReflectiveCallTest.scala index 580a19c54d..7b4fabceef 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ReflectiveCallTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ReflectiveCallTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import language.reflectiveCalls diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala index 3a743d5575..1d881a38e2 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import scala.annotation.tailrec diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ShortTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ShortTest.scala index 1db8b04841..2cbf8e6335 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ShortTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/ShortTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/UnitTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/UnitTest.scala index 401296297a..b95e801081 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/UnitTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/UnitTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.compiler import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/ByteArrayInputStreamTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/ByteArrayInputStreamTest.scala index fb15d1e239..f5f5ba762a 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/ByteArrayInputStreamTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/ByteArrayInputStreamTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.io import java.io._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/ByteArrayOutputStreamTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/ByteArrayOutputStreamTest.scala index e0d191c48a..babdedefa2 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/ByteArrayOutputStreamTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/ByteArrayOutputStreamTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.io import java.io._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/CommonStreamsTests.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/CommonStreamsTests.scala index 980db5daff..6150b82ef0 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/CommonStreamsTests.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/CommonStreamsTests.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.io import java.io._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/DataInputStreamTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/DataInputStreamTest.scala index 22975c8532..f49a67e390 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/DataInputStreamTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/DataInputStreamTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.io import java.io._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/DataOutputStreamTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/DataOutputStreamTest.scala index e2a79b12c5..b00b8b12db 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/DataOutputStreamTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/DataOutputStreamTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.io import java.io._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/InputStreamTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/InputStreamTest.scala index 350371ca84..06981f4525 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/InputStreamTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/InputStreamTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.io import java.io._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/MockByteArrayOutputStream.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/MockByteArrayOutputStream.scala index 06432c2e1a..08d66050e5 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/MockByteArrayOutputStream.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/MockByteArrayOutputStream.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.io import java.io._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/OutputStreamWriterTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/OutputStreamWriterTest.scala index 0dff16346b..8d7d25248c 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/OutputStreamWriterTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/OutputStreamWriterTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.io import java.io._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/PrintStreamTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/PrintStreamTest.scala index 13d21dc544..2ce84cdfd1 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/PrintStreamTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/PrintStreamTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.io import java.io._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/PrintWriterTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/PrintWriterTest.scala index 908b95d7c0..4f9fbb2baa 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/PrintWriterTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/PrintWriterTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.io import scala.language.implicitConversions diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/ReadersTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/ReadersTest.scala index 9983039553..32bcf92cee 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/ReadersTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/ReadersTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.io import scala.annotation.tailrec diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/SerializableTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/SerializableTest.scala index 31dbc9b3f5..13891049bc 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/SerializableTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/SerializableTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.io import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/ThrowablesTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/ThrowablesTest.scala index 0475508b55..e9dfc50e6b 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/ThrowablesTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/io/ThrowablesTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.io import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/BooleanTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/BooleanTest.scala index 03b4f2169a..35024f1df7 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/BooleanTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/BooleanTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import java.lang.{Boolean => JBoolean} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ByteTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ByteTest.scala index 7ce7634d2d..4a7c2de6ca 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ByteTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ByteTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import java.lang.{Byte => JByte} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/CharacterTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/CharacterTest.scala index 7ccd2b88bd..5a01f5daa0 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/CharacterTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/CharacterTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ClassTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ClassTest.scala index 4737466cfd..f6fe83ca0d 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ClassTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ClassTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/DoubleTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/DoubleTest.scala index b97dcc2ebf..413207ea08 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/DoubleTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/DoubleTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/FloatTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/FloatTest.scala index f4a3a359d9..9c6de143b2 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/FloatTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/FloatTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/IntegerTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/IntegerTest.scala index 8af8f67d03..4b32178395 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/IntegerTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/IntegerTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/LongTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/LongTest.scala index 29bc66c262..91027c20a9 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/LongTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/LongTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import java.lang.{Long => JLong} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/MathTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/MathTest.scala index 9d3dc01bf1..07bcdd3149 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/MathTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/MathTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ObjectTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ObjectTest.scala index 075478d5d5..ecaf368855 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ObjectTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ObjectTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ShortTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ShortTest.scala index 4a77d8e486..82886c44a1 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ShortTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ShortTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import java.lang.{Short => JShort} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StackTraceElementTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StackTraceElementTest.scala index a1e09c3bc6..1959539f17 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StackTraceElementTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StackTraceElementTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import org.junit.Assert._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringBufferTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringBufferTest.scala index 31efd0e179..e2a0d6bc58 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringBufferTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringBufferTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringBuilderTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringBuilderTest.scala index e290847825..779374a566 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringBuilderTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringBuilderTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import java.lang.StringBuilder diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringTest.scala index b6220fd2b0..7b614ad0dd 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/StringTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import java.nio.charset.Charset diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemTest.scala index abf468af4c..2e1e51f766 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import language.implicitConversions diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ThreadTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ThreadTest.scala index 63ac5eb2b2..acd0294adb 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ThreadTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ThreadTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ThrowablesTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ThrowablesTest.scala index 3ecb32d2be..2bd97b4395 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ThrowablesTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ThrowablesTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/WrappedStringCharSequence.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/WrappedStringCharSequence.scala index 068125c733..bf614134ee 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/WrappedStringCharSequence.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/WrappedStringCharSequence.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang object WrappedStringCharSequence { diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ref/ReferenceTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ref/ReferenceTest.scala index 59b922a823..11c9241eb4 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ref/ReferenceTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ref/ReferenceTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang.ref import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/reflect/ReflectArrayTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/reflect/ReflectArrayTest.scala index eb51d94ba3..a769c6e0d8 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/reflect/ReflectArrayTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/reflect/ReflectArrayTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.lang.reflect import scala.runtime.BoxedUnit diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalArithmeticTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalArithmeticTest.scala index 27b16a32bb..6f484381e1 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalArithmeticTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalArithmeticTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + // scalastyle:off line.size.limit /* * Ported by Alistair Johnson from diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalCompareTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalCompareTest.scala index 35f6da0038..ad85e8d3ea 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalCompareTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalCompareTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + // scalastyle:off line.size.limit /* * Ported by Alistair Johnson from diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalConstructorsTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalConstructorsTest.scala index cb3ac43474..fbf67d2fa1 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalConstructorsTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalConstructorsTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + // scalastyle:off line.size.limit /* * Ported by Alistair Johnson from diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalConvertTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalConvertTest.scala index 982b45a870..5b744a99d4 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalConvertTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalConvertTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + // scalastyle:off line.size.limit /* * Ported by Alistair Johnson from diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalScaleOperationsTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalScaleOperationsTest.scala index e6e767b950..5589f3bb60 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalScaleOperationsTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalScaleOperationsTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + // scalastyle:off line.size.limit /* * Ported by Alistair Johnson from diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalTest.scala index 36e4901ff9..d719b73062 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigDecimalTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.math import java.math.BigDecimal diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerAddTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerAddTest.scala index 2d6c2f8a05..7774daecf8 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerAddTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerAddTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + // scalastyle:off line.size.limit /* * Ported by Alistair Johnson from diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerAndTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerAndTest.scala index 71b8d0b80d..a360f55253 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerAndTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerAndTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + // scalastyle:off line.size.limit /* * Ported by Alistair Johnson from diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerCompareTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerCompareTest.scala index 759377b4e6..4aad1e9511 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerCompareTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerCompareTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + // scalastyle:off line.size.limit /* * Ported by Alistair Johnson from diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerConstructorsTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerConstructorsTest.scala index 21065e1b6c..d0c326b40f 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerConstructorsTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerConstructorsTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + // scalastyle:off line.size.limit /* * Ported by Alistair Johnson from diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerConvertTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerConvertTest.scala index 7e4c905bde..7faf970399 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerConvertTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerConvertTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + // scalastyle:off line.size.limit /* * Ported by Alistair Johnson from diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerDivideTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerDivideTest.scala index aaefba0f42..48806577f7 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerDivideTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerDivideTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + // scalastyle:off line.size.limit /* * Ported by Alistair Johnson from diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerHashCodeTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerHashCodeTest.scala index b80ed1386e..9df469d7b4 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerHashCodeTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerHashCodeTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + // scalastyle:off line.size.limit /* * Ported by Alistair Johnson from diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerModPowTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerModPowTest.scala index c1c5c72bcf..051ee4c037 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerModPowTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerModPowTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + // scalastyle:off line.size.limit /* * Ported by Alistair Johnson from diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerMultiplyTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerMultiplyTest.scala index 943b280d94..08a9c9b511 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerMultiplyTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerMultiplyTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + // scalastyle:off line.size.limit /* * Ported by Alistair Johnson from diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerNotTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerNotTest.scala index 0ad806f22f..6e3e152e9c 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerNotTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerNotTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + // scalastyle:off line.size.limit /* * Ported by Alistair Johnson from diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerOperateBitsTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerOperateBitsTest.scala index 8477103327..5b96df97f6 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerOperateBitsTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerOperateBitsTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + // scalastyle:off line.size.limit /* * Ported by Alistair Johnson from diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerOrTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerOrTest.scala index 6c87e06712..f0a0604de8 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerOrTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerOrTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + // scalastyle:off line.size.limit /* * Ported by Alistair Johnson from diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerSubtractTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerSubtractTest.scala index 55b50c80f3..8f5389ad4d 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerSubtractTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerSubtractTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + // scalastyle:off line.size.limit /* * Ported by Alistair Johnson from diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerTest.scala index 7a792fc76a..c28bb0a942 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.math import java.math.BigInteger diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerToStringTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerToStringTest.scala index bd7349b553..ce880225b6 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerToStringTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerToStringTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + // scalastyle:off line.size.limit /* * Ported by Alistair Johnson from diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerXorTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerXorTest.scala index 24323ea792..b78a4501fb 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerXorTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/BigIntegerXorTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + // scalastyle:off line.size.limit /* * Ported by Alistair Johnson from diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/MathContextTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/MathContextTest.scala index bf6863b0ec..7cf1bcd1f5 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/MathContextTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/MathContextTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + // scalastyle:off line.size.limit /* * Ported by Alistair Johnson from diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/RoundingModeTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/RoundingModeTest.scala index 9bc42ff47f..f0bea4b2cc 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/RoundingModeTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/math/RoundingModeTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + // scalastyle:off line.size.limit /* * Ported by Alistair Johnson from diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/net/URITest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/net/URITest.scala index d8a275e7f5..cf69f5653c 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/net/URITest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/net/URITest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.net import java.net.{URI, URISyntaxException} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/net/URLDecoderTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/net/URLDecoderTest.scala index 967bf368f5..8f46bfcd9a 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/net/URLDecoderTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/net/URLDecoderTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.net import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/security/ThrowablesTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/security/ThrowablesTest.scala index 405f80d018..ab30d69c79 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/security/ThrowablesTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/security/ThrowablesTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.security import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/AbstractCollectionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/AbstractCollectionTest.scala index 17abe98f26..c0b0729875 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/AbstractCollectionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/AbstractCollectionTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.{util => ju} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/AbstractListTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/AbstractListTest.scala index 1e28437d2b..00eddcad69 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/AbstractListTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/AbstractListTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.{util => ju} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/AbstractMapTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/AbstractMapTest.scala index 8a18146ddd..22fcb14ed0 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/AbstractMapTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/AbstractMapTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.{util => ju} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/AbstractSetTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/AbstractSetTest.scala index ec8af0a802..165c68fd4f 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/AbstractSetTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/AbstractSetTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.{util => ju} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ArrayDequeTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ArrayDequeTest.scala index 0ada3e3a75..3c8bc344d3 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ArrayDequeTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ArrayDequeTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.util diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ArrayListTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ArrayListTest.scala index a8c1898799..a70a262403 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ArrayListTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ArrayListTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ArraysTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ArraysTest.scala index 5f9c29cec1..368ab0142a 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ArraysTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ArraysTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import language.implicitConversions diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionTest.scala index 3b50203d48..05d15aa2c1 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.{util => ju, lang => jl} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedCollectionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedCollectionTest.scala index 0d6ac3b419..5af993f6e0 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedCollectionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedCollectionTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.{util => ju} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedListTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedListTest.scala index bc5ee36729..94ce72d9d8 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedListTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedListTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.{util => ju} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedMapTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedMapTest.scala index 254f6211dc..1705ae1eb8 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedMapTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedMapTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.{util => ju} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedSetTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedSetTest.scala index aa7d9404d7..64e4b2b293 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedSetTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCheckedSetTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.{util => ju} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCollectionsTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCollectionsTest.scala index 8af87256a2..14dc022b6f 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCollectionsTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnCollectionsTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.util.Comparator diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnListsTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnListsTest.scala index c5d3848424..a4c235551e 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnListsTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnListsTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.{lang => jl, util => ju} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnMapsTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnMapsTest.scala index 4832d339ad..ad2ff5fcd8 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnMapsTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnMapsTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.{lang => jl, util => ju} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSetFromMapTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSetFromMapTest.scala index 7a1d45038e..d465165d4e 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSetFromMapTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSetFromMapTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.{lang => jl, util => ju} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSetsTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSetsTest.scala index 087add78a8..b7e1087ff5 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSetsTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSetsTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.{util => ju, lang => jl} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSynchronizedCollectionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSynchronizedCollectionTest.scala index 43bcba24a0..d29a26574b 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSynchronizedCollectionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSynchronizedCollectionTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.{util => ju} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSynchronizedListTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSynchronizedListTest.scala index e86beca3c5..346646a42e 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSynchronizedListTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSynchronizedListTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.{util => ju} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSynchronizedMapTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSynchronizedMapTest.scala index 5f9d2fcfc8..24aed2e475 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSynchronizedMapTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSynchronizedMapTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.{util => ju} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSynchronizedSetTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSynchronizedSetTest.scala index f72594088f..1b49dfec7f 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSynchronizedSetTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsOnSynchronizedSetTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.{util => ju} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsTest.scala index 6df862a77a..1f0646b6d3 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/CollectionsTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.{util => ju} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/DateTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/DateTest.scala index dca8e11a1b..77e56b0f76 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/DateTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/DateTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.util.Date diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/DequeTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/DequeTest.scala index 5064532104..5a841b751b 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/DequeTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/DequeTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.{util => ju} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/EventObjectTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/EventObjectTest.scala index c7edca936c..a138de80c6 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/EventObjectTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/EventObjectTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/FormatterTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/FormatterTest.scala index 074f2c4cdf..59b850b95b 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/FormatterTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/FormatterTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import org.junit.Assert._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/HashMapTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/HashMapTest.scala index 8d7e9dc72c..f49c0b5e5a 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/HashMapTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/HashMapTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.{util => ju} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/HashSetTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/HashSetTest.scala index 8560bdc529..071ef2ac7d 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/HashSetTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/HashSetTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import scala.language.implicitConversions diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/HashtableTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/HashtableTest.scala index 5679a71e1a..a2b42c974f 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/HashtableTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/HashtableTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/LinkedHashMapTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/LinkedHashMapTest.scala index e69a983b1f..4b6697046f 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/LinkedHashMapTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/LinkedHashMapTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/LinkedHashSetTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/LinkedHashSetTest.scala index 3cdda88945..61f631c298 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/LinkedHashSetTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/LinkedHashSetTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.{util => ju} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/LinkedListTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/LinkedListTest.scala index 87ea50ef94..4efaa420f1 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/LinkedListTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/LinkedListTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import scala.language.implicitConversions diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ListTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ListTest.scala index 693fdf50ca..bd31245779 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ListTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ListTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/MapTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/MapTest.scala index 81987c50bc..206e4f00fd 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/MapTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/MapTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.{util => ju} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/NavigableSetTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/NavigableSetTest.scala index 8b3d112a02..897c0bafde 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/NavigableSetTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/NavigableSetTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/PriorityQueueTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/PriorityQueueTest.scala index d0b5c53e09..5577e46d56 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/PriorityQueueTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/PriorityQueueTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import scala.language.implicitConversions diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/PropertiesTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/PropertiesTest.scala index 3acb0ea20b..33382e3f5b 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/PropertiesTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/PropertiesTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.util.Properties diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/RandomTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/RandomTest.scala index 7bb2531bfc..87ec4970cd 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/RandomTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/RandomTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import org.junit.Assert._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/SetTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/SetTest.scala index 2da5a71546..df0eb2053c 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/SetTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/SetTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import scala.language.implicitConversions diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/SortedMapTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/SortedMapTest.scala index bd1c5d20cb..c1dfeec498 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/SortedMapTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/SortedMapTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import java.{util => ju} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/SortedSetTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/SortedSetTest.scala index c063d1edbe..fa55f4ae48 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/SortedSetTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/SortedSetTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ThrowablesTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ThrowablesTest.scala index e54e74f5a2..e43f31f9db 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ThrowablesTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/ThrowablesTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/TreeSetTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/TreeSetTest.scala index 65a77f4aa3..3405797cd7 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/TreeSetTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/TreeSetTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import org.junit.Assert._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/UUIDTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/UUIDTest.scala index aa5b6524d6..ba2c8646b3 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/UUIDTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/UUIDTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util import org.junit.Assert._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentHashMapTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentHashMapTest.scala index 34aca88d01..f17cdab590 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentHashMapTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentHashMapTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util.concurrent import scala.language.implicitConversions diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentLinkedQueueTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentLinkedQueueTest.scala index d83669ec68..57790fc102 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentLinkedQueueTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentLinkedQueueTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util.concurrent import java.util.concurrent.ConcurrentLinkedQueue diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentMapTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentMapTest.scala index 3a36df774c..acf35d2e6a 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentMapTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentMapTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util.concurrent import java.{util => ju} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentSkipListSetTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentSkipListSetTest.scala index 58922a02ee..d8ae7a3c52 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentSkipListSetTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/ConcurrentSkipListSetTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util.concurrent import java.util.concurrent.ConcurrentSkipListSet diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/CopyOnWriteArrayListTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/CopyOnWriteArrayListTest.scala index ead4b20004..c2a7b5b053 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/CopyOnWriteArrayListTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/CopyOnWriteArrayListTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util.concurrent import java.{util => ju} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/TimeUnitTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/TimeUnitTest.scala index cc9256a698..a731fd0186 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/TimeUnitTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/TimeUnitTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util.concurrent import java.util.concurrent.TimeUnit diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/atomic/AtomicTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/atomic/AtomicTest.scala index 52ba329adb..570b50d142 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/atomic/AtomicTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/atomic/AtomicTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util.concurrent.atomic import scala.language.implicitConversions diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/locks/ReentrantLockTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/locks/ReentrantLockTest.scala index 90d9ea76dc..896a387a7e 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/locks/ReentrantLockTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/concurrent/locks/ReentrantLockTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util.concurrent.locks import java.util.concurrent.locks.ReentrantLock diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/package.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/package.scala index bb25a6847b..ae30e1d439 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/package.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/package.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib package object util { diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexMatcherTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexMatcherTest.scala index fb01d3beb2..f2d910cbde 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexMatcherTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexMatcherTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util.regex import scala.language.implicitConversions diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexPatternTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexPatternTest.scala index 7a17b7f419..1b71a90b71 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexPatternTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexPatternTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.javalib.util.regex import scala.language.implicitConversions diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/junit/JUnitAnnotationsParamTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/junit/JUnitAnnotationsParamTest.scala index 1502dac467..ade6013884 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/junit/JUnitAnnotationsParamTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/junit/JUnitAnnotationsParamTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.junit import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/junit/JUnitAnnotationsTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/junit/JUnitAnnotationsTest.scala index caff831d62..073ce6e5ec 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/junit/JUnitAnnotationsTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/junit/JUnitAnnotationsTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.junit import org.junit._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/junit/JUnitAssertionsTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/junit/JUnitAssertionsTest.scala index 83d5d82b2d..b4b76ab23e 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/junit/JUnitAssertionsTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/junit/JUnitAssertionsTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.junit import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/junit/JUnitAssumptionsTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/junit/JUnitAssumptionsTest.scala index 165d6622c1..1616580123 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/junit/JUnitAssumptionsTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/junit/JUnitAssumptionsTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.junit import org.hamcrest.CoreMatchers._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BaseBufferTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BaseBufferTest.scala index 52793ce68f..fbbad172f3 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BaseBufferTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BaseBufferTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niobuffer import java.nio.{ReadOnlyBufferException, BufferUnderflowException, InvalidMarkException, BufferOverflowException} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BufferAdapter.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BufferAdapter.scala index 87112d78ab..037630a17b 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BufferAdapter.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BufferAdapter.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niobuffer import java.nio._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BufferFactory.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BufferFactory.scala index 2a41c6675c..6738efc067 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BufferFactory.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/BufferFactory.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niobuffer import java.nio._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/ByteBufferFactories.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/ByteBufferFactories.scala index fe8393d36c..7fc8205d2f 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/ByteBufferFactories.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/ByteBufferFactories.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niobuffer import java.nio._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/ByteBufferTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/ByteBufferTest.scala index 7c86ea19d2..ebf509f35e 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/ByteBufferTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/ByteBufferTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niobuffer import java.nio._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/CharBufferTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/CharBufferTest.scala index e640d2f62f..3587345261 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/CharBufferTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/CharBufferTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niobuffer import java.nio._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/DoubleBufferTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/DoubleBufferTest.scala index 51c7aae984..2fc021bd3c 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/DoubleBufferTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/DoubleBufferTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niobuffer import java.nio._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/FloatBufferTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/FloatBufferTest.scala index 1437349300..be2b1e7b26 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/FloatBufferTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/FloatBufferTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niobuffer import java.nio._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/IntBufferTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/IntBufferTest.scala index 90aeabbae5..a820bb8a6d 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/IntBufferTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/IntBufferTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niobuffer import java.nio._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/LongBufferTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/LongBufferTest.scala index cd1c8084b7..24cb5193a6 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/LongBufferTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/LongBufferTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niobuffer import java.nio._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/ShortBufferTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/ShortBufferTest.scala index 03b5b52007..f16fa2a471 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/ShortBufferTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/ShortBufferTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niobuffer import java.nio._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/BaseCharsetTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/BaseCharsetTest.scala index bece4d3f55..9e655e4c83 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/BaseCharsetTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/BaseCharsetTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niocharset import scala.language.implicitConversions diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/CharsetTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/CharsetTest.scala index 679bfa43da..788e573231 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/CharsetTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/CharsetTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niocharset import scala.collection.JavaConverters._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/Latin1Test.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/Latin1Test.scala index f7fd18e7fd..11ea2c79a3 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/Latin1Test.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/Latin1Test.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niocharset import java.nio._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/USASCIITest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/USASCIITest.scala index 2c517d4597..1dc84e4fbe 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/USASCIITest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/USASCIITest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niocharset import java.nio.charset._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/UTF16Test.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/UTF16Test.scala index 412d98c29f..492b7d7bb0 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/UTF16Test.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/UTF16Test.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niocharset import java.nio._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/UTF8Test.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/UTF8Test.scala index 04eee371e2..fe52d80adb 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/UTF8Test.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/niocharset/UTF8Test.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.niocharset import java.nio._ diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ArrayBuilderTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ArrayBuilderTest.scala index 769a24c999..fe71fe3b2a 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ArrayBuilderTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ArrayBuilderTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013--2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.scalalib import scala.language.implicitConversions diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ArrayTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ArrayTest.scala index 18f4e2cae3..461666cdd4 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ArrayTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ArrayTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013--2018, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.scalalib import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ClassTagTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ClassTagTest.scala index 066a7d656d..acdd214dea 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ClassTagTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ClassTagTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.scalalib import scala.language.implicitConversions diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/EnumerationTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/EnumerationTest.scala index facbe88e00..158227fa60 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/EnumerationTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/EnumerationTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.scalalib import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/NameTransformerTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/NameTransformerTest.scala index b125661a48..ffdaeb6d3c 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/NameTransformerTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/NameTransformerTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.scalalib import scala.reflect.NameTransformer diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/RangesTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/RangesTest.scala index e904495ba2..ad0e606b84 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/RangesTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/RangesTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.scalalib import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ScalaRunTimeTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ScalaRunTimeTest.scala index 67362d672e..1eb98a106b 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ScalaRunTimeTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/ScalaRunTimeTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.scalalib import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/SymbolTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/SymbolTest.scala index 9458ae42be..d627c94eea 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/SymbolTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/scalalib/SymbolTest.scala @@ -1,10 +1,15 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js Test Suite ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.scalalib import org.junit.Test diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/utils/AssertThrows.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/utils/AssertThrows.scala index ad28a79747..d15acbc9ad 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/utils/AssertThrows.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/utils/AssertThrows.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.utils import scala.util.{Failure, Try, Success} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/utils/CollectionsTestBase.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/utils/CollectionsTestBase.scala index 6c28f85e39..8c23de37f2 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/utils/CollectionsTestBase.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/utils/CollectionsTestBase.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.testsuite.utils import java.{lang => jl, util => ju} diff --git a/tools/js/src/main/scala/org/scalajs/core/tools/io/IRContainerPlatformExtensions.scala b/tools/js/src/main/scala/org/scalajs/core/tools/io/IRContainerPlatformExtensions.scala index 191aa37329..1513b11b30 100644 --- a/tools/js/src/main/scala/org/scalajs/core/tools/io/IRContainerPlatformExtensions.scala +++ b/tools/js/src/main/scala/org/scalajs/core/tools/io/IRContainerPlatformExtensions.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.io diff --git a/tools/js/src/main/scala/org/scalajs/core/tools/io/NodeVirtualFiles.scala b/tools/js/src/main/scala/org/scalajs/core/tools/io/NodeVirtualFiles.scala index 1bcfb21d55..e39c71d941 100644 --- a/tools/js/src/main/scala/org/scalajs/core/tools/io/NodeVirtualFiles.scala +++ b/tools/js/src/main/scala/org/scalajs/core/tools/io/NodeVirtualFiles.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.io import scala.scalajs.js diff --git a/tools/js/src/main/scala/org/scalajs/core/tools/json/Impl.scala b/tools/js/src/main/scala/org/scalajs/core/tools/json/Impl.scala index bb328e4bcd..f5efb45956 100644 --- a/tools/js/src/main/scala/org/scalajs/core/tools/json/Impl.scala +++ b/tools/js/src/main/scala/org/scalajs/core/tools/json/Impl.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.json import org.scalajs.core.tools.io.IO diff --git a/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala b/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala index 2201e8e35e..5960770f6d 100644 --- a/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala +++ b/tools/js/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker diff --git a/tools/js/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala b/tools/js/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala index af3e689ef7..c0c476146a 100644 --- a/tools/js/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala +++ b/tools/js/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker diff --git 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 index 0720215cf8..c055872062 100644 --- 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,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.test.js import org.scalajs.core.tools.io._ diff --git a/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala b/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala index ee43bb95a1..222d0ecc4d 100644 --- a/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala +++ b/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.test.js import scala.scalajs.js diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/io/AtomicFileOutputStream.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/io/AtomicFileOutputStream.scala index 0eb7c9c278..49dba11e5d 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/io/AtomicFileOutputStream.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/io/AtomicFileOutputStream.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.io import java.io._ diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/io/AtomicWritableFileVirtualFiles.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/io/AtomicWritableFileVirtualFiles.scala index 8adc439215..0c3877aefa 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/io/AtomicWritableFileVirtualFiles.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/io/AtomicWritableFileVirtualFiles.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.io import java.io._ diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala index 23dc8f8efb..da792c79f0 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.io import java.io._ diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/io/IRContainerPlatformExtensions.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/io/IRContainerPlatformExtensions.scala index d26ebd519d..6355657e51 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/io/IRContainerPlatformExtensions.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/io/IRContainerPlatformExtensions.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.io diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/json/Impl.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/json/Impl.scala index 08e9f88498..f2ecd02fa5 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/json/Impl.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/json/Impl.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.json import org.json.simple.JSONValue diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala index cdc6f1c660..08e62d7d52 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/LinkerPlatformExtensions.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala index 58c6befd4b..a61556975f 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/StandardLinkerPlatformExtensions.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstBuilder.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstBuilder.scala index 9a9923eec5..50c9b1bba3 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstBuilder.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstBuilder.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.linker.backend.closure import org.scalajs.core.ir diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala index e3e44ea032..4b009df5a2 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureAstTransformer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.linker.backend.closure import scala.annotation.switch diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala index 4ed5fc83f3..a36f84ee3a 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.backend.closure diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/LoggerErrorManager.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/LoggerErrorManager.scala index ba25453aff..eb2b8867a7 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/LoggerErrorManager.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/LoggerErrorManager.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.linker.backend.closure import com.google.javascript.jscomp.{ BasicErrorManager, CheckLevel, JSError } diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ConcurrencyUtils.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ConcurrencyUtils.scala index c76941e04f..d6babb2233 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ConcurrencyUtils.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ConcurrencyUtils.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.frontend.optimizer diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ParIncOptimizer.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ParIncOptimizer.scala index 89ed78b597..4a01075462 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ParIncOptimizer.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/ParIncOptimizer.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.frontend.optimizer diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/CacheUtils.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/CacheUtils.scala index 73acad5e74..65337914ea 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/CacheUtils.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/CacheUtils.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.io object CacheUtils { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/IO.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/IO.scala index 763a787105..b5848af8fd 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/IO.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/IO.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.io import scala.annotation.tailrec diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala index ec1c20d8dd..c43471c6d8 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/IRFileCache.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.io diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/MemFiles.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/MemFiles.scala index 3075058fd9..4f95a463f3 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/MemFiles.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/MemFiles.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.io diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala index 23849532bc..ffa315cddc 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/io/VirtualFiles.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.io import java.io._ diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/ESLevel.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/ESLevel.scala index 7cc3cd14c5..89c67f9f84 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/ESLevel.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/ESLevel.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.javascript diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/JSBuilders.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/JSBuilders.scala index 77cb982fb0..a85c0bca98 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/JSBuilders.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/JSBuilders.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.javascript diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala index 03db778d6a..47c4a93569 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.javascript diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/SourceMapWriter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/SourceMapWriter.scala index 7cd10d9142..6915fabb36 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/SourceMapWriter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/SourceMapWriter.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.javascript diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala index 6a0ce1f907..0193551f1a 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.javascript diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/package.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/package.scala index 610a8170a1..f7a618ad46 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/package.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/package.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools package object javascript { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ComplianceRequirement.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ComplianceRequirement.scala index bcbe0a392b..0202f704de 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ComplianceRequirement.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ComplianceRequirement.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.jsdep import org.scalajs.core.tools.sem.Semantics diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/DependencyResolver.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/DependencyResolver.scala index f7ae2e7374..48d040ae76 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/DependencyResolver.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/DependencyResolver.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.jsdep import scala.collection.mutable diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/Exceptions.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/Exceptions.scala index e490ba8f0e..1664e3e079 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/Exceptions.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/Exceptions.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.jsdep abstract class DependencyException(msg: String) extends Exception(msg) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/FlatJSDependency.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/FlatJSDependency.scala index 22be728071..fe93d4fbc4 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/FlatJSDependency.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/FlatJSDependency.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.jsdep import org.scalajs.core.ir.Trees.isValidIdentifier diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/JSDependency.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/JSDependency.scala index d9c175ad96..2e3a651875 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/JSDependency.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/JSDependency.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.jsdep import org.scalajs.core.tools.json._ diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/JSDependencyManifest.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/JSDependencyManifest.scala index 368cb9edfa..54f3a3e77c 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/JSDependencyManifest.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/JSDependencyManifest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.jsdep import org.scalajs.core.tools.json._ diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ManifestFilters.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ManifestFilters.scala index 5db45ef29f..80b361a0f7 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ManifestFilters.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ManifestFilters.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.jsdep /** Holds useful JSDependencyManifest filters */ diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/Origin.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/Origin.scala index b330662fde..b934dde955 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/Origin.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/Origin.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.jsdep import org.scalajs.core.tools.json._ diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ResolutionInfo.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ResolutionInfo.scala index c5e3b5baf3..baf73fbdb5 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ResolutionInfo.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ResolutionInfo.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.jsdep import org.scalajs.core.ir.Trees.isValidIdentifier diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ResolvedJSDependency.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ResolvedJSDependency.scala index e5faf6078e..a9976cbfdd 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ResolvedJSDependency.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/jsdep/ResolvedJSDependency.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.jsdep import org.scalajs.core.tools.io._ diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/json/AbstractJSONImpl.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/json/AbstractJSONImpl.scala index 2aa8dc4955..9e5f176fb6 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/json/AbstractJSONImpl.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/json/AbstractJSONImpl.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.json import java.io.{Reader, Writer} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONDeserializer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONDeserializer.scala index fd45c21ac2..960f9ad178 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONDeserializer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONDeserializer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.json trait JSONDeserializer[T] { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONObjBuilder.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONObjBuilder.scala index 0834b5740f..983550b870 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONObjBuilder.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONObjBuilder.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.json import scala.collection.mutable diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONObjExtractor.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONObjExtractor.scala index f9baa9cb88..c6f8ef76dc 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONObjExtractor.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONObjExtractor.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.json import scala.collection.mutable diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONSerializer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONSerializer.scala index 04d0f05347..791485e975 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONSerializer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/json/JSONSerializer.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.json trait JSONSerializer[T] { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/json/package.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/json/package.scala index be4d8f0ac7..da5738b7f0 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/json/package.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/json/package.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools import java.io.{Reader, Writer} diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ClearableLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ClearableLinker.scala index b5592f8207..21a22931bf 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ClearableLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ClearableLinker.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala index 5564e56c07..1c4a409a7c 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/GenLinker.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala index d7541755a9..f1dbdf1267 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedClass.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedMember.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedMember.scala index 4b2b5b188a..9d02538a7b 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedMember.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkedMember.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala index 6aa9921f16..fd7fcc52bb 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/Linker.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingException.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingException.scala index 4d6e8a93a7..a1241deae6 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingException.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingException.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala index 2aedf0611c..710586c68f 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/LinkingUnit.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.linker import org.scalajs.core.tools.javascript.ESLevel diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ModuleInitializer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ModuleInitializer.scala index 7189519f01..f41c38d052 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ModuleInitializer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/ModuleInitializer.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker 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 02ce26dff7..295092b6ab 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 @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala index 33475cbe33..c692e43375 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analysis.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.analyzer diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala index 1f2961f0bf..25aa7b8ad4 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/Analyzer.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.analyzer diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/SymbolRequirement.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/SymbolRequirement.scala index 03244da15c..9ba404d009 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/SymbolRequirement.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/analyzer/SymbolRequirement.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.analyzer diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala index a0659a3600..7b55a32fa9 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/BasicLinkerBackend.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.backend diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala index 53c984d31c..8be42b7360 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/LinkerBackend.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.backend diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/ModuleKind.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/ModuleKind.scala index 477a6d6b54..974cb34bb9 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/ModuleKind.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/ModuleKind.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.backend diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala index 53fa36e7b9..8414def688 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/OutputMode.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.backend diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index 111ef242d2..068d202f34 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.backend.emitter diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala index f86dcfe8c0..6ee4e3178d 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/CoreJSLibs.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.backend.emitter diff --git 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 index 30cab7a77b..65cb4b7acf 100644 --- 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 @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.backend.emitter diff --git 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 index c3eedd4973..1f6711f847 100644 --- 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 @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.backend.emitter diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala index 036dcca7c8..408c707b2b 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/GlobalKnowledge.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.backend.emitter diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/InternalOptions.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/InternalOptions.scala index 995a1664af..fb30895a85 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/InternalOptions.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/InternalOptions.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.backend.emitter diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala index a60eae073a..bce65cedd1 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.backend.emitter diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala index 34f76a37f2..a2a6a83570 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/KnowledgeGuardian.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2016, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.backend.emitter diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/LongImpl.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/LongImpl.scala index f293d6c118..8e92559eb0 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/LongImpl.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/LongImpl.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.backend.emitter diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/TreeDSL.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/TreeDSL.scala index a90ea68abf..ef4608c640 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/TreeDSL.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/TreeDSL.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.backend.emitter diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala index 16f3bab15b..c2d4ffe33a 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/IRChecker.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.checker diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/InfoChecker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/InfoChecker.scala index 18cfa7afb7..f1e00d205a 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/InfoChecker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/checker/InfoChecker.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.checker diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala index cb589bc4d1..a7d3404133 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/BaseLinker.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.frontend diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala index 013201462a..042e93d818 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/LinkerFrontend.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.frontend diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala index 28a5e3cdf1..4157f84b58 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/Refiner.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2015, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.frontend diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala index e57fd4ea4d..663f41cb77 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/GenIncOptimizer.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.frontend.optimizer diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/IncOptimizer.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/IncOptimizer.scala index 07566bf137..b620d69a33 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/IncOptimizer.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/IncOptimizer.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.frontend.optimizer diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala index 45a05ae6ee..88edac0286 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/frontend/optimizer/OptimizerCore.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker.frontend.optimizer diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/package.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/package.scala index e1e6e78e55..ba802ef2cf 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/package.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/package.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/package.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/package.scala index 530409962e..68afafec8b 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/package.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/standard/package.scala @@ -1,10 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2017, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.linker diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/logging/Level.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/logging/Level.scala index 196b9809c5..0928d4b34d 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/logging/Level.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/logging/Level.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.logging diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/logging/Logger.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/logging/Logger.scala index 8277ae91ca..12fa9b1660 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/logging/Logger.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/logging/Logger.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.logging diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/logging/NullLogger.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/logging/NullLogger.scala index 15a911acb0..5fc7062d02 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/logging/NullLogger.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/logging/NullLogger.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.logging object NullLogger extends Logger { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/logging/ScalaConsoleLogger.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/logging/ScalaConsoleLogger.scala index 36619040b7..7bb65324a5 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/logging/ScalaConsoleLogger.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/logging/ScalaConsoleLogger.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.logging class ScalaConsoleLogger(minLevel: Level = Level.Debug) extends Logger { diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/sem/CheckedBehavior.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/sem/CheckedBehavior.scala index 5a43c7ee71..68932d77df 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/sem/CheckedBehavior.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/sem/CheckedBehavior.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.sem diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/sem/Semantics.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/sem/Semantics.scala index 96b4a5dfe4..dd26e7fd5e 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/sem/Semantics.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/sem/Semantics.scala @@ -1,11 +1,14 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ package org.scalajs.core.tools.sem diff --git a/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ComplianceRequirementTest.scala b/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ComplianceRequirementTest.scala index 027ea46036..d13c9cac70 100644 --- a/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ComplianceRequirementTest.scala +++ b/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ComplianceRequirementTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.jsdep import org.scalajs.core.tools.sem.Semantics diff --git a/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ManifestFiltersTest.scala b/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ManifestFiltersTest.scala index 9a38d24501..f7ca3928ec 100644 --- a/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ManifestFiltersTest.scala +++ b/tools/shared/src/test/scala/org/scalajs/core/tools/jsdep/ManifestFiltersTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.jsdep import org.junit.Test diff --git a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala index f0b7e5af40..4f6de2a146 100644 --- a/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala +++ b/tools/shared/src/test/scala/org/scalajs/core/tools/linker/LinkerTest.scala @@ -1,3 +1,15 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package org.scalajs.core.tools.linker import org.junit.Test From e5d3d6b495d9aaf4e2b3aadbe24598071317242c Mon Sep 17 00:00:00 2001 From: Ondrej Kraus Date: Fri, 12 Oct 2018 01:57:40 +0200 Subject: [PATCH 0841/2665] Fix #3280: Count capturing groups independently on find. --- .../main/scala/java/util/regex/Matcher.scala | 27 ++++++++++++++++--- .../javalib/util/regex/RegexMatcherTest.scala | 10 +++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/javalib/src/main/scala/java/util/regex/Matcher.scala b/javalib/src/main/scala/java/util/regex/Matcher.scala index 53f4c3a45d..7bfe84fbd2 100644 --- a/javalib/src/main/scala/java/util/regex/Matcher.scala +++ b/javalib/src/main/scala/java/util/regex/Matcher.scala @@ -24,6 +24,9 @@ final class Matcher private[regex] ( private var lastMatchIsValid = false private var canStillFind = true + // Group count + private var lastGroupCount: Option[Int] = None + // Append state (updated by replacement methods) private var appendPos: Int = 0 @@ -160,6 +163,7 @@ final class Matcher private[regex] ( regexp = pattern.newJSRegExp() regexp.lastIndex = prevLastIndex lastMatch = null + lastGroupCount = None startOfGroupCache = None this } @@ -172,7 +176,21 @@ final class Matcher private[regex] ( lastMatch } - def groupCount(): Int = ensureLastMatch.length-1 + def groupCount(): Int = { + if (lastMatch != null) { + lastMatch.length-1 + } else { + lastGroupCount match { + case Some(n) => n + + case None => + val groupCountRegex = new js.RegExp("|" + pattern0.jsPattern) + val newGroupCount = groupCountRegex.exec("").length-1 + lastGroupCount = Some(newGroupCount) + newGroupCount + } + } + } def start(): Int = ensureLastMatch.index def end(): Int = start() + group().length @@ -198,7 +216,7 @@ final class Matcher private[regex] ( // Seal the state - def toMatchResult(): MatchResult = new SealedResult(inputstr, lastMatch, pattern()) + def toMatchResult(): MatchResult = new SealedResult(inputstr, lastMatch, pattern(), groupCount()) // Other query state methods @@ -249,10 +267,11 @@ object Matcher { } private final class SealedResult(inputstr: String, - lastMatch: js.RegExp.ExecResult, pattern: Pattern) + lastMatch: js.RegExp.ExecResult, pattern: Pattern, + lastGroupCount: Int) extends MatchResult { - def groupCount(): Int = ensureLastMatch.length-1 + def groupCount(): Int = lastGroupCount def start(): Int = ensureLastMatch.index def end(): Int = start() + group().length diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexMatcherTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexMatcherTest.scala index fb01d3beb2..4e487b41eb 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexMatcherTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/regex/RegexMatcherTest.scala @@ -102,6 +102,7 @@ class RegexMatcherTest { def parseExpect(regex: String, str: String, pos: (Int, Int)*): Unit = { val matcher = Pattern.compile(regex).matcher(str) + assertEquals(pos.length - 1, matcher.groupCount) assertTrue(matcher.find()) assertEquals(pos.length - 1, matcher.groupCount) var i = 0 @@ -159,6 +160,8 @@ class RegexMatcherTest { } def checkGroups(matcher: Matcher, startEndMatch: (Int, Int, String)*): Unit = { + assertEquals(startEndMatch.size - 1, matcher.groupCount) + assertTrue(matcher.find()) assertEquals(startEndMatch(0)._1, matcher.start) @@ -233,6 +236,13 @@ class RegexMatcherTest { assertTrue(matcher1.matches()) matcher1.usePattern(patternNoDots) assertFalse(matcher1.matches()) + + val patternWithOneGroup = Pattern.compile("ab(cd)efg") + val patternWithTwoGroups = Pattern.compile("ab(cd)(ef)g") + val matcher2 = patternWithOneGroup.matcher("Scala.js") + assertEquals(1, matcher2.groupCount()) + matcher2.usePattern(patternWithTwoGroups) + assertEquals(2, matcher2.groupCount()) } @Test def lookingAt(): Unit = { From ad6fb421d22f9bcef9e991d1ada8ea19bf395460 Mon Sep 17 00:00:00 2001 From: teresy Date: Wed, 17 Oct 2018 12:01:03 -0400 Subject: [PATCH 0842/2665] Refactoring only: simplify one foldLeft(_ && _) with a forall. --- .../main/scala/org/scalajs/testing/interface/HTMLRunner.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-interface/src/main/scala/org/scalajs/testing/interface/HTMLRunner.scala b/test-interface/src/main/scala/org/scalajs/testing/interface/HTMLRunner.scala index 754b0202c3..e545b2faf0 100644 --- a/test-interface/src/main/scala/org/scalajs/testing/interface/HTMLRunner.scala +++ b/test-interface/src/main/scala/org/scalajs/testing/interface/HTMLRunner.scala @@ -519,5 +519,5 @@ protected[interface] object HTMLRunner { } private def and(xs: collection.Seq[Boolean]): Boolean = - xs.foldLeft(true)(_ && _) + xs.forall(identity) } From 206f6f3839d872dba325df1532cb811db1b51218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 18 Oct 2018 11:21:27 +0200 Subject: [PATCH 0843/2665] Fix one license header. It is only relevant in 2.11.{0-2}, so it was only caught by the nightly build. --- .../tools/partest/scalajs/ScalaJSPartest.scala | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/partest/src/main-partest-1.0.13/scala/tools/partest/scalajs/ScalaJSPartest.scala b/partest/src/main-partest-1.0.13/scala/tools/partest/scalajs/ScalaJSPartest.scala index da418ec3f0..f84aeb0628 100644 --- a/partest/src/main-partest-1.0.13/scala/tools/partest/scalajs/ScalaJSPartest.scala +++ b/partest/src/main-partest-1.0.13/scala/tools/partest/scalajs/ScalaJSPartest.scala @@ -1,6 +1,13 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2013 LAMP/EPFL - * @author Sébastien Doeraene +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ package scala.tools.partest From fa0ff83037e2f76d62215f3216018f6a604e0b53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 18 Oct 2018 21:00:44 +0200 Subject: [PATCH 0844/2665] Version 1.0.0-M6. --- ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala index e40fedf118..b0acae5474 100644 --- a/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala @@ -22,7 +22,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "1.0.0-SNAPSHOT" + val current: String = "1.0.0-M6" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" From fde0cfe056812932da77673d23927c4fc0afbd40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 19 Oct 2018 20:46:58 +0200 Subject: [PATCH 0845/2665] Towards 1.0.0 again. --- ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala index b0acae5474..e40fedf118 100644 --- a/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/ir/ScalaJSVersions.scala @@ -22,7 +22,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "1.0.0-M6" + val current: String = "1.0.0-SNAPSHOT" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" From f5a13670f9ce9310b0b1a5d5510d615dc6557489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 24 Oct 2018 13:23:05 +0200 Subject: [PATCH 0846/2665] Fix #3476: Specify that com messages must be valid UTF-16 strings. * Document it in the Scaladoc of `startWithCom` * Assert that all messages are valid in the `TestKit` * Fix `ComTests.largeMessageTest` not to use an invalid message --- .../org/scalajs/jsenv/test/ComTests.scala | 9 ++++-- .../org/scalajs/jsenv/test/kit/ComRun.scala | 30 +++++++++++++++++++ .../main/scala/org/scalajs/jsenv/JSEnv.scala | 5 ++++ .../main/scala/org/scalajs/jsenv/JSRuns.scala | 4 +++ 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala index 10103c91be..2d32118bba 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/ComTests.scala @@ -103,8 +103,13 @@ private[test] class ComTests(config: JSEnvSuiteConfig) { @Test def largeMessageTest: Unit = { - // 1MB data - replyTest(new String(Array.tabulate(1024 * 1024)(_.toChar))) + /* 1MB data. + * (i & 0x7f) limits the input to the ASCII repertoire, which will use + * exactly 1 byte per Char in UTF-8. This restriction also ensures that we + * do not introduce surrogate characters and therefore no invalid UTF-16 + * strings. + */ + replyTest(new String(Array.tabulate(1024 * 1024)(i => (i & 0x7f).toChar))) } @Test diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/kit/ComRun.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/kit/ComRun.scala index 0a3770dd6b..3a6d50541a 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/kit/ComRun.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/kit/ComRun.scala @@ -31,6 +31,7 @@ class ComRun private[kit] (run: JSComRun, out: IOReader, err: IOReader, /** Calls [[JSComRun#send]] on the underlying run. */ final def send(msg: String): this.type = { + requireValidMessage(msg) run.send(msg) this } @@ -41,12 +42,41 @@ class ComRun private[kit] (run: JSComRun, out: IOReader, err: IOReader, * @throws java.util.concurrent.TimeoutException if there is no message for too long. */ final def expectMsg(expected: String): this.type = { + requireValidMessage(expected) require(!noMessages, "You may not call expectMsg after calling expectNoMsgs") val actual = msgs.waitOnMessage(timeout.fromNow) assertEquals("got bad message", expected, actual) this } + private def requireValidMessage(msg: String): Unit = { + val len = msg.length + var i = 0 + while (i < len) { + val c = msg.charAt(i) + + def fail(lowOrHigh: String): Nothing = { + val msgDescription = + if (len > 128) s"Message (of length $len)" + else s"Message '$msg'" + throw new IllegalArgumentException( + s"$msgDescription is not a valid message because it contains an " + + s"unpaired $lowOrHigh surrogate 0x${c.toInt.toHexString} at index $i") + } + + if (Character.isSurrogate(c)) { + if (Character.isLowSurrogate(c)) + fail("low") + else if (i == len - 1 || !Character.isLowSurrogate(msg.charAt(i + 1))) + fail("high") + else + i += 2 + } else { + i += 1 + } + } + } + /** Marks that no further messages are expected. * * This will make the methods [[closeRun]] / [[fails]] / [[succeeds]] fail if diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala index 2eb9ba9441..091afeb168 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/JSEnv.scala @@ -51,6 +51,11 @@ trait JSEnv { * scalajsCom.send("my message"); * }}} * + * All messages, sent in both directions, must be valid UTF-16 strings, + * i.e., they must not contain any unpaired surrogate character. The + * behavior of a communication channel is unspecified if this requirement is + * not met. + * * We describe the expected message delivery guarantees by denoting the * transmitter as `t` and the receiver as `r`. Both the JVM and the JS end * act once as a transmitter and once as a receiver. These two diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/JSRuns.scala b/js-envs/src/main/scala/org/scalajs/jsenv/JSRuns.scala index 7a7851ef5e..57303d6952 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/JSRuns.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/JSRuns.scala @@ -62,6 +62,10 @@ object JSRun { /** A [[JSRun]] that has a communication channel to the running JS code. */ trait JSComRun extends JSRun { /** Sends a message to the JS end. + * + * The `msg` must be a valid UTF-16 string, i.e., it must not contain any + * unpaired surrogate character. The behavior of the communication channel + * is unspecified if this requirement is not met. * * Async, nothrow. See [[JSEnv#startWithCom]] for expected message delivery * guarantees. From f1490408e4e4c9de816dba2791be608b4103e2f6 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 3 Nov 2018 08:22:35 +0100 Subject: [PATCH 0847/2665] Remove FixMethodOrder and related code. The plugin rejected its usage anyways. It is much easier to not define the symbol alltogether. --- .../junit/plugin/ScalaJSJUnitPlugin.scala | 7 ------ .../main/scala/org/junit/FixMethodOrder.scala | 16 ------------ .../org/junit/runners/MethodSorters.scala | 25 ------------------- .../scalajs/junit/JUnitTestBootstrapper.scala | 16 ++---------- 4 files changed, 2 insertions(+), 62 deletions(-) delete mode 100644 junit-runtime/src/main/scala/org/junit/FixMethodOrder.scala delete mode 100644 junit-runtime/src/main/scala/org/junit/runners/MethodSorters.scala diff --git a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala index 7bfb1b9172..d727bd4c53 100644 --- a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala +++ b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala @@ -120,9 +120,6 @@ class ScalaJSJUnitPlugin(val global: Global) extends NscPlugin { private val TestClass = getRequiredClass("org.junit.Test") - private val FixMethodOrderClass = - getRequiredClass("org.junit.FixMethodOrder") - private val annotationWhiteList = List( TestClass, getRequiredClass("org.junit.Before"), @@ -371,10 +368,6 @@ class ScalaJSJUnitPlugin(val global: Global) extends NscPlugin { reporter.error(ann.pos, "@Test(timeout = ...) is not " + "supported in Scala.js JUnit Framework") - case ann if ann.atp.typeSymbol == FixMethodOrderClass => - reporter.error(ann.pos, "@FixMethodOrder(...) is not supported " + - "in Scala.js JUnit Framework") - case _ => // all is well } diff --git a/junit-runtime/src/main/scala/org/junit/FixMethodOrder.scala b/junit-runtime/src/main/scala/org/junit/FixMethodOrder.scala deleted file mode 100644 index 4096184fa4..0000000000 --- a/junit-runtime/src/main/scala/org/junit/FixMethodOrder.scala +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Ported from https://github.com/junit-team/junit - */ -package org.junit - -import java.lang.annotation._ - -import org.junit.runners.MethodSorters - -class FixMethodOrder(val value: MethodSorters) - extends Annotation { - - def this() = this(MethodSorters.DEFAULT) - - def annotationType(): Class[_ <: Annotation] = classOf[FixMethodOrder] -} diff --git a/junit-runtime/src/main/scala/org/junit/runners/MethodSorters.scala b/junit-runtime/src/main/scala/org/junit/runners/MethodSorters.scala deleted file mode 100644 index 6b96a4caca..0000000000 --- a/junit-runtime/src/main/scala/org/junit/runners/MethodSorters.scala +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Ported from https://github.com/junit-team/junit - */ -package org.junit.runners - -object MethodSorters { - - private lazy val _NAME_ASCENDING = new MethodSorters((x, y) => x.compareTo(y)) - private lazy val _JVM = new MethodSorters((x, y) => 0) - private lazy val _DEFAULT = _NAME_ASCENDING - - def NAME_ASCENDING: MethodSorters = _NAME_ASCENDING - - def JVM: MethodSorters = _JVM - - def DEFAULT: MethodSorters = _DEFAULT -} - -class MethodSorters private (f: (String, String) => Int) { - lazy val comparator: Ordering[String] = { - new Ordering[String] { - def compare(x: String, y: String): Int = f(x, y) - } - } -} diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTestBootstrapper.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTestBootstrapper.scala index d61b22c9dc..3faf503205 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTestBootstrapper.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTestBootstrapper.scala @@ -14,8 +14,6 @@ package org.scalajs.junit import java.lang.annotation.Annotation -import org.junit.FixMethodOrder - import scala.scalajs.reflect.annotation._ @EnableReflectiveInstantiation @@ -54,12 +52,8 @@ final class JUnitClassMetadata(classAnnotations: List[Annotation], moduleAnnotations: List[Annotation], classMethods: List[JUnitMethodMetadata], moduleMethods: List[JUnitMethodMetadata]) { - def testMethods: List[JUnitMethodMetadata] = { - val fixMethodOrderAnnotation = getFixMethodOrderAnnotation - val methodSorter = fixMethodOrderAnnotation.value - val tests = classMethods.filter(_.hasTestAnnotation) - tests.sortWith((a, b) => methodSorter.comparator.lt(a.name, b.name)) - } + def testMethods: List[JUnitMethodMetadata] = + classMethods.filter(_.hasTestAnnotation) def beforeMethod: List[JUnitMethodMetadata] = classMethods.filter(_.hasBeforeAnnotation) @@ -72,10 +66,4 @@ final class JUnitClassMetadata(classAnnotations: List[Annotation], def afterClassMethod: List[JUnitMethodMetadata] = moduleMethods.filter(_.hasAfterClassAnnotation) - - def getFixMethodOrderAnnotation: FixMethodOrder = { - classAnnotations.collectFirst { - case fmo: FixMethodOrder => fmo - }.getOrElse(new FixMethodOrder) - } } From 9404d59827747bd36bb64e09b494bbaa4b423203 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 4 Nov 2018 13:06:10 +0100 Subject: [PATCH 0848/2665] Deprecate namespaced top-level exports. `@JSExportTopLevel` with namespaces (containing a `.`) do not have any appropriate equivalent in ECMAScript modules. This commit deprecates them. As with other exports-related deprecations, the warnings can be suppressed in 0.6.x with `-P:scalajs:suppressExportDeprecations`. --- .../scalajs/core/compiler/PrepJSExports.scala | 8 ++++ .../test/JSExportDeprecationsTest.scala | 40 +++++++++++++++++++ .../core/compiler/test/JSExportTest.scala | 18 +++++++++ project/Build.scala | 11 +++-- .../core/tools/test/js/QuickLinker.scala | 2 +- .../core/tools/test/js/TestRunner.scala | 2 +- 6 files changed, 76 insertions(+), 5 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala index 22ea67bbe7..b9d1710cfc 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala @@ -413,6 +413,14 @@ trait PrepJSExports { this: PrepJSInterop => "Only static objects may export their members to the top level") } + // Warn for namespaced top-level exports + if (name.contains('.') && !scalaJSOpts.suppressExportDeprecations) { + reporter.warning(annot.pos, + "Using a namespaced export (with a '.') in @JSExportTopLevel " + + "is deprecated." + + SuppressExportDeprecationsMsg) + } + case ExportDestination.Static => val symOwner = if (sym.isClassConstructor) sym.owner.owner diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportDeprecationsTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportDeprecationsTest.scala index c6be978961..9c17e53fa7 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportDeprecationsTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportDeprecationsTest.scala @@ -114,4 +114,44 @@ class JSExportDeprecationsTest extends DirectTest with TestHelpers { } } + @Test + def warnJSExportTopLevelNamespaced: Unit = { + """ + @JSExportTopLevel("namespaced.export1") + object A + @JSExportTopLevel("namespaced.export2") + class B + object C { + @JSExportTopLevel("namespaced.export3") + val a: Int = 1 + @JSExportTopLevel("namespaced.export4") + var b: Int = 1 + @JSExportTopLevel("namespaced.export5") + def c(): Int = 1 + } + """ hasWarns + """ + |newSource1.scala:3: warning: Using a namespaced export (with a '.') in @JSExportTopLevel is deprecated. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressExportDeprecations` to scalac) + | @JSExportTopLevel("namespaced.export1") + | ^ + |newSource1.scala:5: warning: Using a namespaced export (with a '.') in @JSExportTopLevel is deprecated. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressExportDeprecations` to scalac) + | @JSExportTopLevel("namespaced.export2") + | ^ + |newSource1.scala:8: warning: Using a namespaced export (with a '.') in @JSExportTopLevel is deprecated. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressExportDeprecations` to scalac) + | @JSExportTopLevel("namespaced.export3") + | ^ + |newSource1.scala:10: warning: Using a namespaced export (with a '.') in @JSExportTopLevel is deprecated. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressExportDeprecations` to scalac) + | @JSExportTopLevel("namespaced.export4") + | ^ + |newSource1.scala:12: warning: Using a namespaced export (with a '.') in @JSExportTopLevel is deprecated. + | (you can suppress this warning in 0.6.x by passing the option `-P:scalajs:suppressExportDeprecations` to scalac) + | @JSExportTopLevel("namespaced.export5") + | ^ + """ + } + } diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index 42a951ff8a..7faa946bb1 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -1890,4 +1890,22 @@ class JSExportTest extends DirectTest with TestHelpers { } """.succeeds } + + @Test + def noWarnJSExportTopLevelNamespacedWhenSuppressed: Unit = { + """ + @JSExportTopLevel("namespaced.export1") + object A + @JSExportTopLevel("namespaced.export2") + class B + object C { + @JSExportTopLevel("namespaced.export3") + val a: Int = 1 + @JSExportTopLevel("namespaced.export4") + var b: Int = 1 + @JSExportTopLevel("namespaced.export5") + def c(): Int = 1 + } + """.hasNoWarns + } } diff --git a/project/Build.scala b/project/Build.scala index 58c9b9cb99..1b710ce5ab 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -719,14 +719,14 @@ object Build { val code = { s""" - var linker = scalajs.QuickLinker; + var linker = ScalaJSQuickLinker; var lib = linker.linkTestSuiteNode($irPaths, $mainMethods); var __ScalaJSEnv = $scalaJSEnv; eval("(function() { 'use strict'; " + lib + ";" + - "scalajs.TestRunner.runTests();" + + "ScalaJSTestRunner.runTests();" + "}).call(this);"); """ } @@ -1263,11 +1263,16 @@ object Build { previousArtifactSetting, mimaBinaryIssueFilters ++= BinaryIncompatibilities.TestInterface, unmanagedSourceDirectories in Compile += - baseDirectory.value.getParentFile / "test-common/src/main/scala" + baseDirectory.value.getParentFile / "test-common/src/main/scala", /* Note: We cannot add the test-common tests, since they test async * stuff and JUnit does not support async tests. Therefore we need to * block, so we cannot run on JS. */ + + /* The test bridge uses namespaced top-level exports that we cannot + * get rid of in 0.6.x. + */ + scalacOptions += "-P:scalajs:suppressExportDeprecations" ) ).withScalaJSCompiler.dependsOn(library) diff --git 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 index c055872062..d0ee2d619a 100644 --- 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 @@ -20,7 +20,7 @@ import org.scalajs.core.tools.logging._ import scala.scalajs.js import scala.scalajs.js.annotation._ -@JSExportTopLevel("scalajs.QuickLinker") +@JSExportTopLevel("ScalaJSQuickLinker") object QuickLinker { /** Link a Scala.js application on Node.js */ diff --git a/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala b/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala index 222d0ecc4d..60c3761720 100644 --- a/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala +++ b/tools/js/src/test/scala/org/scalajs/core/tools/test/js/TestRunner.scala @@ -19,7 +19,7 @@ import org.scalajs.testinterface.{ScalaJSClassLoader, TestDetector} import sbt.testing._ -@JSExportTopLevel("scalajs.TestRunner") +@JSExportTopLevel("ScalaJSTestRunner") object TestRunner { @JSExport From 0f2c4df2a9b85ed41e019479b0d70c7af760ebf2 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Sat, 3 Nov 2018 08:21:47 +0100 Subject: [PATCH 0849/2665] Simplify JUnitPlugin / Bootstrappers --- .../junit/plugin/ScalaJSJUnitPlugin.scala | 520 +++++------------- .../org/scalajs/junit/Bootstrapper.scala | 34 ++ .../org/scalajs/junit/JUnitExecuteTest.scala | 49 +- .../scala/org/scalajs/junit/JUnitTask.scala | 4 +- .../scalajs/junit/JUnitTestBootstrapper.scala | 69 --- .../junit/JUnitAbstractClassTest.scala | 6 +- .../testsuite/junit/JUnitMixinTest.scala | 2 +- .../testsuite/junit/JUnitNamesTest.scala | 6 +- .../testsuite/junit/JUnitSubClassTest.scala | 8 +- .../scalajs/testsuite/junit/JUnitUtil.scala | 6 +- .../MultiCompilationSecondUnitTest.scala | 2 +- 11 files changed, 198 insertions(+), 508 deletions(-) create mode 100644 junit-runtime/src/main/scala/org/scalajs/junit/Bootstrapper.scala delete mode 100644 junit-runtime/src/main/scala/org/scalajs/junit/JUnitTestBootstrapper.scala diff --git a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala index d727bd4c53..a66ce72b76 100644 --- a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala +++ b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala @@ -14,81 +14,22 @@ package org.scalajs.junit.plugin import scala.language.reflectiveCalls +import scala.annotation.tailrec + import scala.reflect.internal.Flags import scala.tools.nsc._ import scala.tools.nsc.plugins.{ Plugin => NscPlugin, PluginComponent => NscPluginComponent } -/** The Scala.js jUnit plugin is a way to overcome the lack of annotation - * information of any test class (usually accessed through reflection). - * This is all the information required by the Scala.js testing framework to - * execute the tests. - * - * As an example we take the following test class: - * {{{ - * class Foo { - * @Before def before(): Unit = { - * // Initialize the instance before the tests - * } - * @Test def bar(): Unit = { - * // assert some stuff - * } - * @Ignore("baz not implemented yet") @Test def baz(): Unit = { - * // assert some other stuff - * } - * } - * - * object Foo { - * @BeforeClass def beforeClass(): Unit = { - * // Initialize some global state for the tests. - * } - * } - * }}} - * - * Will generate the following bootstrapper module: - * - * {{{ - * object Foo\$scalajs\$junit\$bootstrapper extends org.scalajs.junit.JUnitTestBootstrapper { - * - * def metadata(): JUnitClassMetadata = { - * new JUnitClassMetadata( - * classAnnotations = List(), - * moduleAnnotations = List(), - * classMethods = List( - * new JUnitMethodMetadata(name = "before", - * annotations = List(new Before)), - * new JUnitMethodMetadata(name = "bar", - * annotations = List(new Test)), - * new JUnitMethodMetadata(name = "baz", - * annotations = List(new Test, new Ignore("baz not implemented yet"))) - * ), - * moduleMethods( - * new JUnitMethodMetadata(name = "beforeClass", - * annotations = List(new BeforeClass))) - * ) - * } - * - * def newInstance(): AnyRef = new Foo() +/** The Scala.js JUnit plugin replaces reflection based test lookup. * - * def invoke(methodName: String): Unit = { - * if (methodName == "0") Foo.beforeClass() - * else throw new NoSuchMethodException(methodId) - * } + * For each JUnit test `my.pkg.X`, it generates a bootstrapper module/object + * `my.pkg.X\$scalajs\$junit\$bootstrapper` implementing + * `org.scalajs.junit.Bootstrapper`. * - * def invoke(instance: AnyRef, methodName: String): Unit = { - * if (methodName == "before") instance.asInstanceOf[Foo].before() - * else if (methodName == "bar") instance.asInstanceOf[Foo].bar() - * else if (methodName == "baz") instance.asInstanceOf[Foo].baz() - * else throw new NoSuchMethodException(methodId) - * } - * } - * }}} - * The test framework will identify `Foo\$scalajs\$junit\$bootstrapper` as a test module - * because it extends `JUnitTestBootstrapper`. It will know which methods to run based - * on the info returned by Foo\$scalajs\$junit\$bootstrapper.metadata, - * it will create new test instances using `Foo\$scalajs\$junit\$bootstrapper.newInstance()` - * and it will invoke test methods using `invoke` on the bootstrapper. + * The test runner uses these objects to obtain test metadata and dispatch to + * relevant methods. */ class ScalaJSJUnitPlugin(val global: Global) extends NscPlugin { @@ -105,6 +46,8 @@ class ScalaJSJUnitPlugin(val global: Global) extends NscPlugin { val global: Global = ScalaJSJUnitPlugin.this.global import global._ + import definitions._ + import rootMirror.getRequiredClass val phaseName: String = "junit-inject" val runsAfter: List[String] = List("mixin") @@ -113,386 +56,177 @@ class ScalaJSJUnitPlugin(val global: Global) extends NscPlugin { protected def newTransformer(unit: CompilationUnit): Transformer = new ScalaJSJUnitPluginTransformer - class ScalaJSJUnitPluginTransformer extends Transformer { - - import rootMirror.getRequiredClass - - private val TestClass = - getRequiredClass("org.junit.Test") - - private val annotationWhiteList = List( - TestClass, - getRequiredClass("org.junit.Before"), - getRequiredClass("org.junit.After"), - getRequiredClass("org.junit.BeforeClass"), - getRequiredClass("org.junit.AfterClass"), - getRequiredClass("org.junit.Ignore") - ) + private object JUnitAnnots { + val Test = getRequiredClass("org.junit.Test") + val Before = getRequiredClass("org.junit.Before") + val After = getRequiredClass("org.junit.After") + val BeforeClass = getRequiredClass("org.junit.BeforeClass") + val AfterClass = getRequiredClass("org.junit.AfterClass") + val Ignore = getRequiredClass("org.junit.Ignore") + } - private val jUnitClassMetadataType = - getRequiredClass("org.scalajs.junit.JUnitClassMetadata").toType + private object Names { + val beforeClass = newTermName("beforeClass") + val afterClass = newTermName("afterClass") + val before = newTermName("before") + val after = newTermName("after") + val tests = newTermName("tests") + val invokeTest = newTermName("invokeTest") + val newInstance = newTermName("newInstance") + + val instance = newTermName("instance") + val name = newTermName("name") + } - private val jUnitTestMetadataType = - getRequiredClass("org.scalajs.junit.JUnitTestBootstrapper").toType + private lazy val BootstrapperClass = + getRequiredClass("org.scalajs.junit.Bootstrapper") - private def jUnitMethodMetadataTypeTree = - TypeTree(getRequiredClass("org.scalajs.junit.JUnitMethodMetadata").toType) + private lazy val TestMetadataClass = + getRequiredClass("org.scalajs.junit.TestMetadata") + class ScalaJSJUnitPluginTransformer extends Transformer { override def transform(tree: Tree): Tree = tree match { case tree: PackageDef => - def isClassWithJUnitAnnotation(sym: Symbol): Boolean = sym match { - case _:ClassSymbol | _:ModuleSymbol => - val hasAnnotationInClass = sym.selfType.members.exists { - case mtdSym: MethodSymbol => hasAnnotation(mtdSym, TestClass) - case _ => false - } - if (hasAnnotationInClass) true - else sym.parentSymbols.headOption.fold(false)(isClassWithJUnitAnnotation) - - case _ => false + @tailrec + def hasTests(sym: Symbol): Boolean = { + sym.info.members.exists(m => m.isMethod && m.hasAnnotation(JUnitAnnots.Test)) || + sym.superClass.exists && hasTests(sym.superClass) } - val bootstrappers = tree.stats.groupBy { // Group the class with its module - case clDef: ClassDef => Some(clDef.name) - case _ => None - }.iterator.flatMap { - case (Some(_), xs) if xs.exists(x => isClassWithJUnitAnnotation(x.symbol)) => - def isModule(cDef: ClassDef): Boolean = - cDef.mods.hasFlag(Flags.MODULE) - def isTestClass(cDef: ClassDef): Boolean = { - !cDef.mods.hasFlag(Flags.MODULE) && - !cDef.mods.hasFlag(Flags.ABSTRACT) && - !cDef.mods.hasFlag(Flags.TRAIT) - } - // Get the class definition and do the transformation - xs.collectFirst { - case clDef: ClassDef if isTestClass(clDef) => - // Get the module definition - val modDefOption = xs collectFirst { - case clDef: ClassDef if isModule(clDef) => clDef - } - // Create a new module for the JUnit entry point. - mkBootstrapperClass(clDef, modDefOption) - } - - case (_, xs) => None + def isTest(sym: Symbol) = { + sym.isClass && + !sym.isModuleClass && + !sym.isAbstract && + !sym.isTrait && + hasTests(sym) } - val newStats = (tree.stats.map(transform).iterator ++ bootstrappers).toList + val bootstrappers = tree.stats.collect { + case clDef: ClassDef if isTest(clDef.symbol) => + genBootstrapper(clDef.symbol.asClass) + } - treeCopy.PackageDef(tree: Tree, tree.pid, newStats) + val newStats = tree.stats.map(transform) ++ bootstrappers + treeCopy.PackageDef(tree, tree.pid, newStats) - case _ => + case tree => super.transform(tree) } - def mkBootstrapperClass(clazz: ClassDef, modDefOption: Option[ClassDef]): ClassDef = { - val bootSym = clazz.symbol.cloneSymbol - val getJUnitMetadataDef = mkGetJUnitMetadataDef(clazz.symbol, - modDefOption.map(_.symbol)) - val newInstanceDef = genNewInstanceDef(clazz.symbol, bootSym) - val invokeJUnitMethodDef = { - val annotatedMethods = modDefOption.fold(List.empty[MethodSymbol]) { mod => - jUnitAnnotatedMethods(mod.symbol.asClass) - } - mkInvokeJUnitMethodOnModuleDef(annotatedMethods, bootSym, - modDefOption.map(_.symbol)) - } - val invokeJUnitMethodOnInstanceDef = { - val annotatedMethods = jUnitAnnotatedMethods(clazz.symbol.asClass) - mkInvokeJUnitMethodOnInstanceDef(annotatedMethods, bootSym, - clazz.symbol) - } - val ctorDef = mkConstructorDef(clazz.symbol, bootSym, clazz.pos) + def genBootstrapper(testClass: ClassSymbol): ClassDef = { + val bootSym = testClass.owner.newModuleClass( + newTypeName(testClass.name.toString + "$scalajs$junit$bootstrapper")) - val bootBody = { - List(getJUnitMetadataDef, newInstanceDef, invokeJUnitMethodDef, - invokeJUnitMethodOnInstanceDef, ctorDef) - } - val bootParents = List( - TypeTree(definitions.ObjectTpe), - TypeTree(jUnitTestMetadataType) - ) - val bootImpl = - treeCopy.Template(clazz.impl, bootParents, clazz.impl.self, bootBody) - - val bootName = newTypeName(clazz.name.toString + "$scalajs$junit$bootstrapper") - val bootClazz = gen.mkClassDef(Modifiers(Flags.MODULE), - bootName, Nil, bootImpl) - bootSym.flags += Flags.MODULE - bootSym.withoutAnnotations - bootSym.setName(bootName) - val newClazzInfo = { - val newParentsInfo = List( - definitions.ObjectTpe, - jUnitTestMetadataType - ) - val decls = bootSym.info.decls - decls.enter(getJUnitMetadataDef.symbol) - decls.enter(newInstanceDef.symbol) - decls.enter(invokeJUnitMethodDef.symbol) - decls.enter(invokeJUnitMethodOnInstanceDef.symbol) - ClassInfoType(newParentsInfo, decls, bootSym.info.typeSymbol) - } - bootSym.setInfo(newClazzInfo) - bootClazz.setSymbol(bootSym) + val bootInfo = + ClassInfoType(List(ObjectTpe, BootstrapperClass.toType), newScope, bootSym) - currentRun.symSource(bootSym) = clazz.symbol.sourceFile + bootSym.setInfo(bootInfo) - bootClazz - } - - def jUnitAnnotatedMethods(sym: Symbol): List[MethodSymbol] = { - sym.selfType.members.collect { - case m: MethodSymbol if !m.isBridge && hasJUnitMethodAnnotation(m) => m - }.toList - } + val testMethods = annotatedMethods(testClass, JUnitAnnots.Test) - /** Generates the constructor of a bootstrapper class. */ - private def mkConstructorDef(classSym: Symbol, bootSymbol: Symbol, - pos: Position): DefDef = { - val rhs = Block( - Apply( - Select( - Super(This(tpnme.EMPTY) setSymbol bootSymbol, tpnme.EMPTY), - nme.CONSTRUCTOR).setSymbol( - definitions.ObjectClass.primaryConstructor), - Nil), - Literal(Constant(())) + val defs = List( + genConstructor(bootSym), + genCallOnModule(bootSym, Names.beforeClass, testClass.companionModule, JUnitAnnots.BeforeClass), + genCallOnModule(bootSym, Names.afterClass, testClass.companionModule, JUnitAnnots.AfterClass), + genCallOnParam(bootSym, Names.before, testClass, JUnitAnnots.Before), + genCallOnParam(bootSym, Names.after, testClass, JUnitAnnots.After), + genTests(bootSym, testMethods), + genInvokeTest(bootSym, testClass, testMethods), + genNewInstance(bootSym, testClass) ) - val sym = bootSymbol.newClassConstructor(pos) - typer.typedDefDef(newDefDef(sym, rhs)()) - } - /** This method generates a method that invokes a test method in the module - * given its name. These methods have no parameters. - * - * Example: - * {{{ - * object Foo { - * @BeforeClass def bar(): Unit - * @AfterClass def baz(): Unit - * } - * object Foo\$scalajs\$junit\$bootstrapper { - * // This is the method generated by mkInvokeJUnitMethodOnModuleDef - * def invoke(methodName: String): Unit = { - * if (methodName == "bar") Foo.bar() - * else if (methodName == "baz") Foo.baz() - * else throw new NoSuchMethodException(methodName + " not found") - * } - * } - * }}} - */ - def mkInvokeJUnitMethodOnModuleDef(methods: List[MethodSymbol], - bootSym: Symbol, modClassSym: Option[Symbol]): DefDef = { - val invokeJUnitMethodSym = bootSym.newMethod(newTermName("invoke")) - - val paramSyms = { - val params = List(("methodName", definitions.StringTpe)) - mkParamSymbols(invokeJUnitMethodSym, params) - } - - invokeJUnitMethodSym.setInfo(MethodType(paramSyms, definitions.UnitTpe)) - - def callLocally(methodSymbol: Symbol): Tree = { - val methodSymbolLocal = { - modClassSym.fold(methodSymbol) { sym => - methodSymbol.cloneSymbol(newOwner = sym) - } - } - gen.mkMethodCall(methodSymbolLocal, Nil) - } - - val invokeJUnitMethodRhs = mkMethodResolutionAndCall(invokeJUnitMethodSym, - methods, paramSyms.head, callLocally) - - mkMethod(invokeJUnitMethodSym, invokeJUnitMethodRhs, paramSyms) + ClassDef(bootSym, defs) } - /** This method generates a method that invokes a test method in the class - * given its name. These methods have no parameters. - * - * Example: - * {{{ - * class Foo { - * @Test def bar(): Unit - * @Test def baz(): Unit - * } - * object Foo\$scalajs\$junit\$bootstrapper { - * // This is the method generated by mkInvokeJUnitMethodOnInstanceDef - * def invoke(instance: AnyRef, methodName: String): Unit = { - * if (methodName == "bar") instance.asInstanceOf[Foo].bar() - * else if (methodName == "baz") instance.asInstanceOf[Foo].baz() - * else throw new NoSuchMethodException(methodName + " not found") - * } - * } - * }}} - */ - def mkInvokeJUnitMethodOnInstanceDef(methods: List[MethodSymbol], - classSym: Symbol, refClassSym: Symbol): DefDef = { - val invokeJUnitMethodSym = classSym.newMethod(newTermName("invoke")) - - val paramSyms = { - val params = List(("instance", definitions.ObjectTpe), - ("methodName", definitions.StringTpe)) - mkParamSymbols(invokeJUnitMethodSym, params) - } + private def genConstructor(owner: ClassSymbol): DefDef = { + val rhs = gen.mkMethodCall( + Super(owner, tpnme.EMPTY), ObjectClass.primaryConstructor, Nil, Nil) - val instanceParamSym :: idParamSym :: Nil = paramSyms - - invokeJUnitMethodSym.setInfo(MethodType(paramSyms, definitions.UnitTpe)) + val sym = owner.newClassConstructor(NoPosition) + sym.setInfoAndEnter(MethodType(Nil, owner.tpe)) + typer.typedDefDef(newDefDef(sym, rhs)()) + } - def callLocally(methodSymbol: Symbol): Tree = { - val instance = gen.mkAttributedIdent(instanceParamSym) - val castedInstance = gen.mkAttributedCast(instance, refClassSym.tpe) - gen.mkMethodCall(castedInstance, methodSymbol, Nil, Nil) - } + private def genCallOnModule(owner: ClassSymbol, name: TermName, module: Symbol, annot: Symbol): DefDef = { + val sym = owner.newMethodSymbol(name) + sym.setInfoAndEnter(MethodType(Nil, definitions.UnitTpe)) - val invokeJUnitMethodRhs = mkMethodResolutionAndCall(invokeJUnitMethodSym, - methods, idParamSym, callLocally) + val calls = annotatedMethods(module, annot) + .map(gen.mkMethodCall(Ident(module), _, Nil, Nil)) + .toList - mkMethod(invokeJUnitMethodSym, invokeJUnitMethodRhs, paramSyms) + typer.typedDefDef(newDefDef(sym, Block(calls: _*))()) } - def mkGetJUnitMetadataDef(clSym: Symbol, - modSymOption: Option[Symbol]): DefDef = { - val methods = jUnitAnnotatedMethods(clSym) - val modMethods = modSymOption.map(jUnitAnnotatedMethods) + private def genCallOnParam(owner: ClassSymbol, name: TermName, testClass: Symbol, annot: Symbol): DefDef = { + val sym = owner.newMethodSymbol(name) - def liftAnnotations(methodSymbol: Symbol): List[Tree] = { - val annotations = methodSymbol.annotations + val instanceParam = sym.newValueParameter(Names.instance).setInfo(ObjectTpe) - // Find and report unsupported JUnit annotations - annotations.foreach { - case ann if ann.atp.typeSymbol == TestClass && ann.original.isInstanceOf[Block] => - reporter.error(ann.pos, "@Test(timeout = ...) is not " + - "supported in Scala.js JUnit Framework") + sym.setInfoAndEnter(MethodType(List(instanceParam), definitions.UnitTpe)) - case _ => // all is well - } + val instance = castParam(instanceParam, testClass) + val calls = annotatedMethods(testClass, annot) + .map(gen.mkMethodCall(instance, _, Nil, Nil)) + .toList - // Collect lifted representations of the JUnit annotations - annotations.collect { - case ann if annotationWhiteList.contains(ann.tpe.typeSymbol) => - val args = if (ann.args != null) ann.args else Nil - mkNewInstance(TypeTree(ann.tpe), args) - } - } + typer.typedDefDef(newDefDef(sym, Block(calls: _*))()) + } - def defaultMethodMetadata(tpe: TypeTree)(mtdSym: MethodSymbol): Tree = { - val annotations = liftAnnotations(mtdSym) - mkNewInstance(tpe, List( - Literal(Constant(mtdSym.name.toString)), - mkList(annotations))) - } + private def genTests(owner: ClassSymbol, tests: Scope): DefDef = { + val sym = owner.newMethodSymbol(Names.tests) + sym.setInfoAndEnter(MethodType(Nil, + typeRef(NoType, ArrayClass, List(TestMetadataClass.tpe)))) - def mkList(elems: List[Tree]): Tree = { - val varargsModule = - if (hasNewCollections) definitions.ScalaRunTimeModule - else definitions.PredefModule - - val array = ArrayValue(TypeTree(definitions.ObjectTpe), elems) - val wrappedArray = gen.mkMethodCall( - varargsModule, - definitions.wrapVarargsArrayMethodName(definitions.ObjectTpe), - Nil, List(array)) - val listApply = typer.typed { - gen.mkMethodCall(definitions.ListModule, nme.apply, Nil, List(wrappedArray)) - } + val metadata = for (test <- tests) yield { + val reifiedAnnot = New( + JUnitAnnots.Test, test.getAnnotation(JUnitAnnots.Test).get.args: _*) - if (listApply.tpe.typeSymbol.isSubClass(definitions.ListClass)) - listApply - else - gen.mkCast(listApply, definitions.ListClass.toTypeConstructor) - } + val name = Literal(Constant(test.name.toString)) + val ignored = Literal(Constant(test.hasAnnotation(JUnitAnnots.Ignore))) - def mkMethodList(tpe: TypeTree)(testMethods: List[MethodSymbol]): Tree = - mkList(testMethods.map(defaultMethodMetadata(tpe))) - - val getJUnitMethodRhs = { - mkNewInstance( - TypeTree(jUnitClassMetadataType), - List( - mkList(liftAnnotations(clSym)), - gen.mkNil, - mkMethodList(jUnitMethodMetadataTypeTree)(methods), - modMethods.fold(gen.mkNil)(mkMethodList(jUnitMethodMetadataTypeTree)) - )) + New(TestMetadataClass, name, ignored, reifiedAnnot) } - val getJUnitMetadataSym = clSym.newMethod(newTermName("metadata")) - getJUnitMetadataSym.setInfo(MethodType(Nil, jUnitClassMetadataType)) + val rhs = ArrayValue(TypeTree(TestMetadataClass.tpe), metadata.toList) - typer.typedDefDef(newDefDef(getJUnitMetadataSym, getJUnitMethodRhs)()) + typer.typedDefDef(newDefDef(sym, rhs)()) } - private def hasJUnitMethodAnnotation(mtd: MethodSymbol): Boolean = - annotationWhiteList.exists(hasAnnotation(mtd, _)) + private def genInvokeTest(owner: ClassSymbol, testClass: Symbol, tests: Scope): DefDef = { + val sym = owner.newMethodSymbol(Names.invokeTest) - private def hasAnnotation(mtd: MethodSymbol, tpe: TypeSymbol): Boolean = - mtd.annotations.exists(_.atp.typeSymbol == tpe) + val instanceParam = sym.newValueParameter(Names.instance).setInfo(ObjectTpe) + val nameParam = sym.newValueParameter(Names.name).setInfo(StringTpe) - private def mkNewInstance[T: TypeTag](params: List[Tree]): Apply = - mkNewInstance(TypeTree(typeOf[T]), params) + sym.setInfo(MethodType(List(instanceParam, nameParam), UnitTpe)) - private def mkNewInstance(tpe: TypeTree, params: List[Tree]): Apply = - Apply(Select(New(tpe), nme.CONSTRUCTOR), params) + val instance = castParam(instanceParam, testClass) + val rhs = tests.foldRight[Tree] { + Throw(New(typeOf[NoSuchMethodException], Ident(nameParam))) + } { (sym, next) => + val cond = gen.mkMethodCall(Ident(nameParam), Object_equals, Nil, + List(Literal(Constant(sym.name.toString)))) - /* Generate a method that creates a new instance of the test class, this - * method will be located in the bootstrapper class. - */ - private def genNewInstanceDef(classSym: Symbol, bootSymbol: Symbol): DefDef = { - val mkNewInstanceDefRhs = - mkNewInstance(TypeTree(classSym.typeConstructor), Nil) - val mkNewInstanceDefSym = bootSymbol.newMethodSymbol(newTermName("newInstance")) - mkNewInstanceDefSym.setInfo(MethodType(Nil, definitions.ObjectTpe)) + val call = gen.mkMethodCall(instance, sym, Nil, Nil) - typer.typedDefDef(newDefDef(mkNewInstanceDefSym, mkNewInstanceDefRhs)()) - } - - private def mkParamSymbols(method: MethodSymbol, - params: List[(String, Type)]): List[Symbol] = { - params.map { - case (pName, tpe) => - val sym = method.newValueParameter(newTermName(pName)) - sym.setInfo(tpe) - sym + If(cond, call, next) } - } - private def mkMethod(methodSym: MethodSymbol, methodRhs: Tree, - paramSymbols: List[Symbol]): DefDef = { - val paramValDefs = List(paramSymbols.map(newValDef(_, EmptyTree)())) - typer.typedDefDef(newDefDef(methodSym, methodRhs)(vparamss = paramValDefs)) + typer.typedDefDef(newDefDef(sym, rhs)()) } - private def mkMethodResolutionAndCall(methodSym: MethodSymbol, - methods: List[Symbol], idParamSym: Symbol, genCall: Symbol => Tree): Tree = { - val tree = methods.foldRight[Tree](mkMethodNotFound(idParamSym)) { (methodSymbol, acc) => - val mName = Literal(Constant(methodSymbol.name.toString)) - val paramIdent = gen.mkAttributedIdent(idParamSym) - val cond = gen.mkMethodCall(paramIdent, definitions.Object_equals, Nil, List(mName)) - val call = genCall(methodSymbol) - If(cond, call, acc) - } - atOwner(methodSym)(typer.typed(tree)) + private def genNewInstance(owner: ClassSymbol, testClass: ClassSymbol): DefDef = { + val sym = owner.newMethodSymbol(Names.newInstance) + sym.setInfoAndEnter(MethodType(Nil, ObjectTpe)) + typer.typedDefDef(newDefDef(sym, New(testClass))()) } - private def mkMethodNotFound(paramSym: Symbol) = { - val paramIdent = gen.mkAttributedIdent(paramSym) - val msg = gen.mkMethodCall(paramIdent, definitions.String_+, Nil, - List(Literal(Constant(" not found")))) - val exception = mkNewInstance[NoSuchMethodException](List(msg)) - Throw(exception) - } - } + private def castParam(param: Symbol, clazz: Symbol): Tree = + gen.mkAsInstanceOf(Ident(param), clazz.tpe, any = false) - private lazy val hasNewCollections = { - val v = scala.util.Properties.versionNumberString - !v.startsWith("2.10.") && - !v.startsWith("2.11.") && - !v.startsWith("2.12.") && - v != "2.13.0-M3" + private def annotatedMethods(owner: Symbol, annot: Symbol): Scope = + owner.info.members.filter(m => m.isMethod && !m.isBridge && m.hasAnnotation(annot)) } } } diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/Bootstrapper.scala b/junit-runtime/src/main/scala/org/scalajs/junit/Bootstrapper.scala new file mode 100644 index 0000000000..31379d4fc0 --- /dev/null +++ b/junit-runtime/src/main/scala/org/scalajs/junit/Bootstrapper.scala @@ -0,0 +1,34 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package org.scalajs.junit + +import scala.scalajs.reflect.annotation._ + +@EnableReflectiveInstantiation +trait Bootstrapper { + def beforeClass(): Unit + def afterClass(): Unit + def before(instance: AnyRef): Unit + def after(instance: AnyRef): Unit + + def tests(): Array[TestMetadata] + def invokeTest(instance: AnyRef, name: String): Unit + + def newInstance(): AnyRef +} + +final class TestMetadata( + val name: String, + val ignored: Boolean, + val annotation: org.junit.Test +) diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala index 59fd68f086..54767e94eb 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala @@ -22,7 +22,7 @@ import sbt.testing._ import scala.util.matching.Regex final class JUnitExecuteTest(taskDef: TaskDef, runner: JUnitBaseRunner, - classMetadata: JUnitTestBootstrapper, richLogger: RichLogger, + bootstrapper: Bootstrapper, richLogger: RichLogger, eventHandler: EventHandler) { private val verbose = runner.runSettings.verbose @@ -34,11 +34,8 @@ final class JUnitExecuteTest(taskDef: TaskDef, runner: JUnitBaseRunner, def fullyQualifiedName: String = taskDef.fullyQualifiedName() def executeTests(): Unit = { - val jUnitMetadata = classMetadata.metadata() - val assumptionViolated = try { - for (method <- jUnitMetadata.beforeClassMethod) - classMetadata.invoke(method.name) + bootstrapper.beforeClass() false } catch { case _: AssumptionViolatedException | _:internal.AssumptionViolatedException => @@ -64,32 +61,27 @@ final class JUnitExecuteTest(taskDef: TaskDef, runner: JUnitBaseRunner, } runWithOrWithoutQuietMode { - for (method <- jUnitMetadata.testMethods) { - method.getIgnoreAnnotation match { - case Some(ign) => - logTestIgnored(method.name) - ignoreTest(method.name) - - case None => - executeTestMethod(classMetadata, method) + for (method <- bootstrapper.tests) { + if (method.ignored) { + logTestIgnored(method.name) + ignoreTest(method.name) + } else { + executeTestMethod(bootstrapper, method) } } } - for (method <- jUnitMetadata.afterClassMethod) - classMetadata.invoke(method.name) + bootstrapper.afterClass() } } - private[this] def executeTestMethod(classMetadata: JUnitTestBootstrapper, - method: JUnitMethodMetadata) = { - val jUnitMetadata = classMetadata.metadata() - val methodName = method.name + private[this] def executeTestMethod(bootstrapper: Bootstrapper, + test: TestMetadata) = { + val methodName = test.name val decodedMethodName = { if (decodeScalaNames) runner.runSettings.decodeName(methodName) else methodName } - val testAnnotation = method.getTestAnnotation.get if (verbose) logFormattedInfo(decodedMethodName, "started") @@ -172,29 +164,27 @@ final class JUnitExecuteTest(taskDef: TaskDef, runner: JUnitBaseRunner, var testClassInstance: AnyRef = null val instantiationSucceeded = execute() { - testClassInstance = classMetadata.newInstance() + testClassInstance = bootstrapper.newInstance() } val success = if (!instantiationSucceeded) { false } else { val beforeSucceeded = execute() { - for (method <- jUnitMetadata.beforeMethod) - classMetadata.invoke(testClassInstance, method.name) + bootstrapper.before(testClassInstance) } val beforeAndTestSucceeded = if (!beforeSucceeded) { false } else { - execute(testAnnotation.expected) { - classMetadata.invoke(testClassInstance, method.name) + execute(test.annotation.expected) { + bootstrapper.invokeTest(testClassInstance, test.name) } } // Whether before and/or test succeeded or not, run the after methods val afterSucceeded = execute() { - for (method <- jUnitMetadata.afterMethod) - classMetadata.invoke(testClassInstance, method.name) + bootstrapper.after(testClassInstance) } beforeAndTestSucceeded && afterSucceeded @@ -205,9 +195,10 @@ final class JUnitExecuteTest(taskDef: TaskDef, runner: JUnitBaseRunner, // Scala.js-specific: timeouts are warnings only, after the fact val timeInSeconds = getTimeInSeconds() - if (testAnnotation.timeout != 0 && testAnnotation.timeout <= timeInSeconds) { + val timeout = test.annotation.timeout + if (timeout != 0 && timeout <= timeInSeconds) { richLogger.warn("Timeout: took " + timeInSeconds + " sec, expected " + - (testAnnotation.timeout.toDouble / 1000) + " sec") + (timeout.toDouble / 1000) + " sec") } if (success) diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTask.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTask.scala index 2ad9e97d7e..36b74309ca 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTask.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTask.scala @@ -59,12 +59,12 @@ final class JUnitTask(val taskDef: TaskDef, runner: JUnitBaseRunner) .getOrElse(throw new ClassNotFoundException(s"Cannot find $bootstrapperName$$")) .loadModule() } match { - case Success(classMetadata: JUnitTestBootstrapper) => + case Success(classMetadata: Bootstrapper) => new JUnitExecuteTest(taskDef, runner, classMetadata, richLogger, eventHandler).executeTests() case Success(_) => - val msg = s"Expected $bootstrapperName to extend JUnitTestBootstrapper" + val msg = s"Expected $bootstrapperName to extend Bootstrapper" errorWhileLoadingClass(new Exception(msg)) case Failure(exception) => diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTestBootstrapper.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTestBootstrapper.scala deleted file mode 100644 index 3faf503205..0000000000 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTestBootstrapper.scala +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Scala.js (https://www.scala-js.org/) - * - * Copyright EPFL. - * - * Licensed under Apache License 2.0 - * (https://www.apache.org/licenses/LICENSE-2.0). - * - * See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - */ - -package org.scalajs.junit - -import java.lang.annotation.Annotation - -import scala.scalajs.reflect.annotation._ - -@EnableReflectiveInstantiation -trait JUnitTestBootstrapper { - def metadata(): JUnitClassMetadata - def newInstance(): AnyRef - def invoke(methodName: String): Unit - def invoke(instance: AnyRef, methodName: String): Unit -} - -final class JUnitMethodMetadata(val name: String, annotations: List[Annotation]) { - - def hasTestAnnotation: Boolean = - annotations.exists(_.isInstanceOf[org.junit.Test]) - - def hasBeforeAnnotation: Boolean = - annotations.exists(_.isInstanceOf[org.junit.Before]) - - def hasAfterAnnotation: Boolean = - annotations.exists(_.isInstanceOf[org.junit.After]) - - def hasBeforeClassAnnotation: Boolean = - annotations.exists(_.isInstanceOf[org.junit.BeforeClass]) - - def hasAfterClassAnnotation: Boolean = - annotations.exists(_.isInstanceOf[org.junit.AfterClass]) - - def getTestAnnotation: Option[org.junit.Test] = - annotations.collectFirst { case test: org.junit.Test => test } - - def getIgnoreAnnotation: Option[org.junit.Ignore] = - annotations.collectFirst { case ign: org.junit.Ignore => ign } -} - -final class JUnitClassMetadata(classAnnotations: List[Annotation], - moduleAnnotations: List[Annotation], classMethods: List[JUnitMethodMetadata], - moduleMethods: List[JUnitMethodMetadata]) { - - def testMethods: List[JUnitMethodMetadata] = - classMethods.filter(_.hasTestAnnotation) - - def beforeMethod: List[JUnitMethodMetadata] = - classMethods.filter(_.hasBeforeAnnotation) - - def afterMethod: List[JUnitMethodMetadata] = - classMethods.filter(_.hasAfterAnnotation) - - def beforeClassMethod: List[JUnitMethodMetadata] = - moduleMethods.filter(_.hasBeforeClassAnnotation) - - def afterClassMethod: List[JUnitMethodMetadata] = - moduleMethods.filter(_.hasAfterClassAnnotation) -} diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitAbstractClassTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitAbstractClassTest.scala index 1b62c09dee..4a58904beb 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitAbstractClassTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitAbstractClassTest.scala @@ -30,7 +30,7 @@ class JUnitAbstractClassTestCheck { val boot = JUnitUtil.loadBootstrapper( "org.scalajs.testsuite.junit.JUnitAbstractClassExtended1Test") try { - boot.invoke(boot.newInstance(), "test1") + boot.invokeTest(boot.newInstance(), "test1") } catch { case e: Throwable => fail(s"Could not invoke a test: ${e.getMessage}") @@ -41,8 +41,8 @@ class JUnitAbstractClassTestCheck { val boot = JUnitUtil.loadBootstrapper( "org.scalajs.testsuite.junit.JUnitAbstractClassExtended2Test") try { - boot.invoke(boot.newInstance(), "test1") - boot.invoke(boot.newInstance(), "test2") + boot.invokeTest(boot.newInstance(), "test1") + boot.invokeTest(boot.newInstance(), "test2") } catch { case e: Throwable => fail(s"Could not invoke a test: ${e.getMessage}") diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitMixinTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitMixinTest.scala index a64f532d88..c6f91ffc3a 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitMixinTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitMixinTest.scala @@ -26,7 +26,7 @@ class JUnitMixinTestCheck { val boot = JUnitUtil.loadBootstrapper( "org.scalajs.testsuite.junit.JUnitMixinTest") try { - boot.invoke(boot.newInstance(), "mixinTest") + boot.invokeTest(boot.newInstance(), "mixinTest") } catch { case _: Throwable => fail("Could not invoke JUnitMixinTest.mixinTest as a test.") diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitNamesTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitNamesTest.scala index c5bb92509d..40169f1633 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitNamesTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitNamesTest.scala @@ -26,9 +26,9 @@ class JUnitNamesTestCheck { val boot = JUnitUtil.loadBootstrapper( "org.scalajs.testsuite.junit.JUnitNamesTest") try { - boot.invoke(boot.newInstance(), "$plus") - boot.invoke(boot.newInstance(), "$times") - boot.invoke(boot.newInstance(), "$u2206ƒ") + boot.invokeTest(boot.newInstance(), "$plus") + boot.invokeTest(boot.newInstance(), "$times") + boot.invokeTest(boot.newInstance(), "$u2206ƒ") } catch { case _: Throwable => fail("Could not invoke method on JUnitNamesTest.") diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitSubClassTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitSubClassTest.scala index bc5fb60a83..c9f54a391f 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitSubClassTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitSubClassTest.scala @@ -31,7 +31,7 @@ class JUnitSubClassTestCheck { val boot = JUnitUtil.loadBootstrapper( "org.scalajs.testsuite.junit.JUnitSubClassTest") try { - boot.invoke(boot.newInstance(), "test1") + boot.invokeTest(boot.newInstance(), "test1") } catch { case e: Throwable => fail(s"Could not invoke a test: ${e.getMessage}") @@ -42,7 +42,7 @@ class JUnitSubClassTestCheck { val boot = JUnitUtil.loadBootstrapper( "org.scalajs.testsuite.junit.JUnitSubClassExtended1Test") try { - boot.invoke(boot.newInstance(), "test1") + boot.invokeTest(boot.newInstance(), "test1") } catch { case e: Throwable => fail(s"Could not invoke a test: ${e.getMessage}") @@ -53,8 +53,8 @@ class JUnitSubClassTestCheck { val boot = JUnitUtil.loadBootstrapper( "org.scalajs.testsuite.junit.JUnitSubClassExtended2Test") try { - boot.invoke(boot.newInstance(), "test1") - boot.invoke(boot.newInstance(), "test2") + boot.invokeTest(boot.newInstance(), "test1") + boot.invokeTest(boot.newInstance(), "test2") } catch { case e: Throwable => fail(s"Could not invoke a test: ${e.getMessage}") diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala index ff8de01bc8..2e102bd402 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/JUnitUtil.scala @@ -12,7 +12,7 @@ package org.scalajs.testsuite.junit -import org.scalajs.junit.JUnitTestBootstrapper +import org.scalajs.junit.Bootstrapper import org.junit.Assert.fail import scala.scalajs.reflect.Reflect @@ -20,14 +20,14 @@ import scala.scalajs.reflect.Reflect object JUnitUtil { private final val BootstrapperSuffix = "$scalajs$junit$bootstrapper" - def loadBootstrapper(classFullName: String): JUnitTestBootstrapper = { + def loadBootstrapper(classFullName: String): Bootstrapper = { val fullName = s"$classFullName$BootstrapperSuffix" try { Reflect .lookupLoadableModuleClass(fullName + "$") .getOrElse(throw new ClassNotFoundException(s"Cannot find $fullName$$")) .loadModule() - .asInstanceOf[JUnitTestBootstrapper] + .asInstanceOf[Bootstrapper] } catch { case ex: Throwable => throw new AssertionError(s"could not load $fullName: ${ex.getMessage}") diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/MultiCompilationSecondUnitTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/MultiCompilationSecondUnitTest.scala index c4976ea32d..342cfd5d04 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/MultiCompilationSecondUnitTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/junit/MultiCompilationSecondUnitTest.scala @@ -23,7 +23,7 @@ class MultiCompilationSecondUnitTestCheck { val boot = JUnitUtil.loadBootstrapper( "org.scalajs.testsuite.junit.MultiCompilationSecondUnitTest") try { - boot.invoke(boot.newInstance(), "testFromMultiCompilation") + boot.invokeTest(boot.newInstance(), "testFromMultiCompilation") } catch { case e: Throwable => fail(s"Could not invoke a test: ${e.getMessage}") From 0f0b728d323c501d8919c9ae38842ff842060176 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Mon, 5 Nov 2018 22:50:22 +0100 Subject: [PATCH 0850/2665] Simplify JUnit runner / task relationship Runners kept a task count which was unnecessary. As a result, we do not need a slave/master distinction anymore. Lastly, we can hide the runners from the tasks and only forward the RunSettings. --- .../com/novocode/junit/JUnitFramework.scala | 12 ++- .../org/scalajs/junit/JUnitBaseRunner.scala | 81 ------------------- .../org/scalajs/junit/JUnitExecuteTest.scala | 32 ++++---- .../org/scalajs/junit/JUnitMasterRunner.scala | 62 -------------- .../scala/org/scalajs/junit/JUnitRunner.scala | 35 ++++++++ .../org/scalajs/junit/JUnitSlaveRunner.scala | 39 --------- .../scala/org/scalajs/junit/JUnitTask.scala | 22 +++-- 7 files changed, 66 insertions(+), 217 deletions(-) delete mode 100644 junit-runtime/src/main/scala/org/scalajs/junit/JUnitBaseRunner.scala delete mode 100644 junit-runtime/src/main/scala/org/scalajs/junit/JUnitMasterRunner.scala create mode 100644 junit-runtime/src/main/scala/org/scalajs/junit/JUnitRunner.scala delete mode 100644 junit-runtime/src/main/scala/org/scalajs/junit/JUnitSlaveRunner.scala diff --git a/junit-runtime/src/main/scala/com/novocode/junit/JUnitFramework.scala b/junit-runtime/src/main/scala/com/novocode/junit/JUnitFramework.scala index 2b110922bc..04bb2041fd 100644 --- a/junit-runtime/src/main/scala/com/novocode/junit/JUnitFramework.scala +++ b/junit-runtime/src/main/scala/com/novocode/junit/JUnitFramework.scala @@ -12,7 +12,7 @@ package com.novocode.junit -import org.scalajs.junit.{JUnitMasterRunner, JUnitSlaveRunner} +import org.scalajs.junit.JUnitRunner import sbt.testing._ final class JUnitFramework extends Framework { @@ -30,15 +30,13 @@ final class JUnitFramework extends Framework { } def runner(args: Array[String], remoteArgs: Array[String], - testClassLoader: ClassLoader): JUnitMasterRunner = { - new JUnitMasterRunner(args, remoteArgs, testClassLoader, - parseRunSettings(args)) + testClassLoader: ClassLoader): Runner = { + new JUnitRunner(args, remoteArgs, parseRunSettings(args)) } def slaveRunner(args: Array[String], remoteArgs: Array[String], - testClassLoader: ClassLoader, send: String => Unit): JUnitSlaveRunner = { - new JUnitSlaveRunner(args, remoteArgs, testClassLoader, send, - parseRunSettings(args)) + testClassLoader: ClassLoader, send: String => Unit): Runner = { + new JUnitRunner(args, remoteArgs, parseRunSettings(args)) } def arrayString(arr: Array[String]): String = arr.mkString("Array(", ", ", ")") diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitBaseRunner.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitBaseRunner.scala deleted file mode 100644 index 5d47de28c6..0000000000 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitBaseRunner.scala +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Scala.js (https://www.scala-js.org/) - * - * Copyright EPFL. - * - * Licensed under Apache License 2.0 - * (https://www.apache.org/licenses/LICENSE-2.0). - * - * See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - */ - -package org.scalajs.junit - -import com.novocode.junit.RunSettings -import sbt.testing._ - -abstract class JUnitBaseRunner( - val args: Array[String], - val remoteArgs: Array[String], - private[junit] val testClassLoader: ClassLoader, - private[junit] val runSettings: RunSettings) extends Runner { - - protected def newTask(taskDef: TaskDef): Task = - new JUnitTask(taskDef, this) - - protected var doneCount = 0 - protected var passedCount = 0 - protected var failedCount = 0 - protected var ignoredCount = 0 - protected var skippedCount = 0 - protected var totalCount = 0 - - private[junit] def taskDoneCount: Int = doneCount - private[junit] def testPassedCount: Int = passedCount - private[junit] def testFailedCount: Int = failedCount - private[junit] def testIgnoredCount: Int = ignoredCount - private[junit] def testSkippedCount: Int = skippedCount - private[junit] def testTotalCount: Int = totalCount - - private[junit] def taskDone(): Unit = doneCount += 1 - private[junit] def testPassed(): Unit = passedCount += 1 - private[junit] def testFailed(): Unit = failedCount += 1 - private[junit] def testIgnored(): Unit = ignoredCount += 1 - private[junit] def testSkipped(): Unit = skippedCount += 1 - private[junit] def testRegisterTotal(count: Int = 1): Unit = totalCount += count - - def serializeTask(task: Task, serializer: TaskDef => String): String = - serializer(task.taskDef) - - def deserializeTask(task: String, deserializer: String => TaskDef): Task = - newTask(deserializer(task)) - - def resetTestCounts(): Unit = { - passedCount = 0 - failedCount = 0 - ignoredCount = 0 - skippedCount = 0 - totalCount = 0 - } -} - -object JUnitBaseRunner { - object Done { - def deserialize(str: String): Done = { - val split = str.split(':') - if (split.length != 6) { - throw new IllegalArgumentException(str) - } else { - Done(split(0).toInt, split(1).toInt, split(2).toInt, split(3).toInt, - split(4).toInt, split(5).toInt) - } - } - } - - case class Done(done: Int, passed: Int, failed: Int, ignored: Int, - skipped: Int, total: Int) { - def serialize(): String = - Seq(done, passed, failed, ignored, skipped, total).mkString(":") - } -} diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala index 54767e94eb..574f96bdda 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala @@ -16,17 +16,19 @@ import java.io.ByteArrayOutputStream import com.novocode.junit.Ansi._ import com.novocode.junit.RichLogger +import com.novocode.junit.RunSettings import org.junit._ import sbt.testing._ import scala.util.matching.Regex -final class JUnitExecuteTest(taskDef: TaskDef, runner: JUnitBaseRunner, +final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, bootstrapper: Bootstrapper, richLogger: RichLogger, eventHandler: EventHandler) { - private val verbose = runner.runSettings.verbose - private val decodeScalaNames = runner.runSettings.decodeScalaNames + private val taskDef = task.taskDef + private val verbose = runSettings.verbose + private val decodeScalaNames = runSettings.decodeScalaNames lazy val packageName = fullyQualifiedName.split('.').init.mkString(".") lazy val className = fullyQualifiedName.split('.').last @@ -51,7 +53,7 @@ final class JUnitExecuteTest(taskDef: TaskDef, runner: JUnitBaseRunner, ignoreTestClass() } else { def runWithOrWithoutQuietMode[T](block: => T): T = { - if (runner.runSettings.quiet) { + if (runSettings.quiet) { scala.Console.withOut(new ByteArrayOutputStream()) { block } @@ -79,7 +81,7 @@ final class JUnitExecuteTest(taskDef: TaskDef, runner: JUnitBaseRunner, test: TestMetadata) = { val methodName = test.name val decodedMethodName = { - if (decodeScalaNames) runner.runSettings.decodeName(methodName) + if (decodeScalaNames) runSettings.decodeName(methodName) else methodName } @@ -96,7 +98,7 @@ final class JUnitExecuteTest(taskDef: TaskDef, runner: JUnitBaseRunner, def emitTestFailed(): Unit = { if (eventAlreadyEmitted) { // Only add to the failed test count, don't emit an event - runner.testFailed() + task.failed += 1 } else { testFailed(methodName) eventAlreadyEmitted = true @@ -134,8 +136,8 @@ final class JUnitExecuteTest(taskDef: TaskDef, runner: JUnitBaseRunner, val isAssertion = ex.isInstanceOf[AssertionError] val failedMsg = new StringBuilder failedMsg ++= "failed: " - if (!runner.runSettings.notLogExceptionClass && - (!isAssertion || runner.runSettings.logAssert)) { + if (!runSettings.notLogExceptionClass && + (!isAssertion || runSettings.logAssert)) { val classParts = ex.getClass.getName.split('.') failedMsg ++= classParts.init.mkString(".") failedMsg += '.' @@ -146,7 +148,7 @@ final class JUnitExecuteTest(taskDef: TaskDef, runner: JUnitBaseRunner, failedMsg += ',' val msg = s"$failedMsg took $timeInSeconds sec" val exOpt = { - if (!isAssertion || runner.runSettings.logAssert) Some(ex) + if (!isAssertion || runSettings.logAssert) Some(ex) else None } logFormattedError(decodedMethodName, msg, exOpt) @@ -204,35 +206,33 @@ final class JUnitExecuteTest(taskDef: TaskDef, runner: JUnitBaseRunner, if (success) testPassed(methodName) - runner.testRegisterTotal() + task.total += 1 } private def ignoreTest(methodName: String) = { - runner.testIgnored() + task.ignored += 1 val selector = new NestedTestSelector(fullyQualifiedName, methodName) eventHandler.handle(new JUnitEvent(taskDef, Status.Skipped, selector)) } private def ignoreTestClass() = { - runner.testIgnored() + task.ignored += 1 val selector = new TestSelector(fullyQualifiedName) eventHandler.handle(new JUnitEvent(taskDef, Status.Skipped, selector)) } private def testSkipped(): Unit = { - runner.testSkipped() val selector = new TestSelector(fullyQualifiedName) eventHandler.handle(new JUnitEvent(taskDef, Status.Skipped, selector)) } private def testFailed(methodName: String): Unit = { - runner.testFailed() + task.failed += 1 val selector = new NestedTestSelector(fullyQualifiedName, methodName) eventHandler.handle(new JUnitEvent(taskDef, Status.Failure, selector)) } private def testPassed(methodName: String): Unit = { - runner.testPassed() val selector = new NestedTestSelector(fullyQualifiedName, methodName) eventHandler.handle(new JUnitEvent(taskDef, Status.Success, selector)) } @@ -240,7 +240,7 @@ final class JUnitExecuteTest(taskDef: TaskDef, runner: JUnitBaseRunner, private[this] def logAssertionWarning(methodName: String, ex: Throwable, timeInSeconds: Double): Unit = { val exName = - if (runner.runSettings.notLogExceptionClass) "" + if (runSettings.notLogExceptionClass) "" else "org.junit.internal." + c("AssumptionViolatedException", ERRMSG) + ": " val msg = s"failed: $exName${ex.getMessage}, took $timeInSeconds sec" diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitMasterRunner.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitMasterRunner.scala deleted file mode 100644 index f75f26cc13..0000000000 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitMasterRunner.scala +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Scala.js (https://www.scala-js.org/) - * - * Copyright EPFL. - * - * Licensed under Apache License 2.0 - * (https://www.apache.org/licenses/LICENSE-2.0). - * - * See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - */ - -package org.scalajs.junit - -import com.novocode.junit.RunSettings -import sbt.testing._ -import java.util.concurrent.atomic.AtomicInteger - -final class JUnitMasterRunner( - args: Array[String], - remoteArgs: Array[String], - testClassLoader: ClassLoader, - runSettings: RunSettings) - extends JUnitBaseRunner(args, remoteArgs, testClassLoader, runSettings) { - - private[this] var registeredCount = 0 - private[this] var slaveCount = 0 - - def tasks(taskDefs: Array[TaskDef]): Array[Task] = { - registeredCount += taskDefs.length - taskDefs.map(newTask) - } - - def done(): String = { - val slaves = slaveCount - val registered = registeredCount - val done = doneCount - - if (slaves > 0) - throw new IllegalStateException(s"There are still $slaves slaves running") - - if (registered != done) { - val msg = s"$registered task(s) were registered, $done were executed" - throw new IllegalStateException(msg) - } else { - "" - } - } - - def receiveMessage(msg: String): Option[String] = msg(0) match { - case 'd' => - val slaveDone = JUnitBaseRunner.Done.deserialize(msg.tail) - doneCount += slaveDone.done - passedCount += slaveDone.passed - failedCount += slaveDone.failed - ignoredCount += slaveDone.skipped - skippedCount += slaveDone.skipped - totalCount += slaveDone.total - slaveCount -= 1 - None - } -} diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitRunner.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitRunner.scala new file mode 100644 index 0000000000..d463208a4a --- /dev/null +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitRunner.scala @@ -0,0 +1,35 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package org.scalajs.junit + +import com.novocode.junit.RunSettings +import sbt.testing._ + +final class JUnitRunner( + val args: Array[String], + val remoteArgs: Array[String], + runSettings: RunSettings) extends Runner { + + def tasks(taskDefs: Array[TaskDef]): Array[Task] = + taskDefs.map(new JUnitTask(_, runSettings)) + + def done(): String = "" + + def serializeTask(task: Task, serializer: TaskDef => String): String = + serializer(task.taskDef) + + def deserializeTask(task: String, deserializer: String => TaskDef): Task = + new JUnitTask(deserializer(task), runSettings) + + def receiveMessage(msg: String): Option[String] = None +} diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitSlaveRunner.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitSlaveRunner.scala deleted file mode 100644 index 7f389f235d..0000000000 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitSlaveRunner.scala +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Scala.js (https://www.scala-js.org/) - * - * Copyright EPFL. - * - * Licensed under Apache License 2.0 - * (https://www.apache.org/licenses/LICENSE-2.0). - * - * See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - */ - -package org.scalajs.junit - -import com.novocode.junit.RunSettings -import sbt.testing._ - -final class JUnitSlaveRunner( - args: Array[String], - remoteArgs: Array[String], - testClassLoader: ClassLoader, - send: String => Unit, - runSettings: RunSettings) - extends JUnitBaseRunner(args, remoteArgs, testClassLoader, runSettings) { - - def tasks(taskDefs: Array[TaskDef]): Array[Task] = { - taskDefs.map(newTask) - } - - def done(): String = { - send("d" + JUnitBaseRunner.Done(taskDoneCount, passedCount, failedCount, - ignoredCount, skippedCount, totalCount).serialize) - "" - } - - def receiveMessage(msg: String): Option[String] = { - None // <- ignored - } -} diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTask.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTask.scala index 36b74309ca..b438dc8c4b 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTask.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTask.scala @@ -12,17 +12,21 @@ package org.scalajs.junit -import com.novocode.junit.{Ansi, RichLogger} +import com.novocode.junit.{Ansi, RichLogger, RunSettings} import Ansi._ import sbt.testing._ import scala.scalajs.reflect.Reflect import scala.util.{Try, Success, Failure} -final class JUnitTask(val taskDef: TaskDef, runner: JUnitBaseRunner) +final class JUnitTask(val taskDef: TaskDef, runSettings: RunSettings) extends sbt.testing.Task { def tags: Array[String] = Array.empty + var failed = 0 + var ignored = 0 + var total = 0 + def execute(eventHandler: EventHandler, loggers: Array[Logger], continuation: Array[Task] => Unit): Unit = { continuation(execute(eventHandler, loggers)) @@ -30,10 +34,10 @@ final class JUnitTask(val taskDef: TaskDef, runner: JUnitBaseRunner) def execute(eventHandler: EventHandler, loggers: Array[Logger]): Array[Task] = { val fullClassName = taskDef.fullyQualifiedName - val richLogger = new RichLogger(loggers, runner.runSettings, fullClassName) + val richLogger = new RichLogger(loggers, runSettings, fullClassName) def infoOrDebug(msg: String): Unit = { - if (runner.runSettings.verbose) + if (runSettings.verbose) richLogger.info(msg) else richLogger.debug(msg) @@ -59,8 +63,8 @@ final class JUnitTask(val taskDef: TaskDef, runner: JUnitBaseRunner) .getOrElse(throw new ClassNotFoundException(s"Cannot find $bootstrapperName$$")) .loadModule() } match { - case Success(classMetadata: Bootstrapper) => - new JUnitExecuteTest(taskDef, runner, classMetadata, + case Success(bootstrapper: Bootstrapper) => + new JUnitExecuteTest(this, runSettings, bootstrapper, richLogger, eventHandler).executeTests() case Success(_) => @@ -71,12 +75,7 @@ final class JUnitTask(val taskDef: TaskDef, runner: JUnitBaseRunner) errorWhileLoadingClass(exception) } - runner.taskDone() - val time = System.nanoTime - startTime - val failed = runner.testFailedCount - val ignored = runner.testIgnoredCount - val total = runner.testTotalCount val msg = { c("Test run finished: ", INFO) + @@ -87,7 +86,6 @@ final class JUnitTask(val taskDef: TaskDef, runner: JUnitBaseRunner) } infoOrDebug(msg) - runner.resetTestCounts() Array() } From b744d12e0c6d8af74960e0ce5071c8e0011249a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 25 Oct 2018 14:49:50 +0200 Subject: [PATCH 0851/2665] [no-master] Fix #2175: Add support for ECMAScript 2015 modules. This commit adds a third `ModuleKind` for ES modules, namely `ModuleKind.ESModule`. When emitting an ES module, `@JSImport`s and `@JSExportTopLevel`s straightforwardly map to ES `import` and `export` clauses, respectively. At the moment, imports are always implemented using a namespace import, then selecting fields inside the namespace. This is suboptimal because it can prevent advanced DCE across ES modules. Improving on this is left for future work. The Node.js-based environment is adapted to interpret files whose name ends with `.mjs` as ES modules rather than scripts. This aligns with how Node.js itself identifies ES modules as of version 10.x, although it is still experimental, so that could change in the future. For the 0.6.x branch, the `TestAdapter` assumes that it can force the `JSEnv` to interpret its launcher as an ES module by giving it the `.mjs` extension as well. This is wrong in general, but there does not seem to be a good way to deal with this issue. In 1.x, this will be a non-issue since the `TestAdapter` does not require any launcher. Although setting `scalaJSLinkerConfig.moduleKind` to `ModuleKind.ESModule` is enough for the Scala.js linker to emit a valid ES module, two additional settings are required to *run* or *test* using Node.js: artifactPath in (proj, Compile, fastOptJS) := (crossTarget in (proj, Compile)).value / "somename.mjs" jsEnv := { new org.scalajs.jsenv.NodeJSEnv( org.scalajs.jsenv.NODEJSEnv.Config() .withArguments(List("--experimental-modules")) ) } The first setting is necessary to give the `.mjs` extension to the file produced by Scala.js, which in turn is necessary for Node.js to accept it as an ES module. The second setting will be necessary until Node.js declares its support for ES module as non-experimental. ES modules are incompatible with a few features, which are all gone in Scala.js 1.x: * `EnvironmentInfo.exportsNamespace`: an ES module cannot read its own exports namespace, short of importing itself (which requires it to know its file name). The value of `exportsNamespace` is `undefined` in an ES module. * Generation of a `main` launcher script by the sbt plugin. Attempting to use one will throw an exception in the build. Moreover, the version of the Closure Compiler that we use does not support ES modules yet, so we deactivate GCC when emitting an ES module. At this point, the emission of ES modules can be considered stable, but the support in `NodeJSEnv` is experimental (since the support of ES modules in Node.js is itself experimental). Running the full test suite with ES modules requires Node.js 10.2.0 or later. It has been tested with v10.12.0. --- Jenkinsfile | 34 ++++++ .../jsenv/nodejs/AbstractNodeJSEnv.scala | 29 ++++- project/Build.scala | 54 ++++++++- .../sbtplugin/ScalaJSPluginInternal.scala | 17 ++- .../scalajs/sbttestadapter/TestAdapter.scala | 61 +++++++--- .../scalajs/testsuite/utils/Platform.scala | 1 + .../testsuite/jsinterop/ModulesTest.scala | 4 +- .../testsuite/javalib/lang/SystemJSTest.scala | 6 +- .../testsuite/jsinterop/ExportsTest.scala | 22 +++- .../ModulesWithGlobalFallbackTest.scala | 4 +- .../core/tools/io/FileVirtualFiles.scala | 2 +- .../closure/ClosureLinkerBackend.scala | 4 +- tools/scalajsenv.js | 4 + .../core/tools/javascript/Printers.scala | 46 ++++++++ .../scalajs/core/tools/javascript/Trees.scala | 108 ++++++++++++++++++ .../tools/linker/backend/ModuleKind.scala | 8 ++ .../linker/backend/emitter/ClassEmitter.scala | 81 ++++++++----- .../linker/backend/emitter/Emitter.scala | 98 ++++++++++++---- .../tools/linker/backend/emitter/JSGen.scala | 4 +- 19 files changed, 500 insertions(+), 87 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index b5dfe4d623..95aa2023dc 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -128,6 +128,18 @@ def Tasks = [ 'set scalaJSModuleKind in helloworld := ModuleKind.CommonJSModule' \ helloworld/run \ helloworld/clean && + sbtretry ++$scala \ + 'set artifactPath in (helloworld, Compile, fastOptJS) := (crossTarget in helloworld).value / "helloworld-fastopt.mjs"' \ + 'set jsEnv in helloworld := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withArgs(List("--experimental-modules")).withSourceMap(false))' \ + 'set scalaJSModuleKind in helloworld := ModuleKind.ESModule' \ + helloworld/run && + sbtretry ++$scala \ + 'set artifactPath in (helloworld, Compile, fullOptJS) := (crossTarget in helloworld).value / "helloworld-opt.mjs"' \ + 'set jsEnv in helloworld := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withArgs(List("--experimental-modules")).withSourceMap(false))' \ + 'set scalaJSModuleKind in helloworld := ModuleKind.ESModule' \ + 'set scalaJSStage in Global := FullOptStage' \ + helloworld/run \ + helloworld/clean && sbtretry ++$scala \ 'set Seq(scalaJSUseMainModuleInitializer in helloworld := false, persistLauncher in helloworld := true)' \ 'set scalaJSUseRhino in Global := true' \ @@ -230,6 +242,16 @@ def Tasks = [ sbtretry 'set scalaJSModuleKind in $testSuite := ModuleKind.CommonJSModule' \ ++$scala $testSuite/test && sbtretry 'set scalaJSModuleKind in $testSuite := ModuleKind.CommonJSModule' \ + 'set scalaJSStage in Global := FullOptStage' \ + ++$scala $testSuite/test \ + $testSuite/clean && + sbtretry 'set artifactPath in ($testSuite, Test, fastOptJS) := (crossTarget in $testSuite).value / "testsuite-fastopt.mjs"' \ + 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withArgs(List("--experimental-modules")).withSourceMap(false))' \ + 'set scalaJSModuleKind in $testSuite := ModuleKind.ESModule' \ + ++$scala $testSuite/test && + sbtretry 'set artifactPath in ($testSuite, Test, fullOptJS) := (crossTarget in $testSuite).value / "testsuite-opt.mjs"' \ + 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withArgs(List("--experimental-modules")).withSourceMap(false))' \ + 'set scalaJSModuleKind in $testSuite := ModuleKind.ESModule' \ 'set scalaJSStage in Global := FullOptStage' \ ++$scala $testSuite/test ''', @@ -280,6 +302,18 @@ def Tasks = [ 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withSourceMap(false))' \ 'set scalaJSModuleKind in $testSuite := ModuleKind.CommonJSModule' \ 'set scalaJSStage in Global := FullOptStage' \ + ++$scala $testSuite/test \ + $testSuite/clean && + sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true)))' \ + 'set artifactPath in ($testSuite, Test, fastOptJS) := (crossTarget in $testSuite).value / "testsuite-fastopt.mjs"' \ + 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withArgs(List("--experimental-modules")).withSourceMap(false))' \ + 'set scalaJSModuleKind in $testSuite := ModuleKind.ESModule' \ + ++$scala $testSuite/test && + sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true)))' \ + 'set artifactPath in ($testSuite, Test, fullOptJS) := (crossTarget in $testSuite).value / "testsuite-opt.mjs"' \ + 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withArgs(List("--experimental-modules")).withSourceMap(false))' \ + 'set scalaJSModuleKind in $testSuite := ModuleKind.ESModule' \ + 'set scalaJSStage in Global := FullOptStage' \ ++$scala $testSuite/test ''', diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala index 39de10fa18..a5f63030b8 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/AbstractNodeJSEnv.scala @@ -134,12 +134,37 @@ abstract class AbstractNodeJSEnv( */ override protected def writeJSFile(file: VirtualJSFile, writer: Writer): Unit = { + + def writeImport(file: File): Unit = { + val uri = file.toURI.toASCIIString + val importerFile = new MemVirtualJSFile("importer.js") + importerFile.content = { + s""" + |import("${escapeJS(uri)}").catch(e => { + | /* Make sure to fail the process, but give time to Node.js to + | * display a good stack trace before that. + | */ + | setTimeout(() => process.exit(1), 100); + | throw e; + |}); + """.stripMargin + } + val f = libCache.materialize(importerFile) + writer.write(s"""require("${escapeJS(f.getAbsolutePath)}");\n""") + } + file match { case file: FileVirtualJSFile => val fname = file.file.getAbsolutePath - writer.write(s"""require("${escapeJS(fname)}");\n""") + if (fname.endsWith(".mjs")) + writeImport(file.file) + else + writer.write(s"""require("${escapeJS(fname)}");\n""") case _ => - super.writeJSFile(file, writer) + if (file.path.endsWith(".mjs")) + writeImport(libCache.materialize(file)) + else + super.writeJSFile(file, writer) } } diff --git a/project/Build.scala b/project/Build.scala index 1b710ce5ab..4287119470 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -28,7 +28,7 @@ import ScalaJSPlugin.autoImport._ import ExternalCompile.scalaJSExternalCompileSettings import Loggers._ -import org.scalajs.core.tools.io.MemVirtualJSFile +import org.scalajs.core.tools.io.{MemVirtualJSFile, FileVirtualJSFile} import org.scalajs.core.tools.sem._ import org.scalajs.core.tools.jsdep.ResolvedJSDependency import org.scalajs.core.tools.json._ @@ -53,6 +53,10 @@ object Build { val bintrayProjectName = settingKey[String]( "Project name on Bintray") + val setModuleLoopbackScript = taskKey[Option[ResolvedJSDependency]]( + "In the test suite, under ES modules, the script that sets the " + + "loopback module namespace") + val fetchScalaSource = taskKey[File]( "Fetches the scala source for the current scala version") val shouldPartest = settingKey[Boolean]( @@ -1485,6 +1489,7 @@ object Build { val moduleKindTag = scalaJSModuleKind.value match { case ModuleKind.NoModule => "modulekind-nomodule" + case ModuleKind.ESModule => "modulekind-esmodule" case ModuleKind.CommonJSModule => "modulekind-commonjs" } @@ -1642,6 +1647,53 @@ object Build { javaOptions in Test += "-Dscalajs.scalaVersion=" + scalaVersion.value, + /* The script that calls setExportsNamespaceForExportsTest to provide + * ExportsTest with a loopback reference to its own exports namespace. + * Only when using an ES module. + * See the comment in ExportsTest for more details. + */ + setModuleLoopbackScript in Test := Def.settingDyn[Task[Option[ResolvedJSDependency]]] { + (scalaJSModuleKind in Test).value match { + case ModuleKind.ESModule => + Def.task { + val linkedFile = + (scalaJSLinkedFile in Test).value.asInstanceOf[FileVirtualJSFile].file + val uri = linkedFile.toURI.toASCIIString + + val setNamespaceScriptFile = + crossTarget.value / (linkedFile.getName + "-loopback.js") + + /* Due to the asynchronous nature of ES module loading, there + * exists a theoretical risk for a race condition here. It is + * possible that tests will start running and reaching the + * ExportsTest before the callback in this script is executed. + * It's quite unlikely, though, given all the message passing + * for the com and all that. + */ + IO.write(setNamespaceScriptFile, + s""" + |(function() { + | "use strict"; + | import("${escapeJS(uri)}").then(mod => { + | mod.setExportsNamespaceForExportsTest(mod); + | }); + |})(); + """.stripMargin) + + val vf = FileVirtualJSFile(setNamespaceScriptFile) + Some(ResolvedJSDependency.minimal(vf)) + } + + case _ => + Def.task { + None + } + } + }.value, + + scalaJSConfigurationLibs in Test ++= + (setModuleLoopbackScript in Test).value.toList, + /* Generate a scala source file that throws exceptions in * various places (while attaching the source line to the * exception). When we catch the exception, we can then diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 95a96ff326..3ca154c3f8 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -505,7 +505,12 @@ object ScalaJSPluginInternal { scalaJSOptimizerOptions in fullOptJS := { val prev = (scalaJSOptimizerOptions in fullOptJS).value val outputMode = (scalaJSOutputMode in fullOptJS).value - prev.withUseClosureCompiler(outputMode == OutputMode.ECMAScript51Isolated) + val moduleKind = (scalaJSModuleKind in fullOptJS).value + val useClosure = { + outputMode == OutputMode.ECMAScript51Isolated && + moduleKind != ModuleKind.ESModule + } + prev.withUseClosureCompiler(useClosure) }, fullOptJS := fullOptJS.dependsOn(packageMinifiedJSDependencies).value, @@ -785,6 +790,11 @@ object ScalaJSPluginInternal { None } + case ModuleKind.ESModule => + Def.task { + Some(scalaJSLinkedFile.value.toURI.toASCIIString) + } + case ModuleKind.CommonJSModule => Def.task { Some(scalaJSLinkedFile.value.path) @@ -814,11 +824,14 @@ object ScalaJSPluginInternal { private[sbtplugin] def makeExportsNamespaceExpr(moduleKind: ModuleKind, moduleIdentifier: Option[String]): String = { - // !!! DUPLICATE code with TestAdpater.startManagedRunner moduleKind match { case ModuleKind.NoModule => jsGlobalExpr + case ModuleKind.ESModule => + throw new MessageOnlyException( + "Using a launcher file is not compatible with ES modules") + case ModuleKind.CommonJSModule => val moduleIdent = moduleIdentifier.getOrElse { throw new IllegalArgumentException( diff --git a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TestAdapter.scala b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TestAdapter.scala index 8150ab0a46..a1965a008a 100644 --- a/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TestAdapter.scala +++ b/test-adapter/src/main/scala/org/scalajs/sbttestadapter/TestAdapter.scala @@ -133,19 +133,6 @@ final class TestAdapter(jsEnv: ComJSEnv, config: TestAdapter.Config) { // Otherwise we might leak runners. require(!closed, "We are closed. Cannot create new runner.") - // !!! DUPLICATE code with ScalaJSPlugin.makeExportsNamespaceExpr - val orgExpr = config.moduleKind match { - case ModuleKind.NoModule => - "typeof(org) != 'undefined' ? org : {}" - - case ModuleKind.CommonJSModule => - val moduleIdent = config.moduleIdentifier.getOrElse { - throw new IllegalArgumentException( - "The module identifier must be specified for CommonJS modules") - } - s"""require("${escapeJS(moduleIdent)}").org || {}""" - } - /* #2752: if there is no testing framework at all on the classpath, * the testing interface will not be there, and therefore the * `startBridge` function will not exist. We must therefore be @@ -153,19 +140,55 @@ final class TestAdapter(jsEnv: ComJSEnv, config: TestAdapter.Config) { * If it is not present, we will simply exit; `loadFrameworks` is prepared * to deal with this case. */ - val code = s""" - (function() { - "use strict"; - var namespace = $orgExpr; + val startBridgeFun = """ + function startBridge(namespace) { namespace = namespace.scalajs || {}; namespace = namespace.testinterface || {}; namespace = namespace.internal || {}; var bridge = namespace.startBridge || function() {}; bridge(); - })(); + } """ - val launcher = new MemVirtualJSFile("startTestBridge.js").withContent(code) + val code = config.moduleKind match { + case ModuleKind.NoModule => + s""" + (function() { + "use strict"; + $startBridgeFun + startBridge(typeof(org) != 'undefined' ? org : {}); + })(); + """ + + case ModuleKind.ESModule => + val moduleIdent = config.moduleIdentifier.getOrElse { + throw new IllegalArgumentException( + "The module identifier must be specified for ES modules") + } + val uri = new java.io.File(moduleIdent).toURI.toASCIIString + s""" + import * as mod from "${escapeJS(moduleIdent)}"; + $startBridgeFun + startBridge(mod.org || {}); + """ + + case ModuleKind.CommonJSModule => + val moduleIdent = config.moduleIdentifier.getOrElse { + throw new IllegalArgumentException( + "The module identifier must be specified for CommonJS modules") + } + s""" + (function() { + "use strict"; + $startBridgeFun + startBridge(require("${escapeJS(moduleIdent)}").org || {}); + })(); + """ + } + + val ext = if (config.moduleKind == ModuleKind.ESModule) ".mjs" else ".js" + + val launcher = new MemVirtualJSFile("startTestBridge" + ext).withContent(code) val runner = jsEnv.comRunner(launcher) val com = new ComJSEnvRPC(runner) val mux = new RunMuxRPC(com) diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala index b2ddb60101..0c718b0491 100644 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala +++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala @@ -62,6 +62,7 @@ object Platform { def hasStrictFloats: Boolean = sysProp("strict-floats") def isNoModule: Boolean = sysProp("modulekind-nomodule") + def isESModule: Boolean = sysProp("modulekind-esmodule") def isCommonJSModule: Boolean = sysProp("modulekind-commonjs") private def sysProp(key: String): Boolean = diff --git a/test-suite/js/src/test/require-modules/org/scalajs/testsuite/jsinterop/ModulesTest.scala b/test-suite/js/src/test/require-modules/org/scalajs/testsuite/jsinterop/ModulesTest.scala index 5228edbcfc..19d3f2c469 100644 --- a/test-suite/js/src/test/require-modules/org/scalajs/testsuite/jsinterop/ModulesTest.scala +++ b/test-suite/js/src/test/require-modules/org/scalajs/testsuite/jsinterop/ModulesTest.scala @@ -26,7 +26,7 @@ class ModulesTest { @Test def testImportModuleItself(): Unit = { val qs = QueryString - assertTrue(qs.isInstanceOf[js.Object]) + assertEquals("object", js.typeOf(qs)) val dict = js.Dictionary("foo" -> "bar", "baz" -> "qux") @@ -42,7 +42,7 @@ class ModulesTest { @Test def testImportLegacyModuleItselfAsDefault(): Unit = { val qs = QueryStringAsDefault - assertTrue(qs.isInstanceOf[js.Object]) + assertEquals("object", js.typeOf(qs)) val dict = js.Dictionary("foo" -> "bar", "baz" -> "qux") diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala index 4165e78724..00c63f97df 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala @@ -69,6 +69,8 @@ class SystemJSTest { @Test def systemProperties(): Unit = { def get(key: String): String = java.lang.System.getProperty(key) + def trueCount(xs: Boolean*): Int = xs.count(identity) + // Defined in System.scala assertEquals("1.8", get("java.version")) @@ -148,9 +150,11 @@ class SystemJSTest { assertEquals(isInFullOpt, Platform.isInFullOpt) val isNoModule = get("scalajs.modulekind-nomodule") == "true" + val isESModule = get("scalajs.modulekind-esmodule") == "true" val isCommonJSModule = get("scalajs.modulekind-commonjs") == "true" assertEquals(isNoModule, Platform.isNoModule) + assertEquals(isESModule, Platform.isESModule) assertEquals(isCommonJSModule, Platform.isCommonJSModule) - assertTrue(isNoModule ^ isCommonJSModule) + assertEquals(1, trueCount(isNoModule, isESModule, isCommonJSModule)) } } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index b88504220b..8784cd5769 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -28,10 +28,30 @@ import org.junit.Test import org.scalajs.testsuite.utils.{JSUtils, Platform} import org.scalajs.testsuite.utils.AssertThrows.assertThrows +object ExportsTest { + /* When using ES modules, there is no way to get hold of our own exports + * namespace from within. The build instead sets up a small script that will + * import our module and call `setExportsNamespaceForExportsTest` with our + * module namespace. + */ + + private[this] var explicitlySetExportsNamespace: Option[js.Dynamic] = None + + @JSExportTopLevel("setExportsNamespaceForExportsTest") + def setExportsNamespaceForExportsTest(value: js.Dynamic): Unit = + explicitlySetExportsNamespace = Some(value) + + def exportsNameSpace: js.Dynamic = { + explicitlySetExportsNamespace.getOrElse { + scala.scalajs.runtime.environmentInfo.exportsNamespace + } + } +} + class ExportsTest { /** The namespace in which top-level exports are stored. */ - val exportsNamespace = scala.scalajs.runtime.environmentInfo.exportsNamespace + val exportsNamespace = ExportsTest.exportsNameSpace /** This package in the JS (export) namespace */ val jsPackage = exportsNamespace.org.scalajs.testsuite.jsinterop diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala index 58e266a210..1c27ae394e 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala @@ -33,7 +33,7 @@ class ModulesWithGlobalFallbackTest { @Test def testImportModuleItself(): Unit = { val qs = QueryString - assertTrue(qs.isInstanceOf[js.Object]) + assertEquals("object", js.typeOf(qs)) val dict = js.Dictionary("foo" -> "bar", "baz" -> "qux") @@ -49,7 +49,7 @@ class ModulesWithGlobalFallbackTest { @Test def testImportLegacyModuleItselfAsDefault(): Unit = { val qs = QueryStringAsDefault - assertTrue(qs.isInstanceOf[js.Object]) + assertEquals("object", js.typeOf(qs)) val dict = js.Dictionary("foo" -> "bar", "baz" -> "qux") diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala index da792c79f0..670bb9d597 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/io/FileVirtualFiles.scala @@ -137,7 +137,7 @@ class FileVirtualJSFile(f: File) extends FileVirtualTextFile(f) import FileVirtualFile._ import FileVirtualTextFile._ - val sourceMapFile: File = withExtension(file, ".js", ".js.map") + val sourceMapFile: File = withName(file, file.getName + ".map") override def sourceMap: Option[String] = { if (sourceMapFile.exists) Some(readFileToString(sourceMapFile)) diff --git a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala index a36f84ee3a..c4b65d9534 100644 --- a/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala +++ b/tools/jvm/src/main/scala/org/scalajs/core/tools/linker/backend/closure/ClosureLinkerBackend.scala @@ -58,8 +58,8 @@ final class ClosureLinkerBackend( val symbolRequirements: SymbolRequirement = emitter.symbolRequirements private val needsIIFEWrapper = moduleKind match { - case ModuleKind.NoModule => true - case ModuleKind.CommonJSModule => false + case ModuleKind.NoModule => true + case ModuleKind.ESModule | ModuleKind.CommonJSModule => false } private def toClosureSource(file: VirtualJSFile) = diff --git a/tools/scalajsenv.js b/tools/scalajsenv.js index cc8162c98d..0006ae9fd3 100644 --- a/tools/scalajsenv.js +++ b/tools/scalajsenv.js @@ -21,6 +21,9 @@ ScalaJS.g = : ((typeof global === "object" && global && global["Object"] === Object) ? global : this); ScalaJS.env["global"] = ScalaJS.g; +//!if moduleKind == ESModule +ScalaJS.env["exportsNamespace"] = void 0; +//!else // Where to send exports //!if moduleKind == CommonJSModule ScalaJS.e = exports; @@ -30,6 +33,7 @@ ScalaJS.e = ? ScalaJS.env["exportsNamespace"] : ScalaJS.g; //!endif ScalaJS.env["exportsNamespace"] = ScalaJS.e; +//!endif // Freeze the environment info ScalaJS.g["Object"]["freeze"](ScalaJS.env); diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala index 47c4a93569..7bc77934d1 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Printers.scala @@ -552,6 +552,49 @@ object Printers { case Super() => print("super") + // ECMAScript 6 modules + + case Import(bindings, from) => + print("import { ") + var first = true + var rest = bindings + while (rest.nonEmpty) { + val binding = rest.head + if (first) + first = false + else + print(", ") + print(binding._1) + print(" as ") + print(binding._2) + rest = rest.tail + } + print(" } from ") + print(from: Tree) + + case ImportNamespace(binding, from) => + print("import * as ") + print(binding) + print(" from ") + print(from: Tree) + + case Export(bindings) => + print("export { ") + var first = true + var rest = bindings + while (rest.nonEmpty) { + val binding = rest.head + if (first) + first = false + else + print(", ") + print(binding._1) + print(" as ") + print(binding._2) + rest = rest.tail + } + print(" }") + case _ => print(s"") } @@ -573,6 +616,9 @@ object Printers { print("]") } + protected def print(exportName: ExportName): Unit = + printEscapeJS(exportName.name) + protected def print(s: String): Unit = out.write(s) diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala index 0193551f1a..9e8468b030 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/javascript/Trees.scala @@ -241,4 +241,112 @@ object Trees { body: Tree)(implicit val pos: Position) extends Tree case class Super()(implicit val pos: Position) extends Tree + + // ECMAScript 6 modules + + /** The name of an ES module export. + * + * It must be a valid `IdentifierName`, as tested by + * [[ExportName.isValidExportName]]. + */ + case class ExportName(name: String)(implicit val pos: Position) { + require(ExportName.isValidExportName(name), + s"'$name' is not a valid export name") + } + + object ExportName { + /** Tests whether a string is a valid export name. + * + * A string is a valid export name if and only if it is a valid ECMAScript + * `IdentifierName`, which is defined in + * [[http://www.ecma-international.org/ecma-262/6.0/#sec-names-and-keywords + * Section 11.6 of the ECMAScript 2015 specification]]. + * + * Currently, this implementation is buggy in some corner cases, as it does + * not accept code points with the Unicode properties `Other_ID_Start` and + * `Other_ID_Continue`. For example, + * `isValidIdentifierName(0x2118.toChar.toString)` will return `false` + * instead of `true`. + * + * In theory, it does not really account for code points with the Unicode + * properties `Pattern_Syntax` and `Pattern_White_Space`, which should be + * rejected. However, with the current version of Unicode (9.0.0), there + * seems to be no such character that would be accepted by this method. + */ + final def isValidExportName(name: String): Boolean = { + // scalastyle:off return + import java.lang.Character._ + + def isJSIdentifierStart(cp: Int): Boolean = + isUnicodeIdentifierStart(cp) || cp == '$' || cp == '_' + + def isJSIdentifierPart(cp: Int): Boolean = { + val ZWNJ = 0x200c + val ZWJ = 0x200d + isUnicodeIdentifierPart(cp) || cp == '$' || cp == '_' || cp == ZWNJ || cp == ZWJ + } + + if (name.isEmpty) + return false + + val firstCP = name.codePointAt(0) + if (!isJSIdentifierStart(firstCP)) + return false + + var i = charCount(firstCP) + while (i < name.length) { + val cp = name.codePointAt(i) + if (!isJSIdentifierPart(cp)) + return false + i += charCount(cp) + } + + true + // scalastyle:on return + } + } + + /** `import` statement, except namespace import. + * + * This corresponds to the following syntax: + * {{{ + * import { as , ..., as } from + * }}} + * The `_1` parts of bindings are therefore the identifier names that are + * imported, as specified in `export` clauses of the module. The `_2` parts + * are the names under which they are imported in the current module. + * + * Special cases: + * - When `_1.name == _2.name`, there is shorter syntax in ES, i.e., + * `import { binding } from 'from'`. + * - When `_1.name == "default"`, it is equivalent to a default import. + */ + case class Import(bindings: List[(ExportName, Ident)], from: StringLiteral)( + implicit val pos: Position) + extends Tree + + /** Namespace `import` statement. + * + * This corresponds to the following syntax: + * {{{ + * import * as from + * }}} + */ + case class ImportNamespace(binding: Ident, from: StringLiteral)( + implicit val pos: Position) + extends Tree + + /** `export` statement. + * + * This corresponds to the following syntax: + * {{{ + * export { as , ..., as } + * }}} + * The `_1` parts of bindings are therefore the identifiers from the current + * module that are exported. The `_2` parts are the names under which they + * are exported to other modules. + */ + case class Export(bindings: List[(Ident, ExportName)])( + implicit val pos: Position) + extends Tree } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/ModuleKind.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/ModuleKind.scala index 974cb34bb9..88c48e328e 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/ModuleKind.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/ModuleKind.scala @@ -24,6 +24,7 @@ object ModuleKind { */ val All: List[ModuleKind] = List( NoModule, + ESModule, CommonJSModule) /** No module structure. @@ -36,6 +37,13 @@ object ModuleKind { */ case object NoModule extends ModuleKind + /** An ECMAScript 2015 module. + * + * Scala.js imports and exports directly map to `import` and `export` + * clauses in the ES module. + */ + case object ESModule extends ModuleKind + /** A CommonJS module (notably used by Node.js). * * Imported modules are fetched with `require`. Exports go to the `exports` diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala index 068d202f34..af10a16307 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/ClassEmitter.scala @@ -1068,31 +1068,38 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { implicit val pos = tree.pos - val (createNamespace, namespace, fieldName) = - genCreateNamespaceInExportsAndGetNamespace(fullName) - - // defineProperty method - val defProp = - genIdentBracketSelect(js.VarRef(js.Ident("Object")), "defineProperty") - - // optional getter definition - val getterDef = { - js.StringLiteral("get") -> js.Function(Nil, { - js.Return(genSelectStatic(cd.encodedName, field)) - }) - } + if (moduleKind == ModuleKind.ESModule && !fullName.contains('.')) { + // Special: directly export the variable + val staticVarIdent = + genSelectStatic(cd.encodedName, field).asInstanceOf[js.VarRef].ident + js.Export((staticVarIdent -> js.ExportName(fullName)) :: Nil) + } else { + val (createNamespace, namespace, fieldName) = + genCreateNamespaceInExportsAndGetNamespace(fullName) + + // defineProperty method + val defProp = + genIdentBracketSelect(js.VarRef(js.Ident("Object")), "defineProperty") + + // optional getter definition + val getterDef = { + js.StringLiteral("get") -> js.Function(Nil, { + js.Return(genSelectStatic(cd.encodedName, field)) + }) + } - // Options passed to the defineProperty method - val descriptor = js.ObjectConstr( - getterDef :: - (js.StringLiteral("configurable") -> js.BooleanLiteral(true)) :: - Nil - ) + // Options passed to the defineProperty method + val descriptor = js.ObjectConstr( + getterDef :: + (js.StringLiteral("configurable") -> js.BooleanLiteral(true)) :: + Nil + ) - val callDefineProp = - js.Apply(defProp, namespace :: fieldName :: descriptor :: Nil) + val callDefineProp = + js.Apply(defProp, namespace :: fieldName :: descriptor :: Nil) - js.Block(createNamespace, callDefineProp) + js.Block(createNamespace, callDefineProp) + } } // Helpers @@ -1138,9 +1145,16 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { */ private def genCreateNamespaceInExports(qualName: String)( implicit pos: Position): (js.Tree, js.Tree) = { - val (createNamespace, namespace, lastPart) = - genCreateNamespaceInExportsAndGetNamespace(qualName) - (createNamespace, genBracketSelect(namespace, lastPart)) + if (moduleKind == ModuleKind.ESModule && !qualName.contains('.')) { + val field = envField("e_" + qualName).asInstanceOf[js.VarRef] + val let = js.Let(field.ident, mutable = true, None) + val export = js.Export((field.ident -> js.ExportName(qualName)) :: Nil) + (js.Block(let, export), field) + } else { + val (createNamespace, namespace, lastPart) = + genCreateNamespaceInExportsAndGetNamespace(qualName) + (createNamespace, genBracketSelect(namespace, lastPart)) + } } /** Gen JS code for assigning an rhs to a qualified name in the exports scope. @@ -1151,7 +1165,10 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { * $e["foo"]["bar"] = $e["foo"]["bar"] || {}; * }}} * - * Returns `(statements, $e["foo"]["bar"], "Something")` + * In an `ESModule`, returns `(statements, $e_foo["bar"], "Something")`. + * + * For other module kinds, returns + * `(statements, $e["foo"]["bar"], "Something")`. */ private def genCreateNamespaceInExportsAndGetNamespace(qualName: String)( implicit pos: Position): (js.Tree, js.Tree, js.StringLiteral) = { @@ -1159,10 +1176,14 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val statements = List.newBuilder[js.Tree] var namespace = envField("e") for (i <- 0 until parts.length-1) { - namespace = genBracketSelect(namespace, js.StringLiteral(parts(i))) - statements += - js.Assign(namespace, js.BinaryOp(JSBinaryOp.||, - namespace, js.ObjectConstr(Nil))) + if (i == 0 && moduleKind == ModuleKind.ESModule) { + namespace = envField("e_" + parts(0)) + } else { + namespace = genBracketSelect(namespace, js.StringLiteral(parts(i))) + statements += + js.Assign(namespace, js.BinaryOp(JSBinaryOp.||, + namespace, js.ObjectConstr(Nil))) + } } (js.Block(statements.result()), namespace, js.StringLiteral(parts.last)) } diff --git 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 index 65cb4b7acf..455090b351 100644 --- 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 @@ -73,7 +73,7 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, true } - case ModuleKind.CommonJSModule => + case ModuleKind.ESModule | ModuleKind.CommonJSModule => false } } @@ -109,6 +109,7 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, val orderedClasses = unit.classDefs.sortWith(compareClasses) emitModuleImports(orderedClasses, builder, logger) + emitModuleExports(orderedClasses, builder, logger) /* Emit all the classes, in the appropriate order: * @@ -147,6 +148,29 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, private def emitModuleImports(orderedClasses: List[LinkedClass], builder: JSTreeBuilder, logger: Logger): Unit = { + + def foreachImportedModule(f: (String, Position) => Unit): Unit = { + val encounteredModuleNames = mutable.Set.empty[String] + for (classDef <- orderedClasses) { + def addModuleRef(module: String): Unit = { + if (encounteredModuleNames.add(module)) + f(module, classDef.pos) + } + + classDef.jsNativeLoadSpec match { + case None => + case Some(JSNativeLoadSpec.Global(_)) => + + case Some(JSNativeLoadSpec.Import(module, _)) => + addModuleRef(module) + + case Some(JSNativeLoadSpec.ImportWithGlobalFallback( + JSNativeLoadSpec.Import(module, _), _)) => + addModuleRef(module) + } + } + } + moduleKind match { case ModuleKind.NoModule => var importsFound: Boolean = false @@ -172,31 +196,61 @@ final class Emitter private (semantics: Semantics, outputMode: OutputMode, "ModuleKind.CommonJSModule.") } + case ModuleKind.ESModule => + foreachImportedModule { (module, pos0) => + implicit val pos = pos0 + val from = js.StringLiteral(module) + val moduleBinding = jsGen.envModuleField(module).ident + val importStat = js.ImportNamespace(moduleBinding, from) + builder.addJSTree(importStat) + } + case ModuleKind.CommonJSModule => - val encounteredModuleNames = mutable.Set.empty[String] + foreachImportedModule { (module, pos0) => + implicit val pos = pos0 + val rhs = js.Apply(js.VarRef(js.Ident("require")), + List(js.StringLiteral(module))) + val lhs = jsGen.envModuleField(module) + val decl = jsGen.genLet(lhs.ident, mutable = false, rhs) + builder.addJSTree(decl) + } + } + } - for (classDef <- orderedClasses) { - def addModuleRef(module: String): Unit = { - if (encounteredModuleNames.add(module)) { - implicit val pos = classDef.pos - val rhs = js.Apply(js.VarRef(js.Ident("require")), - List(js.StringLiteral(module))) - val lhs = jsGen.envModuleField(module) - val decl = jsGen.genLet(lhs.ident, mutable = false, rhs) - builder.addJSTree(decl) - } + private def emitModuleExports(orderedClasses: List[LinkedClass], + builder: JSTreeBuilder, logger: Logger): Unit = { + moduleKind match { + case ModuleKind.NoModule | ModuleKind.CommonJSModule => + + case ModuleKind.ESModule => + /* Things that are exported under an unqualified name will emit their + * own `export` clauses. Here, we only declare top-level namespaces for + * qualified export names, i.e., the part before the first '.', when + * there is one. + */ + + val topLevelNamespaces = mutable.Set.empty[String] + + def declareAndExportNamespace(namespace: String): Unit = { + if (topLevelNamespaces.add(namespace)) { + implicit val pos = Position.NoPosition + val exportVarIdent = + jsGen.envField("e_" + namespace).asInstanceOf[js.VarRef].ident + builder.addJSTree(js.Let( + exportVarIdent, mutable = false, Some(js.ObjectConstr(Nil)))) + builder.addJSTree( + js.Export((exportVarIdent -> js.ExportName(namespace)) :: Nil)) } + } - classDef.jsNativeLoadSpec match { - case None => - case Some(JSNativeLoadSpec.Global(_)) => - - case Some(JSNativeLoadSpec.Import(module, _)) => - addModuleRef(module) - - case Some(JSNativeLoadSpec.ImportWithGlobalFallback( - JSNativeLoadSpec.Import(module, _), _)) => - addModuleRef(module) + for (classDef <- orderedClasses) { + // Early exit for classes without any top-level exports (most of them) + if (classDef.classExports.nonEmpty) { + for (fullName <- classDef.topLevelExportNames) { + val dotPos = fullName.indexOf('.') + if (dotPos >= 0) + declareAndExportNamespace(fullName.substring(0, dotPos)) + } } } } diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala index bce65cedd1..3986f50d36 100644 --- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala +++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/JSGen.scala @@ -188,7 +188,7 @@ private[emitter] final class JSGen(val semantics: Semantics, case irt.JSNativeLoadSpec.Import(module, path) => val moduleValue = envModuleField(module) path match { - case DefaultExportName :: rest => + case DefaultExportName :: rest if moduleKind == ModuleKind.CommonJSModule => val defaultField = genCallHelper("moduleDefault", moduleValue) pathSelection(defaultField, rest) case _ => @@ -199,7 +199,7 @@ private[emitter] final class JSGen(val semantics: Semantics, moduleKind match { case ModuleKind.NoModule => genLoadJSFromSpec(globalSpec) - case ModuleKind.CommonJSModule => + case ModuleKind.ESModule | ModuleKind.CommonJSModule => genLoadJSFromSpec(importSpec) } } From e44ac21516ccedda81dd7d0020cd8e82bbba939d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 7 Nov 2018 11:57:57 +0100 Subject: [PATCH 0852/2665] Disallow namespaced top-level exports. `@JSExportTopLevel` with namespaces (containing a `.`) were deprecated in 9404d59827747bd36bb64e09b494bbaa4b423203 because they do not have any appropriate equivalent in ECMAScript modules. This commit disallows them. --- .../org/scalajs/nscplugin/PrepJSExports.scala | 2 +- .../scalajs/nscplugin/test/JSExportTest.scala | 46 ++++-- .../testsuite/jsinterop/ExportsTest.scala | 153 ++++++------------ 3 files changed, 81 insertions(+), 120 deletions(-) diff --git a/compiler/src/main/scala/org/scalajs/nscplugin/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/nscplugin/PrepJSExports.scala index ca7a446789..db7d092bd3 100644 --- a/compiler/src/main/scala/org/scalajs/nscplugin/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/PrepJSExports.scala @@ -321,7 +321,7 @@ trait PrepJSExports { this: PrepJSInterop => } // The top-level name must be a valid JS identifier - if (!isValidIdentifier(name.split('.').head)) { + if (!isValidIdentifier(name)) { reporter.error(annot.pos, "The top-level export name must be a valid JavaScript " + "identifier") diff --git a/compiler/src/test/scala/org/scalajs/nscplugin/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/JSExportTest.scala index 60e8f28336..df8f494054 100644 --- a/compiler/src/test/scala/org/scalajs/nscplugin/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/JSExportTest.scala @@ -1006,15 +1006,6 @@ class JSExportTest extends DirectTest with TestHelpers { @JSExportTopLevel("") object D - - @JSExportTopLevel("not-a-valid-JS-identifier-6.foo") - object E - - @JSExportTopLevel("foo.not-a-valid-JS-identifier-7") // valid - object F - - @JSExportTopLevel(".tricky") - object G """ hasErrors """ |newSource1.scala:3: error: The top-level export name must be a valid JavaScript identifier @@ -1035,12 +1026,41 @@ class JSExportTest extends DirectTest with TestHelpers { |newSource1.scala:20: error: The top-level export name must be a valid JavaScript identifier | @JSExportTopLevel("") | ^ - |newSource1.scala:23: error: The top-level export name must be a valid JavaScript identifier - | @JSExportTopLevel("not-a-valid-JS-identifier-6.foo") + """ + } + + @Test + def noExportTopLevelNamespaced: Unit = { + """ + @JSExportTopLevel("namespaced.export1") + object A + @JSExportTopLevel("namespaced.export2") + class B + object C { + @JSExportTopLevel("namespaced.export3") + val a: Int = 1 + @JSExportTopLevel("namespaced.export4") + var b: Int = 1 + @JSExportTopLevel("namespaced.export5") + def c(): Int = 1 + } + """ hasErrors + """ + |newSource1.scala:3: error: The top-level export name must be a valid JavaScript identifier + | @JSExportTopLevel("namespaced.export1") | ^ - |newSource1.scala:29: error: The top-level export name must be a valid JavaScript identifier - | @JSExportTopLevel(".tricky") + |newSource1.scala:5: error: The top-level export name must be a valid JavaScript identifier + | @JSExportTopLevel("namespaced.export2") | ^ + |newSource1.scala:8: error: The top-level export name must be a valid JavaScript identifier + | @JSExportTopLevel("namespaced.export3") + | ^ + |newSource1.scala:10: error: The top-level export name must be a valid JavaScript identifier + | @JSExportTopLevel("namespaced.export4") + | ^ + |newSource1.scala:12: error: The top-level export name must be a valid JavaScript identifier + | @JSExportTopLevel("namespaced.export5") + | ^ """ } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index f91ef38f6f..7d2f8172ae 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -52,9 +52,6 @@ class ExportsTest { } } - /** This package in the JS (export) namespace */ - val jsPackage = exportsNamespace.org.scalajs.testsuite.jsinterop - // @JSExport @Test def exports_for_methods_with_implicit_name(): Unit = { @@ -705,15 +702,8 @@ class ExportsTest { assertSame(obj1, SJSDefinedExportedObject) } - @Test def toplevel_exports_for_objects_with_qualified_name(): Unit = { - val obj = exportsNamespace.qualified.testobject.TopLevelExportedObject - assertJSNotUndefined(obj) - assertEquals("object", js.typeOf(obj)) - assertEquals("witness", obj.witness) - } - @Test def toplevel_exports_for_nested_objects(): Unit = { - val obj = exportsNamespace.qualified.nested.ExportedObject + val obj = exportsNamespace.NestedExportedObject assertJSNotUndefined(obj) assertEquals("object", js.typeOf(obj)) assertSame(obj, ExportHolder.ExportedObject) @@ -752,48 +742,22 @@ class ExportsTest { assertSame(constr, js.constructorOf[SJSDefinedTopLevelExportedClass]) } - @Test def toplevel_exports_for_classes_with_qualified_name(): Unit = { - val constr = exportsNamespace.qualified.testclass.TopLevelExportedClass - assertJSNotUndefined(constr) - assertEquals("function", js.typeOf(constr)) - val obj = js.Dynamic.newInstance(constr)(5) - assertEquals(5, obj.x) - } - @Test def toplevel_exports_for_nested_classes(): Unit = { - val constr = exportsNamespace.qualified.nested.ExportedClass + val constr = exportsNamespace.NestedExportedClass assertJSNotUndefined(constr) assertEquals("function", js.typeOf(constr)) val obj = js.Dynamic.newInstance(constr)() assertTrue((obj: Any).isInstanceOf[ExportHolder.ExportedClass]) } - @Test def toplevel_exports_for_classes_with_qualified_name_SJSDefinedExportedClass(): Unit = { - val constr = exportsNamespace.qualified.testclass.SJSDefinedTopLevelExportedClass - assertJSNotUndefined(constr) - assertEquals("function", js.typeOf(constr)) - val obj = js.Dynamic.newInstance(constr)(5) - assertTrue((obj: Any).isInstanceOf[SJSDefinedTopLevelExportedClass]) - assertEquals(5, obj.x) - } - @Test def toplevel_exports_for_nested_sjs_defined_classes(): Unit = { - val constr = exportsNamespace.qualified.nested.SJSDefinedExportedClass + val constr = exportsNamespace.NestedSJSDefinedExportedClass assertJSNotUndefined(constr) assertEquals("function", js.typeOf(constr)) val obj = js.Dynamic.newInstance(constr)() assertTrue((obj: Any).isInstanceOf[ExportHolder.SJSDefinedExportedClass]) } - @Test def toplevel_exports_under_nested_invalid_js_identifier(): Unit = { - val constr = exportsNamespace.qualified.selectDynamic("not-a-JS-identifier") - assertJSNotUndefined(constr) - assertEquals("function", js.typeOf(constr)) - val obj = js.Dynamic.newInstance(constr)() - assertTrue( - (obj: Any).isInstanceOf[ExportHolder.ClassExportedUnderNestedInvalidJSIdentifier]) - } - @Test def exports_for_classes_with_constant_folded_name(): Unit = { val constr = exportsNamespace.ConstantFoldedClassExport assertJSNotUndefined(constr) @@ -975,11 +939,6 @@ class ExportsTest { assertEquals(1, foo.b) } - @Test def exporting_under_org_namespace_issue_364(): Unit = { - val obj = exportsNamespace.org.ExportedUnderOrgObject - assertSame(ExportedUnderOrgObject.asInstanceOf[js.Any], obj) - } - @Test def null_for_arguments_of_primitive_value_type_issue_1719(): Unit = { @JSExportAll class Foo { @@ -1229,48 +1188,43 @@ class ExportsTest { // @JSExportTopLevel @Test def basic_top_level_export(): Unit = { - assertEquals(1, jsPackage.toplevel.basic()) + assertEquals(1, exportsNamespace.TopLevelExport_basic()) } @Test def overloaded_top_level_export(): Unit = { - assertEquals("Hello World", jsPackage.toplevel.overload("World")) - assertEquals(2, jsPackage.toplevel.overload(2)) - assertEquals(9, jsPackage.toplevel.overload(2, 7)) - assertEquals(10, jsPackage.toplevel.overload(1, 2, 3, 4)) - } - - @Test def method_top_level_export_under_invalid_js_identifier(): Unit = { - assertEquals("not an identifier", - jsPackage.toplevel.applyDynamic("not-a-JS-identifier")()) + assertEquals("Hello World", exportsNamespace.TopLevelExport_overload("World")) + assertEquals(2, exportsNamespace.TopLevelExport_overload(2)) + assertEquals(9, exportsNamespace.TopLevelExport_overload(2, 7)) + assertEquals(10, exportsNamespace.TopLevelExport_overload(1, 2, 3, 4)) } @Test def top_level_export_uses_unique_object(): Unit = { - jsPackage.toplevel.set(3) + exportsNamespace.TopLevelExport_set(3) assertEquals(3, TopLevelExports.myVar) - jsPackage.toplevel.set(7) + exportsNamespace.TopLevelExport_set(7) assertEquals(7, TopLevelExports.myVar) } @Test def top_level_export_from_nested_object(): Unit = { - jsPackage.toplevel.setNested(28) + exportsNamespace.TopLevelExport_setNested(28) assertEquals(28, TopLevelExports.Nested.myVar) } @Test def top_level_export_is_always_reachable(): Unit = { - assertEquals("Hello World", jsPackage.toplevel.reachability()) + assertEquals("Hello World", exportsNamespace.TopLevelExport_reachability()) } // @JSExportTopLevel fields @Test def top_level_export_basic_field(): Unit = { // Initialization - assertEquals(5, jsPackage.toplevel.basicVal) - assertEquals("hello", jsPackage.toplevel.basicVar) + assertEquals(5, exportsNamespace.TopLevelExport_basicVal) + assertEquals("hello", exportsNamespace.TopLevelExport_basicVar) // Scala modifies var TopLevelFieldExports.basicVar = "modified" assertEquals("modified", TopLevelFieldExports.basicVar) - assertEquals("modified", jsPackage.toplevel.basicVar) + assertEquals("modified", exportsNamespace.TopLevelExport_basicVar) // Reset var TopLevelFieldExports.basicVar = "hello" @@ -1278,15 +1232,15 @@ class ExportsTest { @Test def top_level_export_field_twice(): Unit = { // Initialization - assertEquals(5, jsPackage.toplevel.valExportedTwice1) - assertEquals("hello", jsPackage.toplevel.varExportedTwice1) - assertEquals("hello", jsPackage.toplevel.varExportedTwice2) + assertEquals(5, exportsNamespace.TopLevelExport_valExportedTwice1) + assertEquals("hello", exportsNamespace.TopLevelExport_varExportedTwice1) + assertEquals("hello", exportsNamespace.TopLevelExport_varExportedTwice2) // Scala modifies var TopLevelFieldExports.varExportedTwice = "modified" assertEquals("modified", TopLevelFieldExports.varExportedTwice) - assertEquals("modified", jsPackage.toplevel.varExportedTwice1) - assertEquals("modified", jsPackage.toplevel.varExportedTwice2) + assertEquals("modified", exportsNamespace.TopLevelExport_varExportedTwice1) + assertEquals("modified", exportsNamespace.TopLevelExport_varExportedTwice2) // Reset var TopLevelFieldExports.varExportedTwice = "hello" @@ -1294,30 +1248,30 @@ class ExportsTest { @Test def top_level_export_write_val_var_causes_typeerror(): Unit = { assertThrows(classOf[js.JavaScriptException], { - jsPackage.toplevel.basicVal = 54 + exportsNamespace.TopLevelExport_basicVal = 54 }) assertThrows(classOf[js.JavaScriptException], { - jsPackage.toplevel.basicVar = 54 + exportsNamespace.TopLevelExport_basicVar = 54 }) } @Test def top_level_export_uninitialized_fields(): Unit = { assertEquals(0, TopLevelFieldExports.uninitializedVarInt) - assertEquals(null, jsPackage.toplevel.uninitializedVarInt) + assertEquals(null, exportsNamespace.TopLevelExport_uninitializedVarInt) assertEquals(0L, TopLevelFieldExports.uninitializedVarLong) - assertEquals(null, jsPackage.toplevel.uninitializedVarLong) + assertEquals(null, exportsNamespace.TopLevelExport_uninitializedVarLong) assertEquals(null, TopLevelFieldExports.uninitializedVarString) - assertEquals(null, jsPackage.toplevel.uninitializedVarString) + assertEquals(null, exportsNamespace.TopLevelExport_uninitializedVarString) assertEquals('\u0000', TopLevelFieldExports.uninitializedVarChar) - assertEquals(null, jsPackage.toplevel.uninitializedVarChar) + assertEquals(null, exportsNamespace.TopLevelExport_uninitializedVarChar) } @Test def top_level_export_field_is_always_reachable_and_initialized(): Unit = { - assertEquals("Hello World", jsPackage.toplevel.fieldreachability) + assertEquals("Hello World", exportsNamespace.TopLevelExport_fieldreachability) } } @@ -1329,7 +1283,6 @@ object ExportNameHolder { } @JSExportTopLevel("TopLevelExportedObject") -@JSExportTopLevel("qualified.testobject.TopLevelExportedObject") @JSExportTopLevel(ExportNameHolder.objectName) object TopLevelExportedObject { @JSExport @@ -1337,7 +1290,6 @@ object TopLevelExportedObject { } @JSExportTopLevel("SJSDefinedTopLevelExportedObject") -@JSExportTopLevel("qualified.testobject.SJSDefinedTopLevelExportedObject") object SJSDefinedExportedObject extends js.Object { val witness: String = "witness" } @@ -1349,7 +1301,6 @@ protected object ProtectedExportedObject { } @JSExportTopLevel("TopLevelExportedClass") -@JSExportTopLevel("qualified.testclass.TopLevelExportedClass") @JSExportTopLevel(ExportNameHolder.className) class TopLevelExportedClass(_x: Int) { @JSExport @@ -1357,7 +1308,6 @@ class TopLevelExportedClass(_x: Int) { } @JSExportTopLevel("SJSDefinedTopLevelExportedClass") -@JSExportTopLevel("qualified.testclass.SJSDefinedTopLevelExportedClass") class SJSDefinedTopLevelExportedClass(val x: Int) extends js.Object @JSExportTopLevel("ProtectedExportedClass") @@ -1386,47 +1336,38 @@ class ExportedDefaultArgClass(x: Int, y: Int, z: Int) { def result: Int = x + y + z } -@JSExportTopLevel("org.ExportedUnderOrgObject") -object ExportedUnderOrgObject - class SomeValueClass(val i: Int) extends AnyVal object ExportHolder { - @JSExportTopLevel("qualified.nested.ExportedClass") + @JSExportTopLevel("NestedExportedClass") class ExportedClass - @JSExportTopLevel("qualified.nested.ExportedObject") + @JSExportTopLevel("NestedExportedObject") object ExportedObject - @JSExportTopLevel("qualified.nested.SJSDefinedExportedClass") + @JSExportTopLevel("NestedSJSDefinedExportedClass") class SJSDefinedExportedClass extends js.Object - - @JSExportTopLevel("qualified.not-a-JS-identifier") - class ClassExportedUnderNestedInvalidJSIdentifier } object TopLevelExports { - @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.basic") + @JSExportTopLevel("TopLevelExport_basic") def basic(): Int = 1 - @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.overload") + @JSExportTopLevel("TopLevelExport_overload") def overload(x: String): String = "Hello " + x - @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.overload") + @JSExportTopLevel("TopLevelExport_overload") def overload(x: Int, y: Int*): Int = x + y.sum - @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.not-a-JS-identifier") - def methodExportedUnderNestedInvalidJSIdentifier(): String = "not an identifier" - var myVar: Int = _ - @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.set") + @JSExportTopLevel("TopLevelExport_set") def setMyVar(x: Int): Unit = myVar = x object Nested { var myVar: Int = _ - @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.setNested") + @JSExportTopLevel("TopLevelExport_setNested") def setMyVar(x: Int): Unit = myVar = x } } @@ -1437,35 +1378,35 @@ object TopLevelExports { object TopLevelExportsReachability { private val name = "World" - @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.reachability") + @JSExportTopLevel("TopLevelExport_reachability") def basic(): String = "Hello " + name } object TopLevelFieldExports { - @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.basicVal") + @JSExportTopLevel("TopLevelExport_basicVal") val basicVal: Int = 5 - @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.basicVar") + @JSExportTopLevel("TopLevelExport_basicVar") var basicVar: String = "hello" - @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.valExportedTwice1") - @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.valExportedTwice2") + @JSExportTopLevel("TopLevelExport_valExportedTwice1") + @JSExportTopLevel("TopLevelExport_valExportedTwice2") val valExportedTwice: Int = 5 - @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.varExportedTwice1") - @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.varExportedTwice2") + @JSExportTopLevel("TopLevelExport_varExportedTwice1") + @JSExportTopLevel("TopLevelExport_varExportedTwice2") var varExportedTwice: String = "hello" - @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.uninitializedVarInt") + @JSExportTopLevel("TopLevelExport_uninitializedVarInt") var uninitializedVarInt: Int = _ - @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.uninitializedVarLong") + @JSExportTopLevel("TopLevelExport_uninitializedVarLong") var uninitializedVarLong: Long = _ - @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.uninitializedVarString") + @JSExportTopLevel("TopLevelExport_uninitializedVarString") var uninitializedVarString: String = _ - @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.uninitializedVarChar") + @JSExportTopLevel("TopLevelExport_uninitializedVarChar") var uninitializedVarChar: Char = _ } @@ -1476,6 +1417,6 @@ object TopLevelFieldExports { object TopLevelFieldExportsReachability { private val name = "World" - @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.fieldreachability") + @JSExportTopLevel("TopLevelExport_fieldreachability") val greeting = "Hello " + name } From 867e3afaf25346dce78e631037a6672336e482f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 7 Nov 2018 14:21:54 +0100 Subject: [PATCH 0853/2665] Simplify the Emitter now that namespaced top-level export are gone. The definition of the IR is implicitly simplified, and we rename the field `fullName` to `exportName` now that it cannot contain namespaces anymore. We simplify the `ClassEmitter` as we remove all the handling of namespaces in top-level exports. --- .../main/scala/org/scalajs/ir/Printers.scala | 12 +- .../scala/org/scalajs/ir/Serializers.scala | 12 +- ir/src/main/scala/org/scalajs/ir/Trees.scala | 6 +- .../linker/backend/emitter/ClassEmitter.scala | 123 ++++-------------- .../scalajs/linker/checker/IRChecker.scala | 2 +- 5 files changed, 39 insertions(+), 116 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/ir/Printers.scala b/ir/src/main/scala/org/scalajs/ir/Printers.scala index bd643bb9fd..f9582e7a7b 100644 --- a/ir/src/main/scala/org/scalajs/ir/Printers.scala +++ b/ir/src/main/scala/org/scalajs/ir/Printers.scala @@ -915,25 +915,25 @@ object Printers { def print(topLevelExportDef: TopLevelExportDef): Unit = { topLevelExportDef match { - case TopLevelJSClassExportDef(fullName) => + case TopLevelJSClassExportDef(exportName) => print("export top class \"") - printEscapeJS(fullName, out) + printEscapeJS(exportName, out) print('\"') - case TopLevelModuleExportDef(fullName) => + case TopLevelModuleExportDef(exportName) => print("export top module \"") - printEscapeJS(fullName, out) + printEscapeJS(exportName, out) print('\"') case TopLevelMethodExportDef(methodDef) => print("export top ") print(methodDef) - case TopLevelFieldExportDef(fullName, field) => + case TopLevelFieldExportDef(exportName, field) => print("export top static field ") print(field) print(" as \"") - printEscapeJS(fullName, out) + printEscapeJS(exportName, out) print('\"') } } diff --git a/ir/src/main/scala/org/scalajs/ir/Serializers.scala b/ir/src/main/scala/org/scalajs/ir/Serializers.scala index 22f25c8a37..b8a5cac9c4 100644 --- a/ir/src/main/scala/org/scalajs/ir/Serializers.scala +++ b/ir/src/main/scala/org/scalajs/ir/Serializers.scala @@ -536,21 +536,21 @@ object Serializers { import buffer._ writePosition(topLevelExportDef.pos) topLevelExportDef match { - case TopLevelJSClassExportDef(fullName) => + case TopLevelJSClassExportDef(exportName) => writeByte(TagTopLevelJSClassExportDef) - writeString(fullName) + writeString(exportName) - case TopLevelModuleExportDef(fullName) => + case TopLevelModuleExportDef(exportName) => writeByte(TagTopLevelModuleExportDef) - writeString(fullName) + writeString(exportName) case TopLevelMethodExportDef(methodDef) => writeByte(TagTopLevelMethodExportDef) writeMemberDef(methodDef) - case TopLevelFieldExportDef(fullName, field) => + case TopLevelFieldExportDef(exportName, field) => writeByte(TagTopLevelFieldExportDef) - writeString(fullName); writeIdent(field) + writeString(exportName); writeIdent(field) } } diff --git a/ir/src/main/scala/org/scalajs/ir/Trees.scala b/ir/src/main/scala/org/scalajs/ir/Trees.scala index 41d83d1aae..747fa38ff2 100644 --- a/ir/src/main/scala/org/scalajs/ir/Trees.scala +++ b/ir/src/main/scala/org/scalajs/ir/Trees.scala @@ -999,7 +999,7 @@ object Trees { } } - case class TopLevelJSClassExportDef(fullName: String)( + case class TopLevelJSClassExportDef(exportName: String)( implicit val pos: Position) extends TopLevelExportDef /** Export for a top-level object. @@ -1007,13 +1007,13 @@ object Trees { * This exports the singleton instance of the containing module class. * The instance is initialized during ES module instantiation. */ - case class TopLevelModuleExportDef(fullName: String)( + case class TopLevelModuleExportDef(exportName: String)( implicit val pos: Position) extends TopLevelExportDef case class TopLevelMethodExportDef(methodDef: MethodDef)( implicit val pos: Position) extends TopLevelExportDef - case class TopLevelFieldExportDef(fullName: String, field: Ident)( + case class TopLevelFieldExportDef(exportName: String, field: Ident)( implicit val pos: Position) extends TopLevelExportDef // Miscellaneous diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala index 0dd45bc2d4..cc5dd4acbf 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala @@ -1057,12 +1057,17 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { def genTopLevelExports(tree: LinkedClass)( implicit globalKnowledge: GlobalKnowledge): WithGlobals[List[js.Tree]] = { - val exportsWithGlobals = tree.topLevelExports.map { topLevelExport => - topLevelExport.value match { - case e: TopLevelJSClassExportDef => - WithGlobals(genTopLevelJSClassExportDef(tree, e)) - case e: TopLevelModuleExportDef => - WithGlobals(genTopLevelModuleExportDef(tree, e)) + val exportsWithGlobals = tree.topLevelExports.map { versionedTopLevelExport => + val topLevelExport = versionedTopLevelExport.value + implicit val pos = topLevelExport.pos + + topLevelExport match { + case TopLevelJSClassExportDef(exportName) => + WithGlobals(genConstValueExportDef( + exportName, genNonNativeJSClassConstructor(tree.name.name))) + case TopLevelModuleExportDef(exportName) => + WithGlobals(genConstValueExportDef( + exportName, genLoadModule(tree.name.name))) case e: TopLevelMethodExportDef => genTopLevelMethodExportDef(tree, e) case e: TopLevelFieldExportDef => @@ -1073,79 +1078,40 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { WithGlobals.list(exportsWithGlobals) } - def genTopLevelJSClassExportDef(cd: LinkedClass, - tree: TopLevelJSClassExportDef): js.Tree = { - import TreeDSL._ - - implicit val pos = tree.pos - - val classVar = genNonNativeJSClassConstructor(cd.name.name) - genClassOrModuleExportDef(cd, tree.fullName, classVar) - } - - /** Generates an exporter for a module at the top-level. - * - * This corresponds to an `@JSExportTopLevel` on a module class. The module - * instance is initialized during ES module instantiation. - */ - def genTopLevelModuleExportDef(cd: LinkedClass, - tree: TopLevelModuleExportDef): js.Tree = { - import TreeDSL._ - - implicit val pos = tree.pos - - val moduleVar = genLoadModule(cd.name.name) - genClassOrModuleExportDef(cd, tree.fullName, moduleVar) - } - - private def genClassOrModuleExportDef(cd: LinkedClass, exportFullName: String, - exportedValue: js.Tree)(implicit pos: Position): js.Tree = { - import TreeDSL._ - - val (createNamespace, expAccessorVar) = - genCreateNamespaceInExports(exportFullName) - js.Block( - createNamespace, - expAccessorVar := exportedValue - ) - } - private def genTopLevelMethodExportDef(cd: LinkedClass, tree: TopLevelMethodExportDef)( implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { import TreeDSL._ - val MethodDef(true, StringLiteral(fullName), args, resultType, Some(body)) = + val MethodDef(true, StringLiteral(exportName), args, resultType, Some(body)) = tree.methodDef implicit val pos = tree.pos - val (createNamespace, expAccessorVar) = - genCreateNamespaceInExports(fullName) - val methodDefWithGlobals = desugarToFunction(cd.encodedName, args, body, resultType) for (methodDef <- methodDefWithGlobals) yield { - js.Block( - createNamespace, - expAccessorVar := methodDef - ) + genConstValueExportDef(exportName, methodDef) } } + private def genConstValueExportDef(exportName: String, + exportedValue: js.Tree)( + implicit pos: Position): js.Tree = { + js.Assign(genBracketSelect(envField("e"), js.StringLiteral(exportName)), + exportedValue) + } + private def genTopLevelFieldExportDef(cd: LinkedClass, tree: TopLevelFieldExportDef)( implicit globalKnowledge: GlobalKnowledge): js.Tree = { import TreeDSL._ - val TopLevelFieldExportDef(fullName, field) = tree + val TopLevelFieldExportDef(exportName, field) = tree implicit val pos = tree.pos - val (createNamespace, namespace, fieldName) = - genCreateNamespaceInExportsAndGetNamespace(fullName) - // defineProperty method val defProp = genIdentBracketSelect(js.VarRef(js.Ident("Object")), "defineProperty") @@ -1164,10 +1130,8 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { Nil ) - val callDefineProp = - js.Apply(defProp, namespace :: fieldName :: descriptor :: Nil) - - js.Block(createNamespace, callDefineProp) + js.Apply(defProp, + envField("e") :: js.StringLiteral(exportName) :: descriptor :: Nil) } // Helpers @@ -1205,47 +1169,6 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { } } - /** Gen JS code for assigning an rhs to a qualified name in the exports scope. - * For example, given the qualified name `"foo.bar.Something"`, generates: - * - * {{{ - * $e["foo"] = $e["foo"] || {}; - * $e["foo"]["bar"] = $e["foo"]["bar"] || {}; - * }}} - * - * Returns `(statements, $e["foo"]["bar"]["Something"])` - */ - private def genCreateNamespaceInExports(qualName: String)( - implicit pos: Position): (js.Tree, js.Tree) = { - val (createNamespace, namespace, lastPart) = - genCreateNamespaceInExportsAndGetNamespace(qualName) - (createNamespace, genBracketSelect(namespace, lastPart)) - } - - /** Gen JS code for assigning an rhs to a qualified name in the exports scope. - * For example, given the qualified name `"foo.bar.Something"`, generates: - * - * {{{ - * $e["foo"] = $e["foo"] || {}; - * $e["foo"]["bar"] = $e["foo"]["bar"] || {}; - * }}} - * - * Returns `(statements, $e["foo"]["bar"], "Something")` - */ - private def genCreateNamespaceInExportsAndGetNamespace(qualName: String)( - implicit pos: Position): (js.Tree, js.Tree, js.StringLiteral) = { - val parts = qualName.split("\\.") - val statements = List.newBuilder[js.Tree] - var namespace: js.Tree = envField("e") - for (i <- 0 until parts.length-1) { - namespace = genBracketSelect(namespace, js.StringLiteral(parts(i))) - statements += - js.Assign(namespace, js.BinaryOp(JSBinaryOp.||, - namespace, js.ObjectConstr(Nil))) - } - (js.Block(statements.result()), namespace, js.StringLiteral(parts.last)) - } - /** Gen JS code for an [[ModuleInitializer]]. */ def genModuleInitializer(moduleInitializer: ModuleInitializer): js.Tree = { import TreeDSL._ diff --git a/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala b/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala index 137808d3d6..3c154c232e 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala @@ -231,7 +231,7 @@ private final class IRChecker(unit: LinkingUnit, case TopLevelMethodExportDef(methodDef) => checkExportedMethodDef(methodDef, classDef, isTopLevel = true) - case TopLevelFieldExportDef(fullName, field) => + case TopLevelFieldExportDef(_, field) => lookupClass(classDef.name.name).lookupStaticField(field.name).fold { reportError(s"Cannot export non-existent static field '$field'") } { checkedField => From 26f826aaa280025e45a0507ead6e1d725a92ff26 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Tue, 6 Nov 2018 21:13:50 +0100 Subject: [PATCH 0854/2665] JUnit: Simplify RunSettings - Remove unused build*Message methods. - Hide decodeScalaNames. - Forbid unsupported flags. --- .../com/novocode/junit/JUnitFramework.scala | 11 ++-- .../com/novocode/junit/RunSettings.scala | 61 ++++--------------- .../org/scalajs/junit/JUnitExecuteTest.scala | 9 +-- 3 files changed, 17 insertions(+), 64 deletions(-) diff --git a/junit-runtime/src/main/scala/com/novocode/junit/JUnitFramework.scala b/junit-runtime/src/main/scala/com/novocode/junit/JUnitFramework.scala index 04bb2041fd..9d573e78ef 100644 --- a/junit-runtime/src/main/scala/com/novocode/junit/JUnitFramework.scala +++ b/junit-runtime/src/main/scala/com/novocode/junit/JUnitFramework.scala @@ -48,8 +48,6 @@ final class JUnitFramework extends Framework { var decodeScalaNames = false var logAssert = false var notLogExceptionClass = false - var ignoreRunners = "org.junit.runners.Suite" - var runListener: String = null for (str <- args) { str match { case "-q" => quiet = true @@ -63,13 +61,13 @@ final class JUnitFramework extends Framework { throw new UnsupportedOperationException("-tests") case s if s.startsWith("--tests=") => - throw new UnsupportedOperationException("--tests") + throw new UnsupportedOperationException("--tests") case s if s.startsWith("--ignore-runners=") => - ignoreRunners = s.substring(17) + throw new UnsupportedOperationException("--ignore-runners") case s if s.startsWith("--run-listener=") => - runListener = s.substring(15) + throw new UnsupportedOperationException("--run-listener") case s if s.startsWith("--include-categories=") => throw new UnsupportedOperationException("--include-categories") @@ -97,7 +95,6 @@ final class JUnitFramework extends Framework { case _ => } } - new RunSettings(!noColor, decodeScalaNames, quiet, verbose, logAssert, - ignoreRunners, notLogExceptionClass) + new RunSettings(!noColor, decodeScalaNames, quiet, verbose, logAssert, notLogExceptionClass) } } diff --git a/junit-runtime/src/main/scala/com/novocode/junit/RunSettings.scala b/junit-runtime/src/main/scala/com/novocode/junit/RunSettings.scala index 2b6cb6f796..5c5fe7bbdc 100644 --- a/junit-runtime/src/main/scala/com/novocode/junit/RunSettings.scala +++ b/junit-runtime/src/main/scala/com/novocode/junit/RunSettings.scala @@ -18,55 +18,16 @@ import java.util.HashSet import scala.util.Try -class RunSettings private (val color: Boolean, val decodeScalaNames: Boolean, - val quiet: Boolean, val verbose: Boolean, val logAssert: Boolean, - val notLogExceptionClass: Boolean) { - - private val ignoreRunnersSet = new HashSet[String] - - def this(color: Boolean, decodeScalaNames: Boolean, quiet: Boolean, - verbose: Boolean, logAssert: Boolean, ignoreRunners: String, - notLogExceptionClass: Boolean) = { - this(color, decodeScalaNames, quiet, verbose, logAssert, notLogExceptionClass) - for (s <- ignoreRunners.split(",")) - ignoreRunnersSet.add(s.trim) - } - - def decodeName(name: String): String = - if (decodeScalaNames) RunSettings.decodeScalaName(name) else name - - def buildColoredMessage(t: Throwable, c1: String): String = { - if (t == null) "null" else { - if (notLogExceptionClass || (!logAssert && t.isInstanceOf[AssertionError])) { - t.getMessage - } else { - val b = new StringBuilder() - val cn = decodeName(t.getClass.getName) - val pos1 = cn.indexOf('$') - val pos2 = { - if (pos1 == -1) cn.lastIndexOf('.') - else cn.lastIndexOf('.', pos1) - } - if (pos2 == -1) b.append(c(cn, c1)) - else { - b.append(cn.substring(0, pos2)) - b.append('.') - b.append(c(cn.substring(pos2 + 1), c1)) - } - b.append(": ").append(t.getMessage) - b.toString() - } - } +final class RunSettings ( + val color: Boolean, + decodeScalaNames: Boolean, + val quiet: Boolean, + val verbose: Boolean, + val logAssert: Boolean, + val notLogExceptionClass: Boolean +) { + def decodeName(name: String): String = { + if (decodeScalaNames) Try(scala.reflect.NameTransformer.decode(name)).getOrElse(name) + else name } - - def buildInfoMessage(t: Throwable): String = - buildColoredMessage(t, NNAME2) - - def buildErrorMessage(t: Throwable): String = - buildColoredMessage(t, ENAME2) -} - -object RunSettings { - private[RunSettings] def decodeScalaName(name: String): String = - Try(scala.reflect.NameTransformer.decode(name)).getOrElse(name) } diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala index 574f96bdda..522ae074c2 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala @@ -27,8 +27,6 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, eventHandler: EventHandler) { private val taskDef = task.taskDef - private val verbose = runSettings.verbose - private val decodeScalaNames = runSettings.decodeScalaNames lazy val packageName = fullyQualifiedName.split('.').init.mkString(".") lazy val className = fullyQualifiedName.split('.').last @@ -80,12 +78,9 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, private[this] def executeTestMethod(bootstrapper: Bootstrapper, test: TestMetadata) = { val methodName = test.name - val decodedMethodName = { - if (decodeScalaNames) runSettings.decodeName(methodName) - else methodName - } + val decodedMethodName = runSettings.decodeName(methodName) - if (verbose) + if (runSettings.verbose) logFormattedInfo(decodedMethodName, "started") else logFormattedDebug(decodedMethodName, "started") From b1baa59cf550177dd3ecf3ca5e7211c6e0c52730 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Tue, 6 Nov 2018 21:15:46 +0100 Subject: [PATCH 0855/2665] JUnit: Fix expected reporting and simplify handling. Mainly driven by the insight that expected can be implemented with re-throwing an AssertionError. This simplifies logging. --- .../org/scalajs/junit/JUnitExecuteTest.scala | 57 ++++++++++--------- .../scala/org/scalajs/junit/ExpectTest.scala | 50 ++++++++++++++++ .../org/scalajs/junit/utils/JUnitTest.scala | 10 ++++ 3 files changed, 89 insertions(+), 28 deletions(-) create mode 100644 junit-test/shared/src/test/scala/org/scalajs/junit/ExpectTest.scala diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala index 522ae074c2..c93ff8a441 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala @@ -100,23 +100,10 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, } } - def execute(expectedException: Class[_] = classOf[org.junit.Test.None])( - body: => Unit): Boolean = { - + def execute(body: => Unit): Boolean = { try { body - - if (expectedException == classOf[org.junit.Test.None]) { - true - } else { - val msg = { - s"failed: Expected exception: " + expectedException + - s"took ${getTimeInSeconds()} sec" - } - logFormattedError(decodedMethodName, msg, None) - emitTestFailed() - false - } + true } catch { case ex: Throwable => val timeInSeconds = getTimeInSeconds() @@ -125,9 +112,7 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, logAssertionWarning(decodedMethodName, ex, timeInSeconds) testSkipped() false - } else if (expectedException.isInstance(ex)) { - true - } else if (expectedException == classOf[org.junit.Test.None]) { + } else { val isAssertion = ex.isInstanceOf[AssertionError] val failedMsg = new StringBuilder failedMsg ++= "failed: " @@ -149,38 +134,54 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, logFormattedError(decodedMethodName, msg, exOpt) emitTestFailed() false - } else { - val msg = s"failed: ${ex.getClass}, took $timeInSeconds sec" - logFormattedError(decodedMethodName, msg, Some(ex)) - emitTestFailed() - false } } } + def handleExpected(expectedException: Class[_ <: Throwable])(body: => Unit) = { + val wantException = expectedException != classOf[org.junit.Test.None] + val succeeded = try { + body + true + } catch { + case t if expectedException.isInstance(t) => false + + case t if wantException => + val expName = expectedException.getName + val gotName = t.getClass.getName + throw new Exception( + s"Unexpected exception, expected<$expName> but was<$gotName>", t) + } + + if (succeeded && wantException) + throw new AssertionError("Expected exception: " + expectedException.getName) + } + var testClassInstance: AnyRef = null - val instantiationSucceeded = execute() { + val instantiationSucceeded = execute { testClassInstance = bootstrapper.newInstance() } val success = if (!instantiationSucceeded) { false } else { - val beforeSucceeded = execute() { + val beforeSucceeded = execute { bootstrapper.before(testClassInstance) } val beforeAndTestSucceeded = if (!beforeSucceeded) { false } else { - execute(test.annotation.expected) { - bootstrapper.invokeTest(testClassInstance, test.name) + execute { + handleExpected(test.annotation.expected) { + bootstrapper.invokeTest(testClassInstance, test.name) + } } } // Whether before and/or test succeeded or not, run the after methods - val afterSucceeded = execute() { + val afterSucceeded = execute { bootstrapper.after(testClassInstance) } diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/ExpectTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/ExpectTest.scala new file mode 100644 index 0000000000..77fc186a63 --- /dev/null +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/ExpectTest.scala @@ -0,0 +1,50 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package org.scalajs.junit + +import org.junit._ +import org.junit.Assert._ + +import org.scalajs.junit.utils._ + +import java.io.IOException + +class ExpectTest { + @Test(expected = classOf[IOException]) + def expectNormal(): Unit = throw new IOException + + @Test(expected = classOf[IOException]) + def failExpectDifferent(): Unit = throw new IllegalArgumentException + + @Test(expected = classOf[IOException]) + def failExpectNoThrow(): Unit = () + + @Test(expected = classOf[AssertionError]) + def expectAssert(): Unit = throw new AssertionError + + @Test(expected = classOf[AssertionError]) + def failExpectAssert(): Unit = () +} + +class ExpectTestAssertions extends JUnitTest { + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = { + builder + .success("expectNormal") + .wrongException("failExpectDifferent", + "Unexpected exception, expected but was", + classOf[IllegalArgumentException]) + .assertion("failExpectNoThrow", "Expected exception: java.io.IOException") + .success("expectAssert") + .assertion("failExpectAssert", "Expected exception: java.lang.AssertionError") + } +} diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala index c3c3722195..9c869fdff9 100644 --- a/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/utils/JUnitTest.scala @@ -125,6 +125,16 @@ abstract class JUnitTest { testFinishedOutput(testName) ) + def wrongException(testName: String, msg: String, clazz: ThrowableClass): OutputBuilder = { + append(1, 0, 1)( + testStartedOutput(testName), + testExceptionMsgOutput(testName, msg, classOf[Exception]), + Error(s"Caused by: ${clazz.getName}"), + failureEvent, + testFinishedOutput(testName) + ) + } + def exception(testName: String, msg: String, clazz: ThrowableClass): OutputBuilder = { append(1, 0, 1)( From 018d2fb50e8744cb6454d34f0d865007bbf20c3d Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Tue, 6 Nov 2018 21:30:49 +0100 Subject: [PATCH 0856/2665] JUnit: Remove unused stuff from RichLogger --- .../scala/com/novocode/junit/RichLogger.scala | 26 +++---------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/junit-runtime/src/main/scala/com/novocode/junit/RichLogger.scala b/junit-runtime/src/main/scala/com/novocode/junit/RichLogger.scala index b6cec79069..ed123b4303 100644 --- a/junit-runtime/src/main/scala/com/novocode/junit/RichLogger.scala +++ b/junit-runtime/src/main/scala/com/novocode/junit/RichLogger.scala @@ -14,28 +14,9 @@ package com.novocode.junit import sbt.testing._ -import scala.collection.mutable - import Ansi._ -final class RichLogger private (loggers: Array[Logger], settings: RunSettings) { - - private[this] var currentTestClassName: List[String] = Nil - - def this(loggers: Array[Logger], settings: RunSettings, - testClassName: String) = { - this(loggers, settings) - currentTestClassName ::= testClassName - } - - def pushCurrentTestClassName(s: String): Unit = - currentTestClassName ::= s - - def popCurrentTestClassName(): Unit = { - if (!currentTestClassName.isEmpty && !currentTestClassName.tail.isEmpty) - currentTestClassName = currentTestClassName.tail - } - +final class RichLogger(loggers: Array[Logger], settings: RunSettings, testClassName: String) { def debug(s: String): Unit = { for (l <- loggers) l.debug(filterAnsiIfNeeded(l, s)) @@ -73,9 +54,8 @@ final class RichLogger private (loggers: Array[Logger], settings: RunSettings) { p.getFileName.contains("Throwables.scala") } } - val testClassName = currentTestClassName.head val testFileName = { - if (settings.color) findTestFileName(trace, testClassName) + if (settings.color) findTestFileName(trace) else null } val i = trace.indexWhere { @@ -144,7 +124,7 @@ final class RichLogger private (loggers: Array[Logger], settings: RunSettings) { } } - private def findTestFileName(trace: Array[StackTraceElement], testClassName: String): String = { + private def findTestFileName(trace: Array[StackTraceElement]): String = { trace.collectFirst { case e if testClassName.equals(e.getClassName) => e.getFileName }.orNull From f968c870736cade86ccd6187332e7969caaa9a4f Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Tue, 6 Nov 2018 21:34:08 +0100 Subject: [PATCH 0857/2665] JUnit: Expose trace in RichLogger to simplify callsites --- .../scala/com/novocode/junit/RichLogger.scala | 8 +------- .../org/scalajs/junit/JUnitExecuteTest.scala | 15 +++++---------- .../main/scala/org/scalajs/junit/JUnitTask.scala | 3 ++- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/junit-runtime/src/main/scala/com/novocode/junit/RichLogger.scala b/junit-runtime/src/main/scala/com/novocode/junit/RichLogger.scala index ed123b4303..0ec5cfb3f9 100644 --- a/junit-runtime/src/main/scala/com/novocode/junit/RichLogger.scala +++ b/junit-runtime/src/main/scala/com/novocode/junit/RichLogger.scala @@ -27,12 +27,6 @@ final class RichLogger(loggers: Array[Logger], settings: RunSettings, testClassN l.error(filterAnsiIfNeeded(l, s)) } - def error(s: String, t: Throwable): Unit = { - error(s) - if (t != null && (settings.logAssert || !t.isInstanceOf[AssertionError])) - logStackTrace(t) - } - def info(s: String): Unit = { for (l <- loggers) l.info(filterAnsiIfNeeded(l, s)) @@ -47,7 +41,7 @@ final class RichLogger(loggers: Array[Logger], settings: RunSettings, testClassN if (l.ansiCodesSupported() && settings.color) s else filterAnsi(s) - private def logStackTrace(t: Throwable): Unit = { + def trace(t: Throwable): Unit = { val trace = t.getStackTrace.dropWhile { p => p.getFileName != null && { p.getFileName.contains("StackTrace.scala") || diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala index c93ff8a441..9c59cb4d73 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala @@ -127,11 +127,10 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, failedMsg ++= ex.getMessage failedMsg += ',' val msg = s"$failedMsg took $timeInSeconds sec" - val exOpt = { - if (!isAssertion || runSettings.logAssert) Some(ex) - else None + logFormattedError(decodedMethodName, msg) + if (!isAssertion || runSettings.logAssert) { + richLogger.trace(ex) } - logFormattedError(decodedMethodName, msg, exOpt) emitTestFailed() false } @@ -262,15 +261,11 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, formatLayout(prefix, packageName, c(className, NNAME1), fMethod, msg)) } - private[this] def logFormattedError(method: String, msg: String, - exOpt: Option[Throwable]): Unit = { + private[this] def logFormattedError(method: String, msg: String): Unit = { val fMethod = if (method != null) c(method, ERRMSG) else null val formattedMsg = formatLayout("Test ", packageName, c(className, NNAME1), fMethod, msg) - exOpt match { - case Some(ex) => richLogger.error(formattedMsg, ex) - case None => richLogger.error(formattedMsg) - } + richLogger.error(formattedMsg) } private[this] def formatLayout(prefix: String, packageName: String, diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTask.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTask.scala index b438dc8c4b..76b154484b 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTask.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTask.scala @@ -50,7 +50,8 @@ final class JUnitTask(val taskDef: TaskDef, runSettings: RunSettings) val startTime = System.nanoTime def errorWhileLoadingClass(t: Throwable): Unit = { - richLogger.error("Error while loading test class: " + fullClassName, t) + richLogger.error("Error while loading test class: " + fullClassName) + richLogger.trace(t) val selector = new TestSelector(fullClassName) val optThrowable = new OptionalThrowable(t) val ev = new JUnitEvent(taskDef, Status.Failure, selector, optThrowable) From 958d5b9a854d6b79d0069dab93491706ec9a3f84 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Tue, 6 Nov 2018 22:10:02 +0100 Subject: [PATCH 0858/2665] JUnit: Simplify logging and color management --- .../main/scala/com/novocode/junit/Ansi.scala | 17 +-- .../scala/com/novocode/junit/RichLogger.scala | 8 +- .../org/scalajs/junit/JUnitExecuteTest.scala | 102 +++++++----------- .../scala/org/scalajs/junit/JUnitTask.scala | 12 +-- 4 files changed, 54 insertions(+), 85 deletions(-) diff --git a/junit-runtime/src/main/scala/com/novocode/junit/Ansi.scala b/junit-runtime/src/main/scala/com/novocode/junit/Ansi.scala index c64973659f..e1cb0a8477 100644 --- a/junit-runtime/src/main/scala/com/novocode/junit/Ansi.scala +++ b/junit-runtime/src/main/scala/com/novocode/junit/Ansi.scala @@ -42,16 +42,9 @@ object Ansi { } } - final val INFO = "\u001B[34m" // BLUE - final val ERRCOUNT = "\u001B[31m" // RED - final val IGNCOUNT = "\u001B[33m" // YELLOW - final val ERRMSG = "\u001B[31m" // RED - final val NNAME1 = "\u001B[33m" // YELLOW - final val NNAME2 = "\u001B[36m" // CYAN - final val NNAME3 = "\u001B[33m" // YELLOW - final val ENAME1 = "\u001B[33m" // YELLOW - final val ENAME2 = "\u001B[31m" // RED - final val ENAME3 = "\u001B[33m" // YELLOW - final val TESTFILE1 = "\u001B[35m" // MAGENTA - final val TESTFILE2 = "\u001B[33m" // YELLOW + final val RED = "\u001B[31m" + final val YELLOW = "\u001B[33m" + final val BLUE = "\u001B[34m" + final val MAGENTA = "\u001B[35m" + final val CYAN = "\u001B[36m" } diff --git a/junit-runtime/src/main/scala/com/novocode/junit/RichLogger.scala b/junit-runtime/src/main/scala/com/novocode/junit/RichLogger.scala index 0ec5cfb3f9..9255f2a526 100644 --- a/junit-runtime/src/main/scala/com/novocode/junit/RichLogger.scala +++ b/junit-runtime/src/main/scala/com/novocode/junit/RichLogger.scala @@ -135,14 +135,14 @@ final class RichLogger(loggers: Array[Logger], settings: RunSettings, testClassN r += '(' if (e.isNativeMethod) { - r += c("Native Method", if (highlight) TESTFILE2 else null) + r += c("Native Method", if (highlight) YELLOW else null) } else if (e.getFileName == null) { - r += c("Unknown Source", if (highlight) TESTFILE2 else null) + r += c("Unknown Source", if (highlight) YELLOW else null) } else { - r += c(e.getFileName, if (highlight) TESTFILE1 else null) + r += c(e.getFileName, if (highlight) MAGENTA else null) if (e.getLineNumber >= 0) { r += ':' - r += c(String.valueOf(e.getLineNumber), if (highlight) TESTFILE2 else null) + r += c(String.valueOf(e.getLineNumber), if (highlight) YELLOW else null) } } r += ')' diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala index 9c59cb4d73..11bbdcf1b4 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala @@ -28,9 +28,6 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, private val taskDef = task.taskDef - lazy val packageName = fullyQualifiedName.split('.').init.mkString(".") - lazy val className = fullyQualifiedName.split('.').last - def fullyQualifiedName: String = taskDef.fullyQualifiedName() def executeTests(): Unit = { @@ -42,12 +39,8 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, true } - def logTestIgnored(name: String): Unit = { - logFormattedInfo(name, "ignored") - } - if (assumptionViolated) { - logTestIgnored(null) + richLogger.info(s"Test $formattedTestClass ignored") ignoreTestClass() } else { def runWithOrWithoutQuietMode[T](block: => T): T = { @@ -63,7 +56,7 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, runWithOrWithoutQuietMode { for (method <- bootstrapper.tests) { if (method.ignored) { - logTestIgnored(method.name) + logTestInfo(_.info, method.name, "ignored") ignoreTest(method.name) } else { executeTestMethod(bootstrapper, method) @@ -81,9 +74,9 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, val decodedMethodName = runSettings.decodeName(methodName) if (runSettings.verbose) - logFormattedInfo(decodedMethodName, "started") + logTestInfo(_.info, decodedMethodName, "started") else - logFormattedDebug(decodedMethodName, "started") + logTestInfo(_.debug, decodedMethodName, "started") val t0 = System.nanoTime def getTimeInSeconds(): Double = (System.nanoTime - t0).toDouble / 1000000000 @@ -107,28 +100,13 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, } catch { case ex: Throwable => val timeInSeconds = getTimeInSeconds() - if (ex.isInstanceOf[AssumptionViolatedException] || - ex.isInstanceOf[internal.AssumptionViolatedException]) { - logAssertionWarning(decodedMethodName, ex, timeInSeconds) + if (isAssumptionViolation(ex)) { + logThrowable(_.warn, "Test assumption in test ", decodedMethodName, ex, timeInSeconds) testSkipped() false } else { - val isAssertion = ex.isInstanceOf[AssertionError] - val failedMsg = new StringBuilder - failedMsg ++= "failed: " - if (!runSettings.notLogExceptionClass && - (!isAssertion || runSettings.logAssert)) { - val classParts = ex.getClass.getName.split('.') - failedMsg ++= classParts.init.mkString(".") - failedMsg += '.' - failedMsg ++= c(classParts.last, ENAME2) - failedMsg ++= ": " - } - failedMsg ++= ex.getMessage - failedMsg += ',' - val msg = s"$failedMsg took $timeInSeconds sec" - logFormattedError(decodedMethodName, msg) - if (!isAssertion || runSettings.logAssert) { + logThrowable(_.error, "Test ", decodedMethodName, ex, timeInSeconds) + if (!ex.isInstanceOf[AssertionError] || runSettings.logAssert) { richLogger.trace(ex) } emitTestFailed() @@ -187,7 +165,7 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, beforeAndTestSucceeded && afterSucceeded } - logFormattedDebug(decodedMethodName, + logTestInfo(_.debug, decodedMethodName, s"finished, took ${getTimeInSeconds()} sec") // Scala.js-specific: timeouts are warnings only, after the fact @@ -232,45 +210,43 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, eventHandler.handle(new JUnitEvent(taskDef, Status.Success, selector)) } - private[this] def logAssertionWarning(methodName: String, ex: Throwable, - timeInSeconds: Double): Unit = { - val exName = - if (runSettings.notLogExceptionClass) "" - else "org.junit.internal." + c("AssumptionViolatedException", ERRMSG) + ": " + private def logTestInfo(level: RichLogger => (String => Unit), method: String, msg: String): Unit = + level(richLogger)(s"Test ${formatMethod(method, CYAN)} $msg") - val msg = s"failed: $exName${ex.getMessage}, took $timeInSeconds sec" - logFormattedWarn("Test assumption in test ", methodName, msg) - } + private def logThrowable(level: RichLogger => (String => Unit), prefix: String, + method: String, ex: Throwable, timeInSeconds: Double): Unit = { + val logException = { + !runSettings.notLogExceptionClass && + (runSettings.logAssert || !ex.isInstanceOf[AssertionError]) + } - private[this] def logFormattedInfo(method: String, msg: String): Unit = { - val fMethod = if (method != null) c(method, NNAME2) else null - richLogger.info( - formatLayout("Test ", packageName, c(className, NNAME1), fMethod, msg)) - } + val fmtName = if (logException) { + val name = + if (isAssumptionViolation(ex)) classOf[internal.AssumptionViolatedException].getName + else ex.getClass.getName - private[this] def logFormattedDebug(method: String, msg: String): Unit = { - val fMethod = if (method != null) c(method, NNAME2) else null - richLogger.debug( - formatLayout("Test ", packageName, c(className, NNAME1), fMethod, msg)) - } + formatClass(name, RED) + ": " + } else { + "" + } - private[this] def logFormattedWarn(prefix: String, method: String, - msg: String): Unit = { - val fMethod = if (method != null) c(method, ERRMSG) else null - richLogger.warn( - formatLayout(prefix, packageName, c(className, NNAME1), fMethod, msg)) + val m = formatMethod(method, RED) + val msg = s"$prefix$m failed: $fmtName${ex.getMessage}, took $timeInSeconds sec" + level(richLogger)(msg) } - private[this] def logFormattedError(method: String, msg: String): Unit = { - val fMethod = if (method != null) c(method, ERRMSG) else null - val formattedMsg = formatLayout("Test ", packageName, c(className, NNAME1), - fMethod, msg) - richLogger.error(formattedMsg) + private def formatMethod(method: String, color: String): String = + s"$formattedTestClass.${c(method, color)}" + + private lazy val formattedTestClass = formatClass(taskDef.fullyQualifiedName, YELLOW) + + private def formatClass(fullName: String, color: String): String = { + val (prefix, name) = fullName.splitAt(fullName.lastIndexOf(".") + 1) + prefix + c(name, color) } - private[this] def formatLayout(prefix: String, packageName: String, - className: String, method: String, msg: String): String = { - if (method != null) s"$prefix$packageName.$className.$method $msg" - else s"$prefix$packageName.$className $msg" + private def isAssumptionViolation(ex: Throwable): Boolean = { + ex.isInstanceOf[AssumptionViolatedException] || + ex.isInstanceOf[internal.AssumptionViolatedException] } } diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTask.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTask.scala index 76b154484b..a0df2b7d03 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTask.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitTask.scala @@ -43,7 +43,7 @@ final class JUnitTask(val taskDef: TaskDef, runSettings: RunSettings) richLogger.debug(msg) } - infoOrDebug(c("Test run started", INFO)) + infoOrDebug(c("Test run started", BLUE)) val bootstrapperName = fullClassName + "$scalajs$junit$bootstrapper" @@ -79,11 +79,11 @@ final class JUnitTask(val taskDef: TaskDef, runSettings: RunSettings) val time = System.nanoTime - startTime val msg = { - c("Test run finished: ", INFO) + - c(s"$failed failed", if (failed == 0) INFO else ERRCOUNT) + - c(s", ", INFO) + - c(s"$ignored ignored", if (ignored == 0) INFO else IGNCOUNT) + - c(s", $total total, ${time.toDouble / 1000000000}s", INFO) + c("Test run finished: ", BLUE) + + c(s"$failed failed", if (failed == 0) BLUE else RED) + + c(s", ", BLUE) + + c(s"$ignored ignored", if (ignored == 0) BLUE else YELLOW) + + c(s", $total total, ${time.toDouble / 1000000000}s", BLUE) } infoOrDebug(msg) From 27b6533375e80f96cb01ac14212947fdb830d2b6 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 9 Nov 2018 18:23:27 +0100 Subject: [PATCH 0859/2665] JUnit: Simplify event emission --- .../org/scalajs/junit/JUnitExecuteTest.scala | 54 +++++++------------ 1 file changed, 18 insertions(+), 36 deletions(-) diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala index 11bbdcf1b4..8149cf9443 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala @@ -41,7 +41,8 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, if (assumptionViolated) { richLogger.info(s"Test $formattedTestClass ignored") - ignoreTestClass() + task.ignored += 1 + emitClassEvent(Status.Skipped) } else { def runWithOrWithoutQuietMode[T](block: => T): T = { if (runSettings.quiet) { @@ -57,7 +58,8 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, for (method <- bootstrapper.tests) { if (method.ignored) { logTestInfo(_.info, method.name, "ignored") - ignoreTest(method.name) + task.ignored += 1 + emitMethodEvent(method.name, Status.Skipped) } else { executeTestMethod(bootstrapper, method) } @@ -83,16 +85,6 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, var eventAlreadyEmitted: Boolean = false - def emitTestFailed(): Unit = { - if (eventAlreadyEmitted) { - // Only add to the failed test count, don't emit an event - task.failed += 1 - } else { - testFailed(methodName) - eventAlreadyEmitted = true - } - } - def execute(body: => Unit): Boolean = { try { body @@ -102,14 +94,21 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, val timeInSeconds = getTimeInSeconds() if (isAssumptionViolation(ex)) { logThrowable(_.warn, "Test assumption in test ", decodedMethodName, ex, timeInSeconds) - testSkipped() + emitMethodEvent(methodName, Status.Skipped) false } else { logThrowable(_.error, "Test ", decodedMethodName, ex, timeInSeconds) if (!ex.isInstanceOf[AssertionError] || runSettings.logAssert) { richLogger.trace(ex) } - emitTestFailed() + + task.failed += 1 + + if (!eventAlreadyEmitted) { + emitMethodEvent(methodName, Status.Failure) + eventAlreadyEmitted = true + } + false } } @@ -177,37 +176,20 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, } if (success) - testPassed(methodName) + emitMethodEvent(methodName, Status.Success) task.total += 1 } - private def ignoreTest(methodName: String) = { - task.ignored += 1 - val selector = new NestedTestSelector(fullyQualifiedName, methodName) - eventHandler.handle(new JUnitEvent(taskDef, Status.Skipped, selector)) - } - - private def ignoreTestClass() = { - task.ignored += 1 - val selector = new TestSelector(fullyQualifiedName) - eventHandler.handle(new JUnitEvent(taskDef, Status.Skipped, selector)) - } - private def testSkipped(): Unit = { + private def emitClassEvent(status: Status): Unit = { val selector = new TestSelector(fullyQualifiedName) - eventHandler.handle(new JUnitEvent(taskDef, Status.Skipped, selector)) - } - - private def testFailed(methodName: String): Unit = { - task.failed += 1 - val selector = new NestedTestSelector(fullyQualifiedName, methodName) - eventHandler.handle(new JUnitEvent(taskDef, Status.Failure, selector)) + eventHandler.handle(new JUnitEvent(taskDef, status, selector)) } - private def testPassed(methodName: String): Unit = { + private def emitMethodEvent(methodName: String, status: Status): Unit = { val selector = new NestedTestSelector(fullyQualifiedName, methodName) - eventHandler.handle(new JUnitEvent(taskDef, Status.Success, selector)) + eventHandler.handle(new JUnitEvent(taskDef, status, selector)) } private def logTestInfo(level: RichLogger => (String => Unit), method: String, msg: String): Unit = From 99bac9777aa264bf6f986cf3e8edcc2c0b6ff25b Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 9 Nov 2018 18:24:41 +0100 Subject: [PATCH 0860/2665] JUnit: Simplify method name decoding --- .../org/scalajs/junit/JUnitExecuteTest.scala | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala index 8149cf9443..19b5e78855 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala @@ -73,12 +73,11 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, private[this] def executeTestMethod(bootstrapper: Bootstrapper, test: TestMetadata) = { val methodName = test.name - val decodedMethodName = runSettings.decodeName(methodName) if (runSettings.verbose) - logTestInfo(_.info, decodedMethodName, "started") + logTestInfo(_.info, methodName, "started") else - logTestInfo(_.debug, decodedMethodName, "started") + logTestInfo(_.debug, methodName, "started") val t0 = System.nanoTime def getTimeInSeconds(): Double = (System.nanoTime - t0).toDouble / 1000000000 @@ -93,11 +92,11 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, case ex: Throwable => val timeInSeconds = getTimeInSeconds() if (isAssumptionViolation(ex)) { - logThrowable(_.warn, "Test assumption in test ", decodedMethodName, ex, timeInSeconds) + logThrowable(_.warn, "Test assumption in test ", methodName, ex, timeInSeconds) emitMethodEvent(methodName, Status.Skipped) false } else { - logThrowable(_.error, "Test ", decodedMethodName, ex, timeInSeconds) + logThrowable(_.error, "Test ", methodName, ex, timeInSeconds) if (!ex.isInstanceOf[AssertionError] || runSettings.logAssert) { richLogger.trace(ex) } @@ -164,7 +163,7 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, beforeAndTestSucceeded && afterSucceeded } - logTestInfo(_.debug, decodedMethodName, + logTestInfo(_.debug, methodName, s"finished, took ${getTimeInSeconds()} sec") // Scala.js-specific: timeouts are warnings only, after the fact @@ -217,8 +216,10 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, level(richLogger)(msg) } - private def formatMethod(method: String, color: String): String = - s"$formattedTestClass.${c(method, color)}" + private def formatMethod(method: String, color: String): String = { + val fmtMethod = c(runSettings.decodeName(method), color) + s"$formattedTestClass.$fmtMethod" + } private lazy val formattedTestClass = formatClass(taskDef.fullyQualifiedName, YELLOW) From 6295f7a8b098532ced4887d28a69b31ed75c9086 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 9 Nov 2018 18:25:54 +0100 Subject: [PATCH 0861/2665] JUnit: Remove unnecessary helper fields / methods --- .../org/scalajs/junit/JUnitExecuteTest.scala | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala index 19b5e78855..15b072caba 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala @@ -26,10 +26,6 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, bootstrapper: Bootstrapper, richLogger: RichLogger, eventHandler: EventHandler) { - private val taskDef = task.taskDef - - def fullyQualifiedName: String = taskDef.fullyQualifiedName() - def executeTests(): Unit = { val assumptionViolated = try { bootstrapper.beforeClass() @@ -182,13 +178,13 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, private def emitClassEvent(status: Status): Unit = { - val selector = new TestSelector(fullyQualifiedName) - eventHandler.handle(new JUnitEvent(taskDef, status, selector)) + val selector = new TestSelector(task.taskDef.fullyQualifiedName) + eventHandler.handle(new JUnitEvent(task.taskDef, status, selector)) } private def emitMethodEvent(methodName: String, status: Status): Unit = { - val selector = new NestedTestSelector(fullyQualifiedName, methodName) - eventHandler.handle(new JUnitEvent(taskDef, status, selector)) + val selector = new NestedTestSelector(task.taskDef.fullyQualifiedName, methodName) + eventHandler.handle(new JUnitEvent(task.taskDef, status, selector)) } private def logTestInfo(level: RichLogger => (String => Unit), method: String, msg: String): Unit = @@ -221,7 +217,8 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, s"$formattedTestClass.$fmtMethod" } - private lazy val formattedTestClass = formatClass(taskDef.fullyQualifiedName, YELLOW) + private lazy val formattedTestClass = + formatClass(task.taskDef.fullyQualifiedName, YELLOW) private def formatClass(fullName: String, color: String): String = { val (prefix, name) = fullName.splitAt(fullName.lastIndexOf(".") + 1) From ab7cb0b0bd381ed0cdc7f0c7513811f1f41e93b8 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Tue, 6 Nov 2018 19:51:27 +0100 Subject: [PATCH 0862/2665] JUnit: Fix double throw corner cases Some of the corner cases w.r.t. double throws were wrong. We fix them and add tests for these. --- .../org/scalajs/junit/JUnitExecuteTest.scala | 90 +++++++------------ .../org/scalajs/junit/AssumeAfterAssume.scala | 36 ++++++++ .../scalajs/junit/AssumeAfterException.scala | 36 ++++++++ .../org/scalajs/junit/AssumeInAfter.scala | 30 +++++++ .../scalajs/junit/ExceptionAfterAssume.scala | 37 ++++++++ 5 files changed, 173 insertions(+), 56 deletions(-) create mode 100644 junit-test/shared/src/test/scala/org/scalajs/junit/AssumeAfterAssume.scala create mode 100644 junit-test/shared/src/test/scala/org/scalajs/junit/AssumeAfterException.scala create mode 100644 junit-test/shared/src/test/scala/org/scalajs/junit/AssumeInAfter.scala create mode 100644 junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionAfterAssume.scala diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala index 15b072caba..12d46e4227 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala @@ -78,37 +78,6 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, val t0 = System.nanoTime def getTimeInSeconds(): Double = (System.nanoTime - t0).toDouble / 1000000000 - var eventAlreadyEmitted: Boolean = false - - def execute(body: => Unit): Boolean = { - try { - body - true - } catch { - case ex: Throwable => - val timeInSeconds = getTimeInSeconds() - if (isAssumptionViolation(ex)) { - logThrowable(_.warn, "Test assumption in test ", methodName, ex, timeInSeconds) - emitMethodEvent(methodName, Status.Skipped) - false - } else { - logThrowable(_.error, "Test ", methodName, ex, timeInSeconds) - if (!ex.isInstanceOf[AssertionError] || runSettings.logAssert) { - richLogger.trace(ex) - } - - task.failed += 1 - - if (!eventAlreadyEmitted) { - emitMethodEvent(methodName, Status.Failure) - eventAlreadyEmitted = true - } - - false - } - } - } - def handleExpected(expectedException: Class[_ <: Throwable])(body: => Unit) = { val wantException = expectedException != classOf[org.junit.Test.None] val succeeded = try { @@ -128,49 +97,58 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, throw new AssertionError("Expected exception: " + expectedException.getName) } - var testClassInstance: AnyRef = null - - val instantiationSucceeded = execute { - testClassInstance = bootstrapper.newInstance() + var exceptions: List[Throwable] = Nil + try { + val instance = bootstrapper.newInstance() + try { + bootstrapper.before(instance) + handleExpected(test.annotation.expected) { + bootstrapper.invokeTest(instance, test.name) + } + } catch { + case t: Throwable => exceptions ::= t + } finally { + bootstrapper.after(instance) + } + } catch { + case t: Throwable => exceptions ::= t } - val success = if (!instantiationSucceeded) { - false - } else { - val beforeSucceeded = execute { - bootstrapper.before(testClassInstance) - } + val timeInSeconds = getTimeInSeconds() - val beforeAndTestSucceeded = if (!beforeSucceeded) { - false - } else { - execute { - handleExpected(test.annotation.expected) { - bootstrapper.invokeTest(testClassInstance, test.name) + exceptions.reverse match { + case Nil => + + case e :: Nil if isAssumptionViolation(e) => + logThrowable(_.warn, "Test assumption in test ", methodName, e, timeInSeconds) + emitMethodEvent(methodName, Status.Skipped) + + case e :: es => + def emit(t: Throwable) = { + logThrowable(_.error, "Test ", methodName, t, timeInSeconds) + + if (!t.isInstanceOf[AssertionError] || runSettings.logAssert) { + richLogger.trace(t) } + task.failed += 1 } - } - // Whether before and/or test succeeded or not, run the after methods - val afterSucceeded = execute { - bootstrapper.after(testClassInstance) - } - - beforeAndTestSucceeded && afterSucceeded + emit(e) + emitMethodEvent(methodName, Status.Failure) + es.foreach(emit) } logTestInfo(_.debug, methodName, s"finished, took ${getTimeInSeconds()} sec") // Scala.js-specific: timeouts are warnings only, after the fact - val timeInSeconds = getTimeInSeconds() val timeout = test.annotation.timeout if (timeout != 0 && timeout <= timeInSeconds) { richLogger.warn("Timeout: took " + timeInSeconds + " sec, expected " + (timeout.toDouble / 1000) + " sec") } - if (success) + if (exceptions.isEmpty) emitMethodEvent(methodName, Status.Success) task.total += 1 diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/AssumeAfterAssume.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/AssumeAfterAssume.scala new file mode 100644 index 0000000000..6f52fffa1c --- /dev/null +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/AssumeAfterAssume.scala @@ -0,0 +1,36 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package org.scalajs.junit + +import org.junit.Assume._ +import org.junit._ + +import org.scalajs.junit.utils._ + +class AssumeAfterAssume { + @After def after(): Unit = + assumeTrue("This assume should not pass", false) + + @Test def assumeFail(): Unit = + assumeTrue("This assume should not pass", false) +} + +class AssumeAfterAssumeAssertions extends JUnitTest { + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = { + builder.exceptionAndAnotherExceptionInAfter("assumeFail", + "This assume should not pass", + classOf[org.junit.internal.AssumptionViolatedException], + "This assume should not pass", + classOf[org.junit.internal.AssumptionViolatedException]) + } +} diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/AssumeAfterException.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/AssumeAfterException.scala new file mode 100644 index 0000000000..57bc895bdb --- /dev/null +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/AssumeAfterException.scala @@ -0,0 +1,36 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package org.scalajs.junit + +import org.junit.Assume._ +import org.junit._ + +import org.scalajs.junit.utils._ + +class AssumeAfterException { + @After def after(): Unit = + assumeTrue("This assume should not pass", false) + + @Test def test(): Unit = + throw new IllegalArgumentException("test throws") +} + +class AssumeAfterExceptionAssertions extends JUnitTest { + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = { + builder.exceptionAndAnotherExceptionInAfter("test", + "test throws", + classOf[IllegalArgumentException], + "This assume should not pass", + classOf[org.junit.internal.AssumptionViolatedException]) + } +} diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/AssumeInAfter.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/AssumeInAfter.scala new file mode 100644 index 0000000000..29064aeb96 --- /dev/null +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/AssumeInAfter.scala @@ -0,0 +1,30 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package org.scalajs.junit + +import org.junit.Assume._ +import org.junit._ + +import org.scalajs.junit.utils._ + +class AssumeInAfter { + @After def after(): Unit = + assumeTrue("This assume should not pass", false) + + @Test def test(): Unit = {} +} + +class AssumeInAfterAssertions extends JUnitTest { + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = + builder.assumptionViolated("test") +} diff --git a/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionAfterAssume.scala b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionAfterAssume.scala new file mode 100644 index 0000000000..61884bc1df --- /dev/null +++ b/junit-test/shared/src/test/scala/org/scalajs/junit/ExceptionAfterAssume.scala @@ -0,0 +1,37 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package org.scalajs.junit + +import org.junit.Assume._ +import org.junit._ + +import org.scalajs.junit.utils._ + +class ExceptionAfterAssume { + @After def after(): Unit = + throw new IllegalArgumentException("after() must be called") + + @Test def assumeFail(): Unit = { + assumeTrue("This assume should not pass", false) + } +} + +class ExceptionAfterAssumeAssertions extends JUnitTest { + protected def expectedOutput(builder: OutputBuilder): OutputBuilder = { + builder.exceptionAndAnotherExceptionInAfter("assumeFail", + "This assume should not pass", + classOf[org.junit.internal.AssumptionViolatedException], + "after() must be called", + classOf[IllegalArgumentException]) + } +} From 63cadde9a08ca83f0de46d8be77ea5aca6d05af7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 28 Aug 2018 13:57:18 +0200 Subject: [PATCH 0863/2665] Remove the internal annotation `@AnonymousJSClass`. We can get by without it by inspecting `sym.isAnonymousClass` and `isJSType(sym)`. --- .../org/scalajs/nscplugin/GenJSCode.scala | 22 +++++++++---------- .../org/scalajs/nscplugin/GenJSExports.scala | 2 +- .../org/scalajs/nscplugin/JSDefinitions.scala | 1 - .../org/scalajs/nscplugin/PrepJSInterop.scala | 4 ---- .../test/InternalAnnotationsTest.scala | 5 ----- .../internal/AnonymousJSClass.scala | 22 ------------------- 6 files changed, 11 insertions(+), 45 deletions(-) delete mode 100644 library/src/main/scala/scala/scalajs/js/annotation/internal/AnonymousJSClass.scala diff --git a/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala index ee459fd3c0..7802b8a206 100644 --- a/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala @@ -272,10 +272,12 @@ abstract class GenJSCode extends plugins.PluginComponent /* There are three types of anonymous classes we want to generate * only once we need them so we can inline them at construction site: * - * - lambdas for js.FunctionN and js.ThisFunctionN (SAMs). (We may not - * generate actual Scala classes for these). - * - anonymous (non-lambda) JS classes. These classes may not have their - * own prototype. Therefore, their constructor *must* be inlined. + * - anonymous class that are JS types, which includes: + * - lambdas for js.FunctionN and js.ThisFunctionN (SAMs). (We may + * not generate actual Scala classes for these). + * - anonymous (non-lambda) JS classes. These classes may not have + * their own prototype. Therefore, their constructor *must* be + * inlined. * - lambdas for scala.FunctionN. This is only an optimization and may * fail. In the case of failure, we fall back to generating a * fully-fledged Scala class. @@ -285,8 +287,7 @@ abstract class GenJSCode extends plugins.PluginComponent */ val (lazyAnons, fullClassDefs0) = allClassDefs.partition { cd => val sym = cd.symbol - isRawJSFunctionDef(sym) || sym.isAnonymousFunction || - isAnonJSClass(sym) + (sym.isAnonymousClass && isJSType(sym)) || sym.isAnonymousFunction } lazilyGeneratedAnonClasses ++= lazyAnons.map(cd => cd.symbol -> cd) @@ -641,7 +642,7 @@ abstract class GenJSCode extends plugins.PluginComponent */ def genAnonJSClassNew(sym: Symbol, jsSuperClassValue: js.Tree, args: List[js.TreeOrJSSpread], pos: Position): js.Tree = { - assert(isAnonJSClass(sym), + assert(sym.isAnonymousClass && !isRawJSFunctionDef(sym), "Generating AnonJSClassNew of non anonymous JS class") // Find the ClassDef for this anonymous class @@ -4637,7 +4638,7 @@ abstract class GenJSCode extends plugins.PluginComponent js.JSObjectConstr(Nil) else if (cls == JSArrayClass && args0.isEmpty) js.JSArrayConstr(Nil) - else if (isAnonJSClass(cls)) + else if (cls.isAnonymousClass) genAnonJSClassNew(cls, jsClassValue.get, args, fun.pos) else if (!nestedJSClass) js.JSNew(genPrimitiveJSClass(cls), args) @@ -4744,7 +4745,7 @@ abstract class GenJSCode extends plugins.PluginComponent */ val isAnonJSClassConstructor = - sym.isClassConstructor && isAnonJSClass(sym.owner) + sym.isClassConstructor && sym.owner.isAnonymousClass val wereRepeated = enteringPhase(currentRun.uncurryPhase) { for { @@ -5748,9 +5749,6 @@ abstract class GenJSCode extends plugins.PluginComponent def isNonNativeJSClass(sym: Symbol): Boolean = !sym.isTrait && isJSType(sym) && !sym.hasAnnotation(JSNativeAnnotation) - def isAnonJSClass(sym: Symbol): Boolean = - sym.hasAnnotation(AnonymousJSClassAnnotation) - def isNestedJSClass(sym: Symbol): Boolean = sym.isLifted && !sym.originalOwner.isModuleClass && isJSType(sym) diff --git a/compiler/src/main/scala/org/scalajs/nscplugin/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/nscplugin/GenJSExports.scala index e56977dd23..242a4c0012 100644 --- a/compiler/src/main/scala/org/scalajs/nscplugin/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/GenJSExports.scala @@ -848,7 +848,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode => private case class ExportedSymbol(sym: Symbol) extends Exported { private val isAnonJSClassConstructor = - sym.isClassConstructor && isAnonJSClass(sym.owner) + sym.isClassConstructor && sym.owner.isAnonymousClass && isJSType(sym.owner) val isLiftedJSConstructor = sym.isClassConstructor && isNestedJSClass(sym.owner) diff --git a/compiler/src/main/scala/org/scalajs/nscplugin/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/nscplugin/JSDefinitions.scala index 6dbf5f2479..c69e1d4557 100644 --- a/compiler/src/main/scala/org/scalajs/nscplugin/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/JSDefinitions.scala @@ -77,7 +77,6 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val ExposedJSMemberAnnot = getRequiredClass("scala.scalajs.js.annotation.internal.ExposedJSMember") lazy val JSOptionalAnnotation = getRequiredClass("scala.scalajs.js.annotation.internal.JSOptional") lazy val RawJSTypeAnnot = getRequiredClass("scala.scalajs.js.annotation.internal.RawJSType") - lazy val AnonymousJSClassAnnotation = getRequiredClass("scala.scalajs.js.annotation.internal.AnonymousJSClass") lazy val WasPublicBeforeTyperClass = getRequiredClass("scala.scalajs.js.annotation.internal.WasPublicBeforeTyper") lazy val JSAnyTpe = JSAnyClass.toTypeConstructor diff --git a/compiler/src/main/scala/org/scalajs/nscplugin/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/nscplugin/PrepJSInterop.scala index 0328e85e39..d72f762c43 100644 --- a/compiler/src/main/scala/org/scalajs/nscplugin/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/PrepJSInterop.scala @@ -495,9 +495,6 @@ abstract class PrepJSInterop extends plugins.PluginComponent val isJSAnonFun = isJSLambda(sym) sym.addAnnotation(RawJSTypeAnnot) - if (sym.isAnonymousClass && !isJSAnonFun) { - sym.addAnnotation(AnonymousJSClassAnnotation) - } /* Anonymous functions are considered native, since they are handled * specially in the backend. @@ -1407,7 +1404,6 @@ abstract class PrepJSInterop extends plugins.PluginComponent def isCompilerAnnotation(annotation: AnnotationInfo): Boolean = { annotation.symbol == ExposedJSMemberAnnot || annotation.symbol == RawJSTypeAnnot || - annotation.symbol == AnonymousJSClassAnnotation || annotation.symbol == JSOptionalAnnotation } diff --git a/compiler/src/test/scala/org/scalajs/nscplugin/test/InternalAnnotationsTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/InternalAnnotationsTest.scala index 3cf37c872b..f7fa3f7d54 100644 --- a/compiler/src/test/scala/org/scalajs/nscplugin/test/InternalAnnotationsTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/InternalAnnotationsTest.scala @@ -33,11 +33,6 @@ class InternalAnnotationsTest extends DirectTest with TestHelpers { test("RawJSType") } - @Test - def anonymousJSClass: Unit = { - test("AnonymousJSClass") - } - @Test def jsOptional: Unit = { test("JSOptional") diff --git a/library/src/main/scala/scala/scalajs/js/annotation/internal/AnonymousJSClass.scala b/library/src/main/scala/scala/scalajs/js/annotation/internal/AnonymousJSClass.scala deleted file mode 100644 index d87e3ffdcd..0000000000 --- a/library/src/main/scala/scala/scalajs/js/annotation/internal/AnonymousJSClass.scala +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Scala.js (https://www.scala-js.org/) - * - * Copyright EPFL. - * - * Licensed under Apache License 2.0 - * (https://www.apache.org/licenses/LICENSE-2.0). - * - * See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - */ - -package scala.scalajs.js.annotation.internal - -/** IMPLEMENTATION DETAIL: Marks anonymous non-native JS classes. - * - * This annotation is added automatically by the compiler to anonymous - * JS classes (that are not lambdas). - * - * Do not use this annotation yourself. - */ -class AnonymousJSClass extends scala.annotation.Annotation From da0d11c044d37188e78770af5807a5e2ae95a434 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 29 Aug 2018 14:14:07 +0200 Subject: [PATCH 0864/2665] Replace "Raw JS" by just "JS" everywhere. There is no difference between JS types and raw JS types. They are all JS types. The "raw" appellation is an accident of history. --- .../scalajs/nscplugin/ExplicitInnerJS.scala | 4 +- .../scalajs/nscplugin/ExplicitLocalJS.scala | 4 +- .../org/scalajs/nscplugin/GenJSCode.scala | 96 +++++++++---------- .../org/scalajs/nscplugin/JSDefinitions.scala | 2 +- .../org/scalajs/nscplugin/PrepJSInterop.scala | 26 ++--- .../nscplugin/test/DiverseErrorsTest.scala | 10 +- .../test/InternalAnnotationsTest.scala | 4 +- .../scalajs/nscplugin/test/JSExportTest.scala | 2 +- .../nscplugin/test/JSInteropTest.scala | 12 +-- .../nscplugin/test/JSOptionalTest.scala | 2 +- ir/src/main/scala/org/scalajs/ir/Types.scala | 10 +- .../src/main/scala/java/lang/Class.scala | 8 +- .../scalajs/js/annotation/JSExport.scala | 2 +- .../{RawJSType.scala => JSType.scala} | 10 +- .../main/scala/scala/scalajs/js/package.scala | 8 +- linker/scalajsenv.js | 8 +- .../linker/backend/emitter/ClassEmitter.scala | 10 +- .../backend/emitter/FunctionEmitter.scala | 8 +- .../linker/backend/emitter/JSGen.scala | 6 +- .../scalajs/linker/checker/IRChecker.scala | 7 +- .../compiler/InteroperabilityTest.scala | 22 ++--- .../testsuite/compiler/ReflectionTest.scala | 34 +++---- .../testsuite/compiler/RuntimeTypesTest.scala | 2 +- 23 files changed, 150 insertions(+), 147 deletions(-) rename library/src/main/scala/scala/scalajs/js/annotation/internal/{RawJSType.scala => JSType.scala} (69%) diff --git a/compiler/src/main/scala/org/scalajs/nscplugin/ExplicitInnerJS.scala b/compiler/src/main/scala/org/scalajs/nscplugin/ExplicitInnerJS.scala index 53d3b69209..5e7fb1f965 100644 --- a/compiler/src/main/scala/org/scalajs/nscplugin/ExplicitInnerJS.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/ExplicitInnerJS.scala @@ -93,7 +93,7 @@ abstract class ExplicitInnerJS /** Is the given clazz an inner JS class? */ private def isInnerJSClass(clazz: Symbol): Boolean = { - clazz.hasAnnotation(RawJSTypeAnnot) && + clazz.hasAnnotation(JSTypeAnnot) && !clazz.isPackageClass && !clazz.outerClass.isStaticOwner && !clazz.isLocalToBlock && !clazz.isModuleClass && !clazz.isTrait } @@ -108,7 +108,7 @@ abstract class ExplicitInnerJS if (innerJSClasses.isEmpty) { tp } else { - val clazzIsJSClass = clazz.hasAnnotation(RawJSTypeAnnot) + val clazzIsJSClass = clazz.hasAnnotation(JSTypeAnnot) val decls1 = decls.cloneScope for (innerJSClass <- innerJSClasses) { diff --git a/compiler/src/main/scala/org/scalajs/nscplugin/ExplicitLocalJS.scala b/compiler/src/main/scala/org/scalajs/nscplugin/ExplicitLocalJS.scala index 983c2e5163..7e344f706c 100644 --- a/compiler/src/main/scala/org/scalajs/nscplugin/ExplicitLocalJS.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/ExplicitLocalJS.scala @@ -164,7 +164,7 @@ abstract class ExplicitLocalJS /** Is the given clazz an inner JS class or object? */ private def isInnerJSClassOrObject(clazz: Symbol): Boolean = { - clazz.hasAnnotation(RawJSTypeAnnot) && + clazz.hasAnnotation(JSTypeAnnot) && !clazz.isPackageClass && !clazz.outerClass.isStaticOwner && !clazz.isLocalToBlock && !clazz.isTrait } @@ -175,7 +175,7 @@ abstract class ExplicitLocalJS clazz.isAnonymousClass && AllJSFunctionClasses.exists(clazz.isSubClass(_)) clazz.isLocalToBlock && - !clazz.isTrait && clazz.hasAnnotation(RawJSTypeAnnot) && + !clazz.isTrait && clazz.hasAnnotation(JSTypeAnnot) && !isJSLambda } diff --git a/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala index 7802b8a206..c3956c0312 100644 --- a/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala @@ -244,7 +244,7 @@ abstract class GenJSCode extends plugins.PluginComponent * Some classes are never actually emitted: * - Classes representing primitive types * - The scala.Array class - * - Implementation classes for raw JS traits + * - Implementation classes for JS traits * * Some classes representing anonymous functions are not actually emitted. * Instead, a temporary representation of their `apply` method is built @@ -253,7 +253,7 @@ abstract class GenJSCode extends plugins.PluginComponent * * Other ClassDefs are emitted according to their nature: * * Non-native JS class -> `genNonNativeJSClass()` - * * Other JS type (<: js.Any) -> `genRawJSClassData()` + * * Other JS type (<: js.Any) -> `genJSClassData()` * * Interface -> `genInterface()` * * Implementation class -> `genImplClass()` * * Normal class -> `genClass()` @@ -297,7 +297,7 @@ abstract class GenJSCode extends plugins.PluginComponent * must exist at the IR level, as `AbstractJSType`s. */ val fullClassDefs = if (isScala211WithXexperimental) { - lazyAnons.filter(cd => isRawJSFunctionDef(cd.symbol)) ::: fullClassDefs0 + lazyAnons.filter(cd => isJSFunctionDef(cd.symbol)) ::: fullClassDefs0 } else { fullClassDefs0 } @@ -311,7 +311,7 @@ abstract class GenJSCode extends plugins.PluginComponent val isPrimitive = isPrimitiveValueClass(sym) || (sym == ArrayClass) - if (!isPrimitive && !isRawJSImplClass(sym)) { + if (!isPrimitive && !isJSImplClass(sym)) { withScopedVars( currentClassSym := sym, unexpectedMutatedFields := mutable.Set.empty, @@ -320,10 +320,10 @@ abstract class GenJSCode extends plugins.PluginComponent try { val tree = if (isJSType(sym)) { if (!sym.isTraitOrInterface && isNonNativeJSClass(sym) && - !isRawJSFunctionDef(sym)) { + !isJSFunctionDef(sym)) { genNonNativeJSClass(cd) } else { - genRawJSClassData(cd) + genJSClassData(cd) } } else if (sym.isTraitOrInterface) { genInterface(cd) @@ -382,7 +382,7 @@ abstract class GenJSCode extends plugins.PluginComponent "genClass() must be called only for normal classes: "+sym) assert(sym.superClass != NoSymbol, sym) - if (hasDefaultCtorArgsAndRawJSModule(sym)) { + if (hasDefaultCtorArgsAndJSModule(sym)) { reporter.error(pos, "Implementation restriction: constructors of " + "Scala classes cannot have default parameters " + @@ -642,7 +642,7 @@ abstract class GenJSCode extends plugins.PluginComponent */ def genAnonJSClassNew(sym: Symbol, jsSuperClassValue: js.Tree, args: List[js.TreeOrJSSpread], pos: Position): js.Tree = { - assert(sym.isAnonymousClass && !isRawJSFunctionDef(sym), + assert(sym.isAnonymousClass && !isJSFunctionDef(sym), "Generating AnonJSClassNew of non anonymous JS class") // Find the ClassDef for this anonymous class @@ -807,18 +807,18 @@ abstract class GenJSCode extends plugins.PluginComponent invocation } - // Generate the class data of a raw JS class ------------------------------- + // Generate the class data of a JS class ----------------------------------- - /** Gen the IR ClassDef for a raw JS class or trait. + /** Gen the IR ClassDef for a JS class or trait. */ - def genRawJSClassData(cd: ClassDef): js.ClassDef = { + def genJSClassData(cd: ClassDef): js.ClassDef = { val sym = cd.symbol implicit val pos = sym.pos val classIdent = encodeClassFullNameIdent(sym) val kind = { if (sym.isTraitOrInterface) ClassKind.AbstractJSType - else if (isRawJSFunctionDef(sym)) ClassKind.AbstractJSType + else if (isJSFunctionDef(sym)) ClassKind.AbstractJSType else if (sym.isModuleClass) ClassKind.NativeJSModuleClass else ClassKind.NativeJSClass } @@ -1102,7 +1102,7 @@ abstract class GenJSCode extends plugins.PluginComponent constructorTrees: List[DefDef]): (Option[List[js.ParamDef]], js.MethodDef) = { implicit val pos = classSym.pos - if (hasDefaultCtorArgsAndRawJSModule(classSym)) { + if (hasDefaultCtorArgsAndJSModule(classSym)) { reporter.error(pos, "Implementation restriction: constructors of " + "non-native JS classes cannot have default parameters " + @@ -1846,7 +1846,7 @@ abstract class GenJSCode extends plugins.PluginComponent } if (!isNonNativeJSClass(currentClassSym) || - isRawJSFunctionDef(currentClassSym)) { + isJSFunctionDef(currentClassSym)) { val body = { if (currentClassSym.isImplClass) { val thisParam = jsParams.head @@ -2458,9 +2458,9 @@ abstract class GenJSCode extends plugins.PluginComponent val Apply(fun, args) = tree val sym = fun.symbol - def isRawJSDefaultParam: Boolean = { + def isJSDefaultParam: Boolean = { if (isCtorDefaultParam(sym)) { - isRawJSCtorDefaultParam(sym) + isJSCtorDefaultParam(sym) } else { sym.hasFlag(reflect.internal.Flags.DEFAULTPARAM) && isJSType(sym.owner) && { @@ -2489,7 +2489,7 @@ abstract class GenJSCode extends plugins.PluginComponent case TypeApply(_, _) => genApplyTypeApply(tree, isStat) - case _ if isRawJSDefaultParam => + case _ if isJSDefaultParam => js.Transient(UndefinedParam)(toIRType(sym.tpe.resultType)) case Select(Super(_, _), _) => @@ -2637,7 +2637,7 @@ abstract class GenJSCode extends plugins.PluginComponent * * new String(...) * * new of a hijacked boxed class * * new of an anonymous function class that was recorded as JS function - * * new of a raw JS class + * * new of a JS class * * new Array * * regular new */ @@ -2653,9 +2653,9 @@ abstract class GenJSCode extends plugins.PluginComponent if (isHijackedClass(clsSym)) { genNewHijackedClass(clsSym, ctor, args.map(genExpr)) - } else if (isRawJSFunctionDef(clsSym)) { + } else if (isJSFunctionDef(clsSym)) { val classDef = consumeLazilyGeneratedAnonClass(clsSym) - genRawJSFunction(classDef, args.map(genExpr)) + genJSFunction(classDef, args.map(genExpr)) } else if (clsSym.isAnonymousFunction) { val classDef = consumeLazilyGeneratedAnonClass(clsSym) tryGenAnonFunctionClass(classDef, args.map(genExpr)).getOrElse { @@ -2804,11 +2804,11 @@ abstract class GenJSCode extends plugins.PluginComponent /** Gen a "normal" apply (to a true method). * * But even these are further refined into: - * * Methods of java.lang.String, which are redirected to the - * RuntimeString trait implementation. - * * Calls to methods of raw JS types (Scala.js -> JS bridge) - * * Calls to methods in impl classes of traits. - * * Regular method call + * + * - Calls to methods of JS types. + * - Calls to methods in impl classes of traits. + * - Direct calls to constructors (from secondary constructor to another one). + * - Regular method calls. */ private def genNormalApply(tree: Apply, isStat: Boolean): js.Tree = { implicit val pos = tree.pos @@ -2844,7 +2844,7 @@ abstract class GenJSCode extends plugins.PluginComponent def genTraitImplApply(method: Symbol, arguments: List[js.Tree])( implicit pos: Position): js.Tree = { - if (method.isMixinConstructor && isRawJSImplClass(method.owner)) { + if (method.isMixinConstructor && isJSImplClass(method.owner)) { /* Do not emit a call to the $init$ method of JS traits. * This exception is necessary because @JSOptional fields cause the * creation of a $init$ method, which we must not call. @@ -2945,7 +2945,7 @@ abstract class GenJSCode extends plugins.PluginComponent } else if (isJSType(sym)) { if (sym.isTrait) { reporter.error(pos, - s"isInstanceOf[${sym.fullName}] not supported because it is a raw JS trait") + s"isInstanceOf[${sym.fullName}] not supported because it is a JS trait") js.BooleanLiteral(true) } else { js.Unbox(js.JSBinaryOp( @@ -2970,7 +2970,7 @@ abstract class GenJSCode extends plugins.PluginComponent if (sym == ObjectClass || isJSType(sym)) { /* asInstanceOf[Object] always succeeds, and - * asInstanceOf to a raw JS type is completely erased. + * asInstanceOf to a JS type is completely erased. */ value } else if (sym == NullClass) { @@ -3015,8 +3015,8 @@ abstract class GenJSCode extends plugins.PluginComponent */ def genNew(clazz: Symbol, ctor: Symbol, arguments: List[js.Tree])( implicit pos: Position): js.Tree = { - assert(!isRawJSFunctionDef(clazz), - s"Trying to instantiate a raw JS function def $clazz") + assert(!isJSFunctionDef(clazz), + s"Trying to instantiate a JS function def $clazz") val className = encodeClassFullName(clazz) val ctorIdent = encodeMethodSym(ctor) js.New(jstpe.ClassType(className), ctorIdent, arguments) @@ -3774,7 +3774,7 @@ abstract class GenJSCode extends plugins.PluginComponent * (scala.runtime.BoxesRunTime.equals). * This is the case when either side of the comparison might have a * run-time type subtype of java.lang.Number or java.lang.Character, - * **which includes when either is a raw JS type**. + * **which includes when either is a JS type**. * * When it is statically known that both sides are equal and subtypes of * Number or Character, not using the rich equality is possible (their @@ -4618,7 +4618,7 @@ abstract class GenJSCode extends plugins.PluginComponent (firstArg, args.tail) } - /** Gen JS code for a new of a raw JS class (subclass of js.Any) */ + /** Gen JS code for a new of a JS class (subclass of js.Any) */ private def genPrimitiveJSNew(tree: Apply): js.Tree = { acquireContextualJSClassValue { jsClassValue => implicit val pos = tree.pos @@ -4947,7 +4947,7 @@ abstract class GenJSCode extends plugins.PluginComponent } } - // Synthesizers for raw JS functions --------------------------------------- + // Synthesizers for JS functions ------------------------------------------- /** Try and generate JS code for an anonymous function class. * @@ -5028,7 +5028,7 @@ abstract class GenJSCode extends plugins.PluginComponent } } - /** Gen JS code for a raw JS function class. + /** Gen JS code for a JS function class. * * This is called when emitting a ClassDef that represents an anonymous * class extending `js.FunctionN`. These are generated by the SAM @@ -5058,21 +5058,21 @@ abstract class GenJSCode extends plugins.PluginComponent * outer.lambdaImpl(param1, ..., paramN, capture1, ..., captureM) * } */ - def genRawJSFunction(cd: ClassDef, captures: List[js.Tree]): js.Tree = { + def genJSFunction(cd: ClassDef, captures: List[js.Tree]): js.Tree = { val sym = cd.symbol - assert(isRawJSFunctionDef(sym), - s"genAndRecordRawJSFunctionClass called with non-JS function $cd") + assert(isJSFunctionDef(sym), + s"genAndRecordJSFunctionClass called with non-JS function $cd") nestedGenerateClass(sym) { val (function, _) = tryGenAnonFunctionClassGeneric(cd, captures)(msg => - abort(s"Could not generate raw function for JS function: $msg")) + abort(s"Could not generate function for JS function: $msg")) function } } /** Code common to tryGenAndRecordAnonFunctionClass and - * genAndRecordRawJSFunctionClass. + * genAndRecordJSFunctionClass. */ private def tryGenAnonFunctionClassGeneric(cd: ClassDef, initialCapturedArgs: List[js.Tree])( @@ -5733,17 +5733,17 @@ abstract class GenJSCode extends plugins.PluginComponent v != "2.13.0-M3" } - /** Tests whether the given type represents a raw JavaScript type, + /** Tests whether the given type represents a JavaScript type, * i.e., whether it extends scala.scalajs.js.Any. */ def isJSType(tpe: Type): Boolean = isJSType(tpe.typeSymbol) - /** Tests whether the given type symbol represents a raw JavaScript type, + /** Tests whether the given type symbol represents a JavaScript type, * i.e., whether it extends scala.scalajs.js.Any. */ def isJSType(sym: Symbol): Boolean = - sym.hasAnnotation(RawJSTypeAnnot) + sym.hasAnnotation(JSTypeAnnot) /** Tests whether the given class is a non-native JS class. */ def isNonNativeJSClass(sym: Symbol): Boolean = @@ -5756,8 +5756,8 @@ abstract class GenJSCode extends plugins.PluginComponent private def isJSNativeClass(sym: Symbol): Boolean = sym.hasAnnotation(JSNativeAnnotation) - /** Tests whether the given class is the impl class of a raw JS trait. */ - private def isRawJSImplClass(sym: Symbol): Boolean = + /** Tests whether the given class is the impl class of a JS trait. */ + private def isJSImplClass(sym: Symbol): Boolean = sym.isImplClass && isJSType(traitOfImplClass(sym)) private def traitOfImplClass(sym: Symbol): Symbol = @@ -5775,11 +5775,11 @@ abstract class GenJSCode extends plugins.PluginComponent } } - /** Test whether `sym` is the symbol of a raw JS function definition */ - private def isRawJSFunctionDef(sym: Symbol): Boolean = + /** Test whether `sym` is the symbol of a JS function definition */ + private def isJSFunctionDef(sym: Symbol): Boolean = sym.isAnonymousClass && AllJSFunctionClasses.exists(sym isSubClass _) - private def isRawJSCtorDefaultParam(sym: Symbol) = { + private def isJSCtorDefaultParam(sym: Symbol) = { isCtorDefaultParam(sym) && isJSType(patchedLinkedClassOfClass(sym.owner)) } @@ -5795,7 +5795,7 @@ abstract class GenJSCode extends plugins.PluginComponent nme.defaultGetterToMethod(sym.name) == nme.CONSTRUCTOR } - private def hasDefaultCtorArgsAndRawJSModule(classSym: Symbol): Boolean = { + private def hasDefaultCtorArgsAndJSModule(classSym: Symbol): Boolean = { /* Get the companion module class. * For inner classes the sym.owner.companionModule can be broken, * therefore companionModule is fetched at uncurryPhase. diff --git a/compiler/src/main/scala/org/scalajs/nscplugin/JSDefinitions.scala b/compiler/src/main/scala/org/scalajs/nscplugin/JSDefinitions.scala index c69e1d4557..04cb25fc37 100644 --- a/compiler/src/main/scala/org/scalajs/nscplugin/JSDefinitions.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/JSDefinitions.scala @@ -76,7 +76,7 @@ trait JSDefinitions { self: JSGlobalAddons => lazy val ExposedJSMemberAnnot = getRequiredClass("scala.scalajs.js.annotation.internal.ExposedJSMember") lazy val JSOptionalAnnotation = getRequiredClass("scala.scalajs.js.annotation.internal.JSOptional") - lazy val RawJSTypeAnnot = getRequiredClass("scala.scalajs.js.annotation.internal.RawJSType") + lazy val JSTypeAnnot = getRequiredClass("scala.scalajs.js.annotation.internal.JSType") lazy val WasPublicBeforeTyperClass = getRequiredClass("scala.scalajs.js.annotation.internal.WasPublicBeforeTyper") lazy val JSAnyTpe = JSAnyClass.toTypeConstructor diff --git a/compiler/src/main/scala/org/scalajs/nscplugin/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/nscplugin/PrepJSInterop.scala index d72f762c43..3a3bcf02da 100644 --- a/compiler/src/main/scala/org/scalajs/nscplugin/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/PrepJSInterop.scala @@ -131,7 +131,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent * won't reach the backend. * * We don't completely disable this phase under ScalaDoc mostly because - * we want to keep the addition of `RawJSType` annotations, so that they + * we want to keep the addition of `JSType` annotations, so that they * appear in the doc. * * Preparing exports, however, is a pure waste of time, which we cannot @@ -191,7 +191,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent checkJSAnySpecificAnnotsOnNonJSAny(cldef) if (sym == UnionClass) - sym.addAnnotation(RawJSTypeAnnot) + sym.addAnnotation(JSTypeAnnot) if (shouldPrepareExports) registerClassOrModuleExports(sym) @@ -214,12 +214,12 @@ abstract class PrepJSInterop extends plugins.PluginComponent super.transform(tree) // Catch ValDef in js.Any - case vdef: ValDef if enclosingOwner is OwnerKind.RawJSType => - transformValOrDefDefInRawJSType(vdef) + case vdef: ValDef if enclosingOwner is OwnerKind.JSType => + transformValOrDefDefInJSType(vdef) // Catch DefDef in js.Any - case ddef: DefDef if enclosingOwner is OwnerKind.RawJSType => - transformValOrDefDefInRawJSType(fixPublicBeforeTyper(ddef)) + case ddef: DefDef if enclosingOwner is OwnerKind.JSType => + transformValOrDefDefInJSType(fixPublicBeforeTyper(ddef)) // Catch ValDefs in enumerations with simple calls to Value case ValDef(mods, name, tpt, ScalaEnumValue.NoName(optPar)) @@ -494,7 +494,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent val isJSAnonFun = isJSLambda(sym) - sym.addAnnotation(RawJSTypeAnnot) + sym.addAnnotation(JSTypeAnnot) /* Anonymous functions are considered native, since they are handled * specially in the backend. @@ -779,7 +779,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent } /** Verify a ValOrDefDef inside a js.Any */ - private def transformValOrDefDefInRawJSType(tree: ValOrDefDef) = { + private def transformValOrDefDefInJSType(tree: ValOrDefDef) = { val sym = tree.symbol assert(!sym.isLocalToBlock, s"$tree at ${tree.pos}") @@ -1129,7 +1129,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent * Reports error messages otherwise. */ def checkSetterSignature(sym: Symbol, pos: Position, exported: Boolean): Unit = { - val typeStr = if (exported) "Exported" else "Raw JS" + val typeStr = if (exported) "Exported" else "JS" // Forbid setters with non-unit return type if (sym.tpe.resultType.typeSymbol != UnitClass) { @@ -1403,7 +1403,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent */ def isCompilerAnnotation(annotation: AnnotationInfo): Boolean = { annotation.symbol == ExposedJSMemberAnnot || - annotation.symbol == RawJSTypeAnnot || + annotation.symbol == JSTypeAnnot || annotation.symbol == JSOptionalAnnotation } @@ -1478,10 +1478,10 @@ object PrepJSInterop { val JSNative = JSNativeClass | JSNativeMod /** A non-native JS class/trait/object. */ val JSNonNative = JSClass | JSMod - /** A raw JS type, i.e., something extending js.Any. */ - val RawJSType = JSNative | JSNonNative + /** A JS type, i.e., something extending js.Any. */ + val JSType = JSNative | JSNonNative - /** Any kind of class/trait, i.e., a Scala or raw JS class/trait. */ + /** Any kind of class/trait, i.e., a Scala or JS class/trait. */ val AnyClass = ScalaClass | JSNativeClass | JSClass } } diff --git a/compiler/src/test/scala/org/scalajs/nscplugin/test/DiverseErrorsTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/DiverseErrorsTest.scala index 2adf9b1499..66706b21d8 100644 --- a/compiler/src/test/scala/org/scalajs/nscplugin/test/DiverseErrorsTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/DiverseErrorsTest.scala @@ -24,20 +24,20 @@ class DiverseErrorsTest extends DirectTest with TestHelpers { """ @Test - def noIsInstanceOnJSRaw: Unit = { + def noIsInstanceOnJS: Unit = { """ @js.native - trait JSRaw extends js.Object + trait JSTrait extends js.Object class A { val a: AnyRef = "asdf" - def x = a.isInstanceOf[JSRaw] + def x = a.isInstanceOf[JSTrait] } """ hasErrors """ - |newSource1.scala:8: error: isInstanceOf[JSRaw] not supported because it is a raw JS trait - | def x = a.isInstanceOf[JSRaw] + |newSource1.scala:8: error: isInstanceOf[JSTrait] not supported because it is a JS trait + | def x = a.isInstanceOf[JSTrait] | ^ """ diff --git a/compiler/src/test/scala/org/scalajs/nscplugin/test/InternalAnnotationsTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/InternalAnnotationsTest.scala index f7fa3f7d54..c677a67434 100644 --- a/compiler/src/test/scala/org/scalajs/nscplugin/test/InternalAnnotationsTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/InternalAnnotationsTest.scala @@ -29,8 +29,8 @@ class InternalAnnotationsTest extends DirectTest with TestHelpers { } @Test - def rawJSType: Unit = { - test("RawJSType") + def jsType: Unit = { + test("JSType") } @Test diff --git a/compiler/src/test/scala/org/scalajs/nscplugin/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/JSExportTest.scala index df8f494054..618a13ab79 100644 --- a/compiler/src/test/scala/org/scalajs/nscplugin/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/JSExportTest.scala @@ -648,7 +648,7 @@ class JSExportTest extends DirectTest with TestHelpers { } @Test - def noExportJSRawMember: Unit = { + def noExportJSMember: Unit = { """ import scala.scalajs.js diff --git a/compiler/src/test/scala/org/scalajs/nscplugin/test/JSInteropTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/JSInteropTest.scala index a5ae204e47..03364af340 100644 --- a/compiler/src/test/scala/org/scalajs/nscplugin/test/JSInteropTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/JSInteropTest.scala @@ -610,16 +610,16 @@ class JSInteropTest extends DirectTest with TestHelpers { } """ hasErrors """ - |newSource1.scala:8: error: Raw JS setters must return Unit + |newSource1.scala:8: error: JS setters must return Unit | def foo_=(x: Int): Int = js.native | ^ - |newSource1.scala:9: error: Raw JS setters must have exactly one argument + |newSource1.scala:9: error: JS setters must have exactly one argument | def bar_=(x: Int, y: Int): Unit = js.native | ^ - |newSource1.scala:10: error: Raw JS setters may not have repeated params + |newSource1.scala:10: error: JS setters may not have repeated params | def goo_=(x: Int*): Unit = js.native | ^ - |newSource1.scala:11: error: Raw JS setters may not have default params + |newSource1.scala:11: error: JS setters may not have default params | def hoo_=(x: Int = 1): Unit = js.native | ^ """ @@ -713,7 +713,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } @Test - def onlyJSRawTraits: Unit = { + def onlyJSTraits: Unit = { """ trait A @@ -1072,7 +1072,7 @@ class JSInteropTest extends DirectTest with TestHelpers { } @Test - def warnNothingRaw: Unit = { + def warnNothingInNativeJS: Unit = { """ @js.native diff --git a/compiler/src/test/scala/org/scalajs/nscplugin/test/JSOptionalTest.scala b/compiler/src/test/scala/org/scalajs/nscplugin/test/JSOptionalTest.scala index c1022e0c3c..4c87f0aab7 100644 --- a/compiler/src/test/scala/org/scalajs/nscplugin/test/JSOptionalTest.scala +++ b/compiler/src/test/scala/org/scalajs/nscplugin/test/JSOptionalTest.scala @@ -170,7 +170,7 @@ class JSOptionalTest extends DirectTest with TestHelpers { |newSource1.scala:7: error: In non-native JS traits, defs with parentheses must be abstract. | def b(x: Int): js.UndefOr[Int] = js.undefined | ^ - |newSource1.scala:8: error: Raw JS setters must return Unit + |newSource1.scala:8: error: JS setters must return Unit | def c_=(v: Int): js.UndefOr[Int] = js.undefined | ^ |newSource1.scala:8: error: In non-native JS traits, defs with parentheses must be abstract. diff --git a/ir/src/main/scala/org/scalajs/ir/Types.scala b/ir/src/main/scala/org/scalajs/ir/Types.scala index d56cc3d090..3739107503 100644 --- a/ir/src/main/scala/org/scalajs/ir/Types.scala +++ b/ir/src/main/scala/org/scalajs/ir/Types.scala @@ -24,7 +24,7 @@ object Types { /** Type of a term (expression or statement) in the IR. * * There is a many-to-one relationship from [[TypeRef]]s to `Type`s, - * because `java.lang.Object` and raw JS types all collapse to [[AnyType]]. + * because `java.lang.Object` and JS types all collapse to [[AnyType]]. * * In fact, there are two `Type`s that do not have any real equivalent in * type refs: [[StringType]] and [[UndefType]], as they refer to the @@ -42,13 +42,13 @@ object Types { /** Any type (the top type of this type system). * A variable of this type can contain any value, including `undefined` - * and `null` and any raw JS value. This type supports a very limited set + * and `null` and any JS value. This type supports a very limited set * of Scala operations, the ones common to all values. Basically only * reference equality tests and instance tests. It also supports all * JavaScript operations, since all Scala objects are also genuine * JavaScript objects. * The type java.lang.Object in the back-end maps to [[AnyType]] because it - * can hold raw JS values (not only instances of Scala.js classes). + * can hold JS values (not only instances of Scala.js classes). */ case object AnyType extends Type @@ -147,7 +147,7 @@ object Types { * * - All primitive types have their `TypeRef` (including `scala.Byte` and * `scala.Short`), and they are different from their boxed versions. - * - Raw JS types are not erased to `any` + * - JS types are not erased to `any` * - Array types are like on the JVM * * A `TypeRef` therefore uniquely identifies a `classOf[T]`. It is also the @@ -247,7 +247,7 @@ object Types { lhsBase == rhsBase } else { /* All things must be considered subclasses of Object for this - * purpose, even raw JS types and interfaces, which do not have + * purpose, even JS types and interfaces, which do not have * Object in their ancestors. */ rhsBase == ObjectClass || isSubclass(lhsBase, rhsBase) diff --git a/javalanglib/src/main/scala/java/lang/Class.scala b/javalanglib/src/main/scala/java/lang/Class.scala index 8cd87a7e35..3b77e13a4e 100644 --- a/javalanglib/src/main/scala/java/lang/Class.scala +++ b/javalanglib/src/main/scala/java/lang/Class.scala @@ -20,7 +20,7 @@ private trait ScalaJSClassData[A] extends js.Object { val isPrimitive: scala.Boolean = js.native val isInterface: scala.Boolean = js.native val isArrayClass: scala.Boolean = js.native - val isRawJSType: scala.Boolean = js.native + val isJSType: scala.Boolean = js.native def isInstance(obj: Object): scala.Boolean = js.native def isAssignableFrom(that: ScalaJSClassData[_]): scala.Boolean = js.native @@ -55,8 +55,8 @@ final class Class[A] private (data0: Object) extends Object { def isPrimitive(): scala.Boolean = data.isPrimitive - private def isRawJSType(): scala.Boolean = - data.isRawJSType + private def isJSType(): scala.Boolean = + data.isJSType def getName(): String = data.name @@ -74,7 +74,7 @@ final class Class[A] private (data0: Object) extends Object { def cast(obj: Object): A = { scala.scalajs.runtime.SemanticsUtils.asInstanceOfCheck( (this eq classOf[Nothing]) || - (obj != null && !isRawJSType && !isInstance(obj)), + (obj != null && !isJSType && !isInstance(obj)), new ClassCastException("" + obj + " is not an instance of " + getName)) obj.asInstanceOf[A] } diff --git a/library/src/main/scala/scala/scalajs/js/annotation/JSExport.scala b/library/src/main/scala/scala/scalajs/js/annotation/JSExport.scala index 0a89e23f1f..504dec4b84 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/JSExport.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/JSExport.scala @@ -14,7 +14,7 @@ package scala.scalajs.js.annotation import scala.annotation.meta._ -/** Specifies that the given entity should be exported for use in raw JS. +/** Specifies that the given entity should be exported for use in JS. * * @see [[http://www.scala-js.org/doc/export-to-javascript.html Export Scala.js APIs to JavaScript]] */ diff --git a/library/src/main/scala/scala/scalajs/js/annotation/internal/RawJSType.scala b/library/src/main/scala/scala/scalajs/js/annotation/internal/JSType.scala similarity index 69% rename from library/src/main/scala/scala/scalajs/js/annotation/internal/RawJSType.scala rename to library/src/main/scala/scala/scalajs/js/annotation/internal/JSType.scala index 0c8d8edfac..bf89e3ba20 100644 --- a/library/src/main/scala/scala/scalajs/js/annotation/internal/RawJSType.scala +++ b/library/src/main/scala/scala/scalajs/js/annotation/internal/JSType.scala @@ -12,14 +12,14 @@ package scala.scalajs.js.annotation.internal -/** Marks the annotated class, trait or object as a raw JavaScript type. +/** IMPLEMENTATION DETAIL: Marks the annotated class, trait or object as a + * JavaScript type. * * This annotation is added automatically by the compiler to all classes, * traits and objects inheriting directly or indirectly from - * [[scala.scalajs.js.Any]]. It marks the annotated entity as being a raw - * JavaScript type, i.e., one that represents type information for an entity - * defined in JavaScript code. + * [[scala.scalajs.js.Any]]. It marks the annotated entity as being a + * JavaScript type. * * Do not use this annotation yourself. */ -class RawJSType extends scala.annotation.StaticAnnotation +class JSType extends scala.annotation.StaticAnnotation diff --git a/library/src/main/scala/scala/scalajs/js/package.scala b/library/src/main/scala/scala/scalajs/js/package.scala index 02cbb1663c..a52e97d9c7 100644 --- a/library/src/main/scala/scala/scalajs/js/package.scala +++ b/library/src/main/scala/scala/scalajs/js/package.scala @@ -133,10 +133,10 @@ package object js { */ def native: Nothing = { throw new java.lang.Error( - "A method defined in a JavaScript raw type of a Scala.js library has " + - "been called. This is most likely because you tried to run Scala.js " + - "binaries on the JVM. Make sure you are using the JVM version of the " + - "libraries.") + "A method defined in a native JavaScript type of a Scala.js library " + + "has been called. This is most likely because you tried to run " + + "Scala.js binaries on the JVM. Make sure you are using the JVM " + + "version of the libraries.") } } diff --git a/linker/scalajsenv.js b/linker/scalajsenv.js index 3709a121da..ae023deac6 100644 --- a/linker/scalajsenv.js +++ b/linker/scalajsenv.js @@ -257,7 +257,7 @@ function $throwArrayIndexOutOfBoundsException(i) { function $noIsInstance(instance) { throw new TypeError( - "Cannot call isInstance() on a Class representing a raw JS trait/object"); + "Cannot call isInstance() on a Class representing a JS trait/object"); }; function $makeNativeArrayWrapper(arrayClassData, nativeArray) { @@ -868,7 +868,7 @@ constructor() { this["isPrimitive"] = false; this["isInterface"] = false; this["isArrayClass"] = false; - this["isRawJSType"] = false; + this["isJSType"] = false; this["isInstance"] = void 0; }; @@ -899,7 +899,7 @@ $TypeData.prototype.initClass = function( initClass( //!endif internalNameObj, isInterface, fullName, - ancestors, isRawJSType, parentData, isInstance, isArrayOf) { + ancestors, isJSType, parentData, isInstance, isArrayOf) { const internalName = $propertyName(internalNameObj); isInstance = isInstance || function(obj) { @@ -920,7 +920,7 @@ initClass( // java.lang.Class support this["name"] = fullName; this["isInterface"] = isInterface; - this["isRawJSType"] = !!isRawJSType; + this["isJSType"] = !!isJSType; this["isInstance"] = isInstance; return this; diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala index cc5dd4acbf..55e5d0208c 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala @@ -161,7 +161,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { } else if (tree.jsSuperClass.isDefined) { WithGlobals(envField("superClass")) } else { - genRawJSClassConstructor(parentIdent.name, + genJSClassConstructor(parentIdent.name, keepOnlyDangerousVarNames = true) } } @@ -242,7 +242,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val superCtor = if (tree.jsSuperClass.isDefined) { WithGlobals(envField("superClass")) } else { - genRawJSClassConstructor(parentIdent.name, + genJSClassConstructor(parentIdent.name, keepOnlyDangerousVarNames = true) } (superCtor.map(makeInheritableCtorDef(_, "h")), envField("h", className)) @@ -868,7 +868,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val isJSType = kind.isJSType - val isRawJSTypeParam = + val isJSTypeParam = if (isJSType) js.BooleanLiteral(true) else js.Undefined() @@ -911,7 +911,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { WithGlobals(envField("noIsInstance")) } else { for { - jsCtor <- genRawJSClassConstructor(className, tree.jsNativeLoadSpec, + jsCtor <- genJSClassConstructor(className, tree.jsNativeLoadSpec, keepOnlyDangerousVarNames = true) } yield { genArrowFunction(List(js.ParamDef(js.Ident("x"), rest = false)), js.Return { @@ -941,7 +941,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { js.BooleanLiteral(kind == ClassKind.Interface), js.StringLiteral(semantics.runtimeClassNameMapper(tree.fullName)), ancestorsRecord, - isRawJSTypeParam, + isJSTypeParam, parentData, isInstanceFun, isArrayOfFun diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala index 9c867d11bb..8485de809e 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala @@ -728,7 +728,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { } else { val superClass = globalKnowledge.getSuperClassOfJSClass(enclosingClassName) - extractWithGlobals(genRawJSClassConstructor(superClass)) + extractWithGlobals(genJSClassConstructor(superClass)) } } @@ -2514,7 +2514,7 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { transformExprNoChar(qualifier), transformExprNoChar(item)) case LoadJSConstructor(cls) => - extractWithGlobals(genRawJSClassConstructor(cls.className)) + extractWithGlobals(genJSClassConstructor(cls.className)) case LoadJSModule(cls) => val className = cls.className @@ -2723,9 +2723,9 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { /* 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)( + private def genJSClassConstructor(className: String)( implicit pos: Position): WithGlobals[js.Tree] = { - jsGen.genRawJSClassConstructor(className, + jsGen.genJSClassConstructor(className, keepOnlyDangerousVarNames = false) } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/JSGen.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/JSGen.scala index 18e91da3fe..5d18f9b06b 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/JSGen.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/JSGen.scala @@ -171,17 +171,17 @@ private[emitter] final class JSGen(val semantics: Semantics, Apply(envField("m", moduleClass), Nil) } - def genRawJSClassConstructor(className: String, + def genJSClassConstructor(className: String, keepOnlyDangerousVarNames: Boolean)( implicit globalKnowledge: GlobalKnowledge, pos: Position): WithGlobals[Tree] = { - genRawJSClassConstructor(className, + genJSClassConstructor(className, globalKnowledge.getJSNativeLoadSpec(className), keepOnlyDangerousVarNames) } - def genRawJSClassConstructor(className: String, + def genJSClassConstructor(className: String, spec: Option[irt.JSNativeLoadSpec], keepOnlyDangerousVarNames: Boolean)( implicit pos: Position): WithGlobals[Tree] = { diff --git a/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala b/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala index 3c154c232e..4959b418f6 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/checker/IRChecker.scala @@ -82,8 +82,11 @@ private final class IRChecker(unit: LinkingUnit, classDef.memberMethods.nonEmpty || classDef.exportedMembers.nonEmpty || classDef.topLevelExports.nonEmpty) { - reportError(s"Raw JS type ${classDef.name} cannot "+ - "have instance members") + val kind = + if (classDef.kind == ClassKind.AbstractJSType) "Abstract" + else "Native" + reportError( + s"$kind JS type ${classDef.name} cannot have instance members") } case _ => checkScalaClassDef(classDef) diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala index 52ce9701ff..1408d44607 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/InteroperabilityTest.scala @@ -380,18 +380,18 @@ class InteroperabilityTest { assertEquals(42, Global.interoperabilityTestGlobalScopeValueAsInt) } - @Test def should_protect_receiver_of_raw_JS_apply_if_its_a_select_issue_804(): Unit = { - val rawReceiver = js.eval(""" - var interoperabilityTestRawReceiver = { + @Test def should_protect_receiver_of_JS_apply_if_its_a_select_issue_804(): Unit = { + val obj = js.eval(""" + var interoperabilityTestJSFunctionFieldApply = { member: 0xbad, - check: function(raw) { return this.member ? this.member : raw; } + check: function(x) { return this.member ? this.member : x; } }; - interoperabilityTestRawReceiver; - """).asInstanceOf[InteroperabilityTestRawReceiver] + interoperabilityTestJSFunctionFieldApply; + """).asInstanceOf[InteroperabilityTestJSFunctionFieldApply] - assertEquals(7357, rawReceiver.check(7357)) + assertEquals(7357, obj.check(7357)) - val check = rawReceiver.check + val check = obj.check assertEquals(0x600d, check(0x600d)) class InScalaSelect(check: js.Function1[Int, Int]) { @@ -672,12 +672,12 @@ object InteroperabilityTest { } @js.native - trait InteroperabilityTestRawReceiver extends js.Object { + trait InteroperabilityTestJSFunctionFieldApply extends js.Object { val check: js.Function1[Int, Int] = js.native } - /** Trait with different method signatures, all forwarded to the same - * JS raw function that returns the argument list for inspection + /** Trait with different method signatures, all forwarded to the same JS + * function that returns the argument list for inspection. */ @js.native trait InteroperabilityTestDefaultParam extends js.Object { diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectionTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectionTest.scala index 79f694e455..210c1e7b22 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectionTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/ReflectionTest.scala @@ -79,32 +79,32 @@ class ReflectionTest { assertTrue(classOf[Cloneable].isInstance(new Array[String](1))) } - @Test def isInstance_for_raw_JS_class(): Unit = { - js.eval("""var ReflectionTestRawJSClass = (function() {})""") + @Test def isInstance_for_JS_class(): Unit = { + js.eval("""var ReflectionTestJSClass = (function() {})""") - val obj = new ReflectionTestRawJSClass - assertTrue(obj.isInstanceOf[ReflectionTestRawJSClass]) - assertTrue(classOf[ReflectionTestRawJSClass].isInstance(obj)) + val obj = new ReflectionTestJSClass + assertTrue(obj.isInstanceOf[ReflectionTestJSClass]) + assertTrue(classOf[ReflectionTestJSClass].isInstance(obj)) val other = (5, 6): Any - assertFalse(other.isInstanceOf[ReflectionTestRawJSClass]) - assertFalse(classOf[ReflectionTestRawJSClass].isInstance(other)) + assertFalse(other.isInstanceOf[ReflectionTestJSClass]) + assertFalse(classOf[ReflectionTestJSClass].isInstance(other)) - val ct = classTag[ReflectionTestRawJSClass] + val ct = classTag[ReflectionTestJSClass] assertTrue(ct.unapply(obj).isDefined) assertFalse(ct.unapply(other).isDefined) - assertTrue(implicitClassTagTest[ReflectionTestRawJSClass](obj)) - assertFalse(implicitClassTagTest[ReflectionTestRawJSClass](other)) + assertTrue(implicitClassTagTest[ReflectionTestJSClass](obj)) + assertFalse(implicitClassTagTest[ReflectionTestJSClass](other)) } - @Test def isInstance_for_raw_JS_traits_should_fail(): Unit = { - assertThrows(classOf[Exception], classOf[ReflectionTestRawJSTrait].isInstance(5)) + @Test def isInstance_for_JS_traits_should_fail(): Unit = { + assertThrows(classOf[Exception], classOf[ReflectionTestJSTrait].isInstance(5)) - val ct = classTag[ReflectionTestRawJSTrait] + val ct = classTag[ReflectionTestJSTrait] assertThrows(classOf[Exception], ct.unapply(new AnyRef)) - assertThrows(classOf[Exception], implicitClassTagTest[ReflectionTestRawJSTrait](new AnyRef)) + assertThrows(classOf[Exception], implicitClassTagTest[ReflectionTestJSTrait](new AnyRef)) } @Test def getClass_for_normal_types(): Unit = { @@ -166,12 +166,12 @@ object ReflectionTest { class OtherPrefixRenamedTestClass - @JSGlobal("ReflectionTestRawJSClass") + @JSGlobal("ReflectionTestJSClass") @js.native - class ReflectionTestRawJSClass extends js.Object + class ReflectionTestJSClass extends js.Object @js.native - trait ReflectionTestRawJSTrait extends js.Object + trait ReflectionTestJSTrait extends js.Object class SomeParentClass class SomeChildClass extends SomeParentClass diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RuntimeTypesTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RuntimeTypesTest.scala index 193b70e355..9720a08660 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RuntimeTypesTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RuntimeTypesTest.scala @@ -110,7 +110,7 @@ class RuntimeTypesTest { arr.asInstanceOf[Array[Null]] } - @Test def rawJSTypes_Arrays_of_raw_JS_types(): Unit = { + @Test def scala_Arrays_of_JS_types(): Unit = { val arrayOfParentJSType = new Array[ParentJSType](0) val arrayOfJSInterface = new Array[SomeJSInterface](0) val arrayOfJSClass = new Array[SomeJSClass](0) From 441ef7f99c00dda057fe37a54db36000b1d5f9d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 19 Nov 2018 17:53:26 +0100 Subject: [PATCH 0865/2665] Do not be verbose in JUnit by default. In an effort to reduce the size of logs on the CI, we disable verbose logging in JUnit by default. It can be enabled locally when needed with testOnly some.Test -- -v --- project/Build.scala | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 4287119470..39a627e52d 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -529,7 +529,7 @@ object Build { mimaBinaryIssueFilters ++= BinaryIncompatibilities.IR, exportJars := true, // required so ScalaDoc linking works - testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a", "-s") + testOptions += Tests.Argument(TestFrameworks.JUnit, "-a", "-s") ) lazy val irProject: Project = Project( @@ -566,7 +566,7 @@ object Build { "org.scala-lang" % "scala-reflect" % scalaVersion.value, "com.novocode" % "junit-interface" % "0.9" % "test" ), - testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a"), + testOptions += Tests.Argument(TestFrameworks.JUnit, "-a"), testOptions += Tests.Setup { () => val testOutDir = (streams.value.cacheDirectory / "scalajs-compiler-test") IO.createDirectory(testOutDir) @@ -1304,7 +1304,7 @@ object Build { unmanagedSourceDirectories in Test += baseDirectory.value.getParentFile / "shared/src/test/scala", testOptions in Test ++= Seq( - Tests.Argument(TestFrameworks.JUnit, "-v", "-a", "-s"), + Tests.Argument(TestFrameworks.JUnit, "-a", "-s"), Tests.Filter(_.endsWith("Assertions")) ) ) @@ -1519,7 +1519,7 @@ object Build { libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value % "provided", - testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a", "-s"), + testOptions += Tests.Argument(TestFrameworks.JUnit, "-a", "-s"), unmanagedSourceDirectories in Test ++= { val testDir = (sourceDirectory in Test).value @@ -1855,7 +1855,7 @@ object Build { withCheckScalaJSIR(false). withBypassLinkingErrors(true) ), - testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a", "-s"), + testOptions += Tests.Argument(TestFrameworks.JUnit, "-a", "-s"), publishArtifact in Compile := false ) ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn(library, jUnitRuntime) @@ -1868,7 +1868,7 @@ object Build { ) ++ Seq( name := "JavaLib Ex Test Suite", publishArtifact in Compile := false, - testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a", "-s"), + testOptions += Tests.Argument(TestFrameworks.JUnit, "-a", "-s"), scalacOptions in Test ~= (_.filter(_ != "-deprecation")) ) ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn(javalibEx, jUnitRuntime) @@ -2018,7 +2018,7 @@ object Build { settings = commonSettings ++ myScalaJSSettings ++ Seq( publishArtifact in Compile := false, - testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a", "-s"), + testOptions += Tests.Argument(TestFrameworks.JUnit, "-a", "-s"), unmanagedSources in Test ++= { assert(scalaBinaryVersion.value != "2.10", From 8463f513e8bad1186935118bfac1eb087c265318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 19 Nov 2018 11:58:00 +0100 Subject: [PATCH 0866/2665] Fix #3492: Allow double-underscore in top-level exports. --- .../scalajs/core/compiler/PrepJSExports.scala | 2 +- .../core/compiler/test/JSExportTest.scala | 19 +++++++++++++++++++ .../testsuite/jsinterop/ExportsTest.scala | 7 +++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala index b9d1710cfc..03685c2139 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala @@ -299,7 +299,7 @@ trait PrepJSExports { this: PrepJSInterop => checkSetterSignature(sym, annot.pos, exported = true) // Enforce no __ in name - if (name.contains("__")) { + if (!isTopLevelExport && name.contains("__")) { // Get position for error message val pos = if (hasExplicitName) annot.args.head.pos else trgSym.pos diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index 7faa946bb1..d807e611d7 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -126,6 +126,25 @@ class JSExportTest extends DirectTest with TestHelpers { """ } + @Test + def doubleUnderscoreOKInTopLevelExport: Unit = { + """ + @JSExportTopLevel("__A") + class A + + @JSExportTopLevel("__B") + object B + + object Container { + @JSExportTopLevel("__c") + def c(): Int = 4 + + @JSExportTopLevel("__d") + val d: Boolean = true + } + """.hasNoWarns + } + @Test def noConflictingExport: Unit = { """ diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index 8784cd5769..2a20a1fd19 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -1426,6 +1426,10 @@ class ExportsTest { assertEquals(28, TopLevelExports.Nested.myVar) } + @Test def top_level_export_with_double_underscore(): Unit = { + assertEquals(true, exportsNamespace.__topLevelExportWithDoubleUnderscore) + } + @Test def top_level_export_is_always_reachable(): Unit = { assertEquals("Hello World", jsPackage.toplevel.reachability()) } @@ -1939,6 +1943,9 @@ object TopLevelExports { @JSExportTopLevel("org.scalajs.testsuite.jsinterop.toplevel.setNested") def setMyVar(x: Int): Unit = myVar = x } + + @JSExportTopLevel("__topLevelExportWithDoubleUnderscore") + val topLevelExportWithDoubleUnderscore: Boolean = true } /* This object is only reachable via the top level export to make sure the From e4ceabec265f60750a43a03aa3b129617db916f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 14 Nov 2018 18:34:55 +0100 Subject: [PATCH 0867/2665] Replace jsExecutionFiles by jsEnvInput of type JSEnv.Input. --- project/Build.scala | 22 ++++++++++++------- .../org/scalajs/sbtplugin/ScalaJSPlugin.scala | 10 ++++----- .../sbtplugin/ScalaJSPluginInternal.scala | 22 ++++++++----------- .../testing/adapter/HTMLRunnerBuilder.scala | 12 +++++++++- 4 files changed, 38 insertions(+), 28 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index b265f569d8..a549153efc 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -67,8 +67,8 @@ object MyScalaJSPlugin extends AutoPlugin { val configSettings: Seq[Setting[_]] = Def.settings( // Add a JS file defining Java system properties - jsExecutionFiles := { - val prev = jsExecutionFiles.value + jsEnvInput := { + val prev = jsEnvInput.value val javaSysPropsPattern = "-D([^=]*)=(.*)".r val javaSystemProperties = javaOptions.value.collect { @@ -78,6 +78,8 @@ object MyScalaJSPlugin extends AutoPlugin { if (javaSystemProperties.isEmpty) { prev } else { + val Input.ScriptsToLoad(prevFiles) = prev + val formattedProps = javaSystemProperties.map { case (propName, propValue) => "\"" + escapeJS(propName) + "\": \"" + escapeJS(propValue) + "\"" @@ -89,7 +91,7 @@ object MyScalaJSPlugin extends AutoPlugin { val javaSysPropsFile = MemVirtualBinaryFile.fromStringUTF8("setJavaSystemProperties.js", code) - javaSysPropsFile +: prev + Input.ScriptsToLoad(javaSysPropsFile +: prevFiles) } } ) @@ -1452,8 +1454,9 @@ object Build { def testSuiteTestHtmlSetting = Def.settings( // We need to patch the system properties. - jsExecutionFiles in (Test, testHtml) := { - val previousFiles = (jsExecutionFiles in (Test, testHtml)).value + jsEnvInput in (Test, testHtml) := { + val previousInput = (jsEnvInput in (Test, testHtml)).value + val Input.ScriptsToLoad(previousFiles) = previousInput val patchedSystemProperties = { // Fetch the defaults @@ -1483,12 +1486,14 @@ object Build { MemVirtualBinaryFile.fromStringUTF8("setJavaSystemProperties.js", code) // Replace the normal `setJavaSystemProperties.js` file with the patch - for (file <- previousFiles) yield { + val newFiles = for (file <- previousFiles) yield { if (file.path == "setJavaSystemProperties.js") patchedSystemPropertiesFile else file } + + Input.ScriptsToLoad(newFiles) } ) @@ -1557,11 +1562,12 @@ object Build { ) def testSuiteJSExecutionFilesSetting: Setting[_] = { - jsExecutionFiles := { + jsEnvInput := { + val Input.ScriptsToLoad(prevFiles) = jsEnvInput.value val resourceDir = (resourceDirectory in Test).value val f = new FileVirtualBinaryFile( resourceDir / "NonNativeJSTypeTestNatives.js") - f +: jsExecutionFiles.value + Input.ScriptsToLoad(f +: prevFiles) } } diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala index 6a473bf73a..d6e1f3ca0f 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala @@ -24,7 +24,7 @@ import org.scalajs.io._ import org.scalajs.linker._ import org.scalajs.linker.irio._ -import org.scalajs.jsenv.JSEnv +import org.scalajs.jsenv.{Input, JSEnv} import org.scalajs.jsenv.nodejs.NodeJSEnv object ScalaJSPlugin extends AutoPlugin { @@ -143,9 +143,9 @@ object ScalaJSPlugin extends AutoPlugin { "Prints the content of a .sjsir file in human readable form.", CTask) - val jsExecutionFiles = TaskKey[Seq[VirtualBinaryFile]]( - "jsExecutionFiles", - "All the JS files given to JS environments on `run`, `test`, etc.", + val jsEnvInput = TaskKey[Input]( + "jsEnvInput", + "The JSEnv.Input to give to the jsEnv for tasks such as `run` and `test`", BTask) val scalaJSSourceFiles = AttributeKey[Seq[File]]("scalaJSSourceFiles", @@ -176,8 +176,6 @@ object ScalaJSPlugin extends AutoPlugin { jsEnv := new NodeJSEnv(), - jsExecutionFiles := Nil, - // Clear the IR cache stats every time a sequence of tasks ends onComplete := { val prev = onComplete.value diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index c3bb03cf00..f7437cdd31 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -305,15 +305,11 @@ private[sbtplugin] object ScalaJSPluginInternal { "are running a JVM REPL. JavaScript things won't work.") }).value, - /* Do not inherit jsExecutionFiles from the parent configuration. - * Instead, always derive them straight from the Zero configuration - * scope. - */ - jsExecutionFiles := (jsExecutionFiles in (This, Zero, This)).value, - - // Add the Scala.js linked file to the JS files (by default, the only one) - jsExecutionFiles += - new FileVirtualBinaryFile(scalaJSLinkedFile.value.data), + // Use the Scala.js linked file as the default Input for the JSEnv + jsEnvInput := { + Input.ScriptsToLoad(List( + new FileVirtualBinaryFile(scalaJSLinkedFile.value.data))) + }, scalaJSMainModuleInitializer := { mainClass.value.map { mainCl => @@ -357,7 +353,7 @@ private[sbtplugin] object ScalaJSPluginInternal { log.info(s"Running $className. Hit any key to interrupt.") log.debug(s"with JSEnv ${env.name}") - val input = Input.ScriptsToLoad(jsExecutionFiles.value.toList) + val input = jsEnvInput.value val config = RunConfig().withLogger(sbtLogger2ToolsLogger(log)) Run.runInterruptible(env, input, config) @@ -423,7 +419,7 @@ private[sbtplugin] object ScalaJSPluginInternal { val frameworks = testFrameworks.value val env = jsEnv.value - val input = Input.ScriptsToLoad(jsExecutionFiles.value.toList) + val input = jsEnvInput.value val frameworkNames = frameworks.map(_.implClassNames.toList).toList val logger = sbtLogger2ToolsLogger(streams.value.log) @@ -459,7 +455,7 @@ private[sbtplugin] object ScalaJSPluginInternal { val log = streams.value.log val output = (artifactPath in testHtml).value val title = name.value + " - tests" - val jsFiles = (jsExecutionFiles in testHtml).value + val input = (jsEnvInput in testHtml).value val frameworks = (loadedTestFrameworks in testHtml).value.toList val frameworkImplClassNames = @@ -470,7 +466,7 @@ private[sbtplugin] object ScalaJSPluginInternal { td.explicitlySpecified, td.selectors) } - HTMLRunnerBuilder.writeToFile(output, title, jsFiles, + HTMLRunnerBuilder.writeToFile(output, title, input, frameworkImplClassNames, taskDefs.toList) log.info(s"Wrote HTML test runner. Point your browser to ${output.toURI}") diff --git a/test-adapter/src/main/scala/org/scalajs/testing/adapter/HTMLRunnerBuilder.scala b/test-adapter/src/main/scala/org/scalajs/testing/adapter/HTMLRunnerBuilder.scala index 9c84137198..4baeee96b8 100644 --- a/test-adapter/src/main/scala/org/scalajs/testing/adapter/HTMLRunnerBuilder.scala +++ b/test-adapter/src/main/scala/org/scalajs/testing/adapter/HTMLRunnerBuilder.scala @@ -24,6 +24,8 @@ import sbt.testing.{Framework, TaskDef} import org.scalajs.io._ import org.scalajs.io.JSUtils.escapeJS +import org.scalajs.jsenv.{Input, UnsupportedInputException} + import org.scalajs.testing.common._ /** Template for the HTML runner. */ @@ -48,10 +50,18 @@ object HTMLRunnerBuilder { } } - def writeToFile(output: File, title: String, jsFiles: Seq[VirtualBinaryFile], + def writeToFile(output: File, title: String, input: Input, frameworkImplClassNames: List[List[String]], taskDefs: List[TaskDef]): Unit = { + val jsFiles = input match { + case Input.ScriptsToLoad(jsFiles) => + jsFiles + case _ => + throw new UnsupportedInputException( + s"Unsupported input for the generation of an HTML runner: $input") + } + val jsFileURIs = jsFiles.map { case file: FileVirtualFile => file.file.toURI case file => tmpFile(file.path, file.inputStream) From 2e76004eed21dc3026bb7a32c961ac43fc0314bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 27 Nov 2018 10:40:35 +0100 Subject: [PATCH 0868/2665] Version 0.6.26. --- ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index 58797ce453..34f63022a9 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -22,7 +22,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.26-SNAPSHOT" + val current: String = "0.6.26" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" From 611bab9566bb127d6f04f52348df799e342658e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 28 Nov 2018 00:29:50 +0100 Subject: [PATCH 0869/2665] Towards 0.6.27. --- ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala | 2 +- project/Build.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala index 34f63022a9..719d8704ab 100644 --- a/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala +++ b/ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala @@ -22,7 +22,7 @@ object ScalaJSVersions { */ /** Scala.js version. */ - val current: String = "0.6.26" + val current: String = "0.6.27-SNAPSHOT" /** true iff the Scala.js version is a snapshot version. */ val currentIsSnapshot: Boolean = current endsWith "-SNAPSHOT" diff --git a/project/Build.scala b/project/Build.scala index 39a627e52d..264338bae4 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -62,7 +62,7 @@ object Build { val shouldPartest = settingKey[Boolean]( "Whether we should partest the current scala version (and fail if we can't)") - val previousVersion = "0.6.25" + val previousVersion = "0.6.26" val previousSJSBinaryVersion = ScalaJSCrossVersion.binaryScalaJSVersion(previousVersion) val previousBinaryCrossVersion = From 0e8f4be3fb30163fca83498fe5bdc40bb3ce35fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 30 Nov 2018 13:11:58 +0100 Subject: [PATCH 0870/2665] Drop support for 2.13.0-M3 and 2.13.0-M4. The commit also drops a few references to 2.12.0-M4 that were lingering in comments and assumptions. --- Jenkinsfile | 6 +- ci/checksizes.sh | 18 - .../core/compiler/Compat210Component.scala | 6 +- .../org/scalajs/core/compiler/GenJSCode.scala | 3 +- .../scalajs/core/compiler/PrepJSInterop.scala | 2 +- .../core/compiler/test/JSExportTest.scala | 3 +- .../core/compiler/test/OptimizationTest.scala | 3 +- .../junit/plugin/ScalaJSJUnitPlugin.scala | 3 +- .../scalajs/2.13.0-M3/BlacklistedTests.txt | 1048 ----- .../scalajs/2.13.0-M3/BuglistedTests.txt | 7 - .../scalajs/2.13.0-M3/WhitelistedTests.txt | 3481 ----------------- .../2.13.0-M3/neg/t6446-additional.check | 30 - .../scalajs/2.13.0-M3/neg/t6446-list.check | 2 - .../scalajs/2.13.0-M3/neg/t6446-missing.check | 30 - .../2.13.0-M3/neg/t6446-show-phases.check | 29 - .../2.13.0-M3/neg/t7494-no-options.check | 31 - .../2.13.0-M3/run/Course-2002-01.check | 37 - .../2.13.0-M3/run/Course-2002-02.check | 187 - .../2.13.0-M3/run/Course-2002-04.check | 64 - .../2.13.0-M3/run/Course-2002-08.check | 171 - .../2.13.0-M3/run/Course-2002-09.check | 50 - .../2.13.0-M3/run/Course-2002-10.check | 46 - .../partest/scalajs/2.13.0-M3/run/Meter.check | 16 - .../2.13.0-M3/run/MeterCaseClass.check | 16 - .../2.13.0-M3/run/anyval-box-types.check | 52 - .../partest/scalajs/2.13.0-M3/run/bugs.sem | 1 - .../scalajs/2.13.0-M3/run/caseClassHash.check | 9 - .../partest/scalajs/2.13.0-M3/run/deeps.check | 87 - .../2.13.0-M3/run/dynamic-anyval.check | 4 - .../scalajs/2.13.0-M3/run/impconvtimes.check | 1 - .../scalajs/2.13.0-M3/run/imports.check | 21 - .../scalajs/2.13.0-M3/run/interpolation.check | 32 - .../run/interpolationMultiline1.check | 26 - .../scalajs/2.13.0-M3/run/issue192.sem | 1 - .../2.13.0-M3/run/macro-bundle-static.check | 6 - .../2.13.0-M3/run/macro-bundle-toplevel.check | 6 - .../run/macro-bundle-whitebox-decl.check | 6 - .../partest/scalajs/2.13.0-M3/run/misc.check | 62 - .../scalajs/2.13.0-M3/run/promotion.check | 4 - .../scalajs/2.13.0-M3/run/runtime.check | 70 - .../scalajs/2.13.0-M3/run/spec-self.check | 2 - .../scalajs/2.13.0-M3/run/structural.check | 37 - .../scalajs/2.13.0-M3/run/t0421-new.check | 3 - .../scalajs/2.13.0-M3/run/t0421-old.check | 3 - .../partest/scalajs/2.13.0-M3/run/t1503.sem | 1 - .../partest/scalajs/2.13.0-M3/run/t3702.check | 2 - .../partest/scalajs/2.13.0-M3/run/t4148.sem | 1 - .../partest/scalajs/2.13.0-M3/run/t4617.check | 1 - .../partest/scalajs/2.13.0-M3/run/t5356.check | 6 - .../partest/scalajs/2.13.0-M3/run/t5552.check | 6 - .../partest/scalajs/2.13.0-M3/run/t5568.check | 9 - .../scalajs/2.13.0-M3/run/t5629b.check | 10 - .../partest/scalajs/2.13.0-M3/run/t5680.check | 3 - .../partest/scalajs/2.13.0-M3/run/t5866.check | 2 - .../2.13.0-M3/run/t6318_primitives.check | 54 - .../partest/scalajs/2.13.0-M3/run/t6662.check | 1 - .../partest/scalajs/2.13.0-M3/run/t7657.check | 3 - .../partest/scalajs/2.13.0-M3/run/t7763.sem | 1 - .../scalajs/2.13.0-M3/run/t8570a.check | 1 - .../partest/scalajs/2.13.0-M3/run/t8764.check | 5 - .../scalajs/2.13.0-M3/run/t9387b.check | 1 - .../partest/scalajs/2.13.0-M3/run/t9656.check | 14 - .../2.13.0-M3/run/try-catch-unify.check | 4 - .../2.13.0-M3/run/virtpatmat_switch.check | 7 - .../2.13.0-M3/run/virtpatmat_typetag.check | 10 - project/Build.scala | 13 +- .../overrides-2.13.0-M3/scala/Array.scala | 550 --- .../scala/Enumeration.scala | 284 -- .../collection/immutable/NumericRange.scala | 375 -- .../scala/collection/immutable/Range.scala | 527 --- .../collection/mutable/ArrayBuilder.scala | 735 ---- .../scala/collection/mutable/Buffer.scala | 51 - .../scala/concurrent/ExecutionContext.scala | 183 - .../overrides-2.13.0-M3/scala/package.scala | 133 - .../scala/reflect/ClassTag.scala | 159 - .../scala/reflect/Manifest.scala | 302 -- .../scala/runtime/ScalaRunTime.scala | 268 -- .../overrides-2.13.0-M4/scala/Array.scala | 615 --- .../scala/Enumeration.scala | 302 -- .../collection/immutable/NumericRange.scala | 409 -- .../scala/collection/immutable/Range.scala | 547 --- .../scala/collection/mutable/Buffer.scala | 176 - .../scala/concurrent/ExecutionContext.scala | 183 - .../scala/reflect/ClassTag.scala | 159 - .../scala/reflect/Manifest.scala | 302 -- .../scala/runtime/ScalaRunTime.scala | 282 -- scripts/publish.sh | 17 +- .../testsuite/library/ArrayOpsTest.scala | 17 +- .../scalajs/testsuite/compiler/IntTest.scala | 3 +- .../testsuite/compiler/RegressionTest.scala | 2 +- 90 files changed, 36 insertions(+), 12422 deletions(-) delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/BlacklistedTests.txt delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/BuglistedTests.txt delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/WhitelistedTests.txt delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t6446-additional.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t6446-list.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t6446-missing.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t6446-show-phases.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t7494-no-options.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-01.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-02.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-04.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-08.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-09.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-10.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Meter.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/MeterCaseClass.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/anyval-box-types.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/bugs.sem delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/caseClassHash.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/deeps.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/dynamic-anyval.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/impconvtimes.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/imports.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/interpolation.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/interpolationMultiline1.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/issue192.sem delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/macro-bundle-static.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/macro-bundle-toplevel.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/macro-bundle-whitebox-decl.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/misc.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/promotion.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/runtime.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/spec-self.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/structural.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t0421-new.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t0421-old.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t1503.sem delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t3702.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t4148.sem delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t4617.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5356.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5552.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5568.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5629b.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5680.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5866.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t6318_primitives.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t6662.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t7657.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t7763.sem delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t8570a.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t8764.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t9387b.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t9656.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/try-catch-unify.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/virtpatmat_switch.check delete mode 100644 partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/virtpatmat_typetag.check delete mode 100644 scalalib/overrides-2.13.0-M3/scala/Array.scala delete mode 100644 scalalib/overrides-2.13.0-M3/scala/Enumeration.scala delete mode 100644 scalalib/overrides-2.13.0-M3/scala/collection/immutable/NumericRange.scala delete mode 100644 scalalib/overrides-2.13.0-M3/scala/collection/immutable/Range.scala delete mode 100644 scalalib/overrides-2.13.0-M3/scala/collection/mutable/ArrayBuilder.scala delete mode 100644 scalalib/overrides-2.13.0-M3/scala/collection/mutable/Buffer.scala delete mode 100644 scalalib/overrides-2.13.0-M3/scala/concurrent/ExecutionContext.scala delete mode 100644 scalalib/overrides-2.13.0-M3/scala/package.scala delete mode 100644 scalalib/overrides-2.13.0-M3/scala/reflect/ClassTag.scala delete mode 100644 scalalib/overrides-2.13.0-M3/scala/reflect/Manifest.scala delete mode 100644 scalalib/overrides-2.13.0-M3/scala/runtime/ScalaRunTime.scala delete mode 100644 scalalib/overrides-2.13.0-M4/scala/Array.scala delete mode 100644 scalalib/overrides-2.13.0-M4/scala/Enumeration.scala delete mode 100644 scalalib/overrides-2.13.0-M4/scala/collection/immutable/NumericRange.scala delete mode 100644 scalalib/overrides-2.13.0-M4/scala/collection/immutable/Range.scala delete mode 100644 scalalib/overrides-2.13.0-M4/scala/collection/mutable/Buffer.scala delete mode 100644 scalalib/overrides-2.13.0-M4/scala/concurrent/ExecutionContext.scala delete mode 100644 scalalib/overrides-2.13.0-M4/scala/reflect/ClassTag.scala delete mode 100644 scalalib/overrides-2.13.0-M4/scala/reflect/Manifest.scala delete mode 100644 scalalib/overrides-2.13.0-M4/scala/runtime/ScalaRunTime.scala diff --git a/Jenkinsfile b/Jenkinsfile index 95aa2023dc..0b90743353 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -431,7 +431,7 @@ def allJavaVersions = otherJavaVersions.clone() allJavaVersions << mainJavaVersion def mainScalaVersion = "2.12.6" -def mainScalaVersions = ["2.10.2", "2.11.12", "2.12.6", "2.13.0-M3"] +def mainScalaVersions = ["2.10.2", "2.11.12", "2.12.6"] def otherScalaVersions = [ "2.10.3", "2.10.4", @@ -455,7 +455,7 @@ def otherScalaVersions = [ "2.12.4", "2.12.5" ] -def limitedCIScalaVersions = ["2.13.0-M4", "2.13.0-M5"] +def noToolsScalaVersions = ["2.13.0-M5"] // The 'quick' matrix def quickMatrix = [] @@ -476,7 +476,7 @@ mainScalaVersions.each { scalaVersion -> quickMatrix.add([task: "partest-fastopt", scala: scalaVersion, java: javaVersion]) } } -limitedCIScalaVersions.each { scalaVersion -> +noToolsScalaVersions.each { scalaVersion -> quickMatrix.add([task: "main", scala: scalaVersion, java: mainJavaVersion]) quickMatrix.add([task: "test-suite-ecma-script5", scala: scalaVersion, java: mainJavaVersion, testSuite: "testSuite"]) quickMatrix.add([task: "test-suite-ecma-script6", scala: scalaVersion, java: mainJavaVersion, testSuite: "testSuite"]) diff --git a/ci/checksizes.sh b/ci/checksizes.sh index 38da8916e9..4bbd263c2e 100755 --- a/ci/checksizes.sh +++ b/ci/checksizes.sh @@ -14,12 +14,6 @@ case $FULLVER in 2.12.6) VER=2.12 ;; - 2.13.0-M3) - VER=2.13.0-M3 - ;; - 2.13.0-M4) - VER=2.13.0-M4 - ;; 2.13.0-M5) VER=2.13.0-M5 ;; @@ -60,18 +54,6 @@ case $FULLVER in REVERSI_PREOPT_GZ_EXPECTEDSIZE=74000 REVERSI_OPT_GZ_EXPECTEDSIZE=32000 ;; - 2.13.0-M3) - REVERSI_PREOPT_EXPECTEDSIZE=630000 - REVERSI_OPT_EXPECTEDSIZE=147000 - REVERSI_PREOPT_GZ_EXPECTEDSIZE=77000 - REVERSI_OPT_GZ_EXPECTEDSIZE=33000 - ;; - 2.13.0-M4) - REVERSI_PREOPT_EXPECTEDSIZE=581000 - REVERSI_OPT_EXPECTEDSIZE=136000 - REVERSI_PREOPT_GZ_EXPECTEDSIZE=78000 - REVERSI_OPT_GZ_EXPECTEDSIZE=34000 - ;; 2.13.0-M5) REVERSI_PREOPT_EXPECTEDSIZE=613000 REVERSI_OPT_EXPECTEDSIZE=143000 diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala b/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala index 65d30dcd47..f8154fc0fd 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/Compat210Component.scala @@ -81,7 +81,7 @@ trait Compat210Component { } } - // Impl classes disappeared in 2.12.0-M4 + // Impl classes disappeared in 2.12 lazy val scalaUsesImplClasses: Boolean = definitions.SeqClass.implClass != NoSymbol // a trait we know has an impl class @@ -98,7 +98,7 @@ trait Compat210Component { def interfaceName(implname: Name): TypeName = noImplClasses() } - // SAMFunction was introduced in 2.12.0-M4 for LMF-capable SAM types + // SAMFunction was introduced in 2.12 for LMF-capable SAM types object SAMFunctionAttachCompatDef { /* Should extend PlainAttachment, but it does not exist in 2.10, and we @@ -135,7 +135,7 @@ trait Compat210Component { * initializeCoreBTypes (it was actually typo'ed as intializeCoreBTypes!) * - In 2.11.6+, including 2.12, we finally have * genBCode.bTypes.initializeCoreBTypes - * - As of 2.12.0-M4, it is mandatory to call that method from GenJSCode.run() + * - As of 2.12, it is mandatory to call that method from GenJSCode.run() */ object LowPrioGenBCodeCompat { diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala index ee760f45e1..614b669760 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala @@ -5579,8 +5579,7 @@ abstract class GenJSCode extends plugins.PluginComponent val v = scala.util.Properties.versionNumberString !v.startsWith("2.10.") && !v.startsWith("2.11.") && - !v.startsWith("2.12.") && - v != "2.13.0-M3" + !v.startsWith("2.12.") } /** Tests whether the given type represents a raw JavaScript type, diff --git a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala index 211ff8663d..a4ab11d81a 100644 --- a/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala +++ b/compiler/src/main/scala/org/scalajs/core/compiler/PrepJSInterop.scala @@ -325,7 +325,7 @@ abstract class PrepJSInterop extends plugins.PluginComponent * * scala.this.Predef.classOf[T] * - * or, as of Scala 2.12.0-M3, as: + * or, as of Scala 2.12.0, as: * * scala.Predef.classOf[T] * diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala index d807e611d7..7b09bec1d8 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/JSExportTest.scala @@ -856,8 +856,7 @@ class JSExportTest extends DirectTest with TestHelpers { val version = scala.util.Properties.versionNumberString if (version.startsWith("2.10.") || version.startsWith("2.11.") || - version.startsWith("2.12.") || - version == "2.13.0-M3") { + version.startsWith("2.12.")) { " " } else { " " diff --git a/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala b/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala index 9f0e554ad2..6b40b70391 100644 --- a/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala +++ b/compiler/src/test/scala/org/scalajs/core/compiler/test/OptimizationTest.scala @@ -286,8 +286,7 @@ object OptimizationTest { version.startsWith("2.10.") || version.startsWith("2.11.") || - version.startsWith("2.12.") || - version == "2.13.0-M3" + version.startsWith("2.12.") } private object WrapArrayCall { diff --git a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala index 355903ebe7..51e5f15386 100644 --- a/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala +++ b/junit-plugin/src/main/scala/org/scalajs/junit/plugin/ScalaJSJUnitPlugin.scala @@ -480,8 +480,7 @@ class ScalaJSJUnitPlugin(val global: Global) extends NscPlugin { val v = scala.util.Properties.versionNumberString !v.startsWith("2.10.") && !v.startsWith("2.11.") && - !v.startsWith("2.12.") && - v != "2.13.0-M3" + !v.startsWith("2.12.") } } } diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/BlacklistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/BlacklistedTests.txt deleted file mode 100644 index 157b42eb1d..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/BlacklistedTests.txt +++ /dev/null @@ -1,1048 +0,0 @@ -# -# POS -# - -# Using Jsoup, what's that? -pos/cycle-jsoup.scala - -# Spuriously fails too often, and causes other subsequent tests to fail too -# Note that this test, by design, stress-tests type checking -pos/t6367.scala - -# Kills our IR serializer, it's an artificially super-deep if/else if -pos/t9181.scala - -# -# NEG -# - -# Screws up, but not really our problem (error: None.get instead of -# phase ordering error) -neg/t7494-multi-right-after -neg/t7494-right-after-before -neg/t7622-multi-followers -neg/t7622-cyclic-dependency - -# Uses some strange macro cross compile mechanism. -neg/macro-incompatible-macro-engine-c.scala - -# Spurious failures -neg/inlineMaxSize.scala -neg/patmatexhaust-huge.scala - -# Uses .java files -run/t9200 -run/noInlineUnknownIndy -# -# RUN -# - -# Relies on the exact toString() representation of Floats/Doubles -run/t2378.scala - -# Uses ClassTags on existentials which are broken in Scala (see #251) -run/valueclasses-classtag-existential.scala - -# Relies on a particular execution speed -run/t5857.scala - -# Using parts of the javalib we don't plan to support - -run/t5018.scala -run/t2417.scala -run/t4813.scala -run/lazy-concurrent.scala -run/t3667.scala -run/t3038d.scala -run/shutdownhooks.scala -run/t5590.scala -run/t3895b.scala -run/t5974.scala -run/t5262.scala -run/serialize-stream.scala -run/sysprops.scala -run/lambda-serialization-gc.scala -run/t9390.scala -run/t9390b.scala -run/t9390c.scala -run/t10527.scala -run/t10650 -run/trait-defaults-super.scala - -run/t2849.scala -run/t1360.scala -run/t3199b.scala -run/t8690.scala - -run/various-flat-classpath-types.scala - -# Uses java.util.Collections -run/t2250.scala - -# Uses java.math.BigDecimal / BigInteger : but failures not due to them -run/hashhash.scala -run/is-valid-num.scala - -# Documented semantic difference on String.split(x: Array[Char]) -run/t0325.scala - -# Using Threads -run/t6969.scala -run/inner-obj-auto.scala -run/predef-cycle.scala -run/synchronized.scala -run/sd409.scala - -# Uses java.security -run/t2318.scala - -# Tries to catch java.lang.StackOverflowError -run/t6154.scala - -# Tries to catch java.lang.OutOfMemoryError -run/t7880.scala - -# Taking too much time, because JavaScript is not as fast as the JVM - -run/collections.scala -run/t3989.scala -run/adding-growing-set.scala -run/t3242.scala -run/hashCodeDistribution.scala -run/t408.scala -run/t6584.scala -run/t6853.scala -run/UnrolledBuffer.scala -run/t6253a.scala -run/t6253b.scala -run/t6253c.scala -run/numbereq.scala -run/t4658.scala - -# Crashes Rhino - -run/bridges.scala -run/patmat-exprs.scala - -# Using partest properties - -run/tailcalls.scala -run/t4294.scala -run/t6331b.scala - -# Using IO - -run/t6488.scala -run/t6988.scala - -# Object{Output|Input}Streams -run/t6935.scala -run/t8188.scala -run/t9375.scala -run/t9365.scala -run/inlineAddDeserializeLambda.scala -run/sammy_seriazable.scala -run/lambda-serialization-security.scala -run/t10232.scala -run/t10233.scala -run/t10244.scala -run/t10522.scala - -# Using System.getProperties - -run/t4426.scala - -# Using Await - -run/t7336.scala -run/t7775.scala -run/t10513.scala -run/future-flatmap-exec-count.scala - -# Using detailed stack trace - -run/t6308.scala - -# Using reflection - -run/t6063 - -run/mixin-bridge-methods.scala -run/t5125.scala -run/outertest.scala -run/t6223.scala -run/t5652b -run/elidable-opt.scala -run/nullable-lazyvals.scala -run/t4794.scala -run/t5652 -run/t5652c -run/getClassTest-old.scala -run/t8960.scala -run/t7965.scala -run/t8087.scala -run/t8931.scala -run/t8445.scala -run/lambda-serialization.scala - -run/reflection-repl-classes.scala -run/t5256e.scala -run/typetags_core.scala -run/reflection-constructormirror-toplevel-badpath.scala -run/t5276_1b.scala -run/reflection-sorted-decls.scala -run/toolbox_typecheck_implicitsdisabled.scala -run/t5418b.scala -run/toolbox_typecheck_macrosdisabled2.scala -run/abstypetags_serialize.scala -run/all-overridden.scala -run/showraw_tree_kinds.scala -run/showraw_tree_types_ids.scala -run/showraw_tree_types_typed.scala -run/showraw_tree_ids.scala -run/showraw_tree_ultimate.scala -run/t5266_2.scala -run/t5274_1.scala -run/t5224.scala -run/reflection-sanitychecks.scala -run/t6086-vanilla.scala -run/t5277_2.scala -run/reflection-methodsymbol-params.scala -run/reflection-valueclasses-standard.scala -run/t5274_2.scala -run/t5423.scala -run/reflection-modulemirror-toplevel-good.scala -run/t5419.scala -run/t5271_3.scala -run/reflection-enclosed-nested-basic.scala -run/reflection-enclosed-nested-nested-basic.scala -run/fail-non-value-types.scala -run/exprs_serialize.scala -run/t5258a.scala -run/typetags_without_scala_reflect_manifest_lookup.scala -run/t4110-new.scala -run/t5273_2b_newpatmat.scala -run/t6277.scala -run/t5335.scala -run/toolbox_typecheck_macrosdisabled.scala -run/reflection-modulemirror-inner-good.scala -run/t5229_2.scala -run/typetags_multi.scala -run/typetags_without_scala_reflect_typetag_manifest_interop.scala -run/reflection-constructormirror-toplevel-good.scala -run/reflection-magicsymbols-invoke.scala -run/t6392b.scala -run/t5229_1.scala -run/reflection-magicsymbols-vanilla.scala -run/t5225_2.scala -run/runtimeEval1.scala -run/reflection-enclosed-nested-inner-basic.scala -run/reflection-fieldmirror-ctorparam.scala -run/t6181.scala -run/reflection-magicsymbols-repl.scala -run/t5272_2_newpatmat.scala -run/t5270.scala -run/t5418a.scala -run/t5276_2b.scala -run/t5256f.scala -run/reflection-enclosed-basic.scala -run/reflection-constructormirror-inner-badpath.scala -run/interop_typetags_are_manifests.scala -run/newTags.scala -run/t5273_1_newpatmat.scala -run/reflection-constructormirror-nested-good.scala -run/t2236-new.scala -run/existentials3-new.scala -run/t6323b.scala -run/t5943a1.scala -run/reflection-fieldmirror-getsetval.scala -run/t5272_1_oldpatmat.scala -run/t5256h.scala -run/t1195-new.scala -run/t5840.scala -run/reflection-methodsymbol-returntype.scala -run/reflection-fieldmirror-accessorsareokay.scala -run/reflection-sorted-members.scala -run/reflection-allmirrors-tostring.scala -run/valueclasses-typetag-existential.scala -run/toolbox_console_reporter.scala -run/reflection-enclosed-inner-inner-basic.scala -run/t5256b.scala -run/bytecodecs.scala -run/elidable.scala -run/freetypes_false_alarm1.scala -run/freetypes_false_alarm2.scala -run/getClassTest-new.scala -run/idempotency-extractors.scala -run/idempotency-case-classes.scala -run/idempotency-this.scala -run/idempotency-labels.scala -run/idempotency-lazy-vals.scala -run/interop_manifests_are_abstypetags.scala -run/interop_manifests_are_typetags.scala -run/abstypetags_core.scala -run/macro-reify-abstypetag-notypeparams -run/macro-reify-abstypetag-typeparams-tags -run/macro-reify-abstypetag-typeparams-notags -run/macro-reify-abstypetag-usetypetag -run/macro-reify-freevars -run/macro-reify-splice-outside-reify -run/macro-reify-tagless-a -run/macro-reify-type -run/macro-reify-typetag-typeparams-tags -run/macro-reify-typetag-notypeparams -run/macro-undetparams-implicitval -run/manifests-new.scala -run/manifests-old.scala -run/no-pickle-skolems -run/position-val-def.scala -run/reflect-priv-ctor.scala -run/primitive-sigs-2-new.scala -run/primitive-sigs-2-old.scala -run/reflection-enclosed-inner-basic.scala -run/reflection-enclosed-inner-nested-basic.scala -run/reflection-constructormirror-inner-good.scala -run/reflection-constructormirror-nested-badpath.scala -run/reflection-fancy-java-classes -run/reflection-fieldsymbol-navigation.scala -run/reflection-fieldmirror-nmelocalsuffixstring.scala -run/reflection-fieldmirror-getsetvar.scala -run/reflection-fieldmirror-privatethis.scala -run/reflection-implicit.scala -run/reflection-mem-glbs.scala -run/reflection-mem-tags.scala -run/reflection-java-annotations -run/reflection-java-crtp -run/reflection-methodsymbol-typeparams.scala -run/reflection-modulemirror-nested-badpath.scala -run/reflection-modulemirror-inner-badpath.scala -run/reflection-modulemirror-nested-good.scala -run/reflection-modulemirror-toplevel-badpath.scala -run/reflection-sync-subtypes.scala -run/reflinit.scala -run/reflection-valueclasses-derived.scala -run/reflection-valueclasses-magic.scala -run/resetattrs-this.scala -run/runtimeEval2.scala -run/showraw_aliases.scala -run/showraw_mods.scala -run/shortClass.scala -run/showraw_nosymbol.scala -run/showraw_tree.scala -run/showraw_tree_types_untyped.scala -run/t1167.scala -run/t2577.scala -run/t2873.scala -run/t2886.scala -run/t2251b.scala -run/t3346j.scala -run/t3507-new.scala -run/t3569.scala -run/t5125b.scala -run/t5225_1.scala -run/t3425b -run/t5256a.scala -run/t5230.scala -run/t5256c.scala -run/t5256g.scala -run/t5266_1.scala -run/t5269.scala -run/t5271_1.scala -run/t5271_2.scala -run/t5271_4.scala -run/t5272_1_newpatmat.scala -run/t5272_2_oldpatmat.scala -run/t5273_1_oldpatmat.scala -run/t5273_2a_newpatmat.scala -run/t5273_2a_oldpatmat.scala -run/t5275.scala -run/t5276_1a.scala -run/t5276_2a.scala -run/t5277_1.scala -run/t5279.scala -run/t5334_1.scala -run/t5334_2.scala -run/t5415.scala -run/t5418.scala -run/t5676.scala -run/t5704.scala -run/t5710-1.scala -run/t5710-2.scala -run/t5770.scala -run/t5894.scala -run/t5816.scala -run/t5824.scala -run/t5912.scala -run/t5942.scala -run/t5943a2.scala -run/t6023.scala -run/t6113.scala -run/t6175.scala -run/t6178.scala -run/t6199-mirror.scala -run/t6199-toolbox.scala -run/t6240-universe-code-gen.scala -run/t6221 -run/t6260b.scala -run/t6259.scala -run/t6287.scala -run/t6344.scala -run/t6392a.scala -run/t6591_1.scala -run/t6591_2.scala -run/t6591_3.scala -run/t6591_5.scala -run/t6591_6.scala -run/t6591_7.scala -run/t6608.scala -run/t6677.scala -run/t6687.scala -run/t6715.scala -run/t6719.scala -run/t6793.scala -run/t6860.scala -run/t6793b.scala -run/t6793c.scala -run/t7045.scala -run/t7046.scala -run/t7008-scala-defined -run/t7120b.scala -run/t7151.scala -run/t7214.scala -run/t7235.scala -run/t7331a.scala -run/t7331b.scala -run/t7331c.scala -run/t7558.scala -run/t7556 -run/t7779.scala -run/t7868b.scala -run/toolbox_current_run_compiles.scala -run/toolbox_default_reporter_is_silent.scala -run/toolbox_parse_package.scala -run/toolbox_silent_reporter.scala -run/toolbox_typecheck_inferimplicitvalue.scala -run/typetags_serialize.scala -run/valueclasses-typetag-basic.scala -run/WeakHashSetTest.scala -run/valueclasses-typetag-generic.scala -run/t4023.scala -run/t4024.scala -run/t6380.scala -run/t5273_2b_oldpatmat.scala -run/t8104 -run/t8047.scala -run/t6992 -run/var-arity-class-symbol.scala -run/typetags_symbolof_x.scala -run/typecheck -run/t8190.scala -run/t8192 -run/t8177f.scala -run/t8199.scala -run/t7932.scala -run/t7700.scala -run/t7570c.scala -run/t7570b.scala -run/t7533.scala -run/t7570a.scala -run/t7044 -run/t7328.scala -run/t6733.scala -run/t6554.scala -run/t6732.scala -run/t6379 -run/t6411b.scala -run/t6411a.scala -run/t6260c.scala -run/t6260-delambdafy.scala -run/showdecl -run/reflection-sync-potpourri.scala -run/reflection-tags.scala -run/reflection-companiontype.scala -run/reflection-scala-annotations.scala -run/reflection-idtc.scala -run/macro-reify-nested-b2 -run/mixin-signatures.scala -run/reflection-companion.scala -run/macro-reify-nested-b1 -run/macro-reify-nested-a2 -run/macro-reify-nested-a1 -run/macro-reify-chained2 -run/macro-reify-chained1 -run/inferred-type-constructors.scala -run/mirror_symbolof_x.scala -run/t8196.scala -run/t8549b.scala -run/t8574.scala -run/t8637.scala -run/t8253.scala -run/t9027.scala -run/t6622.scala -run/toolbox_expand_macro.scala -run/toolbox-varargs -run/t9252.scala -run/t9182.scala -run/t9102.scala -run/t720.scala -run/t9408.scala -run/trait-default-specialize.scala -run/lazy-locals-2.scala -run/t5294.scala -run/trait_fields_final.scala -run/trait_fields_bytecode.scala -run/trait_fields_volatile.scala -run/junitForwarders -run/sip23-toolbox-eval.scala - -run/reify_newimpl_29.scala -run/reify_magicsymbols.scala -run/reify_inheritance.scala -run/reify_newimpl_12.scala -run/reify_typerefs_2b.scala -run/reify_csv.scala -run/reify_inner2.scala -run/reify_maps_oldpatmat.scala -run/reify_newimpl_43.scala -run/reify_nested_inner_refers_to_local.scala -run/reify_closure7.scala -run/reify_closure8b.scala -run/reify_typerefs_3b.scala -run/reify_newimpl_44.scala -run/reify_newimpl_06.scala -run/reify_newimpl_05.scala -run/reify_newimpl_20.scala -run/reify_newimpl_23.scala -run/reify_metalevel_breach_-1_refers_to_1.scala -run/reify_newimpl_41.scala -run/reify-repl-fail-gracefully.scala -run/reify_fors_oldpatmat.scala -run/reify_inner3.scala -run/reify_closure8a.scala -run/reify_closures10.scala -run/reify_ann2a.scala -run/reify_newimpl_51.scala -run/reify_newimpl_47.scala -run/reify_extendbuiltins.scala -run/reify_newimpl_30.scala -run/reify_newimpl_38.scala -run/reify_closure2a.scala -run/reify_newimpl_45.scala -run/reify_closure1.scala -run/reify_generic2.scala -run/reify_printf.scala -run/reify_closure6.scala -run/reify_newimpl_37.scala -run/reify_newimpl_35.scala -run/reify_typerefs_3a.scala -run/reify_newimpl_25.scala -run/reify_ann4.scala -run/reify_typerefs_1b.scala -run/reify_newimpl_22.scala -run/reify_this.scala -run/reify_typerefs_2a.scala -run/reify_newimpl_03.scala -run/reify_newimpl_48.scala -run/reify_varargs.scala -run/reify_newimpl_42.scala -run/reify_newimpl_15.scala -run/reify_nested_inner_refers_to_global.scala -run/reify_newimpl_02.scala -run/reify_newimpl_01.scala -run/reify_fors_newpatmat.scala -run/reify_nested_outer_refers_to_local.scala -run/reify_newimpl_13.scala -run/reify_closure5a.scala -run/reify_inner4.scala -run/reify_sort.scala -run/reify_ann1a.scala -run/reify_closure4a.scala -run/reify_newimpl_33.scala -run/reify_sort1.scala -run/reify_properties.scala -run/reify_generic.scala -run/reify_newimpl_27.scala -run/reify-aliases.scala -run/reify_ann3.scala -run/reify-staticXXX.scala -run/reify_ann1b.scala -run/reify_ann5.scala -run/reify_anonymous.scala -run/reify-each-node-type.scala -run/reify_copypaste2.scala -run/reify_closure3a.scala -run/reify_copypaste1.scala -run/reify_complex.scala -run/reify_for1.scala -run/reify_getter.scala -run/reify_implicits-new.scala -run/reify_inner1.scala -run/reify_implicits-old.scala -run/reify_lazyunit.scala -run/reify_lazyevaluation.scala -run/reify_maps_newpatmat.scala -run/reify_metalevel_breach_+0_refers_to_1.scala -run/reify_metalevel_breach_-1_refers_to_0_a.scala -run/reify_metalevel_breach_-1_refers_to_0_b.scala -run/reify_nested_outer_refers_to_global.scala -run/reify_newimpl_04.scala -run/reify_newimpl_14.scala -run/reify_newimpl_11.scala -run/reify_newimpl_18.scala -run/reify_newimpl_19.scala -run/reify_newimpl_31.scala -run/reify_newimpl_21.scala -run/reify_newimpl_36.scala -run/reify_newimpl_39.scala -run/reify_newimpl_40.scala -run/reify_newimpl_49.scala -run/reify_newimpl_50.scala -run/reify_newimpl_52.scala -run/reify_renamed_term_basic.scala -run/reify_renamed_term_local_to_reifee.scala -run/reify_renamed_term_overloaded_method.scala -run/reify_renamed_type_basic.scala -run/reify_renamed_type_local_to_reifee.scala -run/reify_renamed_type_spliceable.scala -run/reify_typerefs_1a.scala -run/reify_timeofday.scala -run/reify_renamed_term_t5841.scala -run/reify_classfileann_a -run/reify_classfileann_b -run/reify_ann2b.scala - -run/t7521b.scala -run/t8575b.scala -run/t8575c.scala -run/t8944c.scala -run/t9535.scala -run/t9437a -run/t9437b -run/t9814.scala -run/t10009.scala -run/t10075.scala -run/t10075b - -run/t8756.scala -run/inferred-type-constructors-hou.scala -run/trait-static-forwarder -run/SD-235.scala -run/t10026.scala -run/checkinit.scala -run/reflection-clinit -run/reflection-clinit-nested - -# Uses refletction indirectly through -# scala.runtime.ScalaRunTime.replStringOf -run/t6634.scala - -# Using reflection to invoke macros. These tests actually don't require -# or test reflection, but use it to separate compilation units nicely. -# It's a pity we cannot use them - -run/macro-abort-fresh -run/macro-expand-varargs-explicit-over-nonvarargs-bad -run/macro-invalidret-doesnt-conform-to-def-rettype -run/macro-invalidret-nontypeable -run/macro-invalidusage-badret -run/macro-invalidusage-partialapplication -run/macro-invalidusage-partialapplication-with-tparams -run/macro-reflective-ma-normal-mdmi -run/macro-reflective-mamd-normal-mi - -# Using macros, but indirectly creating calls to reflection -run/macro-reify-unreify - -# Using Enumeration in a way we cannot fix - -run/enums.scala -run/t3719.scala -run/t8611b.scala - -# Exceptions that become JavaScriptException - -run/pf-catch.scala -run/exceptions-2.scala -run/exceptions-nest.scala -run/t8601c.scala -run/t8601b.scala -run/inlineHandlers.scala - -# Expecting unsupported exceptions (e.g. ArrayIndexOutOfBounds) -run/optimizer-array-load.scala -run/t6827.scala -run/t8601.scala - -# Expecting exceptions that are linking errors in Scala.js (e.g. NoSuchMethodException) -run/t10334.scala - -# Playing with classfile format - -run/classfile-format-51.scala -run/classfile-format-52.scala - -# Concurrent collections (TrieMap) -# has too much stuff implemented in *.java, so no support -run/triemap-hash.scala - -# Using parallel collections - -run/concurrent-map-conversions.scala -run/map_java_conversions.scala - -# Using scala.xml - -run/t4124.scala - -# Using Swing - -run/t3613.scala - -# Using the REPL - -run/t4285.scala -run/constant-type.scala -run/repl-bare-expr.scala -run/repl-parens.scala -run/repl-assign.scala -run/t5583.scala -run/treePrint.scala -run/constrained-types.scala -run/repl-power.scala -run/t4710.scala -run/repl-paste.scala -run/repl-reset.scala -run/repl-paste-3.scala -run/t6329_repl.scala -run/t6273.scala -run/repl-paste-2.scala -run/t5655.scala -run/t5072.scala -run/repl-colon-type.scala -run/repl-trim-stack-trace.scala -run/t4594-repl-settings.scala -run/repl-save.scala -run/repl-paste-raw.scala -run/repl-paste-4.scala -run/t7801.scala -run/repl-backticks.scala -run/t6633.scala -run/repl-inline.scala - -# Using the Repl (scala.tools.partest.ReplTest) -run/class-symbol-contravariant.scala -run/lub-visibility.scala -run/macro-bundle-repl.scala -run/macro-repl-basic.scala -run/macro-repl-dontexpand.scala -run/macro-system-properties.scala -run/reflection-equality.scala -run/reflection-repl-elementary.scala -run/reify_newimpl_26.scala -run/repl-out-dir.scala -run/repl-term-macros.scala -run/repl-transcript.scala -run/repl-type-verbose.scala -run/t3376.scala -run/t4025.scala -run/t4172.scala -run/t4216.scala -run/t4542.scala -run/t4671.scala -run/t5256d.scala -run/t5535.scala -run/t5537.scala -run/t5789.scala -run/t6086-repl.scala -run/t6146b.scala -run/t6187.scala -run/t6320.scala -run/t6381.scala -run/t6434.scala -run/t6439.scala -run/t6507.scala -run/t6549.scala -run/t6937.scala -run/t7185.scala -run/t7319.scala -run/t7482a.scala -run/t7634.scala -run/t7747-repl.scala -run/t7805-repl-i.scala -run/tpeCache-tyconCache.scala -run/repl-empty-package -run/repl-javap-def.scala -run/repl-javap-mem.scala -run/repl-javap-outdir -run/repl-javap.scala -run/t6329_repl_bug.scala -run/t4950.scala -run/xMigration.scala -run/t6541-option.scala -run/repl-serialization.scala -run/t9174.scala -run/repl-paste-5.scala -run/repl-no-uescape.scala -run/repl-no-imports-no-predef-classbased.scala -run/repl-implicits-nopredef.scala -run/repl-classbased.scala -run/repl-no-imports-no-predef-power.scala -run/repl-paste-b.scala -run/repl-paste-6.scala -run/repl-implicits.scala -run/repl-no-imports-no-predef.scala -run/repl-paste-raw-b.scala -run/repl-paste-raw-c.scala -run/t9749-repl-dot.scala -run/trait_fields_repl.scala -run/t7139 -run/t9689 -run/trailing-commas.scala -run/t4700.scala -run/t9880-9881.scala -run/repl-kind.scala -run/t10284.scala -run/t9016.scala - -# Using Scala Script (partest.ScriptTest) - -run/t7711-script-args.scala -run/t4625.scala -run/t4625c.scala -run/t4625b.scala - -# Using the compiler API - -run/t2512.scala -run/analyzerPlugins.scala -run/compiler-asSeenFrom.scala -run/t5603.scala -run/t6440.scala -run/t5545.scala -run/existentials-in-compiler.scala -run/global-showdef.scala -run/stream_length.scala -run/annotatedRetyping.scala -run/imain.scala -run/existential-rangepos.scala -run/delambdafy_uncurry_byname_inline.scala -run/delambdafy_uncurry_byname_method.scala -run/delambdafy_uncurry_inline.scala -run/delambdafy_t6555.scala -run/delambdafy_uncurry_method.scala -run/delambdafy_t6028.scala -run/memberpos.scala -run/programmatic-main.scala -run/reflection-names.scala -run/settings-parse.scala -run/sm-interpolator.scala -run/t1501.scala -run/t1500.scala -run/sammy_java8.scala -run/t1618.scala -run/t2464 -run/t4072.scala -run/t5064.scala -run/t5385.scala -run/t5699.scala -run/t5717.scala -run/t5940.scala -run/t6028.scala -run/t6194.scala -run/t6669.scala -run/t6745-2.scala -run/t7096.scala -run/t7271.scala -run/t7337.scala -run/t7398.scala -run/t7569.scala -run/t7852.scala -run/t7817-tree-gen.scala -run/t7825.scala - -# partest.ParserTest -run/t3368.scala -run/t3368-b.scala -run/t3368-c.scala -run/t3368-d.scala -run/t9944.scala - -# partest.DirectTest -run/t6288.scala -run/t6331.scala -run/t6440b.scala -run/t6555.scala -run/t7876.scala -run/typetags_without_scala_reflect_typetag_lookup.scala -run/dynamic-updateDynamic.scala -run/dynamic-selectDynamic.scala -run/dynamic-applyDynamic.scala -run/dynamic-applyDynamicNamed.scala -run/t4841-isolate-plugins -run/large_code.scala -run/macroPlugins-namerHooks.scala -run/t4841-no-plugin.scala -run/t4332.scala -run/t8029.scala -run/t8046 -run/t5905-features.scala -run/t5905b-features.scala -run/large_class.scala -run/t8708_b -run/icode-reader-dead-code.scala -run/t5938.scala -run/t8502.scala -run/t6502.scala -run/t8907.scala -run/t9097.scala -run/macroPlugins-enterStats.scala -run/sbt-icode-interface.scala -run/t8502b.scala -run/repl-paste-parse.scala -run/t5463.scala -run/t8433.scala -run/sd275.scala -run/sd275-java -run/t10471.scala -run/t6130.scala - -# Using partest.StoreReporterDirectTest -run/t10171 - -# partest.StubErrorMessageTest -run/StubErrorBInheritsFromA.scala -run/StubErrorComplexInnerClass.scala -run/StubErrorHK.scala -run/StubErrorReturnTypeFunction.scala -run/StubErrorReturnTypeFunction2.scala -run/StubErrorReturnTypePolyFunction.scala -run/StubErrorSubclasses.scala -run/StubErrorTypeclass.scala -run/StubErrorTypeDef.scala - -# partest.CompilerTest -run/t8852a.scala - -# partest.ASMConverters -run/t9403 - -# partest.BytecodeTest -run/t7106 -run/t7974 -run/t8601-closure-elim.scala -run/t4788 -run/t4788-separate-compilation - -# partest.SessionTest -run/t8843-repl-xlat.scala -run/t9206.scala -run/t9170.scala -run/t8918-unary-ids.scala -run/t1931.scala -run/t8935-class.scala -run/t8935-object.scala - -# partest.JavapTest -run/t8608-no-format.scala - -# Using .java source files - -run/t4317 -run/t4238 -run/t2296c -run/t4119 -run/t4283 -run/t4891 -run/t6168 -run/t6168b -run/t6240a -run/t6240b -run/t6548 -run/t6989 -run/t7008 -run/t7246 -run/t7246b -run/t7359 -run/t7439 -run/t7455 -run/t7510 -run/t7582-private-within -run/t7582 -run/t7582b -run/t3897 -run/t7374 -run/t3452e -run/t3452g -run/t3452d -run/t3452b -run/t3452a -run/t8442 -run/t8601e -run/t9298 -run/t9298b -run/t9359 -run/t7741a -run/t7741b -run/bcodeInlinerMixed -run/t9268 -run/t9489 -run/t9915 -run/t10059 -run/t1459 -run/t1459generic -run/t3236 -run/t9013 -run/t10231 -run/t10067 -run/t10249 -run/sd143 -run/t4283b -run/t7936 -run/t7936b -run/t9937 -run/t10368 -run/t10334b -run/sd304 -run/t10450 -run/t10042 -run/t8348 - -# Using scala-script -run/t7791-script-linenums.scala - -# Suffers from bug in Node.js (https://github.com/joyent/node/issues/7528) -run/range-unit.scala - -# Using scalap -run/scalapInvokedynamic.scala - -# Using Manifests (which use Class.getInterfaces) -run/valueclasses-manifest-existential.scala -run/existentials3-old.scala -run/t2236-old.scala -run/interop_manifests_are_classtags.scala -run/valueclasses-manifest-generic.scala -run/valueclasses-manifest-basic.scala -run/t1195-old.scala -run/t3758-old.scala -run/t4110-old.scala -run/t6246.scala - -# Using ScalaRunTime.stringOf -run/value-class-extractor-seq.scala -run/t3493.scala - -# Custom invoke dynamic node -run/indy-via-macro -run/indy-via-macro-with-dynamic-args - -# Test the class name of LMF-generated lambdas -run/t7187.scala - -# Crashes our optimizer because of artificially insane amount of inlining -run/t10594.scala - -### Incorrect partests ### -# Badly uses constract of Console.print (no flush) -run/t429.scala -run/t6102.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/BuglistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/BuglistedTests.txt deleted file mode 100644 index 273cb2c2d4..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/BuglistedTests.txt +++ /dev/null @@ -1,7 +0,0 @@ -# The tests in this file should pass but have never passed so far -# use scala.tools.partest.scalajs.testunknownonly to only run tests -# which are neither in BuglistedTests.txt, WhitelistedTests.txt or -# BlacklistedTests.txt - -# Broken by GCC, filed as #2815 -run/Predef.readLine.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/WhitelistedTests.txt b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/WhitelistedTests.txt deleted file mode 100644 index 4798d4d61b..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/WhitelistedTests.txt +++ /dev/null @@ -1,3481 +0,0 @@ -pos/spec-super.scala -pos/t1035.scala -pos/t5897.scala -pos/irrefutable.scala -pos/spec-partialmap.scala -pos/tcpoly_seq.scala -pos/partialfun.scala -pos/t2795-new.scala -pos/clsrefine.scala -pos/t0774 -pos/t1070.scala -pos/t5957 -pos/looping-jsig.scala -pos/t3274.scala -pos/spec-fields-old.scala -pos/t262.scala -pos/t7486.scala -pos/t2261.scala -pos/t6600.scala -pos/t4786.scala -pos/t5406.scala -pos/tcpoly_late_method_params.scala -pos/t2726 -pos/pos-bug1210.scala -pos/t3312.scala -pos/manifest1-old.scala -pos/gadt-gilles.scala -pos/t4842.scala -pos/ted.scala -pos/NoCyclicReference.scala -pos/t3568.scala -pos/t0030.scala -pos/t2635.scala -pos/t7232b -pos/t0017.scala -pos/t812.scala -pos/t2179.scala -pos/t651.scala -pos/spurious-overload.scala -pos/t758.scala -pos/t4760.scala -pos/t1672.scala -pos/mixins.scala -pos/patterns.scala -pos/t1260.scala -pos/t6551.scala -pos/t2060.scala -pos/t6575a.scala -pos/t1318.scala -pos/t4266.scala -pos/t0695 -pos/protected-static -pos/t5738.scala -pos/t1226.scala -pos/t5013 -pos/t6215.scala -pos/t5692b -pos/traits.scala -pos/t2994a.scala -pos/t3371.scala -pos/t613.scala -pos/t6499.scala -pos/xlint1.scala -pos/t1150 -pos/test4a.scala -pos/t2664.scala -pos/t3528.scala -pos/t3174.scala -pos/t6994.scala -pos/t4812.scala -pos/t5777.scala -pos/t5223.scala -pos/t439.scala -pos/t3079.scala -pos/t5829.scala -pos/t0036.scala -pos/scoping2.scala -pos/t4717.scala -pos/t4257.scala -pos/t1210a.scala -pos/getClassType.scala -pos/t5330.scala -pos/t4524.scala -pos/t2945.scala -pos/t6562.scala -pos/t0273.scala -pos/override-object-yes.scala -pos/t7426.scala -pos/t6601 -pos/t3076 -pos/seq-ordering.scala -pos/spec-groups.scala -pos/t296.scala -pos/t5545 -pos/spec-multiplectors.scala -pos/t1789.scala -pos/t2569 -pos/ksbug1.scala -pos/t0599.scala -pos/local-objects.scala -pos/t0081.scala -pos/t5756.scala -pos/t7126.scala -pos/t7716.scala -pos/t2797.scala -pos/t5399.scala -pos/t1101 -pos/t767.scala -pos/contrib467.scala -pos/t7532b -pos/self-type-override.scala -pos/t4853.scala -pos/t839.scala -pos/t5644 -pos/t5853.scala -pos/t5178.scala -pos/unapplyNeedsMemberType.scala -pos/t5390.scala -pos/t6575b.scala -pos/t151.scala -pos/t2665.scala -pos/t5120.scala -pos/erasure-nsquared.scala -pos/arrays3.scala -pos/t3136.scala -pos/inline-access-levels -pos/t3972.scala -pos/t2591.scala -pos/t3486 -pos/variances-flip.scala -pos/annotated-original -pos/typesafecons.scala -pos/stable.scala -pos/t1996.scala -pos/t3037.scala -pos/t1711 -pos/t3374.scala -pos/t0029.scala -pos/t3278.scala -pos/matthias3.scala -pos/t5546.scala -pos/t4020.scala -pos/matthias4.scala -pos/value-class-override-spec.scala -pos/arrays2.scala -pos/t5119.scala -pos/t2613.scala -pos/t4070b.scala -pos/virtpatmat_exist_uncurry.scala -pos/modules1.scala -pos/spec-constr-new.scala -pos/t6335.scala -pos/t675.scala -pos/t0644.scala -pos/t5892.scala -pos/t360.scala -pos/override.scala -pos/t1798.scala -pos/strip-tvars-for-lubbasetypes.scala -pos/hk-infer.scala -pos/t2119.scala -pos/t0231.scala -pos/t1459 -pos/t1381-new.scala -pos/t2610.scala -pos/t2708.scala -pos/t5604b -pos/t3951 -pos/t361.scala -pos/t319.scala -pos/largecasetest.scala -pos/switchUnbox.scala -pos/typetags.scala -pos/java-access-pos -pos/t803.scala -pos/t3898.scala -pos/t5692a -pos/t2421.scala -pos/t1102 -pos/t0654.scala -pos/exhaust_alternatives.scala -pos/t807.scala -pos/t5702-pos-infix-star.scala -pos/t1186 -pos/t1439.scala -pos/t7427.scala -pos/virtpatmat_binding_opt.scala -pos/t247.scala -pos/abstract.scala -pos/gen-traversable-methods.scala -pos/t2795-old.scala -pos/t5639 -pos/t2667.scala -pos/t2405.scala -pos/t1438.scala -pos/t1659.scala -pos/unchecked-a.scala -pos/t3636.scala -pos/t6745.scala -pos/t2809.scala -pos/t7022.scala -pos/t6447.scala -pos/t5846.scala -pos/lubs.scala -pos/t1987a.scala -pos/spec-arrays.scala -pos/virtpatmat_anonfun_for.scala -pos/listpattern.scala -pos/t5742.scala -pos/test5refine.scala -pos/return_thistype.scala -pos/t348plus.scala -pos/t3420.scala -pos/t3440.scala -pos/maxim1.scala -pos/caseClassInMethod.scala -pos/t3833.scala -pos/t6675.scala -pos/t4402 -pos/t5953.scala -pos/t1152 -pos/t0591.scala -pos/t210.scala -pos/t7035.scala -pos/t5769.scala -pos/pmbug.scala -pos/t2331.scala -pos/t5240.scala -pos/t304.scala -pos/annotated-treecopy -pos/t2081.scala -pos/t0904.scala -pos/t7649.scala -pos/t3498-new.scala -pos/contrib701.scala -pos/t6624.scala -pos/t3924.scala -pos/t374.scala -pos/t1642 -pos/t1591_pos.scala -pos/depmet_implicit_oopsla_session_2.scala -pos/t5899.scala -pos/thistype.scala -pos/t4176b.scala -pos/elidable-tparams.scala -pos/lambdalift.scala -pos/nothing_manifest_disambig-old.scala -pos/t372.scala -pos/t5399a.scala -pos/t2782.scala -pos/patmat-extract-tparam.scala -pos/t4114.scala -pos/unapplyVal.scala -pos/t2486.scala -pos/t5877b.scala -pos/t0625.scala -pos/t6358_2.scala -pos/viewtest1.scala -pos/t1237.scala -pos/scala-singleton.scala -pos/t1254 -pos/t5504 -pos/bounds.scala -pos/t3631.scala -pos/t3177.scala -pos/unapplyContexts2.scala -pos/t0438.scala -pos/t1642b.scala -pos/inferbroadtype.scala -pos/t1858.scala -pos/t3731.scala -pos/t6963c.scala -pos/classtag-pos.scala -pos/t6221.scala -pos/t3343.scala -pos/spec-asseenfrom.scala -pos/t604.scala -pos/spec-example1.scala -pos/t0786.scala -pos/annot-inner.scala -pos/t5886.scala -pos/t1056.scala -pos/t294 -pos/spec-Function1.scala -pos/t1836 -pos/spec-private.scala -pos/depmet_implicit_tpbetareduce.scala -pos/exhaust_2.scala -pos/t7532 -pos/t5175.scala -pos/t802.scala -pos/t5809.scala -pos/tcpoly_typesub.scala -pos/t6029.scala -pos/contextbounds-implicits-new.scala -pos/t3480.scala -pos/patterns3.scala -pos/caseaccs.scala -pos/spec-sparsearray-old.scala -pos/patterns1213.scala -pos/spec-traits.scala -pos/t0020.scala -pos/cycle -pos/t5968.scala -pos/typealiases.scala -pos/init.scala -pos/t697.scala -pos/t2693.scala -pos/t2377 -pos/unapplyGeneric.scala -pos/t1385.scala -pos/t3363-old.scala -pos/t1236.scala -pos/t0068.scala -pos/t4052.scala -pos/lambdalift1.scala -pos/z1730.scala -pos/variances-local.scala -pos/virtpatmat_gadt_array.scala -pos/t2421_delitedsl.scala -pos/t5626.scala -pos/t690.scala -pos/t711.scala -pos/t1937 -pos/t3999 -pos/t2305.scala -pos/t2168.scala -pos/t2660.scala -pos/t1693.scala -pos/t2799.scala -pos/t6966.scala -pos/t1001.scala -pos/S5.scala -pos/t0301.scala -pos/t1048.scala -pos/t415.scala -pos/t6386.scala -pos/t2187.scala -pos/hashhash-overloads.scala -pos/t6921.scala -pos/t0227.scala -pos/t6556.scala -pos/t3946 -pos/t1053.scala -pos/t1000.scala -pos/t0586.scala -pos/t7011.scala -pos/t7329.scala -pos/t4975.scala -pos/t1131.scala -pos/t1027.scala -pos/t2913.scala -pos/t3494.scala -pos/t5606.scala -pos/t4716.scala -pos/tcpoly_gm.scala -pos/t4859.scala -pos/t514.scala -pos/lexical.scala -pos/t2624.scala -pos/t4036.scala -pos/t2741 -pos/t703.scala -pos/five-dot-f.scala -pos/t805.scala -pos/strings.scala -pos/t2433 -pos/t6925.scala -pos/t1085.scala -pos/t7461 -pos/t1942 -pos/spec-lists.scala -pos/t3349 -pos/tcpoly_infer_ticket474.scala -pos/t1614 -pos/virtpatmat_reach_const.scala -pos/t2194.scala -pos/t6976 -pos/t1560.scala -pos/t6891.scala -pos/t3883.scala -pos/infersingle.scala -pos/gui.scala -pos/t1164.scala -pos/t3175-pos.scala -pos/t4336.scala -pos/annotations2.scala -pos/proj-rec-test.scala -pos/t2973.scala -pos/t1123.scala -pos/t6205.scala -pos/t5727.scala -pos/t6537.scala -pos/t6712.scala -pos/t3866.scala -pos/t4831.scala -pos/selftails.scala -pos/t397.scala -pos/spec-vector.scala -pos/t7233b.scala -pos/t1391.scala -pos/spec.scala -pos/t3106.scala -pos/contextbounds-implicits-old.scala -pos/packageobjs.scala -pos/michel3.scala -pos/t628.scala -pos/collections.scala -pos/tcpoly_boundedmonad.scala -pos/t7668.scala -pos/t0032.scala -pos/t0069.scala -pos/t4345.scala -pos/t3521 -pos/t3071.scala -pos/tcpoly_infer_easy.scala -pos/t289.scala -pos/t4365 -pos/rangepos-anonapply.scala -pos/t5033.scala -pos/lambda.scala -pos/S8.scala -pos/t6014.scala -pos/t1785.scala -pos/t6034.scala -pos/t7433.scala -pos/imp2-pos.scala -pos/t0504.scala -pos/t1272.scala -pos/t0612 -pos/value-class-override-no-spec.scala -pos/overloaded-unapply.scala -pos/t5859.scala -pos/chang -pos/localmodules.scala -pos/t4237.scala -pos/rangepos-patmat.scala -pos/t1974.scala -pos/t0054.scala -pos/michel2.scala -pos/t0770.scala -pos/t1146.scala -pos/t2441pos.scala -pos/t5099.scala -pos/tcpoly_seq_typealias.scala -pos/t946.scala -pos/tcpoly_infer_ticket1864.scala -pos/t4737 -pos/t7377b.scala -pos/t616.scala -pos/t201.scala -pos/t6355pos.scala -pos/escapes2.scala -pos/t1675.scala -pos/t3890.scala -pos/t6040.scala -pos/spec-tailcall.scala -pos/existentials.scala -pos/t5317.scala -pos/t7782b.scala -pos/t4758.scala -pos/t7296.scala -pos/t6896.scala -pos/cls1.scala -pos/t402.scala -pos/gosh.scala -pos/t2619.scala -pos/javaConversions-2.10-regression.scala -pos/t759.scala -pos/t5259.scala -pos/t5130.scala -pos/t5156.scala -pos/t0905.scala -pos/package-implicit -pos/t2669.scala -pos/trait-parents.scala -pos/virtpatmat_exhaust.scala -pos/patterns1.scala -pos/t1231 -pos/t1751 -pos/t7233.scala -pos/t6022.scala -pos/tcpoly_checkkinds_mix.scala -pos/depmet_implicit_norm_ret.scala -pos/package-case.scala -pos/philippe4.scala -pos/michel6.scala -pos/t4188.scala -pos/t3936 -pos/t1280.scala -pos/t6722.scala -pos/t796.scala -pos/t5542.scala -pos/t3927.scala -pos/t2293.scala -pos/t3800.scala -pos/t7285a.scala -pos/t927.scala -pos/t4494.scala -pos/t3864 -pos/ilya2 -pos/t2940 -pos/S1.scala -pos/tcpoly_wildcards.scala -pos/tryexpr.scala -pos/t6089b.scala -pos/depmet_implicit_oopsla_zipwith.scala -pos/t245.scala -pos/t6146.scala -pos/t1782 -pos/t851.scala -pos/spec-thistype.scala -pos/tcpoly_poly.scala -pos/t6815_import.scala -pos/t4649.scala -pos/t0453.scala -pos/t5020.scala -pos/ilya -pos/t2435.scala -pos/t1279a.scala -pos/t1957.scala -pos/gadts2.scala -pos/t3567 -pos/Z.scala -pos/t1203b -pos/nested2.scala -pos/t1896 -pos/viewtest2.scala -pos/t5541.scala -pos/existentials-harmful.scala -pos/t4063.scala -pos/t6485a -pos/t1208.scala -pos/t5041.scala -pos/unapplyComplex.scala -pos/t3384.scala -pos/t4112.scala -pos/t788.scala -pos/hklub0.scala -pos/t757.scala -pos/t1197 -pos/t359.scala -pos/t5667.scala -pos/t1107a.scala -pos/virtpatmat_castbinder.scala -pos/t267.scala -pos/t3419 -pos/t3861.scala -pos/t6797.scala -pos/spec-localdefs.scala -pos/t3404 -pos/t4457_1.scala -pos/matthias5.scala -pos/spec-polymeth.scala -pos/kinds.scala -pos/t2310.scala -pos/t6552.scala -pos/valdefs.scala -pos/hkarray.scala -pos/homonym.scala -pos/t1235 -pos/t3429 -pos/t0053.scala -pos/depmet_implicit_chaining_zw.scala -pos/virtpatmat_partialfun_nsdnho.scala -pos/t6664.scala -pos/ticket2251.scala -pos/t3495.scala -pos/super -pos/t121.scala -pos/javaConversions-2.10-ambiguity.scala -pos/t1803.scala -pos/t5877.scala -pos/t0085.scala -pos/t3582.scala -pos/t2939.scala -pos/t1422_pos.scala -pos/manifest1-new.scala -pos/t7505.scala -pos/t5720-ownerous.scala -pos/misc-unapply_pos.scala -pos/tcpoly_variance_pos.scala -pos/t5127.scala -pos/t6123-explaintypes-implicits.scala -pos/t2764 -pos/presuperContext.scala -pos/spec-simple.scala -pos/t3120 -pos/tcpoly_infer_ticket716.scala -pos/tcpoly_bounds1.scala -pos/t7369.scala -pos/imports-pos.scala -pos/t5654.scala -pos/t0123.scala -pos/raw-map -pos/t5330b.scala -pos/t6485b -pos/t6072.scala -pos/t5692c.scala -pos/tcpoly_param_scoping.scala -pos/t6204-b.scala -pos/attachments-typed-another-ident -pos/t5359.scala -pos/ticket2197.scala -pos/t720.scala -pos/t2130-2.scala -pos/t2260.scala -pos/t0304.scala -pos/t464.scala -pos/spec-maps.scala -pos/annotDepMethType.scala -pos/t6117.scala -pos/t911.scala -pos/t757a.scala -pos/t2504.scala -pos/t1381-old.scala -pos/t1232 -pos/needstypeearly.scala -pos/moduletrans.scala -pos/t4957.scala -pos/kinzer.scala -pos/t318.scala -pos/widen-existential.scala -pos/t0095.scala -pos/t566.scala -pos/tcpoly_overloaded.scala -pos/t7516 -pos/t7232 -pos/t698.scala -pos/t0002.scala -pos/t0288 -pos/t2994b.scala -pos/cls.scala -pos/t3622 -pos/t3671.scala -pos/tcpoly_subst.scala -pos/t5703 -pos/depmet_implicit_oopsla_session_simpler.scala -pos/t5022.scala -pos/builders.scala -pos/spec-foo.scala -pos/t756.scala -pos/t1569.scala -pos/implicit-unwrap-tc.scala -pos/t3688.scala -pos/t5198.scala -pos/t432.scala -pos/t6022b.scala -pos/channels.scala -pos/t1075.scala -pos/null.scala -pos/t1840 -pos/t6479.scala -pos/t6311.scala -pos/t0039.scala -pos/t1119.scala -pos/t573.scala -pos/t1136.scala -pos/t3938 -pos/spec-sealed.scala -pos/tcpoly_return_overriding.scala -pos/t3582b.scala -pos/t229.scala -pos/t3498-old.scala -pos/t531.scala -pos/t4545.scala -pos/t6651.scala -pos/t2133.scala -pos/tinondefcons.scala -pos/t6358.scala -pos/t7690.scala -pos/t5779-numeq-warn.scala -pos/list-extractor.scala -pos/t892.scala -pos/t2127.scala -pos/t7180.scala -pos/nullary_poly.scala -pos/virtpatmat_exist3.scala -pos/t1176 -pos/spec-funs.scala -pos/specialize10.scala -pos/t6514.scala -pos/exhaustive_heuristics.scala -pos/t0066.scala -pos/t460.scala -pos/t2130-1.scala -pos/t124.scala -pos/annotations.scala -pos/pat_gilles.scala -pos/array-interfaces.scala -pos/t6210.scala -pos/t3792.scala -pos/implicits-old.scala -pos/t389.scala -pos/t115.scala -pos/virtpatmat_exhaust_unchecked.scala -pos/scoping3.scala -pos/t6033.scala -pos/depmet_implicit_oopsla_session.scala -pos/t602.scala -pos/test5.scala -pos/t611.scala -pos/t5932.scala -pos/t4910.scala -pos/unapplySeq.scala -pos/t344.scala -pos/t3363-new.scala -pos/t4018.scala -pos/t4553.scala -pos/t5082.scala -pos/t3869.scala -pos/t3836.scala -pos/tcpoly_typeapp.scala -pos/t1409 -pos/nonlocal-unchecked.scala -pos/t0082.scala -pos/z1720.scala -pos/t7232c -pos/t2018.scala -pos/t3943 -pos/t2187-2.scala -pos/unicode-decode.scala -pos/t4757 -pos/t0710.scala -pos/t0305.scala -pos/t160.scala -pos/t7591 -pos/simplelists.scala -pos/List1.scala -pos/t516.scala -pos/t6648.scala -pos/t5165 -pos/t0055.scala -pos/t4744 -pos/t7377 -pos/t5726.scala -pos/t0091.scala -pos/t6595.scala -pos/compile.scala -pos/depmet_1_pos.scala -pos/t7364 -pos/philippe3.scala -pos/spec-doubledef-old.scala -pos/t4651.scala -pos/tcpoly_infer_implicit_tuple_wrapper.scala -pos/t6274.scala -pos/tcpoly_infer_explicit_tuple_wrapper.scala -pos/ticket2201.scala -pos/spec-fields-new.scala -pos/optmatch.scala -pos/t7517.scala -pos/t3560.scala -pos/t0165.scala -pos/t0872.scala -pos/t522.scala -pos/t2234.scala -pos/t5031_2.scala -pos/tcpoly_method.scala -pos/t6482.scala -pos/pos-bug1241.scala -pos/implicits-new.scala -pos/t2484.scala -pos/t2425.scala -pos/t1049.scala -pos/michel4.scala -pos/t5958.scala -pos/virtpatmat_instof_valuetype.scala -pos/spec-t6286.scala -pos/t873.scala -pos/t3137.scala -pos/Transactions.scala -pos/t0064.scala -pos/t7486-named.scala -pos/t5444.scala -pos/simple-exceptions.scala -pos/t1006.scala -pos/t7200b.scala -pos/t3777.scala -pos/t4840.scala -pos/t211.scala -pos/nullary.scala -pos/michel1.scala -pos/t5031_3 -pos/typealias_dubious.scala -pos/spec-doubledef-new.scala -pos/philippe1.scala -pos/thistypes.scala -pos/t3570.scala -pos/t6516.scala -pos/context.scala -pos/t3808.scala -pos/philippe2.scala -pos/constfold.scala -pos/t1292.scala -pos/t1147.scala -pos/t404.scala -pos/t4430.scala -pos/A.scala -pos/spec-partially.scala -pos/t5796.scala -pos/t2409 -pos/t284-pos.scala -pos/t5313.scala -pos/t2464 -pos/t1591b.scala -pos/hk-match -pos/t595.scala -pos/t6846.scala -pos/t6162-inheritance.scala -pos/relax_implicit_divergence.scala -pos/patterns2.scala -pos/t4692.scala -pos/t3837.scala -pos/t661.scala -pos/t2810.scala -pos/depexists.scala -pos/virtpatmat_exist4.scala -pos/t5245.scala -pos/t7190.scala -pos/isApplicableSafe.scala -pos/t6204-a.scala -pos/t0076.scala -pos/t1756.scala -pos/t1745 -pos/t6091.scala -pos/t0154.scala -pos/t530.scala -pos/t2094.scala -pos/t1034.scala -pos/t6084.scala -pos/t2454.scala -pos/t2956 -pos/tcpoly_ticket2096.scala -pos/attachments-typed-ident -pos/polymorphic-case-class.scala -pos/t252.scala -pos/spec-constr-old.scala -pos/t2421c.scala -pos/t122.scala -pos/t6574.scala -pos/t3859.scala -pos/spec-params-old.scala -pos/t1196 -pos/t4593.scala -pos/t596.scala -pos/t615.scala -pos/t7689.scala -pos/t3960.scala -pos/t3986.scala -pos/exbound.scala -pos/t2545.scala -pos/t1722 -pos/t159.scala -pos/t3272.scala -pos/t6301.scala -pos/t2794.scala -pos/t3048.scala -pos/t4970.scala -pos/t607.scala -pos/FPTest.scala -pos/test1.scala -pos/t4176.scala -pos/t112606A.scala -pos/t2183.scala -pos/t430-feb09.scala -pos/t6275.scala -pos/t1832.scala -pos/t8965.scala -pos/t7596b -pos/t8900.scala -pos/t9008.scala -pos/t7704.scala -pos/t7459c.scala -pos/sammy_override.scala -pos/t8828.scala -pos/t8868c -pos/t7459d.scala -pos/t8267.scala -pos/t8844.scala -pos/t8868a -pos/t8894.scala -pos/t7459a.scala -pos/t7596c -pos/t8498.scala -pos/t8868b -pos/t5413.scala -pos/t8781 -pos/t8934a -pos/t8310.scala -pos/t3439.scala -pos/t6582_exhaust_big.scala -pos/t8954 -pos/t5217.scala -pos/t7459b.scala -pos/t9018.scala -pos/sammy_exist.scala -pos/t8893.scala -pos/t7596 -pos/t8793.scala -pos/sammy_overload.scala -pos/t6051.scala -pos/t7683-stop-after-parser -pos/t7750.scala -pos/t5454.scala -pos/t8962.scala -pos/t8947 -pos/t8719 -pos/t8410.scala -pos/patmat-suppress.scala -pos/t8999.scala -pos/t8743.scala -pos/t9157.scala -pos/t8801.scala -pos/t9086.scala -pos/t9050.scala -pos/t9135.scala -pos/t9116.scala -pos/t5154.scala -pos/t3368.scala -pos/t9321.scala -pos/t9285.scala -pos/t8861.scala -pos/t9020.scala -pos/jesper.scala -pos/t9356 -pos/virtpatmat_exhaust_big.scala -pos/t9239 -pos/t9111-inliner-workaround - -neg/volatile_no_override.scala -neg/t800.scala -neg/t5426.scala -neg/t2462a.scala -neg/t2641.scala -neg/classtags_dont_use_typetags.scala -neg/t5031 -neg/t2275b.scala -neg/macro-qmarkqmarkqmark.scala -neg/t4879.scala -neg/t5956.scala -neg/t4196.scala -neg/t6666b.scala -neg/warn-unused-privates.scala -neg/t6928.scala -neg/t6337.scala -neg/sealed-java-enums.scala -neg/t563.scala -neg/deadline-inf-illegal.scala -neg/t766.scala -neg/t5429.scala -neg/overloaded-implicit.scala -neg/t875.scala -neg/abstract-class-error -neg/unchecked2.scala -neg/predef-masking.scala -neg/viewtest.scala -neg/macro-noexpand -neg/varargs.scala -neg/t963b.scala -neg/t909.scala -neg/sensitive2.scala -neg/t5390b.scala -neg/abstraction-from-volatile-type-error.scala -neg/macro-exception -neg/t4431.scala -neg/t5689.scala -neg/valueclasses.scala -neg/overload.scala -neg/t0204.scala -neg/t908.scala -neg/t750 -neg/patmatexhaust.scala -neg/macro-invalidusage-badtargs -neg/t1168.scala -neg/t5761.scala -neg/t0503.scala -neg/t7235.scala -neg/t1215.scala -neg/primitive-sigs-1 -neg/t5578.scala -neg/names-defaults-neg-warn.scala -neg/t6436b.scala -neg/t3098 -neg/t910.scala -neg/parstar.scala -neg/t4568.scala -neg/newpat_unreachable.scala -neg/t1181.scala -neg/t5903c -neg/t7294.scala -neg/t4091.scala -neg/t5452-old.scala -neg/t5696.scala -neg/t0209.scala -neg/t2910.scala -neg/t7388.scala -neg/noMember2.scala -neg/no-predef.scala -neg/t6952.scala -neg/t1909b.scala -neg/abstract-report2.scala -neg/t5318.scala -neg/t6074.scala -neg/t7171.scala -neg/abstract-vars.scala -neg/unchecked-impossible.scala -neg/variances-refinement.scala -neg/t3453.scala -neg/t5189.scala -neg/t4302.scala -neg/xmltruncated7.scala -neg/t8217-local-alias-requires-rhs.scala -neg/t7602.scala -neg/t8869.scala -neg/t9008.scala -neg/sammy_error_exist_no_crash.scala -neg/t2866.scala -neg/t8597b.scala -neg/t5691.scala -neg/t8534b.scala -neg/literals.scala -neg/t8534.scala -neg/t8890.scala -neg/t9008b.scala -neg/t8731.scala -neg/t8291.scala -neg/t8597.scala -neg/t5639b -neg/t6582_exhaust_big.scala -neg/t9041.scala -neg/t9093.scala -neg/t7623.scala -neg/t9231.scala -neg/t9286b.scala -neg/t9273.scala -neg/t9127.scala -neg/t9286c.scala -neg/t9286a.scala -neg/virtpatmat_exhaust_big.scala - -run/t7249.scala -run/t3563.scala -run/t6111.scala -run/classtags_multi.scala -run/t5201.scala -run/checked.scala -run/valueclasses-classtag-basic.scala -run/t7171.scala -run/t5053.scala -run/t4535.scala -run/t5923d -run/t7291.scala -run/partialfun.scala -run/macro-term-declared-in-package-object -run/mapValues.scala -run/gadts.scala -run/t2386-new.scala -run/virtpatmat_stringinterp.scala -run/t657.scala -run/t0017.scala -run/t5713 -run/t576.scala -run/t3580.scala -run/virtpatmat_partial.scala -run/t6646.scala -run/mixins.scala -run/t1672.scala -run/macro-expand-implicit-macro-has-implicit -run/tuple-match.scala -run/t7039.scala -run/virtpatmat_opt_sharing.scala -run/virtpatmat_casting.scala -run/t2176.scala -run/macro-impl-relaxed -run/intmap.scala -run/t751.scala -run/t1591.scala -run/macro-typecheck-implicitsdisabled -run/t6911.scala -run/t5604.scala -run/macro-term-declared-in-default-param -run/collection-stacks.scala -run/multi-array.scala -run/t4560b.scala -run/buffer-slice.scala -run/t5629.scala -run/t6690.scala -run/matchonstream.scala -run/t3603.scala -run/lazy-exprs.scala -run/macro-quasiquotes -run/Course-2002-13.scala -run/t6337a.scala -run/exoticnames.scala -run/t0936.scala -run/runtime-richChar.scala -run/t6272.scala -run/t7215.scala -run/t1939.scala -run/ReverseSeqView.scala -run/lazy-leaks.scala -run/t0048.scala -run/t3994.scala -run/t2241.scala -run/t627.scala -run/t5966.scala -run/getClassTest-valueClass.scala -run/t3619.scala -run/t1300.scala -run/t2177.scala -run/t3760.scala -run/t1829.scala -run/macro-expand-implicit-macro-is-view -run/t889.scala -run/QueueTest.scala -run/t4537 -run/t3699.scala -run/t1192.scala -run/macro-expand-tparams-bounds -run/macro-expand-nullary-generic -run/t1434.scala -run/t6443-varargs.scala -run/macro-term-declared-in-trait -run/t4080.scala -run/matcharraytail.scala -run/infiniteloop.scala -run/t5733.scala -run/virtpatmat_nested_lists.scala -run/t5158.scala -run/t6695.scala -run/t6070.scala -run/t4558.scala -run/exc2.scala -run/patmat-behavior-2.scala -run/overloads.scala -run/t6957.scala -run/transform.scala -run/t5500.scala -run/t6663.scala -run/castsingleton.scala -run/t4147.scala -run/virtpatmat_staging.scala -run/t4565_1.scala -run/t5588.scala -run/run-bug4840.scala -run/t3496.scala -run/t5867.scala -run/search.scala -run/t3112.scala -run/hashsetremove.scala -run/t6443.scala -run/macro-expand-tparams-prefix -run/contrib674.scala -run/t3508.scala -run/t4300.scala -run/virtpatmat_typed.scala -run/macro-term-declared-in-class-object -run/map_test.scala -run/t5040.scala -run/t4827b.scala -run/lift-and-unlift.scala -run/t6574b.scala -run/t7240 -run/t3984.scala -run/virtpatmat_tailcalls_verifyerror.scala -run/macro-term-declared-in-class-class -run/emptypf.scala -run/t6104.scala -run/t2818.scala -run/t3761-overload-byname.scala -run/t2526.scala -run/phantomValueClass.scala -run/t3126.scala -run/arybufgrow.scala -run/t3980.scala -run/t7375b -run/t6077_patmat_cse_irrefutable.scala -run/classmanifests_new_core.scala -run/t3395.scala -run/name-based-patmat.scala -run/inliner-infer.scala -run/t5171.scala -run/t3726.scala -run/null-hash.scala -run/t4027.scala -run/t2544.scala -run/patmatnew.scala -run/t5923b -run/t7242.scala -run/classtags_core.scala -run/streamWithFilter.scala -run/t3038b.scala -run/macro-expand-varargs-explicit-over-nonvarargs-good -run/macro-divergence-spurious -run/macro-duplicate -run/t2958.scala -run/patch-boundary.scala -run/t2333.scala -run/lazy-override-run.scala -run/macro-quasiinvalidbody-c -run/t5037.scala -run/takeAndDrop.scala -run/t6126.scala -run/t0883.scala -run/t7617a -run/t4171.scala -run/empty-array.scala -run/t7198.scala -run/t493.scala -run/genericValueClass.scala -run/t0677-old.scala -run/t1373.scala -run/t4461.scala -run/t6011b.scala -run/t7584.scala -run/t3935.scala -run/t6928-run.scala -run/t744.scala -run/t3241.scala -run/blame_eye_triple_eee-double.scala -run/t3829.scala -run/t5577.scala -run/t5914.scala -run/t601.scala -run/t5610.scala -run/macro-basic-mamd-mi -run/t6150.scala -run/stringbuilder.scala -run/t7290.scala -run/t6888.scala -run/t6327.scala -run/virtpatmat_unapplyseq.scala -run/t4656.scala -run/macro-term-declared-in-method -run/macro-expand-implicit-macro-is-implicit -run/blame_eye_triple_eee-float.scala -run/t4482.scala -run/t5488.scala -run/matchemptyarray.scala -run/t3714.scala -run/richWrapperEquals.scala -run/t5328.scala -run/stream_flatmap_odds.scala -run/implicitclasses.scala -run/t6394b -run/complicatedmatch.scala -run/valueclasses-classmanifest-basic.scala -run/unreachable.scala -run/caseclasses.scala -run/withIndex.scala -run/exc1.scala -run/amp.scala -run/t1423.scala -run/t594.scala -run/t6353.scala -run/byname.scala -run/vector1.scala -run/t5879.scala -run/t1048.scala -run/t5080.scala -run/t4190.scala -run/caseClassEquality.scala -run/macro-enclosures -run/collections-toSelf.scala -run/implicits.scala -run/finalvar.scala -run/lazy-locals.scala -run/t7231.scala -run/t0508.scala -run/t6628.scala -run/t6406-regextract.scala -run/t0911.scala -run/t4013c.scala -run/t3502.scala -run/t5648.scala -run/retclosure.scala -run/t2857.scala -run/t4859.scala -run/t5162.scala -run/t3038.scala -run/classof.scala -run/t4062.scala -run/unapplyArray.scala -run/t4297.scala -run/t5923a -run/t1537.scala -run/boolexprs.scala -run/valueclasses-classtag-generic.scala -run/macro-term-declared-in-anonymous -run/tcpoly_monads.scala -run/t5407.scala -run/scan.scala -run/forvaleq.scala -run/null-and-intersect.scala -run/t7047 -run/t0607.scala -run/sequenceComparisons.scala -run/t4396.scala -run/macro-undetparams-consfromsls -run/t2029.scala -run/t1220.scala -run/option-fold.scala -run/t5284c.scala -run/macro-auto-duplicate -run/t3529.scala -run/t4697.scala -run/t2251.scala -run/t5300.scala -run/virtpatmat_valdef.scala -run/t2147.scala -run/virtpatmat_extends_product.scala -run/list_map.scala -run/t1333.scala -run/matchbytes.scala -run/valueclasses-classmanifest-existential.scala -run/records.scala -run/t3088.scala -run/macro-def-path-dependent -run/t6443-by-name.scala -run/t1044.scala -run/delay-good.scala -run/case-class-23.scala -run/weakconform.scala -run/patmat-bind-typed.scala -run/t4835.scala -run/t3097.scala -run/t405.scala -run/existentials.scala -run/t2876.scala -run/t4809.scala -run/t1427.scala -run/t6135.scala -run/t3575.scala -run/t5688.scala -run/t6900.scala -run/macro-expand-unapply-a -run/t6677b.scala -run/t7375a.scala -run/t7300.scala -run/typed-annotated -run/elidable-noflags.scala -run/t0042.scala -run/t3050.scala -run/t4536.scala -run/NestedClasses.scala -run/t3877.scala -run/seqlike-kmp.scala -run/t5907.scala -run/t266.scala -run/missingparams.scala -run/t2255.scala -run/t3488.scala -run/t3950.scala -run/typealias_overriding.scala -run/constant-optimization.scala -run/t7507.scala -run/t6090.scala -run/t4582.scala -run/macro-term-declared-in-class -run/macro-typecheck-macrosdisabled2 -run/t3425.scala -run/t4935.scala -run/t3326.scala -run/boolord.scala -run/t1141.scala -run/virtpatmat_unapply.scala -run/t5971.scala -run/t3651.scala -run/macro-sip19-revised -run/pure-args-byname-noinline.scala -run/preinits.scala -run/t5532.scala -run/concat-two-strings.scala -run/t3269.scala -run/macro-impl-default-params -run/t2162.scala -run/matchonseq.scala -run/t5428.scala -run/macro-expand-overload -run/t4660.scala -run/enrich-gentraversable.scala -run/macro-expand-override -run/t4054.scala -run/t4753.scala -run/macro-typecheck-macrosdisabled -run/t2308a.scala -run/duplicate-meth.scala -run/interop_classtags_are_classmanifests.scala -run/t3232.scala -run/t2075.scala -run/virtpatmat_partial_backquoted.scala -run/try-2.scala -run/macro-openmacros -run/macro-undetparams-macroitself -run/t6318_derived.scala -run/deprecate-early-type-defs.scala -run/dead-code-elimination.scala -run/t4827.scala -run/Course-2002-07.scala -run/slice-strings.scala -run/t6292.scala -run/t6206.scala -run/t1042.scala -run/t1718.scala -run/t2074_2.scala -run/arraycopy.scala -run/indexedSeq.scala -run/macro-term-declared-in-implicit-class -run/t3511.scala -run/t6290.scala -run/distinct.scala -run/virtpatmat_alts.scala -run/valueclasses-pavlov.scala -run/exceptions.scala -run/t1368.scala -run/t5856.scala -run/t6968.scala -run/names-defaults.scala -run/macro-expand-tparams-implicit -run/t5881.scala -run/t3540.scala -run/virtpatmat_try.scala -run/t7181.scala -run/value-class-extractor.scala -run/value-class-extractor-2.scala -run/t3150.scala -run/exc.scala -run/delay-bad.scala -run/infix.scala -run/t1309.scala -run/t6370.scala -run/t6725-2.scala -run/macro-impl-tparam-typetag-is-optional -run/macro-term-declared-in-block -run/matchnull.scala -run/t2127.scala -run/t7325.scala -run/groupby.scala -run/t3932.scala -run/t4871.scala -run/longmap.scala -run/t1524.scala -run/t6187b.scala -run/kmpSliceSearch.scala -run/t7088.scala -run/t5804.scala -run/stringbuilder-drop.scala -run/t5753_1 -run/t9223.scala -run/function-null-unbox.scala -run/t9223b.scala -run/disable-assertions.scala -run/valueClassSelfType.scala -run/indylambda-boxing -run/t9219.scala - -pos/cyclics-pos.scala -pos/cfcrash.scala -pos/tcpoly_higherorder_bound_method.scala -pos/t5084.scala -pos/macro-qmarkqmarkqmark.scala -pos/t7785.scala -pos/nested.scala -pos/t3152.scala -pos/t5031 -pos/t6925b.scala -pos/t1107b -pos/t5012.scala -pos/virtpatmat_obj_in_case.scala -pos/t4938.scala -pos/t3856.scala -pos/spec-cyclic.scala -pos/aliases.scala -pos/typerep_pos.scala -pos/t119.scala -pos/t1050.scala -pos/t3670.scala -pos/t6145.scala -pos/t7315.scala -pos/t5930.scala -pos/t789.scala -pos/t5071.scala -pos/t4731.scala -pos/t4547.scala -pos/t2038.scala -pos/testCoercionThis.scala -pos/t2444.scala -pos/t5744 -pos/t780.scala -pos/t1722-A.scala -pos/virtpatmat_exist1.scala -pos/t6225.scala -pos/t762.scala -pos/t0204.scala -pos/rebind.scala -pos/spec-short.scala -pos/comp-rec-test.scala -pos/lub-dealias-widen.scala -pos/t1168.scala -pos/modules.scala -pos/t4220.scala -pos/t4070.scala -pos/t175.scala -pos/t2500.scala -pos/t5029.scala -pos/itay.scala -pos/t4202.scala -pos/t1987b -pos/t3534.scala -pos/infer2-pos.scala -pos/spec-sparsearray-new.scala -pos/t7091.scala -pos/ticket0137.scala -pos/collectGenericCC.scala -pos/t640.scala -pos/t4305.scala -pos/extractor-types.scala -pos/t3880.scala -pos/spec-annotations.scala -pos/t3577.scala -pos/compile1.scala -pos/spec-t3497.scala -pos/hkrange.scala -pos/t287.scala -pos/t6008.scala -pos/t4432.scala -pos/CustomGlobal.scala -pos/patmat.scala -pos/t2413 -pos/t2910.scala -pos/t592.scala -pos/t6245 -pos/infer.scala -pos/t7228.scala -pos/compound.scala -pos/attributes.scala -pos/t6771.scala -pos/t1090.scala -pos/t684.scala -pos/t577.scala -pos/t4273.scala -pos/t6278-synth-def.scala -pos/t6184.scala -neg/t0214.scala -neg/t4842.scala -neg/t6214.scala -neg/reify_nested_inner_refers_to_local.scala -neg/t576.scala -neg/t5969.scala -neg/tcpoly_variance.scala -neg/t7509.scala -neg/mixins.scala -neg/parent-inherited-twice-error.scala -neg/macro-abort -neg/constructor-init-order.scala -neg/t6042.scala -neg/t0590.scala -neg/t4221.scala -neg/t783.scala -neg/t5554.scala -neg/macro-invalidsig-params-badtype -neg/multi-array.scala -neg/raw-types-stubs -neg/spec-overrides.scala -neg/t836.scala -neg/t7289_status_quo.scala -neg/t5675.scala -neg/macro-quasiquotes -neg/t6667.scala -neg/t6597.scala -neg/t6264.scala -neg/t0345.scala -neg/t7294b.scala -neg/t5340.scala -neg/t2144.scala -neg/t1010.scala -neg/t1838.scala -neg/t5189b.scala -neg/reify_metalevel_breach_-1_refers_to_1.scala -neg/t6601 -neg/wellkinded_wrongarity.scala -neg/t3909.scala -neg/t876.scala -neg/t5390.scala -neg/unit2anyref.scala -neg/t0351.scala -neg/t5120.scala -neg/t1038.scala -neg/t5878.scala -neg/qualifying-class-error-2.scala -neg/t3816.scala -neg/tailrec.scala -neg/volatile.scala -neg/t944.scala -neg/t1705.scala -neg/t3977.scala -neg/t5553_2.scala -neg/t5318c.scala -neg/overload-msg.scala -neg/t5440.scala -neg/t6335.scala -neg/compile-time-only-b.scala -neg/t501.scala -neg/override.scala -neg/t663.scala -neg/t5892.scala -neg/t1980.scala -neg/macro-false-deprecation-warning -neg/t585.scala -neg/t3776.scala -neg/interop_classtags_arenot_manifests.scala -neg/t4044.scala -neg/macro-invalidusage-nontypeable -neg/t500.scala -neg/t4877.scala -neg/t5357.scala -neg/interop_abstypetags_arenot_manifests.scala -neg/t4460a.scala -neg/t5318b.scala -neg/t4440.scala -neg/t6663.scala -neg/t6357.scala -neg/gadts1.scala -neg/cyclics.scala -neg/t5060.scala -neg/scopes.scala -run/t4013.scala -run/macro-expand-tparams-explicit -run/tuples.scala -run/t5753_2 -run/t0528.scala -run/t5105.scala -run/t7341.scala -run/t3670.scala -run/t2594_tcpoly.scala -run/t3895.scala -run/t0668.scala -run/slices.scala -run/t6666a.scala -run/valueclasses-classmanifest-generic.scala -run/t2316_run.scala -run/t3004.scala -run/viewtest.scala -run/t6481.scala -run/t0005.scala -run/t4766.scala -run/t5500b.scala -run/t7407b.scala -run/backreferences.scala -run/arrayview.scala -run/t629.scala -run/t5903c -run/unittest_collection.scala -run/spec-nlreturn.scala -run/macro-term-declared-in-object-object -run/triple-quoted-expr.scala -run/t5937.scala -run/t6011c.scala -run/macro-expand-implicit-argument -run/try.scala -run/t1987b -run/t6089.scala -run/macro-range -run/t2524.scala -run/t4770.scala -run/virtpatmat_unapplyprod.scala -run/t1535.scala -run/ctor-order.scala -pos/t5210.scala -pos/t5384.scala -pos/rangepos.scala -pos/t443.scala -pos/t1480.scala -pos/t116.scala -pos/seqtest2.scala -pos/scoping1.scala -pos/t4269.scala -pos/lookupswitch.scala -pos/t3642 -pos/t5706.scala -pos/t7264 -pos/t0031.scala -pos/macro-deprecate-dont-touch-backquotedidents.scala -pos/t6815.scala -pos/test4refine.scala -pos/michel5.scala -pos/t0851.scala -pos/t1185.scala -pos/sudoku.scala -pos/t7520.scala -pos/t6208.scala -pos/t3411.scala -pos/t295.scala -pos/S3.scala -pos/t0674.scala -pos/t6664b.scala -pos/variances_pos.scala -pos/liftcode_polymorphic.scala -pos/t3174b.scala -pos/t7232d -pos/t578.scala -pos/implicit-infix-ops.scala -pos/t4363.scala -pos/t532.scala -pos/exponential-spec.scala -pos/t599.scala -pos/t5862.scala -pos/t4603 -pos/t3676.scala -pos/t1357.scala -pos/native-warning.scala -pos/t1230 -pos/t6028 -pos/t4275.scala -pos/overloaded_extractor_and_regular_def.scala -pos/t4205 -pos/matthias1.scala -pos/testcast.scala -pos/generic-sigs.scala -pos/t0093.scala -pos/specializes-sym-crash.scala -pos/t0061.scala -pos/t2429.scala -pos/t694.scala -pos/javaReadsSigs -pos/t2023.scala -pos/t704.scala -pos/t2208_pos.scala -pos/t5137.scala -pos/t2683.scala -pos/t0049.scala -pos/t1029 -pos/t4243.scala -pos/typerep-stephane.scala -pos/t177.scala -pos/t5967.scala -pos/t430.scala -pos/virtpatmat_infer_single_1.scala -pos/pat_iuli.scala -pos/t1071.scala -pos/t7226.scala -pos/t1843.scala -pos/t419.scala -pos/t7364b -pos/t1159.scala -pos/t5305.scala -pos/t7694.scala -pos/t6047.scala -pos/t3578.scala -pos/t2082.scala -pos/setter-not-implicit.scala -pos/t1133.scala -pos/t3862.scala -pos/t942 -pos/nothing_manifest_disambig-new.scala -pos/iterator-traversable-mix.scala -pos/eta.scala -pos/test4.scala -pos/t2691.scala -pos/t4502.scala -pos/t7183.scala -pos/protected-t1010.scala -pos/X.scala -pos/virtpatmat_exist2.scala -pos/t4911.scala -pos/t3477.scala -pos/t4173.scala -pos/t7782.scala -pos/t2399.scala -pos/virtpatmat_alts_subst.scala -pos/propagate.scala -pos/t2421b_pos.scala -pos/t183.scala -pos/t7033.scala -pos/t3612.scala -pos/t5330c.scala -pos/t3020.scala -pos/t4869.scala -pos/t3373.scala -pos/spec-params-new.scala -pos/t3672.scala -pos/t4501.scala -pos/t1565.scala -pos/t3774.scala -pos/t6942 -pos/t845.scala -pos/t3240.scala - -neg/t3275.scala -neg/t421.scala -neg/t5702-neg-bad-brace.scala -neg/t3663 -neg/badtok-1.scala -neg/t677.scala -neg/t7756b.scala -neg/t6534.scala -neg/t6276.scala -neg/t5762.scala -neg/abstract.scala -neg/t2405.scala -neg/t0418.scala -neg/t5390c.scala -neg/lazyvals.scala -neg/lubs.scala -neg/abstract-report.scala -neg/t4163.scala -neg/t5702-neg-bad-and-wild.scala -neg/macro-invalidret -neg/t6728.scala -neg/t5152.scala -neg/t1432.scala -neg/abstract-inaccessible.scala -neg/import-precedence.scala -neg/t2462b.scala -neg/macro-invalidusage-presuper -neg/specification-scopes -neg/t6048.scala -neg/t4079 -neg/macro-basic-mamdmi -neg/t7020.scala -neg/t3015.scala -neg/t0207.scala -neg/t2296b -neg/t0673 -neg/t3761-overload-byname.scala -neg/t6675.scala -neg/t5529.scala -neg/sensitive.scala -neg/t742.scala -neg/t5067.scala -neg/t6162-overriding.scala -neg/variances.scala -neg/t5728.scala -neg/t6323a.scala -neg/compile-time-only-a.scala -neg/t6795.scala -neg/t2494.scala -neg/t3649.scala -neg/macro-invalidsig -neg/t2796.scala -neg/t112706A.scala -neg/t0764.scala -neg/t3757 -neg/t1431.scala -neg/exhausting.scala -neg/t1523.scala -neg/t779.scala -neg/xmltruncated1.scala -neg/t2208.scala -neg/t2078.scala -neg/t521.scala -neg/null-unsoundness.scala -neg/stmt-expr-discard.scala -neg/t0513.scala -neg/unchecked-abstract.scala -neg/t4460c.scala -neg/divergent-implicit.scala -neg/t5078.scala -neg/t1701.scala -neg/t0816.scala -neg/t1672b.scala -neg/macro-invalidusage-badbounds -neg/tailrec-2.scala -neg/t4064.scala -neg/t5510.scala -neg/t3873.scala -neg/tailrec-3.scala -neg/t0226.scala -neg/t2031.scala -neg/t633.scala -neg/constrs.scala -neg/anyval-anyref-parent.scala -neg/t7290.scala -neg/t1041.scala -neg/patternalts.scala -neg/error_tooManyArgsPattern.scala -neg/checksensibleUnit.scala -neg/t6539 -neg/t4417.scala -neg/wellkinded_app.scala -neg/for-comprehension-old.scala -neg/t2779.scala -neg/object-not-a-value.scala -neg/t2968b.scala -neg/t6483.scala -neg/t6902.scala -neg/t6963a.scala -neg/t3399.scala -neg/t0015.scala -neg/t276.scala -neg/t6758.scala -neg/t2441.scala -neg/cycle-bounds.scala -neg/t1241.scala -neg/t4137.scala -neg/unicode-unterminated-quote.scala -neg/t4762.scala -neg/typeerror.scala -neg/implicits.scala -neg/t961.scala -neg/ambiguous-float-dots2.scala -neg/t2416.scala -neg/t5799.scala -neg/t7285.scala -neg/implicit-shadow.scala -neg/t2388.scala -neg/java-access-neg -neg/found-req-variance.scala -neg/hk-bad-bounds.scala -neg/t3224.scala -neg/t1033.scala -neg/t7385.scala -neg/t5882.scala -neg/t4541.scala -neg/t2973.scala -neg/t6406-regextract.scala -neg/t6666.scala -neg/t4831.scala -neg/t425.scala -neg/t1845.scala -neg/t3683b.scala -neg/t2801.scala -neg/t6083.scala -neg/t0528neg.scala -neg/stringinterpolation_macro-neg.scala -neg/t668.scala -neg/t5666.scala -neg/t4271.scala -neg/interop_typetags_arenot_classmanifests.scala -neg/t1355.scala -neg/t715.scala -neg/t7238.scala -neg/t7473.scala -neg/t7292-removal.scala -neg/tcpoly_infer_ticket1162.scala -neg/t4098.scala -neg/t6013 -neg/t6227.scala -neg/t464-neg.scala -neg/badtok-3.scala -neg/t6082.scala -neg/anytrait.scala -neg/valueclasses-doubledefs.scala -neg/t7519.scala -neg/overloaded-unapply.scala -neg/t1163.scala -neg/wellkinded_bounds.scala -neg/t7292-deprecation.scala -neg/t0842.scala -neg/t6436.scala -neg/interop_typetags_arenot_classtags.scala -neg/t3653.scala -neg/higherkind_novalue.scala -neg/t935.scala -neg/t6040.scala -neg/macro-deprecate-idents.scala -neg/illegal-stmt-start.scala -neg/t565.scala -neg/case-collision.scala -neg/t3209.scala -neg/t5821.scala -neg/abstract-class-2.scala -neg/t846.scala -neg/quasiquotes-syntax-error-position.scala -neg/t3987.scala -neg/t877.scala -neg/t0117.scala -neg/t692.scala -neg/t5702-neg-ugly-xbrace.scala -neg/t7752.scala -neg/case-collision2.scala -neg/t6526.scala -neg/t2213.scala -neg/t7756a.scala -neg/macro-override-macro-overrides-abstract-method-a -neg/tcpoly_ticket2101.scala -neg/delayed-init-ref.scala -neg/caseinherit.scala -neg/t3189.scala -neg/unchecked-suppress.scala -neg/t2180.scala -neg/t1371.scala -neg/macro-cyclic -neg/t6123-explaintypes-macros -neg/t4134.scala -neg/t691.scala -neg/t2421b.scala -neg/t4691_exhaust_extractor.scala -neg/t4419.scala -neg/t5801.scala -neg/t650.scala -neg/t5735.scala -neg/t696.scala -neg/t882.scala -neg/t2968.scala -neg/t7507.scala -neg/macro-invalidusage-badargs -neg/macro-reify-typetag-typeparams-notags -neg/wellkinded_app2.scala -neg/t4425b.scala -neg/t2296a -neg/t1878.scala -neg/t649.scala -neg/override-object-no.scala -neg/t4174.scala -neg/t2070.scala -neg/sabin2.scala -neg/t5903e -neg/t6566a.scala -neg/finitary-error.scala -neg/t4818.scala -neg/t3614.scala -neg/t6666c.scala -neg/ticket513.scala -neg/suggest-similar.scala -neg/t4457_1.scala -neg/t6666e.scala -neg/tcpoly_bounds.scala -neg/t4727.scala -neg/t4425.scala -neg/macro-invalidusage-methodvaluesyntax -neg/t3854.scala -neg/t3006.scala -neg/t5580b.scala -neg/t5378.scala -neg/t639.scala -neg/wrong-args-for-none.scala -neg/t7171b.scala -neg/t5361.scala -neg/unreachablechar.scala -neg/t5572.scala -neg/t7757a.scala -neg/macro-invalidimpl -neg/t2773.scala -neg/t6359.scala -neg/saito.scala -neg/xmltruncated2.scala -neg/t667.scala -neg/t3934.scala -neg/t6771b.scala -neg/t4584.scala -neg/wellkinded_wrongarity2.scala -neg/t7369.scala -neg/t1477.scala -neg/t5617.scala -neg/t7299.scala -neg/faculty.scala -neg/virtpatmat_reach_null.scala -neg/macro-reify-typetag-hktypeparams-notags -neg/t1224.scala -neg/xmltruncated3.scala -neg/t1872.scala -neg/t558.scala -neg/t7110.scala -neg/any-vs-anyref.scala -neg/t6340.scala -neg/t4166.scala -neg/t2918.scala -neg/t5856.scala -neg/t4989.scala -neg/t0003.scala -neg/t1183.scala -neg/t963.scala -neg/t4515.scala -neg/valueclasses-pavlov.scala -neg/t608.scala -neg/choices.scala -neg/patmat-type-check.scala -neg/valueclasses-impl-restrictions.scala -neg/imp2.scala -neg/protected-constructors.scala -neg/t6788.scala -neg/nullary-override.scala -neg/t200.scala -neg/t343.scala -neg/names-defaults-neg-ref.scala -neg/tcpoly_typealias.scala -neg/classtags_contextbound_b.scala -neg/t729.scala -neg/t5683.scala -neg/t4928.scala -neg/t700.scala -neg/t7669.scala -neg/macro-invalidshape -neg/t6011.scala -neg/t7325.scala -neg/check-dead.scala -neg/t550.scala -neg/t5663-badwarneq.scala -neg/t0699 -neg/nopredefs.scala -neg/t3507-old.scala -neg/t5352.scala -neg/t6336.scala -neg/interop_classmanifests_arenot_typetags.scala -neg/sealed-final-neg.scala -neg/t2102.scala -neg/t7636.scala -neg/t5031b -neg/t798.scala -neg/t5702-neg-bad-xbrace.scala -neg/t0899.scala -neg/cyclics-import.scala -neg/badtok-2.scala -neg/t473.scala -neg/t3160ambiguous.scala -neg/t5106.scala -neg/t1286 -neg/macro-override-macro-overrides-abstract-method-b -neg/t0259.scala -neg/t510.scala -neg/t3836.scala -neg/t5830.scala -neg/t1548 -neg/t5580a.scala -neg/forward.scala -neg/t591.scala -neg/t6558b.scala -neg/t556.scala -neg/xmltruncated4.scala -neg/t5497.scala -neg/t409.scala -neg/t6283.scala -neg/override-object-flag.scala -neg/constructor-prefix-error.scala -neg/eta-expand-star.scala -neg/t3392.scala -neg/t1275.scala -neg/nested-fn-print.scala -neg/t7330.scala -neg/t2275a.scala -neg/t630.scala -neg/t4270.scala -neg/t2775.scala -neg/pat_unreachable.scala -neg/t4158.scala -neg/unit-returns-value.scala -neg/t1422.scala -neg/reify_metalevel_breach_-1_refers_to_0_b.scala -neg/reassignment.scala -neg/t3683a.scala -neg/noMember1.scala -neg/macro-without-xmacros-b -neg/t1106.scala -neg/t5182.scala -neg/t6889.scala -neg/t4217.scala -neg/t7501 -neg/t5063.scala -neg/t1009.scala -neg/t997.scala -neg/unchecked.scala -neg/classtags_contextbound_c.scala -neg/applydynamic_sip.scala -neg/t7715.scala -neg/t588.scala -neg/t6667b.scala -neg/t7757b.scala -neg/t4069.scala -neg/t515.scala -neg/variances2.scala -neg/t1049.scala -neg/t7289.scala -neg/t1623.scala -neg/permanent-blindness.scala -neg/t5803.scala -neg/super-cast-or-test.scala -neg/nonlocal-warning.scala -neg/t5687.scala -neg/t5903a -neg/t6566b.scala -neg/unchecked-knowable.scala -neg/t5093.scala -neg/protected-static-fail -neg/type-diagnostics.scala -neg/forgot-interpolator.scala -neg/interop_abstypetags_arenot_classmanifests.scala -neg/t5376.scala -neg/t545.scala -neg/xmlcorner.scala -neg/switch.scala -neg/depmet_1.scala -neg/abstract-concrete-methods.scala -neg/t4987.scala -neg/t5452-new.scala -neg/t750b -neg/unchecked-refinement.scala -neg/t418.scala -neg/t5354.scala -neg/t3736.scala -neg/t631.scala -neg/t6829.scala -neg/t0218.scala -neg/volatile-intersection.scala -neg/t412.scala -neg/t693.scala -neg/t4882.scala -neg/t1960.scala -neg/macro-divergence-controlled -neg/t712.scala -neg/t5544 -neg/t3222.scala -neg/t3604.scala -neg/t1112.scala -neg/t7157 -neg/accesses.scala -neg/t452.scala -neg/t6162-inheritance -neg/t2442 -neg/t6567.scala -neg/lazy-override.scala -neg/abstract-explaintypes.scala -neg/nested-annotation.scala -neg/t5753 -neg/t3691.scala -neg/infix-op-positions.scala -neg/t3403.scala -neg/t4851 -neg/structural.scala -neg/error_dependentMethodTpeConversionToFunction.scala -neg/t5839.scala -neg/t5553_1.scala -neg/reify_metalevel_breach_+0_refers_to_1.scala -neg/t752.scala -neg/t6574.scala -neg/t3714-neg.scala -neg/t4457_2.scala -neg/t2148.scala -neg/t1364.scala -neg/saferJavaConversions.scala -neg/t414.scala -neg/t5493.scala -neg/classtags_contextbound_a.scala -neg/reify_metalevel_breach_-1_refers_to_0_a.scala -neg/t3118.scala -neg/t512.scala -neg/t2336.scala -neg/t856.scala -neg/xmltruncated6.scala -neg/t2206.scala -neg/virtpatmat_unreach_select.scala -neg/t6258.scala -neg/t6815.scala -neg/dbldef.scala -neg/qualifying-class-error-1.scala -neg/t835.scala -neg/t5455.scala -neg/t6558.scala -neg/t708.scala -neg/macro-nontypeablebody -neg/t0565.scala -neg/xmltruncated5.scala -neg/t5390d.scala -neg/t520.scala -neg/t6138.scala -neg/macro-without-xmacros-a -neg/t7214neg.scala -neg/t2870.scala -neg/t593.scala -neg/t4541b.scala -neg/t4460b.scala -neg/t284.scala -neg/t2488.scala -neg/macro-override-method-overrides-macro -neg/interop_abstypetags_arenot_classtags.scala -neg/t3769.scala -neg/warn-inferred-any.scala -neg/t664.scala -neg/t5903d -neg/t562.scala -neg/t2316.scala -neg/t0152.scala -neg/migration28.scala -neg/t6443c.scala -neg/tcpoly_override.scala -neg/t7324.scala -neg/t987.scala -neg/t5903b -neg/t3481.scala -neg/t6912.scala -neg/tcpoly_variance_enforce.scala -neg/t3913.scala -neg/names-defaults-neg.scala -neg/t765.scala -neg/t5358.scala -neg/t391.scala -neg/serialversionuid-not-const.scala -neg/t771.scala -neg/t0903.scala -neg/catch-all.scala -neg/classmanifests_new_deprecations.scala -neg/t0606.scala -neg/t5189_inferred.scala -neg/macro-reify-typetag-useabstypetag -neg/t5543.scala -neg/logImplicits.scala -neg/interop_typetags_without_classtags_arenot_manifests.scala -neg/t6535.scala -neg/t7259.scala -neg/t2139.scala -neg/t278.scala -neg/t5564.scala -neg/unchecked3.scala -neg/virtpatmat_reach_sealed_unsealed.scala -neg/checksensible.scala -neg/t7721.scala -run/t3798.scala -run/macro-expand-varargs-explicit-over-varargs -run/t3888.scala -run/t0677-new.scala -run/t3273.scala -run/t3763.scala -run/t2755.scala -run/t920.scala -run/t5610a.scala -run/literals.scala -run/proxy.scala -run/unapply.scala -run/t5830.scala -run/array-addition.scala -run/macro-expand-nullary-nongeneric -run/macro-basic-ma-mdmi -run/valueclasses-constr.scala -run/t1247.scala -run/t3487.scala -run/rawstrings.scala -run/patmat-seqs.scala -run/eta-expand-star.scala -run/t7436.scala -run/t3996.scala -run/constructors.scala -run/t498.scala -run/t3835.scala -run/t298.scala -run/t2867.scala -run/t7120 -run/virtpatmat_literal.scala -run/t2175.scala -run/t2503.scala -run/t3026.scala -run/t603.scala -run/t0091.scala -run/t6394a -run/macro-expand-varargs-implicit-over-varargs -run/t7407.scala -run/t2552.scala -run/virtpatmat_npe.scala -run/macro-sip19 -run/t6644.scala -run/t6614.scala -run/t2005.scala -run/t4680.scala -run/t5903a -run/classtags_contextbound.scala -run/Course-2002-05.scala -run/applydynamic_sip.scala -run/t1766.scala -run/retsynch.scala -run/t7715.scala -run/t102.scala -run/nonlocalreturn.scala -run/macro-reify-staticXXX -run/Course-2002-06.scala -run/t6863.scala -run/t6500.scala -run/macro-impl-rename-context -run/t4351.scala -run/t5009.scala -run/macro-term-declared-in-annotation -run/t6271.scala -run/array-existential-bound.scala -run/t6443b.scala -run/t1987.scala -run/MutableListTest.scala -run/t7571.scala -run/t5488-fn.scala -run/macro-bodyexpandstoimpl -run/macro-reify-ref-to-packageless -run/t2212.scala -run/macro-expand-varargs-implicit-over-nonvarargs -run/t0807.scala -run/patmat-behavior.scala -run/t2446.scala -run/breakout.scala -run/t4122.scala -run/macro-settings -run/t7157 -run/t1323.scala -run/t4013b.scala -run/t6309.scala -run/t4047.scala -run/t5544 -run/t978.scala -run/t3361.scala -run/t6611.scala -run/t5387.scala -run/t5656.scala -run/t4897.scala -run/numeric-range.scala -run/t4777.scala -run/Course-2002-03.scala -run/string-extractor.scala -run/view-headoption.scala -run/patmat_unapp_abstype-new.scala -run/stream-stack-overflow-filter-map.scala -run/macro-impl-tparam-only-in-impl -run/t6559.scala -run/macro-reify-tagful-a -run/macro-expand-multiple-arglists -run/t4709.scala -run/t3509.scala -run/t5284b.scala -run/t7617b -run/t3923.scala -run/virtpatmat_apply.scala -run/t363.scala -run/manifests-undeprecated-in-2.10.0.scala -run/matchintasany.scala -run/t3970.scala -run/t4996.scala -run/t5530.scala -run/macro-term-declared-in-object-class -run/t3242b.scala -run/indexedSeq-apply.scala -run/t107.scala -run/t2337.scala -run/t2754.scala -run/flat-flat-flat.scala -run/t6673.scala -run/interpolationMultiline2.scala -run/t0631.scala -run/t2800.scala -run/t6506.scala -run/t6260.scala -run/t2418.scala -run/t4415.scala -run/classmanifests_new_alias.scala -run/t5380.scala -run/tcpoly_parseridioms.scala -run/t1747.scala -run/t5903d -run/t3530.scala -run/t216.scala -run/macro-term-declared-in-refinement -run/t4592.scala -run/t2488.scala -run/t3327.scala -run/t5614.scala -run/t5903b -run/iterables.scala -run/t3964.scala -run/t6329_vanilla.scala -run/t3038c -run/t1697.scala -run/t2030.scala -run/t3397.scala -run/t1005.scala -run/t3353.scala -run/t1466.scala -run/t3186.scala -run/tcpoly_overriding.scala -run/t5394.scala -run/t5284.scala -run/unboxingBug.scala -run/t7200.scala -run/macro-reify-basic -run/t153.scala -run/iterator3444.scala -run/macro-expand-implicit-macro-is-val -run/macro-basic-ma-md-mi -run/interpolationArgs.scala -run/t4954.scala -run/t3645.scala -run/transpose.scala -run/t3887.scala -run/t4288.scala -run/unittest_iterator.scala -run/t5543.scala -run/macro-term-declared-in-object -run/iq.scala -run/t2788.scala -run/t2027.scala -run/macro-expand-recursive -run/t949.scala -run/t1909b.scala -run/delambdafy-nested-by-name.scala -run/delambdafy-two-lambdas.scala -run/macro-blackbox-materialization -run/lists-run.scala -run/macro-parse-position -run/macro-parse-position-malformed -run/macro-whitebox-dynamic-materialization -run/macro-whitebox-extractor -run/macro-vampire-false-warning -run/macro-whitebox-fundep-materialization -run/macro-whitebox-structural -run/mutable-treeset.scala -run/static-module-method.scala -run/sort.scala -run/t1909.scala -run/t1909c.scala -run/t3346a.scala -run/t3346d.scala -run/t3346f.scala -run/t3346h.scala -run/t3346g.scala -run/t3832.scala -run/t4742.scala -run/t5377.scala -run/t5923c.scala -run/t6188.scala -run/t6333.scala -run/t6385.scala -run/t7899.scala -run/t7584b.scala -run/t7223.scala -run/t7859 -run/t7868.scala -run/t7871 -run/arrayclone-new.scala -run/arrayclone-old.scala -run/bitsets.scala -run/comparable-comparator.scala -run/colltest1.scala -run/t2106.scala -run/t5986.scala -run/view-iterator-stream.scala -run/array-charSeq.scala -pos/signatures -pos/t1263 -pos/t3249 -neg/t4749.scala -neg/main1.scala -neg/t7251 -neg/t7494-after-terminal -neg/t7494-before-parser -neg/t7494-right-after-terminal -run/lazy-traits.scala -run/OrderingTest.scala -run/ReplacementMatching.scala -run/patmat-finally.scala -run/t3158.scala -run/t3346e.scala -run/t4398.scala -run/t4930.scala -run/t6534.scala -pos/sammy_scope.scala -pos/delambdafy-patterns.scala -pos/private-types-after-typer.scala -pos/delambdafy-lambdalift.scala -pos/sammy_poly.scala -pos/sammy_single.scala -pos/sammy_twice.scala -pos/t3160.scala -pos/t1014.scala -pos/t4970b.scala -pos/t2698.scala -pos/t5845.scala -pos/t6201.scala -pos/t6260a.scala -pos/t7688.scala -pos/t7818.scala -pos/t1203a.scala -pos/t7834.scala -pos/t7853.scala -pos/t7815.scala -pos/t7853-partial-function.scala -pos/t7864.scala -pos/t7928.scala -pos/t7902.scala -pos/t7944.scala -pos/t7847 -neg/accesses2.scala -neg/bad-advice.scala -neg/gadts2.scala -neg/gadts2-strict.scala -neg/macro-bundle-abstract.scala -neg/macro-bundle-object.scala -neg/macro-bundle-trait.scala -neg/macro-blackbox-dynamic-materialization -neg/macro-blackbox-extractor -neg/run-gadts-strict.scala -neg/macro-blackbox-structural -neg/sammy_restrictions.scala -neg/sammy_wrong_arity.scala -neg/t2462c.scala -neg/t3346b.scala -neg/t1909-object.scala -neg/macro-blackbox-fundep-materialization -neg/t3346c.scala -neg/t3871.scala -neg/t3871b.scala -neg/t3971.scala -neg/t3346i.scala -neg/t6120.scala -neg/t6260c.scala -neg/t6680a.scala -neg/t7239.scala -neg/t7007.scala -neg/t7605-deprecation.scala -neg/t7622-missing-required.scala -neg/t7629-view-bounds-deprecation.scala -neg/t7834neg.scala -neg/t7783.scala -neg/t7848-interp-warn.scala -neg/t7519-b -neg/t7622-missing-dependency -neg/t7870.scala -neg/t7877.scala -neg/t7895.scala -neg/t7895b.scala -neg/t7899.scala -neg/t7895c.scala -neg/t7859 -run/t4752.scala -run/t2087-and-2400.scala -run/t3855.scala -run/t6637.scala -run/t6731.scala -pos/t3999b.scala -run/t0432.scala -run/t2514.scala -run/t7817.scala -run/t874.scala -run/type-currying.scala -run/t3616.scala -run/t3687.scala -run/t4570.scala -run/t5612.scala -run/t1110.scala -run/t2636.scala -run/verify-ctor.scala -run/t4560.scala -run/t6632.scala -run/richs.scala -run/t6725-1.scala -pos/t7776.scala -run/fors.scala -run/t6706.scala -run/t3175.scala -run/delambdafy-dependent-on-param-subst.scala -run/t4332b.scala -run/t8048a -run/t8017 -run/t7985b.scala -run/t8100.scala -run/patmat-mix-case-extractor.scala -run/t4750.scala -run/t7912.scala -run/delambdafy-dependent-on-param-subst-2.scala -run/t8048b -run/t8091.scala -run/macroPlugins-macroRuntime -run/macro-default-params -run/t6355.scala -run/t7777 -run/t8002.scala -run/t8015-ffc.scala -run/macro-subpatterns -run/t7985.scala -run/macroPlugins-macroArgs -run/t7326.scala -run/t5045.scala -run/value-class-partial-func-depmet.scala -run/t6329_vanilla_bug.scala -run/macroPlugins-macroExpand -run/t8010.scala -run/macroPlugins-typedMacroBody -run/t7406.scala -pos/t8146a.scala -pos/t8046c.scala -pos/t8132.scala -pos/t8045.scala -pos/overzealous-assert-genbcode.scala -pos/t8128.scala -pos/t8013 -pos/t8064b -pos/t6780.scala -pos/t7987 -pos/bcode_throw_null -pos/t8064 -pos/t8046.scala -pos/t6231.scala -pos/t7983.scala -pos/t5508.scala -pos/t5508-min.scala -pos/t8023b.scala -pos/t6231b.scala -pos/debug-reset-local-attrs.scala -pos/t8054.scala -pos/t2066.scala -pos/dotless-targs.scala -pos/t8120.scala -pos/t5508-min-okay.scala -pos/t8060.scala -pos/t8001 -pos/t8138.scala -pos/t8111.scala -pos/t8011.scala -pos/t8146b.scala -pos/t8046b.scala -pos/t8023.scala -pos/t5508-min-okay2.scala -pos/macro-implicit-invalidate-on-error.scala -neg/t6563.scala -neg/missing-param-type-tuple.scala -neg/not-a-legal-formal-parameter-tuple.scala -neg/t7897.scala -neg/t8015-ffa.scala -neg/quasiquotes-unliftable-not-found.scala -neg/t2066b.scala -neg/dotless-targs.scala -neg/patmat-classtag-compound.scala -neg/t2066.scala -neg/t8035-deprecated.scala -neg/t6675b.scala -neg/t8104 -neg/t7872.scala -neg/t7850.scala -neg/t7967.scala -neg/macro-bundle-overloaded.scala -neg/t6355a.scala -neg/class-of-double-targs.scala -neg/t6355b.scala -neg/macro-reify-splice-splice -neg/macro-bundle-noncontext.scala -neg/t8015-ffb.scala -neg/t8035-removed.scala -neg/t7984.scala -neg/t8024.scala -neg/t8024b.scala -neg/t8157.scala -neg/t8146-non-finitary-2.scala -neg/t8006.scala -neg/t7872c.scala -neg/t8146-non-finitary.scala -neg/t7872b.scala -neg/t6920.scala -run/t6200.scala -run/t6196.scala -run/macro-bundle-context-refinement -run/macro-enclosingowner-detectvar -run/macro-enclosingowner-sbt -run/macro-bundle-context-alias -run/macro-bundle-whitebox-use-refined -run/macro-bundle-whitebox-use-raw -neg/name-lookup-stable.scala -neg/t0764b.scala -neg/no-implicit-to-anyref-any-val.scala -neg/t1503.scala -neg/t4728.scala -neg/t6455.scala -neg/t6260-named.scala -neg/t6844.scala -neg/t7475c.scala -neg/t7475e.scala -neg/t7475f.scala -neg/macro-bundle-whitebox-use-raw -neg/macro-bundle-whitebox-use-refined -neg/macro-incompatible-macro-engine-b -neg/t7980.scala -neg/macro-incompatible-macro-engine-a -neg/t8143a.scala -neg/t8207.scala -neg/t8182.scala -neg/t8219-any-any-ref-equals.scala -neg/t8177a.scala -neg/t8228.scala -neg/t8229.scala -neg/t8237-default.scala -neg/t8244b.scala -neg/t8244e -neg/t8244c.scala -neg/t8265.scala -neg/t8266-invalid-interp.scala -neg/t6931 -neg/t8376 -neg/t8372.scala -neg/t8300-overloading.scala -neg/t8244 -neg/t8158 -neg/t8431.scala -pos/implicit-anyval-2.10.scala -pos/delambdafy_t6260_method.scala -pos/macro-bundle-disambiguate-bundle.scala -pos/macro-bundle-disambiguate-nonbundle.scala -pos/package-ob-case -pos/t1786-counter.scala -pos/reflection-compat-api-universe.scala -pos/existential-java-case-class -pos/t1786-cycle.scala -pos/reflection-compat-c.scala -pos/t3452f.scala -pos/reflection-compat-ru.scala -pos/t2066-2.10-compat.scala -pos/reflection-compat-macro-universe.scala -pos/t5900a.scala -pos/t5760-pkgobj-warn -pos/t5954a -pos/t5954b -pos/t5954d -pos/t6260.scala -pos/t5165b -pos/t5954c -pos/t6260b.scala -pos/t7475b.scala -pos/t7475a.scala -pos/t7753.scala -pos/t7322.scala -pos/t6948.scala -pos/t7475d.scala -pos/t7475e.scala -pos/t6169 -pos/t7788.scala -pos/t7919.scala -pos/t8177a.scala -pos/t8177.scala -pos/t8170.scala -pos/t8170b.scala -pos/t8177d.scala -pos/t8177b.scala -pos/t8177e.scala -pos/t8134 -pos/t8177h.scala -pos/t8177g.scala -pos/t8207.scala -pos/t8187.scala -pos/t8219.scala -pos/t8219b.scala -pos/t8224.scala -pos/t8237.scala -pos/t8223.scala -pos/t8237b.scala -pos/t8300-conversions-a.scala -pos/t8300-conversions-b.scala -pos/t8209a -pos/t8209b -pos/t8244d -pos/t8300-overloading.scala -pos/t8300-patmat-a.scala -pos/t8300-patmat-b.scala -pos/t8301.scala -pos/t8324.scala -pos/t8301b.scala -pos/t8363.scala -pos/t8367.scala -pos/t8369a.scala -pos/t8369b.scala -pos/t8403.scala -pos/t8364.scala -pos/t8352 -pos/t8376 -neg/macro-bundle-nonpublic-c.scala -neg/literate_existentials.scala -neg/macro-bundle-nonpublic-impl.scala -neg/macro-bundle-ambiguous.scala -neg/macro-bundle-priority-bundle.scala -neg/macro-bundle-need-qualifier.scala -neg/macro-bundle-nonstatic.scala -neg/macro-bundle-polymorphic.scala -neg/macro-bundle-priority-nonbundle.scala -neg/macro-bundle-wrongcontext-a.scala -neg/macro-bundle-wrongcontext-b.scala -run/t8425 -run/t8245.scala -run/t8266-octal-interp.scala -run/t8280.scala -run/t8395.scala -run/t8321 -run/t8153.scala -run/t8197.scala -run/t8197b.scala -run/t8233.scala -run/t8133 -run/t8133b -run/t7475b.scala -run/t6814 -run/t4577.scala -run/t5134.scala -run/t3452f.scala -run/t3452h.scala -run/t3452c.scala -run/t3452.scala -run/t261.scala -run/t3235-minimal.scala -run/t1503_future.scala -run/t5565.scala -pos/t8411 -pos/t8460.scala -run/t8428.scala -run/t8437 -run/absoverride.scala -run/arrays.scala -run/duration-coarsest.scala -run/iterator-from.scala -run/SymbolsTest.scala -run/t1074.scala -run/t1505.scala -run/streams.scala -run/t2111.scala -run/t4601.scala -neg/t3692-new.scala -run/t7015.scala -run/t7992b.scala -run/t7992.scala -run/t8570.scala -pos/t8157-2.10.scala -pos/t8325.scala -pos/t8523.scala -pos/t8578.scala -pos/t8329.scala -pos/t8497 -pos/t8546.scala -pos/t8531 -neg/t8325-c.scala -neg/t8325-b.scala -neg/t8325.scala -neg/t6988.scala -neg/t8463.scala -neg/t8450.scala -neg/t8430.scala -run/finally.scala -neg/t8630.scala -neg/t8035-no-adapted-args.scala -neg/t8675b.scala -neg/t8610-arg.scala -neg/t8736-c.scala -neg/tailrec-4.scala -neg/double-def-top-level -neg/t8610.scala -neg/aladdin1055 -neg/virtpatmat_exhaust_compound.scala -neg/t8675.scala -neg/t8525.scala -pos/t8736.scala -pos/t8625.scala -pos/t8596.scala -pos/t8617.scala -pos/t8736-b.scala -pos/t8708 -pos/macro-attachments -run/t8611a.scala -run/t8738.scala -run/macro-rangepos-args -run/t8610.scala -run/macro-rangepos-subpatterns -run/t8611c.scala -run/macroPlugins-isBlackbox -run/t8601d.scala -run/t8607.scala -run/bugs.scala -run/t1503.scala -run/t4148.scala -run/t7763.scala -run/issue192.scala -run/t8893b.scala -run/t8845.scala -run/t8933 -run/t7459c.scala -run/t9003.scala -run/t7459f.scala -run/t8933c.scala -run/t1994.scala -run/t2866.scala -run/t5665.scala -run/t7459d.scala -run/t8933b -run/t8888.scala -run/t7459b-optimize.scala -run/t7459a.scala -run/t7019.scala -run/t8893.scala -run/t8803.scala -run/t7459b.scala -run/t8823.scala -run/t6541.scala -run/nothingTypeDce.scala -run/t8680.scala -run/t8925.scala -run/nothingTypeNoOpt.scala -run/t9030.scala -run/bigDecimalTest.scala -run/bigDecimalCache.scala -run/range.scala -run/t6064.scala -run/t7521 -run/t8710.scala -run/t8575.scala -run/t8944 -run/t8944b.scala -run/t9387.scala -run/t9387b.scala -pos/t7784.scala -pos/t8862a.scala -pos/t9074.scala -pos/t8462.scala -pos/t8862b.scala -pos/alladin763.scala -pos/t6778.scala -pos/t9074b.scala -pos/t9326a.scala -pos/t9131.scala -pos/t9393 -pos/t9392 -neg/missing-arg-list.scala -neg/deprecated-target.scala -neg/t8777.scala -neg/t8892.scala -neg/t8849.scala -neg/inlineIndyLambdaPrivate -run/t9029.scala -run/t7850c.scala -run/t7850d.scala -run/t8334.scala -run/t9029c.scala -run/t9029b.scala -run/t9422.scala -run/t9425.scala -pos/t9475.scala -pos/t9498.scala -pos/t9479.scala -pos/t9479b.scala -pos/t9442.scala -pos/t9369.scala -pos/t6666d.scala -pos/t9370 -neg/t6810.scala -neg/t8127a.scala -neg/t8989.scala -neg/t9401.scala -neg/implicit-ambiguous.scala -neg/implicit-ambiguous-2.scala -neg/implicit-ambiguous-invalid.scala -neg/warn-unused-imports -run/t7269.scala -run/equality.scala -run/number-parsing.scala -run/t6220.scala -run/mapConserve.scala -run/colltest.scala -run/t0412.scala -run/t6261.scala -run/java-erasure.scala -run/t5880.scala -run/t6197.scala -run/t4201.scala -run/t5608.scala -run/t3518.scala -run/t6198.scala -run/t2813.2.scala -pos/java-type-annotations -pos/sammy_infer_argtype_subtypes.scala -pos/sammy_ctor_arg.scala -pos/fun_undo_eta.scala -pos/sammy_inferargs.scala -pos/existental-slow-compile2.scala -pos/existential-slow-compile1.scala -pos/sammy_implicit.scala -pos/t9178b.scala -pos/t9449.scala -pos/t3234.scala -pos/t9542.scala -pos/t8429.scala -pos/t9658.scala -pos/t9630 -pos/t9399.scala -pos/t9411a.scala -pos/t9411b.scala -neg/partestInvalidFlag.scala -neg/sammy_error.scala -neg/sammy_disabled.scala -neg/sammy_overload.scala -neg/sammy_expected.scala -neg/t8700a -neg/t9527b.scala -neg/t9527a.scala -neg/t9572.scala -neg/t9535.scala -neg/t9629.scala -neg/optimiseDeprecated.scala -neg/t9398 -neg/outer-ref-checks.scala -neg/t8685.scala -neg/t8700b -run/t9349 -run/t9178a.scala -run/t9110.scala -run/sammy_cbn.scala -run/sammy_erasure_cce.scala -run/sammy_after_implicit_view.scala -run/sammy_restrictions_LMF.scala -run/sammy_vararg_cbn.scala -run/t7807.scala -run/sammy_return.scala -run/t9546.scala -run/t9546b.scala -run/lisp.scala -run/t9546c.scala -run/t9546d.scala -run/t9546e.scala -run/t9567.scala -run/t9567b.scala -run/trait-clonable.scala -run/t9567c.scala -run/trait-defaults-modules.scala -run/trait-defaults-modules3.scala -run/trait-defaults-modules2 -pos/functions.scala -pos/MailBox.scala -neg/t6289 -run/t4729 -run/t6114.scala -run/t1430 -pos/constant-warning.scala -pos/t2712-5.scala -pos/t2712-2.scala -pos/t2712-4.scala -pos/t2712-1.scala -pos/t2712-3.scala -pos/t2712-6.scala -pos/t5683.scala -pos/hkgadt.scala -pos/t2712-7.scala -pos/t9245.scala -pos/t7088.scala -pos/t8044.scala -pos/t9665.scala -pos/t9397.scala -pos/t5183.scala -pos/t8449 -neg/t8044-b.scala -neg/t8044.scala -neg/t2712-3.scala -neg/t2712-2.scala -neg/t2712-1.scala -neg/t9045.scala -neg/t8667.scala -neg/t9361.scala -neg/t9781.scala -neg/trait-no-native.scala -neg/hkgadt.scala -neg/t9684b.scala -neg/t9382.scala -neg/trait-defaults-super.scala -neg/t9684.scala -run/hashCodeStatics.scala -run/t9390d.scala -run/trait-static-clash.scala -run/t5568.scala -run/t6318_primitives.scala -pos/fields_widen_trait_var.scala -pos/sammy_extends_function.scala -pos/infer_override_def_args.scala -pos/t482.scala -pos/t8079b.scala -pos/t6161b.scala -pos/t5294b.scala -pos/t5294c.scala -pos/overloaded_ho_fun.scala -pos/t4914.scala -pos/trait_fields_dependent_conflict.scala -pos/t2377b -pos/trait_fields_dependent_rebind.scala -pos/t9855b.scala -pos/trait_fields_inherit_double_def.scala -pos/t9855.scala -pos/t8873.scala -pos/trait_fields_nested_private_object.scala -pos/trait_fields_nested_public_object.scala -pos/trait_fields_private_this.scala -pos/trait_fields_var_override_deferred.scala -pos/trait_fields_static_fwd.scala -pos/trait_fields_owners.scala -pos/trait_fields_volatile.scala -pos/trait_lazy_accessboundary.scala -pos/trait_fields_lambdalift.scala -pos/typevar-in-prefix.scala -pos/val_infer.scala -pos/lub-from-hell.scala -neg/t8079a.scala -neg/sd128 -neg/t9849.scala -neg/trait_fields_var_override.scala -neg/val_infer.scala -neg/val_sig_infer_match.scala -neg/trait_fields_deprecated_overriding.scala -neg/t9847.scala -neg/val_sig_infer_struct.scala -neg/trait_fields_conflicts.scala -neg/lub-from-hell-2.scala -run/t2946 -run/lazy_local_labels.scala -run/sd167.scala -run/t9841.scala -run/trait-fields-override-lazy.scala -run/trait_fields_init.scala -run/trait_fields_three_layer_overrides.scala -run/t9516.scala -run/t10032.scala -pos/sam_erasure_boundedwild.scala -pos/t10154.scala -pos/t10066.scala -pos/t10154b.scala -pos/t10093.scala -pos/t8040.scala -pos/t3772.scala -pos/t10206.scala -pos/t9331.scala -pos/userdefined_apply_poly_overload.scala -pos/userdefined_apply.scala -pos/trailing-commas.scala -neg/t10097.scala -neg/t10068.scala -neg/ambiguous-same.scala -neg/maxerrs.scala -neg/maxwarns.scala -neg/t10207.scala -neg/t10066.scala -neg/t3236-neg -neg/t3772.scala -neg/t8704.scala -neg/t8002-nested-scope.scala -neg/t10097b.scala -neg/trailing-commas.scala -neg/t9834.scala -neg/userdefined_apply.scala -neg/t8417.scala -neg/warn-unused-implicits.scala -neg/t7860.scala -neg/t8763.scala -neg/t9636.scala -neg/warn-unused-params.scala -neg/t9675.scala -neg/warn-unused-patvars.scala -run/t10069.scala -run/SD-290.scala -run/sd329.scala -run/t10072.scala -run/t10261 -run/t9114.scala -run/InferOverloadedPartialFunction.scala -run/t10069b.scala -pos/t5788.scala -pos/t10205.scala -pos/t7100.scala -pos/t4012-b.scala -pos/t7638.scala -pos/leibniz_liskov.scala -pos/t4012-a.scala -pos/dotless-targs-ranged.scala -neg/badtok-1-212.scala -neg/moduleClassReference.scala -neg/t5355.scala -neg/t10081.scala -neg/t6714.scala -neg/t10249 -run/macro-implicit-decorator -run/t10290.scala -run/t10298.scala -run/t10389.scala -run/t6714.scala -run/t9146.scala -run/wacky-value-classes.scala - -# Adapt checkfiles for (1.0).toString == "1" -run/Course-2002-01.scala -run/t0421-new.scala -run/runtime.scala -run/t0421-old.scala -run/spec-self.scala -run/t5552.scala -run/Course-2002-02.scala -run/Course-2002-04.scala -run/promotion.scala -run/t4617.scala -run/Course-2002-09.scala -run/t5866.scala -run/try-catch-unify.scala -run/impconvtimes.scala -run/Course-2002-10.scala -run/Course-2002-08.scala -run/MeterCaseClass.scala -run/Meter.scala -run/deeps.scala -run/caseClassHash.scala -run/interpolation.scala -run/interpolationMultiline1.scala -run/t9656.scala -pos/sd219.scala -pos/t9918 -pos/shapeless-regression.scala -pos/issue244.scala -pos/t9920.scala -pos/t9943.scala -neg/t5148.scala -run/sd242.scala -run/local_obj.scala -run/t9697.scala -run/t9920.scala -run/t9920c.scala -run/t9920d.scala -run/t9920b.scala -run/t9946a.scala -run/t9946c.scala -run/t9946b.scala -run/trait-super-calls.scala -pos/sd268.scala -pos/sd248 -pos/t6734.scala -pos/t10009.scala -pos/t7551 -pos/t6978 -pos/t7046-2 -neg/t9953.scala -neg/t7014 -neg/t7046-2 -neg/t7046 -run/t7046-1 -run/t7046-2 -pos/parallel-classloader.scala -pos/not-possible-cause.scala -pos/sip23-any.scala -pos/hk-existential-subtype.scala -pos/sip23-bounds.scala -pos/sip23-aliasing.scala -pos/any-vs-anyref.scala -pos/sip23-final.scala -pos/patmat-hk.scala -pos/sip23-folding.scala -pos/sip23-negative-literals.scala -pos/sip23-numeric-lub.scala -pos/sip23-no-widen.scala -pos/sip23-strings.scala -pos/sip23-override.scala -pos/sip23-singleton-sub.scala -pos/sip23-named-default.scala -pos/sip23-symbols.scala -pos/sip23-valueof-alias.scala -pos/sip23-valueof-covariance.scala -pos/sip23-singleton-conv.scala -pos/sip23-valueof-this.scala -pos/sip23-widen.scala -pos/t10088.scala -pos/t10195.scala -pos/t10185.scala -pos/sip23-narrow.scala -pos/sip23-narrow-no-empty-refinements.scala -pos/t10195b.scala -pos/t10238.scala -pos/t10197.scala -pos/t10372.scala -pos/t10159 -pos/t10213.scala -pos/t10296 -pos/t10288.scala -pos/t10296-before -pos/t10375.scala -pos/t10270 -pos/t10425.scala -pos/t10569.scala -pos/t10684.scala -pos/t3995.scala -pos/t10667.scala -pos/t4225b.scala -pos/t10528.scala -pos/t4225c.scala -pos/t5044.scala -pos/t5091.scala -pos/t4947.scala -pos/t5340.scala -pos/t5946.scala -pos/t4225.scala -pos/t5818.scala -pos/t8343.scala -pos/t6263.scala -pos/t8841.scala -pos/t900.scala -pos/t6895.scala -pos/t9122.scala -pos/t9291.scala -pos/warn-unused-params-not-implicits.scala -pos/t9647.scala -pos/t10568 -pos/t9220.scala -pos/t5638 -pos/t10387.scala -neg/names-defaults-neg-213.scala -neg/sip23-override.scala -neg/sip23-no-null-type.scala -neg/sip23-null.scala -neg/hk-typevar-unification.scala -neg/hk-existential-lb.scala -neg/sip23-uninitialized-0.scala -neg/annots-constant-neg -neg/sip23-symbols.scala -neg/sip23-uninitialized-2.scala -neg/sip23-tailrec.scala -neg/t10279.scala -neg/t10260 -neg/sip23-widen.scala -neg/names-defaults-neg-pu.scala -neg/sip23-uninitialized-1.scala -neg/t10530.scala -neg/sip23-uninitialized-3.scala -neg/t10545.scala -neg/t10661.scala -neg/t10678.scala -neg/t2712-8.scala -neg/t6934 -neg/t7187-2.13.scala -neg/t8237-default-pu.scala -neg/t8323.scala -neg/t9138.scala -neg/t10296-after -neg/t10270 -neg/t10296-warn -neg/t10296-both -neg/warn-useless-svuid.scala -run/literal-type-varargs.scala -run/implicit-caching.scala -run/abstype_implicits.scala -run/names-defaults-nest.scala -run/hk-typevar-unification.scala -run/sd455.scala -run/sd336.scala -run/sip23-initialization0.scala -run/sip23-cast-1.scala -run/sip23-implicit-resolution.scala -run/sip23-initialization1.scala -run/sip23-no-constant-folding.scala -run/sip23-macro-eval -run/sip23-rangepos.scala -run/sip23-singleton-isas.scala -run/sip23-patterns.scala -run/sip23-rec-constant.scala -run/sip23-type-equality.scala -run/t10283.scala -run/sip23-valueof.scala -run/sip23-widen2.scala -run/t10291.scala -run/t10423 -run/t10439.scala -run/t10545.scala -run/t10454-1 -run/t10454-2 -run/t10611.scala -run/t4225d.scala -run/t1980.scala -run/t4225e.scala -run/t7187-2.13.scala -run/t8564.scala - -# Adapt checkfiles for ().toString == "undefined" -run/t5680.scala -run/dynamic-anyval.scala -run/macro-bundle-toplevel -run/macro-bundle-whitebox-decl -run/t6662 -run/t8570a.scala -run/t3702.scala -run/t7657 -run/macro-bundle-static -run/structural.scala - -# Adapt checkfiles for print & flush (which we cannot 100% emulate) -run/imports.scala -run/misc.scala - -# Adapt checkfiles for compiler phase list -neg/t7494-no-options -neg/t6446-list -neg/t6446-missing -neg/t6446-show-phases.scala -neg/t6446-additional - -# Adapt checkfiles for different behavior with boxed types -run/virtpatmat_typetag.scala -run/virtpatmat_switch.scala -run/t5629b.scala -run/t5356.scala -run/anyval-box-types.scala diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t6446-additional.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t6446-additional.check deleted file mode 100644 index b7ce23da2f..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t6446-additional.check +++ /dev/null @@ -1,30 +0,0 @@ - phase name id description - ---------- -- ----------- - parser 1 parse source into ASTs, perform simple desugaring - jspretyper 2 capture pre-typer only tree info (for Scala.js) - namer 3 resolve names, attach symbols to named trees -packageobjects 4 load package objects - typer 5 the meat and potatoes: type the trees - jsinterop 6 prepare ASTs for JavaScript interop - patmat 7 translate match expressions -superaccessors 8 add super accessors in traits and nested classes - extmethods 9 add extension methods for inline classes - pickler 10 serialize symbol tables - refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - fields 13 synthesize accessors and fields, add bitmaps for lazy vals - tailcalls 14 replace tail calls by jumps - specialize 15 @specialized-driven class and method specialization - explicitouter 16 this refs to outer pointers - erasure 17 erase types, add interfaces for traits - posterasure 18 clean up erased inline classes - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - jvm 26 generate JVM bytecode - ploogin 27 A sample phase that does so many things it's kind of hard... - terminal 28 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t6446-list.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t6446-list.check deleted file mode 100644 index 95883c8c81..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t6446-list.check +++ /dev/null @@ -1,2 +0,0 @@ -ploogin - A sample plugin for testing. -scalajs - Compile to JavaScript diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t6446-missing.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t6446-missing.check deleted file mode 100644 index 56b74a3128..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t6446-missing.check +++ /dev/null @@ -1,30 +0,0 @@ -Error: unable to load class: t6446.Ploogin - phase name id description - ---------- -- ----------- - parser 1 parse source into ASTs, perform simple desugaring - jspretyper 2 capture pre-typer only tree info (for Scala.js) - namer 3 resolve names, attach symbols to named trees -packageobjects 4 load package objects - typer 5 the meat and potatoes: type the trees - jsinterop 6 prepare ASTs for JavaScript interop - patmat 7 translate match expressions -superaccessors 8 add super accessors in traits and nested classes - extmethods 9 add extension methods for inline classes - pickler 10 serialize symbol tables - refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - fields 13 synthesize accessors and fields, add bitmaps for lazy vals - tailcalls 14 replace tail calls by jumps - specialize 15 @specialized-driven class and method specialization - explicitouter 16 this refs to outer pointers - erasure 17 erase types, add interfaces for traits - posterasure 18 clean up erased inline classes - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - jvm 26 generate JVM bytecode - terminal 27 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t6446-show-phases.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t6446-show-phases.check deleted file mode 100644 index cde255e3b1..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t6446-show-phases.check +++ /dev/null @@ -1,29 +0,0 @@ - phase name id description - ---------- -- ----------- - parser 1 parse source into ASTs, perform simple desugaring - jspretyper 2 capture pre-typer only tree info (for Scala.js) - namer 3 resolve names, attach symbols to named trees -packageobjects 4 load package objects - typer 5 the meat and potatoes: type the trees - jsinterop 6 prepare ASTs for JavaScript interop - patmat 7 translate match expressions -superaccessors 8 add super accessors in traits and nested classes - extmethods 9 add extension methods for inline classes - pickler 10 serialize symbol tables - refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - fields 13 synthesize accessors and fields, add bitmaps for lazy vals - tailcalls 14 replace tail calls by jumps - specialize 15 @specialized-driven class and method specialization - explicitouter 16 this refs to outer pointers - erasure 17 erase types, add interfaces for traits - posterasure 18 clean up erased inline classes - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - jvm 26 generate JVM bytecode - terminal 27 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t7494-no-options.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t7494-no-options.check deleted file mode 100644 index d8be421e5e..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/neg/t7494-no-options.check +++ /dev/null @@ -1,31 +0,0 @@ -error: Error: ploogin takes no options - phase name id description - ---------- -- ----------- - parser 1 parse source into ASTs, perform simple desugaring - jspretyper 2 capture pre-typer only tree info (for Scala.js) - namer 3 resolve names, attach symbols to named trees -packageobjects 4 load package objects - typer 5 the meat and potatoes: type the trees - jsinterop 6 prepare ASTs for JavaScript interop - patmat 7 translate match expressions -superaccessors 8 add super accessors in traits and nested classes - extmethods 9 add extension methods for inline classes - pickler 10 serialize symbol tables - refchecks 11 reference/override checking, translate nested objects - uncurry 12 uncurry, translate function values to anonymous classes - fields 13 synthesize accessors and fields, add bitmaps for lazy vals - tailcalls 14 replace tail calls by jumps - specialize 15 @specialized-driven class and method specialization - explicitouter 16 this refs to outer pointers - erasure 17 erase types, add interfaces for traits - posterasure 18 clean up erased inline classes - lambdalift 19 move nested functions to top level - constructors 20 move field definitions into constructors - flatten 21 eliminate inner classes - mixin 22 mixin composition - jscode 23 generate JavaScript code from ASTs - cleanup 24 platform-specific cleanups, generate reflective calls - delambdafy 25 remove lambdas - jvm 26 generate JVM bytecode - ploogin 27 A sample phase that does so many things it's kind of hard... - terminal 28 the last phase during a compilation run diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-01.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-01.check deleted file mode 100644 index fcda9433de..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-01.check +++ /dev/null @@ -1,37 +0,0 @@ -Course-2002-01.scala:41: warning: method loop in object M0 does nothing other than call itself recursively - def loop: Int = loop; - ^ -232 -667 -11 -10 -62.8318 -62.8318 -62.8318 -4 -81 -256 -25 -1 -737 -1 -0 -1 -76 -1.4142156862745097 -1.7321428571428572 -2.0000000929222947 -1.4142156862745097 -1.7321428571428572 -2.0000000929222947 -1.4142156862745097 -1.7321428571428572 -2.0000000929222947 -sqrt(2) = 1.4142135623746899 -sqrt(2) = 1.4142135623746899 -cbrt(2) = 1.2599210500177698 -1 -1 1 -1 2 1 -1 3 3 1 -1 4 6 4 1 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-02.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-02.check deleted file mode 100644 index ab75cfdb61..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-02.check +++ /dev/null @@ -1,187 +0,0 @@ -7 -120 - -10 -100 -2.083333333333333 -3025.7687714031754 -pi = 3.1659792728432152 - -10 -100 -2.083333333333333 -3025.7687714031754 -pi = 3.1659792728432152 - -10 -100 -2.083333333333333 -3025.7687714031754 -pi = 3.1659792728432152 - -10 -100 -2.083333333333333 -3025.7687714031754 -pi = 3.1659792728432152 - -10 -100 -2.083333333333333 -3025.7687714031754 -pi = 3.1659792728432152 - -10 -100 -2.083333333333333 -3025.7687714031754 -pi = 3.1659792728432152 - -10 -100 -2.083333333333333 -3025.7687714031754 -pi = 3.1659792728432152 - -pi = 3.181104885577714 -pi = 3.181104885577714 - -10 -100 -2.083333333333333 -3025.7687714031754 -pi = 3.1659792728432152 -pi = 3.181104885577714 -pi = 3.181104885577714 - -1.5 -1.4166666666666665 -1.4142156862745097 -1.4142135623746899 -sqrt(2) = 1.4142135623746899 - -1.5 -1.4166666666666665 -1.4142156862745097 -1.4142135623746899 -sqrt(2) = 1.4142135623746899 - -1 + 2 + .. + 5 = 15 -1 * 2 * .. * 5 = 120 - -1^2 + 2^2 + .. + 5^2 = 55 -1^2 * 2^2 * .. * 5^2 = 14400 - -factorial(0) = 1 -factorial(1) = 1 -factorial(2) = 2 -factorial(3) = 6 -factorial(4) = 24 -factorial(5) = 120 - -1 + 2 + .. + 5 = 15 -1 * 2 * .. * 5 = 120 - -1^2 + 2^2 + .. + 5^2 = 55 -1^2 * 2^2 * .. * 5^2 = 14400 - -factorial(0) = 1 -factorial(1) = 1 -factorial(2) = 2 -factorial(3) = 6 -factorial(4) = 24 -factorial(5) = 120 - -1 + 2 + .. + 5 = 15 -1 * 2 * .. * 5 = 120 - -1^2 + 2^2 + .. + 5^2 = 55 -1^2 * 2^2 * .. * 5^2 = 14400 - -factorial(0) = 1 -factorial(1) = 1 -factorial(2) = 2 -factorial(3) = 6 -factorial(4) = 24 -factorial(5) = 120 - -fib(0) = 0 -fib(1) = 1 -fib(2) = 1 -fib(3) = 2 -fib(4) = 3 -fib(5) = 5 -fib(6) = 8 -fib(7) = 13 -fib(8) = 21 -fib(9) = 34 -fib(0) = 0 -fib(1) = 1 -fib(2) = 1 -fib(3) = 2 -fib(4) = 3 -fib(5) = 5 -fib(6) = 8 -fib(7) = 13 -fib(8) = 21 -fib(9) = 34 -power(0,0) = 1 -power(0,1) = 0 -power(0,2) = 0 -power(0,3) = 0 -power(0,4) = 0 -power(0,5) = 0 -power(0,6) = 0 -power(0,7) = 0 -power(0,8) = 0 - -power(1,0) = 1 -power(1,1) = 1 -power(1,2) = 1 -power(1,3) = 1 -power(1,4) = 1 -power(1,5) = 1 -power(1,6) = 1 -power(1,7) = 1 -power(1,8) = 1 - -power(2,0) = 1 -power(2,1) = 2 -power(2,2) = 4 -power(2,3) = 8 -power(2,4) = 16 -power(2,5) = 32 -power(2,6) = 64 -power(2,7) = 128 -power(2,8) = 256 - -power(3,0) = 1 -power(3,1) = 3 -power(3,2) = 9 -power(3,3) = 27 -power(3,4) = 81 -power(3,5) = 243 -power(3,6) = 729 -power(3,7) = 2187 -power(3,8) = 6561 - -power(4,0) = 1 -power(4,1) = 4 -power(4,2) = 16 -power(4,3) = 64 -power(4,4) = 256 -power(4,5) = 1024 -power(4,6) = 4096 -power(4,7) = 16384 -power(4,8) = 65536 - -power(5,0) = 1 -power(5,1) = 5 -power(5,2) = 25 -power(5,3) = 125 -power(5,4) = 625 -power(5,5) = 3125 -power(5,6) = 15625 -power(5,7) = 78125 -power(5,8) = 390625 - diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-04.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-04.check deleted file mode 100644 index fc6ad96eed..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-04.check +++ /dev/null @@ -1,64 +0,0 @@ -list0 = List(6, 3, 1, 8, 7, 1, 2, 5, 8, 4, 3, 4, 8) -list1 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) -list2 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) -list3 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) -list4 = List(1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8) -list5 = List(8, 8, 8, 7, 6, 5, 4, 4, 3, 3, 2, 1, 1) -list6 = List(8, 8, 8, 7, 6, 5, 4, 4, 3, 3, 2, 1, 1) - -list0: List() -> List() -list1: List(0) -> List(0) -list2: List(0, 1) -> List(0, 1) -list3: List(1, 0) -> List(0, 1) -list4: List(0, 1, 2) -> List(0, 1, 2) -list5: List(1, 0, 2) -> List(0, 1, 2) -list6: List(0, 1, 2) -> List(0, 1, 2) -list7: List(1, 0, 2) -> List(0, 1, 2) -list8: List(2, 0, 1) -> List(0, 1, 2) -list9: List(2, 1, 0) -> List(0, 1, 2) -listA: List(6, 3, 1, 8, 7, 1, 2, 5, 8, 4) -> List(1, 1, 2, 3, 4, 5, 6, 7, 8, 8) - -f(x) = 5x^3+7x^2+5x+9 -f(0) = 9 -f(1) = 26 -f(2) = 87 -f(3) = 222 - -v1 = List(2, 3, 4) -v2 = List(6, 7, 8) - -id = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) -m1 = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) -m2 = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) - -v1 * v1 = 29 -v1 * v2 = 65 -v2 * v1 = 65 -v1 * v2 = 65 - -id * v1 = List(2, 3, 4) -m1 * v1 = List(4, 6, 8) -m2 * v1 = List(20, 47, 74) - -trn(id) = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) -trn(m1) = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) -trn(m2) = List(List(1, 4, 7), List(2, 5, 8), List(3, 6, 9)) - -List(v1) * id = List(List(2, 3, 4)) -List(v1) * m1 = List(List(4, 6, 8)) -List(v1) * m2 = List(List(42, 51, 60)) - -id * List(v1) = List(List(2, 3, 4), List(0, 0, 0), List(0, 0, 0)) -m1 * List(v1) = List(List(4, 6, 8), List(0, 0, 0), List(0, 0, 0)) -m2 * List(v1) = List(List(2, 3, 4), List(8, 12, 16), List(14, 21, 28)) - -id * id = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) -id * m1 = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) -m1 * id = List(List(2, 0, 0), List(0, 2, 0), List(0, 0, 2)) -m1 * m1 = List(List(4, 0, 0), List(0, 4, 0), List(0, 0, 4)) -id * m2 = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) -m2 * id = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) -m1 * m2 = List(List(2, 4, 6), List(8, 10, 12), List(14, 16, 18)) -m2 * m1 = List(List(2, 4, 6), List(8, 10, 12), List(14, 16, 18)) -m2 * m2 = List(List(30, 36, 42), List(66, 81, 96), List(102, 126, 150)) - diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-08.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-08.check deleted file mode 100644 index 0585d5b44f..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-08.check +++ /dev/null @@ -1,171 +0,0 @@ -x = abc -count = 111 -x = hello -count = 112 - -account deposit 50 -> undefined -account withdraw 20 -> 30 -account withdraw 20 -> 10 -account withdraw 15 -> - -x deposit 30 -> undefined -y withdraw 20 -> - -x deposit 30 -> undefined -x withdraw 20 -> 10 - -x deposit 30 -> undefined -y withdraw 20 -> 10 - -2^0 = 1 -2^1 = 2 -2^2 = 4 -2^3 = 8 - -2^0 = 1 -2^1 = 2 -2^2 = 4 -2^3 = 8 - -1 2 3 -List(1, 2, 3) - -out 0 new-value = false -*** simulation started *** -out 1 new-value = true -!0 = 1 - -*** simulation started *** -out 2 new-value = false -!1 = 0 - -out 2 new-value = false - -*** simulation started *** -0 & 0 = 0 - -*** simulation started *** -0 & 1 = 0 - -*** simulation started *** -out 11 new-value = true -out 11 new-value = false -1 & 0 = 0 - -*** simulation started *** -out 14 new-value = true -1 & 1 = 1 - -out 14 new-value = false - -*** simulation started *** -0 | 0 = 0 - -*** simulation started *** -out 24 new-value = true -0 | 1 = 1 - -*** simulation started *** -1 | 0 = 1 - -*** simulation started *** -1 | 1 = 1 - -sum 34 new-value = false -carry 34 new-value = false - -*** simulation started *** -0 + 0 = 0 - -*** simulation started *** -sum 47 new-value = true -0 + 1 = 1 - -*** simulation started *** -carry 50 new-value = true -carry 50 new-value = false -sum 54 new-value = false -sum 54 new-value = true -1 + 0 = 1 - -*** simulation started *** -carry 57 new-value = true -sum 61 new-value = false -1 + 1 = 2 - -sum 61 new-value = false -carry 61 new-value = false - -*** simulation started *** -0 + 0 + 0 = 0 - -*** simulation started *** -sum 82 new-value = true -0 + 0 + 1 = 1 - -*** simulation started *** -sum 89 new-value = false -carry 90 new-value = true -sum 97 new-value = true -carry 98 new-value = false -0 + 1 + 0 = 1 - -*** simulation started *** -sum 113 new-value = false -carry 114 new-value = true -0 + 1 + 1 = 2 - -*** simulation started *** -sum 121 new-value = true -carry 122 new-value = false -sum 129 new-value = false -sum 129 new-value = true -1 + 0 + 0 = 1 - -*** simulation started *** -carry 137 new-value = true -sum 144 new-value = false -1 + 0 + 1 = 2 - -*** simulation started *** -carry 152 new-value = false -sum 152 new-value = true -sum 158 new-value = false -carry 159 new-value = true -1 + 1 + 0 = 2 - -*** simulation started *** -sum 173 new-value = true -1 + 1 + 1 = 3 - -in 0 new-value = false -ctrl0 0 new-value = false -ctrl1 0 new-value = false -ctrl2 0 new-value = false -out0 0 new-value = false -out1 0 new-value = false -out2 0 new-value = false -out3 0 new-value = false -out4 0 new-value = false -out5 0 new-value = false -out6 0 new-value = false -out7 0 new-value = false -in 0 new-value = true -*** simulation started *** -out0 10 new-value = true -ctrl0 10 new-value = true -*** simulation started *** -out1 13 new-value = true -out0 14 new-value = false -ctrl1 14 new-value = true -*** simulation started *** -out3 20 new-value = true -out1 21 new-value = false -ctrl2 21 new-value = true -*** simulation started *** -out7 30 new-value = true -out3 31 new-value = false -ctrl0 31 new-value = false -*** simulation started *** -out7 34 new-value = false -out6 35 new-value = true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-09.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-09.check deleted file mode 100644 index c921361db7..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-09.check +++ /dev/null @@ -1,50 +0,0 @@ -Probe: f = 32 -Probe: c = 0 -Probe: f = ? -Probe: c = ? - -Probe: f = 212 -Probe: c = 100 -Probe: f = ? -Probe: c = ? - -Probe: c = 0 -Probe: f = 32 -Probe: c = ? -Probe: f = ? - -Probe: c = 100 -Probe: f = 212 -Probe: c = ? -Probe: f = ? - -0 Celsius -> 32 Fahrenheits -100 Celsius -> 212 Fahrenheits -32 Fahrenheits -> 0 Celsius -212 Fahrenheits -> 100 Celsius - -a = ?, b = ?, c = ? => ? * ? = ? -a = 2, b = ?, c = ? => 2 * ? = ? -a = ?, b = 3, c = ? => ? * 3 = ? -a = ?, b = ?, c = 6 => ? * ? = 6 -a = 2, b = 3, c = ? => 2 * 3 = 6 -a = 2, b = ?, c = 6 => 2 * 3 = 6 -a = ?, b = 3, c = 6 => 2 * 3 = 6 -a = 2, b = 3, c = 6 => 2 * 3 = 6 - -a = 0, b = ?, c = ? => 0 * ? = 0 -a = ?, b = 0, c = ? => ? * 0 = 0 -a = ?, b = ?, c = 0 => ? * ? = 0 -a = 0, b = 7, c = ? => 0 * 7 = 0 -a = 7, b = 0, c = ? => 7 * 0 = 0 -a = 0, b = 0, c = ? => 0 * 0 = 0 -a = 0, b = ?, c = 0 => 0 * ? = 0 -a = ?, b = 0, c = 0 => ? * 0 = 0 -a = 0, b = 7, c = 0 => 0 * 7 = 0 -a = 7, b = 0, c = 0 => 7 * 0 = 0 -a = 0, b = 0, c = 0 => 0 * 0 = 0 - -a = 3, b = 4 => c = 5 -a = 3, c = 5 => b = 4 -b = 4, c = 5 => a = 3 - diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-10.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-10.check deleted file mode 100644 index 847f0fa703..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Course-2002-10.check +++ /dev/null @@ -1,46 +0,0 @@ -fib(0) = 0 -fib(1) = 1 -fib(2) = 1 -fib(3) = 2 -fib(4) = 3 -fib(5) = 5 -fib(6) = 8 -fib(7) = 13 -fib(8) = 21 -fib(9) = 34 -fib(10) = 55 -fib(11) = 89 -fib(12) = 144 -fib(13) = 233 -fib(14) = 377 -fib(15) = 610 -fib(16) = 987 -fib(17) = 1597 -fib(18) = 2584 -fib(19) = 4181 - -pi(0) = 4 , 3.166666666666667 , 4 -pi(1) = 2.666666666666667 , 3.1333333333333337, 3.166666666666667 -pi(2) = 3.466666666666667 , 3.1452380952380956, 3.142105263157895 -pi(3) = 2.8952380952380956, 3.1396825396825396, 3.1415993573190044 -pi(4) = 3.33968253968254 , 3.142712842712843 , 3.141592714033778 -pi(5) = 2.976046176046176 , 3.140881340881341 , 3.1415926539752923 -pi(6) = 3.283738483738484 , 3.142071817071817 , 3.141592653591176 -pi(7) = 3.017071817071817 , 3.1412548236077646, 3.141592653589777 -pi(8) = 3.252365934718876 , 3.1418396189294024, 3.141592653589794 -pi(9) = 3.0418396189294024, 3.141406718496502 , 3.1415926535897936 -pi = 3.141592653589793 , 3.141592653589793 , 3.141592653589793 - -ln(0) = 1 , 0.7 , 1 -ln(1) = 0.5 , 0.6904761904761905, 0.7 -ln(2) = 0.8333333333333333, 0.6944444444444444, 0.6932773109243697 -ln(3) = 0.5833333333333333, 0.6924242424242424, 0.6931488693329254 -ln(4) = 0.7833333333333333, 0.6935897435897436, 0.6931471960735491 -ln(5) = 0.6166666666666667, 0.6928571428571428, 0.6931471806635636 -ln(6) = 0.7595238095238095, 0.6933473389355742, 0.6931471805604038 -ln(7) = 0.6345238095238095, 0.6930033416875522, 0.6931471805599444 -ln(8) = 0.7456349206349207, 0.6932539682539682, 0.6931471805599426 -ln(9) = 0.6456349206349206, 0.6930657506744463, 0.6931471805599453 -ln = 0.6931471805599453, 0.6931471805599453, 0.6931471805599453 - -prime numbers: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Meter.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Meter.check deleted file mode 100644 index f46fd557c8..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/Meter.check +++ /dev/null @@ -1,16 +0,0 @@ -Meter.scala:72: warning: a.Meter and Int are unrelated: they will never compare equal - println("x == 1: "+(x == 1)) - ^ -2 -4m -false -x.isInstanceOf[Meter]: true -x.hashCode: 1 -x == 1: false -x == y: true -a == b: true -testing native arrays -Array(1m, 2m) -1m ->>>1m<<< 1m ->>>2m<<< 2m diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/MeterCaseClass.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/MeterCaseClass.check deleted file mode 100644 index ac538d240f..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/MeterCaseClass.check +++ /dev/null @@ -1,16 +0,0 @@ -MeterCaseClass.scala:69: warning: comparing values of types a.Meter and Int using `==' will always yield false - println("x == 1: "+(x == 1)) - ^ -2 -Meter(4) -false -x.isInstanceOf[Meter]: true -x.hashCode: 1 -x == 1: false -x == y: true -a == b: true -testing native arrays -Array(Meter(1), Meter(2)) -Meter(1) ->>>Meter(1)<<< Meter(1) ->>>Meter(2)<<< Meter(2) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/anyval-box-types.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/anyval-box-types.check deleted file mode 100644 index b2d758c906..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/anyval-box-types.check +++ /dev/null @@ -1,52 +0,0 @@ -true -1 -true -1 -true --1 -true -1 -true -false -true -true -false -false - -true -2 -true -2 -true --1 -true -2 -true -false -false -false -false - -true -true -false -true -1 -true -true -true -false -false -false - -true -つ -false -true -true -true -つ -true -false -false -false diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/bugs.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/bugs.sem deleted file mode 100644 index d36898b932..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/bugs.sem +++ /dev/null @@ -1 +0,0 @@ -asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/caseClassHash.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/caseClassHash.check deleted file mode 100644 index f975151e9c..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/caseClassHash.check +++ /dev/null @@ -1,9 +0,0 @@ -Foo(true,-1,-1,d,-5,-10,500,500,List(),5) -Foo(true,-1,-1,d,-5,-10,500,500,List(),5) -1383698062 -1383698062 -true -## method 1: 1383698062 -## method 2: 1383698062 - Murmur 1: 1383698062 - Murmur 2: 1383698062 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/deeps.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/deeps.check deleted file mode 100644 index e533b87dc5..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/deeps.check +++ /dev/null @@ -1,87 +0,0 @@ -testEquals1 -false -false -true - -testEquals2 -false -false -true - -testEquals3 -x=Array(1) -y=Array(1) -false -false -true - -x=Array(Array(1), Array(1)) -y=Array(Array(1), Array(1)) -false -false -true - -x=Array(Array(Array(1), Array(1)), Array(Array(1), Array(1))) -y=Array(Array(Array(1), Array(1)), Array(Array(1), Array(1))) -false -false -true - -testEquals4 -false -false -true -false -false -true -Array(true, false) -Array(true, false) -[true;false] -true;false - -Array(Array(true, false), Array(true, false)) -Array(Array(true, false), Array(true, false)) -[Array(true, false);Array(true, false)] -Array(true, false);Array(true, false) - -Array(Array(Array(true, false), Array(true, false)), Array(Array(true, false), Array(true, false))) -Array(Array(Array(true, false), Array(true, false)), Array(Array(true, false), Array(true, false))) -[Array(Array(true, false), Array(true, false));Array(Array(true, false), Array(true, false))] -Array(Array(true, false), Array(true, false));Array(Array(true, false), Array(true, false)) - -Array(1, 0) -Array(1, 0) -[1;0] -1;0 - -Array(Array(1, 0), Array(1, 0)) -Array(Array(1, 0), Array(1, 0)) -[Array(1, 0);Array(1, 0)] -Array(1, 0);Array(1, 0) - -Array(Array(Array(1, 0), Array(1, 0)), Array(Array(1, 0), Array(1, 0))) -Array(Array(Array(1, 0), Array(1, 0)), Array(Array(1, 0), Array(1, 0))) -[Array(Array(1, 0), Array(1, 0));Array(Array(1, 0), Array(1, 0))] -Array(Array(1, 0), Array(1, 0));Array(Array(1, 0), Array(1, 0)) - -Array(a, b) -Array(a, b) -[a;b] -a;b - -Array(Array(a, b), Array(a, b)) -Array(Array(a, b), Array(a, b)) -[Array(a, b);Array(a, b)] -Array(a, b);Array(a, b) - -Array(Array(Array(a, b), Array(a, b)), Array(Array(a, b), Array(a, b))) -Array(Array(Array(a, b), Array(a, b)), Array(Array(a, b), Array(a, b))) -[Array(Array(a, b), Array(a, b));Array(Array(a, b), Array(a, b))] -Array(Array(a, b), Array(a, b));Array(Array(a, b), Array(a, b)) - -[Array(true, false); Array(false)] -[Array(1, 2); Array(3)] -[Array(1, 2); Array(3)] - -Array(boo, and, foo) -Array(a) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/dynamic-anyval.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/dynamic-anyval.check deleted file mode 100644 index c125372c9a..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/dynamic-anyval.check +++ /dev/null @@ -1,4 +0,0 @@ -undefined.dingo(bippy, 5) -List(1, 2, 3).dingo(bippy, 5) -undefined.dingo(bippy, 5) -List(1, 2, 3).dingo(bippy, 5) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/impconvtimes.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/impconvtimes.check deleted file mode 100644 index 082377e474..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/impconvtimes.check +++ /dev/null @@ -1 +0,0 @@ -3.0 * Hour = Measure(3,Hour) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/imports.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/imports.check deleted file mode 100644 index 1aad598062..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/imports.check +++ /dev/null @@ -1,21 +0,0 @@ -In C_ico, v_ico .toString() returns ↩ -↪C_ico -> ok -In C_ico, field .toString() returns ↩ -↪C_ico -> ok -In C_ico, method.toString() returns ↩ -↪C_ico -> ok - -In C_ioc, v_ioc .toString() returns ↩ -↪C_ioc -> ok -In C_ioc, field .toString() returns ↩ -↪C_ioc -> ok -In C_ioc, method.toString() returns ↩ -↪C_ioc -> ok - -In C_oic, v_oic .toString() returns ↩ -↪C_oic -> ok -In C_oic, field .toString() returns ↩ -↪C_oic -> ok -In C_oic, method.toString() returns ↩ -↪C_oic -> ok - diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/interpolation.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/interpolation.check deleted file mode 100644 index 9c4a77715b..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/interpolation.check +++ /dev/null @@ -1,32 +0,0 @@ -Bob is 1 years old -Bob is 1 years old -Bob will be 2 years old -Bob will be 2 years old -1+1 = 2 -1+1 = 2 -Bob is 12 years old -Bob is 12 years old -Bob will be 13 years old -Bob will be 13 years old -12+1 = 13 -12+1 = 13 -Bob is 123 years old -Bob is 123 years old -Bob will be 124 years old -Bob will be 124 years old -123+1 = 124 -123+1 = 124 -Best price: 10 -Best price: 10.00 -10% discount included -10.00% discount included -Best price: 13.345000267028809 -Best price: 13.35 -13.345000267028809% discount included -13.35% discount included - -0 -00 - -0 -00 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/interpolationMultiline1.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/interpolationMultiline1.check deleted file mode 100644 index 1b6e140c13..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/interpolationMultiline1.check +++ /dev/null @@ -1,26 +0,0 @@ -Bob is 1 years old -Bob is 1 years old -Bob will be 2 years old -Bob will be 2 years old -1+1 = 2 -1+1 = 2 -Bob is 12 years old -Bob is 12 years old -Bob will be 13 years old -Bob will be 13 years old -12+1 = 13 -12+1 = 13 -Bob is 123 years old -Bob is 123 years old -Bob will be 124 years old -Bob will be 124 years old -123+1 = 124 -123+1 = 124 -Best price: 10 -Best price: 10.00 -10% discount included -10.00% discount included -Best price: 13.345000267028809 -Best price: 13.35 -13.345000267028809% discount included -13.35% discount included diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/issue192.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/issue192.sem deleted file mode 100644 index 10abbf7f3b..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/issue192.sem +++ /dev/null @@ -1 +0,0 @@ -strictFloats diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/macro-bundle-static.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/macro-bundle-static.check deleted file mode 100644 index e2e7628a0d..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/macro-bundle-static.check +++ /dev/null @@ -1,6 +0,0 @@ -undefined -Int -undefined -true -IntInt -true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/macro-bundle-toplevel.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/macro-bundle-toplevel.check deleted file mode 100644 index e2e7628a0d..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/macro-bundle-toplevel.check +++ /dev/null @@ -1,6 +0,0 @@ -undefined -Int -undefined -true -IntInt -true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/macro-bundle-whitebox-decl.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/macro-bundle-whitebox-decl.check deleted file mode 100644 index e2e7628a0d..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/macro-bundle-whitebox-decl.check +++ /dev/null @@ -1,6 +0,0 @@ -undefined -Int -undefined -true -IntInt -true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/misc.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/misc.check deleted file mode 100644 index 85f37c51d7..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/misc.check +++ /dev/null @@ -1,62 +0,0 @@ -misc.scala:46: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses - 42; - ^ -misc.scala:47: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses - 42l; - ^ -misc.scala:48: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses - 23.5f; - ^ -misc.scala:49: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses - 23.5; - ^ -misc.scala:50: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses - "Hello"; - ^ -misc.scala:51: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses - 32 + 45; - ^ -misc.scala:62: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses - x; - ^ -misc.scala:74: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses - 1 < 2; - ^ -### Hello -### 17 -### Bye - -### fib(0) = ↩ -↪1 -### fib(1) = ↩ -↪1 -### fib(2) = ↩ -↪2 -### fib(3) = ↩ -↪3 -### fib(4) = ↩ -↪5 -=== MyClass::toString === -=== MySubclass::toString === -=== MyClass::test === - -identity - -A.a = 1 -B.a = 5 -B.b = 2 - -X.a = 4 -Y.a = 11 -Y.b = 5 -Y.b = 5 - -X::foo - -Y::foo -X::foo - -3 -3 - -true diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/promotion.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/promotion.check deleted file mode 100644 index 41e36c369d..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/promotion.check +++ /dev/null @@ -1,4 +0,0 @@ -2 -6 -20 -30 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/runtime.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/runtime.check deleted file mode 100644 index 0450b9498a..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/runtime.check +++ /dev/null @@ -1,70 +0,0 @@ -runtime.scala:141: warning: comparing values of types Null and Null using `eq' will always yield true - check(true , null eq null, null ne null); - ^ -runtime.scala:141: warning: comparing values of types Null and Null using `ne' will always yield false - check(true , null eq null, null ne null); - ^ -<<< Test0 -[false,true] -[0,1,2] -[3,4,5] -[a,b,c] -[6,7,8] -[9,10,11] -[12,13] -[14,15] -[string] ->>> Test0 - -<<< Test1 -10 -14 -15 -16 -20 -23 -24 -25 -26 ->>> Test1 - -<<< Test2 -A -M0 -N0 - -A -N0 -M0 - -A -M0 -M1 -N0 - -A -N0 -N1 -M0 - ->>> Test2 - -<<< Test3 -Ok -Ok -Ok -Ok -Ok -Ok -Ok -Ok -Ok -Ok -Ok -Ok -Ok -Ok -Ok -Ok ->>> Test3 - diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/spec-self.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/spec-self.check deleted file mode 100644 index fd3c81a4d7..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/spec-self.check +++ /dev/null @@ -1,2 +0,0 @@ -5 -5 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/structural.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/structural.check deleted file mode 100644 index 2fec112a87..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/structural.check +++ /dev/null @@ -1,37 +0,0 @@ - 1. hey - 2. 11 - 3. dee - 4. iei - 5. 6 - 6. 51 - 7. 2 - 8. 11 -10. 12 -11. eitch -12. 1 -13. ohone -14. 1 -15. undefined -16. one -17. tieone -18. 2 -19. true -20. 1 -21. undefined -22. one -23. oy -24. 1 -25. null -26. iei -31. 4 -32. undefined -33. iei -33. tieone -1 -2 -3 -4 -5 -caught -3 -2 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t0421-new.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t0421-new.check deleted file mode 100644 index 00d29b7e5b..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t0421-new.check +++ /dev/null @@ -1,3 +0,0 @@ -[Array(0, 1),Array(2, 3),Array(4, 5)] -[Array(31)] -[Array(24, 32)] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t0421-old.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t0421-old.check deleted file mode 100644 index 00d29b7e5b..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t0421-old.check +++ /dev/null @@ -1,3 +0,0 @@ -[Array(0, 1),Array(2, 3),Array(4, 5)] -[Array(31)] -[Array(24, 32)] diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t1503.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t1503.sem deleted file mode 100644 index d36898b932..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t1503.sem +++ /dev/null @@ -1 +0,0 @@ -asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t3702.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t3702.check deleted file mode 100644 index 3fce98715c..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t3702.check +++ /dev/null @@ -1,2 +0,0 @@ -undefined -6 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t4148.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t4148.sem deleted file mode 100644 index d36898b932..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t4148.sem +++ /dev/null @@ -1 +0,0 @@ -asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t4617.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t4617.check deleted file mode 100644 index a6790f16f7..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t4617.check +++ /dev/null @@ -1 +0,0 @@ -Str 8 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5356.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5356.check deleted file mode 100644 index 870c901131..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5356.check +++ /dev/null @@ -1,6 +0,0 @@ -1 java.lang.Byte -1 java.lang.Byte -1 scala.math.BigInt -1 java.lang.Byte -1 java.lang.Byte -1 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5552.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5552.check deleted file mode 100644 index 9e767b6d7b..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5552.check +++ /dev/null @@ -1,6 +0,0 @@ -lazy: 3 -(3,3) -(3,3) -lazy: 3 -(3,3) -(3,3) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5568.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5568.check deleted file mode 100644 index 6f30cc5070..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5568.check +++ /dev/null @@ -1,9 +0,0 @@ -void -int -class scala.runtime.BoxedUnit -class scala.runtime.BoxedUnit -class java.lang.Byte -class java.lang.Byte -5 -5 -5 diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5629b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5629b.check deleted file mode 100644 index c65298a6ce..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5629b.check +++ /dev/null @@ -1,10 +0,0 @@ -=== pf(1): -MySmartPF.apply entered... -newPF.applyOrElse entered... -default -scala.MatchError: 1 (of class java.lang.Byte) -=== pf(42): -MySmartPF.apply entered... -newPF.applyOrElse entered... -ok -=== done diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5680.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5680.check deleted file mode 100644 index a3b8b64a43..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5680.check +++ /dev/null @@ -1,3 +0,0 @@ -[Lscala.runtime.BoxedUnit -undefined -undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5866.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5866.check deleted file mode 100644 index 64df1cec7f..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t5866.check +++ /dev/null @@ -1,2 +0,0 @@ -0 -Foo(0) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t6318_primitives.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t6318_primitives.check deleted file mode 100644 index 654ef1beec..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t6318_primitives.check +++ /dev/null @@ -1,54 +0,0 @@ -Checking if byte matches byte -Some(1) -Checking if byte matches short -Some(1) -Checking if class java.lang.Byte matches byte -Some(1) -Checking if short matches short -Some(1) -Checking if short matches char -None -Checking if class java.lang.Byte matches short -Some(1) -Checking if char matches char -Some() -Checking if char matches int -None -Checking if class java.lang.Character matches char -Some() -Checking if int matches int -Some(1) -Checking if int matches long -None -Checking if class java.lang.Byte matches int -Some(1) -Checking if long matches long -Some(1) -Checking if long matches float -None -Checking if class java.lang.Long matches long -Some(1) -Checking if float matches float -Some(1) -Checking if float matches double -Some(1) -Checking if class java.lang.Byte matches float -Some(1) -Checking if double matches double -Some(1) -Checking if double matches boolean -None -Checking if class java.lang.Byte matches double -Some(1) -Checking if boolean matches boolean -Some(true) -Checking if boolean matches void -None -Checking if class java.lang.Boolean matches boolean -Some(true) -Checking if void matches void -Some(undefined) -Checking if void matches byte -None -Checking if class scala.runtime.BoxedUnit matches void -Some(undefined) diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t6662.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t6662.check deleted file mode 100644 index 417b7b5370..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t6662.check +++ /dev/null @@ -1 +0,0 @@ -undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t7657.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t7657.check deleted file mode 100644 index 1a87c1e866..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t7657.check +++ /dev/null @@ -1,3 +0,0 @@ -undefined -undefined -undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t7763.sem b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t7763.sem deleted file mode 100644 index d36898b932..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t7763.sem +++ /dev/null @@ -1 +0,0 @@ -asInstanceOfs diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t8570a.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t8570a.check deleted file mode 100644 index 417b7b5370..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t8570a.check +++ /dev/null @@ -1 +0,0 @@ -undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t8764.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t8764.check deleted file mode 100644 index 121120217e..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t8764.check +++ /dev/null @@ -1,5 +0,0 @@ -IntOnly: should return an unboxed int -Int: int -IntAndDouble: should just box and return Anyval -Double: class java.lang.Byte -Int: class java.lang.Byte diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t9387b.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t9387b.check deleted file mode 100644 index 417b7b5370..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t9387b.check +++ /dev/null @@ -1 +0,0 @@ -undefined diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t9656.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t9656.check deleted file mode 100644 index a16c04eaad..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/t9656.check +++ /dev/null @@ -1,14 +0,0 @@ -Range 1 to 10 -Range 1 to 10 -inexact Range 1 to 10 by 2 -Range 1 to 10 by 3 -inexact Range 1 until 10 by 2 -Range 100 to 100 -empty Range 100 until 100 -NumericRange 1 to 10 -NumericRange 1 to 10 by 2 -NumericRange 0.1 until 1 by 0.1 -NumericRange 0.1 until 1.0 by 0.1 -NumericRange 0.1 until 1 by 0.1 (using NumericRange 0.1 until 1 by 0.1 of BigDecimal) -NumericRange 0 days until 10 seconds by 1 second -empty NumericRange 0 days until 0 days by 1 second diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/try-catch-unify.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/try-catch-unify.check deleted file mode 100644 index 813f01166d..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/try-catch-unify.check +++ /dev/null @@ -1,4 +0,0 @@ -Failure(java.lang.NumberFormatException: For input string: "Hi") -Success(5) -O NOES -Failure(java.lang.NumberFormatException: For input string: "Hi") diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/virtpatmat_switch.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/virtpatmat_switch.check deleted file mode 100644 index 0900a9ca32..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/virtpatmat_switch.check +++ /dev/null @@ -1,7 +0,0 @@ -zero -one -many -got a -got b -got some letter -scala.MatchError: 5 (of class java.lang.Byte) \ No newline at end of file diff --git a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/virtpatmat_typetag.check b/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/virtpatmat_typetag.check deleted file mode 100644 index 048c3aeed0..0000000000 --- a/partest-suite/src/test/resources/scala/tools/partest/scalajs/2.13.0-M3/run/virtpatmat_typetag.check +++ /dev/null @@ -1,10 +0,0 @@ -1 is a Int -1 is a java.lang.Integer -1 is not a java.lang.String; it's a class java.lang.Byte -true is a Any -woele is a java.lang.String -1 is a Int -1 is a java.lang.Integer -1 is not a java.lang.String; it's a class java.lang.Byte -true is a Any -woele is a java.lang.String diff --git a/project/Build.scala b/project/Build.scala index 264338bae4..d534b3d867 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -71,24 +71,21 @@ object Build { def hasNewCollections(version: String): Boolean = { !version.startsWith("2.10.") && !version.startsWith("2.11.") && - !version.startsWith("2.12.") && - version != "2.13.0-M3" + !version.startsWith("2.12.") } /** Returns the appropriate subdirectory of `sourceDir` depending on the * collection "era" used by the `scalaV`. * - * It can be the new collections (2.13.0-M5+), the old collections (until - * 2.13.0-M3) or the intermediate "M4" collections (the transient state of - * the collections in 2.13.0-M4). + * It can be the new collections (2.13.x+) or the old collections (until + * 2.12.x). */ def collectionsEraDependentDirectory(scalaV: String, sourceDir: File): File = - if (scalaV == "2.13.0-M4") sourceDir / "scala-m4-collections" - else if (hasNewCollections(scalaV)) sourceDir / "scala-new-collections" + if (hasNewCollections(scalaV)) sourceDir / "scala-new-collections" else sourceDir / "scala-old-collections" val scalaVersionsUsedForPublishing: Set[String] = - Set("2.10.7", "2.11.12", "2.12.6", "2.13.0-M3") + Set("2.10.7", "2.11.12", "2.12.6") val newScalaBinaryVersionsInThisRelease: Set[String] = Set() diff --git a/scalalib/overrides-2.13.0-M3/scala/Array.scala b/scalalib/overrides-2.13.0-M3/scala/Array.scala deleted file mode 100644 index 22cace2c7a..0000000000 --- a/scalalib/overrides-2.13.0-M3/scala/Array.scala +++ /dev/null @@ -1,550 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala - -import scala.collection.generic._ -import scala.collection.{ mutable, immutable } -import mutable.{ ArrayBuilder, ArraySeq } -import java.lang.System.arraycopy -import scala.reflect.ClassTag -import scala.runtime.ScalaRunTime.{ array_apply, array_update } - -/** Contains a fallback builder for arrays when the element type - * does not have a class tag. In that case a generic array is built. - */ -class FallbackArrayBuilding { - - /** A builder factory that generates a generic array. - * Called instead of `Array.newBuilder` if the element type of an array - * does not have a class tag. Note that fallbackBuilder factory - * needs an implicit parameter (otherwise it would not be dominated in - * implicit search by `Array.canBuildFrom`). We make sure that - * implicit search is always successful. - */ - implicit def fallbackCanBuildFrom[T](implicit m: DummyImplicit): CanBuildFrom[Array[_], T, ArraySeq[T]] = - new CanBuildFrom[Array[_], T, ArraySeq[T]] { - def apply(from: Array[_]) = ArraySeq.newBuilder[T] - def apply() = ArraySeq.newBuilder[T] - } -} - -/** Utility methods for operating on arrays. - * For example: - * {{{ - * val a = Array(1, 2) - * val b = Array.ofDim[Int](2) - * val c = Array.concat(a, b) - * }}} - * where the array objects `a`, `b` and `c` have respectively the values - * `Array(1, 2)`, `Array(0, 0)` and `Array(1, 2, 0, 0)`. - * - * @author Martin Odersky - * @version 1.0 - */ -object Array extends FallbackArrayBuilding { - def emptyBooleanArray = EmptyArrays.emptyBooleanArray - def emptyByteArray = EmptyArrays.emptyByteArray - def emptyCharArray = EmptyArrays.emptyCharArray - def emptyDoubleArray = EmptyArrays.emptyDoubleArray - def emptyFloatArray = EmptyArrays.emptyFloatArray - def emptyIntArray = EmptyArrays.emptyIntArray - def emptyLongArray = EmptyArrays.emptyLongArray - def emptyShortArray = EmptyArrays.emptyShortArray - def emptyObjectArray = EmptyArrays.emptyObjectArray - - private object EmptyArrays { - val emptyBooleanArray = new Array[Boolean](0) - val emptyByteArray = new Array[Byte](0) - val emptyCharArray = new Array[Char](0) - val emptyDoubleArray = new Array[Double](0) - val emptyFloatArray = new Array[Float](0) - val emptyIntArray = new Array[Int](0) - val emptyLongArray = new Array[Long](0) - val emptyShortArray = new Array[Short](0) - val emptyObjectArray = new Array[Object](0) - } - - implicit def canBuildFrom[T](implicit t: ClassTag[T]): CanBuildFrom[Array[_], T, Array[T]] = { - @inline - class ArrayCanBuildFrom extends CanBuildFrom[Array[_], T, Array[T]] { - def apply(from: Array[_]) = ArrayBuilder.make[T]()(t) - def apply() = ArrayBuilder.make[T]()(t) - } - new ArrayCanBuildFrom - } - - /** - * Returns a new [[scala.collection.mutable.ArrayBuilder]]. - */ - def newBuilder[T](implicit t: ClassTag[T]): ArrayBuilder[T] = ArrayBuilder.make[T]()(t) - - private def slowcopy(src : AnyRef, - srcPos : Int, - dest : AnyRef, - destPos : Int, - length : Int) { - var i = srcPos - var j = destPos - val srcUntil = srcPos + length - while (i < srcUntil) { - array_update(dest, j, array_apply(src, i)) - i += 1 - j += 1 - } - } - - /** Copy one array to another. - * Equivalent to Java's - * `System.arraycopy(src, srcPos, dest, destPos, length)`, - * except that this also works for polymorphic and boxed arrays. - * - * Note that the passed-in `dest` array will be modified by this call. - * - * @param src the source array. - * @param srcPos starting position in the source array. - * @param dest destination array. - * @param destPos starting position in the destination array. - * @param length the number of array elements to be copied. - * - * @see `java.lang.System#arraycopy` - */ - def copy(src: AnyRef, srcPos: Int, dest: AnyRef, destPos: Int, length: Int) { - val srcClass = src.getClass - if (srcClass.isArray && dest.getClass.isAssignableFrom(srcClass)) - arraycopy(src, srcPos, dest, destPos, length) - else - slowcopy(src, srcPos, dest, destPos, length) - } - - /** Returns an array of length 0 */ - def empty[T: ClassTag]: Array[T] = new Array[T](0) - - /** Creates an array with given elements. - * - * @param xs the elements to put in the array - * @return an array containing all elements from xs. - */ - // Subject to a compiler optimization in Cleanup. - // Array(e0, ..., en) is translated to { val a = new Array(3); a(i) = ei; a } - def apply[T: ClassTag](xs: T*): Array[T] = { - val array = new Array[T](xs.length) - var i = 0 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Boolean` objects */ - // Subject to a compiler optimization in Cleanup, see above. - def apply(x: Boolean, xs: Boolean*): Array[Boolean] = { - val array = new Array[Boolean](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Byte` objects */ - // Subject to a compiler optimization in Cleanup, see above. - def apply(x: Byte, xs: Byte*): Array[Byte] = { - val array = new Array[Byte](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Short` objects */ - // Subject to a compiler optimization in Cleanup, see above. - def apply(x: Short, xs: Short*): Array[Short] = { - val array = new Array[Short](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Char` objects */ - // Subject to a compiler optimization in Cleanup, see above. - def apply(x: Char, xs: Char*): Array[Char] = { - val array = new Array[Char](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Int` objects */ - // Subject to a compiler optimization in Cleanup, see above. - def apply(x: Int, xs: Int*): Array[Int] = { - val array = new Array[Int](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Long` objects */ - // Subject to a compiler optimization in Cleanup, see above. - def apply(x: Long, xs: Long*): Array[Long] = { - val array = new Array[Long](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Float` objects */ - // Subject to a compiler optimization in Cleanup, see above. - def apply(x: Float, xs: Float*): Array[Float] = { - val array = new Array[Float](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Double` objects */ - // Subject to a compiler optimization in Cleanup, see above. - def apply(x: Double, xs: Double*): Array[Double] = { - val array = new Array[Double](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Unit` objects */ - def apply(x: Unit, xs: Unit*): Array[Unit] = { - val array = new Array[Unit](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates array with given dimensions */ - def ofDim[T: ClassTag](n1: Int): Array[T] = - new Array[T](n1) - /** Creates a 2-dimensional array */ - def ofDim[T: ClassTag](n1: Int, n2: Int): Array[Array[T]] = { - val arr: Array[Array[T]] = (new Array[Array[T]](n1): Array[Array[T]]) - for (i <- 0 until n1) arr(i) = new Array[T](n2) - arr - // tabulate(n1)(_ => ofDim[T](n2)) - } - /** Creates a 3-dimensional array */ - def ofDim[T: ClassTag](n1: Int, n2: Int, n3: Int): Array[Array[Array[T]]] = - tabulate(n1)(_ => ofDim[T](n2, n3)) - /** Creates a 4-dimensional array */ - def ofDim[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int): Array[Array[Array[Array[T]]]] = - tabulate(n1)(_ => ofDim[T](n2, n3, n4)) - /** Creates a 5-dimensional array */ - def ofDim[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int): Array[Array[Array[Array[Array[T]]]]] = - tabulate(n1)(_ => ofDim[T](n2, n3, n4, n5)) - - /** Concatenates all arrays into a single array. - * - * @param xss the given arrays - * @return the array created from concatenating `xss` - */ - def concat[T: ClassTag](xss: Array[T]*): Array[T] = { - val b = newBuilder[T] - b.sizeHint(xss.map(_.length).sum) - for (xs <- xss) b ++= xs - b.result() - } - - /** Returns an array that contains the results of some element computation a number - * of times. - * - * Note that this means that `elem` is computed a total of n times: - * {{{ - * scala> Array.fill(3){ math.random } - * res3: Array[Double] = Array(0.365461167592537, 1.550395944913685E-4, 0.7907242137333306) - * }}} - * - * @param n the number of elements desired - * @param elem the element computation - * @return an Array of size n, where each element contains the result of computing - * `elem`. - */ - def fill[T: ClassTag](n: Int)(elem: => T): Array[T] = { - val b = newBuilder[T] - b.sizeHint(n) - var i = 0 - while (i < n) { - b += elem - i += 1 - } - b.result() - } - - /** Returns a two-dimensional array that contains the results of some element - * computation a number of times. - * - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param elem the element computation - */ - def fill[T: ClassTag](n1: Int, n2: Int)(elem: => T): Array[Array[T]] = - tabulate(n1)(_ => fill(n2)(elem)) - - /** Returns a three-dimensional array that contains the results of some element - * computation a number of times. - * - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param n3 the number of elements in the 3nd dimension - * @param elem the element computation - */ - def fill[T: ClassTag](n1: Int, n2: Int, n3: Int)(elem: => T): Array[Array[Array[T]]] = - tabulate(n1)(_ => fill(n2, n3)(elem)) - - /** Returns a four-dimensional array that contains the results of some element - * computation a number of times. - * - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param n3 the number of elements in the 3nd dimension - * @param n4 the number of elements in the 4th dimension - * @param elem the element computation - */ - def fill[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int)(elem: => T): Array[Array[Array[Array[T]]]] = - tabulate(n1)(_ => fill(n2, n3, n4)(elem)) - - /** Returns a five-dimensional array that contains the results of some element - * computation a number of times. - * - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param n3 the number of elements in the 3nd dimension - * @param n4 the number of elements in the 4th dimension - * @param n5 the number of elements in the 5th dimension - * @param elem the element computation - */ - def fill[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(elem: => T): Array[Array[Array[Array[Array[T]]]]] = - tabulate(n1)(_ => fill(n2, n3, n4, n5)(elem)) - - /** Returns an array containing values of a given function over a range of integer - * values starting from 0. - * - * @param n The number of elements in the array - * @param f The function computing element values - * @return A traversable consisting of elements `f(0),f(1), ..., f(n - 1)` - */ - def tabulate[T: ClassTag](n: Int)(f: Int => T): Array[T] = { - val b = newBuilder[T] - b.sizeHint(n) - var i = 0 - while (i < n) { - b += f(i) - i += 1 - } - b.result() - } - - /** Returns a two-dimensional array containing values of a given function - * over ranges of integer values starting from `0`. - * - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param f The function computing element values - */ - def tabulate[T: ClassTag](n1: Int, n2: Int)(f: (Int, Int) => T): Array[Array[T]] = - tabulate(n1)(i1 => tabulate(n2)(f(i1, _))) - - /** Returns a three-dimensional array containing values of a given function - * over ranges of integer values starting from `0`. - * - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param n3 the number of elements in the 3rd dimension - * @param f The function computing element values - */ - def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int)(f: (Int, Int, Int) => T): Array[Array[Array[T]]] = - tabulate(n1)(i1 => tabulate(n2, n3)(f(i1, _, _))) - - /** Returns a four-dimensional array containing values of a given function - * over ranges of integer values starting from `0`. - * - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param n3 the number of elements in the 3rd dimension - * @param n4 the number of elements in the 4th dimension - * @param f The function computing element values - */ - def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int)(f: (Int, Int, Int, Int) => T): Array[Array[Array[Array[T]]]] = - tabulate(n1)(i1 => tabulate(n2, n3, n4)(f(i1, _, _, _))) - - /** Returns a five-dimensional array containing values of a given function - * over ranges of integer values starting from `0`. - * - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param n3 the number of elements in the 3rd dimension - * @param n4 the number of elements in the 4th dimension - * @param n5 the number of elements in the 5th dimension - * @param f The function computing element values - */ - def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(f: (Int, Int, Int, Int, Int) => T): Array[Array[Array[Array[Array[T]]]]] = - tabulate(n1)(i1 => tabulate(n2, n3, n4, n5)(f(i1, _, _, _, _))) - - /** Returns an array containing a sequence of increasing integers in a range. - * - * @param start the start value of the array - * @param end the end value of the array, exclusive (in other words, this is the first value '''not''' returned) - * @return the array with values in range `start, start + 1, ..., end - 1` - * up to, but excluding, `end`. - */ - def range(start: Int, end: Int): Array[Int] = range(start, end, 1) - - /** Returns an array containing equally spaced values in some integer interval. - * - * @param start the start value of the array - * @param end the end value of the array, exclusive (in other words, this is the first value '''not''' returned) - * @param step the increment value of the array (may not be zero) - * @return the array with values in `start, start + step, ...` up to, but excluding `end` - */ - def range(start: Int, end: Int, step: Int): Array[Int] = { - if (step == 0) throw new IllegalArgumentException("zero step") - val b = newBuilder[Int] - b.sizeHint(immutable.Range.count(start, end, step, isInclusive = false)) - - var i = start - while (if (step < 0) end < i else i < end) { - b += i - i += step - } - b.result() - } - - /** Returns an array containing repeated applications of a function to a start value. - * - * @param start the start value of the array - * @param len the number of elements returned by the array - * @param f the function that is repeatedly applied - * @return the array returning `len` values in the sequence `start, f(start), f(f(start)), ...` - */ - def iterate[T: ClassTag](start: T, len: Int)(f: T => T): Array[T] = { - val b = newBuilder[T] - - if (len > 0) { - b.sizeHint(len) - var acc = start - var i = 1 - b += acc - - while (i < len) { - acc = f(acc) - i += 1 - b += acc - } - } - b.result() - } - - /** Called in a pattern match like `{ case Array(x,y,z) => println('3 elements')}`. - * - * @param x the selector value - * @return sequence wrapped in a [[scala.Some]], if `x` is a Seq, otherwise `None` - */ - def unapplySeq[T](x: Array[T]): Option[IndexedSeq[T]] = - if (x == null) None else Some(x.toIndexedSeq) - // !!! the null check should to be necessary, but without it 2241 fails. Seems to be a bug - // in pattern matcher. @PP: I noted in #4364 I think the behavior is correct. -} - -/** Arrays are mutable, indexed collections of values. `Array[T]` is Scala's representation - * for Java's `T[]`. - * - * {{{ - * val numbers = Array(1, 2, 3, 4) - * val first = numbers(0) // read the first element - * numbers(3) = 100 // replace the 4th array element with 100 - * val biggerNumbers = numbers.map(_ * 2) // multiply all numbers by two - * }}} - * - * Arrays make use of two common pieces of Scala syntactic sugar, shown on lines 2 and 3 of the above - * example code. - * Line 2 is translated into a call to `apply(Int)`, while line 3 is translated into a call to - * `update(Int, T)`. - * - * Two implicit conversions exist in [[scala.Predef]] that are frequently applied to arrays: a conversion - * to [[scala.collection.mutable.ArrayOps]] (shown on line 4 of the example above) and a conversion - * to [[scala.collection.mutable.WrappedArray]] (a subtype of [[scala.collection.Seq]]). - * Both types make available many of the standard operations found in the Scala collections API. - * The conversion to `ArrayOps` is temporary, as all operations defined on `ArrayOps` return an `Array`, - * while the conversion to `WrappedArray` is permanent as all operations return a `WrappedArray`. - * - * The conversion to `ArrayOps` takes priority over the conversion to `WrappedArray`. For instance, - * consider the following code: - * - * {{{ - * val arr = Array(1, 2, 3) - * val arrReversed = arr.reverse - * val seqReversed : Seq[Int] = arr.reverse - * }}} - * - * Value `arrReversed` will be of type `Array[Int]`, with an implicit conversion to `ArrayOps` occurring - * to perform the `reverse` operation. The value of `seqReversed`, on the other hand, will be computed - * by converting to `WrappedArray` first and invoking the variant of `reverse` that returns another - * `WrappedArray`. - * - * @author Martin Odersky - * @version 1.0 - * @see [[http://www.scala-lang.org/files/archive/spec/2.11/ Scala Language Specification]], for in-depth information on the transformations the Scala compiler makes on Arrays (Sections 6.6 and 6.15 respectively.) - * @see [[http://docs.scala-lang.org/sips/completed/scala-2-8-arrays.html "Scala 2.8 Arrays"]] the Scala Improvement Document detailing arrays since Scala 2.8. - * @see [[http://docs.scala-lang.org/overviews/collections/arrays.html "The Scala 2.8 Collections' API"]] section on `Array` by Martin Odersky for more information. - * @define coll array - * @define Coll `Array` - * @define orderDependent - * @define orderDependentFold - * @define mayNotTerminateInf - * @define willNotTerminateInf - * @define collectExample - * @define undefinedorder - * @define thatinfo the class of the returned collection. In the standard library configuration, - * `That` is either `Array[B]` if an ClassTag is available for B or `ArraySeq[B]` otherwise. - * @define zipthatinfo $thatinfo - * @define bfinfo an implicit value of class `CanBuildFrom` which determines the result class `That` from the current - * representation type `Repr` and the new element type `B`. - */ -final class Array[T](_length: Int) extends java.io.Serializable with java.lang.Cloneable { - - /** The length of the array */ - def length: Int = throw new Error() - - /** The element at given index. - * - * Indices start at `0`; `xs.apply(0)` is the first element of array `xs`. - * Note the indexing syntax `xs(i)` is a shorthand for `xs.apply(i)`. - * - * @param i the index - * @return the element at the given index - * @throws ArrayIndexOutOfBoundsException if `i < 0` or `length <= i` - */ - def apply(i: Int): T = throw new Error() - - /** Update the element at given index. - * - * Indices start at `0`; `xs.update(i, x)` replaces the i^th^ element in the array. - * Note the syntax `xs(i) = x` is a shorthand for `xs.update(i, x)`. - * - * @param i the index - * @param x the value to be written at index `i` - * @throws ArrayIndexOutOfBoundsException if `i < 0` or `length <= i` - */ - def update(i: Int, x: T) { throw new Error() } - - /** Clone the Array. - * - * @return A clone of the Array. - */ - override def clone(): Array[T] = throw new Error() -} diff --git a/scalalib/overrides-2.13.0-M3/scala/Enumeration.scala b/scalalib/overrides-2.13.0-M3/scala/Enumeration.scala deleted file mode 100644 index bdc170156a..0000000000 --- a/scalalib/overrides-2.13.0-M3/scala/Enumeration.scala +++ /dev/null @@ -1,284 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala - -import scala.collection.{ mutable, immutable, generic, SortedSetLike, AbstractSet } -import java.lang.reflect.{ Modifier, Method => JMethod, Field => JField } -import scala.reflect.NameTransformer._ -import java.util.regex.Pattern - -/** Defines a finite set of values specific to the enumeration. Typically - * these values enumerate all possible forms something can take and provide - * a lightweight alternative to case classes. - * - * Each call to a `Value` method adds a new unique value to the enumeration. - * To be accessible, these values are usually defined as `val` members of - * the evaluation. - * - * All values in an enumeration share a common, unique type defined as the - * `Value` type member of the enumeration (`Value` selected on the stable - * identifier path of the enumeration instance). - * - * @example {{{ - * object Main extends App { - * - * object WeekDay extends Enumeration { - * type WeekDay = Value - * val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value - * } - * import WeekDay._ - * - * def isWorkingDay(d: WeekDay) = ! (d == Sat || d == Sun) - * - * WeekDay.values filter isWorkingDay foreach println - * } - * // output: - * // Mon - * // Tue - * // Wed - * // Thu - * // Fri - * }}} - * - * @param initial The initial value from which to count the integers that - * identifies values at run-time. - * @author Matthias Zenger - */ -@SerialVersionUID(8476000850333817230L) -abstract class Enumeration (initial: Int) extends Serializable { - thisenum => - - def this() = this(0) - - /* Note that `readResolve` cannot be private, since otherwise - the JVM does not invoke it when deserializing subclasses. */ - protected def readResolve(): AnyRef = ??? - - /** The name of this enumeration. - */ - override def toString = - (getClass.getName.stripSuffix("$").split('.')).last.split('$').last - - /** The mapping from the integer used to identify values to the actual - * values. */ - private val vmap: mutable.Map[Int, Value] = new mutable.HashMap - - /** The cache listing all values of this enumeration. */ - @transient private var vset: ValueSet = null - @transient @volatile private var vsetDefined = false - - /** The mapping from the integer used to identify values to their - * names. */ - private val nmap: mutable.Map[Int, String] = new mutable.HashMap - - /** The values of this enumeration as a set. - */ - def values: ValueSet = { - if (!vsetDefined) { - vset = (ValueSet.newBuilder ++= vmap.values).result() - vsetDefined = true - } - vset - } - - /** The integer to use to identify the next created value. */ - protected var nextId: Int = initial - - /** The string to use to name the next created value. */ - protected var nextName: Iterator[String] = _ - - private def nextNameOrNull = - if (nextName != null && nextName.hasNext) nextName.next() else null - - /** The highest integer amongst those used to identify values in this - * enumeration. */ - private var topId = initial - - /** The lowest integer amongst those used to identify values in this - * enumeration, but no higher than 0. */ - private var bottomId = if(initial < 0) initial else 0 - - /** The one higher than the highest integer amongst those used to identify - * values in this enumeration. */ - final def maxId = topId - - /** The value of this enumeration with given id `x` - */ - final def apply(x: Int): Value = vmap(x) - - /** Return a `Value` from this `Enumeration` whose name matches - * the argument `s`. The names are determined automatically via reflection. - * - * @param s an `Enumeration` name - * @return the `Value` of this `Enumeration` if its name matches `s` - * @throws NoSuchElementException if no `Value` with a matching - * name is in this `Enumeration` - */ - final def withName(s: String): Value = { - val (unnamed, named) = values partition { - _.toString().startsWith(" v - // If we have unnamed values, we issue a detailed error message - case None if unnamed.nonEmpty => - throw new NoSuchElementException( - s"""Couldn't find enum field with name $s. - |However, there were the following unnamed fields: - |${unnamed.mkString(" ","\n ","")}""".stripMargin) - // Normal case (no unnamed Values) - case _ => None.get - } - } - - /** Creates a fresh value, part of this enumeration. */ - protected final def Value: Value = Value(nextId) - - /** Creates a fresh value, part of this enumeration, identified by the - * integer `i`. - * - * @param i An integer that identifies this value at run-time. It must be - * unique amongst all values of the enumeration. - * @return Fresh value identified by `i`. - */ - protected final def Value(i: Int): Value = Value(i, nextNameOrNull) - - /** Creates a fresh value, part of this enumeration, called `name`. - * - * @param name A human-readable name for that value. - * @return Fresh value called `name`. - */ - protected final def Value(name: String): Value = Value(nextId, name) - - /** Creates a fresh value, part of this enumeration, called `name` - * and identified by the integer `i`. - * - * @param i An integer that identifies this value at run-time. It must be - * unique amongst all values of the enumeration. - * @param name A human-readable name for that value. - * @return Fresh value with the provided identifier `i` and name `name`. - */ - protected final def Value(i: Int, name: String): Value = new Val(i, name) - - /** The type of the enumerated values. */ - @SerialVersionUID(7091335633555234129L) - abstract class Value extends Ordered[Value] with Serializable { - /** the id and bit location of this enumeration value */ - def id: Int - /** a marker so we can tell whose values belong to whom come reflective-naming time */ - private[Enumeration] val outerEnum = thisenum - - override def compare(that: Value): Int = - if (this.id < that.id) -1 - else if (this.id == that.id) 0 - else 1 - override def equals(other: Any) = other match { - case that: Enumeration#Value => (outerEnum eq that.outerEnum) && (id == that.id) - case _ => false - } - override def hashCode: Int = id.## - - /** Create a ValueSet which contains this value and another one */ - def + (v: Value) = ValueSet(this, v) - } - - /** A class implementing the [[scala.Enumeration.Value]] type. This class - * can be overridden to change the enumeration's naming and integer - * identification behaviour. - */ - @SerialVersionUID(0 - 3501153230598116017L) - protected class Val(i: Int, name: String) - extends Value with Serializable { - - def this(i: Int) = this(i, nextNameOrNull) - def this(name: String) = this(nextId, name) - def this() = this(nextId) - - assert(!vmap.isDefinedAt(i), "Duplicate id: " + i) - vmap(i) = this - vsetDefined = false - nextId = i + 1 - if (nextId > topId) topId = nextId - if (i < bottomId) bottomId = i - def id = i - override def toString() = - if (name != null) name - // Scala.js specific - else s"" - - protected def readResolve(): AnyRef = { - val enum = thisenum.readResolve().asInstanceOf[Enumeration] - if (enum.vmap == null) this - else enum.vmap(i) - } - } - - /** An ordering by id for values of this set */ - object ValueOrdering extends Ordering[Value] { - def compare(x: Value, y: Value): Int = x compare y - } - - /** A class for sets of values. - * Iterating through this set will yield values in increasing order of their ids. - * - * @param nnIds The set of ids of values (adjusted so that the lowest value does - * not fall below zero), organized as a `BitSet`. - */ - class ValueSet private[ValueSet] (private[this] var nnIds: immutable.BitSet) - extends AbstractSet[Value] - with immutable.SortedSet[Value] - with SortedSetLike[Value, ValueSet] - with Serializable { - - implicit def ordering: Ordering[Value] = ValueOrdering - def rangeImpl(from: Option[Value], until: Option[Value]): ValueSet = - new ValueSet(nnIds.rangeImpl(from.map(_.id - bottomId), until.map(_.id - bottomId))) - - override def empty = ValueSet.empty - def contains(v: Value) = nnIds contains (v.id - bottomId) - def + (value: Value) = new ValueSet(nnIds + (value.id - bottomId)) - def - (value: Value) = new ValueSet(nnIds - (value.id - bottomId)) - def iterator = nnIds.iterator map (id => thisenum.apply(bottomId + id)) - // This is only defined in 2.11. We change its implementation so it also - // compiles on 2.10. - def keysIteratorFrom(start: Value) = from(start).keySet.toIterator - //nnIds keysIteratorFrom start.id map (id => thisenum.apply(bottomId + id)) - override def stringPrefix = thisenum + ".ValueSet" - /** Creates a bit mask for the zero-adjusted ids in this set as a - * new array of longs */ - def toBitMask: Array[Long] = nnIds.toBitMask - } - - /** A factory object for value sets */ - object ValueSet { - import generic.CanBuildFrom - - /** The empty value set */ - val empty = new ValueSet(immutable.BitSet.empty) - /** A value set consisting of given elements */ - def apply(elems: Value*): ValueSet = (newBuilder ++= elems).result() - /** A value set containing all the values for the zero-adjusted ids - * corresponding to the bits in an array */ - def fromBitMask(elems: Array[Long]): ValueSet = new ValueSet(immutable.BitSet.fromBitMask(elems)) - /** A builder object for value sets */ - def newBuilder: mutable.Builder[Value, ValueSet] = new mutable.Builder[Value, ValueSet] { - private[this] val b = new mutable.BitSet - def += (x: Value) = { b += (x.id - bottomId); this } - def clear() = b.clear() - def result() = new ValueSet(b.toImmutable) - } - /** The implicit builder for value sets */ - implicit def canBuildFrom: CanBuildFrom[ValueSet, Value, ValueSet] = - new CanBuildFrom[ValueSet, Value, ValueSet] { - def apply(from: ValueSet) = newBuilder - def apply() = newBuilder - } - } -} \ No newline at end of file diff --git a/scalalib/overrides-2.13.0-M3/scala/collection/immutable/NumericRange.scala b/scalalib/overrides-2.13.0-M3/scala/collection/immutable/NumericRange.scala deleted file mode 100644 index 65e703829c..0000000000 --- a/scalalib/overrides-2.13.0-M3/scala/collection/immutable/NumericRange.scala +++ /dev/null @@ -1,375 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2006-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala -package collection -package immutable - -// TODO: Now the specialization exists there is no clear reason to have -// separate classes for Range/NumericRange. Investigate and consolidate. - -/** `NumericRange` is a more generic version of the - * `Range` class which works with arbitrary types. - * It must be supplied with an `Integral` implementation of the - * range type. - * - * Factories for likely types include `Range.BigInt`, `Range.Long`, - * and `Range.BigDecimal`. `Range.Int` exists for completeness, but - * the `Int`-based `scala.Range` should be more performant. - * - * {{{ - * val r1 = new Range(0, 100, 1) - * val veryBig = Int.MaxValue.toLong + 1 - * val r2 = Range.Long(veryBig, veryBig + 100, 1) - * assert(r1 sameElements r2.map(_ - veryBig)) - * }}} - * - * @author Paul Phillips - * @version 2.8 - * @define Coll `NumericRange` - * @define coll numeric range - * @define mayNotTerminateInf - * @define willNotTerminateInf - */ -abstract class NumericRange[T] - (val start: T, val end: T, val step: T, val isInclusive: Boolean) - (implicit num: Integral[T]) -extends AbstractSeq[T] with IndexedSeq[T] with Serializable { - /** Note that NumericRange must be invariant so that constructs - * such as "1L to 10 by 5" do not infer the range type as AnyVal. - */ - import num._ - - // See comment in Range for why this must be lazy. - private lazy val numRangeElements: Int = - NumericRange.count(start, end, step, isInclusive) - - override def length = numRangeElements - override def isEmpty = length == 0 - override lazy val last: T = - if (length == 0) Nil.last - else locationAfterN(length - 1) - - /** Create a new range with the start and end values of this range and - * a new `step`. - */ - def by(newStep: T): NumericRange[T] = copy(start, end, newStep) - - /** Create a copy of this range. - */ - def copy(start: T, end: T, step: T): NumericRange[T] - - override def foreach[U](f: T => U) { - var count = 0 - var current = start - while (count < length) { - f(current) - current += step - count += 1 - } - } - - // TODO: these private methods are straight copies from Range, duplicated - // to guard against any (most likely illusory) performance drop. They should - // be eliminated one way or another. - - // Tests whether a number is within the endpoints, without testing - // whether it is a member of the sequence (i.e. when step > 1.) - private def isWithinBoundaries(elem: T) = !isEmpty && ( - (step > zero && start <= elem && elem <= last ) || - (step < zero && last <= elem && elem <= start) - ) - // Methods like apply throw exceptions on invalid n, but methods like take/drop - // are forgiving: therefore the checks are with the methods. - private def locationAfterN(n: Int): T = start + (step * fromInt(n)) - - // When one drops everything. Can't ever have unchecked operations - // like "end + 1" or "end - 1" because ranges involving Int.{ MinValue, MaxValue } - // will overflow. This creates an exclusive range where start == end - // based on the given value. - private def newEmptyRange(value: T) = NumericRange(value, value, step) - - final override def take(n: Int): NumericRange[T] = ( - if (n <= 0 || length == 0) newEmptyRange(start) - else if (n >= length) this - else new NumericRange.Inclusive(start, locationAfterN(n - 1), step) - ) - - final override def drop(n: Int): NumericRange[T] = ( - if (n <= 0 || length == 0) this - else if (n >= length) newEmptyRange(end) - else copy(locationAfterN(n), end, step) - ) - - def apply(idx: Int): T = { - if (idx < 0 || idx >= length) throw new IndexOutOfBoundsException(idx.toString) - else locationAfterN(idx) - } - - import NumericRange.defaultOrdering - - override def min[T1 >: T](implicit ord: Ordering[T1]): T = - // We can take the fast path: - // - If the Integral of this NumericRange is also the requested Ordering - // (Integral <: Ordering). This can happen for custom Integral types. - // - The Ordering is the default Ordering of a well-known Integral type. - if ((ord eq num) || defaultOrdering.get(num).exists(ord eq _)) { - if (num.signum(step) > 0) start - else last - } else super.min(ord) - - override def max[T1 >: T](implicit ord: Ordering[T1]): T = - // See comment for fast path in min(). - if ((ord eq num) || defaultOrdering.get(num).exists(ord eq _)) { - if (num.signum(step) > 0) last - else start - } else super.max(ord) - - // Motivated by the desire for Double ranges with BigDecimal precision, - // we need some way to map a Range and get another Range. This can't be - // done in any fully general way because Ranges are not arbitrary - // sequences but step-valued, so we have a custom method only we can call - // which we promise to use responsibly. - // - // The point of it all is that - // - // 0.0 to 1.0 by 0.1 - // - // should result in - // - // NumericRange[Double](0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0) - // - // and not - // - // NumericRange[Double](0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9) - // - // or perhaps more importantly, - // - // (0.1 to 0.3 by 0.1 contains 0.3) == true - // - private[immutable] def mapRange[A](fm: T => A)(implicit unum: Integral[A]): NumericRange[A] = { - val self = this - - // XXX This may be incomplete. - new NumericRange[A](fm(start), fm(end), fm(step), isInclusive) { - def copy(start: A, end: A, step: A): NumericRange[A] = - if (isInclusive) NumericRange.inclusive(start, end, step) - else NumericRange(start, end, step) - - private lazy val underlyingRange: NumericRange[T] = self - override def foreach[U](f: A => U) { underlyingRange foreach (x => f(fm(x))) } - override def isEmpty = underlyingRange.isEmpty - override def apply(idx: Int): A = fm(underlyingRange(idx)) - override def containsTyped(el: A) = underlyingRange exists (x => fm(x) == el) - - override def toString = { - def simpleOf(x: Any): String = x.getClass.getName.split("\\.").last - val stepped = simpleOf(underlyingRange.step) - s"${super.toString} (using $underlyingRange of $stepped)" - } - } - } - - // a well-typed contains method. - def containsTyped(x: T): Boolean = - isWithinBoundaries(x) && (((x - start) % step) == zero) - - override def contains[A1 >: T](x: A1): Boolean = - try containsTyped(x.asInstanceOf[T]) - catch { case _: ClassCastException => false } - - final override def sum[B >: T](implicit num: Numeric[B]): B = { - if (isEmpty) num.zero - else if (numRangeElements == 1) head - else { - // If there is no overflow, use arithmetic series formula - // a + ... (n terms total) ... + b = n*(a+b)/2 - if ((num eq scala.math.Numeric.IntIsIntegral)|| - (num eq scala.math.Numeric.ShortIsIntegral)|| - (num eq scala.math.Numeric.ByteIsIntegral)|| - (num eq scala.math.Numeric.CharIsIntegral)) { - // We can do math with no overflow in a Long--easy - val exact = (numRangeElements * ((num toLong head) + (num toInt last))) / 2 - num fromInt exact.toInt - } - else if (num eq scala.math.Numeric.LongIsIntegral) { - // Uh-oh, might be overflow, so we have to divide before we overflow. - // Either numRangeElements or (head + last) must be even, so divide the even one before multiplying - val a = head.toLong - val b = last.toLong - val ans = - if ((numRangeElements & 1) == 0) (numRangeElements / 2) * (a + b) - else numRangeElements * { - // Sum is even, but we might overflow it, so divide in pieces and add back remainder - val ha = a/2 - val hb = b/2 - ha + hb + ((a - 2*ha) + (b - 2*hb)) / 2 - } - ans.asInstanceOf[B] - } - else { - // User provided custom Numeric, so we cannot rely on arithmetic series formula (e.g. won't work on something like Z_6) - if (isEmpty) num.zero - else { - var acc = num.zero - var i = head - var idx = 0 - while(idx < length) { - acc = num.plus(acc, i) - i = i + step - idx = idx + 1 - } - acc - } - } - } - } - - override lazy val hashCode = super.hashCode() - override def equals(other: Any) = other match { - case x: NumericRange[_] => - (x canEqual this) && (length == x.length) && ( - (length == 0) || // all empty sequences are equal - (start == x.start && last == x.last) // same length and same endpoints implies equality - ) - case _ => - super.equals(other) - } - - override def toString = { - val empty = if (isEmpty) "empty " else "" - val preposition = if (isInclusive) "to" else "until" - val stepped = if (step == 1) "" else s" by $step" - s"${empty}NumericRange $start $preposition $end$stepped" - } -} - -/** A companion object for numeric ranges. - */ -object NumericRange { - - /** Calculates the number of elements in a range given start, end, step, and - * whether or not it is inclusive. Throws an exception if step == 0 or - * the number of elements exceeds the maximum Int. - */ - def count[T](start: T, end: T, step: T, isInclusive: Boolean)(implicit num: Integral[T]): Int = { - val zero = num.zero - val upward = num.lt(start, end) - val posStep = num.gt(step, zero) - - if (step == zero) throw new IllegalArgumentException("step cannot be 0.") - else if (start == end) if (isInclusive) 1 else 0 - else if (upward != posStep) 0 - else { - /* We have to be frightfully paranoid about running out of range. - * We also can't assume that the numbers will fit in a Long. - * We will assume that if a > 0, -a can be represented, and if - * a < 0, -a+1 can be represented. We also assume that if we - * can't fit in Int, we can represent 2*Int.MaxValue+3 (at least). - * And we assume that numbers wrap rather than cap when they overflow. - */ - // Check whether we can short-circuit by deferring to Int range. - val startint = num.toInt(start) - if (start == num.fromInt(startint)) { - val endint = num.toInt(end) - if (end == num.fromInt(endint)) { - val stepint = num.toInt(step) - if (step == num.fromInt(stepint)) { - return { - if (isInclusive) Range.inclusive(startint, endint, stepint).length - else Range (startint, endint, stepint).length - } - } - } - } - // If we reach this point, deferring to Int failed. - // Numbers may be big. - val one = num.one - val limit = num.fromInt(Int.MaxValue) - def check(t: T): T = - if (num.gt(t, limit)) throw new IllegalArgumentException("More than Int.MaxValue elements.") - else t - // If the range crosses zero, it might overflow when subtracted - val startside = num.signum(start) - val endside = num.signum(end) - num.toInt{ - if (startside*endside >= 0) { - // We're sure we can subtract these numbers. - // Note that we do not use .rem because of different conventions for Long and BigInt - val diff = num.minus(end, start) - val quotient = check(num.quot(diff, step)) - val remainder = num.minus(diff, num.times(quotient, step)) - if (!isInclusive && zero == remainder) quotient else check(num.plus(quotient, one)) - } - else { - // We might not even be able to subtract these numbers. - // Jump in three pieces: - // * start to -1 or 1, whichever is closer (waypointA) - // * one step, which will take us at least to 0 (ends at waypointB) - // * there to the end - val negone = num.fromInt(-1) - val startlim = if (posStep) negone else one - val startdiff = num.minus(startlim, start) - val startq = check(num.quot(startdiff, step)) - val waypointA = if (startq == zero) start else num.plus(start, num.times(startq, step)) - val waypointB = num.plus(waypointA, step) - check { - if (num.lt(waypointB, end) != upward) { - // No last piece - if (isInclusive && waypointB == end) num.plus(startq, num.fromInt(2)) - else num.plus(startq, one) - } - else { - // There is a last piece - val enddiff = num.minus(end,waypointB) - val endq = check(num.quot(enddiff, step)) - val last = if (endq == zero) waypointB else num.plus(waypointB, num.times(endq, step)) - // Now we have to tally up all the pieces - // 1 for the initial value - // startq steps to waypointA - // 1 step to waypointB - // endq steps to the end (one less if !isInclusive and last==end) - num.plus(startq, num.plus(endq, if (!isInclusive && last==end) one else num.fromInt(2))) - } - } - } - } - } - } - - class Inclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]) - extends NumericRange(start, end, step, true) { - def copy(start: T, end: T, step: T): Inclusive[T] = - NumericRange.inclusive(start, end, step) - - def exclusive: Exclusive[T] = NumericRange(start, end, step) - } - - class Exclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]) - extends NumericRange(start, end, step, false) { - def copy(start: T, end: T, step: T): Exclusive[T] = - NumericRange(start, end, step) - - def inclusive: Inclusive[T] = NumericRange.inclusive(start, end, step) - } - - def apply[T](start: T, end: T, step: T)(implicit num: Integral[T]): Exclusive[T] = - new Exclusive(start, end, step) - def inclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]): Inclusive[T] = - new Inclusive(start, end, step) - - private[collection] val defaultOrdering = Map[Numeric[_], Ordering[_]]( - Numeric.IntIsIntegral -> Ordering.Int, - Numeric.ShortIsIntegral -> Ordering.Short, - Numeric.ByteIsIntegral -> Ordering.Byte, - Numeric.CharIsIntegral -> Ordering.Char, - Numeric.LongIsIntegral -> Ordering.Long - ) - -} - diff --git a/scalalib/overrides-2.13.0-M3/scala/collection/immutable/Range.scala b/scalalib/overrides-2.13.0-M3/scala/collection/immutable/Range.scala deleted file mode 100644 index fb2c34c064..0000000000 --- a/scalalib/overrides-2.13.0-M3/scala/collection/immutable/Range.scala +++ /dev/null @@ -1,527 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2006-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - -package scala -package collection.immutable - -/** The `Range` class represents integer values in range - * ''[start;end)'' with non-zero step value `step`. - * It's a special case of an indexed sequence. - * For example: - * - * {{{ - * val r1 = 0 until 10 - * val r2 = r1.start until r1.end by r1.step + 1 - * println(r2.length) // = 5 - * }}} - * - * Ranges that contain more than `Int.MaxValue` elements can be created, but - * these overfull ranges have only limited capabilities. Any method that - * could require a collection of over `Int.MaxValue` length to be created, or - * could be asked to index beyond `Int.MaxValue` elements will throw an - * exception. Overfull ranges can safely be reduced in size by changing - * the step size (e.g. `by 3`) or taking/dropping elements. `contains`, - * `equals`, and access to the ends of the range (`head`, `last`, `tail`, - * `init`) are also permitted on overfull ranges. - * - * @param start the start of this range. - * @param end the end of the range. For exclusive ranges, e.g. - * `Range(0,3)` or `(0 until 3)`, this is one - * step past the last one in the range. For inclusive - * ranges, e.g. `Range.inclusive(0,3)` or `(0 to 3)`, - * it may be in the range if it is not skipped by the step size. - * To find the last element inside a non-empty range, - use `last` instead. - * @param step the step for the range. - * - * @author Martin Odersky - * @author Paul Phillips - * @version 2.8 - * @since 2.5 - * @see [[http://docs.scala-lang.org/overviews/collections/concrete-immutable-collection-classes.html#ranges "Scala's Collection Library overview"]] - * section on `Ranges` for more information. - * - * @define coll range - * @define mayNotTerminateInf - * @define willNotTerminateInf - * @define doesNotUseBuilders - * '''Note:''' this method does not use builders to construct a new range, - * and its complexity is O(1). - */ -@SerialVersionUID(7618862778670199309L) -@inline -@deprecatedInheritance("The implementation details of Range makes inheriting from it unwise.", "2.11.0") -class Range(val start: Int, val end: Int, val step: Int) -extends scala.collection.AbstractSeq[Int] - with IndexedSeq[Int] - with Serializable -{ - private def gap = end.toLong - start.toLong - private def isExact = gap % step == 0 - private def hasStub = isInclusive || !isExact - private def longLength = gap / step + ( if (hasStub) 1 else 0 ) - - // Check cannot be evaluated eagerly because we have a pattern where - // ranges are constructed like: "x to y by z" The "x to y" piece - // should not trigger an exception. So the calculation is delayed, - // which means it will not fail fast for those cases where failing was - // correct. - override final val isEmpty = ( - (start > end && step > 0) - || (start < end && step < 0) - || (start == end && !isInclusive) - ) - - private val numRangeElements: Int = { - if (step == 0) throw new IllegalArgumentException("step cannot be 0.") - else if (isEmpty) 0 - else { - val len = longLength - if (len > scala.Int.MaxValue) -1 - else len.toInt - } - } - - // This field has a sensible value only for non-empty ranges - private val lastElement = step match { - case 1 => if (isInclusive) end else end-1 - case -1 => if (isInclusive) end else end+1 - case _ => - val remainder = (gap % step).toInt - if (remainder != 0) end - remainder - else if (isInclusive) end - else end - step - } - - /** The last element of this range. This method will return the correct value - * even if there are too many elements to iterate over. - */ - override def last = if (isEmpty) Nil.last else lastElement - override def head = if (isEmpty) Nil.head else start - - override def min[A1 >: Int](implicit ord: Ordering[A1]): Int = - if (ord eq Ordering.Int) { - if (step > 0) head - else last - } else super.min(ord) - - override def max[A1 >: Int](implicit ord: Ordering[A1]): Int = - if (ord eq Ordering.Int) { - if (step > 0) last - else head - } else super.max(ord) - - protected def copy(start: Int, end: Int, step: Int): Range = new Range(start, end, step) - - /** Create a new range with the `start` and `end` values of this range and - * a new `step`. - * - * @return a new range with a different step - */ - def by(step: Int): Range = copy(start, end, step) - - def isInclusive = false - - override def size = length - override def length = if (numRangeElements < 0) fail() else numRangeElements - - private def fail() = Range.fail(start, end, step, isInclusive) - private def validateMaxLength() { - if (numRangeElements < 0) - fail() - } - - final def apply(idx: Int): Int = { - validateMaxLength() - if (idx < 0 || idx >= numRangeElements) throw new IndexOutOfBoundsException(idx.toString) - else start + (step * idx) - } - - @inline final override def foreach[@specialized(Unit) U](f: Int => U) { - // Implementation chosen on the basis of favorable microbenchmarks - // Note--initialization catches step == 0 so we don't need to here - if (!isEmpty) { - var i = start - while (true) { - f(i) - if (i == lastElement) return - i += step - } - } - } - - /** Creates a new range containing the first `n` elements of this range. - * - * $doesNotUseBuilders - * - * @param n the number of elements to take. - * @return a new range consisting of `n` first elements. - */ - final override def take(n: Int): Range = ( - if (n <= 0 || isEmpty) newEmptyRange(start) - else if (n >= numRangeElements && numRangeElements >= 0) this - else { - // May have more than Int.MaxValue elements in range (numRangeElements < 0) - // but the logic is the same either way: take the first n - new Range.Inclusive(start, locationAfterN(n - 1), step) - } - ) - - /** Creates a new range containing all the elements of this range except the first `n` elements. - * - * $doesNotUseBuilders - * - * @param n the number of elements to drop. - * @return a new range consisting of all the elements of this range except `n` first elements. - */ - final override def drop(n: Int): Range = ( - if (n <= 0 || isEmpty) this - else if (n >= numRangeElements && numRangeElements >= 0) newEmptyRange(end) - else { - // May have more than Int.MaxValue elements (numRangeElements < 0) - // but the logic is the same either way: go forwards n steps, keep the rest - copy(locationAfterN(n), end, step) - } - ) - - /** Creates a new range containing the elements starting at `from` up to but not including `until`. - * - * $doesNotUseBuilders - * - * @param from the element at which to start - * @param until the element at which to end (not included in the range) - * @return a new range consisting of a contiguous interval of values in the old range - */ - override def slice(from: Int, until: Int): Range = - if (from <= 0) take(until) - else if (until >= numRangeElements && numRangeElements >= 0) drop(from) - else { - val fromValue = locationAfterN(from) - if (from >= until) newEmptyRange(fromValue) - else new Range.Inclusive(fromValue, locationAfterN(until-1), step) - } - - /** Creates a new range containing all the elements of this range except the last one. - * - * $doesNotUseBuilders - * - * @return a new range consisting of all the elements of this range except the last one. - */ - final override def init: Range = { - if (isEmpty) - Nil.init - - dropRight(1) - } - - /** Creates a new range containing all the elements of this range except the first one. - * - * $doesNotUseBuilders - * - * @return a new range consisting of all the elements of this range except the first one. - */ - final override def tail: Range = { - if (isEmpty) - Nil.tail - - drop(1) - } - - // Advance from the start while we meet the given test - private def argTakeWhile(p: Int => Boolean): Long = { - if (isEmpty) start - else { - var current = start - val stop = last - while (current != stop && p(current)) current += step - if (current != stop || !p(current)) current - else current.toLong + step - } - } - // Methods like apply throw exceptions on invalid n, but methods like take/drop - // are forgiving: therefore the checks are with the methods. - private def locationAfterN(n: Int) = start + (step * n) - - // When one drops everything. Can't ever have unchecked operations - // like "end + 1" or "end - 1" because ranges involving Int.{ MinValue, MaxValue } - // will overflow. This creates an exclusive range where start == end - // based on the given value. - private def newEmptyRange(value: Int) = new Range(value, value, step) - - final override def takeWhile(p: Int => Boolean): Range = { - val stop = argTakeWhile(p) - if (stop==start) newEmptyRange(start) - else { - val x = (stop - step).toInt - if (x == last) this - else new Range.Inclusive(start, x, step) - } - } - final override def dropWhile(p: Int => Boolean): Range = { - val stop = argTakeWhile(p) - if (stop == start) this - else { - val x = (stop - step).toInt - if (x == last) newEmptyRange(last) - else new Range.Inclusive(x + step, last, step) - } - } - final override def span(p: Int => Boolean): (Range, Range) = { - val border = argTakeWhile(p) - if (border == start) (newEmptyRange(start), this) - else { - val x = (border - step).toInt - if (x == last) (this, newEmptyRange(last)) - else (new Range.Inclusive(start, x, step), new Range.Inclusive(x+step, last, step)) - } - } - - /** Creates a pair of new ranges, first consisting of elements before `n`, and the second - * of elements after `n`. - * - * $doesNotUseBuilders - */ - final override def splitAt(n: Int) = (take(n), drop(n)) - - /** Creates a new range consisting of the last `n` elements of the range. - * - * $doesNotUseBuilders - */ - final override def takeRight(n: Int): Range = { - if (n <= 0) newEmptyRange(start) - else if (numRangeElements >= 0) drop(numRangeElements - n) - else { - // Need to handle over-full range separately - val y = last - val x = y - step.toLong*(n-1) - if ((step > 0 && x < start) || (step < 0 && x > start)) this - else new Range.Inclusive(x.toInt, y, step) - } - } - - /** Creates a new range consisting of the initial `length - n` elements of the range. - * - * $doesNotUseBuilders - */ - final override def dropRight(n: Int): Range = { - if (n <= 0) this - else if (numRangeElements >= 0) take(numRangeElements - n) - else { - // Need to handle over-full range separately - val y = last - step.toInt*n - if ((step > 0 && y < start) || (step < 0 && y > start)) newEmptyRange(start) - else new Range.Inclusive(start, y.toInt, step) - } - } - - /** Returns the reverse of this range. - * - * $doesNotUseBuilders - */ - final override def reverse: Range = - if (isEmpty) this - else new Range.Inclusive(last, start, -step) - - /** Make range inclusive. - */ - def inclusive = - if (isInclusive) this - else new Range.Inclusive(start, end, step) - - final def contains(x: Int) = { - if (x==end && !isInclusive) false - else if (step > 0) { - if (x < start || x > end) false - else (step == 1) || (((x - start) % step) == 0) - } - else { - if (x < end || x > start) false - else (step == -1) || (((x - start) % step) == 0) - } - } - - final override def sum[B >: Int](implicit num: Numeric[B]): Int = { - if (num eq scala.math.Numeric.IntIsIntegral) { - // this is normal integer range with usual addition. arithmetic series formula can be used - if (isEmpty) 0 - else if (numRangeElements == 1) head - else ((numRangeElements * (head.toLong + last)) / 2).toInt - } else { - // user provided custom Numeric, we cannot rely on arithmetic series formula - if (isEmpty) num.toInt(num.zero) - else { - var acc = num.zero - var i = head - while (true) { - acc = num.plus(acc, i) - if (i == lastElement) return num.toInt(acc) - i = i + step - } - 0 // Never hit this--just to satisfy compiler since it doesn't know while(true) has type Nothing - } - } - } - - override def toIterable = this - - override def toSeq = this - - override def equals(other: Any) = other match { - case x: Range => - // Note: this must succeed for overfull ranges (length > Int.MaxValue) - (x canEqual this) && { - if (isEmpty) x.isEmpty // empty sequences are equal - else // this is non-empty... - x.nonEmpty && start == x.start && { // ...so other must contain something and have same start - val l0 = last - (l0 == x.last && ( // And same end - start == l0 || step == x.step // And either the same step, or not take any steps - )) - } - } - case _ => - super.equals(other) - } - - /* Note: hashCode can't be overridden without breaking Seq's equals contract. */ - - override def toString = { - val preposition = if (isInclusive) "to" else "until" - val stepped = if (step == 1) "" else s" by $step" - val prefix = if (isEmpty) "empty " else if (!isExact) "inexact " else "" - s"${prefix}Range $start $preposition $end$stepped" - } -} - -/** A companion object for the `Range` class. - */ -object Range { - private[immutable] val MAX_PRINT = 512 // some arbitrary value - - private def description(start: Int, end: Int, step: Int, isInclusive: Boolean) = - start + (if (isInclusive) " to " else " until ") + end + " by " + step - - private def fail(start: Int, end: Int, step: Int, isInclusive: Boolean) = - throw new IllegalArgumentException(description(start, end, step, isInclusive) + - ": seqs cannot contain more than Int.MaxValue elements.") - - /** Counts the number of range elements. - * @pre step != 0 - * If the size of the range exceeds Int.MaxValue, the - * result will be negative. - */ - def count(start: Int, end: Int, step: Int, isInclusive: Boolean): Int = { - if (step == 0) - throw new IllegalArgumentException("step cannot be 0.") - - val isEmpty = ( - if (start == end) !isInclusive - else if (start < end) step < 0 - else step > 0 - ) - if (isEmpty) 0 - else { - // Counts with Longs so we can recognize too-large ranges. - val gap: Long = end.toLong - start.toLong - val jumps: Long = gap / step - // Whether the size of this range is one larger than the - // number of full-sized jumps. - val hasStub = isInclusive || (gap % step != 0) - val result: Long = jumps + ( if (hasStub) 1 else 0 ) - - if (result > scala.Int.MaxValue) -1 - else result.toInt - } - } - def count(start: Int, end: Int, step: Int): Int = - count(start, end, step, isInclusive = false) - - @inline - class Inclusive(start: Int, end: Int, step: Int) extends Range(start, end, step) { - override def isInclusive = true - override protected def copy(start: Int, end: Int, step: Int): Range = new Inclusive(start, end, step) - } - - /** Make a range from `start` until `end` (exclusive) with given step value. - * @note step != 0 - */ - def apply(start: Int, end: Int, step: Int): Range = new Range(start, end, step) - - /** Make a range from `start` until `end` (exclusive) with step value 1. - */ - def apply(start: Int, end: Int): Range = new Range(start, end, 1) - - /** Make an inclusive range from `start` to `end` with given step value. - * @note step != 0 - */ - def inclusive(start: Int, end: Int, step: Int): Range.Inclusive = new Inclusive(start, end, step) - - /** Make an inclusive range from `start` to `end` with step value 1. - */ - def inclusive(start: Int, end: Int): Range.Inclusive = new Inclusive(start, end, 1) - - // BigInt and Long are straightforward generic ranges. - object BigInt { - def apply(start: BigInt, end: BigInt, step: BigInt) = NumericRange(start, end, step) - def inclusive(start: BigInt, end: BigInt, step: BigInt) = NumericRange.inclusive(start, end, step) - } - - object Long { - def apply(start: Long, end: Long, step: Long) = NumericRange(start, end, step) - def inclusive(start: Long, end: Long, step: Long) = NumericRange.inclusive(start, end, step) - } - - // BigDecimal uses an alternative implementation of Numeric in which - // it pretends to be Integral[T] instead of Fractional[T]. See Numeric for - // details. The intention is for it to throw an exception anytime - // imprecision or surprises might result from anything, although this may - // not yet be fully implemented. - object BigDecimal { - implicit val bigDecAsIntegral = scala.math.Numeric.BigDecimalAsIfIntegral - - def apply(start: BigDecimal, end: BigDecimal, step: BigDecimal) = - NumericRange(start, end, step) - def inclusive(start: BigDecimal, end: BigDecimal, step: BigDecimal) = - NumericRange.inclusive(start, end, step) - } - - // Double works by using a BigDecimal under the hood for precise - // stepping, but mapping the sequence values back to doubles with - // .doubleValue. This constructs the BigDecimals by way of the - // String constructor (valueOf) instead of the Double one, which - // is necessary to keep 0.3d at 0.3 as opposed to - // 0.299999999999999988897769753748434595763683319091796875 or so. - object Double { - implicit val bigDecAsIntegral = scala.math.Numeric.BigDecimalAsIfIntegral - implicit val doubleAsIntegral = scala.math.Numeric.DoubleAsIfIntegral - def toBD(x: Double): BigDecimal = scala.math.BigDecimal valueOf x - - def apply(start: Double, end: Double, step: Double) = - BigDecimal(toBD(start), toBD(end), toBD(step)) mapRange (_.doubleValue) - - def inclusive(start: Double, end: Double, step: Double) = - BigDecimal.inclusive(toBD(start), toBD(end), toBD(step)) mapRange (_.doubleValue) - } - - // As there is no appealing default step size for not-really-integral ranges, - // we offer a partially constructed object. - class Partial[T, U](private val f: T => U) extends AnyVal { - def by(x: T): U = f(x) - override def toString = "Range requires step" - } - - // Illustrating genericity with Int Range, which should have the same behavior - // as the original Range class. However we leave the original Range - // indefinitely, for performance and because the compiler seems to bootstrap - // off it and won't do so with our parameterized version without modifications. - object Int { - def apply(start: Int, end: Int, step: Int) = NumericRange(start, end, step) - def inclusive(start: Int, end: Int, step: Int) = NumericRange.inclusive(start, end, step) - } -} diff --git a/scalalib/overrides-2.13.0-M3/scala/collection/mutable/ArrayBuilder.scala b/scalalib/overrides-2.13.0-M3/scala/collection/mutable/ArrayBuilder.scala deleted file mode 100644 index ce3a7d5a03..0000000000 --- a/scalalib/overrides-2.13.0-M3/scala/collection/mutable/ArrayBuilder.scala +++ /dev/null @@ -1,735 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala -package collection -package mutable - -import scala.reflect.ClassTag -import scala.runtime.BoxedUnit - -import scala.scalajs.js - -/** A builder class for arrays. - * - * @since 2.8 - * - * @tparam T the type of the elements for the builder. - */ -abstract class ArrayBuilder[T] extends ReusableBuilder[T, Array[T]] with Serializable - -/** A companion object for array builders. - * - * @since 2.8 - */ -object ArrayBuilder { - - /** Creates a new arraybuilder of type `T`. - * - * @tparam T type of the elements for the array builder, with a `ClassTag` context bound. - * @return a new empty array builder. - */ - @inline - def make[T: ClassTag](): ArrayBuilder[T] = - new ArrayBuilder.generic[T](implicitly[ClassTag[T]].runtimeClass) - - /** A generic ArrayBuilder optimized for Scala.js. - * - * @tparam T type of elements for the array builder. - * @param elementClass runtime class of the elements in the array. - */ - @inline - private final class generic[T](elementClass: Class[_]) extends ArrayBuilder[T] { - - private val isCharArrayBuilder = classOf[Char] == elementClass - private var elems: js.Array[Any] = js.Array() - - def +=(elem: T): this.type = { - val unboxedElem = - if (isCharArrayBuilder) elem.asInstanceOf[Char].toInt - else if (elem == null) zeroOf(elementClass) - else elem - elems.push(unboxedElem) - this - } - - def clear(): Unit = - elems = js.Array() - - def result(): Array[T] = { - val elemRuntimeClass = - if (classOf[Unit] == elementClass) classOf[BoxedUnit] - else if (classOf[Null] == elementClass || classOf[Nothing] == elementClass) classOf[Object] - else elementClass - genericArrayBuilderResult(elemRuntimeClass, elems) - } - - override def toString(): String = "ArrayBuilder.generic" - } - - // Intrinsic - private def zeroOf(runtimeClass: Class[_]): Any = runtimeClass match { - case java.lang.Byte.TYPE => 0.toByte - case java.lang.Short.TYPE => 0.toShort - case java.lang.Character.TYPE => 0 // yes, as an Int - case java.lang.Integer.TYPE => 0 - case java.lang.Long.TYPE => 0L - case java.lang.Float.TYPE => 0.0f - case java.lang.Double.TYPE => 0.0 - case java.lang.Boolean.TYPE => false - case java.lang.Void.TYPE => () - case _ => null - } - - // Intrinsic - private def genericArrayBuilderResult[T](runtimeClass: Class[_], - a: js.Array[Any]): Array[T] = { - val len = a.length - - if (classOf[Char] == runtimeClass) { - val result = new Array[Char](len) - var i = 0 - while (i != len) { - result(i) = a(i).asInstanceOf[Int].toChar - i += 1 - } - result.asInstanceOf[Array[T]] - } else { - val result: Array[T] = java.lang.reflect.Array.newInstance( - runtimeClass, len).asInstanceOf[Array[T]] - var i = 0 - while (i != len) { - result(i) = a(i).asInstanceOf[T] - i += 1 - } - result - } - } - - /** A class for array builders for arrays of reference types. - * - * This builder can be reused. - * - * @tparam T type of elements for the array builder, subtype of `AnyRef` with a `ClassTag` context bound. - */ - final class ofRef[T <: AnyRef : ClassTag] extends ArrayBuilder[T] { - - private var elems: Array[T] = _ - private var capacity: Int = 0 - private var size: Int = 0 - - private def mkArray(size: Int): Array[T] = { - val newelems = new Array[T](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) - newelems - } - - private def resize(size: Int) { - elems = mkArray(size) - capacity = size - } - - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: T): this.type = { - ensureSize(size + 1) - elems(size) = elem - size += 1 - this - } - - override def ++=(xs: TraversableOnce[T]): this.type = (xs.asInstanceOf[AnyRef]) match { - case xs: WrappedArray.ofRef[_] => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { size = 0 } - - def result() = { - if (capacity != 0 && capacity == size) { - capacity = 0 - elems - } - else mkArray(size) - } - - override def equals(other: Any): Boolean = other match { - case x: ofRef[_] => (size == x.size) && (elems == x.elems) - case _ => false - } - - override def toString = "ArrayBuilder.ofRef" - } - - /** A class for array builders for arrays of `byte`s. It can be reused. */ - final class ofByte extends ArrayBuilder[Byte] { - - private var elems: Array[Byte] = _ - private var capacity: Int = 0 - private var size: Int = 0 - - private def mkArray(size: Int): Array[Byte] = { - val newelems = new Array[Byte](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) - newelems - } - - private def resize(size: Int) { - elems = mkArray(size) - capacity = size - } - - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Byte): this.type = { - ensureSize(size + 1) - elems(size) = elem - size += 1 - this - } - - override def ++=(xs: TraversableOnce[Byte]): this.type = xs match { - case xs: WrappedArray.ofByte => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { size = 0 } - - def result() = { - if (capacity != 0 && capacity == size) { - capacity = 0 - elems - } - else mkArray(size) - } - - override def equals(other: Any): Boolean = other match { - case x: ofByte => (size == x.size) && (elems == x.elems) - case _ => false - } - - override def toString = "ArrayBuilder.ofByte" - } - - /** A class for array builders for arrays of `short`s. It can be reused. */ - final class ofShort extends ArrayBuilder[Short] { - - private var elems: Array[Short] = _ - private var capacity: Int = 0 - private var size: Int = 0 - - private def mkArray(size: Int): Array[Short] = { - val newelems = new Array[Short](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) - newelems - } - - private def resize(size: Int) { - elems = mkArray(size) - capacity = size - } - - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Short): this.type = { - ensureSize(size + 1) - elems(size) = elem - size += 1 - this - } - - override def ++=(xs: TraversableOnce[Short]): this.type = xs match { - case xs: WrappedArray.ofShort => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { size = 0 } - - def result() = { - if (capacity != 0 && capacity == size) { - capacity = 0 - elems - } - else mkArray(size) - } - - override def equals(other: Any): Boolean = other match { - case x: ofShort => (size == x.size) && (elems == x.elems) - case _ => false - } - - override def toString = "ArrayBuilder.ofShort" - } - - /** A class for array builders for arrays of `char`s. It can be reused. */ - final class ofChar extends ArrayBuilder[Char] { - - private var elems: Array[Char] = _ - private var capacity: Int = 0 - private var size: Int = 0 - - private def mkArray(size: Int): Array[Char] = { - val newelems = new Array[Char](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) - newelems - } - - private def resize(size: Int) { - elems = mkArray(size) - capacity = size - } - - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Char): this.type = { - ensureSize(size + 1) - elems(size) = elem - size += 1 - this - } - - override def ++=(xs: TraversableOnce[Char]): this.type = xs match { - case xs: WrappedArray.ofChar => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { size = 0 } - - def result() = { - if (capacity != 0 && capacity == size) { - capacity = 0 - elems - } - else mkArray(size) - } - - override def equals(other: Any): Boolean = other match { - case x: ofChar => (size == x.size) && (elems == x.elems) - case _ => false - } - - override def toString = "ArrayBuilder.ofChar" - } - - /** A class for array builders for arrays of `int`s. It can be reused. */ - final class ofInt extends ArrayBuilder[Int] { - - private var elems: Array[Int] = _ - private var capacity: Int = 0 - private var size: Int = 0 - - private def mkArray(size: Int): Array[Int] = { - val newelems = new Array[Int](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) - newelems - } - - private def resize(size: Int) { - elems = mkArray(size) - capacity = size - } - - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Int): this.type = { - ensureSize(size + 1) - elems(size) = elem - size += 1 - this - } - - override def ++=(xs: TraversableOnce[Int]): this.type = xs match { - case xs: WrappedArray.ofInt => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { size = 0 } - - def result() = { - if (capacity != 0 && capacity == size) { - capacity = 0 - elems - } - else mkArray(size) - } - - override def equals(other: Any): Boolean = other match { - case x: ofInt => (size == x.size) && (elems == x.elems) - case _ => false - } - - override def toString = "ArrayBuilder.ofInt" - } - - /** A class for array builders for arrays of `long`s. It can be reused. */ - final class ofLong extends ArrayBuilder[Long] { - - private var elems: Array[Long] = _ - private var capacity: Int = 0 - private var size: Int = 0 - - private def mkArray(size: Int): Array[Long] = { - val newelems = new Array[Long](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) - newelems - } - - private def resize(size: Int) { - elems = mkArray(size) - capacity = size - } - - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Long): this.type = { - ensureSize(size + 1) - elems(size) = elem - size += 1 - this - } - - override def ++=(xs: TraversableOnce[Long]): this.type = xs match { - case xs: WrappedArray.ofLong => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { size = 0 } - - def result() = { - if (capacity != 0 && capacity == size) { - capacity = 0 - elems - } - else mkArray(size) - } - - override def equals(other: Any): Boolean = other match { - case x: ofLong => (size == x.size) && (elems == x.elems) - case _ => false - } - - override def toString = "ArrayBuilder.ofLong" - } - - /** A class for array builders for arrays of `float`s. It can be reused. */ - final class ofFloat extends ArrayBuilder[Float] { - - private var elems: Array[Float] = _ - private var capacity: Int = 0 - private var size: Int = 0 - - private def mkArray(size: Int): Array[Float] = { - val newelems = new Array[Float](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) - newelems - } - - private def resize(size: Int) { - elems = mkArray(size) - capacity = size - } - - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Float): this.type = { - ensureSize(size + 1) - elems(size) = elem - size += 1 - this - } - - override def ++=(xs: TraversableOnce[Float]): this.type = xs match { - case xs: WrappedArray.ofFloat => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { size = 0 } - - def result() = { - if (capacity != 0 && capacity == size) { - capacity = 0 - elems - } - else mkArray(size) - } - - override def equals(other: Any): Boolean = other match { - case x: ofFloat => (size == x.size) && (elems == x.elems) - case _ => false - } - - override def toString = "ArrayBuilder.ofFloat" - } - - /** A class for array builders for arrays of `double`s. It can be reused. */ - final class ofDouble extends ArrayBuilder[Double] { - - private var elems: Array[Double] = _ - private var capacity: Int = 0 - private var size: Int = 0 - - private def mkArray(size: Int): Array[Double] = { - val newelems = new Array[Double](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) - newelems - } - - private def resize(size: Int) { - elems = mkArray(size) - capacity = size - } - - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Double): this.type = { - ensureSize(size + 1) - elems(size) = elem - size += 1 - this - } - - override def ++=(xs: TraversableOnce[Double]): this.type = xs match { - case xs: WrappedArray.ofDouble => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { size = 0 } - - def result() = { - if (capacity != 0 && capacity == size) { - capacity = 0 - elems - } - else mkArray(size) - } - - override def equals(other: Any): Boolean = other match { - case x: ofDouble => (size == x.size) && (elems == x.elems) - case _ => false - } - - override def toString = "ArrayBuilder.ofDouble" - } - - /** A class for array builders for arrays of `boolean`s. It can be reused. */ - class ofBoolean extends ArrayBuilder[Boolean] { - - private var elems: Array[Boolean] = _ - private var capacity: Int = 0 - private var size: Int = 0 - - private def mkArray(size: Int): Array[Boolean] = { - val newelems = new Array[Boolean](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) - newelems - } - - private def resize(size: Int) { - elems = mkArray(size) - capacity = size - } - - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size || capacity == 0) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Boolean): this.type = { - ensureSize(size + 1) - elems(size) = elem - size += 1 - this - } - - override def ++=(xs: TraversableOnce[Boolean]): this.type = xs match { - case xs: WrappedArray.ofBoolean => - ensureSize(this.size + xs.length) - Array.copy(xs.array, 0, elems, this.size, xs.length) - size += xs.length - this - case _ => - super.++=(xs) - } - - def clear() { size = 0 } - - def result() = { - if (capacity != 0 && capacity == size) { - capacity = 0 - elems - } - else mkArray(size) - } - - override def equals(other: Any): Boolean = other match { - case x: ofBoolean => (size == x.size) && (elems == x.elems) - case _ => false - } - - override def toString = "ArrayBuilder.ofBoolean" - } - - /** A class for array builders for arrays of `Unit` type. It can be reused. */ - final class ofUnit extends ArrayBuilder[Unit] { - - private var size: Int = 0 - - def +=(elem: Unit): this.type = { - size += 1 - this - } - - override def ++=(xs: TraversableOnce[Unit]): this.type = { - size += xs.size - this - } - - def clear() { size = 0 } - - def result() = { - val ans = new Array[Unit](size) - var i = 0 - while (i < size) { ans(i) = (); i += 1 } - ans - } - - override def equals(other: Any): Boolean = other match { - case x: ofUnit => (size == x.size) - case _ => false - } - - override def toString = "ArrayBuilder.ofUnit" - } -} diff --git a/scalalib/overrides-2.13.0-M3/scala/collection/mutable/Buffer.scala b/scalalib/overrides-2.13.0-M3/scala/collection/mutable/Buffer.scala deleted file mode 100644 index 2171cb9dea..0000000000 --- a/scalalib/overrides-2.13.0-M3/scala/collection/mutable/Buffer.scala +++ /dev/null @@ -1,51 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala -package collection -package mutable - -import generic._ - -import scala.scalajs.js - -/** Buffers are used to create sequences of elements incrementally by - * appending, prepending, or inserting new elements. It is also - * possible to access and modify elements in a random access fashion - * via the index of the element in the current sequence. - * - * @author Matthias Zenger - * @author Martin Odersky - * @version 2.8 - * @since 1 - * - * @tparam A type of the elements contained in this buffer. - * - * @define Coll `Buffer` - * @define coll buffer - */ -trait Buffer[A] extends Seq[A] - with GenericTraversableTemplate[A, Buffer] - with BufferLike[A, Buffer[A]] - with scala.Cloneable { - override def companion: GenericCompanion[Buffer] = Buffer -} - -/** $factoryInfo - * @define coll buffer - * @define Coll `Buffer` - */ -object Buffer extends SeqFactory[Buffer] { - implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Buffer[A]] = ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]] - def newBuilder[A]: Builder[A, Buffer[A]] = new js.WrappedArray -} - -/** Explicit instantiation of the `Buffer` trait to reduce class file size in subclasses. */ -abstract class AbstractBuffer[A] extends AbstractSeq[A] with Buffer[A] diff --git a/scalalib/overrides-2.13.0-M3/scala/concurrent/ExecutionContext.scala b/scalalib/overrides-2.13.0-M3/scala/concurrent/ExecutionContext.scala deleted file mode 100644 index fbe26f4de9..0000000000 --- a/scalalib/overrides-2.13.0-M3/scala/concurrent/ExecutionContext.scala +++ /dev/null @@ -1,183 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.concurrent - - -import java.util.concurrent.{ ExecutorService, Executor } -import scala.annotation.implicitNotFound -import scala.util.Try - -/** - * An `ExecutionContext` can execute program logic asynchronously, - * typically but not necessarily on a thread pool. - * - * A general purpose `ExecutionContext` must be asynchronous in executing - * any `Runnable` that is passed into its `execute`-method. A special purpose - * `ExecutionContext` may be synchronous but must only be passed to code that - * is explicitly safe to be run using a synchronously executing `ExecutionContext`. - * - * APIs such as `Future.onComplete` require you to provide a callback - * and an implicit `ExecutionContext`. The implicit `ExecutionContext` - * will be used to execute the callback. - * - * It is possible to simply import - * `scala.concurrent.ExecutionContext.Implicits.global` to obtain an - * implicit `ExecutionContext`. This global context is a reasonable - * default thread pool. - * - * However, application developers should carefully consider where they - * want to set policy; ideally, one place per application (or per - * logically-related section of code) will make a decision about - * which `ExecutionContext` to use. That is, you might want to avoid - * hardcoding `scala.concurrent.ExecutionContext.Implicits.global` all - * over the place in your code. - * One approach is to add `(implicit ec: ExecutionContext)` - * to methods which need an `ExecutionContext`. Then import a specific - * context in one place for the entire application or module, - * passing it implicitly to individual methods. - * - * A custom `ExecutionContext` may be appropriate to execute code - * which blocks on IO or performs long-running computations. - * `ExecutionContext.fromExecutorService` and `ExecutionContext.fromExecutor` - * are good ways to create a custom `ExecutionContext`. - * - * The intent of `ExecutionContext` is to lexically scope code execution. - * That is, each method, class, file, package, or application determines - * how to run its own code. This avoids issues such as running - * application callbacks on a thread pool belonging to a networking library. - * The size of a networking library's thread pool can be safely configured, - * knowing that only that library's network operations will be affected. - * Application callback execution can be configured separately. - */ -@implicitNotFound("""Cannot find an implicit ExecutionContext. You might pass -an (implicit ec: ExecutionContext) parameter to your method -or import scala.concurrent.ExecutionContext.Implicits.global.""") -trait ExecutionContext { - - /** Runs a block of code on this execution context. - * - * @param runnable the task to execute - */ - def execute(runnable: Runnable): Unit - - /** Reports that an asynchronous computation failed. - * - * @param cause the cause of the failure - */ - def reportFailure(@deprecatedName('t) cause: Throwable): Unit - - /** Prepares for the execution of a task. Returns the prepared - * execution context. The recommended implementation of - * `prepare` is to return `this`. - * - * This method should no longer be overridden or called. It was - * originally expected that `prepare` would be called by - * all libraries that consume ExecutionContexts, in order to - * capture thread local context. However, this usage has proven - * difficult to implement in practice and instead it is - * now better to avoid using `prepare` entirely. - * - * Instead, if an `ExecutionContext` needs to capture thread - * local context, it should capture that context when it is - * constructed, so that it doesn't need any additional - * preparation later. - */ - @deprecated("Preparation of ExecutionContexts will be removed.", "2.12") - def prepare(): ExecutionContext = this -} - -/** - * An [[ExecutionContext]] that is also a - * Java [[http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executor.html Executor]]. - */ -trait ExecutionContextExecutor extends ExecutionContext with Executor - -/** - * An [[ExecutionContext]] that is also a - * Java [[http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html ExecutorService]]. - */ -trait ExecutionContextExecutorService extends ExecutionContextExecutor with ExecutorService - - -/** Contains factory methods for creating execution contexts. - */ -object ExecutionContext { - /** - * The explicit global `ExecutionContext`. Invoke `global` when you want to provide the global - * `ExecutionContext` explicitly. - * - * The default `ExecutionContext` implementation is backed by a work-stealing thread pool. By default, - * the thread pool uses a target number of worker threads equal to the number of - * [[https://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#availableProcessors-- available processors]]. - * - * @return the global `ExecutionContext` - */ - def global: ExecutionContextExecutor = Implicits.global.asInstanceOf[ExecutionContextExecutor] - - object Implicits { - /** - * The implicit global `ExecutionContext`. Import `global` when you want to provide the global - * `ExecutionContext` implicitly. - * - * The default `ExecutionContext` implementation is backed by a work-stealing thread pool. By default, - * the thread pool uses a target number of worker threads equal to the number of - * [[https://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#availableProcessors-- available processors]]. - */ - implicit lazy val global: ExecutionContext = - scala.scalajs.concurrent.JSExecutionContext.queue - } - - /** Creates an `ExecutionContext` from the given `ExecutorService`. - * - * @param e the `ExecutorService` to use. If `null`, a new `ExecutorService` is created with [[http://www.scala-lang.org/api/current/index.html#scala.concurrent.ExecutionContext$@global:scala.concurrent.ExecutionContextExecutor default configuration]]. - * @param reporter a function for error reporting - * @return the `ExecutionContext` using the given `ExecutorService` - */ - def fromExecutorService(e: ExecutorService, reporter: Throwable => Unit): ExecutionContextExecutorService = - impl.ExecutionContextImpl.fromExecutorService(e, reporter) - - /** Creates an `ExecutionContext` from the given `ExecutorService` with the [[scala.concurrent.ExecutionContext$.defaultReporter default reporter]]. - * - * If it is guaranteed that none of the executed tasks are blocking, a single-threaded `ExecutorService` - * can be used to create an `ExecutionContext` as follows: - * - * {{{ - * import java.util.concurrent.Executors - * val ec = ExecutionContext.fromExecutorService(Executors.newSingleThreadExecutor()) - * }}} - * - * @param e the `ExecutorService` to use. If `null`, a new `ExecutorService` is created with [[http://www.scala-lang.org/api/current/index.html#scala.concurrent.ExecutionContext$@global:scala.concurrent.ExecutionContextExecutor default configuration]]. - * @return the `ExecutionContext` using the given `ExecutorService` - */ - def fromExecutorService(e: ExecutorService): ExecutionContextExecutorService = fromExecutorService(e, defaultReporter) - - /** Creates an `ExecutionContext` from the given `Executor`. - * - * @param e the `Executor` to use. If `null`, a new `Executor` is created with [[http://www.scala-lang.org/api/current/index.html#scala.concurrent.ExecutionContext$@global:scala.concurrent.ExecutionContextExecutor default configuration]]. - * @param reporter a function for error reporting - * @return the `ExecutionContext` using the given `Executor` - */ - def fromExecutor(e: Executor, reporter: Throwable => Unit): ExecutionContextExecutor = - impl.ExecutionContextImpl.fromExecutor(e, reporter) - - /** Creates an `ExecutionContext` from the given `Executor` with the [[scala.concurrent.ExecutionContext$.defaultReporter default reporter]]. - * - * @param e the `Executor` to use. If `null`, a new `Executor` is created with [[http://www.scala-lang.org/api/current/index.html#scala.concurrent.ExecutionContext$@global:scala.concurrent.ExecutionContextExecutor default configuration]]. - * @return the `ExecutionContext` using the given `Executor` - */ - def fromExecutor(e: Executor): ExecutionContextExecutor = fromExecutor(e, defaultReporter) - - /** The default reporter simply prints the stack trace of the `Throwable` to [[http://docs.oracle.com/javase/8/docs/api/java/lang/System.html#err System.err]]. - * - * @return the function for error reporting - */ - def defaultReporter: Throwable => Unit = _.printStackTrace() -} - - diff --git a/scalalib/overrides-2.13.0-M3/scala/package.scala b/scalalib/overrides-2.13.0-M3/scala/package.scala deleted file mode 100644 index 21051d473f..0000000000 --- a/scalalib/overrides-2.13.0-M3/scala/package.scala +++ /dev/null @@ -1,133 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - -/** - * Core Scala types. They are always available without an explicit import. - * @contentDiagram hideNodes "scala.Serializable" - */ -package object scala { - type Throwable = java.lang.Throwable - type Exception = java.lang.Exception - type Error = java.lang.Error - - type RuntimeException = java.lang.RuntimeException - type NullPointerException = java.lang.NullPointerException - type ClassCastException = java.lang.ClassCastException - type IndexOutOfBoundsException = java.lang.IndexOutOfBoundsException - type ArrayIndexOutOfBoundsException = java.lang.ArrayIndexOutOfBoundsException - type StringIndexOutOfBoundsException = java.lang.StringIndexOutOfBoundsException - type UnsupportedOperationException = java.lang.UnsupportedOperationException - type IllegalArgumentException = java.lang.IllegalArgumentException - type NoSuchElementException = java.util.NoSuchElementException - type NumberFormatException = java.lang.NumberFormatException - type AbstractMethodError = java.lang.AbstractMethodError - type InterruptedException = java.lang.InterruptedException - - // A dummy used by the specialization annotation. - val AnyRef = new Specializable { - override def toString = "object AnyRef" - } - - type TraversableOnce[+A] = scala.collection.TraversableOnce[A] - - type Traversable[+A] = scala.collection.Traversable[A] - val Traversable = scala.collection.Traversable - - type Iterable[+A] = scala.collection.Iterable[A] - val Iterable = scala.collection.Iterable - - type Seq[+A] = scala.collection.Seq[A] - val Seq = scala.collection.Seq - - type IndexedSeq[+A] = scala.collection.IndexedSeq[A] - val IndexedSeq = scala.collection.IndexedSeq - - type Iterator[+A] = scala.collection.Iterator[A] - val Iterator = scala.collection.Iterator - - type BufferedIterator[+A] = scala.collection.BufferedIterator[A] - - type List[+A] = scala.collection.immutable.List[A] - val List = scala.collection.immutable.List - - val Nil = scala.collection.immutable.Nil - - type ::[A] = scala.collection.immutable.::[A] - val :: = scala.collection.immutable.:: - - val +: = scala.collection.+: - val :+ = scala.collection.:+ - - type Stream[+A] = scala.collection.immutable.Stream[A] - val Stream = scala.collection.immutable.Stream - val #:: = scala.collection.immutable.Stream.#:: - - type Vector[+A] = scala.collection.immutable.Vector[A] - val Vector = scala.collection.immutable.Vector - - type StringBuilder = scala.collection.mutable.StringBuilder - val StringBuilder = scala.collection.mutable.StringBuilder - - type Range = scala.collection.immutable.Range - val Range = scala.collection.immutable.Range - - // Numeric types which were moved into scala.math.* - - type BigDecimal = scala.math.BigDecimal - lazy val BigDecimal = scala.math.BigDecimal - - type BigInt = scala.math.BigInt - lazy val BigInt = scala.math.BigInt - - type Equiv[T] = scala.math.Equiv[T] - val Equiv = scala.math.Equiv - - type Fractional[T] = scala.math.Fractional[T] - val Fractional = scala.math.Fractional - - type Integral[T] = scala.math.Integral[T] - val Integral = scala.math.Integral - - type Numeric[T] = scala.math.Numeric[T] - val Numeric = scala.math.Numeric - - type Ordered[T] = scala.math.Ordered[T] - val Ordered = scala.math.Ordered - - type Ordering[T] = scala.math.Ordering[T] - val Ordering = scala.math.Ordering - - type PartialOrdering[T] = scala.math.PartialOrdering[T] - type PartiallyOrdered[T] = scala.math.PartiallyOrdered[T] - - type Either[+A, +B] = scala.util.Either[A, B] - val Either = scala.util.Either - - type Left[+A, +B] = scala.util.Left[A, B] - val Left = scala.util.Left - - type Right[+A, +B] = scala.util.Right[A, B] - val Right = scala.util.Right - - // Annotations which we might move to annotation.* -/* - type SerialVersionUID = annotation.SerialVersionUID - type deprecated = annotation.deprecated - type deprecatedName = annotation.deprecatedName - type inline = annotation.inline - type native = annotation.native - type noinline = annotation.noinline - type remote = annotation.remote - type specialized = annotation.specialized - type transient = annotation.transient - type throws = annotation.throws - type unchecked = annotation.unchecked.unchecked - type volatile = annotation.volatile - */ -} diff --git a/scalalib/overrides-2.13.0-M3/scala/reflect/ClassTag.scala b/scalalib/overrides-2.13.0-M3/scala/reflect/ClassTag.scala deleted file mode 100644 index 05312cebe0..0000000000 --- a/scalalib/overrides-2.13.0-M3/scala/reflect/ClassTag.scala +++ /dev/null @@ -1,159 +0,0 @@ -package scala -package reflect - -import java.lang.{ Class => jClass } - -/** - * - * A `ClassTag[T]` stores the erased class of a given type `T`, accessible via the `runtimeClass` - * field. This is particularly useful for instantiating `Array`s whose element types are unknown - * at compile time. - * - * `ClassTag`s are a weaker special case of [[scala.reflect.api.TypeTags#TypeTag]]s, in that they - * wrap only the runtime class of a given type, whereas a `TypeTag` contains all static type - * information. That is, `ClassTag`s are constructed from knowing only the top-level class of a - * type, without necessarily knowing all of its argument types. This runtime information is enough - * for runtime `Array` creation. - * - * For example: - * {{{ - * scala> def mkArray[T : ClassTag](elems: T*) = Array[T](elems: _*) - * mkArray: [T](elems: T*)(implicit evidence$1: scala.reflect.ClassTag[T])Array[T] - * - * scala> mkArray(42, 13) - * res0: Array[Int] = Array(42, 13) - * - * scala> mkArray("Japan","Brazil","Germany") - * res1: Array[String] = Array(Japan, Brazil, Germany) - * }}} - * - * See [[scala.reflect.api.TypeTags]] for more examples, or the - * [[http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html Reflection Guide: TypeTags]] - * for more details. - * - */ -@scala.annotation.implicitNotFound(msg = "No ClassTag available for ${T}") -trait ClassTag[T] extends ClassManifestDeprecatedApis[T] with Equals with Serializable { - // please, don't add any APIs here, like it was with `newWrappedArray` and `newArrayBuilder` - // class tags, and all tags in general, should be as minimalistic as possible - - /** A class representing the type `U` to which `T` would be erased. - * Note that there is no subtyping relationship between `T` and `U`. - */ - def runtimeClass: jClass[_] - - /** Produces a `ClassTag` that knows how to instantiate an `Array[Array[T]]` */ - def wrap: ClassTag[Array[T]] = ClassTag[Array[T]](arrayClass(runtimeClass)) - - /** Produces a new array with element type `T` and length `len` */ - override def newArray(len: Int): Array[T] = - runtimeClass match { - case java.lang.Byte.TYPE => new Array[Byte](len).asInstanceOf[Array[T]] - case java.lang.Short.TYPE => new Array[Short](len).asInstanceOf[Array[T]] - case java.lang.Character.TYPE => new Array[Char](len).asInstanceOf[Array[T]] - case java.lang.Integer.TYPE => new Array[Int](len).asInstanceOf[Array[T]] - case java.lang.Long.TYPE => new Array[Long](len).asInstanceOf[Array[T]] - case java.lang.Float.TYPE => new Array[Float](len).asInstanceOf[Array[T]] - case java.lang.Double.TYPE => new Array[Double](len).asInstanceOf[Array[T]] - case java.lang.Boolean.TYPE => new Array[Boolean](len).asInstanceOf[Array[T]] - case java.lang.Void.TYPE => new Array[Unit](len).asInstanceOf[Array[T]] - case _ => java.lang.reflect.Array.newInstance(runtimeClass, len).asInstanceOf[Array[T]] - } - - /** A ClassTag[T] can serve as an extractor that matches only objects of type T. - * - * The compiler tries to turn unchecked type tests in pattern matches into checked ones - * by wrapping a `(_: T)` type pattern as `ct(_: T)`, where `ct` is the `ClassTag[T]` instance. - * Type tests necessary before calling other extractors are treated similarly. - * `SomeExtractor(...)` is turned into `ct(SomeExtractor(...))` if `T` in `SomeExtractor.unapply(x: T)` - * is uncheckable, but we have an instance of `ClassTag[T]`. - */ - def unapply(x: Any): Option[T] = - if (null != x && ( - (runtimeClass.isInstance(x)) - || (x.isInstanceOf[Byte] && runtimeClass.isAssignableFrom(classOf[Byte])) - || (x.isInstanceOf[Short] && runtimeClass.isAssignableFrom(classOf[Short])) - || (x.isInstanceOf[Char] && runtimeClass.isAssignableFrom(classOf[Char])) - || (x.isInstanceOf[Int] && runtimeClass.isAssignableFrom(classOf[Int])) - || (x.isInstanceOf[Long] && runtimeClass.isAssignableFrom(classOf[Long])) - || (x.isInstanceOf[Float] && runtimeClass.isAssignableFrom(classOf[Float])) - || (x.isInstanceOf[Double] && runtimeClass.isAssignableFrom(classOf[Double])) - || (x.isInstanceOf[Boolean] && runtimeClass.isAssignableFrom(classOf[Boolean])) - || (x.isInstanceOf[Unit] && runtimeClass.isAssignableFrom(classOf[Unit]))) - ) Some(x.asInstanceOf[T]) - else None - - // TODO: deprecate overloads in 2.12.0, remove in 2.13.0 - def unapply(x: Byte) : Option[T] = unapplyImpl(x, classOf[Byte]) - def unapply(x: Short) : Option[T] = unapplyImpl(x, classOf[Short]) - def unapply(x: Char) : Option[T] = unapplyImpl(x, classOf[Char]) - def unapply(x: Int) : Option[T] = unapplyImpl(x, classOf[Int]) - def unapply(x: Long) : Option[T] = unapplyImpl(x, classOf[Long]) - def unapply(x: Float) : Option[T] = unapplyImpl(x, classOf[Float]) - def unapply(x: Double) : Option[T] = unapplyImpl(x, classOf[Double]) - def unapply(x: Boolean) : Option[T] = unapplyImpl(x, classOf[Boolean]) - def unapply(x: Unit) : Option[T] = unapplyImpl(x, classOf[Unit]) - - private[this] def unapplyImpl(x: Any, primitiveCls: java.lang.Class[_]): Option[T] = - if (runtimeClass.isInstance(x) || runtimeClass.isAssignableFrom(primitiveCls)) Some(x.asInstanceOf[T]) - else None - - // case class accessories - override def canEqual(x: Any) = x.isInstanceOf[ClassTag[_]] - override def equals(x: Any) = x.isInstanceOf[ClassTag[_]] && this.runtimeClass == x.asInstanceOf[ClassTag[_]].runtimeClass - override def hashCode = runtimeClass.## - override def toString = { - def prettyprint(clazz: jClass[_]): String = - if (clazz.isArray) s"Array[${prettyprint(clazz.getComponentType)}]" else - clazz.getName - prettyprint(runtimeClass) - } -} - -/** - * Class tags corresponding to primitive types and constructor/extractor for ClassTags. - */ -object ClassTag { - def Byte : ClassTag[scala.Byte] = ManifestFactory.Byte - def Short : ClassTag[scala.Short] = ManifestFactory.Short - def Char : ClassTag[scala.Char] = ManifestFactory.Char - def Int : ClassTag[scala.Int] = ManifestFactory.Int - def Long : ClassTag[scala.Long] = ManifestFactory.Long - def Float : ClassTag[scala.Float] = ManifestFactory.Float - def Double : ClassTag[scala.Double] = ManifestFactory.Double - def Boolean : ClassTag[scala.Boolean] = ManifestFactory.Boolean - def Unit : ClassTag[scala.Unit] = ManifestFactory.Unit - def Any : ClassTag[scala.Any] = ManifestFactory.Any - def Object : ClassTag[java.lang.Object] = ManifestFactory.Object - def AnyVal : ClassTag[scala.AnyVal] = ManifestFactory.AnyVal - def AnyRef : ClassTag[scala.AnyRef] = ManifestFactory.AnyRef - def Nothing : ClassTag[scala.Nothing] = ManifestFactory.Nothing - def Null : ClassTag[scala.Null] = ManifestFactory.Null - - @inline - private class GenericClassTag[T](val runtimeClass: jClass[_]) extends ClassTag[T] - - def apply[T](runtimeClass1: jClass[_]): ClassTag[T] = - runtimeClass1 match { - case java.lang.Byte.TYPE => ClassTag.Byte.asInstanceOf[ClassTag[T]] - case java.lang.Short.TYPE => ClassTag.Short.asInstanceOf[ClassTag[T]] - case java.lang.Character.TYPE => ClassTag.Char.asInstanceOf[ClassTag[T]] - case java.lang.Integer.TYPE => ClassTag.Int.asInstanceOf[ClassTag[T]] - case java.lang.Long.TYPE => ClassTag.Long.asInstanceOf[ClassTag[T]] - case java.lang.Float.TYPE => ClassTag.Float.asInstanceOf[ClassTag[T]] - case java.lang.Double.TYPE => ClassTag.Double.asInstanceOf[ClassTag[T]] - case java.lang.Boolean.TYPE => ClassTag.Boolean.asInstanceOf[ClassTag[T]] - case java.lang.Void.TYPE => ClassTag.Unit.asInstanceOf[ClassTag[T]] - case _ => - if (classOf[java.lang.Object] == runtimeClass1) - ClassTag.Object.asInstanceOf[ClassTag[T]] - else if (classOf[scala.runtime.Nothing$] == runtimeClass1) - ClassTag.Nothing.asInstanceOf[ClassTag[T]] - else if (classOf[scala.runtime.Null$] == runtimeClass1) - ClassTag.Null.asInstanceOf[ClassTag[T]] - else - new GenericClassTag[T](runtimeClass1) - } - - def unapply[T](ctag: ClassTag[T]): Option[Class[_]] = Some(ctag.runtimeClass) -} diff --git a/scalalib/overrides-2.13.0-M3/scala/reflect/Manifest.scala b/scalalib/overrides-2.13.0-M3/scala/reflect/Manifest.scala deleted file mode 100644 index 48cdda41c7..0000000000 --- a/scalalib/overrides-2.13.0-M3/scala/reflect/Manifest.scala +++ /dev/null @@ -1,302 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala -package reflect - -import scala.collection.mutable.{ArrayBuilder, WrappedArray} - -/** A `Manifest[T]` is an opaque descriptor for type T. Its supported use - * is to give access to the erasure of the type as a `Class` instance, as - * is necessary for the creation of native `Arrays` if the class is not - * known at compile time. - * - * The type-relation operators `<:<` and `=:=` should be considered - * approximations only, as there are numerous aspects of type conformance - * which are not yet adequately represented in manifests. - * - * Example usages: - * {{{ - * def arr[T] = new Array[T](0) // does not compile - * def arr[T](implicit m: Manifest[T]) = new Array[T](0) // compiles - * def arr[T: Manifest] = new Array[T](0) // shorthand for the preceding - * - * // Methods manifest, classManifest, and optManifest are in [[scala.Predef]]. - * def isApproxSubType[T: Manifest, U: Manifest] = manifest[T] <:< manifest[U] - * isApproxSubType[List[String], List[AnyRef]] // true - * isApproxSubType[List[String], List[Int]] // false - * - * def methods[T: ClassManifest] = classManifest[T].erasure.getMethods - * def retType[T: ClassManifest](name: String) = - * methods[T] find (_.getName == name) map (_.getGenericReturnType) - * - * retType[Map[_, _]]("values") // Some(scala.collection.Iterable) - * }}} - */ -@scala.annotation.implicitNotFound(msg = "No Manifest available for ${T}.") -// TODO undeprecated until Scala reflection becomes non-experimental -// @deprecated("use scala.reflect.ClassTag (to capture erasures) or scala.reflect.runtime.universe.TypeTag (to capture types) or both instead", "2.10.0") -trait Manifest[T] extends ClassManifest[T] with Equals { - override def typeArguments: List[Manifest[_]] = Nil - - override def arrayManifest: Manifest[Array[T]] = - Manifest.classType[Array[T]](arrayClass[T](runtimeClass), this) - - override def canEqual(that: Any): Boolean = that match { - case _: Manifest[_] => true - case _ => false - } - /** Note: testing for erasure here is important, as it is many times - * faster than <:< and rules out most comparisons. - */ - override def equals(that: Any): Boolean = that match { - case m: Manifest[_] => (m canEqual this) && (this.runtimeClass == m.runtimeClass) && (this <:< m) && (m <:< this) - case _ => false - } - override def hashCode = this.runtimeClass.## -} - -// TODO undeprecated until Scala reflection becomes non-experimental -// @deprecated("use type tags and manually check the corresponding class or type instead", "2.10.0") -@SerialVersionUID(1L) -abstract class AnyValManifest[T <: AnyVal](override val toString: String) extends Manifest[T] with Equals { - override def <:<(that: ClassManifest[_]): Boolean = - (that eq this) || (that eq Manifest.Any) || (that eq Manifest.AnyVal) - override def canEqual(other: Any) = other match { - case _: AnyValManifest[_] => true - case _ => false - } - override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef] - override def hashCode = System.identityHashCode(this) -} - -/** `ManifestFactory` defines factory methods for manifests. - * It is intended for use by the compiler and should not be used in client code. - * - * Unlike `Manifest`, this factory isn't annotated with a deprecation warning. - * This is done to prevent avalanches of deprecation warnings in the code that calls methods with manifests. - * Why so complicated? Read up the comments for `ClassManifestFactory`. - */ -object ManifestFactory { - def valueManifests: List[AnyValManifest[_]] = - List(Byte, Short, Char, Int, Long, Float, Double, Boolean, Unit) - - private object ByteManifest extends AnyValManifest[scala.Byte]("Byte") { - def runtimeClass = java.lang.Byte.TYPE - override def newArray(len: Int): Array[Byte] = new Array[Byte](len) - override def newWrappedArray(len: Int): WrappedArray[Byte] = new WrappedArray.ofByte(new Array[Byte](len)) - override def newArrayBuilder(): ArrayBuilder[Byte] = new ArrayBuilder.ofByte() - private def readResolve(): Any = Manifest.Byte - } - def Byte: AnyValManifest[Byte] = ByteManifest - - private object ShortManifest extends AnyValManifest[scala.Short]("Short") { - def runtimeClass = java.lang.Short.TYPE - override def newArray(len: Int): Array[Short] = new Array[Short](len) - override def newWrappedArray(len: Int): WrappedArray[Short] = new WrappedArray.ofShort(new Array[Short](len)) - override def newArrayBuilder(): ArrayBuilder[Short] = new ArrayBuilder.ofShort() - private def readResolve(): Any = Manifest.Short - } - def Short: AnyValManifest[Short] = ShortManifest - - private object CharManifest extends AnyValManifest[scala.Char]("Char") { - def runtimeClass = java.lang.Character.TYPE - override def newArray(len: Int): Array[Char] = new Array[Char](len) - override def newWrappedArray(len: Int): WrappedArray[Char] = new WrappedArray.ofChar(new Array[Char](len)) - override def newArrayBuilder(): ArrayBuilder[Char] = new ArrayBuilder.ofChar() - private def readResolve(): Any = Manifest.Char - } - def Char: AnyValManifest[Char] = CharManifest - - private object IntManifest extends AnyValManifest[scala.Int]("Int") { - def runtimeClass = java.lang.Integer.TYPE - override def newArray(len: Int): Array[Int] = new Array[Int](len) - override def newWrappedArray(len: Int): WrappedArray[Int] = new WrappedArray.ofInt(new Array[Int](len)) - override def newArrayBuilder(): ArrayBuilder[Int] = new ArrayBuilder.ofInt() - private def readResolve(): Any = Manifest.Int - } - def Int: AnyValManifest[Int] = IntManifest - - private object LongManifest extends AnyValManifest[scala.Long]("Long") { - def runtimeClass = java.lang.Long.TYPE - override def newArray(len: Int): Array[Long] = new Array[Long](len) - override def newWrappedArray(len: Int): WrappedArray[Long] = new WrappedArray.ofLong(new Array[Long](len)) - override def newArrayBuilder(): ArrayBuilder[Long] = new ArrayBuilder.ofLong() - private def readResolve(): Any = Manifest.Long - } - def Long: AnyValManifest[Long] = LongManifest - - private object FloatManifest extends AnyValManifest[scala.Float]("Float") { - def runtimeClass = java.lang.Float.TYPE - override def newArray(len: Int): Array[Float] = new Array[Float](len) - override def newWrappedArray(len: Int): WrappedArray[Float] = new WrappedArray.ofFloat(new Array[Float](len)) - override def newArrayBuilder(): ArrayBuilder[Float] = new ArrayBuilder.ofFloat() - private def readResolve(): Any = Manifest.Float - } - def Float: AnyValManifest[Float] = FloatManifest - - private object DoubleManifest extends AnyValManifest[scala.Double]("Double") { - def runtimeClass = java.lang.Double.TYPE - override def newArray(len: Int): Array[Double] = new Array[Double](len) - override def newWrappedArray(len: Int): WrappedArray[Double] = new WrappedArray.ofDouble(new Array[Double](len)) - override def newArrayBuilder(): ArrayBuilder[Double] = new ArrayBuilder.ofDouble() - private def readResolve(): Any = Manifest.Double - } - def Double: AnyValManifest[Double] = DoubleManifest - - private object BooleanManifest extends AnyValManifest[scala.Boolean]("Boolean") { - def runtimeClass = java.lang.Boolean.TYPE - override def newArray(len: Int): Array[Boolean] = new Array[Boolean](len) - override def newWrappedArray(len: Int): WrappedArray[Boolean] = new WrappedArray.ofBoolean(new Array[Boolean](len)) - override def newArrayBuilder(): ArrayBuilder[Boolean] = new ArrayBuilder.ofBoolean() - private def readResolve(): Any = Manifest.Boolean - } - def Boolean: AnyValManifest[Boolean] = BooleanManifest - - private object UnitManifest extends AnyValManifest[scala.Unit]("Unit") { - def runtimeClass = java.lang.Void.TYPE - override def newArray(len: Int): Array[Unit] = new Array[Unit](len) - override def newWrappedArray(len: Int): WrappedArray[Unit] = new WrappedArray.ofUnit(new Array[Unit](len)) - override def newArrayBuilder(): ArrayBuilder[Unit] = new ArrayBuilder.ofUnit() - override protected def arrayClass[T](tp: Class[_]): Class[Array[T]] = - if (tp eq runtimeClass) classOf[Array[scala.runtime.BoxedUnit]].asInstanceOf[Class[Array[T]]] - else super.arrayClass(tp) - private def readResolve(): Any = Manifest.Unit - } - def Unit: AnyValManifest[Unit] = UnitManifest - - private object AnyManifest extends PhantomManifest[scala.Any](classOf[java.lang.Object], "Any") { - override def runtimeClass = classOf[java.lang.Object] - override def newArray(len: Int) = new Array[scala.Any](len) - override def <:<(that: ClassManifest[_]): Boolean = (that eq this) - private def readResolve(): Any = Manifest.Any - } - def Any: Manifest[scala.Any] = AnyManifest - - private object ObjectManifest extends PhantomManifest[java.lang.Object](classOf[java.lang.Object], "Object") { - override def runtimeClass = classOf[java.lang.Object] - override def newArray(len: Int) = new Array[java.lang.Object](len) - override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any) - private def readResolve(): Any = Manifest.Object - } - def Object: Manifest[java.lang.Object] = ObjectManifest - - def AnyRef: Manifest[scala.AnyRef] = Object.asInstanceOf[Manifest[scala.AnyRef]] - - private object AnyValManifest extends PhantomManifest[scala.AnyVal](classOf[java.lang.Object], "AnyVal") { - override def runtimeClass = classOf[java.lang.Object] - override def newArray(len: Int) = new Array[scala.AnyVal](len) - override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any) - private def readResolve(): Any = Manifest.AnyVal - } - def AnyVal: Manifest[scala.AnyVal] = AnyValManifest - - private object NullManifest extends PhantomManifest[scala.Null](classOf[scala.runtime.Null$], "Null") { - override def runtimeClass = classOf[scala.runtime.Null$] - override def newArray(len: Int) = new Array[scala.Null](len) - override def <:<(that: ClassManifest[_]): Boolean = - (that ne null) && (that ne Nothing) && !(that <:< AnyVal) - private def readResolve(): Any = Manifest.Null - } - def Null: Manifest[scala.Null] = NullManifest - - private object NothingManifest extends PhantomManifest[scala.Nothing](classOf[scala.runtime.Nothing$], "Nothing") { - override def runtimeClass = classOf[scala.runtime.Nothing$] - override def newArray(len: Int) = new Array[scala.Nothing](len) - override def <:<(that: ClassManifest[_]): Boolean = (that ne null) - private def readResolve(): Any = Manifest.Nothing - } - def Nothing: Manifest[scala.Nothing] = NothingManifest - - private class SingletonTypeManifest[T <: AnyRef](value: AnyRef) extends Manifest[T] { - lazy val runtimeClass = value.getClass - override lazy val toString = value.toString + ".type" - } - - /** Manifest for the singleton type `value.type`. */ - def singleType[T <: AnyRef](value: AnyRef): Manifest[T] = - new SingletonTypeManifest[T](value) - - /** Manifest for the class type `clazz[args]`, where `clazz` is - * a top-level or static class. - * @note This no-prefix, no-arguments case is separate because we - * it's called from ScalaRunTime.boxArray itself. If we - * pass varargs as arrays into this, we get an infinitely recursive call - * to boxArray. (Besides, having a separate case is more efficient) - */ - def classType[T](clazz: Predef.Class[_]): Manifest[T] = - new ClassTypeManifest[T](None, clazz, Nil) - - /** Manifest for the class type `clazz`, where `clazz` is - * a top-level or static class and args are its type arguments. */ - def classType[T](clazz: Predef.Class[T], arg1: Manifest[_], args: Manifest[_]*): Manifest[T] = - new ClassTypeManifest[T](None, clazz, arg1 :: args.toList) - - /** Manifest for the class type `clazz[args]`, where `clazz` is - * a class with non-package prefix type `prefix` and type arguments `args`. - */ - def classType[T](prefix: Manifest[_], clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] = - new ClassTypeManifest[T](Some(prefix), clazz, args.toList) - - private abstract class PhantomManifest[T](_runtimeClass: Predef.Class[_], - override val toString: String) extends ClassTypeManifest[T](None, _runtimeClass, Nil) { - override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef] - override def hashCode = System.identityHashCode(this) - } - - /** Manifest for the class type `clazz[args]`, where `clazz` is - * a top-level or static class. */ - private class ClassTypeManifest[T](prefix: Option[Manifest[_]], - runtimeClass1: Predef.Class[_], - override val typeArguments: List[Manifest[_]]) extends Manifest[T] { - def runtimeClass: Predef.Class[_] = runtimeClass1 - override def toString = - (if (prefix.isEmpty) "" else prefix.get.toString+"#") + - (if (runtimeClass.isArray) "Array" else runtimeClass.getName) + - argString - } - - def arrayType[T](arg: Manifest[_]): Manifest[Array[T]] = - arg.asInstanceOf[Manifest[T]].arrayManifest - - private class AbstractTypeManifest[T](prefix: Manifest[_], name: String, upperBound: Predef.Class[_], args: Seq[Manifest[_]]) extends Manifest[T] { - def runtimeClass = upperBound - override val typeArguments = args.toList - override def toString = prefix.toString+"#"+name+argString - } - - /** Manifest for the abstract type `prefix # name`. `upperBound` is not - * strictly necessary as it could be obtained by reflection. It was - * added so that erasure can be calculated without reflection. */ - def abstractType[T](prefix: Manifest[_], name: String, upperBound: Predef.Class[_], args: Manifest[_]*): Manifest[T] = - new AbstractTypeManifest[T](prefix, name, upperBound, args) - - private class WildcardManifest[T](lowerBound: Manifest[_], upperBound: Manifest[_]) extends Manifest[T] { - def runtimeClass = upperBound.runtimeClass - override def toString = - "_" + - (if (lowerBound eq Nothing) "" else " >: "+lowerBound) + - (if (upperBound eq Nothing) "" else " <: "+upperBound) - } - - /** Manifest for the unknown type `_ >: L <: U` in an existential. - */ - def wildcardType[T](lowerBound: Manifest[_], upperBound: Manifest[_]): Manifest[T] = - new WildcardManifest[T](lowerBound, upperBound) - - private class IntersectionTypeManifest[T](parents: Array[Manifest[_]]) extends Manifest[T] { - // We use an `Array` instead of a `Seq` for `parents` to avoid cyclic dependencies during deserialization - // which can cause serialization proxies to leak and cause a ClassCastException. - def runtimeClass = parents(0).runtimeClass - override def toString = parents.mkString(" with ") - } - - /** Manifest for the intersection type `parents_0 with ... with parents_n`. */ - def intersectionType[T](parents: Manifest[_]*): Manifest[T] = - new IntersectionTypeManifest[T](parents.toArray) -} diff --git a/scalalib/overrides-2.13.0-M3/scala/runtime/ScalaRunTime.scala b/scalalib/overrides-2.13.0-M3/scala/runtime/ScalaRunTime.scala deleted file mode 100644 index a536bd5fd6..0000000000 --- a/scalalib/overrides-2.13.0-M3/scala/runtime/ScalaRunTime.scala +++ /dev/null @@ -1,268 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala -package runtime - -import scala.collection.{ TraversableView, AbstractIterator, GenIterable } -import scala.collection.mutable.WrappedArray -import scala.collection.immutable.{ StringLike, NumericRange } -import scala.collection.generic.{ Sorted, IsTraversableLike } -import scala.reflect.{ ClassTag, classTag } -import java.lang.{ Class => jClass } - -import java.lang.reflect.{ Method => JMethod } - -/** The object ScalaRunTime provides support methods required by - * the scala runtime. All these methods should be considered - * outside the API and subject to change or removal without notice. - */ -object ScalaRunTime { - def isArray(x: Any, atLevel: Int = 1): Boolean = - x != null && isArrayClass(x.getClass, atLevel) - - private def isArrayClass(clazz: jClass[_], atLevel: Int): Boolean = - clazz != null && clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) - - // A helper method to make my life in the pattern matcher a lot easier. - def drop[Repr](coll: Repr, num: Int)(implicit traversable: IsTraversableLike[Repr]): Repr = - traversable conversion coll drop num - - /** Return the class object representing an array with element class `clazz`. - */ - def arrayClass(clazz: jClass[_]): jClass[_] = { - // newInstance throws an exception if the erasure is Void.TYPE. see SI-5680 - if (clazz == java.lang.Void.TYPE) classOf[Array[Unit]] - else java.lang.reflect.Array.newInstance(clazz, 0).getClass - } - - /** Return the class object representing an unboxed value type, - * e.g., classOf[int], not classOf[java.lang.Integer]. The compiler - * rewrites expressions like 5.getClass to come here. - */ - def anyValClass[T <: AnyVal : ClassTag](value: T): jClass[T] = - classTag[T].runtimeClass.asInstanceOf[jClass[T]] - - /** Retrieve generic array element */ - def array_apply(xs: AnyRef, idx: Int): Any = { - xs match { - case x: Array[AnyRef] => x(idx).asInstanceOf[Any] - case x: Array[Int] => x(idx).asInstanceOf[Any] - case x: Array[Double] => x(idx).asInstanceOf[Any] - case x: Array[Long] => x(idx).asInstanceOf[Any] - case x: Array[Float] => x(idx).asInstanceOf[Any] - case x: Array[Char] => x(idx).asInstanceOf[Any] - case x: Array[Byte] => x(idx).asInstanceOf[Any] - case x: Array[Short] => x(idx).asInstanceOf[Any] - case x: Array[Boolean] => x(idx).asInstanceOf[Any] - case x: Array[Unit] => x(idx).asInstanceOf[Any] - case null => throw new NullPointerException - } - } - - /** update generic array element */ - def array_update(xs: AnyRef, idx: Int, value: Any): Unit = { - xs match { - case x: Array[AnyRef] => x(idx) = value.asInstanceOf[AnyRef] - case x: Array[Int] => x(idx) = value.asInstanceOf[Int] - case x: Array[Double] => x(idx) = value.asInstanceOf[Double] - case x: Array[Long] => x(idx) = value.asInstanceOf[Long] - case x: Array[Float] => x(idx) = value.asInstanceOf[Float] - case x: Array[Char] => x(idx) = value.asInstanceOf[Char] - case x: Array[Byte] => x(idx) = value.asInstanceOf[Byte] - case x: Array[Short] => x(idx) = value.asInstanceOf[Short] - case x: Array[Boolean] => x(idx) = value.asInstanceOf[Boolean] - case x: Array[Unit] => x(idx) = value.asInstanceOf[Unit] - case null => throw new NullPointerException - } - } - - /** Get generic array length */ - def array_length(xs: AnyRef): Int = xs match { - case x: Array[AnyRef] => x.length - case x: Array[Int] => x.length - case x: Array[Double] => x.length - case x: Array[Long] => x.length - case x: Array[Float] => x.length - case x: Array[Char] => x.length - case x: Array[Byte] => x.length - case x: Array[Short] => x.length - case x: Array[Boolean] => x.length - case x: Array[Unit] => x.length - case null => throw new NullPointerException - } - - def array_clone(xs: AnyRef): AnyRef = xs match { - case x: Array[AnyRef] => x.clone() - case x: Array[Int] => x.clone() - case x: Array[Double] => x.clone() - case x: Array[Long] => x.clone() - case x: Array[Float] => x.clone() - case x: Array[Char] => x.clone() - case x: Array[Byte] => x.clone() - case x: Array[Short] => x.clone() - case x: Array[Boolean] => x.clone() - case x: Array[Unit] => x - case null => throw new NullPointerException - } - - /** Convert an array to an object array. - * Needed to deal with vararg arguments of primitive types that are passed - * to a generic Java vararg parameter T ... - */ - def toObjectArray(src: AnyRef): Array[Object] = src match { - case x: Array[AnyRef] => x - case _ => - val length = array_length(src) - val dest = new Array[Object](length) - for (i <- 0 until length) - array_update(dest, i, array_apply(src, i)) - dest - } - - def toArray[T](xs: scala.collection.Seq[T]) = { - val arr = new Array[AnyRef](xs.length) - var i = 0 - for (x <- xs) { - arr(i) = x.asInstanceOf[AnyRef] - i += 1 - } - arr - } - - // Java bug: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4071957 - // More background at ticket #2318. - def ensureAccessible(m: JMethod): JMethod = scala.reflect.ensureAccessible(m) - - def _toString(x: Product): String = - x.productIterator.mkString(x.productPrefix + "(", ",", ")") - - def _hashCode(x: Product): Int = scala.util.hashing.MurmurHash3.productHash(x) - - /** A helper for case classes. */ - def typedProductIterator[T](x: Product): Iterator[T] = { - new AbstractIterator[T] { - private var c: Int = 0 - private val cmax = x.productArity - def hasNext = c < cmax - def next() = { - val result = x.productElement(c) - c += 1 - result.asInstanceOf[T] - } - } - } - - /** Old implementation of `##`. */ - @deprecated("Use scala.runtime.Statics.anyHash instead.", "2.12.0") - def hash(x: Any): Int = Statics.anyHash(x.asInstanceOf[Object]) - - /** Given any Scala value, convert it to a String. - * - * The primary motivation for this method is to provide a means for - * correctly obtaining a String representation of a value, while - * avoiding the pitfalls of naively calling toString on said value. - * In particular, it addresses the fact that (a) toString cannot be - * called on null and (b) depending on the apparent type of an - * array, toString may or may not print it in a human-readable form. - * - * @param arg the value to stringify - * @return a string representation of arg. - */ - def stringOf(arg: Any): String = stringOf(arg, scala.Int.MaxValue) - def stringOf(arg: Any, maxElements: Int): String = { - def packageOf(x: AnyRef) = x.getClass.getPackage match { - case null => "" - case p => p.getName - } - def isScalaClass(x: AnyRef) = packageOf(x) startsWith "scala." - def isScalaCompilerClass(x: AnyRef) = packageOf(x) startsWith "scala.tools.nsc." - - // includes specialized subclasses and future proofed against hypothetical TupleN (for N > 22) - def isTuple(x: Any) = x != null && x.getClass.getName.startsWith("scala.Tuple") - - // We use reflection because the scala.xml package might not be available - def isSubClassOf(potentialSubClass: Class[_], ofClass: String) = - try { - val classLoader = potentialSubClass.getClassLoader - val clazz = Class.forName(ofClass, /*initialize =*/ false, classLoader) - clazz.isAssignableFrom(potentialSubClass) - } catch { - case cnfe: ClassNotFoundException => false - } - def isXmlNode(potentialSubClass: Class[_]) = isSubClassOf(potentialSubClass, "scala.xml.Node") - def isXmlMetaData(potentialSubClass: Class[_]) = isSubClassOf(potentialSubClass, "scala.xml.MetaData") - - // When doing our own iteration is dangerous - def useOwnToString(x: Any) = x match { - // Range/NumericRange have a custom toString to avoid walking a gazillion elements - case _: Range | _: NumericRange[_] => true - // Sorted collections to the wrong thing (for us) on iteration - ticket #3493 - case _: Sorted[_, _] => true - // StringBuilder(a, b, c) and similar not so attractive - case _: StringLike[_] => true - // Don't want to evaluate any elements in a view - case _: TraversableView[_, _] => true - // Node extends NodeSeq extends Seq[Node] and MetaData extends Iterable[MetaData] - // -> catch those by isXmlNode and isXmlMetaData. - // Don't want to a) traverse infinity or b) be overly helpful with peoples' custom - // collections which may have useful toString methods - ticket #3710 - // or c) print AbstractFiles which are somehow also Iterable[AbstractFile]s. - case x: Traversable[_] => !x.hasDefiniteSize || !isScalaClass(x) || isScalaCompilerClass(x) || isXmlNode(x.getClass) || isXmlMetaData(x.getClass) - // Otherwise, nothing could possibly go wrong - case _ => false - } - - // A variation on inner for maps so they print -> instead of bare tuples - def mapInner(arg: Any): String = arg match { - case (k, v) => inner(k) + " -> " + inner(v) - case _ => inner(arg) - } - - // Special casing Unit arrays, the value class which uses a reference array type. - def arrayToString(x: AnyRef) = { - if (x.getClass.getComponentType == classOf[BoxedUnit]) - 0 until (array_length(x) min maxElements) map (_ => "()") mkString ("Array(", ", ", ")") - else - WrappedArray make x take maxElements map inner mkString ("Array(", ", ", ")") - } - - // The recursively applied attempt to prettify Array printing. - // Note that iterator is used if possible and foreach is used as a - // last resort, because the parallel collections "foreach" in a - // random order even on sequences. - def inner(arg: Any): String = arg match { - case null => "null" - case "" => "\"\"" - case x: String => if (x.head.isWhitespace || x.last.isWhitespace) "\"" + x + "\"" else x - case x if useOwnToString(x) => x.toString - case x: AnyRef if isArray(x) => arrayToString(x) - case x: scala.collection.Map[_, _] => x.iterator take maxElements map mapInner mkString (x.stringPrefix + "(", ", ", ")") - case x: GenIterable[_] => x.iterator take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")") - case x: Traversable[_] => x take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")") - case x: Product1[_] if isTuple(x) => "(" + inner(x._1) + ",)" // that special trailing comma - case x: Product if isTuple(x) => x.productIterator map inner mkString ("(", ",", ")") - case x => x.toString - } - - // The try/catch is defense against iterables which aren't actually designed - // to be iterated, such as some scala.tools.nsc.io.AbstractFile derived classes. - try inner(arg) - catch { - case _: UnsupportedOperationException | _: AssertionError => "" + arg - } - } - - /** stringOf formatted for use in a repl result. */ - def replStringOf(arg: Any, maxElements: Int): String = { - val s = stringOf(arg, maxElements) - val nl = if (s contains "\n") "\n" else "" - - nl + s + "\n" - } -} diff --git a/scalalib/overrides-2.13.0-M4/scala/Array.scala b/scalalib/overrides-2.13.0-M4/scala/Array.scala deleted file mode 100644 index 66753eac27..0000000000 --- a/scalalib/overrides-2.13.0-M4/scala/Array.scala +++ /dev/null @@ -1,615 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala - -//import scala.collection.generic._ -import scala.collection.{Factory, immutable, mutable} -import mutable.ArrayBuilder -import immutable.ArraySeq -import scala.language.implicitConversions -import scala.reflect.ClassTag -import scala.runtime.ScalaRunTime -import scala.runtime.ScalaRunTime.{array_apply, array_update} - -/** Utility methods for operating on arrays. - * For example: - * {{{ - * val a = Array(1, 2) - * val b = Array.ofDim[Int](2) - * val c = Array.concat(a, b) - * }}} - * where the array objects `a`, `b` and `c` have respectively the values - * `Array(1, 2)`, `Array(0, 0)` and `Array(1, 2, 0, 0)`. - * - * @author Martin Odersky - * @version 1.0 - */ -object Array { - def emptyBooleanArray = EmptyArrays.emptyBooleanArray - def emptyByteArray = EmptyArrays.emptyByteArray - def emptyCharArray = EmptyArrays.emptyCharArray - def emptyDoubleArray = EmptyArrays.emptyDoubleArray - def emptyFloatArray = EmptyArrays.emptyFloatArray - def emptyIntArray = EmptyArrays.emptyIntArray - def emptyLongArray = EmptyArrays.emptyLongArray - def emptyShortArray = EmptyArrays.emptyShortArray - def emptyObjectArray = EmptyArrays.emptyObjectArray - - private object EmptyArrays { - val emptyBooleanArray = new Array[Boolean](0) - val emptyByteArray = new Array[Byte](0) - val emptyCharArray = new Array[Char](0) - val emptyDoubleArray = new Array[Double](0) - val emptyFloatArray = new Array[Float](0) - val emptyIntArray = new Array[Int](0) - val emptyLongArray = new Array[Long](0) - val emptyShortArray = new Array[Short](0) - val emptyObjectArray = new Array[Object](0) - } - - /** Provides an implicit conversion from the Array object to a collection Factory */ - implicit def toFactory[A : ClassTag](dummy: Array.type): Factory[A, Array[A]] = - new Factory[A, Array[A]] { - def fromSpecific(it: IterableOnce[A]): Array[A] = Array.from[A](it) - def newBuilder: mutable.Builder[A, Array[A]] = Array.newBuilder[A] - } - - /** - * Returns a new [[scala.collection.mutable.ArrayBuilder]]. - */ - def newBuilder[T](implicit t: ClassTag[T]): ArrayBuilder[T] = ArrayBuilder.make[T](t) - - def from[A : ClassTag](it: IterableOnce[A]): Array[A] = { - val b = ArrayBuilder.make[A] - val iterator = it.iterator - while (iterator.hasNext) - b += iterator.next() - b.result() - } - - private def slowcopy(src : AnyRef, - srcPos : Int, - dest : AnyRef, - destPos : Int, - length : Int) { - var i = srcPos - var j = destPos - val srcUntil = srcPos + length - while (i < srcUntil) { - array_update(dest, j, array_apply(src, i)) - i += 1 - j += 1 - } - } - - /** Copy one array to another. - * Equivalent to Java's - * `System.arraycopy(src, srcPos, dest, destPos, length)`, - * except that this also works for polymorphic and boxed arrays. - * - * Note that the passed-in `dest` array will be modified by this call. - * - * @param src the source array. - * @param srcPos starting position in the source array. - * @param dest destination array. - * @param destPos starting position in the destination array. - * @param length the number of array elements to be copied. - * - * @see `java.lang.System#arraycopy` - */ - def copy(src: AnyRef, srcPos: Int, dest: AnyRef, destPos: Int, length: Int) { - val srcClass = src.getClass - if (srcClass.isArray && dest.getClass.isAssignableFrom(srcClass)) - java.lang.System.arraycopy(src, srcPos, dest, destPos, length) - else - slowcopy(src, srcPos, dest, destPos, length) - } - - /** Copy one array to another, truncating or padding with default values (if - * necessary) so the copy has the specified length. - * - * Equivalent to Java's - * `java.util.Arrays.copyOf(original, newLength)`, - * except that this works for primitive and object arrays in a single method. - * - * @see `java.util.Arrays#copyOf` - */ - def copyOf[A](original: Array[A], newLength: Int): Array[A] = (original match { - case x: Array[AnyRef] => java.util.Arrays.copyOf(x, newLength) - case x: Array[Int] => java.util.Arrays.copyOf(x, newLength) - case x: Array[Double] => java.util.Arrays.copyOf(x, newLength) - case x: Array[Long] => java.util.Arrays.copyOf(x, newLength) - case x: Array[Float] => java.util.Arrays.copyOf(x, newLength) - case x: Array[Char] => java.util.Arrays.copyOf(x, newLength) - case x: Array[Byte] => java.util.Arrays.copyOf(x, newLength) - case x: Array[Short] => java.util.Arrays.copyOf(x, newLength) - case x: Array[Boolean] => java.util.Arrays.copyOf(x, newLength) - case x: Array[Unit] => - val dest = new Array[Unit](newLength) - Array.copy(original, 0, dest, 0, original.length) - dest - }).asInstanceOf[Array[A]] - - /** Copy one array to another, truncating or padding with default values (if - * necessary) so the copy has the specified length. The new array can have - * a different type than the original one as long as the values are - * assignment-compatible. When copying between primitive and object arrays, - * boxing and unboxing are supported. - * - * Equivalent to Java's - * `java.util.Arrays.copyOf(original, newLength, newType)`, - * except that this works for all combinations of primitive and object arrays - * in a single method. - * - * @see `java.util.Arrays#copyOf` - */ - def copyAs[A](original: Array[_], newLength: Int)(implicit ct: ClassTag[A]): Array[A] = { - val destClass = ct.runtimeClass.asInstanceOf[Class[A]] - if (destClass.isAssignableFrom(original.getClass.getComponentType)) { - if(destClass.isPrimitive) copyOf[A](original.asInstanceOf[Array[A]], newLength) - else { - val destArrayClass = java.lang.reflect.Array.newInstance(destClass, 0).getClass.asInstanceOf[Class[Array[AnyRef]]] - java.util.Arrays.copyOf(original.asInstanceOf[Array[AnyRef]], newLength, destArrayClass).asInstanceOf[Array[A]] - } - } else { - val dest = new Array[A](newLength) - Array.copy(original, 0, dest, 0, original.length) - dest - } - } - - /** Returns an array of length 0 */ - def empty[T: ClassTag]: Array[T] = new Array[T](0) - - /** Creates an array with given elements. - * - * @param xs the elements to put in the array - * @return an array containing all elements from xs. - */ - // Subject to a compiler optimization in Cleanup. - // Array(e0, ..., en) is translated to { val a = new Array(3); a(i) = ei; a } - def apply[T: ClassTag](xs: T*): Array[T] = { - val array = new Array[T](xs.length) - var i = 0 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Boolean` objects */ - // Subject to a compiler optimization in Cleanup, see above. - def apply(x: Boolean, xs: Boolean*): Array[Boolean] = { - val array = new Array[Boolean](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Byte` objects */ - // Subject to a compiler optimization in Cleanup, see above. - def apply(x: Byte, xs: Byte*): Array[Byte] = { - val array = new Array[Byte](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Short` objects */ - // Subject to a compiler optimization in Cleanup, see above. - def apply(x: Short, xs: Short*): Array[Short] = { - val array = new Array[Short](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Char` objects */ - // Subject to a compiler optimization in Cleanup, see above. - def apply(x: Char, xs: Char*): Array[Char] = { - val array = new Array[Char](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Int` objects */ - // Subject to a compiler optimization in Cleanup, see above. - def apply(x: Int, xs: Int*): Array[Int] = { - val array = new Array[Int](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Long` objects */ - // Subject to a compiler optimization in Cleanup, see above. - def apply(x: Long, xs: Long*): Array[Long] = { - val array = new Array[Long](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Float` objects */ - // Subject to a compiler optimization in Cleanup, see above. - def apply(x: Float, xs: Float*): Array[Float] = { - val array = new Array[Float](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Double` objects */ - // Subject to a compiler optimization in Cleanup, see above. - def apply(x: Double, xs: Double*): Array[Double] = { - val array = new Array[Double](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates an array of `Unit` objects */ - def apply(x: Unit, xs: Unit*): Array[Unit] = { - val array = new Array[Unit](xs.length + 1) - array(0) = x - var i = 1 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } - - /** Creates array with given dimensions */ - def ofDim[T: ClassTag](n1: Int): Array[T] = - new Array[T](n1) - /** Creates a 2-dimensional array */ - def ofDim[T: ClassTag](n1: Int, n2: Int): Array[Array[T]] = { - val arr: Array[Array[T]] = (new Array[Array[T]](n1): Array[Array[T]]) - for (i <- 0 until n1) arr(i) = new Array[T](n2) - arr - // tabulate(n1)(_ => ofDim[T](n2)) - } - /** Creates a 3-dimensional array */ - def ofDim[T: ClassTag](n1: Int, n2: Int, n3: Int): Array[Array[Array[T]]] = - tabulate(n1)(_ => ofDim[T](n2, n3)) - /** Creates a 4-dimensional array */ - def ofDim[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int): Array[Array[Array[Array[T]]]] = - tabulate(n1)(_ => ofDim[T](n2, n3, n4)) - /** Creates a 5-dimensional array */ - def ofDim[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int): Array[Array[Array[Array[Array[T]]]]] = - tabulate(n1)(_ => ofDim[T](n2, n3, n4, n5)) - - /** Concatenates all arrays into a single array. - * - * @param xss the given arrays - * @return the array created from concatenating `xss` - */ - def concat[T: ClassTag](xss: Array[T]*): Array[T] = { - val b = newBuilder[T] - b.sizeHint(xss.map(_.length).sum) - for (xs <- xss) b ++= xs - b.result() - } - - /** Returns an array that contains the results of some element computation a number - * of times. - * - * Note that this means that `elem` is computed a total of n times: - * {{{ - * scala> Array.fill(3){ math.random } - * res3: Array[Double] = Array(0.365461167592537, 1.550395944913685E-4, 0.7907242137333306) - * }}} - * - * @param n the number of elements desired - * @param elem the element computation - * @return an Array of size n, where each element contains the result of computing - * `elem`. - */ - def fill[T: ClassTag](n: Int)(elem: => T): Array[T] = { - val b = newBuilder[T] - b.sizeHint(n) - var i = 0 - while (i < n) { - b += elem - i += 1 - } - b.result() - } - - /** Returns a two-dimensional array that contains the results of some element - * computation a number of times. - * - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param elem the element computation - */ - def fill[T: ClassTag](n1: Int, n2: Int)(elem: => T): Array[Array[T]] = - tabulate(n1)(_ => fill(n2)(elem)) - - /** Returns a three-dimensional array that contains the results of some element - * computation a number of times. - * - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param n3 the number of elements in the 3nd dimension - * @param elem the element computation - */ - def fill[T: ClassTag](n1: Int, n2: Int, n3: Int)(elem: => T): Array[Array[Array[T]]] = - tabulate(n1)(_ => fill(n2, n3)(elem)) - - /** Returns a four-dimensional array that contains the results of some element - * computation a number of times. - * - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param n3 the number of elements in the 3nd dimension - * @param n4 the number of elements in the 4th dimension - * @param elem the element computation - */ - def fill[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int)(elem: => T): Array[Array[Array[Array[T]]]] = - tabulate(n1)(_ => fill(n2, n3, n4)(elem)) - - /** Returns a five-dimensional array that contains the results of some element - * computation a number of times. - * - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param n3 the number of elements in the 3nd dimension - * @param n4 the number of elements in the 4th dimension - * @param n5 the number of elements in the 5th dimension - * @param elem the element computation - */ - def fill[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(elem: => T): Array[Array[Array[Array[Array[T]]]]] = - tabulate(n1)(_ => fill(n2, n3, n4, n5)(elem)) - - /** Returns an array containing values of a given function over a range of integer - * values starting from 0. - * - * @param n The number of elements in the array - * @param f The function computing element values - * @return A traversable consisting of elements `f(0),f(1), ..., f(n - 1)` - */ - def tabulate[T: ClassTag](n: Int)(f: Int => T): Array[T] = { - val b = newBuilder[T] - b.sizeHint(n) - var i = 0 - while (i < n) { - b += f(i) - i += 1 - } - b.result() - } - - /** Returns a two-dimensional array containing values of a given function - * over ranges of integer values starting from `0`. - * - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param f The function computing element values - */ - def tabulate[T: ClassTag](n1: Int, n2: Int)(f: (Int, Int) => T): Array[Array[T]] = - tabulate(n1)(i1 => tabulate(n2)(f(i1, _))) - - /** Returns a three-dimensional array containing values of a given function - * over ranges of integer values starting from `0`. - * - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param n3 the number of elements in the 3rd dimension - * @param f The function computing element values - */ - def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int)(f: (Int, Int, Int) => T): Array[Array[Array[T]]] = - tabulate(n1)(i1 => tabulate(n2, n3)(f(i1, _, _))) - - /** Returns a four-dimensional array containing values of a given function - * over ranges of integer values starting from `0`. - * - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param n3 the number of elements in the 3rd dimension - * @param n4 the number of elements in the 4th dimension - * @param f The function computing element values - */ - def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int)(f: (Int, Int, Int, Int) => T): Array[Array[Array[Array[T]]]] = - tabulate(n1)(i1 => tabulate(n2, n3, n4)(f(i1, _, _, _))) - - /** Returns a five-dimensional array containing values of a given function - * over ranges of integer values starting from `0`. - * - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param n3 the number of elements in the 3rd dimension - * @param n4 the number of elements in the 4th dimension - * @param n5 the number of elements in the 5th dimension - * @param f The function computing element values - */ - def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(f: (Int, Int, Int, Int, Int) => T): Array[Array[Array[Array[Array[T]]]]] = - tabulate(n1)(i1 => tabulate(n2, n3, n4, n5)(f(i1, _, _, _, _))) - - /** Returns an array containing a sequence of increasing integers in a range. - * - * @param start the start value of the array - * @param end the end value of the array, exclusive (in other words, this is the first value '''not''' returned) - * @return the array with values in range `start, start + 1, ..., end - 1` - * up to, but excluding, `end`. - */ - def range(start: Int, end: Int): Array[Int] = range(start, end, 1) - - /** Returns an array containing equally spaced values in some integer interval. - * - * @param start the start value of the array - * @param end the end value of the array, exclusive (in other words, this is the first value '''not''' returned) - * @param step the increment value of the array (may not be zero) - * @return the array with values in `start, start + step, ...` up to, but excluding `end` - */ - def range(start: Int, end: Int, step: Int): Array[Int] = { - if (step == 0) throw new IllegalArgumentException("zero step") - val b = newBuilder[Int] - b.sizeHint(immutable.Range.count(start, end, step, isInclusive = false)) - - var i = start - while (if (step < 0) end < i else i < end) { - b += i - i += step - } - b.result() - } - - /** Returns an array containing repeated applications of a function to a start value. - * - * @param start the start value of the array - * @param len the number of elements returned by the array - * @param f the function that is repeatedly applied - * @return the array returning `len` values in the sequence `start, f(start), f(f(start)), ...` - */ - def iterate[T: ClassTag](start: T, len: Int)(f: T => T): Array[T] = { - val b = newBuilder[T] - - if (len > 0) { - b.sizeHint(len) - var acc = start - var i = 1 - b += acc - - while (i < len) { - acc = f(acc) - i += 1 - b += acc - } - } - b.result() - } - - /** Called in a pattern match like `{ case Array(x,y,z) => println('3 elements')}`. - * - * @param x the selector value - * @return sequence wrapped in a [[scala.Some]], if `x` is an Array, otherwise `None` - */ - def unapplySeq[T](x: Array[T]): Option[IndexedSeq[T]] = - if (x == null) None else Some(ArraySeq.unsafeWrapArray[T](x)) - // !!! the null check should to be necessary, but without it 2241 fails. Seems to be a bug - // in pattern matcher. @PP: I noted in #4364 I think the behavior is correct. - // Is ArraySeq safe here? In 2.12 we used to call .toIndexedSeq which copied the array - // instead of wrapping it in a ArraySeq but it appears unnecessary. -} - -/** Arrays are mutable, indexed collections of values. `Array[T]` is Scala's representation - * for Java's `T[]`. - * - * {{{ - * val numbers = Array(1, 2, 3, 4) - * val first = numbers(0) // read the first element - * numbers(3) = 100 // replace the 4th array element with 100 - * val biggerNumbers = numbers.map(_ * 2) // multiply all numbers by two - * }}} - * - * Arrays make use of two common pieces of Scala syntactic sugar, shown on lines 2 and 3 of the above - * example code. - * Line 2 is translated into a call to `apply(Int)`, while line 3 is translated into a call to - * `update(Int, T)`. - * - * Two implicit conversions exist in [[scala.Predef]] that are frequently applied to arrays: a conversion - * to [[scala.collection.mutable.ArrayOps]] (shown on line 4 of the example above) and a conversion - * to [[scala.collection.mutable.ArraySeq]] (a subtype of [[scala.collection.Seq]]). - * Both types make available many of the standard operations found in the Scala collections API. - * The conversion to `ArrayOps` is temporary, as all operations defined on `ArrayOps` return an `Array`, - * while the conversion to `ArraySeq` is permanent as all operations return a `ArraySeq`. - * - * The conversion to `ArrayOps` takes priority over the conversion to `ArraySeq`. For instance, - * consider the following code: - * - * {{{ - * val arr = Array(1, 2, 3) - * val arrReversed = arr.reverse - * val seqReversed : Seq[Int] = arr.reverse - * }}} - * - * Value `arrReversed` will be of type `Array[Int]`, with an implicit conversion to `ArrayOps` occurring - * to perform the `reverse` operation. The value of `seqReversed`, on the other hand, will be computed - * by converting to `ArraySeq` first and invoking the variant of `reverse` that returns another - * `ArraySeq`. - * - * @author Martin Odersky - * @version 1.0 - * @see [[http://www.scala-lang.org/files/archive/spec/2.11/ Scala Language Specification]], for in-depth information on the transformations the Scala compiler makes on Arrays (Sections 6.6 and 6.15 respectively.) - * @see [[http://docs.scala-lang.org/sips/completed/scala-2-8-arrays.html "Scala 2.8 Arrays"]] the Scala Improvement Document detailing arrays since Scala 2.8. - * @see [[http://docs.scala-lang.org/overviews/collections/arrays.html "The Scala 2.8 Collections' API"]] section on `Array` by Martin Odersky for more information. - * @hideImplicitConversion scala.Predef.booleanArrayOps - * @hideImplicitConversion scala.Predef.byteArrayOps - * @hideImplicitConversion scala.Predef.charArrayOps - * @hideImplicitConversion scala.Predef.doubleArrayOps - * @hideImplicitConversion scala.Predef.floatArrayOps - * @hideImplicitConversion scala.Predef.intArrayOps - * @hideImplicitConversion scala.Predef.longArrayOps - * @hideImplicitConversion scala.Predef.refArrayOps - * @hideImplicitConversion scala.Predef.shortArrayOps - * @hideImplicitConversion scala.Predef.unitArrayOps - * @hideImplicitConversion scala.LowPriorityImplicits.wrapRefArray - * @hideImplicitConversion scala.LowPriorityImplicits.wrapIntArray - * @hideImplicitConversion scala.LowPriorityImplicits.wrapDoubleArray - * @hideImplicitConversion scala.LowPriorityImplicits.wrapLongArray - * @hideImplicitConversion scala.LowPriorityImplicits.wrapFloatArray - * @hideImplicitConversion scala.LowPriorityImplicits.wrapCharArray - * @hideImplicitConversion scala.LowPriorityImplicits.wrapByteArray - * @hideImplicitConversion scala.LowPriorityImplicits.wrapShortArray - * @hideImplicitConversion scala.LowPriorityImplicits.wrapBooleanArray - * @hideImplicitConversion scala.LowPriorityImplicits.wrapUnitArray - * @hideImplicitConversion scala.LowPriorityImplicits.genericWrapArray - * @define coll array - * @define Coll `Array` - * @define orderDependent - * @define orderDependentFold - * @define mayNotTerminateInf - * @define willNotTerminateInf - * @define collectExample - * @define undefinedorder - * @define thatinfo the class of the returned collection. In the standard library configuration, - * `That` is either `Array[B]` if an ClassTag is available for B or `ArraySeq[B]` otherwise. - * @define zipthatinfo $thatinfo - * @define bfinfo an implicit value of class `CanBuildFrom` which determines the result class `That` from the current - * representation type `Repr` and the new element type `B`. - */ -final class Array[T](_length: Int) extends java.io.Serializable with java.lang.Cloneable { - - /** The length of the array */ - def length: Int = throw new Error() - - /** The element at given index. - * - * Indices start at `0`; `xs.apply(0)` is the first element of array `xs`. - * Note the indexing syntax `xs(i)` is a shorthand for `xs.apply(i)`. - * - * @param i the index - * @return the element at the given index - * @throws ArrayIndexOutOfBoundsException if `i < 0` or `length <= i` - */ - def apply(i: Int): T = throw new Error() - - /** Update the element at given index. - * - * Indices start at `0`; `xs.update(i, x)` replaces the i^th^ element in the array. - * Note the syntax `xs(i) = x` is a shorthand for `xs.update(i, x)`. - * - * @param i the index - * @param x the value to be written at index `i` - * @throws ArrayIndexOutOfBoundsException if `i < 0` or `length <= i` - */ - def update(i: Int, x: T) { throw new Error() } - - /** Clone the Array. - * - * @return A clone of the Array. - */ - override def clone(): Array[T] = throw new Error() -} diff --git a/scalalib/overrides-2.13.0-M4/scala/Enumeration.scala b/scalalib/overrides-2.13.0-M4/scala/Enumeration.scala deleted file mode 100644 index cd2469466b..0000000000 --- a/scalalib/overrides-2.13.0-M4/scala/Enumeration.scala +++ /dev/null @@ -1,302 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala - -import scala.collection.{ mutable, immutable, StrictOptimizedIterableOps, SpecificIterableFactory, View } -import java.lang.reflect.{ Method => JMethod, Field => JField } -import scala.reflect.NameTransformer._ -import scala.util.matching.Regex - -/** Defines a finite set of values specific to the enumeration. Typically - * these values enumerate all possible forms something can take and provide - * a lightweight alternative to case classes. - * - * Each call to a `Value` method adds a new unique value to the enumeration. - * To be accessible, these values are usually defined as `val` members of - * the enumeration. - * - * All values in an enumeration share a common, unique type defined as the - * `Value` type member of the enumeration (`Value` selected on the stable - * identifier path of the enumeration instance). - * - * @example {{{ - * // Define a new enumeration with a type alias and work with the full set of enumerated values - * object WeekDay extends Enumeration { - * type WeekDay = Value - * val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value - * } - * import WeekDay._ - * - * def isWorkingDay(d: WeekDay) = ! (d == Sat || d == Sun) - * - * WeekDay.values filter isWorkingDay foreach println - * // output: - * // Mon - * // Tue - * // Wed - * // Thu - * // Fri - * }}} - * - * @example {{{ - * // Example of adding attributes to an enumeration by extending the Enumeration.Val class - * object Planet extends Enumeration { - * protected case class Val(mass: Double, radius: Double) extends super.Val { - * def surfaceGravity: Double = Planet.G * mass / (radius * radius) - * def surfaceWeight(otherMass: Double): Double = otherMass * surfaceGravity - * } - * implicit def valueToPlanetVal(x: Value): Val = x.asInstanceOf[Val] - * - * val G: Double = 6.67300E-11 - * val Mercury = Val(3.303e+23, 2.4397e6) - * val Venus = Val(4.869e+24, 6.0518e6) - * val Earth = Val(5.976e+24, 6.37814e6) - * val Mars = Val(6.421e+23, 3.3972e6) - * val Jupiter = Val(1.9e+27, 7.1492e7) - * val Saturn = Val(5.688e+26, 6.0268e7) - * val Uranus = Val(8.686e+25, 2.5559e7) - * val Neptune = Val(1.024e+26, 2.4746e7) - * } - * - * println(Planet.values.filter(_.radius > 7.0e6)) - * // output: - * // Planet.ValueSet(Jupiter, Saturn, Uranus, Neptune) - * }}} - * - * @param initial The initial value from which to count the integers that - * identifies values at run-time. - * @author Matthias Zenger - */ -@SerialVersionUID(8476000850333817230L) -abstract class Enumeration (initial: Int) extends Serializable { - thisenum => - - def this() = this(0) - - /* Note that `readResolve` cannot be private, since otherwise - the JVM does not invoke it when deserializing subclasses. */ - protected def readResolve(): AnyRef = ??? - - /** The name of this enumeration. - */ - override def toString = - (getClass.getName.stripSuffix("$").split('.')).last.split('$').last - - /** The mapping from the integer used to identify values to the actual - * values. */ - private val vmap: mutable.Map[Int, Value] = new mutable.HashMap - - /** The cache listing all values of this enumeration. */ - @transient private var vset: ValueSet = null - @transient @volatile private var vsetDefined = false - - /** The mapping from the integer used to identify values to their - * names. */ - private val nmap: mutable.Map[Int, String] = new mutable.HashMap - - /** The values of this enumeration as a set. - */ - def values: ValueSet = { - if (!vsetDefined) { - vset = (ValueSet.newBuilder ++= vmap.values).result() - vsetDefined = true - } - vset - } - - /** The integer to use to identify the next created value. */ - protected var nextId: Int = initial - - /** The string to use to name the next created value. */ - protected var nextName: Iterator[String] = _ - - private def nextNameOrNull = - if (nextName != null && nextName.hasNext) nextName.next() else null - - /** The highest integer amongst those used to identify values in this - * enumeration. */ - private var topId = initial - - /** The lowest integer amongst those used to identify values in this - * enumeration, but no higher than 0. */ - private var bottomId = if(initial < 0) initial else 0 - - /** The one higher than the highest integer amongst those used to identify - * values in this enumeration. */ - final def maxId = topId - - /** The value of this enumeration with given id `x` - */ - final def apply(x: Int): Value = vmap(x) - - /** Return a `Value` from this `Enumeration` whose name matches - * the argument `s`. The names are determined automatically via reflection. - * - * @param s an `Enumeration` name - * @return the `Value` of this `Enumeration` if its name matches `s` - * @throws NoSuchElementException if no `Value` with a matching - * name is in this `Enumeration` - */ - final def withName(s: String): Value = { - val (unnamed, named) = values partition { - _.toString().startsWith(" v - // If we have unnamed values, we issue a detailed error message - case None if unnamed.nonEmpty => - throw new NoSuchElementException( - s"""Couldn't find enum field with name $s. - |However, there were the following unnamed fields: - |${unnamed.mkString(" ","\n ","")}""".stripMargin) - // Normal case (no unnamed Values) - case _ => None.get - } - } - - /** Creates a fresh value, part of this enumeration. */ - protected final def Value: Value = Value(nextId) - - /** Creates a fresh value, part of this enumeration, identified by the - * integer `i`. - * - * @param i An integer that identifies this value at run-time. It must be - * unique amongst all values of the enumeration. - * @return Fresh value identified by `i`. - */ - protected final def Value(i: Int): Value = Value(i, nextNameOrNull) - - /** Creates a fresh value, part of this enumeration, called `name`. - * - * @param name A human-readable name for that value. - * @return Fresh value called `name`. - */ - protected final def Value(name: String): Value = Value(nextId, name) - - /** Creates a fresh value, part of this enumeration, called `name` - * and identified by the integer `i`. - * - * @param i An integer that identifies this value at run-time. It must be - * unique amongst all values of the enumeration. - * @param name A human-readable name for that value. - * @return Fresh value with the provided identifier `i` and name `name`. - */ - protected final def Value(i: Int, name: String): Value = new Val(i, name) - - /** The type of the enumerated values. */ - @SerialVersionUID(7091335633555234129L) - abstract class Value extends Ordered[Value] with Serializable { - /** the id and bit location of this enumeration value */ - def id: Int - /** a marker so we can tell whose values belong to whom come reflective-naming time */ - private[Enumeration] val outerEnum = thisenum - - override def compare(that: Value): Int = - if (this.id < that.id) -1 - else if (this.id == that.id) 0 - else 1 - override def equals(other: Any) = other match { - case that: Enumeration#Value => (outerEnum eq that.outerEnum) && (id == that.id) - case _ => false - } - override def hashCode: Int = id.## - - /** Create a ValueSet which contains this value and another one */ - def + (v: Value) = ValueSet(this, v) - } - - /** A class implementing the [[scala.Enumeration.Value]] type. This class - * can be overridden to change the enumeration's naming and integer - * identification behaviour. - */ - @SerialVersionUID(0 - 3501153230598116017L) - protected class Val(i: Int, name: String) extends Value with Serializable { - def this(i: Int) = this(i, nextNameOrNull) - def this(name: String) = this(nextId, name) - def this() = this(nextId) - - assert(!vmap.isDefinedAt(i), "Duplicate id: " + i) - vmap(i) = this - vsetDefined = false - nextId = i + 1 - if (nextId > topId) topId = nextId - if (i < bottomId) bottomId = i - def id = i - override def toString() = - if (name != null) name - // Scala.js specific - else s"" - - protected def readResolve(): AnyRef = { - val enum = thisenum.readResolve().asInstanceOf[Enumeration] - if (enum.vmap == null) this - else enum.vmap(i) - } - } - - /** An ordering by id for values of this set */ - object ValueOrdering extends Ordering[Value] { - def compare(x: Value, y: Value): Int = x compare y - } - - /** A class for sets of values. - * Iterating through this set will yield values in increasing order of their ids. - * - * @param nnIds The set of ids of values (adjusted so that the lowest value does - * not fall below zero), organized as a `BitSet`. - * @define Coll `collection.immutable.SortedSet` - */ - class ValueSet private[ValueSet] (private[this] var nnIds: immutable.BitSet) - extends immutable.AbstractSet[Value] - with immutable.SortedSet[Value] - with immutable.SetOps[Value, immutable.Set, ValueSet] - with StrictOptimizedIterableOps[Value, immutable.Set, ValueSet] - with Serializable { - - implicit def ordering: Ordering[Value] = ValueOrdering - def rangeImpl(from: Option[Value], until: Option[Value]): ValueSet = - new ValueSet(nnIds.rangeImpl(from.map(_.id - bottomId), until.map(_.id - bottomId))) - - override def empty = ValueSet.empty - def contains(v: Value) = nnIds contains (v.id - bottomId) - def incl (value: Value) = new ValueSet(nnIds + (value.id - bottomId)) - def excl (value: Value) = new ValueSet(nnIds - (value.id - bottomId)) - def iterator = nnIds.iterator map (id => thisenum.apply(bottomId + id)) - override def iteratorFrom(start: Value) = nnIds iteratorFrom start.id map (id => thisenum.apply(bottomId + id)) - override def className = thisenum + ".ValueSet" - /** Creates a bit mask for the zero-adjusted ids in this set as a - * new array of longs */ - def toBitMask: Array[Long] = nnIds.toBitMask - - override protected def fromSpecificIterable(coll: Iterable[Value]) = ValueSet.fromSpecific(coll) - override protected def newSpecificBuilder = ValueSet.newBuilder - - def map(f: Value => Value): ValueSet = fromSpecificIterable(new View.Map(toIterable, f)) - def flatMap(f: Value => IterableOnce[Value]): ValueSet = fromSpecificIterable(new View.FlatMap(toIterable, f)) - } - - /** A factory object for value sets */ - object ValueSet extends SpecificIterableFactory[Value, ValueSet] { - /** The empty value set */ - val empty = new ValueSet(immutable.BitSet.empty) - /** A value set containing all the values for the zero-adjusted ids - * corresponding to the bits in an array */ - def fromBitMask(elems: Array[Long]): ValueSet = new ValueSet(immutable.BitSet.fromBitMask(elems)) - /** A builder object for value sets */ - def newBuilder: mutable.Builder[Value, ValueSet] = new mutable.Builder[Value, ValueSet] { - private[this] val b = new mutable.BitSet - def addOne (x: Value) = { b += (x.id - bottomId); this } - def clear() = b.clear() - def result() = new ValueSet(b.toImmutable) - } - def fromSpecific(it: IterableOnce[Value]): ValueSet = - newBuilder.addAll(it).result() - } -} diff --git a/scalalib/overrides-2.13.0-M4/scala/collection/immutable/NumericRange.scala b/scalalib/overrides-2.13.0-M4/scala/collection/immutable/NumericRange.scala deleted file mode 100644 index 69f69051c2..0000000000 --- a/scalalib/overrides-2.13.0-M4/scala/collection/immutable/NumericRange.scala +++ /dev/null @@ -1,409 +0,0 @@ -package scala.collection.immutable - -import scala.collection.{SeqFactory, IterableFactory, IterableOnce, Iterator, StrictOptimizedIterableOps} - -import java.lang.String - -import scala.collection.mutable.Builder - -/** `NumericRange` is a more generic version of the - * `Range` class which works with arbitrary types. - * It must be supplied with an `Integral` implementation of the - * range type. - * - * Factories for likely types include `Range.BigInt`, `Range.Long`, - * and `Range.BigDecimal`. `Range.Int` exists for completeness, but - * the `Int`-based `scala.Range` should be more performant. - * - * {{{ - * val r1 = new Range(0, 100, 1) - * val veryBig = Int.MaxValue.toLong + 1 - * val r2 = Range.Long(veryBig, veryBig + 100, 1) - * assert(r1 sameElements r2.map(_ - veryBig)) - * }}} - * - * @define Coll `NumericRange` - * @define coll numeric range - * @define mayNotTerminateInf - * @define willNotTerminateInf - */ -@SerialVersionUID(3L) -sealed class NumericRange[T]( - val start: T, - val end: T, - val step: T, - val isInclusive: Boolean -)(implicit - num: Integral[T] -) - extends AbstractSeq[T] - with IndexedSeq[T] - with IndexedSeqOps[T, IndexedSeq, IndexedSeq[T]] - with StrictOptimizedSeqOps[T, IndexedSeq, IndexedSeq[T]] - with Serializable { self => - - override def iterator() = new Iterator[T] { - import num.mkNumericOps - - private var _hasNext = !self.isEmpty - private var _next: T = start - private val lastElement: T = if (_hasNext) last else start - override def knownSize: Int = if (_hasNext) num.toInt((lastElement - _next) / step) + 1 else 0 - def hasNext: Boolean = _hasNext - def next(): T = { - if (!_hasNext) Iterator.empty.next() - val value = _next - _hasNext = value != lastElement - _next = num.plus(value, step) - value - } - } - - /** Note that NumericRange must be invariant so that constructs - * such as "1L to 10 by 5" do not infer the range type as AnyVal. - */ - import num._ - - // See comment in Range for why this must be lazy. - override lazy val length: Int = NumericRange.count(start, end, step, isInclusive) - override def isEmpty = length == 0 - override def last: T = - if (length == 0) Nil.head - else locationAfterN(length - 1) - override def init: NumericRange[T] = - if (isEmpty) Nil.init - else new NumericRange(start, end - step, step, isInclusive) - - override def head: T = if (isEmpty) Nil.head else start - override def tail: NumericRange[T] = - if (isEmpty) Nil.tail - else if(isInclusive) new NumericRange.Inclusive(start + step, end, step) - else new NumericRange.Exclusive(start + step, end, step) - - /** Create a new range with the start and end values of this range and - * a new `step`. - */ - def by(newStep: T): NumericRange[T] = copy(start, end, newStep) - - - /** Create a copy of this range. - */ - def copy(start: T, end: T, step: T): NumericRange[T] = - new NumericRange(start, end, step, isInclusive) - - @throws[IndexOutOfBoundsException] - def apply(idx: Int): T = { - if (idx < 0 || idx >= length) throw new IndexOutOfBoundsException(idx.toString) - else locationAfterN(idx) - } - - override def foreach[@specialized(Unit) U](f: T => U): Unit = { - var count = 0 - var current = start - while (count < length) { - f(current) - current += step - count += 1 - } - } - - // TODO: these private methods are straight copies from Range, duplicated - // to guard against any (most likely illusory) performance drop. They should - // be eliminated one way or another. - - // Tests whether a number is within the endpoints, without testing - // whether it is a member of the sequence (i.e. when step > 1.) - private def isWithinBoundaries(elem: T) = !isEmpty && ( - (step > zero && start <= elem && elem <= last ) || - (step < zero && last <= elem && elem <= start) - ) - // Methods like apply throw exceptions on invalid n, but methods like take/drop - // are forgiving: therefore the checks are with the methods. - private def locationAfterN(n: Int): T = start + (step * fromInt(n)) - - // When one drops everything. Can't ever have unchecked operations - // like "end + 1" or "end - 1" because ranges involving Int.{ MinValue, MaxValue } - // will overflow. This creates an exclusive range where start == end - // based on the given value. - private def newEmptyRange(value: T) = NumericRange(value, value, step) - - override def take(n: Int): NumericRange[T] = { - if (n <= 0 || length == 0) newEmptyRange(start) - else if (n >= length) this - else new NumericRange.Inclusive(start, locationAfterN(n - 1), step) - } - - override def drop(n: Int): NumericRange[T] = { - if (n <= 0 || length == 0) this - else if (n >= length) newEmptyRange(end) - else copy(locationAfterN(n), end, step) - } - - override def splitAt(n: Int): (NumericRange[T], NumericRange[T]) = (take(n), drop(n)) - - override def reverse: NumericRange[T] = - if (isEmpty) this else new NumericRange.Inclusive(last, start, -step) - - import NumericRange.defaultOrdering - - override def min[T1 >: T](implicit ord: Ordering[T1]): T = - // We can take the fast path: - // - If the Integral of this NumericRange is also the requested Ordering - // (Integral <: Ordering). This can happen for custom Integral types. - // - The Ordering is the default Ordering of a well-known Integral type. - if ((ord eq num) || defaultOrdering.get(num).exists(ord eq _)) { - if (num.signum(step) > 0) head - else last - } else super.min(ord) - - override def max[T1 >: T](implicit ord: Ordering[T1]): T = - // See comment for fast path in min(). - if ((ord eq num) || defaultOrdering.get(num).exists(ord eq _)) { - if (num.signum(step) > 0) last - else head - } else super.max(ord) - - // Motivated by the desire for Double ranges with BigDecimal precision, - // we need some way to map a Range and get another Range. This can't be - // done in any fully general way because Ranges are not arbitrary - // sequences but step-valued, so we have a custom method only we can call - // which we promise to use responsibly. - // - // The point of it all is that - // - // 0.0 to 1.0 by 0.1 - // - // should result in - // - // NumericRange[Double](0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0) - // - // and not - // - // NumericRange[Double](0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9) - // - // or perhaps more importantly, - // - // (0.1 to 0.3 by 0.1 contains 0.3) == true - // - private[immutable] def mapRange[A](fm: T => A)(implicit unum: Integral[A]): NumericRange[A] = { - val self = this - - // XXX This may be incomplete. - new NumericRange[A](fm(start), fm(end), fm(step), isInclusive) { - - private lazy val underlyingRange: NumericRange[T] = self - override def foreach[@specialized(Unit) U](f: A => U): Unit = { underlyingRange foreach (x => f(fm(x))) } - override def isEmpty = underlyingRange.isEmpty - override def apply(idx: Int): A = fm(underlyingRange(idx)) - override def containsTyped(el: A) = underlyingRange exists (x => fm(x) == el) - - override def toString = { - def simpleOf(x: Any): String = x.getClass.getName.split("\\.").last - val stepped = simpleOf(underlyingRange.step) - s"${super.toString} (using $underlyingRange of $stepped)" - } - } - } - - // a well-typed contains method. - def containsTyped(x: T): Boolean = - isWithinBoundaries(x) && (((x - start) % step) == zero) - - override def contains[A1 >: T](x: A1): Boolean = - try containsTyped(x.asInstanceOf[T]) - catch { case _: ClassCastException => false } - - override def sum[B >: T](implicit num: Numeric[B]): B = { - if (isEmpty) num.zero - else if (size == 1) head - else { - // If there is no overflow, use arithmetic series formula - // a + ... (n terms total) ... + b = n*(a+b)/2 - if ((num eq scala.math.Numeric.IntIsIntegral)|| - (num eq scala.math.Numeric.ShortIsIntegral)|| - (num eq scala.math.Numeric.ByteIsIntegral)|| - (num eq scala.math.Numeric.CharIsIntegral)) { - // We can do math with no overflow in a Long--easy - val exact = (size * ((num toLong head) + (num toInt last))) / 2 - num fromInt exact.toInt - } - else if (num eq scala.math.Numeric.LongIsIntegral) { - // Uh-oh, might be overflow, so we have to divide before we overflow. - // Either numRangeElements or (head + last) must be even, so divide the even one before multiplying - val a = head.toLong - val b = last.toLong - val ans = - if ((size & 1) == 0) (size / 2) * (a + b) - else size * { - // Sum is even, but we might overflow it, so divide in pieces and add back remainder - val ha = a/2 - val hb = b/2 - ha + hb + ((a - 2*ha) + (b - 2*hb)) / 2 - } - ans.asInstanceOf[B] - } - else { - // User provided custom Numeric, so we cannot rely on arithmetic series formula (e.g. won't work on something like Z_6) - if (isEmpty) num.zero - else { - var acc = num.zero - var i = head - var idx = 0 - while(idx < length) { - acc = num.plus(acc, i) - i = i + step - idx = idx + 1 - } - acc - } - } - } - } - - override lazy val hashCode: Int = super.hashCode() - override def equals(other: Any): Boolean = other match { - case x: NumericRange[_] => - (x canEqual this) && (length == x.length) && ( - (length == 0) || // all empty sequences are equal - (start == x.start && last == x.last) // same length and same endpoints implies equality - ) - case _ => - super.equals(other) - } - - override def toString: String = { - val empty = if (isEmpty) "empty " else "" - val preposition = if (isInclusive) "to" else "until" - val stepped = if (step == 1) "" else s" by $step" - s"${empty}NumericRange $start $preposition $end$stepped" - } -} - -/** A companion object for numeric ranges. - * @define Coll `NumericRange` - * @define coll numeric range - */ -object NumericRange { - - /** Calculates the number of elements in a range given start, end, step, and - * whether or not it is inclusive. Throws an exception if step == 0 or - * the number of elements exceeds the maximum Int. - */ - def count[T](start: T, end: T, step: T, isInclusive: Boolean)(implicit num: Integral[T]): Int = { - val zero = num.zero - val upward = num.lt(start, end) - val posStep = num.gt(step, zero) - - if (step == zero) throw new IllegalArgumentException("step cannot be 0.") - else if (start == end) if (isInclusive) 1 else 0 - else if (upward != posStep) 0 - else { - /* We have to be frightfully paranoid about running out of range. - * We also can't assume that the numbers will fit in a Long. - * We will assume that if a > 0, -a can be represented, and if - * a < 0, -a+1 can be represented. We also assume that if we - * can't fit in Int, we can represent 2*Int.MaxValue+3 (at least). - * And we assume that numbers wrap rather than cap when they overflow. - */ - // Check whether we can short-circuit by deferring to Int range. - val startint = num.toInt(start) - if (start == num.fromInt(startint)) { - val endint = num.toInt(end) - if (end == num.fromInt(endint)) { - val stepint = num.toInt(step) - if (step == num.fromInt(stepint)) { - return { - if (isInclusive) Range.inclusive(startint, endint, stepint).length - else Range (startint, endint, stepint).length - } - } - } - } - // If we reach this point, deferring to Int failed. - // Numbers may be big. - val one = num.one - val limit = num.fromInt(Int.MaxValue) - def check(t: T): T = - if (num.gt(t, limit)) throw new IllegalArgumentException("More than Int.MaxValue elements.") - else t - // If the range crosses zero, it might overflow when subtracted - val startside = num.signum(start) - val endside = num.signum(end) - num.toInt{ - if (startside*endside >= 0) { - // We're sure we can subtract these numbers. - // Note that we do not use .rem because of different conventions for Long and BigInt - val diff = num.minus(end, start) - val quotient = check(num.quot(diff, step)) - val remainder = num.minus(diff, num.times(quotient, step)) - if (!isInclusive && zero == remainder) quotient else check(num.plus(quotient, one)) - } - else { - // We might not even be able to subtract these numbers. - // Jump in three pieces: - // * start to -1 or 1, whichever is closer (waypointA) - // * one step, which will take us at least to 0 (ends at waypointB) - // * there to the end - val negone = num.fromInt(-1) - val startlim = if (posStep) negone else one - val startdiff = num.minus(startlim, start) - val startq = check(num.quot(startdiff, step)) - val waypointA = if (startq == zero) start else num.plus(start, num.times(startq, step)) - val waypointB = num.plus(waypointA, step) - check { - if (num.lt(waypointB, end) != upward) { - // No last piece - if (isInclusive && waypointB == end) num.plus(startq, num.fromInt(2)) - else num.plus(startq, one) - } - else { - // There is a last piece - val enddiff = num.minus(end,waypointB) - val endq = check(num.quot(enddiff, step)) - val last = if (endq == zero) waypointB else num.plus(waypointB, num.times(endq, step)) - // Now we have to tally up all the pieces - // 1 for the initial value - // startq steps to waypointA - // 1 step to waypointB - // endq steps to the end (one less if !isInclusive and last==end) - num.plus(startq, num.plus(endq, if (!isInclusive && last==end) one else num.fromInt(2))) - } - } - } - } - } - } - - @SerialVersionUID(3L) - class Inclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]) - extends NumericRange(start, end, step, true) { - override def copy(start: T, end: T, step: T): Inclusive[T] = - NumericRange.inclusive(start, end, step) - - def exclusive: Exclusive[T] = NumericRange(start, end, step) - } - - @SerialVersionUID(3L) - class Exclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]) - extends NumericRange(start, end, step, false) { - override def copy(start: T, end: T, step: T): Exclusive[T] = - NumericRange(start, end, step) - - def inclusive: Inclusive[T] = NumericRange.inclusive(start, end, step) - } - - def apply[T](start: T, end: T, step: T)(implicit num: Integral[T]): Exclusive[T] = - new Exclusive(start, end, step) - def inclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]): Inclusive[T] = - new Inclusive(start, end, step) - - private[collection] val defaultOrdering = Map[Numeric[_], Ordering[_]]( - Numeric.IntIsIntegral -> Ordering.Int, - Numeric.ShortIsIntegral -> Ordering.Short, - Numeric.ByteIsIntegral -> Ordering.Byte, - Numeric.CharIsIntegral -> Ordering.Char, - Numeric.LongIsIntegral -> Ordering.Long - ) - -} - diff --git a/scalalib/overrides-2.13.0-M4/scala/collection/immutable/Range.scala b/scalalib/overrides-2.13.0-M4/scala/collection/immutable/Range.scala deleted file mode 100644 index 8c89fe0f18..0000000000 --- a/scalalib/overrides-2.13.0-M4/scala/collection/immutable/Range.scala +++ /dev/null @@ -1,547 +0,0 @@ -package scala -package collection.immutable - -import collection.{Iterator, SeqFactory} - -import java.lang.String - -import scala.collection.mutable.Builder - -/** The `Range` class represents integer values in range - * ''[start;end)'' with non-zero step value `step`. - * It's a special case of an indexed sequence. - * For example: - * - * {{{ - * val r1 = 0 until 10 - * val r2 = r1.start until r1.end by r1.step + 1 - * println(r2.length) // = 5 - * }}} - * - * Ranges that contain more than `Int.MaxValue` elements can be created, but - * these overfull ranges have only limited capabilities. Any method that - * could require a collection of over `Int.MaxValue` length to be created, or - * could be asked to index beyond `Int.MaxValue` elements will throw an - * exception. Overfull ranges can safely be reduced in size by changing - * the step size (e.g. `by 3`) or taking/dropping elements. `contains`, - * `equals`, and access to the ends of the range (`head`, `last`, `tail`, - * `init`) are also permitted on overfull ranges. - * - * @param start the start of this range. - * @param end the end of the range. For exclusive ranges, e.g. - * `Range(0,3)` or `(0 until 3)`, this is one - * step past the last one in the range. For inclusive - * ranges, e.g. `Range.inclusive(0,3)` or `(0 to 3)`, - * it may be in the range if it is not skipped by the step size. - * To find the last element inside a non-empty range, - * use `last` instead. - * @param step the step for the range. - * - * @define coll range - * @define mayNotTerminateInf - * @define willNotTerminateInf - * @define doesNotUseBuilders - * '''Note:''' this method does not use builders to construct a new range, - * and its complexity is O(1). - */ -@SerialVersionUID(3L) -sealed abstract class Range( - val start: Int, - val end: Int, - val step: Int -) - extends AbstractSeq[Int] - with IndexedSeq[Int] - with IndexedSeqOps[Int, IndexedSeq, IndexedSeq[Int]] - with StrictOptimizedSeqOps[Int, IndexedSeq, IndexedSeq[Int]] - with Serializable { range => - - override def iterator(): Iterator[Int] = new RangeIterator(start, step, lastElement, isEmpty) - - private def gap = end.toLong - start.toLong - private def isExact = gap % step == 0 - private def hasStub = isInclusive || !isExact - private def longLength = gap / step + ( if (hasStub) 1 else 0 ) - - def isInclusive: Boolean - - override val isEmpty: Boolean = ( - (start > end && step > 0) - || (start < end && step < 0) - || (start == end && !isInclusive) - ) - - private val numRangeElements: Int = { - if (step == 0) throw new IllegalArgumentException("step cannot be 0.") - else if (isEmpty) 0 - else { - val len = longLength - if (len > scala.Int.MaxValue) -1 - else len.toInt - } - } - - def length = if (numRangeElements < 0) fail() else numRangeElements - - // This field has a sensible value only for non-empty ranges - private val lastElement = step match { - case 1 => if (isInclusive) end else end-1 - case -1 => if (isInclusive) end else end+1 - case _ => - val remainder = (gap % step).toInt - if (remainder != 0) end - remainder - else if (isInclusive) end - else end - step - } - - /** The last element of this range. This method will return the correct value - * even if there are too many elements to iterate over. - */ - override def last: Int = if (isEmpty) Nil.head else lastElement - override def head: Int = if (isEmpty) Nil.head else start - - /** Creates a new range containing all the elements of this range except the last one. - * - * $doesNotUseBuilders - * - * @return a new range consisting of all the elements of this range except the last one. - */ - override def init: Range = { - if (isEmpty) - Nil.init - - dropRight(1) - } - - /** Creates a new range containing all the elements of this range except the first one. - * - * $doesNotUseBuilders - * - * @return a new range consisting of all the elements of this range except the first one. - */ - override def tail: Range = { - if (isEmpty) - Nil.tail - if (numRangeElements == 1) newEmptyRange(end) - else if(isInclusive) new Range.Inclusive(start + step, end, step) - else new Range.Exclusive(start + step, end, step) - } - - protected def copy(start: Int = start, end: Int = end, step: Int = step, isInclusive: Boolean = isInclusive): Range = - if(isInclusive) new Range.Inclusive(start, end, step) else new Range.Exclusive(start, end, step) - - /** Create a new range with the `start` and `end` values of this range and - * a new `step`. - * - * @return a new range with a different step - */ - def by(step: Int): Range = copy(start, end, step) - - // Check cannot be evaluated eagerly because we have a pattern where - // ranges are constructed like: "x to y by z" The "x to y" piece - // should not trigger an exception. So the calculation is delayed, - // which means it will not fail fast for those cases where failing was - // correct. - private def validateMaxLength(): Unit = { - if (numRangeElements < 0) - fail() - } - private def fail() = Range.fail(start, end, step, isInclusive) - - @throws[IndexOutOfBoundsException] - def apply(idx: Int): Int = { - validateMaxLength() - if (idx < 0 || idx >= numRangeElements) throw new IndexOutOfBoundsException(idx.toString) - else start + (step * idx) - } - - /*@`inline`*/ override def foreach[@specialized(Unit) U](f: Int => U): Unit = { - // Implementation chosen on the basis of favorable microbenchmarks - // Note--initialization catches step == 0 so we don't need to here - if (!isEmpty) { - var i = start - while (true) { - f(i) - if (i == lastElement) return - i += step - } - } - } - - /** Creates a new range containing the first `n` elements of this range. - * - * @param n the number of elements to take. - * @return a new range consisting of `n` first elements. - */ - override def take(n: Int): Range = - if (n <= 0 || isEmpty) newEmptyRange(start) - else if (n >= numRangeElements && numRangeElements >= 0) this - else { - // May have more than Int.MaxValue elements in range (numRangeElements < 0) - // but the logic is the same either way: take the first n - new Range.Inclusive(start, locationAfterN(n - 1), step) - } - - /** Creates a new range containing all the elements of this range except the first `n` elements. - * - * @param n the number of elements to drop. - * @return a new range consisting of all the elements of this range except `n` first elements. - */ - override def drop(n: Int): Range = - if (n <= 0 || isEmpty) this - else if (n >= numRangeElements && numRangeElements >= 0) newEmptyRange(end) - else { - // May have more than Int.MaxValue elements (numRangeElements < 0) - // but the logic is the same either way: go forwards n steps, keep the rest - copy(locationAfterN(n), end, step) - } - - /** Creates a new range consisting of the last `n` elements of the range. - * - * $doesNotUseBuilders - */ - override def takeRight(n: Int): Range = { - if (n <= 0) newEmptyRange(start) - else if (numRangeElements >= 0) drop(numRangeElements - n) - else { - // Need to handle over-full range separately - val y = last - val x = y - step.toLong*(n-1) - if ((step > 0 && x < start) || (step < 0 && x > start)) this - else Range.inclusive(x.toInt, y, step) - } - } - - /** Creates a new range consisting of the initial `length - n` elements of the range. - * - * $doesNotUseBuilders - */ - override def dropRight(n: Int): Range = { - if (n <= 0) this - else if (numRangeElements >= 0) take(numRangeElements - n) - else { - // Need to handle over-full range separately - val y = last - step.toInt*n - if ((step > 0 && y < start) || (step < 0 && y > start)) newEmptyRange(start) - else Range.inclusive(start, y.toInt, step) - } - } - - // Advance from the start while we meet the given test - private def argTakeWhile(p: Int => Boolean): Long = { - if (isEmpty) start - else { - var current = start - val stop = last - while (current != stop && p(current)) current += step - if (current != stop || !p(current)) current - else current.toLong + step - } - } - - override def takeWhile(p: Int => Boolean): Range = { - val stop = argTakeWhile(p) - if (stop==start) newEmptyRange(start) - else { - val x = (stop - step).toInt - if (x == last) this - else Range.inclusive(start, x, step) - } - } - - override def dropWhile(p: Int => Boolean): Range = { - val stop = argTakeWhile(p) - if (stop == start) this - else { - val x = (stop - step).toInt - if (x == last) newEmptyRange(last) - else Range.inclusive(x + step, last, step) - } - } - - override def span(p: Int => Boolean): (Range, Range) = { - val border = argTakeWhile(p) - if (border == start) (newEmptyRange(start), this) - else { - val x = (border - step).toInt - if (x == last) (this, newEmptyRange(last)) - else (Range.inclusive(start, x, step), Range.inclusive(x+step, last, step)) - } - } - - /** Creates a new range containing the elements starting at `from` up to but not including `until`. - * - * $doesNotUseBuilders - * - * @param from the element at which to start - * @param until the element at which to end (not included in the range) - * @return a new range consisting of a contiguous interval of values in the old range - */ - override def slice(from: Int, until: Int): Range = - if (from <= 0) take(until) - else if (until >= numRangeElements && numRangeElements >= 0) drop(from) - else { - val fromValue = locationAfterN(from) - if (from >= until) newEmptyRange(fromValue) - else Range.inclusive(fromValue, locationAfterN(until-1), step) - } - - // Overridden only to refine the return type - override def splitAt(n: Int): (Range, Range) = (take(n), drop(n)) - - // Methods like apply throw exceptions on invalid n, but methods like take/drop - // are forgiving: therefore the checks are with the methods. - private def locationAfterN(n: Int) = start + (step * n) - - // When one drops everything. Can't ever have unchecked operations - // like "end + 1" or "end - 1" because ranges involving Int.{ MinValue, MaxValue } - // will overflow. This creates an exclusive range where start == end - // based on the given value. - private def newEmptyRange(value: Int) = new Range.Exclusive(value, value, step) - - /** Returns the reverse of this range. - */ - override def reverse: Range = - if (isEmpty) this - else new Range.Inclusive(last, start, -step) - - /** Make range inclusive. - */ - def inclusive: Range = - if (isInclusive) this - else new Range.Inclusive(start, end, step) - - def contains(x: Int) = { - if (x == end && !isInclusive) false - else if (step > 0) { - if (x < start || x > end) false - else (step == 1) || (((x - start) % step) == 0) - } - else { - if (x < end || x > start) false - else (step == -1) || (((x - start) % step) == 0) - } - } - - override def sum[B >: Int](implicit num: Numeric[B]): Int = { - if (num eq scala.math.Numeric.IntIsIntegral) { - // this is normal integer range with usual addition. arithmetic series formula can be used - if (isEmpty) 0 - else if (size == 1) head - else ((size * (head.toLong + last)) / 2).toInt - } else { - // user provided custom Numeric, we cannot rely on arithmetic series formula - if (isEmpty) num.toInt(num.zero) - else { - var acc = num.zero - var i = head - while (true) { - acc = num.plus(acc, i) - if (i == lastElement) return num.toInt(acc) - i = i + step - } - 0 // Never hit this--just to satisfy compiler since it doesn't know while(true) has type Nothing - } - } - } - - override def min[A1 >: Int](implicit ord: Ordering[A1]): Int = - if (ord eq Ordering.Int) { - if (step > 0) head - else last - } else super.min(ord) - - override def max[A1 >: Int](implicit ord: Ordering[A1]): Int = - if (ord eq Ordering.Int) { - if (step > 0) last - else head - } else super.max(ord) - - - override def equals(other: Any) = other match { - case x: Range => - // Note: this must succeed for overfull ranges (length > Int.MaxValue) - if (isEmpty) x.isEmpty // empty sequences are equal - else // this is non-empty... - x.nonEmpty && start == x.start && { // ...so other must contain something and have same start - val l0 = last - (l0 == x.last && ( // And same end - start == l0 || step == x.step // And either the same step, or not take any steps - )) - } - case _ => - super.equals(other) - } - - /* Note: hashCode can't be overridden without breaking Seq's equals contract. */ - - override def toString: String = { - val preposition = if (isInclusive) "to" else "until" - val stepped = if (step == 1) "" else s" by $step" - val prefix = if (isEmpty) "empty " else if (!isExact) "inexact " else "" - s"${prefix}Range $start $preposition $end$stepped" - } - -} - -/** - * Companion object for ranges. - * @define Coll `Range` - * @define coll range - */ -object Range { - - private def description(start: Int, end: Int, step: Int, isInclusive: Boolean) = - start + (if (isInclusive) " to " else " until ") + end + " by " + step - - private def fail(start: Int, end: Int, step: Int, isInclusive: Boolean) = - throw new IllegalArgumentException(description(start, end, step, isInclusive) + - ": seqs cannot contain more than Int.MaxValue elements.") - - /** Counts the number of range elements. - * precondition: step != 0 - * If the size of the range exceeds Int.MaxValue, the - * result will be negative. - */ - def count(start: Int, end: Int, step: Int, isInclusive: Boolean): Int = { - if (step == 0) - throw new IllegalArgumentException("step cannot be 0.") - - val isEmpty = - if (start == end) !isInclusive - else if (start < end) step < 0 - else step > 0 - - if (isEmpty) 0 - else { - // Counts with Longs so we can recognize too-large ranges. - val gap: Long = end.toLong - start.toLong - val jumps: Long = gap / step - // Whether the size of this range is one larger than the - // number of full-sized jumps. - val hasStub = isInclusive || (gap % step != 0) - val result: Long = jumps + ( if (hasStub) 1 else 0 ) - - if (result > scala.Int.MaxValue) -1 - else result.toInt - } - } - def count(start: Int, end: Int, step: Int): Int = - count(start, end, step, isInclusive = false) - - /** Make a range from `start` until `end` (exclusive) with given step value. - * @note step != 0 - */ - def apply(start: Int, end: Int, step: Int): Range.Exclusive = new Range.Exclusive(start, end, step) - - /** Make a range from `start` until `end` (exclusive) with step value 1. - */ - def apply(start: Int, end: Int): Range.Exclusive = new Range.Exclusive(start, end, 1) - - /** Make an inclusive range from `start` to `end` with given step value. - * @note step != 0 - */ - def inclusive(start: Int, end: Int, step: Int): Range.Inclusive = new Range.Inclusive(start, end, step) - - /** Make an inclusive range from `start` to `end` with step value 1. - */ - def inclusive(start: Int, end: Int): Range.Inclusive = new Range.Inclusive(start, end, 1) - - @SerialVersionUID(3L) - @inline - final class Inclusive(start: Int, end: Int, step: Int) extends Range(start, end, step) { - def isInclusive = true - } - - @SerialVersionUID(3L) - @inline - final class Exclusive(start: Int, end: Int, step: Int) extends Range(start, end, step) { - def isInclusive = false - } - - // BigInt and Long are straightforward generic ranges. - object BigInt { - def apply(start: BigInt, end: BigInt, step: BigInt) = NumericRange(start, end, step) - def inclusive(start: BigInt, end: BigInt, step: BigInt) = NumericRange.inclusive(start, end, step) - } - - object Long { - def apply(start: Long, end: Long, step: Long) = NumericRange(start, end, step) - def inclusive(start: Long, end: Long, step: Long) = NumericRange.inclusive(start, end, step) - } - - // BigDecimal uses an alternative implementation of Numeric in which - // it pretends to be Integral[T] instead of Fractional[T]. See Numeric for - // details. The intention is for it to throw an exception anytime - // imprecision or surprises might result from anything, although this may - // not yet be fully implemented. - object BigDecimal { - implicit val bigDecAsIntegral: Numeric.BigDecimalAsIfIntegral = Numeric.BigDecimalAsIfIntegral - - def apply(start: BigDecimal, end: BigDecimal, step: BigDecimal) = - NumericRange(start, end, step) - def inclusive(start: BigDecimal, end: BigDecimal, step: BigDecimal) = - NumericRange.inclusive(start, end, step) - } - - // Double works by using a BigDecimal under the hood for precise - // stepping, but mapping the sequence values back to doubles with - // .doubleValue. This constructs the BigDecimals by way of the - // String constructor (valueOf) instead of the Double one, which - // is necessary to keep 0.3d at 0.3 as opposed to - // 0.299999999999999988897769753748434595763683319091796875 or so. - object Double { - implicit val bigDecAsIntegral: Numeric.BigDecimalAsIfIntegral = Numeric.BigDecimalAsIfIntegral - implicit val doubleAsIntegral: Numeric.DoubleAsIfIntegral = Numeric.DoubleAsIfIntegral - def toBD(x: Double): BigDecimal = scala.math.BigDecimal valueOf x - - @deprecated("use Range.BigDecimal instead", "2.12.6") - def apply(start: Double, end: Double, step: Double) = - BigDecimal(toBD(start), toBD(end), toBD(step)) mapRange (_.doubleValue) - - @deprecated("use Range.BigDecimal.inclusive instead", "2.12.6") - def inclusive(start: Double, end: Double, step: Double) = - BigDecimal.inclusive(toBD(start), toBD(end), toBD(step)) mapRange (_.doubleValue) - } - - // As there is no appealing default step size for not-really-integral ranges, - // we offer a partially constructed object. - class Partial[T, U](private val f: T => U) extends AnyVal { - def by(x: T): U = f(x) - override def toString = "Range requires step" - } - - // Illustrating genericity with Int Range, which should have the same behavior - // as the original Range class. However we leave the original Range - // indefinitely, for performance and because the compiler seems to bootstrap - // off it and won't do so with our parameterized version without modifications. - object Int { - def apply(start: Int, end: Int, step: Int) = NumericRange(start, end, step) - def inclusive(start: Int, end: Int, step: Int) = NumericRange.inclusive(start, end, step) - } - -} - -/** - * @param lastElement The last element included in the Range - * @param initiallyEmpty Whether the Range was initially empty or not - */ -private class RangeIterator( - start: Int, - step: Int, - lastElement: Int, - initiallyEmpty: Boolean -) extends Iterator[Int] { - private var _hasNext: Boolean = !initiallyEmpty - private var _next: Int = start - override def knownSize: Int = if (_hasNext) (lastElement - _next) / step + 1 else 0 - def hasNext: Boolean = _hasNext - @throws[NoSuchElementException] - def next(): Int = { - if (!_hasNext) Iterator.empty.next() - val value = _next - _hasNext = value != lastElement - _next = value + step - value - } -} diff --git a/scalalib/overrides-2.13.0-M4/scala/collection/mutable/Buffer.scala b/scalalib/overrides-2.13.0-M4/scala/collection/mutable/Buffer.scala deleted file mode 100644 index 8c62526e34..0000000000 --- a/scalalib/overrides-2.13.0-M4/scala/collection/mutable/Buffer.scala +++ /dev/null @@ -1,176 +0,0 @@ -package scala.collection -package mutable - -import scala.scalajs.js - -/** A `Buffer` is a growable and shrinkable `Seq`. */ -trait Buffer[A] - extends Seq[A] - with SeqOps[A, Buffer, Buffer[A]] - with Growable[A] - with Shrinkable[A] { - - override def iterableFactory: SeqFactory[Buffer] = Buffer - - //TODO Prepend is a logical choice for a readable name of `+=:` but it conflicts with the renaming of `append` to `add` - /** Prepends a single element at the front of this $coll. - * - * @param elem the element to $add. - * @return the $coll itself - */ - def prepend(elem: A): this.type - - @deprecated("Use .addOne or += instead of .append", "2.13.0") - @`inline` final def append(elem: A): this.type = addOne(elem) - - /** Alias for `prepend` */ - @`inline` final def +=: (elem: A): this.type = prepend(elem) - - def prependAll(elems: IterableOnce[A]): this.type = { insertAll(0, elems); this } - - /** Inserts a new element at a given index into this buffer. - * - * @param idx the index where the new elements is inserted. - * @param elem the element to insert. - * @throws IndexOutOfBoundsException if the index `idx` is not in the valid range - * `0 <= idx <= length`. - */ - @throws[IndexOutOfBoundsException] - def insert(idx: Int, elem: A): Unit - - /** Inserts new elements at the index `idx`. Opposed to method - * `update`, this method will not replace an element with a new - * one. Instead, it will insert a new element at index `idx`. - * - * @param idx the index where a new element will be inserted. - * @param elems the iterable object providing all elements to insert. - * @throws IndexOutOfBoundsException if `idx` is out of bounds. - */ - @throws[IndexOutOfBoundsException] - def insertAll(idx: Int, elems: IterableOnce[A]): Unit - - /** Removes the element at a given index position. - * - * @param idx the index which refers to the element to delete. - * @return the element that was formerly at index `idx`. - */ - @throws[IndexOutOfBoundsException] - def remove(idx: Int): A - - /** Removes the element on a given index position. It takes time linear in - * the buffer size. - * - * @param idx the index which refers to the first element to remove. - * @param count the number of elements to remove. - * @throws IndexOutOfBoundsException if the index `idx` is not in the valid range - * `0 <= idx <= length - count` (with `count > 0`). - * @throws IllegalArgumentException if `count < 0`. - */ - @throws[IndexOutOfBoundsException] - @throws[IllegalArgumentException] - def remove(idx: Int, count: Int): Unit - - /** Removes the first ''n'' elements of this buffer. - * - * @param n the number of elements to remove from the beginning - * of this buffer. - */ - def trimStart(n: Int): Unit = remove(0, normalized(n)) - - /** Removes the last ''n'' elements of this buffer. - * - * @param n the number of elements to remove from the end - * of this buffer. - */ - def trimEnd(n: Int): Unit = { - val norm = normalized(n) - remove(length - norm, norm) - } - - def patchInPlace(from: Int, patch: scala.collection.Seq[A], replaced: Int): this.type - - // +=, ++=, clear inherited from Growable - // Per remark of @ichoran, we should preferably not have these: - // - // def +=:(elem: A): this.type = { insert(0, elem); this } - // def +=:(elem1: A, elem2: A, elems: A*): this.type = elem1 +=: elem2 +=: elems ++=: this - // def ++=:(elems: IterableOnce[A]): this.type = { insertAll(0, elems); this } - - def dropInPlace(n: Int): this.type = { remove(0, normalized(n)); this } - def dropRightInPlace(n: Int): this.type = { - val norm = normalized(n) - remove(length - norm, norm) - this - } - def takeInPlace(n: Int): this.type = { - val norm = normalized(n) - remove(norm, length - norm) - this - } - def takeRightInPlace(n: Int): this.type = { remove(0, length - normalized(n)); this } - def sliceInPlace(start: Int, end: Int): this.type = takeInPlace(end).dropInPlace(start) - private def normalized(n: Int): Int = math.min(math.max(n, 0), length) - - def dropWhileInPlace(p: A => Boolean): this.type = { - val idx = indexWhere(!p(_)) - if (idx < 0) { clear(); this } else dropInPlace(idx) - } - def takeWhileInPlace(p: A => Boolean): this.type = { - val idx = indexWhere(!p(_)) - if (idx < 0) this else takeInPlace(idx) - } - def padToInPlace(len: Int, elem: A): this.type = { - while (length < len) +=(elem) - this - } -} - -trait IndexedOptimizedBuffer[A] extends IndexedOptimizedSeq[A] with Buffer[A] { - - def flatMapInPlace(f: A => IterableOnce[A]): this.type = { - // There's scope for a better implementation which copies elements in place. - var i = 0 - val s = size - val newElems = new Array[IterableOnce[A]](s) - while (i < s) { newElems(i) = f(this(i)); i += 1 } - clear() - i = 0 - while (i < s) { ++=(newElems(i)); i += 1 } - this - } - - def filterInPlace(p: A => Boolean): this.type = { - var i, j = 0 - while (i < size) { - if (p(apply(i))) { - if (i != j) { - this(j) = this(i) - } - j += 1 - } - i += 1 - } - - if (i == j) this else takeInPlace(j) - } - - def patchInPlace(from: Int, patch: scala.collection.Seq[A], replaced: Int): this.type = { - val replaced0 = math.min(math.max(replaced, 0), length) - val i = math.min(math.max(from, 0), length) - var j = 0 - val n = math.min(patch.length, replaced0) - while (j < n && i + j < length) { - update(i + j, patch(j)) - j += 1 - } - if (j < patch.length) insertAll(i + j, patch.iterator.drop(j)) - else if (j < replaced0) remove(i + j, replaced0 - j) - this - } -} - -object Buffer extends SeqFactory.Delegate[Buffer](js.WrappedArray) - -/** Explicit instantiation of the `Buffer` trait to reduce class file size in subclasses. */ -@SerialVersionUID(3L) -abstract class AbstractBuffer[A] extends AbstractSeq[A] with Buffer[A] diff --git a/scalalib/overrides-2.13.0-M4/scala/concurrent/ExecutionContext.scala b/scalalib/overrides-2.13.0-M4/scala/concurrent/ExecutionContext.scala deleted file mode 100644 index fbe26f4de9..0000000000 --- a/scalalib/overrides-2.13.0-M4/scala/concurrent/ExecutionContext.scala +++ /dev/null @@ -1,183 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.concurrent - - -import java.util.concurrent.{ ExecutorService, Executor } -import scala.annotation.implicitNotFound -import scala.util.Try - -/** - * An `ExecutionContext` can execute program logic asynchronously, - * typically but not necessarily on a thread pool. - * - * A general purpose `ExecutionContext` must be asynchronous in executing - * any `Runnable` that is passed into its `execute`-method. A special purpose - * `ExecutionContext` may be synchronous but must only be passed to code that - * is explicitly safe to be run using a synchronously executing `ExecutionContext`. - * - * APIs such as `Future.onComplete` require you to provide a callback - * and an implicit `ExecutionContext`. The implicit `ExecutionContext` - * will be used to execute the callback. - * - * It is possible to simply import - * `scala.concurrent.ExecutionContext.Implicits.global` to obtain an - * implicit `ExecutionContext`. This global context is a reasonable - * default thread pool. - * - * However, application developers should carefully consider where they - * want to set policy; ideally, one place per application (or per - * logically-related section of code) will make a decision about - * which `ExecutionContext` to use. That is, you might want to avoid - * hardcoding `scala.concurrent.ExecutionContext.Implicits.global` all - * over the place in your code. - * One approach is to add `(implicit ec: ExecutionContext)` - * to methods which need an `ExecutionContext`. Then import a specific - * context in one place for the entire application or module, - * passing it implicitly to individual methods. - * - * A custom `ExecutionContext` may be appropriate to execute code - * which blocks on IO or performs long-running computations. - * `ExecutionContext.fromExecutorService` and `ExecutionContext.fromExecutor` - * are good ways to create a custom `ExecutionContext`. - * - * The intent of `ExecutionContext` is to lexically scope code execution. - * That is, each method, class, file, package, or application determines - * how to run its own code. This avoids issues such as running - * application callbacks on a thread pool belonging to a networking library. - * The size of a networking library's thread pool can be safely configured, - * knowing that only that library's network operations will be affected. - * Application callback execution can be configured separately. - */ -@implicitNotFound("""Cannot find an implicit ExecutionContext. You might pass -an (implicit ec: ExecutionContext) parameter to your method -or import scala.concurrent.ExecutionContext.Implicits.global.""") -trait ExecutionContext { - - /** Runs a block of code on this execution context. - * - * @param runnable the task to execute - */ - def execute(runnable: Runnable): Unit - - /** Reports that an asynchronous computation failed. - * - * @param cause the cause of the failure - */ - def reportFailure(@deprecatedName('t) cause: Throwable): Unit - - /** Prepares for the execution of a task. Returns the prepared - * execution context. The recommended implementation of - * `prepare` is to return `this`. - * - * This method should no longer be overridden or called. It was - * originally expected that `prepare` would be called by - * all libraries that consume ExecutionContexts, in order to - * capture thread local context. However, this usage has proven - * difficult to implement in practice and instead it is - * now better to avoid using `prepare` entirely. - * - * Instead, if an `ExecutionContext` needs to capture thread - * local context, it should capture that context when it is - * constructed, so that it doesn't need any additional - * preparation later. - */ - @deprecated("Preparation of ExecutionContexts will be removed.", "2.12") - def prepare(): ExecutionContext = this -} - -/** - * An [[ExecutionContext]] that is also a - * Java [[http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executor.html Executor]]. - */ -trait ExecutionContextExecutor extends ExecutionContext with Executor - -/** - * An [[ExecutionContext]] that is also a - * Java [[http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html ExecutorService]]. - */ -trait ExecutionContextExecutorService extends ExecutionContextExecutor with ExecutorService - - -/** Contains factory methods for creating execution contexts. - */ -object ExecutionContext { - /** - * The explicit global `ExecutionContext`. Invoke `global` when you want to provide the global - * `ExecutionContext` explicitly. - * - * The default `ExecutionContext` implementation is backed by a work-stealing thread pool. By default, - * the thread pool uses a target number of worker threads equal to the number of - * [[https://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#availableProcessors-- available processors]]. - * - * @return the global `ExecutionContext` - */ - def global: ExecutionContextExecutor = Implicits.global.asInstanceOf[ExecutionContextExecutor] - - object Implicits { - /** - * The implicit global `ExecutionContext`. Import `global` when you want to provide the global - * `ExecutionContext` implicitly. - * - * The default `ExecutionContext` implementation is backed by a work-stealing thread pool. By default, - * the thread pool uses a target number of worker threads equal to the number of - * [[https://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#availableProcessors-- available processors]]. - */ - implicit lazy val global: ExecutionContext = - scala.scalajs.concurrent.JSExecutionContext.queue - } - - /** Creates an `ExecutionContext` from the given `ExecutorService`. - * - * @param e the `ExecutorService` to use. If `null`, a new `ExecutorService` is created with [[http://www.scala-lang.org/api/current/index.html#scala.concurrent.ExecutionContext$@global:scala.concurrent.ExecutionContextExecutor default configuration]]. - * @param reporter a function for error reporting - * @return the `ExecutionContext` using the given `ExecutorService` - */ - def fromExecutorService(e: ExecutorService, reporter: Throwable => Unit): ExecutionContextExecutorService = - impl.ExecutionContextImpl.fromExecutorService(e, reporter) - - /** Creates an `ExecutionContext` from the given `ExecutorService` with the [[scala.concurrent.ExecutionContext$.defaultReporter default reporter]]. - * - * If it is guaranteed that none of the executed tasks are blocking, a single-threaded `ExecutorService` - * can be used to create an `ExecutionContext` as follows: - * - * {{{ - * import java.util.concurrent.Executors - * val ec = ExecutionContext.fromExecutorService(Executors.newSingleThreadExecutor()) - * }}} - * - * @param e the `ExecutorService` to use. If `null`, a new `ExecutorService` is created with [[http://www.scala-lang.org/api/current/index.html#scala.concurrent.ExecutionContext$@global:scala.concurrent.ExecutionContextExecutor default configuration]]. - * @return the `ExecutionContext` using the given `ExecutorService` - */ - def fromExecutorService(e: ExecutorService): ExecutionContextExecutorService = fromExecutorService(e, defaultReporter) - - /** Creates an `ExecutionContext` from the given `Executor`. - * - * @param e the `Executor` to use. If `null`, a new `Executor` is created with [[http://www.scala-lang.org/api/current/index.html#scala.concurrent.ExecutionContext$@global:scala.concurrent.ExecutionContextExecutor default configuration]]. - * @param reporter a function for error reporting - * @return the `ExecutionContext` using the given `Executor` - */ - def fromExecutor(e: Executor, reporter: Throwable => Unit): ExecutionContextExecutor = - impl.ExecutionContextImpl.fromExecutor(e, reporter) - - /** Creates an `ExecutionContext` from the given `Executor` with the [[scala.concurrent.ExecutionContext$.defaultReporter default reporter]]. - * - * @param e the `Executor` to use. If `null`, a new `Executor` is created with [[http://www.scala-lang.org/api/current/index.html#scala.concurrent.ExecutionContext$@global:scala.concurrent.ExecutionContextExecutor default configuration]]. - * @return the `ExecutionContext` using the given `Executor` - */ - def fromExecutor(e: Executor): ExecutionContextExecutor = fromExecutor(e, defaultReporter) - - /** The default reporter simply prints the stack trace of the `Throwable` to [[http://docs.oracle.com/javase/8/docs/api/java/lang/System.html#err System.err]]. - * - * @return the function for error reporting - */ - def defaultReporter: Throwable => Unit = _.printStackTrace() -} - - diff --git a/scalalib/overrides-2.13.0-M4/scala/reflect/ClassTag.scala b/scalalib/overrides-2.13.0-M4/scala/reflect/ClassTag.scala deleted file mode 100644 index 05312cebe0..0000000000 --- a/scalalib/overrides-2.13.0-M4/scala/reflect/ClassTag.scala +++ /dev/null @@ -1,159 +0,0 @@ -package scala -package reflect - -import java.lang.{ Class => jClass } - -/** - * - * A `ClassTag[T]` stores the erased class of a given type `T`, accessible via the `runtimeClass` - * field. This is particularly useful for instantiating `Array`s whose element types are unknown - * at compile time. - * - * `ClassTag`s are a weaker special case of [[scala.reflect.api.TypeTags#TypeTag]]s, in that they - * wrap only the runtime class of a given type, whereas a `TypeTag` contains all static type - * information. That is, `ClassTag`s are constructed from knowing only the top-level class of a - * type, without necessarily knowing all of its argument types. This runtime information is enough - * for runtime `Array` creation. - * - * For example: - * {{{ - * scala> def mkArray[T : ClassTag](elems: T*) = Array[T](elems: _*) - * mkArray: [T](elems: T*)(implicit evidence$1: scala.reflect.ClassTag[T])Array[T] - * - * scala> mkArray(42, 13) - * res0: Array[Int] = Array(42, 13) - * - * scala> mkArray("Japan","Brazil","Germany") - * res1: Array[String] = Array(Japan, Brazil, Germany) - * }}} - * - * See [[scala.reflect.api.TypeTags]] for more examples, or the - * [[http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html Reflection Guide: TypeTags]] - * for more details. - * - */ -@scala.annotation.implicitNotFound(msg = "No ClassTag available for ${T}") -trait ClassTag[T] extends ClassManifestDeprecatedApis[T] with Equals with Serializable { - // please, don't add any APIs here, like it was with `newWrappedArray` and `newArrayBuilder` - // class tags, and all tags in general, should be as minimalistic as possible - - /** A class representing the type `U` to which `T` would be erased. - * Note that there is no subtyping relationship between `T` and `U`. - */ - def runtimeClass: jClass[_] - - /** Produces a `ClassTag` that knows how to instantiate an `Array[Array[T]]` */ - def wrap: ClassTag[Array[T]] = ClassTag[Array[T]](arrayClass(runtimeClass)) - - /** Produces a new array with element type `T` and length `len` */ - override def newArray(len: Int): Array[T] = - runtimeClass match { - case java.lang.Byte.TYPE => new Array[Byte](len).asInstanceOf[Array[T]] - case java.lang.Short.TYPE => new Array[Short](len).asInstanceOf[Array[T]] - case java.lang.Character.TYPE => new Array[Char](len).asInstanceOf[Array[T]] - case java.lang.Integer.TYPE => new Array[Int](len).asInstanceOf[Array[T]] - case java.lang.Long.TYPE => new Array[Long](len).asInstanceOf[Array[T]] - case java.lang.Float.TYPE => new Array[Float](len).asInstanceOf[Array[T]] - case java.lang.Double.TYPE => new Array[Double](len).asInstanceOf[Array[T]] - case java.lang.Boolean.TYPE => new Array[Boolean](len).asInstanceOf[Array[T]] - case java.lang.Void.TYPE => new Array[Unit](len).asInstanceOf[Array[T]] - case _ => java.lang.reflect.Array.newInstance(runtimeClass, len).asInstanceOf[Array[T]] - } - - /** A ClassTag[T] can serve as an extractor that matches only objects of type T. - * - * The compiler tries to turn unchecked type tests in pattern matches into checked ones - * by wrapping a `(_: T)` type pattern as `ct(_: T)`, where `ct` is the `ClassTag[T]` instance. - * Type tests necessary before calling other extractors are treated similarly. - * `SomeExtractor(...)` is turned into `ct(SomeExtractor(...))` if `T` in `SomeExtractor.unapply(x: T)` - * is uncheckable, but we have an instance of `ClassTag[T]`. - */ - def unapply(x: Any): Option[T] = - if (null != x && ( - (runtimeClass.isInstance(x)) - || (x.isInstanceOf[Byte] && runtimeClass.isAssignableFrom(classOf[Byte])) - || (x.isInstanceOf[Short] && runtimeClass.isAssignableFrom(classOf[Short])) - || (x.isInstanceOf[Char] && runtimeClass.isAssignableFrom(classOf[Char])) - || (x.isInstanceOf[Int] && runtimeClass.isAssignableFrom(classOf[Int])) - || (x.isInstanceOf[Long] && runtimeClass.isAssignableFrom(classOf[Long])) - || (x.isInstanceOf[Float] && runtimeClass.isAssignableFrom(classOf[Float])) - || (x.isInstanceOf[Double] && runtimeClass.isAssignableFrom(classOf[Double])) - || (x.isInstanceOf[Boolean] && runtimeClass.isAssignableFrom(classOf[Boolean])) - || (x.isInstanceOf[Unit] && runtimeClass.isAssignableFrom(classOf[Unit]))) - ) Some(x.asInstanceOf[T]) - else None - - // TODO: deprecate overloads in 2.12.0, remove in 2.13.0 - def unapply(x: Byte) : Option[T] = unapplyImpl(x, classOf[Byte]) - def unapply(x: Short) : Option[T] = unapplyImpl(x, classOf[Short]) - def unapply(x: Char) : Option[T] = unapplyImpl(x, classOf[Char]) - def unapply(x: Int) : Option[T] = unapplyImpl(x, classOf[Int]) - def unapply(x: Long) : Option[T] = unapplyImpl(x, classOf[Long]) - def unapply(x: Float) : Option[T] = unapplyImpl(x, classOf[Float]) - def unapply(x: Double) : Option[T] = unapplyImpl(x, classOf[Double]) - def unapply(x: Boolean) : Option[T] = unapplyImpl(x, classOf[Boolean]) - def unapply(x: Unit) : Option[T] = unapplyImpl(x, classOf[Unit]) - - private[this] def unapplyImpl(x: Any, primitiveCls: java.lang.Class[_]): Option[T] = - if (runtimeClass.isInstance(x) || runtimeClass.isAssignableFrom(primitiveCls)) Some(x.asInstanceOf[T]) - else None - - // case class accessories - override def canEqual(x: Any) = x.isInstanceOf[ClassTag[_]] - override def equals(x: Any) = x.isInstanceOf[ClassTag[_]] && this.runtimeClass == x.asInstanceOf[ClassTag[_]].runtimeClass - override def hashCode = runtimeClass.## - override def toString = { - def prettyprint(clazz: jClass[_]): String = - if (clazz.isArray) s"Array[${prettyprint(clazz.getComponentType)}]" else - clazz.getName - prettyprint(runtimeClass) - } -} - -/** - * Class tags corresponding to primitive types and constructor/extractor for ClassTags. - */ -object ClassTag { - def Byte : ClassTag[scala.Byte] = ManifestFactory.Byte - def Short : ClassTag[scala.Short] = ManifestFactory.Short - def Char : ClassTag[scala.Char] = ManifestFactory.Char - def Int : ClassTag[scala.Int] = ManifestFactory.Int - def Long : ClassTag[scala.Long] = ManifestFactory.Long - def Float : ClassTag[scala.Float] = ManifestFactory.Float - def Double : ClassTag[scala.Double] = ManifestFactory.Double - def Boolean : ClassTag[scala.Boolean] = ManifestFactory.Boolean - def Unit : ClassTag[scala.Unit] = ManifestFactory.Unit - def Any : ClassTag[scala.Any] = ManifestFactory.Any - def Object : ClassTag[java.lang.Object] = ManifestFactory.Object - def AnyVal : ClassTag[scala.AnyVal] = ManifestFactory.AnyVal - def AnyRef : ClassTag[scala.AnyRef] = ManifestFactory.AnyRef - def Nothing : ClassTag[scala.Nothing] = ManifestFactory.Nothing - def Null : ClassTag[scala.Null] = ManifestFactory.Null - - @inline - private class GenericClassTag[T](val runtimeClass: jClass[_]) extends ClassTag[T] - - def apply[T](runtimeClass1: jClass[_]): ClassTag[T] = - runtimeClass1 match { - case java.lang.Byte.TYPE => ClassTag.Byte.asInstanceOf[ClassTag[T]] - case java.lang.Short.TYPE => ClassTag.Short.asInstanceOf[ClassTag[T]] - case java.lang.Character.TYPE => ClassTag.Char.asInstanceOf[ClassTag[T]] - case java.lang.Integer.TYPE => ClassTag.Int.asInstanceOf[ClassTag[T]] - case java.lang.Long.TYPE => ClassTag.Long.asInstanceOf[ClassTag[T]] - case java.lang.Float.TYPE => ClassTag.Float.asInstanceOf[ClassTag[T]] - case java.lang.Double.TYPE => ClassTag.Double.asInstanceOf[ClassTag[T]] - case java.lang.Boolean.TYPE => ClassTag.Boolean.asInstanceOf[ClassTag[T]] - case java.lang.Void.TYPE => ClassTag.Unit.asInstanceOf[ClassTag[T]] - case _ => - if (classOf[java.lang.Object] == runtimeClass1) - ClassTag.Object.asInstanceOf[ClassTag[T]] - else if (classOf[scala.runtime.Nothing$] == runtimeClass1) - ClassTag.Nothing.asInstanceOf[ClassTag[T]] - else if (classOf[scala.runtime.Null$] == runtimeClass1) - ClassTag.Null.asInstanceOf[ClassTag[T]] - else - new GenericClassTag[T](runtimeClass1) - } - - def unapply[T](ctag: ClassTag[T]): Option[Class[_]] = Some(ctag.runtimeClass) -} diff --git a/scalalib/overrides-2.13.0-M4/scala/reflect/Manifest.scala b/scalalib/overrides-2.13.0-M4/scala/reflect/Manifest.scala deleted file mode 100644 index 48cdda41c7..0000000000 --- a/scalalib/overrides-2.13.0-M4/scala/reflect/Manifest.scala +++ /dev/null @@ -1,302 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala -package reflect - -import scala.collection.mutable.{ArrayBuilder, WrappedArray} - -/** A `Manifest[T]` is an opaque descriptor for type T. Its supported use - * is to give access to the erasure of the type as a `Class` instance, as - * is necessary for the creation of native `Arrays` if the class is not - * known at compile time. - * - * The type-relation operators `<:<` and `=:=` should be considered - * approximations only, as there are numerous aspects of type conformance - * which are not yet adequately represented in manifests. - * - * Example usages: - * {{{ - * def arr[T] = new Array[T](0) // does not compile - * def arr[T](implicit m: Manifest[T]) = new Array[T](0) // compiles - * def arr[T: Manifest] = new Array[T](0) // shorthand for the preceding - * - * // Methods manifest, classManifest, and optManifest are in [[scala.Predef]]. - * def isApproxSubType[T: Manifest, U: Manifest] = manifest[T] <:< manifest[U] - * isApproxSubType[List[String], List[AnyRef]] // true - * isApproxSubType[List[String], List[Int]] // false - * - * def methods[T: ClassManifest] = classManifest[T].erasure.getMethods - * def retType[T: ClassManifest](name: String) = - * methods[T] find (_.getName == name) map (_.getGenericReturnType) - * - * retType[Map[_, _]]("values") // Some(scala.collection.Iterable) - * }}} - */ -@scala.annotation.implicitNotFound(msg = "No Manifest available for ${T}.") -// TODO undeprecated until Scala reflection becomes non-experimental -// @deprecated("use scala.reflect.ClassTag (to capture erasures) or scala.reflect.runtime.universe.TypeTag (to capture types) or both instead", "2.10.0") -trait Manifest[T] extends ClassManifest[T] with Equals { - override def typeArguments: List[Manifest[_]] = Nil - - override def arrayManifest: Manifest[Array[T]] = - Manifest.classType[Array[T]](arrayClass[T](runtimeClass), this) - - override def canEqual(that: Any): Boolean = that match { - case _: Manifest[_] => true - case _ => false - } - /** Note: testing for erasure here is important, as it is many times - * faster than <:< and rules out most comparisons. - */ - override def equals(that: Any): Boolean = that match { - case m: Manifest[_] => (m canEqual this) && (this.runtimeClass == m.runtimeClass) && (this <:< m) && (m <:< this) - case _ => false - } - override def hashCode = this.runtimeClass.## -} - -// TODO undeprecated until Scala reflection becomes non-experimental -// @deprecated("use type tags and manually check the corresponding class or type instead", "2.10.0") -@SerialVersionUID(1L) -abstract class AnyValManifest[T <: AnyVal](override val toString: String) extends Manifest[T] with Equals { - override def <:<(that: ClassManifest[_]): Boolean = - (that eq this) || (that eq Manifest.Any) || (that eq Manifest.AnyVal) - override def canEqual(other: Any) = other match { - case _: AnyValManifest[_] => true - case _ => false - } - override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef] - override def hashCode = System.identityHashCode(this) -} - -/** `ManifestFactory` defines factory methods for manifests. - * It is intended for use by the compiler and should not be used in client code. - * - * Unlike `Manifest`, this factory isn't annotated with a deprecation warning. - * This is done to prevent avalanches of deprecation warnings in the code that calls methods with manifests. - * Why so complicated? Read up the comments for `ClassManifestFactory`. - */ -object ManifestFactory { - def valueManifests: List[AnyValManifest[_]] = - List(Byte, Short, Char, Int, Long, Float, Double, Boolean, Unit) - - private object ByteManifest extends AnyValManifest[scala.Byte]("Byte") { - def runtimeClass = java.lang.Byte.TYPE - override def newArray(len: Int): Array[Byte] = new Array[Byte](len) - override def newWrappedArray(len: Int): WrappedArray[Byte] = new WrappedArray.ofByte(new Array[Byte](len)) - override def newArrayBuilder(): ArrayBuilder[Byte] = new ArrayBuilder.ofByte() - private def readResolve(): Any = Manifest.Byte - } - def Byte: AnyValManifest[Byte] = ByteManifest - - private object ShortManifest extends AnyValManifest[scala.Short]("Short") { - def runtimeClass = java.lang.Short.TYPE - override def newArray(len: Int): Array[Short] = new Array[Short](len) - override def newWrappedArray(len: Int): WrappedArray[Short] = new WrappedArray.ofShort(new Array[Short](len)) - override def newArrayBuilder(): ArrayBuilder[Short] = new ArrayBuilder.ofShort() - private def readResolve(): Any = Manifest.Short - } - def Short: AnyValManifest[Short] = ShortManifest - - private object CharManifest extends AnyValManifest[scala.Char]("Char") { - def runtimeClass = java.lang.Character.TYPE - override def newArray(len: Int): Array[Char] = new Array[Char](len) - override def newWrappedArray(len: Int): WrappedArray[Char] = new WrappedArray.ofChar(new Array[Char](len)) - override def newArrayBuilder(): ArrayBuilder[Char] = new ArrayBuilder.ofChar() - private def readResolve(): Any = Manifest.Char - } - def Char: AnyValManifest[Char] = CharManifest - - private object IntManifest extends AnyValManifest[scala.Int]("Int") { - def runtimeClass = java.lang.Integer.TYPE - override def newArray(len: Int): Array[Int] = new Array[Int](len) - override def newWrappedArray(len: Int): WrappedArray[Int] = new WrappedArray.ofInt(new Array[Int](len)) - override def newArrayBuilder(): ArrayBuilder[Int] = new ArrayBuilder.ofInt() - private def readResolve(): Any = Manifest.Int - } - def Int: AnyValManifest[Int] = IntManifest - - private object LongManifest extends AnyValManifest[scala.Long]("Long") { - def runtimeClass = java.lang.Long.TYPE - override def newArray(len: Int): Array[Long] = new Array[Long](len) - override def newWrappedArray(len: Int): WrappedArray[Long] = new WrappedArray.ofLong(new Array[Long](len)) - override def newArrayBuilder(): ArrayBuilder[Long] = new ArrayBuilder.ofLong() - private def readResolve(): Any = Manifest.Long - } - def Long: AnyValManifest[Long] = LongManifest - - private object FloatManifest extends AnyValManifest[scala.Float]("Float") { - def runtimeClass = java.lang.Float.TYPE - override def newArray(len: Int): Array[Float] = new Array[Float](len) - override def newWrappedArray(len: Int): WrappedArray[Float] = new WrappedArray.ofFloat(new Array[Float](len)) - override def newArrayBuilder(): ArrayBuilder[Float] = new ArrayBuilder.ofFloat() - private def readResolve(): Any = Manifest.Float - } - def Float: AnyValManifest[Float] = FloatManifest - - private object DoubleManifest extends AnyValManifest[scala.Double]("Double") { - def runtimeClass = java.lang.Double.TYPE - override def newArray(len: Int): Array[Double] = new Array[Double](len) - override def newWrappedArray(len: Int): WrappedArray[Double] = new WrappedArray.ofDouble(new Array[Double](len)) - override def newArrayBuilder(): ArrayBuilder[Double] = new ArrayBuilder.ofDouble() - private def readResolve(): Any = Manifest.Double - } - def Double: AnyValManifest[Double] = DoubleManifest - - private object BooleanManifest extends AnyValManifest[scala.Boolean]("Boolean") { - def runtimeClass = java.lang.Boolean.TYPE - override def newArray(len: Int): Array[Boolean] = new Array[Boolean](len) - override def newWrappedArray(len: Int): WrappedArray[Boolean] = new WrappedArray.ofBoolean(new Array[Boolean](len)) - override def newArrayBuilder(): ArrayBuilder[Boolean] = new ArrayBuilder.ofBoolean() - private def readResolve(): Any = Manifest.Boolean - } - def Boolean: AnyValManifest[Boolean] = BooleanManifest - - private object UnitManifest extends AnyValManifest[scala.Unit]("Unit") { - def runtimeClass = java.lang.Void.TYPE - override def newArray(len: Int): Array[Unit] = new Array[Unit](len) - override def newWrappedArray(len: Int): WrappedArray[Unit] = new WrappedArray.ofUnit(new Array[Unit](len)) - override def newArrayBuilder(): ArrayBuilder[Unit] = new ArrayBuilder.ofUnit() - override protected def arrayClass[T](tp: Class[_]): Class[Array[T]] = - if (tp eq runtimeClass) classOf[Array[scala.runtime.BoxedUnit]].asInstanceOf[Class[Array[T]]] - else super.arrayClass(tp) - private def readResolve(): Any = Manifest.Unit - } - def Unit: AnyValManifest[Unit] = UnitManifest - - private object AnyManifest extends PhantomManifest[scala.Any](classOf[java.lang.Object], "Any") { - override def runtimeClass = classOf[java.lang.Object] - override def newArray(len: Int) = new Array[scala.Any](len) - override def <:<(that: ClassManifest[_]): Boolean = (that eq this) - private def readResolve(): Any = Manifest.Any - } - def Any: Manifest[scala.Any] = AnyManifest - - private object ObjectManifest extends PhantomManifest[java.lang.Object](classOf[java.lang.Object], "Object") { - override def runtimeClass = classOf[java.lang.Object] - override def newArray(len: Int) = new Array[java.lang.Object](len) - override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any) - private def readResolve(): Any = Manifest.Object - } - def Object: Manifest[java.lang.Object] = ObjectManifest - - def AnyRef: Manifest[scala.AnyRef] = Object.asInstanceOf[Manifest[scala.AnyRef]] - - private object AnyValManifest extends PhantomManifest[scala.AnyVal](classOf[java.lang.Object], "AnyVal") { - override def runtimeClass = classOf[java.lang.Object] - override def newArray(len: Int) = new Array[scala.AnyVal](len) - override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any) - private def readResolve(): Any = Manifest.AnyVal - } - def AnyVal: Manifest[scala.AnyVal] = AnyValManifest - - private object NullManifest extends PhantomManifest[scala.Null](classOf[scala.runtime.Null$], "Null") { - override def runtimeClass = classOf[scala.runtime.Null$] - override def newArray(len: Int) = new Array[scala.Null](len) - override def <:<(that: ClassManifest[_]): Boolean = - (that ne null) && (that ne Nothing) && !(that <:< AnyVal) - private def readResolve(): Any = Manifest.Null - } - def Null: Manifest[scala.Null] = NullManifest - - private object NothingManifest extends PhantomManifest[scala.Nothing](classOf[scala.runtime.Nothing$], "Nothing") { - override def runtimeClass = classOf[scala.runtime.Nothing$] - override def newArray(len: Int) = new Array[scala.Nothing](len) - override def <:<(that: ClassManifest[_]): Boolean = (that ne null) - private def readResolve(): Any = Manifest.Nothing - } - def Nothing: Manifest[scala.Nothing] = NothingManifest - - private class SingletonTypeManifest[T <: AnyRef](value: AnyRef) extends Manifest[T] { - lazy val runtimeClass = value.getClass - override lazy val toString = value.toString + ".type" - } - - /** Manifest for the singleton type `value.type`. */ - def singleType[T <: AnyRef](value: AnyRef): Manifest[T] = - new SingletonTypeManifest[T](value) - - /** Manifest for the class type `clazz[args]`, where `clazz` is - * a top-level or static class. - * @note This no-prefix, no-arguments case is separate because we - * it's called from ScalaRunTime.boxArray itself. If we - * pass varargs as arrays into this, we get an infinitely recursive call - * to boxArray. (Besides, having a separate case is more efficient) - */ - def classType[T](clazz: Predef.Class[_]): Manifest[T] = - new ClassTypeManifest[T](None, clazz, Nil) - - /** Manifest for the class type `clazz`, where `clazz` is - * a top-level or static class and args are its type arguments. */ - def classType[T](clazz: Predef.Class[T], arg1: Manifest[_], args: Manifest[_]*): Manifest[T] = - new ClassTypeManifest[T](None, clazz, arg1 :: args.toList) - - /** Manifest for the class type `clazz[args]`, where `clazz` is - * a class with non-package prefix type `prefix` and type arguments `args`. - */ - def classType[T](prefix: Manifest[_], clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] = - new ClassTypeManifest[T](Some(prefix), clazz, args.toList) - - private abstract class PhantomManifest[T](_runtimeClass: Predef.Class[_], - override val toString: String) extends ClassTypeManifest[T](None, _runtimeClass, Nil) { - override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef] - override def hashCode = System.identityHashCode(this) - } - - /** Manifest for the class type `clazz[args]`, where `clazz` is - * a top-level or static class. */ - private class ClassTypeManifest[T](prefix: Option[Manifest[_]], - runtimeClass1: Predef.Class[_], - override val typeArguments: List[Manifest[_]]) extends Manifest[T] { - def runtimeClass: Predef.Class[_] = runtimeClass1 - override def toString = - (if (prefix.isEmpty) "" else prefix.get.toString+"#") + - (if (runtimeClass.isArray) "Array" else runtimeClass.getName) + - argString - } - - def arrayType[T](arg: Manifest[_]): Manifest[Array[T]] = - arg.asInstanceOf[Manifest[T]].arrayManifest - - private class AbstractTypeManifest[T](prefix: Manifest[_], name: String, upperBound: Predef.Class[_], args: Seq[Manifest[_]]) extends Manifest[T] { - def runtimeClass = upperBound - override val typeArguments = args.toList - override def toString = prefix.toString+"#"+name+argString - } - - /** Manifest for the abstract type `prefix # name`. `upperBound` is not - * strictly necessary as it could be obtained by reflection. It was - * added so that erasure can be calculated without reflection. */ - def abstractType[T](prefix: Manifest[_], name: String, upperBound: Predef.Class[_], args: Manifest[_]*): Manifest[T] = - new AbstractTypeManifest[T](prefix, name, upperBound, args) - - private class WildcardManifest[T](lowerBound: Manifest[_], upperBound: Manifest[_]) extends Manifest[T] { - def runtimeClass = upperBound.runtimeClass - override def toString = - "_" + - (if (lowerBound eq Nothing) "" else " >: "+lowerBound) + - (if (upperBound eq Nothing) "" else " <: "+upperBound) - } - - /** Manifest for the unknown type `_ >: L <: U` in an existential. - */ - def wildcardType[T](lowerBound: Manifest[_], upperBound: Manifest[_]): Manifest[T] = - new WildcardManifest[T](lowerBound, upperBound) - - private class IntersectionTypeManifest[T](parents: Array[Manifest[_]]) extends Manifest[T] { - // We use an `Array` instead of a `Seq` for `parents` to avoid cyclic dependencies during deserialization - // which can cause serialization proxies to leak and cause a ClassCastException. - def runtimeClass = parents(0).runtimeClass - override def toString = parents.mkString(" with ") - } - - /** Manifest for the intersection type `parents_0 with ... with parents_n`. */ - def intersectionType[T](parents: Manifest[_]*): Manifest[T] = - new IntersectionTypeManifest[T](parents.toArray) -} diff --git a/scalalib/overrides-2.13.0-M4/scala/runtime/ScalaRunTime.scala b/scalalib/overrides-2.13.0-M4/scala/runtime/ScalaRunTime.scala deleted file mode 100644 index 84d7395106..0000000000 --- a/scalalib/overrides-2.13.0-M4/scala/runtime/ScalaRunTime.scala +++ /dev/null @@ -1,282 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala -package runtime - -import scala.collection.{ AbstractIterator, AnyConstr, SortedOps, StrictOptimizedIterableOps, StringOps, StringView, View } -import scala.collection.generic.IsIterableLike -import scala.collection.immutable.{ NumericRange, ArraySeq } -import scala.collection.mutable.StringBuilder -import scala.reflect.{ ClassTag, classTag } -import java.lang.{ Class => jClass } - -import java.lang.reflect.{ Method => JMethod } - -/** The object ScalaRunTime provides support methods required by - * the scala runtime. All these methods should be considered - * outside the API and subject to change or removal without notice. - */ -object ScalaRunTime { - def isArray(x: Any, atLevel: Int = 1): Boolean = - x != null && isArrayClass(x.getClass, atLevel) - - private def isArrayClass(clazz: jClass[_], atLevel: Int): Boolean = - clazz != null && clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) - - // A helper method to make my life in the pattern matcher a lot easier. - def drop[Repr](coll: Repr, num: Int)(implicit iterable: IsIterableLike[Repr]): Repr = - iterable conversion coll drop num - - /** Return the class object representing an array with element class `clazz`. - */ - def arrayClass(clazz: jClass[_]): jClass[_] = { - // newInstance throws an exception if the erasure is Void.TYPE. see scala/bug#5680 - if (clazz == java.lang.Void.TYPE) classOf[Array[Unit]] - else java.lang.reflect.Array.newInstance(clazz, 0).getClass - } - - /** Return the class object representing an unboxed value type, - * e.g., classOf[int], not classOf[java.lang.Integer]. The compiler - * rewrites expressions like 5.getClass to come here. - */ - def anyValClass[T <: AnyVal : ClassTag](value: T): jClass[T] = - classTag[T].runtimeClass.asInstanceOf[jClass[T]] - - /** Retrieve generic array element */ - def array_apply(xs: AnyRef, idx: Int): Any = { - xs match { - case x: Array[AnyRef] => x(idx).asInstanceOf[Any] - case x: Array[Int] => x(idx).asInstanceOf[Any] - case x: Array[Double] => x(idx).asInstanceOf[Any] - case x: Array[Long] => x(idx).asInstanceOf[Any] - case x: Array[Float] => x(idx).asInstanceOf[Any] - case x: Array[Char] => x(idx).asInstanceOf[Any] - case x: Array[Byte] => x(idx).asInstanceOf[Any] - case x: Array[Short] => x(idx).asInstanceOf[Any] - case x: Array[Boolean] => x(idx).asInstanceOf[Any] - case x: Array[Unit] => x(idx).asInstanceOf[Any] - case null => throw new NullPointerException - } - } - - /** update generic array element */ - def array_update(xs: AnyRef, idx: Int, value: Any): Unit = { - xs match { - case x: Array[AnyRef] => x(idx) = value.asInstanceOf[AnyRef] - case x: Array[Int] => x(idx) = value.asInstanceOf[Int] - case x: Array[Double] => x(idx) = value.asInstanceOf[Double] - case x: Array[Long] => x(idx) = value.asInstanceOf[Long] - case x: Array[Float] => x(idx) = value.asInstanceOf[Float] - case x: Array[Char] => x(idx) = value.asInstanceOf[Char] - case x: Array[Byte] => x(idx) = value.asInstanceOf[Byte] - case x: Array[Short] => x(idx) = value.asInstanceOf[Short] - case x: Array[Boolean] => x(idx) = value.asInstanceOf[Boolean] - case x: Array[Unit] => x(idx) = value.asInstanceOf[Unit] - case null => throw new NullPointerException - } - } - - /** Get generic array length */ - def array_length(xs: AnyRef): Int = xs match { - case x: Array[AnyRef] => x.length - case x: Array[Int] => x.length - case x: Array[Double] => x.length - case x: Array[Long] => x.length - case x: Array[Float] => x.length - case x: Array[Char] => x.length - case x: Array[Byte] => x.length - case x: Array[Short] => x.length - case x: Array[Boolean] => x.length - case x: Array[Unit] => x.length - case null => throw new NullPointerException - } - - def array_clone(xs: AnyRef): AnyRef = xs match { - case x: Array[AnyRef] => x.clone() - case x: Array[Int] => x.clone() - case x: Array[Double] => x.clone() - case x: Array[Long] => x.clone() - case x: Array[Float] => x.clone() - case x: Array[Char] => x.clone() - case x: Array[Byte] => x.clone() - case x: Array[Short] => x.clone() - case x: Array[Boolean] => x.clone() - case x: Array[Unit] => x - case null => throw new NullPointerException - } - - /** Convert an array to an object array. - * Needed to deal with vararg arguments of primitive types that are passed - * to a generic Java vararg parameter T ... - */ - def toObjectArray(src: AnyRef): Array[Object] = src match { - case x: Array[AnyRef] => x - case _ => - val length = array_length(src) - val dest = new Array[Object](length) - for (i <- 0 until length) - array_update(dest, i, array_apply(src, i)) - dest - } - - def toArray[T](xs: scala.collection.Seq[T]) = { - val arr = new Array[AnyRef](xs.length) - var i = 0 - for (x <- xs) { - arr(i) = x.asInstanceOf[AnyRef] - i += 1 - } - arr - } - - // Java bug: https://bugs.java.com/view_bug.do?bug_id=4071957 - // More background at ticket #2318. - def ensureAccessible(m: JMethod): JMethod = scala.reflect.ensureAccessible(m) - - def _toString(x: Product): String = - x.productIterator.mkString(x.productPrefix + "(", ",", ")") - - def _hashCode(x: Product): Int = scala.util.hashing.MurmurHash3.productHash(x) - - /** A helper for case classes. */ - def typedProductIterator[T](x: Product): Iterator[T] = { - new AbstractIterator[T] { - private var c: Int = 0 - private val cmax = x.productArity - def hasNext = c < cmax - def next() = { - val result = x.productElement(c) - c += 1 - result.asInstanceOf[T] - } - } - } - - /** Given any Scala value, convert it to a String. - * - * The primary motivation for this method is to provide a means for - * correctly obtaining a String representation of a value, while - * avoiding the pitfalls of naively calling toString on said value. - * In particular, it addresses the fact that (a) toString cannot be - * called on null and (b) depending on the apparent type of an - * array, toString may or may not print it in a human-readable form. - * - * @param arg the value to stringify - * @return a string representation of arg. - */ - def stringOf(arg: Any): String = stringOf(arg, scala.Int.MaxValue) - def stringOf(arg: Any, maxElements: Int): String = { - def packageOf(x: AnyRef) = x.getClass.getPackage match { - case null => "" - case p => p.getName - } - def isScalaClass(x: AnyRef) = packageOf(x) startsWith "scala." - def isScalaCompilerClass(x: AnyRef) = packageOf(x) startsWith "scala.tools.nsc." - - // includes specialized subclasses and future proofed against hypothetical TupleN (for N > 22) - def isTuple(x: Any) = x != null && x.getClass.getName.startsWith("scala.Tuple") - - // We use reflection because the scala.xml package might not be available - def isSubClassOf(potentialSubClass: Class[_], ofClass: String) = - try { - val classLoader = potentialSubClass.getClassLoader - val clazz = Class.forName(ofClass, /*initialize =*/ false, classLoader) - clazz.isAssignableFrom(potentialSubClass) - } catch { - case cnfe: ClassNotFoundException => false - } - def isXmlNode(potentialSubClass: Class[_]) = isSubClassOf(potentialSubClass, "scala.xml.Node") - def isXmlMetaData(potentialSubClass: Class[_]) = isSubClassOf(potentialSubClass, "scala.xml.MetaData") - - // When doing our own iteration is dangerous - def useOwnToString(x: Any) = x match { - // Range/NumericRange have a custom toString to avoid walking a gazillion elements - case _: Range | _: NumericRange[_] => true - // Sorted collections to the wrong thing (for us) on iteration - ticket #3493 - case _: SortedOps[_, _] => true - // StringBuilder(a, b, c) and similar not so attractive - case _: StringView | _: StringOps | _: StringBuilder => true - // Don't want to evaluate any elements in a view - case _: View[_] => true - // Node extends NodeSeq extends Seq[Node] and MetaData extends Iterable[MetaData] - // -> catch those by isXmlNode and isXmlMetaData. - // Don't want to a) traverse infinity or b) be overly helpful with peoples' custom - // collections which may have useful toString methods - ticket #3710 - // or c) print AbstractFiles which are somehow also Iterable[AbstractFile]s. - case x: Iterable[_] => (!x.isInstanceOf[StrictOptimizedIterableOps[_, AnyConstr, _]]) || !isScalaClass(x) || isScalaCompilerClass(x) || isXmlNode(x.getClass) || isXmlMetaData(x.getClass) - // Otherwise, nothing could possibly go wrong - case _ => false - } - - // A variation on inner for maps so they print -> instead of bare tuples - def mapInner(arg: Any): String = arg match { - case (k, v) => inner(k) + " -> " + inner(v) - case _ => inner(arg) - } - - // Special casing Unit arrays, the value class which uses a reference array type. - def arrayToString(x: AnyRef) = { - if (x.getClass.getComponentType == classOf[BoxedUnit]) - 0 until (array_length(x) min maxElements) map (_ => "()") mkString ("Array(", ", ", ")") - else - x.asInstanceOf[Array[_]].iterator.take(maxElements).map(inner).mkString("Array(", ", ", ")") - } - - // The recursively applied attempt to prettify Array printing. - // Note that iterator is used if possible and foreach is used as a - // last resort, because the parallel collections "foreach" in a - // random order even on sequences. - def inner(arg: Any): String = arg match { - case null => "null" - case "" => "\"\"" - case x: String => if (x.head.isWhitespace || x.last.isWhitespace) "\"" + x + "\"" else x - case x if useOwnToString(x) => x.toString - case x: AnyRef if isArray(x) => arrayToString(x) - case x: scala.collection.Map[_, _] => x.iterator take maxElements map mapInner mkString (x.className + "(", ", ", ")") - case x: Iterable[_] => x.iterator take maxElements map inner mkString (x.className + "(", ", ", ")") - case x: Product1[_] if isTuple(x) => "(" + inner(x._1) + ",)" // that special trailing comma - case x: Product if isTuple(x) => x.productIterator map inner mkString ("(", ",", ")") - case x => x.toString - } - - // The try/catch is defense against iterables which aren't actually designed - // to be iterated, such as some scala.tools.nsc.io.AbstractFile derived classes. - try inner(arg) - catch { - case _: UnsupportedOperationException | _: AssertionError => "" + arg - } - } - - /** stringOf formatted for use in a repl result. */ - def replStringOf(arg: Any, maxElements: Int): String = { - val s = stringOf(arg, maxElements) - val nl = if (s contains "\n") "\n" else "" - - nl + s + "\n" - } - - // Convert arrays to immutable.ArraySeq for use with Java varargs: - def genericWrapArray[T](xs: Array[T]): ArraySeq[T] = - if (xs eq null) null - else ArraySeq.unsafeWrapArray(xs) - def wrapRefArray[T <: AnyRef](xs: Array[T]): ArraySeq[T] = { - if (xs eq null) null - else if (xs.length == 0) ArraySeq.empty[AnyRef].asInstanceOf[ArraySeq[T]] - else new ArraySeq.ofRef[T](xs) - } - def wrapIntArray(xs: Array[Int]): ArraySeq[Int] = if (xs ne null) new ArraySeq.ofInt(xs) else null - def wrapDoubleArray(xs: Array[Double]): ArraySeq[Double] = if (xs ne null) new ArraySeq.ofDouble(xs) else null - def wrapLongArray(xs: Array[Long]): ArraySeq[Long] = if (xs ne null) new ArraySeq.ofLong(xs) else null - def wrapFloatArray(xs: Array[Float]): ArraySeq[Float] = if (xs ne null) new ArraySeq.ofFloat(xs) else null - def wrapCharArray(xs: Array[Char]): ArraySeq[Char] = if (xs ne null) new ArraySeq.ofChar(xs) else null - def wrapByteArray(xs: Array[Byte]): ArraySeq[Byte] = if (xs ne null) new ArraySeq.ofByte(xs) else null - def wrapShortArray(xs: Array[Short]): ArraySeq[Short] = if (xs ne null) new ArraySeq.ofShort(xs) else null - def wrapBooleanArray(xs: Array[Boolean]): ArraySeq[Boolean] = if (xs ne null) new ArraySeq.ofBoolean(xs) else null - def wrapUnitArray(xs: Array[Unit]): ArraySeq[Unit] = if (xs ne null) new ArraySeq.ofUnit(xs) else null -} diff --git a/scripts/publish.sh b/scripts/publish.sh index dcafc4f297..850c1449d1 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -7,8 +7,9 @@ else CMD="echo sbt" fi -FULL_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.10.7 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.11.12 2.12.0 2.12.1 2.12.2 2.12.3 2.12.4 2.12.5 2.12.6 2.13.0-M3" -BIN_VERSIONS="2.10.7 2.11.12 2.12.6 2.13.0-M3" +COMPILER_VERSIONS="2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.10.7 2.11.0 2.11.1 2.11.2 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.11 2.11.12 2.12.0 2.12.1 2.12.2 2.12.3 2.12.4 2.12.5 2.12.6 2.13.0-M5" +BIN_VERSIONS="2.10.7 2.11.12 2.12.6" +NO_TOOLS_BIN_VERSIONS="2.13.0-M5" CLI_VERSIONS="2.10.7 2.11.12 2.12.6" SBT_VERSION="2.10.7" SBT1_VERSION="2.12.6" @@ -16,9 +17,10 @@ SBT1_SBTVERSION="1.0.0" COMPILER="compiler jUnitPlugin" LIBS="library javalibEx ir irJS tools toolsJS jsEnvs jsEnvsTestKit testAdapter stubs testInterface jUnitRuntime" +NO_TOOLS_LIBS="library javalibEx stubs testInterface jUnitRuntime" # Publish compiler -for v in $FULL_VERSIONS; do +for v in $COMPILER_VERSIONS; do ARGS="++$v" for p in $COMPILER; do ARGS="$ARGS $p/publishSigned" @@ -35,6 +37,15 @@ for v in $BIN_VERSIONS; do $CMD $ARGS done +# Publish limited versions +for v in $NO_TOOLS_BIN_VERSIONS; do + ARGS="++$v" + for p in $NO_TOOLS_LIBS; do + ARGS="$ARGS $p/publishSigned" + done + $CMD $ARGS +done + # Publish the CLI for v in $CLI_VERSIONS; do $CMD "++$v" "cli/publishSigned" diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ArrayOpsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ArrayOpsTest.scala index aa8c6130d8..974e61fe85 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ArrayOpsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/library/ArrayOpsTest.scala @@ -77,14 +77,12 @@ class ArrayOpsTest { @Test def head(): Unit = { assertEquals(5, js.Array(5, 7, 10).head) - assumeFalse(scalaVersion == "2.13.0-M4") assertThrows(classOf[NoSuchElementException], js.Array[Int]().head) } @Test def last(): Unit = { assertEquals(10, js.Array(5, 7, 10).last) - assumeFalse(scalaVersion == "2.13.0-M4") assertThrows(classOf[NoSuchElementException], js.Array[Int]().last) } @@ -203,7 +201,6 @@ class ArrayOpsTest { assertEquals(2, iter.next()) assertFalse(iter.hasNext) - assumeFalse(scalaVersion == "2.13.0-M4") assertThrows(classOf[NoSuchElementException], iter.next()) } @@ -724,7 +721,6 @@ class ArrayOpsTest { assertJSArrayEquals(js.Array(2, 3, 5, 13, 21, 36, 51, 0, 2), array) } - /* TODO Reenable this when we get rid of 2.13.0-M4 @Test def appendAll(): Unit = { val array = js.Array(2, 3, 5) array.appendAll(List(13, 21, 36)) @@ -732,7 +728,6 @@ class ArrayOpsTest { array.appendAll(js.Array(51, 0, 2)) assertJSArrayEquals(js.Array(2, 3, 5, 13, 21, 36, 51, 0, 2), array) } - */ @Test def -=(): Unit = { val array = js.Array(2, 3, 5, 3, 24, 2) @@ -770,7 +765,6 @@ class ArrayOpsTest { assertJSArrayEquals(js.Array(51, 0, 2, 13, 21, 36, 2, 3, 5), array) } - /* TODO Reenable this when we get rid of 2.13.0-M4 @Test def ++=:(): Unit = { val array = js.Array(2, 3, 5) List(13, 21, 36) ++=: array @@ -778,7 +772,6 @@ class ArrayOpsTest { js.Array(51, 0, 2) ++=: array assertJSArrayEquals(js.Array(51, 0, 2, 13, 21, 36, 2, 3, 5), array) } - */ @Test def insert(): Unit = { val array = js.Array(2, 3, 5, 54, 23) @@ -829,11 +822,10 @@ class ArrayOpsTest { val array = js.Array(33, 11, 2, 3, 42, 53, 5, 54, 23, 44, 78) array.trimStart(4) - assumeFalse("the safe behavior was introduced in 2.13.0-M4", + assumeFalse("the safe behavior was introduced in 2.13", scalaVersion.startsWith("2.10.") || scalaVersion.startsWith("2.11.") || - scalaVersion.startsWith("2.12.") || - scalaVersion == "2.13.0-M3") + scalaVersion.startsWith("2.12.")) assertJSArrayEquals(js.Array(42, 53, 5, 54, 23, 44, 78), array) array.trimStart(-3) assertJSArrayEquals(js.Array(42, 53, 5, 54, 23, 44, 78), array) @@ -845,11 +837,10 @@ class ArrayOpsTest { val array = js.Array(33, 11, 2, 3, 42, 53, 5, 54, 23, 44, 78) array.trimEnd(4) - assumeFalse("the safe behavior was introduced in 2.13.0-M4", + assumeFalse("the safe behavior was introduced in 2.13", scalaVersion.startsWith("2.10.") || scalaVersion.startsWith("2.11.") || - scalaVersion.startsWith("2.12.") || - scalaVersion == "2.13.0-M3") + scalaVersion.startsWith("2.12.")) assertJSArrayEquals(js.Array(33, 11, 2, 3, 42, 53, 5), array) array.trimEnd(-3) assertJSArrayEquals(js.Array(33, 11, 2, 3, 42, 53, 5), array) diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/IntTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/IntTest.scala index 7e9ec85d8f..71c2899150 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/IntTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/IntTest.scala @@ -343,8 +343,7 @@ class IntTest { private def scalacCorrectlyHandlesIntShiftLong: Boolean = { import Platform.scalaVersion - !(scalaVersion.startsWith("2.10.") || scalaVersion.startsWith("2.11.") || - scalaVersion.startsWith("2.12.0-M4")) + !(scalaVersion.startsWith("2.10.") || scalaVersion.startsWith("2.11.")) } @Test def intShiftLeftLongConstantFolded(): Unit = { diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala index 1d881a38e2..dfde41ec15 100644 --- a/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/compiler/RegressionTest.scala @@ -175,7 +175,7 @@ class RegressionTest { scalaVersion.startsWith("2.11.") || scalaVersion == "2.12.0" || scalaVersion == "2.12.1" || scalaVersion == "2.12.2" || scalaVersion == "2.12.3" || - scalaVersion == "2.12.4" || scalaVersion == "2.13.0-M3" + scalaVersion == "2.12.4" }) assertEquals("org.scalajs.testsuite.compiler.RegressionTest$Bug218Foo", From 3562e131c8c079d87570d0524b3cd25c3b50c606 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 5 Dec 2018 23:38:40 +0100 Subject: [PATCH 0871/2665] Make `UnsupportedInputException` a normal (non-case) class. There seems to be no reason for it to be a case class. --- js-envs/src/main/scala/org/scalajs/jsenv/Input.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/Input.scala b/js-envs/src/main/scala/org/scalajs/jsenv/Input.scala index 26314eb819..645ffe1b13 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/Input.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/Input.scala @@ -30,7 +30,7 @@ object Input { final case class ScriptsToLoad(scripts: List[VirtualBinaryFile]) extends Input } -case class UnsupportedInputException(msg: String, cause: Throwable) +class UnsupportedInputException(msg: String, cause: Throwable) extends IllegalArgumentException(msg, cause) { def this(msg: String) = this(msg, null) def this(input: Input) = this(s"Unsupported input: $input") From 8ea01ea07fbc9423be463e8381d092468cc01625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 16 Nov 2018 11:29:45 +0100 Subject: [PATCH 0872/2665] Add the distinction between Script and CommonJS module in Input. Scripts must be executed in the global scope, so that top-level declarations end up being available to other scripts, and also as members of the global object. Previously, `NodeJSEnv` would only load `Input.ScriptsToLoad` as true scripts if they were in-memory, by piping them to the standard input of Node.js. For actual files, it used `require`, which loads them as CommonJS modules, producing the wrong behavior for top-level declarations. We now introduce a separate `Input.CommonJSModulesToLoad`. For those, `NodeJSEnv` always uses `require`, even for in-memory ones. For `Input.ScriptsToLoad`, we use the `vm` module of Node.js and its method `runInThisContext` in order to actually run files as scripts, without losing source information. --- .../main/scala/org/scalajs/jsenv/Input.scala | 4 + .../org/scalajs/jsenv/nodejs/NodeJSEnv.scala | 144 ++++++++++++++---- project/Build.scala | 68 ++++++--- .../sbtplugin/ScalaJSPluginInternal.scala | 9 +- 4 files changed, 169 insertions(+), 56 deletions(-) diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/Input.scala b/js-envs/src/main/scala/org/scalajs/jsenv/Input.scala index 645ffe1b13..6d6dc57920 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/Input.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/Input.scala @@ -28,6 +28,10 @@ abstract class Input private () object Input { /** All files are to be loaded as scripts into the global scope in the order given. */ final case class ScriptsToLoad(scripts: List[VirtualBinaryFile]) extends Input + + /** All files are to be loaded as CommonJS modules, in the given order. */ + final case class CommonJSModulesToLoad(modules: List[VirtualBinaryFile]) + extends Input } class UnsupportedInputException(msg: String, cause: Throwable) diff --git a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala index 451a27f6cc..8dc65b81c1 100644 --- a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala +++ b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala @@ -34,25 +34,36 @@ final class NodeJSEnv(config: NodeJSEnv.Config) extends JSEnv { def start(input: Input, runConfig: RunConfig): JSRun = { NodeJSEnv.validator.validate(runConfig) - internalStart(initFiles ++ inputFiles(input), runConfig) + validateInput(input) + internalStart(initFiles, input, runConfig) } def startWithCom(input: Input, runConfig: RunConfig, onMessage: String => Unit): JSComRun = { NodeJSEnv.validator.validate(runConfig) + validateInput(input) ComRun.start(runConfig, onMessage) { comLoader => - val files = initFiles ::: (comLoader :: inputFiles(input)) - internalStart(files, runConfig) + internalStart(initFiles :+ comLoader, input, runConfig) } } - private def internalStart(files: List[VirtualBinaryFile], + private def validateInput(input: Input): Unit = { + input match { + case _:Input.ScriptsToLoad | _:Input.CommonJSModulesToLoad => + // ok + case _ => + throw new UnsupportedInputException(input) + } + } + + private def internalStart(initFiles: List[VirtualBinaryFile], input: Input, runConfig: RunConfig): JSRun = { val command = config.executable :: config.args val externalConfig = ExternalJSRun.Config() .withEnv(env) .withRunConfig(runConfig) - ExternalJSRun.start(command, externalConfig)(NodeJSEnv.write(files)) + ExternalJSRun.start(command, externalConfig)( + NodeJSEnv.write(initFiles, input)) } private def initFiles: List[VirtualBinaryFile] = { @@ -103,39 +114,112 @@ object NodeJSEnv { ) } - private def write(files: List[VirtualBinaryFile])(out: OutputStream): Unit = { + private def write(initFiles: List[VirtualBinaryFile], input: Input)( + out: OutputStream): Unit = { val p = new PrintStream(out, false, "UTF8") try { - files.foreach { - case file: FileVirtualBinaryFile => - val fname = file.file.getAbsolutePath - p.println(s"""require("${escapeJS(fname)}");""") - case f => - val in = f.inputStream - try { - val buf = new Array[Byte](4096) - - @tailrec - def loop(): Unit = { - val read = in.read(buf) - if (read != -1) { - p.write(buf, 0, read) - loop() - } - } - - loop() - } finally { - in.close() - } - - p.println() + def writeRunScript(file: VirtualBinaryFile): Unit = { + file match { + case file: FileVirtualBinaryFile => + val pathJS = "\"" + escapeJS(file.file.getAbsolutePath) + "\"" + p.println(s""" + require('vm').runInThisContext( + require('fs').readFileSync($pathJS, { encoding: "utf-8" }), + { filename: $pathJS, displayErrors: true } + ); + """) + + case _ => + val code = readInputStreamToString(file.inputStream) + val codeJS = "\"" + escapeJS(code) + "\"" + val pathJS = "\"" + escapeJS(file.path) + "\"" + p.println(s""" + require('vm').runInThisContext( + $codeJS, + { filename: $pathJS, displayErrors: true } + ); + """) + } + } + + def writeRequire(file: VirtualBinaryFile): Unit = { + file match { + case file: FileVirtualBinaryFile => + p.println(s"""require("${escapeJS(file.file.getAbsolutePath)}")""") + + case _ => + val f = tmpFile(file.path, file.inputStream) + p.println(s"""require("${escapeJS(f.getAbsolutePath)}")""") + } + } + + for (initFile <- initFiles) + writeRunScript(initFile) + + input match { + case Input.ScriptsToLoad(scripts) => + for (script <- scripts) + writeRunScript(script) + + case Input.CommonJSModulesToLoad(modules) => + for (module <- modules) + writeRequire(module) } } finally { p.close() } } + private def readInputStreamToString(inputStream: InputStream): String = { + val baos = new java.io.ByteArrayOutputStream + val in = inputStream + try { + val buf = new Array[Byte](4096) + + @tailrec + def loop(): Unit = { + val read = in.read(buf) + if (read != -1) { + baos.write(buf, 0, read) + loop() + } + } + + loop() + } finally { + in.close() + } + new String(baos.toByteArray(), StandardCharsets.UTF_8) + } + + private def tmpFile(path: String, content: InputStream): File = { + import java.nio.file.{Files, StandardCopyOption} + + try { + val f = createTmpFile(path) + Files.copy(content, f.toPath(), StandardCopyOption.REPLACE_EXISTING) + f + } finally { + content.close() + } + } + + // tmpSuffixRE and createTmpFile copied from HTMLRunnerBuilder.scala + + private val tmpSuffixRE = """[a-zA-Z0-9-_.]*$""".r + + private def createTmpFile(path: String): File = { + /* - createTempFile requires a prefix of at least 3 chars + * - we use a safe part of the path as suffix so the extension stays (some + * browsers need that) and there is a clue which file it came from. + */ + val suffix = tmpSuffixRE.findFirstIn(path).orNull + + val f = File.createTempFile("tmp-", suffix) + f.deleteOnExit() + f + } + /** Requirements for source map support. */ sealed abstract class SourceMap diff --git a/project/Build.scala b/project/Build.scala index a549153efc..fee1774be9 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -30,7 +30,7 @@ import ScalaJSPlugin.autoImport.{ModuleKind => _, _} import ExternalCompile.scalaJSExternalCompileSettings import Loggers._ -import org.scalajs.io.{FileVirtualBinaryFile, MemVirtualBinaryFile} +import org.scalajs.io._ import org.scalajs.io.JSUtils.escapeJS import org.scalajs.linker._ import org.scalajs.linker.irio._ @@ -78,20 +78,28 @@ object MyScalaJSPlugin extends AutoPlugin { if (javaSystemProperties.isEmpty) { prev } else { - val Input.ScriptsToLoad(prevFiles) = prev - val formattedProps = javaSystemProperties.map { case (propName, propValue) => "\"" + escapeJS(propName) + "\": \"" + escapeJS(propValue) + "\"" } - val code = { + + val needsGlobal = !prev.isInstanceOf[Input.ScriptsToLoad] + val code = if (needsGlobal) { + "global.__ScalaJSEnv = global.__ScalaJSEnv || {};\n" + + "global.__ScalaJSEnv.javaSystemProperties = {" + formattedProps.mkString(", ") + "};\n" + } else { "var __ScalaJSEnv = (typeof __ScalaJSEnv === \"object\" && __ScalaJSEnv) ? __ScalaJSEnv : {};\n" + "__ScalaJSEnv.javaSystemProperties = {" + formattedProps.mkString(", ") + "};\n" } val javaSysPropsFile = MemVirtualBinaryFile.fromStringUTF8("setJavaSystemProperties.js", code) - Input.ScriptsToLoad(javaSysPropsFile +: prevFiles) + prev match { + case Input.ScriptsToLoad(prevFiles) => + Input.ScriptsToLoad(javaSysPropsFile :: prevFiles) + case Input.CommonJSModulesToLoad(prevFiles) => + Input.CommonJSModulesToLoad(javaSysPropsFile :: prevFiles) + } } } ) @@ -1456,7 +1464,6 @@ object Build { // We need to patch the system properties. jsEnvInput in (Test, testHtml) := { val previousInput = (jsEnvInput in (Test, testHtml)).value - val Input.ScriptsToLoad(previousFiles) = previousInput val patchedSystemProperties = { // Fetch the defaults @@ -1476,24 +1483,32 @@ object Build { case (propName, propValue) => "\"" + escapeJS(propName) + "\": \"" + escapeJS(propValue) + "\"" }.mkString("{ ", ", ", " }") - val code = s""" - var __ScalaJSEnv = { - javaSystemProperties: $formattedProps - }; - """ - - val patchedSystemPropertiesFile = - MemVirtualBinaryFile.fromStringUTF8("setJavaSystemProperties.js", code) - - // Replace the normal `setJavaSystemProperties.js` file with the patch - val newFiles = for (file <- previousFiles) yield { - if (file.path == "setJavaSystemProperties.js") - patchedSystemPropertiesFile - else - file + + def patchFiles(files: List[VirtualBinaryFile], needsGlobal: Boolean) = { + val code = s""" + ${if (needsGlobal) "global." else "var "}__ScalaJSEnv = { + javaSystemProperties: $formattedProps + }; + """ + + val patchedSystemPropertiesFile = + MemVirtualBinaryFile.fromStringUTF8("setJavaSystemProperties.js", code) + + // Replace the normal `setJavaSystemProperties.js` file with the patch + for (file <- files) yield { + if (file.path == "setJavaSystemProperties.js") + patchedSystemPropertiesFile + else + file + } } - Input.ScriptsToLoad(newFiles) + previousInput match { + case Input.ScriptsToLoad(prevFiles) => + Input.ScriptsToLoad(patchFiles(prevFiles, needsGlobal = false)) + case Input.CommonJSModulesToLoad(prevFiles) => + Input.CommonJSModulesToLoad(patchFiles(prevFiles, needsGlobal = true)) + } } ) @@ -1563,11 +1578,16 @@ object Build { def testSuiteJSExecutionFilesSetting: Setting[_] = { jsEnvInput := { - val Input.ScriptsToLoad(prevFiles) = jsEnvInput.value val resourceDir = (resourceDirectory in Test).value val f = new FileVirtualBinaryFile( resourceDir / "NonNativeJSTypeTestNatives.js") - Input.ScriptsToLoad(f +: prevFiles) + + jsEnvInput.value match { + case Input.ScriptsToLoad(prevFiles) => + Input.ScriptsToLoad(f :: prevFiles) + case Input.CommonJSModulesToLoad(prevFiles) => + Input.CommonJSModulesToLoad(f :: prevFiles) + } } } diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index f7437cdd31..0a9aedc964 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -307,8 +307,13 @@ private[sbtplugin] object ScalaJSPluginInternal { // Use the Scala.js linked file as the default Input for the JSEnv jsEnvInput := { - Input.ScriptsToLoad(List( - new FileVirtualBinaryFile(scalaJSLinkedFile.value.data))) + val linkedFile = new FileVirtualBinaryFile(scalaJSLinkedFile.value.data) + scalaJSLinkerConfig.value.moduleKind match { + case ModuleKind.NoModule => + Input.ScriptsToLoad(List(linkedFile)) + case ModuleKind.CommonJSModule => + Input.CommonJSModulesToLoad(List(linkedFile)) + } }, scalaJSMainModuleInitializer := { From 657e54142537397e0abcb14e03498b8fe60c1509 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 16 Nov 2018 15:09:19 +0100 Subject: [PATCH 0873/2665] In `NoModule`, use true top-level `var`s for top-level exports. Before, we needed to detect the global object at run-time (which is not fool-proof) to add top-level exports as properties of the global object. Now, top-level exports are truly defined as global `var`s. When using ECMAScript 2015 features, in theory we should use global `let`s instead. However, that means that the variables would not be available in the global object, and that poses a problem for our test suite. Our test suite relies on the ability to get an "exports namespace", which in that case would not be possible. We *could* update our test suite with zillions of if (noModule) js.Dynamic.global.exportToTest else exportsNamespace.exportToTest but that would be really annoying. Doing so is left for a future commit. --- .../closure/ClosureLinkerBackend.scala | 23 +++-- linker/scalajsenv.js | 10 --- .../linker/backend/emitter/ClassEmitter.scala | 83 +++++++++++++------ .../linker/backend/emitter/Emitter.scala | 29 ++++++- .../backend/emitter/FunctionEmitter.scala | 14 +++- .../backend/emitter/GlobalKnowledge.scala | 5 +- .../backend/emitter/KnowledgeGuardian.scala | 40 ++++++++- .../testsuite/jsinterop/ExportsTest.scala | 2 + 8 files changed, 154 insertions(+), 52 deletions(-) diff --git a/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala index 9b20531f38..9ce794fd8c 100644 --- a/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala @@ -72,10 +72,13 @@ final class ClosureLinkerBackend(config: LinkerBackendImpl.Config) verifyUnit(unit) // Build Closure IR - val module = logger.time("Emitter (create Closure trees)") { - val builder = new ClosureModuleBuilder(config.relativizeSourceMapBase) - emitter.emitForClosure(unit, builder, logger) - builder.result() + val (topLevelVarDeclarations, module) = { + logger.time("Emitter (create Closure trees)") { + val builder = new ClosureModuleBuilder(config.relativizeSourceMapBase) + val topLevelVarDeclarations = + emitter.emitForClosure(unit, builder, logger) + (topLevelVarDeclarations, builder.result()) + } } // Compile the module @@ -91,7 +94,7 @@ final class ClosureLinkerBackend(config: LinkerBackendImpl.Config) } logger.time("Closure: Write result") { - writeResult(result, compiler, output) + writeResult(topLevelVarDeclarations, result, compiler, output) } } @@ -131,12 +134,15 @@ final class ClosureLinkerBackend(config: LinkerBackendImpl.Config) compiler } - private def writeResult(result: Result, compiler: ClosureCompiler, - output: LinkerOutput): Unit = { + private def writeResult(topLevelVarDeclarations: Option[String], + result: Result, compiler: ClosureCompiler, output: LinkerOutput): Unit = { def ifIIFE(str: String): String = if (needsIIFEWrapper) str else "" - val header = ifIIFE("(function(){") + "'use strict';\n" + val header = { + topLevelVarDeclarations.fold("")(_ + "\n") + + ifIIFE("(function(){") + "'use strict';\n" + } val footer = ifIIFE("}).call(this);\n") val outputContent = @@ -205,7 +211,6 @@ private object ClosureLinkerBackend { Function.prototype.call = function() {}; Function.prototype.apply = function() {}; function require() {} - var global = {}; var exports = {}; var NaN = 0.0/0.0, Infinity = 1.0/0.0, undefined = void 0; """ diff --git a/linker/scalajsenv.js b/linker/scalajsenv.js index ae023deac6..8034c9f7d7 100644 --- a/linker/scalajsenv.js +++ b/linker/scalajsenv.js @@ -7,16 +7,6 @@ * The top-level Scala.js environment * * ---------------------------------- */ -// Where to send exports -//!if moduleKind == CommonJSModule -const $e = exports; -//!else -// TODO Do not use global object detection, and rather export with actual `var` declarations -const $e = (typeof global === "object" && global && global["Object"] === Object) ? global : this; -// #3036 - convince GCC that $e must not be dce'ed away -this["__ScalaJSWorkaroundToRetainExportsInGCC"] = $e; -//!endif - // Linking info - must be in sync with scala.scalajs.runtime.LinkingInfo const $linkingInfo = { "semantics": { diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala index 55e5d0208c..e7a4e0980f 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala @@ -1063,15 +1063,14 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { topLevelExport match { case TopLevelJSClassExportDef(exportName) => - WithGlobals(genConstValueExportDef( - exportName, genNonNativeJSClassConstructor(tree.name.name))) + genConstValueExportDef( + exportName, genNonNativeJSClassConstructor(tree.name.name)) case TopLevelModuleExportDef(exportName) => - WithGlobals(genConstValueExportDef( - exportName, genLoadModule(tree.name.name))) + genConstValueExportDef(exportName, genLoadModule(tree.name.name)) case e: TopLevelMethodExportDef => genTopLevelMethodExportDef(tree, e) case e: TopLevelFieldExportDef => - WithGlobals(genTopLevelFieldExportDef(tree, e)) + genTopLevelFieldExportDef(tree, e) } } @@ -1091,47 +1090,77 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { val methodDefWithGlobals = desugarToFunction(cd.encodedName, args, body, resultType) - for (methodDef <- methodDefWithGlobals) yield { + methodDefWithGlobals.flatMap { methodDef => genConstValueExportDef(exportName, methodDef) } } private def genConstValueExportDef(exportName: String, exportedValue: js.Tree)( - implicit pos: Position): js.Tree = { - js.Assign(genBracketSelect(envField("e"), js.StringLiteral(exportName)), - exportedValue) + implicit pos: Position): WithGlobals[js.Tree] = { + moduleKind match { + case ModuleKind.NoModule => + genAssignToNoModuleExportVar(exportName, exportedValue) + + case ModuleKind.CommonJSModule => + val exportsVarRef = js.VarRef(js.Ident("exports")) + WithGlobals(js.Assign( + genBracketSelect(exportsVarRef, js.StringLiteral(exportName)), + exportedValue)) + } + } + + private def genAssignToNoModuleExportVar(exportName: String, rhs: js.Tree)( + implicit pos: Position): WithGlobals[js.Tree] = { + val dangerousGlobalRefs: Set[String] = + if (GlobalRefUtils.isDangerousGlobalRef(exportName)) Set(exportName) + else Set.empty + WithGlobals( + js.Assign(js.VarRef(js.Ident(exportName)), rhs), + dangerousGlobalRefs) } private def genTopLevelFieldExportDef(cd: LinkedClass, tree: TopLevelFieldExportDef)( - implicit globalKnowledge: GlobalKnowledge): js.Tree = { + implicit globalKnowledge: GlobalKnowledge): WithGlobals[js.Tree] = { import TreeDSL._ val TopLevelFieldExportDef(exportName, field) = tree implicit val pos = tree.pos - // defineProperty method - val defProp = - genIdentBracketSelect(js.VarRef(js.Ident("Object")), "defineProperty") + moduleKind match { + case ModuleKind.NoModule => + /* Initial value of the export. Updates are taken care of explicitly + * when we assign to the static field. + */ + genAssignToNoModuleExportVar(exportName, + genSelectStatic(cd.encodedName, field)) - // optional getter definition - val getterDef = { - js.StringLiteral("get") -> js.Function(arrow = false, Nil, { - js.Return(genSelectStatic(cd.encodedName, field)) - }) - } + case ModuleKind.CommonJSModule => + // defineProperty method + val defProp = + genIdentBracketSelect(js.VarRef(js.Ident("Object")), "defineProperty") - // Options passed to the defineProperty method - val descriptor = js.ObjectConstr( - getterDef :: - (js.StringLiteral("configurable") -> js.BooleanLiteral(true)) :: - Nil - ) + val exportsVarRef = js.VarRef(js.Ident("exports")) + + // optional getter definition + val getterDef = { + js.StringLiteral("get") -> js.Function(arrow = false, Nil, { + js.Return(genSelectStatic(cd.encodedName, field)) + }) + } - js.Apply(defProp, - envField("e") :: js.StringLiteral(exportName) :: descriptor :: Nil) + // Options passed to the defineProperty method + val descriptor = js.ObjectConstr( + getterDef :: + (js.StringLiteral("configurable") -> js.BooleanLiteral(true)) :: + Nil + ) + + WithGlobals(js.Apply(defProp, + exportsVarRef :: js.StringLiteral(exportName) :: descriptor :: Nil)) + } } // Helpers diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala index d60ba5b704..80abdd9a91 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala @@ -40,7 +40,7 @@ final class Emitter private (config: CommonPhaseConfig, this(config, InternalOptions()) } - private val knowledgeGuardian = new KnowledgeGuardian + private val knowledgeGuardian = new KnowledgeGuardian(config) private val baseCoreJSLib = CoreJSLibs.lib(semantics, esFeatures, moduleKind) @@ -104,6 +104,8 @@ final class Emitter private (config: CommonPhaseConfig, def emitAll(unit: LinkingUnit, builder: JSLineBuilder, logger: Logger): Unit = { emitInternal(unit, builder, logger) { + topLevelVarDeclarations(unit).foreach(builder.addLine(_)) + if (needsIIFEWrapper) builder.addLine("(function(){") @@ -115,13 +117,34 @@ final class Emitter private (config: CommonPhaseConfig, } /** Emits everything but the core JS lib to the builder, and returns the - * core JS lib. + * top-level var declarations. * * This is special for the Closure back-end. */ private[backend] def emitForClosure(unit: LinkingUnit, builder: JSBuilder, - logger: Logger): Unit = { + logger: Logger): Option[String] = { emitInternal(unit, builder, logger)(())(()) + topLevelVarDeclarations(unit) + } + + private def topLevelVarDeclarations(unit: LinkingUnit): Option[String] = { + moduleKind match { + case ModuleKind.NoModule => + val topLevelExportNames = mutable.Set.empty[String] + for { + classDef <- unit.classDefs + export <- classDef.topLevelExports + } { + topLevelExportNames += export.value.topLevelExportName + } + if (topLevelExportNames.isEmpty) + None + else + Some(topLevelExportNames.mkString("var ", ", ", ";")) + + case ModuleKind.CommonJSModule => + None + } } private def emitInternal(unit: LinkingUnit, builder: JSBuilder, diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala index 8485de809e..298126b7ab 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala @@ -1363,8 +1363,20 @@ private[emitter] class FunctionEmitter(jsGen: JSGen) { }) case _ => - js.Assign(transformExpr(lhs, preserveChar = true), + val base = js.Assign(transformExpr(lhs, preserveChar = true), transformExpr(rhs, lhs.tpe)) + lhs match { + case SelectStatic(ClassType(className), Ident(field, _)) + if moduleKind == ModuleKind.NoModule => + val mirrors = + globalKnowledge.getStaticFieldMirrors(className, field) + mirrors.foldLeft(base) { (prev, mirror) => + referenceGlobalName(mirror) + js.Assign(js.VarRef(js.Ident(mirror)), prev) + } + case _ => + base + } } } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/GlobalKnowledge.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/GlobalKnowledge.scala index 08204f3a03..112d675dfb 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/GlobalKnowledge.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/GlobalKnowledge.scala @@ -12,7 +12,7 @@ package org.scalajs.linker.backend.emitter -import org.scalajs.ir.Trees.{FieldDef, JSNativeLoadSpec} +import org.scalajs.ir.Trees.{FieldDef, Ident, JSNativeLoadSpec} import org.scalajs.ir.Types.Type private[emitter] trait GlobalKnowledge { @@ -70,4 +70,7 @@ private[emitter] trait GlobalKnowledge { * JS class. */ def getJSClassFieldDefs(className: String): List[FieldDef] + + /** The global variables that mirror a given static field. */ + def getStaticFieldMirrors(className: String, field: String): List[String] } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/KnowledgeGuardian.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/KnowledgeGuardian.scala index ab3861d75f..fc6fb67e77 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/KnowledgeGuardian.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/KnowledgeGuardian.scala @@ -21,7 +21,7 @@ import org.scalajs.ir.Types.Type import org.scalajs.linker._ import org.scalajs.linker.standard._ -private[emitter] final class KnowledgeGuardian { +private[emitter] final class KnowledgeGuardian(config: CommonPhaseConfig) { import KnowledgeGuardian._ private var firstRun: Boolean = true @@ -161,6 +161,9 @@ private[emitter] final class KnowledgeGuardian { def getJSClassFieldDefs(className: String): List[FieldDef] = classes(className).askJSClassFieldDefs(this) + + def getStaticFieldMirrors(className: String, field: String): List[String] = + classes(className).askStaticFieldMirrors(this, field) } private class Class(initClass: LinkedClass, @@ -176,6 +179,7 @@ private[emitter] final class KnowledgeGuardian { private var jsNativeLoadSpec = computeJSNativeLoadSpec(initClass) private var superClass = computeSuperClass(initClass) private var fieldDefs = computeFieldDefs(initClass) + private var staticFieldMirrors = computeStaticFieldMirrors(initClass) private val isInterfaceAskers = mutable.Set.empty[Invalidatable] private val hasInlineableInitAskers = mutable.Set.empty[Invalidatable] @@ -184,6 +188,7 @@ private[emitter] final class KnowledgeGuardian { private val jsNativeLoadSpecAskers = mutable.Set.empty[Invalidatable] private val superClassAskers = mutable.Set.empty[Invalidatable] private val fieldDefsAskers = mutable.Set.empty[Invalidatable] + private val staticFieldMirrorsAskers = mutable.Set.empty[Invalidatable] def update(linkedClass: LinkedClass, newHasInlineableInit: Boolean): Unit = { isAlive = true @@ -228,6 +233,12 @@ private[emitter] final class KnowledgeGuardian { fieldDefs = newFieldDefs invalidateAskers(fieldDefsAskers) } + + val newStaticFieldMirrors = computeStaticFieldMirrors(linkedClass) + if (newStaticFieldMirrors != staticFieldMirrors) { + staticFieldMirrors = newStaticFieldMirrors + invalidateAskers(staticFieldMirrorsAskers) + } } private def computeIsInterface(linkedClass: LinkedClass): Boolean = @@ -248,6 +259,26 @@ private[emitter] final class KnowledgeGuardian { private def computeFieldDefs(linkedClass: LinkedClass): List[FieldDef] = linkedClass.fields + private def computeStaticFieldMirrors( + linkedClass: LinkedClass): Map[String, List[String]] = { + if (config.coreSpec.moduleKind != ModuleKind.NoModule || + linkedClass.topLevelExports.isEmpty) { + // Fast path + Map.empty + } else { + val result = mutable.Map.empty[String, List[String]] + for (export <- linkedClass.topLevelExports) { + export.value match { + case TopLevelFieldExportDef(exportName, Ident(fieldName, _)) => + result(fieldName) = exportName :: result.getOrElse(fieldName, Nil) + case _ => + () + } + } + result.toMap + } + } + private def invalidateAskers(askers: mutable.Set[Invalidatable]): Unit = { /* Calling `invalidateAndUnregisterFromAll()` will cause the * `Invalidatable` to call `unregister()` in this class, which will @@ -317,6 +348,13 @@ private[emitter] final class KnowledgeGuardian { fieldDefs } + def askStaticFieldMirrors(invalidatable: Invalidatable, + field: String): List[String] = { + invalidatable.registeredTo(this) + staticFieldMirrorsAskers += invalidatable + staticFieldMirrors.getOrElse(field, Nil) + } + def unregister(invalidatable: Invalidatable): Unit = { isInterfaceAskers -= invalidatable hasInlineableInitAskers -= invalidatable diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index 7d2f8172ae..75e084e09f 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -1247,6 +1247,8 @@ class ExportsTest { } @Test def top_level_export_write_val_var_causes_typeerror(): Unit = { + assumeFalse("Unchecked in Script mode", isNoModule) + assertThrows(classOf[js.JavaScriptException], { exportsNamespace.TopLevelExport_basicVal = 54 }) From 54a9e386a7ebf96af8b8d53fb8dd76107c7eb8d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 16 Nov 2018 16:48:35 +0100 Subject: [PATCH 0874/2665] Emit `let`s for top-level exports in ES 2015 `NoModule`. This is trivial to implement, but annoying to test. `ExportsTest` now duplicates every interaction with the "exports namespace", since in ES 2015 `NoModule` the only way to access the exports is as `global.TheExport`, which cannot be abstracted away. This results in quite a bit of code duplication in the tests, but it can't be helped. --- .../linker/backend/emitter/Emitter.scala | 8 +- .../testsuite/jsinterop/ExportsTest.scala | 189 +++++++++++++----- 2 files changed, 142 insertions(+), 55 deletions(-) diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala index 80abdd9a91..a7cf41788c 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala @@ -137,10 +137,12 @@ final class Emitter private (config: CommonPhaseConfig, } { topLevelExportNames += export.value.topLevelExportName } - if (topLevelExportNames.isEmpty) + if (topLevelExportNames.isEmpty) { None - else - Some(topLevelExportNames.mkString("var ", ", ", ";")) + } else { + val kw = if (esFeatures.useECMAScript2015) "let " else "var " + Some(topLevelExportNames.mkString(kw, ", ", ";")) + } case ModuleKind.CommonJSModule => None diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index 75e084e09f..7e6e87612b 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -13,7 +13,8 @@ package org.scalajs.testsuite.jsinterop import scala.scalajs.js -import js.annotation._ +import scala.scalajs.js.annotation._ +import scala.scalajs.js.Dynamic.global import org.scalajs.testsuite.utils.AssertThrows._ import org.scalajs.testsuite.utils.JSAssert._ @@ -42,7 +43,7 @@ class ExportsTest { */ val exportsNamespace: js.Dynamic = { if (Platform.isNoModule) { - org.scalajs.testsuite.utils.JSUtils.globalObject + null // need to use `global` instead } else if (Platform.isCommonJSModule) { js.Dynamic.global.exports } else { @@ -687,14 +688,18 @@ class ExportsTest { } @Test def toplevel_exports_for_objects(): Unit = { - val obj = exportsNamespace.TopLevelExportedObject + val obj = + if (isNoModule) global.TopLevelExportedObject + else exportsNamespace.TopLevelExportedObject assertJSNotUndefined(obj) assertEquals("object", js.typeOf(obj)) assertEquals("witness", obj.witness) } @Test def toplevel_exports_for_Scala_js_defined_JS_objects(): Unit = { - val obj1 = exportsNamespace.SJSDefinedTopLevelExportedObject + val obj1 = + if (isNoModule) global.SJSDefinedTopLevelExportedObject + else exportsNamespace.SJSDefinedTopLevelExportedObject assertJSNotUndefined(obj1) assertEquals("object", js.typeOf(obj1)) assertEquals("witness", obj1.witness) @@ -703,28 +708,36 @@ class ExportsTest { } @Test def toplevel_exports_for_nested_objects(): Unit = { - val obj = exportsNamespace.NestedExportedObject + val obj = + if (isNoModule) global.NestedExportedObject + else exportsNamespace.NestedExportedObject assertJSNotUndefined(obj) assertEquals("object", js.typeOf(obj)) assertSame(obj, ExportHolder.ExportedObject) } @Test def exports_for_objects_with_constant_folded_name(): Unit = { - val obj = exportsNamespace.ConstantFoldedObjectExport + val obj = + if (isNoModule) global.ConstantFoldedObjectExport + else exportsNamespace.ConstantFoldedObjectExport assertJSNotUndefined(obj) assertEquals("object", js.typeOf(obj)) assertEquals("witness", obj.witness) } @Test def exports_for_protected_objects(): Unit = { - val obj = exportsNamespace.ProtectedExportedObject + val obj = + if (isNoModule) global.ProtectedExportedObject + else exportsNamespace.ProtectedExportedObject assertJSNotUndefined(obj) assertEquals("object", js.typeOf(obj)) assertEquals("witness", obj.witness) } @Test def toplevel_exports_for_classes(): Unit = { - val constr = exportsNamespace.TopLevelExportedClass + val constr = + if (isNoModule) global.TopLevelExportedClass + else exportsNamespace.TopLevelExportedClass assertJSNotUndefined(constr) assertEquals("function", js.typeOf(constr)) val obj = js.Dynamic.newInstance(constr)(5) @@ -732,7 +745,9 @@ class ExportsTest { } @Test def toplevel_exports_for_Scala_js_defined_JS_classes(): Unit = { - val constr = exportsNamespace.SJSDefinedTopLevelExportedClass + val constr = + if (isNoModule) global.SJSDefinedTopLevelExportedClass + else exportsNamespace.SJSDefinedTopLevelExportedClass assertJSNotUndefined(constr) assertEquals("function", js.typeOf(constr)) val obj = js.Dynamic.newInstance(constr)(5) @@ -743,7 +758,9 @@ class ExportsTest { } @Test def toplevel_exports_for_nested_classes(): Unit = { - val constr = exportsNamespace.NestedExportedClass + val constr = + if (isNoModule) global.NestedExportedClass + else exportsNamespace.NestedExportedClass assertJSNotUndefined(constr) assertEquals("function", js.typeOf(constr)) val obj = js.Dynamic.newInstance(constr)() @@ -751,7 +768,9 @@ class ExportsTest { } @Test def toplevel_exports_for_nested_sjs_defined_classes(): Unit = { - val constr = exportsNamespace.NestedSJSDefinedExportedClass + val constr = + if (isNoModule) global.NestedSJSDefinedExportedClass + else exportsNamespace.NestedSJSDefinedExportedClass assertJSNotUndefined(constr) assertEquals("function", js.typeOf(constr)) val obj = js.Dynamic.newInstance(constr)() @@ -759,7 +778,9 @@ class ExportsTest { } @Test def exports_for_classes_with_constant_folded_name(): Unit = { - val constr = exportsNamespace.ConstantFoldedClassExport + val constr = + if (isNoModule) global.ConstantFoldedClassExport + else exportsNamespace.ConstantFoldedClassExport assertJSNotUndefined(constr) assertEquals("function", js.typeOf(constr)) val obj = js.Dynamic.newInstance(constr)(5) @@ -767,7 +788,9 @@ class ExportsTest { } @Test def exports_for_protected_classes(): Unit = { - val constr = exportsNamespace.ProtectedExportedClass + val constr = + if (isNoModule) global.ProtectedExportedClass + else exportsNamespace.ProtectedExportedClass assertJSNotUndefined(constr) assertEquals("function", js.typeOf(constr)) val obj = js.Dynamic.newInstance(constr)(5) @@ -775,7 +798,9 @@ class ExportsTest { } @Test def export_for_classes_with_repeated_parameters_in_ctor(): Unit = { - val constr = exportsNamespace.ExportedVarArgClass + val constr = + if (isNoModule) global.ExportedVarArgClass + else exportsNamespace.ExportedVarArgClass assertEquals("", js.Dynamic.newInstance(constr)().result) assertEquals("a", js.Dynamic.newInstance(constr)("a").result) assertEquals("a|b", js.Dynamic.newInstance(constr)("a", "b").result) @@ -784,7 +809,9 @@ class ExportsTest { } @Test def export_for_classes_with_default_parameters_in_ctor(): Unit = { - val constr = exportsNamespace.ExportedDefaultArgClass + val constr = + if (isNoModule) global.ExportedDefaultArgClass + else exportsNamespace.ExportedDefaultArgClass assertEquals(6, js.Dynamic.newInstance(constr)(1,2,3).result) assertEquals(106, js.Dynamic.newInstance(constr)(1).result) assertEquals(103, js.Dynamic.newInstance(constr)(1,2).result) @@ -1188,59 +1215,108 @@ class ExportsTest { // @JSExportTopLevel @Test def basic_top_level_export(): Unit = { - assertEquals(1, exportsNamespace.TopLevelExport_basic()) + if (isNoModule) { + assertEquals(1, global.TopLevelExport_basic()) + } else { + assertEquals(1, exportsNamespace.TopLevelExport_basic()) + } } @Test def overloaded_top_level_export(): Unit = { - assertEquals("Hello World", exportsNamespace.TopLevelExport_overload("World")) - assertEquals(2, exportsNamespace.TopLevelExport_overload(2)) - assertEquals(9, exportsNamespace.TopLevelExport_overload(2, 7)) - assertEquals(10, exportsNamespace.TopLevelExport_overload(1, 2, 3, 4)) + if (isNoModule) { + assertEquals("Hello World", global.TopLevelExport_overload("World")) + assertEquals(2, global.TopLevelExport_overload(2)) + assertEquals(9, global.TopLevelExport_overload(2, 7)) + assertEquals(10, global.TopLevelExport_overload(1, 2, 3, 4)) + } else { + assertEquals("Hello World", exportsNamespace.TopLevelExport_overload("World")) + assertEquals(2, exportsNamespace.TopLevelExport_overload(2)) + assertEquals(9, exportsNamespace.TopLevelExport_overload(2, 7)) + assertEquals(10, exportsNamespace.TopLevelExport_overload(1, 2, 3, 4)) + } } @Test def top_level_export_uses_unique_object(): Unit = { - exportsNamespace.TopLevelExport_set(3) - assertEquals(3, TopLevelExports.myVar) - exportsNamespace.TopLevelExport_set(7) - assertEquals(7, TopLevelExports.myVar) + if (isNoModule) { + global.TopLevelExport_set(3) + assertEquals(3, TopLevelExports.myVar) + global.TopLevelExport_set(7) + assertEquals(7, TopLevelExports.myVar) + } else { + exportsNamespace.TopLevelExport_set(3) + assertEquals(3, TopLevelExports.myVar) + exportsNamespace.TopLevelExport_set(7) + assertEquals(7, TopLevelExports.myVar) + } } @Test def top_level_export_from_nested_object(): Unit = { - exportsNamespace.TopLevelExport_setNested(28) + if (isNoModule) + global.TopLevelExport_setNested(28) + else + exportsNamespace.TopLevelExport_setNested(28) assertEquals(28, TopLevelExports.Nested.myVar) } @Test def top_level_export_is_always_reachable(): Unit = { - assertEquals("Hello World", exportsNamespace.TopLevelExport_reachability()) + if (isNoModule) { + assertEquals("Hello World", global.TopLevelExport_reachability()) + } else { + assertEquals("Hello World", exportsNamespace.TopLevelExport_reachability()) + } } // @JSExportTopLevel fields @Test def top_level_export_basic_field(): Unit = { - // Initialization - assertEquals(5, exportsNamespace.TopLevelExport_basicVal) - assertEquals("hello", exportsNamespace.TopLevelExport_basicVar) - - // Scala modifies var - TopLevelFieldExports.basicVar = "modified" - assertEquals("modified", TopLevelFieldExports.basicVar) - assertEquals("modified", exportsNamespace.TopLevelExport_basicVar) + if (isNoModule) { + // Initialization + assertEquals(5, global.TopLevelExport_basicVal) + assertEquals("hello", global.TopLevelExport_basicVar) + + // Scala modifies var + TopLevelFieldExports.basicVar = "modified" + assertEquals("modified", TopLevelFieldExports.basicVar) + assertEquals("modified", global.TopLevelExport_basicVar) + } else { + // Initialization + assertEquals(5, exportsNamespace.TopLevelExport_basicVal) + assertEquals("hello", exportsNamespace.TopLevelExport_basicVar) + + // Scala modifies var + TopLevelFieldExports.basicVar = "modified" + assertEquals("modified", TopLevelFieldExports.basicVar) + assertEquals("modified", exportsNamespace.TopLevelExport_basicVar) + } // Reset var TopLevelFieldExports.basicVar = "hello" } @Test def top_level_export_field_twice(): Unit = { - // Initialization - assertEquals(5, exportsNamespace.TopLevelExport_valExportedTwice1) - assertEquals("hello", exportsNamespace.TopLevelExport_varExportedTwice1) - assertEquals("hello", exportsNamespace.TopLevelExport_varExportedTwice2) - - // Scala modifies var - TopLevelFieldExports.varExportedTwice = "modified" - assertEquals("modified", TopLevelFieldExports.varExportedTwice) - assertEquals("modified", exportsNamespace.TopLevelExport_varExportedTwice1) - assertEquals("modified", exportsNamespace.TopLevelExport_varExportedTwice2) + if (isNoModule) { + // Initialization + assertEquals(5, global.TopLevelExport_valExportedTwice1) + assertEquals("hello", global.TopLevelExport_varExportedTwice1) + assertEquals("hello", global.TopLevelExport_varExportedTwice2) + + // Scala modifies var + TopLevelFieldExports.varExportedTwice = "modified" + assertEquals("modified", TopLevelFieldExports.varExportedTwice) + assertEquals("modified", global.TopLevelExport_varExportedTwice1) + assertEquals("modified", global.TopLevelExport_varExportedTwice2) + } else { + // Initialization + assertEquals(5, exportsNamespace.TopLevelExport_valExportedTwice1) + assertEquals("hello", exportsNamespace.TopLevelExport_varExportedTwice1) + assertEquals("hello", exportsNamespace.TopLevelExport_varExportedTwice2) + + // Scala modifies var + TopLevelFieldExports.varExportedTwice = "modified" + assertEquals("modified", TopLevelFieldExports.varExportedTwice) + assertEquals("modified", exportsNamespace.TopLevelExport_varExportedTwice1) + assertEquals("modified", exportsNamespace.TopLevelExport_varExportedTwice2) + } // Reset var TopLevelFieldExports.varExportedTwice = "hello" @@ -1260,20 +1336,29 @@ class ExportsTest { @Test def top_level_export_uninitialized_fields(): Unit = { assertEquals(0, TopLevelFieldExports.uninitializedVarInt) - assertEquals(null, exportsNamespace.TopLevelExport_uninitializedVarInt) - assertEquals(0L, TopLevelFieldExports.uninitializedVarLong) - assertEquals(null, exportsNamespace.TopLevelExport_uninitializedVarLong) - assertEquals(null, TopLevelFieldExports.uninitializedVarString) - assertEquals(null, exportsNamespace.TopLevelExport_uninitializedVarString) - assertEquals('\u0000', TopLevelFieldExports.uninitializedVarChar) - assertEquals(null, exportsNamespace.TopLevelExport_uninitializedVarChar) + + if (isNoModule) { + assertEquals(null, global.TopLevelExport_uninitializedVarInt) + assertEquals(null, global.TopLevelExport_uninitializedVarLong) + assertEquals(null, global.TopLevelExport_uninitializedVarString) + assertEquals(null, global.TopLevelExport_uninitializedVarChar) + } else { + assertEquals(null, exportsNamespace.TopLevelExport_uninitializedVarInt) + assertEquals(null, exportsNamespace.TopLevelExport_uninitializedVarLong) + assertEquals(null, exportsNamespace.TopLevelExport_uninitializedVarString) + assertEquals(null, exportsNamespace.TopLevelExport_uninitializedVarChar) + } } @Test def top_level_export_field_is_always_reachable_and_initialized(): Unit = { - assertEquals("Hello World", exportsNamespace.TopLevelExport_fieldreachability) + if (isNoModule) { + assertEquals("Hello World", global.TopLevelExport_fieldreachability) + } else { + assertEquals("Hello World", exportsNamespace.TopLevelExport_fieldreachability) + } } } From 4fffdf61e23916fe17630e826ce55325b9bf6c0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 25 Oct 2018 14:49:50 +0200 Subject: [PATCH 0875/2665] Fix #2175: Add support for ECMAScript 2015 modules. This is a port of b744d12e0c6d8af74960e0ce5071c8e0011249a5. This commit adds a third `ModuleKind` for ES modules, namely `ModuleKind.ESModule`. When emitting an ES module, `@JSImport`s and `@JSExportTopLevel`s straightforwardly map to ES `import` and `export` clauses, respectively. At the moment, imports are always implemented using a namespace import, then selecting fields inside the namespace. This is suboptimal because it can prevent advanced DCE across ES modules. Improving on this is left for future work. A new `Input.ESModulesToLoad` instructs a JSEnv to load files as ES modules. The Node.js-based environment, however, will only *actually* interpret the files as ES modules if their name ends with `.mjs`. This happens because of how Node.js itself identifies ES modules as of version 10.x, although it is still experimental, so that could change in the future. `.js` files will be loaded as CommonJS modules instead. Although setting `scalaJSLinkerConfig.moduleKind` to `ModuleKind.ESModule` is enough for the Scala.js linker to emit a valid ES module, two additional settings are required to *run* or *test* using Node.js: artifactPath in (proj, Compile, fastOptJS) := (crossTarget in (proj, Compile)).value / "somename.mjs" jsEnv := { new org.scalajs.jsenv.NodeJSEnv( org.scalajs.jsenv.NODEJSEnv.Config() .withArguments(List("--experimental-modules")) ) } The first setting is necessary to give the `.mjs` extension to the file produced by Scala.js, which in turn is necessary for Node.js to accept it as an ES module. The second setting will be necessary until Node.js declares its support for ES module as non-experimental. The version of the Closure Compiler that we use does not support ES modules yet, so we deactivate GCC when emitting an ES module. At this point, the emission of ES modules can be considered stable, but the support in `NodeJSEnv` is experimental (since the support of ES modules in Node.js is itself experimental). Running the full test suite with ES modules requires Node.js 10.2.0 or later. It has been tested with v10.12.0. --- Jenkinsfile | 36 ++++++ .../main/scala/org/scalajs/jsenv/Input.scala | 10 ++ .../closure/ClosureLinkerBackend.scala | 11 +- .../scala/org/scalajs/linker/ModuleKind.scala | 8 ++ .../linker/backend/emitter/ClassEmitter.scala | 14 ++- .../linker/backend/emitter/Emitter.scala | 67 ++++++----- .../linker/backend/emitter/JSGen.scala | 8 +- .../linker/backend/javascript/Printers.scala | 46 ++++++++ .../linker/backend/javascript/Trees.scala | 108 ++++++++++++++++++ .../org/scalajs/jsenv/nodejs/NodeJSEnv.scala | 42 ++++++- project/Build.scala | 68 +++++++++++ .../sbtplugin/ScalaJSPluginInternal.scala | 8 +- .../scalajs/testsuite/utils/Platform.scala | 1 + .../testsuite/jsinterop/ModulesTest.scala | 4 +- .../testsuite/javalib/lang/SystemJSTest.scala | 6 +- .../testsuite/jsinterop/ExportsTest.scala | 45 ++++++-- .../ModulesWithGlobalFallbackTest.scala | 4 +- 17 files changed, 431 insertions(+), 55 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index c36c925825..6c63166d0a 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -112,6 +112,18 @@ def Tasks = [ 'set scalaJSLinkerConfig in helloworld ~= (_.withModuleKind(ModuleKind.CommonJSModule))' \ helloworld/run \ helloworld/clean && + sbtretry ++$scala \ + 'set artifactPath in (helloworld, Compile, fastOptJS) := (crossTarget in helloworld).value / "helloworld-fastopt.mjs"' \ + 'set jsEnv in helloworld := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withArgs(List("--experimental-modules")).withSourceMap(false))' \ + 'set scalaJSLinkerConfig in helloworld ~= (_.withModuleKind(ModuleKind.ESModule))' \ + helloworld/run && + sbtretry ++$scala \ + 'set artifactPath in (helloworld, Compile, fullOptJS) := (crossTarget in helloworld).value / "helloworld-opt.mjs"' \ + 'set jsEnv in helloworld := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withArgs(List("--experimental-modules")).withSourceMap(false))' \ + 'set scalaJSLinkerConfig in helloworld ~= (_.withModuleKind(ModuleKind.ESModule))' \ + 'set scalaJSStage in Global := FullOptStage' \ + helloworld/run \ + helloworld/clean && sbtretry ++$scala testingExample/testHtml && sbtretry 'set scalaJSStage in Global := FullOptStage' \ ++$scala testingExample/testHtml \ @@ -169,6 +181,18 @@ def Tasks = [ sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withModuleKind(ModuleKind.CommonJSModule))' \ ++$scala $testSuite/test && sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withModuleKind(ModuleKind.CommonJSModule))' \ + 'set scalaJSStage in Global := FullOptStage' \ + ++$scala $testSuite/test \ + $testSuite/clean && + sbtretry 'set artifactPath in ($testSuite, Test, fastOptJS) := (crossTarget in $testSuite).value / "testsuite-fastopt.mjs"' \ + 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withArgs(List("--experimental-modules")).withSourceMap(false))' \ + 'set scalaJSLinkerConfig in $testSuite ~= (_.withModuleKind(ModuleKind.ESModule))' \ + 'set MyScalaJSPlugin.wantSourceMaps in $testSuite := false' \ + ++$scala $testSuite/test && + sbtretry 'set artifactPath in ($testSuite, Test, fullOptJS) := (crossTarget in $testSuite).value / "testsuite-opt.mjs"' \ + 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withArgs(List("--experimental-modules")).withSourceMap(false))' \ + 'set scalaJSLinkerConfig in $testSuite ~= (_.withModuleKind(ModuleKind.ESModule))' \ + 'set MyScalaJSPlugin.wantSourceMaps in $testSuite := false' \ 'set scalaJSStage in Global := FullOptStage' \ ++$scala $testSuite/test ''', @@ -243,6 +267,18 @@ def Tasks = [ sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true)))' \ 'set scalaJSLinkerConfig in $testSuite ~= (_.withModuleKind(ModuleKind.CommonJSModule))' \ 'set scalaJSStage in Global := FullOptStage' \ + ++$scala $testSuite/test \ + $testSuite/clean && + sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true)))' \ + 'set artifactPath in ($testSuite, Test, fastOptJS) := (crossTarget in $testSuite).value / "testsuite-fastopt.mjs"' \ + 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withArgs(List("--experimental-modules")).withSourceMap(false))' \ + 'set scalaJSLinkerConfig in $testSuite ~= (_.withModuleKind(ModuleKind.ESModule))' \ + ++$scala $testSuite/test && + sbtretry 'set scalaJSLinkerConfig in $testSuite ~= (_.withESFeatures(_.withUseECMAScript2015(true)))' \ + 'set artifactPath in ($testSuite, Test, fullOptJS) := (crossTarget in $testSuite).value / "testsuite-opt.mjs"' \ + 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withArgs(List("--experimental-modules")).withSourceMap(false))' \ + 'set scalaJSLinkerConfig in $testSuite ~= (_.withModuleKind(ModuleKind.ESModule))' \ + 'set scalaJSStage in Global := FullOptStage' \ ++$scala $testSuite/test ''', diff --git a/js-envs/src/main/scala/org/scalajs/jsenv/Input.scala b/js-envs/src/main/scala/org/scalajs/jsenv/Input.scala index 6d6dc57920..c2805bf1c8 100644 --- a/js-envs/src/main/scala/org/scalajs/jsenv/Input.scala +++ b/js-envs/src/main/scala/org/scalajs/jsenv/Input.scala @@ -29,6 +29,16 @@ object Input { /** All files are to be loaded as scripts into the global scope in the order given. */ final case class ScriptsToLoad(scripts: List[VirtualBinaryFile]) extends Input + /** All files are to be loaded as ES modules, in the given order. + * + * Some environments may not be able to execute several ES modules in a + * deterministic order. If that is the case, they must reject an + * `ESModulesToLoad` input if the `modules` argument has more than one + * element. + */ + final case class ESModulesToLoad(modules: List[VirtualBinaryFile]) + extends Input + /** All files are to be loaded as CommonJS modules, in the given order. */ final case class CommonJSModulesToLoad(modules: List[VirtualBinaryFile]) extends Input diff --git a/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala index 9ce794fd8c..9c2d283b6d 100644 --- a/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala +++ b/linker/jvm/src/main/scala/org/scalajs/linker/backend/closure/ClosureLinkerBackend.scala @@ -44,13 +44,16 @@ final class ClosureLinkerBackend(config: LinkerBackendImpl.Config) import config.commonConfig.coreSpec._ require(!esFeatures.useECMAScript2015, - s"Cannot use features $esFeatures with the Closure Compiler" + + s"Cannot use features $esFeatures with the Closure Compiler " + "because they contain ECMAScript 2015 features") require(!esFeatures.allowBigIntsForLongs, - s"Cannot use features $esFeatures with the Closure Compiler" + + s"Cannot use features $esFeatures with the Closure Compiler " + "because they allow to use BigInts") + require(moduleKind != ModuleKind.ESModule, + s"Cannot use module kind $moduleKind with the Closure Compiler") + private[this] val emitter = { new Emitter(config.commonConfig) .withOptimizeBracketSelects(false) @@ -59,8 +62,8 @@ final class ClosureLinkerBackend(config: LinkerBackendImpl.Config) val symbolRequirements: SymbolRequirement = emitter.symbolRequirements private val needsIIFEWrapper = moduleKind match { - case ModuleKind.NoModule => true - case ModuleKind.CommonJSModule => false + case ModuleKind.NoModule => true + case ModuleKind.ESModule | ModuleKind.CommonJSModule => false } /** Emit the given [[standard.LinkingUnit LinkingUnit]] to the target output. diff --git a/linker/shared/src/main/scala/org/scalajs/linker/ModuleKind.scala b/linker/shared/src/main/scala/org/scalajs/linker/ModuleKind.scala index 802817a40b..6340144261 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/ModuleKind.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/ModuleKind.scala @@ -24,6 +24,7 @@ object ModuleKind { */ val All: List[ModuleKind] = List( NoModule, + ESModule, CommonJSModule) /** No module structure. @@ -34,6 +35,13 @@ object ModuleKind { */ case object NoModule extends ModuleKind + /** An ECMAScript 2015 module. + * + * Scala.js imports and exports directly map to `import` and `export` + * clauses in the ES module. + */ + case object ESModule extends ModuleKind + /** A CommonJS module (notably used by Node.js). * * Imported modules are fetched with `require`. Exports go to the `exports` diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala index e7a4e0980f..a28df6bcd3 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala @@ -148,8 +148,7 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { require(useClasses) val className = tree.name.name - val classIdent = - encodeClassVar(className)(tree.name.pos).asInstanceOf[js.VarRef].ident + val classIdent = encodeClassVar(className)(tree.name.pos).ident val parentVarWithGlobals = for (parentIdent <- tree.superClass) yield { implicit val pos = parentIdent.pos @@ -1102,6 +1101,12 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { case ModuleKind.NoModule => genAssignToNoModuleExportVar(exportName, exportedValue) + case ModuleKind.ESModule => + val field = envField("e", exportName) + val let = js.Let(field.ident, mutable = true, Some(exportedValue)) + val export = js.Export((field.ident -> js.ExportName(exportName)) :: Nil) + WithGlobals(js.Block(let, export)) + case ModuleKind.CommonJSModule => val exportsVarRef = js.VarRef(js.Ident("exports")) WithGlobals(js.Assign( @@ -1137,6 +1142,11 @@ private[emitter] final class ClassEmitter(jsGen: JSGen) { genAssignToNoModuleExportVar(exportName, genSelectStatic(cd.encodedName, field)) + case ModuleKind.ESModule => + val staticVarIdent = genSelectStatic(cd.encodedName, field).ident + WithGlobals( + js.Export((staticVarIdent -> js.ExportName(exportName)) :: Nil)) + case ModuleKind.CommonJSModule => // defineProperty method val defProp = diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala index a7cf41788c..b5589c47fe 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala @@ -89,8 +89,8 @@ final class Emitter private (config: CommonPhaseConfig, private val needsIIFEWrapper = { moduleKind match { - case ModuleKind.NoModule => true - case ModuleKind.CommonJSModule => false + case ModuleKind.NoModule => true + case ModuleKind.ESModule | ModuleKind.CommonJSModule => false } } @@ -144,7 +144,7 @@ final class Emitter private (config: CommonPhaseConfig, Some(topLevelExportNames.mkString(kw, ", ", ";")) } - case ModuleKind.CommonJSModule => + case ModuleKind.ESModule | ModuleKind.CommonJSModule => None } } @@ -212,6 +212,26 @@ final class Emitter private (config: CommonPhaseConfig, private def emitModuleImports(orderedClasses: List[LinkedClass], builder: JSBuilder, logger: Logger): Unit = { + + def foreachImportedModule(f: (String, Position) => Unit): Unit = { + val encounteredModuleNames = mutable.Set.empty[String] + for (classDef <- orderedClasses) { + def addModuleRef(module: String): Unit = { + if (encounteredModuleNames.add(module)) + f(module, classDef.pos) + } + classDef.jsNativeLoadSpec match { + case None => + case Some(JSNativeLoadSpec.Global(_, _)) => + case Some(JSNativeLoadSpec.Import(module, _)) => + addModuleRef(module) + case Some(JSNativeLoadSpec.ImportWithGlobalFallback( + JSNativeLoadSpec.Import(module, _), _)) => + addModuleRef(module) + } + } + } + moduleKind match { case ModuleKind.NoModule => var importsFound: Boolean = false @@ -237,32 +257,23 @@ final class Emitter private (config: CommonPhaseConfig, "(_.withModuleKind(ModuleKind.CommonJSModule))`.") } - case ModuleKind.CommonJSModule => - val encounteredModuleNames = mutable.Set.empty[String] - - for (classDef <- orderedClasses) { - def addModuleRef(module: String): Unit = { - if (encounteredModuleNames.add(module)) { - implicit val pos = classDef.pos - val rhs = js.Apply(js.VarRef(js.Ident("require")), - List(js.StringLiteral(module))) - val lhs = jsGen.envModuleField(module) - val decl = jsGen.genLet(lhs.ident, mutable = false, rhs) - builder.addJSTree(decl) - } - } - - classDef.jsNativeLoadSpec match { - case None => - case Some(JSNativeLoadSpec.Global(_, _)) => - - case Some(JSNativeLoadSpec.Import(module, _)) => - addModuleRef(module) + case ModuleKind.ESModule => + foreachImportedModule { (module, pos0) => + implicit val pos = pos0 + val from = js.StringLiteral(module) + val moduleBinding = jsGen.envModuleField(module).ident + val importStat = js.ImportNamespace(moduleBinding, from) + builder.addJSTree(importStat) + } - case Some(JSNativeLoadSpec.ImportWithGlobalFallback( - JSNativeLoadSpec.Import(module, _), _)) => - addModuleRef(module) - } + case ModuleKind.CommonJSModule => + foreachImportedModule { (module, pos0) => + implicit val pos = pos0 + val rhs = js.Apply(js.VarRef(js.Ident("require")), + List(js.StringLiteral(module))) + val lhs = jsGen.envModuleField(module) + val decl = jsGen.genLet(lhs.ident, mutable = false, rhs) + builder.addJSTree(decl) } } } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/JSGen.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/JSGen.scala index 5d18f9b06b..dd2f4512a5 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/JSGen.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/JSGen.scala @@ -96,7 +96,7 @@ private[emitter] final class JSGen(val semantics: Semantics, } def genSelectStatic(className: String, item: irt.Ident)( - implicit pos: Position): Tree = { + implicit pos: Position): VarRef = { envField("t", className + "__" + item.name) } @@ -163,7 +163,7 @@ private[emitter] final class JSGen(val semantics: Semantics, Apply(envField(helperName), args.toList) } - def encodeClassVar(className: String)(implicit pos: Position): Tree = + def encodeClassVar(className: String)(implicit pos: Position): VarRef = envField("c", className) def genLoadModule(moduleClass: String)(implicit pos: Position): Tree = { @@ -224,7 +224,7 @@ private[emitter] final class JSGen(val semantics: Semantics, case irt.JSNativeLoadSpec.Import(module, path) => val moduleValue = envModuleField(module) path match { - case DefaultExportName :: rest => + case DefaultExportName :: rest if moduleKind == ModuleKind.CommonJSModule => val defaultField = genCallHelper("moduleDefault", moduleValue) WithGlobals(pathSelection(defaultField, rest)) case _ => @@ -235,7 +235,7 @@ private[emitter] final class JSGen(val semantics: Semantics, moduleKind match { case ModuleKind.NoModule => genLoadJSFromSpec(globalSpec, keepOnlyDangerousVarNames) - case ModuleKind.CommonJSModule => + case ModuleKind.ESModule | ModuleKind.CommonJSModule => genLoadJSFromSpec(importSpec, keepOnlyDangerousVarNames) } } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/Printers.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/Printers.scala index 02d262c4b3..e4c37370f1 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/Printers.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/Printers.scala @@ -585,6 +585,49 @@ object Printers { case Super() => print("super") + // ECMAScript 6 modules + + case Import(bindings, from) => + print("import { ") + var first = true + var rest = bindings + while (rest.nonEmpty) { + val binding = rest.head + if (first) + first = false + else + print(", ") + print(binding._1) + print(" as ") + print(binding._2) + rest = rest.tail + } + print(" } from ") + print(from: Tree) + + case ImportNamespace(binding, from) => + print("import * as ") + print(binding) + print(" from ") + print(from: Tree) + + case Export(bindings) => + print("export { ") + var first = true + var rest = bindings + while (rest.nonEmpty) { + val binding = rest.head + if (first) + first = false + else + print(", ") + print(binding._1) + print(" as ") + print(binding._2) + rest = rest.tail + } + print(" }") + case _ => print(s"") } @@ -606,6 +649,9 @@ object Printers { print("]") } + protected def print(exportName: ExportName): Unit = + printEscapeJS(exportName.name) + protected def print(s: String): Unit = out.write(s) diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/Trees.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/Trees.scala index fa52fbb73d..ea9aa3a3fe 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/Trees.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/javascript/Trees.scala @@ -247,4 +247,112 @@ object Trees { body: Tree)(implicit val pos: Position) extends Tree case class Super()(implicit val pos: Position) extends Tree + + // ECMAScript 6 modules + + /** The name of an ES module export. + * + * It must be a valid `IdentifierName`, as tested by + * [[ExportName.isValidExportName]]. + */ + case class ExportName(name: String)(implicit val pos: Position) { + require(ExportName.isValidExportName(name), + s"'$name' is not a valid export name") + } + + object ExportName { + /** Tests whether a string is a valid export name. + * + * A string is a valid export name if and only if it is a valid ECMAScript + * `IdentifierName`, which is defined in + * [[http://www.ecma-international.org/ecma-262/6.0/#sec-names-and-keywords + * Section 11.6 of the ECMAScript 2015 specification]]. + * + * Currently, this implementation is buggy in some corner cases, as it does + * not accept code points with the Unicode properties `Other_ID_Start` and + * `Other_ID_Continue`. For example, + * `isValidIdentifierName(0x2118.toChar.toString)` will return `false` + * instead of `true`. + * + * In theory, it does not really account for code points with the Unicode + * properties `Pattern_Syntax` and `Pattern_White_Space`, which should be + * rejected. However, with the current version of Unicode (9.0.0), there + * seems to be no such character that would be accepted by this method. + */ + final def isValidExportName(name: String): Boolean = { + // scalastyle:off return + import java.lang.Character._ + + def isJSIdentifierStart(cp: Int): Boolean = + isUnicodeIdentifierStart(cp) || cp == '$' || cp == '_' + + def isJSIdentifierPart(cp: Int): Boolean = { + val ZWNJ = 0x200c + val ZWJ = 0x200d + isUnicodeIdentifierPart(cp) || cp == '$' || cp == '_' || cp == ZWNJ || cp == ZWJ + } + + if (name.isEmpty) + return false + + val firstCP = name.codePointAt(0) + if (!isJSIdentifierStart(firstCP)) + return false + + var i = charCount(firstCP) + while (i < name.length) { + val cp = name.codePointAt(i) + if (!isJSIdentifierPart(cp)) + return false + i += charCount(cp) + } + + true + // scalastyle:on return + } + } + + /** `import` statement, except namespace import. + * + * This corresponds to the following syntax: + * {{{ + * import { as , ..., as } from + * }}} + * The `_1` parts of bindings are therefore the identifier names that are + * imported, as specified in `export` clauses of the module. The `_2` parts + * are the names under which they are imported in the current module. + * + * Special cases: + * - When `_1.name == _2.name`, there is shorter syntax in ES, i.e., + * `import { binding } from 'from'`. + * - When `_1.name == "default"`, it is equivalent to a default import. + */ + case class Import(bindings: List[(ExportName, Ident)], from: StringLiteral)( + implicit val pos: Position) + extends Tree + + /** Namespace `import` statement. + * + * This corresponds to the following syntax: + * {{{ + * import * as from + * }}} + */ + case class ImportNamespace(binding: Ident, from: StringLiteral)( + implicit val pos: Position) + extends Tree + + /** `export` statement. + * + * This corresponds to the following syntax: + * {{{ + * export { as , ..., as } + * }}} + * The `_1` parts of bindings are therefore the identifiers from the current + * module that are exported. The `_2` parts are the names under which they + * are exported to other modules. + */ + case class Export(bindings: List[(Ident, ExportName)])( + implicit val pos: Position) + extends Tree } diff --git a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala index 8dc65b81c1..0b1dcd7a52 100644 --- a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala +++ b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala @@ -49,7 +49,8 @@ final class NodeJSEnv(config: NodeJSEnv.Config) extends JSEnv { private def validateInput(input: Input): Unit = { input match { - case _:Input.ScriptsToLoad | _:Input.CommonJSModulesToLoad => + case _:Input.ScriptsToLoad | _:Input.ESModulesToLoad | + _:Input.CommonJSModulesToLoad => // ok case _ => throw new UnsupportedInputException(input) @@ -164,6 +165,34 @@ object NodeJSEnv { case Input.CommonJSModulesToLoad(modules) => for (module <- modules) writeRequire(module) + + case Input.ESModulesToLoad(modules) => + if (modules.nonEmpty) { + val uris = modules.map { + case module: FileVirtualBinaryFile => + module.file.toURI + case module => + tmpFile(module.path, module.inputStream).toURI + } + + val imports = uris.map { uri => + s"""import("${escapeJS(uri.toASCIIString)}")""" + } + val importChain = imports.reduceLeft { (prev, imprt) => + s"""$prev.then(_ => $imprt)""" + } + + val importerFileContent = { + s""" + |$importChain.catch(e => { + | console.error(e); + | process.exit(1); + |}); + """.stripMargin + } + val f = tmpFile("importer.js", importerFileContent) + p.println(s"""require("${escapeJS(f.getAbsolutePath)}");""") + } } } finally { p.close() @@ -192,6 +221,17 @@ object NodeJSEnv { new String(baos.toByteArray(), StandardCharsets.UTF_8) } + private def tmpFile(path: String, content: String): File = { + import java.nio.file.{Files, StandardOpenOption} + + val f = createTmpFile(path) + val contentList = new java.util.ArrayList[String]() + contentList.add(content) + Files.write(f.toPath(), contentList, StandardCharsets.UTF_8, + StandardOpenOption.TRUNCATE_EXISTING) + f + } + private def tmpFile(path: String, content: InputStream): File = { import java.nio.file.{Files, StandardCopyOption} diff --git a/project/Build.scala b/project/Build.scala index fee1774be9..f47ad0d20f 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -97,6 +97,8 @@ object MyScalaJSPlugin extends AutoPlugin { prev match { case Input.ScriptsToLoad(prevFiles) => Input.ScriptsToLoad(javaSysPropsFile :: prevFiles) + case Input.ESModulesToLoad(prevFiles) => + Input.ESModulesToLoad(javaSysPropsFile :: prevFiles) case Input.CommonJSModulesToLoad(prevFiles) => Input.CommonJSModulesToLoad(javaSysPropsFile :: prevFiles) } @@ -150,6 +152,10 @@ object Build { val bintrayProjectName = settingKey[String]( "Project name on Bintray") + val setModuleLoopbackScript = taskKey[Option[FileVirtualBinaryFile]]( + "In the test suite, under ES modules, the script that sets the " + + "loopback module namespace") + val fetchScalaSource = taskKey[File]( "Fetches the scala source for the current scala version") val shouldPartest = settingKey[Boolean]( @@ -1387,6 +1393,7 @@ object Build { val moduleKindTag = linkerConfig.moduleKind match { case ModuleKind.NoModule => "modulekind-nomodule" + case ModuleKind.ESModule => "modulekind-esmodule" case ModuleKind.CommonJSModule => "modulekind-commonjs" } @@ -1506,6 +1513,8 @@ object Build { previousInput match { case Input.ScriptsToLoad(prevFiles) => Input.ScriptsToLoad(patchFiles(prevFiles, needsGlobal = false)) + case Input.ESModulesToLoad(prevFiles) => + Input.ESModulesToLoad(patchFiles(prevFiles, needsGlobal = true)) case Input.CommonJSModulesToLoad(prevFiles) => Input.CommonJSModulesToLoad(patchFiles(prevFiles, needsGlobal = true)) } @@ -1585,6 +1594,8 @@ object Build { jsEnvInput.value match { case Input.ScriptsToLoad(prevFiles) => Input.ScriptsToLoad(f :: prevFiles) + case Input.ESModulesToLoad(prevFiles) => + Input.ESModulesToLoad(f :: prevFiles) case Input.CommonJSModulesToLoad(prevFiles) => Input.CommonJSModulesToLoad(f :: prevFiles) } @@ -1615,6 +1626,63 @@ object Build { scalaJSLinkerConfig ~= { _.withSemantics(TestSuiteLinkerOptions.semantics _) }, scalaJSModuleInitializers in Test ++= TestSuiteLinkerOptions.moduleInitializers, + /* The script that calls setExportsNamespaceForExportsTest to provide + * ExportsTest with a loopback reference to its own exports namespace. + * Only when using an ES module. + * See the comment in ExportsTest for more details. + */ + setModuleLoopbackScript in Test := Def.settingDyn[Task[Option[FileVirtualBinaryFile]]] { + (scalaJSLinkerConfig in Test).value.moduleKind match { + case ModuleKind.ESModule => + Def.task { + val linkedFile = (scalaJSLinkedFile in Test).value.data + val uri = linkedFile.toURI.toASCIIString + + val ext = { + val name = linkedFile.getName + val dotPos = name.lastIndexOf('.') + if (dotPos < 0) ".js" else name.substring(dotPos) + } + + val setNamespaceScriptFile = + crossTarget.value / (linkedFile.getName + "-loopback" + ext) + + /* Due to the asynchronous nature of ES module loading, there + * exists a theoretical risk for a race condition here. It is + * possible that tests will start running and reaching the + * ExportsTest before this module is executed. It's quite + * unlikely, though, given all the message passing for the com + * and all that. + */ + IO.write(setNamespaceScriptFile, + s""" + |import * as mod from "${escapeJS(uri)}"; + |mod.setExportsNamespaceForExportsTest(mod); + """.stripMargin) + + Some(new FileVirtualBinaryFile(setNamespaceScriptFile)) + } + + case _ => + Def.task { + None + } + } + }.value, + + jsEnvInput in Test := { + val prev = (jsEnvInput in Test).value + val loopbackScript = (setModuleLoopbackScript in Test).value + + loopbackScript match { + case None => + prev + case Some(script) => + val Input.ESModulesToLoad(modules) = prev + Input.ESModulesToLoad(modules :+ script) + } + }, + /* Generate a scala source file that throws exceptions in * various places (while attaching the source line to the * exception). When we catch the exception, we can then diff --git a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala index 0a9aedc964..e5b4f3b333 100644 --- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala @@ -288,9 +288,13 @@ private[sbtplugin] object ScalaJSPluginInternal { ((moduleName in fullOptJS).value + "-opt.js")), scalaJSLinkerConfig in fullOptJS ~= { prevConfig => + val useClosure = { + !prevConfig.esFeatures.useECMAScript2015 && + prevConfig.moduleKind != ModuleKind.ESModule + } prevConfig .withSemantics(_.optimized) - .withClosureCompiler(!prevConfig.esFeatures.useECMAScript2015) + .withClosureCompiler(useClosure) }, scalaJSLinkedFile := Def.settingDyn { @@ -311,6 +315,8 @@ private[sbtplugin] object ScalaJSPluginInternal { scalaJSLinkerConfig.value.moduleKind match { case ModuleKind.NoModule => Input.ScriptsToLoad(List(linkedFile)) + case ModuleKind.ESModule => + Input.ESModulesToLoad(List(linkedFile)) case ModuleKind.CommonJSModule => Input.CommonJSModulesToLoad(List(linkedFile)) } diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala index 5da531c477..9ce136476c 100644 --- a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala +++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/Platform.scala @@ -60,6 +60,7 @@ object Platform { def hasStrictFloats: Boolean = sysProp("strict-floats") def isNoModule: Boolean = sysProp("modulekind-nomodule") + def isESModule: Boolean = sysProp("modulekind-esmodule") def isCommonJSModule: Boolean = sysProp("modulekind-commonjs") private def sysProp(key: String): Boolean = diff --git a/test-suite/js/src/test/require-modules/org/scalajs/testsuite/jsinterop/ModulesTest.scala b/test-suite/js/src/test/require-modules/org/scalajs/testsuite/jsinterop/ModulesTest.scala index 5228edbcfc..19d3f2c469 100644 --- a/test-suite/js/src/test/require-modules/org/scalajs/testsuite/jsinterop/ModulesTest.scala +++ b/test-suite/js/src/test/require-modules/org/scalajs/testsuite/jsinterop/ModulesTest.scala @@ -26,7 +26,7 @@ class ModulesTest { @Test def testImportModuleItself(): Unit = { val qs = QueryString - assertTrue(qs.isInstanceOf[js.Object]) + assertEquals("object", js.typeOf(qs)) val dict = js.Dictionary("foo" -> "bar", "baz" -> "qux") @@ -42,7 +42,7 @@ class ModulesTest { @Test def testImportLegacyModuleItselfAsDefault(): Unit = { val qs = QueryStringAsDefault - assertTrue(qs.isInstanceOf[js.Object]) + assertEquals("object", js.typeOf(qs)) val dict = js.Dictionary("foo" -> "bar", "baz" -> "qux") diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala index b6c876667a..91f53e3f48 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/javalib/lang/SystemJSTest.scala @@ -69,6 +69,8 @@ class SystemJSTest { @Test def systemProperties(): Unit = { def get(key: String): String = java.lang.System.getProperty(key) + def trueCount(xs: Boolean*): Int = xs.count(identity) + // Defined in System.scala assertEquals("1.8", get("java.version")) @@ -133,9 +135,11 @@ class SystemJSTest { assertEquals(isInFullOpt, Platform.isInFullOpt) val isNoModule = get("scalajs.modulekind-nomodule") == "true" + val isESModule = get("scalajs.modulekind-esmodule") == "true" val isCommonJSModule = get("scalajs.modulekind-commonjs") == "true" assertEquals(isNoModule, Platform.isNoModule) + assertEquals(isESModule, Platform.isESModule) assertEquals(isCommonJSModule, Platform.isCommonJSModule) - assertTrue(isNoModule ^ isCommonJSModule) + assertEquals(1, trueCount(isNoModule, isESModule, isCommonJSModule)) } } diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala index 7e6e87612b..62c5f551c1 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ExportsTest.scala @@ -29,9 +29,23 @@ import org.junit.Test import org.scalajs.testsuite.utils.{JSUtils, Platform} import org.scalajs.testsuite.utils.AssertThrows.assertThrows -class ExportsTest { +object ExportsTest { + /* When using ES modules, there is no way to get hold of our own exports + * namespace from within. The build instead sets up a small script that will + * import our module and call `setExportsNamespaceForExportsTest` with our + * module namespace. + */ + + private[this] var explicitlySetExportsNamespace: Option[js.Dynamic] = None + + @JSExportTopLevel("setExportsNamespaceForExportsTest") + def setExportsNamespaceForExportsTest(value: js.Dynamic): Unit = + explicitlySetExportsNamespace = Some(value) /** The namespace in which top-level exports are stored. + * + * If it has been explicitly set, which is the case for `ESModule`, take + * that value. * * If we are linking the test suite in `NoModule`, then exports are in the * global object (technically they're in the global scope, but at least so @@ -41,17 +55,28 @@ class ExportsTest { * module-global variable, which we can retrieve as if it were in the global * scope. */ - val exportsNamespace: js.Dynamic = { - if (Platform.isNoModule) { - null // need to use `global` instead - } else if (Platform.isCommonJSModule) { - js.Dynamic.global.exports - } else { - throw new NotImplementedError( - "Don't know how to fetch the exports namespace in an unknown " + - "module kind.") + def exportsNameSpace: js.Dynamic = { + explicitlySetExportsNamespace.getOrElse { + assert(!Platform.isESModule, + "The exportsNamespace should have been explicitly set for an ES " + + "module") + if (Platform.isNoModule) { + null // need to use `global` instead + } else if (Platform.isCommonJSModule) { + js.Dynamic.global.exports + } else { + throw new NotImplementedError( + "Don't know how to fetch the exports namespace in an unknown " + + "module kind.") + } } } +} + +class ExportsTest { + + /** The namespace in which top-level exports are stored. */ + val exportsNamespace = ExportsTest.exportsNameSpace // @JSExport diff --git a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala index 1f2a73da8f..b8eb5502f9 100644 --- a/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala +++ b/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ModulesWithGlobalFallbackTest.scala @@ -33,7 +33,7 @@ class ModulesWithGlobalFallbackTest { @Test def testImportModuleItself(): Unit = { val qs = QueryString - assertTrue(qs.isInstanceOf[js.Object]) + assertEquals("object", js.typeOf(qs)) val dict = js.Dictionary("foo" -> "bar", "baz" -> "qux") @@ -49,7 +49,7 @@ class ModulesWithGlobalFallbackTest { @Test def testImportLegacyModuleItselfAsDefault(): Unit = { val qs = QueryStringAsDefault - assertTrue(qs.isInstanceOf[js.Object]) + assertEquals("object", js.typeOf(qs)) val dict = js.Dictionary("foo" -> "bar", "baz" -> "qux") From 86a23e320d6dceee26f8ce32af3c0c46c3120e5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sun, 9 Dec 2018 13:01:58 +0100 Subject: [PATCH 0876/2665] Remove the hack to fix percentage signs in Node.js. Back when that hack was introduced in 1fc8d0526ba9b46049c0deefc3fe3fa93d3271b0, Node.js' `console.log` deduplicated consecutive `%` signs in its argument, even if it was a single argument. At the time we thought that was intentional, and we added our hack to have it behave in a more standard way for Scala.js. The deduplication with only 1 argument turned out to be a bug, recognized as such in https://github.com/nodejs/node/issues/3396, when it was accidentally fixed in Node.js 4. It is now the documented behavior, see https://nodejs.org/api/util.html#util_util_format_format_args which is referenced from https://nodejs.org/api/console.html#console_console_log_data_args. --- .../org/scalajs/jsenv/test/RunTests.scala | 43 +++-------------- .../org/scalajs/jsenv/nodejs/NodeJSEnv.scala | 2 +- .../org/scalajs/jsenv/nodejs/Support.scala | 47 ------------------- 3 files changed, 7 insertions(+), 85 deletions(-) delete mode 100644 nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/Support.scala diff --git a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala index eed303feef..67862a1125 100644 --- a/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala +++ b/js-envs-test-kit/src/main/scala/org/scalajs/jsenv/test/RunTests.scala @@ -95,50 +95,19 @@ private[test] class RunTests(config: JSEnvSuiteConfig, withCom: Boolean) { } } - @Test // Node.js strips double percentage signs - #500 + // #500 Node.js used to strip double percentage signs even with only 1 argument + @Test def percentageTest: Unit = { - val counts = 1 to 15 - val argcs = 1 to 3 - val strings = counts.map("%" * _) - - val strlists = for { - count <- argcs - string <- strings - } yield List.fill(count)(string) - - val codes = for { - strlist <- strlists - } yield { - val args = strlist.map(s => s""""$s"""").mkString(", ") - s"console.log($args);\n" - } + val strings = (1 to 15).map("%" * _) + val code = strings.map(str => s"""console.log("$str");\n""").mkString("") + val result = strings.mkString("", "\n", "\n") - val result = strlists.map(_.mkString(" ") + "\n").mkString("") - - withRun(codes.mkString("")) { + withRun(code) { _.expectOut(result) .closeRun() } } - @Test // Node.js console.log hack didn't allow to log non-Strings - #561 - def nonStringTest: Unit = { - withRun(""" - console.log(1); - console.log(undefined); - console.log(null); - console.log({}); - console.log([1,2]); - """) { - _.expectOut("1\n") - .expectOut("undefined\n") - .expectOut("null\n") - .expectOut("[object Object]\n") - .expectOut("1,2\n") - .closeRun() - } - } - @Test def fastCloseTest: Unit = { /* This test also tests a failure mode where the ExternalJSRun is still diff --git a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala index 0b1dcd7a52..c869504e45 100644 --- a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala +++ b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala @@ -68,7 +68,7 @@ final class NodeJSEnv(config: NodeJSEnv.Config) extends JSEnv { } private def initFiles: List[VirtualBinaryFile] = { - val base = List(NodeJSEnv.runtimeEnv, Support.fixPercentConsole) + val base = List(NodeJSEnv.runtimeEnv) config.sourceMap match { case SourceMap.Disable => base diff --git a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/Support.scala b/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/Support.scala deleted file mode 100644 index 305379a7c4..0000000000 --- a/nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/Support.scala +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Scala.js (https://www.scala-js.org/) - * - * Copyright EPFL. - * - * Licensed under Apache License 2.0 - * (https://www.apache.org/licenses/LICENSE-2.0). - * - * See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - */ - -package org.scalajs.jsenv.nodejs - -import org.scalajs.io._ - -object Support { - def fixPercentConsole: VirtualBinaryFile = { - MemVirtualBinaryFile.fromStringUTF8("nodeConsoleHack.js", - """ - |// Hack console log to duplicate double % signs - |(function() { - | function startsWithAnyOf(s, prefixes) { - | for (var i = 0; i < prefixes.length; i++) { - | // ES5 does not have .startsWith() on strings - | if (s.substring(0, prefixes[i].length) === prefixes[i]) - | return true; - | } - | return false; - | } - | var oldLog = console.log; - | var newLog = function() { - | var args = arguments; - | if (args.length >= 1 && args[0] !== void 0 && args[0] !== null) { - | var argStr = args[0].toString(); - | if (args.length > 1) - | argStr = argStr.replace(/%/g, "%%"); - | args[0] = argStr; - | } - | oldLog.apply(console, args); - | }; - | console.log = newLog; - |})(); - """.stripMargin - ) - } -} From 30fe39af55caef027185fc2e6f78be6ca9ad18e3 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 14 Dec 2018 19:19:32 +0100 Subject: [PATCH 0877/2665] Fix test selector for JUnit on JS --- .../src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala index 12d46e4227..69dca143e6 100644 --- a/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala +++ b/junit-runtime/src/main/scala/org/scalajs/junit/JUnitExecuteTest.scala @@ -161,7 +161,7 @@ final class JUnitExecuteTest(task: JUnitTask, runSettings: RunSettings, } private def emitMethodEvent(methodName: String, status: Status): Unit = { - val selector = new NestedTestSelector(task.taskDef.fullyQualifiedName, methodName) + val selector = new TestSelector(task.taskDef.fullyQualifiedName + "." + runSettings.decodeName(methodName)) eventHandler.handle(new JUnitEvent(task.taskDef, status, selector)) } From 029713690b4b5ee23d09d11c4b2c964f93080bd6 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Fri, 14 Dec 2018 19:19:17 +0100 Subject: [PATCH 0878/2665] Instead of generating expected JUnit output, record it --- junit-test/README.md | 8 + .../junit/utils/JUnitTestPlatformImpl.scala | 11 + .../junit/utils/JUnitTestPlatformImpl.scala | 11 + .../junit/AssertEquals2TestAssertions_.txt | 7 + .../junit/AssertEquals2TestAssertions_a.txt | 7 + .../junit/AssertEquals2TestAssertions_n.txt | 7 + .../junit/AssertEquals2TestAssertions_na.txt | 7 + .../junit/AssertEquals2TestAssertions_nv.txt | 7 + .../junit/AssertEquals2TestAssertions_nva.txt | 7 + .../junit/AssertEquals2TestAssertions_nvc.txt | 7 + .../AssertEquals2TestAssertions_nvca.txt | 7 + .../junit/AssertEquals2TestAssertions_q.txt | 7 + .../junit/AssertEquals2TestAssertions_v.txt | 7 + .../junit/AssertEquals2TestAssertions_va.txt | 7 + .../junit/AssertEquals2TestAssertions_vc.txt | 7 + .../junit/AssertEquals2TestAssertions_vq.txt | 7 + .../junit/AssertEquals2TestAssertions_vs.txt | 7 + .../junit/AssertEquals2TestAssertions_vsn.txt | 7 + .../AssertEqualsDoubleTestAssertions_.txt | 23 + .../AssertEqualsDoubleTestAssertions_a.txt | 23 + .../AssertEqualsDoubleTestAssertions_n.txt | 23 + .../AssertEqualsDoubleTestAssertions_na.txt | 23 + .../AssertEqualsDoubleTestAssertions_nv.txt | 23 + .../AssertEqualsDoubleTestAssertions_nva.txt | 23 + .../AssertEqualsDoubleTestAssertions_nvc.txt | 23 + .../AssertEqualsDoubleTestAssertions_nvca.txt | 23 + .../AssertEqualsDoubleTestAssertions_q.txt | 23 + .../AssertEqualsDoubleTestAssertions_v.txt | 23 + .../AssertEqualsDoubleTestAssertions_va.txt | 23 + .../AssertEqualsDoubleTestAssertions_vc.txt | 23 + .../AssertEqualsDoubleTestAssertions_vq.txt | 23 + .../AssertEqualsDoubleTestAssertions_vs.txt | 23 + .../AssertEqualsDoubleTestAssertions_vsn.txt | 23 + .../junit/AssertEqualsTestAssertions_.txt | 7 + .../junit/AssertEqualsTestAssertions_a.txt | 7 + .../junit/AssertEqualsTestAssertions_n.txt | 7 + .../junit/AssertEqualsTestAssertions_na.txt | 7 + .../junit/AssertEqualsTestAssertions_nv.txt | 7 + .../junit/AssertEqualsTestAssertions_nva.txt | 7 + .../junit/AssertEqualsTestAssertions_nvc.txt | 7 + .../junit/AssertEqualsTestAssertions_nvca.txt | 7 + .../junit/AssertEqualsTestAssertions_q.txt | 7 + .../junit/AssertEqualsTestAssertions_v.txt | 7 + .../junit/AssertEqualsTestAssertions_va.txt | 7 + .../junit/AssertEqualsTestAssertions_vc.txt | 7 + .../junit/AssertEqualsTestAssertions_vq.txt | 7 + .../junit/AssertEqualsTestAssertions_vs.txt | 7 + .../junit/AssertEqualsTestAssertions_vsn.txt | 7 + .../junit/AssertFalse2TestAssertions_.txt | 7 + .../junit/AssertFalse2TestAssertions_a.txt | 7 + .../junit/AssertFalse2TestAssertions_n.txt | 7 + .../junit/AssertFalse2TestAssertions_na.txt | 7 + .../junit/AssertFalse2TestAssertions_nv.txt | 7 + .../junit/AssertFalse2TestAssertions_nva.txt | 7 + .../junit/AssertFalse2TestAssertions_nvc.txt | 7 + .../junit/AssertFalse2TestAssertions_nvca.txt | 7 + .../junit/AssertFalse2TestAssertions_q.txt | 7 + .../junit/AssertFalse2TestAssertions_v.txt | 7 + .../junit/AssertFalse2TestAssertions_va.txt | 7 + .../junit/AssertFalse2TestAssertions_vc.txt | 7 + .../junit/AssertFalse2TestAssertions_vq.txt | 7 + .../junit/AssertFalse2TestAssertions_vs.txt | 7 + .../junit/AssertFalse2TestAssertions_vsn.txt | 7 + .../junit/AssertFalseTestAssertions_.txt | 7 + .../junit/AssertFalseTestAssertions_a.txt | 7 + .../junit/AssertFalseTestAssertions_n.txt | 7 + .../junit/AssertFalseTestAssertions_na.txt | 7 + .../junit/AssertFalseTestAssertions_nv.txt | 7 + .../junit/AssertFalseTestAssertions_nva.txt | 7 + .../junit/AssertFalseTestAssertions_nvc.txt | 7 + .../junit/AssertFalseTestAssertions_nvca.txt | 7 + .../junit/AssertFalseTestAssertions_q.txt | 7 + .../junit/AssertFalseTestAssertions_v.txt | 7 + .../junit/AssertFalseTestAssertions_va.txt | 7 + .../junit/AssertFalseTestAssertions_vc.txt | 7 + .../junit/AssertFalseTestAssertions_vq.txt | 7 + .../junit/AssertFalseTestAssertions_vs.txt | 7 + .../junit/AssertFalseTestAssertions_vsn.txt | 7 + .../AssertStringEqualsTestAssertions_.txt | 7 + .../AssertStringEqualsTestAssertions_a.txt | 7 + .../AssertStringEqualsTestAssertions_n.txt | 7 + .../AssertStringEqualsTestAssertions_na.txt | 7 + .../AssertStringEqualsTestAssertions_nv.txt | 7 + .../AssertStringEqualsTestAssertions_nva.txt | 7 + .../AssertStringEqualsTestAssertions_nvc.txt | 7 + .../AssertStringEqualsTestAssertions_nvca.txt | 7 + .../AssertStringEqualsTestAssertions_q.txt | 7 + .../AssertStringEqualsTestAssertions_v.txt | 7 + .../AssertStringEqualsTestAssertions_va.txt | 7 + .../AssertStringEqualsTestAssertions_vc.txt | 7 + .../AssertStringEqualsTestAssertions_vq.txt | 7 + .../AssertStringEqualsTestAssertions_vs.txt | 7 + .../AssertStringEqualsTestAssertions_vsn.txt | 7 + .../junit/AssertTrueTestAssertions_.txt | 10 + .../junit/AssertTrueTestAssertions_a.txt | 10 + .../junit/AssertTrueTestAssertions_n.txt | 10 + .../junit/AssertTrueTestAssertions_na.txt | 10 + .../junit/AssertTrueTestAssertions_nv.txt | 10 + .../junit/AssertTrueTestAssertions_nva.txt | 10 + .../junit/AssertTrueTestAssertions_nvc.txt | 10 + .../junit/AssertTrueTestAssertions_nvca.txt | 10 + .../junit/AssertTrueTestAssertions_q.txt | 10 + .../junit/AssertTrueTestAssertions_v.txt | 10 + .../junit/AssertTrueTestAssertions_va.txt | 10 + .../junit/AssertTrueTestAssertions_vc.txt | 10 + .../junit/AssertTrueTestAssertions_vq.txt | 10 + .../junit/AssertTrueTestAssertions_vs.txt | 10 + .../junit/AssertTrueTestAssertions_vsn.txt | 10 + .../junit/AssumeAfterAssumeAssertions_.txt | 8 + .../junit/AssumeAfterAssumeAssertions_a.txt | 8 + .../junit/AssumeAfterAssumeAssertions_n.txt | 8 + .../junit/AssumeAfterAssumeAssertions_na.txt | 8 + .../junit/AssumeAfterAssumeAssertions_nv.txt | 8 + .../junit/AssumeAfterAssumeAssertions_nva.txt | 8 + .../junit/AssumeAfterAssumeAssertions_nvc.txt | 8 + .../AssumeAfterAssumeAssertions_nvca.txt | 8 + .../junit/AssumeAfterAssumeAssertions_q.txt | 8 + .../junit/AssumeAfterAssumeAssertions_v.txt | 8 + .../junit/AssumeAfterAssumeAssertions_va.txt | 8 + .../junit/AssumeAfterAssumeAssertions_vc.txt | 8 + .../junit/AssumeAfterAssumeAssertions_vq.txt | 8 + .../junit/AssumeAfterAssumeAssertions_vs.txt | 8 + .../junit/AssumeAfterAssumeAssertions_vsn.txt | 8 + .../junit/AssumeAfterExceptionAssertions_.txt | 8 + .../AssumeAfterExceptionAssertions_a.txt | 8 + .../AssumeAfterExceptionAssertions_n.txt | 8 + .../AssumeAfterExceptionAssertions_na.txt | 8 + .../AssumeAfterExceptionAssertions_nv.txt | 8 + .../AssumeAfterExceptionAssertions_nva.txt | 8 + .../AssumeAfterExceptionAssertions_nvc.txt | 8 + .../AssumeAfterExceptionAssertions_nvca.txt | 8 + .../AssumeAfterExceptionAssertions_q.txt | 8 + .../AssumeAfterExceptionAssertions_v.txt | 8 + .../AssumeAfterExceptionAssertions_va.txt | 8 + .../AssumeAfterExceptionAssertions_vc.txt | 8 + .../AssumeAfterExceptionAssertions_vq.txt | 8 + .../AssumeAfterExceptionAssertions_vs.txt | 8 + .../AssumeAfterExceptionAssertions_vsn.txt | 8 + .../junit/AssumeInAfterAssertions_.txt | 7 + .../junit/AssumeInAfterAssertions_a.txt | 7 + .../junit/AssumeInAfterAssertions_n.txt | 7 + .../junit/AssumeInAfterAssertions_na.txt | 7 + .../junit/AssumeInAfterAssertions_nv.txt | 7 + .../junit/AssumeInAfterAssertions_nva.txt | 7 + .../junit/AssumeInAfterAssertions_nvc.txt | 7 + .../junit/AssumeInAfterAssertions_nvca.txt | 7 + .../junit/AssumeInAfterAssertions_q.txt | 7 + .../junit/AssumeInAfterAssertions_v.txt | 7 + .../junit/AssumeInAfterAssertions_va.txt | 7 + .../junit/AssumeInAfterAssertions_vc.txt | 7 + .../junit/AssumeInAfterAssertions_vq.txt | 7 + .../junit/AssumeInAfterAssertions_vs.txt | 7 + .../junit/AssumeInAfterAssertions_vsn.txt | 7 + .../scalajs/junit/AssumeTestAssertions_.txt | 7 + .../scalajs/junit/AssumeTestAssertions_a.txt | 7 + .../scalajs/junit/AssumeTestAssertions_n.txt | 7 + .../scalajs/junit/AssumeTestAssertions_na.txt | 7 + .../scalajs/junit/AssumeTestAssertions_nv.txt | 7 + .../junit/AssumeTestAssertions_nva.txt | 7 + .../junit/AssumeTestAssertions_nvc.txt | 7 + .../junit/AssumeTestAssertions_nvca.txt | 7 + .../scalajs/junit/AssumeTestAssertions_q.txt | 7 + .../scalajs/junit/AssumeTestAssertions_v.txt | 7 + .../scalajs/junit/AssumeTestAssertions_va.txt | 7 + .../scalajs/junit/AssumeTestAssertions_vc.txt | 7 + .../scalajs/junit/AssumeTestAssertions_vq.txt | 7 + .../scalajs/junit/AssumeTestAssertions_vs.txt | 7 + .../junit/AssumeTestAssertions_vsn.txt | 7 + .../junit/BeforeAndAfterTestAssertions_.txt | 6 + .../junit/BeforeAndAfterTestAssertions_a.txt | 6 + .../junit/BeforeAndAfterTestAssertions_n.txt | 6 + .../junit/BeforeAndAfterTestAssertions_na.txt | 6 + .../junit/BeforeAndAfterTestAssertions_nv.txt | 6 + .../BeforeAndAfterTestAssertions_nva.txt | 6 + .../BeforeAndAfterTestAssertions_nvc.txt | 6 + .../BeforeAndAfterTestAssertions_nvca.txt | 6 + .../junit/BeforeAndAfterTestAssertions_q.txt | 6 + .../junit/BeforeAndAfterTestAssertions_v.txt | 6 + .../junit/BeforeAndAfterTestAssertions_va.txt | 6 + .../junit/BeforeAndAfterTestAssertions_vc.txt | 6 + .../junit/BeforeAndAfterTestAssertions_vq.txt | 6 + .../junit/BeforeAndAfterTestAssertions_vs.txt | 6 + .../BeforeAndAfterTestAssertions_vsn.txt | 6 + .../junit/BeforeAssumeFailTestAssertions_.txt | 5 + .../BeforeAssumeFailTestAssertions_a.txt | 5 + .../BeforeAssumeFailTestAssertions_n.txt | 5 + .../BeforeAssumeFailTestAssertions_na.txt | 5 + .../BeforeAssumeFailTestAssertions_nv.txt | 5 + .../BeforeAssumeFailTestAssertions_nva.txt | 5 + .../BeforeAssumeFailTestAssertions_nvc.txt | 5 + .../BeforeAssumeFailTestAssertions_nvca.txt | 5 + .../BeforeAssumeFailTestAssertions_q.txt | 5 + .../BeforeAssumeFailTestAssertions_v.txt | 5 + .../BeforeAssumeFailTestAssertions_va.txt | 5 + .../BeforeAssumeFailTestAssertions_vc.txt | 5 + .../BeforeAssumeFailTestAssertions_vq.txt | 5 + .../BeforeAssumeFailTestAssertions_vs.txt | 5 + .../BeforeAssumeFailTestAssertions_vsn.txt | 5 + .../junit/ExceptionAfterAssumeAssertions_.txt | 8 + .../ExceptionAfterAssumeAssertions_a.txt | 8 + .../ExceptionAfterAssumeAssertions_n.txt | 8 + .../ExceptionAfterAssumeAssertions_na.txt | 8 + .../ExceptionAfterAssumeAssertions_nv.txt | 8 + .../ExceptionAfterAssumeAssertions_nva.txt | 8 + .../ExceptionAfterAssumeAssertions_nvc.txt | 8 + .../ExceptionAfterAssumeAssertions_nvca.txt | 8 + .../ExceptionAfterAssumeAssertions_q.txt | 8 + .../ExceptionAfterAssumeAssertions_v.txt | 8 + .../ExceptionAfterAssumeAssertions_va.txt | 8 + .../ExceptionAfterAssumeAssertions_vc.txt | 8 + .../ExceptionAfterAssumeAssertions_vq.txt | 8 + .../ExceptionAfterAssumeAssertions_vs.txt | 8 + .../ExceptionAfterAssumeAssertions_vsn.txt | 8 + .../junit/ExceptionInAfterTestAssertions_.txt | 7 + .../ExceptionInAfterTestAssertions_a.txt | 7 + .../ExceptionInAfterTestAssertions_n.txt | 7 + .../ExceptionInAfterTestAssertions_na.txt | 7 + .../ExceptionInAfterTestAssertions_nv.txt | 7 + .../ExceptionInAfterTestAssertions_nva.txt | 7 + .../ExceptionInAfterTestAssertions_nvc.txt | 7 + .../ExceptionInAfterTestAssertions_nvca.txt | 7 + .../ExceptionInAfterTestAssertions_q.txt | 7 + .../ExceptionInAfterTestAssertions_v.txt | 7 + .../ExceptionInAfterTestAssertions_va.txt | 7 + .../ExceptionInAfterTestAssertions_vc.txt | 7 + .../ExceptionInAfterTestAssertions_vq.txt | 7 + .../ExceptionInAfterTestAssertions_vs.txt | 7 + .../ExceptionInAfterTestAssertions_vsn.txt | 7 + .../ExceptionInBeforeTestAssertions_.txt | 8 + .../ExceptionInBeforeTestAssertions_a.txt | 8 + .../ExceptionInBeforeTestAssertions_n.txt | 8 + .../ExceptionInBeforeTestAssertions_na.txt | 8 + .../ExceptionInBeforeTestAssertions_nv.txt | 8 + .../ExceptionInBeforeTestAssertions_nva.txt | 8 + .../ExceptionInBeforeTestAssertions_nvc.txt | 8 + .../ExceptionInBeforeTestAssertions_nvca.txt | 8 + .../ExceptionInBeforeTestAssertions_q.txt | 8 + .../ExceptionInBeforeTestAssertions_v.txt | 8 + .../ExceptionInBeforeTestAssertions_va.txt | 8 + .../ExceptionInBeforeTestAssertions_vc.txt | 8 + .../ExceptionInBeforeTestAssertions_vq.txt | 8 + .../ExceptionInBeforeTestAssertions_vs.txt | 8 + .../ExceptionInBeforeTestAssertions_vsn.txt | 8 + .../ExceptionInConstructorTestAssertions_.txt | 7 + ...ExceptionInConstructorTestAssertions_a.txt | 7 + ...ExceptionInConstructorTestAssertions_n.txt | 7 + ...xceptionInConstructorTestAssertions_na.txt | 7 + ...xceptionInConstructorTestAssertions_nv.txt | 7 + ...ceptionInConstructorTestAssertions_nva.txt | 7 + ...ceptionInConstructorTestAssertions_nvc.txt | 7 + ...eptionInConstructorTestAssertions_nvca.txt | 7 + ...ExceptionInConstructorTestAssertions_q.txt | 7 + ...ExceptionInConstructorTestAssertions_v.txt | 7 + ...xceptionInConstructorTestAssertions_va.txt | 7 + ...xceptionInConstructorTestAssertions_vc.txt | 7 + ...xceptionInConstructorTestAssertions_vq.txt | 7 + ...xceptionInConstructorTestAssertions_vs.txt | 7 + ...ceptionInConstructorTestAssertions_vsn.txt | 7 + .../junit/ExceptionTestAssertions_.txt | 7 + .../junit/ExceptionTestAssertions_a.txt | 7 + .../junit/ExceptionTestAssertions_n.txt | 7 + .../junit/ExceptionTestAssertions_na.txt | 7 + .../junit/ExceptionTestAssertions_nv.txt | 7 + .../junit/ExceptionTestAssertions_nva.txt | 7 + .../junit/ExceptionTestAssertions_nvc.txt | 7 + .../junit/ExceptionTestAssertions_nvca.txt | 7 + .../junit/ExceptionTestAssertions_q.txt | 7 + .../junit/ExceptionTestAssertions_v.txt | 7 + .../junit/ExceptionTestAssertions_va.txt | 7 + .../junit/ExceptionTestAssertions_vc.txt | 7 + .../junit/ExceptionTestAssertions_vq.txt | 7 + .../junit/ExceptionTestAssertions_vs.txt | 7 + .../junit/ExceptionTestAssertions_vsn.txt | 7 + .../scalajs/junit/ExpectTestAssertions_.txt | 22 + .../scalajs/junit/ExpectTestAssertions_a.txt | 22 + .../scalajs/junit/ExpectTestAssertions_n.txt | 22 + .../scalajs/junit/ExpectTestAssertions_na.txt | 22 + .../scalajs/junit/ExpectTestAssertions_nv.txt | 22 + .../junit/ExpectTestAssertions_nva.txt | 22 + .../junit/ExpectTestAssertions_nvc.txt | 22 + .../junit/ExpectTestAssertions_nvca.txt | 22 + .../scalajs/junit/ExpectTestAssertions_q.txt | 22 + .../scalajs/junit/ExpectTestAssertions_v.txt | 22 + .../scalajs/junit/ExpectTestAssertions_va.txt | 22 + .../scalajs/junit/ExpectTestAssertions_vc.txt | 22 + .../scalajs/junit/ExpectTestAssertions_vq.txt | 22 + .../scalajs/junit/ExpectTestAssertions_vs.txt | 22 + .../junit/ExpectTestAssertions_vsn.txt | 22 + .../scalajs/junit/IgnoreTestAssertions_.txt | 5 + .../scalajs/junit/IgnoreTestAssertions_a.txt | 5 + .../scalajs/junit/IgnoreTestAssertions_n.txt | 5 + .../scalajs/junit/IgnoreTestAssertions_na.txt | 5 + .../scalajs/junit/IgnoreTestAssertions_nv.txt | 5 + .../junit/IgnoreTestAssertions_nva.txt | 5 + .../junit/IgnoreTestAssertions_nvc.txt | 5 + .../junit/IgnoreTestAssertions_nvca.txt | 5 + .../scalajs/junit/IgnoreTestAssertions_q.txt | 5 + .../scalajs/junit/IgnoreTestAssertions_v.txt | 5 + .../scalajs/junit/IgnoreTestAssertions_va.txt | 5 + .../scalajs/junit/IgnoreTestAssertions_vc.txt | 5 + .../scalajs/junit/IgnoreTestAssertions_vq.txt | 5 + .../scalajs/junit/IgnoreTestAssertions_vs.txt | 5 + .../junit/IgnoreTestAssertions_vsn.txt | 5 + .../junit/MethodNameDecodeTestAssertions_.txt | 6 + .../MethodNameDecodeTestAssertions_a.txt | 6 + .../MethodNameDecodeTestAssertions_n.txt | 6 + .../MethodNameDecodeTestAssertions_na.txt | 6 + .../MethodNameDecodeTestAssertions_nv.txt | 6 + .../MethodNameDecodeTestAssertions_nva.txt | 6 + .../MethodNameDecodeTestAssertions_nvc.txt | 6 + .../MethodNameDecodeTestAssertions_nvca.txt | 6 + .../MethodNameDecodeTestAssertions_q.txt | 6 + .../MethodNameDecodeTestAssertions_v.txt | 6 + .../MethodNameDecodeTestAssertions_va.txt | 6 + .../MethodNameDecodeTestAssertions_vc.txt | 6 + .../MethodNameDecodeTestAssertions_vn.txt | 6 + .../MethodNameDecodeTestAssertions_vq.txt | 6 + .../MethodNameDecodeTestAssertions_vs.txt | 6 + .../MethodNameDecodeTestAssertions_vsn.txt | 6 + .../scalajs/junit/Multi1TestAssertions_.txt | 9 + .../scalajs/junit/Multi1TestAssertions_a.txt | 9 + .../scalajs/junit/Multi1TestAssertions_n.txt | 9 + .../scalajs/junit/Multi1TestAssertions_na.txt | 9 + .../scalajs/junit/Multi1TestAssertions_nv.txt | 9 + .../junit/Multi1TestAssertions_nva.txt | 9 + .../junit/Multi1TestAssertions_nvc.txt | 9 + .../junit/Multi1TestAssertions_nvca.txt | 9 + .../scalajs/junit/Multi1TestAssertions_q.txt | 9 + .../scalajs/junit/Multi1TestAssertions_v.txt | 9 + .../scalajs/junit/Multi1TestAssertions_va.txt | 9 + .../scalajs/junit/Multi1TestAssertions_vc.txt | 9 + .../scalajs/junit/Multi1TestAssertions_vq.txt | 9 + .../scalajs/junit/Multi1TestAssertions_vs.txt | 9 + .../junit/Multi1TestAssertions_vsn.txt | 9 + .../scalajs/junit/Multi2TestAssertions_.txt | 18 + .../scalajs/junit/Multi2TestAssertions_a.txt | 18 + .../scalajs/junit/Multi2TestAssertions_n.txt | 18 + .../scalajs/junit/Multi2TestAssertions_na.txt | 18 + .../scalajs/junit/Multi2TestAssertions_nv.txt | 18 + .../junit/Multi2TestAssertions_nva.txt | 18 + .../junit/Multi2TestAssertions_nvc.txt | 18 + .../junit/Multi2TestAssertions_nvca.txt | 18 + .../scalajs/junit/Multi2TestAssertions_q.txt | 18 + .../scalajs/junit/Multi2TestAssertions_v.txt | 18 + .../scalajs/junit/Multi2TestAssertions_va.txt | 18 + .../scalajs/junit/Multi2TestAssertions_vc.txt | 18 + .../scalajs/junit/Multi2TestAssertions_vq.txt | 18 + .../scalajs/junit/Multi2TestAssertions_vs.txt | 18 + .../junit/Multi2TestAssertions_vsn.txt | 18 + .../junit/MultiAssumeFail1TestAssertions_.txt | 19 + .../MultiAssumeFail1TestAssertions_a.txt | 19 + .../MultiAssumeFail1TestAssertions_n.txt | 19 + .../MultiAssumeFail1TestAssertions_na.txt | 19 + .../MultiAssumeFail1TestAssertions_nv.txt | 19 + .../MultiAssumeFail1TestAssertions_nva.txt | 19 + .../MultiAssumeFail1TestAssertions_nvc.txt | 19 + .../MultiAssumeFail1TestAssertions_nvca.txt | 19 + .../MultiAssumeFail1TestAssertions_q.txt | 19 + .../MultiAssumeFail1TestAssertions_v.txt | 19 + .../MultiAssumeFail1TestAssertions_va.txt | 19 + .../MultiAssumeFail1TestAssertions_vc.txt | 19 + .../MultiAssumeFail1TestAssertions_vq.txt | 19 + .../MultiAssumeFail1TestAssertions_vs.txt | 19 + .../MultiAssumeFail1TestAssertions_vsn.txt | 19 + .../junit/MultiAssumeFail2TestAssertions_.txt | 20 + .../MultiAssumeFail2TestAssertions_a.txt | 20 + .../MultiAssumeFail2TestAssertions_n.txt | 20 + .../MultiAssumeFail2TestAssertions_na.txt | 20 + .../MultiAssumeFail2TestAssertions_nv.txt | 20 + .../MultiAssumeFail2TestAssertions_nva.txt | 20 + .../MultiAssumeFail2TestAssertions_nvc.txt | 20 + .../MultiAssumeFail2TestAssertions_nvca.txt | 20 + .../MultiAssumeFail2TestAssertions_q.txt | 20 + .../MultiAssumeFail2TestAssertions_v.txt | 20 + .../MultiAssumeFail2TestAssertions_va.txt | 20 + .../MultiAssumeFail2TestAssertions_vc.txt | 20 + .../MultiAssumeFail2TestAssertions_vq.txt | 20 + .../MultiAssumeFail2TestAssertions_vs.txt | 20 + .../MultiAssumeFail2TestAssertions_vsn.txt | 20 + .../MultiBeforeAssumeFailTestAssertions_.txt | 5 + .../MultiBeforeAssumeFailTestAssertions_a.txt | 5 + .../MultiBeforeAssumeFailTestAssertions_n.txt | 5 + ...MultiBeforeAssumeFailTestAssertions_na.txt | 5 + ...MultiBeforeAssumeFailTestAssertions_nv.txt | 5 + ...ultiBeforeAssumeFailTestAssertions_nva.txt | 5 + ...ultiBeforeAssumeFailTestAssertions_nvc.txt | 5 + ...ltiBeforeAssumeFailTestAssertions_nvca.txt | 5 + .../MultiBeforeAssumeFailTestAssertions_q.txt | 5 + .../MultiBeforeAssumeFailTestAssertions_v.txt | 5 + ...MultiBeforeAssumeFailTestAssertions_va.txt | 5 + ...MultiBeforeAssumeFailTestAssertions_vc.txt | 5 + ...MultiBeforeAssumeFailTestAssertions_vq.txt | 5 + ...MultiBeforeAssumeFailTestAssertions_vs.txt | 5 + ...ultiBeforeAssumeFailTestAssertions_vsn.txt | 5 + .../junit/MultiIgnore1TestAssertions_.txt | 17 + .../junit/MultiIgnore1TestAssertions_a.txt | 17 + .../junit/MultiIgnore1TestAssertions_n.txt | 17 + .../junit/MultiIgnore1TestAssertions_na.txt | 17 + .../junit/MultiIgnore1TestAssertions_nv.txt | 17 + .../junit/MultiIgnore1TestAssertions_nva.txt | 17 + .../junit/MultiIgnore1TestAssertions_nvc.txt | 17 + .../junit/MultiIgnore1TestAssertions_nvca.txt | 17 + .../junit/MultiIgnore1TestAssertions_q.txt | 17 + .../junit/MultiIgnore1TestAssertions_v.txt | 17 + .../junit/MultiIgnore1TestAssertions_va.txt | 17 + .../junit/MultiIgnore1TestAssertions_vc.txt | 17 + .../junit/MultiIgnore1TestAssertions_vq.txt | 17 + .../junit/MultiIgnore1TestAssertions_vs.txt | 17 + .../junit/MultiIgnore1TestAssertions_vsn.txt | 17 + .../junit/MultiIgnore2TestAssertions_.txt | 16 + .../junit/MultiIgnore2TestAssertions_a.txt | 16 + .../junit/MultiIgnore2TestAssertions_n.txt | 16 + .../junit/MultiIgnore2TestAssertions_na.txt | 16 + .../junit/MultiIgnore2TestAssertions_nv.txt | 16 + .../junit/MultiIgnore2TestAssertions_nva.txt | 16 + .../junit/MultiIgnore2TestAssertions_nvc.txt | 16 + .../junit/MultiIgnore2TestAssertions_nvca.txt | 16 + .../junit/MultiIgnore2TestAssertions_q.txt | 16 + .../junit/MultiIgnore2TestAssertions_v.txt | 16 + .../junit/MultiIgnore2TestAssertions_va.txt | 16 + .../junit/MultiIgnore2TestAssertions_vc.txt | 16 + .../junit/MultiIgnore2TestAssertions_vq.txt | 16 + .../junit/MultiIgnore2TestAssertions_vs.txt | 16 + .../junit/MultiIgnore2TestAssertions_vsn.txt | 16 + .../junit/MultiIgnoreAllTestAssertions_.txt | 13 + .../junit/MultiIgnoreAllTestAssertions_a.txt | 13 + .../junit/MultiIgnoreAllTestAssertions_n.txt | 13 + .../junit/MultiIgnoreAllTestAssertions_na.txt | 13 + .../junit/MultiIgnoreAllTestAssertions_nv.txt | 13 + .../MultiIgnoreAllTestAssertions_nva.txt | 13 + .../MultiIgnoreAllTestAssertions_nvc.txt | 13 + .../MultiIgnoreAllTestAssertions_nvca.txt | 13 + .../junit/MultiIgnoreAllTestAssertions_q.txt | 13 + .../junit/MultiIgnoreAllTestAssertions_v.txt | 13 + .../junit/MultiIgnoreAllTestAssertions_va.txt | 13 + .../junit/MultiIgnoreAllTestAssertions_vc.txt | 13 + .../junit/MultiIgnoreAllTestAssertions_vq.txt | 13 + .../junit/MultiIgnoreAllTestAssertions_vs.txt | 13 + .../MultiIgnoreAllTestAssertions_vsn.txt | 13 + .../org/scalajs/junit/AssertEquals2Test.scala | 5 +- .../junit/AssertEqualsDoubleTest.scala | 14 +- .../org/scalajs/junit/AssertEqualsTest.scala | 5 +- .../org/scalajs/junit/AssertFalse2Test.scala | 5 +- .../org/scalajs/junit/AssertFalseTest.scala | 5 +- .../junit/AssertStringEqualsTest.scala | 8 +- .../org/scalajs/junit/AssertTrueTest.scala | 7 +- .../org/scalajs/junit/AssumeAfterAssume.scala | 10 +- .../scalajs/junit/AssumeAfterException.scala | 10 +- .../org/scalajs/junit/AssumeInAfter.scala | 5 +- .../scala/org/scalajs/junit/AssumeTest.scala | 5 +- .../scalajs/junit/BeforeAndAfterTest.scala | 5 +- .../scalajs/junit/BeforeAssumeFailTest.scala | 5 +- .../scalajs/junit/ExceptionAfterAssume.scala | 10 +- .../scalajs/junit/ExceptionInAfterTest.scala | 8 +- .../scalajs/junit/ExceptionInBeforeTest.scala | 10 +- .../junit/ExceptionInConstructorTest.scala | 8 +- .../org/scalajs/junit/ExceptionTest.scala | 8 +- .../scala/org/scalajs/junit/ExpectTest.scala | 13 +- .../scala/org/scalajs/junit/IgnoreTest.scala | 5 +- .../scalajs/junit/MethodNameDecodeTest.scala | 16 +- .../scala/org/scalajs/junit/Multi1Test.scala | 8 +- .../scala/org/scalajs/junit/Multi2Test.scala | 11 +- .../scalajs/junit/MultiAssumeFail1Test.scala | 11 +- .../scalajs/junit/MultiAssumeFail2Test.scala | 11 +- .../junit/MultiBeforeAssumeFailTest.scala | 5 +- .../org/scalajs/junit/MultiIgnore1Test.scala | 11 +- .../org/scalajs/junit/MultiIgnore2Test.scala | 11 +- .../scalajs/junit/MultiIgnoreAllTest.scala | 11 +- .../org/scalajs/junit/utils/JUnitTest.scala | 481 ++++++------------ 469 files changed, 4663 insertions(+), 540 deletions(-) create mode 100644 junit-test/README.md create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEquals2TestAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEquals2TestAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEquals2TestAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEquals2TestAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEquals2TestAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEquals2TestAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEquals2TestAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEquals2TestAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEquals2TestAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEquals2TestAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEquals2TestAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEquals2TestAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEquals2TestAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEquals2TestAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEquals2TestAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsDoubleTestAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsDoubleTestAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsDoubleTestAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsDoubleTestAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsDoubleTestAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsDoubleTestAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsDoubleTestAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsDoubleTestAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsDoubleTestAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsDoubleTestAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsDoubleTestAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsDoubleTestAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsDoubleTestAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsDoubleTestAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsDoubleTestAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsTestAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsTestAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsTestAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsTestAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsTestAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsTestAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsTestAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsTestAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsTestAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsTestAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsTestAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsTestAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsTestAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsTestAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertEqualsTestAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalse2TestAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalse2TestAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalse2TestAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalse2TestAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalse2TestAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalse2TestAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalse2TestAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalse2TestAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalse2TestAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalse2TestAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalse2TestAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalse2TestAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalse2TestAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalse2TestAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalse2TestAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalseTestAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalseTestAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalseTestAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalseTestAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalseTestAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalseTestAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalseTestAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalseTestAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalseTestAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalseTestAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalseTestAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalseTestAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalseTestAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalseTestAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertFalseTestAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertStringEqualsTestAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertStringEqualsTestAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertStringEqualsTestAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertStringEqualsTestAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertStringEqualsTestAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertStringEqualsTestAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertStringEqualsTestAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertStringEqualsTestAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertStringEqualsTestAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertStringEqualsTestAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertStringEqualsTestAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertStringEqualsTestAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertStringEqualsTestAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertStringEqualsTestAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertStringEqualsTestAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertTrueTestAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertTrueTestAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertTrueTestAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertTrueTestAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertTrueTestAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertTrueTestAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertTrueTestAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertTrueTestAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertTrueTestAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertTrueTestAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertTrueTestAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertTrueTestAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertTrueTestAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertTrueTestAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssertTrueTestAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterAssumeAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterAssumeAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterAssumeAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterAssumeAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterAssumeAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterAssumeAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterAssumeAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterAssumeAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterAssumeAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterAssumeAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterAssumeAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterAssumeAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterAssumeAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterAssumeAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterAssumeAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterExceptionAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterExceptionAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterExceptionAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterExceptionAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterExceptionAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterExceptionAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterExceptionAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterExceptionAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterExceptionAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterExceptionAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterExceptionAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterExceptionAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterExceptionAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterExceptionAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeAfterExceptionAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeInAfterAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeInAfterAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeInAfterAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeInAfterAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeInAfterAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeInAfterAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeInAfterAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeInAfterAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeInAfterAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeInAfterAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeInAfterAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeInAfterAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeInAfterAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeInAfterAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeInAfterAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeTestAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeTestAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeTestAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeTestAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeTestAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeTestAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeTestAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeTestAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeTestAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeTestAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeTestAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeTestAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeTestAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeTestAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/AssumeTestAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAndAfterTestAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAndAfterTestAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAndAfterTestAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAndAfterTestAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAndAfterTestAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAndAfterTestAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAndAfterTestAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAndAfterTestAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAndAfterTestAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAndAfterTestAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAndAfterTestAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAndAfterTestAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAndAfterTestAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAndAfterTestAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAndAfterTestAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAssumeFailTestAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAssumeFailTestAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAssumeFailTestAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAssumeFailTestAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAssumeFailTestAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAssumeFailTestAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAssumeFailTestAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAssumeFailTestAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAssumeFailTestAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAssumeFailTestAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAssumeFailTestAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAssumeFailTestAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAssumeFailTestAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAssumeFailTestAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/BeforeAssumeFailTestAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionAfterAssumeAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionAfterAssumeAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionAfterAssumeAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionAfterAssumeAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionAfterAssumeAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionAfterAssumeAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionAfterAssumeAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionAfterAssumeAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionAfterAssumeAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionAfterAssumeAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionAfterAssumeAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionAfterAssumeAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionAfterAssumeAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionAfterAssumeAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionAfterAssumeAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInAfterTestAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInAfterTestAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInAfterTestAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInAfterTestAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInAfterTestAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInAfterTestAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInAfterTestAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInAfterTestAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInAfterTestAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInAfterTestAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInAfterTestAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInAfterTestAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInAfterTestAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInAfterTestAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInAfterTestAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInBeforeTestAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInBeforeTestAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInBeforeTestAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInBeforeTestAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInBeforeTestAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInBeforeTestAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInBeforeTestAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInBeforeTestAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInBeforeTestAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInBeforeTestAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInBeforeTestAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInBeforeTestAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInBeforeTestAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInBeforeTestAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInBeforeTestAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInConstructorTestAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInConstructorTestAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInConstructorTestAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInConstructorTestAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInConstructorTestAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInConstructorTestAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInConstructorTestAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInConstructorTestAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInConstructorTestAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInConstructorTestAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInConstructorTestAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInConstructorTestAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInConstructorTestAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInConstructorTestAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionInConstructorTestAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionTestAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionTestAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionTestAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionTestAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionTestAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionTestAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionTestAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionTestAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionTestAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionTestAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionTestAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionTestAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionTestAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionTestAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExceptionTestAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExpectTestAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExpectTestAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExpectTestAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExpectTestAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExpectTestAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExpectTestAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExpectTestAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExpectTestAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExpectTestAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExpectTestAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExpectTestAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExpectTestAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExpectTestAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExpectTestAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/ExpectTestAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/IgnoreTestAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/IgnoreTestAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/IgnoreTestAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/IgnoreTestAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/IgnoreTestAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/IgnoreTestAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/IgnoreTestAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/IgnoreTestAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/IgnoreTestAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/IgnoreTestAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/IgnoreTestAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/IgnoreTestAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/IgnoreTestAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/IgnoreTestAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/IgnoreTestAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MethodNameDecodeTestAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MethodNameDecodeTestAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MethodNameDecodeTestAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MethodNameDecodeTestAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MethodNameDecodeTestAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MethodNameDecodeTestAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MethodNameDecodeTestAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MethodNameDecodeTestAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MethodNameDecodeTestAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MethodNameDecodeTestAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MethodNameDecodeTestAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MethodNameDecodeTestAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MethodNameDecodeTestAssertions_vn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MethodNameDecodeTestAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MethodNameDecodeTestAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MethodNameDecodeTestAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi1TestAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi1TestAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi1TestAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi1TestAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi1TestAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi1TestAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi1TestAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi1TestAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi1TestAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi1TestAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi1TestAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi1TestAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi1TestAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi1TestAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi1TestAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi2TestAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi2TestAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi2TestAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi2TestAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi2TestAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi2TestAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi2TestAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi2TestAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi2TestAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi2TestAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi2TestAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi2TestAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi2TestAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi2TestAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/Multi2TestAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail1TestAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail1TestAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail1TestAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail1TestAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail1TestAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail1TestAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail1TestAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail1TestAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail1TestAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail1TestAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail1TestAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail1TestAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail1TestAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail1TestAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail1TestAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail2TestAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail2TestAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail2TestAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail2TestAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail2TestAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail2TestAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail2TestAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail2TestAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail2TestAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail2TestAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail2TestAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail2TestAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail2TestAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail2TestAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiAssumeFail2TestAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiBeforeAssumeFailTestAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiBeforeAssumeFailTestAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiBeforeAssumeFailTestAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiBeforeAssumeFailTestAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiBeforeAssumeFailTestAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiBeforeAssumeFailTestAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiBeforeAssumeFailTestAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiBeforeAssumeFailTestAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiBeforeAssumeFailTestAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiBeforeAssumeFailTestAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiBeforeAssumeFailTestAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiBeforeAssumeFailTestAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiBeforeAssumeFailTestAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiBeforeAssumeFailTestAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiBeforeAssumeFailTestAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore1TestAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore1TestAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore1TestAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore1TestAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore1TestAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore1TestAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore1TestAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore1TestAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore1TestAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore1TestAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore1TestAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore1TestAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore1TestAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore1TestAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore1TestAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore2TestAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore2TestAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore2TestAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore2TestAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore2TestAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore2TestAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore2TestAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore2TestAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore2TestAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore2TestAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore2TestAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore2TestAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore2TestAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore2TestAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnore2TestAssertions_vsn.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnoreAllTestAssertions_.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnoreAllTestAssertions_a.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnoreAllTestAssertions_n.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnoreAllTestAssertions_na.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnoreAllTestAssertions_nv.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnoreAllTestAssertions_nva.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnoreAllTestAssertions_nvc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnoreAllTestAssertions_nvca.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnoreAllTestAssertions_q.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnoreAllTestAssertions_v.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnoreAllTestAssertions_va.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnoreAllTestAssertions_vc.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnoreAllTestAssertions_vq.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnoreAllTestAssertions_vs.txt create mode 100644 junit-test/outputs/org/scalajs/junit/MultiIgnoreAllTestAssertions_vsn.txt diff --git a/junit-test/README.md b/junit-test/README.md new file mode 100644 index 0000000000..e9a6aa186b --- /dev/null +++ b/junit-test/README.md @@ -0,0 +1,8 @@ +JUnit tests compare the output of a JUnit test to a recording. + +The recordings lie in the `outputs` directory. To re-record all tests, set the +`org.scalajs.junit.utils.record` system property and run the JVM tests: + +``` +sbt -Dorg.scalajs.junit.utils.record jUnitTestOutputsJVM/test +``` diff --git a/junit-test/output-js/src/test/scala/org/scalajs/junit/utils/JUnitTestPlatformImpl.scala b/junit-test/output-js/src/test/scala/org/scalajs/junit/utils/JUnitTestPlatformImpl.scala index 16f09c54fc..111a4cf16e 100644 --- a/junit-test/output-js/src/test/scala/org/scalajs/junit/utils/JUnitTestPlatformImpl.scala +++ b/junit-test/output-js/src/test/scala/org/scalajs/junit/utils/JUnitTestPlatformImpl.scala @@ -12,6 +12,8 @@ package org.scalajs.junit.utils +import scala.scalajs.js + import sbt.testing._ object JUnitTestPlatformImpl { @@ -33,4 +35,13 @@ object JUnitTestPlatformImpl { }, recorder) } } + + def writeLines(lines: List[String], file: String): Unit = + throw new UnsupportedOperationException("Writing is only supported on the JVM.") + + def readLines(file: String): List[String] = { + val fs = js.Dynamic.global.require("fs") + val c = fs.readFileSync(file, "utf8").asInstanceOf[String] + c.split('\n').toList + } } diff --git a/junit-test/output-jvm/src/test/scala/org/scalajs/junit/utils/JUnitTestPlatformImpl.scala b/junit-test/output-jvm/src/test/scala/org/scalajs/junit/utils/JUnitTestPlatformImpl.scala index f6c2fdcdd3..449f70000c 100644 --- a/junit-test/output-jvm/src/test/scala/org/scalajs/junit/utils/JUnitTestPlatformImpl.scala +++ b/junit-test/output-jvm/src/test/scala/org/scalajs/junit/utils/JUnitTestPlatformImpl.scala @@ -12,6 +12,11 @@ package org.scalajs.junit.utils +import scala.collection.JavaConverters._ + +import java.nio.file._ +import java.nio.charset.StandardCharsets.UTF_8 + import sbt.testing._ object JUnitTestPlatformImpl { @@ -23,4 +28,10 @@ object JUnitTestPlatformImpl { executeLoop(tasks.flatMap(_.execute(recorder, Array(recorder))), recorder) } } + + def writeLines(lines: List[String], file: String): Unit = + Files.write(Paths.get(file), lines.toIterable.asJava, UTF_8) + + def readLines(file: String): List[String] = + Files.readAllLines(Paths.get(file), UTF_8).asScala.toList } diff --git a/junit-test/outputs/org/scalajs/junit/AssertEquals2TestAssertions_.txt b/junit-test/outputs/org/scalajs/junit/AssertEquals2TestAssertions_.txt new file mode 100644 index 0000000000..2a161db9ae --- /dev/null +++ b/junit-test/outputs/org/scalajs/junit/AssertEquals2TestAssertions_.txt @@ -0,0 +1,7 @@ +ldTest run started +ldTest org.scalajs.junit.AssertEquals2Test.test started +leTest org.scalajs.junit.AssertEquals2Test.test failed: This is the message expected: but was:, took